--- linux-2.6.28.orig/Makefile +++ linux-2.6.28/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 28 -EXTRAVERSION = +EXTRAVERSION = .9 NAME = Erotic Pickled Herring # *DOCUMENTATION* @@ -328,14 +328,24 @@ CFLAGS_KERNEL = AFLAGS_KERNEL = +# Prefer linux-backports-modules +ifneq ($(KBUILD_SRC),) +ifneq ($(shell if test -e $(KBUILD_OUTPUT)/ubuntu-build; then echo yes; fi),yes) +UBUNTUINCLUDE := -I/usr/src/linux-headers-lbm-$(KERNELRELEASE) +endif +endif # Use LINUXINCLUDE when you must reference the include/ directory. # Needed to be compatible with the O= option -LINUXINCLUDE := -Iinclude \ +LINUXINCLUDE := $(UBUNTUINCLUDE) -Iinclude \ $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \ -I$(srctree)/arch/$(hdr-arch)/include \ -include include/linux/autoconf.h +# UBUNTU: Include our third party driver stuff too +LINUXINCLUDE += -Iubuntu/include \ + $(if $(KBUILD_SRC),-I$(srctree)/ubuntu/include) + KBUILD_CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE) KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ @@ -458,7 +468,7 @@ # Objects we will link into vmlinux / subdirs we need to visit init-y := init/ -drivers-y := drivers/ sound/ firmware/ +drivers-y := drivers/ sound/ firmware/ ubuntu/ net-y := net/ libs-y := lib/ core-y := usr/ @@ -555,6 +565,9 @@ # disable pointer signed / unsigned warnings in gcc 4.0 KBUILD_CFLAGS += $(call cc-option,-Wno-pointer-sign,) +# disable invalid "can't wrap" optimzations for signed / pointers +KBUILD_CFLAGS += $(call cc-option,-fwrapv) + # Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments # But warn user when we do so warn-assign = \ --- linux-2.6.28.orig/crypto/algapi.c +++ linux-2.6.28/crypto/algapi.c @@ -149,6 +149,9 @@ if (q == alg) goto err; + if (crypto_is_moribund(q)) + continue; + if (crypto_is_larval(q)) { if (!strcmp(alg->cra_driver_name, q->cra_driver_name)) goto err; @@ -197,7 +200,7 @@ down_write(&crypto_alg_sem); list_for_each_entry(q, &crypto_alg_list, cra_list) { - if (!crypto_is_larval(q)) + if (crypto_is_moribund(q) || !crypto_is_larval(q)) continue; test = (struct crypto_larval *)q; @@ -210,6 +213,7 @@ goto unlock; found: + q->cra_flags |= CRYPTO_ALG_DEAD; alg = test->adult; if (err || list_empty(&alg->cra_list)) goto complete; --- linux-2.6.28.orig/crypto/authenc.c +++ linux-2.6.28/crypto/authenc.c @@ -157,16 +157,19 @@ dstp = sg_page(dst); vdst = PageHighMem(dstp) ? NULL : page_address(dstp) + dst->offset; - sg_init_table(cipher, 2); - sg_set_buf(cipher, iv, ivsize); - authenc_chain(cipher, dst, vdst == iv + ivsize); + if (ivsize) { + sg_init_table(cipher, 2); + sg_set_buf(cipher, iv, ivsize); + authenc_chain(cipher, dst, vdst == iv + ivsize); + dst = cipher; + } cryptlen = req->cryptlen + ivsize; - hash = crypto_authenc_hash(req, flags, cipher, cryptlen); + hash = crypto_authenc_hash(req, flags, dst, cryptlen); if (IS_ERR(hash)) return PTR_ERR(hash); - scatterwalk_map_and_copy(hash, cipher, cryptlen, + scatterwalk_map_and_copy(hash, dst, cryptlen, crypto_aead_authsize(authenc), 1); return 0; } @@ -284,11 +287,14 @@ srcp = sg_page(src); vsrc = PageHighMem(srcp) ? NULL : page_address(srcp) + src->offset; - sg_init_table(cipher, 2); - sg_set_buf(cipher, iv, ivsize); - authenc_chain(cipher, src, vsrc == iv + ivsize); + if (ivsize) { + sg_init_table(cipher, 2); + sg_set_buf(cipher, iv, ivsize); + authenc_chain(cipher, src, vsrc == iv + ivsize); + src = cipher; + } - return crypto_authenc_verify(req, cipher, cryptlen + ivsize); + return crypto_authenc_verify(req, src, cryptlen + ivsize); } static int crypto_authenc_decrypt(struct aead_request *req) --- linux-2.6.28.orig/crypto/ccm.c +++ linux-2.6.28/crypto/ccm.c @@ -266,6 +266,8 @@ if (assoclen) { pctx->ilen = format_adata(idata, assoclen); get_data_to_compute(cipher, pctx, req->assoc, req->assoclen); + } else { + pctx->ilen = 0; } /* compute plaintext into mac */ --- linux-2.6.28.orig/crypto/async_tx/async_tx.c +++ linux-2.6.28/crypto/async_tx/async_tx.c @@ -124,6 +124,8 @@ if (!dep) return; + /* we'll submit tx->next now, so clear the link */ + tx->next = NULL; chan = dep->chan; /* keep submitting up until a channel switch is detected --- linux-2.6.28.orig/Documentation/kernel-parameters.txt +++ linux-2.6.28/Documentation/kernel-parameters.txt @@ -180,6 +180,9 @@ acpi_no_auto_ssdt [HW,ACPI] Disable automatic loading of SSDT + acpi_no_initrd_override [KNL,ACPI] + Disable loading custom ACPI tables from the initramfs + acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS Format: To spoof as Windows 98: ="Microsoft Windows" @@ -2258,6 +2261,13 @@ Format: ,,,,,,,, + tsc= Disable clocksource-must-verify flag for TSC. + Format: + [x86] reliable: mark tsc clocksource as reliable, this + disables clocksource verification at runtime. + Used to enable high-resolution timer mode on older + hardware, and in virtualized environment. + turbografx.map[2|3]= [HW,JOY] TurboGraFX parallel port interface Format: --- linux-2.6.28.orig/Documentation/DMA-API.txt +++ linux-2.6.28/Documentation/DMA-API.txt @@ -5,7 +5,7 @@ This document describes the DMA API. For a more gentle introduction phrased in terms of the pci_ equivalents (and actual examples) see -DMA-mapping.txt +Documentation/PCI/PCI-DMA-mapping.txt. This API is split into two pieces. Part I describes the API and the corresponding pci_ API. Part II describes the extensions to the API --- linux-2.6.28.orig/Documentation/IO-mapping.txt +++ linux-2.6.28/Documentation/IO-mapping.txt @@ -1,6 +1,6 @@ [ NOTE: The virt_to_bus() and bus_to_virt() functions have been - superseded by the functionality provided by the PCI DMA - interface (see Documentation/DMA-mapping.txt). They continue + superseded by the functionality provided by the PCI DMA interface + (see Documentation/PCI/PCI-DMA-mapping.txt). They continue to be documented below for historical purposes, but new code must not use them. --davidm 00/12/12 ] --- linux-2.6.28.orig/Documentation/block/biodoc.txt +++ linux-2.6.28/Documentation/block/biodoc.txt @@ -186,8 +186,9 @@ do not have a corresponding kernel virtual address space mapping) and low-memory pages. -Note: Please refer to DMA-mapping.txt for a discussion on PCI high mem DMA -aspects and mapping of scatter gather lists, and support for 64 bit PCI. +Note: Please refer to Documentation/PCI/PCI-DMA-mapping.txt for a discussion +on PCI high mem DMA aspects and mapping of scatter gather lists, and support +for 64 bit PCI. Special handling is required only for cases where i/o needs to happen on pages at physical memory addresses beyond what the device can support. In these --- linux-2.6.28.orig/Documentation/networking/README.ipw2200 +++ linux-2.6.28/Documentation/networking/README.ipw2200 @@ -147,7 +147,7 @@ driver. If disabled, the driver will not attempt to scan for and associate to a network until it has been configured with one or more properties for the target network, for example configuring - the network SSID. Default is 1 (auto-associate) + the network SSID. Default is 0 (do not auto-associate) Example: % modprobe ipw2200 associate=0 @@ -171,7 +171,7 @@ led Can be used to turn on experimental LED code. - 0 = Off, 1 = On. Default is 0. + 0 = Off, 1 = On. Default is 1. mode Can be used to set the default mode of the adapter. --- linux-2.6.28.orig/Documentation/acpi/initramfs-add-dsdt.sh +++ linux-2.6.28/Documentation/acpi/initramfs-add-dsdt.sh @@ -0,0 +1,43 @@ +#!/bin/bash +# Adds a DSDT file to the initrd (if it's an initramfs) +# first argument is the name of archive +# second argument is the name of the file to add +# The file will be copied as /DSDT.aml + +# 20060126: fix "Premature end of file" with some old cpio (Roland Robic) +# 20060205: this time it should really work + +# check the arguments +if [ $# -ne 2 ]; then + program_name=$(basename $0) + echo "\ +$program_name: too few arguments +Usage: $program_name initrd-name.img DSDT-to-add.aml +Adds a DSDT file to an initrd (in initramfs format) + + initrd-name.img: filename of the initrd in initramfs format + DSDT-to-add.aml: filename of the DSDT file to add + " 1>&2 + exit 1 +fi + +# we should check it's an initramfs + +tempcpio=$(mktemp -d) +# cleanup on exit, hangup, interrupt, quit, termination +trap 'rm -rf $tempcpio' 0 1 2 3 15 + +# extract the archive +gunzip -c "$1" > "$tempcpio"/initramfs.cpio || exit 1 + +# copy the DSDT file at the root of the directory so that we can call it "/DSDT.aml" +cp -f "$2" "$tempcpio"/DSDT.aml + +# add the file +cd "$tempcpio" +(echo DSDT.aml | cpio --quiet -H newc -o -A -O "$tempcpio"/initramfs.cpio) || exit 1 +cd "$OLDPWD" + +# re-compress the archive +gzip -c "$tempcpio"/initramfs.cpio > "$1" + --- linux-2.6.28.orig/Documentation/acpi/dsdt-override.txt +++ linux-2.6.28/Documentation/acpi/dsdt-override.txt @@ -1,7 +1,15 @@ -Linux supports a method of overriding the BIOS DSDT: +Linux supports two methods of overriding the BIOS DSDT: CONFIG_ACPI_CUSTOM_DSDT builds the image into the kernel. -When to use this method is described in detail on the +CONFIG_ACPI_CUSTOM_DSDT_INITRD adds the image to the initrd. + +When to use these methods is described in detail on the Linux/ACPI home page: http://www.lesswatts.org/projects/acpi/overridingDSDT.php + +Note that if both options are used, the DSDT supplied +by the INITRD method takes precedence. + +Documentation/initramfs-add-dsdt.sh is provided for convenience +for use with the CONFIG_ACPI_CUSTOM_DSDT_INITRD method. --- linux-2.6.28.orig/Documentation/filesystems/sysfs-pci.txt +++ linux-2.6.28/Documentation/filesystems/sysfs-pci.txt @@ -9,6 +9,7 @@ | |-- class | |-- config | |-- device + | |-- enable | |-- irq | |-- local_cpus | |-- resource @@ -32,6 +33,7 @@ class PCI class (ascii, ro) config PCI config space (binary, rw) device PCI device (ascii, ro) + enable Whether the device is enabled (ascii, rw) irq IRQ number (ascii, ro) local_cpus nearby CPU mask (cpumask, ro) resource PCI resource host addresses (ascii, ro) @@ -57,10 +59,19 @@ don't support mmapping of certain resources, so be sure to check the return value from any attempted mmap. +The 'enable' file provides a counter that indicates how many times the device +has been enabled. If the 'enable' file currently returns '4', and a '1' is +echoed into it, it will then return '5'. Echoing a '0' into it will decrease +the count. Even when it returns to 0, though, some of the initialisation +may not be reversed. + The 'rom' file is special in that it provides read-only access to the device's ROM file, if available. It's disabled by default, however, so applications should write the string "1" to the file to enable it before attempting a read -call, and disable it following the access by writing "0" to the file. +call, and disable it following the access by writing "0" to the file. Note +that the device must be enabled for a rom read to return data succesfully. +In the event a driver is not bound to the device, it can be enabled using the +'enable' file, documented above. Accessing legacy resources through sysfs ---------------------------------------- --- linux-2.6.28.orig/Documentation/sound/alsa/ALSA-Configuration.txt +++ linux-2.6.28/Documentation/sound/alsa/ALSA-Configuration.txt @@ -938,6 +938,7 @@ lenovo Lenovo 3000 C200 dallas Dallas laptops hp HP TX1000 + asus-v1s ASUS V1Sn auto auto-config reading BIOS (default) CMI9880 @@ -979,9 +980,10 @@ 6stack 6-jack, separate surrounds (default) 3stack 3-stack, shared surrounds laptop 2-channel only (FSC V2060, Samsung M50) - laptop-eapd 2-channel with EAPD (Samsung R65, ASUS A6J) + laptop-eapd 2-channel with EAPD (ASUS A6J) laptop-automute 2-channel with EAPD and HP-automute (Lenovo N100) ultra 2-channel with EAPD (Samsung Ultra tablet PC) + samsung 2-channel with EAPD (Samsung R65) AD1988/AD1988B/AD1989A/AD1989B 6stack 6-jack @@ -1652,7 +1654,8 @@ * AuzenTech X-Meridian * Bgears b-Enspirer * Club3D Theatron DTS - * HT-Omega Claro + * HT-Omega Claro (plus) + * HT-Omega Claro halo (XT) * Razer Barracuda AC-1 * Sondigo Inferno --- linux-2.6.28.orig/Documentation/usb/dma.txt +++ linux-2.6.28/Documentation/usb/dma.txt @@ -6,8 +6,9 @@ API OVERVIEW The big picture is that USB drivers can continue to ignore most DMA issues, -though they still must provide DMA-ready buffers (see DMA-mapping.txt). -That's how they've worked through the 2.4 (and earlier) kernels. +though they still must provide DMA-ready buffers (see +Documentation/PCI/PCI-DMA-mapping.txt). That's how they've worked through +the 2.4 (and earlier) kernels. OR: they can now be DMA-aware. @@ -62,8 +63,8 @@ force a consistent memory access ordering by using memory barriers. It's not using a streaming DMA mapping, so it's good for small transfers on systems where the I/O would otherwise thrash an IOMMU mapping. (See - Documentation/DMA-mapping.txt for definitions of "coherent" and "streaming" - DMA mappings.) + Documentation/PCI/PCI-DMA-mapping.txt for definitions of "coherent" and + "streaming" DMA mappings.) Asking for 1/Nth of a page (as well as asking for N pages) is reasonably space-efficient. @@ -93,7 +94,7 @@ Existing buffers aren't usable for DMA without first being mapped into the DMA address space of the device. However, most buffers passed to your driver can safely be used with such DMA mapping. (See the first section -of DMA-mapping.txt, titled "What memory is DMA-able?") +of Documentation/PCI/PCI-DMA-mapping.txt, titled "What memory is DMA-able?") - When you're using scatterlists, you can map everything at once. On some systems, this kicks in an IOMMU and turns the scatterlists into single --- linux-2.6.28.orig/arch/Kconfig +++ linux-2.6.28/arch/Kconfig @@ -60,6 +60,9 @@ See Documentation/unaligned-memory-access.txt for more information on the topic of unaligned memory accesses. +config HAVE_SYSCALL_WRAPPERS + bool + config KRETPROBES def_bool y depends on KPROBES && HAVE_KRETPROBES --- linux-2.6.28.orig/arch/alpha/kernel/irq_srm.c +++ linux-2.6.28/arch/alpha/kernel/irq_srm.c @@ -63,6 +63,8 @@ { long i; + if (NR_IRQS <= 16) + return; for (i = 16; i < max; ++i) { if (i < 64 && ((ignore_mask >> i) & 1)) continue; --- linux-2.6.28.orig/arch/alpha/kernel/entry.S +++ linux-2.6.28/arch/alpha/kernel/entry.S @@ -894,9 +894,9 @@ .end sys_getxpid .align 4 - .globl sys_pipe - .ent sys_pipe -sys_pipe: + .globl sys_alpha_pipe + .ent sys_alpha_pipe +sys_alpha_pipe: lda $sp, -16($sp) stq $26, 0($sp) .prologue 0 @@ -914,7 +914,7 @@ stq $1, 80+16($sp) 1: lda $sp, 16($sp) ret -.end sys_pipe +.end sys_alpha_pipe .align 4 .globl sys_execve --- linux-2.6.28.orig/arch/alpha/kernel/systbls.S +++ linux-2.6.28/arch/alpha/kernel/systbls.S @@ -52,7 +52,7 @@ .quad sys_setpgid .quad alpha_ni_syscall /* 40 */ .quad sys_dup - .quad sys_pipe + .quad sys_alpha_pipe .quad osf_set_program_attributes .quad alpha_ni_syscall .quad sys_open /* 45 */ --- linux-2.6.28.orig/arch/mips/include/asm/compat.h +++ linux-2.6.28/arch/mips/include/asm/compat.h @@ -3,6 +3,8 @@ /* * Architecture specific compatibility types */ +#include +#include #include #include #include @@ -218,4 +220,9 @@ compat_ulong_t __unused2; }; +static inline int is_compat_task(void) +{ + return test_thread_flag(TIF_32BIT); +} + #endif /* _ASM_COMPAT_H */ --- linux-2.6.28.orig/arch/mips/include/asm/seccomp.h +++ linux-2.6.28/arch/mips/include/asm/seccomp.h @@ -1,6 +1,5 @@ #ifndef __ASM_SECCOMP_H -#include #include #define __NR_seccomp_read __NR_read --- linux-2.6.28.orig/arch/mips/kernel/scall32-o32.S +++ linux-2.6.28/arch/mips/kernel/scall32-o32.S @@ -398,7 +398,7 @@ sys sys_uselib 1 sys sys_swapon 2 sys sys_reboot 3 - sys old_readdir 3 + sys sys_old_readdir 3 sys old_mmap 6 /* 4090 */ sys sys_munmap 2 sys sys_truncate 2 --- linux-2.6.28.orig/arch/sh/include/asm/syscalls_32.h +++ linux-2.6.28/arch/sh/include/asm/syscalls_32.h @@ -36,9 +36,9 @@ asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, struct pt_regs __regs); -asmlinkage int sys_pipe(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs); +asmlinkage int sys_sh_pipe(unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7, + struct pt_regs __regs); asmlinkage ssize_t sys_pread_wrapper(unsigned int fd, char __user *buf, size_t count, long dummy, loff_t pos); asmlinkage ssize_t sys_pwrite_wrapper(unsigned int fd, const char __user *buf, --- linux-2.6.28.orig/arch/sh/kernel/syscalls_64.S +++ linux-2.6.28/arch/sh/kernel/syscalls_64.S @@ -109,7 +109,7 @@ .long sys_uselib .long sys_swapon .long sys_reboot - .long old_readdir + .long sys_old_readdir .long old_mmap /* 90 */ .long sys_munmap .long sys_truncate --- linux-2.6.28.orig/arch/sh/kernel/sys_sh32.c +++ linux-2.6.28/arch/sh/kernel/sys_sh32.c @@ -22,7 +22,7 @@ * sys_pipe() is the normal C calling standard for creating * a pipe. It's not the way Unix traditionally does this, though. */ -asmlinkage int sys_pipe(unsigned long r4, unsigned long r5, +asmlinkage int sys_sh_pipe(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, struct pt_regs __regs) { --- linux-2.6.28.orig/arch/sh/kernel/syscalls_32.S +++ linux-2.6.28/arch/sh/kernel/syscalls_32.S @@ -58,7 +58,7 @@ .long sys_mkdir .long sys_rmdir /* 40 */ .long sys_dup - .long sys_pipe + .long sys_sh_pipe .long sys_times .long sys_ni_syscall /* old prof syscall holder */ .long sys_brk /* 45 */ @@ -105,7 +105,7 @@ .long sys_uselib .long sys_swapon .long sys_reboot - .long old_readdir + .long sys_old_readdir .long old_mmap /* 90 */ .long sys_munmap .long sys_truncate --- linux-2.6.28.orig/arch/cris/arch-v10/kernel/entry.S +++ linux-2.6.28/arch/cris/arch-v10/kernel/entry.S @@ -691,7 +691,7 @@ .long sys_uselib .long sys_swapon .long sys_reboot - .long old_readdir + .long sys_old_readdir .long old_mmap /* 90 */ .long sys_munmap .long sys_truncate --- linux-2.6.28.orig/arch/cris/arch-v32/kernel/entry.S +++ linux-2.6.28/arch/cris/arch-v32/kernel/entry.S @@ -614,7 +614,7 @@ .long sys_uselib .long sys_swapon .long sys_reboot - .long old_readdir + .long sys_old_readdir .long old_mmap /* 90 */ .long sys_munmap .long sys_truncate --- linux-2.6.28.orig/arch/arm/Kconfig +++ linux-2.6.28/arch/arm/Kconfig @@ -421,14 +421,22 @@ config ARCH_MXC bool "Freescale MXC/iMX-based" + select ARCH_MTD_XIP select GENERIC_TIME select GENERIC_CLOCKEVENTS - select ARCH_MTD_XIP - select GENERIC_GPIO - select ARCH_REQUIRE_GPIOLIB +# select GENERIC_GPIO +# select ARCH_REQUIRE_GPIOLIB + select ZONE_DMA + select ARCH_MXC_CANONICAL help Support for Freescale MXC/iMX-based family of processors +config ARCH_MXC_CANONICAL + bool "Ubuntu - Enable Freescale code that touches common paths" + depends on ARCH_MXC + help + Choose this option to enable all common ARM arch code for Freescale in Ubuntu's kernel. This should be disabled all all Ubuntu kernel flavour except the iMX flavours. + config ARCH_ORION5X bool "Marvell Orion" depends on MMU @@ -1037,7 +1045,7 @@ menu "CPU Power Management" -if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA) +if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA || ARCH_MXC) source "drivers/cpufreq/Kconfig" @@ -1077,6 +1085,12 @@ default y select CPU_FREQ_DEFAULT_GOV_USERSPACE +config CPU_FREQ_IMX + tristate "CPUfreq driver for i.MX CPUs" + depends on ARCH_MXC && CPU_FREQ && REGULATOR + help + This enables the CPUfreq driver for i.MX CPUs. + endif source "drivers/cpuidle/Kconfig" @@ -1178,6 +1192,8 @@ source "net/Kconfig" +source "ubuntu/Kconfig" + menu "Device Drivers" source "drivers/base/Kconfig" @@ -1276,6 +1292,10 @@ source "drivers/uio/Kconfig" +if ARCH_MXC +source "drivers/mxc/Kconfig" +endif + endmenu source "fs/Kconfig" --- linux-2.6.28.orig/arch/arm/Makefile +++ linux-2.6.28/arch/arm/Makefile @@ -139,6 +139,7 @@ plat-$(CONFIG_ARCH_MXC) := mxc machine-$(CONFIG_ARCH_MX2) := mx2 machine-$(CONFIG_ARCH_MX3) := mx3 + machine-$(CONFIG_ARCH_MX51) := mx51 machine-$(CONFIG_ARCH_ORION5X) := orion5x plat-$(CONFIG_PLAT_ORION) := orion machine-$(CONFIG_ARCH_MSM) := msm --- linux-2.6.28.orig/arch/arm/plat-mxc/dvfs_core.c +++ linux-2.6.28/arch/arm/plat-mxc/dvfs_core.c @@ -0,0 +1,583 @@ +/* + * Copyright 2008-2009 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 + */ + +/*! + * @file dvfs_core.c + * + * @brief A simplied driver for the Freescale Semiconductor MXC DVFS module. + * + * Upon initialization, the DVFS driver initializes the DVFS hardware + * sets up driver nodes attaches to the DVFS interrupt and initializes internal + * data structures. When the DVFS interrupt occurs the driver checks the cause + * of the interrupt (lower frequency, increase frequency or emergency) and + * changes the CPU voltage according to translation table that is loaded into + * the driver. + * + * @ingroup PM + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MXC_DVFSTHRS_UPTHR_MASK 0x0FC00000 +#define MXC_DVFSTHRS_UPTHR_OFFSET 22 +#define MXC_DVFSTHRS_DNTHR_MASK 0x003F0000 +#define MXC_DVFSTHRS_DNTHR_OFFSET 16 +#define MXC_DVFSTHRS_PNCTHR_MASK 0x0000003F +#define MXC_DVFSTHRS_PNCTHR_OFFSET 0 + +#define MXC_DVFSCOUN_DNCNT_MASK 0x00FF0000 +#define MXC_DVFSCOUN_DNCNT_OFFSET 16 +#define MXC_DVFSCOUN_UPCNT_MASK 0x000000FF +#define MXC_DVFSCOUN_UPCNT_OFFSET 0 + +#define MXC_DVFSEMAC_EMAC_MASK 0x000001FF +#define MXC_DVFSEMAC_EMAC_OFFSET 0 + +#define MXC_DVFSCNTR_DVFEV 0x10000000 +#define MXC_DVFSCNTR_LBMI 0x08000000 +#define MXC_DVFSCNTR_LBFL 0x06000000 +#define MXC_DVFSCNTR_DVFIS 0x01000000 +#define MXC_DVFSCNTR_FSVAIM 0x00400000 +#define MXC_DVFSCNTR_FSVAI_MASK 0x00300000 +#define MXC_DVFSCNTR_FSVAI_OFFSET 20 +#define MXC_DVFSCNTR_WFIM 0x00080000 +#define MXC_DVFSCNTR_WFIM_OFFSET 19 +#define MXC_DVFSCNTR_MAXF_MASK 0x00040000 +#define MXC_DVFSCNTR_MAXF_OFFSET 18 +#define MXC_DVFSCNTR_MINF_MASK 0x00020000 +#define MXC_DVFSCNTR_MINF_OFFSET 17 +#define MXC_DVFSCNTR_LTBRSR_MASK 0x00000018 +#define MXC_DVFSCNTR_LTBRSR_OFFSET 3 +#define MXC_DVFSCNTR_DVFEN 0x00000001 + +#define MXC_GPCCNTR_GPCIRQ 0x00100000 +#define MXC_GPCCNTR_DVFS0CR 0x00010000 +#define MXC_GPCCNTR_ADU 0x00008000 +#define MXC_GPCCNTR_STRT 0x00004000 +#define MXC_GPCCNTR_FUPD 0x00002000 +#define MXC_GPCCNTR_HTRI_MASK 0x0000000F +#define MXC_GPCCNTR_HTRI_OFFSET 0 + +#define MXC_GPCVCR_VINC_MASK 0x00020000 +#define MXC_GPCVCR_VINC_OFFSET 17 +#define MXC_GPCVCR_VCNTU_MASK 0x00010000 +#define MXC_GPCVCR_VCNTU_OFFSET 16 +#define MXC_GPCVCR_VCNT_MASK 0x00007FFF +#define MXC_GPCVCR_VCNT_OFFSET 0 + +static struct delayed_work dvfs_core_work; +static struct mxc_dvfs_platform_data *dvfs_data; +static struct device *dvfs_dev; +static struct cpu_wp *cpu_wp_tbl; +int curr_wp; +int dvfs_core_is_active; + +/* + * Clock structures + */ +static struct clk *cpu_clk; +static struct clk *dvfs_clk; +static struct regulator *core_regulator; + +#ifdef CONFIG_ARCH_MX51 +extern struct cpu_wp *(*get_cpu_wp)(int *wp); +#endif + +enum { + FSVAI_FREQ_NOCHANGE = 0x0, + FSVAI_FREQ_INCREASE, + FSVAI_FREQ_DECREASE, + FSVAI_FREQ_EMERG, +}; + +/* + * Load tracking buffer source: 1 for ld_add; 0 for pre_ld_add; 2 for after EMA + */ +#define DVFS_LTBRSR (2 << MXC_DVFSCNTR_LTBRSR_OFFSET) + +DEFINE_SPINLOCK(mxc_dvfs_core_lock); + +static void dvfs_load_config(void) +{ + u32 reg; + + reg = 0; + reg |= dvfs_data->upthr_val << MXC_DVFSTHRS_UPTHR_OFFSET; + reg |= dvfs_data->dnthr_val << MXC_DVFSTHRS_DNTHR_OFFSET; + reg |= dvfs_data->pncthr_val; + __raw_writel(reg, dvfs_data->dvfs_thrs_reg_addr); + + reg = 0; + reg |= dvfs_data->dncnt_val << MXC_DVFSCOUN_DNCNT_OFFSET; + reg |= dvfs_data->upcnt_val << MXC_DVFSCOUN_UPCNT_OFFSET; + __raw_writel(reg, dvfs_data->dvfs_coun_reg_addr); +} + +static int start_dvfs(void) +{ + u32 reg; + unsigned long flags; + + if (dvfs_core_is_active) + return 0; + + spin_lock_irqsave(&mxc_dvfs_core_lock, flags); + + clk_enable(dvfs_clk); + + /* config reg GPC_CNTR */ + reg = __raw_readl(dvfs_data->gpc_cntr_reg_addr); + + /* GPCIRQ=1, select ARM IRQ */ + reg |= MXC_GPCCNTR_GPCIRQ; + /* ADU=1, select ARM domain */ + reg |= MXC_GPCCNTR_ADU; + __raw_writel(reg, dvfs_data->gpc_cntr_reg_addr); + + /* Enable DVFS interrupt */ + reg = __raw_readl(dvfs_data->dvfs_cntr_reg_addr); + /* FSVAIM=0 */ + reg = (reg & ~MXC_DVFSCNTR_FSVAIM); + /* Set MAXF, MINF */ + reg = (reg & ~(MXC_DVFSCNTR_MAXF_MASK | MXC_DVFSCNTR_MINF_MASK)); + reg |= 1 << MXC_DVFSCNTR_MAXF_OFFSET; + /* Select ARM domain */ + reg |= MXC_DVFSCNTR_DVFIS; + /* Enable DVFS frequency adjustment interrupt */ + reg = (reg & ~MXC_DVFSCNTR_FSVAIM); + /* Set load tracking buffer register source */ + reg = (reg & ~MXC_DVFSCNTR_LTBRSR_MASK); + reg |= DVFS_LTBRSR; + /* Set DIV3CK */ + reg = (reg & ~(dvfs_data->div3ck_mask)); + reg |= (dvfs_data->div3ck_val) << (dvfs_data->div3ck_offset); + /* Enable DVFS */ + reg |= MXC_DVFSCNTR_DVFEN; + __raw_writel(reg, dvfs_data->dvfs_cntr_reg_addr); + + dvfs_core_is_active = 1; + + spin_unlock_irqrestore(&mxc_dvfs_core_lock, flags); + + printk(KERN_DEBUG "DVFS is started\n"); + + return 0; +} + +/*! + * This function is called for module initialization. + * It sets up the DVFS hardware. + * It sets default values for DVFS thresholds and counters. The default + * values was chosen from a set of different reasonable values. They was tested + * and the default values in the driver gave the best results. + * More work should be done to find optimal values. + * + * @return 0 if successful; non-zero otherwise. + * + */ +static int init_dvfs_controller(void) +{ + /* DVFS loading config */ + dvfs_load_config(); + + /* Set EMAC value */ + __raw_writel((dvfs_data->emac_val << MXC_DVFSEMAC_EMAC_OFFSET), + dvfs_data->dvfs_emac_reg_addr); + + return 0; +} + +static irqreturn_t dvfs_irq(int irq, void *dev_id) +{ + u32 reg; + + /* Check if DVFS0 (ARM) id requesting for freqency/voltage update */ + if ((__raw_readl(dvfs_data->gpc_cntr_reg_addr) & MXC_GPCCNTR_DVFS0CR) == + 0) + return IRQ_NONE; + + /* Mask DVFS irq */ + reg = __raw_readl(dvfs_data->dvfs_cntr_reg_addr); + /* FSVAIM=1 */ + reg |= MXC_DVFSCNTR_FSVAIM; + __raw_writel(reg, dvfs_data->dvfs_cntr_reg_addr); + + schedule_delayed_work(&dvfs_core_work, 0); + + return IRQ_HANDLED; +} + +static void dvfs_core_workqueue_handler(struct work_struct *work) +{ + u32 fsvai; + u32 reg; + u32 curr_cpu; + unsigned long rate = 0; + int ret = 0; + int uvol; + int maxf = 0, minf = 0; + + /* Check DVFS frequency adjustment interrupt status */ + reg = __raw_readl(dvfs_data->dvfs_cntr_reg_addr); + fsvai = (reg & MXC_DVFSCNTR_FSVAI_MASK) >> MXC_DVFSCNTR_FSVAI_OFFSET; + + /* Check FSVAI, FSVAI=0 is error */ + if (fsvai == FSVAI_FREQ_NOCHANGE) { + /* Do nothing. Freq change is not required */ + goto END; + } + + curr_cpu = clk_get_rate(cpu_clk); + + /* If FSVAI indicate freq down, + check arm-clk is not in lowest frequency 200 MHz */ + if (fsvai == FSVAI_FREQ_DECREASE) { + if (curr_cpu == cpu_wp_tbl[dvfs_data->num_wp - 1].cpu_rate) { + minf = 1; + goto END; + } else { + /* freq down */ + curr_wp++; + if (curr_wp >= dvfs_data->num_wp) { + curr_wp = dvfs_data->num_wp - 1; + goto END; + } + + rate = cpu_wp_tbl[curr_wp].cpu_rate; + uvol = cpu_wp_tbl[curr_wp].cpu_voltage; + if (curr_wp == dvfs_data->num_wp - 1) + minf = 1; + + ret = clk_set_rate(cpu_clk, rate); + if (ret != 0) { + printk(KERN_DEBUG + "cannot set CPU clock rate\n"); + goto END; + } + + /* START the GPC main control FSM */ + /* set VINC */ + reg = __raw_readl(dvfs_data->gpc_vcr_reg_addr); + reg &= + ~(MXC_GPCVCR_VINC_MASK | MXC_GPCVCR_VCNTU_MASK | + MXC_GPCVCR_VCNT_MASK); + reg |= + (1 << MXC_GPCVCR_VCNTU_OFFSET) | + (100 << MXC_GPCVCR_VCNT_OFFSET); + __raw_writel(reg, dvfs_data->gpc_vcr_reg_addr); + + /* Set the voltage for the GP domain. */ + ret = regulator_set_voltage(core_regulator, uvol, uvol); + if (ret < 0) { + printk(KERN_DEBUG + "COULD NOT SET CORE VOLTAGE!!!!!\n"); + goto END; + } + udelay(dvfs_data->delay_time); + } + } else { + if (curr_cpu == cpu_wp_tbl[0].cpu_rate) { + maxf = 1; + goto END; + } else { + /* freq up */ + curr_wp = 0; + rate = cpu_wp_tbl[curr_wp].cpu_rate; + /* START the GPC main control FSM */ + /* set VINC */ + reg = __raw_readl(dvfs_data->gpc_vcr_reg_addr); + reg &= + ~(MXC_GPCVCR_VINC_MASK | MXC_GPCVCR_VCNTU_MASK | + MXC_GPCVCR_VCNT_MASK); + reg |= + (1 << MXC_GPCVCR_VCNTU_OFFSET) | + (100 << MXC_GPCVCR_VCNT_OFFSET); + __raw_writel(reg, dvfs_data->gpc_vcr_reg_addr); + + ret = regulator_set_voltage(core_regulator, + cpu_wp_tbl[curr_wp].cpu_voltage, + cpu_wp_tbl[curr_wp].cpu_voltage); + if (ret < 0) { + printk(KERN_DEBUG + "COULD NOT SET CORE VOLTAGE!!!!\n"); + goto END; + } + udelay(dvfs_data->delay_time); + + ret = clk_set_rate(cpu_clk, cpu_wp_tbl[curr_wp].cpu_rate); + if (ret != 0) + printk(KERN_DEBUG + "cannot set CPU clock rate\n"); + maxf = 1; + } + } + +END: /* Set MAXF, MINF */ + reg = __raw_readl(dvfs_data->dvfs_cntr_reg_addr); + reg = (reg & ~(MXC_DVFSCNTR_MAXF_MASK | MXC_DVFSCNTR_MINF_MASK)); + reg |= maxf << MXC_DVFSCNTR_MAXF_OFFSET; + reg |= minf << MXC_DVFSCNTR_MINF_OFFSET; + + /* Enable FVFS interrupt */ + /* FSVAIM=0 */ + reg = (reg & ~MXC_DVFSCNTR_FSVAIM); + /* LBFL=1 */ + reg = (reg & ~MXC_DVFSCNTR_LBFL); + reg |= MXC_DVFSCNTR_LBFL; + __raw_writel(reg, dvfs_data->dvfs_cntr_reg_addr); +} + +/*! + * This function disables the DVFS module. + */ +static void stop_dvfs(void) +{ + u32 reg = 0; + unsigned long flags; + u32 curr_cpu; + + if (dvfs_core_is_active) { + spin_lock_irqsave(&mxc_dvfs_core_lock, flags); + + /* Mask dvfs irq, disable DVFS */ + reg = __raw_readl(dvfs_data->dvfs_cntr_reg_addr); + /* FSVAIM=1 */ + reg |= MXC_DVFSCNTR_FSVAIM; + reg = (reg & ~MXC_DVFSCNTR_DVFEN); + __raw_writel(reg, dvfs_data->dvfs_cntr_reg_addr); + + dvfs_core_is_active = 0; + spin_unlock_irqrestore(&mxc_dvfs_core_lock, flags); + + curr_wp = 0; + curr_cpu = clk_get_rate(cpu_clk); + if (curr_cpu != cpu_wp_tbl[curr_wp].cpu_rate) { + if (regulator_set_voltage(core_regulator, + cpu_wp_tbl[curr_wp].cpu_voltage, + cpu_wp_tbl[curr_wp].cpu_voltage) == 0) + clk_set_rate(cpu_clk, + cpu_wp_tbl[curr_wp].cpu_rate); + } + + clk_disable(dvfs_clk); + } + + printk(KERN_DEBUG "DVFS is stopped\n"); +} + +static ssize_t dvfs_enable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + if (dvfs_core_is_active) + return sprintf(buf, "DVFS is enabled\n"); + else + return sprintf(buf, "DVFS is disabled\n"); +} + + +static ssize_t dvfs_enable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + if (strstr(buf, "1") != NULL) { + if (start_dvfs() != 0) + printk(KERN_ERR "Failed to start DVFS\n"); + } else if (strstr(buf, "0") != NULL) + stop_dvfs(); + + return size; +} + +static DEVICE_ATTR(enable, 0644, dvfs_enable_show, dvfs_enable_store); + +/*! + * This is the probe routine for the DVFS driver. + * + * @param pdev The platform device structure + * + * @return The function returns 0 on success + */ +static int __devinit mxc_dvfs_core_probe(struct platform_device *pdev) +{ + int err = 0; + struct resource *res; + int cpu_wp_nr; + int irq; + + printk(KERN_INFO "mxc_dvfs_core_probe\n"); + dvfs_dev = &pdev->dev; + dvfs_data = pdev->dev.platform_data; + + INIT_DELAYED_WORK(&dvfs_core_work, dvfs_core_workqueue_handler); + + cpu_clk = clk_get(NULL, dvfs_data->clk1_id); + if (IS_ERR(cpu_clk)) { + printk(KERN_ERR "%s: failed to get cpu clock\n", __func__); + return PTR_ERR(cpu_clk); + } + + dvfs_clk = clk_get(NULL, dvfs_data->clk2_id); + if (IS_ERR(dvfs_clk)) { + printk(KERN_ERR "%s: failed to get dvfs clock\n", __func__); + return PTR_ERR(dvfs_clk); + } + + core_regulator = regulator_get(NULL, dvfs_data->reg_id); + if (IS_ERR(core_regulator)) { + clk_put(cpu_clk); + clk_put(dvfs_clk); + printk(KERN_ERR "%s: failed to get gp regulator\n", __func__); + return PTR_ERR(core_regulator); + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) { + err = -ENODEV; + goto err1; + } + + /* + * Request the DVFS interrupt + */ + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + err = irq; + goto err1; + } + + /* request the DVFS interrupt */ + err = request_irq(irq, dvfs_irq, IRQF_SHARED, "dvfs", dvfs_dev); + if (err) + printk(KERN_ERR + "DVFS: Unable to attach to DVFS interrupt,err = %d", + err); + + clk_enable(dvfs_clk); + err = init_dvfs_controller(); + if (err) { + printk(KERN_ERR "DVFS: Unable to initialize DVFS"); + return err; + } + clk_disable(dvfs_clk); + + err = sysfs_create_file(&dvfs_dev->kobj, &dev_attr_enable.attr); + if (err) { + printk(KERN_ERR + "DVFS: Unable to register sysdev entry for DVFS"); + return err; + } + + /* Set the current working point. */ + cpu_wp_tbl = get_cpu_wp(&cpu_wp_nr); + curr_wp = 0; + + return err; + +err1: + dev_err(&pdev->dev, "Failed to probe DVFS CORE\n"); + return err; +} + +/*! + * This function is called to put DPTC in a low power state. + * + * @param pdev the device structure + * @param state the power state the device is entering + * + * @return The function always returns 0. + */ +static int mxc_dvfs_core_suspend(struct platform_device *pdev, + pm_message_t state) +{ + if (dvfs_core_is_active) + stop_dvfs(); + + return 0; +} + +/*! + * This function is called to resume the MU from a low power state. + * + * @param dev the device structure + * @param level the stage in device suspension process that we want the + * device to be put in + * + * @return The function always returns 0. + */ +static int mxc_dvfs_core_resume(struct platform_device *pdev) +{ + if (dvfs_core_is_active) + start_dvfs(); + + return 0; +} + +static struct platform_driver mxc_dvfs_core_driver = { + .driver = { + .name = "mxc_dvfs_core", + }, + .probe = mxc_dvfs_core_probe, + .suspend = mxc_dvfs_core_suspend, + .resume = mxc_dvfs_core_resume, +}; + +static int __init dvfs_init(void) +{ + if (platform_driver_register(&mxc_dvfs_core_driver) != 0) { + printk(KERN_ERR "mxc_dvfs_core_driver register failed\n"); + return -ENODEV; + } + + printk(KERN_INFO "DVFS driver module loaded\n"); + + return 0; +} + +static void __exit dvfs_cleanup(void) +{ + stop_dvfs(); + + /* release the DVFS interrupt */ + free_irq(MXC_INT_GPC1, NULL); + + sysfs_remove_file(&dvfs_dev->kobj, &dev_attr_enable.attr); + + /* Unregister the device structure */ + platform_driver_unregister(&mxc_dvfs_core_driver); + + clk_put(cpu_clk); + clk_put(dvfs_clk); + + printk(KERN_INFO "DVFS driver module unloaded\n"); + +} + +module_init(dvfs_init); +module_exit(dvfs_cleanup); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("DVFS driver"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/arch/arm/plat-mxc/isp1504xc.c +++ linux-2.6.28/arch/arm/plat-mxc/isp1504xc.c @@ -0,0 +1,279 @@ +/* + * Copyright 2005-2009 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* ISP 1504 register addresses */ +#define ISP1504_VID_LOW 0x00 /* Vendor ID low */ +#define ISP1504_VID_HIGH 0x01 /* Vendor ID high */ +#define ISP1504_PID_LOW 0x02 /* Product ID low */ +#define ISP1504_PID_HIGH 0x03 /* Product ID high */ +#define ISP1504_FUNC 0x04 /* Function Control */ +#define ISP1504_ITFCTL 0x07 /* Interface Control */ +#define ISP1504_OTGCTL 0x0A /* OTG Control */ + +/* add to above register address to access Set/Clear functions */ +#define ISP1504_REG_SET 0x01 +#define ISP1504_REG_CLEAR 0x02 + +/* 1504 OTG Control Register bits */ +#define USE_EXT_VBUS_IND (1 << 7) /* Use ext. Vbus indicator */ +#define DRV_VBUS_EXT (1 << 6) /* Drive Vbus external */ +#define DRV_VBUS (1 << 5) /* Drive Vbus */ +#define CHRG_VBUS (1 << 4) /* Charge Vbus */ +#define DISCHRG_VBUS (1 << 3) /* Discharge Vbus */ +#define DM_PULL_DOWN (1 << 2) /* enable DM Pull Down */ +#define DP_PULL_DOWN (1 << 1) /* enable DP Pull Down */ +#define ID_PULL_UP (1 << 0) /* enable ID Pull Up */ + +/* 1504 OTG Function Control Register bits */ +#define SUSPENDM (1 << 6) /* places the PHY into + low-power mode */ +#define DRV_RESET (1 << 5) /* Active HIGH transceiver + reset */ + +/*! + * read ULPI register 'reg' thru VIEWPORT register 'view' + * + * @param reg register to read + * @param view the ULPI VIEWPORT register address + * @return return isp1504 register value + */ +static u8 isp1504_read(int reg, volatile u32 *view) +{ + u32 data; + + /* make sure interface is running */ + if (!(__raw_readl(view) && ULPIVW_SS)) { + __raw_writel(ULPIVW_WU, view); + do { /* wait for wakeup */ + data = __raw_readl(view); + } while (data & ULPIVW_WU); + } + + /* read the register */ + __raw_writel((ULPIVW_RUN | (reg << ULPIVW_ADDR_SHIFT)), view); + + do { /* wait for completion */ + data = __raw_readl(view); + } while (data & ULPIVW_RUN); + + return (u8) (data >> ULPIVW_RDATA_SHIFT) & ULPIVW_RDATA_MASK; +} + +/*! + * set bits into OTG ISP1504 register 'reg' thru VIEWPORT register 'view' + * + * @param bits set value + * @param reg which register + * @param view the ULPI VIEWPORT register address + */ +static void isp1504_set(u8 bits, int reg, volatile u32 *view) +{ + u32 data; + + /* make sure interface is running */ + if (!(__raw_readl(view) && ULPIVW_SS)) { + __raw_writel(ULPIVW_WU, view); + do { /* wait for wakeup */ + data = __raw_readl(view); + } while (data & ULPIVW_WU); + } + + __raw_writel((ULPIVW_RUN | ULPIVW_WRITE | + ((reg + ISP1504_REG_SET) << ULPIVW_ADDR_SHIFT) | + ((bits & ULPIVW_WDATA_MASK) << ULPIVW_WDATA_SHIFT)), + view); + + while (__raw_readl(view) & ULPIVW_RUN) /* wait for completion */ + continue; +} + +/*! + * clear bits in OTG ISP1504 register 'reg' thru VIEWPORT register 'view' + * + * @param bits bits to clear + * @param reg in this register + * @param view the ULPI VIEWPORT register address + */ +static void isp1504_clear(u8 bits, int reg, volatile u32 *view) +{ + __raw_writel((ULPIVW_RUN | ULPIVW_WRITE | + ((reg + ISP1504_REG_CLEAR) << ULPIVW_ADDR_SHIFT) | + ((bits & ULPIVW_WDATA_MASK) << ULPIVW_WDATA_SHIFT)), + view); + + while (__raw_readl(view) & ULPIVW_RUN) /* wait for completion */ + continue; +} + +extern int gpio_usbotg_hs_active(void); + +static void isp1508_fix(u32 *view) +{ + if (!machine_is_mx31_3ds()) + gpio_usbotg_hs_active(); + + /* Set bits IND_PASS_THRU and IND_COMPL */ + isp1504_set(0x60, ISP1504_ITFCTL, view); + + /* Set bit USE_EXT_VBUS_IND */ + isp1504_set(USE_EXT_VBUS_IND, ISP1504_OTGCTL, view); +} + +/*! + * set vbus power + * + * @param view viewport register + * @param on power on or off + */ +static void isp1504_set_vbus_power(struct fsl_xcvr_ops *this, + struct fsl_usb2_platform_data *pdata, int on) +{ + u32 *view = pdata->regs + ULPIVW_OFF; + + pr_debug("real %s(on=%d) view=0x%p\n", __FUNCTION__, on, view); + + pr_debug("ULPI Vendor ID 0x%x Product ID 0x%x\n", + (isp1504_read(ISP1504_VID_HIGH, view) << 8) | + isp1504_read(ISP1504_VID_LOW, view), + (isp1504_read(ISP1504_PID_HIGH, view) << 8) | + isp1504_read(ISP1504_PID_LOW, view)); + + pr_debug("OTG Control before=0x%x\n", + isp1504_read(ISP1504_OTGCTL, view)); + + if (on) { + isp1504_set(DRV_VBUS_EXT | /* enable external Vbus */ + DRV_VBUS | /* enable internal Vbus */ + USE_EXT_VBUS_IND | /* use external indicator */ + CHRG_VBUS, /* charge Vbus */ + ISP1504_OTGCTL, view); + + } else { + isp1508_fix(view); + + isp1504_clear(DRV_VBUS_EXT | /* disable external Vbus */ + DRV_VBUS, /* disable internal Vbus */ + ISP1504_OTGCTL, view); + + isp1504_set(USE_EXT_VBUS_IND | /* use external indicator */ + DISCHRG_VBUS, /* discharge Vbus */ + ISP1504_OTGCTL, view); + } + + pr_debug("OTG Control after = 0x%x\n", + isp1504_read(ISP1504_OTGCTL, view)); +} + +/*! + * set remote wakeup + * + * @param view viewport register + */ +static void isp1504_set_remote_wakeup(u32 * view) +{ + __raw_writel(~ULPIVW_WRITE & __raw_readl(view), view); + __raw_writel((1 << ULPIVW_PORT_SHIFT) | __raw_readl(view), view); + __raw_writel(ULPIVW_RUN | __raw_readl(view), view); + + while (__raw_readl(view) & ULPIVW_RUN) /* wait for completion */ + continue; +} + +static void isp1504_init(struct fsl_xcvr_ops *this) +{ + pr_debug("%s:\n", __FUNCTION__); +} + +static void isp1504_uninit(struct fsl_xcvr_ops *this) +{ + pr_debug("%s:\n", __FUNCTION__); +} + +static void isp1504_suspend(struct fsl_xcvr_ops *this) +{ + pr_debug("%s\n", __func__); + + /* send suspend command */ + isp1504_clear(SUSPENDM, ISP1504_FUNC, &UOG_ULPIVIEW); + pr_debug("%s.\n", __func__); +} + +/*! + * Set the 1504 transceiver to the proper mode for testing purposes. + * + * @param view the ULPI VIEWPORT register address + * @param test_mode Set the 1504 transceiver to disable bit stuffing and NRZI + */ + static void isp1504_set_test_mode(volatile u32 *view, enum usb_test_mode test_mode) +{ + if (test_mode == USB_TEST_J || test_mode == USB_TEST_K) { + printk(KERN_INFO "udc: disable bit stuffing and NRZI\n"); + /* Disable bit-stuffing and NRZI encoding. */ + isp1504_set(0x10, 0x04, view); + } +} + +static struct fsl_xcvr_ops isp1504_ops = { + .name = "isp1504", + .xcvr_type = PORTSC_PTS_ULPI, + .init = isp1504_init, + .uninit = isp1504_uninit, + .suspend = isp1504_suspend, + .set_vbus_power = isp1504_set_vbus_power, + .set_remote_wakeup = isp1504_set_remote_wakeup, + .set_test_mode = isp1504_set_test_mode, +}; + +extern void fsl_usb_xcvr_register(struct fsl_xcvr_ops *xcvr_ops); +extern int fsl_usb_xcvr_suspend(struct fsl_xcvr_ops *xcvr_ops); + +static int __init isp1504xc_init(void) +{ + pr_debug("%s\n", __FUNCTION__); + + fsl_usb_xcvr_register(&isp1504_ops); + + /* suspend isp1504 */ + if (fsl_usb_xcvr_suspend(&isp1504_ops)) + pr_debug("%s: failed to suspend isp1504\n", __func__); + + return 0; +} + +extern void fsl_usb_xcvr_unregister(struct fsl_xcvr_ops *xcvr_ops); + +static void __exit isp1504xc_exit(void) +{ + fsl_usb_xcvr_unregister(&isp1504_ops); +} + +module_init(isp1504xc_init); +module_exit(isp1504xc_exit); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("isp1504 xcvr driver"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/arch/arm/plat-mxc/usb_common.c +++ linux-2.6.28/arch/arm/plat-mxc/usb_common.c @@ -0,0 +1,783 @@ +/* + * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved. + * + * otg_{get,set}_transceiver() are from arm/plat-omap/usb.c. + * which is Copyright (C) 2004 Texas Instruments, Inc. + */ + +/* + * 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 + */ + +/*! + *@defgroup USB ARC OTG USB Driver + */ + +/*! + * @file usb_common.c + * + * @brief platform related part of usb driver. + * @ingroup USB + */ + +/*! + *Include files + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MXC_NUMBER_USB_TRANSCEIVER 6 +struct fsl_xcvr_ops *g_xc_ops[MXC_NUMBER_USB_TRANSCEIVER] = { NULL }; + +static struct clk *usb_clk; +static struct clk *usb_ahb_clk; + +extern int gpio_usbotg_hs_active(void); +extern int gpio_usbotg_hs_inactive(void); + +/* + * make sure USB_CLK is running at 60 MHz +/- 1000 Hz + */ +static int fsl_check_usbclk(void) +{ + unsigned long freq; + + usb_ahb_clk = clk_get(NULL, "usb_ahb_clk"); + if (clk_enable(usb_ahb_clk)) { + printk(KERN_ERR "clk_enable(usb_ahb_clk) failed\n"); + return -EINVAL; + } + clk_put(usb_ahb_clk); + + usb_clk = clk_get(NULL, "usb_clk"); + freq = clk_get_rate(usb_clk); + clk_put(usb_clk); + if ((freq < 59999000) || (freq > 60001000)) { + printk(KERN_ERR "USB_CLK=%lu, should be 60MHz\n", freq); + return -1; + } + + return 0; +} + +void fsl_usb_xcvr_register(struct fsl_xcvr_ops *xcvr_ops) +{ + int i; + + pr_debug("%s\n", __func__); + for (i = 0; i < MXC_NUMBER_USB_TRANSCEIVER; i++) { + if (g_xc_ops[i] == NULL) { + g_xc_ops[i] = xcvr_ops; + return; + } + } + + pr_debug("Failed %s\n", __func__); +} +EXPORT_SYMBOL(fsl_usb_xcvr_register); + +void fsl_platform_set_test_mode (struct fsl_usb2_platform_data *pdata, enum usb_test_mode mode) +{ + if (pdata->xcvr_ops && pdata->xcvr_ops->set_test_mode) + pdata->xcvr_ops->set_test_mode((u32 *)(pdata->regs + ULPIVW_OFF), mode); +} +EXPORT_SYMBOL(fsl_platform_set_test_mode); + +void fsl_usb_xcvr_unregister(struct fsl_xcvr_ops *xcvr_ops) +{ + int i; + + pr_debug("%s\n", __func__); + for (i = 0; i < MXC_NUMBER_USB_TRANSCEIVER; i++) { + if (g_xc_ops[i] == xcvr_ops) { + g_xc_ops[i] = NULL; + return; + } + } + + pr_debug("Failed %s\n", __func__); +} +EXPORT_SYMBOL(fsl_usb_xcvr_unregister); + +static struct fsl_xcvr_ops *fsl_usb_get_xcvr(char *name) +{ + int i; + + pr_debug("%s\n", __func__); + if (name == NULL) { + printk(KERN_ERR "get_xcvr(): No tranceiver name\n"); + return NULL; + } + + for (i = 0; i < MXC_NUMBER_USB_TRANSCEIVER; i++) { + if (strcmp(g_xc_ops[i]->name, name) == 0) { + return g_xc_ops[i]; + } + } + pr_debug("Failed %s\n", __func__); + return NULL; +} + +/* The dmamask must be set for EHCI to work */ +static u64 ehci_dmamask = ~(u32) 0; + +/*! + * Register an instance of a USB host platform device. + * + * @param res: resource pointer + * @param n_res: number of resources + * @param config: config pointer + * + * @return newly-registered platform_device + * + * The USB controller supports 3 host interfaces, and the + * kernel can be configured to support some number of them. + * Each supported host interface is registered as an instance + * of the "fsl-ehci" device. Call this function multiple times + * to register each host interface. + */ +static int instance_id = 0; +struct platform_device *host_pdev_register(struct resource *res, int n_res, + struct fsl_usb2_platform_data *config) +{ + struct platform_device *pdev; + int rc; + + pr_debug("register host res=0x%p, size=%d\n", res, n_res); + + pdev = platform_device_register_simple("fsl-ehci", + instance_id, res, n_res); + if (IS_ERR(pdev)) { + pr_debug("can't register %s Host, %ld\n", + config->name, PTR_ERR(pdev)); + return NULL; + } + + pdev->dev.coherent_dma_mask = 0xffffffff; + pdev->dev.dma_mask = &ehci_dmamask; + + /* + * platform_device_add_data() makes a copy of + * the platform_data passed in. That makes it + * impossible to share the same config struct for + * all OTG devices (host,gadget,otg). So, just + * set the platorm_data pointer ourselves. + */ + rc = platform_device_add_data(pdev, config, + sizeof(struct fsl_usb2_platform_data)); + if (rc) { + platform_device_unregister(pdev); + return NULL; + } + + printk(KERN_INFO "usb: %s host (%s) registered\n", config->name, + config->transceiver); + pr_debug("pdev=0x%p dev=0x%p resources=0x%p pdata=0x%p\n", + pdev, &pdev->dev, pdev->resource, pdev->dev.platform_data); + + instance_id++; + + return pdev; +} + +/* DDD looks like this is needed by Belcarra code */ +void fsl_platform_set_vbus_power(struct fsl_usb2_platform_data *pdata, int on) +{ + if (pdata->xcvr_ops && pdata->xcvr_ops->set_vbus_power) + pdata->xcvr_ops->set_vbus_power(pdata->xcvr_ops, pdata, on); +} +EXPORT_SYMBOL(fsl_platform_set_vbus_power); + +/* DDD looks like this is needed by Belcarra code */ +void fsl_platform_perform_remote_wakeup(struct fsl_usb2_platform_data *pdata) +{ + if (pdata->xcvr_ops && pdata->xcvr_ops->set_remote_wakeup) + pdata->xcvr_ops->set_remote_wakeup( + (u32 *)(pdata->regs + ULPIVW_OFF)); +} +EXPORT_SYMBOL(fsl_platform_perform_remote_wakeup); + +#if defined(CONFIG_USB_OTG) +static struct otg_transceiver *xceiv; + +/** + * otg_get_transceiver - find the (single) OTG transceiver driver + * + * Returns the transceiver driver, after getting a refcount to it; or + * null if there is no such transceiver. The caller is responsible for + * releasing that count. + */ +struct otg_transceiver *otg_get_transceiver(void) +{ + pr_debug("%s xceiv=0x%p\n", __func__, xceiv); + if (xceiv) + get_device(xceiv->dev); + return xceiv; +} +EXPORT_SYMBOL(otg_get_transceiver); + +int otg_set_transceiver(struct otg_transceiver *x) +{ + pr_debug("%s xceiv=0x%p x=0x%p\n", __func__, xceiv, x); + if (xceiv && x) + return -EBUSY; + xceiv = x; + return 0; +} +EXPORT_SYMBOL(otg_set_transceiver); + +static struct resource *otg_resources; + +struct resource *otg_get_resources(void) +{ + return otg_resources; +} +EXPORT_SYMBOL(otg_get_resources); + +int otg_set_resources(struct resource *resources) +{ + otg_resources = resources; + return 0; +} +EXPORT_SYMBOL(otg_set_resources); +#endif + +static void usbh1_set_serial_xcvr(void) +{ + pr_debug("%s: \n", __func__); + USBCTRL &= ~(UCTRL_H1SIC_MASK | UCTRL_BPE); /* disable bypass mode */ + USBCTRL |= UCTRL_H1SIC_SU6 | /* single-ended / unidir. */ + UCTRL_H1WIE | UCTRL_H1DT | /* disable H1 TLL */ + UCTRL_H1PM; /* power mask */ +} + +static void usbh1_set_ulpi_xcvr(void) +{ + pr_debug("%s: \n", __func__); + + /* Stop then Reset */ + UH1_USBCMD &= ~UCMD_RUN_STOP; + while (UH1_USBCMD & UCMD_RUN_STOP) ; + + UH1_USBCMD |= UCMD_RESET; + while (UH1_USBCMD & UCMD_RESET) ; + + /* Select the clock from external PHY */ + USB_CTRL_1 |= USB_CTRL_UH1_EXT_CLK_EN; + + /* select ULPI PHY PTS=2 */ + UH1_PORTSC1 = (UH1_PORTSC1 & ~PORTSC_PTS_MASK) | PORTSC_PTS_ULPI; + + USBCTRL |= UCTRL_H1WIE; /* HOST1 wakeup intr enable */ + USBCTRL |= UCTRL_H1UIE; /* Host1 ULPI interrupt enable */ + USBCTRL &= ~UCTRL_H1PM; /* HOST1 power mask */ + + /* Interrupt Threshold Control:Immediate (no threshold) */ + UH1_USBCMD &= UCMD_ITC_NO_THRESHOLD; + + UH1_USBCMD |= UCMD_RESET; /* reset the controller */ + + /* allow controller to reset, and leave time for + * the ULPI transceiver to reset too. + */ + msleep(100); + + /* Turn off the usbpll for ulpi tranceivers */ + clk_disable(usb_clk); +} +static void usbh2_set_ulpi_xcvr(void) +{ + u32 tmp; + + pr_debug("%s\n", __func__); + USBCTRL &= ~(UCTRL_H2SIC_MASK | UCTRL_BPE); + USBCTRL |= UCTRL_H2WIE | /* wakeup intr enable */ + UCTRL_H2UIE | /* ULPI intr enable */ + UCTRL_H2DT | /* disable H2 TLL */ + UCTRL_H2PM; /* power mask */ + + /* must set ULPI phy before turning off clock */ + tmp = UH2_PORTSC1 & ~PORTSC_PTS_MASK; + tmp |= PORTSC_PTS_ULPI; + UH2_PORTSC1 = tmp; + + UH2_USBCMD |= UCMD_RESET; /* reset the controller */ + + /* allow controller to reset, and leave time for + * the ULPI transceiver to reset too. + */ + msleep(100); + + /* Turn off the usbpll for ulpi tranceivers */ + clk_disable(usb_clk); +} + +static void usbh2_set_serial_xcvr(void) +{ + pr_debug("%s: \n", __func__); + + /* Stop then Reset */ + UH2_USBCMD &= ~UCMD_RUN_STOP; + while (UH2_USBCMD & UCMD_RUN_STOP) ; + + UH2_USBCMD |= UCMD_RESET; + while (UH2_USBCMD & UCMD_RESET) ; + + USBCTRL &= ~(UCTRL_H2SIC_MASK); /* Disable bypass mode */ + USBCTRL &= ~(UCTRL_H2PM); /* Power Mask */ + USBCTRL &= ~UCTRL_H2OCPOL; /* OverCurrent Polarity is Low Active */ + USBCTRL |= UCTRL_H2WIE | /* Wakeup intr enable */ + UCTRL_IP_PUE_DOWN | /* ipp_pue_pulldwn_dpdm */ + UCTRL_USBTE | /* USBT is enabled */ + UCTRL_H2DT; /* Disable H2 TLL */ + + if (cpu_is_mx35_rev(CHIP_REV_2_0) < 0) { + /* Disable Host2 bus Lock for i.MX35 1.0 */ + USBCTRL |= UCTRL_H2LOCKD; + /* USBOTG_PWR low active */ + USBCTRL &= ~UCTRL_PP; + /* OverCurrent Polarity is Low Active */ + USBCTRL &= ~UCTRL_OCPOL; + } else if (cpu_is_mx35_rev(CHIP_REV_2_0) >= 1) { + /* i.MX35 2.0 OTG and Host2 have seperate OC/PWR polarity */ + USBCTRL &= ~UCTRL_H2PP; + USBCTRL &= ~UCTRL_H2OCPOL; + } else if (cpu_is_mx25()) { + /* + * USBH2_PWR and USBH2_OC are active high. + * Must force xcvr clock to "internal" so that + * we can write to PTS field after it's been + * cleared by ehci_turn_off_all_ports(). + */ + USBCTRL |= UCTRL_H2PP | UCTRL_H2OCPOL | UCTRL_XCSH2; + /* Disable Host2 bus Lock */ + USBCTRL |= UCTRL_H2LOCKD; + } + + USBCTRL &= ~(UCTRL_PP); + UH2_PORTSC1 = (UH2_PORTSC1 & (~PORTSC_PTS_MASK)) | PORTSC_PTS_SERIAL; + + if (UH2_HCSPARAMS & HCSPARAMS_PPC) + UH2_PORTSC1 |= PORTSC_PORT_POWER; + + /* Reset controller before set host mode */ + UH2_USBCMD |= UCMD_RESET; + while (UH2_USBCMD & UCMD_RESET) ; + + msleep(100); +} + +extern void gpio_usbh1_setback_stp(void); +extern void gpio_usbh2_setback_stp(void); + +int fsl_usb_host_init(struct platform_device *pdev) +{ + struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; + struct fsl_xcvr_ops *xops; + + pr_debug("%s: pdev=0x%p pdata=0x%p\n", __func__, pdev, pdata); + + xops = fsl_usb_get_xcvr(pdata->transceiver); + if (!xops) { + printk(KERN_ERR "%s transceiver ops missing\n", pdata->name); + return -EINVAL; + } + pdata->xcvr_ops = xops; + pdata->xcvr_type = xops->xcvr_type; + pdata->pdev = pdev; + + if (fsl_check_usbclk() != 0) + return -EINVAL; + + pr_debug("%s: grab pins\n", __func__); + if (pdata->gpio_usb_active()) + return -EINVAL; + + if (clk_enable(usb_clk)) { + printk(KERN_ERR "clk_enable(usb_clk) failed\n"); + return -EINVAL; + } + + if (cpu_is_mx51()) { + usb_clk = clk_get(NULL, "usboh3_clk"); + clk_enable(usb_clk); + clk_put(usb_clk); + } + + /* enable board power supply for xcvr */ + if (pdata->xcvr_pwr) { + if (pdata->xcvr_pwr->regu1) + regulator_enable(pdata->xcvr_pwr->regu1); + if (pdata->xcvr_pwr->regu2) + regulator_enable(pdata->xcvr_pwr->regu2); + } + + if (xops->init) + xops->init(xops); + + if (xops->xcvr_type == PORTSC_PTS_SERIAL) { + if (cpu_is_mx35()) { + usbh2_set_serial_xcvr(); + /* Close the internal 60Mhz */ + USBCTRL &= ~UCTRL_XCSH2; + } else if (cpu_is_mx25()) + usbh2_set_serial_xcvr(); + else + usbh1_set_serial_xcvr(); + } else if (xops->xcvr_type == PORTSC_PTS_ULPI) { + if (cpu_is_mx51()) { +#ifdef CONFIG_USB_EHCI_ARC_H1 + if (pdata->name == "Host 1") { + usbh1_set_ulpi_xcvr(); + if (cpu_is_mx51()) + gpio_usbh1_setback_stp(); + } +#endif +#ifdef CONFIG_USB_EHCI_ARC_H2 + if (pdata->name == "Host 2") { + usbh2_set_ulpi_xcvr(); + if (cpu_is_mx51()) + gpio_usbh2_setback_stp(); + } +#endif + } else + usbh2_set_ulpi_xcvr(); + } + + pr_debug("%s: %s success\n", __func__, pdata->name); + return 0; +} +EXPORT_SYMBOL(fsl_usb_host_init); + +void fsl_usb_host_uninit(struct fsl_usb2_platform_data *pdata) +{ + pr_debug("%s\n", __func__); + + if (pdata->xcvr_ops && pdata->xcvr_ops->uninit) + pdata->xcvr_ops->uninit(pdata->xcvr_ops); + + pdata->regs = NULL; + + pdata->gpio_usb_inactive(); + if (pdata->xcvr_type == PORTSC_PTS_SERIAL) { + /* Workaround an IC issue for 2.6.26 kernal: + * when turn off root hub port power, EHCI set + * PORTSC reserved bits to be 0, but PTS with 0 + * means UTMI interface, so here force the Host2 + * port use the internal 60Mhz. + */ + if (cpu_is_mx35()) + USBCTRL |= UCTRL_XCSH2; + clk_disable(usb_clk); + } + + /* disable board power supply for xcvr */ + if (pdata->xcvr_pwr) { + if (pdata->xcvr_pwr->regu1) + regulator_disable(pdata->xcvr_pwr->regu1); + if (pdata->xcvr_pwr->regu2) + regulator_disable(pdata->xcvr_pwr->regu2); + } + + if (cpu_is_mx51()) { + usb_clk = clk_get(NULL, "usboh3_clk"); + clk_disable(usb_clk); + clk_put(usb_clk); + } +} +EXPORT_SYMBOL(fsl_usb_host_uninit); + +static void otg_set_serial_xcvr(void) +{ + pr_debug("%s\n", __func__); +} + +void otg_set_serial_host(void) +{ + pr_debug("%s\n", __func__); + /* set USBCTRL for host operation + * disable: bypass mode, + * set: single-ended/unidir/6 wire, OTG wakeup intr enable, + * power mask + */ + USBCTRL &= ~UCTRL_OSIC_MASK; +#if defined(CONFIG_ARCH_MX27) || defined(CONFIG_ARCH_MX3) + USBCTRL &= ~UCTRL_BPE; +#endif + +#if defined(CONFIG_MXC_USB_SB3) + USBCTRL |= UCTRL_OSIC_SB3 | UCTRL_OWIE | UCTRL_OPM; +#elif defined(CONFIG_MXC_USB_SU6) + USBCTRL |= UCTRL_OSIC_SU6 | UCTRL_OWIE | UCTRL_OPM; +#elif defined(CONFIG_MXC_USB_DB4) + USBCTRL |= UCTRL_OSIC_DB4 | UCTRL_OWIE | UCTRL_OPM; +#else + USBCTRL |= UCTRL_OSIC_DU6 | UCTRL_OWIE | UCTRL_OPM; +#endif + + USB_OTG_MIRROR = OTGM_VBUSVAL | OTGM_ASESVLD; /* 0xa */ +} +EXPORT_SYMBOL(otg_set_serial_host); + +void otg_set_serial_peripheral(void) +{ + /* set USBCTRL for device operation + * disable: bypass mode + * set: differential/unidir/6 wire, OTG wakeup intr enable, + * power mask + */ + USBCTRL &= ~UCTRL_OSIC_MASK; +#if defined(CONFIG_ARCH_MX27) || defined(CONFIG_ARCH_MX3) + USBCTRL &= ~UCTRL_BPE; +#endif + +#if defined(CONFIG_MXC_USB_SB3) + USBCTRL |= UCTRL_OSIC_SB3 | UCTRL_OWIE | UCTRL_OPM; +#elif defined(CONFIG_MXC_USB_SU6) + USBCTRL |= UCTRL_OSIC_SU6 | UCTRL_OWIE | UCTRL_OPM; +#elif defined(CONFIG_MXC_USB_DB4) + USBCTRL |= UCTRL_OSIC_DB4 | UCTRL_OWIE | UCTRL_OPM; +#else + USBCTRL |= UCTRL_OSIC_DU6 | UCTRL_OWIE | UCTRL_OPM; +#endif + + USB_OTG_MIRROR = OTGM_VBUSVAL | OTGM_BSESVLD | OTGM_IDIDG; /* oxd */ +} +EXPORT_SYMBOL(otg_set_serial_peripheral); + +static void otg_set_ulpi_xcvr(void) +{ + u32 tmp; + + pr_debug("%s\n", __func__); + USBCTRL &= ~UCTRL_OSIC_MASK; +#if defined(CONFIG_ARCH_MX27) || defined(CONFIG_ARCH_MX3) + USBCTRL &= ~UCTRL_BPE; +#endif + USBCTRL |= UCTRL_OUIE | /* ULPI intr enable */ + UCTRL_OWIE | /* OTG wakeup intr enable */ + UCTRL_OPM; /* power mask */ + + /* must set ULPI phy before turning off clock */ + tmp = UOG_PORTSC1 & ~PORTSC_PTS_MASK; + tmp |= PORTSC_PTS_ULPI; + UOG_PORTSC1 = tmp; + + /* need to reset the controller here so that the ID pin + * is correctly detected. + */ + UOG_USBCMD |= UCMD_RESET; + + /* allow controller to reset, and leave time for + * the ULPI transceiver to reset too. + */ + msleep(100); + + /* Turn off the usbpll for ulpi tranceivers */ + clk_disable(usb_clk); +} + +int fsl_usb_xcvr_suspend(struct fsl_xcvr_ops *xcvr_ops) +{ + if (!machine_is_mx31_3ds()) + return -ECANCELED; + + if (xcvr_ops->xcvr_type == PORTSC_PTS_ULPI) { + if (fsl_check_usbclk() != 0) + return -EINVAL; + if (gpio_usbotg_hs_active()) + return -EINVAL; + clk_enable(usb_clk); + + otg_set_ulpi_xcvr(); + + if (xcvr_ops->suspend) + /* suspend transceiver */ + xcvr_ops->suspend(xcvr_ops); + + gpio_usbotg_hs_inactive(); + clk_disable(usb_clk); + } + return 0; +} +EXPORT_SYMBOL(fsl_usb_xcvr_suspend); + +static void otg_set_utmi_xcvr(void) +{ + u32 tmp; + + /* Stop then Reset */ + UOG_USBCMD &= ~UCMD_RUN_STOP; + while (UOG_USBCMD & UCMD_RUN_STOP) ; + + UOG_USBCMD |= UCMD_RESET; + while ((UOG_USBCMD) & (UCMD_RESET)) ; + + if (cpu_is_mx51()) { + /* OTG Polarity of Overcurrent is Low active */ + USB_PHY_CTR_FUNC |= USB_UTMI_PHYCTRL_OC_POL; + /* Enable OTG Overcurrent Event */ + USB_PHY_CTR_FUNC &= ~USB_UTMI_PHYCTRL_OC_DIS; + } else if (cpu_is_mx25()) { + USBCTRL |= UCTRL_OCPOL; + USBCTRL &= ~UCTRL_PP; + } else { + /* USBOTG_PWR low active */ + USBCTRL &= ~UCTRL_PP; + /* OverCurrent Polarity is Low Active */ + USBCTRL &= ~UCTRL_OCPOL; + + if (cpu_is_mx35_rev(CHIP_REV_2_0) < 0) + /* OTG Lock Disable */ + USBCTRL |= UCTRL_OLOCKD; + } + + USBCTRL &= ~UCTRL_OPM; /* OTG Power Mask */ + USBCTRL |= UCTRL_OWIE; /* OTG Wakeup Intr Enable */ + + /* set UTMI xcvr */ + tmp = UOG_PORTSC1 & ~PORTSC_PTS_MASK; + tmp |= PORTSC_PTS_UTMI; + UOG_PORTSC1 = tmp; + + if (cpu_is_mx51()) { + /* Set the PHY clock to 19.2MHz */ + USB_PHY_CTR_FUNC2 &= ~USB_UTMI_PHYCTRL2_PLLDIV_MASK; + USB_PHY_CTR_FUNC2 |= 0x01; + } + if (!cpu_is_mx25()) { + /* Workaround an IC issue for 2.6.26 kernal: + * when turn off root hub port power, EHCI set + * PORTSC reserved bits to be 0, but PTW with 0 + * means 8 bits tranceiver width, here change + * it back to be 16 bits and do PHY diable and + * then enable. + */ + UOG_PORTSC1 |= PORTSC_PTW; + + /* Enable UTMI interface in PHY control Reg */ + USB_PHY_CTR_FUNC &= ~USB_UTMI_PHYCTRL_UTMI_ENABLE; + USB_PHY_CTR_FUNC |= USB_UTMI_PHYCTRL_UTMI_ENABLE; + } + + if (UOG_HCSPARAMS & HCSPARAMS_PPC) + UOG_PORTSC1 |= PORTSC_PORT_POWER; + + /* need to reset the controller here so that the ID pin + * is correctly detected. + */ + /* Stop then Reset */ + UOG_USBCMD &= ~UCMD_RUN_STOP; + while (UOG_USBCMD & UCMD_RUN_STOP) ; + + UOG_USBCMD |= UCMD_RESET; + while ((UOG_USBCMD) & (UCMD_RESET)) ; + + /* allow controller to reset, and leave time for + * the ULPI transceiver to reset too. + */ + msleep(100); + + /* Turn off the usbpll for mx25 UTMI tranceivers */ + /* DDD: can we do this UTMI xcvrs on all boards? */ + if (cpu_is_mx25()) + clk_disable(usb_clk); +} + +static int otg_used = 0; + +int usbotg_init(struct platform_device *pdev) +{ + struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; + struct fsl_xcvr_ops *xops; + + pr_debug("%s: pdev=0x%p pdata=0x%p\n", __func__, pdev, pdata); + + xops = fsl_usb_get_xcvr(pdata->transceiver); + if (!xops) { + printk(KERN_ERR "DR transceiver ops missing\n"); + return -EINVAL; + } + pdata->xcvr_ops = xops; + pdata->xcvr_type = xops->xcvr_type; + pdata->pdev = pdev; + + if (!otg_used) { + if (fsl_check_usbclk() != 0) + return -EINVAL; + + pr_debug("%s: grab pins\n", __func__); + if (pdata->gpio_usb_active()) + return -EINVAL; + + if (clk_enable(usb_clk)) { + printk(KERN_ERR "clk_enable(usb_clk) failed\n"); + return -EINVAL; + } + + if (xops->init) + xops->init(xops); + + if (xops->xcvr_type == PORTSC_PTS_SERIAL) { + if (pdata->operating_mode == FSL_USB2_DR_HOST) { + otg_set_serial_host(); + /* need reset */ + UOG_USBCMD |= UCMD_RESET; + msleep(100); + } else if (pdata->operating_mode == FSL_USB2_DR_DEVICE) + otg_set_serial_peripheral(); + otg_set_serial_xcvr(); + } else if (xops->xcvr_type == PORTSC_PTS_ULPI) { + otg_set_ulpi_xcvr(); + } else if (xops->xcvr_type == PORTSC_PTS_UTMI) { + otg_set_utmi_xcvr(); + } + } + + otg_used++; + pr_debug("%s: success\n", __func__); + return 0; +} +EXPORT_SYMBOL(usbotg_init); + +void usbotg_uninit(struct fsl_usb2_platform_data *pdata) +{ + pr_debug("%s\n", __func__); + + otg_used--; + if (!otg_used) { + if (pdata->xcvr_ops && pdata->xcvr_ops->uninit) + pdata->xcvr_ops->uninit(pdata->xcvr_ops); + + pdata->regs = NULL; + + if (machine_is_mx31_3ds()) { + if (pdata->xcvr_ops && pdata->xcvr_ops->suspend) + pdata->xcvr_ops->suspend(pdata->xcvr_ops); + clk_disable(usb_clk); + } + + pdata->gpio_usb_inactive(); + if (pdata->xcvr_type == PORTSC_PTS_SERIAL) + clk_disable(usb_clk); + } +} +EXPORT_SYMBOL(usbotg_uninit); --- linux-2.6.28.orig/arch/arm/plat-mxc/Kconfig +++ linux-2.6.28/arch/arm/plat-mxc/Kconfig @@ -16,10 +16,16 @@ help This enables support for systems based on the Freescale i.MX3 family +config ARCH_MX51 + bool "MX51-based" + help + This enables support for systems based on Freescale i.MX51 + endchoice source "arch/arm/mach-mx2/Kconfig" source "arch/arm/mach-mx3/Kconfig" +source "arch/arm/mach-mx51/Kconfig" endmenu @@ -34,4 +40,39 @@ requirements for timing. Say N here, unless you have a specialized requirement. +config MXC_TZIC + bool + depends on ARCH_MXC + +config DMA_ZONE_SIZE + int "DMA memory zone size" + range 0 64 + default 24 + help + This is the size in MB for the DMA zone. The DMA zone is used for + dedicated memory for large contiguous video buffers + +# set iff we need the 1504 transceiver code +config ISP1504_MXC + bool + select ISP1504_MXC_OTG if USB_GADGET && USB_EHCI_HCD && USB_OTG + default y if USB_EHCI_FSL_1504 || USB_GADGET_FSL_1504 + +config ISP1504_MXC_OTG + tristate + help + Support for USB OTG pin detect using the ISP1504 transceiver on MXC platforms. + +# set iff we need the UTMI transceiver code +config UTMI_MXC + bool + select UTMI_MXC_OTG if ARCH_MX25 && USB_GADGET && USB_EHCI_HCD && USB_OTG + default y if USB_EHCI_FSL_UTMI || USB_GADGET_FSL_UTMI + depends on ARCH_MX51 + +config UTMI_MXC_OTG + tristate + help + Support for USB OTG pin detect using the UTMI transceiver on MXC platforms. + endif --- linux-2.6.28.orig/arch/arm/plat-mxc/spba.c +++ linux-2.6.28/arch/arm/plat-mxc/spba.c @@ -0,0 +1,133 @@ +/* + * Copyright 2004-2009 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 + */ + +#include +#include +#include +#include +#include +#include + +/*! + * @file plat-mxc/spba.c + * + * @brief This file contains the SPBA API implementation details. + * + * @ingroup SPBA + */ + +static DEFINE_SPINLOCK(spba_lock); + +#define SPBA_MASTER_MIN 1 +#define SPBA_MASTER_MAX 7 + +/*! + * the base addresses for the SPBA modules + */ +static unsigned long spba_base = (unsigned long)IO_ADDRESS(SPBA_CTRL_BASE_ADDR); + +/*! + * SPBA clock + */ +static struct clk *spba_clk; +/*! + * This function allows the three masters (A, B, C) to take ownership of a + * shared peripheral. + * + * @param mod specified module as defined in \b enum \b #spba_module + * @param master one of more (or-ed together) masters as defined in \b enum \b #spba_masters + * + * @return 0 if successful; -1 otherwise. + */ +int spba_take_ownership(int mod, int master) +{ + unsigned long spba_flags; + __u32 rtn_val = -1; + + if (master < SPBA_MASTER_MIN || master > SPBA_MASTER_MAX) { + printk("spba_take_ownership() invalide master= %d\n", master); + BUG(); /* oops */ + } + + if (spba_clk == NULL) + spba_clk = clk_get(NULL, "spba_clk"); + + clk_enable(spba_clk); + + spin_lock_irqsave(&spba_lock, spba_flags); + __raw_writel(master, spba_base + mod); + + if ((__raw_readl(spba_base + mod) & MXC_SPBA_RAR_MASK) == master) { + rtn_val = 0; + } + + spin_unlock_irqrestore(&spba_lock, spba_flags); + + clk_disable(spba_clk); + return rtn_val; +} + +/*! + * This function releases the ownership for a shared peripheral. + * + * @param mod specified module as defined in \b enum \b #spba_module + * @param master one of more (or-ed together) masters as defined in \b enum \b #spba_masters + * + * @return 0 if successful; -1 otherwise. + */ +int spba_rel_ownership(int mod, int master) +{ + unsigned long spba_flags; + volatile unsigned long rar; + + if (master < SPBA_MASTER_MIN || master > SPBA_MASTER_MAX) { + printk("spba_take_ownership() invalide master= %d\n", master); + BUG(); /* oops */ + } + + if (spba_clk == NULL) + spba_clk = clk_get(NULL, "spba_clk"); + + clk_enable(spba_clk); + + if ((__raw_readl(spba_base + mod) & master) == 0) { + clk_disable(spba_clk); + return 0; /* does not own it */ + } + + spin_lock_irqsave(&spba_lock, spba_flags); + + /* Since only the last 3 bits are writeable, doesn't need to mask off + bits 31-3 */ + rar = __raw_readl(spba_base + mod) & (~master); + __raw_writel(rar, spba_base + mod); + + if ((__raw_readl(spba_base + mod) & master) != 0) { + spin_unlock_irqrestore(&spba_lock, spba_flags); + clk_disable(spba_clk); + return -1; + } + + spin_unlock_irqrestore(&spba_lock, spba_flags); + + clk_disable(spba_clk); + + return 0; +} + +EXPORT_SYMBOL(spba_take_ownership); +EXPORT_SYMBOL(spba_rel_ownership); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("SPBA"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/arch/arm/plat-mxc/utmixc.c +++ linux-2.6.28/arch/arm/plat-mxc/utmixc.c @@ -0,0 +1,117 @@ +/* + * Copyright 2005-2009 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static void usb_utmi_init(struct fsl_xcvr_ops *this) +{ +} + +static void usb_utmi_uninit(struct fsl_xcvr_ops *this) +{ +} + +/*! + * set vbus power + * + * @param view viewport register + * @param on power on or off + */ +static void set_power(struct fsl_xcvr_ops *this, + struct fsl_usb2_platform_data *pdata, int on) +{ + struct device *dev = &pdata->pdev->dev; + struct regulator *usbotg_regux; + + pr_debug("real %s(on=%d) pdata=0x%p\n", __func__, on, pdata); + if (machine_is_mx37_3ds()) { + if (!board_is_mx37(BOARD_REV_2)) + usbotg_regux = regulator_get(dev, "DCDC2"); + else + usbotg_regux = regulator_get(dev, "SWBST"); + if (on) { + regulator_enable(usbotg_regux); + } else { + regulator_disable(usbotg_regux); + } +#if defined(CONFIG_MXC_PMIC_MC13892_MODULE) || defined(CONFIG_MXC_PMIC_MC13892) + } else if (machine_is_mx51_3ds()) { + unsigned int value; + + usbotg_regux = regulator_get(dev, "SWBST"); + if (on) + regulator_enable(usbotg_regux); + else + regulator_disable(usbotg_regux); + + /* VUSBIN */ + pmic_read_reg(REG_USB1, &value, 0xffffff); + if (on) + value |= 0x1; + else + value &= ~0x1; + pmic_write_reg(REG_USB1, value, 0xffffff); + + /* VUSBEN */ + usbotg_regux = regulator_get(dev, "VUSB"); + if (on) + regulator_enable(usbotg_regux); + else + regulator_disable(usbotg_regux); +#endif + } +} + +static struct fsl_xcvr_ops utmi_ops = { + .name = "utmi", + .xcvr_type = PORTSC_PTS_UTMI, + .init = usb_utmi_init, + .uninit = usb_utmi_uninit, + .set_vbus_power = set_power, +}; + +extern void fsl_usb_xcvr_register(struct fsl_xcvr_ops *xcvr_ops); + +static int __init utmixc_init(void) +{ + fsl_usb_xcvr_register(&utmi_ops); + return 0; +} + +extern void fsl_usb_xcvr_unregister(struct fsl_xcvr_ops *xcvr_ops); + +static void __exit utmixc_exit(void) +{ + fsl_usb_xcvr_unregister(&utmi_ops); +} + +module_init(utmixc_init); +module_exit(utmixc_exit); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("utmi xcvr driver"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/arch/arm/plat-mxc/Makefile +++ linux-2.6.28/arch/arm/plat-mxc/Makefile @@ -3,6 +3,36 @@ # # Common support -obj-y := irq.o clock.o gpio.o time.o devices.o +obj-y := cpu_common.o gpio.o clock.o wdog.o snoop.o io.o time.o obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.o + +ifeq ($(CONFIG_MXC_TZIC),y) +obj-y += tzic.o +else +obj-y += irq.o +endif + +obj-$(CONFIG_ARCH_MX51) += usb_common.o utmixc.o dvfs_core.o spba.o sdma/ + +# CPU FREQ support +obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o + +# USB support +obj-$(CONFIG_ISP1504_MXC) += isp1504xc.o + +# obj-$(CONFIG_USB_EHCI_FSL_UTMI) += utmixc.o +ifneq ($(strip $(CONFIG_USB_EHCI_FSL_UTMI) $(CONFIG_USB_GADGET_FSL_UTMI)),) +obj-y += utmixc.o +endif + +ifneq ($(CONFIG_USB_EHCI_ARC_H1)$(CONFIG_USB_EHCI_ARC_H2),) +ifeq ($(CONFIG_ARCH_MX51),y) +obj-y += isp1504xc.o +endif +endif + +ifeq ($(CONFIG_USB),y) +obj-y += usb_common.o +endif + --- linux-2.6.28.orig/arch/arm/plat-mxc/wdog.c +++ linux-2.6.28/arch/arm/plat-mxc/wdog.c @@ -0,0 +1,67 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @file plat-mxc/wdog.c + * @brief This file contains watchdog timer implementations. + * + * This file contains watchdog timer implementations for timer tick. + * + * @ingroup WDOG + */ + +#include +#include +#include +#include +#include +#include + +#define WDOG_WT 0x8 /* WDOG WT starting bit inside WCR */ +#define WCR_WOE_BIT (1 << 6) +#define WCR_WDA_BIT (1 << 5) +#define WCR_SRS_BIT (1 << 4) +#define WCR_WRE_BIT (1 << 3) +#define WCR_WDE_BIT (1 << 2) +#define WCR_WDBG_BIT (1 << 1) +#define WCR_WDZST_BIT (1 << 0) + +/* + * WatchDog + */ +#define WDOG_WCR 0 /* 16bit watchdog control reg */ +#define WDOG_WSR 2 /* 16bit watchdog service reg */ +#define WDOG_WRSR 4 /* 16bit watchdog reset status reg */ + +/*! + * The base addresses for the WDOG modules + */ +static unsigned long wdog_base[2] = { + IO_ADDRESS(WDOG1_BASE_ADDR), +#ifdef WDOG2_BASE_ADDR + IO_ADDRESS(WDOG2_BASE_ADDR), +#endif +}; + +void mxc_wd_reset(void) +{ + u16 reg; + struct clk *clk; + + clk = clk_get(NULL, "wdog_clk"); + clk_enable(clk); + + reg = __raw_readw(wdog_base[0] + WDOG_WCR) & ~WCR_SRS_BIT; + reg |= WCR_WDE_BIT; + __raw_writew(reg, wdog_base[0] + WDOG_WCR); +} --- linux-2.6.28.orig/arch/arm/plat-mxc/snoop.c +++ linux-2.6.28/arch/arm/plat-mxc/snoop.c @@ -0,0 +1,133 @@ +/* + * Copyright 2005-2009 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 + */ + +#include +#include +#include +#include +#include + +#ifdef M4IF_BASE_ADDR +#define SNOOP_V2 +#define MAX_SNOOP 2 +#define g_snoop_base (IO_ADDRESS(M4IF_BASE_ADDR) + 0x4C) +#elif defined(M3IF_BASE_ADDR) +#define MAX_SNOOP 1 +#define g_snoop_base (IO_ADDRESS(M3IF_BASE_ADDR) + 0x28) +#else +#define MAX_SNOOP 0 +#define g_snoop_base 0 +#endif + +/* M3IF Snooping Configuration Register 0 (M3IFSCFG0) READ/WRITE*/ +#define SBAR(x) (x * 0x14) +/* M3IF Snooping Configuration Register 1 (M3IFSCFG1) READ/WRITE*/ +#define SERL(x) ((x * 0x14) + 0x4) +/* M3IF Snooping Configuration Register 2 (M3IFSCFG2) READ/WRITE*/ +#define SERH(x) ((x * 0x14) + 0x8) +/* M3IF Snooping Status Register 0 (M3IFSSR0) READ/WRITE */ +#define SSRL(x) ((x * 0x14) + 0xC) +/* M3IF Snooping Status Register 1 (M3IFSSR1) */ +#define SSRH(x) ((x * 0x14) + 0x10) + +#if MAX_SNOOP + +int mxc_snoop_set_config(u32 num, unsigned long base, int size) +{ + u32 reg; + uint32_t msb; + uint32_t seg_size; + uint32_t window_size = 0; + int i; + + if (num >= MAX_SNOOP) { + return -EINVAL; + } + + /* Setup M3IF for snooping */ + if (size) { + + if (base == 0) { + return -EINVAL; + } + + msb = fls(size); + if (!(size & ((1UL << msb) - 1))) + msb--; /* Already aligned to power 2 */ + if (msb < 11) + msb = 11; + + window_size = (1UL << msb); + seg_size = window_size / 64; + + msb -= 11; + + reg = base & ~((1UL << msb) - 1); + reg |= msb << 1; + reg |= 1; /* enable snooping */ + reg |= 0x80; /* Set pulse width to default (M4IF only) */ + __raw_writel(reg, g_snoop_base + SBAR(num)); + + reg = 0; + for (i = 0; i < 32; i++) { + if (i * seg_size >= size) + break; + reg |= 1UL << i; + } + __raw_writel(reg, g_snoop_base + SERL(num)); + + reg = 0; + for (i = 32; i < 64; i++) { + if (i * seg_size >= size) + break; + reg |= 1UL << (i - 32); + } + __raw_writel(reg, g_snoop_base + SERH(num)); + + pr_debug + ("Snooping unit # %d enabled: window size = 0x%X, M3IFSCFG0=0x%08X, M3IFSCFG1=0x%08X, M3IFSCFG2=0x%08X\n", + num, window_size, __raw_readl(g_snoop_base + SBAR(num)), + __raw_readl(g_snoop_base + SERL(num)), + __raw_readl(g_snoop_base + SERH(num))); + } else { + __raw_writel(0, g_snoop_base + SBAR(num)); + } + + return window_size; +} + +EXPORT_SYMBOL(mxc_snoop_set_config); + +int mxc_snoop_get_status(u32 num, u32 * statl, u32 * stath) +{ + if (num >= MAX_SNOOP) { + return -EINVAL; + } + + *statl = __raw_readl(g_snoop_base + SSRL(num)); + *stath = __raw_readl(g_snoop_base + SSRH(num)); + /* DPRINTK("status = 0x%08X%08X\n", stat[1], stat[0]); */ + +#ifdef SNOOP_V2 + __raw_writel(*statl, g_snoop_base + SSRL(num)); + __raw_writel(*stath, g_snoop_base + SSRH(num)); +#else + __raw_writel(0x0, g_snoop_base + SSRL(num)); + __raw_writel(0x0, g_snoop_base + SSRH(num)); +#endif + return 0; +} + +EXPORT_SYMBOL(mxc_snoop_get_status); + +#endif /* MAX_SNOOP */ --- linux-2.6.28.orig/arch/arm/plat-mxc/io.c +++ linux-2.6.28/arch/arm/plat-mxc/io.c @@ -0,0 +1,41 @@ +/* + * Copyright 2007-2009 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 + */ + +/* + * mxc custom ioremap implementation. + */ + +#include +#include +#include +#include + +void *__iomem __mxc_ioremap(unsigned long cookie, size_t size, + unsigned int mtype) +{ + if (mtype == MT_DEVICE && IS_MEM_DEVICE_NONSHARED(cookie)) { + mtype = MT_DEVICE_NONSHARED; + } + return __arm_ioremap(cookie, size, mtype); +} + +EXPORT_SYMBOL(__mxc_ioremap); + +void __mxc_iounmap(void __iomem * addr) +{ + extern void __iounmap(volatile void __iomem * addr); + + __iounmap(addr); +} + +EXPORT_SYMBOL(__mxc_iounmap); --- linux-2.6.28.orig/arch/arm/plat-mxc/tzic.c +++ linux-2.6.28/arch/arm/plat-mxc/tzic.c @@ -0,0 +1,179 @@ +/* + * Copyright 2004-2009 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + ***************************************** + * TZIC Registers * + ***************************************** + */ +#define TZIC_BASE IO_ADDRESS(TZIC_BASE_ADDR) +#define TZIC_INTCNTL (TZIC_BASE + 0x0000) /* control register */ +#define TZIC_INTTYPE (TZIC_BASE + 0x0004) /* Controller type register */ +#define TZIC_IMPID (TZIC_BASE + 0x0008) /* Distributor Implementer Identification Register */ +#define TZIC_PRIOMASK (TZIC_BASE + 0x000C) /* Priority Mask Reg */ +#define TZIC_SYNCCTRL (TZIC_BASE + 0x0010) /* Synchronizer Control register */ +#define TZIC_DSMINT (TZIC_BASE + 0x0014) /* DSM interrupt Holdoffregister */ +#define TZIC_INTSEC0 (TZIC_BASE + 0x0080) /* interrupt security register 0 */ +#define TZIC_ENSET0 (TZIC_BASE + 0x0100) /* Enable Set Register 0 */ +#define TZIC_ENCLEAR0 (TZIC_BASE + 0x0180) /* Enable Clear Register 0 */ +#define TZIC_SRCSET0 (TZIC_BASE + 0x0200) /* Source Set Register 0 */ +#define TZIC_SRCCLAR0 (TZIC_BASE + 0x0280) /* Source Clear Register 0 */ +#define TZIC_PRIORITY0 (TZIC_BASE + 0x0400) /* Priority Register 0 */ +#define TZIC_PND0 (TZIC_BASE + 0x0D00) /* Pending Register 0 */ +#define TZIC_HIPND0 (TZIC_BASE + 0x0D80) /* High Priority Pending Register */ +#define TZIC_WAKEUP0 (TZIC_BASE + 0x0E00) /* Wakeup Config Register */ +#define TZIC_SWINT (TZIC_BASE + 0x0F00) /* Software Interrupt Rigger Register */ +#define TZIC_ID0 (TZIC_BASE + 0x0FD0) /* Indentification Register 0 */ + +/*! + * Disable interrupt number "irq" in the TZIC + * + * @param irq interrupt source number + */ +static void mxc_mask_irq(unsigned int irq) +{ + int index, off; + + index = irq >> 5; + off = irq & 0x1F; + __raw_writel(1 << off, TZIC_ENCLEAR0 + (index << 2)); +} + +/*! + * Enable interrupt number "irq" in the TZIC + * + * @param irq interrupt source number + */ +static void mxc_unmask_irq(unsigned int irq) +{ + int index, off; + + index = irq >> 5; + off = irq & 0x1F; + __raw_writel(1 << off, TZIC_ENSET0 + (index << 2)); +} + +static unsigned int wakeup_intr[4]; + +/*! + * Set interrupt number "irq" in the TZIC as a wake-up source. + * + * @param irq interrupt source number + * @param enable enable as wake-up if equal to non-zero + * disble as wake-up if equal to zero + * + * @return This function returns 0 on success. + */ +static int mxc_set_wake_irq(unsigned int irq, unsigned int enable) +{ + unsigned int index, off; + + index = irq >> 5; + off = irq & 0x1F; + + if (index > 3) + return -1; + + if (enable) + wakeup_intr[index] |= (1 << off); + else + wakeup_intr[index] &= ~(1 << off); + + return 0; +} + +static struct irq_chip mxc_tzic_chip = { + .name = "MXC_TZIC", + .ack = mxc_mask_irq, + .mask = mxc_mask_irq, + .unmask = mxc_unmask_irq, + .set_wake = mxc_set_wake_irq, +}; + +/*! + * This function initializes the TZIC hardware and disables all the + * interrupts. It registers the interrupt enable and disable functions + * to the kernel for each interrupt source. + */ +void __init mxc_init_irq(void) +{ + int i; + + /* put the TZIC into the reset value with + * all interrupts disabled + */ + i = __raw_readl(TZIC_INTCNTL); + + __raw_writel(0x80010001, TZIC_INTCNTL); + i = __raw_readl(TZIC_INTCNTL); + __raw_writel(0x1f, TZIC_PRIOMASK); + i = __raw_readl(TZIC_PRIOMASK); + __raw_writel(0x02, TZIC_SYNCCTRL); + i = __raw_readl(TZIC_SYNCCTRL); + for (i = 0; i < 4; i++) { + __raw_writel(0xFFFFFFFF, TZIC_INTSEC0 + i * 4); + } + /* disable all interrupts */ + for (i = 0; i < 4; i++) { + __raw_writel(0xFFFFFFFF, TZIC_ENCLEAR0 + i * 4); + } + + /* all IRQ no FIQ Warning :: No selection */ + + for (i = 0; i < MXC_MAX_INT_LINES; i++) { + set_irq_chip(i, &mxc_tzic_chip); + set_irq_handler(i, handle_level_irq); + set_irq_flags(i, IRQF_VALID); + } + + printk(KERN_INFO "MXC IRQ initialized\n"); +} + +/*! + * enable wakeup interrupt + * + * @param is_idle 1 if called in idle loop (enset registers); + * 0 to be used when called from low power entry + * @return 0 if successful; non-zero otherwise + */ +int tzic_enable_wake(int is_idle) +{ + unsigned int i, v; + + __raw_writel(1, TZIC_DSMINT); + if (unlikely(__raw_readl(TZIC_DSMINT) == 0)) + return -EAGAIN; + + if (likely(is_idle)) { + for (i = 0; i < 4; i++) { + v = __raw_readl(TZIC_ENSET0 + i * 4); + __raw_writel(v, TZIC_WAKEUP0 + i * 4); + } + } else { + for (i = 0; i < 4; i++) { + v = wakeup_intr[i]; + __raw_writel(v, TZIC_WAKEUP0 + i * 4); + } + } + return 0; +} --- linux-2.6.28.orig/arch/arm/plat-mxc/cpu_common.c +++ linux-2.6.28/arch/arm/plat-mxc/cpu_common.c @@ -0,0 +1,85 @@ +/* + * Copyright 2004-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 + */ + +#include +#include +#include +extern int mxc_early_serial_console_init(char *); + +/*! + * @file plat-mxc/cpu_common.c + * + * @brief This file contains the common CPU initialization code. + * + * @ingroup MSL_MX31 MSL_MXC91321 + */ + +static void __init system_rev_setup(char **p) +{ + system_rev = simple_strtoul(*p, NULL, 16); +} + +__early_param("system_rev=", system_rev_setup); + +int mxc_jtag_enabled; /* OFF: 0 (default), ON: 1 */ + +/* + * Here are the JTAG options from the command line. By default JTAG + * is OFF which means JTAG is not connected and WFI is enabled + * + * "on" -- JTAG is connected, so WFI is disabled + * "off" -- JTAG is disconnected, so WFI is enabled + */ + +static void __init jtag_wfi_setup(char **p) +{ + if (memcmp(*p, "on", 2) == 0) { + mxc_jtag_enabled = 1; + *p += 2; + } else if (memcmp(*p, "off", 3) == 0) { + mxc_jtag_enabled = 0; + *p += 3; + } +} + +__early_param("jtag=", jtag_wfi_setup); + +void __init mxc_cpu_common_init(void) +{ + pr_info("CPU is %s%x Revision %u.%u\n", + (mxc_cpu() < 0x100) ? "i.MX" : "MXC", + mxc_cpu(), mxc_cpu_rev_major(), mxc_cpu_rev_minor()); +} + +/** + * early_console_setup - setup debugging console + * + * Consoles started here require little enough setup that we can start using + * them very early in the boot process, either right after the machine + * vector initialization, or even before if the drivers can detect their hw. + * + * Returns non-zero if a console couldn't be setup. + * This function is developed based on + * early_console_setup function as defined in arch/ia64/kernel/setup.c + */ +int __init early_console_setup(char *cmdline) +{ + int earlycons = 0; + +#ifdef CONFIG_SERIAL_MXC_CONSOLE + if (!mxc_early_serial_console_init(cmdline)) + earlycons++; +#endif + + return (earlycons) ? 0 : -1; +} --- linux-2.6.28.orig/arch/arm/plat-mxc/gpio.c +++ linux-2.6.28/arch/arm/plat-mxc/gpio.c @@ -1,253 +1,906 @@ /* - * 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. + * Copyright 2004-2008 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: * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the 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. + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/* + * Implementation based on omap gpio.c */ #include -#include -#include -#include +#include +#include +#include +#include +#include #include -#include +#include +#include +#include +#include +#include +#include + +/*! + * @file plat-mxc/gpio.c + * + * @brief This file contains the GPIO implementation details. + * + * @ingroup GPIO + */ + +/* GPIO related defines */ +#if defined(CONFIG_ARCH_MX27) || defined(CONFIG_ARCH_MX21) +enum gpio_reg { + GPIO_DR = 0x1C, + GPIO_GDIR = 0x00, + GPIO_PSR = 0x24, + GPIO_ICR1 = 0x028, + GPIO_ICR2 = 0x2C, + GPIO_IMR = 0x30, + GPIO_ISR = 0x34, +}; +#else +enum gpio_reg { + GPIO_DR = 0x00, + GPIO_GDIR = 0x04, + GPIO_PSR = 0x08, + GPIO_ICR1 = 0x0C, + GPIO_ICR2 = 0x10, + GPIO_IMR = 0x14, + GPIO_ISR = 0x18, +}; +#endif + +extern struct mxc_gpio_port mxc_gpio_ports[]; + +struct gpio_port { + u32 num; /*!< gpio port number */ + u32 base; /*!< gpio port base VA */ +#ifdef MXC_GPIO_SPLIT_IRQ_2 + u16 irq_0_15, irq_16_31; +#else + u16 irq; /*!< irq number to the core */ +#endif + u16 virtual_irq_start; /*!< virtual irq start number */ + u32 reserved_map; /*!< keep track of which pins are in use */ + u32 irq_is_level_map; /*!< if a pin's irq is level sensitive. default is edge */ + u32 suspend_wakeup; + u32 saved_wakeup; + spinlock_t lock; /*!< lock when operating on the port */ +}; +static struct gpio_port gpio_port[GPIO_PORT_NUM]; + +/* + * Find the pointer to the gpio_port for a given pin. + * @param gpio a gpio pin number + * @return pointer to \b struc \b gpio_port + */ +static inline struct gpio_port *get_gpio_port(u32 gpio) +{ + return &gpio_port[GPIO_TO_PORT(gpio)]; +} + +/* + * Check if a gpio pin is within [0, MXC_MAX_GPIO_LINES -1]. + * @param gpio a gpio pin number + * @return 0 if the pin number is valid; -1 otherwise + */ +static int check_gpio(u32 gpio) +{ + if (gpio >= MXC_MAX_GPIO_LINES) { + printk(KERN_ERR "mxc-gpio: invalid GPIO %d\n", gpio); + dump_stack(); + return -1; + } + return 0; +} + +/* + * Set a GPIO pin's direction + * @param port pointer to a gpio_port + * @param index gpio pin index value (0~31) + * @param is_input 0 for output; non-zero for input + */ +static void _set_gpio_direction(struct gpio_port *port, u32 index, int is_input) +{ + u32 reg = port->base + GPIO_GDIR; + u32 l; + + l = __raw_readl(reg); + if (is_input) + l &= ~(1 << index); + else + l |= 1 << index; + __raw_writel(l, reg); +} + +/*! + * Exported function to set a GPIO pin's direction + * @param pin a name defined by \b iomux_pin_name_t + * @param is_input 1 (or non-zero) for input; 0 for output + */ +void mxc_set_gpio_direction(iomux_pin_name_t pin, int is_input) +{ + struct gpio_port *port; + u32 gpio = IOMUX_TO_GPIO(pin); + + if (check_gpio(gpio) < 0) + return; + port = get_gpio_port(gpio); + spin_lock(&port->lock); + _set_gpio_direction(port, GPIO_TO_INDEX(gpio), is_input); + spin_unlock(&port->lock); +} + +/* + * Set a GPIO pin's data output + * @param port pointer to a gpio_port + * @param index gpio pin index value (0~31) + * @param data value to be set (only 0 or 1 is valid) + */ +static void _set_gpio_dataout(struct gpio_port *port, u32 index, u32 data) +{ + u32 reg = port->base + GPIO_DR; + u32 l = 0; + + l = (__raw_readl(reg) & (~(1 << index))) | (data << index); + __raw_writel(l, reg); +} + +/*! + * Exported function to set a GPIO pin's data output + * @param pin a name defined by \b iomux_pin_name_t + * @param data value to be set (only 0 or 1 is valid) + */ +void mxc_set_gpio_dataout(iomux_pin_name_t pin, u32 data) +{ + struct gpio_port *port; + u32 gpio = IOMUX_TO_GPIO(pin); -static struct mxc_gpio_port *mxc_gpio_ports; -static int gpio_table_size; + if (check_gpio(gpio) < 0) + return; -/* Note: This driver assumes 32 GPIOs are handled in one register */ + port = get_gpio_port(gpio); + spin_lock(&port->lock); + _set_gpio_dataout(port, GPIO_TO_INDEX(gpio), (data == 0) ? 0 : 1); + spin_unlock(&port->lock); +} -static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index) +/*! + * Return the data value of a GPIO signal. + * @param pin a name defined by \b iomux_pin_name_t + * + * @return value (0 or 1) of the GPIO signal; -1 if pass in invalid pin + */ +int mxc_get_gpio_datain(iomux_pin_name_t pin) +{ + struct gpio_port *port; + u32 gpio = IOMUX_TO_GPIO(pin); + + if (check_gpio(gpio) < 0) + return -1; + + port = get_gpio_port(gpio); + + /* + * SW workaround for the eSDHC1 Write Protected feature + * The PSR of CSPI1_SS0 (GPIO3_2) should be read. + */ + if (machine_is_mx37_3ds() && (gpio == ((32 * 2) + 2))) + return (__raw_readl(port->base + GPIO_PSR) >> + GPIO_TO_INDEX(gpio)) & 1; + else + return (__raw_readl(port->base + GPIO_DR) >> + GPIO_TO_INDEX(gpio)) & 1; +} + +/* + * Clear a GPIO signal's interrupt status + * + * @param port pointer to a gpio_port + * @param index gpio pin index value (0~31) + */ +static inline void _clear_gpio_irqstatus(struct 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) +/* + * Set a GPIO pin's interrupt edge + * @param port pointer to a gpio_port + * @param index gpio pin index value (0~31) + * @param icr one of the values defined in \b gpio_edge_t + * to indicate how to generate an interrupt + */ +static void _set_gpio_edge_ctrl(struct gpio_port *port, u32 index, + gpio_edge_t edge) +{ + u32 reg = port->base; + u32 l, sig; + + reg += (index <= 15) ? GPIO_ICR1 : GPIO_ICR2; + sig = (index <= 15) ? index : (index - 16); + l = __raw_readl(reg); + l = (l & (~(0x3 << (sig * 2)))) | (edge << (sig * 2)); + __raw_writel(l, reg); + _clear_gpio_irqstatus(port, index); +} + +/* + * Enable/disable a GPIO signal's interrupt. + * + * @param port pointer to a gpio_port + * @param index gpio pin index value (0~31) + * @param enable \b #true for enabling the interrupt; \b #false otherwise + */ +static inline void _set_gpio_irqenable(struct gpio_port *port, u32 index, + bool enable) { + u32 reg = port->base + GPIO_IMR; + u32 mask = (!enable) ? 0 : 1; u32 l; - l = __raw_readl(port->base + GPIO_IMR); - l = (l & (~(1 << index))) | (!!enable << index); - __raw_writel(l, port->base + GPIO_IMR); + l = __raw_readl(reg); + l = (l & (~(1 << index))) | (mask << index); + __raw_writel(l, reg); +} + +static inline int _request_gpio(struct gpio_port *port, u32 index) +{ + spin_lock(&port->lock); + if (port->reserved_map & (1 << index)) { + printk(KERN_ERR + "GPIO port %d (0-based), pin %d is already reserved!\n", + port->num, index); + dump_stack(); + spin_unlock(&port->lock); + return -1; + } + port->reserved_map |= (1 << index); + spin_unlock(&port->lock); + return 0; } -static void gpio_ack_irq(u32 irq) +/*! + * Request ownership for a GPIO pin. The caller has to check the return value + * of this function to make sure it returns 0 before make use of that pin. + * @param pin a name defined by \b iomux_pin_name_t + * @return 0 if successful; Non-zero otherwise + */ +int mxc_request_gpio(iomux_pin_name_t pin) { - u32 gpio = irq_to_gpio(irq); - _clear_gpio_irqstatus(&mxc_gpio_ports[gpio / 32], gpio & 0x1f); + struct gpio_port *port; + u32 index, gpio = IOMUX_TO_GPIO(pin); + + if (check_gpio(gpio) < 0) + return -EINVAL; + + port = get_gpio_port(gpio); + index = GPIO_TO_INDEX(gpio); + + return _request_gpio(port, index); } +/*! + * Release ownership for a GPIO pin + * @param pin a name defined by \b iomux_pin_name_t + */ +void mxc_free_gpio(iomux_pin_name_t pin) +{ + struct gpio_port *port; + u32 index, gpio = IOMUX_TO_GPIO(pin); + + if (check_gpio(gpio) < 0) + return; + + port = get_gpio_port(gpio); + index = GPIO_TO_INDEX(gpio); + + spin_lock(&port->lock); + if ((!(port->reserved_map & (1 << index)))) { + printk(KERN_ERR "GPIO port %d, pin %d wasn't reserved!\n", + port->num, index); + dump_stack(); + spin_unlock(&port->lock); + return; + } + port->reserved_map &= ~(1 << index); + port->irq_is_level_map &= ~(1 << index); + _set_gpio_direction(port, index, 1); + _set_gpio_irqenable(port, index, 0); + _clear_gpio_irqstatus(port, index); + spin_unlock(&port->lock); +} + +/* + * We need to unmask the GPIO port interrupt as soon as possible to + * avoid missing GPIO interrupts for other lines in the port. + * Then we need to mask-read-clear-unmask the triggered GPIO lines + * in the port to avoid missing nested interrupts for a GPIO line. + * If we wait to unmask individual GPIO lines in the port after the + * line's interrupt handler has been run, we may miss some nested + * interrupts. + */ +static void mxc_gpio_irq_handler(u32 irq, struct irq_desc *desc) +{ + u32 isr_reg = 0, imr_reg = 0, imr_val; + u32 int_valid; + u32 gpio_irq, mask = 0xFFFFFFFF; + struct gpio_port *port; + + port = (struct gpio_port *)get_irq_data(irq); + isr_reg = port->base + GPIO_ISR; + imr_reg = port->base + GPIO_IMR; + +#ifdef MXC_GPIO_SPLIT_IRQ_2 + if (irq == port->irq_0_15) { + mask = 0x0000FFFF; + } else { + mask = 0xFFFF0000; + } +#endif + + imr_val = __raw_readl(imr_reg) & mask; + int_valid = __raw_readl(isr_reg) & imr_val; + + if (unlikely(!int_valid)) { + printk(KERN_DEBUG + "\nGPIO port: %d Spurious interrupt:0x%0x Mask: %x\n\n", + port->num, int_valid, imr_val); + return; + } + + gpio_irq = port->virtual_irq_start; + for (; int_valid != 0; int_valid >>= 1, gpio_irq++) { + struct irq_desc *d; + + if ((int_valid & 1) == 0) + continue; + d = irq_desc + gpio_irq; + if (unlikely(!(d->handle_irq))) { + printk(KERN_ERR "\nGPIO port: %d irq: %d unhandeled\n", + port->num, gpio_irq); + BUG(); /* oops */ + } + d->handle_irq(gpio_irq, d); + } +} + +#ifdef MXC_MUX_GPIO_INTERRUPTS +static void mxc_gpio_mux_irq_handler(u32 irq, struct irq_desc *desc) +{ + int i; + u32 isr_reg = 0, imr_reg = 0, imr_val; + u32 int_valid; + struct gpio_port *port; + + for (i = 0; i < GPIO_PORT_NUM; i++) { + port = &gpio_port[i]; + isr_reg = port->base + GPIO_ISR; + imr_reg = port->base + GPIO_IMR; + + imr_val = __raw_readl(imr_reg); + int_valid = __raw_readl(isr_reg) & imr_val; + + if (int_valid) { + set_irq_data(irq, (void *)port); + mxc_gpio_irq_handler(irq, desc); + } + } +} +#endif + +/* + * Disable a gpio pin's interrupt by setting the bit in the imr. + * @param irq a gpio virtual irq number + */ static void gpio_mask_irq(u32 irq) { - u32 gpio = irq_to_gpio(irq); - _set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 0); + u32 gpio = MXC_IRQ_TO_GPIO(irq); + struct gpio_port *port = get_gpio_port(gpio); + + _set_gpio_irqenable(port, GPIO_TO_INDEX(gpio), 0); +} + +/* + * Acknowledge a gpio pin's interrupt by clearing the bit in the isr. + * If the GPIO interrupt is level triggered, it also disables the interrupt. + * @param irq a gpio virtual irq number + */ +static void gpio_ack_irq(u32 irq) +{ + u32 gpio = MXC_IRQ_TO_GPIO(irq); + u32 index = GPIO_TO_INDEX(gpio); + struct gpio_port *port = get_gpio_port(gpio); + + _clear_gpio_irqstatus(port, GPIO_TO_INDEX(gpio)); + if (port->irq_is_level_map & (1 << index)) { + gpio_mask_irq(irq); + } } +/* + * Enable a gpio pin's interrupt by clearing the bit in the imr. + * @param irq a gpio virtual irq number + */ static void gpio_unmask_irq(u32 irq) { - u32 gpio = irq_to_gpio(irq); - _set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 1); + u32 gpio = MXC_IRQ_TO_GPIO(irq); + struct gpio_port *port = get_gpio_port(gpio); + + _set_gpio_irqenable(port, GPIO_TO_INDEX(gpio), 1); } +/* + * Enable a gpio pin's interrupt by clearing the bit in the imr. + * @param irq a gpio virtual irq number + */ 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; + u32 gpio = MXC_IRQ_TO_GPIO(irq); + struct gpio_port *port = get_gpio_port(gpio); switch (type) { - case IRQ_TYPE_EDGE_RISING: - edge = GPIO_INT_RISE_EDGE; + case IRQF_TRIGGER_RISING: + _set_gpio_edge_ctrl(port, GPIO_TO_INDEX(gpio), + GPIO_INT_RISE_EDGE); + set_irq_handler(irq, handle_edge_irq); + port->irq_is_level_map &= ~(1 << GPIO_TO_INDEX(gpio)); break; - case IRQ_TYPE_EDGE_FALLING: - edge = GPIO_INT_FALL_EDGE; + case IRQF_TRIGGER_FALLING: + _set_gpio_edge_ctrl(port, GPIO_TO_INDEX(gpio), + GPIO_INT_FALL_EDGE); + set_irq_handler(irq, handle_edge_irq); + port->irq_is_level_map &= ~(1 << GPIO_TO_INDEX(gpio)); break; - case IRQ_TYPE_LEVEL_LOW: - edge = GPIO_INT_LOW_LEV; + case IRQF_TRIGGER_LOW: + _set_gpio_edge_ctrl(port, GPIO_TO_INDEX(gpio), + GPIO_INT_LOW_LEV); + set_irq_handler(irq, handle_level_irq); + port->irq_is_level_map |= 1 << GPIO_TO_INDEX(gpio); break; - case IRQ_TYPE_LEVEL_HIGH: - edge = GPIO_INT_HIGH_LEV; + case IRQF_TRIGGER_HIGH: + _set_gpio_edge_ctrl(port, GPIO_TO_INDEX(gpio), + GPIO_INT_HIGH_LEV); + set_irq_handler(irq, handle_level_irq); + port->irq_is_level_map |= 1 << GPIO_TO_INDEX(gpio); break; - default: /* this includes IRQ_TYPE_EDGE_BOTH */ + default: return -EINVAL; + break; } + return 0; +} - 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); - +/* + * Set interrupt number "irq" in the GPIO as a wake-up source. + * While system is running all registered GPIO interrupts need to have + * wake-up enabled. When system is suspended, only selected GPIO interrupts + * need to have wake-up enabled. + * @param irq interrupt source number + * @param enable enable as wake-up if equal to non-zero + * @return This function returns 0 on success. + */ +static int gpio_set_wake_irq(u32 irq, u32 enable) +{ + u32 gpio = MXC_IRQ_TO_GPIO(irq); + u32 gpio_idx = GPIO_TO_INDEX(gpio); + struct gpio_port *port = get_gpio_port(gpio); + + if (check_gpio(gpio) < 0) + return -ENODEV; + + if (enable) { + port->suspend_wakeup |= (1 << gpio_idx); +#ifdef MXC_GPIO_SPLIT_IRQ_2 + if (gpio_idx < 16) + enable_irq_wake(port->irq_0_15); + else + enable_irq_wake(port->irq_16_31); +#else + enable_irq_wake(port->irq); +#endif + } else { + port->suspend_wakeup &= ~(1 << gpio_idx); +#ifdef MXC_GPIO_SPLIT_IRQ_2 + if (gpio_idx < 16) + disable_irq_wake(port->irq_0_15); + else + disable_irq_wake(port->irq_16_31); +#else + disable_irq_wake(port->irq); +#endif + } return 0; } -/* handle n interrupts in one status register */ -static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat) +static struct irq_chip gpio_irq_chip = { + .name = "MXC_GPIO", + .ack = gpio_ack_irq, + .mask = gpio_mask_irq, + .unmask = gpio_unmask_irq, + .set_type = gpio_set_irq_type, + .set_wake = gpio_set_wake_irq, +}; + +/*! + * This function initializes the GPIO hardware and disables all the + * interrupts. It registers functions for core interrupt handling code, + * for irq-chip based architectures for each interrupt source. + */ +static int __init _mxc_gpio_init(void) { - u32 gpio_irq_no; + int i; + struct gpio_port *port; + + printk(KERN_INFO "MXC GPIO hardware\n"); - gpio_irq_no = port->virtual_irq_start; - for (; irq_stat != 0; irq_stat >>= 1, gpio_irq_no++) { + for (i = 0; i < GPIO_PORT_NUM; i++) { + int j, gpio_count = GPIO_NUM_PIN; - if ((irq_stat & 1) == 0) - continue; + port = &gpio_port[i]; + port->base = mxc_gpio_ports[i].base; + port->num = mxc_gpio_ports[i].num; +#ifdef MXC_GPIO_SPLIT_IRQ_2 + port->irq_0_15 = mxc_gpio_ports[i].irq_0_15; + port->irq_16_31 = mxc_gpio_ports[i].irq_16_31; +#else + port->irq = mxc_gpio_ports[i].irq; +#endif + port->virtual_irq_start = mxc_gpio_ports[i].virtual_irq_start; + + port->reserved_map = 0; + spin_lock_init(&port->lock); - BUG_ON(!(irq_desc[gpio_irq_no].handle_irq)); - irq_desc[gpio_irq_no].handle_irq(gpio_irq_no, - &irq_desc[gpio_irq_no]); + /* disable the interrupt and clear the status */ + __raw_writel(0, port->base + GPIO_IMR); + __raw_writel(0xFFFFFFFF, port->base + GPIO_ISR); + for (j = port->virtual_irq_start; + j < port->virtual_irq_start + gpio_count; j++) { + set_irq_chip(j, &gpio_irq_chip); + set_irq_handler(j, handle_edge_irq); + set_irq_flags(j, IRQF_VALID); + } +#ifndef MXC_MUX_GPIO_INTERRUPTS +#ifdef MXC_GPIO_SPLIT_IRQ_2 + set_irq_chained_handler(port->irq_0_15, mxc_gpio_irq_handler); + set_irq_data(port->irq_0_15, port); + set_irq_chained_handler(port->irq_16_31, mxc_gpio_irq_handler); + set_irq_data(port->irq_16_31, port); +#else + set_irq_chained_handler(port->irq, mxc_gpio_irq_handler); + set_irq_data(port->irq, port); +#endif +#endif } + +#ifdef MXC_MUX_GPIO_INTERRUPTS + set_irq_chained_handler(port->irq, mxc_gpio_mux_irq_handler); + set_irq_data(mxc_gpio_ports[0].irq, gpio_port); +#endif + + return 0; } -#ifdef CONFIG_ARCH_MX3 -/* MX3 has one interrupt *per* gpio port */ -static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc) +#ifdef CONFIG_PM +/*! + * This function puts the GPIO in low-power mode/state. + * All the interrupts that are enabled are first saved. + * Only those interrupts which registers as a wake source by calling + * enable_irq_wake are enabled. All other interrupts are disabled. + * + * @param dev the system device structure used to give information + * on GPIO to suspend + * @param mesg the power state the device is entering + * + * @return The function always returns 0. + */ +static int mxc_gpio_suspend(struct sys_device *dev, pm_message_t mesg) { - u32 irq_stat; - struct mxc_gpio_port *port = (struct mxc_gpio_port *)get_irq_data(irq); + int i; + + for (i = 0; i < GPIO_PORT_NUM; i++) { + struct gpio_port *port = &gpio_port[i]; + u32 isr_reg; + u32 imr_reg; - 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); + isr_reg = port->base + GPIO_ISR; + imr_reg = port->base + GPIO_IMR; + + if (__raw_readl(isr_reg) & port->suspend_wakeup) { + return -EPERM; + } + port->saved_wakeup = __raw_readl(imr_reg); + __raw_writel(port->suspend_wakeup, imr_reg); + } + + return 0; } -#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) +/*! + * This function brings the GPIO back from low-power state. + * All the interrupts enabled before suspension are re-enabled from + * the saved information. + * + * @param dev the system device structure used to give information + * on GPIO to resume + * + * @return The function always returns 0. + */ +static int mxc_gpio_resume(struct sys_device *dev) { 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; + for (i = 0; i < GPIO_PORT_NUM; i++) { + struct gpio_port *port = &gpio_port[i]; + u32 isr_reg; + u32 imr_reg; - irq_stat = __raw_readl(port[i].base + GPIO_ISR) & irq_msk; - if (irq_stat) - mxc_gpio_irq_handler(&port[i], irq_stat); + isr_reg = port->base + GPIO_ISR; + imr_reg = port->base + GPIO_IMR; + + __raw_writel(port->saved_wakeup, imr_reg); } + + return 0; } -#endif +#else +#define mxc_gpio_suspend NULL +#define mxc_gpio_resume NULL +#endif /* CONFIG_PM */ -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, +/*! + * This structure contains pointers to the power management callback functions. + */ +static struct sysdev_class mxc_gpio_sysclass = { + .name = "mxc_gpio", + .suspend = mxc_gpio_suspend, + .resume = mxc_gpio_resume, }; -static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset, - int dir) +/*! + * This structure represents GPIO as a system device. + * System devices follow a slightly different driver model. + * They don't need to do dynammic driver binding, can't be probed, + * and don't reside on any type of peripheral bus. + * So, it is represented and treated a little differently. + */ +static struct sys_device mxc_gpio_device = { + .id = 0, + .cls = &mxc_gpio_sysclass, +}; + +/*! + * This function registers GPIO hardware as a system device and + * intializes all the GPIO ports if not already done. + * System devices will only be suspended with interrupts disabled, and + * after all other devices have been suspended. On resume, they will be + * resumed before any other devices, and also with interrupts disabled. + * This may get called early from board specific init + * + * @return This function returns 0 on success. + */ +int __init mxc_gpio_init(void) { - struct mxc_gpio_port *port = - container_of(chip, struct mxc_gpio_port, chip); - u32 l; + int ret = 0; - l = __raw_readl(port->base + GPIO_GDIR); - if (dir) - l |= 1 << offset; - else - l &= ~(1 << offset); - __raw_writel(l, port->base + GPIO_GDIR); + ret = _mxc_gpio_init(); + + if (ret == 0) { + ret = sysdev_class_register(&mxc_gpio_sysclass); + if (ret == 0) + ret = sysdev_register(&mxc_gpio_device); + } + + return ret; } -static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value) +/* + * FIXME: The following functions are for backward-compatible. + * They will be removed at a future release. + */ +#define PORT_SIG_TO_GPIO(p, s) (p * 32 + s) + +/*! + * This function configures the GPIO signal to be either input or output. For + * input signals used for generating interrupts for the ARM core, how the + * interrupts being triggered is also passed in via \a icr. For output signals, + * the \a icr value doesn't matter. + * FIXED ME: for backward compatible. to be removed! + * + * @param port specified port with 0-GPIO port 1; 1-GPIO port 2 + * @param sig_no specified GPIO signal (0 based) + * @param out #true for output, #false for input + * @param icr value defined in \b #gpio_edge_t + */ +void gpio_config(u32 port, u32 sig_no, bool out, gpio_edge_t icr) { - struct mxc_gpio_port *port = - container_of(chip, struct mxc_gpio_port, chip); - void __iomem *reg = port->base + GPIO_DR; - u32 l; + u32 gpio = PORT_SIG_TO_GPIO(port, sig_no); + struct gpio_port *port_p; - l = (__raw_readl(reg) & (~(1 << offset))) | (value << offset); - __raw_writel(l, reg); + if (check_gpio(gpio) < 0) + return; + + port_p = get_gpio_port(gpio); + + if (!(port_p->reserved_map & (1 << sig_no))) + _request_gpio(port_p, sig_no); + + if (!out) { + /* input */ + _set_gpio_direction(port_p, sig_no, 1); + _set_gpio_edge_ctrl(port_p, sig_no, icr); + } else { /* output */ + _set_gpio_direction(port_p, sig_no, 0); + } } -static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset) +/*! + * This function sets a GPIO signal value. + * FIXED ME: for backward compatible. to be removed! + * + * @param port specified port with 0 for GPIO port 1 and 1 for GPIO port 2 + * @param sig_no specified GPIO signal (0 based) + * @param data value to be set (only 0 or 1 is valid) + */ +void gpio_set_data(u32 port, u32 sig_no, u32 data) { - struct mxc_gpio_port *port = - container_of(chip, struct mxc_gpio_port, chip); + u32 gpio = PORT_SIG_TO_GPIO(port, sig_no); + struct gpio_port *port_p; + + if (check_gpio(gpio) < 0) + return; - return (__raw_readl(port->base + GPIO_PSR) >> offset) & 1; + port_p = get_gpio_port(gpio); + + if (!(port_p->reserved_map & (1 << sig_no))) + _request_gpio(port_p, sig_no); + + spin_lock(&port_p->lock); + _set_gpio_dataout(port_p, sig_no, (data == 0) ? 0 : 1); + spin_unlock(&port_p->lock); } -static int mxc_gpio_direction_input(struct gpio_chip *chip, unsigned offset) +/*! + * This function returns the value of the GPIO signal. + * FIXED ME: for backward compatible. to be removed! + * + * @param port specified port with 0 for GPIO port 1 and 1 for GPIO port 2 + * @param sig_no specified GPIO signal (0 based) + * + * @return Value of the GPIO signal + */ +u32 gpio_get_data(u32 port, u32 sig_no) { - _set_gpio_direction(chip, offset, 0); - return 0; + u32 gpio = PORT_SIG_TO_GPIO(port, sig_no); + struct gpio_port *port_p; + + if (check_gpio(gpio) < 0) + BUG(); + + port_p = get_gpio_port(gpio); + + if (!(port_p->reserved_map & (1 << sig_no))) + _request_gpio(port_p, sig_no); + + return (__raw_readl(port_p->base + GPIO_DR) >> sig_no) & 1; } -static int mxc_gpio_direction_output(struct gpio_chip *chip, - unsigned offset, int value) +/*! + * This function clears the GPIO interrupt for a signal on a port. + * FIXED ME: for backward compatible. to be removed! + * + * @param port specified port with 0 for GPIO port 1 and 1 for GPIO port 2 + * @param sig_no specified GPIO signal (0 based) to clear + */ +void gpio_clear_int(u32 port, u32 sig_no) { - _set_gpio_direction(chip, offset, 1); - mxc_gpio_set(chip, offset, value); + u32 gpio = PORT_SIG_TO_GPIO(port, sig_no); + struct gpio_port *port_p; + + if (check_gpio(gpio) < 0) + return; + + port_p = get_gpio_port(gpio); + + if (!(port_p->reserved_map & (1 << sig_no))) + _request_gpio(port_p, sig_no); + + _clear_gpio_irqstatus(port_p, sig_no); +} + +/*! + * This function is responsible for registering a GPIO signal's ISR. + * FIXED ME: for backward compatible. to be removed! + * + * @param port specified port with 0 for GPIO port 1 and 1 for GPIO port 2 + * @param sig_no specified GPIO signal (0 based) + * @param prio priority as defined in \b enum \b #gpio_prio + * @param handler GPIO ISR function pointer for the GPIO signal + * @param irq_flags irq flags (not used) + * @param devname device name associated with the interrupt + * @param dev_id some unique information for the ISR + * + * @return 0 if successful; non-zero otherwise. + */ +int gpio_request_irq(u32 port, u32 sig_no, enum gpio_prio prio, + gpio_irq_handler handler, u32 irq_flags, + const char *devname, void *dev_id) +{ + u32 gpio = PORT_SIG_TO_GPIO(port, sig_no), ret; + struct gpio_port *port_p; + + if (check_gpio(gpio) < 0) + return -1; + + port_p = get_gpio_port(gpio); + + if (!(port_p->reserved_map & (1 << sig_no))) + _request_gpio(port_p, sig_no); + + ret = request_irq(MXC_GPIO_TO_IRQ(gpio), handler, 0, "gpio", dev_id); + if (ret) { + printk(KERN_ERR "gpio: IRQ%d already in use.\n", + MXC_GPIO_TO_IRQ(gpio)); + return ret; + } return 0; } -int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt) +/*! + * This function un-registers an ISR with the GPIO interrupt module. + * FIXED ME: for backward compatible. to be removed! + * + * @param port specified port with 0 for GPIO port 1 and 1 for GPIO port 2 + * @param sig_no specified GPIO signal (0 based) + * @param prio priority as defined in \b enum \b #gpio_prio + */ +void gpio_free_irq(u32 port, u32 sig_no, enum gpio_prio prio) { - int i, j; + u32 gpio = PORT_SIG_TO_GPIO(port, sig_no); + struct gpio_port *port_p; - /* save for local usage */ - mxc_gpio_ports = port; - gpio_table_size = cnt; + if (check_gpio(gpio) < 0) + return; - printk(KERN_INFO "MXC GPIO hardware\n"); + port_p = get_gpio_port(gpio); - 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); - } + free_irq(MXC_GPIO_TO_IRQ(gpio), NULL); - /* 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 + spin_lock(&port_p->lock); + if ((!(port_p->reserved_map & (1 << sig_no)))) { + printk(KERN_ERR "GPIO port %d, pin %d wasn't reserved!\n", + port_p->num, sig_no); + dump_stack(); + spin_unlock(&port_p->lock); + return; } - -#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; -} + port_p->reserved_map &= ~(1 << sig_no); + _set_gpio_direction(port_p, sig_no, 1); + _set_gpio_irqenable(port_p, sig_no, 0); + _clear_gpio_irqstatus(port_p, sig_no); + spin_unlock(&port_p->lock); +} + +EXPORT_SYMBOL(mxc_request_gpio); +EXPORT_SYMBOL(mxc_free_gpio); +EXPORT_SYMBOL(mxc_set_gpio_direction); +EXPORT_SYMBOL(mxc_set_gpio_dataout); +EXPORT_SYMBOL(mxc_get_gpio_datain); + +/* For backward compatible */ +EXPORT_SYMBOL(gpio_config); +EXPORT_SYMBOL(gpio_set_data); +EXPORT_SYMBOL(gpio_get_data); +EXPORT_SYMBOL(gpio_clear_int); +EXPORT_SYMBOL(gpio_request_irq); +EXPORT_SYMBOL(gpio_free_irq); --- linux-2.6.28.orig/arch/arm/plat-mxc/cpufreq.c +++ linux-2.6.28/arch/arm/plat-mxc/cpufreq.c @@ -0,0 +1,598 @@ +/* + * Copyright 2009 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 + */ + +/*! + * @file cpufreq.c + * + * @brief A driver for the Freescale Semiconductor i.MXC CPUfreq module. + * + * The CPUFREQ driver is for controling CPU frequency. It allows you to change + * the CPU clock speed on the fly. + * + * @ingroup PM + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int low_bus_freq_mode; +int high_bus_freq_mode; +int cpu_freq_khz_min; +int cpu_freq_khz_max; +int arm_lpm_clk; +int arm_normal_clk; +char *gp_reg_id = "SW1"; +char *lp_reg_id = "SW2"; +int axi_c_clk_support; + +static struct clk *cpu_clk; +static struct clk *main_bus_clk; +static struct clk *pll2; +static struct clk *axi_a_clk; +static struct clk *axi_b_clk; +static struct clk *axi_c_clk; +static struct clk *emi_core_clk; +static struct clk *nfc_clk; +static struct clk *ahb_clk; +static struct clk *vpu_clk; +static struct clk *vpu_core_clk; +static struct clk *arm_axi_clk; +static struct clk *ddr_clk; +static struct clk *ipu_clk; +static struct clk *periph_apm_clk; +static struct clk *lp_apm; +static struct clk *osc; +static struct regulator *gp_regulator; +static struct regulator *lp_regulator; +static struct cpu_wp *cpu_wp_tbl; +static struct cpufreq_frequency_table imx_freq_table[4]; + +extern int dvfs_core_is_active; +extern int cpu_wp_nr; +#ifdef CONFIG_ARCH_MX51 +extern struct cpu_wp *(*get_cpu_wp)(int *wp); +#endif + +static int set_cpu_freq(int freq) +{ + int ret = 0; + int org_cpu_rate; + int gp_volt = 0; + int i; + + org_cpu_rate = clk_get_rate(cpu_clk); + + if (org_cpu_rate == freq) + return ret; + + for (i = 0; i < cpu_wp_nr; i++) { + if (freq == cpu_wp_tbl[i].cpu_rate) + gp_volt = cpu_wp_tbl[i].cpu_voltage; + } + + if (gp_volt == 0) + return ret; + + /*Set the voltage for the GP domain. */ + if (freq > org_cpu_rate) { + ret = regulator_set_voltage(gp_regulator, gp_volt, gp_volt); + if (ret < 0) { + printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE!!!!\n"); + return ret; + } + } + + ret = clk_set_rate(cpu_clk, freq); + if (ret != 0) { + printk(KERN_DEBUG "cannot set CPU clock rate\n"); + return ret; + } + + if (freq < org_cpu_rate) { + ret = regulator_set_voltage(gp_regulator, gp_volt, gp_volt); + if (ret < 0) { + printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE!!!!\n"); + return ret; + } + } + + return ret; +} + +static int set_low_bus_freq(void) +{ + int ret = 0; + unsigned long lp_lpm_clk; + + struct clk *p_clk; + struct clk *amode_parent_clk; + + if (axi_c_clk_support == 0) + return 0; + + lp_lpm_clk = clk_get_rate(lp_apm); + amode_parent_clk = lp_apm; + p_clk = clk_get_parent(periph_apm_clk); + + /* Make sure osc_clk is the parent of lp_apm. */ + if (clk_get_parent(amode_parent_clk) != osc) + clk_set_parent(amode_parent_clk, osc); + + /* Set the parent of periph_apm_clk to be lp_apm */ + clk_set_parent(periph_apm_clk, amode_parent_clk); + amode_parent_clk = periph_apm_clk; + + p_clk = clk_get_parent(main_bus_clk); + /* Set the parent of main_bus_clk to be periph_apm_clk */ + clk_set_parent(main_bus_clk, amode_parent_clk); + + clk_set_rate(axi_a_clk, lp_lpm_clk); + clk_set_rate(axi_b_clk, lp_lpm_clk); + clk_set_rate(axi_c_clk, lp_lpm_clk); + clk_set_rate(emi_core_clk, lp_lpm_clk); + clk_set_rate(nfc_clk, 4800000); + clk_set_rate(ahb_clk, lp_lpm_clk); + + amode_parent_clk = emi_core_clk; + + p_clk = clk_get_parent(arm_axi_clk); + if (p_clk != amode_parent_clk) + clk_set_parent(arm_axi_clk, amode_parent_clk); + + p_clk = clk_get_parent(vpu_clk); + if (p_clk != amode_parent_clk) + clk_set_parent(vpu_clk, amode_parent_clk); + + p_clk = clk_get_parent(vpu_core_clk); + if (p_clk != amode_parent_clk) + clk_set_parent(vpu_core_clk, amode_parent_clk); + + /* Set the voltage to 1.0v for the LP domain. */ + ret = regulator_set_voltage(lp_regulator, 1000000, 1000000); + if (ret < 0) { + printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE!!!!!!\n"); + return ret; + } + + low_bus_freq_mode = 1; + high_bus_freq_mode = 0; + return ret; +} + +static int set_high_bus_freq(void) +{ + struct clk *p_clk; + struct clk *rmode_parent_clk; + int ret = 0; + + if (axi_c_clk_support == 0) + return 0; + + if (!low_bus_freq_mode) + return ret; + + low_bus_freq_mode = 0; + + /* Set the voltage to 1.2v for the LP domain. */ + ret = regulator_set_voltage(lp_regulator, 1200000, 1200000); + if (ret < 0) { + printk(KERN_DEBUG "COULD NOT SET LP VOLTAGE!!!!!!\n"); + return ret; + } + + rmode_parent_clk = pll2; + + /* Set the dividers before setting the parent clock. */ + clk_set_rate(axi_a_clk, 4800000); + clk_set_rate(axi_b_clk, 4000000); + clk_set_rate(axi_c_clk, 6000000); + + clk_set_rate(emi_core_clk, 4800000); + clk_set_rate(ahb_clk, 4800000); + + /* Set the parent of main_bus_clk to be pll2 */ + p_clk = clk_get_parent(main_bus_clk); + clk_set_parent(main_bus_clk, rmode_parent_clk); + udelay(5); + high_bus_freq_mode = 1; + return ret; +} + +static int low_freq_bus_used(void) +{ + if (axi_c_clk_support == 0) + return 0; + + if ((clk_get_usecount(ipu_clk) == 0) + && (clk_get_usecount(vpu_clk) == 0)) + return 1; + else + return 0; +} + +static int mxc_verify_speed(struct cpufreq_policy *policy) +{ + if (policy->cpu != 0) + return -EINVAL; + + return cpufreq_frequency_table_verify(policy, imx_freq_table); +} + +static unsigned int mxc_get_speed(unsigned int cpu) +{ + if (cpu) + return 0; + + return clk_get_rate(cpu_clk) / 1000; +} + +static int calc_frequency_khz(int target, unsigned int relation) +{ + int i; + + if (relation == CPUFREQ_RELATION_H) { + for (i = ARRAY_SIZE(imx_freq_table) - 1; i > 0; i--) { + if (imx_freq_table[i].frequency <= target) + return imx_freq_table[i].frequency; + } + } else if (relation == CPUFREQ_RELATION_L) { + for (i = 0; i < ARRAY_SIZE(imx_freq_table) - 1; i++) { + if (imx_freq_table[i].frequency >= target) + return imx_freq_table[i].frequency; + } + } + printk(KERN_ERR "Error: No valid cpufreq relation\n"); + return cpu_freq_khz_max; +} + +static int mxc_set_target(struct cpufreq_policy *policy, + unsigned int target_freq, unsigned int relation) +{ + struct cpufreq_freqs freqs; + long freq_Hz; + int low_freq_bus_ready = 0; + int ret = 0; + + /* + * Some governors do not respects CPU and policy lower limits + * which leads to bad things (division by zero etc), ensure + * that such things do not happen. + */ + if (target_freq < policy->cpuinfo.min_freq) + target_freq = policy->cpuinfo.min_freq; + + if (target_freq < policy->min) + target_freq = policy->min; + + freq_Hz = calc_frequency_khz(target_freq, relation) * 1000; + + freqs.old = clk_get_rate(cpu_clk) / 1000; + freqs.new = freq_Hz / 1000; + freqs.cpu = 0; + freqs.flags = 0; + + if ((freqs.old == freqs.new) && (freqs.new != cpu_freq_khz_min)) + return 0; + + low_freq_bus_ready = low_freq_bus_used(); + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + if ((freq_Hz == arm_lpm_clk) && (!low_bus_freq_mode) + && (low_freq_bus_ready)) { + set_low_bus_freq(); + if (!dvfs_core_is_active) + ret = set_cpu_freq(freq_Hz); + } else { + if (!high_bus_freq_mode) + set_high_bus_freq(); + + if (!dvfs_core_is_active) + ret = set_cpu_freq(freq_Hz); + if (low_bus_freq_mode) { + if (ret == 0) + set_high_bus_freq(); + } + } + + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + + return ret; +} + +static int __init mxc_cpufreq_driver_init(struct cpufreq_policy *policy) +{ + int ret; + int i; + + printk(KERN_INFO "i.MXC CPU frequency driver\n"); + + if (policy->cpu != 0) + return -EINVAL; + + cpu_clk = clk_get(NULL, "cpu_clk"); + if (IS_ERR(cpu_clk)) { + printk(KERN_ERR "%s: failed to get cpu clock\n", __func__); + return PTR_ERR(cpu_clk); + } + + axi_c_clk = clk_get(NULL, "axi_c_clk"); + if (IS_ERR(axi_c_clk)) { + axi_c_clk_support = 0; + printk(KERN_ERR "%s: failed to get axi_c_clk\n", __func__); + } else { + axi_c_clk_support = 1; + main_bus_clk = clk_get(NULL, "main_bus_clk"); + if (IS_ERR(main_bus_clk)) { + printk(KERN_ERR "%s: failed to get main_bus_clk\n", + __func__); + return PTR_ERR(main_bus_clk); + } + + pll2 = clk_get(NULL, "pll2"); + if (IS_ERR(pll2)) { + printk(KERN_ERR "%s: failed to get pll2\n", __func__); + return PTR_ERR(pll2); + } + + axi_a_clk = clk_get(NULL, "axi_a_clk"); + if (IS_ERR(axi_a_clk)) { + printk(KERN_ERR "%s: failed to get axi_a_clk\n", + __func__); + return PTR_ERR(axi_a_clk); + } + + axi_b_clk = clk_get(NULL, "axi_b_clk"); + if (IS_ERR(axi_b_clk)) { + printk(KERN_ERR "%s: failed to get axi_b_clk\n", + __func__); + return PTR_ERR(axi_b_clk); + } + + emi_core_clk = clk_get(NULL, "emi_core_clk"); + if (IS_ERR(emi_core_clk)) { + printk(KERN_ERR "%s: failed to get emi_core_clk\n", + __func__); + return PTR_ERR(emi_core_clk); + } + + nfc_clk = clk_get(NULL, "nfc_clk"); + if (IS_ERR(nfc_clk)) { + printk(KERN_ERR "%s: failed to get nfc_clk\n", + __func__); + return PTR_ERR(nfc_clk); + } + + ahb_clk = clk_get(NULL, "ahb_clk"); + if (IS_ERR(ahb_clk)) { + printk(KERN_ERR "%s: failed to get ahb_clk\n", + __func__); + return PTR_ERR(ahb_clk); + } + + vpu_core_clk = clk_get(NULL, "vpu_core_clk"); + if (IS_ERR(vpu_core_clk)) { + printk(KERN_ERR "%s: failed to get vpu_core_clk\n", + __func__); + return PTR_ERR(vpu_core_clk); + } + + arm_axi_clk = clk_get(NULL, "arm_axi_clk"); + if (IS_ERR(arm_axi_clk)) { + printk(KERN_ERR "%s: failed to get arm_axi_clk\n", + __func__); + return PTR_ERR(arm_axi_clk); + } + + ddr_clk = clk_get(NULL, "ddr_clk"); + if (IS_ERR(ddr_clk)) { + printk(KERN_ERR "%s: failed to get ddr_clk\n", + __func__); + return PTR_ERR(ddr_clk); + } + + ipu_clk = clk_get(NULL, "ipu_clk"); + if (IS_ERR(ipu_clk)) { + printk(KERN_ERR "%s: failed to get ipu_clk\n", + __func__); + return PTR_ERR(ipu_clk); + } + + vpu_clk = clk_get(NULL, "vpu_clk"); + if (IS_ERR(vpu_clk)) { + printk(KERN_ERR "%s: failed to get vpu_clk\n", + __func__); + return PTR_ERR(vpu_clk); + } + + periph_apm_clk = clk_get(NULL, "periph_apm_clk"); + if (IS_ERR(periph_apm_clk)) { + printk(KERN_ERR "%s: failed to get periph_apm_clk\n", + __func__); + return PTR_ERR(periph_apm_clk); + } + + lp_apm = clk_get(NULL, "lp_apm"); + if (IS_ERR(lp_apm)) { + printk(KERN_ERR "%s: failed to get lp_apm\n", __func__); + return PTR_ERR(lp_apm); + } + + osc = clk_get(NULL, "osc"); + if (IS_ERR(osc)) { + printk(KERN_ERR "%s: failed to get osc\n", __func__); + return PTR_ERR(osc); + } + } + + gp_regulator = regulator_get(NULL, gp_reg_id); + if (IS_ERR(gp_regulator)) { + clk_put(cpu_clk); + printk(KERN_ERR "%s: failed to get gp regulator\n", __func__); + return PTR_ERR(gp_regulator); + } + + lp_regulator = regulator_get(NULL, lp_reg_id); + if (IS_ERR(lp_regulator)) { + clk_put(ahb_clk); + printk(KERN_ERR "%s: failed to get lp regulator\n", __func__); + return PTR_ERR(lp_regulator); + } + + /* Set the current working point. */ + cpu_wp_tbl = get_cpu_wp(&cpu_wp_nr); + + cpu_freq_khz_min = cpu_wp_tbl[0].cpu_rate / 1000; + cpu_freq_khz_max = cpu_wp_tbl[0].cpu_rate / 1000; + + for (i = 0; i < cpu_wp_nr; i++) { + imx_freq_table[cpu_wp_nr - 1 - i].index = cpu_wp_nr - i; + imx_freq_table[cpu_wp_nr - 1 - i].frequency = + cpu_wp_tbl[i].cpu_rate / 1000; + + if ((cpu_wp_tbl[i].cpu_rate / 1000) < cpu_freq_khz_min) + cpu_freq_khz_min = cpu_wp_tbl[i].cpu_rate / 1000; + + if ((cpu_wp_tbl[i].cpu_rate / 1000) > cpu_freq_khz_max) + cpu_freq_khz_max = cpu_wp_tbl[i].cpu_rate / 1000; + } + + imx_freq_table[i].index = i + 1; + imx_freq_table[i].frequency = cpu_wp_tbl[i].cpu_rate / 1000; + + if ((cpu_wp_tbl[i].cpu_rate / 1000) < cpu_freq_khz_min) + cpu_freq_khz_min = cpu_wp_tbl[i].cpu_rate / 1000; + + if ((cpu_wp_tbl[i].cpu_rate / 1000) > cpu_freq_khz_max) + cpu_freq_khz_max = cpu_wp_tbl[i].cpu_rate / 1000; + + imx_freq_table[i].index = 0; + imx_freq_table[i].frequency = CPUFREQ_TABLE_END; + + policy->cur = policy->min = policy->max = clk_get_rate(cpu_clk) / 1000; + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; + policy->cpuinfo.min_freq = cpu_freq_khz_min; + policy->cpuinfo.max_freq = cpu_freq_khz_max; + + arm_lpm_clk = cpu_freq_khz_min * 1000; + arm_normal_clk = cpu_freq_khz_max * 1000; + + /* Manual states, that PLL stabilizes in two CLK32 periods */ + policy->cpuinfo.transition_latency = 10; + + ret = cpufreq_frequency_table_cpuinfo(policy, imx_freq_table); + if (ret < 0) { + clk_put(cpu_clk); + if (axi_c_clk_support != 0) { + clk_put(main_bus_clk); + clk_put(pll2); + clk_put(axi_a_clk); + clk_put(axi_b_clk); + clk_put(axi_c_clk); + clk_put(emi_core_clk); + clk_put(nfc_clk); + clk_put(ahb_clk); + clk_put(vpu_core_clk); + clk_put(arm_axi_clk); + clk_put(ddr_clk); + clk_put(ipu_clk); + clk_put(vpu_clk); + clk_put(periph_apm_clk); + clk_put(lp_apm); + clk_put(osc); + } + + regulator_put(gp_regulator); + regulator_put(lp_regulator); + printk(KERN_ERR "%s: failed to register i.MXC CPUfreq\n", + __func__); + return ret; + } + cpufreq_frequency_table_get_attr(imx_freq_table, policy->cpu); + + low_bus_freq_mode = 0; + high_bus_freq_mode = 0; + return 0; +} + +static int mxc_cpufreq_driver_exit(struct cpufreq_policy *policy) +{ + cpufreq_frequency_table_put_attr(policy->cpu); + + /* Reset CPU to 665MHz */ + if (!dvfs_core_is_active) + set_cpu_freq(arm_normal_clk); + + if (low_bus_freq_mode) + set_high_bus_freq(); + + clk_put(cpu_clk); + if (axi_c_clk_support != 0) { + clk_put(main_bus_clk); + clk_put(pll2); + clk_put(axi_a_clk); + clk_put(axi_b_clk); + clk_put(axi_c_clk); + clk_put(emi_core_clk); + clk_put(nfc_clk); + clk_put(ahb_clk); + clk_put(vpu_core_clk); + clk_put(arm_axi_clk); + clk_put(ddr_clk); + clk_put(ipu_clk); + clk_put(periph_apm_clk); + clk_put(lp_apm); + clk_put(osc); + } + regulator_put(gp_regulator); + regulator_put(lp_regulator); + return 0; +} + +static struct cpufreq_driver mxc_driver = { + .flags = CPUFREQ_STICKY, + .verify = mxc_verify_speed, + .target = mxc_set_target, + .get = mxc_get_speed, + .init = mxc_cpufreq_driver_init, + .exit = mxc_cpufreq_driver_exit, + .name = "imx", +}; + +static int __devinit mxc_cpufreq_init(void) +{ + return cpufreq_register_driver(&mxc_driver); +} + +static void mxc_cpufreq_exit(void) +{ + cpufreq_unregister_driver(&mxc_driver); +} + +module_init(mxc_cpufreq_init); +module_exit(mxc_cpufreq_exit); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("CPUfreq driver for i.MX"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/arch/arm/plat-mxc/clock.c +++ linux-2.6.28/arch/arm/plat-mxc/clock.c @@ -4,7 +4,7 @@ * 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 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved. * Copyright 2008 Juergen Beisert, kernel@pengutronix.de * * This program is free software; you can redistribute it and/or @@ -25,6 +25,7 @@ /* #define DEBUG */ #include +#include #include #include #include @@ -42,6 +43,7 @@ static LIST_HEAD(clocks); static DEFINE_MUTEX(clocks_mutex); +static DEFINE_SPINLOCK(clockfw_lock); /*------------------------------------------------------------------------- * Standard clock functions defined in include/linux/clk.h @@ -113,14 +115,16 @@ static void __clk_disable(struct clk *clk) { - if (clk == NULL || IS_ERR(clk)) + if (clk == NULL || IS_ERR(clk) || !clk->usecount) return; - __clk_disable(clk->parent); - __clk_disable(clk->secondary); + if (!(--clk->usecount)) { + if (clk->disable) + clk->disable(clk); - if (!(--clk->usecount) && clk->disable) - clk->disable(clk); + __clk_disable(clk->parent); + __clk_disable(clk->secondary); + } } static int __clk_enable(struct clk *clk) @@ -128,12 +132,13 @@ 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); + if (clk->usecount++ == 0) { + __clk_enable(clk->parent); + __clk_enable(clk->secondary); + if (clk->enable) + clk->enable(clk); + } return 0; } @@ -142,15 +147,23 @@ */ int clk_enable(struct clk *clk) { + unsigned long flags; int ret = 0; if (clk == NULL || IS_ERR(clk)) return -EINVAL; - mutex_lock(&clocks_mutex); + spin_lock_irqsave(&clockfw_lock, flags); + ret = __clk_enable(clk); - mutex_unlock(&clocks_mutex); + spin_unlock_irqrestore(&clockfw_lock, flags); + +#if defined(CONFIG_CPU_FREQ) + if ((clk->flags & CPU_FREQ_TRIG_UPDATE) + && (clk_get_usecount(clk) == 1)) + cpufreq_update_policy(0); +#endif return ret; } EXPORT_SYMBOL(clk_enable); @@ -161,15 +174,44 @@ */ void clk_disable(struct clk *clk) { + unsigned long flags; + if (clk == NULL || IS_ERR(clk)) return; - mutex_lock(&clocks_mutex); + spin_lock_irqsave(&clockfw_lock, flags); + __clk_disable(clk); - mutex_unlock(&clocks_mutex); + + spin_unlock_irqrestore(&clockfw_lock, flags); + +#if defined(CONFIG_CPU_FREQ) + if ((clk->flags & CPU_FREQ_TRIG_UPDATE) + && (clk_get_usecount(clk) == 0)) + cpufreq_update_policy(0); +#endif } EXPORT_SYMBOL(clk_disable); +/*! + * @brief Function to get the usage count for the requested clock. + * + * This function returns the reference count for the clock. + * + * @param clk Handle to clock to disable. + * + * @return Returns the usage count for the requested clock. + */ +int clk_get_usecount(struct clk *clk) +{ + if (clk == NULL || IS_ERR(clk)) + return 0; + + return clk->usecount; +} + +EXPORT_SYMBOL(clk_get_usecount); + /* 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 @@ -180,10 +222,7 @@ if (clk == NULL || IS_ERR(clk)) return 0UL; - if (clk->get_rate) - return clk->get_rate(clk); - - return clk_get_rate(clk->parent); + return clk->rate; } EXPORT_SYMBOL(clk_get_rate); @@ -208,19 +247,48 @@ } EXPORT_SYMBOL(clk_round_rate); +/* Propagate rate to children */ +void propagate_rate(struct clk *tclk) +{ + struct clk *clkp; + + if (tclk == NULL || IS_ERR(tclk)) + return; + + pr_debug("mxc clock: finding children of %s-%d\n", tclk->name, + tclk->id); + list_for_each_entry(clkp, &clocks, node) { + if (likely(clkp->parent != tclk)) + continue; + pr_debug("mxc clock: %s-%d: recalculating rate: old = %lu, ", + clkp->name, clkp->id, clkp->rate); + if (likely((u32) clkp->recalc)) + clkp->recalc(clkp); + else + clkp->rate = tclk->rate; + pr_debug("new = %lu\n", clkp->rate); + propagate_rate(clkp); + } +} + /* 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) { + unsigned long flags; int ret = -EINVAL; if (clk == NULL || IS_ERR(clk) || clk->set_rate == NULL || rate == 0) return ret; - mutex_lock(&clocks_mutex); + spin_lock_irqsave(&clockfw_lock, flags); + ret = clk->set_rate(clk, rate); - mutex_unlock(&clocks_mutex); + if (unlikely((ret == 0) && (clk->flags & RATE_PROPAGATES))) + propagate_rate(clk); + + spin_unlock_irqrestore(&clockfw_lock, flags); return ret; } @@ -229,17 +297,35 @@ /* Set the clock's parent to another clock source */ int clk_set_parent(struct clk *clk, struct clk *parent) { + unsigned long flags; int ret = -EINVAL; + struct clk *prev_parent = clk->parent; if (clk == NULL || IS_ERR(clk) || parent == NULL || IS_ERR(parent) || clk->set_parent == NULL) return ret; - mutex_lock(&clocks_mutex); + if (clk->usecount != 0) { + clk_enable(parent); + } + + spin_lock_irqsave(&clockfw_lock, flags); ret = clk->set_parent(clk, parent); - if (ret == 0) + if (ret == 0) { clk->parent = parent; - mutex_unlock(&clocks_mutex); + if (clk->recalc) { + clk->recalc(clk); + } else { + clk->rate = parent->rate; + } + if (unlikely(clk->flags & RATE_PROPAGATES)) + propagate_rate(clk); + } + spin_unlock_irqrestore(&clockfw_lock, flags); + + if (clk->usecount != 0) { + clk_disable(prev_parent); + } return ret; } --- linux-2.6.28.orig/arch/arm/plat-mxc/include/mach/system.h +++ linux-2.6.28/arch/arm/plat-mxc/include/mach/system.h @@ -1,7 +1,7 @@ /* * Copyright (C) 1999 ARM Limited * Copyright (C) 2000 Deep Blue Solutions Ltd - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2004-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 @@ -21,14 +21,17 @@ #ifndef __ASM_ARCH_MXC_SYSTEM_H__ #define __ASM_ARCH_MXC_SYSTEM_H__ -static inline void arch_idle(void) -{ - cpu_do_idle(); -} +/*! + * This function puts the CPU into idle mode. It is called by default_idle() + * in process.c file. + */ +extern void arch_idle(void); -static inline void arch_reset(char mode) -{ - cpu_reset(0); -} +/* + * This function resets the system. It is called by machine_restart(). + * + * @param mode indicates different kinds of resets + */ +extern void arch_reset(char mode); -#endif /* __ASM_ARCH_MXC_SYSTEM_H__ */ +#endif /* __ASM_ARCH_MXC_SYSTEM_H__ */ --- linux-2.6.28.orig/arch/arm/plat-mxc/include/mach/mxc.h +++ linux-2.6.28/arch/arm/plat-mxc/include/mach/mxc.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved. * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) * * This program is free software; you can redistribute it and/or @@ -24,19 +24,385 @@ #error "Do not include directly." #endif -/* clean up all things that are not used */ -#ifndef CONFIG_ARCH_MX3 -# define cpu_is_mx31() (0) +#ifndef __ASSEMBLY__ +#include + +/*! + * @ingroup MSL_MX27 MSL_MX31 MSL_MXC91321 MSL_MX37 + */ +/*! + * gpio port structure + */ +struct mxc_gpio_port { + u32 num; /*!< gpio port number */ + u32 base; /*!< gpio port base VA */ +#ifdef MXC_GPIO_SPLIT_IRQ_2 + u16 irq_0_15, irq_16_31; +#else + u16 irq; /*!< irq number to the core */ #endif + u16 virtual_irq_start; /*!< virtual irq start number */ +}; +/*! + * This structure is used to define the One wire platform data. + * It includes search rom accelerator. + */ + +struct mxc_w1_config { + int search_rom_accelerator; +}; +/*! + * This structure is used to define the SPI master controller's platform + * data. It includes the SPI bus number and the maximum number of + * slaves/chips it supports. + */ +struct mxc_spi_master { + /*! + * SPI Master's bus number. + */ + unsigned int bus_num; + /*! + * SPI Master's maximum number of chip selects. + */ + unsigned int maxchipselect; + /*! + * CSPI Hardware Version. + */ + unsigned int spi_version; +}; + +struct mxc_ipu_config { + int rev; + struct clk *di_clk[2]; +}; + +struct mxc_ir_platform_data { + int uart_ir_mux; + int ir_rx_invert; + int ir_tx_invert; + struct clk *uart_clk; +}; + +struct mxc_i2c_platform_data { + u32 i2c_clk; +}; + +/* + * This struct is to define the number of SSIs on a platform, + * DAM source port config, DAM external port config, + * regulator names, and other stuff audio needs. + */ +struct mxc_audio_platform_data { + int ssi_num; + int src_port; + int ext_port; + + int intr_id_hp; + int ext_ram; + struct clk *ssi_clk[2]; + char *regulator1; + char *regulator2; + + int hp_irq; + int (*hp_status) (void); + + char *vddio_reg; + char *vdda_reg; + char *vddd_reg; + int vddio; /* voltage of VDDIO (uv) */ + int vdda; /* voltage of vdda (uv) */ + int vddd; /* voltage of vddd (uv), 0 if not connected */ + int sysclk; + + int (*init) (void); /* board specific init */ + int (*amp_enable) (int enable); + int (*finit) (void); /* board specific finit */ + void *priv; /* used by board specific functions */ +}; + +struct mxc_spdif_platform_data { + int spdif_tx; + int spdif_rx; + int spdif_clk_44100; + int spdif_clk_48000; + int spdif_clkid; + struct clk *spdif_clk; + struct clk *spdif_core_clk; +}; + +struct mxc_asrc_platform_data { + struct clk *asrc_core_clk; + struct clk *asrc_audio_clk; + unsigned int channel_bits; +}; + +struct mxc_bt_platform_data { + char *bt_vdd; + char *bt_vdd_parent; + char *bt_vusb; + char *bt_vusb_parent; + void (*bt_reset) (void); +}; + +struct mxc_lightsensor_platform_data { + char *vdd_reg; + int rext; +}; + +struct mxc_fb_platform_data { + struct fb_videomode *mode; + u32 interface_pix_fmt; +}; + +struct mxc_lcd_platform_data { + char *io_reg; + char *core_reg; + char *analog_reg; + void (*reset) (void); +}; + +struct mxc_dvfs_platform_data { + /** Supply voltage regulator name string */ + char *reg_id; + /* CPU clock name string */ + char *clk1_id; + /* DVFS clock name string */ + char *clk2_id; + /* GPC control reg address */ + unsigned int gpc_cntr_reg_addr; + /* GPC voltage counter reg address */ + unsigned int gpc_vcr_reg_addr; + /* DVFS threshold reg address */ + unsigned int dvfs_thrs_reg_addr; + /* DVFS counters reg address */ + unsigned int dvfs_coun_reg_addr; + /* DVFS EMAC reg address */ + unsigned int dvfs_emac_reg_addr; + /* DVFS control reg address */ + unsigned int dvfs_cntr_reg_addr; + /* DIV3CK mask */ + u32 div3ck_mask; + /* DIV3CK offset */ + int div3ck_offset; + /* DIV3CK value */ + int div3ck_val; + /* EMAC value */ + int emac_val; + /* Frequency increase threshold. Increase frequency change request + will be sent if DVFS counter value will be more than this value */ + int upthr_val; + /* Frequency decrease threshold. Decrease frequency change request + will be sent if DVFS counter value will be less than this value */ + int dnthr_val; + /* Panic threshold. Panic frequency change request + will be sent if DVFS counter value will be more than this value */ + int pncthr_val; + /* The amount of times the up threshold should be exceeded + before DVFS will trigger frequency increase request */ + int upcnt_val; + /* The amount of times the down threshold should be exceeded + before DVFS will trigger frequency decrease request */ + int dncnt_val; + /* Delay time in us */ + int delay_time; + /* Number of woking points supported */ + int num_wp; +}; + +struct mxc_tsc_platform_data { + char *vdd_reg; + int penup_threshold; + void (*active) (void); + void (*inactive) (void); +}; + +struct mxc_tvout_platform_data { + char *io_reg; + char *core_reg; + char *analog_reg; + u32 detect_line; +}; + +struct mxc_tvin_platform_data { + char *dvddio_reg; + char *dvdd_reg; + char *avdd_reg; + char *pvdd_reg; + void (*pwdn) (int pwdn); + void (*reset) (void); +}; + +/*! Platform data for the IDE drive structure. */ +struct mxc_ide_platform_data { + char *power_drive; /*!< The power pointer */ + char *power_io; /*!< The power pointer */ +}; -#ifndef CONFIG_MACH_MX27 -# define cpu_is_mx27() (0) +struct mxc_camera_platform_data { + char *core_regulator; + char *io_regulator; + char *analog_regulator; + char *gpo_regulator; + u32 mclk; + u32 csi; +}; + +/*gpo1-3 is in fixed state by hardware design, + * only deal with reset pin and clock_enable pin + * only poll mode can be used to control the chip, + * interrupt mode is not supported by 3ds*/ +struct mxc_fm_platform_data { + char *reg_vio; + char *reg_vdd; + void (*gpio_get) (void); + void (*gpio_put) (void); + void (*reset) (void); + void (*clock_ctl) (int flag); + u8 sksnr; /*0,disable;1,most stop;0xf,fewest stop*/ + u8 skcnt; /*0,disable;1,most stop;0xf,fewest stop*/ + /* + 00 = 87.5-108 MHz (USA,Europe) (Default). + 01 = 76-108 MHz (Japan wide band). + 10 = 76-90 MHz (Japan). + 11 = Reserved. + */ + u8 band; + /* + 00 = 200 kHz (USA, Australia) (default). + 01 = 100 kHz (Europe, Japan). + 10 = 50 kHz. + */ + u8 space; + u8 seekth; +}; + +struct mxc_mma7450_platform_data { + char *reg_dvdd_io; + char *reg_avdd; + void (*gpio_pin_get) (void); + void (*gpio_pin_put) (void); + int int1; + int int2; +}; + +struct mxc_keyp_platform_data { + u16 *matrix; + void (*active) (void); + void (*inactive) (void); + char *vdd_reg; +}; + +struct mxc_unifi_platform_data { + void (*hardreset) (void); + void (*enable) (int en); + /* power parameters */ + char *reg_gpo1; + char *reg_gpo2; + char *reg_1v5_ana_bb; + char *reg_vdd_vpa; + char *reg_1v5_dd; + + int host_id; + + void *priv; +}; + +struct mxc_gps_platform_data { + char *core_reg; + char *analog_reg; +}; + +struct mxc_mlb_platform_data { + u32 buf_address; + u32 phy_address; + char *reg_nvcc; + char *mlb_clk; +}; + +struct flexcan_platform_data { + char *core_reg; + char *io_reg; + void (*xcvr_enable) (int id, int en); + void (*active) (int id); + void (*inactive) (int id); +}; + +struct mxc_srtc_platform_data { + u32 srtc_sec_mode_addr; +}; + +struct tve_platform_data { + char *dac_reg; + char *dig_reg; +}; + +extern void mxc_wd_reset(void); +unsigned long board_get_ckih_rate(void); + +int mxc_snoop_set_config(u32 num, unsigned long base, int size); +int mxc_snoop_get_status(u32 num, u32 * statl, u32 * stath); + +struct platform_device; +void mxc_pg_enable(struct platform_device *pdev); +void mxc_pg_disable(struct platform_device *pdev); + +struct mxc_unifi_platform_data *get_unifi_plat_data(void); + +#endif /* __ASSEMBLY__ */ + +#define MUX_IO_P 29 +#define MUX_IO_I 24 +#define IOMUX_TO_GPIO(pin) ((((unsigned int)pin >> MUX_IO_P) * GPIO_NUM_PIN) + ((pin >> MUX_IO_I) & ((1 << (MUX_IO_P - MUX_IO_I)) -1))) +#define IOMUX_TO_IRQ(pin) (MXC_GPIO_INT_BASE + IOMUX_TO_GPIO(pin)) +#define GPIO_TO_PORT(n) (n / GPIO_NUM_PIN) +#define GPIO_TO_INDEX(n) (n % GPIO_NUM_PIN) + +/* DMA driver defines */ +#define MXC_IDE_DMA_WATERMARK 32 /* DMA watermark level in bytes */ +#define MXC_IDE_DMA_BD_NR (512/3/4) /* Number of BDs per channel */ + +#ifndef IS_MEM_DEVICE_NONSHARED +/* all peripherals on MXC so far are below 0x80000000 but leave L2CC alone */ +#define IS_MEM_DEVICE_NONSHARED(x) ((x) < 0x80000000 && (x) != L2CC_BASE_ADDR) #endif +/*! + * DPTC GP and LP ID + */ +#define DPTC_GP_ID 0 +#define DPTC_LP_ID 1 + +#ifndef __ASSEMBLY__ +#include + +struct cpu_wp { + u32 pll_reg; + u32 pll_rate; + u32 cpu_rate; + u32 pdr0_reg; + u32 pdf; + u32 mfi; + u32 mfd; + u32 mfn; + u32 cpu_voltage; + u32 cpu_podf; +}; + +#ifndef CONFIG_ARCH_MX51 +struct cpu_wp *get_cpu_wp(int *wp); +#endif + +enum mxc_cpu_pwr_mode { + WAIT_CLOCKED, /* wfi only */ + WAIT_UNCLOCKED, /* WAIT */ + WAIT_UNCLOCKED_POWER_OFF, /* WAIT + SRPG */ + STOP_POWER_ON, /* just STOP */ + STOP_POWER_OFF, /* STOP + SRPG */ +}; + +void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode); +int tzic_enable_wake(int is_idle); +void gpio_activate_audio_ports(void); -#if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX2) -#define CSCR_U(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10) -#define CSCR_L(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10 + 0x4) -#define CSCR_A(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10 + 0x8) #endif -#endif /* __ASM_ARCH_MXC_H__ */ +#endif /* __ASM_ARCH_MXC_H__ */ --- linux-2.6.28.orig/arch/arm/plat-mxc/include/mach/gpio.h +++ linux-2.6.28/arch/arm/plat-mxc/include/mach/gpio.h @@ -1,42 +1,167 @@ /* - * 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. + * Copyright 2004-2008 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_GPIO_H__ #define __ASM_ARCH_MXC_GPIO_H__ -#include -#include +/*! + * @defgroup GPIO General Purpose Input Output (GPIO) + */ -/* 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; -}; +/*! + * @file arch-mxc/gpio.h + * @brief This file contains the GPIO API functions. + * + * @ingroup GPIO + */ + +#include +#include -int mxc_gpio_init(struct mxc_gpio_port*, int); +typedef unsigned int iomux_pin_name_t; +/* gpio related defines */ + +/*! + * There are two queues for registered GPIO ISRs. One is for high priority and + * the other is for low priority. The ISRs in the high priority queue will be + * called first before the low priority queue if more than one GPIO interrupt + * occurs at the same time. + */ +enum gpio_prio { + GPIO_HIGH_PRIO = 0, /*!< high priority queue */ + GPIO_LOW_PRIO /*!< low priority queue */ +}; + +/*! + * This enumeration data type defines various different ways for interrupting + * the ARM core from GPIO signals. The way to interrupt the core is dictated + * by the external hardware. + */ +typedef enum gpio_int_cfg { +#if defined(CONFIG_ARCH_MX21) || defined(CONFIG_ARCH_MX27) + GPIO_INT_LOW_LEV = 0x3, /*!< low level sensitive */ + GPIO_INT_HIGH_LEV = 0x2, /*!< high level sensitive */ + GPIO_INT_RISE_EDGE = 0x0, /*!< rising edge sensitive */ + GPIO_INT_FALL_EDGE = 0x1, /*!< falling edge sensitive */ + GPIO_INT_NONE = 0x4 /*!< No interrupt */ +#else + GPIO_INT_LOW_LEV = 0x0, /*!< low level sensitive */ + GPIO_INT_HIGH_LEV = 0x1, /*!< high level sensitive */ + GPIO_INT_RISE_EDGE = 0x2, /*!< rising edge sensitive */ + GPIO_INT_FALL_EDGE = 0x3, /*!< falling edge sensitive */ + GPIO_INT_NONE = 0x4 /*!< No interrupt */ #endif +} gpio_edge_t; + +typedef irqreturn_t(*gpio_irq_handler) (int, void *); + +/*! + * This function configures the GPIO signal to be either input or output. For + * input signals used for generating interrupts for the ARM core, how the + * interrupts being triggered is also passed in via \a icr. For output signals, + * the \a icr value doesn't matter. + * + * @param port specified port with 0-GPIO port 1; 1-GPIO port 2 + * @param sig_no specified GPIO signal (0 based) + * @param out #true for output, #false for input + * @param icr value defined in \b #gpio_int_cfg + */ +void gpio_config(__u32 port, __u32 sig_no, bool out, enum gpio_int_cfg icr); + +/*! + * This function sets a GPIO signal value. + * + * @param port specified port with 0-GPIO port 1; 1-GPIO port 2 + * @param sig_no specified GPIO signal (0 based) + * @param data value to be set (only 0 or 1 is valid) + */ +void gpio_set_data(__u32 port, __u32 sig_no, __u32 data); + +/*! + * This function returns the value of the GPIO signal. + * + * @param port specified port with 0-GPIO port 1; 1-GPIO port 2 + * @param sig_no specified GPIO signal (0 based) + * + * @return Value of the GPIO signal + */ +__u32 gpio_get_data(__u32 port, __u32 sig_no); + +/*! + * This function is responsible for registering a GPIO signal's ISR. + * + * @param port specified port with 0-GPIO port 1; 1-GPIO port 2 + * @param sig_no specified GPIO signal (0 based) + * @param prio priority as defined in \b enum \b #gpio_prio + * @param handler GPIO ISR function pointer for the GPIO signal + * @param irq_flags irq flags (not used) + * @param devname device name associated with the interrupt + * @param dev_id some unique information for the ISR + * + * @return 0 if successful; non-zero otherwise. + */ +int gpio_request_irq(__u32 port, __u32 sig_no, enum gpio_prio prio, + gpio_irq_handler handler, __u32 irq_flags, + const char *devname, void *dev_id); + +/*! + * This function un-registers an ISR with the GPIO interrupt module. + * + * @param port specified port with 0-GPIO port 1; 1-GPIO port 2 + * @param sig_no specified GPIO signal (0 based) + * @param prio priority as defined in \b enum \b #gpio_prio + */ +void gpio_free_irq(__u32 port, __u32 sig_no, enum gpio_prio prio); + +/*! + * Request ownership for a GPIO pin. The caller has to check the return value + * of this function to make sure it returns 0 before make use of that pin. + * @param pin a name defined by \b iomux_pin_name_t + * @return 0 if successful; Non-zero otherwise + */ +int mxc_request_gpio(iomux_pin_name_t pin); + +/*! + * Exported function to set a GPIO pin's direction + * @param pin a name defined by \b iomux_pin_name_t + * @param is_input 1 (or non-zero) for input; 0 for output + */ +void mxc_set_gpio_direction(iomux_pin_name_t pin, int is_input); + +/*! + * Exported function to set a GPIO pin's data output + * @param pin a name defined by \b iomux_pin_name_t + * @param data value to be set (only 0 or 1 is valid) + */ +void mxc_set_gpio_dataout(iomux_pin_name_t pin, u32 data); + +/*! + * Return the data value of a GPIO signal. + * @param pin a name defined by \b iomux_pin_name_t + * + * @return value (0 or 1) of the GPIO signal; -1 if pass in invalid pin + */ +int mxc_get_gpio_datain(iomux_pin_name_t pin); + +/*! + * Release ownership for a GPIO pin + * @param pin a name defined by \b iomux_pin_name_t + */ +void mxc_free_gpio(iomux_pin_name_t pin); + +/*! + * GPIO driver initialization + * @return always 0 + */ +int mxc_gpio_init(void); +#endif /* __ASM_ARCH_MXC_GPIO_H__ */ --- linux-2.6.28.orig/arch/arm/plat-mxc/include/mach/fsl_usb.h +++ linux-2.6.28/arch/arm/plat-mxc/include/mach/fsl_usb.h @@ -0,0 +1,79 @@ +/* + * Copyright 2005-2009 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 + */ + +/* + * USB Host side, platform-specific functionality. + */ + +#include +#include + +/* ehci_arc_hc_driver.flags value */ +#define FSL_PLATFORM_HC_FLAGS (HCD_USB2 | HCD_MEMORY) + +static void fsl_setup_phy(struct ehci_hcd *ehci, + enum fsl_usb2_phy_modes phy_mode, + int port_offset); + +static inline void fsl_platform_usb_setup(struct ehci_hcd *ehci) +{ + struct fsl_usb2_platform_data *pdata; + + pdata = ehci_to_hcd(ehci)->self.controller->platform_data; + fsl_setup_phy(ehci, pdata->phy_mode, 0); +} + +static inline void fsl_platform_set_host_mode(struct usb_hcd *hcd) +{ + unsigned int temp; + struct fsl_usb2_platform_data *pdata; + + pdata = hcd->self.controller->platform_data; + + if (pdata->xcvr_ops && pdata->xcvr_ops->set_host) + pdata->xcvr_ops->set_host(); + + /* set host mode */ + temp = readl(hcd->regs + 0x1a8); + writel(temp | USBMODE_CM_HOST, hcd->regs + 0x1a8); +} + +/* Needed for i2c/serial transceivers */ +static inline void +fsl_platform_set_vbus_power(struct fsl_usb2_platform_data *pdata, int on) +{ + if (pdata->xcvr_ops && pdata->xcvr_ops->set_vbus_power) + pdata->xcvr_ops->set_vbus_power(pdata->xcvr_ops, pdata, on); +} + +/* Set USB AHB burst length for host */ +static inline void fsl_platform_set_ahb_burst(struct usb_hcd *hcd) +{ + struct fsl_usb2_platform_data *pdata; + unsigned int temp; + + pdata = hcd->self.controller->platform_data; + if (pdata->change_ahb_burst) { + temp = readl(hcd->regs + FSL_SOC_USB_SBUSCFG); + writel((temp & (~(0x7))) | pdata->ahb_burst_mode, + hcd->regs + FSL_SOC_USB_SBUSCFG); + } + + /* Increase TX fifo threshold for USB+ATA for i.mx35 2.0 */ + if (cpu_is_mx35_rev(CHIP_REV_2_0) >= 1) { + temp = readl(hcd->regs + FSL_SOC_USB_TXFILLTUNING); + /* Change TX FIFO threshold to be 0x20 */ + writel((temp & (~(0x3f << 16))) | (0x20 << 16), + hcd->regs + FSL_SOC_USB_TXFILLTUNING); + } +} --- linux-2.6.28.orig/arch/arm/plat-mxc/include/mach/irqs.h +++ linux-2.6.28/arch/arm/plat-mxc/include/mach/irqs.h @@ -14,4 +14,21 @@ #include extern void imx_irq_set_priority(unsigned char irq, unsigned char prio); +#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_INTS + +/* Number of fast interrupts */ +#define NR_FIQS MXC_MAX_INTS + +/* + * This function is used to get the AVIC Lo and Hi interrupts + * that are enabled as wake up sources to wake up the core from suspend + */ +void mxc_get_wake_irq(u32 * wake_src[]); + #endif /* __ASM_ARCH_MXC_IRQS_H__ */ --- linux-2.6.28.orig/arch/arm/plat-mxc/include/mach/memory.h +++ linux-2.6.28/arch/arm/plat-mxc/include/mach/memory.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -11,7 +11,57 @@ #ifndef __ASM_ARCH_MXC_MEMORY_H__ #define __ASM_ARCH_MXC_MEMORY_H__ -#include +#include +#include + +/* Start of physical RAM */ +#if defined(CONFIG_MACH_MX35EVB) || defined(CONFIG_ARCH_MX51) +#define PHYS_OFFSET UL(0x90000000) +#endif + +#ifdef CONFIG_MACH_MX27ADS +#define PHYS_OFFSET UL(0xA0000000) +#endif + +#ifdef CONFIG_MACH_MX37_3DS +#define PHYS_OFFSET UL(0x40000000) +#endif + +#ifndef PHYS_OFFSET +#define PHYS_OFFSET UL(0x80000000) +#endif + +/* Size of contiguous memory for DMA and other h/w blocks */ +#ifdef CONFIG_ARCH_MX51 +#define CONSISTENT_DMA_SIZE (64 * SZ_1M) +#else +#define CONSISTENT_DMA_SIZE (32 * SZ_1M) +#endif + +#ifndef __ASSEMBLY__ + +#ifdef CONFIG_DMA_ZONE_SIZE +#define MXC_DMA_ZONE_SIZE ((CONFIG_DMA_ZONE_SIZE * SZ_1M) >> PAGE_SHIFT) +#else +#define MXC_DMA_ZONE_SIZE ((12 * SZ_1M) >> PAGE_SHIFT) +#endif + +static inline void __arch_adjust_zones(int node, unsigned long *zone_size, + unsigned long *zhole_size) +{ + if (node != 0) + return; + /* Create separate zone to reserve memory for DMA */ + zone_size[1] = zone_size[0] - MXC_DMA_ZONE_SIZE; + zone_size[0] = MXC_DMA_ZONE_SIZE; + zhole_size[1] = zhole_size[0]; + zhole_size[0] = 0; +} + +#define arch_adjust_zones(node, size, holes) \ + __arch_adjust_zones(node, size, holes) + +#endif /* * Virtual view <-> DMA view memory address translations --- linux-2.6.28.orig/arch/arm/plat-mxc/include/mach/mxc_scc.h +++ linux-2.6.28/arch/arm/plat-mxc/include/mach/mxc_scc.h @@ -0,0 +1,45 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @file arch-mxc/mxc_scc.h + * + * @brief This is intended to be the file which contains all of code or changes + * needed to port the driver. + * + * @ingroup MXCSCC + */ + +#ifndef __ASM_ARCH_MXC_SCC_H__ +#define __ASM_ARCH_MXC_SCC_H__ + +#include + +/*! + * Expected to come from platform header files. + * This symbol must be the address of the SCC + */ +#define SCC_BASE SCC_BASE_ADDR + +/*! + * This must be the interrupt line number of the SCM interrupt. + */ +#define INT_SCC_SCM MXC_INT_SCC_SCM + +/*! + * if #USE_SMN_INTERRUPT is defined, this must be the interrupt line number of + * the SMN interrupt. + */ +#define INT_SCC_SMN MXC_INT_SCC_SMN + +#endif --- linux-2.6.28.orig/arch/arm/plat-mxc/include/mach/dma.h +++ linux-2.6.28/arch/arm/plat-mxc/include/mach/dma.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -11,4 +11,253 @@ #ifndef __ASM_ARCH_MXC_DMA_H__ #define __ASM_ARCH_MXC_DMA_H__ +#define MXC_DMA_DYNAMIC_CHANNEL 255 + +#define MXC_DMA_DONE 0x0 +#define MXC_DMA_REQUEST_TIMEOUT 0x1 +#define MXC_DMA_TRANSFER_ERROR 0x2 + +/*! This defines the list of device ID's for DMA */ +typedef enum mxc_dma_device { + MXC_DMA_UART1_RX, + MXC_DMA_UART1_TX, + MXC_DMA_UART2_RX, + MXC_DMA_UART2_TX, + MXC_DMA_UART3_RX, + MXC_DMA_UART3_TX, + MXC_DMA_UART4_RX, + MXC_DMA_UART4_TX, + MXC_DMA_UART5_RX, + MXC_DMA_UART5_TX, + MXC_DMA_UART6_RX, + MXC_DMA_UART6_TX, + MXC_DMA_MMC1_WIDTH_1, + MXC_DMA_MMC1_WIDTH_4, + MXC_DMA_MMC2_WIDTH_1, + MXC_DMA_MMC2_WIDTH_4, + MXC_DMA_SSI1_8BIT_RX0, + MXC_DMA_SSI1_8BIT_TX0, + MXC_DMA_SSI1_16BIT_RX0, + MXC_DMA_SSI1_16BIT_TX0, + MXC_DMA_SSI1_24BIT_RX0, + MXC_DMA_SSI1_24BIT_TX0, + MXC_DMA_SSI1_8BIT_RX1, + MXC_DMA_SSI1_8BIT_TX1, + MXC_DMA_SSI1_16BIT_RX1, + MXC_DMA_SSI1_16BIT_TX1, + MXC_DMA_SSI1_24BIT_RX1, + MXC_DMA_SSI1_24BIT_TX1, + MXC_DMA_SSI2_8BIT_RX0, + MXC_DMA_SSI2_8BIT_TX0, + MXC_DMA_SSI2_16BIT_RX0, + MXC_DMA_SSI2_16BIT_TX0, + MXC_DMA_SSI2_24BIT_RX0, + MXC_DMA_SSI2_24BIT_TX0, + MXC_DMA_SSI2_8BIT_RX1, + MXC_DMA_SSI2_8BIT_TX1, + MXC_DMA_SSI2_16BIT_RX1, + MXC_DMA_SSI2_16BIT_TX1, + MXC_DMA_SSI2_24BIT_RX1, + MXC_DMA_SSI2_24BIT_TX1, + MXC_DMA_FIR_RX, + MXC_DMA_FIR_TX, + MXC_DMA_CSPI1_RX, + MXC_DMA_CSPI1_TX, + MXC_DMA_CSPI2_RX, + MXC_DMA_CSPI2_TX, + MXC_DMA_CSPI3_RX, + MXC_DMA_CSPI3_TX, + MXC_DMA_ATA_RX, + MXC_DMA_ATA_TX, + MXC_DMA_MEMORY, + MXC_DMA_FIFO_MEMORY, + MXC_DMA_DSP_PACKET_DATA0_RD, + MXC_DMA_DSP_PACKET_DATA0_WR, + MXC_DMA_DSP_PACKET_DATA1_RD, + MXC_DMA_DSP_PACKET_DATA1_WR, + MXC_DMA_DSP_LOG0_CHNL, + MXC_DMA_DSP_LOG1_CHNL, + MXC_DMA_DSP_LOG2_CHNL, + MXC_DMA_DSP_LOG3_CHNL, + MXC_DMA_CSI_RX, + MXC_DMA_SPDIF_16BIT_TX, + MXC_DMA_SPDIF_16BIT_RX, + MXC_DMA_SPDIF_32BIT_TX, + MXC_DMA_SPDIF_32BIT_RX, + MXC_DMA_ASRC_A_RX, + MXC_DMA_ASRC_A_TX, + MXC_DMA_ASRC_B_RX, + MXC_DMA_ASRC_B_TX, + MXC_DMA_ASRC_C_RX, + MXC_DMA_ASRC_C_TX, + MXC_DMA_ESAI_16BIT_RX, + MXC_DMA_ESAI_16BIT_TX, + MXC_DMA_ESAI_24BIT_RX, + MXC_DMA_ESAI_24BIT_TX, + MXC_DMA_TEST_RAM2D2RAM, + MXC_DMA_TEST_RAM2RAM2D, + MXC_DMA_TEST_RAM2D2RAM2D, + MXC_DMA_TEST_RAM2RAM, + MXC_DMA_TEST_HW_CHAINING, + MXC_DMA_TEST_SW_CHAINING +} mxc_dma_device_t; + +/*! This defines the prototype of callback funtion registered by the drivers */ +typedef void (*mxc_dma_callback_t) (void *arg, int error_status, + unsigned int count); + +/*! This defines the type of DMA transfer requested */ +typedef enum mxc_dma_mode { + MXC_DMA_MODE_READ, + MXC_DMA_MODE_WRITE, +} mxc_dma_mode_t; + +/*! This defines the DMA channel parameters */ +typedef struct mxc_dma_channel { + unsigned int active:1; /*!< When there has a active tranfer, it is set to 1 */ + unsigned int lock; /*!< Defines the channel is allocated or not */ + int curr_buf; /*!< Current buffer */ + mxc_dma_mode_t mode; /*!< Read or Write */ + unsigned int channel; /*!< Channel info */ + unsigned int dynamic:1; /*!< Channel not statically allocated when 1 */ + char *dev_name; /*!< Device name */ + void *private; /*!< Private structure for platform */ + mxc_dma_callback_t cb_fn; /*!< The callback function */ + void *cb_args; /*!< The argument of callback function */ +} mxc_dma_channel_t; + +/*! This structure contains the information about a dma transfer */ +typedef struct mxc_dma_requestbuf { + dma_addr_t src_addr; /*!< source address */ + dma_addr_t dst_addr; /*!< destination address */ + int num_of_bytes; /*!< the length of this transfer : bytes */ +} mxc_dma_requestbuf_t; + +#if defined(CONFIG_ARCH_MX27) || defined(CONFIG_ARCH_MX21) +#include +#else +#include +#endif + +/*! + * This function is generally called by the driver at open time. + * The DMA driver would do any initialization steps that is required + * to get the channel ready for data transfer. + * + * @param channel_id a pre-defined id. The peripheral driver would specify + * the id associated with its peripheral. This would be + * used by the DMA driver to identify the peripheral + * requesting DMA and do the necessary setup on the + * channel associated with the particular peripheral. + * The DMA driver could use static or dynamic DMA channel + * allocation. + * @param dev_name module name or device name + * @return returns a negative number on error if request for a DMA channel did not + * succeed, returns the channel number to be used on success. + */ +extern int mxc_dma_request(mxc_dma_device_t channel_id, char *dev_name); + +/*! + * This function is generally called by the driver at close time. The DMA + * driver would do any cleanup associated with this channel. + * + * @param channel_num the channel number returned at request time. This + * would be used by the DMA driver to identify the calling + * driver and do the necessary cleanup on the channel + * associated with the particular peripheral + * @return returns a negative number on error or 0 on success + */ +extern int mxc_dma_free(int channel_num); + +/*! + * This function would just configure the buffers specified by the user into + * dma channel. The caller must call mxc_dma_enable to start this transfer. + * + * @param channel_num the channel number returned at request time. This + * would be used by the DMA driver to identify the calling + * driver and do the necessary cleanup on the channel + * associated with the particular peripheral + * @param dma_buf an array of physical addresses to the user defined + * buffers. The caller must guarantee the dma_buf is + * available until the transfer is completed. + * @param num_buf number of buffers in the array + * @param mode specifies whether this is READ or WRITE operation + * @return This function returns a negative number on error if buffer could not be + * added with DMA for transfer. On Success, it returns 0 + */ +extern int mxc_dma_config(int channel_num, mxc_dma_requestbuf_t * dma_buf, + int num_buf, mxc_dma_mode_t mode); + +/*! + * This function would just configure the scatterlist specified by the + * user into dma channel. This is a slight variation of mxc_dma_config(), + * it is provided for the convenience of drivers that have a scatterlist + * passed into them. It is the calling driver's responsibility to have the + * correct physical address filled in the "dma_address" field of the + * scatterlist. + * + * @param channel_num the channel number returned at request time. This + * would be used by the DMA driver to identify the calling + * driver and do the necessary cleanup on the channel + * associated with the particular peripheral + * @param sg a scatterlist of buffers. The caller must guarantee + * the dma_buf is available until the transfer is + * completed. + * @param num_buf number of buffers in the array + * @param num_of_bytes total number of bytes to transfer. If set to 0, this + * would imply to use the length field of the scatterlist + * for each DMA transfer. Else it would calculate the size + * for each DMA transfer. + * @param mode specifies whether this is READ or WRITE operation + * @return This function returns a negative number on error if buffer could not + * be added with DMA for transfer. On Success, it returns 0 + */ +extern int mxc_dma_sg_config(int channel_num, struct scatterlist *sg, + int num_buf, int num_of_bytes, + mxc_dma_mode_t mode); + +/*! + * This function is provided if the driver would like to set/change its + * callback function. + * + * @param channel_num the channel number returned at request time. This + * would be used by the DMA driver to identify the calling + * driver and do the necessary cleanup on the channel + * associated with the particular peripheral + * @param callback a callback function to provide notification on transfer + * completion, user could specify NULL if he does not wish + * to be notified + * @param arg an argument that gets passed in to the callback + * function, used by the user to do any driver specific + * operations. + * @return this function returns a negative number on error if the callback + * could not be set for the channel or 0 on success + */ +extern int mxc_dma_callback_set(int channel_num, mxc_dma_callback_t callback, + void *arg); + +/*! + * This stops the DMA channel and any ongoing transfers. Subsequent use of + * mxc_dma_enable() will restart the channel and restart the transfer. + * + * @param channel_num the channel number returned at request time. This + * would be used by the DMA driver to identify the calling + * driver and do the necessary cleanup on the channel + * associated with the particular peripheral + * @return returns a negative number on error or 0 on success + */ +extern int mxc_dma_disable(int channel_num); + +/*! + * This starts DMA transfer. Or it restarts DMA on a stopped channel + * previously stopped with mxc_dma_disable(). + * + * @param channel_num the channel number returned at request time. This + * would be used by the DMA driver to identify the calling + * driver and do the necessary cleanup on the channel + * associated with the particular peripheral + * @return returns a negative number on error or 0 on success + */ +extern int mxc_dma_enable(int channel_num); + #endif --- linux-2.6.28.orig/arch/arm/plat-mxc/include/mach/arc_otg.h +++ linux-2.6.28/arch/arm/plat-mxc/include/mach/arc_otg.h @@ -0,0 +1,339 @@ +/* + * Copyright 2005-2009 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_ARC_OTG_H__ +#define __ASM_ARCH_MXC_ARC_OTG_H__ + +#define USB_OTGREGS_BASE (OTG_BASE_ADDR + 0x000) +#define USB_H1REGS_BASE (OTG_BASE_ADDR + 0x200) +#define USB_H2REGS_BASE (OTG_BASE_ADDR + 0x400) +#ifdef CONFIG_ARCH_MX51 +#define USB_H3REGS_BASE (OTG_BASE_ADDR + 0x600) +#define USB_OTHERREGS_BASE (OTG_BASE_ADDR + 0x800) +#else +#define USB_OTHERREGS_BASE (OTG_BASE_ADDR + 0x600) +#endif + + +#define USBOTG_REG32(offset) (*((volatile u32 *)(IO_ADDRESS(USB_OTGREGS_BASE + (offset))))) +#define USBOTG_REG16(offset) (*((volatile u16 *)(IO_ADDRESS(USB_OTGREGS_BASE + (offset))))) + +#define USBH1_REG32(offset) (*((volatile u32 *)(IO_ADDRESS(USB_H1REGS_BASE + (offset))))) +#define USBH1_REG16(offset) (*((volatile u16 *)(IO_ADDRESS(USB_H1REGS_BASE + (offset))))) + +#define USBH2_REG32(offset) (*((volatile u32 *)(IO_ADDRESS(USB_H2REGS_BASE + (offset))))) +#define USBH2_REG16(offset) (*((volatile u16 *)(IO_ADDRESS(USB_H2REGS_BASE + (offset))))) + +#define USBOTHER_REG(offset) (*((volatile u32 *)(IO_ADDRESS(USB_OTHERREGS_BASE + (offset))))) + +/* + * OTG registers + */ +#define UOG_ID USBOTG_REG32(0x00) /* Host ID */ +#define UOG_HWGENERAL USBOTG_REG32(0x04) /* Host General */ +#define UOG_HWHOST USBOTG_REG32(0x08) /* Host h/w params */ +#define UOG_HWTXBUF USBOTG_REG32(0x10) /* TX buffer h/w params */ +#define UOG_HWRXBUF USBOTG_REG32(0x14) /* RX buffer h/w params */ +#define UOG_CAPLENGTH USBOTG_REG16(0x100) /* Capability register length */ +#define UOG_HCIVERSION USBOTG_REG16(0x102) /* Host Interface version */ +#define UOG_HCSPARAMS USBOTG_REG32(0x104) /* Host control structural params */ +#define UOG_HCCPARAMS USBOTG_REG32(0x108) /* control capability params */ +#define UOG_DCIVERSION USBOTG_REG32(0x120) /* device interface version */ +/* start EHCI registers: */ +#define UOG_USBCMD USBOTG_REG32(0x140) /* USB command register */ +#define UOG_USBSTS USBOTG_REG32(0x144) /* USB status register */ +#define UOG_USBINTR USBOTG_REG32(0x148) /* interrupt enable register */ +#define UOG_FRINDEX USBOTG_REG32(0x14c) /* USB frame index */ +/* segment (0x150) addr bits 63:32 if needed */ +#define UOG_PERIODICLISTBASE USBOTG_REG32(0x154) /* host crtlr frame list base addr */ +#define UOG_DEVICEADDR USBOTG_REG32(0x154) /* device crtlr device address */ +#define UOG_ASYNCLISTADDR USBOTG_REG32(0x158) /* host ctrlr next async addr */ +#define UOG_EPLISTADDR USBOTG_REG32(0x158) /* device ctrlr endpoint list addr */ +#define UOG_BURSTSIZE USBOTG_REG32(0x160) /* host ctrlr embedded TT async buf status */ +#define UOG_TXFILLTUNING USBOTG_REG32(0x164) /* TX FIFO fill tuning */ +#define UOG_ULPIVIEW USBOTG_REG32(0x170) /* ULPI viewport */ +#define UOG_CFGFLAG USBOTG_REG32(0x180) /* configflag (supports HS) */ +#define UOG_PORTSC1 USBOTG_REG32(0x184) /* port status and control */ +/* end EHCI registers: */ +#define UOG_OTGSC USBOTG_REG32(0x1a4) /* OTG status and control */ +#define UOG_USBMODE USBOTG_REG32(0x1a8) /* USB device mode */ +#define UOG_ENDPTSETUPSTAT USBOTG_REG32(0x1ac) /* endpoint setup status */ +#define UOG_ENDPTPRIME USBOTG_REG32(0x1b0) /* endpoint initialization */ +#define UOG_ENDPTFLUSH USBOTG_REG32(0x1b4) /* endpoint de-initialize */ +#define UOG_ENDPTSTAT USBOTG_REG32(0x1b8) /* endpoint status */ +#define UOG_ENDPTCOMPLETE USBOTG_REG32(0x1bc) /* endpoint complete */ +#define UOG_EPCTRL0 USBOTG_REG32(0x1c0) /* endpoint control0 */ +#define UOG_EPCTRL1 USBOTG_REG32(0x1c4) /* endpoint control1 */ +#define UOG_EPCTRL2 USBOTG_REG32(0x1c8) /* endpoint control2 */ +#define UOG_EPCTRL3 USBOTG_REG32(0x1cc) /* endpoint control3 */ +#define UOG_EPCTRL4 USBOTG_REG32(0x1d0) /* endpoint control4 */ +#define UOG_EPCTRL5 USBOTG_REG32(0x1d4) /* endpoint control5 */ +#define UOG_EPCTRL6 USBOTG_REG32(0x1d8) /* endpoint control6 */ +#define UOG_EPCTRL7 USBOTG_REG32(0x1dc) /* endpoint control7 */ + +/* + * Host 1 registers + */ +#define UH1_ID USBH1_REG32(0x00) /* Host ID */ +#define UH1_HWGENERAL USBH1_REG32(0x04) /* Host General */ +#define UH1_HWHOST USBH1_REG32(0x08) /* Host h/w params */ +#define UH1_HWTXBUF USBH1_REG32(0x10) /* TX buffer h/w params */ +#define UH1_HWRXBUF USBH1_REG32(0x14) /* RX buffer h/w params */ +#define UH1_CAPLENGTH USBH1_REG16(0x100) /* Capability register length */ +#define UH1_HCIVERSION USBH1_REG16(0x102) /* Host Interface version */ +#define UH1_HCSPARAMS USBH1_REG32(0x104) /* Host control structural params */ +#define UH1_HCCPARAMS USBH1_REG32(0x108) /* control capability params */ +/* start EHCI registers: */ +#define UH1_USBCMD USBH1_REG32(0x140) /* USB command register */ +#define UH1_USBSTS USBH1_REG32(0x144) /* USB status register */ +#define UH1_USBINTR USBH1_REG32(0x148) /* interrupt enable register */ +#define UH1_FRINDEX USBH1_REG32(0x14c) /* USB frame index */ +/* segment (0x150) addr bits 63:32 if needed */ +#define UH1_PERIODICLISTBASE USBH1_REG32(0x154) /* host crtlr frame list base addr */ +#define UH1_ASYNCLISTADDR USBH1_REG32(0x158) /* host ctrlr nest async addr */ +#define UH1_BURSTSIZE USBH1_REG32(0x160) /* host ctrlr embedded TT async buf status */ +#define UH1_TXFILLTUNING USBH1_REG32(0x164) /* TX FIFO fill tuning */ +/* configured_flag (0x180) configflag (supports HS) */ +#define UH1_PORTSC1 USBH1_REG32(0x184) /* port status and control */ +/* end EHCI registers: */ +#define UH1_USBMODE USBH1_REG32(0x1a8) /* USB device mode */ + +/* + * Host 2 registers + */ +#define UH2_ID USBH2_REG32(0x00) /* Host ID */ +#define UH2_HWGENERAL USBH2_REG32(0x04) /* Host General */ +#define UH2_HWHOST USBH2_REG32(0x08) /* Host h/w params */ +#define UH2_HWTXBUF USBH2_REG32(0x10) /* TX buffer h/w params */ +#define UH2_HWRXBUF USBH2_REG32(0x14) /* RX buffer h/w params */ +#define UH2_CAPLENGTH USBH2_REG16(0x100) /* Capability register length */ +#define UH2_HCIVERSION USBH2_REG16(0x102) /* Host Interface version */ +#define UH2_HCSPARAMS USBH2_REG32(0x104) /* Host control structural params */ +#define UH2_HCCPARAMS USBH2_REG32(0x108) /* control capability params */ +/* start EHCI registers: */ +#define UH2_USBCMD USBH2_REG32(0x140) /* USB command register */ +#define UH2_USBSTS USBH2_REG32(0x144) /* USB status register */ +#define UH2_USBINTR USBH2_REG32(0x148) /* interrupt enable register */ +#define UH2_FRINDEX USBH2_REG32(0x14c) /* USB frame index */ +/* segment (0x150) addr bits 63:32 if needed */ +#define UH2_PERIODICLISTBASE USBH2_REG32(0x154) /* host crtlr frame list base addr */ +#define UH2_ASYNCLISTADDR USBH2_REG32(0x158) /* host ctrlr nest async addr */ +#define UH2_BURSTSIZE USBH2_REG32(0x160) /* host ctrlr embedded TT async buf status */ +#define UH2_TXFILLTUNING USBH2_REG32(0x164) /* TX FIFO fill tuning */ +#define UH2_ULPIVIEW USBH2_REG32(0x170) /* ULPI viewport */ +/* configured_flag (0x180) configflag (supports HS) */ +#define UH2_PORTSC1 USBH2_REG32(0x184) /* port status and control */ +/* end EHCI registers */ +#define UH2_USBMODE USBH2_REG32(0x1a8) /* USB device mode */ + +/* + * other regs (not part of ARC core) + */ +#define USBCTRL USBOTHER_REG(0x00) /* USB Control register */ +#define USB_OTG_MIRROR USBOTHER_REG(0x04) /* USB OTG mirror register */ +#define USB_PHY_CTR_FUNC USBOTHER_REG(0x08) /* OTG UTMI PHY Function Control register */ +#define USB_PHY_CTR_FUNC2 USBOTHER_REG(0x0c) /* OTG UTMI PHY Function Control register */ +#define USB_CTRL_1 USBOTHER_REG(0x10) /* USB Cotrol Register 1*/ +#define USBCTRL_HOST2 USBOTHER_REG(0x14) /* USB Cotrol Register 1*/ +#define USBCTRL_HOST3 USBOTHER_REG(0x18) /* USB Cotrol Register 1*/ + +/* + * register bits + */ + +/* x_PORTSCx */ +#define PORTSC_PTS_MASK (3 << 30) /* parallel xcvr select mask */ +#define PORTSC_PTS_UTMI (0 << 30) /* UTMI/UTMI+ */ +#define PORTSC_PTS_PHILIPS (1 << 30) /* Philips classic */ +#define PORTSC_PTS_ULPI (2 << 30) /* ULPI */ +#define PORTSC_PTS_SERIAL (3 << 30) /* serial */ +#define PORTSC_STS (1 << 29) /* serial xcvr select */ +#define PORTSC_PTW (1 << 28) /* UTMI width */ +#define PORTSC_PORT_POWER (1 << 12) /* port power */ +#define PORTSC_LS_MASK (3 << 10) /* Line State mask */ +#define PORTSC_LS_SE0 (0 << 10) /* SE0 */ +#define PORTSC_LS_K_STATE (1 << 10) /* K-state */ +#define PORTSC_LS_J_STATE (2 << 10) /* J-state */ +#define PORTSC_PORT_RESET (1 << 8) /* Port reset */ +#define PORTSC_PORT_SUSPEND (1 << 7) /* Suspend */ +#define PORTSC_PORT_FORCE_RESUME (1 << 6) /* Force port resume */ +#define PORTSC_OVER_CURRENT_CHG (1 << 5) /* over current change */ +#define PORTSC_OVER_CURRENT_ACT (1 << 4) /* over currrent active */ +#define PORTSC_PORT_EN_DIS_CHANGE (1 << 3) /* port {en,dis}able change */ +#define PORTSC_PORT_ENABLE (1 << 2) /* port enabled */ +#define PORTSC_CONNECT_STATUS_CHANGE (1 << 1) /* connect status change */ +#define PORTSC_CURRENT_CONNECT_STATUS (1 << 0) /* current connect status */ + +#define PORTSC_W1C_BITS \ + ( PORTSC_CONNECT_STATUS_CHANGE | \ + PORTSC_PORT_EN_DIS_CHANGE | \ + PORTSC_OVER_CURRENT_CHG ) + +/* UOG_OTGSC Register Bits */ +/* control bits: */ +#define OTGSC_CTRL_VBUS_DISCHARGE (1 << 0) +#define OTGSC_CTRL_VBUS_CHARGE (1 << 1) +#define OTGSC_CTRL_OTG_TERM (1 << 3) /* controls DM pulldown */ +#define OTGSC_CTRL_DATA_PULSING (1 << 4) +#define OTGSC_CTRL_USB_ID_PU (1 << 5) /* enable ID pullup */ +/* current status: (R/O) */ +#define OTGSC_STS_USB_ID (1 << 8) /* 0=A-device 1=B-device */ +#define OTGSC_STS_A_VBUS_VALID (1 << 9) +#define OTGSC_STS_A_SESSION_VALID (1 << 10) +#define OTGSC_STS_B_SESSION_VALID (1 << 11) +#define OTGSC_STS_B_SESSION_END (1 << 12) +#define OTGSC_STS_1ms_TIMER (1 << 13) +#define OTGSC_STS_DATA_PULSE (1 << 14) +/* interrupt status: (write to clear) */ +#define OTGSC_IS_MASK (0x7f << 16) +#define OTGSC_IS_USB_ID (1 << 16) +#define OTGSC_IS_A_VBUS_VALID (1 << 17) +#define OTGSC_IS_A_SESSION_VALID (1 << 18) +#define OTGSC_IS_B_SESSION_VALID (1 << 19) +#define OTGSC_IS_B_SESSION_END (1 << 20) +#define OTGSC_IS_1ms_TIMER (1 << 21) +#define OTGSC_IS_DATA_PULSE (1 << 22) +/* interrupt enables: */ +#define OTGSC_IE_MASK (0x7f << 24) +#define OTGSC_IE_USB_ID (1 << 24) +#define OTGSC_IE_A_VBUS_VALID (1 << 25) +#define OTGSC_IE_A_SESSION_VALID (1 << 26) +#define OTGSC_IE_B_SESSION_VALID (1 << 27) +#define OTGSC_IE_B_SESSION_END (1 << 28) +#define OTGSC_IE_1ms_TIMER (1 << 29) +#define OTGSC_IE_DATA_PULSE (1 << 30) + +#if 1 /* FIXME these here for compatibility between my names and Leo's */ +/* OTG interrupt enable bit masks */ +#define OTGSC_INTERRUPT_ENABLE_BITS_MASK OTGSC_IE_MASK +#define OTGSC_INTSTS_MASK OTGSC_IS_MASK + +/* OTG interrupt status bit masks */ +#define OTGSC_INTERRUPT_STATUS_BITS_MASK OTGSC_IS_MASK +#endif + +/* x_USBMODE */ +#define USBMODE_SLOM (1 << 3) /* setup lockout mode */ +#define USBMODE_ES (1 << 2) /* (big) endian select */ +#define USBMODE_CM_MASK (3 << 0) /* controller mode mask */ +#define USBMODE_CM_HOST (3 << 0) /* host */ +#define USBMODE_CM_DEVICE (2 << 0) /* device */ +#define USBMODE_CM_reserved (1 << 0) /* reserved */ + +/* USBCTRL */ +#define UCTRL_OWIR (1 << 31) /* OTG wakeup intr request received */ +#define UCTRL_OSIC_MASK (3 << 29) /* OTG Serial Interface Config: */ +#define UCTRL_OSIC_DU6 (0 << 29) /* Differential/unidirectional 6 wire */ +#define UCTRL_OSIC_DB4 (1 << 29) /* Differential/bidirectional 4 wire */ +#define UCTRL_OSIC_SU6 (2 << 29) /* single-ended/unidirectional 6 wire */ +#define UCTRL_OSIC_SB3 (3 << 29) /* single-ended/bidirectional 3 wire */ + +#define UCTRL_OUIE (1 << 28) /* OTG ULPI intr enable */ +#define UCTRL_OWIE (1 << 27) /* OTG wakeup intr enable */ +#define UCTRL_OBPVAL_RXDP (1 << 26) /* OTG RxDp status in bypass mode */ +#define UCTRL_OBPVAL_RXDM (1 << 25) /* OTG RxDm status in bypass mode */ +#define UCTRL_OPM (1 << 24) /* OTG power mask */ +#define UCTRL_H2WIR (1 << 23) /* HOST2 wakeup intr request received */ +#define UCTRL_H2SIC_MASK (3 << 21) /* HOST2 Serial Interface Config: */ +#define UCTRL_H2SIC_DU6 (0 << 21) /* Differential/unidirectional 6 wire */ +#define UCTRL_H2SIC_DB4 (1 << 21) /* Differential/bidirectional 4 wire */ +#define UCTRL_H2SIC_SU6 (2 << 21) /* single-ended/unidirectional 6 wire */ +#define UCTRL_H2SIC_SB3 (3 << 21) /* single-ended/bidirectional 3 wire */ + +#ifdef CONFIG_ARCH_MX51 +#define UCTRL_H2UIE (1 << 8) /* HOST2 ULPI intr enable */ +#define UCTRL_H2WIE (1 << 7) /* HOST2 wakeup intr enable */ +#define UCTRL_H2PP 0 /* Power Polarity for uh2 */ +#define UCTRL_H2PM (1 << 4) /* HOST2 power mask */ +#else +#define UCTRL_H2UIE (1 << 20) /* HOST2 ULPI intr enable */ +#define UCTRL_H2WIE (1 << 19) /* HOST2 wakeup intr enable */ +#define UCTRL_H2PP (1 << 18) /* Power Polarity for uh2 */ +#define UCTRL_H2PM (1 << 16) /* HOST2 power mask */ +#endif + +#define UCTRL_H1WIR (1 << 15) /* HOST1 wakeup intr request received */ +#define UCTRL_H1SIC_MASK (3 << 13) /* HOST1 Serial Interface Config: */ +#define UCTRL_H1SIC_DU6 (0 << 13) /* Differential/unidirectional 6 wire */ +#define UCTRL_H1SIC_DB4 (1 << 13) /* Differential/bidirectional 4 wire */ +#define UCTRL_H1SIC_SU6 (2 << 13) /* single-ended/unidirectional 6 wire */ +#define UCTRL_H1SIC_SB3 (3 << 13) /* single-ended/bidirectional 3 wire */ +#define UCTRL_OLOCKD (1 << 13) /* otg lock disable */ +#define UCTRL_H2LOCKD (1 << 12) /* HOST2 lock disable */ +#define UCTRL_H1UIE (1 << 12) /* Host1 ULPI interrupt enable */ + +#define UCTRL_PP (1 << 11) /* power polarity bit */ +#define UCTRL_H1WIE (1 << 11) /* HOST1 wakeup intr enable */ +#define UCTRL_H1BPVAL_RXDP (1 << 10) /* HOST1 RxDp status in bypass mode */ +#define UCTRL_XCSO (1 << 10) /* Xcvr Clock Select for OTG port */ +#define UCTRL_H1BPVAL_RXDM (1 << 9) /* HOST1 RxDm status in bypass mode */ +#define UCTRL_XCSH2 (1 << 9) /* Xcvr Clock Select for Host port */ +#define UCTRL_H1PM (1 << 8) /* HOST1 power mask */ +#define UCTRL_IP_PULIDP (1 << 8) /* Ipp_Puimpel_Pullup_Dp */ + +#define UCTRL_IP_PUE_UP (1 << 7) /* ipp_pue_pullup_dp */ +#define UCTRL_IP_PUE_DOWN (1 << 6) /* ipp_pue_pulldwn_dpdm */ +#define UCTRL_H2DT (1 << 5) /* HOST2 TLL disabled */ +#define UCTRL_H1DT (1 << 4) /* HOST1 TLL disabled */ +#define UCTRL_USBTE (1 << 4) /* USBT Transceiver enable */ +#define UCTRL_OCPOL (1 << 3) /* OverCurrent Polarity */ +#define UCTRL_OCE (1 << 2) /* OverCurrent Enable */ +#define UCTRL_H2OCPOL (1 << 2) /* OverCurrent Polarity of Host2 */ +#define UCTRL_H2OCS (1 << 1) /* Host OverCurrent State */ +#define UCTRL_BPE (1 << 0) /* bypass mode enable */ +#define UCTRL_OTD (1 << 0) /* OTG TLL Disable */ +#define UCTRL_OOCS (1 << 0) /* OTG OverCurrent State */ + +/* USBCMD */ +#define UCMD_RUN_STOP (1 << 0) /* controller run/stop */ +#define UCMD_RESET (1 << 1) /* controller reset */ +#define UCMD_ITC_NO_THRESHOLD ~(0xff << 16) /* Interrupt Threshold Control */ + +/* OTG_MIRROR */ +#define OTGM_SESEND (1 << 4) /* B device session end */ +#define OTGM_VBUSVAL (1 << 3) /* Vbus valid */ +#define OTGM_BSESVLD (1 << 2) /* B session Valid */ +#define OTGM_ASESVLD (1 << 1) /* A session Valid */ +#define OTGM_IDIDG (1 << 0) /* OTG ID pin status */ + /* 1=high: Operate as B-device */ + /* 0=low : Operate as A-device */ + +/* USB_PHY_CTRL_FUNC */ +#define USB_UTMI_PHYCTRL_UTMI_ENABLE 0x01000000 +#define USB_UTMI_PHYCTRL_OC_POL (1 << 9) /* OTG Polarity of Overcurrent */ +#define USB_UTMI_PHYCTRL_OC_DIS (1 << 8) /* OTG Disable Overcurrent Event */ + +/* USB_PHY_CTRL_FUNC2*/ +#define USB_UTMI_PHYCTRL2_PLLDIV_MASK 0x3 +#define USB_UTMI_PHYCTRL2_PLLDIV_SHIFT 0 + +/* USB_CTRL_1 */ +#define USB_CTRL_UH1_EXT_CLK_EN (1 << 25) +#define USB_CTRL_UH2_EXT_CLK_EN (1 << 26) + +/* ULPIVIEW register bits */ +#define ULPIVW_OFF (0x170) +#define ULPIVW_WU (1 << 31) /* Wakeup */ +#define ULPIVW_RUN (1 << 30) /* read/write run */ +#define ULPIVW_WRITE (1 << 29) /* 0=read 1=write */ +#define ULPIVW_SS (1 << 27) /* SyncState */ +#define ULPIVW_PORT_MASK 0x07 /* Port field */ +#define ULPIVW_PORT_SHIFT 24 +#define ULPIVW_ADDR_MASK 0xFF /* data address field */ +#define ULPIVW_ADDR_SHIFT 16 +#define ULPIVW_RDATA_MASK 0xFF /* read data field */ +#define ULPIVW_RDATA_SHIFT 8 +#define ULPIVW_WDATA_MASK 0xFF /* write data field */ +#define ULPIVW_WDATA_SHIFT 0 + +#define HCSPARAMS_PPC (0x1<<4) /* Port Power Control */ +#endif --- linux-2.6.28.orig/arch/arm/plat-mxc/include/mach/mxc_vpu.h +++ linux-2.6.28/arch/arm/plat-mxc/include/mach/mxc_vpu.h @@ -0,0 +1,92 @@ +/* + * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU Lesser General + * Public License. You may obtain a copy of the GNU Lesser General + * Public License Version 2.1 or later at the following locations: + * + * http://www.opensource.org/licenses/lgpl-license.html + * http://www.gnu.org/copyleft/lgpl.html + */ + +/*! + * @defgroup VPU Video Processor Unit Driver + */ + +/*! + * @file arch-mxc/mxc_vpu.h + * + * @brief VPU system initialization and file operation definition + * + * @ingroup VPU + */ + +#ifndef __ASM_ARCH_MXC_VPU_H__ +#define __ASM_ARCH_MXC_VPU_H__ + +#include + +struct vpu_mem_desc { + u32 size; + dma_addr_t phy_addr; + u32 cpu_addr; /* cpu address to free the dma mem */ + u32 virt_uaddr; /* virtual user space address */ +}; + +#define VPU_IOC_MAGIC 'V' + +#define VPU_IOC_PHYMEM_ALLOC _IO(VPU_IOC_MAGIC, 0) +#define VPU_IOC_PHYMEM_FREE _IO(VPU_IOC_MAGIC, 1) +#define VPU_IOC_WAIT4INT _IO(VPU_IOC_MAGIC, 2) +#define VPU_IOC_PHYMEM_DUMP _IO(VPU_IOC_MAGIC, 3) +#define VPU_IOC_REG_DUMP _IO(VPU_IOC_MAGIC, 4) +#define VPU_IOC_VL2CC_FLUSH _IO(VPU_IOC_MAGIC, 5) +#define VPU_IOC_IRAM_SETTING _IO(VPU_IOC_MAGIC, 6) +#define VPU_IOC_CLKGATE_SETTING _IO(VPU_IOC_MAGIC, 7) +#define VPU_IOC_GET_WORK_ADDR _IO(VPU_IOC_MAGIC, 8) +#define VPU_IOC_GET_PIC_PARA_ADDR _IO(VPU_IOC_MAGIC, 9) +#define VPU_IOC_GET_USER_DATA_ADDR _IO(VPU_IOC_MAGIC, 10) + +#define BIT_CODE_RUN 0x000 +#define BIT_CODE_DOWN 0x004 +#define BIT_INT_CLEAR 0x00C +#define BIT_INT_STATUS 0x010 + +#define BIT_WORK_CTRL_BUF_BASE 0x100 +#define BIT_WORK_CTRL_BUF_REG(i) (BIT_WORK_CTRL_BUF_BASE + i * 4) +#define BIT_CODE_BUF_ADDR BIT_WORK_CTRL_BUF_REG(0) +#define BIT_WORK_BUF_ADDR BIT_WORK_CTRL_BUF_REG(1) +#define BIT_PARA_BUF_ADDR BIT_WORK_CTRL_BUF_REG(2) +#define BIT_BIT_STREAM_CTRL BIT_WORK_CTRL_BUF_REG(3) +#define BIT_FRAME_MEM_CTRL BIT_WORK_CTRL_BUF_REG(4) +#define BIT_BIT_STREAM_PARAM BIT_WORK_CTRL_BUF_REG(5) + +#define BIT_RESET_CTRL 0x11C + +/* i could be 0, 1, 2, 3 */ +#define BIT_RD_PTR_BASE 0x120 +#define BIT_RD_PTR_REG(i) (BIT_RD_PTR_BASE + i * 8) +#define BIT_WR_PTR_REG(i) (BIT_RD_PTR_BASE + i * 8 + 4) + +/* i could be 0, 1, 2, 3 */ +#define BIT_FRM_DIS_FLG_BASE (cpu_is_mx51() ? 0x150 : 0x140) +#define BIT_FRM_DIS_FLG_REG(i) (BIT_FRM_DIS_FLG_BASE + i * 4) + +#define BIT_BUSY_FLAG 0x160 +#define BIT_RUN_COMMAND 0x164 +#define BIT_INT_ENABLE 0x170 + +#define BITVAL_PIC_RUN 8 + +#define VPU_SLEEP_REG_VALUE 10 +#define VPU_WAKE_REG_VALUE 11 + +int vl2cc_init(u32 vl2cc_hw_base); +void vl2cc_enable(void); +void vl2cc_flush(void); +void vl2cc_disable(void); +void vl2cc_cleanup(void); + +#endif --- linux-2.6.28.orig/arch/arm/plat-mxc/include/mach/mmc.h +++ linux-2.6.28/arch/arm/plat-mxc/include/mach/mmc.h @@ -0,0 +1,35 @@ +/* + * Copyright 2007-2008 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_MMC_H__ +#define __ASM_ARCH_MXC_MMC_H__ + +#include + +struct mxc_mmc_platform_data { + unsigned int ocr_mask; /* available voltages */ + unsigned int vendor_ver; + unsigned int caps; + unsigned int min_clk; + unsigned int max_clk; + unsigned int clk_flg; /* 1 clock enable, 0 not */ + unsigned int reserved:16; + unsigned int card_fixed:1; + unsigned int card_inserted_state:1; +// u32 (*translate_vdd)(struct device *, unsigned int); + unsigned int (*status) (struct device *); + int (*wp_status) (struct device *); + char *power_mmc; + char *clock_mmc; +}; + +#endif --- linux-2.6.28.orig/arch/arm/plat-mxc/include/mach/common.h +++ linux-2.6.28/arch/arm/plat-mxc/include/mach/common.h @@ -16,7 +16,11 @@ extern void mxc_map_io(void); extern void mxc_init_irq(void); extern void mxc_timer_init(const char *clk_timer); -extern int mxc_clocks_init(unsigned long fref); +extern int __init mxc_clocks_init(unsigned long ckil, unsigned long osc, unsigned long ckih1, unsigned long ckih2); +extern int mxc_init_devices(void); +extern void mxc_cpu_init(void) __init; +extern void mxc_cpu_common_init(void); +extern void __init early_console_setup(char *); extern int mxc_register_gpios(void); extern int mxc_register_device(struct platform_device *pdev, void *data); --- linux-2.6.28.orig/arch/arm/plat-mxc/include/mach/entry-macro.S +++ linux-2.6.28/arch/arm/plat-mxc/include/mach/entry-macro.S @@ -1,6 +1,6 @@ /* * Copyright (C) 2007 Lennert Buytenhek - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -9,6 +9,8 @@ * published by the Free Software Foundation. */ +#include + #define AVIC_NIMASK 0x04 @ this macro disables fast irq (not implemented) @@ -16,10 +18,14 @@ .endm .macro get_irqnr_preamble, base, tmp +#ifdef CONFIG_MXC_TZIC + ldr \base, =TZIC_IO_ADDRESS(TZIC_BASE_ADDR) +#else ldr \base, =AVIC_IO_ADDRESS(AVIC_BASE_ADDR) #ifdef CONFIG_MXC_IRQ_PRIOR ldr r4, [\base, #AVIC_NIMASK] #endif +#endif .endm .macro arch_ret_to_user, tmp1, tmp2 @@ -29,6 +35,32 @@ @ and returns its number in irqnr @ and returns if an interrupt occured in irqstat .macro get_irqnr_and_base, irqnr, irqstat, base, tmp +#ifdef CONFIG_MXC_TZIC + @ Load offset & priority of the highest priority + @ interrupt pending. + @ 0xD80 is HIPND0 register + ldr \irqnr, =0 + ldr \irqstat, =0x0D80 +1000: + ldr \tmp, [\irqstat, \base] + cmp \tmp, #0 + bne 1001f + addeq \irqnr, \irqnr, #32 + addeq \irqstat, \irqstat, #4 + cmp \irqnr, #128 + blo 1000b + b 2001f +1001: ldr \irqstat, =1 +1002: tst \tmp, \irqstat + bne 2002f + movs \tmp, \tmp, lsr #1 + addne \irqnr, \irqnr, #1 + bne 1002b +2001: + ldr \irqnr, =0 +2002: + movs \irqnr, \irqnr +#else @ Load offset & priority of the highest priority @ interrupt pending from AVIC_NIVECSR ldr \irqstat, [\base, #0x40] @@ -42,6 +74,7 @@ strne \tmp, [\base, #AVIC_NIMASK] streq r4, [\base, #AVIC_NIMASK] #endif +#endif .endm @ irq priority table (not used) --- linux-2.6.28.orig/arch/arm/plat-mxc/include/mach/uncompress.h +++ linux-2.6.28/arch/arm/plat-mxc/include/mach/uncompress.h @@ -27,6 +27,8 @@ #include +unsigned int system_rev; + #define UART(x) (*(volatile unsigned long *)(serial_port + (x))) #define USR2 0x98 --- linux-2.6.28.orig/arch/arm/plat-mxc/include/mach/io.h +++ linux-2.6.28/arch/arm/plat-mxc/include/mach/io.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -14,29 +14,34 @@ /* Allow IO space to be anywhere in the memory */ #define IO_SPACE_LIMIT 0xffffffff -#ifdef CONFIG_ARCH_MX3 -#define __arch_ioremap __mx3_ioremap -#define __arch_iounmap __iounmap - -static inline void __iomem * -__mx3_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype) -{ - if (mtype == MT_DEVICE) { - /* Access all peripherals below 0x80000000 as nonshared device - * but leave l2cc alone. - */ - if ((phys_addr < 0x80000000) && ((phys_addr < L2CC_BASE_ADDR) || - (phys_addr >= L2CC_BASE_ADDR + L2CC_SIZE))) - mtype = MT_DEVICE_NONSHARED; - } +extern void __iomem *__mxc_ioremap(unsigned long cookie, size_t size, + unsigned int mtype); +extern void __mxc_iounmap(void __iomem *addr); - return __arm_ioremap(phys_addr, size, mtype); -} -#endif +#define __arch_ioremap(a, s, f) __mxc_ioremap(a, s, f) +#define __arch_iounmap(a) __mxc_iounmap(a) /* io address mapping macro */ #define __io(a) ((void __iomem *)(a)) #define __mem_pci(a) (a) +/*! + * This function is called to read a CPLD register over CSPI. + * + * @param offset number of the cpld register to be read + * + * @return Returns 0 on success -1 on failure. + */ +unsigned int spi_cpld_read(unsigned int offset); + +/*! + * This function is called to write to a CPLD register over CSPI. + * + * @param offset number of the cpld register to be written + * @param reg_val value to be written + * + * @return Returns 0 on success -1 on failure. + */ +unsigned int spi_cpld_write(unsigned int offset, unsigned int reg_val); #endif --- linux-2.6.28.orig/arch/arm/plat-mxc/include/mach/spba.h +++ linux-2.6.28/arch/arm/plat-mxc/include/mach/spba.h @@ -0,0 +1,66 @@ + +/* + * Copyright 2004-2008 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 + */ + +/*! + * @defgroup SPBA Shared Peripheral Bus Arbiter (SPBA) + * @ingroup MSL_MX31 MSL_MX35 MSL_MX37 MSL_MX51 MSL_MXC91321 + */ + +/*! + * @file arch-mxc/spba.h + * @brief This file contains the Shared Peripheral Bus Arbiter (spba) API. + * + * @ingroup SPBA + */ + +#ifndef __ASM_ARCH_MXC_SPBA_H__ +#define __ASM_ARCH_MXC_SPBA_H__ + +#ifdef __KERNEL__ + +#define MXC_SPBA_RAR_MASK 0x7 + +/*! + * Defines three SPBA masters: A - ARM, C - SDMA (no master B for MX31) + */ +enum spba_masters { + SPBA_MASTER_A = 1, + SPBA_MASTER_B = 2, + SPBA_MASTER_C = 4, +}; + +/*! + * This function allows the three masters (A, B, C) to take ownership of a + * shared peripheral. + * + * @param mod specified module as defined in \b enum \b #spba_module + * @param master one of more (or-ed together) masters as defined in \b enum \b #spba_masters + * + * @return 0 if successful; -1 otherwise. + */ +int spba_take_ownership(int mod, int master); + +/*! + * This function releases the ownership for a shared peripheral. + * + * @param mod specified module as defined in \b enum \b #spba_module + * @param master one of more (or-ed together) masters as defined in \b enum \b #spba_masters + * + * @return 0 if successful; -1 otherwise. + */ +int spba_rel_ownership(int mod, int master); + +#endif /* __KERNEL__ */ + +#endif /* __ASM_ARCH_MXC_SPBA_H__ */ --- linux-2.6.28.orig/arch/arm/plat-mxc/include/mach/clock.h +++ linux-2.6.28/arch/arm/plat-mxc/include/mach/clock.h @@ -34,6 +34,8 @@ struct clk *parent; /* Secondary clock to enable/disable with this clock */ struct clk *secondary; + /* Current clock rate */ + unsigned long rate; /* Reference count of clock enable/disable */ __s8 usecount; /* Register bit position for clock's enable/disable control. */ @@ -41,8 +43,9 @@ /* Register address for clock's enable/disable control. */ void __iomem *enable_reg; u32 flags; - /* get the current clock rate (always a fresh value) */ - unsigned long (*get_rate) (struct clk *); + /* Function ptr to recalculate the clock's rate based on parent + clock's rate */ + void (*recalc) (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 */ @@ -62,6 +65,14 @@ int clk_register(struct clk *clk); void clk_unregister(struct clk *clk); +int clk_get_usecount(struct clk *clk); +int clk_set_pll_dither(struct clk *clk, unsigned int pll_ppm); +/* Clock flags */ +#define RATE_PROPAGATES (1 << 0) /* Program children too */ +#define ALWAYS_ENABLED (1 << 1) /* Clock cannot be disabled */ +#define RATE_FIXED (1 << 2) /* Fixed clock rate */ +#define CPU_FREQ_TRIG_UPDATE (1 << 3) /* CPUFREQ trig update */ + #endif /* __ASSEMBLY__ */ #endif /* __ASM_ARCH_MXC_CLOCK_H__ */ --- linux-2.6.28.orig/arch/arm/plat-mxc/include/mach/mxc_timer.h +++ linux-2.6.28/arch/arm/plat-mxc/include/mach/mxc_timer.h @@ -65,9 +65,8 @@ { __raw_writel(0, TIMER_BASE + MXC_TSTAT); } -#endif /* CONFIG_ARCH_IMX */ -#ifdef CONFIG_ARCH_MX2 +#elif defined(CONFIG_ARCH_MX2) #define TIMER_BASE IO_ADDRESS(GPT1_BASE_ADDR) #define TIMER_INTERRUPT MXC_INT_GPT1 @@ -103,15 +102,15 @@ { __raw_writel(TSTAT_CAPT | TSTAT_COMP, TIMER_BASE + MXC_TSTAT); } -#endif /* CONFIG_ARCH_MX2 */ -#ifdef CONFIG_ARCH_MX3 +#else #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_VAL (TCTL_CLK_HIGH_FREQ | TCTL_WAITEN) #define TCTL_CLK_IPG (1<<6) +#define TCTL_CLK_HIGH_FREQ (2<<6) #define TCTL_FRR (1<<9) #define TCTL_WAITEN (1<<3) --- linux-2.6.28.orig/arch/arm/plat-mxc/include/mach/fsl_usb_gadget.h +++ linux-2.6.28/arch/arm/plat-mxc/include/mach/fsl_usb_gadget.h @@ -0,0 +1,40 @@ +/* + * Copyright 2005-2008 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 + */ + +/* + * USB Gadget side, platform-specific functionality. + */ + +#include + +/* Needed for i2c/serial transceivers */ +static inline void +fsl_platform_set_device_mode(struct fsl_usb2_platform_data *pdata) +{ + if (pdata->xcvr_ops && pdata->xcvr_ops->set_device) + pdata->xcvr_ops->set_device(); +} + +static inline void +fsl_platform_pullup_enable(struct fsl_usb2_platform_data *pdata) +{ + if (pdata->xcvr_ops && pdata->xcvr_ops->pullup) + pdata->xcvr_ops->pullup(1); +} + +static inline void +fsl_platform_pullup_disable(struct fsl_usb2_platform_data *pdata) +{ + if (pdata->xcvr_ops && pdata->xcvr_ops->pullup) + pdata->xcvr_ops->pullup(0); +} --- linux-2.6.28.orig/arch/arm/plat-mxc/include/mach/sdma.h +++ linux-2.6.28/arch/arm/plat-mxc/include/mach/sdma.h @@ -0,0 +1,505 @@ + +/* + * Copyright 2004-2009 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_SDMA_H__ +#define __ASM_ARCH_MXC_SDMA_H__ + +/*! + * @defgroup SDMA Smart Direct Memory Access (SDMA) Driver + */ + +/*! + * @file arch-mxc/sdma.h + * + * @brief This file contains the SDMA API declarations. + * + * SDMA is responsible on moving data between peripherals and memories (MCU, EMI and DSP). + * + * @ingroup SDMA + */ + +#include +#include +#include + +#include + +/*! + * This defines maximum DMA address + */ +#define MAX_DMA_ADDRESS 0xffffffff + +/*! + * This defines maximum number of DMA channels + */ +#ifdef CONFIG_MXC_SDMA_API +#define MAX_DMA_CHANNELS 32 +#define MAX_BD_NUMBER 16 +#define MXC_SDMA_DEFAULT_PRIORITY 1 +#define MXC_SDMA_MIN_PRIORITY 1 +#define MXC_SDMA_MAX_PRIORITY 7 +#else +#define MAX_DMA_CHANNELS 0 +#endif + +#define MXC_FIFO_MEM_DEST_FIXED 0x1 +#define MXC_FIFO_MEM_SRC_FIXED 0x2 +/*! + * This enumerates transfer types + */ +typedef enum { + emi_2_per = 0, /*!< EMI memory to peripheral */ + emi_2_int, /*!< EMI memory to internal RAM */ + emi_2_emi, /*!< EMI memory to EMI memory */ + emi_2_dsp, /*!< EMI memory to DSP memory */ + per_2_int, /*!< Peripheral to internal RAM */ + per_2_emi, /*!< Peripheral to internal EMI memory */ + per_2_dsp, /*!< Peripheral to DSP memory */ + per_2_per, /*!< Peripheral to Peripheral */ + int_2_per, /*!< Internal RAM to peripheral */ + int_2_int, /*!< Internal RAM to Internal RAM */ + int_2_emi, /*!< Internal RAM to EMI memory */ + int_2_dsp, /*!< Internal RAM to DSP memory */ + dsp_2_per, /*!< DSP memory to peripheral */ + dsp_2_int, /*!< DSP memory to internal RAM */ + dsp_2_emi, /*!< DSP memory to EMI memory */ + dsp_2_dsp, /*!< DSP memory to DSP memory */ + emi_2_dsp_loop, /*!< EMI memory to DSP memory loopback */ + dsp_2_emi_loop, /*!< DSP memory to EMI memory loopback */ + dvfs_pll, /*!< DVFS script with PLL change */ + dvfs_pdr /*!< DVFS script without PLL change */ +} sdma_transferT; + +/*! + * This enumerates peripheral types + */ +typedef enum { + SSI, /*!< MCU domain SSI */ + SSI_SP, /*!< Shared SSI */ + MMC, /*!< MMC */ + SDHC, /*!< SDHC */ + UART, /*!< MCU domain UART */ + UART_SP, /*!< Shared UART */ + FIRI, /*!< FIRI */ + CSPI, /*!< MCU domain CSPI */ + CSPI_SP, /*!< Shared CSPI */ + SIM, /*!< SIM */ + ATA, /*!< ATA */ + CCM, /*!< CCM */ + EXT, /*!< External peripheral */ + MSHC, /*!< Memory Stick Host Controller */ + MSHC_SP, /*!< Shared Memory Stick Host Controller */ + DSP, /*!< DSP */ + MEMORY, /*!< Memory */ + FIFO_MEMORY, /*!< FIFO type Memory */ + SPDIF, /*!< SPDIF */ + IPU_MEMORY, /*!< IPU Memory */ + ASRC, /*!< ASRC */ + ESAI, /*!< ESAI */ +} sdma_periphT; + +#ifndef TRANSFER_32BIT +/*! + * This defines SDMA access data size + */ +#define TRANSFER_32BIT 0x00 +#define TRANSFER_8BIT 0x01 +#define TRANSFER_16BIT 0x02 +#define TRANSFER_24BIT 0x03 + +#endif + +/*! + * This defines maximum device name length passed during mxc_request_dma(). + */ +#define MAX_DEVNAME_LENGTH 32 + +/*! + * This defines SDMA interrupt callback function prototype. + */ +typedef void (*dma_callback_t) (void *arg); + +/*! + * Structure containing sdma channel parameters. + */ +typedef struct { + __u32 watermark_level; /*!< Lower/upper threshold that + * triggers SDMA event + */ + __u32 per_address; /*!< Peripheral source/destination + * physical address + */ + sdma_periphT peripheral_type; /*!< Peripheral type */ + sdma_transferT transfer_type; /*!< Transfer type */ + int event_id; /*!< Event number, + * needed by all channels + * that started by peripherals dma + * request (per_2_*,*_2_per) + * Not used for memory and DSP + * transfers. + */ + int event_id2; /*!< Second event number, + * used in ATA scripts only. + */ + int bd_number; /*!< Buffer descriptors number. + * If not set, single buffer + * descriptor will be used. + */ + dma_callback_t callback; /*! callback function */ + void *arg; /*! callback argument */ + unsigned long word_size:8; /*!< SDMA data access word size */ +} dma_channel_params; + +/*! + * Structure containing sdma request parameters. + */ +typedef struct { + /*! physical source memory address */ + __u8 *sourceAddr; + /*! physical destination memory address */ + __u8 *destAddr; + /*! amount of data to transfer, + * updated during mxc_dma_get_config + */ + __u16 count; + /*!< DONE bit of the buffer descriptor, + * updated during mxc_dma_get_config + * 0 - means the BD is done and closed by SDMA + * 1 - means the BD is still being processed by SDMA + */ + int bd_done; + /*!< CONT bit of the buffer descriptor, + * set it if full multi-buffer descriptor mechanism + * required. + */ + int bd_cont; + /*!< ERROR bit of the buffer descriptor, + * updated during mxc_dma_get_config. + * If it is set - there was an error during BD processing. + */ + int bd_error; +} dma_request_t; + +/*! + * Structure containing sdma request parameters. + */ +typedef struct { + /*! address of ap_2_ap script */ + int mxc_sdma_ap_2_ap_addr; + /*! address of ap_2_bp script */ + int mxc_sdma_ap_2_bp_addr; + /*! address of ap_2_ap_fixed script */ + int mxc_sdma_ap_2_ap_fixed_addr; + /*! address of bp_2_ap script */ + int mxc_sdma_bp_2_ap_addr; + /*! address of loopback_on_dsp_side script */ + int mxc_sdma_loopback_on_dsp_side_addr; + /*! address of mcu_interrupt_only script */ + int mxc_sdma_mcu_interrupt_only_addr; + + /*! address of firi_2_per script */ + int mxc_sdma_firi_2_per_addr; + /*! address of firi_2_mcu script */ + int mxc_sdma_firi_2_mcu_addr; + /*! address of per_2_firi script */ + int mxc_sdma_per_2_firi_addr; + /*! address of mcu_2_firi script */ + int mxc_sdma_mcu_2_firi_addr; + + /*! address of uart_2_per script */ + int mxc_sdma_uart_2_per_addr; + /*! address of uart_2_mcu script */ + int mxc_sdma_uart_2_mcu_addr; + /*! address of per_2_app script */ + int mxc_sdma_per_2_app_addr; + /*! address of mcu_2_app script */ + int mxc_sdma_mcu_2_app_addr; + /*! address of per_2_per script */ + int mxc_sdma_per_2_per_addr; + + /*! address of uartsh_2_per script */ + int mxc_sdma_uartsh_2_per_addr; + /*! address of uartsh_2_mcu script */ + int mxc_sdma_uartsh_2_mcu_addr; + /*! address of per_2_shp script */ + int mxc_sdma_per_2_shp_addr; + /*! address of mcu_2_shp script */ + int mxc_sdma_mcu_2_shp_addr; + + /*! address of ata_2_mcu script */ + int mxc_sdma_ata_2_mcu_addr; + /*! address of mcu_2_ata script */ + int mxc_sdma_mcu_2_ata_addr; + + /*! address of app_2_per script */ + int mxc_sdma_app_2_per_addr; + /*! address of app_2_mcu script */ + int mxc_sdma_app_2_mcu_addr; + /*! address of shp_2_per script */ + int mxc_sdma_shp_2_per_addr; + /*! address of shp_2_mcu script */ + int mxc_sdma_shp_2_mcu_addr; + + /*! address of mshc_2_mcu script */ + int mxc_sdma_mshc_2_mcu_addr; + /*! address of mcu_2_mshc script */ + int mxc_sdma_mcu_2_mshc_addr; + + /*! address of spdif_2_mcu script */ + int mxc_sdma_spdif_2_mcu_addr; + /*! address of mcu_2_spdif script */ + int mxc_sdma_mcu_2_spdif_addr; + + /*! address of asrc_2_mcu script */ + int mxc_sdma_asrc_2_mcu_addr; + + /*! address of ext_mem_2_ipu script */ + int mxc_sdma_ext_mem_2_ipu_addr; + + /*! address of descrambler script */ + int mxc_sdma_descrambler_addr; + + /*! address of dptc_dvfs script */ + int mxc_sdma_dptc_dvfs_addr; + + int mxc_sdma_utra_addr; + + /*! address where ram code starts */ + int mxc_sdma_ram_code_start_addr; + /*! size of the ram code */ + int mxc_sdma_ram_code_size; + /*! RAM image address */ + unsigned short *mxc_sdma_start_addr; +} sdma_script_start_addrs; + +/*! Structure to store the initialized dma_channel parameters */ +typedef struct mxc_sdma_channel_params { + /*! Channel params */ + dma_channel_params chnl_params; + /*! Channel type (static channel number or dynamic channel) */ + unsigned int channel_num; + /*! Channel priority [0x1(lowest) - 0x7(highest)] */ + unsigned int chnl_priority; +} mxc_sdma_channel_params_t; + +/*! Private SDMA data structure */ +typedef struct mxc_dma_channel_private { + /*! ID of the buffer that was processed */ + unsigned int buf_tail; + /*! Tasklet for the channel */ + struct tasklet_struct chnl_tasklet; + /*! Flag indicates if interrupt is required after every BD transfer */ + int intr_after_every_bd; +} mxc_dma_channel_private_t; + +/*! + * Setup channel according to parameters. + * Must be called once after mxc_request_dma() + * + * @param channel channel number + * @param p channel parameters pointer + * @return 0 on success, error code on fail + */ +int mxc_dma_setup_channel(int channel, dma_channel_params * p); + +/*! + * Setup the channel priority. This can be used to change the default priority + * for the channel. + * + * @param channel channel number + * @param priority priority to be set for the channel + * + * @return 0 on success, error code on failure + */ +int mxc_dma_set_channel_priority(unsigned int channel, unsigned int priority); + +/*! + * Allocates dma channel. + * If channel's value is 0, then the function allocates a free channel + * dynamically and sets its value to channel. + * Else allocates requested channel if it is free. + * If the channel is busy or no free channels (in dynamic allocation) -EBUSY returned. + * + * @param channel pointer to channel number + * @param devicename device name + * @return 0 on success, error code on fail + */ +int mxc_request_dma(int *channel, const char *devicename); + +/*! + * Configures request parameters. Can be called multiple times after + * mxc_request_dma() and mxc_dma_setup_channel(). + * + * + * @param channel channel number + * @param p request parameters pointer + * @param bd_index index of buffer descriptor to set + * @return 0 on success, error code on fail + */ +/* int mxc_dma_set_config(int channel, dma_request_t *p, int bd_index); */ +int mxc_dma_set_config(int channel, dma_request_t * p, int bd_index); + +/*! + * Returns request parameters. + * + * @param channel channel number + * @param p request parameters pointer + * @param bd_index index of buffer descriptor to get + * @return 0 on success, error code on fail + */ +/* int mxc_dma_get_config(int channel, dma_request_t *p, int bd_index); */ +int mxc_dma_get_config(int channel, dma_request_t * p, int bd_index); + +/*! + * This function is used by MXC IPC's write_ex2. It passes the a pointer to the + * data control structure to iapi_write_ipcv2() + * + * @param channel SDMA channel number + * @param ctrl_ptr Data Control structure pointer + */ +int mxc_sdma_write_ipcv2(int channel, void *ctrl_ptr); + +/*! + * This function is used by MXC IPC's read_ex2. It passes the a pointer to the + * data control structure to iapi_read_ipcv2() + * + * @param channel SDMA channel number + * @param ctrl_ptr Data Control structure pointer + */ +int mxc_sdma_read_ipcv2(int channel, void *ctrl_ptr); + +/*! + * Starts dma channel. + * + * @param channel channel number + */ +int mxc_dma_start(int channel); + +/*! + * Stops dma channel. + * + * @param channel channel number + */ +int mxc_dma_stop(int channel); + +/*! + * Frees dma channel. + * + * @param channel channel number + */ +void mxc_free_dma(int channel); + +/*! + * Sets callback function. Used with standard dma api + * for supporting interrupts + * + * @param channel channel number + * @param callback callback function pointer + * @param arg argument for callback function + */ +void mxc_dma_set_callback(int channel, dma_callback_t callback, void *arg); + +/*! + * Allocates uncachable buffer. Uses hash table. + * + * @param size size of allocated buffer + * @return pointer to buffer + */ +void *sdma_malloc(size_t size); + +#ifdef CONFIG_SDMA_IRAM +/*! + * Allocates uncachable buffer from IRAM.. + * + * @param size size of allocated buffer + * @return pointer to buffer + */ +void *sdma_iram_malloc(size_t size); +#endif /*CONFIG_SDMA_IRAM */ + +/*! + * Frees uncachable buffer. Uses hash table. + */ +void sdma_free(void *buf); + +/*! + * Converts virtual to physical address. Uses hash table. + * + * @param buf virtual address pointer + * @return physical address value + */ +unsigned long sdma_virt_to_phys(void *buf); + +/*! + * Converts physical to virtual address. Uses hash table. + * + * @param buf physical address value + * @return virtual address pointer + */ +void *sdma_phys_to_virt(unsigned long buf); + +/*! + * Configures the BD_INTR bit on a buffer descriptor parameters. + * + * + * @param channel channel number + * @param bd_index index of buffer descriptor to set + * @param bd_intr flag to set or clear the BD_INTR bit + */ +void mxc_dma_set_bd_intr(int channel, int bd_index, int bd_intr); + +/*! + * Gets the BD_INTR bit on a buffer descriptor. + * + * + * @param channel channel number + * @param bd_index index of buffer descriptor to set + * + * @return returns the BD_INTR bit status + */ +int mxc_dma_get_bd_intr(int channel, int bd_index); + +/*! + * Stop the current transfer + * + * @param channel channel number + * @param buffer_number number of buffers (beginning with 0), + * whose done bits should be reset to 0 + */ +int mxc_dma_reset(int channel, int buffer_number); + +/*! + * This functions Returns the SDMA paramaters associated for a module + * + * @param channel_id the ID of the module requesting DMA + * @return returns the sdma parameters structure for the device + */ +mxc_sdma_channel_params_t *mxc_sdma_get_channel_params(mxc_dma_device_t + channel_id); + +/*! + * This functions marks the SDMA channels that are statically allocated + * + * @param chnl the channel array used to store channel information + */ +void mxc_get_static_channels(mxc_dma_channel_t * chnl); + +/*! + * Initializes SDMA driver + */ +int __init sdma_init(void); + +#define DEFAULT_ERR 1 + +#endif --- linux-2.6.28.orig/arch/arm/plat-mxc/include/mach/mx51.h +++ linux-2.6.28/arch/arm/plat-mxc/include/mach/mx51.h @@ -0,0 +1,520 @@ +/* + * Copyright 2008-2009 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_MX51_H__ +#define __ASM_ARCH_MXC_MX51_H__ + +#ifndef __ASM_ARCH_MXC_HARDWARE_H__ +#error "Do not include directly." +#endif + +/*! + * @file arch-mxc/mx51.h + * @brief This file contains register definitions. + * + * @ingroup MSL_MX51 + */ +/*! + * defines the hardware clock tick rate + */ +#define CLOCK_TICK_RATE 8000000 + +/*! + * Register an interrupt handler for the SMN as well as the SCC. In some + * implementations, the SMN is not connected at all, and in others, it is + * on the same interrupt line as the SCM. Comment this line out accordingly + */ +#define USE_SMN_INTERRUPT + +/* + * UART Chip level Configuration that a user may not have to edit. These + * configuration vary depending on how the UART module is integrated with + * the ARM core + */ +#define MXC_UART_NR 3 +/*! + * This option is used to set or clear the RXDMUXSEL bit in control reg 3. + * Certain platforms need this bit to be set in order to receive Irda data. + */ +#define MXC_UART_IR_RXDMUX 0x0004 +/*! + * This option is used to set or clear the RXDMUXSEL bit in control reg 3. + * Certain platforms need this bit to be set in order to receive UART data. + */ +#define MXC_UART_RXDMUX 0x0004 + +/*! + * This option is used to set or clear the dspdma bit in the SDMA config + * register. + */ +#define MXC_SDMA_DSPDMA 0 + +/*! + * Define this option to specify we are using the newer SDMA module. + */ +#define MXC_SDMA_V2 + + /* + * IRAM + */ +#define IRAM_BASE_ADDR 0x1FFE0000 /* internal ram */ +#define IRAM_BASE_ADDR_VIRT 0xFA3E0000 +#define IRAM_PARTITIONS 16 +#define IRAM_PARTITIONS_TO1 12 +#define IRAM_SIZE (IRAM_PARTITIONS*SZ_8K) /* 128KB */ + +#if defined(CONFIG_MXC_SECURITY_SCC2) \ + || defined(CONFIG_MXC_SECURITY_SCC2_MODULE) +#define SCC_IRAM_SIZE SZ_16K +#else +#define SCC_IRAM_SIZE 0 +#endif + +#ifdef CONFIG_SDMA_IRAM +#define SDMA_IRAM_SIZE CONFIG_SDMA_IRAM_SIZE +#else +#define SDMA_IRAM_SIZE 0 +#endif + +#ifdef CONFIG_SND_MXC_SOC_IRAM +#define SND_RAM_SIZE 0x6000 +#else +#define SND_RAM_SIZE 0 +#endif + +#ifdef CONFIG_MXC_VPU_IRAM +#define VPU_IRAM_SIZE 0x7000 +#else +#define VPU_IRAM_SIZE 0 +#endif + +#if (IRAM_SIZE < (SDMA_IRAM_SIZE + SND_RAM_SIZE + VPU_IRAM_SIZE + \ + SCC_IRAM_SIZE)) +#error "IRAM size exceeded" +#endif + +#define SCC_IRAM_BASE_ADDR (IRAM_BASE_ADDR + IRAM_SIZE - SCC_IRAM_SIZE) +#define VPU_IRAM_BASE_ADDR (SCC_IRAM_BASE_ADDR - VPU_IRAM_SIZE) +#define SND_RAM_BASE_ADDR (VPU_IRAM_BASE_ADDR - SND_RAM_SIZE) +#define SDMA_IRAM_BASE_ADDR (SND_RAM_BASE_ADDR - SDMA_IRAM_SIZE) +#define IDLE_IRAM_BASE_ADDR (SDMA_IRAM_BASE_ADDR - SZ_4K) + +/* + * NFC + */ +#define NFC_BASE_ADDR_AXI 0xCFFF0000 /* NAND flash AXI */ +#define NFC_BASE_ADDR_AXI_VIRT 0xF9000000 +#define NFC_AXI_SIZE SZ_64K + +/* + * Graphics Memory of GPU + */ +#define GPU_BASE_ADDR 0x20000000 + +#define TZIC_BASE_ADDR 0x8FFFC000 +#define TZIC_BASE_ADDR_VIRT 0xFA100000 +#define TZIC_SIZE SZ_16K + +#define DEBUG_BASE_ADDR 0x60000000 +#define DEBUG_BASE_ADDR_VIRT 0xFA200000 +#define DEBUG_SIZE SZ_1M +#define ETB_BASE_ADDR (DEBUG_BASE_ADDR + 0x00001000) +#define ETM_BASE_ADDR (DEBUG_BASE_ADDR + 0x00002000) +#define TPIU_BASE_ADDR (DEBUG_BASE_ADDR + 0x00003000) +#define CTI0_BASE_ADDR (DEBUG_BASE_ADDR + 0x00004000) +#define CTI1_BASE_ADDR (DEBUG_BASE_ADDR + 0x00005000) +#define CTI2_BASE_ADDR (DEBUG_BASE_ADDR + 0x00006000) +#define CTI3_BASE_ADDR (DEBUG_BASE_ADDR + 0x00007000) +#define CORTEX_DBG_BASE_ADDR (DEBUG_BASE_ADDR + 0x00008000) + +/* + * SPBA global module enabled #0 + */ +#define SPBA0_BASE_ADDR 0x70000000 +#define SPBA0_BASE_ADDR_VIRT 0xFB100000 +#define SPBA0_SIZE SZ_1M + +#define MMC_SDHC1_BASE_ADDR (SPBA0_BASE_ADDR + 0x00004000) +#define MMC_SDHC2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00008000) +#define UART3_BASE_ADDR (SPBA0_BASE_ADDR + 0x0000C000) +#define CSPI1_BASE_ADDR (SPBA0_BASE_ADDR + 0x00010000) +#define SSI2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00014000) +#define MMC_SDHC3_BASE_ADDR (SPBA0_BASE_ADDR + 0x00020000) +#define MMC_SDHC4_BASE_ADDR (SPBA0_BASE_ADDR + 0x00024000) +#define SPDIF_BASE_ADDR (SPBA0_BASE_ADDR + 0x00028000) +#define ATA_DMA_BASE_ADDR (SPBA0_BASE_ADDR + 0x00030000) +#define SLIM_DMA_BASE_ADDR (SPBA0_BASE_ADDR + 0x00034000) +#define HSI2C_DMA_BASE_ADDR (SPBA0_BASE_ADDR + 0x00038000) +#define SPBA_CTRL_BASE_ADDR (SPBA0_BASE_ADDR + 0x0003C000) + +/*! + * defines for SPBA modules + */ +#define SPBA_SDHC1 0x04 +#define SPBA_SDHC2 0x08 +#define SPBA_UART3 0x0C +#define SPBA_CSPI1 0x10 +#define SPBA_SSI2 0x14 +#define SPBA_SDHC3 0x20 +#define SPBA_SDHC4 0x24 +#define SPBA_SPDIF 0x28 +#define SPBA_ATA 0x30 +#define SPBA_SLIM 0x34 +#define SPBA_HSI2C 0x38 +#define SPBA_CTRL 0x3C + +/* + * AIPS 1 + */ +#define AIPS1_BASE_ADDR 0x73F00000 +#define AIPS1_BASE_ADDR_VIRT 0xFB000000 +#define AIPS1_SIZE SZ_1M + +#define OTG_BASE_ADDR (AIPS1_BASE_ADDR + 0x00080000) +#define GPIO1_BASE_ADDR (AIPS1_BASE_ADDR + 0x00084000) +#define GPIO2_BASE_ADDR (AIPS1_BASE_ADDR + 0x00088000) +#define GPIO3_BASE_ADDR (AIPS1_BASE_ADDR + 0x0008C000) +#define GPIO4_BASE_ADDR (AIPS1_BASE_ADDR + 0x00090000) +#define KPP_BASE_ADDR (AIPS1_BASE_ADDR + 0x00094000) +#define WDOG1_BASE_ADDR (AIPS1_BASE_ADDR + 0x00098000) +#define WDOG2_BASE_ADDR (AIPS1_BASE_ADDR + 0x0009C000) +#define GPT1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A0000) +#define SRTC_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A4000) +#define IOMUXC_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A8000) +#define EPIT1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000AC000) +#define EPIT2_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B0000) +#define PWM1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B4000) +#define PWM2_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B8000) +#define UART1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000BC000) +#define UART2_BASE_ADDR (AIPS1_BASE_ADDR + 0x000C0000) +#define SRC_BASE_ADDR (AIPS1_BASE_ADDR + 0x000D0000) +#define CCM_BASE_ADDR (AIPS1_BASE_ADDR + 0x000D4000) +#define GPC_BASE_ADDR (AIPS1_BASE_ADDR + 0x000D8000) + +/*! + * Defines for modules using static and dynamic DMA channels + */ +#define MXC_DMA_CHANNEL_IRAM 30 +#define MXC_DMA_CHANNEL_SPDIF_TX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_UART1_RX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_UART1_TX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_UART2_RX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_UART2_TX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_UART3_RX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_UART3_TX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_MMC1 MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_MMC2 MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_SSI1_RX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_SSI1_TX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_SSI2_RX MXC_DMA_DYNAMIC_CHANNEL +#ifdef CONFIG_SDMA_IRAM +#define MXC_DMA_CHANNEL_SSI2_TX (MXC_DMA_CHANNEL_IRAM + 1) +#else /*CONFIG_SDMA_IRAM */ +#define MXC_DMA_CHANNEL_SSI2_TX MXC_DMA_DYNAMIC_CHANNEL +#endif /*CONFIG_SDMA_IRAM */ +#define MXC_DMA_CHANNEL_CSPI1_RX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_CSPI1_TX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_CSPI2_RX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_CSPI2_TX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_CSPI3_RX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_CSPI3_TX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_ATA_RX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_ATA_TX MXC_DMA_DYNAMIC_CHANNEL +#define MXC_DMA_CHANNEL_MEMORY MXC_DMA_DYNAMIC_CHANNEL + +/* + * AIPS 2 + */ +#define AIPS2_BASE_ADDR 0x83F00000 +#define AIPS2_BASE_ADDR_VIRT 0xFB200000 +#define AIPS2_SIZE SZ_1M + +#define PLL1_BASE_ADDR (AIPS2_BASE_ADDR + 0x00080000) +#define PLL2_BASE_ADDR (AIPS2_BASE_ADDR + 0x00084000) +#define PLL3_BASE_ADDR (AIPS2_BASE_ADDR + 0x00088000) +#define AHBMAX_BASE_ADDR (AIPS2_BASE_ADDR + 0x00094000) +#define IIM_BASE_ADDR (AIPS2_BASE_ADDR + 0x00098000) +#define CSU_BASE_ADDR (AIPS2_BASE_ADDR + 0x0009C000) +#define ARM_BASE_ADDR (AIPS2_BASE_ADDR + 0x000A0000) +#define OWIRE_BASE_ADDR (AIPS2_BASE_ADDR + 0x000A4000) +#define FIRI_BASE_ADDR (AIPS2_BASE_ADDR + 0x000A8000) +#define CSPI2_BASE_ADDR (AIPS2_BASE_ADDR + 0x000AC000) +#define SDMA_BASE_ADDR (AIPS2_BASE_ADDR + 0x000B0000) +#define SCC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000B4000) +#define ROMCP_BASE_ADDR (AIPS2_BASE_ADDR + 0x000B8000) +#define RTIC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000BC000) +#define CSPI3_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C0000) +#define I2C2_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C4000) +#define I2C1_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C8000) +#define SSI1_BASE_ADDR (AIPS2_BASE_ADDR + 0x000CC000) +#define AUDMUX_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D0000) +#define M4IF_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D8000) +#define ESDCTL_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D9000) +#define WEIM_BASE_ADDR (AIPS2_BASE_ADDR + 0x000DA000) +#define NFC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000DB000) +#define EMI_BASE_ADDR (AIPS2_BASE_ADDR + 0x000DBF00) +#define MIPI_HSC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000DC000) +#define ATA_BASE_ADDR (AIPS2_BASE_ADDR + 0x000E0000) +#define SIM_BASE_ADDR (AIPS2_BASE_ADDR + 0x000E4000) +#define SSI3BASE_ADDR (AIPS2_BASE_ADDR + 0x000E8000) +#define FEC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000EC000) +#define TVE_BASE_ADDR (AIPS2_BASE_ADDR + 0x000F0000) +#define VPU_BASE_ADDR (AIPS2_BASE_ADDR + 0x000F4000) +#define SAHARA_BASE_ADDR (AIPS2_BASE_ADDR + 0x000F8000) + +/* + * Memory regions and CS + */ +#define GPU_CTRL_BASE_ADDR 0x30000000 +#define IPU_CTRL_BASE_ADDR 0x40000000 +#define CSD0_BASE_ADDR 0x90000000 +#define CSD1_BASE_ADDR 0xA0000000 +#define CS0_BASE_ADDR 0xB0000000 +#define CS1_BASE_ADDR 0xB8000000 +#define CS2_BASE_ADDR 0xC0000000 +#define CS3_BASE_ADDR 0xC8000000 +#define CS4_BASE_ADDR 0xCC000000 +#define CS5_BASE_ADDR 0xCE000000 + +/*! + * 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) >= (unsigned long)IRAM_BASE_ADDR) && \ + ((x) < (unsigned long)IRAM_BASE_ADDR + IRAM_SIZE)) ? \ + IRAM_IO_ADDRESS(x):\ + (((x) >= (unsigned long)TZIC_BASE_ADDR) && \ + ((x) < (unsigned long)TZIC_BASE_ADDR + TZIC_SIZE)) ? \ + TZIC_IO_ADDRESS(x):\ + (((x) >= (unsigned long)DEBUG_BASE_ADDR) && \ + ((x) < (unsigned long)DEBUG_BASE_ADDR + DEBUG_SIZE)) ? \ + DEBUG_IO_ADDRESS(x):\ + (((x) >= (unsigned long)SPBA0_BASE_ADDR) && \ + ((x) < (unsigned long)SPBA0_BASE_ADDR + SPBA0_SIZE)) ? \ + SPBA0_IO_ADDRESS(x):\ + (((x) >= (unsigned long)AIPS1_BASE_ADDR) && \ + ((x) < (unsigned long)AIPS1_BASE_ADDR + AIPS1_SIZE)) ? \ + AIPS1_IO_ADDRESS(x):\ + (((x) >= (unsigned long)AIPS2_BASE_ADDR) && \ + ((x) < (unsigned long)AIPS2_BASE_ADDR + AIPS2_SIZE)) ? \ + AIPS2_IO_ADDRESS(x):\ + (((x) >= (unsigned long)NFC_BASE_ADDR_AXI) && \ + ((x) < (unsigned long)NFC_BASE_ADDR_AXI + NFC_AXI_SIZE)) ? \ + NFC_BASE_ADDR_AXI_IO_ADDRESS(x):\ + 0xDEADBEEF) + +/* + * define the address mapping macros: in physical address order + */ +#define IRAM_IO_ADDRESS(x) \ + (((x) - IRAM_BASE_ADDR) + IRAM_BASE_ADDR_VIRT) + +#define TZIC_IO_ADDRESS(x) \ + (((x) - TZIC_BASE_ADDR) + TZIC_BASE_ADDR_VIRT) + +#define DEBUG_IO_ADDRESS(x) \ + (((x) - DEBUG_BASE_ADDR) + DEBUG_BASE_ADDR_VIRT) + +#define SPBA0_IO_ADDRESS(x) \ + (((x) - SPBA0_BASE_ADDR) + SPBA0_BASE_ADDR_VIRT) + +#define AIPS1_IO_ADDRESS(x) \ + (((x) - AIPS1_BASE_ADDR) + AIPS1_BASE_ADDR_VIRT) + +#define AIPS2_IO_ADDRESS(x) \ + (((x) - AIPS2_BASE_ADDR) + AIPS2_BASE_ADDR_VIRT) + +#define NFC_BASE_ADDR_AXI_IO_ADDRESS(x) \ + (((x) - NFC_BASE_ADDR_AXI) + NFC_BASE_ADDR_AXI_VIRT) + +#define IS_MEM_DEVICE_NONSHARED(x) 0 + +/* + * DMA request assignments + */ +#define DMA_REQ_SSI3_TX1 47 +#define DMA_REQ_SSI3_RX1 46 +#define DMA_REQ_SPDIF 45 +#define DMA_REQ_UART3_TX 44 +#define DMA_REQ_UART3_RX 43 +#define DMA_REQ_SLIM_B_TX 42 +#define DMA_REQ_SDHC4 41 +#define DMA_REQ_SDHC3 40 +#define DMA_REQ_CSPI_TX 39 +#define DMA_REQ_CSPI_RX 38 +#define DMA_REQ_SSI3_TX2 37 +#define DMA_REQ_IPU 36 +#define DMA_REQ_SSI3_RX2 35 +#define DMA_REQ_EPIT2 34 +#define DMA_REQ_CTI2_1 33 +#define DMA_REQ_EMI_WR 32 +#define DMA_REQ_CTI2_0 31 +#define DMA_REQ_EMI_RD 30 +#define DMA_REQ_SSI1_TX1 29 +#define DMA_REQ_SSI1_RX1 28 +#define DMA_REQ_SSI1_TX2 27 +#define DMA_REQ_SSI1_RX2 26 +#define DMA_REQ_SSI2_TX1 25 +#define DMA_REQ_SSI2_RX1 24 +#define DMA_REQ_SSI2_TX2 23 +#define DMA_REQ_SSI2_RX2 22 +#define DMA_REQ_SDHC2 21 +#define DMA_REQ_SDHC1 20 +#define DMA_REQ_UART1_TX 19 +#define DMA_REQ_UART1_RX 18 +#define DMA_REQ_UART2_TX 17 +#define DMA_REQ_UART2_RX 16 +#define DMA_REQ_GPU 15 +#define DMA_REQ_EXTREQ1 14 +#define DMA_REQ_FIRI_TX 13 +#define DMA_REQ_FIRI_RX 12 +#define DMA_REQ_HS_I2C_RX 11 +#define DMA_REQ_HS_I2C_TX 10 +#define DMA_REQ_CSPI2_TX 9 +#define DMA_REQ_CSPI2_RX 8 +#define DMA_REQ_CSPI1_TX 7 +#define DMA_REQ_CSPI1_RX 6 +#define DMA_REQ_SLIM_B 5 +#define DMA_REQ_ATA_TX_END 4 +#define DMA_REQ_ATA_TX 3 +#define DMA_REQ_ATA_RX 2 +#define DMA_REQ_GPC 1 +#define DMA_REQ_VPU 0 + +/* + * Interrupt numbers + */ +#define MXC_INT_BASE 0 +#define MXC_INT_RESV0 0 +#define MXC_INT_MMC_SDHC1 1 +#define MXC_INT_MMC_SDHC2 2 +#define MXC_INT_MMC_SDHC3 3 +#define MXC_INT_MMC_SDHC4 4 +#define MXC_INT_RESV5 5 +#define MXC_INT_SDMA 6 +#define MXC_INT_IOMUX 7 +#define MXC_INT_NFC 8 +#define MXC_INT_VPU 9 +#define MXC_INT_IPU_ERR 10 +#define MXC_INT_IPU_SYN 11 +#define MXC_INT_GPU 12 +#define MXC_INT_RESV13 13 +#define MXC_INT_USB_H1 14 +#define MXC_INT_EMI 15 +#define MXC_INT_USB_H2 16 +#define MXC_INT_USB_H3 17 +#define MXC_INT_USB_OTG 18 +#define MXC_INT_SAHARA_H0 19 +#define MXC_INT_SAHARA_H1 20 +#define MXC_INT_SCC_SMN 21 +#define MXC_INT_SCC_STZ 22 +#define MXC_INT_SCC_SCM 23 +#define MXC_INT_SRTC_NTZ 24 +#define MXC_INT_SRTC_TZ 25 +#define MXC_INT_RTIC 26 +#define MXC_INT_CSU 27 +#define MXC_INT_SLIM_B 28 +#define MXC_INT_SSI1 29 +#define MXC_INT_SSI2 30 +#define MXC_INT_UART1 31 +#define MXC_INT_UART2 32 +#define MXC_INT_UART3 33 +#define MXC_INT_RESV34 34 +#define MXC_INT_RESV35 35 +#define MXC_INT_CSPI1 36 +#define MXC_INT_CSPI2 37 +#define MXC_INT_CSPI 38 +#define MXC_INT_GPT 39 +#define MXC_INT_EPIT1 40 +#define MXC_INT_EPIT2 41 +#define MXC_INT_GPIO1_INT7 42 +#define MXC_INT_GPIO1_INT6 43 +#define MXC_INT_GPIO1_INT5 44 +#define MXC_INT_GPIO1_INT4 45 +#define MXC_INT_GPIO1_INT3 46 +#define MXC_INT_GPIO1_INT2 47 +#define MXC_INT_GPIO1_INT1 48 +#define MXC_INT_GPIO1_INT0 49 +#define MXC_INT_GPIO1_LOW 50 +#define MXC_INT_GPIO1_HIGH 51 +#define MXC_INT_GPIO2_LOW 52 +#define MXC_INT_GPIO2_HIGH 53 +#define MXC_INT_GPIO3_LOW 54 +#define MXC_INT_GPIO3_HIGH 55 +#define MXC_INT_GPIO4_LOW 56 +#define MXC_INT_GPIO4_HIGH 57 +#define MXC_INT_WDOG1 58 +#define MXC_INT_WDOG2 59 +#define MXC_INT_KPP 60 +#define MXC_INT_PWM1 61 +#define MXC_INT_I2C1 62 +#define MXC_INT_I2C2 63 +#define MXC_INT_HS_I2C 64 +#define MXC_INT_RESV65 65 +#define MXC_INT_RESV66 66 +#define MXC_INT_SIM_IPB 67 +#define MXC_INT_SIM_DAT 68 +#define MXC_INT_IIM 69 +#define MXC_INT_ATA 70 +#define MXC_INT_CCM1 71 +#define MXC_INT_CCM2 72 +#define MXC_INT_GPC1 73 +#define MXC_INT_GPC2 74 +#define MXC_INT_SRC 75 +#define MXC_INT_NM 76 +#define MXC_INT_PMU 77 +#define MXC_INT_CTI_IRQ 78 +#define MXC_INT_CTI1_TG0 79 +#define MXC_INT_CTI1_TG1 80 +#define MXC_INT_MCG_ERR 81 +#define MXC_INT_MCG_TMR 82 +#define MXC_INT_MCG_FUNC 83 +#define MXC_INT_GPU2_IRQ 84 +#define MXC_INT_GPU2_BUSY 85 +#define MXC_INT_RESV86 86 +#define MXC_INT_FEC 87 +#define MXC_INT_OWIRE 88 +#define MXC_INT_CTI1_TG2 89 +#define MXC_INT_SJC 90 +#define MXC_INT_SPDIF 91 +#define MXC_INT_TVE 92 +#define MXC_INT_FIRI 93 +#define MXC_INT_PWM2 94 +#define MXC_INT_SLIM_EXP 95 +#define MXC_INT_SSI3 96 +#define MXC_INT_EMI_BOOT 97 +#define MXC_INT_CTI1_TG3 98 +#define MXC_INT_SMC_RX 99 +#define MXC_INT_VPU_IDLE 100 +#define MXC_INT_EMI_NFC 101 +#define MXC_INT_GPU_IDLE 102 + +#define MXC_MAX_INT_LINES 128 + +#define MXC_GPIO_INT_BASE (MXC_MAX_INT_LINES) + +/*! + * Number of GPIO port as defined in the IC Spec + */ +#define GPIO_PORT_NUM 4 +/*! + * Number of GPIO pins per port + */ +#define GPIO_NUM_PIN 32 + +#define MXC_GPIO_SPLIT_IRQ_2 + +#endif /* __ASM_ARCH_MXC_MX51_H__ */ --- linux-2.6.28.orig/arch/arm/plat-mxc/include/mach/mxc_uart.h +++ linux-2.6.28/arch/arm/plat-mxc/include/mach/mxc_uart.h @@ -0,0 +1,275 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @defgroup UART Universal Asynchronous Receiver Transmitter (UART) Driver + */ + +/*! + * @file arch-mxc/mxc_uart.h + * + * @brief This file contains the UART configuration structure definition. + * + * + * @ingroup UART + */ + +#ifndef __ASM_ARCH_MXC_UART_H__ +#define __ASM_ARCH_MXC_UART_H__ + +#ifdef __KERNEL__ + +#include +#include + +/* + * The modes of the UART ports + */ +#define MODE_DTE 0 +#define MODE_DCE 1 +/* + * Is the UART configured to be a IR port + */ +#define IRDA 0 +#define NO_IRDA 1 + +/*! + * This structure is used to store the the physical and virtual + * addresses of the UART DMA receive buffer. + */ +typedef struct { + /*! + * DMA Receive buffer virtual address + */ + char *rx_buf; + /*! + * DMA Receive buffer physical address + */ + dma_addr_t rx_handle; +} mxc_uart_rxdmamap; + +/*! + * This structure is a way for the low level driver to define their own + * \b uart_port structure. This structure includes the core \b uart_port + * structure that is provided by Linux as an element and has other + * elements that are specifically required by this low-level driver. + */ +typedef struct { + /*! + * The port structure holds all the information about the UART + * port like base address, and so on. + */ + struct uart_port port; + /*! + * Flag to determine if the interrupts are muxed. + */ + int ints_muxed; + /*! + * Array that holds the receive and master interrupt numbers + * when the interrupts are not muxed. + */ + int irqs[2]; + /*! + * Flag to determine the DTE/DCE mode. + */ + int mode; + /*! + * Flag to hold the IR mode of the port. + */ + int ir_mode; + /*! + * Flag to enable/disable the UART port. + */ + int enabled; + /*! + * Flag to indicate if we wish to use hardware-driven hardware + * flow control. + */ + int hardware_flow; + /*! + * Holds the threshold value at which the CTS line is deasserted in + * case we use hardware-driven hardware flow control. + */ + unsigned int cts_threshold; + /*! + * Flag to enable/disable DMA data transfer. + */ + int dma_enabled; + /*! + * Holds the DMA receive buffer size. + */ + int dma_rxbuf_size; + /*! + * DMA Receive buffers information + */ + mxc_uart_rxdmamap *rx_dmamap; + /*! + * DMA RX buffer id + */ + int dma_rxbuf_id; + /*! + * DMA Transmit buffer virtual address + */ + char *tx_buf; + /*! + * DMA Transmit buffer physical address + */ + dma_addr_t tx_handle; + /*! + * Holds the RxFIFO threshold value. + */ + unsigned int rx_threshold; + /*! + * Holds the TxFIFO threshold value. + */ + unsigned int tx_threshold; + /*! + * Information whether this is a shared UART + */ + unsigned int shared; + /*! + * Clock id for UART clock + */ + struct clk *clk; + /*! + * Information whether RXDMUXSEL must be set or not for IR port + */ + int rxd_mux; + int ir_tx_inv; + int ir_rx_inv; + /*! + * DMA ID for transmit + */ + mxc_dma_device_t dma_tx_id; + /*! + * DMA ID for receive + */ + mxc_dma_device_t dma_rx_id; +} uart_mxc_port; + +/* Address offsets of the UART registers */ +#define MXC_UARTURXD 0x000 /* Receive reg */ +#define MXC_UARTUTXD 0x040 /* Transmitter reg */ +#define MXC_UARTUCR1 0x080 /* Control reg 1 */ +#define MXC_UARTUCR2 0x084 /* Control reg 2 */ +#define MXC_UARTUCR3 0x088 /* Control reg 3 */ +#define MXC_UARTUCR4 0x08C /* Control reg 4 */ +#define MXC_UARTUFCR 0x090 /* FIFO control reg */ +#define MXC_UARTUSR1 0x094 /* Status reg 1 */ +#define MXC_UARTUSR2 0x098 /* Status reg 2 */ +#define MXC_UARTUESC 0x09C /* Escape character reg */ +#define MXC_UARTUTIM 0x0A0 /* Escape timer reg */ +#define MXC_UARTUBIR 0x0A4 /* BRM incremental reg */ +#define MXC_UARTUBMR 0x0A8 /* BRM modulator reg */ +#define MXC_UARTUBRC 0x0AC /* Baud rate count reg */ +#define MXC_UARTONEMS 0x0B0 /* One millisecond reg */ +#define MXC_UARTUTS 0x0B4 /* Test reg */ + +/* Bit definations of UCR1 */ +#define MXC_UARTUCR1_ADEN 0x8000 +#define MXC_UARTUCR1_ADBR 0x4000 +#define MXC_UARTUCR1_TRDYEN 0x2000 +#define MXC_UARTUCR1_IDEN 0x1000 +#define MXC_UARTUCR1_RRDYEN 0x0200 +#define MXC_UARTUCR1_RXDMAEN 0x0100 +#define MXC_UARTUCR1_IREN 0x0080 +#define MXC_UARTUCR1_TXMPTYEN 0x0040 +#define MXC_UARTUCR1_RTSDEN 0x0020 +#define MXC_UARTUCR1_SNDBRK 0x0010 +#define MXC_UARTUCR1_TXDMAEN 0x0008 +#define MXC_UARTUCR1_ATDMAEN 0x0004 +#define MXC_UARTUCR1_DOZE 0x0002 +#define MXC_UARTUCR1_UARTEN 0x0001 + +/* Bit definations of UCR2 */ +#define MXC_UARTUCR2_ESCI 0x8000 +#define MXC_UARTUCR2_IRTS 0x4000 +#define MXC_UARTUCR2_CTSC 0x2000 +#define MXC_UARTUCR2_CTS 0x1000 +#define MXC_UARTUCR2_PREN 0x0100 +#define MXC_UARTUCR2_PROE 0x0080 +#define MXC_UARTUCR2_STPB 0x0040 +#define MXC_UARTUCR2_WS 0x0020 +#define MXC_UARTUCR2_RTSEN 0x0010 +#define MXC_UARTUCR2_ATEN 0x0008 +#define MXC_UARTUCR2_TXEN 0x0004 +#define MXC_UARTUCR2_RXEN 0x0002 +#define MXC_UARTUCR2_SRST 0x0001 + +/* Bit definations of UCR3 */ +#define MXC_UARTUCR3_DTREN 0x2000 +#define MXC_UARTUCR3_PARERREN 0x1000 +#define MXC_UARTUCR3_FRAERREN 0x0800 +#define MXC_UARTUCR3_DSR 0x0400 +#define MXC_UARTUCR3_DCD 0x0200 +#define MXC_UARTUCR3_RI 0x0100 +#define MXC_UARTUCR3_RXDSEN 0x0040 +#define MXC_UARTUCR3_AWAKEN 0x0010 +#define MXC_UARTUCR3_DTRDEN 0x0008 +#define MXC_UARTUCR3_RXDMUXSEL 0x0004 +#define MXC_UARTUCR3_INVT 0x0002 + +/* Bit definations of UCR4 */ +#define MXC_UARTUCR4_CTSTL_OFFSET 10 +#define MXC_UARTUCR4_CTSTL_MASK (0x3F << 10) +#define MXC_UARTUCR4_INVR 0x0200 +#define MXC_UARTUCR4_ENIRI 0x0100 +#define MXC_UARTUCR4_REF16 0x0040 +#define MXC_UARTUCR4_IRSC 0x0020 +#define MXC_UARTUCR4_TCEN 0x0008 +#define MXC_UARTUCR4_OREN 0x0002 +#define MXC_UARTUCR4_DREN 0x0001 + +/* Bit definations of UFCR */ +#define MXC_UARTUFCR_RFDIV 0x0200 /* Ref freq div is set to 2 */ +#define MXC_UARTUFCR_RFDIV_OFFSET 7 +#define MXC_UARTUFCR_RFDIV_MASK (0x7 << 7) +#define MXC_UARTUFCR_TXTL_OFFSET 10 +#define MXC_UARTUFCR_DCEDTE 0x0040 + +/* Bit definations of URXD */ +#define MXC_UARTURXD_ERR 0x4000 +#define MXC_UARTURXD_OVRRUN 0x2000 +#define MXC_UARTURXD_FRMERR 0x1000 +#define MXC_UARTURXD_BRK 0x0800 +#define MXC_UARTURXD_PRERR 0x0400 + +/* Bit definations of USR1 */ +#define MXC_UARTUSR1_PARITYERR 0x8000 +#define MXC_UARTUSR1_RTSS 0x4000 +#define MXC_UARTUSR1_TRDY 0x2000 +#define MXC_UARTUSR1_RTSD 0x1000 +#define MXC_UARTUSR1_FRAMERR 0x0400 +#define MXC_UARTUSR1_RRDY 0x0200 +#define MXC_UARTUSR1_AGTIM 0x0100 +#define MXC_UARTUSR1_DTRD 0x0080 +#define MXC_UARTUSR1_AWAKE 0x0010 + +/* Bit definations of USR2 */ +#define MXC_UARTUSR2_TXFE 0x4000 +#define MXC_UARTUSR2_IDLE 0x1000 +#define MXC_UARTUSR2_RIDELT 0x0400 +#define MXC_UARTUSR2_RIIN 0x0200 +#define MXC_UARTUSR2_DCDDELT 0x0040 +#define MXC_UARTUSR2_DCDIN 0x0020 +#define MXC_UARTUSR2_TXDC 0x0008 +#define MXC_UARTUSR2_ORE 0x0002 +#define MXC_UARTUSR2_RDR 0x0001 +#define MXC_UARTUSR2_BRCD 0x0004 + +/* Bit definations of UTS */ +#define MXC_UARTUTS_LOOP 0x1000 + +#endif /* __KERNEL__ */ + +#endif /* __ASM_ARCH_MXC_UART_H__ */ --- linux-2.6.28.orig/arch/arm/plat-mxc/include/mach/hardware.h +++ linux-2.6.28/arch/arm/plat-mxc/include/mach/hardware.h @@ -1,20 +1,11 @@ /* - * 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. + * Copyright 2004-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 version 2 as + * published by the Free Software Foundation. */ #ifndef __ASM_ARCH_MXC_HARDWARE_H__ @@ -22,16 +13,139 @@ #include +/* + * --------------------------------------------------------------------------- + * Processor specific defines + * --------------------------------------------------------------------------- + */ +#define CHIP_REV_1_0 0x10 +#define CHIP_REV_1_1 0x11 +#define CHIP_REV_1_2 0x12 +#define CHIP_REV_1_3 0x13 +#define CHIP_REV_2_0 0x20 +#define CHIP_REV_2_1 0x21 +#define CHIP_REV_2_2 0x22 +#define CHIP_REV_2_3 0x23 +#define CHIP_REV_3_0 0x30 +#define CHIP_REV_3_1 0x31 +#define CHIP_REV_3_2 0x32 + +#define BOARD_REV_2 0x100 + +#ifndef __ASSEMBLY__ +extern unsigned int system_rev; +#endif +#define mxc_set_system_rev(part, rev) { \ + system_rev = (part << 12) | rev; \ +} + +#define mxc_cpu() (system_rev >> 12) +#define mxc_is_cpu(part) ((mxc_cpu() == part) ? 1 : 0) +#define mxc_cpu_rev() (system_rev & 0xFF) +#define mxc_cpu_rev_major() ((system_rev >> 4) & 0xF) +#define mxc_cpu_rev_minor() (system_rev & 0xF) +#define mxc_cpu_is_rev(rev) \ + ((mxc_cpu_rev() == rev) ? 1 : ((mxc_cpu_rev() < rev) ? -1 : 2)) +#define MXC_REV(type) \ +static inline int type## _rev (int rev) \ +{ \ + return (type() ? mxc_cpu_is_rev(rev) : 0); \ +} + #ifdef CONFIG_ARCH_MX3 # include +#define cpu_is_mx31() (mxc_is_cpu(0x31)) /*system_rev got from Redboot */ +#define cpu_is_mx32() (mxc_is_cpu(0x32)) /*system_rev got from Redboot */ +#else +#define cpu_is_mx31() (0) +#define cpu_is_mx32() (0) +#endif + +#ifdef CONFIG_ARCH_MX35 +#include +#define cpu_is_mx35() (1) +#define board_is_mx35(rev) ((system_rev & rev) ? 1 : 0) +#else +#define cpu_is_mx35() (0) +#define board_is_mx35(rev) (0) +#endif + +#ifdef CONFIG_ARCH_MX37 +#include +#define cpu_is_mx37() (1) +#define board_is_mx37(rev) ((system_rev & rev) ? 1 : 0) +#else +#define cpu_is_mx37() (0) +#define board_is_mx37(rev) (0) #endif -#ifdef CONFIG_ARCH_MX2 -# ifdef CONFIG_MACH_MX27 -# include -# endif +#ifdef CONFIG_ARCH_MX51 +#include +#define cpu_is_mx51() (1) +#else +#define cpu_is_mx51() (0) #endif +#ifdef CONFIG_ARCH_MX21 +#include +#define cpu_is_mx21() (1) +#else +#define cpu_is_mx21() (0) +#endif + +#ifdef CONFIG_ARCH_MX25 +#include +#define cpu_is_mx25() (1) +#else +#define cpu_is_mx25() (0) +#endif + +#ifdef CONFIG_ARCH_MX27 +#include +#define cpu_is_mx27() (1) +#else +#define cpu_is_mx27() (0) +#endif + +#ifndef __ASSEMBLY__ +/* + * Create inline functions to test for cpu revision + * Function name is cpu_is__rev(rev) + * + * Returns: + * 0 - not the cpu queried + * 1 - cpu and revision match + * 2 - cpu matches, but cpu revision is greater than queried rev + * -1 - cpu matches, but cpu revision is less than queried rev + */ +MXC_REV(cpu_is_mx21); +MXC_REV(cpu_is_mx25); +MXC_REV(cpu_is_mx27); +MXC_REV(cpu_is_mx31); +MXC_REV(cpu_is_mx32); +MXC_REV(cpu_is_mx35); +MXC_REV(cpu_is_mx37); +MXC_REV(cpu_is_mx51); +#endif #include +#define MXC_MAX_GPIO_LINES (GPIO_NUM_PIN * GPIO_PORT_NUM) + +#define MXC_EXP_IO_BASE (MXC_MAX_INT_LINES + MXC_MAX_GPIO_LINES) +#define MXC_MAX_EXP_IO_LINES 16 + +#ifdef CONFIG_MXC_PSEUDO_IRQS +#define MXC_PSEUDO_IO_BASE (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES) +#define MXC_MAX_PSEUDO_IO_LINES 16 +#else +#define MXC_MAX_PSEUDO_IO_LINES 0 +#endif + +#ifndef MXC_INT_FORCE +#define MXC_INT_FORCE -1 +#endif +#define MXC_MAX_INTS (MXC_MAX_INT_LINES + \ + MXC_MAX_GPIO_LINES + \ + MXC_MAX_EXP_IO_LINES + \ + MXC_MAX_PSEUDO_IO_LINES) #endif /* __ASM_ARCH_MXC_HARDWARE_H__ */ --- linux-2.6.28.orig/arch/arm/plat-mxc/sdma/Makefile +++ linux-2.6.28/arch/arm/plat-mxc/sdma/Makefile @@ -0,0 +1,18 @@ +ifneq ($(KBUILD_SRC),) +ccflags-y += -I$(KBUILD_SRC)/arch/arm/plat-mxc/sdma/iapi/include \ + -I$(KBUILD_SRC)/include/linux \ + -DMCU -DOS=LINUX \ + -DL_I_T_T_L_E_ENDIAN=0 -DB_I_G_ENDIAN=1 \ + -DENDIANNESS=L_I_T_T_L_E_ENDIAN +else +ccflags-y += -Iarch/arm/plat-mxc/sdma/iapi/include \ + -Iinclude/linux \ + -DMCU -DOS=LINUX \ + -DL_I_T_T_L_E_ENDIAN=0 -DB_I_G_ENDIAN=1 \ + -DENDIANNESS=L_I_T_T_L_E_ENDIAN +endif + +obj-y += dma_sdma.o +obj-$(CONFIG_MXC_SDMA_API) += sdma.o +obj-$(CONFIG_MXC_SDMA_API) += iapi/ +obj-$(CONFIG_MXC_SDMA_API) += sdma_malloc.o --- linux-2.6.28.orig/arch/arm/plat-mxc/sdma/sdma.c +++ linux-2.6.28/arch/arm/plat-mxc/sdma/sdma.c @@ -0,0 +1,1397 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @file plat-mxc/sdma/sdma.c + * @brief This file contains functions for Smart DMA API + * + * SDMA (Smart DMA) is used for transferring data between MCU and peripherals + * + * @ingroup SDMA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "iapi.h" + +#define M3_BASE_ADDRESS CSD0_BASE_ADDR +#define CHAD(ch) sdma_data[0].cd->ccb_ptr[ch].channelDescriptor + +/*! + * SDMA status mutex + */ +static struct semaphore sdma_status_mutex; + +/*! + * SDMA channel sleep queues + */ +//static struct semaphore sdma_sleep_mutex[MAX_DMA_CHANNELS]; +static wait_queue_head_t sdma_sleep_queue[MAX_DMA_CHANNELS]; + +/*! + * SDMA channel synchronization + */ +static struct semaphore sdma_synch_mutex[MAX_DMA_CHANNELS]; + +/*! + * SDMA buffers pool initialization function + */ +extern void init_sdma_pool(void); + +/*! + * Flags are save and restored during interrupt handler + */ +unsigned long flags; + +struct clk *mxc_sdma_ahb_clk, *mxc_sdma_ipg_clk; + +/*! + * Structure containing sdma channels information. + */ +typedef struct { + /*! Channel number */ + int channel; + /*! Channel usage name */ + int in_use; + /*! Name of device using the channel */ + char devicename[MAX_DEVNAME_LENGTH]; + /*! Transfer type. Needed for setting SDMA script */ + sdma_transferT transfer_type; + /*! Peripheral type. Needed for setting SDMA script */ + sdma_periphT peripheral_type; + /*! Watermark level of device's fifo */ + __u32 watermark_level; + /*! Peripheral event id */ + int event_id; + /*! Peripheral event id2 (for channels that use 2 events) */ + int event_id2; + /*! Running status (boolean) */ + int running; + /*! buffer descriptors number */ + int bd_number; + /*! callback function */ + dma_callback_t callback; + /*! callback argument */ + void *arg; + /*! SDMA data access word size */ + unsigned long word_size:8; + /*! channel descriptor pointer */ + channelDescriptor *cd; +} sdma_struct; + +/*! + * Used to save the status of channels. + */ +static sdma_struct sdma_data[MAX_DMA_CHANNELS]; + +/*! + * Stores the start address of the SDMA scripts + */ +static sdma_script_start_addrs sdma_script_addrs; + +extern void mxc_sdma_get_script_info(sdma_script_start_addrs * sdma_script_add); + +/*! + * Init sleep mutex of the channel + * + * @param channel channel number + */ +static void sdma_init_sleep(int channel) +{ + init_waitqueue_head(&sdma_sleep_queue[channel]); +} + +/*! + * Puts channel to sleep + * + * @param channel channel number + */ +static void sdma_sleep_channel(int channel) +{ + while ((iapi_SDMAIntr & (1 << channel)) == 0) { + wait_event_interruptible(sdma_sleep_queue[channel], + ((iapi_SDMAIntr & (1 << channel)) != + 0)); + } +} + +/*! + * Wake up channel from sleep + * + * @param channel channel number + */ +static void sdma_wakeup_channel(int channel) +{ + wake_up_interruptible(&sdma_sleep_queue[channel]); +} + +/*! + * Sdma interrupt handler routine. + * Calls channels callback function + * + * @param irq the interrupt number + * @param dev_id driver private data + * @return the function returns \b IRQ_RETVAL(1) - interrupt was handled + */ +static irqreturn_t sdma_int_handler(int irq, void *dev_id) +{ + IRQ_Handler(); + return IRQ_RETVAL(1); +} + +/*! + * I.API channel callback function + * + * @param cd channel descriptor structure + * @param channel_data SDMA struct of the current channel + */ +static void iapi_interrupt_callback(channelDescriptor * cd, + sdma_struct * channel_data) +{ + int channel; + dma_callback_t callback; + void *arg; + + channel = channel_data->channel; + + channel_data->running = 0; + + arg = channel_data->arg; + + if (arg == 0) { + arg = (void *)&channel; + } + + callback = channel_data->callback; + + if (callback != 0) { + callback(arg); + } +} + +/*! + * Returns pc of SDMA script according to peripheral and transfer type + * + * @param peripheral_type peripheral type + * @param transfer_type transfer type + * + * @return PC of SDMA script +*/ +static unsigned short sdma_get_pc(sdma_periphT peripheral_type, + sdma_transferT transfer_type) +{ + int res = 0; + + if (peripheral_type == MEMORY) { + switch (transfer_type) { + case emi_2_int: + res = sdma_script_addrs.mxc_sdma_ap_2_ap_addr; + break; + case emi_2_emi: + res = sdma_script_addrs.mxc_sdma_ap_2_ap_addr; + break; + case int_2_emi: + res = sdma_script_addrs.mxc_sdma_ap_2_ap_addr; + break; + default: + res = -EINVAL; + } + } else if (peripheral_type == DSP) { + switch (transfer_type) { + case emi_2_dsp: + res = sdma_script_addrs.mxc_sdma_ap_2_bp_addr; + break; + case dsp_2_emi: + res = sdma_script_addrs.mxc_sdma_bp_2_ap_addr; + break; + case dsp_2_emi_loop: + res = + sdma_script_addrs. + mxc_sdma_loopback_on_dsp_side_addr; + break; + case emi_2_dsp_loop: + res = + sdma_script_addrs.mxc_sdma_mcu_interrupt_only_addr; + break; + default: + res = -EINVAL; + } + } else if (peripheral_type == FIRI) { + switch (transfer_type) { + case per_2_int: + res = sdma_script_addrs.mxc_sdma_firi_2_per_addr; + break; + case per_2_emi: + res = sdma_script_addrs.mxc_sdma_firi_2_mcu_addr; + break; + case int_2_per: + res = sdma_script_addrs.mxc_sdma_per_2_firi_addr; + break; + case emi_2_per: + res = sdma_script_addrs.mxc_sdma_mcu_2_firi_addr; + break; + default: + res = -EINVAL; + } + } else if (peripheral_type == UART) { + switch (transfer_type) { + case per_2_int: + res = sdma_script_addrs.mxc_sdma_uart_2_per_addr; + break; + case per_2_emi: + res = sdma_script_addrs.mxc_sdma_uart_2_mcu_addr; + break; + case int_2_per: + res = sdma_script_addrs.mxc_sdma_per_2_app_addr; + break; + case emi_2_per: + res = sdma_script_addrs.mxc_sdma_mcu_2_app_addr; + break; + default: + res = -EINVAL; + } + } else if (peripheral_type == UART_SP) { + switch (transfer_type) { + case per_2_int: + res = sdma_script_addrs.mxc_sdma_uartsh_2_per_addr; + break; + case per_2_emi: + res = sdma_script_addrs.mxc_sdma_uartsh_2_mcu_addr; + break; + case int_2_per: + res = sdma_script_addrs.mxc_sdma_per_2_shp_addr; + break; + case emi_2_per: + res = sdma_script_addrs.mxc_sdma_mcu_2_shp_addr; + break; + default: + res = -EINVAL; + } + } else if (peripheral_type == ATA) { + switch (transfer_type) { + case per_2_emi: + res = sdma_script_addrs.mxc_sdma_ata_2_mcu_addr; + break; + case emi_2_per: + res = sdma_script_addrs.mxc_sdma_mcu_2_ata_addr; + break; + default: + res = -EINVAL; + } + } else if (peripheral_type == CSPI || peripheral_type == EXT || + peripheral_type == SSI) { + switch (transfer_type) { + case per_2_int: + res = sdma_script_addrs.mxc_sdma_app_2_per_addr; + break; + case per_2_emi: + res = sdma_script_addrs.mxc_sdma_app_2_mcu_addr; + break; + case int_2_per: + res = sdma_script_addrs.mxc_sdma_per_2_app_addr; + break; + case emi_2_per: + res = sdma_script_addrs.mxc_sdma_mcu_2_app_addr; + break; + default: + res = -EINVAL; + } + } else if (peripheral_type == SSI_SP || peripheral_type == MMC || + peripheral_type == SDHC || peripheral_type == CSPI_SP || + peripheral_type == ESAI || peripheral_type == MSHC_SP) { + switch (transfer_type) { + case per_2_int: + res = sdma_script_addrs.mxc_sdma_shp_2_per_addr; + break; + case per_2_emi: + res = sdma_script_addrs.mxc_sdma_shp_2_mcu_addr; + break; + case int_2_per: + res = sdma_script_addrs.mxc_sdma_per_2_shp_addr; + break; + case emi_2_per: + res = sdma_script_addrs.mxc_sdma_mcu_2_shp_addr; + break; + default: + res = -EINVAL; + } + } else if (peripheral_type == ASRC) { + switch (transfer_type) { + case per_2_emi: + res = sdma_script_addrs.mxc_sdma_shp_2_mcu_addr; + break; + case emi_2_per: + res = sdma_script_addrs.mxc_sdma_mcu_2_shp_addr; + break; + case per_2_per: + res = sdma_script_addrs.mxc_sdma_per_2_per_addr; + break; + default: + res = -EINVAL; + } + } else if (peripheral_type == MSHC) { + switch (transfer_type) { + case per_2_emi: + res = sdma_script_addrs.mxc_sdma_mshc_2_mcu_addr; + break; + case emi_2_per: + res = sdma_script_addrs.mxc_sdma_mcu_2_mshc_addr; + break; + default: + res = -EINVAL; + } + } else if (peripheral_type == CCM) { + switch (transfer_type) { + case per_2_emi: + res = sdma_script_addrs.mxc_sdma_dptc_dvfs_addr; + break; + default: + res = -EINVAL; + } + } else if (peripheral_type == FIFO_MEMORY) { + res = sdma_script_addrs.mxc_sdma_ap_2_ap_fixed_addr; + } else if (peripheral_type == SPDIF) { + switch (transfer_type) { + case per_2_emi: + res = sdma_script_addrs.mxc_sdma_spdif_2_mcu_addr; + break; + case emi_2_per: + res = sdma_script_addrs.mxc_sdma_mcu_2_spdif_addr; + break; + default: + res = -EINVAL; + } + } else if (peripheral_type == IPU_MEMORY) { + if (transfer_type == emi_2_per) { + res = sdma_script_addrs.mxc_sdma_ext_mem_2_ipu_addr; + } else { + res = -EINVAL; + } + } + + if (res < 0) { + printk(KERN_ERR "SDMA script not found\n"); + } + + return res; + +} + +/*! + * Downloads channel context according to channel parameters + * + * @param channel channel number + * @param p channel parameters + */ +static int sdma_load_context(int channel, dma_channel_params * p) +{ + script_data context; + int res; + int event1_greater_than_32; + int event2_greater_than_32; + + res = 0; + + memset(&context, 0, sizeof(script_data)); + context.load_address = sdma_get_pc(p->peripheral_type, + p->transfer_type); + + if (context.load_address > 0) { + if ((p->peripheral_type != MEMORY) + && (p->peripheral_type != DSP)) { + /* Handle multiple event channels differently */ + if (p->event_id2) { + if (p->event_id2 < 32) { + context.event_mask2 = + 0x1 << p->event_id2; + event2_greater_than_32 = 0; + } else { + context.event_mask2 = + 0x1 << (p->event_id2 - 32); + event2_greater_than_32 = 1 << 31; + } + if (p->event_id < 32) { + context.event_mask1 = + 0x1 << p->event_id; + event1_greater_than_32 = 0; + } else { + context.event_mask1 = + 0x1 << (p->event_id - 32); + event1_greater_than_32 = 1 << 30; + } + } else { + event1_greater_than_32 = 0; + event2_greater_than_32 = 0; + if (p->event_id < 32) { + context.event_mask1 = + 0x1 << p->event_id; + context.event_mask2 = 0; + } else { + context.event_mask1 = 0; + context.event_mask2 = + 0x1 << (p->event_id - 32); + } + } + /* Watermark Level */ + context.wml = + event2_greater_than_32 | event1_greater_than_32 | + p->watermark_level; + + /* Address */ + context.shp_addr = (unsigned long)(p->per_address); + iapi_IoCtl(sdma_data[channel].cd, + IAPI_CHANGE_PERIPHADDR, p->per_address); + } else { + context.wml = M3_BASE_ADDRESS; + } + + sdma_data[channel].transfer_type = p->transfer_type; + sdma_data[channel].peripheral_type = p->peripheral_type; + sdma_data[channel].watermark_level = p->watermark_level; + iapi_AssignScript(sdma_data[channel].cd, &context); + } else { + res = context.load_address; + } + + return res; +} + +/*! + * Setup channel according to parameters. Must be called once after mxc_request_dma() + * + * @param channel channel number + * @param p channel parameters pointer + * @return 0 on success, error code on fail + */ +int mxc_dma_setup_channel(int channel, dma_channel_params * p) +{ + int err = 0; + int i; + + mxc_dma_stop(channel); + + for (i = 0; i < sdma_data[channel].bd_number; i++) { + iapi_IoCtl(sdma_data[channel].cd, + (i << BD_NUM_OFFSET) | + IAPI_CHANGE_SET_STATUS, (unsigned long)0); + } + + sdma_data[channel].bd_number = (p->bd_number <= 0) ? 1 : p->bd_number; + + sdma_data[channel].word_size = p->word_size; + + sdma_data[channel].event_id = p->event_id; + sdma_data[channel].event_id2 = p->event_id2; + + sdma_data[channel].callback = p->callback; + + sdma_data[channel].arg = p->arg; + + err = iapi_IoCtl(sdma_data[channel].cd, + IAPI_CHANGE_BDNUM, sdma_data[channel].bd_number); + + if (err < 0) { + printk(KERN_ERR "Failed allocating buffer \ +descriptors (0x%x)\n", err); + err = -ENOMEM; + goto setup_channel_fail; + } + + if (channel != 0) { + switch (p->transfer_type) { + case dsp_2_per: + break; + case emi_2_per: + case int_2_per: + case per_2_int: + case per_2_emi: + /* + * Peripheral <------> Memory + * evtOvr = 0 dspOvr = 1 + */ + iapi_IoCtl(sdma_data[channel].cd, IAPI_CHANGE_OWNERSHIP, + (OWN_CHANNEL << CH_OWNSHP_OFFSET_EVT) | + (OWN_CHANNEL << CH_OWNSHP_OFFSET_MCU) | + (DONT_OWN_CHANNEL << CH_OWNSHP_OFFSET_DSP)); + if (p->event_id) { + err = iapi_SetChannelEventMapping(p->event_id, + 0x1 << + channel); + } + if (!err && p->event_id2) { + err = iapi_SetChannelEventMapping(p->event_id2, + 0x1 << + channel); + } + break; + case emi_2_dsp: + case int_2_dsp: + case dsp_2_int: + case dsp_2_emi: + case dsp_2_dsp: + /* + * DSP <-----------> Memory + * evtOvr = 1 dspOvr = 0 + */ + iapi_IoCtl(sdma_data[channel].cd, IAPI_CHANGE_OWNERSHIP, + (DONT_OWN_CHANNEL << CH_OWNSHP_OFFSET_EVT) | + (OWN_CHANNEL << CH_OWNSHP_OFFSET_MCU) | + (OWN_CHANNEL << CH_OWNSHP_OFFSET_DSP)); + break; + case emi_2_int: + case emi_2_emi: + case int_2_int: + case int_2_emi: + case emi_2_dsp_loop: + case dsp_2_emi_loop: + /* evtOvr = 1 dspOvr = 1 */ + iapi_IoCtl(sdma_data[channel].cd, IAPI_CHANGE_OWNERSHIP, + (DONT_OWN_CHANNEL << CH_OWNSHP_OFFSET_EVT) | + (OWN_CHANNEL << CH_OWNSHP_OFFSET_MCU) | + (DONT_OWN_CHANNEL << CH_OWNSHP_OFFSET_DSP)); + break; + case per_2_dsp: + /* evtOvr = 0 dspOvr = 0 */ + iapi_IoCtl(sdma_data[channel].cd, IAPI_CHANGE_OWNERSHIP, + (OWN_CHANNEL << CH_OWNSHP_OFFSET_EVT) | + (DONT_OWN_CHANNEL << CH_OWNSHP_OFFSET_MCU) | + (OWN_CHANNEL << CH_OWNSHP_OFFSET_DSP)); + err = iapi_SetChannelEventMapping(p->event_id, + 0x1 << channel); + break; + default: + break; + printk(KERN_ERR "Wrong SDMA transfer type\n"); + err = -EINVAL; + } + if (err == 0) { + err = sdma_load_context(channel, p); + iapi_IoCtl(sdma_data[channel].cd, IAPI_CHANGE_PRIORITY, + MXC_SDMA_DEFAULT_PRIORITY); + } + } + setup_channel_fail: + return err; +} + +/*! + * Setup the channel priority. This can be used to change the default priority + * for the channel. + * + * @param channel channel number + * @param priority priority to be set for the channel + * + * @return 0 on success, error code on failure + */ +int mxc_dma_set_channel_priority(unsigned int channel, unsigned int priority) +{ + if (priority < MXC_SDMA_MIN_PRIORITY + || priority > MXC_SDMA_MAX_PRIORITY) { + return -EINVAL; + } + return iapi_IoCtl(sdma_data[channel].cd, IAPI_CHANGE_PRIORITY, + priority); +} + +/*! + * Allocates dma channel. + * If channel's value is 0, then the function allocates a free channel + * dynamically and sets its value to channel. + * Else allocates requested channel if it is free. + * If the channel is busy or no free channels (in dynamic allocation) -EBUSY returned. + * + * @param channel pointer to channel number + * @param devicename device name + * @return 0 on success, error code on fail + */ +int mxc_request_dma(int *channel, const char *devicename) +{ + int i, res; + + res = 0; + + down(&sdma_status_mutex); + + /* Dynamic allocation */ + if (*channel == 0) { + for (i = MAX_DMA_CHANNELS - 1; i > 0; i--) { +#ifdef CONFIG_SDMA_IRAM + /*TODO:It will be removed after DPTC used UDMA interface */ + if (i >= MXC_DMA_CHANNEL_IRAM) + continue; +#endif /*CONFIG_SDMA_IRAM */ + if (!sdma_data[i].in_use) { + *channel = i; + break; + } + } + } + + if (*channel > 0 && *channel < MAX_DMA_CHANNELS && + sdma_data[*channel].in_use == 0) { + res = iapi_Open(sdma_data[0].cd, *channel); + + if (res < 0) { + printk(KERN_ERR "Failed iapi_Open channel %d, 0x%x\n", + *channel, res); + } else { + sdma_data[*channel].in_use = 1; + strcpy(sdma_data[*channel].devicename, devicename); + sdma_data[*channel].cd = CHAD(*channel); + + iapi_IoCtl(sdma_data[*channel].cd, IAPI_CHANGE_SYNCH, + CALLBACK_ISR); + iapi_IoCtl(sdma_data[*channel].cd, + IAPI_CHANGE_CALLBACKFUNC, + (unsigned long)iapi_interrupt_callback); + iapi_IoCtl(sdma_data[*channel].cd, + IAPI_CHANGE_USER_ARG, + (unsigned long)&(sdma_data[*channel])); + } + } else { + res = -EBUSY; + } + + up(&sdma_status_mutex); + + return res; +} + +/*! + * Configures request parameters. Can be called multiple times after + * mxc_request_dma() and mxc_dma_setup_channel(). + * + * + * @param channel channel number + * @param p request parameters pointer + * @param bd_index index of buffer descriptor to set + * @return 0 on success, error code on fail + */ +int mxc_dma_set_config(int channel, dma_request_t * p, int bd_index) +{ + unsigned char param; + + if (!sdma_data[channel].in_use) { + return -EINVAL; + } + + iapi_IoCtl(sdma_data[channel].cd, + (bd_index << BD_NUM_OFFSET) | + IAPI_CHANGE_SET_TRANSFER_CD, sdma_data[channel].word_size); + + param = BD_DONE | BD_INTR | BD_EXTD; + + if (sdma_data[channel].bd_number > 1 && p->bd_cont == 1) { + param |= BD_CONT; + } + + if (bd_index == sdma_data[channel].bd_number - 1) { + param |= BD_WRAP; + } + + switch (sdma_data[channel].transfer_type) { + case emi_2_per: + case dsp_2_per: + case int_2_per: + case emi_2_dsp: + case int_2_dsp: + case emi_2_dsp_loop: + iapi_IoCtl(sdma_data[channel].cd, + (bd_index << BD_NUM_OFFSET) | + IAPI_CHANGE_SET_BUFFERADDR, + (unsigned long)p->sourceAddr); + break; + case per_2_int: + case per_2_emi: + case per_2_dsp: + case dsp_2_int: + case dsp_2_emi: + case dsp_2_dsp: + case dsp_2_emi_loop: + iapi_IoCtl(sdma_data[channel].cd, + (bd_index << BD_NUM_OFFSET) | + IAPI_CHANGE_SET_BUFFERADDR, + (unsigned long)p->destAddr); + break; + case emi_2_int: + case emi_2_emi: + case int_2_int: + case int_2_emi: + iapi_IoCtl(sdma_data[channel].cd, + (bd_index << BD_NUM_OFFSET) | + IAPI_CHANGE_SET_BUFFERADDR, + (unsigned long)p->sourceAddr); + iapi_IoCtl(sdma_data[channel].cd, + (bd_index << BD_NUM_OFFSET) | + IAPI_CHANGE_SET_EXTDBUFFERADDR, + (unsigned long)p->destAddr); + break; + default: + break; + } + + /* Change the endianness for DSP to MCU Data transfers */ + if (sdma_data[channel].transfer_type == dsp_2_emi || + sdma_data[channel].transfer_type == emi_2_dsp) { + iapi_IoCtl(sdma_data[channel].cd, IAPI_CHANGE_SET_ENDIANNESS, + SET_BIT_ALL); + } + + iapi_IoCtl(sdma_data[channel].cd, + (bd_index << BD_NUM_OFFSET) | + IAPI_CHANGE_SET_COUNT, p->count); + + iapi_IoCtl(sdma_data[channel].cd, + (bd_index << BD_NUM_OFFSET) | IAPI_CHANGE_SET_STATUS, param); + + return 0; +} + +/*! + * Configures the BD_INTR bit on a buffer descriptor parameters. + * + * + * @param channel channel number + * @param bd_index index of buffer descriptor to set + * @param bd_intr flag to set or clear the BD_INTR bit + * @return 0 on success, error code on fail + */ +void mxc_dma_set_bd_intr(int channel, int bd_index, int bd_intr) +{ + unsigned long param; + + iapi_IoCtl(sdma_data[channel].cd, + (bd_index << BD_NUM_OFFSET) | + IAPI_CHANGE_GET_STATUS, (unsigned long)¶m); + + if (bd_intr) { + param |= BD_INTR; + } else { + param &= ~BD_INTR; + } + iapi_IoCtl(sdma_data[channel].cd, + (bd_index << BD_NUM_OFFSET) | IAPI_CHANGE_SET_STATUS, param); + +} + +/*! + * Gets the BD_INTR bit on a buffer descriptor. + * + * + * @param channel channel number + * @param bd_index index of buffer descriptor to set + * + * @return returns the BD_INTR bit status + */ +int mxc_dma_get_bd_intr(int channel, int bd_index) +{ + unsigned long bd_status = 0; + + iapi_IoCtl(sdma_data[channel].cd, + (bd_index << BD_NUM_OFFSET) | + IAPI_CHANGE_GET_STATUS, (unsigned long)&bd_status); + + return (bd_status & BD_INTR); +} + +/*! + * Stop the current transfer + * + * @param channel channel number + * @param buffer_number number of buffers (beginning with 0), + * whose done bits should be reset to 0 + */ +int mxc_dma_reset(int channel, int buffer_number) +{ + unsigned char param = 0; + int i = 0; + + if (!sdma_data[channel].in_use) { + return -EINVAL; + } + + /* clear the BD_DONE bits for all the necessary buffers */ + for (i = 0; i < buffer_number; i++) { + + iapi_IoCtl(sdma_data[channel].cd, (i << BD_NUM_OFFSET) | + IAPI_CHANGE_GET_STATUS, (unsigned long)¶m); + + /* clear the BD_DONE bit of the buffer */ + param = param & (~BD_DONE); + + iapi_IoCtl(sdma_data[channel].cd, (i << BD_NUM_OFFSET) | + IAPI_CHANGE_SET_STATUS, param); + } + + return 0; +} + +/*! + * Returns request parameters. + * + * @param channel channel number + * @param p request parameters pointer + * @param bd_index index of buffer descriptor to get + * @return 0 on success, error code on fail + */ +int mxc_dma_get_config(int channel, dma_request_t * p, int bd_index) +{ + int err = 0; + unsigned long bd_status; + unsigned long bd_count; + __u8 *sourceAddr; + __u8 *destAddr; + + iapi_IoCtl(sdma_data[channel].cd, + (bd_index << BD_NUM_OFFSET) | + IAPI_CHANGE_GET_STATUS, (unsigned long)&bd_status); + iapi_IoCtl(sdma_data[channel].cd, + (bd_index << BD_NUM_OFFSET) | + IAPI_CHANGE_GET_COUNT, (unsigned long)&bd_count); + iapi_IoCtl(sdma_data[channel].cd, + (bd_index << BD_NUM_OFFSET) | + IAPI_CHANGE_GET_BUFFERADDR, (unsigned long)&sourceAddr); + + switch (sdma_data[channel].transfer_type) { + case emi_2_per: + case dsp_2_per: + case int_2_per: + case emi_2_dsp: + case int_2_dsp: + case emi_2_dsp_loop: + p->sourceAddr = sourceAddr; + break; + case per_2_int: + case per_2_emi: + case per_2_dsp: + case dsp_2_int: + case dsp_2_emi: + case dsp_2_dsp: + case dsp_2_emi_loop: + p->destAddr = sourceAddr; + break; + case emi_2_int: + case emi_2_emi: + case int_2_int: + case int_2_emi: + p->sourceAddr = sourceAddr; + iapi_IoCtl(sdma_data[channel].cd, + (bd_index << BD_NUM_OFFSET) | + IAPI_CHANGE_GET_EXTDBUFFERADDR, + (unsigned long)&destAddr); + p->destAddr = destAddr; + break; + default: + break; + } + + p->count = bd_count; + p->bd_done = bd_status & BD_DONE; + p->bd_cont = bd_status & BD_CONT; + p->bd_error = bd_status & BD_RROR; + + return err; +} + +/*! + * This function is used by MXC IPC's write_ex2. It passes the pointer to the + * data control structure to iapi_write_ipcv2() + * + * @param channel SDMA channel number + * @param ctrl_ptr Data Control structure pointer + */ +int mxc_sdma_write_ipcv2(int channel, void *ctrl_ptr) +{ + return iapi_Write_ipcv2(sdma_data[channel].cd, ctrl_ptr); +} + +/*! + * This function is used by MXC IPC's read_ex2. It passes the pointer to the + * data control structure to iapi_read_ipcv2() + * + * @param channel SDMA channel number + * @param ctrl_ptr Data Control structure pointer + */ +int mxc_sdma_read_ipcv2(int channel, void *ctrl_ptr) +{ + return iapi_Read_ipcv2(sdma_data[channel].cd, ctrl_ptr); +} + +/*! + * Starts dma channel. + * + * @param channel channel number + */ +int mxc_dma_start(int channel) +{ + if (sdma_data[channel].running == 0) { + sdma_data[channel].running = 1; + iapi_StartChannel(channel); + } + + return 0; +} + +/*! + * Stops dma channel. + * + * @param channel channel number + */ +int mxc_dma_stop(int channel) +{ + iapi_StopChannel(channel); + sdma_data[channel].running = 0; + + return 0; +} + +/*! + * Frees dma channel. + * + * @param channel channel number + */ +void mxc_free_dma(int channel) +{ + int i; + + mxc_dma_stop(channel); + + if (sdma_data[channel].event_id != 0) { + iapi_SetChannelEventMapping(sdma_data[channel].event_id, 0x0); + } + if (sdma_data[channel].event_id2 != 0) { + iapi_SetChannelEventMapping(sdma_data[channel].event_id2, 0x0); + } + + sdma_data[channel].event_id = 0; + + iapi_IoCtl(sdma_data[channel].cd, IAPI_CHANGE_PRIORITY, 0x0); + iapi_IoCtl(sdma_data[channel].cd, IAPI_CHANGE_OWNERSHIP, + (OWN_CHANNEL << CH_OWNSHP_OFFSET_EVT) | + (OWN_CHANNEL << CH_OWNSHP_OFFSET_MCU) | + (OWN_CHANNEL << CH_OWNSHP_OFFSET_DSP)); + + for (i = 0; i < sdma_data[channel].bd_number; i++) { + iapi_IoCtl(sdma_data[channel].cd, + (i << BD_NUM_OFFSET) | + IAPI_CHANGE_SET_STATUS, (unsigned long)0); + } + + iapi_Close(sdma_data[channel].cd); + + strcpy(sdma_data[channel].devicename, "not used"); + + sdma_data[channel].in_use = 0; +} + +/*! + * Initializes channel's priorities + * + */ +static void __init init_priorities(void) +{ + iapi_IoCtl(sdma_data[0].cd, IAPI_CHANGE_PRIORITY, 0x7); +} + +/*! + * Initializes events table + */ +static void __init init_event_table(void) +{ + int channel; + + for (channel = 0; channel < MAX_DMA_CHANNELS; channel++) { + iapi_SetChannelEventMapping(channel, 0); + } +} + +/*! + * Sets callback function. Used with standard dma api + * for supporting interrupts + * + * @param channel channel number + * @param callback callback function pointer + * @param arg argument for callback function + */ +void mxc_dma_set_callback(int channel, dma_callback_t callback, void *arg) +{ + sdma_data[channel].callback = callback; + sdma_data[channel].arg = arg; +} + +/*! + * Synchronization function used by I.API + * + * @param channel channel number + */ +static int getChannel(int channel) +{ + if (irqs_disabled() || in_atomic()) { + if (down_trylock(&sdma_synch_mutex[channel])) { + return -EBUSY; + } + } else { + if (down_interruptible(&sdma_synch_mutex[channel])) { + return -EBUSY; + } + } + + return 0; +} + +/*! + * Synchronization function used by I.API + * + * @param channel channel number + */ +static int releaseChannel(int channel) +{ + up(&sdma_synch_mutex[channel]); + return 0; +} + +/*! + * Unmask interrupt function. Used by I.API + * + */ +static void unmask_sdma_interrupt(void) +{ + /* Commented out tp take care of the PREEMPT_RT option + * local_irq_restore(flags); + */ +} + +/*! + * Mask interrupt function. Used by I.API + * + */ +static void mask_sdma_interrupt(void) +{ + /* Commented to take of the PREEMPT_RT option + * local_irq_save(flags); + */ +} + +/*! + * Initializes I.API + */ +static void __init init_iapi_struct(void) +{ + channelDescriptor *cd; + + printk(KERN_INFO "Using SDMA I.API\n"); + + iapi_Malloc = &sdma_malloc; +#ifdef CONFIG_SDMA_IRAM + iapi_iram_Malloc = &sdma_iram_malloc; +#endif /*CONFIG_SDMA_IRAM */ + + iapi_Free = &sdma_free; + iapi_Virt2Phys = (void *(*)(void *))&sdma_virt_to_phys; + iapi_Phys2Virt = (void *(*)(void *))&sdma_phys_to_virt; + iapi_memset = &memset; + iapi_memcpy = &memcpy; + + iapi_GotoSleep = &sdma_sleep_channel; + iapi_WakeUp = &sdma_wakeup_channel; + iapi_InitSleep = &sdma_init_sleep; + iapi_ReleaseChannel = &releaseChannel; + iapi_GetChannel = &getChannel; + + iapi_EnableInterrupts = &unmask_sdma_interrupt; + iapi_DisableInterrupts = &mask_sdma_interrupt; + + cd = kmalloc(sizeof(channelDescriptor), GFP_KERNEL); + + memset(cd, 0, sizeof(channelDescriptor)); + + sdma_data[0].cd = cd; +} + +/*! + * Initializes channel synchronization mutexes + */ +static void __init init_mutexes(void) +{ + int i; + + for (i = 0; i < MAX_DMA_CHANNELS; i++) { + init_MUTEX(&sdma_synch_mutex[i]); + } + + init_MUTEX(&sdma_status_mutex); +} + +/*! + * Channels status read proc file system function + * + * @param buf pointer to the buffer the data shuld be written to. + * @param start pointer to the pointer where the new data is + * written to. + * procedure should update the start pointer to point to + * where in the buffer the data was written. + * @param offset offset from start of the file + * @param count number of bytes to read. + * @param eof pointer to eof flag. sould be set to 1 when + * reaching eof. + * @param data driver specific data pointer. + * + * @return number byte read from the log buffer. + */ +static int proc_read_channels(char *buf, char **start, off_t offset, int count, + int *eof, void *data) +{ + char *log; + char *log_ptr; + char tmp[48]; + int i; + + log = kmalloc(4096, GFP_KERNEL); + memset(log, 0, 4096); + log_ptr = log; + + for (i = 0; i < MAX_DMA_CHANNELS; i++) { + if (sdma_data[i].in_use == 0) { + continue; + } + + memset(tmp, 0, 48); + sprintf(tmp, "Channel %d: %s\n", i, sdma_data[i].devicename); + + strcpy(log_ptr, tmp); + log_ptr += strlen(tmp); + } + + if (offset > strlen(log)) { + *eof = 1; + count = 0; + } else { + if (offset + count > strlen(log)) { + count = strlen(log) - offset; + *eof = 1; + } else { + *eof = 0; + } + + memcpy(buf, log, count); + *start = buf; + kfree(log); + } + + return count; +} + +/*! + * SDMA proc file system read function + */ +static int __init init_proc_fs(void) +{ + struct proc_dir_entry *sdma_proc_dir; + int res; + + res = 0; + + sdma_proc_dir = proc_mkdir("sdma", NULL); + create_proc_read_entry("channels", 0, sdma_proc_dir, + proc_read_channels, NULL); + + if (res < 0) { + printk(KERN_WARNING "Failed create SDMA proc entry\n"); + } + + return res; +} + +/*! + * Initializes SDMA private data + */ +static void __init init_sdma_data(void) +{ + int i; + + memset(sdma_data, 0, sizeof(sdma_struct) * MAX_DMA_CHANNELS); + sdma_data[0].in_use = 1; + strcpy(sdma_data[0].devicename, "MCU"); + + for (i = 0; i < MAX_DMA_CHANNELS; i++) { + sdma_data[i].channel = i; + } +} + +#if defined(CONFIG_MXC_SUPER_GEM) +/*! + * Initialize the Super GEM SDMA channel + * + * @return returns -1 on error, 0 on success. + */ +static int __init init_super_gem(void) +{ + channelDescriptor *cd; + script_data context; + int res = 0; + + res = iapi_Open(sdma_data[0].cd, MXC_DMA_CHANNEL_GEM); + if (res < 0) { + return -1; + } + sdma_data[MXC_DMA_CHANNEL_GEM].in_use = 1; + cd = CHAD(MXC_DMA_CHANNEL_GEM); + memset(&context, 0, sizeof(script_data)); + context.load_address = sdma_script_addrs.mxc_sdma_utra_addr; + context.wml = M3_BASE_ADDRESS; + res = iapi_AssignScript(cd, &context); + if (res < 0) { + iapi_Close(cd); + sdma_data[MXC_DMA_CHANNEL_GEM].in_use = 0; + return -1; + } + res = + iapi_IoCtl(cd, IAPI_CHANGE_OWNERSHIP, + (OWN_CHANNEL << CH_OWNSHP_OFFSET_EVT) | + (DONT_OWN_CHANNEL << CH_OWNSHP_OFFSET_MCU) | + (OWN_CHANNEL << CH_OWNSHP_OFFSET_DSP)); + if (res < 0) { + iapi_Close(cd); + sdma_data[MXC_DMA_CHANNEL_GEM].in_use = 0; + return -1; + } + /* Set EP=1, which is required to start SuperGem script the first time */ + /* This can be done only on the AP side */ + SDMA_H_EVTPEND |= 1 << MXC_DMA_CHANNEL_GEM; + + res = + iapi_SetChannelEventMapping(DMA_REQ_GEM, 1 << MXC_DMA_CHANNEL_GEM); + if (res < 0) { + iapi_Close(cd); + sdma_data[MXC_DMA_CHANNEL_GEM].in_use = 0; + return -1; + } + + return 0; +} +#endif + +/*! + * Initializes dma + */ +int __init sdma_init(void) +{ + int res = 0; + configs_data confreg_data; + + /* Initialize to the default values */ + confreg_data = iapi_ConfigDefaults; + + confreg_data.dspdma = MXC_SDMA_DSPDMA; + /* Set ACR bit */ + mxc_sdma_ahb_clk = clk_get(NULL, "sdma_ahb_clk"); + mxc_sdma_ipg_clk = clk_get(NULL, "sdma_ipg_clk"); + clk_enable(mxc_sdma_ahb_clk); + clk_enable(mxc_sdma_ipg_clk); + if (clk_get_rate(mxc_sdma_ahb_clk) / clk_get_rate(mxc_sdma_ipg_clk) < 2) { + printk(KERN_INFO "Setting SDMA ACR\n"); + confreg_data.acr = 1; + } + + init_sdma_data(); + + init_sdma_pool(); + + res = request_irq(MXC_INT_SDMA, sdma_int_handler, 0, "mxcsdma", 0); + + if (res < 0) { + goto sdma_init_fail; + } + + init_mutexes(); + + init_iapi_struct(); + + mxc_sdma_get_script_info(&sdma_script_addrs); + + res = iapi_Init(sdma_data[0].cd, &confreg_data, + sdma_script_addrs.mxc_sdma_start_addr, + sdma_script_addrs.mxc_sdma_ram_code_size * 2, + sdma_script_addrs.mxc_sdma_ram_code_start_addr); + + if (res < 0) { + free_irq(MXC_INT_SDMA, 0); + goto sdma_init_fail; + } + + init_priorities(); + + init_event_table(); + +#if defined(CONFIG_MXC_SUPER_GEM) + res = init_super_gem(); + if (res < 0) { + free_irq(MXC_INT_SDMA, 0); + goto sdma_init_fail; + } +#endif + + init_proc_fs(); + + printk(KERN_INFO "MXC DMA API initialized\n"); + + clk_disable(mxc_sdma_ahb_clk); + clk_disable(mxc_sdma_ipg_clk); + return res; + + sdma_init_fail: + printk(KERN_ERR "Error 0x%x in sdma_init\n", res); + clk_disable(mxc_sdma_ahb_clk); + clk_disable(mxc_sdma_ipg_clk); + return res; + +} + +arch_initcall(sdma_init); + +EXPORT_SYMBOL(mxc_request_dma); +EXPORT_SYMBOL(mxc_free_dma); +EXPORT_SYMBOL(mxc_dma_setup_channel); +EXPORT_SYMBOL(mxc_dma_set_channel_priority); +EXPORT_SYMBOL(mxc_dma_set_config); +EXPORT_SYMBOL(mxc_dma_get_config); +EXPORT_SYMBOL(mxc_dma_set_bd_intr); +EXPORT_SYMBOL(mxc_dma_get_bd_intr); +EXPORT_SYMBOL(mxc_dma_reset); +EXPORT_SYMBOL(mxc_sdma_write_ipcv2); +EXPORT_SYMBOL(mxc_sdma_read_ipcv2); +EXPORT_SYMBOL(mxc_dma_start); +EXPORT_SYMBOL(mxc_dma_stop); +EXPORT_SYMBOL(sdma_malloc); +EXPORT_SYMBOL(sdma_free); +EXPORT_SYMBOL(mxc_dma_set_callback); +EXPORT_SYMBOL(sdma_virt_to_phys); +EXPORT_SYMBOL(sdma_phys_to_virt); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("MXC Linux SDMA API"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/arch/arm/plat-mxc/sdma/sdma_malloc.c +++ linux-2.6.28/arch/arm/plat-mxc/sdma/sdma_malloc.c @@ -0,0 +1,388 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @file plat-mxc/sdma/sdma_malloc.c + * @brief This file contains functions for SDMA non-cacheable buffers allocation + * + * SDMA (Smart DMA) is used for transferring data between MCU and peripherals + * + * @ingroup SDMA + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define DEBUG 0 + +#if DEBUG +#define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args) +#else +#define DPRINTK(fmt, args...) +#endif + +#ifdef CONFIG_SDMA_IRAM +#define IRAM_VIRT_BASE IRAM_BASE_ADDR_VIRT +#define IRAM_PHYS_BASE IRAM_BASE_ADDR +#if (CONFIG_SDMA_IRAM_SIZE&0x3FF) +#error "IRAM size of SDMA should be multiple of 1Kbytes" +#else +#define IRAM_SDMA_SIZE CONFIG_SDMA_IRAM_SIZE /* 4K */ +#endif +#define IRAM_UNIT_SIZE 512 +#define IRAM_POOL_SIZE (IRAM_SDMA_SIZE/IRAM_UNIT_SIZE) + +#define IS_IRAM_VIRT(x) (((x)IRAM_SDMA_SIZE)?0:1) + +#define IS_IRAM_PHYS(x) (((x)IRAM_SDMA_SIZE)?0:1) +#endif /*CONFIG_SDMA_IRAM */ + +/*! + * Defines SDMA non-cacheable buffers pool + */ +static struct dma_pool *pool; + +#ifdef CONFIG_SDMA_IRAM +typedef struct iram_head_s { + struct list_head list; +} iram_head_t; + +static spinlock_t iram_pool_lock = SPIN_LOCK_UNLOCKED; +static struct list_head iram_free_list; +static unsigned char iram_pool_flag[IRAM_POOL_SIZE]; + +static void sdma_iram_free(void *buf); +#endif /*CONFIG_SDMA_IRAM */ + +/*! + * SDMA memory conversion hashing structure + */ +typedef struct { + struct list_head node; + int use_count; + /*! Virtual address */ + void *virt; + /*! Physical address */ + unsigned long phys; +} virt_phys_struct; + +static struct list_head buf_map; + +/*! + * Defines the size of each buffer in SDMA pool. + * The size must be at least 512 bytes, because + * sdma channel control blocks array size is 512 bytes + */ +#define SDMA_POOL_SIZE 1024 + +/*! + * Adds new buffer structure into conversion hash tables + * + * @param vf SDMA memory conversion hashing structure + * + * @return 1 on success, 0 on fail + */ +static int add_entry(virt_phys_struct * vf) +{ + virt_phys_struct *p; + + vf->phys &= PAGE_MASK; + vf->virt = (void *)((u32) vf->virt & PAGE_MASK); + + list_for_each_entry(p, &buf_map, node) { + if (p->virt == vf->virt) { + p->use_count++; + return 0; + } + } + + p = kmalloc(sizeof(virt_phys_struct), GFP_KERNEL); + if (p == 0) { + return -ENOMEM; + } + + *p = *vf; + p->use_count = 1; + list_add_tail(&p->node, &buf_map); + + DPRINTK("added vaddr 0x%p, paddr 0x%08X to list\n", p->virt, p->phys); + + return 0; +} + +/*! + * Deletes buffer stracture from conversion hash tables + * + * @param buf SDMA memory buffer virtual addr + * + * @return 0 on success, -1 on fail + */ +static int delete_entry(void *buf) +{ + virt_phys_struct *p; + + buf = (void *)((u32) buf & PAGE_MASK); + + list_for_each_entry(p, &buf_map, node) { + if (p->virt == buf) { + p->use_count--; + break; + } + } + + if (p->use_count == 0) { + list_del(&p->node); + kfree(p); + } + + return 0; +} + +/*! + * Virtual to physical address conversion functio + * + * @param buf pointer to virtual address + * + * @return physical address + */ +unsigned long sdma_virt_to_phys(void *buf) +{ + u32 offset = (u32) buf & (~PAGE_MASK); + virt_phys_struct *p; + + DPRINTK("searching for vaddr 0x%p\n", buf); + +#ifdef CONFIG_SDMA_IRAM + if (IS_IRAM_VIRT((unsigned long)buf)) { + if ((unsigned long)buf & (IRAM_UNIT_SIZE - 1)) { + printk(KERN_WARNING "%s buffer offset = %ld\n", + __FUNCTION__, (unsigned long)buf); + } + return (unsigned long)buf + IRAM_PHYS_BASE - IRAM_VIRT_BASE; + } +#endif /*CONFIG_SDMA_IRAM */ + + list_for_each_entry(p, &buf_map, node) { + if ((u32) p->virt == ((u32) buf & PAGE_MASK)) { + return p->phys | offset; + } + } + + if (virt_addr_valid(buf)) { + return virt_to_phys(buf); + } + + printk(KERN_WARNING + "SDMA malloc: could not translate virt address 0x%p\n", buf); + return 0; +} + +/*! + * Physical to virtual address conversion functio + * + * @param buf pointer to physical address + * + * @return virtual address + */ +void *sdma_phys_to_virt(unsigned long buf) +{ + u32 offset = buf & (~PAGE_MASK); + virt_phys_struct *p; + +#ifdef CONFIG_SDMA_IRAM + if (IS_IRAM_PHYS((unsigned long)buf)) { + if (buf & (IRAM_UNIT_SIZE - 1)) { + printk(KERN_WARNING "%s buffer offset = %ld\n", + __FUNCTION__, (unsigned long)buf); + } + return (void *)buf + IRAM_VIRT_BASE - IRAM_PHYS_BASE; + } +#endif /*CONFIG_SDMA_IRAM */ + + list_for_each_entry(p, &buf_map, node) { + if (p->phys == (buf & PAGE_MASK)) { + return (void *)((u32) p->virt | offset); + } + } + + printk(KERN_WARNING + "SDMA malloc: could not translate phys address 0x%lx\n", buf); + return 0; +} + +/*! + * Allocates uncacheable buffer + * + * @param size size of allocated buffer + * @return pointer to buffer + */ +void *sdma_malloc(size_t size) +{ + void *buf; + dma_addr_t dma_addr; + virt_phys_struct vf; + + if (size > SDMA_POOL_SIZE) { + printk(KERN_WARNING + "size in sdma_malloc is more than %d bytes\n", + SDMA_POOL_SIZE); + buf = 0; + } else { + buf = dma_pool_alloc(pool, GFP_KERNEL, &dma_addr); + if (buf > 0) { + vf.virt = buf; + vf.phys = dma_addr; + + if (add_entry(&vf) < 0) { + dma_pool_free(pool, buf, dma_addr); + buf = 0; + } + } + } + + DPRINTK("allocated vaddr 0x%p\n", buf); + return buf; +} + +/*! + * Frees uncacheable buffer + * + * @param buf buffer pointer for deletion + */ +void sdma_free(void *buf) +{ +#ifdef CONFIG_SDMA_IRAM + if (IS_IRAM_VIRT((unsigned long)buf)) { + sdma_iram_free(buf); + return; + } +#endif /*CONFIG_SDMA_IRAM */ + + dma_pool_free(pool, buf, sdma_virt_to_phys(buf)); + delete_entry(buf); +} + +#ifdef CONFIG_SDMA_IRAM +/*! + * Allocates uncacheable buffer from IRAM + */ +void *sdma_iram_malloc(size_t size) +{ + void *buf = NULL; + int index = -1; + unsigned long flags; + if (size > IRAM_UNIT_SIZE) { + printk(KERN_WARNING + "size in sdma_iram_malloc is more than %d bytes\n", + IRAM_UNIT_SIZE); + } else { + spin_lock_irqsave(&iram_pool_lock, flags); + if (!list_empty(&iram_free_list)) { + buf = + list_entry(iram_free_list.next, iram_head_t, list); + list_del(iram_free_list.next); + index = + ((unsigned long)buf - + IRAM_VIRT_BASE) / IRAM_UNIT_SIZE; + if (index < 0 || index >= IRAM_POOL_SIZE) { + spin_unlock_irqrestore(&iram_pool_lock, flags); + printk(KERN_ERR "The iram pool has crashed\n"); + return NULL; + } + if (iram_pool_flag[index]) { + spin_unlock_irqrestore(&iram_pool_lock, flags); + printk(KERN_WARNING + "iram block %d already has been allocated \n", + index); + } + iram_pool_flag[index] = 1; + } + spin_unlock_irqrestore(&iram_pool_lock, flags); + if ((unsigned long)buf & (IRAM_UNIT_SIZE - 1)) { + printk(KERN_WARNING + "the start address is not align of %d, buffer offset %ld\n", + IRAM_UNIT_SIZE, (unsigned long)buf); + + buf = PTR_ALIGN(buf, IRAM_UNIT_SIZE); + } + } + return buf; +} + +/*! + * Free uncacheable buffer into IRAM. + */ +static void sdma_iram_free(void *buf) +{ + iram_head_t *p; + int index; + unsigned long flags; + /* The check of parameter will be done in sdma_free */ + index = ((unsigned long)buf - IRAM_VIRT_BASE) / IRAM_UNIT_SIZE; + spin_lock_irqsave(&iram_pool_lock, flags); + p = (iram_head_t *) ((unsigned long)buf & (~(IRAM_UNIT_SIZE - 1))); + list_add_tail(&(p->list), &iram_free_list); + if (iram_pool_flag[index]) { + iram_pool_flag[index] = 0; + spin_unlock_irqrestore(&iram_pool_lock, flags); + } else { + printk(KERN_WARNING + "Free %p which IRAM block %d is already freed\n", buf, + index); + spin_unlock_irqrestore(&iram_pool_lock, flags); + } +} + +/*! + * Initialized the free list of IRAM. + */ +static void iram_pool_init(void) +{ + int i; + iram_head_t *p; + memset(iram_pool_flag, 0, IRAM_POOL_SIZE); + INIT_LIST_HEAD(&iram_free_list); + for (i = 0; i < IRAM_POOL_SIZE; i++) { + p = (iram_head_t *) (IRAM_VIRT_BASE + i * IRAM_UNIT_SIZE); + list_add_tail(&(p->list), &iram_free_list); + } +} +#endif /*CONFIG_SDMA_IRAM */ + +/*! + * SDMA buffers pool initialization function + */ +void __init init_sdma_pool(void) +{ +#ifdef CONFIG_SDMA_IRAM + iram_pool_init(); +#endif /*CONFIG_SDMA_IRAM */ + + pool = dma_pool_create("SDMA", NULL, SDMA_POOL_SIZE, 0, 0); + + INIT_LIST_HEAD(&buf_map); +} + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("MXC Linux SDMA API"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/arch/arm/plat-mxc/sdma/dma_sdma.c +++ linux-2.6.28/arch/arm/plat-mxc/sdma/dma_sdma.c @@ -0,0 +1,684 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @file plat-mxc/sdma/dma_sdma.c + * @brief Front-end to the DMA handling. This handles the allocation/freeing + * of DMA channels, and provides a unified interface to the machines + * DMA facilities. This file contains functions for Smart DMA. + * + * @ingroup SDMA + */ + +#include +#include +#include +#include +#include + +#ifdef CONFIG_MXC_SDMA_API + +static mxc_dma_channel_t mxc_sdma_channels[MAX_DMA_CHANNELS]; +static mxc_dma_channel_private_t mxc_sdma_private[MAX_DMA_CHANNELS]; + +extern struct clk *mxc_sdma_ahb_clk, *mxc_sdma_ipg_clk; + +/*! + * Tasket to handle processing the channel buffers + * + * @param arg channel id + */ +static void mxc_sdma_channeltasklet(unsigned long arg) +{ + dma_request_t request_t; + dma_channel_params chnl_param; + mxc_dma_channel_t *chnl_info; + mxc_dma_channel_private_t *data_priv; + int bd_intr = 0, error = MXC_DMA_DONE; + + chnl_info = &mxc_sdma_channels[arg]; + data_priv = chnl_info->private; + chnl_param = + mxc_sdma_get_channel_params(chnl_info->channel)->chnl_params; + + mxc_dma_get_config(arg, &request_t, data_priv->buf_tail); + + while (request_t.bd_done == 0) { + bd_intr = mxc_dma_get_bd_intr(arg, data_priv->buf_tail); + if ((data_priv->buf_tail += 1) >= chnl_param.bd_number) { + data_priv->buf_tail = 0; + } + chnl_info->active = 0; + if (request_t.bd_error) { + error = MXC_DMA_TRANSFER_ERROR; + } + + if (bd_intr != 0) { + chnl_info->cb_fn(chnl_info->cb_args, error, + request_t.count); + error = MXC_DMA_DONE; + } + + if (data_priv->buf_tail == chnl_info->curr_buf) { + break; + } + memset(&request_t, 0, sizeof(dma_request_t)); + mxc_dma_get_config(arg, &request_t, data_priv->buf_tail); + } +} + +/*! + * This function is generally called by the driver at open time. + * The DMA driver would do any initialization steps that is required + * to get the channel ready for data transfer. + * + * @param channel_id a pre-defined id. The peripheral driver would specify + * the id associated with its peripheral. This would be + * used by the DMA driver to identify the peripheral + * requesting DMA and do the necessary setup on the + * channel associated with the particular peripheral. + * The DMA driver could use static or dynamic DMA channel + * allocation. + * @param dev_name module name or device name + * @return returns a negative number on error if request for a DMA channel did not + * succeed, returns the channel number to be used on success. + */ +int mxc_dma_request(mxc_dma_device_t channel_id, char *dev_name) +{ + mxc_sdma_channel_params_t *chnl; + mxc_dma_channel_private_t *data_priv; + int ret = 0, i = 0, channel_num = 0; + + chnl = mxc_sdma_get_channel_params(channel_id); + if (chnl == NULL) { + return -EINVAL; + } + + /* Enable the SDMA clock */ + clk_enable(mxc_sdma_ahb_clk); + clk_enable(mxc_sdma_ipg_clk); + + channel_num = chnl->channel_num; + if (chnl->channel_num == MXC_DMA_DYNAMIC_CHANNEL) { + /* Get the first free channel */ + for (i = (MAX_DMA_CHANNELS - 1); i > 0; i--) { + /* See if channel is available */ + if ((mxc_sdma_channels[i].dynamic != 1) + || (mxc_sdma_channels[i].lock != 0)) { + continue; + } + channel_num = i; + /* Check to see if we can get this channel */ + ret = mxc_request_dma(&channel_num, dev_name); + if (ret == 0) { + break; + } else { + continue; + } + } + if (ret != 0) { + /* No free channel */ + goto err_ret; + } + } else { + if (mxc_sdma_channels[chnl->channel_num].lock == 1) { + ret = -ENODEV; + goto err_ret; + } + ret = mxc_request_dma(&channel_num, dev_name); + if (ret != 0) { + goto err_ret; + } + } + + ret = mxc_dma_setup_channel(channel_num, &chnl->chnl_params); + + if (ret == 0) { + if (chnl->chnl_priority != MXC_SDMA_DEFAULT_PRIORITY) { + ret = + mxc_dma_set_channel_priority(channel_num, + chnl->chnl_priority); + if (ret != 0) { + pr_info("Failed to set channel prority,\ + continue with the existing \ + priority\n"); + goto err_ret; + } + } + mxc_sdma_channels[channel_num].lock = 1; + if ((chnl->chnl_params.transfer_type == per_2_emi) + || (chnl->chnl_params.transfer_type == dsp_2_emi)) { + mxc_sdma_channels[channel_num].mode = MXC_DMA_MODE_READ; + } else { + mxc_sdma_channels[channel_num].mode = + MXC_DMA_MODE_WRITE; + } + mxc_sdma_channels[channel_num].channel = channel_id; + data_priv = mxc_sdma_channels[channel_num].private; + tasklet_init(&data_priv->chnl_tasklet, + mxc_sdma_channeltasklet, channel_num); + if ((channel_id == MXC_DMA_ATA_RX) + || (channel_id == MXC_DMA_ATA_TX)) { + data_priv->intr_after_every_bd = 0; + } else { + data_priv->intr_after_every_bd = 1; + } + } + err_ret: + if (ret != 0) { + clk_disable(mxc_sdma_ahb_clk); + clk_disable(mxc_sdma_ipg_clk); + channel_num = -ENODEV; + } + + return channel_num; +} + +/*! + * This function is generally called by the driver at close time. The DMA + * driver would do any cleanup associated with this channel. + * + * @param channel_num the channel number returned at request time. This + * would be used by the DMA driver to identify the calling + * driver and do the necessary cleanup on the channel + * associated with the particular peripheral + * @return returns a negative number on error or 0 on success + */ +int mxc_dma_free(int channel_num) +{ + mxc_dma_channel_private_t *data_priv; + + if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) { + return -EINVAL; + } + + if (mxc_sdma_channels[channel_num].lock != 1) { + return -ENODEV; + } + + mxc_free_dma(channel_num); + + /* Disable the SDMA clock */ + clk_disable(mxc_sdma_ahb_clk); + clk_disable(mxc_sdma_ipg_clk); + + mxc_sdma_channels[channel_num].lock = 0; + mxc_sdma_channels[channel_num].active = 0; + mxc_sdma_channels[channel_num].curr_buf = 0; + data_priv = mxc_sdma_channels[channel_num].private; + data_priv->buf_tail = 0; + tasklet_kill(&data_priv->chnl_tasklet); + + return 0; +} + +/*! + * Callback function called from the SDMA Interrupt routine + * + * @param arg driver specific argument that was registered + */ +static void mxc_dma_chnl_callback(void *arg) +{ + int priv; + mxc_dma_channel_private_t *data_priv; + + priv = (int)arg; + data_priv = mxc_sdma_channels[priv].private; + /* Process the buffers in a tasklet */ + tasklet_schedule(&data_priv->chnl_tasklet); +} + +/*! + * This function would just configure the buffers specified by the user into + * dma channel. The caller must call mxc_dma_enable to start this transfer. + * + * @param channel_num the channel number returned at request time. This + * would be used by the DMA driver to identify the calling + * driver and do the necessary cleanup on the channel + * associated with the particular peripheral + * @param dma_buf an array of physical addresses to the user defined + * buffers. The caller must guarantee the dma_buf is + * available until the transfer is completed. + * @param num_buf number of buffers in the array + * @param mode specifies whether this is READ or WRITE operation + * @return This function returns a negative number on error if buffer could not be + * added with DMA for transfer. On Success, it returns 0 + */ +int mxc_dma_config(int channel_num, mxc_dma_requestbuf_t * dma_buf, + int num_buf, mxc_dma_mode_t mode) +{ + int ret = 0, i = 0, prev_buf; + mxc_dma_channel_t *chnl_info; + mxc_dma_channel_private_t *data_priv; + mxc_sdma_channel_params_t *chnl; + dma_channel_params chnl_param; + dma_request_t request_t; + + if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) { + return -EINVAL; + } + + if (num_buf <= 0) { + return -EINVAL; + } + + chnl_info = &mxc_sdma_channels[channel_num]; + data_priv = chnl_info->private; + if (chnl_info->lock != 1) { + return -ENODEV; + } + + /* Check to see if all buffers are taken */ + if (chnl_info->active == 1) { + return -EBUSY; + } + + chnl = mxc_sdma_get_channel_params(chnl_info->channel); + chnl_param = chnl->chnl_params; + + /* Re-setup the SDMA channel if the transfer direction is changed */ + if ((chnl_param.peripheral_type != MEMORY) && (mode != chnl_info->mode)) { + if (chnl_param.peripheral_type == DSP) { + if (mode == MXC_DMA_MODE_READ) { + chnl_param.transfer_type = dsp_2_emi; + } else { + chnl_param.transfer_type = emi_2_dsp; + } + } else if (chnl_param.peripheral_type == FIFO_MEMORY) { + if (mode == MXC_DMA_MODE_READ) + chnl_param.per_address = MXC_FIFO_MEM_SRC_FIXED; + else + chnl_param.per_address = + MXC_FIFO_MEM_DEST_FIXED; + } else { + if (mode == MXC_DMA_MODE_READ) { + chnl_param.transfer_type = per_2_emi; + } else { + chnl_param.transfer_type = emi_2_per; + } + } + chnl_param.callback = mxc_dma_chnl_callback; + chnl_param.arg = (void *)channel_num; + ret = mxc_dma_setup_channel(channel_num, &chnl_param); + if (ret != 0) { + return ret; + } + if (chnl->chnl_priority != MXC_SDMA_DEFAULT_PRIORITY) { + ret = + mxc_dma_set_channel_priority(channel_num, + chnl->chnl_priority); + if (ret != 0) { + pr_info("Failed to set channel prority,\ + continue with the existing \ + priority\n"); + } + } + chnl_info->mode = mode; + } + + for (i = 0; i < num_buf; i++, dma_buf++) { + /* Check to see if all buffers are taken */ + if (chnl_info->active == 1) { + break; + } + request_t.destAddr = (__u8 *) dma_buf->dst_addr; + request_t.sourceAddr = (__u8 *) dma_buf->src_addr; + request_t.count = dma_buf->num_of_bytes; + request_t.bd_cont = 1; + ret = mxc_dma_set_config(channel_num, &request_t, + chnl_info->curr_buf); + if (ret != 0) { + break; + } + if (data_priv->intr_after_every_bd == 0) { + if (i == num_buf - 1) { + mxc_dma_set_bd_intr(channel_num, + chnl_info->curr_buf, 1); + } else { + mxc_dma_set_bd_intr(channel_num, + chnl_info->curr_buf, 0); + } + } + + prev_buf = chnl_info->curr_buf; + if ((chnl_info->curr_buf += 1) >= chnl_param.bd_number) { + chnl_info->curr_buf = 0; + } + if (chnl_info->curr_buf == data_priv->buf_tail) { + if ((data_priv->intr_after_every_bd == 0) + && (i != num_buf - 1)) { + /* + * Set the BD_INTR flag on the last BD that + * was queued + */ + mxc_dma_set_bd_intr(channel_num, prev_buf, 1); + } + chnl_info->active = 1; + } + } + + if (i == 0) { + return -EBUSY; + } + return 0; +} + +/*! + * This function would just configure the scatterlist specified by the + * user into dma channel. This is a slight variation of mxc_dma_config(), + * it is provided for the convenience of drivers that have a scatterlist + * passed into them. It is the calling driver's responsibility to have the + * correct physical address filled in the "dma_address" field of the + * scatterlist. + * + * @param channel_num the channel number returned at request time. This + * would be used by the DMA driver to identify the calling + * driver and do the necessary cleanup on the channel + * associated with the particular peripheral + * @param sg a scatterlist of buffers. The caller must guarantee + * the dma_buf is available until the transfer is + * completed. + * @param num_buf number of buffers in the array + * @param num_of_bytes total number of bytes to transfer. If set to 0, this + * would imply to use the length field of the scatterlist + * for each DMA transfer. Else it would calculate the size + * for each DMA transfer. + * @param mode specifies whether this is READ or WRITE operation + * @return This function returns a negative number on error if buffer could not + * be added with DMA for transfer. On Success, it returns 0 + */ +int mxc_dma_sg_config(int channel_num, struct scatterlist *sg, + int num_buf, int num_of_bytes, mxc_dma_mode_t mode) +{ + int ret = 0, i = 0; + mxc_dma_requestbuf_t *dma_buf; + + if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) { + return -EINVAL; + } + + if (mxc_sdma_channels[channel_num].lock != 1) { + return -ENODEV; + } + + dma_buf = + (mxc_dma_requestbuf_t *) kmalloc(num_buf * + sizeof(mxc_dma_requestbuf_t), + GFP_KERNEL); + + if (dma_buf == NULL) { + return -EFAULT; + } + + for (i = 0; i < num_buf; i++) { + if (mode == MXC_DMA_MODE_READ) { + (dma_buf + i)->dst_addr = sg->dma_address; + } else { + (dma_buf + i)->src_addr = sg->dma_address; + } + + if ((num_of_bytes > sg->length) || (num_of_bytes == 0)) { + (dma_buf + i)->num_of_bytes = sg->length; + } else { + (dma_buf + i)->num_of_bytes = num_of_bytes; + } + sg++; + num_of_bytes -= (dma_buf + i)->num_of_bytes; + } + + ret = mxc_dma_config(channel_num, dma_buf, num_buf, mode); + kfree(dma_buf); + return ret; +} + +/*! + * This function is provided if the driver would like to set/change its + * callback function. + * + * @param channel_num the channel number returned at request time. This + * would be used by the DMA driver to identify the calling + * driver and do the necessary cleanup on the channel + * associated with the particular peripheral + * @param callback a callback function to provide notification on transfer + * completion, user could specify NULL if he does not wish + * to be notified + * @param arg an argument that gets passed in to the callback + * function, used by the user to do any driver specific + * operations. + * @return this function returns a negative number on error if the callback + * could not be set for the channel or 0 on success + */ +int mxc_dma_callback_set(int channel_num, + mxc_dma_callback_t callback, void *arg) +{ + if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) { + return -EINVAL; + } + + if (mxc_sdma_channels[channel_num].lock != 1) { + return -ENODEV; + } + + mxc_sdma_channels[channel_num].cb_fn = callback; + mxc_sdma_channels[channel_num].cb_args = arg; + + mxc_dma_set_callback(channel_num, mxc_dma_chnl_callback, + (void *)channel_num); + + return 0; +} + +/*! + * This stops the DMA channel and any ongoing transfers. Subsequent use of + * mxc_dma_enable() will restart the channel and restart the transfer. + * + * @param channel_num the channel number returned at request time. This + * would be used by the DMA driver to identify the calling + * driver and do the necessary cleanup on the channel + * associated with the particular peripheral + * @return returns a negative number on error or 0 on success + */ +int mxc_dma_disable(int channel_num) +{ + if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) { + return -EINVAL; + } + + if (mxc_sdma_channels[channel_num].lock != 1) { + return -ENODEV; + } + + mxc_dma_stop(channel_num); + return 0; +} + +/*! + * This starts DMA transfer. Or it restarts DMA on a stopped channel + * previously stopped with mxc_dma_disable(). + * + * @param channel_num the channel number returned at request time. This + * would be used by the DMA driver to identify the calling + * driver and do the necessary cleanup on the channel + * associated with the particular peripheral + * @return returns a negative number on error or 0 on success + */ +int mxc_dma_enable(int channel_num) +{ + if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) { + return -EINVAL; + } + + if (mxc_sdma_channels[channel_num].lock != 1) { + return -ENODEV; + } + + mxc_dma_start(channel_num); + return 0; +} + +/*! + * Initializes dma structure with dma_operations + * + * @param dma dma structure + * @return returns 0 on success + */ +static int __init mxc_dma_init(void) +{ + int i; + for (i = 0; i < MAX_DMA_CHANNELS; i++) { + mxc_sdma_channels[i].active = 0; + mxc_sdma_channels[i].lock = 0; + mxc_sdma_channels[i].curr_buf = 0; + mxc_sdma_channels[i].dynamic = 1; + mxc_sdma_private[i].buf_tail = 0; + mxc_sdma_channels[i].private = &mxc_sdma_private[i]; + } + /* + * Make statically allocated channels unavailable for dynamic channel + * requests + */ + mxc_get_static_channels(mxc_sdma_channels); + + return 0; +} + +arch_initcall(mxc_dma_init); + +#else +int mxc_request_dma(int *channel, const char *devicename) +{ + return -ENODEV; +} + +int mxc_dma_setup_channel(int channel, dma_channel_params * p) +{ + return -ENODEV; +} + +int mxc_dma_set_channel_priority(unsigned int channel, unsigned int priority) +{ + return -ENODEV; +} + +int mxc_dma_set_config(int channel, dma_request_t * p, int bd_index) +{ + return -ENODEV; +} + +int mxc_dma_get_config(int channel, dma_request_t * p, int bd_index) +{ + return -ENODEV; +} + +int mxc_dma_start(int channel) +{ + return -ENODEV; +} + +int mxc_dma_stop(int channel) +{ + return -ENODEV; +} + +void mxc_free_dma(int channel) +{ +} + +void mxc_dma_set_callback(int channel, dma_callback_t callback, void *arg) +{ +} + +void *sdma_malloc(size_t size) +{ + return 0; +} + +void sdma_free(void *buf) +{ +} + +void *sdma_phys_to_virt(unsigned long buf) +{ + return 0; +} + +unsigned long sdma_virt_to_phys(void *buf) +{ + return 0; +} + +int mxc_dma_request(mxc_dma_device_t channel_id, char *dev_name) +{ + return -ENODEV; +} + +int mxc_dma_free(int channel_num) +{ + return -ENODEV; +} + +int mxc_dma_config(int channel_num, mxc_dma_requestbuf_t * dma_buf, + int num_buf, mxc_dma_mode_t mode) +{ + return -ENODEV; +} + +int mxc_dma_sg_config(int channel_num, struct scatterlist *sg, + int num_buf, int num_of_bytes, mxc_dma_mode_t mode) +{ + return -ENODEV; +} + +int mxc_dma_callback_set(int channel_num, mxc_dma_callback_t callback, + void *arg) +{ + return -ENODEV; +} + +int mxc_dma_disable(int channel_num) +{ + return -ENODEV; +} + +int mxc_dma_enable(int channel_num) +{ + return -ENODEV; +} + +EXPORT_SYMBOL(mxc_request_dma); +EXPORT_SYMBOL(mxc_dma_setup_channel); +EXPORT_SYMBOL(mxc_dma_set_channel_priority); +EXPORT_SYMBOL(mxc_dma_set_config); +EXPORT_SYMBOL(mxc_dma_get_config); +EXPORT_SYMBOL(mxc_dma_start); +EXPORT_SYMBOL(mxc_dma_stop); +EXPORT_SYMBOL(mxc_free_dma); +EXPORT_SYMBOL(mxc_dma_set_callback); +EXPORT_SYMBOL(sdma_malloc); +EXPORT_SYMBOL(sdma_free); +EXPORT_SYMBOL(sdma_phys_to_virt); +EXPORT_SYMBOL(sdma_virt_to_phys); + +#endif + +EXPORT_SYMBOL(mxc_dma_request); +EXPORT_SYMBOL(mxc_dma_free); +EXPORT_SYMBOL(mxc_dma_config); +EXPORT_SYMBOL(mxc_dma_sg_config); +EXPORT_SYMBOL(mxc_dma_callback_set); +EXPORT_SYMBOL(mxc_dma_disable); +EXPORT_SYMBOL(mxc_dma_enable); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("MXC Linux SDMA API"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/arch/arm/plat-mxc/sdma/iapi/Makefile +++ linux-2.6.28/arch/arm/plat-mxc/sdma/iapi/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for I.API sources. +# + +obj-y := src/ \ No newline at end of file --- linux-2.6.28.orig/arch/arm/plat-mxc/sdma/iapi/include/iapiOS.h +++ linux-2.6.28/arch/arm/plat-mxc/sdma/iapi/include/iapiOS.h @@ -0,0 +1,96 @@ +/****************************************************************************** + * + * Copyright 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 + * + ****************************************************************************** + * + * File: iapiOS.h + * + * $Id iapiOS.h $ + * + * Description: + * prototypes for OS level function of I.API + * + * + * + * + * $Log iapiOS.h + * + * ***************************************************************************/ + +#ifndef _iapiOS_h +#define _iapiOS_h + +/* **************************************************************************** + * Boolean identifiers + *****************************************************************************/ +#define NO_OS 0 +#define LINUX 1 +#define SYMBIAN 2 +#define WINCE 3 + +/* **************************************************************************** + * Include File Section + *****************************************************************************/ +#include "sdmaStruct.h" +#include "iapiDefaults.h" +#ifdef MCU +#include "iapiLowMcu.h" +#endif /*MCU*/ +#if OS == NO_OS +#include +#elif OS == LINUX +#include +#endif + +/* **************************************************************************** + * Macro-command Section + *****************************************************************************/ +#define SDMA_ERAM 0 +#define SDMA_IRAM 1 +#ifdef CONFIG_SDMA_IRAM +#define MALLOC(x, s) (s == SDMA_ERAM)? (* iapi_Malloc)(x):(* iapi_iram_Malloc)(x) +#else /*CONFIG_SDMA_IRAM */ +#define MALLOC(x, s) (* iapi_Malloc)(x) +#endif /*CONFIG_SDMA_IRAM */ +#define FREE(x) if (x!=NULL) (* iapi_Free)(x) + +#define GOTO_SLEEP(x) (iapi_GotoSleep)(x) +#define INIT_SLEEP(x) (iapi_InitSleep)(x) + +/* **************************************************************************** + * Public Function Prototype Section + *****************************************************************************/ + +#ifdef CONFIG_SDMA_IRAM +extern void*(* iapi_iram_Malloc) (size_t size); +#endif /*CONFIG_SDMA_IRAM*/ + +extern void*(* iapi_Malloc) (size_t size); +extern void (* iapi_Free) (void * ptr); + +extern void*(* iapi_Virt2Phys) (void * ptr); +extern void*(* iapi_Phys2Virt) (void * ptr); + +extern void (* iapi_WakeUp)(int); +extern void (* iapi_GotoSleep)(int); +extern void (* iapi_InitSleep)(int); + +extern void*(* iapi_memcpy)(void *dest, const void *src, size_t count); +extern void*(* iapi_memset)(void *dest, int c, size_t count); + +extern void (* iapi_EnableInterrupts)(void); +extern void (* iapi_DisableInterrupts)(void); + +extern int (* iapi_GetChannel)(int); +extern int (* iapi_ReleaseChannel)(int); + +#endif /* _iapiOS_h */ --- linux-2.6.28.orig/arch/arm/plat-mxc/sdma/iapi/include/iapiHigh.h +++ linux-2.6.28/arch/arm/plat-mxc/sdma/iapi/include/iapiHigh.h @@ -0,0 +1,136 @@ +/****************************************************************************** + * + * Copyright 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 + * + ****************************************************************************** + * + * File: iapiHigh.h + * + * $Id iapiHigh.h $ + * + * Description: + * prototypes for high level function of I.API + * + * + * http://venerque.sps.mot.com/pjt/sfs/www/iapi/softsim_api.pdf + * + * $Log iapiHigh.h + * + * ***************************************************************************/ + +#ifndef _iapiHigh_h +#define _iapiHigh_h + +/* **************************************************************************** + * Include File Section + *****************************************************************************/ +#include "sdmaStruct.h" + +/* **************************************************************************** + * Macro-command Section + *****************************************************************************/ +enum { + IAPI_CHANGE_CHANDESC, + IAPI_CHANGE_BDNUM, + IAPI_CHANGE_BUFFSIZE, + IAPI_CHANGE_CHANBLOCK, + IAPI_CHANGE_INSTANCE, + IAPI_CHANGE_OWNERSHIP, + IAPI_CHANGE_SYNCH, + IAPI_CHANGE_TRUST, + IAPI_CHANGE_CALLBACKFUNC, + IAPI_CHANGE_CHANCCB, + IAPI_CHANGE_PRIORITY, + IAPI_CHANGE_BDWRAP, + IAPI_CHANGE_WATERMARK, + IAPI_CHANGE_SET_BDCONT, + IAPI_CHANGE_UNSET_BDCONT, + IAPI_CHANGE_SET_BDEXTD, + IAPI_CHANGE_UNSET_BDEXTD, + IAPI_CHANGE_EVTMASK1, + IAPI_CHANGE_EVTMASK2, + IAPI_CHANGE_PERIPHADDR, + IAPI_CHANGE_SET_BDINTR, + IAPI_CHANGE_UNSET_BDINTR, + IAPI_CHANGE_SET_TRANSFER_CD, + IAPI_CHANGE_FORCE_CLOSE, + IAPI_CHANGE_SET_TRANSFER, + IAPI_CHANGE_USER_ARG, + IAPI_CHANGE_SET_BUFFERADDR, + IAPI_CHANGE_SET_EXTDBUFFERADDR, + IAPI_CHANGE_SET_COMMAND, + IAPI_CHANGE_SET_COUNT, + IAPI_CHANGE_SET_STATUS, + IAPI_CHANGE_GET_BUFFERADDR, + IAPI_CHANGE_GET_EXTDBUFFERADDR, + IAPI_CHANGE_GET_COMMAND, + IAPI_CHANGE_GET_COUNT, + IAPI_CHANGE_GET_STATUS, + IAPI_CHANGE_SET_ENDIANNESS +}; + + +/* + * Public Function Prototype Section + */ +int iapi_Open ( channelDescriptor * cd_p, unsigned char channelNumber ); +int iapi_Close( channelDescriptor * cd_p ); +int iapi_Read ( channelDescriptor * cd_p, void * buf, unsigned short nbyte ); +int iapi_Write( channelDescriptor * cd_p, void * buf, unsigned short nbyte ); +int iapi_MemCopy(channelDescriptor * cd_p, void* dest, void* src, + unsigned long size); +int iapi_IoCtl( channelDescriptor * cd_p, unsigned long ctlRequest, + unsigned long param); + + +int iapi_Read_ipcv2( channelDescriptor * cd_p, void * data_control_struct_ipcv2); + +int iapi_Write_ipcv2( channelDescriptor * cd_p, void * data_control_struct_ipcv2); + +#ifdef MCU +int iapi_Init(channelDescriptor * cd_p, configs_data * config_p, + unsigned short* ram_image, unsigned short code_size, + unsigned long start_addr); +#endif /* MCU */ +#ifdef DSP +int iapi_Init(channelDescriptor * cd_p); +#endif /* DSP */ + +int iapi_StartChannel(unsigned char channel); +int iapi_StopChannel(unsigned char channel); +int iapi_SynchChannel(unsigned char channel); + +int iapi_GetChannelNumber(channelDescriptor * cd_p); +unsigned long iapi_GetError(channelDescriptor * cd_p); +int iapi_GetCount(channelDescriptor * cd_p); +int iapi_GetCountAll(channelDescriptor * cd_p); + +#ifndef IRQ_KEYWORD +#define IRQ_KEYWORD +#endif /* IRQ_KEYWORD */ + +IRQ_KEYWORD void IRQ_Handler(void); + +#ifdef MCU +int iapi_GetScript(channelDescriptor * cd_p, void * buf, unsigned short size, + unsigned long address); +int iapi_GetContext(channelDescriptor * cd_p, void * buf, + unsigned char channel); +int iapi_SetScript(channelDescriptor * cd_p, void * buf, unsigned short nbyte, + unsigned long destAddr); +int iapi_SetContext(channelDescriptor * cd_p, void * buf, + unsigned char channel); +int iapi_AssignScript(channelDescriptor * cd_p, script_data * data_p); + +int iapi_SetChannelEventMapping(unsigned char event, unsigned long channel_map); +#endif /* MCU */ + +#endif /* _iapiHigh_h */ --- linux-2.6.28.orig/arch/arm/plat-mxc/sdma/iapi/include/iapiDefaults.h +++ linux-2.6.28/arch/arm/plat-mxc/sdma/iapi/include/iapiDefaults.h @@ -0,0 +1,128 @@ +/****************************************************************************** + * + * Copyright 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 + * + ****************************************************************************** + * + * File: iapiDefaults.h + * + * $Id iapiDefaults.h $ + * + * Description: + * This library is written in C to guarantee functionality and integrity in + * the usage of SDMA virtual DMA channels. This API (Application Programming + * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE + * fashion. + * + * + * + * + * $Log iapiDefaults.h $ + * + *****************************************************************************/ + + +#ifndef _iapi_defaults_h +#define _iapi_defaults_h + +/****************************************************************************** + * Include File Section + *****************************************************************************/ +#include "epm.h" +#include "sdmaStruct.h" + +/* **************************************************************************** + * Macro-command Section + * ***************************************************************************/ + +/** + * Error codes + * lower 5 bits free to include channel number when available + * and bit number 6 must be set when channel number is available + * + * Note : + * 1) Abbreviations / naming convention : + * - BD : Buffer Descriptor + * - CC : Channel Context + * - CCB : Channel Control Block + * - CD : Channel Descriptor + * - B : Buffer + * - CH : Channel + * + */ +#define IAPI_SUCCESS 0 +#define IAPI_FAILURE -1 +#define IAPI_ERR_CH_AVAILABLE 0x00020 +#define IAPI_ERR_NO_ERROR 0x00000 +#define IAPI_ERR_NO_CCB_DEFINED 0x01000 +#define IAPI_ERR_BD_UNINITIALIZED 0x02000 +#define IAPI_ERR_BD_ALLOCATED 0x03000 +#define IAPI_ERR_BD_ALLOCATION 0x04000 +#define IAPI_ERR_CCB_ALLOC_FAILED 0x05000 +#define IAPI_ERR_CCB_UNINITIALIZED 0x06000 +#define IAPI_ERR_CC_ALREADY_DEFINED 0x07000 +#define IAPI_ERR_CC_ALLOC_FAILED 0x08000 +#define IAPI_ERR_CD_ALREADY_DEFINED 0x09000 +#define IAPI_ERR_CD_ALLOC_FAILED 0x0A000 +#define IAPI_ERR_CD_CHANGE_CH_NUMBER 0x0B000 +#define IAPI_ERR_CD_CHANGE_CCB_PTR 0x0C000 +#define IAPI_ERR_CD_CHANGE_UNKNOWN 0x0D000 +#define IAPI_ERR_CD_CHANGE 0x0E000 +#define IAPI_ERR_CD_UNINITIALIZED 0x0F000 +#define IAPI_ERR_CLOSE 0x10000 +#define IAPI_ERR_B_ALLOC_FAILED 0x11000 +#define IAPI_ERR_CONFIG_OVERRIDE 0x12000 +#define IAPI_ERR_CH_IN_USE 0x13000 +#define IAPI_ERR_CALLBACKSYNCH_UNKNOWN 0x14000 +#define IAPI_ERR_INVALID_PARAMETER 0x15000 +#define IAPI_ERR_TRUST 0x16000 +#define IAPI_ERR_CHANNEL_UNINITIALIZED 0x17000 +#define IAPI_ERR_RROR_BIT_READ 0x18000 +#define IAPI_ERR_RROR_BIT_WRITE 0x19000 +#define IAPI_ERR_NOT_ALLOWED 0x1A000 +#define IAPI_ERR_NO_OS_FN 0x1B000 + + +/* + * Global Variable Section + */ + +/* + * Table to hold pointers to the callback functions registered by the users of + *I.API + */ +extern void (* callbackIsrTable[CH_NUM])(channelDescriptor * cd_p, void * arg); + +/* + * Table to hold user registered data pointers, to be privided in the callback + *function + */ +extern void * userArgTable[CH_NUM]; + +/* channelDescriptor data structure filled with default data*/ +extern channelDescriptor iapi_ChannelDefaults; + +/* Global variable to hold the last error encountered in I.API operations*/ +extern unsigned int iapi_errno; + +/* Used in synchronization, to mark started channels*/ +extern volatile unsigned long iapi_SDMAIntr; + +/* Hold a pointer to the start of the CCB array, to be used in the IRQ routine + *to find the channel descriptor for the channed sending the interrupt to the + *core. + */ +extern channelControlBlock * iapi_CCBHead; + +/* configs_data structure filled with default data*/ +extern configs_data iapi_ConfigDefaults; + +#endif /* iapiDefaults_h */ --- linux-2.6.28.orig/arch/arm/plat-mxc/sdma/iapi/include/iapi.h +++ linux-2.6.28/arch/arm/plat-mxc/sdma/iapi/include/iapi.h @@ -0,0 +1,49 @@ +/****************************************************************************** + * + * Copyright 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 + * + ****************************************************************************** + * + * File: iapi.h + * + * $Id iapi.h $ + * + * Description: + * Unique include for the whole IAPI library. + * + * + * http//compass.mot.com/go/115342679 + * + * $Log iapi.h $ + * + * ***************************************************************************/ + +#ifndef _iapi_h +#define _iapi_h + +/* **************************************************************************** + * Include File Section + * ***************************************************************************/ + +#include "sdmaStruct.h" +#include "iapiDefaults.h" +#include "iapiLow.h" +#include "iapiMiddle.h" +#include "iapiHigh.h" + +#ifdef MCU +#include "iapiLowMcu.h" +#include "iapiMiddleMcu.h" +#endif /* MCU */ + + + +#endif /* _iapi_h */ --- linux-2.6.28.orig/arch/arm/plat-mxc/sdma/iapi/include/sdmaStruct.h +++ linux-2.6.28/arch/arm/plat-mxc/sdma/iapi/include/sdmaStruct.h @@ -0,0 +1,425 @@ +/****************************************************************************** + * + * Copyright 2007-2008 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 + * + ****************************************************************************** + * + * File: sdmaStruct.h + * + * $Id sdmaStruct.h $ + * + * Description: provides necessary definitions and inclusion for ipcmStruct.c + * + * $Log $ + * + *****************************************************************************/ +#ifndef _sdmaStruct_h +#define _sdmaStruct_h + +/* **************************************************************************** + * Include File Section + ******************************************************************************/ + +/* **************************************************************************** + * Macro-command Section + ******************************************************************************/ + +/** + * Identifier NULL + */ +#ifndef NULL +#define NULL 0 +#endif + +/** + * Boolean identifiers + */ +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +/** + * Number of channels + */ +#define CH_NUM 32 +/** + * Number of events + */ +#ifdef MXC_SDMA_V2 +#define EVENTS_NUM 48 +#else +#define EVENTS_NUM 32 +#endif +/** + * Channel configuration + */ +#define DONT_OWN_CHANNEL 0 +#define OWN_CHANNEL 1 + +/** + * Ownership (value defined to computed decimal value) + */ +#define CH_OWNSHP_OFFSET_EVT 0 +#define CH_OWNSHP_OFFSET_MCU 1 +#define CH_OWNSHP_OFFSET_DSP 2 +/** + * Indexof the greg which holds address to start a script from when channel + * becomes current. + */ +#define SDMA_NUMBER_GREGS 8 + +/** + * Channel contexts management + */ + +#define CHANNEL_CONTEXT_BASE_ADDRESS 0x800 +/** + * Buffer descriptor status values. + */ +#define BD_DONE 0x01 +#define BD_WRAP 0x02 +#define BD_CONT 0x04 +#define BD_INTR 0x08 +#define BD_RROR 0x10 +#define BD_LAST 0x20 +#define BD_EXTD 0x80 + + +/** + * Data Node descriptor status values. + */ +#define DND_END_OF_FRAME 0x80 +#define DND_END_OF_XFER 0x40 +#define DND_DONE 0x20 +#define DND_UNUSED 0x01 + +/** + * IPCV2 descriptor status values. + */ +#define BD_IPCV2_END_OF_FRAME 0x40 + + +#define IPCV2_MAX_NODES 50 +/** + * Error bit set in the CCB status field by the SDMA, + * in setbd routine, in case of a transfer error + */ +#define DATA_ERROR 0x10000000 + +/** + * Buffer descriptor commands. + */ +#define C0_ADDR 0x01 +#define C0_LOAD 0x02 +#define C0_DUMP 0x03 +#define C0_SETCTX 0x07 +#define C0_GETCTX 0x03 +#define C0_SETDM 0x01 +#define C0_SETPM 0x04 +#define C0_GETDM 0x02 +#define C0_GETPM 0x08 +/** + * Transfer types, encoded in the BD command field + */ +#define TRANSFER_32BIT 0x00 +#define TRANSFER_8BIT 0x01 +#define TRANSFER_16BIT 0x02 +#define TRANSFER_24BIT 0x03 +/** + * Change endianness indicator in the BD command field + */ +#define CHANGE_ENDIANNESS 0x80 +/** + * Size in bytes + */ +#define SDMA_BD_SIZE 8 +#define SDMA_EXTENDED_BD_SIZE 12 +#define BD_NUMBER 4 +/** + * Channel interrupt policy + */ +#define DEFAULT_POLL 0 +#define CALLBACK_ISR 1 +/** + * Channel status + */ +#define UNINITIALIZED 0 +#define INITIALIZED 1 + +/** + * IoCtl particular values + */ +#define SET_BIT_ALL 0xFFFFFFFF +#define BD_NUM_OFFSET 16 +#define BD_NUM_MASK 0xFFFF0000 + +/** + * Maximum values for IoCtl calls, used in high or middle level calls + */ +#define MAX_BD_NUM 256 +#define MAX_BD_SIZE 65536 +#define MAX_BLOCKING 2 +#define MAX_SYNCH 2 +#define MAX_OWNERSHIP 8 +#define MAX_CH_PRIORITY 8 +#define MAX_TRUST 2 +#define MAX_WML 256 + + +/** + * Access to channelDescriptor fields + */ +enum { + IAPI_CHANNELNUMBER, + IAPI_BUFFERDESCNUMBER, + IAPI_BUFFERSIZE, + IAPI_BLOCKING, + IAPI_CALLBACKSYNCH, + IAPI_OWNERSHIP, + IAPI_PRIORITY, + IAPI_TRUST, + IAPI_UNUSED, + IAPI_CALLBACKISR_PTR, + IAPI_CCB_PTR, + IAPI_BDWRAP, + IAPI_WML +}; + +/** + * Default values for channel descriptor - nobody ownes the channel + */ +#define CD_DEFAULT_OWNERSHIP 7 + + +/** + * User Type Section + */ + +/** + * Command/Mode/Count of buffer descriptors + */ + +#if (ENDIANNESS==B_I_G_ENDIAN) +typedef struct iapi_modeCount_ipcv2 { + unsigned long status : 8; /**< L, E , D bits stored here */ + unsigned long reserved : 8; + unsigned long count : 16; /**< +#elif OS == LINUX +#include +#endif + + +/* **************************************************************************** + * Macro-command Section + *****************************************************************************/ + +#define GOTO_SLEEP(x) (iapi_GotoSleep)(x) +#define INIT_SLEEP(x) (iapi_InitSleep)(x) + +/* **************************************************************************** + * Public Function Prototype Section + *****************************************************************************/ +void iapi_lowStartChannel ( unsigned char channel ); +void iapi_lowStopChannel ( unsigned char channel ); +void iapi_AttachCallbackISR (channelDescriptor * cd_p, + void (* func_p)(channelDescriptor * cd_p, void * arg)); +void iapi_DetachCallbackISR (channelDescriptor * cd_p); +void iapi_ChangeCallbackISR (channelDescriptor * cd_p, + void (* func_p)(channelDescriptor * cd_p, void * arg)); +void iapi_lowSynchChannel ( unsigned char channel ); +void iapi_SetBufferDescriptor(bufferDescriptor *bd_p, unsigned char command, + unsigned char status, unsigned short count, + void * buffAddr, void * extBufferAddr); + +#endif /* _iapiLow_h */ --- linux-2.6.28.orig/arch/arm/plat-mxc/sdma/iapi/include/epm.h +++ linux-2.6.28/arch/arm/plat-mxc/sdma/iapi/include/epm.h @@ -0,0 +1,187 @@ +/* + * Copyright 2007-2009 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_SDMA_REGS_H__ +#define __ASM_ARCH_MXC_SDMA_REGS_H__ + +#include + +/* SDMA Reg definition */ +#define SDMA_BASE_IO_ADDR IO_ADDRESS(SDMA_BASE_ADDR) + +#define SDMA_H_C0PTR *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x000)) +#define SDMA_H_INTR *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x004)) +#define SDMA_H_STATSTOP *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x008)) +#define SDMA_H_START *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x00C)) +#define SDMA_H_EVTOVR *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x010)) +#define SDMA_H_DSPOVR *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x014)) +#define SDMA_H_HOSTOVR *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x018)) +#define SDMA_H_EVTPEND *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x01C)) +#define SDMA_H_DSPENBL *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x020)) +#define SDMA_H_RESET *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x024)) +#define SDMA_H_EVTERR *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x028)) +#define SDMA_H_INTRMSK *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x02C)) +#define SDMA_H_PSW *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x030)) +#define SDMA_H_EVTERRDBG *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x034)) +#define SDMA_H_CONFIG *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x038)) +#define SDMA_ONCE_ENB *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x040)) +#define SDMA_ONCE_DATA *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x044)) +#define SDMA_ONCE_INSTR *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x048)) +#define SDMA_ONCE_STAT *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x04C)) +#define SDMA_ONCE_CMD *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x050)) +#define SDMA_EVT_MIRROR *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x054)) +#define SDMA_ILLINSTADDR *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x058)) +#define SDMA_CHN0ADDR *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x05C)) +#define SDMA_ONCE_RTB *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x060)) +#define SDMA_XTRIG_CONF1 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x070)) +#define SDMA_XTRIG_CONF2 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x074)) + +#ifdef MXC_SDMA_V2 +#define SDMA_CHNENBL_0 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x200)) +#define SDMA_CHNENBL_1 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x204)) +#define SDMA_CHNENBL_2 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x208)) +#define SDMA_CHNENBL_3 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x20C)) +#define SDMA_CHNENBL_4 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x210)) +#define SDMA_CHNENBL_5 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x214)) +#define SDMA_CHNENBL_6 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x218)) +#define SDMA_CHNENBL_7 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x21C)) +#define SDMA_CHNENBL_8 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x220)) +#define SDMA_CHNENBL_9 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x224)) +#define SDMA_CHNENBL_10 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x228)) +#define SDMA_CHNENBL_11 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x22C)) +#define SDMA_CHNENBL_12 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x230)) +#define SDMA_CHNENBL_13 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x234)) +#define SDMA_CHNENBL_14 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x238)) +#define SDMA_CHNENBL_15 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x23C)) +#define SDMA_CHNENBL_16 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x240)) +#define SDMA_CHNENBL_17 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x244)) +#define SDMA_CHNENBL_18 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x248)) +#define SDMA_CHNENBL_19 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x24C)) +#define SDMA_CHNENBL_20 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x250)) +#define SDMA_CHNENBL_21 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x254)) +#define SDMA_CHNENBL_22 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x258)) +#define SDMA_CHNENBL_23 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x25C)) +#define SDMA_CHNENBL_24 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x260)) +#define SDMA_CHNENBL_25 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x264)) +#define SDMA_CHNENBL_26 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x268)) +#define SDMA_CHNENBL_27 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x26C)) +#define SDMA_CHNENBL_28 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x270)) +#define SDMA_CHNENBL_29 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x274)) +#define SDMA_CHNENBL_30 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x278)) +#define SDMA_CHNENBL_31 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x27C)) +#define SDMA_CHNENBL_32 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x280)) +#define SDMA_CHNENBL_33 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x284)) +#define SDMA_CHNENBL_34 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x288)) +#define SDMA_CHNENBL_35 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x28C)) +#define SDMA_CHNENBL_36 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x290)) +#define SDMA_CHNENBL_37 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x294)) +#define SDMA_CHNENBL_38 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x298)) +#define SDMA_CHNENBL_39 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x29C)) +#define SDMA_CHNENBL_40 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x2A0)) +#define SDMA_CHNENBL_41 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x2A4)) +#define SDMA_CHNENBL_42 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x2A8)) +#define SDMA_CHNENBL_43 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x2AC)) +#define SDMA_CHNENBL_44 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x2B0)) +#define SDMA_CHNENBL_45 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x2B4)) +#define SDMA_CHNENBL_46 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x2B8)) +#define SDMA_CHNENBL_47 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x2BC)) + +#define SDMA_ONCE_COUNT *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x300)) +#define SDMA_ONCE_ECTL *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x304)) +#define SDMA_ONCE_EAA *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x308)) +#define SDMA_ONCE_EAB *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x30C)) +#define SDMA_ONCE_EAM *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x310)) +#define SDMA_ONCE_ED *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x314)) +#define SDMA_ONCE_EDM *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x318)) +#define SDMA_ONCE_PCMATCH *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x31C)) + +#else + +#define SDMA_CHNENBL_0 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x080)) +#define SDMA_CHNENBL_1 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x084)) +#define SDMA_CHNENBL_2 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x088)) +#define SDMA_CHNENBL_3 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x08C)) +#define SDMA_CHNENBL_4 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x090)) +#define SDMA_CHNENBL_5 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x094)) +#define SDMA_CHNENBL_6 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x098)) +#define SDMA_CHNENBL_7 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x09C)) +#define SDMA_CHNENBL_8 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0A0)) +#define SDMA_CHNENBL_9 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0A4)) +#define SDMA_CHNENBL_10 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0A8)) +#define SDMA_CHNENBL_11 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0AC)) +#define SDMA_CHNENBL_12 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0B0)) +#define SDMA_CHNENBL_13 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0B4)) +#define SDMA_CHNENBL_14 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0B8)) +#define SDMA_CHNENBL_15 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0BC)) +#define SDMA_CHNENBL_16 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0C0)) +#define SDMA_CHNENBL_17 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0C4)) +#define SDMA_CHNENBL_18 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0C8)) +#define SDMA_CHNENBL_19 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0CC)) +#define SDMA_CHNENBL_20 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0D0)) +#define SDMA_CHNENBL_21 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0D4)) +#define SDMA_CHNENBL_22 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0D8)) +#define SDMA_CHNENBL_23 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0DC)) +#define SDMA_CHNENBL_24 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0E0)) +#define SDMA_CHNENBL_25 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0E4)) +#define SDMA_CHNENBL_26 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0E8)) +#define SDMA_CHNENBL_27 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0EC)) +#define SDMA_CHNENBL_28 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0F0)) +#define SDMA_CHNENBL_29 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0F4)) +#define SDMA_CHNENBL_30 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0F8)) +#define SDMA_CHNENBL_31 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0FC)) + +#define SDMA_ONCE_COUNT *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x200)) +#define SDMA_ONCE_ECTL *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x204)) +#define SDMA_ONCE_EAA *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x208)) +#define SDMA_ONCE_EAB *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x20C)) +#define SDMA_ONCE_EAM *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x210)) +#define SDMA_ONCE_ED *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x214)) +#define SDMA_ONCE_EDM *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x218)) +#define SDMA_ONCE_PCMATCH *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x21C)) + +#endif /* MXC_SDMA_V2 */ + +#define SDMA_CHNPRI_0 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x100)) +#define SDMA_CHNPRI_1 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x104)) +#define SDMA_CHNPRI_2 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x108)) +#define SDMA_CHNPRI_3 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x10C)) +#define SDMA_CHNPRI_4 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x110)) +#define SDMA_CHNPRI_5 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x114)) +#define SDMA_CHNPRI_6 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x118)) +#define SDMA_CHNPRI_7 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x11C)) +#define SDMA_CHNPRI_8 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x120)) +#define SDMA_CHNPRI_9 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x124)) +#define SDMA_CHNPRI_10 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x128)) +#define SDMA_CHNPRI_11 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x12C)) +#define SDMA_CHNPRI_12 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x130)) +#define SDMA_CHNPRI_13 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x134)) +#define SDMA_CHNPRI_14 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x138)) +#define SDMA_CHNPRI_15 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x13C)) +#define SDMA_CHNPRI_16 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x140)) +#define SDMA_CHNPRI_17 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x144)) +#define SDMA_CHNPRI_18 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x148)) +#define SDMA_CHNPRI_19 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x14C)) +#define SDMA_CHNPRI_20 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x150)) +#define SDMA_CHNPRI_21 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x154)) +#define SDMA_CHNPRI_22 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x158)) +#define SDMA_CHNPRI_23 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x15C)) +#define SDMA_CHNPRI_24 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x160)) +#define SDMA_CHNPRI_25 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x164)) +#define SDMA_CHNPRI_26 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x168)) +#define SDMA_CHNPRI_27 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x16C)) +#define SDMA_CHNPRI_28 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x170)) +#define SDMA_CHNPRI_29 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x174)) +#define SDMA_CHNPRI_30 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x178)) +#define SDMA_CHNPRI_31 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x17C)) + +#endif /* _mcuEpm_h */ --- linux-2.6.28.orig/arch/arm/plat-mxc/sdma/iapi/include/iapiLowMcu.h +++ linux-2.6.28/arch/arm/plat-mxc/sdma/iapi/include/iapiLowMcu.h @@ -0,0 +1,60 @@ +/****************************************************************************** + * + * Copyright 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 + * + ****************************************************************************** + * + * File: iapiLowMcu.h + * + * $Id iapiLowMcu.h $ + * + * Description: + * prototypes for low level function of I.API of MCU side only + * + * + * + * + * $Log iapiLowMcu.h $ + * + * ***************************************************************************/ + +#ifndef _iapiLowMcu_h +#define _iapiLowMcu_h + +/****************************************************************************** + * Include File Section + *****************************************************************************/ +#include "sdmaStruct.h" +#include "iapiDefaults.h" + +/* **************************************************************************** + * Public Function Prototype Section + * ***************************************************************************/ + + +void iapi_InitChannelTables ( void ); +int iapi_ChannelConfig(unsigned char channel, unsigned eventOverride, + unsigned mcuOverride, unsigned dspOverride); +int iapi_Channel0Command(channelDescriptor * cd_p, void * buf, + unsigned short nbyte, unsigned char command); +void iapi_lowGetScript(channelDescriptor * cd_p, void * buf, unsigned short size, + unsigned long address); +void iapi_lowGetContext(channelDescriptor * cd_p, void * buf, + unsigned char channel); +void iapi_lowSetScript(channelDescriptor * cd_p, void * buf, unsigned short nbyte, + unsigned long destAddr); +void iapi_lowSetContext(channelDescriptor * cd_p, void * buf, + unsigned char channel); +int iapi_lowAssignScript(channelDescriptor * cd_p, script_data * data_p); + +int iapi_lowSetChannelEventMapping(unsigned char event, unsigned long channel_map); + +#endif /* _iapiLowMcu_h */ --- linux-2.6.28.orig/arch/arm/plat-mxc/sdma/iapi/include/iapiMiddleMcu.h +++ linux-2.6.28/arch/arm/plat-mxc/sdma/iapi/include/iapiMiddleMcu.h @@ -0,0 +1,41 @@ +/****************************************************************************** + * + * Copyright 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 + * + ****************************************************************************** + * + * File: iapiMiddleMcu.h + * + * $Id iapiMiddleMcu.h $ + * + * Description: + * prototypes for middle level function of I.API + * + * + * + * + * $Log iapiMiddleMcu.h + * + * ***************************************************************************/ + +#ifndef _iapiMiddleMcu_h +#define _iapiMiddleMcu_h + +/* **************************************************************************** + * Include File Section + ******************************************************************************/ +#include "sdmaStruct.h" + +/* **************************************************************************** + * Public Function Prototype Section + ******************************************************************************/ + +#endif /* iapiMiddleMcu_h */ --- linux-2.6.28.orig/arch/arm/plat-mxc/sdma/iapi/src/iapiLow.c +++ linux-2.6.28/arch/arm/plat-mxc/sdma/iapi/src/iapiLow.c @@ -0,0 +1,150 @@ +/****************************************************************************** + * + * Copyright 2007-2008 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 + * + ****************************************************************************** + * + * File: iapiLow.c + * + * $Id iapiLow.c $ + * + * Description: + * This library is written in C to guarantee functionality and integrity in + * the usage of SDMA virtual DMA channels. This API (Application Programming + * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE + * fashion. + * These are the LOW level functions of the I.API. + * + * + * / + * + * $Log iapiLow.c $ + * + *****************************************************************************/ + +/* **************************************************************************** + * Include File Section + *****************************************************************************/ +#include "epm.h" +#include "iapiLow.h" + +/** + * Function Section + */ + + +/* ***************************************************************************/ +/**Records an ISR callback function pointer into the ISR callback + * function table + * + * @param cd_p channel descriptor to attach callback to + * @param func_p pointer to the callback function to be registered + * + * @return none + */ +void +iapi_AttachCallbackISR (channelDescriptor * cd_p, + void (* func_p)(channelDescriptor * cd_p, void * arg)) + +{ + if (cd_p->callbackSynch == CALLBACK_ISR) { + iapi_DisableInterrupts(); + callbackIsrTable[cd_p->channelNumber] = func_p; + iapi_EnableInterrupts(); + } else if (cd_p->callbackSynch == DEFAULT_POLL) { + callbackIsrTable[cd_p->channelNumber] = NULL; + } else { + iapi_errno = IAPI_ERR_CALLBACKSYNCH_UNKNOWN | IAPI_ERR_CH_AVAILABLE | + cd_p->channelNumber; + } +} + + +/* ***************************************************************************/ +/**Detaches (removes) an ISR callback function pointer from the ISR callback + * function table + * + * Algorithm:\n + * - Attach a null function to replace the original one. + * + * @param cd_p channel descriptor to detach callback from + * + * @return none + */ +void +iapi_DetachCallbackISR (channelDescriptor * cd_p) + +{ + iapi_AttachCallbackISR (cd_p, NULL); +} + +/* ***************************************************************************/ +/**Updates an ISR callback function pointer into the ISR callback function + * table + * + * Algorithm:\n + * - Detach the old function pointer (if any) and attach the new one + * + * @param cd_p channel descriptor to attach callback to + * @param func_p pointer to the callback function to be registered + * + * @return none + */ +void +iapi_ChangeCallbackISR (channelDescriptor * cd_p, + void (* func_p)(channelDescriptor * cd_p, void * arg)) +{ + iapi_DetachCallbackISR(cd_p); + iapi_AttachCallbackISR(cd_p, func_p); +} + +/* ***************************************************************************/ +/**Loop while the channel is not done on the SDMA + * + * Algorithm:\n + * - Loop doing nothing but checking the I.API global variable to indicate + * that the channel has been completed (interrupt from SDMA) + * + * Notes:\n + * - The ISR must update the I.API global variable iapi_SDMAIntr. + * + * @param channel channel number to poll on + * + * @return none + */ +void +iapi_lowSynchChannel (unsigned char channel) +{ + while (!((1UL << channel) & iapi_SDMAIntr)) ; + iapi_SDMAIntr &= ~(1UL << channel); +} + +/* ***************************************************************************/ +/**Fill the buffer descriptor with the values given in parameter. + * + * @return none + */ +void +iapi_SetBufferDescriptor( bufferDescriptor * bd_p, unsigned char command, + unsigned char status, unsigned short count, + void * buffAddr, void * extBufferAddr) +{ + bd_p->mode.command = command; + bd_p->mode.status = status; + bd_p->mode.count = count; + if (buffAddr != NULL) { + bd_p->bufferAddr = iapi_Virt2Phys(buffAddr); + } else { + bd_p->bufferAddr = buffAddr; + } + bd_p->extBufferAddr = extBufferAddr; +} + --- linux-2.6.28.orig/arch/arm/plat-mxc/sdma/iapi/src/iapiOS.c +++ linux-2.6.28/arch/arm/plat-mxc/sdma/iapi/src/iapiOS.c @@ -0,0 +1,64 @@ +/****************************************************************************** + * + * Copyright 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 + * + ****************************************************************************** + * + * File: iapiOS.c + * + * $Id iapiOS.c $ + * + * Description: + * This library is written in C to guarantee functionality and integrity in + * the usage of SDMA virtual DMA channels. This API (Application Programming + * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE + * fashion. + * These are the OS level functions of the I.API - are OS dependant and must + * be provided by the user of I.API. + * + * + * / + * + * $Log iapiOS.c $ + * + *****************************************************************************/ + +/* **************************************************************************** + * Include File Section + *****************************************************************************/ +#include "epm.h" +#include "iapiLow.h" + +/** + * Function Section + */ +#ifdef CONFIG_SDMA_IRAM +void*(* iapi_iram_Malloc) (size_t size); +#endif /*CONFIG_SDMA_IRAM*/ + +void*(* iapi_Malloc) (size_t size); +void (* iapi_Free) (void * ptr); + +void*(* iapi_Virt2Phys) (void * ptr); +void*(* iapi_Phys2Virt) (void * ptr); + +void (* iapi_WakeUp)(int); +void (* iapi_GotoSleep)(int); +void (* iapi_InitSleep)(int); + +void*(* iapi_memcpy)(void *dest, const void *src, size_t count); +void*(* iapi_memset)(void *dest, int c, size_t count); + +void (* iapi_EnableInterrupts)(void); +void (* iapi_DisableInterrupts)(void); + +int (* iapi_GetChannel)(int); +int (* iapi_ReleaseChannel)(int); --- linux-2.6.28.orig/arch/arm/plat-mxc/sdma/iapi/src/Makefile +++ linux-2.6.28/arch/arm/plat-mxc/sdma/iapi/src/Makefile @@ -0,0 +1,18 @@ +# +# Makefile for I.API sources. +# +ifneq ($(KBUILD_SRC),) +ccflags-y += -I$(KBUILD_SRC)/arch/arm/plat-mxc/sdma/iapi/include \ + -I$(KBUILD_SRC)/include/linux \ + -DMCU -DOS=LINUX \ + -DL_I_T_T_L_E_ENDIAN=0 -DB_I_G_ENDIAN=1 \ + -DENDIANNESS=L_I_T_T_L_E_ENDIAN +else +ccflags-y += -Iarch/arm/plat-mxc/sdma/iapi/include \ + -Iinclude/linux \ + -DMCU -DOS=LINUX \ + -DL_I_T_T_L_E_ENDIAN=0 -DB_I_G_ENDIAN=1 \ + -DENDIANNESS=L_I_T_T_L_E_ENDIAN +endif + +obj-y += iapiLow.o iapiLowMcu.o iapiMiddle.o iapiMiddleMcu.o iapiHigh.o iapiDefaults.o iapiOS.o --- linux-2.6.28.orig/arch/arm/plat-mxc/sdma/iapi/src/iapiMiddle.c +++ linux-2.6.28/arch/arm/plat-mxc/sdma/iapi/src/iapiMiddle.c @@ -0,0 +1,623 @@ +/****************************************************************************** + * + * Copyright 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 + * + ****************************************************************************** + * + * File: iapiMiddle.c + * + * $Id iapiMiddle.c $ + * + * Description: + * This library is written in C to guarantee functionality and integrity in + * the usage of SDMA virtual DMA channels. This API (Application Programming + * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE + * fashion. + * These are the MIDDLE level functions of the I.API. + * + * + * + * + * $Log iapiMiddle.c $ + * + *****************************************************************************/ + + +/* **************************************************************************** + * Include File Section + *****************************************************************************/ +#include "epm.h" +#include + +#include "iapiLow.h" +#include "iapiMiddle.h" + +/* **************************************************************************** + * Global Variable Section + *****************************************************************************/ + + +/* **************************************************************************** + * Function Section + *****************************************************************************/ + +/* ***************************************************************************/ +/**Allocates one Buffer Descriptor structure using information present in the + * channel descriptor. + * + * @param *ccb_p channel control block used to get the channel descriptor + * + * @return + * - pointer on the new Buffer Descriptor + * - NULL if allocation failed + * + */ +bufferDescriptor * +iapi_AllocBD (channelControlBlock * ccb_p) + +{ + bufferDescriptor * ptrBD = NULL; + + if (ccb_p->channelDescriptor->bufferDescNumber != 0){ +#ifdef CONFIG_SDMA_IRAM + channelDescriptor * cd_p = ccb_p->channelDescriptor; + if(cd_p->channelNumber >= MXC_DMA_CHANNEL_IRAM) { + ptrBD = (bufferDescriptor *) + MALLOC( ccb_p->channelDescriptor->bufferDescNumber * + sizeof(bufferDescriptor), SDMA_IRAM); + } else +#endif /*CONFIG_SDMA_IRAM*/ + { + ptrBD = (bufferDescriptor *) + MALLOC( ccb_p->channelDescriptor->bufferDescNumber * + sizeof(bufferDescriptor), SDMA_ERAM); + } + } + if (ptrBD != NULL) { + ptrBD->mode.command = 0; + ptrBD->mode.status = 0; + ptrBD->mode.count = 0; + ptrBD->bufferAddr = NULL; + } + + return ptrBD; +} + +/* ***************************************************************************/ +/**Allocate one channel context data structure. + * + * @param **ctxd_p pointer to context data to be allocated + * @param channel channel number of context data structure + * + * @return + * - IAPI_SUCCESS + * - -iapi_errno if allocation failed + */ +int +iapi_AllocContext(contextData ** ctxd_p, unsigned char channel) +{ + contextData * ctxData; + int result = IAPI_SUCCESS; + + if (*ctxd_p != NULL){ + result = IAPI_ERR_CC_ALREADY_DEFINED | IAPI_ERR_CH_AVAILABLE | channel; + iapi_errno = result; + return -result; + } + + ctxData = (contextData *)MALLOC(sizeof(contextData), SDMA_ERAM); + + if (ctxData !=NULL) { + *ctxd_p = ctxData; + return IAPI_SUCCESS; + + } else { + *ctxd_p = NULL; + result = IAPI_ERR_CC_ALLOC_FAILED | IAPI_ERR_CH_AVAILABLE | channel; + iapi_errno = result; + return -result; + } +} + +/* ***************************************************************************/ +/**Allocates channel description and fill in with default values. + * + * Algorithm:\n + * - Check channel properties. + * - Then modifies the properties of the channel description with default + * + * @param **cd_p pointer to channel descriptor to be allocated + * @param channel channel number of channel descriptor + * + * @return + * - IAPI_SUCCESS + * - -iapi_errno if allocation failed + * + */ +int +iapi_AllocChannelDesc (channelDescriptor ** cd_p, unsigned char channel) +{ +#ifdef MCU + volatile unsigned long * chPriorities = &SDMA_CHNPRI_0; +#endif /* MCU */ + channelDescriptor * tmpCDptr; + int result = IAPI_SUCCESS; + + + if (*cd_p != NULL){ + result = IAPI_ERR_CD_ALREADY_DEFINED | IAPI_ERR_CH_AVAILABLE | channel; + iapi_errno = result; + return -result; + } + + tmpCDptr = (channelDescriptor *)MALLOC(sizeof(channelDescriptor), SDMA_ERAM); + + if (tmpCDptr != NULL){ + iapi_memcpy(tmpCDptr, &iapi_ChannelDefaults, sizeof (channelDescriptor)); + tmpCDptr->channelNumber = channel; +#ifdef MCU + if (chPriorities[channel] != 0) { + tmpCDptr->priority = chPriorities[channel]; + } else { + chPriorities[channel] = tmpCDptr->priority; + } +#endif + * cd_p = tmpCDptr ; + return IAPI_SUCCESS; + } else { + * cd_p = NULL; + result = IAPI_ERR_CD_ALLOC_FAILED | IAPI_ERR_CH_AVAILABLE | channel; + iapi_errno = result; + return -result; + } +} + +/* ***************************************************************************/ +/**Changes channel description information after performing sanity checks. + * + * Algorithm:\n + * - Check channel properties. + * - Then modifies the properties of the channel description. + * + * @param *cd_p channel descriptor of the channel to change + * @param whatToChange control code indicating the desired change + * @param newval new value + * + * @return + * - IAPI_SUCCESS + * - IAPI_FAILURE if change failed + * + */ +int +iapi_ChangeChannelDesc (channelDescriptor * cd_p, unsigned char whatToChange, + unsigned long newval) +{ + bufferDescriptor * tmpBDptr; + unsigned char index = 0; + int result = IAPI_SUCCESS; + + /* verify parameter validity */ + if (cd_p == NULL) { + result = IAPI_ERR_CD_UNINITIALIZED; + iapi_errno = result; + return -result; + } + + /* verify channel descriptor initialization */ + if (cd_p->ccb_ptr == NULL){ + result = IAPI_ERR_CCB_UNINITIALIZED | IAPI_ERR_CH_AVAILABLE | + cd_p->channelNumber; + iapi_errno = result; + return -result; + } + + /* verify channel is not in use */ + tmpBDptr = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + for (index=cd_p->bufferDescNumber ; index>0 ; index--){ + if (tmpBDptr->mode.status & BD_DONE){ + result = IAPI_ERR_CH_IN_USE | IAPI_ERR_CH_AVAILABLE | + cd_p->channelNumber; + iapi_errno = result; + return -result; + } + tmpBDptr++; + } + + /* Select the change accorded to the selector given in parameter */ + switch (whatToChange){ + + /* + * Channel Number + */ + case IAPI_CHANNELNUMBER: + /* Channel number can not be changed (description remains attached) */ + result = IAPI_ERR_CD_CHANGE_CH_NUMBER | IAPI_ERR_CH_AVAILABLE | + cd_p->channelNumber; + iapi_errno = result; + return -result; + + /* + * Buffer Descriptor Number + */ + case IAPI_BUFFERDESCNUMBER: + if (newval < MAX_BD_NUM){ + if (newval != cd_p->bufferDescNumber){ + /* Free memory used for previous old data */ + if (cd_p->ccb_ptr->baseBDptr != NULL){ + tmpBDptr = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + for (index=0 ; index < cd_p->bufferDescNumber ; index++){ + if (tmpBDptr->bufferAddr != NULL){ + if (cd_p->trust == FALSE) { + FREE(iapi_Phys2Virt(tmpBDptr->bufferAddr)); + } + } + tmpBDptr ++ ; + } + FREE((bufferDescriptor *)iapi_Phys2Virt((cd_p->ccb_ptr)->baseBDptr)); + } + (cd_p->ccb_ptr)->baseBDptr = NULL; + (cd_p->ccb_ptr)->currentBDptr = NULL; + /* Allocate and initialize structures */ + cd_p->bufferDescNumber = (unsigned char)newval; + cd_p->ccb_ptr->status.openedInit = FALSE; + if (IAPI_SUCCESS !=iapi_InitializeMemory (cd_p->ccb_ptr)) + { + result = IAPI_ERR_BD_ALLOCATION | cd_p->channelNumber; + iapi_errno = result; + return -result; + } + cd_p->ccb_ptr->status.openedInit = TRUE; + } + break; + } else { + result = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE | + cd_p->channelNumber; + iapi_errno = result; + return -result; + } + + /* + * Buffer size + */ + case IAPI_BUFFERSIZE: + if (newval < MAX_BD_SIZE) + { + if (newval != cd_p->bufferSize) + { + /* Free memory used for previous old data */ + if (cd_p->ccb_ptr->baseBDptr != NULL) + { + tmpBDptr = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + for (index=0 ; index < cd_p->bufferDescNumber ; index++) + { + if (cd_p->trust == FALSE) + { + FREE(iapi_Phys2Virt(tmpBDptr->bufferAddr)); + } + tmpBDptr ++ ; + } + FREE((bufferDescriptor *)iapi_Phys2Virt((cd_p->ccb_ptr)->baseBDptr)); + } + (cd_p->ccb_ptr)->baseBDptr = NULL; + (cd_p->ccb_ptr)->currentBDptr = NULL; + /* Allocate and initialize structures */ + cd_p->bufferSize = (unsigned short)newval; + cd_p->ccb_ptr->status.openedInit = FALSE; + if (IAPI_SUCCESS !=iapi_InitializeMemory (cd_p->ccb_ptr)) + { + result = IAPI_ERR_BD_ALLOCATION | cd_p->channelNumber; + iapi_errno = result; + return -result; + } + cd_p->ccb_ptr->status.openedInit = TRUE; + } + break; + } + else + { + result = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE | + cd_p->channelNumber; + iapi_errno = result; + return -result; + } + + + /* + * Blocking / non blocking feature + */ + case IAPI_BLOCKING: + if (newval < MAX_BLOCKING){ + cd_p->blocking = newval; + break; + } else { + result = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE | + cd_p->channelNumber; + iapi_errno = result; + return -result; + } + + /* + * Synchronization method + */ + case IAPI_CALLBACKSYNCH: + if (newval < MAX_SYNCH){ + cd_p->callbackSynch = newval; + iapi_ChangeCallbackISR( cd_p, cd_p->callbackISR_ptr); + break; + } else { + result = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE | + cd_p->channelNumber; + iapi_errno = result; + return -result; + } + + + /* + * Ownership of the channel + */ + case IAPI_OWNERSHIP: +#ifdef DSP + result = IAPI_ERR_NOT_ALLOWED | cd_p->channelNumber; + iapi_errno = result; + return -result; +#endif /* DSP */ +#ifdef MCU + if (newval < MAX_OWNERSHIP){ + cd_p->ownership = newval; + iapi_ChannelConfig( cd_p->channelNumber, + ( newval >> CH_OWNSHP_OFFSET_EVT ) & 1, + ( newval >> CH_OWNSHP_OFFSET_MCU ) & 1, + ( newval >> CH_OWNSHP_OFFSET_DSP ) & 1); + break; + } else { + result = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE | + cd_p->channelNumber; + iapi_errno = result; + return -result; + } + +#endif /* MCU */ + + /* + * Priority + */ + case IAPI_PRIORITY: +#ifdef DSP + result = IAPI_ERR_NOT_ALLOWED | cd_p->channelNumber; + iapi_errno = result; + return -result; +#endif /* DSP */ + +#ifdef MCU + if (newval < MAX_CH_PRIORITY){ + volatile unsigned long * ChannelPriorities = &SDMA_CHNPRI_0; + ChannelPriorities[ cd_p->channelNumber ] = newval; + break; + } else { + result = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE | + cd_p->channelNumber; + iapi_errno = result; + return -result; + } +#endif /* MCU */ + + + /* + * "Trust" property + */ + case IAPI_TRUST: + if (newval < MAX_TRUST){ + if (cd_p->trust != newval){ + cd_p->trust = newval; + if (newval == FALSE) { + if (IAPI_SUCCESS !=iapi_InitializeMemory (cd_p->ccb_ptr)) + { + result = IAPI_ERR_BD_ALLOCATION | cd_p->channelNumber; + iapi_errno = result; + return -result; + } + } + } + break; + } else { + result = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE | + cd_p->channelNumber; + iapi_errno = result; + return -result; + } + + /* + * Callback function pointer + */ + case IAPI_CALLBACKISR_PTR: + if ( (void *)newval != NULL){ + { + union { + void * voidstar; + void (* funcptr)(channelDescriptor * cd_p, void * arg); + } value; + value.voidstar = (void*) newval; + cd_p->callbackISR_ptr = value.funcptr; + } + iapi_ChangeCallbackISR( cd_p, cd_p->callbackISR_ptr); + break; + } else { + result = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE | + cd_p->channelNumber; + iapi_errno = result; + return -result; + } + + + /* + * Channel Control Block pointer + */ + case IAPI_CCB_PTR: + cd_p->ccb_ptr = (channelControlBlock *)newval; + cd_p->ccb_ptr->channelDescriptor = cd_p; + break; + + /* + * WRAP/UNWRAP + */ + case IAPI_BDWRAP: + /* point to first BD */ + tmpBDptr = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + /* to point to last BD */ + tmpBDptr += cd_p->bufferDescNumber - 1; + if (newval == TRUE){ + /* wrap last BD */ + tmpBDptr->mode.status |= BD_WRAP; + break; + } + else if (newval == FALSE){ + /* unwrap last BD */ + tmpBDptr->mode.status &= ~BD_WRAP; + break; + } + else { + result = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE | + cd_p->channelNumber; + iapi_errno = result; + return -result; + } + + + /* + * Watermark level + */ + case IAPI_WML: +#ifdef DSP + result = IAPI_ERR_NOT_ALLOWED | cd_p->channelNumber; + iapi_errno = result; + return -result; +#endif /* DSP */ +#ifdef MCU + if (newval < MAX_WML){ + if (cd_p->watermarkLevel != newval){ + cd_p->watermarkLevel = newval; + } + break; + } + else { + result = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE | + cd_p->channelNumber; + iapi_errno = result; + return -result; + } +#endif /* MCU */ + + /* + * Detect errors + */ + default: + result = IAPI_ERR_CD_CHANGE_UNKNOWN | IAPI_ERR_CH_AVAILABLE | + cd_p->channelNumber; + iapi_errno = result; + return -result; + } + + return IAPI_SUCCESS; +} + + +/* ***************************************************************************/ +/**Initialize a table of function pointers that contain the interrupt Service + * Routine callback pointers for the SDMA channels with a default value + * + * Algorithm:\n + * - Loop on each element of the global IAPI variable callbackIsrTable + * + * @param *func_p default callback functon for all SDMA channels + * + * @return none + */ +void +iapi_InitializeCallbackISR(void(* func_p)(channelDescriptor * cd_p, void * arg)) +{ + unsigned long chCnt; + + for (chCnt = 0 ; chCnt < CH_NUM ; chCnt++){ + callbackIsrTable[chCnt] = func_p; + } +} + +/* ***************************************************************************/ +/**For the specified channel control block, attach the array of buffer + * descriptors, the channel description structure and initialize channel's + * status using information in the channel descriptor. + * + * @param *ccb_p pointer to channel control block + * + * @return none + * + */ +int +iapi_InitializeMemory (channelControlBlock * ccb_p) +{ + bufferDescriptor * bd_p; + unsigned char index; + int result = IAPI_SUCCESS; + + /* Attach the array of Buffer descriptors */ + bd_p = iapi_AllocBD( ccb_p ); + if (bd_p != NULL) + { + ccb_p->baseBDptr = (bufferDescriptor *)iapi_Virt2Phys(bd_p); + ccb_p->currentBDptr = ccb_p->baseBDptr; + for(index=0 ;index < ccb_p->channelDescriptor->bufferDescNumber-1 ; index++) + { + if (ccb_p->channelDescriptor->trust == TRUE) + { + iapi_SetBufferDescriptor(bd_p, + (unsigned char)ccb_p->channelDescriptor->dataSize, + BD_CONT|BD_EXTD, ccb_p->channelDescriptor->bufferSize, + NULL, NULL); + } + else + { + if (ccb_p->channelDescriptor->bufferSize != 0) + { + iapi_SetBufferDescriptor(bd_p, + (unsigned char)ccb_p->channelDescriptor->dataSize, + BD_CONT|BD_EXTD, ccb_p->channelDescriptor->bufferSize, + MALLOC(ccb_p->channelDescriptor->bufferSize, SDMA_ERAM), NULL); + } + } + bd_p++; + } + + if (ccb_p->channelDescriptor->trust == TRUE) + { + iapi_SetBufferDescriptor(bd_p, + (unsigned char)ccb_p->channelDescriptor->dataSize, + BD_EXTD|BD_WRAP|BD_INTR, ccb_p->channelDescriptor->bufferSize, + NULL, NULL); + } + else + { + if (ccb_p->channelDescriptor->bufferSize != 0) + { + iapi_SetBufferDescriptor(bd_p, + (unsigned char)ccb_p->channelDescriptor->dataSize, + BD_EXTD|BD_WRAP|BD_INTR, + ccb_p->channelDescriptor->bufferSize, + MALLOC(ccb_p->channelDescriptor->bufferSize, SDMA_ERAM), NULL); + } + } + } + else + { + result = IAPI_ERR_BD_ALLOCATION; + return -result; + } + return result; +} --- linux-2.6.28.orig/arch/arm/plat-mxc/sdma/iapi/src/iapiLowMcu.c +++ linux-2.6.28/arch/arm/plat-mxc/sdma/iapi/src/iapiLowMcu.c @@ -0,0 +1,516 @@ +/****************************************************************************** + * + * Copyright 2007-2008 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 + * + ****************************************************************************** + * + * File: iapiLowMcu.c + * + * $Id iapiLowMcu.c $ + * + * Description: + * This library is written in C to guarantee functionality and integrity in + * the usage of SDMA virtual DMA channels. This API (Application Programming + * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE + * fashion. + * These are the LOW level functions of the I.API specific to MCU. + * + * + * http://compass/mot.com/go/115342679 + * + * $Log iapiLowMcu.c $ + * + *****************************************************************************/ + +/* **************************************************************************** + * Include File Section + *****************************************************************************/ +#include + +#include "epm.h" +#include "iapiLow.h" + +/* **************************************************************************** + * Function Section + *****************************************************************************/ +#ifdef MCU + +/* ***************************************************************************/ +/**Send a command on SDMA's channel zero. + * Check if buffer descriptor is already used by the sdma, if yes return + * an error as c0BDNum is wrong. + * + * Notes\n + * There is an upgrade in the script on the Context load command and + * the fact that the context structure has a fixed length of 20 or 24 + * depending on SDMA versions. + * + * @return + * - IAPI_SUCCESS + * - -iapi_errno if failure + */ +int +iapi_Channel0Command( channelDescriptor * cd_p, void * buf, + unsigned short nbyte, unsigned char command) +{ + channelControlBlock * ccb_p; + bufferDescriptor * bd_p; + int result = IAPI_SUCCESS; + unsigned char chNum; + + + /* + * Check data structures are properly initialized + */ + /* Channel descriptor validity */ + if (cd_p == NULL){ + result = IAPI_ERR_CD_UNINITIALIZED; + iapi_errno = result; + return -result; + } + + /* Channel control block validity */ + if (cd_p->ccb_ptr == NULL){ + result = IAPI_ERR_CCB_UNINITIALIZED; + iapi_errno = result; + return -result; + } + + /* Control block & Descriptpor associated with the channel being worked on */ + chNum = cd_p->channelNumber; + ccb_p = cd_p->ccb_ptr; + + /* Is channel already in use ? */ + if (ccb_p->baseBDptr != NULL ) { + result = IAPI_ERR_BD_ALLOCATED | IAPI_ERR_CH_AVAILABLE | chNum; + iapi_errno = result; + return -result; + } + + /* Allocation of buffer descriptors */ + bd_p = (bufferDescriptor *)MALLOC(sizeof( bufferDescriptor ), SDMA_ERAM); + if (bd_p != NULL) { + ccb_p->baseBDptr = (bufferDescriptor *)iapi_Virt2Phys(bd_p); + } else { + result = IAPI_ERR_BD_ALLOCATION | IAPI_ERR_CH_AVAILABLE | chNum; + iapi_errno = result; + return -result; + } + + /* Buffer descriptor setting */ + iapi_SetBufferDescriptor( bd_p, command , BD_WRAP|BD_DONE|BD_INTR , nbyte, + buf,NULL); + + /* Actually the transfer */ + iapi_lowStartChannel( cd_p->channelNumber ); + iapi_lowSynchChannel( cd_p->channelNumber ); + + /* Cleaning of allocation */ + FREE( bd_p ); + ccb_p->baseBDptr = NULL; + + return IAPI_SUCCESS; + +} + +/* ***************************************************************************/ +/**Starts the channel (core specific register) + * + * Algorithm:\n + * - Bit numbered "channel" of HostEnStartReg register is set + * + * @param channel channel to start + * + * @return none + */ +void +iapi_lowStartChannel (unsigned char channel) +{ + SDMA_H_START |= 1 << channel; +} + +/* ***************************************************************************/ +/**Stops the channel (core specific register) + * + * Algorithm: + * - Bit numbered "channel" of HostEnStopReg register is cleared + * + * Notes:\n + * - This is a write one to clear register + * + * @param channel channel to stop + * + * @return none + */ +void +iapi_lowStopChannel (unsigned char channel) +{ + SDMA_H_STATSTOP &= 1 << channel; +} + +/* ***************************************************************************/ +/**Initialize the initial priority of registers and channel enable + * RAM from the MCU side. No channels are enabled, all priorities are set to 0. + * + * @return none + */ +void +iapi_InitChannelTables(void) +{ + + /* No channel is enabled*/ + iapi_memset((void *)&SDMA_CHNENBL_0, 0x00, sizeof(unsigned long)*EVENTS_NUM); + /* All channels have priority 0*/ + iapi_memset((void *)&SDMA_CHNPRI_0, 0x00, sizeof(unsigned long)*CH_NUM); +} + +/* ***************************************************************************/ +/** The host enable (HE), hosts override (HO), dsp enable (DE), dsp override + * (DO) registers are involved here. + * Host and Dsp enable registers are here to signify that the MCU or DSP side + * have prepared the appropriate buffers and are now ready. If the channel is + * owned by the MCU the override bit for that channel needs to be cleared : + * the host allows the channel to be used.\n + * + * Then the override bits can define (mcuOverride dspOverride):\n + * - 0 0 channel is public: transfer to/from MCU to DSP + * - 0 1 channel if owned by DSP + * - 1 0 channel if owned by MCU + * - 1 1 channel zero config + * + * See also :\n + * IAPI Table 1.1 "Channel configuration properties" + * + * @param channel channel to configure + * @param eventOverride event ownership + * @param mcuOverride ARM ownership + * @param dspOverride DSP ownership + * + * @return + * - -iapi_errno if the 3 override parameters are all set + * - IAPI_SUCCESS in other cases (valid cases) + */ +int +iapi_ChannelConfig (unsigned char channel, unsigned eventOverride, + unsigned mcuOverride, unsigned dspOverride) +{ + int result = IAPI_SUCCESS; + + if ( ( eventOverride == 1 ) && + ( mcuOverride == 1 ) && + ( dspOverride == 1 ) ){ + result = IAPI_ERR_CONFIG_OVERRIDE ; + iapi_errno = result; + return -result; + } else { + /* + * DSP side + */ + if ( dspOverride ){ + SDMA_H_DSPOVR &= ~( 1 << channel ); + } else { + SDMA_H_DSPOVR |= ( 1 << channel ); + } + /* + * Event + */ + if ( eventOverride ){ + SDMA_H_EVTOVR &= ~( 1 << channel ); + } else { + SDMA_H_EVTOVR |= ( 1 << channel ); + } + /* + * MCU side + */ + if ( mcuOverride ) { + SDMA_H_HOSTOVR &= ~( 1 << channel ); + } else { + SDMA_H_HOSTOVR |= ( 1 << channel ); + } + } + return IAPI_SUCCESS; +} +/* ***************************************************************************/ +/**Load the context data of a channel from SDMA + * + * Algorithm:\n + * - Setup BD with appropiate parameters + * - Start channel + * - Poll for answer + * + * @param *cd_p channel descriptor for channel 0 + * @param *buf pointer to receive context data + * @param channel channel for which the context data is requested + * + * @return none + */ +void +iapi_lowGetContext(channelDescriptor * cd_p, void * buf, unsigned char channel) +{ + bufferDescriptor * bd_p; + + bd_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + + /*Setup buffer descriptor with channel 0 command*/ + iapi_SetBufferDescriptor(&bd_p[0], + C0_GETDM, + (unsigned char)(BD_DONE | BD_INTR | BD_WRAP | BD_EXTD), + (unsigned short)sizeof(contextData)/4, + buf, + (void *)(CHANNEL_CONTEXT_BASE_ADDRESS + (sizeof(contextData)*channel/4))); + /* Receive, polling method*/ + iapi_lowStartChannel(cd_p->channelNumber); + iapi_lowSynchChannel(cd_p->channelNumber); +} +/* ***************************************************************************/ +/**Read "size" byte /2 at SDMA address (address) and write them in buf + * + * Algorithm:\n + * - Setup BD with appropiate parameters (C0_GETPM) + * - Start channel + * - Poll for answer + * + * Notes\n + * - Parameter "size" is in bytes, it represents the size of "buf", e.g. + * the size in bytes of the script to be loaded. + * - Parameter "address" denotes the RAM address for the script in SDMA + * + * @param *cd_p channel descriptor for channel 0 + * @param *buf pointer to receive the data + * @param size number of bytes to read + * @param address address in SDMA RAM to start reading from + * + * @return none + */ +void +iapi_lowGetScript(channelDescriptor * cd_p, void * buf, unsigned short size, + unsigned long address) +{ + bufferDescriptor * bd_p; + + bd_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + + /*Setup buffer descriptor with channel 0 command*/ + iapi_SetBufferDescriptor(&bd_p[0], + C0_GETPM, + (unsigned char)(BD_DONE | BD_INTR | BD_WRAP | BD_EXTD), + (unsigned short)size/2,/*count in shorts*/ + buf, + (void *)address); + /* Receive, polling method*/ + iapi_lowStartChannel(cd_p->channelNumber); + iapi_lowSynchChannel(cd_p->channelNumber); +} + +/* ***************************************************************************/ +/**Load a SDMA script to SDMA + * + * Algorithm:\n + * - Setup BD with appropiate parameters (C0_SETPM) + * - Start channel + * - Poll for answer + * + * Notes\b + * - Parameter "size" is in bytes, it represents the size of "buf", e.g. + * the size in bytes of the script to be uploaded. + * - Parameter "address" denotes the RAM address for the script in SDMA + * + * @param *cd_p channel descriptor for channel 0 + * @param *buf pointer to the script + * @param size size of the script, in bytes + * @param address address in SDMA RAM to place the script + * + * @return none + */ +void +iapi_lowSetScript(channelDescriptor * cd_p, void * buf, unsigned short size, + unsigned long address) +{ + bufferDescriptor * bd_p; + + bd_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + + /*Setup buffer descriptor with channel 0 command*/ + iapi_SetBufferDescriptor(&bd_p[0], + C0_SETPM, + (unsigned char)(BD_DONE | BD_INTR | BD_WRAP | BD_EXTD), + (unsigned short)size/2,/*count in shorts*/ + buf, + (void *)(address)); + /* Receive, polling method*/ + iapi_lowStartChannel(cd_p->channelNumber); + iapi_lowSynchChannel(cd_p->channelNumber); +} + + +/* ***************************************************************************/ +/**Load the context for a channel to SDMA + * + * Algorithm:\n + * - Send context and poll for answer. + * + * @param *cd_p channel descriptor for channel 0 + * @param *buf pointer to context data + * @param channel channel to place the context for + * + * @return none + */ +void +iapi_lowSetContext(channelDescriptor * cd_p, void * buf, unsigned char channel) +{ + + bufferDescriptor * local_bd_p; +#ifdef SDMA_SKYE + + unsigned char command =0; + + local_bd_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + + + command = channel <<3 ; + command = command | C0_SETCTX; + iapi_SetBufferDescriptor( &local_bd_p[0], + command, + (unsigned char)(BD_DONE | BD_INTR | BD_WRAP), + (unsigned short)(sizeof(contextData)/4), + buf, + NULL); +#else + + local_bd_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + + + + + iapi_SetBufferDescriptor( &local_bd_p[0], + C0_SETDM, + (unsigned char)(BD_DONE | BD_INTR | BD_WRAP|BD_EXTD), + (unsigned short)(sizeof(contextData)/4), + buf, + (void *)(2048+(sizeof(contextData)/4)*channel)); +#endif + /* Send */ + iapi_lowStartChannel( cd_p->channelNumber ); + iapi_lowSynchChannel( cd_p->channelNumber ); + +} + +/* ***************************************************************************/ +/**Associate specified channel with the script starting at the + * specified address. Channel 0 command is used to load the set-up context + * for the channel. The address used must be generated by the GUI tool + * used to create RAM images for SDMA. + * + * Algorithm:\n + * - Set-up and load the context. + * + * @param *cd_p pointer to the channel descriptor of the channel + * @param *data_p: pointer to the data identifying the script to be associated + * with the channel + * + * @return + * - IAPI_SUCCESS : OK + * - -iapi_errno : operation failed, return negated value of iapi_errno + */ + +int +iapi_lowAssignScript(channelDescriptor * cd_p, script_data * data_p) +{ + contextData * chContext; /* context to be loaded for the channel */ + channelDescriptor * cd0_p; /* pointer to channel descriptor of channel 0*/ + int result = IAPI_SUCCESS; + + /*Verify passed data*/ + if(cd_p == NULL || data_p == NULL) + { + result = IAPI_ERR_INVALID_PARAMETER; + iapi_errno = result; + return -result; + } + + /* Allocate context and initialize PC to required script start adress*/ + chContext = (contextData *) MALLOC(sizeof(contextData), SDMA_ERAM); + if (chContext == NULL) + { + result = IAPI_ERR_B_ALLOC_FAILED | cd_p->channelNumber; + iapi_errno = result; + return -result; + } + + iapi_memset(chContext, 0x00, sizeof(contextData)); + chContext->channelState.pc = data_p->load_address; + + /* Send by context the event mask,base address for peripheral + * and watermark level + */ + chContext->gReg[0] = data_p->event_mask2; + chContext->gReg[1] = data_p->event_mask1; + chContext->gReg[6] = data_p->shp_addr; + chContext->gReg[7] = data_p->wml; + + /* Set transmited data to the CD*/ + cd_p->watermarkLevel = data_p->wml; + cd_p->eventMask1 = data_p->event_mask1; + cd_p->eventMask2 = data_p->event_mask2; + + /* Get the cd0_p*/ + cd0_p = (cd_p->ccb_ptr - cd_p->channelNumber)->channelDescriptor; + + /*load the context*/ + iapi_lowSetContext(cd0_p, chContext, cd_p->channelNumber); + + /* release allocated memory*/ + FREE(chContext); + + return IAPI_SUCCESS; +} + +/* ***************************************************************************/ +/** Set the channels to be triggered by an event. The for every channel that + *must be triggered by the event, the corresponding bit from channel_map + *parameter must be set to 1. (e.g. for the event to trigger channels 31 and + *0 one must pass 0x80000001) + * + * + * Algorithm:\n + * - Update the register from Channel Enable RAM with the channel_map + * + * @param event event for which to set the channel association + * @param channel_map channels to be triggered by event. Put the corresponding + * bit from this 32-bit value to 1 for every channel that should be + * triggered by the event. + * + * @return + * - IAPI_SUCCESS : OK + * - -iapi_errno : operation failed, return negated value of iapi_errno + */ +int +iapi_lowSetChannelEventMapping(unsigned char event, unsigned long channel_map) +{ + volatile unsigned long * channelEnableMatx; + int result = IAPI_SUCCESS; + + /* Check validity of event*/ + if (event < EVENTS_NUM) + { + channelEnableMatx = &SDMA_CHNENBL_0; + channelEnableMatx[event] |= channel_map; + return result; + } + else + { + result = IAPI_ERR_INVALID_PARAMETER | event; + iapi_errno = result; + return -result; + } +} + +#endif /* MCU */ --- linux-2.6.28.orig/arch/arm/plat-mxc/sdma/iapi/src/iapiHigh.c +++ linux-2.6.28/arch/arm/plat-mxc/sdma/iapi/src/iapiHigh.c @@ -0,0 +1,2798 @@ +/****************************************************************************** + * + * Copyright 2007-2008 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 + * + ****************************************************************************** + * + * File: iapiHigh.c + * + * $Id iapiHigh.c $ + * + * Description: + * This library is written in C to guarantee functionality and integrity in + * the usage of SDMA virtual DMA channels. This API (Application Programming + * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE + * fashion. + * These are the HIGH level functions of the I.API. + * + * + * / + * + * $Log iapiHigh.c $ + * + *****************************************************************************/ + +/* **************************************************************************** + * Include File Section + *****************************************************************************/ +#include +#include + +#include "epm.h" +#include "iapi.h" + +/* **************************************************************************** + * External Reference Section (for compatibility with already developed code) + *****************************************************************************/ +static void iapi_read_ipcv2_callback(struct iapi_channelDescriptor* cd_p, void* data); + +/* **************************************************************************** + * Global Variable Section + *****************************************************************************/ +#define MAX_CHANNEL 32 + +static dataNodeDescriptor* dnd_read_control_struct[MAX_CHANNEL]; + +/* MASK to get Nullify all the bits of Status in Data Node descriptor apart from L, E and D*/ + +#define GET_LED_MASK 0xE0 + +/*Table defines mapping of Data Node Descriptor to Buffer Descriptor status*/ + +static unsigned char dnd_2_bd_status[]= +{ +0x85, /*00 L = 0, E = 0, D = 0*/ +0x00, /*01*/ +0x00, /*02*/ +0x00, /*03*/ +0x00, /*04*/ +0x00, /*05*/ +0x00, /*06*/ +0x00, /*07*/ +0x00, /*08*/ +0x00, /*09*/ +0x00, /*0A*/ +0x00, /*0B*/ +0x00, /*0C*/ +0x00, /*0D*/ +0x00, /*0E*/ +0x00, /*0F*/ +0x00, /*10*/ +0x00,/*11*/ +0x00,/*12*/ +0x00,/*13*/ +0x00,/*14*/ +0x00,/*15*/ +0x00,/*16*/ +0x00,/*17*/ +0x00,/*18*/ +0x00,/*19*/ +0x00,/*1A*/ +0x00,/*1B*/ +0x00,/*1C*/ +0x00,/*1D*/ +0x00,/*1E*/ +0x00,/*1F*/ +0x84,/*20 L = 0, E = 0, D = 1 */ +0x00,/*21*/ +0x00,/*22*/ +0x00,/*23*/ +0x00,/*24*/ +0x00,/*25*/ +0x00,/*26*/ +0x00,/*27*/ +0x00,/*28*/ +0x00,/*29*/ +0x00,/*2A*/ +0x00,/*2B*/ +0x00,/*2C*/ +0x00,/*2D*/ +0x00,/*2E*/ +0x00,/*2F*/ +0x00,/*30*/ +0x00,/*31*/ +0x00,/*32*/ +0x00,/*33*/ +0x00,/*34*/ +0x00,/*35*/ +0x00,/*36*/ +0x00,/*37*/ +0x00,/*38*/ +0x00,/*39*/ +0x00,/*3A*/ +0x00,/*3B*/ +0x00,/*3C*/ +0x00,/*3D*/ +0x00,/*3E*/ +0x00,/*3F*/ +0xAB,/*40 L = 0, E = 1, D = 0*/ +0x00,/*41*/ +0x00,/*42*/ +0x00,/*43*/ +0x00,/*44*/ +0x00,/*45*/ +0x00,/*46*/ +0x00,/*47*/ +0x00,/*48*/ +0x00,/*49*/ +0x00,/*4A*/ +0x00,/*4B*/ +0x00,/*4C*/ +0x00,/*4D*/ +0x00,/*4E*/ +0x00,/*4F*/ +0x00,/*50*/ +0x00,/*51*/ +0x00,/*52*/ +0x00,/*53*/ +0x00,/*54*/ +0x00,/*55*/ +0x00,/*56*/ +0x00,/*57*/ +0x00,/*58*/ +0x00,/*59*/ +0x00,/*5A*/ +0x00,/*5B*/ +0x00,/*5C*/ +0x00,/*5D*/ +0x00,/*5E*/ +0x00,/*5F*/ +0xAA,/*60 L = 0, E = 1, D = 1*/ +0x00,/*61*/ +0x00,/*62*/ +0x00,/*63*/ +0x00,/*64*/ +0x00,/*65*/ +0x00,/*66*/ +0x00,/*67*/ +0x00,/*68*/ +0x00,/*69*/ +0x00,/*6A*/ +0x00,/*6B*/ +0x00,/*6C*/ +0x00,/*6D*/ +0x00,/*6E*/ +0x00,/*6F*/ +0x00,/*70*/ +0x00,/*71*/ +0x00,/*72*/ +0x00,/*73*/ +0x00,/*74*/ +0x00,/*75*/ +0x00,/*76*/ +0x00,/*77*/ +0x00,/*78*/ +0x00,/*79*/ +0x00,/*7A*/ +0x00,/*7B*/ +0x00,/*7C*/ +0x00,/*7D*/ +0x00,/*7E*/ +0x00,/*7F*/ +0xC5,/*80 L = 1, E = 0, D = 0*/ +0x00,/*81*/ +0x00,/*82*/ +0x00,/*83*/ +0x00,/*84*/ +0x00,/*85*/ +0x00,/*86*/ +0x00,/*87*/ +0x00,/*88*/ +0x00,/*89*/ +0x00,/*8A*/ +0x00,/*8B*/ +0x00,/*8C*/ +0x00,/*8D*/ +0x00,/*8E*/ +0x00,/*8F*/ +0x00,/*90*/ +0x00,/*91*/ +0x00,/*92*/ +0x00,/*93*/ +0x00,/*94*/ +0x00,/*95*/ +0x00,/*96*/ +0x00,/*97*/ +0x00,/*98*/ +0x00,/*99*/ +0x00,/*9A*/ +0x00,/*9B*/ +0x00,/*9C*/ +0x00,/*9D*/ +0x00,/*9E*/ +0x00,/*9F*/ +0xC4,/*A0 L = 1, E = 0, D = 1*/ +0x00,/*A1*/ +0x00,/*A2*/ +0x00,/*A3*/ +0x00,/*A4*/ +0x00,/*A5*/ +0x00,/*A6*/ +0x00,/*A7*/ +0x00,/*A8*/ +0x00,/*A9*/ +0x00,/*AA*/ +0x00,/*AB*/ +0x00,/*AC*/ +0x00,/*AD*/ +0x00,/*AE*/ +0x00,/*AF*/ +0x00,/*B0*/ +0x00,/*B1*/ +0x00,/*B2*/ +0x00,/*B3*/ +0x00,/*B4*/ +0x00,/*B5*/ +0x00,/*B6*/ +0x00,/*B7*/ +0x00,/*B8*/ +0x00,/*B9*/ +0x00,/*BA*/ +0x00,/*BB*/ +0x00,/*BC*/ +0x00,/*BD*/ +0x00,/*BE*/ +0x00,/*BF*/ +0xEB,/*C0 L = 1, E = 1, D = 0*/ +0x00,/*C1*/ +0x00,/*C2*/ +0x00,/*C3*/ +0x00,/*C4*/ +0x00,/*C5*/ +0x00,/*C6*/ +0x00,/*C7*/ +0x00,/*C8*/ +0x00,/*C9*/ +0x00,/*CA*/ +0x00,/*CB*/ +0x00,/*CC*/ +0x00,/*CD*/ +0x00,/*CE*/ +0x00,/*CF*/ +0x00,/*D0*/ +0x00,/*D1*/ +0x00,/*D2*/ +0x00,/*D3*/ +0x00,/*D4*/ +0x00,/*D5*/ +0x00,/*D6*/ +0x00,/*D7*/ +0x00,/*D8*/ +0x00,/*D9*/ +0x00,/*DA*/ +0x00,/*DB*/ +0x00,/*DC*/ +0x00,/*DD*/ +0x00,/*DE*/ +0x00,/*DF*/ +0xEA,/*E0 L = 1, E = 1, D = 1*/ +0x00,/*E1*/ +0x00,/*E2*/ +0x00,/*E3*/ +0x00,/*E4*/ +0x00,/*E5*/ +0x00,/*E6*/ +0x00,/*E7*/ +0x00,/*E8*/ +0x00,/*E9*/ +0x00,/*EA*/ +0x00,/*EB*/ +0x00,/*EC*/ +0x00,/*ED*/ +0x00,/*EE*/ +0x00,/*EF*/ +0x00,/*F0*/ +0x00,/*F1*/ +0x00,/*F2*/ +0x00,/*F3*/ +0x00,/*F4*/ +0x00,/*F5*/ +0x00,/*F6*/ +0x00,/*F7*/ +0x00,/*F8*/ +0x00,/*F9*/ +0x00,/*FA*/ +0x00,/*FB*/ +0x00,/*FC*/ +0x00,/*FD*/ +0x00,/*FE*/ +0x00/*FF*/ +}; +/* **************************************************************************** + * Function Section + *****************************************************************************/ + +/* ***************************************************************************/ +/**Opens an SDMA channel to be used by the library. + * + * Algorithm:\n + * + * - Check if initialization is necessary. + * - Check that user initialized OS dependant functions. + * - Test validity of input parameters + * - Check whole channel control block data structure + * - Finish initializations (tables with default values) + * - Initialize channel 0 is dedicated to communications with SDMA + * - Check channel control block definition + * - if the channel descriptor is not initialized, initialize it with + * the default value + * - If buffer descriptor already allocated, exit with iapi_errno filled + * complete the lowest bits with the number of 'D' bits set + * - Buffer Descriptors allocation + * - Channel's configuration properties (mcu side only) + * - read/write direction => enable/disable channel setting + * + * @param *cd_p -If channelNumber is 0, it is pointer to channel descriptor for the channnel 0 to be opened and + has default values. + * For other channels,this function should be called after channel 0 has been opened, and it is channel descriptor for + channel 0.Must be allocated. + * @param channelNumber channel to be opened + * + * @return + * - IAPI_SUCCESS : OK + * - -iapi_errno : close failed, return negated value of iapi_errno + */ +int +iapi_Open (channelDescriptor * cd_p, unsigned char channelNumber) +{ + channelControlBlock * ccb_p; + channelControlBlock * local_ccb_p; + channelDescriptor * local_cd_p; + bufferDescriptor * bd_p; + unsigned char index = 0; + int result = IAPI_SUCCESS; +#ifdef MCU + volatile unsigned long * channelPriorityMatx; +#endif /* MCU */ + + + /* + * 1. Check if initialization is necessary + */ + if (cd_p == NULL){ + result = IAPI_ERR_CD_UNINITIALIZED | + IAPI_ERR_CH_AVAILABLE | channelNumber; + iapi_errno = result; + return -result; + } + + /* Verify these functions every time*/ + if((iapi_GetChannel == NULL)||(iapi_ReleaseChannel == NULL)) + { + result = IAPI_ERR_NO_OS_FN | channelNumber; + iapi_errno = result; + return -result; + } + + /* Try to aquire channel*/ + if(iapi_GetChannel(channelNumber) != 0) + { + result = IAPI_ERR_CH_IN_USE | channelNumber; + iapi_errno = result; + return -result; + } + + if (channelNumber == 0 && cd_p->ccb_ptr == NULL){ + /* Verify that the user initialized all OS dependant functions required + * by the library. + */ + if((iapi_Malloc == NULL)||(iapi_Free == NULL)||(iapi_Virt2Phys == NULL)|| + (iapi_Phys2Virt == NULL)||(iapi_GotoSleep == NULL)|| + (iapi_WakeUp == NULL)||(iapi_InitSleep == NULL)||(iapi_memset == NULL)|| + (iapi_memcpy == NULL)) + { + result = IAPI_ERR_NO_OS_FN | channelNumber; + iapi_errno = result; + iapi_ReleaseChannel(channelNumber); + return -result; + } + /* Whole channel control block data structure */ + ccb_p = (channelControlBlock *) + MALLOC(CH_NUM*sizeof(channelControlBlock), SDMA_IRAM); + if (ccb_p == NULL){ + result = IAPI_ERR_CCB_ALLOC_FAILED | + IAPI_ERR_CH_AVAILABLE | channelNumber; + iapi_errno = result; + iapi_ReleaseChannel(channelNumber); + return -result; + } + /* Zero-out the CCB structures array just allocated*/ + iapi_memset(ccb_p, 0x00, CH_NUM*sizeof(channelControlBlock)); + /* Save the address of the CCB structures array*/ + iapi_CCBHead = ccb_p; + + cd_p->ccb_ptr = (struct iapi_channelControlBlock *)ccb_p; + ccb_p->channelDescriptor = cd_p; +#ifdef MCU + /* finish initializations */ + iapi_InitChannelTables(); +#endif /* MCU */ + /* Channel 0 is dedicated to communications with SDMA */ + cd_p->ownership = ((DONT_OWN_CHANNEL << CH_OWNSHP_OFFSET_EVT ) | + ( OWN_CHANNEL << CH_OWNSHP_OFFSET_MCU ) | + (DONT_OWN_CHANNEL << CH_OWNSHP_OFFSET_DSP )); + cd_p->bufferDescNumber = 1; + } + + /* + * 2. Check channel control block + */ + ccb_p = cd_p->ccb_ptr; + if (ccb_p == NULL){ + result = IAPI_ERR_NO_CCB_DEFINED | IAPI_ERR_CH_AVAILABLE|channelNumber; + iapi_errno = result; + iapi_ReleaseChannel(channelNumber); + return -result; + } + + /* Control block & Descriptor associated with the channel being worked on */ + local_ccb_p = &ccb_p[channelNumber]; + local_cd_p = ccb_p[channelNumber].channelDescriptor; + + /* If the channel is not initialized, initialize it with the default value */ + if (local_cd_p == NULL){ + result = iapi_AllocChannelDesc (&local_cd_p, channelNumber); + if ( result!= IAPI_SUCCESS) + { + iapi_ReleaseChannel(channelNumber); + return result; //is allready negated from iapi_AllocChannelDesc + } + + local_cd_p->ccb_ptr = (struct iapi_channelControlBlock *)local_ccb_p; + local_ccb_p->channelDescriptor = local_cd_p; + } + + /* + * 3. If buffer descriptor already allocated, exit with iapi_errno filled + */ + if ( local_ccb_p->baseBDptr != NULL ){ + bd_p = (bufferDescriptor *)iapi_Phys2Virt(local_ccb_p->baseBDptr); + result = IAPI_ERR_BD_ALLOCATED; + for (index=1 ; index< local_cd_p->bufferDescNumber ; index++){ + if ((bd_p->mode.status & BD_DONE) == BD_DONE){ + /* complete the lowest bits with the number of 'D' bits set */ + result++; + } + bd_p++; + } + iapi_errno = result; + iapi_ReleaseChannel(channelNumber); + return -result; + } + + /* + * 4. Buffer Descriptors allocation + */ + iapi_InitializeMemory(local_ccb_p); + +#ifdef MCU + /* + * 5. Channel's configuration properties (mcu side only) + */ + iapi_ChannelConfig( channelNumber, + ( local_cd_p->ownership >> CH_OWNSHP_OFFSET_EVT ) & 1UL, + ( local_cd_p->ownership >> CH_OWNSHP_OFFSET_MCU ) & 1UL, + ( local_cd_p->ownership >> CH_OWNSHP_OFFSET_DSP ) & 1UL); +#endif /* MCU */ + + /* Setting interrupt handling */ + iapi_ChangeCallbackISR(local_cd_p, local_cd_p->callbackISR_ptr); + + /* Call initialization fn for polling synch on this channel*/ + INIT_SLEEP(channelNumber); + + /* No user arg pointer yet*/ + userArgTable[cd_p->channelNumber]= NULL; + + /* + * 6. read/write direction => enable/disable channel + */ +#ifdef MCU + channelPriorityMatx = &SDMA_CHNPRI_0; + channelPriorityMatx[channelNumber] = 1; +#endif /* MCU */ + + local_ccb_p->status.openedInit = TRUE; + iapi_ReleaseChannel(channelNumber); + return IAPI_SUCCESS; +} + +/* ***************************************************************************/ +/** Attempts to read nbyte from the data buffer descriptor associated with the + * channel channelNumber, into the user's data buffer pointed to by buf. + * + * Algorithm:\n + * - Check data structures are properly initialized: + * - Channel descriptor validity + * - Control block & Descriptor associated with the channel being worked on + * - Check initialization has been done for trusted channels + * - If transfer data size is used, check validity of combination transfer + * size/requested bytes + * - Set the 'D' done bits on all buffer descriptors + * - Starting of the channel + * - Synchronization mechanism handling: + * - for callback: just exit function + * - for polling: call the synchronization function then read data from + * buffer until either nbyte parameter is reached or all buffer descriptors + * have been processed. + * + * Notes:\n + * 1) Virtual DMA SDMA channels are unidirectional, an iapi_Read authorized + * on a channel means that we are expecting to receive from the SDMA. The + * meaning of an interrupt received from the SDMA is therefore that the + * data has been copied from the SDMA to the host's data buffers and is + * already passed on upper layers of the application.\n + * + * @param *cd_p chanenl descriptor for the channel to read from + * @param *buf buffer to receive the data + * @param nbyte number of bytes to read from channel + * + * @return + * - number of bytes read + * - -iapi_errno : in case of failure return negated value of iapi_errno + */ +int +iapi_Read (channelDescriptor * cd_p, void * buf, unsigned short nbyte) +{ + int index = 0; + int readBytes; + int toRead; + int result = IAPI_SUCCESS; + unsigned int copyFinished; + int bufsize; + bufferDescriptor * bd_p; + channelControlBlock * ccb_p; + unsigned char * local_buf; + unsigned char chNum; + unsigned char div; + + iapi_errno = IAPI_ERR_NO_ERROR; + + /* + * 1. Check data structures are properly initialized + */ + /* Channel descriptor validity */ + if (cd_p == NULL){ + result = IAPI_ERR_CD_UNINITIALIZED; + iapi_errno = result; + return -result; + } + + /* Channel control block validity */ + if (cd_p->ccb_ptr == NULL){ + result = IAPI_ERR_CCB_UNINITIALIZED; + iapi_errno = result; + return -result; + } + + /* Control block & Descriptor associated with the channel being worked on */ + chNum = cd_p->channelNumber; + ccb_p = cd_p->ccb_ptr; + + /* Try to aquire channel*/ + if(iapi_GetChannel(chNum) != 0) + { + result = IAPI_ERR_CH_IN_USE | chNum; + iapi_errno = result; + return -result; + } + + /* Check if channel is already opened/initialized */ + if (ccb_p->status.openedInit == FALSE) { + result = IAPI_ERR_CHANNEL_UNINITIALIZED | IAPI_ERR_CH_AVAILABLE | chNum; + iapi_errno = result; + iapi_ReleaseChannel(chNum); + return -result; + } + + /* Buffer descriptor validity */ + bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr); + if (bd_p == NULL ){ + result = IAPI_ERR_BD_UNINITIALIZED | IAPI_ERR_CH_AVAILABLE | chNum; + iapi_errno = result; + iapi_ReleaseChannel(chNum); + return -result; + } + + + /* Check initialization has been done for trusted channels */ + if (cd_p->trust == TRUE) { + bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr); + for(index=0 ; index < cd_p->bufferDescNumber ; index++){ + if ((bd_p->bufferAddr == NULL) || (bd_p->mode.count == 0)){ + result = IAPI_ERR_BD_UNINITIALIZED | IAPI_ERR_CH_AVAILABLE | chNum; + iapi_errno = result; + iapi_ReleaseChannel(chNum); + return -result; + } + bd_p++; + } + } + + bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr); + /*If transfer data size is used, check that the required read length is + * divisible by transfer data size expressed in bytes + */ + if(cd_p->useDataSize) + { + /*Check for divisibility only if data size different then 8bit*/ + if(cd_p->dataSize != TRANSFER_8BIT) + { + switch(cd_p->dataSize) + { + case TRANSFER_32BIT: + div = 4; + break; + case TRANSFER_16BIT: + div = 2; + break; + case TRANSFER_24BIT: + div = 3; + break; + /*we should not get to default*/ + default: + result = IAPI_ERR_INVALID_PARAMETER | chNum; + iapi_errno = result; + iapi_ReleaseChannel(chNum); + return -result; + } + /*check the total number of bytes requested*/ + if((nbyte % div) != 0) + { + result = IAPI_ERR_INVALID_PARAMETER | chNum; + iapi_errno = result; + iapi_ReleaseChannel(chNum); + return -result; + } + /*now check the length of every BD*/ + for(index=0 ; index < cd_p->bufferDescNumber ; index++) + { + if((bd_p->mode.count % div) != 0) + { + result = IAPI_ERR_INVALID_PARAMETER | chNum; + iapi_errno = result; + iapi_ReleaseChannel(chNum); + return -result; + } + bd_p++; + } + } + } + + /* + * 2. Set the 'D' done bits on all buffer descriptors + */ + bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr); + for (index=0 ; index < cd_p->bufferDescNumber ; index++) { + bd_p->mode.status |= BD_DONE; + bd_p++; + } + + /* + * 3. Starting of the channel + */ + iapi_lowStartChannel (chNum); + ccb_p->status.execute = TRUE; + readBytes = 0; + + /* + * 4. Synchronization mechanism handling + */ + if( cd_p->callbackSynch == DEFAULT_POLL){ + iapi_SynchChannel(chNum); + + bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr); + toRead = nbyte; + copyFinished = FALSE; + local_buf = (unsigned char *)buf; + + /* + * Check the 'RROR' bit on all buffer descriptors, set error number + * and return IAPI_FAILURE if set. + */ + for (index=0 ; index < cd_p->bufferDescNumber ; index++) + { + if(bd_p->mode.status & BD_RROR) + { + result = IAPI_ERR_RROR_BIT_READ | chNum; + iapi_errno = result; + iapi_ReleaseChannel(chNum); + return -result; + } + bd_p++; + } + + + /* + * 5. Read loop + */ + + bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr); + while (!copyFinished) + { + if (!(bd_p->mode.status & BD_DONE)) + { + if (cd_p->trust == FALSE) { + bufsize = cd_p->bufferSize; + } else { + bufsize = bd_p->mode.count; + } + /*if L bit is set, read only "count" bytes and exit the loop*/ + if(bd_p->mode.status & BD_LAST) + { + bufsize = bd_p->mode.count; + copyFinished = TRUE; + } + if (toRead > bufsize) + { + if (cd_p->trust == FALSE) + { + iapi_memcpy(local_buf, iapi_Phys2Virt(bd_p->bufferAddr), bufsize); + local_buf += bufsize; + } + readBytes += bufsize; + toRead -= bufsize; + /*advance bd_p only if bit L is not set. The loop will exit anyway.*/ + if(!(bd_p->mode.status & BD_LAST)) + { + if (bd_p->mode.status & BD_WRAP) + { + bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr); + } + else if(((bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr) + + (cd_p->bufferDescNumber - 1)*sizeof(bufferDescriptor)) != bd_p) + { + bd_p++; + } + else + { + /* finished here : end of buffer descriptors */ + copyFinished = TRUE; + } + } + } + else + { + if (cd_p->trust == FALSE) + { + iapi_memcpy(local_buf, iapi_Phys2Virt(bd_p->bufferAddr), toRead); + local_buf += toRead; + } + readBytes += toRead; + toRead = 0; + /* finished successfully : readBytes = nbytes */ + copyFinished = TRUE; + } + } + else + { + /* finished here : buffer not already done*/ + copyFinished = TRUE; + } + } + iapi_ReleaseChannel(chNum); + } + + /* + *If synchronization type is callback, the user of I.API must + *release the channel + */ + return readBytes; +} + +/* ***************************************************************************/ +/*Attempts to write nbyte from the buffer pointed to by buf to the channel + * data buffers associated with the opened channel number channelNumber + * + * Algorithm:\n + * + * - Check data structures are properly initialized: + * - Channel descriptor validity + * - Channel control block validity + * - Buffer descriptor validity + * - If transfer data size is used, check validity of combination transfer + * size/requested bytes + * - Write loop\n + * Write occurs in the buffer acceded form buffer descriptor and continues + * to the "next" buffer which can be:\n + * -# the last BD of the ring so re-start from beginning\n + * -# the last BD of the BD array but no ring so finish\n + * -# (general case) the next BD in the BD array\n + * And copy continues until data fit in the current buffer or the nbyte + * parameter is reached. + * - Starting of the channel + * + * Notes:\n + * 1) Virtual DMA SDMA channels are unidirectionnal, an iapi_Write authorized + * on a channel means that we are expecting to send to the SDMA. The + * meaning of an interrupt received from the SDMA is therfore that the + * data has been delivered to the SDMA. + * + * @param *cd_p chanenl descriptor for the channel to write to + * @param *buf buffer with data to be written + * @param nbyte number of bytes to write to channel + * + * @return + * - number of bytes written + * - -iapi_errno if failure + */ +int +iapi_Write (channelDescriptor * cd_p, void * buf, unsigned short nbyte) +{ + unsigned int writtenBytes = 0; + unsigned int toWrite; + int result = IAPI_SUCCESS; + unsigned int copyFinished; + unsigned int buffsize; + unsigned int index = 0; + bufferDescriptor * bd_p; + channelControlBlock * ccb_p; + unsigned char * local_buf; + unsigned char chNum; + unsigned char div; + + iapi_errno = IAPI_ERR_NO_ERROR; + + /* + * 1. Check data structures are properly initialized + */ + /* Channel descriptor validity */ + if (cd_p == NULL){ + result = IAPI_ERR_CD_UNINITIALIZED; + iapi_errno = result; + return -result; + } + + /* Channel control block validity */ + if (cd_p->ccb_ptr == NULL){ + result = IAPI_ERR_CCB_UNINITIALIZED; + iapi_errno = result; + return -result; + } + + /* Control block & Descriptpor associated with the channel being worked on */ + chNum = cd_p->channelNumber; + ccb_p = cd_p->ccb_ptr; + + /* Try to aquire channel*/ + if(iapi_GetChannel(chNum) != 0) + { + result = IAPI_ERR_CH_IN_USE | chNum; + iapi_errno = result; + return -result; + } + + /* Buffer descriptor validity */ + bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr); + if (bd_p == NULL ){ + result = IAPI_ERR_BD_UNINITIALIZED | IAPI_ERR_CH_AVAILABLE | chNum; + iapi_errno = result; + iapi_ReleaseChannel(chNum); + return -result; + } + + /* Check initialization has been done for trusted channels */ + if (cd_p->trust == TRUE) { + bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr); + for(index=0 ; index < cd_p->bufferDescNumber ; index++){ + if ((bd_p->bufferAddr == NULL) || (bd_p->mode.count == 0)){ + result = IAPI_ERR_BD_UNINITIALIZED | IAPI_ERR_CH_AVAILABLE | chNum; + iapi_errno = result; + iapi_ReleaseChannel(chNum); + return -result; + } + bd_p++; + } + } + + + bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr); + /*If transfer data size is used, check that the required write length is + * divisible by transfer data size expressed in bytes + */ + if(cd_p->useDataSize) + { + /*Check for divisibility only if data size different then 8bit*/ + if(cd_p->dataSize != TRANSFER_8BIT) + { + switch(cd_p->dataSize) + { + case TRANSFER_32BIT: + div = 4; + break; + case TRANSFER_16BIT: + div = 2; + break; + case TRANSFER_24BIT: + div = 3; + break; + /*we should not get to default*/ + default: + result = IAPI_ERR_INVALID_PARAMETER | chNum; + iapi_errno = result; + iapi_ReleaseChannel(chNum); + return -result; + } + /*check the total number of bytes requested*/ + if((nbyte % div) != 0) + { + result = IAPI_ERR_INVALID_PARAMETER | chNum; + iapi_errno = result; + iapi_ReleaseChannel(chNum); + return -result; + } + /*now check the length of every BD*/ + for(index=0 ; index < cd_p->bufferDescNumber ; index++) + { + if((bd_p->mode.count % div) != 0) + { + result = IAPI_ERR_INVALID_PARAMETER | chNum; + iapi_errno = result; + iapi_ReleaseChannel(chNum); + return -result; + } + bd_p++; + } + } + } + + /* + * 2. Write loop + */ + + local_buf = (unsigned char *)buf; + toWrite = nbyte; + copyFinished = FALSE; + bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr); + + while (!copyFinished){ + + /* variable buffsize contains the nb of bytes that the SDMA will transfer at each pass of the while loop*/ + + /* in NON trusted mode, buffsize is copied from Channel descriptor bufferSize (same size for all transfers) */ + if (cd_p->trust == FALSE) { + buffsize = cd_p->bufferSize; + } + /* in TRUSTED mode, it's up to the user to specify the size of each buffer thru an IoCtl call */ + /* This IoCtl has directly modified the bd_p->mode.count */ + /* therefore, buffersize is copied from the bd_p->mode.count */ + else { + buffsize = bd_p->mode.count; + } + + /* in any mode (trusted or non trusted), the transfer size must be overridden by */ + /* "toWrite" when there is less remaining bytes to transfer than the current buffer size */ + if (toWrite < buffsize) { + buffsize = toWrite; + } + + + if (!(bd_p->mode.status & BD_DONE)){ + /* More data to write than a single buffer can contain */ + if (cd_p->trust == FALSE ){ + iapi_memcpy(iapi_Phys2Virt(bd_p->bufferAddr), local_buf, buffsize); + local_buf += buffsize; + } + + /* update the BD count that will be used by the SDMA to transfer the proper nb of bytes */ + bd_p->mode.count = buffsize; + + bd_p->mode.status |= BD_DONE; + writtenBytes += buffsize; + toWrite -= buffsize; + /* Prepares access to the "next" buffer */ + /* - case 1 - finished successfully : writtenBytes = nbytes */ + if (toWrite == 0) { + copyFinished = TRUE; + } + /* - case 2 - Last BD and WRAP bit set so re-start from beginning */ + /*else if ((bd_p->mode.status & BD_WRAP)){ + bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr); + }*/ + /* - case 3 - Last BD of the BD but nor ring*/ + else if (((bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr) + + (cd_p->bufferDescNumber - 1) * sizeof(bufferDescriptor)) == bd_p){ + copyFinished = TRUE; + } + /* - case 4 - general : next BD in the BD array */ + else { + bd_p++; + } + + } else { + /* finished here : buffer not already done */ + copyFinished = TRUE; + } + } + + ccb_p->currentBDptr = ccb_p->baseBDptr; + + /* + * 3. Starting of the channel + */ + iapi_lowStartChannel(chNum); + ccb_p->status.execute = TRUE; + + if( cd_p->callbackSynch == DEFAULT_POLL) + { + iapi_SynchChannel(chNum); + /* + * Check the 'RROR' bit on all buffer descriptors, set error number + * and return IAPI_FAILURE if set. + */ + bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr); + for (index=0 ; index < cd_p->bufferDescNumber ; index++) + { + if(bd_p->mode.status & BD_RROR) + { + result = IAPI_ERR_RROR_BIT_WRITE | chNum; + iapi_errno = result; + iapi_ReleaseChannel(chNum); + return -result; + } + bd_p++; + } + iapi_ReleaseChannel(chNum); + } + + /* + *If synchronization type is callback, the user of I.API must + *release the channel + */ + return writtenBytes; +} + + + + +/* ***************************************************************************/ +/* This function is used to receive data from the SDMA. + * + * Algorithm:\n + * + * The data control structure would be copied to IPCv1 complied Buffer + * Descriptor Array. This array shall be allocated from non cacheable memory. + * It would then provide this buffer descriptor array as an input to SDMA using + * channel control block and then configure the Host Enable (HE) or + * DSP enable (DE) bit of SDMA for the channel used for this transfer depending + * on the source. + * + * Notes:\n + * Virtual DMA channels are unidirectional, an iapi_Write_ipcv2 authorized + * on a channel means that source processor is expecting to send to the destination + * processor. The meaning of an interrupt received from the SDMA notifies that the + * data has been delivered to the destination processor. + * + * @param *cd_p chanenl descriptor for the channel to receive from + * @param *data_control_struct_ipcv2 + + * Data Control structure: + * ------------------------- + * | Data Node Descriptor 1| + * ------------------------- + * | Data Node Descriptor 2| + * ------------------------- + * | : | + * | : | + * ------------------------- + * |Data Node Descriptor n | + * ------------------------- + * + * Data Node Descriptor (Buffer Descriptor): + *------------------------------------------------------------------------------ + *| 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 … 0| + *------------------------------------------------------------------------------ + *| L E D R R R R R |<---- Reserved ----> |<- Length-> | + *------------------------------------------------------------------------------ + *| <---------------------------- Data Ptr ----------------------------------->| + *------------------------------------------------------------------------------ + * + * L bit (LAST): If set, means that this buffer of data is the last buffer of the frame + * E bit (END): If set, we reached the end of the buffers passed to the function + * D bit (DONE): Only valid on the read callback. When set, means that the buffer has been + * filled by the SDMA. + * Length: Length of data pointed by this node in bytes + * Data Ptr: Pointer to the data pointed to by this node. + * The Function Shall not be called for the same channel unless the Read callback has been + * received for channel for which it has been called already. + * + * @return + * - IAPI_SUCCESS on success, IAPI_ERROR otherwise + * + *- -iapi_errno if failure + */ + +int iapi_Read_ipcv2( channelDescriptor * cd_p, void * data_control_struct_ipcv2) +{ + channelControlBlock * ccb_p; + + +/* The Parameters passed are considered to be validated by the upper layers*/ + + bufferDescriptor_ipcv1_v2 *bd_ipcv2_p; + dataNodeDescriptor *dnd_p = (dataNodeDescriptor*)data_control_struct_ipcv2; + + ccb_p = cd_p->ccb_ptr; + iapi_errno = IAPI_ERR_NO_ERROR; + + if(ccb_p->baseBDptr == NULL) +{ + iapi_errno = IAPI_ERR_BD_UNINITIALIZED; + return -(IAPI_ERR_BD_UNINITIALIZED); +} + + ccb_p->currentBDptr = ccb_p->baseBDptr; + + /* Copy the data Node descriptor information to new BDs */ + bd_ipcv2_p = (bufferDescriptor_ipcv1_v2*)iapi_Phys2Virt(ccb_p->baseBDptr); + + while(1) + { + bd_ipcv2_p->bufferAddr = dnd_p->bufferAddr; + bd_ipcv2_p->mode.count = dnd_p->mode.count; +#ifdef MCU + bd_ipcv2_p->mode.endianness = 1; +#endif +#ifdef DSP + bd_ipcv2_p->mode.endianness = 0; +#endif + + bd_ipcv2_p->mode.status = dnd_2_bd_status[dnd_p->mode.status & GET_LED_MASK]; + + if((dnd_p->mode.status & DND_END_OF_XFER) != 0) + { + /* Break the loop at End of Transfer */ + break; + + } + bd_ipcv2_p++; + dnd_p++; + + } + /* + * Store the buffer address + */ + dnd_read_control_struct[cd_p->channelNumber] = (dataNodeDescriptor*)data_control_struct_ipcv2; + /* + * Register the Call Back + */ + + iapi_AttachCallbackISR(cd_p, iapi_read_ipcv2_callback); + + /* + * Starting of the channel + */ + iapi_lowStartChannel(cd_p->channelNumber); + ccb_p->status.execute = TRUE; + + return IAPI_SUCCESS; + +} + + +/* ***************************************************************************/ +/* + * The function is used send a group of buffers to SDMA. + * Algorithm:\n + * + * The data control structure would be copied to IPCv1 complied Buffer + * Descriptor Array. This array shall be allocated from non cacheable memory. + * It would then provide this buffer descriptor array as an input to SDMA using + * channel control block and then configure the Host Enable (HE) or + * DSP enable (DE) bit of SDMA for the channel used for this transfer depending + * on the source. + * The Function Shall not be called for the same channel unless the Read callback has been + * received for channel for which it has been called already. + * + * Notes:\n + * Virtual DMA channels are unidirectional, an iapi_Write_ipcv2 authorized + * on a channel means that source processor is expecting to send to the destination + * processor. The meaning of an interrupt received from the SDMA notifies that the + * data has been delivered to the destination processor. + * + * @param *cd_p chanenl descriptor for the channel to write to + * @param *data_control_struct_ipcv2 + + * Data Control structure: + * ------------------------- + * | Data Node Descriptor 1| + * ------------------------- + * | Data Node Descriptor 2| + * ------------------------- + * | : | + * | : | + * ------------------------- + * |Data Node Descriptor n | + * ------------------------- + * + * Data Node Descriptor (Buffer Descriptor): + *------------------------------------------------------------------------------ + *| 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 … 0| + *------------------------------------------------------------------------------ + *| L E D R R R R R |<---- Reserved ----> |<- Length-> | + *------------------------------------------------------------------------------ + *| <---------------------------- Data Ptr ----------------------------------->| + *------------------------------------------------------------------------------ + * + * L bit (LAST): If set, means that this buffer of data is the last buffer of the frame + * E bit (END): If set, we reached the end of the buffers passed to the function + * D bit (DONE): Only valid on the read callback. When set, means that the buffer has been + * filled by the SDMA. + * Length: Length of data pointed by this node in bytes + * Data Ptr: Pointer to the data pointed to by this node. + * + * + * @return + * - iapi sucess on success. + * - -iapi_errno if failure + */ + +int iapi_Write_ipcv2( channelDescriptor * cd_p, void * data_control_struct_ipcv2) +{ + + channelControlBlock * ccb_p; + +/* The Parameters passed are considered to be validated by the upper layers*/ + + bufferDescriptor_ipcv1_v2 *bd_ipcv2_p; + dataNodeDescriptor *dnd_p = (dataNodeDescriptor*)data_control_struct_ipcv2; + ccb_p = cd_p->ccb_ptr; + iapi_errno = IAPI_ERR_NO_ERROR; + + if(ccb_p->baseBDptr == NULL) +{ + iapi_errno = IAPI_ERR_BD_UNINITIALIZED; + return -(IAPI_ERR_BD_UNINITIALIZED); +} + + + ccb_p->currentBDptr = ccb_p->baseBDptr; + + bd_ipcv2_p = (bufferDescriptor_ipcv1_v2*)iapi_Phys2Virt(ccb_p->currentBDptr); + /* Copy the data Node descriptor information to new BDs */ + while(1) + { + bd_ipcv2_p->bufferAddr = dnd_p->bufferAddr; + bd_ipcv2_p->mode.count = dnd_p->mode.count; + +#ifdef MCU + bd_ipcv2_p->mode.endianness = 1; +#endif +#ifdef DSP + bd_ipcv2_p->mode.endianness = 0; +#endif + + bd_ipcv2_p->mode.status = dnd_2_bd_status[dnd_p->mode.status & GET_LED_MASK]; + + if((dnd_p->mode.status & DND_END_OF_XFER) != 0) + { + /* Break the loop at End of Transfer */ + break; + } + bd_ipcv2_p++; + dnd_p++; + + } + + /* + * Starting of the channel + */ + iapi_lowStartChannel(cd_p->channelNumber); + ccb_p->status.execute = TRUE; + + return IAPI_SUCCESS; + +} + +/* ***************************************************************************/ +/** Call back ISR for the IPCv2 Receive. + * + * Algorithm:\n + * - This would copy back the informationfrom IPCv1 BD to IPCv2 BD on + * the receiving processor + * + * @return + * - void + */ + +void iapi_read_ipcv2_callback(struct iapi_channelDescriptor* cd_p, void* data) +{ + dataNodeDescriptor *dnd_p = dnd_read_control_struct[cd_p->channelNumber];//cd_p->ccb_ptr->channelDNDBuffer; + bufferDescriptor_ipcv1_v2 *bd_ipcv2_p = (bufferDescriptor_ipcv1_v2*)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + int index = MAX_BD_NUM - 1; + + + do + { + dnd_p->mode.status = 0; + dnd_p->mode.count = bd_ipcv2_p->mode.count; + + dnd_p->mode.status |= bd_ipcv2_p->mode.status & BD_DONE ? 0x00 : DND_DONE ; + dnd_p->mode.status |= bd_ipcv2_p->mode.status & BD_IPCV2_END_OF_FRAME ? DND_END_OF_FRAME : 0x00; + dnd_p->mode.status |= bd_ipcv2_p->mode.status & BD_LAST ? DND_END_OF_XFER : 0x00; + cd_p->ccb_ptr->currentBDptr = (bufferDescriptor*)iapi_Virt2Phys(bd_ipcv2_p); + + if((bd_ipcv2_p->mode.status & BD_LAST) != 0 || + (bd_ipcv2_p->mode.status & BD_CONT) == 0 + ) + break; + dnd_p++; + bd_ipcv2_p++; + + }while(index--); + + /*Call back the Original ISR */ + cd_p->callbackISR_ptr(cd_p, data); +} + +/* ***************************************************************************/ +/**Terminates a channel. + * + * Algorithm:\n + * - Check input parameters ans data structures + * - Check that all buffes have been processed (test all 'D' bits) + * - Stop the channel execution + * - Free alocated memory structures + * - Re-instantiate default interrupt handling + * + * @param *cd_p chanenl descriptor for the channel to close + * + * @return + * - IAPI_SUCCESS : OK + * - -iapi_errno : close failed + */ +int +iapi_Close (channelDescriptor * cd_p) +{ + int index = 0; + int result = IAPI_SUCCESS; + unsigned char chNum; + bufferDescriptor * bd_p; + channelControlBlock * ccb_p; + + /* + * 1. Check input parameters ans data structures + */ + if (cd_p != NULL){ + if (cd_p->ccb_ptr != NULL) { + chNum = cd_p->channelNumber; + ccb_p = cd_p->ccb_ptr; + } else { + result = IAPI_ERR_NO_CCB_DEFINED | IAPI_ERR_CH_AVAILABLE; + iapi_errno = result; + return -result; + } + } else { + result = IAPI_ERR_CD_UNINITIALIZED | IAPI_ERR_CH_AVAILABLE; + iapi_errno = result; + return -result; + } + /* Try to aquire channel*/ + if(iapi_GetChannel(chNum) != 0) + { + result = IAPI_ERR_CH_IN_USE | chNum; + iapi_errno = result; + return -result; + } + + /* + * 2. Check that all buffes have been processed (test all 'D' bits), + * only if the forceClose bit in channel descriptor is set to FALSE + */ + bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr); + if (bd_p == NULL){ + result = IAPI_ERR_BD_UNINITIALIZED | IAPI_ERR_CH_AVAILABLE | chNum; + iapi_errno = result; + return -result; + } + if(cd_p->forceClose == FALSE) + { + for (index=cd_p->bufferDescNumber ; index>0 ; index--){ + if (bd_p->mode.status & BD_DONE){ + result = IAPI_ERR_CLOSE | IAPI_ERR_CH_AVAILABLE | chNum; + iapi_errno = result; + iapi_ReleaseChannel(chNum); + return -result; + } + bd_p++; + } + } + /*if the closing is forced,mark channel unused,set BD ownership to processor*/ + else + { + ccb_p->status.execute = FALSE; + for (index=cd_p->bufferDescNumber ; index>0 ; index--) + { + bd_p->mode.status &= ~BD_DONE; + bd_p++; + } + } + + /* + * 3. Stop the channel execution + */ + iapi_lowStopChannel(chNum); + + /* + * 4. Free alocated memory structures + */ + if (cd_p->trust == FALSE ){ + bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr); + for (index=cd_p->bufferDescNumber ; index>0 ; index--){ + FREE (iapi_Phys2Virt(bd_p->bufferAddr)); + bd_p++; + } + } + + /* + * 5. Re-instantiate default interrupt handling + */ + iapi_DetachCallbackISR (cd_p); + FREE ((bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr)); + FREE (cd_p); + ccb_p->baseBDptr = NULL; + ccb_p->currentBDptr = NULL; + ccb_p->channelDescriptor = NULL; + ccb_p->status.openedInit = FALSE; + + iapi_ReleaseChannel(chNum); + + return IAPI_SUCCESS; +} + +/* ***************************************************************************/ +/**The request argument selects the control function to be performed. + * + * Algorithm:\n + * + * - Check data structures are properly initialized: + * - Channel descriptor validity + * - Channel control block validity + * - The ctlRequest parameter contains in the lower 16 bits the control code of + * the change to be performed, and in the upper 16 bits, the BD to be + * modified if the change affects a BD od the channel. + * - Selection of the parameter to change and appropriate sanity checks: + * - Channel Descriptor: changes the pointer to the channel descriptor + * structure, the pointer to the new channel descriptor is given in the third + * argument call + * - Buffer Descriptor Number: changes the number of buffer descriptor for the + * channel + * - Buffer size: changes the size of the data buffers pointed to by the + * buffer descriptor; note that all buffer descriptors are assumed to have the + * same size for a given buffer descripotr chain + * - Blocking policy: changes the blocking policy for the read and write calls + * - Ownership: changes direction: turnaround + * - Synchronization method: changes the callback type, default or user. The* + * callback function table is set accordingly + * - Trust property: trust can only be changed through ChangeChannelDesc first + * request, this guarantees the close/open sequence for the channel + * - Callback Interrupt service routine pointer: changes the callback function + * pointer, when this method is used, to replace it with a new one + * - Channel control block pointer: not available + * - Priority: changes the channel priority directly in SDMA register + * - Watermark level: changes the value of the peripheral watermark level that + * passed to the script. The new value is passed in the third parameter call. + * - Wrap bit: changes to set to 1 the Wrap bit of the last buffer descriptor + * + * @param *cd_p channel descriptor for the channel to modify + * @param ctlRequest request control code and, if tha case, number of BD to be + * changed + * @param param parameter for the modification + * + * @return + * - IAPI_SUCCESS : OK + * - -iapi_errno : operation failed + */ +int +iapi_IoCtl (channelDescriptor * cd_p, unsigned long ctlRequest, + unsigned long param) +{ + int retvalue; + int result = IAPI_SUCCESS; + unsigned char chNum; + unsigned long clean_ctlRequest; /* lower 16 bits of the ctlRequest*/ + unsigned long bd_num; /* upper 16 bits of the ctlRequest*/ + + /* + * 1. Check data structures are properly initialized + */ + /* Channel descriptor validity */ + if (cd_p == NULL){ + result = IAPI_ERR_CD_UNINITIALIZED; + iapi_errno = result; + return -result; + } + + /* Channel control block validity */ + if (cd_p->ccb_ptr == NULL){ + result = IAPI_ERR_CCB_UNINITIALIZED; + iapi_errno = result; + return -result; + } + + /* Control block & Descriptor associated with the channel being worked on */ + chNum = cd_p->channelNumber; + + /* Remove, if exists, BD number specified in upper bits of ctlRequest*/ + clean_ctlRequest = ctlRequest & (~BD_NUM_MASK); + + /* Extract, if exists, BD number specified in upper bits of ctlRequest*/ + bd_num = (ctlRequest & BD_NUM_MASK) >> BD_NUM_OFFSET; + + /* Check that the bd_num is valid*/ + if(bd_num > cd_p->bufferDescNumber) + { + result = IAPI_ERR_INVALID_PARAMETER | chNum; + iapi_errno = result; + return -result; + } + + /*All checks OK, try to aquire channel*/ + if(iapi_GetChannel(chNum) != 0) + { + result = IAPI_ERR_CH_IN_USE | chNum; + iapi_errno = result; + return -result; + } + + /* + * 2. Selection of the parameter to change and appropriate sanity checks + */ + switch (clean_ctlRequest){ + + /* + * Channel Descriptor + * --- Changes the pointer to the channel descriptor structure: the pointer + * to the new channel descriptor is given in the third argument call. + */ + case IAPI_CHANGE_CHANDESC: + if ((void *) param == NULL) { + result = IAPI_ERR_INVALID_PARAMETER; + iapi_errno = result; + iapi_ReleaseChannel(chNum); + return -result; + } else { + channelDescriptor * chParam = (channelDescriptor *)param; + if (chParam->channelNumber != chNum){ + /* Release ch so it can be aquired by the Close fn*/ + iapi_ReleaseChannel(chNum); + result = iapi_Close(cd_p); + if (result == IAPI_SUCCESS){ + FREE((void*)cd_p); + iapi_AllocChannelDesc (&cd_p, chParam->channelNumber); + iapi_memcpy((void*)cd_p, (void*)chParam, sizeof (channelDescriptor)); + /* Channel is released allready, so Open can get the channel*/ + result = iapi_Open(cd_p, chParam->channelNumber); + if(result != IAPI_SUCCESS) + { + return result; /* error code already set in iapi_Open*/ + } + } else { + return result; /* error code already set in iapi_Close*/ + } + } else { + result = IAPI_ERR_CD_CHANGE | IAPI_ERR_CH_AVAILABLE | + cd_p->channelNumber; + iapi_ReleaseChannel(chNum); + iapi_errno = result; + return -result; + } + return IAPI_SUCCESS; + } + + /* + * Buffer Descriptor Number + * --- Changes the number of buffer descriptor for the channel. + */ + case IAPI_CHANGE_BDNUM: + result = iapi_ChangeChannelDesc(cd_p, IAPI_BUFFERDESCNUMBER, param); + iapi_ReleaseChannel(chNum); + return result; + + /* + * Buffer size + * --- Changes the size of the data buffers pointed to by the buffer + * descriptor; note that all buffer descriptors are assumed to have the + * same size for a given buffer descripotr chain. + */ + case IAPI_CHANGE_BUFFSIZE: + result = iapi_ChangeChannelDesc(cd_p, IAPI_BUFFERSIZE, param); + iapi_ReleaseChannel(chNum); + return result; + + /* + * Blocking policy + * --- Changes the blocking policy for the read and write calls. + */ + case IAPI_CHANGE_CHANBLOCK: + result = iapi_ChangeChannelDesc(cd_p, IAPI_BLOCKING, param); + iapi_ReleaseChannel(chNum); + return result; + + /* + * Ownership + * --- Changes direction: turnaround + */ + case IAPI_CHANGE_OWNERSHIP: + result = iapi_ChangeChannelDesc(cd_p, IAPI_OWNERSHIP, param); + iapi_ReleaseChannel(chNum); + return result; + + /* + * Synchronization method + * --- Changes the callback type, default or user. The callback function + * table is set accordingly. + */ + case IAPI_CHANGE_SYNCH: + result = iapi_ChangeChannelDesc(cd_p, IAPI_CALLBACKSYNCH, param); + iapi_ReleaseChannel(chNum); + return result; + + /* + * Trust property + * --- trust can only be changed through ChangeChannelDesc first request, + * this guarantees the close/open sequence for the channel. + */ + case IAPI_CHANGE_TRUST: + result = iapi_ChangeChannelDesc(cd_p, IAPI_TRUST, param); + iapi_ReleaseChannel(chNum); + return result; + + /* + * Callback Interrupt service routine pointer + * --- Cahnges the callback function pointer, when this method is used, to + * replace it with a new one. + */ + case IAPI_CHANGE_CALLBACKFUNC: + result = iapi_ChangeChannelDesc(cd_p, IAPI_CALLBACKISR_PTR, param); + iapi_ReleaseChannel(chNum); + return result; + + /* + * Channel control block pointer + * --- NA + */ + case IAPI_CHANGE_CHANCCB: + result = iapi_ChangeChannelDesc(cd_p, IAPI_CCB_PTR, param); + iapi_ReleaseChannel(chNum); + return result; + +#ifdef MCU + /* + * Priority + * --- Changes the channel priority directly in SDMA register + */ + case IAPI_CHANGE_PRIORITY: + { + volatile unsigned long * ChannelPriorities = &SDMA_CHNPRI_0; + if(param < MAX_CH_PRIORITY) + { + ChannelPriorities[ cd_p->channelNumber ] = param; + } + else + { + iapi_ReleaseChannel(chNum); + return IAPI_FAILURE; + } + } + break; +#endif /* MCU */ + + /* + * Wrap + * --- Set to 1 the wrap bit of the last buffer descriptor of the array. + * it provides the possibility to have a circular buffer structure. + */ + case IAPI_CHANGE_BDWRAP: + { + result = iapi_ChangeChannelDesc(cd_p,IAPI_BDWRAP , param); + iapi_ReleaseChannel(chNum); + return result; + } + + /* + * Watermark + * --- Changes the value of the peripheral watermark level that triggers + * a DMA request. It impacts context of the channel, therefore channel 0 + * must be started to update the context with this new value. + */ + case IAPI_CHANGE_WATERMARK: + { + result = iapi_ChangeChannelDesc(cd_p,IAPI_WML , param); + iapi_ReleaseChannel(chNum); + return result; + } + /* + * INTR + * --- Set the INTR bit on specified BD or on all BD's if SET_BIT_ALL + * is passed as parameter. + */ + case IAPI_CHANGE_SET_BDINTR: + { + bufferDescriptor * bde_p; + int j = 0; + + retvalue = IAPI_SUCCESS; + if(param == SET_BIT_ALL) + { + bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + for(j = 0; j < cd_p->bufferDescNumber; j++) + { + bde_p->mode.status |= BD_INTR; + bde_p++; + } + } + else if(param < cd_p->bufferDescNumber) + { + bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr) + + param; + bde_p->mode.status |= BD_INTR; + } + else + { + retvalue = IAPI_FAILURE; + } + iapi_ReleaseChannel(chNum); + return retvalue; + } + /* + * INTR + * --- Unset the INTR bit on specified BD or on all BD's if SET_BIT_ALL + * is passed as parameter. + */ + case IAPI_CHANGE_UNSET_BDINTR: + { + bufferDescriptor * bde_p; + + int j = 0; + + retvalue = IAPI_SUCCESS; + if(param == SET_BIT_ALL) + { + bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + for(j = 0; j < cd_p->bufferDescNumber; j++) + { + bde_p->mode.status &= ~BD_INTR; + bde_p++; + } + } + else if(param < cd_p->bufferDescNumber) + { + bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr) + + param; + bde_p->mode.status &= ~BD_INTR; + } + else + { + retvalue = IAPI_FAILURE; + } + iapi_ReleaseChannel(chNum); + return retvalue; + } +/* + * EventMask1 + * --- Changes the value of the eventMask1 + */ + case IAPI_CHANGE_EVTMASK1: + { + cd_p->eventMask1 = param; + } + break; + /* + * EventMask2 + * --- Changes the value of the eventMask2 + */ + case IAPI_CHANGE_EVTMASK2: + { + cd_p->eventMask2 = param; + } + break; + /* + * Peripheral Address + * --- Changes the value of the peripheralAddr + */ + case IAPI_CHANGE_PERIPHADDR: + { + cd_p->peripheralAddr = param; + } + break; + /* + * Cont + * --- Set the CONT bit on specified BD on all BD's if SET_BIT_ALL + * is passed as parameter. + */ + case IAPI_CHANGE_SET_BDCONT: + { + bufferDescriptor * bde_p; + int j = 0; + + retvalue = IAPI_SUCCESS; + if(param == SET_BIT_ALL) + { + bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + for(j = 0; j < cd_p->bufferDescNumber; j++) + { + bde_p->mode.status |= BD_CONT; + bde_p++; + } + } + else if(param < cd_p->bufferDescNumber) + { + bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr) + + param; + bde_p->mode.status |= BD_CONT; + } + else + { + retvalue = IAPI_FAILURE; + } + iapi_ReleaseChannel(chNum); + return retvalue; + } + /* + * Cont + * --- Unset the CONT bit on specified BD or on all BD's if SET_BIT_ALL + * is passed as parameter. + */ + case IAPI_CHANGE_UNSET_BDCONT: + { + bufferDescriptor * bde_p; + + int j = 0; + + retvalue = IAPI_SUCCESS; + if(param == SET_BIT_ALL) + { + bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + for(j = 0; j < cd_p->bufferDescNumber; j++) + { + bde_p->mode.status &= ~BD_CONT; + bde_p++; + } + } + else if(param < cd_p->bufferDescNumber) + { + bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr) + + param; + bde_p->mode.status &= ~BD_CONT; + } + else + { + retvalue = IAPI_FAILURE; + } + iapi_ReleaseChannel(chNum); + return retvalue; + } + + /* + * EXTD + * --- Set the EXTD bit on specified BD or on all BD's if SET_BIT_ALL + * is passed as parameter. + */ + case IAPI_CHANGE_SET_BDEXTD: + { + bufferDescriptor * bde_p; + int j = 0; + + retvalue = IAPI_SUCCESS; + if(param == SET_BIT_ALL) + { + bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + for(j = 0; j < cd_p->bufferDescNumber; j++) + { + bde_p->mode.status |= BD_EXTD; + bde_p++; + } + } + else if(param < cd_p->bufferDescNumber) + { + bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr) + + param; + bde_p->mode.status |= BD_EXTD; + } + else + { + retvalue = IAPI_FAILURE; + } + iapi_ReleaseChannel(chNum); + return retvalue; + } + /* + * EXTD + * --- Unset the EXTD bit on specified BD or on all BD's if SET_BIT_ALL + * is passed as parameter. + */ + case IAPI_CHANGE_UNSET_BDEXTD: + { + bufferDescriptor * bde_p; + + int j = 0; + + retvalue = IAPI_SUCCESS; + if(param == SET_BIT_ALL) + { + bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + for(j = 0; j < cd_p->bufferDescNumber; j++) + { + bde_p->mode.status &= ~BD_EXTD; + bde_p++; + } + } + else if(param < cd_p->bufferDescNumber) + { + bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr) + + param; + bde_p->mode.status &= ~BD_EXTD; + } + else + { + retvalue = IAPI_FAILURE; + } + iapi_ReleaseChannel(chNum); + return retvalue; + } + + /* + * TRANSFER SIZE to be used for this channel + * --- Set the transfer size used indicator and code for transfer size in + * the CD + */ +case IAPI_CHANGE_SET_TRANSFER_CD: + { + bufferDescriptor * bde_p; + int j = 0; + retvalue = IAPI_SUCCESS; + if((param == TRANSFER_8BIT) || (param == TRANSFER_16BIT) || + (param == TRANSFER_24BIT) || (param == TRANSFER_32BIT)) + { + cd_p->useDataSize = TRUE; + cd_p->dataSize = param; + bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + for(j = 0; j < cd_p->bufferDescNumber; j++) + { + bde_p->mode.command = param; + bde_p++; + } + } + else + { + retvalue = IAPI_FAILURE; + } + iapi_ReleaseChannel(chNum); + return retvalue; + } + + + /* + * USER_ARG + * --- Set the user selectable pointer to be received by the callback + * function, if IRQ synch is used + */ + case IAPI_CHANGE_USER_ARG: + { + userArgTable[cd_p->channelNumber]= (void*)param; + iapi_ReleaseChannel(chNum); + return IAPI_SUCCESS; + } + /* + * FORCE_CLOSE + * --- Set the forceClose bit in channelDescriptor to value passed in param. + * If this bit is TRUE, the channel in closed even if some BD are still + * owned by the SDMA. + */ + case IAPI_CHANGE_FORCE_CLOSE: + { + retvalue = IAPI_SUCCESS; + if((param == TRUE) || (param == FALSE)) + { + cd_p->forceClose = param; + } + else + { + iapi_errno = IAPI_ERR_INVALID_PARAMETER | cd_p->channelNumber; + retvalue = -iapi_errno; + } + iapi_ReleaseChannel(chNum); + return retvalue; + } + /* + * TRANSFER type + * --- Set the last 2 bits in the command field of the BD to specify the + * transfer type 8, 16, 24, or 32 bits on all BD's, allready set in the CD + */ + case IAPI_CHANGE_SET_TRANSFER: + { + bufferDescriptor * bde_p; + int j = 0; + + retvalue = IAPI_SUCCESS; + if((param == TRANSFER_8BIT)||(param == TRANSFER_16BIT)|| + (param == TRANSFER_24BIT)||(param == TRANSFER_32BIT)) + { + bde_p = cd_p->ccb_ptr->baseBDptr; + for(j = 0; j < cd_p->bufferDescNumber; j++) + { + bde_p->mode.command = param; + bde_p++; + } + } + else + { + retvalue = IAPI_FAILURE; + } + iapi_ReleaseChannel(chNum); + return retvalue; + } + /* + * BUFFER address + * --- Change buffer address in BD specified in the upper 16 bits of the + * ctlRequest. + */ + case IAPI_CHANGE_SET_BUFFERADDR: + { + bufferDescriptor * bde_p; + retvalue = IAPI_SUCCESS; + + /* Get pointer to the BD structure to change*/ + bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + bde_p+= bd_num; + + /* DO NOT translate address to physical */ + bde_p->bufferAddr = (void*)param; + + iapi_ReleaseChannel(chNum); + return retvalue; + } + /* + * BUFFER address + * --- Get the buffer address from the BD specified in the upper 16 bits of the + * ctlRequest. + */ + case IAPI_CHANGE_GET_BUFFERADDR: + { + bufferDescriptor * bde_p; + retvalue = IAPI_SUCCESS; + + /* Get pointer to the BD structure to change*/ + bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + bde_p+= bd_num; + /* Translate to virtual*/ + *((unsigned long*)param) = (unsigned long)bde_p->bufferAddr; + + iapi_ReleaseChannel(chNum); + return retvalue; + } + /* + * EXTENDED BUFFER address + * --- Change extended buffer address in BD specified in the upper 16 bits + * of the ctlRequest. + */ + case IAPI_CHANGE_SET_EXTDBUFFERADDR: + { + bufferDescriptor * bde_p; + retvalue = IAPI_SUCCESS; + + /* Get pointer to the BD structure to change*/ + bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + bde_p+= bd_num; + + /* DO NOT translate address to physical. The user might want something else + *here + */ + bde_p->extBufferAddr = (void*)param; + + iapi_ReleaseChannel(chNum); + return retvalue; + } + /* + * EXTENDED BUFFER address + * --- Get extended buffer address from the BD specified in the upper 16 bits + * of the ctlRequest. + */ + case IAPI_CHANGE_GET_EXTDBUFFERADDR: + { + bufferDescriptor * bde_p; + retvalue = IAPI_SUCCESS; + + /* Get pointer to the BD structure to change*/ + bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + bde_p+= bd_num; + + /* DO NOT translate address to vitual - user knows what is here. + */ + *((unsigned long*)param) = (unsigned long)bde_p->extBufferAddr; + + iapi_ReleaseChannel(chNum); + return retvalue; + } + /* + * COMMAND field + * --- Change command field in BD specified in the upper 16 bits of the + * ctlRequest. + */ + case IAPI_CHANGE_SET_COMMAND: + { + bufferDescriptor * bde_p; + retvalue = IAPI_SUCCESS; + + /* Get pointer to the BD structure to change*/ + bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + bde_p+= bd_num; + /* Update command field*/ + bde_p->mode.command = param; + + iapi_ReleaseChannel(chNum); + return retvalue; + } + /* + * COMMAND field + * --- Get the command field from the BD specified in the upper 16 bits + * of the ctlRequest. + */ + case IAPI_CHANGE_GET_COMMAND: + { + bufferDescriptor * bde_p; + retvalue = IAPI_SUCCESS; + + /* Get pointer to the BD structure to change*/ + bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + bde_p+= bd_num; + /* Get the command field*/ + *((unsigned long*)param) = bde_p->mode.command; + + iapi_ReleaseChannel(chNum); + return retvalue; + } + /* + * COUNT field + * --- Change count field in BD specified in the upper 16 bits of the + * ctlRequest. + */ + case IAPI_CHANGE_SET_COUNT: + { + bufferDescriptor * bde_p; + retvalue = IAPI_SUCCESS; + + /* Get pointer to the BD structure to change*/ + bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + bde_p+= bd_num; + /* Update count field*/ + bde_p->mode.count = param; + + iapi_ReleaseChannel(chNum); + return retvalue; + } + /* + * COUNT field + * --- Get the count field of the BD specified in the upper 16 bits of the + * ctlRequest. + */ + case IAPI_CHANGE_GET_COUNT: + { + bufferDescriptor * bde_p; + retvalue = IAPI_SUCCESS; + + /* Get pointer to the BD structure to change*/ + bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + bde_p+= bd_num; + /* Update count field*/ + *((unsigned long*)param) = bde_p->mode.count; + + iapi_ReleaseChannel(chNum); + return retvalue; + } + /* + * STATUS field + * --- Change status field in BD specified in the upper 16 bits of the + * ctlRequest. + */ + case IAPI_CHANGE_SET_STATUS: + { + bufferDescriptor * bde_p; + retvalue = IAPI_SUCCESS; + + /* Get pointer to the BD structure to change*/ + bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + bde_p+= bd_num; + /* Update status field*/ + bde_p->mode.status = param; + + iapi_ReleaseChannel(chNum); + return retvalue; + } + /* + * STATUS field + * --- Get the status field of the BD specified in the upper 16 bits + * of the ctlRequest. + */ + case IAPI_CHANGE_GET_STATUS: + { + bufferDescriptor * bde_p; + retvalue = IAPI_SUCCESS; + + /* Get pointer to the BD structure to change*/ + bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + bde_p+= bd_num; + /* Update status field*/ + *((unsigned long*)param) = bde_p->mode.status; + + iapi_ReleaseChannel(chNum); + return retvalue; + } + +#ifdef MCU + /* + * Endianness + * --- Set the ENDIANNESS indicator in the command filed of the specified BD + * or on all BD's if SET_BIT_ALL is passed as parameter. + */ + case IAPI_CHANGE_SET_ENDIANNESS: + { + bufferDescriptor * bde_p; + int j = 0; + + retvalue = IAPI_SUCCESS; + if(param == SET_BIT_ALL) + { + bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + for(j = 0; j < cd_p->bufferDescNumber; j++) + { + bde_p->mode.command = CHANGE_ENDIANNESS; + bde_p++; + } + } + else if(param < cd_p->bufferDescNumber) + { + bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr) + + param; + bde_p->mode.command = CHANGE_ENDIANNESS; + } + else + { + retvalue = IAPI_FAILURE; + } + iapi_ReleaseChannel(chNum); + return retvalue; + } +#endif + +#ifdef SDMA_SKYE +#ifdef MCU + + /* + * SDMA State + * --- Enter the SDMA into LOCK Mode. No RAM updation allowed except same Context + * update with same PC Value. + */ + case IAPI_ENTER_LOCK_MODE: + { + if(param == RESET_CLEAR_LOCK) + { + SDMA_SDMA_LOCK = (1 << RESET_CLR_BIT_OFFSET); + SDMA_SDMA_LOCK = (1 << LOCK_BIT_OFFSET); + iapi_SdmaState = LOCK; + } + else if(param == RESET_NOCLEAR_LOCK) + { + SDMA_SDMA_LOCK = (1 << LOCK_BIT_OFFSET); + iapi_SdmaState = LOCK; + } + + } + break; + +#endif +#endif + default: + retvalue = IAPI_ERR_CD_CHANGE_UNKNOWN | IAPI_ERR_CH_AVAILABLE | chNum; + iapi_errno = retvalue; + iapi_ReleaseChannel(chNum); + return -retvalue; + } + + + iapi_ReleaseChannel(chNum); + return IAPI_SUCCESS; +} +/* ***************************************************************************/ +/**Initialization of the SDMA - opening of channel 0, download RAM image. + * + * Algorithm:\n + * - open channel 0 + * - if ram_image pointer passed is not NULL, download RAM image to SDMA + * + * @param + * - cd_p channel descriptor pointer for channel 0 + * - ram_image pointer to RAM image to download, or NULL if this operation + * is not required + * - code_size size of the RAM image, in bytes + * - start_addr start address for the RAM image + * + * @return + * - IAPI_SUCCESS if all operations were successful + * - negated I.API error code if any operation failed + */ +#ifdef MCU +int +iapi_Init(channelDescriptor * cd_p, configs_data * config_p, unsigned short* ram_image, + unsigned short code_size, unsigned long start_addr) +{ +#endif +#ifdef DSP +int +iapi_Init(channelDescriptor * cd_p) +{ +#endif + +int retvalue = IAPI_SUCCESS; /* Variable to store the results from I.API calls */ + + /* Check initialization not allredy done*/ + if(iapi_CCBHead != NULL) + { + retvalue = IAPI_ERR_NOT_ALLOWED; + iapi_errno = retvalue; + return -retvalue; + } + /* Be sure SDMA has not started yet */ +#ifdef MCU + SDMA_H_C0PTR = 0x0; +#endif +#ifdef DSP + SDMA_D_C0PTR = 0x0; +#endif + + /*Try to open channel 0*/ + retvalue = iapi_Open(cd_p, 0); + if(retvalue != IAPI_SUCCESS) + { + return retvalue; + } + +#ifdef MCU + /* Set Command Channel (Channel Zero) */ + SDMA_CHN0ADDR = 0x4050; + + /* Set bits of CONFIG register but with static context switching */ + SDMA_H_CONFIG = (config_p->dspdma << 12) | (config_p->rtdobs << 11) | + (config_p->acr << 4) | (0); + + /* Send the address for the host channel table to the SDMA*/ + SDMA_H_C0PTR = (unsigned long)iapi_Virt2Phys(iapi_CCBHead); + /* If required, download the RAM image for SDMA*/ + if(ram_image != NULL) + { + retvalue = iapi_SetScript(cd_p, (void*)ram_image, code_size, + start_addr); + } + + /* Set bits of CONFIG register with given context switching mode */ + SDMA_H_CONFIG = (config_p->dspdma << 12) | (config_p->rtdobs << 11) | + (config_p->acr << 4) | (config_p->csm); + +#endif +#ifdef DSP + /* Send the address for the host channel table to the SDMA*/ + SDMA_D_C0PTR = (unsigned long)iapi_Virt2Phys(iapi_CCBHead); +#endif + +#ifdef SDMA_SKYE + iapi_SdmaState = OPEN; +#endif + + return retvalue; +} + + +/* ***************************************************************************/ +/**High layer interface for starting a channel + * + * Algorithm:\n + * - call low layer function for starting a channel + * + * @return + * - IAPI_SUCCESS + */ +int +iapi_StartChannel(unsigned char channel) +{ + iapi_lowStartChannel(channel); + return IAPI_SUCCESS; +} +/* ***************************************************************************/ +/**High layer interface for stopping a channel + * + * Algorithm:\n + * - call low layer function for stopping a channel + * + * @return + * - IAPI_SUCCESS + */ +int +iapi_StopChannel(unsigned char channel) +{ + iapi_lowStopChannel(channel); + return IAPI_SUCCESS; +} + +/* ***************************************************************************/ +/**High layer interface for synchronising a channel + * + * Algorithm:\n + * - call low layer function for stopping a channel + * + * @return + * - IAPI_SUCCESS + */ +int iapi_SynchChannel(unsigned char channel) +{ + iapi_lowSynchChannel(channel); + return IAPI_SUCCESS; +} + +#ifdef MCU +/* ***************************************************************************/ +/**High layer interface for getting program memory data from SDMA + * + * Algorithm:\n + * - call coresponding low layer function + * + * @return + * - IAPI_SUCCESS + */ +int +iapi_GetScript(channelDescriptor * cd_p, void * buf, unsigned short size, + unsigned long address) +{ + iapi_lowGetScript(cd_p, buf, size, address); + return IAPI_SUCCESS; +} + +/* ***************************************************************************/ +/**High layer interface for getting data memory from SDMA + * + * Algorithm:\n + * - call coresponding low layer function + * + * @return + * - IAPI_SUCCESS + */ +int +iapi_GetContext(channelDescriptor * cd_p, void * buf, + unsigned char channel) +{ + iapi_lowGetContext(cd_p, buf, channel); + return IAPI_SUCCESS; +} + +/* ***************************************************************************/ +/**High layer interface for set program memory data to SDMA - e.g. scripts + * + * Algorithm:\n + * - call coresponding low layer function + * + * @return + * - IAPI_SUCCESS + */ +int +iapi_SetScript(channelDescriptor * cd_p, void * buf, unsigned short nbyte, + unsigned long destAddr) +{ + iapi_lowSetScript(cd_p, buf, nbyte, destAddr); + return IAPI_SUCCESS; +} + +/* ***************************************************************************/ +/**High layer interface for set data memory to SDMA - e.g. contexts. + * + * Algorithm:\n + * - call coresponding low layer function + * + * @return + * - IAPI_SUCCESS + */ +int +iapi_SetContext(channelDescriptor * cd_p, void * buf, + unsigned char channel) +{ + iapi_lowSetContext(cd_p, buf, channel); + return IAPI_SUCCESS; +} + +/* ***************************************************************************/ +/**High layer interface used to associate specified channel with a script. + * + * Algorithm:\n + * - call coresponding low layer function + * + * @return + * - IAPI_SUCCESS + */ +int +iapi_AssignScript(channelDescriptor * cd_p, script_data * data_p) +{ + /* VERIFY THAT THE CHANNEL IT IS OPENED !!!!*/ + return iapi_lowAssignScript(cd_p, data_p); +} + +/* ***************************************************************************/ +/**High layer interface used to associate specified channel with a script. + * + * Algorithm:\n + * - call coresponding low layer function + * + * @return + * - IAPI_SUCCESS + */ +int +iapi_SetChannelEventMapping(unsigned char event, unsigned long channel_map) +{ + return iapi_lowSetChannelEventMapping(event, channel_map); +} +#endif + + + +#ifdef DSP +#define SDMA_DI SDMA_D_INTR +void IRQ_Handler(); +#pragma interrupt IRQ_Handler +#endif + +#ifdef MCU +#define SDMA_DI SDMA_H_INTR +#endif + +#ifndef IRQ_KEYWORD +#define IRQ_KEYWORD +#endif /* IRQ_KEYWORD */ + +/* ***************************************************************************/ +/** + *@brief Find the first set bit in data parameter. + * + * Find the first set bit in unsigned integer parameter data. Data is scanned + * from MSB to LSB, searching for the set bit. The value returned is the + * offset from the most significant bit of data. If bit 31 is set, the value + * returned is zero. If no bits are set, a value of 32 is returned. This is compliant + * with the MCore FF1 instruction. + * + * + * + * @param + * - data: variable to check + * + * @return + * - the offset of the most significant bit set from the MSB + */ +unsigned int +quartz_FF1( unsigned int data ) +{ + register unsigned int result = 0; + while ( (result <= 31 ) && !( data & 0x80000000U) ) + { + data <<= 1U; + result++; + } + + return result; +} + +IRQ_KEYWORD +void +IRQ_Handler(void) +{ + unsigned int intrReg;/* interrupt register mask for clearing the interrupt bit */ + unsigned char chNum; /* SDMA channel number generating the a IRQ*/ + + /* Disable interrupts */ + iapi_DisableInterrupts(); + /* + * Clear interrupt in SDMA DI register => ACK to the SDMA the IT request. + * Get each interrupt number, clear them one after the other. + */ + if(SDMA_DI != 0) + { + chNum = (unsigned char)(CH_NUM - 1 - quartz_FF1(SDMA_DI)); + intrReg = (unsigned int)(1 << chNum); + } + else + { + chNum = 32; + intrReg = 0; + } + + while (intrReg != 0) + { + SDMA_DI &= intrReg; + iapi_SDMAIntr |= intrReg; + iapi_WakeUp(chNum); + if (callbackIsrTable[chNum] != NULL) + { + /* release channel before callback, so IoCtl's are available*/ + iapi_ReleaseChannel(chNum); + callbackIsrTable[chNum](iapi_CCBHead[chNum].channelDescriptor, + userArgTable[chNum]); + } + + chNum = (unsigned char)(CH_NUM - 1 - quartz_FF1(SDMA_DI)); + intrReg = (unsigned int)(1 << chNum); + } + + /* Enable interrupts */ + iapi_EnableInterrupts(); +} + +/* ***************************************************************************/ +/** + *@brief Perform a memory copy operation, in the memory of the same processor + * + * Size bytes are copied from the src address to dest address. It is used + * the channel pointed by cd_p, which must be configured prior to this call: + * opened, associated with the script to perform the operation - DSP_2_DSP, + * or MCU_2_MCU - and have the synchronization option set. + * + * + * + * @param + * - cd_p: channel configured to perform DSP_2_DSP or MCU_2_MCU transfers + * - dest: destination memory address + * - src : source memory address + * - size: number of bytes to copy from src to dest + * + * @return + * - the offset of the most significant bit set from the MSB + */ + +int iapi_MemCopy(channelDescriptor * cd_p, void* dest, void* src, unsigned long size) +{ + int result = IAPI_SUCCESS; + bufferDescriptor * bd_p; + + /* Channel descriptor validity */ + if (cd_p == NULL) + { + result = IAPI_ERR_CD_UNINITIALIZED; + iapi_errno = result; + return -result; + } + + /* Check and set correct parameter */ + if(cd_p->trust != TRUE) + { + result = iapi_ChangeChannelDesc(cd_p, IAPI_TRUST, TRUE); + } + + if(cd_p->bufferDescNumber != 1) + { + result = iapi_ChangeChannelDesc(cd_p, IAPI_BUFFERDESCNUMBER, 1); + if(result != IAPI_SUCCESS) + { + return result; + } + } + + if(cd_p->bufferSize != size) + { + result = iapi_ChangeChannelDesc(cd_p, IAPI_BUFFERSIZE, size); + if(result != IAPI_SUCCESS) + { + return result; + } + } + /* Set addresses*/ + bd_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr); + bd_p->bufferAddr = iapi_Virt2Phys(src); + bd_p->extBufferAddr = iapi_Virt2Phys(dest); + + /* Set mode*/ + bd_p->mode.count = size; + bd_p->mode.command = 0x00; + bd_p->mode.status = BD_INTR|BD_EXTD|BD_DONE|BD_WRAP; + + /*Decide if we sleep or not*/ + if(cd_p->callbackSynch == DEFAULT_POLL) + { + iapi_StartChannel(cd_p->channelNumber); + /* Call synchronization routine*/ + iapi_SynchChannel(cd_p->channelNumber); + } + else + { + /* Just start the channel*/ + iapi_StartChannel(cd_p->channelNumber); + } + + return result; +} + +/* ***************************************************************************/ +/**Return the channel number from the channel descriptor + * + * @param cd_p pointer to channel descriptor to obtain the channel number + * + * @return + * - the channel number + * + */ +int iapi_GetChannelNumber(channelDescriptor * cd_p) +{ + return cd_p->channelNumber; +} + +/* ***************************************************************************/ +/**Return the error bit from the current BD of the channel + * + * + * @param cd_p pointer to channel descriptor + * + * @return + * - 0 if no error detected + * - BD_RROR | DATA_ERROR if error detected + * + */ +unsigned long iapi_GetError(channelDescriptor * cd_p) +{ + return ((cd_p->ccb_ptr->currentBDptr->mode.status & BD_RROR) | + (*(unsigned long*)&cd_p->ccb_ptr->status & DATA_ERROR)); +} + +/* ***************************************************************************/ +/**Return the count from the current BD of the channel + * + * + * @param cd_p pointer to channel descriptor + * + * @return + * - count field of the current BD for the channel + * + */ +int iapi_GetCount(channelDescriptor * cd_p) +{ + return (int)(cd_p->ccb_ptr->currentBDptr->mode.count); +} + +/* ***************************************************************************/ +/**Return the sum of counts for all the BD's owned by the processor for + * the channel specified by the received parameter. + * + * + * @param cd_p pointer to channel descriptor + * + * @return + * - sum of count fields + * + */ +int iapi_GetCountAll(channelDescriptor * cd_p) +{ + int retval = 0; + int i = 0; + bufferDescriptor* bd_p; + + bd_p = cd_p->ccb_ptr->baseBDptr; + + while((i < cd_p->bufferDescNumber) && ((bd_p->mode.status & BD_DONE) == 0)) + { + retval += bd_p->mode.count; + i++; + bd_p++; + } + return retval; +} --- linux-2.6.28.orig/arch/arm/plat-mxc/sdma/iapi/src/iapiDefaults.c +++ linux-2.6.28/arch/arm/plat-mxc/sdma/iapi/src/iapiDefaults.c @@ -0,0 +1,110 @@ +/****************************************************************************** + * + * Copyright 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 + * + ****************************************************************************** + * + * File: iapiDefaults.c + * + * $Id iapiDefaults.c $ + * + * Description: + * This library is written in C to guarantee functionality and integrity in + * the usage of SDMA virtual DMA channels. This API (Application Programming + * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE + * fashion. + * + * Usage: + * + * Files: + * + * +* / + * + * $Log iapiDefaults.c $ + * + *****************************************************************************/ + +/* **************************************************************************** + * Include File Section + ******************************************************************************/ +#include "iapiDefaults.h" + +/* **************************************************************************** + * Global Variable Section + ******************************************************************************/ + +/** + * @brief System Call-back ISRs Table + */ +void (* callbackIsrTable[CH_NUM])(channelDescriptor* cd_p, void* arg); + +/** + * @brief User registered pointers table + */ +void * userArgTable[CH_NUM]; + +/** + * @brief Pointer to the first CCB in the CCB array + */ +channelControlBlock * iapi_CCBHead = NULL; + + +/**Default channel description. + * + * Initialization values are:\n + * - channelNumber = 0 + * - bufferDescNumber = 1 + * - bufferSize = 8 + * - blocking = 0 + * - callbackSynch = DEFAULT_POLL + * - ownership = CD_DEFAULT_OWNERSHIP + * - priority = 1 + * - trust = TRUE + * - useDataSize = 0 + * - dataSize = 0 + * - forceClose = 0 + * - scriptId = 0 + * - watermarkLevel = 0 + * - eventMask1 = 0 + * - eventMask2 = 0 + * - peripheralAddr = NULL + * - callbackISR_ptr = NULL + * - iapi_channelControlBlock = NULL + */ +channelDescriptor iapi_ChannelDefaults = {0, 1, 8, 0, DEFAULT_POLL, + CD_DEFAULT_OWNERSHIP, 1, TRUE, 0, 0, 0, 0, + 0, 0x00, 0x00, 0x00, NULL, NULL}; + +/** + * Integrated error management + */ +unsigned int iapi_errno = 0; +volatile unsigned long iapi_SDMAIntr = 0; + +/* Default config register. + * Initialization values are: + * dspdma used + * Real-Time Debug pins disabled + * AHB freq / core freq = 2 + * dynamic context switch +*/ +configs_data iapi_ConfigDefaults = {1, 0, 0, 3}; + +#ifdef SDMA_SKYE +/* Default sdma State : UNDEF + *possible value are UNDEF, OPEN, LOCK, CLOSED, CLOSE_LOCK + */ + +sdmaState iapi_SdmaState= UNDEF; +#endif + +/* ***************************************************************************/ --- linux-2.6.28.orig/arch/arm/plat-mxc/sdma/iapi/src/iapiMiddleMcu.c +++ linux-2.6.28/arch/arm/plat-mxc/sdma/iapi/src/iapiMiddleMcu.c @@ -0,0 +1,52 @@ +/****************************************************************************** + * + * Copyright 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 + * + ****************************************************************************** + * + * File: iapiMiddleMcu.c + * + * $Id iapiMiddleMcu.c $ + * + * Description: + * This library is written in C to guarantee functionality and integrity in + * the usage of SDMA virtual DMA channels. This API (Application Programming + * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE + * fashion. + * These are the MIDDLE level functions of the I.API specific to MCU. + * + * + * + * + * $Log iapiMiddleMcu.c $ + * + *****************************************************************************/ + +/* **************************************************************************** + * Include File Section + *****************************************************************************/ +#include "epm.h" +#include + +#include "iapiLow.h" +#include "iapiMiddle.h" + +/* **************************************************************************** + * Global Variable Section + *****************************************************************************/ + +/*extern void * __HEAP_START; +extern void * __HEAP_END; +*/ + +/* **************************************************************************** + * Function Section + *****************************************************************************/ --- linux-2.6.28.orig/arch/arm/mm/Kconfig +++ linux-2.6.28/arch/arm/mm/Kconfig @@ -187,7 +187,7 @@ ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || \ ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || \ ARCH_AT91SAM9G20 || ARCH_AT91CAP9 || \ - ARCH_NS9XXX || ARCH_DAVINCI || ARCH_MX2 + ARCH_NS9XXX || ARCH_DAVINCI || ARCH_MX2 || ARCH_MXC default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || \ ARCH_OMAP730 || ARCH_OMAP16XX || \ ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || \ @@ -400,7 +400,7 @@ # ARMv6 config CPU_V6 bool "Support ARM V6 processor" - depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2 || ARCH_MX3 || ARCH_MSM || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 + depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2 || ARCH_MX3 || ARCH_MXC || ARCH_MSM || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 default y if ARCH_MX3 default y if ARCH_MSM select CPU_32v6 @@ -428,7 +428,7 @@ # ARMv7 config CPU_V7 bool "Support ARM V7 processor" - depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP3 + depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP3 || ARCH_MXC select CPU_32v6K select CPU_32v7 select CPU_ABRT_EV7 --- linux-2.6.28.orig/arch/arm/mm/proc-macros.S +++ linux-2.6.28/arch/arm/mm/proc-macros.S @@ -119,8 +119,8 @@ .long 0x00 @ unused .long PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_DEV_CACHED .long PTE_EXT_TEX(2) @ L_PTE_MT_DEV_NONSHARED - .long 0x00 @ unused - .long 0x00 @ unused + .long PTE_EXT_TEX(4) | PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_OUTER_UNCACHED + .long PTE_EXT_TEX(6) | PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_OUTER_WRITETHRU .long 0x00 @ unused .endm --- linux-2.6.28.orig/arch/arm/mach-rpc/riscpc.c +++ linux-2.6.28/arch/arm/mach-rpc/riscpc.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -201,8 +202,13 @@ &pata_device, }; +static struct i2c_board_info i2c_rtc = { + I2C_BOARD_INFO("pcf8583", 0x50) +}; + static int __init rpc_init(void) { + i2c_register_board_info(0, &i2c_rtc, 1); return platform_add_devices(devs, ARRAY_SIZE(devs)); } --- linux-2.6.28.orig/arch/arm/vfp/vfpmodule.c +++ linux-2.6.28/arch/arm/vfp/vfpmodule.c @@ -371,6 +371,15 @@ * in place; report VFP support to userspace. */ elf_hwcap |= HWCAP_VFP; +#ifdef CONFIG_NEON + /* + * Check for the presence of the Advanced SIMD + * load/store instructions, integer and single + * precision floating point operations. + */ + if ((fmrx(MVFR1) & 0x000fff00) == 0x00011100) + elf_hwcap |= HWCAP_NEON; +#endif } return 0; } --- linux-2.6.28.orig/arch/arm/include/asm/pgtable.h +++ linux-2.6.28/arch/arm/include/asm/pgtable.h @@ -186,6 +186,8 @@ #define L_PTE_MT_DEV_NONSHARED (0x0c << 2) /* 1100 */ #define L_PTE_MT_DEV_WC (0x09 << 2) /* 1001 */ #define L_PTE_MT_DEV_CACHED (0x0b << 2) /* 1011 */ +#define L_PTE_MT_OUTER_UNCACHED (0x0d << 2) /* 1101 */ +#define L_PTE_MT_OUTER_WRITETHRU (0x0e << 2) /* 1110 */ #define L_PTE_MT_MASK (0x0f << 2) #ifndef __ASSEMBLY__ @@ -313,6 +315,19 @@ __pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_UNCACHED) #define pgprot_writecombine(prot) \ __pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_BUFFERABLE) +#define pgprot_writethru(prot) \ + __pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_WRITETHROUGH) +#define pgprot_nonshareddev(prot) \ + __pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_DEV_NONSHARED) + +/* Extended configurations for inner writeback cacheable */ +#define pgprot_writealloc(prot) \ + __pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_WRITEALLOC) +#define pgprot_outer_wrthru(prot) \ + __pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_OUTER_WRITETHRU) +#define pgprot_outer_noncached(prot) \ + __pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_OUTER_UNCACHED) + #define pmd_none(pmd) (!pmd_val(pmd)) #define pmd_present(pmd) (pmd_val(pmd)) --- linux-2.6.28.orig/arch/arm/include/asm/hwcap.h +++ linux-2.6.28/arch/arm/include/asm/hwcap.h @@ -16,6 +16,7 @@ #define HWCAP_IWMMXT 512 #define HWCAP_CRUNCH 1024 #define HWCAP_THUMBEE 2048 +#define HWCAP_NEON 4096 #if defined(__KERNEL__) && !defined(__ASSEMBLY__) /* --- linux-2.6.28.orig/arch/arm/include/asm/mach/keypad.h +++ linux-2.6.28/arch/arm/include/asm/mach/keypad.h @@ -0,0 +1,28 @@ +/* + * include/asm-arm/mach/keypad.h + * + * Generic Keypad struct + * + * Author: Armin Kuster + * + * 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. + */ + +#ifndef __ASM_MACH_KEYPAD_H_ +#define __ASM_MACH_KEYPAD_H_ + +#include + +struct keypad_data { + u16 rowmax; + u16 colmax; + u32 irq; + u16 delay; + u16 learning; + u16 *matrix; +}; + +#endif /* __ARM_MACH_KEYPAD_H_ */ --- linux-2.6.28.orig/arch/arm/tools/mach-types +++ linux-2.6.28/arch/arm/tools/mach-types @@ -12,7 +12,7 @@ # # http://www.arm.linux.org.uk/developer/machines/?action=new # -# Last update: Thu Sep 25 10:10:50 2008 +# Last update: Tue Mar 3 15:42:36 2009 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -1380,7 +1380,7 @@ olip8 MACH_OLIP8 OLIP8 1378 ghi270hg MACH_GHI270HG GHI270HG 1379 davinci_dm6467_evm MACH_DAVINCI_DM6467_EVM DAVINCI_DM6467_EVM 1380 -davinci_dm355_evm MACH_DAVINCI_DM350_EVM DAVINCI_DM350_EVM 1381 +davinci_dm355_evm MACH_DAVINCI_DM355_EVM DAVINCI_DM355_EVM 1381 blackriver MACH_BLACKRIVER BLACKRIVER 1383 sandgate_wp MACH_SANDGATEWP SANDGATEWP 1384 cdotbwsg MACH_CDOTBWSG CDOTBWSG 1385 @@ -1771,7 +1771,7 @@ 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 +at572d940hfek MACH_AT572D940HFEB AT572D940HFEB 1783 cybook3 MACH_CYBOOK3 CYBOOK3 1784 wdg002 MACH_WDG002 WDG002 1785 sg560adsl MACH_SG560ADSL SG560ADSL 1786 @@ -1811,7 +1811,7 @@ jade MACH_JADE JADE 1821 ks8695_softplc MACH_KS8695_SOFTPLC KS8695_SOFTPLC 1822 gprisc3 MACH_GPRISC3 GPRISC3 1823 -stamp9260 MACH_STAMP9260 STAMP9260 1824 +stamp9g20 MACH_STAMP9G20 STAMP9G20 1824 smdk6430 MACH_SMDK6430 SMDK6430 1825 smdkc100 MACH_SMDKC100 SMDKC100 1826 tavorevb MACH_TAVOREVB TAVOREVB 1827 @@ -1899,3 +1899,217 @@ asusp535 MACH_ASUSP535 ASUSP535 1909 htcraphael MACH_HTCRAPHAEL HTCRAPHAEL 1910 sygdg1 MACH_SYGDG1 SYGDG1 1911 +sygdg2 MACH_SYGDG2 SYGDG2 1912 +seoul MACH_SEOUL SEOUL 1913 +salerno MACH_SALERNO SALERNO 1914 +ucn_s3c64xx MACH_UCN_S3C64XX UCN_S3C64XX 1915 +msm7201a MACH_MSM7201A MSM7201A 1916 +lpr1 MACH_LPR1 LPR1 1917 +armadillo500fx MACH_ARMADILLO500FX ARMADILLO500FX 1918 +g3evm MACH_G3EVM G3EVM 1919 +z3_dm355 MACH_Z3_DM355 Z3_DM355 1920 +w90p910evb MACH_W90P910EVB W90P910EVB 1921 +w90p920evb MACH_W90P920EVB W90P920EVB 1922 +w90p950evb MACH_W90P950EVB W90P950EVB 1923 +w90n960evb MACH_W90N960EVB W90N960EVB 1924 +camhd MACH_CAMHD CAMHD 1925 +mvc100 MACH_MVC100 MVC100 1926 +electrum_200 MACH_ELECTRUM_200 ELECTRUM_200 1927 +htcjade MACH_HTCJADE HTCJADE 1928 +memphis MACH_MEMPHIS MEMPHIS 1929 +imx27sbc MACH_IMX27SBC IMX27SBC 1930 +lextar MACH_LEXTAR LEXTAR 1931 +mv88f6281gtw_ge MACH_MV88F6281GTW_GE MV88F6281GTW_GE 1932 +ncp MACH_NCP NCP 1933 +z32an_series MACH_Z32AN Z32AN 1934 +tmq_capd MACH_TMQ_CAPD TMQ_CAPD 1935 +omap3_wl MACH_OMAP3_WL OMAP3_WL 1936 +chumby MACH_CHUMBY CHUMBY 1937 +atsarm9 MACH_ATSARM9 ATSARM9 1938 +davinci_dm365_evm MACH_DAVINCI_DM365_EVM DAVINCI_DM365_EVM 1939 +bahamas MACH_BAHAMAS BAHAMAS 1940 +das MACH_DAS DAS 1941 +minidas MACH_MINIDAS MINIDAS 1942 +vk1000 MACH_VK1000 VK1000 1943 +centro MACH_CENTRO CENTRO 1944 +ctera_2bay MACH_CTERA_2BAY CTERA_2BAY 1945 +edgeconnect MACH_EDGECONNECT EDGECONNECT 1946 +nd27000 MACH_ND27000 ND27000 1947 +cobra MACH_GEMALTO_COBRA GEMALTO_COBRA 1948 +ingelabs_comet MACH_INGELABS_COMET INGELABS_COMET 1949 +pollux_wiz MACH_POLLUX_WIZ POLLUX_WIZ 1950 +blackstone MACH_BLACKSTONE BLACKSTONE 1951 +topaz MACH_TOPAZ TOPAZ 1952 +aixle MACH_AIXLE AIXLE 1953 +mw998 MACH_MW998 MW998 1954 +nokia_rx51 MACH_NOKIA_RX51 NOKIA_RX51 1955 +vsc5605ev MACH_VSC5605EV VSC5605EV 1956 +nt98700dk MACH_NT98700DK NT98700DK 1957 +icontact MACH_ICONTACT ICONTACT 1958 +swarco_frcpu MACH_SWARCO_FRCPU SWARCO_FRCPU 1959 +swarco_scpu MACH_SWARCO_SCPU SWARCO_SCPU 1960 +bbox_p16 MACH_BBOX_P16 BBOX_P16 1961 +bstd MACH_BSTD BSTD 1962 +sbc2440ii MACH_SBC2440II SBC2440II 1963 +pcm034 MACH_PCM034 PCM034 1964 +neso MACH_NESO NESO 1965 +wlnx_9g20 MACH_WLNX_9G20 WLNX_9G20 1966 +omap_zoom2 MACH_OMAP_ZOOM2 OMAP_ZOOM2 1967 +totemnova MACH_TOTEMNOVA TOTEMNOVA 1968 +c5000 MACH_C5000 C5000 1969 +unipo_at91sam9263 MACH_UNIPO_AT91SAM9263 UNIPO_AT91SAM9263 1970 +ethernut5 MACH_ETHERNUT5 ETHERNUT5 1971 +arm11 MACH_ARM11 ARM11 1972 +cpuat9260 MACH_CPUAT9260 CPUAT9260 1973 +cpupxa255 MACH_CPUPXA255 CPUPXA255 1974 +cpuimx27 MACH_CPUIMX27 CPUIMX27 1975 +cheflux MACH_CHEFLUX CHEFLUX 1976 +eb_cpux9k2 MACH_EB_CPUX9K2 EB_CPUX9K2 1977 +opcotec MACH_OPCOTEC OPCOTEC 1978 +yt MACH_YT YT 1979 +motoq MACH_MOTOQ MOTOQ 1980 +bsb1 MACH_BSB1 BSB1 1981 +acs5k MACH_ACS5K ACS5K 1982 +milan MACH_MILAN MILAN 1983 +quartzv2 MACH_QUARTZV2 QUARTZV2 1984 +rsvp MACH_RSVP RSVP 1985 +rmp200 MACH_RMP200 RMP200 1986 +snapper_9260 MACH_SNAPPER_9260 SNAPPER_9260 1987 +dsm320 MACH_DSM320 DSM320 1988 +adsgcm MACH_ADSGCM ADSGCM 1989 +ase2_400 MACH_ASE2_400 ASE2_400 1990 +pizza MACH_PIZZA PIZZA 1991 +spot_ngpl MACH_SPOT_NGPL SPOT_NGPL 1992 +armata MACH_ARMATA ARMATA 1993 +exeda MACH_EXEDA EXEDA 1994 +mx31sf005 MACH_MX31SF005 MX31SF005 1995 +f5d8231_4_v2 MACH_F5D8231_4_V2 F5D8231_4_V2 1996 +q2440 MACH_Q2440 Q2440 1997 +qq2440 MACH_QQ2440 QQ2440 1998 +mini2440 MACH_MINI2440 MINI2440 1999 +colibri300 MACH_COLIBRI300 COLIBRI300 2000 +jades MACH_JADES JADES 2001 +spark MACH_SPARK SPARK 2002 +benzina MACH_BENZINA BENZINA 2003 +blaze MACH_BLAZE BLAZE 2004 +linkstation_ls_hgl MACH_LINKSTATION_LS_HGL LINKSTATION_LS_HGL 2005 +htckovsky MACH_HTCVENUS HTCVENUS 2006 +sony_prs505 MACH_SONY_PRS505 SONY_PRS505 2007 +hanlin_v3 MACH_HANLIN_V3 HANLIN_V3 2008 +sapphira MACH_SAPPHIRA SAPPHIRA 2009 +dack_sda_01 MACH_DACK_SDA_01 DACK_SDA_01 2010 +armbox MACH_ARMBOX ARMBOX 2011 +harris_rvp MACH_HARRIS_RVP HARRIS_RVP 2012 +ribaldo MACH_RIBALDO RIBALDO 2013 +agora MACH_AGORA AGORA 2014 +omap3_mini MACH_OMAP3_MINI OMAP3_MINI 2015 +a9sam6432_b MACH_A9SAM6432_B A9SAM6432_B 2016 +usg2410 MACH_USG2410 USG2410 2017 +pc72052_i10_revb MACH_PC72052_I10_REVB PC72052_I10_REVB 2018 +mx35_exm32 MACH_MX35_EXM32 MX35_EXM32 2019 +topas910 MACH_TOPAS910 TOPAS910 2020 +hyena MACH_HYENA HYENA 2021 +pospax MACH_POSPAX POSPAX 2022 +hdl_gx MACH_HDL_GX HDL_GX 2023 +ctera_4bay MACH_CTERA_4BAY CTERA_4BAY 2024 +ctera_plug_c MACH_CTERA_PLUG_C CTERA_PLUG_C 2025 +crwea_plug_i MACH_CRWEA_PLUG_I CRWEA_PLUG_I 2026 +egauge2 MACH_EGAUGE2 EGAUGE2 2027 +didj MACH_DIDJ DIDJ 2028 +meister MACH_MEISTER MEISTER 2029 +htcblackstone MACH_HTCBLACKSTONE HTCBLACKSTONE 2030 +cpuat9g20 MACH_CPUAT9G20 CPUAT9G20 2031 +smdk6440 MACH_SMDK6440 SMDK6440 2032 +omap_35xx_mvp MACH_OMAP_35XX_MVP OMAP_35XX_MVP 2033 +ctera_plug_i MACH_CTERA_PLUG_I CTERA_PLUG_I 2034 +pvg610_100 MACH_PVG610 PVG610 2035 +hprw6815 MACH_HPRW6815 HPRW6815 2036 +omap3_oswald MACH_OMAP3_OSWALD OMAP3_OSWALD 2037 +nas4220b MACH_NAS4220B NAS4220B 2038 +htcraphael_cdma MACH_HTCRAPHAEL_CDMA HTCRAPHAEL_CDMA 2039 +htcdiamond_cdma MACH_HTCDIAMOND_CDMA HTCDIAMOND_CDMA 2040 +scaler MACH_SCALER SCALER 2041 +zylonite2 MACH_ZYLONITE2 ZYLONITE2 2042 +aspenite MACH_ASPENITE ASPENITE 2043 +teton MACH_TETON TETON 2044 +ttc_dkb MACH_TTC_DKB TTC_DKB 2045 +bishop2 MACH_BISHOP2 BISHOP2 2046 +ippv5 MACH_IPPV5 IPPV5 2047 +farm926 MACH_FARM926 FARM926 2048 +mmccpu MACH_MMCCPU MMCCPU 2049 +sgmsfl MACH_SGMSFL SGMSFL 2050 +tt8000 MACH_TT8000 TT8000 2051 +zrn4300lp MACH_ZRN4300LP ZRN4300LP 2052 +mptc MACH_MPTC MPTC 2053 +h6051 MACH_H6051 H6051 2054 +pvg610_101 MACH_PVG610_101 PVG610_101 2055 +stamp9261_pc_evb MACH_STAMP9261_PC_EVB STAMP9261_PC_EVB 2056 +pelco_odysseus MACH_PELCO_ODYSSEUS PELCO_ODYSSEUS 2057 +tny_a9260 MACH_TNY_A9260 TNY_A9260 2058 +tny_a9g20 MACH_TNY_A9G20 TNY_A9G20 2059 +aesop_mp2530f MACH_AESOP_MP2530F AESOP_MP2530F 2060 +dx900 MACH_DX900 DX900 2061 +cpodc2 MACH_CPODC2 CPODC2 2062 +tilt_8925 MACH_TILT_8925 TILT_8925 2063 +davinci_dm357_evm MACH_DAVINCI_DM357_EVM DAVINCI_DM357_EVM 2064 +swordfish MACH_SWORDFISH SWORDFISH 2065 +corvus MACH_CORVUS CORVUS 2066 +taurus MACH_TAURUS TAURUS 2067 +axm MACH_AXM AXM 2068 +axc MACH_AXC AXC 2069 +baby MACH_BABY BABY 2070 +mp200 MACH_MP200 MP200 2071 +pcm043 MACH_PCM043 PCM043 2072 +hanlin_v3c MACH_HANLIN_V3C HANLIN_V3C 2073 +kbk9g20 MACH_KBK9G20 KBK9G20 2074 +adsturbog5 MACH_ADSTURBOG5 ADSTURBOG5 2075 +avenger_lite1 MACH_AVENGER_LITE1 AVENGER_LITE1 2076 +suc82x MACH_SUC SUC 2077 +at91sam7s256 MACH_AT91SAM7S256 AT91SAM7S256 2078 +mendoza MACH_MENDOZA MENDOZA 2079 +kira MACH_KIRA KIRA 2080 +mx1hbm MACH_MX1HBM MX1HBM 2081 +quatro43xx MACH_QUATRO43XX QUATRO43XX 2082 +quatro4230 MACH_QUATRO4230 QUATRO4230 2083 +nsb400 MACH_NSB400 NSB400 2084 +drp255 MACH_DRP255 DRP255 2085 +thoth MACH_THOTH THOTH 2086 +firestone MACH_FIRESTONE FIRESTONE 2087 +asusp750 MACH_ASUSP750 ASUSP750 2088 +ctera_dl MACH_CTERA_DL CTERA_DL 2089 +socr MACH_SOCR SOCR 2090 +htcoxygen MACH_HTCOXYGEN HTCOXYGEN 2091 +heroc MACH_HEROC HEROC 2092 +zeno6800 MACH_ZENO6800 ZENO6800 2093 +sc2mcs MACH_SC2MCS SC2MCS 2094 +gene100 MACH_GENE100 GENE100 2095 +as353x MACH_AS353X AS353X 2096 +kirkwood_plug MACH_KIRKWOOD_PLUG KIRKWOOD_PLUG 2097 +at91sam9g20 MACH_AT91SAM9G20 AT91SAM9G20 2098 +mv88f6192gtw_fe MACH_MV88F6192GTW_FE MV88F6192GTW_FE 2099 +cc9200 MACH_CC9200 CC9200 2100 +sm9200 MACH_SM9200 SM9200 2101 +tp9200 MACH_TP9200 TP9200 2102 +snapperdv MACH_SNAPPERDV SNAPPERDV 2103 +avengers_lite MACH_AVENGERS_LITE AVENGERS_LITE 2104 +avengers_lite1 MACH_AVENGERS_LITE1 AVENGERS_LITE1 2105 +omap3axon MACH_OMAP3AXON OMAP3AXON 2106 +ma8xx MACH_MA8XX MA8XX 2107 +mp201ek MACH_MP201EK MP201EK 2108 +davinci_tux MACH_DAVINCI_TUX DAVINCI_TUX 2109 +mpa1600 MACH_MPA1600 MPA1600 2110 +pelco_troy MACH_PELCO_TROY PELCO_TROY 2111 +nsb667 MACH_NSB667 NSB667 2112 +rovers5_4mpix MACH_ROVERS5_4MPIX ROVERS5_4MPIX 2113 +twocom MACH_TWOCOM TWOCOM 2114 +ubisys_p9_rcu3r2 MACH_UBISYS_P9_RCU3R2 UBISYS_P9_RCU3R2 2115 +hero_espresso MACH_HERO_ESPRESSO HERO_ESPRESSO 2116 +afeusb MACH_AFEUSB AFEUSB 2117 +t830 MACH_T830 T830 2118 +spd8020_cc MACH_SPD8020_CC SPD8020_CC 2119 +om_3d7k MACH_OM_3D7K OM_3D7K 2120 +picocom2 MACH_PICOCOM2 PICOCOM2 2121 +uwg4mx27 MACH_UWG4MX27 UWG4MX27 2122 +uwg4mx31 MACH_UWG4MX31 UWG4MX31 2123 +cherry MACH_CHERRY CHERRY 2124 +mx51_babbage MACH_MX51_BABBAGE MX51_BABBAGE 2125 --- linux-2.6.28.orig/arch/arm/configs/imx51_defconfig +++ linux-2.6.28/arch/arm/configs/imx51_defconfig @@ -0,0 +1,1814 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.26 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +# CONFIG_GENERIC_GPIO is not set +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 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_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 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_MX37 is not set +# CONFIG_ARCH_MX35 is not set +CONFIG_ARCH_MX51=y +# CONFIG_ARCH_MX3 is not set +# CONFIG_ARCH_MX27 is not set +# CONFIG_ARCH_MX25 is not set +# CONFIG_ARCH_MX21 is not set +CONFIG_I2C_MXC_SELECT1=y +CONFIG_I2C_MXC_SELECT2=y +CONFIG_MXC_SDMA_API=y +# CONFIG_I2C_MXC_SELECT3 is not set +CONFIG_SDMA_IRAM=y +CONFIG_SDMA_IRAM_SIZE=0x1000 +CONFIG_ARCH_MXC_HAS_NFC_V3=y + +# +# MX51 Options +# +CONFIG_MX51_OPTIONS=y +CONFIG_MACH_MX51_3DS=y +CONFIG_MACH_MX51_BABBAGE=y +CONFIG_ARCH_MXC_HAS_NFC_V3_2=y + +# +# SDMA options +# + +# +# Device options +# +CONFIG_MXC_TZIC=y +CONFIG_DMA_ZONE_SIZE=64 +CONFIG_UTMI_MXC=y + +# +# Processor Type +# +CONFIG_CPU_32=y +# CONFIG_CPU_ARM926T is not set +# CONFIG_CPU_V6 is not set +CONFIG_CPU_32v6K=y +CONFIG_CPU_V7=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_PABRT_IFAR=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_ARM_THUMBEE is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_HAS_TLS_REG=y +# 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_LEDS is not set +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 rootfstype=jffs2 ip=off" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_IMX=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_NEON=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=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_APM_EMULATION 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_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES 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=y + +# +# Queueing/Scheduling +# +# CONFIG_NET_SCH_CBQ is not set +# CONFIG_NET_SCH_HTB is not set +# CONFIG_NET_SCH_HFSC is not set +# CONFIG_NET_SCH_PRIO is not set +# CONFIG_NET_SCH_RED is not set +# CONFIG_NET_SCH_SFQ is not set +# CONFIG_NET_SCH_TEQL is not set +# CONFIG_NET_SCH_TBF is not set +# CONFIG_NET_SCH_GRED is not set +# CONFIG_NET_SCH_DSMARK is not set +# CONFIG_NET_SCH_NETEM is not set + +# +# Classification +# +# CONFIG_NET_CLS_BASIC is not set +# CONFIG_NET_CLS_TCINDEX is not set +# CONFIG_NET_CLS_ROUTE4 is not set +# CONFIG_NET_CLS_FW is not set +# CONFIG_NET_CLS_U32 is not set +# CONFIG_NET_CLS_RSVP is not set +# CONFIG_NET_CLS_RSVP6 is not set +# CONFIG_NET_CLS_FLOW is not set +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_CLS_ACT is not set +CONFIG_NET_SCH_FIFO=y + +# +# 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=y +# CONFIG_MAC80211 is not set +CONFIG_IEEE80211=y +# CONFIG_IEEE80211_DEBUG is not set +# CONFIG_IEEE80211_CRYPT_WEP is not set +# CONFIG_IEEE80211_CRYPT_CCMP is not set +# CONFIG_IEEE80211_CRYPT_TKIP 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=y +CONFIG_PROC_EVENTS=y +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 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 +# CONFIG_MTD_MXC 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=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_MXC_V3=y +# CONFIG_MTD_NAND_MXC_SWECC is not set +# CONFIG_MTD_NAND_MXC_FORCE_CE is not set +# CONFIG_MXC_NAND_LOW_LEVEL_ERASE 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 + +# +# Voltage and Current regulators +# +CONFIG_REGULATOR_API=y +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_DEBUG is not set +CONFIG_REGULATOR_MC13892=y +# CONFIG_REGULATOR_WM8350 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 is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 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 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=m +# CONFIG_ATA_NONSTANDARD is not set +# CONFIG_SATA_PMP is not set +CONFIG_ATA_SFF=y +# CONFIG_SATA_MV is not set +# CONFIG_PATA_PLATFORM is not set +CONFIG_PATA_FSL=m +# 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_ENC28J60 is not set +# CONFIG_SMC911X is not set +CONFIG_SMSC911X=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_B44 is not set +# CONFIG_CS89x0 is not set +CONFIG_FEC=y +# CONFIG_FEC2 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=y + +# +# 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_KEYBOARD_MXC=y +CONFIG_GPIO_BUTTON_MXC=y +# 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_MXC=y +# 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_TOUCHSCREEN_TSC2007 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_MXC=y +CONFIG_SERIAL_MXC_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +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=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Hardware Bus support +# +CONFIG_I2C_MXC=y +CONFIG_I2C_MXC_HS=y +# 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_TINY_USB 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_I2C_SLAVE is not set +CONFIG_SPI=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_BITBANG=y +CONFIG_SPI_MXC=y +# CONFIG_SPI_MXC_TEST_LOOPBACK is not set +CONFIG_SPI_MXC_SELECT1=y +# CONFIG_SPI_MXC_SELECT2 is not set +# CONFIG_SPI_MXC_SELECT3 is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_AT25 is not set +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set +CONFIG_W1=m +CONFIG_W1_CON=y + +# +# 1-wire Bus Masters +# +# CONFIG_W1_MASTER_DS2490 is not set +# CONFIG_W1_MASTER_DS2482 is not set +CONFIG_W1_MASTER_MXC=m +# CONFIG_W1_MASTER_DS1WM is not set + +# +# 1-wire Slaves +# +# CONFIG_W1_SLAVE_THERM is not set +# CONFIG_W1_SLAVE_SMEM is not set +# CONFIG_W1_SLAVE_DS2751 is not set +# CONFIG_W1_SLAVE_DS2433 is not set +CONFIG_W1_SLAVE_DS2438=m +# CONFIG_W1_SLAVE_DS2760 is not set +CONFIG_POWER_SUPPLY=m +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_BATTERY_DS2760 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_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_LM70 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 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_VT1211 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 +CONFIG_SENSORS_ISL29003=y +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_MXC_WATCHDOG=y + +# +# 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_MEDIA_TUNER=y +CONFIG_MEDIA_TUNER_CUSTOMIZE=y +# CONFIG_MEDIA_TUNER_SIMPLE is not set +# CONFIG_MEDIA_TUNER_TDA8290 is not set +# CONFIG_MEDIA_TUNER_TDA827X is not set +# CONFIG_MEDIA_TUNER_TDA18271 is not set +# CONFIG_MEDIA_TUNER_TDA9887 is not set +# CONFIG_MEDIA_TUNER_TEA5761 is not set +# CONFIG_MEDIA_TUNER_TEA5767 is not set +# CONFIG_MEDIA_TUNER_MT20XX is not set +# CONFIG_MEDIA_TUNER_MT2060 is not set +# CONFIG_MEDIA_TUNER_MT2266 is not set +# CONFIG_MEDIA_TUNER_MT2131 is not set +# CONFIG_MEDIA_TUNER_QT1010 is not set +# CONFIG_MEDIA_TUNER_XC2028 is not set +# CONFIG_MEDIA_TUNER_XC5000 is not set +# CONFIG_MEDIA_TUNER_MXL5005S 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 is not set + +# +# Encoders/decoders and other helper chips +# + +# +# Audio decoders +# +# CONFIG_VIDEO_TVAUDIO is not set +# CONFIG_VIDEO_TDA7432 is not set +# CONFIG_VIDEO_TDA9840 is not set +# CONFIG_VIDEO_TDA9875 is not set +# CONFIG_VIDEO_TEA6415C is not set +# CONFIG_VIDEO_TEA6420 is not set +# CONFIG_VIDEO_MSP3400 is not set +# CONFIG_VIDEO_CS5345 is not set +# CONFIG_VIDEO_CS53L32A is not set +# CONFIG_VIDEO_M52790 is not set +# CONFIG_VIDEO_TLV320AIC23B is not set +# CONFIG_VIDEO_WM8775 is not set +# CONFIG_VIDEO_WM8739 is not set +# CONFIG_VIDEO_VP27SMPX is not set + +# +# Video decoders +# +# CONFIG_VIDEO_BT819 is not set +# CONFIG_VIDEO_BT856 is not set +# CONFIG_VIDEO_BT866 is not set +# CONFIG_VIDEO_KS0127 is not set +# CONFIG_VIDEO_OV7670 is not set +# CONFIG_VIDEO_TCM825X is not set +# CONFIG_VIDEO_SAA7110 is not set +# CONFIG_VIDEO_SAA7111 is not set +# CONFIG_VIDEO_SAA7114 is not set +# CONFIG_VIDEO_SAA711X is not set +# CONFIG_VIDEO_SAA717X is not set +# CONFIG_VIDEO_SAA7191 is not set +# CONFIG_VIDEO_TVP5150 is not set +# CONFIG_VIDEO_VPX3220 is not set + +# +# Video and audio decoders +# +# CONFIG_VIDEO_CX25840 is not set + +# +# MPEG video encoders +# +# CONFIG_VIDEO_CX2341X is not set + +# +# Video encoders +# +# CONFIG_VIDEO_SAA7127 is not set +# CONFIG_VIDEO_SAA7185 is not set +# CONFIG_VIDEO_ADV7170 is not set +# CONFIG_VIDEO_ADV7175 is not set + +# +# Video improvement chips +# +# CONFIG_VIDEO_UPD64031A is not set +# CONFIG_VIDEO_UPD64083 is not set +# CONFIG_VIDEO_VIVI is not set +CONFIG_VIDEO_MXC_CAMERA=m + +# +# MXC Camera/V4L2 PRP Features support +# +CONFIG_VIDEO_MXC_IPU_CAMERA=y +# CONFIG_MXC_CAMERA_MC521DA is not set +# CONFIG_MXC_EMMA_CAMERA_MICRON111 is not set +# CONFIG_MXC_CAMERA_OV2640_EMMA is not set +# CONFIG_MXC_CAMERA_MICRON111 is not set +# CONFIG_MXC_CAMERA_OV2640 is not set +CONFIG_MXC_CAMERA_OV3640=m +# CONFIG_MXC_TVIN_ADV7180 is not set +CONFIG_MXC_IPU_PRP_VF_SDC=m +CONFIG_MXC_IPU_PRP_ENC=m +CONFIG_VIDEO_MXC_OUTPUT=y +CONFIG_VIDEO_MXC_IPU_OUTPUT=y +# CONFIG_VIDEO_MXC_IPUV1_WVGA_OUTPUT is not set +# CONFIG_VIDEO_MXC_OPL is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +CONFIG_V4L_USB_DRIVERS=y +# CONFIG_USB_VIDEO_CLASS is not set +# CONFIG_VIDEO_PVRUSB2 is not set +# CONFIG_VIDEO_EM28XX is not set +# CONFIG_VIDEO_USBVISION is not set +# 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_VIDEO_OVCAMCHIP is not set +# CONFIG_USB_W9968CF 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 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=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_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_MXC=y +CONFIG_FB_MXC_SYNC_PANEL=y +CONFIG_FB_MXC_EPSON_VGA_SYNC_PANEL=y +CONFIG_FB_MXC_TVOUT_TVE=y +# CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL is not set +# CONFIG_FB_MXC_SII9022 is not set +CONFIG_FB_MXC_CH7026=y +# CONFIG_FB_MXC_TVOUT is not set +# CONFIG_FB_MXC_TVOUT_CH7024 is not set +# CONFIG_FB_MXC_ASYNC_PANEL is not set +# CONFIG_FB_UVESA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +# CONFIG_LCD_CLASS_DEVICE is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +# CONFIG_BACKLIGHT_CORGI is not set +CONFIG_BACKLIGHT_MXC=y +# CONFIG_BACKLIGHT_MXC_PWM is not set +CONFIG_BACKLIGHT_MXC_MC13892=y + +# +# 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 is not set +CONFIG_FONT_8x16=y +# 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=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=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_OSSEMUL=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +CONFIG_SND_PCM_OSS_PLUGINS=y +# 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_DUMMY 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_MXC_SPDIF=m + +# +# SPI devices +# + +# +# USB devices +# +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_CAIAQ is not set + +# +# System on Chip audio support +# +CONFIG_SND_SOC=y +CONFIG_SND_MXC_SOC=y +CONFIG_SND_MXC_SOC_SSI=y +CONFIG_SND_MXC_SOC_IRAM=y +# CONFIG_SND_SOC_IMX_3STACK_WM8350 is not set +# CONFIG_SND_SOC_IMX_3STACK_AK4647 is not set +# CONFIG_SND_SOC_IMX_3STACK_WM8580 is not set +CONFIG_SND_SOC_IMX_3STACK_WM8903=y +CONFIG_SND_SOC_IMX_3STACK_SGTL5000=y +# CONFIG_SND_SOC_IMX_3STACK_BLUETOOTH is not set + +# +# ALSA SoC audio for Freescale SOCs +# + +# +# SoC Audio for the Texas Instruments OMAP +# +CONFIG_SND_SOC_WM8903=y +CONFIG_SND_SOC_SGTL5000=y + +# +# 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 is not set +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 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_EHCI_HCD=y +CONFIG_USB_EHCI_ARC=y +CONFIG_USB_EHCI_ARC_H1=y +CONFIG_USB_EHCI_ARC_H2=y +CONFIG_USB_EHCI_ARC_OTG=y +# CONFIG_USB_STATIC_IRAM is not set +# CONFIG_USB_EHCI_FSL_MC13783 is not set +# CONFIG_USB_EHCI_FSL_1301 is not set +# CONFIG_USB_EHCI_FSL_1504 is not set +CONFIG_USB_EHCI_FSL_UTMI=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +# CONFIG_USB_EHCI_TT_NEWSCHED 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=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 is not set + +# +# Belcarra USBLAN Networking for USB +# +# CONFIG_USB_USBLAN is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_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_ISIGHTFW is not set +CONFIG_USB_GADGET=m +# 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_PXA27X 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_ARC=y +CONFIG_USB_ARC=m +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +CONFIG_USB_GADGET_ARC_OTG=y +# CONFIG_USB_GADGET_FSL_MC13783 is not set +# CONFIG_USB_GADGET_FSL_1301 is not set +# CONFIG_USB_GADGET_FSL_1504 is not set +CONFIG_USB_GADGET_FSL_UTMI=y +# CONFIG_USB_ZERO is not set +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +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_USB_G_PRINTER 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 +# CONFIG_MMC_TEST is not set +CONFIG_SDIO_UNIFI_FS=m + +# +# MMC/SD Host Controller Drivers +# +# CONFIG_MMC_SPI is not set +# CONFIG_MMC_MXC is not set +CONFIG_MMC_IMX_ESDHCI=y +# CONFIG_MMC_IMX_ESDHCI_PIO_MODE is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +CONFIG_LEDS_MC13892=y + +# +# LED Triggers +# +# CONFIG_LEDS_TRIGGERS is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +# CONFIG_RTC_DRV_TEST is not set + +# +# 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 +# +# 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_RTC_MXC is not set +CONFIG_RTC_DRV_MXC_V2=y +# CONFIG_RTC_DRV_IMXDI is not set +CONFIG_RTC_MC13892=m +# CONFIG_UIO is not set + +# +# MXC support drivers +# +CONFIG_MXC_IPU=y +CONFIG_MXC_IPU_V3=y + +# +# MXC SSI support +# +# CONFIG_MXC_SSI is not set + +# +# MXC Digital Audio Multiplexer support +# +# CONFIG_MXC_DAM is not set + +# +# MXC PMIC support +# +CONFIG_MXC_PMIC=y +# CONFIG_MXC_PMIC_MC13783 is not set +CONFIG_MXC_PMIC_MC13892=y +CONFIG_MXC_PMIC_I2C=y +CONFIG_MXC_PMIC_SPI=y +# CONFIG_MXC_PMIC_MC34704 is not set +# CONFIG_MXC_PMIC_CHARDEV is not set + +# +# MXC PMIC Client Drivers +# +CONFIG_MXC_MC13892_ADC=y +CONFIG_MXC_MC13892_RTC=y +CONFIG_MXC_MC13892_LIGHT=y +CONFIG_MXC_MC13892_BATTERY=y +CONFIG_MXC_MC13892_CONNECTIVITY=y +CONFIG_MXC_MC13892_POWER=y +# CONFIG_MXC_PMIC_MC9SDZ60 is not set + +# +# Advanced Power Management devices +# + +# +# MXC Security Drivers +# +# CONFIG_MXC_SECURITY_SCC is not set +CONFIG_MXC_SECURITY_SCC2=y +CONFIG_SCC_DEBUG=y +# CONFIG_MXC_SECURITY_RNG is not set + +# +# SAHARA2 Security Hardware Support +# +CONFIG_MXC_SAHARA=y +CONFIG_MXC_SAHARA_USER_MODE=y +# CONFIG_MXC_SAHARA_POLL_MODE is not set + +# +# MXC MPEG4 Encoder Kernel module support +# +# CONFIG_MXC_HMP4E is not set + +# +# MXC HARDWARE EVENT +# +# CONFIG_MXC_HWEVENT is not set + +# +# MXC VPU(Video Processing Unit) support +# +CONFIG_MXC_VPU=y +CONFIG_MXC_VPU_IRAM=y +# CONFIG_MXC_VPU_DEBUG is not set + +# +# MXC Asynchronous Sample Rate Converter support +# + +# +# MXC Bluetooth support +# +CONFIG_MXC_BLUETOOTH=m + +# +# Broadcom GPS ioctrl support +# + +# +# MXC Media Local Bus Driver +# + +# +# i.MX ADC support +# +# CONFIG_IMX_ADC 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_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=m +# 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 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=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=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=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 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 + +# +# 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_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS 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=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 --- linux-2.6.28.orig/arch/arm/configs/imx51_3stack_defconfig +++ linux-2.6.28/arch/arm/configs/imx51_3stack_defconfig @@ -0,0 +1,1803 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.26 +# Wed Feb 11 14:35:12 2009 +# +CONFIG_ARM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +# CONFIG_GENERIC_GPIO is not set +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 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_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 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_MX37 is not set +# CONFIG_ARCH_MX35 is not set +CONFIG_ARCH_MX51=y +# CONFIG_ARCH_MX3 is not set +# CONFIG_ARCH_MX27 is not set +# CONFIG_ARCH_MX25 is not set +# CONFIG_ARCH_MX21 is not set +# CONFIG_I2C_MXC_SELECT1 is not set +CONFIG_I2C_MXC_SELECT2=y +CONFIG_MXC_SDMA_API=y +# CONFIG_I2C_MXC_SELECT3 is not set +CONFIG_SDMA_IRAM=y +CONFIG_SDMA_IRAM_SIZE=0x1000 +CONFIG_ARCH_MXC_HAS_NFC_V3=y + +# +# MX51 Options +# +CONFIG_MX51_OPTIONS=y +CONFIG_MACH_MX51_3DS=y +CONFIG_ARCH_MXC_HAS_NFC_V3_2=y + +# +# SDMA options +# + +# +# Device options +# +CONFIG_MXC_TZIC=y +CONFIG_DMA_ZONE_SIZE=64 +CONFIG_UTMI_MXC=y + +# +# Processor Type +# +CONFIG_CPU_32=y +# CONFIG_CPU_ARM926T is not set +# CONFIG_CPU_V6 is not set +CONFIG_CPU_32v6K=y +CONFIG_CPU_V7=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_PABRT_IFAR=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_ARM_THUMBEE is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_HAS_TLS_REG=y +# 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_LEDS is not set +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 rootfstype=jffs2 ip=off" +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_IMX=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_NEON=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=y +# CONFIG_PM_DEBUG is not set +CONFIG_PM_SLEEP=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_APM_EMULATION 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_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES 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=y + +# +# Queueing/Scheduling +# +# CONFIG_NET_SCH_CBQ is not set +# CONFIG_NET_SCH_HTB is not set +# CONFIG_NET_SCH_HFSC is not set +# CONFIG_NET_SCH_PRIO is not set +# CONFIG_NET_SCH_RED is not set +# CONFIG_NET_SCH_SFQ is not set +# CONFIG_NET_SCH_TEQL is not set +# CONFIG_NET_SCH_TBF is not set +# CONFIG_NET_SCH_GRED is not set +# CONFIG_NET_SCH_DSMARK is not set +# CONFIG_NET_SCH_NETEM is not set + +# +# Classification +# +# CONFIG_NET_CLS_BASIC is not set +# CONFIG_NET_CLS_TCINDEX is not set +# CONFIG_NET_CLS_ROUTE4 is not set +# CONFIG_NET_CLS_FW is not set +# CONFIG_NET_CLS_U32 is not set +# CONFIG_NET_CLS_RSVP is not set +# CONFIG_NET_CLS_RSVP6 is not set +# CONFIG_NET_CLS_FLOW is not set +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_CLS_ACT is not set +CONFIG_NET_SCH_FIFO=y + +# +# 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=y +# CONFIG_MAC80211 is not set +CONFIG_IEEE80211=y +# CONFIG_IEEE80211_DEBUG is not set +# CONFIG_IEEE80211_CRYPT_WEP is not set +# CONFIG_IEEE80211_CRYPT_CCMP is not set +# CONFIG_IEEE80211_CRYPT_TKIP 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=y +CONFIG_PROC_EVENTS=y +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 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 +# CONFIG_MTD_MXC 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=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_MXC_V3=y +# CONFIG_MTD_NAND_MXC_SWECC is not set +# CONFIG_MTD_NAND_MXC_FORCE_CE is not set +# CONFIG_MXC_NAND_LOW_LEVEL_ERASE 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 + +# +# Voltage and Current regulators +# +CONFIG_REGULATOR_API=y +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_DEBUG is not set +CONFIG_REGULATOR_MC13892=y +# CONFIG_REGULATOR_WM8350 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 is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 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 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=m +# CONFIG_ATA_NONSTANDARD is not set +# CONFIG_SATA_PMP is not set +CONFIG_ATA_SFF=y +# CONFIG_SATA_MV is not set +# CONFIG_PATA_PLATFORM is not set +CONFIG_PATA_FSL=m +# 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_ENC28J60 is not set +# CONFIG_SMC911X is not set +CONFIG_SMSC911X=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_B44 is not set +# CONFIG_CS89x0 is not set +# CONFIG_FEC 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=y + +# +# 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_KEYBOARD_MXC=y +# 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_MXC=y +# 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_TOUCHSCREEN_TSC2007 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 +CONFIG_FM_SI4702=m + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_MXC=y +CONFIG_SERIAL_MXC_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +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=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Hardware Bus support +# +CONFIG_I2C_MXC=y +CONFIG_I2C_MXC_HS=y +# 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_TINY_USB 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_I2C_SLAVE is not set +CONFIG_SPI=y +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_BITBANG=y +CONFIG_SPI_MXC=y +# CONFIG_SPI_MXC_TEST_LOOPBACK is not set +CONFIG_SPI_MXC_SELECT1=y +# CONFIG_SPI_MXC_SELECT2 is not set +# CONFIG_SPI_MXC_SELECT3 is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_AT25 is not set +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set +CONFIG_W1=m +CONFIG_W1_CON=y + +# +# 1-wire Bus Masters +# +# CONFIG_W1_MASTER_DS2490 is not set +# CONFIG_W1_MASTER_DS2482 is not set +CONFIG_W1_MASTER_MXC=m +# CONFIG_W1_MASTER_DS1WM is not set + +# +# 1-wire Slaves +# +# CONFIG_W1_SLAVE_THERM is not set +# CONFIG_W1_SLAVE_SMEM is not set +# CONFIG_W1_SLAVE_DS2751 is not set +# CONFIG_W1_SLAVE_DS2433 is not set +CONFIG_W1_SLAVE_DS2438=m +# CONFIG_W1_SLAVE_DS2760 is not set +CONFIG_POWER_SUPPLY=m +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_BATTERY_DS2760 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_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_LM70 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 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_VT1211 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 +CONFIG_SENSORS_ISL29003=y +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_MXC_WATCHDOG=y + +# +# 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_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 is not set + +# +# Encoders/decoders and other helper chips +# + +# +# Audio decoders +# +# CONFIG_VIDEO_TVAUDIO is not set +# CONFIG_VIDEO_TDA7432 is not set +# CONFIG_VIDEO_TDA9840 is not set +# CONFIG_VIDEO_TDA9875 is not set +# CONFIG_VIDEO_TEA6415C is not set +# CONFIG_VIDEO_TEA6420 is not set +# CONFIG_VIDEO_MSP3400 is not set +# CONFIG_VIDEO_CS5345 is not set +# CONFIG_VIDEO_CS53L32A is not set +# CONFIG_VIDEO_M52790 is not set +# CONFIG_VIDEO_TLV320AIC23B is not set +# CONFIG_VIDEO_WM8775 is not set +# CONFIG_VIDEO_WM8739 is not set +# CONFIG_VIDEO_VP27SMPX is not set + +# +# Video decoders +# +# CONFIG_VIDEO_BT819 is not set +# CONFIG_VIDEO_BT856 is not set +# CONFIG_VIDEO_BT866 is not set +# CONFIG_VIDEO_KS0127 is not set +# CONFIG_VIDEO_OV7670 is not set +# CONFIG_VIDEO_TCM825X is not set +# CONFIG_VIDEO_SAA7110 is not set +# CONFIG_VIDEO_SAA7111 is not set +# CONFIG_VIDEO_SAA7114 is not set +# CONFIG_VIDEO_SAA711X is not set +# CONFIG_VIDEO_SAA717X is not set +# CONFIG_VIDEO_SAA7191 is not set +# CONFIG_VIDEO_TVP5150 is not set +# CONFIG_VIDEO_VPX3220 is not set + +# +# Video and audio decoders +# +# CONFIG_VIDEO_CX25840 is not set + +# +# MPEG video encoders +# +# CONFIG_VIDEO_CX2341X is not set + +# +# Video encoders +# +# CONFIG_VIDEO_SAA7127 is not set +# CONFIG_VIDEO_SAA7185 is not set +# CONFIG_VIDEO_ADV7170 is not set +# CONFIG_VIDEO_ADV7175 is not set + +# +# Video improvement chips +# +# CONFIG_VIDEO_UPD64031A is not set +# CONFIG_VIDEO_UPD64083 is not set +# CONFIG_VIDEO_VIVI is not set +CONFIG_VIDEO_MXC_CAMERA=m + +# +# MXC Camera/V4L2 PRP Features support +# +CONFIG_VIDEO_MXC_IPU_CAMERA=y +# CONFIG_MXC_CAMERA_MC521DA is not set +# CONFIG_MXC_EMMA_CAMERA_MICRON111 is not set +# CONFIG_MXC_CAMERA_OV2640_EMMA is not set +# CONFIG_MXC_CAMERA_MICRON111 is not set +# CONFIG_MXC_CAMERA_OV2640 is not set +CONFIG_MXC_CAMERA_OV3640=m +# CONFIG_MXC_TVIN_ADV7180 is not set +CONFIG_MXC_IPU_PRP_VF_SDC=m +CONFIG_MXC_IPU_PRP_ENC=m +CONFIG_VIDEO_MXC_OUTPUT=y +CONFIG_VIDEO_MXC_IPU_OUTPUT=y +# CONFIG_VIDEO_MXC_IPUV1_WVGA_OUTPUT is not set +# CONFIG_VIDEO_MXC_OPL is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +CONFIG_V4L_USB_DRIVERS=y +# CONFIG_USB_VIDEO_CLASS is not set +# CONFIG_VIDEO_PVRUSB2 is not set +# CONFIG_VIDEO_EM28XX is not set +# CONFIG_VIDEO_USBVISION is not set +# 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_VIDEO_OVCAMCHIP is not set +# CONFIG_USB_W9968CF 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 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=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_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_MXC=y +CONFIG_FB_MXC_SYNC_PANEL=y +CONFIG_FB_MXC_EPSON_VGA_SYNC_PANEL=y +CONFIG_FB_MXC_TVOUT_TVE=y +# CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL is not set +# CONFIG_FB_MXC_TVOUT is not set +# CONFIG_FB_MXC_TVOUT_CH7024 is not set +# CONFIG_FB_MXC_ASYNC_PANEL is not set +# CONFIG_FB_UVESA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +# CONFIG_LCD_CLASS_DEVICE is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +# CONFIG_BACKLIGHT_CORGI is not set +CONFIG_BACKLIGHT_MXC=y +CONFIG_BACKLIGHT_MXC_MC13892=y + +# +# 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 is not set +CONFIG_FONT_8x16=y +# 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=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=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_OSSEMUL=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +CONFIG_SND_PCM_OSS_PLUGINS=y +# 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_DUMMY 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_MXC_SPDIF=m + +# +# SPI devices +# + +# +# USB devices +# +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_CAIAQ is not set + +# +# System on Chip audio support +# +CONFIG_SND_SOC=y +CONFIG_SND_MXC_SOC=y +CONFIG_SND_MXC_SOC_SSI=y +CONFIG_SND_MXC_SOC_IRAM=y +# CONFIG_SND_SOC_IMX_3STACK_WM8350 is not set +# CONFIG_SND_SOC_IMX_3STACK_AK4647 is not set +# CONFIG_SND_SOC_IMX_3STACK_WM8580 is not set +CONFIG_SND_SOC_IMX_3STACK_WM8903=y +CONFIG_SND_SOC_IMX_3STACK_SGTL5000=y +# CONFIG_SND_SOC_IMX_3STACK_BLUETOOTH is not set + +# +# ALSA SoC audio for Freescale SOCs +# + +# +# SoC Audio for the Texas Instruments OMAP +# +CONFIG_SND_SOC_WM8903=y +CONFIG_SND_SOC_SGTL5000=y + +# +# 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=m +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +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 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_EHCI_HCD=m +CONFIG_USB_EHCI_ARC=y +CONFIG_USB_EHCI_ARC_H1=y +CONFIG_USB_EHCI_ARC_OTG=y +# CONFIG_USB_STATIC_IRAM is not set +# CONFIG_USB_EHCI_FSL_MC13783 is not set +# CONFIG_USB_EHCI_FSL_1301 is not set +# CONFIG_USB_EHCI_FSL_1504 is not set +CONFIG_USB_EHCI_FSL_UTMI=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +# CONFIG_USB_EHCI_TT_NEWSCHED 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=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 is not set + +# +# Belcarra USBLAN Networking for USB +# +# CONFIG_USB_USBLAN is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_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_ISIGHTFW is not set +CONFIG_USB_GADGET=m +# 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_PXA27X 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_ARC=y +CONFIG_USB_ARC=m +# CONFIG_USB_GADGET_S3C2410 is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +CONFIG_USB_GADGET_DUALSPEED=y +CONFIG_USB_GADGET_ARC_OTG=y +# CONFIG_USB_GADGET_FSL_MC13783 is not set +# CONFIG_USB_GADGET_FSL_1301 is not set +# CONFIG_USB_GADGET_FSL_1504 is not set +CONFIG_USB_GADGET_FSL_UTMI=y +# CONFIG_USB_ZERO is not set +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +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_USB_G_PRINTER 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 +# CONFIG_MMC_TEST is not set +CONFIG_SDIO_UNIFI_FS=m + +# +# MMC/SD Host Controller Drivers +# +# CONFIG_MMC_SPI is not set +# CONFIG_MMC_MXC is not set +CONFIG_MMC_IMX_ESDHCI=m +# CONFIG_MMC_IMX_ESDHCI_PIO_MODE is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +CONFIG_LEDS_MC13892=y + +# +# LED Triggers +# +# CONFIG_LEDS_TRIGGERS is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +# CONFIG_RTC_DRV_TEST is not set + +# +# 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 +# +# 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_RTC_MXC is not set +CONFIG_RTC_DRV_MXC_V2=y +# CONFIG_RTC_DRV_IMXDI is not set +CONFIG_RTC_MC13892=m +# CONFIG_UIO is not set + +# +# MXC support drivers +# +CONFIG_MXC_IPU=y +CONFIG_MXC_IPU_V3=y + +# +# MXC SSI support +# +# CONFIG_MXC_SSI is not set + +# +# MXC Digital Audio Multiplexer support +# +# CONFIG_MXC_DAM is not set + +# +# MXC PMIC support +# +CONFIG_MXC_PMIC=y +# CONFIG_MXC_PMIC_MC13783 is not set +CONFIG_MXC_PMIC_MC13892=y +CONFIG_MXC_PMIC_I2C=y +CONFIG_MXC_PMIC_SPI=y +# CONFIG_MXC_PMIC_MC34704 is not set +# CONFIG_MXC_PMIC_CHARDEV is not set + +# +# MXC PMIC Client Drivers +# +CONFIG_MXC_MC13892_ADC=y +CONFIG_MXC_MC13892_RTC=y +CONFIG_MXC_MC13892_LIGHT=y +CONFIG_MXC_MC13892_BATTERY=y +CONFIG_MXC_MC13892_CONNECTIVITY=y +CONFIG_MXC_MC13892_POWER=y +# CONFIG_MXC_PMIC_MC9SDZ60 is not set + +# +# Advanced Power Management devices +# + +# +# MXC Security Drivers +# +# CONFIG_MXC_SECURITY_SCC is not set +CONFIG_MXC_SECURITY_SCC2=y +CONFIG_SCC_DEBUG=y +# CONFIG_MXC_SECURITY_RNG is not set + +# +# SAHARA2 Security Hardware Support +# +CONFIG_MXC_SAHARA=y +CONFIG_MXC_SAHARA_USER_MODE=y +# CONFIG_MXC_SAHARA_POLL_MODE is not set + +# +# MXC MPEG4 Encoder Kernel module support +# +# CONFIG_MXC_HMP4E is not set + +# +# MXC HARDWARE EVENT +# +# CONFIG_MXC_HWEVENT is not set + +# +# MXC VPU(Video Processing Unit) support +# +CONFIG_MXC_VPU=y +CONFIG_MXC_VPU_IRAM=y +# CONFIG_MXC_VPU_DEBUG is not set + +# +# MXC Asynchronous Sample Rate Converter support +# + +# +# MXC Bluetooth support +# +CONFIG_MXC_BLUETOOTH=m + +# +# Broadcom GPS ioctrl support +# + +# +# MXC Media Local Bus Driver +# + +# +# i.MX ADC support +# +# CONFIG_IMX_ADC 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 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=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=m +# 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 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=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=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=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 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 + +# +# 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_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS 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=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 --- linux-2.6.28.orig/arch/arm/mach-mx51/iomux.c +++ linux-2.6.28/arch/arm/mach-mx51/iomux.c @@ -0,0 +1,248 @@ +/* + * Copyright 2008-2009 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 + */ + +/*! + * @defgroup GPIO_MX51 Board GPIO and Muxing Setup + * @ingroup MSL_MX51 + */ +/*! + * @file mach-mx51/iomux.c + * + * @brief I/O Muxing control functions + * + * @ingroup GPIO_MX51 + */ + +#include +#include +#include +#include +#include +#include "iomux.h" + +/*! + * IOMUX register (base) addresses + */ +enum iomux_reg_addr { + IOMUXGPR0 = IO_ADDRESS(IOMUXC_BASE_ADDR), + IOMUXGPR1 = IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x004, + IOMUXSW_MUX_CTL = IO_ADDRESS(IOMUXC_BASE_ADDR), + IOMUXSW_MUX_END = IO_ADDRESS(IOMUXC_BASE_ADDR) + MUX_I_END, + IOMUXSW_PAD_CTL = IO_ADDRESS(IOMUXC_BASE_ADDR) + PAD_I_START, + IOMUXSW_INPUT_CTL = IO_ADDRESS(IOMUXC_BASE_ADDR), +}; + +#define MUX_PIN_NUM_MAX ((MUX_I_END >> 2) + 1) + +static u8 iomux_pin_res_table[MUX_PIN_NUM_MAX]; +static DEFINE_SPINLOCK(gpio_mux_lock); + +static inline u32 _get_mux_reg(iomux_pin_name_t pin) +{ + u32 mux_reg = PIN_TO_IOMUX_MUX(pin); + + if (cpu_is_mx51_rev(CHIP_REV_2_0) < 0) { + if ((pin == MX51_PIN_NANDF_RB5) || + (pin == MX51_PIN_NANDF_RB6) || + (pin == MX51_PIN_NANDF_RB7)) + ; /* Do nothing */ + else if (mux_reg >= 0x2FC) + mux_reg += 8; + else if (mux_reg >= 0x130) + mux_reg += 0xC; + } + mux_reg += IOMUXSW_MUX_CTL; + return mux_reg; +} + +static inline u32 _get_pad_reg(iomux_pin_name_t pin) +{ + u32 pad_reg = PIN_TO_IOMUX_PAD(pin); + + if (cpu_is_mx51_rev(CHIP_REV_2_0) < 0) { + if ((pin == MX51_PIN_NANDF_RB5) || + (pin == MX51_PIN_NANDF_RB6) || + (pin == MX51_PIN_NANDF_RB7)) + ; /* Do nothing */ + else if (pad_reg == 0x4D0 - PAD_I_START) + pad_reg += 0x4C; + else if (pad_reg == 0x860 - PAD_I_START) + pad_reg += 0x9C; + else if (pad_reg >= 0x804 - PAD_I_START) + pad_reg += 0xB0; + else if (pad_reg >= 0x7FC - PAD_I_START) + pad_reg += 0xB4; + else if (pad_reg >= 0x4E4 - PAD_I_START) + pad_reg += 0xCC; + else + pad_reg += 8; + } + pad_reg += IOMUXSW_PAD_CTL; + return pad_reg; +} + +static inline u32 _get_mux_end(void) +{ + if (cpu_is_mx51_rev(CHIP_REV_2_0) < 0) + return(IO_ADDRESS(IOMUXC_BASE_ADDR) + (0x3F8 - 4)); + else + return(IO_ADDRESS(IOMUXC_BASE_ADDR) + (0x3F0 - 4)); +} + +/*! + * This function is used to configure a pin through the IOMUX module. + * @param pin a pin number as defined in \b #iomux_pin_name_t + * @param config a configuration as defined in \b #iomux_pin_cfg_t + * + * @return 0 if successful; Non-zero otherwise + */ +static int iomux_config_mux(iomux_pin_name_t pin, iomux_pin_cfg_t config) +{ + u32 ret = 0; + u32 pin_index = PIN_TO_IOMUX_INDEX(pin); + u32 mux_reg = _get_mux_reg(pin); + u32 mux_data = 0; + u8 *rp; + + BUG_ON((mux_reg > _get_mux_end()) || (mux_reg < IOMUXSW_MUX_CTL)); + spin_lock(&gpio_mux_lock); + + if (config == IOMUX_CONFIG_GPIO) + mux_data = PIN_TO_ALT_GPIO(pin); + else + mux_data = config; + + __raw_writel(mux_data, mux_reg); + + /* + * Log a warning if a pin changes ownership + */ + rp = iomux_pin_res_table + pin_index; + if ((mux_data & *rp) && (*rp != mux_data)) { + /* + * Don't call printk if we're tweaking the console uart or + * we'll deadlock. + */ + printk(KERN_ERR "iomux_config_mux: Warning: iomux pin" + " config changed, pin=%d, " + " prev=0x%x new=0x%x\n", mux_reg, *rp, mux_data); + ret = -EINVAL; + } + *rp = mux_data; + spin_unlock(&gpio_mux_lock); + return ret; +} + +/*! + * Request ownership for an IO pin. This function has to be the first one + * being called before that pin is used. The caller has to check the + * return value to make sure it returns 0. + * + * @param pin a name defined by \b iomux_pin_name_t + * @param config a configuration as defined in \b #iomux_pin_cfg_t + * + * @return 0 if successful; Non-zero otherwise + */ +int mxc_request_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t config) +{ + int ret = iomux_config_mux(pin, config); + int gpio_port = GPIO_TO_PORT(IOMUX_TO_GPIO(pin)); + + if (!ret && (gpio_port != NON_GPIO_PORT) + && ((config == IOMUX_CONFIG_GPIO) + || (config == PIN_TO_ALT_GPIO(pin)))) + ret |= mxc_request_gpio(pin); + + return ret; +} +EXPORT_SYMBOL(mxc_request_iomux); + +/*! + * Release ownership for an IO pin + * + * @param pin a name defined by \b iomux_pin_name_t + * @param config config as defined in \b #iomux_pin_ocfg_t + */ +void mxc_free_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t config) +{ + u32 pin_index = PIN_TO_IOMUX_INDEX(pin); + u8 *rp = iomux_pin_res_table + pin_index; + int gpio_port = GPIO_TO_PORT(IOMUX_TO_GPIO(pin)); + + *rp = 0; + if ((gpio_port != NON_GPIO_PORT) + && ((config == IOMUX_CONFIG_GPIO) + || (config == PIN_TO_ALT_GPIO(pin)))) + mxc_free_gpio(pin); + +} +EXPORT_SYMBOL(mxc_free_iomux); + +/*! + * This function configures the pad value for a IOMUX pin. + * + * @param pin a pin number as defined in \b #iomux_pin_name_t + * @param config the ORed value of elements defined in \b #iomux_pad_config_t + */ +void mxc_iomux_set_pad(iomux_pin_name_t pin, u32 config) +{ + u32 pad_reg = _get_pad_reg(pin); + + BUG_ON(pad_reg < IOMUXSW_PAD_CTL); + __raw_writel(config, pad_reg); +} +EXPORT_SYMBOL(mxc_iomux_set_pad); + +unsigned int mxc_iomux_get_pad(iomux_pin_name_t pin) +{ + u32 pad_reg = _get_pad_reg(pin); + + return __raw_readl(pad_reg); +} +EXPORT_SYMBOL(mxc_iomux_get_pad); + +/*! + * This function configures input path. + * + * @param input index of input select register as defined in \b #iomux_input_select_t + * @param config the binary value of elements defined in \b #iomux_input_config_t + * */ +void mxc_iomux_set_input(iomux_input_select_t input, u32 config) +{ + u32 reg; + + if (cpu_is_mx51_rev(CHIP_REV_2_0) < 0) { + if (input == MUX_IN_IPU_IPP_DI_0_IND_DISPB_SD_D_SELECT_INPUT) + input -= 4; + else if (input == MUX_IN_IPU_IPP_DI_1_IND_DISPB_SD_D_SELECT_INPUT) + input -= 3; + else if (input >= MUX_IN_KPP_IPP_IND_COL_6_SELECT_INPUT) + input -= 2; + else if (input >= MUX_IN_HSC_MIPI_MIX_PAR_SISG_TRIG_SELECT_INPUT) + input -= 5; + else if (input >= MUX_IN_HSC_MIPI_MIX_IPP_IND_SENS1_DATA_EN_SELECT_INPUT) + input -= 3; + else if (input >= MUX_IN_ECSPI2_IPP_IND_SS_B_3_SELECT_INPUT) + input -= 2; + else if (input >= MUX_IN_CCM_PLL1_BYPASS_CLK_SELECT_INPUT) + input -= 1; + + reg = IOMUXSW_INPUT_CTL + (input << 2) + INPUT_CTL_START_TO1; + } else { + reg = IOMUXSW_INPUT_CTL + (input << 2) + INPUT_CTL_START; + } + + BUG_ON(input >= MUX_INPUT_NUM_MUX); + __raw_writel(config, reg); +} +EXPORT_SYMBOL(mxc_iomux_set_input); --- linux-2.6.28.orig/arch/arm/mach-mx51/suspend.S +++ linux-2.6.28/arch/arm/mach-mx51/suspend.S @@ -0,0 +1,145 @@ +/* + * Copyright 2008-2009 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 + */ + +#include + +#define ARM_CTRL_DCACHE 1 << 2 +#define ARM_CTRL_ICACHE 1 << 12 +#define ARM_AUXCR_L2EN 1 << 1 + + +/* + * cpu_do_suspend_workaround() + * + * Suspend the processor (eg, wait for interrupt). + * + * IRQs are already disabled. + */ +ENTRY(cpu_do_suspend_workaround) + stmfd sp!, {r4,r5,r7,r9,r10,r11} @ Save registers + + /* Disable L1 caches */ + mrc p15, 0, r0, c1, c0, 0 @ R0 = system control reg + bic r0, r0, #ARM_CTRL_ICACHE @ Disable ICache + bic r0, r0, #ARM_CTRL_DCACHE @ Disable DCache + mcr p15, 0, r0, c1, c0, 0 @ Update system control reg + + mrc p15, 1, r0, c0, c0, 1 @ Read CLIDR + ands r3, r0, #0x7000000 @ Isolate level of coherency + mov r3, r3, lsr #23 @ Cache level value (naturally aligned) + beq FinishedClean + mov r10, #0 +Loop1Clean: + add r2, r10, r10, lsr #1 @ Work out cache level + mov r1, r0, lsr r2 @ R0 bottom 3 bits = Cache Type for this level + and r1, r1, #7 @ Get those 3 bits alone + cmp r1, #2 + blt SkipClean @ No cache or only instruction cache at this level + mcr p15, 2, r10, c0, c0, 0 @ Write the Cache Size selection register + mov r1, #0 + .long 0xF57FF06F @ ISB + mrc p15, 1, r1, c0, c0, 0 @ Reads current Cache Size ID register + and r2, r1, #7 @ Extract the line length field + add r2, r2, #4 @ Add 4 for the line length offset (log2 16 bytes) + ldr r4, =0x3FF + ands r4, r4, r1, lsr #3 @ R4 is the max number on the way size (right aligned) + clz r5, r4 @ R5 is the bit position of the way size increment + ldr r7, =0x00007FFF + ands r7, r7, r1, lsr #13 @ R7 is the max number of the index size (right aligned) +Loop2Clean: + mov r9, r4 @ R9 working copy of the max way size (right aligned) +Loop3Clean: + orr r11, r10, r9, lsl r5 @ Factor in the way number and cache number into R11 + orr r11, r11, r7, lsl r2 @ Factor in the index number + mcr p15, 0, r11, c7, c14, 2 @ Clean and invalidate by set/way + subs r9, r9, #1 @ Decrement the way number + bge Loop3Clean + subs r7, r7, #1 @ Decrement the index + bge Loop2Clean +SkipClean: + add r10, r10, #2 @ Increment the cache number + cmp r3, r10 + bgt Loop1Clean + +FinishedClean: + + /* Disable L2 cache */ + mrc p15, 0, r0, c1, c0, 1 @ R0 = auxiliary control reg + bic r0, r0, #ARM_AUXCR_L2EN @ Disable L2 cache + mcr p15, 0, r0, c1, c0, 1 @ Update aux control reg + + .long 0xe320f003 @ Opcode for WFI + + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ Invalidate inst cache + + /* Invalidate data caches */ + mrc p15, 1, r0, c0, c0, 1 @ Read CLIDR + ands r3, r0, #0x7000000 @ Isolate level of coherency + mov r3, r3, lsr #23 @ Cache level value (naturally aligned) + beq FinishedInvalidate + mov r10, #0 +Loop1Invalidate: + add r2, r10, r10, lsr #1 @ Work out cache level + mov r1, r0, lsr r2 @ R0 bottom 3 bits = Cache Type for this level + and r1, r1, #7 @ Get those 3 bits alone + cmp r1, #2 + blt SkipInvalidate @ No cache or only instruction cache at this level + mcr p15, 2, r10, c0, c0, 0 @ Write the Cache Size selection register + mov r1, #0 + .long 0xF57FF06F @ ISB + mrc p15, 1, r1, c0, c0, 0 @ Reads current Cache Size ID register + and r2, r1, #7 @ Extract the line length field + add r2, r2, #4 @ Add 4 for the line length offset (log2 16 bytes) + ldr r4, =0x3FF + ands r4, r4, r1, lsr #3 @ R4 is the max number on the way size (right aligned) + clz r5, r4 @ R5 is the bit position of the way size increment + ldr r7, =0x00007FFF + ands r7, r7, r1, lsr #13 @ R7 is the max number of the index size (right aligned) +Loop2Invalidate: + mov r9, r4 @ R9 working copy of the max way size (right aligned) +Loop3Invalidate: + orr r11, r10, r9, lsl r5 @ Factor in the way number and cache number into R11 + orr r11, r11, r7, lsl r2 @ Factor in the index number + mcr p15, 0, r11, c7, c6, 2 @ Invalidate by set/way + subs r9, r9, #1 @ Decrement the way number + bge Loop3Invalidate + subs r7, r7, #1 @ Decrement the index + bge Loop2Invalidate +SkipInvalidate: + add r10, r10, #2 @ Increment the cache number + cmp r3, r10 + bgt Loop1Invalidate + +FinishedInvalidate: + + /* Enable L2 cache */ + mrc p15, 0, r0, c1, c0, 1 @ R0 = auxiliary control reg + orr r0, r0, #ARM_AUXCR_L2EN @ Enable L2 cache + mcr p15, 0, r0, c1, c0, 1 @ Update aux control reg + + /* Enable L1 caches */ + mrc p15, 0, r0, c1, c0, 0 @ R0 = system control reg + orr r0, r0, #ARM_CTRL_ICACHE @ Enable ICache + orr r0, r0, #ARM_CTRL_DCACHE @ Enable DCache + mcr p15, 0, r0, c1, c0, 0 @ Update system control reg + + /* Restore registers */ + ldmfd sp!, {r4,r5,r7,r9,r10,r11} + mov pc, lr + + .type cpu_do_suspend, #object +ENTRY(cpu_do_suspend) + .word cpu_do_suspend_workaround + .size cpu_do_suspend_workaround, . - cpu_do_suspend_workaround + + --- linux-2.6.28.orig/arch/arm/mach-mx51/mx51_3stack.c +++ linux-2.6.28/arch/arm/mach-mx51/mx51_3stack.c @@ -0,0 +1,1077 @@ +/* + * Copyright 2008-2009 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE) +#include +#include +#include + +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "board-mx51_3stack.h" +#include "iomux.h" +#include "crm_regs.h" + +/*! + * @file mach-mx51/mx51_3stack.c + * + * @brief This file contains the board specific initialization routines. + * + * @ingroup MSL_MX51 + */ +extern void __init mx51_3stack_io_init(void); +extern struct cpu_wp *(*get_cpu_wp)(int *wp); + +/* working point(wp): 0 - 800MHz; 1 - 200MHz; */ +static struct cpu_wp cpu_wp_auto[] = { + { + .pll_rate = 800000000, + .cpu_rate = 800000000, + .pdf = 0, + .mfi = 8, + .mfd = 2, + .mfn = 1, + .cpu_podf = 0, + .cpu_voltage = 1050000,}, + { + .pll_rate = 800000000, + .cpu_rate = 200000000, + .pdf = 3, + .mfi = 8, + .mfd = 2, + .mfn = 1, + .cpu_podf = 3, + .cpu_voltage = 775000,}, +}; + +struct cpu_wp *mx51_3stack_get_cpu_wp(int *wp) +{ + *wp = 2; + return cpu_wp_auto; +} + +static void mxc_nop_release(struct device *dev) +{ + /* Nothing */ +} + +#if defined(CONFIG_KEYBOARD_MXC) || defined(CONFIG_KEYBOARD_MXC_MODULE) +static u16 keymapping[24] = { + KEY_1, KEY_2, KEY_3, KEY_F1, KEY_UP, KEY_F2, + KEY_4, KEY_5, KEY_6, KEY_LEFT, KEY_SELECT, KEY_RIGHT, + KEY_7, KEY_8, KEY_9, KEY_F3, KEY_DOWN, KEY_F4, + KEY_0, KEY_OK, KEY_ESC, KEY_ENTER, KEY_MENU, KEY_BACK, +}; + +static struct resource mxc_kpp_resources[] = { + [0] = { + .start = MXC_INT_KPP, + .end = MXC_INT_KPP, + .flags = IORESOURCE_IRQ, + } +}; + +static struct keypad_data keypad_plat_data = { + .rowmax = 4, + .colmax = 6, + .irq = MXC_INT_KPP, + .learning = 0, + .delay = 2, + .matrix = keymapping, +}; + +/* mxc keypad driver */ +static struct platform_device mxc_keypad_device = { + .name = "mxc_keypad", + .id = 0, + .num_resources = ARRAY_SIZE(mxc_kpp_resources), + .resource = mxc_kpp_resources, + .dev = { + .release = mxc_nop_release, + .platform_data = &keypad_plat_data, + }, +}; + +static void mxc_init_keypad(void) +{ + (void)platform_device_register(&mxc_keypad_device); +} +#else +static inline void mxc_init_keypad(void) +{ +} +#endif + +/* MTD NAND flash */ +#if defined(CONFIG_MTD_NAND_MXC) \ + || defined(CONFIG_MTD_NAND_MXC_MODULE) \ + || defined(CONFIG_MTD_NAND_MXC_V2) \ + || defined(CONFIG_MTD_NAND_MXC_V2_MODULE) \ + || defined(CONFIG_MTD_NAND_MXC_V3) \ + || defined(CONFIG_MTD_NAND_MXC_V3_MODULE) + +static struct mtd_partition mxc_nand_partitions[] = { + { + .name = "bootloader", + .offset = 0, + .size = 3 * 1024 * 1024}, + { + .name = "nand.kernel", + .offset = MTDPART_OFS_APPEND, + .size = 5 * 1024 * 1024}, + { + .name = "nand.rootfs", + .offset = MTDPART_OFS_APPEND, + .size = 128 * 1024 * 1024}, + { + .name = "nand.userfs1", + .offset = MTDPART_OFS_APPEND, + .size = 256 * 1024 * 1024}, + { + .name = "nand.userfs2", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL}, +}; + +extern void gpio_nand_active(void); +extern void gpio_nand_inactive(void); + +static int nand_init(void) +{ + /* Configure the pins */ + gpio_nand_active(); + return 0; +} + +static void nand_exit(void) +{ + /* Free the pins */ + gpio_nand_inactive(); +} + +static struct flash_platform_data mxc_nand_data = { + .parts = mxc_nand_partitions, + .nr_parts = ARRAY_SIZE(mxc_nand_partitions), + .width = 1, + .init = nand_init, + .exit = nand_exit, +}; + +static struct platform_device mxc_nandv2_mtd_device = { + .name = "mxc_nandv2_flash", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxc_nand_data, + }, +}; + +static void mxc_init_nand_mtd(void) +{ + (void)platform_device_register(&mxc_nandv2_mtd_device); +} +#else +static inline void mxc_init_nand_mtd(void) +{ +} +#endif + +#if defined(CONFIG_FB_MXC_SYNC_PANEL) || \ + defined(CONFIG_FB_MXC_SYNC_PANEL_MODULE) +static struct platform_device mxc_fb_device[] = { + { + .name = "mxc_sdc_fb", + .id = 0, + .dev = { + .release = mxc_nop_release, + .coherent_dma_mask = 0xFFFFFFFF, + }, + }, + { + .name = "mxc_sdc_fb", + .id = 1, + .dev = { + .release = mxc_nop_release, + .coherent_dma_mask = 0xFFFFFFFF, + }, + }, + { + .name = "mxc_sdc_fb", + .id = 2, + .dev = { + .release = mxc_nop_release, + .coherent_dma_mask = 0xFFFFFFFF, + }, + }, +}; + +static void lcd_reset_to2(void) +{ + ipu_reset_disp_panel(); + + return; +} + +static void lcd_reset(void) +{ + mxc_set_gpio_dataout(MX51_PIN_DISPB2_SER_RS, 0); + mxc_set_gpio_direction(MX51_PIN_DISPB2_SER_RS, 0); + /* do reset */ + msleep(10); /* tRES >= 100us */ + mxc_set_gpio_dataout(MX51_PIN_DISPB2_SER_RS, 1); + msleep(60); +} + +static struct mxc_lcd_platform_data lcd_data = { + .core_reg = "VIOHI", + .io_reg = "SW4", + .reset = lcd_reset, +}; + +static struct platform_device mxc_lcd_device = { + .name = "lcd_spi", + .dev = { + .release = mxc_nop_release, + .platform_data = &lcd_data, + }, +}; + +static struct mxc_lcd_platform_data lcd_wvga_data; + +static struct platform_device lcd_wvga_device = { + .name = "lcd_claa", + .dev = { + .release = mxc_nop_release, + .platform_data = &lcd_wvga_data, + }, +}; + +static void mxc_init_fb(void) +{ + + if (cpu_is_mx51_rev(CHIP_REV_2_0) > 0) + lcd_data.reset = lcd_reset_to2; + + (void)platform_device_register(&mxc_lcd_device); + (void)platform_device_register(&lcd_wvga_device); + + (void)platform_device_register(&mxc_fb_device[0]); + (void)platform_device_register(&mxc_fb_device[1]); + (void)platform_device_register(&mxc_fb_device[2]); +} +#else +static inline void mxc_init_fb(void) +{ +} +#endif + +static struct platform_device mxcbl_device = { + .name = "mxc_mc13892_bl", +}; + +static inline void mxc_init_bl(void) +{ + platform_device_register(&mxcbl_device); +} + +void si4702_reset(void) +{ + mxc_set_gpio_dataout(MX51_PIN_EIM_DTACK, 0); + msleep(100); + mxc_set_gpio_dataout(MX51_PIN_EIM_DTACK, 1); + msleep(100); +} + +void si4702_clock_ctl(int flag) +{ +} + +static void si4702_gpio_get(void) +{ + /* reset pin */ + mxc_request_iomux(MX51_PIN_EIM_DTACK, IOMUX_CONFIG_GPIO); + mxc_set_gpio_direction(MX51_PIN_EIM_DTACK, 0); +} + +static void si4702_gpio_put(void) +{ + mxc_free_iomux(MX51_PIN_EIM_DTACK, IOMUX_CONFIG_GPIO); +} + +static struct mxc_fm_platform_data si4702_data = { + .reg_vio = "SW4", + .reg_vdd = "VIOHI", + .gpio_get = si4702_gpio_get, + .gpio_put = si4702_gpio_put, + .reset = si4702_reset, + .clock_ctl = si4702_clock_ctl, + .sksnr = 0, + .skcnt = 0, + .band = 0, + .space = 100, + .seekth = 0xa, +}; + +#if defined(CONFIG_I2C_MXC) || defined(CONFIG_I2C_MXC_MODULE) + +#ifdef CONFIG_I2C_MXC_SELECT1 +static struct i2c_board_info mxc_i2c0_board_info[] __initdata = { +}; +#endif +#ifdef CONFIG_I2C_MXC_SELECT2 +static struct i2c_board_info mxc_i2c1_board_info[] __initdata = { + { + .type = "wm8903-i2c", + .addr = 0x1a, + }, + { + .type = "sgtl5000-i2c", + .addr = 0x0a, + }, + { + .type = "tsc2007", + .addr = 0x48, + .irq = IOMUX_TO_IRQ(MX51_PIN_GPIO1_5), + }, + { + .type = "si4702", + .addr = 0x10, + .platform_data = (void *)&si4702_data, + }, +}; +#endif +#if defined(CONFIG_I2C_MXC_HS) || defined(CONFIG_I2C_MXC_HS_MODULE) +static struct mxc_camera_platform_data camera_data = { + .io_regulator = "SW4", + .analog_regulator = "VIOHI", + .mclk = 24000000, + .csi = 0, +}; +static struct mxc_lightsensor_platform_data ls_data = { + .vdd_reg = NULL, + .rext = 100, +}; + +static struct i2c_board_info mxc_i2c_hs_board_info[] __initdata = { + { + .type = "ov3640", + .addr = 0x3C, + .platform_data = (void *)&camera_data, + }, + { + .type = "isl29003", + .addr = 0x44, + .platform_data = &ls_data, + }, +}; +#endif + +#endif + +static u32 cpld_base_addr; + +/*lan9217 device*/ +#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE) +static struct resource smsc911x_resources[] = { + { + .flags = IORESOURCE_MEM, + }, + { + .start = LAN9217_IRQ, + .end = LAN9217_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; +static struct platform_device smsc_lan9217_device = { + .name = "smsc911x", + .id = 0, + .dev = { + .release = mxc_nop_release, + }, + .num_resources = ARRAY_SIZE(smsc911x_resources), + .resource = smsc911x_resources, +}; +static void mxc_init_enet(void) +{ + smsc_lan9217_device.resource[0].start = + LAN9217_BASE_ADDR(cpld_base_addr); + smsc_lan9217_device.resource[0].end = LAN9217_BASE_ADDR(cpld_base_addr) + + 0x100; + (void)platform_device_register(&smsc_lan9217_device); +} +#else +static inline void mxc_init_enet(void) +{ +} +#endif + +#if defined(CONFIG_MMC_IMX_ESDHCI) || defined(CONFIG_MMC_IMX_ESDHCI_MODULE) +/*! + * Get WP pin value to detect write protection + */ +int sdhc_write_protect(struct device *dev) +{ + unsigned short rc = 0; + + if (to_platform_device(dev)->id == 0) + rc = mxc_get_gpio_datain(MX51_PIN_GPIO1_1); + else + rc = 0; + return rc; +} + +/* + * Probe for the card. If present the GPIO data would be set. + */ +int sdhc_get_card_det_status(struct device *dev) +{ + int ret; + + if (to_platform_device(dev)->id == 0) { + ret = mxc_get_gpio_datain(MX51_PIN_GPIO1_0); + return ret; + } else { /* config the det pin for SDHC2 */ + return 0; + } +} + +static struct mxc_mmc_platform_data mmc_data = { + .ocr_mask = MMC_VDD_32_33, + .caps = MMC_CAP_4_BIT_DATA, + .min_clk = 400000, + .max_clk = 52000000, + .card_inserted_state = 0, + .status = sdhc_get_card_det_status, + .wp_status = sdhc_write_protect, + .clock_mmc = "esdhc_clk", + .power_mmc = NULL, +}; + +/*! + * Resource definition for the SDHC1 + */ +static struct resource mxcsdhc1_resources[] = { + [0] = { + .start = MMC_SDHC1_BASE_ADDR, + .end = MMC_SDHC1_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_MMC_SDHC1, + .end = MXC_INT_MMC_SDHC1, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IOMUX_TO_IRQ(MX51_PIN_GPIO1_0), + .end = IOMUX_TO_IRQ(MX51_PIN_GPIO1_0), + .flags = IORESOURCE_IRQ, + }, +}; + +/*! + * Resource definition for the SDHC2 + */ +static struct resource mxcsdhc2_resources[] = { + [0] = { + .start = MMC_SDHC2_BASE_ADDR, + .end = MMC_SDHC2_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_MMC_SDHC2, + .end = MXC_INT_MMC_SDHC2, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = 0, + .end = 0, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! Device Definition for MXC SDHC1 */ +static struct platform_device mxcsdhc1_device = { + .name = "mxsdhci", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mmc_data, + }, + .num_resources = ARRAY_SIZE(mxcsdhc1_resources), + .resource = mxcsdhc1_resources, +}; + +/*! Device Definition for MXC SDHC2 */ +static struct platform_device mxcsdhc2_device = { + .name = "mxsdhci", + .id = 1, + .dev = { + .release = mxc_nop_release, + .platform_data = &mmc_data, + }, + .num_resources = ARRAY_SIZE(mxcsdhc2_resources), + .resource = mxcsdhc2_resources, +}; + +static inline void mxc_init_mmc(void) +{ + (void)platform_device_register(&mxcsdhc1_device); + (void)platform_device_register(&mxcsdhc2_device); +} +#else +static inline void mxc_init_mmc(void) +{ +} +#endif + +static u32 brd_io; +static void expio_ack_irq(u32 irq); + +static void mxc_expio_irq_handler(u32 irq, struct irq_desc *desc) +{ + u32 imr_val; + u32 int_valid; + u32 expio_irq; + + desc->chip->mask(irq); /* irq = gpio irq number */ + + imr_val = __raw_readw(brd_io + INTR_MASK_REG); + int_valid = __raw_readw(brd_io + INTR_STATUS_REG) & ~imr_val; + + if (unlikely(!int_valid)) + goto out; + + expio_irq = MXC_EXP_IO_BASE; + for (; int_valid != 0; int_valid >>= 1, expio_irq++) { + struct irq_desc *d; + if ((int_valid & 1) == 0) + continue; + d = irq_desc + expio_irq; + if (unlikely(!(d->handle_irq))) { + printk(KERN_ERR "\nEXPIO irq: %d unhandled\n", + expio_irq); + BUG(); /* oops */ + } + d->handle_irq(expio_irq, d); + } + + out: + desc->chip->ack(irq); + desc->chip->unmask(irq); +} + +/* + * Disable an expio pin's interrupt by setting the bit in the imr. + * @param irq an expio virtual irq number + */ +static void expio_mask_irq(u32 irq) +{ + u16 reg; + u32 expio = MXC_IRQ_TO_EXPIO(irq); + /* mask the interrupt */ + reg = __raw_readw(brd_io + INTR_MASK_REG); + reg |= (1 << expio); + __raw_writew(reg, brd_io + INTR_MASK_REG); +} + +/* + * Acknowledge an expanded io pin's interrupt by clearing the bit in the isr. + * @param irq an expanded io virtual irq number + */ +static void expio_ack_irq(u32 irq) +{ + u32 expio = MXC_IRQ_TO_EXPIO(irq); + /* clear the interrupt status */ + __raw_writew(1 << expio, brd_io + INTR_RESET_REG); + __raw_writew(0, brd_io + INTR_RESET_REG); + /* mask the interrupt */ + expio_mask_irq(irq); +} + +/* + * Enable a expio pin's interrupt by clearing the bit in the imr. + * @param irq a expio virtual irq number + */ +static void expio_unmask_irq(u32 irq) +{ + u16 reg; + u32 expio = MXC_IRQ_TO_EXPIO(irq); + /* unmask the interrupt */ + reg = __raw_readw(brd_io + INTR_MASK_REG); + reg &= ~(1 << expio); + __raw_writew(reg, brd_io + INTR_MASK_REG); +} + +static struct irq_chip expio_irq_chip = { + .ack = expio_ack_irq, + .mask = expio_mask_irq, + .unmask = expio_unmask_irq, +}; + +static int __init mxc_expio_init(void) +{ + int i; + + brd_io = (u32) ioremap(BOARD_IO_ADDR(CS5_BASE_ADDR), SZ_4K); + if (brd_io == 0) + return -ENOMEM; + + if ((__raw_readw(brd_io + MAGIC_NUMBER1_REG) != 0xAAAA) || + (__raw_readw(brd_io + MAGIC_NUMBER2_REG) != 0x5555) || + (__raw_readw(brd_io + MAGIC_NUMBER3_REG) != 0xCAFE)) { + iounmap((void *)brd_io); + brd_io = (u32) ioremap(BOARD_IO_ADDR(CS1_BASE_ADDR), SZ_4K); + if (brd_io == 0) + return -ENOMEM; + + if ((__raw_readw(brd_io + MAGIC_NUMBER1_REG) != 0xAAAA) || + (__raw_readw(brd_io + MAGIC_NUMBER2_REG) != 0x5555) || + (__raw_readw(brd_io + MAGIC_NUMBER3_REG) != 0xCAFE)) { + iounmap((void *)brd_io); + brd_io = 0; + return -ENODEV; + } + cpld_base_addr = CS1_BASE_ADDR; + } else { + cpld_base_addr = CS5_BASE_ADDR; + } + + pr_info("3-Stack Debug board detected, rev = 0x%04X\n", + readw(brd_io + CPLD_CODE_VER_REG)); + + /* + * Configure INT line as GPIO input + */ + mxc_set_gpio_direction(MX51_PIN_GPIO1_6, 1); + + /* disable the interrupt and clear the status */ + __raw_writew(0, brd_io + INTR_MASK_REG); + __raw_writew(0xFFFF, brd_io + INTR_RESET_REG); + __raw_writew(0, brd_io + INTR_RESET_REG); + __raw_writew(0x1F, brd_io + INTR_MASK_REG); + for (i = MXC_EXP_IO_BASE; i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES); + i++) { + set_irq_chip(i, &expio_irq_chip); + set_irq_handler(i, handle_level_irq); + set_irq_flags(i, IRQF_VALID); + } + set_irq_type(EXPIO_PARENT_INT, IRQF_TRIGGER_LOW); + set_irq_chained_handler(EXPIO_PARENT_INT, mxc_expio_irq_handler); + + return 0; +} + +#if defined(CONFIG_PATA_FSL) || defined(CONFIG_PATA_FSL_MODULE) +extern void gpio_ata_active(void); +extern void gpio_ata_inactive(void); + +static int ata_init(struct platform_device *pdev) +{ + /* Configure the pins */ + gpio_ata_active(); + return 0; +} + +static void ata_exit(void) +{ + /* Free the pins */ + gpio_ata_inactive(); +} + +static struct fsl_ata_platform_data ata_data = { + .udma_mask = ATA_UDMA3, + .mwdma_mask = ATA_MWDMA2, + .pio_mask = ATA_PIO4, + .fifo_alarm = MXC_IDE_DMA_WATERMARK / 2, + .max_sg = MXC_IDE_DMA_BD_NR, + .init = ata_init, + .exit = ata_exit, + .core_reg = NULL, + .io_reg = NULL, +}; + +static struct resource pata_fsl_resources[] = { + [0] = { + .start = ATA_BASE_ADDR, + .end = ATA_BASE_ADDR + 0x000000C8, + .flags = IORESOURCE_MEM,}, + [2] = { + .start = MXC_INT_ATA, + .end = MXC_INT_ATA, + .flags = IORESOURCE_IRQ,}, +}; + +static struct platform_device pata_fsl_device = { + .name = "pata_fsl", + .id = -1, + .num_resources = ARRAY_SIZE(pata_fsl_resources), + .resource = pata_fsl_resources, + .dev = { + .platform_data = &ata_data, + .coherent_dma_mask = ~0,}, +}; + +static void __init mxc_init_pata(void) +{ + (void)platform_device_register(&pata_fsl_device); +} +#else /* CONFIG_PATA_FSL */ +static void __init mxc_init_pata(void) +{ +} +#endif /* CONFIG_PATA_FSL */ + +#if defined(CONFIG_TOUCHSCREEN_TSC2007) \ + || defined(CONFIG_TOUCHSCREEN_TSC2007_MODULE) + +static int __init mxc_init_touchscreen(void) +{ + mxc_set_gpio_direction(MX51_PIN_GPIO1_5, 1); + + return 0; +} +#else +static int __init mxc_init_touchscreen(void) +{ + return 0; +} +#endif + +static int __init mxc_init_srpgconfig(void) +{ + struct clk *gpcclk = clk_get(NULL, "gpc_dvfs_clk"); + clk_enable(gpcclk); + + /* Setup the number of clock cycles to wait for SRPG + * power up and power down requests. + */ + __raw_writel(0x010F0201, MXC_SRPG_ARM_PUPSCR); + __raw_writel(0x010F0201, MXC_SRPG_NEON_PUPSCR); + __raw_writel(0x00000008, MXC_SRPG_EMPGC0_PUPSCR); + __raw_writel(0x00000008, MXC_SRPG_EMPGC1_PUPSCR); + + __raw_writel(0x01010101, MXC_SRPG_ARM_PDNSCR); + __raw_writel(0x01010101, MXC_SRPG_NEON_PDNSCR); + __raw_writel(0x00000018, MXC_SRPG_EMPGC0_PDNSCR); + __raw_writel(0x00000018, MXC_SRPG_EMPGC1_PDNSCR); + + clk_disable(gpcclk); + clk_put(gpcclk); + + return 0; +} + +#if defined(CONFIG_SND_SOC_IMX_3STACK_WM8903) \ + || defined(CONFIG_SND_SOC_IMX_3STACK_WM8903_MODULE) +static struct mxc_audio_platform_data wm8903_data; + +static struct platform_device mxc_wm8903_device = { + .name = "imx-3stack-wm8903", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &wm8903_data, + }, +}; + +static void __init mxc_init_wm8903(void) +{ + wm8903_data.ssi_clk[0] = clk_get(NULL, "ssi_clk.0"); + clk_put(wm8903_data.ssi_clk[0]); + + wm8903_data.ssi_clk[1] = clk_get(NULL, "ssi_clk.1"); + clk_put(wm8903_data.ssi_clk[1]); + + wm8903_data.ssi_num = 1; + wm8903_data.src_port = 2; + wm8903_data.ext_port = 3; + + (void)platform_device_register(&mxc_wm8903_device); +} +#else +static void __init mxc_init_wm8903(void) +{ +} +#endif + +#if defined(CONFIG_SND_SOC_IMX_3STACK_SGTL5000) \ + || defined(CONFIG_SND_SOC_IMX_3STACK_SGTL5000_MODULE) +static int mxc_sgtl5000_plat_init(void); +static int mxc_sgtl5000_plat_finit(void); +static int mxc_sgtl5000_amp_enable(int enable); + +int headphone_det_status(void) +{ + return mxc_get_gpio_datain(MX51_PIN_EIM_A26); +} + +static struct mxc_audio_platform_data sgtl5000_data = { + .ssi_num = 1, + .src_port = 2, + .ext_port = 3, + .hp_irq = IOMUX_TO_IRQ(MX51_PIN_EIM_A26), + .hp_status = headphone_det_status, + .amp_enable = mxc_sgtl5000_amp_enable, + .vddio = 1800000, + .vdda = 1800000, + .vddd = 12000000, + .sysclk = 12000000, + .init = mxc_sgtl5000_plat_init, + .finit = mxc_sgtl5000_plat_finit, +}; + +static struct platform_device mxc_sgtl5000_device = { + .name = "imx-3stack-sgtl5000", + .dev = { + .release = mxc_nop_release, + .platform_data = &sgtl5000_data, + }, +}; + +static int mxc_sgtl5000_plat_init(void) +{ + struct regulator *reg; + reg = regulator_get(&mxc_sgtl5000_device.dev, "GPO2"); + if (IS_ERR(reg)) + return -EINVAL; + sgtl5000_data.priv = reg; + return 0; +} + +static int mxc_sgtl5000_plat_finit(void) +{ + struct regulator *reg; + reg = sgtl5000_data.priv; + if (reg) { + regulator_put(reg); + sgtl5000_data.priv = NULL; + } + return 0; +} + +static int mxc_sgtl5000_amp_enable(int enable) +{ + struct regulator *reg; + reg = sgtl5000_data.priv; + + if (!reg) + return -EINVAL; + if (enable) + regulator_enable(reg); + else + regulator_disable(reg); + return 0; +} + +static void mxc_init_sgtl5000(void) +{ + platform_device_register(&mxc_sgtl5000_device); +} +#else +static inline void mxc_init_sgtl5000(void) +{ +} +#endif + +static void bt_reset(void) +{ + mxc_set_gpio_dataout(MX51_PIN_EIM_D19, 1); +} + +static struct mxc_bt_platform_data mxc_bt_data = { + .bt_vdd = NULL, + .bt_vdd_parent = NULL, + .bt_vusb = "SW4", + .bt_vusb_parent = NULL, + .bt_reset = bt_reset, +}; + +static struct platform_device mxc_bt_device = { + .name = "mxc_bt", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxc_bt_data, + }, +}; + +static void mxc_init_bluetooth(void) +{ + (void)platform_device_register(&mxc_bt_device); +} + +#if defined(CONFIG_SDIO_UNIFI_FS) || defined(CONFIG_SDIO_UNIFI_FS_MODULE) +static void mxc_unifi_hardreset(void) +{ + mxc_set_gpio_dataout(MX51_PIN_EIM_D19, 0); + msleep(100); + mxc_set_gpio_dataout(MX51_PIN_EIM_D19, 1); +} + +static struct mxc_unifi_platform_data unifi_data = { + .hardreset = mxc_unifi_hardreset, + .reg_vdd_vpa = "VSD", + .reg_1v5_dd = "VGEN1", + .host_id = 1, +}; + +struct mxc_unifi_platform_data *get_unifi_plat_data(void) +{ + return &unifi_data; +} +#else +struct mxc_unifi_platform_data *get_unifi_plat_data(void) +{ + return NULL; +} +#endif + +EXPORT_SYMBOL(get_unifi_plat_data); + +/*! + * Board specific fixup function. It is called by \b setup_arch() in + * setup.c file very early on during kernel starts. It allows the user to + * statically fill in the proper values for the passed-in parameters. None of + * the parameters is used currently. + * + * @param desc pointer to \b struct \b machine_desc + * @param tags pointer to \b struct \b tag + * @param cmdline pointer to the command line + * @param mi pointer to \b struct \b meminfo + */ +static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags, + char **cmdline, struct meminfo *mi) +{ + mxc_cpu_init(); + + get_cpu_wp = mx51_3stack_get_cpu_wp; +#ifdef CONFIG_DISCONTIGMEM + do { + int nid; + mi->nr_banks = MXC_NUMNODES; + for (nid = 0; nid < mi->nr_banks; nid++) + SET_NODE(mi, nid); + + } while (0); +#endif +} + +/*! + * Board specific initialization. + */ +static void __init mxc_board_init(void) +{ + int err; + + mxc_cpu_common_init(); + mxc_gpio_init(); + mx51_3stack_io_init(); + early_console_setup(saved_command_line); + mxc_init_devices(); + + mxc_expio_init(); + mxc_init_enet(); + mxc_init_pata(); + mxc_init_fb(); + mxc_init_bl(); + mxc_init_keypad(); + mxc_init_nand_mtd(); + mxc_init_mmc(); + mxc_init_srpgconfig(); + mx51_3stack_init_mc13892(); + +#if defined(CONFIG_I2C_MXC) || defined(CONFIG_I2C_MXC_MODULE) + +#ifdef CONFIG_I2C_MXC_SELECT1 + i2c_register_board_info(0, mxc_i2c0_board_info, + ARRAY_SIZE(mxc_i2c0_board_info)); +#endif +#ifdef CONFIG_I2C_MXC_SELECT2 + i2c_register_board_info(1, mxc_i2c1_board_info, + ARRAY_SIZE(mxc_i2c1_board_info)); +#endif +#if defined(CONFIG_I2C_MXC_HS) || defined(CONFIG_I2C_MXC_HS_MODULE) + i2c_register_board_info(3, mxc_i2c_hs_board_info, + ARRAY_SIZE(mxc_i2c_hs_board_info)); +#endif + +#endif + mxc_init_touchscreen(); + mxc_init_wm8903(); + mxc_init_sgtl5000(); + mxc_init_bluetooth(); + + err = mxc_request_iomux(MX51_PIN_EIM_D19, IOMUX_CONFIG_GPIO); + if (err) + printk(KERN_ERR "Error: bt reset request gpio failed!\n"); + else + mxc_set_gpio_direction(MX51_PIN_EIM_D19, 0); +} + +static void __init mx51_3stack_timer_init(void) +{ + mxc_clocks_init(32768, 24000000, 22579200, 24576000); + mxc_timer_init("gpt_clk.0"); +} + +static struct sys_timer mxc_timer = { + .init = mx51_3stack_timer_init, +}; + +/* + * The following uses standard kernel macros define in arch.h in order to + * initialize __mach_desc_MX51_3STACK data structure. + */ +/* *INDENT-OFF* */ +MACHINE_START(MX51_3DS, "Freescale MX51 3-Stack Board") + /* Maintainer: Freescale Semiconductor, Inc. */ + .phys_io = AIPS1_BASE_ADDR, + .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, + .boot_params = PHYS_OFFSET + 0x100, + .fixup = fixup_mxc_board, + .map_io = mxc_map_io, + .init_irq = mxc_init_irq, + .init_machine = mxc_board_init, + .timer = &mxc_timer, +MACHINE_END --- linux-2.6.28.orig/arch/arm/mach-mx51/dma.c +++ linux-2.6.28/arch/arm/mach-mx51/dma.c @@ -0,0 +1,666 @@ +/* + * Copyright 2008-2009 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 + */ +#include +#include +#include +#include + +#include "serial.h" + +#define MXC_MMC_BUFFER_ACCESS 0x20 +#define MXC_SDHC_MMC_WML 64 +#define MXC_SDHC_SD_WML 256 +#define MXC_SSI_TX0_REG 0x0 +#define MXC_SSI_TX1_REG 0x4 +#define MXC_SSI_RX0_REG 0x8 +#define MXC_SSI_RX1_REG 0xC +#define MXC_SSI_TXFIFO_WML 0x4 +#define MXC_SSI_RXFIFO_WML 0x6 +#define MXC_SPDIF_TXFIFO_WML 0x8 +#define MXC_SPDIF_TX_REG 0x2C + +typedef struct mxc_sdma_info_entry_s { + mxc_dma_device_t device; + mxc_sdma_channel_params_t *chnl_info; +} mxc_sdma_info_entry_t; + +static mxc_sdma_channel_params_t mxc_sdma_uart1_rx_params = { + .chnl_params = { + .watermark_level = UART1_UFCR_RXTL, + .per_address = UART1_BASE_ADDR, + .peripheral_type = UART, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_UART1_RX, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_UART1_RX, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_uart1_tx_params = { + .chnl_params = { + .watermark_level = UART1_UFCR_TXTL, + .per_address = UART1_BASE_ADDR + MXC_UARTUTXD, + .peripheral_type = UART, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_UART1_TX, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_UART1_TX, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_uart2_rx_params = { + .chnl_params = { + .watermark_level = UART2_UFCR_RXTL, + .per_address = UART2_BASE_ADDR, + .peripheral_type = UART, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_UART2_RX, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_UART2_RX, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_uart2_tx_params = { + .chnl_params = { + .watermark_level = UART2_UFCR_TXTL, + .per_address = UART2_BASE_ADDR + MXC_UARTUTXD, + .peripheral_type = UART, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_UART2_TX, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_UART2_TX, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_uart3_rx_params = { + .chnl_params = { + .watermark_level = UART3_UFCR_RXTL, + .per_address = UART3_BASE_ADDR, + .peripheral_type = UART_SP, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_UART3_RX, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_UART3_RX, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_uart3_tx_params = { + .chnl_params = { + .watermark_level = UART3_UFCR_TXTL, + .per_address = UART3_BASE_ADDR + MXC_UARTUTXD, + .peripheral_type = UART_SP, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_UART3_TX, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_UART3_TX, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_mmc1_width1_params = { + .chnl_params = { + .watermark_level = MXC_SDHC_MMC_WML, + .per_address = + MMC_SDHC1_BASE_ADDR + MXC_MMC_BUFFER_ACCESS, + .peripheral_type = MMC, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SDHC1, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_MMC1, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_mmc1_width4_params = { + .chnl_params = { + .watermark_level = MXC_SDHC_SD_WML, + .per_address = + MMC_SDHC1_BASE_ADDR + MXC_MMC_BUFFER_ACCESS, + .peripheral_type = MMC, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SDHC1, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_MMC1, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_mmc2_width1_params = { + .chnl_params = { + .watermark_level = MXC_SDHC_MMC_WML, + .per_address = + MMC_SDHC2_BASE_ADDR + MXC_MMC_BUFFER_ACCESS, + .peripheral_type = MMC, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SDHC2, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_MMC2, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_mmc2_width4_params = { + .chnl_params = { + .watermark_level = MXC_SDHC_SD_WML, + .per_address = + MMC_SDHC2_BASE_ADDR + MXC_MMC_BUFFER_ACCESS, + .peripheral_type = MMC, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SDHC2, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_MMC2, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_rx0_params = { + .chnl_params = { + .watermark_level = MXC_SSI_RXFIFO_WML, + .per_address = SSI1_BASE_ADDR + MXC_SSI_RX0_REG, + .peripheral_type = SSI, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SSI1_RX1, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI1_RX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_tx0_params = { + .chnl_params = { + .watermark_level = MXC_SSI_TXFIFO_WML, + .per_address = SSI1_BASE_ADDR + MXC_SSI_TX0_REG, + .peripheral_type = SSI, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_SSI1_TX1, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI1_TX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_rx0_params = { + .chnl_params = { + .watermark_level = MXC_SSI_RXFIFO_WML, + .per_address = SSI1_BASE_ADDR + MXC_SSI_RX0_REG, + .peripheral_type = SSI, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SSI1_RX1, + .bd_number = 32, + .word_size = TRANSFER_16BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI1_RX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_tx0_params = { + .chnl_params = { + .watermark_level = MXC_SSI_TXFIFO_WML, + .per_address = SSI1_BASE_ADDR + MXC_SSI_TX0_REG, + .peripheral_type = SSI, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_SSI1_TX1, + .bd_number = 32, + .word_size = TRANSFER_16BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI1_TX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_rx0_params = { + .chnl_params = { + .watermark_level = MXC_SSI_RXFIFO_WML, + .per_address = SSI1_BASE_ADDR + MXC_SSI_RX0_REG, + .peripheral_type = SSI, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SSI1_RX1, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI1_RX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_tx0_params = { + .chnl_params = { + .watermark_level = MXC_SSI_TXFIFO_WML, + .per_address = SSI1_BASE_ADDR + MXC_SSI_TX0_REG, + .peripheral_type = SSI, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_SSI1_TX1, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI1_TX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_rx1_params = { + .chnl_params = { + .watermark_level = MXC_SSI_RXFIFO_WML, + .per_address = SSI1_BASE_ADDR + MXC_SSI_RX1_REG, + .peripheral_type = SSI, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SSI1_RX2, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI1_RX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_tx1_params = { + .chnl_params = { + .watermark_level = MXC_SSI_TXFIFO_WML, + .per_address = SSI1_BASE_ADDR + MXC_SSI_TX1_REG, + .peripheral_type = SSI, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_SSI1_TX2, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI1_TX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_rx1_params = { + .chnl_params = { + .watermark_level = MXC_SSI_RXFIFO_WML, + .per_address = SSI1_BASE_ADDR + MXC_SSI_RX1_REG, + .peripheral_type = SSI, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SSI1_RX2, + .bd_number = 32, + .word_size = TRANSFER_16BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI1_RX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_tx1_params = { + .chnl_params = { + .watermark_level = MXC_SSI_TXFIFO_WML, + .per_address = SSI1_BASE_ADDR + MXC_SSI_TX1_REG, + .peripheral_type = SSI, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_SSI1_TX2, + .bd_number = 32, + .word_size = TRANSFER_16BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI1_TX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_rx1_params = { + .chnl_params = { + .watermark_level = MXC_SSI_RXFIFO_WML, + .per_address = SSI1_BASE_ADDR + MXC_SSI_RX1_REG, + .peripheral_type = SSI, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SSI1_RX2, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI1_RX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_tx1_params = { + .chnl_params = { + .watermark_level = MXC_SSI_TXFIFO_WML, + .per_address = SSI1_BASE_ADDR + MXC_SSI_TX1_REG, + .peripheral_type = SSI, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_SSI1_TX2, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI1_TX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_rx0_params = { + .chnl_params = { + .watermark_level = MXC_SSI_RXFIFO_WML, + .per_address = SSI2_BASE_ADDR + MXC_SSI_RX0_REG, + .peripheral_type = SSI_SP, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SSI2_RX1, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI2_RX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_tx0_params = { + .chnl_params = { + .watermark_level = MXC_SSI_TXFIFO_WML, + .per_address = SSI2_BASE_ADDR + MXC_SSI_TX0_REG, + .peripheral_type = SSI_SP, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_SSI2_TX1, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI2_TX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_rx0_params = { + .chnl_params = { + .watermark_level = MXC_SSI_RXFIFO_WML, + .per_address = SSI2_BASE_ADDR + MXC_SSI_RX0_REG, + .peripheral_type = SSI_SP, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SSI2_RX1, + .bd_number = 32, + .word_size = TRANSFER_16BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI2_RX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_tx0_params = { + .chnl_params = { + .watermark_level = MXC_SSI_TXFIFO_WML, + .per_address = SSI2_BASE_ADDR + MXC_SSI_TX0_REG, + .peripheral_type = SSI_SP, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_SSI2_TX1, + .bd_number = 32, + .word_size = TRANSFER_16BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI2_TX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_rx0_params = { + .chnl_params = { + .watermark_level = MXC_SSI_RXFIFO_WML, + .per_address = SSI2_BASE_ADDR + MXC_SSI_RX0_REG, + .peripheral_type = SSI_SP, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SSI2_RX1, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI2_RX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_tx0_params = { + .chnl_params = { + .watermark_level = MXC_SSI_TXFIFO_WML, + .per_address = SSI2_BASE_ADDR + MXC_SSI_TX0_REG, + .peripheral_type = SSI_SP, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_SSI2_TX1, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI2_TX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_rx1_params = { + .chnl_params = { + .watermark_level = MXC_SSI_RXFIFO_WML, + .per_address = SSI2_BASE_ADDR + MXC_SSI_RX1_REG, + .peripheral_type = SSI_SP, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SSI2_RX2, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI2_RX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_tx1_params = { + .chnl_params = { + .watermark_level = MXC_SSI_TXFIFO_WML, + .per_address = SSI2_BASE_ADDR + MXC_SSI_TX1_REG, + .peripheral_type = SSI_SP, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_SSI2_TX2, + .bd_number = 32, + .word_size = TRANSFER_8BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI2_TX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_rx1_params = { + .chnl_params = { + .watermark_level = MXC_SSI_RXFIFO_WML, + .per_address = SSI2_BASE_ADDR + MXC_SSI_RX1_REG, + .peripheral_type = SSI_SP, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SSI2_RX2, + .bd_number = 32, + .word_size = TRANSFER_16BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI2_RX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_tx1_params = { + .chnl_params = { + .watermark_level = MXC_SSI_TXFIFO_WML, + .per_address = SSI2_BASE_ADDR + MXC_SSI_TX1_REG, + .peripheral_type = SSI_SP, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_SSI2_TX2, + .bd_number = 32, + .word_size = TRANSFER_16BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI2_TX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_rx1_params = { + .chnl_params = { + .watermark_level = MXC_SSI_RXFIFO_WML, + .per_address = SSI2_BASE_ADDR + MXC_SSI_RX1_REG, + .peripheral_type = SSI_SP, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_SSI2_RX2, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI2_RX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_tx1_params = { + .chnl_params = { + .watermark_level = MXC_SSI_TXFIFO_WML, + .per_address = SSI2_BASE_ADDR + MXC_SSI_TX1_REG, + .peripheral_type = SSI_SP, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_SSI2_TX2, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SSI2_TX, + .chnl_priority = 2, +}; + +static mxc_sdma_channel_params_t mxc_sdma_memory_params = { + .chnl_params = { + .peripheral_type = MEMORY, + .transfer_type = emi_2_emi, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_MEMORY, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ata_rx_params = { + .chnl_params = { + .watermark_level = MXC_IDE_DMA_WATERMARK, + .per_address = ATA_DMA_BASE_ADDR, + .peripheral_type = ATA, + .transfer_type = per_2_emi, + .event_id = DMA_REQ_ATA_TX_END, + .event_id2 = DMA_REQ_ATA_RX, + .bd_number = MXC_IDE_DMA_BD_NR, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_ATA_RX, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_ata_tx_params = { + .chnl_params = { + .watermark_level = MXC_IDE_DMA_WATERMARK, + .per_address = ATA_DMA_BASE_ADDR + 0x18, + .peripheral_type = ATA, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_ATA_TX_END, + .event_id2 = DMA_REQ_ATA_TX, + .bd_number = MXC_IDE_DMA_BD_NR, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_ATA_TX, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_spdif_16bit_tx_params = { + .chnl_params = { + .watermark_level = MXC_SPDIF_TXFIFO_WML, + .per_address = SPDIF_BASE_ADDR + MXC_SPDIF_TX_REG, + .peripheral_type = SPDIF, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_SPDIF, + .bd_number = 32, + .word_size = TRANSFER_16BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SPDIF_TX, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_channel_params_t mxc_sdma_spdif_32bit_tx_params = { + .chnl_params = { + .watermark_level = MXC_SPDIF_TXFIFO_WML, + .per_address = SPDIF_BASE_ADDR + MXC_SPDIF_TX_REG, + .peripheral_type = SPDIF, + .transfer_type = emi_2_per, + .event_id = DMA_REQ_SPDIF, + .bd_number = 32, + .word_size = TRANSFER_32BIT, + }, + .channel_num = MXC_DMA_CHANNEL_SPDIF_TX, + .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY, +}; + +static mxc_sdma_info_entry_t mxc_sdma_active_dma_info[] = { + {MXC_DMA_UART1_RX, &mxc_sdma_uart1_rx_params}, + {MXC_DMA_UART1_TX, &mxc_sdma_uart1_tx_params}, + {MXC_DMA_UART2_RX, &mxc_sdma_uart2_rx_params}, + {MXC_DMA_UART2_TX, &mxc_sdma_uart2_tx_params}, + {MXC_DMA_UART3_RX, &mxc_sdma_uart3_rx_params}, + {MXC_DMA_UART3_TX, &mxc_sdma_uart3_tx_params}, + {MXC_DMA_MMC1_WIDTH_1, &mxc_sdma_mmc1_width1_params}, + {MXC_DMA_MMC1_WIDTH_4, &mxc_sdma_mmc1_width4_params}, + {MXC_DMA_MMC2_WIDTH_1, &mxc_sdma_mmc2_width1_params}, + {MXC_DMA_MMC2_WIDTH_4, &mxc_sdma_mmc2_width4_params}, + {MXC_DMA_SSI1_8BIT_RX0, &mxc_sdma_ssi1_8bit_rx0_params}, + {MXC_DMA_SSI1_8BIT_TX0, &mxc_sdma_ssi1_8bit_tx0_params}, + {MXC_DMA_SSI1_16BIT_RX0, &mxc_sdma_ssi1_16bit_rx0_params}, + {MXC_DMA_SSI1_16BIT_TX0, &mxc_sdma_ssi1_16bit_tx0_params}, + {MXC_DMA_SSI1_24BIT_RX0, &mxc_sdma_ssi1_24bit_rx0_params}, + {MXC_DMA_SSI1_24BIT_TX0, &mxc_sdma_ssi1_24bit_tx0_params}, + {MXC_DMA_SSI1_8BIT_RX1, &mxc_sdma_ssi1_8bit_rx1_params}, + {MXC_DMA_SSI1_8BIT_TX1, &mxc_sdma_ssi1_8bit_tx1_params}, + {MXC_DMA_SSI1_16BIT_RX1, &mxc_sdma_ssi1_16bit_rx1_params}, + {MXC_DMA_SSI1_16BIT_TX1, &mxc_sdma_ssi1_16bit_tx1_params}, + {MXC_DMA_SSI1_24BIT_RX1, &mxc_sdma_ssi1_24bit_rx1_params}, + {MXC_DMA_SSI1_24BIT_TX1, &mxc_sdma_ssi1_24bit_tx1_params}, + {MXC_DMA_SSI2_8BIT_RX0, &mxc_sdma_ssi2_8bit_rx0_params}, + {MXC_DMA_SSI2_8BIT_TX0, &mxc_sdma_ssi2_8bit_tx0_params}, + {MXC_DMA_SSI2_16BIT_RX0, &mxc_sdma_ssi2_16bit_rx0_params}, + {MXC_DMA_SSI2_16BIT_TX0, &mxc_sdma_ssi2_16bit_tx0_params}, + {MXC_DMA_SSI2_24BIT_RX0, &mxc_sdma_ssi2_24bit_rx0_params}, + {MXC_DMA_SSI2_24BIT_TX0, &mxc_sdma_ssi2_24bit_tx0_params}, + {MXC_DMA_SSI2_8BIT_RX1, &mxc_sdma_ssi2_8bit_rx1_params}, + {MXC_DMA_SSI2_8BIT_TX1, &mxc_sdma_ssi2_8bit_tx1_params}, + {MXC_DMA_SSI2_16BIT_RX1, &mxc_sdma_ssi2_16bit_rx1_params}, + {MXC_DMA_SSI2_16BIT_TX1, &mxc_sdma_ssi2_16bit_tx1_params}, + {MXC_DMA_SSI2_24BIT_RX1, &mxc_sdma_ssi2_24bit_rx1_params}, + {MXC_DMA_SSI2_24BIT_TX1, &mxc_sdma_ssi2_24bit_tx1_params}, + {MXC_DMA_MEMORY, &mxc_sdma_memory_params}, + {MXC_DMA_ATA_RX, &mxc_sdma_ata_rx_params}, + {MXC_DMA_ATA_TX, &mxc_sdma_ata_tx_params}, + {MXC_DMA_SPDIF_16BIT_TX, &mxc_sdma_spdif_16bit_tx_params}, + {MXC_DMA_SPDIF_32BIT_TX, &mxc_sdma_spdif_32bit_tx_params}, +}; + +static int mxc_sdma_info_entrys = + sizeof(mxc_sdma_active_dma_info) / sizeof(mxc_sdma_active_dma_info[0]); + +/*! + * This functions Returns the SDMA paramaters associated for a module + * + * @param channel_id the ID of the module requesting DMA + * @return returns the sdma parameters structure for the device + */ +mxc_sdma_channel_params_t *mxc_sdma_get_channel_params(mxc_dma_device_t + channel_id) +{ + mxc_sdma_info_entry_t *p = mxc_sdma_active_dma_info; + int i; + + for (i = 0; i < mxc_sdma_info_entrys; i++, p++) { + if (p->device == channel_id) + return p->chnl_info; + + } + return NULL; +} + +/*! + * This functions marks the SDMA channels that are statically allocated + * + * @param chnl the channel array used to store channel information + */ +void mxc_get_static_channels(mxc_dma_channel_t *chnl) +{ +#ifdef CONFIG_SDMA_IRAM + int i; + for (i = MXC_DMA_CHANNEL_IRAM; i < MAX_DMA_CHANNELS; i++) + chnl[i].dynamic = 0; +#endif +} + +EXPORT_SYMBOL(mxc_sdma_get_channel_params); +EXPORT_SYMBOL(mxc_get_static_channels); --- linux-2.6.28.orig/arch/arm/mach-mx51/sdma_script_code.h +++ linux-2.6.28/arch/arm/mach-mx51/sdma_script_code.h @@ -0,0 +1,170 @@ +/* + * Copyright 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You 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 */ + +/*! + * @file sdma_script_code.h + * @brief This file contains functions of SDMA scripts code initialization + * + * The file was generated automatically. Based on sdma scripts library. + * + * @ingroup SDMA + */ +/******************************************************************************* + + SDMA RELEASE LABEL: "SS15_ELVIS" + +*******************************************************************************/ + +#ifndef __SDMA_SCRIPT_CODE_H__ +#define __SDMA_SCRIPT_CODE_H__ + +/*! +* SDMA ROM scripts start addresses and sizes +*/ + +#define start_ADDR 0 +#define start_SIZE 24 + +#define core_ADDR 80 +#define core_SIZE 232 + +#define common_ADDR 312 +#define common_SIZE 330 + +#define ap_2_ap_ADDR 642 +#define ap_2_ap_SIZE 41 + +#define app_2_mcu_ADDR 683 +#define app_2_mcu_SIZE 64 + +#define mcu_2_app_ADDR 747 +#define mcu_2_app_SIZE 70 + +#define uart_2_mcu_ADDR 817 +#define uart_2_mcu_SIZE 75 + +#define shp_2_mcu_ADDR 892 +#define shp_2_mcu_SIZE 69 + +#define mcu_2_shp_ADDR 961 +#define mcu_2_shp_SIZE 72 + +#define app_2_per_ADDR 1033 +#define app_2_per_SIZE 66 + +#define per_2_app_ADDR 1099 +#define per_2_app_SIZE 74 + +#define per_2_shp_ADDR 1173 +#define per_2_shp_SIZE 78 + +#define shp_2_per_ADDR 1251 +#define shp_2_per_SIZE 72 + +#define uartsh_2_mcu_ADDR 1323 +#define uartsh_2_mcu_SIZE 69 + +#define mcu_2_ata_ADDR 1392 +#define mcu_2_ata_SIZE 81 + +#define ata_2_mcu_ADDR 1473 +#define ata_2_mcu_SIZE 96 + +#define loop_DMAs_routines_ADDR 1569 +#define loop_DMAs_routines_SIZE 227 + +#define test_ADDR 1796 +#define test_SIZE 63 + +#define signature_ADDR 1023 +#define signature_SIZE 1 + +/*! +* SDMA RAM scripts start addresses and sizes +*/ + +#define ext_mem__ipu_ram_ADDR 6144 +#define ext_mem__ipu_ram_SIZE 123 + +#define mcu_2_spdif_ADDR 6267 +#define mcu_2_spdif_SIZE 59 + +#define uart_2_per_ADDR 6326 +#define uart_2_per_SIZE 73 + +#define uartsh_2_per_ADDR 6399 +#define uartsh_2_per_SIZE 67 + +/*! +* SDMA RAM image start address and size +*/ + +#define RAM_CODE_START_ADDR 6144 +#define RAM_CODE_SIZE 322 + +/*! +* Buffer that holds the SDMA RAM image +*/ +__attribute__ ((__aligned__(4))) +#ifndef CONFIG_XIP_KERNEL +const +#endif +static const short sdma_code[] = { + 0x0e70, 0x0611, 0x5616, 0xc13c, 0x7d2a, 0x5ade, 0x008e, 0xc14e, + 0x7c26, 0x5be0, 0x5ef0, 0x5ce8, 0x0688, 0x08ff, 0x0011, 0x28ff, + 0x00bc, 0x53f6, 0x05df, 0x7d0b, 0x6dc5, 0x03df, 0x7d03, 0x6bd5, + 0xd84f, 0x982b, 0x6b05, 0xc681, 0x7e27, 0x7f29, 0x982b, 0x6d01, + 0x03df, 0x7d05, 0x6bd5, 0xc6ab, 0x7e18, 0x7f1a, 0x982b, 0x6b05, + 0xc621, 0x7e07, 0x7f06, 0x52de, 0x53e6, 0xc159, 0x7dd7, 0x0200, + 0x9803, 0x0007, 0x6004, 0x680c, 0x53f6, 0x028e, 0x00a3, 0xc256, + 0x048b, 0x0498, 0x0454, 0x068a, 0x982b, 0x0207, 0x680c, 0x6ddf, + 0x0107, 0x68ff, 0x60d0, 0x9834, 0x0207, 0x68ff, 0x6d28, 0x0107, + 0x6004, 0x680c, 0x9834, 0x0007, 0x68ff, 0x60d0, 0x9834, 0x0288, + 0x03a5, 0x3b03, 0x3d03, 0x4d00, 0x7d0a, 0x0804, 0x00a5, 0x00da, + 0x7d1a, 0x02a0, 0x7b01, 0x65d8, 0x7eee, 0x65ff, 0x7eec, 0x0804, + 0x02d0, 0x7d11, 0x4b00, 0x7c0f, 0x008a, 0x3003, 0x6dcf, 0x6bdf, + 0x0015, 0x0015, 0x7b02, 0x65d8, 0x0000, 0x7edd, 0x63ff, 0x7edb, + 0x3a03, 0x6dcd, 0x6bdd, 0x008a, 0x7b02, 0x65d8, 0x0000, 0x7ed3, + 0x65ff, 0x7ed1, 0x0006, 0xc1d9, 0xc1e3, 0x57db, 0x52f3, 0x6a01, + 0x008f, 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x5deb, 0x56fb, 0x0478, + 0x7d28, 0x0479, 0x7c16, 0x0015, 0x0015, 0x0388, 0x620a, 0x0808, + 0x7801, 0x0217, 0x5a06, 0x7f1d, 0x620a, 0x0808, 0x7801, 0x0217, + 0x5a26, 0x7f17, 0x2301, 0x4b00, 0x7cf1, 0x0b70, 0x0311, 0x5313, + 0x98aa, 0x0015, 0x0015, 0x0015, 0x7804, 0x620b, 0x5a06, 0x620b, + 0x5a26, 0x7c07, 0x0000, 0x55eb, 0x4d00, 0x7d06, 0xc1fa, 0x57db, + 0x9880, 0x0007, 0x680c, 0xc213, 0xc20a, 0x987d, 0xc1e3, 0x57db, + 0x52f3, 0x6ad5, 0x56fb, 0x028e, 0x1a94, 0x6ac3, 0x62c8, 0x0269, + 0x7d1e, 0x1e94, 0x6ee3, 0x62d0, 0x5aeb, 0x62c8, 0x0248, 0x6ed3, + 0x6ac8, 0x2694, 0x52eb, 0x6ad5, 0x6ee3, 0x62c8, 0x026e, 0x7d27, + 0x6ac8, 0x7f23, 0x2501, 0x4d00, 0x7d26, 0x028e, 0x1a98, 0x6ac3, + 0x62c8, 0x6ec3, 0x0260, 0x7df1, 0x62d0, 0xc27a, 0x98fb, 0x6ee3, + 0x008f, 0x2001, 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x62c8, 0x026e, + 0x7d0e, 0x6ac8, 0x7f0a, 0x2001, 0x7cf9, 0x6add, 0x7f06, 0x0000, + 0x4d00, 0x7d09, 0xc1fa, 0x57db, 0x98ba, 0x0007, 0x6aff, 0x62d0, + 0xc27a, 0x0458, 0x0454, 0x6add, 0x7ff8, 0xc20a, 0x98b7, 0xc1d9, + 0xc1e3, 0x57db, 0x52f3, 0x6ad5, 0x56fb, 0x028e, 0x1a94, 0x5202, + 0x0269, 0x7d17, 0x1e94, 0x5206, 0x0248, 0x5a06, 0x2694, 0x5206, + 0x026e, 0x7d26, 0x6ac8, 0x7f22, 0x2501, 0x4d00, 0x7d27, 0x028e, + 0x1a98, 0x5202, 0x0260, 0x7df3, 0x6add, 0x7f18, 0x62d0, 0xc27a, + 0x993e, 0x008f, 0x2001, 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x5206, + 0x026e, 0x7d0e, 0x6ac8, 0x7f0a, 0x2001, 0x7cf9, 0x6add, 0x7f06, + 0x0000, 0x4d00, 0x7d0b, 0xc1fa, 0x57db, 0x9904, 0x0007, 0x6aff, + 0x6add, 0x7ffc, 0x62d0, 0xc27a, 0x0458, 0x0454, 0x6add, 0x7ff6, + 0xc20a, 0x9901 +}; +#endif --- linux-2.6.28.orig/arch/arm/mach-mx51/wfi.S +++ linux-2.6.28/arch/arm/mach-mx51/wfi.S @@ -0,0 +1,427 @@ +/* + * Copyright 2008-2009 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 + */ + +#include + +#define ARM_CTRL_DCACHE 1 << 2 +#define ARM_AUXCR_L2EN 1 << 1 +/* + * cpu_cortexa8_do_idle() + * + * Idle the processor (eg, wait for interrupt). + * + * IRQs are already disabled. + */ +ENTRY(cpu_cortexa8_do_idle) + + mrc p15, 0, r1, c1, c0, 1 @ R1 = auxiliary control reg + ands r2, r1, #ARM_AUXCR_L2EN @ Check if L2 is disabled + beq SkipL2Access + + mrc p15, 0, r2, c1, c0, 0 @ R2 = system control reg + bic r2, r2, #ARM_CTRL_DCACHE @ Disable DCache + mcr p15, 0, r2, c1, c0, 0 @ Update system control reg + + bic r1, r1, #ARM_AUXCR_L2EN @ Disable L2 cache + mcr p15, 0, r1, c1, c0, 1 @ Update aux control reg + + ldr r1, =(0x0 << 6) @ A[6] = 0 + mcr p15, 0, r1, c15, c9, 2 @ Read L2 tag RAM into L2 data 0 register + mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2 + str r2, [r0, #0x00] @ Save tag info + + ldr r1, =(0x1 << 6) @ A[6] = 1 + mcr p15, 0, r1, c15, c9, 2 @ Read L2 tag RAM into L2 data 0 register + mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2 + str r2, [r0, #0x04] @ Save tag info + + ldr r1, =(0x0 << 3) @ A[6:3] = b0000 + mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register + mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2 + str r2, [r0, #0x08] @ Store data info + mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2 + str r2, [r0, #0x0C] @ Store data info + mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2 + str r2, [r0, #0x10] @ Store data info + + ldr r1, =(0x1 << 3) @ A[6:3] = b0001 + mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register + mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2 + str r2, [r0, #0x14] @ Store data info + mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2 + str r2, [r0, #0x18] @ Store data info + mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2 + str r2, [r0, #0x1C] @ Store data info + + ldr r1, =(0x2 << 3) @ A[6:3] = b0010 + mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register + mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2 + str r2, [r0, #0x20] @ Store data info + mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2 + str r2, [r0, #0x24] @ Store data info + mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2 + str r2, [r0, #0x28] @ Store data info + + ldr r1, =(0x3 << 3) @ A[6:3] = b0011 + mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register + mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2 + str r2, [r0, #0x2C] @ Store data info + mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2 + str r2, [r0, #0x30] @ Store data info + mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2 + str r2, [r0, #0x34] @ Store data info + + ldr r1, =(0x4 << 3) @ A[6:3] = b0100 + mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register + mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2 + str r2, [r0, #0x38] @ Store data info + mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2 + str r2, [r0, #0x3C] @ Store data info + mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2 + str r2, [r0, #0x40] @ Store data info + + ldr r1, =(0x5 << 3) @ A[6:3] = b0101 + mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register + mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2 + str r2, [r0, #0x44] @ Store data info + mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2 + str r2, [r0, #0x48] @ Store data info + mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2 + str r2, [r0, #0x4C] @ Store data info + + ldr r1, =(0x6 << 3) @ A[6:3] = b0110 + mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register + mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2 + str r2, [r0, #0x50] @ Store data info + mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2 + str r2, [r0, #0x54] @ Store data info + mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2 + str r2, [r0, #0x58] @ Store data info + + ldr r1, =(0x7 << 3) @ A[6:3] = b0111 + mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register + mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2 + str r2, [r0, #0x5C] @ Store data info + mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2 + str r2, [r0, #0x60] @ Store data info + mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2 + str r2, [r0, #0x64] @ Store data info + + ldr r1, =(0x8 << 3) @ A[6:3] = b1000 + mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register + mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2 + str r2, [r0, #0x68] @ Store data info + mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2 + str r2, [r0, #0x6C] @ Store data info + mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2 + str r2, [r0, #0x70] @ Store data info + + ldr r1, =(0x9 << 3) @ A[6:3] = b1001 + mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register + mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2 + str r2, [r0, #0x74] @ Store data info + mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2 + str r2, [r0, #0x78] @ Store data info + mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2 + str r2, [r0, #0x7C] @ Store data info + + ldr r1, =(0xA << 3) @ A[6:3] = b1010 + mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register + mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2 + str r2, [r0, #0x80] @ Store data info + mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2 + str r2, [r0, #0x84] @ Store data info + mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2 + str r2, [r0, #0x88] @ Store data info + + ldr r1, =(0xB << 3) @ A[6:3] = b1011 + mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register + mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2 + str r2, [r0, #0x8C] @ Store data info + mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2 + str r2, [r0, #0x90] @ Store data info + mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2 + str r2, [r0, #0x94] @ Store data info + + ldr r1, =(0xC << 3) @ A[6:3] = b1100 + mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register + mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2 + str r2, [r0, #0x98] @ Store data info + mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2 + str r2, [r0, #0x9C] @ Store data info + mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2 + str r2, [r0, #0xA0] @ Store data info + + ldr r1, =(0xD << 3) @ A[6:3] = b1101 + mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register + mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2 + str r2, [r0, #0xA4] @ Store data info + mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2 + str r2, [r0, #0xA8] @ Store data info + mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2 + str r2, [r0, #0xAC] @ Store data info + + ldr r1, =(0xE << 3) @ A[6:3] = b1110 + mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register + mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2 + str r2, [r0, #0xB0] @ Store data info + mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2 + str r2, [r0, #0xB4] @ Store data info + mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2 + str r2, [r0, #0xB8] @ Store data info + + ldr r1, =(0xF << 3) @ A[6:3] = b1111 + mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register + mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2 + str r2, [r0, #0xBC] @ Store data info + mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2 + str r2, [r0, #0xC0] @ Store data info + mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2 + str r2, [r0, #0xC4] @ Store data info + + ldr r1, =(0x2 << 29) | (0x0 << 6) @ WAY = A[31:29] = 2, A[6] = 0 + mcr p15, 0, r1, c15, c9, 2 @ Read L2 tag RAM into L2 data 0 register + mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2 + str r2, [r0, #0xC8] @ Save tag info + + ldr r1, =(0x2 << 29) | (0x1 << 6) @ WAY = A[31:29] = 2, A[6] = 1 + mcr p15, 0, r1, c15, c9, 2 @ Read L2 tag RAM into L2 data 0 register + mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2 + str r2, [r0, #0xCC] @ Save tag info + + ldr r1, =(0x4 << 29) | (0x0 << 6) @ WAY = A[31:29] = 4, A[6] = 0 + mcr p15, 0, r1, c15, c9, 2 @ Read L2 tag RAM into L2 data 0 register + mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2 + str r2, [r0, #0xD0] @ Save tag info + + ldr r1, =(0x4 << 29) | (0x1 << 6) @ WAY = A[31:29] = 4, A[6] = 1 + mcr p15, 0, r1, c15, c9, 2 @ Read L2 tag RAM into L2 data 0 register + mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2 + str r2, [r0, #0xD4] @ Save tag info + + ldr r1, =(0x6 << 29) | (0x0 << 6) @ WAY = A[31:29] = 6, A[6] = 0 + mcr p15, 0, r1, c15, c9, 2 @ Read L2 tag RAM into L2 data 0 register + mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2 + str r2, [r0, #0xD8] @ Save tag info + + ldr r1, =(0x6 << 29) | (0x1 << 6) @ WAY = A[31:29] = 6, A[6] = 1 + mcr p15, 0, r1, c15, c9, 2 @ Read L2 tag RAM into L2 data 0 register + mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2 + str r2, [r0, #0xDC] @ Save tag info + + .long 0xe320f003 @ Opcode for WFI + + ldr r1, =(0x0 << 6) @ A[6] = 0 + ldr r2, [r0, #0x00] @ Load tag info + mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register + mcr p15, 0, r1, c15, c8, 2 @ Write L2 data 0 register to L2 tag RAM + + ldr r1, =(0x1 << 6) @ A[6] = 1 + ldr r2, [r0, #0x04] @ Load tag info + mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register + mcr p15, 0, r1, c15, c8, 2 @ Write L2 data 0 register to L2 tag RAM + + ldr r1, =(0x0 << 3) @ A[6:3] = b0000 + ldr r2, [r0, #0x08] @ Load data info + mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register + ldr r2, [r0, #0x0C] @ Load data info + mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register + ldr r2, [r0, #0x10] @ Load data info + mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register + mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM + + ldr r1, =(0x1 << 3) @ A[6:3] = b0001 + ldr r2, [r0, #0x14] @ Load data info + mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register + ldr r2, [r0, #0x18] @ Load data info + mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register + ldr r2, [r0, #0x1C] @ Load data info + mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register + mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM + + ldr r1, =(0x2 << 3) @ A[6:3] = b0010 + ldr r2, [r0, #0x20] @ Load data info + mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register + ldr r2, [r0, #0x24] @ Load data info + mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register + ldr r2, [r0, #0x28] @ Load data info + mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register + mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM + + ldr r1, =(0x3 << 3) @ A[6:3] = b0011 + ldr r2, [r0, #0x2C] @ Load data info + mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register + ldr r2, [r0, #0x30] @ Load data info + mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register + ldr r2, [r0, #0x34] @ Load data info + mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register + mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM + + ldr r1, =(0x4 << 3) @ A[6:3] = b0100 + ldr r2, [r0, #0x38] @ Load data info + mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register + ldr r2, [r0, #0x3C] @ Load data info + mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register + ldr r2, [r0, #0x40] @ Load data info + mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register + mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM + + ldr r1, =(0x5 << 3) @ A[6:3] = b0101 + ldr r2, [r0, #0x44] @ Load data info + mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register + ldr r2, [r0, #0x48] @ Load data info + mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register + ldr r2, [r0, #0x4C] @ Load data info + mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register + mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM + + ldr r1, =(0x6 << 3) @ A[6:3] = b0110 + ldr r2, [r0, #0x50] @ Load data info + mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register + ldr r2, [r0, #0x54] @ Load data info + mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register + ldr r2, [r0, #0x58] @ Load data info + mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register + mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM + + ldr r1, =(0x7 << 3) @ A[6:3] = b0111 + ldr r2, [r0, #0x5C] @ Load data info + mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register + ldr r2, [r0, #0x60] @ Load data info + mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register + ldr r2, [r0, #0x64] @ Load data info + mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register + mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM + + ldr r1, =(0x8 << 3) @ A[6:3] = b1000 + ldr r2, [r0, #0x68] @ Load data info + mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register + ldr r2, [r0, #0x6C] @ Load data info + mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register + ldr r2, [r0, #0x70] @ Load data info + mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register + mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM + + ldr r1, =(0x9 << 3) @ A[6:3] = b1001 + ldr r2, [r0, #0x74] @ Load data info + mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register + ldr r2, [r0, #0x78] @ Load data info + mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register + ldr r2, [r0, #0x7C] @ Load data info + mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register + mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM + + ldr r1, =(0xA << 3) @ A[6:3] = b1010 + ldr r2, [r0, #0x80] @ Load data info + mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register + ldr r2, [r0, #0x84] @ Load data info + mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register + ldr r2, [r0, #0x88] @ Load data info + mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register + mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM + + ldr r1, =(0xB << 3) @ A[6:3] = b1011 + ldr r2, [r0, #0x8C] @ Load data info + mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register + ldr r2, [r0, #0x90] @ Load data info + mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register + ldr r2, [r0, #0x94] @ Load data info + mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register + mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM + + ldr r1, =(0xC << 3) @ A[6:3] = b1100 + ldr r2, [r0, #0x98] @ Load data info + mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register + ldr r2, [r0, #0x9C] @ Load data info + mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register + ldr r2, [r0, #0xA0] @ Load data info + mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register + mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM + + ldr r1, =(0xD << 3) @ A[6:3] = b1101 + ldr r2, [r0, #0xA4] @ Load data info + mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register + ldr r2, [r0, #0xA8] @ Load data info + mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register + ldr r2, [r0, #0xAC] @ Load data info + mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register + mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM + + ldr r1, =(0xE << 3) @ A[6:3] = b1110 + ldr r2, [r0, #0xB0] @ Load data info + mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register + ldr r2, [r0, #0xB4] @ Load data info + mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register + ldr r2, [r0, #0xB8] @ Load data info + mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register + mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM + + ldr r1, =(0xF << 3) @ A[6:3] = b1111 + ldr r2, [r0, #0xBC] @ Load data info + mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register + ldr r2, [r0, #0xC0] @ Load data info + mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register + ldr r2, [r0, #0xC4] @ Load data info + mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register + mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM + + ldr r1, =(0x2 << 29) | (0x0 << 6) @ WAY = A[31:29] = 2, A[6] = 0 + ldr r2, [r0, #0xC8] @ Load tag info + mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register + mcr p15, 0, r1, c15, c8, 2 @ Write L2 data 0 register to L2 tag RAM + + ldr r1, =(0x2 << 29) | (0x1 << 6) @ WAY = A[31:29] = 2, A[6] = 1 + ldr r2, [r0, #0xCC] @ Load tag info + mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register + mcr p15, 0, r1, c15, c8, 2 @ Write L2 data 0 register to L2 tag RAM + + ldr r1, =(0x4 << 29) | (0x0 << 6) @ WAY = A[31:29] = 4, A[6] = 0 + ldr r2, [r0, #0xD0] @ Load tag info + mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register + mcr p15, 0, r1, c15, c8, 2 @ Write L2 data 0 register to L2 tag RAM + + ldr r1, =(0x4 << 29) | (0x1 << 6) @ WAY = A[31:29] = 4, A[6] = 1 + ldr r2, [r0, #0xD4] @ Load tag info + mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register + mcr p15, 0, r1, c15, c8, 2 @ Write L2 data 0 register to L2 tag RAM + + ldr r1, =(0x6 << 29) | (0x0 << 6) @ WAY = A[31:29] = 6, A[6] = 0 + ldr r2, [r0, #0xD8] @ Load tag info + mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register + mcr p15, 0, r1, c15, c8, 2 @ Write L2 data 0 register to L2 tag RAM + + ldr r1, =(0x6 << 29) | (0x1 << 6) @ WAY = A[31:29] = 6, A[6] = 1 + ldr r2, [r0, #0xDC] @ Load tag info + mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register + mcr p15, 0, r1, c15, c8, 2 @ Write L2 data 0 register to L2 tag RAM + + mrc p15, 0, r1, c1, c0, 1 @ R1 = auxiliary control reg + orr r1, r1, #ARM_AUXCR_L2EN @ Enable L2 cache + mcr p15, 0, r1, c1, c0, 1 @ Update aux control reg + + mrc p15, 0, r2, c1, c0, 0 @ R2 = system control reg + orr r2, r2, #ARM_CTRL_DCACHE @ Enable DCache + mcr p15, 0, r2, c1, c0, 0 @ Update system control reg + + b Done + +SkipL2Access: + .long 0xe320f003 @ Opcode for WFI + +Done: + mov pc, lr + + .type cortexa8_idle_workaround, #object +ENTRY(cortexa8_idle_workaround) + .word cpu_cortexa8_do_idle + .size cortexa8_idle_workaround, . - cortexa8_idle_workaround + --- linux-2.6.28.orig/arch/arm/mach-mx51/usb_dr.c +++ linux-2.6.28/arch/arm/mach-mx51/usb_dr.c @@ -0,0 +1,143 @@ +/* + * Copyright 2005-2009 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 + */ + +#include +#include +#include +#include +#include +#include +#include "usb.h" + +static int usbotg_init_ext(struct platform_device *pdev); +static void usbotg_uninit_ext(struct fsl_usb2_platform_data *pdata); + +/* + * platform data structs + * - Which one to use is determined by CONFIG options in usb.h + * - operating_mode plugged at run time + */ +static struct fsl_usb2_platform_data __maybe_unused dr_utmi_config = { + .name = "DR", + .platform_init = usbotg_init_ext, + .platform_uninit = usbotg_uninit_ext, + .phy_mode = FSL_USB2_PHY_UTMI_WIDE, + .power_budget = 500, /* 500 mA max power */ + .gpio_usb_active = gpio_usbotg_hs_active, + .gpio_usb_inactive = gpio_usbotg_hs_inactive, + .transceiver = "utmi", +}; + + +/* + * resources + */ +static struct resource otg_resources[] = { + [0] = { + .start = (u32)(USB_OTGREGS_BASE), + .end = (u32)(USB_OTGREGS_BASE + 0x1ff), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_USB_OTG, + .flags = IORESOURCE_IRQ, + }, +}; + + +static u64 dr_udc_dmamask = ~(u32) 0; +static void dr_udc_release(struct device *dev) +{ +} + +static u64 dr_otg_dmamask = ~(u32) 0; +static void dr_otg_release(struct device *dev) +{ +} + +/* + * platform device structs + * dev.platform_data field plugged at run time + */ +static struct platform_device dr_udc_device = { + .name = "fsl-usb2-udc", + .id = -1, + .dev = { + .release = dr_udc_release, + .dma_mask = &dr_udc_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .resource = otg_resources, + .num_resources = ARRAY_SIZE(otg_resources), +}; + +static struct platform_device __maybe_unused dr_otg_device = { + .name = "fsl-usb2-otg", + .id = -1, + .dev = { + .release = dr_otg_release, + .dma_mask = &dr_otg_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .resource = otg_resources, + .num_resources = ARRAY_SIZE(otg_resources), +}; + +/* Notes: configure USB clock*/ +static int usbotg_init_ext(struct platform_device *pdev) +{ + struct clk *usb_clk; + + usb_clk = clk_get(NULL, "usboh3_clk"); + clk_enable(usb_clk); + clk_put(usb_clk); + + usb_clk = clk_get(NULL, "usb_phy_clk"); + clk_enable(usb_clk); + clk_put(usb_clk); + + /*derive clock from oscillator */ + usb_clk = clk_get(NULL, "usb_utmi_clk"); + clk_disable(usb_clk); + clk_put(usb_clk); + + return usbotg_init(pdev); +} + +static void usbotg_uninit_ext(struct fsl_usb2_platform_data *pdata) +{ + struct clk *usb_clk; + + usb_clk = clk_get(NULL, "usboh3_clk"); + clk_disable(usb_clk); + clk_put(usb_clk); + + usb_clk = clk_get(NULL, "usb_phy_clk"); + clk_disable(usb_clk); + clk_put(usb_clk); + + usbotg_uninit(pdata); +} + +static int __init usb_dr_init(void) +{ + pr_debug("%s: \n", __func__); + + dr_register_otg(); + dr_register_host(otg_resources, ARRAY_SIZE(otg_resources)); + dr_register_udc(); + + return 0; +} + +module_init(usb_dr_init); --- linux-2.6.28.orig/arch/arm/mach-mx51/mm.c +++ linux-2.6.28/arch/arm/mach-mx51/mm.c @@ -0,0 +1,84 @@ +/* + * Copyright 2008-2009 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 + */ + +#include +#include +#include +#include +#include + +/*! + * @file mach-mx51/mm.c + * + * @brief This file creates static mapping between physical to virtual memory. + * + * @ingroup Memory_MX51 + */ + +/*! + * This structure defines the MX51 memory map. + */ +static struct map_desc mxc_io_desc[] __initdata = { + { + .virtual = IRAM_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(IRAM_BASE_ADDR), + .length = IRAM_SIZE, + .type = MT_DEVICE}, + { + .virtual = DEBUG_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(DEBUG_BASE_ADDR), + .length = DEBUG_SIZE, + .type = MT_DEVICE}, + { + .virtual = TZIC_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(TZIC_BASE_ADDR), + .length = TZIC_SIZE, + .type = MT_DEVICE}, + { + .virtual = AIPS1_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(AIPS1_BASE_ADDR), + .length = AIPS1_SIZE, + .type = MT_DEVICE}, + { + .virtual = SPBA0_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(SPBA0_BASE_ADDR), + .length = SPBA0_SIZE, + .type = MT_DEVICE}, + { + .virtual = AIPS2_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(AIPS2_BASE_ADDR), + .length = AIPS2_SIZE, + .type = MT_DEVICE}, + { + .virtual = NFC_BASE_ADDR_AXI_VIRT, + .pfn = __phys_to_pfn(NFC_BASE_ADDR_AXI), + .length = NFC_AXI_SIZE, + .type = MT_DEVICE}, +}; + +/*! + * This function initializes 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) +{ + u32 tzic_addr; + if (cpu_is_mx51_rev(CHIP_REV_2_0) < 0) + tzic_addr = 0x8FFFC000; + else + tzic_addr = 0xE0003000; + + mxc_io_desc[2].pfn = __phys_to_pfn(tzic_addr); + iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc)); +} --- linux-2.6.28.orig/arch/arm/mach-mx51/usb_h2.c +++ linux-2.6.28/arch/arm/mach-mx51/usb_h2.c @@ -0,0 +1,85 @@ +/* + * Copyright 2005-2009 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 + */ + +#include +#include +#include +#include +#include +#include +#include "usb.h" +#include "iomux.h" + +/* + * USB Host2 HS port + */ +static int gpio_usbh2_active(void) +{ + /* Set USBH2_STP to GPIO and toggle it */ + mxc_request_iomux(MX51_PIN_EIM_A26, IOMUX_CONFIG_GPIO); + mxc_set_gpio_direction(MX51_PIN_EIM_A26, 0); + mxc_set_gpio_dataout(MX51_PIN_EIM_A26, 1); + + msleep(100); + + return 0; +} + +void gpio_usbh2_setback_stp(void) +{ + /* setback USBH2_STP to be function */ + mxc_request_iomux(MX51_PIN_EIM_A26, IOMUX_CONFIG_ALT2); +} +EXPORT_SYMBOL(gpio_usbh2_setback_stp); + +static void gpio_usbh2_inactive(void) +{ + mxc_request_gpio(MX51_PIN_EIM_A26); + mxc_free_iomux(MX51_PIN_EIM_A26, IOMUX_CONFIG_GPIO); +} + +static struct fsl_usb2_platform_data usbh2_config = { + .name = "Host 2", + .platform_init = fsl_usb_host_init, + .platform_uninit = fsl_usb_host_uninit, + .operating_mode = FSL_USB2_MPH_HOST, + .phy_mode = FSL_USB2_PHY_ULPI, + .power_budget = 500, /* 500 mA max power */ + .gpio_usb_active = gpio_usbh2_active, + .gpio_usb_inactive = gpio_usbh2_inactive, + .transceiver = "isp1504", +}; + +static struct resource usbh2_resources[] = { + [0] = { + .start = (u32) (USB_H2REGS_BASE), + .end = (u32) (USB_H2REGS_BASE + 0x1ff), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_USB_H2, + .flags = IORESOURCE_IRQ, + }, +}; + +static int __init usbh2_init(void) +{ + pr_debug("%s: \n", __func__); + + host_pdev_register(usbh2_resources, ARRAY_SIZE(usbh2_resources), + &usbh2_config); + return 0; +} + +module_init(usbh2_init); + --- linux-2.6.28.orig/arch/arm/mach-mx51/mx51_babbage_gpio.c +++ linux-2.6.28/arch/arm/mach-mx51/mx51_babbage_gpio.c @@ -0,0 +1,464 @@ +/* + * Copyright 2007-2009 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 + */ + +#include +#include +#include +#include +#include +#include + +#include "iomux.h" + +/*! + * @file mach-mx51/mx51_babbage_gpio.c + * + * @brief This file contains all the GPIO setup functions for the board. + * + * @ingroup GPIO + */ + +static struct mxc_iomux_pin_cfg __initdata mxc_iomux_pins[] = { + /* USBH2_DATA0 */ + { + MX51_PIN_EIM_D16, IOMUX_CONFIG_ALT2, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_100K_PU | PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | + PAD_CTL_HYS_ENABLE), + }, + /* USBH2_DATA1 */ + { + MX51_PIN_EIM_D17, IOMUX_CONFIG_ALT2, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + /* USBH2_DATA2 */ + { + MX51_PIN_EIM_D18, IOMUX_CONFIG_ALT2, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + /* USBH2_DATA3 */ + { + MX51_PIN_EIM_D19, IOMUX_CONFIG_ALT2, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + /* USBH2_DATA4 */ + { + MX51_PIN_EIM_D20, IOMUX_CONFIG_ALT2, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + /* USBH2_DATA5 */ + { + MX51_PIN_EIM_D21, IOMUX_CONFIG_ALT2, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + /* USBH2_DATA6 */ + { + MX51_PIN_EIM_D22, IOMUX_CONFIG_ALT2, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + /* USBH2_DATA7 */ + { + MX51_PIN_EIM_D23, IOMUX_CONFIG_ALT2, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { + MX51_PIN_EIM_A16, IOMUX_CONFIG_GPIO, + }, + { + MX51_PIN_EIM_A17, IOMUX_CONFIG_GPIO, + }, + { + MX51_PIN_EIM_A18, IOMUX_CONFIG_GPIO, + }, + { + MX51_PIN_EIM_A19, IOMUX_CONFIG_GPIO, + }, + { + MX51_PIN_EIM_A20, IOMUX_CONFIG_GPIO, + (PAD_CTL_PKE_ENABLE), + }, + { + MX51_PIN_EIM_A21, IOMUX_CONFIG_GPIO, + }, + { + MX51_PIN_EIM_A22, IOMUX_CONFIG_GPIO, + }, + { + MX51_PIN_EIM_A23, IOMUX_CONFIG_GPIO, + }, + { + MX51_PIN_EIM_A24, IOMUX_CONFIG_ALT2, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { + MX51_PIN_EIM_A25, IOMUX_CONFIG_ALT2, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { + MX51_PIN_EIM_A26, IOMUX_CONFIG_ALT2, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { + MX51_PIN_EIM_A27, IOMUX_CONFIG_ALT2, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /*MDIO */ + MX51_PIN_EIM_EB2, IOMUX_CONFIG_ALT3, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_ENABLE | + PAD_CTL_22K_PU | PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | + PAD_CTL_PUE_PULL), + }, + { /*RDATA[1] */ + + MX51_PIN_EIM_EB3, IOMUX_CONFIG_ALT3, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE), + }, + { /*RDATA[2] */ + MX51_PIN_EIM_CS2, IOMUX_CONFIG_ALT3, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE), + }, + { /*RDATA[3] */ + MX51_PIN_EIM_CS3, IOMUX_CONFIG_ALT3, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE), + }, + { /*RX_ER */ + MX51_PIN_EIM_CS4, IOMUX_CONFIG_ALT3, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE), + }, + { /*CRS */ + MX51_PIN_EIM_CS5, IOMUX_CONFIG_ALT3, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE), + }, + { + MX51_PIN_EIM_DTACK, IOMUX_CONFIG_GPIO, + (PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU), + }, + { + MX51_PIN_EIM_LBA, IOMUX_CONFIG_GPIO, + }, + { + MX51_PIN_EIM_CRE, IOMUX_CONFIG_GPIO, + }, + { + MX51_PIN_NANDF_RB2, IOMUX_CONFIG_ALT1, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE), + }, + { + MX51_PIN_NANDF_RB3, IOMUX_CONFIG_ALT1, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE), + }, + { + MX51_PIN_NANDF_RB4, IOMUX_CONFIG_ALT1, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE), + }, + { /*RDATA[0] */ + MX51_PIN_NANDF_RB6, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_VOT_HIGH | PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE), + }, + { /*TDATA[0] */ + MX51_PIN_NANDF_RB7, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_VOT_HIGH | PAD_CTL_DRV_HIGH), + }, + { + MX51_PIN_NANDF_CS0, IOMUX_CONFIG_GPIO, + (PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU), + }, + { + MX51_PIN_NANDF_CS1, IOMUX_CONFIG_GPIO, + }, + { /*TX_ER */ + MX51_PIN_NANDF_CS2, IOMUX_CONFIG_ALT2, + (PAD_CTL_DRV_VOT_HIGH | PAD_CTL_DRV_HIGH), + }, + { + MX51_PIN_NANDF_CS3, IOMUX_CONFIG_ALT2, + (PAD_CTL_DRV_VOT_HIGH | PAD_CTL_DRV_HIGH), + }, + { /*TDATA[1] */ + MX51_PIN_NANDF_CS4, IOMUX_CONFIG_ALT2, + (PAD_CTL_DRV_VOT_HIGH | PAD_CTL_DRV_HIGH), + }, + { /*TDATA[2] */ + MX51_PIN_NANDF_CS5, IOMUX_CONFIG_ALT2, + (PAD_CTL_DRV_VOT_HIGH | PAD_CTL_DRV_HIGH), + }, + { /*TDATA[3] */ + MX51_PIN_NANDF_CS6, IOMUX_CONFIG_ALT2, + (PAD_CTL_DRV_VOT_HIGH | PAD_CTL_DRV_HIGH), + }, + { /*TX_EN */ + MX51_PIN_NANDF_CS7, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_VOT_HIGH | PAD_CTL_DRV_HIGH), + }, + { /*TX_CLK */ + MX51_PIN_NANDF_RDY_INT, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_VOT_HIGH | PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE), + }, + { + MX51_PIN_GPIO1_8, IOMUX_CONFIG_GPIO | IOMUX_CONFIG_SION, + (PAD_CTL_SRE_SLOW | PAD_CTL_DRV_MEDIUM | PAD_CTL_100K_PU | + PAD_CTL_HYS_ENABLE | PAD_CTL_DRV_VOT_HIGH), + }, + { + MX51_PIN_DI_GP4, IOMUX_CONFIG_ALT4, + }, + { + MX51_PIN_DISPB2_SER_DIN, IOMUX_CONFIG_GPIO, + 0, + MUX_IN_GPIO3_IPP_IND_G_IN_5_SELECT_INPUT, + INPUT_CTL_PATH1, + }, + { + MX51_PIN_I2C1_CLK, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + 0x1E4, + }, + { + MX51_PIN_I2C1_DAT, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + 0x1E4, + }, + { + MX51_PIN_GPIO1_2, IOMUX_CONFIG_ALT2 | IOMUX_CONFIG_SION, + (PAD_CTL_SRE_FAST | PAD_CTL_ODE_OPENDRAIN_ENABLE | PAD_CTL_DRV_HIGH | + PAD_CTL_100K_PU | PAD_CTL_HYS_ENABLE), + MUX_IN_I2C2_IPP_SCL_IN_SELECT_INPUT, INPUT_CTL_PATH3, + }, + { + MX51_PIN_GPIO1_3, IOMUX_CONFIG_ALT2 | IOMUX_CONFIG_SION, + (PAD_CTL_SRE_FAST | PAD_CTL_ODE_OPENDRAIN_ENABLE | PAD_CTL_DRV_HIGH | + PAD_CTL_100K_PU | PAD_CTL_HYS_ENABLE), + MUX_IN_I2C2_IPP_SDA_IN_SELECT_INPUT, INPUT_CTL_PATH3, + }, + { + MX51_PIN_USBH1_STP, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_PUE_KEEPER | + PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* USBH1_CLK */ + MX51_PIN_USBH1_CLK, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_PUE_KEEPER | + PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE | PAD_CTL_DDR_INPUT_CMOS), + }, + { /* USBH1_DIR */ + MX51_PIN_USBH1_DIR, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_PUE_KEEPER | + PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE | PAD_CTL_DDR_INPUT_CMOS), + }, + { /* USBH1_NXT */ + MX51_PIN_USBH1_NXT, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_PUE_KEEPER | + PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE | PAD_CTL_DDR_INPUT_CMOS), + }, + { /* USBH1_DATA0 */ + MX51_PIN_USBH1_DATA0, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* USBH1_DATA1 */ + MX51_PIN_USBH1_DATA1, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* USBH1_DATA2 */ + MX51_PIN_USBH1_DATA2, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* USBH1_DATA3 */ + MX51_PIN_USBH1_DATA3, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* USBH1_DATA4 */ + MX51_PIN_USBH1_DATA4, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* USBH1_DATA5 */ + MX51_PIN_USBH1_DATA5, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* USBH1_DATA6 */ + MX51_PIN_USBH1_DATA6, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* USBH1_DATA7 */ + MX51_PIN_USBH1_DATA7, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { + MX51_PIN_SD1_CMD, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_SD1_CLK, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_SD1_DATA0, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_SD1_DATA1, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_SD1_DATA2, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_SD1_DATA3, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_GPIO1_0, IOMUX_CONFIG_GPIO | IOMUX_CONFIG_SION, + (PAD_CTL_HYS_ENABLE | PAD_CTL_100K_PU), + }, + { + MX51_PIN_GPIO1_1, IOMUX_CONFIG_GPIO | IOMUX_CONFIG_SION, + (PAD_CTL_HYS_ENABLE | PAD_CTL_100K_PU), + }, + { + MX51_PIN_UART1_RXD, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST), + MUX_IN_UART1_IPP_UART_RXD_MUX_SELECT_INPUT, + INPUT_CTL_PATH0, + }, + { + MX51_PIN_UART1_TXD, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_UART1_RTS, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_DRV_HIGH), + MUX_IN_UART1_IPP_UART_RTS_B_SELECT_INPUT, + INPUT_CTL_PATH0, + }, + { + MX51_PIN_UART1_CTS, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_DRV_HIGH), + }, + { + MX51_PIN_AUD3_BB_TXD, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_100K_PU | PAD_CTL_HYS_NONE | PAD_CTL_DDR_INPUT_CMOS | + PAD_CTL_DRV_VOT_LOW), + }, + { + MX51_PIN_AUD3_BB_RXD, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_100K_PU | PAD_CTL_HYS_NONE | PAD_CTL_DDR_INPUT_CMOS | + PAD_CTL_DRV_VOT_LOW), + }, + { + MX51_PIN_AUD3_BB_CK, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_100K_PU | PAD_CTL_HYS_NONE | PAD_CTL_DDR_INPUT_CMOS | + PAD_CTL_DRV_VOT_LOW), + }, + { + MX51_PIN_AUD3_BB_FS, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_100K_PU | PAD_CTL_HYS_NONE | PAD_CTL_DDR_INPUT_CMOS | + PAD_CTL_DRV_VOT_LOW), + }, +}; + +void __init mx51_babbage_io_init(void) +{ + int i; + + /* Work-around For external USB HUB chip to use default configuration + by reseting hub with i2c lines pulled low */ + mxc_request_iomux(MX51_PIN_GPIO1_7, IOMUX_CONFIG_GPIO); + mxc_iomux_set_pad(MX51_PIN_GPIO1_7, PAD_CTL_DRV_HIGH | + PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST); + mxc_set_gpio_direction(MX51_PIN_GPIO1_7, 0); + mxc_set_gpio_dataout(MX51_PIN_GPIO1_7, 1); + + /* Drive I2C1 SDA line low */ + mxc_request_iomux(MX51_PIN_GPIO1_3, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX51_PIN_GPIO1_3, PAD_CTL_DRV_HIGH | + PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST); + mxc_set_gpio_direction(MX51_PIN_GPIO1_3, 0); + mxc_set_gpio_dataout(MX51_PIN_GPIO1_3, 0); + + /* Drive I2C1 SCL line low */ + mxc_request_iomux(MX51_PIN_GPIO1_2, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX51_PIN_GPIO1_2, PAD_CTL_DRV_HIGH | + PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST); + mxc_set_gpio_direction(MX51_PIN_GPIO1_2, 0); + mxc_set_gpio_dataout(MX51_PIN_GPIO1_2, 0); + + /* USB HUB RESET - De-assert USB HUB RESET_N */ + msleep(1); + mxc_set_gpio_dataout(MX51_PIN_GPIO1_7, 0); + msleep(5); + mxc_set_gpio_dataout(MX51_PIN_GPIO1_7, 1); + + msleep(5); + mxc_free_iomux(MX51_PIN_GPIO1_2, IOMUX_CONFIG_ALT2); + mxc_free_iomux(MX51_PIN_GPIO1_3, IOMUX_CONFIG_ALT2); + + for (i = 0; i < ARRAY_SIZE(mxc_iomux_pins); i++) { + mxc_request_iomux(mxc_iomux_pins[i].pin, + mxc_iomux_pins[i].mux_mode); + if (mxc_iomux_pins[i].pad_cfg) + mxc_iomux_set_pad(mxc_iomux_pins[i].pin, + mxc_iomux_pins[i].pad_cfg); + if (mxc_iomux_pins[i].in_select) + mxc_iomux_set_input(mxc_iomux_pins[i].in_select, + mxc_iomux_pins[i].in_mode); + } + + mxc_set_gpio_direction(MX51_PIN_GPIO1_8, 1); + mxc_set_gpio_direction(MX51_PIN_GPIO1_0, 1); /* SD1 CD */ + mxc_set_gpio_direction(MX51_PIN_GPIO1_1, 1); /* SD1 WP */ + + /* reset FEC PHY */ + mxc_set_gpio_direction(MX51_PIN_EIM_A20, 0); + mxc_set_gpio_dataout(MX51_PIN_EIM_A20, 0); + msleep(10); + mxc_set_gpio_dataout(MX51_PIN_EIM_A20, 1); + + /* reset FM */ + mxc_set_gpio_dataout(MX51_PIN_EIM_A21, 0); + mxc_set_gpio_direction(MX51_PIN_EIM_A21, 0); + msleep(10); + mxc_set_gpio_dataout(MX51_PIN_EIM_A21, 1); + + /* MX51_PIN_EIM_CRE - De-assert USB PHY RESETB */ + mxc_set_gpio_direction(MX51_PIN_EIM_CRE, 0); + mxc_set_gpio_dataout(MX51_PIN_EIM_CRE, 1); + + /* Deassert VGA reset to free i2c bus */ + mxc_set_gpio_direction(MX51_PIN_EIM_A19, 0); + mxc_set_gpio_dataout(MX51_PIN_EIM_A19, 1); +} --- linux-2.6.28.orig/arch/arm/mach-mx51/Kconfig +++ linux-2.6.28/arch/arm/mach-mx51/Kconfig @@ -0,0 +1,91 @@ +menu "MX51 Options" + depends on ARCH_MX51 + +config MX51_OPTIONS + bool + default y + select CPU_V7 + select USB_ARCH_HAS_EHCI + select MXC_TZIC + +config MACH_MX51_3DS + bool "Support MX51 3-Stack platforms" + default y + help + Include support for MX51 3-Stack platform. This includes specific + configurations for the board and its peripherals. + +config MACH_MX51_BABBAGE + bool "Support MX51 BABBAGE platforms" + help + Include support for MX51 Babbage platform. This includes specific + configurations for the board and its peripherals. + +config MXC_SDMA_API + bool "Use SDMA API" + default y + help + This selects the Freescale MXC SDMA API. + If unsure, say N. + +config ARCH_MXC_HAS_NFC_V3 + bool "MXC NFC Hardware Version 3" + depends on ARCH_MX51 + default y + help + This selects the Freescale MXC Nand Flash Controller Hardware Version 3 + If unsure, say N. + +config ARCH_MXC_HAS_NFC_V3_2 + bool "MXC NFC Hardware Version 3.2" + depends on ARCH_MXC_HAS_NFC_V3 + default y + help + This selects the Freescale MXC Nand Flash Controller Hardware Version 3.1 + If unsure, say N. + +menu "SDMA options" + depends on MXC_SDMA_API + +config SDMA_IRAM + bool "Use Internal RAM for SDMA transfer" + default n + help + Support Internal RAM as SDMA buffer or control structures + +config SDMA_IRAM_SIZE + hex "Reserved bytes of IRAM for SDMA (0x800-0x1000)" + range 0x800 0x1000 + depends on SDMA_IRAM + default "0x1000" + help + Set the size of IRAM for SDMA. It must be a multiple of 512bytes. +endmenu + +menu "Device options" + +config I2C_MXC_SELECT1 + bool "Enable I2C1 module" + default y + depends on I2C_MXC + help + Enable MX51 I2C1 module. + +config I2C_MXC_SELECT2 + bool "Enable I2C2 module" + default n + depends on I2C_MXC + help + Enable MX51 I2C2 module. + +config I2C_MXC_SELECT3 + bool "Enable I2C3 module" + default n + depends on I2C_MXC + help + Enable MX51 I2C3 module. + +endmenu + +endmenu + --- linux-2.6.28.orig/arch/arm/mach-mx51/mx51_3stack_pmic_mc13892.c +++ linux-2.6.28/arch/arm/mach-mx51/mx51_3stack_pmic_mc13892.c @@ -0,0 +1,280 @@ +/* + * mx51-3stack-pmic-mc13892.c -- i.MX51 3STACK Driver for Atlas MC13892 PMIC + */ + /* + * Copyright 2009 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "iomux.h" + +/* + * Convenience conversion. + * Here atm, maybe there is somewhere better for this. + */ +#define mV_to_uV(mV) (mV * 1000) +#define uV_to_mV(uV) (uV / 1000) +#define V_to_uV(V) (mV_to_uV(V * 1000)) +#define uV_to_V(uV) (uV_to_mV(uV) / 1000) + +/* CPU */ +static struct regulator_consumer_supply sw1_consumers[] = { + { + .supply = "cpu_vcc", + } +}; + +struct mc13892; + +static struct regulator_init_data sw1_init = { + .constraints = { + .name = "SW1", + .min_uV = mV_to_uV(600), + .max_uV = mV_to_uV(1375), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .valid_modes_mask = 0, + .always_on = 1, + .boot_on = 1, + .initial_state = PM_SUSPEND_MEM, + .state_mem = { + .uV = 700000, + .mode = REGULATOR_MODE_NORMAL, + .enabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(sw1_consumers), + .consumer_supplies = sw1_consumers, +}; + +static struct regulator_init_data sw2_init = { + .constraints = { + .name = "SW2", + .min_uV = mV_to_uV(900), + .max_uV = mV_to_uV(1850), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .always_on = 1, + .boot_on = 1, + .initial_state = PM_SUSPEND_MEM, + .state_mem = { + .uV = 900000, + .mode = REGULATOR_MODE_NORMAL, + .enabled = 1, + }, + } +}; + +static struct regulator_init_data sw3_init = { + .constraints = { + .name = "SW3", + .min_uV = mV_to_uV(1100), + .max_uV = mV_to_uV(1850), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .always_on = 1, + .boot_on = 1, + } +}; + +static struct regulator_init_data sw4_init = { + .constraints = { + .name = "SW4", + .min_uV = mV_to_uV(1100), + .max_uV = mV_to_uV(1850), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .always_on = 1, + .boot_on = 1, + } +}; + +static struct regulator_init_data viohi_init = { + .constraints = { + .name = "VIOHI", + .boot_on = 1, + } +}; + +static struct regulator_init_data vusb_init = { + .constraints = { + .name = "VUSB", + .boot_on = 1, + } +}; + +static struct regulator_init_data swbst_init = { + .constraints = { + .name = "SWBST", + } +}; + +static struct regulator_init_data vdig_init = { + .constraints = { + .name = "VDIG", + .min_uV = mV_to_uV(1050), + .max_uV = mV_to_uV(1800), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .boot_on = 1, + } +}; + +static struct regulator_init_data vpll_init = { + .constraints = { + .name = "VPLL", + .min_uV = mV_to_uV(1050), + .max_uV = mV_to_uV(1800), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .boot_on = 1, + } +}; + +static struct regulator_init_data vusb2_init = { + .constraints = { + .name = "VUSB2", + .min_uV = mV_to_uV(2400), + .max_uV = mV_to_uV(2775), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .boot_on = 1, + } +}; + +static struct regulator_init_data vvideo_init = { + .constraints = { + .name = "VVIDEO", + .min_uV = mV_to_uV(2500), + .max_uV = mV_to_uV(2775), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + } +}; + +static struct regulator_init_data vaudio_init = { + .constraints = { + .name = "VAUDIO", + .min_uV = mV_to_uV(2300), + .max_uV = mV_to_uV(3000), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + } +}; + +static struct regulator_init_data vsd_init = { + .constraints = { + .name = "VSD", + .min_uV = mV_to_uV(1800), + .max_uV = mV_to_uV(3150), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + } +}; + +static struct regulator_init_data vcam_init = { + .constraints = { + .name = "VCAM", + .min_uV = mV_to_uV(2500), + .max_uV = mV_to_uV(3000), + .valid_ops_mask = + REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE, + .valid_modes_mask = REGULATOR_MODE_FAST | REGULATOR_MODE_NORMAL, + } +}; + +static struct regulator_init_data vgen1_init = { + .constraints = { + .name = "VGEN1", + .min_uV = mV_to_uV(1200), + .max_uV = mV_to_uV(3150), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + } +}; + +static struct regulator_init_data vgen2_init = { + .constraints = { + .name = "VGEN2", + .min_uV = mV_to_uV(1200), + .max_uV = mV_to_uV(3150), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + } +}; + +static struct regulator_init_data vgen3_init = { + .constraints = { + .name = "VGEN3", + .min_uV = mV_to_uV(1800), + .max_uV = mV_to_uV(2900), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + } +}; + +/*! + * the event handler for power on event + */ +static void power_on_evt_handler(void) +{ + pr_info("pwr on event1 is received \n"); +} + +static int mc13892_regulator_init(struct mc13892 *mc13892) +{ + unsigned int value; + pmic_event_callback_t power_key_event; + + if (mxc_cpu_is_rev(CHIP_REV_2_0) < 0) + sw2_init.constraints.state_mem.uV = 1100000; + + /* subscribe PWRON1 event to enable ON_OFF key */ + power_key_event.param = NULL; + power_key_event.func = (void *)power_on_evt_handler; + pmic_event_subscribe(EVENT_PWRONI, power_key_event); + + /* Bit 4 DRM: keep VSRTC and CLK32KMCU on for all states */ + pmic_read_reg(REG_POWER_CTL0, &value, 0xffffff); + value |= 0x000010; + pmic_write_reg(REG_POWER_CTL0, value, 0xffffff); + + mc13892_register_regulator(mc13892, MC13892_SW1, &sw1_init); + mc13892_register_regulator(mc13892, MC13892_SW2, &sw2_init); + mc13892_register_regulator(mc13892, MC13892_SW3, &sw3_init); + mc13892_register_regulator(mc13892, MC13892_SW4, &sw4_init); + mc13892_register_regulator(mc13892, MC13892_SWBST, &swbst_init); + mc13892_register_regulator(mc13892, MC13892_VIOHI, &viohi_init); + mc13892_register_regulator(mc13892, MC13892_VPLL, &vpll_init); + mc13892_register_regulator(mc13892, MC13892_VDIG, &vdig_init); + mc13892_register_regulator(mc13892, MC13892_VSD, &vsd_init); + mc13892_register_regulator(mc13892, MC13892_VUSB2, &vusb2_init); + mc13892_register_regulator(mc13892, MC13892_VVIDEO, &vvideo_init); + mc13892_register_regulator(mc13892, MC13892_VAUDIO, &vaudio_init); + mc13892_register_regulator(mc13892, MC13892_VCAM, &vcam_init); + mc13892_register_regulator(mc13892, MC13892_VGEN1, &vgen1_init); + mc13892_register_regulator(mc13892, MC13892_VGEN2, &vgen2_init); + mc13892_register_regulator(mc13892, MC13892_VGEN3, &vgen3_init); + mc13892_register_regulator(mc13892, MC13892_VUSB, &vusb_init); + + return 0; +} + +static struct mc13892_platform_data mc13892_plat = { + .init = mc13892_regulator_init, +}; + +static struct i2c_board_info __initdata mc13892_i2c_device = { + I2C_BOARD_INFO("mc13892", 0x08), + .irq = IOMUX_TO_IRQ(MX51_PIN_GPIO1_5), + .platform_data = &mc13892_plat, +}; + +int __init mx51_3stack_init_mc13892(void) +{ + return i2c_register_board_info(1, &mc13892_i2c_device, 1); +} + --- linux-2.6.28.orig/arch/arm/mach-mx51/pm.c +++ linux-2.6.28/arch/arm/mach-mx51/pm.c @@ -0,0 +1,147 @@ +/* + * Copyright 2008-2009 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 + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "crm_regs.h" + +static struct device *pm_dev; +struct clk *gpc_dvfs_clk; +extern void cpu_do_suspend_workaround(void); +extern void cpu_cortexa8_do_idle(u32); + +extern int iram_ready; + +static int mx51_suspend_enter(suspend_state_t state) +{ + if (tzic_enable_wake(0) != 0) + return -EAGAIN; + + if (gpc_dvfs_clk == NULL) + gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs_clk"); + /* gpc clock is needed for SRPG */ + clk_enable(gpc_dvfs_clk); + switch (state) { + case PM_SUSPEND_MEM: + mxc_cpu_lp_set(STOP_POWER_OFF); + break; + case PM_SUSPEND_STANDBY: + mxc_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); + break; + default: + return -EINVAL; + } + if (state == PM_SUSPEND_MEM) { + cpu_do_suspend_workaround(); + /*clear the EMPGC0/1 bits */ + __raw_writel(0, MXC_SRPG_EMPGC0_SRPGCR); + __raw_writel(0, MXC_SRPG_EMPGC1_SRPGCR); + } else { + if ((mxc_cpu_is_rev(CHIP_REV_2_0)) < 0) { + /* do cpu_idle_workaround */ + u32 l2_iram_addr = IDLE_IRAM_BASE_ADDR; + if (!iram_ready) + return 0; + if (l2_iram_addr > 0x1FFE8000) + cpu_cortexa8_do_idle(IO_ADDRESS(l2_iram_addr)); + } else { + cpu_do_idle(); + } + } + clk_disable(gpc_dvfs_clk); + + return 0; +} + +/* + * Called after processes are frozen, but before we shut down devices. + */ +static int mx51_suspend_prepare(void) +{ + return 0; +} + +/* + * Called before devices are re-setup. + */ +static void mx51_suspend_finish(void) +{ +} + +/* + * Called after devices are re-setup, but before processes are thawed. + */ +static void mx51_suspend_end(void) +{ +} + +static int mx51_pm_valid(suspend_state_t state) +{ + return (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX); +} + +struct platform_suspend_ops mx51_suspend_ops = { + .valid = mx51_pm_valid, + .prepare = mx51_suspend_prepare, + .enter = mx51_suspend_enter, + .finish = mx51_suspend_finish, + .end = mx51_suspend_end, +}; + + +static int __devinit mx51_pm_probe(struct platform_device *pdev) +{ + pm_dev = &pdev->dev; + return 0; +} + +static struct platform_driver mx51_pm_driver = { + .driver = { + .name = "mx51_pm", + }, + .probe = mx51_pm_probe, +}; + +static int __init pm_init(void) +{ + pr_info("Static Power Management for Freescale i.MX51\n"); + if (platform_driver_register(&mx51_pm_driver) != 0) { + printk(KERN_ERR "mx51_pm_driver register failed\n"); + return -ENODEV; + } + suspend_set_ops(&mx51_suspend_ops); + + printk(KERN_INFO "PM driver module loaded\n"); + + return 0; +} + + +static void __exit pm_cleanup(void) +{ + /* Unregister the device structure */ + platform_driver_unregister(&mx51_pm_driver); +} + +module_init(pm_init); +module_exit(pm_cleanup); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("PM driver"); +MODULE_LICENSE("GPL"); + --- linux-2.6.28.orig/arch/arm/mach-mx51/lpmodes.c +++ linux-2.6.28/arch/arm/mach-mx51/lpmodes.c @@ -0,0 +1,205 @@ +/* + * Copyright 2008-2009 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 + */ + +/*! + * @file mx51_lpmodes.c + * + * @brief Driver for the Freescale Semiconductor MXC low power modes setup. + * + * MX51 is designed to play and video with minimal power consumption. + * This driver enables the platform to enter and exit audio and video low + * power modes. + * + * @ingroup PM + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "crm_regs.h" + +#define ARM_LP_CLK 200000000 +#define GP_LPM_VOLTAGE 775000 +#define GP_NORMAL_VOLTAGE 1050000 + +static int org_cpu_rate; +int lp_video_mode; +int lp_audio_mode; +static struct device *lpmode_dev; +struct regulator *gp_core; + +void enter_lp_video_mode(void) +{ +} + +void exit_lp_video_mode(void) +{ +} + +void enter_lp_audio_mode(void) +{ + struct clk *tclk; + int ret; + + tclk = clk_get(NULL, "cpu_clk"); + org_cpu_rate = clk_get_rate(tclk); + + ret = clk_set_rate(tclk, ARM_LP_CLK); + if (ret != 0) + printk(KERN_DEBUG "cannot set CPU clock rate\n"); + clk_put(tclk); + + /* Set the voltage to 0.775v for the GP domain. */ + ret = regulator_set_voltage(gp_core, GP_LPM_VOLTAGE, GP_LPM_VOLTAGE); + if (ret < 0) + printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE!!!\n"); + + lp_audio_mode = 1; +} + +void exit_lp_audio_mode(void) +{ + struct clk *tclk; + int ret; + + /* Set the voltage to 1.05v for the GP domain. */ + ret = regulator_set_voltage(gp_core, + GP_NORMAL_VOLTAGE, GP_NORMAL_VOLTAGE); + if (ret < 0) + printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE!!!\n"); + + tclk = clk_get(NULL, "cpu_clk"); + ret = clk_set_rate(tclk, org_cpu_rate); + if (ret != 0) + printk(KERN_DEBUG "cannot set CPU clock rate\n"); + clk_put(tclk); + + lp_audio_mode = 0; + +} + +static ssize_t lp_curr_mode(struct device *dev, + struct device_attribute *attr, char *buf) +{ + if (lp_video_mode) + return sprintf(buf, "in lp_video_mode\n"); + else if (lp_audio_mode) + return sprintf(buf, "in lp_audio_mode\n"); + else + return sprintf(buf, "in normal mode\n"); +} + +static ssize_t set_lp_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + printk(KERN_DEBUG "In set_lp_mode() \n"); + + if (strstr(buf, "enable_lp_video") != NULL) { + if (!lp_video_mode) + enter_lp_video_mode(); + } else if (strstr(buf, "disable_lp_video") != NULL) { + if (lp_video_mode) + exit_lp_video_mode(); + } else if (strstr(buf, "enable_lp_audio") != NULL) { + if (!lp_audio_mode) + enter_lp_audio_mode(); + } else if (strstr(buf, "disable_lp_audio") != NULL) { + if (lp_audio_mode) + exit_lp_audio_mode(); + } + return size; +} + +static DEVICE_ATTR(lp_modes, 0644, lp_curr_mode, set_lp_mode); + +/*! + * This is the probe routine for the lp_mode driver. + * + * @param pdev The platform device structure + * + * @return The function returns 0 on success + * + */ +static int __devinit mx51_lpmode_probe(struct platform_device *pdev) +{ + u32 res = 0; + lpmode_dev = &pdev->dev; + + res = sysfs_create_file(&lpmode_dev->kobj, &dev_attr_lp_modes.attr); + if (res) { + printk(KERN_ERR + "lpmode_dev: Unable to register sysdev entry for lpmode_dev"); + return res; + } + + if (res != 0) { + printk(KERN_ERR "lpmode_dev: Unable to start"); + return res; + } + gp_core = regulator_get(NULL, "SW1"); + lp_video_mode = 0; + lp_audio_mode = 0; + + return 0; +} + +static struct platform_driver mx51_lpmode_driver = { + .driver = { + .name = "mx51_lpmode", + }, + .probe = mx51_lpmode_probe, +}; + +/*! + * Initialise the mx51_lpmode_driver. + * + * @return The function always returns 0. + */ + +static int __init lpmode_init(void) +{ + if (platform_driver_register(&mx51_lpmode_driver) != 0) { + printk(KERN_ERR "mx37_lpmode_driver register failed\n"); + return -ENODEV; + } + + printk(KERN_INFO "LPMode driver module loaded\n"); + return 0; +} + +static void __exit lpmode_cleanup(void) +{ + sysfs_remove_file(&lpmode_dev->kobj, &dev_attr_lp_modes.attr); + + /* Unregister the device structure */ + platform_driver_unregister(&mx51_lpmode_driver); +} + +module_init(lpmode_init); +module_exit(lpmode_cleanup); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("LPMode driver"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/arch/arm/mach-mx51/serial.c +++ linux-2.6.28/arch/arm/mach-mx51/serial.c @@ -0,0 +1,169 @@ +/* + * Copyright 2008-2009 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 + */ +/*! + * @file mach-mx51/serial.c + * + * @brief This file contains the UART initiliazation. + * + * @ingroup MSL_MX51 + */ +#include +#include +#include +#include +#include +#include +#include "serial.h" +#include "board-mx51_3stack.h" + +#if defined(CONFIG_SERIAL_MXC) || defined(CONFIG_SERIAL_MXC_MODULE) + +/*! + * This is an array where each element holds information about a UART port, + * like base address of the UART, interrupt numbers etc. This structure is + * passed to the serial_core.c file. Based on which UART is used, the core file + * passes back the appropriate port structure as an argument to the control + * functions. + */ +static uart_mxc_port mxc_ports[] = { + [0] = { + .port = { + .membase = (void *)IO_ADDRESS(UART1_BASE_ADDR), + .mapbase = UART1_BASE_ADDR, + .iotype = SERIAL_IO_MEM, + .irq = UART1_INT1, + .fifosize = 32, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 0, + }, + .ints_muxed = UART1_MUX_INTS, + .irqs = {UART1_INT2, UART1_INT3}, + .mode = UART1_MODE, + .ir_mode = UART1_IR, + .enabled = UART1_ENABLED, + .hardware_flow = UART1_HW_FLOW, + .cts_threshold = UART1_UCR4_CTSTL, + .dma_enabled = UART1_DMA_ENABLE, + .dma_rxbuf_size = UART1_DMA_RXBUFSIZE, + .rx_threshold = UART1_UFCR_RXTL, + .tx_threshold = UART1_UFCR_TXTL, + .shared = UART1_SHARED_PERI, + .dma_tx_id = MXC_DMA_UART1_TX, + .dma_rx_id = MXC_DMA_UART1_RX, + .rxd_mux = MXC_UART_RXDMUX, + }, + [1] = { + .port = { + .membase = (void *)IO_ADDRESS(UART2_BASE_ADDR), + .mapbase = UART2_BASE_ADDR, + .iotype = SERIAL_IO_MEM, + .irq = UART2_INT1, + .fifosize = 32, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 1, + }, + .ints_muxed = UART2_MUX_INTS, + .irqs = {UART2_INT2, UART2_INT3}, + .mode = UART2_MODE, + .ir_mode = UART2_IR, + .enabled = UART2_ENABLED, + .hardware_flow = UART2_HW_FLOW, + .cts_threshold = UART2_UCR4_CTSTL, + .dma_enabled = UART2_DMA_ENABLE, + .dma_rxbuf_size = UART2_DMA_RXBUFSIZE, + .rx_threshold = UART2_UFCR_RXTL, + .tx_threshold = UART2_UFCR_TXTL, + .shared = UART2_SHARED_PERI, + .dma_tx_id = MXC_DMA_UART2_TX, + .dma_rx_id = MXC_DMA_UART2_RX, + .rxd_mux = MXC_UART_RXDMUX, + }, + [2] = { + .port = { + .membase = (void *)IO_ADDRESS(UART3_BASE_ADDR), + .mapbase = UART3_BASE_ADDR, + .iotype = SERIAL_IO_MEM, + .irq = UART3_INT1, + .fifosize = 32, + .flags = ASYNC_BOOT_AUTOCONF, + .line = 2, + }, + .ints_muxed = UART3_MUX_INTS, + .irqs = {UART3_INT2, UART3_INT3}, + .mode = UART3_MODE, + .ir_mode = UART3_IR, + .enabled = UART3_ENABLED, + .hardware_flow = UART3_HW_FLOW, + .cts_threshold = UART3_UCR4_CTSTL, + .dma_enabled = UART3_DMA_ENABLE, + .dma_rxbuf_size = UART3_DMA_RXBUFSIZE, + .rx_threshold = UART3_UFCR_RXTL, + .tx_threshold = UART3_UFCR_TXTL, + .shared = UART3_SHARED_PERI, + .dma_tx_id = MXC_DMA_UART3_TX, + .dma_rx_id = MXC_DMA_UART3_RX, + .rxd_mux = MXC_UART_RXDMUX, + }, +}; + +static struct platform_device mxc_uart_device1 = { + .name = "mxcintuart", + .id = 0, + .dev = { + .platform_data = &mxc_ports[0], + }, +}; + +static struct platform_device mxc_uart_device2 = { + .name = "mxcintuart", + .id = 1, + .dev = { + .platform_data = &mxc_ports[1], + }, +}; + +static struct platform_device mxc_uart_device3 = { + .name = "mxcintuart", + .id = 2, + .dev = { + .platform_data = &mxc_ports[2], + }, +}; + +static int __init mxc_init_uart(void) +{ + /* Register all the MXC UART platform device structures */ + platform_device_register(&mxc_uart_device1); + platform_device_register(&mxc_uart_device2); + + /* Grab ownership of shared UARTs 3 and 4, only when enabled */ +#if UART3_ENABLED == 1 +#if UART3_DMA_ENABLE == 1 + spba_take_ownership(UART3_SHARED_PERI, (SPBA_MASTER_A | SPBA_MASTER_C)); +#else + spba_take_ownership(UART3_SHARED_PERI, SPBA_MASTER_A); +#endif /* UART3_DMA_ENABLE */ + platform_device_register(&mxc_uart_device3); +#endif /* UART3_ENABLED */ + + return 0; +} + +#else +static int __init mxc_init_uart(void) +{ + return 0; +} +#endif + +arch_initcall(mxc_init_uart); --- linux-2.6.28.orig/arch/arm/mach-mx51/mx51_3stack_gpio.c +++ linux-2.6.28/arch/arm/mach-mx51/mx51_3stack_gpio.c @@ -0,0 +1,507 @@ +/* + * Copyright 2008-2009 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iomux.h" + +/*! + * @file mach-mx51/mx51_3stack_gpio.c + * + * @brief This file contains all the GPIO setup functions for the board. + * + * @ingroup GPIO + */ +#define ATA_PAD_CONFIG (PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH) + +static struct mxc_iomux_pin_cfg __initdata mxc_iomux_pins[] = { + /* CSI0 */ + { + MX51_PIN_CSI1_D8, IOMUX_CONFIG_ALT3, + PAD_CTL_PKE_ENABLE, + MUX_IN_GPIO3_IPP_IND_G_IN_12_SELECT_INPUT, + INPUT_CTL_PATH1, + }, + { + MX51_PIN_CSI1_D9, IOMUX_CONFIG_ALT3, + PAD_CTL_PKE_ENABLE, + }, + { + MX51_PIN_CSI1_D10, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI1_D11, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI1_D12, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI1_D13, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI1_D14, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI1_D15, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI1_D16, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI1_D17, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI1_D18, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI1_D19, IOMUX_CONFIG_ALT0, PAD_CTL_HYS_NONE, + }, + { + MX51_PIN_CSI1_VSYNC, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_NONE | PAD_CTL_SRE_SLOW), + }, + { + MX51_PIN_CSI1_HSYNC, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_NONE | PAD_CTL_SRE_SLOW), + }, + { + MX51_PIN_EIM_A26, IOMUX_CONFIG_ALT5 | IOMUX_CONFIG_SION, + (PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU | PAD_CTL_PUE_PULL), + MUX_IN_HSC_MIPI_MIX_IPP_IND_SENS2_DATA_EN_SELECT_INPUT, + INPUT_CTL_PATH0, + }, + { /* SPI1 */ + MX51_PIN_CSPI1_MISO, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | + PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_CSPI1_MOSI, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | + PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_CSPI1_RDY, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | + PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_CSPI1_SCLK, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | + PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_CSPI1_SS0, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | + PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_CSPI1_SS1, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH | + PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_OWIRE_LINE, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | + PAD_CTL_ODE_OPENDRAIN_ENABLE | PAD_CTL_DRV_HIGH | + PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_DISP2_DAT15, IOMUX_CONFIG_ALT5, + }, + { + MX51_PIN_DI_GP2, IOMUX_CONFIG_ALT0, + }, + { + MX51_PIN_DI_GP3, IOMUX_CONFIG_ALT0, + }, + { + MX51_PIN_KEY_COL0, IOMUX_CONFIG_ALT0, + }, + { + MX51_PIN_KEY_COL1, IOMUX_CONFIG_ALT0, + }, + { + MX51_PIN_KEY_COL2, IOMUX_CONFIG_ALT0, + }, + { + MX51_PIN_KEY_COL3, IOMUX_CONFIG_ALT0, + }, + { + MX51_PIN_KEY_COL4, IOMUX_CONFIG_ALT0, + }, + { + MX51_PIN_KEY_COL5, IOMUX_CONFIG_ALT0, + }, + { + MX51_PIN_KEY_ROW0, IOMUX_CONFIG_ALT0, + }, + { + MX51_PIN_KEY_ROW1, IOMUX_CONFIG_ALT0, + }, + { + MX51_PIN_KEY_ROW2, IOMUX_CONFIG_ALT0, + }, + { + MX51_PIN_KEY_ROW3, IOMUX_CONFIG_ALT0, + }, + { /* AUD3_TXD */ + MX51_PIN_AUD3_BB_TXD, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | + PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_100K_PU | + PAD_CTL_HYS_NONE | PAD_CTL_DDR_INPUT_CMOS | PAD_CTL_DRV_VOT_LOW), + }, + { /* AUD3_RXD */ + MX51_PIN_AUD3_BB_RXD, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | + PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_100K_PU | + PAD_CTL_HYS_NONE | PAD_CTL_DDR_INPUT_CMOS | PAD_CTL_DRV_VOT_LOW), + }, + { /* AUD3_CLK */ + MX51_PIN_AUD3_BB_CK, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | + PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_100K_PU | + PAD_CTL_HYS_NONE | PAD_CTL_DDR_INPUT_CMOS | PAD_CTL_DRV_VOT_LOW), + }, + { /* AUD3_FS */ + MX51_PIN_AUD3_BB_FS, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | + PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_100K_PU | + PAD_CTL_HYS_NONE | PAD_CTL_DDR_INPUT_CMOS | PAD_CTL_DRV_VOT_LOW), + }, + { + MX51_PIN_EIM_D16, IOMUX_CONFIG_ALT1, + (PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_EIM_A27, IOMUX_CONFIG_ALT2, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { + MX51_PIN_EIM_EB2, IOMUX_CONFIG_ALT1, + PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | PAD_CTL_100K_PD, + }, + { + MX51_PIN_EIM_DTACK, IOMUX_CONFIG_GPIO, + (PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU), + }, + { + MX51_PIN_EIM_CRE, IOMUX_CONFIG_GPIO, + }, + { + MX51_PIN_NANDF_CS0, IOMUX_CONFIG_ALT0, + }, + { + MX51_PIN_NANDF_CS1, IOMUX_CONFIG_ALT0, + }, + { + MX51_PIN_NANDF_CS2, IOMUX_CONFIG_ALT0, + }, + { + MX51_PIN_NANDF_CS3, IOMUX_CONFIG_ALT0, + }, + { + MX51_PIN_NANDF_CS4, IOMUX_CONFIG_ALT0, + }, + { + MX51_PIN_NANDF_CS5, IOMUX_CONFIG_ALT0, + }, + { + MX51_PIN_NANDF_CS6, IOMUX_CONFIG_ALT0, + }, + { + MX51_PIN_NANDF_CS7, IOMUX_CONFIG_ALT0, + }, + { /* TO2 */ + MX51_PIN_GPIO_NAND, IOMUX_CONFIG_ALT0, + }, + { /* TO1 */ + MX51_PIN_NANDF_RB5, IOMUX_CONFIG_ALT0, + }, + { + MX51_PIN_DI_GP4, IOMUX_CONFIG_ALT2, + }, + { + MX51_PIN_DISPB2_SER_DIN, IOMUX_CONFIG_GPIO, + 0, + MUX_IN_GPIO3_IPP_IND_G_IN_5_SELECT_INPUT, + INPUT_CTL_PATH1, + }, + { + MX51_PIN_DISPB2_SER_RS, IOMUX_CONFIG_GPIO, + }, + { /* TO2 */ + MX51_PIN_DI1_D1_CS, IOMUX_CONFIG_ALT4, + }, + { /* TO2 */ + MX51_PIN_DI1_D0_CS, IOMUX_CONFIG_ALT1, + }, + { /* TO2 */ + MX51_PIN_DI1_PIN11, IOMUX_CONFIG_ALT1, + }, + { /* TO2 */ + MX51_PIN_DI1_PIN12, IOMUX_CONFIG_ALT1, + }, + { /* TO2 */ + MX51_PIN_DI1_PIN13, IOMUX_CONFIG_ALT1, + }, + { + MX51_PIN_I2C1_CLK, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + 0x1E4, + }, + { + MX51_PIN_I2C1_DAT, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + 0x1E4, + }, + { + MX51_PIN_GPIO1_6, IOMUX_CONFIG_GPIO, + }, + { + MX51_PIN_GPIO1_7, IOMUX_CONFIG_ALT2, + (PAD_CTL_DRV_HIGH | PAD_CTL_PUE_PULL | + PAD_CTL_100K_PU | PAD_CTL_PKE_ENABLE | + PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_GPIO1_2, IOMUX_CONFIG_ALT2 | IOMUX_CONFIG_SION, + (PAD_CTL_SRE_FAST | PAD_CTL_ODE_OPENDRAIN_ENABLE | PAD_CTL_DRV_HIGH | + PAD_CTL_100K_PU | PAD_CTL_HYS_ENABLE), + MUX_IN_I2C2_IPP_SCL_IN_SELECT_INPUT, INPUT_CTL_PATH3, + }, + { + MX51_PIN_GPIO1_3, IOMUX_CONFIG_ALT2 | IOMUX_CONFIG_SION, + (PAD_CTL_SRE_FAST | PAD_CTL_ODE_OPENDRAIN_ENABLE | PAD_CTL_DRV_HIGH | + PAD_CTL_100K_PU | PAD_CTL_HYS_ENABLE), + MUX_IN_I2C2_IPP_SDA_IN_SELECT_INPUT, INPUT_CTL_PATH3, + }, + { + MX51_PIN_USBH1_STP, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_PUE_KEEPER | + PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* USBH1_CLK */ + MX51_PIN_USBH1_CLK, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_PUE_KEEPER | + PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE | PAD_CTL_DDR_INPUT_CMOS), + }, + { /* USBH1_DIR */ + MX51_PIN_USBH1_DIR, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_PUE_KEEPER | + PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE | PAD_CTL_DDR_INPUT_CMOS), + }, + { /* USBH1_NXT */ + MX51_PIN_USBH1_NXT, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_PUE_KEEPER | + PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE | PAD_CTL_DDR_INPUT_CMOS), + }, + { /* USBH1_DATA0 */ + MX51_PIN_USBH1_DATA0, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* USBH1_DATA1 */ + MX51_PIN_USBH1_DATA1, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* USBH1_DATA2 */ + MX51_PIN_USBH1_DATA2, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* USBH1_DATA3 */ + MX51_PIN_USBH1_DATA3, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* USBH1_DATA4 */ + MX51_PIN_USBH1_DATA4, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* USBH1_DATA5 */ + MX51_PIN_USBH1_DATA5, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* USBH1_DATA6 */ + MX51_PIN_USBH1_DATA6, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* USBH1_DATA7 */ + MX51_PIN_USBH1_DATA7, IOMUX_CONFIG_ALT0, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE), + }, + { /* USB1_OC */ + MX51_PIN_GPIO1_9, IOMUX_CONFIG_ALT1, + (PAD_CTL_SRE_SLOW | PAD_CTL_DRV_LOW | PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | + PAD_CTL_HYS_ENABLE), + }, + { /* USB1_PWR */ + MX51_PIN_GPIO1_8, IOMUX_CONFIG_ALT1, + (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_PKE_NONE | PAD_CTL_HYS_ENABLE), + }, + { + MX51_PIN_SD1_CMD, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_SD1_CLK, IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION, + (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_SD1_DATA0, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_SD1_DATA1, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_SD1_DATA2, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_SD1_DATA3, IOMUX_CONFIG_ALT0, + (PAD_CTL_DRV_MAX | PAD_CTL_22K_PU | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_GPIO1_0, IOMUX_CONFIG_GPIO | IOMUX_CONFIG_SION, + (PAD_CTL_HYS_ENABLE | PAD_CTL_100K_PU), + }, + { + MX51_PIN_GPIO1_1, IOMUX_CONFIG_GPIO | IOMUX_CONFIG_SION, + (PAD_CTL_HYS_ENABLE | PAD_CTL_100K_PU), + }, + { + MX51_PIN_UART1_RXD, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST), + MUX_IN_UART1_IPP_UART_RXD_MUX_SELECT_INPUT, + INPUT_CTL_PATH0, + }, + { + MX51_PIN_UART1_TXD, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_UART1_RTS, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_DRV_HIGH), + MUX_IN_UART1_IPP_UART_RTS_B_SELECT_INPUT, + INPUT_CTL_PATH0, + }, + { + MX51_PIN_UART1_CTS, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_DRV_HIGH), + }, + { + MX51_PIN_UART2_RXD, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_NONE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST), + MUX_IN_UART2_IPP_UART_RXD_MUX_SELECT_INPUT, + INPUT_CTL_PATH2, + }, + { + MX51_PIN_UART2_TXD, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_NONE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL | + PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_EIM_D26, IOMUX_CONFIG_ALT4, + (PAD_CTL_HYS_NONE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER | + PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST), + MUX_IN_UART2_IPP_UART_RTS_B_SELECT_INPUT, + INPUT_CTL_PATH3, + }, + { + MX51_PIN_EIM_D25, IOMUX_CONFIG_ALT4, + (PAD_CTL_HYS_NONE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER | + PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_UART3_RXD, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_NONE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER | + PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST), + MUX_IN_UART3_IPP_UART_RXD_MUX_SELECT_INPUT, + INPUT_CTL_PATH0, + }, + { + MX51_PIN_UART3_TXD, IOMUX_CONFIG_ALT0, + (PAD_CTL_HYS_NONE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER | + PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST), + }, + { + MX51_PIN_EIM_D27, IOMUX_CONFIG_ALT3, + (PAD_CTL_HYS_NONE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER | + PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST), + MUX_IN_UART3_IPP_UART_RTS_B_SELECT_INPUT, + INPUT_CTL_PATH2, + }, + { + MX51_PIN_EIM_D24, IOMUX_CONFIG_ALT3, + (PAD_CTL_HYS_NONE | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER | + PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST), + }, +}; + +void __init mx51_3stack_io_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(mxc_iomux_pins); i++) { + mxc_request_iomux(mxc_iomux_pins[i].pin, + mxc_iomux_pins[i].mux_mode); + if (mxc_iomux_pins[i].pad_cfg) + mxc_iomux_set_pad(mxc_iomux_pins[i].pin, + mxc_iomux_pins[i].pad_cfg); + if (mxc_iomux_pins[i].in_select) + mxc_iomux_set_input(mxc_iomux_pins[i].in_select, + mxc_iomux_pins[i].in_mode); + } + + /* Camera low power */ + mxc_set_gpio_direction(MX51_PIN_CSI1_D8, 0); + mxc_set_gpio_dataout(MX51_PIN_CSI1_D8, 0); + mxc_set_gpio_direction(MX51_PIN_EIM_EB2, 0); /* TO1 */ + mxc_set_gpio_dataout(MX51_PIN_EIM_EB2, 0); /* TO1 */ + + /* Camera reset */ + mxc_set_gpio_direction(MX51_PIN_CSI1_D9, 0); + mxc_set_gpio_dataout(MX51_PIN_CSI1_D9, 1); + mxc_set_gpio_direction(MX51_PIN_DI1_D1_CS, 0); + + mxc_set_gpio_direction(MX51_PIN_GPIO1_0, 1); /* SD1 CD */ + mxc_set_gpio_direction(MX51_PIN_GPIO1_1, 1); /* SD1 WP */ + + /* EIM_D16 */ + /* osc_en is shared by SPDIF */ + mxc_set_gpio_direction(MX51_PIN_EIM_D16, 0); + mxc_set_gpio_dataout(MX51_PIN_EIM_D16, 1); +} + --- linux-2.6.28.orig/arch/arm/mach-mx51/dummy_gpio.c +++ linux-2.6.28/arch/arm/mach-mx51/dummy_gpio.c @@ -0,0 +1,108 @@ +/* + * Copyright 2007-2009 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 + */ + +#include +#include + +void gpio_uart_active(int port, int no_irda) {} +EXPORT_SYMBOL(gpio_uart_active); + +void gpio_uart_inactive(int port, int no_irda) {} +EXPORT_SYMBOL(gpio_uart_inactive); + +void config_uartdma_event(int port) {} +EXPORT_SYMBOL(config_uartdma_event); + +void gpio_spi_active(int cspi_mod) {} +EXPORT_SYMBOL(gpio_spi_active); + +void gpio_spi_inactive(int cspi_mod) {} +EXPORT_SYMBOL(gpio_spi_inactive); + +void gpio_owire_active(void) {} +EXPORT_SYMBOL(gpio_owire_active); + +void gpio_owire_inactive(void) {} +EXPORT_SYMBOL(gpio_owire_inactive); + +void gpio_i2c_active(int i2c_num) {} +EXPORT_SYMBOL(gpio_i2c_active); + +void gpio_i2c_inactive(int i2c_num) {} +EXPORT_SYMBOL(gpio_i2c_inactive); + +void gpio_i2c_hs_active(void) {} +EXPORT_SYMBOL(gpio_i2c_hs_active); + +void gpio_i2c_hs_inactive(void) {} +EXPORT_SYMBOL(gpio_i2c_hs_inactive); + +void gpio_pmic_active(void) {} +EXPORT_SYMBOL(gpio_pmic_active); + +void gpio_activate_audio_ports(void) {} +EXPORT_SYMBOL(gpio_activate_audio_ports); + +void gpio_sdhc_active(int module) {} +EXPORT_SYMBOL(gpio_sdhc_active); + +void gpio_sdhc_inactive(int module) {} +EXPORT_SYMBOL(gpio_sdhc_inactive); + +void gpio_sensor_select(int sensor) {} + +void gpio_sensor_active(unsigned int csi) {} +EXPORT_SYMBOL(gpio_sensor_active); + +void gpio_sensor_inactive(unsigned int csi) {} +EXPORT_SYMBOL(gpio_sensor_inactive); + +void gpio_ata_active(void) {} +EXPORT_SYMBOL(gpio_ata_active); + +void gpio_ata_inactive(void) {} +EXPORT_SYMBOL(gpio_ata_inactive); + +void gpio_nand_active(void) {} +EXPORT_SYMBOL(gpio_nand_active); + +void gpio_nand_inactive(void) {} +EXPORT_SYMBOL(gpio_nand_inactive); + +void gpio_keypad_active(void) {} +EXPORT_SYMBOL(gpio_keypad_active); + +void gpio_keypad_inactive(void) {} +EXPORT_SYMBOL(gpio_keypad_inactive); + +int gpio_usbotg_hs_active(void) +{ + return 0; +} +EXPORT_SYMBOL(gpio_usbotg_hs_active); + +void gpio_usbotg_hs_inactive(void) {} +EXPORT_SYMBOL(gpio_usbotg_hs_inactive); + +void gpio_fec_active(void) {} +EXPORT_SYMBOL(gpio_fec_active); + +void gpio_fec_inactive(void) {} +EXPORT_SYMBOL(gpio_fec_inactive); + +void gpio_spdif_active(void) {} +EXPORT_SYMBOL(gpio_spdif_active); + +void gpio_spdif_inactive(void) {} +EXPORT_SYMBOL(gpio_spdif_inactive); + --- linux-2.6.28.orig/arch/arm/mach-mx51/system.c +++ linux-2.6.28/arch/arm/mach-mx51/system.c @@ -0,0 +1,191 @@ +/* + * Copyright 2008-2009 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include "crm_regs.h" + +/*! + * @defgroup MSL_MX51 i.MX51 Machine Specific Layer (MSL) + */ + +/*! + * @file mach-mx51/system.c + * @brief This file contains idle and reset functions. + * + * @ingroup MSL_MX51 + */ + +extern int mxc_jtag_enabled; +extern int iram_ready; +static struct clk *gpc_dvfs_clk; + +extern void cpu_cortexa8_do_idle(u32 addr); + + +/* set cpu low power mode before WFI instruction */ +void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode) +{ + u32 plat_lpc, gpc_pgr, arm_srpgcr, ccm_clpcr; + u32 empgc0, empgc1; + int stop_mode = 0; + + /* always allow platform to issue a deep sleep mode request */ + plat_lpc = __raw_readl(MXC_CORTEXA8_PLAT_LPC) & + ~(MXC_CORTEXA8_PLAT_LPC_DSM); + ccm_clpcr = __raw_readl(MXC_CCM_CLPCR) & ~(MXC_CCM_CLPCR_LPM_MASK); + arm_srpgcr = __raw_readl(MXC_SRPG_ARM_SRPGCR) & ~(MXC_SRPGCR_PCR); + empgc0 = __raw_readl(MXC_SRPG_EMPGC0_SRPGCR) & ~(MXC_SRPGCR_PCR); + empgc1 = __raw_readl(MXC_SRPG_EMPGC1_SRPGCR) & ~(MXC_SRPGCR_PCR); + + gpc_pgr = __raw_readl(MXC_GPC_PGR) & ~(MXC_GPC_PGR_ARMPG_MASK); + + switch (mode) { + case WAIT_CLOCKED: + break; + case WAIT_UNCLOCKED: + ccm_clpcr |= (0x1 << MXC_CCM_CLPCR_LPM_OFFSET); + break; + case WAIT_UNCLOCKED_POWER_OFF: + case STOP_POWER_OFF: + plat_lpc |= MXC_CORTEXA8_PLAT_LPC_DSM + | MXC_CORTEXA8_PLAT_LPC_DBG_DSM; + if (mode == WAIT_UNCLOCKED_POWER_OFF) { + ccm_clpcr |= (0x1 << MXC_CCM_CLPCR_LPM_OFFSET); + ccm_clpcr &= ~MXC_CCM_CLPCR_VSTBY; + stop_mode = 0; + } else { + ccm_clpcr |= (0x2 << MXC_CCM_CLPCR_LPM_OFFSET); + ccm_clpcr |= (0x3 << MXC_CCM_CLPCR_STBY_COUNT_OFFSET); + ccm_clpcr |= MXC_CCM_CLPCR_VSTBY; + ccm_clpcr |= MXC_CCM_CLPCR_SBYOS; + stop_mode = 1; + } + + arm_srpgcr |= MXC_SRPGCR_PCR; + gpc_pgr |= (0x1 << MXC_GPC_PGR_ARMPG_OFFSET); + if (stop_mode) { + empgc0 |= MXC_SRPGCR_PCR; + empgc1 |= MXC_SRPGCR_PCR; + } + + if (tzic_enable_wake(1) != 0) + return; + break; + case STOP_POWER_ON: + ccm_clpcr |= (0x2 << MXC_CCM_CLPCR_LPM_OFFSET); + break; + default: + printk(KERN_WARNING "UNKNOWN cpu power mode: %d\n", mode); + return; + } + + __raw_writel(plat_lpc, MXC_CORTEXA8_PLAT_LPC); + __raw_writel(ccm_clpcr, MXC_CCM_CLPCR); + __raw_writel(gpc_pgr, MXC_GPC_PGR); + __raw_writel(arm_srpgcr, MXC_SRPG_ARM_SRPGCR); + __raw_writel(arm_srpgcr, MXC_SRPG_NEON_SRPGCR); + if (stop_mode) { + __raw_writel(empgc0, MXC_SRPG_EMPGC0_SRPGCR); + __raw_writel(empgc1, MXC_SRPG_EMPGC1_SRPGCR); + } +} + +void mxc_pg_enable(struct platform_device *pdev) +{ + if (pdev == NULL) + return; + + if (strcmp(pdev->name, "mxc_ipu") == 0) { + __raw_writel(MXC_PGCR_PCR, MXC_PGC_IPU_PGCR); + __raw_writel(MXC_PGSR_PSR, MXC_PGC_IPU_PGSR); + } else if (strcmp(pdev->name, "mxc_vpu") == 0) { + __raw_writel(MXC_PGCR_PCR, MXC_PGC_VPU_PGCR); + __raw_writel(MXC_PGSR_PSR, MXC_PGC_VPU_PGSR); + } +} + +EXPORT_SYMBOL(mxc_pg_enable); + +void mxc_pg_disable(struct platform_device *pdev) +{ + if (pdev == NULL) + return; + + if (strcmp(pdev->name, "mxc_ipu") == 0) { + __raw_writel(0x0, MXC_PGC_IPU_PGCR); + if (__raw_readl(MXC_PGC_IPU_PGSR) & MXC_PGSR_PSR) + dev_dbg(&pdev->dev, "power gating successful\n"); + __raw_writel(MXC_PGSR_PSR, MXC_PGC_IPU_PGSR); + } else if (strcmp(pdev->name, "mxc_vpu") == 0) { + __raw_writel(0x0, MXC_PGC_VPU_PGCR); + if (__raw_readl(MXC_PGC_VPU_PGSR) & MXC_PGSR_PSR) + dev_dbg(&pdev->dev, "power gating successful\n"); + __raw_writel(MXC_PGSR_PSR, MXC_PGC_VPU_PGSR); + } +} + +EXPORT_SYMBOL(mxc_pg_disable); + +/* To change the idle power mode, need to set arch_idle_mode to a different + * power mode as in enum mxc_cpu_pwr_mode. + * May allow dynamically changing the idle mode. + */ +static int arch_idle_mode = WAIT_UNCLOCKED_POWER_OFF; +/*! + * This function puts the CPU into idle mode. It is called by default_idle() + * in process.c file. + */ +void arch_idle(void) +{ + if (likely(!mxc_jtag_enabled)) { + if (gpc_dvfs_clk == NULL) + gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs_clk"); + /* gpc clock is needed for SRPG */ + clk_enable(gpc_dvfs_clk); + mxc_cpu_lp_set(arch_idle_mode); + if ((mxc_cpu_is_rev(CHIP_REV_2_0)) < 0) { + u32 l2_iram_addr = IDLE_IRAM_BASE_ADDR; + + if (!iram_ready) + return; + + if (l2_iram_addr > 0x1FFE8000) + cpu_cortexa8_do_idle(IO_ADDRESS(l2_iram_addr)); + } else { + cpu_do_idle(); + } + clk_disable(gpc_dvfs_clk); + } +} + +/* + * This function resets the system. It is called by machine_restart(). + * + * @param mode indicates different kinds of resets + */ +void arch_reset(char mode) +{ + /* Workaround to reset NFC_CONFIG3 register + * due to the chip warm reset does not reset it + */ + __raw_writel(0x20600, IO_ADDRESS(NFC_BASE_ADDR) + 0x28); + + /* Assert SRS signal */ + mxc_wd_reset(); +} --- linux-2.6.28.orig/arch/arm/mach-mx51/Makefile.boot +++ linux-2.6.28/arch/arm/mach-mx51/Makefile.boot @@ -0,0 +1,3 @@ + zreladdr-y := 0x90008000 +params_phys-y := 0x90000100 +initrd_phys-y := 0x90800000 --- linux-2.6.28.orig/arch/arm/mach-mx51/board-mx51_babbage.h +++ linux-2.6.28/arch/arm/mach-mx51/board-mx51_babbage.h @@ -0,0 +1,85 @@ +/* + * Copyright 2009 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_MX51_BABBAGE_H__ +#define __ASM_ARCH_MXC_BOARD_MX51_BABBAGE_H__ + +/*! + * @defgroup BRDCFG_MX51 Board Configuration Options + * @ingroup MSL_MX51 + */ + +/*! + * @file mach-mx51/board-mx51_babbage.h + * + * @brief This file contains all the board level configuration options. + * + * It currently hold the options defined for MX51 Babbage Platform. + * + * @ingroup BRDCFG_MX51 + */ + +/* + * Include Files + */ +#include + +/*! + * @name MXC UART board level configurations + */ +/*! @{ */ +/*! + * Specifies if the Irda transmit path is inverting + */ +#define MXC_IRDA_TX_INV 0 +/*! + * Specifies if the Irda receive path is inverting + */ +#define MXC_IRDA_RX_INV 0 + +/* UART 1 configuration */ +/*! + * This define specifies if the UART port is configured to be in DTE or + * DCE mode. There exists a define like this for each UART port. Valid + * values that can be used are \b MODE_DTE or \b MODE_DCE. + */ +#define UART1_MODE MODE_DCE +/*! + * This define specifies if the UART is to be used for IRDA. There exists a + * define like this for each UART port. Valid values that can be used are + * \b IRDA or \b NO_IRDA. + */ +#define UART1_IR NO_IRDA +/*! + * This define is used to enable or disable a particular UART port. If + * disabled, the UART will not be registered in the file system and the user + * will not be able to access it. There exists a define like this for each UART + * port. Specify a value of 1 to enable the UART and 0 to disable it. + */ +#define UART1_ENABLED 1 +/*! @} */ +/* UART 2 configuration */ +#define UART2_MODE MODE_DCE +#define UART2_IR IRDA +#define UART2_ENABLED 1 +/* UART 3 configuration */ +#define UART3_MODE MODE_DTE +#define UART3_IR NO_IRDA +#define UART3_ENABLED 1 + +#define MXC_LL_UART_PADDR UART1_BASE_ADDR +#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) + +extern int __init mx51_babbage_init_mc13892(void); + +#endif /* __ASM_ARCH_MXC_BOARD_MX51_BABBAGE_H__ */ --- linux-2.6.28.orig/arch/arm/mach-mx51/Makefile +++ linux-2.6.28/arch/arm/mach-mx51/Makefile @@ -0,0 +1,22 @@ +# +# Makefile for the linux kernel. +# + +# Object file lists. + + +obj-y := system.o iomux.o cpu.o mm.o clock.o devices.o serial.o dma.o lpmodes.o pm.o + +obj-y += dummy_gpio.o + +obj-$(CONFIG_CPU_V7) += wfi.o suspend.o +obj-$(CONFIG_MACH_MX51_3DS) += mx51_3stack.o mx51_3stack_gpio.o mx51_3stack_pmic_mc13892.o +obj-$(CONFIG_MACH_MX51_BABBAGE) += mx51_babbage.o mx51_babbage_gpio.o mx51_babbage_pmic_mc13892.o + +obj-$(CONFIG_USB_EHCI_ARC_H1) += usb_h1.o +obj-$(CONFIG_USB_EHCI_ARC_H2) += usb_h2.o + +ifneq ($(strip $(CONFIG_USB_GADGET_ARC) $(CONFIG_USB_EHCI_ARC_OTG)),) + obj-y += usb_dr.o +endif + --- linux-2.6.28.orig/arch/arm/mach-mx51/mx51_pins.h +++ linux-2.6.28/arch/arm/mach-mx51/mx51_pins.h @@ -0,0 +1,361 @@ +/* + * Copyright 2008-2009 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_MX51_PINS_H__ +#define __ASM_ARCH_MXC_MX51_PINS_H__ + +/*! + * @file arch-mxc/mx51_pins.h + * + * @brief MX51 I/O Pin List + * + * @ingroup GPIO_MX51 + */ + +#ifndef __ASSEMBLY__ + +/*! + * @name IOMUX/PAD Bit field definitions + */ + +/*! @{ */ + +/*! + * In order to identify pins more effectively, each mux-controlled pin's + * enumerated value is constructed in the following way: + * + * ------------------------------------------------------------------- + * 31-29 | 28 - 24 | 23 - 21 | 20 - 10| 9 - 0 + * ------------------------------------------------------------------- + * IO_P | IO_I | GPIO_I | PAD_I | MUX_I + * ------------------------------------------------------------------- + * + * Bit 0 to 9 contains MUX_I used to identify the register + * offset (0-based. base is IOMUX_module_base) defined in the Section + * "sw_pad_ctl & sw_mux_ctl details" of the IC Spec. The + * similar field definitions are used for the pad control register. + * For example, the MX51_PIN_ETM_D0 is defined in the enumeration: + * ( (0x28 - MUX_I_START) << MUX_I)|( (0x250 - PAD_I_START) << PAD_I) + * It means the mux control register is at register offset 0x28. The pad control + * register offset is: 0x250 and also occupy the least significant bits + * within the register. + */ + +/*! + * Starting bit position within each entry of \b iomux_pins to represent the + * MUX control register offset + */ +#define MUX_I 0 +/*! + * Starting bit position within each entry of \b iomux_pins to represent the + * PAD control register offset + */ +#define PAD_I 10 +/*! + * Starting bit position within each entry of \b iomux_pins to represent which + * mux mode is for GPIO (0-based) + */ +#define GPIO_I 21 + +#define NON_GPIO_PORT 0x7 +#define PIN_TO_MUX_MASK ((1 << (PAD_I - MUX_I)) - 1) +#define PIN_TO_PAD_MASK ((1 << (GPIO_I - PAD_I)) - 1) +#define PIN_TO_ALT_GPIO_MASK ((1 << (MUX_IO_I - GPIO_I)) - 1) + +#define NON_MUX_I PIN_TO_MUX_MASK +#define MUX_I_START 0x001C +#define PAD_I_START 0x3F0 +#define INPUT_CTL_START 0x8C4 +#define INPUT_CTL_START_TO1 0x928 +#define MUX_I_END (PAD_I_START - 4) + +#define _MXC_BUILD_PIN(gp, gi, ga, mi, pi) \ + (((gp) << MUX_IO_P) | ((gi) << MUX_IO_I) | \ + ((mi) << MUX_I) | \ + ((pi - PAD_I_START) << PAD_I) | \ + ((ga) << GPIO_I)) + +#define _MXC_BUILD_GPIO_PIN(gp, gi, ga, mi, pi) \ + _MXC_BUILD_PIN(gp, gi, ga, mi, pi) + +#define _MXC_BUILD_NON_GPIO_PIN(mi, pi) \ + _MXC_BUILD_PIN(NON_GPIO_PORT, 0, 0, mi, pi) + +#define PIN_TO_IOMUX_MUX(pin) ((pin >> MUX_I) & PIN_TO_MUX_MASK) +#define PIN_TO_IOMUX_PAD(pin) ((pin >> PAD_I) & PIN_TO_PAD_MASK) +#define PIN_TO_ALT_GPIO(pin) ((pin >> GPIO_I) & PIN_TO_ALT_GPIO_MASK) +#define PIN_TO_IOMUX_INDEX(pin) (PIN_TO_IOMUX_MUX(pin) >> 2) + +/*! @} End IOMUX/PAD Bit field definitions */ + +/*! + * This enumeration is constructed based on the Section + * "sw_pad_ctl & sw_mux_ctl details" of the MX51 IC Spec. Each enumerated + * value is constructed based on the rules described above. + */ +enum iomux_pins { + MX51_PIN_EIM_DA0 = _MXC_BUILD_NON_GPIO_PIN(0x1C, 0x7A8), + MX51_PIN_EIM_DA1 = _MXC_BUILD_NON_GPIO_PIN(0x20, 0x7A8), + MX51_PIN_EIM_DA2 = _MXC_BUILD_NON_GPIO_PIN(0x24, 0x7A8), + MX51_PIN_EIM_DA3 = _MXC_BUILD_NON_GPIO_PIN(0x28, 0x7A8), + MX51_PIN_EIM_DA4 = _MXC_BUILD_NON_GPIO_PIN(0x2C, 0x7AC), + MX51_PIN_EIM_DA5 = _MXC_BUILD_NON_GPIO_PIN(0x30, 0x7AC), + MX51_PIN_EIM_DA6 = _MXC_BUILD_NON_GPIO_PIN(0x34, 0x7AC), + MX51_PIN_EIM_DA7 = _MXC_BUILD_NON_GPIO_PIN(0x38, 0x7AC), + MX51_PIN_EIM_DA8 = _MXC_BUILD_NON_GPIO_PIN(0x3C, 0x7B0), + MX51_PIN_EIM_DA9 = _MXC_BUILD_NON_GPIO_PIN(0x40, 0x7B0), + MX51_PIN_EIM_DA10 = _MXC_BUILD_NON_GPIO_PIN(0x44, 0x7B0), + MX51_PIN_EIM_DA11 = _MXC_BUILD_NON_GPIO_PIN(0x48, 0x7B0), + MX51_PIN_EIM_DA12 = _MXC_BUILD_NON_GPIO_PIN(0x4C, 0x7BC), + MX51_PIN_EIM_DA13 = _MXC_BUILD_NON_GPIO_PIN(0x50, 0x7BC), + MX51_PIN_EIM_DA14 = _MXC_BUILD_NON_GPIO_PIN(0x54, 0x7BC), + MX51_PIN_EIM_DA15 = _MXC_BUILD_NON_GPIO_PIN(0x58, 0x7BC), + MX51_PIN_EIM_D16 = _MXC_BUILD_GPIO_PIN(1, 0, 1, 0x5C, 0x3F0), + MX51_PIN_EIM_D17 = _MXC_BUILD_GPIO_PIN(1, 1, 1, 0x60, 0x3F4), + MX51_PIN_EIM_D18 = _MXC_BUILD_GPIO_PIN(1, 2, 1, 0x64, 0x3F8), + MX51_PIN_EIM_D19 = _MXC_BUILD_GPIO_PIN(1, 3, 1, 0x68, 0x3FC), + MX51_PIN_EIM_D20 = _MXC_BUILD_GPIO_PIN(1, 4, 1, 0x6C, 0x400), + MX51_PIN_EIM_D21 = _MXC_BUILD_GPIO_PIN(1, 5, 1, 0x70, 0x404), + MX51_PIN_EIM_D22 = _MXC_BUILD_GPIO_PIN(1, 6, 1, 0x74, 0x408), + MX51_PIN_EIM_D23 = _MXC_BUILD_GPIO_PIN(1, 7, 1, 0x78, 0x40C), + MX51_PIN_EIM_D24 = _MXC_BUILD_GPIO_PIN(1, 8, 1, 0x7C, 0x410), + MX51_PIN_EIM_D25 = _MXC_BUILD_NON_GPIO_PIN(0x80, 0x414), + MX51_PIN_EIM_D26 = _MXC_BUILD_NON_GPIO_PIN(0x84, 0x418), + MX51_PIN_EIM_D27 = _MXC_BUILD_GPIO_PIN(1, 9, 1, 0x88, 0x41C), + MX51_PIN_EIM_D28 = _MXC_BUILD_NON_GPIO_PIN(0x8C, 0x420), + MX51_PIN_EIM_D29 = _MXC_BUILD_NON_GPIO_PIN(0x90, 0x424), + MX51_PIN_EIM_D30 = _MXC_BUILD_NON_GPIO_PIN(0x94, 0x428), + MX51_PIN_EIM_D31 = _MXC_BUILD_NON_GPIO_PIN(0x98, 0x42C), + MX51_PIN_EIM_A16 = _MXC_BUILD_GPIO_PIN(1, 10, 1, 0x9C, 0x430), + MX51_PIN_EIM_A17 = _MXC_BUILD_GPIO_PIN(1, 11, 1, 0xA0, 0x434), + MX51_PIN_EIM_A18 = _MXC_BUILD_GPIO_PIN(1, 12, 1, 0xA4, 0x438), + MX51_PIN_EIM_A19 = _MXC_BUILD_GPIO_PIN(1, 13, 1, 0xA8, 0x43C), + MX51_PIN_EIM_A20 = _MXC_BUILD_GPIO_PIN(1, 14, 1, 0xAC, 0x440), + MX51_PIN_EIM_A21 = _MXC_BUILD_GPIO_PIN(1, 15, 1, 0xB0, 0x444), + MX51_PIN_EIM_A22 = _MXC_BUILD_GPIO_PIN(1, 16, 1, 0xB4, 0x448), + MX51_PIN_EIM_A23 = _MXC_BUILD_GPIO_PIN(1, 17, 1, 0xB8, 0x44C), + MX51_PIN_EIM_A24 = _MXC_BUILD_GPIO_PIN(1, 18, 1, 0xBC, 0x450), + MX51_PIN_EIM_A25 = _MXC_BUILD_GPIO_PIN(1, 19, 1, 0xC0, 0x454), + MX51_PIN_EIM_A26 = _MXC_BUILD_GPIO_PIN(1, 20, 1, 0xC4, 0x458), + MX51_PIN_EIM_A27 = _MXC_BUILD_GPIO_PIN(1, 21, 1, 0xC8, 0x45C), + MX51_PIN_EIM_EB0 = _MXC_BUILD_NON_GPIO_PIN(0xCC, 0x460), + MX51_PIN_EIM_EB1 = _MXC_BUILD_NON_GPIO_PIN(0xD0, 0x464), + MX51_PIN_EIM_EB2 = _MXC_BUILD_GPIO_PIN(1, 22, 1, 0xD4, 0x468), + MX51_PIN_EIM_EB3 = _MXC_BUILD_GPIO_PIN(1, 23, 1, 0xD8, 0x46C), + MX51_PIN_EIM_OE = _MXC_BUILD_GPIO_PIN(1, 24, 1, 0xDC, 0x470), + MX51_PIN_EIM_CS0 = _MXC_BUILD_GPIO_PIN(1, 25, 1, 0xE0, 0x474), + MX51_PIN_EIM_CS1 = _MXC_BUILD_GPIO_PIN(1, 26, 1, 0xE4, 0x478), + MX51_PIN_EIM_CS2 = _MXC_BUILD_GPIO_PIN(1, 27, 1, 0xE8, 0x47C), + MX51_PIN_EIM_CS3 = _MXC_BUILD_GPIO_PIN(1, 28, 1, 0xEC, 0x480), + MX51_PIN_EIM_CS4 = _MXC_BUILD_GPIO_PIN(1, 29, 1, 0xF0, 0x484), + MX51_PIN_EIM_CS5 = _MXC_BUILD_GPIO_PIN(1, 30, 1, 0xF4, 0x488), + MX51_PIN_EIM_DTACK = _MXC_BUILD_GPIO_PIN(1, 31, 1, 0xF8, 0x48C), + MX51_PIN_EIM_LBA = _MXC_BUILD_GPIO_PIN(2, 1, 1, 0xFC, 0x494), + MX51_PIN_EIM_CRE = _MXC_BUILD_GPIO_PIN(2, 2, 1, 0x100, 0x4A0), + MX51_PIN_DRAM_CS1 = _MXC_BUILD_NON_GPIO_PIN(0x104, 0x4D0), + MX51_PIN_NANDF_WE_B = _MXC_BUILD_GPIO_PIN(2, 3, 3, 0x108, 0x4E4), + MX51_PIN_NANDF_RE_B = _MXC_BUILD_GPIO_PIN(2, 4, 3, 0x10C, 0x4E8), + MX51_PIN_NANDF_ALE = _MXC_BUILD_GPIO_PIN(2, 5, 3, 0x110, 0x4EC), + MX51_PIN_NANDF_CLE = _MXC_BUILD_GPIO_PIN(2, 6, 3, 0x114, 0x4F0), + MX51_PIN_NANDF_WP_B = _MXC_BUILD_GPIO_PIN(2, 7, 3, 0x118, 0x4F4), + MX51_PIN_NANDF_RB0 = _MXC_BUILD_GPIO_PIN(2, 8, 3, 0x11C, 0x4F8), + MX51_PIN_NANDF_RB1 = _MXC_BUILD_GPIO_PIN(2, 9, 3, 0x120, 0x4FC), + MX51_PIN_NANDF_RB2 = _MXC_BUILD_GPIO_PIN(2, 10, 3, 0x124, 0x500), + MX51_PIN_NANDF_RB3 = _MXC_BUILD_GPIO_PIN(2, 11, 3, 0x128, 0x504), + MX51_PIN_GPIO_NAND = _MXC_BUILD_GPIO_PIN(2, 12, 3, 0x12C, 0x514), + MX51_PIN_NANDF_RB4 = MX51_PIN_GPIO_NAND, + MX51_PIN_NANDF_RB5 = _MXC_BUILD_GPIO_PIN(2, 13, 3, 0x130, 0x5D8), + MX51_PIN_NANDF_RB6 = _MXC_BUILD_GPIO_PIN(2, 14, 3, 0x134, 0x5DC), + MX51_PIN_NANDF_RB7 = _MXC_BUILD_GPIO_PIN(2, 15, 3, 0x138, 0x5E0), + MX51_PIN_NANDF_CS0 = _MXC_BUILD_GPIO_PIN(2, 16, 3, 0x130, 0x518), + MX51_PIN_NANDF_CS1 = _MXC_BUILD_GPIO_PIN(2, 17, 3, 0x134, 0x51C), + MX51_PIN_NANDF_CS2 = _MXC_BUILD_GPIO_PIN(2, 18, 3, 0x138, 0x520), + MX51_PIN_NANDF_CS3 = _MXC_BUILD_GPIO_PIN(2, 19, 3, 0x13C, 0x524), + MX51_PIN_NANDF_CS4 = _MXC_BUILD_GPIO_PIN(2, 20, 3, 0x140, 0x528), + MX51_PIN_NANDF_CS5 = _MXC_BUILD_GPIO_PIN(2, 21, 3, 0x144, 0x52C), + MX51_PIN_NANDF_CS6 = _MXC_BUILD_GPIO_PIN(2, 22, 3, 0x148, 0x530), + MX51_PIN_NANDF_CS7 = _MXC_BUILD_GPIO_PIN(2, 23, 3, 0x14C, 0x534), + MX51_PIN_NANDF_RDY_INT = _MXC_BUILD_GPIO_PIN(2, 24, 3, 0x150, 0x538), + MX51_PIN_NANDF_D15 = _MXC_BUILD_GPIO_PIN(2, 25, 3, 0x154, 0x53C), + MX51_PIN_NANDF_D14 = _MXC_BUILD_GPIO_PIN(2, 26, 3, 0x158, 0x540), + MX51_PIN_NANDF_D13 = _MXC_BUILD_GPIO_PIN(2, 27, 3, 0x15C, 0x544), + MX51_PIN_NANDF_D12 = _MXC_BUILD_GPIO_PIN(2, 28, 3, 0x160, 0x548), + MX51_PIN_NANDF_D11 = _MXC_BUILD_GPIO_PIN(2, 29, 3, 0x164, 0x54C), + MX51_PIN_NANDF_D10 = _MXC_BUILD_GPIO_PIN(2, 30, 3, 0x168, 0x550), + MX51_PIN_NANDF_D9 = _MXC_BUILD_GPIO_PIN(2, 31, 3, 0x16C, 0x554), + MX51_PIN_NANDF_D8 = _MXC_BUILD_GPIO_PIN(3, 0, 3, 0x170, 0x558), + MX51_PIN_NANDF_D7 = _MXC_BUILD_GPIO_PIN(3, 1, 3, 0x174, 0x55C), + MX51_PIN_NANDF_D6 = _MXC_BUILD_GPIO_PIN(3, 2, 3, 0x178, 0x560), + MX51_PIN_NANDF_D5 = _MXC_BUILD_GPIO_PIN(3, 3, 3, 0x17C, 0x564), + MX51_PIN_NANDF_D4 = _MXC_BUILD_GPIO_PIN(3, 4, 3, 0x180, 0x568), + MX51_PIN_NANDF_D3 = _MXC_BUILD_GPIO_PIN(3, 5, 3, 0x184, 0x56C), + MX51_PIN_NANDF_D2 = _MXC_BUILD_GPIO_PIN(3, 6, 3, 0x188, 0x570), + MX51_PIN_NANDF_D1 = _MXC_BUILD_GPIO_PIN(3, 7, 3, 0x18C, 0x574), + MX51_PIN_NANDF_D0 = _MXC_BUILD_GPIO_PIN(3, 8, 3, 0x190, 0x578), + MX51_PIN_CSI1_D8 = _MXC_BUILD_GPIO_PIN(2, 12, 3, 0x194, 0x57C), + MX51_PIN_CSI1_D9 = _MXC_BUILD_GPIO_PIN(2, 13, 3, 0x198, 0x580), + MX51_PIN_CSI1_D10 = _MXC_BUILD_NON_GPIO_PIN(0x19C, 0x584), + MX51_PIN_CSI1_D11 = _MXC_BUILD_NON_GPIO_PIN(0x1A0, 0x588), + MX51_PIN_CSI1_D12 = _MXC_BUILD_NON_GPIO_PIN(0x1A4, 0x58C), + MX51_PIN_CSI1_D13 = _MXC_BUILD_NON_GPIO_PIN(0x1A8, 0x590), + MX51_PIN_CSI1_D14 = _MXC_BUILD_NON_GPIO_PIN(0x1AC, 0x594), + MX51_PIN_CSI1_D15 = _MXC_BUILD_NON_GPIO_PIN(0x1B0, 0x598), + MX51_PIN_CSI1_D16 = _MXC_BUILD_NON_GPIO_PIN(0x1B4, 0x59C), + MX51_PIN_CSI1_D17 = _MXC_BUILD_NON_GPIO_PIN(0x1B8, 0x5A0), + MX51_PIN_CSI1_D18 = _MXC_BUILD_NON_GPIO_PIN(0x1BC, 0x5A4), + MX51_PIN_CSI1_D19 = _MXC_BUILD_NON_GPIO_PIN(0x1C0, 0x5A8), + MX51_PIN_CSI1_VSYNC = _MXC_BUILD_NON_GPIO_PIN(0x1C4, 0x5AC), + MX51_PIN_CSI1_HSYNC = _MXC_BUILD_NON_GPIO_PIN(0x1C8, 0x5B0), + MX51_PIN_CSI1_PIXCLK = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x5B4), + MX51_PIN_CSI1_MCLK = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x5B8), + MX51_PIN_CSI1_PKE0 = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x860), + MX51_PIN_CSI2_D12 = _MXC_BUILD_GPIO_PIN(3, 9, 3, 0x1CC, 0x5BC), + MX51_PIN_CSI2_D13 = _MXC_BUILD_GPIO_PIN(3, 10, 3, 0x1D0, 0x5C0), + MX51_PIN_CSI2_D14 = _MXC_BUILD_GPIO_PIN(3, 11, 3, 0x1D4, 0x5C4), + MX51_PIN_CSI2_D15 = _MXC_BUILD_GPIO_PIN(3, 12, 3, 0x1D8, 0x5C8), + MX51_PIN_CSI2_D16 = _MXC_BUILD_GPIO_PIN(3, 11, 3, 0x1DC, 0x5CC), + MX51_PIN_CSI2_D17 = _MXC_BUILD_GPIO_PIN(3, 12, 3, 0x1E0, 0x5D0), + MX51_PIN_CSI2_D18 = _MXC_BUILD_GPIO_PIN(3, 11, 3, 0x1E4, 0x5D4), + MX51_PIN_CSI2_D19 = _MXC_BUILD_GPIO_PIN(3, 12, 3, 0x1E8, 0x5D8), + MX51_PIN_CSI2_VSYNC = _MXC_BUILD_GPIO_PIN(3, 13, 3, 0x1EC, 0x5DC), + MX51_PIN_CSI2_HSYNC = _MXC_BUILD_GPIO_PIN(3, 14, 3, 0x1F0, 0x5E0), + MX51_PIN_CSI2_PIXCLK = _MXC_BUILD_GPIO_PIN(3, 15, 3, 0x1F4, 0x5E4), + MX51_PIN_CSI2_PKE0 = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x81C), + MX51_PIN_I2C1_CLK = _MXC_BUILD_GPIO_PIN(3, 16, 3, 0x1F8, 0x5E8), + MX51_PIN_I2C1_DAT = _MXC_BUILD_GPIO_PIN(3, 17, 3, 0x1FC, 0x5EC), + MX51_PIN_AUD3_BB_TXD = _MXC_BUILD_GPIO_PIN(3, 18, 3, 0x200, 0x5F0), + MX51_PIN_AUD3_BB_RXD = _MXC_BUILD_GPIO_PIN(3, 19, 3, 0x204, 0x5F4), + MX51_PIN_AUD3_BB_CK = _MXC_BUILD_GPIO_PIN(3, 20, 3, 0x208, 0x5F8), + MX51_PIN_AUD3_BB_FS = _MXC_BUILD_GPIO_PIN(3, 21, 3, 0x20C, 0x5FC), + MX51_PIN_CSPI1_MOSI = _MXC_BUILD_GPIO_PIN(3, 22, 3, 0x210, 0x600), + MX51_PIN_CSPI1_MISO = _MXC_BUILD_GPIO_PIN(3, 23, 3, 0x214, 0x604), + MX51_PIN_CSPI1_SS0 = _MXC_BUILD_GPIO_PIN(3, 24, 3, 0x218, 0x608), + MX51_PIN_CSPI1_SS1 = _MXC_BUILD_GPIO_PIN(3, 25, 3, 0x21C, 0x60C), + MX51_PIN_CSPI1_RDY = _MXC_BUILD_GPIO_PIN(3, 26, 3, 0x220, 0x610), + MX51_PIN_CSPI1_SCLK = _MXC_BUILD_GPIO_PIN(3, 27, 3, 0x224, 0x614), + MX51_PIN_UART1_RXD = _MXC_BUILD_GPIO_PIN(3, 28, 3, 0x228, 0x618), + MX51_PIN_UART1_TXD = _MXC_BUILD_GPIO_PIN(3, 29, 3, 0x22C, 0x61C), + MX51_PIN_UART1_RTS = _MXC_BUILD_GPIO_PIN(3, 30, 3, 0x230, 0x620), + MX51_PIN_UART1_CTS = _MXC_BUILD_GPIO_PIN(3, 31, 3, 0x234, 0x624), + MX51_PIN_UART2_RXD = _MXC_BUILD_GPIO_PIN(0, 20, 3, 0x238, 0x628), + MX51_PIN_UART2_TXD = _MXC_BUILD_GPIO_PIN(0, 21, 3, 0x23C, 0x62C), + MX51_PIN_UART3_RXD = _MXC_BUILD_GPIO_PIN(0, 22, 3, 0x240, 0x630), + MX51_PIN_UART3_TXD = _MXC_BUILD_GPIO_PIN(0, 23, 3, 0x244, 0x634), + MX51_PIN_OWIRE_LINE = _MXC_BUILD_GPIO_PIN(0, 24, 3, 0x248, 0x638), + MX51_PIN_KEY_ROW0 = _MXC_BUILD_NON_GPIO_PIN(0x24C, 0x63C), + MX51_PIN_KEY_ROW1 = _MXC_BUILD_NON_GPIO_PIN(0x250, 0x640), + MX51_PIN_KEY_ROW2 = _MXC_BUILD_NON_GPIO_PIN(0x254, 0x644), + MX51_PIN_KEY_ROW3 = _MXC_BUILD_NON_GPIO_PIN(0x258, 0x648), + MX51_PIN_KEY_COL0 = _MXC_BUILD_NON_GPIO_PIN(0x25C, 0x64C), + MX51_PIN_KEY_COL1 = _MXC_BUILD_NON_GPIO_PIN(0x260, 0x650), + MX51_PIN_KEY_COL2 = _MXC_BUILD_NON_GPIO_PIN(0x264, 0x654), + MX51_PIN_KEY_COL3 = _MXC_BUILD_NON_GPIO_PIN(0x268, 0x658), + MX51_PIN_KEY_COL4 = _MXC_BUILD_NON_GPIO_PIN(0x26C, 0x65C), + MX51_PIN_KEY_COL5 = _MXC_BUILD_NON_GPIO_PIN(0x270, 0x660), + MX51_PIN_USBH1_CLK = _MXC_BUILD_GPIO_PIN(0, 25, 2, 0x278, 0x678), + MX51_PIN_USBH1_DIR = _MXC_BUILD_GPIO_PIN(0, 26, 2, 0x27C, 0x67C), + MX51_PIN_USBH1_STP = _MXC_BUILD_GPIO_PIN(0, 27, 2, 0x280, 0x680), + MX51_PIN_USBH1_NXT = _MXC_BUILD_GPIO_PIN(0, 28, 2, 0x284, 0x684), + MX51_PIN_USBH1_DATA0 = _MXC_BUILD_GPIO_PIN(0, 11, 2, 0x288, 0x688), + MX51_PIN_USBH1_DATA1 = _MXC_BUILD_GPIO_PIN(0, 12, 2, 0x28C, 0x68C), + MX51_PIN_USBH1_DATA2 = _MXC_BUILD_GPIO_PIN(0, 13, 2, 0x290, 0x690), + MX51_PIN_USBH1_DATA3 = _MXC_BUILD_GPIO_PIN(0, 14, 2, 0x294, 0x694), + MX51_PIN_USBH1_DATA4 = _MXC_BUILD_GPIO_PIN(0, 15, 2, 0x298, 0x698), + MX51_PIN_USBH1_DATA5 = _MXC_BUILD_GPIO_PIN(0, 16, 2, 0x29C, 0x69C), + MX51_PIN_USBH1_DATA6 = _MXC_BUILD_GPIO_PIN(0, 17, 2, 0x2A0, 0x6A0), + MX51_PIN_USBH1_DATA7 = _MXC_BUILD_GPIO_PIN(0, 18, 2, 0x2A4, 0x6A4), + MX51_PIN_DI1_PIN11 = _MXC_BUILD_GPIO_PIN(2, 0, 4, 0x2A8, 0x6A8), + MX51_PIN_DI1_PIN12 = _MXC_BUILD_GPIO_PIN(2, 1, 4, 0x2AC, 0x6AC), + MX51_PIN_DI1_PIN13 = _MXC_BUILD_GPIO_PIN(2, 2, 4, 0x2B0, 0x6B0), + MX51_PIN_DI1_D0_CS = _MXC_BUILD_GPIO_PIN(2, 3, 4, 0x2B4, 0x6B4), + MX51_PIN_DI1_D1_CS = _MXC_BUILD_GPIO_PIN(2, 4, 4, 0x2B8, 0x6B8), + MX51_PIN_DISPB2_SER_DIN = _MXC_BUILD_GPIO_PIN(2, 5, 4, 0x2BC, 0x6BC), + MX51_PIN_DISPB2_SER_DIO = _MXC_BUILD_GPIO_PIN(2, 6, 4, 0x2C0, 0x6C0), + MX51_PIN_DISPB2_SER_CLK = _MXC_BUILD_GPIO_PIN(2, 7, 4, 0x2C4, 0x6C4), + MX51_PIN_DISPB2_SER_RS = _MXC_BUILD_GPIO_PIN(2, 8, 4, 0x2C8, 0x6C8), + MX51_PIN_DISP1_DAT0 = _MXC_BUILD_NON_GPIO_PIN(0x2CC, 0x6CC), + MX51_PIN_DISP1_DAT1 = _MXC_BUILD_NON_GPIO_PIN(0x2D0, 0x6D0), + MX51_PIN_DISP1_DAT2 = _MXC_BUILD_NON_GPIO_PIN(0x2D4, 0x6D4), + MX51_PIN_DISP1_DAT3 = _MXC_BUILD_NON_GPIO_PIN(0x2D8, 0x6D8), + MX51_PIN_DISP1_DAT4 = _MXC_BUILD_NON_GPIO_PIN(0x2DC, 0x6DC), + MX51_PIN_DISP1_DAT5 = _MXC_BUILD_NON_GPIO_PIN(0x2E0, 0x6E0), + MX51_PIN_DISP1_DAT6 = _MXC_BUILD_NON_GPIO_PIN(0x2E4, 0x6E4), + MX51_PIN_DISP1_DAT7 = _MXC_BUILD_NON_GPIO_PIN(0x2E8, 0x6E8), + MX51_PIN_DISP1_DAT8 = _MXC_BUILD_NON_GPIO_PIN(0x2EC, 0x6EC), + MX51_PIN_DISP1_DAT9 = _MXC_BUILD_NON_GPIO_PIN(0x2F0, 0x6F0), + MX51_PIN_DISP1_DAT10 = _MXC_BUILD_NON_GPIO_PIN(0x2F4, 0x6F4), + MX51_PIN_DISP1_DAT11 = _MXC_BUILD_NON_GPIO_PIN(0x2F8, 0x6F8), + MX51_PIN_DISP1_DAT12 = _MXC_BUILD_NON_GPIO_PIN(0x2FC, 0x6FC), + MX51_PIN_DISP1_DAT13 = _MXC_BUILD_NON_GPIO_PIN(0x300, 0x700), + MX51_PIN_DISP1_DAT14 = _MXC_BUILD_NON_GPIO_PIN(0x304, 0x704), + MX51_PIN_DISP1_DAT15 = _MXC_BUILD_NON_GPIO_PIN(0x308, 0x708), + MX51_PIN_DISP1_DAT16 = _MXC_BUILD_NON_GPIO_PIN(0x30C, 0x70C), + MX51_PIN_DISP1_DAT17 = _MXC_BUILD_NON_GPIO_PIN(0x310, 0x710), + MX51_PIN_DISP1_DAT18 = _MXC_BUILD_NON_GPIO_PIN(0x314, 0x714), + MX51_PIN_DISP1_DAT19 = _MXC_BUILD_NON_GPIO_PIN(0x318, 0x718), + MX51_PIN_DISP1_DAT20 = _MXC_BUILD_NON_GPIO_PIN(0x31C, 0x71C), + MX51_PIN_DISP1_DAT21 = _MXC_BUILD_NON_GPIO_PIN(0x320, 0x720), + MX51_PIN_DISP1_DAT22 = _MXC_BUILD_NON_GPIO_PIN(0x324, 0x724), + MX51_PIN_DISP1_DAT23 = _MXC_BUILD_NON_GPIO_PIN(0x328, 0x728), + MX51_PIN_DI1_PIN3 = _MXC_BUILD_NON_GPIO_PIN(0x32C, 0x72C), + MX51_PIN_DI1_PIN2 = _MXC_BUILD_NON_GPIO_PIN(0x330, 0x734), + MX51_PIN_DI_GP1 = _MXC_BUILD_NON_GPIO_PIN(0x334, 0x73C), + MX51_PIN_DI_GP2 = _MXC_BUILD_NON_GPIO_PIN(0x338, 0x740), + MX51_PIN_DI_GP3 = _MXC_BUILD_NON_GPIO_PIN(0x33C, 0x744), + MX51_PIN_DI2_PIN4 = _MXC_BUILD_NON_GPIO_PIN(0x340, 0x748), + MX51_PIN_DI2_PIN2 = _MXC_BUILD_NON_GPIO_PIN(0x344, 0x74C), + MX51_PIN_DI2_PIN3 = _MXC_BUILD_NON_GPIO_PIN(0x348, 0x750), + MX51_PIN_DI2_DISP_CLK = _MXC_BUILD_NON_GPIO_PIN(0x34C, 0x754), + MX51_PIN_DI_GP4 = _MXC_BUILD_NON_GPIO_PIN(0x350, 0x758), + MX51_PIN_DISP2_DAT0 = _MXC_BUILD_NON_GPIO_PIN(0x354, 0x75C), + MX51_PIN_DISP2_DAT1 = _MXC_BUILD_NON_GPIO_PIN(0x358, 0x760), + MX51_PIN_DISP2_DAT2 = _MXC_BUILD_NON_GPIO_PIN(0x35C, 0x764), + MX51_PIN_DISP2_DAT3 = _MXC_BUILD_NON_GPIO_PIN(0x360, 0x768), + MX51_PIN_DISP2_DAT4 = _MXC_BUILD_NON_GPIO_PIN(0x364, 0x76C), + MX51_PIN_DISP2_DAT5 = _MXC_BUILD_NON_GPIO_PIN(0x368, 0x770), + MX51_PIN_DISP2_DAT6 = _MXC_BUILD_GPIO_PIN(0, 19, 5, 0x36C, 0x774), + MX51_PIN_DISP2_DAT7 = _MXC_BUILD_GPIO_PIN(0, 29, 5, 0x370, 0x778), + MX51_PIN_DISP2_DAT8 = _MXC_BUILD_GPIO_PIN(0, 30, 5, 0x374, 0x77C), + MX51_PIN_DISP2_DAT9 = _MXC_BUILD_GPIO_PIN(0, 31, 5, 0x378, 0x780), + MX51_PIN_DISP2_DAT10 = _MXC_BUILD_NON_GPIO_PIN(0x37C, 0x784), + MX51_PIN_DISP2_DAT11 = _MXC_BUILD_NON_GPIO_PIN(0x380, 0x788), + MX51_PIN_DISP2_DAT12 = _MXC_BUILD_NON_GPIO_PIN(0x384, 0x78C), + MX51_PIN_DISP2_DAT13 = _MXC_BUILD_NON_GPIO_PIN(0x388, 0x790), + MX51_PIN_DISP2_DAT14 = _MXC_BUILD_NON_GPIO_PIN(0x38C, 0x794), + MX51_PIN_DISP2_DAT15 = _MXC_BUILD_NON_GPIO_PIN(0x390, 0x798), + MX51_PIN_SD1_CMD = _MXC_BUILD_NON_GPIO_PIN(0x394, 0x79C), + MX51_PIN_SD1_CLK = _MXC_BUILD_NON_GPIO_PIN(0x398, 0x7A0), + MX51_PIN_SD1_DATA0 = _MXC_BUILD_NON_GPIO_PIN(0x39C, 0x7A4), + MX51_PIN_SD1_DATA1 = _MXC_BUILD_NON_GPIO_PIN(0x3A0, 0x7A8), + MX51_PIN_SD1_DATA2 = _MXC_BUILD_NON_GPIO_PIN(0x3A4, 0x7AC), + MX51_PIN_SD1_DATA3 = _MXC_BUILD_NON_GPIO_PIN(0x3A8, 0x7B0), + MX51_PIN_GPIO1_0 = _MXC_BUILD_GPIO_PIN(0, 0, 1, 0x3AC, 0x7B4), + MX51_PIN_GPIO1_1 = _MXC_BUILD_GPIO_PIN(0, 1, 1, 0x3B0, 0x7B8), + MX51_PIN_SD2_CMD = _MXC_BUILD_NON_GPIO_PIN(0x3B4, 0x7BC), + MX51_PIN_SD2_CLK = _MXC_BUILD_NON_GPIO_PIN(0x3B8, 0x7C0), + MX51_PIN_SD2_DATA0 = _MXC_BUILD_NON_GPIO_PIN(0x3BC, 0x7C4), + MX51_PIN_SD2_DATA1 = _MXC_BUILD_NON_GPIO_PIN(0x3C0, 0x7C8), + MX51_PIN_SD2_DATA2 = _MXC_BUILD_NON_GPIO_PIN(0x3C4, 0x7CC), + MX51_PIN_SD2_DATA3 = _MXC_BUILD_NON_GPIO_PIN(0x3C8, 0x7D0), + MX51_PIN_GPIO1_2 = _MXC_BUILD_GPIO_PIN(0, 2, 0, 0x3CC, 0x7D4), + MX51_PIN_GPIO1_3 = _MXC_BUILD_GPIO_PIN(0, 3, 0, 0x3D0, 0x7D8), + MX51_PIN_PMIC_INT_REQ = _MXC_BUILD_NON_GPIO_PIN(0x3D4, 0x7FC), + MX51_PIN_GPIO1_4 = _MXC_BUILD_GPIO_PIN(0, 4, 0, 0x3D8, 0x804), + MX51_PIN_GPIO1_5 = _MXC_BUILD_GPIO_PIN(0, 5, 0, 0x3DC, 0x808), + MX51_PIN_GPIO1_6 = _MXC_BUILD_GPIO_PIN(0, 6, 0, 0x3E0, 0x80C), + MX51_PIN_GPIO1_7 = _MXC_BUILD_GPIO_PIN(0, 7, 0, 0x3E4, 0x810), + MX51_PIN_GPIO1_8 = _MXC_BUILD_GPIO_PIN(0, 8, 0, 0x3E8, 0x814), + MX51_PIN_GPIO1_9 = _MXC_BUILD_GPIO_PIN(0, 9, 0, 0x3EC, 0x818), +}; + +#endif /* __ASSEMBLY__ */ +#endif /* __ASM_ARCH_MXC_MX51_PINS_H__ */ --- linux-2.6.28.orig/arch/arm/mach-mx51/devices.c +++ linux-2.6.28/arch/arm/mach-mx51/devices.c @@ -0,0 +1,916 @@ +/* + * Copyright 2008-2009 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "iomux.h" +#include "crm_regs.h" +#include +#include "sdma_script_code.h" + +/* Flag used to indicate when IRAM has been initialized */ +int iram_ready; + +void mxc_sdma_get_script_info(sdma_script_start_addrs * sdma_script_addr) +{ + /* AP<->BP */ + sdma_script_addr->mxc_sdma_ap_2_ap_addr = ap_2_ap_ADDR; + sdma_script_addr->mxc_sdma_ap_2_bp_addr = -1; + sdma_script_addr->mxc_sdma_bp_2_ap_addr = -1; + sdma_script_addr->mxc_sdma_ap_2_ap_fixed_addr = -1; + + /*misc */ + sdma_script_addr->mxc_sdma_loopback_on_dsp_side_addr = -1; + sdma_script_addr->mxc_sdma_mcu_interrupt_only_addr = -1; + + /* firi */ + sdma_script_addr->mxc_sdma_firi_2_per_addr = -1; + sdma_script_addr->mxc_sdma_firi_2_mcu_addr = -1; + sdma_script_addr->mxc_sdma_per_2_firi_addr = -1; + sdma_script_addr->mxc_sdma_mcu_2_firi_addr = -1; + + /* uart */ + sdma_script_addr->mxc_sdma_uart_2_per_addr = uart_2_per_ADDR; + sdma_script_addr->mxc_sdma_uart_2_mcu_addr = uart_2_mcu_ADDR; + + /* UART SH */ + sdma_script_addr->mxc_sdma_uartsh_2_per_addr = uartsh_2_per_ADDR; + sdma_script_addr->mxc_sdma_uartsh_2_mcu_addr = uartsh_2_mcu_ADDR; + + /* SHP */ + sdma_script_addr->mxc_sdma_per_2_shp_addr = per_2_shp_ADDR; + sdma_script_addr->mxc_sdma_shp_2_per_addr = shp_2_per_ADDR; + sdma_script_addr->mxc_sdma_mcu_2_shp_addr = mcu_2_shp_ADDR; + sdma_script_addr->mxc_sdma_shp_2_mcu_addr = shp_2_mcu_ADDR; + + /* ATA */ + sdma_script_addr->mxc_sdma_mcu_2_ata_addr = mcu_2_ata_ADDR; + sdma_script_addr->mxc_sdma_ata_2_mcu_addr = ata_2_mcu_ADDR; + + /* app */ + sdma_script_addr->mxc_sdma_app_2_per_addr = app_2_per_ADDR; + sdma_script_addr->mxc_sdma_app_2_mcu_addr = app_2_mcu_ADDR; + sdma_script_addr->mxc_sdma_per_2_app_addr = per_2_app_ADDR; + sdma_script_addr->mxc_sdma_mcu_2_app_addr = mcu_2_app_ADDR; + + /* MSHC */ + sdma_script_addr->mxc_sdma_mshc_2_mcu_addr = -1; + sdma_script_addr->mxc_sdma_mcu_2_mshc_addr = -1; + + /* spdif */ + sdma_script_addr->mxc_sdma_spdif_2_mcu_addr = -1; + sdma_script_addr->mxc_sdma_mcu_2_spdif_addr = mcu_2_spdif_ADDR; + + /* IPU */ + sdma_script_addr->mxc_sdma_ext_mem_2_ipu_addr = ext_mem__ipu_ram_ADDR; + + /* DVFS */ + sdma_script_addr->mxc_sdma_dptc_dvfs_addr = -1; + + /* core */ + sdma_script_addr->mxc_sdma_start_addr = (unsigned short *)sdma_code; + sdma_script_addr->mxc_sdma_ram_code_start_addr = RAM_CODE_START_ADDR; + sdma_script_addr->mxc_sdma_ram_code_size = RAM_CODE_SIZE; +} + +static void mxc_nop_release(struct device *dev) +{ + /* Nothing */ +} + +#if defined(CONFIG_W1_MASTER_MXC) || defined(CONFIG_W1_MASTER_MXC_MODULE) +static struct resource w1_resources[] = { + { + .start = MXC_INT_OWIRE, + .flags = IORESOURCE_IRQ, + } +}; + +static struct mxc_w1_config mxc_w1_data = { + .search_rom_accelerator = 1, +}; + +static struct platform_device mxc_w1_devices = { + .name = "mxc_w1", + .dev = { + .release = mxc_nop_release, + .platform_data = &mxc_w1_data, + }, + .num_resources = ARRAY_SIZE(w1_resources), + .resource = w1_resources, + .id = 0 +}; + +static void mxc_init_owire(void) +{ + (void)platform_device_register(&mxc_w1_devices); +} +#else +static inline void mxc_init_owire(void) +{ +} +#endif + +#if defined(CONFIG_RTC_DRV_MXC_V2) || defined(CONFIG_RTC_DRV_MXC_V2_MODULE) +static struct mxc_srtc_platform_data srtc_data = { + .srtc_sec_mode_addr = 0x83F98840, +}; + +static struct resource rtc_resources[] = { + { + .start = SRTC_BASE_ADDR, + .end = SRTC_BASE_ADDR + 0x40, + .flags = IORESOURCE_MEM, + }, + { + .start = MXC_INT_SRTC_NTZ, + .flags = IORESOURCE_IRQ, + }, +}; +static struct platform_device mxc_rtc_device = { + .name = "mxc_rtc", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &srtc_data, + }, + .num_resources = ARRAY_SIZE(rtc_resources), + .resource = rtc_resources, +}; +static void mxc_init_rtc(void) +{ + (void)platform_device_register(&mxc_rtc_device); +} +#else +static inline void mxc_init_rtc(void) +{ +} +#endif + +#if defined(CONFIG_MXC_WATCHDOG) || defined(CONFIG_MXC_WATCHDOG_MODULE) + +static struct resource wdt_resources[] = { + { + .start = WDOG1_BASE_ADDR, + .end = WDOG1_BASE_ADDR + 0x30, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device mxc_wdt_device = { + .name = "mxc_wdt", + .id = 0, + .dev = { + .release = mxc_nop_release, + }, + .num_resources = ARRAY_SIZE(wdt_resources), + .resource = wdt_resources, +}; + +static void mxc_init_wdt(void) +{ + (void)platform_device_register(&mxc_wdt_device); +} +#else +static inline void mxc_init_wdt(void) +{ +} +#endif + +#if defined(CONFIG_MXC_IPU_V3) || defined(CONFIG_MXC_IPU_V3_MODULE) +static struct mxc_ipu_config mxc_ipu_data = { + .rev = 1, +}; + +static struct resource ipu_resources[] = { + { + .start = IPU_CTRL_BASE_ADDR, + .end = IPU_CTRL_BASE_ADDR + SZ_512M, + .flags = IORESOURCE_MEM, + }, + { + .start = MXC_INT_IPU_SYN, + .flags = IORESOURCE_IRQ, + }, + { + .start = MXC_INT_IPU_ERR, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mxc_ipu_device = { + .name = "mxc_ipu", + .id = -1, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxc_ipu_data, + }, + .num_resources = ARRAY_SIZE(ipu_resources), + .resource = ipu_resources, +}; + +static void mxc_init_ipu(void) +{ + u32 reg_hsc_mcd = IO_ADDRESS(MIPI_HSC_BASE_ADDR); + u32 reg_hsc_mxt_conf = IO_ADDRESS(MIPI_HSC_BASE_ADDR + 0x800); + struct clk *clk; + uint32_t temp; + + /* Select IPUv3 h/w version */ + if (cpu_is_mx51_rev(CHIP_REV_2_0) > 0) + mxc_ipu_data.rev = 2; + + mxc_ipu_data.di_clk[1] = clk_get(NULL, "ipu_di_clk"); + clk = clk_get(NULL, "tve_clk"); + clk_set_parent(mxc_ipu_data.di_clk[1], clk); + clk_put(clk); + + /* Temporarily setup MIPI module to legacy mode */ + clk = clk_get(NULL, "mipi_hsp_clk"); + if (!IS_ERR(clk)) { + clk_enable(clk); + + /* Temporarily setup MIPI module to legacy mode */ + __raw_writel(0xF00, reg_hsc_mcd); + + /* CSI mode reserved*/ + temp = __raw_readl(reg_hsc_mxt_conf); + __raw_writel(temp | 0x0FF, reg_hsc_mxt_conf); + + if (cpu_is_mx51_rev(CHIP_REV_2_0) > 0) { + temp = __raw_readl(reg_hsc_mxt_conf); + __raw_writel(temp | 0x10000, reg_hsc_mxt_conf); + } + + clk_disable(clk); + clk_put(clk); + } + platform_device_register(&mxc_ipu_device); +} +#else +static inline void mxc_init_ipu(void) +{ +} +#endif + +#if defined(CONFIG_MXC_VPU) || defined(CONFIG_MXC_VPU_MODULE) +static struct resource vpu_resources[] = { + { + .start = VPU_IRAM_BASE_ADDR, + .end = VPU_IRAM_BASE_ADDR + VPU_IRAM_SIZE, + .flags = IORESOURCE_MEM, + }, +}; + +/*! Platform Data for MXC VPU */ +static struct platform_device mxcvpu_device = { + .name = "mxc_vpu", + .id = 0, + .dev = { + .release = mxc_nop_release, + }, + .num_resources = ARRAY_SIZE(vpu_resources), + .resource = vpu_resources, +}; + +static inline void mxc_init_vpu(void) +{ + if (platform_device_register(&mxcvpu_device) < 0) + printk(KERN_ERR "Error: Registering the VPU.\n"); +} +#else +static inline void mxc_init_vpu(void) +{ +} +#endif + +/*! + * This is platform device structure for adding SCC + */ +#if defined(CONFIG_MXC_SECURITY_SCC) || defined(CONFIG_MXC_SECURITY_SCC_MODULE) +static struct platform_device mxc_scc_device = { + .name = "mxc_scc", + .id = 0, +}; + +static void mxc_init_scc(void) +{ + platform_device_register(&mxc_scc_device); +} +#else +static inline void mxc_init_scc(void) +{ + uint32_t reg_value; + uint32_t reg_mask = 0; + uint8_t *UMID_base; + uint32_t *MAP_base; + uint8_t i; + uint32_t partition_no; + uint32_t scc_partno; + void *scm_ram_base; + void *scc_base; + uint8_t iram_partitions = 16; + + if (cpu_is_mx51_rev(CHIP_REV_2_0) < 0) + iram_partitions = 12; + + scc_base = ioremap((uint32_t) SCC_BASE_ADDR, 0x140); + if (scc_base == NULL) { + printk(KERN_ERR "FAILED TO MAP IRAM REGS\n"); + return; + } + scm_ram_base = ioremap((uint32_t) IRAM_BASE_ADDR, IRAM_SIZE); + if (scm_ram_base == NULL) { + printk(KERN_ERR "FAILED TO MAP IRAM\n"); + return; + } + + for (partition_no = 0; partition_no < iram_partitions; partition_no++) { + /*De-allocate a Partition*/ + reg_value = ((partition_no << SCM_ZCMD_PART_SHIFT) & + SCM_ZCMD_PART_MASK) | ((0x03 << + SCM_ZCMD_CCMD_SHIFT) + & SCM_ZCMD_CCMD_MASK); + __raw_writel(reg_value, scc_base + SCM_ZCMD_REG); + msleep(1); + while ((__raw_readl(scc_base + SCM_STATUS_REG) & + SCM_STATUS_SRS_READY) != SCM_STATUS_SRS_READY) ; + + /*In Supervisor mode claims a partition for it's own use + by writing zero to SMID register.*/ + __raw_writel(0, scc_base + (SCM_SMID0_REG + 8 * partition_no)); + + reg_mask |= (3 << (2 * (partition_no))); + } + + msleep(1); + reg_value = __raw_readl(scc_base + SCM_PART_OWNERS_REG); + + if ((reg_value & reg_mask) != reg_mask) { + printk(KERN_ERR "FAILED TO ACQUIRE IRAM PARTITION\n"); + iounmap(scm_ram_base); + iounmap(scc_base); + return; + } + + for (partition_no = 0; partition_no < iram_partitions; partition_no++) { + MAP_base = scm_ram_base + (partition_no * 0x2000); + UMID_base = (uint8_t *) MAP_base + 0x10; + + for (i = 0; i < 16; i++) + UMID_base[i] = 0; + + MAP_base[0] = SCM_PERM_NO_ZEROIZE | SCM_PERM_HD_SUP_DISABLE | + SCM_PERM_HD_READ | SCM_PERM_HD_WRITE | + SCM_PERM_TH_READ | SCM_PERM_TH_WRITE; + + } + + /* Freeing 2 partitions for SCC2 */ + scc_partno = iram_partitions - (SCC_IRAM_SIZE / SZ_8K); + for (partition_no = scc_partno; partition_no < iram_partitions; + partition_no++) { + reg_value = ((partition_no << SCM_ZCMD_PART_SHIFT) & + SCM_ZCMD_PART_MASK) | ((0x03 << + SCM_ZCMD_CCMD_SHIFT) + & SCM_ZCMD_CCMD_MASK); + __raw_writel(reg_value, scc_base + SCM_ZCMD_REG); + msleep(1); + while ((__raw_readl(scc_base + SCM_STATUS_REG) & + SCM_STATUS_SRS_READY) != SCM_STATUS_SRS_READY) ; + } + iounmap(scm_ram_base); + iounmap(scc_base); + printk(KERN_INFO "IRAM READY\n"); + iram_ready = 1; +} +#endif + +/* SPI controller and device data */ +#if defined(CONFIG_SPI_MXC) || defined(CONFIG_SPI_MXC_MODULE) + +#ifdef CONFIG_SPI_MXC_SELECT1 +/*! + * Resource definition for the CSPI1 + */ +static struct resource mxcspi1_resources[] = { + [0] = { + .start = CSPI1_BASE_ADDR, + .end = CSPI1_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_CSPI1, + .end = MXC_INT_CSPI1, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! Platform Data for MXC CSPI1 */ +static struct mxc_spi_master mxcspi1_data = { + .maxchipselect = 4, + .spi_version = 23, +}; + +/*! Device Definition for MXC CSPI1 */ +static struct platform_device mxcspi1_device = { + .name = "mxc_spi", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxcspi1_data, + }, + .num_resources = ARRAY_SIZE(mxcspi1_resources), + .resource = mxcspi1_resources, +}; + +#endif /* CONFIG_SPI_MXC_SELECT1 */ + +#ifdef CONFIG_SPI_MXC_SELECT2 +/*! + * Resource definition for the CSPI2 + */ +static struct resource mxcspi2_resources[] = { + [0] = { + .start = CSPI2_BASE_ADDR, + .end = CSPI2_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_CSPI2, + .end = MXC_INT_CSPI2, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! Platform Data for MXC CSPI2 */ +static struct mxc_spi_master mxcspi2_data = { + .maxchipselect = 4, + .spi_version = 23, +}; + +/*! Device Definition for MXC CSPI2 */ +static struct platform_device mxcspi2_device = { + .name = "mxc_spi", + .id = 1, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxcspi2_data, + }, + .num_resources = ARRAY_SIZE(mxcspi2_resources), + .resource = mxcspi2_resources, +}; +#endif /* CONFIG_SPI_MXC_SELECT2 */ + +#ifdef CONFIG_SPI_MXC_SELECT3 +/*! + * Resource definition for the CSPI3 + */ +static struct resource mxcspi3_resources[] = { + [0] = { + .start = CSPI3_BASE_ADDR, + .end = CSPI3_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_CSPI, + .end = MXC_INT_CSPI, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! Platform Data for MXC CSPI3 */ +static struct mxc_spi_master mxcspi3_data = { + .maxchipselect = 4, + .spi_version = 7, +}; + +/*! Device Definition for MXC CSPI3 */ +static struct platform_device mxcspi3_device = { + .name = "mxc_spi", + .id = 2, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxcspi3_data, + }, + .num_resources = ARRAY_SIZE(mxcspi3_resources), + .resource = mxcspi3_resources, +}; +#endif /* CONFIG_SPI_MXC_SELECT3 */ + +void __init mxc_init_spi(void) +{ + /* SPBA configuration for CSPI2 - MCU is set */ + spba_take_ownership(SPBA_CSPI1, SPBA_MASTER_A); +#ifdef CONFIG_SPI_MXC_SELECT1 + if (platform_device_register(&mxcspi1_device) < 0) + printk(KERN_ERR "Error: Registering the SPI Controller_1\n"); +#endif /* CONFIG_SPI_MXC_SELECT1 */ +#ifdef CONFIG_SPI_MXC_SELECT2 + if (platform_device_register(&mxcspi2_device) < 0) + printk(KERN_ERR "Error: Registering the SPI Controller_2\n"); +#endif /* CONFIG_SPI_MXC_SELECT2 */ +#ifdef CONFIG_SPI_MXC_SELECT3 + if (platform_device_register(&mxcspi3_device) < 0) + printk(KERN_ERR "Error: Registering the SPI Controller_3\n"); +#endif /* CONFIG_SPI_MXC_SELECT3 */ +} +#else +void __init mxc_init_spi(void) +{ +} +#endif + +/* I2C controller and device data */ +#if defined(CONFIG_I2C_MXC) || defined(CONFIG_I2C_MXC_MODULE) + +#ifdef CONFIG_I2C_MXC_SELECT1 +/*! + * Resource definition for the I2C1 + */ +static struct resource mxci2c1_resources[] = { + [0] = { + .start = I2C1_BASE_ADDR, + .end = I2C1_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_I2C1, + .end = MXC_INT_I2C1, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! Platform Data for MXC I2C */ +static struct mxc_i2c_platform_data mxci2c1_data = { + .i2c_clk = 100000, +}; +#endif + +#ifdef CONFIG_I2C_MXC_SELECT2 +/*! + * Resource definition for the I2C2 + */ +static struct resource mxci2c2_resources[] = { + [0] = { + .start = I2C2_BASE_ADDR, + .end = I2C2_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_I2C2, + .end = MXC_INT_I2C2, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! Platform Data for MXC I2C */ +static struct mxc_i2c_platform_data mxci2c2_data = { + .i2c_clk = 100000, +}; +#endif + +#ifdef CONFIG_I2C_MXC_SELECT3 +/*! + * Resource definition for the I2C3 + */ +static struct resource mxci2c3_resources[] = { + [0] = { + .start = I2C3_BASE_ADDR, + .end = I2C3_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_I2C3, + .end = MXC_INT_I2C3, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! Platform Data for MXC I2C */ +static struct mxc_i2c_platform_data mxci2c3_data = { + .i2c_clk = 100000, +}; +#endif + +/*! Device Definition for MXC I2C1 */ +static struct platform_device mxci2c_devices[] = { +#ifdef CONFIG_I2C_MXC_SELECT1 + { + .name = "mxc_i2c", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxci2c1_data, + }, + .num_resources = ARRAY_SIZE(mxci2c1_resources), + .resource = mxci2c1_resources,}, +#endif +#ifdef CONFIG_I2C_MXC_SELECT2 + { + .name = "mxc_i2c", + .id = 1, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxci2c2_data, + }, + .num_resources = ARRAY_SIZE(mxci2c2_resources), + .resource = mxci2c2_resources,}, +#endif +#ifdef CONFIG_I2C_MXC_SELECT3 + { + .name = "mxc_i2c", + .id = 2, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxci2c3_data, + }, + .num_resources = ARRAY_SIZE(mxci2c3_resources), + .resource = mxci2c3_resources,}, +#endif +}; + +static inline void mxc_init_i2c(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(mxci2c_devices); i++) { + if (platform_device_register(&mxci2c_devices[i]) < 0) + dev_err(&mxci2c_devices[i].dev, + "Unable to register I2C device\n"); + } +} +#else +static inline void mxc_init_i2c(void) +{ +} +#endif + +#if defined(CONFIG_I2C_MXC_HS) || defined(CONFIG_I2C_MXC_HS_MODULE) +static struct resource mxci2c_hs_resources[] = { + [0] = { + .start = HSI2C_DMA_BASE_ADDR, + .end = HSI2C_DMA_BASE_ADDR + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_HS_I2C, + .end = MXC_INT_HS_I2C, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! Platform Data for MXC I2C */ +static struct mxc_i2c_platform_data mxci2c_hs_data = { + .i2c_clk = 400000, +}; + +static struct platform_device mxci2c_hs_device = { + .name = "mxc_i2c_hs", + .id = 3, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxci2c_hs_data, + }, + .num_resources = ARRAY_SIZE(mxci2c_hs_resources), + .resource = mxci2c_hs_resources +}; + +static inline void mxc_init_i2c_hs(void) +{ + if (platform_device_register(&mxci2c_hs_device) < 0) + dev_err(&mxci2c_hs_device.dev, + "Unable to register High Speed I2C device\n"); +} +#else +static inline void mxc_init_i2c_hs(void) +{ +} +#endif + +#if defined(CONFIG_FB_MXC_TVOUT_TVE) || defined(CONFIG_FB_MXC_TVOUT_TVE_MODULE) +static struct resource tve_resources[] = { + { + .start = TVE_BASE_ADDR, + .end = TVE_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = MXC_INT_TVE, + .flags = IORESOURCE_IRQ, + }, +}; +static struct tve_platform_data tve_data = { + .dac_reg = "VVIDEO", + .dig_reg = "VDIG", +}; + +static struct platform_device mxc_tve_device = { + .name = "tve", + .dev = { + .platform_data = &tve_data, + .release = mxc_nop_release, + }, + .num_resources = ARRAY_SIZE(tve_resources), + .resource = tve_resources, +}; + +void __init mxc_init_tve(void) +{ + platform_device_register(&mxc_tve_device); +} +#else +static inline void mxc_init_tve(void) +{ +} +#endif + +/*! + * Resource definition for the DVFS CORE + */ +static struct resource dvfs_core_resources[] = { + [0] = { + .start = MXC_DVFS_CORE_BASE, + .end = MXC_DVFS_CORE_BASE + 4 * SZ_16 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_GPC1, + .end = MXC_INT_GPC1, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! Platform Data for DVFS CORE */ +struct mxc_dvfs_platform_data dvfs_core_data = { + .reg_id = "SW1", + .clk1_id = "cpu_clk", + .clk2_id = "gpc_dvfs_clk", + .gpc_cntr_reg_addr = MXC_GPC_CNTR, + .gpc_vcr_reg_addr = MXC_GPC_VCR, + .dvfs_thrs_reg_addr = MXC_DVFSTHRS, + .dvfs_coun_reg_addr = MXC_DVFSCOUN, + .dvfs_emac_reg_addr = MXC_DVFSEMAC, + .dvfs_cntr_reg_addr = MXC_DVFSCNTR, + .div3ck_mask = 0xE0000000, + .div3ck_offset = 29, + .div3ck_val = 2, + .emac_val = 0x10, + .upthr_val = 25, + .dnthr_val = 9, + .pncthr_val = 33, + .upcnt_val = 3, + .dncnt_val = 3, + .delay_time = 30, + .num_wp = 2, +}; + +/*! Device Definition for MXC DVFS core */ +static struct platform_device mxc_dvfs_core_device = { + .name = "mxc_dvfs_core", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &dvfs_core_data, + }, + .num_resources = ARRAY_SIZE(dvfs_core_resources), + .resource = dvfs_core_resources, +}; + +static inline void mxc_init_dvfs(void) +{ + if (platform_device_register(&mxc_dvfs_core_device) < 0) + dev_err(&mxc_dvfs_core_device.dev, + "Unable to register DVFS core device\n"); +} + +struct mxc_gpio_port mxc_gpio_ports[GPIO_PORT_NUM] = { + { + .num = 0, + .base = IO_ADDRESS(GPIO1_BASE_ADDR), + .irq_0_15 = MXC_INT_GPIO1_LOW, + .irq_16_31 = MXC_INT_GPIO1_HIGH, + .virtual_irq_start = MXC_GPIO_INT_BASE, + }, + { + .num = 1, + .base = IO_ADDRESS(GPIO2_BASE_ADDR), + .irq_0_15 = MXC_INT_GPIO2_LOW, + .irq_16_31 = MXC_INT_GPIO2_HIGH, + .virtual_irq_start = MXC_GPIO_INT_BASE + GPIO_NUM_PIN * 1, + }, + { + .num = 2, + .base = IO_ADDRESS(GPIO3_BASE_ADDR), + .irq_0_15 = MXC_INT_GPIO3_LOW, + .irq_16_31 = MXC_INT_GPIO3_HIGH, + .virtual_irq_start = MXC_GPIO_INT_BASE + GPIO_NUM_PIN * 2, + }, + { + .num = 3, + .base = IO_ADDRESS(GPIO4_BASE_ADDR), + .irq_0_15 = MXC_INT_GPIO4_LOW, + .irq_16_31 = MXC_INT_GPIO4_HIGH, + .virtual_irq_start = MXC_GPIO_INT_BASE + GPIO_NUM_PIN * 3, + }, +}; + +static struct platform_device mxc_dma_device = { + .name = "mxc_dma", + .id = 0, + .dev = { + .release = mxc_nop_release, + }, +}; + +static inline void mxc_init_dma(void) +{ + (void)platform_device_register(&mxc_dma_device); +} + +static struct resource spdif_resources[] = { + { + .start = SPDIF_BASE_ADDR, + .end = SPDIF_BASE_ADDR + 0x50, + .flags = IORESOURCE_MEM, + }, +}; + +static struct mxc_spdif_platform_data mxc_spdif_data = { + .spdif_tx = 1, + .spdif_rx = 0, + .spdif_clk_44100 = 0, /* spdif_ext_clk source for 44.1KHz */ + .spdif_clk_48000 = 7, /* audio osc source */ + .spdif_clkid = 0, + .spdif_clk = NULL, /* spdif bus clk */ +}; + +static struct platform_device mxc_alsa_spdif_device = { + .name = "mxc_alsa_spdif", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mxc_spdif_data, + }, + .num_resources = ARRAY_SIZE(spdif_resources), + .resource = spdif_resources, +}; + +static inline void mxc_init_spdif(void) +{ + mxc_spdif_data.spdif_core_clk = clk_get(NULL, "spdif_xtal_clk"); + clk_put(mxc_spdif_data.spdif_core_clk); + platform_device_register(&mxc_alsa_spdif_device); +} + +static struct platform_device mx51_lpmode_device = { + .name = "mx51_lpmode", + .id = 0, + .dev = { + .release = mxc_nop_release, + }, +}; + +static inline void mx51_init_lpmode(void) +{ + (void)platform_device_register(&mx51_lpmode_device); +} + +int __init mxc_init_devices(void) +{ + mxc_init_wdt(); + mxc_init_spi(); + mxc_init_i2c(); + mxc_init_i2c_hs(); + mxc_init_rtc(); + mxc_init_scc(); + mxc_init_dma(); + mxc_init_owire(); + mxc_init_ipu(); + mxc_init_vpu(); + mxc_init_spdif(); + mxc_init_tve(); + mx51_init_lpmode(); + mxc_init_dvfs(); + return 0; +} --- linux-2.6.28.orig/arch/arm/mach-mx51/serial.h +++ linux-2.6.28/arch/arm/mach-mx51/serial.h @@ -0,0 +1,127 @@ +/* + * Copyright 2008-2009 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 __ARCH_ARM_MACH_MX51_SERIAL_H__ +#define __ARCH_ARM_MACH_MX51_SERIAL_H__ + +#include + +/* UART 1 configuration */ +/*! + * This option allows to choose either an interrupt-driven software controlled + * hardware flow control (set this option to 0) or hardware-driven hardware + * flow control (set this option to 1). + */ +/* UART used as wakeup source */ +#define UART1_HW_FLOW 0 +/*! + * This specifies the threshold at which the CTS pin is deasserted by the + * RXFIFO. Set this value in Decimal to anything from 0 to 32 for + * hardware-driven hardware flow control. Read the HW spec while specifying + * this value. When using interrupt-driven software controlled hardware + * flow control set this option to -1. + */ +#define UART1_UCR4_CTSTL 16 +/*! + * This is option to enable (set this option to 1) or disable DMA data transfer + */ +#define UART1_DMA_ENABLE 0 +/*! + * Specify the size of the DMA receive buffer. The minimum buffer size is 512 + * bytes. The buffer size should be a multiple of 256. + */ +#define UART1_DMA_RXBUFSIZE 1024 +/*! + * Specify the MXC UART's Receive Trigger Level. This controls the threshold at + * which a maskable interrupt is generated by the RxFIFO. Set this value in + * Decimal to anything from 0 to 32. Read the HW spec while specifying this + * value. + */ +#define UART1_UFCR_RXTL 16 +/*! + * Specify the MXC UART's Transmit Trigger Level. This controls the threshold at + * which a maskable interrupt is generated by the TxFIFO. Set this value in + * Decimal to anything from 0 to 32. Read the HW spec while specifying this + * value. + */ +#define UART1_UFCR_TXTL 16 +/* UART 2 configuration */ +#define UART2_HW_FLOW 0 +#define UART2_UCR4_CTSTL -1 +#define UART2_DMA_ENABLE 0 +#define UART2_DMA_RXBUFSIZE 512 +#define UART2_UFCR_RXTL 16 +#define UART2_UFCR_TXTL 16 +/* UART 3 configuration */ +#define UART3_HW_FLOW 1 +#define UART3_UCR4_CTSTL 16 +#define UART3_DMA_ENABLE 1 +#define UART3_DMA_RXBUFSIZE 1024 +#define UART3_UFCR_RXTL 16 +#define UART3_UFCR_TXTL 16 +/* + * UART Chip level Configuration that a user may not have to edit. These + * configuration vary depending on how the UART module is integrated with + * the ARM core + */ +/* + * Is the MUXED interrupt output sent to the ARM core + */ +#define INTS_NOTMUXED 0 +#define INTS_MUXED 1 +/* UART 1 configuration */ +/*! + * This define specifies whether the muxed ANDed interrupt line or the + * individual interrupts from the UART port is integrated with the ARM core. + * There exists a define like this for each UART port. Valid values that can + * be used are \b INTS_NOTMUXED or \b INTS_MUXED. + */ +#define UART1_MUX_INTS INTS_MUXED +/*! + * This define specifies the transmitter interrupt number or the interrupt + * number of the ANDed interrupt in case the interrupts are muxed. There exists + * a define like this for each UART port. + */ +#define UART1_INT1 MXC_INT_UART1 +/*! + * This define specifies the receiver interrupt number. If the interrupts of + * the UART are muxed, then we specify here a dummy value -1. There exists a + * define like this for each UART port. + */ +#define UART1_INT2 -1 +/*! + * This specifies the master interrupt number. If the interrupts of the UART + * are muxed, then we specify here a dummy value of -1. There exists a define + * like this for each UART port. + */ +#define UART1_INT3 -1 +/*! + * This specifies if the UART is a shared peripheral. It holds the shared + * peripheral number if it is shared or -1 if it is not shared. There exists + * a define like this for each UART port. + */ +#define UART1_SHARED_PERI -1 +/* UART 2 configuration */ +#define UART2_MUX_INTS INTS_MUXED +#define UART2_INT1 MXC_INT_UART2 +#define UART2_INT2 -1 +#define UART2_INT3 -1 +#define UART2_SHARED_PERI -1 +/* UART 3 configuration */ +#define UART3_MUX_INTS INTS_MUXED +#define UART3_INT1 MXC_INT_UART3 +#define UART3_INT2 -1 +#define UART3_INT3 -1 +#define UART3_SHARED_PERI SPBA_UART3 + +#endif /* __ARCH_ARM_MACH_MX51_SERIAL_H__ */ --- linux-2.6.28.orig/arch/arm/mach-mx51/mx51_babbage.c +++ linux-2.6.28/arch/arm/mach-mx51/mx51_babbage.c @@ -0,0 +1,618 @@ +/* + * Copyright 2009 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "board-mx51_babbage.h" +#include "iomux.h" +#include "crm_regs.h" + +/*! + * @file mach-mx51/mx51_babbage.c + * + * @brief This file contains the board specific initialization routines. + * + * @ingroup MSL_MX51 + */ +extern void __init mx51_babbage_io_init(void); +extern struct cpu_wp *(*get_cpu_wp)(int *wp); + +/* working point(wp): 0 - 800MHz; 1 - 200MHz; */ +static struct cpu_wp cpu_wp_auto[] = { + { + .pll_rate = 800000000, + .cpu_rate = 800000000, + .pdf = 0, + .mfi = 8, + .mfd = 2, + .mfn = 1, + .cpu_podf = 0, + .cpu_voltage = 1050000,}, + { + .pll_rate = 800000000, + .cpu_rate = 200000000, + .pdf = 3, + .mfi = 8, + .mfd = 2, + .mfn = 1, + .cpu_podf = 3, + .cpu_voltage = 775000,}, +}; + +struct cpu_wp *mx51_babbage_get_cpu_wp(int *wp) +{ + *wp = 2; + return cpu_wp_auto; +} + +static void mxc_nop_release(struct device *dev) +{ + /* Nothing */ +} + +#if defined(CONFIG_FB_MXC_SYNC_PANEL) || \ + defined(CONFIG_FB_MXC_SYNC_PANEL_MODULE) +static struct resource mxcfb_resources[] = { + [0] = { + .flags = IORESOURCE_MEM, + }, +}; + +static struct mxc_fb_platform_data fb_data[] = { + { + .interface_pix_fmt = IPU_PIX_FMT_RGB24, + }, + { + .interface_pix_fmt = IPU_PIX_FMT_RGB565, + }, +}; + +static struct platform_device mxc_fb_device[] = { + { + .name = "mxc_sdc_fb", + .id = 0, + .dev = { + .release = mxc_nop_release, + .coherent_dma_mask = 0xFFFFFFFF, + .platform_data = &fb_data[0], + }, + }, + { + .name = "mxc_sdc_fb", + .id = 1, + .dev = { + .release = mxc_nop_release, + .coherent_dma_mask = 0xFFFFFFFF, + .platform_data = &fb_data[1], + }, + }, + { + .name = "mxc_sdc_fb", + .id = 2, + .dev = { + .release = mxc_nop_release, + .coherent_dma_mask = 0xFFFFFFFF, + }, + }, +}; + +static void mxc_init_fb(void) +{ + (void)platform_device_register(&mxc_fb_device[1]); + (void)platform_device_register(&mxc_fb_device[2]); +} +#else +static inline void mxc_init_fb(void) +{ +} +#endif + +static struct platform_device mxcbl_device = { + .name = "mxc_mc13892_bl", +}; + +static inline void mxc_init_bl(void) +{ + platform_device_register(&mxcbl_device); +} + +static void dvi_reset(void) +{ + mxc_set_gpio_direction(MX51_PIN_DISPB2_SER_DIN, 0); + mxc_set_gpio_dataout(MX51_PIN_DISPB2_SER_DIN, 0); + msleep(50); + + /* do reset */ + mxc_set_gpio_dataout(MX51_PIN_DISPB2_SER_DIN, 1); + msleep(20); /* tRES >= 50us */ + + mxc_set_gpio_dataout(MX51_PIN_DISPB2_SER_DIN, 0); +} + +static struct mxc_lcd_platform_data dvi_data = { + .core_reg = "VGEN1", + .io_reg = "VGEN3", + .reset = dvi_reset, +}; + +static void vga_reset(void) +{ + mxc_set_gpio_direction(MX51_PIN_EIM_A19, 0); + mxc_set_gpio_dataout(MX51_PIN_EIM_A19, 0); + msleep(50); + /* do reset */ + mxc_set_gpio_dataout(MX51_PIN_EIM_A19, 1); + msleep(10); /* tRES >= 50us */ + mxc_set_gpio_dataout(MX51_PIN_EIM_A19, 0); +} + +static struct mxc_lcd_platform_data vga_data = { + .core_reg = "VCAM", + .io_reg = "VGEN3", + .analog_reg = "VAUDIO", + .reset = vga_reset, +}; + +static void si4702_reset(void) +{ + return; + mxc_set_gpio_dataout(MX51_PIN_EIM_A21, 0); + msleep(100); + mxc_set_gpio_dataout(MX51_PIN_EIM_A21, 1); + msleep(100); +} + +static void si4702_clock_ctl(int flag) +{ + mxc_set_gpio_dataout(MX51_PIN_EIM_A18, flag); + msleep(100); +} + +static void si4702_gpio_get(void) +{ + mxc_set_gpio_direction(MX51_PIN_EIM_A18, 0); +} + +static void si4702_gpio_put(void) +{ +} + +static struct mxc_fm_platform_data si4702_data = { + .reg_vio = "SW4", + .reg_vdd = "VIOHI", + .gpio_get = si4702_gpio_get, + .gpio_put = si4702_gpio_put, + .reset = si4702_reset, + .clock_ctl = si4702_clock_ctl, +}; + +#if defined(CONFIG_I2C_MXC) || defined(CONFIG_I2C_MXC_MODULE) + +#ifdef CONFIG_I2C_MXC_SELECT1 +static struct i2c_board_info mxc_i2c0_board_info[] __initdata = { +}; +#endif +#ifdef CONFIG_I2C_MXC_SELECT2 +static struct i2c_board_info mxc_i2c1_board_info[] __initdata = { + { + .type = "sgtl5000-i2c", + .addr = 0x0a, + }, +}; +#endif + +#if defined(CONFIG_I2C_MXC_HS) || defined(CONFIG_I2C_MXC_HS_MODULE) +static struct i2c_board_info mxc_i2c_hs_board_info[] __initdata = { + { + .type = "sii9022", + .addr = 0x39, + .platform_data = &dvi_data, + }, + { + .type = "ch7026", + .addr = 0x75, + .platform_data = &vga_data, + }, + { + .type = "si4702", + .addr = 0x10, + .platform_data = (void *)&si4702_data, + }, +}; +#endif + +#endif + +#if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE) +static struct mtd_partition mxc_spi_flash_partitions[] = { + { + .name = "bootloader", + .offset = 0, + .size = 0x00040000, + .mask_flags = MTD_CAP_ROM}, + { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL}, +}; + +static struct flash_platform_data mxc_spi_flash_data = { + .name = "mxc_spi_nor", + .parts = mxc_spi_flash_partitions, + .nr_parts = ARRAY_SIZE(mxc_spi_flash_partitions), + .type = "sst25vf016b", +}; +#endif + +static struct spi_board_info mxc_spi_board_info[] __initdata = { +#if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE) + { + .modalias = "mxc_spi_nor", + .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ + .bus_num = 1, + .chip_select = 1, + .platform_data = &mxc_spi_flash_data, + }, +#endif +}; + +#if defined(CONFIG_FEC) || defined(CONFIG_FEC_MODULE) +unsigned int expio_intr_fec; + +EXPORT_SYMBOL(expio_intr_fec); +#endif + +#if defined(CONFIG_MMC_IMX_ESDHCI) || defined(CONFIG_MMC_IMX_ESDHCI_MODULE) +static int sdhc_write_protect(struct device *dev) +{ + unsigned short rc = 0; + + if (to_platform_device(dev)->id == 0) + rc = mxc_get_gpio_datain(MX51_PIN_GPIO1_1); + + return rc; +} + +static unsigned int sdhc_get_card_det_status(struct device *dev) +{ + int ret; + + if (to_platform_device(dev)->id == 0) { + ret = mxc_get_gpio_datain(MX51_PIN_GPIO1_0); + return ret; + } else { /* config the det pin for SDHC2 */ + return 0; + } +} + +static struct mxc_mmc_platform_data mmc_data = { + .ocr_mask = MMC_VDD_31_32, + .caps = MMC_CAP_4_BIT_DATA, + .min_clk = 400000, + .max_clk = 52000000, + .card_inserted_state = 1, + .status = sdhc_get_card_det_status, + .wp_status = sdhc_write_protect, + .clock_mmc = "esdhc_clk", + .power_mmc = NULL, +}; + +/*! + * Resource definition for the SDHC1 + */ +static struct resource mxcsdhc1_resources[] = { + [0] = { + .start = MMC_SDHC1_BASE_ADDR, + .end = MMC_SDHC1_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_MMC_SDHC1, + .end = MXC_INT_MMC_SDHC1, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = IOMUX_TO_IRQ(MX51_PIN_GPIO1_0), + .end = IOMUX_TO_IRQ(MX51_PIN_GPIO1_0), + .flags = IORESOURCE_IRQ, + }, +}; + +/*! + * Resource definition for the SDHC2 + */ +static struct resource mxcsdhc2_resources[] = { + [0] = { + .start = MMC_SDHC2_BASE_ADDR, + .end = MMC_SDHC2_BASE_ADDR + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_MMC_SDHC2, + .end = MXC_INT_MMC_SDHC2, + .flags = IORESOURCE_IRQ, + }, + [2] = { + .start = 0, + .end = 0, + .flags = IORESOURCE_IRQ, + }, +}; + +/*! Device Definition for MXC SDHC1 */ +static struct platform_device mxcsdhc1_device = { + .name = "mxsdhci", + .id = 0, + .dev = { + .release = mxc_nop_release, + .platform_data = &mmc_data, + }, + .num_resources = ARRAY_SIZE(mxcsdhc1_resources), + .resource = mxcsdhc1_resources, +}; + +/*! Device Definition for MXC SDHC2 */ +static struct platform_device mxcsdhc2_device = { + .name = "mxsdhci", + .id = 1, + .dev = { + .release = mxc_nop_release, + .platform_data = &mmc_data, + }, + .num_resources = ARRAY_SIZE(mxcsdhc2_resources), + .resource = mxcsdhc2_resources, +}; + +static inline void mxc_init_mmc(void) +{ + (void)platform_device_register(&mxcsdhc1_device); + (void)platform_device_register(&mxcsdhc2_device); +} +#else +static inline void mxc_init_mmc(void) +{ +} +#endif + +#if defined(CONFIG_SND_SOC_IMX_3STACK_SGTL5000) \ + || defined(CONFIG_SND_SOC_IMX_3STACK_SGTL5000_MODULE) +static int mxc_sgtl5000_amp_enable(int enable); + +static int headphone_det_status(void) +{ + return mxc_get_gpio_datain(MX51_PIN_NANDF_CS0); +} + +static struct mxc_audio_platform_data sgtl5000_data = { + .ssi_num = 1, + .src_port = 2, + .ext_port = 3, + .hp_irq = IOMUX_TO_IRQ(MX51_PIN_NANDF_CS0), + .hp_status = headphone_det_status, + .vddio_reg = "VVIDEO", + .vdda_reg = "VDIG", + .vddd_reg = "VGEN1", + .amp_enable = mxc_sgtl5000_amp_enable, + .vddio = 2775000, + .vdda = 1650000, + .vddd = 12000000, + .sysclk = 12288000, +}; + +static struct platform_device mxc_sgtl5000_device = { + .name = "imx-3stack-sgtl5000", + .dev = { + .release = mxc_nop_release, + .platform_data = &sgtl5000_data, + }, +}; + +static int mxc_sgtl5000_amp_enable(int enable) +{ + mxc_set_gpio_dataout(MX51_PIN_EIM_A23, enable ? 1 : 0); + return 0; +} + +static void mxc_init_sgtl5000(void) +{ + mxc_set_gpio_direction(MX51_PIN_NANDF_CS0, 1); + mxc_set_gpio_direction(MX51_PIN_EIM_A23, 0); + + platform_device_register(&mxc_sgtl5000_device); +} +#else +static inline void mxc_init_sgtl5000(void) +{ +} +#endif + +#if defined(CONFIG_GPIO_BUTTON_MXC) || \ + defined(CONFIG_GPIO_BUTTON_MXC_MODULE) + +#define MXC_BUTTON_GPIO_PIN MX51_PIN_EIM_DTACK + +static struct mxc_gpio_button_data gpio_button_data = { + .name = "Power Button (CM)", + .gpio = MXC_BUTTON_GPIO_PIN, + .irq = IOMUX_TO_IRQ(MXC_BUTTON_GPIO_PIN), + .key = KEY_POWER, +}; + +static struct platform_device gpio_button_device = { + .name = "gpio_button", + .dev = { + .release = mxc_nop_release, + .platform_data = &gpio_button_data, + }, +}; + +static inline void mxc_init_gpio_button(void) +{ + mxc_set_gpio_direction(MXC_BUTTON_GPIO_PIN, 1); + platform_device_register(&gpio_button_device); +} +#else +static inline void mxc_init_gpio_button(void) +{ +} +#endif + +/*! + * Board specific fixup function. It is called by \b setup_arch() in + * setup.c file very early on during kernel starts. It allows the user to + * statically fill in the proper values for the passed-in parameters. None of + * the parameters is used currently. + * + * @param desc pointer to \b struct \b machine_desc + * @param tags pointer to \b struct \b tag + * @param cmdline pointer to the command line + * @param mi pointer to \b struct \b meminfo + */ +static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags, + char **cmdline, struct meminfo *mi) +{ + struct tag *t; + + mxc_cpu_init(); + + get_cpu_wp = mx51_babbage_get_cpu_wp; + + for_each_tag(t, tags) { + if (t->hdr.tag != ATAG_MEM) + continue; + + if (t->u.mem.size == SZ_512M) + t->u.mem.size -= SZ_32M; + mxcfb_resources[0].start = t->u.mem.start + t->u.mem.size; + mxcfb_resources[0].end = t->u.mem.start + SZ_512M - 1; + } +} + +#define PWGT1SPIEN (1<<15) +#define PWGT2SPIEN (1<<16) +#define USEROFFSPI (1<<3) + +static void mxc_power_off(void) +{ + /* We can do power down one of two ways: + Set the power gating + Set USEROFFSPI */ + + /* Set the power gate bits to power down */ + pmic_write_reg(REG_POWER_MISC, (PWGT1SPIEN|PWGT2SPIEN), + (PWGT1SPIEN|PWGT2SPIEN)); +} + +/*! + * Board specific initialization. + */ +static void __init mxc_board_init(void) +{ + struct regulator *regulator; + + mxc_cpu_common_init(); + mxc_gpio_init(); + mx51_babbage_io_init(); + early_console_setup(saved_command_line); + + mxc_init_devices(); + + mxc_init_fb(); + mxc_init_bl(); + mxc_init_mmc(); + mxc_init_gpio_button(); + mx51_babbage_init_mc13892(); + + spi_register_board_info(mxc_spi_board_info, + ARRAY_SIZE(mxc_spi_board_info)); + +#if defined(CONFIG_I2C_MXC) || defined(CONFIG_I2C_MXC_MODULE) + +#ifdef CONFIG_I2C_MXC_SELECT1 + i2c_register_board_info(0, mxc_i2c0_board_info, + ARRAY_SIZE(mxc_i2c0_board_info)); +#endif +#ifdef CONFIG_I2C_MXC_SELECT2 + i2c_register_board_info(1, mxc_i2c1_board_info, + ARRAY_SIZE(mxc_i2c1_board_info)); +#endif +#if defined(CONFIG_I2C_MXC_HS) || defined(CONFIG_I2C_MXC_HS_MODULE) + i2c_register_board_info(3, mxc_i2c_hs_board_info, + ARRAY_SIZE(mxc_i2c_hs_board_info)); +#endif + +#endif + pm_power_off = mxc_power_off; + mxc_init_sgtl5000(); +} + +static void __init mx51_babbage_timer_init(void) +{ + mxc_clocks_init(32768, 24000000, 22579200, 24576000); + mxc_timer_init("gpt_clk.0"); +} + +static struct sys_timer mxc_timer = { + .init = mx51_babbage_timer_init, +}; + +/* + * The following uses standard kernel macros define in arch.h in order to + * initialize __mach_desc_MX51_BABBAGE data structure. + */ +/* *INDENT-OFF* */ +MACHINE_START(MX51_BABBAGE, "Freescale MX51 Babbage Board") + /* Maintainer: Freescale Semiconductor, Inc. */ + .phys_io = AIPS1_BASE_ADDR, + .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, + .boot_params = PHYS_OFFSET + 0x100, + .fixup = fixup_mxc_board, + .map_io = mxc_map_io, + .init_irq = mxc_init_irq, + .init_machine = mxc_board_init, + .timer = &mxc_timer, +MACHINE_END --- linux-2.6.28.orig/arch/arm/mach-mx51/crm_regs.h +++ linux-2.6.28/arch/arm/mach-mx51/crm_regs.h @@ -0,0 +1,673 @@ +/* + * Copyright 2008-2009 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 __ARCH_ARM_MACH_MX51_CRM_REGS_H__ +#define __ARCH_ARM_MACH_MX51_CRM_REGS_H__ + +#define MXC_CCM_BASE ((char *)IO_ADDRESS(CCM_BASE_ADDR)) +#define MXC_DPLL1_BASE IO_ADDRESS(PLL1_BASE_ADDR) +#define MXC_DPLL2_BASE IO_ADDRESS(PLL2_BASE_ADDR) +#define MXC_DPLL3_BASE IO_ADDRESS(PLL3_BASE_ADDR) + +/* PLL Register Offsets */ +#define MXC_PLL_DP_CTL 0x00 +#define MXC_PLL_DP_CONFIG 0x04 +#define MXC_PLL_DP_OP 0x08 +#define MXC_PLL_DP_MFD 0x0C +#define MXC_PLL_DP_MFN 0x10 +#define MXC_PLL_DP_MFNMINUS 0x14 +#define MXC_PLL_DP_MFNPLUS 0x18 +#define MXC_PLL_DP_HFS_OP 0x1C +#define MXC_PLL_DP_HFS_MFD 0x20 +#define MXC_PLL_DP_HFS_MFN 0x24 +#define MXC_PLL_DP_MFN_TOGC 0x28 +#define MXC_PLL_DP_DESTAT 0x2c + +/* PLL Register Bit definitions */ +#define MXC_PLL_DP_CTL_MUL_CTRL 0x2000 +#define MXC_PLL_DP_CTL_DPDCK0_2_EN 0x1000 +#define MXC_PLL_DP_CTL_DPDCK0_2_OFFSET 12 +#define MXC_PLL_DP_CTL_ADE 0x800 +#define MXC_PLL_DP_CTL_REF_CLK_DIV 0x400 +#define MXC_PLL_DP_CTL_REF_CLK_SEL_MASK (3 << 8) +#define MXC_PLL_DP_CTL_REF_CLK_SEL_OFFSET 8 +#define MXC_PLL_DP_CTL_HFSM 0x80 +#define MXC_PLL_DP_CTL_PRE 0x40 +#define MXC_PLL_DP_CTL_UPEN 0x20 +#define MXC_PLL_DP_CTL_RST 0x10 +#define MXC_PLL_DP_CTL_RCP 0x8 +#define MXC_PLL_DP_CTL_PLM 0x4 +#define MXC_PLL_DP_CTL_BRM0 0x2 +#define MXC_PLL_DP_CTL_LRF 0x1 + +#define MXC_PLL_DP_CONFIG_BIST 0x8 +#define MXC_PLL_DP_CONFIG_SJC_CE 0x4 +#define MXC_PLL_DP_CONFIG_AREN 0x2 +#define MXC_PLL_DP_CONFIG_LDREQ 0x1 + +#define MXC_PLL_DP_OP_MFI_OFFSET 4 +#define MXC_PLL_DP_OP_MFI_MASK (0xF << 4) +#define MXC_PLL_DP_OP_PDF_OFFSET 0 +#define MXC_PLL_DP_OP_PDF_MASK 0xF + +#define MXC_PLL_DP_MFD_OFFSET 0 +#define MXC_PLL_DP_MFD_MASK 0x07FFFFFF + +#define MXC_PLL_DP_MFN_OFFSET 0x0 +#define MXC_PLL_DP_MFN_MASK 0x07FFFFFF + +#define MXC_PLL_DP_MFN_TOGC_TOG_DIS (1 << 17) +#define MXC_PLL_DP_MFN_TOGC_TOG_EN (1 << 16) +#define MXC_PLL_DP_MFN_TOGC_CNT_OFFSET 0x0 +#define MXC_PLL_DP_MFN_TOGC_CNT_MASK 0xFFFF + +#define MXC_PLL_DP_DESTAT_TOG_SEL (1 << 31) +#define MXC_PLL_DP_DESTAT_MFN 0x07FFFFFF + +/* Register addresses of CCM*/ +#define MXC_CCM_CCR (MXC_CCM_BASE + 0x00) +#define MXC_CCM_CCDR (MXC_CCM_BASE + 0x04) +#define MXC_CCM_CSR (MXC_CCM_BASE + 0x08) +#define MXC_CCM_CCSR (MXC_CCM_BASE + 0x0C) +#define MXC_CCM_CACRR (MXC_CCM_BASE + 0x10) +#define MXC_CCM_CBCDR (MXC_CCM_BASE + 0x14) +#define MXC_CCM_CBCMR (MXC_CCM_BASE + 0x18) +#define MXC_CCM_CSCMR1 (MXC_CCM_BASE + 0x1C) +#define MXC_CCM_CSCMR2 (MXC_CCM_BASE + 0x20) +#define MXC_CCM_CSCDR1 (MXC_CCM_BASE + 0x24) +#define MXC_CCM_CS1CDR (MXC_CCM_BASE + 0x28) +#define MXC_CCM_CS2CDR (MXC_CCM_BASE + 0x2C) +#define MXC_CCM_CDCDR (MXC_CCM_BASE + 0x30) +#define MXC_CCM_CHSCDR (MXC_CCM_BASE + 0x34) +#define MXC_CCM_CSCDR2 (MXC_CCM_BASE + 0x38) +#define MXC_CCM_CSCDR3 (MXC_CCM_BASE + 0x3C) +#define MXC_CCM_CSCDR4 (MXC_CCM_BASE + 0x40) +#define MXC_CCM_CWDR (MXC_CCM_BASE + 0x44) +#define MXC_CCM_CDHIPR (MXC_CCM_BASE + 0x48) +#define MXC_CCM_CDCR (MXC_CCM_BASE + 0x4C) +#define MXC_CCM_CTOR (MXC_CCM_BASE + 0x50) +#define MXC_CCM_CLPCR (MXC_CCM_BASE + 0x54) +#define MXC_CCM_CISR (MXC_CCM_BASE + 0x58) +#define MXC_CCM_CIMR (MXC_CCM_BASE + 0x5C) +#define MXC_CCM_CCOSR (MXC_CCM_BASE + 0x60) +#define MXC_CCM_CGPR (MXC_CCM_BASE + 0x64) +#define MXC_CCM_CCGR0 (MXC_CCM_BASE + 0x68) +#define MXC_CCM_CCGR1 (MXC_CCM_BASE + 0x6C) +#define MXC_CCM_CCGR2 (MXC_CCM_BASE + 0x70) +#define MXC_CCM_CCGR3 (MXC_CCM_BASE + 0x74) +#define MXC_CCM_CCGR4 (MXC_CCM_BASE + 0x78) +#define MXC_CCM_CCGR5 (MXC_CCM_BASE + 0x7C) +#define MXC_CCM_CCGR6 (MXC_CCM_BASE + 0x80) +#define MXC_CCM_CMEOR (MXC_CCM_BASE + 0x84) + +/* Define the bits in register CCR */ +#define MXC_CCM_CCR_COSC_EN (1 << 12) +#define MXC_CCM_CCR_FPM_MULT_MASK (1 << 11) +#define MXC_CCM_CCR_CAMP2_EN (1 << 10) +#define MXC_CCM_CCR_CAMP1_EN (1 << 9) +#define MXC_CCM_CCR_FPM_EN (1 << 8) +#define MXC_CCM_CCR_OSCNT_OFFSET (0) +#define MXC_CCM_CCR_OSCNT_MASK (0xFF) + +/* Define the bits in register CCDR */ +#define MXC_CCM_CCDR_HSC_HS_MASK (0x1 << 18) +#define MXC_CCM_CCDR_IPU_HS_MASK (0x1 << 17) +#define MXC_CCM_CCDR_EMI_HS_MASK (0x1 << 16) + +/* Define the bits in register CSR */ +#define MXC_CCM_CSR_COSR_READY (1 << 5) +#define MXC_CCM_CSR_LVS_VALUE (1 << 4) +#define MXC_CCM_CSR_CAMP2_READY (1 << 3) +#define MXC_CCM_CSR_CAMP1_READY (1 << 2) +#define MXC_CCM_CSR_FPM_READY (1 << 1) +#define MXC_CCM_CSR_REF_EN_B (1 << 0) + +/* Define the bits in register CCSR */ +#define MXC_CCM_CCSR_LP_APM_SEL (0x1 << 9) +#define MXC_CCM_CCSR_STEP_SEL_OFFSET (7) +#define MXC_CCM_CCSR_STEP_SEL_MASK (0x3 << 7) +#define MXC_CCM_CCSR_PLL2_PODF_OFFSET (5) +#define MXC_CCM_CCSR_PLL2_PODF_MASK (0x3 << 5) +#define MXC_CCM_CCSR_PLL3_PODF_OFFSET (3) +#define MXC_CCM_CCSR_PLL3_PODF_MASK (0x3 << 3) +#define MXC_CCM_CCSR_PLL1_SW_CLK_SEL (1 << 2) +#define MXC_CCM_CCSR_PLL2_SW_CLK_SEL (1 << 1) +#define MXC_CCM_CCSR_PLL3_SW_CLK_SEL (1 << 0) + +/* Define the bits in register CACRR */ +#define MXC_CCM_CACRR_ARM_PODF_OFFSET (0) +#define MXC_CCM_CACRR_ARM_PODF_MASK (0x7) + +/* Define the bits in register CBCDR */ +#define MXC_CCM_CBCDR_EMI_CLK_SEL (0x1 << 26) +#define MXC_CCM_CBCDR_PERIPH_CLK_SEL (0x1 << 25) +#define MXC_CCM_CBCDR_DDR_HF_SEL_OFFSET (30) +#define MXC_CCM_CBCDR_DDR_HF_SEL (0x1 << 30) +#define MXC_CCM_CBCDR_DDR_PODF_OFFSET (27) +#define MXC_CCM_CBCDR_DDR_PODF_MASK (0x7 << 27) +#define MXC_CCM_CBCDR_EMI_PODF_OFFSET (22) +#define MXC_CCM_CBCDR_EMI_PODF_MASK (0x7 << 22) +#define MXC_CCM_CBCDR_AXI_B_PODF_OFFSET (19) +#define MXC_CCM_CBCDR_AXI_B_PODF_MASK (0x7 << 19) +#define MXC_CCM_CBCDR_AXI_A_PODF_OFFSET (16) +#define MXC_CCM_CBCDR_AXI_A_PODF_MASK (0x7 << 16) +#define MXC_CCM_CBCDR_NFC_PODF_OFFSET (13) +#define MXC_CCM_CBCDR_NFC_PODF_MASK (0x7 << 13) +#define MXC_CCM_CBCDR_AHB_PODF_OFFSET (10) +#define MXC_CCM_CBCDR_AHB_PODF_MASK (0x7 << 10) +#define MXC_CCM_CBCDR_IPG_PODF_OFFSET (8) +#define MXC_CCM_CBCDR_IPG_PODF_MASK (0x3 << 8) +#define MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET (6) +#define MXC_CCM_CBCDR_PERCLK_PRED1_MASK (0x3 << 6) +#define MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET (3) +#define MXC_CCM_CBCDR_PERCLK_PRED2_MASK (0x7 << 3) +#define MXC_CCM_CBCDR_PERCLK_PODF_OFFSET (0) +#define MXC_CCM_CBCDR_PERCLK_PODF_MASK (0x7) + +/* Define the bits in register CBCMR */ +#define MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_OFFSET (14) +#define MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_MASK (0x3 << 14) +#define MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET (12) +#define MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK (0x3 << 12) +#define MXC_CCM_CBCMR_DDR_CLK_SEL_OFFSET (10) +#define MXC_CCM_CBCMR_DDR_CLK_SEL_MASK (0x3 << 10) +#define MXC_CCM_CBCMR_ARM_AXI_CLK_SEL_OFFSET (8) +#define MXC_CCM_CBCMR_ARM_AXI_CLK_SEL_MASK (0x3 << 8) +#define MXC_CCM_CBCMR_IPU_HSP_CLK_SEL_OFFSET (6) +#define MXC_CCM_CBCMR_IPU_HSP_CLK_SEL_MASK (0x3 << 6) +#define MXC_CCM_CBCMR_GPU_CLK_SEL_OFFSET (4) +#define MXC_CCM_CBCMR_GPU_CLK_SEL_MASK (0x3 << 4) +#define MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL (0x1 << 1) +#define MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL (0x1 << 0) + +/* Define the bits in register CSCMR1 */ +#define MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_OFFSET (30) +#define MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_MASK (0x3 << 30) +#define MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_OFFSET (28) +#define MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_MASK (0x3 << 28) +#define MXC_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET (26) +#define MXC_CCM_CSCMR1_USB_PHY_CLK_SEL (0x1 << 26) +#define MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET (24) +#define MXC_CCM_CSCMR1_UART_CLK_SEL_MASK (0x3 << 24) +#define MXC_CCM_CSCMR1_USBOH3_CLK_SEL_OFFSET (22) +#define MXC_CCM_CSCMR1_USBOH3_CLK_SEL_MASK (0x3 << 22) +#define MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_OFFSET (20) +#define MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_MASK (0x3 << 20) +#define MXC_CCM_CSCMR1_ESDHC3_CLK_SEL (0x1 << 19) +#define MXC_CCM_CSCMR1_ESDHC4_CLK_SEL (0x1 << 18) +#define MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_OFFSET (16) +#define MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_MASK (0x3 << 16) +#define MXC_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET (14) +#define MXC_CCM_CSCMR1_SSI1_CLK_SEL_MASK (0x3 << 14) +#define MXC_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET (12) +#define MXC_CCM_CSCMR1_SSI2_CLK_SEL_MASK (0x3 << 12) +#define MXC_CCM_CSCMR1_SSI3_CLK_SEL (0x1 << 11) +#define MXC_CCM_CSCMR1_VPU_RCLK_SEL (0x1 << 10) +#define MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_OFFSET (8) +#define MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_MASK (0x3 << 8) +#define MXC_CCM_CSCMR1_TVE_CLK_SEL (0x1 << 7) +#define MXC_CCM_CSCMR1_TVE_EXT_CLK_SEL (0x1 << 6) +#define MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET (4) +#define MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK (0x3 << 4) +#define MXC_CCM_CSCMR1_SPDIF_CLK_SEL_OFFSET (2) +#define MXC_CCM_CSCMR1_SPDIF_CLK_SEL_MASK (0x3 << 2) +#define MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL (0x1 << 1) +#define MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL (0x1) + +/* Define the bits in register CSCMR2 */ +#define MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET (26) +#define MXC_CCM_CSCMR2_DI_CLK_SEL_MASK (0x7 << 26) +#define MXC_CCM_CSCMR2_CSI_MCLK2_CLK_SEL_OFFSET (24) +#define MXC_CCM_CSCMR2_CSI_MCLK2_CLK_SEL_MASK (0x3 << 24) +#define MXC_CCM_CSCMR2_CSI_MCLK1_CLK_SEL_OFFSET (22) +#define MXC_CCM_CSCMR2_CSI_MCLK1_CLK_SEL_MASK (0x3 << 22) +#define MXC_CCM_CSCMR2_ESC_CLK_SEL_OFFSET (20) +#define MXC_CCM_CSCMR2_ESC_CLK_SEL_MASK (0x3 << 20) +#define MXC_CCM_CSCMR2_HSC2_CLK_SEL_OFFSET (18) +#define MXC_CCM_CSCMR2_HSC2_CLK_SEL_MASK (0x3 << 18) +#define MXC_CCM_CSCMR2_HSC1_CLK_SEL_OFFSET (16) +#define MXC_CCM_CSCMR2_HSC1_CLK_SEL_MASK (0x3 << 16) +#define MXC_CCM_CSCMR2_HSI2C_CLK_SEL_OFFSET (14) +#define MXC_CCM_CSCMR2_HSI2C_CLK_SEL_MASK (0x3 << 14) +#define MXC_CCM_CSCMR2_FIRI_CLK_SEL_OFFSET (12) +#define MXC_CCM_CSCMR2_FIRI_CLK_SEL_MASK (0x3 << 12) +#define MXC_CCM_CSCMR2_SIM_CLK_SEL_OFFSET (10) +#define MXC_CCM_CSCMR2_SIM_CLK_SEL_MASK (0x3 << 10) +#define MXC_CCM_CSCMR2_SLIMBUS_COM (0x1 << 9) +#define MXC_CCM_CSCMR2_SLIMBUS_CLK_SEL_OFFSET (6) +#define MXC_CCM_CSCMR2_SLIMBUS_CLK_SEL_MASK (0x7 << 6) +#define MXC_CCM_CSCMR2_SPDIF1_COM (1 << 5) +#define MXC_CCM_CSCMR2_SPDIF0_COM (1 << 4) +#define MXC_CCM_CSCMR2_SPDIF1_CLK_SEL_OFFSET (2) +#define MXC_CCM_CSCMR2_SPDIF1_CLK_SEL_MASK (0x3 << 2) +#define MXC_CCM_CSCMR2_SPDIF0_CLK_SEL_OFFSET (0) +#define MXC_CCM_CSCMR2_SPDIF0_CLK_SEL_MASK (0x3) + +/* Define the bits in register CSCDR1 */ +#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_OFFSET (22) +#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_MASK (0x7 << 22) +#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_OFFSET (19) +#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_MASK (0x7 << 19) +#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_OFFSET (16) +#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_MASK (0x7 << 16) +#define MXC_CCM_CSCDR1_PGC_CLK_PODF_OFFSET (14) +#define MXC_CCM_CSCDR1_PGC_CLK_PODF_MASK (0x3 << 14) +#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_OFFSET (11) +#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_MASK (0x7 << 11) +#define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET (8) +#define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK (0x7 << 8) +#define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET (6) +#define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK (0x3 << 6) +#define MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET (3) +#define MXC_CCM_CSCDR1_UART_CLK_PRED_MASK (0x7 << 3) +#define MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET (0) +#define MXC_CCM_CSCDR1_UART_CLK_PODF_MASK (0x7) + +/* Define the bits in register CS1CDR and CS2CDR */ +#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_OFFSET (22) +#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_MASK (0x7 << 22) +#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_OFFSET (16) +#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_MASK (0x3F << 16) +#define MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET (6) +#define MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK (0x7 << 6) +#define MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET (0) +#define MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK (0x3F) + +#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_OFFSET (22) +#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_MASK (0x7 << 22) +#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_OFFSET (16) +#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_MASK (0x3F << 16) +#define MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET (6) +#define MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK (0x7 << 6) +#define MXC_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET (0) +#define MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK (0x3F) + +/* Define the bits in register CDCDR */ +#define MXC_CCM_CDCDR_TVE_CLK_PRED_OFFSET (28) +#define MXC_CCM_CDCDR_TVE_CLK_PRED_MASK (0x7 << 28) +#define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_OFFSET (25) +#define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK (0x7 << 25) +#define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_OFFSET (19) +#define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK (0x3F << 19) +#define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_OFFSET (16) +#define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_MASK (0x7 << 16) +#define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_OFFSET (9) +#define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_MASK (0x3F << 9) +#define MXC_CCM_CDCDR_DI_CLK_PRED_OFFSET (6) +#define MXC_CCM_CDCDR_DI_CLK_PRED_MASK (0x7 << 6) +#define MXC_CCM_CDCDR_USB_PHY_PRED_OFFSET (3) +#define MXC_CCM_CDCDR_USB_PHY_PRED_MASK (0x7 << 3) +#define MXC_CCM_CDCDR_USB_PHY_PODF_OFFSET (0) +#define MXC_CCM_CDCDR_USB_PHY_PODF_MASK (0x7) + +/* Define the bits in register CHSCCDR */ +#define MXC_CCM_CHSCCDR_ESC_CLK_PRED_OFFSET (12) +#define MXC_CCM_CHSCCDR_ESC_CLK_PRED_MASK (0x7 << 12) +#define MXC_CCM_CHSCCDR_ESC_CLK_PODF_OFFSET (6) +#define MXC_CCM_CHSCCDR_ESC_CLK_PODF_MASK (0x3F << 6) +#define MXC_CCM_CHSCCDR_HSC2_CLK_PODF_OFFSET (3) +#define MXC_CCM_CHSCCDR_HSC2_CLK_PODF_MASK (0x7 << 3) +#define MXC_CCM_CHSCCDR_HSC1_CLK_PODF_OFFSET (0) +#define MXC_CCM_CHSCCDR_HSC1_CLK_PODF_MASK (0x7) + +/* Define the bits in register CSCDR2 */ +#define MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET (25) +#define MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK (0x7 << 25) +#define MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET (19) +#define MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK (0x3F << 19) +#define MXC_CCM_CSCDR2_SIM_CLK_PRED_OFFSET (16) +#define MXC_CCM_CSCDR2_SIM_CLK_PRED_MASK (0x7 << 16) +#define MXC_CCM_CSCDR2_SIM_CLK_PODF_OFFSET (9) +#define MXC_CCM_CSCDR2_SIM_CLK_PODF_MASK (0x3F << 9) +#define MXC_CCM_CSCDR2_SLIMBUS_CLK_PRED_OFFSET (6) +#define MXC_CCM_CSCDR2_SLIMBUS_PRED_MASK (0x7 << 6) +#define MXC_CCM_CSCDR2_SLIMBUS_PODF_OFFSET (0) +#define MXC_CCM_CSCDR2_SLIMBUS_PODF_MASK (0x3F) + +/* Define the bits in register CSCDR3 */ +#define MXC_CCM_CSCDR3_HSI2C_CLK_PRED_OFFSET (16) +#define MXC_CCM_CSCDR3_HSI2C_CLK_PRED_MASK (0x7 << 16) +#define MXC_CCM_CSCDR3_HSI2C_CLK_PODF_OFFSET (9) +#define MXC_CCM_CSCDR3_HSI2C_CLK_PODF_MASK (0x3F << 9) +#define MXC_CCM_CSCDR3_FIRI_CLK_PRED_OFFSET (6) +#define MXC_CCM_CSCDR3_FIRI_CLK_PRED_MASK (0x7 << 6) +#define MXC_CCM_CSCDR3_FIRI_CLK_PODF_OFFSET (0) +#define MXC_CCM_CSCDR3_FIRI_CLK_PODF_MASK (0x3F) + +/* Define the bits in register CSCDR4 */ +#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_OFFSET (16) +#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_MASK (0x7 << 16) +#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_OFFSET (9) +#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_MASK (0x3F << 9) +#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_OFFSET (6) +#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_MASK (0x7 << 6) +#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_OFFSET (0) +#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_MASK (0x3F) + +/* Define the bits in register CDHIPR */ +#define MXC_CCM_CDHIPR_ARM_PODF_BUSY (1 << 16) +#define MXC_CCM_CDHIPR_EMI_CLK_SEL_BUSY (1 << 6) +#define MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY (1 << 5) +#define MXC_CCM_CDHIPR_NFC_IPG_INT_MEM_PODF_BUSY (1 << 4) +#define MXC_CCM_CDHIPR_AHB_PODF_BUSY (1 << 3) +#define MXC_CCM_CDHIPR_EMI_PODF_BUSY (1 << 2) +#define MXC_CCM_CDHIPR_AXI_B_PODF_BUSY (1 << 1) +#define MXC_CCM_CDHIPR_AXI_A_PODF_BUSY (1 << 0) + +/* Define the bits in register CDCR */ +#define MXC_CCM_CDCR_ARM_FREQ_SHIFT_DIVIDER (0x1 << 2) +#define MXC_CCM_CDCR_PERIPH_CLK_DVFS_PODF_OFFSET (0) +#define MXC_CCM_CDCR_PERIPH_CLK_DVFS_PODF_MASK (0x3) + +/* Define the bits in register CLPCR */ +#define MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS (0x1 << 23) +#define MXC_CCM_CLPCR_BYPASS_SCC_LPM_HS (0x1 << 22) +#define MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS (0x1 << 21) +#define MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS (0x1 << 20) +#define MXC_CCM_CLPCR_BYPASS_EMI_LPM_HS (0x1 << 19) +#define MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS (0x1 << 18) +#define MXC_CCM_CLPCR_BYPASS_RTIC_LPM_HS (0x1 << 17) +#define MXC_CCM_CLPCR_BYPASS_RNGC_LPM_HS (0x1 << 16) +#define MXC_CCM_CLPCR_COSC_PWRDOWN (0x1 << 11) +#define MXC_CCM_CLPCR_STBY_COUNT_OFFSET (9) +#define MXC_CCM_CLPCR_STBY_COUNT_MASK (0x3 << 9) +#define MXC_CCM_CLPCR_VSTBY (0x1 << 8) +#define MXC_CCM_CLPCR_DIS_REF_OSC (0x1 << 7) +#define MXC_CCM_CLPCR_SBYOS (0x1 << 6) +#define MXC_CCM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5) +#define MXC_CCM_CLPCR_LPSR_CLK_SEL_OFFSET (3) +#define MXC_CCM_CLPCR_LPSR_CLK_SEL_MASK (0x3 << 3) +#define MXC_CCM_CLPCR_LPM_OFFSET (0) +#define MXC_CCM_CLPCR_LPM_MASK (0x3) + +/* Define the bits in register CISR */ +#define MXC_CCM_CISR_ARM_PODF_LOADED (0x1 << 25) +#define MXC_CCM_CISR_NFC_IPG_INT_MEM_PODF_LOADED (0x1 << 21) +#define MXC_CCM_CISR_AHB_PODF_LOADED (0x1 << 20) +#define MXC_CCM_CISR_EMI_PODF_LOADED (0x1 << 19) +#define MXC_CCM_CISR_AXI_B_PODF_LOADED (0x1 << 18) +#define MXC_CCM_CISR_AXI_A_PODF_LOADED (0x1 << 17) +#define MXC_CCM_CISR_DIVIDER_LOADED (0x1 << 16) +#define MXC_CCM_CISR_COSC_READY (0x1 << 6) +#define MXC_CCM_CISR_CKIH2_READY (0x1 << 5) +#define MXC_CCM_CISR_CKIH_READY (0x1 << 4) +#define MXC_CCM_CISR_FPM_READY (0x1 << 3) +#define MXC_CCM_CISR_LRF_PLL3 (0x1 << 2) +#define MXC_CCM_CISR_LRF_PLL2 (0x1 << 1) +#define MXC_CCM_CISR_LRF_PLL1 (0x1) + +/* Define the bits in register CIMR */ +#define MXC_CCM_CIMR_MASK_ARM_PODF_LOADED (0x1 << 25) +#define MXC_CCM_CIMR_MASK_NFC_IPG_INT_MEM_PODF_LOADED (0x1 << 21) +#define MXC_CCM_CIMR_MASK_EMI_PODF_LOADED (0x1 << 20) +#define MXC_CCM_CIMR_MASK_AXI_C_PODF_LOADED (0x1 << 19) +#define MXC_CCM_CIMR_MASK_AXI_B_PODF_LOADED (0x1 << 18) +#define MXC_CCM_CIMR_MASK_AXI_A_PODF_LOADED (0x1 << 17) +#define MXC_CCM_CIMR_MASK_DIVIDER_LOADED (0x1 << 16) +#define MXC_CCM_CIMR_MASK_COSC_READY (0x1 << 5) +#define MXC_CCM_CIMR_MASK_CKIH_READY (0x1 << 4) +#define MXC_CCM_CIMR_MASK_FPM_READY (0x1 << 3) +#define MXC_CCM_CIMR_MASK_LRF_PLL3 (0x1 << 2) +#define MXC_CCM_CIMR_MASK_LRF_PLL2 (0x1 << 1) +#define MXC_CCM_CIMR_MASK_LRF_PLL1 (0x1) + +/* Define the bits in register CCOSR */ +#define MXC_CCM_CCOSR_CKO2_EN_OFFSET (0x1 << 24) +#define MXC_CCM_CCOSR_CKO2_DIV_OFFSET (21) +#define MXC_CCM_CCOSR_CKO2_DIV_MASK (0x7 << 21) +#define MXC_CCM_CCOSR_CKO2_SEL_OFFSET (16) +#define MXC_CCM_CCOSR_CKO2_SEL_MASK (0x1F << 16) +#define MXC_CCM_CCOSR_CKOL_EN (0x1 << 7) +#define MXC_CCM_CCOSR_CKOL_DIV_OFFSET (4) +#define MXC_CCM_CCOSR_CKOL_DIV_MASK (0x7 << 4) +#define MXC_CCM_CCOSR_CKOL_SEL_OFFSET (0) +#define MXC_CCM_CCOSR_CKOL_SEL_MASK (0xF) + +/* Define the bits in registers CGPR */ +#define MXC_CCM_CGPR_EFUSE_PROG_SUPPLY_GATE (0x1 << 4) +#define MXC_CCM_CGPR_FPM_SEL (0x1 << 3) +#define MXC_CCM_CGPR_VL_L2BIST_CLKDIV_OFFSET (0) +#define MXC_CCM_CGPR_VL_L2BIST_CLKDIV_MASK (0x7) + +/* Define the bits in registers CCGRx */ +#define MXC_CCM_CCGR_CG_MASK 0x3 + +#define MXC_CCM_CCGR0_CG15_OFFSET 30 +#define MXC_CCM_CCGR0_CG15_MASK (0x3 << 30) +#define MXC_CCM_CCGR0_CG14_OFFSET 28 +#define MXC_CCM_CCGR0_CG14_MASK (0x3 << 28) +#define MXC_CCM_CCGR0_CG13_OFFSET 26 +#define MXC_CCM_CCGR0_CG13_MASK (0x3 << 26) +#define MXC_CCM_CCGR0_CG12_OFFSET 24 +#define MXC_CCM_CCGR0_CG12_MASK (0x3 << 24) +#define MXC_CCM_CCGR0_CG11_OFFSET 22 +#define MXC_CCM_CCGR0_CG11_MASK (0x3 << 22) +#define MXC_CCM_CCGR0_CG10_OFFSET 20 +#define MXC_CCM_CCGR0_CG10_MASK (0x3 << 20) +#define MXC_CCM_CCGR0_CG9_OFFSET 18 +#define MXC_CCM_CCGR0_CG9_MASK (0x3 << 18) +#define MXC_CCM_CCGR0_CG8_OFFSET 16 +#define MXC_CCM_CCGR0_CG8_MASK (0x3 << 16) +#define MXC_CCM_CCGR0_CG7_OFFSET 14 +#define MXC_CCM_CCGR0_CG6_OFFSET 12 +#define MXC_CCM_CCGR0_CG5_OFFSET 10 +#define MXC_CCM_CCGR0_CG5_MASK (0x3 << 10) +#define MXC_CCM_CCGR0_CG4_OFFSET 8 +#define MXC_CCM_CCGR0_CG4_MASK (0x3 << 8) +#define MXC_CCM_CCGR0_CG3_OFFSET 6 +#define MXC_CCM_CCGR0_CG3_MASK (0x3 << 6) +#define MXC_CCM_CCGR0_CG2_OFFSET 4 +#define MXC_CCM_CCGR0_CG2_MASK (0x3 << 4) +#define MXC_CCM_CCGR0_CG1_OFFSET 2 +#define MXC_CCM_CCGR0_CG1_MASK (0x3 << 2) +#define MXC_CCM_CCGR0_CG0_OFFSET 0 +#define MXC_CCM_CCGR0_CG0_MASK 0x3 + +#define MXC_CCM_CCGR1_CG15_OFFSET 30 +#define MXC_CCM_CCGR1_CG14_OFFSET 28 +#define MXC_CCM_CCGR1_CG13_OFFSET 26 +#define MXC_CCM_CCGR1_CG12_OFFSET 24 +#define MXC_CCM_CCGR1_CG11_OFFSET 22 +#define MXC_CCM_CCGR1_CG10_OFFSET 20 +#define MXC_CCM_CCGR1_CG9_OFFSET 18 +#define MXC_CCM_CCGR1_CG8_OFFSET 16 +#define MXC_CCM_CCGR1_CG7_OFFSET 14 +#define MXC_CCM_CCGR1_CG6_OFFSET 12 +#define MXC_CCM_CCGR1_CG5_OFFSET 10 +#define MXC_CCM_CCGR1_CG4_OFFSET 8 +#define MXC_CCM_CCGR1_CG3_OFFSET 6 +#define MXC_CCM_CCGR1_CG2_OFFSET 4 +#define MXC_CCM_CCGR1_CG1_OFFSET 2 +#define MXC_CCM_CCGR1_CG0_OFFSET 0 + +#define MXC_CCM_CCGR2_CG15_OFFSET 30 +#define MXC_CCM_CCGR2_CG14_OFFSET 28 +#define MXC_CCM_CCGR2_CG13_OFFSET 26 +#define MXC_CCM_CCGR2_CG12_OFFSET 24 +#define MXC_CCM_CCGR2_CG11_OFFSET 22 +#define MXC_CCM_CCGR2_CG10_OFFSET 20 +#define MXC_CCM_CCGR2_CG9_OFFSET 18 +#define MXC_CCM_CCGR2_CG8_OFFSET 16 +#define MXC_CCM_CCGR2_CG7_OFFSET 14 +#define MXC_CCM_CCGR2_CG6_OFFSET 12 +#define MXC_CCM_CCGR2_CG5_OFFSET 10 +#define MXC_CCM_CCGR2_CG4_OFFSET 8 +#define MXC_CCM_CCGR2_CG3_OFFSET 6 +#define MXC_CCM_CCGR2_CG2_OFFSET 4 +#define MXC_CCM_CCGR2_CG1_OFFSET 2 +#define MXC_CCM_CCGR2_CG0_OFFSET 0 + +#define MXC_CCM_CCGR3_CG15_OFFSET 30 +#define MXC_CCM_CCGR3_CG14_OFFSET 28 +#define MXC_CCM_CCGR3_CG13_OFFSET 26 +#define MXC_CCM_CCGR3_CG12_OFFSET 24 +#define MXC_CCM_CCGR3_CG11_OFFSET 22 +#define MXC_CCM_CCGR3_CG10_OFFSET 20 +#define MXC_CCM_CCGR3_CG9_OFFSET 18 +#define MXC_CCM_CCGR3_CG8_OFFSET 16 +#define MXC_CCM_CCGR3_CG7_OFFSET 14 +#define MXC_CCM_CCGR3_CG6_OFFSET 12 +#define MXC_CCM_CCGR3_CG5_OFFSET 10 +#define MXC_CCM_CCGR3_CG4_OFFSET 8 +#define MXC_CCM_CCGR3_CG3_OFFSET 6 +#define MXC_CCM_CCGR3_CG2_OFFSET 4 +#define MXC_CCM_CCGR3_CG1_OFFSET 2 +#define MXC_CCM_CCGR3_CG0_OFFSET 0 + +#define MXC_CCM_CCGR4_CG15_OFFSET 30 +#define MXC_CCM_CCGR4_CG14_OFFSET 28 +#define MXC_CCM_CCGR4_CG13_OFFSET 26 +#define MXC_CCM_CCGR4_CG12_OFFSET 24 +#define MXC_CCM_CCGR4_CG11_OFFSET 22 +#define MXC_CCM_CCGR4_CG10_OFFSET 20 +#define MXC_CCM_CCGR4_CG9_OFFSET 18 +#define MXC_CCM_CCGR4_CG8_OFFSET 16 +#define MXC_CCM_CCGR4_CG7_OFFSET 14 +#define MXC_CCM_CCGR4_CG6_OFFSET 12 +#define MXC_CCM_CCGR4_CG5_OFFSET 10 +#define MXC_CCM_CCGR4_CG4_OFFSET 8 +#define MXC_CCM_CCGR4_CG3_OFFSET 6 +#define MXC_CCM_CCGR4_CG2_OFFSET 4 +#define MXC_CCM_CCGR4_CG1_OFFSET 2 +#define MXC_CCM_CCGR4_CG0_OFFSET 0 + +#define MXC_CCM_CCGR5_CG15_OFFSET 30 +#define MXC_CCM_CCGR5_CG14_OFFSET 28 +#define MXC_CCM_CCGR5_CG14_MASK (0x3 << 28) +#define MXC_CCM_CCGR5_CG13_OFFSET 26 +#define MXC_CCM_CCGR5_CG13_MASK (0x3 << 26) +#define MXC_CCM_CCGR5_CG12_OFFSET 24 +#define MXC_CCM_CCGR5_CG12_MASK (0x3 << 24) +#define MXC_CCM_CCGR5_CG11_OFFSET 22 +#define MXC_CCM_CCGR5_CG11_MASK (0x3 << 22) +#define MXC_CCM_CCGR5_CG10_OFFSET 20 +#define MXC_CCM_CCGR5_CG10_MASK (0x3 << 20) +#define MXC_CCM_CCGR5_CG9_OFFSET 18 +#define MXC_CCM_CCGR5_CG9_MASK (0x3 << 18) +#define MXC_CCM_CCGR5_CG8_OFFSET 16 +#define MXC_CCM_CCGR5_CG8_MASK (0x3 << 16) +#define MXC_CCM_CCGR5_CG7_OFFSET 14 +#define MXC_CCM_CCGR5_CG7_MASK (0x3 << 14) +#define MXC_CCM_CCGR5_CG6_OFFSET 12 +#define MXC_CCM_CCGR5_CG5_OFFSET 10 +#define MXC_CCM_CCGR5_CG4_OFFSET 8 +#define MXC_CCM_CCGR5_CG3_OFFSET 6 +#define MXC_CCM_CCGR5_CG2_OFFSET 4 +#define MXC_CCM_CCGR5_CG2_MASK (0x3 << 4) +#define MXC_CCM_CCGR5_CG1_OFFSET 2 +#define MXC_CCM_CCGR5_CG0_OFFSET 0 + +#define MXC_CCM_CCGR6_CG4_OFFSET 8 +#define MXC_CCM_CCGR6_CG4_MASK (0x3 << 8) +#define MXC_CCM_CCGR6_CG3_OFFSET 6 +#define MXC_CCM_CCGR6_CG2_OFFSET 4 +#define MXC_CCM_CCGR6_CG1_OFFSET 2 +#define MXC_CCM_CCGR6_CG0_OFFSET 0 + +#define MXC_CORTEXA8_BASE IO_ADDRESS(ARM_BASE_ADDR) +#define MXC_GPC_BASE IO_ADDRESS(GPC_BASE_ADDR) +#define MXC_DPTC_LP_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x80) +#define MXC_DPTC_GP_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x100) +#define MXC_DVFS_CORE_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x180) +#define MXC_DPTC_PER_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x1C0) +#define MXC_PGC_IPU_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x220) +#define MXC_PGC_VPU_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x240) +#define MXC_PGC_GPU_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x260) +#define MXC_SRPG_NEON_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x280) +#define MXC_SRPG_ARM_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x2A0) +#define MXC_SRPG_EMPGC0_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x2C0) +#define MXC_SRPG_EMPGC1_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x2D0) +#define MXC_SRPG_MEGAMIX_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x2E0) +#define MXC_SRPG_EMI_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x300) + +/* CORTEXA8 platform */ +#define MXC_CORTEXA8_PLAT_PVID (MXC_CORTEXA8_BASE + 0x0) +#define MXC_CORTEXA8_PLAT_GPC (MXC_CORTEXA8_BASE + 0x4) +#define MXC_CORTEXA8_PLAT_PIC (MXC_CORTEXA8_BASE + 0x8) +#define MXC_CORTEXA8_PLAT_LPC (MXC_CORTEXA8_BASE + 0xC) +#define MXC_CORTEXA8_PLAT_NEON_LPC (MXC_CORTEXA8_BASE + 0x10) +#define MXC_CORTEXA8_PLAT_ICGC (MXC_CORTEXA8_BASE + 0x14) +#define MXC_CORTEXA8_PLAT_AMC (MXC_CORTEXA8_BASE + 0x18) +#define MXC_CORTEXA8_PLAT_NMC (MXC_CORTEXA8_BASE + 0x20) +#define MXC_CORTEXA8_PLAT_NMS (MXC_CORTEXA8_BASE + 0x24) + +/* DVFS CORE */ +#define MXC_DVFSTHRS (MXC_DVFS_CORE_BASE + 0x00) +#define MXC_DVFSCOUN (MXC_DVFS_CORE_BASE + 0x04) +#define MXC_DVFSSIG1 (MXC_DVFS_CORE_BASE + 0x08) +#define MXC_DVFSSIG0 (MXC_DVFS_CORE_BASE + 0x0C) +#define MXC_DVFSGPC0 (MXC_DVFS_CORE_BASE + 0x10) +#define MXC_DVFSGPC1 (MXC_DVFS_CORE_BASE + 0x14) +#define MXC_DVFSGPBT (MXC_DVFS_CORE_BASE + 0x18) +#define MXC_DVFSEMAC (MXC_DVFS_CORE_BASE + 0x1C) +#define MXC_DVFSCNTR (MXC_DVFS_CORE_BASE + 0x20) +#define MXC_DVFSLTR0_0 (MXC_DVFS_CORE_BASE + 0x24) +#define MXC_DVFSLTR0_1 (MXC_DVFS_CORE_BASE + 0x28) +#define MXC_DVFSLTR1_0 (MXC_DVFS_CORE_BASE + 0x2C) +#define MXC_DVFSLTR1_1 (MXC_DVFS_CORE_BASE + 0x30) +#define MXC_DVFSPT0 (MXC_DVFS_CORE_BASE + 0x34) +#define MXC_DVFSPT1 (MXC_DVFS_CORE_BASE + 0x38) +#define MXC_DVFSPT2 (MXC_DVFS_CORE_BASE + 0x3C) +#define MXC_DVFSPT3 (MXC_DVFS_CORE_BASE + 0x40) + +/* GPC */ +#define MXC_GPC_CNTR (MXC_GPC_BASE + 0x0) +#define MXC_GPC_PGR (MXC_GPC_BASE + 0x4) +#define MXC_GPC_VCR (MXC_GPC_BASE + 0x8) +#define MXC_GPC_ALL_PU (MXC_GPC_BASE + 0xC) +#define MXC_GPC_NEON (MXC_GPC_BASE + 0x10) +#define MXC_GPC_PGR_ARMPG_OFFSET 8 +#define MXC_GPC_PGR_ARMPG_MASK (3 << 8) + +/* PGC */ +#define MXC_PGC_IPU_PGCR (MXC_PGC_IPU_BASE + 0x0) +#define MXC_PGC_IPU_PGSR (MXC_PGC_IPU_BASE + 0xC) +#define MXC_PGC_VPU_PGCR (MXC_PGC_VPU_BASE + 0x0) +#define MXC_PGC_VPU_PGSR (MXC_PGC_VPU_BASE + 0xC) +#define MXC_PGC_GPU_PGCR (MXC_PGC_GPU_BASE + 0x0) +#define MXC_PGC_GPU_PGSR (MXC_PGC_GPU_BASE + 0xC) + +#define MXC_PGCR_PCR 1 +#define MXC_SRPGCR_PCR 1 +#define MXC_EMPGCR_PCR 1 +#define MXC_PGSR_PSR 1 + + +#define MXC_CORTEXA8_PLAT_LPC_DSM (1 << 0) +#define MXC_CORTEXA8_PLAT_LPC_DBG_DSM (1 << 1) + +/* SRPG */ +#define MXC_SRPG_NEON_SRPGCR (MXC_SRPG_NEON_BASE + 0x0) +#define MXC_SRPG_NEON_PUPSCR (MXC_SRPG_NEON_BASE + 0x4) +#define MXC_SRPG_NEON_PDNSCR (MXC_SRPG_NEON_BASE + 0x8) + +#define MXC_SRPG_ARM_SRPGCR (MXC_SRPG_ARM_BASE + 0x0) +#define MXC_SRPG_ARM_PUPSCR (MXC_SRPG_ARM_BASE + 0x4) +#define MXC_SRPG_ARM_PDNSCR (MXC_SRPG_ARM_BASE + 0x8) + +#define MXC_SRPG_EMPGC0_SRPGCR (MXC_SRPG_EMPGC0_BASE + 0x0) +#define MXC_SRPG_EMPGC0_PUPSCR (MXC_SRPG_EMPGC0_BASE + 0x4) +#define MXC_SRPG_EMPGC0_PDNSCR (MXC_SRPG_EMPGC0_BASE + 0x8) + +#define MXC_SRPG_EMPGC1_SRPGCR (MXC_SRPG_EMPGC1_BASE + 0x0) +#define MXC_SRPG_EMPGC1_PUPSCR (MXC_SRPG_EMPGC1_BASE + 0x4) +#define MXC_SRPG_EMPGC1_PDNSCR (MXC_SRPG_EMPGC1_BASE + 0x8) + +#define MXC_SRPG_MEGAMIX_SRPGCR (MXC_SRPG_MEGAMIX_BASE + 0x0) +#define MXC_SRPG_MEGAMIX_PUPSCR (MXC_SRPG_MEGAMIX_BASE + 0x4) +#define MXC_SRPG_MEGAMIX_PDNSCR (MXC_SRPG_MEGAMIX_BASE + 0x8) + +#define MXC_SRPGC_EMI_SRPGCR (MXC_SRPGC_EMI_BASE + 0x0) +#define MXC_SRPGC_EMI_PUPSCR (MXC_SRPGC_EMI_BASE + 0x4) +#define MXC_SRPGC_EMI_PDNSCR (MXC_SRPGC_EMI_BASE + 0x8) + +#endif /* __ARCH_ARM_MACH_MX51_CRM_REGS_H__ */ --- linux-2.6.28.orig/arch/arm/mach-mx51/usb.h +++ linux-2.6.28/arch/arm/mach-mx51/usb.h @@ -0,0 +1,112 @@ +/* + * Copyright 2005-2009 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 + */ + + +extern int usbotg_init(struct platform_device *pdev); +extern void usbotg_uninit(struct fsl_usb2_platform_data *pdata); +extern int gpio_usbotg_hs_active(void); +extern void gpio_usbotg_hs_inactive(void); +extern struct platform_device *host_pdev_register(struct resource *res, + int n_res, struct fsl_usb2_platform_data *config); + +extern int fsl_usb_host_init(struct platform_device *pdev); +extern void fsl_usb_host_uninit(struct fsl_usb2_platform_data *pdata); +extern int gpio_usbotg_utmi_active(void); +extern void gpio_usbotg_utmi_inactive(void); + +/* + * Determine which platform_data struct to use for the DR controller, + * based on which transceiver is configured. + * PDATA is a pointer to it. + */ +#if defined(CONFIG_ISP1301_MXC) +static struct fsl_usb2_platform_data __maybe_unused dr_1301_config; +#define PDATA (&dr_1301_config) +#elif defined(CONFIG_MC13783_MXC) +static struct fsl_usb2_platform_data __maybe_unused dr_13783_config; +#define PDATA (&dr_13783_config) +#elif defined(CONFIG_UTMI_MXC) +static struct fsl_usb2_platform_data __maybe_unused dr_utmi_config; +#define PDATA (&dr_utmi_config) +#endif + + +/* + * Used to set pdata->operating_mode before registering the platform_device. + * If OTG is configured, the controller operates in OTG mode, + * otherwise it's either host or device. + */ +#ifdef CONFIG_USB_OTG +#define DR_UDC_MODE FSL_USB2_DR_OTG +#define DR_HOST_MODE FSL_USB2_DR_OTG +#else +#define DR_UDC_MODE FSL_USB2_DR_DEVICE +#define DR_HOST_MODE FSL_USB2_DR_HOST +#endif + + +#ifdef CONFIG_USB_EHCI_ARC_OTG +static inline void dr_register_host(struct resource *r, int rs) +{ + PDATA->operating_mode = DR_HOST_MODE; + host_pdev_register(r, rs, PDATA); +} +#else +static inline void dr_register_host(struct resource *r, int rs) +{ +} +#endif + +#ifdef CONFIG_USB_GADGET_ARC +static struct platform_device dr_udc_device; + +static inline void dr_register_udc(void) +{ + PDATA->operating_mode = DR_UDC_MODE; + dr_udc_device.dev.platform_data = PDATA; + + if (platform_device_register(&dr_udc_device)) + printk(KERN_ERR "usb: can't register DR gadget\n"); + else + printk(KERN_INFO "usb: DR gadget (%s) registered\n", + PDATA->transceiver); +} +#else +static inline void dr_register_udc(void) +{ +} +#endif + +#ifdef CONFIG_USB_OTG +static struct platform_device dr_otg_device; + +/* + * set the proper operating_mode and + * platform_data pointer, then register the + * device. + */ +static inline void dr_register_otg(void) +{ + PDATA->operating_mode = FSL_USB2_DR_OTG; + dr_otg_device.dev.platform_data = PDATA; + + if (platform_device_register(&dr_otg_device)) + printk(KERN_ERR "usb: can't register otg device\n"); + else + printk(KERN_INFO "usb: DR OTG registered\n"); +} +#else +static inline void dr_register_otg(void) +{ +} +#endif --- linux-2.6.28.orig/arch/arm/mach-mx51/board-mx51_3stack.h +++ linux-2.6.28/arch/arm/mach-mx51/board-mx51_3stack.h @@ -0,0 +1,125 @@ +/* + * Copyright 2008-2009 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_MX51_3STACK_H__ +#define __ASM_ARCH_MXC_BOARD_MX51_3STACK_H__ + +/*! + * @defgroup BRDCFG_MX51 Board Configuration Options + * @ingroup MSL_MX51 + */ + +/*! + * @file mach-mx51/board-mx51_3stack.h + * + * @brief This file contains all the board level configuration options. + * + * It currently hold the options defined for MX51 3Stack Platform. + * + * @ingroup BRDCFG_MX51 + */ + +/* + * Include Files + */ +#include + +/*! + * @name MXC UART board level configurations + */ +/*! @{ */ +/*! + * Specifies if the Irda transmit path is inverting + */ +#define MXC_IRDA_TX_INV 0 +/*! + * Specifies if the Irda receive path is inverting + */ +#define MXC_IRDA_RX_INV 0 + +/* UART 1 configuration */ +/*! + * This define specifies if the UART port is configured to be in DTE or + * DCE mode. There exists a define like this for each UART port. Valid + * values that can be used are \b MODE_DTE or \b MODE_DCE. + */ +#define UART1_MODE MODE_DCE +/*! + * This define specifies if the UART is to be used for IRDA. There exists a + * define like this for each UART port. Valid values that can be used are + * \b IRDA or \b NO_IRDA. + */ +#define UART1_IR NO_IRDA +/*! + * This define is used to enable or disable a particular UART port. If + * disabled, the UART will not be registered in the file system and the user + * will not be able to access it. There exists a define like this for each UART + * port. Specify a value of 1 to enable the UART and 0 to disable it. + */ +#define UART1_ENABLED 1 +/*! @} */ +/* UART 2 configuration */ +#define UART2_MODE MODE_DCE +#define UART2_IR NO_IRDA +#define UART2_ENABLED 1 +/* UART 3 configuration */ +#define UART3_MODE MODE_DTE +#define UART3_IR NO_IRDA +#define UART3_ENABLED 1 + +#define MXC_LL_UART_PADDR UART1_BASE_ADDR +#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) + +#define DEBUG_BOARD_BASE_ADDRESS(n) (n) +/* LAN9217 ethernet base address */ +#define LAN9217_BASE_ADDR(n) (DEBUG_BOARD_BASE_ADDRESS(n)) +/* External UART */ +#define UARTA_BASE_ADDR(n) (DEBUG_BOARD_BASE_ADDRESS(n) + 0x8000) +#define UARTB_BASE_ADDR(n) (DEBUG_BOARD_BASE_ADDRESS(n) + 0x10000) + +#define BOARD_IO_ADDR(n) (DEBUG_BOARD_BASE_ADDRESS(n) + 0x20000) +/* LED switchs */ +#define LED_SWITCH_REG 0x00 +/* buttons */ +#define SWITCH_BUTTONS_REG 0x08 +/* status, interrupt */ +#define INTR_STATUS_REG 0x10 +#define INTR_MASK_REG 0x38 +#define INTR_RESET_REG 0x20 +/* magic word for debug CPLD */ +#define MAGIC_NUMBER1_REG 0x40 +#define MAGIC_NUMBER2_REG 0x48 +/* CPLD code version */ +#define CPLD_CODE_VER_REG 0x50 +/* magic word for debug CPLD */ +#define MAGIC_NUMBER3_REG 0x58 +/* module reset register*/ +#define MODULE_RESET_REG 0x60 +/* CPU ID and Personality ID */ +#define MCU_BOARD_ID_REG 0x68 + +/* interrupts like external uart , external ethernet etc*/ +#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX51_PIN_GPIO1_6) + +#define EXPIO_INT_ENET (MXC_EXP_IO_BASE + 0) +#define EXPIO_INT_XUART_A (MXC_EXP_IO_BASE + 1) +#define EXPIO_INT_XUART_B (MXC_EXP_IO_BASE + 2) +#define EXPIO_INT_BUTTON_A (MXC_EXP_IO_BASE + 3) +#define EXPIO_INT_BUTTON_B (MXC_EXP_IO_BASE + 4) + +/*! This is System IRQ used by LAN9217 */ +#define LAN9217_IRQ EXPIO_INT_ENET + +extern int __init mx51_3stack_init_mc13892(void); + +#endif /* __ASM_ARCH_MXC_BOARD_MX51_3STACK_H__ */ --- linux-2.6.28.orig/arch/arm/mach-mx51/mx51_babbage_pmic_mc13892.c +++ linux-2.6.28/arch/arm/mach-mx51/mx51_babbage_pmic_mc13892.c @@ -0,0 +1,265 @@ +/* + * mx51-3stack-pmic-mc13892.c -- i.MX51 3STACK Driver for Atlas MC13892 PMIC + */ + /* + * Copyright 2009 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "iomux.h" + +/* + * Convenience conversion. + * Here atm, maybe there is somewhere better for this. + */ +#define mV_to_uV(mV) (mV * 1000) +#define uV_to_mV(uV) (uV / 1000) +#define V_to_uV(V) (mV_to_uV(V * 1000)) +#define uV_to_V(uV) (uV_to_mV(uV) / 1000) + +/* CPU */ +static struct regulator_consumer_supply sw1_consumers[] = { + { + .supply = "cpu_vcc", + } +}; + +struct mc13892; + +static struct regulator_init_data sw1_init = { + .constraints = { + .name = "SW1", + .min_uV = mV_to_uV(600), + .max_uV = mV_to_uV(1375), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .valid_modes_mask = 0, + .always_on = 1, + .boot_on = 1, + .initial_state = PM_SUSPEND_MEM, + .state_mem = { + .uV = 700000, + .mode = REGULATOR_MODE_NORMAL, + .enabled = 1, + }, + }, + .num_consumer_supplies = ARRAY_SIZE(sw1_consumers), + .consumer_supplies = sw1_consumers, +}; + +static struct regulator_init_data sw2_init = { + .constraints = { + .name = "SW2", + .min_uV = mV_to_uV(900), + .max_uV = mV_to_uV(1850), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .always_on = 1, + .boot_on = 1, + .initial_state = PM_SUSPEND_MEM, + .state_mem = { + .uV = 900000, + .mode = REGULATOR_MODE_NORMAL, + .enabled = 1, + }, + } +}; + +static struct regulator_init_data sw3_init = { + .constraints = { + .name = "SW3", + .min_uV = mV_to_uV(1100), + .max_uV = mV_to_uV(1850), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .always_on = 1, + .boot_on = 1, + } +}; + +static struct regulator_init_data sw4_init = { + .constraints = { + .name = "SW4", + .min_uV = mV_to_uV(1100), + .max_uV = mV_to_uV(1850), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .always_on = 1, + .boot_on = 1, + } +}; + +static struct regulator_init_data viohi_init = { + .constraints = { + .name = "VIOHI", + .boot_on = 1, + } +}; + +static struct regulator_init_data vusb_init = { + .constraints = { + .name = "VUSB", + .boot_on = 1, + } +}; + +static struct regulator_init_data swbst_init = { + .constraints = { + .name = "SWBST", + } +}; + +static struct regulator_init_data vdig_init = { + .constraints = { + .name = "VDIG", + .min_uV = mV_to_uV(1050), + .max_uV = mV_to_uV(1800), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .boot_on = 1, + } +}; + +static struct regulator_init_data vpll_init = { + .constraints = { + .name = "VPLL", + .min_uV = mV_to_uV(1050), + .max_uV = mV_to_uV(1800), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .boot_on = 1, + } +}; + +static struct regulator_init_data vusb2_init = { + .constraints = { + .name = "VUSB2", + .min_uV = mV_to_uV(2400), + .max_uV = mV_to_uV(2775), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .boot_on = 1, + } +}; + +static struct regulator_init_data vvideo_init = { + .constraints = { + .name = "VVIDEO", + .min_uV = mV_to_uV(2775), + .max_uV = mV_to_uV(2775), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .always_on = 1, + .apply_uV =1, + } +}; + +static struct regulator_init_data vaudio_init = { + .constraints = { + .name = "VAUDIO", + .min_uV = mV_to_uV(2300), + .max_uV = mV_to_uV(3000), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + } +}; + +static struct regulator_init_data vsd_init = { + .constraints = { + .name = "VSD", + .min_uV = mV_to_uV(1800), + .max_uV = mV_to_uV(3150), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + } +}; + +static struct regulator_init_data vcam_init = { + .constraints = { + .name = "VCAM", + .min_uV = mV_to_uV(2500), + .max_uV = mV_to_uV(3000), + .valid_ops_mask = + REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE, + .valid_modes_mask = REGULATOR_MODE_FAST | REGULATOR_MODE_NORMAL, + } +}; + +static struct regulator_init_data vgen1_init = { + .constraints = { + .name = "VGEN1", + .min_uV = mV_to_uV(1200), + .max_uV = mV_to_uV(3150), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + } +}; + +static struct regulator_init_data vgen2_init = { + .constraints = { + .name = "VGEN2", + .min_uV = mV_to_uV(1200), + .max_uV = mV_to_uV(3150), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + } +}; + +static struct regulator_init_data vgen3_init = { + .constraints = { + .name = "VGEN3", + .min_uV = mV_to_uV(1800), + .max_uV = mV_to_uV(2900), + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + } +}; + +static int mc13892_regulator_init(struct mc13892 *mc13892) +{ + if (mxc_cpu_is_rev(CHIP_REV_2_0) < 0) + sw2_init.constraints.state_mem.uV = 1100000; + + mc13892_register_regulator(mc13892, MC13892_SW1, &sw1_init); + mc13892_register_regulator(mc13892, MC13892_SW2, &sw2_init); + mc13892_register_regulator(mc13892, MC13892_SW3, &sw3_init); + mc13892_register_regulator(mc13892, MC13892_SW4, &sw4_init); + mc13892_register_regulator(mc13892, MC13892_SWBST, &swbst_init); + mc13892_register_regulator(mc13892, MC13892_VIOHI, &viohi_init); + mc13892_register_regulator(mc13892, MC13892_VPLL, &vpll_init); + mc13892_register_regulator(mc13892, MC13892_VDIG, &vdig_init); + mc13892_register_regulator(mc13892, MC13892_VSD, &vsd_init); + mc13892_register_regulator(mc13892, MC13892_VUSB2, &vusb2_init); + mc13892_register_regulator(mc13892, MC13892_VVIDEO, &vvideo_init); + mc13892_register_regulator(mc13892, MC13892_VAUDIO, &vaudio_init); + mc13892_register_regulator(mc13892, MC13892_VCAM, &vcam_init); + mc13892_register_regulator(mc13892, MC13892_VGEN1, &vgen1_init); + mc13892_register_regulator(mc13892, MC13892_VGEN2, &vgen2_init); + mc13892_register_regulator(mc13892, MC13892_VGEN3, &vgen3_init); + mc13892_register_regulator(mc13892, MC13892_VUSB, &vusb_init); + + return 0; +} + +static struct mc13892_platform_data mc13892_plat = { + .init = mc13892_regulator_init, +}; + +static struct spi_board_info __initdata mc13892_spi_device = { + .modalias = "pmic_spi", + .irq = IOMUX_TO_IRQ(MX51_PIN_GPIO1_8), + .max_speed_hz = 1000000, /* max spi SCK clock speed in HZ */ + .bus_num = 1, + .chip_select = 0, + .platform_data = &mc13892_plat, +}; + + +int __init mx51_babbage_init_mc13892(void) +{ + return spi_register_board_info(&mc13892_spi_device, 1); +} + --- linux-2.6.28.orig/arch/arm/mach-mx51/cpu.c +++ linux-2.6.28/arch/arm/mach-mx51/cpu.c @@ -0,0 +1,60 @@ +/* + * Copyright 2008-2009 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 + */ + +/*! + * @file mach-mx51/cpu.c + * + * @brief This file contains the CPU initialization code. + * + * @ingroup MSL_MX51 + */ + +#include +#include +#include +#include +#include + +/*! + * CPU initialization. It is called by fixup_mxc_board() + */ +void __init mxc_cpu_init(void) +{ + if (!system_rev) + mxc_set_system_rev(0x51, CHIP_REV_1_0); +} + +static int __init post_cpu_init(void) +{ + unsigned int base, reg; + + base = IO_ADDRESS(AIPS1_BASE_ADDR); + __raw_writel(0x0, base + 0x40); + __raw_writel(0x0, base + 0x44); + __raw_writel(0x0, base + 0x48); + __raw_writel(0x0, base + 0x4C); + reg = __raw_readl(base + 0x50) & 0x00FFFFFF; + __raw_writel(reg, base + 0x50); + + base = IO_ADDRESS(AIPS2_BASE_ADDR); + __raw_writel(0x0, base + 0x40); + __raw_writel(0x0, base + 0x44); + __raw_writel(0x0, base + 0x48); + __raw_writel(0x0, base + 0x4C); + reg = __raw_readl(base + 0x50) & 0x00FFFFFF; + __raw_writel(reg, base + 0x50); + + return 0; +} + +postcore_initcall(post_cpu_init); --- linux-2.6.28.orig/arch/arm/mach-mx51/iomux.h +++ linux-2.6.28/arch/arm/mach-mx51/iomux.h @@ -0,0 +1,244 @@ +/* + * Copyright 2008-2009 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 __MACH_MX51_IOMUX_H__ +#define __MACH_MX51_IOMUX_H__ + +#include +#include +#include "mx51_pins.h" + +/*! + * @file mach-mx51/iomux.h + * + * @brief I/O Muxing control definitions and functions + * + * @ingroup GPIO_MX51 + */ + +/*! + * various IOMUX output functions + */ +typedef enum iomux_config { + IOMUX_CONFIG_ALT0, /*!< used as alternate function 0 */ + IOMUX_CONFIG_ALT1, /*!< used as alternate function 1 */ + IOMUX_CONFIG_ALT2, /*!< used as alternate function 2 */ + IOMUX_CONFIG_ALT3, /*!< used as alternate function 3 */ + IOMUX_CONFIG_ALT4, /*!< used as alternate function 4 */ + IOMUX_CONFIG_ALT5, /*!< used as alternate function 5 */ + IOMUX_CONFIG_ALT6, /*!< used as alternate function 6 */ + IOMUX_CONFIG_ALT7, /*!< used as alternate function 7 */ + IOMUX_CONFIG_GPIO, /*!< added to help user use GPIO mode */ + IOMUX_CONFIG_SION = 0x1 << 4, /*!< used as LOOPBACK:MUX SION bit */ +} iomux_pin_cfg_t; + +/*! + * various IOMUX pad functions + */ +typedef enum iomux_pad_config { + PAD_CTL_SRE_SLOW = 0x0 << 0, + PAD_CTL_SRE_FAST = 0x1 << 0, + PAD_CTL_DRV_LOW = 0x0 << 1, + PAD_CTL_DRV_MEDIUM = 0x1 << 1, + PAD_CTL_DRV_HIGH = 0x2 << 1, + PAD_CTL_DRV_MAX = 0x3 << 1, + PAD_CTL_ODE_OPENDRAIN_NONE = 0x0 << 3, + PAD_CTL_ODE_OPENDRAIN_ENABLE = 0x1 << 3, + PAD_CTL_100K_PD = 0x0 << 4, + PAD_CTL_47K_PU = 0x1 << 4, + PAD_CTL_100K_PU = 0x2 << 4, + PAD_CTL_22K_PU = 0x3 << 4, + PAD_CTL_PUE_KEEPER = 0x0 << 6, + PAD_CTL_PUE_PULL = 0x1 << 6, + PAD_CTL_PKE_NONE = 0x0 << 7, + PAD_CTL_PKE_ENABLE = 0x1 << 7, + PAD_CTL_HYS_NONE = 0x0 << 8, + PAD_CTL_HYS_ENABLE = 0x1 << 8, + PAD_CTL_DDR_INPUT_CMOS = 0x0 << 9, + PAD_CTL_DDR_INPUT_DDR = 0x1 << 9, + PAD_CTL_DRV_VOT_LOW = 0x0 << 13, + PAD_CTL_DRV_VOT_HIGH = 0x1 << 13, +} iomux_pad_config_t; + +/*! + * various IOMUX input select register index + */ +typedef enum iomux_input_select { + MUX_IN_AUDMUX_P4_INPUT_DA_AMX_SELECT_I = 0, + MUX_IN_AUDMUX_P4_INPUT_DB_AMX_SELECT_I, + MUX_IN_AUDMUX_P4_INPUT_TXCLK_AMX_SELECT_INPUT, + MUX_IN_AUDMUX_P4_INPUT_TXFS_AMX_SELECT_INPUT, + MUX_IN_AUDMUX_P5_INPUT_DA_AMX_SELECT_INPUT, + MUX_IN_AUDMUX_P5_INPUT_DB_AMX_SELECT_INPUT, + MUX_IN_AUDMUX_P5_INPUT_RXCLK_AMX_SELECT_INPUT, + MUX_IN_AUDMUX_P5_INPUT_RXFS_AMX_SELECT, + MUX_IN_AUDMUX_P5_INPUT_TXCLK_AMX_SELECT_INPUT, + MUX_IN_AUDMUX_P5_INPUT_TXFS_AMX_SELECT_INPUT, + MUX_IN_AUDMUX_P6_INPUT_DA_AMX_SELECT_INPUT, + MUX_IN_AUDMUX_P6_INPUT_DB_AMX_SELECT_INPUT, + MUX_IN_AUDMUX_P6_INPUT_RXCLK_AMX_SELECT_INPUT, + MUX_IN_AUDMUX_P6_INPUT_RXFS_AMX_SELECT_INPUT, + MUX_IN_AUDMUX_P6_INPUT_TXCLK_AMX_SELECT_INPUT, + MUX_IN_AUDMUX_P6_INPUT_TXFS_AMX_SELECT_INPUT, + MUX_IN_CCM_IPP_DI_CLK_SELECT_INPUT, + /* TO2 */ + MUX_IN_CCM_IPP_DI1_CLK_SELECT_INPUT, + MUX_IN_CCM_PLL1_BYPASS_CLK_SELECT_INPUT, + MUX_IN_CCM_PLL2_BYPASS_CLK_SELECT_INPUT, + MUX_IN_CSPI_IPP_CSPI_CLK_IN_SELECT_INPUT, + MUX_IN_CSPI_IPP_IND_MISO_SELECT_INPUT, + MUX_IN_CSPI_IPP_IND_MOSI_SELECT_INPUT, + MUX_IN_CSPI_IPP_IND_SS_B_1_SELECT_INPUT, + MUX_IN_CSPI_IPP_IND_SS_B_2_SELECT_INPUT, + MUX_IN_CSPI_IPP_IND_SS_B_3_SELECT_INPUT, + MUX_IN_DPLLIP1_L1T_TOG_EN_SELECT_INPUT, + /* TO2 */ + MUX_IN_ECSPI2_IPP_IND_SS_B_1_SELECT_INPUT, + MUX_IN_ECSPI2_IPP_IND_SS_B_3_SELECT_INPUT, + MUX_IN_EMI_IPP_IND_RDY_INT_SELECT_INPUT, + MUX_IN_ESDHC3_IPP_DAT0_IN_SELECT_INPUT, + MUX_IN_ESDHC3_IPP_DAT1_IN_SELECT_INPUT, + MUX_IN_ESDHC3_IPP_DAT2_IN_SELECT_INPUT, + MUX_IN_ESDHC3_IPP_DAT3_IN_SELECT_INPUT, + MUX_IN_FEC_FEC_COL_SELECT_INPUT, + MUX_IN_FEC_FEC_CRS_SELECT_INPUT, + MUX_IN_FEC_FEC_MDI_SELECT_INPUT, + MUX_IN_FEC_FEC_RDATA_0_SELECT_INPUT, + MUX_IN_FEC_FEC_RDATA_1_SELECT_INPUT, + MUX_IN_FEC_FEC_RDATA_2_SELECT_INPUT, + MUX_IN_FEC_FEC_RDATA_3_SELECT_INPUT, + MUX_IN_FEC_FEC_RX_CLK_SELECT_INPUT, + MUX_IN_FEC_FEC_RX_DV_SELECT_INPUT, + MUX_IN_FEC_FEC_RX_ER_SELECT_INPUT, + MUX_IN_FEC_FEC_TX_CLK_SELECT_INPUT, + MUX_IN_GPIO3_IPP_IND_G_IN_1_SELECT_INPUT, + MUX_IN_GPIO3_IPP_IND_G_IN_2_SELECT_INPUT, + MUX_IN_GPIO3_IPP_IND_G_IN_3_SELECT_INPUT, + MUX_IN_GPIO3_IPP_IND_G_IN_4_SELECT_INPUT, + MUX_IN_GPIO3_IPP_IND_G_IN_5_SELECT_INPUT, + MUX_IN_GPIO3_IPP_IND_G_IN_6_SELECT_INPUT, + MUX_IN_GPIO3_IPP_IND_G_IN_7_SELECT_INPUT, + MUX_IN_GPIO3_IPP_IND_G_IN_8_SELECT_INPUT, + /* TO2 */ + MUX_IN_GPIO3_IPP_IND_G_IN_12_SELECT_INPUT, + MUX_IN_HSC_MIPI_MIX_IPP_IND_SENS1_DATA_EN_SELECT_INPUT, + MUX_IN_HSC_MIPI_MIX_IPP_IND_SENS2_DATA_EN_SELECT_INPUT, + /* TO2 */ + MUX_IN_HSC_MIPI_MIX_PAR_VSYNC_SELECT_INPUT, + /* TO2 */ + MUX_IN_HSC_MIPI_MIX_PAR_DI_WAIT_SELECT_INPUT, + MUX_IN_HSC_MIPI_MIX_PAR_SISG_TRIG_SELECT_INPUT, + MUX_IN_I2C1_IPP_SCL_IN_SELECT_INPUT, + MUX_IN_I2C1_IPP_SDA_IN_SELECT_INPUT, + MUX_IN_I2C2_IPP_SCL_IN_SELECT_INPUT, + MUX_IN_I2C2_IPP_SDA_IN_SELECT_INPUT, + + MUX_IN_IPU_IPP_DI_0_IND_DISPB_SD_D_SELECT_INPUT, + + MUX_IN_IPU_IPP_DI_1_IND_DISPB_SD_D_SELECT_INPUT, + + MUX_IN_KPP_IPP_IND_COL_6_SELECT_INPUT, + MUX_IN_KPP_IPP_IND_COL_7_SELECT_INPUT, + MUX_IN_KPP_IPP_IND_ROW_4_SELECT_INPUT, + MUX_IN_KPP_IPP_IND_ROW_5_SELECT_INPUT, + MUX_IN_KPP_IPP_IND_ROW_6_SELECT_INPUT, + MUX_IN_KPP_IPP_IND_ROW_7_SELECT_INPUT, + MUX_IN_UART1_IPP_UART_RTS_B_SELECT_INPUT, + MUX_IN_UART1_IPP_UART_RXD_MUX_SELECT_INPUT, + MUX_IN_UART2_IPP_UART_RTS_B_SELECT_INPUT, + MUX_IN_UART2_IPP_UART_RXD_MUX_SELECT_INPUT, + MUX_IN_UART3_IPP_UART_RTS_B_SELECT_INPUT, + MUX_IN_UART3_IPP_UART_RXD_MUX_SELECT_INPUT, + MUX_IN_USBOH3_IPP_IND_UH3_CLK_SELECT_INPUT, + MUX_IN_USBOH3_IPP_IND_UH3_DATA_0_SELECT_INPUT, + MUX_IN_USBOH3_IPP_IND_UH3_DATA_1_SELECT_INPUT, + MUX_IN_USBOH3_IPP_IND_UH3_DATA_2_SELECT_INPUT, + MUX_IN_USBOH3_IPP_IND_UH3_DATA_3_SELECT_INPUT, + MUX_IN_USBOH3_IPP_IND_UH3_DATA_4_SELECT_INPUT, + MUX_IN_USBOH3_IPP_IND_UH3_DATA_5_SELECT_INPUT, + MUX_IN_USBOH3_IPP_IND_UH3_DATA_6_SELECT_INPUT, + MUX_IN_USBOH3_IPP_IND_UH3_DATA_7_SELECT_INPUT, + MUX_IN_USBOH3_IPP_IND_UH3_DIR_SELECT_INPUT, + MUX_IN_USBOH3_IPP_IND_UH3_NXT_SELECT_INPUT, + MUX_IN_USBOH3_IPP_IND_UH3_STP_SELECT_INPUT, + MUX_INPUT_NUM_MUX, +} iomux_input_select_t; + +/*! + * various IOMUX input functions + */ +typedef enum iomux_input_config { + INPUT_CTL_PATH0 = 0x0, + INPUT_CTL_PATH1, + INPUT_CTL_PATH2, + INPUT_CTL_PATH3, + INPUT_CTL_PATH4, + INPUT_CTL_PATH5, + INPUT_CTL_PATH6, + INPUT_CTL_PATH7, +} iomux_input_config_t; + +struct mxc_iomux_pin_cfg { + iomux_pin_name_t pin; + u8 mux_mode; + u16 pad_cfg; + u8 in_select; + u8 in_mode; +}; + +/*! + * Request ownership for an IO pin. This function has to be the first one + * being called before that pin is used. The caller has to check the + * return value to make sure it returns 0. + * + * @param pin a name defined by \b iomux_pin_name_t + * @param config config as defined in \b #iomux_pin_ocfg_t + * + * @return 0 if successful; Non-zero otherwise + */ +int mxc_request_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t config); + +/*! + * Release ownership for an IO pin + * + * @param pin a name defined by \b iomux_pin_name_t + * @param config config as defined in \b #iomux_pin_ocfg_t + */ +void mxc_free_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t config); + +/*! + * This function configures the pad value for a IOMUX pin. + * + * @param pin a pin number as defined in \b #iomux_pin_name_t + * @param config the ORed value of elements defined in + * \b #iomux_pad_config_t + */ +void mxc_iomux_set_pad(iomux_pin_name_t pin, u32 config); + +/*! + * This function gets the current pad value for a IOMUX pin. + * + * @param pin a pin number as defined in \b #iomux_pin_name_t + * @return current pad value + */ +unsigned int mxc_iomux_get_pad(iomux_pin_name_t pin); + +/*! + * This function configures input path. + * + * @param input index of input select register as defined in + * \b #iomux_input_select_t + * @param config the binary value of elements defined in \b #iomux_input_config_t + */ +void mxc_iomux_set_input(iomux_input_select_t input, u32 config); + +#endif /* __MACH_MX51_IOMUX_H__ */ --- linux-2.6.28.orig/arch/arm/mach-mx51/clock.c +++ linux-2.6.28/arch/arm/mach-mx51/clock.c @@ -0,0 +1,3049 @@ +/* + * Copyright 2008-2009 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "crm_regs.h" + +static unsigned long pll_base[] = { + (unsigned long)MXC_DPLL1_BASE, + (unsigned long)MXC_DPLL2_BASE, + (unsigned long)MXC_DPLL3_BASE, +}; + +static struct clk pll1_main_clk; +static struct clk pll1_sw_clk; +static struct clk pll2_sw_clk; +static struct clk pll3_sw_clk; +static struct clk lp_apm_clk; +static struct clk tve_clk; +static struct clk emi_fast_clk; +static struct clk emi_slow_clk; +static struct clk emi_intr_clk; +static struct clk ddr_clk; +static struct clk ipu_clk[]; +static struct clk axi_a_clk; +static struct clk axi_b_clk; +static struct clk ddr_hf_clk; +static int cpu_curr_wp; +static struct cpu_wp *cpu_wp_tbl; + +int cpu_wp_nr; + +extern int mxc_jtag_enabled; + +static int cpu_clk_set_wp(int wp); +extern void propagate_rate(struct clk *tclk); +struct cpu_wp *(*get_cpu_wp)(int *wp); + +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 >= 8) { + 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; + } +} + +static int _clk_enable(struct clk *clk) +{ + u32 reg; + reg = __raw_readl(clk->enable_reg); + reg |= MXC_CCM_CCGR_CG_MASK << 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 &= ~(MXC_CCM_CCGR_CG_MASK << clk->enable_shift); + __raw_writel(reg, clk->enable_reg); +} + +static void _clk_disable_inwait(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(clk->enable_reg); + reg &= ~(MXC_CCM_CCGR_CG_MASK << clk->enable_shift); + reg |= 1 << clk->enable_shift; + __raw_writel(reg, clk->enable_reg); +} + +/* + * For the 4-to-1 muxed input clock + */ +static inline u32 _get_mux(struct clk *parent, struct clk *m0, + struct clk *m1, struct clk *m2, struct clk *m3) +{ + if (parent == m0) + return 0; + else if (parent == m1) + return 1; + else if (parent == m2) + return 2; + else if (parent == m3) + return 3; + else + BUG(); + + return 0; +} + +/* + * For the ddr muxed input clock + */ +static inline u32 _get_mux_ddr(struct clk *parent, struct clk *m0, + struct clk *m1, struct clk *m2, struct clk *m3, struct clk *m4) +{ + if (parent == m0) + return 0; + else if (parent == m1) + return 1; + else if (parent == m2) + return 2; + else if (parent == m3) + return 3; + else if (parent == m4) + return 4; + else + BUG(); + + return 0; +} + +static inline unsigned long _get_pll_base(struct clk *pll) +{ + if (pll == &pll1_main_clk) + return pll_base[0]; + else if (pll == &pll2_sw_clk) + return pll_base[1]; + else if (pll == &pll3_sw_clk) + return pll_base[2]; + else + BUG(); + + return 0; +} + +static struct clk ckih_clk = { + .name = "ckih", + .flags = RATE_PROPAGATES, +}; + +static struct clk ckih2_clk = { + .name = "ckih2", + .flags = RATE_PROPAGATES, +}; + +static struct clk osc_clk = { + .name = "osc", + .flags = RATE_PROPAGATES, +}; + +static struct clk ckil_clk = { + .name = "ckil", + .flags = RATE_PROPAGATES, +}; + +static void _fpm_recalc(struct clk *clk) +{ + clk->rate = ckil_clk.rate * 512; + if ((__raw_readl(MXC_CCM_CCR) & MXC_CCM_CCR_FPM_MULT_MASK) != 0) + clk->rate *= 2; + +} + +static int _fpm_enable(struct clk *clk) +{ + u32 reg = __raw_readl(MXC_CCM_CCR); + reg |= MXC_CCM_CCR_FPM_EN; + __raw_writel(reg, MXC_CCM_CCR); + return 0; +} + +static void _fpm_disable(struct clk *clk) +{ + u32 reg = __raw_readl(MXC_CCM_CCR); + reg &= ~MXC_CCM_CCR_FPM_EN; + __raw_writel(reg, MXC_CCM_CCR); +} + +static struct clk fpm_clk = { + .name = "fpm_clk", + .parent = &ckil_clk, + .recalc = _fpm_recalc, + .enable = _fpm_enable, + .disable = _fpm_disable, + .flags = RATE_PROPAGATES, +}; + +static void _fpm_div2_recalc(struct clk *clk) +{ + clk->rate = clk->parent->rate / 2; +} + +static struct clk fpm_div2_clk = { + .name = "fpm_div2_clk", + .parent = &fpm_clk, + .recalc = _fpm_div2_recalc, + .flags = RATE_PROPAGATES, +}; + +static void _clk_pll_recalc(struct clk *clk) +{ + long mfi, mfn, mfd, pdf, ref_clk, mfn_abs; + unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl; + unsigned long pllbase; + s64 temp; + + pllbase = _get_pll_base(clk); + + dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); + pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM; + dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN; + + if (pll_hfsm == 0) { + dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP); + dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD); + dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN); + } else { + dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP); + dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD); + dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN); + } + pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK; + mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET; + mfi = (mfi <= 5) ? 5 : mfi; + mfd = dp_mfd & MXC_PLL_DP_MFD_MASK; + mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK; + /* Sign extend to 32-bits */ + if (mfn >= 0x04000000) { + mfn |= 0xFC000000; + mfn_abs = -mfn; + } + + ref_clk = 2 * clk->parent->rate; + if (dbl != 0) + 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; + + clk->rate = temp; +} + +static int _clk_pll_enable(struct clk *clk) +{ + u32 reg; + u32 pllbase; + + pllbase = _get_pll_base(clk); + reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) | MXC_PLL_DP_CTL_UPEN; + __raw_writel(reg, pllbase + MXC_PLL_DP_CTL); + + /* Wait for lock */ + while (!(__raw_readl(pllbase + MXC_PLL_DP_CTL) & MXC_PLL_DP_CTL_LRF)) ; + + return 0; +} + +static void _clk_pll_disable(struct clk *clk) +{ + u32 reg; + u32 pllbase; + + pllbase = _get_pll_base(clk); + reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN; + __raw_writel(reg, pllbase + MXC_PLL_DP_CTL); +} + +static struct clk pll1_main_clk = { + .name = "pll1_main_clk", + .parent = &osc_clk, + .recalc = _clk_pll_recalc, + .enable = _clk_pll_enable, + .disable = _clk_pll_disable, + .flags = RATE_PROPAGATES, +}; + +static int _clk_pll1_sw_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + reg = __raw_readl(MXC_CCM_CCSR); + + if (parent == &pll1_main_clk) { + reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL; + } else { + if (parent == &lp_apm_clk) { + reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL; + reg = __raw_readl(MXC_CCM_CCSR); + mux = _get_mux(parent, &lp_apm_clk, NULL, &pll2_sw_clk, + &pll3_sw_clk); + reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) | + (mux << MXC_CCM_CCSR_STEP_SEL_OFFSET); + } else { + mux = _get_mux(parent, &lp_apm_clk, NULL, &pll2_sw_clk, + &pll3_sw_clk); + reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) | + (mux << MXC_CCM_CCSR_STEP_SEL_OFFSET); + __raw_writel(reg, MXC_CCM_CCSR); + reg = __raw_readl(MXC_CCM_CCSR); + reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL; + + } + } + __raw_writel(reg, MXC_CCM_CCSR); + return 0; +} + +static void _clk_pll1_sw_recalc(struct clk *clk) +{ + u32 reg, div; + div = 1; + reg = __raw_readl(MXC_CCM_CCSR); + + if (clk->parent == &pll2_sw_clk) { + div = ((reg & MXC_CCM_CCSR_PLL2_PODF_MASK) >> + MXC_CCM_CCSR_PLL2_PODF_OFFSET) + 1; + } else if (clk->parent == &pll3_sw_clk) { + div = ((reg & MXC_CCM_CCSR_PLL3_PODF_MASK) >> + MXC_CCM_CCSR_PLL3_PODF_OFFSET) + 1; + } + clk->rate = clk->parent->rate / div; +} + +/* pll1 switch clock */ +static struct clk pll1_sw_clk = { + .name = "pll1_sw_clk", + .parent = &pll1_main_clk, + .set_parent = _clk_pll1_sw_set_parent, + .recalc = _clk_pll1_sw_recalc, + .flags = RATE_PROPAGATES, +}; + +/* same as pll2_main_clk. These two clocks should always be the same */ +static struct clk pll2_sw_clk = { + .name = "pll2", + .parent = &osc_clk, + .recalc = _clk_pll_recalc, + .enable = _clk_pll_enable, + .disable = _clk_pll_disable, + .flags = RATE_PROPAGATES, +}; + +/* same as pll3_main_clk. These two clocks should always be the same */ +static struct clk pll3_sw_clk = { + .name = "pll3", + .parent = &osc_clk, + .recalc = _clk_pll_recalc, + .enable = _clk_pll_enable, + .disable = _clk_pll_disable, + .flags = RATE_PROPAGATES, +}; + +static int _clk_lp_apm_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg; + + if (parent == &osc_clk) + reg = __raw_readl(MXC_CCM_CCSR) & ~MXC_CCM_CCSR_LP_APM_SEL; + else if (parent == &fpm_clk) + reg = __raw_readl(MXC_CCM_CCSR) | MXC_CCM_CCSR_LP_APM_SEL; + else + return -EINVAL; + + __raw_writel(reg, MXC_CCM_CCSR); + + return 0; +} + +static struct clk lp_apm_clk = { + .name = "lp_apm", + .parent = &osc_clk, + .set_parent = _clk_lp_apm_set_parent, + .flags = RATE_PROPAGATES, +}; + +static void _clk_arm_recalc(struct clk *clk) +{ + u32 cacrr, div; + + cacrr = __raw_readl(MXC_CCM_CACRR); + div = (cacrr & MXC_CCM_CACRR_ARM_PODF_MASK) + 1; + clk->rate = clk->parent->rate / div; +} + +static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate) +{ + u32 i; + for (i = 0; i < cpu_wp_nr; i++) { + if (rate == cpu_wp_tbl[i].cpu_rate) + break; + } + if (i > cpu_wp_nr) + return -EINVAL; + cpu_clk_set_wp(i); + + return 0; +} + +static unsigned long _clk_cpu_round_rate(struct clk *clk, + unsigned long rate) +{ + u32 i; + u32 wp; + + for (i = 0; i < cpu_wp_nr; i++) { + if (rate == cpu_wp_tbl[i].cpu_rate) + break; + } + + if (i > cpu_wp_nr) + wp = 0; + + return cpu_wp_tbl[wp].cpu_rate; +} + + +static struct clk cpu_clk = { + .name = "cpu_clk", + .parent = &pll1_sw_clk, + .recalc = _clk_arm_recalc, + .set_rate = _clk_cpu_set_rate, + .round_rate = _clk_cpu_round_rate, +}; + +static int _clk_periph_apm_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + mux = _get_mux(parent, &pll1_sw_clk, &pll3_sw_clk, &lp_apm_clk, NULL); + + reg = __raw_readl(MXC_CCM_CBCMR) & ~MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK; + reg |= mux << MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET; + __raw_writel(reg, MXC_CCM_CBCMR); + + return 0; +} + +static struct clk periph_apm_clk = { + .name = "periph_apm_clk", + .parent = &pll1_sw_clk, + .set_parent = _clk_periph_apm_set_parent, + .flags = RATE_PROPAGATES, +}; + +/* TODO: Need to sync with GPC to determine if DVFS is in place so that + * the DVFS_PODF divider can be applied in CDCR register. + */ +static void _clk_main_bus_recalc(struct clk *clk) +{ + clk->rate = clk->parent->rate; +} + +static int _clk_main_bus_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg; + + if (emi_fast_clk.usecount == 0) + emi_fast_clk.enable(&emi_fast_clk); + if (emi_slow_clk.usecount == 0) + emi_slow_clk.enable(&emi_slow_clk); + if (emi_intr_clk.usecount == 0) + emi_intr_clk.enable(&emi_intr_clk); + + if (parent == &pll2_sw_clk) { + reg = __raw_readl(MXC_CCM_CBCDR) & + ~MXC_CCM_CBCDR_PERIPH_CLK_SEL; + } else if (parent == &periph_apm_clk) { + reg = __raw_readl(MXC_CCM_CBCDR) | MXC_CCM_CBCDR_PERIPH_CLK_SEL; + } else { + return -EINVAL; + } + __raw_writel(reg, MXC_CCM_CBCDR); + + if (emi_fast_clk.usecount == 0) + emi_fast_clk.disable(&emi_fast_clk); + if (emi_slow_clk.usecount == 0) + emi_slow_clk.disable(&emi_slow_clk); + if (emi_intr_clk.usecount == 0) + emi_intr_clk.disable(&emi_intr_clk); + + return 0; +} + +static struct clk main_bus_clk = { + .name = "main_bus_clk", + .parent = &pll2_sw_clk, + .set_parent = _clk_main_bus_set_parent, + .recalc = _clk_main_bus_recalc, + .flags = RATE_PROPAGATES, +}; + +static void _clk_axi_a_recalc(struct clk *clk) +{ + u32 reg, div; + + reg = __raw_readl(MXC_CCM_CBCDR); + div = ((reg & MXC_CCM_CBCDR_AXI_A_PODF_MASK) >> + MXC_CCM_CBCDR_AXI_A_PODF_OFFSET) + 1; + clk->rate = clk->parent->rate / div; +} + +static struct clk axi_a_clk = { + .name = "axi_a_clk", + .parent = &main_bus_clk, + .recalc = _clk_axi_a_recalc, + .flags = RATE_PROPAGATES, +}; + +static void _clk_ddr_hf_recalc(struct clk *clk) +{ + u32 reg, div; + + reg = __raw_readl(MXC_CCM_CBCDR); + div = ((reg & MXC_CCM_CBCDR_DDR_PODF_MASK) >> + MXC_CCM_CBCDR_DDR_PODF_OFFSET) + 1; + clk->rate = clk->parent->rate / div; +} + +static struct clk ddr_hf_clk = { + .name = "ddr_hf_clk", + .parent = &pll1_sw_clk, + .recalc = _clk_ddr_hf_recalc, + .flags = RATE_PROPAGATES, +}; + +static void _clk_axi_b_recalc(struct clk *clk) +{ + u32 reg, div; + + reg = __raw_readl(MXC_CCM_CBCDR); + div = ((reg & MXC_CCM_CBCDR_AXI_B_PODF_MASK) >> + MXC_CCM_CBCDR_AXI_B_PODF_OFFSET) + 1; + clk->rate = clk->parent->rate / div; +} + +static struct clk axi_b_clk = { + .name = "axi_b_clk", + .parent = &main_bus_clk, + .recalc = _clk_axi_b_recalc, + .flags = RATE_PROPAGATES, +}; + +static void _clk_ahb_recalc(struct clk *clk) +{ + u32 reg, div; + + reg = __raw_readl(MXC_CCM_CBCDR); + div = ((reg & MXC_CCM_CBCDR_AHB_PODF_MASK) >> + MXC_CCM_CBCDR_AHB_PODF_OFFSET) + 1; + clk->rate = clk->parent->rate / div; +} + +static struct clk ahb_clk = { + .name = "ahb_clk", + .parent = &main_bus_clk, + .recalc = _clk_ahb_recalc, + .flags = RATE_PROPAGATES, +}; + +static int _clk_max_enable(struct clk *clk) +{ + u32 reg; + + _clk_enable(clk); + + /* Handshake with MAX when LPM is entered. */ + reg = __raw_readl(MXC_CCM_CLPCR); + reg &= ~MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS; + __raw_writel(reg, MXC_CCM_CLPCR); + + return 0; +} + + +static void _clk_max_disable(struct clk *clk) +{ + u32 reg; + + _clk_disable_inwait(clk); + + /* No Handshake with MAX when LPM is entered as its disabled. */ + reg = __raw_readl(MXC_CCM_CLPCR); + reg |= MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS; + __raw_writel(reg, MXC_CCM_CLPCR); +} + + +static struct clk ahb_max_clk = { + .name = "max_clk", + .parent = &ahb_clk, + .enable_reg = MXC_CCM_CCGR0, + .enable_shift = MXC_CCM_CCGR0_CG14_OFFSET, + .enable = _clk_max_enable, + .disable = _clk_max_disable, +}; + +static int _clk_emi_slow_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CBCDR); + if (parent == &ahb_clk) { + reg |= MXC_CCM_CBCDR_EMI_CLK_SEL; + } else if (parent == &main_bus_clk) { + reg &= ~MXC_CCM_CBCDR_EMI_CLK_SEL; + } else { + BUG(); + } + __raw_writel(reg, MXC_CCM_CBCDR); + + return 0; +} + +static void _clk_emi_slow_recalc(struct clk *clk) +{ + u32 reg, div; + + reg = __raw_readl(MXC_CCM_CBCDR); + div = ((reg & MXC_CCM_CBCDR_EMI_PODF_MASK) >> + MXC_CCM_CBCDR_EMI_PODF_OFFSET) + 1; + clk->rate = clk->parent->rate / div; +} + +static int _clk_emi_slow_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg, div; + + div = clk->parent->rate / rate; + if (div == 0) + div++; + if (((clk->parent->rate / div) != rate) || (div > 8)) + return -EINVAL; + + if (emi_fast_clk.usecount == 0) + emi_fast_clk.enable(&emi_fast_clk); + if (emi_intr_clk.usecount == 0) + emi_intr_clk.enable(&emi_intr_clk); + + reg = __raw_readl(MXC_CCM_CBCDR); + reg &= ~MXC_CCM_CBCDR_EMI_PODF_MASK; + reg |= (div - 1) << MXC_CCM_CBCDR_EMI_PODF_OFFSET; + __raw_writel(reg, MXC_CCM_CBCDR); + + clk->rate = rate; + + if (emi_fast_clk.usecount == 0) + emi_fast_clk.disable(&emi_fast_clk); + if (emi_intr_clk.usecount == 0) + emi_intr_clk.disable(&emi_intr_clk); + + return 0; +} + +static unsigned long _clk_emi_slow_round_rate(struct clk *clk, + unsigned long rate) +{ + u32 div; + + div = clk->parent->rate / rate; + if (div > 8) + div = 8; + else if (div == 0) + div++; + return clk->parent->rate / div; +} + + +static struct clk emi_slow_clk = { + .name = "emi_slow_clk", + .parent = &main_bus_clk, + .set_parent = _clk_emi_slow_set_parent, + .recalc = _clk_emi_slow_recalc, + .set_rate = _clk_emi_slow_set_rate, + .round_rate = _clk_emi_slow_round_rate, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR5, + .enable_shift = MXC_CCM_CCGR5_CG8_OFFSET, + .disable = _clk_disable_inwait, + .flags = RATE_PROPAGATES, +}; + +static struct clk ahbmux1_clk = { + .name = "ahbmux1_clk", + .id = 0, + .parent = &ahb_clk, + .secondary = &ahb_max_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR0, + .enable_shift = MXC_CCM_CCGR0_CG8_OFFSET, + .disable = _clk_disable_inwait, +}; + +static struct clk ahbmux2_clk = { + .name = "ahbmux2_clk", + .id = 0, + .parent = &ahb_clk, + .secondary = &emi_intr_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR0, + .enable_shift = MXC_CCM_CCGR0_CG9_OFFSET, + .disable = _clk_disable_inwait, +}; + + +static struct clk emi_fast_clk = { + .name = "emi_fast_clk", + .parent = &ddr_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR5, + .enable_shift = MXC_CCM_CCGR5_CG7_OFFSET, + .disable = _clk_disable_inwait, +}; + +static struct clk emi_intr_clk = { + .name = "emi_intr_clk", + .parent = &ahb_clk, + .secondary = &ahbmux2_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR5, + .enable_shift = MXC_CCM_CCGR5_CG9_OFFSET, + .disable = _clk_disable_inwait, +}; + +static void _clk_ipg_recalc(struct clk *clk) +{ + u32 reg, div; + + reg = __raw_readl(MXC_CCM_CBCDR); + div = ((reg & MXC_CCM_CBCDR_IPG_PODF_MASK) >> + MXC_CCM_CBCDR_IPG_PODF_OFFSET) + 1; + clk->rate = clk->parent->rate / div; +} + +static struct clk ipg_clk = { + .name = "ipg_clk", + .parent = &ahb_clk, + .recalc = _clk_ipg_recalc, + .flags = RATE_PROPAGATES, +}; + +static void _clk_ipg_per_recalc(struct clk *clk) +{ + u32 reg, prediv1, prediv2, podf; + + if (clk->parent == &main_bus_clk || clk->parent == &lp_apm_clk) { + /* the main_bus_clk is the one before the DVFS engine */ + reg = __raw_readl(MXC_CCM_CBCDR); + prediv1 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >> + MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET) + 1; + prediv2 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >> + MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET) + 1; + podf = ((reg & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >> + MXC_CCM_CBCDR_PERCLK_PODF_OFFSET) + 1; + clk->rate = clk->parent->rate / (prediv1 * prediv2 * podf); + } else if (clk->parent == &ipg_clk) { + clk->rate = ipg_clk.rate; + } else { + BUG(); + } +} + +static int _clk_ipg_per_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + reg = __raw_readl(MXC_CCM_CBCMR); + mux = _get_mux(parent, &main_bus_clk, &lp_apm_clk, &ipg_clk, NULL); + if (mux == 2) { + reg |= MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL; + } else { + reg &= ~MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL; + if (mux == 0) + reg &= ~MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL; + else + reg |= MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL; + } + __raw_writel(reg, MXC_CCM_CBCMR); + + return 0; +} + +static struct clk ipg_perclk = { + .name = "ipg_perclk", + .parent = &lp_apm_clk, + .recalc = _clk_ipg_per_recalc, + .set_parent = _clk_ipg_per_set_parent, + .flags = RATE_PROPAGATES, +}; + +static struct clk aips_tz1_clk = { + .name = "aips_tz1_clk", + .parent = &ahb_clk, + .secondary = &ahb_max_clk, + .enable_reg = MXC_CCM_CCGR0, + .enable_shift = MXC_CCM_CCGR0_CG12_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable_inwait, +}; + +static struct clk aips_tz2_clk = { + .name = "aips_tz2_clk", + .parent = &ahb_clk, + .secondary = &ahb_max_clk, + .enable_reg = MXC_CCM_CCGR0, + .enable_shift = MXC_CCM_CCGR0_CG13_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable_inwait, +}; + +static struct clk gpc_dvfs_clk = { + .name = "gpc_dvfs_clk", + .parent = &aips_tz1_clk, + .enable_reg = MXC_CCM_CCGR5, + .enable_shift = MXC_CCM_CCGR5_CG12_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, +}; + +static int _clk_sdma_enable(struct clk *clk) +{ + u32 reg; + + _clk_enable(clk); + + /* Handshake with SDMA when LPM is entered. */ + reg = __raw_readl(MXC_CCM_CLPCR); + reg &= ~MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS; + __raw_writel(reg, MXC_CCM_CLPCR); + + return 0; +} + +static void _clk_sdma_disable(struct clk *clk) +{ + u32 reg; + + _clk_disable(clk); + /* No handshake with SDMA as its not enabled. */ + reg = __raw_readl(MXC_CCM_CLPCR); + reg |= MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS; + __raw_writel(reg, MXC_CCM_CLPCR); +} + + +static struct clk sdma_clk[] = { + { + .name = "sdma_ahb_clk", + .parent = &ahb_clk, + .secondary = &emi_fast_clk, + .enable_reg = MXC_CCM_CCGR4, + .enable_shift = MXC_CCM_CCGR4_CG15_OFFSET, + .enable = _clk_sdma_enable, + .disable = _clk_sdma_disable, + }, + { + .name = "sdma_ipg_clk", + .parent = &ipg_clk, +#ifdef CONFIG_SDMA_IRAM + .secondary = &emi_intr_clk, +#endif + }, +}; + +static int _clk_ipu_enable(struct clk *clk) +{ + u32 reg; + + _clk_enable(clk); + /* Handshake with IPU when certain clock rates are changed. */ + reg = __raw_readl(MXC_CCM_CCDR); + reg &= ~MXC_CCM_CCDR_IPU_HS_MASK; + __raw_writel(reg, MXC_CCM_CCDR); + + /* Handshake with IPU when LPM is entered as its enabled. */ + reg = __raw_readl(MXC_CCM_CLPCR); + reg &= ~MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS; + __raw_writel(reg, MXC_CCM_CLPCR); + + + return 0; +} + +static void _clk_ipu_disable(struct clk *clk) +{ + u32 reg; + _clk_disable(clk); + + /* No handshake with IPU whe dividers are changed + * as its not enabled. */ + reg = __raw_readl(MXC_CCM_CCDR); + reg |= MXC_CCM_CCDR_IPU_HS_MASK; + __raw_writel(reg, MXC_CCM_CCDR); + + /* No handshake with IPU when LPM is entered as its not enabled. */ + reg = __raw_readl(MXC_CCM_CLPCR); + reg |= MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS; + __raw_writel(reg, MXC_CCM_CLPCR); + +} + + +static struct clk ipu_clk[] = { + { + .name = "ipu_clk", + .parent = &ahb_clk, + .secondary = &ipu_clk[1], + .enable_reg = MXC_CCM_CCGR5, + .enable_shift = MXC_CCM_CCGR5_CG5_OFFSET, + .enable = _clk_ipu_enable, + .disable = _clk_ipu_disable, + }, + { + .name = "ipu_sec_clk", + .parent = &emi_fast_clk, + .secondary = &ahbmux1_clk, + } +}; + +static int _clk_ipu_di_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CSCMR2); + reg &= ~MXC_CCM_CSCMR2_DI_CLK_SEL_MASK; + if (parent == &pll3_sw_clk) + ; + else if (parent == &osc_clk) + reg |= 1 << MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET; + else if (parent == &ckih_clk) + reg |= 2 << MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET; + else if (parent == &tve_clk) + reg |= 3 << MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET; + else /* Assume any other clock is external clock pin */ + reg |= 4 << MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET; + __raw_writel(reg, MXC_CCM_CSCMR2); + + return 0; +} + +static void _clk_ipu_di_recalc(struct clk *clk) +{ + u32 reg, div, mux; + + reg = __raw_readl(MXC_CCM_CSCMR2); + mux = (reg & MXC_CCM_CSCMR2_DI_CLK_SEL_MASK) >> + MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET; + if (mux == 0) { + reg = __raw_readl(MXC_CCM_CDCDR) & + MXC_CCM_CDCDR_DI_CLK_PRED_MASK; + div = (reg >> MXC_CCM_CDCDR_DI_CLK_PRED_OFFSET) + 1; + clk->rate = clk->parent->rate / div; + } else if (mux == 3) { + clk->rate = clk->parent->rate / 8; + } else { + clk->rate = clk->parent->rate; + } +} + +static struct clk ipu_di_clk = { + .name = "ipu_di_clk", + .parent = &pll3_sw_clk, + .enable_reg = MXC_CCM_CCGR5, + .enable_shift = MXC_CCM_CCGR5_CG6_OFFSET, + .recalc = _clk_ipu_di_recalc, + .set_parent = _clk_ipu_di_set_parent, + .enable = _clk_enable, + .disable = _clk_disable, +}; + +static int _clk_csi0_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + reg = __raw_readl(MXC_CCM_CSCMR2); + mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, NULL); + reg = (reg & ~MXC_CCM_CSCMR2_CSI_MCLK1_CLK_SEL_MASK) | + (mux << MXC_CCM_CSCMR2_CSI_MCLK1_CLK_SEL_OFFSET); + __raw_writel(reg, MXC_CCM_CSCMR2); + + return 0; +} + +static void _clk_csi0_recalc(struct clk *clk) +{ + u32 reg, pred, podf; + + reg = __raw_readl(MXC_CCM_CSCDR4); + pred = ((reg & MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_MASK) >> + MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_OFFSET) + 1; + podf = ((reg & MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_MASK) >> + MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_OFFSET) + 1; + clk->rate = clk->parent->rate / (pred * podf); +} + +static unsigned long _clk_csi0_round_rate(struct clk *clk, unsigned long rate) +{ + u32 pre, post; + u32 div = clk->parent->rate / rate; + if (clk->parent->rate % rate) + div++; + + __calc_pre_post_dividers(div, &pre, &post); + + return clk->parent->rate / (pre * post); +} + +static int _clk_csi0_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg; + u32 div; + u32 pre, post; + + div = clk->parent->rate / rate; + + if ((clk->parent->rate / div) != rate) + return -EINVAL; + + __calc_pre_post_dividers(div, &pre, &post); + + /* Set CSI clock divider */ + reg = __raw_readl(MXC_CCM_CSCDR4) & + ~(MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_MASK | + MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_MASK); + reg |= (post - 1) << MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_OFFSET; + reg |= (pre - 1) << MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_OFFSET; + __raw_writel(reg, MXC_CCM_CSCDR4); + + clk->rate = rate; + return 0; +} + +static struct clk csi0_clk = { + .name = "csi_mclk1", + .parent = &pll3_sw_clk, + .set_parent = _clk_csi0_set_parent, + .recalc = _clk_csi0_recalc, + .round_rate = _clk_csi0_round_rate, + .set_rate = _clk_csi0_set_rate, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR6, + .enable_shift = MXC_CCM_CCGR6_CG2_OFFSET, + .disable = _clk_disable, +}; + +static int _clk_csi1_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + reg = __raw_readl(MXC_CCM_CSCMR2); + mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, NULL); + reg = (reg & ~MXC_CCM_CSCMR2_CSI_MCLK2_CLK_SEL_MASK) | + (mux << MXC_CCM_CSCMR2_CSI_MCLK2_CLK_SEL_OFFSET); + __raw_writel(reg, MXC_CCM_CSCMR2); + + return 0; +} + +static void _clk_csi1_recalc(struct clk *clk) +{ + u32 reg, pred, podf; + + reg = __raw_readl(MXC_CCM_CSCDR4); + pred = ((reg & MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_MASK) >> + MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_OFFSET) + 1; + podf = ((reg & MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_MASK) >> + MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_OFFSET) + 1; + clk->rate = clk->parent->rate / (pred * podf); +} + +static unsigned long _clk_csi1_round_rate(struct clk *clk, unsigned long rate) +{ + u32 pre, post; + u32 div = clk->parent->rate / rate; + if (clk->parent->rate % rate) + div++; + + __calc_pre_post_dividers(div, &pre, &post); + + return clk->parent->rate / (pre * post); +} + +static int _clk_csi1_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg; + u32 div; + u32 pre, post; + + div = clk->parent->rate / rate; + + if ((clk->parent->rate / div) != rate) + return -EINVAL; + + __calc_pre_post_dividers(div, &pre, &post); + + /* Set CSI clock divider */ + reg = __raw_readl(MXC_CCM_CSCDR4) & + ~(MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_MASK | + MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_MASK); + reg |= (post - 1) << MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_OFFSET; + reg |= (pre - 1) << MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_OFFSET; + __raw_writel(reg, MXC_CCM_CSCDR4); + + clk->rate = rate; + return 0; +} + +static struct clk csi1_clk = { + .name = "csi_mclk2", + .parent = &pll3_sw_clk, + .set_parent = _clk_csi1_set_parent, + .recalc = _clk_csi1_recalc, + .round_rate = _clk_csi1_round_rate, + .set_rate = _clk_csi1_set_rate, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR6, + .enable_shift = MXC_CCM_CCGR6_CG3_OFFSET, + .disable = _clk_disable, +}; + + +static int _clk_hsc_enable(struct clk *clk) +{ + u32 reg; + + _clk_enable(clk); + /* Handshake with IPU when certain clock rates are changed. */ + reg = __raw_readl(MXC_CCM_CCDR); + reg &= ~MXC_CCM_CCDR_HSC_HS_MASK; + __raw_writel(reg, MXC_CCM_CCDR); + + reg = __raw_readl(MXC_CCM_CLPCR); + reg &= ~MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS; + __raw_writel(reg, MXC_CCM_CLPCR); + + return 0; +} + +static void _clk_hsc_disable(struct clk *clk) +{ + u32 reg; + + _clk_disable(clk); + /* No handshake with HSC as its not enabled. */ + reg = __raw_readl(MXC_CCM_CCDR); + reg |= MXC_CCM_CCDR_IPU_HS_MASK; + __raw_writel(reg, MXC_CCM_CCDR); + + reg = __raw_readl(MXC_CCM_CLPCR); + reg |= MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS; + __raw_writel(reg, MXC_CCM_CLPCR); +} + +static struct clk mipi_esc_clk = { + .name = "mipi_esc_clk", + .parent = &pll2_sw_clk, + .enable_reg = MXC_CCM_CCGR4, + .enable_shift = MXC_CCM_CCGR4_CG5_OFFSET, +}; + +static struct clk mipi_hsc2_clk = { + .name = "mipi_hsc2_clk", + .parent = &pll2_sw_clk, + .enable_reg = MXC_CCM_CCGR4, + .enable_shift = MXC_CCM_CCGR4_CG4_OFFSET, + .secondary = &mipi_esc_clk, +}; + +static struct clk mipi_hsc1_clk = { + .name = "mipi_hsc1_clk", + .parent = &pll2_sw_clk, + .enable_reg = MXC_CCM_CCGR4, + .enable_shift = MXC_CCM_CCGR4_CG3_OFFSET, + .secondary = &mipi_hsc2_clk, +}; + +static struct clk mipi_hsp_clk = { + .name = "mipi_hsp_clk", + .parent = &ipu_clk[0], + .enable_reg = MXC_CCM_CCGR4, + .enable_shift = MXC_CCM_CCGR4_CG6_OFFSET, + .enable = _clk_hsc_enable, + .disable = _clk_hsc_disable, + .secondary = &mipi_hsc1_clk, +}; + +static int _clk_tve_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CSCMR1); + + if (parent == &pll3_sw_clk) { + reg &= ~(MXC_CCM_CSCMR1_TVE_CLK_SEL); + } else if (parent == &osc_clk) { + reg |= MXC_CCM_CSCMR1_TVE_CLK_SEL; + reg &= MXC_CCM_CSCMR1_TVE_EXT_CLK_SEL; + } else if (parent == &ckih_clk) { + reg |= MXC_CCM_CSCMR1_TVE_CLK_SEL; + reg |= MXC_CCM_CSCMR1_TVE_EXT_CLK_SEL; + } else { + BUG(); + } + + __raw_writel(reg, MXC_CCM_CSCMR1); + return 0; +} + +static void _clk_tve_recalc(struct clk *clk) +{ + u32 reg, div; + + reg = __raw_readl(MXC_CCM_CSCMR1); + if ((reg & MXC_CCM_CSCMR1_TVE_CLK_SEL) == 0) { + reg = __raw_readl(MXC_CCM_CDCDR) & + MXC_CCM_CDCDR_TVE_CLK_PRED_MASK; + div = (reg >> MXC_CCM_CDCDR_TVE_CLK_PRED_OFFSET) + 1; + clk->rate = clk->parent->rate / div; + } else { + clk->rate = clk->parent->rate; + } +} + +static unsigned long _clk_tve_round_rate(struct clk *clk, + unsigned long rate) +{ + u32 reg, div; + + reg = __raw_readl(MXC_CCM_CSCMR1); + if (reg & MXC_CCM_CSCMR1_TVE_CLK_SEL) + return -EINVAL; + + div = clk->parent->rate / rate; + if (div > 8) + div = 8; + else if (div == 0) + div++; + return clk->parent->rate / div; +} + +static int _clk_tve_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg, div; + + reg = __raw_readl(MXC_CCM_CSCMR1); + if (reg & MXC_CCM_CSCMR1_TVE_CLK_SEL) + return -EINVAL; + + div = clk->parent->rate / rate; + if (div == 0) + div++; + if (((clk->parent->rate / div) != rate) || (div > 8)) + return -EINVAL; + + div--; + reg = __raw_readl(MXC_CCM_CDCDR) & ~MXC_CCM_CDCDR_TVE_CLK_PRED_MASK; + reg |= div << MXC_CCM_CDCDR_TVE_CLK_PRED_OFFSET; + __raw_writel(reg, MXC_CCM_CDCDR); + clk->rate = rate; + return 0; +} + +static struct clk tve_clk = { + .name = "tve_clk", + .parent = &pll3_sw_clk, + .set_parent = _clk_tve_set_parent, + .enable_reg = MXC_CCM_CCGR2, + .enable_shift = MXC_CCM_CCGR2_CG15_OFFSET, + .recalc = _clk_tve_recalc, + .round_rate = _clk_tve_round_rate, + .set_rate = _clk_tve_set_rate, + .enable = _clk_enable, + .disable = _clk_disable, +}; + +static struct clk spba_clk = { + .name = "spba_clk", + .parent = &ipg_clk, + .enable_reg = MXC_CCM_CCGR5, + .enable_shift = MXC_CCM_CCGR5_CG0_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, +}; + +static void _clk_uart_recalc(struct clk *clk) +{ + u32 reg, prediv, podf; + + reg = __raw_readl(MXC_CCM_CSCDR1); + prediv = ((reg & MXC_CCM_CSCDR1_UART_CLK_PRED_MASK) >> + MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET) + 1; + podf = ((reg & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK) >> + MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET) + 1; + + clk->rate = clk->parent->rate / (prediv * podf); +} + +static int _clk_uart_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, + &lp_apm_clk); + reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_UART_CLK_SEL_MASK; + reg |= mux << MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET; + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + +static struct clk uart_main_clk = { + .name = "uart_main_clk", + .parent = &pll2_sw_clk, + .recalc = _clk_uart_recalc, + .set_parent = _clk_uart_set_parent, + .flags = RATE_PROPAGATES, +}; + +static struct clk uart1_clk[] = { + { + .name = "uart_clk", + .id = 0, + .parent = &uart_main_clk, + .secondary = &uart1_clk[1], + .enable_reg = MXC_CCM_CCGR1, + .enable_shift = MXC_CCM_CCGR1_CG4_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, + { + .name = "uart_ipg_clk", + .id = 0, + .parent = &ipg_clk, + .secondary = &aips_tz1_clk, + .enable_reg = MXC_CCM_CCGR1, + .enable_shift = MXC_CCM_CCGR1_CG3_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, +}; + +static struct clk uart2_clk[] = { + { + .name = "uart_clk", + .id = 1, + .parent = &uart_main_clk, + .secondary = &uart2_clk[1], + .enable_reg = MXC_CCM_CCGR1, + .enable_shift = MXC_CCM_CCGR1_CG6_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, + { + .name = "uart_ipg_clk", + .id = 1, + .parent = &ipg_clk, + .secondary = &aips_tz1_clk, + .enable_reg = MXC_CCM_CCGR1, + .enable_shift = MXC_CCM_CCGR1_CG5_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, +}; + +static struct clk uart3_clk[] = { + { + .name = "uart_clk", + .id = 2, + .parent = &uart_main_clk, + .secondary = &uart3_clk[1], + .enable_reg = MXC_CCM_CCGR1, + .enable_shift = MXC_CCM_CCGR1_CG8_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, + { + .name = "uart_ipg_clk", + .id = 2, + .parent = &ipg_clk, + .secondary = &spba_clk, + .enable_reg = MXC_CCM_CCGR1, + .enable_shift = MXC_CCM_CCGR1_CG7_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, +}; + +static struct clk gpt_clk[] = { + { + .name = "gpt_clk", + .parent = &ipg_perclk, + .id = 0, + .enable_reg = MXC_CCM_CCGR2, + .enable_shift = MXC_CCM_CCGR2_CG9_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + .secondary = &gpt_clk[1], + }, + { + .name = "gpt_ipg_clk", + .id = 0, + .parent = &ipg_clk, + .enable_reg = MXC_CCM_CCGR2, + .enable_shift = MXC_CCM_CCGR2_CG10_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, + { + .name = "gpt_32k_clk", + .id = 0, + .parent = &ckil_clk, + }, +}; + +static struct clk pwm1_clk[] = { + { + .name = "pwm_clk", + .parent = &ipg_perclk, + .id = 0, + .enable_reg = MXC_CCM_CCGR2, + .enable_shift = MXC_CCM_CCGR2_CG6_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + .secondary = &pwm1_clk[1], + }, + { + .name = "pwm_ipg_clk", + .id = 0, + .parent = &ipg_clk, + .enable_reg = MXC_CCM_CCGR2, + .enable_shift = MXC_CCM_CCGR2_CG5_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, + { + .name = "pwm_32k_clk", + .id = 0, + .parent = &ckil_clk, + }, +}; + +static struct clk pwm2_clk[] = { + { + .name = "pwm_clk", + .parent = &ipg_perclk, + .id = 1, + .enable_reg = MXC_CCM_CCGR2, + .enable_shift = MXC_CCM_CCGR2_CG8_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + .secondary = &pwm2_clk[1], + }, + { + .name = "pwm_ipg_clk", + .id = 1, + .parent = &ipg_clk, + .enable_reg = MXC_CCM_CCGR2, + .enable_shift = MXC_CCM_CCGR2_CG7_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, + { + .name = "pwm_32k_clk", + .id = 1, + .parent = &ckil_clk, + }, +}; + +static struct clk i2c_clk[] = { + { + .name = "i2c_clk", + .id = 0, + .parent = &ipg_perclk, + .enable_reg = MXC_CCM_CCGR1, + .enable_shift = MXC_CCM_CCGR1_CG9_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, + { + .name = "i2c_clk", + .id = 1, + .parent = &ipg_perclk, + .enable_reg = MXC_CCM_CCGR1, + .enable_shift = MXC_CCM_CCGR1_CG10_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, +}; + +static void _clk_hsi2c_serial_recalc(struct clk *clk) +{ + u32 reg, prediv, podf; + + reg = __raw_readl(MXC_CCM_CSCDR3); + prediv = ((reg & MXC_CCM_CSCDR3_HSI2C_CLK_PRED_MASK) >> + MXC_CCM_CSCDR3_HSI2C_CLK_PRED_OFFSET) + 1; + podf = ((reg & MXC_CCM_CSCDR3_HSI2C_CLK_PODF_MASK) >> + MXC_CCM_CSCDR3_HSI2C_CLK_PODF_OFFSET) + 1; + + clk->rate = clk->parent->rate / (prediv * podf); +} + +static struct clk hsi2c_serial_clk = { + .name = "hsi2c_serial_clk", + .id = 0, + .parent = &pll3_sw_clk, + .secondary = &spba_clk, + .enable_reg = MXC_CCM_CCGR1, + .enable_shift = MXC_CCM_CCGR1_CG11_OFFSET, + .recalc = _clk_hsi2c_serial_recalc, + .enable = _clk_enable, + .disable = _clk_disable, +}; + +static struct clk hsi2c_clk = { + .name = "hsi2c_clk", + .id = 0, + .parent = &ipg_clk, + .enable_reg = MXC_CCM_CCGR1, + .enable_shift = MXC_CCM_CCGR1_CG12_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, +}; + +static void _clk_cspi_recalc(struct clk *clk) +{ + u32 reg, prediv, podf; + + reg = __raw_readl(MXC_CCM_CSCDR2); + prediv = ((reg & MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK) >> + MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET) + 1; + if (prediv == 1) + BUG(); + podf = ((reg & MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK) >> + MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET) + 1; + + clk->rate = clk->parent->rate / (prediv * podf); +} + +static int _clk_cspi_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, + &lp_apm_clk); + reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK; + reg |= mux << MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET; + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + +static struct clk cspi_main_clk = { + .name = "cspi_main_clk", + .parent = &pll3_sw_clk, + .recalc = _clk_cspi_recalc, + .set_parent = _clk_cspi_set_parent, + .flags = RATE_PROPAGATES, +}; + +static struct clk cspi1_clk[] = { + { + .name = "cspi_clk", + .id = 0, + .parent = &cspi_main_clk, + .secondary = &cspi1_clk[1], + .enable_reg = MXC_CCM_CCGR4, + .enable_shift = MXC_CCM_CCGR4_CG10_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, + { + .name = "cspi_ipg_clk", + .id = 0, + .parent = &ipg_clk, + .secondary = &spba_clk, + .enable_reg = MXC_CCM_CCGR4, + .enable_shift = MXC_CCM_CCGR4_CG9_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, +}; + +static struct clk cspi2_clk[] = { + { + .name = "cspi_clk", + .id = 1, + .parent = &cspi_main_clk, + .secondary = &cspi2_clk[1], + .enable_reg = MXC_CCM_CCGR4, + .enable_shift = MXC_CCM_CCGR4_CG12_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, + { + .name = "cspi_ipg_clk", + .id = 1, + .parent = &ipg_clk, + .secondary = &aips_tz2_clk, + .enable_reg = MXC_CCM_CCGR4, + .enable_shift = MXC_CCM_CCGR4_CG11_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, +}; + +static struct clk cspi3_clk[] = { + { + .name = "cspi_clk", + .id = 2, + .parent = &cspi_main_clk, + .enable_reg = MXC_CCM_CCGR4, + .enable_shift = MXC_CCM_CCGR4_CG13_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + .secondary = &cspi3_clk[1], + }, + { + .name = "cspi_ipg_clk", + .id = 2, + .parent = &ipg_clk, + .secondary = &aips_tz2_clk, + }, +}; + +static int _clk_ssi_lp_apm_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + mux = _get_mux(parent, &ckih_clk, &lp_apm_clk, &ckih2_clk, NULL); + reg = __raw_readl(MXC_CCM_CSCMR1) & + ~MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_MASK; + reg |= mux << MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_OFFSET; + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + +static struct clk ssi_lp_apm_clk = { + .name = "ssi_lp_apm_clk", + .parent = &ckih_clk, + .set_parent = _clk_ssi_lp_apm_set_parent, +}; + +static void _clk_ssi1_recalc(struct clk *clk) +{ + u32 reg, prediv, podf; + + reg = __raw_readl(MXC_CCM_CS1CDR); + prediv = ((reg & MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK) >> + MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET) + 1; + if (prediv == 1) + BUG(); + podf = ((reg & MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK) >> + MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET) + 1; + + clk->rate = clk->parent->rate / (prediv * podf); +} +static int _clk_ssi1_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, + &pll3_sw_clk, &ssi_lp_apm_clk); + reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_SSI1_CLK_SEL_MASK; + reg |= mux << MXC_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET; + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + +static struct clk ssi1_clk[] = { + { + .name = "ssi_clk", + .id = 0, + .parent = &pll3_sw_clk, + .set_parent = _clk_ssi1_set_parent, + .secondary = &ssi1_clk[1], + .recalc = _clk_ssi1_recalc, + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG9_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, + { + .name = "ssi_ipg_clk", + .id = 0, + .parent = &ipg_clk, + .secondary = &ssi1_clk[2], + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG8_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, + { + .name = "ssi_dep_clk", + .id = 0, + .parent = &aips_tz2_clk, +#ifdef CONFIG_SND_MXC_SOC_IRAM + .secondary = &emi_intr_clk, +#else + .secondary = &emi_fast_clk, +#endif + }, +}; + +static void _clk_ssi2_recalc(struct clk *clk) +{ + u32 reg, prediv, podf; + + reg = __raw_readl(MXC_CCM_CS2CDR); + prediv = ((reg & MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK) >> + MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET) + 1; + if (prediv == 1) + BUG(); + podf = ((reg & MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK) >> + MXC_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET) + 1; + + clk->rate = clk->parent->rate / (prediv * podf); +} + +static int _clk_ssi2_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, + &pll3_sw_clk, &ssi_lp_apm_clk); + reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_SSI2_CLK_SEL_MASK; + reg |= mux << MXC_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET; + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + +static struct clk ssi2_clk[] = { + { + .name = "ssi_clk", + .id = 1, + .parent = &pll3_sw_clk, + .set_parent = _clk_ssi2_set_parent, + .secondary = &ssi2_clk[1], + .recalc = _clk_ssi2_recalc, + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG11_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, + { + .name = "ssi_ipg_clk", + .id = 1, + .parent = &ipg_clk, + .secondary = &ssi2_clk[2], + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG10_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, + { + .name = "ssi_dep_clk", + .id = 1, + .parent = &spba_clk, +#ifdef CONFIG_SND_MXC_SOC_IRAM + .secondary = &emi_intr_clk, +#else + .secondary = &emi_fast_clk, +#endif + }, +}; + +static void _clk_ssi_ext1_recalc(struct clk *clk) +{ + u32 reg, prediv, podf; + + clk->rate = clk->parent->rate; + reg = __raw_readl(MXC_CCM_CSCMR1); + if ((reg & MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL) == 0) { + reg = __raw_readl(MXC_CCM_CS1CDR); + prediv = ((reg & MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_MASK) >> + MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_OFFSET) + 1; + if (prediv == 1) + BUG(); + podf = ((reg & MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_MASK) >> + MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_OFFSET) + 1; + clk->rate = clk->parent->rate / (prediv * podf); + } +} + +static int _clk_ssi_ext1_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + reg = __raw_readl(MXC_CCM_CSCMR1); + if (parent == &ssi1_clk[0]) { + reg |= MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL; + } else { + reg &= ~MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL; + mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, + &ssi_lp_apm_clk); + reg = (reg & ~MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_MASK) | + (mux << MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_OFFSET); + } + + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + +static struct clk ssi_ext1_clk = { + .name = "ssi_ext1_clk", + .parent = &pll3_sw_clk, + .set_parent = _clk_ssi_ext1_set_parent, + .recalc = _clk_ssi_ext1_recalc, + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG14_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, +}; + +static void _clk_ssi_ext2_recalc(struct clk *clk) +{ + u32 reg, prediv, podf; + + clk->rate = clk->parent->rate; + reg = __raw_readl(MXC_CCM_CSCMR1); + if ((reg & MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL) == 0) { + reg = __raw_readl(MXC_CCM_CS2CDR); + prediv = ((reg & MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_MASK) >> + MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_OFFSET) + 1; + if (prediv == 1) + BUG(); + podf = ((reg & MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_MASK) >> + MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_OFFSET) + 1; + clk->rate = clk->parent->rate / (prediv * podf); + } +} + +static int _clk_ssi_ext2_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + reg = __raw_readl(MXC_CCM_CSCMR1); + if (parent == &ssi2_clk[0]) { + reg |= MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL; + } else { + reg &= ~MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL; + mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, + &ssi_lp_apm_clk); + reg = (reg & ~MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_MASK) | + (mux << MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_OFFSET); + } + + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + +static struct clk ssi_ext2_clk = { + .name = "ssi_ext2_clk", + .parent = &pll3_sw_clk, + .set_parent = _clk_ssi_ext2_set_parent, + .recalc = _clk_ssi_ext2_recalc, + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG15_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, +}; + +static struct clk iim_clk = { + .name = "iim_clk", + .parent = &ipg_clk, + .secondary = &aips_tz2_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR0, + .enable_shift = MXC_CCM_CCGR0_CG15_OFFSET, + .disable = _clk_disable, +}; + +static struct clk tmax1_clk = { + .name = "tmax1_clk", + .id = 0, + .parent = &ahb_clk, + .secondary = &ahb_max_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR1, + .enable_shift = MXC_CCM_CCGR1_CG0_OFFSET, + .disable = _clk_disable, + }; + +static struct clk tmax2_clk = { + .name = "tmax2_clk", + .id = 0, + .parent = &ahb_clk, + .secondary = &ahb_max_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR1, + .enable_shift = MXC_CCM_CCGR1_CG1_OFFSET, + .disable = _clk_disable, +}; + +static struct clk tmax3_clk = { + .name = "tmax3_clk", + .id = 0, + .parent = &ahb_clk, + .secondary = &ahb_max_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR1, + .enable_shift = MXC_CCM_CCGR1_CG2_OFFSET, + .disable = _clk_disable, +}; + +static void _clk_usboh3_recalc(struct clk *clk) +{ + u32 reg, prediv, podf; + + reg = __raw_readl(MXC_CCM_CSCDR1); + prediv = ((reg & MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK) >> + MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET) + 1; + if (prediv == 1) + BUG(); + podf = ((reg & MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK) >> + MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET) + 1; + + clk->rate = clk->parent->rate / (prediv * podf); +} + +static int _clk_usboh3_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, + &lp_apm_clk); + reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USBOH3_CLK_SEL_MASK; + reg |= mux << MXC_CCM_CSCMR1_USBOH3_CLK_SEL_OFFSET; + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + +static struct clk usboh3_clk[] = { + { + .name = "usboh3_clk", + .parent = &pll3_sw_clk, + .set_parent = _clk_usboh3_set_parent, + .recalc = _clk_usboh3_recalc, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR2, + .enable_shift = MXC_CCM_CCGR2_CG14_OFFSET, + .disable = _clk_disable, + .secondary = &usboh3_clk[1], + }, + { + .name = "usb_ahb_clk", + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR2, + .enable_shift = MXC_CCM_CCGR2_CG13_OFFSET, + .disable = _clk_disable, + .secondary = &usboh3_clk[2], + }, + { + .name = "usb_sec_clk", + .parent = &tmax2_clk, + .secondary = &emi_fast_clk, + }, +}; + +static void _clk_usb_phy_recalc(struct clk *clk) +{ + u32 reg, prediv, podf; + + if (clk->parent == &pll3_sw_clk) { + reg = __raw_readl(MXC_CCM_CDCDR); + prediv = ((reg & MXC_CCM_CDCDR_USB_PHY_PRED_MASK) >> + MXC_CCM_CDCDR_USB_PHY_PRED_OFFSET) + 1; + podf = ((reg & MXC_CCM_CDCDR_USB_PHY_PODF_MASK) >> + MXC_CCM_CDCDR_USB_PHY_PODF_OFFSET) + 1; + + clk->rate = clk->parent->rate / (prediv * podf); + } else + clk->rate = clk->parent->rate; +} + +static int _clk_usb_phy_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CSCMR1); + if (parent == &osc_clk) + reg &= ~MXC_CCM_CSCMR1_USB_PHY_CLK_SEL; + else if (parent == &pll3_sw_clk) + reg |= MXC_CCM_CSCMR1_USB_PHY_CLK_SEL; + else + BUG(); + + __raw_writel(reg, MXC_CCM_CSCMR1); + return 0; +} + +static struct clk usb_phy_clk = { + .name = "usb_phy_clk", + .parent = &pll3_sw_clk, + .secondary = &tmax3_clk, + .set_parent = _clk_usb_phy_set_parent, + .recalc = _clk_usb_phy_recalc, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR2, + .enable_shift = MXC_CCM_CCGR2_CG0_OFFSET, + .disable = _clk_disable, +}; + +static struct clk esdhc_dep_clks = { + .name = "sd_dep_clk", + .parent = &spba_clk, + .secondary = &emi_fast_clk, +}; + + +static void _clk_esdhc1_recalc(struct clk *clk) +{ + u32 reg, prediv, podf; + + reg = __raw_readl(MXC_CCM_CSCDR1); + prediv = ((reg & MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_MASK) >> + MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_OFFSET) + 1; + podf = ((reg & MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_MASK) >> + MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_OFFSET) + 1; + + clk->rate = clk->parent->rate / (prediv * podf); +} + +static int _clk_esdhc1_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, + &lp_apm_clk); + reg = __raw_readl(MXC_CCM_CSCMR1) & + ~MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_MASK; + reg |= mux << MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_OFFSET; + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + +static struct clk esdhc1_clk[] = { + { + .name = "esdhc_clk", + .id = 0, + .parent = &pll3_sw_clk, + .set_parent = _clk_esdhc1_set_parent, + .recalc = _clk_esdhc1_recalc, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG1_OFFSET, + .disable = _clk_disable, + .secondary = &esdhc1_clk[1], + }, + { + .name = "esdhc_ipg_clk", + .id = 0, + .parent = &ipg_clk, + .secondary = &esdhc1_clk[2], + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG0_OFFSET, + .disable = _clk_disable, + }, + { + .name = "esdhc_sec_clk", + .id = 0, + .parent = &tmax3_clk, + .secondary = &esdhc_dep_clks, + }, + +}; + +static void _clk_esdhc2_recalc(struct clk *clk) +{ + u32 reg, prediv, podf; + + reg = __raw_readl(MXC_CCM_CSCDR1); + prediv = ((reg & MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_MASK) >> + MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_OFFSET) + 1; + podf = ((reg & MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_MASK) >> + MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_OFFSET) + 1; + + clk->rate = clk->parent->rate / (prediv * podf); +} + +static int _clk_esdhc2_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, + &lp_apm_clk); + reg = __raw_readl(MXC_CCM_CSCMR1) & + ~MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_MASK; + reg |= mux << MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_OFFSET; + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + +static struct clk esdhc2_clk[] = { + { + .name = "esdhc_clk", + .id = 1, + .parent = &pll3_sw_clk, + .set_parent = _clk_esdhc2_set_parent, + .recalc = _clk_esdhc2_recalc, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG3_OFFSET, + .disable = _clk_disable, + .secondary = &esdhc2_clk[1], + }, + { + .name = "esdhc_ipg_clk", + .id = 1, + .parent = &ipg_clk, + .secondary = &esdhc2_clk[2], + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG2_OFFSET, + .disable = _clk_disable, + }, + { + .name = "esdhc_sec_clk", + .id = 0, + .parent = &tmax2_clk, + .secondary = &esdhc_dep_clks, + }, +}; + +static int _clk_esdhc3_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CSCMR1); + if (parent == &esdhc1_clk[0]) + reg &= ~MXC_CCM_CSCMR1_ESDHC3_CLK_SEL; + else if (parent == &esdhc2_clk[0]) + reg |= MXC_CCM_CSCMR1_ESDHC3_CLK_SEL; + else + BUG(); + + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + +static struct clk esdhc3_clk[] = { + { + .name = "esdhc_clk", + .id = 2, + .parent = &esdhc1_clk[0], + .set_parent = _clk_esdhc3_set_parent, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG5_OFFSET, + .disable = _clk_disable, + .secondary = &esdhc3_clk[1], + }, + { + .name = "esdhc_ipg_clk", + .id = 2, + .parent = &ipg_clk, + .secondary = &esdhc3_clk[2], + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG4_OFFSET, + .disable = _clk_disable, + }, + { + .name = "esdhc_sec_clk", + .id = 0, + .parent = &ahb_max_clk, + .secondary = &esdhc_dep_clks, + }, +}; + + +static int _clk_esdhc4_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg; + + reg = __raw_readl(MXC_CCM_CSCMR1); + if (parent == &esdhc1_clk[0]) + reg &= ~MXC_CCM_CSCMR1_ESDHC4_CLK_SEL; + else if (parent == &esdhc2_clk[0]) + reg |= MXC_CCM_CSCMR1_ESDHC4_CLK_SEL; + else + BUG(); + + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + +static struct clk esdhc4_clk[] = { + { + .name = "esdhc_clk", + .id = 3, + .parent = &esdhc1_clk[0], + .set_parent = _clk_esdhc4_set_parent, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG7_OFFSET, + .disable = _clk_disable, + .secondary = &esdhc3_clk[1], + }, + { + .name = "esdhc_ipg_clk", + .id = 3, + .parent = &ipg_clk, + .secondary = &esdhc3_clk[2], + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGR3_CG6_OFFSET, + .disable = _clk_disable, + }, + { + .name = "esdhc_sec_clk", + .id = 0, + .parent = &tmax3_clk, + .secondary = &esdhc_dep_clks, + }, +}; + +static void _clk_nfc_recalc(struct clk *clk) +{ + u32 reg, div; + + reg = __raw_readl(MXC_CCM_CBCDR); + div = ((reg & MXC_CCM_CBCDR_NFC_PODF_MASK) >> + MXC_CCM_CBCDR_NFC_PODF_OFFSET) + 1; + clk->rate = clk->parent->rate / div; +} + +static struct clk emi_enfc_clk = { + .name = "nfc_clk", + .parent = &emi_slow_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR5, + .enable_shift = MXC_CCM_CCGR5_CG10_OFFSET, + .disable = _clk_disable_inwait, + .recalc = _clk_nfc_recalc, +}; + +static int _clk_spdif_xtal_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + mux = _get_mux(parent, &osc_clk, &ckih_clk, &ckih2_clk, NULL); + reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_SPDIF_CLK_SEL_MASK; + reg |= mux << MXC_CCM_CSCMR1_SPDIF_CLK_SEL_OFFSET; + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + +static struct clk spdif_xtal_clk = { + .name = "spdif_xtal_clk", + .parent = &osc_clk, + .set_parent = _clk_spdif_xtal_set_parent, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR5, + .enable_shift = MXC_CCM_CCGR5_CG15_OFFSET, + .disable = _clk_disable, +}; + +static int _clk_spdif0_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + reg = __raw_readl(MXC_CCM_CSCMR2); + reg |= MXC_CCM_CSCMR2_SPDIF0_COM; + if (parent != &ssi1_clk[0]) { + reg &= ~MXC_CCM_CSCMR2_SPDIF0_COM; + mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, + &spdif_xtal_clk); + reg = (reg & ~MXC_CCM_CSCMR2_SPDIF0_CLK_SEL_MASK) | + (mux << MXC_CCM_CSCMR2_SPDIF0_CLK_SEL_OFFSET); + } + __raw_writel(reg, MXC_CCM_CSCMR2); + + return 0; +} + +static void _clk_spdif0_recalc(struct clk *clk) +{ + u32 reg, pred, podf; + + if (clk->parent == &ssi1_clk[0]) { + clk->rate = clk->parent->rate; + } else { + reg = __raw_readl(MXC_CCM_CDCDR); + pred = ((reg & MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK) >> + MXC_CCM_CDCDR_SPDIF0_CLK_PRED_OFFSET) + 1; + podf = ((reg & MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK) >> + MXC_CCM_CDCDR_SPDIF0_CLK_PODF_OFFSET) + 1; + clk->rate = clk->parent->rate / (pred * podf); + } +} + +static struct clk spdif0_clk[] = { + { + .name = "spdif_clk", + .id = 0, + .parent = &pll3_sw_clk, + .set_parent = _clk_spdif0_set_parent, + .recalc = _clk_spdif0_recalc, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR5, + .enable_shift = MXC_CCM_CCGR5_CG13_OFFSET, + .disable = _clk_disable, + }, + { + .name = "spdif_ipg_clk", + .id = 0, + .parent = &ipg_clk, + .secondary = &spba_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR5, + .enable_shift = MXC_CCM_CCGR5_CG15_OFFSET, + .disable = _clk_disable, + }, +}; + +static int _clk_spdif1_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + reg = __raw_readl(MXC_CCM_CSCMR2); + reg |= MXC_CCM_CSCMR2_SPDIF1_COM; + if (parent != &ssi2_clk[0]) { + reg &= ~MXC_CCM_CSCMR2_SPDIF1_COM; + mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, + &spdif_xtal_clk); + reg = (reg & ~MXC_CCM_CSCMR2_SPDIF1_CLK_SEL_MASK) | + (mux << MXC_CCM_CSCMR2_SPDIF1_CLK_SEL_OFFSET); + } + __raw_writel(reg, MXC_CCM_CSCMR2); + + return 0; +} + +static void _clk_spdif1_recalc(struct clk *clk) +{ + u32 reg, pred, podf; + + if (clk->parent == &ssi2_clk[0]) { + clk->rate = clk->parent->rate; + } else { + reg = __raw_readl(MXC_CCM_CDCDR); + pred = ((reg & MXC_CCM_CDCDR_SPDIF1_CLK_PRED_MASK) >> + MXC_CCM_CDCDR_SPDIF1_CLK_PRED_OFFSET) + 1; + podf = ((reg & MXC_CCM_CDCDR_SPDIF1_CLK_PODF_MASK) >> + MXC_CCM_CDCDR_SPDIF1_CLK_PODF_OFFSET) + 1; + clk->rate = clk->parent->rate / (pred * podf); + } +} + +static struct clk spdif1_clk[] = { + { + .name = "spdif_clk", + .id = 1, + .parent = &pll3_sw_clk, + .set_parent = _clk_spdif1_set_parent, + .recalc = _clk_spdif1_recalc, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR5, + .enable_shift = MXC_CCM_CCGR5_CG14_OFFSET, + .disable = _clk_disable, + }, + { + .name = "spdif_ipg_clk", + .id = 0, + .parent = &ipg_clk, + .secondary = &spba_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR5, + .enable_shift = MXC_CCM_CCGR5_CG15_OFFSET, + .disable = _clk_disable, + }, +}; + +static int _clk_ddr_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, reg2, mux; + reg = __raw_readl(MXC_CCM_CBCMR); + reg2 = __raw_readl(MXC_CCM_CBCDR); + mux = _get_mux_ddr(parent, &axi_a_clk, &axi_b_clk, &emi_slow_clk, &ahb_clk, &ddr_hf_clk); + if (mux < 4) { + reg = (reg & ~MXC_CCM_CBCMR_DDR_CLK_SEL_MASK) | + (mux << MXC_CCM_CBCMR_DDR_CLK_SEL_OFFSET); + __raw_writel(reg, MXC_CCM_CBCMR); + } else { + reg2 = (reg2 & ~MXC_CCM_CBCDR_DDR_HF_SEL) | + (MXC_CCM_CBCDR_DDR_HF_SEL); + __raw_writel(reg2, MXC_CCM_CBCDR); + } + + return 0; +} + +static struct clk ddr_clk = { + .name = "ddr_clk", + .parent = &ddr_hf_clk, + .set_parent = _clk_ddr_set_parent, + .flags = RATE_PROPAGATES, +}; + +static int _clk_arm_axi_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + reg = __raw_readl(MXC_CCM_CBCMR); + mux = _get_mux(parent, &axi_a_clk, &axi_b_clk, &emi_slow_clk, &ahb_clk); + reg = (reg & ~MXC_CCM_CBCMR_ARM_AXI_CLK_SEL_MASK) | + (mux << MXC_CCM_CBCMR_ARM_AXI_CLK_SEL_OFFSET); + __raw_writel(reg, MXC_CCM_CBCMR); + + return 0; +} + +static struct clk arm_axi_clk = { + .name = "arm_axi_clk", + .parent = &axi_a_clk, + .set_parent = _clk_arm_axi_set_parent, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR0, + .enable_shift = MXC_CCM_CCGR0_CG1_OFFSET, + .disable = _clk_disable, +}; + +static int _clk_vpu_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + reg = __raw_readl(MXC_CCM_CBCMR); + mux = _get_mux(parent, &axi_a_clk, &axi_b_clk, &emi_slow_clk, &ahb_clk); + reg = (reg & ~MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_MASK) | + (mux << MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_OFFSET); + __raw_writel(reg, MXC_CCM_CBCMR); + + return 0; +} + +static struct clk vpu_clk[] = { + { + .name = "vpu_clk", + .set_parent = _clk_vpu_set_parent, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR5, + .enable_shift = MXC_CCM_CCGR5_CG4_OFFSET, + .disable = _clk_disable, + .secondary = &vpu_clk[1], + }, + { + .name = "vpu_core_clk", + .set_parent = _clk_vpu_set_parent, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR5, + .enable_shift = MXC_CCM_CCGR5_CG3_OFFSET, + .disable = _clk_disable, + .secondary = &vpu_clk[2], + }, + { + .name = "vpu_emi_clk", + .parent = &emi_fast_clk, +#ifdef CONFIG_MXC_VPU_IRAM + .secondary = &emi_intr_clk, +#endif + } +}; + +static int _clk_lpsr_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + reg = __raw_readl(MXC_CCM_CLPCR); + mux = _get_mux(parent, &ckil_clk, &fpm_clk, &fpm_div2_clk, NULL); + reg = (reg & ~MXC_CCM_CLPCR_LPSR_CLK_SEL_MASK) | + (mux << MXC_CCM_CLPCR_LPSR_CLK_SEL_OFFSET); + __raw_writel(reg, MXC_CCM_CLPCR); + + return 0; +} + +static struct clk lpsr_clk = { + .name = "lpsr_clk", + .parent = &ckil_clk, + .set_parent = _clk_lpsr_set_parent, +}; + +static void _clk_pgc_recalc(struct clk *clk) +{ + u32 reg, div; + + reg = __raw_readl(MXC_CCM_CSCDR1); + div = (reg & MXC_CCM_CSCDR1_PGC_CLK_PODF_MASK) >> + MXC_CCM_CSCDR1_PGC_CLK_PODF_OFFSET; + div = 1 >> div; + clk->rate = clk->parent->rate / div; +} + +static struct clk pgc_clk = { + .name = "pgc_clk", + .parent = &ipg_clk, + .recalc = _clk_pgc_recalc, +}; + +/*usb OTG clock */ + +static struct clk usb_clk = { + .name = "usb_clk", + .rate = 60000000, +}; + +static struct clk usb_utmi_clk = { + .name = "usb_utmi_clk", + .enable = _clk_enable, + .enable_reg = MXC_CCM_CSCMR1, + .enable_shift = MXC_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET, + .disable = _clk_disable, +}; + +static struct clk rtc_clk = { + .name = "rtc_clk", + .parent = &ckil_clk, + .secondary = &ipg_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR4, + .enable_shift = MXC_CCM_CCGR4_CG14_OFFSET, + .disable = _clk_disable, +}; + +static struct clk ata_clk = { + .name = "ata_clk", + .parent = &ipg_clk, + .secondary = &spba_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR4, + .enable_shift = MXC_CCM_CCGR4_CG0_OFFSET, + .disable = _clk_disable, +}; + +static struct clk owire_clk = { + .name = "owire_clk", + .parent = &ipg_perclk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR2, + .enable_shift = MXC_CCM_CCGR2_CG11_OFFSET, + .disable = _clk_disable, +}; + + +static struct clk fec_clk[] = { + { + .name = "fec_clk", + .parent = &ipg_clk, + .secondary = &fec_clk[1], + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR2, + .enable_shift = MXC_CCM_CCGR2_CG12_OFFSET, + .disable = _clk_disable, + }, + { + .name = "fec_sec1_clk", + .parent = &tmax2_clk, + .secondary = &fec_clk[2], + }, + { + .name = "fec_sec2_clk", + .parent = &aips_tz2_clk, + .secondary = &emi_fast_clk, + }, +}; + +static struct clk sahara_clk[] = { + { + .name = "sahara_clk", + .parent = &ahb_clk, + .secondary = &sahara_clk[1], + .enable_reg = MXC_CCM_CCGR4, + .enable_shift = MXC_CCM_CCGR4_CG7_OFFSET, + .enable = _clk_enable, + .disable = _clk_disable, + }, + { + .name = "sahara_sec_clk", + .parent = &tmax1_clk, + .secondary = &emi_fast_clk, + } +}; + +static int _clk_gpu3d_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg, mux; + + reg = __raw_readl(MXC_CCM_CBCMR); + mux = _get_mux(parent, &axi_a_clk, &axi_b_clk, &emi_slow_clk, &ahb_clk); + reg = (reg & ~MXC_CCM_CBCMR_GPU_CLK_SEL_MASK) | + (mux << MXC_CCM_CBCMR_GPU_CLK_SEL_OFFSET); + __raw_writel(reg, MXC_CCM_CBCMR); + + return 0; +} + +static struct clk gpu3d_clk = { + .name = "gpu3d_clk", + .parent = &axi_a_clk, + .set_parent = _clk_gpu3d_set_parent, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR5, + .enable_shift = MXC_CCM_CCGR5_CG1_OFFSET, + .disable = _clk_disable, +}; + +static struct clk garb_clk = { + .name = "garb_clk", + .parent = &axi_a_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR5, + .enable_shift = MXC_CCM_CCGR5_CG2_OFFSET, + .disable = _clk_disable, +}; + +static struct clk emi_garb_clk = { + .name = "emi_garb_clk", + .parent = &axi_a_clk, + .enable = _clk_enable, + .enable_reg = MXC_CCM_CCGR6, + .enable_shift = MXC_CCM_CCGR6_CG4_OFFSET, + .disable = _clk_disable, +}; + +static struct clk *mxc_clks[] = { + &osc_clk, + &ckih_clk, + &ckih2_clk, + &ckil_clk, + &fpm_clk, + &fpm_div2_clk, + &pll1_main_clk, + &pll1_sw_clk, + &pll2_sw_clk, + &pll3_sw_clk, + &gpc_dvfs_clk, + &lp_apm_clk, + &cpu_clk, + &periph_apm_clk, + &main_bus_clk, + &axi_a_clk, + &axi_b_clk, + &ahb_clk, + &ahb_max_clk, + &ipg_clk, + &ipg_perclk, + &ahbmux1_clk, + &ahbmux2_clk, + &aips_tz1_clk, + &aips_tz2_clk, + &sdma_clk[0], + &sdma_clk[1], + &ipu_clk[0], + &ipu_clk[1], + &ipu_di_clk, + &tve_clk, + &csi0_clk, + &csi1_clk, + &uart_main_clk, + &uart1_clk[0], + &uart1_clk[1], + &uart2_clk[0], + &uart2_clk[1], + &uart3_clk[0], + &uart3_clk[1], + &spba_clk, + &i2c_clk[0], + &i2c_clk[1], + &hsi2c_clk, + &hsi2c_serial_clk, + &gpt_clk[0], + &gpt_clk[1], + &gpt_clk[2], + &pwm1_clk[0], + &pwm1_clk[1], + &pwm1_clk[2], + &pwm2_clk[0], + &pwm2_clk[1], + &pwm2_clk[2], + &cspi_main_clk, + &cspi1_clk[0], + &cspi1_clk[1], + &cspi2_clk[0], + &cspi2_clk[1], + &cspi3_clk[0], + &cspi3_clk[1], + &ssi_lp_apm_clk, + &ssi1_clk[0], + &ssi1_clk[1], + &ssi1_clk[2], + &ssi2_clk[0], + &ssi2_clk[1], + &ssi2_clk[2], + &ssi_ext1_clk, + &ssi_ext2_clk, + &iim_clk, + &tmax1_clk, + &tmax2_clk, + &tmax3_clk, + &usboh3_clk[0], + &usboh3_clk[1], + &usboh3_clk[2], + &usb_phy_clk, + &usb_utmi_clk, + &usb_clk, + &esdhc1_clk[0], + &esdhc1_clk[1], + &esdhc2_clk[0], + &esdhc2_clk[1], + &esdhc3_clk[0], + &esdhc3_clk[1], + &esdhc4_clk[0], + &esdhc4_clk[1], + &esdhc_dep_clks, + &emi_slow_clk, + &ddr_clk, + &emi_enfc_clk, + &emi_fast_clk, + &emi_intr_clk, + &spdif_xtal_clk, + &spdif0_clk[0], + &spdif0_clk[1], + &spdif1_clk[0], + &spdif1_clk[1], + &arm_axi_clk, + &vpu_clk[0], + &vpu_clk[1], + &vpu_clk[2], + &lpsr_clk, + &pgc_clk, + &rtc_clk, + &ata_clk, + &owire_clk, + &fec_clk[0], + &fec_clk[1], + &fec_clk[2], + &mipi_hsc1_clk, + &mipi_hsc2_clk, + &mipi_esc_clk, + &mipi_hsp_clk, + &sahara_clk[0], + &sahara_clk[1], + &gpu3d_clk, + &garb_clk, + &emi_garb_clk, + &ddr_hf_clk, +}; + +static void clk_tree_init(void) +{ + u32 reg, reg2, dp_ctl; + + ipg_perclk.set_parent(&ipg_perclk, &lp_apm_clk); + + /* + *Initialise the IPG PER CLK dividers to 3. IPG_PER_CLK should be at + * 8MHz, its derived from lp_apm. + */ + reg = __raw_readl(MXC_CCM_CBCDR); + reg &= ~MXC_CCM_CBCDR_PERCLK_PRED1_MASK; + reg &= ~MXC_CCM_CBCDR_PERCLK_PRED2_MASK; + reg &= ~MXC_CCM_CBCDR_PERCLK_PODF_MASK; + reg |= (2 << MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET); + __raw_writel(reg, MXC_CCM_CBCDR); + + /* set pll1_main_clk parent */ + pll1_main_clk.parent = &osc_clk; + dp_ctl = __raw_readl(pll_base[0] + MXC_PLL_DP_CTL); + if ((dp_ctl & MXC_PLL_DP_CTL_REF_CLK_SEL_MASK) == 0) + pll1_main_clk.parent = &fpm_clk; + /* set pll2_sw_clk parent */ + pll2_sw_clk.parent = &osc_clk; + dp_ctl = __raw_readl(pll_base[1] + MXC_PLL_DP_CTL); + if ((dp_ctl & MXC_PLL_DP_CTL_REF_CLK_SEL_MASK) == 0) + pll2_sw_clk.parent = &fpm_clk; + /* set pll3_clk parent */ + pll3_sw_clk.parent = &osc_clk; + dp_ctl = __raw_readl(pll_base[2] + MXC_PLL_DP_CTL); + if ((dp_ctl & MXC_PLL_DP_CTL_REF_CLK_SEL_MASK) == 0) + pll3_sw_clk.parent = &fpm_clk; + + /* set emi_slow_clk parent */ + emi_slow_clk.parent = &main_bus_clk; + reg = __raw_readl(MXC_CCM_CBCDR); + if ((reg & MXC_CCM_CBCDR_EMI_CLK_SEL) != 0) + emi_slow_clk.parent = &ahb_clk; + + /* set ipg_perclk parent */ + ipg_perclk.parent = &lp_apm_clk; + reg = __raw_readl(MXC_CCM_CBCMR); + if ((reg & MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL) != 0) { + ipg_perclk.parent = &ipg_clk; + } else { + if ((reg & MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL) == 0) + ipg_perclk.parent = &main_bus_clk; + } + + /* set DDR clock parent */ + reg = __raw_readl(MXC_CCM_CBCMR) & MXC_CCM_CBCMR_DDR_CLK_SEL_MASK; + reg >>= MXC_CCM_CBCMR_DDR_CLK_SEL_OFFSET; + reg2 = __raw_readl(MXC_CCM_CBCDR) & MXC_CCM_CBCDR_DDR_HF_SEL; + reg2 >>= MXC_CCM_CBCDR_DDR_HF_SEL_OFFSET; + + if (reg2) { + ddr_clk.parent = &ddr_hf_clk; + } else { + if (reg == 0) { + ddr_clk.parent = &axi_a_clk; + } else if (reg == 1) { + ddr_clk.parent = &axi_b_clk; + } else if (reg == 2) { + ddr_clk.parent = &emi_slow_clk; + } else { + ddr_clk.parent = &ahb_clk; + } + } +} + +int __init mxc_clocks_init(unsigned long ckil, unsigned long osc, unsigned long ckih1, unsigned long ckih2) +{ + struct clk **clkp; + int i, reg; + + ckil_clk.rate = ckil; + osc_clk.rate = osc; + ckih_clk.rate = ckih1; + ckih2_clk.rate = ckih2; + + clk_tree_init(); + + for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++) + clk_register(*clkp); + + /* Turn off all possible clocks */ + if (mxc_jtag_enabled) { + __raw_writel(1 << MXC_CCM_CCGR0_CG0_OFFSET | + 1 << MXC_CCM_CCGR0_CG1_OFFSET | + 1 << MXC_CCM_CCGR0_CG2_OFFSET | + 1 << MXC_CCM_CCGR0_CG3_OFFSET | + 1 << MXC_CCM_CCGR0_CG4_OFFSET | + 1 << MXC_CCM_CCGR0_CG8_OFFSET | + 1 << MXC_CCM_CCGR0_CG9_OFFSET | + 1 << MXC_CCM_CCGR0_CG12_OFFSET | + 1 << MXC_CCM_CCGR0_CG13_OFFSET | + 1 << MXC_CCM_CCGR0_CG14_OFFSET, MXC_CCM_CCGR0); + } else { + __raw_writel(1 << MXC_CCM_CCGR0_CG0_OFFSET | + 1 << MXC_CCM_CCGR0_CG1_OFFSET | + 1 << MXC_CCM_CCGR0_CG2_OFFSET | + 1 << MXC_CCM_CCGR0_CG3_OFFSET | + 1 << MXC_CCM_CCGR0_CG8_OFFSET | + 1 << MXC_CCM_CCGR0_CG9_OFFSET | + 1 << MXC_CCM_CCGR0_CG12_OFFSET | + 1 << MXC_CCM_CCGR0_CG13_OFFSET | + 1 << MXC_CCM_CCGR0_CG14_OFFSET, MXC_CCM_CCGR0); + } + __raw_writel(0, MXC_CCM_CCGR1); + __raw_writel(0, MXC_CCM_CCGR2); + __raw_writel(0, MXC_CCM_CCGR3); + __raw_writel(3 << MXC_CCM_CCGR4_CG8_OFFSET, MXC_CCM_CCGR4); + __raw_writel(1 << MXC_CCM_CCGR5_CG2_OFFSET | + 1 << MXC_CCM_CCGR5_CG7_OFFSET | + 1 << MXC_CCM_CCGR5_CG8_OFFSET | + 1 << MXC_CCM_CCGR5_CG9_OFFSET | + 1 << MXC_CCM_CCGR5_CG10_OFFSET | + 3 << MXC_CCM_CCGR5_CG11_OFFSET, MXC_CCM_CCGR5); + __raw_writel(1 << MXC_CCM_CCGR6_CG4_OFFSET, MXC_CCM_CCGR6); + + /*Setup the LPM bypass bits */ + reg = __raw_readl(MXC_CCM_CLPCR); + reg |= MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS + | MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS + | MXC_CCM_CLPCR_BYPASS_RTIC_LPM_HS + | MXC_CCM_CLPCR_BYPASS_SCC_LPM_HS + | MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS; + __raw_writel(reg, MXC_CCM_CLPCR); + + /* This will propagate to all children and init all the clock rates */ + propagate_rate(&osc_clk); + propagate_rate(&ckih_clk); + propagate_rate(&ckih2_clk); + propagate_rate(&ckil_clk); + propagate_rate(&pll1_sw_clk); + propagate_rate(&pll2_sw_clk); + + clk_enable(&cpu_clk); + clk_enable(&main_bus_clk); + + reg = __raw_readl(MXC_CCM_CBCDR) & MXC_CCM_CBCDR_DDR_HF_SEL; + reg >>= MXC_CCM_CBCDR_DDR_HF_SEL_OFFSET; + + if (reg) + clk_set_parent(&ddr_clk, &ddr_hf_clk); + else + clk_set_parent(&ddr_clk, &axi_a_clk); + + if (cpu_is_mx51_rev(CHIP_REV_2_0) < 0) { + clk_set_parent(&vpu_clk[0], &ahb_clk); + clk_set_parent(&vpu_clk[1], &ahb_clk); + } else { + clk_set_parent(&vpu_clk[0], &axi_a_clk); + clk_set_parent(&vpu_clk[1], &axi_a_clk); + } + + /* Set the current working point. */ + cpu_wp_tbl = get_cpu_wp(&cpu_wp_nr); + for (i = 0; i < cpu_wp_nr; i++) { + if (clk_get_rate(&cpu_clk) == cpu_wp_tbl[i].cpu_rate) { + cpu_curr_wp = i; + break; + } + } + if (i > cpu_wp_nr) + BUG(); + + return 0; +} + +/*! + * Setup cpu clock based on working point. + * @param wp cpu freq working point + * @return 0 on success or error code on failure. + */ +static int cpu_clk_set_wp(int wp) +{ + struct cpu_wp *p; + u32 reg; + u32 stat; + + if (wp == cpu_curr_wp) + return 0; + + p = &cpu_wp_tbl[wp]; + + /* + * If DDR clock is sourced from PLL1, we cannot drop PLL1 freq. + * Use the ARM_PODF to change the freq of the core, leave the PLL1 + * freq unchanged. + */ + if (ddr_clk.parent == &ddr_hf_clk) { + reg = __raw_readl(MXC_CCM_CACRR); + reg &= ~MXC_CCM_CACRR_ARM_PODF_MASK; + reg |= cpu_wp_tbl[wp].cpu_podf << MXC_CCM_CACRR_ARM_PODF_OFFSET; + __raw_writel(reg, MXC_CCM_CACRR); + cpu_curr_wp = wp; + cpu_clk.rate = cpu_wp_tbl[wp].cpu_rate; + } else { + /* Change the ARM clock to requested frequency */ + /* First move the ARM clock to step clock which is running + * at 24MHz. + */ + + /* Change the source of pll1_sw_clk to be the step_clk */ + reg = __raw_readl(MXC_CCM_CCSR); + reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL; + __raw_writel(reg, MXC_CCM_CCSR); + + /* Stop the PLL */ + reg = __raw_readl(MXC_DPLL1_BASE + MXC_PLL_DP_CTL); + reg &= ~MXC_PLL_DP_CTL_UPEN; + __raw_writel(reg, MXC_DPLL1_BASE + MXC_PLL_DP_CTL); + + /* PDF and MFI */ + reg = p->pdf | p->mfi << MXC_PLL_DP_OP_MFI_OFFSET; + __raw_writel(reg, MXC_DPLL1_BASE + MXC_PLL_DP_OP); + + /* MFD */ + __raw_writel(p->mfd, MXC_DPLL1_BASE + MXC_PLL_DP_MFD); + + /* MFI */ + __raw_writel(p->mfn, MXC_DPLL1_BASE + MXC_PLL_DP_MFN); + + reg = __raw_readl(MXC_DPLL1_BASE + MXC_PLL_DP_CTL); + reg |= MXC_PLL_DP_CTL_UPEN; + /* Set the UPEN bits */ + __raw_writel(reg, MXC_DPLL1_BASE + MXC_PLL_DP_CTL); + /* Forcefully restart the PLL */ + reg |= MXC_PLL_DP_CTL_RST; + __raw_writel(reg, MXC_DPLL1_BASE + MXC_PLL_DP_CTL); + + /* Wait for the PLL to lock */ + do { + stat = __raw_readl(MXC_DPLL1_BASE + MXC_PLL_DP_CTL) & + MXC_PLL_DP_CTL_LRF; + } while (!stat); + + reg = __raw_readl(MXC_CCM_CCSR); + /* Move the PLL1 back to the pll1_main_clk */ + reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL; + __raw_writel(reg, MXC_CCM_CCSR); + + cpu_curr_wp = wp; + + pll1_sw_clk.rate = cpu_wp_tbl[wp].cpu_rate; + pll1_main_clk.rate = pll1_sw_clk.rate; + cpu_clk.rate = pll1_sw_clk.rate; + } + return 0; +} + --- linux-2.6.28.orig/arch/arm/mach-mx51/usb_h1.c +++ linux-2.6.28/arch/arm/mach-mx51/usb_h1.c @@ -0,0 +1,104 @@ +/* + * Copyright 2005-2009 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "usb.h" +#include "iomux.h" + + +/* + * USB Host1 HS port + */ +static int gpio_usbh1_active(void) +{ + /* Set USBH1_STP to GPIO and toggle it */ + mxc_request_iomux(MX51_PIN_USBH1_STP, IOMUX_CONFIG_GPIO | + IOMUX_CONFIG_SION); + mxc_set_gpio_direction(MX51_PIN_USBH1_STP, 0); + mxc_set_gpio_dataout(MX51_PIN_USBH1_STP, 1); + + /* Signal only used on MX51-3DS for reset to PHY.*/ + if (machine_is_mx51_3ds()) { + mxc_request_iomux(MX51_PIN_EIM_D17, IOMUX_CONFIG_ALT1); + mxc_iomux_set_pad(MX51_PIN_EIM_D17, PAD_CTL_DRV_HIGH | + PAD_CTL_HYS_NONE | PAD_CTL_PUE_KEEPER | + PAD_CTL_100K_PU | PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST); + mxc_set_gpio_direction(MX51_PIN_EIM_D17, 0); + mxc_set_gpio_dataout(MX51_PIN_EIM_D17, 1); + } + + msleep(100); + + return 0; +} + +void gpio_usbh1_setback_stp(void) +{ + /* setback USBH1_STP to be function */ + mxc_request_iomux(MX51_PIN_USBH1_STP, IOMUX_CONFIG_ALT0); + mxc_iomux_set_pad(MX51_PIN_USBH1_STP, PAD_CTL_SRE_FAST | + PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE | + PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE | + PAD_CTL_HYS_ENABLE | PAD_CTL_DDR_INPUT_CMOS | + PAD_CTL_DRV_VOT_LOW); +} +EXPORT_SYMBOL(gpio_usbh1_setback_stp); + +static void gpio_usbh1_inactive(void) +{ + mxc_request_gpio(MX51_PIN_USBH1_STP); + mxc_free_iomux(MX51_PIN_USBH1_STP, IOMUX_CONFIG_GPIO); +} + +static struct fsl_usb2_platform_data usbh1_config = { + .name = "Host 1", + .platform_init = fsl_usb_host_init, + .platform_uninit = fsl_usb_host_uninit, + .operating_mode = FSL_USB2_MPH_HOST, + .phy_mode = FSL_USB2_PHY_ULPI, + .power_budget = 500, /* 500 mA max power */ + .gpio_usb_active = gpio_usbh1_active, + .gpio_usb_inactive = gpio_usbh1_inactive, + .transceiver = "isp1504", +}; + +static struct resource usbh1_resources[] = { + [0] = { + .start = (u32) (USB_H1REGS_BASE), + .end = (u32) (USB_H1REGS_BASE + 0x1ff), + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = MXC_INT_USB_H1, + .flags = IORESOURCE_IRQ, + }, +}; + +static int __init usbh1_init(void) +{ + pr_debug("%s: \n", __func__); + + host_pdev_register(usbh1_resources, ARRAY_SIZE(usbh1_resources), + &usbh1_config); + return 0; +} + +module_init(usbh1_init); --- linux-2.6.28.orig/arch/arm/kernel/setup.c +++ linux-2.6.28/arch/arm/kernel/setup.c @@ -772,6 +772,8 @@ "java", "iwmmxt", "crunch", + "thumbee", + "neon", NULL }; --- linux-2.6.28.orig/arch/arm/kernel/calls.S +++ linux-2.6.28/arch/arm/kernel/calls.S @@ -98,7 +98,7 @@ CALL(sys_uselib) CALL(sys_swapon) CALL(sys_reboot) - CALL(OBSOLETE(old_readdir)) /* used by libc4 */ + CALL(OBSOLETE(sys_old_readdir)) /* used by libc4 */ /* 90 */ CALL(OBSOLETE(old_mmap)) /* used by libc4 */ CALL(sys_munmap) CALL(sys_truncate) --- linux-2.6.28.orig/arch/sparc/include/asm/compat.h +++ linux-2.6.28/arch/sparc/include/asm/compat.h @@ -240,4 +240,9 @@ unsigned int __unused2; }; +static inline int is_compat_task(void) +{ + return test_thread_flag(TIF_32BIT); +} + #endif /* _ASM_SPARC64_COMPAT_H */ --- linux-2.6.28.orig/arch/sparc/include/asm/seccomp.h +++ linux-2.6.28/arch/sparc/include/asm/seccomp.h @@ -1,11 +1,5 @@ #ifndef _ASM_SECCOMP_H -#include /* already defines TIF_32BIT */ - -#ifndef TIF_32BIT -#error "unexpected TIF_32BIT on sparc64" -#endif - #include #define __NR_seccomp_read __NR_read --- linux-2.6.28.orig/arch/sparc/kernel/entry.S +++ linux-2.6.28/arch/sparc/kernel/entry.S @@ -1088,8 +1088,8 @@ ld [%sp + STACKFRAME_SZ + PT_I0], %o0 .align 4 - .globl sys_pipe -sys_pipe: + .globl sys_sparc_pipe +sys_sparc_pipe: mov %o7, %l5 add %sp, STACKFRAME_SZ, %o0 ! pt_regs *regs arg call sparc_pipe --- linux-2.6.28.orig/arch/sparc/kernel/systbls.S +++ linux-2.6.28/arch/sparc/kernel/systbls.S @@ -24,7 +24,7 @@ /*25*/ .long sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_pause /*30*/ .long sys_utime, sys_lchown, sys_fchown, sys_access, sys_nice /*35*/ .long sys_chown, sys_sync, sys_kill, sys_newstat, sys_sendfile -/*40*/ .long sys_newlstat, sys_dup, sys_pipe, sys_times, sys_getuid +/*40*/ .long sys_newlstat, sys_dup, sys_sparc_pipe, sys_times, sys_getuid /*45*/ .long sys_umount, sys_setgid16, sys_getgid16, sys_signal, sys_geteuid16 /*50*/ .long sys_getegid16, sys_acct, sys_nis_syscall, sys_getgid, sys_ioctl /*55*/ .long sys_reboot, sys_mmap2, sys_symlink, sys_readlink, sys_execve @@ -56,7 +56,7 @@ /*185*/ .long sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_newuname /*190*/ .long sys_init_module, sys_personality, sparc_remap_file_pages, sys_epoll_create, sys_epoll_ctl /*195*/ .long sys_epoll_wait, sys_ioprio_set, sys_getppid, sparc_sigaction, sys_sgetmask -/*200*/ .long sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, old_readdir +/*200*/ .long sys_ssetmask, sys_sigsuspend, sys_newlstat, sys_uselib, sys_old_readdir /*205*/ .long sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_fadvise64 /*210*/ .long sys_fadvise64_64, sys_tgkill, sys_waitpid, sys_swapoff, sys_sysinfo /*215*/ .long sys_ipc, sys_sigreturn, sys_clone, sys_ioprio_get, sys_adjtimex --- linux-2.6.28.orig/arch/mn10300/kernel/entry.S +++ linux-2.6.28/arch/mn10300/kernel/entry.S @@ -478,7 +478,7 @@ .long sys_uselib .long sys_swapon .long sys_reboot - .long old_readdir + .long sys_old_readdir .long old_mmap /* 90 */ .long sys_munmap .long sys_truncate --- linux-2.6.28.orig/arch/s390/Kconfig +++ linux-2.6.28/arch/s390/Kconfig @@ -70,6 +70,7 @@ config S390 def_bool y + select HAVE_SYSCALL_WRAPPERS select HAVE_OPROFILE select HAVE_KPROBES select HAVE_KRETPROBES --- linux-2.6.28.orig/arch/s390/lib/div64.c +++ linux-2.6.28/arch/s390/lib/div64.c @@ -61,7 +61,7 @@ " clr %0,%3\n" " jl 0f\n" " slr %0,%3\n" - " alr %1,%2\n" + " ahi %1,1\n" "0:\n" : "+d" (reg2), "+d" (reg3), "=d" (tmp) : "d" (base), "2" (1UL) : "cc" ); --- linux-2.6.28.orig/arch/s390/kernel/compat_wrapper.S +++ linux-2.6.28/arch/s390/kernel/compat_wrapper.S @@ -547,7 +547,7 @@ .globl sys32_newuname_wrapper sys32_newuname_wrapper: llgtr %r2,%r2 # struct new_utsname * - jg s390x_newuname # branch to system call + jg sys_s390_newuname # branch to system call .globl compat_sys_adjtimex_wrapper compat_sys_adjtimex_wrapper: @@ -615,7 +615,7 @@ .globl sys32_personality_wrapper sys32_personality_wrapper: llgfr %r2,%r2 # unsigned long - jg s390x_personality # branch to system call + jg sys_s390_personality # branch to system call .globl sys32_setfsuid16_wrapper sys32_setfsuid16_wrapper: --- linux-2.6.28.orig/arch/s390/kernel/entry.h +++ linux-2.6.28/arch/s390/kernel/entry.h @@ -30,23 +30,23 @@ struct old_sigaction; struct sel_arg_struct; -long sys_pipe(unsigned long __user *fildes); long sys_mmap2(struct mmap_arg_struct __user *arg); -long old_mmap(struct mmap_arg_struct __user *arg); +long sys_s390_old_mmap(struct mmap_arg_struct __user *arg); long sys_ipc(uint call, int first, unsigned long second, unsigned long third, void __user *ptr); -long s390x_newuname(struct new_utsname __user *name); -long s390x_personality(unsigned long personality); -long s390_fadvise64(int fd, u32 offset_high, u32 offset_low, +long sys_s390_newuname(struct new_utsname __user *name); +long sys_s390_personality(unsigned long personality); +long sys_s390_fadvise64(int fd, u32 offset_high, u32 offset_low, size_t len, int advice); -long s390_fadvise64_64(struct fadvise64_64_args __user *args); -long s390_fallocate(int fd, int mode, loff_t offset, u32 len_high, u32 len_low); +long sys_s390_fadvise64_64(struct fadvise64_64_args __user *args); +long sys_s390_fallocate(int fd, int mode, loff_t offset, u32 len_high, + u32 len_low); long sys_fork(void); long sys_clone(void); long sys_vfork(void); void execve_tail(void); long sys_execve(void); -int sys_sigsuspend(int history0, int history1, old_sigset_t mask); +long sys_sigsuspend(int history0, int history1, old_sigset_t mask); long sys_sigaction(int sig, const struct old_sigaction __user *act, struct old_sigaction __user *oact); long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss); --- linux-2.6.28.orig/arch/s390/kernel/process.c +++ linux-2.6.28/arch/s390/kernel/process.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -260,13 +261,13 @@ return 0; } -asmlinkage long sys_fork(void) +SYSCALL_DEFINE0(fork) { struct pt_regs *regs = task_pt_regs(current); return do_fork(SIGCHLD, regs->gprs[15], regs, 0, NULL, NULL); } -asmlinkage long sys_clone(void) +SYSCALL_DEFINE0(clone) { struct pt_regs *regs = task_pt_regs(current); unsigned long clone_flags; @@ -293,7 +294,7 @@ * do not have enough call-clobbered registers to hold all * the information you need. */ -asmlinkage long sys_vfork(void) +SYSCALL_DEFINE0(vfork) { struct pt_regs *regs = task_pt_regs(current); return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, @@ -313,7 +314,7 @@ /* * sys_execve() executes a new program. */ -asmlinkage long sys_execve(void) +SYSCALL_DEFINE0(execve) { struct pt_regs *regs = task_pt_regs(current); char *filename; --- linux-2.6.28.orig/arch/s390/kernel/syscalls.S +++ linux-2.6.28/arch/s390/kernel/syscalls.S @@ -98,7 +98,7 @@ SYSCALL(sys_swapon,sys_swapon,sys32_swapon_wrapper) SYSCALL(sys_reboot,sys_reboot,sys32_reboot_wrapper) SYSCALL(sys_ni_syscall,sys_ni_syscall,old32_readdir_wrapper) /* old readdir syscall */ -SYSCALL(old_mmap,old_mmap,old32_mmap_wrapper) /* 90 */ +SYSCALL(sys_s390_old_mmap,sys_s390_old_mmap,old32_mmap_wrapper) /* 90 */ SYSCALL(sys_munmap,sys_munmap,sys32_munmap_wrapper) SYSCALL(sys_truncate,sys_truncate,sys32_truncate_wrapper) SYSCALL(sys_ftruncate,sys_ftruncate,sys32_ftruncate_wrapper) @@ -130,7 +130,7 @@ SYSCALL(sys_sigreturn,sys_sigreturn,sys32_sigreturn) SYSCALL(sys_clone,sys_clone,sys32_clone) /* 120 */ SYSCALL(sys_setdomainname,sys_setdomainname,sys32_setdomainname_wrapper) -SYSCALL(sys_newuname,s390x_newuname,sys32_newuname_wrapper) +SYSCALL(sys_newuname,sys_s390_newuname,sys32_newuname_wrapper) NI_SYSCALL /* modify_ldt for i386 */ SYSCALL(sys_adjtimex,sys_adjtimex,compat_sys_adjtimex_wrapper) SYSCALL(sys_mprotect,sys_mprotect,sys32_mprotect_wrapper) /* 125 */ @@ -144,7 +144,7 @@ SYSCALL(sys_fchdir,sys_fchdir,sys32_fchdir_wrapper) SYSCALL(sys_bdflush,sys_bdflush,sys32_bdflush_wrapper) SYSCALL(sys_sysfs,sys_sysfs,sys32_sysfs_wrapper) /* 135 */ -SYSCALL(sys_personality,s390x_personality,sys32_personality_wrapper) +SYSCALL(sys_personality,sys_s390_personality,sys32_personality_wrapper) NI_SYSCALL /* for afs_syscall */ SYSCALL(sys_setfsuid16,sys_ni_syscall,sys32_setfsuid16_wrapper) /* old setfsuid16 syscall */ SYSCALL(sys_setfsgid16,sys_ni_syscall,sys32_setfsgid16_wrapper) /* old setfsgid16 syscall */ @@ -261,7 +261,7 @@ SYSCALL(sys_epoll_ctl,sys_epoll_ctl,sys_epoll_ctl_wrapper) /* 250 */ SYSCALL(sys_epoll_wait,sys_epoll_wait,sys_epoll_wait_wrapper) SYSCALL(sys_set_tid_address,sys_set_tid_address,sys32_set_tid_address_wrapper) -SYSCALL(s390_fadvise64,sys_fadvise64_64,sys32_fadvise64_wrapper) +SYSCALL(sys_s390_fadvise64,sys_fadvise64_64,sys32_fadvise64_wrapper) SYSCALL(sys_timer_create,sys_timer_create,sys32_timer_create_wrapper) SYSCALL(sys_timer_settime,sys_timer_settime,sys32_timer_settime_wrapper) /* 255 */ SYSCALL(sys_timer_gettime,sys_timer_gettime,sys32_timer_gettime_wrapper) @@ -272,7 +272,7 @@ SYSCALL(sys_clock_getres,sys_clock_getres,sys32_clock_getres_wrapper) SYSCALL(sys_clock_nanosleep,sys_clock_nanosleep,sys32_clock_nanosleep_wrapper) NI_SYSCALL /* reserved for vserver */ -SYSCALL(s390_fadvise64_64,sys_ni_syscall,sys32_fadvise64_64_wrapper) +SYSCALL(sys_s390_fadvise64_64,sys_ni_syscall,sys32_fadvise64_64_wrapper) SYSCALL(sys_statfs64,sys_statfs64,compat_sys_statfs64_wrapper) SYSCALL(sys_fstatfs64,sys_fstatfs64,compat_sys_fstatfs64_wrapper) SYSCALL(sys_remap_file_pages,sys_remap_file_pages,sys32_remap_file_pages_wrapper) @@ -322,7 +322,7 @@ SYSCALL(sys_getcpu,sys_getcpu,sys_getcpu_wrapper) SYSCALL(sys_epoll_pwait,sys_epoll_pwait,compat_sys_epoll_pwait_wrapper) SYSCALL(sys_utimes,sys_utimes,compat_sys_utimes_wrapper) -SYSCALL(s390_fallocate,sys_fallocate,sys_fallocate_wrapper) +SYSCALL(sys_s390_fallocate,sys_fallocate,sys_fallocate_wrapper) SYSCALL(sys_utimensat,sys_utimensat,compat_sys_utimensat_wrapper) /* 315 */ SYSCALL(sys_signalfd,sys_signalfd,compat_sys_signalfd_wrapper) NI_SYSCALL /* 317 old sys_timer_fd */ --- linux-2.6.28.orig/arch/s390/kernel/signal.c +++ linux-2.6.28/arch/s390/kernel/signal.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -53,8 +54,7 @@ /* * Atomically swap in the new signal mask, and wait for a signal. */ -asmlinkage int -sys_sigsuspend(int history0, int history1, old_sigset_t mask) +SYSCALL_DEFINE3(sigsuspend, int, history0, int, history1, old_sigset_t, mask) { mask &= _BLOCKABLE; spin_lock_irq(¤t->sighand->siglock); @@ -70,9 +70,8 @@ return -ERESTARTNOHAND; } -asmlinkage long -sys_sigaction(int sig, const struct old_sigaction __user *act, - struct old_sigaction __user *oact) +SYSCALL_DEFINE3(sigaction, int, sig, const struct old_sigaction __user *, act, + struct old_sigaction __user *, oact) { struct k_sigaction new_ka, old_ka; int ret; @@ -102,15 +101,13 @@ return ret; } -asmlinkage long -sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) +SYSCALL_DEFINE2(sigaltstack, const stack_t __user *, uss, + stack_t __user *, uoss) { struct pt_regs *regs = task_pt_regs(current); return do_sigaltstack(uss, uoss, regs->gprs[15]); } - - /* Returns non-zero on fault. */ static int save_sigregs(struct pt_regs *regs, _sigregs __user *sregs) { @@ -164,7 +161,7 @@ return 0; } -asmlinkage long sys_sigreturn(void) +SYSCALL_DEFINE0(sigreturn) { struct pt_regs *regs = task_pt_regs(current); sigframe __user *frame = (sigframe __user *)regs->gprs[15]; @@ -191,7 +188,7 @@ return 0; } -asmlinkage long sys_rt_sigreturn(void) +SYSCALL_DEFINE0(rt_sigreturn) { struct pt_regs *regs = task_pt_regs(current); rt_sigframe __user *frame = (rt_sigframe __user *)regs->gprs[15]; --- linux-2.6.28.orig/arch/s390/kernel/sys_s390.c +++ linux-2.6.28/arch/s390/kernel/sys_s390.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "entry.h" @@ -74,7 +75,7 @@ unsigned long offset; }; -asmlinkage long sys_mmap2(struct mmap_arg_struct __user *arg) +SYSCALL_DEFINE1(mmap2, struct mmap_arg_struct __user *, arg) { struct mmap_arg_struct a; int error = -EFAULT; @@ -86,7 +87,7 @@ return error; } -asmlinkage long old_mmap(struct mmap_arg_struct __user *arg) +SYSCALL_DEFINE1(s390_old_mmap, struct mmap_arg_struct __user *, arg) { struct mmap_arg_struct a; long error = -EFAULT; @@ -127,8 +128,8 @@ * * This is really horribly ugly. */ -asmlinkage long sys_ipc(uint call, int first, unsigned long second, - unsigned long third, void __user *ptr) +SYSCALL_DEFINE5(ipc, uint, call, int, first, unsigned long, second, + unsigned long, third, void __user *, ptr) { struct ipc_kludge tmp; int ret; @@ -194,7 +195,7 @@ } #ifdef CONFIG_64BIT -asmlinkage long s390x_newuname(struct new_utsname __user *name) +SYSCALL_DEFINE1(s390_newuname, struct new_utsname __user *, name) { int ret = sys_newuname(name); @@ -205,7 +206,7 @@ return ret; } -asmlinkage long s390x_personality(unsigned long personality) +SYSCALL_DEFINE1(s390_personality, unsigned long, personality) { int ret; @@ -224,15 +225,13 @@ */ #ifndef CONFIG_64BIT -asmlinkage long -s390_fadvise64(int fd, u32 offset_high, u32 offset_low, size_t len, int advice) +SYSCALL_DEFINE5(s390_fadvise64, int, fd, u32, offset_high, u32, offset_low, + size_t, len, int, advice) { return sys_fadvise64(fd, (u64) offset_high << 32 | offset_low, len, advice); } -#endif - struct fadvise64_64_args { int fd; long long offset; @@ -240,8 +239,7 @@ int advice; }; -asmlinkage long -s390_fadvise64_64(struct fadvise64_64_args __user *args) +SYSCALL_DEFINE1(s390_fadvise64_64, struct fadvise64_64_args __user *, args) { struct fadvise64_64_args a; @@ -250,7 +248,6 @@ return sys_fadvise64_64(a.fd, a.offset, a.len, a.advice); } -#ifndef CONFIG_64BIT /* * This is a wrapper to call sys_fallocate(). For 31 bit s390 the last * 64 bit argument "len" is split into the upper and lower 32 bits. The @@ -263,9 +260,19 @@ * to * %r2: fd, %r3: mode, %r4/%r5: offset, 96(%r15)-103(%r15): len */ -asmlinkage long s390_fallocate(int fd, int mode, loff_t offset, +SYSCALL_DEFINE(s390_fallocate)(int fd, int mode, loff_t offset, u32 len_high, u32 len_low) { return sys_fallocate(fd, mode, offset, ((u64)len_high << 32) | len_low); } +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_s390_fallocate(long fd, long mode, loff_t offset, + long len_high, long len_low) +{ + return SYSC_s390_fallocate((int) fd, (int) mode, offset, + (u32) len_high, (u32) len_low); +} +SYSCALL_ALIAS(sys_s390_fallocate, SyS_s390_fallocate); +#endif + #endif --- linux-2.6.28.orig/arch/parisc/include/asm/dma-mapping.h +++ linux-2.6.28/arch/parisc/include/asm/dma-mapping.h @@ -5,7 +5,7 @@ #include #include -/* See Documentation/DMA-mapping.txt */ +/* See Documentation/PCI/PCI-DMA-mapping.txt */ struct hppa_dma_ops { int (*dma_supported)(struct device *dev, u64 mask); void *(*alloc_consistent)(struct device *dev, size_t size, dma_addr_t *iova, gfp_t flag); --- linux-2.6.28.orig/arch/parisc/kernel/pci-dma.c +++ linux-2.6.28/arch/parisc/kernel/pci-dma.c @@ -2,7 +2,7 @@ ** PARISC 1.1 Dynamic DMA mapping support. ** This implementation is for PA-RISC platforms that do not support ** I/O TLBs (aka DMA address translation hardware). -** See Documentation/DMA-mapping.txt for interface definitions. +** See Documentation/PCI/PCI-DMA-mapping.txt for interface definitions. ** ** (c) Copyright 1999,2000 Hewlett-Packard Company ** (c) Copyright 2000 Grant Grundler --- linux-2.6.28.orig/arch/ia64/Kconfig +++ linux-2.6.28/arch/ia64/Kconfig @@ -17,6 +17,7 @@ select ACPI if (!IA64_HP_SIM) select PM if (!IA64_HP_SIM) select ARCH_SUPPORTS_MSI + select HAVE_UNSTABLE_SCHED_CLOCK select HAVE_IDE select HAVE_OPROFILE select HAVE_KPROBES @@ -478,8 +479,7 @@ default y if VIRTUAL_MEM_MAP config HAVE_ARCH_EARLY_PFN_TO_NID - def_bool y - depends on NEED_MULTIPLE_NODES + def_bool NUMA && SPARSEMEM config HAVE_ARCH_NODEDATA_EXTENSION def_bool y --- linux-2.6.28.orig/arch/ia64/hp/common/sba_iommu.c +++ linux-2.6.28/arch/ia64/hp/common/sba_iommu.c @@ -906,7 +906,7 @@ * @dir: R/W or both. * @attrs: optional dma attributes * - * See Documentation/DMA-mapping.txt + * See Documentation/PCI/PCI-DMA-mapping.txt */ dma_addr_t sba_map_single_attrs(struct device *dev, void *addr, size_t size, int dir, @@ -1024,7 +1024,7 @@ * @dir: R/W or both. * @attrs: optional dma attributes * - * See Documentation/DMA-mapping.txt + * See Documentation/PCI/PCI-DMA-mapping.txt */ void sba_unmap_single_attrs(struct device *dev, dma_addr_t iova, size_t size, int dir, struct dma_attrs *attrs) @@ -1102,7 +1102,7 @@ * @size: number of bytes mapped in driver buffer. * @dma_handle: IOVA of new buffer. * - * See Documentation/DMA-mapping.txt + * See Documentation/PCI/PCI-DMA-mapping.txt */ void * sba_alloc_coherent (struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flags) @@ -1165,7 +1165,7 @@ * @vaddr: virtual address IOVA of "consistent" buffer. * @dma_handler: IO virtual address of "consistent" buffer. * - * See Documentation/DMA-mapping.txt + * See Documentation/PCI/PCI-DMA-mapping.txt */ void sba_free_coherent (struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle) { @@ -1420,7 +1420,7 @@ * @dir: R/W or both. * @attrs: optional dma attributes * - * See Documentation/DMA-mapping.txt + * See Documentation/PCI/PCI-DMA-mapping.txt */ int sba_map_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents, int dir, struct dma_attrs *attrs) @@ -1512,7 +1512,7 @@ * @dir: R/W or both. * @attrs: optional dma attributes * - * See Documentation/DMA-mapping.txt + * See Documentation/PCI/PCI-DMA-mapping.txt */ void sba_unmap_sg_attrs(struct device *dev, struct scatterlist *sglist, int nents, int dir, struct dma_attrs *attrs) --- linux-2.6.28.orig/arch/ia64/mm/numa.c +++ linux-2.6.28/arch/ia64/mm/numa.c @@ -58,7 +58,7 @@ * SPARSEMEM to allocate the SPARSEMEM sectionmap on the NUMA node where * the section resides. */ -int early_pfn_to_nid(unsigned long pfn) +int __meminit __early_pfn_to_nid(unsigned long pfn) { int i, section = pfn >> PFN_SECTION_SHIFT, ssec, esec; @@ -70,7 +70,7 @@ return node_memblk[i].nid; } - return 0; + return -1; } #ifdef CONFIG_MEMORY_HOTPLUG --- linux-2.6.28.orig/arch/ia64/include/asm/mmzone.h +++ linux-2.6.28/arch/ia64/include/asm/mmzone.h @@ -31,10 +31,6 @@ #endif } -#ifdef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID -extern int early_pfn_to_nid(unsigned long pfn); -#endif - #ifdef CONFIG_IA64_DIG /* DIG systems are small */ # define MAX_PHYSNODE_ID 8 # define NR_NODE_MEMBLKS (MAX_NUMNODES * 8) --- linux-2.6.28.orig/arch/ia64/include/asm/unistd.h +++ linux-2.6.28/arch/ia64/include/asm/unistd.h @@ -364,7 +364,7 @@ struct sigaction; long sys_execve(char __user *filename, char __user * __user *argv, char __user * __user *envp, struct pt_regs *regs); -asmlinkage long sys_pipe(void); +asmlinkage long sys_ia64_pipe(void); asmlinkage long sys_rt_sigaction(int sig, const struct sigaction __user *act, struct sigaction __user *oact, --- linux-2.6.28.orig/arch/ia64/sn/kernel/io_acpi_init.c +++ linux-2.6.28/arch/ia64/sn/kernel/io_acpi_init.c @@ -434,7 +434,7 @@ size = pci_resource_len(dev, PCI_ROM_RESOURCE); addr = ioremap(pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE], size); - image_size = pci_get_rom_size(addr, size); + image_size = pci_get_rom_size(dev, addr, size); dev->resource[PCI_ROM_RESOURCE].start = (unsigned long) addr; dev->resource[PCI_ROM_RESOURCE].end = (unsigned long) addr + image_size - 1; --- linux-2.6.28.orig/arch/ia64/sn/kernel/io_init.c +++ linux-2.6.28/arch/ia64/sn/kernel/io_init.c @@ -269,7 +269,7 @@ rom = ioremap(pci_resource_start(dev, PCI_ROM_RESOURCE), size + 1); - image_size = pci_get_rom_size(rom, size + 1); + image_size = pci_get_rom_size(dev, rom, size + 1); dev->resource[PCI_ROM_RESOURCE].end = dev->resource[PCI_ROM_RESOURCE].start + image_size - 1; --- linux-2.6.28.orig/arch/ia64/ia32/ia32_entry.S +++ linux-2.6.28/arch/ia64/ia32/ia32_entry.S @@ -220,7 +220,7 @@ data8 sys_mkdir data8 sys_rmdir /* 40 */ data8 sys_dup - data8 sys_pipe + data8 sys_ia64_pipe data8 compat_sys_times data8 sys_ni_syscall /* old prof syscall holder */ data8 sys32_brk /* 45 */ --- linux-2.6.28.orig/arch/ia64/kernel/entry.S +++ linux-2.6.28/arch/ia64/kernel/entry.S @@ -1442,7 +1442,7 @@ data8 sys_mkdir // 1055 data8 sys_rmdir data8 sys_dup - data8 sys_pipe + data8 sys_ia64_pipe data8 sys_times data8 ia64_brk // 1060 data8 sys_setgid --- linux-2.6.28.orig/arch/ia64/kernel/sys_ia64.c +++ linux-2.6.28/arch/ia64/kernel/sys_ia64.c @@ -154,7 +154,7 @@ * and r9) as this is faster than doing a copy_to_user(). */ asmlinkage long -sys_pipe (void) +sys_ia64_pipe (void) { struct pt_regs *regs = task_pt_regs(current); int fd[2]; --- linux-2.6.28.orig/arch/sparc64/Kconfig +++ linux-2.6.28/arch/sparc64/Kconfig @@ -14,6 +14,7 @@ select HAVE_FUNCTION_TRACER select HAVE_IDE select HAVE_LMB + select HAVE_SYSCALL_WRAPPERS select HAVE_ARCH_KGDB select USE_GENERIC_SMP_HELPERS if SMP select HAVE_ARCH_TRACEHOOK --- linux-2.6.28.orig/arch/sparc64/kernel/traps.c +++ linux-2.6.28/arch/sparc64/kernel/traps.c @@ -1,6 +1,6 @@ /* arch/sparc64/kernel/traps.c * - * Copyright (C) 1995,1997,2008 David S. Miller (davem@davemloft.net) + * Copyright (C) 1995,1997,2008,2009 David S. Miller (davem@davemloft.net) * Copyright (C) 1997,1999,2000 Jakub Jelinek (jakub@redhat.com) */ @@ -313,6 +313,21 @@ return; if (regs->tstate & TSTATE_PRIV) { + /* Test if this comes from uaccess places. */ + const struct exception_table_entry *entry; + + entry = search_exception_tables(regs->tpc); + if (entry) { + /* Ouch, somebody is trying VM hole tricks on us... */ +#ifdef DEBUG_EXCEPTIONS + printk("Exception: PC<%016lx> faddr\n", regs->tpc); + printk("EX_TABLE: insn<%016lx> fixup<%016lx>\n", + regs->tpc, entry->fixup); +#endif + regs->tpc = entry->fixup; + regs->tnpc = regs->tpc + 4; + return; + } printk("sun4v_data_access_exception: ADDR[%016lx] " "CTX[%04x] TYPE[%04x], going.\n", addr, ctx, type); --- linux-2.6.28.orig/arch/sparc64/kernel/systbls.h +++ linux-2.6.28/arch/sparc64/kernel/systbls.h @@ -16,9 +16,6 @@ void __user *ptr, long fifth); extern asmlinkage long sparc64_newuname(struct new_utsname __user *name); extern asmlinkage long sparc64_personality(unsigned long personality); -extern asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, - unsigned long prot, unsigned long flags, - unsigned long fd, unsigned long off); extern asmlinkage long sys64_munmap(unsigned long addr, size_t len); extern asmlinkage unsigned long sys64_mremap(unsigned long addr, unsigned long old_len, --- linux-2.6.28.orig/arch/sparc64/kernel/systbls.S +++ linux-2.6.28/arch/sparc64/kernel/systbls.S @@ -21,12 +21,12 @@ /*0*/ .word sys_restart_syscall, sys32_exit, sys_fork, sys_read, sys_write /*5*/ .word sys32_open, sys_close, sys32_wait4, sys32_creat, sys_link /*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys32_mknod -/*15*/ .word sys_chmod, sys_lchown16, sparc_brk, sys32_perfctr, sys32_lseek +/*15*/ .word sys_chmod, sys_lchown16, sys_sparc_brk, sys32_perfctr, sys32_lseek /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16 /*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys_pause /*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice .word sys_chown, sys_sync, sys32_kill, compat_sys_newstat, sys32_sendfile -/*40*/ .word compat_sys_newlstat, sys_dup, sys_pipe, compat_sys_times, sys_getuid +/*40*/ .word compat_sys_newlstat, sys_dup, sys_sparc_pipe, compat_sys_times, sys_getuid .word sys32_umount, sys_setgid16, sys_getgid16, sys32_signal, sys_geteuid16 /*50*/ .word sys_getegid16, sys_acct, sys_nis_syscall, sys_getgid, compat_sys_ioctl .word sys32_reboot, sys32_mmap2, sys_symlink, sys32_readlink, sys32_execve @@ -55,8 +55,8 @@ /*170*/ .word sys32_lsetxattr, sys32_fsetxattr, sys_getxattr, sys_lgetxattr, compat_sys_getdents .word sys_setsid, sys_fchdir, sys32_fgetxattr, sys_listxattr, sys_llistxattr /*180*/ .word sys32_flistxattr, sys_removexattr, sys_lremovexattr, compat_sys_sigpending, sys_ni_syscall - .word sys32_setpgid, sys32_fremovexattr, sys32_tkill, sys32_exit_group, sparc64_newuname -/*190*/ .word sys32_init_module, sparc64_personality, sys_remap_file_pages, sys32_epoll_create, sys32_epoll_ctl + .word sys32_setpgid, sys32_fremovexattr, sys32_tkill, sys32_exit_group, sys_sparc64_newuname +/*190*/ .word sys32_init_module, sys_sparc64_personality, sys_remap_file_pages, sys32_epoll_create, sys32_epoll_ctl .word sys32_epoll_wait, sys32_ioprio_set, sys_getppid, sys32_sigaction, sys_sgetmask /*200*/ .word sys32_ssetmask, sys_sigsuspend, compat_sys_newlstat, sys_uselib, compat_sys_old_readdir .word sys32_readahead, sys32_socketcall, sys32_syslog, sys32_lookup_dcookie, sys32_fadvise64 @@ -95,18 +95,18 @@ /*0*/ .word sys_restart_syscall, sparc_exit, sys_fork, sys_read, sys_write /*5*/ .word sys_open, sys_close, sys_wait4, sys_creat, sys_link /*10*/ .word sys_unlink, sys_nis_syscall, sys_chdir, sys_chown, sys_mknod -/*15*/ .word sys_chmod, sys_lchown, sparc_brk, sys_perfctr, sys_lseek +/*15*/ .word sys_chmod, sys_lchown, sys_sparc_brk, sys_perfctr, sys_lseek /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid, sys_getuid /*25*/ .word sys_vmsplice, sys_ptrace, sys_alarm, sys_sigaltstack, sys_nis_syscall /*30*/ .word sys_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice .word sys_nis_syscall, sys_sync, sys_kill, sys_newstat, sys_sendfile64 -/*40*/ .word sys_newlstat, sys_dup, sys_pipe, sys_times, sys_nis_syscall +/*40*/ .word sys_newlstat, sys_dup, sys_sparc_pipe, sys_times, sys_nis_syscall .word sys_umount, sys_setgid, sys_getgid, sys_signal, sys_geteuid /*50*/ .word sys_getegid, sys_acct, sys_memory_ordering, sys_nis_syscall, sys_ioctl .word sys_reboot, sys_nis_syscall, sys_symlink, sys_readlink, sys_execve /*60*/ .word sys_umask, sys_chroot, sys_newfstat, sys_fstat64, sys_getpagesize .word sys_msync, sys_vfork, sys_pread64, sys_pwrite64, sys_nis_syscall -/*70*/ .word sys_nis_syscall, sys_mmap, sys_nis_syscall, sys64_munmap, sys_mprotect +/*70*/ .word sys_nis_syscall, sys_mmap, sys_nis_syscall, sys_64_munmap, sys_mprotect .word sys_madvise, sys_vhangup, sys_nis_syscall, sys_mincore, sys_getgroups /*80*/ .word sys_setgroups, sys_getpgrp, sys_nis_syscall, sys_setitimer, sys_nis_syscall .word sys_swapon, sys_getitimer, sys_nis_syscall, sys_sethostname, sys_nis_syscall @@ -129,8 +129,8 @@ /*170*/ .word sys_lsetxattr, sys_fsetxattr, sys_getxattr, sys_lgetxattr, sys_getdents .word sys_setsid, sys_fchdir, sys_fgetxattr, sys_listxattr, sys_llistxattr /*180*/ .word sys_flistxattr, sys_removexattr, sys_lremovexattr, sys_nis_syscall, sys_ni_syscall - .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sparc64_newuname -/*190*/ .word sys_init_module, sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl + .word sys_setpgid, sys_fremovexattr, sys_tkill, sys_exit_group, sys_sparc64_newuname +/*190*/ .word sys_init_module, sys_sparc64_personality, sys_remap_file_pages, sys_epoll_create, sys_epoll_ctl .word sys_epoll_wait, sys_ioprio_set, sys_getppid, sys_nis_syscall, sys_sgetmask /*200*/ .word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall .word sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_fadvise64 @@ -142,7 +142,7 @@ .word sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall /*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler .word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep -/*250*/ .word sys64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl +/*250*/ .word sys_64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl .word sys_sync_file_range, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep /*260*/ .word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy --- linux-2.6.28.orig/arch/sparc64/kernel/sys_sparc.c +++ linux-2.6.28/arch/sparc64/kernel/sys_sparc.c @@ -397,7 +397,7 @@ } } -asmlinkage unsigned long sparc_brk(unsigned long brk) +SYSCALL_DEFINE1(sparc_brk, unsigned long, brk) { /* People could try to be nasty and use ta 0x6d in 32bit programs */ if (test_thread_flag(TIF_32BIT) && brk >= STACK_TOP32) @@ -413,7 +413,7 @@ * sys_pipe() is the normal C calling standard for creating * a pipe. It's not the way unix traditionally does this, though. */ -asmlinkage long sparc_pipe(struct pt_regs *regs) +SYSCALL_DEFINE1(sparc_pipe_real, struct pt_regs *, regs) { int fd[2]; int error; @@ -433,8 +433,8 @@ * This is really horribly ugly. */ -asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second, - unsigned long third, void __user *ptr, long fifth) +SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, + unsigned long, third, void __user *, ptr, long, fifth) { long err; @@ -517,7 +517,7 @@ return err; } -asmlinkage long sparc64_newuname(struct new_utsname __user *name) +SYSCALL_DEFINE1(sparc64_newuname, struct new_utsname __user *, name) { int ret = sys_newuname(name); @@ -528,7 +528,7 @@ return ret; } -asmlinkage long sparc64_personality(unsigned long personality) +SYSCALL_DEFINE1(sparc64_personality, unsigned long, personality) { int ret; @@ -562,9 +562,9 @@ } /* Linux version of mmap */ -asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, - unsigned long prot, unsigned long flags, unsigned long fd, - unsigned long off) +SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, + unsigned long, prot, unsigned long, flags, unsigned long, fd, + unsigned long, off) { struct file * file = NULL; unsigned long retval = -EBADF; @@ -587,7 +587,7 @@ return retval; } -asmlinkage long sys64_munmap(unsigned long addr, size_t len) +SYSCALL_DEFINE2(64_munmap, unsigned long, addr, size_t, len) { long ret; @@ -604,9 +604,9 @@ unsigned long old_len, unsigned long new_len, unsigned long flags, unsigned long new_addr); -asmlinkage unsigned long sys64_mremap(unsigned long addr, - unsigned long old_len, unsigned long new_len, - unsigned long flags, unsigned long new_addr) +SYSCALL_DEFINE5(64_mremap, unsigned long, addr, unsigned long, old_len, + unsigned long, new_len, unsigned long, flags, + unsigned long, new_addr) { unsigned long ret = -EINVAL; @@ -669,7 +669,7 @@ extern void check_pending(int signum); -asmlinkage long sys_getdomainname(char __user *name, int len) +SYSCALL_DEFINE2(getdomainname, char __user *, name, int, len) { int nlen, err; @@ -692,11 +692,10 @@ return err; } -asmlinkage long sys_utrap_install(utrap_entry_t type, - utrap_handler_t new_p, - utrap_handler_t new_d, - utrap_handler_t __user *old_p, - utrap_handler_t __user *old_d) +SYSCALL_DEFINE5(utrap_install, utrap_entry_t, type, + utrap_handler_t, new_p, utrap_handler_t, new_d, + utrap_handler_t __user *, old_p, + utrap_handler_t __user *, old_d) { if (type < UT_INSTRUCTION_EXCEPTION || type > UT_TRAP_INSTRUCTION_31) return -EINVAL; @@ -762,11 +761,9 @@ return 0; } -asmlinkage long sys_rt_sigaction(int sig, - const struct sigaction __user *act, - struct sigaction __user *oact, - void __user *restorer, - size_t sigsetsize) +SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act, + struct sigaction __user *, oact, void __user *, restorer, + size_t, sigsetsize) { struct k_sigaction new_ka, old_ka; int ret; @@ -806,7 +803,8 @@ reset_pic(); } -asmlinkage long sys_perfctr(int opcode, unsigned long arg0, unsigned long arg1, unsigned long arg2) +SYSCALL_DEFINE4(perfctr, int, opcode, unsigned long, arg0, + unsigned long, arg1, unsigned long, arg2) { int err = 0; --- linux-2.6.28.orig/arch/sparc64/kernel/syscalls.S +++ linux-2.6.28/arch/sparc64/kernel/syscalls.S @@ -20,8 +20,8 @@ add %sp, PTREGS_OFF, %o0 .align 32 -sys_pipe: - ba,pt %xcc, sparc_pipe +sys_sparc_pipe: + ba,pt %xcc, sys_sparc_pipe_real add %sp, PTREGS_OFF, %o0 sys_nis_syscall: ba,pt %xcc, c_sys_nis_syscall --- linux-2.6.28.orig/arch/sparc64/kernel/chmc.c +++ linux-2.6.28/arch/sparc64/kernel/chmc.c @@ -306,6 +306,7 @@ buf[1] = '?'; buf[2] = '?'; buf[3] = '\0'; + return 0; } p = dp->controller; prop = &p->layout; --- linux-2.6.28.orig/arch/h8300/kernel/syscalls.S +++ linux-2.6.28/arch/h8300/kernel/syscalls.S @@ -103,7 +103,7 @@ .long SYMBOL_NAME(sys_uselib) .long SYMBOL_NAME(sys_swapon) .long SYMBOL_NAME(sys_reboot) - .long SYMBOL_NAME(old_readdir) + .long SYMBOL_NAME(sys_old_readdir) .long SYMBOL_NAME(old_mmap) /* 90 */ .long SYMBOL_NAME(sys_munmap) .long SYMBOL_NAME(sys_truncate) --- linux-2.6.28.orig/arch/x86/Kconfig +++ linux-2.6.28/arch/x86/Kconfig @@ -267,6 +267,12 @@ help Choose this option if your computer is a standard PC or compatible. +config X86_LPIA + bool "LPIA-compatible" + depends on X86_32 && X86_PC + help + Choose this option if your computer is an LPIA platform. + config X86_ELAN bool "AMD Elan" depends on X86_32 @@ -569,7 +575,7 @@ # need this always selected by IOMMU for the VIA workaround config SWIOTLB - bool + def_bool y if X86_64 help Support for software bounce buffers used on x86-64 systems which don't have a hardware IOMMU (e.g. the current generation @@ -1905,6 +1911,8 @@ source "drivers/Kconfig" +source "ubuntu/Kconfig" + source "drivers/firmware/Kconfig" source "fs/Kconfig" --- linux-2.6.28.orig/arch/x86/mm/pat.c +++ linux-2.6.28/arch/x86/mm/pat.c @@ -333,11 +333,23 @@ req_type & _PAGE_CACHE_MASK); } - is_range_ram = pagerange_is_ram(start, end); - if (is_range_ram == 1) - return reserve_ram_pages_type(start, end, req_type, new_type); - else if (is_range_ram < 0) - return -EINVAL; + if (new_type) + *new_type = actual_type; + + /* + * For legacy reasons, some parts of the physical address range in the + * legacy 1MB region is treated as non-RAM (even when listed as RAM in + * the e820 tables). So we will track the memory attributes of this + * legacy 1MB region using the linear memtype_list always. + */ + if (end >= ISA_END_ADDRESS) { + is_range_ram = pagerange_is_ram(start, end); + if (is_range_ram == 1) + return reserve_ram_pages_type(start, end, req_type, + new_type); + else if (is_range_ram < 0) + return -EINVAL; + } new = kmalloc(sizeof(struct memtype), GFP_KERNEL); if (!new) @@ -347,9 +359,6 @@ new->end = end; new->type = actual_type; - if (new_type) - *new_type = actual_type; - spin_lock(&memtype_lock); if (cached_entry && start >= cached_start) @@ -437,11 +446,19 @@ if (is_ISA_range(start, end - 1)) return 0; - is_range_ram = pagerange_is_ram(start, end); - if (is_range_ram == 1) - return free_ram_pages_type(start, end); - else if (is_range_ram < 0) - return -EINVAL; + /* + * For legacy reasons, some parts of the physical address range in the + * legacy 1MB region is treated as non-RAM (even when listed as RAM in + * the e820 tables). So we will track the memory attributes of this + * legacy 1MB region using the linear memtype_list always. + */ + if (end >= ISA_END_ADDRESS) { + is_range_ram = pagerange_is_ram(start, end); + if (is_range_ram == 1) + return free_ram_pages_type(start, end); + else if (is_range_ram < 0) + return -EINVAL; + } spin_lock(&memtype_lock); list_for_each_entry(entry, &memtype_list, nd) { --- linux-2.6.28.orig/arch/x86/mm/fault.c +++ linux-2.6.28/arch/x86/mm/fault.c @@ -533,7 +533,7 @@ happen within a race in page table update. In the later case just flush. */ - pgd = pgd_offset(current->mm ?: &init_mm, address); + pgd = pgd_offset(current->active_mm, address); pgd_ref = pgd_offset_k(address); if (pgd_none(*pgd_ref)) return -1; @@ -601,8 +601,6 @@ si_code = SEGV_MAPERR; - if (notify_page_fault(regs)) - return; if (unlikely(kmmio_fault(regs, address))) return; @@ -632,6 +630,9 @@ if (spurious_fault(address, error_code)) return; + /* kprobes don't want to hook the spurious faults. */ + if (notify_page_fault(regs)) + return; /* * Don't take the mm semaphore here. If we fixup a prefetch * fault we could otherwise deadlock. @@ -639,6 +640,9 @@ goto bad_area_nosemaphore; } + /* kprobes don't want to hook the spurious faults. */ + if (notify_page_fault(regs)) + return; /* * It's safe to allow irq's after cr2 has been saved and the --- linux-2.6.28.orig/arch/x86/mm/numa_64.c +++ linux-2.6.28/arch/x86/mm/numa_64.c @@ -145,7 +145,7 @@ return shift; } -int early_pfn_to_nid(unsigned long pfn) +int __meminit __early_pfn_to_nid(unsigned long pfn) { return phys_to_nid(pfn << PAGE_SHIFT); } --- linux-2.6.28.orig/arch/x86/mm/pageattr.c +++ linux-2.6.28/arch/x86/mm/pageattr.c @@ -534,6 +534,36 @@ return 0; } +static int __cpa_process_fault(struct cpa_data *cpa, unsigned long vaddr, + int primary) +{ + /* + * Ignore all non primary paths. + */ + if (!primary) + return 0; + + /* + * Ignore the NULL PTE for kernel identity mapping, as it is expected + * to have holes. + * Also set numpages to '1' indicating that we processed cpa req for + * one virtual address page and its pfn. TBD: numpages can be set based + * on the initial value and the level returned by lookup_address(). + */ + if (within(vaddr, PAGE_OFFSET, + PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT))) { + cpa->numpages = 1; + cpa->pfn = __pa(vaddr) >> PAGE_SHIFT; + return 0; + } else { + WARN(1, KERN_WARNING "CPA: called for zero pte. " + "vaddr = %lx cpa->vaddr = %lx\n", vaddr, + *cpa->vaddr); + + return -EFAULT; + } +} + static int __change_page_attr(struct cpa_data *cpa, int primary) { unsigned long address; @@ -546,20 +576,21 @@ else address = *cpa->vaddr; + /* + * If we're called with lazy mmu updates enabled, the + * in-memory pte state may be stale. Flush pending updates to + * bring them up to date. + */ + arch_flush_lazy_mmu_mode(); + repeat: kpte = lookup_address(address, &level); if (!kpte) - return 0; + return __cpa_process_fault(cpa, address, primary); old_pte = *kpte; - if (!pte_val(old_pte)) { - if (!primary) - return 0; - WARN(1, KERN_WARNING "CPA: called for zero pte. " - "vaddr = %lx cpa->vaddr = %lx\n", address, - *cpa->vaddr); - return -EINVAL; - } + if (!pte_val(old_pte)) + return __cpa_process_fault(cpa, address, primary); if (level == PG_LEVEL_4K) { pte_t new_pte; @@ -657,12 +688,7 @@ vaddr = *cpa->vaddr; if (!(within(vaddr, PAGE_OFFSET, - PAGE_OFFSET + (max_low_pfn_mapped << PAGE_SHIFT)) -#ifdef CONFIG_X86_64 - || within(vaddr, PAGE_OFFSET + (1UL<<32), - PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT)) -#endif - )) { + PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT)))) { alias_cpa = *cpa; temp_cpa_vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT); @@ -835,6 +861,13 @@ } else cpa_flush_all(cache); + /* + * If we've been called with lazy mmu updates enabled, then + * make sure that everything gets flushed out before we + * return. + */ + arch_flush_lazy_mmu_mode(); + out: return ret; } --- linux-2.6.28.orig/arch/x86/lib/usercopy_32.c +++ linux-2.6.28/arch/x86/lib/usercopy_32.c @@ -56,7 +56,7 @@ " jmp 2b\n" \ ".previous\n" \ _ASM_EXTABLE(0b,3b) \ - : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \ + : "=&d"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1), \ "=&D" (__d2) \ : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \ : "memory"); \ @@ -218,7 +218,7 @@ " .align 4\n" " .long 0b,2b\n" ".previous" - :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp) + :"=&r" (n), "=&D" (s), "=&a" (res), "=&c" (tmp) :"0" (n), "1" (s), "2" (0), "3" (mask) :"cc"); return res & mask; --- linux-2.6.28.orig/arch/x86/lib/usercopy_64.c +++ linux-2.6.28/arch/x86/lib/usercopy_64.c @@ -32,7 +32,7 @@ " jmp 2b\n" \ ".previous\n" \ _ASM_EXTABLE(0b,3b) \ - : "=r"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \ + : "=&r"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1), \ "=&D" (__d2) \ : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \ : "memory"); \ @@ -86,7 +86,7 @@ ".previous\n" _ASM_EXTABLE(0b,3b) _ASM_EXTABLE(1b,2b) - : [size8] "=c"(size), [dst] "=&D" (__d0) + : [size8] "=&c"(size), [dst] "=&D" (__d0) : [size1] "r"(size & 7), "[size8]" (size / 8), "[dst]"(addr), [zero] "r" (0UL), [eight] "r" (8UL)); return size; --- linux-2.6.28.orig/arch/x86/pci/i386.c +++ linux-2.6.28/arch/x86/pci/i386.c @@ -129,7 +129,7 @@ pr = pci_find_parent_resource(dev, r); if (!r->start || !pr || request_resource(pr, r) < 0) { - dev_err(&dev->dev, "BAR %d: can't allocate resource\n", idx); + dev_warn(&dev->dev, "BAR %d: can't allocate resource\n", idx); /* * Something is wrong with the region. * Invalidate the resource to prevent @@ -170,7 +170,7 @@ r->flags, disabled, pass); pr = pci_find_parent_resource(dev, r); if (!pr || request_resource(pr, r) < 0) { - dev_err(&dev->dev, "BAR %d: can't allocate resource\n", idx); + dev_warn(&dev->dev, "BAR %d: can't allocate resource\n", idx); /* We'll assign a new address later */ r->end -= r->start; r->start = 0; --- linux-2.6.28.orig/arch/x86/pci/irq.c +++ linux-2.6.28/arch/x86/pci/irq.c @@ -573,6 +573,7 @@ case PCI_DEVICE_ID_INTEL_ICH7_1: case PCI_DEVICE_ID_INTEL_ICH7_30: case PCI_DEVICE_ID_INTEL_ICH7_31: + case PCI_DEVICE_ID_INTEL_TGP_LPC: case PCI_DEVICE_ID_INTEL_ESB2_0: case PCI_DEVICE_ID_INTEL_ICH8_0: case PCI_DEVICE_ID_INTEL_ICH8_1: --- linux-2.6.28.orig/arch/x86/include/asm/cpufeature.h +++ linux-2.6.28/arch/x86/include/asm/cpufeature.h @@ -92,6 +92,7 @@ #define X86_FEATURE_NOPL (3*32+20) /* The NOPL (0F 1F) instructions */ #define X86_FEATURE_AMDC1E (3*32+21) /* AMD C1E detected */ #define X86_FEATURE_XTOPOLOGY (3*32+22) /* cpu topology enum extensions */ +#define X86_FEATURE_TSC_RELIABLE (3*32+23) /* TSC is known to be reliable */ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ #define X86_FEATURE_XMM3 (4*32+ 0) /* "pni" SSE-3 */ @@ -117,6 +118,7 @@ #define X86_FEATURE_XSAVE (4*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV */ #define X86_FEATURE_OSXSAVE (4*32+27) /* "" XSAVE enabled in the OS */ #define X86_FEATURE_AVX (4*32+28) /* Advanced Vector Extensions */ +#define X86_FEATURE_HYPERVISOR (4*32+31) /* Running on a hypervisor */ /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */ #define X86_FEATURE_XSTORE (5*32+ 2) /* "rng" RNG present (xstore) */ @@ -237,6 +239,7 @@ #define cpu_has_xmm4_2 boot_cpu_has(X86_FEATURE_XMM4_2) #define cpu_has_x2apic boot_cpu_has(X86_FEATURE_X2APIC) #define cpu_has_xsave boot_cpu_has(X86_FEATURE_XSAVE) +#define cpu_has_hypervisor boot_cpu_has(X86_FEATURE_HYPERVISOR) #if defined(CONFIG_X86_INVLPG) || defined(CONFIG_X86_64) # define cpu_has_invlpg 1 --- linux-2.6.28.orig/arch/x86/include/asm/dma-mapping.h +++ linux-2.6.28/arch/x86/include/asm/dma-mapping.h @@ -2,8 +2,8 @@ #define _ASM_X86_DMA_MAPPING_H /* - * IOMMU interface. See Documentation/DMA-mapping.txt and DMA-API.txt for - * documentation. + * IOMMU interface. See Documentation/PCI/PCI-DMA-mapping.txt and + * Documentation/DMA-API.txt for documentation. */ #include --- linux-2.6.28.orig/arch/x86/include/asm/msr-index.h +++ linux-2.6.28/arch/x86/include/asm/msr-index.h @@ -200,6 +200,35 @@ #define MSR_IA32_THERM_STATUS 0x0000019c #define MSR_IA32_MISC_ENABLE 0x000001a0 +/* MISC_ENABLE bits: architectural */ +#define MSR_IA32_MISC_ENABLE_FAST_STRING (1ULL << 0) +#define MSR_IA32_MISC_ENABLE_TCC (1ULL << 1) +#define MSR_IA32_MISC_ENABLE_EMON (1ULL << 7) +#define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL (1ULL << 11) +#define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL (1ULL << 12) +#define MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP (1ULL << 16) +#define MSR_IA32_MISC_ENABLE_MWAIT (1ULL << 18) +#define MSR_IA32_MISC_ENABLE_LIMIT_CPUID (1ULL << 22) +#define MSR_IA32_MISC_ENABLE_XTPR_DISABLE (1ULL << 23) +#define MSR_IA32_MISC_ENABLE_XD_DISABLE (1ULL << 34) + +/* MISC_ENABLE bits: model-specific, meaning may vary from core to core */ +#define MSR_IA32_MISC_ENABLE_X87_COMPAT (1ULL << 2) +#define MSR_IA32_MISC_ENABLE_TM1 (1ULL << 3) +#define MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE (1ULL << 4) +#define MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE (1ULL << 6) +#define MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK (1ULL << 8) +#define MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE (1ULL << 9) +#define MSR_IA32_MISC_ENABLE_FERR (1ULL << 10) +#define MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX (1ULL << 10) +#define MSR_IA32_MISC_ENABLE_TM2 (1ULL << 13) +#define MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE (1ULL << 19) +#define MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK (1ULL << 20) +#define MSR_IA32_MISC_ENABLE_L1D_CONTEXT (1ULL << 24) +#define MSR_IA32_MISC_ENABLE_DCU_PREF_DISABLE (1ULL << 37) +#define MSR_IA32_MISC_ENABLE_TURBO_DISABLE (1ULL << 38) +#define MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE (1ULL << 39) + /* Intel Model 6 */ #define MSR_P6_EVNTSEL0 0x00000186 #define MSR_P6_EVNTSEL1 0x00000187 --- linux-2.6.28.orig/arch/x86/include/asm/paravirt.h +++ linux-2.6.28/arch/x86/include/asm/paravirt.h @@ -1352,14 +1352,7 @@ PVOP_VCALL0(pv_cpu_ops.lazy_mode.leave); } -static inline void arch_flush_lazy_cpu_mode(void) -{ - if (unlikely(paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU)) { - arch_leave_lazy_cpu_mode(); - arch_enter_lazy_cpu_mode(); - } -} - +void arch_flush_lazy_cpu_mode(void); #define __HAVE_ARCH_ENTER_LAZY_MMU_MODE static inline void arch_enter_lazy_mmu_mode(void) @@ -1372,13 +1365,7 @@ PVOP_VCALL0(pv_mmu_ops.lazy_mode.leave); } -static inline void arch_flush_lazy_mmu_mode(void) -{ - if (unlikely(paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU)) { - arch_leave_lazy_mmu_mode(); - arch_enter_lazy_mmu_mode(); - } -} +void arch_flush_lazy_mmu_mode(void); static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx, unsigned long phys, pgprot_t flags) --- linux-2.6.28.orig/arch/x86/include/asm/pgalloc.h +++ linux-2.6.28/arch/x86/include/asm/pgalloc.h @@ -42,6 +42,7 @@ static inline void pte_free(struct mm_struct *mm, struct page *pte) { + pgtable_page_dtor(pte); __free_page(pte); } --- linux-2.6.28.orig/arch/x86/include/asm/processor.h +++ linux-2.6.28/arch/x86/include/asm/processor.h @@ -110,6 +110,7 @@ /* Index into per_cpu list: */ u16 cpu_index; #endif + unsigned int x86_hyper_vendor; } __attribute__((__aligned__(SMP_CACHE_BYTES))); #define X86_VENDOR_INTEL 0 @@ -123,6 +124,9 @@ #define X86_VENDOR_UNKNOWN 0xff +#define X86_HYPER_VENDOR_NONE 0 +#define X86_HYPER_VENDOR_VMWARE 1 + /* * capabilities of CPUs */ @@ -349,7 +353,7 @@ u8 no_update; u8 rm; u8 alimit; - struct info *info; + struct math_emu_info *info; u32 entry_eip; }; --- linux-2.6.28.orig/arch/x86/include/asm/seccomp_32.h +++ linux-2.6.28/arch/x86/include/asm/seccomp_32.h @@ -1,12 +1,6 @@ #ifndef _ASM_X86_SECCOMP_32_H #define _ASM_X86_SECCOMP_32_H -#include - -#ifdef TIF_32BIT -#error "unexpected TIF_32BIT on i386" -#endif - #include #define __NR_seccomp_read __NR_read --- linux-2.6.28.orig/arch/x86/include/asm/traps.h +++ linux-2.6.28/arch/x86/include/asm/traps.h @@ -41,7 +41,7 @@ dotraplinkage void do_overflow(struct pt_regs *, long); dotraplinkage void do_bounds(struct pt_regs *, long); dotraplinkage void do_invalid_op(struct pt_regs *, long); -dotraplinkage void do_device_not_available(struct pt_regs *, long); +dotraplinkage void do_device_not_available(struct pt_regs); dotraplinkage void do_coprocessor_segment_overrun(struct pt_regs *, long); dotraplinkage void do_invalid_TSS(struct pt_regs *, long); dotraplinkage void do_segment_not_present(struct pt_regs *, long); @@ -74,8 +74,8 @@ #ifdef CONFIG_X86_32 void math_error(void __user *); +void math_emulate(struct math_emu_info *); unsigned long patch_espfix_desc(unsigned long, unsigned long); -asmlinkage void math_emulate(long); #endif #endif /* _ASM_X86_TRAPS_H */ --- linux-2.6.28.orig/arch/x86/include/asm/mmzone_64.h +++ linux-2.6.28/arch/x86/include/asm/mmzone_64.h @@ -40,8 +40,6 @@ #define node_end_pfn(nid) (NODE_DATA(nid)->node_start_pfn + \ NODE_DATA(nid)->node_spanned_pages) -extern int early_pfn_to_nid(unsigned long pfn); - #ifdef CONFIG_NUMA_EMU #define FAKE_NODE_MIN_SIZE (64 * 1024 * 1024) #define FAKE_NODE_MIN_HASH_MASK (~(FAKE_NODE_MIN_SIZE - 1UL)) --- linux-2.6.28.orig/arch/x86/include/asm/math_emu.h +++ linux-2.6.28/arch/x86/include/asm/math_emu.h @@ -1,31 +1,18 @@ #ifndef _ASM_X86_MATH_EMU_H #define _ASM_X86_MATH_EMU_H +#include +#include + /* This structure matches the layout of the data saved to the stack following a device-not-present interrupt, part of it saved automatically by the 80386/80486. */ -struct info { +struct math_emu_info { long ___orig_eip; - long ___ebx; - long ___ecx; - long ___edx; - long ___esi; - long ___edi; - long ___ebp; - long ___eax; - long ___ds; - long ___es; - long ___fs; - long ___orig_eax; - long ___eip; - long ___cs; - long ___eflags; - long ___esp; - long ___ss; - long ___vm86_es; /* This and the following only in vm86 mode */ - long ___vm86_ds; - long ___vm86_fs; - long ___vm86_gs; + union { + struct pt_regs *regs; + struct kernel_vm86_regs *vm86; + }; }; #endif /* _ASM_X86_MATH_EMU_H */ --- linux-2.6.28.orig/arch/x86/include/asm/mmzone_32.h +++ linux-2.6.28/arch/x86/include/asm/mmzone_32.h @@ -32,8 +32,6 @@ get_memcfg_numa_flat(); } -extern int early_pfn_to_nid(unsigned long pfn); - extern void resume_map_numa_kva(pgd_t *pgd); #else /* !CONFIG_NUMA */ --- linux-2.6.28.orig/arch/x86/include/asm/seccomp_64.h +++ linux-2.6.28/arch/x86/include/asm/seccomp_64.h @@ -1,14 +1,6 @@ #ifndef _ASM_X86_SECCOMP_64_H #define _ASM_X86_SECCOMP_64_H -#include - -#ifdef TIF_32BIT -#error "unexpected TIF_32BIT on x86_64" -#else -#define TIF_32BIT TIF_IA32 -#endif - #include #include --- linux-2.6.28.orig/arch/x86/include/asm/hypervisor.h +++ linux-2.6.28/arch/x86/include/asm/hypervisor.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2008, VMware, 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 program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + * You 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. + * + */ +#ifndef ASM_X86__HYPERVISOR_H +#define ASM_X86__HYPERVISOR_H + +extern unsigned long get_hypervisor_tsc_freq(void); +extern void init_hypervisor(struct cpuinfo_x86 *c); + +#endif --- linux-2.6.28.orig/arch/x86/include/asm/vmware.h +++ linux-2.6.28/arch/x86/include/asm/vmware.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2008, VMware, 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 program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + * You 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. + * + */ +#ifndef ASM_X86__VMWARE_H +#define ASM_X86__VMWARE_H + +extern unsigned long vmware_get_tsc_khz(void); +extern int vmware_platform(void); +extern void vmware_set_feature_bits(struct cpuinfo_x86 *c); + +#endif --- linux-2.6.28.orig/arch/x86/xen/enlighten.c +++ linux-2.6.28/arch/x86/xen/enlighten.c @@ -1669,6 +1669,9 @@ possible map and a non-dummy shared_info. */ per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0]; + local_irq_disable(); + early_boot_irqs_off(); + xen_raw_console_write("mapping kernel into physical memory\n"); pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages); --- linux-2.6.28.orig/arch/x86/ia32/ia32entry.S +++ linux-2.6.28/arch/x86/ia32/ia32entry.S @@ -418,9 +418,9 @@ orl $TS_COMPAT,TI_status(%r10) testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%r10) jnz ia32_tracesys -ia32_do_syscall: cmpl $(IA32_NR_syscalls-1),%eax - ja int_ret_from_sys_call /* ia32_tracesys has set RAX(%rsp) */ + ja ia32_badsys +ia32_do_call: IA32_ARG_FIXUP call *ia32_sys_call_table(,%rax,8) # xxx: rip relative ia32_sysret: @@ -435,7 +435,9 @@ call syscall_trace_enter LOAD_ARGS32 ARGOFFSET /* reload args from stack in case ptrace changed it */ RESTORE_REST - jmp ia32_do_syscall + cmpl $(IA32_NR_syscalls-1),%eax + ja int_ret_from_sys_call /* ia32_tracesys has set RAX(%rsp) */ + jmp ia32_do_call END(ia32_syscall) ia32_badsys: --- linux-2.6.28.orig/arch/x86/kernel/alternative.c +++ linux-2.6.28/arch/x86/kernel/alternative.c @@ -410,6 +410,8 @@ void __init alternative_instructions(void) { + unsigned long flags; + /* The patching is not fully atomic, so try to avoid local interruptions that might execute the to be patched code. Other CPUs are not running. */ @@ -418,7 +420,9 @@ stop_mce(); #endif + local_irq_save(flags); apply_alternatives(__alt_instructions, __alt_instructions_end); + local_irq_restore(flags); /* switch to patch-once-at-boottime-only mode and free the * tables in case we know the number of CPUs will never ever @@ -448,7 +452,9 @@ alternatives_smp_switch(0); } #endif + local_irq_save(flags); apply_paravirt(__parainstructions, __parainstructions_end); + local_irq_restore(flags); if (smp_alt_once) free_init_pages("SMP alternatives", --- linux-2.6.28.orig/arch/x86/kernel/early-quirks.c +++ linux-2.6.28/arch/x86/kernel/early-quirks.c @@ -200,6 +200,12 @@ void (*f)(int num, int slot, int func); }; +/* + * Only works for devices on the root bus. If you add any devices + * not on bus 0 readd another loop level in early_quirks(). But + * be careful because at least the Nvidia quirk here relies on + * only matching on bus 0. + */ static struct chipset early_qrk[] __initdata = { { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, PCI_CLASS_BRIDGE_PCI, PCI_ANY_ID, QFLAG_APPLY_ONCE, nvidia_bugs }, @@ -266,17 +272,17 @@ void __init early_quirks(void) { - int num, slot, func; + int slot, func; if (!early_pci_allowed()) return; /* Poor man's PCI discovery */ - for (num = 0; num < 32; num++) - for (slot = 0; slot < 32; slot++) - for (func = 0; func < 8; func++) { - /* Only probe function 0 on single fn devices */ - if (check_dev_quirk(num, slot, func)) - break; - } + /* Only scan the root bus */ + for (slot = 0; slot < 32; slot++) + for (func = 0; func < 8; func++) { + /* Only probe function 0 on single fn devices */ + if (check_dev_quirk(0, slot, func)) + break; + } } --- linux-2.6.28.orig/arch/x86/kernel/setup.c +++ linux-2.6.28/arch/x86/kernel/setup.c @@ -98,6 +98,7 @@ #include #include +#include #include #include @@ -907,6 +908,12 @@ dmi_check_system(bad_bios_dmi_table); + /* + * VMware detection requires dmi to be available, so this + * needs to be done after dmi_scan_machine, for the BP. + */ + init_hypervisor(&boot_cpu_data); + #ifdef CONFIG_X86_32 probe_roms(); #endif --- linux-2.6.28.orig/arch/x86/kernel/msr.c +++ linux-2.6.28/arch/x86/kernel/msr.c @@ -249,3 +249,4 @@ MODULE_AUTHOR("H. Peter Anvin "); MODULE_DESCRIPTION("x86 generic MSR driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS_CHARDEV_MAJOR(MSR_MAJOR); --- linux-2.6.28.orig/arch/x86/kernel/hpet.c +++ linux-2.6.28/arch/x86/kernel/hpet.c @@ -267,6 +267,8 @@ now = hpet_readl(HPET_COUNTER); cmp = now + (unsigned long) delta; cfg = hpet_readl(HPET_Tn_CFG(timer)); + /* Make sure we use edge triggered interrupts */ + cfg &= ~HPET_TN_LEVEL; cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL | HPET_TN_32BIT; hpet_writel(cfg, HPET_Tn_CFG(timer)); --- linux-2.6.28.orig/arch/x86/kernel/microcode_amd.c +++ linux-2.6.28/arch/x86/kernel/microcode_amd.c @@ -62,7 +62,7 @@ unsigned int mc_patch_data_checksum; unsigned int nb_dev_id; unsigned int sb_dev_id; - unsigned char processor_rev_id[2]; + u16 processor_rev_id; unsigned char nb_rev_id; unsigned char sb_rev_id; unsigned char bios_api_rev; @@ -125,7 +125,7 @@ while (equiv_cpu_table[i].installed_cpu != 0) { if (current_cpu_id == equiv_cpu_table[i].installed_cpu) { - equiv_cpu_id = equiv_cpu_table[i].equiv_cpu; + equiv_cpu_id = equiv_cpu_table[i].equiv_cpu & 0xffff; break; } i++; @@ -137,21 +137,10 @@ return 0; } - if ((mc_header->processor_rev_id[0]) != (equiv_cpu_id & 0xff)) { - printk(KERN_ERR - "microcode: CPU%d patch does not match " - "(patch is %x, cpu extended is %x) \n", - cpu, mc_header->processor_rev_id[0], - (equiv_cpu_id & 0xff)); - return 0; - } - - if ((mc_header->processor_rev_id[1]) != ((equiv_cpu_id >> 16) & 0xff)) { - printk(KERN_ERR "microcode: CPU%d patch does not match " - "(patch is %x, cpu base id is %x) \n", - cpu, mc_header->processor_rev_id[1], - ((equiv_cpu_id >> 16) & 0xff)); - + if (mc_header->processor_rev_id != equiv_cpu_id) { + printk(KERN_ERR "microcode: CPU%d patch does not match " + "(processor_rev_id: %x, eqiv_cpu_id: %x)\n", + cpu, mc_header->processor_rev_id, equiv_cpu_id); return 0; } --- linux-2.6.28.orig/arch/x86/kernel/traps.c +++ linux-2.6.28/arch/x86/kernel/traps.c @@ -104,6 +104,12 @@ local_irq_enable(); } +static inline void conditional_cli(struct pt_regs *regs) +{ + if (regs->flags & X86_EFLAGS_IF) + local_irq_disable(); +} + static inline void preempt_conditional_cli(struct pt_regs *regs) { if (regs->flags & X86_EFLAGS_IF) @@ -629,8 +635,10 @@ #ifdef CONFIG_X86_32 debug_vm86: + /* reenable preemption: handle_vm86_trap() might sleep */ + dec_preempt_count(); handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1); - preempt_conditional_cli(regs); + conditional_cli(regs); return; #endif @@ -904,7 +912,7 @@ EXPORT_SYMBOL_GPL(math_state_restore); #ifndef CONFIG_MATH_EMULATION -asmlinkage void math_emulate(long arg) +void math_emulate(struct math_emu_info *info) { printk(KERN_EMERG "math-emulation not enabled and no coprocessor found.\n"); @@ -914,16 +922,19 @@ } #endif /* CONFIG_MATH_EMULATION */ -dotraplinkage void __kprobes -do_device_not_available(struct pt_regs *regs, long error) +dotraplinkage void __kprobes do_device_not_available(struct pt_regs regs) { #ifdef CONFIG_X86_32 if (read_cr0() & X86_CR0_EM) { - conditional_sti(regs); - math_emulate(0); + struct math_emu_info info = { }; + + conditional_sti(®s); + + info.regs = ®s; + math_emulate(&info); } else { math_state_restore(); /* interrupts still off */ - conditional_sti(regs); + conditional_sti(®s); } #else math_state_restore(); --- linux-2.6.28.orig/arch/x86/kernel/vmi_32.c +++ linux-2.6.28/arch/x86/kernel/vmi_32.c @@ -430,6 +430,16 @@ } /* + * We use the pgd_free hook for releasing the pgd page: + */ +static void vmi_pgd_free(struct mm_struct *mm, pgd_t *pgd) +{ + unsigned long pfn = __pa(pgd) >> PAGE_SHIFT; + + vmi_ops.release_page(pfn, VMI_PAGE_L2); +} + +/* * Helper macros for MMU update flags. We can defer updates until a flush * or page invalidation only if the update is to the current address space * (otherwise, there is no flush). We must check against init_mm, since @@ -881,6 +891,7 @@ if (vmi_ops.release_page) { pv_mmu_ops.release_pte = vmi_release_pte; pv_mmu_ops.release_pmd = vmi_release_pmd; + pv_mmu_ops.pgd_free = vmi_pgd_free; } /* Set linear is needed in all cases */ --- linux-2.6.28.orig/arch/x86/kernel/paravirt.c +++ linux-2.6.28/arch/x86/kernel/paravirt.c @@ -268,6 +268,30 @@ return __get_cpu_var(paravirt_lazy_mode); } +void arch_flush_lazy_mmu_mode(void) +{ + preempt_disable(); + + if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) { + arch_leave_lazy_mmu_mode(); + arch_enter_lazy_mmu_mode(); + } + + preempt_enable(); +} + +void arch_flush_lazy_cpu_mode(void) +{ + preempt_disable(); + + if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU) { + arch_leave_lazy_cpu_mode(); + arch_enter_lazy_cpu_mode(); + } + + preempt_enable(); +} + struct pv_info pv_info = { .name = "bare hardware", .paravirt_enabled = 0, --- linux-2.6.28.orig/arch/x86/kernel/tsc.c +++ linux-2.6.28/arch/x86/kernel/tsc.c @@ -15,6 +15,7 @@ #include #include #include +#include unsigned int cpu_khz; /* TSC clocks / usec, not used here */ EXPORT_SYMBOL(cpu_khz); @@ -31,6 +32,7 @@ erroneous rdtsc usage on !cpu_has_tsc processors */ static int tsc_disabled = -1; +static int tsc_clocksource_reliable; /* * Scheduler clock - returns current time in nanosec units. */ @@ -98,6 +100,15 @@ __setup("notsc", notsc_setup); +static int __init tsc_setup(char *str) +{ + if (!strcmp(str, "reliable")) + tsc_clocksource_reliable = 1; + return 1; +} + +__setup("tsc=", tsc_setup); + #define MAX_RETRIES 5 #define SMI_TRESHOLD 50000 @@ -352,9 +363,15 @@ { u64 tsc1, tsc2, delta, ref1, ref2; unsigned long tsc_pit_min = ULONG_MAX, tsc_ref_min = ULONG_MAX; - unsigned long flags, latch, ms, fast_calibrate; + unsigned long flags, latch, ms, fast_calibrate, tsc_khz; int hpet = is_hpet_enabled(), i, loopmin; + tsc_khz = get_hypervisor_tsc_freq(); + if (tsc_khz) { + printk(KERN_INFO "TSC: Frequency read from the hypervisor\n"); + return tsc_khz; + } + local_irq_save(flags); fast_calibrate = quick_pit_calibrate(); local_irq_restore(flags); @@ -731,24 +748,21 @@ {} }; -/* - * Geode_LX - the OLPC CPU has a possibly a very reliable TSC - */ +static void __init check_system_tsc_reliable(void) +{ #ifdef CONFIG_MGEODE_LX -/* RTSC counts during suspend */ + /* RTSC counts during suspend */ #define RTSC_SUSP 0x100 - -static void __init check_geode_tsc_reliable(void) -{ unsigned long res_low, res_high; rdmsr_safe(MSR_GEODE_BUSCONT_CONF0, &res_low, &res_high); + /* Geode_LX - the OLPC CPU has a possibly a very reliable TSC */ if (res_low & RTSC_SUSP) - clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY; -} -#else -static inline void check_geode_tsc_reliable(void) { } + tsc_clocksource_reliable = 1; #endif + if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) + tsc_clocksource_reliable = 1; +} /* * Make an educated guess if the TSC is trustworthy and synchronized @@ -783,6 +797,8 @@ { clocksource_tsc.mult = clocksource_khz2mult(tsc_khz, clocksource_tsc.shift); + if (tsc_clocksource_reliable) + clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY; /* lower the rating if we already know its unstable: */ if (check_tsc_unstable()) { clocksource_tsc.rating = 0; @@ -843,7 +859,7 @@ if (unsynchronized_tsc()) mark_tsc_unstable("TSCs unsynchronized"); - check_geode_tsc_reliable(); + check_system_tsc_reliable(); init_tsc_clocksource(); } --- linux-2.6.28.orig/arch/x86/kernel/tlb_uv.c +++ linux-2.6.28/arch/x86/kernel/tlb_uv.c @@ -586,7 +586,6 @@ static struct bau_control * __init uv_table_bases_init(int blade, int node) { int i; - int *ip; struct bau_msg_status *msp; struct bau_control *bau_tabp; @@ -603,13 +602,6 @@ bau_cpubits_clear(&msp->seen_by, (int) uv_blade_nr_possible_cpus(blade)); - bau_tabp->watching = - kmalloc_node(sizeof(int) * DEST_NUM_RESOURCES, GFP_KERNEL, node); - BUG_ON(!bau_tabp->watching); - - for (i = 0, ip = bau_tabp->watching; i < DEST_Q_SIZE; i++, ip++) - *ip = 0; - uv_bau_table_bases[blade] = bau_tabp; return bau_tabp; @@ -632,7 +624,6 @@ bcp->bau_msg_head = bau_tablesp->va_queue_first; bcp->va_queue_first = bau_tablesp->va_queue_first; bcp->va_queue_last = bau_tablesp->va_queue_last; - bcp->watching = bau_tablesp->watching; bcp->msg_statuses = bau_tablesp->msg_statuses; bcp->descriptor_base = adp; } --- linux-2.6.28.orig/arch/x86/kernel/head64.c +++ linux-2.6.28/arch/x86/kernel/head64.c @@ -26,7 +26,7 @@ #include /* boot cpu pda */ -static struct x8664_pda _boot_cpu_pda __read_mostly; +static struct x8664_pda _boot_cpu_pda; #ifdef CONFIG_SMP /* --- linux-2.6.28.orig/arch/x86/kernel/reboot.c +++ linux-2.6.28/arch/x86/kernel/reboot.c @@ -194,6 +194,15 @@ DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation T5400"), }, }, + { /* Handle problems with rebooting on Dell Dimension 9200 */ + .callback = set_bios_reboot, + .ident = "Dell Dimension 9200", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Dell DXP061"), + DMI_MATCH(DMI_BOARD_NAME, "0CT017"), + }, + }, { /* Handle problems with rebooting on HP laptops */ .callback = set_bios_reboot, .ident = "HP Compaq Laptop", @@ -202,6 +211,26 @@ DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"), }, }, +#ifdef CONFIG_X86_LPIA + { /* Handle problems with rebooting on Intel Crown Beach board */ + .callback = set_bios_reboot, + .ident = "Intel Crown Beach board", + .matches = { + /* Currently the DMI info is not customized and indicates + * OEM need change that */ + DMI_MATCH(DMI_SYS_VENDOR, "To Be Filled By O.E.M."), + DMI_MATCH(DMI_PRODUCT_NAME, "To Be Filled By O.E.M."), + }, + }, +#endif + { /* Handle problems with rebooting on Dell XPS710 */ + .callback = set_bios_reboot, + .ident = "Dell XPS710", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Dell XPS710"), + }, + }, { } }; --- linux-2.6.28.orig/arch/x86/kernel/apic.c +++ linux-2.6.28/arch/x86/kernel/apic.c @@ -1451,7 +1451,7 @@ switch (boot_cpu_data.x86_vendor) { case X86_VENDOR_AMD: if ((boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model > 1) || - (boot_cpu_data.x86 == 15)) + (boot_cpu_data.x86 >= 15)) break; goto no_apic; case X86_VENDOR_INTEL: --- linux-2.6.28.orig/arch/x86/kernel/ptrace.c +++ linux-2.6.28/arch/x86/kernel/ptrace.c @@ -1512,7 +1512,7 @@ #ifdef CONFIG_X86_32 # define IS_IA32 1 #elif defined CONFIG_IA32_EMULATION -# define IS_IA32 test_thread_flag(TIF_IA32) +# define IS_IA32 is_compat_task() #else # define IS_IA32 0 #endif --- linux-2.6.28.orig/arch/x86/kernel/syscall_table_32.S +++ linux-2.6.28/arch/x86/kernel/syscall_table_32.S @@ -88,7 +88,7 @@ .long sys_uselib .long sys_swapon .long sys_reboot - .long old_readdir + .long sys_old_readdir .long old_mmap /* 90 */ .long sys_munmap .long sys_truncate --- linux-2.6.28.orig/arch/x86/kernel/tsc_sync.c +++ linux-2.6.28/arch/x86/kernel/tsc_sync.c @@ -112,6 +112,12 @@ if (unsynchronized_tsc()) return; + if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) { + printk(KERN_INFO + "Skipping synchronization checks as TSC is reliable.\n"); + return; + } + printk(KERN_INFO "checking TSC synchronization [CPU#%d -> CPU#%d]:", smp_processor_id(), cpu); @@ -165,7 +171,7 @@ { int cpus = 2; - if (unsynchronized_tsc()) + if (unsynchronized_tsc() || boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) return; /* --- linux-2.6.28.orig/arch/x86/kernel/pci-gart_64.c +++ linux-2.6.28/arch/x86/kernel/pci-gart_64.c @@ -5,7 +5,7 @@ * This allows to use PCI devices that only support 32bit addresses on systems * with more than 4GB. * - * See Documentation/DMA-mapping.txt for the interface specification. + * See Documentation/PCI/PCI-DMA-mapping.txt for the interface specification. * * Copyright 2002 Andi Kleen, SuSE Labs. * Subject to the GNU General Public License v2 only. --- linux-2.6.28.orig/arch/x86/kernel/cpuid.c +++ linux-2.6.28/arch/x86/kernel/cpuid.c @@ -237,3 +237,4 @@ MODULE_AUTHOR("H. Peter Anvin "); MODULE_DESCRIPTION("x86 generic CPUID driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS_CHARDEV_MAJOR(CPUID_MAJOR); --- linux-2.6.28.orig/arch/x86/kernel/head_64.S +++ linux-2.6.28/arch/x86/kernel/head_64.S @@ -305,7 +305,7 @@ call dump_stack #ifdef CONFIG_KALLSYMS leaq early_idt_ripmsg(%rip),%rdi - movq 8(%rsp),%rsi # get rip again + movq 0(%rsp),%rsi # get rip again call __print_symbol #endif #endif /* EARLY_PRINTK */ --- linux-2.6.28.orig/arch/x86/kernel/vmiclock_32.c +++ linux-2.6.28/arch/x86/kernel/vmiclock_32.c @@ -283,10 +283,13 @@ #endif /** vmi clocksource */ +static struct clocksource clocksource_vmi; static cycle_t read_real_cycles(void) { - return vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL); + cycle_t ret = (cycle_t)vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL); + return ret >= clocksource_vmi.cycle_last ? + ret : clocksource_vmi.cycle_last; } static struct clocksource clocksource_vmi = { --- linux-2.6.28.orig/arch/x86/kernel/acpi/cstate.c +++ linux-2.6.28/arch/x86/kernel/acpi/cstate.c @@ -56,6 +56,7 @@ static short mwait_supported[ACPI_PROCESSOR_MAX_POWER]; #define MWAIT_SUBSTATE_MASK (0xf) +#define MWAIT_CSTATE_MASK (0xf) #define MWAIT_SUBSTATE_SIZE (4) #define CPUID_MWAIT_LEAF (5) @@ -98,7 +99,8 @@ cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx); /* Check whether this particular cx_type (in CST) is supported or not */ - cstate_type = (cx->address >> MWAIT_SUBSTATE_SIZE) + 1; + cstate_type = ((cx->address >> MWAIT_SUBSTATE_SIZE) & + MWAIT_CSTATE_MASK) + 1; edx_part = edx >> (cstate_type * MWAIT_SUBSTATE_SIZE); num_cstate_subtype = edx_part & MWAIT_SUBSTATE_MASK; --- linux-2.6.28.orig/arch/x86/kernel/cpu/hypervisor.c +++ linux-2.6.28/arch/x86/kernel/cpu/hypervisor.c @@ -0,0 +1,57 @@ +/* + * Common hypervisor code + * + * Copyright (C) 2008, VMware, Inc. + * Author : Alok N Kataria + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + * You 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. + * + */ + +#include +#include + +static inline void __cpuinit +detect_hypervisor_vendor(struct cpuinfo_x86 *c) +{ + if (vmware_platform()) { + c->x86_hyper_vendor = X86_HYPER_VENDOR_VMWARE; + } else { + c->x86_hyper_vendor = X86_HYPER_VENDOR_NONE; + } +} + +unsigned long get_hypervisor_tsc_freq(void) +{ + if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE) + return vmware_get_tsc_khz(); + return 0; +} + +static inline void __cpuinit +hypervisor_set_feature_bits(struct cpuinfo_x86 *c) +{ + if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE) { + vmware_set_feature_bits(c); + return; + } +} + +void __cpuinit init_hypervisor(struct cpuinfo_x86 *c) +{ + detect_hypervisor_vendor(c); + hypervisor_set_feature_bits(c); +} --- linux-2.6.28.orig/arch/x86/kernel/cpu/intel.c +++ linux-2.6.28/arch/x86/kernel/cpu/intel.c @@ -30,6 +30,19 @@ static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) { + /* Unmask CPUID levels if masked: */ + if (c->x86 == 6 && c->x86_model >= 15) { + u64 misc_enable; + + rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable); + + if (misc_enable & MSR_IA32_MISC_ENABLE_LIMIT_CPUID) { + misc_enable &= ~MSR_IA32_MISC_ENABLE_LIMIT_CPUID; + wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable); + c->cpuid_level = cpuid_eax(0); + } + } + if ((c->x86 == 0xf && c->x86_model >= 0x03) || (c->x86 == 0x6 && c->x86_model >= 0x0e)) set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); @@ -242,6 +255,13 @@ intel_workarounds(c); + /* + * Detect the extended topology information if available. This + * will reinitialise the initial_apicid which will be used + * in init_intel_cacheinfo() + */ + detect_extended_topology(c); + l2 = init_intel_cacheinfo(c); if (c->cpuid_level > 9) { unsigned eax = cpuid_eax(10); @@ -313,7 +333,6 @@ #endif - detect_extended_topology(c); if (!cpu_has(c, X86_FEATURE_XTOPOLOGY)) { /* * let's use the legacy cpuid vector 0x1 and 0x4 for topology --- linux-2.6.28.orig/arch/x86/kernel/cpu/vmware.c +++ linux-2.6.28/arch/x86/kernel/cpu/vmware.c @@ -0,0 +1,112 @@ +/* + * VMware Detection code. + * + * Copyright (C) 2008, VMware, Inc. + * Author : Alok N Kataria + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + * You 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. + * + */ + +#include +#include +#include + +#define CPUID_VMWARE_INFO_LEAF 0x40000000 +#define VMWARE_HYPERVISOR_MAGIC 0x564D5868 +#define VMWARE_HYPERVISOR_PORT 0x5658 + +#define VMWARE_PORT_CMD_GETVERSION 10 +#define VMWARE_PORT_CMD_GETHZ 45 + +#define VMWARE_PORT(cmd, eax, ebx, ecx, edx) \ + __asm__("inl (%%dx)" : \ + "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) : \ + "0"(VMWARE_HYPERVISOR_MAGIC), \ + "1"(VMWARE_PORT_CMD_##cmd), \ + "2"(VMWARE_HYPERVISOR_PORT), "3"(UINT_MAX) : \ + "memory"); + +static inline int __vmware_platform(void) +{ + uint32_t eax, ebx, ecx, edx; + VMWARE_PORT(GETVERSION, eax, ebx, ecx, edx); + return eax != (uint32_t)-1 && ebx == VMWARE_HYPERVISOR_MAGIC; +} + +static unsigned long __vmware_get_tsc_khz(void) +{ + uint64_t tsc_hz; + uint32_t eax, ebx, ecx, edx; + + VMWARE_PORT(GETHZ, eax, ebx, ecx, edx); + + if (ebx == UINT_MAX) + return 0; + tsc_hz = eax | (((uint64_t)ebx) << 32); + do_div(tsc_hz, 1000); + BUG_ON(tsc_hz >> 32); + return tsc_hz; +} + +/* + * While checking the dmi string infomation, just checking the product + * serial key should be enough, as this will always have a VMware + * specific string when running under VMware hypervisor. + */ +int vmware_platform(void) +{ + if (cpu_has_hypervisor) { + unsigned int eax, ebx, ecx, edx; + char hyper_vendor_id[13]; + + cpuid(CPUID_VMWARE_INFO_LEAF, &eax, &ebx, &ecx, &edx); + memcpy(hyper_vendor_id + 0, &ebx, 4); + memcpy(hyper_vendor_id + 4, &ecx, 4); + memcpy(hyper_vendor_id + 8, &edx, 4); + hyper_vendor_id[12] = '\0'; + if (!strcmp(hyper_vendor_id, "VMwareVMware")) + return 1; + } else if (dmi_available && dmi_name_in_serial("VMware") && + __vmware_platform()) + return 1; + + return 0; +} + +unsigned long vmware_get_tsc_khz(void) +{ + BUG_ON(!vmware_platform()); + return __vmware_get_tsc_khz(); +} + +/* + * VMware hypervisor takes care of exporting a reliable TSC to the guest. + * Still, due to timing difference when running on virtual cpus, the TSC can + * be marked as unstable in some cases. For example, the TSC sync check at + * bootup can fail due to a marginal offset between vcpus' TSCs (though the + * TSCs do not drift from each other). Also, the ACPI PM timer clocksource + * is not suitable as a watchdog when running on a hypervisor because the + * kernel may miss a wrap of the counter if the vcpu is descheduled for a + * long time. To skip these checks at runtime we set these capability bits, + * so that the kernel could just trust the hypervisor with providing a + * reliable virtual TSC that is suitable for timekeeping. + */ +void __cpuinit vmware_set_feature_bits(struct cpuinfo_x86 *c) +{ + set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); + set_cpu_cap(c, X86_FEATURE_TSC_RELIABLE); +} --- linux-2.6.28.orig/arch/x86/kernel/cpu/Makefile +++ linux-2.6.28/arch/x86/kernel/cpu/Makefile @@ -4,6 +4,7 @@ obj-y := intel_cacheinfo.o addon_cpuid_features.o obj-y += proc.o capflags.o powerflags.o common.o +obj-y += vmware.o hypervisor.o obj-$(CONFIG_X86_32) += bugs.o cmpxchg.o obj-$(CONFIG_X86_64) += bugs_64.o --- linux-2.6.28.orig/arch/x86/kernel/cpu/addon_cpuid_features.c +++ linux-2.6.28/arch/x86/kernel/cpu/addon_cpuid_features.c @@ -120,9 +120,17 @@ c->cpu_core_id = phys_pkg_id(c->initial_apicid, ht_mask_width) & core_select_mask; c->phys_proc_id = phys_pkg_id(c->initial_apicid, core_plus_mask_width); + /* + * Reinit the apicid, now that we have extended initial_apicid. + */ + c->apicid = phys_pkg_id(c->initial_apicid, 0); #else c->cpu_core_id = phys_pkg_id(ht_mask_width) & core_select_mask; c->phys_proc_id = phys_pkg_id(core_plus_mask_width); + /* + * Reinit the apicid, now that we have extended initial_apicid. + */ + c->apicid = phys_pkg_id(0); #endif c->x86_max_cores = (core_level_siblings / smp_num_siblings); --- linux-2.6.28.orig/arch/x86/kernel/cpu/common.c +++ linux-2.6.28/arch/x86/kernel/cpu/common.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "cpu.h" @@ -703,6 +704,7 @@ detect_ht(c); #endif + init_hypervisor(c); /* * On SMP, boot_cpu_data holds the common feature set between * all CPUs; so make sure that we indicate which features are --- linux-2.6.28.orig/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c +++ linux-2.6.28/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c @@ -45,6 +45,7 @@ CPU_DOTHAN_A1, CPU_DOTHAN_A2, CPU_DOTHAN_B0, + CPU_DOTHAN_C0, CPU_MP4HT_D0, CPU_MP4HT_E0, }; @@ -54,6 +55,7 @@ [CPU_DOTHAN_A1] = { 6, 13, 1 }, [CPU_DOTHAN_A2] = { 6, 13, 2 }, [CPU_DOTHAN_B0] = { 6, 13, 6 }, + [CPU_DOTHAN_C0] = { 6, 13, 8 }, [CPU_MP4HT_D0] = {15, 3, 4 }, [CPU_MP4HT_E0] = {15, 4, 1 }, }; @@ -196,6 +198,88 @@ }; #undef OP + +#define OPEX(mhz, base, mva, mvb, mvc, mvd) \ +{ \ + .frequency = (mhz) * 1000, \ + .index = (((mhz)/(base)) << 8) | ((mva - 700) / 16) \ +} + +/* Intel Pentium M processor 730 / 1.60 GHz (Sonoma) */ +static struct cpufreq_frequency_table sonoma_1596[] = +{ + OPEX( 798, 133, 988, 988, 988, 988), + OPEX(1064, 133, 1116, 1111, 1084, 1079), + OPEX(1330, 133, 1244, 1233, 1180, 1169), + OPEX(1596, 133, 1356, 1356, 1260, 1260), + { .frequency = CPUFREQ_TABLE_END } +}; + +/* Intel Pentium M processor 740 / 1.73 GHz (Sonoma) */ +static struct cpufreq_frequency_table sonoma_1729[] = +{ + OPEX( 798, 133, 988, 988, 988, 988), + OPEX(1064, 133, 1100, 1093, 1068, 1066), + OPEX(1330, 133, 1212, 1198, 1148, 1143), + OPEX(1729, 133, 1356, 1356, 1260, 1260), + { .frequency = CPUFREQ_TABLE_END } +}; + +/* Intel Pentium M processor 750 / 1.86 GHz (Sonoma) */ +static struct cpufreq_frequency_table sonoma_1862[] = +{ + OPEX( 798, 133, 988, 988, 988, 988), + OPEX(1064, 133, 1084, 1080, 1068, 1056), + OPEX(1330, 133, 1180, 1172, 1132, 1124), + OPEX(1596, 133, 1276, 1264, 1196, 1192), + OPEX(1862, 133, 1356, 1356, 1260, 1260), + { .frequency = CPUFREQ_TABLE_END } +}; + +/* Intel Pentium M processor 760 / 2.00 GHz (Sonoma) */ +static struct cpufreq_frequency_table sonoma_1995[] = +{ + OPEX( 798, 133, 988, 988, 988, 988), + OPEX(1064, 133, 1084, 1070, 1052, 1048), + OPEX(1330, 133, 1164, 1152, 1116, 1109), + OPEX(1596, 133, 1244, 1233, 1180, 1169), + OPEX(1995, 133, 1356, 1356, 1260, 1260), + { .frequency = CPUFREQ_TABLE_END } +}; +/* Intel Pentium M processor 770 / 2.13 GHz (Sonoma) */ +static struct cpufreq_frequency_table sonoma_2128[] = +{ + OPEX( 798, 133, 988, 988, 988, 988), + OPEX(1064, 133, 1068, 1065, 1052, 1042), + OPEX(1330, 133, 1148, 1142, 1100, 1097), + OPEX(1596, 133, 1228, 1218, 1164, 1151), + OPEX(1862, 133, 1308, 1295, 1212, 1206), + OPEX(2128, 133, 1372, 1372, 1260, 1260), + { .frequency = CPUFREQ_TABLE_END } +}; + +/* Intel Pentium M processor 780 / 2.26 GHz (Sonoma) */ +static struct cpufreq_frequency_table sonoma_2261[] = +{ + OPEX( 798, 133, 988, 988, 988, 988), + OPEX(1064, 133, 1068, 1064, 1052, 1037), + OPEX(1330, 133, 1148, 1139, 1100, 1087), + OPEX(1596, 133, 1228, 1215, 1148, 1136), + OPEX(1862, 133, 1292, 1291, 1196, 1186), + OPEX(2261, 133, 1404, 1404, 1260, 1260), + { .frequency = CPUFREQ_TABLE_END } +}; + +#undef OPEX + +#define SONOMA(cpuid, max, base, name) \ +{ .cpu_id = cpuid, \ + .model_name = "Intel(R) Pentium(R) M processor " name "GHz", \ + .max_freq = (max)*1000, \ + .op_points = sonoma_##max, \ +} + + #define _BANIAS(cpuid, max, name) \ { .cpu_id = cpuid, \ .model_name = "Intel(R) Pentium(R) M processor " name "MHz", \ @@ -218,6 +302,15 @@ BANIAS(1600), BANIAS(1700), + /* Builtin tables for Dothan C0 CPUs, a.k.a Sonoma */ + SONOMA(&cpu_ids[CPU_DOTHAN_C0], 1596, 133, "1.60"), + SONOMA(&cpu_ids[CPU_DOTHAN_C0], 1729, 133, "1.73"), + SONOMA(&cpu_ids[CPU_DOTHAN_C0], 1862, 133, "1.86"), + SONOMA(&cpu_ids[CPU_DOTHAN_C0], 1995, 133, "2.00"), + SONOMA(&cpu_ids[CPU_DOTHAN_C0], 2128, 133, "2.13"), + SONOMA(&cpu_ids[CPU_DOTHAN_C0], 2261, 133, "2.26"), + + /* NULL model_name is a wildcard */ { &cpu_ids[CPU_DOTHAN_A1], NULL, 0, NULL }, { &cpu_ids[CPU_DOTHAN_A2], NULL, 0, NULL }, --- linux-2.6.28.orig/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c +++ linux-2.6.28/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c @@ -420,7 +420,7 @@ /* detect chipset */ if (nforce2_detect_chipset()) { - printk(KERN_ERR "cpufreq: No nForce2 chipset.\n"); + printk(KERN_INFO "cpufreq: No nForce2 chipset.\n"); return -ENODEV; } --- linux-2.6.28.orig/arch/x86/kernel/cpu/cpufreq/Makefile +++ linux-2.6.28/arch/x86/kernel/cpu/cpufreq/Makefile @@ -1,6 +1,11 @@ +# Link order matters. K8 is preferred to ACPI because of firmware bugs in early +# K8 systems. ACPI is preferred to all other hardware-specific drivers. +# speedstep-* is preferred over p4-clockmod. + +obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o +obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o obj-$(CONFIG_X86_POWERNOW_K6) += powernow-k6.o obj-$(CONFIG_X86_POWERNOW_K7) += powernow-k7.o -obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o obj-$(CONFIG_X86_LONGHAUL) += longhaul.o obj-$(CONFIG_X86_E_POWERSAVER) += e_powersaver.o obj-$(CONFIG_ELAN_CPUFREQ) += elanfreq.o @@ -10,7 +15,6 @@ obj-$(CONFIG_X86_SPEEDSTEP_ICH) += speedstep-ich.o obj-$(CONFIG_X86_SPEEDSTEP_LIB) += speedstep-lib.o obj-$(CONFIG_X86_SPEEDSTEP_SMI) += speedstep-smi.o -obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi-cpufreq.o obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO) += speedstep-centrino.o obj-$(CONFIG_X86_P4_CLOCKMOD) += p4-clockmod.o obj-$(CONFIG_X86_CPUFREQ_NFORCE2) += cpufreq-nforce2.o --- linux-2.6.28.orig/arch/x86/kernel/cpu/mtrr/generic.c +++ linux-2.6.28/arch/x86/kernel/cpu/mtrr/generic.c @@ -45,6 +45,32 @@ static int mtrr_show; module_param_named(show, mtrr_show, bool, 0); +/** + * BIOS is expected to clear MtrrFixDramModEn bit, see for example + * "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD + * Opteron Processors" (26094 Rev. 3.30 February 2006), section + * "13.2.1.2 SYSCFG Register": "The MtrrFixDramModEn bit should be set + * to 1 during BIOS initalization of the fixed MTRRs, then cleared to + * 0 for operation." + */ +static inline void k8_check_syscfg_dram_mod_en(void) +{ + u32 lo, hi; + + if (!((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && + (boot_cpu_data.x86 >= 0x0f))) + return; + + rdmsr(MSR_K8_SYSCFG, lo, hi); + if (lo & K8_MTRRFIXRANGE_DRAM_MODIFY) { + printk(KERN_ERR FW_WARN "MTRR: CPU %u: SYSCFG[MtrrFixDramModEn]" + " not cleared by BIOS, clearing this bit\n", + smp_processor_id()); + lo &= ~K8_MTRRFIXRANGE_DRAM_MODIFY; + mtrr_wrmsr(MSR_K8_SYSCFG, lo, hi); + } +} + /* * Returns the effective MTRR type for the region * Error returns: @@ -178,6 +204,8 @@ unsigned int *p = (unsigned int *) frs; int i; + k8_check_syscfg_dram_mod_en(); + rdmsr(MTRRfix64K_00000_MSR, p[0], p[1]); for (i = 0; i < 2; i++) @@ -312,27 +340,10 @@ } /** - * Enable and allow read/write of extended fixed-range MTRR bits on K8 CPUs - * see AMD publication no. 24593, chapter 3.2.1 for more information - */ -static inline void k8_enable_fixed_iorrs(void) -{ - unsigned lo, hi; - - rdmsr(MSR_K8_SYSCFG, lo, hi); - mtrr_wrmsr(MSR_K8_SYSCFG, lo - | K8_MTRRFIXRANGE_DRAM_ENABLE - | K8_MTRRFIXRANGE_DRAM_MODIFY, hi); -} - -/** * set_fixed_range - checks & updates a fixed-range MTRR if it differs from the value it should have * @msr: MSR address of the MTTR which should be checked and updated * @changed: pointer which indicates whether the MTRR needed to be changed * @msrwords: pointer to the MSR values which the MSR should have - * - * If K8 extentions are wanted, update the K8 SYSCFG MSR also. - * See AMD publication no. 24593, chapter 7.8.1, page 233 for more information. */ static void set_fixed_range(int msr, bool *changed, unsigned int *msrwords) { @@ -341,10 +352,6 @@ rdmsr(msr, lo, hi); if (lo != msrwords[0] || hi != msrwords[1]) { - if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD && - (boot_cpu_data.x86 >= 0x0f && boot_cpu_data.x86 <= 0x11) && - ((msrwords[0] | msrwords[1]) & K8_MTRR_RDMEM_WRMEM_MASK)) - k8_enable_fixed_iorrs(); mtrr_wrmsr(msr, msrwords[0], msrwords[1]); *changed = true; } @@ -423,6 +430,8 @@ bool changed = false; int block=-1, range; + k8_check_syscfg_dram_mod_en(); + while (fixed_range_blocks[++block].ranges) for (range=0; range < fixed_range_blocks[block].ranges; range++) set_fixed_range(fixed_range_blocks[block].base_msr + range, --- linux-2.6.28.orig/arch/x86/kernel/cpu/mtrr/main.c +++ linux-2.6.28/arch/x86/kernel/cpu/mtrr/main.c @@ -1600,8 +1600,7 @@ /* kvm/qemu doesn't have mtrr set right, don't trim them all */ if (!highest_pfn) { - WARN(!kvm_para_available(), KERN_WARNING - "WARNING: strange, CPU MTRRs all blank?\n"); + printk(KERN_INFO "CPU MTRRs all blank - virtualized system.\n"); return 0; } --- linux-2.6.28.orig/arch/x86/oprofile/op_model_ppro.c +++ linux-2.6.28/arch/x86/oprofile/op_model_ppro.c @@ -78,8 +78,18 @@ if (cpu_has_arch_perfmon) { union cpuid10_eax eax; eax.full = cpuid_eax(0xa); - if (counter_width < eax.split.bit_width) - counter_width = eax.split.bit_width; + + /* + * For Core2 (family 6, model 15), don't reset the + * counter width: + */ + if (!(eax.split.version_id == 0 && + current_cpu_data.x86 == 6 && + current_cpu_data.x86_model == 15)) { + + if (counter_width < eax.split.bit_width) + counter_width = eax.split.bit_width; + } } /* clear all counters */ --- linux-2.6.28.orig/arch/x86/math-emu/fpu_system.h +++ linux-2.6.28/arch/x86/math-emu/fpu_system.h @@ -16,10 +16,6 @@ #include #include -/* This sets the pointer FPU_info to point to the argument part - of the stack frame of math_emulate() */ -#define SETUP_DATA_AREA(arg) FPU_info = (struct info *) &arg - /* s is always from a cpu register, and the cpu does bounds checking * during register load --> no further bounds checks needed */ #define LDT_DESCRIPTOR(s) (((struct desc_struct *)current->mm->context.ldt)[(s) >> 3]) @@ -38,12 +34,12 @@ #define I387 (current->thread.xstate) #define FPU_info (I387->soft.info) -#define FPU_CS (*(unsigned short *) &(FPU_info->___cs)) -#define FPU_SS (*(unsigned short *) &(FPU_info->___ss)) -#define FPU_DS (*(unsigned short *) &(FPU_info->___ds)) -#define FPU_EAX (FPU_info->___eax) -#define FPU_EFLAGS (FPU_info->___eflags) -#define FPU_EIP (FPU_info->___eip) +#define FPU_CS (*(unsigned short *) &(FPU_info->regs->cs)) +#define FPU_SS (*(unsigned short *) &(FPU_info->regs->ss)) +#define FPU_DS (*(unsigned short *) &(FPU_info->regs->ds)) +#define FPU_EAX (FPU_info->regs->ax) +#define FPU_EFLAGS (FPU_info->regs->flags) +#define FPU_EIP (FPU_info->regs->ip) #define FPU_ORIG_EIP (FPU_info->___orig_eip) #define FPU_lookahead (I387->soft.lookahead) --- linux-2.6.28.orig/arch/x86/math-emu/fpu_entry.c +++ linux-2.6.28/arch/x86/math-emu/fpu_entry.c @@ -131,7 +131,7 @@ static int valid_prefix(u_char *Byte, u_char __user ** fpu_eip, overrides * override); -asmlinkage void math_emulate(long arg) +void math_emulate(struct math_emu_info *info) { u_char FPU_modrm, byte1; unsigned short code; @@ -161,7 +161,7 @@ RE_ENTRANT_CHECK_ON; #endif /* RE_ENTRANT_CHECKING */ - SETUP_DATA_AREA(arg); + FPU_info = info; FPU_ORIG_EIP = FPU_EIP; @@ -659,7 +659,7 @@ } } -void math_abort(struct info *info, unsigned int signal) +void math_abort(struct math_emu_info *info, unsigned int signal) { FPU_EIP = FPU_ORIG_EIP; current->thread.trap_no = 16; --- linux-2.6.28.orig/arch/x86/math-emu/fpu_proto.h +++ linux-2.6.28/arch/x86/math-emu/fpu_proto.h @@ -51,8 +51,8 @@ extern void fst_i_(void); extern void fstp_i(void); /* fpu_entry.c */ -asmlinkage extern void math_emulate(long arg); -extern void math_abort(struct info *info, unsigned int signal); +extern void math_emulate(struct math_emu_info *info); +extern void math_abort(struct math_emu_info *info, unsigned int signal); /* fpu_etc.c */ extern void FPU_etc(void); /* fpu_tags.c */ --- linux-2.6.28.orig/arch/x86/math-emu/get_address.c +++ linux-2.6.28/arch/x86/math-emu/get_address.c @@ -29,46 +29,43 @@ #define FPU_WRITE_BIT 0x10 static int reg_offset[] = { - offsetof(struct info, ___eax), - offsetof(struct info, ___ecx), - offsetof(struct info, ___edx), - offsetof(struct info, ___ebx), - offsetof(struct info, ___esp), - offsetof(struct info, ___ebp), - offsetof(struct info, ___esi), - offsetof(struct info, ___edi) + offsetof(struct pt_regs, ax), + offsetof(struct pt_regs, cx), + offsetof(struct pt_regs, dx), + offsetof(struct pt_regs, bx), + offsetof(struct pt_regs, sp), + offsetof(struct pt_regs, bp), + offsetof(struct pt_regs, si), + offsetof(struct pt_regs, di) }; -#define REG_(x) (*(long *)(reg_offset[(x)]+(u_char *) FPU_info)) +#define REG_(x) (*(long *)(reg_offset[(x)] + (u_char *)FPU_info->regs)) static int reg_offset_vm86[] = { - offsetof(struct info, ___cs), - offsetof(struct info, ___vm86_ds), - offsetof(struct info, ___vm86_es), - offsetof(struct info, ___vm86_fs), - offsetof(struct info, ___vm86_gs), - offsetof(struct info, ___ss), - offsetof(struct info, ___vm86_ds) + offsetof(struct pt_regs, cs), + offsetof(struct kernel_vm86_regs, ds), + offsetof(struct kernel_vm86_regs, es), + offsetof(struct kernel_vm86_regs, fs), + offsetof(struct kernel_vm86_regs, gs), + offsetof(struct pt_regs, ss), + offsetof(struct kernel_vm86_regs, ds) }; #define VM86_REG_(x) (*(unsigned short *) \ - (reg_offset_vm86[((unsigned)x)]+(u_char *) FPU_info)) - -/* This dummy, gs is not saved on the stack. */ -#define ___GS ___ds + (reg_offset_vm86[((unsigned)x)] + (u_char *)FPU_info->regs)) static int reg_offset_pm[] = { - offsetof(struct info, ___cs), - offsetof(struct info, ___ds), - offsetof(struct info, ___es), - offsetof(struct info, ___fs), - offsetof(struct info, ___GS), - offsetof(struct info, ___ss), - offsetof(struct info, ___ds) + offsetof(struct pt_regs, cs), + offsetof(struct pt_regs, ds), + offsetof(struct pt_regs, es), + offsetof(struct pt_regs, fs), + offsetof(struct pt_regs, ds), /* dummy, not saved on stack */ + offsetof(struct pt_regs, ss), + offsetof(struct pt_regs, ds) }; #define PM_REG_(x) (*(unsigned short *) \ - (reg_offset_pm[((unsigned)x)]+(u_char *) FPU_info)) + (reg_offset_pm[((unsigned)x)] + (u_char *)FPU_info->regs)) /* Decode the SIB byte. This function assumes mod != 0 */ static int sib(int mod, unsigned long *fpu_eip) @@ -349,34 +346,34 @@ } switch (rm) { case 0: - address += FPU_info->___ebx + FPU_info->___esi; + address += FPU_info->regs->bx + FPU_info->regs->si; break; case 1: - address += FPU_info->___ebx + FPU_info->___edi; + address += FPU_info->regs->bx + FPU_info->regs->di; break; case 2: - address += FPU_info->___ebp + FPU_info->___esi; + address += FPU_info->regs->bp + FPU_info->regs->si; if (addr_modes.override.segment == PREFIX_DEFAULT) addr_modes.override.segment = PREFIX_SS_; break; case 3: - address += FPU_info->___ebp + FPU_info->___edi; + address += FPU_info->regs->bp + FPU_info->regs->di; if (addr_modes.override.segment == PREFIX_DEFAULT) addr_modes.override.segment = PREFIX_SS_; break; case 4: - address += FPU_info->___esi; + address += FPU_info->regs->si; break; case 5: - address += FPU_info->___edi; + address += FPU_info->regs->di; break; case 6: - address += FPU_info->___ebp; + address += FPU_info->regs->bp; if (addr_modes.override.segment == PREFIX_DEFAULT) addr_modes.override.segment = PREFIX_SS_; break; case 7: - address += FPU_info->___ebx; + address += FPU_info->regs->bx; break; } --- linux-2.6.28.orig/arch/m68k/kernel/entry.S +++ linux-2.6.28/arch/m68k/kernel/entry.S @@ -513,7 +513,7 @@ .long sys_uselib .long sys_swapon .long sys_reboot - .long old_readdir + .long sys_old_readdir .long old_mmap /* 90 */ .long sys_munmap .long sys_truncate --- linux-2.6.28.orig/arch/m68knommu/Kconfig +++ linux-2.6.28/arch/m68knommu/Kconfig @@ -14,6 +14,10 @@ bool default n +config NO_DMA + bool + default y + config FPU bool default n --- linux-2.6.28.orig/arch/m68knommu/kernel/syscalltable.S +++ linux-2.6.28/arch/m68knommu/kernel/syscalltable.S @@ -107,7 +107,7 @@ .long sys_uselib .long sys_ni_syscall /* sys_swapon */ .long sys_reboot - .long old_readdir + .long sys_old_readdir .long old_mmap /* 90 */ .long sys_munmap .long sys_truncate --- linux-2.6.28.orig/arch/powerpc/Kconfig +++ linux-2.6.28/arch/powerpc/Kconfig @@ -121,6 +121,7 @@ select HAVE_DMA_ATTRS if PPC64 select USE_GENERIC_SMP_HELPERS if SMP select HAVE_OPROFILE + select HAVE_SYSCALL_WRAPPERS if PPC64 config EARLY_PRINTK bool --- linux-2.6.28.orig/arch/powerpc/mm/pgtable_32.c +++ linux-2.6.28/arch/powerpc/mm/pgtable_32.c @@ -65,8 +65,8 @@ #ifdef HAVE_TLBCAM extern unsigned int tlbcam_index; -extern unsigned long v_mapped_by_tlbcam(unsigned long va); -extern unsigned long p_mapped_by_tlbcam(unsigned long pa); +extern phys_addr_t v_mapped_by_tlbcam(unsigned long va); +extern unsigned long p_mapped_by_tlbcam(phys_addr_t pa); #else /* !HAVE_TLBCAM */ #define v_mapped_by_tlbcam(x) (0UL) #define p_mapped_by_tlbcam(x) (0UL) --- linux-2.6.28.orig/arch/powerpc/mm/slice.c +++ linux-2.6.28/arch/powerpc/mm/slice.c @@ -710,9 +710,18 @@ unsigned long len) { struct slice_mask mask, available; + unsigned int psize = mm->context.user_psize; mask = slice_range_to_mask(addr, len); - available = slice_mask_for_size(mm, mm->context.user_psize); + available = slice_mask_for_size(mm, psize); +#ifdef CONFIG_PPC_64K_PAGES + /* We need to account for 4k slices too */ + if (psize == MMU_PAGE_64K) { + struct slice_mask compat_mask; + compat_mask = slice_mask_for_size(mm, MMU_PAGE_4K); + or_mask(available, compat_mask); + } +#endif #if 0 /* too verbose */ slice_dbg("is_hugepage_only_range(mm=%p, addr=%lx, len=%lx)\n", --- linux-2.6.28.orig/arch/powerpc/mm/fsl_booke_mmu.c +++ linux-2.6.28/arch/powerpc/mm/fsl_booke_mmu.c @@ -80,7 +80,7 @@ /* * Return PA for this VA if it is mapped by a CAM, or 0 */ -unsigned long v_mapped_by_tlbcam(unsigned long va) +phys_addr_t v_mapped_by_tlbcam(unsigned long va) { int b; for (b = 0; b < tlbcam_index; ++b) @@ -92,7 +92,7 @@ /* * Return VA for a given PA or 0 if not mapped */ -unsigned long p_mapped_by_tlbcam(unsigned long pa) +unsigned long p_mapped_by_tlbcam(phys_addr_t pa) { int b; for (b = 0; b < tlbcam_index; ++b) --- linux-2.6.28.orig/arch/powerpc/include/asm/systbl.h +++ linux-2.6.28/arch/powerpc/include/asm/systbl.h @@ -92,7 +92,7 @@ SYSCALL(uselib) SYSCALL(swapon) SYSCALL(reboot) -SYSX(sys_ni_syscall,compat_sys_old_readdir,old_readdir) +SYSX(sys_ni_syscall,compat_sys_old_readdir,sys_old_readdir) SYSCALL_SPU(mmap) SYSCALL_SPU(munmap) SYSCALL_SPU(truncate) --- linux-2.6.28.orig/arch/powerpc/include/asm/compat.h +++ linux-2.6.28/arch/powerpc/include/asm/compat.h @@ -210,5 +210,10 @@ compat_ulong_t __unused6; }; +static inline int is_compat_task(void) +{ + return test_thread_flag(TIF_32BIT); +} + #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_COMPAT_H */ --- linux-2.6.28.orig/arch/powerpc/include/asm/seccomp.h +++ linux-2.6.28/arch/powerpc/include/asm/seccomp.h @@ -1,10 +1,6 @@ #ifndef _ASM_POWERPC_SECCOMP_H #define _ASM_POWERPC_SECCOMP_H -#ifdef __KERNEL__ -#include -#endif - #include #define __NR_seccomp_read __NR_read --- linux-2.6.28.orig/arch/powerpc/sysdev/fsl_soc.c +++ linux-2.6.28/arch/powerpc/sysdev/fsl_soc.c @@ -257,7 +257,7 @@ gfar_mdio_of_init_one(np); /* try the deprecated version */ - for_each_compatible_node(np, "mdio", "gianfar"); + for_each_compatible_node(np, "mdio", "gianfar") gfar_mdio_of_init_one(np); return 0; --- linux-2.6.28.orig/arch/powerpc/platforms/pseries/Kconfig +++ linux-2.6.28/arch/powerpc/platforms/pseries/Kconfig @@ -54,7 +54,7 @@ config CMM tristate "Collaborative memory management" - depends on PPC_SMLPAR + depends on PPC_SMLPAR && !CRASH_DUMP default y help Select this option, if you want to enable the kernel interface --- linux-2.6.28.orig/arch/powerpc/kernel/align.c +++ linux-2.6.28/arch/powerpc/kernel/align.c @@ -367,27 +367,24 @@ 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; + char *ptr0 = (char *) ¤t->thread.TS_FPR(reg); + char *ptr1 = (char *) ¤t->thread.TS_FPR(reg+1); + int i, ret, sw = 0; if (!(flags & F)) return 0; if (reg & 1) return 0; /* invalid form: FRS/FRT must be even */ - if (!(flags & SW)) { - /* not byte-swapped - easy */ - if (!(flags & ST)) - ret = __copy_from_user(ptr, addr, 16); - else - ret = __copy_to_user(addr, ptr, 16); - } else { - /* each FPR value is byte-swapped separately */ - ret = 0; - for (i = 0; i < 16; ++i) { - if (!(flags & ST)) - ret |= __get_user(ptr[i^7], addr + i); - else - ret |= __put_user(ptr[i^7], addr + i); + if (flags & SW) + sw = 7; + ret = 0; + for (i = 0; i < 8; ++i) { + if (!(flags & ST)) { + ret |= __get_user(ptr0[i^sw], addr + i); + ret |= __get_user(ptr1[i^sw], addr + i + 8); + } else { + ret |= __put_user(ptr0[i^sw], addr + i); + ret |= __put_user(ptr1[i^sw], addr + i + 8); } } if (ret) @@ -646,11 +643,16 @@ unsigned int areg, struct pt_regs *regs, unsigned int flags, unsigned int length) { - char *ptr = (char *) ¤t->thread.TS_FPR(reg); + char *ptr; int ret = 0; flush_vsx_to_thread(current); + if (reg < 32) + ptr = (char *) ¤t->thread.TS_FPR(reg); + else + ptr = (char *) ¤t->thread.vr[reg - 32]; + if (flags & ST) ret = __copy_to_user(addr, ptr, length); else { --- linux-2.6.28.orig/mm/mempolicy.c +++ linux-2.6.28/mm/mempolicy.c @@ -1068,10 +1068,9 @@ return copy_to_user(mask, nodes_addr(*nodes), copy) ? -EFAULT : 0; } -asmlinkage long sys_mbind(unsigned long start, unsigned long len, - unsigned long mode, - unsigned long __user *nmask, unsigned long maxnode, - unsigned flags) +SYSCALL_DEFINE6(mbind, unsigned long, start, unsigned long, len, + unsigned long, mode, unsigned long __user *, nmask, + unsigned long, maxnode, unsigned, flags) { nodemask_t nodes; int err; @@ -1091,8 +1090,8 @@ } /* Set the process memory policy */ -asmlinkage long sys_set_mempolicy(int mode, unsigned long __user *nmask, - unsigned long maxnode) +SYSCALL_DEFINE3(set_mempolicy, int, mode, unsigned long __user *, nmask, + unsigned long, maxnode) { int err; nodemask_t nodes; @@ -1110,9 +1109,9 @@ return do_set_mempolicy(mode, flags, &nodes); } -asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode, - const unsigned long __user *old_nodes, - const unsigned long __user *new_nodes) +SYSCALL_DEFINE4(migrate_pages, pid_t, pid, unsigned long, maxnode, + const unsigned long __user *, old_nodes, + const unsigned long __user *, new_nodes) { struct mm_struct *mm; struct task_struct *task; @@ -1180,10 +1179,9 @@ /* Retrieve NUMA policy */ -asmlinkage long sys_get_mempolicy(int __user *policy, - unsigned long __user *nmask, - unsigned long maxnode, - unsigned long addr, unsigned long flags) +SYSCALL_DEFINE5(get_mempolicy, int __user *, policy, + unsigned long __user *, nmask, unsigned long, maxnode, + unsigned long, addr, unsigned long, flags) { int err; int uninitialized_var(pval); --- linux-2.6.28.orig/mm/filemap.c +++ linux-2.6.28/mm/filemap.c @@ -210,7 +210,7 @@ int ret; struct writeback_control wbc = { .sync_mode = sync_mode, - .nr_to_write = mapping->nrpages * 2, + .nr_to_write = LONG_MAX, .range_start = start, .range_end = end, }; @@ -1317,7 +1317,8 @@ goto out; /* skip atime */ size = i_size_read(inode); if (pos < size) { - retval = filemap_write_and_wait(mapping); + retval = filemap_write_and_wait_range(mapping, pos, + pos + iov_length(iov, nr_segs) - 1); if (!retval) { retval = mapping->a_ops->direct_IO(READ, iocb, iov, pos, nr_segs); @@ -1366,7 +1367,7 @@ return 0; } -asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count) +SYSCALL_DEFINE(readahead)(int fd, loff_t offset, size_t count) { ssize_t ret; struct file *file; @@ -1385,6 +1386,13 @@ } return ret; } +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_readahead(long fd, loff_t offset, long count) +{ + return SYSC_readahead((int) fd, offset, (size_t) count); +} +SYSCALL_ALIAS(sys_readahead, SyS_readahead); +#endif #ifdef CONFIG_MMU /** @@ -1773,12 +1781,12 @@ } EXPORT_SYMBOL(should_remove_suid); -static int __remove_suid(struct dentry *dentry, int kill) +static int __remove_suid(struct path *path, int kill) { struct iattr newattrs; newattrs.ia_valid = ATTR_FORCE | kill; - return notify_change(dentry, &newattrs); + return notify_change(path->dentry, path->mnt, &newattrs); } int file_remove_suid(struct file *file) @@ -1793,7 +1801,7 @@ if (killpriv) error = security_inode_killpriv(dentry); if (!error && killsuid) - error = __remove_suid(dentry, killsuid); + error = __remove_suid(&file->f_path, killsuid); return error; } @@ -2060,18 +2068,10 @@ if (count != ocount) *nr_segs = iov_shorten((struct iovec *)iov, *nr_segs, count); - /* - * Unmap all mmappings of the file up-front. - * - * This will cause any pte dirty bits to be propagated into the - * pageframes for the subsequent filemap_write_and_wait(). - */ write_len = iov_length(iov, *nr_segs); end = (pos + write_len - 1) >> PAGE_CACHE_SHIFT; - if (mapping_mapped(mapping)) - unmap_mapping_range(mapping, pos, write_len, 0); - written = filemap_write_and_wait(mapping); + written = filemap_write_and_wait_range(mapping, pos, pos + write_len - 1); if (written) goto out; @@ -2140,19 +2140,24 @@ * Find or create a page at the given pagecache position. Return the locked * page. This function is specifically for buffered writes. */ -struct page *__grab_cache_page(struct address_space *mapping, pgoff_t index) +struct page *grab_cache_page_write_begin(struct address_space *mapping, + pgoff_t index, unsigned flags) { int status; struct page *page; + gfp_t gfp_notmask = 0; + if (flags & AOP_FLAG_NOFS) + gfp_notmask = __GFP_FS; repeat: page = find_lock_page(mapping, index); if (likely(page)) return page; - page = page_cache_alloc(mapping); + page = __page_cache_alloc(mapping_gfp_mask(mapping) & ~gfp_notmask); if (!page) return NULL; - status = add_to_page_cache_lru(page, mapping, index, GFP_KERNEL); + status = add_to_page_cache_lru(page, mapping, index, + GFP_KERNEL & ~gfp_notmask); if (unlikely(status)) { page_cache_release(page); if (status == -EEXIST) @@ -2161,7 +2166,7 @@ } return page; } -EXPORT_SYMBOL(__grab_cache_page); +EXPORT_SYMBOL(grab_cache_page_write_begin); static ssize_t generic_perform_write(struct file *file, struct iov_iter *i, loff_t pos) @@ -2286,7 +2291,8 @@ * the file data here, to try to honour O_DIRECT expectations. */ if (unlikely(file->f_flags & O_DIRECT) && written) - status = filemap_write_and_wait(mapping); + status = filemap_write_and_wait_range(mapping, + pos, pos + written - 1); return written ? written : status; } --- linux-2.6.28.orig/mm/page-writeback.c +++ linux-2.6.28/mm/page-writeback.c @@ -868,9 +868,11 @@ int done = 0; struct pagevec pvec; int nr_pages; + pgoff_t uninitialized_var(writeback_index); pgoff_t index; pgoff_t end; /* Inclusive */ - int scanned = 0; + pgoff_t done_index; + int cycled; int range_whole = 0; long nr_to_write = wbc->nr_to_write; @@ -881,83 +883,146 @@ pagevec_init(&pvec, 0); if (wbc->range_cyclic) { - index = mapping->writeback_index; /* Start from prev offset */ + writeback_index = mapping->writeback_index; /* prev offset */ + index = writeback_index; + if (index == 0) + cycled = 1; + else + cycled = 0; end = -1; } else { index = wbc->range_start >> PAGE_CACHE_SHIFT; end = wbc->range_end >> PAGE_CACHE_SHIFT; if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) range_whole = 1; - scanned = 1; + cycled = 1; /* ignore range_cyclic tests */ } retry: - while (!done && (index <= end) && - (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, - PAGECACHE_TAG_DIRTY, - min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1))) { - unsigned i; + done_index = index; + while (!done && (index <= end)) { + int i; + + nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, + PAGECACHE_TAG_DIRTY, + min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1); + if (nr_pages == 0) + break; - scanned = 1; for (i = 0; i < nr_pages; i++) { struct page *page = pvec.pages[i]; /* - * At this point we hold neither mapping->tree_lock nor - * lock on the page itself: the page may be truncated or - * invalidated (changing page->mapping to NULL), or even - * swizzled back from swapper_space to tmpfs file - * mapping + * At this point, the page may be truncated or + * invalidated (changing page->mapping to NULL), or + * even swizzled back from swapper_space to tmpfs file + * mapping. However, page->index will not change + * because we have a reference on the page. */ + if (page->index > end) { + /* + * can't be range_cyclic (1st pass) because + * end == -1 in that case. + */ + done = 1; + break; + } + + done_index = page->index + 1; + lock_page(page); + /* + * Page truncated or invalidated. We can freely skip it + * then, even for data integrity operations: the page + * has disappeared concurrently, so there could be no + * real expectation of this data interity operation + * even if there is now a new, dirty page at the same + * pagecache address. + */ if (unlikely(page->mapping != mapping)) { +continue_unlock: unlock_page(page); continue; } - if (!wbc->range_cyclic && page->index > end) { - done = 1; - unlock_page(page); - continue; + if (!PageDirty(page)) { + /* someone wrote it for us */ + goto continue_unlock; } - if (wbc->sync_mode != WB_SYNC_NONE) - wait_on_page_writeback(page); - - if (PageWriteback(page) || - !clear_page_dirty_for_io(page)) { - unlock_page(page); - continue; + if (PageWriteback(page)) { + if (wbc->sync_mode != WB_SYNC_NONE) + wait_on_page_writeback(page); + else + goto continue_unlock; } - ret = (*writepage)(page, wbc, data); + BUG_ON(PageWriteback(page)); + if (!clear_page_dirty_for_io(page)) + goto continue_unlock; - if (unlikely(ret == AOP_WRITEPAGE_ACTIVATE)) { - unlock_page(page); - ret = 0; + ret = (*writepage)(page, wbc, data); + if (unlikely(ret)) { + if (ret == AOP_WRITEPAGE_ACTIVATE) { + unlock_page(page); + ret = 0; + } else { + /* + * done_index is set past this page, + * so media errors will not choke + * background writeout for the entire + * file. This has consequences for + * range_cyclic semantics (ie. it may + * not be suitable for data integrity + * writeout). + */ + done = 1; + break; + } + } + + if (nr_to_write > 0) { + nr_to_write--; + if (nr_to_write == 0 && + wbc->sync_mode == WB_SYNC_NONE) { + /* + * We stop writing back only if we are + * not doing integrity sync. In case of + * integrity sync we have to keep going + * because someone may be concurrently + * dirtying pages, and we might have + * synced a lot of newly appeared dirty + * pages, but have not synced all of the + * old dirty pages. + */ + done = 1; + break; + } } - if (ret || (--nr_to_write <= 0)) - done = 1; + if (wbc->nonblocking && bdi_write_congested(bdi)) { wbc->encountered_congestion = 1; done = 1; + break; } } pagevec_release(&pvec); cond_resched(); } - if (!scanned && !done) { + if (!cycled && !done) { /* + * range_cyclic: * We hit the last page and there is more work to be done: wrap * back to the start of the file */ - scanned = 1; + cycled = 1; index = 0; + end = writeback_index - 1; goto retry; } if (!wbc->no_nrwrite_index_update) { if (wbc->range_cyclic || (range_whole && nr_to_write > 0)) - mapping->writeback_index = index; + mapping->writeback_index = done_index; wbc->nr_to_write = nr_to_write; } --- linux-2.6.28.orig/mm/madvise.c +++ linux-2.6.28/mm/madvise.c @@ -281,7 +281,7 @@ * -EBADF - map exists, but area maps something that isn't a file. * -EAGAIN - a kernel resource was temporarily unavailable. */ -asmlinkage long sys_madvise(unsigned long start, size_t len_in, int behavior) +SYSCALL_DEFINE3(madvise, unsigned long, start, size_t, len_in, int, behavior) { unsigned long end, tmp; struct vm_area_struct * vma, *prev; --- linux-2.6.28.orig/mm/fremap.c +++ linux-2.6.28/mm/fremap.c @@ -120,8 +120,8 @@ * and the vma's default protection is used. Arbitrary protections * might be implemented in the future. */ -asmlinkage long sys_remap_file_pages(unsigned long start, unsigned long size, - unsigned long prot, unsigned long pgoff, unsigned long flags) +SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, + unsigned long, prot, unsigned long, pgoff, unsigned long, flags) { struct mm_struct *mm = current->mm; struct address_space *mapping; --- linux-2.6.28.orig/mm/mprotect.c +++ linux-2.6.28/mm/mprotect.c @@ -219,8 +219,8 @@ return error; } -asmlinkage long -sys_mprotect(unsigned long start, size_t len, unsigned long prot) +SYSCALL_DEFINE3(mprotect, unsigned long, start, size_t, len, + unsigned long, prot) { unsigned long vm_flags, nstart, end, tmp, reqprot; struct vm_area_struct *vma, *prev; --- linux-2.6.28.orig/mm/mlock.c +++ linux-2.6.28/mm/mlock.c @@ -293,14 +293,10 @@ * * return number of pages [> 0] to be removed from locked_vm on success * of "special" vmas. - * - * return negative error if vma spanning @start-@range disappears while - * mmap semaphore is dropped. Unlikely? */ long mlock_vma_pages_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { - struct mm_struct *mm = vma->vm_mm; int nr_pages = (end - start) / PAGE_SIZE; BUG_ON(!(vma->vm_flags & VM_LOCKED)); @@ -313,20 +309,11 @@ if (!((vma->vm_flags & (VM_DONTEXPAND | VM_RESERVED)) || is_vm_hugetlb_page(vma) || vma == get_gate_vma(current))) { - long error; - downgrade_write(&mm->mmap_sem); - - error = __mlock_vma_pages_range(vma, start, end, 1); - up_read(&mm->mmap_sem); - /* vma can change or disappear */ - down_write(&mm->mmap_sem); - vma = find_vma(mm, start); - /* non-NULL vma must contain @start, but need to check @end */ - if (!vma || end > vma->vm_end) - return -ENOMEM; + __mlock_vma_pages_range(vma, start, end, 1); - return 0; /* hide other errors from mmap(), et al */ + /* Hide errors from mmap() and other callers */ + return 0; } /* @@ -437,41 +424,14 @@ vma->vm_flags = newflags; if (lock) { - /* - * mmap_sem is currently held for write. Downgrade the write - * lock to a read lock so that other faults, mmap scans, ... - * while we fault in all pages. - */ - downgrade_write(&mm->mmap_sem); - ret = __mlock_vma_pages_range(vma, start, end, 1); - /* - * Need to reacquire mmap sem in write mode, as our callers - * expect this. We have no support for atomically upgrading - * a sem to write, so we need to check for ranges while sem - * is unlocked. - */ - up_read(&mm->mmap_sem); - /* vma can change or disappear */ - down_write(&mm->mmap_sem); - *prev = find_vma(mm, start); - /* non-NULL *prev must contain @start, but need to check @end */ - if (!(*prev) || end > (*prev)->vm_end) - ret = -ENOMEM; - else if (ret > 0) { + if (ret > 0) { mm->locked_vm -= ret; ret = 0; } else ret = __mlock_posix_error_return(ret); /* translate if needed */ } else { - /* - * TODO: for unlocking, pages will already be resident, so - * we don't need to wait for allocations/reclaim/pagein, ... - * However, unlocking a very large region can still take a - * while. Should we downgrade the semaphore for both lock - * AND unlock ? - */ __mlock_vma_pages_range(vma, start, end, 0); } @@ -529,7 +489,7 @@ return error; } -asmlinkage long sys_mlock(unsigned long start, size_t len) +SYSCALL_DEFINE2(mlock, unsigned long, start, size_t, len) { unsigned long locked; unsigned long lock_limit; @@ -557,7 +517,7 @@ return error; } -asmlinkage long sys_munlock(unsigned long start, size_t len) +SYSCALL_DEFINE2(munlock, unsigned long, start, size_t, len) { int ret; @@ -594,7 +554,7 @@ return 0; } -asmlinkage long sys_mlockall(int flags) +SYSCALL_DEFINE1(mlockall, int, flags) { unsigned long lock_limit; int ret = -EINVAL; @@ -622,7 +582,7 @@ return ret; } -asmlinkage long sys_munlockall(void) +SYSCALL_DEFINE0(munlockall) { int ret; --- linux-2.6.28.orig/mm/fadvise.c +++ linux-2.6.28/mm/fadvise.c @@ -24,7 +24,7 @@ * POSIX_FADV_WILLNEED could set PG_Referenced, and POSIX_FADV_NOREUSE could * deactivate the pages and clear PG_Referenced. */ -asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice) +SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice) { struct file *file = fget(fd); struct address_space *mapping; @@ -126,12 +126,26 @@ fput(file); return ret; } +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_fadvise64_64(long fd, loff_t offset, loff_t len, long advice) +{ + return SYSC_fadvise64_64((int) fd, offset, len, (int) advice); +} +SYSCALL_ALIAS(sys_fadvise64_64, SyS_fadvise64_64); +#endif #ifdef __ARCH_WANT_SYS_FADVISE64 -asmlinkage long sys_fadvise64(int fd, loff_t offset, size_t len, int advice) +SYSCALL_DEFINE(fadvise64)(int fd, loff_t offset, size_t len, int advice) { return sys_fadvise64_64(fd, offset, len, advice); } +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_fadvise64(long fd, loff_t offset, long len, long advice) +{ + return SYSC_fadvise64((int) fd, offset, (size_t)len, (int)advice); +} +SYSCALL_ALIAS(sys_fadvise64, SyS_fadvise64); +#endif #endif --- linux-2.6.28.orig/mm/nommu.c +++ linux-2.6.28/mm/nommu.c @@ -377,7 +377,7 @@ * to a regular file. in this case, the unmapping will need * to invoke file system routines that need the global lock. */ -asmlinkage unsigned long sys_brk(unsigned long brk) +SYSCALL_DEFINE1(brk, unsigned long, brk) { struct mm_struct *mm = current->mm; @@ -1192,7 +1192,7 @@ } EXPORT_SYMBOL(do_munmap); -asmlinkage long sys_munmap(unsigned long addr, size_t len) +SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) { int ret; struct mm_struct *mm = current->mm; @@ -1283,9 +1283,9 @@ } EXPORT_SYMBOL(do_mremap); -asmlinkage unsigned long sys_mremap(unsigned long addr, - unsigned long old_len, unsigned long new_len, - unsigned long flags, unsigned long new_addr) +SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len, + unsigned long, new_len, unsigned long, flags, + unsigned long, new_addr) { unsigned long ret; --- linux-2.6.28.orig/mm/swapfile.c +++ linux-2.6.28/mm/swapfile.c @@ -286,6 +286,8 @@ swap_list.next = p - swap_info; nr_swap_pages++; p->inuse_pages--; + if (p->notify_swap_entry_free_fn) + p->notify_swap_entry_free_fn(offset); } } return count; @@ -1223,7 +1225,7 @@ } #endif -asmlinkage long sys_swapoff(const char __user * specialfile) +SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) { struct swap_info_struct * p = NULL; unsigned short *swap_map; @@ -1467,7 +1469,7 @@ * * The swapon system call */ -asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags) +SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) { struct swap_info_struct * p; char *name = NULL; @@ -1818,6 +1820,23 @@ } /* + * Sets callback for event when swap_map[offset] == 0 + * i.e. page at this swap offset is not longer used. + * + * type: identifies swap file + * fn: callback function + */ +void set_notify_swap_entry_free(unsigned type, void (*fn) (unsigned long)) +{ + struct swap_info_struct *sis; + sis = get_swap_info_struct(type); + BUG_ON(!sis); + sis->notify_swap_entry_free_fn = fn; + return; +} +EXPORT_SYMBOL(set_notify_swap_entry_free); + +/* * swap_lock prevents swap_map being freed. Don't grab an extra * reference on the swaphandle, it doesn't matter if it becomes unused. */ --- linux-2.6.28.orig/mm/mincore.c +++ linux-2.6.28/mm/mincore.c @@ -177,8 +177,8 @@ * mapped * -EAGAIN - A kernel resource was temporarily unavailable. */ -asmlinkage long sys_mincore(unsigned long start, size_t len, - unsigned char __user * vec) +SYSCALL_DEFINE3(mincore, unsigned long, start, size_t, len, + unsigned char __user *, vec) { long retval; unsigned long pages; --- linux-2.6.28.orig/mm/migrate.c +++ linux-2.6.28/mm/migrate.c @@ -1070,10 +1070,10 @@ * Move a list of pages in the address space of the currently executing * process. */ -asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages, - const void __user * __user *pages, - const int __user *nodes, - int __user *status, int flags) +SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages, + const void __user * __user *, pages, + const int __user *, nodes, + int __user *, status, int, flags) { struct task_struct *task; struct mm_struct *mm; --- linux-2.6.28.orig/mm/mmap.c +++ linux-2.6.28/mm/mmap.c @@ -245,7 +245,7 @@ return next; } -asmlinkage unsigned long sys_brk(unsigned long brk) +SYSCALL_DEFINE1(brk, unsigned long, brk) { unsigned long rlim, retval; unsigned long newbrk, oldbrk; @@ -1095,6 +1095,7 @@ { struct mm_struct *mm = current->mm; struct vm_area_struct *vma, *prev; + struct vm_area_struct *merged_vma; int correct_wcount = 0; int error; struct rb_node **rb_link, *rb_parent; @@ -1207,13 +1208,17 @@ if (vma_wants_writenotify(vma)) vma->vm_page_prot = vm_get_page_prot(vm_flags & ~VM_SHARED); - if (file && vma_merge(mm, prev, addr, vma->vm_end, - vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) { + merged_vma = NULL; + if (file) + merged_vma = vma_merge(mm, prev, addr, vma->vm_end, + vma->vm_flags, NULL, file, pgoff, vma_policy(vma)); + if (merged_vma) { mpol_put(vma_policy(vma)); kmem_cache_free(vm_area_cachep, vma); fput(file); if (vm_flags & VM_EXECUTABLE) removed_exe_file_vma(mm); + vma = merged_vma; } else { vma_link(mm, vma, prev, rb_link, rb_parent); file = vma->vm_file; @@ -1949,7 +1954,7 @@ EXPORT_SYMBOL(do_munmap); -asmlinkage long sys_munmap(unsigned long addr, size_t len) +SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) { int ret; struct mm_struct *mm = current->mm; @@ -2088,7 +2093,6 @@ unsigned long end; /* mm's last user has gone, and its about to be pulled down */ - arch_exit_mmap(mm); mmu_notifier_release(mm); if (mm->locked_vm) { @@ -2099,7 +2103,13 @@ vma = vma->vm_next; } } + + arch_exit_mmap(mm); + vma = mm->mmap; + if (!vma) /* Can happen if dup_mmap() received an OOM */ + return; + lru_add_drain(); flush_cache_mm(mm); tlb = tlb_gather_mmu(mm, 1); --- linux-2.6.28.orig/mm/page_alloc.c +++ linux-2.6.28/mm/page_alloc.c @@ -2974,7 +2974,7 @@ * was used and there are no special requirements, this is a convenient * alternative */ -int __meminit early_pfn_to_nid(unsigned long pfn) +int __meminit __early_pfn_to_nid(unsigned long pfn) { int i; @@ -2985,10 +2985,33 @@ if (start_pfn <= pfn && pfn < end_pfn) return early_node_map[i].nid; } + /* This is a memory hole */ + return -1; +} +#endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */ + +int __meminit early_pfn_to_nid(unsigned long pfn) +{ + int nid; + nid = __early_pfn_to_nid(pfn); + if (nid >= 0) + return nid; + /* just returns 0 */ return 0; } -#endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */ + +#ifdef CONFIG_NODES_SPAN_OTHER_NODES +bool __meminit early_pfn_in_nid(unsigned long pfn, int node) +{ + int nid; + + nid = __early_pfn_to_nid(pfn); + if (nid >= 0 && nid != node) + return false; + return true; +} +#endif /* Basic iterator support to walk early_node_map[] */ #define for_each_active_range_index_in_nid(i, nid) \ --- linux-2.6.28.orig/mm/mremap.c +++ linux-2.6.28/mm/mremap.c @@ -420,9 +420,9 @@ return ret; } -asmlinkage unsigned long sys_mremap(unsigned long addr, - unsigned long old_len, unsigned long new_len, - unsigned long flags, unsigned long new_addr) +SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len, + unsigned long, new_len, unsigned long, flags, + unsigned long, new_addr) { unsigned long ret; --- linux-2.6.28.orig/mm/msync.c +++ linux-2.6.28/mm/msync.c @@ -28,7 +28,7 @@ * So by _not_ starting I/O in MS_ASYNC we provide complete flexibility to * applications. */ -asmlinkage long sys_msync(unsigned long start, size_t len, int flags) +SYSCALL_DEFINE3(msync, unsigned long, start, size_t, len, int, flags) { unsigned long end; struct mm_struct *mm = current->mm; --- linux-2.6.28.orig/mm/memory.c +++ linux-2.6.28/mm/memory.c @@ -1881,7 +1881,7 @@ * Don't let another task, with possibly unlocked vma, * keep the mlocked page. */ - if (vma->vm_flags & VM_LOCKED) { + if ((vma->vm_flags & VM_LOCKED) && old_page) { lock_page(old_page); /* for LRU manipulation */ clear_page_mlock(old_page); unlock_page(old_page); --- linux-2.6.28.orig/mm/vmalloc.c +++ linux-2.6.28/mm/vmalloc.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -151,11 +152,12 @@ * * Ie. pte at addr+N*PAGE_SIZE shall point to pfn corresponding to pages[N] */ -static int vmap_page_range(unsigned long addr, unsigned long end, +static int vmap_page_range(unsigned long start, unsigned long end, pgprot_t prot, struct page **pages) { pgd_t *pgd; unsigned long next; + unsigned long addr = start; int err = 0; int nr = 0; @@ -167,7 +169,7 @@ if (err) break; } while (pgd++, addr = next, addr != end); - flush_cache_vmap(addr, end); + flush_cache_vmap(start, end); if (unlikely(err)) return err; @@ -321,6 +323,7 @@ unsigned long addr; int purged = 0; + BUG_ON(!size); BUG_ON(size & ~PAGE_MASK); va = kmalloc_node(sizeof(struct vmap_area), @@ -332,6 +335,9 @@ addr = ALIGN(vstart, align); spin_lock(&vmap_area_lock); + if (addr + size - 1 < addr) + goto overflow; + /* XXX: could have a last_hole cache */ n = vmap_area_root.rb_node; if (n) { @@ -363,6 +369,8 @@ while (addr + size > first->va_start && addr + size <= vend) { addr = ALIGN(first->va_end + PAGE_SIZE, align); + if (addr + size - 1 < addr) + goto overflow; n = rb_next(&first->rb_node); if (n) @@ -373,6 +381,7 @@ } found: if (addr + size > vend) { +overflow: spin_unlock(&vmap_area_lock); if (!purged) { purge_vmap_area_lazy(); @@ -474,6 +483,7 @@ static DEFINE_SPINLOCK(purge_lock); LIST_HEAD(valist); struct vmap_area *va; + struct vmap_area *n_va; int nr = 0; /* @@ -513,7 +523,7 @@ if (nr) { spin_lock(&vmap_area_lock); - list_for_each_entry(va, &valist, purge_list) + list_for_each_entry_safe(va, n_va, &valist, purge_list) __free_vmap_area(va); spin_unlock(&vmap_area_lock); } @@ -959,6 +969,8 @@ void __init vmalloc_init(void) { + struct vmap_area *va; + struct vm_struct *tmp; int i; for_each_possible_cpu(i) { @@ -971,12 +983,22 @@ vbq->nr_dirty = 0; } + /* Import existing vmlist entries. */ + for (tmp = vmlist; tmp; tmp = tmp->next) { + va = alloc_bootmem(sizeof(struct vmap_area)); + va->flags = tmp->flags | VM_VM_AREA; + va->va_start = (unsigned long)tmp->addr; + va->va_end = va->va_start + tmp->size; + __insert_vmap_area(va); + } vmap_initialized = true; } void unmap_kernel_range(unsigned long addr, unsigned long size) { unsigned long end = addr + size; + + flush_cache_vunmap(addr, end); vunmap_page_range(addr, end); flush_tlb_kernel_range(addr, end); } --- linux-2.6.28.orig/security/commoncap.c +++ linux-2.6.28/security/commoncap.c @@ -411,8 +411,9 @@ current->egid != current->gid); } -int cap_inode_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags) +int cap_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, size_t size, + int flags, struct file *file) { if (!strcmp(name, XATTR_NAME_CAPS)) { if (!capable(CAP_SETFCAP)) @@ -425,7 +426,8 @@ return 0; } -int cap_inode_removexattr(struct dentry *dentry, const char *name) +int cap_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *file) { if (!strcmp(name, XATTR_NAME_CAPS)) { if (!capable(CAP_SETFCAP)) --- linux-2.6.28.orig/security/Kconfig +++ linux-2.6.28/security/Kconfig @@ -125,6 +125,7 @@ source security/selinux/Kconfig source security/smack/Kconfig +source security/apparmor/Kconfig endmenu --- linux-2.6.28.orig/security/security.c +++ linux-2.6.28/security/security.c @@ -367,72 +367,81 @@ } EXPORT_SYMBOL(security_inode_init_security); -int security_inode_create(struct inode *dir, struct dentry *dentry, int mode) +int security_inode_create(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode) { if (unlikely(IS_PRIVATE(dir))) return 0; - return security_ops->inode_create(dir, dentry, mode); + return security_ops->inode_create(dir, dentry, mnt, mode); } -int security_inode_link(struct dentry *old_dentry, struct inode *dir, - struct dentry *new_dentry) +int security_inode_link(struct dentry *old_dentry, struct vfsmount *old_mnt, + struct inode *dir, struct dentry *new_dentry, + struct vfsmount *new_mnt) { if (unlikely(IS_PRIVATE(old_dentry->d_inode))) return 0; - return security_ops->inode_link(old_dentry, dir, new_dentry); + return security_ops->inode_link(old_dentry, old_mnt, dir, + new_dentry, new_mnt); } -int security_inode_unlink(struct inode *dir, struct dentry *dentry) +int security_inode_unlink(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt) { if (unlikely(IS_PRIVATE(dentry->d_inode))) return 0; - return security_ops->inode_unlink(dir, dentry); + return security_ops->inode_unlink(dir, dentry, mnt); } int security_inode_symlink(struct inode *dir, struct dentry *dentry, - const char *old_name) + struct vfsmount *mnt, const char *old_name) { if (unlikely(IS_PRIVATE(dir))) return 0; - return security_ops->inode_symlink(dir, dentry, old_name); + return security_ops->inode_symlink(dir, dentry, mnt, old_name); } -int security_inode_mkdir(struct inode *dir, struct dentry *dentry, int mode) +int security_inode_mkdir(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode) { if (unlikely(IS_PRIVATE(dir))) return 0; - return security_ops->inode_mkdir(dir, dentry, mode); + return security_ops->inode_mkdir(dir, dentry, mnt, mode); } -int security_inode_rmdir(struct inode *dir, struct dentry *dentry) +int security_inode_rmdir(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt) { if (unlikely(IS_PRIVATE(dentry->d_inode))) return 0; - return security_ops->inode_rmdir(dir, dentry); + return security_ops->inode_rmdir(dir, dentry, mnt); } -int security_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) +int security_inode_mknod(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode, dev_t dev) { if (unlikely(IS_PRIVATE(dir))) return 0; - return security_ops->inode_mknod(dir, dentry, mode, dev); + return security_ops->inode_mknod(dir, dentry, mnt, mode, dev); } +EXPORT_SYMBOL_GPL(security_inode_permission); int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry) + struct vfsmount *old_mnt, struct inode *new_dir, + struct dentry *new_dentry, struct vfsmount *new_mnt) { if (unlikely(IS_PRIVATE(old_dentry->d_inode) || (new_dentry->d_inode && IS_PRIVATE(new_dentry->d_inode)))) return 0; - return security_ops->inode_rename(old_dir, old_dentry, - new_dir, new_dentry); + return security_ops->inode_rename(old_dir, old_dentry, old_mnt, + new_dir, new_dentry, new_mnt); } -int security_inode_readlink(struct dentry *dentry) +int security_inode_readlink(struct dentry *dentry, struct vfsmount *mnt) { if (unlikely(IS_PRIVATE(dentry->d_inode))) return 0; - return security_ops->inode_readlink(dentry); + return security_ops->inode_readlink(dentry, mnt); } int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd) @@ -449,11 +458,12 @@ return security_ops->inode_permission(inode, mask); } -int security_inode_setattr(struct dentry *dentry, struct iattr *attr) +int security_inode_setattr(struct dentry *dentry, struct vfsmount *mnt, + struct iattr *attr) { if (unlikely(IS_PRIVATE(dentry->d_inode))) return 0; - return security_ops->inode_setattr(dentry, attr); + return security_ops->inode_setattr(dentry, mnt, attr); } EXPORT_SYMBOL_GPL(security_inode_setattr); @@ -471,41 +481,48 @@ security_ops->inode_delete(inode); } -int security_inode_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags) +int security_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, size_t size, + int flags, struct file *file) { if (unlikely(IS_PRIVATE(dentry->d_inode))) return 0; - return security_ops->inode_setxattr(dentry, name, value, size, flags); + return security_ops->inode_setxattr(dentry, mnt, name, value, size, + flags, file); } -void security_inode_post_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags) +void security_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, + size_t size, int flags) { if (unlikely(IS_PRIVATE(dentry->d_inode))) return; - security_ops->inode_post_setxattr(dentry, name, value, size, flags); + security_ops->inode_post_setxattr(dentry, mnt, name, value, size, + flags); } -int security_inode_getxattr(struct dentry *dentry, const char *name) +int security_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *file) { if (unlikely(IS_PRIVATE(dentry->d_inode))) return 0; - return security_ops->inode_getxattr(dentry, name); + return security_ops->inode_getxattr(dentry, mnt, name, file); } -int security_inode_listxattr(struct dentry *dentry) +int security_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt, + struct file *file) { if (unlikely(IS_PRIVATE(dentry->d_inode))) return 0; - return security_ops->inode_listxattr(dentry); + return security_ops->inode_listxattr(dentry, mnt, file); } -int security_inode_removexattr(struct dentry *dentry, const char *name) +int security_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *file) { if (unlikely(IS_PRIVATE(dentry->d_inode))) return 0; - return security_ops->inode_removexattr(dentry, name); + return security_ops->inode_removexattr(dentry, mnt, name, file); } int security_inode_need_killpriv(struct dentry *dentry) @@ -608,6 +625,15 @@ return security_ops->dentry_open(file); } +int security_path_permission(struct path *path, int mask) +{ + struct inode *inode = path->dentry->d_inode; + if (unlikely(IS_PRIVATE(inode))) + return 0; + + return security_ops->path_permission(path, mask); +} + int security_task_create(unsigned long clone_flags) { return security_ops->task_create(clone_flags); --- linux-2.6.28.orig/security/device_cgroup.c +++ linux-2.6.28/security/device_cgroup.c @@ -513,6 +513,9 @@ struct dev_cgroup *dev_cgroup; struct dev_whitelist_item *wh; + if (!S_ISBLK(mode) && !S_ISCHR(mode)) + return 0; + rcu_read_lock(); dev_cgroup = task_devcgroup(current); --- linux-2.6.28.orig/security/Makefile +++ linux-2.6.28/security/Makefile @@ -15,5 +15,6 @@ # Must precede capability.o in order to stack properly. obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o -obj-$(CONFIG_SECURITY_ROOTPLUG) += root_plug.o +obj-$(CONFIG_SECURITY_APPARMOR) += commoncap.o apparmor/ + obj-$(CONFIG_SECURITY_ROOTPLUG) += root_plug.o obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o --- linux-2.6.28.orig/security/capability.c +++ linux-2.6.28/security/capability.c @@ -155,52 +155,56 @@ } static int cap_inode_create(struct inode *inode, struct dentry *dentry, - int mask) + struct vfsmount *mnt, int mask) { return 0; } -static int cap_inode_link(struct dentry *old_dentry, struct inode *inode, - struct dentry *new_dentry) +static int cap_inode_link(struct dentry *old_dentry, struct vfsmount *old_mnt, + struct inode *inode, + struct dentry *new_dentry, struct vfsmount *new_mnt) { return 0; } -static int cap_inode_unlink(struct inode *inode, struct dentry *dentry) +static int cap_inode_unlink(struct inode *inode, struct dentry *dentry, + struct vfsmount *mnt) { return 0; } static int cap_inode_symlink(struct inode *inode, struct dentry *dentry, - const char *name) + struct vfsmount *mnt, const char *name) { return 0; } static int cap_inode_mkdir(struct inode *inode, struct dentry *dentry, - int mask) + struct vfsmount *mnt, int mask) { return 0; } -static int cap_inode_rmdir(struct inode *inode, struct dentry *dentry) +static int cap_inode_rmdir(struct inode *inode, struct dentry *dentry, + struct vfsmount *mnt) { return 0; } static int cap_inode_mknod(struct inode *inode, struct dentry *dentry, - int mode, dev_t dev) + struct vfsmount *mnt, 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) + struct vfsmount *old_mnt, struct inode *new_inode, + struct dentry *new_dentry, struct vfsmount *new_mnt) { return 0; } -static int cap_inode_readlink(struct dentry *dentry) +static int cap_inode_readlink(struct dentry *dentry, struct vfsmount *mnt) { return 0; } @@ -216,7 +220,8 @@ return 0; } -static int cap_inode_setattr(struct dentry *dentry, struct iattr *iattr) +static int cap_inode_setattr(struct dentry *dentry, struct vfsmount *mnt, + struct iattr *iattr) { return 0; } @@ -230,17 +235,20 @@ { } -static void cap_inode_post_setxattr(struct dentry *dentry, const char *name, +static void cap_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, size_t size, int flags) { } -static int cap_inode_getxattr(struct dentry *dentry, const char *name) +static int cap_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *f) { return 0; } -static int cap_inode_listxattr(struct dentry *dentry) +static int cap_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt, + struct file *f) { return 0; } @@ -335,6 +343,11 @@ return 0; } +static int cap_path_permission(struct path *path, int mask) +{ + return security_inode_permission(path->dentry->d_inode, mask); +} + static int cap_task_create(unsigned long clone_flags) { return 0; @@ -889,6 +902,7 @@ 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, path_permission); 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); --- linux-2.6.28.orig/security/keys/keyctl.c +++ linux-2.6.28/security/keys/keyctl.c @@ -54,11 +54,11 @@ * - returns the new key's serial number * - implements add_key() */ -asmlinkage long sys_add_key(const char __user *_type, - const char __user *_description, - const void __user *_payload, - size_t plen, - key_serial_t ringid) +SYSCALL_DEFINE5(add_key, const char __user *, _type, + const char __user *, _description, + const void __user *, _payload, + size_t, plen, + key_serial_t, ringid) { key_ref_t keyring_ref, key_ref; char type[32], *description; @@ -146,10 +146,10 @@ * - if the _callout_info string is empty, it will be rendered as "-" * - implements request_key() */ -asmlinkage long sys_request_key(const char __user *_type, - const char __user *_description, - const char __user *_callout_info, - key_serial_t destringid) +SYSCALL_DEFINE4(request_key, const char __user *, _type, + const char __user *, _description, + const char __user *, _callout_info, + key_serial_t, destringid) { struct key_type *ktype; struct key *key; @@ -270,6 +270,7 @@ /* join the session */ ret = join_session_keyring(name); + kfree(name); error: return ret; @@ -1152,8 +1153,8 @@ /* * the key control system call */ -asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3, - unsigned long arg4, unsigned long arg5) +SYSCALL_DEFINE5(keyctl, int, option, unsigned long, arg2, unsigned long, arg3, + unsigned long, arg4, unsigned long, arg5) { switch (option) { case KEYCTL_GET_KEYRING_ID: --- linux-2.6.28.orig/security/selinux/hooks.c +++ linux-2.6.28/security/selinux/hooks.c @@ -1814,40 +1814,16 @@ static int selinux_sysctl_get_sid(ctl_table *table, u16 tclass, u32 *sid) { - int buflen, rc; - char *buffer, *path, *end; + char *buffer, *path; + int rc = -ENOMEM; - rc = -ENOMEM; buffer = (char *)__get_free_page(GFP_KERNEL); if (!buffer) goto out; - buflen = PAGE_SIZE; - end = buffer+buflen; - *--end = '\0'; - buflen--; - path = end-1; - *path = '/'; - while (table) { - const char *name = table->procname; - size_t namelen = strlen(name); - buflen -= namelen + 1; - if (buflen < 0) - goto out_free; - end -= namelen; - memcpy(end, name, namelen); - *--end = '/'; - path = end; - table = table->parent; - } - buflen -= 4; - if (buflen < 0) - goto out_free; - end -= 4; - memcpy(end, "/sys", 4); - path = end; - rc = security_genfs_sid("proc", path, tclass, sid); -out_free: + path = sysctl_pathname(table, buffer, PAGE_SIZE); + if (path) + rc = security_genfs_sid("proc", path, tclass, sid); free_page((unsigned long)buffer); out: return rc; @@ -2564,64 +2540,79 @@ return 0; } -static int selinux_inode_create(struct inode *dir, struct dentry *dentry, int mask) +static int selinux_inode_create(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mask) { return may_create(dir, dentry, SECCLASS_FILE); } -static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) +static int selinux_inode_link(struct dentry *old_dentry, + struct vfsmount *old_mnt, + struct inode *dir, + struct dentry *new_dentry, + struct vfsmount *new_mnt) { int rc; - rc = secondary_ops->inode_link(old_dentry, dir, new_dentry); + rc = secondary_ops->inode_link(old_dentry, old_mnt, dir, new_dentry, + new_mnt); if (rc) return rc; return may_link(dir, old_dentry, MAY_LINK); } -static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry) +static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt) { int rc; - rc = secondary_ops->inode_unlink(dir, dentry); + rc = secondary_ops->inode_unlink(dir, dentry, mnt); if (rc) return rc; return may_link(dir, dentry, MAY_UNLINK); } -static int selinux_inode_symlink(struct inode *dir, struct dentry *dentry, const char *name) +static int selinux_inode_symlink(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, const char *name) { return may_create(dir, dentry, SECCLASS_LNK_FILE); } -static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry, int mask) +static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mask) { return may_create(dir, dentry, SECCLASS_DIR); } -static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry) +static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt) { return may_link(dir, dentry, MAY_RMDIR); } -static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) +static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode, dev_t dev) { int rc; - rc = secondary_ops->inode_mknod(dir, dentry, mode, dev); + rc = secondary_ops->inode_mknod(dir, dentry, mnt, mode, dev); if (rc) return rc; return may_create(dir, dentry, inode_mode_to_security_class(mode)); } -static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry, - struct inode *new_inode, struct dentry *new_dentry) +static int selinux_inode_rename(struct inode *old_inode, + struct dentry *old_dentry, + struct vfsmount *old_mnt, + struct inode *new_inode, + struct dentry *new_dentry, + struct vfsmount *new_mnt) { return may_rename(old_inode, old_dentry, new_inode, new_dentry); } -static int selinux_inode_readlink(struct dentry *dentry) +static int selinux_inode_readlink(struct dentry *dentry, struct vfsmount *mnt) { return dentry_has_perm(current, NULL, dentry, FILE__READ); } @@ -2653,11 +2644,12 @@ open_file_mask_to_av(inode->i_mode, mask), NULL); } -static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) +static int selinux_inode_setattr(struct dentry *dentry, struct vfsmount *mnt, + struct iattr *iattr) { int rc; - rc = secondary_ops->inode_setattr(dentry, iattr); + rc = secondary_ops->inode_setattr(dentry, mnt, iattr); if (rc) return rc; @@ -2695,8 +2687,9 @@ return dentry_has_perm(current, NULL, dentry, FILE__SETATTR); } -static int selinux_inode_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags) +static int selinux_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, + size_t size, int flags, struct file *file) { struct task_security_struct *tsec = current->security; struct inode *inode = dentry->d_inode; @@ -2750,7 +2743,8 @@ &ad); } -static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name, +static void selinux_inode_post_setxattr(struct dentry *dentry, + struct vfsmount *mnt, const char *name, const void *value, size_t size, int flags) { @@ -2776,17 +2770,21 @@ return; } -static int selinux_inode_getxattr(struct dentry *dentry, const char *name) +static int selinux_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *file) { return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); } -static int selinux_inode_listxattr(struct dentry *dentry) +static int selinux_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt, + struct file *file) { return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); } -static int selinux_inode_removexattr(struct dentry *dentry, const char *name) +static int selinux_inode_removexattr(struct dentry *dentry, + struct vfsmount *mnt, const char *name, + struct file *file) { if (strcmp(name, XATTR_NAME_SELINUX)) return selinux_inode_setotherxattr(dentry, name); --- linux-2.6.28.orig/security/selinux/netlabel.c +++ linux-2.6.28/security/selinux/netlabel.c @@ -386,11 +386,12 @@ if (!S_ISSOCK(inode->i_mode) || ((mask & (MAY_WRITE | MAY_APPEND)) == 0)) return 0; - sock = SOCKET_I(inode); sk = sock->sk; + if (sk == NULL) + return 0; sksec = sk->sk_security; - if (sksec->nlbl_state != NLBL_REQUIRE) + if (sksec == NULL || sksec->nlbl_state != NLBL_REQUIRE) return 0; local_bh_disable(); @@ -490,8 +491,10 @@ lock_sock(sk); rc = netlbl_sock_getattr(sk, &secattr); release_sock(sk); - if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) + if (rc == 0) rc = -EACCES; + else if (rc == -ENOMSG) + rc = 0; netlbl_secattr_destroy(&secattr); } --- linux-2.6.28.orig/security/smack/smack_lsm.c +++ linux-2.6.28/security/smack/smack_lsm.c @@ -432,8 +432,9 @@ * * Returns 0 if access is permitted, an error code otherwise */ -static int smack_inode_link(struct dentry *old_dentry, struct inode *dir, - struct dentry *new_dentry) +static int smack_inode_link(struct dentry *old_dentry, struct vfsmount *old_mnt, + struct inode *dir, + struct dentry *new_dentry, struct vfsmount *new_mnt) { int rc; char *isp; @@ -453,11 +454,13 @@ * smack_inode_unlink - Smack check on inode deletion * @dir: containing directory object * @dentry: file to unlink + * @mnt: vfsmount of file to unlink * * Returns 0 if current can write the containing directory * and the object, error code otherwise */ -static int smack_inode_unlink(struct inode *dir, struct dentry *dentry) +static int smack_inode_unlink(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt) { struct inode *ip = dentry->d_inode; int rc; @@ -479,11 +482,13 @@ * smack_inode_rmdir - Smack check on directory deletion * @dir: containing directory object * @dentry: directory to unlink + * @mnt: vfsmount @dentry to unlink * * Returns 0 if current can write the containing directory * and the directory, error code otherwise */ -static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry) +static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt) { int rc; @@ -504,8 +509,10 @@ * smack_inode_rename - Smack check on rename * @old_inode: the old directory * @old_dentry: unused + * @old_mnt: unused * @new_inode: the new directory * @new_dentry: unused + * @new_mnt: unused * * Read and write access is required on both the old and * new directories. @@ -514,8 +521,10 @@ */ static int smack_inode_rename(struct inode *old_inode, struct dentry *old_dentry, + struct vfsmount *old_mnt, struct inode *new_inode, - struct dentry *new_dentry) + struct dentry *new_dentry, + struct vfsmount *new_mnt) { int rc; char *isp; @@ -559,7 +568,8 @@ * * Returns 0 if access is permitted, an error code otherwise */ -static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr) +static int smack_inode_setattr(struct dentry *dentry, struct vfsmount *mnt, + struct iattr *iattr) { /* * Need to allow for clearing the setuid bit. @@ -585,17 +595,20 @@ /** * smack_inode_setxattr - Smack check for setting xattrs * @dentry: the object + * @mnt: unused * @name: name of the attribute * @value: unused * @size: unused * @flags: unused + * @file: unused * * This protects the Smack attribute explicitly. * * Returns 0 if access is permitted, an error code otherwise */ -static int smack_inode_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags) +static int smack_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, + size_t size, int flags, struct file *file) { int rc = 0; @@ -605,7 +618,8 @@ if (!capable(CAP_MAC_ADMIN)) rc = -EPERM; } else - rc = cap_inode_setxattr(dentry, name, value, size, flags); + rc = cap_inode_setxattr(dentry, mnt, name, value, size, flags, + file); if (rc == 0) rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); @@ -616,6 +630,7 @@ /** * smack_inode_post_setxattr - Apply the Smack update approved above * @dentry: object + * @mnt: unused * @name: attribute name * @value: attribute value * @size: attribute size @@ -624,7 +639,8 @@ * Set the pointer in the inode blob to the entry found * in the master label list. */ -static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, +static void smack_inode_post_setxattr(struct dentry *dentry, + struct vfsmount *mnt, const char *name, const void *value, size_t size, int flags) { struct inode_smack *isp; @@ -657,11 +673,14 @@ /* * smack_inode_getxattr - Smack check on getxattr * @dentry: the object + * @mnt: unused * @name: unused + * @file: unused * * Returns 0 if access is permitted, an error code otherwise */ -static int smack_inode_getxattr(struct dentry *dentry, const char *name) +static int smack_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *file) { return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ); } @@ -669,13 +688,16 @@ /* * smack_inode_removexattr - Smack check on removexattr * @dentry: the object + * @mnt: unused * @name: name of the attribute + * @file: unused * * Removing the Smack attribute requires CAP_MAC_ADMIN * * Returns 0 if access is permitted, an error code otherwise */ -static int smack_inode_removexattr(struct dentry *dentry, const char *name) +static int smack_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *file) { int rc = 0; @@ -685,7 +707,7 @@ if (!capable(CAP_MAC_ADMIN)) rc = -EPERM; } else - rc = cap_inode_removexattr(dentry, name); + rc = cap_inode_removexattr(dentry, mnt, name, file); if (rc == 0) rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); --- linux-2.6.28.orig/security/apparmor/module_interface.c +++ linux-2.6.28/security/apparmor/module_interface.c @@ -0,0 +1,967 @@ +/* + * Copyright (C) 1998-2007 Novell/SUSE + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + * + * AppArmor userspace policy interface + */ + +#include + +#include "apparmor.h" +#include "inline.h" + +/* + * This mutex is used to synchronize profile adds, replacements, and + * removals: we only allow one of these operations at a time. + * We do not use the profile list lock here in order to avoid blocking + * exec during those operations. (Exec involves a profile list lookup + * for named-profile transitions.) + */ +DEFINE_MUTEX(aa_interface_lock); + +/* + * The AppArmor interface treats data as a type byte followed by the + * actual data. The interface has the notion of a a named entry + * which has a name (AA_NAME typecode followed by name string) followed by + * the entries typecode and data. Named types allow for optional + * elements and extensions to be added and tested for without breaking + * backwards compatability. + */ + +enum aa_code { + AA_U8, + AA_U16, + AA_U32, + AA_U64, + AA_NAME, /* same as string except it is items name */ + AA_STRING, + AA_BLOB, + AA_STRUCT, + AA_STRUCTEND, + AA_LIST, + AA_LISTEND, + AA_ARRAY, + AA_ARRAYEND, +}; + +/* + * aa_ext is the read of the buffer containing the serialized profile. The + * data is copied into a kernel buffer in apparmorfs and then handed off to + * the unpack routines. + */ +struct aa_ext { + void *start; + void *end; + void *pos; /* pointer to current position in the buffer */ + u32 version; + char *ns_name; +}; + +static inline int aa_inbounds(struct aa_ext *e, size_t size) +{ + return (size <= e->end - e->pos); +} + +/** + * aa_u16_chunck - test and do bounds checking for a u16 size based chunk + * @e: serialized data read head + * @chunk: start address for chunk of data + * + * return the size of chunk found with the read head at the end of + * the chunk. + */ +static size_t aa_is_u16_chunk(struct aa_ext *e, char **chunk) +{ + void *pos = e->pos; + size_t size = 0; + + if (!aa_inbounds(e, sizeof(u16))) + goto fail; + size = le16_to_cpu(get_unaligned((u16 *)e->pos)); + e->pos += sizeof(u16); + if (!aa_inbounds(e, size)) + goto fail; + *chunk = e->pos; + e->pos += size; + return size; + +fail: + e->pos = pos; + return 0; +} + +static inline int aa_is_X(struct aa_ext *e, enum aa_code code) +{ + if (!aa_inbounds(e, 1)) + return 0; + if (*(u8 *) e->pos != code) + return 0; + e->pos++; + return 1; +} + +/** + * aa_is_nameX - check is the next element is of type X with a name of @name + * @e: serialized data extent information + * @code: type code + * @name: name to match to the serialized element. + * + * check that the next serialized data element is of type X and has a tag + * name @name. If @name is specified then there must be a matching + * name element in the stream. If @name is NULL any name element will be + * skipped and only the typecode will be tested. + * returns 1 on success (both type code and name tests match) and the read + * head is advanced past the headers + * returns %0 if either match failes, the read head does not move + */ +static int aa_is_nameX(struct aa_ext *e, enum aa_code code, const char *name) +{ + void *pos = e->pos; + /* + * Check for presence of a tagname, and if present name size + * AA_NAME tag value is a u16. + */ + if (aa_is_X(e, AA_NAME)) { + char *tag; + size_t size = aa_is_u16_chunk(e, &tag); + /* if a name is specified it must match. otherwise skip tag */ + if (name && (!size || strcmp(name, tag))) + goto fail; + } else if (name) { + /* if a name is specified and there is no name tag fail */ + goto fail; + } + + /* now check if type code matches */ + if (aa_is_X(e, code)) + return 1; + +fail: + e->pos = pos; + return 0; +} + +static int aa_is_u16(struct aa_ext *e, u16 *data, const char *name) +{ + void *pos = e->pos; + if (aa_is_nameX(e, AA_U16, name)) { + if (!aa_inbounds(e, sizeof(u16))) + goto fail; + if (data) + *data = le16_to_cpu(get_unaligned((u16 *)e->pos)); + e->pos += sizeof(u16); + return 1; + } +fail: + e->pos = pos; + return 0; +} + +static int aa_is_u32(struct aa_ext *e, u32 *data, const char *name) +{ + void *pos = e->pos; + if (aa_is_nameX(e, AA_U32, name)) { + if (!aa_inbounds(e, sizeof(u32))) + goto fail; + if (data) + *data = le32_to_cpu(get_unaligned((u32 *)e->pos)); + e->pos += sizeof(u32); + return 1; + } +fail: + e->pos = pos; + return 0; +} + +static int aa_is_u64(struct aa_ext *e, u64 *data, const char *name) +{ + void *pos = e->pos; + if (aa_is_nameX(e, AA_U64, name)) { + if (!aa_inbounds(e, sizeof(u64))) + goto fail; + if (data) + *data = le64_to_cpu(get_unaligned((u64 *)e->pos)); + e->pos += sizeof(u64); + return 1; + } +fail: + e->pos = pos; + return 0; +} + +static size_t aa_is_array(struct aa_ext *e, const char *name) +{ + void *pos = e->pos; + if (aa_is_nameX(e, AA_ARRAY, name)) { + int size; + if (!aa_inbounds(e, sizeof(u16))) + goto fail; + size = (int) le16_to_cpu(get_unaligned((u16 *)e->pos)); + e->pos += sizeof(u16); + return size; + } +fail: + e->pos = pos; + return 0; +} + +static size_t aa_is_blob(struct aa_ext *e, char **blob, const char *name) +{ + void *pos = e->pos; + if (aa_is_nameX(e, AA_BLOB, name)) { + u32 size; + if (!aa_inbounds(e, sizeof(u32))) + goto fail; + size = le32_to_cpu(get_unaligned((u32 *)e->pos)); + e->pos += sizeof(u32); + if (aa_inbounds(e, (size_t) size)) { + * blob = e->pos; + e->pos += size; + return size; + } + } +fail: + e->pos = pos; + return 0; +} + +static int aa_is_dynstring(struct aa_ext *e, char **string, const char *name) +{ + char *src_str; + size_t size = 0; + void *pos = e->pos; + *string = NULL; + if (aa_is_nameX(e, AA_STRING, name) && + (size = aa_is_u16_chunk(e, &src_str))) { + char *str; + if (!(str = kmalloc(size, GFP_KERNEL))) + goto fail; + memcpy(str, src_str, size); + *string = str; + } + + return size; + +fail: + e->pos = pos; + return 0; +} + +/** + * aa_unpack_dfa - unpack a file rule dfa + * @e: serialized data extent information + * + * returns dfa or ERR_PTR + */ +static struct aa_dfa *aa_unpack_dfa(struct aa_ext *e) +{ + char *blob = NULL; + size_t size, error = 0; + struct aa_dfa *dfa = NULL; + + size = aa_is_blob(e, &blob, "aadfa"); + if (size) { + dfa = aa_match_alloc(); + if (dfa) { + /* + * The dfa is aligned with in the blob to 8 bytes + * from the beginning of the stream. + */ + size_t sz = blob - (char *) e->start; + size_t pad = ALIGN(sz, 8) - sz; + error = unpack_dfa(dfa, blob + pad, size - pad); + if (!error) + error = verify_dfa(dfa); + } else { + error = -ENOMEM; + } + + if (error) { + aa_match_free(dfa); + dfa = ERR_PTR(error); + } + } + + return dfa; +} + +static int aa_unpack_exec_table(struct aa_ext *e, struct aa_profile *profile) +{ + void *pos = e->pos; + + /* exec table is optional */ + if (aa_is_nameX(e, AA_STRUCT, "xtable")) { + int i, size; + + size = aa_is_array(e, NULL); + /* currently 4 exec bits and entries 0-3 are reserved iupcx */ + if (size > 16 - 4) + goto fail; + profile->exec_table = kzalloc(sizeof(char *) * size, + GFP_KERNEL); + if (!profile->exec_table) + goto fail; + + for (i = 0; i < size; i++) { + char *tmp; + if (!aa_is_dynstring(e, &tmp, NULL)) + goto fail; + /* note: strings beginning with a : have an embedded + \0 seperating the profile ns name from the profile + name */ + profile->exec_table[i] = tmp; + } + if (!aa_is_nameX(e, AA_ARRAYEND, NULL)) + goto fail; + if (!aa_is_nameX(e, AA_STRUCTEND, NULL)) + goto fail; + profile->exec_table_size = size; + } + return 1; + +fail: + e->pos = pos; + return 0; +} + +int aa_unpack_rlimits(struct aa_ext *e, struct aa_profile *profile) +{ + void *pos = e->pos; + + /* rlimits are optional */ + if (aa_is_nameX(e, AA_STRUCT, "rlimits")) { + int i, size; + u32 tmp = 0; + if (!aa_is_u32(e, &tmp, NULL)) + goto fail; + profile->rlimits.mask = tmp; + + size = aa_is_array(e, NULL); + if (size > RLIM_NLIMITS) + goto fail; + for (i = 0; i < size; i++) { + u64 tmp = 0; + if (!aa_is_u64(e, &tmp, NULL)) + goto fail; + profile->rlimits.limits[i].rlim_max = tmp; + } + if (!aa_is_nameX(e, AA_ARRAYEND, NULL)) + goto fail; + if (!aa_is_nameX(e, AA_STRUCTEND, NULL)) + goto fail; + } + return 1; + +fail: + e->pos = pos; + return 0; +} + +/** + * aa_unpack_profile - unpack a serialized profile + * @e: serialized data extent information + * @sa: audit struct for the operation + */ +static struct aa_profile *aa_unpack_profile(struct aa_ext *e, + struct aa_audit *sa) +{ + struct aa_profile *profile = NULL; + size_t size = 0; + int i, error = -EPROTO; + + profile = alloc_aa_profile(); + if (!profile) + return ERR_PTR(-ENOMEM); + + /* check that we have the right struct being passed */ + if (!aa_is_nameX(e, AA_STRUCT, "profile")) + goto fail; + if (!aa_is_dynstring(e, &profile->name, NULL)) + goto fail; + + /* per profile debug flags (complain, audit) */ + if (!aa_is_nameX(e, AA_STRUCT, "flags")) + goto fail; + if (!aa_is_u32(e, &(profile->flags.hat), NULL)) + goto fail; + if (!aa_is_u32(e, &(profile->flags.complain), NULL)) + goto fail; + if (!aa_is_u32(e, &(profile->flags.audit), NULL)) + goto fail; + if (!aa_is_nameX(e, AA_STRUCTEND, NULL)) + goto fail; + + if (!aa_is_u32(e, &(profile->capabilities.cap[0]), NULL)) + goto fail; + if (!aa_is_u32(e, &(profile->audit_caps.cap[0]), NULL)) + goto fail; + if (!aa_is_u32(e, &(profile->quiet_caps.cap[0]), NULL)) + goto fail; + if (!aa_is_u32(e, &(profile->set_caps.cap[0]), NULL)) + goto fail; + + if (aa_is_nameX(e, AA_STRUCT, "caps64")) { + /* optional upper half of 64 bit caps */ + if (!aa_is_u32(e, &(profile->capabilities.cap[1]), NULL)) + goto fail; + if (!aa_is_u32(e, &(profile->audit_caps.cap[1]), NULL)) + goto fail; + if (!aa_is_u32(e, &(profile->quiet_caps.cap[1]), NULL)) + goto fail; + if (!aa_is_u32(e, &(profile->set_caps.cap[1]), NULL)) + goto fail; + if (!aa_is_nameX(e, AA_STRUCTEND, NULL)) + goto fail; + } + + if (!aa_unpack_rlimits(e, profile)) + goto fail; + + size = aa_is_array(e, "net_allowed_af"); + if (size) { + if (size > AF_MAX) + goto fail; + + for (i = 0; i < size; i++) { + if (!aa_is_u16(e, &profile->network_families[i], NULL)) + goto fail; + if (!aa_is_u16(e, &profile->audit_network[i], NULL)) + goto fail; + if (!aa_is_u16(e, &profile->quiet_network[i], NULL)) + goto fail; + } + if (!aa_is_nameX(e, AA_ARRAYEND, NULL)) + goto fail; + /* allow unix domain and netlink sockets they are handled + * by IPC + */ + } + profile->network_families[AF_UNIX] = 0xffff; + profile->network_families[AF_NETLINK] = 0xffff; + + /* get file rules */ + profile->file_rules = aa_unpack_dfa(e); + if (IS_ERR(profile->file_rules)) { + error = PTR_ERR(profile->file_rules); + profile->file_rules = NULL; + goto fail; + } + + if (!aa_unpack_exec_table(e, profile)) + goto fail; + + if (!aa_is_nameX(e, AA_STRUCTEND, NULL)) + goto fail; + + return profile; + +fail: + sa->name = profile && profile->name ? profile->name : "unknown"; + if (!sa->info) + sa->info = "failed to unpack profile"; + aa_audit_status(NULL, sa); + + if (profile) + free_aa_profile(profile); + + return ERR_PTR(error); +} + +/** + * aa_verify_head - unpack serialized stream header + * @e: serialized data read head + * @operation: operation header is being verified for + * + * returns error or 0 if header is good + */ +static int aa_verify_header(struct aa_ext *e, struct aa_audit *sa) +{ + /* get the interface version */ + if (!aa_is_u32(e, &e->version, "version")) { + sa->info = "invalid profile format"; + aa_audit_status(NULL, sa); + return -EPROTONOSUPPORT; + } + + /* check that the interface version is currently supported */ + if (e->version != 5) { + sa->info = "unsupported interface version"; + aa_audit_status(NULL, sa); + return -EPROTONOSUPPORT; + } + + /* read the namespace if present */ + if (!aa_is_dynstring(e, &e->ns_name, "namespace")) { + e->ns_name = NULL; + } + + return 0; +} + +/** + * aa_add_profile - Unpack and add a new profile to the profile list + * @data: serialized data stream + * @size: size of the serialized data stream + */ +ssize_t aa_add_profile(void *data, size_t size) +{ + struct aa_profile *profile = NULL; + struct aa_namespace *ns = NULL; + struct aa_ext e = { + .start = data, + .end = data + size, + .pos = data, + .ns_name = NULL + }; + ssize_t error; + struct aa_audit sa; + memset(&sa, 0, sizeof(sa)); + sa.operation = "profile_load"; + sa.gfp_mask = GFP_KERNEL; + + error = aa_verify_header(&e, &sa); + if (error) + return error; + + profile = aa_unpack_profile(&e, &sa); + if (IS_ERR(profile)) + return PTR_ERR(profile); + + mutex_lock(&aa_interface_lock); + write_lock(&profile_ns_list_lock); + if (e.ns_name) + ns = __aa_find_namespace(e.ns_name, &profile_ns_list); + else + ns = default_namespace; + if (!ns) { + struct aa_namespace *new_ns; + write_unlock(&profile_ns_list_lock); + new_ns = alloc_aa_namespace(e.ns_name); + if (!new_ns) { + mutex_unlock(&aa_interface_lock); + return -ENOMEM; + } + write_lock(&profile_ns_list_lock); + ns = __aa_find_namespace(e.ns_name, &profile_ns_list); + if (!ns) { + list_add(&new_ns->list, &profile_ns_list); + ns = new_ns; + } else + free_aa_namespace(new_ns); + } + + write_lock(&ns->lock); + if (__aa_find_profile(profile->name, &ns->profiles)) { + /* A profile with this name exists already. */ + write_unlock(&ns->lock); + write_unlock(&profile_ns_list_lock); + sa.name = profile->name; + sa.name2 = ns->name; + sa.info = "failed: profile already loaded"; + aa_audit_status(NULL, &sa); + mutex_unlock(&aa_interface_lock); + aa_put_profile(profile); + return -EEXIST; + } + profile->ns = aa_get_namespace(ns); + ns->profile_count++; + list_add(&profile->list, &ns->profiles); + write_unlock(&ns->lock); + write_unlock(&profile_ns_list_lock); + + sa.name = profile->name; + sa.name2 = ns->name; + aa_audit_status(NULL, &sa); + mutex_unlock(&aa_interface_lock); + return size; +} + +/** + * task_replace - replace a task's profile + * @task: task to replace profile on + * @new_cxt: new aa_task_context to do replacement with + * @new_profile: new profile + */ +static inline void task_replace(struct task_struct *task, + struct aa_task_context *new_cxt, + struct aa_profile *new_profile) +{ + struct aa_task_context *cxt = aa_task_context(task); + + AA_DEBUG("%s: replacing profile for task %d " + "profile=%s (%p)\n", + __FUNCTION__, + cxt->task->pid, + cxt->profile->name, cxt->profile); + + aa_change_task_context(task, new_cxt, new_profile, cxt->cookie, + cxt->previous_profile); +} + +/** + * aa_replace_profile - replace a profile on the profile list + * @udata: serialized data stream + * @size: size of the serialized data stream + * + * unpack and replace a profile on the profile list and uses of that profile + * by any aa_task_context. If the profile does not exist on the profile list + * it is added. Return %0 or error. + */ +ssize_t aa_replace_profile(void *udata, size_t size) +{ + struct aa_profile *old_profile, *new_profile; + struct aa_namespace *ns; + struct aa_task_context *new_cxt; + struct aa_ext e = { + .start = udata, + .end = udata + size, + .pos = udata, + .ns_name = NULL + }; + ssize_t error; + struct aa_audit sa; + memset(&sa, 0, sizeof(sa)); + sa.operation = "profile_replace"; + sa.gfp_mask = GFP_KERNEL; + + error = aa_verify_header(&e, &sa); + if (error) + return error; + + new_profile = aa_unpack_profile(&e, &sa); + if (IS_ERR(new_profile)) + return PTR_ERR(new_profile); + + mutex_lock(&aa_interface_lock); + write_lock(&profile_ns_list_lock); + if (e.ns_name) + ns = __aa_find_namespace(e.ns_name, &profile_ns_list); + else + ns = default_namespace; + if (!ns) { + struct aa_namespace *new_ns; + write_unlock(&profile_ns_list_lock); + new_ns = alloc_aa_namespace(e.ns_name); + if (!new_ns) { + mutex_unlock(&aa_interface_lock); + return -ENOMEM; + } + write_lock(&profile_ns_list_lock); + ns = __aa_find_namespace(e.ns_name, &profile_ns_list); + if (!ns) { + list_add(&new_ns->list, &profile_ns_list); + ns = new_ns; + } else + free_aa_namespace(new_ns); + } + + write_lock(&ns->lock); + old_profile = __aa_find_profile(new_profile->name, &ns->profiles); + if (old_profile) { + lock_profile(old_profile); + old_profile->isstale = 1; + list_del_init(&old_profile->list); + unlock_profile(old_profile); + ns->profile_count--; + } + new_profile->ns = aa_get_namespace(ns); + ns->profile_count++; + /* not don't need an extra ref count to keep new_profile as + * it is protect by the interface mutex */ + list_add(&new_profile->list, &ns->profiles); + write_unlock(&ns->lock); + write_unlock(&profile_ns_list_lock); + + if (!old_profile) { + sa.operation = "profile_load"; + goto out; + } + /* do not fail replacement based off of profile's NPROC rlimit */ + + /* + * Replacement needs to allocate a new aa_task_context for each + * task confined by old_profile. To do this the profile locks + * are only held when the actual switch is done per task. While + * looping to allocate a new aa_task_context the old_task list + * may get shorter if tasks exit/change their profile but will + * not get longer as new task will not use old_profile detecting + * that is stale. + */ + do { + new_cxt = aa_alloc_task_context(GFP_KERNEL | __GFP_NOFAIL); + + lock_both_profiles(old_profile, new_profile); + if (!list_empty(&old_profile->task_contexts)) { + struct task_struct *task = + list_entry(old_profile->task_contexts.next, + struct aa_task_context, list)->task; + task_lock(task); + task_replace(task, new_cxt, new_profile); + task_unlock(task); + aa_set_rlimits(task, new_profile); + new_cxt = NULL; + } + unlock_both_profiles(old_profile, new_profile); + } while (!new_cxt); + aa_free_task_context(new_cxt); + aa_put_profile(old_profile); + +out: + sa.name = new_profile->name; + sa.name2 = ns->name; + aa_audit_status(NULL, &sa); + mutex_unlock(&aa_interface_lock); + return size; +} + +/** + * aa_remove_profile - remove a profile from the system + * @name: name of the profile to remove + * @size: size of the name + * + * remove a profile from the profile list and all aa_task_context references + * to said profile. + * NOTE: removing confinement does not restore rlimits to preconfinemnet values + */ +ssize_t aa_remove_profile(char *name, size_t size) +{ + struct aa_namespace *ns; + struct aa_profile *profile; + struct aa_audit sa; + memset(&sa, 0, sizeof(sa)); + sa.operation = "profile_remove"; + sa.gfp_mask = GFP_KERNEL; + + mutex_lock(&aa_interface_lock); + write_lock(&profile_ns_list_lock); + + if (name[0] == ':') { + char *split = strchr(name + 1, ':'); + if (!split) + goto noent; + *split = 0; + ns = __aa_find_namespace(name + 1, &profile_ns_list); + name = split + 1; + } else { + ns = default_namespace; + } + + if (!ns) + goto noent; + sa.name2 = ns->name; + write_lock(&ns->lock); + profile = __aa_find_profile(name, &ns->profiles); + if (!profile) { + write_unlock(&ns->lock); + goto noent; + } + sa.name = profile->name; + + /* Remove the profile from each task context it is on. */ + lock_profile(profile); + profile->isstale = 1; + aa_unconfine_tasks(profile); + list_del_init(&profile->list); + ns->profile_count--; + unlock_profile(profile); + /* Release the profile itself. */ + write_unlock(&ns->lock); + /* check to see if the namespace has become stale */ + if (ns != default_namespace && ns->profile_count == 0) { + list_del_init(&ns->list); + aa_put_namespace(ns); + } + write_unlock(&profile_ns_list_lock); + + aa_audit_status(NULL, &sa); + mutex_unlock(&aa_interface_lock); + aa_put_profile(profile); + + return size; + +noent: + write_unlock(&profile_ns_list_lock); + sa.info = "failed: profile does not exist"; + aa_audit_status(NULL, &sa); + mutex_unlock(&aa_interface_lock); + return -ENOENT; +} + +/** + * free_aa_namespace_kref - free aa_namespace by kref (see aa_put_namespace) + * @kr: kref callback for freeing of a namespace + */ +void free_aa_namespace_kref(struct kref *kref) +{ + struct aa_namespace *ns=container_of(kref, struct aa_namespace, count); + + free_aa_namespace(ns); +} + +/** + * alloc_aa_namespace - allocate, initialize and return a new namespace + * @name: a preallocated name + * Returns NULL on failure. + */ +struct aa_namespace *alloc_aa_namespace(char *name) +{ + struct aa_namespace *ns; + + ns = kzalloc(sizeof(*ns), GFP_KERNEL); + AA_DEBUG("%s(%p)\n", __FUNCTION__, ns); + if (ns) { + ns->name = name; + INIT_LIST_HEAD(&ns->list); + INIT_LIST_HEAD(&ns->profiles); + kref_init(&ns->count); + rwlock_init(&ns->lock); + + ns->null_complain_profile = alloc_aa_profile(); + if (!ns->null_complain_profile) { + if (!name) + kfree(ns->name); + kfree(ns); + return NULL; + } + ns->null_complain_profile->name = + kstrdup("null-complain-profile", GFP_KERNEL); + if (!ns->null_complain_profile->name) { + free_aa_profile(ns->null_complain_profile); + if (!name) + kfree(ns->name); + kfree(ns); + return NULL; + } + ns->null_complain_profile->flags.complain = 1; + /* null_complain_profile doesn't contribute to ns ref count */ + ns->null_complain_profile->ns = ns; + } + return ns; +} + +/** + * free_aa_namespace - free a profile namespace + * @namespace: the namespace to free + * + * Free a namespace. All references to the namespace must have been put. + * If the namespace was referenced by a profile confining a task, + * free_aa_namespace will be called indirectly (through free_aa_profile) + * from an rcu callback routine, so we must not sleep here. + */ +void free_aa_namespace(struct aa_namespace *ns) +{ + AA_DEBUG("%s(%p)\n", __FUNCTION__, ns); + + if (!ns) + return; + + /* namespace still contains profiles -- invalid */ + if (!list_empty(&ns->profiles)) { + AA_ERROR("%s: internal error, " + "namespace '%s' still contains profiles\n", + __FUNCTION__, + ns->name); + BUG(); + } + if (!list_empty(&ns->list)) { + AA_ERROR("%s: internal error, " + "namespace '%s' still on list\n", + __FUNCTION__, + ns->name); + BUG(); + } + /* null_complain_profile doesn't contribute to ns ref counting */ + ns->null_complain_profile->ns = NULL; + aa_put_profile(ns->null_complain_profile); + kfree(ns->name); + kfree(ns); +} + +/** + * free_aa_profile_kref - free aa_profile by kref (called by aa_put_profile) + * @kr: kref callback for freeing of a profile + */ +void free_aa_profile_kref(struct kref *kref) +{ + struct aa_profile *p=container_of(kref, struct aa_profile, count); + + free_aa_profile(p); +} + +/** + * alloc_aa_profile - allocate, initialize and return a new profile + * Returns NULL on failure. + */ +struct aa_profile *alloc_aa_profile(void) +{ + struct aa_profile *profile; + + profile = kzalloc(sizeof(*profile), GFP_KERNEL); + AA_DEBUG("%s(%p)\n", __FUNCTION__, profile); + if (profile) { + INIT_LIST_HEAD(&profile->list); + kref_init(&profile->count); + INIT_LIST_HEAD(&profile->task_contexts); + spin_lock_init(&profile->lock); + } + return profile; +} + +/** + * free_aa_profile - free a profile + * @profile: the profile to free + * + * Free a profile, its hats and null_profile. All references to the profile, + * its hats and null_profile must have been put. + * + * If the profile was referenced from a task context, free_aa_profile() will + * be called from an rcu callback routine, so we must not sleep here. + */ +void free_aa_profile(struct aa_profile *profile) +{ + AA_DEBUG("%s(%p)\n", __FUNCTION__, profile); + + if (!profile) + return; + + /* profile is still on profile namespace list -- invalid */ + if (!list_empty(&profile->list)) { + AA_ERROR("%s: internal error, " + "profile '%s' still on global list\n", + __FUNCTION__, + profile->name); + BUG(); + } + aa_put_namespace(profile->ns); + + aa_match_free(profile->file_rules); + + if (profile->name) { + AA_DEBUG("%s: %s\n", __FUNCTION__, profile->name); + kfree(profile->name); + } + + kfree(profile); +} + +/** + * aa_unconfine_tasks - remove tasks on a profile's task context list + * @profile: profile to remove tasks from + * + * Assumes that @profile lock is held. + */ +void aa_unconfine_tasks(struct aa_profile *profile) +{ + while (!list_empty(&profile->task_contexts)) { + struct task_struct *task = + list_entry(profile->task_contexts.next, + struct aa_task_context, list)->task; + task_lock(task); + aa_change_task_context(task, NULL, NULL, 0, NULL); + task_unlock(task); + } +} --- linux-2.6.28.orig/security/apparmor/apparmorfs.c +++ linux-2.6.28/security/apparmor/apparmorfs.c @@ -0,0 +1,281 @@ +/* + * Copyright (C) 1998-2007 Novell/SUSE + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + * + * AppArmor filesystem (part of securityfs) + */ + +#include +#include +#include +#include +#include +#include + +#include "apparmor.h" +#include "inline.h" + +static char *aa_simple_write_to_buffer(const char __user *userbuf, + size_t alloc_size, size_t copy_size, + loff_t *pos, const char *operation) +{ + struct aa_profile *profile; + char *data; + + if (*pos != 0) { + /* only writes from pos 0, that is complete writes */ + data = ERR_PTR(-ESPIPE); + goto out; + } + + /* + * Don't allow confined processes to load/replace/remove profiles. + * No sane person would add rules allowing this to a profile + * but we enforce the restriction anyways. + */ + profile = aa_get_profile(current); + if (profile) { + struct aa_audit sa; + memset(&sa, 0, sizeof(sa)); + sa.operation = operation; + sa.gfp_mask = GFP_KERNEL; + sa.error_code = -EACCES; + data = ERR_PTR(aa_audit_reject(profile, &sa)); + aa_put_profile(profile); + goto out; + } + + data = vmalloc(alloc_size); + if (data == NULL) { + data = ERR_PTR(-ENOMEM); + goto out; + } + + if (copy_from_user(data, userbuf, copy_size)) { + vfree(data); + data = ERR_PTR(-EFAULT); + goto out; + } + +out: + return data; +} + +/* apparmor/profiles */ +extern struct seq_operations apparmorfs_profiles_op; + +static int aa_profiles_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &apparmorfs_profiles_op); +} + + +static int aa_profiles_release(struct inode *inode, struct file *file) +{ + return seq_release(inode, file); +} + +static struct file_operations apparmorfs_profiles_fops = { + .open = aa_profiles_open, + .read = seq_read, + .llseek = seq_lseek, + .release = aa_profiles_release, +}; + +/* apparmor/matching */ +static ssize_t aa_matching_read(struct file *file, char __user *buf, + size_t size, loff_t *ppos) +{ + const char *matching = "pattern=aadfa audit perms=rwxamlk/ user::other"; + + return simple_read_from_buffer(buf, size, ppos, matching, + strlen(matching)); +} + +static struct file_operations apparmorfs_matching_fops = { + .read = aa_matching_read, +}; + +/* apparmor/features */ +static ssize_t aa_features_read(struct file *file, char __user *buf, + size_t size, loff_t *ppos) +{ + const char *features = "file=3.0 capability=2.0 network=1.0 " + "change_hat=1.5 change_profile=1.0 " + "aanamespaces=1.0 rlimit=1.0"; + + return simple_read_from_buffer(buf, size, ppos, features, + strlen(features)); +} + +static struct file_operations apparmorfs_features_fops = { + .read = aa_features_read, +}; + +/* apparmor/.load */ +static ssize_t aa_profile_load(struct file *f, const char __user *buf, + size_t size, loff_t *pos) +{ + char *data; + ssize_t error; + + data = aa_simple_write_to_buffer(buf, size, size, pos, "profile_load"); + + error = PTR_ERR(data); + if (!IS_ERR(data)) { + error = aa_add_profile(data, size); + vfree(data); + } + + return error; +} + + +static struct file_operations apparmorfs_profile_load = { + .write = aa_profile_load +}; + +/* apparmor/.replace */ +static ssize_t aa_profile_replace(struct file *f, const char __user *buf, + size_t size, loff_t *pos) +{ + char *data; + ssize_t error; + + data = aa_simple_write_to_buffer(buf, size, size, pos, + "profile_replace"); + + error = PTR_ERR(data); + if (!IS_ERR(data)) { + error = aa_replace_profile(data, size); + vfree(data); + } + + return error; +} + + +static struct file_operations apparmorfs_profile_replace = { + .write = aa_profile_replace +}; + +/* apparmor/.remove */ +static ssize_t aa_profile_remove(struct file *f, const char __user *buf, + size_t size, loff_t *pos) +{ + char *data; + ssize_t error; + + /* + * aa_remove_profile needs a null terminated string so 1 extra + * byte is allocated and the copied data is null terminated. + */ + data = aa_simple_write_to_buffer(buf, size + 1, size, pos, + "profile_remove"); + + error = PTR_ERR(data); + if (!IS_ERR(data)) { + data[size] = 0; + error = aa_remove_profile(data, size); + vfree(data); + } + + return error; +} + +static struct file_operations apparmorfs_profile_remove = { + .write = aa_profile_remove +}; + +static struct dentry *apparmor_dentry; + +static void aafs_remove(const char *name) +{ + struct dentry *dentry; + + dentry = lookup_one_len(name, apparmor_dentry, strlen(name)); + if (!IS_ERR(dentry)) { + securityfs_remove(dentry); + dput(dentry); + } +} + +static int aafs_create(const char *name, int mask, struct file_operations *fops) +{ + struct dentry *dentry; + + dentry = securityfs_create_file(name, S_IFREG | mask, apparmor_dentry, + NULL, fops); + + return IS_ERR(dentry) ? PTR_ERR(dentry) : 0; +} + +void destroy_apparmorfs(void) +{ + if (apparmor_dentry) { + aafs_remove(".remove"); + aafs_remove(".replace"); + aafs_remove(".load"); + aafs_remove("matching"); + aafs_remove("features"); + aafs_remove("profiles"); + securityfs_remove(apparmor_dentry); + apparmor_dentry = NULL; + } +} + +int create_apparmorfs(void) +{ + int error; + + if (!apparmor_initialized) + return 0; + + if (apparmor_dentry) { + AA_ERROR("%s: AppArmor securityfs already exists\n", + __FUNCTION__); + return -EEXIST; + } + + apparmor_dentry = securityfs_create_dir("apparmor", NULL); + if (IS_ERR(apparmor_dentry)) { + error = PTR_ERR(apparmor_dentry); + apparmor_dentry = NULL; + goto error; + } + error = aafs_create("profiles", 0440, &apparmorfs_profiles_fops); + if (error) + goto error; + error = aafs_create("matching", 0444, &apparmorfs_matching_fops); + if (error) + goto error; + error = aafs_create("features", 0444, &apparmorfs_features_fops); + if (error) + goto error; + error = aafs_create(".load", 0640, &apparmorfs_profile_load); + if (error) + goto error; + error = aafs_create(".replace", 0640, &apparmorfs_profile_replace); + if (error) + goto error; + error = aafs_create(".remove", 0640, &apparmorfs_profile_remove); + if (error) + goto error; + + /* Report that AppArmor fs is enabled */ + info_message("AppArmor Filesystem Enabled"); + return 0; + +error: + destroy_apparmorfs(); + AA_ERROR("Error creating AppArmor securityfs\n"); + apparmor_disable(); + return error; +} + +fs_initcall(create_apparmorfs); + --- linux-2.6.28.orig/security/apparmor/inline.h +++ linux-2.6.28/security/apparmor/inline.h @@ -0,0 +1,250 @@ +/* + * Copyright (C) 1998-2007 Novell/SUSE + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + */ + +#ifndef __INLINE_H +#define __INLINE_H + +#include + +#include "match.h" + +static inline int mediated_filesystem(struct inode *inode) +{ + return !(inode->i_sb->s_flags & MS_NOUSER); +} + +static inline struct aa_task_context *aa_task_context(struct task_struct *task) +{ + return (struct aa_task_context *) rcu_dereference(task->security); +} + +static inline struct aa_namespace *aa_get_namespace(struct aa_namespace *ns) +{ + if (ns) + kref_get(&(ns->count)); + + return ns; +} + +static inline void aa_put_namespace(struct aa_namespace *ns) +{ + if (ns) + kref_put(&ns->count, free_aa_namespace_kref); +} + + +static inline struct aa_namespace *aa_find_namespace(const char *name) +{ + struct aa_namespace *ns = NULL; + + read_lock(&profile_ns_list_lock); + ns = aa_get_namespace(__aa_find_namespace(name, &profile_ns_list)); + read_unlock(&profile_ns_list_lock); + + return ns; +} + +/** + * aa_dup_profile - increment refcount on profile @p + * @p: profile + */ +static inline struct aa_profile *aa_dup_profile(struct aa_profile *p) +{ + if (p) + kref_get(&(p->count)); + + return p; +} + +/** + * aa_put_profile - decrement refcount on profile @p + * @p: profile + */ +static inline void aa_put_profile(struct aa_profile *p) +{ + if (p) + kref_put(&p->count, free_aa_profile_kref); +} + +static inline struct aa_profile *aa_get_profile(struct task_struct *task) +{ + struct aa_task_context *cxt; + struct aa_profile *profile = NULL; + + rcu_read_lock(); + cxt = aa_task_context(task); + if (cxt) { + profile = cxt->profile; + aa_dup_profile(profile); + } + rcu_read_unlock(); + + return profile; +} + +static inline struct aa_profile *aa_find_profile(struct aa_namespace *ns, + const char *name) +{ + struct aa_profile *profile = NULL; + + read_lock(&ns->lock); + profile = aa_dup_profile(__aa_find_profile(name, &ns->profiles)); + read_unlock(&ns->lock); + + return profile; +} + +static inline struct aa_task_context *aa_alloc_task_context(gfp_t flags) +{ + struct aa_task_context *cxt; + + cxt = kzalloc(sizeof(*cxt), flags); + if (cxt) { + INIT_LIST_HEAD(&cxt->list); + INIT_RCU_HEAD(&cxt->rcu); + } + + return cxt; +} + +static inline void aa_free_task_context(struct aa_task_context *cxt) +{ + if (cxt) { + aa_put_profile(cxt->profile); + aa_put_profile(cxt->previous_profile); + kfree(cxt); + } +} + +/** + * lock_profile - lock a profile + * @profile: the profile to lock + * + * While the profile is locked, local interrupts are disabled. This also + * gives us RCU reader safety. + */ +static inline void lock_profile_nested(struct aa_profile *profile, + enum aa_lock_class lock_class) +{ + /* + * Lock the profile. + * + * Need to disable interrupts here because this lock is used in + * the task_free_security hook, which may run in RCU context. + */ + if (profile) + spin_lock_irqsave_nested(&profile->lock, profile->int_flags, + lock_class); +} + +static inline void lock_profile(struct aa_profile *profile) +{ + lock_profile_nested(profile, aa_lock_normal); +} + +/** + * unlock_profile - unlock a profile + * @profile: the profile to unlock + */ +static inline void unlock_profile(struct aa_profile *profile) +{ + /* Unlock the profile. */ + if (profile) + spin_unlock_irqrestore(&profile->lock, profile->int_flags); +} + +/** + * lock_both_profiles - lock two profiles in a deadlock-free way + * @profile1: profile to lock (may be NULL) + * @profile2: profile to lock (may be NULL) + * + * The order in which profiles are passed into lock_both_profiles() / + * unlock_both_profiles() does not matter. + * While the profile is locked, local interrupts are disabled. This also + * gives us RCU reader safety. + */ +static inline void lock_both_profiles(struct aa_profile *profile1, + struct aa_profile *profile2) +{ + /* + * Lock the two profiles. + * + * We need to disable interrupts because the profile locks are + * used in the task_free_security hook, which may run in RCU + * context. + * + * Do not nest spin_lock_irqsave()/spin_unlock_irqresore(): + * interrupts only need to be turned off once. + */ + if (!profile1 || profile1 == profile2) { + if (profile2) + spin_lock_irqsave_nested(&profile2->lock, + profile2->int_flags, + aa_lock_normal); + } else if (profile1 > profile2) { + /* profile1 cannot be NULL here. */ + spin_lock_irqsave_nested(&profile1->lock, profile1->int_flags, + aa_lock_normal); + if (profile2) + spin_lock_nested(&profile2->lock, aa_lock_nested); + + } else { + /* profile2 cannot be NULL here. */ + spin_lock_irqsave_nested(&profile2->lock, profile2->int_flags, + aa_lock_normal); + spin_lock_nested(&profile1->lock, aa_lock_nested); + } +} + +/** + * unlock_both_profiles - unlock two profiles in a deadlock-free way + * @profile1: profile to unlock (may be NULL) + * @profile2: profile to unlock (may be NULL) + * + * The order in which profiles are passed into lock_both_profiles() / + * unlock_both_profiles() does not matter. + * While the profile is locked, local interrupts are disabled. This also + * gives us RCU reader safety. + */ +static inline void unlock_both_profiles(struct aa_profile *profile1, + struct aa_profile *profile2) +{ + /* Unlock the two profiles. */ + if (!profile1 || profile1 == profile2) { + if (profile2) + spin_unlock_irqrestore(&profile2->lock, + profile2->int_flags); + } else if (profile1 > profile2) { + /* profile1 cannot be NULL here. */ + if (profile2) + spin_unlock(&profile2->lock); + spin_unlock_irqrestore(&profile1->lock, profile1->int_flags); + } else { + /* profile2 cannot be NULL here. */ + spin_unlock(&profile1->lock); + spin_unlock_irqrestore(&profile2->lock, profile2->int_flags); + } +} + +static inline unsigned int aa_match(struct aa_dfa *dfa, const char *pathname, + int *audit_mask) +{ + if (dfa) + return aa_dfa_match(dfa, pathname, audit_mask); + if (audit_mask) + *audit_mask = 0; + return 0; +} + +static inline int dfa_audit_mask(struct aa_dfa *dfa, unsigned int state) +{ + return ACCEPT_TABLE2(dfa)[state]; +} + +#endif /* __INLINE_H__ */ --- linux-2.6.28.orig/security/apparmor/match.c +++ linux-2.6.28/security/apparmor/match.c @@ -0,0 +1,364 @@ +/* + * Copyright (C) 2007 Novell/SUSE + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + * + * Regular expression transition table matching + */ + +#include +#include +#include +#include "apparmor.h" +#include "match.h" +#include "inline.h" + +static struct table_header *unpack_table(void *blob, size_t bsize) +{ + struct table_header *table = NULL; + struct table_header th; + size_t tsize; + + if (bsize < sizeof(struct table_header)) + goto out; + + th.td_id = be16_to_cpu(*(u16 *) (blob)); + th.td_flags = be16_to_cpu(*(u16 *) (blob + 2)); + th.td_lolen = be32_to_cpu(*(u32 *) (blob + 8)); + blob += sizeof(struct table_header); + + if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 || + th.td_flags == YYTD_DATA8)) + goto out; + + tsize = table_size(th.td_lolen, th.td_flags); + if (bsize < tsize) + goto out; + + table = kmalloc(tsize, GFP_KERNEL); + if (table) { + *table = th; + if (th.td_flags == YYTD_DATA8) + UNPACK_ARRAY(table->td_data, blob, th.td_lolen, + u8, byte_to_byte); + else if (th.td_flags == YYTD_DATA16) + UNPACK_ARRAY(table->td_data, blob, th.td_lolen, + u16, be16_to_cpu); + else + UNPACK_ARRAY(table->td_data, blob, th.td_lolen, + u32, be32_to_cpu); + } + +out: + return table; +} + +int unpack_dfa(struct aa_dfa *dfa, void *blob, size_t size) +{ + int hsize, i; + int error = -ENOMEM; + + /* get dfa table set header */ + if (size < sizeof(struct table_set_header)) + goto fail; + + if (ntohl(*(u32 *)blob) != YYTH_MAGIC) + goto fail; + + hsize = ntohl(*(u32 *)(blob + 4)); + if (size < hsize) + goto fail; + + blob += hsize; + size -= hsize; + + error = -EPROTO; + while (size > 0) { + struct table_header *table; + table = unpack_table(blob, size); + if (!table) + goto fail; + + switch(table->td_id) { + case YYTD_ID_ACCEPT: + case YYTD_ID_ACCEPT2: + case YYTD_ID_BASE: + dfa->tables[table->td_id - 1] = table; + if (table->td_flags != YYTD_DATA32) + goto fail; + break; + case YYTD_ID_DEF: + case YYTD_ID_NXT: + case YYTD_ID_CHK: + dfa->tables[table->td_id - 1] = table; + if (table->td_flags != YYTD_DATA16) + goto fail; + break; + case YYTD_ID_EC: + dfa->tables[table->td_id - 1] = table; + if (table->td_flags != YYTD_DATA8) + goto fail; + break; + default: + kfree(table); + goto fail; + } + + blob += table_size(table->td_lolen, table->td_flags); + size -= table_size(table->td_lolen, table->td_flags); + } + + return 0; + +fail: + for (i = 0; i < ARRAY_SIZE(dfa->tables); i++) { + if (dfa->tables[i]) { + kfree(dfa->tables[i]); + dfa->tables[i] = NULL; + } + } + return error; +} + +/** + * verify_dfa - verify that all the transitions and states in the dfa tables + * are in bounds. + * @dfa: dfa to test + * + * assumes dfa has gone through the verification done by unpacking + */ +int verify_dfa(struct aa_dfa *dfa) +{ + size_t i, state_count, trans_count; + int error = -EPROTO; + + /* check that required tables exist */ + if (!(dfa->tables[YYTD_ID_ACCEPT - 1] && + dfa->tables[YYTD_ID_ACCEPT2 - 1] && + dfa->tables[YYTD_ID_DEF - 1] && + dfa->tables[YYTD_ID_BASE - 1] && + dfa->tables[YYTD_ID_NXT - 1] && + dfa->tables[YYTD_ID_CHK - 1])) + goto out; + + /* accept.size == default.size == base.size */ + state_count = dfa->tables[YYTD_ID_BASE - 1]->td_lolen; + if (!(state_count == dfa->tables[YYTD_ID_DEF - 1]->td_lolen && + state_count == dfa->tables[YYTD_ID_ACCEPT - 1]->td_lolen && + state_count == dfa->tables[YYTD_ID_ACCEPT2 - 1]->td_lolen)) + goto out; + + /* next.size == chk.size */ + trans_count = dfa->tables[YYTD_ID_NXT - 1]->td_lolen; + if (trans_count != dfa->tables[YYTD_ID_CHK - 1]->td_lolen) + goto out; + + /* if equivalence classes then its table size must be 256 */ + if (dfa->tables[YYTD_ID_EC - 1] && + dfa->tables[YYTD_ID_EC - 1]->td_lolen != 256) + goto out; + + for (i = 0; i < state_count; i++) { + if (DEFAULT_TABLE(dfa)[i] >= state_count) + goto out; + if (BASE_TABLE(dfa)[i] >= trans_count + 256) + goto out; + } + + for (i = 0; i < trans_count ; i++) { + if (NEXT_TABLE(dfa)[i] >= state_count) + goto out; + if (CHECK_TABLE(dfa)[i] >= state_count) + goto out; + } + + /* verify accept permissions */ + for (i = 0; i < state_count; i++) { + int mode = ACCEPT_TABLE(dfa)[i]; + + if (mode & ~AA_VALID_PERM_MASK) + goto out; + if (ACCEPT_TABLE2(dfa)[i] & ~AA_VALID_PERM2_MASK) + goto out; + + /* if any exec modifier is set MAY_EXEC must be set */ + if ((mode & AA_USER_EXEC_TYPE) && !(mode & AA_USER_EXEC)) + goto out; + if ((mode & AA_OTHER_EXEC_TYPE) && !(mode & AA_OTHER_EXEC)) + goto out; + } + + error = 0; +out: + return error; +} + +struct aa_dfa *aa_match_alloc(void) +{ + return kzalloc(sizeof(struct aa_dfa), GFP_KERNEL); +} + +void aa_match_free(struct aa_dfa *dfa) +{ + if (dfa) { + int i; + + for (i = 0; i < ARRAY_SIZE(dfa->tables); i++) + kfree(dfa->tables[i]); + } + kfree(dfa); +} + +/** + * aa_dfa_next_state_len - traverse @dfa to find state @str stops at + * @dfa: the dfa to match @str against + * @start: the state of the dfa to start matching in + * @str: the string of bytes to match against the dfa + * @len: length of the string of bytes to match + * + * aa_dfa_next_state will match @str against the dfa and return the state it + * finished matching in. The final state can be used to look up the accepting + * label, or as the start state of a continuing match. + * + * aa_dfa_next_state could be implement using this function by doing + * return aa_dfa_next_state_len(dfa, start, str, strlen(str)); + * but that would require traversing the string twice and be slightly + * slower. + */ +unsigned int aa_dfa_next_state_len(struct aa_dfa *dfa, unsigned int start, + const char *str, int len) +{ + u16 *def = DEFAULT_TABLE(dfa); + u32 *base = BASE_TABLE(dfa); + u16 *next = NEXT_TABLE(dfa); + u16 *check = CHECK_TABLE(dfa); + unsigned int state = start, pos; + + if (state == 0) + return 0; + + /* current state is , matching character *str */ + if (dfa->tables[YYTD_ID_EC - 1]) { + u8 *equiv = EQUIV_TABLE(dfa); + for (; len; len--) { + pos = base[state] + equiv[(u8)*str++]; + if (check[pos] == state) + state = next[pos]; + else + state = def[state]; + } + } else { + for (; len; len--) { + pos = base[state] + (u8)*str++; + if (check[pos] == state) + state = next[pos]; + else + state = def[state]; + } + } + return state; +} + +/** + * aa_dfa_next_state - traverse @dfa to find state @str stops at + * @dfa: the dfa to match @str against + * @start: the state of the dfa to start matching in + * @str: the null terminated string of bytes to match against the dfa + * + * aa_dfa_next_state will match @str against the dfa and return the state it + * finished matching in. The final state can be used to look up the accepting + * label, or as the start state of a continuing match. + */ +unsigned int aa_dfa_next_state(struct aa_dfa *dfa, unsigned int start, + const char *str) +{ + u16 *def = DEFAULT_TABLE(dfa); + u32 *base = BASE_TABLE(dfa); + u16 *next = NEXT_TABLE(dfa); + u16 *check = CHECK_TABLE(dfa); + unsigned int state = start, pos; + + if (state == 0) + return 0; + + /* current state is , matching character *str */ + if (dfa->tables[YYTD_ID_EC - 1]) { + u8 *equiv = EQUIV_TABLE(dfa); + while (*str) { + pos = base[state] + equiv[(u8)*str++]; + if (check[pos] == state) + state = next[pos]; + else + state = def[state]; + } + } else { + while (*str) { + pos = base[state] + (u8)*str++; + if (check[pos] == state) + state = next[pos]; + else + state = def[state]; + } + } + return state; +} + +/** + * aa_dfa_null_transition - step to next state after null character + * @dfa: the dfa to match against + * @start: the state of the dfa to start matching in + * + * aa_dfa_null_transition transitions to the next state after a null + * character which is not used in standard matching and is only + * used to seperate pairs. + */ +unsigned int aa_dfa_null_transition(struct aa_dfa *dfa, unsigned int start) +{ + return aa_dfa_next_state_len(dfa, start, "", 1); +} + +/** + * aa_dfa_match - find accept perm for @str in @dfa + * @dfa: the dfa to match @str against + * @str: the string to match against the dfa + * @audit_mask: the audit_mask for the final state + * + * aa_dfa_match will match @str and return the accept perms for the + * final state. + */ +unsigned int aa_dfa_match(struct aa_dfa *dfa, const char *str, int *audit_mask) +{ + int state = aa_dfa_next_state(dfa, DFA_START, str); + if (audit_mask) + *audit_mask = dfa_audit_mask(dfa, state); + return ACCEPT_TABLE(dfa)[state]; +} + +/** + * aa_match_state - find accept perm and state for @str in @dfa + * @dfa: the dfa to match @str against + * @start: the state to start the match from + * @str: the string to match against the dfa + * @final: the state that the match finished in + * + * aa_match_state will match @str and return the accept perms, and @final + * state, the match occured in. + */ +unsigned int aa_match_state(struct aa_dfa *dfa, unsigned int start, + const char *str, unsigned int *final) +{ + unsigned int state; + if (dfa) { + state = aa_dfa_next_state(dfa, start, str); + if (final) + *final = state; + return ACCEPT_TABLE(dfa)[state]; + } + if (final) + *final = 0; + return 0; +} + --- linux-2.6.28.orig/security/apparmor/apparmor.h +++ linux-2.6.28/security/apparmor/apparmor.h @@ -0,0 +1,403 @@ +/* + * Copyright (C) 1998-2007 Novell/SUSE + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + * + * AppArmor internal prototypes + */ + +#ifndef __APPARMOR_H +#define __APPARMOR_H + +#include +#include +#include +#include +#include +#include +#include + +/* + * We use MAY_READ, MAY_WRITE, MAY_EXEC, MAY_APPEND and the following flags + * for profile permissions + */ +#define AA_MAY_LINK 0x0010 +#define AA_MAY_LOCK 0x0020 +#define AA_EXEC_MMAP 0x0040 +#define AA_MAY_MOUNT 0x0080 /* no direct audit mapping */ +#define AA_EXEC_UNSAFE 0x0100 +#define AA_EXEC_INHERIT 0x0200 +#define AA_EXEC_MOD_0 0x0400 +#define AA_EXEC_MOD_1 0x0800 +#define AA_EXEC_MOD_2 0x1000 +#define AA_EXEC_MOD_3 0x2000 + +#define AA_BASE_PERMS (MAY_READ | MAY_WRITE | MAY_EXEC | \ + MAY_APPEND | AA_MAY_LINK | \ + AA_MAY_LOCK | AA_EXEC_MMAP | \ + AA_MAY_MOUNT | AA_EXEC_UNSAFE | \ + AA_EXEC_INHERIT | AA_EXEC_MOD_0 | \ + AA_EXEC_MOD_1 | AA_EXEC_MOD_2 | \ + AA_EXEC_MOD_3) + +#define AA_EXEC_MODIFIERS (AA_EXEC_MOD_0 | AA_EXEC_MOD_1 | \ + AA_EXEC_MOD_2 | AA_EXEC_MOD_3) + +#define AA_EXEC_TYPE (AA_EXEC_UNSAFE | AA_EXEC_INHERIT | \ + AA_EXEC_MODIFIERS) + +#define AA_EXEC_UNCONFINED AA_EXEC_MOD_0 +#define AA_EXEC_PROFILE AA_EXEC_MOD_1 +#define AA_EXEC_CHILD (AA_EXEC_MOD_0 | AA_EXEC_MOD_1) +/* remaining exec modes are index into profile name table */ +#define AA_EXEC_INDEX(mode) ((mode & AA_EXEC_MODIFIERS) >> 10) + +#define AA_USER_SHIFT 0 +#define AA_OTHER_SHIFT 14 + +#define AA_USER_PERMS (AA_BASE_PERMS << AA_USER_SHIFT) +#define AA_OTHER_PERMS (AA_BASE_PERMS << AA_OTHER_SHIFT) + +#define AA_FILE_PERMS (AA_USER_PERMS | AA_OTHER_PERMS) + +#define AA_LINK_BITS ((AA_MAY_LINK << AA_USER_SHIFT) | \ + (AA_MAY_LINK << AA_OTHER_SHIFT)) + +#define AA_USER_EXEC (MAY_EXEC << AA_USER_SHIFT) +#define AA_OTHER_EXEC (MAY_EXEC << AA_OTHER_SHIFT) + +#define AA_USER_EXEC_TYPE (AA_EXEC_TYPE << AA_USER_SHIFT) +#define AA_OTHER_EXEC_TYPE (AA_EXEC_TYPE << AA_OTHER_SHIFT) + +#define AA_EXEC_BITS (AA_USER_EXEC | AA_OTHER_EXEC) + +#define ALL_AA_EXEC_UNSAFE ((AA_EXEC_UNSAFE << AA_USER_SHIFT) | \ + (AA_EXEC_UNSAFE << AA_OTHER_SHIFT)) + +#define ALL_AA_EXEC_TYPE (AA_USER_EXEC_TYPE | AA_OTHER_EXEC_TYPE) + +/* overloaded permissions for link pairs */ +#define AA_LINK_SUBSET_TEST 0x0020 + +#define AA_USER_PTRACE 0x10000000 +#define AA_OTHER_PTRACE 0x20000000 +#define AA_PTRACE_PERMS (AA_USER_PTRACE | AA_OTHER_PTRACE) + +/* shared permissions that are not duplicated in user::other */ +#define AA_CHANGE_HAT 0x40000000 +#define AA_CHANGE_PROFILE 0x80000000 + +#define AA_SHARED_PERMS (AA_CHANGE_HAT | AA_CHANGE_PROFILE) + +#define AA_VALID_PERM_MASK (AA_FILE_PERMS | AA_PTRACE_PERMS | \ + AA_SHARED_PERMS) + +/* audit bits for the second accept field */ +#define AUDIT_FILE_MASK 0x1fc07f +#define AUDIT_QUIET_MASK(mask) ((mask >> 7) & AUDIT_FILE_MASK) +#define AA_VALID_PERM2_MASK 0x0fffffff + +#define AA_SECURE_EXEC_NEEDED 1 + +/* Control parameters (0 or 1), settable thru module/boot flags or + * via /sys/kernel/security/apparmor/control */ +extern int apparmor_complain; +extern int apparmor_debug; +extern int apparmor_audit; +extern int apparmor_logsyscall; +extern unsigned int apparmor_path_max; + +#define PROFILE_COMPLAIN(_profile) \ + (apparmor_complain == 1 || ((_profile) && (_profile)->flags.complain)) + +#define APPARMOR_COMPLAIN(_cxt) \ + (apparmor_complain == 1 || \ + ((_cxt) && (_cxt)->profile && (_cxt)->profile->flags.complain)) + +#define PROFILE_AUDIT(_profile) \ + (apparmor_audit == 1 || ((_profile) && (_profile)->flags.audit)) + +#define APPARMOR_AUDIT(_cxt) \ + (apparmor_audit == 1 || \ + ((_cxt) && (_cxt)->profile && (_cxt)->profile->flags.audit)) + +#define PROFILE_IS_HAT(_profile) \ + ((_profile) && (_profile)->flags.hat) + +/* + * DEBUG remains global (no per profile flag) since it is mostly used in sysctl + * which is not related to profile accesses. + */ + +#define AA_DEBUG(fmt, args...) \ + do { \ + if (apparmor_debug) \ + printk(KERN_DEBUG "AppArmor: " fmt, ##args); \ + } while (0) + +#define AA_ERROR(fmt, args...) printk(KERN_ERR "AppArmor: " fmt, ##args) + +/* struct aa_rlimit - rlimits settings for the profile + * @mask: which hard limits to set + * @limits: rlimit values that override task limits + * + * AppArmor rlimits are used to set confined task rlimits. Only the + * limits specified in @mask will be controlled by apparmor. + */ +struct aa_rlimit { + unsigned int mask; + struct rlimit limits[RLIM_NLIMITS]; +}; + +struct aa_profile; + +/* struct aa_namespace - namespace for a set of profiles + * @name: the name of the namespace + * @list: list the namespace is on + * @profiles: list of profile in the namespace + * @profile_count: the number of profiles in the namespace + * @null_complain_profile: special profile used for learning in this namespace + * @count: reference count on the namespace + * @lock: lock for adding/removing profile to the namespace + */ +struct aa_namespace { + char *name; + struct list_head list; + struct list_head profiles; + int profile_count; + struct aa_profile *null_complain_profile; + + struct kref count; + rwlock_t lock; +}; + +/* struct aa_profile - basic confinement data + * @name: the profiles name + * @list: list this profile is on + * @ns: namespace the profile is in + * @file_rules: dfa containing the profiles file rules + * @flags: flags controlling profile behavior + * @isstale: flag indicating if profile is stale + * @set_caps: capabilities that are being set + * @capabilities: capabilities mask + * @audit_caps: caps that are to be audited + * @quiet_caps: caps that should not be audited + * @capabilities: capabilities granted by the process + * @rlimits: rlimits for the profile + * @task_count: how many tasks the profile is attached to + * @count: reference count of the profile + * @task_contexts: list of tasks confined by profile + * @lock: lock for the task_contexts list + * @network_families: basic network permissions + * @audit_network: which network permissions to force audit + * @quiet_network: which network permissions to quiet rejects + * + * The AppArmor profile contains the basic confinement data. Each profile + * has a name, and all nonstale profile are in a profile namespace. + * + * The task_contexts list and the isstale flag are protected by the + * profile lock. + * + * If a task context is moved between two profiles, we first need to grab + * both profile locks. lock_both_profiles() does that in a deadlock-safe + * way. + */ +struct aa_profile { + char *name; + struct list_head list; + struct aa_namespace *ns; + + int exec_table_size; + char **exec_table; + struct aa_dfa *file_rules; + struct { + int hat; + int complain; + int audit; + } flags; + int isstale; + + kernel_cap_t set_caps; + kernel_cap_t capabilities; + kernel_cap_t audit_caps; + kernel_cap_t quiet_caps; + + struct aa_rlimit rlimits; + unsigned int task_count; + + struct kref count; + struct list_head task_contexts; + spinlock_t lock; + unsigned long int_flags; + u16 network_families[AF_MAX]; + u16 audit_network[AF_MAX]; + u16 quiet_network[AF_MAX]; +}; + +extern struct list_head profile_ns_list; +extern rwlock_t profile_ns_list_lock; +extern struct mutex aa_interface_lock; + +/** + * struct aa_task_context - primary label for confined tasks + * @profile: the current profile + * @previous_profile: profile the task may return to + * @cookie: magic value the task must know for returning to @previous_profile + * @list: list this aa_task_context is on + * @task: task that the aa_task_context confines + * @rcu: rcu head used when freeing the aa_task_context + * @caps_logged: caps that have previously generated log entries + * + * Contains the task's current profile (which could change due to + * change_hat). Plus the hat_magic needed during change_hat. + */ +struct aa_task_context { + struct aa_profile *profile; + struct aa_profile *previous_profile; + u64 cookie; + struct list_head list; + struct task_struct *task; + struct rcu_head rcu; + kernel_cap_t caps_logged; +}; + +extern struct aa_namespace *default_namespace; + +/* aa_audit - AppArmor auditing structure + * Structure is populated by access control code and passed to aa_audit which + * provides for a single point of logging. + */ + +struct aa_audit { + const char *operation; + gfp_t gfp_mask; + const char *info; + const char *name; + const char *name2; + const char *name3; + int request_mask, denied_mask, audit_mask; + int rlimit; + struct iattr *iattr; + pid_t task, parent; + int family, type, protocol; + int error_code; +}; + +/* Flags for the permission check functions */ +#define AA_CHECK_FD 1 /* coming from a file descriptor */ +#define AA_CHECK_DIR 2 /* file type is directory */ + +/* lock subtypes so lockdep does not raise false dependencies */ +enum aa_lock_class { + aa_lock_normal, + aa_lock_nested, + aa_lock_task_release +}; + +/* main.c */ +extern int alloc_default_namespace(void); +extern void free_default_namespace(void); +extern int aa_audit_message(struct aa_profile *profile, struct aa_audit *sa, + int type); +void aa_audit_hint(struct aa_profile *profile, struct aa_audit *sa); +void aa_audit_status(struct aa_profile *profile, struct aa_audit *sa); +int aa_audit_reject(struct aa_profile *profile, struct aa_audit *sa); +extern int aa_audit_syscallreject(struct aa_profile *profile, gfp_t gfp, + const char *); +extern int aa_audit(struct aa_profile *profile, struct aa_audit *); + +extern int aa_attr(struct aa_profile *profile, struct dentry *dentry, + struct vfsmount *mnt, struct iattr *iattr); +extern int aa_perm_xattr(struct aa_profile *profile, const char *operation, + struct dentry *dentry, struct vfsmount *mnt, + int mask, int check); +extern int aa_capability(struct aa_task_context *cxt, int cap); +extern int aa_perm(struct aa_profile *profile, const char *operation, + struct dentry *dentry, struct vfsmount *mnt, int mask, + int check); +extern int aa_perm_dir(struct aa_profile *profile, const char *operation, + struct dentry *dentry, struct vfsmount *mnt, + int mask); +extern int aa_perm_path(struct aa_profile *, const char *operation, + const char *name, int mask, uid_t uid); +extern int aa_link(struct aa_profile *profile, + struct dentry *link, struct vfsmount *link_mnt, + struct dentry *target, struct vfsmount *target_mnt); +extern int aa_clone(struct task_struct *task); +extern int aa_register(struct linux_binprm *bprm); +extern void aa_release(struct task_struct *task); +extern int aa_change_hat(const char *id, u64 hat_magic); +extern int aa_change_profile(const char *ns_name, const char *name); +extern struct aa_profile *__aa_replace_profile(struct task_struct *task, + struct aa_profile *profile); +extern struct aa_task_context *lock_task_and_profiles(struct task_struct *task, + struct aa_profile *profile); +extern void unlock_task_and_profiles(struct task_struct *task, + struct aa_task_context *cxt, + struct aa_profile *profile); +extern void aa_change_task_context(struct task_struct *task, + struct aa_task_context *new_cxt, + struct aa_profile *profile, u64 cookie, + struct aa_profile *previous_profile); +extern int aa_may_ptrace(struct aa_task_context *cxt, + struct aa_profile *tracee); +extern int aa_net_perm(struct aa_profile *profile, char *operation, + int family, int type, int protocol); +extern int aa_revalidate_sk(struct sock *sk, char *operation); +extern int aa_task_setrlimit(struct aa_profile *profile, unsigned int resource, + struct rlimit *new_rlim); +extern void aa_set_rlimits(struct task_struct *task, struct aa_profile *profile); + + +/* lsm.c */ +extern int apparmor_initialized; +extern void info_message(const char *str); +extern void apparmor_disable(void); + +/* list.c */ +extern struct aa_namespace *__aa_find_namespace(const char *name, + struct list_head *list); +extern struct aa_profile *__aa_find_profile(const char *name, + struct list_head *list); +extern void aa_profile_ns_list_release(void); + +/* module_interface.c */ +extern ssize_t aa_add_profile(void *, size_t); +extern ssize_t aa_replace_profile(void *, size_t); +extern ssize_t aa_remove_profile(char *, size_t); +extern struct aa_namespace *alloc_aa_namespace(char *name); +extern void free_aa_namespace(struct aa_namespace *ns); +extern void free_aa_namespace_kref(struct kref *kref); +extern struct aa_profile *alloc_aa_profile(void); +extern void free_aa_profile(struct aa_profile *profile); +extern void free_aa_profile_kref(struct kref *kref); +extern void aa_unconfine_tasks(struct aa_profile *profile); + +/* procattr.c */ +extern int aa_getprocattr(struct aa_profile *profile, char **string, + unsigned *len); +extern int aa_setprocattr_changehat(char *args); +extern int aa_setprocattr_changeprofile(char *args); +extern int aa_setprocattr_setprofile(struct task_struct *task, char *args); + +/* apparmorfs.c */ +extern int create_apparmorfs(void); +extern void destroy_apparmorfs(void); + +/* match.c */ +extern struct aa_dfa *aa_match_alloc(void); +extern void aa_match_free(struct aa_dfa *dfa); +extern int unpack_dfa(struct aa_dfa *dfa, void *blob, size_t size); +extern int verify_dfa(struct aa_dfa *dfa); +extern unsigned int aa_dfa_match(struct aa_dfa *dfa, const char *str, int *); +extern unsigned int aa_dfa_next_state(struct aa_dfa *dfa, unsigned int start, + const char *str); +extern unsigned int aa_match_state(struct aa_dfa *dfa, unsigned int start, + const char *str, unsigned int *final); +extern unsigned int aa_dfa_null_transition(struct aa_dfa *dfa, + unsigned int start); + +#endif /* __APPARMOR_H */ --- linux-2.6.28.orig/security/apparmor/match.h +++ linux-2.6.28/security/apparmor/match.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2007 Novell/SUSE + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + * + * AppArmor submodule (match) prototypes + */ + +#ifndef __MATCH_H +#define __MATCH_H + +#define DFA_START 1 + +/** + * The format used for transition tables is based on the GNU flex table + * file format (--tables-file option; see Table File Format in the flex + * info pages and the flex sources for documentation). The magic number + * used in the header is 0x1B5E783D insted of 0xF13C57B1 though, because + * the YY_ID_CHK (check) and YY_ID_DEF (default) tables are used + * slightly differently (see the apparmor-parser package). + */ + +#define YYTH_MAGIC 0x1B5E783D + +struct table_set_header { + u32 th_magic; /* YYTH_MAGIC */ + u32 th_hsize; + u32 th_ssize; + u16 th_flags; + char th_version[]; +}; + +#define YYTD_ID_ACCEPT 1 +#define YYTD_ID_BASE 2 +#define YYTD_ID_CHK 3 +#define YYTD_ID_DEF 4 +#define YYTD_ID_EC 5 +#define YYTD_ID_META 6 +#define YYTD_ID_ACCEPT2 7 +#define YYTD_ID_NXT 8 + + +#define YYTD_DATA8 1 +#define YYTD_DATA16 2 +#define YYTD_DATA32 4 + +struct table_header { + u16 td_id; + u16 td_flags; + u32 td_hilen; + u32 td_lolen; + char td_data[]; +}; + +#define DEFAULT_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_DEF - 1]->td_data)) +#define BASE_TABLE(DFA) ((u32 *)((DFA)->tables[YYTD_ID_BASE - 1]->td_data)) +#define NEXT_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_NXT - 1]->td_data)) +#define CHECK_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_CHK - 1]->td_data)) +#define EQUIV_TABLE(DFA) ((u8 *)((DFA)->tables[YYTD_ID_EC - 1]->td_data)) +#define ACCEPT_TABLE(DFA) ((u32 *)((DFA)->tables[YYTD_ID_ACCEPT - 1]->td_data)) +#define ACCEPT_TABLE2(DFA) ((u32 *)((DFA)->tables[YYTD_ID_ACCEPT2 -1]->td_data)) + +struct aa_dfa { + struct table_header *tables[YYTD_ID_NXT]; +}; + +#define byte_to_byte(X) (X) + +#define UNPACK_ARRAY(TABLE, BLOB, LEN, TYPE, NTOHX) \ + do { \ + typeof(LEN) __i; \ + TYPE *__t = (TYPE *) TABLE; \ + TYPE *__b = (TYPE *) BLOB; \ + for (__i = 0; __i < LEN; __i++) { \ + __t[__i] = NTOHX(__b[__i]); \ + } \ + } while (0) + +static inline size_t table_size(size_t len, size_t el_size) +{ + return ALIGN(sizeof(struct table_header) + len * el_size, 8); +} + +#endif /* __MATCH_H */ --- linux-2.6.28.orig/security/apparmor/Kconfig +++ linux-2.6.28/security/apparmor/Kconfig @@ -0,0 +1,43 @@ +config SECURITY_APPARMOR + bool "AppArmor support" + depends on SECURITY + select AUDIT + select SECURITYFS + help + This enables the AppArmor security module. + Required userspace tools (if they are not included in your + distribution) and further information may be found at + + + If you are unsure how to answer this question, answer N. + +config SECURITY_APPARMOR_BOOTPARAM_VALUE + int "AppArmor boot parameter default value" + depends on SECURITY_APPARMOR + range 0 1 + default 1 + help + This option sets the default value for the kernel parameter + 'apparmor', which allows AppArmor to be enabled or disabled + at boot. If this option is set to 0 (zero), the AppArmor + kernel parameter will default to 0, disabling AppArmor at + bootup. If this option is set to 1 (one), the AppArmor + kernel parameter will default to 1, enabling AppArmor at + bootup. + + If you are unsure how to answer this question, answer 1. + +config SECURITY_APPARMOR_DISABLE + bool "AppArmor runtime disable" + depends on SECURITY_APPARMOR + default n + help + This option enables writing to a apparmorfs node 'disable', which + allows AppArmor to be disabled at runtime prior to the policy load. + AppArmor will then remain disabled until the next boot. + This option is similar to the apparmor.enabled=0 boot parameter, + but is to support runtime disabling of AppArmor, e.g. from + /sbin/init, for portability across platforms where boot + parameters are difficult to employ. + + If you are unsure how to answer this question, answer N. --- linux-2.6.28.orig/security/apparmor/procattr.c +++ linux-2.6.28/security/apparmor/procattr.c @@ -0,0 +1,195 @@ +/* + * Copyright (C) 1998-2007 Novell/SUSE + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + * + * AppArmor /proc/pid/attr handling + */ + +#include "apparmor.h" +#include "inline.h" + +int aa_getprocattr(struct aa_profile *profile, char **string, unsigned *len) +{ + char *str; + + if (profile) { + const char *mode_str = PROFILE_COMPLAIN(profile) ? + " (complain)" : " (enforce)"; + int mode_len, name_len, ns_len = 0; + + mode_len = strlen(mode_str); + name_len = strlen(profile->name); + if (profile->ns != default_namespace) + ns_len = strlen(profile->ns->name) + 2; + *len = mode_len + ns_len + name_len + 1; + str = kmalloc(*len, GFP_ATOMIC); + if (!str) + return -ENOMEM; + + if (ns_len) { + *str++ = ':'; + memcpy(str, profile->ns->name, ns_len - 2); + str += ns_len - 2; + *str++ = ':'; + } + memcpy(str, profile->name, name_len); + str += name_len; + memcpy(str, mode_str, mode_len); + str += mode_len; + *str++ = '\n'; + str -= *len; + } else { + const char *unconfined_str = "unconfined\n"; + + *len = strlen(unconfined_str); + str = kmalloc(*len, GFP_ATOMIC); + if (!str) + return -ENOMEM; + + memcpy(str, unconfined_str, *len); + } + *string = str; + + return 0; +} + +static char *split_token_from_name(const char *op, char *args, u64 *cookie) +{ + char *name; + + *cookie = simple_strtoull(args, &name, 16); + if ((name == args) || *name != '^') { + AA_ERROR("%s: Invalid input '%s'", op, args); + return ERR_PTR(-EINVAL); + } + + name++; /* skip ^ */ + if (!*name) + name = NULL; + return name; +} + +int aa_setprocattr_changehat(char *args) +{ + char *hat; + u64 cookie; + + hat = split_token_from_name("change_hat", args, &cookie); + if (IS_ERR(hat)) + return PTR_ERR(hat); + + if (!hat && !cookie) { + AA_ERROR("change_hat: Invalid input, NULL hat and NULL magic"); + return -EINVAL; + } + + AA_DEBUG("%s: Magic 0x%llx Hat '%s'\n", + __FUNCTION__, cookie, hat ? hat : NULL); + + return aa_change_hat(hat, cookie); +} + +int aa_setprocattr_changeprofile(char *args) +{ + char *name = args, *ns_name = NULL; + + if (name[0] == ':') { + char *split = strchr(&name[1], ':'); + if (split) { + *split = 0; + ns_name = &name[1]; + name = split + 1; + } + } + + return aa_change_profile(ns_name, name); +} + +int aa_setprocattr_setprofile(struct task_struct *task, char *args) +{ + struct aa_profile *old_profile, *new_profile; + struct aa_namespace *ns; + struct aa_audit sa; + char *name, *ns_name = NULL; + + memset(&sa, 0, sizeof(sa)); + sa.operation = "profile_set"; + sa.gfp_mask = GFP_KERNEL; + sa.task = task->pid; + + AA_DEBUG("%s: current %d\n", + __FUNCTION__, current->pid); + + name = args; + if (args[0] != '/') { + char *split = strchr(args, ':'); + if (split) { + *split = 0; + ns_name = args; + name = split + 1; + } + } + if (ns_name) + ns = aa_find_namespace(ns_name); + else + ns = aa_get_namespace(default_namespace); + if (!ns) { + sa.name = ns_name; + sa.info = "unknown namespace"; + aa_audit_reject(NULL, &sa); + aa_put_namespace(ns); + return -EINVAL; + } + +repeat: + if (strcmp(name, "unconfined") == 0) + new_profile = NULL; + else { + new_profile = aa_find_profile(ns, name); + if (!new_profile) { + sa.name = ns_name; + sa.name2 = name; + sa.info = "unknown profile"; + aa_audit_reject(NULL, &sa); + aa_put_namespace(ns); + return -EINVAL; + } + } + + old_profile = __aa_replace_profile(task, new_profile); + if (IS_ERR(old_profile)) { + int error; + + aa_put_profile(new_profile); + error = PTR_ERR(old_profile); + if (error == -ESTALE) + goto repeat; + aa_put_namespace(ns); + return error; + } + + if (new_profile) { + sa.name = ns_name; + sa.name2 = name; + sa.name3 = old_profile ? old_profile->name : + "unconfined"; + aa_audit_status(NULL, &sa); + } else { + if (old_profile) { + sa.name = "unconfined"; + sa.name2 = old_profile->name; + aa_audit_status(NULL, &sa); + } else { + sa.info = "task is unconfined"; + aa_audit_status(NULL, &sa); + } + } + aa_put_namespace(ns); + aa_put_profile(old_profile); + aa_put_profile(new_profile); + return 0; +} --- linux-2.6.28.orig/security/apparmor/Makefile +++ linux-2.6.28/security/apparmor/Makefile @@ -0,0 +1,18 @@ +# Makefile for AppArmor Linux Security Module +# +obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o + +apparmor-y := main.o list.o procattr.o lsm.o apparmorfs.o \ + module_interface.o match.o + +quiet_cmd_make-caps = GEN $@ +cmd_make-caps = sed -n -e "/CAP_FS_MASK/d" -e "s/^\#define[ \\t]\\+CAP_\\([A-Z0-9_]\\+\\)[ \\t]\\+\\([0-9]\\+\\)\$$/[\\2] = \"\\1\",/p" $< | tr A-Z a-z > $@ + +quiet_cmd_make-af = GEN $@ +cmd_make-af = sed -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e "s/^\#define[ \\t]\\+AF_\\([A-Z0-9_]\\+\\)[ \\t]\\+\\([0-9]\\+\\)\\(.*\\)\$$/[\\2] = \"\\1\",/p" $< | tr A-Z a-z > $@ + +$(obj)/main.o : $(obj)/capability_names.h $(obj)/af_names.h +$(obj)/capability_names.h : $(srctree)/include/linux/capability.h + $(call cmd,make-caps) +$(obj)/af_names.h : $(srctree)/include/linux/socket.h + $(call cmd,make-af) --- linux-2.6.28.orig/security/apparmor/locking.txt +++ linux-2.6.28/security/apparmor/locking.txt @@ -0,0 +1,68 @@ +Locking in AppArmor +=================== + +Lock hierarchy: + + aa_interface_lock + profile_list_lock + aa_profile->lock + task_lock() + + +Which lock protects what? + + /-----------------------+-------------------------------\ + | Variable | Lock | + >-----------------------+-------------------------------< + | profile_list | profile_list_lock | + +-----------------------+-------------------------------+ + | aa_profile | (reference count) | + +-----------------------+-------------------------------+ + | aa_profile-> | aa_profile->lock | + | isstale, | | + | task_contexts | | + +-----------------------+-------------------------------+ + | task_struct->security | read: RCU | + | | write: task_lock() | + +-----------------------+-------------------------------+ + | aa_profile->sub | handle on the profile (list | + | | is never modified) | + \-----------------------+-------------------------------/ + +(Obviously, the list_heads embedded in data structures are always +protected with the lock that also protects the list.) + +When moving a task context from one profile to another, we grab both +profile locks with lock_both_profiles(). This ensures that both locks +are always taken in the same order, and so we won't deadlock. + +Since task_struct->security is RCU protected the aa_task_struct it +references is only guarenteed to exist for the rcu cycle. Where +aa_task_context->profile is needed in blocking operations the +profile's reference count is incremented and the profile reference +is used. + +Profiles on profile_list are never stale: when a profile becomes stale, +it is removed from profile_list at the same time (under profile_list_lock +and aa_profile->lock). + +The aa_interface_lock is taken whenever user-space modifies the profile +list, and can sleep. This ensures that profile loading/replacement/removal +won't race with itself. We release the profile_list_lock as soon as +possible to avoid stalling exec during profile loading/replacement/removal. + +AppArmor uses lock subtyping to avoid false positives from lockdep. The +profile lock is often taken nested, but it is guaranteed to be in a lock +safe order and not the same lock when done, so it is safe. + +A third lock type (aa_lock_task_release) is given to the profile lock +when it is taken in soft irq context during task release (aa_release). +This is to avoid a false positive between the task lock and the profile +lock. In task context the profile lock wraps the task lock with irqs +off, but the kernel takes the task lock with irqs enabled. This won't +result in a deadlock because for a deadlock to occur the kernel must +take dead task A's lock (irqs on), the rcu callback hook freeing +dead task A must be run and AppArmor must be changing the profile on +dead task A. The kernel should not be taking a dead task's task_lock +at the same time the task is being freed by task rcu cleanup other wise +the task would not be out of its quiescent period. --- linux-2.6.28.orig/security/apparmor/list.c +++ linux-2.6.28/security/apparmor/list.c @@ -0,0 +1,174 @@ +/* + * Copyright (C) 1998-2007 Novell/SUSE + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + * + * AppArmor Profile List Management + */ + +#include +#include "apparmor.h" +#include "inline.h" + +/* list of profile namespaces and lock */ +LIST_HEAD(profile_ns_list); +rwlock_t profile_ns_list_lock = RW_LOCK_UNLOCKED; + +/** + * __aa_find_namespace - look up a profile namespace on the namespace list + * @name: name of namespace to find + * @head: list to search + * + * Returns a pointer to the namespace on the list, or NULL if no namespace + * called @name exists. The caller must hold the profile_ns_list_lock. + */ +struct aa_namespace *__aa_find_namespace(const char *name, + struct list_head *head) +{ + struct aa_namespace *ns; + + list_for_each_entry(ns, head, list) { + if (!strcmp(ns->name, name)) + return ns; + } + + return NULL; +} + +/** + * __aa_find_profile - look up a profile on the profile list + * @name: name of profile to find + * @head: list to search + * + * Returns a pointer to the profile on the list, or NULL if no profile + * called @name exists. The caller must hold the profile_list_lock. + */ +struct aa_profile *__aa_find_profile(const char *name, struct list_head *head) +{ + struct aa_profile *profile; + + list_for_each_entry(profile, head, list) { + if (!strcmp(profile->name, name)) + return profile; + } + + return NULL; +} + +static void aa_profile_list_release(struct list_head *head) +{ + struct aa_profile *profile, *tmp; + list_for_each_entry_safe(profile, tmp, head, list) { + /* Remove the profile from each task context it is on. */ + lock_profile(profile); + profile->isstale = 1; + aa_unconfine_tasks(profile); + list_del_init(&profile->list); + unlock_profile(profile); + aa_put_profile(profile); + } +} + +/** + * aa_profilelist_release - Remove all profiles from profile_list + */ +void aa_profile_ns_list_release(void) +{ + struct aa_namespace *ns, *tmp; + + /* Remove and release all the profiles on namespace profile lists. */ + write_lock(&profile_ns_list_lock); + list_for_each_entry_safe(ns, tmp, &profile_ns_list, list) { + write_lock(&ns->lock); + aa_profile_list_release(&ns->profiles); + list_del_init(&ns->list); + write_unlock(&ns->lock); + aa_put_namespace(ns); + } + write_unlock(&profile_ns_list_lock); +} + + +static struct aa_profile *next_profile(struct aa_profile *profile) +{ + struct aa_profile *next = profile; + struct aa_namespace *ns; + + list_for_each_entry_continue(next, &profile->ns->profiles, list) + return next; + + ns = profile->ns; + read_unlock(&ns->lock); + list_for_each_entry_continue(ns, &profile_ns_list, list) { + read_lock(&ns->lock); + list_for_each_entry(profile, &ns->profiles, list) + return profile; + read_unlock(&ns->lock); + } + return NULL; +} + +static void *p_start(struct seq_file *f, loff_t *pos) +{ + struct aa_namespace *ns; + loff_t l = *pos; + + read_lock(&profile_ns_list_lock); + if (!list_empty(&profile_ns_list)) { + struct aa_profile *profile = NULL; + ns = list_first_entry(&profile_ns_list, typeof(*ns), list); + read_lock(&ns->lock); + if (!list_empty(&ns->profiles)) + profile = list_first_entry(&ns->profiles, + typeof(*profile), list); + else + read_unlock(&ns->lock); + for ( ; profile && l > 0; l--) + profile = next_profile(profile); + return profile; + } + return NULL; +} + +static void *p_next(struct seq_file *f, void *p, loff_t *pos) +{ + struct aa_profile *profile = (struct aa_profile *) p; + + (*pos)++; + profile = next_profile(profile); + + return profile; +} + +static void p_stop(struct seq_file *f, void *p) +{ + struct aa_profile *profile = (struct aa_profile *) p; + + if (profile) + read_unlock(&profile->ns->lock); + read_unlock(&profile_ns_list_lock); +} + +static int seq_show_profile(struct seq_file *f, void *p) +{ + struct aa_profile *profile = (struct aa_profile *)p; + + if (profile->ns == default_namespace) + seq_printf(f, "%s (%s)\n", profile->name, + PROFILE_COMPLAIN(profile) ? "complain" : "enforce"); + else + seq_printf(f, ":%s:%s (%s)\n", profile->ns->name, profile->name, + PROFILE_COMPLAIN(profile) ? "complain" : "enforce"); + return 0; +} + +/* Used in apparmorfs.c */ +struct seq_operations apparmorfs_profiles_op = { + .start = p_start, + .next = p_next, + .stop = p_stop, + .show = seq_show_profile, +}; --- linux-2.6.28.orig/security/apparmor/lsm.c +++ linux-2.6.28/security/apparmor/lsm.c @@ -0,0 +1,1060 @@ +/* + * Copyright (C) 1998-2007 Novell/SUSE + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + * + * AppArmor LSM interface + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "apparmor.h" +#include "inline.h" + +/* Flag indicating whether initialization completed */ +int apparmor_initialized = 0; + +static int param_set_aabool(const char *val, struct kernel_param *kp); +static int param_get_aabool(char *buffer, struct kernel_param *kp); +#define param_check_aabool(name, p) __param_check(name, p, int) + +static int param_set_aauint(const char *val, struct kernel_param *kp); +static int param_get_aauint(char *buffer, struct kernel_param *kp); +#define param_check_aauint(name, p) __param_check(name, p, int) + +/* Flag values, also controllable via /sys/module/apparmor/parameters + * We define special types as we want to do additional mediation. + * + * Complain mode -- in complain mode access failures result in auditing only + * and task is allowed access. audit events are processed by userspace to + * generate policy. Default is 'enforce' (0). + * Value is also togglable per profile and referenced when global value is + * enforce. + */ +int apparmor_complain = 0; +module_param_named(complain, apparmor_complain, aabool, S_IRUSR | S_IWUSR); +MODULE_PARM_DESC(apparmor_complain, "Toggle AppArmor complain mode"); + +/* Debug mode */ +int apparmor_debug = 0; +module_param_named(debug, apparmor_debug, aabool, S_IRUSR | S_IWUSR); +MODULE_PARM_DESC(apparmor_debug, "Toggle AppArmor debug mode"); + +/* Audit mode */ +int apparmor_audit = 0; +module_param_named(audit, apparmor_audit, aabool, S_IRUSR | S_IWUSR); +MODULE_PARM_DESC(apparmor_audit, "Toggle AppArmor audit mode"); + +/* Syscall logging mode */ +int apparmor_logsyscall = 0; +module_param_named(logsyscall, apparmor_logsyscall, aabool, S_IRUSR | S_IWUSR); +MODULE_PARM_DESC(apparmor_logsyscall, "Toggle AppArmor logsyscall mode"); + +/* Maximum pathname length before accesses will start getting rejected */ +unsigned int apparmor_path_max = 2 * PATH_MAX; +module_param_named(path_max, apparmor_path_max, aauint, S_IRUSR | S_IWUSR); +MODULE_PARM_DESC(apparmor_path_max, "Maximum pathname length allowed"); + +/* Boot time disable flag */ +#ifdef CONFIG_SECURITY_APPARMOR_DISABLE +#define AA_ENABLED_PERMS 0600 +#else +#define AA_ENABLED_PERMS 0400 +#endif +static int param_set_aa_enabled(const char *val, struct kernel_param *kp); +unsigned int apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE; +module_param_call(enabled, param_set_aa_enabled, param_get_aauint, + &apparmor_enabled, AA_ENABLED_PERMS); +MODULE_PARM_DESC(apparmor_enabled, "Enable/Disable Apparmor on boot"); + +static int __init apparmor_enabled_setup(char *str) +{ + apparmor_enabled = simple_strtol(str, NULL, 0); + return 1; +} +__setup("apparmor=", apparmor_enabled_setup); + +static int param_set_aabool(const char *val, struct kernel_param *kp) +{ + if (aa_task_context(current)) + return -EPERM; + return param_set_bool(val, kp); +} + +static int param_get_aabool(char *buffer, struct kernel_param *kp) +{ + if (aa_task_context(current)) + return -EPERM; + return param_get_bool(buffer, kp); +} + +static int param_set_aauint(const char *val, struct kernel_param *kp) +{ + if (aa_task_context(current)) + return -EPERM; + return param_set_uint(val, kp); +} + +static int param_get_aauint(char *buffer, struct kernel_param *kp) +{ + if (aa_task_context(current)) + return -EPERM; + return param_get_uint(buffer, kp); +} + +/* allow run time disabling of apparmor */ +static int param_set_aa_enabled(const char *val, struct kernel_param *kp) +{ + char *endp; + unsigned long l; + + if (!apparmor_initialized) { + apparmor_enabled = 0; + return 0; + } + + if (aa_task_context(current)) + return -EPERM; + + if (!apparmor_enabled) + return -EINVAL; + + if (!val) + return -EINVAL; + + l = simple_strtoul(val, &endp, 0); + if (endp == val || l != 0) + return -EINVAL; + + apparmor_enabled = 0; + apparmor_disable(); + return 0; +} + +static int aa_reject_syscall(struct task_struct *task, gfp_t flags, + const char *name) +{ + struct aa_profile *profile = aa_get_profile(task); + int error = 0; + + if (profile) { + error = aa_audit_syscallreject(profile, flags, name); + aa_put_profile(profile); + } + + return error; +} + +static int apparmor_ptrace(struct task_struct *tracer, + struct task_struct *tracee) +{ + struct aa_task_context *cxt; + int error = 0; + + /* + * tracer can ptrace tracee when + * - tracer is unconfined + * - tracer & tracee are in the same namespace && + * - tracer is in complain mode + * - tracer and tracee are confined by the same profile + * - tracer profile has CAP_SYS_PTRACE + */ + + rcu_read_lock(); + cxt = aa_task_context(tracer); + if (cxt) { + if (tracer->nsproxy != tracee->nsproxy) { + struct aa_audit sa; + memset(&sa, 0, sizeof(sa)); + sa.operation = "ptrace"; + sa.gfp_mask = GFP_ATOMIC; + sa.parent = tracer->pid; + sa.task = tracee->pid; + sa.info = "different namespaces"; + aa_audit_reject(cxt->profile, &sa); + error = -EPERM; + } else { + struct aa_task_context *tracee_cxt = + aa_task_context(tracee); + + error = aa_may_ptrace(cxt, tracee_cxt ? + tracee_cxt->profile : NULL); + if (error && PROFILE_COMPLAIN(cxt->profile)) { + struct aa_audit sa; + memset(&sa, 0, sizeof(sa)); + sa.operation = "ptrace"; + sa.gfp_mask = GFP_ATOMIC; + sa.parent = tracer->pid; + sa.task = tracee->pid; + aa_audit_hint(cxt->profile, &sa); + } + } + } + rcu_read_unlock(); + + return error; +} + +static int apparmor_ptrace_may_access(struct task_struct *child, + unsigned int mode) +{ + return apparmor_ptrace(current, child); +} + + +static int apparmor_ptrace_traceme(struct task_struct *parent) +{ + return apparmor_ptrace(parent, current); +} + +static int apparmor_capable(struct task_struct *task, int cap) +{ + int error; + struct aa_task_context *cxt; + + /* cap_capable returns 0 on success, else -EPERM */ + error = cap_capable(task, cap); + + rcu_read_lock(); + cxt = aa_task_context(task); + if (cxt && (!error || cap_raised(cxt->profile->set_caps, cap))) + error = aa_capability(cxt, cap); + rcu_read_unlock(); + + return error; +} + +static int apparmor_sysctl(struct ctl_table *table, int op) +{ + struct aa_profile *profile = aa_get_profile(current); + int error = 0; + + if (profile) { + char *buffer, *name; + int mask; + + mask = 0; + if (op & 4) + mask |= MAY_READ; + if (op & 2) + mask |= MAY_WRITE; + + error = -ENOMEM; + buffer = (char*)__get_free_page(GFP_KERNEL); + if (!buffer) + goto out; + name = sysctl_pathname(table, buffer, PAGE_SIZE); + if (name && name - buffer >= 5) { + name -= 5; + memcpy(name, "/proc", 5); + error = aa_perm_path(profile, "sysctl", name, mask, 0); + } + free_page((unsigned long)buffer); + } + +out: + aa_put_profile(profile); + return error; +} + +static int apparmor_bprm_set_security(struct linux_binprm *bprm) +{ + /* handle capability bits with setuid, etc */ + cap_bprm_set_security(bprm); + /* already set based on script name */ + if (bprm->sh_bang) + return 0; + return aa_register(bprm); +} + +static int apparmor_bprm_secureexec(struct linux_binprm *bprm) +{ + int ret = cap_bprm_secureexec(bprm); + + if (!ret && (unsigned long)bprm->security & AA_SECURE_EXEC_NEEDED) { + AA_DEBUG("%s: secureexec required for %s\n", + __FUNCTION__, bprm->filename); + ret = 1; + } + + return ret; +} + +static int apparmor_sb_mount(char *dev_name, struct path *path, char *type, + unsigned long flags, void *data) +{ + return aa_reject_syscall(current, GFP_KERNEL, "mount"); +} + +static int apparmor_umount(struct vfsmount *mnt, int flags) +{ + return aa_reject_syscall(current, GFP_KERNEL, "umount"); +} + +static int apparmor_inode_mkdir(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mask) +{ + struct aa_profile *profile; + int error = 0; + + if (!mnt || !mediated_filesystem(dir)) + goto out; + + profile = aa_get_profile(current); + + if (profile) + error = aa_perm_dir(profile, "inode_mkdir", dentry, mnt, + MAY_WRITE); + + aa_put_profile(profile); + +out: + return error; +} + +static int apparmor_inode_rmdir(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt) +{ + struct aa_profile *profile; + int error = 0; + + if (!mnt || !mediated_filesystem(dir)) + goto out; + + profile = aa_get_profile(current); + + if (profile) + error = aa_perm_dir(profile, "inode_rmdir", dentry, mnt, + MAY_WRITE); + + aa_put_profile(profile); + +out: + return error; +} + +static int aa_permission(const char *operation, struct inode *inode, + struct dentry *dentry, struct vfsmount *mnt, + int mask, int check) +{ + int error = 0; + + if (mnt && mediated_filesystem(inode)) { + struct aa_profile *profile; + + profile = aa_get_profile(current); + if (profile) + error = aa_perm(profile, operation, dentry, mnt, mask, + check); + aa_put_profile(profile); + } + return error; +} + +static inline int aa_mask_permissions(int mask) +{ + if (mask & MAY_APPEND) + mask &= (MAY_READ | MAY_APPEND | MAY_EXEC); + else + mask &= (MAY_READ | MAY_WRITE | MAY_EXEC); + return mask; +} + +static int apparmor_inode_create(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mask) +{ + return aa_permission("inode_create", dir, dentry, mnt, MAY_APPEND, 0); +} + +static int apparmor_inode_link(struct dentry *old_dentry, + struct vfsmount *old_mnt, struct inode *dir, + struct dentry *new_dentry, + struct vfsmount *new_mnt) +{ + int error = 0; + struct aa_profile *profile; + + if (!old_mnt || !new_mnt || !mediated_filesystem(dir)) + goto out; + + profile = aa_get_profile(current); + + if (profile) + error = aa_link(profile, new_dentry, new_mnt, + old_dentry, old_mnt); + + aa_put_profile(profile); + +out: + return error; +} + +static int apparmor_inode_unlink(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt) +{ + int check = 0; + + if (S_ISDIR(dentry->d_inode->i_mode)) + check |= AA_CHECK_DIR; + return aa_permission("inode_unlink", dir, dentry, mnt, MAY_WRITE, + check); +} + +static int apparmor_inode_symlink(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, const char *old_name) +{ + return aa_permission("inode_symlink", dir, dentry, mnt, MAY_WRITE, 0); +} + +static int apparmor_inode_mknod(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode, dev_t dev) +{ + return aa_permission("inode_mknod", dir, dentry, mnt, MAY_WRITE, 0); +} + +static int apparmor_inode_rename(struct inode *old_dir, + struct dentry *old_dentry, + struct vfsmount *old_mnt, + struct inode *new_dir, + struct dentry *new_dentry, + struct vfsmount *new_mnt) +{ + struct aa_profile *profile; + int error = 0; + + if ((!old_mnt && !new_mnt) || !mediated_filesystem(old_dir)) + goto out; + + profile = aa_get_profile(current); + + if (profile) { + struct inode *inode = old_dentry->d_inode; + int check = 0; + + if (inode && S_ISDIR(inode->i_mode)) + check |= AA_CHECK_DIR; + if (old_mnt) + error = aa_perm(profile, "inode_rename", old_dentry, + old_mnt, MAY_READ | MAY_WRITE, check); + + if (!error && new_mnt) { + error = aa_perm(profile, "inode_rename", new_dentry, + new_mnt, MAY_WRITE, check); + } + } + + aa_put_profile(profile); + +out: + return error; +} + +static int apparmor_inode_permission(struct inode *inode, int mask) +{ + return 0; +} + +static int apparmor_inode_setattr(struct dentry *dentry, struct vfsmount *mnt, + struct iattr *iattr) +{ + int error = 0; + + if (!mnt) + goto out; + + if (mediated_filesystem(dentry->d_inode)) { + struct aa_profile *profile; + + profile = aa_get_profile(current); + /* + * Mediate any attempt to change attributes of a file + * (chmod, chown, chgrp, etc) + */ + if (profile) + error = aa_attr(profile, dentry, mnt, iattr); + + aa_put_profile(profile); + } + +out: + return error; +} + +static int aa_xattr_permission(struct dentry *dentry, struct vfsmount *mnt, + const char *operation, int mask, + struct file *file) +{ + int error = 0; + + if (mnt && mediated_filesystem(dentry->d_inode)) { + struct aa_profile *profile = aa_get_profile(current); + int check = file ? AA_CHECK_FD : 0; + + if (profile) + error = aa_perm_xattr(profile, operation, dentry, mnt, + mask, check); + aa_put_profile(profile); + } + + return error; +} + +static int apparmor_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, + size_t size, int flags, struct file *file) +{ + int error = cap_inode_setxattr(dentry, mnt, name, value, size, flags, + file); + + if (!error) + error = aa_xattr_permission(dentry, mnt, "xattr set", + MAY_WRITE, file); + return error; +} + +static int apparmor_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *file) +{ + return aa_xattr_permission(dentry, mnt, "xattr get", MAY_READ, file); +} + +static int apparmor_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt, + struct file *file) +{ + return aa_xattr_permission(dentry, mnt, "xattr list", MAY_READ, file); +} + +static int apparmor_inode_removexattr(struct dentry *dentry, + struct vfsmount *mnt, const char *name, + struct file *file) +{ + return aa_xattr_permission(dentry, mnt, "xattr remove", MAY_WRITE, + file); +} + +static int aa_file_permission(const char *op, struct file *file, int mask) +{ + struct aa_profile *profile; + struct aa_profile *file_profile = (struct aa_profile*)file->f_security; + int error = 0; + + if (!file_profile) + goto out; + + /* + * If this file was opened under a different profile, we + * revalidate the access against the current profile. + */ + profile = aa_get_profile(current); + if (profile && (file_profile != profile || mask & AA_MAY_LOCK)) { + struct dentry *dentry = file->f_dentry; + struct vfsmount *mnt = file->f_vfsmnt; + struct inode *inode = dentry->d_inode; + int check = AA_CHECK_FD; + + /* + * FIXME: We should remember which profiles we revalidated + * against. + */ + if (S_ISDIR(inode->i_mode)) + check |= AA_CHECK_DIR; + error = aa_permission(op, inode, dentry, mnt, mask, check); + } + aa_put_profile(profile); + +out: + return error; +} + +static int apparmor_file_permission(struct file *file, int mask) +{ + return aa_file_permission("file_permission", file, + aa_mask_permissions(mask)); +} + +static inline int apparmor_file_lock (struct file *file, unsigned int cmd) +{ + int mask = AA_MAY_LOCK; + if (cmd == F_WRLCK) + mask |= MAY_WRITE; + return aa_file_permission("file_lock", file, mask); +} + +static int apparmor_file_alloc_security(struct file *file) +{ + struct aa_profile *profile; + + profile = aa_get_profile(current); + if (profile) + file->f_security = profile; + + return 0; +} + +static void apparmor_file_free_security(struct file *file) +{ + struct aa_profile *file_profile = (struct aa_profile*)file->f_security; + + aa_put_profile(file_profile); +} + +static inline int aa_mmap(struct file *file, const char *operation, + unsigned long prot, unsigned long flags) +{ + struct dentry *dentry; + int mask = 0; + + if (!file || !file->f_security) + return 0; + + if (prot & PROT_READ) + mask |= MAY_READ; + /* Private mappings don't require write perms since they don't + * write back to the files */ + if ((prot & PROT_WRITE) && !(flags & MAP_PRIVATE)) + mask |= MAY_WRITE; + if (prot & PROT_EXEC) + mask |= AA_EXEC_MMAP; + + dentry = file->f_dentry; + return aa_permission(operation, dentry->d_inode, dentry, + file->f_vfsmnt, mask, AA_CHECK_FD); +} + +static int apparmor_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)) { + struct aa_profile *profile = aa_get_profile(current); + if (profile) + /* future control check here */ + return -EACCES; + else + return -EACCES; + aa_put_profile(profile); + } + + return aa_mmap(file, "file_mmap", prot, flags); +} + +static int apparmor_file_mprotect(struct vm_area_struct *vma, + unsigned long reqprot, unsigned long prot) +{ + return aa_mmap(vma->vm_file, "file_mprotect", prot, + !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0); +} + +static int apparmor_path_permission(struct path *path, int mask) +{ + struct inode *inode; + int check = 0; + + if (!path) + return 0; + + inode = path->dentry->d_inode; + + mask = aa_mask_permissions(mask); + if (S_ISDIR(inode->i_mode)) { + check |= AA_CHECK_DIR; + /* allow traverse accesses to directories */ + mask &= ~MAY_EXEC; + if (!mask) + return 0; + } + + return aa_permission("inode_permission", inode, path->dentry, + path->mnt, mask, check); +} + +static int apparmor_task_alloc_security(struct task_struct *task) +{ + return aa_clone(task); +} + +/* + * Called from IRQ context from RCU callback. + */ +static void apparmor_task_free_security(struct task_struct *task) +{ + aa_release(task); +} + +static int apparmor_socket_create(int family, int type, int protocol, int kern) +{ + struct aa_profile *profile; + int error = 0; + + if (kern) + return 0; + + profile = aa_get_profile(current); + if (profile) + error = aa_net_perm(profile, "socket_create", family, + type, protocol); + aa_put_profile(profile); + + return error; +} + +static int apparmor_socket_post_create(struct socket *sock, int family, + int type, int protocol, int kern) +{ + struct sock *sk = sock->sk; + + if (kern) + return 0; + + return aa_revalidate_sk(sk, "socket_post_create"); +} + +static int apparmor_socket_bind(struct socket *sock, + struct sockaddr *address, int addrlen) +{ + struct sock *sk = sock->sk; + + return aa_revalidate_sk(sk, "socket_bind"); +} + +static int apparmor_socket_connect(struct socket *sock, + struct sockaddr *address, int addrlen) +{ + struct sock *sk = sock->sk; + + return aa_revalidate_sk(sk, "socket_connect"); +} + +static int apparmor_socket_listen(struct socket *sock, int backlog) +{ + struct sock *sk = sock->sk; + + return aa_revalidate_sk(sk, "socket_listen"); +} + +static int apparmor_socket_accept(struct socket *sock, struct socket *newsock) +{ + struct sock *sk = sock->sk; + + return aa_revalidate_sk(sk, "socket_accept"); +} + +static int apparmor_socket_sendmsg(struct socket *sock, + struct msghdr *msg, int size) +{ + struct sock *sk = sock->sk; + + return aa_revalidate_sk(sk, "socket_sendmsg"); +} + +static int apparmor_socket_recvmsg(struct socket *sock, + struct msghdr *msg, int size, int flags) +{ + struct sock *sk = sock->sk; + + return aa_revalidate_sk(sk, "socket_recvmsg"); +} + +static int apparmor_socket_getsockname(struct socket *sock) +{ + struct sock *sk = sock->sk; + + return aa_revalidate_sk(sk, "socket_getsockname"); +} + +static int apparmor_socket_getpeername(struct socket *sock) +{ + struct sock *sk = sock->sk; + + return aa_revalidate_sk(sk, "socket_getpeername"); +} + +static int apparmor_socket_getsockopt(struct socket *sock, int level, + int optname) +{ + struct sock *sk = sock->sk; + + return aa_revalidate_sk(sk, "socket_getsockopt"); +} + +static int apparmor_socket_setsockopt(struct socket *sock, int level, + int optname) +{ + struct sock *sk = sock->sk; + + return aa_revalidate_sk(sk, "socket_setsockopt"); +} + +static int apparmor_socket_shutdown(struct socket *sock, int how) +{ + struct sock *sk = sock->sk; + + return aa_revalidate_sk(sk, "socket_shutdown"); +} + +static int apparmor_getprocattr(struct task_struct *task, char *name, + char **value) +{ + unsigned len; + int error; + struct aa_profile *profile; + + /* AppArmor only supports the "current" process attribute */ + if (strcmp(name, "current") != 0) + return -EINVAL; + + /* must be task querying itself or admin */ + if (current != task && !capable(CAP_SYS_ADMIN)) + return -EPERM; + + profile = aa_get_profile(task); + error = aa_getprocattr(profile, value, &len); + aa_put_profile(profile); + if (!error) + error = len; + + return error; +} + +static int apparmor_setprocattr(struct task_struct *task, char *name, + void *value, size_t size) +{ + char *command, *args; + int error; + + if (strcmp(name, "current") != 0 || size == 0 || size >= PAGE_SIZE) + return -EINVAL; + args = value; + args[size] = '\0'; + args = strstrip(args); + command = strsep(&args, " "); + if (!args) + return -EINVAL; + while (isspace(*args)) + args++; + if (!*args) + return -EINVAL; + + if (strcmp(command, "changehat") == 0) { + if (current != task) + return -EACCES; + error = aa_setprocattr_changehat(args); + } else if (strcmp(command, "changeprofile") == 0) { + if (current != task) + return -EACCES; + error = aa_setprocattr_changeprofile(args); + } else if (strcmp(command, "setprofile") == 0) { + struct aa_profile *profile; + + /* Only an unconfined process with admin capabilities + * may change the profile of another task. + */ + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + profile = aa_get_profile(current); + if (profile) { + struct aa_audit sa; + memset(&sa, 0, sizeof(sa)); + sa.operation = "profile_set"; + sa.gfp_mask = GFP_KERNEL; + sa.task = task->pid; + sa.info = "from confined process"; + aa_audit_reject(profile, &sa); + aa_put_profile(profile); + return -EACCES; + } + error = aa_setprocattr_setprofile(task, args); + } else { + struct aa_audit sa; + memset(&sa, 0, sizeof(sa)); + sa.operation = "setprocattr"; + sa.gfp_mask = GFP_KERNEL; + sa.info = "invalid command"; + sa.name = command; + sa.task = task->pid; + aa_audit_reject(NULL, &sa); + return -EINVAL; + } + + if (!error) + error = size; + return error; +} + +static int apparmor_task_setrlimit(unsigned int resource, + struct rlimit *new_rlim) +{ + struct aa_profile *profile; + int error = 0; + + profile = aa_get_profile(current); + if (profile) { + error = aa_task_setrlimit(profile, resource, new_rlim); + } + aa_put_profile(profile); + + return error; +} + +struct security_operations apparmor_ops = { + .ptrace_may_access = apparmor_ptrace_may_access, + .ptrace_traceme = apparmor_ptrace_traceme, + .capget = cap_capget, + .capset_check = cap_capset_check, + .capset_set = cap_capset_set, + .sysctl = apparmor_sysctl, + .capable = apparmor_capable, + .syslog = cap_syslog, + + .bprm_apply_creds = cap_bprm_apply_creds, + .bprm_set_security = apparmor_bprm_set_security, + .bprm_secureexec = apparmor_bprm_secureexec, + + .sb_mount = apparmor_sb_mount, + .sb_umount = apparmor_umount, + + .inode_mkdir = apparmor_inode_mkdir, + .inode_rmdir = apparmor_inode_rmdir, + .inode_create = apparmor_inode_create, + .inode_link = apparmor_inode_link, + .inode_unlink = apparmor_inode_unlink, + .inode_symlink = apparmor_inode_symlink, + .inode_mknod = apparmor_inode_mknod, + .inode_rename = apparmor_inode_rename, + .inode_permission = apparmor_inode_permission, + .inode_setattr = apparmor_inode_setattr, + .inode_setxattr = apparmor_inode_setxattr, + .inode_getxattr = apparmor_inode_getxattr, + .inode_listxattr = apparmor_inode_listxattr, + .inode_removexattr = apparmor_inode_removexattr, + .file_permission = apparmor_file_permission, + .file_alloc_security = apparmor_file_alloc_security, + .file_free_security = apparmor_file_free_security, + .file_mmap = apparmor_file_mmap, + .file_mprotect = apparmor_file_mprotect, + .file_lock = apparmor_file_lock, + + .path_permission = apparmor_path_permission, + + .task_alloc_security = apparmor_task_alloc_security, + .task_free_security = apparmor_task_free_security, + .task_post_setuid = cap_task_post_setuid, + .task_reparent_to_init = cap_task_reparent_to_init, + .task_setrlimit = apparmor_task_setrlimit, + + .getprocattr = apparmor_getprocattr, + .setprocattr = apparmor_setprocattr, + + .socket_create = apparmor_socket_create, + .socket_post_create = apparmor_socket_post_create, + .socket_bind = apparmor_socket_bind, + .socket_connect = apparmor_socket_connect, + .socket_listen = apparmor_socket_listen, + .socket_accept = apparmor_socket_accept, + .socket_sendmsg = apparmor_socket_sendmsg, + .socket_recvmsg = apparmor_socket_recvmsg, + .socket_getsockname = apparmor_socket_getsockname, + .socket_getpeername = apparmor_socket_getpeername, + .socket_getsockopt = apparmor_socket_getsockopt, + .socket_setsockopt = apparmor_socket_setsockopt, + .socket_shutdown = apparmor_socket_shutdown, +}; + +void info_message(const char *str) +{ + struct aa_audit sa; + memset(&sa, 0, sizeof(sa)); + sa.gfp_mask = GFP_KERNEL; + sa.info = str; + printk(KERN_INFO "AppArmor: %s\n", str); + if (audit_enabled) + aa_audit_message(NULL, &sa, AUDIT_APPARMOR_STATUS); +} + +static int __init apparmor_init(void) +{ + int error; + + if (!apparmor_enabled) { + info_message("AppArmor disabled by boottime parameter\n"); + return 0; + } + + if ((error = create_apparmorfs())) { + AA_ERROR("Unable to activate AppArmor filesystem\n"); + goto createfs_out; + } + + if ((error = alloc_default_namespace())){ + AA_ERROR("Unable to allocate default profile namespace\n"); + goto alloc_out; + } + + if ((error = register_security(&apparmor_ops))) { + AA_ERROR("Unable to register AppArmor\n"); + goto register_security_out; + } + + /* Report that AppArmor successfully initialized */ + apparmor_initialized = 1; + if (apparmor_complain) + info_message("AppArmor initialized: complainmode enabled"); + else + info_message("AppArmor initialized"); + + return error; + +register_security_out: + free_default_namespace(); + +alloc_out: + destroy_apparmorfs(); + +createfs_out: + return error; + +} + +security_initcall(apparmor_init); + +void apparmor_disable(void) +{ + /* Remove and release all the profiles on the profile list. */ + mutex_lock(&aa_interface_lock); + aa_profile_ns_list_release(); + + /* FIXME: cleanup profiles references on files */ + free_default_namespace(); + + /* + * Delay for an rcu cycle to make sure that all active task + * context readers have finished, and all profiles have been + * freed by their rcu callbacks. + */ + synchronize_rcu(); + + destroy_apparmorfs(); + mutex_unlock(&aa_interface_lock); + + apparmor_initialized = 0; + + info_message("AppArmor protection removed"); +} + +MODULE_DESCRIPTION("AppArmor process confinement"); +MODULE_AUTHOR("Novell/Immunix, http://bugs.opensuse.org"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/security/apparmor/main.c +++ linux-2.6.28/security/apparmor/main.c @@ -0,0 +1,1690 @@ +/* + * Copyright (C) 2002-2007 Novell/SUSE + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + * + * AppArmor Core + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "apparmor.h" + +#include "inline.h" + +/* + * Table of capability names: we generate it from capabilities.h. + */ +static const char *capability_names[] = { +#include "capability_names.h" +}; + +struct aa_namespace *default_namespace; + +static int aa_inode_mode(struct inode *inode) +{ + /* if the inode doesn't exist the user is creating it */ + if (!inode || current->fsuid == inode->i_uid) + return AA_USER_SHIFT; + return AA_OTHER_SHIFT; +} + +int alloc_default_namespace(void) +{ + struct aa_namespace *ns; + char *name = kstrdup("default", GFP_KERNEL); + if (!name) + return -ENOMEM; + ns = alloc_aa_namespace(name); + if (!ns) { + kfree(name); + return -ENOMEM; + } + + write_lock(&profile_ns_list_lock); + default_namespace = ns; + aa_get_namespace(ns); + list_add(&ns->list, &profile_ns_list); + write_unlock(&profile_ns_list_lock); + + return 0; +} + +void free_default_namespace(void) +{ + write_lock(&profile_ns_list_lock); + list_del_init(&default_namespace->list); + write_unlock(&profile_ns_list_lock); + aa_put_namespace(default_namespace); + default_namespace = NULL; +} + +static void aa_audit_file_sub_mask(struct audit_buffer *ab, char *buffer, + int mask) +{ + const char unsafex[] = "upcn"; + const char safex[] = "UPCN"; + char *m = buffer; + + if (mask & AA_EXEC_MMAP) + *m++ = 'm'; + if (mask & MAY_READ) + *m++ = 'r'; + if (mask & MAY_WRITE) + *m++ = 'w'; + else if (mask & MAY_APPEND) + *m++ = 'a'; + if (mask & MAY_EXEC) { + int index = AA_EXEC_INDEX(mask); + /* all indexes > 4 are also named transitions */ + if (index > 4) + index = 4; + if (index > 0) { + if (mask & AA_EXEC_UNSAFE) + *m++ = unsafex[index - 1]; + else + *m++ = safex[index - 1]; + } + if (mask & AA_EXEC_INHERIT) + *m++ = 'i'; + *m++ = 'x'; + } + if (mask & AA_MAY_LINK) + *m++ = 'l'; + if (mask & AA_MAY_LOCK) + *m++ = 'k'; + *m++ = '\0'; +} + +static void aa_audit_file_mask(struct audit_buffer *ab, const char *name, + int mask) +{ + char user[10], other[10]; + + aa_audit_file_sub_mask(ab, user, + (mask & AA_USER_PERMS) >> AA_USER_SHIFT); + aa_audit_file_sub_mask(ab, other, + (mask & AA_OTHER_PERMS) >> AA_OTHER_SHIFT); + + audit_log_format(ab, " %s=\"%s::%s\"", name, user, other); +} + +static const char *address_families[] = { +#include "af_names.h" +}; + +static const char *sock_types[] = { + "unknown(0)", + "stream", + "dgram", + "raw", + "rdm", + "seqpacket", + "dccp", + "unknown(7)", + "unknown(8)", + "unknown(9)", + "packet", +}; + +/** + * aa_audit - Log an audit event to the audit subsystem + * @profile: profile to check against + * @sa: audit event + * @audit_cxt: audit context to log message to + * @type: audit event number + */ +static int aa_audit_base(struct aa_profile *profile, struct aa_audit *sa, + struct audit_context *audit_cxt, int type) +{ + struct audit_buffer *ab = NULL; + + ab = audit_log_start(audit_cxt, sa->gfp_mask, type); + + if (!ab) { + AA_ERROR("Unable to log event (%d) to audit subsys\n", + type); + /* don't fail operations in complain mode even if logging + * fails */ + return type == AUDIT_APPARMOR_ALLOWED ? 0 : -ENOMEM; + } + + if (sa->operation) + audit_log_format(ab, "operation=\"%s\"", sa->operation); + + if (sa->info) { + audit_log_format(ab, " info=\"%s\"", sa->info); + if (sa->error_code) + audit_log_format(ab, " error=%d", sa->error_code); + } + + if (sa->request_mask) + aa_audit_file_mask(ab, "requested_mask", sa->request_mask); + + if (sa->denied_mask) + aa_audit_file_mask(ab, "denied_mask", sa->denied_mask); + + if (sa->request_mask) + audit_log_format(ab, " fsuid=%d", current->fsuid); + + if (sa->rlimit) + audit_log_format(ab, " rlimit=%d", sa->rlimit - 1); + + if (sa->iattr) { + struct iattr *iattr = sa->iattr; + + audit_log_format(ab, " attribute=\"%s%s%s%s%s%s%s\"", + iattr->ia_valid & ATTR_MODE ? "mode," : "", + iattr->ia_valid & ATTR_UID ? "uid," : "", + iattr->ia_valid & ATTR_GID ? "gid," : "", + iattr->ia_valid & ATTR_SIZE ? "size," : "", + iattr->ia_valid & (ATTR_ATIME | ATTR_ATIME_SET) ? + "atime," : "", + iattr->ia_valid & (ATTR_MTIME | ATTR_MTIME_SET) ? + "mtime," : "", + iattr->ia_valid & ATTR_CTIME ? "ctime," : ""); + } + + if (sa->task) + audit_log_format(ab, " task=%d", sa->task); + + if (sa->parent) + audit_log_format(ab, " parent=%d", sa->parent); + + if (sa->name) { + audit_log_format(ab, " name="); + audit_log_untrustedstring(ab, sa->name); + } + + if (sa->name2) { + audit_log_format(ab, " name2="); + audit_log_untrustedstring(ab, sa->name2); + } + + if (sa->family || sa->type) { + if (address_families[sa->family]) + audit_log_format(ab, " family=\"%s\"", + address_families[sa->family]); + else + audit_log_format(ab, " family=\"unknown(%d)\"", + sa->family); + + if (sock_types[sa->type]) + audit_log_format(ab, " sock_type=\"%s\"", + sock_types[sa->type]); + else + audit_log_format(ab, " sock_type=\"unknown(%d)\"", + sa->type); + + audit_log_format(ab, " protocol=%d", sa->protocol); + } + + audit_log_format(ab, " pid=%d", current->pid); + + if (profile) { + audit_log_format(ab, " profile="); + audit_log_untrustedstring(ab, profile->name); + + if (profile->ns != default_namespace) { + audit_log_format(ab, " namespace="); + audit_log_untrustedstring(ab, profile->ns->name); + } + } + + audit_log_end(ab); + + return type == AUDIT_APPARMOR_ALLOWED ? 0 : sa->error_code; +} + +/** + * aa_audit_syscallreject - Log a syscall rejection to the audit subsystem + * @profile: profile to check against + * @gfp: memory allocation flags + * @msg: string describing syscall being rejected + */ +int aa_audit_syscallreject(struct aa_profile *profile, gfp_t gfp, + const char *msg) +{ + struct aa_audit sa; + memset(&sa, 0, sizeof(sa)); + sa.operation = "syscall"; + sa.name = msg; + sa.gfp_mask = gfp; + sa.error_code = -EPERM; + + return aa_audit_base(profile, &sa, current->audit_context, + AUDIT_APPARMOR_DENIED); +} + +int aa_audit_message(struct aa_profile *profile, struct aa_audit *sa, + int type) +{ + struct audit_context *audit_cxt; + + audit_cxt = apparmor_logsyscall ? current->audit_context : NULL; + return aa_audit_base(profile, sa, audit_cxt, type); +} + +void aa_audit_hint(struct aa_profile *profile, struct aa_audit *sa) +{ + aa_audit_message(profile, sa, AUDIT_APPARMOR_HINT); +} + +void aa_audit_status(struct aa_profile *profile, struct aa_audit *sa) +{ + aa_audit_message(profile, sa, AUDIT_APPARMOR_STATUS); +} + +int aa_audit_reject(struct aa_profile *profile, struct aa_audit *sa) +{ + return aa_audit_message(profile, sa, AUDIT_APPARMOR_DENIED); +} + +/** + * aa_audit - Log an audit event to the audit subsystem + * @profile: profile to check against + * @sa: audit event + */ +int aa_audit(struct aa_profile *profile, struct aa_audit *sa) +{ + int type = AUDIT_APPARMOR_DENIED; + struct audit_context *audit_cxt; + + if (likely(!sa->error_code)) + type = AUDIT_APPARMOR_AUDIT; + else if (PROFILE_COMPLAIN(profile)) + type = AUDIT_APPARMOR_ALLOWED; + + audit_cxt = apparmor_logsyscall ? current->audit_context : NULL; + return aa_audit_base(profile, sa, audit_cxt, type); +} + +static int aa_audit_file(struct aa_profile *profile, struct aa_audit *sa) +{ + if (likely(!sa->error_code)) { + int mask = sa->audit_mask & AUDIT_FILE_MASK; + + if (unlikely(PROFILE_AUDIT(profile))) + mask |= AUDIT_FILE_MASK; + + if (likely(!(sa->request_mask & mask))) + return 0; + + /* mask off perms that are not being force audited */ + sa->request_mask &= mask | ALL_AA_EXEC_TYPE; + } else { + int mask = AUDIT_QUIET_MASK(sa->audit_mask); + + if (!(sa->denied_mask & ~mask)) + return sa->error_code; + + /* mask off perms whose denial is being silenced */ + if (!PROFILE_COMPLAIN(profile)) + sa->denied_mask &= (~mask) | ALL_AA_EXEC_TYPE; + } + + return aa_audit(profile, sa); +} + +static int aa_audit_caps(struct aa_profile *profile, struct aa_audit *sa, + int cap) +{ + if (likely(!sa->error_code)) { + if (likely(!PROFILE_AUDIT(profile) && + !cap_raised(profile->audit_caps, cap))) + return 0; + } + + /* quieting of capabilities is handled the caps_logged cache */ + return aa_audit(profile, sa); +} + +/** + * aa_file_denied - check for @mask access on a file + * @profile: profile to check against + * @name: pathname of file + * @mask: permission mask requested for file + * @audit_mask: return audit mask for the match + * + * Return %0 on success, or else the permissions in @mask that the + * profile denies. + */ +static int aa_file_denied(struct aa_profile *profile, const char *name, + int mask, int *audit_mask) +{ + return (mask & ~aa_match(profile->file_rules, name, audit_mask)); +} + +/** + * aa_link_denied - check for permission to link a file + * @profile: profile to check against + * @link: pathname of link being created + * @target: pathname of target to be linked to + * @target_mode: UGO shift for target inode + * @request_mask: the permissions subset valid only if link succeeds + * @audit_mask: return the audit_mask for the link permission + * Return %0 on success, or else the permissions that the profile denies. + */ +static int aa_link_denied(struct aa_profile *profile, const char *link, + const char *target, int target_mode, + int *request_mask, int *audit_mask) +{ + unsigned int state; + int l_mode, t_mode, l_x, t_x, denied_mask = 0; + int link_mask = AA_MAY_LINK << target_mode; + + *request_mask = link_mask; + + l_mode = aa_match_state(profile->file_rules, DFA_START, link, &state); + + if (l_mode & link_mask) { + int mode; + /* test to see if target can be paired with link */ + state = aa_dfa_null_transition(profile->file_rules, state); + mode = aa_match_state(profile->file_rules, state, target, + &state); + + if (!(mode & link_mask)) + denied_mask |= link_mask; + + *audit_mask = dfa_audit_mask(profile->file_rules, state); + + /* return if link subset test is not required */ + if (!(mode & (AA_LINK_SUBSET_TEST << target_mode))) + return denied_mask; + } + + /* Do link perm subset test requiring permission on link are a + * subset of the permissions on target. + * If a subset test is required a permission subset test of the + * perms for the link are done against the user::other of the + * target's 'r', 'w', 'x', 'a', 'k', and 'm' permissions. + * + * If the link has 'x', an exact match of all the execute flags + * must match. + */ + denied_mask |= ~l_mode & link_mask; + + t_mode = aa_match(profile->file_rules, target, NULL); + + l_x = l_mode & (ALL_AA_EXEC_TYPE | AA_EXEC_BITS); + t_x = t_mode & (ALL_AA_EXEC_TYPE | AA_EXEC_BITS); + + /* For actual subset test ignore valid-profile-transition flags, + * and link bits + */ + l_mode &= AA_FILE_PERMS & ~AA_LINK_BITS; + t_mode &= AA_FILE_PERMS & ~AA_LINK_BITS; + + *request_mask = l_mode | link_mask; + + if (l_mode) { + int x = l_x | (t_x & ALL_AA_EXEC_UNSAFE); + denied_mask |= l_mode & ~t_mode; + /* mask off x modes not used by link */ + + /* handle exec subset + * - link safe exec issubset of unsafe exec + * - no link x perm is subset of target having x perm + */ + if ((l_mode & AA_USER_EXEC) && + (x & AA_USER_EXEC_TYPE) != (t_x & AA_USER_EXEC_TYPE)) + denied_mask = AA_USER_EXEC | (l_x & AA_USER_EXEC_TYPE); + if ((l_mode & AA_OTHER_EXEC) && + (x & AA_OTHER_EXEC_TYPE) != (t_x & AA_OTHER_EXEC_TYPE)) + denied_mask = AA_OTHER_EXEC | (l_x & AA_OTHER_EXEC_TYPE); + } + + return denied_mask; +} + +/** + * aa_get_name - compute the pathname of a file + * @dentry: dentry of the file + * @mnt: vfsmount of the file + * @buffer: buffer that aa_get_name() allocated + * @check: AA_CHECK_DIR is set if the file is a directory + * + * Returns a pointer to the beginning of the pathname (which usually differs + * from the beginning of the buffer), or an error code. + * + * We need @check to indicate whether the file is a directory or not because + * the file may not yet exist, and so we cannot check the inode's file type. + */ +static char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt, + char **buffer, int check) +{ + char *name; + int is_dir, size = 256; + + is_dir = (check & AA_CHECK_DIR) ? 1 : 0; + + for (;;) { + char *buf = kmalloc(size, GFP_KERNEL); + if (!buf) + return ERR_PTR(-ENOMEM); + + name = d_namespace_path(dentry, mnt, buf, size - is_dir); + if (!IS_ERR(name)) { + if (name[0] != '/') { + /* + * This dentry is not connected to the + * namespace root -- reject access. + */ + kfree(buf); + return ERR_PTR(-ENOENT); + } + if (is_dir && name[1] != '\0') { + /* + * Append "/" to the pathname. The root + * directory is a special case; it already + * ends in slash. + */ + buf[size - 2] = '/'; + buf[size - 1] = '\0'; + } + + *buffer = buf; + return name; + } + kfree(buf); + if (PTR_ERR(name) != -ENAMETOOLONG) + return name; + + size <<= 1; + if (size > apparmor_path_max) + return ERR_PTR(-ENAMETOOLONG); + } +} + +static char *new_compound_name(const char *n1, const char *n2) +{ + char *name = kmalloc(strlen(n1) + strlen(n2) + 3, GFP_KERNEL); + if (name) + sprintf(name, "%s//%s", n1, n2); + return name; +} +static inline void aa_put_name_buffer(char *buffer) +{ + kfree(buffer); +} + +/** + * aa_perm_dentry - check if @profile allows @mask for a file + * @profile: profile to check against + * @dentry: dentry of the file + * @mnt: vfsmount o the file + * @sa: audit context + * @mask: requested profile permissions + * @check: kind of check to perform + * + * Returns 0 upon success, or else an error code. + * + * @check indicates the file type, and whether the file was accessed through + * an open file descriptor (AA_CHECK_FD) or not. + */ +static int aa_perm_dentry(struct aa_profile *profile, struct dentry *dentry, + struct vfsmount *mnt, struct aa_audit *sa, int check) +{ + int error; + char *buffer = NULL; + + sa->name = aa_get_name(dentry, mnt, &buffer, check); + sa->request_mask <<= aa_inode_mode(dentry->d_inode); + if (IS_ERR(sa->name)) { + /* + * deleted files are given a pass on permission checks when + * accessed through a file descriptor. + */ + if (PTR_ERR(sa->name) == -ENOENT && (check & AA_CHECK_FD)) + sa->denied_mask = 0; + else { + sa->denied_mask = sa->request_mask; + sa->error_code = PTR_ERR(sa->name); + if (sa->error_code == -ENOENT) + sa->info = "Failed name resolution - object not a valid entry"; + else if (sa->error_code == -ENAMETOOLONG) + sa->info = "Failed name resolution - name too long"; + else + sa->info = "Failed name resolution"; + } + sa->name = NULL; + } else + sa->denied_mask = aa_file_denied(profile, sa->name, + sa->request_mask, + &sa->audit_mask); + + if (!sa->denied_mask) + sa->error_code = 0; + + error = aa_audit_file(profile, sa); + aa_put_name_buffer(buffer); + + return error; +} + +/** + * aa_attr - check if attribute change is allowed + * @profile: profile to check against + * @dentry: dentry of the file to check + * @mnt: vfsmount of the file to check + * @iattr: attribute changes requested + */ +int aa_attr(struct aa_profile *profile, struct dentry *dentry, + struct vfsmount *mnt, struct iattr *iattr) +{ + struct inode *inode = dentry->d_inode; + int error, check; + struct aa_audit sa; + + memset(&sa, 0, sizeof(sa)); + sa.operation = "setattr"; + sa.gfp_mask = GFP_KERNEL; + sa.iattr = iattr; + sa.request_mask = MAY_WRITE; + sa.error_code = -EACCES; + + check = 0; + if (inode && S_ISDIR(inode->i_mode)) + check |= AA_CHECK_DIR; + if (iattr->ia_valid & ATTR_FILE) + check |= AA_CHECK_FD; + + error = aa_perm_dentry(profile, dentry, mnt, &sa, check); + + return error; +} + +/** + * aa_perm_xattr - check if xattr attribute change is allowed + * @profile: profile to check against + * @dentry: dentry of the file to check + * @mnt: vfsmount of the file to check + * @operation: xattr operation being done + * @mask: access mode requested + * @check: kind of check to perform + */ +int aa_perm_xattr(struct aa_profile *profile, const char *operation, + struct dentry *dentry, struct vfsmount *mnt, int mask, + int check) +{ + struct inode *inode = dentry->d_inode; + int error; + struct aa_audit sa; + + memset(&sa, 0, sizeof(sa)); + sa.operation = operation; + sa.gfp_mask = GFP_KERNEL; + sa.request_mask = mask; + sa.error_code = -EACCES; + + if (inode && S_ISDIR(inode->i_mode)) + check |= AA_CHECK_DIR; + + error = aa_perm_dentry(profile, dentry, mnt, &sa, check); + + return error; +} + +/** + * aa_perm - basic apparmor permissions check + * @profile: profile to check against + * @dentry: dentry of the file to check + * @mnt: vfsmount of the file to check + * @mask: access mode requested + * @check: kind of check to perform + * + * Determine if access @mask for the file is authorized by @profile. + * Returns 0 on success, or else an error code. + */ +int aa_perm(struct aa_profile *profile, const char *operation, + struct dentry *dentry, struct vfsmount *mnt, int mask, int check) +{ + struct aa_audit sa; + int error = 0; + + if (mask == 0) + goto out; + + memset(&sa, 0, sizeof(sa)); + sa.operation = operation; + sa.gfp_mask = GFP_KERNEL; + sa.request_mask = mask; + sa.error_code = -EACCES; + + error = aa_perm_dentry(profile, dentry, mnt, &sa, check); + +out: + return error; +} + +/** + * aa_perm_dir + * @profile: profile to check against + * @dentry: dentry of directory to check + * @mnt: vfsmount of directory to check + * @operation: directory operation being performed + * @mask: access mode requested + * + * Determine if directory operation (make/remove) for dentry is authorized + * by @profile. + * Returns 0 on success, or else an error code. + */ +int aa_perm_dir(struct aa_profile *profile, const char *operation, + struct dentry *dentry, struct vfsmount *mnt, int mask) +{ + struct aa_audit sa; + + memset(&sa, 0, sizeof(sa)); + sa.operation = operation; + sa.gfp_mask = GFP_KERNEL; + sa.request_mask = mask; + sa.error_code = -EACCES; + + return aa_perm_dentry(profile, dentry, mnt, &sa, AA_CHECK_DIR); +} + +int aa_perm_path(struct aa_profile *profile, const char *operation, + const char *name, int mask, uid_t uid) +{ + struct aa_audit sa; + + memset(&sa, 0, sizeof(sa)); + sa.operation = operation; + sa.gfp_mask = GFP_KERNEL; + sa.request_mask = mask; + sa.name = name; + if (current->fsuid == uid) + sa.request_mask = mask << AA_USER_SHIFT; + else + sa.request_mask = mask << AA_OTHER_SHIFT; + + sa.denied_mask = aa_file_denied(profile, name, sa.request_mask, + &sa.audit_mask) ; + sa.error_code = sa.denied_mask ? -EACCES : 0; + + return aa_audit_file(profile, &sa); +} + +/** + * aa_capability - test permission to use capability + * @cxt: aa_task_context with profile to check against + * @cap: capability to be tested + * + * Look up capability in profile capability set. + * Returns 0 on success, or else an error code. + */ +int aa_capability(struct aa_task_context *cxt, int cap) +{ + int error = cap_raised(cxt->profile->capabilities, cap) ? 0 : -EPERM; + struct aa_audit sa; + + /* test if cap has alread been logged */ + if (cap_raised(cxt->caps_logged, cap)) { + if (PROFILE_COMPLAIN(cxt->profile)) + error = 0; + return error; + } else + /* don't worry about rcu replacement of the cxt here. + * caps_logged is a cache to reduce the occurence of + * duplicate messages in the log. The worst that can + * happen is duplicate capability messages shows up in + * the audit log + */ + cap_raise(cxt->caps_logged, cap); + + memset(&sa, 0, sizeof(sa)); + sa.operation = "capable"; + sa.gfp_mask = GFP_ATOMIC; + sa.name = capability_names[cap]; + sa.error_code = error; + + error = aa_audit_caps(cxt->profile, &sa, cap); + + return error; +} + +/* must be used inside rcu_read_lock or task_lock */ +int aa_may_ptrace(struct aa_task_context *cxt, struct aa_profile *tracee) +{ + if (!cxt || cxt->profile == tracee) + return 0; + return aa_capability(cxt, CAP_SYS_PTRACE); +} + +/** + * aa_link - hard link check + * @profile: profile to check against + * @link: dentry of link being created + * @link_mnt: vfsmount of link being created + * @target: dentry of link target + * @target_mnt: vfsmunt of link target + * + * Returns 0 on success, or else an error code. + */ +int aa_link(struct aa_profile *profile, + struct dentry *link, struct vfsmount *link_mnt, + struct dentry *target, struct vfsmount *target_mnt) +{ + int error; + struct aa_audit sa; + char *buffer = NULL, *buffer2 = NULL; + + memset(&sa, 0, sizeof(sa)); + sa.operation = "inode_link"; + sa.gfp_mask = GFP_KERNEL; + sa.name = aa_get_name(link, link_mnt, &buffer, 0); + sa.name2 = aa_get_name(target, target_mnt, &buffer2, 0); + + if (IS_ERR(sa.name)) { + sa.error_code = PTR_ERR(sa.name); + sa.name = NULL; + } + if (IS_ERR(sa.name2)) { + sa.error_code = PTR_ERR(sa.name2); + sa.name2 = NULL; + } + + if (sa.name && sa.name2) { + sa.denied_mask = aa_link_denied(profile, sa.name, sa.name2, + aa_inode_mode(target->d_inode), + &sa.request_mask, + &sa.audit_mask); + sa.error_code = sa.denied_mask ? -EACCES : 0; + } + + error = aa_audit_file(profile, &sa); + + aa_put_name_buffer(buffer); + aa_put_name_buffer(buffer2); + + return error; +} + +int aa_net_perm(struct aa_profile *profile, char *operation, + int family, int type, int protocol) +{ + struct aa_audit sa; + int error = 0; + u16 family_mask, audit_mask, quiet_mask; + + if ((family < 0) || (family >= AF_MAX)) + return -EINVAL; + + if ((type < 0) || (type >= SOCK_MAX)) + return -EINVAL; + + /* unix domain and netlink sockets are handled by ipc */ + if (family == AF_UNIX || family == AF_NETLINK) + return 0; + + family_mask = profile->network_families[family]; + audit_mask = profile->audit_network[family]; + quiet_mask = profile->quiet_network[family]; + + error = (family_mask & (1 << type)) ? 0 : -EACCES; + + memset(&sa, 0, sizeof(sa)); + sa.operation = operation; + sa.gfp_mask = GFP_KERNEL; + sa.family = family; + sa.type = type; + sa.protocol = protocol; + sa.error_code = error; + + if (likely(!error)) { + if (!PROFILE_AUDIT(profile) && !(family_mask & audit_mask)) + return 0; + } else if (!((1 << type) & ~quiet_mask)) { + return error; + } + + error = aa_audit(profile, &sa); + + return error; +} + +int aa_revalidate_sk(struct sock *sk, char *operation) +{ + struct aa_profile *profile; + int error = 0; + + /* this is some debugging code to flush out the network hooks that + that are called in interrupt context */ + if (in_interrupt()) { + printk("AppArmor Debug: Hook being called from interrupt context\n"); + dump_stack(); + return 0; + } + + profile = aa_get_profile(current); + if (profile) + error = aa_net_perm(profile, operation, + sk->sk_family, sk->sk_type, + sk->sk_protocol); + aa_put_profile(profile); + + return error; +} +/** + * aa_task_setrlimit - test permission to set an rlimit + * @profile - profile confining the task + * @resource - the resource being set + * @new_rlim - the new resource limit + * + * Control raising the processes hard limit. + */ +int aa_task_setrlimit(struct aa_profile *profile, unsigned int resource, + struct rlimit *new_rlim) +{ + struct aa_audit sa; + int error = 0; + + memset(&sa, 0, sizeof(sa)); + sa.operation = "setrlimit"; + sa.gfp_mask = GFP_KERNEL; + sa.rlimit = resource + 1; + + if (profile->rlimits.mask & (1 << resource) && + new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max) { + sa.error_code = -EACCES; + + error = aa_audit(profile, &sa); + } + + return error; +} + +static int aa_rlimit_nproc(struct aa_profile *profile) { + if (profile && (profile->rlimits.mask & (1 << RLIMIT_NPROC)) && + profile->task_count >= profile->rlimits.limits[RLIMIT_NPROC].rlim_max) + return -EAGAIN; + return 0; +} + +void aa_set_rlimits(struct task_struct *task, struct aa_profile *profile) +{ + int i, mask; + + if (!profile) + return; + + if (!profile->rlimits.mask) + return; + + task_lock(task->group_leader); + mask = 1; + for (i = 0; i < RLIM_NLIMITS; i++, mask <<= 1) { + struct rlimit new_rlim, *old_rlim; + + /* check to see if NPROC which is per profile and handled + * in clone/exec or whether this is a limit to be set + * can't set cpu limit either right now + */ + if (i == RLIMIT_NPROC || i == RLIMIT_CPU) + continue; + + old_rlim = task->signal->rlim + i; + new_rlim = *old_rlim; + + if (mask & profile->rlimits.mask && + profile->rlimits.limits[i].rlim_max < new_rlim.rlim_max) { + new_rlim.rlim_max = profile->rlimits.limits[i].rlim_max; + /* soft limit should not exceed hard limit */ + if (new_rlim.rlim_cur > new_rlim.rlim_max) + new_rlim.rlim_cur = new_rlim.rlim_max; + } + + *old_rlim = new_rlim; + } + task_unlock(task->group_leader); +} + +/******************************* + * Global task related functions + *******************************/ + +/** + * aa_clone - initialize the task context for a new task + * @child: task that is being created + * + * Returns 0 on success, or else an error code. + */ +int aa_clone(struct task_struct *child) +{ + struct aa_audit sa; + struct aa_task_context *cxt, *child_cxt; + struct aa_profile *profile; + + if (!aa_task_context(current)) + return 0; + child_cxt = aa_alloc_task_context(GFP_KERNEL); + if (!child_cxt) + return -ENOMEM; + + memset(&sa, 0, sizeof(sa)); + sa.operation = "clone"; + sa.task = child->pid; + sa.gfp_mask = GFP_KERNEL; + +repeat: + profile = aa_get_profile(current); + if (profile) { + lock_profile(profile); + cxt = aa_task_context(current); + if (unlikely(profile->isstale || !cxt || + cxt->profile != profile)) { + /** + * Race with profile replacement or removal, or with + * task context removal. + */ + unlock_profile(profile); + aa_put_profile(profile); + goto repeat; + } + + if (aa_rlimit_nproc(profile)) { + sa.info = "rlimit nproc limit exceeded"; + unlock_profile(profile); + aa_audit_reject(profile, &sa); + aa_put_profile(profile); + return -EAGAIN; + } + + /* No need to grab the child's task lock here. */ + aa_change_task_context(child, child_cxt, profile, + cxt->cookie, cxt->previous_profile); + + unlock_profile(profile); + + if (APPARMOR_COMPLAIN(child_cxt) && + profile == profile->ns->null_complain_profile) { + aa_audit_hint(profile, &sa); + } + aa_put_profile(profile); + } else + aa_free_task_context(child_cxt); + + return 0; +} + +static struct aa_profile * +aa_register_find(struct aa_profile *profile, const char* ns_name, + const char *name, int mandatory, int complain, + struct aa_audit *sa) +{ + struct aa_namespace *ns; + struct aa_profile *new_profile; + int ns_ref = 0; + + if (profile) + ns = profile->ns; + else + ns = default_namespace; + + if (ns_name) { + /* locate the profile namespace */ + ns = aa_find_namespace(ns_name); + if (!ns) { + if (mandatory) { + sa->info = "profile namespace not found"; + sa->denied_mask = sa->request_mask; + sa->error_code = -ENOENT; + return ERR_PTR(-ENOENT); + } else { + return NULL; + } + } + ns_ref++; + } + + /* Locate new profile */ + new_profile = aa_find_profile(ns, name); + + if (new_profile) { + AA_DEBUG("%s: setting profile %s\n", + __FUNCTION__, new_profile->name); + } else if (mandatory && profile) { + sa->info = "mandatory profile missing"; + sa->denied_mask = sa->request_mask; /* shifted MAY_EXEC */ + if (complain) { + aa_audit_hint(profile, sa); + new_profile = + aa_dup_profile(profile->ns->null_complain_profile); + } else { + sa->error_code = -EACCES; + if (ns_ref) + aa_put_namespace(ns); + return ERR_PTR(-EACCES); + } + } else { + /* Only way we can get into this code is if task + * is unconfined, pix, nix. + */ + AA_DEBUG("%s: No profile found for exec image '%s'\n", + __FUNCTION__, + name); + } + if (ns_ref) + aa_put_namespace(ns); + return new_profile; +} + +static struct aa_profile * +aa_x_to_profile(struct aa_profile *profile, const char *filename, int xmode, + struct aa_audit *sa, char **child) +{ + struct aa_profile *new_profile = NULL; + int ix = xmode & AA_EXEC_INHERIT; + int complain = PROFILE_COMPLAIN(profile); + int index; + + *child = NULL; + switch (xmode & AA_EXEC_MODIFIERS) { + case 0: + /* only valid with ix flag */ + ix = 1; + break; + case AA_EXEC_UNCONFINED: + /* only valid without ix flag */ + ix = 0; + break; + case AA_EXEC_PROFILE: + new_profile = aa_register_find(profile, NULL, filename, !ix, + complain, sa); + break; + case AA_EXEC_CHILD: + *child = new_compound_name(profile->name, filename); + sa->name2 = *child; + if (!*child) { + sa->info = "Failed name resolution - exec failed"; + sa->error_code = -ENOMEM; + new_profile = ERR_PTR(-ENOMEM); + } else { + new_profile = aa_register_find(profile, NULL, *child, + !ix, complain, sa); + } + break; + default: + /* all other indexes are named transitions */ + index = AA_EXEC_INDEX(xmode); + if (index - 4 > profile->exec_table_size) { + sa->info = "invalid named transition - exec failed"; + sa->error_code = -EACCES; + new_profile = ERR_PTR(-EACCES); + } else { + char *ns_name = NULL; + char *name = profile->exec_table[index - 4]; + if (*name == ':') { + ns_name = name + 1; + name = ns_name + strlen(ns_name) + 1; + } + sa->name2 = name; + sa->name3 = ns_name; + new_profile = + aa_register_find(profile, ns_name, name, + !ix, complain, sa); + } + } + if (IS_ERR(new_profile)) + /* all these failures must be audited - no quieting */ + return ERR_PTR(aa_audit_reject(profile, sa)); + return new_profile; +} + +/** + * aa_register - register a new program + * @bprm: binprm of program being registered + * + * Try to register a new program during execve(). This should give the + * new program a valid aa_task_context if confined. + */ +int aa_register(struct linux_binprm *bprm) +{ + const char *filename; + char *buffer = NULL, *child = NULL; + struct file *filp = bprm->file; + struct aa_profile *profile, *old_profile, *new_profile = NULL; + int exec_mode, complain = 0, shift; + struct aa_audit sa; + + AA_DEBUG("%s\n", __FUNCTION__); + + profile = aa_get_profile(current); + + shift = aa_inode_mode(filp->f_dentry->d_inode); + memset(&sa, 0, sizeof(sa)); + sa.operation = "exec"; + sa.gfp_mask = GFP_KERNEL; + sa.request_mask = MAY_EXEC << shift; + + filename = aa_get_name(filp->f_dentry, filp->f_vfsmnt, &buffer, 0); + if (IS_ERR(filename)) { + if (profile) { + sa.info = "Failed name resolution - exec failed"; + sa.error_code = PTR_ERR(filename); + aa_audit_file(profile, &sa); + return sa.error_code; + } else + return 0; + } + sa.name = filename; + + exec_mode = AA_EXEC_UNSAFE << shift; + +repeat: + if (profile) { + complain = PROFILE_COMPLAIN(profile); + + /* Confined task, determine what mode inherit, unconfined or + * mandatory to load new profile + */ + exec_mode = aa_match(profile->file_rules, filename, + &sa.audit_mask); + + + if (exec_mode & sa.request_mask) { + int xm = exec_mode >> shift; + new_profile = aa_x_to_profile(profile, filename, + xm, &sa, &child); + + if (!new_profile && (xm & AA_EXEC_INHERIT)) + /* (p|c|n|)ix - don't change profile */ + goto cleanup; + /* error case caught below */ + + } else if (sa.request_mask & AUDIT_QUIET_MASK(sa.audit_mask)) { + /* quiet failed exit */ + new_profile = ERR_PTR(-EACCES); + } else if (complain) { + /* There was no entry in calling profile + * describing mode to execute image in. + * Drop into null-profile (disabling secure exec). + */ + new_profile = + aa_dup_profile(profile->ns->null_complain_profile); + exec_mode |= AA_EXEC_UNSAFE << shift; + } else { + sa.denied_mask = sa.request_mask; + sa.error_code = -EACCES; + new_profile = ERR_PTR(aa_audit_file(profile, &sa)); + } + } else { + /* Unconfined task, load profile if it exists */ + new_profile = aa_register_find(NULL, NULL, filename, 0, 0, &sa); + if (new_profile == NULL) + goto cleanup; + } + + if (IS_ERR(new_profile)) + goto cleanup; + + old_profile = __aa_replace_profile(current, new_profile); + if (IS_ERR(old_profile)) { + aa_put_profile(new_profile); + aa_put_profile(profile); + if (PTR_ERR(old_profile) == -ESTALE) { + profile = aa_get_profile(current); + goto repeat; + } + if (PTR_ERR(old_profile) == -EPERM) { + sa.denied_mask = sa.request_mask; + sa.info = "unable to set profile due to ptrace"; + sa.task = current->parent->pid; + aa_audit_reject(profile, &sa); + } + if (PTR_ERR(old_profile) == -EAGAIN) { + sa.info = "rlimit nproc limit exceeded"; + aa_audit_reject(profile, &sa); + } + new_profile = old_profile; + goto cleanup; + } + aa_put_profile(old_profile); + aa_put_profile(profile); + + /* Handle confined exec. + * Can be at this point for the following reasons: + * 1. unconfined switching to confined + * 2. confined switching to different confinement + * 3. confined switching to unconfined + * + * Cases 2 and 3 are marked as requiring secure exec + * (unless policy specified "unsafe exec") + */ + if (!(exec_mode & (AA_EXEC_UNSAFE << shift))) { + unsigned long bprm_flags; + + bprm_flags = AA_SECURE_EXEC_NEEDED; + bprm->security = (void*) + ((unsigned long)bprm->security | bprm_flags); + } + + if (complain && new_profile && + new_profile == new_profile->ns->null_complain_profile) { + sa.request_mask = 0; + sa.name = NULL; + sa.info = "set profile"; + aa_audit_hint(new_profile, &sa); + } + +cleanup: + aa_put_name_buffer(child); + aa_put_name_buffer(buffer); + if (IS_ERR(new_profile)) + return PTR_ERR(new_profile); + aa_put_profile(new_profile); + return 0; +} + +/** + * aa_release - release a task context + * @task: task being released + * + * This is called after a task has exited and the parent has reaped it. + */ +void aa_release(struct task_struct *task) +{ + struct aa_task_context *cxt; + struct aa_profile *profile; + /* + * While the task context is still on a profile's task context + * list, another process could replace the profile under us, + * leaving us with a locked profile that is no longer attached + * to this task. So after locking the profile, we check that + * the profile is still attached. The profile lock is + * sufficient to prevent the replacement race so we do not lock + * the task. + * + * Use lock subtyping to avoid lockdep reporting a false irq + * possible inversion between the task_lock and profile_lock + * + * We also avoid taking the task_lock here because lock_dep + * would report another false {softirq-on-W} potential irq_lock + * inversion. + * + * If the task does not have a profile attached we are safe; + * nothing can race with us at this point. + */ + +repeat: + profile = aa_get_profile(task); + if (profile) { + lock_profile_nested(profile, aa_lock_task_release); + cxt = aa_task_context(task); + if (unlikely(!cxt || cxt->profile != profile)) { + unlock_profile(profile); + aa_put_profile(profile); + goto repeat; + } + aa_change_task_context(task, NULL, NULL, 0, NULL); + unlock_profile(profile); + aa_put_profile(profile); + } +} + +static int do_change_profile(struct aa_profile *expected, + struct aa_namespace *ns, const char *name, + u64 cookie, int restore, int hat, + struct aa_audit *sa) +{ + struct aa_profile *new_profile = NULL, *old_profile = NULL, + *previous_profile = NULL; + struct aa_task_context *new_cxt, *cxt; + int error = 0; + + sa->name = name; + + new_cxt = aa_alloc_task_context(GFP_KERNEL); + if (!new_cxt) + return -ENOMEM; + + new_profile = aa_find_profile(ns, name); + if (!new_profile && !restore) { + if (!PROFILE_COMPLAIN(expected)) { + aa_free_task_context(new_cxt); + return -ENOENT; + } + new_profile = aa_dup_profile(ns->null_complain_profile); + } else if (new_profile && hat && !PROFILE_IS_HAT(new_profile)) { + aa_free_task_context(new_cxt); + aa_put_profile(new_profile); + return error; + } + + cxt = lock_task_and_profiles(current, new_profile); + if (!cxt) { + error = -EPERM; + goto out; + } + old_profile = cxt->profile; + + if (cxt->profile != expected || (new_profile && new_profile->isstale)) { + error = -ESTALE; + goto out; + } + + if (cxt->previous_profile) { + if (cxt->cookie != cookie) { + error = -EACCES; + sa->info = "killing process"; + aa_audit_reject(cxt->profile, sa); + /* terminate process */ + (void)send_sig_info(SIGKILL, NULL, current); + goto out; + } + + if (!restore) + previous_profile = cxt->previous_profile; + } else + previous_profile = cxt->profile; + + if ((current->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, new_profile)) { + error = -EACCES; + goto out; + } + + if ((error = aa_rlimit_nproc(new_profile))) { + sa->info = "rlimit nproc limit exceeded"; + aa_audit_reject(cxt->profile, sa); + goto out; + } + + if (new_profile == ns->null_complain_profile) + aa_audit_hint(cxt->profile, sa); + + if (APPARMOR_AUDIT(cxt)) + aa_audit_message(cxt->profile, sa, AUDIT_APPARMOR_AUDIT); + + if (!restore && cookie) + aa_change_task_context(current, new_cxt, new_profile, cookie, + previous_profile); + else + /* either return to previous_profile, or a permanent change */ + aa_change_task_context(current, new_cxt, new_profile, 0, NULL); + +out: + if (aa_task_context(current) != new_cxt) + aa_free_task_context(new_cxt); + task_unlock(current); + unlock_both_profiles(old_profile, new_profile); + aa_put_profile(new_profile); + return error; +} + +/** + * aa_change_profile - perform a one-way profile transition + * @ns_name: name of the profile namespace to change to + * @name: name of profile to change to + * Change to new profile @name. Unlike with hats, there is no way + * to change back. + * + * Returns %0 on success, error otherwise. + */ +int aa_change_profile(const char *ns_name, const char *name) +{ + struct aa_task_context *cxt; + struct aa_profile *profile = NULL; + struct aa_namespace *ns = NULL; + struct aa_audit sa; + unsigned int state; + int error = -EINVAL; + + if (!name) + return -EINVAL; + + memset(&sa, 0, sizeof(sa)); + sa.gfp_mask = GFP_ATOMIC; + sa.operation = "change_profile"; + +repeat: + task_lock(current); + cxt = aa_task_context(current); + if (cxt) + profile = aa_dup_profile(cxt->profile); + task_unlock(current); + + if (ns_name) + ns = aa_find_namespace(ns_name); + else if (profile) + ns = aa_get_namespace(profile->ns); + else + ns = aa_get_namespace(default_namespace); + + if (!ns) { + aa_put_profile(profile); + return -ENOENT; + } + + if (!profile || PROFILE_COMPLAIN(profile) || + (ns == profile->ns && + (aa_match(profile->file_rules, name, NULL) & AA_CHANGE_PROFILE))) + error = do_change_profile(profile, ns, name, 0, 0, 0, &sa); + else { + /* check for a rule with a namespace prepended */ + aa_match_state(profile->file_rules, DFA_START, ns->name, + &state); + state = aa_dfa_null_transition(profile->file_rules, state); + if ((aa_match_state(profile->file_rules, state, name, NULL) & + AA_CHANGE_PROFILE)) + error = do_change_profile(profile, ns, name, 0, 0, 0, + &sa); + else + /* no permission to transition to profile @name */ + error = -EACCES; + } + + aa_put_namespace(ns); + aa_put_profile(profile); + if (error == -ESTALE) + goto repeat; + + return error; +} + +/** + * aa_change_hat - change hat to/from subprofile + * @hat_name: hat to change to + * @cookie: magic value to validate the hat change + * + * Change to new @hat_name, and store the @hat_magic in the current task + * context. If the new @hat_name is %NULL and the @cookie matches that + * stored in the current task context and is not 0, return to the top level + * profile. + * Returns %0 on success, error otherwise. + */ +int aa_change_hat(const char *hat_name, u64 cookie) +{ + struct aa_task_context *cxt; + struct aa_profile *profile, *previous_profile; + struct aa_audit sa; + int error = 0; + + memset(&sa, 0, sizeof(sa)); + sa.gfp_mask = GFP_ATOMIC; + sa.operation = "change_hat"; + +repeat: + task_lock(current); + cxt = aa_task_context(current); + if (!cxt) { + task_unlock(current); + return -EPERM; + } + profile = aa_dup_profile(cxt->profile); + previous_profile = aa_dup_profile(cxt->previous_profile); + task_unlock(current); + + if (hat_name) { + char *name, *profile_name; + + if (previous_profile) + profile_name = previous_profile->name; + else + profile_name = profile->name; + + name = new_compound_name(profile_name, hat_name); + if (!name) { + error = -ENOMEM; + goto out; + } + error = do_change_profile(profile, profile->ns, name, cookie, + 0, 1, &sa); + aa_put_name_buffer(name); + } else if (previous_profile) + error = do_change_profile(profile, profile->ns, + previous_profile->name, cookie, 1, 0, + &sa); + /* else ignore restores when there is no saved profile */ + +out: + aa_put_profile(previous_profile); + aa_put_profile(profile); + if (error == -ESTALE) + goto repeat; + + return error; +} + +/** + * __aa_replace_profile - replace a task's profile + * @task: task to switch the profile of + * @profile: profile to switch to + * + * Returns a handle to the previous profile upon success, or else an + * error code. + */ +struct aa_profile *__aa_replace_profile(struct task_struct *task, + struct aa_profile *profile) +{ + struct aa_task_context *cxt, *new_cxt = NULL; + struct aa_profile *old_profile = NULL; + + if (profile) { + new_cxt = aa_alloc_task_context(GFP_KERNEL); + if (!new_cxt) + return ERR_PTR(-ENOMEM); + } + + cxt = lock_task_and_profiles(task, profile); + if (unlikely(profile && profile->isstale)) { + old_profile = ERR_PTR(-ESTALE); + goto error; + } + + if ((current->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, profile)) { + old_profile = ERR_PTR(-EPERM); + goto error; + } + + if (aa_rlimit_nproc(profile)) { + old_profile = ERR_PTR(-EAGAIN); + goto error; + } + + if (cxt) + old_profile = aa_dup_profile(cxt->profile); + aa_change_task_context(task, new_cxt, profile, 0, NULL); + + task_unlock(task); + aa_set_rlimits(task, profile); + unlock_both_profiles(profile, old_profile); + return old_profile; + +error: + task_unlock(task); + unlock_both_profiles(profile, cxt ? cxt->profile : NULL); + aa_free_task_context(new_cxt); + return old_profile; +} + +/** + * lock_task_and_profiles - lock the task and confining profiles and @profile + * @task: task to lock + * @profile: extra profile to lock in addition to the current profile + * + * Handle the spinning on locking to make sure the task context and + * profile are consistent once all locks are aquired. + * + * return the aa_task_context currently confining the task. The task lock + * will be held whether or not the task is confined. + */ +struct aa_task_context * +lock_task_and_profiles(struct task_struct *task, struct aa_profile *profile) +{ + struct aa_task_context *cxt; + struct aa_profile *old_profile = NULL; + + rcu_read_lock(); +repeat: + cxt = aa_task_context(task); + if (cxt) + old_profile = cxt->profile; + + lock_both_profiles(profile, old_profile); + task_lock(task); + + /* check for race with profile transition, replacement or removal */ + if (unlikely(cxt != aa_task_context(task))) { + task_unlock(task); + unlock_both_profiles(profile, old_profile); + old_profile = NULL; + goto repeat; + } + rcu_read_unlock(); + return cxt; +} + +static void free_aa_task_context_rcu_callback(struct rcu_head *head) +{ + struct aa_task_context *cxt; + + cxt = container_of(head, struct aa_task_context, rcu); + aa_free_task_context(cxt); +} + +/** + * aa_change_task_context - switch a task to use a new context and profile + * @task: task that is having its task context changed + * @new_cxt: new task context to use after the switch + * @profile: new profile to use after the switch + * @cookie: magic value to switch to + * @previous_profile: profile the task can return to + */ +void aa_change_task_context(struct task_struct *task, + struct aa_task_context *new_cxt, + struct aa_profile *profile, u64 cookie, + struct aa_profile *previous_profile) +{ + struct aa_task_context *old_cxt = aa_task_context(task); + + if (old_cxt) { + list_del_init(&old_cxt->list); + old_cxt->profile->task_count--; + call_rcu(&old_cxt->rcu, free_aa_task_context_rcu_callback); + } + if (new_cxt) { + /* set the caps_logged cache to the quiet_caps mask + * this has the effect of quieting caps that are not + * supposed to be logged + */ + new_cxt->caps_logged = profile->quiet_caps; + new_cxt->cookie = cookie; + new_cxt->task = task; + new_cxt->profile = aa_dup_profile(profile); + profile->task_count++; + new_cxt->previous_profile = aa_dup_profile(previous_profile); + list_move(&new_cxt->list, &profile->task_contexts); + } + rcu_assign_pointer(task->security, new_cxt); +} --- linux-2.6.28.orig/lib/kobject_uevent.c +++ linux-2.6.28/lib/kobject_uevent.c @@ -316,7 +316,7 @@ "kobject_uevent: unable to create netlink socket!\n"); return -ENODEV; } - + netlink_set_nonroot(NETLINK_KOBJECT_UEVENT, NL_NONROOT_RECV); return 0; } --- linux-2.6.28.orig/lib/idr.c +++ linux-2.6.28/lib/idr.c @@ -121,7 +121,7 @@ { while (idp->id_free_cnt < IDR_FREE_MAX) { struct idr_layer *new; - new = kmem_cache_alloc(idr_layer_cache, gfp_mask); + new = kmem_cache_zalloc(idr_layer_cache, gfp_mask); if (new == NULL) return (0); move_to_free_list(idp, new); @@ -623,16 +623,10 @@ } EXPORT_SYMBOL(idr_replace); -static void idr_cache_ctor(void *idr_layer) -{ - memset(idr_layer, 0, sizeof(struct idr_layer)); -} - void __init idr_init_cache(void) { idr_layer_cache = kmem_cache_create("idr_layer_cache", - sizeof(struct idr_layer), 0, SLAB_PANIC, - idr_cache_ctor); + sizeof(struct idr_layer), 0, SLAB_PANIC, NULL); } /** --- linux-2.6.28.orig/include/mtd/mtd-abi.h +++ linux-2.6.28/include/mtd/mtd-abi.h @@ -28,12 +28,17 @@ #define MTD_BIT_WRITEABLE 0x800 /* Single bits can be flipped */ #define MTD_NO_ERASE 0x1000 /* No erase necessary */ #define MTD_POWERUP_LOCK 0x2000 /* Always locked after reset */ +#define MTD_OOB_WRITEABLE 0x4000 /* Use Out-Of-Band area */ // Some common devices / combinations of capabilities #define MTD_CAP_ROM 0 #define MTD_CAP_RAM (MTD_WRITEABLE | MTD_BIT_WRITEABLE | MTD_NO_ERASE) #define MTD_CAP_NORFLASH (MTD_WRITEABLE | MTD_BIT_WRITEABLE) +#ifdef CONFIG_ARCH_MXC_CANONICAL +#define MTD_CAP_NANDFLASH (MTD_WRITEABLE | MTD_OOB_WRITEABLE) +#else #define MTD_CAP_NANDFLASH (MTD_WRITEABLE) +#endif /* ECC byte placement */ #define MTD_NANDECC_OFF 0 // Switch off ECC (Not recommended) --- linux-2.6.28.orig/include/trace/fs.h +++ linux-2.6.28/include/trace/fs.h @@ -0,0 +1,11 @@ +#ifndef _TRACE_FS_H +#define _TRACE_FS_H + +#include +#include + +DEFINE_TRACE(do_sys_open, + TPPROTO(struct file *filp, int flags, int mode, long fd), + TPARGS(filp, flags, mode, fd)); + +#endif --- linux-2.6.28.orig/include/drm/drm_pciids.h +++ linux-2.6.28/include/drm/drm_pciids.h @@ -239,10 +239,123 @@ {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x791e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ {0x1002, 0x791f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ + {0x1002, 0x793f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS600|RADEON_IS_IGP|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x7941, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS600|RADEON_IS_IGP|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x7942, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS600|RADEON_IS_IGP|RADEON_NEW_MEMMAP}, \ {0x1002, 0x796c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ {0x1002, 0x796d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ {0x1002, 0x796e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ {0x1002, 0x796f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \ + {0x1002, 0x9400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R600|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9401, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R600|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9402, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R600|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9403, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R600|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9405, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R600|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x940A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R600|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x940B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R600|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x940F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R600|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9440, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9441, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9442, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9444, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x944A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x944B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x944C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x944E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9450, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9452, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9456, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x945A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x945B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x946A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x946B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x947A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x947B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV770|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9480, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9487, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9488, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9489, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x948F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9490, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9491, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9498, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x949C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x949E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x949F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV730|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x94C0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV610|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x94C1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV610|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x94C3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV610|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x94C4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV610|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x94C5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV610|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x94C6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV610|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x94C7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV610|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x94C8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV610|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x94C9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV610|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x94CB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV610|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x94CC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV610|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x94CD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV610|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9500, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9501, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9504, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9505, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9506, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9507, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9508, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9509, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x950F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9511, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9515, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9517, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9519, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV670|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9540, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9541, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9542, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x954E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x954F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9552, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9553, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9555, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV710|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9580, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9581, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9583, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9586, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9587, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9588, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9589, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x958A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x958B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x958C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x958D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x958E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x958F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV630|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9590, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV635|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9591, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV635|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9593, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV635|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9595, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV635|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9596, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV635|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9597, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV635|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9598, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV635|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9599, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV635|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x959B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV635|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x95C0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x95C5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x95C6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x95C7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x95C9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x95C2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x95C4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x95CC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x95CD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x95CE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x95CF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV620|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x9610, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9611, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9612, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9613, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9614, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9615, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9616, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS780|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0, 0, 0} #define r128_PCI_IDS \ --- linux-2.6.28.orig/include/drm/i915_drm.h +++ linux-2.6.28/include/drm/i915_drm.h @@ -113,8 +113,31 @@ int pipeB_y; int pipeB_w; int pipeB_h; + + /* fill out some space for old userspace triple buffer */ + drm_handle_t unused_handle; + uint32_t unused1, unused2, unused3; + + /* buffer object handles for static buffers. May change + * over the lifetime of the client. + */ + uint32_t front_bo_handle; + uint32_t back_bo_handle; + uint32_t unused_bo_handle; + uint32_t depth_bo_handle; + } drm_i915_sarea_t; +/* due to userspace building against these headers we need some compat here */ +#define planeA_x pipeA_x +#define planeA_y pipeA_y +#define planeA_w pipeA_w +#define planeA_h pipeA_h +#define planeB_x pipeB_x +#define planeB_y pipeB_y +#define planeB_w pipeB_w +#define planeB_h pipeB_h + /* Flags for perf_boxes */ #define I915_BOX_RING_EMPTY 0x1 @@ -177,6 +200,8 @@ #define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t) #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t) #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t) +#define DRM_IOCTL_I915_GEM_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_INIT, struct drm_i915_gem_init) +#define DRM_IOCTL_I915_GEM_EXECBUFFER DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER, struct drm_i915_gem_execbuffer) #define DRM_IOCTL_I915_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_PIN, struct drm_i915_gem_pin) #define DRM_IOCTL_I915_GEM_UNPIN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_UNPIN, struct drm_i915_gem_unpin) #define DRM_IOCTL_I915_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_BUSY, struct drm_i915_gem_busy) --- linux-2.6.28.orig/include/drm/radeon_drm.h +++ linux-2.6.28/include/drm/radeon_drm.h @@ -304,6 +304,8 @@ #define RADEON_SCRATCH_REG_OFFSET 32 +#define R600_SCRATCH_REG_OFFSET 256 + #define RADEON_NR_SAREA_CLIPRECTS 12 /* There are 2 heaps (local/GART). Each region within a heap is a @@ -526,7 +528,8 @@ RADEON_INIT_CP = 0x01, RADEON_CLEANUP_CP = 0x02, RADEON_INIT_R200_CP = 0x03, - RADEON_INIT_R300_CP = 0x04 + RADEON_INIT_R300_CP = 0x04, + RADEON_INIT_R600_CP = 0x05 } func; unsigned long sarea_priv_offset; int is_pci; --- linux-2.6.28.orig/include/media/videobuf-dma-sg.h +++ linux-2.6.28/include/media/videobuf-dma-sg.h @@ -49,7 +49,7 @@ * does memory allocation too using vmalloc_32(). * * videobuf_dma_*() - * see Documentation/DMA-mapping.txt, these functions to + * see Documentation/PCI/PCI-DMA-mapping.txt, these functions to * basically the same. The map function does also build a * scatterlist for the buffer (and unmap frees it ...) * --- linux-2.6.28.orig/include/linux/security.h +++ linux-2.6.28/include/linux/security.h @@ -54,9 +54,11 @@ extern int cap_bprm_set_security(struct linux_binprm *bprm); extern void cap_bprm_apply_creds(struct linux_binprm *bprm, int unsafe); extern int cap_bprm_secureexec(struct linux_binprm *bprm); -extern int cap_inode_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags); -extern int cap_inode_removexattr(struct dentry *dentry, const char *name); +extern int cap_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, size_t size, + int flags, struct file *file); +extern int cap_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *file); extern int cap_inode_need_killpriv(struct dentry *dentry); extern int cap_inode_killpriv(struct dentry *dentry); extern int cap_task_post_setuid(uid_t old_ruid, uid_t old_euid, uid_t old_suid, int flags); @@ -337,23 +339,28 @@ * Check permission to create a regular file. * @dir contains inode structure of the parent of the new file. * @dentry contains the dentry structure for the file to be created. + * @mnt is the vfsmount corresponding to @dentry (may be NULL). * @mode contains the file mode of the file to be created. * Return 0 if permission is granted. * @inode_link: * Check permission before creating a new hard link to a file. * @old_dentry contains the dentry structure for an existing link to the file. + * @old_mnt is the vfsmount corresponding to @old_dentry (may be NULL). * @dir contains the inode structure of the parent directory of the new link. * @new_dentry contains the dentry structure for the new link. + * @new_mnt is the vfsmount corresponding to @new_dentry (may be NULL). * Return 0 if permission is granted. * @inode_unlink: * Check the permission to remove a hard link to a file. * @dir contains the inode structure of parent directory of the file. * @dentry contains the dentry structure for file to be unlinked. + * @mnt is the vfsmount corresponding to @dentry (may be NULL). * Return 0 if permission is granted. * @inode_symlink: * Check the permission to create a symbolic link to a file. * @dir contains the inode structure of parent directory of the symbolic link. * @dentry contains the dentry structure of the symbolic link. + * @mnt is the vfsmount corresponding to @dentry (may be NULL). * @old_name contains the pathname of file. * Return 0 if permission is granted. * @inode_mkdir: @@ -361,12 +368,14 @@ * associated with inode strcture @dir. * @dir containst the inode structure of parent of the directory to be created. * @dentry contains the dentry structure of new directory. + * @mnt is the vfsmount corresponding to @dentry (may be NULL). * @mode contains the mode of new directory. * Return 0 if permission is granted. * @inode_rmdir: * Check the permission to remove a directory. * @dir contains the inode structure of parent of the directory to be removed. * @dentry contains the dentry structure of directory to be removed. + * @mnt is the vfsmount corresponding to @dentry (may be NULL). * Return 0 if permission is granted. * @inode_mknod: * Check permissions when creating a special file (or a socket or a fifo @@ -375,6 +384,7 @@ * and not this hook. * @dir contains the inode structure of parent of the new file. * @dentry contains the dentry structure of the new file. + * @mnt is the vfsmount corresponding to @dentry (may be NULL). * @mode contains the mode of the new file. * @dev contains the device number. * Return 0 if permission is granted. @@ -382,12 +392,15 @@ * Check for permission to rename a file or directory. * @old_dir contains the inode structure for parent of the old link. * @old_dentry contains the dentry structure of the old link. + * @old_mnt is the vfsmount corresponding to @old_dentry (may be NULL). * @new_dir contains the inode structure for parent of the new link. * @new_dentry contains the dentry structure of the new link. + * @new_mnt is the vfsmount corresponding to @new_dentry (may be NULL). * Return 0 if permission is granted. * @inode_readlink: * Check the permission to read the symbolic link. * @dentry contains the dentry structure for the file link. + * @mnt is the vfsmount corresponding to @dentry (may be NULL). * Return 0 if permission is granted. * @inode_follow_link: * Check permission to follow a symbolic link when looking up a pathname. @@ -411,6 +424,7 @@ * file attributes change (such as when a file is truncated, chown/chmod * operations, transferring disk quotas, etc). * @dentry contains the dentry structure for the file. + * @mnt is the vfsmount corresponding to @dentry (may be NULL). * @attr is the iattr structure containing the new file attributes. * Return 0 if permission is granted. * @inode_getattr: @@ -426,18 +440,18 @@ * inode. * @inode_setxattr: * Check permission before setting the extended attributes - * @value identified by @name for @dentry. + * @value identified by @name for @dentry and @mnt. * Return 0 if permission is granted. * @inode_post_setxattr: * Update inode security field after successful setxattr operation. - * @value identified by @name for @dentry. + * @value identified by @name for @dentry and @mnt. * @inode_getxattr: * Check permission before obtaining the extended attributes - * identified by @name for @dentry. + * identified by @name for @dentry and @mnt. * Return 0 if permission is granted. * @inode_listxattr: * Check permission before obtaining the list of extended attribute - * names for @dentry. + * names for @dentry and @mnt. * Return 0 if permission is granted. * @inode_removexattr: * Check permission before removing the extended attribute @@ -578,6 +592,20 @@ * file_permission, and recheck access if anything has changed * since inode_permission. * + * Security hook for path + * + * @path_permission: + * Check permission before accessing a path. This hook is called by the + * existing Linux permission function, so a security module can use it to + * provide additional checking for existing Linux permission checks. + * Notice that this hook is called when a file is opened (as well as many + * other operations), whereas the file_security_ops permission hook is + * called when the actual read/write operations are performed. This + * hook is optional and if absent, inode_permission will be substituted. + * @path contains the path structure to check. + * @mask contains the permission mask. + * Return 0 if permission is granted. + * Security hooks for task operations. * * @task_create: @@ -1354,32 +1382,45 @@ void (*inode_free_security) (struct inode *inode); int (*inode_init_security) (struct inode *inode, struct inode *dir, char **name, void **value, size_t *len); - int (*inode_create) (struct inode *dir, - struct dentry *dentry, int mode); - int (*inode_link) (struct dentry *old_dentry, - struct inode *dir, struct dentry *new_dentry); - int (*inode_unlink) (struct inode *dir, struct dentry *dentry); - int (*inode_symlink) (struct inode *dir, - struct dentry *dentry, const char *old_name); - int (*inode_mkdir) (struct inode *dir, struct dentry *dentry, int mode); - int (*inode_rmdir) (struct inode *dir, struct dentry *dentry); + int (*inode_create) (struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode); + int (*inode_link) (struct dentry *old_dentry, struct vfsmount *old_mnt, + struct inode *dir, struct dentry *new_dentry, + struct vfsmount *new_mnt); + int (*inode_unlink) (struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt); + int (*inode_symlink) (struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, const char *old_name); + int (*inode_mkdir) (struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode); + int (*inode_rmdir) (struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt); int (*inode_mknod) (struct inode *dir, struct dentry *dentry, - int mode, dev_t dev); + struct vfsmount *mnt, int mode, dev_t dev); int (*inode_rename) (struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry); - int (*inode_readlink) (struct dentry *dentry); + struct vfsmount *old_mnt, + struct inode *new_dir, struct dentry *new_dentry, + struct vfsmount *new_mnt); + int (*inode_readlink) (struct dentry *dentry, struct vfsmount *mnt); int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd); int (*inode_permission) (struct inode *inode, int mask); - int (*inode_setattr) (struct dentry *dentry, struct iattr *attr); + int (*inode_setattr) (struct dentry *dentry, struct vfsmount *, + struct iattr *attr); int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry); void (*inode_delete) (struct inode *inode); - int (*inode_setxattr) (struct dentry *dentry, const char *name, - const void *value, size_t size, int flags); - void (*inode_post_setxattr) (struct dentry *dentry, const char *name, - const void *value, size_t size, int flags); - int (*inode_getxattr) (struct dentry *dentry, const char *name); - int (*inode_listxattr) (struct dentry *dentry); - int (*inode_removexattr) (struct dentry *dentry, const char *name); + int (*inode_setxattr) (struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, size_t size, + int flags, struct file *file); + void (*inode_post_setxattr) (struct dentry *dentry, + struct vfsmount *mnt, + const char *name, const void *value, + size_t size, int flags); + int (*inode_getxattr) (struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *file); + int (*inode_listxattr) (struct dentry *dentry, struct vfsmount *mnt, + struct file *file); + int (*inode_removexattr) (struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *file); int (*inode_need_killpriv) (struct dentry *dentry); int (*inode_killpriv) (struct dentry *dentry); int (*inode_getsecurity) (const struct inode *inode, const char *name, void **buffer, bool alloc); @@ -1407,6 +1448,7 @@ struct fown_struct *fown, int sig); int (*file_receive) (struct file *file); int (*dentry_open) (struct file *file); + int (*path_permission) (struct path *path, int mask); int (*task_create) (unsigned long clone_flags); int (*task_alloc_security) (struct task_struct *p); @@ -1618,30 +1660,43 @@ void security_inode_free(struct inode *inode); int security_inode_init_security(struct inode *inode, struct inode *dir, char **name, void **value, size_t *len); -int security_inode_create(struct inode *dir, struct dentry *dentry, int mode); -int security_inode_link(struct dentry *old_dentry, struct inode *dir, - struct dentry *new_dentry); -int security_inode_unlink(struct inode *dir, struct dentry *dentry); +int security_inode_create(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode); +int security_inode_link(struct dentry *old_dentry, struct vfsmount *old_mnt, + struct inode *dir, struct dentry *new_dentry, + struct vfsmount *new_mnt); +int security_inode_unlink(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt); int security_inode_symlink(struct inode *dir, struct dentry *dentry, - const char *old_name); -int security_inode_mkdir(struct inode *dir, struct dentry *dentry, int mode); -int security_inode_rmdir(struct inode *dir, struct dentry *dentry); -int security_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev); + struct vfsmount *mnt, const char *old_name); +int security_inode_mkdir(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode); +int security_inode_rmdir(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt); +int security_inode_mknod(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode, dev_t dev); int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry); -int security_inode_readlink(struct dentry *dentry); + struct vfsmount *old_mnt, struct inode *new_dir, + struct dentry *new_dentry, struct vfsmount *new_mnt); +int security_inode_readlink(struct dentry *dentry, struct vfsmount *mnt); int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd); int security_inode_permission(struct inode *inode, int mask); -int security_inode_setattr(struct dentry *dentry, struct iattr *attr); +int security_inode_setattr(struct dentry *dentry, struct vfsmount *mnt, + struct iattr *attr); int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry); void security_inode_delete(struct inode *inode); -int security_inode_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags); -void security_inode_post_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags); -int security_inode_getxattr(struct dentry *dentry, const char *name); -int security_inode_listxattr(struct dentry *dentry); -int security_inode_removexattr(struct dentry *dentry, const char *name); +int security_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, + size_t size, int flags, struct file *file); +void security_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, + size_t size, int flags); +int security_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *file); +int security_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt, + struct file *file); +int security_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *file); int security_inode_need_killpriv(struct dentry *dentry); int security_inode_killpriv(struct dentry *dentry); int security_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc); @@ -1664,6 +1719,7 @@ struct fown_struct *fown, int sig); int security_file_receive(struct file *file); int security_dentry_open(struct file *file); +int security_path_permission(struct path *path, int mask); int security_task_create(unsigned long clone_flags); int security_task_alloc(struct task_struct *p); void security_task_free(struct task_struct *p); @@ -1973,26 +2029,31 @@ static inline int security_inode_create(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode) { return 0; } static inline int security_inode_link(struct dentry *old_dentry, - struct inode *dir, - struct dentry *new_dentry) + struct vfsmount *old_mnt, + struct inode *dir, + struct dentry *new_dentry, + struct vfsmount *new_mnt) { return 0; } static inline int security_inode_unlink(struct inode *dir, - struct dentry *dentry) + struct dentry *dentry, + struct vfsmount *mnt) { return 0; } static inline int security_inode_symlink(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, const char *old_name) { return 0; @@ -2000,19 +2061,22 @@ static inline int security_inode_mkdir(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode) { return 0; } static inline int security_inode_rmdir(struct inode *dir, - struct dentry *dentry) + struct dentry *dentry, + struct vfsmount *mnt) { return 0; } static inline int security_inode_mknod(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode, dev_t dev) { return 0; @@ -2020,13 +2084,16 @@ static inline int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry, + struct vfsmount *old_mnt, struct inode *new_dir, - struct dentry *new_dentry) + struct dentry *new_dentry, + struct vfsmount *new_mnt) { return 0; } -static inline int security_inode_readlink(struct dentry *dentry) +static inline int security_inode_readlink(struct dentry *dentry, + struct vfsmount *mnt) { return 0; } @@ -2043,7 +2110,8 @@ } static inline int security_inode_setattr(struct dentry *dentry, - struct iattr *attr) + struct vfsmount *mnt, + struct iattr *attr) { return 0; } @@ -2058,30 +2126,42 @@ { } static inline int security_inode_setxattr(struct dentry *dentry, - const char *name, const void *value, size_t size, int flags) + struct vfsmount *mnt, + const char *name, const void *value, + size_t size, int flags, + struct file *file) { - return cap_inode_setxattr(dentry, name, value, size, flags); + return cap_inode_setxattr(dentry, mnt, name, value, size, flags, file); } static inline void security_inode_post_setxattr(struct dentry *dentry, - const char *name, const void *value, size_t size, int flags) + struct vfsmount *mnt, + const char *name, + const void *value, + size_t size, int flags) { } static inline int security_inode_getxattr(struct dentry *dentry, - const char *name) + struct vfsmount *mnt, + const char *name, + struct file *file) { return 0; } -static inline int security_inode_listxattr(struct dentry *dentry) +static inline int security_inode_listxattr(struct dentry *dentry, + struct vfsmount *mnt, + struct file *file) { return 0; } static inline int security_inode_removexattr(struct dentry *dentry, - const char *name) + struct vfsmount *mnt, + const char *name, + struct file *file) { - return cap_inode_removexattr(dentry, name); + return cap_inode_removexattr(dentry, mnt, name, file); } static inline int security_inode_need_killpriv(struct dentry *dentry) @@ -2182,6 +2262,11 @@ return 0; } +static inline int security_path_permission(struct path *path, int mask) +{ + return 0; +} + static inline int security_task_create(unsigned long clone_flags) { return 0; --- linux-2.6.28.orig/include/linux/ata.h +++ linux-2.6.28/include/linux/ata.h @@ -731,12 +731,17 @@ static inline int ata_id_is_cfa(const u16 *id) { - if (id[ATA_ID_CONFIG] == 0x848A) /* Standard CF */ + if (id[ATA_ID_CONFIG] == 0x848A) /* Traditional CF */ return 1; - /* Could be CF hiding as standard ATA */ - if (ata_id_major_version(id) >= 3 && - id[ATA_ID_COMMAND_SET_1] != 0xFFFF && - (id[ATA_ID_COMMAND_SET_1] & (1 << 2))) + /* + * CF specs don't require specific value in the word 0 anymore and yet + * they forbid to report the ATA version in the word 80 and require the + * CFA feature set support to be indicated in the word 83 in this case. + * Unfortunately, some cards only follow either of this requirements, + * and while those that don't indicate CFA feature support need some + * sort of quirk list, it seems impractical for the ones that do... + */ + if ((id[ATA_ID_COMMAND_SET_2] & 0xC004) == 0x4004) return 1; return 0; } --- linux-2.6.28.orig/include/linux/mmzone.h +++ linux-2.6.28/include/linux/mmzone.h @@ -1067,7 +1067,7 @@ #endif /* CONFIG_SPARSEMEM */ #ifdef CONFIG_NODES_SPAN_OTHER_NODES -#define early_pfn_in_nid(pfn, nid) (early_pfn_to_nid(pfn) == (nid)) +bool early_pfn_in_nid(unsigned long pfn, int nid); #else #define early_pfn_in_nid(pfn, nid) (1) #endif --- linux-2.6.28.orig/include/linux/sched.h +++ linux-2.6.28/include/linux/sched.h @@ -631,7 +631,6 @@ atomic_t inotify_devs; /* How many inotify devs does this user have opened? */ #endif #ifdef CONFIG_EPOLL - atomic_t epoll_devs; /* The number of epoll descriptors currently open */ atomic_t epoll_watches; /* The number of file descriptors currently watched */ #endif #ifdef CONFIG_POSIX_MQUEUE --- linux-2.6.28.orig/include/linux/capability.h +++ linux-2.6.28/include/linux/capability.h @@ -382,8 +382,10 @@ # define CAP_FULL_SET ((kernel_cap_t){{ ~0, ~0 }}) # define CAP_INIT_EFF_SET ((kernel_cap_t){{ ~CAP_TO_MASK(CAP_SETPCAP), ~0 }}) # define CAP_FS_SET ((kernel_cap_t){{ CAP_FS_MASK_B0, CAP_FS_MASK_B1 } }) -# define CAP_NFSD_SET ((kernel_cap_t){{ CAP_FS_MASK_B0|CAP_TO_MASK(CAP_SYS_RESOURCE), \ - CAP_FS_MASK_B1 } }) +# define CAP_NFSD_SET ((kernel_cap_t){{ CAP_FS_MASK_B0 \ + | CAP_TO_MASK(CAP_SYS_RESOURCE) \ + | CAP_TO_MASK(CAP_MKNOD), \ + CAP_FS_MASK_B1 } }) #endif /* _KERNEL_CAPABILITY_U32S != 2 */ --- linux-2.6.28.orig/include/linux/mxcfb.h +++ linux-2.6.28/include/linux/mxcfb.h @@ -0,0 +1,75 @@ +/* + * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU Lesser General + * Public License. You may obtain a copy of the GNU Lesser General + * Public License Version 2.1 or later at the following locations: + * + * http://www.opensource.org/licenses/lgpl-license.html + * http://www.gnu.org/copyleft/lgpl.html + */ + +/* + * @file arch-mxc/ mxcfb.h + * + * @brief Global header file for the MXC Frame buffer + * + * @ingroup Framebuffer + */ +#ifndef __ASM_ARCH_MXCFB_H__ +#define __ASM_ARCH_MXCFB_H__ + +#include + +#define FB_SYNC_OE_LOW_ACT 0x80000000 +#define FB_SYNC_CLK_LAT_FALL 0x40000000 +#define FB_SYNC_DATA_INVERT 0x20000000 +#define FB_SYNC_CLK_IDLE_EN 0x10000000 +#define FB_SYNC_SHARP_MODE 0x08000000 +#define FB_SYNC_SWAP_RGB 0x04000000 + +struct mxcfb_gbl_alpha { + int enable; + int alpha; +}; + +struct mxcfb_color_key { + int enable; + __u32 color_key; +}; + +struct mxcfb_pos { + __u16 x; + __u16 y; +}; + +#define MXCFB_WAIT_FOR_VSYNC _IOW('F', 0x20, u_int32_t) +#define MXCFB_SET_GBL_ALPHA _IOW('F', 0x21, struct mxcfb_gbl_alpha) +#define MXCFB_SET_CLR_KEY _IOW('F', 0x22, struct mxcfb_color_key) +#define MXCFB_SET_OVERLAY_POS _IOW('F', 0x24, struct mxcfb_pos) + +#ifdef __KERNEL__ + +extern struct fb_videomode mxcfb_modedb[]; +extern int mxcfb_modedb_sz; + +enum { + MXCFB_REFRESH_OFF, + MXCFB_REFRESH_AUTO, + MXCFB_REFRESH_PARTIAL, +}; + +struct mxcfb_rect { + u32 top; + u32 left; + u32 width; + u32 height; +}; + +int mxcfb_set_refresh_mode(struct fb_info *fbi, int mode, + struct mxcfb_rect *update_region); + +#endif /* __KERNEL__ */ +#endif --- linux-2.6.28.orig/include/linux/seq_file.h +++ linux-2.6.28/include/linux/seq_file.h @@ -19,6 +19,7 @@ size_t from; size_t count; loff_t index; + loff_t read_pos; u64 version; struct mutex lock; const struct seq_operations *op; --- linux-2.6.28.orig/include/linux/aufs_type.h +++ linux-2.6.28/include/linux/aufs_type.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* $Id: aufs_type.h,v 1.124 2008/09/22 03:52:19 sfjro Exp $ */ + +#include + +#ifndef __AUFS_TYPE_H__ +#define __AUFS_TYPE_H__ + +#define AUFS_VERSION "20080922" + +/* move this to linux-2.6.19/include/magic.h */ +#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') + +/* ---------------------------------------------------------------------- */ + +#ifdef CONFIG_AUFS_BRANCH_MAX_127 +/* some environments treat 'char' as 'unsigned char' by default */ +typedef signed char aufs_bindex_t; +#define AUFS_BRANCH_MAX 127 +#else +typedef short aufs_bindex_t; +#ifdef CONFIG_AUFS_BRANCH_MAX_511 +#define AUFS_BRANCH_MAX 511 +#elif defined(CONFIG_AUFS_BRANCH_MAX_1023) +#define AUFS_BRANCH_MAX 1023 +#elif defined(CONFIG_AUFS_BRANCH_MAX_32767) +#define AUFS_BRANCH_MAX 32767 +#else +#error unknown CONFIG_AUFS_BRANCH_MAX value +#endif +#endif + +#define AUFS_NAME "aufs" +#define AUFS_FSTYPE AUFS_NAME + +#define AUFS_ROOT_INO 2 +#define AUFS_FIRST_INO 11 + +#define AUFS_WH_PFX ".wh." +#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1) +#define AUFS_XINO_FNAME "." AUFS_NAME ".xino" +#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME +#define AUFS_XINO_TRUNC_INIT 64 /* blocks */ +#define AUFS_XINO_TRUNC_STEP 4 /* blocks */ +#define AUFS_DIRWH_DEF 3 +#define AUFS_RDCACHE_DEF 10 /* seconds */ +#define AUFS_WKQ_NAME AUFS_NAME "d" +#define AUFS_NWKQ_DEF 4 +#define AUFS_MFS_SECOND_DEF 30 /* seconds */ +#define AUFS_PLINK_WARN 100 /* number of plinks */ + +#ifdef CONFIG_AUFS_COMPAT +#define AUFS_DIROPQ_NAME "__dir_opaque" +#else +#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */ +#endif +#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME + +/* will be whiteouted doubly */ +#define AUFS_WH_BASENAME AUFS_WH_PFX AUFS_NAME +#define AUFS_WH_PLINKDIR AUFS_WH_PFX "plnk" +#define AUFS_WH_TMPDIR AUFS_WH_PFX ".tmp" + +/* ---------------------------------------------------------------------- */ + +/* ioctl */ +#if 0 /* reserved for future use */ +enum { + AuCtlErr, + AuCtlErr_Last +}; +enum { + AuCtl_REFRESH, AuCtl_REFRESHV, + AuCtl_FLUSH_PLINK, + AuCtl_CPUP, + AuCtl_CPDOWN, AuCtl_MVDOWN, + AuCtl_DIROPQ +}; + +struct aufs_ctl_cp { + int bsrc, bdst; + int err; +}; + +#define AuCtlType 'A' +#define AUFS_CTL_REFRESH _IO(AuCtlType, AuCtl_REFRESH) +#define AUFS_CTL_REFRESHV _IO(AuCtlType, AuCtl_REFRESHV) +#define AUFS_CTL_FLUSH_PLINK _IOR(AuCtlType, AuCtl_FLUSH_PLINK) +#define AUFS_CTL_CPUP _IOWR(AuCtlType, AuCtl_CPUP, struct aufs_ctl_cp) +#define AUFS_CTL_CPDOWN \ + _IOWR(AuCtlType, AuCtl_CPDOWN, struct aufs_ctl_cp) +#define AUFS_CTL_MVDOWN \ + _IOWR(AuCtlType, AuCtl_MVDOWN, struct aufs_ctl_cp) +#define AUFS_CTL_DIROPQ _IO(AuCtlType, AuCtl_DIROPQ) +#endif + +#endif /* __AUFS_TYPE_H__ */ --- linux-2.6.28.orig/include/linux/timerfd.h +++ linux-2.6.28/include/linux/timerfd.h @@ -11,13 +11,21 @@ /* For O_CLOEXEC and O_NONBLOCK */ #include -/* Flags for timerfd_settime. */ +/* + * CAREFUL: Check include/asm-generic/fcntl.h when defining + * new flags, since they might collide with O_* ones. We want + * to re-use O_* flags that couldn't possibly have a meaning + * from eventfd, in order to leave a free define-space for + * shared O_* flags. + */ #define TFD_TIMER_ABSTIME (1 << 0) - -/* Flags for timerfd_create. */ #define TFD_CLOEXEC O_CLOEXEC #define TFD_NONBLOCK O_NONBLOCK +#define TFD_SHARED_FCNTL_FLAGS (TFD_CLOEXEC | TFD_NONBLOCK) +/* Flags for timerfd_create. */ +#define TFD_CREATE_FLAGS TFD_SHARED_FCNTL_FLAGS +/* Flags for timerfd_settime. */ +#define TFD_SETTIME_FLAGS TFD_TIMER_ABSTIME #endif /* _LINUX_TIMERFD_H */ - --- linux-2.6.28.orig/include/linux/libata.h +++ linux-2.6.28/include/linux/libata.h @@ -271,7 +271,7 @@ * advised to wait only for the following duration before * doing SRST. */ - ATA_TMOUT_PMP_SRST_WAIT = 1000, + ATA_TMOUT_PMP_SRST_WAIT = 5000, /* ATA bus states */ BUS_UNKNOWN = 0, --- linux-2.6.28.orig/include/linux/dcache.h +++ linux-2.6.28/include/linux/dcache.h @@ -300,9 +300,12 @@ /* * helper function for dentry_operations.d_dname() members */ +#define D_PATH_FAIL_DELETED 1 +#define D_PATH_DISCONNECT 2 extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...); -extern char *__d_path(const struct path *path, struct path *root, char *, int); +extern char *__d_path(const struct path *path, struct path *root, char *, int, + int); extern char *d_path(const struct path *, char *, int); extern char *dentry_path(struct dentry *, char *, int); --- linux-2.6.28.orig/include/linux/serial_core.h +++ linux-2.6.28/include/linux/serial_core.h @@ -158,6 +158,9 @@ /* SH-SCI */ #define PORT_SCIFA 83 +/* Freescale Semiconductor MXC fmaily */ +#define PORT_MXC 84 + #ifdef __KERNEL__ #include @@ -288,6 +291,7 @@ #define UPF_HARDPPS_CD ((__force upf_t) (1 << 11)) #define UPF_LOW_LATENCY ((__force upf_t) (1 << 13)) #define UPF_BUGGY_UART ((__force upf_t) (1 << 14)) +#define UPF_NO_TXEN_TEST ((__force upf_t) (1 << 15)) #define UPF_MAGIC_MULTIPLIER ((__force upf_t) (1 << 16)) #define UPF_CONS_FLOW ((__force upf_t) (1 << 23)) #define UPF_SHARE_IRQ ((__force upf_t) (1 << 24)) --- linux-2.6.28.orig/include/linux/swap.h +++ linux-2.6.28/include/linux/swap.h @@ -150,6 +150,7 @@ unsigned int max; unsigned int inuse_pages; int next; /* next entry on swap list */ + void (*notify_swap_entry_free_fn) (unsigned long); }; struct swap_list_t { @@ -309,6 +310,7 @@ extern int can_share_swap_page(struct page *); extern int remove_exclusive_swap_page(struct page *); extern int remove_exclusive_swap_page_ref(struct page *); +extern void set_notify_swap_entry_free(unsigned, void (*) (unsigned long)); struct backing_dev_info; /* linux/mm/thrash.c */ --- linux-2.6.28.orig/include/linux/syscalls.h +++ linux-2.6.28/include/linux/syscalls.h @@ -54,6 +54,7 @@ struct compat_timeval; struct robust_list_head; struct getcpu_cache; +struct old_linux_dirent; #include #include @@ -65,6 +66,74 @@ #include #include +#define __SC_DECL1(t1, a1) t1 a1 +#define __SC_DECL2(t2, a2, ...) t2 a2, __SC_DECL1(__VA_ARGS__) +#define __SC_DECL3(t3, a3, ...) t3 a3, __SC_DECL2(__VA_ARGS__) +#define __SC_DECL4(t4, a4, ...) t4 a4, __SC_DECL3(__VA_ARGS__) +#define __SC_DECL5(t5, a5, ...) t5 a5, __SC_DECL4(__VA_ARGS__) +#define __SC_DECL6(t6, a6, ...) t6 a6, __SC_DECL5(__VA_ARGS__) + +#define __SC_LONG1(t1, a1) long a1 +#define __SC_LONG2(t2, a2, ...) long a2, __SC_LONG1(__VA_ARGS__) +#define __SC_LONG3(t3, a3, ...) long a3, __SC_LONG2(__VA_ARGS__) +#define __SC_LONG4(t4, a4, ...) long a4, __SC_LONG3(__VA_ARGS__) +#define __SC_LONG5(t5, a5, ...) long a5, __SC_LONG4(__VA_ARGS__) +#define __SC_LONG6(t6, a6, ...) long a6, __SC_LONG5(__VA_ARGS__) + +#define __SC_CAST1(t1, a1) (t1) a1 +#define __SC_CAST2(t2, a2, ...) (t2) a2, __SC_CAST1(__VA_ARGS__) +#define __SC_CAST3(t3, a3, ...) (t3) a3, __SC_CAST2(__VA_ARGS__) +#define __SC_CAST4(t4, a4, ...) (t4) a4, __SC_CAST3(__VA_ARGS__) +#define __SC_CAST5(t5, a5, ...) (t5) a5, __SC_CAST4(__VA_ARGS__) +#define __SC_CAST6(t6, a6, ...) (t6) a6, __SC_CAST5(__VA_ARGS__) + +#define __SC_TEST(type) BUILD_BUG_ON(sizeof(type) > sizeof(long)) +#define __SC_TEST1(t1, a1) __SC_TEST(t1) +#define __SC_TEST2(t2, a2, ...) __SC_TEST(t2); __SC_TEST1(__VA_ARGS__) +#define __SC_TEST3(t3, a3, ...) __SC_TEST(t3); __SC_TEST2(__VA_ARGS__) +#define __SC_TEST4(t4, a4, ...) __SC_TEST(t4); __SC_TEST3(__VA_ARGS__) +#define __SC_TEST5(t5, a5, ...) __SC_TEST(t5); __SC_TEST4(__VA_ARGS__) +#define __SC_TEST6(t6, a6, ...) __SC_TEST(t6); __SC_TEST5(__VA_ARGS__) + +#define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void) +#define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__) +#define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__) +#define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__) +#define SYSCALL_DEFINE4(name, ...) SYSCALL_DEFINEx(4, _##name, __VA_ARGS__) +#define SYSCALL_DEFINE5(name, ...) SYSCALL_DEFINEx(5, _##name, __VA_ARGS__) +#define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__) + +#ifdef CONFIG_PPC64 +#define SYSCALL_ALIAS(alias, name) \ + asm ("\t.globl " #alias "\n\t.set " #alias ", " #name "\n" \ + "\t.globl ." #alias "\n\t.set ." #alias ", ." #name) +#else +#define SYSCALL_ALIAS(alias, name) \ + asm ("\t.globl " #alias "\n\t.set " #alias ", " #name) +#endif + +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS + +#define SYSCALL_DEFINE(name) static inline long SYSC_##name +#define SYSCALL_DEFINEx(x, name, ...) \ + asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__)); \ + static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__)); \ + asmlinkage long SyS##name(__SC_LONG##x(__VA_ARGS__)) \ + { \ + __SC_TEST##x(__VA_ARGS__); \ + return (long) SYSC##name(__SC_CAST##x(__VA_ARGS__)); \ + } \ + SYSCALL_ALIAS(sys##name, SyS##name); \ + static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__)) + +#else /* CONFIG_HAVE_SYSCALL_WRAPPERS */ + +#define SYSCALL_DEFINE(name) asmlinkage long sys_##name +#define SYSCALL_DEFINEx(x, name, ...) \ + asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__)) + +#endif /* CONFIG_HAVE_SYSCALL_WRAPPERS */ + asmlinkage long sys_time(time_t __user *tloc); asmlinkage long sys_stime(time_t __user *tptr); asmlinkage long sys_gettimeofday(struct timeval __user *tv, @@ -77,7 +146,7 @@ asmlinkage long sys_gettid(void); asmlinkage long sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp); -asmlinkage unsigned long sys_alarm(unsigned int seconds); +asmlinkage long sys_alarm(unsigned int seconds); asmlinkage long sys_getpid(void); asmlinkage long sys_getppid(void); asmlinkage long sys_getuid(void); @@ -166,7 +235,7 @@ unsigned long flags); asmlinkage long sys_exit(int error_code); -asmlinkage void sys_exit_group(int error_code); +asmlinkage long sys_exit_group(int error_code); asmlinkage long sys_wait4(pid_t pid, int __user *stat_addr, int options, struct rusage __user *ru); asmlinkage long sys_waitid(int which, pid_t pid, @@ -196,7 +265,7 @@ asmlinkage long sys_rt_sigqueueinfo(int pid, int sig, siginfo_t __user *uinfo); asmlinkage long sys_sgetmask(void); asmlinkage long sys_ssetmask(int newmask); -asmlinkage unsigned long sys_signal(int sig, __sighandler_t handler); +asmlinkage long sys_signal(int sig, __sighandler_t handler); asmlinkage long sys_pause(void); asmlinkage long sys_sync(void); @@ -246,29 +315,29 @@ const void __user *value, size_t size, int flags); asmlinkage long sys_fsetxattr(int fd, const char __user *name, const void __user *value, size_t size, int flags); -asmlinkage ssize_t sys_getxattr(const char __user *path, const char __user *name, - void __user *value, size_t size); -asmlinkage ssize_t sys_lgetxattr(const char __user *path, const char __user *name, - void __user *value, size_t size); -asmlinkage ssize_t sys_fgetxattr(int fd, const char __user *name, - void __user *value, size_t size); -asmlinkage ssize_t sys_listxattr(const char __user *path, char __user *list, - size_t size); -asmlinkage ssize_t sys_llistxattr(const char __user *path, char __user *list, - size_t size); -asmlinkage ssize_t sys_flistxattr(int fd, char __user *list, size_t size); +asmlinkage long sys_getxattr(const char __user *path, const char __user *name, + void __user *value, size_t size); +asmlinkage long sys_lgetxattr(const char __user *path, const char __user *name, + void __user *value, size_t size); +asmlinkage long sys_fgetxattr(int fd, const char __user *name, + void __user *value, size_t size); +asmlinkage long sys_listxattr(const char __user *path, char __user *list, + size_t size); +asmlinkage long sys_llistxattr(const char __user *path, char __user *list, + size_t size); +asmlinkage long sys_flistxattr(int fd, char __user *list, size_t size); asmlinkage long sys_removexattr(const char __user *path, const char __user *name); asmlinkage long sys_lremovexattr(const char __user *path, const char __user *name); asmlinkage long sys_fremovexattr(int fd, const char __user *name); -asmlinkage unsigned long sys_brk(unsigned long brk); +asmlinkage long sys_brk(unsigned long brk); asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot); -asmlinkage unsigned long sys_mremap(unsigned long addr, - unsigned long old_len, unsigned long new_len, - unsigned long flags, unsigned long new_addr); +asmlinkage long sys_mremap(unsigned long addr, + unsigned long old_len, unsigned long new_len, + unsigned long flags, unsigned long new_addr); asmlinkage long sys_remap_file_pages(unsigned long start, unsigned long size, unsigned long prot, unsigned long pgoff, unsigned long flags); @@ -321,10 +390,10 @@ struct iocb __user * __user *); asmlinkage long sys_io_cancel(aio_context_t ctx_id, struct iocb __user *iocb, struct io_event __user *result); -asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, - off_t __user *offset, size_t count); -asmlinkage ssize_t sys_sendfile64(int out_fd, int in_fd, - loff_t __user *offset, size_t count); +asmlinkage long sys_sendfile(int out_fd, int in_fd, + off_t __user *offset, size_t count); +asmlinkage long sys_sendfile64(int out_fd, int in_fd, + loff_t __user *offset, size_t count); asmlinkage long sys_readlink(const char __user *path, char __user *buf, int bufsiz); asmlinkage long sys_creat(const char __user *pathname, int mode); @@ -368,26 +437,25 @@ struct utimbuf __user *times); asmlinkage long sys_utimes(char __user *filename, struct timeval __user *utimes); -asmlinkage off_t sys_lseek(unsigned int fd, off_t offset, - unsigned int origin); +asmlinkage long sys_lseek(unsigned int fd, off_t offset, + unsigned int origin); asmlinkage long sys_llseek(unsigned int fd, unsigned long offset_high, unsigned long offset_low, loff_t __user *result, unsigned int origin); -asmlinkage ssize_t sys_read(unsigned int fd, char __user *buf, - size_t count); -asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count); -asmlinkage ssize_t sys_readv(unsigned long fd, - const struct iovec __user *vec, - unsigned long vlen); -asmlinkage ssize_t sys_write(unsigned int fd, const char __user *buf, - size_t count); -asmlinkage ssize_t sys_writev(unsigned long fd, - const struct iovec __user *vec, - unsigned long vlen); -asmlinkage ssize_t sys_pread64(unsigned int fd, char __user *buf, - size_t count, loff_t pos); -asmlinkage ssize_t sys_pwrite64(unsigned int fd, const char __user *buf, - size_t count, loff_t pos); +asmlinkage long sys_read(unsigned int fd, char __user *buf, size_t count); +asmlinkage long sys_readahead(int fd, loff_t offset, size_t count); +asmlinkage long sys_readv(unsigned long fd, + const struct iovec __user *vec, + unsigned long vlen); +asmlinkage long sys_write(unsigned int fd, const char __user *buf, + size_t count); +asmlinkage long sys_writev(unsigned long fd, + const struct iovec __user *vec, + unsigned long vlen); +asmlinkage long sys_pread64(unsigned int fd, char __user *buf, + size_t count, loff_t pos); +asmlinkage long sys_pwrite64(unsigned int fd, const char __user *buf, + size_t count, loff_t pos); asmlinkage long sys_getcwd(char __user *buf, unsigned long size); asmlinkage long sys_mkdir(const char __user *pathname, int mode); asmlinkage long sys_chdir(const char __user *filename); @@ -476,7 +544,7 @@ asmlinkage long sys_mq_open(const char __user *name, int oflag, mode_t mode, struct mq_attr __user *attr); asmlinkage long sys_mq_unlink(const char __user *name); asmlinkage long sys_mq_timedsend(mqd_t mqdes, const char __user *msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec __user *abs_timeout); -asmlinkage ssize_t sys_mq_timedreceive(mqd_t mqdes, char __user *msg_ptr, size_t msg_len, unsigned int __user *msg_prio, const struct timespec __user *abs_timeout); +asmlinkage long sys_mq_timedreceive(mqd_t mqdes, char __user *msg_ptr, size_t msg_len, unsigned int __user *msg_prio, const struct timespec __user *abs_timeout); asmlinkage long sys_mq_notify(mqd_t mqdes, const struct sigevent __user *notification); asmlinkage long sys_mq_getsetattr(mqd_t mqdes, const struct mq_attr __user *mqstat, struct mq_attr __user *omqstat); @@ -530,11 +598,6 @@ const int __user *nodes, int __user *status, int flags); -asmlinkage long compat_sys_move_pages(pid_t pid, unsigned long nr_page, - __u32 __user *pages, - const int __user *nodes, - int __user *status, - int flags); asmlinkage long sys_mbind(unsigned long start, unsigned long len, unsigned long mode, unsigned long __user *nmask, @@ -549,7 +612,7 @@ asmlinkage long sys_inotify_init1(int flags); asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask); -asmlinkage long sys_inotify_rm_watch(int fd, u32 wd); +asmlinkage long sys_inotify_rm_watch(int fd, __s32 wd); asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus); @@ -583,13 +646,6 @@ int bufsiz); asmlinkage long sys_utimensat(int dfd, char __user *filename, struct timespec __user *utimes, int flags); -asmlinkage long compat_sys_futimesat(unsigned int dfd, char __user *filename, - struct compat_timeval __user *t); -asmlinkage long compat_sys_newfstatat(unsigned int dfd, char __user * filename, - struct compat_stat __user *statbuf, - int flag); -asmlinkage long compat_sys_openat(unsigned int dfd, const char __user *filename, - int flags, int mode); asmlinkage long sys_unshare(unsigned long unshare_flags); asmlinkage long sys_splice(int fd_in, loff_t __user *off_in, @@ -621,6 +677,15 @@ asmlinkage long sys_eventfd(unsigned int count); asmlinkage long sys_eventfd2(unsigned int count, int flags); asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len); +asmlinkage long sys_old_readdir(unsigned int, struct old_linux_dirent __user *, unsigned int); +asmlinkage long sys_pselect6(int, fd_set __user *, fd_set __user *, + fd_set __user *, struct timespec __user *, + void __user *); +asmlinkage long sys_ppoll(struct pollfd __user *, unsigned int, + struct timespec __user *, const sigset_t __user *, + size_t); +asmlinkage long sys_pipe2(int __user *, int); +asmlinkage long sys_pipe(int __user *); int kernel_execve(const char *filename, char *const argv[], char *const envp[]); --- linux-2.6.28.orig/include/linux/namei.h +++ linux-2.6.28/include/linux/namei.h @@ -84,6 +84,8 @@ extern struct dentry *lock_rename(struct dentry *, struct dentry *); extern void unlock_rename(struct dentry *, struct dentry *); +struct dentry * __lookup_hash(struct qstr *name, struct dentry * base, struct nameidata *nd); + static inline void nd_set_link(struct nameidata *nd, char *path) { nd->saved_names[nd->depth] = path; --- linux-2.6.28.orig/include/linux/pmic_status.h +++ linux-2.6.28/include/linux/pmic_status.h @@ -0,0 +1,82 @@ +/* + * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU Lesser General + * Public License. You may obtain a copy of the GNU Lesser General + * Public License Version 2.1 or later at the following locations: + * + * http://www.opensource.org/licenses/lgpl-license.html + * http://www.gnu.org/copyleft/lgpl.html + */ +#ifndef __ASM_ARCH_MXC_PMIC_STATUS_H__ +#define __ASM_ARCH_MXC_PMIC_STATUS_H__ +#include +#ifdef __KERNEL__ +#include /* copy_{from,to}_user() */ +#endif +/*! + * @file arch-mxc/pmic_status.h + * @brief PMIC APIs return code definition. + * + * @ingroup PMIC_CORE + */ + +/*! + * @enum PMIC_STATUS + * @brief Define return values for all PMIC APIs. + * + * These return values are used by all of the PMIC APIs. + * + * @ingroup PMIC + */ +typedef enum { + PMIC_SUCCESS = 0, /*!< The requested operation was successfully + completed. */ + PMIC_ERROR = -1, /*!< The requested operation could not be completed + due to an error. */ + PMIC_PARAMETER_ERROR = -2, /*!< The requested operation failed because + one or more of the parameters was + invalid. */ + PMIC_NOT_SUPPORTED = -3, /*!< The requested operation could not be + completed because the PMIC hardware + does not support it. */ + PMIC_SYSTEM_ERROR_EINTR = -EINTR, + + PMIC_MALLOC_ERROR = -5, /*!< Error in malloc function */ + PMIC_UNSUBSCRIBE_ERROR = -6, /*!< Error in un-subscribe event */ + PMIC_EVENT_NOT_SUBSCRIBED = -7, /*!< Event occur and not subscribed */ + PMIC_EVENT_CALL_BACK = -8, /*!< Error - bad call back */ + PMIC_CLIENT_NBOVERFLOW = -9, /*!< The requested operation could not be + completed because there are too many + PMIC client requests */ +} PMIC_STATUS; + +/* + * Bitfield macros that use rely on bitfield width/shift information. + */ +#define BITFMASK(field) (((1U << (field ## _WID)) - 1) << (field ## _LSH)) +#define BITFVAL(field, val) ((val) << (field ## _LSH)) +#define BITFEXT(var, bit) ((var & BITFMASK(bit)) >> (bit ## _LSH)) + +/* + * Macros implementing error handling + */ +#define CHECK_ERROR(a) \ +do { \ + int ret = (a); \ + if (ret != PMIC_SUCCESS) \ + return ret; \ +} while (0) + +#define CHECK_ERROR_KFREE(func, freeptrs) \ +do { \ + int ret = (func); \ + if (ret != PMIC_SUCCESS) { \ + freeptrs; \ + return ret; \ + } \ +} while (0); + +#endif /* __ASM_ARCH_MXC_PMIC_STATUS_H__ */ --- linux-2.6.28.orig/include/linux/Kbuild +++ linux-2.6.28/include/linux/Kbuild @@ -41,6 +41,7 @@ header-y += bfs_fs.h header-y += blkpg.h header-y += bpqether.h +header-y += bsg.h header-y += can.h header-y += cdk.h header-y += chio.h @@ -91,7 +92,6 @@ header-y += if_slip.h header-y += if_strip.h header-y += if_tun.h -header-y += if_tunnel.h header-y += in_route.h header-y += ioctl.h header-y += ip6_tunnel.h @@ -240,6 +240,7 @@ unifdef-y += if_pppol2tp.h unifdef-y += if_pppox.h unifdef-y += if_tr.h +unifdef-y += if_tunnel.h unifdef-y += if_vlan.h unifdef-y += igmp.h unifdef-y += inet_diag.h --- linux-2.6.28.orig/include/linux/ipu.h +++ linux-2.6.28/include/linux/ipu.h @@ -0,0 +1,1164 @@ +/* + * Copyright 2005-2009 Freescale Semiconductor, Inc. + */ + +/* + * The code contained herein is licensed under the GNU Lesser General + * Public License. You may obtain a copy of the GNU Lesser General + * Public License Version 2.1 or later at the following locations: + * + * http://www.opensource.org/licenses/lgpl-license.html + * http://www.gnu.org/copyleft/lgpl.html + */ + +/*! + * @defgroup IPU MXC Image Processing Unit (IPU) Driver + */ +/*! + * @file arch-mxc/ipu.h + * + * @brief This file contains the IPU driver API declarations. + * + * @ingroup IPU + */ + +#ifndef __ASM_ARCH_IPU_H__ +#define __ASM_ARCH_IPU_H__ + +#include +#ifdef __KERNEL__ +#include +#else +#define bool char +#define irqreturn_t int +#define dma_addr_t int +#define u32 unsigned int +#define __u32 u32 +#endif + +/*! + * Enumeration of IPU rotation modes + */ +typedef enum { + /* Note the enum values correspond to BAM value */ + IPU_ROTATE_NONE = 0, + IPU_ROTATE_VERT_FLIP = 1, + IPU_ROTATE_HORIZ_FLIP = 2, + IPU_ROTATE_180 = 3, + IPU_ROTATE_90_RIGHT = 4, + IPU_ROTATE_90_RIGHT_VFLIP = 5, + IPU_ROTATE_90_RIGHT_HFLIP = 6, + IPU_ROTATE_90_LEFT = 7, +} ipu_rotate_mode_t; + +/*! + * Enumeration of Post Filter modes + */ +typedef enum { + PF_DISABLE_ALL = 0, + PF_MPEG4_DEBLOCK = 1, + PF_MPEG4_DERING = 2, + PF_MPEG4_DEBLOCK_DERING = 3, + PF_H264_DEBLOCK = 4, +} pf_operation_t; + +/*! + * Enumeration of Synchronous (Memory-less) panel types + */ +typedef enum { + IPU_PANEL_SHARP_TFT, + IPU_PANEL_TFT, +} ipu_panel_t; + +/* IPU Pixel format definitions */ +/* Four-character-code (FOURCC) */ +#define fourcc(a, b, c, d)\ + (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24)) + +/*! + * @name IPU Pixel Formats + * + * Pixel formats are defined with ASCII FOURCC code. The pixel format codes are + * the same used by V4L2 API. + */ + +/*! @{ */ +/*! @name Generic or Raw Data Formats */ +/*! @{ */ +#define IPU_PIX_FMT_GENERIC fourcc('I', 'P', 'U', '0') /*!< IPU Generic Data */ +#define IPU_PIX_FMT_GENERIC_32 fourcc('I', 'P', 'U', '1') /*!< IPU Generic Data */ +#define IPU_PIX_FMT_LVDS666 fourcc('L', 'V', 'D', '6') /*!< IPU Generic Data */ +#define IPU_PIX_FMT_LVDS888 fourcc('L', 'V', 'D', '8') /*!< IPU Generic Data */ +/*! @} */ +/*! @name RGB Formats */ +/*! @{ */ +#define IPU_PIX_FMT_RGB332 fourcc('R', 'G', 'B', '1') /*!< 8 RGB-3-3-2 */ +#define IPU_PIX_FMT_RGB555 fourcc('R', 'G', 'B', 'O') /*!< 16 RGB-5-5-5 */ +#define IPU_PIX_FMT_RGB565 fourcc('R', 'G', 'B', 'P') /*!< 1 6 RGB-5-6-5 */ +#define IPU_PIX_FMT_RGB666 fourcc('R', 'G', 'B', '6') /*!< 18 RGB-6-6-6 */ +#define IPU_PIX_FMT_BGR666 fourcc('B', 'G', 'R', '6') /*!< 18 BGR-6-6-6 */ +#define IPU_PIX_FMT_BGR24 fourcc('B', 'G', 'R', '3') /*!< 24 BGR-8-8-8 */ +#define IPU_PIX_FMT_RGB24 fourcc('R', 'G', 'B', '3') /*!< 24 RGB-8-8-8 */ +#define IPU_PIX_FMT_BGR32 fourcc('B', 'G', 'R', '4') /*!< 32 BGR-8-8-8-8 */ +#define IPU_PIX_FMT_BGRA32 fourcc('B', 'G', 'R', 'A') /*!< 32 BGR-8-8-8-8 */ +#define IPU_PIX_FMT_RGB32 fourcc('R', 'G', 'B', '4') /*!< 32 RGB-8-8-8-8 */ +#define IPU_PIX_FMT_RGBA32 fourcc('R', 'G', 'B', 'A') /*!< 32 RGB-8-8-8-8 */ +#define IPU_PIX_FMT_ABGR32 fourcc('A', 'B', 'G', 'R') /*!< 32 ABGR-8-8-8-8 */ +/*! @} */ +/*! @name YUV Interleaved Formats */ +/*! @{ */ +#define IPU_PIX_FMT_YUYV fourcc('Y', 'U', 'Y', 'V') /*!< 16 YUV 4:2:2 */ +#define IPU_PIX_FMT_UYVY fourcc('U', 'Y', 'V', 'Y') /*!< 16 YUV 4:2:2 */ +#define IPU_PIX_FMT_Y41P fourcc('Y', '4', '1', 'P') /*!< 12 YUV 4:1:1 */ +#define IPU_PIX_FMT_YUV444 fourcc('Y', '4', '4', '4') /*!< 24 YUV 4:4:4 */ +/* two planes -- one Y, one Cb + Cr interleaved */ +#define IPU_PIX_FMT_NV12 fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */ +/*! @} */ +/*! @name YUV Planar Formats */ +/*! @{ */ +#define IPU_PIX_FMT_GREY fourcc('G', 'R', 'E', 'Y') /*!< 8 Greyscale */ +#define IPU_PIX_FMT_YVU410P fourcc('Y', 'V', 'U', '9') /*!< 9 YVU 4:1:0 */ +#define IPU_PIX_FMT_YUV410P fourcc('Y', 'U', 'V', '9') /*!< 9 YUV 4:1:0 */ +#define IPU_PIX_FMT_YVU420P fourcc('Y', 'V', '1', '2') /*!< 12 YVU 4:2:0 */ +#define IPU_PIX_FMT_YUV420P fourcc('I', '4', '2', '0') /*!< 12 YUV 4:2:0 */ +#define IPU_PIX_FMT_YUV420P2 fourcc('Y', 'U', '1', '2') /*!< 12 YUV 4:2:0 */ +#define IPU_PIX_FMT_YVU422P fourcc('Y', 'V', '1', '6') /*!< 16 YVU 4:2:2 */ +#define IPU_PIX_FMT_YUV422P fourcc('4', '2', '2', 'P') /*!< 16 YUV 4:2:2 */ +/*! @} */ + +/* IPU Driver channels definitions. */ +/* Note these are different from IDMA channels */ +#ifdef CONFIG_MXC_IPU_V1 +#define _MAKE_CHAN(num, in, out, sec) ((num << 24) | (sec << 16) | (out << 8) | in) +#define IPU_CHAN_ID(ch) (ch >> 24) +#define IPU_CHAN_SEC_DMA(ch) ((uint32_t) (ch >> 16) & 0xFF) +#define IPU_CHAN_OUT_DMA(ch) ((uint32_t) (ch >> 8) & 0xFF) +#define IPU_CHAN_IN_DMA(ch) ((uint32_t) (ch & 0xFF)) + +#else +#define IPU_MAX_CH 32 +#define _MAKE_CHAN(num, v_in, g_in, a_in, out) \ + ((num << 24) | (v_in << 18) | (g_in << 12) | (a_in << 6) | out) +#define _MAKE_ALT_CHAN(ch) (ch | (IPU_MAX_CH << 24)) +#define IPU_CHAN_ID(ch) (ch >> 24) +#define IPU_CHAN_ALT(ch) (ch & 0x02000000) +#define IPU_CHAN_ALPHA_IN_DMA(ch) ((uint32_t) (ch >> 6) & 0x3F) +#define IPU_CHAN_GRAPH_IN_DMA(ch) ((uint32_t) (ch >> 12) & 0x3F) +#define IPU_CHAN_VIDEO_IN_DMA(ch) ((uint32_t) (ch >> 18) & 0x3F) +#define IPU_CHAN_OUT_DMA(ch) ((uint32_t) (ch & 0x3F)) +#define NO_DMA 0x3F +#define ALT 1 +#endif +/*! + * Enumeration of IPU logical channels. An IPU logical channel is defined as a + * combination of an input (memory to IPU), output (IPU to memory), and/or + * secondary input IDMA channels and in some cases an Image Converter task. + * Some channels consist of only an input or output. + */ +typedef enum { + CHAN_NONE = -1, +#ifdef CONFIG_MXC_IPU_V1 + CSI_MEM = _MAKE_CHAN(1, 0xFF, 7, 0xFF), /*!< CSI raw sensor data to memory */ + + CSI_PRP_ENC_MEM = _MAKE_CHAN(2, 0xFF, 0, 0xFF), /*!< CSI to IC Encoder PreProcessing to Memory */ + MEM_PRP_ENC_MEM = _MAKE_CHAN(3, 6, 0, 0xFF), /*!< Memory to IC Encoder PreProcessing to Memory */ + MEM_ROT_ENC_MEM = _MAKE_CHAN(4, 10, 8, 0xFF), /*!< Memory to IC Encoder Rotation to Memory */ + + CSI_PRP_VF_MEM = _MAKE_CHAN(5, 0xFF, 1, 0xFF), /*!< CSI to IC Viewfinder PreProcessing to Memory */ + CSI_PRP_VF_ADC = _MAKE_CHAN(6, 0xFF, 1, 0xFF), /*!< CSI to IC Viewfinder PreProcessing to ADC */ + MEM_PRP_VF_MEM = _MAKE_CHAN(7, 6, 1, 3), /*!< Memory to IC Viewfinder PreProcessing to Memory */ + MEM_PRP_VF_ADC = _MAKE_CHAN(8, 6, 1, 3), /*!< Memory to IC Viewfinder PreProcessing to ADC */ + MEM_ROT_VF_MEM = _MAKE_CHAN(9, 11, 9, 0xFF), /*!< Memory to IC Viewfinder Rotation to Memory */ + + MEM_PP_MEM = _MAKE_CHAN(10, 5, 2, 4), /*!< Memory to IC PostProcessing to Memory */ + MEM_ROT_PP_MEM = _MAKE_CHAN(11, 13, 12, 0xFF), /*!< Memory to IC PostProcessing Rotation to Memory */ + MEM_PP_ADC = _MAKE_CHAN(12, 5, 2, 4), /*!< Memory to IC PostProcessing to ADC */ + + MEM_SDC_BG = _MAKE_CHAN(14, 14, 0xFF, 0xFF), /*!< Memory to SDC Background plane */ + MEM_SDC_FG = _MAKE_CHAN(15, 15, 0xFF, 0xFF), /*!< Memory to SDC Foreground plane */ + MEM_SDC_MASK = _MAKE_CHAN(16, 16, 0xFF, 0xFF), /*!< Memory to SDC Mask */ + + MEM_BG_SYNC = MEM_SDC_BG, + MEM_FG_SYNC = MEM_SDC_FG, + + ADC_SYS1 = _MAKE_CHAN(17, 18, 22, 20), /*!< Memory to ADC System Channel 1 */ + ADC_SYS2 = _MAKE_CHAN(18, 19, 23, 21), /*!< Memory to ADC System Channel 2 */ + + MEM_PF_Y_MEM = _MAKE_CHAN(19, 26, 29, 24), /*!< Y and PF Memory to Post-filter to Y Memory */ + MEM_PF_U_MEM = _MAKE_CHAN(20, 27, 30, 25), /*!< U and PF Memory to Post-filter to U Memory */ + MEM_PF_V_MEM = _MAKE_CHAN(21, 28, 31, 0xFF), /*!< V Memory to Post-filter to V Memory */ + + MEM_DC_SYNC = CHAN_NONE, + DIRECT_ASYNC0 = CHAN_NONE, + DIRECT_ASYNC1 = CHAN_NONE, +#else + MEM_ROT_ENC_MEM = _MAKE_CHAN(1, 45, NO_DMA, NO_DMA, 48), + MEM_ROT_VF_MEM = _MAKE_CHAN(2, 46, NO_DMA, NO_DMA, 49), + MEM_ROT_PP_MEM = _MAKE_CHAN(3, 47, NO_DMA, NO_DMA, 50), + + MEM_PRP_ENC_MEM = _MAKE_CHAN(4, 12, 14, 17, 20), + MEM_PRP_VF_MEM = _MAKE_CHAN(5, 12, 14, 17, 21), + MEM_PP_MEM = _MAKE_CHAN(6, 11, 15, 18, 22), + + MEM_DC_SYNC = _MAKE_CHAN(7, 28, NO_DMA, NO_DMA, NO_DMA), + MEM_DC_ASYNC = _MAKE_CHAN(8, 41, NO_DMA, NO_DMA, NO_DMA), + MEM_BG_SYNC = _MAKE_CHAN(9, 23, NO_DMA, 51, NO_DMA), + MEM_FG_SYNC = _MAKE_CHAN(10, 27, NO_DMA, 31, NO_DMA), + + MEM_BG_ASYNC0 = _MAKE_CHAN(11, 24, NO_DMA, 52, NO_DMA), + MEM_FG_ASYNC0 = _MAKE_CHAN(12, 29, NO_DMA, 33, NO_DMA), + MEM_BG_ASYNC1 = _MAKE_ALT_CHAN(MEM_BG_ASYNC0), + MEM_FG_ASYNC1 = _MAKE_ALT_CHAN(MEM_FG_ASYNC0), + + DIRECT_ASYNC0 = _MAKE_CHAN(13, NO_DMA, NO_DMA, NO_DMA, NO_DMA), + DIRECT_ASYNC1 = _MAKE_CHAN(14, NO_DMA, NO_DMA, NO_DMA, NO_DMA), + + CSI_MEM0 = _MAKE_CHAN(15, NO_DMA, NO_DMA, NO_DMA, 0), + CSI_MEM1 = _MAKE_CHAN(16, NO_DMA, NO_DMA, NO_DMA, 1), + CSI_MEM2 = _MAKE_CHAN(17, NO_DMA, NO_DMA, NO_DMA, 2), + CSI_MEM3 = _MAKE_CHAN(18, NO_DMA, NO_DMA, NO_DMA, 3), + + CSI_MEM = CSI_MEM0, + + CSI_PRP_ENC_MEM = _MAKE_CHAN(19, NO_DMA, NO_DMA, NO_DMA, 20), + CSI_PRP_VF_MEM = _MAKE_CHAN(20, NO_DMA, NO_DMA, NO_DMA, 21), + + MEM_PP_ADC = CHAN_NONE, + ADC_SYS2 = CHAN_NONE, +#endif + +} ipu_channel_t; + +/*! + * Enumeration of types of buffers for a logical channel. + */ +typedef enum { + IPU_OUTPUT_BUFFER = 0, /*!< Buffer for output from IPU */ + IPU_ALPHA_IN_BUFFER = 1, /*!< Buffer for input to IPU */ + IPU_GRAPH_IN_BUFFER = 2, /*!< Buffer for input to IPU */ + IPU_VIDEO_IN_BUFFER = 3, /*!< Buffer for input to IPU */ + IPU_INPUT_BUFFER = IPU_VIDEO_IN_BUFFER, + IPU_SEC_INPUT_BUFFER = IPU_GRAPH_IN_BUFFER, +} ipu_buffer_t; + +#define IPU_PANEL_SERIAL 1 +#define IPU_PANEL_PARALLEL 2 + +/*! + * Enumeration of DI ports for ADC. + */ +typedef enum { + DISP0, + DISP1, + DISP2, + DISP3 +} display_port_t; + +/*! + * Enumeration of ADC channel operation mode. + */ +typedef enum { + Disable, + WriteTemplateNonSeq, + ReadTemplateNonSeq, + WriteTemplateUnCon, + ReadTemplateUnCon, + WriteDataWithRS, + WriteDataWoRS, + WriteCmd +} mcu_mode_t; + +/*! + * Enumeration of ADC channel addressing mode. + */ +typedef enum { + FullWoBE, + FullWithBE, + XY +} display_addressing_t; + +/*! + * Union of initialization parameters for a logical channel. + */ +typedef union { + struct { + uint32_t csi; + bool mipi_en; + uint32_t mipi_id; + } csi_mem; + struct { + uint32_t in_width; + uint32_t in_height; + uint32_t in_pixel_fmt; + uint32_t out_width; + uint32_t out_height; + uint32_t out_pixel_fmt; + uint32_t csi; + } csi_prp_enc_mem; + struct { + uint32_t in_width; + uint32_t in_height; + uint32_t in_pixel_fmt; + uint32_t out_width; + uint32_t out_height; + uint32_t out_pixel_fmt; + } mem_prp_enc_mem; + struct { + uint32_t in_width; + uint32_t in_height; + uint32_t in_pixel_fmt; + uint32_t out_width; + uint32_t out_height; + uint32_t out_pixel_fmt; + } mem_rot_enc_mem; + struct { + uint32_t in_width; + uint32_t in_height; + uint32_t in_pixel_fmt; + uint32_t out_width; + uint32_t out_height; + uint32_t out_pixel_fmt; + bool graphics_combine_en; + bool global_alpha_en; + bool key_color_en; + uint32_t csi; + } csi_prp_vf_mem; + struct { + uint32_t in_width; + uint32_t in_height; + uint32_t in_pixel_fmt; + uint32_t out_width; + uint32_t out_height; + uint32_t out_pixel_fmt; + bool graphics_combine_en; + bool global_alpha_en; + bool key_color_en; + display_port_t disp; + uint32_t out_left; + uint32_t out_top; + } csi_prp_vf_adc; + struct { + uint32_t in_width; + uint32_t in_height; + uint32_t in_pixel_fmt; + uint32_t out_width; + uint32_t out_height; + uint32_t out_pixel_fmt; + bool graphics_combine_en; + bool global_alpha_en; + bool key_color_en; + } mem_prp_vf_mem; + struct { + uint32_t temp; + } mem_prp_vf_adc; + struct { + uint32_t temp; + } mem_rot_vf_mem; + struct { + uint32_t in_width; + uint32_t in_height; + uint32_t in_pixel_fmt; + uint32_t out_width; + uint32_t out_height; + uint32_t out_pixel_fmt; + bool graphics_combine_en; + bool global_alpha_en; + bool key_color_en; + } mem_pp_mem; + struct { + uint32_t temp; + } mem_rot_mem; + struct { + uint32_t in_width; + uint32_t in_height; + uint32_t in_pixel_fmt; + uint32_t out_width; + uint32_t out_height; + uint32_t out_pixel_fmt; + bool graphics_combine_en; + bool global_alpha_en; + bool key_color_en; + display_port_t disp; + uint32_t out_left; + uint32_t out_top; + } mem_pp_adc; + struct { + pf_operation_t operation; + } mem_pf_mem; + struct { + uint32_t di; + bool interlaced; + } mem_dc_sync; + struct { + uint32_t temp; + } mem_sdc_fg; + struct { + uint32_t di; + bool interlaced; + uint32_t in_pixel_fmt; + uint32_t out_pixel_fmt; + } mem_dp_bg_sync; + struct { + uint32_t temp; + } mem_sdc_bg; + struct { + uint32_t di; + bool interlaced; + uint32_t in_pixel_fmt; + uint32_t out_pixel_fmt; + } mem_dp_fg_sync; + struct { + uint32_t di; + } direct_async; + struct { + display_port_t disp; + mcu_mode_t ch_mode; + uint32_t out_left; + uint32_t out_top; + } adc_sys1; + struct { + display_port_t disp; + mcu_mode_t ch_mode; + uint32_t out_left; + uint32_t out_top; + } adc_sys2; +} ipu_channel_params_t; + +/*! + * Enumeration of IPU interrupt sources. + */ +enum ipu_irq_line { +#ifdef CONFIG_MXC_IPU_V1 + IPU_IRQ_DC_FC_1 = -1, + + IPU_IRQ_PRP_ENC_OUT_EOF = 0, + IPU_IRQ_PRP_VF_OUT_EOF = 1, + IPU_IRQ_PP_OUT_EOF = 2, + IPU_IRQ_PRP_GRAPH_IN_EOF = 3, + IPU_IRQ_PP_GRAPH_IN_EOF = 4, + IPU_IRQ_PP_IN_EOF = 5, + IPU_IRQ_PRP_IN_EOF = 6, + IPU_IRQ_SENSOR_OUT_EOF = 7, + IPU_IRQ_PRP_ENC_ROT_OUT_EOF = 8, + IPU_IRQ_PRP_VF_ROT_OUT_EOF = 9, + IPU_IRQ_PRP_ENC_ROT_IN_EOF = 10, + IPU_IRQ_PRP_VF_ROT_IN_EOF = 11, + IPU_IRQ_PP_ROT_OUT_EOF = 12, + IPU_IRQ_PP_ROT_IN_EOF = 13, + IPU_IRQ_BG_SYNC_EOF = 14, + IPU_IRQ_SDC_BG_EOF = IPU_IRQ_BG_SYNC_EOF, + IPU_IRQ_FG_SYNC_EOF = 15, + IPU_IRQ_SDC_FG_EOF = IPU_IRQ_FG_SYNC_EOF, + IPU_IRQ_SDC_MASK_EOF = 16, + IPU_IRQ_SDC_BG_PART_EOF = 17, + IPU_IRQ_ADC_SYS1_WR_EOF = 18, + IPU_IRQ_ADC_SYS2_WR_EOF = 19, + IPU_IRQ_ADC_SYS1_CMD_EOF = 20, + IPU_IRQ_ADC_SYS2_CMD_EOF = 21, + IPU_IRQ_ADC_SYS1_RD_EOF = 22, + IPU_IRQ_ADC_SYS2_RD_EOF = 23, + IPU_IRQ_PF_QP_IN_EOF = 24, + IPU_IRQ_PF_BSP_IN_EOF = 25, + IPU_IRQ_PF_Y_IN_EOF = 26, + IPU_IRQ_PF_U_IN_EOF = 27, + IPU_IRQ_PF_V_IN_EOF = 28, + IPU_IRQ_PF_Y_OUT_EOF = 29, + IPU_IRQ_PF_U_OUT_EOF = 30, + IPU_IRQ_PF_V_OUT_EOF = 31, + + IPU_IRQ_PRP_ENC_OUT_NF = 32, + IPU_IRQ_PRP_VF_OUT_NF = 33, + IPU_IRQ_PP_OUT_NF = 34, + IPU_IRQ_PRP_GRAPH_IN_NF = 35, + IPU_IRQ_PP_GRAPH_IN_NF = 36, + IPU_IRQ_PP_IN_NF = 37, + IPU_IRQ_PRP_IN_NF = 38, + IPU_IRQ_SENSOR_OUT_NF = 39, + IPU_IRQ_PRP_ENC_ROT_OUT_NF = 40, + IPU_IRQ_PRP_VF_ROT_OUT_NF = 41, + IPU_IRQ_PRP_ENC_ROT_IN_NF = 42, + IPU_IRQ_PRP_VF_ROT_IN_NF = 43, + IPU_IRQ_PP_ROT_OUT_NF = 44, + IPU_IRQ_PP_ROT_IN_NF = 45, + IPU_IRQ_SDC_FG_NF = 46, + IPU_IRQ_SDC_BG_NF = 47, + IPU_IRQ_SDC_MASK_NF = 48, + IPU_IRQ_SDC_BG_PART_NF = 49, + IPU_IRQ_ADC_SYS1_WR_NF = 50, + IPU_IRQ_ADC_SYS2_WR_NF = 51, + IPU_IRQ_ADC_SYS1_CMD_NF = 52, + IPU_IRQ_ADC_SYS2_CMD_NF = 53, + IPU_IRQ_ADC_SYS1_RD_NF = 54, + IPU_IRQ_ADC_SYS2_RD_NF = 55, + IPU_IRQ_PF_QP_IN_NF = 56, + IPU_IRQ_PF_BSP_IN_NF = 57, + IPU_IRQ_PF_Y_IN_NF = 58, + IPU_IRQ_PF_U_IN_NF = 59, + IPU_IRQ_PF_V_IN_NF = 60, + IPU_IRQ_PF_Y_OUT_NF = 61, + IPU_IRQ_PF_U_OUT_NF = 62, + IPU_IRQ_PF_V_OUT_NF = 63, + + IPU_IRQ_BREAKRQ = 64, + IPU_IRQ_SDC_BG_OUT_EOF = 65, + IPU_IRQ_BG_SF_END = IPU_IRQ_SDC_BG_OUT_EOF, + IPU_IRQ_SDC_FG_OUT_EOF = 66, + IPU_IRQ_SDC_MASK_OUT_EOF = 67, + IPU_IRQ_ADC_SERIAL_DATA_OUT = 68, + IPU_IRQ_SENSOR_NF = 69, + IPU_IRQ_SENSOR_EOF = 70, + IPU_IRQ_SDC_DISP3_VSYNC = 80, + IPU_IRQ_ADC_DISP0_VSYNC = 81, + IPU_IRQ_ADC_DISP12_VSYNC = 82, + IPU_IRQ_ADC_PRP_EOF = 83, + IPU_IRQ_ADC_PP_EOF = 84, + IPU_IRQ_ADC_SYS1_EOF = 85, + IPU_IRQ_ADC_SYS2_EOF = 86, + + IPU_IRQ_PRP_ENC_OUT_NFB4EOF_ERR = 96, + IPU_IRQ_PRP_VF_OUT_NFB4EOF_ERR = 97, + IPU_IRQ_PP_OUT_NFB4EOF_ERR = 98, + IPU_IRQ_PRP_GRAPH_IN_NFB4EOF_ERR = 99, + IPU_IRQ_PP_GRAPH_IN_NFB4EOF_ERR = 100, + IPU_IRQ_PP_IN_NFB4EOF_ERR = 101, + IPU_IRQ_PRP_IN_NFB4EOF_ERR = 102, + IPU_IRQ_SENSOR_OUT_NFB4EOF_ERR = 103, + IPU_IRQ_PRP_ENC_ROT_OUT_NFB4EOF_ERR = 104, + IPU_IRQ_PRP_VF_ROT_OUT_NFB4EOF_ERR = 105, + IPU_IRQ_PRP_ENC_ROT_IN_NFB4EOF_ERR = 106, + IPU_IRQ_PRP_VF_ROT_IN_NFB4EOF_ERR = 107, + IPU_IRQ_PP_ROT_OUT_NFB4EOF_ERR = 108, + IPU_IRQ_PP_ROT_IN_NFB4EOF_ERR = 109, + IPU_IRQ_SDC_FG_NFB4EOF_ERR = 110, + IPU_IRQ_SDC_BG_NFB4EOF_ERR = 111, + IPU_IRQ_SDC_MASK_NFB4EOF_ERR = 112, + IPU_IRQ_SDC_BG_PART_NFB4EOF_ERR = 113, + IPU_IRQ_ADC_SYS1_WR_NFB4EOF_ERR = 114, + IPU_IRQ_ADC_SYS2_WR_NFB4EOF_ERR = 115, + IPU_IRQ_ADC_SYS1_CMD_NFB4EOF_ERR = 116, + IPU_IRQ_ADC_SYS2_CMD_NFB4EOF_ERR = 117, + IPU_IRQ_ADC_SYS1_RD_NFB4EOF_ERR = 118, + IPU_IRQ_ADC_SYS2_RD_NFB4EOF_ERR = 119, + IPU_IRQ_PF_QP_IN_NFB4EOF_ERR = 120, + IPU_IRQ_PF_BSP_IN_NFB4EOF_ERR = 121, + IPU_IRQ_PF_Y_IN_NFB4EOF_ERR = 122, + IPU_IRQ_PF_U_IN_NFB4EOF_ERR = 123, + IPU_IRQ_PF_V_IN_NFB4EOF_ERR = 124, + IPU_IRQ_PF_Y_OUT_NFB4EOF_ERR = 125, + IPU_IRQ_PF_U_OUT_NFB4EOF_ERR = 126, + IPU_IRQ_PF_V_OUT_NFB4EOF_ERR = 127, + + IPU_IRQ_BAYER_BUFOVF_ERR = 128, + IPU_IRQ_ENC_BUFOVF_ERR = 129, + IPU_IRQ_VF_BUFOVF_ERR = 130, + IPU_IRQ_ADC_PP_TEAR_ERR = 131, + IPU_IRQ_ADC_SYS1_TEAR_ERR = 132, + IPU_IRQ_ADC_SYS2_TEAR_ERR = 133, + IPU_IRQ_SDC_BGD_ERR = 134, + IPU_IRQ_SDC_FGD_ERR = 135, + IPU_IRQ_SDC_MASKD_ERR = 136, + IPU_IRQ_BAYER_FRM_LOST_ERR = 137, + IPU_IRQ_ENC_FRM_LOST_ERR = 138, + IPU_IRQ_VF_FRM_LOST_ERR = 139, + IPU_IRQ_ADC_LOCK_ERR = 140, + IPU_IRQ_DI_LLA_LOCK_ERR = 141, + IPU_IRQ_AHB_M1_ERR = 142, + IPU_IRQ_AHB_M12_ERR = 143, +#else + IPU_IRQ_CSI0_OUT_EOF = 0, + IPU_IRQ_CSI1_OUT_EOF = 1, + IPU_IRQ_CSI2_OUT_EOF = 2, + IPU_IRQ_CSI3_OUT_EOF = 3, + IPU_IRQ_PP_IN_EOF = 11, + IPU_IRQ_PRP_IN_EOF = 12, + IPU_IRQ_PRP_GRAPH_IN_EOF = 14, + IPU_IRQ_PP_GRAPH_IN_EOF = 15, + IPU_IRQ_PRP_ALPHA_IN_EOF = 17, + IPU_IRQ_PP_ALPHA_IN_EOF = 18, + IPU_IRQ_PRP_ENC_OUT_EOF = 20, + IPU_IRQ_PRP_VF_OUT_EOF = 21, + IPU_IRQ_PP_OUT_EOF = 22, + IPU_IRQ_BG_SYNC_EOF = 23, + IPU_IRQ_BG_ASYNC_EOF = 24, + IPU_IRQ_FG_SYNC_EOF = 27, + IPU_IRQ_DC_SYNC_EOF = 28, + IPU_IRQ_FG_ASYNC_EOF = 29, + IPU_IRQ_FG_ALPHA_SYNC_EOF = 31, + + IPU_IRQ_FG_ALPHA_ASYNC_EOF = 33, + IPU_IRQ_DC_READ_EOF = 40, + IPU_IRQ_DC_ASYNC_EOF = 41, + IPU_IRQ_DC_CMD1_EOF = 42, + IPU_IRQ_DC_CMD2_EOF = 43, + IPU_IRQ_DC_MASK_EOF = 44, + IPU_IRQ_PRP_ENC_ROT_OUT_EOF = 45, + IPU_IRQ_PRP_VF_ROT_OUT_EOF = 46, + IPU_IRQ_PP_ROT_OUT_EOF = 47, + IPU_IRQ_PRP_ENC_ROT_IN_EOF = 48, + IPU_IRQ_PRP_VF_ROT_IN_EOF = 49, + IPU_IRQ_PP_ROT_IN_EOF = 50, + IPU_IRQ_BG_ALPHA_SYNC_EOF = 51, + IPU_IRQ_BG_ALPHA_ASYNC_EOF = 52, + + IPU_IRQ_DP_SF_START = 448 + 2, + IPU_IRQ_DP_SF_END = 448 + 3, + IPU_IRQ_BG_SF_END = IPU_IRQ_DP_SF_END, + IPU_IRQ_DC_FC_0 = 448 + 8, + IPU_IRQ_DC_FC_1 = 448 + 9, + IPU_IRQ_DC_FC_2 = 448 + 10, + IPU_IRQ_DC_FC_3 = 448 + 11, + IPU_IRQ_DC_FC_4 = 448 + 12, + IPU_IRQ_DC_FC_6 = 448 + 13, + IPU_IRQ_VSYNC_PRE_0 = 448 + 14, + IPU_IRQ_VSYNC_PRE_1 = 448 + 15, +#endif + + IPU_IRQ_COUNT +}; + +/*! + * Bitfield of Display Interface signal polarities. + */ +typedef struct { + unsigned datamask_en:1; + unsigned ext_clk:1; + unsigned interlaced:1; + unsigned odd_field_first:1; + unsigned clksel_en:1; + unsigned clkidle_en:1; + unsigned data_pol:1; /* true = inverted */ + unsigned clk_pol:1; /* true = rising edge */ + unsigned enable_pol:1; + unsigned Hsync_pol:1; /* true = active high */ + unsigned Vsync_pol:1; +} ipu_di_signal_cfg_t; + +/*! + * Bitfield of CSI signal polarities and modes. + */ + +typedef struct { + unsigned data_width:4; + unsigned clk_mode:3; + unsigned ext_vsync:1; + unsigned Vsync_pol:1; + unsigned Hsync_pol:1; + unsigned pixclk_pol:1; + unsigned data_pol:1; + unsigned sens_clksrc:1; + unsigned pack_tight:1; + unsigned force_eof:1; + unsigned data_en_pol:1; + unsigned data_fmt; + unsigned csi; + unsigned mclk; +} ipu_csi_signal_cfg_t; + +/*! + * Enumeration of CSI data bus widths. + */ +enum { + IPU_CSI_DATA_WIDTH_4, + IPU_CSI_DATA_WIDTH_8, + IPU_CSI_DATA_WIDTH_10, + IPU_CSI_DATA_WIDTH_16, +}; + +/*! + * Enumeration of CSI clock modes. + */ +enum { + IPU_CSI_CLK_MODE_GATED_CLK, + IPU_CSI_CLK_MODE_NONGATED_CLK, + IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE, + IPU_CSI_CLK_MODE_CCIR656_INTERLACED, + IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR, + IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR, + IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR, + IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR, +}; + +enum { + IPU_CSI_MIPI_DI0, + IPU_CSI_MIPI_DI1, + IPU_CSI_MIPI_DI2, + IPU_CSI_MIPI_DI3, +}; + +typedef enum { + RGB, + YCbCr, + YUV +} ipu_color_space_t; + +/*! + * Enumeration of ADC vertical sync mode. + */ +typedef enum { + VsyncNone, + VsyncInternal, + VsyncCSI, + VsyncExternal +} vsync_t; + +typedef enum { + DAT, + CMD +} cmddata_t; + +/*! + * Enumeration of ADC display update mode. + */ +typedef enum { + IPU_ADC_REFRESH_NONE, + IPU_ADC_AUTO_REFRESH, + IPU_ADC_AUTO_REFRESH_SNOOP, + IPU_ADC_SNOOPING, +} ipu_adc_update_mode_t; + +/*! + * Enumeration of ADC display interface types (serial or parallel). + */ +enum { + IPU_ADC_IFC_MODE_SYS80_TYPE1, + IPU_ADC_IFC_MODE_SYS80_TYPE2, + IPU_ADC_IFC_MODE_SYS68K_TYPE1, + IPU_ADC_IFC_MODE_SYS68K_TYPE2, + IPU_ADC_IFC_MODE_3WIRE_SERIAL, + IPU_ADC_IFC_MODE_4WIRE_SERIAL, + IPU_ADC_IFC_MODE_5WIRE_SERIAL_CLK, + IPU_ADC_IFC_MODE_5WIRE_SERIAL_CS, +}; + +enum { + IPU_ADC_IFC_WIDTH_8, + IPU_ADC_IFC_WIDTH_16, +}; + +/*! + * Enumeration of ADC display interface burst mode. + */ +enum { + IPU_ADC_BURST_WCS, + IPU_ADC_BURST_WBLCK, + IPU_ADC_BURST_NONE, + IPU_ADC_BURST_SERIAL, +}; + +/*! + * Enumeration of ADC display interface RW signal timing modes. + */ +enum { + IPU_ADC_SER_NO_RW, + IPU_ADC_SER_RW_BEFORE_RS, + IPU_ADC_SER_RW_AFTER_RS, +}; + +/*! + * Bitfield of ADC signal polarities and modes. + */ +typedef struct { + unsigned data_pol:1; + unsigned clk_pol:1; + unsigned cs_pol:1; + unsigned rs_pol:1; + unsigned addr_pol:1; + unsigned read_pol:1; + unsigned write_pol:1; + unsigned Vsync_pol:1; + unsigned burst_pol:1; + unsigned burst_mode:2; + unsigned ifc_mode:3; + unsigned ifc_width:5; + unsigned ser_preamble_len:4; + unsigned ser_preamble:8; + unsigned ser_rw_mode:2; +} ipu_adc_sig_cfg_t; + +/*! + * Enumeration of ADC template commands. + */ +enum { + RD_DATA, + RD_ACK, + RD_WAIT, + WR_XADDR, + WR_YADDR, + WR_ADDR, + WR_CMND, + WR_DATA, +}; + +/*! + * Enumeration of ADC template command flow control. + */ +enum { + SINGLE_STEP, + PAUSE, + STOP, +}; + +/*Define template constants*/ +#define ATM_ADDR_RANGE 0x20 /*offset address of DISP */ +#define TEMPLATE_BUF_SIZE 0x20 /*size of template */ + +/*! + * Define to create ADC template command entry. + */ +#define ipu_adc_template_gen(oc, rs, fc, dat) ( ((rs) << 29) | ((fc) << 27) | \ + ((oc) << 24) | (dat) ) + +typedef struct { + u32 reg; + u32 value; +} ipu_lpmc_reg_t; + +#define IPU_LPMC_REG_READ 0x80000000L + +#define CSI_MCLK_VF 1 +#define CSI_MCLK_ENC 2 +#define CSI_MCLK_RAW 4 +#define CSI_MCLK_I2C 8 + +/* Common IPU API */ +int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t * params); +void ipu_uninit_channel(ipu_channel_t channel); + +static inline bool ipu_can_rotate_in_place(ipu_rotate_mode_t rot) +{ +#ifdef CONFIG_MXC_IPU_V3D + return (rot < IPU_ROTATE_HORIZ_FLIP); +#else + return (rot < IPU_ROTATE_90_RIGHT); +#endif +} + +int32_t ipu_init_channel_buffer(ipu_channel_t channel, ipu_buffer_t type, + uint32_t pixel_fmt, + uint16_t width, uint16_t height, + uint32_t stride, + ipu_rotate_mode_t rot_mode, + dma_addr_t phyaddr_0, dma_addr_t phyaddr_1, + uint32_t u_offset, uint32_t v_offset); + +int32_t ipu_update_channel_buffer(ipu_channel_t channel, ipu_buffer_t type, + uint32_t bufNum, dma_addr_t phyaddr); + +int32_t ipu_select_buffer(ipu_channel_t channel, + ipu_buffer_t type, uint32_t bufNum); + +int32_t ipu_link_channels(ipu_channel_t src_ch, ipu_channel_t dest_ch); +int32_t ipu_unlink_channels(ipu_channel_t src_ch, ipu_channel_t dest_ch); + +int32_t ipu_enable_channel(ipu_channel_t channel); +int32_t ipu_disable_channel(ipu_channel_t channel, bool wait_for_stop); + +int ipu_lowpwr_display_enable(void); +int ipu_lowpwr_display_disable(void); + +void ipu_enable_irq(uint32_t irq); +void ipu_disable_irq(uint32_t irq); +void ipu_clear_irq(uint32_t irq); +int ipu_request_irq(uint32_t irq, + irqreturn_t(*handler) (int, void *), + uint32_t irq_flags, const char *devname, void *dev_id); +void ipu_free_irq(uint32_t irq, void *dev_id); +bool ipu_get_irq_status(uint32_t irq); +void ipu_set_csc_coefficients(ipu_channel_t channel, int32_t param[][3]); + +/* SDC API */ +int32_t ipu_sdc_init_panel(ipu_panel_t panel, + uint32_t pixel_clk, + uint16_t width, uint16_t height, + uint32_t pixel_fmt, + uint16_t hStartWidth, uint16_t hSyncWidth, + uint16_t hEndWidth, uint16_t vStartWidth, + uint16_t vSyncWidth, uint16_t vEndWidth, + ipu_di_signal_cfg_t sig); + +int32_t ipu_sdc_set_global_alpha(bool enable, uint8_t alpha); +int32_t ipu_sdc_set_color_key(ipu_channel_t channel, bool enable, + uint32_t colorKey); +int32_t ipu_sdc_set_brightness(uint8_t value); + +int32_t ipu_init_sync_panel(int disp, + uint32_t pixel_clk, + uint16_t width, uint16_t height, + uint32_t pixel_fmt, + uint16_t h_start_width, uint16_t h_sync_width, + uint16_t h_end_width, uint16_t v_start_width, + uint16_t v_sync_width, uint16_t v_end_width, + uint32_t v_to_h_sync, ipu_di_signal_cfg_t sig); + +int32_t ipu_disp_set_window_pos(ipu_channel_t channel, int16_t x_pos, + int16_t y_pos); +int32_t ipu_disp_set_global_alpha(ipu_channel_t channel, bool enable, + uint8_t alpha); +int32_t ipu_disp_set_color_key(ipu_channel_t channel, bool enable, + uint32_t colorKey); + +int ipu_init_async_panel(int disp, int type, uint32_t cycle_time, + uint32_t pixel_fmt, ipu_adc_sig_cfg_t sig); +void ipu_disp_direct_write(ipu_channel_t channel, u32 value, u32 offset); +void ipu_reset_disp_panel(void); + +/* ADC API */ +int32_t ipu_adc_write_template(display_port_t disp, uint32_t * pCmd, + bool write); + +int32_t ipu_adc_set_update_mode(ipu_channel_t channel, + ipu_adc_update_mode_t mode, + uint32_t refresh_rate, unsigned long addr, + uint32_t * size); + +int32_t ipu_adc_get_snooping_status(uint32_t * statl, uint32_t * stath); + +int32_t ipu_adc_write_cmd(display_port_t disp, cmddata_t type, + uint32_t cmd, const uint32_t * params, + uint16_t numParams); + +int32_t ipu_adc_init_panel(display_port_t disp, + uint16_t width, uint16_t height, + uint32_t pixel_fmt, + uint32_t stride, + ipu_adc_sig_cfg_t sig, + display_addressing_t addr, + uint32_t vsync_width, vsync_t mode); + +int32_t ipu_adc_init_ifc_timing(display_port_t disp, bool read, + uint32_t cycle_time, + uint32_t up_time, + uint32_t down_time, + uint32_t read_latch_time, uint32_t pixel_clk); + +/* CMOS Sensor Interface API */ +int32_t ipu_csi_init_interface(uint16_t width, uint16_t height, + uint32_t pixel_fmt, ipu_csi_signal_cfg_t sig); + +int32_t ipu_csi_enable_mclk(int src, bool flag, bool wait); + +static inline int32_t ipu_csi_enable_mclk_if(int src, uint32_t csi, + bool flag, bool wait) +{ +#ifdef CONFIG_MXC_IPU_V1 + return ipu_csi_enable_mclk(src, flag, wait); +#else + return ipu_csi_enable_mclk(csi, flag, wait); +#endif +} + +int ipu_csi_read_mclk_flag(void); + +void ipu_csi_flash_strobe(bool flag); + +void ipu_csi_get_window_size(uint32_t *width, uint32_t *height, uint32_t csi); + +void ipu_csi_set_window_size(uint32_t width, uint32_t height, uint32_t csi); + +void ipu_csi_set_window_pos(uint32_t left, uint32_t top, uint32_t csi); + +/* Post Filter functions */ +int32_t ipu_pf_set_pause_row(uint32_t pause_row); + +uint32_t bytes_per_pixel(uint32_t fmt); + +/* New added for IPU-lib functionality*/ +int ipu_open(void); +int ipu_register_generic_isr(int irq, void *dev); +void ipu_close(void); + +typedef struct _ipu_channel_parm { + ipu_channel_t channel; + ipu_channel_params_t params; + bool flag; +} ipu_channel_parm; + +typedef struct _ipu_channel_buf_parm { + ipu_channel_t channel; + ipu_buffer_t type; + uint32_t pixel_fmt; + uint16_t width; + uint16_t height; + uint16_t stride; + ipu_rotate_mode_t rot_mode; + dma_addr_t phyaddr_0; + dma_addr_t phyaddr_1; + uint32_t u_offset; + uint32_t v_offset; + uint32_t bufNum; +} ipu_channel_buf_parm; + +typedef struct _ipu_channel_link { + ipu_channel_t src_ch; + ipu_channel_t dest_ch; +} ipu_channel_link; + +typedef struct _ipu_channel_info { + ipu_channel_t channel; + bool stop; +} ipu_channel_info; + +typedef struct ipu_irq_info { + uint32_t irq; + irqreturn_t(*handler) (int, void *); + uint32_t irq_flags; + char *devname; + void *dev_id; +} ipu_irq_info; + +typedef struct _ipu_sdc_panel_info { + ipu_panel_t panel; + uint32_t pixel_clk; + uint16_t width; + uint16_t height; + uint32_t pixel_fmt; + uint16_t hStartWidth; + uint16_t hSyncWidth; + uint16_t hEndWidth; + uint16_t vStartWidth; + uint16_t vSyncWidth; + uint16_t vEndWidth; + ipu_di_signal_cfg_t signal; +} ipu_sdc_panel_info; + +typedef struct _ipu_sdc_window_pos { + ipu_channel_t channel; + int16_t x_pos; + int16_t y_pos; +} ipu_sdc_window_pos; + +typedef struct _ipu_sdc_global_alpha { + bool enable; + uint8_t alpha; +} ipu_sdc_global_alpha; + +typedef struct _ipu_sdc_color_key { + ipu_channel_t channel; + bool enable; + uint32_t colorKey; +} ipu_sdc_color_key; + +typedef struct _ipu_adc_template { + display_port_t disp; + uint32_t *pCmd; + bool write; +} ipu_adc_template; + +typedef struct _ipu_adc_update { + ipu_channel_t channel; + ipu_adc_update_mode_t mode; + uint32_t refresh_rate; + unsigned long addr; + uint32_t *size; +} ipu_adc_update; + +typedef struct _ipu_adc_snoop { + uint32_t *statl; + uint32_t *stath; +} ipu_adc_snoop; + +typedef struct _ipu_adc_cmd { + display_port_t disp; + cmddata_t type; + uint32_t cmd; + uint32_t *params; + uint16_t numParams; +} ipu_adc_cmd; + +typedef struct _ipu_adc_panel { + display_port_t disp; + uint16_t width; + uint16_t height; + uint32_t pixel_fmt; + uint32_t stride; + ipu_adc_sig_cfg_t signal; + display_addressing_t addr; + uint32_t vsync_width; + vsync_t mode; +} ipu_adc_panel; + +typedef struct _ipu_adc_ifc_timing { + display_port_t disp; + bool read; + uint32_t cycle_time; + uint32_t up_time; + uint32_t down_time; + uint32_t read_latch_time; + uint32_t pixel_clk; +} ipu_adc_ifc_timing; + +typedef struct _ipu_csi_interface { + uint16_t width; + uint16_t height; + uint16_t pixel_fmt; + ipu_csi_signal_cfg_t signal; +} ipu_csi_interface; + +typedef struct _ipu_csi_mclk { + int src; + bool flag; + bool wait; +} ipu_csi_mclk; + +typedef struct _ipu_csi_window { + uint32_t left; + uint32_t top; +} ipu_csi_window; + +typedef struct _ipu_csi_window_size { + uint32_t width; + uint32_t height; +} ipu_csi_window_size; + +typedef struct _ipu_event_info { + int irq; + void *dev; +} ipu_event_info; + +typedef struct _ipu_mem_info { + dma_addr_t paddr; + void *vaddr; + int size; +} ipu_mem_info; + +/* IOCTL commands */ + +#define IPU_INIT_CHANNEL _IOW('I',0x1,ipu_channel_parm) +#define IPU_UNINIT_CHANNEL _IOW('I',0x2,ipu_channel_t) +#define IPU_INIT_CHANNEL_BUFFER _IOW('I',0x3,ipu_channel_buf_parm) +#define IPU_UPDATE_CHANNEL_BUFFER _IOW('I',0x4,ipu_channel_buf_parm) +#define IPU_SELECT_CHANNEL_BUFFER _IOW('I',0x5,ipu_channel_buf_parm) +#define IPU_LINK_CHANNELS _IOW('I',0x6,ipu_channel_link) +#define IPU_UNLINK_CHANNELS _IOW('I',0x7,ipu_channel_link) +#define IPU_ENABLE_CHANNEL _IOW('I',0x8,ipu_channel_t) +#define IPU_DISABLE_CHANNEL _IOW('I',0x9,ipu_channel_info) +#define IPU_ENABLE_IRQ _IOW('I',0xA,int) +#define IPU_DISABLE_IRQ _IOW('I',0xB,int) +#define IPU_CLEAR_IRQ _IOW('I',0xC,int) +#define IPU_FREE_IRQ _IOW('I',0xD,ipu_irq_info) +#define IPU_REQUEST_IRQ_STATUS _IOW('I',0xE,int) +#define IPU_SDC_INIT_PANEL _IOW('I',0xF,ipu_sdc_panel_info) +#define IPU_SDC_SET_WIN_POS _IOW('I',0x10,ipu_sdc_window_pos) +#define IPU_SDC_SET_GLOBAL_ALPHA _IOW('I',0x11,ipu_sdc_global_alpha) +#define IPU_SDC_SET_COLOR_KEY _IOW('I',0x12,ipu_sdc_color_key) +#define IPU_SDC_SET_BRIGHTNESS _IOW('I',0x13,int) +#define IPU_ADC_WRITE_TEMPLATE _IOW('I',0x14,ipu_adc_template) +#define IPU_ADC_UPDATE _IOW('I',0x15,ipu_adc_update) +#define IPU_ADC_SNOOP _IOW('I',0x16,ipu_adc_snoop) +#define IPU_ADC_CMD _IOW('I',0x17,ipu_adc_cmd) +#define IPU_ADC_INIT_PANEL _IOW('I',0x18,ipu_adc_panel) +#define IPU_ADC_IFC_TIMING _IOW('I',0x19,ipu_adc_ifc_timing) +#define IPU_CSI_INIT_INTERFACE _IOW('I',0x1A,ipu_csi_interface) +#define IPU_CSI_ENABLE_MCLK _IOW('I',0x1B,ipu_csi_mclk) +#define IPU_CSI_READ_MCLK_FLAG _IOR('I',0x1C,ipu_csi_mclk) +#define IPU_CSI_FLASH_STROBE _IOW('I',0x1D,ipu_csi_mclk) +#define IPU_CSI_GET_WIN_SIZE _IOR('I',0x1E,ipu_csi_window_size) +#define IPU_CSI_SET_WIN_SIZE _IOW('I',0x1F,ipu_csi_window_size) +#define IPU_CSI_SET_WINDOW _IOW('I',0x20,ipu_csi_window) +#define IPU_PF_SET_PAUSE_ROW _IOW('I',0x21, uint32_t) +#define IPU_REGISTER_GENERIC_ISR _IOW('I',0x22,ipu_event_info) +#define IPU_GET_EVENT _IOR('I',0x23,ipu_event_info) +#define IPU_ALOC_MEM _IOWR('I', 0x24, ipu_mem_info) +#define IPU_FREE_MEM _IOW('I', 0x25, ipu_mem_info) + +#endif --- linux-2.6.28.orig/include/linux/module.h +++ linux-2.6.28/include/linux/module.h @@ -391,7 +391,6 @@ static inline void __module_get(struct module *module) { if (module) { - BUG_ON(module_refcount(module) == 0); local_inc(&module->ref[get_cpu()].count); put_cpu(); } --- linux-2.6.28.orig/include/linux/fsl_devices.h +++ linux-2.6.28/include/linux/fsl_devices.h @@ -100,11 +100,45 @@ FSL_USB2_PHY_SERIAL, }; +struct platform_device; struct fsl_usb2_platform_data { /* board specific information */ enum fsl_usb2_operating_modes operating_mode; enum fsl_usb2_phy_modes phy_mode; unsigned int port_enables; + + char *name; /* pretty print */ + int (*platform_init) (struct platform_device *); + void (*platform_uninit) (struct fsl_usb2_platform_data *); + void __iomem *regs; /* ioremap'd register base */ + u32 xcvr_type; /* PORTSC_PTS_* */ + char *transceiver; /* transceiver name */ + unsigned power_budget; /* for hcd->power_budget */ + struct platform_device *pdev; + struct fsl_xcvr_ops *xcvr_ops; + struct fsl_xcvr_power *xcvr_pwr; + int (*gpio_usb_active) (void); + void (*gpio_usb_inactive) (void); + unsigned big_endian_mmio : 1; + unsigned big_endian_desc : 1; + unsigned es : 1; /* need USBMODE:ES */ + unsigned have_sysif_regs : 1; + unsigned le_setup_buf : 1; + unsigned change_ahb_burst:1; + unsigned ahb_burst_mode:3; + unsigned suspended : 1; + unsigned already_suspended : 1; + + /* register save area for suspend/resume */ + u32 pm_command; + u32 pm_status; + u32 pm_intr_enable; + u32 pm_frame_index; + u32 pm_segment; + u32 pm_frame_list; + u32 pm_async_next; + u32 pm_configured_flag; + u32 pm_portsc; }; /* Flags in fsl_usb2_mph_platform_data */ @@ -122,6 +156,20 @@ u32 sysclk; }; +struct fsl_ata_platform_data { + int adma_flag; /* AMDA mode is used or not, 1:used.*/ + int udma_mask; /* UDMA modes h/w can handle */ + int mwdma_mask; /* MDMA modes h/w can handle */ + int pio_mask; /* PIO modes h/w can handle */ + int fifo_alarm; /* value for fifo_alarm reg */ + int max_sg; /* longest sglist h/w can handle */ + int (*init)(struct platform_device *pdev); + void (*exit)(void); + char *io_reg; + char *core_reg; +}; + + struct mpc8xx_pcmcia_ops { void(*hw_ctrl)(int slot, int enable); int(*voltage_set)(int slot, int vcc, int vpp); --- linux-2.6.28.orig/include/linux/radix-tree.h +++ linux-2.6.28/include/linux/radix-tree.h @@ -136,7 +136,7 @@ */ static inline void *radix_tree_deref_slot(void **pslot) { - void *ret = *pslot; + void *ret = rcu_dereference(*pslot); if (unlikely(radix_tree_is_indirect_ptr(ret))) ret = RADIX_TREE_RETRY; return ret; --- linux-2.6.28.orig/include/linux/writeback.h +++ linux-2.6.28/include/linux/writeback.h @@ -30,7 +30,6 @@ enum writeback_sync_modes { WB_SYNC_NONE, /* Don't wait on anything */ WB_SYNC_ALL, /* Wait on every mapping */ - WB_SYNC_HOLD, /* Hold the inode on sb_dirty for sys_sync() */ }; /* --- linux-2.6.28.orig/include/linux/mxc_scc2_driver.h +++ linux-2.6.28/include/linux/mxc_scc2_driver.h @@ -0,0 +1,973 @@ + +/* + * Copyright 2004-2009 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 SCC_DRIVER_H +#define SCC_DRIVER_H + +/* + * NAMING CONVENTIONS + * ================== + * (A note to maintainers and other interested parties) + * + * Use scc_ or SCC_ prefix for 'high-level' interface routines and the types + * passed to those routines. Try to avoid #defines in these interfaces. + * + * Use SMN_ or SCM_ prefix for the #defines used with scc_read_register() and + * scc_write_register, or values passed/retrieved from those routines. + */ + +/*! @file mxc_scc2_driver.h + * + * @brief (Header file to use the SCC2 driver.) + * + * The SCC2 driver is available to other kernel modules directly. Secure + * Partition functionality is extended to users through the SHW API. Other + * functionality of the SCC2 is limited to kernel-space users. + * + * With the exception of #scc_monitor_security_failure(), all routines are + * 'synchronous', i.e. they will not return to their caller until the requested + * action is complete, or fails to complete. Some of these functions could + * take quite a while to perform, depending upon the request. + * + * Routines are provided to: + * @li trigger a security-violation alarm - #scc_set_sw_alarm() + * @li get configuration and version information - #scc_get_configuration() + * @li zeroize memory - #scc_zeroize_memories() + * @li Work with secure partitions: #scc_allocate_partition() + * #scc_engage_partition() #scc_diminish_permissions() + * #scc_release_partition() + * @li Encrypt or decrypt regions of data: #scc_encrypt_region() + * #scc_decrypt_region() + * @li monitor the Security Failure alarm - #scc_monitor_security_failure() + * @li stop monitoring Security Failure alarm - + * #scc_stop_monitoring_security_failure() + * @li write registers of the SCC - #scc_write_register() + * @li read registers of the SCC - #scc_read_register() + * + * The SCC2 encrypts and decrypts using Triple DES with an internally stored + * key. When the SCC2 is in Secure mode, it uses its secret, unique-per-chip + * key. When it is in Non-Secure mode, it uses a default key. This ensures + * that secrets stay secret if the SCC2 is not in Secure mode. + * + * Not all functions that could be provided in a 'high level' manner have been + * implemented. Among the missing are interfaces to the ASC/AIC components and + * the timer functions. These and other features must be accessed through + * #scc_read_register() and #scc_write_register(), using the @c \#define values + * provided. + * + * Here is a glossary of acronyms used in the SCC2 driver documentation: + * - CBC - Cipher Block Chaining. A method of performing a block cipher. + * Each block is encrypted using some part of the result of the previous + * block's encryption. It needs an 'initialization vector' to seed the + * operation. + * - ECB - Electronic Code Book. A method of performing a block cipher. + * With a given key, a given block will always encrypt to the same value. + * - DES - Data Encryption Standard. (8-byte) Block cipher algorithm which + * uses 56-bit keys. In SCC2, this key is constant and unique to the device. + * SCC uses the "triple DES" form of this algorithm. + * - AIC - Algorithm Integrity Checker. + * - ASC - Algorithm Sequence Checker. + * - SMN - Security Monitor. The part of the SCC2 responsible for monitoring + * for security problems and notifying the CPU and other PISA components. + * - SCM - Secure Memory. The part of the SCC2 which handles the cryptography. + * - SCC - Security Controller. Central security mechanism for PISA. + * - PISA - Platform-Independent Security Architecture. + */ + +/* Temporarily define compile-time flags to make Doxygen happy. */ +#ifdef DOXYGEN_HACK +/** @defgroup scccompileflags SCC Driver compile-time flags + * + * These preprocessor flags should be set, if desired, in a makefile so + * that they show up on the compiler command line. + */ +/** @addtogroup scccompileflags */ + +/** @{ */ +/** + * Compile-time flag to change @ref smnregs and @ref scmregs + * offset values for the SCC's implementation on the MX.21 board. + * + * This must also be set properly for any code which calls the + * scc_read_register() or scc_write_register() functions or references the + * register offsets. + */ +#define TAHITI +/** @} */ +#undef TAHITI + +#endif /* DOXYGEN_HACK */ + +/*! Major Version of the driver. Used for + scc_configuration->driver_major_version */ +#define SCC_DRIVER_MAJOR_VERSION 2 +/*! Old Minor Version of the driver. */ +#define SCC_DRIVER_MINOR_VERSION_0 0 +/*! Minor Version of the driver. Used for + scc_configuration->driver_minor_version */ +#define SCC_DRIVER_MINOR_VERSION_2 2 + + +/*! + * Interrupt line number of SCM interrupt. + */ +#define INT_SCC_SCM MXC_INT_SCC_SCM + +/*! + * Interrupt line number of the SMN interrupt. + */ +#define INT_SCC_SMN MXC_INT_SCC_SMN + +/** + * @typedef scc_return_t + */ +/** Common status return values from SCC driver functions. */ + typedef enum scc_return_t { + SCC_RET_OK = 0, /**< Function succeeded */ + SCC_RET_FAIL, /**< Non-specific failure */ + SCC_RET_VERIFICATION_FAILED, + /**< Decrypt validation failed */ + SCC_RET_TOO_MANY_FUNCTIONS, + /**< At maximum registered functions */ + SCC_RET_BUSY, /**< SCC is busy and cannot handle request */ + /**< Encryption or decryption failed because@c count_out_bytes + says that @c data_out is too small to hold the value. */ + SCC_RET_INSUFFICIENT_SPACE, + } scc_return_t; + +/** + * @typedef scc_partition_status_t + */ +/** Partition status information. */ + typedef enum scc_partition_status_t { + SCC_PART_S_UNUSABLE, + /**< Partition not implemented */ + SCC_PART_S_UNAVAILABLE, + /**< Partition owned by other host */ + SCC_PART_S_AVAILABLE, + /**< Partition available */ + SCC_PART_S_ALLOCATED, + /**< Partition owned by host but not engaged*/ + SCC_PART_S_ENGAGED, + /**< Partition owned by host and engaged */ + } scc_partition_status_t; + +/** + * Configuration information about SCC and the driver. + * + * This struct/typedef contains information from the SCC and the driver to + * allow the user of the driver to determine the size of the SCC's memories and + * the version of the SCC and the driver. + */ + typedef struct scc_config_t { + int driver_major_version; + /**< Major version of the SCC driver code */ + int driver_minor_version; + /**< Minor version of the SCC driver code */ + int scm_version; /**< Version from SCM Configuration register */ + int smn_version; /**< Version from SMN Status register */ + /**< Number of bytes per block of RAM; also + block size of the crypto algorithm. */ + int block_size_bytes; + int partition_size_bytes; + /**< Number of bytes in each partition */ + int partition_count; + /**< Number of partitions on this platform */ + } scc_config_t; + +/** + * @typedef scc_enc_dec_t + */ +/** + * Determine whether SCC will run its cryptographic + * function as an encryption or decryption. + */ + typedef enum scc_enc_dec_t { + SCC_ENCRYPT, /**< Encrypt (from Red to Black) */ + SCC_DECRYPT /**< Decrypt (from Black to Red) */ + } scc_enc_dec_t; + +/** + * @typedef scc_verify_t + */ +/** + * Tell the driver whether it is responsible for verifying the integrity of a + * secret. During an encryption, using other than #SCC_VERIFY_MODE_NONE will + * cause a check value to be generated and appended to the plaintext before + * encryption. During decryption, the check value will be verified after + * decryption, and then stripped from the message. + */ + typedef enum scc_verify_t { + /** No verification value added or checked. Input plaintext data must be + * be a multiple of the blocksize (#scc_get_configuration()). */ + SCC_VERIFY_MODE_NONE, + /** Driver will generate/validate a 2-byte CCITT CRC. Input plaintext + will be padded to a multiple of the blocksize, adding 3-10 bytes + to the resulting output ciphertext. Upon decryption, this padding + will be stripped, and the CRC will be verified. */ + SCC_VERIFY_MODE_CCITT_CRC + } scc_verify_t; + +/** + * @typedef scc_cypher_mode_t + */ +/** + * Select the cypher mode to use for partition cover/uncover operations. + */ + + typedef enum scc_cypher_mode_t { + SCC_CYPHER_MODE_ECB = 1, + /**< ECB mode */ + SCC_CYPHER_MODE_CBC = 2, + /**< CBC mode */ + } scc_cypher_mode_t; + +/** + * Allocate a partition of secure memory + * + * @param smid_value Value to use for the SMID register. Must be 0 for + * kernel mode ownership. + * @param[out] part_no (If successful) Assigned partition number. + * @param[out] part_base Kernel virtual address of the partition. + * @param[out] part_phys Physical address of the partition. + * + * @return SCC_RET_OK if successful. + */ + extern scc_return_t + scc_allocate_partition(uint32_t smid_value, + int *part_no, + void **part_base, uint32_t *part_phys); + +/* Note: This function has to be run in the same context (userspace or kernel + * mode) as the process that will be using the partition. Because the SCC2 API + * is not accessible in user mode, this function is also provided as a macro in + * in fsl_shw.h. Kernel-mode users that include this file are able to use this + * version of the function without having to include the whole SHW API. If the + * macro definition was defined before we got here, un-define it so this + * version will be used instead. + */ + +#ifdef scc_engage_partition +#undef scc_engage_partition +#endif + +/** + * Engage partition of secure memory + * + * @param part_base (kernel) Virtual + * @param UMID NULL, or 16-byte UMID for partition security + * @param permissions ORed values of the type SCM_PERM_* which will be used as + * initial partition permissions. SHW API users should use + * the FSL_PERM_* definitions instead. + * + * @return SCC_RET_OK if successful. + */ + extern scc_return_t + scc_engage_partition(void *part_base, + const uint8_t *UMID, uint32_t permissions); + +/** + * Release a partition of secure memory + * + * @param part_base Kernel virtual address of the partition to be released. + * + * @return SCC_RET_OK if successful. + */ + extern scc_return_t scc_release_partition(void *part_base); + +/** + * Diminish the permissions on a partition of secure memory + * + * @param part_base Kernel virtual address of the partition. + * + * @param permissions ORed values of the type SCM_PERM_* which will be used as + * initial partition permissions. SHW API users should use + * the FSL_PERM_* definitions instead. + * + * @return SCC_RET_OK if successful. + */ + extern scc_return_t + scc_diminish_permissions(void *part_base, uint32_t permissions); + +/** + * Query the status of a partition of secure memory + * + * @param part_base Kernel virtual address of the partition. + * + * @return SCC_RET_OK if successful. + */ + extern scc_partition_status_t scc_partition_status(void *part_base); + +/** + * Calculate the physical address from the kernel virtual address. + */ + extern uint32_t scc_virt_to_phys(void *address); +/*scc_return_t +scc_verify_slot_access(uint64_t owner_id, uint32_t slot, uint32_t access_len);*/ + + +/** + * Encrypt a region of secure memory. + * + * @param part_base Kernel virtual address of the partition. + * @param offset_bytes Offset from the start of the partition to the plaintext + * data. + * @param byte_count Length of the region (octets). + * @param black_data Physical location to store the encrypted data. + * @param IV Value to use for the Initialization Vector. + * @param cypher_mode Cyphering mode to use, specified by type + * #scc_cypher_mode_t + * + * @return SCC_RET_OK if successful. + */ + extern scc_return_t + scc_encrypt_region(uint32_t part_base, uint32_t offset_bytes, + uint32_t byte_count, uint8_t *black_data, + uint32_t *IV, scc_cypher_mode_t cypher_mode); + +/** + * Decrypt a region into secure memory + * + * @param part_base Kernel virtual address of the partition. + * @param offset_bytes Offset from the start of the partition to store the + * plaintext data. + * @param byte_count Length of the region (octets). + * @param black_data Physical location of the encrypted data. + * @param IV Value to use for the Initialization Vector. + * @param cypher_mode Cyphering mode to use, specified by type + * #scc_cypher_mode_t + * + * @return SCC_RET_OK if successful. + */ + extern scc_return_t + scc_decrypt_region(uint32_t part_base, uint32_t offset_bytes, + uint32_t byte_count, uint8_t *black_data, + uint32_t *IV, scc_cypher_mode_t cypher_mode); + +/** + * Retrieve configuration information from the SCC. + * + * This function always succeeds. + * + * @return A pointer to the configuration information. This is a pointer to + * static memory and must not be freed. The values never change, and + * the return value will never be null. + */ + extern scc_config_t *scc_get_configuration(void); + +/** + * Zeroize Red and Black memories of the SCC. This will start the Zeroizing + * process. The routine will return when the memories have zeroized or failed + * to do so. The driver will poll waiting for this to occur, so this + * routine must not be called from interrupt level. Some future version of + * driver may elect instead to sleep. + * + * @return 0 or error if initialization fails. + */ + extern scc_return_t scc_zeroize_memories(void); + +/** + * Signal a software alarm to the SCC. This will take the SCC and other PISA + * parts out of Secure mode and into Security Failure mode. The SCC will stay + * in failed mode until a reboot. + * + * @internal + * If the SCC is not already in fail state, simply write the + * #SMN_COMMAND_SET_SOFTWARE_ALARM bit in #SMN_COMMAND_REG. Since there is no + * reason to wait for the interrupt to bounce back, simply act as though + * one did. + */ + extern void scc_set_sw_alarm(void); + +/** + * This routine will register a function to be called should a Security Failure + * be signalled by the SCC (Security Monitor). + * + * The callback function may be called from interrupt level, it may be called + * from some process' task. It should therefore not take a long time to + * perform its operation, and it may not sleep. + * + * @param callback_func Function pointer to routine which will receive + * notification of the security failure. + * @return 0 if function was successfully registered, non-zero on + * failure. See #scc_return_t. + * + * @internal + * There is a fixed global static array which keeps track of the requests to + * monitor the failure. + * + * Add @c callback_func to the first empty slot in #scc_callbacks[]. If there + * is no room, return #SCC_RET_TOO_MANY_FUNCTIONS. + */ + extern scc_return_t scc_monitor_security_failure(void + callback_func(void)); + +/** + * This routine will deregister a function previously registered with + * #scc_monitor_security_failure(). + * + * @param callback_func Function pointer to routine previously registered with + * #scc_stop_monitoring_security_failure(). + */ + extern void scc_stop_monitoring_security_failure(void + callback_func(void)); + +/** + * Read value from an SCC register. + * The offset will be checked for validity (range) as well as whether it is + * accessible (e.g. not busy, not in failed state) at the time of the call. + * + * @param[in] register_offset The (byte) offset within the SCC block + * of the register to be queried. See + * @ref scmregs and @ref smnregs. + * @param[out] value Pointer to where value from the register + * should be placed. + * @return 0 if OK, non-zero on error. See #scc_return_t. + * + * @internal + * Verify that the register_offset is a) valid, b) refers to a readable + * register, and c) the SCC is in a state which would allow a read of this + * register. + */ + extern scc_return_t scc_read_register(int register_offset, + uint32_t * value); + +/** + * Write a new value into an SCC register. + * The offset will be checked for validity (range) as well as whether it is + * accessible (e.g. not busy, not in failed state) at the time of the call. + * + * @param[in] register_offset The (byte) offset within the SCC block + * of the register to be modified. See + * @ref scmregs and @ref smnregs + * @param[in] value The value to store into the register. + * @return 0 if OK, non-zero on error. See #scc_return_t. + * + * @internal + * Verify that the register_offset is a) valid, b) refers to a writeable + * register, and c) the SCC is in a state which would allow a write to this + * register. + */ + extern scc_return_t scc_write_register(int register_offset, + uint32_t value); + +/** + * @defgroup scmregs SCM Registers + * + * These values are offsets into the SCC for the Secure Memory + * (SCM) registers. They are used in the @c register_offset parameter of + * #scc_read_register() and #scc_write_register(). + */ +/** @addtogroup scmregs */ +/** @{ */ +/** Offset of SCM Version ID Register */ +#define SCM_VERSION_REG 0x000 +/** Offset of SCM Interrupt Control Register */ +#define SCM_INT_CTL_REG 0x008 +/** Offset of SCM Status Register */ +#define SCM_STATUS_REG 0x00c +/** Offset of SCM Error Status Register */ +#define SCM_ERR_STATUS_REG 0x010 +/** Offset of SCM Fault Address Register */ +#define SCM_FAULT_ADR_REG 0x014 +/** Offset of SCM Partition Owners Register */ +#define SCM_PART_OWNERS_REG 0x018 +/** Offset of SCM Partitions Engaged Register */ +#define SCM_PART_ENGAGED_REG 0x01c +/** Offset of SCM Unique Number 0 Register */ +#define SCM_UNIQUE_ID0_REG 0x020 +/** Offset of SCM Unique Number 1 Register */ +#define SCM_UNIQUE_ID1_REG 0x024 +/** Offset of SCM Unique Number 2 Register */ +#define SCM_UNIQUE_ID2_REG 0x028 +/** Offset of SCM Unique Number 3 Register */ +#define SCM_UNIQUE_ID3_REG 0x02c +/** Offset of SCM Zeroize Command Register */ +#define SCM_ZCMD_REG 0x050 +/** Offset of SCM Cipher Command Register */ +#define SCM_CCMD_REG 0x054 +/** Offset of SCM Cipher Black RAM Start Address Register */ +#define SCM_C_BLACK_ST_REG 0x058 +/** Offset of SCM Internal Debug Register */ +#define SCM_DBG_STATUS_REG 0x05c +/** Offset of SCM Cipher IV 0 Register */ +#define SCM_AES_CBC_IV0_REG 0x060 +/** Offset of SCM Cipher IV 1 Register */ +#define SCM_AES_CBC_IV1_REG 0x064 +/** Offset of SCM Cipher IV 2 Register */ +#define SCM_AES_CBC_IV2_REG 0x068 +/** Offset of SCM Cipher IV 3 Register */ +#define SCM_AES_CBC_IV3_REG 0x06c +/** Offset of SCM SMID Partition 0 Register */ +#define SCM_SMID0_REG 0x080 +/** Offset of SCM Partition 0 Access Permissions Register */ +#define SCM_ACC0_REG 0x084 +/** Offset of SCM SMID Partition 1 Register */ +#define SCM_SMID1_REG 0x088 +/** Offset of SCM Partition 1 Access Permissions Register */ +#define SCM_ACC1_REG 0x08c +/** Offset of SCM SMID Partition 2 Register */ +#define SCM_SMID2_REG 0x090 +/** Offset of SCM Partition 2 Access Permissions Register */ +#define SCM_ACC2_REG 0x094 +/** Offset of SCM SMID Partition 3 Register */ +#define SCM_SMID3_REG 0x098 +/** Offset of SCM Partition 3 Access Permissions Register */ +#define SCM_ACC3_REG 0x09c +/** Offset of SCM SMID Partition 4 Register */ +#define SCM_SMID4_REG 0x0a0 +/** Offset of SCM Partition 4 Access Permissions Register */ +#define SCM_ACC4_REG 0x0a4 +/** Offset of SCM SMID Partition 5 Register */ +#define SCM_SMID5_REG 0x0a8 +/** Offset of SCM Partition 5 Access Permissions Register */ +#define SCM_ACC5_REG 0x0ac +/** Offset of SCM SMID Partition 6 Register */ +#define SCM_SMID6_REG 0x0b0 +/** Offset of SCM Partition 6 Access Permissions Register */ +#define SCM_ACC6_REG 0x0b4 +/** Offset of SCM SMID Partition 7 Register */ +#define SCM_SMID7_REG 0x0b8 +/** Offset of SCM Partition 7 Access Permissions Register */ +#define SCM_ACC7_REG 0x0bc +/** Offset of SCM SMID Partition 8 Register */ +#define SCM_SMID8_REG 0x0c0 +/** Offset of SCM Partition 8 Access Permissions Register */ +#define SCM_ACC8_REG 0x0c4 +/** Offset of SCM SMID Partition 9 Register */ +#define SCM_SMID9_REG 0x0c8 +/** Offset of SCM Partition 9 Access Permissions Register */ +#define SCM_ACC9_REG 0x0cc +/** Offset of SCM SMID Partition 10 Register */ +#define SCM_SMID10_REG 0x0d0 +/** Offset of SCM Partition 10 Access Permissions Register */ +#define SCM_ACC10_REG 0x0d4 +/** Offset of SCM SMID Partition 11 Register */ +#define SCM_SMID11_REG 0x0d8 +/** Offset of SCM Partition 11 Access Permissions Register */ +#define SCM_ACC11_REG 0x0dc +/** Offset of SCM SMID Partition 12 Register */ +#define SCM_SMID12_REG 0x0e0 +/** Offset of SCM Partition 12 Access Permissions Register */ +#define SCM_ACC12_REG 0x0e4 +/** Offset of SCM SMID Partition 13 Register */ +#define SCM_SMID13_REG 0x0e8 +/** Offset of SCM Partition 13 Access Permissions Register */ +#define SCM_ACC13_REG 0x0ec +/** Offset of SCM SMID Partition 14 Register */ +#define SCM_SMID14_REG 0x0f0 +/** Offset of SCM Partition 14 Access Permissions Register */ +#define SCM_ACC14_REG 0x0f4 +/** Offset of SCM SMID Partition 15 Register */ +#define SCM_SMID15_REG 0x0f8 +/** Offset of SCM Partition 15 Access Permissions Register */ +#define SCM_ACC15_REG 0x0fc +/** @} */ + +/** Number of bytes of register space for the SCM. */ +#define SCM_REG_BANK_SIZE 0x100 + +/** Number of bytes of register space for the SCM. */ +#define SCM_REG_BANK_SIZE 0x100 + +/** Offset of the SMN registers */ +#define SMN_ADDR_OFFSET 0x100 + +/** + * @defgroup smnregs SMN Registers + * + * These values are offsets into the SCC for the Security Monitor + * (SMN) registers. They are used in the @c register_offset parameter of the + * #scc_read_register() and #scc_write_register(). + */ +/** @addtogroup smnregs */ +/** @{ */ +/** Offset of SMN Status Register */ +#define SMN_STATUS_REG (SMN_ADDR_OFFSET+0x00000000) +/** Offset of SMH Command Register */ +#define SMN_COMMAND_REG (SMN_ADDR_OFFSET+0x00000004) +/** Offset of SMH Sequence Start Register */ +#define SMN_SEQ_START_REG (SMN_ADDR_OFFSET+0x00000008) +/** Offset of SMH Sequence End Register */ +#define SMN_SEQ_END_REG (SMN_ADDR_OFFSET+0x0000000c) +/** Offset of SMH Sequence Check Register */ +#define SMN_SEQ_CHECK_REG (SMN_ADDR_OFFSET+0x00000010) +/** Offset of SMH BitBank Count Register */ +#define SMN_BB_CNT_REG (SMN_ADDR_OFFSET+0x00000014) +/** Offset of SMH BitBank Increment Register */ +#define SMN_BB_INC_REG (SMN_ADDR_OFFSET+0x00000018) +/** Offset of SMH BitBank Decrement Register */ +#define SMN_BB_DEC_REG (SMN_ADDR_OFFSET+0x0000001c) +/** Offset of SMH Compare Register */ +#define SMN_COMPARE_REG (SMN_ADDR_OFFSET+0x00000020) +/** Offset of SMH Plaintext Check Register */ +#define SMN_PT_CHK_REG (SMN_ADDR_OFFSET+0x00000024) +/** Offset of SMH Ciphertext Check Register */ +#define SMN_CT_CHK_REG (SMN_ADDR_OFFSET+0x00000028) +/** Offset of SMH Timer Initial Value Register */ +#define SMN_TIMER_IV_REG (SMN_ADDR_OFFSET+0x0000002c) +/** Offset of SMH Timer Control Register */ +#define SMN_TIMER_CTL_REG (SMN_ADDR_OFFSET+0x00000030) +/** Offset of SMH Security Violation Register */ +#define SMN_SEC_VIO_REG (SMN_ADDR_OFFSET+0x00000034) +/** Offset of SMH Timer Register */ +#define SMN_TIMER_REG (SMN_ADDR_OFFSET+0x00000038) +/** Offset of SMH High-Assurance Control Register */ +#define SMN_HAC_REG (SMN_ADDR_OFFSET+0x0000003c) +/** Number of bytes allocated to the SMN registers */ +#define SMN_REG_BANK_SIZE 0x40 +/** @} */ + +/** Number of bytes of total register space for the SCC. */ +#define SCC_ADDRESS_RANGE (SMN_ADDR_OFFSET + SMN_REG_BANK_SIZE) + +/** + * @defgroup smnstatusregdefs SMN Status Register definitions (SMN_STATUS) + */ +/** @addtogroup smnstatusregdefs */ +/** @{ */ +/** SMN version id. */ +#define SMN_STATUS_VERSION_ID_MASK 0xfc000000 +/** number of bits to shift #SMN_STATUS_VERSION_ID_MASK to get it to LSB */ +#define SMN_STATUS_VERSION_ID_SHIFT 28 +/** Illegal bus master access attempted. */ +#define SMN_STATUS_ILLEGAL_MASTER 0x01000000 +/** Scan mode entered/exited since last reset. */ +#define SMN_STATUS_SCAN_EXIT 0x00800000 +/** Some security peripheral is initializing */ +#define SMN_STATUS_PERIP_INIT 0x00010000 +/** Internal error detected in SMN. */ +#define SMN_STATUS_SMN_ERROR 0x00008000 +/** SMN has an outstanding interrupt. */ +#define SMN_STATUS_SMN_STATUS_IRQ 0x00004000 +/** Software Alarm was triggered. */ +#define SMN_STATUS_SOFTWARE_ALARM 0x00002000 +/** Timer has expired. */ +#define SMN_STATUS_TIMER_ERROR 0x00001000 +/** Plaintext/Ciphertext compare failed. */ +#define SMN_STATUS_PC_ERROR 0x00000800 +/** Bit Bank detected overflow or underflow */ +#define SMN_STATUS_BITBANK_ERROR 0x00000400 +/** Algorithm Sequence Check failed. */ +#define SMN_STATUS_ASC_ERROR 0x00000200 +/** Security Policy Block detected error. */ +#define SMN_STATUS_SECURITY_POLICY_ERROR 0x00000100 +/** Security Violation Active error. */ +#define SMN_STATUS_SEC_VIO_ACTIVE_ERROR 0x00000080 +/** Processor booted from internal ROM. */ +#define SMN_STATUS_INTERNAL_BOOT 0x00000020 +/** SMN's internal state. */ +#define SMN_STATUS_STATE_MASK 0x0000001F +/** Number of bits to shift #SMN_STATUS_STATE_MASK to get it to LSB. */ +#define SMN_STATUS_STATE_SHIFT 0 +/** @} */ + +/** + * @defgroup sccscmstates SMN Model Secure State Controller States (SMN_STATE_MASK) + */ +/** @addtogroup sccscmstates */ +/** @{ */ +/** This is the first state of the SMN after power-on reset */ +#define SMN_STATE_START 0x0 +/** The SMN is zeroizing its RAM during reset */ +#define SMN_STATE_ZEROIZE_RAM 0x5 +/** SMN has passed internal checks, and is waiting for Software check-in */ +#define SMN_STATE_HEALTH_CHECK 0x6 +/** Fatal Security Violation. SMN is locked, SCM is inoperative. */ +#define SMN_STATE_FAIL 0x9 +/** SCC is in secure state. SCM is using secret key. */ +#define SMN_STATE_SECURE 0xA +/** Due to non-fatal error, device is not secure. SCM is using default key. */ +#define SMN_STATE_NON_SECURE 0xC +/** @} */ + +/** @{ */ +/** SCM Status bit: Key Status is Default Key in Use */ +#define SCM_STATUS_KST_DEFAULT_KEY 0x80000000 +/** SCM Status bit: Key Status is (reserved) */ +#define SCM_STATUS_KST_RESERVED1 0x40000000 +/** SCM Status bit: Key status is Wrong Key */ +#define SCM_STATUS_KST_WRONG_KEY 0x20000000 +/** SCM Status bit: Bad Key detected */ +#define SCM_STATUS_KST_BAD_KEY 0x10000000 +/** SCM Status bit: Error has occurred */ +#define SCM_STATUS_ERR 0x00008000 +/** SCM Status bit: Monitor State is Failed */ +#define SCM_STATUS_MSS_FAIL 0x00004000 +/** SCM Status bit: Monitor State is Secure */ +#define SCM_STATUS_MSS_SEC 0x00002000 +/** SCM Status bit: Secure Storage is Failed */ +#define SCM_STATUS_RSS_FAIL 0x00000400 +/** SCM Status bit: Secure Storage is Secure */ +#define SCM_STATUS_RSS_SEC 0x00000200 +/** SCM Status bit: Secure Storage is Initializing */ +#define SCM_STATUS_RSS_INIT 0x00000100 +/** SCM Status bit: Unique Number Valid */ +#define SCM_STATUS_UNV 0x00000080 +/** SCM Status bit: Big Endian mode */ +#define SCM_STATUS_BIG 0x00000040 +/** SCM Status bit: Using Secret Key */ +#define SCM_STATUS_USK 0x00000020 +/** SCM Status bit: Ram is being blocked */ +#define SCM_STATUS_BAR 0x00000010 +/** Bit mask of SRS */ +#define SCM_STATUS_SRS_MASK 0x0000000F +/** Number of bits to shift SRS to/from MSb */ +#define SCM_STATUS_SRS_SHIFT 0 +/** @} */ + +#define SCM_STATUS_SRS_RESET 0x0 /**< Reset, Zeroise All */ +#define SCM_STATUS_SRS_READY 0x1 /**< All Ready */ +#define SCM_STATUS_SRS_ZBUSY 0x2 /**< Zeroize Busy (Partition Only) */ +#define SCM_STATUS_SRS_CBUSY 0x3 /**< Cipher Busy */ +#define SCM_STATUS_SRS_ABUSY 0x4 /**< All Busy */ +#define SCM_STATUS_SRS_ZDONE 0x5 /**< Zeroize Done, Cipher Ready */ +#define SCM_STATUS_SRS_CDONE 0x6 /**< Cipher Done, Zeroize Ready */ +#define SCM_STATUS_SRS_ZDONE2 0x7 /**< Zeroize Done, Cipher Busy */ +#define SCM_STATUS_SRS_CDONE2 0x8 /**< Cipher Done, Zeroize Busy */ +#define SCM_STATUS_SRS_ADONE 0xD /**< All Done */ + +/* Format of the SCM VERSION ID REGISTER */ +#define SCM_VER_BPP_MASK 0xFF000000 /**< Bytes Per Partition Mask */ +#define SCM_VER_BPP_SHIFT 24 /**< Bytes Per Partition Shift */ +#define SCM_VER_BPCB_MASK 0x001F0000 /**< Bytes Per Cipher Block Mask */ +#define SCM_VER_BPCB_SHIFT 16 /**< Bytes Per Cipher Block Shift */ +#define SCM_VER_NP_MASK 0x0000F000 /**< Number of Partitions Mask */ +#define SCM_VER_NP_SHIFT 12 /**< Number of Partitions Shift */ +#define SCM_VER_MAJ_MASK 0x00000F00 /**< Major Version Mask */ +#define SCM_VER_MAJ_SHIFT 8 /**< Major Version Shift */ +#define SCM_VER_MIN_MASK 0x000000FF /**< Minor Version Mask */ +#define SCM_VER_MIN_SHIFT 0 /**< Minor Version Shift */ + +/**< SCC Hardware version supported by this driver */ +#define SCM_MAJOR_VERSION_2 2 + +/* Format of the SCM ERROR STATUS REGISTER */ +#define SCM_ERRSTAT_MID_MASK 0x00F00000 /**< Master ID Mask */ +#define SCM_ERRSTAT_MID_SHIFT 20 /**< Master ID Shift */ +#define SCM_ERRSTAT_ILM 0x00080000 /**< Illegal Master */ +#define SCM_ERRSTAT_SUP 0x00008000 /**< Supervisor Access */ +#define SCM_ERRSTAT_ERC_MASK 0x00000F00 /**< Error Code Mask */ +#define SCM_ERRSTAT_ERC_SHIFT 8 /**< Error Code Shift */ +#define SCM_ERRSTAT_SMS_MASK 0x000000F0 /**< Secure Monitor State Mask */ +#define SCM_ERRSTAT_SMS_SHIFT 4 /**< Secure Monitor State Shift */ +#define SCM_ERRSTAT_SRS_MASK 0x0000000F /**< Secure Ram State Mask */ +#define SCM_ERRSTAT_SRS_SHIFT 0 /**< Secure Ram State Shift */ + +/* SCM ERROR STATUS REGISTER ERROR CODES */ +#define SCM_ERCD_UNK_ADDR 0x1 /**< Unknown Address */ +#define SCM_ERCD_UNK_CMD 0x2 /**< Unknown Command */ +#define SCM_ERCD_READ_PERM 0x3 /**< Read Permission Error */ +#define SCM_ERCD_WRITE_PERM 0x4 /**< Write Permission Error */ +#define SCM_ERCD_DMA_ERROR 0x5 /**< DMA Error */ +#define SCM_ERCD_BLK_OVFL 0x6 /**< Encryption Block Length Overflow */ +#define SCM_ERCD_NO_KEY 0x7 /**< Key Not Engaged */ +#define SCM_ERCD_ZRZ_OVFL 0x8 /**< Zeroize Command Queue Overflow */ +#define SCM_ERCD_CPHR_OVFL 0x9 /**< Cipher Command Queue Overflow */ +#define SCM_ERCD_PROC_INTR 0xA /**< Process Interrupted */ +#define SCM_ERCD_WRNG_KEY 0xB /**< Wrong Key */ +#define SCM_ERCD_DEVICE_BUSY 0xC /**< Device Busy */ +#define SCM_ERCD_UNALGN_ADDR 0xD /**< DMA Unaligned Address */ + +/* Format of the CIPHER COMMAND REGISTER */ +#define SCM_CCMD_LENGTH_MASK 0xFFF00000 /**< Cipher Length Mask */ +#define SCM_CCMD_LENGTH_SHIFT 20 /**< Cipher Length Shift */ +#define SCM_CCMD_OFFSET_MASK 0x000FFF00 /**< Block Offset Mask */ +#define SCM_CCMD_OFFSET_SHIFT 8 /**< Block Offset Shift */ +#define SCM_CCMD_PART_MASK 0x000000F0 /**< Partition Number Mask */ +#define SCM_CCMD_PART_SHIFT 4 /**< Partition Number Shift */ +#define SCM_CCMD_CCMD_MASK 0x0000000F /**< Cipher Command Mask */ +#define SCM_CCMD_CCMD_SHIFT 0 /**< Cipher Command Shift */ + +/* Values for SCM_CCMD_CCMD field */ +#define SCM_CCMD_AES_DEC_ECB 1 /**< Decrypt without Chaining (ECB) */ +#define SCM_CCMD_AES_ENC_ECB 3 /**< Encrypt without Chaining (ECB) */ +#define SCM_CCMD_AES_DEC_CBC 5 /**< Decrypt with Chaining (CBC) */ +#define SCM_CCMD_AES_ENC_CBC 7 /**< Encrypt with Chaining (CBC) */ + +#define SCM_CCMD_AES 1 /**< Use AES Mode */ +#define SCM_CCMD_DEC 0 /**< Decrypt */ +#define SCM_CCMD_ENC 2 /**< Encrypt */ +#define SCM_CCMD_ECB 0 /**< Perform operation without chaining (ECB) */ +#define SCM_CCMD_CBC 4 /**< Perform operation with chaining (CBC) */ + +/* Format of the ZEROIZE COMMAND REGISTER */ +#define SCM_ZCMD_PART_MASK 0x000000F0 /**< Target Partition Mask */ +#define SCM_ZCMD_PART_SHIFT 4 /**< Target Partition Shift */ +#define SCM_ZCMD_CCMD_MASK 0x0000000F /**< Zeroize Command Mask */ +#define SCM_ZCMD_CCMD_SHIFT 0 /**< Zeroize Command Shift */ + +/* MASTER ACCESS PERMISSIONS REGISTER */ +/* Note that API users should use the FSL_PERM_ defines instead of these */ +/** SCM Access Permission: Do not zeroize/deallocate partition + on SMN Fail state */ +#define SCM_PERM_NO_ZEROIZE 0x10000000 +/** SCM Access Permission: Ignore Supervisor/User mode + in permission determination */ +#define SCM_PERM_HD_SUP_DISABLE 0x00000800 +/** SCM Access Permission: Allow Read Access to Host Domain */ +#define SCM_PERM_HD_READ 0x00000400 +/** SCM Access Permission: Allow Write Access to Host Domain */ +#define SCM_PERM_HD_WRITE 0x00000200 +/** SCM Access Permission: Allow Execute Access to Host Domain */ +#define SCM_PERM_HD_EXECUTE 0x00000100 +/** SCM Access Permission: Allow Read Access to Trusted Host Domain */ +#define SCM_PERM_TH_READ 0x00000040 +/** SCM Access Permission: Allow Write Access to Trusted Host Domain */ +#define SCM_PERM_TH_WRITE 0x00000020 +/** SCM Access Permission: Allow Read Access to Other/World Domain */ +#define SCM_PERM_OT_READ 0x00000004 +/** SCM Access Permission: Allow Write Access to Other/World Domain */ +#define SCM_PERM_OT_WRITE 0x00000002 +/** SCM Access Permission: Allow Execute Access to Other/World Domain */ +#define SCM_PERM_OT_EXECUTE 0x00000001 +/**< Valid bits that can be set in the Permissions register */ +#define SCM_PERM_MASK 0xC0000F67 + +/* Zeroize Command register definitions */ +#define ZCMD_DEALLOC_PART 3 /**< Deallocate Partition */ +#define Z_INT_EN 0x00000002 /**< Zero Interrupt Enable */ + +/** + * @defgroup scmpartitionownersregdefs SCM Partition Owners Register + */ +/** @addtogroup scmpartitionownersregdefs */ +/** @{ */ +/** Number of bits to shift partition number to get to its field. */ +#define SCM_POWN_SHIFT 2 +/** Mask for a field once the register has been shifted. */ +#define SCM_POWN_MASK 3 +/** Partition is free */ +#define SCM_POWN_PART_FREE 0 +/** Partition is unable to be allocated */ +#define SCM_POWN_PART_UNUSABLE 1 +/** Partition is owned by another master */ +#define SCM_POWN_PART_OTHER 2 +/** Partition is owned by this master */ +#define SCM_POWN_PART_OWNED 3 +/** @} */ + +/** + * @defgroup smnpartitionsengagedregdefs SCM Partitions Engaged Register + */ +/** @addtogroup smnpartitionsengagedregdefs */ +/** @{ */ +/** Number of bits to shift partition number to get to its field. */ +#define SCM_PENG_SHIFT 1 +/** Engaged value for a field once the register has been shifted. */ +#define SCM_PENG_ENGAGED 1 +/** @} */ + +/** Number of bytes between each subsequent SMID register */ +#define SCM_SMID_WIDTH 8 + +/** + * @defgroup smncommandregdefs SMN Command Register Definitions (SMN_COMMAND_REG) + */ +/** @addtogroup smncommandregdefs */ +/** @{ */ + +/** These bits are unimplemented or reserved */ +#define SMN_COMMAND_ZEROS_MASK 0xfffffff0 +#define SMN_COMMAND_CLEAR_INTERRUPT 0x8 /**< Clear SMN Interrupt */ +#define SMN_COMMAND_CLEAR_BIT_BANK 0x4 /**< Clear SMN Bit Bank */ +#define SMN_COMMAND_ENABLE_INTERRUPT 0x2 /**< Enable SMN Interrupts */ +#define SMN_COMMAND_SET_SOFTWARE_ALARM 0x1 /**< Set Software Alarm */ +/** @} */ + +/** + * @defgroup smntimercontroldefs SMN Timer Control Register definitions (SMN_TIMER_CONTROL) + */ +/** @addtogroup smntimercontroldefs */ +/** @{ */ +/** These bits are reserved or zero */ +#define SMN_TIMER_CTRL_ZEROS_MASK 0xfffffffc +/** Load the timer from #SMN_TIMER_IV_REG */ +#define SMN_TIMER_LOAD_TIMER 0x2 +/** Setting to zero stops the Timer */ +#define SMN_TIMER_STOP_MASK 0x1 +/** Setting this value starts the timer */ +#define SMN_TIMER_START_TIMER 0x1 +/** @} */ + +/** + * @defgroup scmchainmodedefs SCM_CHAINING_MODE_MASK - Bit definitions + */ +/** @addtogroup scmchainmodedefs */ +/** @{ */ +#define SCM_CBC_MODE 0x2 /**< Cipher block chaining */ +#define SCM_ECB_MODE 0x0 /**< Electronic codebook. */ +/** @} */ + +/* Bit definitions in the SCM_CIPHER_MODE_MASK */ +/** + * @defgroup scmciphermodedefs SCM_CIPHER_MODE_MASK - Bit definitions + */ +/** @addtogroup scmciphermodedefs */ +/** @{ */ +#define SCM_DECRYPT_MODE 0x1 /**< decrypt from black to red memory */ +#define SCM_ENCRYPT_MODE 0x0 /**< encrypt from red to black memory */ +/** @} */ + +/** + * @defgroup smndbgdetdefs SMN Debug Detector Status Register (SCM_DEBUG_DETECT_STAT) + */ +/** @addtogroup smndbgdetdefs */ +/** @{ */ +#define SMN_DBG_ZEROS_MASK 0xfffff000 /**< These bits are zero or reserved */ +#define SMN_DBG_D12 0x0800 /**< Error detected on Debug Port D12 */ +#define SMN_DBG_D11 0x0400 /**< Error detected on Debug Port D11 */ +#define SMN_DBG_D10 0x0200 /**< Error detected on Debug Port D10 */ +#define SMN_DBG_D9 0x0100 /**< Error detected on Debug Port D9 */ +#define SMN_DBG_D8 0x0080 /**< Error detected on Debug Port D8 */ +#define SMN_DBG_D7 0x0040 /**< Error detected on Debug Port D7 */ +#define SMN_DBG_D6 0x0020 /**< Error detected on Debug Port D6 */ +#define SMN_DBG_D5 0x0010 /**< Error detected on Debug Port D5 */ +#define SMN_DBG_D4 0x0008 /**< Error detected on Debug Port D4 */ +#define SMN_DBG_D3 0x0004 /**< Error detected on Debug Port D3 */ +#define SMN_DBG_D2 0x0002 /**< Error detected on Debug Port D2 */ +#define SMN_DBG_D1 0x0001 /**< Error detected on Debug Port D1 */ +/** @} */ + +/** Mask for the usable bits of the Sequence Start Register + (#SMN_SEQ_START_REG) */ +#define SMN_SEQUENCE_START_MASK 0x0000ffff + +/** Mask for the usable bits of the Sequence End Register + (#SMN_SEQ_END_REG) */ +#define SMN_SEQUENCE_END_MASK 0x0000ffff + +/** Mask for the usable bits of the Sequence Check Register + (#SMN_SEQ_CHECK_REG) */ +#define SMN_SEQUENCE_CHECK_MASK 0x0000ffff + +/** Mask for the usable bits of the Bit Counter Register + (#SMN_BB_CNT_REG) */ +#define SMN_BIT_COUNT_MASK 0x000007ff + +/** Mask for the usable bits of the Bit Bank Increment Size Register + (#SMN_BB_INC_REG) */ +#define SMN_BITBANK_INC_SIZE_MASK 0x000007ff + +/** Mask for the usable bits of the Bit Bank Decrement Register + (#SMN_BB_DEC_REG) */ +#define SMN_BITBANK_DECREMENT_MASK 0x000007ff + +/** Mask for the usable bits of the Compare Size Register + (#SMN_COMPARE_REG) */ +#define SMN_COMPARE_SIZE_MASK 0x0000003f + +/*! @} */ + +#endif /* SCC_DRIVER_H */ --- linux-2.6.28.orig/include/linux/mm.h +++ linux-2.6.28/include/linux/mm.h @@ -253,7 +253,6 @@ */ static inline int get_page_unless_zero(struct page *page) { - VM_BUG_ON(PageTail(page)); return atomic_inc_not_zero(&page->_count); } @@ -1028,10 +1027,23 @@ typedef int (*work_fn_t)(unsigned long, unsigned long, void *); extern void work_with_active_regions(int nid, work_fn_t work_fn, void *data); extern void sparse_memory_present_with_active_regions(int nid); -#ifndef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID -extern int early_pfn_to_nid(unsigned long pfn); -#endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */ #endif /* CONFIG_ARCH_POPULATES_NODE_MAP */ + +#if !defined(CONFIG_ARCH_POPULATES_NODE_MAP) && \ + !defined(CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID) +static inline int __early_pfn_to_nid(unsigned long pfn) +{ + return 0; +} +#else +/* please see mm/page_alloc.c */ +extern int __meminit early_pfn_to_nid(unsigned long pfn); +#ifdef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID +/* there is a per-arch backend function. */ +extern int __meminit __early_pfn_to_nid(unsigned long pfn); +#endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */ +#endif + extern void set_dma_reserve(unsigned long new_dma_reserve); extern void memmap_init_zone(unsigned long, int, unsigned long, unsigned long, enum memmap_context); --- linux-2.6.28.orig/include/linux/fs.h +++ linux-2.6.28/include/linux/fs.h @@ -63,24 +63,30 @@ #define MAY_ACCESS 16 #define MAY_OPEN 32 +/* + * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond + * to O_WRONLY and O_RDWR via the strange trick in __dentry_open() + */ + /* file is open for reading */ #define FMODE_READ ((__force fmode_t)1) /* file is open for writing */ #define FMODE_WRITE ((__force fmode_t)2) /* file is seekable */ #define FMODE_LSEEK ((__force fmode_t)4) -/* file can be accessed using pread/pwrite */ +/* file can be accessed using pread */ #define FMODE_PREAD ((__force fmode_t)8) -#define FMODE_PWRITE FMODE_PREAD /* These go hand in hand */ +/* file can be accessed using pwrite */ +#define FMODE_PWRITE ((__force fmode_t)16) /* File is opened for execution with sys_execve / sys_uselib */ -#define FMODE_EXEC ((__force fmode_t)16) +#define FMODE_EXEC ((__force fmode_t)32) /* File is opened with O_NDELAY (only set for block devices) */ -#define FMODE_NDELAY ((__force fmode_t)32) +#define FMODE_NDELAY ((__force fmode_t)64) /* File is opened with O_EXCL (only set for block devices) */ -#define FMODE_EXCL ((__force fmode_t)64) +#define FMODE_EXCL ((__force fmode_t)128) /* File is opened using open(.., 3, ..) and is writeable only for ioctls (specialy hack for floppy.c) */ -#define FMODE_WRITE_IOCTL ((__force fmode_t)128) +#define FMODE_WRITE_IOCTL ((__force fmode_t)256) #define RW_MASK 1 #define RWA_MASK 2 @@ -372,6 +378,10 @@ * Not an attribute, but an auxilary info for filesystems wanting to * implement an ftruncate() like method. NOTE: filesystem should * check for (ia_valid & ATTR_FILE), and not for (ia_file != NULL). + * + * NOTE: With patches.apparmor/fsetattr.diff applied, this is + * for compatibility with external file system modules only. There + * should not be any in-kernel users left. */ struct file *ia_file; }; @@ -414,6 +424,9 @@ #define AOP_FLAG_UNINTERRUPTIBLE 0x0001 /* will not do a short write */ #define AOP_FLAG_CONT_EXPAND 0x0002 /* called from cont_expand */ +#define AOP_FLAG_NOFS 0x0004 /* used by filesystem to direct + * helper code (eg buffer layer) + * to clear GFP_FS from alloc */ /* * oh the beauties of C type declarations. @@ -1121,7 +1134,6 @@ struct rw_semaphore s_umount; struct mutex s_lock; int s_count; - int s_syncing; int s_need_sync_fs; atomic_t s_active; #ifdef CONFIG_SECURITY @@ -1205,13 +1217,13 @@ */ extern int vfs_permission(struct nameidata *, int); extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *); -extern int vfs_mkdir(struct inode *, struct dentry *, int); -extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t); -extern int vfs_symlink(struct inode *, struct dentry *, const char *); -extern int vfs_link(struct dentry *, struct inode *, struct dentry *); -extern int vfs_rmdir(struct inode *, struct dentry *); -extern int vfs_unlink(struct inode *, struct dentry *); -extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); +extern int vfs_mkdir(struct inode *, struct dentry *, struct vfsmount *, int); +extern int vfs_mknod(struct inode *, struct dentry *, struct vfsmount *, int, dev_t); +extern int vfs_symlink(struct inode *, struct dentry *, struct vfsmount *, const char *); +extern int vfs_link(struct dentry *, struct vfsmount *, struct inode *, struct dentry *, struct vfsmount *); +extern int vfs_rmdir(struct inode *, struct dentry *, struct vfsmount *); +extern int vfs_unlink(struct inode *, struct dentry *, struct vfsmount *); +extern int vfs_rename(struct inode *, struct dentry *, struct vfsmount *, struct inode *, struct dentry *, struct vfsmount *); /* * VFS dentry helper functions. @@ -1224,6 +1236,11 @@ extern int file_permission(struct file *, int); /* + * VFS path helper functions. + */ +extern int path_permission(struct path *, int); + +/* * VFS FS_IOC_FIEMAP helper definitions. */ struct fiemap_extent_info { @@ -1306,6 +1323,7 @@ ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); int (*setlease)(struct file *, long, struct file_lock **); + int (*fsetattr)(struct file *, struct iattr *); }; struct inode_operations { @@ -1669,8 +1687,8 @@ /* fs/open.c */ -extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs, - struct file *filp); +extern int do_truncate(struct dentry *, struct vfsmount *, loff_t start, + unsigned int time_attrs, struct file *filp); extern long do_sys_open(int dfd, const char __user *filename, int flags, int mode); extern struct file *filp_open(const char *, int, int); @@ -1830,7 +1848,8 @@ #ifdef CONFIG_BLOCK extern sector_t bmap(struct inode *, sector_t); #endif -extern int notify_change(struct dentry *, struct iattr *); +extern int notify_change(struct dentry *, struct vfsmount *, struct iattr *); +extern int fnotify_change(struct dentry *, struct vfsmount *, struct iattr *, struct file *); extern int inode_permission(struct inode *, int); extern int generic_permission(struct inode *, int, int (*check_acl)(struct inode *, int)); @@ -2023,7 +2042,7 @@ extern void *page_follow_link_light(struct dentry *, struct nameidata *); extern void page_put_link(struct dentry *, struct nameidata *, void *); extern int __page_symlink(struct inode *inode, const char *symname, int len, - gfp_t gfp_mask); + int nofs); extern int page_symlink(struct inode *inode, const char *symname, int len); extern const struct inode_operations page_symlink_inode_operations; extern int generic_readlink(struct dentry *, char __user *, int); --- linux-2.6.28.orig/include/linux/mod_devicetable.h +++ linux-2.6.28/include/linux/mod_devicetable.h @@ -443,6 +443,13 @@ struct dmi_strmatch matches[4]; void *driver_data; }; +/* + * struct dmi_device_id appears during expansion of + * "MODULE_DEVICE_TABLE(dmi, x)". Compiler doesn't look inside it + * but this is enough for gcc 3.4.6 to error out: + * error: storage size of '__mod_dmi_device_table' isn't known + */ +#define dmi_device_id dmi_system_id #endif #define DMI_MATCH(a, b) { a, b } --- linux-2.6.28.orig/include/linux/pmic_light.h +++ linux-2.6.28/include/linux/pmic_light.h @@ -0,0 +1,1082 @@ +/* + * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU Lesser General + * Public License. You may obtain a copy of the GNU Lesser General + * Public License Version 2.1 or later at the following locations: + * + * http://www.opensource.org/licenses/lgpl-license.html + * http://www.gnu.org/copyleft/lgpl.html + */ +#ifndef __ASM_ARCH_MXC_PMIC_LIGHT_H__ +#define __ASM_ARCH_MXC_PMIC_LIGHT_H__ + +/*! + * @defgroup PMIC_LIGHT PMIC Light Driver + * @ingroup PMIC_DRVRS + */ + +/*! + * @file arch-mxc/pmic_light.h + * @brief This is the header of PMIC Light driver. + * + * @ingroup PMIC_LIGHT + */ + +#include +#include +#include + +/*! + * @name IOCTL user space interface + */ + +/*! @{ */ +/*! + * Enable Backlight. + * Argument type: none. + */ +#define PMIC_BKLIT_ENABLE _IO('p', 0xe0) +/*! + * Disable Backlight. + * Argument type: none. + */ +#define PMIC_BKLIT_DISABLE _IO('p', 0xe1) +/*! + * Set backlight configuration. + * Argument type: pointer to t_bklit_setting_param + */ +#define PMIC_SET_BKLIT _IOW('p', 0xe2, int) +/*! + * Get backlight configuration. + * Argument type: pointer to t_bklit_setting_param + */ +#define PMIC_GET_BKLIT _IOWR('p', 0xe3, int) +/*! + * Ramp up configuration. + * Argument type: t_bklit_channel + */ +#define PMIC_RAMPUP_BKLIT _IOW('p', 0xe4, int) +/*! + * Ramp down configuration. + * Argument type: t_bklit_channel + */ +#define PMIC_RAMPDOWN_BKLIT _IOW('p', 0xe5, int) +/*! + * Enable Tri-color LED. + * Argument type: t_tcled_enable_param + */ +#define PMIC_TCLED_ENABLE _IOW('p', 0xe6, int) +/*! + * Disable Tri-color LED. + * Argument type: t_funlight_bank + */ +#define PMIC_TCLED_DISABLE _IOW('p', 0xe7, int) +/*! + * Start Tri-color LED pattern. + * Argument type: t_fun_param + */ +#define PMIC_TCLED_PATTERN _IOW('p', 0xe8, int) +/*! + * Enable Backlight & tcled. + * Argument type: none. + */ +#define PMIC_BKLIT_TCLED_ENABLE _IO('p', 0xe9) +/*! + * Disable Backlight & tcled. + * Argument type: none. + */ +#define PMIC_BKLIT_TCLED_DISABLE _IO('p', 0xea) +/*! + * Reset ramp up configuration. + * Argument type: t_bklit_channel + */ +#define PMIC_OFF_RAMPUP_BKLIT _IOW('p', 0xeb, int) +/*! + * Reset ramp down configuration. + * Argument type: t_bklit_channel + */ +#define PMIC_OFF_RAMPDOWN_BKLIT _IOW('p', 0xec, int) +/*! + * Set tcled ind configuration. + * Argument type: t_tcled_ind_param + */ +#define PMIC_SET_TCLED _IOW('p', 0xed, int) +/*! + * Get tcled ind configuration. + * Argument type: t_tcled_ind_param + */ +#define PMIC_GET_TCLED _IOWR('p', 0xee, int) +/*! @} */ +/*! + * @enum t_bklit_mode + * @brief Backlight modes. + */ +typedef enum { + BACKLIGHT_CURRENT_CTRL_MODE, /*! < Current control mode */ + BACKLIGHT_TRIODE_MODE /*! < Triode mode */ +} t_bklit_mode; + +/*! + * @enum t_bklit_channel + * @brief Backlight channels. + */ +typedef enum { + BACKLIGHT_LED1, /*! < Backlight channel 1 */ + BACKLIGHT_LED2, /*! < Backlight channel 2 */ + BACKLIGHT_LED3 /*! < Backlight channel 3 */ +} t_bklit_channel; + +/*! + * @enum t_bklit_strobe_mode + * @brief Backlight Strobe Light Pulsing modes. + */ +typedef enum { + /*! + * No Strobe Light Pulsing + */ + BACKLIGHT_STROBE_NONE, + /*! + * Strobe Light Pulsing at 3.3% duty cycle over 300msec (Driver goes + * into Triode Mode with pulses constrained to 10msec.) + */ + BACKLIGHT_STROBE_FAST, + /*! + * Strobe Light Pulsing at 10% duty cycle over 100msec (Driver goes + * into Triode Mode with pulses constrained to 10msec.) + */ + BACKLIGHT_STROBE_SLOW +} t_bklit_strobe_mode; + +/*! + * @struct t_bklit_setting_param + * @brief Backlight setting. + */ + +typedef struct { + t_bklit_channel channel; /*!< Channel */ + t_bklit_mode mode; /*!< Mode */ + t_bklit_strobe_mode strobe; /*!< Strobe mode */ + unsigned char current_level; /*!< Current level */ + unsigned char duty_cycle; /*!< Duty cycle */ + unsigned char cycle_time; /*!< Cycle time */ + bool edge_slow; /*!< Edge Slow */ + bool en_dis; /*!< Enable disable boost mode */ + unsigned int abms; /*!< Adaptive boost + * mode selection */ + unsigned int abr; /*!< Adaptive + * boost reference */ +} t_bklit_setting_param; + +/*! + * @enum t_funlight_bank + * @brief Tri-color LED fun light banks. + */ +typedef enum { + TCLED_FUN_BANK1 = 0, /*! < Fun light bank 1 */ + TCLED_FUN_BANK2, /*! < Fun light bank 2 */ + TCLED_FUN_BANK3 /*! < Fun light bank 3 */ +} t_funlight_bank; + +/*! + * @enum t_tcled_mode + * @brief Tri-color LED operation modes. + * + * The Tri-Color LED Driver circuitry includes 2 modes of operation. In LED + * Indicator Mode, this circuitry operates as Red and Green LED Drivers with + * flasher timing to indicate GSM network status. In Fun Light Mode, this + * circuitry provides expanded capability for current control and distribution + * that supplements the three channels. + */ +typedef enum { + TCLED_IND_MODE = 0, /*! < LED Indicator Mode */ + TCLED_FUN_MODE /*! < Fun Light Mode */ +} t_tcled_mode; + +/*! + * @struct t_tcled_enable_param + * @brief enable setting. + */ +typedef struct { + t_funlight_bank bank; /*!< Bank */ + t_tcled_mode mode; /*!< Mode */ +} t_tcled_enable_param; + +/*! + * @enum t_ind_channel + * @brief Tri-color LED indicator mode channels. + * + */ + +typedef enum { + TCLED_IND_RED = 0, /*! < Red LED */ + TCLED_IND_GREEN, /*! < Green LED */ + TCLED_IND_BLUE /*! < Blue LED */ +} t_ind_channel; + +/*! + * @enum t_funlight_channel + * @brief Tri-color LED fun light mode channels. + * + */ +typedef enum { + TCLED_FUN_CHANNEL1 = 0, /*! < Fun light channel 1 (Red) */ + TCLED_FUN_CHANNEL2, /*! < Fun light channel 2 (Green) */ + TCLED_FUN_CHANNEL3 /*! < Fun light channel 3 (Blue) */ +} t_funlight_channel; + +/*! + * @enum t_tcled_ind_blink_pattern + * @brief Tri-color LED Indicator Mode blinking mode. + */ +typedef enum { + TCLED_IND_OFF = 0, /*! < Continuous off */ + TCLED_IND_BLINK_1, /*! < 1 / 31 */ + TCLED_IND_BLINK_2, /*! < 2 / 31 */ + TCLED_IND_BLINK_3, /*! < 3 / 31 */ + TCLED_IND_BLINK_4, /*! < 4 / 31 */ + TCLED_IND_BLINK_5, /*! < 5 / 31 */ + TCLED_IND_BLINK_6, /*! < 6 / 31 */ + TCLED_IND_BLINK_7, /*! < 7 / 31 */ + TCLED_IND_BLINK_8, /*! < 8 / 31 */ + TCLED_IND_BLINK_9, /*! < 9 / 31 */ + TCLED_IND_BLINK_10, /*! < 10 / 31 */ + TCLED_IND_BLINK_11, /*! < 11 / 31 */ + TCLED_IND_BLINK_12, /*! < 12 / 31 */ + TCLED_IND_BLINK_13, /*! < 13 / 31 */ + TCLED_IND_BLINK_14, /*! < 14 / 31 */ + TCLED_IND_BLINK_15, /*! < 15 / 31 */ + TCLED_IND_BLINK_16, /*! < 16 / 31 */ + TCLED_IND_BLINK_17, /*! < 17 / 31 */ + TCLED_IND_BLINK_18, /*! < 18 / 31 */ + TCLED_IND_BLINK_19, /*! < 19 / 31 */ + TCLED_IND_BLINK_20, /*! < 20 / 31 */ + TCLED_IND_BLINK_21, /*! < 21 / 31 */ + TCLED_IND_BLINK_22, /*! < 22 / 31 */ + TCLED_IND_BLINK_23, /*! < 23 / 31 */ + TCLED_IND_BLINK_24, /*! < 24 / 31 */ + TCLED_IND_BLINK_25, /*! < 25 / 31 */ + TCLED_IND_BLINK_26, /*! < 26 / 31 */ + TCLED_IND_BLINK_27, /*! < 27 / 31 */ + TCLED_IND_BLINK_28, /*! < 28 / 31 */ + TCLED_IND_BLINK_29, /*! < 29 / 31 */ + TCLED_IND_BLINK_30, /*! < 30 / 31 */ + TCLED_IND_ON /*! < Continuous on */ +} t_tcled_ind_blink_pattern; + +/*! + * @enum t_tcled_cur_level + * @brief Tri-color LED current levels. + */ +typedef enum { + TCLED_CUR_LEVEL_1 = 0, /*! < Tri-Color LED current level 1 */ + TCLED_CUR_LEVEL_2, /*! < Tri-Color LED current level 2 */ + TCLED_CUR_LEVEL_3, /*! < Tri-Color LED current level 3 */ + TCLED_CUR_LEVEL_4 /*! < Tri-Color LED current level 4 */ +} t_tcled_cur_level; + +/*! + * @enum t_tcled_fun_cycle_time + * @brief Tri-color LED fun light mode cycle time. + */ +typedef enum { + TC_CYCLE_TIME_1 = 0, /*! < Tri-Color LED cycle time 1 */ + TC_CYCLE_TIME_2, /*! < Tri-Color LED cycle time 2 */ + TC_CYCLE_TIME_3, /*! < Tri-Color LED cycle time 3 */ + TC_CYCLE_TIME_4 /*! < Tri-Color LED cycle time 4 */ +} t_tcled_fun_cycle_time; + +/*! + * @enum t_tcled_fun_speed + * @brief Tri-color LED fun light mode pattern speed. + */ +typedef enum { + TC_OFF = 0, /*! < Tri-Color pattern off */ + TC_SLOW, /*! < Tri-Color slow pattern */ + TC_FAST /*! < Tri-Color fast pattern */ +} t_tcled_fun_speed; + +/*! + * @enum t_tcled_fun_speed + * @brief Tri-color LED fun light mode pattern speed. + */ +typedef enum { + TC_STROBE_OFF = 0, /*! < No strobe */ + TC_STROBE_SLOW, /*! < Slow strobe pattern */ + TC_STROBE_FAST /*! < fast strobe pattern */ +} t_tcled_fun_strobe_speed; + +/*! + * @enum t_chaselight_pattern + * @brief Tri-color LED fun light mode chasing light patterns. + */ +typedef enum { + PMIC_RGB = 0, /*!< R -> G -> B */ + BGR /*!< B -> G -> R */ +} t_chaselight_pattern; + +/*! + * This enumeration of Fun Light Pattern. + */ +typedef enum { + /*! + * Blended ramps slow + */ + BLENDED_RAMPS_SLOW, + /*! + * Blended ramps fast + */ + BLENDED_RAMPS_FAST, + /*! + * Saw ramps slow + */ + SAW_RAMPS_SLOW, + /*! + * Saw ramps fast + */ + SAW_RAMPS_FAST, + /*! + * Blended bowtie slow + */ + BLENDED_BOWTIE_SLOW, + /*! + * Blended bowtie fast + */ + BLENDED_BOWTIE_FAST, + /*! + * Strobe slow + */ + STROBE_SLOW, + /*! + * Strobe fast + */ + STROBE_FAST, + /*! + * Chasing Light RGB Slow + */ + CHASING_LIGHT_RGB_SLOW, + /*! + * Chasing Light RGB fast + */ + CHASING_LIGHT_RGB_FAST, + /*! + * Chasing Light BGR Slow + */ + CHASING_LIGHT_BGR_SLOW, + /*! + * Chasing Light BGR fast + */ + CHASING_LIGHT_BGR_FAST, +} t_fun_pattern; + +/*! + * @struct t_fun_param + * @brief LED fun pattern IOCTL parameter + */ +typedef struct { + t_funlight_bank bank; /*!< TCLED bank */ + t_funlight_channel channel; /*!< TCLED channel */ + t_fun_pattern pattern; /*!< Fun pattern */ +} t_fun_param; + +/*! + * @enum t_led_channel + * @brief LED channels including backlight and tri-color LEDs. + */ +typedef enum { + AUDIO_LED1, /*! < Backlight channel 1 */ + AUDIO_LED2, /*! < Backlight channel 2 */ + AUDIO_LEDR, /*! < Fun light channel 1 (Red) */ + AUDIO_LEDG, /*! < Fun light channel 2 (Green) */ + AUDIO_LEDB /*! < Fun light channel 3 (Blue) */ +} t_led_channel; + +/*! + * @enum t_aud_path + * @brief LED audio modulation in-out audio channels + */ +typedef enum { + MIXED_RX = 0, /*!< Mixed L & R Channel RX audio */ + TX /*!< TX path */ +} t_aud_path; + +/*! + * @enum t_aud_gain + * @brief LED audio modulation in-out audio channels + */ +typedef enum { + GAIN_MINUS6DB = 0, /*!< -6 dB */ + GAIN_0DB, /*!< 0 dB */ + GAIN_6DB, /*!< 6 dB */ + GAIN_12DB /*!< 12 dB */ +} t_aud_gain; + +/*! + * @struct t_tcled_ind_param + * @brief LED parameter + */ +typedef struct { + t_funlight_bank bank; /*! < tcled bank */ + t_ind_channel channel; /*! < tcled channel */ + t_tcled_cur_level level; /*! < tcled current level */ + t_tcled_ind_blink_pattern pattern; /*! < tcled dutty cycle */ + bool skip; /*! < tcled skip */ + bool rampup; /*! < tcled rampup */ + bool rampdown; /*! < tcled rampdown */ + bool half_current; /*! < tcled half current */ +} t_tcled_ind_param; + +#if defined(CONFIG_MXC_PMIC_MC13892) + +enum curr_level { + LIT_CURR_0 = 0, + LIT_CURR_3, + LIT_CURR_6, + LIT_CURR_9, + LIT_CURR_12, + LIT_CURR_15, + LIT_CURR_18, + LIT_CURR_21, + /* below setting only used for main/aux/keypad */ + LIT_CURR_HI_0, + LIT_CURR_HI_6, + LIT_CURR_HI_12, + LIT_CURR_HI_18, + LIT_CURR_HI_24, + LIT_CURR_HI_30, + LIT_CURR_HI_36, + LIT_CURR_HI_42, +}; + +enum lit_channel { + LIT_MAIN = 0, + LIT_AUX, + LIT_KEY, + LIT_RED, + LIT_GREEN, + LIT_BLUE, +}; + +#endif + +/* EXPORTED FUNCTIONS */ +#ifdef __KERNEL__ +/*! + * This function enables backlight & tcled. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_bklit_tcled_master_enable(void); + +/*! + * This function disables backlight & tcled. + * + * @return This function returns PMIC_SUCCESS if successful + */ +PMIC_STATUS pmic_bklit_tcled_master_disable(void); + +/*! + * This function enables backlight. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_bklit_master_enable(void); + +/*! + * This function disables backlight. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_bklit_master_disable(void); + +/*! + * This function sets backlight current level. + * + * @param channel Backlight channel + * @param level Backlight current level, as the following table. + * @verbatim + level current + ------ ----------- + 0 0 mA + 1 12 mA + 2 24 mA + 3 36 mA + 4 48 mA + 5 60 mA + 6 72 mA + 7 84 mA + @endverbatim + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_bklit_set_current(t_bklit_channel channel, + unsigned char level); + +/*! + * This function retrives backlight current level. + * + * @param channel Backlight channel + * @param level Pointer to store backlight current level result. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_bklit_get_current(t_bklit_channel channel, + unsigned char *level); + +/*! + * This function sets a backlight channel duty cycle. + * LED perceived brightness for each zone may be individually set by setting + * duty cycle. The default setting is for 0% duty cycle; this keeps all zone + * drivers turned off even after the master enable command. Each LED current + * sink can be turned on and adjusted for brightness with an independent 4 bit + * word for a duty cycle ranging from 0% to 100% in approximately 6.7% steps. + * + * @param channel Backlight channel. + * @param dc Backlight duty cycle, as the following table. + * @verbatim + dc Duty Cycle (% On-time over Cycle Time) + ------ --------------------------------------- + 0 0% + 1 6.7% + 2 13.3% + 3 20% + 4 26.7% + 5 33.3% + 6 40% + 7 46.7% + 8 53.3% + 9 60% + 10 66.7% + 11 73.3% + 12 80% + 13 86.7% + 14 93.3% + 15 100% + @endverbatim + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_bklit_set_dutycycle(t_bklit_channel channel, unsigned char dc); + +/*! + * This function retrives a backlight channel duty cycle. + * + * @param channel Backlight channel. + * @param cycle Pointer to backlight duty cycle. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_bklit_get_dutycycle(t_bklit_channel channel, + unsigned char *dc); + +/*! + * This function sets a backlight channel cycle time. + * Cycle Time is defined as the period of a complete cycle of + * Time_on + Time_off. The default Cycle Time is set to 0.01 seconds such that + * the 100 Hz on-off cycling is averaged out by the eye to eliminate + * flickering. Additionally, the Cycle Time can be programmed to intentionally + * extend the period of on-off cycles for a visual pulsating or blinking effect. + * + * @param period Backlight cycle time, as the following table. + * @verbatim + period Cycle Time + -------- ------------ + 0 0.01 seconds + 1 0.1 seconds + 2 0.5 seconds + 3 2 seconds + @endverbatim + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_bklit_set_cycle_time(unsigned char period); + +/*! + * This function retrives a backlight channel cycle time setting. + * + * @param period Pointer to save backlight cycle time setting result. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_bklit_get_cycle_time(unsigned char *period); + +/*! + * This function sets backlight operation mode. There are two modes of + * operations: current control and triode mode. + * The Duty Cycle/Cycle Time control is retained in Triode Mode. Audio + * coupling is not available in Triode Mode. + * + * @param channel Backlight channel. + * @param mode Backlight operation mode. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_bklit_set_mode(t_bklit_channel channel, t_bklit_mode mode); +/*! + * This function gets backlight operation mode. There are two modes of + * operations: current control and triode mode. + * The Duty Cycle/Cycle Time control is retained in Triode Mode. Audio + * coupling is not available in Triode Mode. + * + * @param channel Backlight channel. + * @param mode Backlight operation mode. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_bklit_get_mode(t_bklit_channel channel, t_bklit_mode * mode); +/*! + * This function starts backlight brightness ramp up function; ramp time is + * fixed at 0.5 seconds. + * + * @param channel Backlight channel. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_bklit_rampup(t_bklit_channel channel); +/*! + * This function stops backlight brightness ramp up function; + * + * @param channel Backlight channel. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_bklit_off_rampup(t_bklit_channel channel); +/*! + * This function starts backlight brightness ramp down function; ramp time is + * fixed at 0.5 seconds. + * + * @param channel Backlight channel. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_bklit_rampdown(t_bklit_channel channel); +/*! + * This function stops backlight brightness ramp down function. + * + * @param channel Backlight channel. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_bklit_off_rampdown(t_bklit_channel channel); +/*! + * This function enables backlight analog edge slowing mode. Analog Edge + * Slowing slows down the transient edges to reduce the chance of coupling LED + * modulation activity into other circuits. Rise and fall times will be targeted + * for approximately 50usec. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_bklit_enable_edge_slow(void); + +/*! + * This function disables backlight analog edge slowing mode. The backlight + * drivers will default to an “Instant On” mode. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_bklit_disable_edge_slow(void); +/*! + * This function gets backlight analog edge slowing mode. DThe backlight + * + * @param edge Edge slowing mode. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_bklit_get_edge_slow(bool * edge); +/*! + * This function sets backlight Strobe Light Pulsing mode. + * + * @param channel Backlight channel. + * @param mode Strobe Light Pulsing mode. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_bklit_set_strobemode(t_bklit_channel channel, + t_bklit_strobe_mode mode); + +/*! + * This function enables tri-color LED. + * + * @param mode Tri-color LED operation mode. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_tcled_enable(t_tcled_mode mode, t_funlight_bank bank); +/*! + * This function disables tri-color LED. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_tcled_disable(t_funlight_bank bank); +/*! + * This function retrives tri-color LED operation mode. + * + * @param mode Pointer to Tri-color LED operation mode. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_tcled_get_mode(t_tcled_mode * mode, t_funlight_bank bank); +/*! + * This function sets a tri-color LED channel current level in indicator mode. + * + * @param channel Tri-color LED channel. + * @param level Current level. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_tcled_ind_set_current(t_ind_channel channel, + t_tcled_cur_level level, + t_funlight_bank bank); +/*! + * This function retrives a tri-color LED channel current level in indicator mode. + * + * @param channel Tri-color LED channel. + * @param level Pointer to current level. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_tcled_ind_get_current(t_ind_channel channel, + t_tcled_cur_level * level, + t_funlight_bank bank); +/*! + * This function sets a tri-color LED channel blinking pattern in indication + * mode. + * + * @param channel Tri-color LED channel. + * @param pattern Blinking pattern. + * @param skip If true, skip a cycle after each cycle. + * + * @return This function returns PMIC_SUCCESS if successful. + */ + +PMIC_STATUS pmic_tcled_ind_set_blink_pattern(t_ind_channel channel, + t_tcled_ind_blink_pattern pattern, + bool skip, t_funlight_bank bank); +/*! + * This function retrives a tri-color LED channel blinking pattern in + * indication mode. + * + * @param channel Tri-color LED channel. + * @param pattern Pointer to Blinking pattern. + * @param skip Pointer to a boolean variable indicating if skip + * a cycle after each cycle. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_tcled_ind_get_blink_pattern(t_ind_channel channel, + t_tcled_ind_blink_pattern * + pattern, bool * skip, + t_funlight_bank bank); +/*! + * This function sets a tri-color LED channel current level in Fun Light mode. + * + * @param bank Tri-color LED bank + * @param channel Tri-color LED channel. + * @param level Current level. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_tcled_fun_set_current(t_funlight_bank bank, + t_funlight_channel channel, + t_tcled_cur_level level); + +/*! + * This function retrives a tri-color LED channel current level + * in Fun Light mode. + * + * @param bank Tri-color LED bank + * @param channel Tri-color LED channel. + * @param level Pointer to current level. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_tcled_fun_get_current(t_funlight_bank bank, + t_funlight_channel channel, + t_tcled_cur_level * level); + +/*! + * This function sets tri-color LED cycle time in Fun Light mode. + * + * @param bank Tri-color LED bank + * @param ct Cycle time. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_tcled_fun_set_cycletime(t_funlight_bank bank, + t_tcled_fun_cycle_time ct); + +/*! + * This function retrives tri-color LED cycle time in Fun Light mode. + * + * @param bank Tri-color LED bank + * @param ct Pointer to cycle time. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_tcled_fun_get_cycletime(t_funlight_bank bank, + t_tcled_fun_cycle_time * ct); + +/*! + * This function sets a tri-color LED channel duty cycle in Fun Light mode. + * + * @param bank Tri-color LED bank + * @param channel Tri-color LED channel. + * @param dc Duty cycle. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_tcled_fun_set_dutycycle(t_funlight_bank bank, + t_funlight_channel channel, + unsigned char dc); + +/*! + * This function retrives a tri-color LED channel duty cycle in Fun Light mode. + * + * @param bank Tri-color LED bank + * @param channel Tri-color LED channel. + * @param dc Pointer to duty cycle. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_tcled_fun_get_dutycycle(t_funlight_bank bank, + t_funlight_channel channel, + unsigned char *dc); + +/*! + * This function initiates Blended Ramp fun light pattern. + * + * @param bank Tri-color LED bank + * @param speed Speed of pattern. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_tcled_fun_blendedramps(t_funlight_bank bank, + t_tcled_fun_speed speed); + +/*! + * This function initiates Saw Ramp fun light pattern. + * + * @param bank Tri-color LED bank + * @param speed Speed of pattern. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_tcled_fun_sawramps(t_funlight_bank bank, + t_tcled_fun_speed speed); + +/*! + * This function initiates Blended Bowtie fun light pattern. + * + * @param bank Tri-color LED bank + * @param speed Speed of pattern. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_tcled_fun_blendedbowtie(t_funlight_bank bank, + t_tcled_fun_speed speed); + +/*! + * This function initiates Chasing Lights fun light pattern. + * + * @param bank Tri-color LED bank + * @param pattern Chasing light pattern mode. + * @param speed Speed of pattern. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_tcled_fun_chasinglightspattern(t_funlight_bank bank, + t_chaselight_pattern pattern, + t_tcled_fun_speed speed); + +/*! + * This function initiates Strobe Mode fun light pattern. + * + * @param bank Tri-color LED bank + * @param channel Tri-color LED channel. + * @param speed Speed of pattern. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_tcled_fun_strobe(t_funlight_bank bank, + t_funlight_channel channel, + t_tcled_fun_strobe_speed speed); + +/*! + * This function initiates Tri-color LED brightness Ramp Up function; Ramp time + * is fixed at 1 second. + * + * @param bank Tri-color LED bank + * @param channel Tri-color LED channel. + * @param rampup Ramp-up configuration. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_tcled_fun_rampup(t_funlight_bank bank, + t_funlight_channel channel, bool rampup); +/*! + * This function gets Tri-color LED brightness Ramp Up function; Ramp time + * is fixed at 1 second. + * + * @param bank Tri-color LED bank + * @param channel Tri-color LED channel. + * @param rampup Ramp-up configuration. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_tcled_get_fun_rampup(t_funlight_bank bank, + t_funlight_channel channel, + bool * rampup); + +/*! + * This function initiates Tri-color LED brightness Ramp Down function; Ramp + * time is fixed at 1 second. + * + * @param bank Tri-color LED bank + * @param channel Tri-color LED channel. + * @param rampdown Ramp-down configuration. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_tcled_fun_rampdown(t_funlight_bank bank, + t_funlight_channel channel, bool rampdown); +/*! + * This function initiates Tri-color LED brightness Ramp Down function; Ramp + * time is fixed at 1 second. + * + * @param bank Tri-color LED bank + * @param channel Tri-color LED channel. + * @param rampdown Ramp-down configuration. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_tcled_get_fun_rampdown(t_funlight_bank bank, + t_funlight_channel channel, + bool * rampdown); + +/*! + * This function enables a Tri-color channel triode mode. + * + * @param bank Tri-color LED bank + * @param channel Tri-color LED channel. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_tcled_fun_triode_on(t_funlight_bank bank, + t_funlight_channel channel); + +/*! + * This function disables a Tri-color LED channel triode mode. + * + * @param bank Tri-color LED bank + * @param channel Tri-color LED channel. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_tcled_fun_triode_off(t_funlight_bank bank, + t_funlight_channel channel); + +/*! + * This function enables Tri-color LED edge slowing. + * + * @return This function returns PMIC_NOT_SUPPORTED. + */ +PMIC_STATUS pmic_tcled_enable_edge_slow(void); + +/*! + * This function disables Tri-color LED edge slowing. + * + * @return This function returns PMIC_NOT_SUPPORTED. + */ +PMIC_STATUS pmic_tcled_disable_edge_slow(void); + +/*! + * This function enables Tri-color LED half current mode. + * + * @return This function returns PMIC_NOT_SUPPORTED. + */ +PMIC_STATUS pmic_tcled_enable_half_current(void); + +/*! + * This function disables Tri-color LED half current mode. + * + * @return This function returns PMIC_NOT_SUPPORTED. + */ +PMIC_STATUS pmic_tcled_disable_half_current(void); + +/*! + * This function enables backlight or Tri-color LED audio modulation. + * + * @return This function returns PMIC_NOT_SUPPORTED. + */ +PMIC_STATUS pmic_tcled_enable_audio_modulation(t_led_channel channel, + t_aud_path path, + t_aud_gain gain, + bool lpf_bypass); + +/*! + * This function disables backlight or Tri-color LED audio modulation. + * + * @return This function returns PMIC_NOT_SUPPORTED. + */ +PMIC_STATUS pmic_tcled_disable_audio_modulation(void); +/*! + * This function enables the boost mode. + * Only on mc13783 2.0 or higher + * + * @param en_dis Enable or disable the boost mode + * + * @return This function returns 0 if successful. + */ +PMIC_STATUS pmic_bklit_set_boost_mode(bool en_dis); + +/*! + * This function gets the boost mode. + * Only on mc13783 2.0 or higher + * + * @param en_dis Enable or disable the boost mode + * + * @return This function returns 0 if successful. + */ +PMIC_STATUS pmic_bklit_get_boost_mode(bool * en_dis); + +/*! + * This function sets boost mode configuration + * Only on mc13783 2.0 or higher + * + * @param abms Define adaptive boost mode selection + * @param abr Define adaptive boost reference + * + * @return This function returns 0 if successful. + */ +PMIC_STATUS pmic_bklit_config_boost_mode(unsigned int abms, unsigned int abr); + +/*! + * This function gets boost mode configuration + * Only on mc13783 2.0 or higher + * + * @param abms Define adaptive boost mode selection + * @param abr Define adaptive boost reference + * + * @return This function returns 0 if successful. + */ +PMIC_STATUS pmic_bklit_gets_boost_mode(unsigned int *abms, unsigned int *abr); + +#if defined(CONFIG_MXC_PMIC_MC13892) + +PMIC_STATUS mc13892_bklit_set_current(enum lit_channel channel, + unsigned char level); +PMIC_STATUS mc13892_bklit_get_current(enum lit_channel channel, + unsigned char *level); +PMIC_STATUS mc13892_bklit_set_dutycycle(enum lit_channel channel, + unsigned char dc); +PMIC_STATUS mc13892_bklit_get_dutycycle(enum lit_channel channel, + unsigned char *dc); +PMIC_STATUS mc13892_bklit_set_ramp(enum lit_channel channel, int flag); +PMIC_STATUS mc13892_bklit_get_ramp(enum lit_channel channel, int *flag); +PMIC_STATUS mc13892_bklit_set_blink_p(enum lit_channel channel, int period); +PMIC_STATUS mc13892_bklit_get_blink_p(enum lit_channel channel, int *period); + +#endif + +#endif /* __KERNEL__ */ + +#endif /* __ASM_ARCH_MXC_PMIC_LIGHT_H__ */ --- linux-2.6.28.orig/include/linux/klist.h +++ linux-2.6.28/include/linux/klist.h @@ -23,7 +23,7 @@ struct list_head k_list; void (*get)(struct klist_node *); void (*put)(struct klist_node *); -}; +} __attribute__ ((aligned (4))); #define KLIST_INIT(_name, _get, _put) \ { .k_lock = __SPIN_LOCK_UNLOCKED(_name.k_lock), \ --- linux-2.6.28.orig/include/linux/xattr.h +++ linux-2.6.28/include/linux/xattr.h @@ -16,6 +16,8 @@ #ifdef __KERNEL__ #include +#include +#include /* Namespaces */ #define XATTR_OS2_PREFIX "os2." @@ -47,10 +49,10 @@ }; ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t); -ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t); -ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size); -int vfs_setxattr(struct dentry *, const char *, const void *, size_t, int); -int vfs_removexattr(struct dentry *, const char *); +ssize_t vfs_getxattr(struct dentry *, struct vfsmount *, const char *, void *, size_t, struct file *file); +ssize_t vfs_listxattr(struct dentry *d, struct vfsmount *, char *list, size_t size, struct file *file); +int vfs_setxattr(struct dentry *, struct vfsmount *, const char *, const void *, size_t, int, struct file *file); +int vfs_removexattr(struct dentry *, struct vfsmount *mnt, const char *, struct file *file); ssize_t generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size); ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size); --- linux-2.6.28.orig/include/linux/usb_usual.h +++ linux-2.6.28/include/linux/usb_usual.h @@ -52,8 +52,9 @@ US_FLAG(MAX_SECTORS_MIN,0x00002000) \ /* Sets max_sectors to arch min */ \ US_FLAG(BULK_IGNORE_TAG,0x00004000) \ - /* Ignore tag mismatch in bulk operations */ - + /* Ignore tag mismatch in bulk operations */ \ + US_FLAG(CAPACITY_OK, 0x00010000) \ + /* READ CAPACITY response is correct */ #define US_FLAG(name, value) US_FL_##name = value , enum { US_DO_ALL_FLAGS }; --- linux-2.6.28.orig/include/linux/dmi.h +++ linux-2.6.28/include/linux/dmi.h @@ -44,6 +44,7 @@ extern void dmi_scan_machine(void); extern int dmi_get_year(int field); extern int dmi_name_in_vendors(const char *str); +extern int dmi_name_in_serial(const char *str); extern int dmi_available; extern int dmi_walk(void (*decode)(const struct dmi_header *)); @@ -56,6 +57,7 @@ static inline void dmi_scan_machine(void) { return; } static inline int dmi_get_year(int year) { return 0; } static inline int dmi_name_in_vendors(const char *s) { return 0; } +static inline int dmi_name_in_serial(const char *s) { return 0; } #define dmi_available 0 static inline int dmi_walk(void (*decode)(const struct dmi_header *)) { return -1; } --- linux-2.6.28.orig/include/linux/mount.h +++ linux-2.6.28/include/linux/mount.h @@ -112,4 +112,6 @@ extern spinlock_t vfsmount_lock; extern dev_t name_to_dev_t(char *name); +extern char *d_namespace_path(struct dentry *, struct vfsmount *, char *, int); + #endif /* _LINUX_MOUNT_H */ --- linux-2.6.28.orig/include/linux/audit.h +++ linux-2.6.28/include/linux/audit.h @@ -33,7 +33,7 @@ * 1200 - 1299 messages internal to the audit daemon * 1300 - 1399 audit event messages * 1400 - 1499 SE Linux use - * 1500 - 1599 kernel LSPP events + * 1500 - 1599 AppArmor use * 1600 - 1699 kernel crypto events * 1700 - 1799 kernel anomaly records * 1800 - 1999 future kernel use (maybe integrity labels and related events) @@ -119,6 +119,13 @@ #define AUDIT_MAC_UNLBL_STCADD 1416 /* NetLabel: add a static label */ #define AUDIT_MAC_UNLBL_STCDEL 1417 /* NetLabel: del a static label */ +#define AUDIT_APPARMOR_AUDIT 1501 /* AppArmor audited grants */ +#define AUDIT_APPARMOR_ALLOWED 1502 /* Allowed Access for learning */ +#define AUDIT_APPARMOR_DENIED 1503 +#define AUDIT_APPARMOR_HINT 1504 /* Process Tracking information */ +#define AUDIT_APPARMOR_STATUS 1505 /* Changes in config */ +#define AUDIT_APPARMOR_ERROR 1506 /* Internal AppArmor Errors */ + #define AUDIT_FIRST_KERN_ANOM_MSG 1700 #define AUDIT_LAST_KERN_ANOM_MSG 1799 #define AUDIT_ANOM_PROMISCUOUS 1700 /* Device changed promiscuous mode */ @@ -547,6 +554,9 @@ __attribute__((format(printf,4,5))); extern struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type); +extern void audit_log_vformat(struct audit_buffer *ab, + const char *fmt, va_list args) + __attribute__((format(printf,2,0))); extern void audit_log_format(struct audit_buffer *ab, const char *fmt, ...) __attribute__((format(printf,2,3))); --- linux-2.6.28.orig/include/linux/slab_def.h +++ linux-2.6.28/include/linux/slab_def.h @@ -43,10 +43,7 @@ i++; #include #undef CACHE - { - extern void __you_cannot_kmalloc_that_much(void); - __you_cannot_kmalloc_that_much(); - } + return NULL; found: #ifdef CONFIG_ZONE_DMA if (flags & GFP_DMA) @@ -77,10 +74,7 @@ i++; #include #undef CACHE - { - extern void __you_cannot_kmalloc_that_much(void); - __you_cannot_kmalloc_that_much(); - } + return NULL; found: #ifdef CONFIG_ZONE_DMA if (flags & GFP_DMA) --- linux-2.6.28.orig/include/linux/serial.h +++ linux-2.6.28/include/linux/serial.h @@ -10,8 +10,9 @@ #ifndef _LINUX_SERIAL_H #define _LINUX_SERIAL_H -#ifdef __KERNEL__ #include + +#ifdef __KERNEL__ #include /* --- linux-2.6.28.orig/include/linux/sysctl.h +++ linux-2.6.28/include/linux/sysctl.h @@ -996,6 +996,8 @@ extern int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int, struct file *, void __user *, size_t *, loff_t *); +extern char *sysctl_pathname(ctl_table *, char *, int); + extern int do_sysctl (int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, void __user *newval, size_t newlen); --- linux-2.6.28.orig/include/linux/pagemap.h +++ linux-2.6.28/include/linux/pagemap.h @@ -241,7 +241,8 @@ unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index, int tag, unsigned int nr_pages, struct page **pages); -struct page *__grab_cache_page(struct address_space *mapping, pgoff_t index); +struct page *grab_cache_page_write_begin(struct address_space *mapping, + pgoff_t index, unsigned flags); /* * Returns locked page at given index in given cache, creating it if needed. --- linux-2.6.28.orig/include/linux/pmic_external.h +++ linux-2.6.28/include/linux/pmic_external.h @@ -0,0 +1,1134 @@ +/* + * Copyright 2008-2009 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_PMIC_EXTERNAL_H__ +#define __ASM_ARCH_MXC_PMIC_EXTERNAL_H__ + +#ifdef __KERNEL__ +#include +#endif + +/*! + * @defgroup PMIC_DRVRS PMIC Drivers + */ + +/*! + * @defgroup PMIC_CORE PMIC Protocol Drivers + * @ingroup PMIC_DRVRS + */ + +/*! + * @file arch-mxc/pmic_external.h + * @brief This file contains interface of PMIC protocol driver. + * + * @ingroup PMIC_CORE + */ + +#include +#include + +/*! + * This is the enumeration of versions of PMIC + */ +typedef enum { + PMIC_MC13783 = 1, /*!< MC13783 */ + PMIC_SC55112 = 2, /*!< SC55112 */ + PMIC_MC13892 = 3, + PMIC_MC34704 = 4 +} pmic_id_t; + +/*! + * @struct pmic_version_t + * @brief PMIC version and revision + */ +typedef struct { + /*! + * PMIC version identifier. + */ + pmic_id_t id; + /*! + * Revision of the PMIC. + */ + int revision; +} pmic_version_t; + +/*! + * struct pmic_event_callback_t + * @brief This structure contains callback function pointer and its + * parameter to be used when un/registering and launching a callback + * for an event. + */ +typedef struct { + /*! + * call back function + */ + void (*func) (void *); + + /*! + * call back function parameter + */ + void *param; +} pmic_event_callback_t; + +/*! + * This structure is used with IOCTL. + * It defines register, register value, register mask and event number + */ +typedef struct { + /*! + * register number + */ + int reg; + /*! + * value of register + */ + unsigned int reg_value; + /*! + * mask of bits, only used with PMIC_WRITE_REG + */ + unsigned int reg_mask; +} register_info; + +/*! + * @name IOCTL definitions for sc55112 core driver + */ +/*! @{ */ +/*! Read a PMIC register */ +#define PMIC_READ_REG _IOWR('P', 0xa0, register_info*) +/*! Write a PMIC register */ +#define PMIC_WRITE_REG _IOWR('P', 0xa1, register_info*) +/*! Subscribe a PMIC interrupt event */ +#define PMIC_SUBSCRIBE _IOR('P', 0xa2, int) +/*! Unsubscribe a PMIC interrupt event */ +#define PMIC_UNSUBSCRIBE _IOR('P', 0xa3, int) +/*! Subscribe a PMIC event for user notification*/ +#define PMIC_NOTIFY_USER _IOR('P', 0xa4, int) +/*! Get the PMIC event occured for which user recieved notification */ +#define PMIC_GET_NOTIFY _IOW('P', 0xa5, int) +/*! @} */ + +/*! + * This is PMIC registers valid bits + */ +#define PMIC_ALL_BITS 0xFFFFFF +#define PMIC_MAX_EVENTS 48 + +#define PMIC_ARBITRATION "NULL" + +#ifdef CONFIG_MXC_PMIC_MC13783 +/*! + * This is the enumeration of register names of MC13783 + */ +typedef enum { + /*! + * REG_INTERRUPT_STATUS_0 + */ + REG_INTERRUPT_STATUS_0 = 0, + /*! + * REG_INTERRUPT_MASK_0 + */ + REG_INTERRUPT_MASK_0, + /*! + * REG_INTERRUPT_SENSE_0 + */ + REG_INTERRUPT_SENSE_0, + /*! + * REG_INTERRUPT_STATUS_1 + */ + REG_INTERRUPT_STATUS_1, + /*! + * REG_INTERRUPT_MASK_1 + */ + REG_INTERRUPT_MASK_1, + /*! + * REG_INTERRUPT_SENSE_1 + */ + REG_INTERRUPT_SENSE_1, + /*! + * REG_POWER_UP_MODE_SENSE + */ + REG_POWER_UP_MODE_SENSE, + /*! + * REG_REVISION + */ + REG_REVISION, + /*! + * REG_SEMAPHORE + */ + REG_SEMAPHORE, + /*! + * REG_ARBITRATION_PERIPHERAL_AUDIO + */ + REG_ARBITRATION_PERIPHERAL_AUDIO, + /*! + * REG_ARBITRATION_SWITCHERS + */ + REG_ARBITRATION_SWITCHERS, + /*! + * REG_ARBITRATION_REGULATORS_0 + */ + REG_ARBITRATION_REGULATORS_0, + /*! + * REG_ARBITRATION_REGULATORS_1 + */ + REG_ARBITRATION_REGULATORS_1, + /*! + * REG_POWER_CONTROL_0 + */ + REG_POWER_CONTROL_0, + /*! + * REG_POWER_CONTROL_1 + */ + REG_POWER_CONTROL_1, + /*! + * REG_POWER_CONTROL_2 + */ + REG_POWER_CONTROL_2, + /*! + * REG_REGEN_ASSIGNMENT + */ + REG_REGEN_ASSIGNMENT, + /*! + * REG_CONTROL_SPARE + */ + REG_CONTROL_SPARE, + /*! + * REG_MEMORY_A + */ + REG_MEMORY_A, + /*! + * REG_MEMORY_B + */ + REG_MEMORY_B, + /*! + * REG_RTC_TIME + */ + REG_RTC_TIME, + /*! + * REG_RTC_ALARM + */ + REG_RTC_ALARM, + /*! + * REG_RTC_DAY + */ + REG_RTC_DAY, + /*! + * REG_RTC_DAY_ALARM + */ + REG_RTC_DAY_ALARM, + /*! + * REG_SWITCHERS_0 + */ + REG_SWITCHERS_0, + /*! + * REG_SWITCHERS_1 + */ + REG_SWITCHERS_1, + /*! + * REG_SWITCHERS_2 + */ + REG_SWITCHERS_2, + /*! + * REG_SWITCHERS_3 + */ + REG_SWITCHERS_3, + /*! + * REG_SWITCHERS_4 + */ + REG_SWITCHERS_4, + /*! + * REG_SWITCHERS_5 + */ + REG_SWITCHERS_5, + /*! + * REG_REGULATOR_SETTING_0 + */ + REG_REGULATOR_SETTING_0, + /*! + * REG_REGULATOR_SETTING_1 + */ + REG_REGULATOR_SETTING_1, + /*! + * REG_REGULATOR_MODE_0 + */ + REG_REGULATOR_MODE_0, + /*! + * REG_REGULATOR_MODE_1 + */ + REG_REGULATOR_MODE_1, + /*! + * REG_POWER_MISCELLANEOUS + */ + REG_POWER_MISCELLANEOUS, + /*! + * REG_POWER_SPARE + */ + REG_POWER_SPARE, + /*! + * REG_AUDIO_RX_0 + */ + REG_AUDIO_RX_0, + /*! + * REG_AUDIO_RX_1 + */ + REG_AUDIO_RX_1, + /*! + * REG_AUDIO_TX + */ + REG_AUDIO_TX, + /*! + * REG_AUDIO_SSI_NETWORK + */ + REG_AUDIO_SSI_NETWORK, + /*! + * REG_AUDIO_CODEC + */ + REG_AUDIO_CODEC, + /*! + * REG_AUDIO_STEREO_DAC + */ + REG_AUDIO_STEREO_DAC, + /*! + * REG_AUDIO_SPARE + */ + REG_AUDIO_SPARE, + /*! + * REG_ADC_0 + */ + REG_ADC_0, + /*! + * REG_ADC_1 + */ + REG_ADC_1, + /*! + * REG_ADC_2 + */ + REG_ADC_2, + /*! + * REG_ADC_3 + */ + REG_ADC_3, + /*! + * REG_ADC_4 + */ + REG_ADC_4, + /*! + * REG_CHARGER + */ + REG_CHARGER, + /*! + * REG_USB + */ + REG_USB, + /*! + * REG_CHARGE_USB_SPARE + */ + REG_CHARGE_USB_SPARE, + /*! + * REG_LED_CONTROL_0 + */ + REG_LED_CONTROL_0, + /*! + * REG_LED_CONTROL_1 + */ + REG_LED_CONTROL_1, + /*! + * REG_LED_CONTROL_2 + */ + REG_LED_CONTROL_2, + /*! + * REG_LED_CONTROL_3 + */ + REG_LED_CONTROL_3, + /*! + * REG_LED_CONTROL_4 + */ + REG_LED_CONTROL_4, + /*! + * REG_LED_CONTROL_5 + */ + REG_LED_CONTROL_5, + /*! + * REG_SPARE + */ + REG_SPARE, + /*! + * REG_TRIM_0 + */ + REG_TRIM_0, + /*! + * REG_TRIM_1 + */ + REG_TRIM_1, + /*! + * REG_TEST_0 + */ + REG_TEST_0, + /*! + * REG_TEST_1 + */ + REG_TEST_1, + /*! + * REG_TEST_2 + */ + REG_TEST_2, + /*! + * REG_TEST_3 + */ + REG_TEST_3, + /*! + * REG_NB + */ + REG_NB, +} pmic_reg; + +/*! + * This is event list of mc13783 interrupt + */ + +typedef enum { + /*! + * ADC has finished requested conversions + */ + EVENT_ADCDONEI = 0, + /*! + * ADCBIS has finished requested conversions + */ + EVENT_ADCBISDONEI = 1, + /*! + * Touchscreen wakeup + */ + EVENT_TSI = 2, + /*! + * ADC reading above high limit + */ + EVENT_WHIGHI = 3, + /*! + * ADC reading below low limit + */ + EVENT_WLOWI = 4, + /*! + * Charger attach and removal + */ + EVENT_CHGDETI = 6, + /*! + * Charger over-voltage detection + */ + EVENT_CHGOVI = 7, + /*! + * Charger path reverse current + */ + EVENT_CHGREVI = 8, + /*! + * Charger path short circuit + */ + EVENT_CHGSHORTI = 9, + /*! + * BP regulator current or voltage regulation + */ + EVENT_CCCVI = 10, + /*! + * Charge current below threshold + */ + EVENT_CHRGCURRI = 11, + /*! + * BP turn on threshold detection + */ + EVENT_BPONI = 12, + /*! + * End of life / low battery detect + */ + EVENT_LOBATLI = 13, + /*! + * Low battery warning + */ + EVENT_LOBATHI = 14, + /*! + * USB detect + */ + EVENT_USBI = 16, + /*! + * USB ID Line detect + */ + EVENT_IDI = 19, + /*! + * Single ended 1 detect + */ + EVENT_SE1I = 21, + /*! + * Car-kit detect + */ + EVENT_CKDETI = 22, + /*! + * 1 Hz time-tick + */ + EVENT_E1HZI = 24, + /*! + * Time of day alarm + */ + EVENT_TODAI = 25, + /*! + * ON1B event + */ + EVENT_ONOFD1I = 27, + /*! + * ON2B event + */ + EVENT_ONOFD2I = 28, + /*! + * ON3B event + */ + EVENT_ONOFD3I = 29, + /*! + * System reset + */ + EVENT_SYSRSTI = 30, + /*! + * RTC reset occurred + */ + EVENT_RTCRSTI = 31, + /*! + * Power cut event + */ + EVENT_PCI = 32, + /*! + * Warm start event + */ + EVENT_WARMI = 33, + /*! + * Memory hold event + */ + EVENT_MEMHLDI = 34, + /*! + * Power ready + */ + EVENT_PWRRDYI = 35, + /*! + * Thermal warning lower threshold + */ + EVENT_THWARNLI = 36, + /*! + * Thermal warning higher threshold + */ + EVENT_THWARNHI = 37, + /*! + * Clock source change + */ + EVENT_CLKI = 38, + /*! + * Semaphore + */ + EVENT_SEMAFI = 39, + /*! + * Microphone bias 2 detect + */ + EVENT_MC2BI = 41, + /*! + * Headset attach + */ + EVENT_HSDETI = 42, + /*! + * Stereo headset detect + */ + EVENT_HSLI = 43, + /*! + * Thermal shutdown ALSP + */ + EVENT_ALSPTHI = 44, + /*! + * Short circuit on AHS outputs + */ + EVENT_AHSSHORTI = 45, + /*! + * number of event + */ + EVENT_NB, +} type_event; + +/*! + * This enumeration all senses of MC13783. + */ +typedef enum { + /*! + * Charger attach sense + */ + SENSE_CHGDETS = 6, + /*! + * Charger over-voltage sense + */ + SENSE_CHGOVS, + /*! + * Charger reverse current + * If 1 current flows into phone + */ + SENSE_CHGREVS, + /*! + * Charger short circuit + */ + SENSE_CHGSHORTS, + /*! + * Charger regulator operating mode + */ + SENSE_CCCVS, + /*! + * Charger current below threshold + */ + SENSE_CHGCURRS, + /*! + * BP turn on + */ + SENSE_BPONS, + /*! + * Low bat detect + */ + SENSE_LOBATLS, + /*! + * Low bat warning + */ + SENSE_LOBATHS, + /*! + * UDPS + */ + SENSE_UDPS, + /*! + * USB 4V4 + */ + SENSE_USB4V4S, + /*! + * USB 2V0 + */ + SENSE_USB2V0S, + /*! + * USB 0V8 + */ + SENSE_USB0V8S, + /*! + * ID Floats + */ + SENSE_ID_FLOATS, + /*! + * ID Gnds + */ + SENSE_ID_GNDS, + /*! + * Single ended + */ + SENSE_SE1S, + /*! + * Car-kit detect + */ + SENSE_CKDETS, + /*! + * UDMS + */ + SENSE_UDMS, + /*! + * mic bias detect + */ + SENSE_MC2BS, + /*! + * headset attached + */ + SENSE_HSDETS, + /*! + * ST headset attached + */ + SENSE_HSLS, + /*! + * Thermal shutdown ALSP + */ + SENSE_ALSPTHS, + /*! + * short circuit on AHS + */ + SENSE_AHSSHORTS, + /*! + * ON1B pin is hight + */ + SENSE_ONOFD1S, + /*! + * ON2B pin is hight + */ + SENSE_ONOFD2S, + /*! + * ON3B pin is hight + */ + SENSE_ONOFD3S, + /*! + * System reset power ready + */ + SENSE_PWRRDYS, + /*! + * Thermal warning higher threshold + */ + SENSE_THWARNHS, + /*! + * Thermal warning lower threshold + */ + SENSE_THWARNLS, + /*! + * Clock source is XTAL + */ + SENSE_CLKS, +} t_sensor; + +/*! + * This structure is used to read all sense bits of MC13783. + */ +typedef struct { + /*! + * Charger attach sense + */ + bool sense_chgdets; + /*! + * Charger over-voltage sense + */ + bool sense_chgovs; + /*! + * Charger reverse current + * If 1 current flows into phone + */ + bool sense_chgrevs; + /*! + * Charger short circuit + */ + bool sense_chgshorts; + /*! + * Charger regulator operating mode + */ + bool sense_cccvs; + /*! + * Charger current below threshold + */ + bool sense_chgcurrs; + /*! + * BP turn on + */ + bool sense_bpons; + /*! + * Low bat detect + */ + bool sense_lobatls; + /*! + * Low bat warning + */ + bool sense_lobaths; + /*! + * USB 4V4 + */ + bool sense_usb4v4s; + /*! + * USB 2V0 + */ + bool sense_usb2v0s; + /*! + * USB 0V8 + */ + bool sense_usb0v8s; + /*! + * ID Floats + */ + bool sense_id_floats; + /*! + * ID Gnds + */ + bool sense_id_gnds; + /*! + * Single ended + */ + bool sense_se1s; + /*! + * Car-kit detect + */ + bool sense_ckdets; + /*! + * mic bias detect + */ + bool sense_mc2bs; + /*! + * headset attached + */ + bool sense_hsdets; + /*! + * ST headset attached + */ + bool sense_hsls; + /*! + * Thermal shutdown ALSP + */ + bool sense_alspths; + /*! + * short circuit on AHS + */ + bool sense_ahsshorts; + /*! + * ON1B pin is hight + */ + bool sense_onofd1s; + /*! + * ON2B pin is hight + */ + bool sense_onofd2s; + /*! + * ON3B pin is hight + */ + bool sense_onofd3s; + /*! + * System reset power ready + */ + bool sense_pwrrdys; + /*! + * Thermal warning higher threshold + */ + bool sense_thwarnhs; + /*! + * Thermal warning lower threshold + */ + bool sense_thwarnls; + /*! + * Clock source is XTAL + */ + bool sense_clks; +} t_sensor_bits; + +#endif /*CONFIG_MXC_PMIC_MC13783 */ + +#if defined(CONFIG_MXC_PMIC_MC13892_MODULE) || defined(CONFIG_MXC_PMIC_MC13892) +enum { + REG_INT_STATUS0 = 0, + REG_INT_MASK0, + REG_INT_SENSE0, + REG_INT_STATUS1, + REG_INT_MASK1, + REG_INT_SENSE1, + REG_PU_MODE_S, + REG_IDENTIFICATION, + REG_UNUSED0, + REG_ACC0, + REG_ACC1, /*10 */ + REG_UNUSED1, + REG_UNUSED2, + REG_POWER_CTL0, + REG_POWER_CTL1, + REG_POWER_CTL2, + REG_REGEN_ASSIGN, + REG_UNUSED3, + REG_MEM_A, + REG_MEM_B, + REG_RTC_TIME, /*20 */ + REG_RTC_ALARM, + REG_RTC_DAY, + REG_RTC_DAY_ALARM, + REG_SW_0, + REG_SW_1, + REG_SW_2, + REG_SW_3, + REG_SW_4, + REG_SW_5, + REG_SETTING_0, /*30 */ + REG_SETTING_1, + REG_MODE_0, + REG_MODE_1, + REG_POWER_MISC, + REG_UNUSED4, + REG_UNUSED5, + REG_UNUSED6, + REG_UNUSED7, + REG_UNUSED8, + REG_UNUSED9, /*40 */ + REG_UNUSED10, + REG_UNUSED11, + REG_ADC0, + REG_ADC1, + REG_ADC2, + REG_ADC3, + REG_ADC4, + REG_CHARGE, + REG_USB0, + REG_USB1, /*50 */ + REG_LED_CTL0, + REG_LED_CTL1, + REG_LED_CTL2, + REG_LED_CTL3, + REG_UNUSED12, + REG_UNUSED13, + REG_TRIM0, + REG_TRIM1, + REG_TEST0, + REG_TEST1, /*60 */ + REG_TEST2, + REG_TEST3, + REG_TEST4, +}; + +typedef enum { + EVENT_ADCDONEI = 0, + EVENT_ADCBISDONEI = 1, + EVENT_TSI = 2, + EVENT_VBUSVI = 3, + EVENT_IDFACI = 4, + EVENT_USBOVI = 5, + EVENT_CHGDETI = 6, + EVENT_CHGFAULTI = 7, + EVENT_CHGREVI = 8, + EVENT_CHGRSHORTI = 9, + EVENT_CCCVI = 10, + EVENT_CHGCURRI = 11, + EVENT_BPONI = 12, + EVENT_LOBATLI = 13, + EVENT_LOBATHI = 14, + EVENT_IDFLOATI = 19, + EVENT_IDGNDI = 20, + EVENT_SE1I = 21, + EVENT_CKDETI = 22, + EVENT_1HZI = 24, + EVENT_TODAI = 25, + EVENT_PWRONI = 27, + EVENT_WDIRESETI = 29, + EVENT_SYSRSTI = 30, + EVENT_RTCRSTI = 31, + EVENT_PCI = 32, + EVENT_WARMI = 33, + EVENT_MEMHLDI = 34, + EVENT_THWARNLI = 36, + EVENT_THWARNHI = 37, + EVENT_CLKI = 38, + EVENT_SCPI = 40, + EVENT_LBPI = 44, + EVENT_NB, +} type_event; + +typedef enum { + SENSE_VBUSVS = 3, + SENSE_IDFACS = 4, + SENSE_USBOVS = 5, + SENSE_CHGDETS = 6, + SENSE_CHGREVS = 8, + SENSE_CHGRSHORTS = 9, + SENSE_CCCVS = 10, + SENSE_CHGCURRS = 11, + SENSE_BPONS = 12, + SENSE_LOBATLS = 13, + SENSE_LOBATHS = 14, + SENSE_IDFLOATS = 19, + SENSE_IDGNDS = 20, + SENSE_SE1S = 21, + SENSE_PWRONS = 27, + SENSE_THWARNLS = 36, + SENSE_THWARNHS = 37, + SENSE_CLKS = 38, + SENSE_LBPS = 44, + SENSE_NB, +} t_sensor; + +typedef struct { + bool sense_vbusvs; + bool sense_idfacs; + bool sense_usbovs; + bool sense_chgdets; + bool sense_chgrevs; + bool sense_chgrshorts; + bool sense_cccvs; + bool sense_chgcurrs; + bool sense_bpons; + bool sense_lobatls; + bool sense_lobaths; + bool sense_idfloats; + bool sense_idgnds; + bool sense_se1s; + bool sense_pwrons; + bool sense_thwarnls; + bool sense_thwarnhs; + bool sense_clks; + bool sense_lbps; +} t_sensor_bits; + +extern struct i2c_client *mc13892_client; +int pmic_i2c_24bit_read(struct i2c_client *client, unsigned int reg_num, + unsigned int *value); +int pmic_read(int reg_num, unsigned int *reg_val); +int pmic_write(int reg_num, const unsigned int reg_val); +void gpio_pmic_active(void); +void pmic_event_list_init(void); +void mc13892_power_off(void); + +#endif + +#if defined(CONFIG_MXC_PMIC_MC34704_MODULE) || defined(CONFIG_MXC_PMIC_MC34704) + +typedef enum { + /* register names for mc34704 */ + REG_MC34704_GENERAL1 = 0x01, + REG_MC34704_GENERAL2 = 0x02, + REG_MC34704_GENERAL3 = 0x03, + REG_MC34704_VGSET1 = 0x04, + REG_MC34704_VGSET2 = 0x05, + REG_MC34704_REG2SET1 = 0x06, + REG_MC34704_REG2SET2 = 0x07, + REG_MC34704_REG3SET1 = 0x08, + REG_MC34704_REG3SET2 = 0x09, + REG_MC34704_REG4SET1 = 0x0A, + REG_MC34704_REG4SET2 = 0x0B, + REG_MC34704_REG5SET1 = 0x0C, + REG_MC34704_REG5SET2 = 0x0D, + REG_MC34704_REG5SET3 = 0x0E, + REG_MC34704_REG6SET1 = 0x0F, + REG_MC34704_REG6SET2 = 0x10, + REG_MC34704_REG6SET3 = 0x11, + REG_MC34704_REG7SET1 = 0x12, + REG_MC34704_REG7SET2 = 0x13, + REG_MC34704_REG7SET3 = 0x14, + REG_MC34704_REG8SET1 = 0x15, + REG_MC34704_REG8SET2 = 0x16, + REG_MC34704_REG8SET3 = 0x17, + REG_MC34704_FAULTS = 0x18, + REG_MC34704_I2CSET1 = 0x19, + REG_MC34704_REG3DAC = 0x49, + REG_MC34704_REG7CR0 = 0x58, + REG_MC34704_REG7DAC = 0x59, + REG_NB = 0x60, +} pmic_reg; + +typedef enum { + /* events for mc34704 */ + EVENT_FLT1 = 0, + EVENT_FLT2, + EVENT_FLT3, + EVENT_FLT4, + EVENT_FLT5, + EVENT_FLT6, + EVENT_FLT7, + EVENT_FLT8, + EVENT_NB, +} type_event; + +typedef enum { + MCU_SENSOR_NOT_SUPPORT +} t_sensor; + +typedef enum { + MCU_SENSOR_BIT_NOT_SUPPORT +} t_sensor_bits; + +#endif /* MXC_PMIC_MC34704 */ + +/* EXPORTED FUNCTIONS */ +#ifdef __KERNEL__ + +#if defined(CONFIG_MXC_PMIC) +/*! + * This function is used to determine the PMIC type and its revision. + * + * @return Returns the PMIC type and its revision. + */ +pmic_version_t pmic_get_version(void); + +/*! + * This function is called by PMIC clients to read a register on PMIC. + * + * @param priority priority of access + * @param reg number of register + * @param reg_value return value of register + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_read_reg(int reg, unsigned int *reg_value, + unsigned int reg_mask); +/*! + * This function is called by PMIC clients to write a register on MC13783. + * + * @param priority priority of access + * @param reg number of register + * @param reg_value New value of register + * @param reg_mask Bitmap mask indicating which bits to modify + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_write_reg(int reg, unsigned int reg_value, + unsigned int reg_mask); + +/*! + * This function is called by PMIC clients to subscribe on an event. + * + * @param event_sub structure of event, it contains type of event and callback + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_event_subscribe(type_event event, + pmic_event_callback_t callback); +/*! +* This function is called by PMIC clients to un-subscribe on an event. +* +* @param event_unsub structure of event, it contains type of event and callback +* +* @return This function returns PMIC_SUCCESS if successful. +*/ +PMIC_STATUS pmic_event_unsubscribe(type_event event, + pmic_event_callback_t callback); +/*! +* This function is called to read all sensor bits of PMIC. +* +* @param sensor Sensor to be checked. +* +* @return This function returns true if the sensor bit is high; +* or returns false if the sensor bit is low. +*/ +bool pmic_check_sensor(t_sensor sensor); + +/*! +* This function checks one sensor of PMIC. +* +* @param sensor_bits structure of all sensor bits. +* +* @return This function returns PMIC_SUCCESS if successful. +*/ +PMIC_STATUS pmic_get_sensors(t_sensor_bits * sensor_bits); + +void pmic_event_callback(type_event event); +void pmic_event_list_init(void); + +#ifdef CONFIG_REGULATOR_MC13783 +/*! + * This function is used to initialize the regulator for MC13783. + * + * @return Returns 0. + */ +int reg_mc13783_probe(struct device *dev); +#else +static inline int reg_mc13783_probe(struct device *dev) +{ + return 0; +}; +#endif + +#ifdef CONFIG_REGULATOR_MC13892 +int mc13892_regulator_i2c_init(struct i2c_client *client); +#else +static inline int mc13892_regulator_i2c_init(struct i2c_client *client) +{ + return 0; +}; +#endif + +#ifdef CONFIG_REGULATOR_MC34704 +int reg_mc34704_probe(void); +#else +static inline int reg_mc34704_probe(void) +{ + return 0; +}; +#endif +#endif /*CONFIG_MXC_PMIC*/ +#endif /* __KERNEL__ */ +/* CONFIG_MXC_PMIC_MC13783 || CONFIG_MXC_PMIC_MC9SDZ60 */ + +#endif /* __ASM_ARCH_MXC_PMIC_EXTERNAL_H__ */ --- linux-2.6.28.orig/include/linux/pid.h +++ linux-2.6.28/include/linux/pid.h @@ -123,6 +123,24 @@ extern void free_pid(struct pid *pid); /* + * ns_of_pid() returns the pid namespace in which the specified pid was + * allocated. + * + * NOTE: + * ns_of_pid() is expected to be called for a process (task) that has + * an attached 'struct pid' (see attach_pid(), detach_pid()) i.e @pid + * is expected to be non-NULL. If @pid is NULL, caller should handle + * the resulting NULL pid-ns. + */ +static inline struct pid_namespace *ns_of_pid(struct pid *pid) +{ + struct pid_namespace *ns = NULL; + if (pid) + ns = pid->numbers[pid->level].ns; + return ns; +} + +/* * the helpers to get the pid's id seen from different namespaces * * pid_nr() : global id, i.e. the id seen from the init namespace; --- linux-2.6.28.orig/include/linux/wait.h +++ linux-2.6.28/include/linux/wait.h @@ -132,6 +132,8 @@ list_del(&old->task_list); } +void __wake_up_common(wait_queue_head_t *q, unsigned int mode, + int nr_exclusive, int sync, void *key); void __wake_up(wait_queue_head_t *q, unsigned int mode, int nr, void *key); extern void __wake_up_locked(wait_queue_head_t *q, unsigned int mode); extern void __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr); @@ -333,16 +335,19 @@ for (;;) { \ prepare_to_wait_exclusive(&wq, &__wait, \ TASK_INTERRUPTIBLE); \ - if (condition) \ + if (condition) { \ + finish_wait(&wq, &__wait); \ break; \ + } \ if (!signal_pending(current)) { \ schedule(); \ continue; \ } \ ret = -ERESTARTSYS; \ + abort_exclusive_wait(&wq, &__wait, \ + TASK_INTERRUPTIBLE, NULL); \ break; \ } \ - finish_wait(&wq, &__wait); \ } while (0) #define wait_event_interruptible_exclusive(wq, condition) \ @@ -431,6 +436,8 @@ void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state); void prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *wait, int state); void finish_wait(wait_queue_head_t *q, wait_queue_t *wait); +void abort_exclusive_wait(wait_queue_head_t *q, wait_queue_t *wait, + unsigned int mode, void *key); int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key); int wake_bit_function(wait_queue_t *wait, unsigned mode, int sync, void *key); --- linux-2.6.28.orig/include/linux/splice.h +++ linux-2.6.28/include/linux/splice.h @@ -71,4 +71,10 @@ extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *, splice_direct_actor *); +extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags); +extern long do_splice_to(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags); + #endif --- linux-2.6.28.orig/include/linux/if_tunnel.h +++ linux-2.6.28/include/linux/if_tunnel.h @@ -2,7 +2,10 @@ #define _IF_TUNNEL_H_ #include + +#ifdef __KERNEL__ #include +#endif #define SIOCGETTUNNEL (SIOCDEVPRIVATE + 0) #define SIOCADDTUNNEL (SIOCDEVPRIVATE + 1) --- linux-2.6.28.orig/include/linux/skbuff.h +++ linux-2.6.28/include/linux/skbuff.h @@ -411,15 +411,6 @@ void *here); extern void skb_under_panic(struct sk_buff *skb, int len, void *here); -extern void skb_truesize_bug(struct sk_buff *skb); - -static inline void skb_truesize_check(struct sk_buff *skb) -{ - int len = sizeof(struct sk_buff) + skb->len; - - if (unlikely((int)skb->truesize < len)) - skb_truesize_bug(skb); -} extern int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb, int getfrag(void *from, char *to, int offset, --- linux-2.6.28.orig/include/linux/jbd2.h +++ linux-2.6.28/include/linux/jbd2.h @@ -308,7 +308,8 @@ int val = (expr); \ if (!val) { \ printk(KERN_ERR \ - "EXT3-fs unexpected failure: %s;\n",# expr); \ + "JBD2 unexpected failure: %s: %s;\n", \ + __func__, #expr); \ printk(KERN_ERR why "\n"); \ } \ val; \ @@ -329,6 +330,7 @@ BH_State, /* Pins most journal_head state */ BH_JournalHead, /* Pins bh->b_private and jh->b_bh */ BH_Unshadow, /* Dummy bit, for BJ_Shadow wakeup filtering */ + BH_JBDPrivateStart, /* First bit available for private use by FS */ }; BUFFER_FNS(JBD, jbd) @@ -1085,7 +1087,8 @@ 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 int jbd2_journal_begin_ordered_truncate(journal_t *journal, + 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); --- linux-2.6.28.orig/include/linux/pmic_adc.h +++ linux-2.6.28/include/linux/pmic_adc.h @@ -0,0 +1,455 @@ +/* + * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU Lesser General + * Public License. You may obtain a copy of the GNU Lesser General + * Public License Version 2.1 or later at the following locations: + * + * http://www.opensource.org/licenses/lgpl-license.html + * http://www.gnu.org/copyleft/lgpl.html + */ + +#ifndef __ASM_ARCH_MXC_PMIC_ADC_H__ +#define __ASM_ARCH_MXC_PMIC_ADC_H__ + +/*! + * @defgroup PMIC_ADC PMIC Digitizer Driver + * @ingroup PMIC_DRVRS + */ + +/*! + * @file arch-mxc/pmic_adc.h + * @brief This is the header of PMIC ADC driver. + * + * @ingroup PMIC_ADC + */ + +#include +#include +#include + +/*! + * @name IOCTL user space interface + */ + +/*! @{ */ +/*! + * Initialize ADC. + * Argument type: none. + */ +#define PMIC_ADC_INIT _IO('p', 0xb0) +/*! + * De-initialize ADC. + * Argument type: none. + */ +#define PMIC_ADC_DEINIT _IO('p', 0xb1) +/*! + * Convert one channel. + * Argument type: pointer to t_adc_convert_param. + */ +#define PMIC_ADC_CONVERT _IOWR('p', 0xb2, int) +/*! + * Convert one channel eight samples. + * Argument type: pointer to t_adc_convert_param. + */ +#define PMIC_ADC_CONVERT_8X _IOWR('p', 0xb3, int) +/*! + * Convert multiple channels. + * Argument type: pointer to t_adc_convert_param. + */ +#define PMIC_ADC_CONVERT_MULTICHANNEL _IOWR('p', 0xb4, int) +/*! + * Set touch screen operation mode. + * Argument type: t_touch_mode. + */ +#define PMIC_ADC_SET_TOUCH_MODE _IOW('p', 0xb5, int) +/*! + * Get touch screen operation mode. + * Argument type: pointer to t_touch_mode. + */ +#define PMIC_ADC_GET_TOUCH_MODE _IOR('p', 0xb6, int) +/*! + * Get touch screen sample. + * Argument type: pointer to t_touch_sample. + */ +#define PMIC_ADC_GET_TOUCH_SAMPLE _IOWR('p', 0xb7, int) +/*! + * Get battery current. + * Argument type: pointer to unsigned short. + */ +#define PMIC_ADC_GET_BATTERY_CURRENT _IOR('p', 0xb8, int) +/*! + * Activate comparator. + * Argument type: pointer to t_adc_comp_param. + */ +#define PMIC_ADC_ACTIVATE_COMPARATOR _IOW('p', 0xb9, int) +/*! + * De-active comparator. + * Argument type: none. + */ +#define PMIC_ADC_DEACTIVE_COMPARATOR _IOW('p', 0xba, int) + +/*! + * Install touch screen read interface. + */ +#define TOUCH_SCREEN_READ_INSTALL _IOWR('D',4, int) +/*! + * Remove touch screen read interface. + */ +#define TOUCH_SCREEN_READ_UNINSTALL _IOWR('D',5, int) + +/*! @{ */ +/*! + * @name Touch Screen minimum and maximum values + */ +#define TS_X_MIN 80 /*! < Minimum X */ +#define TS_Y_MIN 80 /*! < Minimum Y */ + +#define TS_X_MAX 1000 /*! < Maximum X */ +#define TS_Y_MAX 1000 /*! < Maximum Y */ +/*! @} */ +/*! + * This enumeration defines input channels for PMIC ADC + */ + +typedef enum { + BATTERY_VOLTAGE, + BATTERY_CURRENT, + CHARGE_VOLTAGE, + CHARGE_CURRENT, + APPLICATION_SUPPLY, + TS_X_POS1, + TS_X_POS2, + TS_Y_POS1, + TS_Y_POS2, + GEN_PURPOSE_AD4, + GEN_PURPOSE_AD5, + GEN_PURPOSE_AD6, + GEN_PURPOSE_AD7, + GEN_PURPOSE_AD8, + GEN_PURPOSE_AD9, + GEN_PURPOSE_AD10, + GEN_PURPOSE_AD11, + USB_ID, + LICELL, + RAWEXTBPLUSSENSE, + MPBSENSE, + BATSENSE, + GND, + THERMISTOR, + DIE_TEMP +} t_channel; + +/*! + * This enumeration defines reason of ADC Comparator interrupt. + */ +typedef enum { + /*! + * Greater than WHIGH + */ + GTWHIGH, + /*! + * Less than WLOW + */ + LTWLOW, +} t_comp_exception; + +/*! + * ADC comparator callback function type + */ +typedef void (*t_comparator_cb) (t_comp_exception reason); + +/*! + * This enumeration defines the touch screen operation modes. + */ +typedef enum { + /*! + * Touch Screen X position + */ + TS_X_POSITION = 0, + /*! + * Touch Screen Y position + */ + TS_Y_POSITION = 1, + /*! + * Pressure + */ + TS_PRESSURE = 2, + /*! + * Plate X + */ + TS_PLATE_X = 3, + /*! + * Plate Y + */ + TS_PLATE_Y = 4, + /*! + * Standby + */ + TS_STANDBY = 5, + /*! + * No touch screen, TSX1, TSX2, TSY1 and TSY2 are used as general + * purpose A/D inputs. + */ + TS_NONE = 6, +} t_touch_mode; +/*! + * This structure is used to report touch screen value. + */ +typedef struct { +/*! + * Touch Screen X position + */ + unsigned int x_position; + /*! + * Touch Screen X position1 + */ + unsigned int x_position1; + /*! + * Touch Screen X position2 + */ + unsigned int x_position2; + /*! + * Touch Screen X position3 + */ + unsigned int x_position3; + /*! + * Touch Screen Y position + */ + unsigned int y_position; + /*! + * Touch Screen Y position1 + */ + unsigned int y_position1; + /*! + * Touch Screen Y position2 + */ + unsigned int y_position2; + /*! + * Touch Screen Y position3 + */ + unsigned int y_position3; + /*! + * Touch Screen contact value + */ + unsigned int contact_resistance; +} t_touch_screen; + +/*! + * This enumeration defines ADC conversion modes. + */ +typedef enum { + /*! + * Sample 8 channels, 1 sample per channel + */ + ADC_8CHAN_1X = 0, + /*! + * Sample 1 channel 8 times + */ + ADC_1CHAN_8X, +} t_conversion_mode; + +/*! + * This structure is used with IOCTL code \a PMIC_ADC_CONVERT, + * \a PMIC_ADC_CONVERT_8X and \a PMIC_ADC_CONVERT_MULTICHANNEL. + */ + +typedef struct { + /*! + * channel or channels to be sampled. + */ + t_channel channel; + /*! + * holds up to 16 sampling results + */ + unsigned short result[16]; +} t_adc_convert_param; + +/*! + * This structure is used to activate/deactivate ADC comparator. + */ +typedef struct { + /*! + * wlow. + */ + unsigned char wlow; + /*! + * whigh. + */ + unsigned char whigh; + /*! + * channel to monitor + */ + t_channel channel; + /*! + * callback function. + */ + t_comparator_cb callback; +} t_adc_comp_param; + +/* EXPORTED FUNCTIONS */ + +#ifdef __KERNEL__ +/*! + * This function initializes all ADC registers with default values. This + * function also registers the interrupt events. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_adc_init(void); + +/*! + * This function disables the ADC, de-registers the interrupt events. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_adc_deinit(void); + +/*! + * This function triggers a conversion and returns one sampling result of one + * channel. + * + * @param channel The channel to be sampled + * @param result The pointer to the conversion result. The memory + * should be allocated by the caller of this function. + * + * @return This function returns PMIC_SUCCESS if successful. + */ + +PMIC_STATUS pmic_adc_convert(t_channel channel, unsigned short *result); + +/*! + * This function triggers a conversion and returns eight sampling results of + * one channel. + * + * @param channel The channel to be sampled + * @param result The pointer to array to store eight sampling results. + * The memory should be allocated by the caller of this + * function. + * + * @return This function returns PMIC_SUCCESS if successful. + */ + +PMIC_STATUS pmic_adc_convert_8x(t_channel channel, unsigned short *result); + +/*! + * This function triggers a conversion and returns sampling results of each + * specified channel. + * + * @param channels This input parameter is bitmap to specify channels + * to be sampled. + * @param result The pointer to array to store sampling result. + * The order of the result in the array is from lowest + * channel number to highest channel number of the + * sampled channels. + * The memory should be allocated by the caller of this + * function. + * Note that the behavior of this function might differ + * from one platform to another regarding especially + * channels order. + * + * @return This function returns PMIC_SUCCESS if successful. + */ + +PMIC_STATUS pmic_adc_convert_multichnnel(t_channel channels, + unsigned short *result); + +/*! + * This function sets touch screen operation mode. + * + * @param touch_mode Touch screen operation mode. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_adc_set_touch_mode(t_touch_mode touch_mode); + +/*! + * This function retrieves the current touch screen operation mode. + * + * @param touch_mode Pointer to the retrieved touch screen operation + * mode. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_adc_get_touch_mode(t_touch_mode * touch_mode); + +/*! + * This function retrieves the current touch screen operation mode. + * + * @param touch_sample Pointer to touch sample. + * @param wait Indicates if this function needs to block or not. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_adc_get_touch_sample(t_touch_screen * ts_value, int wait); + +/*! + * This function starts a Battery Current mode conversion. + * + * @param mode Conversion mode. + * @param result Battery Current measurement result. + * if \a mode = ADC_8CHAN_1X, the result is \n + * result[0] = (BATTP - BATT_I) \n + * if \a mode = ADC_1CHAN_8X, the result is \n + * result[0] = BATTP \n + * result[1] = BATT_I \n + * result[2] = BATTP \n + * result[3] = BATT_I \n + * result[4] = BATTP \n + * result[5] = BATT_I \n + * result[6] = BATTP \n + * result[7] = BATT_I + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_adc_get_battery_current(t_conversion_mode mode, + unsigned short *result); + +/*! + * This function actives the comparator. When comparator is activated and ADC + * is enabled, the 8th converted value will be digitally compared against the + * window defined by WLOW and WHIGH registers. + * + * @param low Comparison window low threshold (WLOW). + * @param high Comparison window high threshold (WHIGH). + * @param callback Callback function to be called when the converted + * value is beyond the comparison window. The callback + * function will pass a parameter of type + * \b t_comp_expection to indicate the reason of + * comparator exception. + * + * @return This function returns PMIC_SUCCESS if successful. + */ + +PMIC_STATUS pmic_adc_active_comparator(unsigned char low, + unsigned char high, + t_channel channel, + t_comparator_cb callback); + +/*! + * This function de-actives the comparator. + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_adc_deactive_comparator(void); + +/*! + * This function enables the touch screen read interface. + * + * @return This function returns 0 if successful. + */ +PMIC_STATUS pmic_adc_install_ts(void); + +/*! + * This function disables the touch screen read interface. + * + * @return This function returns 0 if successful. + */ +PMIC_STATUS pmic_adc_remove_ts(void); + +int is_pmic_adc_ready(void); + +#endif /* _KERNEL */ +#endif /* __ASM_ARCH_MXC_PMIC_ADC_H__ */ --- linux-2.6.28.orig/include/linux/compat.h +++ linux-2.6.28/include/linux/compat.h @@ -280,5 +280,18 @@ asmlinkage long compat_sys_timerfd_gettime(int ufd, struct compat_itimerspec __user *otmr); +asmlinkage long compat_sys_move_pages(pid_t pid, unsigned long nr_page, + __u32 __user *pages, + const int __user *nodes, + int __user *status, + int flags); +asmlinkage long compat_sys_futimesat(unsigned int dfd, char __user *filename, + struct compat_timeval __user *t); +asmlinkage long compat_sys_newfstatat(unsigned int dfd, char __user * filename, + struct compat_stat __user *statbuf, + int flag); +asmlinkage long compat_sys_openat(unsigned int dfd, const char __user *filename, + int flags, int mode); + #endif /* CONFIG_COMPAT */ #endif /* _LINUX_COMPAT_H */ --- linux-2.6.28.orig/include/linux/pci.h +++ linux-2.6.28/include/linux/pci.h @@ -651,7 +651,7 @@ void pci_disable_rom(struct pci_dev *pdev); void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size); void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom); -size_t pci_get_rom_size(void __iomem *rom, size_t size); +size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size); /* Power management related routines */ int pci_save_state(struct pci_dev *dev); --- linux-2.6.28.orig/include/linux/pci_ids.h +++ linux-2.6.28/include/linux/pci_ids.h @@ -1312,6 +1312,7 @@ #define PCI_DEVICE_ID_VIA_VT3351 0x0351 #define PCI_DEVICE_ID_VIA_VT3364 0x0364 #define PCI_DEVICE_ID_VIA_8371_0 0x0391 +#define PCI_DEVICE_ID_VIA_6415 0x0415 #define PCI_DEVICE_ID_VIA_8501_0 0x0501 #define PCI_DEVICE_ID_VIA_82C561 0x0561 #define PCI_DEVICE_ID_VIA_82C586_1 0x0571 @@ -1357,6 +1358,7 @@ #define PCI_DEVICE_ID_VIA_8783_0 0x3208 #define PCI_DEVICE_ID_VIA_8237 0x3227 #define PCI_DEVICE_ID_VIA_8251 0x3287 +#define PCI_DEVICE_ID_VIA_8261 0x3402 #define PCI_DEVICE_ID_VIA_8237A 0x3337 #define PCI_DEVICE_ID_VIA_8237S 0x3372 #define PCI_DEVICE_ID_VIA_SATA_EIDE 0x5324 @@ -1366,10 +1368,13 @@ #define PCI_DEVICE_ID_VIA_CX700 0x8324 #define PCI_DEVICE_ID_VIA_CX700_IDE 0x0581 #define PCI_DEVICE_ID_VIA_VX800 0x8353 +#define PCI_DEVICE_ID_VIA_VX855 0x8409 #define PCI_DEVICE_ID_VIA_8371_1 0x8391 #define PCI_DEVICE_ID_VIA_82C598_1 0x8598 #define PCI_DEVICE_ID_VIA_838X_1 0xB188 #define PCI_DEVICE_ID_VIA_83_87XX_1 0xB198 +#define PCI_DEVICE_ID_VIA_C409_IDE 0XC409 +#define PCI_DEVICE_ID_VIA_ANON 0xFFFF #define PCI_VENDOR_ID_SIEMENS 0x110A #define PCI_DEVICE_ID_SIEMENS_DSCC4 0x2102 @@ -1440,6 +1445,7 @@ #define PCI_DEVICE_ID_DIGI_DF_M_E 0x0071 #define PCI_DEVICE_ID_DIGI_DF_M_IOM2_A 0x0072 #define PCI_DEVICE_ID_DIGI_DF_M_A 0x0073 +#define PCI_DEVICE_ID_DIGI_NEO_8 0x00B1 #define PCI_DEVICE_ID_NEO_2DB9 0x00C8 #define PCI_DEVICE_ID_NEO_2DB9PRI 0x00C9 #define PCI_DEVICE_ID_NEO_2RJ45 0x00CA @@ -1766,6 +1772,7 @@ #define PCI_DEVICE_ID_SIIG_8S_20x_650 0x2081 #define PCI_DEVICE_ID_SIIG_8S_20x_850 0x2082 #define PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL 0x2050 +#define PCI_SUBDEVICE_ID_SIIG_DUAL_SERIAL 0x2530 #define PCI_VENDOR_ID_RADISYS 0x1331 @@ -1795,6 +1802,7 @@ #define PCI_DEVICE_ID_SEALEVEL_UCOMM232 0x7202 #define PCI_DEVICE_ID_SEALEVEL_COMM4 0x7401 #define PCI_DEVICE_ID_SEALEVEL_COMM8 0x7801 +#define PCI_DEVICE_ID_SEALEVEL_7803 0x7803 #define PCI_DEVICE_ID_SEALEVEL_UCOMM8 0x7804 #define PCI_VENDOR_ID_HYPERCOPE 0x1365 @@ -2171,6 +2179,7 @@ #define PCI_DEVICE_ID_RDC_R6040 0x6040 #define PCI_DEVICE_ID_RDC_R6060 0x6060 #define PCI_DEVICE_ID_RDC_R6061 0x6061 +#define PCI_DEVICE_ID_RDC_D1010 0x1010 #define PCI_VENDOR_ID_LENOVO 0x17aa @@ -2309,6 +2318,9 @@ #define PCI_DEVICE_ID_INTEL_82378 0x0484 #define PCI_DEVICE_ID_INTEL_I960 0x0960 #define PCI_DEVICE_ID_INTEL_I960RM 0x0962 +#define PCI_DEVICE_ID_INTEL_8257X_SOL 0x1062 +#define PCI_DEVICE_ID_INTEL_82573E_SOL 0x1085 +#define PCI_DEVICE_ID_INTEL_82573L_SOL 0x108F #define PCI_DEVICE_ID_INTEL_82815_MC 0x1130 #define PCI_DEVICE_ID_INTEL_82815_CGC 0x1132 #define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221 @@ -2412,6 +2424,7 @@ #define PCI_DEVICE_ID_INTEL_ICH7_0 0x27b8 #define PCI_DEVICE_ID_INTEL_ICH7_1 0x27b9 #define PCI_DEVICE_ID_INTEL_ICH7_30 0x27b0 +#define PCI_DEVICE_ID_INTEL_TGP_LPC 0x27bc #define PCI_DEVICE_ID_INTEL_ICH7_31 0x27bd #define PCI_DEVICE_ID_INTEL_ICH7_17 0x27da #define PCI_DEVICE_ID_INTEL_ICH7_19 0x27dd --- linux-2.6.28.orig/include/linux/connector.h +++ linux-2.6.28/include/linux/connector.h @@ -39,8 +39,10 @@ #define CN_IDX_V86D 0x4 #define CN_VAL_V86D_UVESAFB 0x1 #define CN_IDX_BB 0x5 /* BlackBoard, from the TSP GPL sampling framework */ +#define CN_IDX_DRBD 0x6 +#define CN_VAL_DRBD 0x1 -#define CN_NETLINK_USERS 6 +#define CN_NETLINK_USERS 7 /* * Maximum connector's message size. --- linux-2.6.28.orig/include/linux/time.h +++ linux-2.6.28/include/linux/time.h @@ -105,6 +105,7 @@ extern int update_persistent_clock(struct timespec now); extern int no_sync_cmos_clock __read_mostly; void timekeeping_init(void); +extern int timekeeping_suspended; unsigned long get_seconds(void); struct timespec current_kernel_time(void); --- linux-2.6.28.orig/include/linux/mxc_v4l2.h +++ linux-2.6.28/include/linux/mxc_v4l2.h @@ -0,0 +1,42 @@ +/* + * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU Lesser General + * Public License. You may obtain a copy of the GNU Lesser General + * Public License Version 2.1 or later at the following locations: + * + * http://www.opensource.org/licenses/lgpl-license.html + * http://www.gnu.org/copyleft/lgpl.html + */ + +/*! + * @file arch-mxc/mxc_v4l2.h + * + * @brief mxc V4L2 private structures + * + * @ingroup MXC_V4L2_CAPTURE + */ + +#ifndef __ASM_ARCH_MXC_V4L2_H__ +#define __ASM_ARCH_MXC_V4L2_H__ + +#define V4L2_CID_MXC_ROT (V4L2_CID_PRIVATE_BASE + 0) +#define V4L2_CID_MXC_FLASH (V4L2_CID_PRIVATE_BASE + 1) + +#define V4L2_MXC_ROTATE_NONE 0 +#define V4L2_MXC_ROTATE_VERT_FLIP 1 +#define V4L2_MXC_ROTATE_HORIZ_FLIP 2 +#define V4L2_MXC_ROTATE_180 3 +#define V4L2_MXC_ROTATE_90_RIGHT 4 +#define V4L2_MXC_ROTATE_90_RIGHT_VFLIP 5 +#define V4L2_MXC_ROTATE_90_RIGHT_HFLIP 6 +#define V4L2_MXC_ROTATE_90_LEFT 7 + +struct v4l2_mxc_offset { + uint32_t u_offset; + uint32_t v_offset; +}; + +#endif --- linux-2.6.28.orig/include/linux/mmc/host.h +++ linux-2.6.28/include/linux/mmc/host.h @@ -41,6 +41,7 @@ #define MMC_BUS_WIDTH_1 0 #define MMC_BUS_WIDTH_4 2 +#define MMC_BUS_WIDTH_8 3 unsigned char timing; /* timing specification used */ @@ -116,6 +117,7 @@ #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 */ +#define MMC_CAP_8_BIT_DATA (1 << 6) /* Can the host do 8 bit transfers */ /* host specific block data */ unsigned int max_seg_size; /* see blk_queue_max_segment_size */ --- linux-2.6.28.orig/include/linux/netfilter/Kbuild +++ linux-2.6.28/include/linux/netfilter/Kbuild @@ -31,6 +31,8 @@ header-y += xt_owner.h header-y += xt_pkttype.h header-y += xt_rateest.h +header-y += xt_policy.h +header-y += xt_quota.h header-y += xt_realm.h header-y += xt_recent.h header-y += xt_sctp.h --- linux-2.6.28.orig/include/linux/netfilter_ipv6/Kbuild +++ linux-2.6.28/include/linux/netfilter_ipv6/Kbuild @@ -11,6 +11,7 @@ header-y += ip6t_limit.h header-y += ip6t_mac.h header-y += ip6t_mark.h +header-y += ip6t_mh.h header-y += ip6t_multiport.h header-y += ip6t_opts.h header-y += ip6t_owner.h --- linux-2.6.28.orig/include/linux/usb/fsl_xcvr.h +++ linux-2.6.28/include/linux/usb/fsl_xcvr.h @@ -0,0 +1,44 @@ +#ifndef __LINUX_USB_FSL_XCVR_H +#define __LINUX_USB_FSL_XCVR_H +#include +#include + +struct fsl_usb2_platform_data; + +enum usb_test_mode{ + USB_TEST_J = 1, + USB_TEST_K = 2, +}; + +/** + * @name: transceiver name + * @xcvr_type: one of PORTSC_PTS_{UTMI,SERIAL,ULPI} + * @init: transceiver- and board-specific initialization function + * @uninit: transceiver- and board-specific uninitialization function + * @set_host: + * @set_device: + * @pullup: enable or disable D+ pullup + * + */ +struct fsl_xcvr_ops { + char *name; + u32 xcvr_type; + + void (*init)(struct fsl_xcvr_ops *ops); + void (*uninit)(struct fsl_xcvr_ops *ops); + void (*suspend)(struct fsl_xcvr_ops *ops); + void (*set_host)(void); + void (*set_device)(void); + void (*set_vbus_power)(struct fsl_xcvr_ops *ops, + struct fsl_usb2_platform_data *pdata, int on); + void (*set_remote_wakeup)(u32 *view); + void (*pullup)(int on); + void(*set_test_mode)(u32 *view, enum usb_test_mode mode); +}; + +struct fsl_xcvr_power { + struct platform_device *usb_pdev; + struct regulator *regu1; + struct regulator *regu2; +}; +#endif --- linux-2.6.28.orig/include/linux/mfd/mc13892/core.h +++ linux-2.6.28/include/linux/mfd/mc13892/core.h @@ -0,0 +1,77 @@ +/* + * Copyright 2009 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 __LINUX_MFD_MC13892_CORE_H_ +#define __LINUX_MFD_MC13892_CORE_H_ + +#include +#include +#include + +#define MC13892_SW1 0 +#define MC13892_SW2 1 +#define MC13892_SW3 2 +#define MC13892_SW4 3 +#define MC13892_SWBST 4 +#define MC13892_VIOHI 5 +#define MC13892_VPLL 6 +#define MC13892_VDIG 7 +#define MC13892_VSD 8 +#define MC13892_VUSB2 9 +#define MC13892_VVIDEO 10 +#define MC13892_VAUDIO 11 +#define MC13892_VCAM 12 +#define MC13892_VGEN1 13 +#define MC13892_VGEN2 14 +#define MC13892_VGEN3 15 +#define MC13892_VUSB 16 +#define MC13892_GPO1 17 +#define MC13892_GPO2 18 +#define MC13892_GPO3 19 +#define MC13892_GPO4 20 +#define MC13892_PWGT1 21 +#define MC13892_PWGT2 22 +#define MC13892_REG_NUM 23 + +struct mc13892; +struct regulator_init_data; + +struct mc13892_platform_data { + int (*init)(struct mc13892 *); +}; + +struct mc13892_pmic { + /* regulator devices */ + struct platform_device *pdev[MC13892_REG_NUM]; +}; + +struct mc13892 { + int rev; /* chip revision */ + + struct device *dev; + + /* device IO */ + union { + struct i2c_client *i2c_client; + struct spi_device *spi_device; + }; + u16 *reg_cache; + + /* Client devices */ + struct mc13892_pmic pmic; +}; + +int mc13892_register_regulator(struct mc13892 *mc13892, int reg, + struct regulator_init_data *initdata); + +#endif --- linux-2.6.28.orig/include/linux/nfsd/nfsd.h +++ linux-2.6.28/include/linux/nfsd/nfsd.h @@ -86,7 +86,8 @@ #ifdef CONFIG_NFSD_V4 __be32 nfsd4_set_nfs4_acl(struct svc_rqst *, struct svc_fh *, struct nfs4_acl *); -int nfsd4_get_nfs4_acl(struct svc_rqst *, struct dentry *, struct nfs4_acl **); +int nfsd4_get_nfs4_acl(struct svc_rqst *, struct dentry *, + struct vfsmount *mnt, struct nfs4_acl **); #endif /* CONFIG_NFSD_V4 */ __be32 nfsd_create(struct svc_rqst *, struct svc_fh *, char *name, int len, struct iattr *attrs, --- linux-2.6.28.orig/include/acpi/pdc_intel.h +++ linux-2.6.28/include/acpi/pdc_intel.h @@ -14,6 +14,7 @@ #define ACPI_PDC_SMP_T_SWCOORD (0x0080) #define ACPI_PDC_C_C1_FFH (0x0100) #define ACPI_PDC_C_C2C3_FFH (0x0200) +#define ACPI_PDC_SMP_P_HWCOORD (0x0800) #define ACPI_PDC_EST_CAPABILITY_SMP (ACPI_PDC_SMP_C1PT | \ ACPI_PDC_C_C1_HALT | \ @@ -22,6 +23,7 @@ #define ACPI_PDC_EST_CAPABILITY_SWSMP (ACPI_PDC_SMP_C1PT | \ ACPI_PDC_C_C1_HALT | \ ACPI_PDC_SMP_P_SWCOORD | \ + ACPI_PDC_SMP_P_HWCOORD | \ ACPI_PDC_P_FFH) #define ACPI_PDC_C_CAPABILITY_SMP (ACPI_PDC_SMP_C2C3 | \ --- linux-2.6.28.orig/include/net/sock.h +++ linux-2.6.28/include/net/sock.h @@ -784,7 +784,6 @@ static inline void sk_wmem_free_skb(struct sock *sk, struct sk_buff *skb) { - skb_truesize_check(skb); sock_set_flag(sk, SOCK_QUEUE_SHRUNK); sk->sk_wmem_queued -= skb->truesize; sk_mem_uncharge(sk, skb->truesize); --- linux-2.6.28.orig/include/net/ieee80211.h +++ linux-2.6.28/include/net/ieee80211.h @@ -1253,6 +1253,9 @@ extern void free_ieee80211(struct net_device *dev); extern struct net_device *alloc_ieee80211(int sizeof_priv); +extern void ieee80211_networks_age(struct ieee80211_device *ieee, + unsigned long age_secs); + extern int ieee80211_set_encryption(struct ieee80211_device *ieee); /* ieee80211_tx.c */ --- linux-2.6.28.orig/include/net/sctp/checksum.h +++ linux-2.6.28/include/net/sctp/checksum.h @@ -79,5 +79,5 @@ static inline __be32 sctp_end_cksum(__be32 crc32) { - return ~crc32; + return (__force __be32)~cpu_to_le32((__force u32)crc32); } --- linux-2.6.28.orig/fs/open.c +++ linux-2.6.28/fs/open.c @@ -30,6 +30,10 @@ #include #include +#include + +DECLARE_TRACE(do_sys_open); + int vfs_statfs(struct dentry *dentry, struct kstatfs *buf) { int retval = -ENODEV; @@ -122,7 +126,7 @@ return 0; } -asmlinkage long sys_statfs(const char __user *pathname, struct statfs __user * buf) +SYSCALL_DEFINE2(statfs, const char __user *, pathname, struct statfs __user *, buf) { struct path path; int error; @@ -138,8 +142,7 @@ return error; } - -asmlinkage long sys_statfs64(const char __user *pathname, size_t sz, struct statfs64 __user *buf) +SYSCALL_DEFINE3(statfs64, const char __user *, pathname, size_t, sz, struct statfs64 __user *, buf) { struct path path; long error; @@ -157,8 +160,7 @@ return error; } - -asmlinkage long sys_fstatfs(unsigned int fd, struct statfs __user * buf) +SYSCALL_DEFINE2(fstatfs, unsigned int, fd, struct statfs __user *, buf) { struct file * file; struct statfs tmp; @@ -176,7 +178,7 @@ return error; } -asmlinkage long sys_fstatfs64(unsigned int fd, size_t sz, struct statfs64 __user *buf) +SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, size_t, sz, struct statfs64 __user *, buf) { struct file * file; struct statfs64 tmp; @@ -197,8 +199,8 @@ return error; } -int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, - struct file *filp) +int do_truncate(struct dentry *dentry, struct vfsmount *mnt, loff_t length, + unsigned int time_attrs, struct file *filp) { int err; struct iattr newattrs; @@ -209,16 +211,15 @@ newattrs.ia_size = length; newattrs.ia_valid = ATTR_SIZE | time_attrs; - if (filp) { - newattrs.ia_file = filp; + + if (filp) newattrs.ia_valid |= ATTR_FILE; - } /* Remove suid/sgid on truncate too */ newattrs.ia_valid |= should_remove_suid(dentry); mutex_lock(&dentry->d_inode->i_mutex); - err = notify_change(dentry, &newattrs); + err = fnotify_change(dentry, mnt, &newattrs, filp); mutex_unlock(&dentry->d_inode->i_mutex); return err; } @@ -251,7 +252,7 @@ if (error) goto dput_and_out; - error = inode_permission(inode, MAY_WRITE); + error = path_permission(&path, MAY_WRITE); if (error) goto mnt_drop_write_and_out; @@ -274,7 +275,7 @@ error = locks_verify_truncate(inode, NULL, length); if (!error) { DQUOT_INIT(inode); - error = do_truncate(path.dentry, length, 0, NULL); + error = do_truncate(path.dentry, path.mnt, length, 0, NULL); } put_write_and_out: @@ -287,7 +288,7 @@ return error; } -asmlinkage long sys_truncate(const char __user * path, unsigned long length) +SYSCALL_DEFINE2(truncate, const char __user *, path, unsigned long, length) { /* on 32-bit boxen it will cut the range 2^31--2^32-1 off */ return do_sys_truncate(path, (long)length); @@ -329,14 +330,15 @@ error = locks_verify_truncate(inode, file, length); if (!error) - error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file); + error = do_truncate(dentry, file->f_path.mnt, length, + ATTR_MTIME|ATTR_CTIME, file); out_putf: fput(file); out: return error; } -asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length) +SYSCALL_DEFINE2(ftruncate, unsigned int, fd, unsigned long, length) { long ret = do_sys_ftruncate(fd, length, 1); /* avoid REGPARM breakage on x86: */ @@ -346,21 +348,35 @@ /* LFS versions of truncate are only needed on 32 bit machines */ #if BITS_PER_LONG == 32 -asmlinkage long sys_truncate64(const char __user * path, loff_t length) +SYSCALL_DEFINE(truncate64)(const char __user * path, loff_t length) { return do_sys_truncate(path, length); } +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_truncate64(long path, loff_t length) +{ + return SYSC_truncate64((const char __user *) path, length); +} +SYSCALL_ALIAS(sys_truncate64, SyS_truncate64); +#endif -asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length) +SYSCALL_DEFINE(ftruncate64)(unsigned int fd, loff_t length) { long ret = do_sys_ftruncate(fd, length, 0); /* avoid REGPARM breakage on x86: */ asmlinkage_protect(2, ret, fd, length); return ret; } +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_ftruncate64(long fd, loff_t length) +{ + return SYSC_ftruncate64((unsigned int) fd, length); +} +SYSCALL_ALIAS(sys_ftruncate64, SyS_ftruncate64); #endif +#endif /* BITS_PER_LONG == 32 */ -asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len) +SYSCALL_DEFINE(fallocate)(int fd, int mode, loff_t offset, loff_t len) { struct file *file; struct inode *inode; @@ -417,13 +433,20 @@ out: return ret; } +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_fallocate(long fd, long mode, loff_t offset, loff_t len) +{ + return SYSC_fallocate((int)fd, (int)mode, offset, len); +} +SYSCALL_ALIAS(sys_fallocate, SyS_fallocate); +#endif /* * access() needs to use the real uid/gid, not the effective uid/gid. * We do this by temporarily clearing all FS-related capabilities and * switching the fsuid/fsgid around to the real ones. */ -asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode) +SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode) { struct path path; struct inode *inode; @@ -474,7 +497,7 @@ goto out_path_release; } - res = inode_permission(inode, mode | MAY_ACCESS); + res = path_permission(&path, mode | MAY_ACCESS); /* SuS v2 requires we report a read only fs too */ if (res || !(mode & S_IWOTH) || special_file(inode->i_mode)) goto out_path_release; @@ -503,12 +526,12 @@ return res; } -asmlinkage long sys_access(const char __user *filename, int mode) +SYSCALL_DEFINE2(access, const char __user *, filename, int, mode) { return sys_faccessat(AT_FDCWD, filename, mode); } -asmlinkage long sys_chdir(const char __user * filename) +SYSCALL_DEFINE1(chdir, const char __user *, filename) { struct path path; int error; @@ -517,7 +540,7 @@ if (error) goto out; - error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS); + error = path_permission(&path, MAY_EXEC | MAY_ACCESS); if (error) goto dput_and_out; @@ -529,7 +552,7 @@ return error; } -asmlinkage long sys_fchdir(unsigned int fd) +SYSCALL_DEFINE1(fchdir, unsigned int, fd) { struct file *file; struct inode *inode; @@ -546,7 +569,7 @@ if (!S_ISDIR(inode->i_mode)) goto out_putf; - error = inode_permission(inode, MAY_EXEC | MAY_ACCESS); + error = path_permission(&file->f_path, MAY_EXEC | MAY_ACCESS); if (!error) set_fs_pwd(current->fs, &file->f_path); out_putf: @@ -555,7 +578,7 @@ return error; } -asmlinkage long sys_chroot(const char __user * filename) +SYSCALL_DEFINE1(chroot, const char __user *, filename) { struct path path; int error; @@ -564,7 +587,7 @@ if (error) goto out; - error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS); + error = path_permission(&path, MAY_EXEC | MAY_ACCESS); if (error) goto dput_and_out; @@ -580,7 +603,7 @@ return error; } -asmlinkage long sys_fchmod(unsigned int fd, mode_t mode) +SYSCALL_DEFINE2(fchmod, unsigned int, fd, mode_t, mode) { struct inode * inode; struct dentry * dentry; @@ -604,8 +627,8 @@ if (mode == (mode_t) -1) mode = inode->i_mode; newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); - newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; - err = notify_change(dentry, &newattrs); + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME | ATTR_FILE; + err = fnotify_change(dentry, file->f_path.mnt, &newattrs, file); mutex_unlock(&inode->i_mutex); mnt_drop_write(file->f_path.mnt); out_putf: @@ -614,8 +637,7 @@ return err; } -asmlinkage long sys_fchmodat(int dfd, const char __user *filename, - mode_t mode) +SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, mode_t, mode) { struct path path; struct inode *inode; @@ -635,7 +657,7 @@ mode = inode->i_mode; newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; - error = notify_change(path.dentry, &newattrs); + error = notify_change(path.dentry, path.mnt, &newattrs); mutex_unlock(&inode->i_mutex); mnt_drop_write(path.mnt); dput_and_out: @@ -644,12 +666,13 @@ return error; } -asmlinkage long sys_chmod(const char __user *filename, mode_t mode) +SYSCALL_DEFINE2(chmod, const char __user *, filename, mode_t, mode) { return sys_fchmodat(AT_FDCWD, filename, mode); } -static int chown_common(struct dentry * dentry, uid_t user, gid_t group) +static int chown_common(struct dentry * dentry, struct vfsmount *mnt, + uid_t user, gid_t group, struct file *file) { struct inode *inode = dentry->d_inode; int error; @@ -667,14 +690,17 @@ if (!S_ISDIR(inode->i_mode)) newattrs.ia_valid |= ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; + if (file) + newattrs.ia_valid |= ATTR_FILE; + mutex_lock(&inode->i_mutex); - error = notify_change(dentry, &newattrs); + error = fnotify_change(dentry, mnt, &newattrs, file); mutex_unlock(&inode->i_mutex); return error; } -asmlinkage long sys_chown(const char __user * filename, uid_t user, gid_t group) +SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group) { struct path path; int error; @@ -685,7 +711,7 @@ error = mnt_want_write(path.mnt); if (error) goto out_release; - error = chown_common(path.dentry, user, group); + error = chown_common(path.dentry, path.mnt, user, group, NULL); mnt_drop_write(path.mnt); out_release: path_put(&path); @@ -693,8 +719,8 @@ return error; } -asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user, - gid_t group, int flag) +SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user, + gid_t, group, int, flag) { struct path path; int error = -EINVAL; @@ -710,7 +736,7 @@ error = mnt_want_write(path.mnt); if (error) goto out_release; - error = chown_common(path.dentry, user, group); + error = chown_common(path.dentry, path.mnt, user, group, NULL); mnt_drop_write(path.mnt); out_release: path_put(&path); @@ -718,7 +744,7 @@ return error; } -asmlinkage long sys_lchown(const char __user * filename, uid_t user, gid_t group) +SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group) { struct path path; int error; @@ -729,7 +755,7 @@ error = mnt_want_write(path.mnt); if (error) goto out_release; - error = chown_common(path.dentry, user, group); + error = chown_common(path.dentry, path.mnt, user, group, NULL); mnt_drop_write(path.mnt); out_release: path_put(&path); @@ -737,8 +763,7 @@ return error; } - -asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group) +SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group) { struct file * file; int error = -EBADF; @@ -753,7 +778,7 @@ goto out_fput; dentry = file->f_path.dentry; audit_inode(NULL, dentry); - error = chown_common(dentry, user, group); + error = chown_common(dentry, file->f_path.mnt, user, group, file); mnt_drop_write(file->f_path.mnt); out_fput: fput(file); @@ -1022,6 +1047,7 @@ } else { fsnotify_open(f->f_path.dentry); fd_install(fd, f); + trace_do_sys_open(f, flags, mode, fd); } } putname(tmp); @@ -1029,7 +1055,7 @@ return fd; } -asmlinkage long sys_open(const char __user *filename, int flags, int mode) +SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, int, mode) { long ret; @@ -1042,8 +1068,8 @@ return ret; } -asmlinkage long sys_openat(int dfd, const char __user *filename, int flags, - int mode) +SYSCALL_DEFINE4(openat, int, dfd, const char __user *, filename, int, flags, + int, mode) { long ret; @@ -1062,7 +1088,7 @@ * For backward compatibility? Maybe this should be moved * into arch/i386 instead? */ -asmlinkage long sys_creat(const char __user * pathname, int mode) +SYSCALL_DEFINE2(creat, const char __user *, pathname, int, mode) { return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode); } @@ -1098,7 +1124,7 @@ * releasing the fd. This ensures that one clone task can't release * an fd while another clone is opening it. */ -asmlinkage long sys_close(unsigned int fd) +SYSCALL_DEFINE1(close, unsigned int, fd) { struct file * filp; struct files_struct *files = current->files; @@ -1131,14 +1157,13 @@ spin_unlock(&files->file_lock); return -EBADF; } - EXPORT_SYMBOL(sys_close); /* * This routine simulates a hangup on the tty, to arrange that users * are given clean terminals at login time. */ -asmlinkage long sys_vhangup(void) +SYSCALL_DEFINE0(vhangup) { if (capable(CAP_SYS_TTY_CONFIG)) { tty_vhangup_self(); --- linux-2.6.28.orig/fs/stat.c +++ linux-2.6.28/fs/stat.c @@ -152,7 +152,7 @@ return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; } -asmlinkage long sys_stat(char __user * filename, struct __old_kernel_stat __user * statbuf) +SYSCALL_DEFINE2(stat, char __user *, filename, struct __old_kernel_stat __user *, statbuf) { struct kstat stat; int error = vfs_stat_fd(AT_FDCWD, filename, &stat); @@ -162,7 +162,8 @@ return error; } -asmlinkage long sys_lstat(char __user * filename, struct __old_kernel_stat __user * statbuf) + +SYSCALL_DEFINE2(lstat, char __user *, filename, struct __old_kernel_stat __user *, statbuf) { struct kstat stat; int error = vfs_lstat_fd(AT_FDCWD, filename, &stat); @@ -172,7 +173,8 @@ return error; } -asmlinkage long sys_fstat(unsigned int fd, struct __old_kernel_stat __user * statbuf) + +SYSCALL_DEFINE2(fstat, unsigned int, fd, struct __old_kernel_stat __user *, statbuf) { struct kstat stat; int error = vfs_fstat(fd, &stat); @@ -235,7 +237,7 @@ return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; } -asmlinkage long sys_newstat(char __user *filename, struct stat __user *statbuf) +SYSCALL_DEFINE2(newstat, char __user *, filename, struct stat __user *, statbuf) { struct kstat stat; int error = vfs_stat_fd(AT_FDCWD, filename, &stat); @@ -246,7 +248,7 @@ return error; } -asmlinkage long sys_newlstat(char __user *filename, struct stat __user *statbuf) +SYSCALL_DEFINE2(newlstat, char __user *, filename, struct stat __user *, statbuf) { struct kstat stat; int error = vfs_lstat_fd(AT_FDCWD, filename, &stat); @@ -258,8 +260,8 @@ } #if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT) -asmlinkage long sys_newfstatat(int dfd, char __user *filename, - struct stat __user *statbuf, int flag) +SYSCALL_DEFINE4(newfstatat, int, dfd, char __user *, filename, + struct stat __user *, statbuf, int, flag) { struct kstat stat; int error = -EINVAL; @@ -280,7 +282,7 @@ } #endif -asmlinkage long sys_newfstat(unsigned int fd, struct stat __user *statbuf) +SYSCALL_DEFINE2(newfstat, unsigned int, fd, struct stat __user *, statbuf) { struct kstat stat; int error = vfs_fstat(fd, &stat); @@ -291,8 +293,8 @@ return error; } -asmlinkage long sys_readlinkat(int dfd, const char __user *pathname, - char __user *buf, int bufsiz) +SYSCALL_DEFINE4(readlinkat, int, dfd, const char __user *, pathname, + char __user *, buf, int, bufsiz) { struct path path; int error; @@ -306,7 +308,7 @@ error = -EINVAL; if (inode->i_op && inode->i_op->readlink) { - error = security_inode_readlink(path.dentry); + error = security_inode_readlink(path.dentry, path.mnt); if (!error) { touch_atime(path.mnt, path.dentry); error = inode->i_op->readlink(path.dentry, @@ -318,8 +320,8 @@ return error; } -asmlinkage long sys_readlink(const char __user *path, char __user *buf, - int bufsiz) +SYSCALL_DEFINE3(readlink, const char __user *, path, char __user *, buf, + int, bufsiz) { return sys_readlinkat(AT_FDCWD, path, buf, bufsiz); } @@ -365,7 +367,7 @@ return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; } -asmlinkage long sys_stat64(char __user * filename, struct stat64 __user * statbuf) +SYSCALL_DEFINE2(stat64, char __user *, filename, struct stat64 __user *, statbuf) { struct kstat stat; int error = vfs_stat(filename, &stat); @@ -375,7 +377,8 @@ return error; } -asmlinkage long sys_lstat64(char __user * filename, struct stat64 __user * statbuf) + +SYSCALL_DEFINE2(lstat64, char __user *, filename, struct stat64 __user *, statbuf) { struct kstat stat; int error = vfs_lstat(filename, &stat); @@ -385,7 +388,8 @@ return error; } -asmlinkage long sys_fstat64(unsigned long fd, struct stat64 __user * statbuf) + +SYSCALL_DEFINE2(fstat64, unsigned long, fd, struct stat64 __user *, statbuf) { struct kstat stat; int error = vfs_fstat(fd, &stat); @@ -396,8 +400,8 @@ return error; } -asmlinkage long sys_fstatat64(int dfd, char __user *filename, - struct stat64 __user *statbuf, int flag) +SYSCALL_DEFINE4(fstatat64, int, dfd, char __user *, filename, + struct stat64 __user *, statbuf, int, flag) { struct kstat stat; int error = -EINVAL; --- linux-2.6.28.orig/fs/namespace.c +++ linux-2.6.28/fs/namespace.c @@ -1128,7 +1128,7 @@ * unixes. Our API is identical to OSF/1 to avoid making a mess of AMD */ -asmlinkage long sys_umount(char __user * name, int flags) +SYSCALL_DEFINE2(umount, char __user *, name, int, flags) { struct path path; int retval; @@ -1160,7 +1160,7 @@ /* * The 2.0 compatible umount. No flags. */ -asmlinkage long sys_oldumount(char __user * name) +SYSCALL_DEFINE1(oldumount, char __user *, name) { return sys_umount(name, 0); } @@ -2045,9 +2045,8 @@ return new_ns; } -asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name, - char __user * type, unsigned long flags, - void __user * data) +SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, + char __user *, type, unsigned long, flags, void __user *, data) { int retval; unsigned long data_page; @@ -2172,8 +2171,8 @@ * though, so you may need to say mount --bind /nfs/my_root /nfs/my_root * first. */ -asmlinkage long sys_pivot_root(const char __user * new_root, - const char __user * put_old) +SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, + const char __user *, put_old) { struct vfsmount *tmp; struct path new, old, parent_path, root_parent, root; @@ -2349,3 +2348,33 @@ release_mounts(&umount_list); kfree(ns); } + +char *d_namespace_path(struct dentry *dentry, struct vfsmount *vfsmnt, + char *buf, int buflen) +{ + struct path root, tmp, ns_root = { }; + struct path path = { .mnt = vfsmnt, .dentry = dentry }; + char *res; + + read_lock(¤t->fs->lock); + root = current->fs->root; + path_get(¤t->fs->root); + read_unlock(¤t->fs->lock); + spin_lock(&vfsmount_lock); + if (root.mnt) + ns_root.mnt = mntget(root.mnt->mnt_ns->root); + if (ns_root.mnt) + ns_root.dentry = dget(ns_root.mnt->mnt_root); + spin_unlock(&vfsmount_lock); + tmp = ns_root; + res = __d_path(&path, &tmp, buf, buflen, + D_PATH_FAIL_DELETED | D_PATH_DISCONNECT); + path_put(&root); + path_put(&ns_root); + + /* Prevent empty path for lazily unmounted filesystems. */ + if (!IS_ERR(res) && *res == '\0') + *--res = '.'; + return res; +} +EXPORT_SYMBOL(d_namespace_path); --- linux-2.6.28.orig/fs/fcntl.c +++ linux-2.6.28/fs/fcntl.c @@ -50,7 +50,7 @@ return res; } -asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags) +SYSCALL_DEFINE3(dup3, unsigned int, oldfd, unsigned int, newfd, int, flags) { int err = -EBADF; struct file * file, *tofree; @@ -113,7 +113,7 @@ return err; } -asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd) +SYSCALL_DEFINE2(dup2, unsigned int, oldfd, unsigned int, newfd) { if (unlikely(newfd == oldfd)) { /* corner case */ struct files_struct *files = current->files; @@ -126,7 +126,7 @@ return sys_dup3(oldfd, newfd, 0); } -asmlinkage long sys_dup(unsigned int fildes) +SYSCALL_DEFINE1(dup, unsigned int, fildes) { int ret = -EBADF; struct file *file = fget(fildes); @@ -334,7 +334,7 @@ return err; } -asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg) +SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) { struct file *filp; long err = -EBADF; @@ -357,7 +357,8 @@ } #if BITS_PER_LONG == 32 -asmlinkage long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg) +SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, + unsigned long, arg) { struct file * filp; long err; --- linux-2.6.28.orig/fs/libfs.c +++ linux-2.6.28/fs/libfs.c @@ -360,7 +360,7 @@ index = pos >> PAGE_CACHE_SHIFT; from = pos & (PAGE_CACHE_SIZE - 1); - page = __grab_cache_page(mapping, index); + page = grab_cache_page_write_begin(mapping, index, flags); if (!page) return -ENOMEM; --- linux-2.6.28.orig/fs/select.c +++ linux-2.6.28/fs/select.c @@ -507,8 +507,8 @@ return ret; } -asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp, - fd_set __user *exp, struct timeval __user *tvp) +SYSCALL_DEFINE5(select, int, n, fd_set __user *, inp, fd_set __user *, outp, + fd_set __user *, exp, struct timeval __user *, tvp) { struct timespec end_time, *to = NULL; struct timeval tv; @@ -532,9 +532,9 @@ } #ifdef HAVE_SET_RESTORE_SIGMASK -asmlinkage long sys_pselect7(int n, fd_set __user *inp, fd_set __user *outp, - fd_set __user *exp, struct timespec __user *tsp, - const sigset_t __user *sigmask, size_t sigsetsize) +static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp, + fd_set __user *exp, struct timespec __user *tsp, + const sigset_t __user *sigmask, size_t sigsetsize) { sigset_t ksigmask, sigsaved; struct timespec ts, end_time, *to = NULL; @@ -560,7 +560,7 @@ sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); } - ret = core_sys_select(n, inp, outp, exp, &end_time); + ret = core_sys_select(n, inp, outp, exp, to); ret = poll_select_copy_remaining(&end_time, tsp, 0, ret); if (ret == -ERESTARTNOHAND) { @@ -586,8 +586,9 @@ * which has a pointer to the sigset_t itself followed by a size_t containing * the sigset size. */ -asmlinkage long sys_pselect6(int n, fd_set __user *inp, fd_set __user *outp, - fd_set __user *exp, struct timespec __user *tsp, void __user *sig) +SYSCALL_DEFINE6(pselect6, int, n, fd_set __user *, inp, fd_set __user *, outp, + fd_set __user *, exp, struct timespec __user *, tsp, + void __user *, sig) { size_t sigsetsize = 0; sigset_t __user *up = NULL; @@ -600,7 +601,7 @@ return -EFAULT; } - return sys_pselect7(n, inp, outp, exp, tsp, up, sigsetsize); + return do_pselect(n, inp, outp, exp, tsp, up, sigsetsize); } #endif /* HAVE_SET_RESTORE_SIGMASK */ @@ -806,8 +807,8 @@ return ret; } -asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds, - long timeout_msecs) +SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds, + long, timeout_msecs) { struct timespec end_time, *to = NULL; int ret; @@ -841,9 +842,9 @@ } #ifdef HAVE_SET_RESTORE_SIGMASK -asmlinkage long sys_ppoll(struct pollfd __user *ufds, unsigned int nfds, - struct timespec __user *tsp, const sigset_t __user *sigmask, - size_t sigsetsize) +SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds, + struct timespec __user *, tsp, const sigset_t __user *, sigmask, + size_t, sigsetsize) { sigset_t ksigmask, sigsaved; struct timespec ts, end_time, *to = NULL; --- linux-2.6.28.orig/fs/readdir.c +++ linux-2.6.28/fs/readdir.c @@ -102,7 +102,8 @@ return -EFAULT; } -asmlinkage long old_readdir(unsigned int fd, struct old_linux_dirent __user * dirent, unsigned int count) +SYSCALL_DEFINE3(old_readdir, unsigned int, fd, + struct old_linux_dirent __user *, dirent, unsigned int, count) { int error; struct file * file; @@ -187,7 +188,8 @@ return -EFAULT; } -asmlinkage long sys_getdents(unsigned int fd, struct linux_dirent __user * dirent, unsigned int count) +SYSCALL_DEFINE3(getdents, unsigned int, fd, + struct linux_dirent __user *, dirent, unsigned int, count) { struct file * file; struct linux_dirent __user * lastdirent; @@ -268,7 +270,8 @@ return -EFAULT; } -asmlinkage long sys_getdents64(unsigned int fd, struct linux_dirent64 __user * dirent, unsigned int count) +SYSCALL_DEFINE3(getdents64, unsigned int, fd, + struct linux_dirent64 __user *, dirent, unsigned int, count) { struct file * file; struct linux_dirent64 __user * lastdirent; --- linux-2.6.28.orig/fs/locks.c +++ linux-2.6.28/fs/locks.c @@ -1564,7 +1564,7 @@ * %LOCK_MAND can be combined with %LOCK_READ or %LOCK_WRITE to allow other * processes read and write access respectively. */ -asmlinkage long sys_flock(unsigned int fd, unsigned int cmd) +SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd) { struct file *filp; struct file_lock *lock; --- linux-2.6.28.orig/fs/namei.c +++ linux-2.6.28/fs/namei.c @@ -226,7 +226,7 @@ return -EACCES; } -int inode_permission(struct inode *inode, int mask) +static int __inode_permission(struct inode *inode, int mask) { int retval; @@ -256,7 +256,12 @@ if (retval) return retval; - retval = devcgroup_inode_permission(inode, mask); + return devcgroup_inode_permission(inode, mask); +} + +int inode_permission(struct inode *inode, int mask) +{ + int retval = __inode_permission(inode, mask); if (retval) return retval; @@ -264,6 +269,15 @@ mask & (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND)); } +int path_permission(struct path *path, int mask) +{ + int retval = __inode_permission(path->dentry->d_inode, mask); + if (retval) + return retval; + return security_path_permission(path, + mask & (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND)); +} + /** * vfs_permission - check for access rights to a given path * @nd: lookup result that describes the path @@ -276,7 +290,7 @@ */ int vfs_permission(struct nameidata *nd, int mask) { - return inode_permission(nd->path.dentry->d_inode, mask); + return path_permission(&nd->path, mask); } /** @@ -293,7 +307,7 @@ */ int file_permission(struct file *file, int mask) { - return inode_permission(file->f_path.dentry->d_inode, mask); + return path_permission(&file->f_path, mask); } /* @@ -434,8 +448,9 @@ * short-cut DAC fails, then call permission() to do more * complete permission check. */ -static int exec_permission_lite(struct inode *inode) +static int exec_permission_lite(struct path *path) { + struct inode *inode = path->dentry->d_inode; umode_t mode = inode->i_mode; if (inode->i_op && inode->i_op->permission) @@ -460,7 +475,7 @@ return -EACCES; ok: - return security_inode_permission(inode, MAY_EXEC); + return security_path_permission(path, MAY_EXEC); } /* @@ -857,7 +872,7 @@ unsigned int c; nd->flags |= LOOKUP_CONTINUE; - err = exec_permission_lite(inode); + err = exec_permission_lite(&nd->path); if (err == -EAGAIN) err = vfs_permission(nd, MAY_EXEC); if (err) @@ -1052,24 +1067,21 @@ path_get(&fs->pwd); read_unlock(&fs->lock); } else { - struct dentry *dentry; - file = fget_light(dfd, &fput_needed); retval = -EBADF; if (!file) goto out_fail; - dentry = file->f_path.dentry; + nd->path = file->f_path; retval = -ENOTDIR; - if (!S_ISDIR(dentry->d_inode->i_mode)) + if (!S_ISDIR(nd->path.dentry->d_inode->i_mode)) goto fput_fail; retval = file_permission(file, MAY_EXEC); if (retval) goto fput_fail; - nd->path = file->f_path; path_get(&file->f_path); fput_light(file, fput_needed); @@ -1164,7 +1176,7 @@ return err; } -static struct dentry *__lookup_hash(struct qstr *name, +struct dentry *__lookup_hash(struct qstr *name, struct dentry *base, struct nameidata *nd) { struct dentry *dentry; @@ -1216,7 +1228,7 @@ { int err; - err = inode_permission(nd->path.dentry->d_inode, MAY_EXEC); + err = path_permission(&nd->path, MAY_EXEC); if (err) return ERR_PTR(err); return __lookup_hash(&nd->last, nd->path.dentry, nd); @@ -1481,7 +1493,7 @@ return -EACCES; /* shouldn't it be ENOSYS? */ mode &= S_IALLUGO; mode |= S_IFREG; - error = security_inode_create(dir, dentry, mode); + error = security_inode_create(dir, dentry, nd ? nd->path.mnt : NULL, mode); if (error) return error; DQUOT_INIT(dir); @@ -1557,7 +1569,7 @@ if (!error) { DQUOT_INIT(inode); - error = do_truncate(dentry, 0, + error = do_truncate(dentry, nd->path.mnt, 0, ATTR_MTIME|ATTR_CTIME|ATTR_OPEN, NULL); } @@ -1924,7 +1936,8 @@ } EXPORT_SYMBOL_GPL(lookup_create); -int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) +int vfs_mknod(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt, + int mode, dev_t dev) { int error = may_create(dir, dentry); @@ -1941,7 +1954,7 @@ if (error) return error; - error = security_inode_mknod(dir, dentry, mode, dev); + error = security_inode_mknod(dir, dentry, mnt, mode, dev); if (error) return error; @@ -1969,8 +1982,8 @@ } } -asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode, - unsigned dev) +SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, int, mode, + unsigned, dev) { int error; char *tmp; @@ -2002,11 +2015,12 @@ error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd); break; case S_IFCHR: case S_IFBLK: - error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode, - new_decode_dev(dev)); + error = vfs_mknod(nd.path.dentry->d_inode, dentry, + nd.path.mnt, mode, new_decode_dev(dev)); break; case S_IFIFO: case S_IFSOCK: - error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0); + error = vfs_mknod(nd.path.dentry->d_inode, dentry, + nd.path.mnt, mode, 0); break; } mnt_drop_write(nd.path.mnt); @@ -2020,12 +2034,13 @@ return error; } -asmlinkage long sys_mknod(const char __user *filename, int mode, unsigned dev) +SYSCALL_DEFINE3(mknod, const char __user *, filename, int, mode, unsigned, dev) { return sys_mknodat(AT_FDCWD, filename, mode, dev); } -int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) +int vfs_mkdir(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt, + int mode) { int error = may_create(dir, dentry); @@ -2036,7 +2051,7 @@ return -EPERM; mode &= (S_IRWXUGO|S_ISVTX); - error = security_inode_mkdir(dir, dentry, mode); + error = security_inode_mkdir(dir, dentry, mnt, mode); if (error) return error; @@ -2047,7 +2062,7 @@ return error; } -asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode) +SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, int, mode) { int error = 0; char * tmp; @@ -2068,7 +2083,7 @@ error = mnt_want_write(nd.path.mnt); if (error) goto out_dput; - error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); + error = vfs_mkdir(nd.path.dentry->d_inode, dentry, nd.path.mnt, mode); mnt_drop_write(nd.path.mnt); out_dput: dput(dentry); @@ -2080,7 +2095,7 @@ return error; } -asmlinkage long sys_mkdir(const char __user *pathname, int mode) +SYSCALL_DEFINE2(mkdir, const char __user *, pathname, int, mode) { return sys_mkdirat(AT_FDCWD, pathname, mode); } @@ -2112,7 +2127,7 @@ spin_unlock(&dcache_lock); } -int vfs_rmdir(struct inode *dir, struct dentry *dentry) +int vfs_rmdir(struct inode *dir, struct dentry *dentry,struct vfsmount *mnt) { int error = may_delete(dir, dentry, 1); @@ -2122,6 +2137,10 @@ if (!dir->i_op || !dir->i_op->rmdir) return -EPERM; + error = security_inode_rmdir(dir, dentry, mnt); + if (error) + return error; + DQUOT_INIT(dir); mutex_lock(&dentry->d_inode->i_mutex); @@ -2129,12 +2148,9 @@ if (d_mountpoint(dentry)) error = -EBUSY; else { - error = security_inode_rmdir(dir, dentry); - if (!error) { - error = dir->i_op->rmdir(dir, dentry); - if (!error) - dentry->d_inode->i_flags |= S_DEAD; - } + error = dir->i_op->rmdir(dir, dentry); + if (!error) + dentry->d_inode->i_flags |= S_DEAD; } mutex_unlock(&dentry->d_inode->i_mutex); if (!error) { @@ -2178,7 +2194,7 @@ error = mnt_want_write(nd.path.mnt); if (error) goto exit3; - error = vfs_rmdir(nd.path.dentry->d_inode, dentry); + error = vfs_rmdir(nd.path.dentry->d_inode, dentry, nd.path.mnt); mnt_drop_write(nd.path.mnt); exit3: dput(dentry); @@ -2190,12 +2206,12 @@ return error; } -asmlinkage long sys_rmdir(const char __user *pathname) +SYSCALL_DEFINE1(rmdir, const char __user *, pathname) { return do_rmdir(AT_FDCWD, pathname); } -int vfs_unlink(struct inode *dir, struct dentry *dentry) +int vfs_unlink(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt) { int error = may_delete(dir, dentry, 0); @@ -2211,7 +2227,7 @@ if (d_mountpoint(dentry)) error = -EBUSY; else { - error = security_inode_unlink(dir, dentry); + error = security_inode_unlink(dir, dentry, mnt); if (!error) error = dir->i_op->unlink(dir, dentry); } @@ -2263,7 +2279,7 @@ error = mnt_want_write(nd.path.mnt); if (error) goto exit2; - error = vfs_unlink(nd.path.dentry->d_inode, dentry); + error = vfs_unlink(nd.path.dentry->d_inode, dentry, nd.path.mnt); mnt_drop_write(nd.path.mnt); exit2: dput(dentry); @@ -2282,7 +2298,7 @@ goto exit2; } -asmlinkage long sys_unlinkat(int dfd, const char __user *pathname, int flag) +SYSCALL_DEFINE3(unlinkat, int, dfd, const char __user *, pathname, int, flag) { if ((flag & ~AT_REMOVEDIR) != 0) return -EINVAL; @@ -2293,12 +2309,13 @@ return do_unlinkat(dfd, pathname); } -asmlinkage long sys_unlink(const char __user *pathname) +SYSCALL_DEFINE1(unlink, const char __user *, pathname) { return do_unlinkat(AT_FDCWD, pathname); } -int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) +int vfs_symlink(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt, + const char *oldname) { int error = may_create(dir, dentry); @@ -2308,7 +2325,7 @@ if (!dir->i_op || !dir->i_op->symlink) return -EPERM; - error = security_inode_symlink(dir, dentry, oldname); + error = security_inode_symlink(dir, dentry, mnt, oldname); if (error) return error; @@ -2319,8 +2336,8 @@ return error; } -asmlinkage long sys_symlinkat(const char __user *oldname, - int newdfd, const char __user *newname) +SYSCALL_DEFINE3(symlinkat, const char __user *, oldname, + int, newdfd, const char __user *, newname) { int error; char *from; @@ -2344,7 +2361,7 @@ error = mnt_want_write(nd.path.mnt); if (error) goto out_dput; - error = vfs_symlink(nd.path.dentry->d_inode, dentry, from); + error = vfs_symlink(nd.path.dentry->d_inode, dentry, nd.path.mnt, from); mnt_drop_write(nd.path.mnt); out_dput: dput(dentry); @@ -2357,12 +2374,12 @@ return error; } -asmlinkage long sys_symlink(const char __user *oldname, const char __user *newname) +SYSCALL_DEFINE2(symlink, const char __user *, oldname, const char __user *, newname) { return sys_symlinkat(oldname, AT_FDCWD, newname); } -int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) +int vfs_link(struct dentry *old_dentry, struct vfsmount *old_mnt, struct inode *dir, struct dentry *new_dentry, struct vfsmount *new_mnt) { struct inode *inode = old_dentry->d_inode; int error; @@ -2387,7 +2404,8 @@ if (S_ISDIR(inode->i_mode)) return -EPERM; - error = security_inode_link(old_dentry, dir, new_dentry); + error = security_inode_link(old_dentry, old_mnt, dir, new_dentry, + new_mnt); if (error) return error; @@ -2409,9 +2427,8 @@ * with linux 2.0, and to avoid hard-linking to directories * and other special files. --ADM */ -asmlinkage long sys_linkat(int olddfd, const char __user *oldname, - int newdfd, const char __user *newname, - int flags) +SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname, + int, newdfd, const char __user *, newname, int, flags) { struct dentry *new_dentry; struct nameidata nd; @@ -2441,7 +2458,9 @@ error = mnt_want_write(nd.path.mnt); if (error) goto out_dput; - error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry); + error = vfs_link(old_path.dentry, old_path.mnt, + nd.path.dentry->d_inode, + new_dentry, nd.path.mnt); mnt_drop_write(nd.path.mnt); out_dput: dput(new_dentry); @@ -2456,7 +2475,7 @@ return error; } -asmlinkage long sys_link(const char __user *oldname, const char __user *newname) +SYSCALL_DEFINE2(link, const char __user *, oldname, const char __user *, newname) { return sys_linkat(AT_FDCWD, oldname, AT_FDCWD, newname, 0); } @@ -2494,7 +2513,8 @@ * locking]. */ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry) + struct vfsmount *old_mnt, struct inode *new_dir, + struct dentry *new_dentry, struct vfsmount *new_mnt) { int error = 0; struct inode *target; @@ -2509,7 +2529,8 @@ return error; } - error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry); + error = security_inode_rename(old_dir, old_dentry, old_mnt, + new_dir, new_dentry, new_mnt); if (error) return error; @@ -2537,12 +2558,14 @@ } static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry) + struct vfsmount *old_mnt, struct inode *new_dir, + struct dentry *new_dentry, struct vfsmount *new_mnt) { struct inode *target; int error; - error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry); + error = security_inode_rename(old_dir, old_dentry, old_mnt, + new_dir, new_dentry, new_mnt); if (error) return error; @@ -2565,7 +2588,8 @@ } int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry) + struct vfsmount *old_mnt, struct inode *new_dir, + struct dentry *new_dentry, struct vfsmount *new_mnt) { int error; int is_dir = S_ISDIR(old_dentry->d_inode->i_mode); @@ -2594,9 +2618,11 @@ old_name = fsnotify_oldname_init(old_dentry->d_name.name); if (is_dir) - error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry); + error = vfs_rename_dir(old_dir, old_dentry, old_mnt, + new_dir, new_dentry, new_mnt); else - error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry); + error = vfs_rename_other(old_dir, old_dentry, old_mnt, + new_dir, new_dentry, new_mnt); if (!error) { const char *new_name = old_dentry->d_name.name; fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir, @@ -2607,8 +2633,8 @@ return error; } -asmlinkage long sys_renameat(int olddfd, const char __user *oldname, - int newdfd, const char __user *newname) +SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname, + int, newdfd, const char __user *, newname) { struct dentry *old_dir, *new_dir; struct dentry *old_dentry, *new_dentry; @@ -2677,8 +2703,8 @@ error = mnt_want_write(oldnd.path.mnt); if (error) goto exit5; - error = vfs_rename(old_dir->d_inode, old_dentry, - new_dir->d_inode, new_dentry); + error = vfs_rename(old_dir->d_inode, old_dentry, oldnd.path.mnt, + new_dir->d_inode, new_dentry, newnd.path.mnt); mnt_drop_write(oldnd.path.mnt); exit5: dput(new_dentry); @@ -2696,7 +2722,7 @@ return error; } -asmlinkage long sys_rename(const char __user *oldname, const char __user *newname) +SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newname) { return sys_renameat(AT_FDCWD, oldname, AT_FDCWD, newname); } @@ -2786,18 +2812,23 @@ } } -int __page_symlink(struct inode *inode, const char *symname, int len, - gfp_t gfp_mask) +/* + * The nofs argument instructs pagecache_write_begin to pass AOP_FLAG_NOFS + */ +int __page_symlink(struct inode *inode, const char *symname, int len, int nofs) { struct address_space *mapping = inode->i_mapping; struct page *page; void *fsdata; int err; char *kaddr; + unsigned int flags = AOP_FLAG_UNINTERRUPTIBLE; + if (nofs) + flags |= AOP_FLAG_NOFS; retry: err = pagecache_write_begin(NULL, mapping, 0, len-1, - AOP_FLAG_UNINTERRUPTIBLE, &page, &fsdata); + flags, &page, &fsdata); if (err) goto fail; @@ -2821,7 +2852,7 @@ int page_symlink(struct inode *inode, const char *symname, int len) { return __page_symlink(inode, symname, len, - mapping_gfp_mask(inode->i_mapping)); + !(mapping_gfp_mask(inode->i_mapping) & __GFP_FS)); } const struct inode_operations page_symlink_inode_operations = { @@ -2847,6 +2878,7 @@ EXPORT_SYMBOL(kern_path); EXPORT_SYMBOL(vfs_path_lookup); EXPORT_SYMBOL(inode_permission); +EXPORT_SYMBOL(path_permission); EXPORT_SYMBOL(vfs_permission); EXPORT_SYMBOL(file_permission); EXPORT_SYMBOL(unlock_rename); @@ -2863,3 +2895,5 @@ EXPORT_SYMBOL(vfs_unlink); EXPORT_SYMBOL(dentry_unhash); EXPORT_SYMBOL(generic_readlink); +EXPORT_SYMBOL(deny_write_access); +EXPORT_SYMBOL(__lookup_hash); --- linux-2.6.28.orig/fs/eventpoll.c +++ linux-2.6.28/fs/eventpoll.c @@ -234,8 +234,6 @@ /* * Configuration options available inside /proc/sys/fs/epoll/ */ -/* Maximum number of epoll devices, per user */ -static int max_user_instances __read_mostly; /* Maximum number of epoll watched descriptors, per user */ static int max_user_watches __read_mostly; @@ -261,14 +259,6 @@ ctl_table epoll_table[] = { { - .procname = "max_user_instances", - .data = &max_user_instances, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec_minmax, - .extra1 = &zero, - }, - { .procname = "max_user_watches", .data = &max_user_watches, .maxlen = sizeof(int), @@ -491,7 +481,6 @@ mutex_unlock(&epmutex); mutex_destroy(&ep->mtx); - atomic_dec(&ep->user->epoll_devs); free_uid(ep->user); kfree(ep); } @@ -581,10 +570,6 @@ struct eventpoll *ep; user = get_current_user(); - error = -EMFILE; - if (unlikely(atomic_read(&user->epoll_devs) >= - max_user_instances)) - goto free_uid; error = -ENOMEM; ep = kzalloc(sizeof(*ep), GFP_KERNEL); if (unlikely(!ep)) @@ -1110,7 +1095,7 @@ /* * Open an eventpoll file descriptor. */ -asmlinkage long sys_epoll_create1(int flags) +SYSCALL_DEFINE1(epoll_create1, int, flags) { int error, fd = -1; struct eventpoll *ep; @@ -1141,7 +1126,6 @@ flags & O_CLOEXEC); if (fd < 0) ep_free(ep); - atomic_inc(&ep->user->epoll_devs); error_return: DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n", @@ -1150,7 +1134,7 @@ return fd; } -asmlinkage long sys_epoll_create(int size) +SYSCALL_DEFINE1(epoll_create, int, size) { if (size < 0) return -EINVAL; @@ -1163,8 +1147,8 @@ * the eventpoll file that enables the insertion/removal/change of * file descriptors inside the interest set. */ -asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, - struct epoll_event __user *event) +SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd, + struct epoll_event __user *, event) { int error; struct file *file, *tfile; @@ -1261,8 +1245,8 @@ * Implement the event wait interface for the eventpoll file. It is the kernel * part of the user space epoll_wait(2). */ -asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events, - int maxevents, int timeout) +SYSCALL_DEFINE4(epoll_wait, int, epfd, struct epoll_event __user *, events, + int, maxevents, int, timeout) { int error; struct file *file; @@ -1319,9 +1303,9 @@ * Implement the event wait interface for the eventpoll file. It is the kernel * part of the user space epoll_pwait(2). */ -asmlinkage long sys_epoll_pwait(int epfd, struct epoll_event __user *events, - int maxevents, int timeout, const sigset_t __user *sigmask, - size_t sigsetsize) +SYSCALL_DEFINE6(epoll_pwait, int, epfd, struct epoll_event __user *, events, + int, maxevents, int, timeout, const sigset_t __user *, sigmask, + size_t, sigsetsize) { int error; sigset_t ksigmask, sigsaved; @@ -1366,8 +1350,10 @@ struct sysinfo si; si_meminfo(&si); - max_user_instances = 128; - max_user_watches = (((si.totalram - si.totalhigh) / 32) << PAGE_SHIFT) / + /* + * Allows top 4% of lomem to be allocated for epoll watches (per user). + */ + max_user_watches = (((si.totalram - si.totalhigh) / 25) << PAGE_SHIFT) / EP_ITEM_COST; /* Initialize the structure used to perform safe poll wait head wake ups */ --- linux-2.6.28.orig/fs/file_table.c +++ linux-2.6.28/fs/file_table.c @@ -351,6 +351,7 @@ file_free(file); } } +EXPORT_SYMBOL(put_filp); void file_move(struct file *file, struct list_head *list) { --- linux-2.6.28.orig/fs/read_write.c +++ linux-2.6.28/fs/read_write.c @@ -134,7 +134,7 @@ } EXPORT_SYMBOL(vfs_llseek); -asmlinkage off_t sys_lseek(unsigned int fd, off_t offset, unsigned int origin) +SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, origin) { off_t retval; struct file * file; @@ -158,9 +158,9 @@ } #ifdef __ARCH_WANT_SYS_LLSEEK -asmlinkage long sys_llseek(unsigned int fd, unsigned long offset_high, - unsigned long offset_low, loff_t __user * result, - unsigned int origin) +SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high, + unsigned long, offset_low, loff_t __user *, result, + unsigned int, origin) { int retval; struct file * file; @@ -356,7 +356,7 @@ file->f_pos = pos; } -asmlinkage ssize_t sys_read(unsigned int fd, char __user * buf, size_t count) +SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) { struct file *file; ssize_t ret = -EBADF; @@ -373,7 +373,8 @@ return ret; } -asmlinkage ssize_t sys_write(unsigned int fd, const char __user * buf, size_t count) +SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf, + size_t, count) { struct file *file; ssize_t ret = -EBADF; @@ -390,8 +391,8 @@ return ret; } -asmlinkage ssize_t sys_pread64(unsigned int fd, char __user *buf, - size_t count, loff_t pos) +SYSCALL_DEFINE(pread64)(unsigned int fd, char __user *buf, + size_t count, loff_t pos) { struct file *file; ssize_t ret = -EBADF; @@ -410,9 +411,17 @@ return ret; } +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_pread64(long fd, long buf, long count, loff_t pos) +{ + return SYSC_pread64((unsigned int) fd, (char __user *) buf, + (size_t) count, pos); +} +SYSCALL_ALIAS(sys_pread64, SyS_pread64); +#endif -asmlinkage ssize_t sys_pwrite64(unsigned int fd, const char __user *buf, - size_t count, loff_t pos) +SYSCALL_DEFINE(pwrite64)(unsigned int fd, const char __user *buf, + size_t count, loff_t pos) { struct file *file; ssize_t ret = -EBADF; @@ -431,6 +440,14 @@ return ret; } +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_pwrite64(long fd, long buf, long count, loff_t pos) +{ + return SYSC_pwrite64((unsigned int) fd, (const char __user *) buf, + (size_t) count, pos); +} +SYSCALL_ALIAS(sys_pwrite64, SyS_pwrite64); +#endif /* * Reduce an iovec's length in-place. Return the resulting number of segments @@ -659,8 +676,8 @@ EXPORT_SYMBOL(vfs_writev); -asmlinkage ssize_t -sys_readv(unsigned long fd, const struct iovec __user *vec, unsigned long vlen) +SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec, + unsigned long, vlen) { struct file *file; ssize_t ret = -EBADF; @@ -680,8 +697,8 @@ return ret; } -asmlinkage ssize_t -sys_writev(unsigned long fd, const struct iovec __user *vec, unsigned long vlen) +SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec __user *, vec, + unsigned long, vlen) { struct file *file; ssize_t ret = -EBADF; @@ -799,7 +816,7 @@ return retval; } -asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t __user *offset, size_t count) +SYSCALL_DEFINE4(sendfile, int, out_fd, int, in_fd, off_t __user *, offset, size_t, count) { loff_t pos; off_t off; @@ -818,7 +835,7 @@ return do_sendfile(out_fd, in_fd, NULL, count, 0); } -asmlinkage ssize_t sys_sendfile64(int out_fd, int in_fd, loff_t __user *offset, size_t count) +SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd, loff_t __user *, offset, size_t, count) { loff_t pos; ssize_t ret; --- linux-2.6.28.orig/fs/signalfd.c +++ linux-2.6.28/fs/signalfd.c @@ -205,8 +205,8 @@ .read = signalfd_read, }; -asmlinkage long sys_signalfd4(int ufd, sigset_t __user *user_mask, - size_t sizemask, int flags) +SYSCALL_DEFINE4(signalfd4, int, ufd, sigset_t __user *, user_mask, + size_t, sizemask, int, flags) { sigset_t sigmask; struct signalfd_ctx *ctx; @@ -259,8 +259,8 @@ return ufd; } -asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, - size_t sizemask) +SYSCALL_DEFINE3(signalfd, int, ufd, sigset_t __user *, user_mask, + size_t, sizemask) { return sys_signalfd4(ufd, user_mask, sizemask, 0); } --- linux-2.6.28.orig/fs/inotify.c +++ linux-2.6.28/fs/inotify.c @@ -156,7 +156,7 @@ int ret; do { - if (unlikely(!idr_pre_get(&ih->idr, GFP_KERNEL))) + if (unlikely(!idr_pre_get(&ih->idr, GFP_NOFS))) return -ENOSPC; ret = idr_get_new_above(&ih->idr, watch, ih->last_wd+1, &watch->wd); } while (ret == -EAGAIN); --- linux-2.6.28.orig/fs/binfmt_elf.c +++ linux-2.6.28/fs/binfmt_elf.c @@ -1196,9 +1196,11 @@ * check for an ELF header. If we find one, dump the first page to * aid in determining what was mapped here. */ - if (FILTER(ELF_HEADERS) && vma->vm_file != NULL && vma->vm_pgoff == 0) { + if (FILTER(ELF_HEADERS) && + vma->vm_pgoff == 0 && (vma->vm_flags & VM_READ)) { u32 __user *header = (u32 __user *) vma->vm_start; u32 word; + mm_segment_t fs = get_fs(); /* * Doing it this way gets the constant folded by GCC. */ @@ -1211,7 +1213,15 @@ magic.elfmag[EI_MAG1] = ELFMAG1; magic.elfmag[EI_MAG2] = ELFMAG2; magic.elfmag[EI_MAG3] = ELFMAG3; - if (get_user(word, header) == 0 && word == magic.cmp) + /* + * Switch to the user "segment" for get_user(), + * then put back what elf_core_dump() had in place. + */ + set_fs(USER_DS); + if (unlikely(get_user(word, header))) + word = 0; + set_fs(fs); + if (word == magic.cmp) return PAGE_SIZE; } --- linux-2.6.28.orig/fs/xattr.c +++ linux-2.6.28/fs/xattr.c @@ -67,8 +67,8 @@ } int -vfs_setxattr(struct dentry *dentry, const char *name, const void *value, - size_t size, int flags) +vfs_setxattr(struct dentry *dentry, struct vfsmount *mnt, const char *name, + const void *value, size_t size, int flags, struct file *file) { struct inode *inode = dentry->d_inode; int error; @@ -78,7 +78,7 @@ return error; mutex_lock(&inode->i_mutex); - error = security_inode_setxattr(dentry, name, value, size, flags); + error = security_inode_setxattr(dentry, mnt, name, value, size, flags, file); if (error) goto out; error = -EOPNOTSUPP; @@ -86,7 +86,7 @@ error = inode->i_op->setxattr(dentry, name, value, size, flags); if (!error) { fsnotify_xattr(dentry); - security_inode_post_setxattr(dentry, name, value, + security_inode_post_setxattr(dentry, mnt, name, value, size, flags); } } else if (!strncmp(name, XATTR_SECURITY_PREFIX, @@ -131,7 +131,8 @@ EXPORT_SYMBOL_GPL(xattr_getsecurity); ssize_t -vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size) +vfs_getxattr(struct dentry *dentry, struct vfsmount *mnt, const char *name, + void *value, size_t size, struct file *file) { struct inode *inode = dentry->d_inode; int error; @@ -140,7 +141,7 @@ if (error) return error; - error = security_inode_getxattr(dentry, name); + error = security_inode_getxattr(dentry, mnt, name, file); if (error) return error; @@ -167,18 +168,20 @@ EXPORT_SYMBOL_GPL(vfs_getxattr); ssize_t -vfs_listxattr(struct dentry *d, char *list, size_t size) +vfs_listxattr(struct dentry *dentry, struct vfsmount *mnt, char *list, + size_t size, struct file *file) { + struct inode *inode = dentry->d_inode; ssize_t error; - error = security_inode_listxattr(d); + error = security_inode_listxattr(dentry, mnt, file); if (error) return error; error = -EOPNOTSUPP; - if (d->d_inode->i_op && d->d_inode->i_op->listxattr) { - error = d->d_inode->i_op->listxattr(d, list, size); - } else { - error = security_inode_listsecurity(d->d_inode, list, size); + if (inode->i_op && inode->i_op->listxattr) + error = inode->i_op->listxattr(dentry, list, size); + else { + error = security_inode_listsecurity(inode, list, size); if (size && error > size) error = -ERANGE; } @@ -187,7 +190,8 @@ EXPORT_SYMBOL_GPL(vfs_listxattr); int -vfs_removexattr(struct dentry *dentry, const char *name) +vfs_removexattr(struct dentry *dentry, struct vfsmount *mnt, const char *name, + struct file *file) { struct inode *inode = dentry->d_inode; int error; @@ -199,7 +203,7 @@ if (error) return error; - error = security_inode_removexattr(dentry, name); + error = security_inode_removexattr(dentry, mnt, name, file); if (error) return error; @@ -218,8 +222,8 @@ * Extended attribute SET operations */ static long -setxattr(struct dentry *d, const char __user *name, const void __user *value, - size_t size, int flags) +setxattr(struct dentry *dentry, struct vfsmount *mnt, const char __user *name, + const void __user *value, size_t size, int flags, struct file *file) { int error; void *kvalue = NULL; @@ -246,14 +250,14 @@ } } - error = vfs_setxattr(d, kname, kvalue, size, flags); + error = vfs_setxattr(dentry, mnt, kname, kvalue, size, flags, file); kfree(kvalue); return error; } -asmlinkage long -sys_setxattr(const char __user *pathname, const char __user *name, - const void __user *value, size_t size, int flags) +SYSCALL_DEFINE5(setxattr, const char __user *, pathname, + const char __user *, name, const void __user *, value, + size_t, size, int, flags) { struct path path; int error; @@ -263,16 +267,16 @@ return error; error = mnt_want_write(path.mnt); if (!error) { - error = setxattr(path.dentry, name, value, size, flags); + error = setxattr(path.dentry, path.mnt, name, value, size, flags, NULL); mnt_drop_write(path.mnt); } path_put(&path); return error; } -asmlinkage long -sys_lsetxattr(const char __user *pathname, const char __user *name, - const void __user *value, size_t size, int flags) +SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname, + const char __user *, name, const void __user *, value, + size_t, size, int, flags) { struct path path; int error; @@ -282,16 +286,15 @@ return error; error = mnt_want_write(path.mnt); if (!error) { - error = setxattr(path.dentry, name, value, size, flags); + error = setxattr(path.dentry, path.mnt, name, value, size, flags, NULL); mnt_drop_write(path.mnt); } path_put(&path); return error; } -asmlinkage long -sys_fsetxattr(int fd, const char __user *name, const void __user *value, - size_t size, int flags) +SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, + const void __user *,value, size_t, size, int, flags) { struct file *f; struct dentry *dentry; @@ -304,7 +307,8 @@ audit_inode(NULL, dentry); error = mnt_want_write(f->f_path.mnt); if (!error) { - error = setxattr(dentry, name, value, size, flags); + error = setxattr(dentry, f->f_vfsmnt, name, value, size, flags, + f); mnt_drop_write(f->f_path.mnt); } fput(f); @@ -315,8 +319,8 @@ * Extended attribute GET operations */ static ssize_t -getxattr(struct dentry *d, const char __user *name, void __user *value, - size_t size) +getxattr(struct dentry *dentry, struct vfsmount *mnt, const char __user *name, + void __user *value, size_t size, struct file *file) { ssize_t error; void *kvalue = NULL; @@ -336,7 +340,7 @@ return -ENOMEM; } - error = vfs_getxattr(d, kname, kvalue, size); + error = vfs_getxattr(dentry, mnt, kname, kvalue, size, file); if (error > 0) { if (size && copy_to_user(value, kvalue, error)) error = -EFAULT; @@ -349,9 +353,8 @@ return error; } -asmlinkage ssize_t -sys_getxattr(const char __user *pathname, const char __user *name, - void __user *value, size_t size) +SYSCALL_DEFINE4(getxattr, const char __user *, pathname, + const char __user *, name, void __user *, value, size_t, size) { struct path path; ssize_t error; @@ -359,14 +362,13 @@ error = user_path(pathname, &path); if (error) return error; - error = getxattr(path.dentry, name, value, size); + error = getxattr(path.dentry, path.mnt, name, value, size, NULL); path_put(&path); return error; } -asmlinkage ssize_t -sys_lgetxattr(const char __user *pathname, const char __user *name, void __user *value, - size_t size) +SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname, + const char __user *, name, void __user *, value, size_t, size) { struct path path; ssize_t error; @@ -374,13 +376,13 @@ error = user_lpath(pathname, &path); if (error) return error; - error = getxattr(path.dentry, name, value, size); + error = getxattr(path.dentry, path.mnt, name, value, size, NULL); path_put(&path); return error; } -asmlinkage ssize_t -sys_fgetxattr(int fd, const char __user *name, void __user *value, size_t size) +SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name, + void __user *, value, size_t, size) { struct file *f; ssize_t error = -EBADF; @@ -389,7 +391,7 @@ if (!f) return error; audit_inode(NULL, f->f_path.dentry); - error = getxattr(f->f_path.dentry, name, value, size); + error = getxattr(f->f_path.dentry, f->f_path.mnt, name, value, size, f); fput(f); return error; } @@ -398,7 +400,8 @@ * Extended attribute LIST operations */ static ssize_t -listxattr(struct dentry *d, char __user *list, size_t size) +listxattr(struct dentry *dentry, struct vfsmount *mnt, char __user *list, + size_t size, struct file *file) { ssize_t error; char *klist = NULL; @@ -411,7 +414,7 @@ return -ENOMEM; } - error = vfs_listxattr(d, klist, size); + error = vfs_listxattr(dentry, mnt, klist, size, file); if (error > 0) { if (size && copy_to_user(list, klist, error)) error = -EFAULT; @@ -424,8 +427,8 @@ return error; } -asmlinkage ssize_t -sys_listxattr(const char __user *pathname, char __user *list, size_t size) +SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list, + size_t, size) { struct path path; ssize_t error; @@ -433,13 +436,13 @@ error = user_path(pathname, &path); if (error) return error; - error = listxattr(path.dentry, list, size); + error = listxattr(path.dentry, path.mnt, list, size, NULL); path_put(&path); return error; } -asmlinkage ssize_t -sys_llistxattr(const char __user *pathname, char __user *list, size_t size) +SYSCALL_DEFINE3(llistxattr, const char __user *, pathname, char __user *, list, + size_t, size) { struct path path; ssize_t error; @@ -447,13 +450,12 @@ error = user_lpath(pathname, &path); if (error) return error; - error = listxattr(path.dentry, list, size); + error = listxattr(path.dentry, path.mnt, list, size, NULL); path_put(&path); return error; } -asmlinkage ssize_t -sys_flistxattr(int fd, char __user *list, size_t size) +SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size) { struct file *f; ssize_t error = -EBADF; @@ -462,7 +464,7 @@ if (!f) return error; audit_inode(NULL, f->f_path.dentry); - error = listxattr(f->f_path.dentry, list, size); + error = listxattr(f->f_path.dentry, f->f_path.mnt, list, size, f); fput(f); return error; } @@ -471,7 +473,8 @@ * Extended attribute REMOVE operations */ static long -removexattr(struct dentry *d, const char __user *name) +removexattr(struct dentry *dentry, struct vfsmount *mnt, + const char __user *name, struct file *file) { int error; char kname[XATTR_NAME_MAX + 1]; @@ -482,11 +485,11 @@ if (error < 0) return error; - return vfs_removexattr(d, kname); + return vfs_removexattr(dentry, mnt, kname, file); } -asmlinkage long -sys_removexattr(const char __user *pathname, const char __user *name) +SYSCALL_DEFINE2(removexattr, const char __user *, pathname, + const char __user *, name) { struct path path; int error; @@ -496,15 +499,15 @@ return error; error = mnt_want_write(path.mnt); if (!error) { - error = removexattr(path.dentry, name); + error = removexattr(path.dentry, path.mnt, name, NULL); mnt_drop_write(path.mnt); } path_put(&path); return error; } -asmlinkage long -sys_lremovexattr(const char __user *pathname, const char __user *name) +SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname, + const char __user *, name) { struct path path; int error; @@ -514,15 +517,14 @@ return error; error = mnt_want_write(path.mnt); if (!error) { - error = removexattr(path.dentry, name); + error = removexattr(path.dentry, path.mnt, name, NULL); mnt_drop_write(path.mnt); } path_put(&path); return error; } -asmlinkage long -sys_fremovexattr(int fd, const char __user *name) +SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name) { struct file *f; struct dentry *dentry; @@ -535,7 +537,7 @@ audit_inode(NULL, dentry); error = mnt_want_write(f->f_path.mnt); if (!error) { - error = removexattr(dentry, name); + error = removexattr(dentry, f->f_path.mnt, name, f); mnt_drop_write(f->f_path.mnt); } fput(f); --- linux-2.6.28.orig/fs/utimes.c +++ linux-2.6.28/fs/utimes.c @@ -24,7 +24,7 @@ * must be owner or have write permission. * Else, update from *times, must be owner or super user. */ -asmlinkage long sys_utime(char __user *filename, struct utimbuf __user *times) +SYSCALL_DEFINE2(utime, char __user *, filename, struct utimbuf __user *, times) { struct timespec tv[2]; @@ -48,7 +48,8 @@ return nsec >= 0 && nsec <= 999999999; } -static int utimes_common(struct path *path, struct timespec *times) +static int utimes_common(struct path *path, struct timespec *times, + struct file *f) { int error; struct iattr newattrs; @@ -102,7 +103,7 @@ } } mutex_lock(&inode->i_mutex); - error = notify_change(path->dentry, &newattrs); + error = fnotify_change(path->dentry, path->mnt, &newattrs, f); mutex_unlock(&inode->i_mutex); mnt_drop_write_and_out: @@ -149,7 +150,7 @@ if (!file) goto out; - error = utimes_common(&file->f_path, times); + error = utimes_common(&file->f_path, times, file); fput(file); } else { struct path path; @@ -162,7 +163,7 @@ if (error) goto out; - error = utimes_common(&path, times); + error = utimes_common(&path, times, NULL); path_put(&path); } @@ -170,7 +171,8 @@ return error; } -asmlinkage long sys_utimensat(int dfd, char __user *filename, struct timespec __user *utimes, int flags) +SYSCALL_DEFINE4(utimensat, int, dfd, char __user *, filename, + struct timespec __user *, utimes, int, flags) { struct timespec tstimes[2]; @@ -187,7 +189,8 @@ return do_utimes(dfd, filename, utimes ? tstimes : NULL, flags); } -asmlinkage long sys_futimesat(int dfd, char __user *filename, struct timeval __user *utimes) +SYSCALL_DEFINE3(futimesat, int, dfd, char __user *, filename, + struct timeval __user *, utimes) { struct timeval times[2]; struct timespec tstimes[2]; @@ -214,7 +217,8 @@ return do_utimes(dfd, filename, utimes ? tstimes : NULL, 0); } -asmlinkage long sys_utimes(char __user *filename, struct timeval __user *utimes) +SYSCALL_DEFINE2(utimes, char __user *, filename, + struct timeval __user *, utimes) { return sys_futimesat(AT_FDCWD, filename, utimes); } --- linux-2.6.28.orig/fs/exec.c +++ linux-2.6.28/fs/exec.c @@ -102,7 +102,7 @@ * * Also note that we take the address to load from from the file itself. */ -asmlinkage long sys_uselib(const char __user * library) +SYSCALL_DEFINE1(uselib, const char __user *, library) { struct file *file; struct nameidata nd; @@ -1829,7 +1829,8 @@ goto close_fail; if (!file->f_op->write) goto close_fail; - if (!ispipe && do_truncate(file->f_path.dentry, 0, 0, file) != 0) + if (!ispipe && + do_truncate(file->f_path.dentry, file->f_path.mnt, 0, 0, file) != 0) goto close_fail; retval = binfmt->core_dump(signr, regs, file, core_limit); --- linux-2.6.28.orig/fs/ioprio.c +++ linux-2.6.28/fs/ioprio.c @@ -65,7 +65,7 @@ return err; } -asmlinkage long sys_ioprio_set(int which, int who, int ioprio) +SYSCALL_DEFINE3(ioprio_set, int, which, int, who, int, ioprio) { int class = IOPRIO_PRIO_CLASS(ioprio); int data = IOPRIO_PRIO_DATA(ioprio); @@ -181,7 +181,7 @@ return aprio; } -asmlinkage long sys_ioprio_get(int which, int who) +SYSCALL_DEFINE2(ioprio_get, int, which, int, who) { struct task_struct *g, *p; struct user_struct *user; @@ -245,4 +245,3 @@ read_unlock(&tasklist_lock); return ret; } - --- linux-2.6.28.orig/fs/attr.c +++ linux-2.6.28/fs/attr.c @@ -100,7 +100,8 @@ } EXPORT_SYMBOL(inode_setattr); -int notify_change(struct dentry * dentry, struct iattr * attr) +int fnotify_change(struct dentry *dentry, struct vfsmount *mnt, + struct iattr *attr, struct file *file) { struct inode *inode = dentry->d_inode; mode_t mode = inode->i_mode; @@ -159,7 +160,7 @@ if (!(attr->ia_valid & ~(ATTR_KILL_SUID | ATTR_KILL_SGID))) return 0; - error = security_inode_setattr(dentry, attr); + error = security_inode_setattr(dentry, mnt, attr); if (error) return error; @@ -167,7 +168,24 @@ down_write(&dentry->d_inode->i_alloc_sem); if (inode->i_op && inode->i_op->setattr) { - error = inode->i_op->setattr(dentry, attr); + error = security_inode_setattr(dentry, mnt, attr); + if (!error) { + if (file && file->f_op && file->f_op->fsetattr) + error = file->f_op->fsetattr(file, attr); + else { + /* External file system still expect to be + * passed a file pointer via ia_file and + * have it announced via ATTR_FILE. This + * just makes it so they don't need to + * change their API just for us. External + * callers will have set these themselves. */ + if (file) { + attr->ia_valid |= ATTR_FILE; + attr->ia_file = file; + } + error = inode->i_op->setattr(dentry, attr); + } + } } else { error = inode_change_ok(inode, attr); if (!error) { @@ -187,5 +205,12 @@ return error; } +EXPORT_SYMBOL_GPL(fnotify_change); + +int notify_change(struct dentry *dentry, struct vfsmount *mnt, + struct iattr *attr) +{ + return fnotify_change(dentry, mnt, attr, NULL); +} EXPORT_SYMBOL(notify_change); --- linux-2.6.28.orig/fs/timerfd.c +++ linux-2.6.28/fs/timerfd.c @@ -177,7 +177,7 @@ return file; } -asmlinkage long sys_timerfd_create(int clockid, int flags) +SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) { int ufd; struct timerfd_ctx *ctx; @@ -186,10 +186,9 @@ BUILD_BUG_ON(TFD_CLOEXEC != O_CLOEXEC); BUILD_BUG_ON(TFD_NONBLOCK != O_NONBLOCK); - if (flags & ~(TFD_CLOEXEC | TFD_NONBLOCK)) - return -EINVAL; - if (clockid != CLOCK_MONOTONIC && - clockid != CLOCK_REALTIME) + if ((flags & ~TFD_CREATE_FLAGS) || + (clockid != CLOCK_MONOTONIC && + clockid != CLOCK_REALTIME)) return -EINVAL; ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); @@ -201,16 +200,16 @@ hrtimer_init(&ctx->tmr, clockid, HRTIMER_MODE_ABS); ufd = anon_inode_getfd("[timerfd]", &timerfd_fops, ctx, - flags & (O_CLOEXEC | O_NONBLOCK)); + flags & TFD_SHARED_FCNTL_FLAGS); if (ufd < 0) kfree(ctx); return ufd; } -asmlinkage long sys_timerfd_settime(int ufd, int flags, - const struct itimerspec __user *utmr, - struct itimerspec __user *otmr) +SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, + const struct itimerspec __user *, utmr, + struct itimerspec __user *, otmr) { struct file *file; struct timerfd_ctx *ctx; @@ -219,7 +218,8 @@ if (copy_from_user(&ktmr, utmr, sizeof(ktmr))) return -EFAULT; - if (!timespec_valid(&ktmr.it_value) || + if ((flags & ~TFD_SETTIME_FLAGS) || + !timespec_valid(&ktmr.it_value) || !timespec_valid(&ktmr.it_interval)) return -EINVAL; @@ -265,7 +265,7 @@ return 0; } -asmlinkage long sys_timerfd_gettime(int ufd, struct itimerspec __user *otmr) +SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr) { struct file *file; struct timerfd_ctx *ctx; --- linux-2.6.28.orig/fs/quota.c +++ linux-2.6.28/fs/quota.c @@ -368,7 +368,8 @@ * calls. Maybe we need to add the process quotas etc. in the future, * but we probably should use rlimits for that. */ -asmlinkage long sys_quotactl(unsigned int cmd, const char __user *special, qid_t id, void __user *addr) +SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special, + qid_t, id, void __user *, addr) { uint cmds, type; struct super_block *sb = NULL; --- linux-2.6.28.orig/fs/pipe.c +++ linux-2.6.28/fs/pipe.c @@ -699,12 +699,12 @@ int retval; mutex_lock(&inode->i_mutex); - retval = fasync_helper(fd, filp, on, &pipe->fasync_readers); - - if (retval >= 0) + if (retval >= 0) { retval = fasync_helper(fd, filp, on, &pipe->fasync_writers); - + if (retval < 0) /* this can happen only if on == T */ + fasync_helper(-1, filp, 0, &pipe->fasync_readers); + } mutex_unlock(&inode->i_mutex); if (retval < 0) @@ -1048,7 +1048,7 @@ * sys_pipe() is the normal C calling standard for creating * a pipe. It's not the way Unix traditionally does this, though. */ -asmlinkage long __weak sys_pipe2(int __user *fildes, int flags) +SYSCALL_DEFINE2(pipe2, int __user *, fildes, int, flags) { int fd[2]; int error; @@ -1064,7 +1064,7 @@ return error; } -asmlinkage long __weak sys_pipe(int __user *fildes) +SYSCALL_DEFINE1(pipe, int __user *, fildes) { return sys_pipe2(fildes, 0); } --- linux-2.6.28.orig/fs/dcache.c +++ linux-2.6.28/fs/dcache.c @@ -1620,8 +1620,11 @@ */ memcpy(dentry->d_iname, target->d_name.name, target->d_name.len + 1); + dentry->d_name.len = target->d_name.len; + return; } } + do_switch(dentry->d_name.len, target->d_name.len); } /* @@ -1681,7 +1684,6 @@ /* Switch the names.. */ switch_names(dentry, target); - do_switch(dentry->d_name.len, target->d_name.len); do_switch(dentry->d_name.hash, target->d_name.hash); /* ... and switch the parents */ @@ -1791,7 +1793,6 @@ struct dentry *dparent, *aparent; switch_names(dentry, anon); - do_switch(dentry->d_name.len, anon->d_name.len); do_switch(dentry->d_name.hash, anon->d_name.hash); dparent = dentry->d_parent; @@ -1907,44 +1908,46 @@ * @root: root vfsmnt/dentry (may be modified by this function) * @buffer: buffer to return value in * @buflen: buffer length + * @flags: flags controling behavior of d_path * - * Convert a dentry into an ASCII path name. If the entry has been deleted - * the string " (deleted)" is appended. Note that this is ambiguous. - * - * Returns the buffer or an error code if the path was too long. - * - * "buflen" should be positive. Caller holds the dcache_lock. + * Convert a dentry into an ASCII path name. If the entry has been deleted, + * then if @flags has D_PATH_FAIL_DELETED set, ERR_PTR(-ENOENT) is returned. + * Otherwise, the string " (deleted)" is appended. Note that this is ambiguous. * * If path is not reachable from the supplied root, then the value of - * root is changed (without modifying refcounts). + * root is changed (without modifying refcounts). The path returned in this + * case will be relative (i.e., it will not start with a slash). + * + * Returns the buffer or an error code if the path was too long. */ char *__d_path(const struct path *path, struct path *root, - char *buffer, int buflen) + char *buffer, int buflen, int flags) { struct dentry *dentry = path->dentry; struct vfsmount *vfsmnt = path->mnt; - char *end = buffer + buflen; - char *retval; + const unsigned char *name; + int namelen; + + buffer += buflen; + prepend(&buffer, &buflen, "\0", 1); spin_lock(&vfsmount_lock); - prepend(&end, &buflen, "\0", 1); - if (!IS_ROOT(dentry) && d_unhashed(dentry) && - (prepend(&end, &buflen, " (deleted)", 10) != 0)) + spin_lock(&dcache_lock); + if (!IS_ROOT(dentry) && d_unhashed(dentry)) { + if (flags & D_PATH_FAIL_DELETED) { + buffer = ERR_PTR(-ENOENT); + goto out; + } + if (prepend(&buffer, &buflen, " (deleted)", 10) != 0) goto Elong; - + } if (buflen < 1) goto Elong; - /* Get '/' right */ - retval = end-1; - *retval = '/'; - for (;;) { + while (dentry != root->dentry || vfsmnt != root->mnt) { struct dentry * parent; - if (dentry == root->dentry && vfsmnt == root->mnt) - break; if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) { - /* Global root? */ if (vfsmnt->mnt_parent == vfsmnt) { goto global_root; } @@ -1954,27 +1957,51 @@ } parent = dentry->d_parent; prefetch(parent); - if ((prepend_name(&end, &buflen, &dentry->d_name) != 0) || - (prepend(&end, &buflen, "/", 1) != 0)) + if ((prepend_name(&buffer, &buflen, &dentry->d_name) != 0) || + (prepend(&buffer, &buflen, "/", 1) != 0)) goto Elong; - retval = end; dentry = parent; } + /* Get '/' right. */ + if (*buffer != '/' && prepend(&buffer, &buflen, "/", 1)) + goto Elong; out: + spin_unlock(&dcache_lock); spin_unlock(&vfsmount_lock); - return retval; + return buffer; global_root: - retval += 1; /* hit the slash */ - if (prepend_name(&retval, &buflen, &dentry->d_name) != 0) + /* + * We went past the (vfsmount, dentry) we were looking for and have + * either hit a root dentry, a lazily unmounted dentry, an + * unconnected dentry, or the file is on a pseudo filesystem. + */ + namelen = dentry->d_name.len; + name = dentry->d_name.name; + + /* + * If this is a root dentry, then overwrite the slash. This + * will also DTRT with pseudo filesystems which have root + * dentries named "foo:". + */ + if (IS_ROOT(dentry) && *buffer == '/') { + buffer++; + buflen++; + } + if ((flags & D_PATH_DISCONNECT) && *name == '/') { + /* Make sure we won't return a pathname starting with '/' */ + name++; + namelen--; + } + if (prepend(&buffer, &buflen, name, namelen)) goto Elong; root->mnt = vfsmnt; root->dentry = dentry; goto out; Elong: - retval = ERR_PTR(-ENAMETOOLONG); + buffer = ERR_PTR(-ENAMETOOLONG); goto out; } @@ -2011,10 +2038,8 @@ root = current->fs->root; path_get(&root); read_unlock(¤t->fs->lock); - spin_lock(&dcache_lock); tmp = root; - res = __d_path(path, &tmp, buf, buflen); - spin_unlock(&dcache_lock); + res = __d_path(path, &tmp, buf, buflen, 0); path_put(&root); return res; } @@ -2095,11 +2120,11 @@ * return NULL; * } */ -asmlinkage long sys_getcwd(char __user *buf, unsigned long size) +SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size) { - int error; - struct path pwd, root; - char *page = (char *) __get_free_page(GFP_USER); + int error, len; + struct path pwd, root, tmp; + char *page = (char *) __get_free_page(GFP_USER), *cwd; if (!page) return -ENOMEM; @@ -2111,30 +2136,20 @@ path_get(&root); read_unlock(¤t->fs->lock); - error = -ENOENT; - /* Has the current directory has been unlinked? */ - spin_lock(&dcache_lock); - if (IS_ROOT(pwd.dentry) || !d_unhashed(pwd.dentry)) { - unsigned long len; - struct path tmp = root; - char * cwd; - - cwd = __d_path(&pwd, &tmp, page, PAGE_SIZE); - spin_unlock(&dcache_lock); - + tmp = root; + cwd = __d_path(&pwd, &tmp, page, PAGE_SIZE, D_PATH_FAIL_DELETED); + if (IS_ERR(cwd)) { error = PTR_ERR(cwd); - if (IS_ERR(cwd)) - goto out; + goto out; + } - error = -ERANGE; - len = PAGE_SIZE + page - cwd; - if (len <= size) { - error = len; - if (copy_to_user(buf, cwd, len)) - error = -EFAULT; - } - } else - spin_unlock(&dcache_lock); + error = -ERANGE; + len = PAGE_SIZE + page - cwd; + if (len <= size) { + error = len; + if (copy_to_user(buf, cwd, len)) + error = -EFAULT; + } out: path_put(&pwd); --- linux-2.6.28.orig/fs/inode.c +++ linux-2.6.28/fs/inode.c @@ -339,6 +339,7 @@ invalidate_inode_buffers(inode); if (!atomic_read(&inode->i_count)) { list_move(&inode->i_list, dispose); + WARN_ON(inode->i_state & I_NEW); inode->i_state |= I_FREEING; count++; continue; @@ -440,6 +441,7 @@ continue; } list_move(&inode->i_list, &freeable); + WARN_ON(inode->i_state & I_NEW); inode->i_state |= I_FREEING; nr_pruned++; } @@ -595,6 +597,7 @@ * just created it (so there can be no old holders * that haven't tested I_LOCK). */ + WARN_ON((inode->i_state & (I_LOCK|I_NEW)) != (I_LOCK|I_NEW)); inode->i_state &= ~(I_LOCK|I_NEW); wake_up_inode(inode); } @@ -1041,6 +1044,7 @@ list_del_init(&inode->i_list); list_del_init(&inode->i_sb_list); + WARN_ON(inode->i_state & I_NEW); inode->i_state |= I_FREEING; inodes_stat.nr_inodes--; spin_unlock(&inode_lock); @@ -1082,16 +1086,19 @@ spin_unlock(&inode_lock); return; } + WARN_ON(inode->i_state & I_NEW); inode->i_state |= I_WILL_FREE; spin_unlock(&inode_lock); write_inode_now(inode, 1); spin_lock(&inode_lock); + WARN_ON(inode->i_state & I_NEW); inode->i_state &= ~I_WILL_FREE; inodes_stat.nr_unused--; hlist_del_init(&inode->i_hash); } list_del_init(&inode->i_list); list_del_init(&inode->i_sb_list); + WARN_ON(inode->i_state & I_NEW); inode->i_state |= I_FREEING; inodes_stat.nr_inodes--; spin_unlock(&inode_lock); --- linux-2.6.28.orig/fs/fs-writeback.c +++ linux-2.6.28/fs/fs-writeback.c @@ -274,6 +274,7 @@ int ret; BUG_ON(inode->i_state & I_SYNC); + WARN_ON(inode->i_state & I_NEW); /* Set I_SYNC, reset I_DIRTY */ dirty = inode->i_state & I_DIRTY; @@ -298,6 +299,7 @@ } spin_lock(&inode_lock); + WARN_ON(inode->i_state & I_NEW); inode->i_state &= ~I_SYNC; if (!(inode->i_state & I_FREEING)) { if (!(inode->i_state & I_DIRTY) && @@ -421,9 +423,6 @@ * If we're a pdlfush thread, then implement pdflush collision avoidance * against the entire list. * - * 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(). - * * 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, @@ -443,6 +442,7 @@ struct writeback_control *wbc) { const unsigned long start = jiffies; /* livelock avoidance */ + int sync = wbc->sync_mode == WB_SYNC_ALL; spin_lock(&inode_lock); if (!wbc->for_kupdate || list_empty(&sb->s_io)) @@ -472,6 +472,11 @@ break; } + if (inode->i_state & I_NEW) { + requeue_io(inode); + continue; + } + if (wbc->nonblocking && bdi_write_congested(bdi)) { wbc->encountered_congestion = 1; if (!sb_is_blkdev_sb(sb)) @@ -499,10 +504,6 @@ __iget(inode); pages_skipped = wbc->pages_skipped; __writeback_single_inode(inode, wbc); - if (wbc->sync_mode == WB_SYNC_HOLD) { - inode->dirtied_when = jiffies; - list_move(&inode->i_list, &sb->s_dirty); - } if (current_is_pdflush()) writeback_release(bdi); if (wbc->pages_skipped != pages_skipped) { @@ -523,7 +524,49 @@ if (!list_empty(&sb->s_more_io)) wbc->more_io = 1; } - spin_unlock(&inode_lock); + + if (sync) { + struct inode *inode, *old_inode = NULL; + + /* + * Data integrity sync. Must wait for all pages under writeback, + * because there may have been pages dirtied before our sync + * call, but which had writeout started before we write it out. + * In which case, the inode may not be on the dirty list, but + * we still have to wait for that writeout. + */ + list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { + struct address_space *mapping; + + if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) + continue; + mapping = inode->i_mapping; + if (mapping->nrpages == 0) + continue; + __iget(inode); + spin_unlock(&inode_lock); + /* + * We hold a reference to 'inode' so it couldn't have + * been removed from s_inodes list while we dropped the + * inode_lock. We cannot iput the inode now as we can + * be holding the last reference and we cannot iput it + * under inode_lock. So we keep the reference and iput + * it later. + */ + iput(old_inode); + old_inode = inode; + + filemap_fdatawait(mapping); + + cond_resched(); + + spin_lock(&inode_lock); + } + spin_unlock(&inode_lock); + iput(old_inode); + } else + spin_unlock(&inode_lock); + return; /* Leave any unwritten inodes on s_io */ } EXPORT_SYMBOL_GPL(generic_sync_sb_inodes); @@ -588,8 +631,7 @@ /* * writeback and wait upon the filesystem's dirty inodes. The caller will - * do this in two passes - one to write, and one to wait. WB_SYNC_HOLD is - * used to park the written inodes on sb->s_dirty for the wait pass. + * do this in two passes - one to write, and one to wait. * * A finite limit is set on the number of pages which will be written. * To prevent infinite livelock of sys_sync(). @@ -600,30 +642,21 @@ void sync_inodes_sb(struct super_block *sb, int wait) { struct writeback_control wbc = { - .sync_mode = wait ? WB_SYNC_ALL : WB_SYNC_HOLD, + .sync_mode = wait ? WB_SYNC_ALL : WB_SYNC_NONE, .range_start = 0, .range_end = LLONG_MAX, }; - unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY); - unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS); - wbc.nr_to_write = nr_dirty + nr_unstable + - (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 */ - sync_sb_inodes(sb, &wbc); -} + if (!wait) { + unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY); + unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS); + + wbc.nr_to_write = nr_dirty + nr_unstable + + (inodes_stat.nr_inodes - inodes_stat.nr_unused); + } else + wbc.nr_to_write = LONG_MAX; /* doesn't actually matter */ -/* - * Rather lame livelock avoidance. - */ -static void set_sb_syncing(int val) -{ - struct super_block *sb; - spin_lock(&sb_lock); - list_for_each_entry_reverse(sb, &super_blocks, s_list) - sb->s_syncing = val; - spin_unlock(&sb_lock); + sync_sb_inodes(sb, &wbc); } /** @@ -652,9 +685,6 @@ spin_lock(&sb_lock); restart: list_for_each_entry(sb, &super_blocks, s_list) { - if (sb->s_syncing) - continue; - sb->s_syncing = 1; sb->s_count++; spin_unlock(&sb_lock); down_read(&sb->s_umount); @@ -672,13 +702,10 @@ void sync_inodes(int wait) { - set_sb_syncing(0); __sync_inodes(0); - if (wait) { - set_sb_syncing(0); + if (wait) __sync_inodes(1); - } } /** --- linux-2.6.28.orig/fs/ioctl.c +++ linux-2.6.28/fs/ioctl.c @@ -472,7 +472,7 @@ return error; } -asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) +SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg) { struct file *filp; int error = -EBADF; --- linux-2.6.28.orig/fs/super.c +++ linux-2.6.28/fs/super.c @@ -534,7 +534,7 @@ return NULL; } -asmlinkage long sys_ustat(unsigned dev, struct ustat __user * ubuf) +SYSCALL_DEFINE2(ustat, unsigned, dev, struct ustat __user *, ubuf) { struct super_block *s; struct ustat tmp; --- linux-2.6.28.orig/fs/inotify_user.c +++ linux-2.6.28/fs/inotify_user.c @@ -372,7 +372,7 @@ if (error) return error; /* you can only watch an inode if you have read permissions on it */ - error = inode_permission(path->dentry->d_inode, MAY_READ); + error = path_permission(path, MAY_READ); if (error) path_put(path); return error; @@ -427,10 +427,61 @@ return ret; } +/* + * Get an inotify_kernel_event if one exists and is small + * enough to fit in "count". Return an error pointer if + * not large enough. + * + * Called with the device ev_mutex held. + */ +static struct inotify_kernel_event *get_one_event(struct inotify_device *dev, + size_t count) +{ + size_t event_size = sizeof(struct inotify_event); + struct inotify_kernel_event *kevent; + + if (list_empty(&dev->events)) + return NULL; + + kevent = inotify_dev_get_event(dev); + if (kevent->name) + event_size += kevent->event.len; + + if (event_size > count) + return ERR_PTR(-EINVAL); + + remove_kevent(dev, kevent); + return kevent; +} + +/* + * Copy an event to user space, returning how much we copied. + * + * We already checked that the event size is smaller than the + * buffer we had in "get_one_event()" above. + */ +static ssize_t copy_event_to_user(struct inotify_kernel_event *kevent, + char __user *buf) +{ + size_t event_size = sizeof(struct inotify_event); + + if (copy_to_user(buf, &kevent->event, event_size)) + return -EFAULT; + + if (kevent->name) { + buf += event_size; + + if (copy_to_user(buf, kevent->name, kevent->event.len)) + return -EFAULT; + + event_size += kevent->event.len; + } + return event_size; +} + static ssize_t inotify_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { - size_t event_size = sizeof (struct inotify_event); struct inotify_device *dev; char __user *start; int ret; @@ -440,81 +491,43 @@ dev = file->private_data; while (1) { + struct inotify_kernel_event *kevent; prepare_to_wait(&dev->wq, &wait, TASK_INTERRUPTIBLE); mutex_lock(&dev->ev_mutex); - if (!list_empty(&dev->events)) { - ret = 0; - break; - } + kevent = get_one_event(dev, count); mutex_unlock(&dev->ev_mutex); - if (file->f_flags & O_NONBLOCK) { - ret = -EAGAIN; - break; - } - - if (signal_pending(current)) { - ret = -EINTR; - break; + if (kevent) { + ret = PTR_ERR(kevent); + if (IS_ERR(kevent)) + break; + ret = copy_event_to_user(kevent, buf); + free_kevent(kevent); + if (ret < 0) + break; + buf += ret; + count -= ret; + continue; } - schedule(); - } - - finish_wait(&dev->wq, &wait); - if (ret) - return ret; - - while (1) { - struct inotify_kernel_event *kevent; - - ret = buf - start; - if (list_empty(&dev->events)) + ret = -EAGAIN; + if (file->f_flags & O_NONBLOCK) break; - - kevent = inotify_dev_get_event(dev); - if (event_size + kevent->event.len > count) { - if (ret == 0 && count > 0) { - /* - * could not get a single event because we - * didn't have enough buffer space. - */ - ret = -EINVAL; - } + ret = -EINTR; + if (signal_pending(current)) break; - } - remove_kevent(dev, kevent); - /* - * Must perform the copy_to_user outside the mutex in order - * to avoid a lock order reversal with mmap_sem. - */ - mutex_unlock(&dev->ev_mutex); - - if (copy_to_user(buf, &kevent->event, event_size)) { - ret = -EFAULT; + if (start != buf) break; - } - buf += event_size; - count -= event_size; - - if (kevent->name) { - if (copy_to_user(buf, kevent->name, kevent->event.len)){ - ret = -EFAULT; - break; - } - buf += kevent->event.len; - count -= kevent->event.len; - } - free_kevent(kevent); - - mutex_lock(&dev->ev_mutex); + schedule(); } - mutex_unlock(&dev->ev_mutex); + finish_wait(&dev->wq, &wait); + if (start != buf && ret != -EFAULT) + ret = buf - start; return ret; } @@ -576,7 +589,7 @@ .destroy_watch = free_inotify_user_watch, }; -asmlinkage long sys_inotify_init1(int flags) +SYSCALL_DEFINE1(inotify_init1, int, flags) { struct inotify_device *dev; struct inotify_handle *ih; @@ -655,12 +668,13 @@ return ret; } -asmlinkage long sys_inotify_init(void) +SYSCALL_DEFINE0(inotify_init) { return sys_inotify_init1(0); } -asmlinkage long sys_inotify_add_watch(int fd, const char __user *pathname, u32 mask) +SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname, + u32, mask) { struct inode *inode; struct inotify_device *dev; @@ -704,7 +718,7 @@ return ret; } -asmlinkage long sys_inotify_rm_watch(int fd, u32 wd) +SYSCALL_DEFINE2(inotify_rm_watch, int, fd, __s32, wd) { struct file *filp; struct inotify_device *dev; --- linux-2.6.28.orig/fs/sync.c +++ linux-2.6.28/fs/sync.c @@ -36,7 +36,7 @@ laptop_sync_completion(); } -asmlinkage long sys_sync(void) +SYSCALL_DEFINE0(sync) { do_sync(1); return 0; @@ -118,12 +118,12 @@ return ret; } -asmlinkage long sys_fsync(unsigned int fd) +SYSCALL_DEFINE1(fsync, unsigned int, fd) { return __do_fsync(fd, 0); } -asmlinkage long sys_fdatasync(unsigned int fd) +SYSCALL_DEFINE1(fdatasync, unsigned int, fd) { return __do_fsync(fd, 1); } @@ -175,8 +175,8 @@ * already-instantiated disk blocks, there are no guarantees here that the data * will be available after a crash. */ -asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, - unsigned int flags) +SYSCALL_DEFINE(sync_file_range)(int fd, loff_t offset, loff_t nbytes, + unsigned int flags) { int ret; struct file *file; @@ -236,14 +236,32 @@ out: return ret; } +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_sync_file_range(long fd, loff_t offset, loff_t nbytes, + long flags) +{ + return SYSC_sync_file_range((int) fd, offset, nbytes, + (unsigned int) flags); +} +SYSCALL_ALIAS(sys_sync_file_range, SyS_sync_file_range); +#endif /* It would be nice if people remember that not all the world's an i386 when they introduce new system calls */ -asmlinkage long sys_sync_file_range2(int fd, unsigned int flags, - loff_t offset, loff_t nbytes) +SYSCALL_DEFINE(sync_file_range2)(int fd, unsigned int flags, + loff_t offset, loff_t nbytes) { return sys_sync_file_range(fd, offset, nbytes, flags); } +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_sync_file_range2(long fd, long flags, + loff_t offset, loff_t nbytes) +{ + return SYSC_sync_file_range2((int) fd, (unsigned int) flags, + offset, nbytes); +} +SYSCALL_ALIAS(sys_sync_file_range2, SyS_sync_file_range2); +#endif /* * `endbyte' is inclusive @@ -269,7 +287,7 @@ if (flags & SYNC_FILE_RANGE_WRITE) { ret = __filemap_fdatawrite_range(mapping, offset, endbyte, - WB_SYNC_NONE); + WB_SYNC_ALL); if (ret < 0) goto out; } --- linux-2.6.28.orig/fs/dcookies.c +++ linux-2.6.28/fs/dcookies.c @@ -140,7 +140,7 @@ /* And here is where the userspace process can look up the cookie value * to retrieve the path. */ -asmlinkage long sys_lookup_dcookie(u64 cookie64, char __user * buf, size_t len) +SYSCALL_DEFINE(lookup_dcookie)(u64 cookie64, char __user * buf, size_t len) { unsigned long cookie = (unsigned long)cookie64; int err = -EINVAL; @@ -193,7 +193,13 @@ mutex_unlock(&dcookie_mutex); return err; } - +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_lookup_dcookie(u64 cookie64, long buf, long len) +{ + return SYSC_lookup_dcookie(cookie64, (char __user *) buf, (size_t) len); +} +SYSCALL_ALIAS(sys_lookup_dcookie, SyS_lookup_dcookie); +#endif static int dcookie_init(void) { --- linux-2.6.28.orig/fs/eventfd.c +++ linux-2.6.28/fs/eventfd.c @@ -198,7 +198,7 @@ return file; } -asmlinkage long sys_eventfd2(unsigned int count, int flags) +SYSCALL_DEFINE2(eventfd2, unsigned int, count, int, flags) { int fd; struct eventfd_ctx *ctx; @@ -228,8 +228,7 @@ return fd; } -asmlinkage long sys_eventfd(unsigned int count) +SYSCALL_DEFINE1(eventfd, unsigned int, count) { return sys_eventfd2(count, 0); } - --- linux-2.6.28.orig/fs/splice.c +++ linux-2.6.28/fs/splice.c @@ -887,8 +887,8 @@ /* * Attempt to initiate a splice from pipe to file. */ -static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, - loff_t *ppos, size_t len, unsigned int flags) +long do_splice_from(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags) { int ret; @@ -907,13 +907,14 @@ return out->f_op->splice_write(pipe, out, ppos, len, flags); } +EXPORT_SYMBOL(do_splice_from); /* * Attempt to initiate a splice from a file to a pipe. */ -static long do_splice_to(struct file *in, loff_t *ppos, - struct pipe_inode_info *pipe, size_t len, - unsigned int flags) +long do_splice_to(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags) { int ret; @@ -929,6 +930,7 @@ return in->f_op->splice_read(in, ppos, pipe, len, flags); } +EXPORT_SYMBOL(do_splice_to); /** * splice_direct_to_actor - splices data directly between two non-pipes @@ -1434,8 +1436,8 @@ * Currently we punt and implement it as a normal copy, see pipe_to_user(). * */ -asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov, - unsigned long nr_segs, unsigned int flags) +SYSCALL_DEFINE4(vmsplice, int, fd, const struct iovec __user *, iov, + unsigned long, nr_segs, unsigned int, flags) { struct file *file; long error; @@ -1460,9 +1462,9 @@ return error; } -asmlinkage long sys_splice(int fd_in, loff_t __user *off_in, - int fd_out, loff_t __user *off_out, - size_t len, unsigned int flags) +SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in, + int, fd_out, loff_t __user *, off_out, + size_t, len, unsigned int, flags) { long error; struct file *in, *out; @@ -1684,7 +1686,7 @@ return ret; } -asmlinkage long sys_tee(int fdin, int fdout, size_t len, unsigned int flags) +SYSCALL_DEFINE4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags) { struct file *in; int error, fput_in; --- linux-2.6.28.orig/fs/compat_ioctl.c +++ linux-2.6.28/fs/compat_ioctl.c @@ -538,6 +538,7 @@ * cannot be fixed without breaking all existing apps. */ case TUNSETIFF: + case TUNGETIFF: case SIOCGIFFLAGS: case SIOCGIFMETRIC: case SIOCGIFMTU: @@ -1937,6 +1938,8 @@ /* Big K */ COMPATIBLE_IOCTL(PIO_FONT) COMPATIBLE_IOCTL(GIO_FONT) +COMPATIBLE_IOCTL(PIO_CMAP) +COMPATIBLE_IOCTL(GIO_CMAP) ULONG_IOCTL(KDSIGACCEPT) COMPATIBLE_IOCTL(KDGETKEYCODE) COMPATIBLE_IOCTL(KDSETKEYCODE) @@ -1982,6 +1985,11 @@ COMPATIBLE_IOCTL(TUNSETDEBUG) COMPATIBLE_IOCTL(TUNSETPERSIST) COMPATIBLE_IOCTL(TUNSETOWNER) +COMPATIBLE_IOCTL(TUNSETLINK) +COMPATIBLE_IOCTL(TUNSETGROUP) +COMPATIBLE_IOCTL(TUNGETFEATURES) +COMPATIBLE_IOCTL(TUNSETOFFLOAD) +COMPATIBLE_IOCTL(TUNSETTXFILTER) /* Big V */ COMPATIBLE_IOCTL(VT_SETMODE) COMPATIBLE_IOCTL(VT_GETMODE) @@ -2573,6 +2581,7 @@ HANDLE_IOCTL(SIOCGIFTXQLEN, dev_ifsioc) HANDLE_IOCTL(SIOCSIFTXQLEN, dev_ifsioc) HANDLE_IOCTL(TUNSETIFF, dev_ifsioc) +HANDLE_IOCTL(TUNGETIFF, dev_ifsioc) HANDLE_IOCTL(SIOCETHTOOL, ethtool_ioctl) HANDLE_IOCTL(SIOCBONDENSLAVE, bond_ioctl) HANDLE_IOCTL(SIOCBONDRELEASE, bond_ioctl) --- linux-2.6.28.orig/fs/compat.c +++ linux-2.6.28/fs/compat.c @@ -1697,7 +1697,7 @@ } #ifdef HAVE_SET_RESTORE_SIGMASK -asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp, +static long do_compat_pselect(int n, compat_ulong_t __user *inp, compat_ulong_t __user *outp, compat_ulong_t __user *exp, struct compat_timespec __user *tsp, compat_sigset_t __user *sigmask, compat_size_t sigsetsize) @@ -1763,8 +1763,8 @@ (compat_size_t __user *)(sig+sizeof(up)))) return -EFAULT; } - return compat_sys_pselect7(n, inp, outp, exp, tsp, compat_ptr(up), - sigsetsize); + return do_compat_pselect(n, inp, outp, exp, tsp, compat_ptr(up), + sigsetsize); } asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds, --- linux-2.6.28.orig/fs/aio.c +++ linux-2.6.28/fs/aio.c @@ -428,7 +428,7 @@ req->private = NULL; req->ki_iovec = NULL; INIT_LIST_HEAD(&req->ki_run_list); - req->ki_eventfd = ERR_PTR(-EINVAL); + req->ki_eventfd = NULL; /* Check if the completion queue has enough free space to * accept an event from this io. @@ -470,8 +470,6 @@ { assert_spin_locked(&ctx->ctx_lock); - if (!IS_ERR(req->ki_eventfd)) - fput(req->ki_eventfd); if (req->ki_dtor) req->ki_dtor(req); if (req->ki_iovec != &req->ki_inline_vec) @@ -493,8 +491,11 @@ list_del(&req->ki_list); spin_unlock_irq(&fput_lock); - /* Complete the fput */ - __fput(req->ki_filp); + /* Complete the fput(s) */ + if (req->ki_filp != NULL) + __fput(req->ki_filp); + if (req->ki_eventfd != NULL) + __fput(req->ki_eventfd); /* Link the iocb into the context's free list */ spin_lock_irq(&ctx->ctx_lock); @@ -512,12 +513,14 @@ */ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req) { + int schedule_putreq = 0; + dprintk(KERN_DEBUG "aio_put(%p): f_count=%ld\n", req, atomic_long_read(&req->ki_filp->f_count)); assert_spin_locked(&ctx->ctx_lock); - req->ki_users --; + req->ki_users--; BUG_ON(req->ki_users < 0); if (likely(req->ki_users)) return 0; @@ -525,10 +528,23 @@ req->ki_cancel = NULL; req->ki_retry = NULL; - /* Must be done under the lock to serialise against cancellation. - * Call this aio_fput as it duplicates fput via the fput_work. + /* + * Try to optimize the aio and eventfd file* puts, by avoiding to + * schedule work in case it is not __fput() time. In normal cases, + * we would not be holding the last reference to the file*, so + * this function will be executed w/out any aio kthread wakeup. */ - if (unlikely(atomic_long_dec_and_test(&req->ki_filp->f_count))) { + if (unlikely(atomic_long_dec_and_test(&req->ki_filp->f_count))) + schedule_putreq++; + else + req->ki_filp = NULL; + if (req->ki_eventfd != NULL) { + if (unlikely(atomic_long_dec_and_test(&req->ki_eventfd->f_count))) + schedule_putreq++; + else + req->ki_eventfd = NULL; + } + if (unlikely(schedule_putreq)) { get_ioctx(ctx); spin_lock(&fput_lock); list_add(&req->ki_list, &fput_head); @@ -992,7 +1008,7 @@ * eventfd. The eventfd_signal() function is safe to be called * from IRQ context. */ - if (!IS_ERR(iocb->ki_eventfd)) + if (iocb->ki_eventfd != NULL) eventfd_signal(iocb->ki_eventfd, 1); put_rq: @@ -1258,7 +1274,7 @@ * pointer is passed for ctxp. Will fail with -ENOSYS if not * implemented. */ -asmlinkage long sys_io_setup(unsigned nr_events, aio_context_t __user *ctxp) +SYSCALL_DEFINE2(io_setup, unsigned, nr_events, aio_context_t __user *, ctxp) { struct kioctx *ioctx = NULL; unsigned long ctx; @@ -1296,7 +1312,7 @@ * implemented. May fail with -EFAULT if the context pointed to * is invalid. */ -asmlinkage long sys_io_destroy(aio_context_t ctx) +SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx) { struct kioctx *ioctx = lookup_ioctx(ctx); if (likely(NULL != ioctx)) { @@ -1596,6 +1612,7 @@ req->ki_eventfd = eventfd_fget((int) iocb->aio_resfd); if (IS_ERR(req->ki_eventfd)) { ret = PTR_ERR(req->ki_eventfd); + req->ki_eventfd = NULL; goto out_put_req; } } @@ -1650,8 +1667,8 @@ * are available to queue any iocbs. Will return 0 if nr is 0. Will * fail with -ENOSYS if not implemented. */ -asmlinkage long sys_io_submit(aio_context_t ctx_id, long nr, - struct iocb __user * __user *iocbpp) +SYSCALL_DEFINE3(io_submit, aio_context_t, ctx_id, long, nr, + struct iocb __user * __user *, iocbpp) { struct kioctx *ctx; long ret = 0; @@ -1725,8 +1742,8 @@ * invalid. May fail with -EAGAIN if the iocb specified was not * cancelled. Will fail with -ENOSYS if not implemented. */ -asmlinkage long sys_io_cancel(aio_context_t ctx_id, struct iocb __user *iocb, - struct io_event __user *result) +SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb, + struct io_event __user *, result) { int (*cancel)(struct kiocb *iocb, struct io_event *res); struct kioctx *ctx; @@ -1787,11 +1804,11 @@ * will be updated if not NULL and the operation blocks. Will fail * with -ENOSYS if not implemented. */ -asmlinkage long sys_io_getevents(aio_context_t ctx_id, - long min_nr, - long nr, - struct io_event __user *events, - struct timespec __user *timeout) +SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id, + long, min_nr, + long, nr, + struct io_event __user *, events, + struct timespec __user *, timeout) { struct kioctx *ioctx = lookup_ioctx(ctx_id); long ret = -EINVAL; --- linux-2.6.28.orig/fs/filesystems.c +++ linux-2.6.28/fs/filesystems.c @@ -179,7 +179,7 @@ /* * Whee.. Weird sysv syscall. */ -asmlinkage long sys_sysfs(int option, unsigned long arg1, unsigned long arg2) +SYSCALL_DEFINE3(sysfs, int, option, unsigned long, arg1, unsigned long, arg2) { int retval = -EINVAL; --- linux-2.6.28.orig/fs/buffer.c +++ linux-2.6.28/fs/buffer.c @@ -1988,7 +1988,7 @@ page = *pagep; if (page == NULL) { ownpage = 1; - page = __grab_cache_page(mapping, index); + page = grab_cache_page_write_begin(mapping, index, flags); if (!page) { status = -ENOMEM; goto out; @@ -2494,7 +2494,7 @@ from = pos & (PAGE_CACHE_SIZE - 1); to = from + len; - page = __grab_cache_page(mapping, index); + page = grab_cache_page_write_begin(mapping, index, flags); if (!page) return -ENOMEM; *pagep = page; @@ -3177,7 +3177,7 @@ * Use of bdflush() is deprecated and will be removed in a future kernel. * The `pdflush' kernel threads fully replace bdflush daemons and this call. */ -asmlinkage long sys_bdflush(int func, long data) +SYSCALL_DEFINE2(bdflush, int, func, long, data) { static int msg_count; --- linux-2.6.28.orig/fs/nfsctl.c +++ linux-2.6.28/fs/nfsctl.c @@ -82,8 +82,8 @@ }, }; -long -asmlinkage sys_nfsservctl(int cmd, struct nfsctl_arg __user *arg, void __user *res) +SYSCALL_DEFINE3(nfsservctl, int, cmd, struct nfsctl_arg __user *, arg, + void __user *, res) { struct file *file; void __user *p = &arg->u; --- linux-2.6.28.orig/fs/seq_file.c +++ linux-2.6.28/fs/seq_file.c @@ -48,12 +48,78 @@ */ file->f_version = 0; - /* SEQ files support lseek, but not pread/pwrite */ - file->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE); + /* + * seq_files support lseek() and pread(). They do not implement + * write() at all, but we clear FMODE_PWRITE here for historical + * reasons. + * + * If a client of seq_files a) implements file.write() and b) wishes to + * support pwrite() then that client will need to implement its own + * file.open() which calls seq_open() and then sets FMODE_PWRITE. + */ + file->f_mode &= ~FMODE_PWRITE; return 0; } EXPORT_SYMBOL(seq_open); +static int traverse(struct seq_file *m, loff_t offset) +{ + loff_t pos = 0, index; + int error = 0; + void *p; + + m->version = 0; + index = 0; + m->count = m->from = 0; + if (!offset) { + m->index = index; + return 0; + } + if (!m->buf) { + m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL); + if (!m->buf) + return -ENOMEM; + } + p = m->op->start(m, &index); + while (p) { + error = PTR_ERR(p); + if (IS_ERR(p)) + break; + error = m->op->show(m, p); + if (error < 0) + break; + if (unlikely(error)) { + error = 0; + m->count = 0; + } + if (m->count == m->size) + goto Eoverflow; + if (pos + m->count > offset) { + m->from = offset - pos; + m->count -= m->from; + m->index = index; + break; + } + pos += m->count; + m->count = 0; + if (pos == offset) { + index++; + m->index = index; + break; + } + p = m->op->next(m, p, &index); + } + m->op->stop(m, p); + m->index = index; + return error; + +Eoverflow: + m->op->stop(m, p); + kfree(m->buf); + m->buf = kmalloc(m->size <<= 1, GFP_KERNEL); + return !m->buf ? -ENOMEM : -EAGAIN; +} + /** * seq_read - ->read() method for sequential files. * @file: the file to read from @@ -73,6 +139,22 @@ int err = 0; mutex_lock(&m->lock); + + /* Don't assume *ppos is where we left it */ + if (unlikely(*ppos != m->read_pos)) { + m->read_pos = *ppos; + while ((err = traverse(m, *ppos)) == -EAGAIN) + ; + if (err) { + /* With prejudice... */ + m->read_pos = 0; + m->version = 0; + m->index = 0; + m->count = 0; + goto Done; + } + } + /* * seq_file->op->..m_start/m_stop/m_next may do special actions * or optimisations based on the file->f_version, so we want to @@ -172,8 +254,10 @@ Done: if (!copied) copied = err; - else + else { *ppos += copied; + m->read_pos += copied; + } file->f_version = m->version; mutex_unlock(&m->lock); return copied; @@ -186,63 +270,6 @@ } EXPORT_SYMBOL(seq_read); -static int traverse(struct seq_file *m, loff_t offset) -{ - loff_t pos = 0, index; - int error = 0; - void *p; - - m->version = 0; - index = 0; - m->count = m->from = 0; - if (!offset) { - m->index = index; - return 0; - } - if (!m->buf) { - m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL); - if (!m->buf) - return -ENOMEM; - } - p = m->op->start(m, &index); - while (p) { - error = PTR_ERR(p); - if (IS_ERR(p)) - break; - error = m->op->show(m, p); - if (error < 0) - break; - if (unlikely(error)) { - error = 0; - m->count = 0; - } - if (m->count == m->size) - goto Eoverflow; - if (pos + m->count > offset) { - m->from = offset - pos; - m->count -= m->from; - m->index = index; - break; - } - pos += m->count; - m->count = 0; - if (pos == offset) { - index++; - m->index = index; - break; - } - p = m->op->next(m, p, &index); - } - m->op->stop(m, p); - return error; - -Eoverflow: - m->op->stop(m, p); - kfree(m->buf); - m->buf = kmalloc(m->size <<= 1, GFP_KERNEL); - return !m->buf ? -ENOMEM : -EAGAIN; -} - /** * seq_lseek - ->llseek() method for sequential files. * @file: the file in question @@ -265,16 +292,18 @@ if (offset < 0) break; retval = offset; - if (offset != file->f_pos) { + if (offset != m->read_pos) { while ((retval=traverse(m, offset)) == -EAGAIN) ; if (retval) { /* with extreme prejudice... */ file->f_pos = 0; + m->read_pos = 0; m->version = 0; m->index = 0; m->count = 0; } else { + m->read_pos = offset; retval = file->f_pos = offset; } } @@ -412,9 +441,7 @@ char *s = m->buf + m->count; char *p; - spin_lock(&dcache_lock); - p = __d_path(path, root, s, m->size - m->count); - spin_unlock(&dcache_lock); + p = __d_path(path, root, s, m->size - m->count, 0); err = PTR_ERR(p); if (!IS_ERR(p)) { s = mangle_path(s, p, esc); --- linux-2.6.28.orig/fs/minix/dir.c +++ linux-2.6.28/fs/minix/dir.c @@ -280,7 +280,7 @@ return -EINVAL; got_it: - pos = (page->index >> PAGE_CACHE_SHIFT) + p - (char*)page_address(page); + pos = page_offset(page) + p - (char *)page_address(page); err = __minix_write_begin(NULL, page->mapping, pos, sbi->s_dirsize, AOP_FLAG_UNINTERRUPTIBLE, &page, NULL); if (err) --- linux-2.6.28.orig/fs/lockd/svclock.c +++ linux-2.6.28/fs/lockd/svclock.c @@ -427,7 +427,7 @@ goto out; case -EAGAIN: ret = nlm_lck_denied; - goto out; + break; case FILE_LOCK_DEFERRED: if (wait) break; @@ -443,6 +443,10 @@ goto out; } + ret = nlm_lck_denied; + if (!wait) + goto out; + ret = nlm_lck_blocked; /* Append to list of blocked */ --- linux-2.6.28.orig/fs/cifs/CHANGES +++ linux-2.6.28/fs/cifs/CHANGES @@ -1,3 +1,5 @@ +Fix oops in cifs_dfs_ref.c when prefixpath is not reachable when using DFS. + Version 1.55 ------------ Various fixes to make delete of open files behavior more predictable --- linux-2.6.28.orig/fs/cifs/file.c +++ linux-2.6.28/fs/cifs/file.c @@ -2073,7 +2073,7 @@ cFYI(1, ("write_begin from %lld len %d", (long long)pos, len)); - page = __grab_cache_page(mapping, index); + page = grab_cache_page_write_begin(mapping, index, flags); if (!page) { rc = -ENOMEM; goto out; --- linux-2.6.28.orig/fs/cifs/sess.c +++ linux-2.6.28/fs/cifs/sess.c @@ -228,7 +228,7 @@ kfree(ses->serverOS); /* UTF-8 string will not grow more than four times as big as UCS-16 */ - ses->serverOS = kzalloc(4 * len, GFP_KERNEL); + ses->serverOS = kzalloc((4 * len) + 2 /* trailing null */, GFP_KERNEL); if (ses->serverOS != NULL) cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp); data += 2 * (len + 1); @@ -241,7 +241,7 @@ return rc; kfree(ses->serverNOS); - ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */ + ses->serverNOS = kzalloc((4 * len) + 2 /* trailing null */, GFP_KERNEL); if (ses->serverNOS != NULL) { cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len, nls_cp); --- linux-2.6.28.orig/fs/cifs/connect.c +++ linux-2.6.28/fs/cifs/connect.c @@ -1356,7 +1356,7 @@ } static struct TCP_Server_Info * -cifs_find_tcp_session(struct sockaddr *addr) +cifs_find_tcp_session(struct sockaddr_storage *addr) { struct list_head *tmp; struct TCP_Server_Info *server; @@ -1376,11 +1376,11 @@ if (server->tcpStatus == CifsNew) continue; - if (addr->sa_family == AF_INET && + if (addr->ss_family == AF_INET && (addr4->sin_addr.s_addr != server->addr.sockAddr.sin_addr.s_addr)) continue; - else if (addr->sa_family == AF_INET6 && + else if (addr->ss_family == AF_INET6 && memcmp(&server->addr.sockAddr6.sin6_addr, &addr6->sin6_addr, sizeof(addr6->sin6_addr))) continue; @@ -2036,7 +2036,7 @@ int rc = 0; int xid; struct socket *csocket = NULL; - struct sockaddr addr; + struct sockaddr_storage addr; struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr; struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr; struct smb_vol volume_info; @@ -2048,7 +2048,7 @@ /* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */ - memset(&addr, 0, sizeof(struct sockaddr)); + memset(&addr, 0, sizeof(struct sockaddr_storage)); memset(&volume_info, 0, sizeof(struct smb_vol)); if (cifs_parse_mount_options(mount_data, devname, &volume_info)) { rc = -EINVAL; @@ -2078,9 +2078,9 @@ rc = cifs_inet_pton(AF_INET6, volume_info.UNCip, &sin_server6->sin6_addr.in6_u); if (rc > 0) - addr.sa_family = AF_INET6; + addr.ss_family = AF_INET6; } else { - addr.sa_family = AF_INET; + addr.ss_family = AF_INET; } if (rc <= 0) { @@ -2122,7 +2122,7 @@ srvTcp = cifs_find_tcp_session(&addr); if (!srvTcp) { /* create socket */ - if (addr.sa_family == AF_INET6) { + if (addr.ss_family == AF_INET6) { cFYI(1, ("attempting ipv6 connect")); /* BB should we allow ipv6 on port 139? */ /* other OS never observed in Wild doing 139 with v6 */ @@ -2153,7 +2153,7 @@ } else { srvTcp->noblocksnd = volume_info.noblocksnd; srvTcp->noautotune = volume_info.noautotune; - if (addr.sa_family == AF_INET6) + if (addr.ss_family == AF_INET6) memcpy(&srvTcp->addr.sockAddr6, sin_server6, sizeof(struct sockaddr_in6)); else --- linux-2.6.28.orig/fs/cifs/cifs_dfs_ref.c +++ linux-2.6.28/fs/cifs/cifs_dfs_ref.c @@ -122,7 +122,7 @@ char **devname) { int rc; - char *mountdata; + char *mountdata = NULL; int md_len; char *tkn_e; char *srvIP = NULL; @@ -136,10 +136,9 @@ *devname = cifs_get_share_name(ref->node_name); rc = dns_resolve_server_name_to_ip(*devname, &srvIP); if (rc != 0) { - cERROR(1, ("%s: Failed to resolve server part of %s to IP", - __func__, *devname)); - mountdata = ERR_PTR(rc); - goto compose_mount_options_out; + cERROR(1, ("%s: Failed to resolve server part of %s to IP: %d", + __func__, *devname, rc));; + goto compose_mount_options_err; } /* md_len = strlen(...) + 12 for 'sep+prefixpath=' * assuming that we have 'unc=' and 'ip=' in @@ -149,8 +148,8 @@ strlen(ref->node_name) + 12; mountdata = kzalloc(md_len+1, GFP_KERNEL); if (mountdata == NULL) { - mountdata = ERR_PTR(-ENOMEM); - goto compose_mount_options_out; + rc = -ENOMEM; + goto compose_mount_options_err; } /* copy all options except of unc,ip,prefixpath */ @@ -197,18 +196,32 @@ /* find & copy prefixpath */ tkn_e = strchr(ref->node_name + 2, '\\'); - if (tkn_e == NULL) /* invalid unc, missing share name*/ - goto compose_mount_options_out; + if (tkn_e == NULL) { + /* invalid unc, missing share name*/ + rc = -EINVAL; + goto compose_mount_options_err; + } + /* + * this function gives us a path with a double backslash prefix. We + * require a single backslash for DFS. Temporarily increment fullpath + * to put it in the proper form and decrement before freeing it. + */ fullpath = build_path_from_dentry(dentry); + if (!fullpath) { + rc = -ENOMEM; + goto compose_mount_options_err; + } + ++fullpath; tkn_e = strchr(tkn_e + 1, '\\'); - if (tkn_e || strlen(fullpath) - (ref->path_consumed)) { + if (tkn_e || (strlen(fullpath) - ref->path_consumed)) { strncat(mountdata, &sep, 1); strcat(mountdata, "prefixpath="); if (tkn_e) strcat(mountdata, tkn_e + 1); - strcat(mountdata, fullpath + (ref->path_consumed)); + strcat(mountdata, fullpath + ref->path_consumed); } + --fullpath; kfree(fullpath); /*cFYI(1,("%s: parent mountdata: %s", __func__,sb_mountdata));*/ @@ -217,6 +230,11 @@ compose_mount_options_out: kfree(srvIP); return mountdata; + +compose_mount_options_err: + kfree(mountdata); + mountdata = ERR_PTR(rc); + goto compose_mount_options_out; } @@ -309,13 +327,19 @@ goto out_err; } + /* + * The MSDFS spec states that paths in DFS referral requests and + * responses must be prefixed by a single '\' character instead of + * the double backslashes usually used in the UNC. This function + * gives us the latter, so we must adjust the result. + */ full_path = build_path_from_dentry(dentry); if (full_path == NULL) { rc = -ENOMEM; goto out_err; } - rc = get_dfs_path(xid, ses , full_path, cifs_sb->local_nls, + rc = get_dfs_path(xid, ses , full_path + 1, cifs_sb->local_nls, &num_referrals, &referrals, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); --- linux-2.6.28.orig/fs/udf/unicode.c +++ linux-2.6.28/fs/udf/unicode.c @@ -254,7 +254,7 @@ { const uint8_t *ocu; uint8_t cmp_id, ocu_len; - int i; + int i, len; ocu_len = ocu_i->u_len; @@ -279,8 +279,13 @@ if (cmp_id == 16) c = (c << 8) | ocu[i++]; - utf_o->u_len += nls->uni2char(c, &utf_o->u_name[utf_o->u_len], - UDF_NAME_LEN - utf_o->u_len); + len = nls->uni2char(c, &utf_o->u_name[utf_o->u_len], + UDF_NAME_LEN - utf_o->u_len); + /* Valid character? */ + if (len >= 0) + utf_o->u_len += len; + else + utf_o->u_name[utf_o->u_len++] = '?'; } utf_o->u_cmpID = 8; @@ -290,7 +295,8 @@ static int udf_NLStoCS0(struct nls_table *nls, dstring *ocu, struct ustr *uni, int length) { - unsigned len, i, max_val; + int len; + unsigned i, max_val; uint16_t uni_char; int u_len; @@ -302,8 +308,13 @@ u_len = 0U; for (i = 0U; i < uni->u_len; i++) { len = nls->char2uni(&uni->u_name[i], uni->u_len - i, &uni_char); - if (len <= 0) + if (!len) continue; + /* Invalid character, deal with it */ + if (len < 0) { + len = 1; + uni_char = '?'; + } if (uni_char > max_val) { max_val = 0xffffU; --- linux-2.6.28.orig/fs/reiserfs/xattr.c +++ linux-2.6.28/fs/reiserfs/xattr.c @@ -459,7 +459,7 @@ newattrs.ia_size = buffer_size; newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; mutex_lock_nested(&xinode->i_mutex, I_MUTEX_XATTR); - err = notify_change(dentry, &newattrs); + err = notify_change(dentry, NULL, &newattrs); if (err) goto out_filp; @@ -746,7 +746,7 @@ if (dir->d_inode->i_nlink <= 2) { root = get_xa_root(inode->i_sb, XATTR_REPLACE); reiserfs_write_lock_xattrs(inode->i_sb); - err = vfs_rmdir(root->d_inode, dir); + err = vfs_rmdir(root->d_inode, dir, NULL); reiserfs_write_unlock_xattrs(inode->i_sb); dput(root); } else { @@ -790,7 +790,7 @@ } if (!S_ISDIR(xafile->d_inode->i_mode)) - err = notify_change(xafile, attrs); + err = notify_change(xafile, NULL, attrs); dput(xafile); return err; @@ -834,7 +834,7 @@ goto out_dir; } - err = notify_change(dir, attrs); + err = notify_change(dir, NULL, attrs); unlock_kernel(); out_dir: --- linux-2.6.28.orig/fs/reiserfs/inode.c +++ linux-2.6.28/fs/reiserfs/inode.c @@ -2556,7 +2556,7 @@ } index = pos >> PAGE_CACHE_SHIFT; - page = __grab_cache_page(mapping, index); + page = grab_cache_page_write_begin(mapping, index, flags); if (!page) return -ENOMEM; *pagep = page; --- linux-2.6.28.orig/fs/ext3/namei.c +++ linux-2.6.28/fs/ext3/namei.c @@ -1357,7 +1357,7 @@ struct fake_dirent *fde; blocksize = dir->i_sb->s_blocksize; - dxtrace(printk("Creating index\n")); + dxtrace(printk(KERN_DEBUG "Creating index: inode %lu\n", dir->i_ino)); retval = ext3_journal_get_write_access(handle, bh); if (retval) { ext3_std_error(dir->i_sb, retval); @@ -1366,6 +1366,19 @@ } root = (struct dx_root *) bh->b_data; + /* The 0th block becomes the root, move the dirents out */ + fde = &root->dotdot; + de = (struct ext3_dir_entry_2 *)((char *)fde + + ext3_rec_len_from_disk(fde->rec_len)); + if ((char *) de >= (((char *) root) + blocksize)) { + ext3_error(dir->i_sb, __func__, + "invalid rec_len for '..' in inode %lu", + dir->i_ino); + brelse(bh); + return -EIO; + } + len = ((char *) root) + blocksize - (char *) de; + bh2 = ext3_append (handle, dir, &block, &retval); if (!(bh2)) { brelse(bh); @@ -1374,11 +1387,6 @@ EXT3_I(dir)->i_flags |= EXT3_INDEX_FL; data1 = bh2->b_data; - /* The 0th block becomes the root, move the dirents out */ - fde = &root->dotdot; - de = (struct ext3_dir_entry_2 *)((char *)fde + - ext3_rec_len_from_disk(fde->rec_len)); - len = ((char *) root) + blocksize - (char *) de; memcpy (data1, de, len); de = (struct ext3_dir_entry_2 *) data1; top = data1 + len; @@ -2170,8 +2178,7 @@ * We have a transaction open. All is sweetness. It also sets * i_size in generic_commit_write(). */ - err = __page_symlink(inode, symname, l, - mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); + err = __page_symlink(inode, symname, l, 1); if (err) { drop_nlink(inode); ext3_mark_inode_dirty(handle, inode); --- linux-2.6.28.orig/fs/ext3/inode.c +++ linux-2.6.28/fs/ext3/inode.c @@ -1160,7 +1160,7 @@ to = from + len; retry: - page = __grab_cache_page(mapping, index); + page = grab_cache_page_write_begin(mapping, index, flags); if (!page) return -ENOMEM; *pagep = page; --- linux-2.6.28.orig/fs/affs/file.c +++ linux-2.6.28/fs/affs/file.c @@ -628,7 +628,7 @@ } index = pos >> PAGE_CACHE_SHIFT; - page = __grab_cache_page(mapping, index); + page = grab_cache_page_write_begin(mapping, index, flags); if (!page) return -ENOMEM; *pagep = page; --- linux-2.6.28.orig/fs/jffs2/fs.c +++ linux-2.6.28/fs/jffs2/fs.c @@ -680,7 +680,13 @@ static int jffs2_flash_setup(struct jffs2_sb_info *c) { int ret = 0; +#ifdef CONFIG_ARCH_MXC_CANONICAL + if (c->mtd->type == MTD_NANDFLASH) { + if (!(c->mtd->flags & MTD_OOB_WRITEABLE)) + printk(KERN_INFO "JFFS2 doesn't use OOB.\n"); +#else if (jffs2_cleanmarker_oob(c)) { +#endif /* NAND flash... do setup accordingly */ ret = jffs2_nand_flash_setup(c); if (ret) @@ -713,7 +719,11 @@ void jffs2_flash_cleanup(struct jffs2_sb_info *c) { +#ifdef CONFIG_ARCH_MXC_CANONICAL + if (c->mtd->type == MTD_NANDFLASH) { +#else if (jffs2_cleanmarker_oob(c)) { +#endif jffs2_nand_flash_cleanup(c); } --- linux-2.6.28.orig/fs/jffs2/file.c +++ linux-2.6.28/fs/jffs2/file.c @@ -132,7 +132,7 @@ uint32_t pageofs = index << PAGE_CACHE_SHIFT; int ret = 0; - pg = __grab_cache_page(mapping, index); + pg = grab_cache_page_write_begin(mapping, index, flags); if (!pg) return -ENOMEM; *pagep = pg; --- linux-2.6.28.orig/fs/jffs2/os-linux.h +++ linux-2.6.28/fs/jffs2/os-linux.h @@ -110,7 +110,11 @@ #define jffs2_can_mark_obsolete(c) (c->mtd->flags & (MTD_BIT_WRITEABLE)) #endif +#ifdef CONFIG_ARCH_MXC_CANONICAL +#define jffs2_cleanmarker_oob(c) (c->mtd->type == MTD_NANDFLASH && (c->mtd->flags & MTD_OOB_WRITEABLE)) +#else #define jffs2_cleanmarker_oob(c) (c->mtd->type == MTD_NANDFLASH) +#endif #define jffs2_flash_write_oob(c, ofs, len, retlen, buf) ((c)->mtd->write_oob((c)->mtd, ofs, len, retlen, buf)) #define jffs2_flash_read_oob(c, ofs, len, retlen, buf) ((c)->mtd->read_oob((c)->mtd, ofs, len, retlen, buf)) --- linux-2.6.28.orig/fs/jffs2/readinode.c +++ linux-2.6.28/fs/jffs2/readinode.c @@ -220,7 +220,7 @@ struct jffs2_tmp_dnode_info *tn) { uint32_t fn_end = tn->fn->ofs + tn->fn->size; - struct jffs2_tmp_dnode_info *this; + struct jffs2_tmp_dnode_info *this, *ptn; dbg_readinode("insert fragment %#04x-%#04x, ver %u at %08x\n", tn->fn->ofs, fn_end, tn->version, ref_offset(tn->fn->raw)); @@ -251,11 +251,18 @@ if (this) { /* If the node is coincident with another at a lower address, back up until the other node is found. It may be relevant */ - while (this->overlapped) - this = tn_prev(this); - - /* First node should never be marked overlapped */ - BUG_ON(!this); + while (this->overlapped) { + ptn = tn_prev(this); + if (!ptn) { + /* + * We killed a node which set the overlapped + * flags during the scan. Fix it up. + */ + this->overlapped = 0; + break; + } + this = ptn; + } dbg_readinode("'this' found %#04x-%#04x (%s)\n", this->fn->ofs, this->fn->ofs + this->fn->size, this->fn ? "data" : "hole"); } @@ -360,7 +367,17 @@ } if (!this->overlapped) break; - this = tn_prev(this); + + ptn = tn_prev(this); + if (!ptn) { + /* + * We killed a node which set the overlapped + * flags during the scan. Fix it up. + */ + this->overlapped = 0; + break; + } + this = ptn; } } @@ -456,8 +473,15 @@ eat_last(&rii->tn_root, &last->rb); ver_insert(&ver_root, last); - if (unlikely(last->overlapped)) - continue; + if (unlikely(last->overlapped)) { + if (pen) + continue; + /* + * We killed a node which set the overlapped + * flags during the scan. Fix it up. + */ + last->overlapped = 0; + } /* Now we have a bunch of nodes in reverse version order, in the tree at ver_root. Most of the time, --- linux-2.6.28.orig/fs/proc/page.c +++ linux-2.6.28/fs/proc/page.c @@ -80,7 +80,7 @@ #define KPF_RECLAIM 9 #define KPF_BUDDY 10 -#define kpf_copy_bit(flags, srcpos, dstpos) (((flags >> srcpos) & 1) << dstpos) +#define kpf_copy_bit(flags, dstpos, srcpos) (((flags >> srcpos) & 1) << dstpos) static ssize_t kpageflags_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) @@ -107,7 +107,7 @@ else kflags = ppage->flags; - uflags = kpf_copy_bit(KPF_LOCKED, PG_locked, kflags) | + uflags = kpf_copy_bit(kflags, KPF_LOCKED, PG_locked) | kpf_copy_bit(kflags, KPF_ERROR, PG_error) | kpf_copy_bit(kflags, KPF_REFERENCED, PG_referenced) | kpf_copy_bit(kflags, KPF_UPTODATE, PG_uptodate) | --- linux-2.6.28.orig/fs/proc/Makefile +++ linux-2.6.28/fs/proc/Makefile @@ -25,3 +25,4 @@ proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o proc-$(CONFIG_PRINTK) += kmsg.o proc-$(CONFIG_PROC_PAGE_MONITOR) += page.o +proc-y += version_signature.o --- linux-2.6.28.orig/fs/proc/version_signature.c +++ linux-2.6.28/fs/proc/version_signature.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include +#include +#include + +static int version_signature_proc_show(struct seq_file *m, void *v) +{ + seq_printf(m, "%s\n", CONFIG_VERSION_SIGNATURE); + return 0; +} + +static int version_signature_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, version_signature_proc_show, NULL); +} + +static const struct file_operations version_signature_proc_fops = { + .open = version_signature_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init proc_version_signature_init(void) +{ + proc_create("version_signature", 0, NULL, &version_signature_proc_fops); + return 0; +} +module_init(proc_version_signature_init); --- linux-2.6.28.orig/fs/afs/file.c +++ linux-2.6.28/fs/afs/file.c @@ -36,6 +36,7 @@ .fsync = afs_fsync, .lock = afs_lock, .flock = afs_flock, + .fsetattr = afs_fsetattr, }; const struct inode_operations afs_file_inode_operations = { --- linux-2.6.28.orig/fs/afs/write.c +++ linux-2.6.28/fs/afs/write.c @@ -144,7 +144,7 @@ candidate->state = AFS_WBACK_PENDING; init_waitqueue_head(&candidate->waitq); - page = __grab_cache_page(mapping, index); + page = grab_cache_page_write_begin(mapping, index, flags); if (!page) { kfree(candidate); return -ENOMEM; --- linux-2.6.28.orig/fs/afs/internal.h +++ linux-2.6.28/fs/afs/internal.h @@ -548,6 +548,7 @@ extern int afs_validate(struct afs_vnode *, struct key *); extern int afs_getattr(struct vfsmount *, struct dentry *, struct kstat *); extern int afs_setattr(struct dentry *, struct iattr *); +extern int afs_fsetattr(struct file *, struct iattr *); extern void afs_clear_inode(struct inode *); /* --- linux-2.6.28.orig/fs/afs/inode.c +++ linux-2.6.28/fs/afs/inode.c @@ -358,7 +358,8 @@ /* * set the attributes of an inode */ -int afs_setattr(struct dentry *dentry, struct iattr *attr) +static int afs_do_setattr(struct dentry *dentry, struct iattr *attr, + struct file *file) { struct afs_vnode *vnode = AFS_FS_I(dentry->d_inode); struct key *key; @@ -380,8 +381,8 @@ afs_writeback_all(vnode); } - if (attr->ia_valid & ATTR_FILE) { - key = attr->ia_file->private_data; + if (file) { + key = file->private_data; } else { key = afs_request_key(vnode->volume->cell); if (IS_ERR(key)) { @@ -391,10 +392,20 @@ } ret = afs_vnode_setattr(vnode, key, attr); - if (!(attr->ia_valid & ATTR_FILE)) + if (!file) key_put(key); error: _leave(" = %d", ret); return ret; } + +int afs_setattr(struct dentry *dentry, struct iattr *attr) +{ + return afs_do_setattr(dentry, attr, NULL); +} + +int afs_fsetattr(struct file *file, struct iattr *attr) +{ + return afs_do_setattr(file->f_path.dentry, attr, file); +} --- linux-2.6.28.orig/fs/afs/dir.c +++ linux-2.6.28/fs/afs/dir.c @@ -46,6 +46,7 @@ .readdir = afs_readdir, .lock = afs_lock, .llseek = generic_file_llseek, + .fsetattr = afs_fsetattr, }; const struct inode_operations afs_dir_inode_operations = { --- linux-2.6.28.orig/fs/ubifs/file.c +++ linux-2.6.28/fs/ubifs/file.c @@ -219,7 +219,8 @@ } static int write_begin_slow(struct address_space *mapping, - loff_t pos, unsigned len, struct page **pagep) + loff_t pos, unsigned len, struct page **pagep, + unsigned flags) { struct inode *inode = mapping->host; struct ubifs_info *c = inode->i_sb->s_fs_info; @@ -247,7 +248,7 @@ if (unlikely(err)) return err; - page = __grab_cache_page(mapping, index); + page = grab_cache_page_write_begin(mapping, index, flags); if (unlikely(!page)) { ubifs_release_budget(c, &req); return -ENOMEM; @@ -438,7 +439,7 @@ return -EROFS; /* Try out the fast-path part first */ - page = __grab_cache_page(mapping, index); + page = grab_cache_page_write_begin(mapping, index, flags); if (unlikely(!page)) return -ENOMEM; @@ -483,7 +484,7 @@ unlock_page(page); page_cache_release(page); - return write_begin_slow(mapping, pos, len, pagep); + return write_begin_slow(mapping, pos, len, pagep, flags); } /* --- linux-2.6.28.orig/fs/smbfs/file.c +++ linux-2.6.28/fs/smbfs/file.c @@ -297,7 +297,7 @@ struct page **pagep, void **fsdata) { pgoff_t index = pos >> PAGE_CACHE_SHIFT; - *pagep = __grab_cache_page(mapping, index); + *pagep = grab_cache_page_write_begin(mapping, index, flags); if (!*pagep) return -ENOMEM; return 0; --- linux-2.6.28.orig/fs/jbd2/commit.c +++ linux-2.6.28/fs/jbd2/commit.c @@ -25,6 +25,7 @@ #include #include #include +#include /* * Default IO end handler for temporary BJ_IO buffer_heads. @@ -168,12 +169,34 @@ * This function along with journal_submit_commit_record * allows to write the commit record asynchronously. */ -static int journal_wait_on_commit_record(struct buffer_head *bh) +static int journal_wait_on_commit_record(journal_t *journal, + struct buffer_head *bh) { int ret = 0; +retry: clear_buffer_dirty(bh); wait_on_buffer(bh); + if (buffer_eopnotsupp(bh) && (journal->j_flags & JBD2_BARRIER)) { + printk(KERN_WARNING + "JBD2: wait_on_commit_record: sync failed on %s - " + "disabling barriers\n", journal->j_devname); + spin_lock(&journal->j_state_lock); + journal->j_flags &= ~JBD2_BARRIER; + spin_unlock(&journal->j_state_lock); + + lock_buffer(bh); + clear_buffer_dirty(bh); + set_buffer_uptodate(bh); + bh->b_end_io = journal_end_buffer_io_sync; + + ret = submit_bh(WRITE_SYNC, bh); + if (ret) { + unlock_buffer(bh); + return ret; + } + goto retry; + } if (unlikely(!buffer_uptodate(bh))) ret = -EIO; @@ -799,7 +822,7 @@ __jbd2_journal_abort_hard(journal); } if (!err && !is_journal_aborted(journal)) - err = journal_wait_on_commit_record(cbh); + err = journal_wait_on_commit_record(journal, cbh); if (err) jbd2_journal_abort(journal, err); --- linux-2.6.28.orig/fs/jbd2/transaction.c +++ linux-2.6.28/fs/jbd2/transaction.c @@ -2050,26 +2050,46 @@ } /* - * 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. + * File truncate and transaction commit interact with each other in a + * non-trivial way. If a transaction writing data block A is + * committing, we cannot discard the data by truncate until we have + * written them. Otherwise if we crashed after the transaction with + * write has committed but before the transaction with truncate has + * committed, we could see stale data in block A. This function is a + * helper to solve this problem. It starts writeout of the truncated + * part in case it is in the committing transaction. + * + * Filesystem code must call this function when inode is journaled in + * ordered mode before truncation happens and after the inode has been + * placed on orphan list with the new inode size. The second condition + * avoids the race that someone writes new data and we start + * committing the transaction after this function has been called but + * before a transaction for truncate is started (and furthermore it + * allows us to optimize the case where the addition to orphan list + * happens in the same transaction as write --- we don't have to write + * any data in such case). */ -int jbd2_journal_begin_ordered_truncate(struct jbd2_inode *inode, +int jbd2_journal_begin_ordered_truncate(journal_t *journal, + struct jbd2_inode *jinode, loff_t new_size) { - journal_t *journal; - transaction_t *commit_trans; + transaction_t *inode_trans, *commit_trans; int ret = 0; - if (!inode->i_transaction && !inode->i_next_transaction) + /* This is a quick check to avoid locking if not necessary */ + if (!jinode->i_transaction) goto out; - journal = inode->i_transaction->t_journal; + /* Locks are here just to force reading of recent values, it is + * enough that the transaction was not committing before we started + * a transaction adding the inode to orphan list */ 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, + spin_lock(&journal->j_list_lock); + inode_trans = jinode->i_transaction; + spin_unlock(&journal->j_list_lock); + if (inode_trans == commit_trans) { + ret = filemap_fdatawrite_range(jinode->i_vfs_inode->i_mapping, new_size, LLONG_MAX); if (ret) jbd2_journal_abort(journal, ret); --- linux-2.6.28.orig/fs/jbd2/journal.c +++ linux-2.6.28/fs/jbd2/journal.c @@ -430,7 +430,7 @@ } /* - * Called under j_state_lock. Returns true if a transaction was started. + * Called under j_state_lock. Returns true if a transaction commit was started. */ int __jbd2_log_start_commit(journal_t *journal, tid_t target) { @@ -498,7 +498,8 @@ /* * Start a commit of the current running transaction (if any). Returns true - * if a transaction was started, and fills its tid in at *ptid + * if a transaction is going to be committed (or is currently already + * committing), and fills its tid in at *ptid */ int jbd2_journal_start_commit(journal_t *journal, tid_t *ptid) { @@ -508,15 +509,19 @@ if (journal->j_running_transaction) { tid_t tid = journal->j_running_transaction->t_tid; - ret = __jbd2_log_start_commit(journal, tid); - if (ret && ptid) + __jbd2_log_start_commit(journal, tid); + /* There's a running transaction and we've just made sure + * it's commit has been scheduled. */ + if (ptid) *ptid = tid; - } else if (journal->j_committing_transaction && ptid) { + ret = 1; + } else if (journal->j_committing_transaction) { /* * If ext3_write_super() recently started a commit, then we * have to wait for completion of that transaction */ - *ptid = journal->j_committing_transaction->t_tid; + if (ptid) + *ptid = journal->j_committing_transaction->t_tid; ret = 1; } spin_unlock(&journal->j_state_lock); --- linux-2.6.28.orig/fs/ecryptfs/ecryptfs_kernel.h +++ linux-2.6.28/fs/ecryptfs/ecryptfs_kernel.h @@ -51,12 +51,16 @@ #define ECRYPTFS_VERSIONING_XATTR 0x00000010 #define ECRYPTFS_VERSIONING_MULTKEY 0x00000020 #define ECRYPTFS_VERSIONING_DEVMISC 0x00000040 +#define ECRYPTFS_VERSIONING_HMAC 0x00000080 +#define ECRYPTFS_VERSIONING_FILENAME_ENCRYPTION 0x00000100 +#define ECRYPTFS_VERSIONING_GCM 0x00000200 #define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \ | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH \ | ECRYPTFS_VERSIONING_PUBKEY \ | ECRYPTFS_VERSIONING_XATTR \ | ECRYPTFS_VERSIONING_MULTKEY \ - | ECRYPTFS_VERSIONING_DEVMISC) + | ECRYPTFS_VERSIONING_DEVMISC \ + | ECRYPTFS_VERSIONING_FILENAME_ENCRYPTION) #define ECRYPTFS_MAX_PASSWORD_LENGTH 64 #define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH #define ECRYPTFS_SALT_SIZE 8 @@ -199,6 +203,7 @@ #define ECRYPTFS_DEFAULT_CIPHER "aes" #define ECRYPTFS_DEFAULT_KEY_BYTES 16 #define ECRYPTFS_DEFAULT_HASH "md5" +#define ECRYPTFS_TAG_70_DIGEST ECRYPTFS_DEFAULT_HASH #define ECRYPTFS_TAG_1_PACKET_TYPE 0x01 #define ECRYPTFS_TAG_3_PACKET_TYPE 0x8C #define ECRYPTFS_TAG_11_PACKET_TYPE 0xED @@ -206,30 +211,64 @@ #define ECRYPTFS_TAG_65_PACKET_TYPE 0x41 #define ECRYPTFS_TAG_66_PACKET_TYPE 0x42 #define ECRYPTFS_TAG_67_PACKET_TYPE 0x43 +#define ECRYPTFS_TAG_70_PACKET_TYPE 0x46 /* FNEK-encrypted filename + * as dentry name */ +#define ECRYPTFS_TAG_71_PACKET_TYPE 0x47 /* FNEK-encrypted filename in + * metadata */ +#define ECRYPTFS_TAG_72_PACKET_TYPE 0x48 /* FEK-encrypted filename as + * dentry name */ +#define ECRYPTFS_TAG_73_PACKET_TYPE 0x49 /* FEK-encrypted filename as + * metadata */ +/* Constraint: ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES >= + * ECRYPTFS_MAX_IV_BYTES */ +#define ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES 16 +#define ECRYPTFS_NON_NULL 0x42 /* A reasonable substitute for NULL */ #define MD5_DIGEST_SIZE 16 +#define ECRYPTFS_TAG_70_DIGEST_SIZE MD5_DIGEST_SIZE +#define ECRYPTFS_FEK_ENCRYPTED_FILENAME_PREFIX "ECRYPTFS_FEK_ENCRYPTED." +#define ECRYPTFS_FEK_ENCRYPTED_FILENAME_PREFIX_SIZE 23 +#define ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX "ECRYPTFS_FNEK_ENCRYPTED." +#define ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE 24 +#define ECRYPTFS_ENCRYPTED_DENTRY_NAME_LEN (18 + 1 + 4 + 1 + 32) struct ecryptfs_key_sig { struct list_head crypt_stat_list; char keysig[ECRYPTFS_SIG_SIZE_HEX]; }; +struct ecryptfs_filename { + struct list_head crypt_stat_list; +#define ECRYPTFS_FILENAME_CONTAINS_DECRYPTED 0x00000001 + u32 flags; + u32 seq_no; + char *filename; + char *encrypted_filename; + size_t filename_size; + size_t encrypted_filename_size; + char fnek_sig[ECRYPTFS_SIG_SIZE_HEX]; + char dentry_name[ECRYPTFS_ENCRYPTED_DENTRY_NAME_LEN + 1]; +}; + /** * This is the primary struct associated with each encrypted file. * * TODO: cache align/pack? */ struct ecryptfs_crypt_stat { -#define ECRYPTFS_STRUCT_INITIALIZED 0x00000001 -#define ECRYPTFS_POLICY_APPLIED 0x00000002 -#define ECRYPTFS_NEW_FILE 0x00000004 -#define ECRYPTFS_ENCRYPTED 0x00000008 -#define ECRYPTFS_SECURITY_WARNING 0x00000010 -#define ECRYPTFS_ENABLE_HMAC 0x00000020 -#define ECRYPTFS_ENCRYPT_IV_PAGES 0x00000040 -#define ECRYPTFS_KEY_VALID 0x00000080 -#define ECRYPTFS_METADATA_IN_XATTR 0x00000100 -#define ECRYPTFS_VIEW_AS_ENCRYPTED 0x00000200 -#define ECRYPTFS_KEY_SET 0x00000400 +#define ECRYPTFS_STRUCT_INITIALIZED 0x00000001 +#define ECRYPTFS_POLICY_APPLIED 0x00000002 +#define ECRYPTFS_NEW_FILE 0x00000004 +#define ECRYPTFS_ENCRYPTED 0x00000008 +#define ECRYPTFS_SECURITY_WARNING 0x00000010 +#define ECRYPTFS_ENABLE_HMAC 0x00000020 +#define ECRYPTFS_ENCRYPT_IV_PAGES 0x00000040 +#define ECRYPTFS_KEY_VALID 0x00000080 +#define ECRYPTFS_METADATA_IN_XATTR 0x00000100 +#define ECRYPTFS_VIEW_AS_ENCRYPTED 0x00000200 +#define ECRYPTFS_KEY_SET 0x00000400 +#define ECRYPTFS_ENCRYPT_FILENAMES 0x00000800 +#define ECRYPTFS_ENCFN_USE_MOUNT_FNEK 0x00001000 +#define ECRYPTFS_ENCFN_USE_FEK 0x00002000 u32 flags; unsigned int file_version; size_t iv_bytes; @@ -289,6 +328,7 @@ */ struct ecryptfs_global_auth_tok { #define ECRYPTFS_AUTH_TOK_INVALID 0x00000001 +#define ECRYPTFS_AUTH_TOK_FNEK 0x00000002 u32 flags; struct list_head mount_crypt_stat_list; struct key *global_auth_tok_key; @@ -332,13 +372,20 @@ #define ECRYPTFS_XATTR_METADATA_ENABLED 0x00000002 #define ECRYPTFS_ENCRYPTED_VIEW_ENABLED 0x00000004 #define ECRYPTFS_MOUNT_CRYPT_STAT_INITIALIZED 0x00000008 +#define ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES 0x00000010 +#define ECRYPTFS_GLOBAL_ENCFN_USE_MOUNT_FNEK 0x00000020 +#define ECRYPTFS_GLOBAL_ENCFN_USE_FEK 0x00000040 u32 flags; struct list_head global_auth_tok_list; struct mutex global_auth_tok_list_mutex; size_t num_global_auth_toks; size_t global_default_cipher_key_size; + size_t global_default_fn_cipher_key_bytes; unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE + 1]; + unsigned char global_default_fn_cipher_name[ + ECRYPTFS_MAX_CIPHER_NAME_SIZE + 1]; + char global_default_fnek_sig[ECRYPTFS_SIG_SIZE_HEX + 1]; }; /* superblock private data. */ @@ -571,13 +618,21 @@ int ecryptfs_interpose(struct dentry *hidden_dentry, struct dentry *this_dentry, struct super_block *sb, u32 flags); +int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, + struct dentry *lower_dentry, + struct inode *ecryptfs_dir_inode, + struct nameidata *ecryptfs_nd); +int ecryptfs_decode_and_decrypt_filename(char **decrypted_name, + size_t *decrypted_name_size, + struct dentry *ecryptfs_dentry, + const char *name, size_t name_size); int ecryptfs_fill_zeros(struct file *file, loff_t new_length); -int ecryptfs_decode_filename(struct ecryptfs_crypt_stat *crypt_stat, - const char *name, int length, - char **decrypted_name); -int ecryptfs_encode_filename(struct ecryptfs_crypt_stat *crypt_stat, - const char *name, int length, - char **encoded_name); +int ecryptfs_encrypt_and_encode_filename( + char **encoded_name, + size_t *encoded_name_size, + struct ecryptfs_crypt_stat *crypt_stat, + struct ecryptfs_mount_crypt_stat *mount_crypt_stat, + const char *name, size_t name_size); struct dentry *ecryptfs_lower_dentry(struct dentry *this_dentry); void ecryptfs_dump_hex(char *data, int bytes); int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg, @@ -599,7 +654,7 @@ struct inode *ecryptfs_inode); int ecryptfs_read_and_validate_xattr_region(char *page_virt, struct dentry *ecryptfs_dentry); -u8 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat); +u8 ecryptfs_code_for_cipher_string(char *cipher_name, size_t key_bytes); int ecryptfs_cipher_code_to_string(char *str, u8 cipher_code); void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat); int ecryptfs_generate_key_packet_set(char *dest_base, @@ -641,7 +696,7 @@ int ecryptfs_add_keysig(struct ecryptfs_crypt_stat *crypt_stat, char *sig); int ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, - char *sig); + char *sig, u32 global_auth_tok_flags); int ecryptfs_get_global_auth_tok_for_sig( struct ecryptfs_global_auth_tok **global_auth_tok, struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig); @@ -693,5 +748,17 @@ struct dentry *lower_dentry, struct vfsmount *lower_mnt); int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry); +int +ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, + size_t *packet_size, + struct ecryptfs_mount_crypt_stat *mount_crypt_stat, + char *filename, size_t filename_size); +int +ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, + size_t *packet_size, + struct ecryptfs_mount_crypt_stat *mount_crypt_stat, + char *data, size_t max_packet_size); +int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat, + loff_t offset); #endif /* #ifndef ECRYPTFS_KERNEL_H */ --- linux-2.6.28.orig/fs/ecryptfs/file.c +++ linux-2.6.28/fs/ecryptfs/file.c @@ -77,27 +77,27 @@ /* Inspired by generic filldir in fs/readdir.c */ static int -ecryptfs_filldir(void *dirent, const char *name, int namelen, loff_t offset, - u64 ino, unsigned int d_type) +ecryptfs_filldir(void *dirent, const char *lower_name, int lower_namelen, + loff_t offset, u64 ino, unsigned int d_type) { - struct ecryptfs_crypt_stat *crypt_stat; struct ecryptfs_getdents_callback *buf = (struct ecryptfs_getdents_callback *)dirent; + size_t name_size; + char *name; int rc; - int decoded_length; - char *decoded_name; - crypt_stat = ecryptfs_dentry_to_private(buf->dentry)->crypt_stat; buf->filldir_called++; - decoded_length = ecryptfs_decode_filename(crypt_stat, name, namelen, - &decoded_name); - if (decoded_length < 0) { - rc = decoded_length; + rc = ecryptfs_decode_and_decrypt_filename(&name, &name_size, + buf->dentry, lower_name, + lower_namelen); + if (rc) { + printk(KERN_ERR "%s: Error attempting to decode and decrypt " + "filename [%s]; rc = [%d]\n", __func__, lower_name, + rc); goto out; } - rc = buf->filldir(buf->dirent, decoded_name, decoded_length, offset, - ino, d_type); - kfree(decoded_name); + rc = buf->filldir(buf->dirent, name, name_size, offset, ino, d_type); + kfree(name); if (rc >= 0) buf->entries_written++; out: @@ -106,8 +106,8 @@ /** * ecryptfs_readdir - * @file: The ecryptfs file struct - * @dirent: Directory entry + * @file: The eCryptfs directory file + * @dirent: Directory entry handle * @filldir: The filldir callback function */ static int ecryptfs_readdir(struct file *file, void *dirent, filldir_t filldir) --- linux-2.6.28.orig/fs/ecryptfs/crypto.c +++ linux-2.6.28/fs/ecryptfs/crypto.c @@ -175,8 +175,8 @@ * * Returns zero on success; non-zero on error. */ -static int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat, - loff_t offset) +int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat, + loff_t offset) { int rc = 0; char dst[MD5_DIGEST_SIZE]; @@ -924,6 +924,15 @@ crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) crypt_stat->flags |= ECRYPTFS_VIEW_AS_ENCRYPTED; + if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) { + crypt_stat->flags |= ECRYPTFS_ENCRYPT_FILENAMES; + if (mount_crypt_stat->flags + & ECRYPTFS_GLOBAL_ENCFN_USE_MOUNT_FNEK) + crypt_stat->flags |= ECRYPTFS_ENCFN_USE_MOUNT_FNEK; + else if (mount_crypt_stat->flags + & ECRYPTFS_GLOBAL_ENCFN_USE_FEK) + crypt_stat->flags |= ECRYPTFS_ENCFN_USE_FEK; + } } static int ecryptfs_copy_mount_wide_sigs_to_inode_sigs( @@ -937,6 +946,8 @@ list_for_each_entry(global_auth_tok, &mount_crypt_stat->global_auth_tok_list, mount_crypt_stat_list) { + if (global_auth_tok->flags & ECRYPTFS_AUTH_TOK_FNEK) + continue; rc = ecryptfs_add_keysig(crypt_stat, global_auth_tok->sig); if (rc) { printk(KERN_ERR "Error adding keysig; rc = [%d]\n", rc); @@ -1060,7 +1071,8 @@ static struct ecryptfs_flag_map_elem ecryptfs_flag_map[] = { {0x00000001, ECRYPTFS_ENABLE_HMAC}, {0x00000002, ECRYPTFS_ENCRYPTED}, - {0x00000004, ECRYPTFS_METADATA_IN_XATTR} + {0x00000004, ECRYPTFS_METADATA_IN_XATTR}, + {0x00000008, ECRYPTFS_ENCRYPT_FILENAMES} }; /** @@ -1149,19 +1161,20 @@ /** * ecryptfs_code_for_cipher_string - * @crypt_stat: The cryptographic context + * @cipher_name: The string alias for the cipher + * @key_bytes: Length of key in bytes; used for AES code selection * * Returns zero on no match, or the cipher code on match */ -u8 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat) +u8 ecryptfs_code_for_cipher_string(char *cipher_name, size_t key_bytes) { int i; u8 code = 0; struct ecryptfs_cipher_code_str_map_elem *map = ecryptfs_cipher_code_str_map; - if (strcmp(crypt_stat->cipher, "aes") == 0) { - switch (crypt_stat->key_size) { + if (strcmp(cipher_name, "aes") == 0) { + switch (key_bytes) { case 16: code = RFC2440_CIPHER_AES_128; break; @@ -1173,7 +1186,7 @@ } } else { for (i = 0; i < ARRAY_SIZE(ecryptfs_cipher_code_str_map); i++) - if (strcmp(crypt_stat->cipher, map[i].cipher_str) == 0){ + if (strcmp(cipher_name, map[i].cipher_str) == 0) { code = map[i].cipher_code; break; } @@ -1212,6 +1225,8 @@ &(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat); int rc; + if (crypt_stat->extent_size == 0) + crypt_stat->extent_size = ECRYPTFS_DEFAULT_EXTENT_SIZE; rc = ecryptfs_read_lower(data, 0, crypt_stat->extent_size, ecryptfs_inode); if (rc) { @@ -1221,7 +1236,6 @@ } if (!contains_ecryptfs_marker(data + ECRYPTFS_FILE_SIZE_BYTES)) { rc = -EINVAL; - ecryptfs_printk(KERN_DEBUG, "Valid marker not found\n"); } out: return rc; @@ -1310,14 +1324,13 @@ } static int -ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt_stat, - struct dentry *ecryptfs_dentry, - char *virt) +ecryptfs_write_metadata_to_contents(struct dentry *ecryptfs_dentry, + char *virt, size_t virt_len) { int rc; rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode, virt, - 0, crypt_stat->num_header_bytes_at_front); + 0, virt_len); if (rc) printk(KERN_ERR "%s: Error attempting to write header " "information to lower file; rc = [%d]\n", __func__, @@ -1327,7 +1340,6 @@ static int ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry, - struct ecryptfs_crypt_stat *crypt_stat, char *page_virt, size_t size) { int rc; @@ -1337,6 +1349,17 @@ return rc; } +static unsigned long ecryptfs_get_zeroed_pages(gfp_t gfp_mask, + unsigned int order) +{ + struct page *page; + + page = alloc_pages(gfp_mask | __GFP_ZERO, order); + if (page) + return (unsigned long) page_address(page); + return 0; +} + /** * ecryptfs_write_metadata * @ecryptfs_dentry: The eCryptfs dentry @@ -1353,7 +1376,9 @@ { struct ecryptfs_crypt_stat *crypt_stat = &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; + unsigned int order; char *virt; + size_t virt_len; size_t size = 0; int rc = 0; @@ -1369,33 +1394,35 @@ rc = -EINVAL; goto out; } + virt_len = crypt_stat->num_header_bytes_at_front; + order = get_order(virt_len); /* Released in this function */ - virt = (char *)get_zeroed_page(GFP_KERNEL); + virt = (char *)ecryptfs_get_zeroed_pages(GFP_KERNEL, order); if (!virt) { printk(KERN_ERR "%s: Out of memory\n", __func__); rc = -ENOMEM; goto out; } - rc = ecryptfs_write_headers_virt(virt, PAGE_CACHE_SIZE, &size, - crypt_stat, ecryptfs_dentry); + rc = ecryptfs_write_headers_virt(virt, virt_len, &size, crypt_stat, + ecryptfs_dentry); if (unlikely(rc)) { printk(KERN_ERR "%s: Error whilst writing headers; rc = [%d]\n", __func__, rc); goto out_free; } if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) - rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry, - crypt_stat, virt, size); + rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry, virt, + size); else - rc = ecryptfs_write_metadata_to_contents(crypt_stat, - ecryptfs_dentry, virt); + rc = ecryptfs_write_metadata_to_contents(ecryptfs_dentry, virt, + virt_len); if (rc) { printk(KERN_ERR "%s: Error writing metadata out to lower file; " "rc = [%d]\n", __func__, rc); goto out_free; } out_free: - free_page((unsigned long)virt); + free_pages((unsigned long)virt, order); out: return rc; } @@ -1628,95 +1655,95 @@ } /** - * ecryptfs_encode_filename - converts a plaintext file name to cipher text - * @crypt_stat: The crypt_stat struct associated with the file anem to encode - * @name: The plaintext name - * @length: The length of the plaintext - * @encoded_name: The encypted name - * - * Encrypts and encodes a filename into something that constitutes a - * valid filename for a filesystem, with printable characters. + * ecryptfs_encrypt_filename - encrypt filename * - * We assume that we have a properly initialized crypto context, - * pointed to by crypt_stat->tfm. + * CBC-encrypts the filename. We do not want to encrypt the same + * filename with the same key and IV, which may happen with hard + * links, so we prepend random bits to each filename. * - * TODO: Implement filename decoding and decryption here, in place of - * memcpy. We are keeping the framework around for now to (1) - * facilitate testing of the components needed to implement filename - * encryption and (2) to provide a code base from which other - * developers in the community can easily implement this feature. - * - * Returns the length of encoded filename; negative if error + * Returns zero on success; non-zero otherwise */ -int -ecryptfs_encode_filename(struct ecryptfs_crypt_stat *crypt_stat, - const char *name, int length, char **encoded_name) +static int +ecryptfs_encrypt_filename(struct ecryptfs_filename *filename, + struct ecryptfs_crypt_stat *crypt_stat, + struct ecryptfs_mount_crypt_stat *mount_crypt_stat) { - int error = 0; + int rc = 0; - (*encoded_name) = kmalloc(length + 2, GFP_KERNEL); - if (!(*encoded_name)) { - error = -ENOMEM; + filename->encrypted_filename = NULL; + filename->encrypted_filename_size = 0; + if ((crypt_stat && (crypt_stat->flags & ECRYPTFS_ENCFN_USE_MOUNT_FNEK)) + || (mount_crypt_stat && (mount_crypt_stat->flags + & ECRYPTFS_GLOBAL_ENCFN_USE_MOUNT_FNEK))) { + size_t packet_size; + size_t remaining_bytes; + + rc = ecryptfs_write_tag_70_packet( + NULL, NULL, + &filename->encrypted_filename_size, + mount_crypt_stat, NULL, + filename->filename_size); + if (rc) { + printk(KERN_ERR "%s: Error attempting to get packet " + "size for tag 72; rc = [%d]\n", __func__, + rc); + filename->encrypted_filename_size = 0; + goto out; + } + filename->encrypted_filename = + kmalloc(filename->encrypted_filename_size, GFP_KERNEL); + if (!filename->encrypted_filename) { + printk(KERN_ERR "%s: Out of memory whilst attempting " + "to kmalloc [%zd] bytes\n", __func__, + filename->encrypted_filename_size); + rc = -ENOMEM; + goto out; + } + remaining_bytes = filename->encrypted_filename_size; + rc = ecryptfs_write_tag_70_packet(filename->encrypted_filename, + &remaining_bytes, + &packet_size, + mount_crypt_stat, + filename->filename, + filename->filename_size); + if (rc) { + printk(KERN_ERR "%s: Error attempting to generate " + "tag 70 packet; rc = [%d]\n", __func__, + rc); + kfree(filename->encrypted_filename); + filename->encrypted_filename = NULL; + filename->encrypted_filename_size = 0; + goto out; + } + filename->encrypted_filename_size = packet_size; + } else { + printk(KERN_ERR "%s: No support for requested filename " + "encryption method in this release\n", __func__); + rc = -ENOTSUPP; goto out; } - /* TODO: Filename encryption is a scheduled feature for a - * future version of eCryptfs. This function is here only for - * the purpose of providing a framework for other developers - * to easily implement filename encryption. Hint: Replace this - * memcpy() with a call to encrypt and encode the - * filename, the set the length accordingly. */ - memcpy((void *)(*encoded_name), (void *)name, length); - (*encoded_name)[length] = '\0'; - error = length + 1; out: - return error; + return rc; } -/** - * ecryptfs_decode_filename - converts the cipher text name to plaintext - * @crypt_stat: The crypt_stat struct associated with the file - * @name: The filename in cipher text - * @length: The length of the cipher text name - * @decrypted_name: The plaintext name - * - * Decodes and decrypts the filename. - * - * We assume that we have a properly initialized crypto context, - * pointed to by crypt_stat->tfm. - * - * TODO: Implement filename decoding and decryption here, in place of - * memcpy. We are keeping the framework around for now to (1) - * facilitate testing of the components needed to implement filename - * encryption and (2) to provide a code base from which other - * developers in the community can easily implement this feature. - * - * Returns the length of decoded filename; negative if error - */ -int -ecryptfs_decode_filename(struct ecryptfs_crypt_stat *crypt_stat, - const char *name, int length, char **decrypted_name) +static int ecryptfs_copy_filename(char **copied_name, size_t *copied_name_size, + const char *name, size_t name_size) { - int error = 0; + int rc = 0; - (*decrypted_name) = kmalloc(length + 2, GFP_KERNEL); - if (!(*decrypted_name)) { - error = -ENOMEM; - goto out; - } - /* TODO: Filename encryption is a scheduled feature for a - * future version of eCryptfs. This function is here only for - * the purpose of providing a framework for other developers - * to easily implement filename encryption. Hint: Replace this - * memcpy() with a call to decode and decrypt the - * filename, the set the length accordingly. */ - memcpy((void *)(*decrypted_name), (void *)name, length); - (*decrypted_name)[length + 1] = '\0'; /* Only for convenience + (*copied_name) = kmalloc((name_size + 1), GFP_KERNEL); + if (!(*copied_name)) { + rc = -ENOMEM; + goto out; + } + memcpy((void *)(*copied_name), (void *)name, name_size); + (*copied_name)[(name_size)] = '\0'; /* Only for convenience * in printing out the * string in debug * messages */ - error = length; + (*copied_name_size) = name_size; out: - return error; + return rc; } /** @@ -1740,7 +1767,7 @@ *key_tfm = NULL; if (*key_size > ECRYPTFS_MAX_KEY_BYTES) { rc = -EINVAL; - printk(KERN_ERR "Requested key size is [%Zd] bytes; maximum " + printk(KERN_ERR "Requested key size is [%zd] bytes; maximum " "allowable is [%d]\n", *key_size, ECRYPTFS_MAX_KEY_BYTES); goto out; } @@ -1765,7 +1792,7 @@ get_random_bytes(dummy_key, *key_size); rc = crypto_blkcipher_setkey(*key_tfm, dummy_key, *key_size); if (rc) { - printk(KERN_ERR "Error attempting to set key of size [%Zd] for " + printk(KERN_ERR "Error attempting to set key of size [%zd] for " "cipher [%s]; rc = [%d]\n", *key_size, cipher_name, rc); rc = -EINVAL; goto out; @@ -1910,3 +1937,343 @@ mutex_unlock(&key_tfm_list_mutex); return rc; } + +/* 64 characters forming a 6-bit target field */ +static unsigned char *portable_filename_chars = ("-.0123456789ABCD" + "EFGHIJKLMNOPQRST" + "UVWXYZabcdefghij" + "klmnopqrstuvwxyz"); + +/* We could either offset on every reverse map or just pad some 0x00's + * at the front here */ +static const unsigned char filename_rev_map[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 15 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 23 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 31 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 39 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, /* 47 */ + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* 55 */ + 0x0A, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 63 */ + 0x00, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, /* 71 */ + 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, /* 79 */ + 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, /* 87 */ + 0x23, 0x24, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, /* 95 */ + 0x00, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, /* 103 */ + 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, /* 111 */ + 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, /* 119 */ + 0x3D, 0x3E, 0x3F +}; + +/** + * ecryptfs_encode_for_filename + * @dst: Destination location for encoded filename + * @dst_size: Size of the encoded filename in bytes + * @src: Source location for the filename to encode + * @src_size: Size of the source in bytes + */ +void ecryptfs_encode_for_filename(unsigned char *dst, size_t *dst_size, + unsigned char *src, size_t src_size) +{ + size_t num_blocks; + size_t block_num = 0; + size_t dst_offset = 0; + unsigned char last_block[3]; + + if (src_size == 0) { + (*dst_size) = 0; + goto out; + } + num_blocks = (src_size / 3); + if ((src_size % 3) == 0) { + memcpy(last_block, (&src[src_size - 3]), 3); + } else { + num_blocks++; + last_block[2] = 0x00; + switch (src_size % 3) { + case 1: + last_block[0] = src[src_size - 1]; + last_block[1] = 0x00; + break; + case 2: + last_block[0] = src[src_size - 2]; + last_block[1] = src[src_size - 1]; + } + } + (*dst_size) = (num_blocks * 4); + if (!dst) + goto out; + while (block_num < num_blocks) { + unsigned char *src_block; + unsigned char dst_block[4]; + + if (block_num == (num_blocks - 1)) + src_block = last_block; + else + src_block = &src[block_num * 3]; + dst_block[0] = ((src_block[0] >> 2) & 0x3F); + dst_block[1] = (((src_block[0] << 4) & 0x30) + | ((src_block[1] >> 4) & 0x0F)); + dst_block[2] = (((src_block[1] << 2) & 0x3C) + | ((src_block[2] >> 6) & 0x03)); + dst_block[3] = (src_block[2] & 0x3F); + dst[dst_offset++] = portable_filename_chars[dst_block[0]]; + dst[dst_offset++] = portable_filename_chars[dst_block[1]]; + dst[dst_offset++] = portable_filename_chars[dst_block[2]]; + dst[dst_offset++] = portable_filename_chars[dst_block[3]]; + block_num++; + } +out: + return; +} + +/** + * ecryptfs_decode_from_filename + * @dst: If NULL, this function only sets @dst_size and returns. If + * non-NULL, this function decodes the encoded octets in @src + * into the memory that @dst points to. + * @dst_size: Set to the size of the decoded string. + * @src: The encoded set of octets to decode. + * @src_size: The size of the encoded set of octets to decode. + */ +static void +ecryptfs_decode_from_filename(unsigned char *dst, size_t *dst_size, + const unsigned char *src, size_t src_size) +{ + u8 current_bit_offset = 0; + size_t src_byte_offset = 0; + size_t dst_byte_offset = 0; + + if (dst == NULL) { + /* Not exact; conservatively long. Every block of 4 + * encoded characters decodes into a block of 3 + * decoded characters. This segment of code provides + * the caller with the maximum amount of allocated + * space that @dst will need to point to in a + * subsequent call. */ + (*dst_size) = (((src_size + 1) * 3) / 4); + goto out; + } + while (src_byte_offset < src_size) { + unsigned char src_byte = + filename_rev_map[(int)src[src_byte_offset]]; + + switch (current_bit_offset) { + case 0: + dst[dst_byte_offset] = (src_byte << 2); + current_bit_offset = 6; + break; + case 6: + dst[dst_byte_offset++] |= (src_byte >> 4); + dst[dst_byte_offset] = ((src_byte & 0xF) + << 4); + current_bit_offset = 4; + break; + case 4: + dst[dst_byte_offset++] |= (src_byte >> 2); + dst[dst_byte_offset] = (src_byte << 6); + current_bit_offset = 2; + break; + case 2: + dst[dst_byte_offset++] |= (src_byte); + dst[dst_byte_offset] = 0; + current_bit_offset = 0; + break; + } + src_byte_offset++; + } + (*dst_size) = dst_byte_offset; +out: + return; +} + +/** + * ecryptfs_encrypt_and_encode_filename - converts a plaintext file name to cipher text + * @crypt_stat: The crypt_stat struct associated with the file anem to encode + * @name: The plaintext name + * @length: The length of the plaintext + * @encoded_name: The encypted name + * + * Encrypts and encodes a filename into something that constitutes a + * valid filename for a filesystem, with printable characters. + * + * We assume that we have a properly initialized crypto context, + * pointed to by crypt_stat->tfm. + * + * Returns zero on success; non-zero on otherwise + */ +int ecryptfs_encrypt_and_encode_filename( + char **encoded_name, + size_t *encoded_name_size, + struct ecryptfs_crypt_stat *crypt_stat, + struct ecryptfs_mount_crypt_stat *mount_crypt_stat, + const char *name, size_t name_size) +{ + size_t encoded_name_no_prefix_size; + int rc = 0; + + (*encoded_name) = NULL; + (*encoded_name_size) = 0; + if ((crypt_stat && (crypt_stat->flags & ECRYPTFS_ENCRYPT_FILENAMES)) + || (mount_crypt_stat && (mount_crypt_stat->flags + & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES))) { + struct ecryptfs_filename *filename; + + filename = kzalloc(sizeof(*filename), GFP_KERNEL); + if (!filename) { + printk(KERN_ERR "%s: Out of memory whilst attempting " + "to kzalloc [%zd] bytes\n", __func__, + sizeof(*filename)); + rc = -ENOMEM; + goto out; + } + filename->filename = (char *)name; + filename->filename_size = name_size; + rc = ecryptfs_encrypt_filename(filename, crypt_stat, + mount_crypt_stat); + if (rc) { + printk(KERN_ERR "%s: Error attempting to encrypt " + "filename; rc = [%d]\n", __func__, rc); + kfree(filename); + goto out; + } + ecryptfs_encode_for_filename( + NULL, &encoded_name_no_prefix_size, + filename->encrypted_filename, + filename->encrypted_filename_size); + if ((crypt_stat && (crypt_stat->flags + & ECRYPTFS_ENCFN_USE_MOUNT_FNEK)) + || (mount_crypt_stat + && (mount_crypt_stat->flags + & ECRYPTFS_GLOBAL_ENCFN_USE_MOUNT_FNEK))) + (*encoded_name_size) = + (ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE + + encoded_name_no_prefix_size); + else + (*encoded_name_size) = + (ECRYPTFS_FEK_ENCRYPTED_FILENAME_PREFIX_SIZE + + encoded_name_no_prefix_size); + (*encoded_name) = kmalloc((*encoded_name_size) + 1, GFP_KERNEL); + if (!(*encoded_name)) { + printk(KERN_ERR "%s: Out of memory whilst attempting " + "to kzalloc [%zd] bytes\n", __func__, + (*encoded_name_size)); + rc = -ENOMEM; + kfree(filename->encrypted_filename); + kfree(filename); + goto out; + } + if ((crypt_stat && (crypt_stat->flags + & ECRYPTFS_ENCFN_USE_MOUNT_FNEK)) + || (mount_crypt_stat + && (mount_crypt_stat->flags + & ECRYPTFS_GLOBAL_ENCFN_USE_MOUNT_FNEK))) { + memcpy((*encoded_name), + ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX, + ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE); + ecryptfs_encode_for_filename( + ((*encoded_name) + + ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE), + &encoded_name_no_prefix_size, + filename->encrypted_filename, + filename->encrypted_filename_size); + (*encoded_name_size) = + (ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE + + encoded_name_no_prefix_size); + (*encoded_name)[(*encoded_name_size)] = '\0'; + (*encoded_name_size)++; + } else { + rc = -ENOTSUPP; + } + if (rc) { + printk(KERN_ERR "%s: Error attempting to encode " + "encrypted filename; rc = [%d]\n", __func__, + rc); + kfree((*encoded_name)); + (*encoded_name) = NULL; + (*encoded_name_size) = 0; + } + kfree(filename->encrypted_filename); + kfree(filename); + } else { + rc = ecryptfs_copy_filename(encoded_name, + encoded_name_size, + name, name_size); + } +out: + return rc; +} + +/** + * ecryptfs_decode_and_decrypt_filename - converts the encoded cipher text name to decoded plaintext + * @plaintext_name: The plaintext name + * @plaintext_name_size: The plaintext name size + * @ecryptfs_dir_dentry: eCryptfs directory dentry + * @name: The filename in cipher text + * @name_size: The cipher text name size + * + * Decrypts and decodes the filename. + * + * Returns zero on error; non-zero otherwise + */ +int ecryptfs_decode_and_decrypt_filename(char **plaintext_name, + size_t *plaintext_name_size, + struct dentry *ecryptfs_dir_dentry, + const char *name, size_t name_size) +{ + struct ecryptfs_mount_crypt_stat *mount_crypt_stat = + &ecryptfs_superblock_to_private( + ecryptfs_dir_dentry->d_sb)->mount_crypt_stat; + char *decoded_name; + size_t decoded_name_size; + size_t packet_size; + int rc = 0; + + if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) + && !(mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) + && (name_size > ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE) + && (strncmp(name, ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX, + ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE) == 0)) { + const char *orig_name = name; + size_t orig_name_size = name_size; + + name += ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE; + name_size -= ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE; + ecryptfs_decode_from_filename(NULL, &decoded_name_size, + name, name_size); + decoded_name = kmalloc(decoded_name_size, GFP_KERNEL); + if (!decoded_name) { + printk(KERN_ERR "%s: Out of memory whilst attempting " + "to kmalloc [%zd] bytes\n", __func__, + decoded_name_size); + rc = -ENOMEM; + goto out; + } + ecryptfs_decode_from_filename(decoded_name, &decoded_name_size, + name, name_size); + rc = ecryptfs_parse_tag_70_packet(plaintext_name, + plaintext_name_size, + &packet_size, + mount_crypt_stat, + decoded_name, + decoded_name_size); + if (rc) { + printk(KERN_INFO "%s: Could not parse tag 70 packet " + "from filename; copying through filename " + "as-is\n", __func__); + rc = ecryptfs_copy_filename(plaintext_name, + plaintext_name_size, + orig_name, orig_name_size); + goto out_free; + } + } else { + rc = ecryptfs_copy_filename(plaintext_name, + plaintext_name_size, + name, name_size); + goto out; + } +out_free: + kfree(decoded_name); +out: + return rc; +} --- linux-2.6.28.orig/fs/ecryptfs/inode.c +++ linux-2.6.28/fs/ecryptfs/inode.c @@ -52,8 +52,7 @@ /** * ecryptfs_create_underlying_file * @lower_dir_inode: inode of the parent in the lower fs of the new file - * @lower_dentry: New file's dentry in the lower fs - * @ecryptfs_dentry: New file's dentry in ecryptfs + * @dentry: New file's dentry * @mode: The mode of the new file * @nd: nameidata of ecryptfs' parent's dentry & vfsmount * @@ -228,8 +227,7 @@ { int rc; - /* ecryptfs_do_create() calls ecryptfs_interpose(), which opens - * the crypt_stat->lower_file (persistent file) */ + /* ecryptfs_do_create() calls ecryptfs_interpose() */ rc = ecryptfs_do_create(directory_inode, ecryptfs_dentry, mode, nd); if (unlikely(rc)) { ecryptfs_printk(KERN_WARNING, "Failed to create file in" @@ -244,141 +242,96 @@ } /** - * ecryptfs_lookup - * @dir: inode - * @dentry: The dentry - * @nd: nameidata, may be NULL - * - * Find a file on disk. If the file does not exist, then we'll add it to the - * dentry cache and continue on to read it from the disk. + * ecryptfs_lookup_and_interpose_lower - Perform a lookup */ -static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, - struct nameidata *nd) +int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, + struct dentry *lower_dentry, + struct inode *ecryptfs_dir_inode, + struct nameidata *ecryptfs_nd) { - int rc = 0; struct dentry *lower_dir_dentry; - struct dentry *lower_dentry; struct vfsmount *lower_mnt; - char *encoded_name; - int encoded_namelen; - struct ecryptfs_crypt_stat *crypt_stat = NULL; + struct inode *lower_inode; struct ecryptfs_mount_crypt_stat *mount_crypt_stat; + struct ecryptfs_crypt_stat *crypt_stat; char *page_virt = NULL; - struct inode *lower_inode; u64 file_size; + int rc = 0; - lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent); - dentry->d_op = &ecryptfs_dops; - if ((dentry->d_name.len == 1 && !strcmp(dentry->d_name.name, ".")) - || (dentry->d_name.len == 2 - && !strcmp(dentry->d_name.name, ".."))) { - d_drop(dentry); - goto out; - } - encoded_namelen = ecryptfs_encode_filename(crypt_stat, - dentry->d_name.name, - dentry->d_name.len, - &encoded_name); - if (encoded_namelen < 0) { - rc = encoded_namelen; - d_drop(dentry); - goto out; - } - ecryptfs_printk(KERN_DEBUG, "encoded_name = [%s]; encoded_namelen " - "= [%d]\n", encoded_name, encoded_namelen); - lower_dentry = lookup_one_len(encoded_name, lower_dir_dentry, - encoded_namelen - 1); - kfree(encoded_name); - if (IS_ERR(lower_dentry)) { - ecryptfs_printk(KERN_ERR, "ERR from lower_dentry\n"); - rc = PTR_ERR(lower_dentry); - d_drop(dentry); - goto out; - } - lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent)); - ecryptfs_printk(KERN_DEBUG, "lower_dentry = [%p]; lower_dentry->" - "d_name.name = [%s]\n", lower_dentry, - lower_dentry->d_name.name); + lower_dir_dentry = lower_dentry->d_parent; + lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt( + ecryptfs_dentry->d_parent)); lower_inode = lower_dentry->d_inode; - fsstack_copy_attr_atime(dir, lower_dir_dentry->d_inode); + fsstack_copy_attr_atime(ecryptfs_dir_inode, lower_dir_dentry->d_inode); BUG_ON(!atomic_read(&lower_dentry->d_count)); - ecryptfs_set_dentry_private(dentry, + ecryptfs_set_dentry_private(ecryptfs_dentry, kmem_cache_alloc(ecryptfs_dentry_info_cache, GFP_KERNEL)); - if (!ecryptfs_dentry_to_private(dentry)) { + if (!ecryptfs_dentry_to_private(ecryptfs_dentry)) { rc = -ENOMEM; - ecryptfs_printk(KERN_ERR, "Out of memory whilst attempting " - "to allocate ecryptfs_dentry_info struct\n"); + printk(KERN_ERR "%s: Out of memory whilst attempting " + "to allocate ecryptfs_dentry_info struct\n", + __func__); goto out_dput; } - ecryptfs_set_dentry_lower(dentry, lower_dentry); - ecryptfs_set_dentry_lower_mnt(dentry, lower_mnt); + ecryptfs_set_dentry_lower(ecryptfs_dentry, lower_dentry); + ecryptfs_set_dentry_lower_mnt(ecryptfs_dentry, lower_mnt); if (!lower_dentry->d_inode) { /* We want to add because we couldn't find in lower */ - d_add(dentry, NULL); + d_add(ecryptfs_dentry, NULL); goto out; } - rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, - ECRYPTFS_INTERPOSE_FLAG_D_ADD); + rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry, + ecryptfs_dir_inode->i_sb, 1); if (rc) { - ecryptfs_printk(KERN_ERR, "Error interposing\n"); + printk(KERN_ERR "%s: Error interposing; rc = [%d]\n", + __func__, rc); goto out; } - if (S_ISDIR(lower_inode->i_mode)) { - ecryptfs_printk(KERN_DEBUG, "Is a directory; returning\n"); + if (S_ISDIR(lower_inode->i_mode)) goto out; - } - if (S_ISLNK(lower_inode->i_mode)) { - ecryptfs_printk(KERN_DEBUG, "Is a symlink; returning\n"); + if (S_ISLNK(lower_inode->i_mode)) goto out; - } - if (special_file(lower_inode->i_mode)) { - ecryptfs_printk(KERN_DEBUG, "Is a special file; returning\n"); + if (special_file(lower_inode->i_mode)) goto out; - } - if (!nd) { - ecryptfs_printk(KERN_DEBUG, "We have a NULL nd, just leave" - "as we *think* we are about to unlink\n"); + if (!ecryptfs_nd) goto out; - } /* Released in this function */ - page_virt = kmem_cache_zalloc(ecryptfs_header_cache_2, - GFP_USER); + page_virt = kmem_cache_zalloc(ecryptfs_header_cache_2, GFP_USER); if (!page_virt) { + printk(KERN_ERR "%s: Cannot kmem_cache_zalloc() a page\n", + __func__); rc = -ENOMEM; - ecryptfs_printk(KERN_ERR, - "Cannot ecryptfs_kmalloc a page\n"); goto out; } - crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; - if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) - ecryptfs_set_default_sizes(crypt_stat); - if (!ecryptfs_inode_to_private(dentry->d_inode)->lower_file) { - rc = ecryptfs_init_persistent_file(dentry); + if (!ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->lower_file) { + rc = ecryptfs_init_persistent_file(ecryptfs_dentry); if (rc) { printk(KERN_ERR "%s: Error attempting to initialize " "the persistent file for the dentry with name " "[%s]; rc = [%d]\n", __func__, - dentry->d_name.name, rc); - goto out; + ecryptfs_dentry->d_name.name, rc); + goto out_free_kmem; } } + crypt_stat = &ecryptfs_inode_to_private( + ecryptfs_dentry->d_inode)->crypt_stat; + /* TODO: lock for crypt_stat comparison */ + if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) + ecryptfs_set_default_sizes(crypt_stat); rc = ecryptfs_read_and_validate_header_region(page_virt, - dentry->d_inode); + ecryptfs_dentry->d_inode); if (rc) { - rc = ecryptfs_read_and_validate_xattr_region(page_virt, dentry); + rc = ecryptfs_read_and_validate_xattr_region(page_virt, + ecryptfs_dentry); if (rc) { - printk(KERN_DEBUG "Valid metadata not found in header " - "region or xattr region; treating file as " - "unencrypted\n"); rc = 0; - kmem_cache_free(ecryptfs_header_cache_2, page_virt); - goto out; + goto out_free_kmem; } crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; } mount_crypt_stat = &ecryptfs_superblock_to_private( - dentry->d_sb)->mount_crypt_stat; + ecryptfs_dentry->d_sb)->mount_crypt_stat; if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) { if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) file_size = (crypt_stat->num_header_bytes_at_front @@ -388,14 +341,90 @@ } else { file_size = get_unaligned_be64(page_virt); } - i_size_write(dentry->d_inode, (loff_t)file_size); + i_size_write(ecryptfs_dentry->d_inode, (loff_t)file_size); +out_free_kmem: kmem_cache_free(ecryptfs_header_cache_2, page_virt); goto out; - out_dput: dput(lower_dentry); - d_drop(dentry); + d_drop(ecryptfs_dentry); out: + return rc; +} + +/** + * ecryptfs_lookup + * @ecryptfs_dir_inode: The eCryptfs directory inode + * @ecryptfs_dentry: The eCryptfs dentry that we are looking up + * @ecryptfs_nd: nameidata; may be NULL + * + * Find a file on disk. If the file does not exist, then we'll add it to the + * dentry cache and continue on to read it from the disk. + */ +static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, + struct dentry *ecryptfs_dentry, + struct nameidata *ecryptfs_nd) +{ + char *encrypted_and_encoded_name = NULL; + size_t encrypted_and_encoded_name_size; + struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL; + struct dentry *lower_dir_dentry, *lower_dentry; + int rc = 0; + + ecryptfs_dentry->d_op = &ecryptfs_dops; + if ((ecryptfs_dentry->d_name.len == 1 + && !strcmp(ecryptfs_dentry->d_name.name, ".")) + || (ecryptfs_dentry->d_name.len == 2 + && !strcmp(ecryptfs_dentry->d_name.name, ".."))) { + goto out_d_drop; + } + lower_dir_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry->d_parent); + lower_dentry = lookup_one_len(ecryptfs_dentry->d_name.name, + lower_dir_dentry, + ecryptfs_dentry->d_name.len); + if (IS_ERR(lower_dentry)) { + rc = PTR_ERR(lower_dentry); + printk(KERN_ERR "%s: lookup_one_len() returned [%d] on " + "lower_dentry = [%s]\n", __func__, rc, + ecryptfs_dentry->d_name.name); + goto out_d_drop; + } + if (lower_dentry->d_inode) + goto lookup_and_interpose; + mount_crypt_stat = &ecryptfs_superblock_to_private( + ecryptfs_dentry->d_sb)->mount_crypt_stat; + if (!(mount_crypt_stat + && (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES))) + goto lookup_and_interpose; + dput(lower_dentry); + rc = ecryptfs_encrypt_and_encode_filename( + &encrypted_and_encoded_name, &encrypted_and_encoded_name_size, + NULL, mount_crypt_stat, ecryptfs_dentry->d_name.name, + ecryptfs_dentry->d_name.len); + if (rc) { + printk(KERN_ERR "%s: Error attempting to encrypt and encode " + "filename; rc = [%d]\n", __func__, rc); + goto out_d_drop; + } + lower_dentry = lookup_one_len(encrypted_and_encoded_name, + lower_dir_dentry, + encrypted_and_encoded_name_size - 1); + if (IS_ERR(lower_dentry)) { + rc = PTR_ERR(lower_dentry); + printk(KERN_ERR "%s: lookup_one_len() returned [%d] on " + "lower_dentry = [%s]\n", __func__, rc, + encrypted_and_encoded_name); + goto out_d_drop; + } +lookup_and_interpose: + rc = ecryptfs_lookup_and_interpose_lower(ecryptfs_dentry, lower_dentry, + ecryptfs_dir_inode, + ecryptfs_nd); + goto out; +out_d_drop: + d_drop(ecryptfs_dentry); +out: + kfree(encrypted_and_encoded_name); return ERR_PTR(rc); } @@ -403,19 +432,24 @@ struct dentry *new_dentry) { struct dentry *lower_old_dentry; + struct vfsmount *lower_old_mnt; struct dentry *lower_new_dentry; + struct vfsmount *lower_new_mnt; struct dentry *lower_dir_dentry; u64 file_size_save; int rc; file_size_save = i_size_read(old_dentry->d_inode); lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); + lower_old_mnt = ecryptfs_dentry_to_lower_mnt(old_dentry); lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); + lower_new_mnt = ecryptfs_dentry_to_lower_mnt(new_dentry); dget(lower_old_dentry); dget(lower_new_dentry); lower_dir_dentry = lock_parent(lower_new_dentry); - rc = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode, - lower_new_dentry); + rc = vfs_link(lower_old_dentry, lower_old_mnt, + lower_dir_dentry->d_inode, lower_new_dentry, + lower_new_mnt); if (rc || !lower_new_dentry->d_inode) goto out_lock; rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0); @@ -440,11 +474,12 @@ { int rc = 0; struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); + struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir); struct dentry *lower_dir_dentry; lower_dir_dentry = lock_parent(lower_dentry); - rc = vfs_unlink(lower_dir_inode, lower_dentry); + rc = vfs_unlink(lower_dir_inode, lower_dentry, lower_mnt); if (rc) { printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); goto out_unlock; @@ -464,22 +499,26 @@ { int rc; struct dentry *lower_dentry; + struct vfsmount *lower_mnt; struct dentry *lower_dir_dentry; char *encoded_symname; - int encoded_symlen; - struct ecryptfs_crypt_stat *crypt_stat = NULL; + size_t encoded_symlen; + struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL; lower_dentry = ecryptfs_dentry_to_lower(dentry); dget(lower_dentry); + lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); lower_dir_dentry = lock_parent(lower_dentry); - encoded_symlen = ecryptfs_encode_filename(crypt_stat, symname, - strlen(symname), - &encoded_symname); - if (encoded_symlen < 0) { - rc = encoded_symlen; + mount_crypt_stat = &ecryptfs_superblock_to_private( + dir->i_sb)->mount_crypt_stat; + rc = ecryptfs_encrypt_and_encode_filename(&encoded_symname, + &encoded_symlen, + NULL, + mount_crypt_stat, symname, + strlen(symname)); + if (rc) goto out_lock; - } - rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry, + rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry, lower_mnt, encoded_symname); kfree(encoded_symname); if (rc || !lower_dentry->d_inode) @@ -501,11 +540,14 @@ { int rc; struct dentry *lower_dentry; + struct vfsmount *lower_mnt; struct dentry *lower_dir_dentry; lower_dentry = ecryptfs_dentry_to_lower(dentry); + lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); lower_dir_dentry = lock_parent(lower_dentry); - rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, mode); + rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, lower_mnt, + mode); if (rc || !lower_dentry->d_inode) goto out; rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); @@ -524,14 +566,16 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) { struct dentry *lower_dentry; + struct vfsmount *lower_mnt; struct dentry *lower_dir_dentry; int rc; lower_dentry = ecryptfs_dentry_to_lower(dentry); + lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); dget(dentry); lower_dir_dentry = lock_parent(lower_dentry); dget(lower_dentry); - rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry); + rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry, lower_mnt); dput(lower_dentry); if (!rc) d_delete(lower_dentry); @@ -549,11 +593,14 @@ { int rc; struct dentry *lower_dentry; + struct vfsmount *lower_mnt; struct dentry *lower_dir_dentry; lower_dentry = ecryptfs_dentry_to_lower(dentry); + lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); lower_dir_dentry = lock_parent(lower_dentry); - rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev); + rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, lower_mnt, mode, + dev); if (rc || !lower_dentry->d_inode) goto out; rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0); @@ -574,19 +621,24 @@ { int rc; struct dentry *lower_old_dentry; + struct vfsmount *lower_old_mnt; struct dentry *lower_new_dentry; + struct vfsmount *lower_new_mnt; struct dentry *lower_old_dir_dentry; struct dentry *lower_new_dir_dentry; lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); + lower_old_mnt = ecryptfs_dentry_to_lower_mnt(old_dentry); lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); + lower_new_mnt = ecryptfs_dentry_to_lower_mnt(new_dentry); dget(lower_old_dentry); dget(lower_new_dentry); lower_old_dir_dentry = dget_parent(lower_old_dentry); lower_new_dir_dentry = dget_parent(lower_new_dentry); lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); rc = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry, - lower_new_dir_dentry->d_inode, lower_new_dentry); + lower_old_mnt, lower_new_dir_dentry->d_inode, + lower_new_dentry, lower_new_mnt); if (rc) goto out_lock; fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode, NULL); @@ -602,14 +654,15 @@ } static int -ecryptfs_readlink(struct dentry *dentry, char __user * buf, int bufsiz) +ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) { - int rc; - struct dentry *lower_dentry; - char *decoded_name; char *lower_buf; - mm_segment_t old_fs; + struct dentry *lower_dentry; struct ecryptfs_crypt_stat *crypt_stat; + char *plaintext_name; + size_t plaintext_name_size; + mm_segment_t old_fs; + int rc; lower_dentry = ecryptfs_dentry_to_lower(dentry); if (!lower_dentry->d_inode->i_op || @@ -617,38 +670,39 @@ rc = -EINVAL; goto out; } + crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; /* Released in this function */ lower_buf = kmalloc(bufsiz, GFP_KERNEL); if (lower_buf == NULL) { - ecryptfs_printk(KERN_ERR, "Out of memory\n"); + printk(KERN_ERR "%s: Out of memory whilst attempting to " + "kmalloc [%d] bytes\n", __func__, bufsiz); rc = -ENOMEM; goto out; } old_fs = get_fs(); set_fs(get_ds()); - ecryptfs_printk(KERN_DEBUG, "Calling readlink w/ " - "lower_dentry->d_name.name = [%s]\n", - lower_dentry->d_name.name); rc = lower_dentry->d_inode->i_op->readlink(lower_dentry, (char __user *)lower_buf, bufsiz); set_fs(old_fs); if (rc >= 0) { - crypt_stat = NULL; - rc = ecryptfs_decode_filename(crypt_stat, lower_buf, rc, - &decoded_name); - if (rc == -ENOMEM) + rc = ecryptfs_decode_and_decrypt_filename(&plaintext_name, + &plaintext_name_size, + dentry, lower_buf, + rc); + if (rc) { + printk(KERN_ERR "%s: Error attempting to decode and " + "decrypt filename; rc = [%d]\n", __func__, + rc); goto out_free_lower_buf; - if (rc > 0) { - ecryptfs_printk(KERN_DEBUG, "Copying [%d] bytes " - "to userspace: [%*s]\n", rc, - decoded_name); - if (copy_to_user(buf, decoded_name, rc)) - rc = -EFAULT; } - kfree(decoded_name); - fsstack_copy_attr_atime(dentry->d_inode, - lower_dentry->d_inode); + rc = copy_to_user(buf, plaintext_name, plaintext_name_size); + if (rc) + rc = -EFAULT; + else + rc = plaintext_name_size; + kfree(plaintext_name); + fsstack_copy_attr_atime(dentry->d_inode, lower_dentry->d_inode); } out_free_lower_buf: kfree(lower_buf); @@ -670,13 +724,12 @@ } old_fs = get_fs(); set_fs(get_ds()); - ecryptfs_printk(KERN_DEBUG, "Calling readlink w/ " - "dentry->d_name.name = [%s]\n", dentry->d_name.name); rc = dentry->d_inode->i_op->readlink(dentry, (char __user *)buf, len); - buf[rc] = '\0'; set_fs(old_fs); if (rc < 0) goto out_free; + else + buf[rc] = '\0'; rc = 0; nd_set_link(nd, buf); goto out; @@ -849,6 +902,7 @@ { int rc = 0; struct dentry *lower_dentry; + struct vfsmount *lower_mnt; struct inode *inode; struct inode *lower_inode; struct ecryptfs_crypt_stat *crypt_stat; @@ -859,6 +913,7 @@ inode = dentry->d_inode; lower_inode = ecryptfs_inode_to_lower(inode); lower_dentry = ecryptfs_dentry_to_lower(dentry); + lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); mutex_lock(&crypt_stat->cs_mutex); if (S_ISDIR(dentry->d_inode->i_mode)) crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); @@ -910,7 +965,7 @@ ia->ia_valid &= ~ATTR_MODE; mutex_lock(&lower_dentry->d_inode->i_mutex); - rc = notify_change(lower_dentry, ia); + rc = notify_change(lower_dentry, lower_mnt, ia); mutex_unlock(&lower_dentry->d_inode->i_mutex); out: fsstack_copy_attr_all(inode, lower_inode, NULL); --- linux-2.6.28.orig/fs/ecryptfs/miscdev.c +++ linux-2.6.28/fs/ecryptfs/miscdev.c @@ -200,7 +200,7 @@ if (!msg_ctx->msg) { rc = -ENOMEM; printk(KERN_ERR "%s: Out of memory whilst attempting " - "to kmalloc(%Zd, GFP_KERNEL)\n", __func__, + "to kmalloc(%zd, GFP_KERNEL)\n", __func__, (sizeof(*msg_ctx->msg) + data_size)); goto out_unlock; } @@ -323,7 +323,7 @@ if (count < total_length) { rc = 0; printk(KERN_WARNING "%s: Only given user buffer of " - "size [%Zd], but we need [%Zd] to read the " + "size [%zd], but we need [%zd] to read the " "pending message\n", __func__, count, total_length); goto out_unlock_msg_ctx; } @@ -377,7 +377,7 @@ if ((sizeof(*msg) + msg->data_len) != data_size) { printk(KERN_WARNING "%s: (sizeof(*msg) + msg->data_len) = " - "[%Zd]; data_size = [%Zd]. Invalid packet.\n", __func__, + "[%zd]; data_size = [%zd]. Invalid packet.\n", __func__, (sizeof(*msg) + msg->data_len), data_size); rc = -EINVAL; goto out; @@ -421,7 +421,7 @@ data = kmalloc(count, GFP_KERNEL); if (!data) { printk(KERN_ERR "%s: Out of memory whilst attempting to " - "kmalloc([%Zd], GFP_KERNEL)\n", __func__, count); + "kmalloc([%zd], GFP_KERNEL)\n", __func__, count); goto out; } rc = copy_from_user(data, buf, count); @@ -436,8 +436,8 @@ case ECRYPTFS_MSG_RESPONSE: if (count < (1 + 4 + 1 + sizeof(struct ecryptfs_message))) { printk(KERN_WARNING "%s: Minimum acceptable packet " - "size is [%Zd], but amount of data written is " - "only [%Zd]. Discarding response packet.\n", + "size is [%zd], but amount of data written is " + "only [%zd]. Discarding response packet.\n", __func__, (1 + 4 + 1 + sizeof(struct ecryptfs_message)), count); @@ -455,9 +455,9 @@ } i += packet_size_length; if ((1 + 4 + packet_size_length + packet_size) != count) { - printk(KERN_WARNING "%s: (1 + packet_size_length([%Zd])" - " + packet_size([%Zd]))([%Zd]) != " - "count([%Zd]). Invalid packet format.\n", + printk(KERN_WARNING "%s: (1 + packet_size_length([%zd])" + " + packet_size([%zd]))([%zd]) != " + "count([%zd]). Invalid packet format.\n", __func__, packet_size_length, packet_size, (1 + packet_size_length + packet_size), count); goto out_free; --- linux-2.6.28.orig/fs/ecryptfs/mmap.c +++ linux-2.6.28/fs/ecryptfs/mmap.c @@ -288,7 +288,7 @@ loff_t prev_page_end_size; int rc = 0; - page = __grab_cache_page(mapping, index); + page = grab_cache_page_write_begin(mapping, index, flags); if (!page) return -ENOMEM; *pagep = page; --- linux-2.6.28.orig/fs/ecryptfs/keystore.c +++ linux-2.6.28/fs/ecryptfs/keystore.c @@ -358,7 +358,7 @@ /* verify that everything through the encrypted FEK size is present */ if (message_len < 4) { rc = -EIO; - printk(KERN_ERR "%s: message_len is [%Zd]; minimum acceptable " + printk(KERN_ERR "%s: message_len is [%zd]; minimum acceptable " "message length is [%d]\n", __func__, message_len, 4); goto out; } @@ -385,13 +385,13 @@ i += data_len; if (message_len < (i + key_rec->enc_key_size)) { rc = -EIO; - printk(KERN_ERR "%s: message_len [%Zd]; max len is [%Zd]\n", + printk(KERN_ERR "%s: message_len [%zd]; max len is [%zd]\n", __func__, message_len, (i + key_rec->enc_key_size)); goto out; } if (key_rec->enc_key_size > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) { rc = -EIO; - printk(KERN_ERR "%s: Encrypted key_size [%Zd] larger than " + printk(KERN_ERR "%s: Encrypted key_size [%zd] larger than " "the maximum key size [%d]\n", __func__, key_rec->enc_key_size, ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES); @@ -403,6 +403,580 @@ } static int +ecryptfs_find_global_auth_tok_for_sig( + struct ecryptfs_global_auth_tok **global_auth_tok, + struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig) +{ + struct ecryptfs_global_auth_tok *walker; + int rc = 0; + + (*global_auth_tok) = NULL; + mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); + list_for_each_entry(walker, + &mount_crypt_stat->global_auth_tok_list, + mount_crypt_stat_list) { + if (memcmp(walker->sig, sig, ECRYPTFS_SIG_SIZE_HEX) == 0) { + (*global_auth_tok) = walker; + goto out; + } + } + rc = -EINVAL; +out: + mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex); + return rc; +} + +/** + * ecryptfs_find_auth_tok_for_sig + * @auth_tok: Set to the matching auth_tok; NULL if not found + * @crypt_stat: inode crypt_stat crypto context + * @sig: Sig of auth_tok to find + * + * For now, this function simply looks at the registered auth_tok's + * linked off the mount_crypt_stat, so all the auth_toks that can be + * used must be registered at mount time. This function could + * potentially try a lot harder to find auth_tok's (e.g., by calling + * out to ecryptfsd to dynamically retrieve an auth_tok object) so + * that static registration of auth_tok's will no longer be necessary. + * + * Returns zero on no error; non-zero on error + */ +static int +ecryptfs_find_auth_tok_for_sig( + struct ecryptfs_auth_tok **auth_tok, + struct ecryptfs_mount_crypt_stat *mount_crypt_stat, + char *sig) +{ + struct ecryptfs_global_auth_tok *global_auth_tok; + int rc = 0; + + (*auth_tok) = NULL; + if (ecryptfs_find_global_auth_tok_for_sig(&global_auth_tok, + mount_crypt_stat, sig)) { + struct key *auth_tok_key; + + rc = ecryptfs_keyring_auth_tok_for_sig(&auth_tok_key, auth_tok, + sig); + } else + (*auth_tok) = global_auth_tok->global_auth_tok; + return rc; +} + +/** + * write_tag_70_packet can gobble a lot of stack space. We stuff most + * of the function's parameters in a kmalloc'd struct to help reduce + * eCryptfs' overall stack usage. + */ +struct ecryptfs_write_tag_70_packet_silly_stack { + u8 cipher_code; + size_t max_packet_size; + size_t packet_size_len; + size_t block_aligned_filename_size; + size_t block_size; + size_t i; + size_t j; + size_t num_rand_bytes; + struct mutex *tfm_mutex; + char *block_aligned_filename; + struct ecryptfs_auth_tok *auth_tok; + struct scatterlist src_sg; + struct scatterlist dst_sg; + struct blkcipher_desc desc; + char iv[ECRYPTFS_MAX_IV_BYTES]; + char hash[ECRYPTFS_TAG_70_DIGEST_SIZE]; + char tmp_hash[ECRYPTFS_TAG_70_DIGEST_SIZE]; + struct hash_desc hash_desc; + struct scatterlist hash_sg; +}; + +/** + * write_tag_70_packet - Write encrypted filename (EFN) packet against FNEK + * @filename: NULL-terminated filename string + * + * This is the simplest mechanism for achieving filename encryption in + * eCryptfs. It encrypts the given filename with the mount-wide + * filename encryption key (FNEK) and stores it in a packet to @dest, + * which the callee will encode and write directly into the dentry + * name. + */ +int +ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, + size_t *packet_size, + struct ecryptfs_mount_crypt_stat *mount_crypt_stat, + char *filename, size_t filename_size) +{ + struct ecryptfs_write_tag_70_packet_silly_stack *s; + int rc = 0; + + s = kmalloc(sizeof(*s), GFP_KERNEL); + if (!s) { + printk(KERN_ERR "%s: Out of memory whilst trying to kmalloc " + "[%zd] bytes of kernel memory\n", __func__, sizeof(*s)); + goto out; + } + s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; + (*packet_size) = 0; + rc = ecryptfs_get_tfm_and_mutex_for_cipher_name( + &s->desc.tfm, + &s->tfm_mutex, mount_crypt_stat->global_default_fn_cipher_name); + if (unlikely(rc)) { + printk(KERN_ERR "Internal error whilst attempting to get " + "tfm and mutex for cipher name [%s]; rc = [%d]\n", + mount_crypt_stat->global_default_fn_cipher_name, rc); + goto out; + } + mutex_lock(s->tfm_mutex); + s->block_size = crypto_blkcipher_blocksize(s->desc.tfm); + /* Plus one for the \0 separator between the random prefix + * and the plaintext filename */ + s->num_rand_bytes = (ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES + 1); + s->block_aligned_filename_size = (s->num_rand_bytes + filename_size); + if ((s->block_aligned_filename_size % s->block_size) != 0) { + s->num_rand_bytes += (s->block_size + - (s->block_aligned_filename_size + % s->block_size)); + s->block_aligned_filename_size = (s->num_rand_bytes + + filename_size); + } + /* Octet 0: Tag 70 identifier + * Octets 1-N1: Tag 70 packet size (includes cipher identifier + * and block-aligned encrypted filename size) + * Octets N1-N2: FNEK sig (ECRYPTFS_SIG_SIZE) + * Octet N2-N3: Cipher identifier (1 octet) + * Octets N3-N4: Block-aligned encrypted filename + * - Consists of a minimum number of random characters, a \0 + * separator, and then the filename */ + s->max_packet_size = (1 /* Tag 70 identifier */ + + 3 /* Max Tag 70 packet size */ + + ECRYPTFS_SIG_SIZE /* FNEK sig */ + + 1 /* Cipher identifier */ + + s->block_aligned_filename_size); + if (dest == NULL) { + (*packet_size) = s->max_packet_size; + goto out_unlock; + } + if (s->max_packet_size > (*remaining_bytes)) { + printk(KERN_WARNING "%s: Require [%zd] bytes to write; only " + "[%zd] available\n", __func__, s->max_packet_size, + (*remaining_bytes)); + rc = -EINVAL; + goto out_unlock; + } + s->block_aligned_filename = kzalloc(s->block_aligned_filename_size, + GFP_KERNEL); + if (!s->block_aligned_filename) { + printk(KERN_ERR "%s: Out of kernel memory whilst attempting to " + "kzalloc [%zd] bytes\n", __func__, + s->block_aligned_filename_size); + rc = -ENOMEM; + goto out_unlock; + } + s->i = 0; + dest[s->i++] = ECRYPTFS_TAG_70_PACKET_TYPE; + rc = ecryptfs_write_packet_length(&dest[s->i], + (ECRYPTFS_SIG_SIZE + + 1 /* Cipher code */ + + s->block_aligned_filename_size), + &s->packet_size_len); + if (rc) { + printk(KERN_ERR "%s: Error generating tag 70 packet " + "header; cannot generate packet length; rc = [%d]\n", + __func__, rc); + goto out_free_unlock; + } + s->i += s->packet_size_len; + ecryptfs_from_hex(&dest[s->i], + mount_crypt_stat->global_default_fnek_sig, + ECRYPTFS_SIG_SIZE); + s->i += ECRYPTFS_SIG_SIZE; + s->cipher_code = ecryptfs_code_for_cipher_string( + mount_crypt_stat->global_default_fn_cipher_name, + mount_crypt_stat->global_default_fn_cipher_key_bytes); + if (s->cipher_code == 0) { + printk(KERN_WARNING "%s: Unable to generate code for " + "cipher [%s] with key bytes [%zd]\n", __func__, + mount_crypt_stat->global_default_fn_cipher_name, + mount_crypt_stat->global_default_fn_cipher_key_bytes); + rc = -EINVAL; + goto out_free_unlock; + } + dest[s->i++] = s->cipher_code; + rc = ecryptfs_find_auth_tok_for_sig( + &s->auth_tok, mount_crypt_stat, + mount_crypt_stat->global_default_fnek_sig); + if (rc) { + printk(KERN_ERR "%s: Error attempting to find auth tok for " + "fnek sig [%s]; rc = [%d]\n", __func__, + mount_crypt_stat->global_default_fnek_sig, rc); + goto out_free_unlock; + } + /* TODO: Support other key modules than passphrase for + * filename encryption */ + BUG_ON(s->auth_tok->token_type != ECRYPTFS_PASSWORD); + sg_init_one( + &s->hash_sg, + (u8 *)s->auth_tok->token.password.session_key_encryption_key, + s->auth_tok->token.password.session_key_encryption_key_bytes); + s->hash_desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; + s->hash_desc.tfm = crypto_alloc_hash(ECRYPTFS_TAG_70_DIGEST, 0, + CRYPTO_ALG_ASYNC); + if (IS_ERR(s->hash_desc.tfm)) { + rc = PTR_ERR(s->hash_desc.tfm); + printk(KERN_ERR "%s: Error attempting to " + "allocate hash crypto context; rc = [%d]\n", + __func__, rc); + goto out_free_unlock; + } + rc = crypto_hash_init(&s->hash_desc); + if (rc) { + printk(KERN_ERR + "%s: Error initializing crypto hash; rc = [%d]\n", + __func__, rc); + goto out_release_free_unlock; + } + rc = crypto_hash_update( + &s->hash_desc, &s->hash_sg, + s->auth_tok->token.password.session_key_encryption_key_bytes); + if (rc) { + printk(KERN_ERR + "%s: Error updating crypto hash; rc = [%d]\n", + __func__, rc); + goto out_release_free_unlock; + } + rc = crypto_hash_final(&s->hash_desc, s->hash); + if (rc) { + printk(KERN_ERR + "%s: Error finalizing crypto hash; rc = [%d]\n", + __func__, rc); + goto out_release_free_unlock; + } + for (s->j = 0; s->j < (s->num_rand_bytes - 1); s->j++) { + s->block_aligned_filename[s->j] = + s->hash[(s->j % ECRYPTFS_TAG_70_DIGEST_SIZE)]; + if ((s->j % ECRYPTFS_TAG_70_DIGEST_SIZE) + == (ECRYPTFS_TAG_70_DIGEST_SIZE - 1)) { + sg_init_one(&s->hash_sg, (u8 *)s->hash, + ECRYPTFS_TAG_70_DIGEST_SIZE); + rc = crypto_hash_init(&s->hash_desc); + if (rc) { + printk(KERN_ERR + "%s: Error initializing crypto hash; " + "rc = [%d]\n", __func__, rc); + goto out_release_free_unlock; + } + rc = crypto_hash_update(&s->hash_desc, &s->hash_sg, + ECRYPTFS_TAG_70_DIGEST_SIZE); + if (rc) { + printk(KERN_ERR + "%s: Error updating crypto hash; " + "rc = [%d]\n", __func__, rc); + goto out_release_free_unlock; + } + rc = crypto_hash_final(&s->hash_desc, s->tmp_hash); + if (rc) { + printk(KERN_ERR + "%s: Error finalizing crypto hash; " + "rc = [%d]\n", __func__, rc); + goto out_release_free_unlock; + } + memcpy(s->hash, s->tmp_hash, + ECRYPTFS_TAG_70_DIGEST_SIZE); + } + if (s->block_aligned_filename[s->j] == '\0') + s->block_aligned_filename[s->j] = ECRYPTFS_NON_NULL; + } + memcpy(&s->block_aligned_filename[s->num_rand_bytes], filename, + filename_size); + rc = virt_to_scatterlist(s->block_aligned_filename, + s->block_aligned_filename_size, &s->src_sg, 1); + if (rc != 1) { + printk(KERN_ERR "%s: Internal error whilst attempting to " + "convert filename memory to scatterlist; " + "expected rc = 1; got rc = [%d]. " + "block_aligned_filename_size = [%zd]\n", __func__, rc, + s->block_aligned_filename_size); + goto out_release_free_unlock; + } + rc = virt_to_scatterlist(&dest[s->i], s->block_aligned_filename_size, + &s->dst_sg, 1); + if (rc != 1) { + printk(KERN_ERR "%s: Internal error whilst attempting to " + "convert encrypted filename memory to scatterlist; " + "expected rc = 1; got rc = [%d]. " + "block_aligned_filename_size = [%zd]\n", __func__, rc, + s->block_aligned_filename_size); + goto out_release_free_unlock; + } + /* The characters in the first block effectively do the job + * of the IV here, so we just use 0's for the IV. Note the + * constraint that ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES + * >= ECRYPTFS_MAX_IV_BYTES. */ + memset(s->iv, 0, ECRYPTFS_MAX_IV_BYTES); + s->desc.info = s->iv; + rc = crypto_blkcipher_setkey( + s->desc.tfm, + s->auth_tok->token.password.session_key_encryption_key, + mount_crypt_stat->global_default_fn_cipher_key_bytes); + if (rc < 0) { + printk(KERN_ERR "%s: Error setting key for crypto context; " + "rc = [%d]. s->auth_tok->token.password.session_key_" + "encryption_key = [0x%p]; mount_crypt_stat->" + "global_default_fn_cipher_key_bytes = [%zd]\n", __func__, + rc, + s->auth_tok->token.password.session_key_encryption_key, + mount_crypt_stat->global_default_fn_cipher_key_bytes); + goto out_release_free_unlock; + } + rc = crypto_blkcipher_encrypt_iv(&s->desc, &s->dst_sg, &s->src_sg, + s->block_aligned_filename_size); + if (rc) { + printk(KERN_ERR "%s: Error attempting to encrypt filename; " + "rc = [%d]\n", __func__, rc); + goto out_release_free_unlock; + } + s->i += s->block_aligned_filename_size; + (*packet_size) = s->i; + (*remaining_bytes) -= (*packet_size); +out_release_free_unlock: + crypto_free_hash(s->hash_desc.tfm); +out_free_unlock: + memset(s->block_aligned_filename, 0, s->block_aligned_filename_size); + kfree(s->block_aligned_filename); +out_unlock: + mutex_unlock(s->tfm_mutex); +out: + kfree(s); + return rc; +} + +struct ecryptfs_parse_tag_70_packet_silly_stack { + u8 cipher_code; + size_t max_packet_size; + size_t packet_size_len; + size_t parsed_tag_70_packet_size; + size_t block_aligned_filename_size; + size_t block_size; + size_t i; + struct mutex *tfm_mutex; + char *decrypted_filename; + struct ecryptfs_auth_tok *auth_tok; + struct scatterlist src_sg; + struct scatterlist dst_sg; + struct blkcipher_desc desc; + char fnek_sig_hex[ECRYPTFS_SIG_SIZE_HEX + 1]; + char iv[ECRYPTFS_MAX_IV_BYTES]; + char cipher_string[ECRYPTFS_MAX_CIPHER_NAME_SIZE]; +}; + +/** + * parse_tag_70_packet - Parse and process FNEK-encrypted passphrase packet + * @filename: This function kmalloc's the memory for the filename + * @filename_size: This function sets this to the amount of memory + * kmalloc'd for the filename + * @packet_size: This function sets this to the the number of octets + * in the packet parsed + * @mount_crypt_stat: The mount-wide cryptographic context + * @data: The memory location containing the start of the tag 70 + * packet + * @max_packet_size: The maximum legal size of the packet to be parsed + * from @data + * + * Returns zero on success; non-zero otherwise + */ +int +ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, + size_t *packet_size, + struct ecryptfs_mount_crypt_stat *mount_crypt_stat, + char *data, size_t max_packet_size) +{ + struct ecryptfs_parse_tag_70_packet_silly_stack *s; + int rc = 0; + + (*packet_size) = 0; + (*filename_size) = 0; + (*filename) = NULL; + s = kmalloc(sizeof(*s), GFP_KERNEL); + if (!s) { + printk(KERN_ERR "%s: Out of memory whilst trying to kmalloc " + "[%zd] bytes of kernel memory\n", __func__, sizeof(*s)); + goto out; + } + s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP; + if (max_packet_size < (1 + 1 + ECRYPTFS_SIG_SIZE + 1 + 1)) { + printk(KERN_WARNING "%s: max_packet_size is [%zd]; it must be " + "at least [%d]\n", __func__, max_packet_size, + (1 + 1 + ECRYPTFS_SIG_SIZE + 1 + 1)); + rc = -EINVAL; + goto out; + } + /* Octet 0: Tag 70 identifier + * Octets 1-N1: Tag 70 packet size (includes cipher identifier + * and block-aligned encrypted filename size) + * Octets N1-N2: FNEK sig (ECRYPTFS_SIG_SIZE) + * Octet N2-N3: Cipher identifier (1 octet) + * Octets N3-N4: Block-aligned encrypted filename + * - Consists of a minimum number of random numbers, a \0 + * separator, and then the filename */ + if (data[(*packet_size)++] != ECRYPTFS_TAG_70_PACKET_TYPE) { + printk(KERN_WARNING "%s: Invalid packet tag [0x%.2x]; must be " + "tag [0x%.2x]\n", __func__, + data[((*packet_size) - 1)], ECRYPTFS_TAG_70_PACKET_TYPE); + rc = -EINVAL; + goto out; + } + rc = ecryptfs_parse_packet_length(&data[(*packet_size)], + &s->parsed_tag_70_packet_size, + &s->packet_size_len); + if (rc) { + printk(KERN_WARNING "%s: Error parsing packet length; " + "rc = [%d]\n", __func__, rc); + goto out; + } + s->block_aligned_filename_size = (s->parsed_tag_70_packet_size + - ECRYPTFS_SIG_SIZE - 1); + if ((1 + s->packet_size_len + s->parsed_tag_70_packet_size) + > max_packet_size) { + printk(KERN_WARNING "%s: max_packet_size is [%zd]; real packet " + "size is [%zd]\n", __func__, max_packet_size, + (1 + s->packet_size_len + 1 + + s->block_aligned_filename_size)); + rc = -EINVAL; + goto out; + } + (*packet_size) += s->packet_size_len; + ecryptfs_to_hex(s->fnek_sig_hex, &data[(*packet_size)], + ECRYPTFS_SIG_SIZE); + s->fnek_sig_hex[ECRYPTFS_SIG_SIZE_HEX] = '\0'; + (*packet_size) += ECRYPTFS_SIG_SIZE; + s->cipher_code = data[(*packet_size)++]; + rc = ecryptfs_cipher_code_to_string(s->cipher_string, s->cipher_code); + if (rc) { + printk(KERN_WARNING "%s: Cipher code [%d] is invalid\n", + __func__, s->cipher_code); + goto out; + } + rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&s->desc.tfm, + &s->tfm_mutex, + s->cipher_string); + if (unlikely(rc)) { + printk(KERN_ERR "Internal error whilst attempting to get " + "tfm and mutex for cipher name [%s]; rc = [%d]\n", + s->cipher_string, rc); + goto out; + } + mutex_lock(s->tfm_mutex); + rc = virt_to_scatterlist(&data[(*packet_size)], + s->block_aligned_filename_size, &s->src_sg, 1); + if (rc != 1) { + printk(KERN_ERR "%s: Internal error whilst attempting to " + "convert encrypted filename memory to scatterlist; " + "expected rc = 1; got rc = [%d]. " + "block_aligned_filename_size = [%zd]\n", __func__, rc, + s->block_aligned_filename_size); + goto out_unlock; + } + (*packet_size) += s->block_aligned_filename_size; + s->decrypted_filename = kmalloc(s->block_aligned_filename_size, + GFP_KERNEL); + if (!s->decrypted_filename) { + printk(KERN_ERR "%s: Out of memory whilst attempting to " + "kmalloc [%zd] bytes\n", __func__, + s->block_aligned_filename_size); + rc = -ENOMEM; + goto out_unlock; + } + rc = virt_to_scatterlist(s->decrypted_filename, + s->block_aligned_filename_size, &s->dst_sg, 1); + if (rc != 1) { + printk(KERN_ERR "%s: Internal error whilst attempting to " + "convert decrypted filename memory to scatterlist; " + "expected rc = 1; got rc = [%d]. " + "block_aligned_filename_size = [%zd]\n", __func__, rc, + s->block_aligned_filename_size); + goto out_free_unlock; + } + /* The characters in the first block effectively do the job of + * the IV here, so we just use 0's for the IV. Note the + * constraint that ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES + * >= ECRYPTFS_MAX_IV_BYTES. */ + memset(s->iv, 0, ECRYPTFS_MAX_IV_BYTES); + s->desc.info = s->iv; + rc = ecryptfs_find_auth_tok_for_sig(&s->auth_tok, mount_crypt_stat, + s->fnek_sig_hex); + if (rc) { + printk(KERN_ERR "%s: Error attempting to find auth tok for " + "fnek sig [%s]; rc = [%d]\n", __func__, s->fnek_sig_hex, + rc); + goto out_free_unlock; + } + /* TODO: Support other key modules than passphrase for + * filename encryption */ + BUG_ON(s->auth_tok->token_type != ECRYPTFS_PASSWORD); + rc = crypto_blkcipher_setkey( + s->desc.tfm, + s->auth_tok->token.password.session_key_encryption_key, + mount_crypt_stat->global_default_fn_cipher_key_bytes); + if (rc < 0) { + printk(KERN_ERR "%s: Error setting key for crypto context; " + "rc = [%d]. s->auth_tok->token.password.session_key_" + "encryption_key = [0x%p]; mount_crypt_stat->" + "global_default_fn_cipher_key_bytes = [%zd]\n", __func__, + rc, + s->auth_tok->token.password.session_key_encryption_key, + mount_crypt_stat->global_default_fn_cipher_key_bytes); + goto out_free_unlock; + } + rc = crypto_blkcipher_decrypt_iv(&s->desc, &s->dst_sg, &s->src_sg, + s->block_aligned_filename_size); + if (rc) { + printk(KERN_ERR "%s: Error attempting to decrypt filename; " + "rc = [%d]\n", __func__, rc); + goto out_free_unlock; + } + s->i = 0; + while (s->decrypted_filename[s->i] != '\0' + && s->i < s->block_aligned_filename_size) + s->i++; + if (s->i == s->block_aligned_filename_size) { + printk(KERN_WARNING "%s: Invalid tag 70 packet; could not " + "find valid separator between random characters and " + "the filename\n", __func__); + rc = -EINVAL; + goto out_free_unlock; + } + s->i++; + (*filename_size) = (s->block_aligned_filename_size - s->i); + if (!((*filename_size) > 0 && (*filename_size < PATH_MAX))) { + printk(KERN_WARNING "%s: Filename size is [%zd], which is " + "invalid\n", __func__, (*filename_size)); + rc = -EINVAL; + goto out_free_unlock; + } + (*filename) = kmalloc(((*filename_size) + 1), GFP_KERNEL); + if (!(*filename)) { + printk(KERN_ERR "%s: Out of memory whilst attempting to " + "kmalloc [%zd] bytes\n", __func__, + ((*filename_size) + 1)); + rc = -ENOMEM; + goto out_free_unlock; + } + memcpy((*filename), &s->decrypted_filename[s->i], (*filename_size)); + (*filename)[(*filename_size)] = '\0'; +out_free_unlock: + kfree(s->decrypted_filename); +out_unlock: + mutex_unlock(s->tfm_mutex); +out: + if (rc) { + (*packet_size) = 0; + (*filename_size) = 0; + (*filename) = NULL; + } + kfree(s); + return rc; +} + +static int ecryptfs_get_auth_tok_sig(char **sig, struct ecryptfs_auth_tok *auth_tok) { int rc = 0; @@ -897,30 +1471,6 @@ return rc; } -static int -ecryptfs_find_global_auth_tok_for_sig( - struct ecryptfs_global_auth_tok **global_auth_tok, - struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig) -{ - struct ecryptfs_global_auth_tok *walker; - int rc = 0; - - (*global_auth_tok) = NULL; - mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); - list_for_each_entry(walker, - &mount_crypt_stat->global_auth_tok_list, - mount_crypt_stat_list) { - if (memcmp(walker->sig, sig, ECRYPTFS_SIG_SIZE_HEX) == 0) { - (*global_auth_tok) = walker; - goto out; - } - } - rc = -EINVAL; -out: - mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex); - return rc; -} - /** * ecryptfs_verify_version * @version: The version number to confirm @@ -990,43 +1540,6 @@ } /** - * ecryptfs_find_auth_tok_for_sig - * @auth_tok: Set to the matching auth_tok; NULL if not found - * @crypt_stat: inode crypt_stat crypto context - * @sig: Sig of auth_tok to find - * - * For now, this function simply looks at the registered auth_tok's - * linked off the mount_crypt_stat, so all the auth_toks that can be - * used must be registered at mount time. This function could - * potentially try a lot harder to find auth_tok's (e.g., by calling - * out to ecryptfsd to dynamically retrieve an auth_tok object) so - * that static registration of auth_tok's will no longer be necessary. - * - * Returns zero on no error; non-zero on error - */ -static int -ecryptfs_find_auth_tok_for_sig( - struct ecryptfs_auth_tok **auth_tok, - struct ecryptfs_crypt_stat *crypt_stat, char *sig) -{ - struct ecryptfs_mount_crypt_stat *mount_crypt_stat = - crypt_stat->mount_crypt_stat; - struct ecryptfs_global_auth_tok *global_auth_tok; - int rc = 0; - - (*auth_tok) = NULL; - if (ecryptfs_find_global_auth_tok_for_sig(&global_auth_tok, - mount_crypt_stat, sig)) { - struct key *auth_tok_key; - - rc = ecryptfs_keyring_auth_tok_for_sig(&auth_tok_key, auth_tok, - sig); - } else - (*auth_tok) = global_auth_tok->global_auth_tok; - return rc; -} - -/** * decrypt_passphrase_encrypted_session_key - Decrypt the session key with the given auth_tok. * @auth_tok: The passphrase authentication token to use to encrypt the FEK * @crypt_stat: The cryptographic context @@ -1256,7 +1769,8 @@ rc = -EINVAL; goto out_wipe_list; } - ecryptfs_find_auth_tok_for_sig(&matching_auth_tok, crypt_stat, + ecryptfs_find_auth_tok_for_sig(&matching_auth_tok, + crypt_stat->mount_crypt_stat, candidate_auth_tok_sig); if (matching_auth_tok) { found_auth_tok = 1; @@ -1336,7 +1850,9 @@ int rc; rc = write_tag_66_packet(auth_tok->token.private_key.signature, - ecryptfs_code_for_cipher_string(crypt_stat), + ecryptfs_code_for_cipher_string( + crypt_stat->cipher, + crypt_stat->key_size), crypt_stat, &payload, &payload_len); if (rc) { ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet\n"); @@ -1696,7 +2212,8 @@ dest[(*packet_size)++] = 0x04; /* version 4 */ /* TODO: Break from RFC2440 so that arbitrary ciphers can be * specified with strings */ - cipher_code = ecryptfs_code_for_cipher_string(crypt_stat); + cipher_code = ecryptfs_code_for_cipher_string(crypt_stat->cipher, + crypt_stat->key_size); if (cipher_code == 0) { ecryptfs_printk(KERN_WARNING, "Unable to generate code for " "cipher [%s]\n", crypt_stat->cipher); @@ -1858,7 +2375,7 @@ int ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, - char *sig) + char *sig, u32 global_auth_tok_flags) { struct ecryptfs_global_auth_tok *new_auth_tok; int rc = 0; @@ -1872,6 +2389,7 @@ goto out; } memcpy(new_auth_tok->sig, sig, ECRYPTFS_SIG_SIZE_HEX); + new_auth_tok->flags = global_auth_tok_flags; new_auth_tok->sig[ECRYPTFS_SIG_SIZE_HEX] = '\0'; mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); list_add(&new_auth_tok->mount_crypt_stat_list, --- linux-2.6.28.orig/fs/ecryptfs/main.c +++ linux-2.6.28/fs/ecryptfs/main.c @@ -205,7 +205,9 @@ ecryptfs_opt_cipher, ecryptfs_opt_ecryptfs_cipher, ecryptfs_opt_ecryptfs_key_bytes, ecryptfs_opt_passthrough, ecryptfs_opt_xattr_metadata, - ecryptfs_opt_encrypted_view, ecryptfs_opt_err }; + ecryptfs_opt_encrypted_view, ecryptfs_opt_fnek_sig, + ecryptfs_opt_fn_cipher, ecryptfs_opt_fn_cipher_key_bytes, + ecryptfs_opt_err }; static const match_table_t tokens = { {ecryptfs_opt_sig, "sig=%s"}, @@ -216,6 +218,9 @@ {ecryptfs_opt_passthrough, "ecryptfs_passthrough"}, {ecryptfs_opt_xattr_metadata, "ecryptfs_xattr_metadata"}, {ecryptfs_opt_encrypted_view, "ecryptfs_encrypted_view"}, + {ecryptfs_opt_fnek_sig, "ecryptfs_fnek_sig=%s"}, + {ecryptfs_opt_fn_cipher, "ecryptfs_fn_cipher=%s"}, + {ecryptfs_opt_fn_cipher_key_bytes, "ecryptfs_fn_key_bytes=%u"}, {ecryptfs_opt_err, NULL} }; @@ -280,8 +285,11 @@ int rc = 0; int sig_set = 0; int cipher_name_set = 0; + int fn_cipher_name_set = 0; int cipher_key_bytes; int cipher_key_bytes_set = 0; + int fn_cipher_key_bytes; + int fn_cipher_key_bytes_set = 0; struct ecryptfs_mount_crypt_stat *mount_crypt_stat = &ecryptfs_superblock_to_private(sb)->mount_crypt_stat; substring_t args[MAX_OPT_ARGS]; @@ -289,7 +297,12 @@ char *sig_src; char *cipher_name_dst; char *cipher_name_src; + char *fn_cipher_name_dst; + char *fn_cipher_name_src; + char *fnek_dst; + char *fnek_src; char *cipher_key_bytes_src; + char *fn_cipher_key_bytes_src; if (!options) { rc = -EINVAL; @@ -305,7 +318,7 @@ case ecryptfs_opt_ecryptfs_sig: sig_src = args[0].from; rc = ecryptfs_add_global_auth_tok(mount_crypt_stat, - sig_src); + sig_src, 0); if (rc) { printk(KERN_ERR "Error attempting to register " "global sig; rc = [%d]\n", rc); @@ -321,10 +334,7 @@ global_default_cipher_name; strncpy(cipher_name_dst, cipher_name_src, ECRYPTFS_MAX_CIPHER_NAME_SIZE); - ecryptfs_printk(KERN_DEBUG, - "The mount_crypt_stat " - "global_default_cipher_name set to: " - "[%s]\n", cipher_name_dst); + cipher_name_dst[ECRYPTFS_MAX_CIPHER_NAME_SIZE] = '\0'; cipher_name_set = 1; break; case ecryptfs_opt_ecryptfs_key_bytes: @@ -334,11 +344,6 @@ &cipher_key_bytes_src, 0); mount_crypt_stat->global_default_cipher_key_size = cipher_key_bytes; - ecryptfs_printk(KERN_DEBUG, - "The mount_crypt_stat " - "global_default_cipher_key_size " - "set to: [%d]\n", mount_crypt_stat-> - global_default_cipher_key_size); cipher_key_bytes_set = 1; break; case ecryptfs_opt_passthrough: @@ -355,11 +360,52 @@ mount_crypt_stat->flags |= ECRYPTFS_ENCRYPTED_VIEW_ENABLED; break; + case ecryptfs_opt_fnek_sig: + fnek_src = args[0].from; + fnek_dst = + mount_crypt_stat->global_default_fnek_sig; + strncpy(fnek_dst, fnek_src, ECRYPTFS_SIG_SIZE_HEX); + mount_crypt_stat->global_default_fnek_sig[ + ECRYPTFS_SIG_SIZE_HEX] = '\0'; + rc = ecryptfs_add_global_auth_tok( + mount_crypt_stat, + mount_crypt_stat->global_default_fnek_sig, + ECRYPTFS_AUTH_TOK_FNEK); + if (rc) { + printk(KERN_ERR "Error attempting to register " + "global fnek sig [%s]; rc = [%d]\n", + mount_crypt_stat->global_default_fnek_sig, + rc); + goto out; + } + mount_crypt_stat->flags |= + (ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES + | ECRYPTFS_GLOBAL_ENCFN_USE_MOUNT_FNEK); + break; + case ecryptfs_opt_fn_cipher: + fn_cipher_name_src = args[0].from; + fn_cipher_name_dst = + mount_crypt_stat->global_default_fn_cipher_name; + strncpy(fn_cipher_name_dst, fn_cipher_name_src, + ECRYPTFS_MAX_CIPHER_NAME_SIZE); + mount_crypt_stat->global_default_fn_cipher_name[ + ECRYPTFS_MAX_CIPHER_NAME_SIZE] = '\0'; + fn_cipher_name_set = 1; + break; + case ecryptfs_opt_fn_cipher_key_bytes: + fn_cipher_key_bytes_src = args[0].from; + fn_cipher_key_bytes = + (int)simple_strtol(fn_cipher_key_bytes_src, + &fn_cipher_key_bytes_src, 0); + mount_crypt_stat->global_default_fn_cipher_key_bytes = + fn_cipher_key_bytes; + fn_cipher_key_bytes_set = 1; + break; case ecryptfs_opt_err: default: - ecryptfs_printk(KERN_WARNING, - "eCryptfs: unrecognized option '%s'\n", - p); + printk(KERN_WARNING + "%s: eCryptfs: unrecognized option [%s]\n", + __func__, p); } } if (!sig_set) { @@ -373,33 +419,60 @@ int cipher_name_len = strlen(ECRYPTFS_DEFAULT_CIPHER); BUG_ON(cipher_name_len >= ECRYPTFS_MAX_CIPHER_NAME_SIZE); - strcpy(mount_crypt_stat->global_default_cipher_name, ECRYPTFS_DEFAULT_CIPHER); } - if (!cipher_key_bytes_set) { + if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) + && !fn_cipher_name_set) + strcpy(mount_crypt_stat->global_default_fn_cipher_name, + mount_crypt_stat->global_default_cipher_name); + if (!cipher_key_bytes_set) mount_crypt_stat->global_default_cipher_key_size = 0; - } + if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) + && !fn_cipher_key_bytes_set) + mount_crypt_stat->global_default_fn_cipher_key_bytes = + mount_crypt_stat->global_default_cipher_key_size; mutex_lock(&key_tfm_list_mutex); if (!ecryptfs_tfm_exists(mount_crypt_stat->global_default_cipher_name, - NULL)) + NULL)) { rc = ecryptfs_add_new_key_tfm( NULL, mount_crypt_stat->global_default_cipher_name, mount_crypt_stat->global_default_cipher_key_size); - mutex_unlock(&key_tfm_list_mutex); - if (rc) { - printk(KERN_ERR "Error attempting to initialize cipher with " - "name = [%s] and key size = [%td]; rc = [%d]\n", - mount_crypt_stat->global_default_cipher_name, - mount_crypt_stat->global_default_cipher_key_size, rc); - rc = -EINVAL; - goto out; + if (rc) { + printk(KERN_ERR "Error attempting to initialize " + "cipher with name = [%s] and key size = [%td]; " + "rc = [%d]\n", + mount_crypt_stat->global_default_cipher_name, + mount_crypt_stat->global_default_cipher_key_size, + rc); + rc = -EINVAL; + mutex_unlock(&key_tfm_list_mutex); + goto out; + } } + if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) + && !ecryptfs_tfm_exists( + mount_crypt_stat->global_default_fn_cipher_name, NULL)) { + rc = ecryptfs_add_new_key_tfm( + NULL, mount_crypt_stat->global_default_fn_cipher_name, + mount_crypt_stat->global_default_fn_cipher_key_bytes); + if (rc) { + printk(KERN_ERR "Error attempting to initialize " + "cipher with name = [%s] and key size = [%td]; " + "rc = [%d]\n", + mount_crypt_stat->global_default_fn_cipher_name, + mount_crypt_stat->global_default_fn_cipher_key_bytes, + rc); + rc = -EINVAL; + mutex_unlock(&key_tfm_list_mutex); + goto out; + } + } + mutex_unlock(&key_tfm_list_mutex); rc = ecryptfs_init_global_auth_toks(mount_crypt_stat); - if (rc) { + if (rc) printk(KERN_WARNING "One or more global auth toks could not " "properly register; rc = [%d]\n", rc); - } out: return rc; } --- linux-2.6.28.orig/fs/ecryptfs/messaging.c +++ linux-2.6.28/fs/ecryptfs/messaging.c @@ -193,7 +193,7 @@ (*daemon) = kzalloc(sizeof(**daemon), GFP_KERNEL); if (!(*daemon)) { rc = -ENOMEM; - printk(KERN_ERR "%s: Failed to allocate [%Zd] bytes of " + printk(KERN_ERR "%s: Failed to allocate [%zd] bytes of " "GFP_KERNEL memory\n", __func__, sizeof(**daemon)); goto out; } @@ -434,7 +434,7 @@ msg_ctx->msg = kmalloc(msg_size, GFP_KERNEL); if (!msg_ctx->msg) { rc = -ENOMEM; - printk(KERN_ERR "%s: Failed to allocate [%Zd] bytes of " + printk(KERN_ERR "%s: Failed to allocate [%zd] bytes of " "GFP_KERNEL memory\n", __func__, msg_size); goto unlock; } --- linux-2.6.28.orig/fs/ext4/ext4.h +++ linux-2.6.28/fs/ext4/ext4.h @@ -19,6 +19,7 @@ #include #include #include +#include #include "ext4_i.h" /* @@ -254,6 +255,7 @@ #define EXT4_STATE_NEW 0x00000002 /* inode is newly created */ #define EXT4_STATE_XATTR 0x00000004 /* has in-inode xattrs */ #define EXT4_STATE_NO_EXPAND 0x00000008 /* No space for expansion */ +#define EXT4_STATE_DA_ALLOC_CLOSE 0x00000010 /* Alloc DA blks on close */ /* Used to pass group descriptor data when online resize is done */ struct ext4_new_group_input { @@ -301,7 +303,9 @@ #define EXT4_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long) #define EXT4_IOC_GROUP_ADD _IOW('f', 8, struct ext4_new_group_input) #define EXT4_IOC_MIGRATE _IO('f', 9) + /* note ioctl 10 reserved for an early version of the FIEMAP ioctl */ /* note ioctl 11 reserved for filesystem-independent FIEMAP ioctl */ +#define EXT4_IOC_ALLOC_DA_BLKS _IO('f', 12) /* * ioctl commands in 32 bit emulation @@ -861,7 +865,7 @@ { unsigned len = le16_to_cpu(dlen); - if (len == EXT4_MAX_REC_LEN) + if (len == EXT4_MAX_REC_LEN || len == 0) return 1 << 16; return len; } @@ -891,6 +895,9 @@ #define DX_HASH_LEGACY 0 #define DX_HASH_HALF_MD4 1 #define DX_HASH_TEA 2 +#define DX_HASH_LEGACY_UNSIGNED 3 +#define DX_HASH_HALF_MD4_UNSIGNED 4 +#define DX_HASH_TEA_UNSIGNED 5 #ifdef __KERNEL__ @@ -1006,9 +1013,8 @@ extern int ext4_has_free_blocks(struct ext4_sb_info *sbi, s64 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, - ext4_fsblk_t block, unsigned long count, - unsigned long *pdquot_freed_blocks); +extern void ext4_add_groupblocks(handle_t *handle, struct super_block *sb, + ext4_fsblk_t block, unsigned long count); extern ext4_fsblk_t ext4_count_free_blocks(struct super_block *); extern void ext4_check_blocks_bitmap(struct super_block *); extern struct ext4_group_desc * ext4_get_group_desc(struct super_block * sb, @@ -1054,12 +1060,13 @@ 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, +extern int ext4_mb_add_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); - - +extern int ext4_mb_get_buddy_cache_lock(struct super_block *, ext4_group_t); +extern void ext4_mb_put_buddy_cache_lock(struct super_block *, + ext4_group_t, int); /* inode.c */ int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode, struct buffer_head *bh, ext4_fsblk_t blocknr); @@ -1088,6 +1095,7 @@ extern void ext4_truncate(struct inode *); extern void ext4_set_inode_flags(struct inode *); extern void ext4_get_inode_flags(struct ext4_inode_info *); +extern int ext4_alloc_da_blocks(struct inode *inode); extern void ext4_set_aops(struct inode *inode); extern int ext4_writepage_trans_blocks(struct inode *); extern int ext4_meta_trans_blocks(struct inode *, int nrblocks, int idxblocks); @@ -1184,8 +1192,11 @@ static inline loff_t ext4_isize(struct ext4_inode *raw_inode) { - return ((loff_t)le32_to_cpu(raw_inode->i_size_high) << 32) | - le32_to_cpu(raw_inode->i_size_lo); + if (S_ISREG(le16_to_cpu(raw_inode->i_mode))) + return ((loff_t)le32_to_cpu(raw_inode->i_size_high) << 32) | + le32_to_cpu(raw_inode->i_size_lo); + else + return (loff_t) le32_to_cpu(raw_inode->i_size_lo); } static inline void ext4_isize_set(struct ext4_inode *raw_inode, loff_t i_size) @@ -1283,6 +1294,24 @@ sector_t block, unsigned long max_blocks, struct buffer_head *bh, int create, int extend_disksize, int flag); + +/* + * Add new method to test wether block and inode bitmaps are properly + * initialized. With uninit_bg reading the block from disk is not enough + * to mark the bitmap uptodate. We need to also zero-out the bitmap + */ +#define BH_BITMAP_UPTODATE BH_JBDPrivateStart + +static inline int bitmap_uptodate(struct buffer_head *bh) +{ + return (buffer_uptodate(bh) && + test_bit(BH_BITMAP_UPTODATE, &(bh)->b_state)); +} +static inline void set_bitmap_uptodate(struct buffer_head *bh) +{ + set_bit(BH_BITMAP_UPTODATE, &(bh)->b_state); +} + #endif /* __KERNEL__ */ #endif /* _EXT4_H */ --- linux-2.6.28.orig/fs/ext4/namei.c +++ linux-2.6.28/fs/ext4/namei.c @@ -372,6 +372,8 @@ goto fail; } hinfo->hash_version = root->info.hash_version; + if (hinfo->hash_version <= DX_HASH_TEA) + hinfo->hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned; hinfo->seed = EXT4_SB(dir->i_sb)->s_hash_seed; if (d_name) ext4fs_dirhash(d_name->name, d_name->len, hinfo); @@ -641,6 +643,9 @@ dir = dir_file->f_path.dentry->d_inode; if (!(EXT4_I(dir)->i_flags & EXT4_INDEX_FL)) { hinfo.hash_version = EXT4_SB(dir->i_sb)->s_def_hash_version; + if (hinfo.hash_version <= DX_HASH_TEA) + hinfo.hash_version += + EXT4_SB(dir->i_sb)->s_hash_unsigned; hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed; count = htree_dirblock_to_tree(dir_file, dir, 0, &hinfo, start_hash, start_minor_hash); @@ -1367,7 +1372,7 @@ struct fake_dirent *fde; blocksize = dir->i_sb->s_blocksize; - dxtrace(printk(KERN_DEBUG "Creating index\n")); + dxtrace(printk(KERN_DEBUG "Creating index: inode %lu\n", dir->i_ino)); retval = ext4_journal_get_write_access(handle, bh); if (retval) { ext4_std_error(dir->i_sb, retval); @@ -1376,6 +1381,20 @@ } root = (struct dx_root *) bh->b_data; + /* The 0th block becomes the root, move the dirents out */ + fde = &root->dotdot; + de = (struct ext4_dir_entry_2 *)((char *)fde + + ext4_rec_len_from_disk(fde->rec_len)); + if ((char *) de >= (((char *) root) + blocksize)) { + ext4_error(dir->i_sb, __func__, + "invalid rec_len for '..' in inode %lu", + dir->i_ino); + brelse(bh); + return -EIO; + } + len = ((char *) root) + blocksize - (char *) de; + + /* Allocate new block for the 0th block's dirents */ bh2 = ext4_append(handle, dir, &block, &retval); if (!(bh2)) { brelse(bh); @@ -1384,11 +1403,6 @@ EXT4_I(dir)->i_flags |= EXT4_INDEX_FL; data1 = bh2->b_data; - /* The 0th block becomes the root, move the dirents out */ - fde = &root->dotdot; - de = (struct ext4_dir_entry_2 *)((char *)fde + - ext4_rec_len_from_disk(fde->rec_len)); - len = ((char *) root) + blocksize - (char *) de; memcpy (data1, de, len); de = (struct ext4_dir_entry_2 *) data1; top = data1 + len; @@ -1408,6 +1422,8 @@ /* Initialize as for dx_probe */ hinfo.hash_version = root->info.hash_version; + if (hinfo.hash_version <= DX_HASH_TEA) + hinfo.hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned; hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed; ext4fs_dirhash(name, namelen, &hinfo); frame = frames; @@ -2208,8 +2224,7 @@ * We have a transaction open. All is sweetness. It also sets * i_size in generic_commit_write(). */ - err = __page_symlink(inode, symname, l, - mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); + err = __page_symlink(inode, symname, l, 1); if (err) { clear_nlink(inode); ext4_mark_inode_dirty(handle, inode); @@ -2283,7 +2298,7 @@ struct inode *old_inode, *new_inode; struct buffer_head *old_bh, *new_bh, *dir_bh; struct ext4_dir_entry_2 *old_de, *new_de; - int retval; + int retval, force_da_alloc = 0; old_bh = new_bh = dir_bh = NULL; @@ -2421,6 +2436,7 @@ ext4_mark_inode_dirty(handle, new_inode); if (!new_inode->i_nlink) ext4_orphan_add(handle, new_inode); + force_da_alloc = 1; } retval = 0; @@ -2429,6 +2445,8 @@ brelse(old_bh); brelse(new_bh); ext4_journal_stop(handle); + if (retval == 0 && force_da_alloc) + ext4_alloc_da_blocks(old_inode); return retval; } --- linux-2.6.28.orig/fs/ext4/hash.c +++ linux-2.6.28/fs/ext4/hash.c @@ -35,23 +35,71 @@ /* The old legacy hash */ -static __u32 dx_hack_hash(const char *name, int len) +static __u32 dx_hack_hash_unsigned(const char *name, int len) { - __u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9; + __u32 hash, hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9; + const unsigned char *ucp = (const unsigned char *) name; + + while (len--) { + hash = hash1 + (hash0 ^ (((int) *ucp++) * 7152373)); + + if (hash & 0x80000000) + hash -= 0x7fffffff; + hash1 = hash0; + hash0 = hash; + } + return hash0 << 1; +} + +static __u32 dx_hack_hash_signed(const char *name, int len) +{ + __u32 hash, hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9; + const signed char *scp = (const signed char *) name; + while (len--) { - __u32 hash = hash1 + (hash0 ^ (*name++ * 7152373)); + hash = hash1 + (hash0 ^ (((int) *scp++) * 7152373)); - if (hash & 0x80000000) hash -= 0x7fffffff; + if (hash & 0x80000000) + hash -= 0x7fffffff; hash1 = hash0; hash0 = hash; } - return (hash0 << 1); + return hash0 << 1; +} + +static void str2hashbuf_signed(const char *msg, int len, __u32 *buf, int num) +{ + __u32 pad, val; + int i; + const signed char *scp = (const signed char *) msg; + + pad = (__u32)len | ((__u32)len << 8); + pad |= pad << 16; + + val = pad; + if (len > num*4) + len = num * 4; + for (i = 0; i < len; i++) { + if ((i % 4) == 0) + val = pad; + val = ((int) scp[i]) + (val << 8); + if ((i % 4) == 3) { + *buf++ = val; + val = pad; + num--; + } + } + if (--num >= 0) + *buf++ = val; + while (--num >= 0) + *buf++ = pad; } -static void str2hashbuf(const char *msg, int len, __u32 *buf, int num) +static void str2hashbuf_unsigned(const char *msg, int len, __u32 *buf, int num) { __u32 pad, val; int i; + const unsigned char *ucp = (const unsigned char *) msg; pad = (__u32)len | ((__u32)len << 8); pad |= pad << 16; @@ -62,7 +110,7 @@ for (i = 0; i < len; i++) { if ((i % 4) == 0) val = pad; - val = msg[i] + (val << 8); + val = ((int) ucp[i]) + (val << 8); if ((i % 4) == 3) { *buf++ = val; val = pad; @@ -95,6 +143,8 @@ const char *p; int i; __u32 in[8], buf[4]; + void (*str2hashbuf)(const char *, int, __u32 *, int) = + str2hashbuf_signed; /* Initialize the default seed for the hash checksum functions */ buf[0] = 0x67452301; @@ -113,13 +163,18 @@ } switch (hinfo->hash_version) { + case DX_HASH_LEGACY_UNSIGNED: + hash = dx_hack_hash_unsigned(name, len); + break; case DX_HASH_LEGACY: - hash = dx_hack_hash(name, len); + hash = dx_hack_hash_signed(name, len); break; + case DX_HASH_HALF_MD4_UNSIGNED: + str2hashbuf = str2hashbuf_unsigned; case DX_HASH_HALF_MD4: p = name; while (len > 0) { - str2hashbuf(p, len, in, 8); + (*str2hashbuf)(p, len, in, 8); half_md4_transform(buf, in); len -= 32; p += 32; @@ -127,10 +182,12 @@ minor_hash = buf[2]; hash = buf[1]; break; + case DX_HASH_TEA_UNSIGNED: + str2hashbuf = str2hashbuf_unsigned; case DX_HASH_TEA: p = name; while (len > 0) { - str2hashbuf(p, len, in, 4); + (*str2hashbuf)(p, len, in, 4); TEA_transform(buf, in); len -= 16; p += 16; --- linux-2.6.28.orig/fs/ext4/extents.c +++ linux-2.6.28/fs/ext4/extents.c @@ -1120,7 +1120,8 @@ struct ext4_extent_idx *ix; struct ext4_extent *ex; ext4_fsblk_t block; - int depth, ee_len; + int depth; /* Note, NOT eh_depth; depth from top of tree */ + int ee_len; BUG_ON(path == NULL); depth = path->p_depth; @@ -1179,7 +1180,8 @@ if (bh == NULL) return -EIO; eh = ext_block_hdr(bh); - if (ext4_ext_check_header(inode, eh, depth)) { + /* subtract from p_depth to get proper eh_depth */ + if (ext4_ext_check_header(inode, eh, path->p_depth - depth)) { put_bh(bh); return -EIO; } --- linux-2.6.28.orig/fs/ext4/file.c +++ linux-2.6.28/fs/ext4/file.c @@ -33,6 +33,10 @@ */ static int ext4_release_file(struct inode *inode, struct file *filp) { + if (EXT4_I(inode)->i_state & EXT4_STATE_DA_ALLOC_CLOSE) { + ext4_alloc_da_blocks(inode); + EXT4_I(inode)->i_state &= ~EXT4_STATE_DA_ALLOC_CLOSE; + } /* if we are the last writer on the inode, drop the block reservation */ if ((filp->f_mode & FMODE_WRITE) && (atomic_read(&inode->i_writecount) == 1)) --- linux-2.6.28.orig/fs/ext4/mballoc.h +++ linux-2.6.28/fs/ext4/mballoc.h @@ -20,6 +20,7 @@ #include #include #include +#include #include "ext4_jbd2.h" #include "ext4.h" #include "group.h" @@ -98,9 +99,6 @@ */ #define MB_DEFAULT_GROUP_PREALLOC 512 -static struct kmem_cache *ext4_pspace_cachep; -static struct kmem_cache *ext4_ac_cachep; -static struct kmem_cache *ext4_free_ext_cachep; struct ext4_free_data { /* this links the free block information from group_info */ @@ -130,6 +128,7 @@ #ifdef DOUBLE_CHECK void *bb_bitmap; #endif + struct rw_semaphore alloc_sem; unsigned short bb_counters[]; }; @@ -217,6 +216,11 @@ __u8 ac_op; /* operation, for history only */ struct page *ac_bitmap_page; struct page *ac_buddy_page; + /* + * pointer to the held semaphore upon successful + * block allocation + */ + struct rw_semaphore *alloc_semp; struct ext4_prealloc_space *ac_pa; struct ext4_locality_group *ac_lg; }; @@ -250,6 +254,7 @@ struct super_block *bd_sb; __u16 bd_blkbits; ext4_group_t bd_group; + struct rw_semaphore *alloc_semp; }; #define EXT4_MB_BITMAP(e4b) ((e4b)->bd_bitmap) #define EXT4_MB_BUDDY(e4b) ((e4b)->bd_buddy) @@ -259,25 +264,12 @@ { return; } -#else -static void ext4_mb_store_history(struct ext4_allocation_context *ac); #endif #define in_range(b, first, len) ((b) >= (first) && (b) <= (first) + (len) - 1) struct buffer_head *read_block_bitmap(struct super_block *, ext4_group_t); -static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, - ext4_group_t group); -static void ext4_mb_return_to_preallocation(struct inode *inode, - struct ext4_buddy *e4b, sector_t block, - int count); -static void ext4_mb_put_pa(struct ext4_allocation_context *, - struct super_block *, struct ext4_prealloc_space *pa); -static int ext4_mb_init_per_dev_proc(struct super_block *sb); -static int ext4_mb_destroy_per_dev_proc(struct super_block *sb); -static void release_blocks_on_commit(journal_t *journal, transaction_t *txn); - static inline void ext4_lock_group(struct super_block *sb, ext4_group_t group) { @@ -303,7 +295,7 @@ &(grinfo->bb_state)); } -static ext4_fsblk_t ext4_grp_offs_to_block(struct super_block *sb, +static inline ext4_fsblk_t ext4_grp_offs_to_block(struct super_block *sb, struct ext4_free_extent *fex) { ext4_fsblk_t block; --- linux-2.6.28.orig/fs/ext4/ialloc.c +++ linux-2.6.28/fs/ext4/ialloc.c @@ -84,7 +84,7 @@ } memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8); - mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), EXT4_BLOCKS_PER_GROUP(sb), + mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), sb->s_blocksize * 8, bh->b_data); return EXT4_INODES_PER_GROUP(sb); @@ -115,20 +115,40 @@ block_group, bitmap_blk); return NULL; } - if (buffer_uptodate(bh) && - !(desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT))) + if (bitmap_uptodate(bh)) return bh; lock_buffer(bh); + if (bitmap_uptodate(bh)) { + unlock_buffer(bh); + return bh; + } spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group)); if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) { ext4_init_inode_bitmap(sb, bh, block_group, desc); + set_bitmap_uptodate(bh); set_buffer_uptodate(bh); unlock_buffer(bh); spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group)); return bh; } spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group)); + if (buffer_uptodate(bh)) { + /* + * if not uninit if bh is uptodate, + * bitmap is also uptodate + */ + set_bitmap_uptodate(bh); + unlock_buffer(bh); + return bh; + } + /* + * submit the buffer_head for read. We can + * safely mark the bitmap as uptodate now. + * We do it here so the bitmap uptodate bit + * get set with buffer lock held. + */ + set_bitmap_uptodate(bh); if (bh_submit_read(bh) < 0) { put_bh(bh); ext4_error(sb, __func__, @@ -570,6 +590,77 @@ } /* + * claim the inode from the inode bitmap. If the group + * is uninit we need to take the groups's sb_bgl_lock + * and clear the uninit flag. The inode bitmap update + * and group desc uninit flag clear should be done + * after holding sb_bgl_lock so that ext4_read_inode_bitmap + * doesn't race with the ext4_claim_inode + */ +static int ext4_claim_inode(struct super_block *sb, + struct buffer_head *inode_bitmap_bh, + unsigned long ino, ext4_group_t group, int mode) +{ + int free = 0, retval = 0; + struct ext4_sb_info *sbi = EXT4_SB(sb); + struct ext4_group_desc *gdp = ext4_get_group_desc(sb, group, NULL); + + spin_lock(sb_bgl_lock(sbi, group)); + if (ext4_set_bit(ino, inode_bitmap_bh->b_data)) { + /* not a free inode */ + retval = 1; + goto err_ret; + } + ino++; + if ((group == 0 && ino < EXT4_FIRST_INO(sb)) || + ino > EXT4_INODES_PER_GROUP(sb)) { + spin_unlock(sb_bgl_lock(sbi, group)); + ext4_error(sb, __func__, + "reserved inode or inode > inodes count - " + "block_group = %lu, inode=%lu", group, + ino + group * EXT4_INODES_PER_GROUP(sb)); + return 1; + } + /* If we didn't allocate from within the initialized part of the inode + * table then we need to initialize up to this inode. */ + if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) { + + if (gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) { + gdp->bg_flags &= cpu_to_le16(~EXT4_BG_INODE_UNINIT); + /* When marking the block group with + * ~EXT4_BG_INODE_UNINIT we don't want to depend + * on the value of bg_itable_unused even though + * mke2fs could have initialized the same for us. + * Instead we calculated the value below + */ + + free = 0; + } else { + free = EXT4_INODES_PER_GROUP(sb) - + le16_to_cpu(gdp->bg_itable_unused); + } + + /* + * Check the relative inode number against the last used + * relative inode number in this group. if it is greater + * we need to update the bg_itable_unused count + * + */ + if (ino > free) + gdp->bg_itable_unused = + cpu_to_le16(EXT4_INODES_PER_GROUP(sb) - ino); + } + le16_add_cpu(&gdp->bg_free_inodes_count, -1); + if (S_ISDIR(mode)) { + le16_add_cpu(&gdp->bg_used_dirs_count, 1); + } + gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp); +err_ret: + spin_unlock(sb_bgl_lock(sbi, group)); + return retval; +} + +/* * There are two policies for allocating an inode. If the new inode is * a directory, then a forward search is made for a block group with both * free space and a low directory-to-inode ratio; if that fails, then of @@ -612,6 +703,13 @@ if (sbi->s_log_groups_per_flex) { ret2 = find_group_flex(sb, dir, &group); + if (ret2 == -1) { + ret2 = find_group_other(sb, dir, &group); + if (ret2 == 0 && printk_ratelimit()) + printk(KERN_NOTICE "ext4: find_group_flex " + "failed, fallback succeeded dir %lu\n", + dir->i_ino); + } goto got_group; } @@ -652,8 +750,12 @@ if (err) goto fail; - if (!ext4_set_bit_atomic(sb_bgl_lock(sbi, group), - ino, bitmap_bh->b_data)) { + BUFFER_TRACE(bh2, "get_write_access"); + err = ext4_journal_get_write_access(handle, bh2); + if (err) + goto fail; + if (!ext4_claim_inode(sb, bitmap_bh, + ino, group, mode)) { /* we won it */ BUFFER_TRACE(bitmap_bh, "call ext4_journal_dirty_metadata"); @@ -661,10 +763,13 @@ bitmap_bh); if (err) goto fail; + /* zero bit is inode number 1*/ + ino++; goto got; } /* we lost it */ jbd2_journal_release_buffer(handle, bitmap_bh); + jbd2_journal_release_buffer(handle, bh2); if (++ino < EXT4_INODES_PER_GROUP(sb)) goto repeat_in_this_group; @@ -684,21 +789,6 @@ goto out; got: - ino++; - if ((group == 0 && ino < EXT4_FIRST_INO(sb)) || - ino > EXT4_INODES_PER_GROUP(sb)) { - ext4_error(sb, __func__, - "reserved inode or inode > inodes count - " - "block_group = %lu, inode=%lu", group, - ino + group * EXT4_INODES_PER_GROUP(sb)); - err = -EIO; - goto fail; - } - - BUFFER_TRACE(bh2, "get_write_access"); - err = ext4_journal_get_write_access(handle, bh2); - if (err) goto fail; - /* 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)) { @@ -733,47 +823,10 @@ if (err) goto fail; } - - spin_lock(sb_bgl_lock(sbi, group)); - /* If we didn't allocate from within the initialized part of the inode - * table then we need to initialize up to this inode. */ - if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) { - if (gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) { - gdp->bg_flags &= cpu_to_le16(~EXT4_BG_INODE_UNINIT); - - /* When marking the block group with - * ~EXT4_BG_INODE_UNINIT we don't want to depend - * on the value of bg_itable_unused even though - * mke2fs could have initialized the same for us. - * Instead we calculated the value below - */ - - free = 0; - } else { - free = EXT4_INODES_PER_GROUP(sb) - - le16_to_cpu(gdp->bg_itable_unused); - } - - /* - * Check the relative inode number against the last used - * relative inode number in this group. if it is greater - * we need to update the bg_itable_unused count - * - */ - if (ino > free) - gdp->bg_itable_unused = - cpu_to_le16(EXT4_INODES_PER_GROUP(sb) - ino); - } - - le16_add_cpu(&gdp->bg_free_inodes_count, -1); - if (S_ISDIR(mode)) { - le16_add_cpu(&gdp->bg_used_dirs_count, 1); - } - gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp); - spin_unlock(sb_bgl_lock(sbi, group)); - BUFFER_TRACE(bh2, "call ext4_journal_dirty_metadata"); + BUFFER_TRACE(bh2, "call ext4_handle_dirty_metadata"); err = ext4_journal_dirty_metadata(handle, bh2); - if (err) goto fail; + if (err) + goto fail; percpu_counter_dec(&sbi->s_freeinodes_counter); if (S_ISDIR(mode)) --- linux-2.6.28.orig/fs/ext4/mballoc.c +++ linux-2.6.28/fs/ext4/mballoc.c @@ -100,7 +100,7 @@ * inode as: * * { page } - * [ group 0 buddy][ group 0 bitmap] [group 1][ group 1]... + * [ group 0 bitmap][ group 0 buddy] [group 1][ group 1]... * * * one block each for bitmap and buddy information. So for each group we @@ -330,6 +330,18 @@ * object * */ +static struct kmem_cache *ext4_pspace_cachep; +static struct kmem_cache *ext4_ac_cachep; +static struct kmem_cache *ext4_free_ext_cachep; +static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, + ext4_group_t group); +static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap, + ext4_group_t group); +static int ext4_mb_init_per_dev_proc(struct super_block *sb); +static int ext4_mb_destroy_per_dev_proc(struct super_block *sb); +static void release_blocks_on_commit(journal_t *journal, transaction_t *txn); + + static inline void *mb_correct_addr_and_bit(int *bit, void *addr) { @@ -716,7 +728,7 @@ * stored in the inode as * * { page } - * [ group 0 buddy][ group 0 bitmap] [group 1][ group 1]... + * [ group 0 bitmap][ group 0 buddy] [group 1][ group 1]... * * * one block each for bitmap and buddy information. @@ -782,22 +794,42 @@ if (bh[i] == NULL) goto out; - if (buffer_uptodate(bh[i]) && - !(desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) + if (bitmap_uptodate(bh[i])) continue; lock_buffer(bh[i]); + if (bitmap_uptodate(bh[i])) { + unlock_buffer(bh[i]); + continue; + } spin_lock(sb_bgl_lock(EXT4_SB(sb), first_group + i)); if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { ext4_init_block_bitmap(sb, bh[i], first_group + i, desc); + set_bitmap_uptodate(bh[i]); set_buffer_uptodate(bh[i]); unlock_buffer(bh[i]); spin_unlock(sb_bgl_lock(EXT4_SB(sb), first_group + i)); continue; } spin_unlock(sb_bgl_lock(EXT4_SB(sb), first_group + i)); + if (buffer_uptodate(bh[i])) { + /* + * if not uninit if bh is uptodate, + * bitmap is also uptodate + */ + set_bitmap_uptodate(bh[i]); + unlock_buffer(bh[i]); + continue; + } get_bh(bh[i]); + /* + * submit the buffer_head for read. We can + * safely mark the bitmap as uptodate now. + * We do it here so the bitmap uptodate bit + * get set with buffer lock held. + */ + set_bitmap_uptodate(bh[i]); bh[i]->b_end_io = end_buffer_read_sync; submit_bh(READ, bh[i]); mb_debug("read bitmap for group %lu\n", first_group + i); @@ -814,6 +846,8 @@ err = 0; first_block = page->index * blocks_per_page; + /* init the page */ + memset(page_address(page), 0xff, PAGE_CACHE_SIZE); for (i = 0; i < blocks_per_page; i++) { int group; struct ext4_group_info *grinfo; @@ -840,7 +874,6 @@ BUG_ON(incore == NULL); mb_debug("put buddy for group %u in page %lu/%x\n", group, page->index, i * blocksize); - memset(data, 0xff, blocksize); grinfo = ext4_get_group_info(sb, group); grinfo->bb_fragments = 0; memset(grinfo->bb_counters, 0, @@ -848,7 +881,9 @@ /* * incore got set to the group block bitmap below */ + ext4_lock_group(sb, group); ext4_mb_generate_buddy(sb, data, incore, group); + ext4_unlock_group(sb, group); incore = NULL; } else { /* this is block of bitmap */ @@ -862,6 +897,7 @@ /* mark all preallocated blks used in in-core bitmap */ ext4_mb_generate_from_pa(sb, data, group); + ext4_mb_generate_from_freelist(sb, data, group); ext4_unlock_group(sb, group); /* set incore so that the buddy information can be @@ -886,18 +922,20 @@ ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group, struct ext4_buddy *e4b) { - struct ext4_sb_info *sbi = EXT4_SB(sb); - struct inode *inode = sbi->s_buddy_cache; int blocks_per_page; int block; int pnum; int poff; struct page *page; int ret; + struct ext4_group_info *grp; + struct ext4_sb_info *sbi = EXT4_SB(sb); + struct inode *inode = sbi->s_buddy_cache; mb_debug("load group %lu\n", group); blocks_per_page = PAGE_CACHE_SIZE / sb->s_blocksize; + grp = ext4_get_group_info(sb, group); e4b->bd_blkbits = sb->s_blocksize_bits; e4b->bd_info = ext4_get_group_info(sb, group); @@ -905,6 +943,15 @@ e4b->bd_group = group; e4b->bd_buddy_page = NULL; e4b->bd_bitmap_page = NULL; + e4b->alloc_semp = &grp->alloc_sem; + + /* Take the read lock on the group alloc + * sem. This would make sure a parallel + * ext4_mb_init_group happening on other + * groups mapped by the page is blocked + * till we are done with allocation + */ + down_read(e4b->alloc_semp); /* * the buddy cache inode stores the block bitmap @@ -920,6 +967,14 @@ page = find_get_page(inode->i_mapping, pnum); if (page == NULL || !PageUptodate(page)) { if (page) + /* + * drop the page reference and try + * to get the page with lock. If we + * are not uptodate that implies + * somebody just created the page but + * is yet to initialize the same. So + * wait for it to initialize. + */ page_cache_release(page); page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS); if (page) { @@ -985,6 +1040,9 @@ page_cache_release(e4b->bd_buddy_page); e4b->bd_buddy = NULL; e4b->bd_bitmap = NULL; + + /* Done with the buddy cache */ + up_read(e4b->alloc_semp); return ret; } @@ -994,6 +1052,9 @@ page_cache_release(e4b->bd_bitmap_page); if (e4b->bd_buddy_page) page_cache_release(e4b->bd_buddy_page); + /* Done with the buddy cache */ + if (e4b->alloc_semp) + up_read(e4b->alloc_semp); } @@ -1031,7 +1092,10 @@ cur += 32; continue; } - mb_clear_bit_atomic(lock, cur, bm); + if (lock) + mb_clear_bit_atomic(lock, cur, bm); + else + mb_clear_bit(cur, bm); cur++; } } @@ -1049,7 +1113,10 @@ cur += 32; continue; } - mb_set_bit_atomic(lock, cur, bm); + if (lock) + mb_set_bit_atomic(lock, cur, bm); + else + mb_set_bit(cur, bm); cur++; } } @@ -1296,13 +1363,20 @@ ac->ac_tail = ret & 0xffff; ac->ac_buddy = ret >> 16; - /* XXXXXXX: SUCH A HORRIBLE **CK */ - /*FIXME!! Why ? */ + /* + * take the page reference. We want the page to be pinned + * so that we don't get a ext4_mb_init_cache_call for this + * group until we update the bitmap. That would mean we + * double allocate blocks. The reference is dropped + * in ext4_mb_release_context + */ ac->ac_bitmap_page = e4b->bd_bitmap_page; get_page(ac->ac_bitmap_page); ac->ac_buddy_page = e4b->bd_buddy_page; get_page(ac->ac_buddy_page); - + /* on allocation we use ac to track the held semaphore */ + ac->alloc_semp = e4b->alloc_semp; + e4b->alloc_semp = NULL; /* store last allocated for subsequent stream allocation */ if ((ac->ac_flags & EXT4_MB_HINT_DATA)) { spin_lock(&sbi->s_md_lock); @@ -1326,6 +1400,8 @@ struct ext4_free_extent ex; int max; + if (ac->ac_status == AC_STATUS_FOUND) + return; /* * We don't want to scan for a whole year */ @@ -1692,6 +1768,173 @@ return 0; } +/* + * lock the group_info alloc_sem of all the groups + * belonging to the same buddy cache page. This + * make sure other parallel operation on the buddy + * cache doesn't happen whild holding the buddy cache + * lock + */ +int ext4_mb_get_buddy_cache_lock(struct super_block *sb, ext4_group_t group) +{ + int i; + int block, pnum; + int blocks_per_page; + int groups_per_page; + ext4_group_t first_group; + struct ext4_group_info *grp; + + blocks_per_page = PAGE_CACHE_SIZE / sb->s_blocksize; + /* + * the buddy cache inode stores the block bitmap + * and buddy information in consecutive blocks. + * So for each group we need two blocks. + */ + block = group * 2; + pnum = block / blocks_per_page; + first_group = pnum * blocks_per_page / 2; + + groups_per_page = blocks_per_page >> 1; + if (groups_per_page == 0) + groups_per_page = 1; + /* read all groups the page covers into the cache */ + for (i = 0; i < groups_per_page; i++) { + + if ((first_group + i) >= EXT4_SB(sb)->s_groups_count) + break; + grp = ext4_get_group_info(sb, first_group + i); + /* take all groups write allocation + * semaphore. This make sure there is + * no block allocation going on in any + * of that groups + */ + down_write(&grp->alloc_sem); + } + return i; +} + +void ext4_mb_put_buddy_cache_lock(struct super_block *sb, + ext4_group_t group, int locked_group) +{ + int i; + int block, pnum; + int blocks_per_page; + ext4_group_t first_group; + struct ext4_group_info *grp; + + blocks_per_page = PAGE_CACHE_SIZE / sb->s_blocksize; + /* + * the buddy cache inode stores the block bitmap + * and buddy information in consecutive blocks. + * So for each group we need two blocks. + */ + block = group * 2; + pnum = block / blocks_per_page; + first_group = pnum * blocks_per_page / 2; + /* release locks on all the groups */ + for (i = 0; i < locked_group; i++) { + + grp = ext4_get_group_info(sb, first_group + i); + /* take all groups write allocation + * semaphore. This make sure there is + * no block allocation going on in any + * of that groups + */ + up_write(&grp->alloc_sem); + } + +} + +static int ext4_mb_init_group(struct super_block *sb, ext4_group_t group) +{ + + int ret; + void *bitmap; + int blocks_per_page; + int block, pnum, poff; + int num_grp_locked = 0; + struct ext4_group_info *this_grp; + struct ext4_sb_info *sbi = EXT4_SB(sb); + struct inode *inode = sbi->s_buddy_cache; + struct page *page = NULL, *bitmap_page = NULL; + + mb_debug("init group %lu\n", group); + blocks_per_page = PAGE_CACHE_SIZE / sb->s_blocksize; + this_grp = ext4_get_group_info(sb, group); + /* + * This ensures we don't add group + * to this buddy cache via resize + */ + num_grp_locked = ext4_mb_get_buddy_cache_lock(sb, group); + if (!EXT4_MB_GRP_NEED_INIT(this_grp)) { + /* + * somebody initialized the group + * return without doing anything + */ + ret = 0; + goto err; + } + /* + * the buddy cache inode stores the block bitmap + * and buddy information in consecutive blocks. + * So for each group we need two blocks. + */ + block = group * 2; + pnum = block / blocks_per_page; + poff = block % blocks_per_page; + page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS); + if (page) { + BUG_ON(page->mapping != inode->i_mapping); + ret = ext4_mb_init_cache(page, NULL); + if (ret) { + unlock_page(page); + goto err; + } + unlock_page(page); + } + if (page == NULL || !PageUptodate(page)) { + ret = -EIO; + goto err; + } + mark_page_accessed(page); + bitmap_page = page; + bitmap = page_address(page) + (poff * sb->s_blocksize); + + /* init buddy cache */ + block++; + pnum = block / blocks_per_page; + poff = block % blocks_per_page; + page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS); + if (page == bitmap_page) { + /* + * If both the bitmap and buddy are in + * the same page we don't need to force + * init the buddy + */ + unlock_page(page); + } else if (page) { + BUG_ON(page->mapping != inode->i_mapping); + ret = ext4_mb_init_cache(page, bitmap); + if (ret) { + unlock_page(page); + goto err; + } + unlock_page(page); + } + if (page == NULL || !PageUptodate(page)) { + ret = -EIO; + goto err; + } + mark_page_accessed(page); +err: + ext4_mb_put_buddy_cache_lock(sb, group, num_grp_locked); + if (bitmap_page) + page_cache_release(bitmap_page); + if (page) + page_cache_release(page); + return ret; +} + static noinline_for_stack int ext4_mb_regular_allocator(struct ext4_allocation_context *ac) { @@ -1775,7 +2018,7 @@ group = 0; /* quick check to skip empty groups */ - grp = ext4_get_group_info(ac->ac_sb, group); + grp = ext4_get_group_info(sb, group); if (grp->bb_free == 0) continue; @@ -1788,10 +2031,9 @@ * we need full data about the group * to make a good selection */ - err = ext4_mb_load_buddy(sb, group, &e4b); + err = ext4_mb_init_group(sb, group); if (err) goto out; - ext4_mb_release_desc(&e4b); } /* @@ -2300,6 +2542,7 @@ } INIT_LIST_HEAD(&meta_group_info[i]->bb_prealloc_list); + init_rwsem(&meta_group_info[i]->alloc_sem); meta_group_info[i]->bb_free_root.rb_node = NULL;; #ifdef DOUBLE_CHECK @@ -2327,54 +2570,6 @@ } /* 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 */ @@ -2493,6 +2688,8 @@ if (sbi->s_mb_offsets == NULL) { return -ENOMEM; } + + i = (sb->s_blocksize_bits + 2) * sizeof(unsigned int); sbi->s_mb_maxs = kmalloc(i, GFP_KERNEL); if (sbi->s_mb_maxs == NULL) { kfree(sbi->s_mb_maxs); @@ -2843,8 +3040,8 @@ in_range(block + len - 1, ext4_inode_table(sb, gdp), EXT4_SB(sb)->s_itb_per_group)) { ext4_error(sb, __func__, - "Allocating block in system zone - block = %llu", - block); + "Allocating block %llu in system zone of %d group\n", + block, ac->ac_b_ex.fe_group); /* File system mounted not to panic on error * Fix the bitmap and repeat the block allocation * We leak some of the blocks here. @@ -2866,10 +3063,9 @@ } } #endif - mb_set_bits(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group), bitmap_bh->b_data, - ac->ac_b_ex.fe_start, ac->ac_b_ex.fe_len); - spin_lock(sb_bgl_lock(sbi, ac->ac_b_ex.fe_group)); + mb_set_bits(NULL, bitmap_bh->b_data, + ac->ac_b_ex.fe_start, ac->ac_b_ex.fe_len); if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); gdp->bg_free_blocks_count = @@ -3307,6 +3503,32 @@ } /* + * the function goes through all block freed in the group + * but not yet committed and marks them used in in-core bitmap. + * buddy must be generated from this bitmap + * Need to be called with ext4 group lock (ext4_lock_group) + */ +static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap, + ext4_group_t group) +{ + struct rb_node *n; + struct ext4_group_info *grp; + struct ext4_free_data *entry; + + grp = ext4_get_group_info(sb, group); + n = rb_first(&(grp->bb_free_root)); + + while (n) { + entry = rb_entry(n, struct ext4_free_data, node); + mb_set_bits(sb_bgl_lock(EXT4_SB(sb), group), + bitmap, entry->start_blk, + entry->count); + n = rb_next(n); + } + return; +} + +/* * the function goes through all preallocation in this group and marks them * used in in-core bitmap. buddy must be generated from this bitmap * Need to be called with ext4 group lock (ext4_lock_group) @@ -3364,6 +3586,7 @@ struct super_block *sb, struct ext4_prealloc_space *pa) { unsigned long grp; + ext4_fsblk_t grp_blk; if (!atomic_dec_and_test(&pa->pa_count) || pa->pa_free != 0) return; @@ -3378,8 +3601,12 @@ pa->pa_deleted = 1; spin_unlock(&pa->pa_lock); - /* -1 is to protect from crossing allocation group */ - ext4_get_group_no_and_offset(sb, pa->pa_pstart - 1, &grp, NULL); + grp_blk = pa->pa_pstart; + /* If linear, pa_pstart may be in the next group when pa is used up */ + if (pa->pa_linear) + grp_blk--; + + ext4_get_group_no_and_offset(sb, grp_blk, &grp, NULL); /* * possible race: @@ -3468,6 +3695,8 @@ pa->pa_free = pa->pa_len; atomic_set(&pa->pa_count, 1); spin_lock_init(&pa->pa_lock); + INIT_LIST_HEAD(&pa->pa_inode_list); + INIT_LIST_HEAD(&pa->pa_group_list); pa->pa_deleted = 0; pa->pa_linear = 0; @@ -3526,6 +3755,7 @@ atomic_set(&pa->pa_count, 1); spin_lock_init(&pa->pa_lock); INIT_LIST_HEAD(&pa->pa_inode_list); + INIT_LIST_HEAD(&pa->pa_group_list); pa->pa_deleted = 0; pa->pa_linear = 1; @@ -4068,6 +4298,7 @@ ac->ac_pa = NULL; ac->ac_bitmap_page = NULL; ac->ac_buddy_page = NULL; + ac->alloc_semp = NULL; ac->ac_lg = NULL; /* we have to define context: we'll we work with a file or @@ -4233,18 +4464,23 @@ pa->pa_free -= ac->ac_b_ex.fe_len; pa->pa_len -= ac->ac_b_ex.fe_len; spin_unlock(&pa->pa_lock); - /* - * We want to add the pa to the right bucket. - * Remove it from the list and while adding - * make sure the list to which we are adding - * doesn't grow big. - */ - if (likely(pa->pa_free)) { - spin_lock(pa->pa_obj_lock); - list_del_rcu(&pa->pa_inode_list); - spin_unlock(pa->pa_obj_lock); - ext4_mb_add_n_trim(ac); - } + } + } + if (ac->alloc_semp) + up_read(ac->alloc_semp); + if (pa) { + /* + * We want to add the pa to the right bucket. + * Remove it from the list and while adding + * make sure the list to which we are adding + * doesn't grow big. We need to release + * alloc_semp before calling ext4_mb_add_n_trim() + */ + if (pa->pa_linear && likely(pa->pa_free)) { + spin_lock(pa->pa_obj_lock); + list_del_rcu(&pa->pa_inode_list); + spin_unlock(pa->pa_obj_lock); + ext4_mb_add_n_trim(ac); } ext4_mb_put_pa(ac, ac->ac_sb, pa); } @@ -4313,7 +4549,7 @@ } if (ar->len == 0) { *errp = -EDQUOT; - return 0; + goto out3; } inquota = ar->len; @@ -4348,10 +4584,14 @@ ac->ac_o_ex.fe_len < ac->ac_b_ex.fe_len) ext4_mb_new_preallocation(ac); } - if (likely(ac->ac_status == AC_STATUS_FOUND)) { *errp = ext4_mb_mark_diskspace_used(ac, handle, reserv_blks); if (*errp == -EAGAIN) { + /* + * drop the reference that we took + * in ext4_mb_use_best_found + */ + ext4_mb_release_context(ac); ac->ac_b_ex.fe_group = 0; ac->ac_b_ex.fe_start = 0; ac->ac_b_ex.fe_len = 0; @@ -4382,6 +4622,13 @@ out1: if (ar->len < inquota) DQUOT_FREE_BLOCK(ar->inode, inquota - ar->len); +out3: + if (!ar->len) { + if (!EXT4_I(ar->inode)->i_delalloc_reserved_flag) + /* release all the reserved blocks if non delalloc */ + percpu_counter_sub(&sbi->s_dirtyblocks_counter, + reserv_blks); + } return block; } @@ -4403,12 +4650,13 @@ static noinline_for_stack int ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b, - ext4_group_t group, ext4_grpblk_t block, int count) + struct ext4_free_data *new_entry) { + ext4_grpblk_t block; + struct ext4_free_data *entry; struct ext4_group_info *db = e4b->bd_info; struct super_block *sb = e4b->bd_sb; struct ext4_sb_info *sbi = EXT4_SB(sb); - struct ext4_free_data *entry, *new_entry; struct rb_node **n = &db->bb_free_root.rb_node, *node; struct rb_node *parent = NULL, *new_node; @@ -4416,14 +4664,9 @@ BUG_ON(e4b->bd_bitmap_page == NULL); BUG_ON(e4b->bd_buddy_page == NULL); - new_entry = kmem_cache_alloc(ext4_free_ext_cachep, GFP_NOFS); - new_entry->start_blk = block; - new_entry->group = group; - new_entry->count = count; - new_entry->t_tid = handle->h_transaction->t_tid; new_node = &new_entry->node; + block = new_entry->start_blk; - ext4_lock_group(sb, group); if (!*n) { /* first free block exent. We need to protect buddy cache from being freed, @@ -4441,7 +4684,6 @@ else if (block >= (entry->start_blk + entry->count)) n = &(*n)->rb_right; else { - ext4_unlock_group(sb, group); ext4_error(sb, __func__, "Double free of blocks %d (%d %d)\n", block, entry->start_blk, entry->count); @@ -4483,7 +4725,6 @@ spin_lock(&sbi->s_md_lock); list_add(&new_entry->list, &handle->h_transaction->t_private_list); spin_unlock(&sbi->s_md_lock); - ext4_unlock_group(sb, group); return 0; } @@ -4581,11 +4822,6 @@ err = ext4_journal_get_write_access(handle, gd_bh); if (err) goto error_return; - - err = ext4_mb_load_buddy(sb, block_group, &e4b); - if (err) - goto error_return; - #ifdef AGGRESSIVE_CHECK { int i; @@ -4593,13 +4829,6 @@ BUG_ON(!mb_test_bit(bit + i, bitmap_bh->b_data)); } #endif - mb_clear_bits(sb_bgl_lock(sbi, block_group), bitmap_bh->b_data, - bit, count); - - /* We dirtied the bitmap block */ - BUFFER_TRACE(bitmap_bh, "dirtied bitmap block"); - err = ext4_journal_dirty_metadata(handle, bitmap_bh); - if (ac) { ac->ac_b_ex.fe_group = block_group; ac->ac_b_ex.fe_start = bit; @@ -4607,12 +4836,33 @@ ext4_mb_store_history(ac); } + err = ext4_mb_load_buddy(sb, block_group, &e4b); + if (err) + goto error_return; if (metadata) { - /* blocks being freed are metadata. these blocks shouldn't - * be used until this transaction is committed */ - ext4_mb_free_metadata(handle, &e4b, block_group, bit, count); + struct ext4_free_data *new_entry; + /* + * blocks being freed are metadata. these blocks shouldn't + * be used until this transaction is committed + */ + new_entry = kmem_cache_alloc(ext4_free_ext_cachep, GFP_NOFS); + new_entry->start_blk = bit; + new_entry->group = block_group; + new_entry->count = count; + new_entry->t_tid = handle->h_transaction->t_tid; + ext4_lock_group(sb, block_group); + mb_clear_bits(sb_bgl_lock(sbi, block_group), bitmap_bh->b_data, + bit, count); + ext4_mb_free_metadata(handle, &e4b, new_entry); + ext4_unlock_group(sb, block_group); } else { ext4_lock_group(sb, block_group); + /* need to update group_info->bb_free and bitmap + * with group lock held. generate_buddy look at + * them with group lock_held + */ + mb_clear_bits(sb_bgl_lock(sbi, block_group), bitmap_bh->b_data, + bit, count); mb_free_blocks(inode, &e4b, bit, count); ext4_mb_return_to_preallocation(inode, &e4b, block, count); ext4_unlock_group(sb, block_group); @@ -4635,6 +4885,10 @@ *freed += count; + /* We dirtied the bitmap block */ + BUFFER_TRACE(bitmap_bh, "dirtied bitmap block"); + err = ext4_journal_dirty_metadata(handle, bitmap_bh); + /* And the group descriptor block */ BUFFER_TRACE(gd_bh, "dirtied group descriptor block"); ret = ext4_journal_dirty_metadata(handle, gd_bh); --- linux-2.6.28.orig/fs/ext4/inode.c +++ linux-2.6.28/fs/ext4/inode.c @@ -46,8 +46,10 @@ 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); + return jbd2_journal_begin_ordered_truncate( + EXT4_SB(inode->i_sb)->s_journal, + &EXT4_I(inode)->jinode, + new_size); } static void ext4_invalidatepage(struct page *page, unsigned long offset); @@ -351,9 +353,9 @@ final = ptrs; } else { ext4_warning(inode->i_sb, "ext4_block_to_path", - "block %lu > max", + "block %lu > max in inode %lu", i_block + direct_blocks + - indirect_blocks + double_blocks); + indirect_blocks + double_blocks, inode->i_ino); } if (boundary) *boundary = final - 1 - (i_block & (ptrs - 1)); @@ -1345,7 +1347,11 @@ goto out; } - page = __grab_cache_page(mapping, index); + /* We cannot recurse into the filesystem as the transaction is already + * started */ + flags |= AOP_FLAG_NOFS; + + page = grab_cache_page_write_begin(mapping, index, flags); if (!page) { ext4_journal_stop(handle); ret = -ENOMEM; @@ -1354,7 +1360,7 @@ *pagep = page; ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata, - ext4_get_block); + ext4_get_block); if (!ret && ext4_should_journal_data(inode)) { ret = walk_page_buffers(handle, page_buffers(page), @@ -1644,35 +1650,39 @@ */ static int mpage_da_submit_io(struct mpage_da_data *mpd) { - struct address_space *mapping = mpd->inode->i_mapping; - int ret = 0, err, nr_pages, i; - unsigned long index, end; - struct pagevec pvec; long pages_skipped; + struct pagevec pvec; + unsigned long index, end; + int ret = 0, err, nr_pages, i; + struct inode *inode = mpd->inode; + struct address_space *mapping = inode->i_mapping; BUG_ON(mpd->next_page <= mpd->first_page); - pagevec_init(&pvec, 0); + /* + * We need to start from the first_page to the next_page - 1 + * to make sure we also write the mapped dirty buffer_heads. + * If we look at mpd->lbh.b_blocknr we would only be looking + * at the currently mapped buffer_heads. + */ index = mpd->first_page; end = mpd->next_page - 1; + pagevec_init(&pvec, 0); while (index <= end) { - /* - * We can use PAGECACHE_TAG_DIRTY lookup here because - * even though we have cleared the dirty flag on the page - * We still keep the page in the radix tree with tag - * PAGECACHE_TAG_DIRTY. See clear_page_dirty_for_io. - * The PAGECACHE_TAG_DIRTY is cleared in set_page_writeback - * which is called via the below writepage callback. - */ - nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, - PAGECACHE_TAG_DIRTY, - min(end - index, - (pgoff_t)PAGEVEC_SIZE-1) + 1); + 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)); + pages_skipped = mpd->wbc->pages_skipped; err = mapping->a_ops->writepage(page, mpd->wbc); if (!err && (pages_skipped == mpd->wbc->pages_skipped)) @@ -2086,11 +2096,29 @@ bh = head; do { BUG_ON(buffer_locked(bh)); + /* + * We need to try to allocate + * unmapped blocks in the same page. + * Otherwise we won't make progress + * with the page in ext4_da_writepage + */ if (buffer_dirty(bh) && (!buffer_mapped(bh) || buffer_delay(bh))) { mpage_add_bh_to_extent(mpd, logical, bh); if (mpd->io_done) return MPAGE_DA_EXTENT_TAIL; + } else if (buffer_dirty(bh) && (buffer_mapped(bh))) { + /* + * mapped dirty buffer. We need to update + * the b_state because we look at + * b_state in mpage_da_map_blocks. We don't + * update b_size because if we find an + * unmapped buffer_head later we need to + * use the b_state flag of that buffer_head. + */ + if (mpd->lbh.b_size == 0) + mpd->lbh.b_state = + bh->b_state & BH_FLAGS; } logical++; } while ((bh = bh->b_this_page) != head); @@ -2378,6 +2406,7 @@ struct inode *inode = mapping->host; int no_nrwrite_index_update; long pages_written = 0, pages_skipped; + int range_cyclic, cycled = 1, io_done = 0; int needed_blocks, ret = 0, nr_to_writebump = 0; struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb); @@ -2388,6 +2417,20 @@ */ if (!mapping->nrpages || !mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) return 0; + + /* + * If the filesystem has aborted, it is read-only, so return + * right away instead of dumping stack traces later on that + * will obscure the real source of the problem. We test + * EXT4_MOUNT_ABORT instead of sb->s_flag's MS_RDONLY because + * the latter could be true if the filesystem is mounted + * read-only, and in that case, ext4_da_writepages should + * *never* be called, so if that ever happens, we would want + * the stack trace. + */ + if (unlikely(sbi->s_mount_opt & EXT4_MOUNT_ABORT)) + return -EROFS; + /* * Make sure nr_to_write is >= sbi->s_mb_stream_request * This make sure small files blocks are allocated in @@ -2401,9 +2444,15 @@ if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) range_whole = 1; - if (wbc->range_cyclic) + range_cyclic = wbc->range_cyclic; + if (wbc->range_cyclic) { index = mapping->writeback_index; - else + if (index) + cycled = 0; + wbc->range_start = index << PAGE_CACHE_SHIFT; + wbc->range_end = LLONG_MAX; + wbc->range_cyclic = 0; + } else index = wbc->range_start >> PAGE_CACHE_SHIFT; mpd.wbc = wbc; @@ -2417,6 +2466,7 @@ wbc->no_nrwrite_index_update = 1; pages_skipped = wbc->pages_skipped; +retry: while (!ret && wbc->nr_to_write > 0) { /* @@ -2432,7 +2482,7 @@ handle = ext4_journal_start(inode, needed_blocks); if (IS_ERR(handle)) { ret = PTR_ERR(handle); - printk(KERN_EMERG "%s: jbd2_start: " + printk(KERN_CRIT "%s: jbd2_start: " "%ld pages, ino %lu; err %d\n", __func__, wbc->nr_to_write, inode->i_ino, ret); dump_stack(); @@ -2459,6 +2509,7 @@ pages_written += mpd.pages_written; wbc->pages_skipped = pages_skipped; ret = 0; + io_done = 1; } else if (wbc->nr_to_write) /* * There is no more writeout needed @@ -2467,6 +2518,13 @@ */ break; } + if (!io_done && !cycled) { + cycled = 1; + index = 0; + wbc->range_start = index << PAGE_CACHE_SHIFT; + wbc->range_end = mapping->writeback_index - 1; + goto retry; + } if (pages_skipped != wbc->pages_skipped) printk(KERN_EMERG "This should not happen leaving %s " "with nr_to_write = %ld ret = %d\n", @@ -2474,6 +2532,7 @@ /* Update index */ index += pages_written; + wbc->range_cyclic = range_cyclic; if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) /* * set the writeback_index so that range_cyclic @@ -2548,8 +2607,11 @@ ret = PTR_ERR(handle); goto out; } + /* We cannot recurse into the filesystem as the transaction is already + * started */ + flags |= AOP_FLAG_NOFS; - page = __grab_cache_page(mapping, index); + page = grab_cache_page_write_begin(mapping, index, flags); if (!page) { ext4_journal_stop(handle); ret = -ENOMEM; @@ -2686,6 +2748,48 @@ return; } +/* + * Force all delayed allocation blocks to be allocated for a given inode. + */ +int ext4_alloc_da_blocks(struct inode *inode) +{ + if (!EXT4_I(inode)->i_reserved_data_blocks && + !EXT4_I(inode)->i_reserved_meta_blocks) + return 0; + + /* + * We do something simple for now. The filemap_flush() will + * also start triggering a write of the data blocks, which is + * not strictly speaking necessary (and for users of + * laptop_mode, not even desirable). However, to do otherwise + * would require replicating code paths in: + * + * ext4_da_writepages() -> + * write_cache_pages() ---> (via passed in callback function) + * __mpage_da_writepage() --> + * mpage_add_bh_to_extent() + * mpage_da_map_blocks() + * + * The problem is that write_cache_pages(), located in + * mm/page-writeback.c, marks pages clean in preparation for + * doing I/O, which is not desirable if we're not planning on + * doing I/O at all. + * + * We could call write_cache_pages(), and then redirty all of + * the pages by calling redirty_page_for_writeback() but that + * would be ugly in the extreme. So instead we would need to + * replicate parts of the code in the above functions, + * simplifying them becuase we wouldn't actually intend to + * write out the pages, but rather only collect contiguous + * logical block extents, call the multi-block allocator, and + * then update the buffer heads with the block allocations. + * + * For now, though, we'll cheat by calling filemap_flush(), + * which will map the blocks, and start the I/O, but not + * actually wait for the I/O to complete. + */ + return filemap_flush(inode->i_mapping); +} /* * bmap() is special. It gets used by applications such as lilo and by @@ -3695,6 +3799,9 @@ if (!ext4_can_truncate(inode)) return; + if (inode->i_size == 0) + ei->i_state |= EXT4_STATE_DA_ALLOC_CLOSE; + if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) { ext4_ext_truncate(inode); return; --- linux-2.6.28.orig/fs/ext4/ioctl.c +++ linux-2.6.28/fs/ext4/ioctl.c @@ -263,6 +263,20 @@ return err; } + case EXT4_IOC_ALLOC_DA_BLKS: + { + int err; + if (!is_owner_or_cap(inode)) + return -EACCES; + + err = mnt_want_write(filp->f_path.mnt); + if (err) + return err; + err = ext4_alloc_da_blocks(inode); + mnt_drop_write(filp->f_path.mnt); + return err; + } + default: return -ENOTTY; } --- linux-2.6.28.orig/fs/ext4/balloc.c +++ linux-2.6.28/fs/ext4/balloc.c @@ -20,6 +20,7 @@ #include "ext4.h" #include "ext4_jbd2.h" #include "group.h" +#include "mballoc.h" /* * balloc.c contains the blocks allocation and deallocation routines @@ -319,20 +320,41 @@ block_group, bitmap_blk); return NULL; } - if (buffer_uptodate(bh) && - !(desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) + + if (bitmap_uptodate(bh)) return bh; lock_buffer(bh); + if (bitmap_uptodate(bh)) { + unlock_buffer(bh); + return bh; + } spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group)); if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { ext4_init_block_bitmap(sb, bh, block_group, desc); + set_bitmap_uptodate(bh); set_buffer_uptodate(bh); unlock_buffer(bh); spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group)); return bh; } spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group)); + if (buffer_uptodate(bh)) { + /* + * if not uninit if bh is uptodate, + * bitmap is also uptodate + */ + set_bitmap_uptodate(bh); + unlock_buffer(bh); + return bh; + } + /* + * submit the buffer_head for read. We can + * safely mark the bitmap as uptodate now. + * We do it here so the bitmap uptodate bit + * get set with buffer lock held. + */ + set_bitmap_uptodate(bh); if (bh_submit_read(bh) < 0) { put_bh(bh); ext4_error(sb, __func__, @@ -350,62 +372,44 @@ } /** - * ext4_free_blocks_sb() -- Free given blocks and update quota + * ext4_add_groupblocks() -- Add given blocks to an existing group * @handle: handle to this transaction * @sb: super block - * @block: start physcial block to free + * @block: start physcial block to add to the block group * @count: number of blocks to free - * @pdquot_freed_blocks: pointer to quota * - * XXX This function is only used by the on-line resizing code, which - * should probably be fixed up to call the mballoc variant. There - * this needs to be cleaned up later; in fact, I'm not convinced this - * is 100% correct in the face of the mballoc code. The online resizing - * code needs to be fixed up to more tightly (and correctly) interlock - * with the mballoc code. - */ -void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb, - ext4_fsblk_t block, unsigned long count, - unsigned long *pdquot_freed_blocks) + * This marks the blocks as free in the bitmap. We ask the + * mballoc to reload the buddy after this by setting group + * EXT4_GROUP_INFO_NEED_INIT_BIT flag + */ +void ext4_add_groupblocks(handle_t *handle, struct super_block *sb, + ext4_fsblk_t block, unsigned long count) { struct buffer_head *bitmap_bh = NULL; struct buffer_head *gd_bh; ext4_group_t block_group; ext4_grpblk_t bit; unsigned long i; - unsigned long overflow; struct ext4_group_desc *desc; struct ext4_super_block *es; struct ext4_sb_info *sbi; int err = 0, ret; - ext4_grpblk_t group_freed; + ext4_grpblk_t blocks_freed; + struct ext4_group_info *grp; - *pdquot_freed_blocks = 0; sbi = EXT4_SB(sb); es = sbi->s_es; - if (block < le32_to_cpu(es->s_first_data_block) || - block + count < block || - block + count > ext4_blocks_count(es)) { - ext4_error(sb, "ext4_free_blocks", - "Freeing blocks not in datazone - " - "block = %llu, count = %lu", block, count); - goto error_return; - } - - ext4_debug("freeing block(s) %llu-%llu\n", block, block + count - 1); + ext4_debug("Adding block(s) %llu-%llu\n", block, block + count - 1); -do_more: - overflow = 0; ext4_get_group_no_and_offset(sb, block, &block_group, &bit); + grp = ext4_get_group_info(sb, block_group); /* * Check to see if we are freeing blocks across a group * boundary. */ if (bit + count > EXT4_BLOCKS_PER_GROUP(sb)) { - overflow = bit + count - EXT4_BLOCKS_PER_GROUP(sb); - count -= overflow; + goto error_return; } - brelse(bitmap_bh); bitmap_bh = ext4_read_block_bitmap(sb, block_group); if (!bitmap_bh) goto error_return; @@ -418,18 +422,17 @@ in_range(block, ext4_inode_table(sb, desc), sbi->s_itb_per_group) || in_range(block + count - 1, ext4_inode_table(sb, desc), sbi->s_itb_per_group)) { - ext4_error(sb, "ext4_free_blocks", - "Freeing blocks in system zones - " + ext4_error(sb, __func__, + "Adding blocks in system zones - " "Block = %llu, count = %lu", block, count); goto error_return; } /* - * We are about to start releasing blocks in the bitmap, + * We are about to add blocks to the bitmap, * so we need undo access. */ - /* @@@ check errors */ BUFFER_TRACE(bitmap_bh, "getting undo access"); err = ext4_journal_get_undo_access(handle, bitmap_bh); if (err) @@ -444,90 +447,42 @@ err = ext4_journal_get_write_access(handle, gd_bh); if (err) goto error_return; - - jbd_lock_bh_state(bitmap_bh); - - for (i = 0, group_freed = 0; i < count; i++) { - /* - * An HJ special. This is expensive... - */ -#ifdef CONFIG_JBD2_DEBUG - jbd_unlock_bh_state(bitmap_bh); - { - struct buffer_head *debug_bh; - debug_bh = sb_find_get_block(sb, block + i); - if (debug_bh) { - BUFFER_TRACE(debug_bh, "Deleted!"); - if (!bh2jh(bitmap_bh)->b_committed_data) - BUFFER_TRACE(debug_bh, - "No commited data in bitmap"); - BUFFER_TRACE2(debug_bh, bitmap_bh, "bitmap"); - __brelse(debug_bh); - } - } - jbd_lock_bh_state(bitmap_bh); -#endif - if (need_resched()) { - jbd_unlock_bh_state(bitmap_bh); - cond_resched(); - jbd_lock_bh_state(bitmap_bh); - } - /* @@@ This prevents newly-allocated data from being - * freed and then reallocated within the same - * transaction. - * - * Ideally we would want to allow that to happen, but to - * do so requires making jbd2_journal_forget() capable of - * revoking the queued write of a data block, which - * implies blocking on the journal lock. *forget() - * cannot block due to truncate races. - * - * Eventually we can fix this by making jbd2_journal_forget() - * return a status indicating whether or not it was able - * to revoke the buffer. On successful revoke, it is - * safe not to set the allocation bit in the committed - * bitmap, because we know that there is no outstanding - * activity on the buffer any more and so it is safe to - * reallocate it. - */ - BUFFER_TRACE(bitmap_bh, "set in b_committed_data"); - J_ASSERT_BH(bitmap_bh, - bh2jh(bitmap_bh)->b_committed_data != NULL); - ext4_set_bit_atomic(sb_bgl_lock(sbi, block_group), bit + i, - bh2jh(bitmap_bh)->b_committed_data); - - /* - * We clear the bit in the bitmap after setting the committed - * data bit, because this is the reverse order to that which - * the allocator uses. - */ + /* + * make sure we don't allow a parallel init on other groups in the + * same buddy cache + */ + down_write(&grp->alloc_sem); + for (i = 0, blocks_freed = 0; i < count; i++) { BUFFER_TRACE(bitmap_bh, "clear bit"); if (!ext4_clear_bit_atomic(sb_bgl_lock(sbi, block_group), bit + i, bitmap_bh->b_data)) { - jbd_unlock_bh_state(bitmap_bh); ext4_error(sb, __func__, "bit already cleared for block %llu", (ext4_fsblk_t)(block + i)); - jbd_lock_bh_state(bitmap_bh); BUFFER_TRACE(bitmap_bh, "bit already cleared"); } else { - group_freed++; + blocks_freed++; } } - jbd_unlock_bh_state(bitmap_bh); - spin_lock(sb_bgl_lock(sbi, block_group)); - le16_add_cpu(&desc->bg_free_blocks_count, group_freed); + le16_add_cpu(&desc->bg_free_blocks_count, blocks_freed); desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc); spin_unlock(sb_bgl_lock(sbi, block_group)); - percpu_counter_add(&sbi->s_freeblocks_counter, count); + percpu_counter_add(&sbi->s_freeblocks_counter, blocks_freed); 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; + sbi->s_flex_groups[flex_group].free_blocks += blocks_freed; spin_unlock(sb_bgl_lock(sbi, flex_group)); } + /* + * request to reload the buddy with the + * new bitmap information + */ + set_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &(grp->bb_state)); + ext4_mb_update_group_info(grp, blocks_freed); + up_write(&grp->alloc_sem); /* We dirtied the bitmap block */ BUFFER_TRACE(bitmap_bh, "dirtied bitmap block"); @@ -536,15 +491,10 @@ /* And the group descriptor block */ BUFFER_TRACE(gd_bh, "dirtied group descriptor block"); ret = ext4_journal_dirty_metadata(handle, gd_bh); - if (!err) err = ret; - *pdquot_freed_blocks += group_freed; - - if (overflow && !err) { - block += count; - count = overflow; - goto do_more; - } + if (!err) + err = ret; sb->s_dirt = 1; + error_return: brelse(bitmap_bh); ext4_std_error(sb, err); --- linux-2.6.28.orig/fs/ext4/super.c +++ linux-2.6.28/fs/ext4/super.c @@ -1445,7 +1445,6 @@ 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) { @@ -1468,9 +1467,6 @@ goto failed; } - 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); @@ -1873,8 +1869,8 @@ char *cp; int ret = -EINVAL; int blocksize; - int db_count; - int i; + unsigned int db_count; + unsigned int i; int needs_recovery, has_huge_files; __le32 features; __u64 blocks_count; @@ -2118,6 +2114,18 @@ for (i = 0; i < 4; i++) sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]); sbi->s_def_hash_version = es->s_def_hash_version; + i = le32_to_cpu(es->s_flags); + if (i & EXT2_FLAGS_UNSIGNED_HASH) + sbi->s_hash_unsigned = 3; + else if ((i & EXT2_FLAGS_SIGNED_HASH) == 0) { +#ifdef __CHAR_UNSIGNED__ + es->s_flags |= cpu_to_le32(EXT2_FLAGS_UNSIGNED_HASH); + sbi->s_hash_unsigned = 3; +#else + es->s_flags |= cpu_to_le32(EXT2_FLAGS_SIGNED_HASH); +#endif + sb->s_dirt = 1; + } if (sbi->s_blocks_per_group > blocksize * 8) { printk(KERN_ERR @@ -2145,20 +2153,30 @@ if (EXT4_BLOCKS_PER_GROUP(sb) == 0) goto cantfind_ext4; - /* ensure blocks_count calculation below doesn't sign-extend */ - if (ext4_blocks_count(es) + EXT4_BLOCKS_PER_GROUP(sb) < - le32_to_cpu(es->s_first_data_block) + 1) { - printk(KERN_WARNING "EXT4-fs: bad geometry: block count %llu, " - "first data block %u, blocks per group %lu\n", - ext4_blocks_count(es), - le32_to_cpu(es->s_first_data_block), - EXT4_BLOCKS_PER_GROUP(sb)); + /* + * It makes no sense for the first data block to be beyond the end + * of the filesystem. + */ + if (le32_to_cpu(es->s_first_data_block) >= ext4_blocks_count(es)) { + printk(KERN_WARNING "EXT4-fs: bad geometry: first data" + "block %u is beyond end of filesystem (%llu)\n", + le32_to_cpu(es->s_first_data_block), + ext4_blocks_count(es)); goto failed_mount; } blocks_count = (ext4_blocks_count(es) - le32_to_cpu(es->s_first_data_block) + EXT4_BLOCKS_PER_GROUP(sb) - 1); do_div(blocks_count, EXT4_BLOCKS_PER_GROUP(sb)); + if (blocks_count > ((uint64_t)1<<32) - EXT4_DESC_PER_BLOCK(sb)) { + printk(KERN_WARNING "EXT4-fs: groups count too large: %u " + "(block count %llu, first data block %u, " + "blocks per group %lu)\n", sbi->s_groups_count, + ext4_blocks_count(es), + le32_to_cpu(es->s_first_data_block), + EXT4_BLOCKS_PER_GROUP(sb)); + goto failed_mount; + } sbi->s_groups_count = blocks_count; db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) / EXT4_DESC_PER_BLOCK(sb); @@ -2896,15 +2914,15 @@ static int ext4_sync_fs(struct super_block *sb, int wait) { - int ret = 0; + tid_t target; trace_mark(ext4_sync_fs, "dev %s wait %d", sb->s_id, wait); sb->s_dirt = 0; - if (wait) - ret = ext4_force_commit(sb); - else - jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, NULL); - return ret; + if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, &target)) { + if (wait) + jbd2_log_wait_commit(EXT4_SB(sb)->s_journal, target); + } + return 0; } /* --- linux-2.6.28.orig/fs/ext4/resize.c +++ linux-2.6.28/fs/ext4/resize.c @@ -284,11 +284,9 @@ if ((err = extend_or_restart_transaction(handle, 2, bh))) goto exit_bh; - mark_bitmap_end(input->blocks_count, EXT4_BLOCKS_PER_GROUP(sb), - bh->b_data); + mark_bitmap_end(input->blocks_count, sb->s_blocksize * 8, bh->b_data); ext4_journal_dirty_metadata(handle, bh); brelse(bh); - /* Mark unused entries in inode bitmap used */ ext4_debug("clear inode bitmap %#04llx (+%llu)\n", input->inode_bitmap, input->inode_bitmap - start); @@ -297,7 +295,7 @@ goto exit_journal; } - mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), EXT4_BLOCKS_PER_GROUP(sb), + mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), sb->s_blocksize * 8, bh->b_data); ext4_journal_dirty_metadata(handle, bh); exit_bh: @@ -747,6 +745,7 @@ struct inode *inode = NULL; handle_t *handle; int gdb_off, gdb_num; + int num_grp_locked = 0; int err, err2; gdb_num = input->group / EXT4_DESC_PER_BLOCK(sb); @@ -787,6 +786,7 @@ } } + if ((err = verify_group_input(sb, input))) goto exit_put; @@ -855,24 +855,29 @@ * using the new disk blocks. */ + num_grp_locked = ext4_mb_get_buddy_cache_lock(sb, input->group); /* Update group descriptor block for new group */ gdp = (struct ext4_group_desc *)((char *)primary->b_data + gdb_off * EXT4_DESC_SIZE(sb)); + memset(gdp, 0, EXT4_DESC_SIZE(sb)); ext4_block_bitmap_set(sb, gdp, input->block_bitmap); /* LV FIXME */ ext4_inode_bitmap_set(sb, gdp, input->inode_bitmap); /* LV FIXME */ ext4_inode_table_set(sb, gdp, input->inode_table); /* LV FIXME */ gdp->bg_free_blocks_count = cpu_to_le16(input->free_blocks_count); gdp->bg_free_inodes_count = cpu_to_le16(EXT4_INODES_PER_GROUP(sb)); + gdp->bg_flags = cpu_to_le16(EXT4_BG_INODE_ZEROED); gdp->bg_checksum = ext4_group_desc_csum(sbi, input->group, gdp); /* * We can allocate memory for mb_alloc based on the new group * descriptor */ - err = ext4_mb_add_more_groupinfo(sb, input->group, gdp); - if (err) + err = ext4_mb_add_groupinfo(sb, input->group, gdp); + if (err) { + ext4_mb_put_buddy_cache_lock(sb, input->group, num_grp_locked); goto exit_journal; + } /* * Make the new blocks and inodes valid next. We do this before @@ -914,6 +919,7 @@ /* Update the global fs size fields */ sbi->s_groups_count++; + ext4_mb_put_buddy_cache_lock(sb, input->group, num_grp_locked); ext4_journal_dirty_metadata(handle, primary); @@ -975,9 +981,7 @@ struct buffer_head *bh; 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 @@ -1076,57 +1080,13 @@ unlock_super(sb); ext4_debug("freeing blocks %llu through %llu\n", o_blocks_count, o_blocks_count + add); - ext4_free_blocks_sb(handle, sb, o_blocks_count, add, &freed_blocks); + /* We add the blocks to the bitmap and set the group need init bit */ + ext4_add_groupblocks(handle, sb, o_blocks_count, add); ext4_debug("freed blocks %llu through %llu\n", o_blocks_count, 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. - * - * XXX Bad, Bad, BAD!!! We should not be overloading the - * Uptodate flag, particularly on thte bitmap bh, as way of - * hinting to ext4_mb_load_buddy() that it needs to be - * overloaded. A user could take a LVM snapshot, then do an - * on-line fsck, and clear the uptodate flag, and this would - * not be a bug in userspace, but a bug in the kernel. FIXME!!! - */ - { - 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)); --- linux-2.6.28.orig/fs/ext4/migrate.c +++ linux-2.6.28/fs/ext4/migrate.c @@ -480,7 +480,7 @@ + 1); if (IS_ERR(handle)) { retval = PTR_ERR(handle); - goto err_out; + return retval; } tmp_inode = ext4_new_inode(handle, inode->i_sb->s_root->d_inode, @@ -488,8 +488,7 @@ if (IS_ERR(tmp_inode)) { retval = -ENOMEM; ext4_journal_stop(handle); - tmp_inode = NULL; - goto err_out; + return retval; } i_size_write(tmp_inode, i_size_read(inode)); /* @@ -617,8 +616,7 @@ ext4_journal_stop(handle); - if (tmp_inode) - iput(tmp_inode); + iput(tmp_inode); return retval; } --- linux-2.6.28.orig/fs/ext4/ext4_sb.h +++ linux-2.6.28/fs/ext4/ext4_sb.h @@ -57,6 +57,7 @@ u32 s_next_generation; u32 s_hash_seed[4]; int s_def_hash_version; + int s_hash_unsigned; /* 3 if hash should be signed, 0 if not */ struct percpu_counter s_freeblocks_counter; struct percpu_counter s_freeinodes_counter; struct percpu_counter s_dirs_counter; @@ -101,7 +102,8 @@ spinlock_t s_reserve_lock; spinlock_t s_md_lock; tid_t s_last_transaction; - unsigned short *s_mb_offsets, *s_mb_maxs; + unsigned short *s_mb_offsets; + unsigned int *s_mb_maxs; /* tunables */ unsigned long s_stripe; --- linux-2.6.28.orig/fs/fat/file.c +++ linux-2.6.28/fs/fat/file.c @@ -93,7 +93,7 @@ * out the RO attribute for checking by the security * module, just because it maps to a file mode. */ - err = security_inode_setattr(filp->f_path.dentry, &ia); + err = security_inode_setattr(filp->f_path.dentry, filp->f_path.mnt, &ia); if (err) goto up; --- linux-2.6.28.orig/fs/hpfs/namei.c +++ linux-2.6.28/fs/hpfs/namei.c @@ -426,7 +426,7 @@ /*printk("HPFS: truncating file before delete.\n");*/ newattrs.ia_size = 0; newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; - err = notify_change(dentry, &newattrs); + err = notify_change(dentry, NULL, &newattrs); put_write_access(inode); if (!err) goto again; --- linux-2.6.28.orig/fs/nfs/file.c +++ linux-2.6.28/fs/nfs/file.c @@ -354,7 +354,7 @@ file->f_path.dentry->d_name.name, mapping->host->i_ino, len, (long long) pos); - page = __grab_cache_page(mapping, index); + page = grab_cache_page_write_begin(mapping, index, flags); if (!page) return -ENOMEM; *pagep = page; --- linux-2.6.28.orig/fs/nfs/read.c +++ linux-2.6.28/fs/nfs/read.c @@ -533,12 +533,6 @@ unsigned int len; int error; - error = nfs_wb_page(inode, page); - if (error) - goto out_unlock; - if (PageUptodate(page)) - goto out_unlock; - len = nfs_page_length(page); if (len == 0) return nfs_return_empty_page(page); --- linux-2.6.28.orig/fs/nfs/dir.c +++ linux-2.6.28/fs/nfs/dir.c @@ -1621,8 +1621,7 @@ } else if (atomic_read(&new_dentry->d_count) > 1) /* dentry still busy? */ goto out; - } else - nfs_drop_nlink(new_inode); + } go_ahead: /* @@ -1635,10 +1634,8 @@ } nfs_inode_return_delegation(old_inode); - if (new_inode != NULL) { + if (new_inode != NULL) nfs_inode_return_delegation(new_inode); - d_delete(new_dentry); - } error = NFS_PROTO(old_dir)->rename(old_dir, &old_dentry->d_name, new_dir, &new_dentry->d_name); @@ -1647,6 +1644,8 @@ if (rehash) d_rehash(rehash); if (!error) { + if (new_inode != NULL) + nfs_drop_nlink(new_inode); d_move(old_dentry, new_dentry); nfs_set_verifier(new_dentry, nfs_save_change_attribute(new_dir)); --- linux-2.6.28.orig/fs/sysfs/bin.c +++ linux-2.6.28/fs/sysfs/bin.c @@ -63,6 +63,9 @@ int count = min_t(size_t, bytes, PAGE_SIZE); char *temp; + if (!bytes) + return 0; + if (size) { if (offs > size) return 0; @@ -131,6 +134,9 @@ int count = min_t(size_t, bytes, PAGE_SIZE); char *temp; + if (!bytes) + return 0; + if (size) { if (offs > size) return 0; --- linux-2.6.28.orig/fs/xfs/xfs_dir2_leaf.c +++ linux-2.6.28/fs/xfs/xfs_dir2_leaf.c @@ -1092,7 +1092,7 @@ * Won't fit. Return to caller. */ if (filldir(dirent, dep->name, dep->namelen, - xfs_dir2_byte_to_dataptr(mp, curoff), + xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff, ino, DT_UNKNOWN)) break; @@ -1108,9 +1108,9 @@ * All done. Set output offset value to current offset. */ if (curoff > xfs_dir2_dataptr_to_byte(mp, XFS_DIR2_MAX_DATAPTR)) - *offset = XFS_DIR2_MAX_DATAPTR; + *offset = XFS_DIR2_MAX_DATAPTR & 0x7fffffff; else - *offset = xfs_dir2_byte_to_dataptr(mp, curoff); + *offset = xfs_dir2_byte_to_dataptr(mp, curoff) & 0x7fffffff; kmem_free(map); if (bp) xfs_da_brelse(NULL, bp); --- linux-2.6.28.orig/fs/xfs/xfs_dir2_sf.c +++ linux-2.6.28/fs/xfs/xfs_dir2_sf.c @@ -752,8 +752,8 @@ #if XFS_BIG_INUMS ino += mp->m_inoadd; #endif - if (filldir(dirent, ".", 1, dot_offset, ino, DT_DIR)) { - *offset = dot_offset; + if (filldir(dirent, ".", 1, dot_offset & 0x7fffffff, ino, DT_DIR)) { + *offset = dot_offset & 0x7fffffff; return 0; } } @@ -766,8 +766,8 @@ #if XFS_BIG_INUMS ino += mp->m_inoadd; #endif - if (filldir(dirent, "..", 2, dotdot_offset, ino, DT_DIR)) { - *offset = dotdot_offset; + if (filldir(dirent, "..", 2, dotdot_offset & 0x7fffffff, ino, DT_DIR)) { + *offset = dotdot_offset & 0x7fffffff; return 0; } } @@ -791,14 +791,15 @@ #endif if (filldir(dirent, sfep->name, sfep->namelen, - off, ino, DT_UNKNOWN)) { - *offset = off; + off & 0x7fffffff, ino, DT_UNKNOWN)) { + *offset = off & 0x7fffffff; return 0; } sfep = xfs_dir2_sf_nextentry(sfp, sfep); } - *offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0); + *offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) & + 0x7fffffff; return 0; } --- linux-2.6.28.orig/fs/xfs/xfs_dir2_block.c +++ linux-2.6.28/fs/xfs/xfs_dir2_block.c @@ -517,9 +517,9 @@ /* * If it didn't fit, set the final offset to here & return. */ - if (filldir(dirent, dep->name, dep->namelen, cook, + if (filldir(dirent, dep->name, dep->namelen, cook & 0x7fffffff, ino, DT_UNKNOWN)) { - *offset = cook; + *offset = cook & 0x7fffffff; xfs_da_brelse(NULL, bp); return 0; } @@ -529,7 +529,8 @@ * Reached the end of the block. * Set the offset to a non-existent block 1 and return. */ - *offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0); + *offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) & + 0x7fffffff; xfs_da_brelse(NULL, bp); return 0; } --- linux-2.6.28.orig/fs/xfs/linux-2.6/xfs_buf.c +++ linux-2.6.28/fs/xfs/linux-2.6/xfs_buf.c @@ -1114,8 +1114,7 @@ unsigned int blocksize = bp->b_target->bt_bsize; struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; - if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) - bp->b_error = EIO; + xfs_buf_ioerror(bp, -error); do { struct page *page = bvec->bv_page; --- linux-2.6.28.orig/fs/dlm/plock.c +++ linux-2.6.28/fs/dlm/plock.c @@ -304,7 +304,9 @@ if (rv == -ENOENT) rv = 0; else if (rv > 0) { + locks_init_lock(fl); fl->fl_type = (op->info.ex) ? F_WRLCK : F_RDLCK; + fl->fl_flags = FL_POSIX; fl->fl_pid = op->info.pid; fl->fl_start = op->info.start; fl->fl_end = op->info.end; --- linux-2.6.28.orig/fs/ocfs2/journal.h +++ linux-2.6.28/fs/ocfs2/journal.h @@ -445,8 +445,10 @@ static inline int ocfs2_begin_ordered_truncate(struct inode *inode, loff_t new_size) { - return jbd2_journal_begin_ordered_truncate(&OCFS2_I(inode)->ip_jinode, - new_size); + return jbd2_journal_begin_ordered_truncate( + OCFS2_SB(inode->i_sb)->journal->j_journal, + &OCFS2_I(inode)->ip_jinode, + new_size); } #endif /* OCFS2_JOURNAL_H */ --- linux-2.6.28.orig/fs/fuse/file.c +++ linux-2.6.28/fs/fuse/file.c @@ -54,7 +54,7 @@ ff->reserved_req = fuse_request_alloc(); if (!ff->reserved_req) { kfree(ff); - ff = NULL; + return NULL; } else { INIT_LIST_HEAD(&ff->write_entry); atomic_set(&ff->count, 0); @@ -646,7 +646,7 @@ { pgoff_t index = pos >> PAGE_CACHE_SHIFT; - *pagep = __grab_cache_page(mapping, index); + *pagep = grab_cache_page_write_begin(mapping, index, flags); if (!*pagep) return -ENOMEM; return 0; @@ -779,7 +779,7 @@ break; err = -ENOMEM; - page = __grab_cache_page(mapping, index); + page = grab_cache_page_write_begin(mapping, index, 0); if (!page) break; @@ -1470,6 +1470,11 @@ return retval; } +static int fuse_fsetattr(struct file *file, struct iattr *attr) +{ + return fuse_do_setattr(file->f_path.dentry, attr, file); +} + static const struct file_operations fuse_file_operations = { .llseek = fuse_file_llseek, .read = do_sync_read, @@ -1483,6 +1488,7 @@ .fsync = fuse_fsync, .lock = fuse_file_lock, .flock = fuse_file_flock, + .fsetattr = fuse_fsetattr, .splice_read = generic_file_splice_read, }; @@ -1496,6 +1502,7 @@ .fsync = fuse_fsync, .lock = fuse_file_lock, .flock = fuse_file_flock, + .fsetattr = fuse_fsetattr, /* no mmap and splice_read */ }; --- linux-2.6.28.orig/fs/fuse/inode.c +++ linux-2.6.28/fs/fuse/inode.c @@ -292,6 +292,7 @@ list_del(&fc->entry); fuse_ctl_remove_conn(fc); mutex_unlock(&fuse_mutex); + bdi_destroy(&fc->bdi); fuse_conn_put(fc); } @@ -531,7 +532,6 @@ if (fc->destroy_req) fuse_request_free(fc->destroy_req); mutex_destroy(&fc->inst_mutex); - bdi_destroy(&fc->bdi); kfree(fc); } } @@ -825,12 +825,16 @@ if (!file) return -EINVAL; - if (file->f_op != &fuse_dev_operations) + if (file->f_op != &fuse_dev_operations) { + fput(file); return -EINVAL; + } fc = new_conn(sb); - if (!fc) + if (!fc) { + fput(file); return -ENOMEM; + } fc->flags = d.flags; fc->user_id = d.user_id; --- linux-2.6.28.orig/fs/fuse/fuse_i.h +++ linux-2.6.28/fs/fuse/fuse_i.h @@ -554,6 +554,10 @@ */ int fuse_dev_init(void); + +int fuse_do_setattr(struct dentry *entry, struct iattr *attr, + struct file *file); + /** * Cleanup the client device */ --- linux-2.6.28.orig/fs/fuse/dev.c +++ linux-2.6.28/fs/fuse/dev.c @@ -281,7 +281,8 @@ fc->blocked = 0; wake_up_all(&fc->blocked_waitq); } - if (fc->num_background == FUSE_CONGESTION_THRESHOLD) { + if (fc->num_background == FUSE_CONGESTION_THRESHOLD && + fc->connected) { clear_bdi_congested(&fc->bdi, READ); clear_bdi_congested(&fc->bdi, WRITE); } --- linux-2.6.28.orig/fs/fuse/dir.c +++ linux-2.6.28/fs/fuse/dir.c @@ -1105,21 +1105,22 @@ return file ? fuse_fsync_common(file, de, datasync, 1) : 0; } -static bool update_mtime(unsigned ivalid) +static bool update_mtime(unsigned ivalid, bool have_file) { /* Always update if mtime is explicitly set */ if (ivalid & ATTR_MTIME_SET) return true; /* If it's an open(O_TRUNC) or an ftruncate(), don't update */ - if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE))) + if ((ivalid & ATTR_SIZE) && ((ivalid & ATTR_OPEN) || have_file)) return false; /* In all other cases update */ return true; } -static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg) +static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg, + bool have_file) { unsigned ivalid = iattr->ia_valid; @@ -1138,7 +1139,7 @@ if (!(ivalid & ATTR_ATIME_SET)) arg->valid |= FATTR_ATIME_NOW; } - if ((ivalid & ATTR_MTIME) && update_mtime(ivalid)) { + if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, have_file)) { arg->valid |= FATTR_MTIME; arg->mtime = iattr->ia_mtime.tv_sec; arg->mtimensec = iattr->ia_mtime.tv_nsec; @@ -1199,8 +1200,8 @@ * vmtruncate() doesn't allow for this case, so do the rlimit checking * and the actual truncation by hand. */ -static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, - struct file *file) +int fuse_do_setattr(struct dentry *entry, struct iattr *attr, + struct file *file) { struct inode *inode = entry->d_inode; struct fuse_conn *fc = get_fuse_conn(inode); @@ -1244,7 +1245,7 @@ memset(&inarg, 0, sizeof(inarg)); memset(&outarg, 0, sizeof(outarg)); - iattr_to_fattr(attr, &inarg); + iattr_to_fattr(attr, &inarg, file != NULL); if (file) { struct fuse_file *ff = file->private_data; inarg.valid |= FATTR_FH; @@ -1314,10 +1315,7 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr) { - if (attr->ia_valid & ATTR_FILE) - return fuse_do_setattr(entry, attr, attr->ia_file); - else - return fuse_do_setattr(entry, attr, NULL); + return fuse_do_setattr(entry, attr, NULL); } static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, --- linux-2.6.28.orig/fs/ext2/super.c +++ linux-2.6.28/fs/ext2/super.c @@ -1177,9 +1177,12 @@ es = sbi->s_es; if (((sbi->s_mount_opt & EXT2_MOUNT_XIP) != (old_mount_opt & EXT2_MOUNT_XIP)) && - invalidate_inodes(sb)) - ext2_warning(sb, __func__, "busy inodes while remounting "\ - "xip remain in cache (no functional problem)"); + invalidate_inodes(sb)) { + ext2_warning(sb, __func__, "refusing change of xip flag " + "with busy inodes while remounting"); + sbi->s_mount_opt &= ~EXT2_MOUNT_XIP; + sbi->s_mount_opt |= old_mount_opt & EXT2_MOUNT_XIP; + } if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) return 0; if (*flags & MS_RDONLY) { --- linux-2.6.28.orig/fs/hostfs/hostfs_kern.c +++ linux-2.6.28/fs/hostfs/hostfs_kern.c @@ -501,7 +501,7 @@ { pgoff_t index = pos >> PAGE_CACHE_SHIFT; - *pagep = __grab_cache_page(mapping, index); + *pagep = grab_cache_page_write_begin(mapping, index, flags); if (!*pagep) return -ENOMEM; return 0; --- linux-2.6.28.orig/fs/gfs2/ops_address.c +++ linux-2.6.28/fs/gfs2/ops_address.c @@ -675,7 +675,7 @@ goto out_trans_fail; error = -ENOMEM; - page = __grab_cache_page(mapping, index); + page = grab_cache_page_write_begin(mapping, index, flags); *pagep = page; if (unlikely(!page)) goto out_endtrans; --- linux-2.6.28.orig/fs/nfsd/vfs.c +++ linux-2.6.28/fs/nfsd/vfs.c @@ -387,7 +387,7 @@ err = nfserr_notsync; if (!check_guard || guardtime == inode->i_ctime.tv_sec) { fh_lock(fhp); - host_err = notify_change(dentry, iap); + host_err = notify_change(dentry, fhp->fh_export->ex_path.mnt, iap); err = nfserrno(host_err); fh_unlock(fhp); } @@ -407,12 +407,13 @@ #if defined(CONFIG_NFSD_V2_ACL) || \ defined(CONFIG_NFSD_V3_ACL) || \ defined(CONFIG_NFSD_V4) -static ssize_t nfsd_getxattr(struct dentry *dentry, char *key, void **buf) +static ssize_t nfsd_getxattr(struct dentry *dentry, struct vfsmount *mnt, + char *key, void **buf) { ssize_t buflen; ssize_t ret; - buflen = vfs_getxattr(dentry, key, NULL, 0); + buflen = vfs_getxattr(dentry, mnt, key, NULL, 0, NULL); if (buflen <= 0) return buflen; @@ -420,7 +421,7 @@ if (!*buf) return -ENOMEM; - ret = vfs_getxattr(dentry, key, *buf, buflen); + ret = vfs_getxattr(dentry, mnt, key, *buf, buflen, NULL); if (ret < 0) kfree(*buf); return ret; @@ -429,7 +430,8 @@ #if defined(CONFIG_NFSD_V4) static int -set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key) +set_nfsv4_acl_one(struct dentry *dentry, struct vfsmount *mnt, + struct posix_acl *pacl, char *key) { int len; size_t buflen; @@ -448,7 +450,7 @@ goto out; } - error = vfs_setxattr(dentry, key, buf, len, 0); + error = vfs_setxattr(dentry, mnt, key, buf, len, 0, NULL); out: kfree(buf); return error; @@ -461,6 +463,7 @@ __be32 error; int host_error; struct dentry *dentry; + struct vfsmount *mnt; struct inode *inode; struct posix_acl *pacl = NULL, *dpacl = NULL; unsigned int flags = 0; @@ -471,6 +474,7 @@ return error; dentry = fhp->fh_dentry; + mnt = fhp->fh_export->ex_path.mnt; inode = dentry->d_inode; if (S_ISDIR(inode->i_mode)) flags = NFS4_ACL_DIR; @@ -481,12 +485,14 @@ } else if (host_error < 0) goto out_nfserr; - host_error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS); + host_error = set_nfsv4_acl_one(dentry, mnt, pacl, + POSIX_ACL_XATTR_ACCESS); if (host_error < 0) goto out_release; if (S_ISDIR(inode->i_mode)) - host_error = set_nfsv4_acl_one(dentry, dpacl, POSIX_ACL_XATTR_DEFAULT); + host_error = set_nfsv4_acl_one(dentry, mnt, dpacl, + POSIX_ACL_XATTR_DEFAULT); out_release: posix_acl_release(pacl); @@ -499,13 +505,13 @@ } static struct posix_acl * -_get_posix_acl(struct dentry *dentry, char *key) +_get_posix_acl(struct dentry *dentry, struct vfsmount *mnt, char *key) { void *buf = NULL; struct posix_acl *pacl = NULL; int buflen; - buflen = nfsd_getxattr(dentry, key, &buf); + buflen = nfsd_getxattr(dentry, mnt, key, &buf); if (!buflen) buflen = -ENODATA; if (buflen <= 0) @@ -517,14 +523,15 @@ } int -nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, struct nfs4_acl **acl) +nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, + struct vfsmount *mnt, struct nfs4_acl **acl) { struct inode *inode = dentry->d_inode; int error = 0; struct posix_acl *pacl = NULL, *dpacl = NULL; unsigned int flags = 0; - pacl = _get_posix_acl(dentry, POSIX_ACL_XATTR_ACCESS); + pacl = _get_posix_acl(dentry, mnt, POSIX_ACL_XATTR_ACCESS); if (IS_ERR(pacl) && PTR_ERR(pacl) == -ENODATA) pacl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); if (IS_ERR(pacl)) { @@ -534,7 +541,7 @@ } if (S_ISDIR(inode->i_mode)) { - dpacl = _get_posix_acl(dentry, POSIX_ACL_XATTR_DEFAULT); + dpacl = _get_posix_acl(dentry, mnt, POSIX_ACL_XATTR_DEFAULT); if (IS_ERR(dpacl) && PTR_ERR(dpacl) == -ENODATA) dpacl = NULL; else if (IS_ERR(dpacl)) { @@ -947,13 +954,13 @@ return err; } -static void kill_suid(struct dentry *dentry) +static void kill_suid(struct dentry *dentry, struct vfsmount *mnt) { struct iattr ia; ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; mutex_lock(&dentry->d_inode->i_mutex); - notify_change(dentry, &ia); + notify_change(dentry, mnt, &ia); mutex_unlock(&dentry->d_inode->i_mutex); } @@ -1012,7 +1019,7 @@ /* clear setuid/setgid flag after write */ if (host_err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID))) - kill_suid(dentry); + kill_suid(dentry, exp->ex_path.mnt); if (host_err >= 0 && stable) { static ino_t last_ino; @@ -1190,6 +1197,7 @@ int type, dev_t rdev, struct svc_fh *resfhp) { struct dentry *dentry, *dchild = NULL; + struct svc_export *exp; struct inode *dirp; __be32 err; __be32 err2; @@ -1207,6 +1215,7 @@ goto out; dentry = fhp->fh_dentry; + exp = fhp->fh_export; dirp = dentry->d_inode; err = nfserr_notdir; @@ -1223,7 +1232,7 @@ host_err = PTR_ERR(dchild); if (IS_ERR(dchild)) goto out_nfserr; - err = fh_compose(resfhp, fhp->fh_export, dchild, fhp); + err = fh_compose(resfhp, exp, dchild, fhp); if (err) goto out; } else { @@ -1273,13 +1282,14 @@ host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL); break; case S_IFDIR: - host_err = vfs_mkdir(dirp, dchild, iap->ia_mode); + host_err = vfs_mkdir(dirp, dchild, exp->ex_path.mnt, iap->ia_mode); break; case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK: - host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev); + host_err = vfs_mknod(dirp, dchild, exp->ex_path.mnt, + iap->ia_mode, rdev); break; } if (host_err < 0) { @@ -1287,7 +1297,7 @@ goto out_nfserr; } - if (EX_ISSYNC(fhp->fh_export)) { + if (EX_ISSYNC(exp)) { err = nfserrno(nfsd_sync_dir(dentry)); write_inode_now(dchild->d_inode, 1); } @@ -1517,6 +1527,7 @@ struct iattr *iap) { struct dentry *dentry, *dnew; + struct svc_export *exp; __be32 err, cerr; int host_err; @@ -1541,6 +1552,7 @@ if (host_err) goto out_nfserr; + exp = fhp->fh_export; if (unlikely(path[plen] != 0)) { char *path_alloced = kmalloc(plen+1, GFP_KERNEL); if (path_alloced == NULL) @@ -1548,14 +1560,16 @@ else { strncpy(path_alloced, path, plen); path_alloced[plen] = 0; - host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced); + host_err = vfs_symlink(dentry->d_inode, dnew, + exp->ex_path.mnt, path_alloced); kfree(path_alloced); } } else - host_err = vfs_symlink(dentry->d_inode, dnew, path); + host_err = vfs_symlink(dentry->d_inode, dnew, exp->ex_path.mnt, + path); if (!host_err) { - if (EX_ISSYNC(fhp->fh_export)) + if (EX_ISSYNC(exp)) host_err = nfsd_sync_dir(dentry); } err = nfserrno(host_err); @@ -1563,7 +1577,7 @@ mnt_drop_write(fhp->fh_export->ex_path.mnt); - cerr = fh_compose(resfhp, fhp->fh_export, dnew, fhp); + cerr = fh_compose(resfhp, exp, dnew, fhp); dput(dnew); if (err==0) err = cerr; out: @@ -1618,7 +1632,8 @@ err = nfserrno(host_err); goto out_dput; } - host_err = vfs_link(dold, dirp, dnew); + host_err = vfs_link(dold, tfhp->fh_export->ex_path.mnt, dirp, + dnew, ffhp->fh_export->ex_path.mnt); if (!host_err) { if (EX_ISSYNC(ffhp->fh_export)) { err = nfserrno(nfsd_sync_dir(ddir)); @@ -1719,7 +1734,8 @@ if (host_err) goto out_dput_new; - host_err = vfs_rename(fdir, odentry, tdir, ndentry); + host_err = vfs_rename(fdir, odentry, ffhp->fh_export->ex_path.mnt, + tdir, ndentry, tfhp->fh_export->ex_path.mnt); if (!host_err && EX_ISSYNC(tfhp->fh_export)) { host_err = nfsd_sync_dir(tdentry); if (!host_err) @@ -1757,6 +1773,7 @@ char *fname, int flen) { struct dentry *dentry, *rdentry; + struct svc_export *exp; struct inode *dirp; __be32 err; int host_err; @@ -1771,6 +1788,7 @@ fh_lock_nested(fhp, I_MUTEX_PARENT); dentry = fhp->fh_dentry; dirp = dentry->d_inode; + exp = fhp->fh_export; rdentry = lookup_one_len(fname, dentry, flen); host_err = PTR_ERR(rdentry); @@ -1792,21 +1810,21 @@ if (type != S_IFDIR) { /* It's UNLINK */ #ifdef MSNFS - if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) && + if ((exp->ex_flags & NFSEXP_MSNFS) && (atomic_read(&rdentry->d_count) > 1)) { host_err = -EPERM; } else #endif - host_err = vfs_unlink(dirp, rdentry); + host_err = vfs_unlink(dirp, rdentry, exp->ex_path.mnt); } else { /* It's RMDIR */ - host_err = vfs_rmdir(dirp, rdentry); + host_err = vfs_rmdir(dirp, rdentry, exp->ex_path.mnt); } dput(rdentry); if (host_err) goto out_drop; - if (EX_ISSYNC(fhp->fh_export)) + if (EX_ISSYNC(exp)) host_err = nfsd_sync_dir(dentry); out_drop: @@ -2143,7 +2161,8 @@ return ERR_PTR(-EOPNOTSUPP); } - size = nfsd_getxattr(fhp->fh_dentry, name, &value); + size = nfsd_getxattr(fhp->fh_dentry, fhp->fh_export->ex_path.mnt, name, + &value); if (size < 0) return ERR_PTR(size); @@ -2155,6 +2174,7 @@ int nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl) { + struct vfsmount *mnt; struct inode *inode = fhp->fh_dentry->d_inode; char *name; void *value = NULL; @@ -2187,21 +2207,24 @@ } else size = 0; - error = mnt_want_write(fhp->fh_export->ex_path.mnt); + mnt = fhp->fh_export->ex_path.mnt; + error = mnt_want_write(mnt); if (error) goto getout; if (size) - error = vfs_setxattr(fhp->fh_dentry, name, value, size, 0); + error = vfs_setxattr(fhp->fh_dentry, mnt, name, value, size, 0, + NULL); else { if (!S_ISDIR(inode->i_mode) && type == ACL_TYPE_DEFAULT) error = 0; else { - error = vfs_removexattr(fhp->fh_dentry, name); + error = vfs_removexattr(fhp->fh_dentry, mnt, name, + NULL); if (error == -ENODATA) error = 0; } } - mnt_drop_write(fhp->fh_export->ex_path.mnt); + mnt_drop_write(mnt); getout: kfree(value); --- linux-2.6.28.orig/fs/nfsd/nfs4state.c +++ linux-2.6.28/fs/nfsd/nfs4state.c @@ -2769,6 +2769,25 @@ } /* + * The NFSv4 spec allows a client to do a LOCKT without holding an OPEN, + * so we do a temporary open here just to get an open file to pass to + * vfs_test_lock. (Arguably perhaps test_lock should be done with an + * inode operation.) + */ +static int nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock) +{ + struct file *file; + int err; + + err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file); + if (err) + return err; + err = vfs_test_lock(file, lock); + nfsd_close(file); + return err; +} + +/* * LOCKT operation */ __be32 @@ -2776,7 +2795,6 @@ struct nfsd4_lockt *lockt) { struct inode *inode; - struct file file; struct file_lock file_lock; int error; __be32 status; @@ -2824,7 +2842,6 @@ file_lock.fl_owner = (fl_owner_t)lockt->lt_stateowner; file_lock.fl_pid = current->tgid; file_lock.fl_flags = FL_POSIX; - file_lock.fl_lmops = &nfsd_posix_mng_ops; file_lock.fl_start = lockt->lt_offset; if ((lockt->lt_length == ~(u64)0) || LOFF_OVERFLOW(lockt->lt_offset, lockt->lt_length)) @@ -2834,16 +2851,8 @@ nfs4_transform_lock_offset(&file_lock); - /* vfs_test_lock uses the struct file _only_ to resolve the inode. - * since LOCKT doesn't require an OPEN, and therefore a struct - * file may not exist, pass vfs_test_lock a struct file with - * only the dentry:inode set. - */ - memset(&file, 0, sizeof (struct file)); - file.f_path.dentry = cstate->current_fh.fh_dentry; - status = nfs_ok; - error = vfs_test_lock(&file, &file_lock); + error = nfsd_test_lock(rqstp, &cstate->current_fh, &file_lock); if (error) { status = nfserrno(error); goto out; --- linux-2.6.28.orig/fs/nfsd/nfs4recover.c +++ linux-2.6.28/fs/nfsd/nfs4recover.c @@ -158,7 +158,8 @@ status = mnt_want_write(rec_dir.mnt); if (status) goto out_put; - status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU); + status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, + rec_dir.mnt, S_IRWXU); mnt_drop_write(rec_dir.mnt); out_put: dput(dentry); @@ -263,7 +264,7 @@ return -EINVAL; } mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); - status = vfs_unlink(dir->d_inode, dentry); + status = vfs_unlink(dir->d_inode, dentry, rec_dir.mnt); mutex_unlock(&dir->d_inode->i_mutex); return status; } @@ -278,7 +279,7 @@ * a kernel from the future.... */ nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file); mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); - status = vfs_rmdir(dir->d_inode, dentry); + status = vfs_rmdir(dir->d_inode, dentry, rec_dir.mnt); mutex_unlock(&dir->d_inode->i_mutex); return status; } --- linux-2.6.28.orig/fs/nfsd/nfs4xdr.c +++ linux-2.6.28/fs/nfsd/nfs4xdr.c @@ -1458,7 +1458,7 @@ } if (bmval0 & (FATTR4_WORD0_ACL | FATTR4_WORD0_ACLSUPPORT | FATTR4_WORD0_SUPPORTED_ATTRS)) { - err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl); + err = nfsd4_get_nfs4_acl(rqstp, dentry, exp->ex_path.mnt, &acl); aclsupport = (err == 0); if (bmval0 & FATTR4_WORD0_ACL) { if (err == -EOPNOTSUPP) @@ -2598,6 +2598,7 @@ [OP_LOOKUPP] = (nfsd4_enc)nfsd4_encode_noop, [OP_NVERIFY] = (nfsd4_enc)nfsd4_encode_noop, [OP_OPEN] = (nfsd4_enc)nfsd4_encode_open, + [OP_OPENATTR] = (nfsd4_enc)nfsd4_encode_noop, [OP_OPEN_CONFIRM] = (nfsd4_enc)nfsd4_encode_open_confirm, [OP_OPEN_DOWNGRADE] = (nfsd4_enc)nfsd4_encode_open_downgrade, [OP_PUTFH] = (nfsd4_enc)nfsd4_encode_noop, --- linux-2.6.28.orig/init/initramfs.c +++ linux-2.6.28/init/initramfs.c @@ -7,6 +7,9 @@ #include #include #include +#ifdef ACPI_CONFIG +#include +#endif static __initdata char *message; static void __init error(char *x) @@ -124,6 +127,12 @@ static __initdata uid_t uid; static __initdata gid_t gid; static __initdata unsigned rdev; +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD +static __initdata char *file_looked_for; +static __initdata struct acpi_table_header *file_mem; +#else +const char *file_looked_for = NULL; +#endif static void __init parse_header(char *s) { @@ -158,6 +167,7 @@ SkipIt, GotName, CopyFile, + CopyFileMem, GotSymlink, Reset } state, next_state; @@ -295,6 +305,54 @@ static __initdata int wfd; +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD +static __init int is_file_looked_for(char *filename) +{ + char *tmp_collected = collected; + if (file_looked_for == NULL) + return 0; + if (!S_ISREG(mode)) + return 0; + /* remove the leading / */ + while (*tmp_collected == '/') + tmp_collected++; + return (strcmp(tmp_collected, file_looked_for) == 0); +} + +static int __init do_copy_mem(void) +{ + static void *file_current; /* current position in the memory */ + if (file_mem == NULL) { + if (body_len < 4) { /* check especially against empty files */ + error("file is less than 4 bytes"); + return 1; + } + file_mem = kmalloc(body_len, GFP_ATOMIC); + if (!file_mem) { + error("failed to allocate enough memory"); + return 1; + } + file_current = file_mem; + } + if (count >= body_len) { + memcpy(file_current, victim, body_len); + eat(body_len); + file_looked_for = NULL; /* don't find files with same name */ + state = SkipIt; + return 0; + } else { + memcpy(file_current, victim, count); + file_current += count; + body_len -= count; + eat(count); + return 1; + } +} +#else +static inline int is_file_looked_for(char *filename) {return 0;} +#define do_copy_mem NULL /* because it is used as a pointer */ +#endif + static int __init do_name(void) { state = SkipIt; @@ -303,6 +361,8 @@ free_hash(); return 0; } + if (is_file_looked_for(file_looked_for)) + state = CopyFileMem; if (dry_run) return 0; clean_path(collected, mode); @@ -375,6 +435,7 @@ [SkipIt] = do_skip, [GotName] = do_name, [CopyFile] = do_copy, + [CopyFileMem] = do_copy_mem, [GotSymlink] = do_symlink, [Reset] = do_reset, }; @@ -613,3 +674,31 @@ return 0; } rootfs_initcall(populate_rootfs); + +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD +struct __init acpi_table_header *acpi_find_dsdt_initrd(void) +{ + char *err, *ramfs_dsdt_name = "DSDT.aml"; + + printk(KERN_INFO "ACPI: Checking initramfs for custom DSDT\n"); + file_mem = NULL; + file_looked_for = ramfs_dsdt_name; + err = unpack_to_rootfs((char *)initrd_start, + initrd_end - initrd_start, 1); + file_looked_for = NULL; + + if (err) { + /* + * Even if reading the DSDT file was successful, + * we give up if the initramfs cannot be entirely read. + */ + kfree(file_mem); + printk(KERN_ERR "ACPI: Aborted because %s.\n", err); + return NULL; + } + if (file_mem) + printk(KERN_INFO "ACPI: Found DSDT in %s.\n", ramfs_dsdt_name); + + return file_mem; +} +#endif --- linux-2.6.28.orig/init/Kconfig +++ linux-2.6.28/init/Kconfig @@ -101,6 +101,15 @@ which is done within the script "scripts/setlocalversion".) +config VERSION_SIGNATURE + string "Arbitrary version signature" + help + This string will be created in a file, /proc/version_signature. It + is useful in determining arbitrary data about your kernel. For instance, + if you have several kernels of the same version, but need to keep track + of a revision of the same kernel, but not affect it's ability to load + compatible modules, this is the easiest way to do that. + config SWAP bool "Support for paging of anonymous memory (swap)" depends on MMU && BLOCK @@ -538,6 +547,9 @@ config SYSCTL bool +config ANON_INODES + bool + menuconfig EMBEDDED bool "Configure standard kernel features (for small systems)" help @@ -643,18 +655,6 @@ This option allows to disable the internal PC-Speaker support, saving some memory. -config COMPAT_BRK - bool "Disable heap randomization" - default y - help - Randomizing heap placement makes heap exploits harder, but it - also breaks ancient binaries (including anything libc5 based). - This option changes the bootup default to heap randomization - disabled, and can be overriden runtime by setting - /proc/sys/kernel/randomize_va_space to 2. - - On non-ancient distros (post-2000 ones) N is usually a safe choice. - config BASE_FULL default y bool "Enable full-sized data structures for core" if EMBEDDED @@ -672,9 +672,6 @@ support for "fast userspace mutexes". The resulting kernel may not run glibc-based applications correctly. -config ANON_INODES - bool - config EPOLL bool "Enable eventpoll support" if EMBEDDED default y @@ -760,6 +757,18 @@ SLUB sysfs support. /sys/slab will not exist and there will be no support for cache validation etc. +config COMPAT_BRK + bool "Disable heap randomization" + default y + help + Randomizing heap placement makes heap exploits harder, but it + also breaks ancient binaries (including anything libc5 based). + This option changes the bootup default to heap randomization + disabled, and can be overriden runtime by setting + /proc/sys/kernel/randomize_va_space to 2. + + On non-ancient distros (post-2000 ones) N is usually a safe choice. + choice prompt "Choose SLAB allocator" default SLUB --- linux-2.6.28.orig/init/version.c +++ linux-2.6.28/init/version.c @@ -39,7 +39,11 @@ /* FIXED STRINGS! Don't touch! */ const char linux_banner[] = "Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@" - LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n"; + LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION +#ifdef CONFIG_VERSION_SIGNATURE + " (" CONFIG_VERSION_SIGNATURE ")" +#endif + "\n"; const char linux_proc_banner[] = "%s version %s" --- linux-2.6.28.orig/init/do_mounts_rd.c +++ linux-2.6.28/init/do_mounts_rd.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -37,6 +38,7 @@ * numbers could not be found. * * We currently check for the following magic numbers: + * squashfs * minix * ext2 * romfs @@ -51,6 +53,7 @@ struct ext2_super_block *ext2sb; struct romfs_super_block *romfsb; struct cramfs_super *cramfsb; + struct squashfs_super_block *squashfsb; int nblocks = -1; unsigned char *buf; @@ -62,6 +65,7 @@ ext2sb = (struct ext2_super_block *) buf; romfsb = (struct romfs_super_block *) buf; cramfsb = (struct cramfs_super *) buf; + squashfsb = (struct squashfs_super_block *) buf; memset(buf, 0xe5, size); /* @@ -99,6 +103,18 @@ goto done; } + /* squashfs is at block zero too */ + if (squashfsb->s_magic == SQUASHFS_MAGIC) { + printk(KERN_NOTICE + "RAMDISK: squashfs filesystem found at block %d\n", + start_block); + if (squashfsb->s_major < 3) + nblocks = (squashfsb->bytes_used_2+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS; + else + nblocks = (squashfsb->bytes_used+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS; + goto done; + } + /* * Read block 1 to test for minix and ext2 superblock */ --- linux-2.6.28.orig/ipc/sem.c +++ linux-2.6.28/ipc/sem.c @@ -308,7 +308,7 @@ return 0; } -asmlinkage long sys_semget(key_t key, int nsems, int semflg) +SYSCALL_DEFINE3(semget, key_t, key, int, nsems, int, semflg) { struct ipc_namespace *ns; struct ipc_ops sem_ops; @@ -887,7 +887,7 @@ return err; } -asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg) +SYSCALL_DEFINE(semctl)(int semid, int semnum, int cmd, union semun arg) { int err = -EINVAL; int version; @@ -923,6 +923,13 @@ return -EINVAL; } } +#ifdef CONFIG_HAVE_SYSCALL_WRAPPERS +asmlinkage long SyS_semctl(int semid, int semnum, int cmd, union semun arg) +{ + return SYSC_semctl((int) semid, (int) semnum, (int) cmd, arg); +} +SYSCALL_ALIAS(sys_semctl, SyS_semctl); +#endif /* If the task doesn't already have a undo_list, then allocate one * here. We guarantee there is only one thread using this undo list, @@ -1048,8 +1055,8 @@ return un; } -asmlinkage long sys_semtimedop(int semid, struct sembuf __user *tsops, - unsigned nsops, const struct timespec __user *timeout) +SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, + unsigned, nsops, const struct timespec __user *, timeout) { int error = -EINVAL; struct sem_array *sma; @@ -1226,7 +1233,8 @@ return error; } -asmlinkage long sys_semop (int semid, struct sembuf __user *tsops, unsigned nsops) +SYSCALL_DEFINE3(semop, int, semid, struct sembuf __user *, tsops, + unsigned, nsops) { return sys_semtimedop(semid, tsops, nsops, NULL); } --- linux-2.6.28.orig/ipc/mqueue.c +++ linux-2.6.28/ipc/mqueue.c @@ -506,7 +506,8 @@ sig_i.si_errno = 0; sig_i.si_code = SI_MESGQ; sig_i.si_value = info->notify.sigev_value; - sig_i.si_pid = task_tgid_vnr(current); + sig_i.si_pid = task_tgid_nr_ns(current, + ns_of_pid(info->notify_owner)); sig_i.si_uid = current->uid; kill_pid_info(info->notify.sigev_signo, @@ -655,8 +656,8 @@ return dentry_open(dentry, mqueue_mnt, oflag); } -asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode, - struct mq_attr __user *u_attr) +SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode, + struct mq_attr __user *, u_attr) { struct dentry *dentry; struct file *filp; @@ -723,7 +724,7 @@ return fd; } -asmlinkage long sys_mq_unlink(const char __user *u_name) +SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name) { int err; char *name; @@ -753,7 +754,7 @@ err = mnt_want_write(mqueue_mnt); if (err) goto out_err; - err = vfs_unlink(dentry->d_parent->d_inode, dentry); + err = vfs_unlink(dentry->d_parent->d_inode, dentry, mqueue_mnt); mnt_drop_write(mqueue_mnt); out_err: dput(dentry); @@ -816,9 +817,9 @@ sender->state = STATE_READY; } -asmlinkage long sys_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr, - size_t msg_len, unsigned int msg_prio, - const struct timespec __user *u_abs_timeout) +SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr, + size_t, msg_len, unsigned int, msg_prio, + const struct timespec __user *, u_abs_timeout) { struct file *filp; struct inode *inode; @@ -904,9 +905,9 @@ return ret; } -asmlinkage ssize_t sys_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr, - size_t msg_len, unsigned int __user *u_msg_prio, - const struct timespec __user *u_abs_timeout) +SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr, + size_t, msg_len, unsigned int __user *, u_msg_prio, + const struct timespec __user *, u_abs_timeout) { long timeout; ssize_t ret; @@ -989,8 +990,8 @@ * and he isn't currently owner of notification, will be silently discarded. * It isn't explicitly defined in the POSIX. */ -asmlinkage long sys_mq_notify(mqd_t mqdes, - const struct sigevent __user *u_notification) +SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes, + const struct sigevent __user *, u_notification) { int ret; struct file *filp; @@ -1115,9 +1116,9 @@ return ret; } -asmlinkage long sys_mq_getsetattr(mqd_t mqdes, - const struct mq_attr __user *u_mqstat, - struct mq_attr __user *u_omqstat) +SYSCALL_DEFINE3(mq_getsetattr, mqd_t, mqdes, + const struct mq_attr __user *, u_mqstat, + struct mq_attr __user *, u_omqstat) { int ret; struct mq_attr mqstat, omqstat; --- linux-2.6.28.orig/ipc/shm.c +++ linux-2.6.28/ipc/shm.c @@ -440,7 +440,7 @@ return 0; } -asmlinkage long sys_shmget (key_t key, size_t size, int shmflg) +SYSCALL_DEFINE3(shmget, key_t, key, size_t, size, int, shmflg) { struct ipc_namespace *ns; struct ipc_ops shm_ops; @@ -565,11 +565,15 @@ struct hstate *h = hstate_file(shp->shm_file); *rss += pages_per_huge_page(h) * mapping->nrpages; } else { +#ifdef CONFIG_SHMEM struct shmem_inode_info *info = SHMEM_I(inode); spin_lock(&info->lock); *rss += inode->i_mapping->nrpages; *swp += info->swapped; spin_unlock(&info->lock); +#else + *rss += inode->i_mapping->nrpages; +#endif } total++; @@ -621,7 +625,7 @@ return err; } -asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf) +SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf) { struct shmid_kernel *shp; int err, version; @@ -945,7 +949,7 @@ goto out_nattch; } -asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg) +SYSCALL_DEFINE3(shmat, int, shmid, char __user *, shmaddr, int, shmflg) { unsigned long ret; long err; @@ -961,7 +965,7 @@ * detach and kill segment if marked destroyed. * The work is done in shm_close. */ -asmlinkage long sys_shmdt(char __user *shmaddr) +SYSCALL_DEFINE1(shmdt, char __user *, shmaddr) { struct mm_struct *mm = current->mm; struct vm_area_struct *vma, *next; --- linux-2.6.28.orig/ipc/msg.c +++ linux-2.6.28/ipc/msg.c @@ -309,7 +309,7 @@ return security_msg_queue_associate(msq, msgflg); } -asmlinkage long sys_msgget(key_t key, int msgflg) +SYSCALL_DEFINE2(msgget, key_t, key, int, msgflg) { struct ipc_namespace *ns; struct ipc_ops msg_ops; @@ -466,7 +466,7 @@ return err; } -asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf) +SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf) { struct msg_queue *msq; int err, version; @@ -723,8 +723,8 @@ return err; } -asmlinkage long -sys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz, int msgflg) +SYSCALL_DEFINE4(msgsnd, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz, + int, msgflg) { long mtype; @@ -904,8 +904,8 @@ return msgsz; } -asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz, - long msgtyp, int msgflg) +SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz, + long, msgtyp, int, msgflg) { long err, mtype; --- linux-2.6.28.orig/sound/isa/opl3sa2.c +++ linux-2.6.28/sound/isa/opl3sa2.c @@ -550,21 +550,27 @@ #ifdef CONFIG_PM static int snd_opl3sa2_suspend(struct snd_card *card, pm_message_t state) { - struct snd_opl3sa2 *chip = card->private_data; + if (card) { + struct snd_opl3sa2 *chip = card->private_data; - snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - chip->wss->suspend(chip->wss); - /* power down */ - snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D3); + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + chip->wss->suspend(chip->wss); + /* power down */ + snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D3); + } return 0; } static int snd_opl3sa2_resume(struct snd_card *card) { - struct snd_opl3sa2 *chip = card->private_data; + struct snd_opl3sa2 *chip; int i; + if (!card) + return 0; + + chip = card->private_data; /* power up */ snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D0); --- linux-2.6.28.orig/sound/soc/Kconfig +++ linux-2.6.28/sound/soc/Kconfig @@ -29,6 +29,7 @@ source "sound/soc/pxa/Kconfig" source "sound/soc/s3c24xx/Kconfig" source "sound/soc/sh/Kconfig" +source "sound/soc/imx/Kconfig" source "sound/soc/fsl/Kconfig" source "sound/soc/davinci/Kconfig" source "sound/soc/omap/Kconfig" --- linux-2.6.28.orig/sound/soc/Makefile +++ linux-2.6.28/sound/soc/Makefile @@ -1,5 +1,5 @@ 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) += codecs/ at32/ at91/ pxa/ s3c24xx/ sh/ fsl/ davinci/ imx/ obj-$(CONFIG_SND_SOC) += omap/ au1x/ blackfin/ --- linux-2.6.28.orig/sound/soc/codecs/sgtl5000.c +++ linux-2.6.28/sound/soc/codecs/sgtl5000.c @@ -0,0 +1,973 @@ +/* + * sgtl5000.c -- SGTL5000 ALSA SoC Audio driver + * + * Copyright 2008-2009 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sgtl5000.h" + +struct sgtl5000_priv { + int sysclk; + int master; + int fmt; + int rev; +}; + +static int sgtl5000_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level); + +static unsigned int sgtl5000_read(struct snd_soc_codec *codec, unsigned int reg) +{ + struct i2c_client *client = codec->control_data; + int i2c_ret; + u16 value; + u8 buf0[2], buf1[2]; + u16 addr = client->addr; + u16 flags = client->flags; + struct i2c_msg msg[2] = { + {addr, flags, 2, buf0}, + {addr, flags | I2C_M_RD, 2, buf1}, + }; + + buf0[0] = (reg & 0xff00) >> 8; + buf0[1] = reg & 0xff; + i2c_ret = i2c_transfer(client->adapter, msg, 2); + if (i2c_ret < 0) { + pr_err("%s: read reg error : reg=%x\n", __func__, reg); + return 0; + } + + value = buf1[0] << 8 | buf1[1]; + + pr_debug("r r:%02x,v:%04x\n", reg, value); + return value; +} + +static int sgtl5000_write(struct snd_soc_codec *codec, unsigned int reg, + unsigned int value) +{ + struct i2c_client *client = codec->control_data; + u16 addr = client->addr; + u16 flags = client->flags; + u8 buf[4]; + int i2c_ret; + struct i2c_msg msg = { addr, flags, 4, buf }; + + pr_debug("w r:%02x,v:%04x\n", reg, value); + buf[0] = (reg & 0xff00) >> 8; + buf[1] = reg & 0xff; + buf[2] = (value & 0xff00) >> 8; + buf[3] = value & 0xff; + + i2c_ret = i2c_transfer(client->adapter, &msg, 1); + if (i2c_ret < 0) { + pr_err("%s: write reg error : R%02d = 0x%04x\n", + __func__, reg, value); + return -EIO; + } + + return i2c_ret; +} + +#ifdef DEBUG +static int all_reg[] = { + SGTL5000_CHIP_ID, + SGTL5000_CHIP_DIG_POWER, + SGTL5000_CHIP_CLK_CTRL, + SGTL5000_CHIP_I2S_CTRL, + SGTL5000_CHIP_SSS_CTRL, + SGTL5000_CHIP_ADCDAC_CTRL, + SGTL5000_CHIP_DAC_VOL, + SGTL5000_CHIP_PAD_STRENGTH, + SGTL5000_CHIP_ANA_ADC_CTRL, + SGTL5000_CHIP_ANA_HP_CTRL, + SGTL5000_CHIP_ANA_CTRL, + SGTL5000_CHIP_LINREG_CTRL, + SGTL5000_CHIP_REF_CTRL, + SGTL5000_CHIP_MIC_CTRL, + SGTL5000_CHIP_LINE_OUT_CTRL, + SGTL5000_CHIP_LINE_OUT_VOL, + SGTL5000_CHIP_ANA_POWER, + SGTL5000_CHIP_PLL_CTRL, + SGTL5000_CHIP_CLK_TOP_CTRL, + SGTL5000_CHIP_ANA_STATUS, + SGTL5000_CHIP_SHORT_CTRL, +}; + +static void dump_reg(struct snd_soc_codec *codec) +{ + int i, reg; + printk(KERN_DEBUG "dump begin\n"); + for (i = 0; i < 21; i++) { + reg = sgtl5000_read(codec, all_reg[i]); + printk(KERN_DEBUG "d r %04x, v %04x\n", all_reg[i], reg); + } + printk(KERN_DEBUG "dump end\n"); +} +#else +static void dump_reg(struct snd_soc_codec *codec) +{ +} +#endif + +static int dac_mux_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = widget->codec; + unsigned int reg; + + if (ucontrol->value.enumerated.item[0]) { + reg = sgtl5000_read(codec, SGTL5000_CHIP_CLK_TOP_CTRL); + reg |= SGTL5000_INT_OSC_EN; + sgtl5000_write(codec, SGTL5000_CHIP_CLK_TOP_CTRL, reg); + + if (codec->bias_level != SND_SOC_BIAS_ON) { + sgtl5000_set_bias_level(codec, SND_SOC_BIAS_PREPARE); + snd_soc_dapm_put_enum_double(kcontrol, ucontrol); + sgtl5000_set_bias_level(codec, SND_SOC_BIAS_ON); + } else + snd_soc_dapm_put_enum_double(kcontrol, ucontrol); + + reg = sgtl5000_read(codec, SGTL5000_CHIP_ANA_CTRL); + reg &= ~(SGTL5000_LINE_OUT_MUTE | SGTL5000_HP_MUTE); + sgtl5000_write(codec, SGTL5000_CHIP_ANA_CTRL, reg); + } else { + reg = sgtl5000_read(codec, SGTL5000_CHIP_CLK_TOP_CTRL); + reg &= ~SGTL5000_INT_OSC_EN; + sgtl5000_write(codec, SGTL5000_CHIP_CLK_TOP_CTRL, reg); + + snd_soc_dapm_put_enum_double(kcontrol, ucontrol); + sgtl5000_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + } + return 0; +} + +static const char *adc_mux_text[] = { + "MIC_IN", "LINE_IN" +}; + +static const char *dac_mux_text[] = { + "DAC", "LINE_IN" +}; + +static const struct soc_enum adc_enum = +SOC_ENUM_SINGLE(SGTL5000_CHIP_ANA_CTRL, 2, 2, adc_mux_text); + +static const struct soc_enum dac_enum = +SOC_ENUM_SINGLE(SGTL5000_CHIP_ANA_CTRL, 6, 2, dac_mux_text); + +static const struct snd_kcontrol_new adc_mux = +SOC_DAPM_ENUM("ADC Mux", adc_enum); + +static const struct snd_kcontrol_new dac_mux = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "DAC Mux", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE + | SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .info = snd_soc_info_enum_double, + .get = snd_soc_dapm_get_enum_double, + .put = dac_mux_put, + .private_value = (unsigned long)&dac_enum, +}; + +static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = { + SND_SOC_DAPM_INPUT("LINE_IN"), + SND_SOC_DAPM_INPUT("MIC_IN"), + + SND_SOC_DAPM_OUTPUT("HP_OUT"), + SND_SOC_DAPM_OUTPUT("LINE_OUT"), + + SND_SOC_DAPM_MUX("ADC Mux", SND_SOC_NOPM, 0, 0, &adc_mux), + SND_SOC_DAPM_MUX("DAC Mux", SND_SOC_NOPM, 0, 0, &dac_mux), + + SND_SOC_DAPM_ADC("ADC", "Capture", SGTL5000_CHIP_DIG_POWER, 6, 0), + SND_SOC_DAPM_DAC("DAC", "Playback", SGTL5000_CHIP_DIG_POWER, 5, 0), +}; + +static const struct snd_soc_dapm_route audio_map[] = { + {"ADC Mux", "LINE_IN", "LINE_IN"}, + {"ADC Mux", "MIC_IN", "MIC_IN"}, + {"ADC", NULL, "ADC Mux"}, + {"DAC Mux", "DAC", "DAC"}, + {"DAC Mux", "LINE_IN", "LINE_IN"}, + {"LINE_OUT", NULL, "DAC"}, + {"HP_OUT", NULL, "DAC Mux"}, +}; + +static int sgtl5000_add_widgets(struct snd_soc_codec *codec) +{ + snd_soc_dapm_new_controls(codec, sgtl5000_dapm_widgets, + ARRAY_SIZE(sgtl5000_dapm_widgets)); + + snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + + snd_soc_dapm_new_widgets(codec); + return 0; +} + +static int dac_info_volsw(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; + uinfo->value.integer.max = 0xfc - 0x3c; + return 0; +} + +static int dac_get_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + int reg, l, r; + + reg = sgtl5000_read(codec, SGTL5000_CHIP_DAC_VOL); + l = (reg & SGTL5000_DAC_VOL_LEFT_MASK) << SGTL5000_DAC_VOL_LEFT_SHIFT; + r = (reg & SGTL5000_DAC_VOL_RIGHT_MASK) << SGTL5000_DAC_VOL_RIGHT_SHIFT; + l = l < 0x3c ? 0x3c : l; + l = l > 0xfc ? 0xfc : l; + r = r < 0x3c ? 0x3c : r; + r = r > 0xfc ? 0xfc : r; + l = 0xfc - l; + r = 0xfc - r; + + ucontrol->value.integer.value[0] = l; + ucontrol->value.integer.value[1] = l; + + return 0; +} + +static int dac_put_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + int reg, l, r; + + l = ucontrol->value.integer.value[0]; + r = ucontrol->value.integer.value[1]; + + l = l < 0x3c ? 0x3c : l; + l = l > 0xfc ? 0xfc : l; + r = r < 0x3c ? 0x3c : r; + r = r > 0xfc ? 0xfc : r; + l = 0xfc - l; + r = 0xfc - r; + + reg = l << SGTL5000_DAC_VOL_LEFT_SHIFT | + r << SGTL5000_DAC_VOL_RIGHT_SHIFT; + + sgtl5000_write(codec, SGTL5000_CHIP_DAC_VOL, reg); + + return 0; +} + +static const char *mic_gain_text[] = { + "0dB", "20dB", "30dB", "40dB" +}; + +static const char *adc_m6db_text[] = { + "No Change", "Reduced by 6dB" +}; + +static const struct soc_enum mic_gain = +SOC_ENUM_SINGLE(SGTL5000_CHIP_MIC_CTRL, 0, 4, mic_gain_text); + +static const struct soc_enum adc_m6db = +SOC_ENUM_SINGLE(SGTL5000_CHIP_ANA_ADC_CTRL, 8, 2, adc_m6db_text); + +static const struct snd_kcontrol_new sgtl5000_snd_controls[] = { + SOC_ENUM("MIC GAIN", mic_gain), + SOC_DOUBLE("Capture Volume", SGTL5000_CHIP_ANA_ADC_CTRL, 0, 4, 0xf, 0), + SOC_ENUM("Capture Vol Reduction", adc_m6db), + {.iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Playback Volume", + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | + SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .info = dac_info_volsw, + .get = dac_get_volsw, + .put = dac_put_volsw, + }, + SOC_DOUBLE("Headphone Volume", SGTL5000_CHIP_ANA_HP_CTRL, 0, 8, 0x7f, + 1), +}; + +static int sgtl5000_add_controls(struct snd_soc_codec *codec) +{ + int err, i; + + for (i = 0; i < ARRAY_SIZE(sgtl5000_snd_controls); i++) { + err = snd_ctl_add(codec->card, + snd_soc_cnew(&sgtl5000_snd_controls[i], + codec, NULL)); + if (err < 0) + return err; + } + + return 0; +} + +static int sgtl5000_digital_mute(struct snd_soc_dai *codec_dai, int mute) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 reg1, reg2; + + reg1 = sgtl5000_read(codec, SGTL5000_CHIP_ANA_CTRL); + reg2 = sgtl5000_read(codec, SGTL5000_CHIP_ADCDAC_CTRL); + + if (mute) { + reg1 |= SGTL5000_LINE_OUT_MUTE; + reg1 |= SGTL5000_HP_MUTE; + reg1 |= SGTL5000_ADC_MUTE; + reg2 |= SGTL5000_DAC_MUTE_LEFT; + reg2 |= SGTL5000_DAC_MUTE_RIGHT; + } else { + reg1 &= ~SGTL5000_LINE_OUT_MUTE; + reg1 &= ~SGTL5000_HP_MUTE; + reg1 &= ~SGTL5000_ADC_MUTE; + reg2 &= ~SGTL5000_DAC_MUTE_LEFT; + reg2 &= ~SGTL5000_DAC_MUTE_RIGHT; + } + + sgtl5000_write(codec, SGTL5000_CHIP_ANA_CTRL, reg1); + sgtl5000_write(codec, SGTL5000_CHIP_ADCDAC_CTRL, reg2); + if (!mute) + dump_reg(codec); + return 0; +} + +static int sgtl5000_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct sgtl5000_priv *sgtl5000 = codec->private_data; + u16 i2sctl = 0; + pr_debug("%s:fmt=%08x\n", __func__, fmt); + sgtl5000->master = 0; + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + break; + case SND_SOC_DAIFMT_CBM_CFM: + i2sctl |= SGTL5000_I2S_MASTER; + sgtl5000->master = 1; + break; + case SND_SOC_DAIFMT_CBM_CFS: + case SND_SOC_DAIFMT_CBS_CFM: + return -EINVAL; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + i2sctl |= SGTL5000_I2S_MODE_PCM; + break; + case SND_SOC_DAIFMT_DSP_B: + i2sctl |= SGTL5000_I2S_MODE_PCM; + i2sctl |= SGTL5000_I2S_LRALIGN; + break; + case SND_SOC_DAIFMT_I2S: + i2sctl |= SGTL5000_I2S_MODE_I2S_LJ; + break; + case SND_SOC_DAIFMT_RIGHT_J: + i2sctl |= SGTL5000_I2S_MODE_RJ; + i2sctl |= SGTL5000_I2S_LRPOL; + break; + case SND_SOC_DAIFMT_LEFT_J: + i2sctl |= SGTL5000_I2S_MODE_I2S_LJ; + i2sctl |= SGTL5000_I2S_LRALIGN; + break; + default: + return -EINVAL; + } + sgtl5000->fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK; + + /* Clock inversion */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + case SND_SOC_DAIFMT_NB_IF: + break; + case SND_SOC_DAIFMT_IB_IF: + case SND_SOC_DAIFMT_IB_NF: + i2sctl |= SGTL5000_I2S_SCLK_INV; + break; + default: + return -EINVAL; + } + sgtl5000_write(codec, SGTL5000_CHIP_I2S_CTRL, i2sctl); + + return 0; +} + +static int sgtl5000_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; + struct sgtl5000_priv *sgtl5000 = codec->private_data; + + sgtl5000->sysclk = freq; + + return 0; +} + +static void sgtl5000_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; + int reg; + + reg = sgtl5000_read(codec, SGTL5000_CHIP_DIG_POWER); + reg &= ~(SGTL5000_I2S_IN_POWERUP | SGTL5000_I2S_OUT_POWERUP); + sgtl5000_write(codec, SGTL5000_CHIP_DIG_POWER, reg); +} + +/* + * Set PCM DAI bit size and sample rate. + * input: params_rate, params_fmt + */ +static int sgtl5000_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; + struct sgtl5000_priv *sgtl5000 = codec->private_data; + int fs = params_rate(params); + int channels = params_channels(params); + int clk_ctl = 0; + int pll_ctl = 0; + int i2s_ctl; + int div2 = 0; + int reg; + + if (!sgtl5000->sysclk) { + pr_err("%s: set sysclk first!\n", __func__); + return -EFAULT; + } + + /* rev 1 does not support mono playback */ + if (sgtl5000->rev != 0x00) { + reg = sgtl5000_read(codec, SGTL5000_CHIP_ANA_TEST2); + if (channels == 1) + reg |= SGTL5000_MONO_DAC; + else + reg &= ~SGTL5000_MONO_DAC; + sgtl5000_write(codec, SGTL5000_CHIP_ANA_TEST2, reg); + } + + switch (fs) { + case 32000: + clk_ctl |= SGTL5000_SYS_FS_32k << SGTL5000_SYS_FS_SHIFT; + break; + case 44100: + clk_ctl |= SGTL5000_SYS_FS_44_1k << SGTL5000_SYS_FS_SHIFT; + break; + case 48000: + clk_ctl |= SGTL5000_SYS_FS_48k << SGTL5000_SYS_FS_SHIFT; + break; + case 96000: + clk_ctl |= SGTL5000_SYS_FS_96k << SGTL5000_SYS_FS_SHIFT; + break; + default: + pr_err("%s: sample rate %d not supported\n", __func__, fs); + return -EFAULT; + } + +#if 0 /* SGTL5000 rev1 has a IC bug to prevent switching to MCLK from PLL. */ + if (fs * 256 == sgtl5000->sysclk) + clk_ctl |= SGTL5000_MCLK_FREQ_256FS << SGTL5000_MCLK_FREQ_SHIFT; + else if (fs * 384 == sgtl5000->sysclk && fs != 96000) + clk_ctl |= SGTL5000_MCLK_FREQ_384FS << SGTL5000_MCLK_FREQ_SHIFT; + else if (fs * 512 == sgtl5000->sysclk && fs != 96000) + clk_ctl |= SGTL5000_MCLK_FREQ_512FS << SGTL5000_MCLK_FREQ_SHIFT; + else +#endif + { + if (!sgtl5000->master) { + pr_err("%s: PLL not supported in slave mode\n", + __func__); + return -EINVAL; + } + clk_ctl |= SGTL5000_MCLK_FREQ_PLL << SGTL5000_MCLK_FREQ_SHIFT; + } + + if ((clk_ctl & SGTL5000_MCLK_FREQ_MASK) == SGTL5000_MCLK_FREQ_PLL) { + u64 out, t; + unsigned int in, int_div, frac_div; + if (sgtl5000->sysclk > 17000000) { + div2 = 1; + in = sgtl5000->sysclk / 2; + } else { + div2 = 0; + in = sgtl5000->sysclk; + } + if (fs == 44100) + out = 180633600; + else + out = 196608000; + t = do_div(out, in); + int_div = out; + t *= 2048; + do_div(t, in); + frac_div = t; + pll_ctl = int_div << SGTL5000_PLL_INT_DIV_SHIFT | + frac_div << SGTL5000_PLL_FRAC_DIV_SHIFT; + } + + i2s_ctl = sgtl5000_read(codec, SGTL5000_CHIP_I2S_CTRL); + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + if (sgtl5000->fmt == SND_SOC_DAIFMT_RIGHT_J) + return -EINVAL; + i2s_ctl |= SGTL5000_I2S_DLEN_16 << SGTL5000_I2S_DLEN_SHIFT; + i2s_ctl |= SGTL5000_I2S_SCLKFREQ_32FS << + SGTL5000_I2S_SCLKFREQ_SHIFT; + break; + case SNDRV_PCM_FORMAT_S20_3LE: + i2s_ctl |= SGTL5000_I2S_DLEN_20 << SGTL5000_I2S_DLEN_SHIFT; + i2s_ctl |= SGTL5000_I2S_SCLKFREQ_64FS << + SGTL5000_I2S_SCLKFREQ_SHIFT; + break; + case SNDRV_PCM_FORMAT_S24_LE: + i2s_ctl |= SGTL5000_I2S_DLEN_24 << SGTL5000_I2S_DLEN_SHIFT; + i2s_ctl |= SGTL5000_I2S_SCLKFREQ_64FS << + SGTL5000_I2S_SCLKFREQ_SHIFT; + break; + case SNDRV_PCM_FORMAT_S32_LE: + if (sgtl5000->fmt == SND_SOC_DAIFMT_RIGHT_J) + return -EINVAL; + i2s_ctl |= SGTL5000_I2S_DLEN_32 << SGTL5000_I2S_DLEN_SHIFT; + i2s_ctl |= SGTL5000_I2S_SCLKFREQ_64FS << + SGTL5000_I2S_SCLKFREQ_SHIFT; + break; + default: + return -EINVAL; + } + + pr_debug("fs=%d,clk_ctl=%d,pll_ctl=%d,i2s_ctl=%d,div2=%d\n", + fs, clk_ctl, pll_ctl, i2s_ctl, div2); + + if ((clk_ctl & SGTL5000_MCLK_FREQ_MASK) == SGTL5000_MCLK_FREQ_PLL) { + sgtl5000_write(codec, SGTL5000_CHIP_PLL_CTRL, pll_ctl); + reg = sgtl5000_read(codec, SGTL5000_CHIP_CLK_TOP_CTRL); + if (div2) + reg |= SGTL5000_INPUT_FREQ_DIV2; + else + reg &= ~SGTL5000_INPUT_FREQ_DIV2; + sgtl5000_write(codec, SGTL5000_CHIP_CLK_TOP_CTRL, reg); + reg = sgtl5000_read(codec, SGTL5000_CHIP_ANA_POWER); + reg |= SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP; + sgtl5000_write(codec, SGTL5000_CHIP_ANA_POWER, reg); + } + sgtl5000_write(codec, SGTL5000_CHIP_CLK_CTRL, clk_ctl); + sgtl5000_write(codec, SGTL5000_CHIP_I2S_CTRL, i2s_ctl); + reg = sgtl5000_read(codec, SGTL5000_CHIP_DIG_POWER); + reg |= SGTL5000_I2S_IN_POWERUP | SGTL5000_I2S_OUT_POWERUP; + sgtl5000_write(codec, SGTL5000_CHIP_DIG_POWER, reg); + return 0; +} + +static int sgtl5000_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + u16 reg; + pr_debug("dapm level %d\n", level); + switch (level) { + case SND_SOC_BIAS_ON: /* full On */ + case SND_SOC_BIAS_PREPARE: /* partial On */ + reg = sgtl5000_read(codec, SGTL5000_CHIP_ANA_POWER); + reg |= SGTL5000_HP_POWERUP; + reg |= SGTL5000_LINE_OUT_POWERUP; + sgtl5000_write(codec, SGTL5000_CHIP_ANA_POWER, reg); + + reg = sgtl5000_read(codec, SGTL5000_CHIP_MIC_CTRL); + reg &= ~SGTL5000_BIAS_R_MASK; + reg |= SGTL5000_BIAS_R_4k << SGTL5000_BIAS_R_SHIFT; + sgtl5000_write(codec, SGTL5000_CHIP_MIC_CTRL, reg); + + reg = sgtl5000_read(codec, SGTL5000_CHIP_ANA_CTRL); + reg |= SGTL5000_HP_ZCD_EN; + reg |= SGTL5000_ADC_ZCD_EN; + sgtl5000_write(codec, SGTL5000_CHIP_ANA_CTRL, reg); + break; + + case SND_SOC_BIAS_STANDBY: /* Off, with power */ + reg = sgtl5000_read(codec, SGTL5000_CHIP_MIC_CTRL); + reg &= ~SGTL5000_BIAS_R_MASK; + reg |= SGTL5000_BIAS_R_off; + sgtl5000_write(codec, SGTL5000_CHIP_MIC_CTRL, reg); + + reg = sgtl5000_read(codec, SGTL5000_CHIP_ANA_CTRL); + reg &= ~SGTL5000_HP_ZCD_EN; + reg &= ~SGTL5000_ADC_ZCD_EN; + sgtl5000_write(codec, SGTL5000_CHIP_ANA_CTRL, reg); + + reg = sgtl5000_read(codec, SGTL5000_CHIP_ANA_POWER); + if (codec->bias_level == SND_SOC_BIAS_OFF) { + reg |= SGTL5000_VAG_POWERUP; + reg |= SGTL5000_REFTOP_POWERUP; + reg |= SGTL5000_DAC_POWERUP; + reg |= SGTL5000_ADC_POWERUP; + } + /*reg &= ~SGTL5000_PLL_POWERUP; + reg &= ~SGTL5000_VCOAMP_POWERUP; */ + reg &= ~SGTL5000_HP_POWERUP; + reg &= ~SGTL5000_CAPLESS_HP_POWERUP; + reg &= ~SGTL5000_LINE_OUT_POWERUP; + sgtl5000_write(codec, SGTL5000_CHIP_ANA_POWER, reg); + + msleep(400); + + break; + + case SND_SOC_BIAS_OFF: /* Off, without power */ + reg = sgtl5000_read(codec, SGTL5000_CHIP_ANA_POWER); + reg &= ~SGTL5000_VAG_POWERUP; + reg &= ~SGTL5000_REFTOP_POWERUP; + reg &= ~SGTL5000_DAC_POWERUP; + reg &= ~SGTL5000_ADC_POWERUP; + sgtl5000_write(codec, SGTL5000_CHIP_ANA_POWER, reg); + break; + } + codec->bias_level = level; + return 0; +} + +#define SGTL5000_RATES (SNDRV_PCM_RATE_32000 |\ + SNDRV_PCM_RATE_44100 |\ + SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000) + +#define SGTL5000_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S20_3LE |\ + SNDRV_PCM_FMTBIT_S24_LE) + +struct snd_soc_dai sgtl5000_dai = { + .name = "SGTL5000", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 2, + .rates = SGTL5000_RATES, + .formats = SGTL5000_FORMATS, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 1, + .rates = SGTL5000_RATES, + .formats = SGTL5000_FORMATS, + }, + .ops = { + .shutdown = sgtl5000_pcm_shutdown, + .hw_params = sgtl5000_pcm_hw_params, + }, + .dai_ops = { + .digital_mute = sgtl5000_digital_mute, + .set_fmt = sgtl5000_set_dai_fmt, + .set_sysclk = sgtl5000_set_dai_sysclk} +}; +EXPORT_SYMBOL_GPL(sgtl5000_dai); + +static int sgtl5000_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; + + sgtl5000_set_bias_level(codec, SND_SOC_BIAS_OFF); + + return 0; +} + +static int sgtl5000_resume(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->codec; + + /* Bring the codec back up to standby first to minimise pop/clicks */ + sgtl5000_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + sgtl5000_set_bias_level(codec, codec->suspend_bias_level); + + return 0; +} + +/* + * initialise the SGTL5000 driver + * register the mixer and dsp interfaces with the kernel + */ +static int sgtl5000_init(struct snd_soc_device *socdev) +{ + struct sgtl5000_platform_data *plat = socdev->codec_data; + struct snd_soc_codec *codec = socdev->codec; + struct i2c_client *client = codec->control_data; + struct sgtl5000_priv *sgtl5000 = codec->private_data; + u16 reg, ana_pwr, lreg_ctrl, ref_ctrl, lo_ctrl, short_ctrl, sss; + int vag; + unsigned int val; + int ret = 0; + + val = sgtl5000_read(codec, SGTL5000_CHIP_ID); + if (((val & SGTL5000_PARTID_MASK) >> SGTL5000_PARTID_SHIFT) != + SGTL5000_PARTID_PART_ID) { + pr_err("Device with ID register %x is not a SGTL5000\n", val); + return -ENODEV; + } + + sgtl5000->rev = (val & SGTL5000_REVID_MASK) >> SGTL5000_REVID_SHIFT; + dev_info(&client->dev, "SGTL5000 revision %d\n", sgtl5000->rev); + + /* For Rev2 or higher, CODEC will copy left channel data to right. + For Rev1, set playback channels_min to 2. */ + if (sgtl5000->rev == 0x00) /* if chip is rev 1 */ + sgtl5000_dai.playback.channels_min = 2; + + codec->name = "SGTL5000"; + codec->owner = THIS_MODULE; + codec->read = sgtl5000_read; + codec->write = sgtl5000_write; + codec->bias_level = SND_SOC_BIAS_OFF; + codec->set_bias_level = sgtl5000_set_bias_level; + codec->dai = &sgtl5000_dai; + codec->num_dai = 1; + + /* register pcms */ + ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); + if (ret < 0) { + dev_err(&client->dev, "failed to create pcms\n"); + return ret; + } + + /* reset value */ + ana_pwr = SGTL5000_DAC_STERO | + SGTL5000_LINREG_SIMPLE_POWERUP | + SGTL5000_STARTUP_POWERUP | + SGTL5000_ADC_STERO | SGTL5000_REFTOP_POWERUP; + lreg_ctrl = 0; + ref_ctrl = 0; + lo_ctrl = 0; + short_ctrl = 0; + sss = SGTL5000_DAC_SEL_I2S_IN << SGTL5000_DAC_SEL_SHIFT; + + if (!plat->vddd) { + /* set VDDD to 1.2v */ + lreg_ctrl |= 0x8 << SGTL5000_LINREG_VDDD_SHIFT; + /* power internal linear regulator */ + ana_pwr |= SGTL5000_LINEREG_D_POWERUP; + } else { + /* turn of startup power */ + ana_pwr &= ~SGTL5000_STARTUP_POWERUP; + ana_pwr &= ~SGTL5000_LINREG_SIMPLE_POWERUP; + } + if (plat->vddio < 3100 && plat->vdda < 3100) { + /* Enable VDDC charge pump */ + ana_pwr |= SGTL5000_VDDC_CHRGPMP_POWERUP; + } + if (plat->vddio >= 3100 && plat->vdda >= 3100) { + /* VDDC use VDDIO rail */ + lreg_ctrl |= SGTL5000_VDDC_ASSN_OVRD; + if (plat->vddio >= 3100) + lreg_ctrl |= SGTL5000_VDDC_MAN_ASSN_VDDIO << + SGTL5000_VDDC_MAN_ASSN_SHIFT; + } + /* If PLL is powered up (such as on power cycle) leave it on. */ + reg = sgtl5000_read(codec, SGTL5000_CHIP_ANA_POWER); + ana_pwr |= reg & (SGTL5000_PLL_POWERUP | SGTL5000_VCOAMP_POWERUP); + + /* set ADC/DAC ref voltage to vdda/2 */ + vag = plat->vdda / 2; + if (vag <= SGTL5000_ANA_GND_BASE) + vag = 0; + else if (vag >= SGTL5000_ANA_GND_BASE + SGTL5000_ANA_GND_STP * + (SGTL5000_ANA_GND_MASK >> SGTL5000_ANA_GND_SHIFT)) + vag = SGTL5000_ANA_GND_MASK >> SGTL5000_ANA_GND_SHIFT; + else + vag = (vag - SGTL5000_ANA_GND_BASE) / SGTL5000_ANA_GND_STP; + ref_ctrl |= vag << SGTL5000_ANA_GND_SHIFT; + + /* set line out ref voltage to vddio/2 */ + vag = plat->vddio / 2; + if (vag <= SGTL5000_LINE_OUT_GND_BASE) + vag = 0; + else if (vag >= SGTL5000_LINE_OUT_GND_BASE + SGTL5000_LINE_OUT_GND_STP * + SGTL5000_LINE_OUT_GND_MAX) + vag = SGTL5000_LINE_OUT_GND_MAX; + else + vag = (vag - SGTL5000_LINE_OUT_GND_BASE) / + SGTL5000_LINE_OUT_GND_STP; + lo_ctrl |= vag << SGTL5000_LINE_OUT_GND_SHIFT; + + /* enable small pop */ + ref_ctrl |= SGTL5000_SMALL_POP; + + /* set short detect */ + /* keep default */ + + /* set routing */ + /* keep default, bypass DAP */ + + sgtl5000_write(codec, SGTL5000_CHIP_LINREG_CTRL, lreg_ctrl); + sgtl5000_write(codec, SGTL5000_CHIP_ANA_POWER, ana_pwr); + msleep(10); + sgtl5000_write(codec, SGTL5000_CHIP_REF_CTRL, ref_ctrl); + sgtl5000_write(codec, SGTL5000_CHIP_LINE_OUT_CTRL, lo_ctrl); + sgtl5000_write(codec, SGTL5000_CHIP_SHORT_CTRL, short_ctrl); + sgtl5000_write(codec, SGTL5000_CHIP_SSS_CTRL, sss); + sgtl5000_write(codec, SGTL5000_CHIP_DIG_POWER, 0); + + reg = SGTL5000_DAC_VOL_RAMP_EN | + SGTL5000_DAC_MUTE_RIGHT | SGTL5000_DAC_MUTE_LEFT; + sgtl5000_write(codec, SGTL5000_CHIP_ADCDAC_CTRL, reg); + + sgtl5000_write(codec, SGTL5000_CHIP_PAD_STRENGTH, 0x015f); + + reg = sgtl5000_read(codec, SGTL5000_CHIP_ANA_ADC_CTRL); + reg &= ~SGTL5000_ADC_VOL_M6DB; + reg &= ~(SGTL5000_ADC_VOL_LEFT_MASK | SGTL5000_ADC_VOL_RIGHT_MASK); + reg |= (0xf << SGTL5000_ADC_VOL_LEFT_SHIFT) + | (0xf << SGTL5000_ADC_VOL_RIGHT_SHIFT); + sgtl5000_write(codec, SGTL5000_CHIP_ANA_ADC_CTRL, reg); + + reg = SGTL5000_LINE_OUT_MUTE | SGTL5000_HP_MUTE | SGTL5000_ADC_MUTE; + sgtl5000_write(codec, SGTL5000_CHIP_ANA_CTRL, reg); + + sgtl5000_write(codec, SGTL5000_CHIP_MIC_CTRL, 0); + sgtl5000_write(codec, SGTL5000_CHIP_CLK_TOP_CTRL, 0); + /* disable DAP */ + sgtl5000_write(codec, SGTL5000_DAP_CTRL, 0); + /* TODO: initialize DAP */ + + sgtl5000_add_controls(codec); + sgtl5000_add_widgets(codec); + + sgtl5000_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + ret = snd_soc_register_card(socdev); + if (ret < 0) { + printk(KERN_ERR "sgtl5000: failed to register card\n"); + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); + return ret; + } + + return 0; +} + +static struct snd_soc_device *sgtl5000_socdev; + +static int sgtl5000_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct snd_soc_device *socdev = sgtl5000_socdev; + struct snd_soc_codec *codec = socdev->codec; + int ret; + + i2c_set_clientdata(i2c, codec); + codec->control_data = i2c; + + ret = sgtl5000_init(socdev); + if (ret < 0) + dev_err(&i2c->dev, "Device initialisation failed\n"); + + return ret; +} + +static const struct i2c_device_id sgtl5000_id[] = { + {"sgtl5000-i2c", 0}, + {}, +}; + +MODULE_DEVICE_TABLE(i2c, sgtl5000_id); + +static struct i2c_driver sgtl5000_i2c_driver = { + .driver = { + .name = "sgtl5000-i2c", + .owner = THIS_MODULE, + }, + .probe = sgtl5000_i2c_probe, + .id_table = sgtl5000_id, +}; + +static int sgtl5000_probe(struct platform_device *pdev) +{ + struct snd_soc_device *socdev = platform_get_drvdata(pdev); + struct snd_soc_codec *codec = socdev->codec; + struct sgtl5000_priv *sgtl5000; + int ret = 0; + + codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); + if (codec == NULL) + return -ENOMEM; + + sgtl5000 = kzalloc(sizeof(struct sgtl5000_priv), GFP_KERNEL); + if (sgtl5000 == NULL) { + kfree(codec); + return -ENOMEM; + } + + codec->private_data = sgtl5000; + socdev->codec = codec; + mutex_init(&codec->mutex); + INIT_LIST_HEAD(&codec->dapm_widgets); + INIT_LIST_HEAD(&codec->dapm_paths); + sgtl5000_socdev = socdev; + + ret = i2c_add_driver(&sgtl5000_i2c_driver); + if (ret != 0) { + dev_err(&pdev->dev, "can't add i2c driver\n"); + kfree(codec->private_data); + kfree(codec); + } + + return ret; +} + +/* power down chip */ +static int sgtl5000_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) + sgtl5000_set_bias_level(codec, SND_SOC_BIAS_OFF); + + snd_soc_free_pcms(socdev); + snd_soc_dapm_free(socdev); + i2c_unregister_device(codec->control_data); + i2c_del_driver(&sgtl5000_i2c_driver); + kfree(codec->private_data); + kfree(codec); + + return 0; +} + +struct snd_soc_codec_device soc_codec_dev_sgtl5000 = { + .probe = sgtl5000_probe, + .remove = sgtl5000_remove, + .suspend = sgtl5000_suspend, + .resume = sgtl5000_resume, +}; +EXPORT_SYMBOL_GPL(soc_codec_dev_sgtl5000); + +MODULE_DESCRIPTION("ASoC SGTL5000 driver"); +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/sound/soc/codecs/Kconfig +++ linux-2.6.28/sound/soc/codecs/Kconfig @@ -110,3 +110,7 @@ config SND_SOC_WM9713 tristate + +config SND_SOC_SGTL5000 + tristate + depends on I2C --- linux-2.6.28.orig/sound/soc/codecs/Makefile +++ linux-2.6.28/sound/soc/codecs/Makefile @@ -19,6 +19,7 @@ snd-soc-wm8990-objs := wm8990.o snd-soc-wm9712-objs := wm9712.o snd-soc-wm9713-objs := wm9713.o +snd-soc-sgtl5000-objs := sgtl5000.o obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o @@ -41,3 +42,4 @@ obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o +obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o --- linux-2.6.28.orig/sound/soc/codecs/sgtl5000.h +++ linux-2.6.28/sound/soc/codecs/sgtl5000.h @@ -0,0 +1,402 @@ +/* + * sgtl5000.h - SGTL5000 audio codec interface + * + * Copyright 2008-2009 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. + */ + +#ifndef _SGTL5000_H +#define _SGTL5000_H + +#include + +extern struct snd_soc_dai sgtl5000_dai; +extern struct snd_soc_codec_device soc_codec_dev_sgtl5000; + +/* + * Register values. + */ +#define SGTL5000_CHIP_ID 0x0000 +#define SGTL5000_CHIP_DIG_POWER 0x0002 +#define SGTL5000_CHIP_CLK_CTRL 0x0004 +#define SGTL5000_CHIP_I2S_CTRL 0x0006 +#define SGTL5000_CHIP_SSS_CTRL 0x000a +#define SGTL5000_CHIP_ADCDAC_CTRL 0x000e +#define SGTL5000_CHIP_DAC_VOL 0x0010 +#define SGTL5000_CHIP_PAD_STRENGTH 0x0014 +#define SGTL5000_CHIP_ANA_ADC_CTRL 0x0020 +#define SGTL5000_CHIP_ANA_HP_CTRL 0x0022 +#define SGTL5000_CHIP_ANA_CTRL 0x0024 +#define SGTL5000_CHIP_LINREG_CTRL 0x0026 +#define SGTL5000_CHIP_REF_CTRL 0x0028 +#define SGTL5000_CHIP_MIC_CTRL 0x002a +#define SGTL5000_CHIP_LINE_OUT_CTRL 0x002c +#define SGTL5000_CHIP_LINE_OUT_VOL 0x002e +#define SGTL5000_CHIP_ANA_POWER 0x0030 +#define SGTL5000_CHIP_PLL_CTRL 0x0032 +#define SGTL5000_CHIP_CLK_TOP_CTRL 0x0034 +#define SGTL5000_CHIP_ANA_STATUS 0x0036 +#define SGTL5000_CHIP_SHORT_CTRL 0x003c +#define SGTL5000_CHIP_ANA_TEST2 0x003a +#define SGTL5000_DAP_CTRL 0x0100 +#define SGTL5000_DAP_PEQ 0x0102 +#define SGTL5000_DAP_BASS_ENHANCE 0x0104 +#define SGTL5000_DAP_BASS_ENHANCE_CTRL 0x0106 +#define SGTL5000_DAP_AUDIO_EQ 0x0108 +#define SGTL5000_DAP_SURROUND 0x010a +#define SGTL5000_DAP_FLT_COEF_ACCESS 0x010c +#define SGTL5000_DAP_COEF_WR_B0_MSB 0x010e +#define SGTL5000_DAP_COEF_WR_B0_LSB 0x0110 +#define SGTL5000_DAP_EQ_BASS_BAND0 0x0116 +#define SGTL5000_DAP_EQ_BASS_BAND1 0x0118 +#define SGTL5000_DAP_EQ_BASS_BAND2 0x011a +#define SGTL5000_DAP_EQ_BASS_BAND3 0x011c +#define SGTL5000_DAP_EQ_BASS_BAND4 0x011e +#define SGTL5000_DAP_MAIN_CHAN 0x0120 +#define SGTL5000_DAP_MIX_CHAN 0x0122 +#define SGTL5000_DAP_AVC_CTRL 0x0124 +#define SGTL5000_DAP_AVC_THRESHOLD 0x0126 +#define SGTL5000_DAP_AVC_ATTACK 0x0128 +#define SGTL5000_DAP_AVC_DECAY 0x012a +#define SGTL5000_DAP_COEF_WR_B1_MSB 0x012c +#define SGTL5000_DAP_COEF_WR_B1_LSB 0x012e +#define SGTL5000_DAP_COEF_WR_B2_MSB 0x0130 +#define SGTL5000_DAP_COEF_WR_B2_LSB 0x0132 +#define SGTL5000_DAP_COEF_WR_A1_MSB 0x0134 +#define SGTL5000_DAP_COEF_WR_A1_LSB 0x0136 +#define SGTL5000_DAP_COEF_WR_A2_MSB 0x0138 +#define SGTL5000_DAP_COEF_WR_A2_LSB 0x013a + +/* + * Field Definitions. + */ + +/* + * SGTL5000_CHIP_ID + */ +#define SGTL5000_PARTID_MASK 0xff00 +#define SGTL5000_PARTID_SHIFT 8 +#define SGTL5000_PARTID_WIDTH 8 +#define SGTL5000_PARTID_PART_ID 0xa0 +#define SGTL5000_REVID_MASK 0x00ff +#define SGTL5000_REVID_SHIFT 0 +#define SGTL5000_REVID_WIDTH 8 + +/* + * SGTL5000_CHIP_DIG_POWER + */ +#define SGTL5000_ADC_EN 0x0040 +#define SGTL5000_DAC_EN 0x0020 +#define SGTL5000_DAP_POWERUP 0x0010 +#define SGTL5000_I2S_OUT_POWERUP 0x0002 +#define SGTL5000_I2S_IN_POWERUP 0x0001 + +/* + * SGTL5000_CHIP_CLK_CTRL + */ +#define SGTL5000_SYS_FS_MASK 0x00c0 +#define SGTL5000_SYS_FS_SHIFT 2 +#define SGTL5000_SYS_FS_WIDTH 2 +#define SGTL5000_SYS_FS_32k 0x0 +#define SGTL5000_SYS_FS_44_1k 0x1 +#define SGTL5000_SYS_FS_48k 0x2 +#define SGTL5000_SYS_FS_96k 0x3 +#define SGTL5000_MCLK_FREQ_MASK 0x0003 +#define SGTL5000_MCLK_FREQ_SHIFT 0 +#define SGTL5000_MCLK_FREQ_WIDTH 2 +#define SGTL5000_MCLK_FREQ_256FS 0x0 +#define SGTL5000_MCLK_FREQ_384FS 0x1 +#define SGTL5000_MCLK_FREQ_512FS 0x2 +#define SGTL5000_MCLK_FREQ_PLL 0x3 + +/* + * SGTL5000_CHIP_I2S_CTRL + */ +#define SGTL5000_I2S_SCLKFREQ_MASK 0x0100 +#define SGTL5000_I2S_SCLKFREQ_SHIFT 8 +#define SGTL5000_I2S_SCLKFREQ_WIDTH 1 +#define SGTL5000_I2S_SCLKFREQ_64FS 0x0 +#define SGTL5000_I2S_SCLKFREQ_32FS 0x1 /* Not for RJ mode */ +#define SGTL5000_I2S_MASTER 0x0080 +#define SGTL5000_I2S_SCLK_INV 0x0040 +#define SGTL5000_I2S_DLEN_MASK 0x0030 +#define SGTL5000_I2S_DLEN_SHIFT 4 +#define SGTL5000_I2S_DLEN_WIDTH 2 +#define SGTL5000_I2S_DLEN_32 0x0 +#define SGTL5000_I2S_DLEN_24 0x1 +#define SGTL5000_I2S_DLEN_20 0x2 +#define SGTL5000_I2S_DLEN_16 0x3 +#define SGTL5000_I2S_MODE_MASK 0x000c +#define SGTL5000_I2S_MODE_SHIFT 2 +#define SGTL5000_I2S_MODE_WIDTH 2 +#define SGTL5000_I2S_MODE_I2S_LJ 0x0 +#define SGTL5000_I2S_MODE_RJ 0x1 +#define SGTL5000_I2S_MODE_PCM 0x2 +#define SGTL5000_I2S_LRALIGN 0x0002 +#define SGTL5000_I2S_LRPOL 0x0001 /* set for which mode */ + +/* + * SGTL5000_CHIP_SSS_CTRL + */ +#define SGTL5000_DAP_MIX_LRSWAP 0x4000 +#define SGTL5000_DAP_LRSWAP 0x2000 +#define SGTL5000_DAC_LRSWAP 0x1000 +#define SGTL5000_I2S_OUT_LRSWAP 0x0400 +#define SGTL5000_DAP_MIX_SEL_MASK 0x0300 +#define SGTL5000_DAP_MIX_SEL_SHIFT 8 +#define SGTL5000_DAP_MIX_SEL_WIDTH 2 +#define SGTL5000_DAP_MIX_SEL_ADC 0x0 +#define SGTL5000_DAP_MIX_SEL_I2S_IN 0x1 +#define SGTL5000_DAP_SEL_MASK 0x00c0 +#define SGTL5000_DAP_SEL_SHIFT 6 +#define SGTL5000_DAP_SEL_WIDTH 2 +#define SGTL5000_DAP_SEL_ADC 0x0 +#define SGTL5000_DAP_SEL_I2S_IN 0x1 +#define SGTL5000_DAC_SEL_MASK 0x0030 +#define SGTL5000_DAC_SEL_SHIFT 4 +#define SGTL5000_DAC_SEL_WIDTH 2 +#define SGTL5000_DAC_SEL_ADC 0x0 +#define SGTL5000_DAC_SEL_I2S_IN 0x1 +#define SGTL5000_DAC_SEL_DAP 0x3 +#define SGTL5000_I2S_OUT_SEL_MASK 0x0003 +#define SGTL5000_I2S_OUT_SEL_SHIFT 0 +#define SGTL5000_I2S_OUT_SEL_WIDTH 2 +#define SGTL5000_I2S_OUT_SEL_ADC 0x0 +#define SGTL5000_I2S_OUT_SEL_I2S_IN 0x1 +#define SGTL5000_I2S_OUT_SEL_DAP 0x3 + +/* + * SGTL5000_CHIP_ADCDAC_CTRL + */ +#define SGTL5000_VOL_BUSY_DAC_RIGHT 0x2000 +#define SGTL5000_VOL_BUSY_DAC_LEFT 0x1000 +#define SGTL5000_DAC_VOL_RAMP_EN 0x0200 +#define SGTL5000_DAC_VOL_RAMP_EXPO 0x0100 +#define SGTL5000_DAC_MUTE_RIGHT 0x0008 +#define SGTL5000_DAC_MUTE_LEFT 0x0004 +#define SGTL5000_ADC_HPF_FREEZE 0x0002 +#define SGTL5000_ADC_HPF_BYPASS 0x0001 + +/* + * SGTL5000_CHIP_DAC_VOL + */ +#define SGTL5000_DAC_VOL_RIGHT_MASK 0xff00 +#define SGTL5000_DAC_VOL_RIGHT_SHIFT 8 +#define SGTL5000_DAC_VOL_RIGHT_WIDTH 8 +#define SGTL5000_DAC_VOL_LEFT_MASK 0x00ff +#define SGTL5000_DAC_VOL_LEFT_SHIFT 0 +#define SGTL5000_DAC_VOL_LEFT_WIDTH 8 + +/* + * SGTL5000_CHIP_PAD_STRENGTH + */ +#define SGTL5000_PAD_I2S_LRCLK_MASK 0x0300 +#define SGTL5000_PAD_I2S_LRCLK_SHIFT 8 +#define SGTL5000_PAD_I2S_LRCLK_WIDTH 2 +#define SGTL5000_PAD_I2S_SCLK_MASK 0x00c0 +#define SGTL5000_PAD_I2S_SCLK_SHIFT 6 +#define SGTL5000_PAD_I2S_SCLK_WIDTH 2 +#define SGTL5000_PAD_I2S_DOUT_MASK 0x0030 +#define SGTL5000_PAD_I2S_DOUT_SHIFT 4 +#define SGTL5000_PAD_I2S_DOUT_WIDTH 2 +#define SGTL5000_PAD_I2C_SDA_MASK 0x000c +#define SGTL5000_PAD_I2C_SDA_SHIFT 2 +#define SGTL5000_PAD_I2C_SDA_WIDTH 2 +#define SGTL5000_PAD_I2C_SCL_MASK 0x0003 +#define SGTL5000_PAD_I2C_SCL_SHIFT 0 +#define SGTL5000_PAD_I2C_SCL_WIDTH 2 + +/* + * SGTL5000_CHIP_ANA_ADC_CTRL + */ +#define SGTL5000_ADC_VOL_M6DB 0x0100 +#define SGTL5000_ADC_VOL_RIGHT_MASK 0x00f0 +#define SGTL5000_ADC_VOL_RIGHT_SHIFT 4 +#define SGTL5000_ADC_VOL_RIGHT_WIDTH 4 +#define SGTL5000_ADC_VOL_LEFT_MASK 0x000f +#define SGTL5000_ADC_VOL_LEFT_SHIFT 0 +#define SGTL5000_ADC_VOL_LEFT_WIDTH 4 + +/* + * SGTL5000_CHIP_ANA_HP_CTRL + */ +#define SGTL5000_HP_VOL_RIGHT_MASK 0x7f00 +#define SGTL5000_HP_VOL_RIGHT_SHIFT 8 +#define SGTL5000_HP_VOL_RIGHT_WIDTH 7 +#define SGTL5000_HP_VOL_LEFT_MASK 0x007f +#define SGTL5000_HP_VOL_LEFT_SHIFT 0 +#define SGTL5000_HP_VOL_LEFT_WIDTH 7 + +/* + * SGTL5000_CHIP_ANA_CTRL + */ +#define SGTL5000_LINE_OUT_MUTE 0x0100 +#define SGTL5000_HP_SEL_MASK 0x0040 +#define SGTL5000_HP_SEL_SHIFT 6 +#define SGTL5000_HP_SEL_WIDTH 1 +#define SGTL5000_HP_SEL_DAC 0x0 +#define SGTL5000_HP_SEL_LINE_IN 0x1 +#define SGTL5000_HP_ZCD_EN 0x0020 +#define SGTL5000_HP_MUTE 0x0010 +#define SGTL5000_ADC_SEL_MASK 0x0004 +#define SGTL5000_ADC_SEL_SHIFT 2 +#define SGTL5000_ADC_SEL_WIDTH 1 +#define SGTL5000_ADC_SEL_MIC 0x0 +#define SGTL5000_ADC_SEL_LINE_IN 0x1 +#define SGTL5000_ADC_ZCD_EN 0x0002 +#define SGTL5000_ADC_MUTE 0x0001 + +/* + * SGTL5000_CHIP_LINREG_CTRL + */ +#define SGTL5000_VDDC_MAN_ASSN_MASK 0x0040 +#define SGTL5000_VDDC_MAN_ASSN_SHIFT 6 +#define SGTL5000_VDDC_MAN_ASSN_WIDTH 1 +#define SGTL5000_VDDC_MAN_ASSN_VDDA 0x0 +#define SGTL5000_VDDC_MAN_ASSN_VDDIO 0x1 +#define SGTL5000_VDDC_ASSN_OVRD 0x0020 +#define SGTL5000_LINREG_VDDD_MASK 0x000f +#define SGTL5000_LINREG_VDDD_SHIFT 0 +#define SGTL5000_LINREG_VDDD_WIDTH 4 + +/* + * SGTL5000_CHIP_REF_CTRL + */ +#define SGTL5000_ANA_GND_MASK 0x01f0 +#define SGTL5000_ANA_GND_SHIFT 4 +#define SGTL5000_ANA_GND_WIDTH 5 +#define SGTL5000_ANA_GND_BASE 800 /* mv */ +#define SGTL5000_ANA_GND_STP 25 /*mv */ +#define SGTL5000_BIAS_CTRL_MASK 0x000e +#define SGTL5000_BIAS_CTRL_SHIFT 1 +#define SGTL5000_BIAS_CTRL_WIDTH 3 +#define SGTL5000_SMALL_POP 0x0001 + +/* + * SGTL5000_CHIP_MIC_CTRL + */ +#define SGTL5000_BIAS_R_MASK 0x0200 +#define SGTL5000_BIAS_R_SHIFT 8 +#define SGTL5000_BIAS_R_WIDTH 2 +#define SGTL5000_BIAS_R_off 0x0 +#define SGTL5000_BIAS_R_2K 0x1 +#define SGTL5000_BIAS_R_4k 0x2 +#define SGTL5000_BIAS_R_8k 0x3 +#define SGTL5000_BIAS_VOLT_MASK 0x0070 +#define SGTL5000_BIAS_VOLT_SHIFT 4 +#define SGTL5000_BIAS_VOLT_WIDTH 3 +#define SGTL5000_MIC_GAIN_MASK 0x0003 +#define SGTL5000_MIC_GAIN_SHIFT 0 +#define SGTL5000_MIC_GAIN_WIDTH 2 + +/* + * SGTL5000_CHIP_LINE_OUT_CTRL + */ +#define SGTL5000_LINE_OUT_CURRENT_MASK 0x0f00 +#define SGTL5000_LINE_OUT_CURRENT_SHIFT 8 +#define SGTL5000_LINE_OUT_CURRENT_WIDTH 4 +#define SGTL5000_LINE_OUT_CURRENT_180u 0x0 +#define SGTL5000_LINE_OUT_CURRENT_270u 0x1 +#define SGTL5000_LINE_OUT_CURRENT_360u 0x3 +#define SGTL5000_LINE_OUT_CURRENT_450u 0x7 +#define SGTL5000_LINE_OUT_CURRENT_540u 0xf +#define SGTL5000_LINE_OUT_GND_MASK 0x003f +#define SGTL5000_LINE_OUT_GND_SHIFT 0 +#define SGTL5000_LINE_OUT_GND_WIDTH 6 +#define SGTL5000_LINE_OUT_GND_BASE 800 /* mv */ +#define SGTL5000_LINE_OUT_GND_STP 25 +#define SGTL5000_LINE_OUT_GND_MAX 0x23 + +/* + * SGTL5000_CHIP_LINE_OUT_VOL + */ +#define SGTL5000_LINE_OUT_VOL_RIGHT_MASK 0x1f00 +#define SGTL5000_LINE_OUT_VOL_RIGHT_SHIFT 8 +#define SGTL5000_LINE_OUT_VOL_RIGHT_WIDTH 5 +#define SGTL5000_LINE_OUT_VOL_LEFT_MASK 0x001f +#define SGTL5000_LINE_OUT_VOL_LEFT_SHIFT 0 +#define SGTL5000_LINE_OUT_VOL_LEFT_WIDTH 5 + +/* + * SGTL5000_CHIP_ANA_POWER + */ +#define SGTL5000_DAC_STERO 0x4000 +#define SGTL5000_LINREG_SIMPLE_POWERUP 0x2000 +#define SGTL5000_STARTUP_POWERUP 0x1000 +#define SGTL5000_VDDC_CHRGPMP_POWERUP 0x0800 +#define SGTL5000_PLL_POWERUP 0x0400 +#define SGTL5000_LINEREG_D_POWERUP 0x0200 +#define SGTL5000_VCOAMP_POWERUP 0x0100 +#define SGTL5000_VAG_POWERUP 0x0080 +#define SGTL5000_ADC_STERO 0x0040 +#define SGTL5000_REFTOP_POWERUP 0x0020 +#define SGTL5000_HP_POWERUP 0x0010 +#define SGTL5000_DAC_POWERUP 0x0008 +#define SGTL5000_CAPLESS_HP_POWERUP 0x0004 +#define SGTL5000_ADC_POWERUP 0x0002 +#define SGTL5000_LINE_OUT_POWERUP 0x0001 + +/* + * SGTL5000_CHIP_PLL_CTRL + */ +#define SGTL5000_PLL_INT_DIV_MASK 0xf800 +#define SGTL5000_PLL_INT_DIV_SHIFT 11 +#define SGTL5000_PLL_INT_DIV_WIDTH 5 +#define SGTL5000_PLL_FRAC_DIV_MASK 0x0700 +#define SGTL5000_PLL_FRAC_DIV_SHIFT 0 +#define SGTL5000_PLL_FRAC_DIV_WIDTH 11 + +/* + * SGTL5000_CHIP_CLK_TOP_CTRL + */ +#define SGTL5000_INT_OSC_EN 0x0800 +#define SGTL5000_INPUT_FREQ_DIV2 0x0008 + +/* + * SGTL5000_CHIP_ANA_STATUS + */ +#define SGTL5000_HP_LRSHORT 0x0200 +#define SGTL5000_CAPLESS_SHORT 0x0100 +#define SGTL5000_PLL_LOCKED 0x0010 + +/* + * SGTL5000_CHIP_SHORT_CTRL + */ +#define SGTL5000_LVLADJR_MASK 0x7000 +#define SGTL5000_LVLADJR_SHIFT 12 +#define SGTL5000_LVLADJR_WIDTH 3 +#define SGTL5000_LVLADJL_MASK 0x0700 +#define SGTL5000_LVLADJL_SHIFT 8 +#define SGTL5000_LVLADJL_WIDTH 3 +#define SGTL5000_LVLADJC_MASK 0x0070 +#define SGTL5000_LVLADJC_SHIFT 4 +#define SGTL5000_LVLADJC_WIDTH 3 +#define SGTL5000_LR_SHORT_MOD_MASK 0x000c +#define SGTL5000_LR_SHORT_MOD_SHIFT 2 +#define SGTL5000_LR_SHORT_MOD_WIDTH 2 +#define SGTL5000_CM_SHORT_MOD_MASK 0x0003 +#define SGTL5000_CM_SHORT_MOD_SHIFT 0 +#define SGTL5000_CM_SHORT_MOD_WIDTH 2 + +/* + *SGTL5000_CHIP_ANA_TEST2 + */ +#define SGTL5000_MONO_DAC 0x1000 + +/* + * SGTL5000_DAP_CTRL + */ +#define SGTL5000_DAP_MIX_EN 0x0010 +#define SGTL5000_DAP_EN 0x0001 + +struct sgtl5000_platform_data { + int vddio; /* voltage of VDDIO (mv) */ + int vdda; /* voltage of vdda (mv) */ + int vddd; /* voltage of vddd (mv), 0 if not connected */ +}; + +#endif --- linux-2.6.28.orig/sound/soc/imx/imx-3stack-sgtl5000.c +++ linux-2.6.28/sound/soc/imx/imx-3stack-sgtl5000.c @@ -0,0 +1,592 @@ +/* + * imx-3stack-sgtl5000.c -- i.MX 3Stack Driver for Freescale SGTL5000 Codec + * + * Copyright 2008-2009 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. + * + * Revision history + * 21th Oct 2008 Initial version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "../codecs/sgtl5000.h" +#include "imx-ssi.h" +#include "imx-pcm.h" + +/* SSI BCLK and LRC master */ +#define SGTL5000_SSI_MASTER 1 + +struct imx_3stack_priv { + int sysclk; + int hw; + struct platform_device *pdev; + struct regulator *reg_vddio; + struct regulator *reg_vdda; + struct regulator *reg_vddd; +}; + +static struct imx_3stack_priv machine_priv; + +static int imx_3stack_audio_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai_link *machine = rtd->dai; + struct snd_soc_dai *cpu_dai = machine->cpu_dai; + struct snd_soc_dai *codec_dai = machine->codec_dai; + struct imx_3stack_priv *priv = &machine_priv; + int ret = 0; + + unsigned int channels = params_channels(params); + u32 dai_format; + + /* only need to do this once as capture and playback are sync */ + if (priv->hw) + return 0; + priv->hw = 1; + + snd_soc_dai_set_sysclk(codec_dai, 0, priv->sysclk, 0); + +#if SGTL5000_SSI_MASTER + dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_SYNC; + if (channels == 2) + dai_format |= SND_SOC_DAIFMT_TDM; + + /* set codec DAI configuration */ + ret = snd_soc_dai_set_fmt(codec_dai, dai_format); + if (ret < 0) + return ret; + + /* set cpu DAI configuration */ + ret = snd_soc_dai_set_fmt(cpu_dai, dai_format); + if (ret < 0) + return ret; +#else + dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_SYNC; + if (channels == 2) + dai_format |= SND_SOC_DAIFMT_TDM; + + /* set codec DAI configuration */ + ret = snd_soc_dai_set_fmt(codec_dai, dai_format); + if (ret < 0) + return ret; + + /* set cpu DAI configuration */ + ret = snd_soc_dai_set_fmt(cpu_dai, dai_format); + if (ret < 0) + return ret; +#endif + + /* set i.MX active slot mask */ + snd_soc_dai_set_tdm_slot(cpu_dai, + channels == 1 ? 0xfffffffe : 0xfffffffc, + channels); + + /* set the SSI system clock as input (unused) */ + snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0, SND_SOC_CLOCK_IN); + + return 0; +} + +static void imx_3stack_shutdown(struct snd_pcm_substream *substream) +{ + struct imx_3stack_priv *priv = &machine_priv; + + priv->hw = 0; +} + +/* + * imx_3stack SGTL5000 audio DAI opserations. + */ +static struct snd_soc_ops imx_3stack_ops = { + .shutdown = imx_3stack_shutdown, + .hw_params = imx_3stack_audio_hw_params, +}; + +static void imx_3stack_init_dam(int ssi_port, int dai_port) +{ + unsigned int ssi_ptcr = 0; + unsigned int dai_ptcr = 0; + unsigned int ssi_pdcr = 0; + unsigned int dai_pdcr = 0; + /* SGTL5000 uses SSI1 or SSI2 via AUDMUX port dai_port for audio */ + + /* reset port ssi_port & dai_port */ + __raw_writel(0, DAM_PTCR(ssi_port)); + __raw_writel(0, DAM_PTCR(dai_port)); + __raw_writel(0, DAM_PDCR(ssi_port)); + __raw_writel(0, DAM_PDCR(dai_port)); + + /* set to synchronous */ + ssi_ptcr |= AUDMUX_PTCR_SYN; + dai_ptcr |= AUDMUX_PTCR_SYN; + +#if SGTL5000_SSI_MASTER + /* set Rx sources ssi_port <--> dai_port */ + ssi_pdcr |= AUDMUX_PDCR_RXDSEL(dai_port); + dai_pdcr |= AUDMUX_PDCR_RXDSEL(ssi_port); + + /* set Tx frame direction and source dai_port--> ssi_port output */ + ssi_ptcr |= AUDMUX_PTCR_TFSDIR; + ssi_ptcr |= AUDMUX_PTCR_TFSSEL(AUDMUX_FROM_TXFS, dai_port); + + /* set Tx Clock direction and source dai_port--> ssi_port output */ + ssi_ptcr |= AUDMUX_PTCR_TCLKDIR; + ssi_ptcr |= AUDMUX_PTCR_TCSEL(AUDMUX_FROM_TXFS, dai_port); +#else + /* set Rx sources ssi_port <--> dai_port */ + ssi_pdcr |= AUDMUX_PDCR_RXDSEL(dai_port); + dai_pdcr |= AUDMUX_PDCR_RXDSEL(ssi_port); + + /* set Tx frame direction and source ssi_port --> dai_port output */ + dai_ptcr |= AUDMUX_PTCR_TFSDIR; + dai_ptcr |= AUDMUX_PTCR_TFSSEL(AUDMUX_FROM_TXFS, ssi_port); + + /* set Tx Clock direction and source ssi_port--> dai_port output */ + dai_ptcr |= AUDMUX_PTCR_TCLKDIR; + dai_ptcr |= AUDMUX_PTCR_TCSEL(AUDMUX_FROM_TXFS, ssi_port); +#endif + + __raw_writel(ssi_ptcr, DAM_PTCR(ssi_port)); + __raw_writel(dai_ptcr, DAM_PTCR(dai_port)); + __raw_writel(ssi_pdcr, DAM_PDCR(ssi_port)); + __raw_writel(dai_pdcr, DAM_PDCR(dai_port)); +} + +/* imx_3stack machine connections to the codec pins */ +static const struct snd_soc_dapm_route audio_map[] = { + + /* Mic Jack --> MIC_IN (with automatic bias) */ + {"MIC_IN", NULL, "Mic Jack"}, + + /* Line in Jack --> LINE_IN */ + {"LINE_IN", NULL, "Line In Jack"}, + + /* HP_OUT --> Headphone Jack */ + {"Headphone Jack", NULL, "HP_OUT"}, + + /* LINE_OUT --> Line Out Jack */ + {"Line Out Jack", NULL, "LINE_OUT"}, + + /* LINE_OUT --> Ext Speaker */ + {"Ext Spk", NULL, "LINE_OUT"}, +}; + +static int sgtl5000_jack_func; +static int sgtl5000_spk_func; + +static void headphone_detect_handler(struct work_struct *work) +{ + struct imx_3stack_priv *priv = &machine_priv; + struct platform_device *pdev = priv->pdev; + struct mxc_audio_platform_data *plat = pdev->dev.platform_data; + int hp_status; + + sysfs_notify(&pdev->dev.kobj, NULL, "headphone"); + + hp_status = plat->hp_status(); + if (hp_status) + set_irq_type(plat->hp_irq, IRQ_TYPE_EDGE_FALLING); + else + set_irq_type(plat->hp_irq, IRQ_TYPE_EDGE_RISING); + enable_irq(plat->hp_irq); +} + +static DECLARE_DELAYED_WORK(hp_event, headphone_detect_handler); + +static irqreturn_t imx_headphone_detect_handler(int irq, void *data) +{ + disable_irq(irq); + schedule_delayed_work(&hp_event, msecs_to_jiffies(200)); + return IRQ_HANDLED; +} + +static ssize_t show_headphone(struct device_driver *dev, char *buf) +{ + struct imx_3stack_priv *priv = &machine_priv; + struct platform_device *pdev = priv->pdev; + struct mxc_audio_platform_data *plat = pdev->dev.platform_data; + u16 hp_status; + + /* determine whether hp is plugged in */ + hp_status = plat->hp_status(); + + if (hp_status == 0) + strcpy(buf, "speaker\n"); + else + strcpy(buf, "headphone\n"); + + return strlen(buf); +} + +static DRIVER_ATTR(headphone, S_IRUGO | S_IWUSR, show_headphone, NULL); + +static const char *jack_function[] = { "off", "on" +}; + +static const char *spk_function[] = { "off", "on" }; + +static const struct soc_enum sgtl5000_enum[] = { + SOC_ENUM_SINGLE_EXT(2, jack_function), + SOC_ENUM_SINGLE_EXT(2, spk_function), +}; + +static int sgtl5000_get_jack(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.enumerated.item[0] = sgtl5000_jack_func; + return 0; +} + +static int sgtl5000_set_jack(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + + if (sgtl5000_jack_func == ucontrol->value.enumerated.item[0]) + return 0; + + sgtl5000_jack_func = ucontrol->value.enumerated.item[0]; + if (sgtl5000_jack_func) + snd_soc_dapm_enable_pin(codec, "Headphone Jack"); + else + snd_soc_dapm_disable_pin(codec, "Headphone Jack"); + + snd_soc_dapm_sync(codec); + return 1; +} + +static int sgtl5000_get_spk(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.enumerated.item[0] = sgtl5000_spk_func; + return 0; +} + +static int sgtl5000_set_spk(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + + if (sgtl5000_spk_func == ucontrol->value.enumerated.item[0]) + return 0; + + sgtl5000_spk_func = ucontrol->value.enumerated.item[0]; + if (sgtl5000_spk_func) + snd_soc_dapm_enable_pin(codec, "Line Out Jack"); + else + snd_soc_dapm_disable_pin(codec, "Line Out Jack"); + + snd_soc_dapm_sync(codec); + return 1; +} + +static int spk_amp_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + int hp_status; + struct imx_3stack_priv *priv = &machine_priv; + struct platform_device *pdev = priv->pdev; + struct mxc_audio_platform_data *plat = pdev->dev.platform_data; + + if ((plat->amp_enable == NULL) || (priv->reg_vdda == NULL)) + return 0; + + hp_status = plat->hp_status(); + if (SND_SOC_DAPM_EVENT_ON(event)) { + if (hp_status) { + plat->amp_enable(0); + regulator_set_mode(priv->reg_vdda, + REGULATOR_MODE_NORMAL); + } else { + plat->amp_enable(1); + regulator_set_mode(priv->reg_vdda, REGULATOR_MODE_FAST); + } + } else { + plat->amp_enable(0); + regulator_set_mode(priv->reg_vdda, REGULATOR_MODE_NORMAL); + } + return 0; +} + +/* imx_3stack machine dapm widgets */ +static const struct snd_soc_dapm_widget imx_3stack_dapm_widgets[] = { + SND_SOC_DAPM_MIC("Mic Jack", NULL), + SND_SOC_DAPM_LINE("Line In Jack", NULL), + SND_SOC_DAPM_LINE("Line Out Jack", NULL), + SND_SOC_DAPM_SPK("Ext Spk", spk_amp_event), + SND_SOC_DAPM_HP("Headphone Jack", NULL), +}; + +static const struct snd_kcontrol_new sgtl5000_machine_controls[] = { + SOC_ENUM_EXT("Jack Function", sgtl5000_enum[0], sgtl5000_get_jack, + sgtl5000_set_jack), + SOC_ENUM_EXT("Speaker Function", sgtl5000_enum[1], sgtl5000_get_spk, + sgtl5000_set_spk), +}; + +static int imx_3stack_sgtl5000_init(struct snd_soc_codec *codec) +{ + int i, ret; + + /* Add imx_3stack specific controls */ + for (i = 0; i < ARRAY_SIZE(sgtl5000_machine_controls); i++) { + ret = snd_ctl_add(codec->card, + snd_soc_cnew(&sgtl5000_machine_controls[i], + codec, NULL)); + if (ret < 0) + return ret; + } + + /* Add imx_3stack specific widgets */ + snd_soc_dapm_new_controls(codec, imx_3stack_dapm_widgets, + ARRAY_SIZE(imx_3stack_dapm_widgets)); + + /* Set up imx_3stack specific audio path audio_map */ + snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + + snd_soc_dapm_sync(codec); + + return 0; +} + +/* imx_3stack digital audio interface glue - connects codec <--> CPU */ +static struct snd_soc_dai_link imx_3stack_dai = { + .name = "SGTL5000", + .stream_name = "SGTL5000", + .cpu_dai = &imx_ssi_dai, + .codec_dai = &sgtl5000_dai, + .init = imx_3stack_sgtl5000_init, + .ops = &imx_3stack_ops, +}; + +/* imx_3stack audio machine driver */ +static struct snd_soc_machine snd_soc_machine_imx_3stack = { + .name = "imx-3stack", + .dai_link = &imx_3stack_dai, + .num_links = 1, +}; + +static struct snd_soc_device imx_3stack_snd_devdata = { + .machine = &snd_soc_machine_imx_3stack, + .platform = &imx_soc_platform, + .codec_dev = &soc_codec_dev_sgtl5000, +}; + +static int __devinit imx_3stack_sgtl5000_probe(struct platform_device *pdev) +{ + struct mxc_audio_platform_data *plat = pdev->dev.platform_data; + struct regulator *reg; + struct imx_3stack_priv *priv = &machine_priv; + struct sgtl5000_platform_data *codec_data; + int ret = 0; + + priv->sysclk = plat->sysclk; + priv->pdev = pdev; + imx_ssi_dai.private_data = plat; + + codec_data = kzalloc(sizeof(struct sgtl5000_platform_data), GFP_KERNEL); + if (!codec_data) { + ret = -ENOMEM; + goto err_codec_data; + } + codec_data->vddio = plat->vddio / 1000; /* uV to mV */ + codec_data->vdda = plat->vdda / 1000; + codec_data->vddd = plat->vddd / 1000; + imx_3stack_snd_devdata.codec_data = codec_data; + + gpio_activate_audio_ports(); + imx_3stack_init_dam(plat->src_port, plat->ext_port); + + if (plat->src_port == 2) + strcpy(imx_ssi_dai.name, "imx-ssi-3"); + else + strcpy(imx_ssi_dai.name, "imx-ssi-1"); + + ret = driver_create_file(pdev->dev.driver, &driver_attr_headphone); + if (ret < 0) { + pr_err("%s:failed to create driver_attr_headphone\n", __func__); + goto sysfs_err; + } + + ret = -EINVAL; + if (plat->init && plat->init()) + goto err_plat_init; + if (plat->vddio_reg) { + reg = regulator_get(&pdev->dev, plat->vddio_reg); + if (IS_ERR(reg)) + goto err_reg_vddio; + priv->reg_vddio = reg; + } + if (plat->vdda_reg) { + reg = regulator_get(&pdev->dev, plat->vdda_reg); + if (IS_ERR(reg)) + goto err_reg_vdda; + priv->reg_vdda = reg; + } + if (plat->vddd_reg) { + reg = regulator_get(&pdev->dev, plat->vddd_reg); + if (IS_ERR(reg)) + goto err_reg_vddd; + priv->reg_vddd = reg; + } + + if (priv->reg_vdda) { + ret = regulator_set_voltage(priv->reg_vdda, + plat->vdda, plat->vdda); + regulator_enable(priv->reg_vdda); + } + if (priv->reg_vddio) { + regulator_set_voltage(priv->reg_vddio, + plat->vddio, plat->vddio); + regulator_enable(priv->reg_vddio); + } + if (priv->reg_vddd) { + regulator_set_voltage(priv->reg_vddd, plat->vddd, plat->vddd); + regulator_enable(priv->reg_vddd); + } + + /* The SGTL5000 has an internal reset that is deasserted 8 SYS_MCLK + cycles after all power rails have been brought up. After this time + communication can start */ + msleep(1); + + if (plat->hp_status()) + ret = request_irq(plat->hp_irq, + imx_headphone_detect_handler, + IRQ_TYPE_EDGE_FALLING, pdev->name, priv); + else + ret = request_irq(plat->hp_irq, + imx_headphone_detect_handler, + IRQ_TYPE_EDGE_RISING, pdev->name, priv); + if (ret < 0) { + pr_err("%s: request irq failed\n", __func__); + goto err_card_reg; + } + + sgtl5000_jack_func = 1; + sgtl5000_spk_func = 1; + + return 0; + +err_card_reg: + if (priv->reg_vddd) + regulator_put(priv->reg_vddd); +err_reg_vddd: + if (priv->reg_vdda) + regulator_put(priv->reg_vdda); +err_reg_vdda: + if (priv->reg_vddio) + regulator_put(priv->reg_vddio); +err_reg_vddio: + if (plat->finit) + plat->finit(); +err_plat_init: + driver_remove_file(pdev->dev.driver, &driver_attr_headphone); +sysfs_err: + kfree(codec_data); +err_codec_data: + return ret; +} + +static int imx_3stack_sgtl5000_remove(struct platform_device *pdev) +{ + struct mxc_audio_platform_data *plat = pdev->dev.platform_data; + struct imx_3stack_priv *priv = &machine_priv; + + free_irq(plat->hp_irq, priv); + + if (priv->reg_vddio) + regulator_disable(priv->reg_vddio); + if (priv->reg_vddd) + regulator_disable(priv->reg_vddd); + if (priv->reg_vdda) + regulator_disable(priv->reg_vdda); + if (plat->amp_enable) + plat->amp_enable(0); + if (plat->finit) + plat->finit(); + if (priv->reg_vdda) + regulator_put(priv->reg_vdda); + if (priv->reg_vddio) + regulator_put(priv->reg_vddio); + if (priv->reg_vddd) + regulator_put(priv->reg_vddd); + + return 0; +} + +static struct platform_driver imx_3stack_sgtl5000_audio_driver = { + .probe = imx_3stack_sgtl5000_probe, + .remove = imx_3stack_sgtl5000_remove, + .driver = { + .name = "imx-3stack-sgtl5000", + }, +}; + +static struct platform_device *imx_3stack_snd_device; + +static int __init imx_3stack_init(void) +{ + int ret; + + ret = platform_driver_register(&imx_3stack_sgtl5000_audio_driver); + if (ret) + return -ENOMEM; + + imx_3stack_snd_device = platform_device_alloc("soc-audio", -1); + if (!imx_3stack_snd_device) + return -ENOMEM; + + platform_set_drvdata(imx_3stack_snd_device, &imx_3stack_snd_devdata); + imx_3stack_snd_devdata.dev = &imx_3stack_snd_device->dev; + ret = platform_device_add(imx_3stack_snd_device); + + if (ret) + platform_device_put(imx_3stack_snd_device); + + return ret; +} + +static void __exit imx_3stack_exit(void) +{ + platform_driver_unregister(&imx_3stack_sgtl5000_audio_driver); + platform_device_unregister(imx_3stack_snd_device); +} + +module_init(imx_3stack_init); +module_exit(imx_3stack_exit); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("SGTL5000 Driver for i.MX 3STACK"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/sound/soc/imx/Kconfig +++ linux-2.6.28/sound/soc/imx/Kconfig @@ -0,0 +1,29 @@ +config SND_MXC_SOC + tristate "SoC Audio for the Freescale i.MX CPU" + depends on ARCH_MXC && SND + select SND_PCM + help + Say Y or M if you want to add support for codecs attached to + the MXC I2S or SSP interface. You will also need + to select the audio interfaces to support below. + +if SND_MXC_SOC + +config SND_MXC_SOC_SSI + tristate + +config SND_MXC_SOC_IRAM + bool "Locate Audio DMA playback buffers in IRAM" + help + Say Y if you don't want Audio playback buffers in external ram + +config SND_SOC_IMX_3STACK_SGTL5000 + tristate "SoC Audio support for IMX - SGTL5000" + select SND_MXC_SOC_SSI + select SND_SOC_SGTL5000 + help + Say Y if you want to add support for SoC audio on IMX 3STACK + with the SGTL5000. + +endif + --- linux-2.6.28.orig/sound/soc/imx/imx-ssi.h +++ linux-2.6.28/sound/soc/imx/imx-ssi.h @@ -0,0 +1,218 @@ +/* + * This program is free software; you can 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 _IMX_SSI_H +#define _IMX_SSI_H + +#include + +/* SSI regs definition */ +#define SSI1_IO_BASE_ADDR IO_ADDRESS(SSI1_BASE_ADDR) +#define SSI2_IO_BASE_ADDR IO_ADDRESS(SSI2_BASE_ADDR) + +#define SSI1_STX0 ((SSI1_IO_BASE_ADDR) + 0x00) +#define SSI1_STX1 ((SSI1_IO_BASE_ADDR) + 0x04) +#define SSI1_SRX0 ((SSI1_IO_BASE_ADDR) + 0x08) +#define SSI1_SRX1 ((SSI1_IO_BASE_ADDR) + 0x0c) +#define SSI1_SCR ((SSI1_IO_BASE_ADDR) + 0x10) +#define SSI1_SISR ((SSI1_IO_BASE_ADDR) + 0x14) +#define SSI1_SIER ((SSI1_IO_BASE_ADDR) + 0x18) +#define SSI1_STCR ((SSI1_IO_BASE_ADDR) + 0x1c) +#define SSI1_SRCR ((SSI1_IO_BASE_ADDR) + 0x20) +#define SSI1_STCCR ((SSI1_IO_BASE_ADDR) + 0x24) +#define SSI1_SRCCR ((SSI1_IO_BASE_ADDR) + 0x28) +#define SSI1_SFCSR ((SSI1_IO_BASE_ADDR) + 0x2c) +#define SSI1_STR ((SSI1_IO_BASE_ADDR) + 0x30) +#define SSI1_SOR ((SSI1_IO_BASE_ADDR) + 0x34) +#define SSI1_SACNT ((SSI1_IO_BASE_ADDR) + 0x38) +#define SSI1_SACADD ((SSI1_IO_BASE_ADDR) + 0x3c) +#define SSI1_SACDAT ((SSI1_IO_BASE_ADDR) + 0x40) +#define SSI1_SATAG ((SSI1_IO_BASE_ADDR) + 0x44) +#define SSI1_STMSK ((SSI1_IO_BASE_ADDR) + 0x48) +#define SSI1_SRMSK ((SSI1_IO_BASE_ADDR) + 0x4c) + +#define SSI2_STX0 ((SSI2_IO_BASE_ADDR) + 0x00) +#define SSI2_STX1 ((SSI2_IO_BASE_ADDR) + 0x04) +#define SSI2_SRX0 ((SSI2_IO_BASE_ADDR) + 0x08) +#define SSI2_SRX1 ((SSI2_IO_BASE_ADDR) + 0x0c) +#define SSI2_SCR ((SSI2_IO_BASE_ADDR) + 0x10) +#define SSI2_SISR ((SSI2_IO_BASE_ADDR) + 0x14) +#define SSI2_SIER ((SSI2_IO_BASE_ADDR) + 0x18) +#define SSI2_STCR ((SSI2_IO_BASE_ADDR) + 0x1c) +#define SSI2_SRCR ((SSI2_IO_BASE_ADDR) + 0x20) +#define SSI2_STCCR ((SSI2_IO_BASE_ADDR) + 0x24) +#define SSI2_SRCCR ((SSI2_IO_BASE_ADDR) + 0x28) +#define SSI2_SFCSR ((SSI2_IO_BASE_ADDR) + 0x2c) +#define SSI2_STR ((SSI2_IO_BASE_ADDR) + 0x30) +#define SSI2_SOR ((SSI2_IO_BASE_ADDR) + 0x34) +#define SSI2_SACNT ((SSI2_IO_BASE_ADDR) + 0x38) +#define SSI2_SACADD ((SSI2_IO_BASE_ADDR) + 0x3c) +#define SSI2_SACDAT ((SSI2_IO_BASE_ADDR) + 0x40) +#define SSI2_SATAG ((SSI2_IO_BASE_ADDR) + 0x44) +#define SSI2_STMSK ((SSI2_IO_BASE_ADDR) + 0x48) +#define SSI2_SRMSK ((SSI2_IO_BASE_ADDR) + 0x4c) + +#define SSI_SCR_CLK_IST (1 << 9) +#define SSI_SCR_TCH_EN (1 << 8) +#define SSI_SCR_SYS_CLK_EN (1 << 7) +#define SSI_SCR_I2S_MODE_NORM (0 << 5) +#define SSI_SCR_I2S_MODE_MSTR (1 << 5) +#define SSI_SCR_I2S_MODE_SLAVE (2 << 5) +#define SSI_SCR_SYN (1 << 4) +#define SSI_SCR_NET (1 << 3) +#define SSI_SCR_RE (1 << 2) +#define SSI_SCR_TE (1 << 1) +#define SSI_SCR_SSIEN (1 << 0) +#define SSI_SCR_I2S_MODE_MASK (3 << 5) + +#define SSI_SISR_CMDAU (1 << 18) +#define SSI_SISR_CMDDU (1 << 17) +#define SSI_SISR_RXT (1 << 16) +#define SSI_SISR_RDR1 (1 << 15) +#define SSI_SISR_RDR0 (1 << 14) +#define SSI_SISR_TDE1 (1 << 13) +#define SSI_SISR_TDE0 (1 << 12) +#define SSI_SISR_ROE1 (1 << 11) +#define SSI_SISR_ROE0 (1 << 10) +#define SSI_SISR_TUE1 (1 << 9) +#define SSI_SISR_TUE0 (1 << 8) +#define SSI_SISR_TFS (1 << 7) +#define SSI_SISR_RFS (1 << 6) +#define SSI_SISR_TLS (1 << 5) +#define SSI_SISR_RLS (1 << 4) +#define SSI_SISR_RFF1 (1 << 3) +#define SSI_SISR_RFF0 (1 << 2) +#define SSI_SISR_TFE1 (1 << 1) +#define SSI_SISR_TFE0 (1 << 0) + +#define SSI_SIER_RDMAE (1 << 22) +#define SSI_SIER_RIE (1 << 21) +#define SSI_SIER_TDMAE (1 << 20) +#define SSI_SIER_TIE (1 << 19) +#define SSI_SIER_CMDAU_EN (1 << 18) +#define SSI_SIER_CMDDU_EN (1 << 17) +#define SSI_SIER_RXT_EN (1 << 16) +#define SSI_SIER_RDR1_EN (1 << 15) +#define SSI_SIER_RDR0_EN (1 << 14) +#define SSI_SIER_TDE1_EN (1 << 13) +#define SSI_SIER_TDE0_EN (1 << 12) +#define SSI_SIER_ROE1_EN (1 << 11) +#define SSI_SIER_ROE0_EN (1 << 10) +#define SSI_SIER_TUE1_EN (1 << 9) +#define SSI_SIER_TUE0_EN (1 << 8) +#define SSI_SIER_TFS_EN (1 << 7) +#define SSI_SIER_RFS_EN (1 << 6) +#define SSI_SIER_TLS_EN (1 << 5) +#define SSI_SIER_RLS_EN (1 << 4) +#define SSI_SIER_RFF1_EN (1 << 3) +#define SSI_SIER_RFF0_EN (1 << 2) +#define SSI_SIER_TFE1_EN (1 << 1) +#define SSI_SIER_TFE0_EN (1 << 0) + +#define SSI_STCR_TXBIT0 (1 << 9) +#define SSI_STCR_TFEN1 (1 << 8) +#define SSI_STCR_TFEN0 (1 << 7) +#define SSI_STCR_TFDIR (1 << 6) +#define SSI_STCR_TXDIR (1 << 5) +#define SSI_STCR_TSHFD (1 << 4) +#define SSI_STCR_TSCKP (1 << 3) +#define SSI_STCR_TFSI (1 << 2) +#define SSI_STCR_TFSL (1 << 1) +#define SSI_STCR_TEFS (1 << 0) + +#define SSI_SRCR_RXBIT0 (1 << 9) +#define SSI_SRCR_RFEN1 (1 << 8) +#define SSI_SRCR_RFEN0 (1 << 7) +#define SSI_SRCR_RFDIR (1 << 6) +#define SSI_SRCR_RXDIR (1 << 5) +#define SSI_SRCR_RSHFD (1 << 4) +#define SSI_SRCR_RSCKP (1 << 3) +#define SSI_SRCR_RFSI (1 << 2) +#define SSI_SRCR_RFSL (1 << 1) +#define SSI_SRCR_REFS (1 << 0) + +#define SSI_STCCR_DIV2 (1 << 18) +#define SSI_STCCR_PSR (1 << 15) +#define SSI_STCCR_WL(x) ((((x) - 2) >> 1) << 13) +#define SSI_STCCR_DC(x) (((x) & 0x1f) << 8) +#define SSI_STCCR_PM(x) (((x) & 0xff) << 0) +#define SSI_STCCR_WL_MASK (0xf << 13) +#define SSI_STCCR_DC_MASK (0x1f << 8) +#define SSI_STCCR_PM_MASK (0xff << 0) + +#define SSI_SRCCR_DIV2 (1 << 18) +#define SSI_SRCCR_PSR (1 << 15) +#define SSI_SRCCR_WL(x) ((((x) - 2) >> 1) << 13) +#define SSI_SRCCR_DC(x) (((x) & 0x1f) << 8) +#define SSI_SRCCR_PM(x) (((x) & 0xff) << 0) +#define SSI_SRCCR_WL_MASK (0xf << 13) +#define SSI_SRCCR_DC_MASK (0x1f << 8) +#define SSI_SRCCR_PM_MASK (0xff << 0) + + +#define SSI_SFCSR_RFCNT1(x) (((x) & 0xf) << 28) +#define SSI_SFCSR_TFCNT1(x) (((x) & 0xf) << 24) +#define SSI_SFCSR_RFWM1(x) (((x) & 0xf) << 20) +#define SSI_SFCSR_TFWM1(x) (((x) & 0xf) << 16) +#define SSI_SFCSR_RFCNT0(x) (((x) & 0xf) << 12) +#define SSI_SFCSR_TFCNT0(x) (((x) & 0xf) << 8) +#define SSI_SFCSR_RFWM0(x) (((x) & 0xf) << 4) +#define SSI_SFCSR_TFWM0(x) (((x) & 0xf) << 0) + +#define SSI_STR_TEST (1 << 15) +#define SSI_STR_RCK2TCK (1 << 14) +#define SSI_STR_RFS2TFS (1 << 13) +#define SSI_STR_RXSTATE(x) (((x) & 0xf) << 8) +#define SSI_STR_TXD2RXD (1 << 7) +#define SSI_STR_TCK2RCK (1 << 6) +#define SSI_STR_TFS2RFS (1 << 5) +#define SSI_STR_TXSTATE(x) (((x) & 0xf) << 0) + +#define SSI_SOR_CLKOFF (1 << 6) +#define SSI_SOR_RX_CLR (1 << 5) +#define SSI_SOR_TX_CLR (1 << 4) +#define SSI_SOR_INIT (1 << 3) +#define SSI_SOR_WAIT(x) (((x) & 0x3) << 1) +#define SSI_SOR_SYNRST (1 << 0) + +#define SSI_SACNT_FRDIV(x) (((x) & 0x3f) << 5) +#define SSI_SACNT_WR (x << 4) +#define SSI_SACNT_RD (x << 3) +#define SSI_SACNT_TIF (x << 2) +#define SSI_SACNT_FV (x << 1) +#define SSI_SACNT_AC97EN (x << 0) + +/* SDMA & SSI watermarks for FIFO's */ +#define SDMA_TXFIFO_WATERMARK 0x4 +#define SDMA_RXFIFO_WATERMARK 0x6 +#define SSI_TXFIFO_WATERMARK 0x4 +#define SSI_RXFIFO_WATERMARK 0x6 + +/* i.MX DAI SSP ID's */ +#define IMX_DAI_SSI0 0 /* SSI1 FIFO 0 */ +#define IMX_DAI_SSI1 1 /* SSI1 FIFO 1 */ +#define IMX_DAI_SSI2 2 /* SSI2 FIFO 0 */ +#define IMX_DAI_SSI3 3 /* SSI2 FIFO 1 */ + +/* SSI clock sources */ +#define IMX_SSP_SYS_CLK 0 + +/* SSI audio dividers */ +#define IMX_SSI_TX_DIV_2 0 +#define IMX_SSI_TX_DIV_PSR 1 +#define IMX_SSI_TX_DIV_PM 2 +#define IMX_SSI_RX_DIV_2 3 +#define IMX_SSI_RX_DIV_PSR 4 +#define IMX_SSI_RX_DIV_PM 5 + + +/* SSI Div 2 */ +#define IMX_SSI_DIV_2_OFF (~SSI_STCCR_DIV2) +#define IMX_SSI_DIV_2_ON SSI_STCCR_DIV2 + +extern struct snd_soc_dai imx_ssi_dai; + +#endif --- linux-2.6.28.orig/sound/soc/imx/imx-pcm.h +++ linux-2.6.28/sound/soc/imx/imx-pcm.h @@ -0,0 +1,70 @@ +/* + * imx-pcm.h :- ASoC platform header for Freescale i.MX + * + * This program is free software; you can 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 _MXC_PCM_H +#define _MXC_PCM_H + +#include + +/* AUDMUX regs definition */ +#define AUDMUX_IO_BASE_ADDR IO_ADDRESS(AUDMUX_BASE_ADDR) + +#define DAM_PTCR1 ((AUDMUX_IO_BASE_ADDR) + 0x00) +#define DAM_PDCR1 ((AUDMUX_IO_BASE_ADDR) + 0x04) +#define DAM_PTCR2 ((AUDMUX_IO_BASE_ADDR) + 0x08) +#define DAM_PDCR2 ((AUDMUX_IO_BASE_ADDR) + 0x0C) +#define DAM_PTCR3 ((AUDMUX_IO_BASE_ADDR) + 0x10) +#define DAM_PDCR3 ((AUDMUX_IO_BASE_ADDR) + 0x14) +#define DAM_PTCR4 ((AUDMUX_IO_BASE_ADDR) + 0x18) +#define DAM_PDCR4 ((AUDMUX_IO_BASE_ADDR) + 0x1C) +#define DAM_PTCR5 ((AUDMUX_IO_BASE_ADDR) + 0x20) +#define DAM_PDCR5 ((AUDMUX_IO_BASE_ADDR) + 0x24) +#define DAM_PTCR6 ((AUDMUX_IO_BASE_ADDR) + 0x28) +#define DAM_PDCR6 ((AUDMUX_IO_BASE_ADDR) + 0x2C) +#define DAM_PTCR7 ((AUDMUX_IO_BASE_ADDR) + 0x30) +#define DAM_PDCR7 ((AUDMUX_IO_BASE_ADDR) + 0x34) +#define DAM_CNMCR ((AUDMUX_IO_BASE_ADDR) + 0x38) +#define DAM_PTCR(a) ((AUDMUX_IO_BASE_ADDR) + (a-1)*8) +#define DAM_PDCR(a) ((AUDMUX_IO_BASE_ADDR) + 4 + (a-1)*8) + +#define AUDMUX_PTCR_TFSDIR (1 << 31) +#define AUDMUX_PTCR_TFSSEL(x, y) \ + ((x << 30) | (((y - 1) & 0x7) << 27)) +#define AUDMUX_PTCR_TCLKDIR (1 << 26) +#define AUDMUX_PTCR_TCSEL(x, y) \ + ((x << 25) | (((y - 1) & 0x7) << 22)) +#define AUDMUX_PTCR_RFSDIR (1 << 21) +#define AUDMUX_PTCR_RFSSEL(x, y) \ + ((x << 20) | (((y - 1) & 0x7) << 17)) +#define AUDMUX_PTCR_RCLKDIR (1 << 16) +#define AUDMUX_PTCR_RCSEL(x, y) \ + ((x << 15) | (((y - 1) & 0x7) << 12)) +#define AUDMUX_PTCR_SYN (1 << 11) + +#define AUDMUX_FROM_TXFS 0 +#define AUDMUX_FROM_RXFS 1 + +#define AUDMUX_PDCR_RXDSEL(x) (((x - 1) & 0x7) << 13) +#define AUDMUX_PDCR_TXDXEN (1 << 12) +#define AUDMUX_PDCR_MODE(x) (((x) & 0x3) << 8) +#define AUDMUX_PDCR_INNMASK(x) (((x) & 0xff) << 0) + +#define AUDMUX_CNMCR_CEN (1 << 18) +#define AUDMUX_CNMCR_FSPOL (1 << 17) +#define AUDMUX_CNMCR_CLKPOL (1 << 16) +#define AUDMUX_CNMCR_CNTHI(x) (((x) & 0xff) << 8) +#define AUDMUX_CNMCR_CNTLOW(x) (((x) & 0xff) << 0) + +struct mxc_pcm_dma_params { + char *name; /* stream identifier */ + dma_channel_params params; +}; + +extern struct snd_soc_platform imx_soc_platform; + +#endif --- linux-2.6.28.orig/sound/soc/imx/Makefile +++ linux-2.6.28/sound/soc/imx/Makefile @@ -0,0 +1,11 @@ +# i.MX Platform Support +snd-soc-imx-objs := imx-pcm.o +snd-soc-imx-ssi-objs := imx-ssi.o + +obj-$(CONFIG_SND_MXC_SOC) += snd-soc-imx.o +obj-$(CONFIG_SND_MXC_SOC_SSI) += snd-soc-imx-ssi.o + +# i.MX Machine Support +snd-soc-imx-3stack-sgtl5000-objs := imx-3stack-sgtl5000.o +obj-$(CONFIG_SND_SOC_IMX_3STACK_SGTL5000) += snd-soc-imx-3stack-sgtl5000.o + --- linux-2.6.28.orig/sound/soc/imx/imx-pcm.c +++ linux-2.6.28/sound/soc/imx/imx-pcm.c @@ -0,0 +1,600 @@ +/* + * imx-pcm.c -- ALSA SoC interface for the Freescale i.MX3 CPU's + * + * Copyright 2006 Wolfson Microelectronics PLC. + * Author: Liam Girdwood + * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com + * + * Based on imx31-pcm.c by Nicolas Pitre, (C) 2004 MontaVista Software, Inc. + * and on mxc-alsa-mc13783 (C) 2006-2008 Freescale. + * + * This program is free software; you can 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 "imx-pcm.h" +#include "imx-ssi.h" +#if 0 +#include "imx-esai.h" +#endif + +#ifdef CONFIG_SND_MXC_SOC_IRAM +static bool UseIram = 1; +#else +static bool UseIram; +#endif + +/* debug */ +#define IMX_PCM_DEBUG 0 +#if IMX_PCM_DEBUG +#define dbg(format, arg...) printk(format, ## arg) +#else +#define dbg(format, arg...) +#endif + +static const struct snd_pcm_hardware imx_pcm_hardware = { + .info = (SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, +#ifdef CONFIG_SND_MXC_SOC_IRAM + .buffer_bytes_max = SND_RAM_SIZE, + .period_bytes_max = SND_RAM_SIZE / 4, +#else + .buffer_bytes_max = 64 * 1024, + .period_bytes_max = 16 * 1024, +#endif + .period_bytes_min = 64, + .periods_min = 2, + .periods_max = 255, + .fifo_size = 0, +}; + +struct mxc_runtime_data { + int dma_ch; + spinlock_t dma_lock; + int active, period, periods; + int dma_wchannel; + int dma_active; + int dma_alloc; +}; + +static uint32_t audio_iram_phys_base_addr; +static void *audio_iram_virt_base_addr; + +static struct vm_operations_struct snd_mxc_audio_playback_vm_ops = { + .open = snd_pcm_mmap_data_open, + .close = snd_pcm_mmap_data_close, +}; + +/* + enable user space access to iram buffer +*/ +static int imx_iram_audio_playback_mmap(struct snd_pcm_substream *substream, + struct vm_area_struct *area) +{ + unsigned long off; + unsigned long phys; + unsigned long size; + int ret = 0; + + area->vm_ops = &snd_mxc_audio_playback_vm_ops; + area->vm_private_data = substream; + + off = area->vm_pgoff << PAGE_SHIFT; + phys = audio_iram_phys_base_addr + off; + size = area->vm_end - area->vm_start; + + if (off + size > SND_RAM_SIZE) + return -EINVAL; + + area->vm_page_prot = pgprot_nonshareddev(area->vm_page_prot); + area->vm_flags |= VM_IO; + ret = + remap_pfn_range(area, area->vm_start, phys >> PAGE_SHIFT, + size, area->vm_page_prot); + if (ret == 0) + area->vm_ops->open(area); + + return ret; +} + +/* + Map nbytes in virtual space + bytes -audio iram iram partition size + phys_addr - physical address of iram buffer + returns - virtual address of the iram buffer or NULL if fail +*/ +static void *imx_iram_init(dma_addr_t * phys_addr, size_t bytes) +{ + void *iram_base; + + iram_base = (void *)ioremap((uint32_t) SND_RAM_BASE_ADDR, bytes); + + audio_iram_virt_base_addr = iram_base; + audio_iram_phys_base_addr = (uint32_t) SND_RAM_BASE_ADDR; + *phys_addr = (dma_addr_t) SND_RAM_BASE_ADDR; + + return audio_iram_virt_base_addr; + +} + +/* + destroy the virtual mapping of the iram buffer +*/ + +static void imx_iram_free(void) +{ + iounmap(audio_iram_virt_base_addr); +} + +static int imx_get_sdma_transfer(int format, int dai_port, int stream_type) +{ + int transfer = -1; + + if (dai_port == IMX_DAI_SSI0) { + if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) { + if (format == SNDRV_PCM_FORMAT_S16_LE) + transfer = MXC_DMA_SSI1_16BIT_TX0; + else if (format == SNDRV_PCM_FORMAT_S24_LE) + transfer = MXC_DMA_SSI1_24BIT_TX0; + else if (format == SNDRV_PCM_FORMAT_S20_3LE) + transfer = MXC_DMA_SSI1_24BIT_TX0; + } else { + if (format == SNDRV_PCM_FORMAT_S16_LE) + transfer = MXC_DMA_SSI1_16BIT_RX0; + else if (format == SNDRV_PCM_FORMAT_S24_LE) + transfer = MXC_DMA_SSI1_24BIT_RX0; + else if (format == SNDRV_PCM_FORMAT_S20_3LE) + transfer = MXC_DMA_SSI1_24BIT_RX0; + } + } else if (dai_port == IMX_DAI_SSI1) { + if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) { + if (format == SNDRV_PCM_FORMAT_S16_LE) + transfer = MXC_DMA_SSI1_16BIT_TX1; + else if (format == SNDRV_PCM_FORMAT_S24_LE) + transfer = MXC_DMA_SSI1_24BIT_TX1; + else if (format == SNDRV_PCM_FORMAT_S20_3LE) + transfer = MXC_DMA_SSI1_24BIT_TX1; + } else { + if (format == SNDRV_PCM_FORMAT_S16_LE) + transfer = MXC_DMA_SSI1_16BIT_RX1; + else if (format == SNDRV_PCM_FORMAT_S24_LE) + transfer = MXC_DMA_SSI1_24BIT_RX1; + else if (format == SNDRV_PCM_FORMAT_S20_3LE) + transfer = MXC_DMA_SSI1_24BIT_RX1; + } + } else if (dai_port == IMX_DAI_SSI2) { + if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) { + if (format == SNDRV_PCM_FORMAT_S16_LE) + transfer = MXC_DMA_SSI2_16BIT_TX0; + else if (format == SNDRV_PCM_FORMAT_S24_LE) + transfer = MXC_DMA_SSI2_24BIT_TX0; + else if (format == SNDRV_PCM_FORMAT_S20_3LE) + transfer = MXC_DMA_SSI2_24BIT_TX0; + } else { + if (format == SNDRV_PCM_FORMAT_S16_LE) + transfer = MXC_DMA_SSI2_16BIT_RX0; + else if (format == SNDRV_PCM_FORMAT_S24_LE) + transfer = MXC_DMA_SSI2_24BIT_RX0; + else if (format == SNDRV_PCM_FORMAT_S20_3LE) + transfer = MXC_DMA_SSI2_24BIT_RX0; + } + } else if (dai_port == IMX_DAI_SSI3) { + if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) { + if (format == SNDRV_PCM_FORMAT_S16_LE) + transfer = MXC_DMA_SSI2_16BIT_TX1; + else if (format == SNDRV_PCM_FORMAT_S24_LE) + transfer = MXC_DMA_SSI2_24BIT_TX1; + else if (format == SNDRV_PCM_FORMAT_S20_3LE) + transfer = MXC_DMA_SSI2_24BIT_TX1; + } else { + if (format == SNDRV_PCM_FORMAT_S16_LE) + transfer = MXC_DMA_SSI2_16BIT_RX1; + else if (format == SNDRV_PCM_FORMAT_S24_LE) + transfer = MXC_DMA_SSI2_24BIT_RX1; + else if (format == SNDRV_PCM_FORMAT_S20_3LE) + transfer = MXC_DMA_SSI2_24BIT_RX1; + } +#if 0 + } else if ((dai_port & IMX_DAI_ESAI_TX) + || (dai_port & IMX_DAI_ESAI_RX)) { + if (stream_type == SNDRV_PCM_STREAM_PLAYBACK) { + if (format == SNDRV_PCM_FORMAT_S16_LE) + transfer = MXC_DMA_ESAI_16BIT_TX; + else if (format == SNDRV_PCM_FORMAT_S24_LE) + transfer = MXC_DMA_ESAI_24BIT_TX; + else if (format == SNDRV_PCM_FORMAT_S20_3LE) + transfer = MXC_DMA_ESAI_24BIT_TX; + } else { + if (format == SNDRV_PCM_FORMAT_S16_LE) + transfer = MXC_DMA_ESAI_16BIT_RX; + else if (format == SNDRV_PCM_FORMAT_S24_LE) + transfer = MXC_DMA_ESAI_24BIT_RX; + else if (format == SNDRV_PCM_FORMAT_S20_3LE) + transfer = MXC_DMA_ESAI_24BIT_RX; + } +#endif + } + + return transfer; +} + +static int dma_new_period(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct mxc_runtime_data *prtd = runtime->private_data; + unsigned int dma_size = frames_to_bytes(runtime, runtime->period_size); + unsigned int offset = dma_size * prtd->period; + int ret = 0; + mxc_dma_requestbuf_t sdma_request; + + if (!prtd->active) + return 0; + + memset(&sdma_request, 0, sizeof(mxc_dma_requestbuf_t)); + + dbg("period pos ALSA %x DMA %x\n", runtime->periods, prtd->period); + dbg("period size ALSA %x DMA %x Offset %x dmasize %x\n", + (unsigned int)runtime->period_size, runtime->dma_bytes, + offset, dma_size); + dbg("DMA addr %x\n", runtime->dma_addr + offset); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + sdma_request.src_addr = + (dma_addr_t) (runtime->dma_addr + offset); + else + sdma_request.dst_addr = + (dma_addr_t) (runtime->dma_addr + offset); + + sdma_request.num_of_bytes = dma_size; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + mxc_dma_config(prtd->dma_wchannel, &sdma_request, 1, + MXC_DMA_MODE_WRITE); + ret = mxc_dma_enable(prtd->dma_wchannel); + } else { + + mxc_dma_config(prtd->dma_wchannel, &sdma_request, 1, + MXC_DMA_MODE_READ); + ret = mxc_dma_enable(prtd->dma_wchannel); + } + prtd->dma_active = 1; + prtd->period++; + prtd->period %= runtime->periods; + + return ret; +} + +static void audio_dma_irq(void *data) +{ + struct snd_pcm_substream *substream = (struct snd_pcm_substream *)data; + struct snd_pcm_runtime *runtime = substream->runtime; + struct mxc_runtime_data *prtd = runtime->private_data; + + prtd->dma_active = 0; + prtd->periods++; + prtd->periods %= runtime->periods; + + dbg("irq per %d offset %x\n", prtd->periods, + frames_to_bytes(runtime, runtime->period_size) * prtd->periods); + + if (prtd->active) + snd_pcm_period_elapsed(substream); + dma_new_period(substream); +} + +static int imx_pcm_prepare(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct mxc_runtime_data *prtd = runtime->private_data; + int ret = 0, channel = 0; + + if (prtd->dma_alloc) { + mxc_dma_free(prtd->dma_wchannel); + prtd->dma_alloc = 0; + } + + /* only allocate the DMA chn once */ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + + channel = mxc_dma_request(prtd->dma_ch, "ALSA TX SDMA"); + if (channel < 0) { + pr_err("imx-pcm: error requesting \ + a write dma channel\n"); + return channel; + } + ret = mxc_dma_callback_set(channel, (mxc_dma_callback_t) + audio_dma_irq, (void *)substream); + + } else { + channel = mxc_dma_request(prtd->dma_ch, "ALSA RX SDMA"); + if (channel < 0) { + pr_err("imx-pcm: error requesting \ + a read dma channel\n"); + return channel; + } + ret = mxc_dma_callback_set(channel, (mxc_dma_callback_t) + audio_dma_irq, (void *)substream); + } + prtd->dma_wchannel = channel; + prtd->dma_alloc = 1; + + prtd->period = 0; + prtd->periods = 0; + return 0; +} + +static int imx_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct mxc_runtime_data *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + + prtd->dma_ch = imx_get_sdma_transfer(params_format(params), + rtd->dai->cpu_dai->id, + substream->stream); + + if (prtd->dma_ch < 0) { + printk(KERN_ERR "imx-pcm: invaild sdma transfer type"); + return -1; + } + + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + + return 0; +} + +static int imx_pcm_hw_free(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct mxc_runtime_data *prtd = runtime->private_data; + + if (prtd->dma_wchannel) { + mxc_dma_free(prtd->dma_wchannel); + prtd->dma_wchannel = 0; + prtd->dma_alloc = 0; + } + + return 0; +} + +static int imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) +{ + struct mxc_runtime_data *prtd = substream->runtime->private_data; + int ret = 0; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + prtd->dma_active = 0; + prtd->active = 1; + ret = dma_new_period(substream); + ret = dma_new_period(substream); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + prtd->active = 0; + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static snd_pcm_uframes_t imx_pcm_pointer(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct mxc_runtime_data *prtd = runtime->private_data; + unsigned int offset = 0; + + offset = (runtime->period_size * (prtd->periods)); + if (offset >= runtime->buffer_size) + offset = 0; + dbg("pointer offset %x\n", offset); + + return offset; +} + +static int imx_pcm_open(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct mxc_runtime_data *prtd; + int ret; + + snd_soc_set_runtime_hwparams(substream, &imx_pcm_hardware); + + ret = snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); + if (ret < 0) + return ret; + + prtd = kzalloc(sizeof(struct mxc_runtime_data), GFP_KERNEL); + if (prtd == NULL) + return -ENOMEM; + + runtime->private_data = prtd; + return 0; +} + +static int imx_pcm_close(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct mxc_runtime_data *prtd = runtime->private_data; + + kfree(prtd); + return 0; +} + +static int +imx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_dai *cpu_dai = socdev->machine->dai_link->cpu_dai; + struct mxc_audio_platform_data *dev_data = cpu_dai->private_data; + int ext_ram = 0; + int ret = 0; + + dbg("+imx_pcm_mmap:" + "UseIram=%d dma_addr=%x dma_area=%x dma_bytes=%d\n", + UseIram, (unsigned int)runtime->dma_addr, + runtime->dma_area, runtime->dma_bytes); + + if (dev_data) + ext_ram = dev_data->ext_ram; + + if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) || ext_ram + || !UseIram) { + ret = dma_mmap_writecombine(substream->pcm->card->dev, vma, + runtime->dma_area, + runtime->dma_addr, + runtime->dma_bytes); + return ret; + } else + return imx_iram_audio_playback_mmap(substream, vma); +} + +struct snd_pcm_ops imx_pcm_ops = { + .open = imx_pcm_open, + .close = imx_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = imx_pcm_hw_params, + .hw_free = imx_pcm_hw_free, + .prepare = imx_pcm_prepare, + .trigger = imx_pcm_trigger, + .pointer = imx_pcm_pointer, + .mmap = imx_pcm_mmap, +}; + +static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) +{ + struct snd_pcm_substream *substream = pcm->streams[stream].substream; + struct snd_dma_buffer *buf = &substream->dma_buffer; + struct snd_soc_pcm_runtime *rtd = pcm->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_dai *cpu_dai = socdev->machine->dai_link->cpu_dai; + struct mxc_audio_platform_data *dev_data = cpu_dai->private_data; + int ext_ram = 0; + size_t size = imx_pcm_hardware.buffer_bytes_max; + + if (dev_data) + ext_ram = dev_data->ext_ram; + + buf->dev.type = SNDRV_DMA_TYPE_DEV; + buf->dev.dev = pcm->card->dev; + buf->private_data = NULL; + + if ((stream == SNDRV_PCM_STREAM_CAPTURE) || ext_ram || !UseIram) + buf->area = dma_alloc_writecombine(pcm->card->dev, size, + &buf->addr, GFP_KERNEL); + else + buf->area = imx_iram_init(&buf->addr, size); + + if (!buf->area) + return -ENOMEM; + buf->bytes = size; + printk(KERN_INFO "DMA Sound Buffers Allocated:" + "UseIram=%d buf->addr=%x buf->area=%p size=%d\n", + UseIram, buf->addr, buf->area, size); + return 0; +} + +static void imx_pcm_free_dma_buffers(struct snd_pcm *pcm) +{ + struct snd_pcm_substream *substream; + struct snd_dma_buffer *buf; + struct snd_soc_pcm_runtime *rtd = pcm->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_dai *cpu_dai = socdev->machine->dai_link->cpu_dai; + struct mxc_audio_platform_data *dev_data = cpu_dai->private_data; + int ext_ram = 0; + int stream; + + if (dev_data) + ext_ram = dev_data->ext_ram; + + for (stream = 0; stream < 2; stream++) { + substream = pcm->streams[stream].substream; + if (!substream) + continue; + + buf = &substream->dma_buffer; + if (!buf->area) + continue; + + if ((stream == SNDRV_PCM_STREAM_CAPTURE) || ext_ram || !UseIram) + dma_free_writecombine(pcm->card->dev, buf->bytes, + buf->area, buf->addr); + else + imx_iram_free(); + buf->area = NULL; + } +} + +static u64 imx_pcm_dmamask = 0xffffffff; + +static int imx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, + struct snd_pcm *pcm) +{ + int ret = 0; + + if (!card->dev->dma_mask) + card->dev->dma_mask = &imx_pcm_dmamask; + if (!card->dev->coherent_dma_mask) + card->dev->coherent_dma_mask = 0xffffffff; + + if (dai->playback.channels_min) { + ret = imx_pcm_preallocate_dma_buffer(pcm, + SNDRV_PCM_STREAM_PLAYBACK); + if (ret) + goto out; + } + + if (dai->capture.channels_min) { + ret = imx_pcm_preallocate_dma_buffer(pcm, + SNDRV_PCM_STREAM_CAPTURE); + if (ret) + goto out; + } +out: + return ret; +} + +struct snd_soc_platform imx_soc_platform = { + .name = "imx-audio", + .pcm_ops = &imx_pcm_ops, + .pcm_new = imx_pcm_new, + .pcm_free = imx_pcm_free_dma_buffers, +}; +EXPORT_SYMBOL_GPL(imx_soc_platform); + +MODULE_AUTHOR("Liam Girdwood"); +MODULE_DESCRIPTION("Freescale i.MX3x PCM DMA module"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/sound/soc/imx/imx-ssi.c +++ linux-2.6.28/sound/soc/imx/imx-ssi.c @@ -0,0 +1,766 @@ +/* + * imx-ssi.c -- SSI driver for Freescale IMX + * + * Copyright 2006 Wolfson Microelectronics PLC. + * Author: Liam Girdwood + * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com + * + * Based on mxc-alsa-mc13783 (C) 2006-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. + * + * Revision history + * 29th Aug 2006 Initial version. + * + * TODO: + * Need to rework SSI register defs when new defs go into mainline. + * Add support for TDM and FIFO 1. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "imx-ssi.h" +#include "imx-pcm.h" + +/* debug */ +#define IMX_SSI_DEBUG 0 +#if IMX_SSI_DEBUG +#define dbg(format, arg...) printk(format, ## arg) +#else +#define dbg(format, arg...) +#endif + +#define IMX_SSI_DUMP 0 +#if IMX_SSI_DUMP +#define SSI_DUMP() \ + do { \ + printk(KERN_INFO "dump @ %s\n", __func__); \ + printk(KERN_INFO "scr %x\t, %x\n", \ + __raw_readl(SSI1_SCR), __raw_readl(SSI2_SCR)); \ + printk(KERN_INFO "sisr %x\t, %x\n", \ + __raw_readl(SSI1_SISR), __raw_readl(SSI2_SISR)); \ + printk(KERN_INFO "stcr %x\t, %x\n", \ + __raw_readl(SSI1_STCR), __raw_readl(SSI2_STCR)); \ + printk(KERN_INFO "srcr %x\t, %x\n", \ + __raw_readl(SSI1_SRCR), __raw_readl(SSI2_SRCR)); \ + printk(KERN_INFO "stccr %x\t, %x\n", \ + __raw_readl(SSI1_STCCR), __raw_readl(SSI2_STCCR)); \ + printk(KERN_INFO "srccr %x\t, %x\n", \ + __raw_readl(SSI1_SRCCR), __raw_readl(SSI2_SRCCR)); \ + printk(KERN_INFO "sfcsr %x\t, %x\n", \ + __raw_readl(SSI1_SFCSR), __raw_readl(SSI2_SFCSR)); \ + printk(KERN_INFO "stmsk %x\t, %x\n", \ + __raw_readl(SSI1_STMSK), __raw_readl(SSI2_STMSK)); \ + printk(KERN_INFO "srmsk %x\t, %x\n", \ + __raw_readl(SSI1_SRMSK), __raw_readl(SSI2_SRMSK)); \ + printk(KERN_INFO "sier %x\t, %x\n", \ + __raw_readl(SSI1_SIER), __raw_readl(SSI2_SIER)); \ + } while (0); +#else +#define SSI_DUMP() +#endif + +#define SSI1_PORT 0 +#define SSI2_PORT 1 + +static int ssi_active[2] = { 0, 0 }; + +/* + * SSI system clock configuration. + * Should only be called when port is inactive (i.e. SSIEN = 0). + */ +static int imx_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai, + int clk_id, unsigned int freq, int dir) +{ + u32 scr; + + if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI1) + scr = __raw_readl(SSI1_SCR); + else + scr = __raw_readl(SSI2_SCR); + + if (scr & SSI_SCR_SSIEN) + return 0; + + switch (clk_id) { + case IMX_SSP_SYS_CLK: + if (dir == SND_SOC_CLOCK_OUT) + scr |= SSI_SCR_SYS_CLK_EN; + else + scr &= ~SSI_SCR_SYS_CLK_EN; + break; + default: + return -EINVAL; + } + + if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI1) + __raw_writel(scr, SSI1_SCR); + else + __raw_writel(scr, SSI2_SCR); + + return 0; +} + +/* + * SSI Clock dividers + * Should only be called when port is inactive (i.e. SSIEN = 0). + */ +static int imx_ssi_set_dai_clkdiv(struct snd_soc_dai *cpu_dai, + int div_id, int div) +{ + u32 stccr, srccr; + + if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI1) { + if (__raw_readl(SSI1_SCR) & SSI_SCR_SSIEN) + return 0; + + srccr = __raw_readl(SSI1_SRCCR); + stccr = __raw_readl(SSI1_STCCR); + } else { + if (__raw_readl(SSI2_SCR) & SSI_SCR_SSIEN) + return 0; + + srccr = __raw_readl(SSI2_SRCCR); + stccr = __raw_readl(SSI2_STCCR); + } + + switch (div_id) { + case IMX_SSI_TX_DIV_2: + stccr &= ~SSI_STCCR_DIV2; + stccr |= div; + break; + case IMX_SSI_TX_DIV_PSR: + stccr &= ~SSI_STCCR_PSR; + stccr |= div; + break; + case IMX_SSI_TX_DIV_PM: + stccr &= ~0xff; + stccr |= SSI_STCCR_PM(div); + break; + case IMX_SSI_RX_DIV_2: + stccr &= ~SSI_STCCR_DIV2; + stccr |= div; + break; + case IMX_SSI_RX_DIV_PSR: + stccr &= ~SSI_STCCR_PSR; + stccr |= div; + break; + case IMX_SSI_RX_DIV_PM: + stccr &= ~0xff; + stccr |= SSI_STCCR_PM(div); + break; + default: + return -EINVAL; + } + + if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI1) { + __raw_writel(stccr, SSI1_STCCR); + __raw_writel(srccr, SSI1_SRCCR); + } else { + __raw_writel(stccr, SSI2_STCCR); + __raw_writel(srccr, SSI2_SRCCR); + } + return 0; +} + +/* + * SSI Network Mode or TDM slots configuration. + * Should only be called when port is inactive (i.e. SSIEN = 0). + */ +static int imx_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, + unsigned int mask, int slots) +{ + u32 stmsk, srmsk, stccr; + + if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI1) { + if (__raw_readl(SSI1_SCR) & SSI_SCR_SSIEN) + return 0; + stccr = __raw_readl(SSI1_STCCR); + } else { + if (__raw_readl(SSI2_SCR) & SSI_SCR_SSIEN) + return 0; + stccr = __raw_readl(SSI2_STCCR); + } + + stmsk = srmsk = mask; + stccr &= ~SSI_STCCR_DC_MASK; + stccr |= SSI_STCCR_DC(slots - 1); + + if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI1) { + __raw_writel(stmsk, SSI1_STMSK); + __raw_writel(srmsk, SSI1_SRMSK); + __raw_writel(stccr, SSI1_STCCR); + __raw_writel(stccr, SSI1_SRCCR); + } else { + __raw_writel(stmsk, SSI2_STMSK); + __raw_writel(srmsk, SSI2_SRMSK); + __raw_writel(stccr, SSI2_STCCR); + __raw_writel(stccr, SSI2_SRCCR); + } + + return 0; +} + +/* + * SSI DAI format configuration. + * Should only be called when port is inactive (i.e. SSIEN = 0). + * Note: We don't use the I2S modes but instead manually configure the + * SSI for I2S. + */ +static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) +{ + u32 stcr = 0, srcr = 0, scr; + + if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI1) + scr = __raw_readl(SSI1_SCR) & ~(SSI_SCR_SYN | SSI_SCR_NET); + else + scr = __raw_readl(SSI2_SCR) & ~(SSI_SCR_SYN | SSI_SCR_NET); + + if (scr & SSI_SCR_SSIEN) + return 0; + + /* DAI mode */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + /* data on rising edge of bclk, frame low 1clk before data */ + stcr |= SSI_STCR_TFSI | SSI_STCR_TEFS | SSI_STCR_TXBIT0; + srcr |= SSI_SRCR_RFSI | SSI_SRCR_REFS | SSI_SRCR_RXBIT0; + break; + case SND_SOC_DAIFMT_LEFT_J: + /* data on rising edge of bclk, frame high with data */ + stcr |= SSI_STCR_TXBIT0; + srcr |= SSI_SRCR_RXBIT0; + break; + case SND_SOC_DAIFMT_DSP_B: + /* data on rising edge of bclk, frame high with data */ + stcr |= SSI_STCR_TFSL; + srcr |= SSI_SRCR_RFSL; + break; + case SND_SOC_DAIFMT_DSP_A: + /* data on rising edge of bclk, frame high 1clk before data */ + stcr |= SSI_STCR_TFSL | SSI_STCR_TEFS; + srcr |= SSI_SRCR_RFSL | SSI_SRCR_REFS; + break; + } + + /* DAI clock inversion */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_IB_IF: + stcr &= ~(SSI_STCR_TSCKP | SSI_STCR_TFSI); + srcr &= ~(SSI_SRCR_RSCKP | SSI_SRCR_RFSI); + break; + case SND_SOC_DAIFMT_IB_NF: + stcr |= SSI_STCR_TFSI; + stcr &= ~SSI_STCR_TSCKP; + srcr |= SSI_SRCR_RFSI; + srcr &= ~SSI_SRCR_RSCKP; + break; + case SND_SOC_DAIFMT_NB_IF: + stcr &= ~SSI_STCR_TFSI; + stcr |= SSI_STCR_TSCKP; + srcr &= ~SSI_SRCR_RFSI; + srcr |= SSI_SRCR_RSCKP; + break; + case SND_SOC_DAIFMT_NB_NF: + stcr |= SSI_STCR_TFSI | SSI_STCR_TSCKP; + srcr |= SSI_SRCR_RFSI | SSI_SRCR_RSCKP; + break; + } + + /* DAI clock master masks */ + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + stcr |= SSI_STCR_TFDIR | SSI_STCR_TXDIR; + srcr |= SSI_SRCR_RFDIR | SSI_SRCR_RXDIR; + if (((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S) + && (fmt & SND_SOC_DAIFMT_TDM)) { + scr &= ~SSI_SCR_I2S_MODE_MASK; + scr |= SSI_SCR_I2S_MODE_MSTR; + } + break; + case SND_SOC_DAIFMT_CBM_CFS: + stcr |= SSI_STCR_TFDIR; + srcr |= SSI_SRCR_RFDIR; + break; + case SND_SOC_DAIFMT_CBS_CFM: + stcr |= SSI_STCR_TXDIR; + srcr |= SSI_SRCR_RXDIR; + break; + case SND_SOC_DAIFMT_CBM_CFM: + if (((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S) + && (fmt & SND_SOC_DAIFMT_TDM)) { + scr &= ~SSI_SCR_I2S_MODE_MASK; + scr |= SSI_SCR_I2S_MODE_SLAVE; + } + break; + } + + /* sync */ + if (!(fmt & SND_SOC_DAIFMT_ASYNC)) + scr |= SSI_SCR_SYN; + + /* tdm - only for stereo atm */ + if (fmt & SND_SOC_DAIFMT_TDM) + scr |= SSI_SCR_NET; + + if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI1) { + __raw_writel(stcr, SSI1_STCR); + __raw_writel(srcr, SSI1_SRCR); + __raw_writel(scr, SSI1_SCR); + } else { + __raw_writel(stcr, SSI2_STCR); + __raw_writel(srcr, SSI2_SRCR); + __raw_writel(scr, SSI2_SCR); + } + SSI_DUMP(); + return 0; +} + +static struct clk *ssi1_clk; +static struct clk *ssi2_clk; + +static int imx_ssi_startup(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + + /* we cant really change any SSI values after SSI is enabled + * need to fix in software for max flexibility - lrg */ + if (cpu_dai->playback.active || cpu_dai->capture.active) + return 0; + + /* reset the SSI port - Sect 45.4.4 */ + if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI1) { + + if (ssi_active[SSI1_PORT]++) + return 0; + + __raw_writel(0, SSI1_SCR); + ssi1_clk = clk_get(NULL, "ssi_clk.0"); + clk_enable(ssi1_clk); + + /* BIG FAT WARNING + * SDMA FIFO watermark must == SSI FIFO watermark for + * best results. + */ + __raw_writel((SSI_SFCSR_RFWM1(SSI_RXFIFO_WATERMARK) | + SSI_SFCSR_RFWM0(SSI_RXFIFO_WATERMARK) | + SSI_SFCSR_TFWM1(SSI_TXFIFO_WATERMARK) | + SSI_SFCSR_TFWM0(SSI_TXFIFO_WATERMARK)), + SSI1_SFCSR); + __raw_writel(0, SSI1_SIER); + } else { + + if (ssi_active[SSI2_PORT]++) + return 0; + + __raw_writel(0, SSI2_SCR); + ssi2_clk = clk_get(NULL, "ssi_clk.1"); + clk_enable(ssi2_clk); + /* above warning applies here too */ + __raw_writel((SSI_SFCSR_RFWM1(SSI_RXFIFO_WATERMARK) | + SSI_SFCSR_RFWM0(SSI_RXFIFO_WATERMARK) | + SSI_SFCSR_TFWM1(SSI_TXFIFO_WATERMARK) | + SSI_SFCSR_TFWM0(SSI_TXFIFO_WATERMARK)), + SSI2_SFCSR); + __raw_writel(0, SSI2_SIER); + } + + SSI_DUMP(); + return 0; +} + +static int imx_ssi_hw_tx_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + u32 stccr, stcr, sier; + + if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI1) { + stccr = __raw_readl(SSI1_STCCR) & ~SSI_STCCR_WL_MASK; + stcr = __raw_readl(SSI1_STCR); + sier = __raw_readl(SSI1_SIER); + } else { + stccr = __raw_readl(SSI2_STCCR) & ~SSI_STCCR_WL_MASK; + stcr = __raw_readl(SSI2_STCR); + sier = __raw_readl(SSI2_SIER); + } + + /* DAI data (word) size */ + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + stccr |= SSI_STCCR_WL(16); + break; + case SNDRV_PCM_FORMAT_S20_3LE: + stccr |= SSI_STCCR_WL(20); + break; + case SNDRV_PCM_FORMAT_S24_LE: + stccr |= SSI_STCCR_WL(24); + break; + } + + /* enable interrupts */ + if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) + stcr |= SSI_STCR_TFEN0; + else + stcr |= SSI_STCR_TFEN1; + sier |= SSI_SIER_TDMAE | SSI_SIER_TIE | SSI_SIER_TUE0_EN; + + if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI1) { + __raw_writel(stcr, SSI1_STCR); + __raw_writel(stccr, SSI1_STCCR); + __raw_writel(sier, SSI1_SIER); + } else { + __raw_writel(stcr, SSI2_STCR); + __raw_writel(stccr, SSI2_STCCR); + __raw_writel(sier, SSI2_SIER); + } + + return 0; +} + +static int imx_ssi_hw_rx_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + u32 srccr, srcr, sier; + bool sync_mode; + + if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI1) { + sync_mode = + (__raw_readl(SSI1_SCR) & SSI_SCR_SYN) ? true : false; + srccr = + sync_mode ? __raw_readl(SSI1_STCCR) : + __raw_readl(SSI1_SRCCR); + srcr = __raw_readl(SSI1_SRCR); + sier = __raw_readl(SSI1_SIER); + } else { + sync_mode = + (__raw_readl(SSI2_SCR) & SSI_SCR_SYN) ? true : false; + srccr = + sync_mode ? __raw_readl(SSI2_STCCR) : + __raw_readl(SSI2_SRCCR); + srcr = __raw_readl(SSI2_SRCR); + sier = __raw_readl(SSI2_SIER); + } + srccr &= ~SSI_SRCCR_WL_MASK; + + /* DAI data (word) size */ + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + srccr |= SSI_SRCCR_WL(16); + break; + case SNDRV_PCM_FORMAT_S20_3LE: + srccr |= SSI_SRCCR_WL(20); + break; + case SNDRV_PCM_FORMAT_S24_LE: + srccr |= SSI_SRCCR_WL(24); + break; + } + + /* enable interrupts */ + if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) + srcr |= SSI_SRCR_RFEN0; + else + srcr |= SSI_SRCR_RFEN1; + sier |= SSI_SIER_RDMAE | SSI_SIER_RIE | SSI_SIER_ROE0_EN; + + if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI1) { + __raw_writel(srcr, SSI1_SRCR); + if (sync_mode) + __raw_writel(srccr, SSI1_STCCR); + else + __raw_writel(srccr, SSI1_SRCCR); + __raw_writel(sier, SSI1_SIER); + } else { + __raw_writel(srcr, SSI2_SRCR); + if (sync_mode) + __raw_writel(srccr, SSI2_STCCR); + else + __raw_writel(srccr, SSI2_SRCCR); + __raw_writel(sier, SSI2_SIER); + } + return 0; +} + +/* + * Should only be called when port is inactive (i.e. SSIEN = 0), + * although can be called multiple times by upper layers. + */ +static int imx_ssi_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + int id; + + id = cpu_dai->id; + + /* Tx/Rx config */ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + /* cant change any parameters when SSI is running */ + if (id == IMX_DAI_SSI0 || id == IMX_DAI_SSI1) { + if ((__raw_readl(SSI1_SCR) & SSI_SCR_SSIEN) && + (__raw_readl(SSI1_SCR) & SSI_SCR_TE)) + return 0; + } else { + if ((__raw_readl(SSI2_SCR) & SSI_SCR_SSIEN) && + (__raw_readl(SSI2_SCR) & SSI_SCR_TE)) + return 0; + } + return imx_ssi_hw_tx_params(substream, params); + } else { + /* cant change any parameters when SSI is running */ + if (id == IMX_DAI_SSI0 || id == IMX_DAI_SSI1) { + if ((__raw_readl(SSI1_SCR) & SSI_SCR_SSIEN) && + (__raw_readl(SSI1_SCR) & SSI_SCR_RE)) + return 0; + } else { + if ((__raw_readl(SSI2_SCR) & SSI_SCR_SSIEN) && + (__raw_readl(SSI2_SCR) & SSI_SCR_RE)) + return 0; + } + return imx_ssi_hw_rx_params(substream, params); + } +} + +static int imx_ssi_prepare(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + u32 scr; + + /* enable the SSI port, note that no other port config + * should happen after SSIEN is set */ + if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI1) { + scr = __raw_readl(SSI1_SCR); + __raw_writel((scr | SSI_SCR_SSIEN), SSI1_SCR); + } else { + scr = __raw_readl(SSI2_SCR); + __raw_writel((scr | SSI_SCR_SSIEN), SSI2_SCR); + } + SSI_DUMP(); + return 0; +} + +static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + u32 scr; + + if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI1) + scr = __raw_readl(SSI1_SCR); + else + scr = __raw_readl(SSI2_SCR); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + scr |= SSI_SCR_TE; + else + scr |= SSI_SCR_RE; + break; + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + scr &= ~SSI_SCR_TE; + else + scr &= ~SSI_SCR_RE; + break; + default: + return -EINVAL; + } + if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI1) + __raw_writel(scr, SSI1_SCR); + else + __raw_writel(scr, SSI2_SCR); + + SSI_DUMP(); + return 0; +} + +static void imx_ssi_shutdown(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + int id; + + id = cpu_dai->id; + + /* shutdown SSI if neither Tx or Rx is active */ + if (cpu_dai->playback.active || cpu_dai->capture.active) + return; + + if (id == IMX_DAI_SSI0 || id == IMX_DAI_SSI1) { + + if (--ssi_active[SSI1_PORT] > 1) + return; + + __raw_writel(0, SSI1_SCR); + + clk_disable(ssi1_clk); + clk_put(ssi1_clk); + + } else { + if (--ssi_active[SSI2_PORT]) + return; + __raw_writel(0, SSI2_SCR); + clk_disable(ssi2_clk); + clk_put(ssi2_clk); + } +} + +#ifdef CONFIG_PM +static int imx_ssi_suspend(struct platform_device *dev, struct snd_soc_dai *dai) +{ + if (!dai->active) + return 0; + + /* do we need to disable any clocks? */ + + return 0; +} + +static int imx_ssi_resume(struct platform_device *dev, struct snd_soc_dai *dai) +{ + if (!dai->active) + return 0; + + /* do we need to enable any clocks? */ + + return 0; +} +#else +#define imx_ssi_suspend NULL +#define imx_ssi_resume NULL +#endif + +static int fifo_err_counter; + +static irqreturn_t ssi1_irq(int irq, void *dev_id) +{ + if (fifo_err_counter++ % 1000 == 0) + printk(KERN_ERR "ssi1_irq SISR %x SIER %x fifo_errs=%d\n", + __raw_readl(SSI1_SISR), __raw_readl(SSI1_SIER), + fifo_err_counter); + __raw_writel((SSI_SIER_TUE0_EN | SSI_SIER_ROE0_EN), SSI1_SISR); + return IRQ_HANDLED; +} + +static irqreturn_t ssi2_irq(int irq, void *dev_id) +{ + if (fifo_err_counter++ % 1000 == 0) + printk(KERN_ERR "ssi2_irq SISR %x SIER %x fifo_errs=%d\n", + __raw_readl(SSI2_SISR), __raw_readl(SSI2_SIER), + fifo_err_counter); + __raw_writel((SSI_SIER_TUE0_EN | SSI_SIER_ROE0_EN), SSI2_SISR); + return IRQ_HANDLED; +} + +static int imx_ssi_probe(struct platform_device *pdev, struct snd_soc_dai *dai) +{ + if (!strcmp(dai->name, "imx-ssi-1")) + dai->id = IMX_DAI_SSI0; + else if (!strcmp(dai->name, "imx-ssi-2")) + dai->id = IMX_DAI_SSI1; + else if (!strcmp(dai->name, "imx-ssi-3")) + dai->id = IMX_DAI_SSI2; + else if (!strcmp(dai->name, "imx-ssi-4")) + dai->id = IMX_DAI_SSI3; + else { + printk(KERN_ERR "%s: invalid device %s\n", __func__, dai->name); + return -ENODEV; + } + + if ((!strcmp(dai->name, "imx-ssi-1")) || + (!strcmp(dai->name, "imx-ssi-2"))) + if (request_irq(MXC_INT_SSI1, ssi1_irq, 0, "ssi1", dai)) { + printk(KERN_ERR "%s: failure requesting irq %s\n", + __func__, "ssi1"); + return -EBUSY; + } + + if ((!strcmp(dai->name, "imx-ssi-3")) || + (!strcmp(dai->name, "imx-ssi-4"))) + if (request_irq(MXC_INT_SSI2, ssi2_irq, 0, "ssi2", dai)) { + printk(KERN_ERR "%s: failure requesting irq %s\n", + __func__, "ssi2"); + return -EBUSY; + } + + return 0; +} + +#define IMX_SSI_RATES \ + (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | \ + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | \ + SNDRV_PCM_RATE_96000) + +#define IMX_SSI_FORMATS \ + (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ + SNDRV_PCM_FMTBIT_S24_LE) + +struct snd_soc_dai imx_ssi_dai = { + .name = "imx-ssi", + .id = 0, + .type = SND_SOC_DAI_PCM, + .probe = imx_ssi_probe, + .suspend = imx_ssi_suspend, + .resume = imx_ssi_resume, + .playback = { + .channels_min = 1, + .channels_max = 2, + .rates = IMX_SSI_RATES, + .formats = IMX_SSI_FORMATS, + }, + .capture = { + .channels_min = 1, + .channels_max = 2, + .rates = IMX_SSI_RATES, + .formats = IMX_SSI_FORMATS, + }, + .ops = { + .startup = imx_ssi_startup, + .shutdown = imx_ssi_shutdown, + .trigger = imx_ssi_trigger, + .prepare = imx_ssi_prepare, + .hw_params = imx_ssi_hw_params, + }, + .dai_ops = { + .set_sysclk = imx_ssi_set_dai_sysclk, + .set_clkdiv = imx_ssi_set_dai_clkdiv, + .set_fmt = imx_ssi_set_dai_fmt, + .set_tdm_slot = imx_ssi_set_dai_tdm_slot, + }, +}; +EXPORT_SYMBOL_GPL(imx_ssi_dai); + +MODULE_AUTHOR + ("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com"); +MODULE_DESCRIPTION("i.MX ASoC I2S driver"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/sound/pci/Kconfig +++ linux-2.6.28/sound/pci/Kconfig @@ -208,7 +208,8 @@ * AuzenTech X-Meridian * Bgears b-Enspirer * Club3D Theatron DTS - * HT-Omega Claro + * HT-Omega Claro (plus) + * HT-Omega Claro halo (XT) * Razer Barracuda AC-1 * Sondigo Inferno @@ -549,6 +550,14 @@ Say Y here to include IDT (Sigmatel) HD-audio codec support in snd-hda-intel driver, such as STAC9200. +config SND_LPIA_HDA_CODEC_SIGMATEL + bool "Build IDT/Sigmatel HD-audio codec support for LPIA" + depends on SND_HDA_INTEL && !SND_HDA_CODEC_SIGMATEL + default y + help + Say Y here to include IDT (Sigmatel) HD-audio codec support in + snd-hda-intel driver, such as STAC9200. + config SND_HDA_CODEC_VIA bool "Build VIA HD-audio codec support" depends on SND_HDA_INTEL @@ -573,6 +582,18 @@ Say Y here to include NVIDIA HDMI HD-audio codec support in snd-hda-intel driver, such as NVIDIA MCP78 HDMI. +config SND_HDA_CODEC_INTELHDMI + bool "Build INTEL HDMI HD-audio codec support" + depends on SND_HDA_INTEL + default y + help + Say Y here to include INTEL HDMI HD-audio codec support in + snd-hda-intel driver, such as Eaglelake integrated HDMI. + +config SND_HDA_ELD + def_bool y + depends on SND_HDA_CODEC_INTELHDMI + config SND_HDA_CODEC_CONEXANT bool "Build Conexant HD-audio codec support" depends on SND_HDA_INTEL --- linux-2.6.28.orig/sound/pci/hda/hda_proc.c +++ linux-2.6.28/sound/pci/hda/hda_proc.c @@ -89,20 +89,28 @@ snd_iprintf(buffer, "\n"); } -static void print_pcm_rates(struct snd_info_buffer *buffer, unsigned int pcm) +void snd_print_pcm_rates(int pcm, char *buf, int buflen) { static unsigned int rates[] = { 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200, 96000, 176400, 192000, 384000 }; - int i; + int i, j; + + for (i = 0, j = 0; i < ARRAY_SIZE(rates); i++) + if (pcm & (1 << i)) + j += snprintf(buf + j, buflen - j, " %d", rates[i]); + + buf[j] = '\0'; /* necessary when j == 0 */ +} +static void print_pcm_rates(struct snd_info_buffer *buffer, unsigned int pcm) +{ + char buf[SND_PRINT_RATES_ADVISED_BUFSIZE]; pcm &= AC_SUPPCM_RATES; snd_iprintf(buffer, " rates [0x%x]:", pcm); - for (i = 0; i < ARRAY_SIZE(rates); i++) - if (pcm & (1 << i)) - snd_iprintf(buffer, " %d", rates[i]); - snd_iprintf(buffer, "\n"); + snd_print_pcm_rates(pcm, buf, sizeof(buf)); + snd_iprintf(buffer, "%s\n", buf); } static void print_pcm_bits(struct snd_info_buffer *buffer, unsigned int pcm) --- linux-2.6.28.orig/sound/pci/hda/patch_realtek.c +++ linux-2.6.28/sound/pci/hda/patch_realtek.c @@ -152,6 +152,7 @@ enum { ALC660VD_3ST, ALC660VD_3ST_DIG, + ALC660VD_ASUS_V1S, ALC861VD_3ST, ALC861VD_3ST_DIG, ALC861VD_6ST_DIG, @@ -228,6 +229,7 @@ ALC883_3ST_6ch_INTEL, ALC888_ASUS_M90V, ALC888_ASUS_EEE1601, + ALC1200_ASUS_P5Q, ALC883_AUTO, ALC883_MODEL_LAST, }; @@ -967,6 +969,7 @@ case 0x10ec0267: case 0x10ec0268: case 0x10ec0269: + case 0x10ec0272: case 0x10ec0660: case 0x10ec0662: case 0x10ec0663: @@ -995,6 +998,7 @@ case 0x10ec0882: case 0x10ec0883: case 0x10ec0885: + case 0x10ec0887: case 0x10ec0889: snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); @@ -6774,12 +6778,15 @@ break; case 0x106b1000: /* iMac 24 */ case 0x106b2800: /* AppleTV */ + case 0x106b3e00: /* iMac 24 Aluminium */ board_config = ALC885_IMAC24; break; + case 0x106b00a0: /* MacBookPro3,1 - Another revision */ case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */ case 0x106b00a4: /* MacbookPro4,1 */ case 0x106b2c00: /* Macbook Pro rev3 */ case 0x106b3600: /* Macbook 3.1 */ + case 0x106b3800: /* MacbookPro4,1 - latter revision */ board_config = ALC885_MBP3; break; default: @@ -6879,6 +6886,8 @@ #define ALC883_DIGOUT_NID 0x06 #define ALC883_DIGIN_NID 0x0a +#define ALC1200_DIGOUT_NID 0x10 + static hda_nid_t alc883_dac_nids[4] = { /* front, rear, clfe, rear_surr */ 0x02, 0x03, 0x04, 0x05 @@ -8408,6 +8417,7 @@ [ALC883_CLEVO_M720] = "clevo-m720", [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515", [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", + [ALC1200_ASUS_P5Q] = "asus-p5q", [ALC883_AUTO] = "auto", }; @@ -8424,11 +8434,15 @@ SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), + SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP), SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), + SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q), SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), + SND_PCI_QUIRK(0x1043, 0x8284, "ASUS Z37E", ALC883_6ST_DIG), SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), + SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC), SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC), SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), @@ -8452,6 +8466,7 @@ SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), + SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG), SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG), SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), @@ -8462,6 +8477,8 @@ SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD), SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), + SND_PCI_QUIRK(0x1734, 0x1107, "FSC AMILO Xi2550", + ALC883_FUJITSU_PI2515), SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515), SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), @@ -8474,6 +8491,8 @@ SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), + SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC), + SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL), SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), {} }; @@ -8768,6 +8787,17 @@ .unsol_event = alc883_eee1601_unsol_event, .init_hook = alc883_eee1601_inithook, }, + [ALC1200_ASUS_P5Q] = { + .mixers = { alc883_base_mixer, alc883_chmode_mixer }, + .init_verbs = { alc883_init_verbs }, + .num_dacs = ARRAY_SIZE(alc883_dac_nids), + .dac_nids = alc883_dac_nids, + .dig_out_nid = ALC1200_DIGOUT_NID, + .dig_in_nid = ALC883_DIGIN_NID, + .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), + .channel_mode = alc883_sixstack_modes, + .input_mux = &alc883_capture_source, + }, }; @@ -10466,6 +10496,8 @@ SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), + SND_PCI_QUIRK(0x104d, 0x9033, "Sony VAIO VGN-SR19XN", + ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", ALC262_TOSHIBA_RX1), SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06), @@ -10473,6 +10505,7 @@ SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA), SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA), + SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO), SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000), SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), @@ -11572,6 +11605,7 @@ SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One", ALC268_ACER_ASPIRE_ONE), SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), + SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL), SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA), SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA), @@ -14169,6 +14203,7 @@ static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { [ALC660VD_3ST] = "3stack-660", [ALC660VD_3ST_DIG] = "3stack-660-digout", + [ALC660VD_ASUS_V1S] = "asus-v1s", [ALC861VD_3ST] = "3stack", [ALC861VD_3ST_DIG] = "3stack-digout", [ALC861VD_6ST_DIG] = "6stack-digout", @@ -14183,7 +14218,7 @@ SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), - SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC861VD_LENOVO), + SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S), SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), @@ -14290,6 +14325,21 @@ .unsol_event = alc861vd_dallas_unsol_event, .init_hook = alc861vd_dallas_automute, }, + [ALC660VD_ASUS_V1S] = { + .mixers = { alc861vd_lenovo_mixer }, + .init_verbs = { alc861vd_volume_init_verbs, + alc861vd_3stack_init_verbs, + alc861vd_eapd_verbs, + alc861vd_lenovo_unsol_verbs }, + .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), + .dac_nids = alc660vd_dac_nids, + .dig_out_nid = ALC861VD_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), + .channel_mode = alc861vd_3stack_2ch_modes, + .input_mux = &alc861vd_capture_source, + .unsol_event = alc861vd_lenovo_unsol_event, + .init_hook = alc861vd_lenovo_automute, + }, }; /* @@ -16478,9 +16528,9 @@ .patch = patch_alc882 }, /* should be patch_alc883() in future */ { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 }, - { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 }, { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", .patch = patch_alc883 }, + { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 }, { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 }, {} /* terminator */ }; --- linux-2.6.28.orig/sound/pci/hda/lpia_ubuntu_patch_sigmatel.c +++ linux-2.6.28/sound/pci/hda/lpia_ubuntu_patch_sigmatel.c @@ -0,0 +1,5683 @@ +/* + * Universal Interface for Intel High Definition Audio Codec + * + * HD audio interface patch for SigmaTel STAC92xx + * + * Copyright (c) 2005 Embedded Alley Solutions, Inc. + * Matt Porter + * + * Based on patch_cmedia.c and patch_realtek.c + * Copyright (c) 2004 Takashi Iwai + * + * This driver is free software; you can redistribute it and/or modify + * it under the terms of the 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 driver is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You 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 "hda_codec.h" +#include "hda_local.h" +#include "hda_patch.h" +#include "hda_beep.h" + +#define dbg(f, x...) \ + printk(KERN_ALERT " [%s()]: " f "\n", __func__,## x) + +#define NUM_CONTROL_ALLOC 32 + +#define STAC_VREF_EVENT 0x00 +#define STAC_INSERT_EVENT 0x10 +#define STAC_PWR_EVENT 0x20 +#define STAC_HP_EVENT 0x30 + +enum { + STAC_REF, + STAC_9200_OQO, + STAC_9200_DELL_D21, + STAC_9200_DELL_D22, + STAC_9200_DELL_D23, + STAC_9200_DELL_M21, + STAC_9200_DELL_M22, + STAC_9200_DELL_M23, + STAC_9200_DELL_M24, + STAC_9200_DELL_M25, + STAC_9200_DELL_M26, + STAC_9200_DELL_M27, + STAC_9200_M4, + STAC_9200_M4_2, + STAC_9200_PANASONIC, + STAC_9200_MODELS +}; + +enum { + STAC_9202_REF, + STAC_9202_TEST1, + STAC_9202_MODELS +}; + +enum { + STAC_9205_REF, + STAC_9205_DELL_M42, + STAC_9205_DELL_M43, + STAC_9205_DELL_M44, + STAC_9205_MODELS +}; + +enum { + STAC_92HD73XX_NO_JD, /* no jack-detection */ + STAC_92HD73XX_REF, + STAC_DELL_M6_AMIC, + STAC_DELL_M6_DMIC, + STAC_DELL_M6_BOTH, + STAC_DELL_EQ, + STAC_92HD73XX_MODELS +}; + +enum { + STAC_92HD83XXX_REF, + STAC_92HD83XXX_MODELS +}; + +enum { + STAC_92HD71BXX_REF, + STAC_DELL_M4_1, + STAC_DELL_M4_2, + STAC_DELL_M4_3, + STAC_HP_M4, + STAC_HP_DV5, + STAC_92HD71BXX_MODELS +}; + +enum { + STAC_925x_REF, + STAC_M1, + STAC_M1_2, + STAC_M2, + STAC_M2_2, + STAC_M3, + STAC_M5, + STAC_M6, + STAC_925x_MODELS +}; + +enum { + STAC_D945_REF, + STAC_D945GTP3, + STAC_D945GTP5, + STAC_INTEL_MAC_V1, + STAC_INTEL_MAC_V2, + STAC_INTEL_MAC_V3, + STAC_INTEL_MAC_V4, + STAC_INTEL_MAC_V5, + STAC_INTEL_MAC_AUTO, /* This model is selected if no module parameter + * is given, one of the above models will be + * chosen according to the subsystem id. */ + /* for backward compatibility */ + STAC_MACMINI, + STAC_MACBOOK, + STAC_MACBOOK_PRO_V1, + STAC_MACBOOK_PRO_V2, + STAC_IMAC_INTEL, + STAC_IMAC_INTEL_20, + STAC_ECS_202, + STAC_922X_DELL_D81, + STAC_922X_DELL_D82, + STAC_922X_DELL_M81, + STAC_922X_DELL_M82, + STAC_922X_MODELS +}; + +enum { + STAC_D965_REF_NO_JD, /* no jack-detection */ + STAC_D965_REF, + STAC_D965_3ST, + STAC_D965_5ST, + STAC_DELL_3ST, + STAC_DELL_BIOS, + STAC_927X_MODELS +}; + +struct sigmatel_spec { + struct snd_kcontrol_new *mixers[4]; + unsigned int num_mixers; + + int board_config; + unsigned int eapd_switch: 1; + unsigned int surr_switch: 1; + unsigned int line_switch: 1; + unsigned int mic_switch: 1; + unsigned int alt_switch: 1; + unsigned int hp_detect: 1; + unsigned int spdif_mute: 1; + + /* gpio lines */ + unsigned int eapd_mask; + unsigned int gpio_mask; + unsigned int gpio_dir; + unsigned int gpio_data; + unsigned int gpio_mute; + + /* stream */ + unsigned int stream_delay; + + /* analog loopback */ + unsigned char aloopback_mask; + unsigned char aloopback_shift; + + /* power management */ + unsigned int num_pwrs; + unsigned int *pwr_mapping; + hda_nid_t *pwr_nids; + hda_nid_t *dac_list; + + /* playback */ + struct hda_input_mux *mono_mux; + struct hda_input_mux *amp_mux; + unsigned int cur_mmux; + struct hda_multi_out multiout; + hda_nid_t dac_nids[5]; + + /* capture */ + hda_nid_t *adc_nids; + unsigned int num_adcs; + hda_nid_t *mux_nids; + unsigned int num_muxes; + hda_nid_t *dmic_nids; + unsigned int num_dmics; + hda_nid_t *dmux_nids; + unsigned int num_dmuxes; + hda_nid_t *smux_nids; + unsigned int num_smuxes; + const char **spdif_labels; + + hda_nid_t dig_in_nid; + hda_nid_t mono_nid; + hda_nid_t anabeep_nid; + hda_nid_t digbeep_nid; + + /* pin widgets */ + hda_nid_t *pin_nids; + unsigned int num_pins; + unsigned int *pin_configs; + unsigned int *bios_pin_configs; + + /* codec specific stuff */ + struct hda_verb *init; + struct snd_kcontrol_new *mixer; + + /* capture source */ + struct hda_input_mux *dinput_mux; + unsigned int cur_dmux[2]; + struct hda_input_mux *input_mux; + unsigned int cur_mux[3]; + struct hda_input_mux *sinput_mux; + unsigned int cur_smux[2]; + unsigned int cur_amux; + hda_nid_t *amp_nids; + unsigned int num_amps; + unsigned int powerdown_adcs; + + /* i/o switches */ + unsigned int io_switch[2]; + unsigned int clfe_swap; + unsigned int hp_switch; /* NID of HP as line-out */ + unsigned int aloopback; + + struct hda_pcm pcm_rec[2]; /* PCM information */ + + /* dynamic controls and input_mux */ + struct auto_pin_cfg autocfg; + unsigned int num_kctl_alloc, num_kctl_used; + struct snd_kcontrol_new *kctl_alloc; + struct hda_input_mux private_dimux; + struct hda_input_mux private_imux; + struct hda_input_mux private_smux; + struct hda_input_mux private_amp_mux; + struct hda_input_mux private_mono_mux; +}; + +static hda_nid_t stac9200_adc_nids[1] = { + 0x03, +}; + +static hda_nid_t stac9200_mux_nids[1] = { + 0x0c, +}; + +static hda_nid_t stac9200_dac_nids[1] = { + 0x02, +}; + +static hda_nid_t stac92hd73xx_pwr_nids[8] = { + 0x0a, 0x0b, 0x0c, 0xd, 0x0e, + 0x0f, 0x10, 0x11 +}; + +static hda_nid_t stac92hd73xx_slave_dig_outs[2] = { + 0x26, 0, +}; + +static hda_nid_t stac92hd73xx_adc_nids[2] = { + 0x1a, 0x1b +}; + +#define DELL_M6_AMP 2 +static hda_nid_t stac92hd73xx_amp_nids[3] = { + 0x0b, 0x0c, 0x0e +}; + +#define STAC92HD73XX_NUM_DMICS 2 +static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = { + 0x13, 0x14, 0 +}; + +#define STAC92HD73_DAC_COUNT 5 +static hda_nid_t stac92hd73xx_dac_nids[STAC92HD73_DAC_COUNT] = { + 0x15, 0x16, 0x17, 0x18, 0x19, +}; + +static hda_nid_t stac92hd73xx_mux_nids[4] = { + 0x28, 0x29, 0x2a, 0x2b, +}; + +static hda_nid_t stac92hd73xx_dmux_nids[2] = { + 0x20, 0x21, +}; + +static hda_nid_t stac92hd73xx_smux_nids[2] = { + 0x22, 0x23, +}; + +#define STAC92HD83XXX_NUM_DMICS 2 +static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = { + 0x11, 0x12, 0 +}; + +#define STAC92HD81_DAC_COUNT 2 +#define STAC92HD83_DAC_COUNT 3 +static hda_nid_t stac92hd83xxx_dac_nids[STAC92HD73_DAC_COUNT] = { + 0x13, 0x14, 0x22, +}; + +static hda_nid_t stac92hd83xxx_dmux_nids[2] = { + 0x17, 0x18, +}; + +static hda_nid_t stac92hd83xxx_adc_nids[2] = { + 0x15, 0x16, +}; + +static hda_nid_t stac92hd83xxx_pwr_nids[4] = { + 0xa, 0xb, 0xd, 0xe, +}; + +static hda_nid_t stac92hd83xxx_slave_dig_outs[2] = { + 0x1e, 0, +}; + +static unsigned int stac92hd83xxx_pwr_mapping[4] = { + 0x03, 0x0c, 0x10, 0x40, +}; + +static hda_nid_t stac92hd71bxx_pwr_nids[3] = { + 0x0a, 0x0d, 0x0f +}; + +static hda_nid_t stac92hd71bxx_adc_nids[2] = { + 0x12, 0x13, +}; + +static hda_nid_t stac92hd71bxx_mux_nids[2] = { + 0x1a, 0x1b +}; + +static hda_nid_t stac92hd71bxx_dmux_nids[2] = { + 0x1c, 0x1d, +}; + +static hda_nid_t stac92hd71bxx_smux_nids[2] = { + 0x24, 0x25, +}; + +static hda_nid_t stac92hd71bxx_dac_nids[1] = { + 0x10, /*0x11, */ +}; + +#define STAC92HD71BXX_NUM_DMICS 2 +static hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = { + 0x18, 0x19, 0 +}; + +static hda_nid_t stac92hd71bxx_slave_dig_outs[2] = { + 0x22, 0 +}; + +static hda_nid_t stac9202_adc_nids[1] = { + 0x03, +}; + +static hda_nid_t stac9202_mux_nids[1] = { + 0x0f, +}; + +static hda_nid_t stac9202_dac_nids[1] = { + 0x02, +}; + +static hda_nid_t stac9202_dmic_nids[2] = { + 0x15, 0 +}; + +static hda_nid_t stac925x_adc_nids[1] = { + 0x03, +}; + +static hda_nid_t stac925x_mux_nids[1] = { + 0x0f, +}; + +static hda_nid_t stac925x_dac_nids[1] = { + 0x02, +}; + +#define STAC925X_NUM_DMICS 1 +static hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = { + 0x15, 0 +}; + +static hda_nid_t stac925x_dmux_nids[1] = { + 0x14, +}; + +static hda_nid_t stac922x_adc_nids[2] = { + 0x06, 0x07, +}; + +static hda_nid_t stac922x_mux_nids[2] = { + 0x12, 0x13, +}; + +static hda_nid_t stac927x_adc_nids[3] = { + 0x07, 0x08, 0x09 +}; + +static hda_nid_t stac927x_mux_nids[3] = { + 0x15, 0x16, 0x17 +}; + +static hda_nid_t stac927x_smux_nids[1] = { + 0x21, +}; + +static hda_nid_t stac927x_dac_nids[6] = { + 0x02, 0x03, 0x04, 0x05, 0x06, 0 +}; + +static hda_nid_t stac927x_dmux_nids[1] = { + 0x1b, +}; + +#define STAC927X_NUM_DMICS 2 +static hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = { + 0x13, 0x14, 0 +}; + +static const char *stac927x_spdif_labels[5] = { + "Digital Playback", "ADAT", "Analog Mux 1", + "Analog Mux 2", "Analog Mux 3" +}; + +static hda_nid_t stac9205_adc_nids[2] = { + 0x12, 0x13 +}; + +static hda_nid_t stac9205_mux_nids[2] = { + 0x19, 0x1a +}; + +static hda_nid_t stac9205_dmux_nids[1] = { + 0x1d, +}; + +static hda_nid_t stac9205_smux_nids[1] = { + 0x21, +}; + +#define STAC9205_NUM_DMICS 2 +static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = { + 0x17, 0x18, 0 +}; + +static hda_nid_t stac9200_pin_nids[8] = { + 0x08, 0x09, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, +}; + +static hda_nid_t stac9202_pin_nids[9] = { + 0x07, 0x08, 0x0a, 0x0d, + 0x0c, 0x0b, 0x10, 0x11, 0x15, +}; + +static hda_nid_t stac925x_pin_nids[8] = { + 0x07, 0x08, 0x0a, 0x0b, + 0x0c, 0x0d, 0x10, 0x11, +}; + +static hda_nid_t stac922x_pin_nids[10] = { + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x15, 0x1b, +}; + +static hda_nid_t stac92hd73xx_pin_nids[13] = { + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, + 0x14, 0x22, 0x23 +}; + +static hda_nid_t stac92hd83xxx_pin_nids[14] = { + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, + 0x1d, 0x1e, 0x1f, 0x20 +}; +static hda_nid_t stac92hd71bxx_pin_nids[11] = { + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x14, 0x18, 0x19, 0x1e, + 0x1f, +}; + +static hda_nid_t stac927x_pin_nids[14] = { + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, + 0x14, 0x21, 0x22, 0x23, +}; + +static hda_nid_t stac9205_pin_nids[12] = { + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x14, 0x16, 0x17, 0x18, + 0x21, 0x22, +}; + +#define stac92xx_amp_volume_info snd_hda_mixer_amp_volume_info + +static int stac92xx_amp_volume_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + hda_nid_t nid = spec->amp_nids[spec->cur_amux]; + + kcontrol->private_value ^= get_amp_nid(kcontrol); + kcontrol->private_value |= nid; + + return snd_hda_mixer_amp_volume_get(kcontrol, ucontrol); +} + +static int stac92xx_amp_volume_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + hda_nid_t nid = spec->amp_nids[spec->cur_amux]; + + kcontrol->private_value ^= get_amp_nid(kcontrol); + kcontrol->private_value |= nid; + + return snd_hda_mixer_amp_volume_put(kcontrol, ucontrol); +} + +static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + return snd_hda_input_mux_info(spec->dinput_mux, uinfo); +} + +static int stac92xx_dmux_enum_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + unsigned int dmux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + + ucontrol->value.enumerated.item[0] = spec->cur_dmux[dmux_idx]; + return 0; +} + +static int stac92xx_dmux_enum_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + unsigned int dmux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + + return snd_hda_input_mux_put(codec, spec->dinput_mux, ucontrol, + spec->dmux_nids[dmux_idx], &spec->cur_dmux[dmux_idx]); +} + +static int stac92xx_smux_enum_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + return snd_hda_input_mux_info(spec->sinput_mux, uinfo); +} + +static int stac92xx_smux_enum_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + + ucontrol->value.enumerated.item[0] = spec->cur_smux[smux_idx]; + return 0; +} + +static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + struct hda_input_mux *smux = &spec->private_smux; + unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + int err, val; + hda_nid_t nid; + + err = snd_hda_input_mux_put(codec, spec->sinput_mux, ucontrol, + spec->smux_nids[smux_idx], &spec->cur_smux[smux_idx]); + if (err < 0) + return err; + + if (spec->spdif_mute) { + if (smux_idx == 0) + nid = spec->multiout.dig_out_nid; + else + nid = codec->slave_dig_outs[smux_idx - 1]; + if (spec->cur_smux[smux_idx] == smux->num_items - 1) + val = AMP_OUT_MUTE; + else + val = AMP_OUT_UNMUTE; + /* un/mute SPDIF out */ + snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_AMP_GAIN_MUTE, val); + } + return 0; +} + +static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + return snd_hda_input_mux_info(spec->input_mux, uinfo); +} + +static int stac92xx_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + + ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; + return 0; +} + +static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + + return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, + spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]); +} + +static int stac92xx_mono_mux_enum_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + return snd_hda_input_mux_info(spec->mono_mux, uinfo); +} + +static int stac92xx_mono_mux_enum_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + + ucontrol->value.enumerated.item[0] = spec->cur_mmux; + return 0; +} + +static int stac92xx_mono_mux_enum_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + + return snd_hda_input_mux_put(codec, spec->mono_mux, ucontrol, + spec->mono_nid, &spec->cur_mmux); +} + +static int stac92xx_amp_mux_enum_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + return snd_hda_input_mux_info(spec->amp_mux, uinfo); +} + +static int stac92xx_amp_mux_enum_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + + ucontrol->value.enumerated.item[0] = spec->cur_amux; + return 0; +} + +static int stac92xx_amp_mux_enum_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + struct snd_kcontrol *ctl = + snd_hda_find_mixer_ctl(codec, "Amp Capture Volume"); + if (!ctl) + return -EINVAL; + + snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE | + SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); + + return snd_hda_input_mux_put(codec, spec->amp_mux, ucontrol, + 0, &spec->cur_amux); +} + +#define stac92xx_aloopback_info snd_ctl_boolean_mono_info + +static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + struct sigmatel_spec *spec = codec->spec; + + ucontrol->value.integer.value[0] = !!(spec->aloopback & + (spec->aloopback_mask << idx)); + return 0; +} + +static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + unsigned int dac_mode; + unsigned int val, idx_val; + + idx_val = spec->aloopback_mask << idx; + if (ucontrol->value.integer.value[0]) + val = spec->aloopback | idx_val; + else + val = spec->aloopback & ~idx_val; + if (spec->aloopback == val) + return 0; + + spec->aloopback = val; + + /* Only return the bits defined by the shift value of the + * first two bytes of the mask + */ + dac_mode = snd_hda_codec_read(codec, codec->afg, 0, + kcontrol->private_value & 0xFFFF, 0x0); + dac_mode >>= spec->aloopback_shift; + + if (spec->aloopback & idx_val) { + snd_hda_power_up(codec); + dac_mode |= idx_val; + } else { + snd_hda_power_down(codec); + dac_mode &= ~idx_val; + } + + snd_hda_codec_write_cache(codec, codec->afg, 0, + kcontrol->private_value >> 16, dac_mode); + + return 1; +} + +static struct hda_verb stac9200_core_init[] = { + /* set dac0mux for dac converter */ + { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, + {} +}; + +static struct hda_verb stac9200_eapd_init[] = { + /* set dac0mux for dac converter */ + {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, + {} +}; + +static struct hda_verb stac92hd73xx_6ch_core_init[] = { + /* set master volume and direct control */ + { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, + /* setup audio connections */ + { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00}, + { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01}, + { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02}, + /* setup adcs to point to mixer */ + { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, + { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, + { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + /* setup import muxs */ + { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01}, + { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01}, + { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01}, + { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x00}, + {} +}; + +static struct hda_verb dell_eq_core_init[] = { + /* set master volume to max value without distortion + * and direct control */ + { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec}, + /* setup audio connections */ + { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, + { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x02}, + { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01}, + /* setup adcs to point to mixer */ + { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, + { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, + /* setup import muxs */ + { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01}, + { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01}, + { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01}, + { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x00}, + {} +}; + +static struct hda_verb dell_m6_core_init[] = { + { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, + /* setup audio connections */ + { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, + { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, + { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x02}, + /* setup adcs to point to mixer */ + { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, + { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, + /* setup import muxs */ + { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01}, + { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01}, + { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01}, + { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x00}, + {} +}; + +static struct hda_verb stac92hd73xx_8ch_core_init[] = { + /* set master volume and direct control */ + { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, + /* setup audio connections */ + { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00}, + { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01}, + { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02}, + /* connect hp ports to dac3 */ + { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x03}, + { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x03}, + /* setup adcs to point to mixer */ + { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, + { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, + { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + /* setup import muxs */ + { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01}, + { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01}, + { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01}, + { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x03}, + {} +}; + +static struct hda_verb stac92hd73xx_10ch_core_init[] = { + /* set master volume and direct control */ + { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, + /* setup audio connections */ + { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, + { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01 }, + { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02 }, + /* dac3 is connected to import3 mux */ + { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb07f}, + /* connect hp ports to dac4 */ + { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x04}, + { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x04}, + /* setup adcs to point to mixer */ + { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, + { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, + { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + /* setup import muxs */ + { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01}, + { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01}, + { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01}, + { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x03}, + {} +}; + +static struct hda_verb stac92hd83xxx_core_init[] = { + /* start of config #1 */ + { 0xe, AC_VERB_SET_CONNECT_SEL, 0x3}, + + /* start of config #2 */ + { 0xa, AC_VERB_SET_CONNECT_SEL, 0x0}, + { 0xb, AC_VERB_SET_CONNECT_SEL, 0x0}, + { 0xd, AC_VERB_SET_CONNECT_SEL, 0x1}, + + /* power state controls amps */ + { 0x01, AC_VERB_SET_EAPD, 1 << 2}, + {} +}; + +static struct hda_verb stac92hd71bxx_core_init[] = { + /* set master volume and direct control */ + { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, + /* connect headphone jack to dac1 */ + { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, + /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */ + { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {} +}; + +#define HD_DISABLE_PORTF 2 +static struct hda_verb stac92hd71bxx_analog_core_init[] = { + /* start of config #1 */ + + /* connect port 0f to audio mixer */ + { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2}, + /* unmute right and left channels for node 0x0f */ + { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + /* start of config #2 */ + + /* set master volume and direct control */ + { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, + /* connect headphone jack to dac1 */ + { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, + /* unmute right and left channels for nodes 0x0a, 0xd */ + { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {} +}; + +static struct hda_verb stac9202_core_init[] = { + /* set dac0mux for dac converter */ + { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00}, + {} +}; + +/* NID 6, the DAC mux, is set to 0, which forces it to uses NID 2 as its input; + Not the loopbacks from either the analog (NID 14) nor stereo (NID 7) inputs. + + NID 15, the DMIC input, has its widget control set to 0x20, which enables it's + output into the Azalia link, not the Analog input + + NID 7, the SPDIF IN pin, set for EAPD; set power amplifier on */ + +static struct hda_verb stac9202_test1_init[] = { + /* set dac0mux for dac converter */ + { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00}, + /* Set pin widgets */ + { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, + /* Set EAPD on SPDIF IN for amp on */ + { 0x07, AC_VERB_SET_EAPD_BTLENABLE , 0x02}, + /* Set Input MUX for digital input */ + { 0x14, AC_VERB_SET_CONNECT_SEL, 0x01}, + /* Unmute the Input MUX */ + { 0x14, 0x390, 0x00}, + { 0x14, 0x3a0, 0x00}, + {} +}; + +static struct hda_verb stac925x_core_init[] = { + /* set dac0mux for dac converter */ + { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00}, + {} +}; + +static struct hda_verb stac922x_core_init[] = { + /* set master volume and direct control */ + { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, + {} +}; + +static struct hda_verb d965_core_init[] = { + /* set master volume and direct control */ + { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, + /* unmute node 0x1b */ + { 0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, + /* select node 0x03 as DAC */ + { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x01}, + {} +}; + +static struct hda_verb stac927x_core_init[] = { + /* set master volume and direct control */ + { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, + /* enable analog pc beep path */ + { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5}, + {} +}; + +static struct hda_verb stac9205_core_init[] = { + /* set master volume and direct control */ + { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, + /* enable analog pc beep path */ + { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5}, + {} +}; + +#define STAC_MONO_MUX \ + { \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = "Mono Mux", \ + .count = 1, \ + .info = stac92xx_mono_mux_enum_info, \ + .get = stac92xx_mono_mux_enum_get, \ + .put = stac92xx_mono_mux_enum_put, \ + } + +#define STAC_AMP_MUX \ + { \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = "Amp Selector Capture Switch", \ + .count = 1, \ + .info = stac92xx_amp_mux_enum_info, \ + .get = stac92xx_amp_mux_enum_get, \ + .put = stac92xx_amp_mux_enum_put, \ + } + +#define STAC_AMP_VOL(xname, nid, chs, idx, dir) \ + { \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .index = 0, \ + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ + SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ + SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \ + .info = stac92xx_amp_volume_info, \ + .get = stac92xx_amp_volume_get, \ + .put = stac92xx_amp_volume_put, \ + .tlv = { .c = snd_hda_mixer_amp_tlv }, \ + .private_value = HDA_COMPOSE_AMP_VAL(nid, chs, idx, dir) \ + } + +#define STAC_INPUT_SOURCE(cnt) \ + { \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = "Input Source", \ + .count = cnt, \ + .info = stac92xx_mux_enum_info, \ + .get = stac92xx_mux_enum_get, \ + .put = stac92xx_mux_enum_put, \ + } + +#define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \ + { \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = "Analog Loopback", \ + .count = cnt, \ + .info = stac92xx_aloopback_info, \ + .get = stac92xx_aloopback_get, \ + .put = stac92xx_aloopback_put, \ + .private_value = verb_read | (verb_write << 16), \ + } + +static struct snd_kcontrol_new stac9200_mixer[] = { + HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), + HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), + STAC_INPUT_SOURCE(1), + HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), + HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), + { } /* end */ +}; + +#define DELL_M6_MIXER 6 +static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = { + /* start of config #1 */ + HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT), + HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT), + + HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT), + HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT), + + HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT), + HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT), + + /* start of config #2 */ + HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT), + + HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT), + HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT), + + STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3), + + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT), + + { } /* end */ +}; + +static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = { + STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4), + + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT), + HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT), + + HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT), + + HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT), + HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT), + + HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT), + HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT), + + HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT), + HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT), + { } /* end */ +}; + +static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = { + STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5), + + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT), + HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT), + + HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT), + + HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT), + HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT), + + HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT), + HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT), + + HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT), + HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT), + { } /* end */ +}; + + +static struct snd_kcontrol_new stac92hd83xxx_mixer[] = { + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0, HDA_INPUT), + HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0, HDA_INPUT), + + HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x1b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("DAC1 Capture Switch", 0x1b, 0x1, HDA_INPUT), + + HDA_CODEC_VOLUME("Front Mic Capture Volume", 0x1b, 0x2, HDA_INPUT), + HDA_CODEC_MUTE("Front Mic Capture Switch", 0x1b, 0x2, HDA_INPUT), + + HDA_CODEC_VOLUME("Line In Capture Volume", 0x1b, 0x3, HDA_INPUT), + HDA_CODEC_MUTE("Line In Capture Switch", 0x1b, 0x3, HDA_INPUT), + + /* + HDA_CODEC_VOLUME("Mic Capture Volume", 0x1b, 0x4, HDA_INPUT), + HDA_CODEC_MUTE("Mic Capture Switch", 0x1b 0x4, HDA_INPUT), + */ + { } /* end */ +}; + +static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { + STAC_INPUT_SOURCE(2), + STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2), + + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT), + /* analog pc-beep replaced with digital beep support */ + /* + HDA_CODEC_VOLUME("PC Beep Volume", 0x17, 0x2, HDA_INPUT), + HDA_CODEC_MUTE("PC Beep Switch", 0x17, 0x2, HDA_INPUT), + */ + + HDA_CODEC_MUTE("Import0 Mux Capture Switch", 0x17, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Import0 Mux Capture Volume", 0x17, 0x0, HDA_INPUT), + + HDA_CODEC_MUTE("Import1 Mux Capture Switch", 0x17, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Import1 Mux Capture Volume", 0x17, 0x1, HDA_INPUT), + + HDA_CODEC_MUTE("DAC0 Capture Switch", 0x17, 0x3, HDA_INPUT), + HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x17, 0x3, HDA_INPUT), + + HDA_CODEC_MUTE("DAC1 Capture Switch", 0x17, 0x4, HDA_INPUT), + HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x17, 0x4, HDA_INPUT), + { } /* end */ +}; + +static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { + STAC_INPUT_SOURCE(2), + STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2), + + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT), + { } /* end */ +}; + +static struct snd_kcontrol_new stac9202_mixer[] = { + HDA_CODEC_VOLUME("Master Playback Volume", 0xe, 0, HDA_OUTPUT), + HDA_CODEC_MUTE("Master Playback Switch", 0xe, 0, HDA_OUTPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Input Source", + .count = 1, + .info = stac92xx_mux_enum_info, + .get = stac92xx_mux_enum_get, + .put = stac92xx_mux_enum_put, + }, +/* + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Digital Input Source", + .count = 1, + .info = stac92xx_dmux_enum_info, + .get = stac92xx_dmux_enum_get, + .put = stac92xx_dmux_enum_put, + }, +*/ + HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), + HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Capture Mux Volume", 0x0f, 0, HDA_OUTPUT), + { } /* end */ +}; + +static struct snd_kcontrol_new stac9202_test1_mixer[] = { + HDA_CODEC_VOLUME("Master Playback Volume", 0xe, 0, HDA_OUTPUT), + HDA_CODEC_MUTE("Master Playback Switch", 0xe, 0, HDA_OUTPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Input Source", + .count = 1, + .info = stac92xx_mux_enum_info, + .get = stac92xx_mux_enum_get, + .put = stac92xx_mux_enum_put, + }, +/* + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Digital Input Source", + .count = 1, + .info = stac92xx_dmux_enum_info, + .get = stac92xx_dmux_enum_get, + .put = stac92xx_dmux_enum_put, + }, +*/ + HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), + HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Capture Mux Volume", 0x0f, 0, HDA_OUTPUT), + { } /* end */ +}; + +static struct snd_kcontrol_new stac925x_mixer[] = { + STAC_INPUT_SOURCE(1), + HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), + HDA_CODEC_MUTE("Capture Switch", 0x14, 0, HDA_OUTPUT), + { } /* end */ +}; + +static struct snd_kcontrol_new stac9205_mixer[] = { + STAC_INPUT_SOURCE(2), + STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1), + + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1c, 0x0, HDA_INPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1e, 0x0, HDA_OUTPUT), + { } /* end */ +}; + +/* This needs to be generated dynamically based on sequence */ +static struct snd_kcontrol_new stac922x_mixer[] = { + STAC_INPUT_SOURCE(2), + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT), + + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_INPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_INPUT), + { } /* end */ +}; + + +static struct snd_kcontrol_new stac927x_mixer[] = { + STAC_INPUT_SOURCE(3), + STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1), + + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x19, 0x0, HDA_INPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1c, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x2, 0x1A, 0x0, HDA_INPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x2, 0x1d, 0x0, HDA_OUTPUT), + { } /* end */ +}; + +static struct snd_kcontrol_new stac_dmux_mixer = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Digital Input Source", + /* count set later */ + .info = stac92xx_dmux_enum_info, + .get = stac92xx_dmux_enum_get, + .put = stac92xx_dmux_enum_put, +}; + +static struct snd_kcontrol_new stac_smux_mixer = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "IEC958 Playback Source", + /* count set later */ + .info = stac92xx_smux_enum_info, + .get = stac92xx_smux_enum_get, + .put = stac92xx_smux_enum_put, +}; + +static const char *slave_vols[] = { + "Front Playback Volume", + "Surround Playback Volume", + "Center Playback Volume", + "LFE Playback Volume", + "Side Playback Volume", + "Headphone Playback Volume", + "Headphone Playback Volume", + "Speaker Playback Volume", + "External Speaker Playback Volume", + "Speaker2 Playback Volume", + NULL +}; + +static const char *slave_sws[] = { + "Front Playback Switch", + "Surround Playback Switch", + "Center Playback Switch", + "LFE Playback Switch", + "Side Playback Switch", + "Headphone Playback Switch", + "Headphone Playback Switch", + "Speaker Playback Switch", + "External Speaker Playback Switch", + "Speaker2 Playback Switch", + "IEC958 Playback Switch", + NULL +}; + +static int stac92xx_build_controls(struct hda_codec *codec) +{ + struct sigmatel_spec *spec = codec->spec; + int err; + int i; + + err = snd_hda_add_new_ctls(codec, spec->mixer); + if (err < 0) + return err; + + for (i = 0; i < spec->num_mixers; i++) { + err = snd_hda_add_new_ctls(codec, spec->mixers[i]); + if (err < 0) + return err; + } + if (spec->num_dmuxes > 0) { + stac_dmux_mixer.count = spec->num_dmuxes; + err = snd_ctl_add(codec->bus->card, + snd_ctl_new1(&stac_dmux_mixer, codec)); + if (err < 0) + return err; + } + if (spec->num_smuxes > 0) { + int wcaps = get_wcaps(codec, spec->multiout.dig_out_nid); + struct hda_input_mux *smux = &spec->private_smux; + /* check for mute support on SPDIF out */ + if (wcaps & AC_WCAP_OUT_AMP) { + smux->items[smux->num_items].label = "Off"; + smux->items[smux->num_items].index = 0; + smux->num_items++; + spec->spdif_mute = 1; + } + stac_smux_mixer.count = spec->num_smuxes; + err = snd_ctl_add(codec->bus->card, + snd_ctl_new1(&stac_smux_mixer, codec)); + if (err < 0) + return err; + } + + if (spec->multiout.dig_out_nid) { + err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); + if (err < 0) + return err; + err = snd_hda_create_spdif_share_sw(codec, + &spec->multiout); + if (err < 0) + return err; + spec->multiout.share_spdif = 1; + } + if (spec->dig_in_nid && !(spec->gpio_dir & 0x01)) { + err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); + if (err < 0) + return err; + } + + /* if we have no master control, let's create it */ + if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { + unsigned int vmaster_tlv[4]; + snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0], + HDA_OUTPUT, vmaster_tlv); + err = snd_hda_add_vmaster(codec, "Master Playback Volume", + vmaster_tlv, slave_vols); + if (err < 0) + return err; + } + if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { + err = snd_hda_add_vmaster(codec, "Master Playback Switch", + NULL, slave_sws); + if (err < 0) + return err; + } + + return 0; +} + +static unsigned int ref9200_pin_configs[8] = { + 0x01c47010, 0x01447010, 0x0221401f, 0x01114010, + 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, +}; + +static unsigned int gateway9200_m4_pin_configs[8] = { + 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010, + 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3, +}; +static unsigned int gateway9200_m4_2_pin_configs[8] = { + 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010, + 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3, +}; + +/* + STAC 9200 pin configs for + 102801A8 + 102801DE + 102801E8 +*/ +static unsigned int dell9200_d21_pin_configs[8] = { + 0x400001f0, 0x400001f1, 0x02214030, 0x01014010, + 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, +}; + +/* + STAC 9200 pin configs for + 102801C0 + 102801C1 +*/ +static unsigned int dell9200_d22_pin_configs[8] = { + 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010, + 0x01813020, 0x02a19021, 0x90100140, 0x400001f2, +}; + +/* + STAC 9200 pin configs for + 102801C4 (Dell Dimension E310) + 102801C5 + 102801C7 + 102801D9 + 102801DA + 102801E3 +*/ +static unsigned int dell9200_d23_pin_configs[8] = { + 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010, + 0x01813020, 0x01a19021, 0x90100140, 0x400001f2, +}; + + +/* + STAC 9200-32 pin configs for + 102801B5 (Dell Inspiron 630m) + 102801D8 (Dell Inspiron 640m) +*/ +static unsigned int dell9200_m21_pin_configs[8] = { + 0x40c003fa, 0x03441340, 0x0321121f, 0x90170310, + 0x408003fb, 0x03a11020, 0x401003fc, 0x403003fd, +}; + +/* + STAC 9200-32 pin configs for + 102801C2 (Dell Latitude D620) + 102801C8 + 102801CC (Dell Latitude D820) + 102801D4 + 102801D6 +*/ +static unsigned int dell9200_m22_pin_configs[8] = { + 0x40c003fa, 0x0144131f, 0x0321121f, 0x90170310, + 0x90a70321, 0x03a11020, 0x401003fb, 0x40f000fc, +}; + +/* + STAC 9200-32 pin configs for + 102801CE (Dell XPS M1710) + 102801CF (Dell Precision M90) +*/ +static unsigned int dell9200_m23_pin_configs[8] = { + 0x40c003fa, 0x01441340, 0x0421421f, 0x90170310, + 0x408003fb, 0x04a1102e, 0x90170311, 0x403003fc, +}; + +/* + STAC 9200-32 pin configs for + 102801C9 + 102801CA + 102801CB (Dell Latitude 120L) + 102801D3 +*/ +static unsigned int dell9200_m24_pin_configs[8] = { + 0x40c003fa, 0x404003fb, 0x0321121f, 0x90170310, + 0x408003fc, 0x03a11020, 0x401003fd, 0x403003fe, +}; + +/* + STAC 9200-32 pin configs for + 102801BD (Dell Inspiron E1505n) + 102801EE + 102801EF +*/ +static unsigned int dell9200_m25_pin_configs[8] = { + 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310, + 0x408003fb, 0x04a11020, 0x401003fc, 0x403003fd, +}; + +/* + STAC 9200-32 pin configs for + 102801F5 (Dell Inspiron 1501) + 102801F6 +*/ +static unsigned int dell9200_m26_pin_configs[8] = { + 0x40c003fa, 0x404003fb, 0x0421121f, 0x90170310, + 0x408003fc, 0x04a11020, 0x401003fd, 0x403003fe, +}; + +/* + STAC 9200-32 + 102801CD (Dell Inspiron E1705/9400) +*/ +static unsigned int dell9200_m27_pin_configs[8] = { + 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310, + 0x90170310, 0x04a11020, 0x90170310, 0x40f003fc, +}; + +static unsigned int oqo9200_pin_configs[8] = { + 0x40c000f0, 0x404000f1, 0x0221121f, 0x02211210, + 0x90170111, 0x90a70120, 0x400000f2, 0x400000f3, +}; + + +static unsigned int ref9202_pin_configs[9] = { + 0x01c10014, 0x01410013, 0x01210011, 0x01010012, + 0x01810022, 0x01a10021, 0x01010031, 0x01310023, 0x01d10024, +}; + +static unsigned int test19202_pin_configs[9] = { + + 0x01c100f4, 0x014100f3, 0x01010012, 0x01210011, + 0x01210013, 0x01a10023, 0x01010031, 0x01310015, 0x01d10024, + +/* + + 0x01c100f4, 0x014100f3, 0x01010012, 0x01010011, + 0x01810013, 0x01a10023, 0x01010031, 0x01310015, 0x01d10024, + + 0x01c10014, 0x01410013, 0x01210011, 0x01010012, + 0x01810022, 0x01a10021, 0x01010031, 0x01310023, 0x01d10024, + + 0x70fff100, 0x70fff100, 0x9717f11f, 0x03214011, + 0x01810022, 0x01a10021, 0x01010031, 0x01310023, 0x97a00120, +*/ + +}; + +static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = { + [STAC_REF] = ref9200_pin_configs, + [STAC_9200_OQO] = oqo9200_pin_configs, + [STAC_9200_DELL_D21] = dell9200_d21_pin_configs, + [STAC_9200_DELL_D22] = dell9200_d22_pin_configs, + [STAC_9200_DELL_D23] = dell9200_d23_pin_configs, + [STAC_9200_DELL_M21] = dell9200_m21_pin_configs, + [STAC_9200_DELL_M22] = dell9200_m22_pin_configs, + [STAC_9200_DELL_M23] = dell9200_m23_pin_configs, + [STAC_9200_DELL_M24] = dell9200_m24_pin_configs, + [STAC_9200_DELL_M25] = dell9200_m25_pin_configs, + [STAC_9200_DELL_M26] = dell9200_m26_pin_configs, + [STAC_9200_DELL_M27] = dell9200_m27_pin_configs, + [STAC_9200_M4] = gateway9200_m4_pin_configs, + [STAC_9200_M4_2] = gateway9200_m4_2_pin_configs, + [STAC_9200_PANASONIC] = ref9200_pin_configs, +}; + +static const char *stac9200_models[STAC_9200_MODELS] = { + [STAC_REF] = "ref", + [STAC_9200_OQO] = "oqo", + [STAC_9200_DELL_D21] = "dell-d21", + [STAC_9200_DELL_D22] = "dell-d22", + [STAC_9200_DELL_D23] = "dell-d23", + [STAC_9200_DELL_M21] = "dell-m21", + [STAC_9200_DELL_M22] = "dell-m22", + [STAC_9200_DELL_M23] = "dell-m23", + [STAC_9200_DELL_M24] = "dell-m24", + [STAC_9200_DELL_M25] = "dell-m25", + [STAC_9200_DELL_M26] = "dell-m26", + [STAC_9200_DELL_M27] = "dell-m27", + [STAC_9200_M4] = "gateway-m4", + [STAC_9200_M4_2] = "gateway-m4-2", + [STAC_9200_PANASONIC] = "panasonic", +}; + +static unsigned int *stac9202_brd_tbl[STAC_9202_MODELS] = { + [STAC_REF] = ref9202_pin_configs, + [STAC_9202_TEST1] = test19202_pin_configs, +}; + +static const char *stac9202_models[STAC_9202_MODELS] = { + [STAC_REF] = "ref", + [STAC_9202_TEST1] = "test1", +}; + +static struct snd_pci_quirk stac9200_cfg_tbl[] = { + /* SigmaTel reference board */ + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, + "DFI LanParty", STAC_REF), + /* Dell laptops have BIOS problem */ + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8, + "unknown Dell", STAC_9200_DELL_D21), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5, + "Dell Inspiron 630m", STAC_9200_DELL_M21), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bd, + "Dell Inspiron E1505n", STAC_9200_DELL_M25), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c0, + "unknown Dell", STAC_9200_DELL_D22), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c1, + "unknown Dell", STAC_9200_DELL_D22), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2, + "Dell Latitude D620", STAC_9200_DELL_M22), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c5, + "unknown Dell", STAC_9200_DELL_D23), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c7, + "unknown Dell", STAC_9200_DELL_D23), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c8, + "unknown Dell", STAC_9200_DELL_M22), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c9, + "unknown Dell", STAC_9200_DELL_M24), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ca, + "unknown Dell", STAC_9200_DELL_M24), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb, + "Dell Latitude 120L", STAC_9200_DELL_M24), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc, + "Dell Latitude D820", STAC_9200_DELL_M22), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cd, + "Dell Inspiron E1705/9400", STAC_9200_DELL_M27), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ce, + "Dell XPS M1710", STAC_9200_DELL_M23), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf, + "Dell Precision M90", STAC_9200_DELL_M23), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d3, + "unknown Dell", STAC_9200_DELL_M22), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d4, + "unknown Dell", STAC_9200_DELL_M22), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6, + "unknown Dell", STAC_9200_DELL_M22), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d8, + "Dell Inspiron 640m", STAC_9200_DELL_M21), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d9, + "unknown Dell", STAC_9200_DELL_D23), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01da, + "unknown Dell", STAC_9200_DELL_D23), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01de, + "unknown Dell", STAC_9200_DELL_D21), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e3, + "unknown Dell", STAC_9200_DELL_D23), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01e8, + "unknown Dell", STAC_9200_DELL_D21), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ee, + "unknown Dell", STAC_9200_DELL_M25), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ef, + "unknown Dell", STAC_9200_DELL_M25), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f5, + "Dell Inspiron 1501", STAC_9200_DELL_M26), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6, + "unknown Dell", STAC_9200_DELL_M26), + /* Panasonic */ + SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_9200_PANASONIC), + /* Gateway machines needs EAPD to be set on resume */ + SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_M4), + SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*", STAC_9200_M4_2), + SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707", STAC_9200_M4_2), + /* OQO Mobile */ + SND_PCI_QUIRK(0x1106, 0x3288, "OQO Model 2", STAC_9200_OQO), + {} /* terminator */ +}; + +static struct snd_pci_quirk stac9202_cfg_tbl[] = { + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, + "Stac 9202 Ref Config", STAC_REF), + SND_PCI_QUIRK(0x8384, 0x7632, + "Stac 9202 Test 1", STAC_9202_TEST1), + {} +}; + +static unsigned int ref925x_pin_configs[8] = { + 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021, + 0x90a70320, 0x02214210, 0x01019020, 0x9033032e, +}; + +static unsigned int stac925xM1_pin_configs[8] = { + 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, + 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, +}; + +static unsigned int stac925xM1_2_pin_configs[8] = { + 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, + 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, +}; + +static unsigned int stac925xM2_pin_configs[8] = { + 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, + 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, +}; + +static unsigned int stac925xM2_2_pin_configs[8] = { + 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, + 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, +}; + +static unsigned int stac925xM3_pin_configs[8] = { + 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, + 0x40a000f0, 0x90100210, 0x400003f1, 0x503303f3, +}; + +static unsigned int stac925xM5_pin_configs[8] = { + 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, + 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, +}; + +static unsigned int stac925xM6_pin_configs[8] = { + 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, + 0x40a000f0, 0x90100210, 0x400003f1, 0x90330320, +}; + +static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = { + [STAC_REF] = ref925x_pin_configs, + [STAC_M1] = stac925xM1_pin_configs, + [STAC_M1_2] = stac925xM1_2_pin_configs, + [STAC_M2] = stac925xM2_pin_configs, + [STAC_M2_2] = stac925xM2_2_pin_configs, + [STAC_M3] = stac925xM3_pin_configs, + [STAC_M5] = stac925xM5_pin_configs, + [STAC_M6] = stac925xM6_pin_configs, +}; + +static const char *stac925x_models[STAC_925x_MODELS] = { + [STAC_REF] = "ref", + [STAC_M1] = "m1", + [STAC_M1_2] = "m1-2", + [STAC_M2] = "m2", + [STAC_M2_2] = "m2-2", + [STAC_M3] = "m3", + [STAC_M5] = "m5", + [STAC_M6] = "m6", +}; + +static struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = { + SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_M2), + SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_M5), + SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_M1), + SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_M2), + SND_PCI_QUIRK(0x107b, 0x0367, "Gateway MX6453", STAC_M1_2), + /* Not sure about the brand name for those */ + SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M1), + SND_PCI_QUIRK(0x107b, 0x0507, "Gateway mobile", STAC_M3), + SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M6), + SND_PCI_QUIRK(0x107b, 0x0685, "Gateway mobile", STAC_M2_2), + {} /* terminator */ +}; + +static struct snd_pci_quirk stac925x_cfg_tbl[] = { + /* SigmaTel reference board */ + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF), + SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF), + + /* Default table for unknown ID */ + SND_PCI_QUIRK(0x1002, 0x437b, "Gateway mobile", STAC_M2_2), + + {} /* terminator */ +}; + +static unsigned int ref92hd73xx_pin_configs[13] = { + 0x02214030, 0x02a19040, 0x01a19020, 0x02214030, + 0x0181302e, 0x01014010, 0x01014020, 0x01014030, + 0x02319040, 0x90a000f0, 0x90a000f0, 0x01452050, + 0x01452050, +}; + +static unsigned int dell_m6_pin_configs[13] = { + 0x0321101f, 0x4f00000f, 0x4f0000f0, 0x90170110, + 0x03a11020, 0x0321101f, 0x4f0000f0, 0x4f0000f0, + 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0, + 0x4f0000f0, +}; + +static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { + [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs, + [STAC_DELL_M6_AMIC] = dell_m6_pin_configs, + [STAC_DELL_M6_DMIC] = dell_m6_pin_configs, + [STAC_DELL_M6_BOTH] = dell_m6_pin_configs, + [STAC_DELL_EQ] = dell_m6_pin_configs, +}; + +static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { + [STAC_92HD73XX_NO_JD] = "no-jd", + [STAC_92HD73XX_REF] = "ref", + [STAC_DELL_M6_AMIC] = "dell-m6-amic", + [STAC_DELL_M6_DMIC] = "dell-m6-dmic", + [STAC_DELL_M6_BOTH] = "dell-m6", + [STAC_DELL_EQ] = "dell-eq", +}; + +static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { + /* SigmaTel reference board */ + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, + "DFI LanParty", STAC_92HD73XX_REF), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254, + "Dell Studio 1535", STAC_DELL_M6_DMIC), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255, + "unknown Dell", STAC_DELL_M6_DMIC), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0256, + "unknown Dell", STAC_DELL_M6_BOTH), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0257, + "unknown Dell", STAC_DELL_M6_BOTH), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025e, + "unknown Dell", STAC_DELL_M6_AMIC), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025f, + "unknown Dell", STAC_DELL_M6_AMIC), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0271, + "unknown Dell", STAC_DELL_M6_DMIC), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0272, + "unknown Dell", STAC_DELL_M6_DMIC), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x029f, + "Dell Studio 1537", STAC_DELL_M6_DMIC), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a0, + "Dell Studio 17", STAC_DELL_M6_DMIC), + {} /* terminator */ +}; + +static unsigned int ref92hd83xxx_pin_configs[14] = { + 0x02214030, 0x02211010, 0x02a19020, 0x02170130, + 0x01014050, 0x01819040, 0x01014020, 0x90a3014e, + 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x40f000f0, + 0x01451160, 0x98560170, +}; + +static unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { + [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, +}; + +static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { + [STAC_92HD83XXX_REF] = "ref", +}; + +static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { + /* SigmaTel reference board */ + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, + "DFI LanParty", STAC_92HD71BXX_REF), + {} /* terminator */ +}; + +static unsigned int ref92hd71bxx_pin_configs[11] = { + 0x02214030, 0x02a19040, 0x01a19020, 0x01014010, + 0x0181302e, 0x01014010, 0x01019020, 0x90a000f0, + 0x90a000f0, 0x01452050, 0x01452050, +}; + +static unsigned int dell_m4_1_pin_configs[11] = { + 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110, + 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0, + 0x40f000f0, 0x4f0000f0, 0x4f0000f0, +}; + +static unsigned int dell_m4_2_pin_configs[11] = { + 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, + 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0, + 0x40f000f0, 0x044413b0, 0x044413b0, +}; + +static unsigned int dell_m4_3_pin_configs[11] = { + 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, + 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a000f0, + 0x40f000f0, 0x044413b0, 0x044413b0, +}; + +static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { + [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs, + [STAC_DELL_M4_1] = dell_m4_1_pin_configs, + [STAC_DELL_M4_2] = dell_m4_2_pin_configs, + [STAC_DELL_M4_3] = dell_m4_3_pin_configs, + [STAC_HP_M4] = NULL, + [STAC_HP_DV5] = NULL, +}; + +static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { + [STAC_92HD71BXX_REF] = "ref", + [STAC_DELL_M4_1] = "dell-m4-1", + [STAC_DELL_M4_2] = "dell-m4-2", + [STAC_DELL_M4_3] = "dell-m4-3", + [STAC_HP_M4] = "hp-m4", + [STAC_HP_DV5] = "hp-dv5", +}; + +static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { + /* SigmaTel reference board */ + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, + "DFI LanParty", STAC_92HD71BXX_REF), + SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f2, + "HP dv5", STAC_HP_M4), + SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f4, + "HP dv7", STAC_HP_M4), + SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fc, + "HP dv7", STAC_HP_M4), + SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3603, + "HP dv5", STAC_HP_DV5), + SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, + "unknown HP", STAC_HP_M4), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, + "unknown Dell", STAC_DELL_M4_1), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234, + "unknown Dell", STAC_DELL_M4_1), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0250, + "unknown Dell", STAC_DELL_M4_1), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024f, + "unknown Dell", STAC_DELL_M4_1), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024d, + "unknown Dell", STAC_DELL_M4_1), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0251, + "unknown Dell", STAC_DELL_M4_1), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0277, + "unknown Dell", STAC_DELL_M4_1), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0263, + "unknown Dell", STAC_DELL_M4_2), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0265, + "unknown Dell", STAC_DELL_M4_2), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0262, + "unknown Dell", STAC_DELL_M4_2), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0264, + "unknown Dell", STAC_DELL_M4_2), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02aa, + "unknown Dell", STAC_DELL_M4_3), + {} /* terminator */ +}; + +static unsigned int ref922x_pin_configs[10] = { + 0x01014010, 0x01016011, 0x01012012, 0x0221401f, + 0x01813122, 0x01011014, 0x01441030, 0x01c41030, + 0x40000100, 0x40000100, +}; + +/* + STAC 922X pin configs for + 102801A7 + 102801AB + 102801A9 + 102801D1 + 102801D2 +*/ +static unsigned int dell_922x_d81_pin_configs[10] = { + 0x02214030, 0x01a19021, 0x01111012, 0x01114010, + 0x02a19020, 0x01117011, 0x400001f0, 0x400001f1, + 0x01813122, 0x400001f2, +}; + +/* + STAC 922X pin configs for + 102801AC + 102801D0 +*/ +static unsigned int dell_922x_d82_pin_configs[10] = { + 0x02214030, 0x01a19021, 0x01111012, 0x01114010, + 0x02a19020, 0x01117011, 0x01451140, 0x400001f0, + 0x01813122, 0x400001f1, +}; + +/* + STAC 922X pin configs for + 102801BF +*/ +static unsigned int dell_922x_m81_pin_configs[10] = { + 0x0321101f, 0x01112024, 0x01111222, 0x91174220, + 0x03a11050, 0x01116221, 0x90a70330, 0x01452340, + 0x40C003f1, 0x405003f0, +}; + +/* + STAC 9221 A1 pin configs for + 102801D7 (Dell XPS M1210) +*/ +static unsigned int dell_922x_m82_pin_configs[10] = { + 0x02211211, 0x408103ff, 0x02a1123e, 0x90100310, + 0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2, + 0x508003f3, 0x405003f4, +}; + +static unsigned int d945gtp3_pin_configs[10] = { + 0x0221401f, 0x01a19022, 0x01813021, 0x01014010, + 0x40000100, 0x40000100, 0x40000100, 0x40000100, + 0x02a19120, 0x40000100, +}; + +static unsigned int d945gtp5_pin_configs[10] = { + 0x0221401f, 0x01011012, 0x01813024, 0x01014010, + 0x01a19021, 0x01016011, 0x01452130, 0x40000100, + 0x02a19320, 0x40000100, +}; + +static unsigned int intel_mac_v1_pin_configs[10] = { + 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd, + 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240, + 0x400000fc, 0x400000fb, +}; + +static unsigned int intel_mac_v2_pin_configs[10] = { + 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd, + 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa, + 0x400000fc, 0x400000fb, +}; + +static unsigned int intel_mac_v3_pin_configs[10] = { + 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd, + 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240, + 0x400000fc, 0x400000fb, +}; + +static unsigned int intel_mac_v4_pin_configs[10] = { + 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f, + 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240, + 0x400000fc, 0x400000fb, +}; + +static unsigned int intel_mac_v5_pin_configs[10] = { + 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f, + 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240, + 0x400000fc, 0x400000fb, +}; + +static unsigned int ecs202_pin_configs[10] = { + 0x0221401f, 0x02a19020, 0x01a19020, 0x01114010, + 0x408000f0, 0x01813022, 0x074510a0, 0x40c400f1, + 0x9037012e, 0x40e000f2, +}; + +static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { + [STAC_D945_REF] = ref922x_pin_configs, + [STAC_D945GTP3] = d945gtp3_pin_configs, + [STAC_D945GTP5] = d945gtp5_pin_configs, + [STAC_INTEL_MAC_V1] = intel_mac_v1_pin_configs, + [STAC_INTEL_MAC_V2] = intel_mac_v2_pin_configs, + [STAC_INTEL_MAC_V3] = intel_mac_v3_pin_configs, + [STAC_INTEL_MAC_V4] = intel_mac_v4_pin_configs, + [STAC_INTEL_MAC_V5] = intel_mac_v5_pin_configs, + [STAC_INTEL_MAC_AUTO] = intel_mac_v3_pin_configs, + /* for backward compatibility */ + [STAC_MACMINI] = intel_mac_v3_pin_configs, + [STAC_MACBOOK] = intel_mac_v5_pin_configs, + [STAC_MACBOOK_PRO_V1] = intel_mac_v3_pin_configs, + [STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs, + [STAC_IMAC_INTEL] = intel_mac_v2_pin_configs, + [STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs, + [STAC_ECS_202] = ecs202_pin_configs, + [STAC_922X_DELL_D81] = dell_922x_d81_pin_configs, + [STAC_922X_DELL_D82] = dell_922x_d82_pin_configs, + [STAC_922X_DELL_M81] = dell_922x_m81_pin_configs, + [STAC_922X_DELL_M82] = dell_922x_m82_pin_configs, +}; + +static const char *stac922x_models[STAC_922X_MODELS] = { + [STAC_D945_REF] = "ref", + [STAC_D945GTP5] = "5stack", + [STAC_D945GTP3] = "3stack", + [STAC_INTEL_MAC_V1] = "intel-mac-v1", + [STAC_INTEL_MAC_V2] = "intel-mac-v2", + [STAC_INTEL_MAC_V3] = "intel-mac-v3", + [STAC_INTEL_MAC_V4] = "intel-mac-v4", + [STAC_INTEL_MAC_V5] = "intel-mac-v5", + [STAC_INTEL_MAC_AUTO] = "intel-mac-auto", + /* for backward compatibility */ + [STAC_MACMINI] = "macmini", + [STAC_MACBOOK] = "macbook", + [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1", + [STAC_MACBOOK_PRO_V2] = "macbook-pro", + [STAC_IMAC_INTEL] = "imac-intel", + [STAC_IMAC_INTEL_20] = "imac-intel-20", + [STAC_ECS_202] = "ecs202", + [STAC_922X_DELL_D81] = "dell-d81", + [STAC_922X_DELL_D82] = "dell-d82", + [STAC_922X_DELL_M81] = "dell-m81", + [STAC_922X_DELL_M82] = "dell-m82", +}; + +static struct snd_pci_quirk stac922x_cfg_tbl[] = { + /* SigmaTel reference board */ + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, + "DFI LanParty", STAC_D945_REF), + /* Intel 945G based systems */ + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101, + "Intel D945G", STAC_D945GTP3), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0202, + "Intel D945G", STAC_D945GTP3), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0606, + "Intel D945G", STAC_D945GTP3), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0601, + "Intel D945G", STAC_D945GTP3), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0111, + "Intel D945G", STAC_D945GTP3), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1115, + "Intel D945G", STAC_D945GTP3), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1116, + "Intel D945G", STAC_D945GTP3), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1117, + "Intel D945G", STAC_D945GTP3), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1118, + "Intel D945G", STAC_D945GTP3), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1119, + "Intel D945G", STAC_D945GTP3), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x8826, + "Intel D945G", STAC_D945GTP3), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5049, + "Intel D945G", STAC_D945GTP3), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5055, + "Intel D945G", STAC_D945GTP3), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5048, + "Intel D945G", STAC_D945GTP3), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0110, + "Intel D945G", STAC_D945GTP3), + /* Intel D945G 5-stack systems */ + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0404, + "Intel D945G", STAC_D945GTP5), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0303, + "Intel D945G", STAC_D945GTP5), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0013, + "Intel D945G", STAC_D945GTP5), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0417, + "Intel D945G", STAC_D945GTP5), + /* Intel 945P based systems */ + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0b0b, + "Intel D945P", STAC_D945GTP3), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0112, + "Intel D945P", STAC_D945GTP3), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0d0d, + "Intel D945P", STAC_D945GTP3), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0909, + "Intel D945P", STAC_D945GTP3), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0505, + "Intel D945P", STAC_D945GTP3), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707, + "Intel D945P", STAC_D945GTP5), + /* other systems */ + /* Apple Intel Mac (Mac Mini, MacBook, MacBook Pro...) */ + SND_PCI_QUIRK(0x8384, 0x7680, + "Mac", STAC_INTEL_MAC_AUTO), + /* Dell systems */ + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a7, + "unknown Dell", STAC_922X_DELL_D81), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a9, + "unknown Dell", STAC_922X_DELL_D81), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ab, + "unknown Dell", STAC_922X_DELL_D81), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ac, + "unknown Dell", STAC_922X_DELL_D82), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01bf, + "unknown Dell", STAC_922X_DELL_M81), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d0, + "unknown Dell", STAC_922X_DELL_D82), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d1, + "unknown Dell", STAC_922X_DELL_D81), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d2, + "unknown Dell", STAC_922X_DELL_D81), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7, + "Dell XPS M1210", STAC_922X_DELL_M82), + /* ECS/PC Chips boards */ + SND_PCI_QUIRK(0x1019, 0x2144, + "ECS/PC chips", STAC_ECS_202), + SND_PCI_QUIRK(0x1019, 0x2608, + "ECS/PC chips", STAC_ECS_202), + SND_PCI_QUIRK(0x1019, 0x2633, + "ECS/PC chips P17G/1333", STAC_ECS_202), + SND_PCI_QUIRK(0x1019, 0x2811, + "ECS/PC chips", STAC_ECS_202), + SND_PCI_QUIRK(0x1019, 0x2812, + "ECS/PC chips", STAC_ECS_202), + SND_PCI_QUIRK(0x1019, 0x2813, + "ECS/PC chips", STAC_ECS_202), + SND_PCI_QUIRK(0x1019, 0x2814, + "ECS/PC chips", STAC_ECS_202), + SND_PCI_QUIRK(0x1019, 0x2815, + "ECS/PC chips", STAC_ECS_202), + SND_PCI_QUIRK(0x1019, 0x2816, + "ECS/PC chips", STAC_ECS_202), + SND_PCI_QUIRK(0x1019, 0x2817, + "ECS/PC chips", STAC_ECS_202), + SND_PCI_QUIRK(0x1019, 0x2818, + "ECS/PC chips", STAC_ECS_202), + SND_PCI_QUIRK(0x1019, 0x2819, + "ECS/PC chips", STAC_ECS_202), + SND_PCI_QUIRK(0x1019, 0x2820, + "ECS/PC chips", STAC_ECS_202), + {} /* terminator */ +}; + +static unsigned int ref927x_pin_configs[14] = { + 0x02214020, 0x02a19080, 0x0181304e, 0x01014010, + 0x01a19040, 0x01011012, 0x01016011, 0x0101201f, + 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070, + 0x01c42190, 0x40000100, +}; + +static unsigned int d965_3st_pin_configs[14] = { + 0x0221401f, 0x02a19120, 0x40000100, 0x01014011, + 0x01a19021, 0x01813024, 0x40000100, 0x40000100, + 0x40000100, 0x40000100, 0x40000100, 0x40000100, + 0x40000100, 0x40000100 +}; + +static unsigned int d965_5st_pin_configs[14] = { + 0x02214020, 0x02a19080, 0x0181304e, 0x01014010, + 0x01a19040, 0x01011012, 0x01016011, 0x40000100, + 0x40000100, 0x40000100, 0x40000100, 0x01442070, + 0x40000100, 0x40000100 +}; + +static unsigned int dell_3st_pin_configs[14] = { + 0x02211230, 0x02a11220, 0x01a19040, 0x01114210, + 0x01111212, 0x01116211, 0x01813050, 0x01112214, + 0x403003fa, 0x90a60040, 0x90a60040, 0x404003fb, + 0x40c003fc, 0x40000100 +}; + +static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = { + [STAC_D965_REF_NO_JD] = ref927x_pin_configs, + [STAC_D965_REF] = ref927x_pin_configs, + [STAC_D965_3ST] = d965_3st_pin_configs, + [STAC_D965_5ST] = d965_5st_pin_configs, + [STAC_DELL_3ST] = dell_3st_pin_configs, + [STAC_DELL_BIOS] = NULL, +}; + +static const char *stac927x_models[STAC_927X_MODELS] = { + [STAC_D965_REF_NO_JD] = "ref-no-jd", + [STAC_D965_REF] = "ref", + [STAC_D965_3ST] = "3stack", + [STAC_D965_5ST] = "5stack", + [STAC_DELL_3ST] = "dell-3stack", + [STAC_DELL_BIOS] = "dell-bios", +}; + +static struct snd_pci_quirk stac927x_cfg_tbl[] = { + /* SigmaTel reference board */ + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, + "DFI LanParty", STAC_D965_REF), + /* Intel 946 based systems */ + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST), + /* 965 based 3 stack systems */ + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2116, "Intel D965", STAC_D965_3ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2115, "Intel D965", STAC_D965_3ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2114, "Intel D965", STAC_D965_3ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2113, "Intel D965", STAC_D965_3ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2112, "Intel D965", STAC_D965_3ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2111, "Intel D965", STAC_D965_3ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2110, "Intel D965", STAC_D965_3ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2009, "Intel D965", STAC_D965_3ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2008, "Intel D965", STAC_D965_3ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2007, "Intel D965", STAC_D965_3ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2006, "Intel D965", STAC_D965_3ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2005, "Intel D965", STAC_D965_3ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2004, "Intel D965", STAC_D965_3ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2003, "Intel D965", STAC_D965_3ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2002, "Intel D965", STAC_D965_3ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2001, "Intel D965", STAC_D965_3ST), + /* Dell 3 stack systems */ + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_3ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ed, "Dell ", STAC_DELL_3ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f4, "Dell ", STAC_DELL_3ST), + /* Dell 3 stack systems with verb table in BIOS */ + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_3ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_DELL_BIOS), + /* 965 based 5 stack systems */ + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2301, "Intel D965", STAC_D965_5ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2302, "Intel D965", STAC_D965_5ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2303, "Intel D965", STAC_D965_5ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2304, "Intel D965", STAC_D965_5ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2305, "Intel D965", STAC_D965_5ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2501, "Intel D965", STAC_D965_5ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2502, "Intel D965", STAC_D965_5ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2503, "Intel D965", STAC_D965_5ST), + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2504, "Intel D965", STAC_D965_5ST), + {} /* terminator */ +}; + +static unsigned int ref9205_pin_configs[12] = { + 0x40000100, 0x40000100, 0x01016011, 0x01014010, + 0x01813122, 0x01a19021, 0x01019020, 0x40000100, + 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030 +}; + +/* + STAC 9205 pin configs for + 102801F1 + 102801F2 + 102801FC + 102801FD + 10280204 + 1028021F + 10280228 (Dell Vostro 1500) +*/ +static unsigned int dell_9205_m42_pin_configs[12] = { + 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310, + 0x400003FB, 0x400003FC, 0x400003FD, 0x40F000F9, + 0x90A60330, 0x400003FF, 0x0144131F, 0x40C003FE, +}; + +/* + STAC 9205 pin configs for + 102801F9 + 102801FA + 102801FE + 102801FF (Dell Precision M4300) + 10280206 + 10280200 + 10280201 +*/ +static unsigned int dell_9205_m43_pin_configs[12] = { + 0x0321101f, 0x03a11020, 0x90a70330, 0x90170310, + 0x400000fe, 0x400000ff, 0x400000fd, 0x40f000f9, + 0x400000fa, 0x400000fc, 0x0144131f, 0x40c003f8, +}; + +static unsigned int dell_9205_m44_pin_configs[12] = { + 0x0421101f, 0x04a11020, 0x400003fa, 0x90170310, + 0x400003fb, 0x400003fc, 0x400003fd, 0x400003f9, + 0x90a60330, 0x400003ff, 0x01441340, 0x40c003fe, +}; + +static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { + [STAC_9205_REF] = ref9205_pin_configs, + [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs, + [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs, + [STAC_9205_DELL_M44] = dell_9205_m44_pin_configs, +}; + +static const char *stac9205_models[STAC_9205_MODELS] = { + [STAC_9205_REF] = "ref", + [STAC_9205_DELL_M42] = "dell-m42", + [STAC_9205_DELL_M43] = "dell-m43", + [STAC_9205_DELL_M44] = "dell-m44", +}; + +static struct snd_pci_quirk stac9205_cfg_tbl[] = { + /* SigmaTel reference board */ + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, + "DFI LanParty", STAC_9205_REF), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1, + "unknown Dell", STAC_9205_DELL_M42), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2, + "unknown Dell", STAC_9205_DELL_M42), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f8, + "Dell Precision", STAC_9205_DELL_M43), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f9, + "Dell Precision", STAC_9205_DELL_M43), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fa, + "Dell Precision", STAC_9205_DELL_M43), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fc, + "unknown Dell", STAC_9205_DELL_M42), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fd, + "unknown Dell", STAC_9205_DELL_M42), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01fe, + "Dell Precision", STAC_9205_DELL_M43), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01ff, + "Dell Precision M4300", STAC_9205_DELL_M43), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0204, + "unknown Dell", STAC_9205_DELL_M42), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0206, + "Dell Precision", STAC_9205_DELL_M43), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021b, + "Dell Precision", STAC_9205_DELL_M43), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021c, + "Dell Precision", STAC_9205_DELL_M43), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x021f, + "Dell Inspiron", STAC_9205_DELL_M44), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228, + "Dell Vostro 1500", STAC_9205_DELL_M42), + {} /* terminator */ +}; + +static int stac92xx_save_bios_config_regs(struct hda_codec *codec) +{ + int i; + struct sigmatel_spec *spec = codec->spec; + + if (! spec->bios_pin_configs) { + spec->bios_pin_configs = kcalloc(spec->num_pins, + sizeof(*spec->bios_pin_configs), GFP_KERNEL); + if (! spec->bios_pin_configs) + return -ENOMEM; + } + + for (i = 0; i < spec->num_pins; i++) { + hda_nid_t nid = spec->pin_nids[i]; + unsigned int pin_cfg; + + pin_cfg = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_CONFIG_DEFAULT, 0x00); + snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x bios pin config %8.8x\n", + nid, pin_cfg); + spec->bios_pin_configs[i] = pin_cfg; + } + + return 0; +} + +static void stac92xx_set_config_reg(struct hda_codec *codec, + hda_nid_t pin_nid, unsigned int pin_config) +{ + int i; + snd_hda_codec_write(codec, pin_nid, 0, + AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, + pin_config & 0x000000ff); + snd_hda_codec_write(codec, pin_nid, 0, + AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, + (pin_config & 0x0000ff00) >> 8); + snd_hda_codec_write(codec, pin_nid, 0, + AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, + (pin_config & 0x00ff0000) >> 16); + snd_hda_codec_write(codec, pin_nid, 0, + AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, + pin_config >> 24); + i = snd_hda_codec_read(codec, pin_nid, 0, + AC_VERB_GET_CONFIG_DEFAULT, + 0x00); + snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n", + pin_nid, i); +} + +static void stac92xx_set_config_regs(struct hda_codec *codec) +{ + int i; + struct sigmatel_spec *spec = codec->spec; + + if (!spec->pin_configs) + return; + + for (i = 0; i < spec->num_pins; i++) + stac92xx_set_config_reg(codec, spec->pin_nids[i], + spec->pin_configs[i]); +} + +/* + * Analog playback callbacks + */ +static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream) +{ + struct sigmatel_spec *spec = codec->spec; + if (spec->stream_delay) + msleep(spec->stream_delay); + return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, + hinfo); +} + +static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct sigmatel_spec *spec = codec->spec; + return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, format, substream); +} + +static int stac92xx_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream) +{ + struct sigmatel_spec *spec = codec->spec; + return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); +} + +/* + * Digital playback callbacks + */ +static int stac92xx_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream) +{ + struct sigmatel_spec *spec = codec->spec; + return snd_hda_multi_out_dig_open(codec, &spec->multiout); +} + +static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream) +{ + struct sigmatel_spec *spec = codec->spec; + return snd_hda_multi_out_dig_close(codec, &spec->multiout); +} + +static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct sigmatel_spec *spec = codec->spec; + return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, + stream_tag, format, substream); +} + + +/* + * Analog capture callbacks + */ +static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct sigmatel_spec *spec = codec->spec; + hda_nid_t nid = spec->adc_nids[substream->number]; + + if (spec->powerdown_adcs) { + msleep(40); + snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); + } + snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); + return 0; +} + +static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream) +{ + struct sigmatel_spec *spec = codec->spec; + hda_nid_t nid = spec->adc_nids[substream->number]; + + snd_hda_codec_cleanup_stream(codec, nid); + if (spec->powerdown_adcs) + snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); + return 0; +} + +static struct hda_pcm_stream stac92xx_pcm_digital_playback = { + .substreams = 1, + .channels_min = 2, + .channels_max = 2, + /* NID is set in stac92xx_build_pcms */ + .ops = { + .open = stac92xx_dig_playback_pcm_open, + .close = stac92xx_dig_playback_pcm_close, + .prepare = stac92xx_dig_playback_pcm_prepare + }, +}; + +static struct hda_pcm_stream stac92xx_pcm_digital_capture = { + .substreams = 1, + .channels_min = 2, + .channels_max = 2, + /* NID is set in stac92xx_build_pcms */ +}; + +static struct hda_pcm_stream stac92xx_pcm_analog_playback = { + .substreams = 1, + .channels_min = 2, + .channels_max = 8, + .nid = 0x02, /* NID to query formats and rates */ + .ops = { + .open = stac92xx_playback_pcm_open, + .prepare = stac92xx_playback_pcm_prepare, + .cleanup = stac92xx_playback_pcm_cleanup + }, +}; + +static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = { + .substreams = 1, + .channels_min = 2, + .channels_max = 2, + .nid = 0x06, /* NID to query formats and rates */ + .ops = { + .open = stac92xx_playback_pcm_open, + .prepare = stac92xx_playback_pcm_prepare, + .cleanup = stac92xx_playback_pcm_cleanup + }, +}; + +static struct hda_pcm_stream stac92xx_pcm_analog_capture = { + .channels_min = 2, + .channels_max = 2, + /* NID + .substreams is set in stac92xx_build_pcms */ + .ops = { + .prepare = stac92xx_capture_pcm_prepare, + .cleanup = stac92xx_capture_pcm_cleanup + }, +}; + +static int stac92xx_build_pcms(struct hda_codec *codec) +{ + struct sigmatel_spec *spec = codec->spec; + struct hda_pcm *info = spec->pcm_rec; + + codec->num_pcms = 1; + codec->pcm_info = info; + + info->name = "STAC92xx Analog"; + info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback; + info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = + spec->multiout.dac_nids[0]; + info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture; + info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; + info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adcs; + + if (spec->alt_switch) { + codec->num_pcms++; + info++; + info->name = "STAC92xx Analog Alt"; + info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_alt_playback; + } + + if (spec->multiout.dig_out_nid || spec->dig_in_nid) { + codec->num_pcms++; + info++; + info->name = "STAC92xx Digital"; + info->pcm_type = HDA_PCM_TYPE_SPDIF; + if (spec->multiout.dig_out_nid) { + info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback; + info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; + } + if (spec->dig_in_nid) { + info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_digital_capture; + info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; + } + } + + return 0; +} + +static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid) +{ + unsigned int pincap = snd_hda_param_read(codec, nid, + AC_PAR_PIN_CAP); + pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; + if (pincap & AC_PINCAP_VREF_100) + return AC_PINCTL_VREF_100; + if (pincap & AC_PINCAP_VREF_80) + return AC_PINCTL_VREF_80; + if (pincap & AC_PINCAP_VREF_50) + return AC_PINCTL_VREF_50; + if (pincap & AC_PINCAP_VREF_GRD) + return AC_PINCTL_VREF_GRD; + return 0; +} + +static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type) + +{ + snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); +} + +#define stac92xx_hp_switch_info snd_ctl_boolean_mono_info + +static int stac92xx_hp_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + + ucontrol->value.integer.value[0] = !!spec->hp_switch; + return 0; +} + +static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + int nid = kcontrol->private_value; + + spec->hp_switch = ucontrol->value.integer.value[0] ? nid : 0; + + /* check to be sure that the ports are upto date with + * switch changes + */ + codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); + + return 1; +} + +#define stac92xx_io_switch_info snd_ctl_boolean_mono_info + +static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + int io_idx = kcontrol-> private_value & 0xff; + + ucontrol->value.integer.value[0] = spec->io_switch[io_idx]; + return 0; +} + +static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + hda_nid_t nid = kcontrol->private_value >> 8; + int io_idx = kcontrol-> private_value & 0xff; + unsigned short val = !!ucontrol->value.integer.value[0]; + + spec->io_switch[io_idx] = val; + + if (val) + stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN); + else { + unsigned int pinctl = AC_PINCTL_IN_EN; + if (io_idx) /* set VREF for mic */ + pinctl |= stac92xx_get_vref(codec, nid); + stac92xx_auto_set_pinctl(codec, nid, pinctl); + } + + /* check the auto-mute again: we need to mute/unmute the speaker + * appropriately according to the pin direction + */ + if (spec->hp_detect) + codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); + + return 1; +} + +#define stac92xx_clfe_switch_info snd_ctl_boolean_mono_info + +static int stac92xx_clfe_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + + ucontrol->value.integer.value[0] = spec->clfe_swap; + return 0; +} + +static int stac92xx_clfe_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + hda_nid_t nid = kcontrol->private_value & 0xff; + unsigned int val = !!ucontrol->value.integer.value[0]; + + if (spec->clfe_swap == val) + return 0; + + spec->clfe_swap = val; + + snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, + spec->clfe_swap ? 0x4 : 0x0); + + return 1; +} + +#define STAC_CODEC_HP_SWITCH(xname) \ + { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .index = 0, \ + .info = stac92xx_hp_switch_info, \ + .get = stac92xx_hp_switch_get, \ + .put = stac92xx_hp_switch_put, \ + } + +#define STAC_CODEC_IO_SWITCH(xname, xpval) \ + { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .index = 0, \ + .info = stac92xx_io_switch_info, \ + .get = stac92xx_io_switch_get, \ + .put = stac92xx_io_switch_put, \ + .private_value = xpval, \ + } + +#define STAC_CODEC_CLFE_SWITCH(xname, xpval) \ + { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .index = 0, \ + .info = stac92xx_clfe_switch_info, \ + .get = stac92xx_clfe_switch_get, \ + .put = stac92xx_clfe_switch_put, \ + .private_value = xpval, \ + } + +enum { + STAC_CTL_WIDGET_VOL, + STAC_CTL_WIDGET_MUTE, + STAC_CTL_WIDGET_MONO_MUX, + STAC_CTL_WIDGET_AMP_MUX, + STAC_CTL_WIDGET_AMP_VOL, + STAC_CTL_WIDGET_HP_SWITCH, + STAC_CTL_WIDGET_IO_SWITCH, + STAC_CTL_WIDGET_CLFE_SWITCH +}; + +static struct snd_kcontrol_new stac92xx_control_templates[] = { + HDA_CODEC_VOLUME(NULL, 0, 0, 0), + HDA_CODEC_MUTE(NULL, 0, 0, 0), + STAC_MONO_MUX, + STAC_AMP_MUX, + STAC_AMP_VOL(NULL, 0, 0, 0, 0), + STAC_CODEC_HP_SWITCH(NULL), + STAC_CODEC_IO_SWITCH(NULL, 0), + STAC_CODEC_CLFE_SWITCH(NULL, 0), +}; + +/* add dynamic controls */ +static int stac92xx_add_control_temp(struct sigmatel_spec *spec, + struct snd_kcontrol_new *ktemp, + int idx, const char *name, + unsigned long val) +{ + struct snd_kcontrol_new *knew; + + if (spec->num_kctl_used >= spec->num_kctl_alloc) { + int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; + + knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */ + if (! knew) + return -ENOMEM; + if (spec->kctl_alloc) { + memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc); + kfree(spec->kctl_alloc); + } + spec->kctl_alloc = knew; + spec->num_kctl_alloc = num; + } + + knew = &spec->kctl_alloc[spec->num_kctl_used]; + *knew = *ktemp; + knew->index = idx; + knew->name = kstrdup(name, GFP_KERNEL); + if (!knew->name) + return -ENOMEM; + knew->private_value = val; + spec->num_kctl_used++; + return 0; +} + +static inline int stac92xx_add_control_idx(struct sigmatel_spec *spec, + int type, int idx, const char *name, + unsigned long val) +{ + return stac92xx_add_control_temp(spec, + &stac92xx_control_templates[type], + idx, name, val); +} + + +/* add dynamic controls */ +static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type, + const char *name, unsigned long val) +{ + return stac92xx_add_control_idx(spec, type, 0, name, val); +} + +/* flag inputs as additional dynamic lineouts */ +static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg) +{ + struct sigmatel_spec *spec = codec->spec; + unsigned int wcaps, wtype; + int i, num_dacs = 0; + + /* use the wcaps cache to count all DACs available for line-outs */ + for (i = 0; i < codec->num_nodes; i++) { + wcaps = codec->wcaps[i]; + wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; + + if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL)) + num_dacs++; + } + + snd_printdd("%s: total dac count=%d\n", __func__, num_dacs); + + switch (cfg->line_outs) { + case 3: + /* add line-in as side */ + if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) { + cfg->line_out_pins[cfg->line_outs] = + cfg->input_pins[AUTO_PIN_LINE]; + spec->line_switch = 1; + cfg->line_outs++; + } + break; + case 2: + /* add line-in as clfe and mic as side */ + if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) { + cfg->line_out_pins[cfg->line_outs] = + cfg->input_pins[AUTO_PIN_LINE]; + spec->line_switch = 1; + cfg->line_outs++; + } + if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) { + cfg->line_out_pins[cfg->line_outs] = + cfg->input_pins[AUTO_PIN_MIC]; + spec->mic_switch = 1; + cfg->line_outs++; + } + break; + case 1: + /* add line-in as surr and mic as clfe */ + if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) { + cfg->line_out_pins[cfg->line_outs] = + cfg->input_pins[AUTO_PIN_LINE]; + spec->line_switch = 1; + cfg->line_outs++; + } + if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) { + cfg->line_out_pins[cfg->line_outs] = + cfg->input_pins[AUTO_PIN_MIC]; + spec->mic_switch = 1; + cfg->line_outs++; + } + break; + } + + return 0; +} + + +static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) +{ + int i; + + for (i = 0; i < spec->multiout.num_dacs; i++) { + if (spec->multiout.dac_nids[i] == nid) + return 1; + } + + return 0; +} + +/* + * Fill in the dac_nids table from the parsed pin configuration + * This function only works when every pin in line_out_pins[] + * contains atleast one DAC in its connection list. Some 92xx + * codecs are not connected directly to a DAC, such as the 9200 + * and 9202/925x. For those, dac_nids[] must be hard-coded. + */ +static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, + struct auto_pin_cfg *cfg) +{ + struct sigmatel_spec *spec = codec->spec; + int i, j, conn_len = 0; + hda_nid_t nid, conn[HDA_MAX_CONNECTIONS]; + unsigned int wcaps, wtype; + + for (i = 0; i < cfg->line_outs; i++) { + nid = cfg->line_out_pins[i]; + conn_len = snd_hda_get_connections(codec, nid, conn, + HDA_MAX_CONNECTIONS); + for (j = 0; j < conn_len; j++) { + wcaps = snd_hda_param_read(codec, conn[j], + AC_PAR_AUDIO_WIDGET_CAP); + wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; + if (wtype != AC_WID_AUD_OUT || + (wcaps & AC_WCAP_DIGITAL)) + continue; + /* conn[j] is a DAC routed to this line-out */ + if (!is_in_dac_nids(spec, conn[j])) + break; + } + + if (j == conn_len) { + if (spec->multiout.num_dacs > 0) { + /* we have already working output pins, + * so let's drop the broken ones again + */ + cfg->line_outs = spec->multiout.num_dacs; + break; + } + /* error out, no available DAC found */ + snd_printk(KERN_ERR + "%s: No available DAC for pin 0x%x\n", + __func__, nid); + return -ENODEV; + } + + spec->multiout.dac_nids[i] = conn[j]; + spec->multiout.num_dacs++; + if (conn_len > 1) { + /* select this DAC in the pin's input mux */ + snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_CONNECT_SEL, j); + + } + } + + snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", + spec->multiout.num_dacs, + spec->multiout.dac_nids[0], + spec->multiout.dac_nids[1], + spec->multiout.dac_nids[2], + spec->multiout.dac_nids[3], + spec->multiout.dac_nids[4]); + return 0; +} + +/* create volume control/switch for the given prefx type */ +static int create_controls(struct sigmatel_spec *spec, const char *pfx, hda_nid_t nid, int chs) +{ + char name[32]; + int err; + + sprintf(name, "%s Playback Volume", pfx); + err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); + if (err < 0) + return err; + sprintf(name, "%s Playback Switch", pfx); + err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, name, + HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); + if (err < 0) + return err; + return 0; +} + +static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid) +{ + if (!spec->multiout.hp_nid) + spec->multiout.hp_nid = nid; + else if (spec->multiout.num_dacs > 4) { + printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid); + return 1; + } else { + spec->multiout.dac_nids[spec->multiout.num_dacs] = nid; + spec->multiout.num_dacs++; + } + return 0; +} + +static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) +{ + if (is_in_dac_nids(spec, nid)) + return 1; + if (spec->multiout.hp_nid == nid) + return 1; + return 0; +} + +/* add playback controls from the parsed DAC table */ +static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, + const struct auto_pin_cfg *cfg) +{ + static const char *chname[4] = { + "Front", "Surround", NULL /*CLFE*/, "Side" + }; + hda_nid_t nid = 0; + int i, err; + + struct sigmatel_spec *spec = codec->spec; + unsigned int wid_caps, pincap; + + + for (i = 0; i < cfg->line_outs && i < spec->multiout.num_dacs; i++) { + if (!spec->multiout.dac_nids[i]) + continue; + + nid = spec->multiout.dac_nids[i]; + + if (i == 2) { + /* Center/LFE */ + err = create_controls(spec, "Center", nid, 1); + if (err < 0) + return err; + err = create_controls(spec, "LFE", nid, 2); + if (err < 0) + return err; + + wid_caps = get_wcaps(codec, nid); + + if (wid_caps & AC_WCAP_LR_SWAP) { + err = stac92xx_add_control(spec, + STAC_CTL_WIDGET_CLFE_SWITCH, + "Swap Center/LFE Playback Switch", nid); + + if (err < 0) + return err; + } + + } else { + err = create_controls(spec, chname[i], nid, 3); + if (err < 0) + return err; + } + } + + if ((spec->multiout.num_dacs - cfg->line_outs) > 0 && + cfg->hp_outs == 1 && !spec->multiout.hp_nid) + spec->multiout.hp_nid = nid; + + if (cfg->hp_outs > 1 && cfg->line_out_type == AUTO_PIN_LINE_OUT) { + err = stac92xx_add_control(spec, + STAC_CTL_WIDGET_HP_SWITCH, + "Headphone as Line Out Switch", + cfg->hp_pins[cfg->hp_outs - 1]); + if (err < 0) + return err; + } + + if (spec->line_switch) { + nid = cfg->input_pins[AUTO_PIN_LINE]; + pincap = snd_hda_param_read(codec, nid, + AC_PAR_PIN_CAP); + if (pincap & AC_PINCAP_OUT) { + err = stac92xx_add_control(spec, + STAC_CTL_WIDGET_IO_SWITCH, + "Line In as Output Switch", nid << 8); + if (err < 0) + return err; + } + } + + if (spec->mic_switch) { + unsigned int def_conf; + unsigned int mic_pin = AUTO_PIN_MIC; +again: + nid = cfg->input_pins[mic_pin]; + def_conf = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_CONFIG_DEFAULT, 0); + /* some laptops have an internal analog microphone + * which can't be used as a output */ + if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) { + pincap = snd_hda_param_read(codec, nid, + AC_PAR_PIN_CAP); + if (pincap & AC_PINCAP_OUT) { + err = stac92xx_add_control(spec, + STAC_CTL_WIDGET_IO_SWITCH, + "Mic as Output Switch", (nid << 8) | 1); + nid = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_CONNECT_LIST, 0) & 0xff; + if (!check_in_dac_nids(spec, nid)) + add_spec_dacs(spec, nid); + if (err < 0) + return err; + } + } else if (mic_pin == AUTO_PIN_MIC) { + mic_pin = AUTO_PIN_FRONT_MIC; + goto again; + } + } + + return 0; +} + +/* add playback controls for Speaker and HP outputs */ +static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, + struct auto_pin_cfg *cfg) +{ + struct sigmatel_spec *spec = codec->spec; + hda_nid_t nid; + int i, old_num_dacs, err; + + old_num_dacs = spec->multiout.num_dacs; + for (i = 0; i < cfg->hp_outs; i++) { + unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]); + if (wid_caps & AC_WCAP_UNSOL_CAP) + spec->hp_detect = 1; + nid = snd_hda_codec_read(codec, cfg->hp_pins[i], 0, + AC_VERB_GET_CONNECT_LIST, 0) & 0xff; + if (check_in_dac_nids(spec, nid)) + nid = 0; + if (! nid) + continue; + add_spec_dacs(spec, nid); + } + for (i = 0; i < cfg->speaker_outs; i++) { + nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0, + AC_VERB_GET_CONNECT_LIST, 0) & 0xff; + if (check_in_dac_nids(spec, nid)) + nid = 0; + if (! nid) + continue; + add_spec_dacs(spec, nid); + } + for (i = 0; i < cfg->line_outs; i++) { + nid = snd_hda_codec_read(codec, cfg->line_out_pins[i], 0, + AC_VERB_GET_CONNECT_LIST, 0) & 0xff; + if (check_in_dac_nids(spec, nid)) + nid = 0; + if (! nid) + continue; + add_spec_dacs(spec, nid); + } + for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) { + static const char *pfxs[] = { + "Speaker", "External Speaker", "Speaker2", + }; + err = create_controls(spec, pfxs[i - old_num_dacs], + spec->multiout.dac_nids[i], 3); + if (err < 0) + return err; + } + if (spec->multiout.hp_nid) { + err = create_controls(spec, "Headphone", + spec->multiout.hp_nid, 3); + if (err < 0) + return err; + } + + return 0; +} + +/* labels for mono mux outputs */ +static const char *stac92xx_mono_labels[4] = { + "DAC0", "DAC1", "Mixer", "DAC2" +}; + +/* create mono mux for mono out on capable codecs */ +static int stac92xx_auto_create_mono_output_ctls(struct hda_codec *codec) +{ + struct sigmatel_spec *spec = codec->spec; + struct hda_input_mux *mono_mux = &spec->private_mono_mux; + int i, num_cons; + hda_nid_t con_lst[ARRAY_SIZE(stac92xx_mono_labels)]; + + num_cons = snd_hda_get_connections(codec, + spec->mono_nid, + con_lst, + HDA_MAX_NUM_INPUTS); + if (!num_cons || num_cons > ARRAY_SIZE(stac92xx_mono_labels)) + return -EINVAL; + + for (i = 0; i < num_cons; i++) { + mono_mux->items[mono_mux->num_items].label = + stac92xx_mono_labels[i]; + mono_mux->items[mono_mux->num_items].index = i; + mono_mux->num_items++; + } + + return stac92xx_add_control(spec, STAC_CTL_WIDGET_MONO_MUX, + "Mono Mux", spec->mono_nid); +} + +/* labels for amp mux outputs */ +static const char *stac92xx_amp_labels[3] = { + "Front Microphone", "Microphone", "Line In", +}; + +/* create amp out controls mux on capable codecs */ +static int stac92xx_auto_create_amp_output_ctls(struct hda_codec *codec) +{ + struct sigmatel_spec *spec = codec->spec; + struct hda_input_mux *amp_mux = &spec->private_amp_mux; + int i, err; + + for (i = 0; i < spec->num_amps; i++) { + amp_mux->items[amp_mux->num_items].label = + stac92xx_amp_labels[i]; + amp_mux->items[amp_mux->num_items].index = i; + amp_mux->num_items++; + } + + if (spec->num_amps > 1) { + err = stac92xx_add_control(spec, STAC_CTL_WIDGET_AMP_MUX, + "Amp Selector Capture Switch", 0); + if (err < 0) + return err; + } + return stac92xx_add_control(spec, STAC_CTL_WIDGET_AMP_VOL, + "Amp Capture Volume", + HDA_COMPOSE_AMP_VAL(spec->amp_nids[0], 3, 0, HDA_INPUT)); +} + + +/* create PC beep volume controls */ +static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec, + hda_nid_t nid) +{ + struct sigmatel_spec *spec = codec->spec; + u32 caps = query_amp_caps(codec, nid, HDA_OUTPUT); + int err; + + /* check for mute support for the the amp */ + if ((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT) { + err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, + "PC Beep Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT)); + if (err < 0) + return err; + } + + /* check to see if there is volume support for the amp */ + if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) { + err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, + "PC Beep Playback Volume", + HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT)); + if (err < 0) + return err; + } + return 0; +} + +#ifdef CONFIG_SND_HDA_INPUT_BEEP +#define stac92xx_dig_beep_switch_info snd_ctl_boolean_mono_info + +static int stac92xx_dig_beep_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + ucontrol->value.integer.value[0] = codec->beep->enabled; + return 0; +} + +static int stac92xx_dig_beep_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + int enabled = !!ucontrol->value.integer.value[0]; + if (codec->beep->enabled != enabled) { + codec->beep->enabled = enabled; + return 1; + } + return 0; +} + +static struct snd_kcontrol_new stac92xx_dig_beep_ctrl = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .info = stac92xx_dig_beep_switch_info, + .get = stac92xx_dig_beep_switch_get, + .put = stac92xx_dig_beep_switch_put, +}; + +static int stac92xx_beep_switch_ctl(struct hda_codec *codec) +{ + return stac92xx_add_control_temp(codec->spec, &stac92xx_dig_beep_ctrl, + 0, "PC Beep Playback Switch", 0); +} +#endif + +static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec) +{ + struct sigmatel_spec *spec = codec->spec; + int wcaps, nid, i, err = 0; + + for (i = 0; i < spec->num_muxes; i++) { + nid = spec->mux_nids[i]; + wcaps = get_wcaps(codec, nid); + + if (wcaps & AC_WCAP_OUT_AMP) { + err = stac92xx_add_control_idx(spec, + STAC_CTL_WIDGET_VOL, i, "Mux Capture Volume", + HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); + if (err < 0) + return err; + } + } + return 0; +}; + +static const char *stac92xx_spdif_labels[3] = { + "Digital Playback", "Analog Mux 1", "Analog Mux 2", +}; + +static int stac92xx_auto_create_spdif_mux_ctls(struct hda_codec *codec) +{ + struct sigmatel_spec *spec = codec->spec; + struct hda_input_mux *spdif_mux = &spec->private_smux; + const char **labels = spec->spdif_labels; + int i, num_cons; + hda_nid_t con_lst[HDA_MAX_NUM_INPUTS]; + + num_cons = snd_hda_get_connections(codec, + spec->smux_nids[0], + con_lst, + HDA_MAX_NUM_INPUTS); + if (!num_cons) + return -EINVAL; + + if (!labels) + labels = stac92xx_spdif_labels; + + for (i = 0; i < num_cons; i++) { + spdif_mux->items[spdif_mux->num_items].label = labels[i]; + spdif_mux->items[spdif_mux->num_items].index = i; + spdif_mux->num_items++; + } + + return 0; +} + +/* labels for dmic mux inputs */ +static const char *stac92xx_dmic_labels[5] = { + "Analog Inputs", "Digital Mic 1", "Digital Mic 2", + "Digital Mic 3", "Digital Mic 4" +}; + +/* create playback/capture controls for input pins on dmic capable codecs */ +static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, + const struct auto_pin_cfg *cfg) +{ + struct sigmatel_spec *spec = codec->spec; + struct hda_input_mux *dimux = &spec->private_dimux; + hda_nid_t con_lst[HDA_MAX_NUM_INPUTS]; + int err, i, j; + char name[32]; + + dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0]; + dimux->items[dimux->num_items].index = 0; + dimux->num_items++; + + for (i = 0; i < spec->num_dmics; i++) { + hda_nid_t nid; + int index; + int num_cons; + unsigned int wcaps; + unsigned int def_conf; + + def_conf = snd_hda_codec_read(codec, + spec->dmic_nids[i], + 0, + AC_VERB_GET_CONFIG_DEFAULT, + 0); + if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) + continue; + + nid = spec->dmic_nids[i]; + num_cons = snd_hda_get_connections(codec, + spec->dmux_nids[0], + con_lst, + HDA_MAX_NUM_INPUTS); + for (j = 0; j < num_cons; j++) + if (con_lst[j] == nid) { + index = j; + goto found; + } + continue; +found: + wcaps = get_wcaps(codec, nid) & + (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP); + + if (wcaps) { + sprintf(name, "%s Capture Volume", + stac92xx_dmic_labels[dimux->num_items]); + + err = stac92xx_add_control(spec, + STAC_CTL_WIDGET_VOL, + name, + HDA_COMPOSE_AMP_VAL(nid, 3, 0, + (wcaps & AC_WCAP_OUT_AMP) ? + HDA_OUTPUT : HDA_INPUT)); + if (err < 0) + return err; + } + + dimux->items[dimux->num_items].label = + stac92xx_dmic_labels[dimux->num_items]; + dimux->items[dimux->num_items].index = index; + dimux->num_items++; + } + + return 0; +} + +/* create playback/capture controls for input pins */ +static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) +{ + struct sigmatel_spec *spec = codec->spec; + struct hda_input_mux *imux = &spec->private_imux; + hda_nid_t con_lst[HDA_MAX_NUM_INPUTS]; + int i, j, k; + + for (i = 0; i < AUTO_PIN_LAST; i++) { + int index; + + if (!cfg->input_pins[i]) + continue; + index = -1; + for (j = 0; j < spec->num_muxes; j++) { + int num_cons; + num_cons = snd_hda_get_connections(codec, + spec->mux_nids[j], + con_lst, + HDA_MAX_NUM_INPUTS); + for (k = 0; k < num_cons; k++) + if (con_lst[k] == cfg->input_pins[i]) { + index = k; + goto found; + } + } + continue; + found: + imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; + imux->items[imux->num_items].index = index; + imux->num_items++; + } + + if (imux->num_items) { + /* + * Set the current input for the muxes. + * The STAC9221 has two input muxes with identical source + * NID lists. Hopefully this won't get confused. + */ + for (i = 0; i < spec->num_muxes; i++) { + snd_hda_codec_write_cache(codec, spec->mux_nids[i], 0, + AC_VERB_SET_CONNECT_SEL, + imux->items[0].index); + } + } + + return 0; +} + +static void stac92xx_auto_init_multi_out(struct hda_codec *codec) +{ + struct sigmatel_spec *spec = codec->spec; + int i; + + for (i = 0; i < spec->autocfg.line_outs; i++) { + hda_nid_t nid = spec->autocfg.line_out_pins[i]; + stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN); + } +} + +static void stac92xx_auto_init_hp_out(struct hda_codec *codec) +{ + struct sigmatel_spec *spec = codec->spec; + int i; + + for (i = 0; i < spec->autocfg.hp_outs; i++) { + hda_nid_t pin; + pin = spec->autocfg.hp_pins[i]; + if (pin) /* connect to front */ + stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); + } + for (i = 0; i < spec->autocfg.speaker_outs; i++) { + hda_nid_t pin; + pin = spec->autocfg.speaker_pins[i]; + if (pin) /* connect to front */ + stac92xx_auto_set_pinctl(codec, pin, AC_PINCTL_OUT_EN); + } +} + +static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in) +{ + struct sigmatel_spec *spec = codec->spec; + int err; + int hp_speaker_swap = 0; + + if ((err = snd_hda_parse_pin_def_config(codec, + &spec->autocfg, + spec->dmic_nids)) < 0) + return err; + if (! spec->autocfg.line_outs) + return 0; /* can't find valid pin config */ + + /* If we have no real line-out pin and multiple hp-outs, HPs should + * be set up as multi-channel outputs. + */ + if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT && + spec->autocfg.hp_outs > 1) { + /* Copy hp_outs to line_outs, backup line_outs in + * speaker_outs so that the following routines can handle + * HP pins as primary outputs. + */ + memcpy(spec->autocfg.speaker_pins, spec->autocfg.line_out_pins, + sizeof(spec->autocfg.line_out_pins)); + spec->autocfg.speaker_outs = spec->autocfg.line_outs; + memcpy(spec->autocfg.line_out_pins, spec->autocfg.hp_pins, + sizeof(spec->autocfg.hp_pins)); + spec->autocfg.line_outs = spec->autocfg.hp_outs; + hp_speaker_swap = 1; + } + if (spec->autocfg.mono_out_pin) { + int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) & + (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP); + u32 caps = query_amp_caps(codec, + spec->autocfg.mono_out_pin, dir); + hda_nid_t conn_list[1]; + + /* get the mixer node and then the mono mux if it exists */ + if (snd_hda_get_connections(codec, + spec->autocfg.mono_out_pin, conn_list, 1) && + snd_hda_get_connections(codec, conn_list[0], + conn_list, 1)) { + + int wcaps = get_wcaps(codec, conn_list[0]); + int wid_type = (wcaps & AC_WCAP_TYPE) + >> AC_WCAP_TYPE_SHIFT; + /* LR swap check, some stac925x have a mux that + * changes the DACs output path instead of the + * mono-mux path. + */ + if (wid_type == AC_WID_AUD_SEL && + !(wcaps & AC_WCAP_LR_SWAP)) + spec->mono_nid = conn_list[0]; + } + if (dir) { + hda_nid_t nid = spec->autocfg.mono_out_pin; + + /* most mono outs have a least a mute/unmute switch */ + dir = (dir & AC_WCAP_OUT_AMP) ? HDA_OUTPUT : HDA_INPUT; + err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, + "Mono Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 1, 0, dir)); + if (err < 0) + return err; + /* check for volume support for the amp */ + if ((caps & AC_AMPCAP_NUM_STEPS) + >> AC_AMPCAP_NUM_STEPS_SHIFT) { + err = stac92xx_add_control(spec, + STAC_CTL_WIDGET_VOL, + "Mono Playback Volume", + HDA_COMPOSE_AMP_VAL(nid, 1, 0, dir)); + if (err < 0) + return err; + } + } + + stac92xx_auto_set_pinctl(codec, spec->autocfg.mono_out_pin, + AC_PINCTL_OUT_EN); + } + + if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0) + return err; + if (spec->multiout.num_dacs == 0) + if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) + return err; + + err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg); + + if (err < 0) + return err; + + /* setup analog beep controls */ + if (spec->anabeep_nid > 0) { + err = stac92xx_auto_create_beep_ctls(codec, + spec->anabeep_nid); + if (err < 0) + return err; + } + + /* setup digital beep controls and input device */ +#ifdef CONFIG_SND_HDA_INPUT_BEEP + if (spec->digbeep_nid > 0) { + hda_nid_t nid = spec->digbeep_nid; + unsigned int caps; + + err = stac92xx_auto_create_beep_ctls(codec, nid); + if (err < 0) + return err; + err = snd_hda_attach_beep_device(codec, nid); + if (err < 0) + return err; + /* if no beep switch is available, make its own one */ + caps = query_amp_caps(codec, nid, HDA_OUTPUT); + if (codec->beep && + !((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT)) { + err = stac92xx_beep_switch_ctl(codec); + if (err < 0) + return err; + } + } +#endif + + if (hp_speaker_swap == 1) { + /* Restore the hp_outs and line_outs */ + memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins, + sizeof(spec->autocfg.line_out_pins)); + spec->autocfg.hp_outs = spec->autocfg.line_outs; + memcpy(spec->autocfg.line_out_pins, spec->autocfg.speaker_pins, + sizeof(spec->autocfg.speaker_pins)); + spec->autocfg.line_outs = spec->autocfg.speaker_outs; + memset(spec->autocfg.speaker_pins, 0, + sizeof(spec->autocfg.speaker_pins)); + spec->autocfg.speaker_outs = 0; + } + + err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg); + + if (err < 0) + return err; + + err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg); + + if (err < 0) + return err; + + if (spec->mono_nid > 0) { + err = stac92xx_auto_create_mono_output_ctls(codec); + if (err < 0) + return err; + } + if (spec->num_amps > 0) { + err = stac92xx_auto_create_amp_output_ctls(codec); + if (err < 0) + return err; + } + if (spec->num_dmics > 0 && !spec->dinput_mux) + if ((err = stac92xx_auto_create_dmic_input_ctls(codec, + &spec->autocfg)) < 0) + return err; + if (spec->num_muxes > 0) { + err = stac92xx_auto_create_mux_input_ctls(codec); + if (err < 0) + return err; + } + if (spec->num_smuxes > 0) { + err = stac92xx_auto_create_spdif_mux_ctls(codec); + if (err < 0) + return err; + } + + spec->multiout.max_channels = spec->multiout.num_dacs * 2; + if (spec->multiout.max_channels > 2) + spec->surr_switch = 1; + + if (spec->autocfg.dig_out_pin) + spec->multiout.dig_out_nid = dig_out; + if (dig_in && spec->autocfg.dig_in_pin) + spec->dig_in_nid = dig_in; + + if (spec->kctl_alloc) + spec->mixers[spec->num_mixers++] = spec->kctl_alloc; + + spec->input_mux = &spec->private_imux; + spec->dinput_mux = &spec->private_dimux; + spec->sinput_mux = &spec->private_smux; + spec->mono_mux = &spec->private_mono_mux; + spec->amp_mux = &spec->private_amp_mux; + return 1; +} + +/* add playback controls for HP output */ +static int stac9200_auto_create_hp_ctls(struct hda_codec *codec, + struct auto_pin_cfg *cfg) +{ + struct sigmatel_spec *spec = codec->spec; + hda_nid_t pin = cfg->hp_pins[0]; + unsigned int wid_caps; + + if (! pin) + return 0; + + wid_caps = get_wcaps(codec, pin); + if (wid_caps & AC_WCAP_UNSOL_CAP) + spec->hp_detect = 1; + + return 0; +} + +/* add playback controls for LFE output */ +static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec, + struct auto_pin_cfg *cfg) +{ + struct sigmatel_spec *spec = codec->spec; + int err; + hda_nid_t lfe_pin = 0x0; + int i; + + /* + * search speaker outs and line outs for a mono speaker pin + * with an amp. If one is found, add LFE controls + * for it. + */ + for (i = 0; i < spec->autocfg.speaker_outs && lfe_pin == 0x0; i++) { + hda_nid_t pin = spec->autocfg.speaker_pins[i]; + unsigned int wcaps = get_wcaps(codec, pin); + wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP); + if (wcaps == AC_WCAP_OUT_AMP) + /* found a mono speaker with an amp, must be lfe */ + lfe_pin = pin; + } + + /* if speaker_outs is 0, then speakers may be in line_outs */ + if (lfe_pin == 0 && spec->autocfg.speaker_outs == 0) { + for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) { + hda_nid_t pin = spec->autocfg.line_out_pins[i]; + unsigned int defcfg; + defcfg = snd_hda_codec_read(codec, pin, 0, + AC_VERB_GET_CONFIG_DEFAULT, + 0x00); + if (get_defcfg_device(defcfg) == AC_JACK_SPEAKER) { + unsigned int wcaps = get_wcaps(codec, pin); + wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP); + if (wcaps == AC_WCAP_OUT_AMP) + /* found a mono speaker with an amp, + must be lfe */ + lfe_pin = pin; + } + } + } + + if (lfe_pin) { + err = create_controls(spec, "LFE", lfe_pin, 1); + if (err < 0) + return err; + } + + return 0; +} + +static int stac9200_parse_auto_config(struct hda_codec *codec) +{ + struct sigmatel_spec *spec = codec->spec; + int err; + + if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0) + return err; + + if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0) + return err; + + if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0) + return err; + + if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0) + return err; + + if (spec->num_muxes > 0) { + err = stac92xx_auto_create_mux_input_ctls(codec); + if (err < 0) + return err; + } + + if (spec->autocfg.dig_out_pin) + spec->multiout.dig_out_nid = 0x05; + if (spec->autocfg.dig_in_pin) + spec->dig_in_nid = 0x04; + + if (spec->kctl_alloc) + spec->mixers[spec->num_mixers++] = spec->kctl_alloc; + + spec->input_mux = &spec->private_imux; + spec->dinput_mux = &spec->private_dimux; + + return 1; +} + +static int stac9202_parse_auto_config(struct hda_codec *codec) +{ + struct sigmatel_spec *spec = codec->spec; + int err; + + if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0) + return err; + + if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0) + return err; + + if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0) + return err; + + if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0) + return err; + + if (spec->autocfg.dig_out_pin) + spec->multiout.dig_out_nid = 0x05; + if (spec->autocfg.dig_in_pin) + spec->dig_in_nid = 0x04; + + if (spec->kctl_alloc) + spec->mixers[spec->num_mixers++] = spec->kctl_alloc; + + spec->input_mux = &spec->private_imux; + spec->dinput_mux = &spec->private_dimux; + + return 1; +} + +/* + * Early 2006 Intel Macintoshes with STAC9220X5 codecs seem to have a + * funky external mute control using GPIO pins. + */ + +static void stac_gpio_set(struct hda_codec *codec, unsigned int mask, + unsigned int dir_mask, unsigned int data) +{ + unsigned int gpiostate, gpiomask, gpiodir; + + gpiostate = snd_hda_codec_read(codec, codec->afg, 0, + AC_VERB_GET_GPIO_DATA, 0); + gpiostate = (gpiostate & ~dir_mask) | (data & dir_mask); + + gpiomask = snd_hda_codec_read(codec, codec->afg, 0, + AC_VERB_GET_GPIO_MASK, 0); + gpiomask |= mask; + + gpiodir = snd_hda_codec_read(codec, codec->afg, 0, + AC_VERB_GET_GPIO_DIRECTION, 0); + gpiodir |= dir_mask; + + /* Configure GPIOx as CMOS */ + snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0); + + snd_hda_codec_write(codec, codec->afg, 0, + AC_VERB_SET_GPIO_MASK, gpiomask); + snd_hda_codec_read(codec, codec->afg, 0, + AC_VERB_SET_GPIO_DIRECTION, gpiodir); /* sync */ + + msleep(1); + + snd_hda_codec_read(codec, codec->afg, 0, + AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */ +} + +static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid, + unsigned int event) +{ + if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) + snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_UNSOLICITED_ENABLE, + (AC_USRSP_EN | event)); +} + +static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid) +{ + int i; + for (i = 0; i < cfg->hp_outs; i++) + if (cfg->hp_pins[i] == nid) + return 1; /* nid is a HP-Out */ + + return 0; /* nid is not a HP-Out */ +}; + +static void stac92xx_power_down(struct hda_codec *codec) +{ + struct sigmatel_spec *spec = codec->spec; + + /* power down inactive DACs */ + hda_nid_t *dac; + for (dac = spec->dac_list; *dac; dac++) + if (!is_in_dac_nids(spec, *dac) && + spec->multiout.hp_nid != *dac) + snd_hda_codec_write_cache(codec, *dac, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); +} + +static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, + int enable); + +static int stac92xx_init(struct hda_codec *codec) +{ + struct sigmatel_spec *spec = codec->spec; + struct auto_pin_cfg *cfg = &spec->autocfg; + unsigned int gpio; + int i; + + snd_hda_sequence_write(codec, spec->init); + + /* power down adcs initially */ + if (spec->powerdown_adcs) + for (i = 0; i < spec->num_adcs; i++) + snd_hda_codec_write_cache(codec, + spec->adc_nids[i], 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); + + /* set up GPIO */ + gpio = spec->gpio_data; + /* turn on EAPD statically when spec->eapd_switch isn't set. + * otherwise, unsol event will turn it on/off dynamically + */ + if (!spec->eapd_switch) + gpio |= spec->eapd_mask; + stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, gpio); + + /* set up pins */ + if (spec->hp_detect) { + /* Enable unsolicited responses on the HP widget */ + for (i = 0; i < cfg->hp_outs; i++) + enable_pin_detect(codec, cfg->hp_pins[i], + STAC_HP_EVENT); + /* force to enable the first line-out; the others are set up + * in unsol_event + */ + stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0], + AC_PINCTL_OUT_EN); + stac92xx_auto_init_hp_out(codec); + /* fake event to set up pins */ + codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); + } else { + stac92xx_auto_init_multi_out(codec); + stac92xx_auto_init_hp_out(codec); + } + for (i = 0; i < AUTO_PIN_LAST; i++) { + hda_nid_t nid = cfg->input_pins[i]; + if (nid) { + unsigned int pinctl; + if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) { + /* for mic pins, force to initialize */ + pinctl = stac92xx_get_vref(codec, nid); + } else { + pinctl = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_PIN_WIDGET_CONTROL, 0); + /* if PINCTL already set then skip */ + if (pinctl & AC_PINCTL_IN_EN) + continue; + } + pinctl |= AC_PINCTL_IN_EN; + stac92xx_auto_set_pinctl(codec, nid, pinctl); + } + } + for (i = 0; i < spec->num_dmics; i++) + stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i], + AC_PINCTL_IN_EN); + if (cfg->dig_out_pin) + stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin, + AC_PINCTL_OUT_EN); + if (cfg->dig_in_pin) + stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin, + AC_PINCTL_IN_EN); + for (i = 0; i < spec->num_pwrs; i++) { + hda_nid_t nid = spec->pwr_nids[i]; + int pinctl, def_conf; + int event = STAC_PWR_EVENT; + + if (is_nid_hp_pin(cfg, nid) && spec->hp_detect) + continue; /* already has an unsol event */ + + pinctl = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_PIN_WIDGET_CONTROL, 0); + /* outputs are only ports capable of power management + * any attempts on powering down a input port cause the + * referenced VREF to act quirky. + */ + if (pinctl & AC_PINCTL_IN_EN) + continue; + def_conf = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_CONFIG_DEFAULT, 0); + def_conf = get_defcfg_connect(def_conf); + /* skip any ports that don't have jacks since presence + * detection is useless */ + if (def_conf != AC_JACK_PORT_COMPLEX) { + if (def_conf != AC_JACK_PORT_NONE) + stac_toggle_power_map(codec, nid, 1); + continue; + } + enable_pin_detect(codec, spec->pwr_nids[i], event | i); + codec->patch_ops.unsol_event(codec, (event | i) << 26); + } + if (spec->dac_list) + stac92xx_power_down(codec); + return 0; +} + +static void stac92xx_free(struct hda_codec *codec) +{ + struct sigmatel_spec *spec = codec->spec; + int i; + + if (! spec) + return; + + if (spec->kctl_alloc) { + for (i = 0; i < spec->num_kctl_used; i++) + kfree(spec->kctl_alloc[i].name); + kfree(spec->kctl_alloc); + } + + if (spec->bios_pin_configs) + kfree(spec->bios_pin_configs); + + kfree(spec); + snd_hda_detach_beep_device(codec); +} + +static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, + unsigned int flag) +{ + unsigned int pin_ctl = snd_hda_codec_read(codec, nid, + 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); + + if (pin_ctl & AC_PINCTL_IN_EN) { + /* + * we need to check the current set-up direction of + * shared input pins since they can be switched via + * "xxx as Output" mixer switch + */ + struct sigmatel_spec *spec = codec->spec; + struct auto_pin_cfg *cfg = &spec->autocfg; + if ((nid == cfg->input_pins[AUTO_PIN_LINE] && + spec->line_switch) || + (nid == cfg->input_pins[AUTO_PIN_MIC] && + spec->mic_switch)) + return; + } + + /* if setting pin direction bits, clear the current + direction bits first */ + if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)) + pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN); + + snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + pin_ctl | flag); +} + +static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid, + unsigned int flag) +{ + unsigned int pin_ctl = snd_hda_codec_read(codec, nid, + 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); + snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + pin_ctl & ~flag); +} + +static int get_hp_pin_presence(struct hda_codec *codec, hda_nid_t nid) +{ + if (!nid) + return 0; + if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00) + & (1 << 31)) { + unsigned int pinctl; + pinctl = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_PIN_WIDGET_CONTROL, 0); + if (pinctl & AC_PINCTL_IN_EN) + return 0; /* mic- or line-input */ + else + return 1; /* HP-output */ + } + return 0; +} + +/* return non-zero if the hp-pin of the given array index isn't + * a jack-detection target + */ +static int no_hp_sensing(struct sigmatel_spec *spec, int i) +{ + struct auto_pin_cfg *cfg = &spec->autocfg; + + /* ignore sensing of shared line and mic jacks */ + if (spec->line_switch && + cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_LINE]) + return 1; + if (spec->mic_switch && + cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_MIC]) + return 1; + /* ignore if the pin is set as line-out */ + if (cfg->hp_pins[i] == spec->hp_switch) + return 1; + return 0; +} + +static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res) +{ + struct sigmatel_spec *spec = codec->spec; + struct auto_pin_cfg *cfg = &spec->autocfg; + int i, presence; + + presence = 0; + if (spec->gpio_mute) + presence = !(snd_hda_codec_read(codec, codec->afg, 0, + AC_VERB_GET_GPIO_DATA, 0) & spec->gpio_mute); + + for (i = 0; i < cfg->hp_outs; i++) { + if (presence) + break; + if (no_hp_sensing(spec, i)) + continue; + presence = get_hp_pin_presence(codec, cfg->hp_pins[i]); + } + + if (presence) { + /* disable lineouts */ + if (spec->hp_switch) + stac92xx_reset_pinctl(codec, spec->hp_switch, + AC_PINCTL_OUT_EN); + for (i = 0; i < cfg->line_outs; i++) + stac92xx_reset_pinctl(codec, cfg->line_out_pins[i], + AC_PINCTL_OUT_EN); + for (i = 0; i < cfg->speaker_outs; i++) + stac92xx_reset_pinctl(codec, cfg->speaker_pins[i], + AC_PINCTL_OUT_EN); + if (spec->eapd_mask && spec->eapd_switch) + stac_gpio_set(codec, spec->gpio_mask, + spec->gpio_dir, spec->gpio_data & + ~spec->eapd_mask); + } else { + /* enable lineouts */ + if (spec->hp_switch) + stac92xx_set_pinctl(codec, spec->hp_switch, + AC_PINCTL_OUT_EN); + for (i = 0; i < cfg->line_outs; i++) + stac92xx_set_pinctl(codec, cfg->line_out_pins[i], + AC_PINCTL_OUT_EN); + for (i = 0; i < cfg->speaker_outs; i++) + stac92xx_set_pinctl(codec, cfg->speaker_pins[i], + AC_PINCTL_OUT_EN); + if (spec->eapd_mask && spec->eapd_switch) + stac_gpio_set(codec, spec->gpio_mask, + spec->gpio_dir, spec->gpio_data | + spec->eapd_mask); + } + /* toggle hp outs */ + for (i = 0; i < cfg->hp_outs; i++) { + unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN; + if (no_hp_sensing(spec, i)) + continue; + if (presence) + stac92xx_set_pinctl(codec, cfg->hp_pins[i], val); +#if 0 /* FIXME */ +/* Resetting the pinctl like below may lead to (a sort of) regressions + * on some devices since they use the HP pin actually for line/speaker + * outs although the default pin config shows a different pin (that is + * wrong and useless). + * + * So, it's basically a problem of default pin configs, likely a BIOS issue. + * But, disabling the code below just works around it, and I'm too tired of + * bug reports with such devices... + */ + else + stac92xx_reset_pinctl(codec, cfg->hp_pins[i], val); +#endif /* FIXME */ + } +} + +static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, + int enable) +{ + struct sigmatel_spec *spec = codec->spec; + unsigned int idx, val; + + for (idx = 0; idx < spec->num_pwrs; idx++) { + if (spec->pwr_nids[idx] == nid) + break; + } + if (idx >= spec->num_pwrs) + return; + + /* several codecs have two power down bits */ + if (spec->pwr_mapping) + idx = spec->pwr_mapping[idx]; + else + idx = 1 << idx; + + val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) & 0xff; + if (enable) + val &= ~idx; + else + val |= idx; + + /* power down unused output ports */ + snd_hda_codec_write(codec, codec->afg, 0, 0x7ec, val); +} + +static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid) +{ + stac_toggle_power_map(codec, nid, get_hp_pin_presence(codec, nid)); +} + +static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) +{ + struct sigmatel_spec *spec = codec->spec; + int idx = res >> 26 & 0x0f; + + switch ((res >> 26) & 0x70) { + case STAC_HP_EVENT: + stac92xx_hp_detect(codec, res); + /* fallthru */ + case STAC_PWR_EVENT: + if (spec->num_pwrs > 0) + stac92xx_pin_sense(codec, idx); + break; + case STAC_VREF_EVENT: { + int data = snd_hda_codec_read(codec, codec->afg, 0, + AC_VERB_GET_GPIO_DATA, 0); + /* toggle VREF state based on GPIOx status */ + snd_hda_codec_write(codec, codec->afg, 0, 0x7e0, + !!(data & (1 << idx))); + break; + } + } +} + +#ifdef SND_HDA_NEEDS_RESUME +static int stac92xx_resume(struct hda_codec *codec) +{ + struct sigmatel_spec *spec = codec->spec; + + stac92xx_set_config_regs(codec); + snd_hda_sequence_write(codec, spec->init); + stac_gpio_set(codec, spec->gpio_mask, + spec->gpio_dir, spec->gpio_data); + snd_hda_codec_resume_amp(codec); + snd_hda_codec_resume_cache(codec); + /* power down inactive DACs */ + if (spec->dac_list) + stac92xx_power_down(codec); + /* invoke unsolicited event to reset the HP state */ + if (spec->hp_detect) + codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); + return 0; +} +#endif + +static struct hda_codec_ops stac92xx_patch_ops = { + .build_controls = stac92xx_build_controls, + .build_pcms = stac92xx_build_pcms, + .init = stac92xx_init, + .free = stac92xx_free, + .unsol_event = stac92xx_unsol_event, +#ifdef SND_HDA_NEEDS_RESUME + .resume = stac92xx_resume, +#endif +}; + +static int patch_stac9200(struct hda_codec *codec) +{ + struct sigmatel_spec *spec; + int err; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (spec == NULL) + return -ENOMEM; + + codec->spec = spec; + spec->num_pins = ARRAY_SIZE(stac9200_pin_nids); + spec->pin_nids = stac9200_pin_nids; + spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS, + stac9200_models, + stac9200_cfg_tbl); + if (spec->board_config < 0) { + snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n"); + err = stac92xx_save_bios_config_regs(codec); + if (err < 0) { + stac92xx_free(codec); + return err; + } + spec->pin_configs = spec->bios_pin_configs; + } else { + spec->pin_configs = stac9200_brd_tbl[spec->board_config]; + stac92xx_set_config_regs(codec); + } + + spec->multiout.max_channels = 2; + spec->multiout.num_dacs = 1; + spec->multiout.dac_nids = stac9200_dac_nids; + spec->adc_nids = stac9200_adc_nids; + spec->mux_nids = stac9200_mux_nids; + spec->num_muxes = 1; + spec->num_dmics = 0; + spec->num_adcs = 1; + spec->num_pwrs = 0; + + if (spec->board_config == STAC_9200_M4 || + spec->board_config == STAC_9200_M4_2 || + spec->board_config == STAC_9200_OQO) + spec->init = stac9200_eapd_init; + else + spec->init = stac9200_core_init; + spec->mixer = stac9200_mixer; + + if (spec->board_config == STAC_9200_PANASONIC) { + spec->gpio_mask = spec->gpio_dir = 0x09; + spec->gpio_data = 0x00; + } + + err = stac9200_parse_auto_config(codec); + if (err < 0) { + stac92xx_free(codec); + return err; + } + + /* CF-74 has no headphone detection, and the driver should *NOT* + * do detection and HP/speaker toggle because the hardware does it. + */ + if (spec->board_config == STAC_9200_PANASONIC) + spec->hp_detect = 0; + + codec->patch_ops = stac92xx_patch_ops; + + return 0; +} + +static int patch_stac9202(struct hda_codec *codec) +{ + struct sigmatel_spec *spec; + int err; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (spec == NULL) + return -ENOMEM; + + codec->spec = spec; + spec->num_pins = 9; + spec->pin_nids = stac9202_pin_nids; + spec->board_config = snd_hda_check_board_config(codec, STAC_9202_MODELS, + stac9202_models, + stac9202_cfg_tbl); + if (spec->board_config < 0) { + snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9202, using BIOS defaults\n"); + err = stac92xx_save_bios_config_regs(codec); + if (err < 0) { + stac92xx_free(codec); + return err; + } + spec->pin_configs = spec->bios_pin_configs; + } else { + spec->pin_configs = stac9202_brd_tbl[spec->board_config]; + stac92xx_set_config_regs(codec); + } + + switch (spec->board_config) { + case STAC_9202_TEST1: + snd_printdd(KERN_INFO "here in test1 %x\n", spec->board_config); + spec->multiout.max_channels = 2; + spec->multiout.num_dacs = 1; + spec->multiout.dac_nids = stac9202_dac_nids; + spec->adc_nids = stac9202_adc_nids; + spec->mux_nids = stac9202_mux_nids; + spec->dmic_nids = stac9202_dmic_nids; + spec->num_dmics = 1; + spec->num_muxes = 1; + spec->init = stac9202_test1_init; + spec->mixer = stac9202_test1_mixer; + break; + default: + snd_printdd(KERN_INFO "here in default %x\n", spec->board_config); + spec->multiout.max_channels = 2; + spec->multiout.num_dacs = 1; + spec->multiout.dac_nids = stac9202_dac_nids; + spec->adc_nids = stac9202_adc_nids; + spec->mux_nids = stac9202_mux_nids; + spec->dmic_nids = stac9202_dmic_nids; + spec->num_muxes = 1; + spec->num_dmics = 1; + spec->init = stac9202_core_init; + spec->mixer = stac9202_mixer; + } + + err = stac9202_parse_auto_config(codec); + if (err < 0) { + stac92xx_free(codec); + return err; + } + + codec->patch_ops = stac92xx_patch_ops; + + return 0; +} + + + +static int patch_stac925x(struct hda_codec *codec) +{ + struct sigmatel_spec *spec; + int err; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (spec == NULL) + return -ENOMEM; + + codec->spec = spec; + spec->num_pins = ARRAY_SIZE(stac925x_pin_nids); + spec->pin_nids = stac925x_pin_nids; + + /* Check first for codec ID */ + spec->board_config = snd_hda_check_board_codec_sid_config(codec, + STAC_925x_MODELS, + stac925x_models, + stac925x_codec_id_cfg_tbl); + + /* Now checks for PCI ID, if codec ID is not found */ + if (spec->board_config < 0) + spec->board_config = snd_hda_check_board_config(codec, + STAC_925x_MODELS, + stac925x_models, + stac925x_cfg_tbl); + again: + if (spec->board_config < 0) { + snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x," + "using BIOS defaults\n"); + err = stac92xx_save_bios_config_regs(codec); + if (err < 0) { + stac92xx_free(codec); + return err; + } + spec->pin_configs = spec->bios_pin_configs; + } else if (stac925x_brd_tbl[spec->board_config] != NULL){ + spec->pin_configs = stac925x_brd_tbl[spec->board_config]; + stac92xx_set_config_regs(codec); + } + + spec->multiout.max_channels = 2; + spec->multiout.num_dacs = 1; + spec->multiout.dac_nids = stac925x_dac_nids; + spec->adc_nids = stac925x_adc_nids; + spec->mux_nids = stac925x_mux_nids; + spec->num_muxes = 1; + spec->num_adcs = 1; + spec->num_pwrs = 0; + switch (codec->vendor_id) { + case 0x83847632: /* STAC9202 */ + case 0x83847633: /* STAC9202D */ + case 0x83847636: /* STAC9251 */ + case 0x83847637: /* STAC9251D */ + spec->num_dmics = STAC925X_NUM_DMICS; + spec->dmic_nids = stac925x_dmic_nids; + spec->num_dmuxes = ARRAY_SIZE(stac925x_dmux_nids); + spec->dmux_nids = stac925x_dmux_nids; + break; + default: + spec->num_dmics = 0; + break; + } + + spec->init = stac925x_core_init; + spec->mixer = stac925x_mixer; + + err = stac92xx_parse_auto_config(codec, 0x8, 0x7); + if (!err) { + if (spec->board_config < 0) { + printk(KERN_WARNING "hda_codec: No auto-config is " + "available, default to model=ref\n"); + spec->board_config = STAC_925x_REF; + goto again; + } + err = -EINVAL; + } + if (err < 0) { + stac92xx_free(codec); + return err; + } + + codec->patch_ops = stac92xx_patch_ops; + + return 0; +} + +static struct hda_input_mux stac92hd73xx_dmux = { + .num_items = 4, + .items = { + { "Analog Inputs", 0x0b }, + { "Digital Mic 1", 0x09 }, + { "Digital Mic 2", 0x0a }, + { "CD", 0x08 }, + } +}; + +static int patch_stac92hd73xx(struct hda_codec *codec) +{ + struct sigmatel_spec *spec; + hda_nid_t conn[STAC92HD73_DAC_COUNT + 2]; + int err = 0; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (spec == NULL) + return -ENOMEM; + + codec->spec = spec; + codec->slave_dig_outs = stac92hd73xx_slave_dig_outs; + spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids); + spec->pin_nids = stac92hd73xx_pin_nids; + spec->board_config = snd_hda_check_board_config(codec, + STAC_92HD73XX_MODELS, + stac92hd73xx_models, + stac92hd73xx_cfg_tbl); +again: + if (spec->board_config < 0) { + snd_printdd(KERN_INFO "hda_codec: Unknown model for" + " STAC92HD73XX, using BIOS defaults\n"); + err = stac92xx_save_bios_config_regs(codec); + if (err < 0) { + stac92xx_free(codec); + return err; + } + spec->pin_configs = spec->bios_pin_configs; + } else { + spec->pin_configs = stac92hd73xx_brd_tbl[spec->board_config]; + stac92xx_set_config_regs(codec); + } + + spec->multiout.num_dacs = snd_hda_get_connections(codec, 0x0a, + conn, STAC92HD73_DAC_COUNT + 2) - 1; + + if (spec->multiout.num_dacs < 0) { + printk(KERN_WARNING "hda_codec: Could not determine " + "number of channels defaulting to DAC count\n"); + spec->multiout.num_dacs = STAC92HD73_DAC_COUNT; + } + + switch (spec->multiout.num_dacs) { + case 0x3: /* 6 Channel */ + spec->multiout.hp_nid = 0x17; + spec->mixer = stac92hd73xx_6ch_mixer; + spec->init = stac92hd73xx_6ch_core_init; + break; + case 0x4: /* 8 Channel */ + spec->multiout.hp_nid = 0x18; + spec->mixer = stac92hd73xx_8ch_mixer; + spec->init = stac92hd73xx_8ch_core_init; + break; + case 0x5: /* 10 Channel */ + spec->multiout.hp_nid = 0x19; + spec->mixer = stac92hd73xx_10ch_mixer; + spec->init = stac92hd73xx_10ch_core_init; + }; + + spec->multiout.dac_nids = stac92hd73xx_dac_nids; + spec->aloopback_mask = 0x01; + spec->aloopback_shift = 8; + + spec->digbeep_nid = 0x1c; + spec->mux_nids = stac92hd73xx_mux_nids; + spec->adc_nids = stac92hd73xx_adc_nids; + spec->dmic_nids = stac92hd73xx_dmic_nids; + spec->dmux_nids = stac92hd73xx_dmux_nids; + spec->smux_nids = stac92hd73xx_smux_nids; + spec->amp_nids = stac92hd73xx_amp_nids; + spec->num_amps = ARRAY_SIZE(stac92hd73xx_amp_nids); + + spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids); + spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids); + spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids); + memcpy(&spec->private_dimux, &stac92hd73xx_dmux, + sizeof(stac92hd73xx_dmux)); + + switch (spec->board_config) { + case STAC_DELL_EQ: + spec->init = dell_eq_core_init; + /* fallthru */ + case STAC_DELL_M6_AMIC: + case STAC_DELL_M6_DMIC: + case STAC_DELL_M6_BOTH: + spec->num_smuxes = 0; + spec->mixer = &stac92hd73xx_6ch_mixer[DELL_M6_MIXER]; + spec->amp_nids = &stac92hd73xx_amp_nids[DELL_M6_AMP]; + spec->eapd_switch = 0; + spec->num_amps = 1; + spec->multiout.hp_nid = 0; /* dual HPs */ + + if (!spec->init) + spec->init = dell_m6_core_init; + switch (spec->board_config) { + case STAC_DELL_M6_AMIC: /* Analog Mics */ + stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); + spec->num_dmics = 0; + spec->private_dimux.num_items = 1; + break; + case STAC_DELL_M6_DMIC: /* Digital Mics */ + stac92xx_set_config_reg(codec, 0x13, 0x90A60160); + spec->num_dmics = 1; + spec->private_dimux.num_items = 2; + break; + case STAC_DELL_M6_BOTH: /* Both */ + stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); + stac92xx_set_config_reg(codec, 0x13, 0x90A60160); + spec->num_dmics = 1; + spec->private_dimux.num_items = 2; + break; + } + break; + default: + spec->num_dmics = STAC92HD73XX_NUM_DMICS; + spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids); + spec->eapd_switch = 1; + } + if (spec->board_config > STAC_92HD73XX_REF) { + /* GPIO0 High = Enable EAPD */ + spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; + spec->gpio_data = 0x01; + } + spec->dinput_mux = &spec->private_dimux; + + spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids); + spec->pwr_nids = stac92hd73xx_pwr_nids; + + err = stac92xx_parse_auto_config(codec, 0x25, 0x27); + + if (!err) { + if (spec->board_config < 0) { + printk(KERN_WARNING "hda_codec: No auto-config is " + "available, default to model=ref\n"); + spec->board_config = STAC_92HD73XX_REF; + goto again; + } + err = -EINVAL; + } + + if (err < 0) { + stac92xx_free(codec); + return err; + } + + if (spec->board_config == STAC_92HD73XX_NO_JD) + spec->hp_detect = 0; + + codec->patch_ops = stac92xx_patch_ops; + + return 0; +} + +static struct hda_input_mux stac92hd83xxx_dmux = { + .num_items = 3, + .items = { + { "Analog Inputs", 0x03 }, + { "Digital Mic 1", 0x04 }, + { "Digital Mic 2", 0x05 }, + } +}; + +static int patch_stac92hd83xxx(struct hda_codec *codec) +{ + struct sigmatel_spec *spec; + int err; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (spec == NULL) + return -ENOMEM; + + codec->spec = spec; + codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; + spec->mono_nid = 0x19; + spec->digbeep_nid = 0x21; + spec->dmic_nids = stac92hd83xxx_dmic_nids; + spec->dmux_nids = stac92hd83xxx_dmux_nids; + spec->adc_nids = stac92hd83xxx_adc_nids; + spec->pwr_nids = stac92hd83xxx_pwr_nids; + spec->pwr_mapping = stac92hd83xxx_pwr_mapping; + spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); + spec->multiout.dac_nids = stac92hd83xxx_dac_nids; + + spec->init = stac92hd83xxx_core_init; + switch (codec->vendor_id) { + case 0x111d7605: + spec->multiout.num_dacs = STAC92HD81_DAC_COUNT; + break; + default: + spec->num_pwrs--; + spec->init++; /* switch to config #2 */ + spec->multiout.num_dacs = STAC92HD83_DAC_COUNT; + } + + spec->mixer = stac92hd83xxx_mixer; + spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids); + spec->num_dmuxes = ARRAY_SIZE(stac92hd83xxx_dmux_nids); + spec->num_adcs = ARRAY_SIZE(stac92hd83xxx_adc_nids); + spec->num_dmics = STAC92HD83XXX_NUM_DMICS; + spec->dinput_mux = &stac92hd83xxx_dmux; + spec->pin_nids = stac92hd83xxx_pin_nids; + spec->board_config = snd_hda_check_board_config(codec, + STAC_92HD83XXX_MODELS, + stac92hd83xxx_models, + stac92hd83xxx_cfg_tbl); +again: + if (spec->board_config < 0) { + snd_printdd(KERN_INFO "hda_codec: Unknown model for" + " STAC92HD83XXX, using BIOS defaults\n"); + err = stac92xx_save_bios_config_regs(codec); + if (err < 0) { + stac92xx_free(codec); + return err; + } + spec->pin_configs = spec->bios_pin_configs; + } else { + spec->pin_configs = stac92hd83xxx_brd_tbl[spec->board_config]; + stac92xx_set_config_regs(codec); + } + + err = stac92xx_parse_auto_config(codec, 0x1d, 0); + if (!err) { + if (spec->board_config < 0) { + printk(KERN_WARNING "hda_codec: No auto-config is " + "available, default to model=ref\n"); + spec->board_config = STAC_92HD83XXX_REF; + goto again; + } + err = -EINVAL; + } + + if (err < 0) { + stac92xx_free(codec); + return err; + } + + codec->patch_ops = stac92xx_patch_ops; + + return 0; +} + +#ifdef SND_HDA_NEEDS_RESUME +static void stac92hd71xx_set_power_state(struct hda_codec *codec, int pwr) +{ + struct sigmatel_spec *spec = codec->spec; + int i; + snd_hda_codec_write_cache(codec, codec->afg, 0, + AC_VERB_SET_POWER_STATE, pwr); + + msleep(1); + for (i = 0; i < spec->num_adcs; i++) { + snd_hda_codec_write_cache(codec, + spec->adc_nids[i], 0, + AC_VERB_SET_POWER_STATE, pwr); + } +}; + +static int stac92hd71xx_resume(struct hda_codec *codec) +{ + stac92hd71xx_set_power_state(codec, AC_PWRST_D0); + return stac92xx_resume(codec); +} + +static int stac92hd71xx_suspend(struct hda_codec *codec, pm_message_t state) +{ + struct sigmatel_spec *spec = codec->spec; + + stac92hd71xx_set_power_state(codec, AC_PWRST_D3); + if (spec->eapd_mask) + stac_gpio_set(codec, spec->gpio_mask, + spec->gpio_dir, spec->gpio_data & + ~spec->eapd_mask); + return 0; +}; + +#endif + +static struct hda_codec_ops stac92hd71bxx_patch_ops = { + .build_controls = stac92xx_build_controls, + .build_pcms = stac92xx_build_pcms, + .init = stac92xx_init, + .free = stac92xx_free, + .unsol_event = stac92xx_unsol_event, +#ifdef SND_HDA_NEEDS_RESUME + .resume = stac92hd71xx_resume, + .suspend = stac92hd71xx_suspend, +#endif +}; + +static struct hda_input_mux stac92hd71bxx_dmux = { + .num_items = 4, + .items = { + { "Analog Inputs", 0x00 }, + { "Mixer", 0x01 }, + { "Digital Mic 1", 0x02 }, + { "Digital Mic 2", 0x03 }, + } +}; + +static int patch_stac92hd71bxx(struct hda_codec *codec) +{ + struct sigmatel_spec *spec; + int err = 0; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (spec == NULL) + return -ENOMEM; + + codec->spec = spec; + codec->patch_ops = stac92xx_patch_ops; + spec->num_pins = ARRAY_SIZE(stac92hd71bxx_pin_nids); + spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); + spec->pin_nids = stac92hd71bxx_pin_nids; + memcpy(&spec->private_dimux, &stac92hd71bxx_dmux, + sizeof(stac92hd71bxx_dmux)); + spec->board_config = snd_hda_check_board_config(codec, + STAC_92HD71BXX_MODELS, + stac92hd71bxx_models, + stac92hd71bxx_cfg_tbl); +again: + if (spec->board_config < 0) { + snd_printdd(KERN_INFO "hda_codec: Unknown model for" + " STAC92HD71BXX, using BIOS defaults\n"); + err = stac92xx_save_bios_config_regs(codec); + if (err < 0) { + stac92xx_free(codec); + return err; + } + spec->pin_configs = spec->bios_pin_configs; + } else { + spec->pin_configs = stac92hd71bxx_brd_tbl[spec->board_config]; + stac92xx_set_config_regs(codec); + } + + if (spec->board_config > STAC_92HD71BXX_REF) { + /* GPIO0 = EAPD */ + spec->gpio_mask = 0x01; + spec->gpio_dir = 0x01; + spec->gpio_data = 0x01; + } + + switch (codec->vendor_id) { + case 0x111d76b6: /* 4 Port without Analog Mixer */ + case 0x111d76b7: + case 0x111d76b4: /* 6 Port without Analog Mixer */ + case 0x111d76b5: + spec->mixer = stac92hd71bxx_mixer; + spec->init = stac92hd71bxx_core_init; + codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; + break; + case 0x111d7608: /* 5 Port with Analog Mixer */ + switch (spec->board_config) { + case STAC_HP_M4: + /* Enable VREF power saving on GPIO1 detect */ + snd_hda_codec_write_cache(codec, codec->afg, 0, + AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02); + snd_hda_codec_write_cache(codec, codec->afg, 0, + AC_VERB_SET_UNSOLICITED_ENABLE, + (AC_USRSP_EN | STAC_VREF_EVENT | 0x01)); + spec->gpio_mask |= 0x02; + break; + } + if ((codec->revision_id & 0xf) == 0 || + (codec->revision_id & 0xf) == 1) { +#ifdef SND_HDA_NEEDS_RESUME + codec->patch_ops = stac92hd71bxx_patch_ops; +#endif + spec->stream_delay = 40; /* 40 milliseconds */ + } + + /* no output amps */ + spec->num_pwrs = 0; + spec->mixer = stac92hd71bxx_analog_mixer; + spec->dinput_mux = &spec->private_dimux; + + /* disable VSW */ + spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF]; + stac92xx_set_config_reg(codec, 0xf, 0x40f000f0); + break; + case 0x111d7603: /* 6 Port with Analog Mixer */ + if ((codec->revision_id & 0xf) == 1) { +#ifdef SND_HDA_NEEDS_RESUME + codec->patch_ops = stac92hd71bxx_patch_ops; +#endif + spec->stream_delay = 40; /* 40 milliseconds */ + } + + /* no output amps */ + spec->num_pwrs = 0; + /* fallthru */ + default: + spec->dinput_mux = &spec->private_dimux; + spec->mixer = stac92hd71bxx_analog_mixer; + spec->init = stac92hd71bxx_analog_core_init; + codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; + } + + spec->aloopback_mask = 0x50; + spec->aloopback_shift = 0; + + spec->powerdown_adcs = 1; + spec->digbeep_nid = 0x26; + spec->mux_nids = stac92hd71bxx_mux_nids; + spec->adc_nids = stac92hd71bxx_adc_nids; + spec->dmic_nids = stac92hd71bxx_dmic_nids; + spec->dmux_nids = stac92hd71bxx_dmux_nids; + spec->smux_nids = stac92hd71bxx_smux_nids; + spec->pwr_nids = stac92hd71bxx_pwr_nids; + + spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); + spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); + + switch (spec->board_config) { + case STAC_HP_M4: + /* enable internal microphone */ + stac92xx_set_config_reg(codec, 0x0e, 0x01813040); + stac92xx_auto_set_pinctl(codec, 0x0e, + AC_PINCTL_IN_EN | AC_PINCTL_VREF_80); + /* fallthru */ + case STAC_DELL_M4_2: + spec->num_dmics = 0; + spec->num_smuxes = 0; + spec->num_dmuxes = 0; + break; + case STAC_DELL_M4_1: + case STAC_DELL_M4_3: + spec->num_dmics = 1; + spec->num_smuxes = 0; + spec->num_dmuxes = 0; + break; + default: + spec->num_dmics = STAC92HD71BXX_NUM_DMICS; + spec->num_smuxes = ARRAY_SIZE(stac92hd71bxx_smux_nids); + spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); + }; + + spec->multiout.num_dacs = 1; + spec->multiout.hp_nid = 0x11; + spec->multiout.dac_nids = stac92hd71bxx_dac_nids; + if (spec->dinput_mux) + spec->private_dimux.num_items += + spec->num_dmics - + (ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1); + + err = stac92xx_parse_auto_config(codec, 0x21, 0x23); + if (!err) { + if (spec->board_config < 0) { + printk(KERN_WARNING "hda_codec: No auto-config is " + "available, default to model=ref\n"); + spec->board_config = STAC_92HD71BXX_REF; + goto again; + } + err = -EINVAL; + } + + if (err < 0) { + stac92xx_free(codec); + return err; + } + + return 0; +}; + +static int patch_stac922x(struct hda_codec *codec) +{ + struct sigmatel_spec *spec; + int err; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (spec == NULL) + return -ENOMEM; + + codec->spec = spec; + spec->num_pins = ARRAY_SIZE(stac922x_pin_nids); + spec->pin_nids = stac922x_pin_nids; + spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS, + stac922x_models, + stac922x_cfg_tbl); + if (spec->board_config == STAC_INTEL_MAC_AUTO) { + spec->gpio_mask = spec->gpio_dir = 0x03; + spec->gpio_data = 0x03; + /* Intel Macs have all same PCI SSID, so we need to check + * codec SSID to distinguish the exact models + */ + printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id); + switch (codec->subsystem_id) { + + case 0x106b0800: + spec->board_config = STAC_INTEL_MAC_V1; + break; + case 0x106b0600: + case 0x106b0700: + spec->board_config = STAC_INTEL_MAC_V2; + break; + case 0x106b0e00: + case 0x106b0f00: + case 0x106b1600: + case 0x106b1700: + case 0x106b0200: + case 0x106b1e00: + spec->board_config = STAC_INTEL_MAC_V3; + break; + case 0x106b1a00: + case 0x00000100: + spec->board_config = STAC_INTEL_MAC_V4; + break; + case 0x106b0a00: + case 0x106b2200: + spec->board_config = STAC_INTEL_MAC_V5; + break; + default: + spec->board_config = STAC_INTEL_MAC_V3; + break; + } + } + + again: + if (spec->board_config < 0) { + snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, " + "using BIOS defaults\n"); + err = stac92xx_save_bios_config_regs(codec); + if (err < 0) { + stac92xx_free(codec); + return err; + } + spec->pin_configs = spec->bios_pin_configs; + } else if (stac922x_brd_tbl[spec->board_config] != NULL) { + spec->pin_configs = stac922x_brd_tbl[spec->board_config]; + stac92xx_set_config_regs(codec); + } + + spec->adc_nids = stac922x_adc_nids; + spec->mux_nids = stac922x_mux_nids; + spec->num_muxes = ARRAY_SIZE(stac922x_mux_nids); + spec->num_adcs = ARRAY_SIZE(stac922x_adc_nids); + spec->num_dmics = 0; + spec->num_pwrs = 0; + + spec->init = stac922x_core_init; + spec->mixer = stac922x_mixer; + + spec->multiout.dac_nids = spec->dac_nids; + + err = stac92xx_parse_auto_config(codec, 0x08, 0x09); + if (!err) { + if (spec->board_config < 0) { + printk(KERN_WARNING "hda_codec: No auto-config is " + "available, default to model=ref\n"); + spec->board_config = STAC_D945_REF; + goto again; + } + err = -EINVAL; + } + if (err < 0) { + stac92xx_free(codec); + return err; + } + + codec->patch_ops = stac92xx_patch_ops; + + /* Fix Mux capture level; max to 2 */ + snd_hda_override_amp_caps(codec, 0x12, HDA_OUTPUT, + (0 << AC_AMPCAP_OFFSET_SHIFT) | + (2 << AC_AMPCAP_NUM_STEPS_SHIFT) | + (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) | + (0 << AC_AMPCAP_MUTE_SHIFT)); + + return 0; +} + +static int patch_stac927x(struct hda_codec *codec) +{ + struct sigmatel_spec *spec; + int err; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (spec == NULL) + return -ENOMEM; + + codec->spec = spec; + spec->num_pins = ARRAY_SIZE(stac927x_pin_nids); + spec->pin_nids = stac927x_pin_nids; + spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS, + stac927x_models, + stac927x_cfg_tbl); + again: + if (spec->board_config < 0 || !stac927x_brd_tbl[spec->board_config]) { + if (spec->board_config < 0) + snd_printdd(KERN_INFO "hda_codec: Unknown model for" + "STAC927x, using BIOS defaults\n"); + err = stac92xx_save_bios_config_regs(codec); + if (err < 0) { + stac92xx_free(codec); + return err; + } + spec->pin_configs = spec->bios_pin_configs; + } else { + spec->pin_configs = stac927x_brd_tbl[spec->board_config]; + stac92xx_set_config_regs(codec); + } + + spec->digbeep_nid = 0x23; + spec->adc_nids = stac927x_adc_nids; + spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids); + spec->mux_nids = stac927x_mux_nids; + spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); + spec->smux_nids = stac927x_smux_nids; + spec->num_smuxes = ARRAY_SIZE(stac927x_smux_nids); + spec->spdif_labels = stac927x_spdif_labels; + spec->dac_list = stac927x_dac_nids; + spec->multiout.dac_nids = spec->dac_nids; + + switch (spec->board_config) { + case STAC_D965_3ST: + case STAC_D965_5ST: + /* GPIO0 High = Enable EAPD */ + spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x01; + spec->gpio_data = 0x01; + spec->num_dmics = 0; + + spec->init = d965_core_init; + spec->mixer = stac927x_mixer; + break; + case STAC_DELL_BIOS: + switch (codec->subsystem_id) { + case 0x10280209: + case 0x1028022e: + /* correct the device field to SPDIF out */ + stac92xx_set_config_reg(codec, 0x21, 0x01442070); + break; + }; + /* configure the analog microphone on some laptops */ + stac92xx_set_config_reg(codec, 0x0c, 0x90a79130); + /* correct the front output jack as a hp out */ + stac92xx_set_config_reg(codec, 0x0f, 0x0227011f); + /* correct the front input jack as a mic */ + stac92xx_set_config_reg(codec, 0x0e, 0x02a79130); + /* fallthru */ + case STAC_DELL_3ST: + /* GPIO2 High = Enable EAPD */ + spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x04; + spec->gpio_data = 0x04; + spec->dmic_nids = stac927x_dmic_nids; + spec->num_dmics = STAC927X_NUM_DMICS; + + spec->init = d965_core_init; + spec->mixer = stac927x_mixer; + spec->dmux_nids = stac927x_dmux_nids; + spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids); + break; + default: + if (spec->board_config > STAC_D965_REF) { + /* GPIO0 High = Enable EAPD */ + spec->eapd_mask = spec->gpio_mask = 0x01; + spec->gpio_dir = spec->gpio_data = 0x01; + } + spec->num_dmics = 0; + + spec->init = stac927x_core_init; + spec->mixer = stac927x_mixer; + } + + spec->num_pwrs = 0; + spec->aloopback_mask = 0x40; + spec->aloopback_shift = 0; + spec->eapd_switch = 1; + + err = stac92xx_parse_auto_config(codec, 0x1e, 0x20); + if (!err) { + if (spec->board_config < 0) { + printk(KERN_WARNING "hda_codec: No auto-config is " + "available, default to model=ref\n"); + spec->board_config = STAC_D965_REF; + goto again; + } + err = -EINVAL; + } + if (err < 0) { + stac92xx_free(codec); + return err; + } + + codec->patch_ops = stac92xx_patch_ops; + + /* + * !!FIXME!! + * The STAC927x seem to require fairly long delays for certain + * command sequences. With too short delays (even if the answer + * is set to RIRB properly), it results in the silence output + * on some hardwares like Dell. + * + * The below flag enables the longer delay (see get_response + * in hda_intel.c). + */ + codec->bus->needs_damn_long_delay = 1; + + /* no jack detecion for ref-no-jd model */ + if (spec->board_config == STAC_D965_REF_NO_JD) + spec->hp_detect = 0; + + return 0; +} + +static int patch_stac9205(struct hda_codec *codec) +{ + struct sigmatel_spec *spec; + int err; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (spec == NULL) + return -ENOMEM; + + codec->spec = spec; + spec->num_pins = ARRAY_SIZE(stac9205_pin_nids); + spec->pin_nids = stac9205_pin_nids; + spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS, + stac9205_models, + stac9205_cfg_tbl); + again: + if (spec->board_config < 0) { + snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n"); + err = stac92xx_save_bios_config_regs(codec); + if (err < 0) { + stac92xx_free(codec); + return err; + } + spec->pin_configs = spec->bios_pin_configs; + } else { + spec->pin_configs = stac9205_brd_tbl[spec->board_config]; + stac92xx_set_config_regs(codec); + } + + spec->digbeep_nid = 0x23; + spec->adc_nids = stac9205_adc_nids; + spec->num_adcs = ARRAY_SIZE(stac9205_adc_nids); + spec->mux_nids = stac9205_mux_nids; + spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids); + spec->smux_nids = stac9205_smux_nids; + spec->num_smuxes = ARRAY_SIZE(stac9205_smux_nids); + spec->dmic_nids = stac9205_dmic_nids; + spec->num_dmics = STAC9205_NUM_DMICS; + spec->dmux_nids = stac9205_dmux_nids; + spec->num_dmuxes = ARRAY_SIZE(stac9205_dmux_nids); + spec->num_pwrs = 0; + + spec->init = stac9205_core_init; + spec->mixer = stac9205_mixer; + + spec->aloopback_mask = 0x40; + spec->aloopback_shift = 0; + spec->eapd_switch = 1; + spec->multiout.dac_nids = spec->dac_nids; + + switch (spec->board_config){ + case STAC_9205_DELL_M43: + /* Enable SPDIF in/out */ + stac92xx_set_config_reg(codec, 0x1f, 0x01441030); + stac92xx_set_config_reg(codec, 0x20, 0x1c410030); + + /* Enable unsol response for GPIO4/Dock HP connection */ + snd_hda_codec_write_cache(codec, codec->afg, 0, + AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10); + snd_hda_codec_write_cache(codec, codec->afg, 0, + AC_VERB_SET_UNSOLICITED_ENABLE, + (AC_USRSP_EN | STAC_HP_EVENT)); + + spec->gpio_dir = 0x0b; + spec->eapd_mask = 0x01; + spec->gpio_mask = 0x1b; + spec->gpio_mute = 0x10; + /* GPIO0 High = EAPD, GPIO1 Low = Headphone Mute, + * GPIO3 Low = DRM + */ + spec->gpio_data = 0x01; + break; + case STAC_9205_REF: + /* SPDIF-In enabled */ + break; + default: + /* GPIO0 High = EAPD */ + spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; + spec->gpio_data = 0x01; + break; + } + + err = stac92xx_parse_auto_config(codec, 0x1f, 0x20); + if (!err) { + if (spec->board_config < 0) { + printk(KERN_WARNING "hda_codec: No auto-config is " + "available, default to model=ref\n"); + spec->board_config = STAC_9205_REF; + goto again; + } + err = -EINVAL; + } + if (err < 0) { + stac92xx_free(codec); + return err; + } + + codec->patch_ops = stac92xx_patch_ops; + + return 0; +} + +/* + * STAC9872 hack + */ + +/* static config for Sony VAIO FE550G and Sony VAIO AR */ +static hda_nid_t vaio_dacs[] = { 0x2 }; +#define VAIO_HP_DAC 0x5 +static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ }; +static hda_nid_t vaio_mux_nids[] = { 0x15 }; + +static struct hda_input_mux vaio_mux = { + .num_items = 3, + .items = { + /* { "HP", 0x0 }, */ + { "Mic Jack", 0x1 }, + { "Internal Mic", 0x2 }, + { "PCM", 0x3 }, + } +}; + +static struct hda_verb vaio_init[] = { + {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */ + {0x0a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | STAC_HP_EVENT}, + {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */ + {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */ + {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ + {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ + {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ + {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ + {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */ + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */ + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ + {} +}; + +static struct hda_verb vaio_ar_init[] = { + {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */ + {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */ + {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */ + {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ +/* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */ + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ + {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ + {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ + {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ +/* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */ + {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */ + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */ + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ + {} +}; + +/* bind volumes of both NID 0x02 and 0x05 */ +static struct hda_bind_ctls vaio_bind_master_vol = { + .ops = &snd_hda_bind_vol, + .values = { + HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT), + 0 + }, +}; + +/* bind volumes of both NID 0x02 and 0x05 */ +static struct hda_bind_ctls vaio_bind_master_sw = { + .ops = &snd_hda_bind_sw, + .values = { + HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT), + 0, + }, +}; + +static struct snd_kcontrol_new vaio_mixer[] = { + HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol), + HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw), + /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */ + HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Capture Source", + .count = 1, + .info = stac92xx_mux_enum_info, + .get = stac92xx_mux_enum_get, + .put = stac92xx_mux_enum_put, + }, + {} +}; + +static struct snd_kcontrol_new vaio_ar_mixer[] = { + HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol), + HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw), + /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */ + HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), + /*HDA_CODEC_MUTE("Optical Out Switch", 0x10, 0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Optical Out Volume", 0x10, 0, HDA_OUTPUT),*/ + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Capture Source", + .count = 1, + .info = stac92xx_mux_enum_info, + .get = stac92xx_mux_enum_get, + .put = stac92xx_mux_enum_put, + }, + {} +}; + +static struct hda_codec_ops stac9872_patch_ops = { + .build_controls = stac92xx_build_controls, + .build_pcms = stac92xx_build_pcms, + .init = stac92xx_init, + .free = stac92xx_free, +#ifdef SND_HDA_NEEDS_RESUME + .resume = stac92xx_resume, +#endif +}; + +static int stac9872_vaio_init(struct hda_codec *codec) +{ + int err; + + err = stac92xx_init(codec); + if (err < 0) + return err; + if (codec->patch_ops.unsol_event) + codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); + return 0; +} + +static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res) +{ + if (get_hp_pin_presence(codec, 0x0a)) { + stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN); + stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN); + } else { + stac92xx_reset_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN); + stac92xx_set_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN); + } +} + +static void stac9872_vaio_unsol_event(struct hda_codec *codec, unsigned int res) +{ + switch (res >> 26) { + case STAC_HP_EVENT: + stac9872_vaio_hp_detect(codec, res); + break; + } +} + +static struct hda_codec_ops stac9872_vaio_patch_ops = { + .build_controls = stac92xx_build_controls, + .build_pcms = stac92xx_build_pcms, + .init = stac9872_vaio_init, + .free = stac92xx_free, + .unsol_event = stac9872_vaio_unsol_event, +#ifdef CONFIG_PM + .resume = stac92xx_resume, +#endif +}; + +enum { /* FE and SZ series. id=0x83847661 and subsys=0x104D0700 or 104D1000. */ + CXD9872RD_VAIO, + /* Unknown. id=0x83847662 and subsys=0x104D1200 or 104D1000. */ + STAC9872AK_VAIO, + /* Unknown. id=0x83847661 and subsys=0x104D1200. */ + STAC9872K_VAIO, + /* AR Series. id=0x83847664 and subsys=104D1300 */ + CXD9872AKD_VAIO, + STAC_9872_MODELS, +}; + +static const char *stac9872_models[STAC_9872_MODELS] = { + [CXD9872RD_VAIO] = "vaio", + [CXD9872AKD_VAIO] = "vaio-ar", +}; + +static struct snd_pci_quirk stac9872_cfg_tbl[] = { + SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO), + SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO), + SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO), + SND_PCI_QUIRK(0x104d, 0x8205, "Sony VAIO AR", CXD9872AKD_VAIO), + {} +}; + +static int patch_stac9872(struct hda_codec *codec) +{ + struct sigmatel_spec *spec; + int board_config; + + board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS, + stac9872_models, + stac9872_cfg_tbl); + if (board_config < 0) + /* unknown config, let generic-parser do its job... */ + return snd_hda_parse_generic_codec(codec); + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (spec == NULL) + return -ENOMEM; + + codec->spec = spec; + switch (board_config) { + case CXD9872RD_VAIO: + case STAC9872AK_VAIO: + case STAC9872K_VAIO: + spec->mixer = vaio_mixer; + spec->init = vaio_init; + spec->multiout.max_channels = 2; + spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs); + spec->multiout.dac_nids = vaio_dacs; + spec->multiout.hp_nid = VAIO_HP_DAC; + spec->num_adcs = ARRAY_SIZE(vaio_adcs); + spec->adc_nids = vaio_adcs; + spec->num_pwrs = 0; + spec->input_mux = &vaio_mux; + spec->mux_nids = vaio_mux_nids; + codec->patch_ops = stac9872_vaio_patch_ops; + break; + + case CXD9872AKD_VAIO: + spec->mixer = vaio_ar_mixer; + spec->init = vaio_ar_init; + spec->multiout.max_channels = 2; + spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs); + spec->multiout.dac_nids = vaio_dacs; + spec->multiout.hp_nid = VAIO_HP_DAC; + spec->num_adcs = ARRAY_SIZE(vaio_adcs); + spec->num_pwrs = 0; + spec->adc_nids = vaio_adcs; + spec->input_mux = &vaio_mux; + spec->mux_nids = vaio_mux_nids; + codec->patch_ops = stac9872_patch_ops; + break; + } + + return 0; +} + + +/* + * patch entries + */ +struct hda_codec_preset snd_hda_preset_sigmatel[] = { + { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 }, + { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x }, + { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x }, + { .id = 0x83847880, .name = "STAC9220 A2", .patch = patch_stac922x }, + { .id = 0x83847681, .name = "STAC9220D/9223D A2", .patch = patch_stac922x }, + { .id = 0x83847682, .name = "STAC9221 A2", .patch = patch_stac922x }, + { .id = 0x83847683, .name = "STAC9221D A2", .patch = patch_stac922x }, + { .id = 0x83847618, .name = "STAC9227", .patch = patch_stac927x }, + { .id = 0x83847619, .name = "STAC9227", .patch = patch_stac927x }, + { .id = 0x83847616, .name = "STAC9228", .patch = patch_stac927x }, + { .id = 0x83847617, .name = "STAC9228", .patch = patch_stac927x }, + { .id = 0x83847614, .name = "STAC9229", .patch = patch_stac927x }, + { .id = 0x83847615, .name = "STAC9229", .patch = patch_stac927x }, + { .id = 0x83847620, .name = "STAC9274", .patch = patch_stac927x }, + { .id = 0x83847621, .name = "STAC9274D", .patch = patch_stac927x }, + { .id = 0x83847622, .name = "STAC9273X", .patch = patch_stac927x }, + { .id = 0x83847623, .name = "STAC9273D", .patch = patch_stac927x }, + { .id = 0x83847624, .name = "STAC9272X", .patch = patch_stac927x }, + { .id = 0x83847625, .name = "STAC9272D", .patch = patch_stac927x }, + { .id = 0x83847626, .name = "STAC9271X", .patch = patch_stac927x }, + { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x }, + { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x }, + { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x }, + { .id = 0x83847632, .name = "STAC9202", .patch = patch_stac9202 }, + { .id = 0x83847633, .name = "STAC9202D", .patch = patch_stac9202 }, + { .id = 0x83847634, .name = "STAC9250", .patch = patch_stac925x }, + { .id = 0x83847635, .name = "STAC9250D", .patch = patch_stac925x }, + { .id = 0x83847636, .name = "STAC9251", .patch = patch_stac925x }, + { .id = 0x83847637, .name = "STAC9250D", .patch = patch_stac925x }, + { .id = 0x83847645, .name = "92HD206X", .patch = patch_stac927x }, + { .id = 0x83847646, .name = "92HD206D", .patch = patch_stac927x }, + /* The following does not take into account .id=0x83847661 when subsys = + * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are + * currently not fully supported. + */ + { .id = 0x83847661, .name = "CXD9872RD/K", .patch = patch_stac9872 }, + { .id = 0x83847662, .name = "STAC9872AK", .patch = patch_stac9872 }, + { .id = 0x83847664, .name = "CXD9872AKD", .patch = patch_stac9872 }, + { .id = 0x838476a0, .name = "STAC9205", .patch = patch_stac9205 }, + { .id = 0x838476a1, .name = "STAC9205D", .patch = patch_stac9205 }, + { .id = 0x838476a2, .name = "STAC9204", .patch = patch_stac9205 }, + { .id = 0x838476a3, .name = "STAC9204D", .patch = patch_stac9205 }, + { .id = 0x838476a4, .name = "STAC9255", .patch = patch_stac9205 }, + { .id = 0x838476a5, .name = "STAC9255D", .patch = patch_stac9205 }, + { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 }, + { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, + { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx}, + { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx}, + { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx}, + { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx}, + { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, + { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, + { .id = 0x111d7676, .name = "92HD73E1X5", .patch = patch_stac92hd73xx }, + { .id = 0x111d76b0, .name = "92HD71B8X", .patch = patch_stac92hd71bxx }, + { .id = 0x111d76b1, .name = "92HD71B8X", .patch = patch_stac92hd71bxx }, + { .id = 0x111d76b2, .name = "92HD71B7X", .patch = patch_stac92hd71bxx }, + { .id = 0x111d76b3, .name = "92HD71B7X", .patch = patch_stac92hd71bxx }, + { .id = 0x111d76b4, .name = "92HD71B6X", .patch = patch_stac92hd71bxx }, + { .id = 0x111d76b5, .name = "92HD71B6X", .patch = patch_stac92hd71bxx }, + { .id = 0x111d76b6, .name = "92HD71B5X", .patch = patch_stac92hd71bxx }, + { .id = 0x111d76b7, .name = "92HD71B5X", .patch = patch_stac92hd71bxx }, + {} /* terminator */ +}; --- linux-2.6.28.orig/sound/pci/hda/hda_codec.c +++ linux-2.6.28/sound/pci/hda/hda_codec.c @@ -66,6 +66,7 @@ { 0x1854, "LG" }, { 0x1aec, "Wolfson Microelectronics" }, { 0x434d, "C-Media" }, + { 0x8086, "Intel" }, { 0x8384, "SigmaTel" }, {} /* terminator */ }; @@ -98,6 +99,9 @@ #ifdef CONFIG_SND_HDA_CODEC_NVHDMI snd_hda_preset_nvhdmi, #endif +#ifdef CONFIG_SND_HDA_CODEC_INTELHDMI + snd_hda_preset_intelhdmi, +#endif NULL }; @@ -2372,6 +2376,67 @@ } /** + * snd_hda_check_board_codec_sid_config - compare the current codec + subsystem ID with the + config table + + This is important for Gateway notebooks with SB450 HDA Audio + where the vendor ID of the PCI device is: + ATI Technologies Inc SB450 HDA Audio [1002:437b] + and the vendor/subvendor are found only at the codec. + + * @codec: the HDA codec + * @num_configs: number of config enums + * @models: array of model name strings + * @tbl: configuration table, terminated by null entries + * + * Compares the modelname or PCI subsystem id of the current codec with the + * given configuration table. If a matching entry is found, returns its + * config value (supposed to be 0 or positive). + * + * If no entries are matching, the function returns a negative value. + */ +int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, + int num_configs, const char **models, + const struct snd_pci_quirk *tbl) +{ + const struct snd_pci_quirk *q; + + /* Search for codec ID */ + for (q = tbl; q->subvendor; q++) { + unsigned long vendorid = (q->subdevice) | (q->subvendor << 16); + + if (vendorid == codec->subsystem_id) + break; + } + + if (!q->subvendor) + return -1; + + tbl = q; + + if (tbl->value >= 0 && tbl->value < num_configs) { +#ifdef CONFIG_SND_DEBUG_DETECT + char tmp[10]; + const char *model = NULL; + if (models) + model = models[tbl->value]; + if (!model) { + sprintf(tmp, "#%d", tbl->value); + model = tmp; + } + snd_printdd(KERN_INFO "hda_codec: model '%s' is selected " + "for config %x:%x (%s)\n", + model, tbl->subvendor, tbl->subdevice, + (tbl->name ? tbl->name : "Unknown device")); +#endif + return tbl->value; + } + return -1; +} +EXPORT_SYMBOL_HDA(snd_hda_check_board_codec_sid_config); + +/** * snd_hda_add_new_ctls - create controls from the array * @codec: the HDA codec * @knew: the array of struct snd_kcontrol_new --- linux-2.6.28.orig/sound/pci/hda/patch_conexant.c +++ linux-2.6.28/sound/pci/hda/patch_conexant.c @@ -1470,6 +1470,7 @@ SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP), SND_PCI_QUIRK(0x103c, 0x30b2, "HP DV2000T/DV3000T", CXT5047_LAPTOP), SND_PCI_QUIRK(0x103c, 0x30b5, "HP DV2000Z", CXT5047_LAPTOP), + SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6700", CXT5047_LAPTOP), SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P100", CXT5047_LAPTOP_EAPD), {} }; @@ -1701,6 +1702,40 @@ { } /* end */ }; +static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = { + /* Line in, Mic */ + {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, + {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, + {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, + {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, + {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, + /* SPK */ + {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, + /* HP, Amp */ + {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, + /* Docking HP */ + {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, + /* DAC1 */ + {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + /* Record selector: Int mic */ + {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, + {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, + /* SPDIF route: PCM */ + {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0}, + /* EAPD */ + {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ + {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, + {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT}, + {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTC_EVENT}, + {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, + { } /* end */ +}; + /* initialize jack-sensing, too */ static int cxt5051_init(struct hda_codec *codec) { @@ -1717,18 +1752,21 @@ enum { CXT5051_LAPTOP, /* Laptops w/ EAPD support */ CXT5051_HP, /* no docking */ + CXT5051_LENOVO_X200, /* Lenovo X200 laptop */ CXT5051_MODELS }; static const char *cxt5051_models[CXT5051_MODELS] = { [CXT5051_LAPTOP] = "laptop", [CXT5051_HP] = "hp", + [CXT5051_LENOVO_X200] = "lenovo-x200", }; static struct snd_pci_quirk cxt5051_cfg_tbl[] = { SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", CXT5051_LAPTOP), SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP), + SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200), {} }; @@ -1769,6 +1807,9 @@ codec->patch_ops.unsol_event = cxt5051_hp_unsol_event; spec->mixers[0] = cxt5051_hp_mixers; break; + case CXT5051_LENOVO_X200: + spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs; + /* fallthru */ default: case CXT5051_LAPTOP: codec->patch_ops.unsol_event = cxt5051_hp_unsol_event; --- linux-2.6.28.orig/sound/pci/hda/hda_eld.c +++ linux-2.6.28/sound/pci/hda/hda_eld.c @@ -0,0 +1,538 @@ +/* + * Generic routines and proc interface for ELD(EDID Like Data) information + * + * Copyright(c) 2008 Intel Corporation. + * + * Authors: + * Wu Fengguang + * + * This driver is free software; you can redistribute it and/or modify + * it under the terms of the 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 driver is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You 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 "hda_codec.h" +#include "hda_local.h" + +enum eld_versions { + ELD_VER_CEA_861D = 2, + ELD_VER_PARTIAL = 31, +}; + +static char *eld_versoin_names[32] = { + "reserved", + "reserved", + "CEA-861D or below", + [3 ... 30] = "reserved", + [31] = "partial" +}; + +enum cea_edid_versions { + CEA_EDID_VER_NONE = 0, + CEA_EDID_VER_CEA861 = 1, + CEA_EDID_VER_CEA861A = 2, + CEA_EDID_VER_CEA861BCD = 3, + CEA_EDID_VER_RESERVED = 4, +}; + +static char *cea_edid_version_names[8] = { + "no CEA EDID Timing Extension block present", + "CEA-861", + "CEA-861-A", + "CEA-861-B, C or D", + [4 ... 7] = "reserved" +}; + +static char *cea_speaker_allocation_names[] = { + /* 0 */ "FL/FR", + /* 1 */ "LFE", + /* 2 */ "FC", + /* 3 */ "RL/RR", + /* 4 */ "RC", + /* 5 */ "FLC/FRC", + /* 6 */ "RLC/RRC", + /* 7 */ "FLW/FRW", + /* 8 */ "FLH/FRH", + /* 9 */ "TC", + /* 10 */ "FCH", +}; + +static char *eld_connection_type_names[4] = { + "HDMI", + "Display Port", + "2-reserved", + "3-reserved" +}; + +enum cea_audio_coding_types { + AUDIO_CODING_TYPE_REF_STREAM_HEADER = 0, + AUDIO_CODING_TYPE_LPCM = 1, + AUDIO_CODING_TYPE_AC3 = 2, + AUDIO_CODING_TYPE_MPEG1 = 3, + AUDIO_CODING_TYPE_MP3 = 4, + AUDIO_CODING_TYPE_MPEG2 = 5, + AUDIO_CODING_TYPE_AACLC = 6, + AUDIO_CODING_TYPE_DTS = 7, + AUDIO_CODING_TYPE_ATRAC = 8, + AUDIO_CODING_TYPE_SACD = 9, + AUDIO_CODING_TYPE_EAC3 = 10, + AUDIO_CODING_TYPE_DTS_HD = 11, + AUDIO_CODING_TYPE_MLP = 12, + AUDIO_CODING_TYPE_DST = 13, + AUDIO_CODING_TYPE_WMAPRO = 14, + AUDIO_CODING_TYPE_REF_CXT = 15, + /* also include valid xtypes below */ + AUDIO_CODING_TYPE_HE_AAC = 15, + AUDIO_CODING_TYPE_HE_AAC2 = 16, + AUDIO_CODING_TYPE_MPEG_SURROUND = 17, +}; + +enum cea_audio_coding_xtypes { + AUDIO_CODING_XTYPE_HE_REF_CT = 0, + AUDIO_CODING_XTYPE_HE_AAC = 1, + AUDIO_CODING_XTYPE_HE_AAC2 = 2, + AUDIO_CODING_XTYPE_MPEG_SURROUND = 3, + AUDIO_CODING_XTYPE_FIRST_RESERVED = 4, +}; + +static char *cea_audio_coding_type_names[] = { + /* 0 */ "undefined", + /* 1 */ "LPCM", + /* 2 */ "AC-3", + /* 3 */ "MPEG1", + /* 4 */ "MP3", + /* 5 */ "MPEG2", + /* 6 */ "AAC-LC", + /* 7 */ "DTS", + /* 8 */ "ATRAC", + /* 9 */ "DSD (1-bit audio)", + /* 10 */ "E-AC-3/DD+ (Dolby Digital Plus)", + /* 11 */ "DTS-HD", + /* 12 */ "MLP (Dolby TrueHD)", + /* 13 */ "DST", + /* 14 */ "WMAPro", + /* 15 */ "HE-AAC", + /* 16 */ "HE-AACv2", + /* 17 */ "MPEG Surround", +}; + +/* + * The following two lists are shared between + * - HDMI audio InfoFrame (source to sink) + * - CEA E-EDID Extension (sink to source) + */ + +/* + * SS1:SS0 index => sample size + */ +static int cea_sample_sizes[4] = { + 0, /* 0: Refer to Stream Header */ + AC_SUPPCM_BITS_16, /* 1: 16 bits */ + AC_SUPPCM_BITS_20, /* 2: 20 bits */ + AC_SUPPCM_BITS_24, /* 3: 24 bits */ +}; + +/* + * SF2:SF1:SF0 index => sampling frequency + */ +static int cea_sampling_frequencies[8] = { + 0, /* 0: Refer to Stream Header */ + SNDRV_PCM_RATE_32000, /* 1: 32000Hz */ + SNDRV_PCM_RATE_44100, /* 2: 44100Hz */ + SNDRV_PCM_RATE_48000, /* 3: 48000Hz */ + SNDRV_PCM_RATE_88200, /* 4: 88200Hz */ + SNDRV_PCM_RATE_96000, /* 5: 96000Hz */ + SNDRV_PCM_RATE_176400, /* 6: 176400Hz */ + SNDRV_PCM_RATE_192000, /* 7: 192000Hz */ +}; + +static unsigned char hdmi_get_eld_byte(struct hda_codec *codec, hda_nid_t nid, + int byte_index) +{ + unsigned int val; + + val = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_HDMI_ELDD, byte_index); + +#ifdef BE_PARANOID + printk(KERN_INFO "ELD data byte %d: 0x%x\n", byte_index, val); +#endif + + if ((val & AC_ELDD_ELD_VALID) == 0) { + snd_printd(KERN_INFO "Invalid ELD data byte %d\n", + byte_index); + val = 0; + } + + return val & AC_ELDD_ELD_DATA; +} + +#define GRAB_BITS(buf, byte, lowbit, bits) \ +({ \ + BUILD_BUG_ON(lowbit > 7); \ + BUILD_BUG_ON(bits > 8); \ + BUILD_BUG_ON(bits <= 0); \ + \ + (buf[byte] >> (lowbit)) & ((1 << (bits)) - 1); \ +}) + +static void hdmi_update_short_audio_desc(struct cea_sad *a, + const unsigned char *buf) +{ + int i; + int val; + + val = GRAB_BITS(buf, 1, 0, 7); + a->rates = 0; + for (i = 0; i < 7; i++) + if (val & (1 << i)) + a->rates |= cea_sampling_frequencies[i + 1]; + + a->channels = GRAB_BITS(buf, 0, 0, 3); + a->channels++; + + a->format = GRAB_BITS(buf, 0, 3, 4); + switch (a->format) { + case AUDIO_CODING_TYPE_REF_STREAM_HEADER: + snd_printd(KERN_INFO + "audio coding type 0 not expected in ELD\n"); + break; + + case AUDIO_CODING_TYPE_LPCM: + val = GRAB_BITS(buf, 2, 0, 3); + a->sample_bits = 0; + for (i = 0; i < 3; i++) + if (val & (1 << i)) + a->sample_bits |= cea_sample_sizes[i + 1]; + break; + + case AUDIO_CODING_TYPE_AC3: + case AUDIO_CODING_TYPE_MPEG1: + case AUDIO_CODING_TYPE_MP3: + case AUDIO_CODING_TYPE_MPEG2: + case AUDIO_CODING_TYPE_AACLC: + case AUDIO_CODING_TYPE_DTS: + case AUDIO_CODING_TYPE_ATRAC: + a->max_bitrate = GRAB_BITS(buf, 2, 0, 8); + a->max_bitrate *= 8000; + break; + + case AUDIO_CODING_TYPE_SACD: + break; + + case AUDIO_CODING_TYPE_EAC3: + break; + + case AUDIO_CODING_TYPE_DTS_HD: + break; + + case AUDIO_CODING_TYPE_MLP: + break; + + case AUDIO_CODING_TYPE_DST: + break; + + case AUDIO_CODING_TYPE_WMAPRO: + a->profile = GRAB_BITS(buf, 2, 0, 3); + break; + + case AUDIO_CODING_TYPE_REF_CXT: + a->format = GRAB_BITS(buf, 2, 3, 5); + if (a->format == AUDIO_CODING_XTYPE_HE_REF_CT || + a->format >= AUDIO_CODING_XTYPE_FIRST_RESERVED) { + snd_printd(KERN_INFO + "audio coding xtype %d not expected in ELD\n", + a->format); + a->format = 0; + } else + a->format += AUDIO_CODING_TYPE_HE_AAC - + AUDIO_CODING_XTYPE_HE_AAC; + break; + } +} + +/* + * Be careful, ELD buf could be totally rubbish! + */ +static int hdmi_update_eld(struct hdmi_eld *e, + const unsigned char *buf, int size) +{ + int mnl; + int i; + + e->eld_ver = GRAB_BITS(buf, 0, 3, 5); + if (e->eld_ver != ELD_VER_CEA_861D && + e->eld_ver != ELD_VER_PARTIAL) { + snd_printd(KERN_INFO "Unknown ELD version %d\n", e->eld_ver); + goto out_fail; + } + + e->eld_size = size; + e->baseline_len = GRAB_BITS(buf, 2, 0, 8); + mnl = GRAB_BITS(buf, 4, 0, 5); + e->cea_edid_ver = GRAB_BITS(buf, 4, 5, 3); + + e->support_hdcp = GRAB_BITS(buf, 5, 0, 1); + e->support_ai = GRAB_BITS(buf, 5, 1, 1); + e->conn_type = GRAB_BITS(buf, 5, 2, 2); + e->sad_count = GRAB_BITS(buf, 5, 4, 4); + + e->aud_synch_delay = GRAB_BITS(buf, 6, 0, 8) * 2; + e->spk_alloc = GRAB_BITS(buf, 7, 0, 7); + + e->port_id = get_unaligned_le64(buf + 8); + + /* not specified, but the spec's tendency is little endian */ + e->manufacture_id = get_unaligned_le16(buf + 16); + e->product_id = get_unaligned_le16(buf + 18); + + if (mnl > ELD_MAX_MNL) { + snd_printd(KERN_INFO "MNL is reserved value %d\n", mnl); + goto out_fail; + } else if (ELD_FIXED_BYTES + mnl > size) { + snd_printd(KERN_INFO "out of range MNL %d\n", mnl); + goto out_fail; + } else + strlcpy(e->monitor_name, buf + ELD_FIXED_BYTES, mnl); + + for (i = 0; i < e->sad_count; i++) { + if (ELD_FIXED_BYTES + mnl + 3 * (i + 1) > size) { + snd_printd(KERN_INFO "out of range SAD %d\n", i); + goto out_fail; + } + hdmi_update_short_audio_desc(e->sad + i, + buf + ELD_FIXED_BYTES + mnl + 3 * i); + } + + return 0; + +out_fail: + e->eld_ver = 0; + return -EINVAL; +} + +static int hdmi_present_sense(struct hda_codec *codec, hda_nid_t nid) +{ + return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0); +} + +static int hdmi_eld_valid(struct hda_codec *codec, hda_nid_t nid) +{ + int eldv; + int present; + + present = hdmi_present_sense(codec, nid); + eldv = (present & AC_PINSENSE_ELDV); + present = (present & AC_PINSENSE_PRESENCE); + +#ifdef CONFIG_SND_DEBUG_VERBOSE + printk(KERN_INFO "pinp = %d, eldv = %d\n", !!present, !!eldv); +#endif + + return eldv && present; +} + +int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid) +{ + return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE, + AC_DIPSIZE_ELD_BUF); +} + +int snd_hdmi_get_eld(struct hdmi_eld *eld, + struct hda_codec *codec, hda_nid_t nid) +{ + int i; + int ret; + int size; + unsigned char *buf; + + if (!hdmi_eld_valid(codec, nid)) + return -ENOENT; + + size = snd_hdmi_get_eld_size(codec, nid); + if (size == 0) { + /* wfg: workaround for ASUS P5E-VM HDMI board */ + snd_printd(KERN_INFO "ELD buf size is 0, force 128\n"); + size = 128; + } + if (size < ELD_FIXED_BYTES || size > PAGE_SIZE) { + snd_printd(KERN_INFO "Invalid ELD buf size %d\n", size); + return -ERANGE; + } + + buf = kmalloc(size, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + for (i = 0; i < size; i++) + buf[i] = hdmi_get_eld_byte(codec, nid, i); + + ret = hdmi_update_eld(eld, buf, size); + + kfree(buf); + return ret; +} + +static void hdmi_show_short_audio_desc(struct cea_sad *a) +{ + char buf[SND_PRINT_RATES_ADVISED_BUFSIZE]; + + printk(KERN_INFO "coding type: %s\n", + cea_audio_coding_type_names[a->format]); + printk(KERN_INFO "channels: %d\n", a->channels); + + snd_print_pcm_rates(a->rates, buf, sizeof(buf)); + printk(KERN_INFO "sampling frequencies: %s\n", buf); + + if (a->format == AUDIO_CODING_TYPE_LPCM) + printk(KERN_INFO "sample bits: 0x%x\n", a->sample_bits); + + if (a->max_bitrate) + printk(KERN_INFO "max bitrate: %d\n", a->max_bitrate); + + if (a->profile) + printk(KERN_INFO "profile: %d\n", a->profile); +} + +void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen) +{ + int i, j; + + for (i = 0, j = 0; i < ARRAY_SIZE(cea_speaker_allocation_names); i++) { + if (spk_alloc & (1 << i)) + j += snprintf(buf + j, buflen - j, "%s ", + cea_speaker_allocation_names[i]); + } + if (j) + j--; /* skip last space */ + buf[j] = '\0'; /* necessary when j == 0 */ +} + +void snd_hdmi_show_eld(struct hdmi_eld *e) +{ + int i; + char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE]; + + printk(KERN_INFO "ELD buffer size is %d\n", e->eld_size); + printk(KERN_INFO "ELD baseline len is %d*4\n", e->baseline_len); + printk(KERN_INFO "vendor block len is %d\n", + e->eld_size - e->baseline_len * 4 - 4); + printk(KERN_INFO "ELD version is %s\n", + eld_versoin_names[e->eld_ver]); + printk(KERN_INFO "CEA EDID version is %s\n", + cea_edid_version_names[e->cea_edid_ver]); + printk(KERN_INFO "manufacture id is 0x%x\n", e->manufacture_id); + printk(KERN_INFO "product id is 0x%x\n", e->product_id); + printk(KERN_INFO "port id is 0x%llx\n", (long long)e->port_id); + printk(KERN_INFO "HDCP support is %d\n", e->support_hdcp); + printk(KERN_INFO "AI support is %d\n", e->support_ai); + printk(KERN_INFO "SAD count is %d\n", e->sad_count); + printk(KERN_INFO "audio sync delay is %x\n", e->aud_synch_delay); + printk(KERN_INFO "connection type is %s\n", + eld_connection_type_names[e->conn_type]); + printk(KERN_INFO "monitor name is %s\n", e->monitor_name); + + snd_print_channel_allocation(e->spk_alloc, buf, sizeof(buf)); + printk(KERN_INFO "speaker allocations: (0x%x)%s\n", e->spk_alloc, buf); + + for (i = 0; i < e->sad_count; i++) + hdmi_show_short_audio_desc(e->sad + i); +} + +#ifdef CONFIG_PROC_FS + +static void hdmi_print_sad_info(int i, struct cea_sad *a, + struct snd_info_buffer *buffer) +{ + char buf[80]; + + snd_iprintf(buffer, "sad%d_coding_type\t[0x%x] %s\n", + i, a->format, cea_audio_coding_type_names[a->format]); + snd_iprintf(buffer, "sad%d_channels\t\t%d\n", i, a->channels); + + snd_print_pcm_rates(a->rates, buf, sizeof(buf)); + snd_iprintf(buffer, "sad%d_sampling_rates\t[0x%x] %s\n", + i, a->rates, buf); + + if (a->format == AUDIO_CODING_TYPE_LPCM) + snd_iprintf(buffer, "sad%d_sample_bits\t0x%x\n", + i, a->sample_bits); + + if (a->max_bitrate) + snd_iprintf(buffer, "sad%d_max_bitrate\t%d\n", + i, a->max_bitrate); + + if (a->profile) + snd_iprintf(buffer, "sad%d_profile\t\t%d\n", i, a->profile); +} + +static void hdmi_print_eld_info(struct snd_info_entry *entry, + struct snd_info_buffer *buffer) +{ + struct hdmi_eld *e = entry->private_data; + char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE]; + int i; + + snd_iprintf(buffer, "monitor name\t\t%s\n", e->monitor_name); + snd_iprintf(buffer, "connection_type\t\t%s\n", + eld_connection_type_names[e->conn_type]); + snd_iprintf(buffer, "eld_version\t\t[0x%x] %s\n", e->eld_ver, + eld_versoin_names[e->eld_ver]); + snd_iprintf(buffer, "edid_version\t\t[0x%x] %s\n", e->cea_edid_ver, + cea_edid_version_names[e->cea_edid_ver]); + snd_iprintf(buffer, "manufacture_id\t\t0x%x\n", e->manufacture_id); + snd_iprintf(buffer, "product_id\t\t0x%x\n", e->product_id); + snd_iprintf(buffer, "port_id\t\t\t0x%llx\n", (long long)e->port_id); + snd_iprintf(buffer, "support_hdcp\t\t%d\n", e->support_hdcp); + snd_iprintf(buffer, "support_ai\t\t%d\n", e->support_ai); + snd_iprintf(buffer, "audio_sync_delay\t%d\n", e->aud_synch_delay); + + snd_print_channel_allocation(e->spk_alloc, buf, sizeof(buf)); + snd_iprintf(buffer, "speakers\t\t[0x%x] %s\n", e->spk_alloc, buf); + + snd_iprintf(buffer, "sad_count\t\t%d\n", e->sad_count); + + for (i = 0; i < e->sad_count; i++) + hdmi_print_sad_info(i, e->sad + i, buffer); +} + +int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld) +{ + char name[32]; + struct snd_info_entry *entry; + int err; + + snprintf(name, sizeof(name), "eld#%d", codec->addr); + err = snd_card_proc_new(codec->bus->card, name, &entry); + if (err < 0) + return err; + + snd_info_set_text_ops(entry, eld, hdmi_print_eld_info); + + eld->proc_entry = entry; + + return 0; +} + +void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld) +{ + if (/* !codec->bus->shutdown && */ eld->proc_entry) { + snd_device_free(codec->bus->card, eld->proc_entry); + eld->proc_entry = NULL; + } +} + +#endif /* CONFIG_PROC_FS */ --- linux-2.6.28.orig/sound/pci/hda/patch_nvhdmi.c +++ linux-2.6.28/sound/pci/hda/patch_nvhdmi.c @@ -161,5 +161,6 @@ struct hda_codec_preset snd_hda_preset_nvhdmi[] = { { .id = 0x10de0002, .name = "NVIDIA MCP78 HDMI", .patch = patch_nvhdmi }, { .id = 0x10de0007, .name = "NVIDIA MCP7A HDMI", .patch = patch_nvhdmi }, + { .id = 0x10de0067, .name = "NVIDIA MCP67 HDMI", .patch = patch_nvhdmi }, {} /* terminator */ }; --- linux-2.6.28.orig/sound/pci/hda/Makefile +++ linux-2.6.28/sound/pci/hda/Makefile @@ -4,6 +4,7 @@ # designed to be individual modules snd-hda-intel-y += hda_codec.o snd-hda-intel-$(CONFIG_PROC_FS) += hda_proc.o +snd-hda-intel-$(CONFIG_SND_HDA_ELD) += hda_eld.o snd-hda-intel-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o snd-hda-intel-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o snd-hda-intel-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o @@ -11,10 +12,12 @@ snd-hda-intel-$(CONFIG_SND_HDA_CODEC_CMEDIA) += patch_cmedia.o snd-hda-intel-$(CONFIG_SND_HDA_CODEC_ANALOG) += patch_analog.o snd-hda-intel-$(CONFIG_SND_HDA_CODEC_SIGMATEL) += patch_sigmatel.o +snd-hda-intel-$(CONFIG_SND_LPIA_HDA_CODEC_SIGMATEL) += lpia_ubuntu_patch_sigmatel.o snd-hda-intel-$(CONFIG_SND_HDA_CODEC_SI3054) += patch_si3054.o snd-hda-intel-$(CONFIG_SND_HDA_CODEC_ATIHDMI) += patch_atihdmi.o snd-hda-intel-$(CONFIG_SND_HDA_CODEC_CONEXANT) += patch_conexant.o snd-hda-intel-$(CONFIG_SND_HDA_CODEC_VIA) += patch_via.o snd-hda-intel-$(CONFIG_SND_HDA_CODEC_NVHDMI) += patch_nvhdmi.o +snd-hda-intel-$(CONFIG_SND_HDA_CODEC_INTELHDMI) += patch_intelhdmi.o obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o --- linux-2.6.28.orig/sound/pci/hda/patch_analog.c +++ linux-2.6.28/sound/pci/hda/patch_analog.c @@ -629,6 +629,36 @@ HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw), HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Capture Source", + .info = ad198x_mux_enum_info, + .get = ad198x_mux_enum_get, + .put = ad198x_mux_enum_put, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "External Amplifier", + .info = ad198x_eapd_info, + .get = ad198x_eapd_get, + .put = ad198x_eapd_put, + .private_value = 0x1b | (1 << 8), /* port-D, inversed */ + }, + { } /* end */ +}; + +static struct snd_kcontrol_new ad1986a_samsung_mixers[] = { + HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), + HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw), + HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), @@ -917,6 +947,7 @@ AD1986A_LAPTOP_EAPD, AD1986A_LAPTOP_AUTOMUTE, AD1986A_ULTRA, + AD1986A_SAMSUNG, AD1986A_MODELS }; @@ -927,6 +958,7 @@ [AD1986A_LAPTOP_EAPD] = "laptop-eapd", [AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute", [AD1986A_ULTRA] = "ultra", + [AD1986A_SAMSUNG] = "samsung", }; static struct snd_pci_quirk ad1986a_cfg_tbl[] = { @@ -949,9 +981,9 @@ SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba", AD1986A_LAPTOP_EAPD), SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK), SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP), - SND_PCI_QUIRK(0x144d, 0xc023, "Samsung X60", AD1986A_LAPTOP_EAPD), - SND_PCI_QUIRK(0x144d, 0xc024, "Samsung R65", AD1986A_LAPTOP_EAPD), - SND_PCI_QUIRK(0x144d, 0xc026, "Samsung X11", AD1986A_LAPTOP_EAPD), + SND_PCI_QUIRK(0x144d, 0xc023, "Samsung X60", AD1986A_SAMSUNG), + SND_PCI_QUIRK(0x144d, 0xc024, "Samsung R65", AD1986A_SAMSUNG), + SND_PCI_QUIRK(0x144d, 0xc026, "Samsung X11", AD1986A_SAMSUNG), SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA), SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK), SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_LAPTOP), @@ -1033,6 +1065,17 @@ break; case AD1986A_LAPTOP_EAPD: spec->mixers[0] = ad1986a_laptop_eapd_mixers; + spec->num_init_verbs = 2; + spec->init_verbs[1] = ad1986a_eapd_init_verbs; + spec->multiout.max_channels = 2; + spec->multiout.num_dacs = 1; + spec->multiout.dac_nids = ad1986a_laptop_dac_nids; + if (!is_jack_available(codec, 0x25)) + spec->multiout.dig_out_nid = 0; + spec->input_mux = &ad1986a_laptop_eapd_capture_source; + break; + case AD1986A_SAMSUNG: + spec->mixers[0] = ad1986a_samsung_mixers; spec->num_init_verbs = 3; spec->init_verbs[1] = ad1986a_eapd_init_verbs; spec->init_verbs[2] = ad1986a_automic_verbs; @@ -1830,8 +1873,8 @@ #define AD1988_SPDIF_OUT_HDMI 0x0b #define AD1988_SPDIF_IN 0x07 -static hda_nid_t ad1989b_slave_dig_outs[2] = { - AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI +static hda_nid_t ad1989b_slave_dig_outs[] = { + AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI, 0 }; static struct hda_input_mux ad1988_6stack_capture_source = { @@ -3860,7 +3903,9 @@ static struct snd_pci_quirk ad1884a_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), + SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP), SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE), + SND_PCI_QUIRK(0x103c, 0x30e6, "HP 6730b", AD1884A_LAPTOP), SND_PCI_QUIRK(0x103c, 0x30e7, "HP EliteBook 8530p", AD1884A_LAPTOP), SND_PCI_QUIRK(0x103c, 0x3614, "HP 6730s", AD1884A_LAPTOP), SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD), @@ -4221,13 +4266,13 @@ spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids); spec->adc_nids = ad1882_adc_nids; spec->capsrc_nids = ad1882_capsrc_nids; - if (codec->vendor_id == 0x11d1882) + if (codec->vendor_id == 0x11d41882) spec->input_mux = &ad1882_capture_source; else spec->input_mux = &ad1882a_capture_source; spec->num_mixers = 2; spec->mixers[0] = ad1882_base_mixers; - if (codec->vendor_id == 0x11d1882) + if (codec->vendor_id == 0x11d41882) spec->mixers[1] = ad1882_loopback_mixers; else spec->mixers[1] = ad1882a_loopback_mixers; --- linux-2.6.28.orig/sound/pci/hda/hda_patch.h +++ linux-2.6.28/sound/pci/hda/hda_patch.h @@ -20,3 +20,5 @@ extern struct hda_codec_preset snd_hda_preset_via[]; /* NVIDIA HDMI codecs */ extern struct hda_codec_preset snd_hda_preset_nvhdmi[]; +/* INTEL HDMI codecs */ +extern struct hda_codec_preset snd_hda_preset_intelhdmi[]; --- linux-2.6.28.orig/sound/pci/hda/patch_sigmatel.c +++ linux-2.6.28/sound/pci/hda/patch_sigmatel.c @@ -55,7 +55,8 @@ STAC_9200_DELL_M25, STAC_9200_DELL_M26, STAC_9200_DELL_M27, - STAC_9200_GATEWAY, + STAC_9200_M4, + STAC_9200_M4_2, STAC_9200_PANASONIC, STAC_9200_MODELS }; @@ -89,14 +90,19 @@ STAC_DELL_M4_2, STAC_DELL_M4_3, STAC_HP_M4, + STAC_HP_DV5, STAC_92HD71BXX_MODELS }; enum { STAC_925x_REF, + STAC_M1, + STAC_M1_2, + STAC_M2, STAC_M2_2, - STAC_MA6, - STAC_PA6, + STAC_M3, + STAC_M5, + STAC_M6, STAC_925x_MODELS }; @@ -1320,7 +1326,16 @@ 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, }; -/* +static unsigned int gateway9200_m4_pin_configs[8] = { + 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010, + 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3, +}; +static unsigned int gateway9200_m4_2_pin_configs[8] = { + 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010, + 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3, +}; + +/* STAC 9200 pin configs for 102801A8 102801DE @@ -1450,6 +1465,8 @@ [STAC_9200_DELL_M25] = dell9200_m25_pin_configs, [STAC_9200_DELL_M26] = dell9200_m26_pin_configs, [STAC_9200_DELL_M27] = dell9200_m27_pin_configs, + [STAC_9200_M4] = gateway9200_m4_pin_configs, + [STAC_9200_M4_2] = gateway9200_m4_2_pin_configs, [STAC_9200_PANASONIC] = ref9200_pin_configs, }; @@ -1466,7 +1483,8 @@ [STAC_9200_DELL_M25] = "dell-m25", [STAC_9200_DELL_M26] = "dell-m26", [STAC_9200_DELL_M27] = "dell-m27", - [STAC_9200_GATEWAY] = "gateway", + [STAC_9200_M4] = "gateway-m4", + [STAC_9200_M4_2] = "gateway-m4-2", [STAC_9200_PANASONIC] = "panasonic", }; @@ -1536,11 +1554,9 @@ /* Panasonic */ SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_9200_PANASONIC), /* Gateway machines needs EAPD to be set on resume */ - SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_GATEWAY), - SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*", - STAC_9200_GATEWAY), - SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707", - STAC_9200_GATEWAY), + SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_M4), + SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*", STAC_9200_M4_2), + SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707", STAC_9200_M4_2), /* OQO Mobile */ SND_PCI_QUIRK(0x1106, 0x3288, "OQO Model 2", STAC_9200_OQO), {} /* terminator */ @@ -1551,44 +1567,85 @@ 0x90a70320, 0x02214210, 0x01019020, 0x9033032e, }; -static unsigned int stac925x_MA6_pin_configs[8] = { - 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021, - 0x90a70320, 0x90100211, 0x400003f1, 0x9033032e, +static unsigned int stac925xM1_pin_configs[8] = { + 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, + 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, }; -static unsigned int stac925x_PA6_pin_configs[8] = { - 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021, - 0x50a103f0, 0x90100211, 0x400003f1, 0x9033032e, +static unsigned int stac925xM1_2_pin_configs[8] = { + 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, + 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, +}; + +static unsigned int stac925xM2_pin_configs[8] = { + 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, + 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, }; static unsigned int stac925xM2_2_pin_configs[8] = { - 0x40c003f3, 0x424503f2, 0x04180011, 0x02a19020, - 0x50a103f0, 0x90100212, 0x400003f1, 0x9033032e, + 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, + 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, +}; + +static unsigned int stac925xM3_pin_configs[8] = { + 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, + 0x40a000f0, 0x90100210, 0x400003f1, 0x503303f3, +}; + +static unsigned int stac925xM5_pin_configs[8] = { + 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, + 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, +}; + +static unsigned int stac925xM6_pin_configs[8] = { + 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, + 0x40a000f0, 0x90100210, 0x400003f1, 0x90330320, }; static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = { [STAC_REF] = ref925x_pin_configs, + [STAC_M1] = stac925xM1_pin_configs, + [STAC_M1_2] = stac925xM1_2_pin_configs, + [STAC_M2] = stac925xM2_pin_configs, [STAC_M2_2] = stac925xM2_2_pin_configs, - [STAC_MA6] = stac925x_MA6_pin_configs, - [STAC_PA6] = stac925x_PA6_pin_configs, + [STAC_M3] = stac925xM3_pin_configs, + [STAC_M5] = stac925xM5_pin_configs, + [STAC_M6] = stac925xM6_pin_configs, }; static const char *stac925x_models[STAC_925x_MODELS] = { [STAC_REF] = "ref", + [STAC_M1] = "m1", + [STAC_M1_2] = "m1-2", + [STAC_M2] = "m2", [STAC_M2_2] = "m2-2", - [STAC_MA6] = "m6", - [STAC_PA6] = "pa6", + [STAC_M3] = "m3", + [STAC_M5] = "m5", + [STAC_M6] = "m6", +}; + +static struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = { + SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_M2), + SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_M5), + SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_M1), + SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_M2), + SND_PCI_QUIRK(0x107b, 0x0367, "Gateway MX6453", STAC_M1_2), + /* Not sure about the brand name for those */ + SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M1), + SND_PCI_QUIRK(0x107b, 0x0507, "Gateway mobile", STAC_M3), + SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M6), + SND_PCI_QUIRK(0x107b, 0x0685, "Gateway mobile", STAC_M2_2), + {} /* terminator */ }; static struct snd_pci_quirk stac925x_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF), SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF), - SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_REF), - SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_REF), - SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_MA6), - SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_PA6), - SND_PCI_QUIRK(0x1002, 0x437b, "Gateway MX6453", STAC_M2_2), + + /* Default table for unknown ID */ + SND_PCI_QUIRK(0x1002, 0x437b, "Gateway mobile", STAC_M2_2), + {} /* terminator */ }; @@ -1702,6 +1759,7 @@ [STAC_DELL_M4_2] = dell_m4_2_pin_configs, [STAC_DELL_M4_3] = dell_m4_3_pin_configs, [STAC_HP_M4] = NULL, + [STAC_HP_DV5] = NULL, }; static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { @@ -1710,6 +1768,7 @@ [STAC_DELL_M4_2] = "dell-m4-2", [STAC_DELL_M4_3] = "dell-m4-3", [STAC_HP_M4] = "hp-m4", + [STAC_HP_DV5] = "hp-dv5", }; static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { @@ -1720,6 +1779,12 @@ "HP dv5", STAC_HP_M4), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f4, "HP dv7", STAC_HP_M4), + SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f7, + "HP dv4", STAC_HP_DV5), + SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fc, + "HP dv7", STAC_HP_M4), + SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3603, + "HP dv5", STAC_HP_DV5), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, "unknown HP", STAC_HP_M4), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, @@ -2421,6 +2486,8 @@ info->name = "STAC92xx Analog"; info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback; + info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = + spec->multiout.dac_nids[0]; info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture; info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adcs; @@ -3978,8 +4045,19 @@ continue; if (presence) stac92xx_set_pinctl(codec, cfg->hp_pins[i], val); +#if 0 /* FIXME */ +/* Resetting the pinctl like below may lead to (a sort of) regressions + * on some devices since they use the HP pin actually for line/speaker + * outs although the default pin config shows a different pin (that is + * wrong and useless). + * + * So, it's basically a problem of default pin configs, likely a BIOS issue. + * But, disabling the code below just works around it, and I'm too tired of + * bug reports with such devices... + */ else stac92xx_reset_pinctl(codec, cfg->hp_pins[i], val); +#endif /* FIXME */ } } @@ -4111,7 +4189,8 @@ spec->num_adcs = 1; spec->num_pwrs = 0; - if (spec->board_config == STAC_9200_GATEWAY || + if (spec->board_config == STAC_9200_M4 || + spec->board_config == STAC_9200_M4_2 || spec->board_config == STAC_9200_OQO) spec->init = stac9200_eapd_init; else @@ -4129,6 +4208,12 @@ return err; } + /* CF-74 has no headphone detection, and the driver should *NOT* + * do detection and HP/speaker toggle because the hardware does it. + */ + if (spec->board_config == STAC_9200_PANASONIC) + spec->hp_detect = 0; + codec->patch_ops = stac92xx_patch_ops; return 0; @@ -4146,12 +4231,22 @@ codec->spec = spec; spec->num_pins = ARRAY_SIZE(stac925x_pin_nids); spec->pin_nids = stac925x_pin_nids; - spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS, + + /* Check first for codec ID */ + spec->board_config = snd_hda_check_board_codec_sid_config(codec, + STAC_925x_MODELS, + stac925x_models, + stac925x_codec_id_cfg_tbl); + + /* Now checks for PCI ID, if codec ID is not found */ + if (spec->board_config < 0) + spec->board_config = snd_hda_check_board_config(codec, + STAC_925x_MODELS, stac925x_models, stac925x_cfg_tbl); again: if (spec->board_config < 0) { - snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x," + snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x," "using BIOS defaults\n"); err = stac92xx_save_bios_config_regs(codec); if (err < 0) { @@ -4648,7 +4743,7 @@ case STAC_DELL_M4_3: spec->num_dmics = 1; spec->num_smuxes = 0; - spec->num_dmuxes = 0; + spec->num_dmuxes = 1; break; default: spec->num_dmics = STAC92HD71BXX_NUM_DMICS; --- linux-2.6.28.orig/sound/pci/hda/patch_intelhdmi.c +++ linux-2.6.28/sound/pci/hda/patch_intelhdmi.c @@ -0,0 +1,685 @@ +/* + * + * patch_intelhdmi.c - Patch for Intel HDMI codecs + * + * Copyright(c) 2008 Intel Corporation. All rights reserved. + * + * Authors: + * Jiang Zhe + * Wu Fengguang + * + * Maintained by: + * Wu Fengguang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the 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 "hda_codec.h" +#include "hda_local.h" +#include "hda_patch.h" + +#define CVT_NID 0x02 /* audio converter */ +#define PIN_NID 0x03 /* HDMI output pin */ + +#define INTEL_HDMI_EVENT_TAG 0x08 + +struct intel_hdmi_spec { + struct hda_multi_out multiout; + struct hda_pcm pcm_rec; + struct hdmi_eld sink_eld; +}; + +static struct hda_verb pinout_enable_verb[] = { + {PIN_NID, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {} /* terminator */ +}; + +static struct hda_verb pinout_disable_verb[] = { + {PIN_NID, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00}, + {} +}; + +static struct hda_verb unsolicited_response_verb[] = { + {PIN_NID, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | + INTEL_HDMI_EVENT_TAG}, + {} +}; + +static struct hda_verb def_chan_map[] = { + {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x00}, + {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x11}, + {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x22}, + {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x33}, + {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x44}, + {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x55}, + {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x66}, + {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x77}, + {} +}; + + +struct hdmi_audio_infoframe { + u8 type; /* 0x84 */ + u8 ver; /* 0x01 */ + u8 len; /* 0x0a */ + + u8 checksum; /* PB0 */ + u8 CC02_CT47; /* CC in bits 0:2, CT in 4:7 */ + u8 SS01_SF24; + u8 CXT04; + u8 CA; + u8 LFEPBL01_LSV36_DM_INH7; + u8 reserved[5]; /* PB6 - PB10 */ +}; + +/* + * CEA speaker placement: + * + * FLH FCH FRH + * FLW FL FLC FC FRC FR FRW + * + * LFE + * TC + * + * RL RLC RC RRC RR + * + * The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M corresponds to + * CEA RL/RR; The SMPTE channel _assignment_ C/LFE is swapped to CEA LFE/FC. + */ +enum cea_speaker_placement { + FL = (1 << 0), /* Front Left */ + FC = (1 << 1), /* Front Center */ + FR = (1 << 2), /* Front Right */ + FLC = (1 << 3), /* Front Left Center */ + FRC = (1 << 4), /* Front Right Center */ + RL = (1 << 5), /* Rear Left */ + RC = (1 << 6), /* Rear Center */ + RR = (1 << 7), /* Rear Right */ + RLC = (1 << 8), /* Rear Left Center */ + RRC = (1 << 9), /* Rear Right Center */ + LFE = (1 << 10), /* Low Frequency Effect */ + FLW = (1 << 11), /* Front Left Wide */ + FRW = (1 << 12), /* Front Right Wide */ + FLH = (1 << 13), /* Front Left High */ + FCH = (1 << 14), /* Front Center High */ + FRH = (1 << 15), /* Front Right High */ + TC = (1 << 16), /* Top Center */ +}; + +/* + * ELD SA bits in the CEA Speaker Allocation data block + */ +static int eld_speaker_allocation_bits[] = { + [0] = FL | FR, + [1] = LFE, + [2] = FC, + [3] = RL | RR, + [4] = RC, + [5] = FLC | FRC, + [6] = RLC | RRC, + /* the following are not defined in ELD yet */ + [7] = FLW | FRW, + [8] = FLH | FRH, + [9] = TC, + [10] = FCH, +}; + +struct cea_channel_speaker_allocation { + int ca_index; + int speakers[8]; + + /* derived values, just for convenience */ + int channels; + int spk_mask; +}; + +/* + * This is an ordered list! + * + * The preceding ones have better chances to be selected by + * hdmi_setup_channel_allocation(). + */ +static struct cea_channel_speaker_allocation channel_allocations[] = { +/* channel: 8 7 6 5 4 3 2 1 */ +{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } }, + /* 2.1 */ +{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } }, + /* Dolby Surround */ +{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } }, +{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } }, +{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } }, +{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } }, +{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } }, +{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } }, +{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } }, +{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } }, +{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } }, + /* 5.1 */ +{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } }, +{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } }, +{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } }, +{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } }, + /* 6.1 */ +{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } }, +{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } }, +{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } }, +{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } }, + /* 7.1 */ +{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } }, +{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } }, +{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } }, +{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } }, +{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } }, +{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } }, +{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } }, +{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } }, +{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } }, +{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } }, +{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } }, +{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } }, +{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } }, +{ .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } }, +{ .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } }, +{ .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } }, +{ .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } }, +{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } }, +{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } }, +{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } }, +{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } }, +{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } }, +{ .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } }, +{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } }, +{ .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } }, +{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } }, +{ .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } }, +{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } }, +{ .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } }, +{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } }, +{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } }, +}; + +/* + * HDMI routines + */ + +#ifdef BE_PARANOID +static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t nid, + int *packet_index, int *byte_index) +{ + int val; + + val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_INDEX, 0); + + *packet_index = val >> 5; + *byte_index = val & 0x1f; +} +#endif + +static void hdmi_set_dip_index(struct hda_codec *codec, hda_nid_t nid, + int packet_index, int byte_index) +{ + int val; + + val = (packet_index << 5) | (byte_index & 0x1f); + + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val); +} + +static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t nid, + unsigned char val) +{ + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val); +} + +static void hdmi_enable_output(struct hda_codec *codec) +{ + /* Enable Audio InfoFrame Transmission */ + hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); + snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT, + AC_DIPXMIT_BEST); + /* Unmute */ + if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP) + snd_hda_codec_write(codec, PIN_NID, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); + /* Enable pin out */ + snd_hda_sequence_write(codec, pinout_enable_verb); +} + +static void hdmi_disable_output(struct hda_codec *codec) +{ + snd_hda_sequence_write(codec, pinout_disable_verb); + if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP) + snd_hda_codec_write(codec, PIN_NID, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); + + /* + * FIXME: noises may arise when playing music after reloading the + * kernel module, until the next X restart or monitor repower. + */ +} + +static int hdmi_get_channel_count(struct hda_codec *codec) +{ + return 1 + snd_hda_codec_read(codec, CVT_NID, 0, + AC_VERB_GET_CVT_CHAN_COUNT, 0); +} + +static void hdmi_set_channel_count(struct hda_codec *codec, int chs) +{ + snd_hda_codec_write(codec, CVT_NID, 0, + AC_VERB_SET_CVT_CHAN_COUNT, chs - 1); + + if (chs != hdmi_get_channel_count(codec)) + snd_printd(KERN_INFO "Channel count expect=%d, real=%d\n", + chs, hdmi_get_channel_count(codec)); +} + +static void hdmi_debug_channel_mapping(struct hda_codec *codec) +{ +#ifdef CONFIG_SND_DEBUG_VERBOSE + int i; + int slot; + + for (i = 0; i < 8; i++) { + slot = snd_hda_codec_read(codec, CVT_NID, 0, + AC_VERB_GET_HDMI_CHAN_SLOT, i); + printk(KERN_DEBUG "ASP channel %d => slot %d\n", + slot >> 4, slot & 0x7); + } +#endif +} + +static void hdmi_parse_eld(struct hda_codec *codec) +{ + struct intel_hdmi_spec *spec = codec->spec; + struct hdmi_eld *eld = &spec->sink_eld; + + if (!snd_hdmi_get_eld(eld, codec, PIN_NID)) + snd_hdmi_show_eld(eld); +} + + +/* + * Audio InfoFrame routines + */ + +static void hdmi_debug_dip_size(struct hda_codec *codec) +{ +#ifdef CONFIG_SND_DEBUG_VERBOSE + int i; + int size; + + size = snd_hdmi_get_eld_size(codec, PIN_NID); + printk(KERN_DEBUG "ELD buf size is %d\n", size); + + for (i = 0; i < 8; i++) { + size = snd_hda_codec_read(codec, PIN_NID, 0, + AC_VERB_GET_HDMI_DIP_SIZE, i); + printk(KERN_DEBUG "DIP GP[%d] buf size is %d\n", i, size); + } +#endif +} + +static void hdmi_clear_dip_buffers(struct hda_codec *codec) +{ +#ifdef BE_PARANOID + int i, j; + int size; + int pi, bi; + for (i = 0; i < 8; i++) { + size = snd_hda_codec_read(codec, PIN_NID, 0, + AC_VERB_GET_HDMI_DIP_SIZE, i); + if (size == 0) + continue; + + hdmi_set_dip_index(codec, PIN_NID, i, 0x0); + for (j = 1; j < 1000; j++) { + hdmi_write_dip_byte(codec, PIN_NID, 0x0); + hdmi_get_dip_index(codec, PIN_NID, &pi, &bi); + if (pi != i) + snd_printd(KERN_INFO "dip index %d: %d != %d\n", + bi, pi, i); + if (bi == 0) /* byte index wrapped around */ + break; + } + snd_printd(KERN_INFO + "DIP GP[%d] buf reported size=%d, written=%d\n", + i, size, j); + } +#endif +} + +static void hdmi_fill_audio_infoframe(struct hda_codec *codec, + struct hdmi_audio_infoframe *ai) +{ + u8 *params = (u8 *)ai; + int i; + + hdmi_debug_dip_size(codec); + hdmi_clear_dip_buffers(codec); /* be paranoid */ + + hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); + for (i = 0; i < sizeof(ai); i++) + hdmi_write_dip_byte(codec, PIN_NID, params[i]); +} + +/* + * Compute derived values in channel_allocations[]. + */ +static void init_channel_allocations(void) +{ + int i, j; + struct cea_channel_speaker_allocation *p; + + for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { + p = channel_allocations + i; + p->channels = 0; + p->spk_mask = 0; + for (j = 0; j < ARRAY_SIZE(p->speakers); j++) + if (p->speakers[j]) { + p->channels++; + p->spk_mask |= p->speakers[j]; + } + } +} + +/* + * The transformation takes two steps: + * + * eld->spk_alloc => (eld_speaker_allocation_bits[]) => spk_mask + * spk_mask => (channel_allocations[]) => ai->CA + * + * TODO: it could select the wrong CA from multiple candidates. +*/ +static int hdmi_setup_channel_allocation(struct hda_codec *codec, + struct hdmi_audio_infoframe *ai) +{ + struct intel_hdmi_spec *spec = codec->spec; + struct hdmi_eld *eld = &spec->sink_eld; + int i; + int spk_mask = 0; + int channels = 1 + (ai->CC02_CT47 & 0x7); + char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE]; + + /* + * CA defaults to 0 for basic stereo audio + */ + if (!eld->eld_ver) + return 0; + if (!eld->spk_alloc) + return 0; + if (channels <= 2) + return 0; + + /* + * expand ELD's speaker allocation mask + * + * ELD tells the speaker mask in a compact(paired) form, + * expand ELD's notions to match the ones used by Audio InfoFrame. + */ + for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) { + if (eld->spk_alloc & (1 << i)) + spk_mask |= eld_speaker_allocation_bits[i]; + } + + /* search for the first working match in the CA table */ + for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { + if (channels == channel_allocations[i].channels && + (spk_mask & channel_allocations[i].spk_mask) == + channel_allocations[i].spk_mask) { + ai->CA = channel_allocations[i].ca_index; + break; + } + } + + snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf)); + snd_printdd(KERN_INFO + "HDMI: select CA 0x%x for %d-channel allocation: %s\n", + ai->CA, channels, buf); + + return ai->CA; +} + +static void hdmi_setup_channel_mapping(struct hda_codec *codec, + struct hdmi_audio_infoframe *ai) +{ + if (!ai->CA) + return; + + /* + * TODO: adjust channel mapping if necessary + * ALSA sequence is front/surr/clfe/side? + */ + + snd_hda_sequence_write(codec, def_chan_map); + hdmi_debug_channel_mapping(codec); +} + + +static void hdmi_setup_audio_infoframe(struct hda_codec *codec, + struct snd_pcm_substream *substream) +{ + struct hdmi_audio_infoframe ai = { + .type = 0x84, + .ver = 0x01, + .len = 0x0a, + .CC02_CT47 = substream->runtime->channels - 1, + }; + + hdmi_setup_channel_allocation(codec, &ai); + hdmi_setup_channel_mapping(codec, &ai); + + hdmi_fill_audio_infoframe(codec, &ai); +} + + +/* + * Unsolicited events + */ + +static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) +{ + int pind = !!(res & AC_UNSOL_RES_PD); + int eldv = !!(res & AC_UNSOL_RES_ELDV); + + printk(KERN_INFO "HDMI intrinsic event: PD=%d ELDV=%d\n", pind, eldv); + + if (pind && eldv) { + hdmi_parse_eld(codec); + /* TODO: do real things about ELD */ + } +} + +static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) +{ + int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT; + int cp_state = !!(res & AC_UNSOL_RES_CP_STATE); + int cp_ready = !!(res & AC_UNSOL_RES_CP_READY); + + printk(KERN_INFO "HDMI non-intrinsic event: " + "SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n", + subtag, + cp_state, + cp_ready); + + /* who cares? */ + if (cp_state) + ; + if (cp_ready) + ; +} + + +static void intel_hdmi_unsol_event(struct hda_codec *codec, unsigned int res) +{ + int tag = res >> AC_UNSOL_RES_TAG_SHIFT; + int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT; + + if (tag != INTEL_HDMI_EVENT_TAG) { + snd_printd(KERN_INFO + "Unexpected HDMI unsolicited event tag 0x%x\n", + tag); + return; + } + + if (subtag == 0) + hdmi_intrinsic_event(codec, res); + else + hdmi_non_intrinsic_event(codec, res); +} + +/* + * Callbacks + */ + +static int intel_hdmi_playback_pcm_open(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream) +{ + struct intel_hdmi_spec *spec = codec->spec; + + return snd_hda_multi_out_dig_open(codec, &spec->multiout); +} + +static int intel_hdmi_playback_pcm_close(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream) +{ + struct intel_hdmi_spec *spec = codec->spec; + + hdmi_disable_output(codec); + + return snd_hda_multi_out_dig_close(codec, &spec->multiout); +} + +static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct intel_hdmi_spec *spec = codec->spec; + + snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, + format, substream); + + hdmi_set_channel_count(codec, substream->runtime->channels); + + hdmi_setup_audio_infoframe(codec, substream); + + hdmi_enable_output(codec); + + return 0; +} + +static struct hda_pcm_stream intel_hdmi_pcm_playback = { + .substreams = 1, + .channels_min = 2, + .channels_max = 8, + .nid = CVT_NID, /* NID to query formats and rates and setup streams */ + .ops = { + .open = intel_hdmi_playback_pcm_open, + .close = intel_hdmi_playback_pcm_close, + .prepare = intel_hdmi_playback_pcm_prepare + }, +}; + +static int intel_hdmi_build_pcms(struct hda_codec *codec) +{ + struct intel_hdmi_spec *spec = codec->spec; + struct hda_pcm *info = &spec->pcm_rec; + + codec->num_pcms = 1; + codec->pcm_info = info; + + info->name = "INTEL HDMI"; + info->pcm_type = HDA_PCM_TYPE_HDMI; + info->stream[SNDRV_PCM_STREAM_PLAYBACK] = intel_hdmi_pcm_playback; + + return 0; +} + +static int intel_hdmi_build_controls(struct hda_codec *codec) +{ + struct intel_hdmi_spec *spec = codec->spec; + int err; + + err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); + if (err < 0) + return err; + + return 0; +} + +static int intel_hdmi_init(struct hda_codec *codec) +{ + /* disable audio output as early as possible */ + hdmi_disable_output(codec); + + snd_hda_sequence_write(codec, unsolicited_response_verb); + + return 0; +} + +static void intel_hdmi_free(struct hda_codec *codec) +{ + struct intel_hdmi_spec *spec = codec->spec; + + snd_hda_eld_proc_free(codec, &spec->sink_eld); + kfree(spec); +} + +static struct hda_codec_ops intel_hdmi_patch_ops = { + .init = intel_hdmi_init, + .free = intel_hdmi_free, + .build_pcms = intel_hdmi_build_pcms, + .build_controls = intel_hdmi_build_controls, + .unsol_event = intel_hdmi_unsol_event, +}; + +static int patch_intel_hdmi(struct hda_codec *codec) +{ + struct intel_hdmi_spec *spec; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (spec == NULL) + return -ENOMEM; + + spec->multiout.num_dacs = 0; /* no analog */ + spec->multiout.max_channels = 8; + spec->multiout.dig_out_nid = CVT_NID; + + codec->spec = spec; + codec->patch_ops = intel_hdmi_patch_ops; + + snd_hda_eld_proc_new(codec, &spec->sink_eld); + + init_channel_allocations(); + + return 0; +} + +struct hda_codec_preset snd_hda_preset_intelhdmi[] = { + { .id = 0x808629fb, .name = "G45 DEVCL", .patch = patch_intel_hdmi }, + { .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi }, + { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi }, + { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi }, + { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi }, + {} /* terminator */ +}; --- linux-2.6.28.orig/sound/pci/hda/hda_local.h +++ linux-2.6.28/sound/pci/hda/hda_local.h @@ -282,12 +282,18 @@ static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; } #endif +#define SND_PRINT_RATES_ADVISED_BUFSIZE 80 +void snd_print_pcm_rates(int pcm, char *buf, int buflen); + /* * Misc */ int snd_hda_check_board_config(struct hda_codec *codec, int num_configs, const char **modelnames, const struct snd_pci_quirk *pci_list); +int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, + int num_configs, const char **models, + const struct snd_pci_quirk *tbl); int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew); @@ -430,4 +436,65 @@ #define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1) #define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf) +/* + * CEA Short Audio Descriptor data + */ +struct cea_sad { + int channels; + int format; /* (format == 0) indicates invalid SAD */ + int rates; + int sample_bits; /* for LPCM */ + int max_bitrate; /* for AC3...ATRAC */ + int profile; /* for WMAPRO */ +}; + +#define ELD_FIXED_BYTES 20 +#define ELD_MAX_MNL 16 +#define ELD_MAX_SAD 16 + +/* + * ELD: EDID Like Data + */ +struct hdmi_eld { + int eld_size; + int baseline_len; + int eld_ver; /* (eld_ver == 0) indicates invalid ELD */ + int cea_edid_ver; + char monitor_name[ELD_MAX_MNL + 1]; + int manufacture_id; + int product_id; + u64 port_id; + int support_hdcp; + int support_ai; + int conn_type; + int aud_synch_delay; + int spk_alloc; + int sad_count; + struct cea_sad sad[ELD_MAX_SAD]; +#ifdef CONFIG_PROC_FS + struct snd_info_entry *proc_entry; +#endif +}; + +int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid); +int snd_hdmi_get_eld(struct hdmi_eld *, struct hda_codec *, hda_nid_t); +void snd_hdmi_show_eld(struct hdmi_eld *eld); + +#ifdef CONFIG_PROC_FS +int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld); +void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld); +#else +inline int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld) +{ + return 0; +} +static inline void snd_hda_eld_proc_free(struct hda_codec *codec, + struct hdmi_eld *eld) +{ +} +#endif + +#define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80 +void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen); + #endif /* __SOUND_HDA_LOCAL_H */ --- linux-2.6.28.orig/sound/pci/hda/hda_intel.c +++ linux-2.6.28/sound/pci/hda/hda_intel.c @@ -292,6 +292,8 @@ /* Define VIA HD Audio Device ID*/ #define VIA_HDAC_DEVICE_ID 0x3288 +/* HD Audio class code */ +#define PCI_CLASS_MULTIMEDIA_HD_AUDIO 0x0403 /* */ @@ -414,6 +416,7 @@ AZX_DRIVER_ULI, AZX_DRIVER_NVIDIA, AZX_DRIVER_TERA, + AZX_DRIVER_GENERIC, AZX_NUM_DRIVERS, /* keep this as last entry */ }; @@ -427,6 +430,7 @@ [AZX_DRIVER_ULI] = "HDA ULI M5461", [AZX_DRIVER_NVIDIA] = "HDA NVidia", [AZX_DRIVER_TERA] = "HDA Teradici", + [AZX_DRIVER_GENERIC] = "HD-Audio Generic", }; /* @@ -2063,26 +2067,31 @@ { const struct snd_pci_quirk *q; - /* Check VIA HD Audio Controller exist */ - if (chip->pci->vendor == PCI_VENDOR_ID_VIA && - chip->pci->device == VIA_HDAC_DEVICE_ID) { + switch (fix) { + case POS_FIX_LPIB: + case POS_FIX_POSBUF: + return fix; + } + + /* Check VIA/ATI HD Audio Controller exist */ + switch (chip->driver_type) { + case AZX_DRIVER_VIA: + case AZX_DRIVER_ATI: chip->via_dmapos_patch = 1; /* Use link position directly, avoid any transfer problem. */ return POS_FIX_LPIB; } chip->via_dmapos_patch = 0; - if (fix == POS_FIX_AUTO) { - q = snd_pci_quirk_lookup(chip->pci, position_fix_list); - if (q) { - printk(KERN_INFO - "hda_intel: position_fix set to %d " - "for device %04x:%04x\n", - q->value, q->subvendor, q->subdevice); - return q->value; - } + q = snd_pci_quirk_lookup(chip->pci, position_fix_list); + if (q) { + printk(KERN_INFO + "hda_intel: position_fix set to %d " + "for device %04x:%04x\n", + q->value, q->subvendor, q->subdevice); + return q->value; } - return fix; + return POS_FIX_AUTO; } /* @@ -2095,6 +2104,7 @@ SND_PCI_QUIRK(0x1014, 0x05b7, "Thinkpad Z60", 0x01), SND_PCI_QUIRK(0x17aa, 0x2010, "Thinkpad X/T/R60", 0x01), SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X/T/R61", 0x01), + SND_PCI_QUIRK(0x1028, 0x0271, "Dell Studio XPS 1340", 0x09), {} }; @@ -2208,9 +2218,17 @@ gcap = azx_readw(chip, GCAP); snd_printdd("chipset global capabilities = 0x%x\n", gcap); + /* ATI chips seems buggy about 64bit DMA addresses */ + if (chip->driver_type == AZX_DRIVER_ATI) + gcap &= ~0x01; + /* allow 64bit DMA address if supported by H/W */ if ((gcap & 0x01) && !pci_set_dma_mask(pci, DMA_64BIT_MASK)) pci_set_consistent_dma_mask(pci, DMA_64BIT_MASK); + else { + pci_set_dma_mask(pci, DMA_32BIT_MASK); + pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK); + } /* read number of streams from GCAP register instead of using * hardcoded value @@ -2229,6 +2247,7 @@ chip->playback_streams = ATIHDMI_NUM_PLAYBACK; chip->capture_streams = ATIHDMI_NUM_CAPTURE; break; + case AZX_DRIVER_GENERIC: default: chip->playback_streams = ICH6_NUM_PLAYBACK; chip->capture_streams = ICH6_NUM_CAPTURE; @@ -2453,6 +2472,11 @@ { PCI_DEVICE(0x10de, 0x0bd7), .driver_data = AZX_DRIVER_NVIDIA }, /* Teradici */ { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, + /* AMD Generic, PCI class code and Vendor ID for HD Audio */ + { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID), + .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, + .class_mask = 0xffffff, + .driver_data = AZX_DRIVER_GENERIC }, { 0, } }; MODULE_DEVICE_TABLE(pci, azx_ids); --- linux-2.6.28.orig/sound/pci/hda/patch_atihdmi.c +++ linux-2.6.28/sound/pci/hda/patch_atihdmi.c @@ -193,7 +193,6 @@ { .id = 0x1002791a, .name = "ATI RS690/780 HDMI", .patch = patch_atihdmi }, { .id = 0x1002aa01, .name = "ATI R6xx HDMI", .patch = patch_atihdmi }, { .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_atihdmi }, - { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_atihdmi }, { .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_atihdmi }, {} /* terminator */ }; --- linux-2.6.28.orig/sound/pci/mixart/mixart.c +++ linux-2.6.28/sound/pci/mixart/mixart.c @@ -607,6 +607,7 @@ /* set the format to the board */ err = mixart_set_format(stream, format); if(err < 0) { + mutex_unlock(&mgr->setup_mutex); return err; } --- linux-2.6.28.orig/sound/pci/aw2/aw2-alsa.c +++ linux-2.6.28/sound/pci/aw2/aw2-alsa.c @@ -165,7 +165,7 @@ MODULE_PARM_DESC(enable, "Enable Audiowerk2 soundcard."); static struct pci_device_id snd_aw2_ids[] = { - {PCI_VENDOR_ID_SAA7146, PCI_DEVICE_ID_SAA7146, PCI_ANY_ID, PCI_ANY_ID, + {PCI_VENDOR_ID_SAA7146, PCI_DEVICE_ID_SAA7146, 0, 0, 0, 0, 0}, {0} }; --- linux-2.6.28.orig/sound/pci/ac97/ac97_patch.c +++ linux-2.6.28/sound/pci/ac97/ac97_patch.c @@ -2832,6 +2832,8 @@ val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */ else val |= (1 << 1); /* Pin 47 is spdif input pin */ + /* this seems missing on some hardwares */ + ac97->ext_id |= AC97_EI_SPDIF; } val &= ~(1 << 12); /* vref enable */ snd_ac97_write_cache(ac97, 0x7a, val); --- linux-2.6.28.orig/sound/pci/oxygen/virtuoso.c +++ linux-2.6.28/sound/pci/oxygen/virtuoso.c @@ -899,6 +899,7 @@ .dac_channels = 8, .dac_volume_min = 0x0f, .dac_volume_max = 0xff, + .misc_flags = OXYGEN_MISC_MIDI, .function_flags = OXYGEN_FUNCTION_2WIRE, .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, --- linux-2.6.28.orig/sound/pci/oxygen/oxygen.c +++ linux-2.6.28/sound/pci/oxygen/oxygen.c @@ -61,6 +61,7 @@ enum { MODEL_CMEDIA_REF, /* C-Media's reference design */ MODEL_MERIDIAN, /* AuzenTech X-Meridian */ + MODEL_HALO, /* HT-Omega Claro halo */ }; static struct pci_device_id oxygen_ids[] __devinitdata = { @@ -74,6 +75,7 @@ { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN }, { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CMEDIA_REF }, + { OXYGEN_PCI_SUBID(0x7284, 0x9781), .driver_data = MODEL_HALO }, { } }; MODULE_DEVICE_TABLE(pci, oxygen_ids); @@ -301,6 +303,8 @@ PLAYBACK_1_TO_SPDIF | CAPTURE_0_FROM_I2S_2 | CAPTURE_1_FROM_SPDIF; + } + if (driver_data == MODEL_MERIDIAN || driver_data == MODEL_HALO) { chip->model.misc_flags = OXYGEN_MISC_MIDI; chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT; } --- linux-2.6.28.orig/sound/arm/mxc-alsa-spdif.c +++ linux-2.6.28/sound/arm/mxc-alsa-spdif.c @@ -0,0 +1,2264 @@ +/* + * Copyright 2007-2009 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 + */ + +/*! + * @defgroup SOUND_DRV MXC Sound Driver for ALSA + */ + +/*! + * @file mxc-alsa-spdif.c + * @brief this fle mxc-alsa-spdif.c + * @brief this file implements mxc alsa driver for spdif. + * The spdif tx supports consumer channel for linear PCM and + * compressed audio data. The supported sample rates are + * 48KHz, 44.1KHz and 32KHz. + * + * @ingroup SOUND_DRV + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_PM +#include +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define MXC_SPDIF_NAME "MXC_SPDIF" +static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; +static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; +static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; +module_param_array(index, int, NULL, 0444); +MODULE_PARM_DESC(index, "Index value for spdif sound card."); +module_param_array(id, charp, NULL, 0444); +MODULE_PARM_DESC(id, "ID string for spdif sound card."); +module_param_array(enable, bool, NULL, 0444); +MODULE_PARM_DESC(enable, "Enable spdif sound card."); + +#define SPDIF_MAX_BUF_SIZE (32*1024) +#define SPDIF_DMA_BUF_SIZE (8*1024) +#define SPDIF_MIN_PERIOD_SIZE 64 +#define SPDIF_MIN_PERIOD 2 +#define SPDIF_MAX_PERIOD 255 + +#define SPDIF_REG_SCR 0x00 +#define SPDIF_REG_SRCD 0x04 +#define SPDIF_REG_SRPC 0x08 +#define SPDIF_REG_SIE 0x0C +#define SPDIF_REG_SIS 0x10 +#define SPDIF_REG_SIC 0x10 +#define SPDIF_REG_SRL 0x14 +#define SPDIF_REG_SRR 0x18 +#define SPDIF_REG_SRCSLH 0x1C +#define SPDIF_REG_SRCSLL 0x20 +#define SPDIF_REG_SQU 0x24 +#define SPDIF_REG_SRQ 0x28 +#define SPDIF_REG_STL 0x2C +#define SPDIF_REG_STR 0x30 +#define SPDIF_REG_STCSCH 0x34 +#define SPDIF_REG_STCSCL 0x38 +#define SPDIF_REG_SRFM 0x44 +#define SPDIF_REG_STC 0x50 + +/* SPDIF Configuration register */ +#define SCR_RXFIFO_CTL_ZERO (1 << 23) +#define SCR_RXFIFO_OFF (1 << 22) +#define SCR_RXFIFO_RST (1 << 21) +#define SCR_RXFIFO_FSEL_BIT (19) +#define SCR_RXFIFO_FSEL_MASK (0x3 << SCR_RXFIFO_FSEL_BIT) +#define SCR_RXFIFO_AUTOSYNC (1 << 18) +#define SCR_TXFIFO_AUTOSYNC (1 << 17) +#define SCR_TXFIFO_ESEL_BIT (15) +#define SCR_TXFIFO_ESEL_MASK (0x3 << SCR_TXFIFO_FSEL_BIT) +#define SCR_LOW_POWER (1 << 13) +#define SCR_SOFT_RESET (1 << 12) +#define SCR_TXFIFO_ZERO (0 << 10) +#define SCR_TXFIFO_NORMAL (1 << 10) +#define SCR_TXFIFO_ONESAMPLE (1 << 11) +#define SCR_DMA_RX_EN (1 << 9) +#define SCR_DMA_TX_EN (1 << 8) +#define SCR_VAL_CLEAR (1 << 5) +#define SCR_TXSEL_OFF (0 << 2) +#define SCR_TXSEL_RX (1 << 2) +#define SCR_TXSEL_NORMAL (0x5 << 2) +#define SCR_USRC_SEL_NONE (0x0) +#define SCR_USRC_SEL_RECV (0x1) +#define SCR_USRC_SEL_CHIP (0x3) + +/* SPDIF CDText control */ +#define SRCD_CD_USER_OFFSET 1 +#define SRCD_CD_USER (1 << SRCD_CD_USER_OFFSET) + +/* SPDIF Phase Configuration register */ +#define SRPC_DPLL_LOCKED (1 << 6) +#define SRPC_CLKSRC_SEL_OFFSET 7 +#define SRPC_CLKSRC_SEL_LOCKED 5 +/* gain sel */ +#define SRPC_GAINSEL_OFFSET 3 + +enum spdif_gainsel { + GAINSEL_MULTI_24 = 0, + GAINSEL_MULTI_16, + GAINSEL_MULTI_12, + GAINSEL_MULTI_8, + GAINSEL_MULTI_6, + GAINSEL_MULTI_4, + GAINSEL_MULTI_3, + GAINSEL_MULTI_MAX, +}; + +#define SPDIF_DEFAULT_GAINSEL GAINSEL_MULTI_8 + +/* SPDIF interrupt mask define */ +#define INT_DPLL_LOCKED (1 << 20) +#define INT_TXFIFO_UNOV (1 << 19) +#define INT_TXFIFO_RESYNC (1 << 18) +#define INT_CNEW (1 << 17) +#define INT_VAL_NOGOOD (1 << 16) +#define INT_SYM_ERR (1 << 15) +#define INT_BIT_ERR (1 << 14) +#define INT_URX_FUL (1 << 10) +#define INT_URX_OV (1 << 9) +#define INT_QRX_FUL (1 << 8) +#define INT_QRX_OV (1 << 7) +#define INT_UQ_SYNC (1 << 6) +#define INT_UQ_ERR (1 << 5) +#define INT_RX_UNOV (1 << 4) +#define INT_RX_RESYNC (1 << 3) +#define INT_LOSS_LOCK (1 << 2) +#define INT_TX_EMPTY (1 << 1) +#define INT_RXFIFO_FUL (1 << 0) + +/* SPDIF Clock register */ +#define STC_SYSCLK_DIV_OFFSET 11 +#define STC_TXCLK_SRC_OFFSET 8 +#define STC_TXCLK_DIV_OFFSET 0 + +#define SPDIF_CSTATUS_BYTE 6 +#define SPDIF_UBITS_SIZE 96 +#define SPDIF_QSUB_SIZE (SPDIF_UBITS_SIZE/8) + +enum spdif_clk_accuracy { + SPDIF_CLK_ACCURACY_LEV2 = 0, + SPDIF_CLK_ACCURACY_LEV1 = 2, + SPDIF_CLK_ACCURACY_LEV3 = 1, + SPDIF_CLK_ACCURACY_RESV = 3 +}; + +/* SPDIF clock source */ +enum spdif_clk_src { + SPDIF_CLK_SRC1 = 0, + SPDIF_CLK_SRC2, + SPDIF_CLK_SRC3, + SPDIF_CLK_SRC4, + SPDIF_CLK_SRC5, +}; + +enum spdif_max_wdl { + SPDIF_MAX_WDL_20, + SPDIF_MAX_WDL_24 +}; + +enum spdif_wdl { + SPDIF_WDL_DEFAULT = 0, + SPDIF_WDL_FIFTH = 4, + SPDIF_WDL_FOURTH = 3, + SPDIF_WDL_THIRD = 2, + SPDIF_WDL_SECOND = 1, + SPDIF_WDL_MAX = 5 +}; + +static unsigned int gainsel_multi[GAINSEL_MULTI_MAX] = { + 24 * 1024, 16 * 1024, 12 * 1024, + 8 * 1024, 6 * 1024, 4 * 1024, + 3 * 1024, +}; + +/*! + * SPDIF control structure + * Defines channel status, subcode and Q sub + */ +struct spdif_mixer_control { + + /* spinlock to access control data */ + spinlock_t ctl_lock; + /* IEC958 channel tx status bit */ + unsigned char ch_status[4]; + /* User bits */ + unsigned char subcode[2 * SPDIF_UBITS_SIZE]; + /* Q subcode part of user bits */ + unsigned char qsub[2 * SPDIF_QSUB_SIZE]; + /* buffer ptrs for writer */ + unsigned int upos; + unsigned int qpos; + /* ready buffer index of the two buffers */ + unsigned int ready_buf; +}; + +/*! + * This structure represents an audio stream in term of + * channel DMA, HW configuration on spdif controller. + */ +struct mxc_spdif_stream { + + /*! + * identification string + */ + char *id; + /*! + * device identifier for DMA + */ + int dma_wchannel; + /*! + * we are using this stream for transfer now + */ + int active:1; + /*! + * current transfer period + */ + int period; + /*! + * current count of transfered periods + */ + int periods; + /*! + * for locking in DMA operations + */ + spinlock_t dma_lock; + /*! + * Alsa substream pointer + */ + struct snd_pcm_substream *stream; +}; + +struct mxc_spdif_device { + /*! + * SPDIF module register base address + */ + unsigned long __iomem *reg_base; + + /*! + * spdif tx available or not + */ + int mxc_spdif_tx; + + /*! + * spdif rx available or not + */ + int mxc_spdif_rx; + + /*! + * spdif 44100 clock src + */ + int spdif_txclk_44100; + + /*! + * spdif 48000 clock src + */ + int spdif_txclk_48000; + + /*! + * ALSA SPDIF sound card handle + */ + struct snd_card *card; + + /*! + * ALSA spdif driver type handle + */ + struct snd_pcm *pcm; + + /*! + * DPLL locked status + */ + atomic_t dpll_locked; + + /*! + * Playback/Capture substream + */ + struct mxc_spdif_stream s[2]; +}; + +static struct spdif_mixer_control mxc_spdif_control; + +static unsigned long spdif_base_addr; + +/* define each spdif interrupt handlers */ +typedef void (*spdif_irq_func_t) (unsigned int bit, void *desc); + +/* spdif irq functions declare */ +static void spdif_irq_fifo(unsigned int bit, void *devid); +static void spdif_irq_dpll_lock(unsigned int bit, void *devid); +static void spdif_irq_uq(unsigned int bit, void *devid); +static void spdif_irq_bit_error(unsigned int bit, void *devid); +static void spdif_irq_sym_error(unsigned int bit, void *devid); +static void spdif_irq_valnogood(unsigned int bit, void *devid); +static void spdif_irq_cnew(unsigned int bit, void *devid); + +/* irq function list */ +static spdif_irq_func_t spdif_irq_handlers[] = { + spdif_irq_fifo, + spdif_irq_fifo, + spdif_irq_dpll_lock, + NULL, + spdif_irq_fifo, + spdif_irq_uq, + spdif_irq_uq, + spdif_irq_uq, + spdif_irq_uq, + spdif_irq_uq, + spdif_irq_uq, + NULL, + NULL, + NULL, + spdif_irq_bit_error, + spdif_irq_sym_error, + spdif_irq_valnogood, + spdif_irq_cnew, + NULL, + spdif_irq_fifo, + spdif_irq_dpll_lock, +}; + +/*! + * @brief Enable/Disable spdif DMA request + * + * This function is called to enable or disable the dma transfer + */ +static void spdif_dma_enable(int txrx, int enable) +{ + unsigned long value; + + value = __raw_readl(SPDIF_REG_SCR + spdif_base_addr) & 0xfffeff; + if (enable) + value |= txrx; + + __raw_writel(value, SPDIF_REG_SCR + spdif_base_addr); + +} + +/*! + * @brief Enable spdif interrupt + * + * This function is called to enable relevant interrupts. + */ +static void spdif_intr_enable(unsigned long intr, int enable) +{ + unsigned long value; + + value = __raw_readl(spdif_base_addr + SPDIF_REG_SIE) & 0xffffff; + if (enable) + value |= intr; + else + value &= ~intr; + + __raw_writel(value, spdif_base_addr + SPDIF_REG_SIE); +} + +/*! + * @brief Set the clock accuracy level in the channel bit + * + * This function is called to set the clock accuracy level + */ +static int spdif_set_clk_accuracy(enum spdif_clk_accuracy level) +{ + unsigned long value; + + value = __raw_readl(SPDIF_REG_STCSCL + spdif_base_addr) & 0xffffcf; + value |= (level << 4); + __raw_writel(value, SPDIF_REG_STCSCL + spdif_base_addr); + + return 0; +} + +/*! + * set SPDIF PhaseConfig register for rx clock + */ +static int spdif_set_rx_clksrc(enum spdif_clk_src clksrc, + enum spdif_gainsel gainsel, int dpll_locked) +{ + unsigned long value; + if (clksrc > SPDIF_CLK_SRC5 || gainsel > GAINSEL_MULTI_3) + return 1; + + value = (dpll_locked ? (clksrc) : + (clksrc + SRPC_CLKSRC_SEL_LOCKED)) << SRPC_CLKSRC_SEL_OFFSET | + (gainsel << SRPC_GAINSEL_OFFSET); + __raw_writel(value, spdif_base_addr + SPDIF_REG_SRPC); + + return 0; +} + +/*! + * Get RX data clock rate + * given the SPDIF bus_clk + */ +static int spdif_get_rxclk_rate(struct clk *bus_clk, enum spdif_gainsel gainsel) +{ + unsigned long freqmeas, phaseconf, busclk_freq = 0; + u64 tmpval64; + enum spdif_clk_src clksrc; + + freqmeas = __raw_readl(spdif_base_addr + SPDIF_REG_SRFM); + phaseconf = __raw_readl(spdif_base_addr + SPDIF_REG_SRPC); + + clksrc = (phaseconf >> SRPC_CLKSRC_SEL_OFFSET) & 0x0F; + if (clksrc < 5 && (phaseconf & SRPC_DPLL_LOCKED)) { + /* get bus clock from system */ + busclk_freq = clk_get_rate(bus_clk); + } + + /* FreqMeas_CLK = (BUS_CLK*FreqMeas[23:0])/2^10/GAINSEL/128 */ + tmpval64 = (u64) busclk_freq * freqmeas; + do_div(tmpval64, gainsel_multi[gainsel]); + do_div(tmpval64, 128 * 1024); + return (int)tmpval64; +} + +/*! + * @brief Set the audio sample rate in the channel status bit + * + * This function is called to set the audio sample rate to be transfered. + */ +static int spdif_set_sample_rate(int src_44100, int src_48000, int sample_rate) +{ + unsigned long cstatus, stc; + + cstatus = __raw_readl(SPDIF_REG_STCSCL + spdif_base_addr) & 0xfffff0; + stc = __raw_readl(SPDIF_REG_STC + spdif_base_addr) & ~0x7FF; + + switch (sample_rate) { + case 44100: + __raw_writel(cstatus, SPDIF_REG_STCSCL + spdif_base_addr); + stc |= (src_44100 << 8) | 0x07; + __raw_writel(stc, SPDIF_REG_STC + spdif_base_addr); + pr_debug("set sample rate to 44100\n"); + break; + case 48000: + cstatus |= 0x04; + __raw_writel(cstatus, SPDIF_REG_STCSCL + spdif_base_addr); + stc |= (src_48000 << 8) | 0x07; + __raw_writel(stc, SPDIF_REG_STC + spdif_base_addr); + pr_debug("set sample rate to 48000\n"); + break; + case 32000: + cstatus |= 0x0c; + __raw_writel(cstatus, SPDIF_REG_STCSCL + spdif_base_addr); + stc |= (src_48000 << 8) | 0x0b; + __raw_writel(stc, SPDIF_REG_STC + spdif_base_addr); + pr_debug("set sample rate to 32000\n"); + break; + } + + return 0; +} + +/*! + * @brief Set the lchannel status bit + * + * This function is called to set the channel status + */ +static int spdif_set_channel_status(int value, unsigned long reg) +{ + __raw_writel(value & 0xffffff, reg + spdif_base_addr); + + return 0; +} + +/*! + * @brief Get spdif interrupt status and clear the interrupt + * + * This function is called to check relevant interrupt status + */ +static int spdif_intr_status(void) +{ + unsigned long value; + + value = __raw_readl(SPDIF_REG_SIS + spdif_base_addr) & 0xffffff; + value &= __raw_readl(spdif_base_addr + SPDIF_REG_SIE); + __raw_writel(value, SPDIF_REG_SIC + spdif_base_addr); + + return value; +} + +/*! + * @brief spdif interrupt handler + */ +static irqreturn_t spdif_isr(int irq, void *dev_id) +{ + unsigned long int_stat; + int line; + + int_stat = spdif_intr_status(); + + while ((line = ffs(int_stat)) != 0) { + int_stat &= ~(1UL << (line - 1)); + if (spdif_irq_handlers[line - 1] != NULL) + spdif_irq_handlers[line - 1] (line - 1, dev_id); + } + + return IRQ_HANDLED; +} + +/*! + * Interrupt handlers + * + */ +/*! + * FIFO related interrupts handler + * + * Rx FIFO Full, Underrun/Overrun interrupts + * Tx FIFO Empty, Underrun/Overrun interrupts + */ +static void spdif_irq_fifo(unsigned int bit, void *devid) +{ + +} + +/*! + * DPLL lock related interrupts handler + * + * DPLL locked and lock loss interrupts + */ +static void spdif_irq_dpll_lock(unsigned int bit, void *devid) +{ + struct mxc_spdif_device *chip = (struct mxc_spdif_device *)devid; + unsigned int locked = __raw_readl(spdif_base_addr + SPDIF_REG_SRPC); + + if (locked & SRPC_DPLL_LOCKED) { + pr_debug("SPDIF Rx dpll locked\n"); + atomic_set(&chip->dpll_locked, 1); + } else { + /* INT_LOSS_LOCK */ + pr_debug("SPDIF Rx dpll loss lock\n"); + atomic_set(&chip->dpll_locked, 0); + } +} + +/*! + * U/Q channel related interrupts handler + * + * U/QChannel full, overrun interrupts + * U/QChannel sync error and frame error interrupts + */ +static void spdif_irq_uq(unsigned int bit, void *devid) +{ + unsigned long val; + int index; + struct spdif_mixer_control *ctrl = &mxc_spdif_control; + + bit = 1 << bit; + /* get U/Q channel datas */ + switch (bit) { + + case INT_URX_OV: /* read U data */ + pr_debug("User bit receive overrun\n"); + case INT_URX_FUL: + pr_debug("U bit receive full\n"); + + if (ctrl->upos >= SPDIF_UBITS_SIZE * 2) { + ctrl->upos = 0; + } else if (unlikely((ctrl->upos % SPDIF_UBITS_SIZE) + 3 + > SPDIF_UBITS_SIZE)) { + pr_err("User bit receivce buffer overflow\n"); + break; + } + val = __raw_readl(spdif_base_addr + SPDIF_REG_SQU); + ctrl->subcode[ctrl->upos++] = val >> 16; + ctrl->subcode[ctrl->upos++] = val >> 8; + ctrl->subcode[ctrl->upos++] = val; + + break; + + case INT_QRX_OV: /* read Q data */ + pr_debug("Q bit receive overrun\n"); + case INT_QRX_FUL: + pr_debug("Q bit receive full\n"); + + if (ctrl->qpos >= SPDIF_QSUB_SIZE * 2) { + ctrl->qpos = 0; + } else if (unlikely((ctrl->qpos % SPDIF_QSUB_SIZE) + 3 + > SPDIF_QSUB_SIZE)) { + pr_err("Q bit receivce buffer overflow\n"); + break; + } + val = __raw_readl(spdif_base_addr + SPDIF_REG_SRQ); + ctrl->qsub[ctrl->qpos++] = val >> 16; + ctrl->qsub[ctrl->qpos++] = val >> 8; + ctrl->qsub[ctrl->qpos++] = val; + + break; + + case INT_UQ_ERR: /* read U/Q data and do buffer reset */ + pr_debug("U/Q bit receive error\n"); + val = __raw_readl(spdif_base_addr + SPDIF_REG_SQU); + val = __raw_readl(spdif_base_addr + SPDIF_REG_SRQ); + /* drop this U/Q buffer */ + ctrl->ready_buf = ctrl->upos = ctrl->qpos = 0; + break; + + case INT_UQ_SYNC: /* U/Q buffer reset */ + pr_debug("U/Q sync receive\n"); + + if (ctrl->qpos == 0) + break; + index = (ctrl->qpos - 1) / SPDIF_QSUB_SIZE; + /* set ready to this buffer */ + ctrl->ready_buf = index + 1; + break; + } +} + +/*! + * SPDIF receiver found parity bit error interrupt handler + */ +static void spdif_irq_bit_error(unsigned int bit, void *devid) +{ + pr_debug("SPDIF interrupt parity bit error\n"); +} + +/*! + * SPDIF receiver found illegal symbol interrupt handler + */ +static void spdif_irq_sym_error(unsigned int bit, void *devid) +{ + pr_debug("SPDIF interrupt symbol error\n"); +} + +/*! + * SPDIF validity flag no good interrupt handler + */ +static void spdif_irq_valnogood(unsigned int bit, void *devid) +{ + pr_debug("SPDIF interrupt validate is not good\n"); +} + +/*! + * SPDIF receive change in value of control channel + */ +static void spdif_irq_cnew(unsigned int bit, void *devid) +{ + pr_debug("SPDIF interrupt cstatus new\n"); +} + +/*! + * Do software reset to SPDIF + */ +static void spdif_softreset(void) +{ + unsigned long value = 1; + int cycle = 0; + __raw_writel(SCR_SOFT_RESET, spdif_base_addr + SPDIF_REG_SCR); + while (value && (cycle++ < 10)) { + value = __raw_readl(spdif_base_addr + SPDIF_REG_SCR) & 0x1000; + } + +} + +/*! + * SPDIF RX initial function + */ +static void spdif_rx_init(void) +{ + unsigned long regval; + + regval = __raw_readl(spdif_base_addr + SPDIF_REG_SCR); + /** + * initial and reset SPDIF configuration: + * RxFIFO off + * RxFIFO sel to 8 sample + * Autosync + * Valid bit set + */ + regval &= ~(SCR_RXFIFO_OFF | SCR_RXFIFO_CTL_ZERO | SCR_LOW_POWER); + regval |= (2 << SCR_RXFIFO_FSEL_BIT) | SCR_RXFIFO_AUTOSYNC; + __raw_writel(regval, spdif_base_addr + SPDIF_REG_SCR); +} + +/*! + * SPDIF RX un-initial function + */ +static void spdif_rx_uninit(void) +{ + unsigned long regval; + + /* turn off RX fifo, disable dma and autosync */ + regval = __raw_readl(spdif_base_addr + SPDIF_REG_SCR); + regval |= SCR_RXFIFO_OFF | SCR_RXFIFO_CTL_ZERO; + regval &= ~(SCR_DMA_RX_EN | SCR_RXFIFO_AUTOSYNC); + __raw_writel(regval, spdif_base_addr + SPDIF_REG_SCR); +} + +/*! + * @brief Initialize spdif module + * + * This function is called to set the spdif to initial state. + */ +static void spdif_tx_init(void) +{ + unsigned long regval; + + regval = __raw_readl(spdif_base_addr + SPDIF_REG_SCR); + + regval &= 0xfc32e3; + regval |= SCR_TXFIFO_AUTOSYNC | SCR_TXFIFO_NORMAL | + SCR_TXSEL_NORMAL | SCR_USRC_SEL_CHIP | (2 << SCR_TXFIFO_ESEL_BIT); + __raw_writel(regval, SPDIF_REG_SCR + spdif_base_addr); + + /* Default clock source from EXTAL, divider by 8, generate 44.1kHz + sample rate */ + regval = 0x07; + __raw_writel(regval, SPDIF_REG_STC + spdif_base_addr); + +} + +/*! + * @brief deinitialize spdif module + * + * This function is called to stop the spdif + */ +static void spdif_tx_uninit(void) +{ + unsigned long regval; + + regval = __raw_readl(SPDIF_REG_SCR + spdif_base_addr) & 0xffffe3; + regval |= SCR_TXSEL_OFF; + __raw_writel(regval, SPDIF_REG_SCR + spdif_base_addr); + regval = __raw_readl(SPDIF_REG_STC + spdif_base_addr) & ~0x7FF; + regval |= (0x7 << STC_TXCLK_SRC_OFFSET); + __raw_writel(regval, SPDIF_REG_STC + spdif_base_addr); + +} + +static unsigned int spdif_playback_rates[] = { 32000, 44100, 48000 }; +static unsigned int spdif_capture_rates[] = { + 16000, 32000, 44100, 48000, 64000, 96000 +}; + +/*! + * this structure represents the sample rates supported + * by SPDIF + */ +static struct snd_pcm_hw_constraint_list hw_playback_rates_stereo = { + .count = ARRAY_SIZE(spdif_playback_rates), + .list = spdif_playback_rates, + .mask = 0, +}; + +static struct snd_pcm_hw_constraint_list hw_capture_rates_stereo = { + .count = ARRAY_SIZE(spdif_capture_rates), + .list = spdif_capture_rates, + .mask = 0, +}; + +/*! + * This structure reprensents the capabilities of the driver + * in playback mode. + */ +static struct snd_pcm_hardware snd_spdif_playback_hw = { + .info = + (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_HALF_DUPLEX | + SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_RESUME), + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | + SNDRV_PCM_FMTBIT_S24_LE, + .rates = + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, + .rate_min = 32000, + .rate_max = 48000, + .channels_min = 2, + .channels_max = 2, + .buffer_bytes_max = SPDIF_MAX_BUF_SIZE, + .period_bytes_min = SPDIF_MIN_PERIOD_SIZE, + .period_bytes_max = SPDIF_DMA_BUF_SIZE, + .periods_min = SPDIF_MIN_PERIOD, + .periods_max = SPDIF_MAX_PERIOD, + .fifo_size = 0, +}; + +/*! + * This structure reprensents the capabilities of the driver + * in capture mode. + */ +static struct snd_pcm_hardware snd_spdif_capture_hw = { + .info = (SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME), + .formats = SNDRV_PCM_FMTBIT_S24_LE, + .rates = + (SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 + | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | + SNDRV_PCM_RATE_96000), + .rate_min = 16000, + .rate_max = 96000, + .channels_min = 2, + .channels_max = 2, + .buffer_bytes_max = SPDIF_MAX_BUF_SIZE, + .period_bytes_min = SPDIF_MIN_PERIOD_SIZE, + .period_bytes_max = SPDIF_DMA_BUF_SIZE, + .periods_min = SPDIF_MIN_PERIOD, + .periods_max = SPDIF_MAX_PERIOD, + .fifo_size = 0, + +}; + +/*! + * This function configures the DMA channel used to transfer + * audio from MCU to SPDIF or from SPDIF to MCU + * + * @param s pointer to the structure of the current stream. + * @param callback pointer to function that will be + * called when a SDMA TX transfer finishes. + * + * @return 0 on success, -1 otherwise. + */ +static int +spdif_configure_dma_channel(struct mxc_spdif_stream *s, + mxc_dma_callback_t callback) +{ + int ret = -1; + int channel = -1; + + if (s->dma_wchannel != 0) + mxc_dma_free(s->dma_wchannel); + + if (s->stream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + + if (s->stream->runtime->sample_bits > 16) { + channel = + mxc_dma_request(MXC_DMA_SPDIF_32BIT_TX, + "SPDIF TX DMA"); + } else { + channel = + mxc_dma_request(MXC_DMA_SPDIF_16BIT_TX, + "SPDIF TX DMA"); + } + + } else if (s->stream->stream == SNDRV_PCM_STREAM_CAPTURE) { + + channel = mxc_dma_request(MXC_DMA_SPDIF_32BIT_RX, + "SPDIF RX DMA"); + + } + + pr_debug("spdif_configure_dma_channel: %d\n", channel); + + ret = mxc_dma_callback_set(channel, + (mxc_dma_callback_t) callback, (void *)s); + if (ret != 0) { + pr_info("spdif_configure_dma_channel - err\n"); + mxc_dma_free(channel); + return -1; + } + s->dma_wchannel = channel; + return 0; +} + +/*! + * This function gets the dma pointer position during playback/capture. + * Our DMA implementation does not allow to retrieve this position + * when a transfert is active, so, it answers the middle of + * the current period beeing transfered + * + * @param s pointer to the structure of the current stream. + * + */ +static u_int spdif_get_dma_pos(struct mxc_spdif_stream *s) +{ + struct snd_pcm_substream *substream; + struct snd_pcm_runtime *runtime; + unsigned int offset = 0; + substream = s->stream; + runtime = substream->runtime; + + offset = (runtime->period_size * (s->periods)); + if (offset >= runtime->buffer_size) + offset = 0; + pr_debug + ("MXC: spdif_get_dma_pos BIS offset %d, buffer_size %d\n", + offset, (int)runtime->buffer_size); + return offset; +} + +/*! + * This function stops the current dma transfert for playback + * and clears the dma pointers. + * + * @param s pointer to the structure of the current stream. + * + */ +static void spdif_stop_tx(struct mxc_spdif_stream *s) +{ + struct snd_pcm_substream *substream; + struct snd_pcm_runtime *runtime; + unsigned int dma_size; + unsigned int offset; + + substream = s->stream; + runtime = substream->runtime; + dma_size = frames_to_bytes(runtime, runtime->period_size); + offset = dma_size * s->periods; + + s->active = 0; + s->period = 0; + s->periods = 0; + + /* this stops the dma channel and clears the buffer ptrs */ + mxc_dma_disable(s->dma_wchannel); + spdif_dma_enable(SCR_DMA_TX_EN, 0); + dma_unmap_single(NULL, runtime->dma_addr + offset, dma_size, + DMA_TO_DEVICE); +} + +/*! + * This function is called whenever a new audio block needs to be + * transferred to SPDIF. The function receives the address and the size + * of the new block and start a new DMA transfer. + * + * @param s pointer to the structure of the current stream. + * + */ +static void spdif_start_tx(struct mxc_spdif_stream *s) +{ + struct snd_pcm_substream *substream; + struct snd_pcm_runtime *runtime; + unsigned int dma_size = 0; + unsigned int offset; + int ret = 0; + mxc_dma_requestbuf_t dma_request; + substream = s->stream; + runtime = substream->runtime; + memset(&dma_request, 0, sizeof(mxc_dma_requestbuf_t)); + if (s->active) { + dma_size = frames_to_bytes(runtime, runtime->period_size); + offset = dma_size * s->period; + dma_request.src_addr = + (dma_addr_t) (dma_map_single + (NULL, runtime->dma_area + offset, dma_size, + DMA_TO_DEVICE)); + + dma_request.dst_addr = (dma_addr_t) (SPDIF_BASE_ADDR + 0x2c); + + dma_request.num_of_bytes = dma_size; + mxc_dma_config(s->dma_wchannel, &dma_request, 1, + MXC_DMA_MODE_WRITE); + ret = mxc_dma_enable(s->dma_wchannel); + spdif_dma_enable(SCR_DMA_TX_EN, 1); + if (ret) { + pr_info("audio_process_dma: cannot queue DMA \ + buffer\n"); + return; + } + s->period++; + s->period %= runtime->periods; + + if ((s->period > s->periods) + && ((s->period - s->periods) > 1)) { + pr_debug("audio playback chain dma: already double \ + buffered\n"); + return; + } + + if ((s->period < s->periods) + && ((s->period + runtime->periods - s->periods) > 1)) { + pr_debug("audio playback chain dma: already double \ + buffered\n"); + return; + } + + if (s->period == s->periods) { + pr_debug("audio playback chain dma: s->period == \ + s->periods\n"); + return; + } + + if (snd_pcm_playback_hw_avail(runtime) < + 2 * runtime->period_size) { + pr_debug("audio playback chain dma: available data \ + is not enough\n"); + return; + } + + pr_debug + ("audio playback chain dma:to set up the 2nd dma buffer\n"); + pr_debug("SCR: 0x%08x\n", + __raw_readl(spdif_base_addr + SPDIF_REG_SCR)); + + offset = dma_size * s->period; + dma_request.src_addr = + (dma_addr_t) (dma_map_single + (NULL, runtime->dma_area + offset, dma_size, + DMA_TO_DEVICE)); + mxc_dma_config(s->dma_wchannel, &dma_request, 1, + MXC_DMA_MODE_WRITE); + ret = mxc_dma_enable(s->dma_wchannel); + s->period++; + s->period %= runtime->periods; + + } + return; +} + +/*! + * This is a callback which will be called + * when a TX transfer finishes. The call occurs + * in interrupt context. + * + * @param data pointer to the structure of the current stream + * @param error DMA error flag + * @param count number of bytes transfered by the DMA + */ +static void spdif_tx_callback(void *data, int error, unsigned int count) +{ + struct mxc_spdif_stream *s; + struct snd_pcm_substream *substream; + struct snd_pcm_runtime *runtime; + unsigned int dma_size; + unsigned int previous_period; + unsigned int offset; + s = data; + substream = s->stream; + runtime = substream->runtime; + previous_period = s->periods; + dma_size = frames_to_bytes(runtime, runtime->period_size); + offset = dma_size * previous_period; + + spin_lock(&s->dma_lock); + s->periods++; + s->periods %= runtime->periods; + dma_unmap_single(NULL, runtime->dma_addr + offset, dma_size, + DMA_TO_DEVICE); + spin_unlock(&s->dma_lock); + + if (s->active) + snd_pcm_period_elapsed(s->stream); + + spin_lock(&s->dma_lock); + spdif_start_tx(s); + spin_unlock(&s->dma_lock); +} + +/*! + * This function is a dispatcher of command to be executed + * by the driver for playback. + * + * @param substream pointer to the structure of the current stream. + * @param cmd command to be executed + * + * @return 0 on success, -1 otherwise. + */ +static int +snd_mxc_spdif_playback_trigger(struct snd_pcm_substream *substream, int cmd) +{ + struct mxc_spdif_device *chip; + struct mxc_spdif_stream *s; + int err = 0; + unsigned long flags; + chip = snd_pcm_substream_chip(substream); + s = &chip->s[SNDRV_PCM_STREAM_PLAYBACK]; + + spin_lock_irqsave(&s->dma_lock, flags); + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + s->active = 1; + spdif_start_tx(s); + break; + case SNDRV_PCM_TRIGGER_STOP: + spdif_stop_tx(s); + break; + case SNDRV_PCM_TRIGGER_SUSPEND: + s->active = 0; + s->periods = 0; + break; + case SNDRV_PCM_TRIGGER_RESUME: + s->active = 1; + spdif_start_tx(s); + break; + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + s->active = 0; + break; + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + s->active = 1; + spdif_start_tx(s); + break; + default: + err = -EINVAL; + break; + } + spin_unlock_irqrestore(&s->dma_lock, flags); + return err; +} + +/*! + * This function configures the hardware to allow audio + * playback operations. It is called by ALSA framework. + * + * @param substream pointer to the structure of the current stream. + * + * @return 0 on success, -1 otherwise. + */ +static int snd_mxc_spdif_playback_prepare(struct snd_pcm_substream *substream) +{ + struct mxc_spdif_device *chip; + struct snd_pcm_runtime *runtime; + int err; + unsigned int ch_status; + + chip = snd_pcm_substream_chip(substream); + runtime = substream->runtime; + + spdif_tx_init(); + + ch_status = + ((mxc_spdif_control.ch_status[2] << 16) | (mxc_spdif_control. + ch_status[1] << 8) | + mxc_spdif_control.ch_status[0]); + spdif_set_channel_status(ch_status, SPDIF_REG_STCSCH); + ch_status = mxc_spdif_control.ch_status[3]; + spdif_set_channel_status(ch_status, SPDIF_REG_STCSCL); + spdif_intr_enable(INT_TXFIFO_RESYNC, 1); + spdif_set_sample_rate(chip->spdif_txclk_44100, chip->spdif_txclk_48000, + runtime->rate); + spdif_set_clk_accuracy(SPDIF_CLK_ACCURACY_LEV2); + /* setup DMA controller for spdif tx */ + err = spdif_configure_dma_channel(&chip-> + s[SNDRV_PCM_STREAM_PLAYBACK], + spdif_tx_callback); + if (err < 0) { + pr_info("snd_mxc_spdif_playback_prepare - err < 0\n"); + return err; + } + + /** + * FIXME: dump registers + */ + pr_debug("SCR: 0x%08x\n", __raw_readl(spdif_base_addr + SPDIF_REG_SCR)); + pr_debug("SIE: 0x%08x\n", __raw_readl(spdif_base_addr + SPDIF_REG_SIE)); + pr_debug("STC: 0x%08x\n", __raw_readl(spdif_base_addr + SPDIF_REG_STC)); + return 0; +} + +/*! + * This function gets the current playback pointer position. + * It is called by ALSA framework. + * + * @param substream pointer to the structure of the current stream. + * + */ +static snd_pcm_uframes_t +snd_mxc_spdif_playback_pointer(struct snd_pcm_substream *substream) +{ + struct mxc_spdif_device *chip; + chip = snd_pcm_substream_chip(substream); + return spdif_get_dma_pos(&chip->s[SNDRV_PCM_STREAM_PLAYBACK]); +} + +static int snd_card_mxc_spdif_playback_open(struct snd_pcm_substream *substream) +{ + struct mxc_spdif_device *chip; + struct snd_pcm_runtime *runtime; + int err; + struct mxc_spdif_platform_data *spdif_data; + + chip = snd_pcm_substream_chip(substream); + + spdif_data = chip->card->dev->platform_data; + /* enable tx clock */ + clk_enable(spdif_data->spdif_clk); + + runtime = substream->runtime; + chip->s[SNDRV_PCM_STREAM_PLAYBACK].stream = substream; + runtime->hw = snd_spdif_playback_hw; + err = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &hw_playback_rates_stereo); + if (err < 0) + goto failed; + err = + snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); + if (err < 0) + goto failed; + + return 0; + failed: + clk_disable(spdif_data->spdif_clk); + return err; +} + +/*! + * This function closes an spdif device for playback. + * It is called by ALSA framework. + * + * @param substream pointer to the structure of the current stream. + * + * @return 0 on success, -1 otherwise. + */ +static int snd_card_mxc_spdif_playback_close(struct snd_pcm_substream + *substream) +{ + struct mxc_spdif_device *chip; + struct mxc_spdif_platform_data *spdif_data; + + chip = snd_pcm_substream_chip(substream); + spdif_data = chip->card->dev->platform_data; + + pr_debug("SIS: 0x%08x\n", __raw_readl(spdif_base_addr + SPDIF_REG_SIS)); + + spdif_intr_status(); + spdif_intr_enable(INT_TXFIFO_RESYNC, 0); + spdif_tx_uninit(); + clk_disable(spdif_data->spdif_clk); + mxc_dma_free(chip->s[SNDRV_PCM_STREAM_PLAYBACK].dma_wchannel); + chip->s[SNDRV_PCM_STREAM_PLAYBACK].dma_wchannel = 0; + + return 0; +} + +/*! TODO: update the dma start/stop callback routine + * This function stops the current dma transfert for capture + * and clears the dma pointers. + * + * @param s pointer to the structure of the current stream. + * + */ +static void spdif_stop_rx(struct mxc_spdif_stream *s) +{ + struct snd_pcm_substream *substream; + struct snd_pcm_runtime *runtime; + unsigned int dma_size; + unsigned int offset; + + substream = s->stream; + runtime = substream->runtime; + dma_size = frames_to_bytes(runtime, runtime->period_size); + offset = dma_size * s->periods; + + s->active = 0; + s->period = 0; + s->periods = 0; + + /* this stops the dma channel and clears the buffer ptrs */ + mxc_dma_disable(s->dma_wchannel); + spdif_dma_enable(SCR_DMA_RX_EN, 0); + dma_unmap_single(NULL, runtime->dma_addr + offset, dma_size, + DMA_FROM_DEVICE); +} + +/*! + * This function is called whenever a new audio block needs to be + * received from SPDIF. The function receives the address and the size + * of the new block and start a new DMA transfer. + * + * @param s pointer to the structure of the current stream. + * + */ +static void spdif_start_rx(struct mxc_spdif_stream *s) +{ + struct snd_pcm_substream *substream; + struct snd_pcm_runtime *runtime; + unsigned int dma_size = 0; + unsigned int offset; + int ret = 0; + mxc_dma_requestbuf_t dma_request; + + substream = s->stream; + runtime = substream->runtime; + memset(&dma_request, 0, sizeof(mxc_dma_requestbuf_t)); + + if (s->active) { + dma_size = frames_to_bytes(runtime, runtime->period_size); + pr_debug("s->period (%x) runtime->periods (%d)\n", + s->period, runtime->periods); + pr_debug("runtime->period_size (%d) dma_size (%d)\n", + (unsigned int)runtime->period_size, + runtime->dma_bytes); + + offset = dma_size * s->period; + dma_request.dst_addr = + (dma_addr_t) (dma_map_single + (NULL, runtime->dma_area + offset, dma_size, + DMA_FROM_DEVICE)); + + dma_request.src_addr = + (dma_addr_t) (SPDIF_BASE_ADDR + SPDIF_REG_SRL); + dma_request.num_of_bytes = dma_size; + /* config and enable sdma for RX */ + mxc_dma_config(s->dma_wchannel, &dma_request, 1, + MXC_DMA_MODE_READ); + ret = mxc_dma_enable(s->dma_wchannel); + /* enable SPDIF dma */ + spdif_dma_enable(SCR_DMA_RX_EN, 1); + + if (ret) { + pr_info("audio_process_dma: cannot queue DMA \ + buffer\n"); + return; + } + s->period++; + s->period %= runtime->periods; + + if ((s->period > s->periods) + && ((s->period - s->periods) > 1)) { + pr_debug("audio capture chain dma: already double \ + buffered\n"); + return; + } + + if ((s->period < s->periods) + && ((s->period + runtime->periods - s->periods) > 1)) { + pr_debug("audio capture chain dma: already double \ + buffered\n"); + return; + } + + if (s->period == s->periods) { + pr_debug("audio capture chain dma: s->period == \ + s->periods\n"); + return; + } + + if (snd_pcm_capture_hw_avail(runtime) < + 2 * runtime->period_size) { + pr_debug("audio capture chain dma: available data \ + is not enough\n"); + return; + } + + pr_debug + ("audio playback chain dma:to set up the 2nd dma buffer\n"); + + offset = dma_size * s->period; + dma_request.dst_addr = + (dma_addr_t) (dma_map_single + (NULL, runtime->dma_area + offset, dma_size, + DMA_FROM_DEVICE)); + mxc_dma_config(s->dma_wchannel, &dma_request, 1, + MXC_DMA_MODE_READ); + ret = mxc_dma_enable(s->dma_wchannel); + s->period++; + s->period %= runtime->periods; + + } + return; +} + +/*! + * This is a callback which will be called + * when a RX transfer finishes. The call occurs + * in interrupt context. + * + * @param data pointer to the structure of the current stream + * @param error DMA error flag + * @param count number of bytes transfered by the DMA + */ +static void spdif_rx_callback(void *data, int error, unsigned int count) +{ + struct mxc_spdif_stream *s; + struct snd_pcm_substream *substream; + struct snd_pcm_runtime *runtime; + unsigned int dma_size; + unsigned int previous_period; + unsigned int offset; + + s = data; + substream = s->stream; + runtime = substream->runtime; + previous_period = s->periods; + dma_size = frames_to_bytes(runtime, runtime->period_size); + offset = dma_size * previous_period; + + spin_lock(&s->dma_lock); + s->periods++; + s->periods %= runtime->periods; + + dma_unmap_single(NULL, runtime->dma_addr + offset, dma_size, + DMA_FROM_DEVICE); + spin_unlock(&s->dma_lock); + + if (s->active) + snd_pcm_period_elapsed(s->stream); + spin_lock(&s->dma_lock); + spdif_start_rx(s); + spin_unlock(&s->dma_lock); +} + +/*! + * This function is a dispatcher of command to be executed + * by the driver for capture. + * + * @param substream pointer to the structure of the current stream. + * @param cmd command to be executed + * + * @return 0 on success, -1 otherwise. + */ +static int +snd_mxc_spdif_capture_trigger(struct snd_pcm_substream *substream, int cmd) +{ + struct mxc_spdif_device *chip; + struct mxc_spdif_stream *s; + int err = 0; + unsigned long flags; + chip = snd_pcm_substream_chip(substream); + s = &chip->s[SNDRV_PCM_STREAM_CAPTURE]; + + spin_lock_irqsave(&s->dma_lock, flags); + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + s->active = 1; + spdif_start_rx(s); + break; + case SNDRV_PCM_TRIGGER_STOP: + spdif_stop_rx(s); + break; + case SNDRV_PCM_TRIGGER_SUSPEND: + s->active = 0; + s->periods = 0; + break; + case SNDRV_PCM_TRIGGER_RESUME: + s->active = 1; + spdif_start_rx(s); + break; + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + s->active = 0; + break; + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + s->active = 1; + spdif_start_rx(s); + break; + default: + err = -EINVAL; + break; + } + spin_unlock_irqrestore(&s->dma_lock, flags); + return err; +} + +/*! + * This function configures the hardware to allow audio + * capture operations. It is called by ALSA framework. + * + * @param substream pointer to the structure of the current stream. + * + * @return 0 on success, -1 otherwise. + */ +static int snd_mxc_spdif_capture_prepare(struct snd_pcm_substream *substream) +{ + struct mxc_spdif_device *chip; + struct mxc_spdif_platform_data *spdif_data; + struct snd_pcm_runtime *runtime; + int err; + + chip = snd_pcm_substream_chip(substream); + runtime = substream->runtime; + spdif_data = chip->card->dev->platform_data; + + spdif_rx_init(); + /* enable interrupts, include DPLL lock */ + spdif_intr_enable(INT_SYM_ERR | INT_BIT_ERR | INT_URX_FUL | + INT_URX_OV | INT_QRX_FUL | INT_QRX_OV | + INT_UQ_SYNC | INT_UQ_ERR | INT_RX_RESYNC | + INT_LOSS_LOCK, 1); + + /* setup rx clock source */ + spdif_set_rx_clksrc(spdif_data->spdif_clkid, SPDIF_DEFAULT_GAINSEL, 1); + + /* setup DMA controller for spdif rx */ + err = spdif_configure_dma_channel(&chip-> + s[SNDRV_PCM_STREAM_CAPTURE], + spdif_rx_callback); + if (err < 0) { + pr_info("snd_mxc_spdif_playback_prepare - err < 0\n"); + return err; + } + + /* Debug: dump registers */ + pr_debug("SCR: 0x%08x\n", __raw_readl(spdif_base_addr + SPDIF_REG_SCR)); + pr_debug("SIE: 0x%08x\n", __raw_readl(spdif_base_addr + SPDIF_REG_SIE)); + pr_debug("SRPC: 0x%08x\n", + __raw_readl(spdif_base_addr + SPDIF_REG_SRPC)); + pr_debug("FreqMeas: 0x%08x\n", + __raw_readl(spdif_base_addr + SPDIF_REG_SRFM)); + + return 0; +} + +/*! + * This function gets the current capture pointer position. + * It is called by ALSA framework. + * + * @param substream pointer to the structure of the current stream. + * + */ +static snd_pcm_uframes_t +snd_mxc_spdif_capture_pointer(struct snd_pcm_substream *substream) +{ + struct mxc_spdif_device *chip; + chip = snd_pcm_substream_chip(substream); + return spdif_get_dma_pos(&chip->s[SNDRV_PCM_STREAM_CAPTURE]); +} + +/*! + * This function opens a spdif device in capture mode + * It is called by ALSA framework. + * + * @param substream pointer to the structure of the current stream. + * + * @return 0 on success, -1 otherwise. + */ +static int snd_card_mxc_spdif_capture_open(struct snd_pcm_substream *substream) +{ + struct mxc_spdif_device *chip; + struct snd_pcm_runtime *runtime; + int err = 0; + struct mxc_spdif_platform_data *spdif_data; + + chip = snd_pcm_substream_chip(substream); + + spdif_data = chip->card->dev->platform_data; + /* enable rx bus clock */ + clk_enable(spdif_data->spdif_clk); + + runtime = substream->runtime; + chip->s[SNDRV_PCM_STREAM_CAPTURE].stream = substream; + runtime->hw = snd_spdif_capture_hw; + + /* set hw param constraints */ + err = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &hw_capture_rates_stereo); + if (err < 0) + goto failed; + err = + snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); + if (err < 0) + goto failed; + + /* enable spdif dpll lock interrupt */ + spdif_intr_enable(INT_DPLL_LOCKED, 1); + + return 0; + + failed: + clk_disable(spdif_data->spdif_clk); + return err; +} + +/*! + * This function closes an spdif device for capture. + * It is called by ALSA framework. + * + * @param substream pointer to the structure of the current stream. + * + * @return 0 on success, -1 otherwise. + */ +static int snd_card_mxc_spdif_capture_close(struct snd_pcm_substream + *substream) +{ + struct mxc_spdif_device *chip; + struct mxc_spdif_platform_data *spdif_data; + + chip = snd_pcm_substream_chip(substream); + spdif_data = chip->card->dev->platform_data; + + pr_debug("SIS: 0x%08x\n", __raw_readl(spdif_base_addr + SPDIF_REG_SIS)); + pr_debug("SRPC: 0x%08x\n", + __raw_readl(spdif_base_addr + SPDIF_REG_SRPC)); + pr_debug("FreqMeas: 0x%08x\n", + __raw_readl(spdif_base_addr + SPDIF_REG_SRFM)); + + spdif_intr_enable(INT_DPLL_LOCKED | INT_SYM_ERR | INT_BIT_ERR | + INT_URX_FUL | INT_URX_OV | INT_QRX_FUL | INT_QRX_OV | + INT_UQ_SYNC | INT_UQ_ERR | INT_RX_RESYNC | + INT_LOSS_LOCK, 0); + spdif_rx_uninit(); + clk_disable(spdif_data->spdif_clk); + mxc_dma_free(chip->s[SNDRV_PCM_STREAM_CAPTURE].dma_wchannel); + chip->s[SNDRV_PCM_STREAM_CAPTURE].dma_wchannel = 0; + return 0; +} + +/*! + * This function configure the Audio HW in terms of memory allocation. + * It is called by ALSA framework. + * + * @param substream pointer to the structure of the current stream. + * @param hw_params Pointer to hardware paramters structure + * + * @return 0 on success, -1 otherwise. + */ +static int snd_mxc_spdif_hw_params(struct snd_pcm_substream + *substream, struct snd_pcm_hw_params + *hw_params) +{ + struct snd_pcm_runtime *runtime; + int ret = 0; + runtime = substream->runtime; + ret = + snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); + if (ret < 0) { + pr_info("snd_mxc_spdif_hw_params - ret: %d\n", ret); + return ret; + } + runtime->dma_addr = virt_to_phys(runtime->dma_area); + return ret; +} + +/*! + * This function frees the spdif hardware at the end of playback. + * + * @param substream pointer to the structure of the current stream. + * + * @return 0 on success, -1 otherwise. + */ +static int snd_mxc_spdif_hw_free(struct snd_pcm_substream *substream) +{ + return snd_pcm_lib_free_pages(substream); +} + +/*! + * This structure is the list of operation that the driver + * must provide for the playback interface + */ +static struct snd_pcm_ops snd_card_mxc_spdif_playback_ops = { + .open = snd_card_mxc_spdif_playback_open, + .close = snd_card_mxc_spdif_playback_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_mxc_spdif_hw_params, + .hw_free = snd_mxc_spdif_hw_free, + .prepare = snd_mxc_spdif_playback_prepare, + .trigger = snd_mxc_spdif_playback_trigger, + .pointer = snd_mxc_spdif_playback_pointer, +}; + +static struct snd_pcm_ops snd_card_mxc_spdif_capture_ops = { + .open = snd_card_mxc_spdif_capture_open, + .close = snd_card_mxc_spdif_capture_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_mxc_spdif_hw_params, + .hw_free = snd_mxc_spdif_hw_free, + .prepare = snd_mxc_spdif_capture_prepare, + .trigger = snd_mxc_spdif_capture_trigger, + .pointer = snd_mxc_spdif_capture_pointer, +}; + +/*! + * This functions initializes the playback audio device supported by + * spdif + * + * @param mxc_spdif pointer to the sound card structure. + * + */ +void mxc_init_spdif_device(struct mxc_spdif_device *mxc_spdif) +{ + + /* initial spinlock for control data */ + spin_lock_init(&mxc_spdif_control.ctl_lock); + + if (mxc_spdif->mxc_spdif_tx) { + + mxc_spdif->s[SNDRV_PCM_STREAM_PLAYBACK].id = "spdif tx"; + /* init tx channel status default value */ + mxc_spdif_control.ch_status[0] = + IEC958_AES0_CON_NOT_COPYRIGHT | + IEC958_AES0_CON_EMPHASIS_5015; + mxc_spdif_control.ch_status[1] = IEC958_AES1_CON_DIGDIGCONV_ID; + mxc_spdif_control.ch_status[2] = 0x00; + mxc_spdif_control.ch_status[3] = + IEC958_AES3_CON_FS_44100 | IEC958_AES3_CON_CLOCK_1000PPM; + } + if (mxc_spdif->mxc_spdif_rx) { + + /* TODO: Add code here if capture is available */ + mxc_spdif->s[SNDRV_PCM_STREAM_CAPTURE].id = "spdif rx"; + } + +} + +/*! + * MXC SPDIF IEC958 controller(mixer) functions + * + * Channel status get/put control + * User bit value get/put control + * Valid bit value get control + * DPLL lock status get control + * User bit sync mode selection control + * + */ +static int mxc_pb_spdif_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; + uinfo->count = 1; + return 0; +} + +static int mxc_pb_spdif_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *uvalue) +{ + uvalue->value.iec958.status[0] = mxc_spdif_control.ch_status[0]; + uvalue->value.iec958.status[1] = mxc_spdif_control.ch_status[1]; + uvalue->value.iec958.status[2] = mxc_spdif_control.ch_status[2]; + uvalue->value.iec958.status[3] = mxc_spdif_control.ch_status[3]; + return 0; +} + +static int mxc_pb_spdif_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *uvalue) +{ + unsigned int ch_status; + mxc_spdif_control.ch_status[0] = uvalue->value.iec958.status[0]; + mxc_spdif_control.ch_status[1] = uvalue->value.iec958.status[1]; + mxc_spdif_control.ch_status[2] = uvalue->value.iec958.status[2]; + mxc_spdif_control.ch_status[3] = uvalue->value.iec958.status[3]; + ch_status = + ((mxc_spdif_control.ch_status[2] << 16) | (mxc_spdif_control. + ch_status[1] << 8) | + mxc_spdif_control.ch_status[0]); + spdif_set_channel_status(ch_status, SPDIF_REG_STCSCH); + ch_status = mxc_spdif_control.ch_status[3]; + spdif_set_channel_status(ch_status, SPDIF_REG_STCSCL); + return 0; +} + +static int snd_mxc_spdif_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; + uinfo->count = 1; + return 0; +} + +/*! + * Get channel status from SPDIF_RX_CCHAN register + */ +static int snd_mxc_spdif_capture_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned int cstatus; + + if (!(__raw_readl(spdif_base_addr + SPDIF_REG_SIS) & INT_CNEW)) + return -EAGAIN; + + cstatus = __raw_readl(spdif_base_addr + SPDIF_REG_SRCSLH); + ucontrol->value.iec958.status[0] = (cstatus >> 16) & 0xFF; + ucontrol->value.iec958.status[1] = (cstatus >> 8) & 0xFF; + ucontrol->value.iec958.status[2] = cstatus & 0xFF; + cstatus = __raw_readl(spdif_base_addr + SPDIF_REG_SRCSLL); + ucontrol->value.iec958.status[3] = (cstatus >> 16) & 0xFF; + ucontrol->value.iec958.status[4] = (cstatus >> 8) & 0xFF; + ucontrol->value.iec958.status[5] = cstatus & 0xFF; + + /* clear intr */ + __raw_writel(INT_CNEW, spdif_base_addr + SPDIF_REG_SIC); + + return 0; +} + +/*! + * Get User bits (subcode) from chip value which readed out + * in UChannel register. + */ +static int snd_mxc_spdif_subcode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&mxc_spdif_control.ctl_lock, flags); + if (mxc_spdif_control.ready_buf) { + memcpy(&ucontrol->value.iec958.subcode[0], + &mxc_spdif_control. + subcode[(mxc_spdif_control.ready_buf - + 1) * SPDIF_UBITS_SIZE], SPDIF_UBITS_SIZE); + } else { + ret = -EAGAIN; + } + spin_unlock_irqrestore(&mxc_spdif_control.ctl_lock, flags); + + return ret; +} + +/*! + * Q-subcode infomation. + * the byte size is SPDIF_UBITS_SIZE/8 + */ +static int snd_mxc_spdif_qinfo(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = SPDIF_QSUB_SIZE; + return 0; +} + +/*! + * Get Q subcode from chip value which readed out + * in QChannel register. + */ +static int snd_mxc_spdif_qget(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&mxc_spdif_control.ctl_lock, flags); + if (mxc_spdif_control.ready_buf) { + memcpy(&ucontrol->value.bytes.data[0], + &mxc_spdif_control. + qsub[(mxc_spdif_control.ready_buf - + 1) * SPDIF_QSUB_SIZE], SPDIF_QSUB_SIZE); + } else { + ret = -EAGAIN; + } + spin_unlock_irqrestore(&mxc_spdif_control.ctl_lock, flags); + + return ret; +} + +/*! + * Valid bit infomation. + */ +static int snd_mxc_spdif_vbit_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +/*! + * Get valid good bit from interrupt status register. + */ +static int snd_mxc_spdif_vbit_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned int int_val; + + int_val = __raw_readl(spdif_base_addr + SPDIF_REG_SIS); + ucontrol->value.integer.value[0] = (int_val & INT_VAL_NOGOOD) != 0; + __raw_writel(INT_VAL_NOGOOD, spdif_base_addr + SPDIF_REG_SIC); + + return 0; +} + +/*! + * DPLL lock infomation. + */ +static int snd_mxc_spdif_rxrate_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = 16000; + uinfo->value.integer.max = 96000; + return 0; +} + +/*! + * Get DPLL lock or not info from stable interrupt status register. + * User application must use this control to get locked, + * then can do next PCM operation + */ +static int snd_mxc_spdif_rxrate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct mxc_spdif_device *chip = snd_kcontrol_chip(kcontrol); + struct mxc_spdif_platform_data *spdif_data; + + spdif_data = chip->card->dev->platform_data; + + if (atomic_read(&chip->dpll_locked)) { + ucontrol->value.integer.value[0] = + spdif_get_rxclk_rate(spdif_data->spdif_clk, + SPDIF_DEFAULT_GAINSEL); + } else { + ucontrol->value.integer.value[0] = 0; + } + return 0; +} + +/*! + * User bit sync mode info + */ +static int snd_mxc_spdif_usync_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +/*! + * User bit sync mode: + * 1 CD User channel subcode + * 0 Non-CD data + */ +static int snd_mxc_spdif_usync_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned int int_val; + + int_val = __raw_readl(spdif_base_addr + SPDIF_REG_SRCD); + ucontrol->value.integer.value[0] = (int_val & SRCD_CD_USER) != 0; + return 0; +} + +/*! + * User bit sync mode: + * 1 CD User channel subcode + * 0 Non-CD data + */ +static int snd_mxc_spdif_usync_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned int int_val; + + int_val = ucontrol->value.integer.value[0] << SRCD_CD_USER_OFFSET; + __raw_writel(int_val, spdif_base_addr + SPDIF_REG_SRCD); + return 0; +} + +/*! + * MXC SPDIF IEC958 controller defines + */ +static struct snd_kcontrol_new snd_mxc_spdif_ctrls[] = { + /* status cchanel controller */ + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), + .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE | + SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .info = mxc_pb_spdif_info, + .get = mxc_pb_spdif_get, + .put = mxc_pb_spdif_put, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT), + .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .info = snd_mxc_spdif_info, + .get = snd_mxc_spdif_capture_get, + }, + /* user bits controller */ + { + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "IEC958 Subcode Capture Default", + .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .info = snd_mxc_spdif_info, + .get = snd_mxc_spdif_subcode_get, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "IEC958 Q-subcode Capture Default", + .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .info = snd_mxc_spdif_qinfo, + .get = snd_mxc_spdif_qget, + }, + /* valid bit error controller */ + { + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "IEC958 V-Bit Errors", + .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .info = snd_mxc_spdif_vbit_info, + .get = snd_mxc_spdif_vbit_get, + }, + /* DPLL lock info get controller */ + { + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "RX Sample Rate", + .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .info = snd_mxc_spdif_rxrate_info, + .get = snd_mxc_spdif_rxrate_get, + }, + /* User bit sync mode set/get controller */ + { + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "IEC958 USyncMode CDText", + .access = + SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_WRITE | + SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .info = snd_mxc_spdif_usync_info, + .get = snd_mxc_spdif_usync_get, + .put = snd_mxc_spdif_usync_put, + }, +}; + +/*! + * This function the soundcard structure. + * + * @param mxc_spdif pointer to the sound card structure. + * + * @return 0 on success, -1 otherwise. + */ +static int snd_card_mxc_spdif_pcm(struct mxc_spdif_device *mxc_spdif) +{ + struct snd_pcm *pcm; + int err; + err = snd_pcm_new(mxc_spdif->card, MXC_SPDIF_NAME, 0, + mxc_spdif->mxc_spdif_tx, + mxc_spdif->mxc_spdif_rx, &pcm); + if (err < 0) + return err; + + snd_pcm_lib_preallocate_pages_for_all(pcm, + SNDRV_DMA_TYPE_CONTINUOUS, + snd_dma_continuous_data + (GFP_KERNEL), + SPDIF_MAX_BUF_SIZE * 2, + SPDIF_MAX_BUF_SIZE * 2); + if (mxc_spdif->mxc_spdif_tx) + snd_pcm_set_ops(pcm, + SNDRV_PCM_STREAM_PLAYBACK, + &snd_card_mxc_spdif_playback_ops); + if (mxc_spdif->mxc_spdif_rx) + snd_pcm_set_ops(pcm, + SNDRV_PCM_STREAM_CAPTURE, + &snd_card_mxc_spdif_capture_ops); + pcm->private_data = mxc_spdif; + pcm->info_flags = 0; + strncpy(pcm->name, MXC_SPDIF_NAME, sizeof(pcm->name)); + mxc_spdif->pcm = pcm; + mxc_init_spdif_device(mxc_spdif); + return 0; +} + +extern void gpio_spdif_active(void); + +/*! + * This function initializes the driver in terms of memory of the soundcard + * and some basic HW clock settings. + * + * @param pdev Pointer to the platform device + * @return 0 on success, -1 otherwise. + */ +static int mxc_alsa_spdif_probe(struct platform_device + *pdev) +{ + int err, idx; + static int dev; + struct snd_card *card; + struct mxc_spdif_device *chip; + struct resource *res; + struct snd_kcontrol *kctl; + struct mxc_spdif_platform_data *plat_data; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENOENT; + + if (dev >= SNDRV_CARDS) + return -ENODEV; + if (!enable[dev]) { + dev++; + return -ENOENT; + } + + /* register the soundcard */ + card = snd_card_new(index[dev], id[dev], THIS_MODULE, + sizeof(struct mxc_spdif_device)); + if (card == NULL) + return -ENOMEM; + chip = card->private_data; + chip->card = card; + card->dev = &pdev->dev; + chip->reg_base = ioremap(res->start, res->end - res->start + 1); + spdif_base_addr = (unsigned long)chip->reg_base; + plat_data = (struct mxc_spdif_platform_data *)pdev->dev.platform_data; + chip->mxc_spdif_tx = plat_data->spdif_tx; + chip->mxc_spdif_rx = plat_data->spdif_rx; + chip->spdif_txclk_44100 = plat_data->spdif_clk_44100; + chip->spdif_txclk_48000 = plat_data->spdif_clk_48000; + atomic_set(&chip->dpll_locked, 0); + + err = snd_card_mxc_spdif_pcm(chip); + if (err < 0) + goto nodev; + + /*! + * Add controls to the card + */ + for (idx = 0; idx < ARRAY_SIZE(snd_mxc_spdif_ctrls); idx++) { + + kctl = snd_ctl_new1(&snd_mxc_spdif_ctrls[idx], chip); + if (kctl == NULL) { + err = -ENOMEM; + goto nodev; + } + /* check to add control to corresponding substream */ + if (strstr(kctl->id.name, "Playback")) + kctl->id.device = 0; + else + kctl->id.device = 1; + + err = snd_ctl_add(card, kctl); + if (err < 0) + goto nodev; + } + + clk_enable(plat_data->spdif_core_clk); + /*! + * SPDIF interrupt initialization + * software reset to SPDIF + */ + spdif_softreset(); + /* disable all the interrupts */ + spdif_intr_enable(0xffffff, 0); + /* spdif interrupt register and disable */ + if (request_irq(MXC_INT_SPDIF, spdif_isr, 0, "spdif", chip)) { + pr_err("MXC spdif: failed to request irq\n"); + err = -EBUSY; + goto nodev; + } + + if (chip->mxc_spdif_tx) + spin_lock_init(&chip->s[SNDRV_PCM_STREAM_PLAYBACK].dma_lock); + if (chip->mxc_spdif_rx) + spin_lock_init(&chip->s[SNDRV_PCM_STREAM_CAPTURE].dma_lock); + strcpy(card->driver, MXC_SPDIF_NAME); + strcpy(card->shortname, "MXC SPDIF TX/RX"); + sprintf(card->longname, "MXC Freescale with SPDIF"); + + err = snd_card_register(card); + if (err == 0) { + pr_info("MXC spdif support initialized\n"); + platform_set_drvdata(pdev, card); + gpio_spdif_active(); + return 0; + } + + nodev: + snd_card_free(card); + return err; +} + +extern void gpio_spdif_inactive(void); + +/*! + * This function releases the sound card and unmap the io address + * + * @param pdev Pointer to the platform device + * @return 0 on success, -1 otherwise. + */ + +static int mxc_alsa_spdif_remove(struct platform_device *pdev) +{ + struct mxc_spdif_device *chip; + struct snd_card *card; + struct mxc_spdif_platform_data *plat_data; + + card = platform_get_drvdata(pdev); + plat_data = pdev->dev.platform_data; + chip = card->private_data; + free_irq(MXC_INT_SPDIF, chip); + iounmap(chip->reg_base); + + snd_card_free(card); + platform_set_drvdata(pdev, NULL); + + clk_disable(plat_data->spdif_core_clk); + gpio_spdif_inactive(); + + return 0; +} + +#ifdef CONFIG_PM +/*! + * This function suspends all active streams. + * + * TBD + * + * @param card pointer to the sound card structure. + * @param state requested state + * + * @return 0 on success, -1 otherwise. + */ +static int mxc_alsa_spdif_suspend(struct platform_device *pdev, + pm_message_t state) +{ + return 0; +} + +/*! + * This function resumes all suspended streams. + * + * TBD + * + * @param card pointer to the sound card structure. + * @param state requested state + * + * @return 0 on success, -1 otherwise. + */ +static int mxc_alsa_spdif_resume(struct platform_device *pdev) +{ + return 0; +} +#endif + +static struct platform_driver mxc_alsa_spdif_driver = { + .probe = mxc_alsa_spdif_probe, + .remove = mxc_alsa_spdif_remove, +#ifdef CONFIG_PM + .suspend = mxc_alsa_spdif_suspend, + .resume = mxc_alsa_spdif_resume, +#endif + .driver = { + .name = "mxc_alsa_spdif", + }, +}; + +/*! + * This function registers the sound driver structure. + * + */ +static int __init mxc_alsa_spdif_init(void) +{ + return platform_driver_register(&mxc_alsa_spdif_driver); +} + +/*! + * This function frees the sound driver structure. + * + */ +static void __exit mxc_alsa_spdif_exit(void) +{ + platform_driver_unregister(&mxc_alsa_spdif_driver); +} + +module_init(mxc_alsa_spdif_init); +module_exit(mxc_alsa_spdif_exit); +MODULE_AUTHOR("FREESCALE SEMICONDUCTOR"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MXC ALSA driver for SPDIF"); --- linux-2.6.28.orig/sound/arm/Kconfig +++ linux-2.6.28/sound/arm/Kconfig @@ -50,5 +50,19 @@ Say Y or M if you want to support any AC97 codec attached to the PXA2xx AC97 interface. +config SND_MXC_SPDIF + tristate "MXC SPDIF sound card spport" + select SND_PCM + help + Say Y here to enable SPDIF sound card + +config SND_MXC_PMIC_IRAM + bool "MXC PMIC sound system supports IRAM" + depends on SND_MXC_PMIC && SDMA_IRAM + default n + select SND_PCM + help + It will use IRAM as the DMA buffer of ALSA playback. + endif # SND_ARM --- linux-2.6.28.orig/sound/arm/Makefile +++ linux-2.6.28/sound/arm/Makefile @@ -17,3 +17,10 @@ obj-$(CONFIG_SND_PXA2XX_AC97) += snd-pxa2xx-ac97.o snd-pxa2xx-ac97-objs := pxa2xx-ac97.o + +# +# Define the header file locations for PMIC drivers. +# +CFLAGS_mxc_alsa_spdif.o = -I$(TOPDIR)/drivers/mxc +obj-$(CONFIG_SND_MXC_SPDIF) += snd-spdif.o +snd-spdif-objs := mxc-alsa-spdif.o --- linux-2.6.28.orig/sound/core/pcm_lib.c +++ linux-2.6.28/sound/core/pcm_lib.c @@ -125,19 +125,27 @@ } } +#ifdef CONFIG_SND_PCM_XRUN_DEBUG +#define xrun_debug(substream) ((substream)->pstr->xrun_debug) +#else +#define xrun_debug(substream) 0 +#endif + +#define dump_stack_on_xrun(substream) do { \ + if (xrun_debug(substream) > 1) \ + dump_stack(); \ + } while (0) + static void xrun(struct snd_pcm_substream *substream) { snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); -#ifdef CONFIG_SND_PCM_XRUN_DEBUG - if (substream->pstr->xrun_debug) { + if (xrun_debug(substream)) { snd_printd(KERN_DEBUG "XRUN: pcmC%dD%d%c\n", substream->pcm->card->number, substream->pcm->device, substream->stream ? 'c' : 'p'); - if (substream->pstr->xrun_debug > 1) - dump_stack(); + dump_stack_on_xrun(substream); } -#endif } static inline snd_pcm_uframes_t snd_pcm_update_hw_ptr_pos(struct snd_pcm_substream *substream, @@ -150,11 +158,15 @@ pos = substream->ops->pointer(substream); if (pos == SNDRV_PCM_POS_XRUN) return pos; /* XRUN */ -#ifdef CONFIG_SND_DEBUG if (pos >= runtime->buffer_size) { - snd_printk(KERN_ERR "BUG: stream = %i, pos = 0x%lx, buffer size = 0x%lx, period size = 0x%lx\n", substream->stream, pos, runtime->buffer_size, runtime->period_size); + if (printk_ratelimit()) { + snd_printd(KERN_ERR "BUG: stream = %i, pos = 0x%lx, " + "buffer size = 0x%lx, period size = 0x%lx\n", + substream->stream, pos, runtime->buffer_size, + runtime->period_size); + } + pos = 0; } -#endif pos -= pos % runtime->min_align; return pos; } @@ -182,11 +194,21 @@ return 0; } +#define hw_ptr_error(substream, fmt, args...) \ + do { \ + if (xrun_debug(substream)) { \ + if (printk_ratelimit()) { \ + snd_printd("PCM: " fmt, ##args); \ + } \ + dump_stack_on_xrun(substream); \ + } \ + } while (0) + static inline int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; snd_pcm_uframes_t pos; - snd_pcm_uframes_t new_hw_ptr, hw_ptr_interrupt; + snd_pcm_uframes_t new_hw_ptr, hw_ptr_interrupt, hw_base; snd_pcm_sframes_t delta; pos = snd_pcm_update_hw_ptr_pos(substream, runtime); @@ -194,36 +216,52 @@ xrun(substream); return -EPIPE; } - if (runtime->period_size == runtime->buffer_size) - goto __next_buf; - new_hw_ptr = runtime->hw_ptr_base + pos; + hw_base = runtime->hw_ptr_base; + new_hw_ptr = hw_base + pos; hw_ptr_interrupt = runtime->hw_ptr_interrupt + runtime->period_size; - - delta = hw_ptr_interrupt - new_hw_ptr; - if (delta > 0) { - if ((snd_pcm_uframes_t)delta < runtime->buffer_size / 2) { -#ifdef CONFIG_SND_PCM_XRUN_DEBUG - if (runtime->periods > 1 && substream->pstr->xrun_debug) { - snd_printd(KERN_ERR "Unexpected hw_pointer value [1] (stream = %i, delta: -%ld, max jitter = %ld): wrong interrupt acknowledge?\n", substream->stream, (long) delta, runtime->buffer_size / 2); - if (substream->pstr->xrun_debug > 1) - dump_stack(); - } -#endif - return 0; - } - __next_buf: - runtime->hw_ptr_base += runtime->buffer_size; - if (runtime->hw_ptr_base == runtime->boundary) - runtime->hw_ptr_base = 0; - new_hw_ptr = runtime->hw_ptr_base + pos; + delta = new_hw_ptr - hw_ptr_interrupt; + if (hw_ptr_interrupt == runtime->boundary) { + hw_ptr_interrupt %= runtime->boundary; + if (!hw_base) /* hw_base was already lapped; recalc delta */ + delta = new_hw_ptr - hw_ptr_interrupt; + } + if (delta < 0) { + delta += runtime->buffer_size; + if (delta < 0) { + hw_ptr_error(substream, + "Unexpected hw_pointer value " + "(stream=%i, pos=%ld, intr_ptr=%ld)\n", + substream->stream, (long)pos, + (long)hw_ptr_interrupt); + /* rebase to interrupt position */ + hw_base = new_hw_ptr = hw_ptr_interrupt; + /* align hw_base to buffer_size */ + hw_base -= hw_base % runtime->buffer_size; + delta = 0; + } else { + hw_base += runtime->buffer_size; + if (hw_base == runtime->boundary) + hw_base = 0; + new_hw_ptr = hw_base + pos; + } + } + if (delta > runtime->period_size) { + hw_ptr_error(substream, + "Lost interrupts? " + "(stream=%i, delta=%ld, intr_ptr=%ld)\n", + substream->stream, (long)delta, + (long)hw_ptr_interrupt); + /* rebase hw_ptr_interrupt */ + hw_ptr_interrupt = + new_hw_ptr - new_hw_ptr % runtime->period_size; } - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && runtime->silence_size > 0) snd_pcm_playback_silence(substream, new_hw_ptr); + runtime->hw_ptr_base = hw_base; runtime->status->hw_ptr = new_hw_ptr; - runtime->hw_ptr_interrupt = new_hw_ptr - new_hw_ptr % runtime->period_size; + runtime->hw_ptr_interrupt = hw_ptr_interrupt; return snd_pcm_update_hw_ptr_post(substream, runtime); } @@ -233,7 +271,7 @@ { struct snd_pcm_runtime *runtime = substream->runtime; snd_pcm_uframes_t pos; - snd_pcm_uframes_t old_hw_ptr, new_hw_ptr; + snd_pcm_uframes_t old_hw_ptr, new_hw_ptr, hw_base; snd_pcm_sframes_t delta; old_hw_ptr = runtime->status->hw_ptr; @@ -242,29 +280,38 @@ xrun(substream); return -EPIPE; } - new_hw_ptr = runtime->hw_ptr_base + pos; + hw_base = runtime->hw_ptr_base; + new_hw_ptr = hw_base + pos; - delta = old_hw_ptr - new_hw_ptr; - if (delta > 0) { - if ((snd_pcm_uframes_t)delta < runtime->buffer_size / 2) { -#ifdef CONFIG_SND_PCM_XRUN_DEBUG - if (runtime->periods > 2 && substream->pstr->xrun_debug) { - snd_printd(KERN_ERR "Unexpected hw_pointer value [2] (stream = %i, delta: -%ld, max jitter = %ld): wrong interrupt acknowledge?\n", substream->stream, (long) delta, runtime->buffer_size / 2); - if (substream->pstr->xrun_debug > 1) - dump_stack(); - } -#endif + delta = new_hw_ptr - old_hw_ptr; + if (delta < 0) { + delta += runtime->buffer_size; + if (delta < 0) { + hw_ptr_error(substream, + "Unexpected hw_pointer value [2] " + "(stream=%i, pos=%ld, old_ptr=%ld)\n", + substream->stream, (long)pos, + (long)old_hw_ptr); return 0; } - runtime->hw_ptr_base += runtime->buffer_size; - if (runtime->hw_ptr_base == runtime->boundary) - runtime->hw_ptr_base = 0; - new_hw_ptr = runtime->hw_ptr_base + pos; + hw_base += runtime->buffer_size; + if (hw_base == runtime->boundary) + hw_base = 0; + new_hw_ptr = hw_base + pos; + } + if (delta > runtime->period_size && runtime->periods > 1) { + hw_ptr_error(substream, + "hw_ptr skipping! " + "(pos=%ld, delta=%ld, period=%ld)\n", + (long)pos, (long)delta, + (long)runtime->period_size); + return 0; } if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && runtime->silence_size > 0) snd_pcm_playback_silence(substream, new_hw_ptr); + runtime->hw_ptr_base = hw_base; runtime->status->hw_ptr = new_hw_ptr; return snd_pcm_update_hw_ptr_post(substream, runtime); --- linux-2.6.28.orig/sound/core/sgbuf.c +++ linux-2.6.28/sound/core/sgbuf.c @@ -38,6 +38,10 @@ if (! sgbuf) return -EINVAL; + if (dmab->area) + vunmap(dmab->area); + dmab->area = NULL; + tmpb.dev.type = SNDRV_DMA_TYPE_DEV; tmpb.dev.dev = sgbuf->dev; for (i = 0; i < sgbuf->pages; i++) { @@ -48,9 +52,6 @@ tmpb.bytes = (sgbuf->table[i].addr & ~PAGE_MASK) << PAGE_SHIFT; snd_dma_free_pages(&tmpb); } - if (dmab->area) - vunmap(dmab->area); - dmab->area = NULL; kfree(sgbuf->table); kfree(sgbuf->page_table); --- linux-2.6.28.orig/sound/core/oss/rate.c +++ linux-2.6.28/sound/core/oss/rate.c @@ -157,7 +157,7 @@ while (dst_frames1 > 0) { S1 = S2; if (src_frames1-- > 0) { - S1 = *src; + S2 = *src; src += src_step; } if (pos & ~R_MASK) { --- linux-2.6.28.orig/sound/core/oss/pcm_oss.c +++ linux-2.6.28/sound/core/oss/pcm_oss.c @@ -2872,7 +2872,7 @@ setup = kmalloc(sizeof(*setup), GFP_KERNEL); if (! setup) { buffer->error = -ENOMEM; - mutex_lock(&pstr->oss.setup_mutex); + mutex_unlock(&pstr->oss.setup_mutex); return; } if (pstr->oss.setup_list == NULL) @@ -2886,7 +2886,7 @@ if (! template.task_name) { kfree(setup); buffer->error = -ENOMEM; - mutex_lock(&pstr->oss.setup_mutex); + mutex_unlock(&pstr->oss.setup_mutex); return; } } --- linux-2.6.28.orig/sound/usb/usbaudio.c +++ linux-2.6.28/sound/usb/usbaudio.c @@ -2524,7 +2524,6 @@ * build the rate table and bitmap flags */ int r, idx; - unsigned int nonzero_rates = 0; fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL); if (fp->rate_table == NULL) { @@ -2532,24 +2531,27 @@ return -1; } - fp->nr_rates = nr_rates; - fp->rate_min = fp->rate_max = combine_triple(&fmt[8]); + fp->nr_rates = 0; + fp->rate_min = fp->rate_max = 0; for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) { unsigned int rate = combine_triple(&fmt[idx]); + if (!rate) + continue; /* C-Media CM6501 mislabels its 96 kHz altsetting */ if (rate == 48000 && nr_rates == 1 && - chip->usb_id == USB_ID(0x0d8c, 0x0201) && + (chip->usb_id == USB_ID(0x0d8c, 0x0201) || + chip->usb_id == USB_ID(0x0d8c, 0x0102)) && fp->altsetting == 5 && fp->maxpacksize == 392) rate = 96000; - fp->rate_table[r] = rate; - nonzero_rates |= rate; - if (rate < fp->rate_min) + fp->rate_table[fp->nr_rates] = rate; + if (!fp->rate_min || rate < fp->rate_min) fp->rate_min = rate; - else if (rate > fp->rate_max) + if (!fp->rate_max || rate > fp->rate_max) fp->rate_max = rate; fp->rates |= snd_pcm_rate_to_rate_bit(rate); + fp->nr_rates++; } - if (!nonzero_rates) { + if (!fp->nr_rates) { hwc_debug("All rates were zero. Skipping format!\n"); return -1; } @@ -2966,6 +2968,7 @@ return -EINVAL; } alts = &iface->altsetting[fp->altset_idx]; + fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); usb_set_interface(chip->dev, fp->iface, 0); init_usb_pitch(chip->dev, fp->iface, alts, fp); init_usb_sample_rate(chip->dev, fp->iface, alts, fp, fp->rate_max); --- linux-2.6.28.orig/sound/usb/usbmidi.c +++ linux-2.6.28/sound/usb/usbmidi.c @@ -1628,6 +1628,7 @@ } ep_info.out_ep = get_endpoint(hostif, 2)->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + ep_info.out_interval = 0; ep_info.out_cables = endpoint->out_cables & 0x5555; err = snd_usbmidi_out_endpoint_create(umidi, &ep_info, &umidi->endpoints[0]); if (err < 0) --- linux-2.6.28.orig/sound/usb/usbquirks.h +++ linux-2.6.28/sound/usb/usbquirks.h @@ -128,6 +128,14 @@ .bInterfaceClass = USB_CLASS_AUDIO, .bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL }, +{ + USB_DEVICE(0x046d, 0x0990), + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + .vendor_name = "Logitech, Inc.", + .product_name = "QuickCam Pro 9000", + .ifnum = QUIRK_NO_INTERFACE + } +}, /* * Yamaha devices --- linux-2.6.28.orig/sound/usb/caiaq/caiaq-device.h +++ linux-2.6.28/sound/usb/caiaq/caiaq-device.h @@ -75,6 +75,7 @@ wait_queue_head_t ep1_wait_queue; wait_queue_head_t prepare_wait_queue; int spec_received, audio_parm_answer; + int midi_out_active; char vendor_name[CAIAQ_USB_STR_LEN]; char product_name[CAIAQ_USB_STR_LEN]; --- linux-2.6.28.orig/sound/usb/caiaq/caiaq-midi.c +++ linux-2.6.28/sound/usb/caiaq/caiaq-midi.c @@ -59,6 +59,11 @@ static int snd_usb_caiaq_midi_output_close(struct snd_rawmidi_substream *substream) { + struct snd_usb_caiaqdev *dev = substream->rmidi->private_data; + if (dev->midi_out_active) { + usb_kill_urb(&dev->midi_out_urb); + dev->midi_out_active = 0; + } return 0; } @@ -69,7 +74,8 @@ dev->midi_out_buf[0] = EP1_CMD_MIDI_WRITE; dev->midi_out_buf[1] = 0; /* port */ - len = snd_rawmidi_transmit_peek(substream, dev->midi_out_buf+3, EP1_BUFSIZE-3); + len = snd_rawmidi_transmit(substream, dev->midi_out_buf + 3, + EP1_BUFSIZE - 3); if (len <= 0) return; @@ -79,24 +85,24 @@ ret = usb_submit_urb(&dev->midi_out_urb, GFP_ATOMIC); if (ret < 0) - log("snd_usb_caiaq_midi_send(%p): usb_submit_urb() failed, %d\n", - substream, ret); + log("snd_usb_caiaq_midi_send(%p): usb_submit_urb() failed," + "ret=%d, len=%d\n", + substream, ret, len); + else + dev->midi_out_active = 1; } static void snd_usb_caiaq_midi_output_trigger(struct snd_rawmidi_substream *substream, int up) { struct snd_usb_caiaqdev *dev = substream->rmidi->private_data; - if (dev->midi_out_substream != NULL) - return; - - if (!up) { + if (up) { + dev->midi_out_substream = substream; + if (!dev->midi_out_active) + snd_usb_caiaq_midi_send(dev, substream); + } else { dev->midi_out_substream = NULL; - return; } - - dev->midi_out_substream = substream; - snd_usb_caiaq_midi_send(dev, substream); } @@ -161,16 +167,14 @@ void snd_usb_caiaq_midi_output_done(struct urb* urb) { struct snd_usb_caiaqdev *dev = urb->context; - char *buf = urb->transfer_buffer; + dev->midi_out_active = 0; if (urb->status != 0) return; if (!dev->midi_out_substream) return; - snd_rawmidi_transmit_ack(dev->midi_out_substream, buf[2]); - dev->midi_out_substream = NULL; snd_usb_caiaq_midi_send(dev, dev->midi_out_substream); } --- linux-2.6.28.orig/sound/drivers/mtpav.c +++ linux-2.6.28/sound/drivers/mtpav.c @@ -706,7 +706,6 @@ mtp_card->card = card; mtp_card->irq = -1; mtp_card->share_irq = 0; - mtp_card->inmidiport = 0xffffffff; mtp_card->inmidistate = 0; mtp_card->outmidihwport = 0xffffffff; init_timer(&mtp_card->timer); @@ -719,6 +718,8 @@ if (err < 0) goto __error; + mtp_card->inmidiport = mtp_card->num_ports + MTPAV_PIDX_BROADCAST; + err = snd_mtpav_get_ISA(mtp_card); if (err < 0) goto __error; --- linux-2.6.28.orig/debian/control +++ linux-2.6.28/debian/control @@ -0,0 +1,474 @@ +Source: linux +Section: devel +Priority: optional +Maintainer: Ubuntu Kernel Team +Standards-Version: 3.6.1 +Build-Depends: debhelper (>= 3), module-init-tools, kernel-wedge (>= 2.24ubuntu1), makedumpfile [!armel] +Build-Depends-Indep: xmlto, docbook-utils, gs, transfig, bzip2, sharutils +Vcs-Git: http://kernel.ubuntu.com/git-repos/ubuntu/ubuntu-jaunty.git + +Package: linux-source-2.6.28 +Architecture: all +Section: devel +Priority: optional +Provides: linux-source, linux-source-2.6 +Depends: binutils, bzip2, coreutils | fileutils (>= 4.0) +Recommends: libc-dev, gcc, make +Suggests: libncurses-dev | ncurses-dev, kernel-package, libqt3-dev +Description: Linux kernel source for version 2.6.28 with Ubuntu patches + This package provides the source code for the Linux kernel version + 2.6.28. + . + This package is mainly meant for other packages to use, in order to build + custom flavours. + . + If you wish to use this package to create a custom Linux kernel, then it + is suggested that you investigate the package kernel-package, which has + been designed to ease the task of creating kernel image packages. + . + If you are simply trying to build third-party modules for your kernel, + you do not want this package. Install the appropriate linux-headers + package instead. + +Package: linux-doc-2.6.28 +Architecture: all +Section: doc +Priority: optional +Provides: linux-doc-2.6 +Conflicts: linux-doc-2.6 +Replaces: linux-doc-2.6 +Depends: coreutils | fileutils (>= 4.0) +Description: Linux kernel specific documentation for version 2.6.28 + This package provides the various readme's in the 2.6.28 kernel + Documentation/ subdirectory: these typically contain kernel-specific + installation notes for some drivers for example. See + /usr/share/doc/linux-doc-2.6.28/Documentation/00-INDEX for a list of what + is contained in each file. Please read the Changes file, as it contains + information about the problems, which may result by upgrading your + kernel. + +Package: linux-headers-2.6.28-11 +Architecture: all +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0) +Provides: linux-headers, linux-headers-2.6 +Description: Header files related to Linux kernel version 2.6.28 + This package provides kernel header files for version 2.6.28, for sites + that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-11/debian.README.gz for details + +Package: linux-libc-dev +Architecture: i386 amd64 armel lpia +Conflicts: libc6-dev (<< 2.3.2.ds1-6), libc6.1-dev (<< 2.3.2.ds1-6), dvb-dev (<< 1.0.1-6), amd64-libs-dev (<= 1.1), linux-kernel-headers +Replaces: libc6-dev (<< 2.3.2.ds1-6), libc6.1-dev (<< 2.3.2.ds1-6), dvb-dev (<< 1.0.1-6), linux-kernel-headers, libdrm-dev +Provides: linux-kernel-headers +Description: Linux Kernel Headers for development + This package provides headers from the Linux kernel. These headers + are used by the installed headers for GNU glibc and other system + libraries. They are NOT meant to be used to build third-party modules for + your kernel. Use linux-headers-* packages for that. + +Package: linux-image-2.6.28-11-generic +Architecture: i386 amd64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, redhat-cluster-modules, ivtv-modules, ndiswrapper-modules-1.9 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3), wireless-crda +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: grub | lilo (>= 19.1) +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on x86/x86_64 + This package contains the Linux kernel image for version 2.6.28 on + x86/x86_64. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Generic processors. + . + Geared toward desktop systems. + . + You likely do not want to install this package directly. Instead, install + the linux-generic meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.28-11-generic +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-11, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on x86/x86_64 + This package provides kernel header files for version 2.6.28 on + x86/x86_64. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-11/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-11-generic +Architecture: i386 amd64 +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on x86/x86_64 + This package provides a kernel debug image for version 2.6.28 on + x86/x86_64. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-11-imx51 +Architecture: armel +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3), wireless-crda +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: flash-kernel +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on I.MX51-based systems + This package contains the Linux kernel image for version 2.6.28 on + I.MX51-based systems. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports I.MX51 processors. + . + Babbage and 3-stack boards + . + You likely do not want to install this package directly. Instead, install + the linux-imx51 meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.28-11-imx51 +Architecture: armel +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-11, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on I.MX51-based systems + This package provides kernel header files for version 2.6.28 on + I.MX51-based systems. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-11/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-11-imx51 +Architecture: armel +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on I.MX51-based systems + This package provides a kernel debug image for version 2.6.28 on + I.MX51-based systems. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-11-iop32x +Architecture: armel +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3), wireless-crda +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: flash-kernel +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on IOP32x-based systems + This package contains the Linux kernel image for version 2.6.28 on + IOP32x-based systems. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports IOP32x processors. + . + Thecus N2100, etc. + . + You likely do not want to install this package directly. Instead, install + the linux-iop32x meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.28-11-iop32x +Architecture: armel +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-11, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on IOP32x-based systems + This package provides kernel header files for version 2.6.28 on + IOP32x-based systems. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-11/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-11-iop32x +Architecture: armel +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on IOP32x-based systems + This package provides a kernel debug image for version 2.6.28 on + IOP32x-based systems. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-11-ixp4xx +Architecture: armel +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3), wireless-crda +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: flash-kernel +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on IXP4xx-based systems + This package contains the Linux kernel image for version 2.6.28 on + IXP4xx-based systems. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports IXP4xx processors. + . + Linksys NSLU2, etc. + . + You likely do not want to install this package directly. Instead, install + the linux-ixp4xx meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.28-11-ixp4xx +Architecture: armel +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-11, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on IXP4xx-based systems + This package provides kernel header files for version 2.6.28 on + IXP4xx-based systems. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-11/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-11-ixp4xx +Architecture: armel +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on IXP4xx-based systems + This package provides a kernel debug image for version 2.6.28 on + IXP4xx-based systems. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-11-lpia +Architecture: lpia +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, redhat-cluster-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3), wireless-crda +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on Intel Atom processors + This package contains the Linux kernel image for version 2.6.28 on + Intel Atom processors. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Intel Atom processors. + . + Geared toward LPIA-based mobile devices + . + You likely do not want to install this package directly. Instead, install + the linux-lpia meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.28-11-lpia +Architecture: lpia +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-11, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on Intel Atom processors + This package provides kernel header files for version 2.6.28 on + Intel Atom processors. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-11/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-11-lpia +Architecture: lpia +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on Intel Atom processors + This package provides a kernel debug image for version 2.6.28 on + Intel Atom processors. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-11-server +Architecture: i386 amd64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules, kvm-api-4, ivtv-modules, ndiswrapper-modules-1.9 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3), wireless-crda +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: grub | lilo (>= 19.1) +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on x86/x86_64 + This package contains the Linux kernel image for version 2.6.28 on + x86/x86_64. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Server processors. + . + Geared toward server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-server meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.28-11-server +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-11, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on x86/x86_64 + This package provides kernel header files for version 2.6.28 on + x86/x86_64. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-11/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-11-server +Architecture: i386 amd64 +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on x86/x86_64 + This package provides a kernel debug image for version 2.6.28 on + x86/x86_64. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-11-versatile +Architecture: armel +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3), wireless-crda +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on Versatile-based systems + This package contains the Linux kernel image for version 2.6.28 on + Versatile-based systems. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Versatile processors. + . + PB, AB, Qemu, etc. + . + You likely do not want to install this package directly. Instead, install + the linux-versatile meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.28-11-versatile +Architecture: armel +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-11, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on Versatile-based systems + This package provides kernel header files for version 2.6.28 on + Versatile-based systems. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-11/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-11-versatile +Architecture: armel +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on Versatile-based systems + This package provides a kernel debug image for version 2.6.28 on + Versatile-based systems. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-11-virtual +Architecture: i386 amd64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1), linux-image-2.6.28-11-server +Recommends: grub | lilo (>= 19.1) +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on x86/x86_64 + This package contains the Linux kernel image for version 2.6.28 on + x86/x86_64. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Virtual processors. + . + Geared toward virtual machine guests. + . + You likely do not want to install this package directly. Instead, install + the linux-virtual meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. --- linux-2.6.28.orig/debian/copyright +++ linux-2.6.28/debian/copyright @@ -0,0 +1,30 @@ +This is the Ubuntu prepackaged version of the Linux kernel. +Linux was written by Linus Torvalds +and others. + +This package was put together by the Ubuntu Kernel Team, from +sources retrieved from upstream linux git. +The sources may be found at most Linux ftp sites, including +ftp://ftp.kernel.org/pub/linux/kernel/ + +This package is currently maintained by the +Ubuntu Kernel Team + +Linux is copyrighted by Linus Torvalds and others. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 dated June, 1991. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You 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. + +On Ubuntu Linux systems, the complete text of the GNU General +Public License v2 can be found in `/usr/share/common-licenses/GPL-2'. --- linux-2.6.28.orig/debian/rules +++ linux-2.6.28/debian/rules @@ -0,0 +1,147 @@ +#!/usr/bin/make -f +# +# debian/rules for Ubuntu linux +# +# Use this however you want, just give credit where credit is due. +# +# Copyright (c) 2007 Ben Collins +# + +# dpkg-buildpackage passes options that are incomptatible +# with the kernel build. +unexport CFLAGS +unexport LDFLAGS + +# This is the debhelper compatability version to use. +export DH_COMPAT=4 +export LC_ALL=C +export SHELL=/bin/bash -e + +# Common variables for all architectures +include debian/rules.d/0-common-vars.mk + +# Pill in some arch specific stuff +include debian/rules.d/$(arch).mk + +# Maintainer targets +include debian/rules.d/1-maintainer.mk + +# Debian Build System targets +binary: binary-indep binary-arch + +build: build-arch build-indep + +clean: debian/control + dh_testdir + dh_testroot + dh_clean + + # d-i stuff + rm -rf modules kernel-versions package-list + rm -rf debian/d-i-$(arch) + + # normal build junk + rm -rf debian/abi/$(release)-$(revision) + rm -rf $(builddir) + rm -f $(stampdir)/stamp-* + rm -rf debian/linux-* + + # This gets rid of the d-i packages in control + cp -f debian/control.stub debian/control + +# Builds the image, arch headers and debug packages +include debian/rules.d/2-binary-arch.mk + +# Rules for building the udebs (debian-installer) +include debian/rules.d/5-udebs.mk + +# Builds the source, doc and linux-headers indep packages +include debian/rules.d/3-binary-indep.mk + +# Various checks to be performed on builds +include debian/rules.d/4-checks.mk + +# Misc stuff +debian/control.stub: debian/d-i/kernel-versions.in \ + debian/scripts/control-create \ + debian/control.stub.in \ + debian/changelog \ + $(wildcard debian/control.d/* debian/sub-flavours/*.vars) + for i in debian/d-i/kernel-versions.in debian/control.stub.in; do \ + new=`echo $$i | sed 's/\.in$$//'`; \ + cat $$i | sed -e 's/PKGVER/$(release)/g' -e 's/ABINUM/$(abinum)/g' > \ + $$new; \ + done + flavours="$(wildcard debian/control.d/vars.* debian/sub-flavours/*.vars)";\ + for i in $$flavours; do \ + $(SHELL) debian/scripts/control-create $$i | \ + sed -e 's/PKGVER/$(release)/g' -e 's/ABINUM/$(abinum)/g' >> \ + debian/control.stub; \ + done + cp debian/control.stub debian/control + +.PHONY: debian/control +debian/control: debian/control.stub + rm -rf modules kernel-versions package-list + mkdir -p modules/$(arch)/ + cp debian/d-i/modules/* modules/$(arch)/ + cp debian/d-i/package-list debian/d-i/kernel-versions . + touch modules/$(arch)/kernel-image + + # Some files may need to differ between architectures + if [ -d debian/d-i/modules-$(arch) ]; then \ + cp debian/d-i/modules-$(arch)/* modules/$(arch)/; \ + fi + + # Remove unwanted stuff for this architecture + if [ -r "debian/d-i/exclude-modules.$(arch)" ]; then \ + (cat debian/d-i/exclude-modules.$(arch); \ + ls modules/$(arch)/) | sort | uniq -d | \ + (cd modules/$(arch)/; xargs rm -f); \ + fi + + # Per flavour module lists + flavour_modules=`ls debian/d-i/modules.$(arch)-* 2>/dev/null` \ + || true; \ + if [ "$$flavour_modules" != "" ]; then \ + for flav in $$flavour_modules; do \ + name=`echo $$flav | sed 's/.*\/modules.$(arch)-//'`; \ + mkdir modules/$(arch)-$$name; \ + (cd modules/; tar cf - `cat ../$$flav`) | \ + (cd modules/$(arch)-$$name/; tar xf -); \ + touch modules/$(arch)-$$name/kernel-image; \ + done; \ + fi + + # Some files may need to differ between flavours + flavour_module_dirs=`ls -d debian/d-i/modules-$(arch)-* 2>/dev/null`\ + || true; \ + if [ "$$flavour_module_dirs" ]; then \ + for flav in $$flavour_module_dirs; do \ + name=`echo $$flav | sed 's/.*\/modules-$(arch)-//'`; \ + [ -d modules/$(arch)-$$name ] || \ + cp -a modules/$(arch) modules/$(arch)-$$name; \ + cp $$flav/* modules/$(arch)-$$name/; \ + done; \ + fi + + # Remove unwanted stuff for each flavour + flavour_exclude=`ls debian/d-i/exclude-modules.$(arch)-* 2>/dev/null`\ + || true; \ + if [ "$$flavour_exclude" ]; then \ + for flav in $$flavour_exclude; do \ + name=`echo $$flav | sed 's/.*\/exclude-modules.$(arch)-//'`;\ + [ -d modules/$(arch)-$$name ] || \ + cp -a modules/$(arch) modules/$(arch)-$$name; \ + (cat $$flav; \ + ls modules/$(arch)-$$name) | sort | uniq -d | \ + (cd modules/$(arch)-$$name/; xargs rm -f); \ + done; \ + fi + + if [ ! -d modules/$(build_arch) ]; then \ + mkdir -p modules/$(build_arch); \ + cp modules/$(arch)/* modules/$(build_arch); \ + fi + + kernel-wedge gen-control > debian/control --- linux-2.6.28.orig/debian/changelog.historical +++ linux-2.6.28/debian/changelog.historical @@ -0,0 +1,5745 @@ +linux (2.6.24-19.33) UNRELEASED; urgency=low + + CHANGELOG: Do not edit directly. Autogenerated at release. + CHANGELOG: Use the printchanges target to see the curent changes. + CHANGELOG: Use the insertchanges target to create the final log. + + -- Tim Gardner Sun, 04 May 2008 20:22:21 -0600 + +linux (2.6.24-18.32) hardy-security; urgency=low + + * CVE-2007-6694: [POWERPC] CHRP: Fix possible NULL pointer dereference + * fix SMP ordering hole in fcntl_setlk() (CVE-2008-1669) + * Fix dnotify/close race (CVE-2008-1375) + * tehuti: check register size (CVE-2008-1675) + * tehuti: move ioctl perm check closer to function start (CVE-2008-1675) + + -- Ben Collins Mon, 19 May 2008 16:50:11 +0000 + +linux (2.6.24-17.31) hardy; urgency=low + + [Alessio Igor Bogani] + + * rt: Fix mutex in the toshiba_acpi driver + * rt: Updated configuration files + + [Ben Collins] + + * build: Fix revert detection in git-ubuntu-log + * SAUCE: Re-add eeprom_bad_csum_allow module-param + - LP: #60388 + + [Stefan Bader] + + * Pulled updates to openvz custom build. Fixes openvz 'refuses to boot' problem. + - LP: #210672 + * sched: retain vruntime, fix delayed key events when CONFIG_FAIR_GROUP_SCHED. + - LP: #218516 + * UBUNTU: SAUCE: Add blacklist support to fix Belkin bluetooth dongle. + - LP: #140511 + + [Tim Gardner] + + * Enable CONFIG_ISCSI_TCP for -virtual + - LP: #218215 + * build: Add fancontrol modules to powerpc64-smp debian installer + * Fix Xen Dom0/DomU bridging + - LP: #218126 + * TSC Clocksource can cause hangs and time jumps + - LP: #221351 + * Kernel should use CONFIG_FAIR_CGROUP_SCHED. Fixes high load issues + with pulseaudio. + - LP: #188226 + + [Upstream Kernel Changes] + + * KVM: MMU: prepopulate guest pages after write-protecting + - LP: #221032 + + -- Tim Gardner Fri, 11 Apr 2008 07:59:10 -0600 + +linux (2.6.24-16.30) hardy; urgency=low + + * Fix amd64/i386 ABI and module check FTBS by creating an ignore + and ignore.modules in the ABI directory. + + -- Tim Gardner Wed, 09 Apr 2008 21:58:25 -0600 + +linux (2.6.24-16.29) hardy; urgency=low + + [Stephan Bader] + + * UBUNTU: SAUCE: mmc: Increase power_up deleay to fix TI readers + + [Alessio Igor Bogani] + + * rt: Updated configuration files + + [Chuck Short] + + * Xen updates for vitrio changes. + + [Tim Gardner] + + * openvz updates for vitrio changes. + + -- Tim Gardner Tue, 08 Apr 2008 21:48:16 -0600 + +linux (2.6.24-16.28) hardy; urgency=low + + [Tim Gardner] + + * Revert "UBUNTU: x86: tsc prevent time going backwards" + + [Kees Cook] + + * AppArmor: implement mmap_min_addr check as done in mainline. + + [Soren Hansen] + + * Bring our virtio code up to date with 2.6.25-rc7 + + [Upstream Kernel Changes] + + * Ubuntu: Revert all our virtio changes + * lguest: Reboot support + * lguest: adapt launcher to per-cpuness + * virtio: Implement skb_partial_csum_set, for setting partial csums on + untrusted packets. + * virtio: simplify config mechanism. + * virtio: explicit enable_cb/disable_cb rather than callback return. + * virtio: configuration change callback + * virtio: Fix vring_init/vring_size to take unsigned long + * virtio: clarify NO_NOTIFY flag usage + * virtio: remove unused id field from struct virtio_blk_outhdr + * virtio: Net header needs hdr_len + * virtio: Tweak virtio_net defines + * virtio: populate network rings in the probe routine, not open + * virtio: reset function + * virtio: handle interrupts after callbacks turned off + * virtio: Use the sg_phys convenience function. + * virtio: Allow virtio to be modular and used by modules + * virtnet: remove double ether_setup + * virtio: flush buffers on open + * virtio: free transmit skbs when notified, not on next xmit. + * virtio_net: parametrize the napi_weight for virtio receive queue. + * virtio_blk: provide getgeo + * virtio_blk: Dont waste major numbers + * virtio_blk: implement naming for vda-vdz,vdaa-vdzz,vdaaa-vdzzz + * virtio: PCI device + * virtio: Use PCI revision field to indicate virtio PCI ABI version + * virtio: balloon driver + * virtio net: fix oops on interface-up + * virtio: add missing #include + * virtio: fix race in enable_cb + * virtio: handle > 2 billion page balloon targets + * virtio_net: Fix oops on early interrupts - introduced by virtio reset + code + * lguest: Do not append space to guests kernel command line + * virtio: Use spin_lock_irqsave/restore for virtio-pci + * virtio: Fix sysfs bits to have proper block symlink + * virtio: Enable netpoll interface for netconsole logging + * virtio_pci: unregister virtio device at device remove + * lguest: Add puppies which where previously missing. + * lguest: lguest.txt documentation fix + * lguest: Don't need comment terminator before disk section. + * virtio_pci iomem annotations + * virtio_net: remove overzealous printk + * virtio: remove overzealous BUG_ON. + + -- Tim Gardner Tue, 08 Apr 2008 11:53:49 -0600 + +linux (2.6.24-15.27) hardy; urgency=low + + [Alan Stern] + + * usb-storage: don't access beyond the end of the sg buffer + - LP: #204922 + + [Mario Limonciello] + + * Enable Reset and SCO workaround on Dell 410 BT adapter + + [Tim Gardner] + + * Enable CONFIG_E1000 in the i386 virtual image. + - LP: #205646 + + [Thomas Gleixner] + + * x86: tsc prevent time going backwards + + [Matthew Garrett] + + * Fix framebuffer fonts on non-x86 platforms + + -- Tim Gardner Fri, 04 Apr 2008 08:14:49 -0600 + +linux (2.6.24-15.26) hardy; urgency=low + + [Colin Ian King] + + * airprime.c supports more devices + - LP: #208250 + + [Kees Cook] + + * AppArmor: get latest batch of upstream fixes into Hardy (svn 1160) + + [Stefan Bader] + + * ACPI: fix boot oops regression in kernel + - LP: #207014 + + [Tim Gardner] + + * Enable CGROUPS for non x86/x86_64 arches, all flavours. + - LP: #188226 + + -- Tim Gardner Thu, 03 Apr 2008 07:00:29 -0600 + +linux (2.6.24-14.25) hardy; urgency=low + + [Mario Limonciello] + + * Resolve sky2 race condition leading to failed suspends + - LP: #210877 + + [Tim Gardner] + + * Copy drivers/media internal header files into header + package for external LUM compilation. This paves the + way for LP #202065. + + -- Tim Gardner Wed, 02 Apr 2008 08:28:32 -0600 + +linux (2.6.24-14.24) hardy; urgency=low + + [Amit Kucheria] + + * LPIA: Update from moblin + * LPIA: Fix reboot problem after S3/S4 + * LPIA: Integrate latest Dabney thermal patches + * LPIA: Change-umd_dbg-debug-level-to-KERN_INFO + * LPIA: Compile modules into kernel to save on boot time + * LPIA: lots of Dabney CONFIG options dissapeared + * LPIA: Purge nonexistent config options + + [Jay Chetty] + + * UBUNTU:USBC:Integrated USBC 2.0.0.32L.0009 + + [Misha Zhilin] + + * USB: ehci: handle large bulk URBs correctly (again) + - LP: #204857 + + [Tim Gardner] + + * frame buffer regression - screen blank except for blinking cursor after + fbcon vtswitch + - LP: #201591 + * Blacklist Bluetooth Dell Wireless 370 for SCO MTU + - LP: #209715 + * Set CONFIG_FAIR_CGROUP_SCHED for server flavours. + - LP: #188226 + * Add DMI IO_DELAY support. + - LP: #200057 + + -- Tim Gardner Mon, 31 Mar 2008 11:19:49 -0600 + +linux (2.6.24-13.23) hardy; urgency=low + + [Alessio Igor Bogani] + + * rt: Updated configuration files + + [Ben Collins] + + * openvz: New custom flavour for OpenVZ + * config: Disable IDE AMD driver in favor of PATA version + - LP: #181561 + * config: Disable IDE VIA driver in favor of PATA version + - LP: #181561 + * drivers/video: Restore gutsy backlight dimming behavior + - LP: #205261 + * build/config: Enable CONFIG_CIFS_WEAK_PW_HASH + - LP: #202445 + + [Colin Ian King] + + * SAUCE: Add support for version 4 of Chelsio NICs in cxgb3 driver + - LP: #201893 + + [Kees Cook] + + * AppArmor: re-add missing "type" field in syslog reports. + - LP: #202888 + * kvm: reset TSS on x86_64 to avoid ioperm bitmap corruption + - LP: #144900 + + [Stefan Bader] + + * USB: EHCI: add separate IAA watchdog timer + - LP: #198619 + * SAUCE: Always use SCO protocol (disable eSCO support) + - LP: #39414 + * PM: Introduce PM_EVENT_HIBERNATE callback state + - LP: #201086 + + [Tim Gardner] + + * Disable DRM suspend/resume on pre-915 Intel chips + - LP: #207496 + * frame buffer regression - screen blank except for blinking cursor after fbcon + vtswitch + - LP: #201591 + + -- Tim Gardner Wed, 19 Mar 2008 10:05:05 -0400 + +linux (2.6.24-12.22) hardy; urgency=low + + [Ben Collins] + + * custom/rt: Disable toshiba_acpi, since it isn't compatible + + -- Ben Collins Wed, 12 Mar 2008 14:38:59 -0400 + +linux (2.6.24-12.21) hardy; urgency=low + + [Ben Collins] + + * build: Fix vesafb module inclusion into initrd subdir + - LP: #129910 + * net/bluetooth: POWERBOOK => APPLE, fix for apple keyboard patch + * custom/xen: Remove asix portion of xen patch, breaks driver + - LP: #199296 + + [Colin Ian King] + + * SAUCE: fix Udma not fully available in Acer 1694 Wlmi + - LP: #187121 + * SAUCE: Update toshiba_acpi.c to version 0.19a + - LP: #77026 + + [Stefan Bader] + + * x86: Clear DF before calling signal handler + * Enable FN key on Apple aluminum bluetooth keyboard + - LP: #162083 + + -- Ben Collins Tue, 11 Mar 2008 13:20:49 -0400 + +linux (2.6.24-12.20) hardy; urgency=low + + [Ben Collins] + + * Enable CONFIG_SOUND at least, so alsa build in lum works + - LP: #200338 + + -- Ben Collins Mon, 10 Mar 2008 08:15:00 -0400 + +linux (2.6.24-12.19) hardy; urgency=low + + * Re-upload of -12.18 to fix build failures + * Fixup binary-custom configs + * Fixup xen patch to cope with kvm changes + + [Amit Kucheria] + + * Move Marvell 8686 and 8688 to LUM + * Poulsbo: Sync patches with moblin/ume-hardy tree + * Break if a patch fails to apply + * SAUCE: implement smarter atime updates support + - LP: #199427 + * Enable USB_PERSIST to allow devices with /root on usb to work with + suspend + * Enable USB_PERSIST across the board + + [Ben Collins] + + * build/config: Really fix ide on smp ppc configs + * build/configs: Enable relatime config option for all flavors + * build/abi: Ignore ide-core module for ppc, moved to built-in + + [Colin Ian King] + + * fix reversed logic for bbuild check leads to -j1 default + - LP: #197040 + * Enable IDE_PMAC for powerpc-smp + - LP: #196686 + * Disable CONFIG_USB_OHCI_HCD_SSB + - LP: #182716 + * SAUCE: fix arcmsr + archttp64 calls dma_free_coherent() with irqs + disabled - dmesg filled with warnings + - LP: #194207 + + [Jorge Boncompte [DTI2]] + + * Fix Messed multicast lists after dev_mc_sync/unsync + - LP: #193468 + + [Stefan Bader] + + * Add support for Apple Aluminium keyboards. + - LP: #162083 + * SAUCE: Restore VT fonts on switch + + [Upstream Kernel Changes] + + * [NET]: Messed multicast lists after dev_mc_sync/unsync + * KVM: x86 emulator: add support for group decoding + * KVM: x86 emulator: group decoding for group 1A + * KVM: x86 emulator: Group decoding for group 3 + * KVM: x86 emulator: Group decoding for groups 4 and 5 + * KVM: x86 emulator: add group 7 decoding + * KVM: constify function pointer tables + * KVM: Only x86 has pio + * KVM: x86 emulator: group decoding for group 1 instructions + * KVM: MMU: Decouple mmio from shadow page tables + * KVM: Limit vcpu mmap size to one page on non-x86 + * KVM: VMX: Enable Virtual Processor Identification (VPID) + * KVM: Use CONFIG_PREEMPT_NOTIFIERS around struct preempt_notifier + * KVM: Disable pagefaults during copy_from_user_inatomic() + * KVM: make EFER_RESERVED_BITS configurable for architecture code + * KVM: align valid EFER bits with the features of the host system + * KVM: allow access to EFER in 32bit KVM + * kvm: i386 fix + * KVM: export information about NPT to generic x86 code + * KVM: MMU: make the __nonpaging_map function generic + * KVM: export the load_pdptrs() function to modules + * KVM: MMU: add TDP support to the KVM MMU + * KVM: x86 emulator: Fix 'jmp abs' + * KVM: x86 emulator: fix group 5 decoding + * KVM: Fix kvm_arch_vcpu_ioctl_set_sregs so that set_cr0 works properly + * KVM: Make the supported cpuid list a host property rather than a vm + property + * KVM: emulate access to MSR_IA32_MCG_CTL + * KVM: remove the usage of the mmap_sem for the protection of the memory + slots. + * KVM: SVM: allocate the MSR permission map per VCPU + * KVM: make MMU_DEBUG compile again + * KVM: paravirtualized clocksource: host part + * KVM: Add missing semicolon + * KVM: x86 emulator: add ad_mask static inline + * KVM: x86 emulator: make register_address, address_mask static inlines + * KVM: x86 emulator: make register_address_increment and JMP_REL static + inlines + * KVM: Add API to retrieve the number of supported vcpus per vm + * KVM: Increase vcpu count to 16 + * KVM: Add API for determining the number of supported memory slots + * KVM: Increase the number of user memory slots per vm + * KVM: Add stat counter for hypercalls + * KVM: x86 emulator: fix sparse warnings in x86_emulate.c + * KVM: sparse fixes for kvm/x86.c + * KVM: Implement dummy values for MSR_PERF_STATUS + * KVM: MMU: ignore zapped root pagetables + * KVM: call write_guest_time as soon as we register the paravirt clock + * KVM: MMU: large page support + * KVM: Prefix control register accessors with kvm_ to avoid namespace + pollution + * KVM: Avoid infinite-frequency local apic timer + * KVM: Route irq 0 to vcpu 0 exclusively + * KVM: SVM: add support for Nested Paging + * KVM: SVM: enable LBR virtualization + * KVM: SVM: make iopm_base static + * KVM: SVM: let init_vmcb() take struct vcpu_svm as parameter + * KVM: VMX: fix typo in VMX header define + * KVM: SVM: fix Windows XP 64 bit installation crash + * KVM: VMX: Fix invalid opcode of VPID + * KVM: VMX: Handle machines without EFER + * KVM: move alloc_apic_access_page() outside of non-preemptable region + * KVM: VMX: unifdef the EFER specific code + * KVM: SVM: move feature detection to hardware setup code + * KVM: Export include/linux/kvm.h only if $ARCH actually supports KVM + * dlm: fix rcom_names message to self + * virtio: Net header needs hdr_len + + -- Tim Gardner Mon, 03 Mar 2008 07:07:16 -0700 + +linux (2.6.24-11.17) hardy; urgency=low + + [Alan Cox] + + * Pull in fixes for pata_it821x. + - LP: #106931 + + [Alessio Igor Bogani] + + * rt: Synchronized with upstream (2.6.24.3-rt3) + * rt: Updated configuration files + + [Amit Kucheria] + + * Add AGP support for Radeon Mobility 9000 chipset + - LP: #178634 + * Bluetooth: SCO flow control to enable bluetooth headsets + + [Ben Collins] + + * binary: Include vesafs in initrd subdir, should fix vga= usage + + [Colin Ian King] + + * AMD SB700 south bridge support patches + - LP: #195354 + * BCM4311 Revision 2 fix + - LP: #184600 + + [Mauro Carvalho Chehab] + + * V4L/DVB (6753): Fix vivi to support non-zero minor node + + [Tim Gardner] + + * Merged 2.6.24.3 + * Add atl1 to d-i bits. + - LP: #159561 + * SAUCE: Add xpad support for RedOctane Guitar Hero + - LP: #196745 + + [Upstream Kernel Changes] + + * DVB: cx23885: add missing subsystem ID for Hauppauge HVR1800 Retail + * slab: fix bootstrap on memoryless node + * vm audit: add VM_DONTEXPAND to mmap for drivers that need it + (CVE-2008-0007) + * USB: keyspan: Fix oops + * usb gadget: fix fsl_usb2_udc potential OOPS + * USB: CP2101 New Device IDs + * USB: add support for 4348:5523 WinChipHead USB->RS 232 adapter + * USB: Sierra - Add support for Aircard 881U + * USB: Adding YC Cable USB Serial device to pl2303 + * USB: sierra driver - add devices + * USB: ftdi_sio - enabling multiple ELV devices, adding EM1010PC + * USB: ftdi-sio: Patch to add vendor/device id for ATK_16IC CCD + * USB: sierra: add support for Onda H600/Zte MF330 datacard to USB Driver + for Sierra Wireless + * USB: remove duplicate entry in Option driver and Pl2303 driver for + Huawei modem + * USB: pl2303: add support for RATOC REX-USB60F + * USB: ftdi driver - add support for optical probe device + * USB: use GFP_NOIO in reset path + * USB: Variant of the Dell Wireless 5520 driver + * USB: storage: Add unusual_dev for HP r707 + * USB: fix usbtest halt check on big endian systems + * USB: handle idVendor of 0x0000 + * USB: Fix usb_serial_driver structure for Kobil cardreader driver. + * forcedeth: mac address mcp77/79 + * lockdep: annotate epoll + * sys_remap_file_pages: fix ->vm_file accounting + * PCI: Fix fakephp deadlock + * ACPI: update ACPI blacklist + * x86: restore correct module name for apm + * sky2: restore multicast addresses after recovery + * sky2: fix for WOL on some devices + * b43: Fix suspend/resume + * b43: Drop packets we are not able to encrypt + * b43: Fix dma-slot resource leakage + * b43legacy: fix PIO crash + * b43legacy: fix suspend/resume + * b43legacy: drop packets we are not able to encrypt + * b43legacy: fix DMA slot resource leakage + * selinux: fix labeling of /proc/net inodes + * b43: Reject new firmware early + * sched: let +nice tasks have smaller impact + * sched: fix high wake up latencies with FAIR_USER_SCHED + * fix writev regression: pan hanging unkillable and un-straceable + * Driver core: Revert "Fix Firmware class name collision" + * drm: the drm really should call pci_set_master.. + * splice: missing user pointer access verification (CVE-2008-0009/10) + * Linux 2.6.24.1 + * splice: fix user pointer access in get_iovec_page_array() + * Linux 2.6.24.2 + * ACPI: video: Rationalise ACPI backlight implementation + * ACPI: video: Ignore ACPI video devices that aren't present in hardware + * SPARC/SPARC64: Fix usage of .section .sched.text in assembler code. + * NETFILTER: nf_conntrack_tcp: conntrack reopening fix + * NFS: Fix a potential file corruption issue when writing + * inotify: fix check for one-shot watches before destroying them + * hugetlb: add locking for overcommit sysctl + * XFS: Fix oops in xfs_file_readdir() + * Fix dl2k constants + * SCSI: sd: handle bad lba in sense information + * TCP: Fix a bug in strategy_allowed_congestion_control + * TC: oops in em_meta + * SELinux: Fix double free in selinux_netlbl_sock_setsid() + * PKT_SCHED: ematch: oops from uninitialized variable (resend) + * NET: Add if_addrlabel.h to sanitized headers. + * IPV4: fib_trie: apply fixes from fib_hash + * IPV4: fib: fix route replacement, fib_info is shared + * IPCOMP: Fix reception of incompressible packets + * IPCOMP: Fetch nexthdr before ipch is destroyed + * INET_DIAG: Fix inet_diag_lock_handler error path. + * INET: Prevent out-of-sync truesize on ip_fragment slow path + * BLUETOOTH: Add conn add/del workqueues to avoid connection fail. + * AUDIT: Increase skb->truesize in audit_expand + * Be more robust about bad arguments in get_user_pages() + * Disable G5 NAP mode during SMU commands on U3 + * hrtimer: fix *rmtp handling in hrtimer_nanosleep() + * hrtimer: fix *rmtp/restarts handling in compat_sys_nanosleep() + * SLUB: Deal with annoying gcc warning on kfree() + * hrtimer: check relative timeouts for overflow + * hrtimer: catch expired CLOCK_REALTIME timers early + * genirq: do not leave interupts enabled on free_irq + * S390: Fix futex_atomic_cmpxchg_std inline assembly. + * USB: fix pm counter leak in usblp + * SCSI: gdth: scan for scsi devices + * PCMCIA: Fix station address detection in smc + * POWERPC: Revert chrp_pci_fixup_vt8231_ata devinit to fix libata on + pegasos + * bonding: fix NULL pointer deref in startup processing + * x86_64: CPA, fix cache attribute inconsistency bug + * Linux 2.6.24.3 + + -- Tim Gardner Mon, 25 Feb 2008 12:28:13 -0700 + +linux (2.6.24-10.16) hardy; urgency=low + + [Alessio Igor Bogani] + + * rt: Synchronized with upstream (2.6.24.2-rt2) + * rt: Updated configuration files + + [Eric Piel] + + * SAUCE: ACPI: Allow custom DSDT tables to be loaded from initramfs + Amit Kucheria consolidated the DSDT patch with another fix that + ifdefs symbols required when BLK_DEV_INITR is disabled. + + [Stefan Bader] + + * Add Optiarc DVD drive to audio quirks list. + - LP: #186664 + * Update drm and i915 drm driver to fix suspend issues. + - LP: #189260 + + [Tim Gardner] + + * Fix FTBS without BLK_DEV_INITRD + - LP: #193507 + * 64 bit CPA cache attribute bug + - LP: #193736 + * Implemented default EDD control + + [Upstream Kernel Changes] + + * bonding: fix NULL pointer deref in startup processing + * dlm: bind connections from known local address when using TCP + * dlm: proper prototypes + * dlm: don't print common non-errors + * dlm: use dlm prefix on alloc and free functions + * dlm: close othercons + * dlm: align midcomms message buffer + * dlm: swap bytes for rcom lock reply + * dlm: use fixed errno values in messages + * dlm: clear ast_type when removing from astqueue + * dlm: recover locks waiting for overlap replies + * dlm: another call to confirm_master in receive_request_reply + * dlm: reject messages from non-members + * dlm: validate messages before processing + * dlm: reject normal unlock when lock is waiting for lookup + * dlm: limit dir lookup loop + * dlm: fix possible use-after-free + * dlm: change error message to debug + * dlm: keep cached master rsbs during recovery + * dlm: Sanity check namelen before copying it + * dlm: clean ups + * dlm: static initialization improvements + * dlm: use proper C for dlm/requestqueue stuff (and fix alignment bug) + * dlm: dlm_process_incoming_buffer() fixes + * dlm: do not byteswap rcom_lock + * dlm: do not byteswap rcom_config + * dlm: use proper type for ->ls_recover_buf + * dlm: missing length check in check_config() + * dlm: validate data in dlm_recover_directory() + * dlm: verify that places expecting rcom_lock have packet long enough + * dlm: receive_rcom_lock_args() overflow check + * dlm: make find_rsb() fail gracefully when namelen is too large + * dlm: fix overflows when copying from ->m_extra to lvb + * dlm: fix dlm_dir_lookup() handling of too long names + * dlm: dlm/user.c input validation fixes + * dlm: proper types for asts and basts + * dlm: eliminate astparam type casting + * dlm: add __init and __exit marks to init and exit functions + * virtio: Use PCI revision field to indicate virtio PCI ABI version + + -- Tim Gardner Tue, 19 Feb 2008 09:57:18 -0700 + +linux (2.6.24-9.15) hardy; urgency=low + + [Alessio Igor Bogani] + + * rt: Fix FTBS + * rt: Updated configuration files + + [Tim Gardner] + + * SAUCE: make /dev/kmem a config option + * SAUCE: x86: introduce /dev/mem restrictions with a config option + * Fixed CGROUP FTBS caused by AppArmor patch. + * Enabled CGROUP and CPUSETS for server flavor. + - LP: #182434 + + [Colin King] + + * Turn on /proc/acpi/alarm for x86_64 (amd64) + - LP: #186297 + + [Upstream Kernel Changes] + + * Ubuntu: LatencyTOP infrastructure patch + + -- Tim Gardner Thu, 14 Feb 2008 13:34:55 -0700 + +linux (2.6.24-8.14) hardy; urgency=low + + [cking] + + * Support Novatel U727 EVDO modem: Add pid and vid to + drivers/usb/serial/airprime.c + - LP: #150996 + * Enable speedstep for sonoma processors. + - LP: #132271 + + [Stefan Bader] + + * SAUCE: Export dm_disk function of device-mapper + + -- Tim Gardner Wed, 13 Feb 2008 21:47:18 -0700 + +linux (2.6.24-8.13) hardy; urgency=low + + [Soren Hansen] + + * Add missing iscsi modules to kernel udebs + + [Stefan Bader] + + * Lower message level for PCI memory and I/O allocation. + + [Tim Gardner] + + * Enabled IP_ADVANCED_ROUTER and IP_MULTIPLE_TABLES in sparc, hppa + - LP: #189560 + * Compile RealTek 8139 using PIO method. + - LP: #90271 + * Add WD WD800ADFS NCQ horkage quirk support. + - LP: #147858 + + [Upstream Kernel Changes] + + * Introduce WEXT scan capabilities + * DVB: cx23885: add missing subsystem ID for Hauppauge HVR1800 Retail + * slab: fix bootstrap on memoryless node + * vm audit: add VM_DONTEXPAND to mmap for drivers that need it + (CVE-2008-0007) + * USB: keyspan: Fix oops + * usb gadget: fix fsl_usb2_udc potential OOPS + * USB: CP2101 New Device IDs + * USB: add support for 4348:5523 WinChipHead USB->RS 232 adapter + * USB: Sierra - Add support for Aircard 881U + * USB: Adding YC Cable USB Serial device to pl2303 + * USB: sierra driver - add devices + * USB: ftdi_sio - enabling multiple ELV devices, adding EM1010PC + * USB: ftdi-sio: Patch to add vendor/device id for ATK_16IC CCD + * USB: sierra: add support for Onda H600/Zte MF330 datacard to USB Driver + for Sierra Wireless + * USB: remove duplicate entry in Option driver and Pl2303 driver for + Huawei modem + * USB: pl2303: add support for RATOC REX-USB60F + * USB: ftdi driver - add support for optical probe device + * USB: use GFP_NOIO in reset path + * USB: Variant of the Dell Wireless 5520 driver + * USB: storage: Add unusual_dev for HP r707 + * USB: fix usbtest halt check on big endian systems + * USB: handle idVendor of 0x0000 + * forcedeth: mac address mcp77/79 + * lockdep: annotate epoll + * sys_remap_file_pages: fix ->vm_file accounting + * PCI: Fix fakephp deadlock + * ACPI: update ACPI blacklist + * x86: restore correct module name for apm + * sky2: restore multicast addresses after recovery + * sky2: fix for WOL on some devices + * b43: Fix suspend/resume + * b43: Drop packets we are not able to encrypt + * b43: Fix dma-slot resource leakage + * b43legacy: fix PIO crash + * b43legacy: fix suspend/resume + * b43legacy: drop packets we are not able to encrypt + * b43legacy: fix DMA slot resource leakage + * selinux: fix labeling of /proc/net inodes + * b43: Reject new firmware early + * sched: let +nice tasks have smaller impact + * sched: fix high wake up latencies with FAIR_USER_SCHED + * fix writev regression: pan hanging unkillable and un-straceable + * Driver core: Revert "Fix Firmware class name collision" + * drm: the drm really should call pci_set_master.. + * splice: missing user pointer access verification (CVE-2008-0009/10) + * Linux 2.6.24.1 + * splice: fix user pointer access in get_iovec_page_array() + * Linux 2.6.24.2 + + -- Tim Gardner Thu, 07 Feb 2008 06:50:13 -0700 + +linux (2.6.24-7.12) hardy; urgency=low + + [Jay Chetty] + + * Added patch to fix legacy USB interrupt issue + * Enabled Poulsbo PATA udma5 support + * Add touchscreen doubleclick workaround + + [Amit Kucheria] + + * Add AGP support for Radeon Mobility 9000 chipset + - LP: #178634 + + [Soren Hansen] + + * Add virtio modules to the relevant udebs + * Add missing "?" for virtio modules in storage-core-modules + + [Stefan Bader] + + * Added vendor id for Dell 5720 broadband modem + + -- Jay Chetty Wed, 06 Feb 2008 14:13:41 -0800 + +linux (2.6.24-7.11) hardy; urgency=low + + [Jay Chetty] + + * poulsbo: Add a 100ms delay for SiB workaround + + [Tim Gardner] + + * -6.10 should have been an ABI bump, but due to incomplete build testing + went undetected. + + -- Tim Gardner Mon, 04 Feb 2008 19:13:52 -0700 + +linux (2.6.24-6.10) hardy; urgency=low + + [Alessio Igor Bogani] + + * rt: Synced with upstream, removed old kvm related patches and updated + configurations files. + + [Chuck Short] + + * SAUCE: Enable Xen + + [Soren Hansen] + + * Update kvm driver to kvm-60. + * Added CONFIG_ARCH_SUPPORTS_KVM=y for lpia, i386, and amd64 + * Add rtl8139 driver to -virtual flavour + + [Stefan Bader] + + * Fix usb_serial_driver structure for Kobil cardreader driver. + - LP: #183109 + * Lower warning level of pci resource allocation messages. + - LP: #159241 + + [Tim Gardner] + + * Enabled CONFIG_BLK_DEV_IDE_PMAC + - LP: #185862 + * Add virtio config options to lpiacompat. + * SAUCE: Export symbols for aufs (in lum). + * Enabled Xen + + [Upstream Kernel Changes] + + * KVM: mmu: add missing dirty page tracking cases + * KVM: Move virtualization deactivation from CPU_DEAD state to + CPU_DOWN_PREPARE + * KVM: Cosmetics + * KVM: vmx: hack set_cr0_no_modeswitch() to actually do modeswitch + * KVM: Use ARRAY_SIZE macro instead of manual calculation. + * KVM: Use page_private()/set_page_private() apis + * KVM: add MSR based hypercall API + * KVM: Add host hypercall support for vmx + * KVM: Add hypercall host support for svm + * KVM: Wire up hypercall handlers to a central arch-independent location + * KVM: svm: init cr0 with the wp bit set + * KVM: SVM: intercept SMI to handle it at host level + * KVM: More 0 -> NULL conversions + * kvm, dirty pages log: adding some calls to mark_page_dirty() + * KVM: Add internal filesystem for generating inodes + * KVM: Create an inode per virtual machine + * KVM: Rename some kvm_dev_ioctl_*() functions to kvm_vm_ioctl_*() + * KVM: Move kvm_vm_ioctl_create_vcpu() around + * KVM: Per-vcpu inodes + * KVM: Bump API version + * .gitignore: ignore emacs backup files (*~) + * kvm: dirty pages log: fix bitmap size/access calculation + * kvm: move do_remove_write_access() up + * kvm: dirty page logging: remove write access permissions when + dirty-page-logging is enabled + * KVM: Add missing calls to mark_page_dirty() + * KVM: Fix dirty page log bitmap size/access calculation + * kvm: move do_remove_write_access() up + * KVM: Remove write access permissions when dirty-page-logging is enabled + * KVM: Fix bogus failure in kvm.ko module initialization + * KVM: Move kvmfs magic number to + * KVM: Unset kvm_arch_ops if arch module loading failed + * KVM: Fix guest register corruption on paravirt hypercall + * KVM: Use the generic skip_emulated_instruction() in hypercall code + * KVM: Use own minor number + * KVM: Fix guest sysenter on vmx + * KVM: Export + * KVM: Fix bogus sign extension in mmu mapping audit + * KVM: MMU: Fix guest writes to nonpae pde + * KVM: MMU: Fix host memory corruption on i386 with >= 4GB ram + * KVM: trivial whitespace fixes + * KVM: always reload segment selectors + * KVM: Remove extraneous guest entry on mmio read + * added KVM_GET_MEM_MAP ioctl to get the memory bitmap for a memory slot + * KVM: Prevent system selectors leaking into guest on real->protected + mode transition on vmx + * KVM: Use a shared page for kernel/user communication when runing a vcpu + * KVM: Do not communicate to userspace through cpu registers during PIO + * KVM: Initialize PIO I/O count + * KVM: Handle cpuid in the kernel instead of punting to userspace + * KVM: Remove the 'emulated' field from the userspace interface + * KVM: Remove minor wart from KVM_CREATE_VCPU ioctl + * KVM: Renumber ioctls + * KVM: Add method to check for backwards-compatible API extensions + * KVM: Allow userspace to process hypercalls which have no kernel handler + * KVM: Fold kvm_run::exit_type into kvm_run::exit_reason + * KVM: Add a special exit reason when exiting due to an interrupt + * KVM: Initialize the apic_base msr on svm too + * KVM: Add guest mode signal mask + * KVM: Allow kernel to select size of mmap() buffer + * KVM: Future-proof argument-less ioctls + * KVM: Avoid guest virtual addresses in string pio userspace interface + * KVM: MMU: Remove unnecessary check for pdptr access + * KVM: MMU: Remove global pte tracking + * KVM: Workaround vmx inability to virtualize the reset state + * KVM: Remove set_cr0_no_modeswitch() arch op + * KVM: Modify guest segments after potentially switching modes + * KVM: Hack real-mode segments on vmx from KVM_SET_SREGS + * KVM: Don't allow the guest to turn off the cpu cache + * KVM: Remove unused and write-only variables + * KVM: Handle writes to MCG_STATUS msr + * KVM: MMU: Fix hugepage pdes mapping same physical address with + different access + * KVM: SVM: Ensure timestamp counter monotonicity + * KVM: Remove unused function + * KVM: Remove debug message + * KVM: x86 emulator: fix bit string operations operand size + * KVM: SVM: enable LBRV virtualization if available + * Add mmu cache clear function + * KVM: Simply gfn_to_page() + * KVM: Add physical memory aliasing feature + * KVM: Add fpu get/set operations + * KVM: Use kernel-standard types + * KVM: Fix overflow bug in overflow detection code + * KVM: Fix memory leak on pio completion + * KVM: Handle partial pae pdptr + * KVM: Fix string pio when count == 0 + * KVM: Use slab caches to allocate mmu data structures + * KVM: Retry sleeping allocation if atomic allocation fails + * KVM: Fix pio completion + * KVM: SVM: Report hardware exit reason to userspace instead of dmesg + * KVM: Handle guest page faults when emulating mmio + * KVM: VMX: Reduce unnecessary saving of host msrs + * KVM: Fix off-by-one when writing to a nonpae guest pde + * KVM: VMX: Don't switch 64-bit msrs for 32-bit guests + * KVM: Fold drivers/kvm/kvm_vmx.h into drivers/kvm/vmx.c + * KVM: VMX: Only save/restore MSR_K6_STAR if necessary + * KVM: Per-vcpu statistics + * KVM: Silence compile warning on i386 + * KVM: Allow passing 64-bit values to the emulated read/write API + * KVM: Lazy FPU support for SVM + * KVM: Fix msr-avoidance regression on Core processors + * KVM: Don't complain about cpu erratum AA15 + * KVM: Document MSR_K6_STAR's special place in the msr index array + * KVM: MMU: Avoid heavy ASSERT at non debug mode. + * KVM: Initialize cr0 to indicate an fpu is present + * KVM: We want asserts on debug builds, not release + * KVM: Avoid unused function warning due to assertion removal + * KVM: VMX: Avoid unnecessary vcpu_load()/vcpu_put() cycles + * KVM: Move need_resched() check to common code + * KVM: VMX: Properly shadow the CR0 register in the vcpu struct + * KVM: VMX: Add lazy FPU support for VT + * KVM: fix an if() condition + * KVM: SVM: Only save/restore MSRs when needed + * KVM: Remove trailing whitespace + * KVM: Remove extraneous guest entry on mmio read + * KVM: Don't require explicit indication of completion of mmio or pio + * KVM: Remove unused 'instruction_length' + * KVM: VMX: Enable io bitmaps to avoid IO port 0x80 VMEXITs + * KVM: SVM: Allow direct guest access to PC debug port + * KVM: Fix RMW mmio handling + * KVM: Assume that writes smaller than 4 bytes are to non-pagetable pages + * KVM: Avoid saving and restoring some host CPU state on lightweight + vmexit + * KVM: Unindent some code + * KVM: Reduce misfirings of the fork detector + * KVM: Be more careful restoring fs on lightweight vmexit + * KVM: Unify kvm_mmu_pre_write() and kvm_mmu_post_write() + * KVM: MMU: Respect nonpae pagetable quadrant when zapping ptes + * KVM: Update shadow pte on write to guest pte + * KVM: Increase mmu shadow cache to 1024 pages + * KVM: Fix potential guest state leak into host + * KVM: Prevent guest fpu state from leaking into the host + * KVM: Move some more msr mangling into vmx_save_host_state() + * KVM: Rationalize exception bitmap usage + * KVM: Consolidate guest fpu activation and deactivation + * KVM: Ensure host cr0.ts is saved + * KVM: Set cr0.mp for guests + * KVM: Implement IA32_EBL_CR_POWERON msr + * KVM: MMU: Simplify kvm_mmu_free_page() a tiny bit + * KVM: MMU: Store shadow page tables as kernel virtual addresses, not + physical + * KVM: VMX: Only reload guest msrs if they are already loaded + * KVM: Avoid corrupting tr in real mode + * KVM: Fix vmx I/O bitmap initialization on highmem systems + * KVM: Remove merge artifact + * KVM: VMX: Use local labels in inline assembly + * KVM: VMX: Handle #SS faults from real mode + * KVM: VMX: Avoid saving and restoring msrs on lightweight vmexit + * KVM: VMX: Compile-fix for 32-bit hosts + * KVM: VMX: Cleanup redundant code in MSR set + * KVM: VMX: Fix a typo which mixes X86_64 and CONFIG_X86_64 + * KVM: VMX: Avoid saving and restoring msr_efer on lightweight vmexit + * KVM: VMX: Remove warnings on i386 + * Use menuconfig objects II - KVM/Virt + * KVM: x86 emulator: implement wbinvd + * KVM: Fix includes + * KVM: Use symbolic constants instead of magic numbers + * KVM: MMU: Use slab caches for shadow pages and their headers + * KVM: MMU: Simplify fetch() a little bit + * KVM: MMU: Move set_pte_common() to pte width dependent code + * KVM: MMU: Pass the guest pde to set_pte_common + * KVM: MMU: Fold fix_read_pf() into set_pte_common() + * KVM: MMU: Fold fix_write_pf() into set_pte_common() + * KVM: Move shadow pte modifications from set_pte/set_pde to + set_pde_common() + * KVM: Make shadow pte updates atomic + * KVM: MMU: Make setting shadow ptes atomic on i386 + * KVM: MMU: Remove cr0.wp tricks + * KVM: MMU: Simpify accessed/dirty/present/nx bit handling + * KVM: MMU: Don't cache guest access bits in the shadow page table + * KVM: MMU: Remove unused large page marker + * KVM: VMX: Fix asm constraint + * KVM: Lazy guest cr3 switching + * KVM: Replace C code with call to ARRAY_SIZE() macro. + * KVM: Remove unnecessary initialization and checks in mark_page_dirty() + * KVM: Fix vcpu freeing for guest smp + * KVM: Fix adding an smp virtual machine to the vm list + * KVM: Enable guest smp + * KVM: Move duplicate halt handling code into kvm_main.c + * KVM: Emulate hlt on real mode for Intel + * KVM: Keep an upper bound of initialized vcpus + * KVM: Flush remote tlbs when reducing shadow pte permissions + * KVM: SVM: Replace memset(, 0, PAGESIZE) with clear_page() + * KVM: VMX: Replace memset(, 0, PAGESIZE) with clear_page() + * KVM: Require a cpu which can set 64-bit values atomically + * KVM: Initialize the BSP bit in the APIC_BASE msr correctly + * KVM: VMX: Ensure vcpu time stamp counter is monotonous + * KVM: Bring local tree in line with origin + * KVM: Implement emulation of "pop reg" instruction (opcode 0x58-0x5f) + * KVM: Implement emulation of instruction "ret" (opcode 0xc3) + * KVM: Adds support for in-kernel mmio handlers + * KVM: VMX: Fix interrupt checking on lightweight exit + * KVM: Add support for in-kernel pio handlers + * KVM: Fix x86 emulator writeback + * KVM: Avoid useless memory write when possible + * KVM: VMX: Reinitialize the real-mode tss when entering real mode + * KVM: MMU: Fix Wrong tlb flush order + * KVM: VMX: Remove unnecessary code in vmx_tlb_flush() + * KVM: SVM: Reliably detect if SVM was disabled by BIOS + * KVM: Remove kvmfs in favor of the anonymous inodes source + * KVM: Clean up #includes + * KVM: Fix svm availability check miscompile on i386 + * HOTPLUG: Add CPU_DYING notifier + * HOTPLUG: Adapt cpuset hotplug callback to CPU_DYING + * HOTPLUG: Adapt thermal throttle to CPU_DYING + * SMP: Implement on_cpu() + * KVM: Keep track of which cpus have virtualization enabled + * KVM: Tune hotplug/suspend IPIs + * KVM: Use CPU_DYING for disabling virtualization + * KVM: MMU: Store nx bit for large page shadows + * KVM: Fix *nopage() in kvm_main.c + * KVM: SMP: Add vcpu_id field in struct vcpu + * KVM - add hypercall nr to kvm_run + * KVM:: Future-proof the exit information union ABI + * KVM: In-kernel string pio write support + * KVM: Fix memory slot management functions for guest smp + * KVM: x86 emulator: implement rdmsr and wrmsr + * KVM: Trivial: /dev/kvm interface is no longer experimental. + * KVM: Trivial: Remove unused struct cpu_user_regs declaration + * KVM: Trivial: Make decode_register() static + * KVM: Trivial: Comment spelling may escape grep + * KVM: Trivial: Avoid hardware_disable predeclaration + * KVM: Trivial: Use standard CR0 flags macros from asm/cpu-features.h + * Use standard CR3 flags, tighten checking + * Use standard CR4 flags, tighten checking + * KVM: Trivial: Use standard BITMAP macros, open-code userspace-exposed + header + * KVM: Set exit_reason to KVM_EXIT_MMIO where run->mmio is initialized. + * KVM: Use standard CR8 flags, and fix TPR definition + * KVM: MMU: Fix oopses with SLUB + * KVM: x86 emulator: fix cmov for writeback changes + * KVM: MMU: Fix cleaning up the shadow page allocation cache + * KVM: Require CONFIG_ANON_INODES + * KVM: x86 emulator: fix faulty check for two-byte opcode + * KVM: Correctly handle writes crossing a page boundary + * KVM: Fix unlikely kvm_create vs decache_vcpus_on_cpu race + * KVM: Hoist kvm_mmu_reload() out of the critical section + * KVM: Fix removal of nx capability from guest cpuid + * KVM: Move gfn_to_page out of kmap/unmap pairs + * KVM: disable writeback for 0x0f 0x01 instructions. + * KVM: VMX: Import some constants of vmcs from IA32 SDM + * KVM: Remove dead code in the cmpxchg instruction emulation + * KVM: load_pdptrs() cleanups + * KVM: Remove arch specific components from the general code + * KVM: Dynamically allocate vcpus + * KVM: VMX: Improve the method of writing vmcs control + * KVM: Use the scheduler preemption notifiers to make kvm preemptible + * KVM: Convert vm lock to a mutex + * KVM: fx_init() needs preemption disabled while it plays with the FPU + state + * KVM: VMX: pass vcpu_vmx internally + * KVM: Remove three magic numbers + * KVM: SVM: de-containization + * KVM: SVM: internal function name cleanup + * KVM: x86 emulator: disable writeback for debug register instructions + * KVM: Change the emulator_{read,write,cmpxchg}_* functions to take a + vcpu + * KVM: Remove kvm_{read,write}_guest() + * KVM: Use kmem cache for allocating vcpus + * KVM: Use alignment properties of vcpu to simplify FPU ops + * KVM: kvm_vm_ioctl_get_dirty_log restore "nothing dirty" optimization + * KVM: VMX: Add cpu consistency check + * KVM: Don't assign vcpu->cr3 if it's invalid: check first, set last + * KVM: Cleanup mark_page_dirty + * KVM: SVM: Make set_msr_interception more reliable + * KVM: Remove redundant alloc_vmcs_cpu declaration + * KVM: Fix defined but not used warning in drivers/kvm/vmx.c + * KVM: Remove stat_set from debugfs + * KVM: Remove unneeded kvm_dev_open and kvm_dev_release functions. + * KVM: Add and use pr_unimpl for standard formatting of unimplemented + features + * KVM: Use kmem_cache_free for kmem_cache_zalloc'ed objects + * KVM: VMX: Remove a duplicated ia32e mode vm entry control + * KVM: Remove useless assignment + * KVM: Cleanup string I/O instruction emulation + * KVM: Clean up kvm_setup_pio() + * KVM: VMX: Don't require cr8 load/store exit capability when running on + 32-bit + * KVM: Close minor race in signal handling + * KVM: Communicate cr8 changes to userspace + * KVM: x86 emulator: implement 'and $imm, %{al|ax|eax}' + * KVM: x86 emulator: implement 'jmp rel' instruction (opcode 0xe9) + * KVM: x86 emulator: Implement 'jmp rel short' instruction (opcode 0xeb) + * KVM: x86 emulator: implement 'push reg' (opcodes 0x50-0x57) + * KVM: VMX: allow rmode_tss_base() to work with >2G of guest memory + * KVM: Avoid calling smp_call_function_single() with interrupts disabled + * KVM: MMU: Fix rare oops on guest context switch + * KVM: Support more memory slots + * KVM: X86 emulator: fix 'push reg' writeback + * KVM: VMX: Split segments reload in vmx_load_host_state() + * KVM: Add support for in-kernel PIC emulation + * KVM: Define and use cr8 access functions + * KVM: Emulate local APIC in kernel + * KVM: In-kernel I/O APIC model + * KVM: Emulate hlt in the kernel + * KVM: Protect in-kernel pio using kvm->lock + * KVM: Add get/set irqchip ioctls for in-kernel PIC live migration + support + * KVM: Bypass irq_pending get/set when using in kernel irqchip + * KVM: in-kernel IOAPIC save and restore support + * KVM: in-kernel LAPIC save and restore support + * KVM: pending irq save/restore + * KVM: VMX: Use shadow TPR/cr8 for 64-bits guests + * KVM: Keep track of missed timer irq injections + * KVM: Migrate lapic hrtimer when vcpu moves to another cpu + * KVM: disable tpr/cr8 sync when in-kernel APIC is used + * KVM: VMX: Fix tpr threshold updating + * KVM: deliver PIC interrupt only to vcpu0 + * KVM: round robin for APIC lowest priority delivery mode + * KVM: enable in-kernel APIC INIT/SIPI handling + * KVM: Set the ET flag in CR0 after initializing FX + * KVM: Remove the unused invlpg member of struct kvm_arch_ops. + * KVM: Clean up unloved invlpg emulation + * KVM: Keep control regs in sync + * KVM: Hoist SVM's get_cs_db_l_bits into core code. + * KVM: Simplify memory allocation + * KVM: Rename kvm_arch_ops to kvm_x86_ops + * KVM: Fix lapic 64-bit division on 32-bit hosts + * KVM: fix apic timer migration when inactive + * KVM: MMU: Don't do GFP_NOWAIT allocations + * KVM: Remove smp_processor_id() in kvm_vcpu_kick() + * KVM: VMX: Move vm entry failure handling to the exit handler + * KVM: Move main vcpu loop into subarch independent code + * KVM: Fix link error to "genapic" + * KVM: VMX: Fix exit qualification width on i386 + * KVM: x86 emulator: push imm8 + * KVM: x86 emulator: call near + * KVM: x86 emulator: pushf + * KVM: Improve emulation failure reporting + * KVM: VMX: Prevent setting CPU_BASED_TPR_SHADOW on i386 host + * KVM: x86 emulator: sort opcodes into ascending order + * KVM: x86 emulator: imlpement jump conditional relative + * KVM: X86 emulator: jump conditional short + * KVM: x86 emulator: lea + * KVM: x86 emulator: jmp abs + * KVM: x86 emulator: fix src, dst value initialization + * KVM: x86 emulator: popf + * KVM: Skip pio instruction when it is emulated, not executed + * KVM: fix PIC interrupt delivery on different APIC conditions + * KVM: Fix kvm_vcpu_ioctl_get_sregs() warning on i386 + * KVM: Remove errant printk() in kvm_vcpu_ioctl_get_sregs() + * KVM: Fix virtualization menu help text + * KVM: x86 emulator: Add vmmcall/vmcall to x86_emulate (v3) + * KVM: Refactor hypercall infrastructure (v3) + * KVM: x86 emulator: remove unused functions + * KVM: x86 emulator: move all x86_emulate_memop() to a structure + * KVM: x86 emulator: move all decoding process to function + x86_decode_insn() + * KVM: emulate_instruction() calls now x86_decode_insn() and + x86_emulate_insn() + * KVM: Call x86_decode_insn() only when needed + * KVM: Fix ioapic level-triggered interrupt redelivery + * KVM: Fix #UD exception delivery + * KVM: VMX: Further reduce efer reloads + * KVM: VMX: Fix build on i386 due to EFER_LMA not defined + * KVM: Fix ioapic.c compilation failure due to missing include + * KVM: x86 emulator: fix merge screwup due to emulator split + * KVM: x85 emulator: Correct inconcistency in between cr2 and ctxt->cr2. + * KVM: Avoid redelivery of edge-triggered irq if it is already in service + * KVM: Implement ioapic irq polarity bit + * KVM: x86 emulator: fix repne/repnz decoding + * KVM: Fix host oops due to guest changing efer + * KVM: Fix ioapic edge-triggered interrupts + * KVM: MMU: Set shadow pte atomically in mmu_pte_write_zap_pte() + * KVM: Allow not-present guest page faults to bypass kvm + * KVM: MMU: Make flooding detection work when guest page faults are + bypassed + * KVM: MMU: Ignore reserved bits in cr3 in non-pae mode + * KVM: x86 emulator: split some decoding into functions for readability + * KVM: x86 emulator: remove _eflags and use directly ctxt->eflags. + * KVM: x86 emulator: Remove no_wb, use dst.type = OP_NONE instead + * KVM: x86_emulator: no writeback for bt + * KVM: apic round robin cleanup + * KVM: Purify x86_decode_insn() error case management + * KVM: x86 emulator: Any legacy prefix after a REX prefix nullifies its + effect + * i386: Expose IOAPIC register definitions even if CONFIG_X86_IO_APIC is + not set + * KVM: x86 emulator: On a pop instruction, don't restore ECX and EIP on + error + * KVM: x86 emulator: remove unused variable + * KVM: VMX: Don't clear the vmcs if the vcpu is not loaded on any + processor + * KVM: VMX: Simplify vcpu_clear() + * KVM: Remove the usage of paeg->private field by rmap + * KVM: x86 emulator: Correct management of REP prefix + * KVM: Add general accessors to read and write guest memory + * KVM: Allow dynamic allocation of the mmu shadow cache size + * KVM: Check I/O APIC indirect index before writing + * KVM: Add kvm_free_lapic() to pair with kvm_create_lapic() + * KVM: Hoist kvm_create_lapic() into kvm_vcpu_init() + * KVM: Remove gratuitous casts from lapic.c + * KVM: CodingStyle cleanup + * KVM: VMX: Handle NMIs before enabling interrupts and preemption + * KVM: Support assigning userspace memory to the guest + * KVM: Export PIC reset for kernel device reset + * KVM: Split IOAPIC reset function and export for kernel RESET + * KVM: VMX: Reset mmu context when entering real mode + * KVM: Replace enum by #define + * KVM: Move x86 msr handling to new files x86.[ch] + * KVM: MMU: Clean up MMU functions to take struct kvm when appropriate + * KVM: MMU: More struct kvm_vcpu -> struct kvm cleanups + * KVM: Move guest pte dirty bit management to the guest pagetable walker + * KVM: MMU: Fix nx access bit for huge pages + * KVM: MMU: Disable write access on clean large pages + * KVM: MMU: Instatiate real-mode shadows as user writable shadows + * KVM: MMU: Move dirty bit updates to a separate function + * KVM: MMU: When updating the dirty bit, inform the mmu about it + * KVM: Portability: split kvm_vcpu_ioctl + * KVM: Restore missing #include + * KVM: Add some \n in ioapic_debug() + * KVM: x86 emulator: implement 'movnti mem, reg' + * KVM: MMU: Call update_dirty_bit() without disabling preemption + * KVM: Move apic timer interrupt backlog processing to common code + * KVM: Move interrupt injection out of interrupt disabled section + * KVM: Rename KVM_TLB_FLUSH to KVM_REQ_TLB_FLUSH + * KVM: VMX: Force vm86 mode if setting flags during real mode + * KVM: MMU: Simplify page table walker + * KVM: Actually move the interrupt injection code out of the critical + section + * KVM: x86 emulator: cmc, clc, cli, sti + * KVM: x86 emulator: use a defined flag definition + * KVM: x86 emulator: fix access registers for instructions with ModR/M + byte and Mod = 3 + * KVM: MMU: Add rmap_next(), a helper for walking kvm rmaps + * KVM: MMU: Keep a reverse mapping of non-writable translations + * KVM: MMU: Make gfn_to_page() always safe + * KVM: Partial swapping of guest memory + * KVM: VMX: Initialize vcpu with preemption enabled + * KVM: Use virtual cpu accounting if available for guest times. + * KVM: Move kvm_guest_exit() after local_irq_enable() + * KVM: MMU: Fix dirty bit pte gpa calculation + * KVM: Allocate userspace memory for older userspace + * KVM: Portability: Split kvm_vcpu into arch dependent and independent + parts (part 1) + * KVM: Fix local apic timer divide by zero + * KVM: Move vmx_vcpu_reset() out of vmx_vcpu_setup() + * KVM: Add a might_sleep() annotation to gfn_to_page() + * KVM: VMX: vmx_vcpu_setup(): remove unused variable. + * KVM: Per-architecture hypercall definitions + * KVM: Use new smp_call_function_mask() in kvm_flush_remote_tlbs() + * KVM: Unmap kernel-allocated memory on slot destruction + * KVM: Export memory slot allocation mechanism + * KVM: Add kernel-internal memory slots + * KVM: Add ioctl to tss address from userspace, + * KVM: x86 emulator: fix 'push imm8' emulation + * KVM: VMX: Let gcc to choose which registers to save (x86_64) + * KVM: VMX: Let gcc to choose which registers to save (i386) + * KVM: SVM: Let gcc to choose which registers to save (x86_64) + * KVM: SVM: Let gcc to choose which registers to save (i386) + * KVM: x86 emulator: invd instruction + * KVM: SVM: Intercept the 'invd' and 'wbinvd' instructions + * KVM: x86 emulator: don't depend on cr2 for mov abs emulation + * KVM: Move page fault processing to common code + * KVM: MMU: Topup the mmu memory preallocation caches before emulating an + insn + * KVM: Portability: Split kvm_vm_ioctl v3 + * KVM: Portability: Move memory segmentation to x86.c + * KVM: Portability: move get/set_apic_base to x86.c + * KVM: Portability: Move control register helper functions to x86.c + * KVM: VMX: Enable memory mapped TPR shadow (FlexPriority) + * KVM: Fix gfn_to_page() acquiring mmap_sem twice + * KVM: Portability: Move kvm_get/set_msr[_common] to x86.c + * KVM: Portability: Move x86 emulation and mmio device hook to x86.c + * KVM: Portability: Move pio emulation functions to x86.c + * KVM: x86 emulator: Extract the common code of SrcReg and DstReg + * KVM: x86 emulator: centralize decoding of one-byte register access + insns + * KVM: Simplify decode_register_operand() calling convention + * KVM: Make mark_page_dirty() work for aliased pages too. + * KVM: x86 emulator: Hoist modrm and abs decoding into separate functions + * KVM: Portability: Make exported debugfs data architecture-specific + * KVM: Portability: Move x86 instruction emulation code to x86.c + * KVM: Portability: Move x86 FPU handling to x86.c + * KVM: Portability: Move x86 vcpu ioctl handlers to x86.c + * KVM: x86 emulator: Move one-byte insns with reg operand into one-byte + section + * KVM: VMX: Fix repeated allocation of apic access page on smp + * KVM: SVM: Fix SMP with kernel apic + * KVM: Add make_page_dirty() to kvm_clear_guest_page() + * KVM: SVM: Defer nmi processing until switch to host state is complete + * KVM: VMX: Avoid reloading host efer on cpus that don't have it + * KVM: VMX: Use vmx to inject real interrupts + * KVM: Go back to atomically injecting interrupts + * KVM: VMX: Comment VMX primary/secondary exec ctl definitions + * KVM: VMX: wbinvd exiting + * KVM: x86 emulator: fix JMP_REL + * KVM: x86 emulator: fix the saving of of the eip value + * KVM: x86 emulator: remove 8 bytes operands emulator for call near + instruction + * KVM: Simplify CPU_TASKS_FROZEN cpu notifier handling + * KVM: add kvm_is_error_hva() + * KVM: introduce gfn_to_hva() + * KVM: Change kvm_{read,write}_guest() to use copy_{from,to}_user() + * KVM: Portability: Move some includes to x86.c + * KVM: Portability: Move kvm_x86_ops to x86.c + * KVM: Portability: Add vcpu and hardware management arch hooks + * KVM: Portability: Combine kvm_init and kvm_init_x86 + * KVM: Portability: Move x86 specific code from kvm_init() to kvm_arch() + * KVM: x86 emulator: modify 'lods', and 'stos' not to depend on CR2 + * KVM: Portability: move KVM_CHECK_EXTENSION + * KVM: VMX: Consolidate register usage in vmx_vcpu_run() + * KVM: Portability: Make kvm_vcpu_ioctl_translate arch dependent + * KVM: x86 emulator: Rename 'cr2' to 'memop' + * KVM: Remove ptr comparisons to 0 + * KVM: Remove __init attributes for kvm_init_debug and kvm_init_msr_list + * KVM: Portability: Add two hooks to handle kvm_create and destroy vm + * KVM: Replace 'light_exits' stat with 'host_state_reload' + * KVM: Add fpu_reload counter + * KVM: Add instruction emulation statistics + * KVM: Extend stats support for VM stats + * KVM: MMU: Add some mmu statistics + * KVM: x86 emulator: Use emulator_write_emulated and not + emulator_write_std + * KVM: Make unloading of FPU state when putting vcpu arch-independent + * KVM: SVM: Disable Lazy FPU optimization + * KVM: Portability: Move kvm_vcpu_ioctl_get_dirty_log to arch-specific + file + * KVM: Portability: MMU initialization and teardown split + * KVM: Portability: Move some macro definitions from kvm.h to x86.h + * KVM: Portability: Move struct kvm_x86_ops definition to x86.h + * KVM: Portability: Move vcpu regs enumeration definition to x86.h + * KVM: Move some static inline functions out from kvm.h into x86.h + * KVM: Portability: Move some function declarations to x86.h + * KVM: VMX: Force seg.base == (seg.sel << 4) in real mode + * KVM: MMU: Change guest pte access to kvm_{read,write}_guest() + * kvm: simplify kvm_clear_guest_page() + * KVM: Add missing #include + * KVM: MMU: Remove unused variable + * KVM: Remove unused "rmap_overflow" variable + * KVM: Correct consistent typo: "destory" -> "destroy" + * KVM: Move misplaced comment + * KVM: Portability: Move kvm_memory_alias to asm/kvm.h + * KVM: Portability: Move x86 pic strutctures + * KVM: Portability: Move kvm_regs to + * KVM: Portability: Move structure lapic_state to + * KVM: Portability: Move kvm_segment & kvm_dtable structure to + + * KVM: Portability: Move kvm_sregs and msr structures to + * KVM: Portability: Move cpuid structures to + * KVM: Export include/asm-x86/kvm.h + * KVM: MMU: Fix potential memory leak with smp real-mode + * KVM: MMU: Selectively set PageDirty when releasing guest memory + * KVM: x86 emulator: retire ->write_std() + * KVM: x86 emulator: prefetch up to 15 bytes of the instruction executed + * KVM: SVM: Fix FPU leak and re-enable lazy FPU switching + * KVM: Recalculate mmu pages needed for every memory region change + * KVM: Portability: Split kvm_set_memory_region() to have an arch + callout + * KVM: Split vcpu creation to avoid vcpu_load() before preemption setup + * KVM: MMU: Implement guest page fault bypass for nonpae + * KVM: Add statistic for remote tlb flushes + * KVM: MMU: Avoid unnecessary remote tlb flushes when guest updates a pte + * KVM: Add parentheses to silence gcc + * KVM: Don't bother the mmu if cr3 load doesn't change cr3 + * KVM: MMU: Code cleanup + * KVM: MMU: Introduce and use gpte_to_gfn() + * KVM: MMU: Move pse36 handling to the guest walker + * KVM: MMU: Remove extra gaddr parameter from set_pte_common() + * KVM: MMU: Remove set_pde() + * KVM: MMU: Adjust page_header_update_slot() to accept a gfn instead of a + gpa + * KVM: MMU: Introduce gfn_to_gpa() + * KVM: MMU: Simplify nonpaging_map() + * KVM: MMU: Remove gva_to_hpa() + * KVM: Remove gpa_to_hpa() + * KVM: MMU: Rename variable of type 'struct kvm_mmu_page *' + * KVM: MMU: Rename 'release_page' + * KVM: Disallow fork() and similar games when using a VM + * KVM: Enhance guest cpuid management + * KVM: Replace private 'struct segment descriptor' by x86's desc_struct + * KVM: Remove segment_descriptor, part 2 + * KVM: Fix compile error on i386 + * KVM: VMX: Read & store IDT_VECTORING_INFO_FIELD + * KVM: Fix faults during injection of real-mode interrupts + * KVM: x86 emulator: Fix instruction fetch cache hit check + * KVM: VMX: Remove the secondary execute control dependency on irqchip + * KVM: Portability: Move unalias_gfn to arch dependent file + * KVM: x86 emulator: Make a distinction between repeat prefixes F3 and F2 + * KVM: x86 emulator: address size and operand size overrides are sticky + * KVM: Remove desc.h include in kvm_main.c + * KVM: Revert segment_descriptor.h removal + * KVM: Remove misleading check for mmio during event injection + * KVM: MMU: mark pages that were inserted to the shadow pages table as + accessed + * KVM: x86 emulator: rename REP_REPE_PREFIX + * KVM: x86 emulator: cmps instruction + * KVM: Add ifdef in irqchip struct for x86 only structures + * KVM: Fix cpuid2 killing 32-bit guests on non-NX machines + * KVM: x86 emulator: Move rep processing before instruction execution + * KVM: x86 emulator: unify two switches + * KVM: x86 emulator: unify four switch statements into two + * KVM: Don't bypass the mmu if in pae and pdptrs changed + * KVM: Portability: Move KVM_INTERRUPT vcpu ioctl to x86.c + * KVM: Correct kvm_init() error paths not freeing bad_pge. + * KVM: Export include/linux/kvm.h only if $ARCH actually supports KVM + * KVM: SVM: Remove KVM specific defines for MSR_EFER + * KVM: Replace kvm_lapic with kvm_vcpu in ioapic/lapic interface + * KVM: Replace dest_Lowest_Prio and dest_Fixed with self-defined macros + * KVM: Extend ioapic code to support iosapic + * KVM: Portability: Move address types to their own header file + * KVM: Portability: Move IO device definitions to its own header file + * KVM: Portability: Stop including x86-specific headers in kvm_main.c + * KVM: Portability: Create kvm_arch_vcpu_runnable() function + * KVM: Convert KVM from ->nopage() to ->fault() + * KVM: MMU: Remove unused prev_shadow_ent variable from fetch() + * KVM: Generalize exception injection mechanism + * KVM: Replace page fault injection by the generalized exception queue + * KVM: Replace #GP injection by the generalized exception queue + * KVM: Use generalized exception queue for injecting #UD + * KVM: x86 emulator: fix eflags preparation for emulation + * KVM: VMX: Avoid exit when setting cr8 if the local apic is in the + kernel + * KVM: SVM: Emulate read/write access to cr8 + * KVM: x86 emulator: Fix stack instructions on 64-bit mode + * KVM: SVM: Trap access to the cr8 register + * KVM: VMX: Fix cr8 exit optimization + * KVM: MMU: Use cmpxchg for pte updates on walk_addr() + * KVM: MMU: Simplify calculation of pte access + * KVM: MMU: Set nx bit correctly on shadow ptes + * KVM: MMU: Move pte access calculation into a helper function + * KVM: MMU: Fix inherited permissions for emulated guest pte updates + * KVM: MMU: No need to pick up nx bit from guest pte + * KVM: MMU: Pass pte dirty flag to set_pte() instead of calculating it + on-site + * KVM: MMU: Remove walker argument to set_pte() + * KVM: MMU: Move set_pte() into guest paging mode independent code + * KVM: MMU: Adjust mmu_set_spte() debug code for gpte removal + * KVM: MMU: Use mmu_set_spte() for real-mode shadows + * KVM: SVM: Exit to userspace if write to cr8 and not using in-kernel + apic + * KVM: SVM: support writing 0 to K8 performance counter control registers + * KVM: MMU: Fix kunmap_atomic() call in cmpxchg_gpte() + * KVM: MMU: Fix SMP shadow instantiation race + * KVM: LAPIC: minor debugging compile fix + * KVM: MMU: emulated cmpxchg8b should be atomic on i386 + * KVM: Fix bad kunmap_atomic() paramerter inm cmpxchg emulation + * KVM: Make cmpxchg emulation compile on i386 + * KVM: Another cmpxchg i386 compile fix + * KVM: Another cmpxchg emulation compile fix + * KVM: Another cmpxchg emulation compile fix + * KVM: Portability: Move kvm{pic,ioapic} accesors to x86 specific code + * KVM: Portability: Introduce kvm_vcpu_arch + * KVM: Portability: Split mmu-related static inline functions to mmu.h + * KVM: Portability: Move kvm_vcpu definition back to kvm.h + * KVM: Portability: Expand the KVM_VCPU_COMM in kvm_vcpu structure. + * KVM: Portability: Move kvm_vcpu_stat to x86.h + * KVM: Portability: Move memslot aliases to new struct kvm_arch + * KVM: Portability: Move mmu-related fields to kvm_arch + * KVM: Portability: move vpic and vioapic to kvm_arch + * KVM: Portability: Move round_robin_prev_vcpu and tss_addr to kvm_arch + * KVM: Portability: Move kvm_vm_stat to x86.h + * KVM: VMX: Add printk_ratelimit in vmx_intr_assist + * KVM: Move arch dependent files to new directory arch/x86/kvm/ + * KVM: Move drivers/kvm/* to virt/kvm/ + * KVM: Fix compile error in asm/kvm_host.h + * KVM: Move irqchip declarations into new ioapic.h and lapic.h + * KVM: Move ioapic code to common directory. + * KVM: Move kvm_vcpu_kick() to x86.c + * KVM: Expose ioapic to ia64 save/restore APIs + * KVM: MMU: Coalesce remote tlb flushes + * KVM: MMU: Add cache miss statistic + * KVM: Print data for unimplemented wrmsr + * KVM: Ensure pages are copied on write + * KVM: MMU: Fix cmpxchg8b emulation on i386 (again) + * KVM: x86 emulator: Add vmmcall/vmcall to x86_emulate (v3) + * KVM: Refactor hypercall infrastructure (v3) + * KVM: x86 emulator: remove unused functions + * KVM: x86 emulator: move all x86_emulate_memop() to a structure + * KVM: x86 emulator: move all decoding process to function + x86_decode_insn() + * KVM: emulate_instruction() calls now x86_decode_insn() and + x86_emulate_insn() + * KVM: Call x86_decode_insn() only when needed + * KVM: VMX: Further reduce efer reloads + * KVM: Allow not-present guest page faults to bypass kvm + * KVM: MMU: Make flooding detection work when guest page faults are + bypassed + * KVM: MMU: Ignore reserved bits in cr3 in non-pae mode + * KVM: x86 emulator: split some decoding into functions for readability + * KVM: x86 emulator: remove _eflags and use directly ctxt->eflags. + * KVM: x86 emulator: Remove no_wb, use dst.type = OP_NONE instead + * KVM: x86_emulator: no writeback for bt + * KVM: Purify x86_decode_insn() error case management + * KVM: x86 emulator: Any legacy prefix after a REX prefix nullifies its + effect + * KVM: VMX: Don't clear the vmcs if the vcpu is not loaded on any + processor + * KVM: VMX: Simplify vcpu_clear() + * KVM: Remove the usage of page->private field by rmap + * KVM: Add general accessors to read and write guest memory + * KVM: Allow dynamic allocation of the mmu shadow cache size + * KVM: Add kvm_free_lapic() to pair with kvm_create_lapic() + * KVM: Hoist kvm_create_lapic() into kvm_vcpu_init() + * KVM: Remove gratuitous casts from lapic.c + * KVM: CodingStyle cleanup + * KVM: Support assigning userspace memory to the guest + * KVM: Move x86 msr handling to new files x86.[ch] + * KVM: MMU: Clean up MMU functions to take struct kvm when appropriate + * KVM: MMU: More struct kvm_vcpu -> struct kvm cleanups + * KVM: Move guest pte dirty bit management to the guest pagetable walker + * KVM: MMU: Fix nx access bit for huge pages + * KVM: MMU: Disable write access on clean large pages + * KVM: MMU: Instantiate real-mode shadows as user writable shadows + * KVM: MMU: Move dirty bit updates to a separate function + * KVM: MMU: When updating the dirty bit, inform the mmu about it + * KVM: Portability: split kvm_vcpu_ioctl + * KVM: apic round robin cleanup + * KVM: Add some \n in ioapic_debug() + * KVM: Move apic timer interrupt backlog processing to common code + * KVM: Rename KVM_TLB_FLUSH to KVM_REQ_TLB_FLUSH + * KVM: x86 emulator: Implement emulation of instruction: inc & dec + * KVM: MMU: Simplify page table walker + * KVM: x86 emulator: cmc, clc, cli, sti + * KVM: MMU: Add rmap_next(), a helper for walking kvm rmaps + * KVM: MMU: Keep a reverse mapping of non-writable translations + * KVM: MMU: Make gfn_to_page() always safe + * KVM: MMU: Partial swapping of guest memory + * KVM: Use virtual cpu accounting if available for guest times. + * KVM: Allocate userspace memory for older userspace + * KVM: Portability: Split kvm_vcpu into arch dependent and independent + parts (part 1) + * KVM: Move vmx_vcpu_reset() out of vmx_vcpu_setup() + * KVM: Add a might_sleep() annotation to gfn_to_page() + * KVM: Export PIC reset for kernel device reset + * KVM: Split IOAPIC reset function and export for kernel RESET + * KVM: Per-architecture hypercall definitions + * KVM: Unmap kernel-allocated memory on slot destruction + * KVM: Export memory slot allocation mechanism + * KVM: Add kernel-internal memory slots + * KVM: Add ioctl to tss address from userspace, + * KVM: VMX: Let gcc to choose which registers to save (x86_64) + * KVM: VMX: Let gcc to choose which registers to save (i386) + * KVM: SVM: Let gcc to choose which registers to save (x86_64) + * KVM: SVM: Let gcc to choose which registers to save (i386) + * KVM: x86 emulator: don't depend on cr2 for mov abs emulation + * KVM: Move page fault processing to common code + * KVM: MMU: Topup the mmu memory preallocation caches before emulating an + insn + * KVM: Portability: Split kvm_vm_ioctl v3 + * KVM: Portability: Move memory segmentation to x86.c + * KVM: Portability: move get/set_apic_base to x86.c + * KVM: Portability: Move control register helper functions to x86.c + * KVM: VMX: Enable memory mapped TPR shadow (FlexPriority) + * KVM: Fix gfn_to_page() acquiring mmap_sem twice + * KVM: Portability: Move kvm_get/set_msr[_common] to x86.c + * KVM: Portability: Move x86 emulation and mmio device hook to x86.c + * KVM: Portability: Move pio emulation functions to x86.c + * KVM: x86 emulator: Extract the common code of SrcReg and DstReg + * KVM: x86 emulator: centralize decoding of one-byte register access + insns + * KVM: Simplify decode_register_operand() calling convention + * KVM: Make mark_page_dirty() work for aliased pages too. + * KVM: x86 emulator: Hoist modrm and abs decoding into separate functions + * KVM: Portability: Make exported debugfs data architecture-specific + * KVM: Portability: Move x86 instruction emulation code to x86.c + * KVM: Portability: Move x86 FPU handling to x86.c + * KVM: Portability: Move x86 vcpu ioctl handlers to x86.c + * KVM: Add make_page_dirty() to kvm_clear_guest_page() + * KVM: VMX: Use vmx to inject real-mode interrupts + * KVM: VMX: Read & store IDT_VECTORING_INFO_FIELD + * KVM: Fix faults during injection of real-mode interrupts + * KVM: VMX: Comment VMX primary/secondary exec ctl definitions + * KVM: VMX: wbinvd exiting + * KVM: x86 emulator: remove 8 bytes operands emulator for call near + instruction + * KVM: Simplify CPU_TASKS_FROZEN cpu notifier handling + * KVM: add kvm_is_error_hva() + * KVM: introduce gfn_to_hva() + * KVM: Change kvm_{read,write}_guest() to use copy_{from,to}_user() + * KVM: Portability: Move some includes to x86.c + * KVM: Portability: Move kvm_x86_ops to x86.c + * KVM: Portability: Add vcpu and hardware management arch hooks + * KVM: Portability: Combine kvm_init and kvm_init_x86 + * KVM: Portability: Move x86 specific code from kvm_init() to kvm_arch() + * KVM: x86 emulator: modify 'lods', and 'stos' not to depend on CR2 + * KVM: Portability: move KVM_CHECK_EXTENSION + * KVM: VMX: Consolidate register usage in vmx_vcpu_run() + * KVM: Portability: Make kvm_vcpu_ioctl_translate arch dependent + * KVM: Remove ptr comparisons to 0 + * KVM: Remove __init attributes for kvm_init_debug and kvm_init_msr_list + * KVM: Portability: Add two hooks to handle kvm_create and destroy vm + * KVM: Replace 'light_exits' stat with 'host_state_reload' + * KVM: Add fpu_reload counter + * KVM: Add instruction emulation statistics + * KVM: Extend stats support for VM stats + * KVM: MMU: Add some mmu statistics + * KVM: Make unloading of FPU state when putting vcpu arch-independent + * KVM: Portability: Move kvm_vcpu_ioctl_get_dirty_log to arch-specific + file + * KVM: Portability: MMU initialization and teardown split + * KVM: Portability: Move some macro definitions from kvm.h to x86.h + * KVM: Portability: Move struct kvm_x86_ops definition to x86.h + * KVM: Portability: Move vcpu regs enumeration definition to x86.h + * KVM: Move some static inline functions out from kvm.h into x86.h + * KVM: Portability: Move some function declarations to x86.h + * KVM: VMX: Force seg.base == (seg.sel << 4) in real mode + * KVM: MMU: Change guest pte access to kvm_{read,write}_guest() + * KVM: Simplify kvm_clear_guest_page() + * KVM: Add missing #include + * KVM: MMU: Remove unused variable + * KVM: Remove unused "rmap_overflow" variable + * KVM: Correct consistent typo: "destory" -> "destroy" + * KVM: Move misplaced comment + * KVM: Portability: Move kvm_memory_alias to asm/kvm.h + * KVM: Portability: Move x86 pic strutctures + * KVM: Portability: Move kvm_regs to + * KVM: Portability: Move structure lapic_state to + * KVM: Portability: Move kvm_segment & kvm_dtable structure to + + * KVM: Portability: Move kvm_sregs and msr structures to + * KVM: Portability: Move cpuid structures to + * KVM: Export include/asm-x86/kvm.h + * KVM: MMU: Fix potential memory leak with smp real-mode + * KVM: MMU: Selectively set PageDirty when releasing guest memory + * KVM: x86 emulator: retire ->write_std() + * KVM: x86 emulator: prefetch up to 15 bytes of the instruction executed + * KVM: Recalculate mmu pages needed for every memory region change + * KVM: Portability: Split kvm_set_memory_region() to have an arch + callout + * KVM: Split vcpu creation to avoid vcpu_load() before preemption setup + * KVM: MMU: Implement guest page fault bypass for nonpae + * KVM: Add statistic for remote tlb flushes + * KVM: MMU: Avoid unnecessary remote tlb flushes when guest updates a pte + * KVM: Don't bother the mmu if cr3 load doesn't change cr3 + * KVM: MMU: Code cleanup + * KVM: MMU: Introduce and use gpte_to_gfn() + * KVM: MMU: Move pse36 handling to the guest walker + * KVM: MMU: Remove extra gaddr parameter from set_pte_common() + * KVM: MMU: Remove set_pde() + * KVM: MMU: Adjust page_header_update_slot() to accept a gfn instead of a + gpa + * KVM: MMU: Introduce gfn_to_gpa() + * KVM: MMU: Simplify nonpaging_map() + * KVM: MMU: Remove gva_to_hpa() + * KVM: Remove gpa_to_hpa() + * KVM: MMU: Rename variables of type 'struct kvm_mmu_page *' + * KVM: MMU: Rename 'release_page' + * KVM: Disallow fork() and similar games when using a VM + * KVM: Enhance guest cpuid management + * KVM: VMX: Remove the secondary execute control dependency on irqchip + * KVM: Portability: Move unalias_gfn to arch dependent file + * KVM: x86 emulator: Make a distinction between repeat prefixes F3 and F2 + * KVM: x86 emulator: address size and operand size overrides are sticky + * KVM: Remove misleading check for mmio during event injection + * KVM: MMU: mark pages that were inserted to the shadow pages table as + accessed + * KVM: x86 emulator: rename REP_REPE_PREFIX + * KVM: x86 emulator: Rename 'cr2' to 'memop' + * KVM: x86 emulator: cmps instruction + * KVM: Add ifdef in irqchip struct for x86 only structures + * KVM: Fix cpuid2 killing 32-bit guests on non-NX machines + * KVM: x86 emulator: Move rep processing before instruction execution + * KVM: x86 emulator: unify two switches + * KVM: x86 emulator: unify four switch statements into two + * KVM: Portability: Move KVM_INTERRUPT vcpu ioctl to x86.c + * KVM: Correct kvm_init() error paths not freeing bad_pge. + * KVM: Export include/linux/kvm.h only if $ARCH actually supports KVM + * KVM: SVM: Remove KVM specific defines for MSR_EFER + * KVM: Replace kvm_lapic with kvm_vcpu in ioapic/lapic interface + * KVM: Replace dest_Lowest_Prio and dest_Fixed with self-defined macros + * KVM: Extend ioapic code to support iosapic + * KVM: Portability: Move address types to their own header file + * KVM: Portability: Move IO device definitions to its own header file + * KVM: Portability: Stop including x86-specific headers in kvm_main.c + * KVM: Portability: Create kvm_arch_vcpu_runnable() function + * KVM: Convert KVM from ->nopage() to ->fault() + * KVM: MMU: Remove unused prev_shadow_ent variable from fetch() + * KVM: Generalize exception injection mechanism + * KVM: Replace page fault injection by the generalized exception queue + * KVM: Replace #GP injection by the generalized exception queue + * KVM: Use generalized exception queue for injecting #UD + * KVM: x86 emulator: fix eflags preparation for emulation + * KVM: VMX: Avoid exit when setting cr8 if the local apic is in the + kernel + * KVM: SVM: Emulate read/write access to cr8 + * KVM: x86 emulator: Fix stack instructions on 64-bit mode + * KVM: SVM: Trap access to the cr8 register + * KVM: VMX: Fix cr8 exit optimization + * KVM: MMU: Use cmpxchg for pte updates on walk_addr() + * KVM: MMU: Simplify calculation of pte access + * KVM: MMU: Set nx bit correctly on shadow ptes + * KVM: MMU: Move pte access calculation into a helper function + * KVM: MMU: Fix inherited permissions for emulated guest pte updates + * KVM: MMU: No need to pick up nx bit from guest pte + * KVM: MMU: Pass pte dirty flag to set_pte() instead of calculating it + on-site + * KVM: MMU: Remove walker argument to set_pte() + * KVM: MMU: Move set_pte() into guest paging mode independent code + * KVM: MMU: Adjust mmu_set_spte() debug code for gpte removal + * KVM: MMU: Use mmu_set_spte() for real-mode shadows + * KVM: SVM: Exit to userspace if write to cr8 and not using in-kernel + apic + * KVM: MMU: Fix SMP shadow instantiation race + * KVM: LAPIC: minor debugging compile fix + * KVM: SVM: support writing 0 to K8 performance counter control registers + * KVM: MMU: emulated cmpxchg8b should be atomic on i386 + * KVM: Portability: Move kvm{pic,ioapic} accesors to x86 specific code + * KVM: Portability: Introduce kvm_vcpu_arch + * KVM: Portability: Split mmu-related static inline functions to mmu.h + * KVM: Portability: Move kvm_vcpu definition back to kvm.h + * KVM: Portability: Expand the KVM_VCPU_COMM in kvm_vcpu structure. + * KVM: Portability: Move kvm_vcpu_stat to x86.h + * KVM: Portability: Move memslot aliases to new struct kvm_arch + * KVM: Portability: Move mmu-related fields to kvm_arch + * KVM: Portability: move vpic and vioapic to kvm_arch + * KVM: Portability: Move round_robin_prev_vcpu and tss_addr to kvm_arch + * KVM: Portability: Move kvm_vm_stat to x86.h + * KVM: VMX: Add printk_ratelimit in vmx_intr_assist + * KVM: Move arch dependent files to new directory arch/x86/kvm/ + * KVM: Move drivers/kvm/* to virt/kvm/ + * KVM: Move irqchip declarations into new ioapic.h and lapic.h + * KVM: Move ioapic code to common directory. + * KVM: Move kvm_vcpu_kick() to x86.c + * KVM: Expose ioapic to ia64 save/restore APIs + * KVM: MMU: Coalesce remote tlb flushes + * KVM: MMU: Add cache miss statistic + * KVM: Print data for unimplemented wrmsr + * KVM: Ensure pages are copied on write + * KVM: local APIC TPR access reporting facility + * KVM: Accelerated apic support + * KVM: Disable vapic support on Intel machines with FlexPriority + * KVM: MMU: Concurrent guest walkers + * KVM: Add kvm_read_guest_atomic() + * KVM: MMU: Avoid calling gfn_to_page() in mmu_set_spte() + * KVM: MMU: Switch to mmu spinlock + * KVM: MMU: Move kvm_free_some_pages() into critical section + * KVM: MMU: Broaden scope of mmap_sem to include actual mapping + * KVM: MMU: Fix recursive locking of mmap_sem() + * KVM: Fix unbalanced mmap_sem operations in cmpxchg8b emulation + * KVM: Mark vapic page as dirty for save/restore/migrate + * KVM: x86 emulator: Only allow VMCALL/VMMCALL trapped by #UD + * KVM: MMU: Update shadow ptes on partial guest pte writes + * KVM: MMU: Simplify hash table indexing + * KVM: Portability: Move kvm_fpu to asm-x86/kvm.h + * KVM: MMU: Fix dirty page setting for pages removed from rmap + * KVM: Initialize the mmu caches only after verifying cpu support + * KVM: Fix unbounded preemption latency + * KVM: Put kvm_para.h include outside __KERNEL__ + * KVM: Move apic timer migration away from critical section + * KVM: SVM: Fix lazy FPU switching + * KVM: MMU: Fix gpa truncation when reading a pte + * [GFS2] Handle multiple glock demote requests + * [GFS2] Clean up internal read function + * [GFS2] Use ->page_mkwrite() for mmap() + * [GFS2] Remove useless i_cache from inodes + * [GFS2] Remove unused field in struct gfs2_inode + * [GFS2] Add gfs2_is_writeback() + * [GFS2] Introduce gfs2_set_aops() + * [GFS2] Split gfs2_writepage into three cases + * [GFS2] Add writepages for GFS2 jdata + * [GFS2] Don't hold page lock when starting transaction + * [GFS2] Use correct include file in ops_address.c + * [GFS2] Remove unused variables + * [GFS2] Remove "reclaim limit" + * [GFS2] Add sync_page to metadata address space operations + * [GFS2] Reorder writeback for glock sync + * [GFS2] Remove flags no longer required + * [GFS2] Given device ID rather than s_id in "id" sysfs file + * [GFS2] check kthread_should_stop when waiting + * [GFS2] Don't add glocks to the journal + * [GFS2] Use atomic_t for journal free blocks counter + * [GFS2] Move gfs2_logd into log.c + * [GFS2] Don't periodically update the jindex + * [GFS2] Check for installation of mount helpers for DLM mounts + * [GFS2] tidy up error message + * [GFS2] Fix runtime issue with UP kernels + * [GFS2] remove unnecessary permission checks + * [GFS2] Fix build warnings + * [GFS2] Remove unrequired code + * [GFS2] Remove lock methods for lock_nolock protocol + * [GFS2] patch to check for recursive lock requests in gfs2_rename code + path + * [GFS2] Remove unused variable + * [GFS2] use pid for plock owner for nfs clients + * [GFS2] Remove function gfs2_get_block + * [GFS2] Journal extent mapping + * [GFS2] Get rid of useless "found" variable in quota.c + * [GFS2] Run through full bitmaps quicker in gfs2_bitfit + * [GFS2] Reorganize function gfs2_glmutex_lock + * [GFS2] Only fetch the dinode once in block_map + * [GFS2] Function meta_read optimization + * [GFS2] Incremental patch to fix compiler warning + * [GFS2] Eliminate the no longer needed sd_statfs_mutex + * [GFS2] Minor correction + * [GFS2] Fix log block mapper + * [GFS2] Remove unused variable + * [GFS2] Allow page migration for writeback and ordered pages + * [GFS2] Initialize extent_list earlier + * [GFS2] Fix problems relating to execution of files on GFS2 + * [GFS2] Fix assert in log code + * [GFS2] Reduce inode size by moving i_alloc out of line + * [GFS2] Remove unneeded i_spin + * [GFS2] gfs2_alloc_required performance + * [GFS2] Fix write alloc required shortcut calculation + * [GFS2] Fix typo + * [GFS2] Fix page_mkwrite truncation race path + * [GFS2] Lockup on error + * [GFS2] Allow journal recovery on read-only mount + + -- Tim Gardner Sun, 27 Jan 2008 20:37:18 -0700 + +linux (2.6.24-5.9) hardy; urgency=low + + [Amit Kucheria] + + * Fix LPIA FTBFS due to virtio Ignore: yes + + [Upstream Kernel Changes] + + * ACPI: processor: Fix null pointer dereference in throttling + * [SPARC64]: Fix of section mismatch warnings. + * [SPARC64]: Fix section error in sparcspkr + * [SPARC]: Constify function pointer tables. + * [BLUETOOTH]: Move children of connection device to NULL before + connection down. + * [TULIP] DMFE: Fix SROM parsing regression. + * [IPV4]: Add missing skb->truesize increment in ip_append_page(). + * iwlwifi: fix possible read attempt on ucode that is not available + * [NETNS]: Re-export init_net via EXPORT_SYMBOL. + * [INET]: Fix truesize setting in ip_append_data + * sis190: add cmos ram access code for the SiS19x/968 chipset pair + * sis190: remove duplicate INIT_WORK + * sis190: mdio operation failure is not correctly detected + * sis190: scheduling while atomic error + * Update ctime and mtime for memory-mapped files + * [SCSI] initio: fix module hangs on loading + * xen: disable vcpu_info placement for now + * agp/intel: add support for E7221 chipset + * drm/i915: add support for E7221 chipset + * DMI: move dmi_available declaration to linux/dmi.h + * DMI: create dmi_get_slot() + * ACPI: create acpi_dmi_dump() + * ACPI: on OSI(Linux), print needed DMI rather than requesting dmidecode + output + * ACPI: Delete Intel Customer Reference Board (CRB) from OSI(Linux) DMI + list + * ACPI: make _OSI(Linux) console messages smarter + * ACPI: Add ThinkPad R61, ThinkPad T61 to OSI(Linux) white-list + * ACPI: DMI blacklist to reduce console warnings on OSI(Linux) systems. + * ACPI: EC: fix dmesg spam regression + * ACPI: EC: add leading zeros to debug messages + * Pull bugzilla-9747 into release branch + * Pull bugzilla-8459 into release branch + * Pull bugzilla-9798 into release branch + * Pull dmi-2.6.24 into release branch + * [SPARC64]: Partially revert "Constify function pointer tables." + * lockdep: fix kernel crash on module unload + * sysctl: kill binary sysctl KERN_PPC_L2CR + * fix hugepages leak due to pagetable page sharing + * spi: omap2_mcspi PIO RX fix + * Linux 2.6.24 + + -- Tim Gardner Fri, 25 Jan 2008 01:44:27 -0700 + +linux (2.6.24-5.8) hardy; urgency=low + + [Alessio Igor Bogani] + + * rt: Update to 2.6.24-rc8-rt1 + * rt: Update configuration files + + [Amit Kucheria] + + * Asix: fix breakage caused in 2.6.24-rc7 + * Add CONFIG_CPUSETS to server-related flavours + - LP: #182434 + + [Chuck Short] + + * SAUCE: ata: blacklist FUJITSU MHW2160BH PL + - LP: #175834 + + [Kees Cook] + + * AppArmor: updated patch series to upstream SVN 1079. + + [Soren Hansen] + + * Updated configs to enable virtio stuff Ignore: yes + + [Stefan Bader] + + * Enabled CONFIG_BSD_PROCESS_ACCT=y for sparc. + - LP: #176587 + * Enable CONFIG_AUDITSYSCALL=y. + - LP: #140784 + * Added CONFIG_AUDIT_SYSCALL=y to custom lpia(compat) + * Enabled CONFIG_HUGETLBFS=y for i386/server amd64/server and ia64. + * Lower priority of pnpacpi resource messages to warning level. + - LP: #159241 + * Fix the messed up message level of pnpacpi parser. + + [Tim Gardner] + + * Start new release, bump ABI to -5 + * Disabled iwlwifi preperatory to moving it to l-u-m. + * Enabled CONFIG_USB_SERIAL_KEYSPAN + * Disabled CONFIG_CGROUPS. + * Virtio config settings for -rt. + * Re-enable IWLWIFI in the kernel. + * Fixed -rt saa7134-core.c FTBS + + [Upstream Kernel Changes] + + * Input: Handle EV_PWR type of input caps in input_set_capability. + * Input: jornada680_kbd - fix default keymap + * increase PNP_MAX_PORT to 40 from 24 + * sched: fix gcc warnings + * leds: Fix leds_list_lock locking issues + * leds: Fix locomo LED driver oops + * x86: fix asm-x86/byteorder.h for userspace export + * x86: fix asm-x86/msr.h for user-space export + * ACPI: EC: Enable boot EC before bus_scan + * ACPI: Make sysfs interface in ACPI power optional. + * fix lguest rmmod "bad pgd" + * slub: provide /proc/slabinfo + * [POWERPC] Fix build failure on Cell when CONFIG_SPU_FS=y + * slub: register slabinfo to procfs + * [SCSI] scsi_sysfs: restore prep_fn when ULD is removed + * Unify /proc/slabinfo configuration + * scsi: revert "[SCSI] Get rid of scsi_cmnd->done" + * restrict reading from /proc//maps to those who share ->mm or can + ptrace pid + * Fix kernel/ptrace.c compile problem (missing "may_attach()") + * hwmon: (w83627ehf) Be more careful when changing VID input level + * NFS: Fix a possible Oops in fs/nfs/super.c + * NFSv4: Fix circular locking dependency in nfs4_kill_renewd + * NFS: add newline to kernel warning message in auth_gss code + * NFSv4: nfs4_open_confirm must not set the open_owner as confirmed on + error + * NFSv4: Fix open_to_lock_owner sequenceid allocation... + * gameport: don't export functions that are static inline + * Input: spitzkbd - fix suspend key handling + * Input: pass EV_PWR events to event handlers + * [ARM] 4735/1: Unbreak pxa25x suspend/resume + * IB/srp: Fix list corruption/oops on module reload + * Console is utf-8 by default + * [IA64] Update Altix BTE error return status patch + * [IA64] Update Altix nofault code + * [X25]: Add missing x25_neigh_put + * [XFRM]: Do not define km_migrate() if !CONFIG_XFRM_MIGRATE + * [CASSINI]: Fix endianness bug. + * [CASSINI]: Revert 'dont touch page_count'. + * [CASSINI]: Program parent Intel31154 bridge when necessary. + * [CASSINI]: Set skb->truesize properly on receive packets. + * [CASSINI]: Fix two obvious NAPI bugs. + * [CASSINI]: Bump driver version and release date. + * [INET]: Fix netdev renaming and inet address labels + * [CONNECTOR]: Return proper error code in cn_call_callback() + * [ISDN] i4l: 'NO CARRIER' message lost after ldisc flush + * [ISDN]: i4l: Fix DLE handling for i4l-audio + * fix: using joysticks in 32 bit applications on 64 bit systems + * [ARM] 4691/1: add missing i2c_board_info struct for at91rm9200 + * hda_intel suspend latency: shorten codec read + * CPU hotplug: fix cpu_is_offline() on !CONFIG_HOTPLUG_CPU + * Linux 2.6.24-rc7 + * sh: Fix argument page dcache flushing regression. + * V4L/DVB (6944a): Fix Regression VIDIOCGMBUF ioctl hangs on bttv driver + * V4L/DVB (6916): ivtv: udelay has to be changed *after* the eeprom was + read, not before + * [MIPS] Move inclusing of kernel/time/Kconfig menu to appropriate place + * [MIPS] Alchemy: Fix use of __init code bug exposed by modpost warning + * [MIPS] Fix IP32 breakage + * [MIPS] Assume R4000/R4400 newer than 3.0 don't have the mfc0 count bug + * [MIPS] Fix CONFIG_BOOT_RAW. + * ACPI: Reintroduce run time configurable max_cstate for !CPU_IDLE case + * core dump: real_parent ppid + * acct: real_parent ppid + * IB/mlx4: Fix value of pkey_index in QP1 completions + * IB/srp: Release transport before removing host + * x86: fix do_fork_idle section mismatch + * spi_bitbang: always grab lock with irqs blocked + * fat: optimize fat_count_free_clusters() + * KEYS: fix macro + * md: fix data corruption when a degraded raid5 array is reshaped + * xip: fix get_zeroed_page with __GFP_HIGHMEM + * eCryptfs: fix dentry handling on create error, unlink, and inode + destroy + * vmcoreinfo: add the array length of "free_list" for filtering free + pages + * dmi-id: fix for __you_cannot_kmalloc_that_much failure + * snd_mixer_oss_build_input(): fix for __you_cannot_kmalloc_that_much + failure with gcc-3.2 + * Fix crash with FLAT_MEMORY and ARCH_PFN_OFFSET != 0 + * hfs: handle more on-disk corruptions without oopsing + * pl2303: Fix mode switching regression + * futex: Prevent stale futex owner when interrupted/timeout + * [NIU]: Fix slowpath interrupt handling. + * [NIU]: Missing ->last_rx update. + * [NIU]: Fix potentially stuck TCP socket send queues. + * [NIU]: Update driver version and release date. + * [IPV4] raw: Strengthen check on validity of iph->ihl + * [IPV4] ipconfig: Fix regression in ip command line processing + * [NET]: Fix netx-eth.c compilation. + * [METH]: Fix MAC address handling. + * [TULIP]: NAPI full quantum bug. + * [ATM]: [nicstar] delay irq setup until card is configured + * [SCTP]: Fix the name of the authentication event. + * [SCTP]: Correctly handle AUTH parameters in unexpected INIT + * [SCTP]: Add back the code that accounted for FORWARD_TSN parameter in + INIT. + * [IRDA]: irda_create() nuke user triggable printk + * b43: Fix rxheader channel parsing + * [NET]: Do not grab device reference when scheduling a NAPI poll. + * [NET]: Add NAPI_STATE_DISABLE. + * [NET]: Do not check netif_running() and carrier state in ->poll() + * ssb: Fix probing of PCI cores if PCI and PCIE core is available + * mac80211: return an error when SIWRATE doesn't match any rate + * [NETXEN]: Fix ->poll() done logic. + * [NET]: Fix drivers to handle napi_disable() disabling interrupts. + * [NET]: Stop polling when napi_disable() is pending. + * [NET]: Make ->poll() breakout consistent in Intel ethernet drivers. + * [NET] Intel ethernet drivers: update MAINTAINERS + * [NET]: kaweth was forgotten in msec switchover of usb_start_wait_urb + * [IPV4] ROUTE: ip_rt_dump() is unecessary slow + * [NET]: Clone the sk_buff 'iif' field in __skb_clone() + * [LRO] Fix lro_mgr->features checks + * [NET]: mcs7830 passes msecs instead of jiffies to usb_control_msg + * [FORCEDETH]: Fix reversing the MAC address on suspend. + * [XFRM]: xfrm_algo_clone() allocates too much memory + * [SOCK]: Adds a rcu_dereference() in sk_filter + * [CONNECTOR]: Don't touch queue dev after decrement of ref count. + * [IPV6]: IPV6_MULTICAST_IF setting is ignored on link-local connect() + * [ATM]: Check IP header validity in mpc_send_packet + * show_task: real_parent + * [SCSI] qla1280: fix 32 bit segment code + * [NIU]: Support for Marvell PHY + * [NEIGH]: Fix race between neigh_parms_release and neightbl_fill_parms + * [IPV4] ROUTE: fix rcu_dereference() uses in /proc/net/rt_cache + * [AX25]: Kill user triggable printks. + * [ARM] pxa: silence warnings from cpu_is_xxx() macros + * [POWERPC] efika: add phy-handle property for fec_mpc52xx + * [ARM] vfp: fix fuitod/fsitod instructions + * [CRYPTO] padlock: Fix alignment fault in aes_crypt_copy + * rt2x00: Allow rt61 to catch up after a missing tx report + * rt2x00: Corectly initialize rt2500usb MAC + * rt2x00: Put 802.11 data on 4 byte boundary + * NFSv4: Give the lock stateid its own sequence queue + * sata_qstor: use hardreset instead of softreset + * libata-sff: PCI IRQ handling fix + * pata_pdc202xx_old: Further fixups + * pata_ixp4xx_cf: fix compilation introduced by ata_port_desc() + conversion + * libata-pmp: 4726 hates SRST + * libata-pmp: propagate timeout to host link + * libata: don't normalize UNKNOWN to NONE after reset + * Update kernel parameter document for libata DMA mode setting knobs. + * sata_sil24: prevent hba lockup when pass-through ATA commands are used + * ide: workaround suspend bug for ACPI IDE + * ide: fix cable detection for SATA bridges + * trm290: do hook dma_host_{on,off} methods (take 2) + * libata and starting/stopping ATAPI floppy devices + * ACPI : Not register gsi for PCI IDE controller in legacy mode + * ACPICA: fix acpi_serialize hang regression + * sh: Force __access_ok() to obey address space limit. + * [AX25] af_ax25: Possible circular locking. + * ACPI: apply quirk_ich6_lpc_acpi to more ICH8 and ICH9 + * [POWERPC] Fix CPU hotplug when using the SLB shadow buffer + * [BLUETOOTH]: rfcomm tty BUG_ON() code fix + * [BLUETOOTH]: Always send explicit hci_ll wake-up acks. + * [DECNET] ROUTE: fix rcu_dereference() uses in /proc/net/decnet_cache + * [VLAN]: nested VLAN: fix lockdep's recursive locking warning + * [MACVLAN]: Prevent nesting macvlan devices + * [NETFILTER]: ip6t_eui64: Fixes calculation of Universal/Local bit + * [NETFILTER]: xt_helper: Do not bypass RCU + * [XFS] fix unaligned access in readdir + * Don't blatt first element of prv in sg_chain() + * loop: fix bad bio_alloc() nr_iovec request + * block: fix blktrace timestamps + * blktrace: kill the unneeded initcall + * V4L/DVB (6999): ivtv: stick to udelay=10 after all + * V4L/DVB (7001): av7110: fix section mismatch + * [MIPS] Wrong CONFIG option prevents setup of DMA zone. + * [MIPS] pnx8xxx: move to clocksource + * [MIPS] Malta: Fix software reset on big endian + * [MIPS] Lasat: Fix built in separate object directory. + * [MIPS] Replace 40c7869b693b18412491fdcff64682215b739f9e kludge + * Pull bugzilla-5637 into release branch + * Pull bugzilla-8171 into release branch + * Pull bugzilla-8973 into release branch + * PM: ACPI and APM must not be enabled at the same time + * Pull bugzilla-9194 into release branch + * Pull bugzilla-9494 into release branch + * Pull bugzilla-9535 into release branch + * Pull bugzilla-9627 into release branch + * Pull bugzilla-9683 into release branch + * IDE: terminate ACPI DMI list + * cache invalidation error for buffered write + * ps3fb: prevent use after free of fb_info + * ps3fb: fix deadlock on kexec() + * [NETFILTER]: bridge: fix double POST_ROUTING invocation + * xircom_cb endianness fixes + * de4x5 fixes + * endianness noise in tulip_core + * netxen: update MAINTAINERS + * netxen: update driver version + * netxen: stop second phy correctly + * netxen: optimize tx handling + * netxen: fix byte-swapping in tx and rx + * 3c509: PnP resource management fix + * Fixed a small typo in the loopback driver + * ip1000: menu location change + * r8169: fix missing loop variable increment + * [usb netdev] asix: fix regression + * fs_enet: check for phydev existence in the ethtool handlers + * Use access mode instead of open flags to determine needed permissions + * sky2: large memory workaround. + * sky2: remove check for PCI wakeup setting from BIOS + * spidernet MAINTAINERship update + * pnpacpi: print resource shortage message only once + * Pull bugzilla-9535 into release branch + * [SPARC]: Make gettimeofday() monotonic again. + * [SPARC64]: Fix build with SPARSEMEM_VMEMMAP disabled. + * remove task_ppid_nr_ns + * knfsd: Allow NFSv2/3 WRITE calls to succeed when krb5i etc is used. + * Input: improve Kconfig help entries for HP Jornada devices + * [TOKENRING]: rif_timer not initialized properly + * modules: de-mutex more symbol lookup paths in the module code + * w1: decrement slave counter only in ->release() callback + * Kick CPUS that might be sleeping in cpus_idle_wait + * TPM: fix suspend and resume failure + * MAINTAINERS: email update and add missing entry + * quicklists: Only consider memory that can be used with GFP_KERNEL + * macintosh: fix fabrication of caplock key events + * scsi/qla2xxx/qla_os.c section fix + * cciss: section mismatch + * advansys: fix section mismatch warning + * hugetlbfs: fix quota leak + * s3c2410fb: fix incorrect argument type in resume function + * CRIS: define __ARCH_WANT_SYS_RT_SIGSUSPEND in unistd.h for CRIS + * CRIS v10: correct do_signal to fix oops and clean up signal handling in + general + * CRIS v10: kernel/time.c needs to include linux/vmstat.h to compile + * uvesafb: fix section mismatch warnings + * CRIS v10: driver for ds1302 needs to include cris-specific i2c.h + * OSS msnd: fix array overflows + * i2c-omap: Fix NULL pointer dereferencing + * i2c: Spelling fixes + * i2c: Driver IDs are optional + * i2c-sibyte: Fix an error path + * fix the "remove task_ppid_nr_ns" commit + * [MIPS] Kconfig fixes for BCM47XX platform + * [MIPS] Cobalt: Fix ethernet interrupts for RaQ1 + * [MIPS] Cobalt: Qube1 has no serial port so don't use it + * [MIPS] Cacheops.h: Fix typo. + * ata_piix: ignore ATA_DMA_ERR on vmware ich4 + * sata_sil24: fix stupid typo + * sata_sil24: freeze on non-dev errors reported via CERR + * libata: relocate sdev->manage_start_stop configuration + * [POWERPC] Fix boot failure on POWER6 + * x86: fix boot crash on HIGHMEM4G && SPARSEMEM + * x86: asm-x86/msr.h: pull in linux/types.h + * x86: fix RTC_AIE with CONFIG_HPET_EMULATE_RTC + * Fix ARM profiling/instrumentation configuration + * Fix Blackfin HARDWARE_PM support + * libata fixes for sparse-found problems + * [libata] pata_bf54x: checkpatch fixes + * [libata] core checkpatch fix + * libata: correct handling of TSS DVD + * [IA64] Fix unaligned handler for floating point instructions with base + update + * Linux 2.6.24-rc8 + * lockdep: fix internal double unlock during self-test + * lockdep: fix workqueue creation API lockdep interaction + * lockdep: more hardirq annotations for notify_die() + * hostap: section mismatch warning + * wireless/libertas support for 88w8385 sdio older revision + * ipw2200: fix typo in kerneldoc + * b43: fix use-after-free rfkill bug + * rt2x00: Fix ieee80211 payload alignment + * sysfs: make sysfs_lookup() return ERR_PTR(-ENOENT) on failed lookup + * sysfs: fix bugs in sysfs_rename/move_dir() + * Use access mode instead of open flags to determine needed permissions + (CVE-2008-0001) + * IB/ipath: Fix receiving UD messages with immediate data + * [NET]: Fix TX timeout regression in Intel drivers. + * [NIU]: Fix 1G PHY link state handling. + * [SPARC64]: Fix hypervisor TLB operation error reporting. + * Input: mousedev - handle mice that use absolute coordinates + * Input: usbtouchscreen - fix buffer overflow, make more egalax work + * Input: psmouse - fix potential memory leak in psmouse_connect() + * Input: psmouse - fix input_dev leak in lifebook driver + * Input: ALPS - fix sync loss on Acer Aspire 5720ZG + * ipg: balance locking in irq handler + * ipg: plug Tx completion leak + * ipg: fix queue stop condition in the xmit handler + * ipg: fix Tx completion irq request + * cpufreq: Initialise default governor before use + * hfs: fix coverity-found null deref + * pnpacpi: print resource shortage message only once (more) + * CRIS v10: vmlinux.lds.S: ix kernel oops on boot and use common defines + * mm: fix section mismatch warning in page_alloc.c + * jbd: do not try lock_acquire after handle made invalid + * alpha: fix conversion from denormal float to double + * #ifdef very expensive debug check in page fault path + * Fix unbalanced helper_lock in kernel/kmod.c + * fix wrong sized spinlock flags argument + * bonding: fix locking in sysfs primary/active selection + * bonding: fix ASSERT_RTNL that produces spurious warnings + * bonding: fix locking during alb failover and slave removal + * bonding: release slaves when master removed via sysfs + * bonding: Fix up parameter parsing + * bonding: fix lock ordering for rtnl and bonding_rwsem + * bonding: Don't hold lock when calling rtnl_unlock + * Documentation: add a guideline for hard_start_xmit method + * atl1: fix frame length bug + * S2io: Fixed synchronization between scheduling of napi with card reset + and close + * dscc4 endian fixes + * wan/lmc bitfields fixes + * sbni endian fixes + * 3c574, 3c515 bitfields abuse + * dl2k: BMCR_t fixes + * dl2k: ANAR, ANLPAR fixes + * dl2k: BMSR fixes + * dl2k: MSCR, MSSR, ESR, PHY_SCR fixes + * dl2k: the rest + * Replace cpmac fix + * [WATCHDOG] Revert "Stop looking for device as soon as one is found" + * [WATCHDOG] clarify watchdog operation in documentation + * x86: add support for the latest Intel processors to Oprofile + * Selecting LGUEST should turn on Guest support, as in 2.6.23. + * ARM: OMAP1: Keymap fix for f-sample and p2-sample + * ARM: OMAP1: Fix compile for board-nokia770 + * pata_pdc202xx_old: Fix crashes with ATAPI + * arch: Ignore arch/i386 and arch/x86_64 + * Remove bogus duplicate CONFIG_LGUEST_GUEST entry. + * [ARM] pxa: don't rely on r2 being preserved over a function call + * [ARM] 4748/1: dca: source drivers/dca/Kconfig in arch/arm/Kconfig to + fix warning + * rfkill: call rfkill_led_trigger_unregister() on error + * [IPV6]: Mischecked tw match in __inet6_check_established. + * [IPV4] fib_hash: fix duplicated route issue + * [IPV4] fib_trie: fix duplicated route issue + * [NET]: Fix interrupt semaphore corruption in Intel drivers. + * [IPV4] FIB_HASH : Avoid unecessary loop in fn_hash_dump_zone() + * [IPV6] ROUTE: Make sending algorithm more friendly with RFC 4861. + * [NETFILTER]: bridge-netfilter: fix net_device refcnt leaks + * [NEIGH]: Revert 'Fix race between neigh_parms_release and + neightbl_fill_parms' + * [IrDA]: af_irda memory leak fixes + * [ATM] atm/idt77105.c: Fix section mismatch. + * [ATM] atm/suni.c: Fix section mismatch. + * [AF_KEY]: Fix skb leak on pfkey_send_migrate() error + * [NET]: rtnl_link: fix use-after-free + * [IPV6]: ICMP6_MIB_OUTMSGS increment duplicated + * [IPV6]: RFC 2011 compatibility broken + * [ICMP]: ICMP_MIB_OUTMSGS increment duplicated + * selinux: fix memory leak in netlabel code + * [MIPS] SMTC: Fix build error. + * [MIPS] Malta: Fix reading the PCI clock frequency on big-endian + * tc35815: Use irq number for tc35815-mac platform device id + * keyspan: fix oops + * hrtimer: fix section mismatch + * timer: fix section mismatch + * CRIS: add missed local_irq_restore call + * s3c2410_fb: fix line length calculation + * Fix filesystem capability support + * sched: group scheduler, set uid share fix + * hwmon: (it87) request only Environment Controller ports + * W1: w1_therm.c ds18b20 decode freezing temperatures correctly + * W1: w1_therm.c is flagging 0C etc as invalid + * rcu: fix section mismatch + * Fix file references in documentation and Kconfig + * x86: GEODE fix a race condition in the MFGPT timer tick + * virtnet: remove double ether_setup + * virtio:simplify-config-mechanism + * virtio: An entropy device, as suggested by hpa. + * virtio: Export vring functions for modules to use + * virtio: Put the virtio under the virtualization menu + * virtio:pci-device + * Fix vring_init/vring_size to take unsigned long + * virtio:vring-kick-when-empty + * virtio:explicit-callback-disable + * virtio:net-flush-queue-on-init + * virtio:net-fix-xmit-skb-free-real + * Parametrize the napi_weight for virtio receive queue. + * Handle module unload Add the device release function. + * Update all status fields on driver unload + * Make virtio modules GPL + * Make virtio_pci license be GPL2+ + * Use Qumranet donated PCI vendor/device IDs + * virtio:more-interrupt-suppression + * Reboot Implemented + * lguest:reboot-fix + * introduce vcpu struct + * adapt lguest launcher to per-cpuness + * initialize vcpu + * per-cpu run guest + * make write() operation smp aware + * make hypercalls use the vcpu struct + * per-vcpu lguest timers + * per-vcpu interrupt processing. + * map_switcher_in_guest() per-vcpu + * make emulate_insn receive a vcpu struct. + * make registers per-vcpu + * replace lguest_arch with lg_cpu_arch. + * per-vcpu lguest task management + * makes special fields be per-vcpu + * make pending notifications per-vcpu + * per-vcpu lguest pgdir management + + -- Tim Gardner Thu, 17 Jan 2008 14:45:01 -0700 + +linux (2.6.24-4.7) hardy; urgency=low + + [Amit Kucheria] + + * Poulsbo: Add SD8686 and 8688 WLAN drivers + * Poulsbo: Mass update of patches to be identical to those on moblin + * SAUCE: make fc transport removal of target configurable OriginalAuthor: + Michael Reed sgi.com> OriginalLocation: + http://thread.gmane.org/gmane.linux.scsi/25318 Bug: 163075 + + [Fabio M. Di Nitto] + + * Fix handling of gcc-4.1 for powerpc and ia64 + + [Tim Gardner] + + * Re-engineered architecture specific linux-headers compiler version + dependencies. + * Doh! Changed header-depends to header_depends. + + -- Tim Gardner Fri, 11 Jan 2008 07:10:46 -0700 + +linux (2.6.24-4.6) hardy; urgency=low + + [Alessio Igor Bogani] + + * Fix -rt build FTBS. + + [Amit Kucheria] + + * LPIACOMPAT: Update thermal patches to be inline with lpia flavour + * Poulsbo: Add USB Controller patch and corresponding config change + + [Fabio M. Di Nitto] + + * Enable aoe and nbd modules on hppa Ignore: yes + * Fix ia64 build by using gcc-4.1 + + [Tim Gardner] + + * Enable JFFS2 LZO compression. + - LP: #178343 + * Remove IS_G33 special handling. + - LP: #174367 + * Enabled CONFIG_SECURITY_CAPABILITIES and + CONFIG_SECURITY_FILE_CAPABILITIES + - LP: #95089 + * Enabled CONFIG_TASKSTATS and CONFIG_TASK_IO_ACCOUNTING + * Turned CONFIG_SECURITY_FILE_CAPABILITIES back off. + * Enabled CONFIG_B43LEGACY=m + * Enabled CONFIG_SCSI_QLOGIC_1280=m + * Enabled CONFIG_FUSION=y for virtual + * USB bluetooth device 0x0e5e:0x6622 floods errors to syslog + - LP: #152689 + * Removed lpia from d-i. + * Added ia64 modules. + * Added hppa32/64 modules. + + [Upstream Kernel Changes] + + * DMI autoload dcdbas on all Dell systems. + * sched: fix gcc warnings + * leds: Fix leds_list_lock locking issues + * leds: Fix locomo LED driver oops + * x86: fix asm-x86/byteorder.h for userspace export + * x86: fix asm-x86/msr.h for user-space export + * fix lguest rmmod "bad pgd" + * slub: provide /proc/slabinfo + * [POWERPC] Fix build failure on Cell when CONFIG_SPU_FS=y + * slub: register slabinfo to procfs + * [SCSI] scsi_sysfs: restore prep_fn when ULD is removed + * Unify /proc/slabinfo configuration + * scsi: revert "[SCSI] Get rid of scsi_cmnd->done" + * restrict reading from /proc//maps to those who share ->mm or can + ptrace pid + * Fix kernel/ptrace.c compile problem (missing "may_attach()") + * hwmon: (w83627ehf) Be more careful when changing VID input level + * NFS: Fix a possible Oops in fs/nfs/super.c + * NFSv4: Fix circular locking dependency in nfs4_kill_renewd + * NFS: add newline to kernel warning message in auth_gss code + * NFSv4: nfs4_open_confirm must not set the open_owner as confirmed on + error + * NFSv4: Fix open_to_lock_owner sequenceid allocation... + * IB/srp: Fix list corruption/oops on module reload + * Console is utf-8 by default + * [IA64] Update Altix BTE error return status patch + * [IA64] Update Altix nofault code + * [X25]: Add missing x25_neigh_put + * [XFRM]: Do not define km_migrate() if !CONFIG_XFRM_MIGRATE + * [CASSINI]: Fix endianness bug. + * [CASSINI]: Revert 'dont touch page_count'. + * [CASSINI]: Program parent Intel31154 bridge when necessary. + * [CASSINI]: Set skb->truesize properly on receive packets. + * [CASSINI]: Fix two obvious NAPI bugs. + * [CASSINI]: Bump driver version and release date. + * [INET]: Fix netdev renaming and inet address labels + * [CONNECTOR]: Return proper error code in cn_call_callback() + * [ISDN] i4l: 'NO CARRIER' message lost after ldisc flush + * [ISDN]: i4l: Fix DLE handling for i4l-audio + * fix: using joysticks in 32 bit applications on 64 bit systems + * hda_intel suspend latency: shorten codec read + * CPU hotplug: fix cpu_is_offline() on !CONFIG_HOTPLUG_CPU + * Linux 2.6.24-rc7 + * PIE executable randomization (upstream cherry pick by kees) + + -- Tim Gardner Fri, 04 Jan 2008 07:15:47 -0700 + +linux (2.6.24-3.5) hardy; urgency=low + + [Alessio Igor Bogani] + + * rt: Fix rt preempt patchset version + * Updated README file for binary custom flavours + * Fix -rt build FTBS. + * rt: Update configuration files + + [Tim Gardner] + + * SAUCE: Add extra headers to linux-libc-dev + + [Upstream Kernel Changes] + + * [WATCHDOG] at32ap700x_wdt: add support for boot status and add fix for + silicon errata + * [WATCHDOG] Stop looking for device as soon as one is found + * [WATCHDOG] bfin_wdt, remove SPIN_LOCK_UNLOCKED + * [WATCHDOG] Sbus: cpwatchdog, remove SPIN_LOCK_UNLOCKED + * [WATCHDOG] IT8212F watchdog driver + * ACPI: acpiphp: Remove dmesg spam on device remove + * [WATCHDOG] ipmi: add the standard watchdog timeout ioctls + * [WATCHDOG] add Nano 7240 driver + * ACPI: battery: fix ACPI battery technology reporting + * [ARM] 4667/1: CM-X270 fixes + * [ARM] 4690/1: PXA: fix CKEN corruption in PXA27x AC97 cold reset code + * [IPV6] XFRM: Fix auditing rt6i_flags; use RTF_xxx flags instead of + RTCF_xxx. + * [IPV4]: Swap the ifa allocation with the"ipv4_devconf_setall" call + * [IPv4] ESP: Discard dummy packets introduced in rfc4303 + * [IPv6] ESP: Discard dummy packets introduced in rfc4303 + * [UM]: Fix use of skb after netif_rx + * [XTENSA]: Fix use of skb after netif_rx + * [S390]: Fix use of skb after netif_rx + * [BNX2]: Add PHY_DIS_EARLY_DAC workaround. + * [BNX2]: Fix RX packet rot. + * [BNX2]: Update version to 1.6.9. + * [NET]: Fix wrong comments for unregister_net* + * [VLAN]: Fix potential race in vlan_cleanup_module vs + vlan_ioctl_handler. + * [IPSEC]: Fix potential dst leak in xfrm_lookup + * V4L/DVB (6485): ivtv: fix compile warning + * V4L/DVB (6540): em28xx: fix failing autodetection after the reboot + * V4L/DVB (6542): Fix S-video mode on tvp5150 + * V4L/DVB (6579): Fix bug #8824: Correct support for Diseqc on tda10086 + * V4L/DVB (6581): Fix: avoids negative vma usage count + * V4L/DVB (6601): V4L: videobuf-core locking fixes and comments + * V4L/DVB (6602): V4L: Convert videobuf drivers to videobuf_stop + * V4L/DVB (6615): V4L: Fix VIDIOCGMBUF locking in saa7146 + * V4L/DVB (6629): zl10353: fix default adc_clock and TRL nominal rate + calculation + * V4L/DVB (6666): saa7134-alsa: fix period handling + * V4L/DVB (6684): Complement va_start() with va_end() + style fixes + * V4L/DVB (6686): saa7134: fix composite over s-video input on the Tevion + MD 9717 + * V4L/DVB (6690): saa7134: fix ignored interrupts + * V4L/DVB (6751): V4L: Memory leak! Fix count in videobuf-vmalloc mmap + * V4L/DVB (6746): saa7134-dvb: fix tuning for WinTV HVR-1110 + * V4L/DVB (6750): Fix in-kernel compilation for cxusb + * V4L/DVB (6733): DVB: Compile 3000MC-specific DIB code only for + CONFIG_DVB_DIB3000MC + * V4L/DVB (6794): Fix compilation when dib3000mc is compiled as a module + * NFS: Fix NFS mountpoint crossing... + * V4L/DVB (6796): ivtv/ section fix + * V4L/DVB (6797): bt8xx/ section fixes + * NFSv2/v3: Fix a memory leak when using -onolock + * V4L/DVB (6609): Re-adds lock safe videobuf_read_start + * i2c: Delete an outdated piece of documentation + * i2c-gpio: Initialize adapter class + * i2c: Add missing spaces in split log messages + * i2c/isp1301_omap: Build fix + * [SERIAL] sparc: Infrastructure to fix section mismatch bugs. + * NFS: Fix an Oops in NFS unmount + * sdhci: describe quirks + * sdhci: don't warn about sdhci 2.0 controllers + * sdhci: use PIO when DMA can't satisfy the request + * sdhci: support JMicron JMB38x chips + * mmc: remove unused 'mode' from the mmc_host structure + * IB/ehca: Return correct number of SGEs for SRQ + * IB/ehca: Serialize HCA-related hCalls if necessary + * ide-scsi: add ide_scsi_hex_dump() helper + * ide: add missing checks for control register existence + * ide: deprecate CONFIG_BLK_DEV_OFFBOARD + * ide: fix ide_scan_pcibus() error message + * ide: coding style fixes for drivers/ide/setup-pci.c + * ide: add /sys/bus/ide/devices/*/{model,firmware,serial} sysfs entries + * ide: DMA reporting and validity checking fixes (take 3) + * ide-cd: remove dead post_transform_command() + * pdc202xx_new: fix Promise TX4 support + * hpt366: fix HPT37x PIO mode timings (take 2) + * ide: remove dead code from __ide_dma_test_irq() + * ide: remove stale changelog from ide-disk.c + * ide: remove stale changelog from ide-probe.c + * ide: fix ->io_32bit race in set_io_32bit() + * MAINTAINERS: update the NFS CLIENT entry + * V4L/DVB (6803): buf-core.c locking fixes + * [SPARC64]: Fix two kernel linear mapping setup bugs. + * IB/ehca: Fix lock flag variable location, bump version number + * kbuild: re-enable Makefile generation in a new O=... directory + * V4L/DVB (6798): saa7134: enable LNA in analog mode for Hauppauge WinTV + HVR-1110 + * V4L/DVB (6814): Makefile: always enter video/ + * V4L/DVB (6819): i2c: fix drivers/media/video/bt866.c + * V4L/DVB (6820): s5h1409: QAM SNR related fixes + * ACPI: video_device_list corruption + * ACPI: fix modpost warnings + * ACPI: thinkpad-acpi: fix lenovo keymap for brightness + * Pull thinkpad-2.6.24 into release branch + * Pull battery-2.6.24 into release branch + * [POWERPC] Fix typo #ifdef -> #ifndef + * [POWERPC] Kill non-existent symbols from ksyms and commproc.h + * [POWRPC] CPM2: Eliminate section mismatch warning in cpm2_reset(). + * [POWERPC] 82xx: mpc8272ads, pq2fads: Update defconfig with + CONFIG_FS_ENET_MDIO_FCC + * [POWERPC] iSeries: don't printk with HV spinlock held + * [POWERPC] Fix rounding bug in emulation for double float operating + * [POWERPC] Make PS3_SYS_MANAGER default y, not m + * [MIPS] time: Set up Cobalt's mips_hpt_frequency + * [MIPS] Alchemy: fix PCI resource conflict + * [MIPS] Alchemy: fix off by two error in __fixup_bigphys_addr() + * [MIPS] Atlas, Malta: Don't free firmware memory on free_initmem. + * [MIPS] PCI: Make pcibios_fixup_device_resources ignore legacy + resources. + * [MIPS] time: Delete weak definition of plat_time_init() due to gcc bug. + * [MIPS] Ensure that ST0_FR is never set on a 32 bit kernel + * [SPARC32]: Silence sparc32 warnings on missing syscalls. + * Pull hotplug into release branch + * ACPI: SBS: Reset alarm bit + * ACPI: SBS: Ignore alarms coming from unknown devices + * ACPI: SBS: Return rate in mW if capacity in mWh + * Pull bugzilla-9362 into release branch + * sky2: RX lockup fix + * sundance fixes + * starfire VLAN fix + * e100: free IRQ to remove warningwhenrebooting + * hamachi endianness fixes + * drivers/net/sis190.c section fix + * drivers/net/s2io.c section fixes + * ucc_geth: minor whitespace fix + * net: smc911x: shut up compiler warnings + * Net: ibm_newemac, remove SPIN_LOCK_UNLOCKED + * ixgb: make sure jumbos stay enabled after reset + * [NETFILTER]: ctnetlink: set expected bit for related conntracks + * [NETFILTER]: ip_tables: fix compat copy race + * [XFRM]: Display the audited SPI value in host byte order. + * [NETFILTER]: xt_hashlimit should use time_after_eq() + * [TIPC]: Fix semaphore handling. + * [SYNCPPP]: Endianness and 64bit fixes. + * [NETFILTER]: bridge: fix missing link layer headers on outgoing routed + packets + * [ATM]: Fix compiler warning noise with FORE200E driver + * [IPV4]: Updates to nfsroot documentation + * [BRIDGE]: Assign random address. + * [IPV6]: Fix the return value of ipv6_getsockopt + * [IPV4]: Make tcp_input_metrics() get minimum RTO via tcp_rto_min() + * [AX25]: Locking dependencies fix in ax25_disconnect(). + * [SCTP]: Flush fragment queue when exiting partial delivery. + * [IRDA]: Race between open and disconnect in irda-usb. + * [IRDA]: mcs7780 needs to free allocated rx buffer. + * [IRDA]: irlmp_unregister_link() needs to free lsaps. + * [IRDA]: stir4200 fixes. + * [IRDA]: irda parameters warning fixes. + * [S390] pud_present/pmd_present bug. + * [ARM] 4710/1: Fix coprocessor 14 usage for debug messages via ICEDCC + * [ARM] 4694/1: IXP4xx: Update clockevent support for shutdown and resume + * kobject: fix the documentation of how kobject_set_name works + * tipar: remove obsolete module + * HOWTO: Change man-page maintainer address for Japanese HOWTO + * Add Documentation for FAIR_USER_SCHED sysfs files + * HOWTO: change addresses of maintainer and lxr url for Korean HOWTO + * add stable_api_nonsense.txt in korean + * HOWTO: update misspelling and word incorrected + * PCI: Restore PCI expansion ROM P2P prefetch window creation + * USB: sierra: fix product id + * usb-storage: Fix devices that cannot handle 32k transfers + * USB: cp2101: new device id + * USB: option: Bind to the correct interface of the Huawei E220 + * usb.h: fix kernel-doc warning + * USB: fix locking loop by avoiding flush_scheduled_work + * USB: use IRQF_DISABLED for HCD interrupt handlers + * USB: at91_udc: correct hanging while disconnecting usb cable + * usb: Remove broken optimisation in OHCI IRQ handler + * USB: revert portions of "UNUSUAL_DEV: Sync up some reported devices + from Ubuntu" + * ocfs2: fix exit-while-locked bug in ocfs2_queue_orphans() + * ocfs2: Don't panic when truncating an empty extent + * ocfs2: Allow for debugging of transaction extends + * ocfs2: Re-journal buffers after transaction extend + * pcnet_cs: add new id + * ucc_geth: really fix section mismatch + * sis190 endianness + * libertas: add Dan Williams as maintainer + * zd1211rw: Fix alignment problems + * wireless/ipw2200.c: add __dev{init,exit} annotations + * ieee80211_rate: missed unlock + * iwlwifi3945/4965: fix rate control algo reference leak + * libertas: select WIRELESS_EXT + * bcm43xx_debugfs sscanf fix + * b43: Fix rfkill radio LED + * iwlwifi: fix rf_kill state inconsistent during suspend and resume + * sata_sil: fix spurious IRQ handling + * libata: clear link->eh_info.serror from ata_std_postreset() + * libata: add ST3160023AS / 3.42 to NCQ blacklist + * sata_mv: improve warnings about Highpoint RocketRAID 23xx cards + * libata-acpi: adjust constness in ata_acpi_gtm/stm() parameters + * libata: update ata_*_printk() macros such that level can be a variable + * libata: add more opcodes to ata.h + * libata: ata_dev_disable() should be called from EH context + * libata-acpi: add new hooks ata_acpi_dissociate() and + ata_acpi_on_disable() + * libata-acpi: implement and use ata_acpi_init_gtm() + * libata-acpi: implement dev->gtf_cache and evaluate _GTF right after + _STM during resume + * libata-acpi: improve ACPI disabling + * libata-acpi: improve _GTF execution error handling and reporting + * libata-acpi: implement _GTF command filtering + * libata: update atapi_eh_request_sense() such that lbam/lbah contains + buffer size + * libata: fix ATAPI draining + * fix headers_install + * revert "Hibernation: Use temporary page tables for kernel text mapping + on x86_64" + * uml: stop gdb from deleting breakpoints when running UML + * alpha: strncpy/strncat fixes + * rtc-at32ap700x: fix irq init oops + * parport: "dev->timeslice" is an unsigned long, not an int + * ecryptfs: initialize new auth_tokens before teardown + * Fix lguest documentation + * sparsemem: make SPARSEMEM_VMEMMAP selectable + * fs/Kconfig: grammar fix + * ext3, ext4: avoid divide by zero + * alpha: build fixes + * cpufreq: fix missing unlocks in cpufreq_add_dev error paths. + * mm/sparse.c: check the return value of sparse_index_alloc() + * mm/sparse.c: improve the error handling for sparse_add_one_section() + * pktcdvd: add kobject_put when kobject register fails + * drivers/macintosh/via-pmu.c: Added a missing iounmap + * drivers/cpufreq/cpufreq_stats.c section fix + * apm_event{,info}_t are userspace types + * mm: fix page allocation for larger I/O segments + * ecryptfs: set s_blocksize from lower fs in sb + * I/OAT: fixups from code comments + * I/OAT: fix null device in call to dev_err() + * fix bloat-o-meter for ppc64 + * ecryptfs: fix fsx data corruption problems + * Documentation: update hugetlb information + * Fix compilation warning in dquot.c + * SLUB: remove useless masking of GFP_ZERO + * quicklist: Set tlb->need_flush if pages are remaining in quicklist 0 + * sysctl: fix ax25 checks + * [XFS] Don't wait for pending I/Os when purging blocks beyond eof. + * [XFS] Put the correct offset in dirent d_off + * block: use jiffies conversion functions in scsi_ioctl.c + * as-iosched: fix incorrect comments + * as-iosched: fix write batch start point + * block: let elv_register() return void + * Cleanup umem driver: fix most checkpatch warnings, conform to kernel + * sched: fix crash on ia64, introduce task_current() + * sched: mark rwsem functions as __sched for wchan/profiling + * sched: sysctl, proc_dointvec_minmax() expects int values for + * sched: touch softlockup watchdog after idling + * sched: do not hurt SCHED_BATCH on wakeup + * oprofile: op_model_athlon.c support for AMD family 10h barcelona + performance counters + * clockevents: fix reprogramming decision in oneshot broadcast + * genirq: add unlocked version of set_irq_handler() + * timer: kernel/timer.c section fixes + * x86: jprobe bugfix + * x86: kprobes bugfix + * x86: also define AT_VECTOR_SIZE_ARCH + * genirq: revert lazy irq disable for simple irqs + * x86: fix "Kernel panic - not syncing: IO-APIC + timer doesn't work!" + * [SCSI] sym53c8xx: fix free_irq() regression + * [SCSI] dpt_i2o: driver is only 32 bit so don't set 64 bit DMA mask + * [SCSI] sym53c8xx: fix "irq X: nobody cared" regression + * [SCSI] initio: fix conflict when loading driver + * [SCSI] st: fix kernel BUG at include/linux/scatterlist.h:59! + * [SCSI] initio: bugfix for accessors patch + * IA64: Slim down __clear_bit_unlock + * [IA64] signal: remove redundant code in setup_sigcontext() + * [IA64] ia32 nopage + * [IA64] Avoid unnecessary TLB flushes when allocating memory + * [IA64] Two trivial spelling fixes + * [IA64] print kernel release in OOPS to make kerneloops.org happy + * [IA64] set_thread_area fails in IA32 chroot + * [IA64] Remove compiler warinings about uninitialized variable in + irq_ia64.c + * [IA64] Remove assembler warnings on head.S + * [IA64] Fix Altix BTE error return status + * [IA64] Guard elfcorehdr_addr with #if CONFIG_PROC_FS + * [IA64] make flush_tlb_kernel_range() an inline function + * [IA64] Adjust CMCI mask on CPU hotplug + * Do dirty page accounting when removing a page from the page cache + * x86 apic_32.c section fix + * x86 smpboot_32.c section fixes + * x86_32: select_idle_routine() must be __cpuinit + * x86_32: disable_pse must be __cpuinitdata + * x86: fix show cpuinfo cpu number always zero + * ps3fb: Update for firmware 2.10 + * ps3fb: Fix ps3fb free_irq() dev_id + * pata_hpt37x: Fix HPT374 detection + * mac80211: Drop out of associated state if link is lost + * mac80211: fix header ops + * NET: mac80211: fix inappropriate memory freeing + * [TG3]: Endianness annotations. + * [TG3]: Endianness bugfix. + * rtl8187: Add USB ID for Sitecom WL-168 v1 001 + * p54: add Kconfig description + * iwlwifi: fix possible priv->mutex deadlock during suspend + * ipw2200: prevent alloc of unspecified size on stack + * [IPV4] ARP: Remove not used code + * [IPSEC]: Avoid undefined shift operation when testing algorithm ID + * [XFRM]: Audit function arguments misordered + * [IPV4] ip_gre: set mac_header correctly in receive path + * [NET]: Correct two mistaken skb_reset_mac_header() conversions. + * [SPARC64]: Fix OOPS in dma_sync_*_for_device() + * sched: rt: account the cpu time during the tick + * debug: add end-of-oops marker + * mm: fix exit_mmap BUG() on a.out binary exit + * dm: table detect io beyond device + * dm mpath: hp requires scsi + * dm crypt: fix write endio + * dm: trigger change uevent on rename + * dm: merge max_hw_sector + * dm crypt: use bio_add_page + * [SPARC64]: Spelling fixes + * [SPARC32]: Spelling fixes + * [NET] include/net/: Spelling fixes + * [DCCP]: Spelling fixes + * [IRDA]: Spelling fixes + * [IPV6]: Spelling fixes + * [NET] net/core/: Spelling fixes + * [PKT_SCHED]: Spelling fixes + * [NETLABEL]: Spelling fixes + * [SCTP]: Spelling fixes + * [NETFILTER]: Spelling fixes + * [NETFILTER] ipv4: Spelling fixes + * [ATM]: Spelling fixes + * [NET]: Fix function put_cmsg() which may cause usr application memory + overflow + * x86: fix die() to not be preemptible + * x86: intel_cacheinfo.c: cpu cache info entry for Intel Tolapai + * [XFS] Fix mknod regression + * [XFS] Initialise current offset in xfs_file_readdir correctly + * Linux 2.6.24-rc6 + * [IPV4]: OOPS with NETLINK_FIB_LOOKUP netlink socket + * SLUB: Improve hackbench speed + * typhoon: endianness bug in tx/rx byte counters + * typhoon: missing le32_to_cpu() in get_drvinfo + * typhoon: set_settings broken on big-endian + * typhoon: missed rx overruns on big-endian + * typhoon: memory corruptor on big-endian if TSO is enabled + * typhoon: trivial endianness annotations + * cycx: annotations and fixes (.24 fodder?) + * asix fixes + * yellowfin: annotations and fixes (.24 fodder?) + * dl2k endianness fixes (.24 fodder?) + * r8169 endianness + * rrunner: use offsetof() instead of homegrown insanity + * 3c574 and 3c589 endianness fixes (.24?) + * fec_mpc52xx: write in C... + * 3c359 endianness annotations and fixes + * MACB: clear transmit buffers properly on transmit underrun + * UIO: Add a MAINTAINERS entry for Userspace I/O + * Modules: fix memory leak of module names + * USB: Unbreak fsl_usb2_udc + * USB: VID/PID update for sierra + * USB: New device ID for the CP2101 driver + * quicklists: do not release off node pages early + * ecryptfs: fix string overflow on long cipher names + * Fix computation of SKB size for quota messages + * Don't send quota messages repeatedly when hardlimit reached + * ecryptfs: fix unlocking in error paths + * ecryptfs: redo dget,mntget on dentry_open failure + * MAINTAINERS: mailing list archives are web links + * ps3: vuart: fix error path locking + * lib: proportion: fix underflow in prop_norm_percpu() + * pcmcia: remove pxa2xx_lubbock build warning + * kconfig: obey KCONFIG_ALLCONFIG choices with randconfig. + * tty: fix logic change introduced by wait_event_interruptible_timeout() + * uml: user of helper_wait() got missed when it got extra arguments + * V4L/DVB (6871): Kconfig: VIDEO_CX23885 must select DVB_LGDT330X + * V4L/DVB (6876): ivtv: mspx4xx needs a longer i2c udelay + * drivers/ide/: Spelling fixes + * ide-cd: fix SAMSUNG CD-ROM SCR-3231 quirk + * ide-cd: fix ACER/AOpen 24X CDROM speed reporting on big-endian machines + * ide-cd: use ide_cd_release() in ide_cd_probe() + * ide-cd: fix error messages in cdrom_{read,write}_check_ireason() + * ide-cd: add missing 'ireason' masking to cdrom_write_intr() + * ide-cd: fix error messages in cdrom_write_intr() + * ide-cd: add error message for DMA error to cdrom_read_intr() + * ide-cd: fix error message in cdrom_pc_intr() + * ide-cd: fix 'ireason' reporting in cdrom_pc_intr() + * MAINTAINERS: update ide-cd entry + * [SPARC64]: Implement pci_resource_to_user() + * mac80211: round station cleanup timer + * mac80211: warn when receiving frames with unaligned data + * [NETFILTER]: nf_conntrack_ipv4: fix module parameter compatibility + * [TUNTAP]: Fix wrong debug message. + * [NET] tc_nat: header install + * [VETH]: move veth.h to include/linux + * [IPV4]: Fix ip command line processing. + * Revert quicklist need->flush fix + * [CRYPTO] padlock: Fix spurious ECB page fault + * [POWERPC] Oprofile: Remove dependency on spufs module + * [POWERPC] PS3: Fix printing of os-area magic numbers + * [PCI] Do not enable CRS Software Visibility by default + * [IPV4] Fix ip=dhcp regression + * [SERIAL]: Fix section mismatches in Sun serial console drivers. + * [TCP]: use non-delayed ACK for congestion control RTT + * [BLUETOOTH]: put_device before device_del fix + + -- Tim Gardner Sat, 22 Dec 2007 15:16:11 -0700 + +linux (2.6.24-2.4) hardy; urgency=low + + [Alessio Igor Bogani] + + * rt: First import for Hardy + + [Amit Kucheria] + + * LPIA: Fix FTBFS for hda + * LPIA: Trim configs including disabling stock DRM + + [Tim Gardner] + + * SAUCE: Increase CONFIG_IDE_MAX_HWIFS to 8 (from 4) + - LP: #157909 + Then reverted since it causes an ABI bump. Will pick it up + again when next the ABI changes. + * Expose apm for applications. + + -- Tim Gardner Wed, 19 Dec 2007 13:17:31 -0700 + +linux (2.6.24-2.3) hardy; urgency=low + + [Amit Kucheria] + + * LPIA: Add thermal framework from Intel + * LPIA: Poulsbo-specific patches + * LPIA: Add thermal framework from Intel + + [Tim Gardner] + + * SAUCE: hdaps module does not load on Thinkpad T61P + - LP: #133636 + + [Upstream Kernel Changes] + + * Rebased against 2.6.24-rc5 + + -- Tim Gardner Wed, 12 Dec 2007 13:58:52 -0700 + +linux (2.6.24-1.2) hardy; urgency=low + + [Ben Collins] + + * cell: Remove cell custom flavour, merged upstream + * apparmor: Added module from SVN repo + * ubuntu: Update configs to enable apparmor + * ubuntu/configs: Disable vga type framebuffers on hppa32. Fixes FTBFS + + [Tim Gardner] + + * Add support for PPA builds. + + [Upstream Kernel Changes] + + * [SPARC64] Export symbols for sunvnet and sunvdc to be built modular + + -- Ben Collins Fri, 07 Dec 2007 15:18:32 -0500 + +linux (2.6.24-1.1) hardy; urgency=low + + [Ben Collins] + + * ubuntu: Disable custom binary flavours for now + * ubuntu: Remove cruft in headers-postinst + * ubuntu: Set skipabi/skipmodule to true if prev_revions == 0.0 + * ubuntu: Do not fail on missing module lists when skipmodule is set + * ubuntu: capability.ko is built-in now, no need to place in initrd. + * ubuntu: Change to "linux" instead of "linux-source-2.6.x" + * d-i: cdrom-modules disappeared, and sha256/aes modules renamed. + * ubuntu-build: Add asm_link= to arch rules, and use them + * config: Re-enable snd-hda-intel + + -- Ben Collins Wed, 28 Nov 2007 12:58:37 -0500 + +linux-source-2.6.22 (2.6.22-14.46) gutsy; urgency=low + + [Upstream Kernel Changes] + + * [SPARC64]: Fix bugs in SYSV IPC handling in 64-bit processes. + + -- Kyle McMartin Sun, 14 Oct 2007 20:30:09 +0000 + +linux-source-2.6.22 (2.6.22-14.45) gutsy; urgency=low + + [Upstream Kernel Changes] + + * [SPARC64]: Fix register usage in xor_raid_4(). + + -- Kyle McMartin Sun, 14 Oct 2007 12:34:44 -0400 + +linux-source-2.6.22 (2.6.22-14.44) gutsy; urgency=low + + [Kyle McMartin] + + * Revert "sparc wants ehci built in" + + [Upstream Kernel Changes] + + * Revert "[PATCH]: Gutsy OHCI hang workaround for Huron" + * [USB]: Serialize EHCI CF initialization. + + -- Kyle McMartin Sun, 14 Oct 2007 16:25:51 +0000 + +linux-source-2.6.22 (2.6.22-14.43) gutsy; urgency=low + + [Kyle McMartin] + + * sparc wants ehci built in + + -- Kyle McMartin Tue, 09 Oct 2007 20:07:58 +0000 + +linux-source-2.6.22 (2.6.22-14.42) gutsy; urgency=low + + [Kyle McMartin] + + * fix up module-check to bail early if asked to ignore modules + * disable kernel DRM on lpia (we provide one in lum) + - LP: #145168 + * add ignore for ia64 abi too + + [Upstream Kernel Changes] + + * [NIU]: Use netif_msg_*(). + * [NIU]: Use pr_info(). + * [NIU]: Remove redundant BUILD_BUG_ON() in __niu_wait_bits_clear(). + * [NIU]: Remove BUG_ON() NULL pointer checks. + * [NIU]: Use dev_err(). + * [NIU]: Fix x86_64 build failure. + * [NIU]: Use linux/io.h instead of asm/io.h + * [NIU]: Fix some checkpatch caught coding style issues. + * [NIU]: Fix shadowed local variables. + * [NIU]: Fix locking errors in link_status_10g(). + * [NIU]: Document a few magic constants using comments. + * [NIU]: MII phy handling fixes. + * [NIU]: Make sure link_up status is set to something in + link_status_{1,10}g(). + * [PATCH]: Gutsy OHCI hang workaround for Huron + + -- Kyle McMartin Tue, 09 Oct 2007 17:25:06 +0000 + +linux-source-2.6.22 (2.6.22-14.41) gutsy; urgency=low + + [Ben Collins] + + * ubuntu/d-i: Add niu to nic-modules + + [Kyle McMartin] + + * vesafb is not for ia64 + * remove CONFIG_NIU from places it shouldn't be + * fix orinoco_cs oops + - LP: #149997 + + [Upstream Kernel Changes] + + * [SPARC64]: Allow userspace to get at the machine description. + * [SPARC64]: Niagara-2 optimized copies. + * [SPARC64]: Do not touch %tick_cmpr on sun4v cpus. + * [SPARC64]: SMP trampoline needs to avoid %tick_cmpr on sun4v too. + * [SPARC64]: Create a HWCAP_SPARC_N2 and report it to userspace on + Niagara-2. + * [MATH-EMU]: Fix underflow exception reporting. + * [SPARC64]: Need to clobber global reg vars in switch_to(). + * [MATH]: Fix typo in FP_TRAPPING_EXCEPTIONS default setting. + * [SUNVDC]: Use slice 0xff on VD_DISK_TYPE_DISK. + * [SPARC64]: Fix type and constant sizes wrt. sun4u IMAP/ICLR handling. + * [SPARC64]: Enable MSI on sun4u Fire PCI-E controllers. + * [SPARC64]: Fix several bugs in MSI handling. + * [SPARC64]: Fix booting on V100 systems. + * [SPARC64]: Fix lockdep, particularly on SMP. + * [SPARC64]: Warn user if cpu is ignored. + * [SUNSAB]: Fix several bugs. + * [SUNSAB]: Fix broken SYSRQ. + * [SPARC64]: Fix missing load-twin usage in Niagara-1 memcpy. + * [SPARC64]: Don't use in/local regs for ldx/stx data in N1 memcpy. + * [SPARC64]: Fix domain-services port probing. + * [SPARC64]: VIO device addition log message level is too high. + * [SPARC64]: check fork_idle() error + * [SPARC64]: Fix 'niu' complex IRQ probing. + * [NIU]: Add Sun Neptune ethernet driver. + + -- Kyle McMartin Tue, 09 Oct 2007 00:38:16 +0000 + +linux-source-2.6.22 (2.6.22-13.40) gutsy; urgency=low + + [Amit Kucheria] + + * Enable CONFIG_VM86 for LPIA + - LP: #146311 + * Update configuration files + * Disable MSI by default + * Add mmconf documentation + * Update configuration files + + [Bartlomiej Zolnierkiewicz] + + * ide-disk: workaround for buggy HPA support on ST340823A (take 3) + - LP: #26119 + + [Ben Collins] + + * ubuntu/cell: Fixup ps3 related modules for d-i, enable RTAS console + * ubuntu/cell: Enable CELLEB and related modules (pata_scc) + * ubuntu/cell: Move ps3rom to storage-core. Also use spidernet, not + spider_net. + * ubuntu/cell: Set PS3_MANAGER=y + * ubuntu: Set NR_CPUS=256 for sparc64-smp + + [Chuck Short] + + * [USB] USB] Support for MediaTek MT6227 in cdc-acm. + - LP: #134123 + * [XEN] Fix xen vif create with more than 14 guests. + - LP: #14486 + + [Jorge Juan Chico] + + * ide: ST320413A has the same problem as ST340823A + - LP: #26119 + + [Kyle McMartin] + + * fix -rt build + * fix ia32entry-xen.S for CVE-2007-4573 + * fix build when CONFIG_PCI_MSI is not set + + [Matthew Garrett] + + * hostap: send events on data interface as well as master interface + - LP: #57146 + * A malformed _GTF object should not prevent ATA device recovery + - LP: #139079 + * hostap: send events on data interface as well as master interface + - LP: #57146 + * A malformed _GTF object should not prevent ATA device recovery + - LP: #139079 + * Don't lose appletouch button release events + * Fix build with appletouch change + * Disable Thinkpad backlight support on machines with ACPI video + - LP: #148055 + * Don't attempt to register a callback if there is no CMOS object + - LP: #145857 + * Update ACPI bay hotswap code to support locking + - LP: #148219 + * Update ACPI bay hotswap code to support locking + - LP: #148219 + * Don't attempt to register a callback if there is no CMOS object + - LP: #145857 + * Disable Thinkpad backlight support on machines with ACPI video + - LP: #148055 + + [Steffen Klassert] + + * 3c59x: fix duplex configuration + - LP: #94186 + + [Thomas Gleixner] + + * clockevents: remove the suspend/resume workaround^Wthinko + + [Tim Gardner] + + * orinoco_cs.ko missing + - LP: #125832 + * Marvell Technology ethernet card not recognized and not operational + - LP: #135316 + * Marvell Technology ethernet card not recognized and not operational + - LP: #135316 + * acpi_scan_rsdp() breaks some PCs by not honouring ACPI specification + - LP: #144336 + * VIA southbridge Intel id missing + - LP: #128289 + * Add T-Sinus 111card to hostap_cs driver to be able to upload firmware + - LP: #132466 + * RTL8111 PCI Express Gigabit driver r8169 big files produce slow file + transfer + - LP: #114171 + * Guest OS does not recognize a lun with non zero target id on Vmware ESX + Server + - LP: #140761 + * Modualrize vesafb + - LP: #139505 + * Nikon cameras need support in unusual_devs.h + - LP: #134477 + * agp for i830m broken in gutsy + - LP: #139767 + * hdaps: Added support for Thinkpad T61 + - LP: #147383 + * xen: Update config for i386 + - LP: #139047 + * xen: resync for amd64 + - LP: #139047 + * ide-disk: workaround for buggy HPA support on ST340823A (take 4) + - LP: #26119 + + [Upstream Kernel Changes] + + * Convert snd-page-alloc proc file to use seq_file (CVE-2007-4571) + * Linux 2.6.22.8 + * ACPI: disable lower idle C-states across suspend/resume + * V4L: ivtv: fix VIDIOC_S_FBUF: new OSD values were never set + * DVB: get_dvb_firmware: update script for new location of sp8870 + firmware + * DVB: get_dvb_firmware: update script for new location of tda10046 + firmware + * DVB: b2c2-flexcop: fix Airstar HD5000 tuning regression + * setpgid(child) fails if the child was forked by sub-thread + * sigqueue_free: fix the race with collect_signal() + * kconfig: oldconfig shall not set symbols if it does not need to + * MTD: Makefile fix for mtdsuper + * USB: fix linked list insertion bugfix for usb core + * ACPI: Validate XSDT, use RSDT if XSDT fails + * POWERPC: Flush registers to proper task context + * 3w-9xxx: Fix dma mask setting + * MTD: Initialise s_flags in get_sb_mtd_aux() + * JFFS2: fix write deadlock regression + * V4L: cx88: Avoid a NULL pointer dereference during mpeg_open() + * hwmon: End of I/O region off-by-one + * Fix debug regression in video/pwc + * splice: fix direct splice error handling + * rpc: fix garbage in printk in svc_tcp_accept() + * disable sys_timerfd() + * afs: mntput called before dput + * Fix DAC960 driver on machines which don't support 64-bit DMA + * Fix "Fix DAC960 driver on machines which don't support 64-bit DMA" + * firewire: fw-ohci: ignore failure of pci_set_power_state (fix suspend + regression) + * futex_compat: fix list traversal bugs + * Leases can be hidden by flocks + * ext34: ensure do_split leaves enough free space in both blocks + * nfs: fix oops re sysctls and V4 support + * dir_index: error out instead of BUG on corrupt dx dirs + * ieee1394: ohci1394: fix initialization if built non-modular + * Correctly close old nfsd/lockd sockets. + * Fix race with shared tag queue maps + * crypto: blkcipher_get_spot() handling of buffer at end of page + * fix realtek phy id in forcedeth + * Fix decnet device address listing. + * Fix device address listing for ipv4. + * Fix inet_diag OOPS. + * Fix IPV6 append OOPS. + * Fix IPSEC AH4 options handling + * Fix ipv6 double-sock-release with MSG_CONFIRM + * Fix IPV6 DAD handling + * Fix ipv6 source address handling. + * Fix oops in vlan and bridging code + * Fix tc_ematch kbuild + * Handle snd_una in tcp_cwnd_down() + * Fix TCP DSACK cwnd handling + * Fix datagram recvmsg NULL iov handling regression. + * Fix pktgen src_mac handling. + * Fix sparc64 v100 platform booting. + * bcm43xx: Fix cancellation of work queue crashes + * Linux 2.6.22.9 + * usb: serial/pl2303: support for BenQ Siemens Mobile Phone EF81 + * pata_it821x: fix lost interrupt with atapi devices + * i915: make vbl interrupts work properly on i965g/gm hw. + + -- Kyle McMartin Thu, 04 Oct 2007 13:57:53 +0000 + +linux-source-2.6.22 (2.6.22-12.39) gutsy; urgency=low + + [Ben Collins] + + * ubuntu: Re-order deps so that binary-custom is done before + binary-udebs. Fixes ppc build + + [Upstream Kernel Changes] + + * x86_64: Zero extend all registers after ptrace in 32bit entry path. + * Linux 2.6.22.7 + + -- Ben Collins Sun, 23 Sep 2007 11:05:32 -0400 + +linux-source-2.6.22 (2.6.22-12.38) gutsy; urgency=low + + [Kyle McMartin] + + * add -12 abi files + * update getabis for new flavours + + -- Kyle McMartin Fri, 21 Sep 2007 13:35:49 -0400 + +linux-source-2.6.22 (2.6.22-12.37) gutsy; urgency=low + + [Kyle McMartin] + + * enable d-i for cell flavour + * ignore ABI check on all hppa flavours + + -- Kyle McMartin Fri, 21 Sep 2007 11:28:34 -0400 + +linux-source-2.6.22 (2.6.22-12.36) gutsy; urgency=low + + [Ben Collins] + + * ABI bump due to LED support being enabled. + + [Kyle McMartin] + + * fix memory leak in psparse.c + - Bug introduced in previous commit to acpi + + [Upstream Kernel Changes] + + * Ubuntu: Allocate acpi_devices structure rather than leaving it on the + stack. + * ipw2100: Fix `iwpriv set_power` error + * Fix ipw2200 set wrong power parameter causing firmware error + * [SCSI] Fix async scanning double-add problems + - LP: #110997 + + -- Ben Collins Thu, 20 Sep 2007 11:34:52 -0400 + +linux-source-2.6.22 (2.6.22-11.34) gutsy; urgency=low + + [Alan Stern] + + * USB: disable autosuspend by default for non-hubs + - LP: #85488 + + [Ben Collins] + + * ubuntu: Enable LEDS_TRIGGERS and related options + - Needed for iwlwifi + * ubuntu: Add real ABI files for virtual flavour + * ubuntu: Re-enable missing CONFIG_SERPENT for hppa64 + - Noticed by Lamont + * ubuntu: Add linux-headers postinst to handle hooks + - LP: #125816 + * ubuntu: Add support for /etc/kernel/headers_postinst.d/ to + headers-postinst + - LP: #120049 + * cell: Add binary-custom flavour "cell" to support ps3 + + [Mattia Dongili] + + * sony-laptop: restore the last user requested brightness level on + resume. + - LP: #117331 + + [Tejun Heo] + + * ata_piix: fix suspend/resume for some TOSHIBA laptops + - LP: #139045 + * PCI: export __pci_reenable_device() + - needed for ata_piix change + + [Tim Gardner] + + * Enable Sierra Wireless MC8775 0x6813 + - LP: #131167 + + [Zhang Rui] + + * ACPI: work around duplicate name "VID" problem on T61 + - Noted by mjg59 + + -- Ben Collins Sun, 16 Sep 2007 22:31:47 -0400 + +linux-source-2.6.22 (2.6.22-11.33) gutsy; urgency=low + + [Alessio Igor Bogani] + + * rt: Update to rt9 + * rt: Update configuration files + + [Ben Collins] + + * ubuntu: Enable A100 driver + - LP: #138632 + * libata: Default to hpa being overridden + + [Chuck Short] + + * [HDAPS] Add support for Thinkpad R61. + * [LIBATA] Add more hard drives to blacklist. + * [USB] Added support for Sprint Pantech PX-500. + * [XEN] No really enable amd64. + * [XEN] Fix amd64 yet again. + + [Matthew Garrett] + + * alter default behaviour of ACPI video module + * Add infrastructure for notification on ACPI method execution + * Get thinkpad_acpi to send notifications on CMOS updates + * Add support to libata-acpi for acpi-based bay hotplug + + [Phillip Lougher] + + * Add kernel flavour optimised for virtualised environments + * Change abi-check script to check for $flavour.ignore in previous abi + * Disable abi and module check for virtual flavour + + [Richard Hughes] + + * Refresh laptop lid status on resume + + [Upstream Kernel Changes] + + * [pata_marvell]: Add more identifiers + + -- Ben Collins Sun, 16 Sep 2007 22:13:08 -0400 + +linux-source-2.6.22 (2.6.22-11.32) gutsy; urgency=low + + [Amit Kucheria] + + * Build system: Allow custom builds to comprise multiple patches + * Move UME to a Custom build and add first setup of thermal framework + + [Ben Collins] + + * ubuntu: Enable CONFIG_BLK_DEV_IO_TRACE + * bcm203x: Fix firmware loading + - LP: #85247 + * ubuntu: mtd changes caused module renaming. Ignore + * rt: Do not patch top level Makefile for SUBLEVEL. Will always end up + breaking + + [Chuck Short] + + * [USB] Unusual Device support for Gold MP3 Player Energy + - LP: #125250 + * [SIERRA] Adds support for Onda H600 ZTE MF330 + - LP: #129433 + * [HDAPS] Add Thinkpad T61P to whitelist. + - LP: #133636 + * [USB] Add support for Toshiba (Novatel Wireless) HSDPA for M400. + - LP: #133650 + + [Kyle McMartin] + + * apparmor 10.3 hooks + * unionfs 2.1 hooks + * nuke UNION_FS stuff from fs/{Kconfig,Makefile} + + [Tim Gardner] + + * Paravirt-ops I/O hypercalls + * Fix lazy vmalloc bug for Gutsy + * bluetooth headset patch + - LP: #130870 + * Add the PCI ID of this ICH4 in list of laptops that use short cables. + * v2.6.22.5 merge + * Update Xen config options. + - LP: #132726 + * Remove mtd modules from ABI + * Support parallel= in DEB_BUILD_OPTIONS + - LP: #136426 + + [Upstream Kernel Changes] + + * hwmon: fix w83781d temp sensor type setting + * hwmon: (smsc47m1) restore missing name attribute + * sky2: restore workarounds for lost interrupts + * sky2: carrier management + * sky2: check for more work before leaving NAPI + * sky2: check drop truncated packets + * revert "x86, serial: convert legacy COM ports to platform devices" + * ACPICA: Fixed possible corruption of global GPE list + * ACPICA: Clear reserved fields for incoming ACPI 1.0 FADTs + * AVR32: Fix atomic_add_unless() and atomic_sub_unless() + * r8169: avoid needless NAPI poll scheduling + * forcedeth: fix random hang in forcedeth driver when using netconsole + * libata: add ATI SB700 device IDs to AHCI driver + * Hibernation: do not try to mark invalid PFNs as nosave + * i386: allow debuggers to access the vsyscall page with compat vDSO + * x86_64: Check for .cfi_rel_offset in CFI probe + * x86_64: Change PMDS invocation to single macro + * i386: Handle P6s without performance counters in nmi watchdog + * i386: Fix double fault handler + * JFFS2 locking regression fix. + * [Input]: appletouch - improve powersaving for Geyser3 devices + * [Input]: add driver for Fujitsu serial touchscreens + * [sdhci]: add support to ENE-CB714 + * v2.6.22.5 + * [MTD] Makefile fix for mtdsuper + * ocfs2: Fix bad source start calculation during kernel writes + * NET: Share correct feature code between bridging and bonding + * sky2: don't clear phy power bits + * uml: fix previous request size limit fix + * i386: fix lazy mode vmalloc synchronization for paravirt + * signalfd: fix interaction with posix-timers + * signalfd: make it group-wide, fix posix-timers scheduling + * DCCP: Fix DCCP GFP_KERNEL allocation in atomic context + * IPV6: Fix kernel panic while send SCTP data with IP fragments + * IPv6: Invalid semicolon after if statement + * Fix soft-fp underflow handling. + * Netfilter: Missing Kbuild entry for netfilter + * SNAP: Fix SNAP protocol header accesses. + * NET: Fix missing rcu unlock in __sock_create() + * SPARC64: Fix sparc64 task stack traces. + * SPARC64: Fix sparc64 PCI config accesses on sun4u + * TCP: Do not autobind ports for TCP sockets + * TCP: Fix TCP rate-halving on bidirectional flows. + * TCP: Fix TCP handling of SACK in bidirectional flows. + * PPP: Fix PPP buffer sizing. + * PCI: lets kill the 'PCI hidden behind bridge' message + * PCI: disable MSI on RS690 + * PCI: disable MSI on RD580 + * PCI: disable MSI on RX790 + * USB: allow retry on descriptor fetch errors + * USB: fix DoS in pwc USB video driver + * usb: add PRODUCT, TYPE to usb-interface events + * Linux 2.6.22.6 + * V4L/DVB (6042): b2c2-flexcop: fix Airstar HD5000 tuning regression + * V4L/DVB (5967): ivtv: fix VIDIOC_S_FBUF:new OSD values where never set + * Re-add _GTM and _STM support + + -- Ben Collins Fri, 31 Aug 2007 16:26:56 -0400 + +linux-source-2.6.22 (2.6.22-10.30) gutsy; urgency=low + + * URGENT upload to fix FTBFS with xen-{i386,amd64} configs, + lpia d-i ftbfs, xen ftbfs. + * URGENT fix module-check to actually ignore things + * URGENT ignore ume modules + + [Alek Du] + + * Add Intel Poulsbo chipset Libata support + + [Amit Kucheria] + + * Update configuration files + * Enable stylus on Lenovo X60/X61 thinkpads + + [Ben Collins] + + * ubuntu: Disable snd-hda-intel, in favor of lum updated version + + [Kyle McMartin] + + * apparmor 10.3 hooks + * add lpia d-i udeb generation + * fix bits of rt/diff for -rt8 + * fix rt/diff for 2.6.22.3 changes + * fix up rt/diff for stable 2.6.22.4 + + [LaMont Jones] + + * Update configuration files + + [Phillip Lougher] + + * WriteSupportForNTFS: make fuse module available to d-i + + [Tim Gardner] + + * Gutsy Tribe 3 CD don't load on Dell Inspiron 1501 + - LP: #121111 + * Update configuration files + * Update configuration files + * Update configuration files + + [Upstream Kernel Changes] + + * [SPARC64]: Fix handling of multiple vdc-port nodes. + * [SPARC64]: Tweak assertions in sun4v_build_virq(). + * [SPARC64]: Fix log message type in vio_create_one(). + * [SPARC64]: Fix two year old bug in early bootup asm. + * [SPARC64]: Improve VIO device naming further. + * [SPARC64]: Handle multiple domain-services-port nodes properly. + * [SPARC64]: Add proper multicast support to VNET driver. + * [SPARC64]: Do not flood log with failed DS messages. + * [SPARC64]: Use KERN_ERR in IRQ manipulation error printks. + * [SPARC64]: Fix virq decomposition. + * [SPARC]: Fix serial console device detection. + * [SPARC64]: fix section mismatch warning in pci_sunv4 + * [SPARC64]: fix section mismatch warning in mdesc.c + * [SPARC64] viohs: extern on function definition + * [SPARC64]: Fix sun4u PCI config space accesses on sun4u. + * [SPARC64]: Fix show_stack() when stack argument is NULL. + * [SUNLANCE]: Fix sparc32 crashes by using of_*() interfaces. + * [SPARC]: Centralize find_in_proplist() instead of duplicating N times. + * [SPARC64]: Fix hard-coding of cpu type output in /proc/cpuinfo on + sun4v. + * [SPARC64]: Do not assume sun4v chips have load-twin/store-init support. + * [SPARC64]: Fix memory leak when cpu hotplugging. + * USB: cdc-acm: fix sysfs attribute registration bug + * TCP FRTO retransmit bug fix + * Fix TC deadlock. + * Fix IPCOMP crashes. + * Fix console write locking in sparc drivers. + * Add a PCI ID for santa rosa's PATA controller. + * Missing header include in ipt_iprange.h + * SCTP scope_id handling fix + * Fix rfkill IRQ flags. + * gen estimator timer unload race + * gen estimator deadlock fix + * Fix error queue socket lookup in ipv6 + * Fix ipv6 link down handling. + * Netpoll leak + * Sparc64 bootup assembler bug + * Fix ipv6 tunnel endianness bug. + * Fix sparc32 memset() + * Fix sparc32 udelay() rounding errors. + * Fix TCP IPV6 MD5 bug. + * KVM: SVM: Reliably detect if SVM was disabled by BIOS + * USB: fix warning caused by autosuspend counter going negative + * usb-serial: Fix edgeport regression on non-EPiC devices + * Fix reported task file values in sense data + * aacraid: fix security hole + * firewire: fw-sbp2: set correct maximum payload (fixes CardBus adapters) + * make timerfd return a u64 and fix the __put_user + * V4L: Add check for valid control ID to v4l2_ctrl_next + * V4L: ivtv: fix broken VBI output support + * V4L: ivtv: fix DMA timeout when capturing VBI + another stream + * V4L: ivtv: Add locking to ensure stream setup is atomic + * V4L: wm8775/wm8739: Fix memory leak when unloading module + * Input: lifebook - fix an oops on Panasonic CF-18 + * splice: fix double page unlock + * drm/i915: Fix i965 secured batchbuffer usage (CVE-2007-3851) + * Fix leak on /proc/lockdep_stats + * CPU online file permission + * Fix user struct leakage with locked IPC shem segment + * md: handle writes to broken raid10 arrays gracefully + * md: raid10: fix use-after-free of bio + * pcmcia: give socket time to power down + * Fix leaks on /proc/{*/sched, sched_debug, timer_list, timer_stats} + * futex: pass nr_wake2 to futex_wake_op + * "ext4_ext_put_in_cache" uses __u32 to receive physical block number + * Include serial_reg.h with userspace headers + * dm io: fix panic on large request + * i386: HPET, check if the counter works + * fw-ohci: fix "scheduling while atomic" + * firewire: fix memory leak of fw_request instances + * softmac: Fix ESSID problem + * eCryptfs: ecryptfs_setattr() bugfix + * nfsd: fix possible read-ahead cache and export table corruption + * readahead: MIN_RA_PAGES/MAX_RA_PAGES macros + * fs: 9p/conv.c error path fix + * forcedeth bug fix: cicada phy + * forcedeth bug fix: vitesse phy + * forcedeth bug fix: realtek phy + * acpi-cpufreq: Proper ReadModifyWrite of PERF_CTL MSR + * jbd commit: fix transaction dropping + * jbd2 commit: fix transaction dropping + * hugetlb: fix race in alloc_fresh_huge_page() + * do not limit locked memory when RLIMIT_MEMLOCK is RLIM_INFINITY + * uml: limit request size on COWed devices + * sony-laptop: fix bug in event handling + * destroy_workqueue() can livelock + * drivers/video/macmodes.c:mac_find_mode() mustn't be __devinit + * cfq-iosched: fix async queue behaviour + * libata: add FUJITSU MHV2080BH to NCQ blacklist + * ieee1394: revert "sbp2: enforce 32bit DMA mapping" + * nfsd: fix possible oops on re-insertion of rpcsec_gss modules + * dm raid1: fix status + * dm io: fix another panic on large request + * dm snapshot: permit invalid activation + * dm: disable barriers + * cr_backlight_probe() allocates too little storage for struct cr_panel + * ACPI: dock: fix opps after dock driver fails to initialize + * Hangup TTY before releasing rfcomm_dev + * Keep rfcomm_dev on the list until it is freed + * nf_conntrack: don't track locally generated special ICMP error + * IPV6: /proc/net/anycast6 unbalanced inet6_dev refcnt + * sysfs: release mutex when kmalloc() failed in sysfs_open_file(). + * Netfilter: Fix logging regression + * USB: fix for ftdi_sio quirk handling + * sx: switch subven and subid values + * UML: exports for hostfs + * Linux 2.6.22.2 + * fix oops in __audit_signal_info() + * random: fix bound check ordering (CVE-2007-3105) + * softmac: Fix deadlock of wx_set_essid with assoc work + * ata_piix: update map 10b for ich8m + * PPC: Revert "[POWERPC] Don't complain if size-cells == 0 in + prom_parse()" + * PPC: Revert "[POWERPC] Add 'mdio' to bus scan id list for platforms + with QE UEC" + * powerpc: Fix size check for hugetlbfs + * direct-io: fix error-path crashes + * stifb: detect cards in double buffer mode more reliably + * pata_atiixp: add SB700 PCI ID + * CPUFREQ: ondemand: fix tickless accounting and software coordination + bug + * CPUFREQ: ondemand: add a check to avoid negative load calculation + * Linux 2.6.22.3 + * intel_agp: really fix 945/965GME + * Reset current->pdeath_signal on SUID binary execution (CVE-2007-3848) + * MSS(mmc/sd/sdio) driver patch + + -- Kyle McMartin Thu, 16 Aug 2007 12:17:27 -0400 + +linux-source-2.6.22 (2.6.22-9.25) gutsy; urgency=low + + [Kyle McMartin] + + * ubuntu: Fix FTBFS -- forgot to bump debian/abi + + -- Kyle McMartin Thu, 02 Aug 2007 22:13:28 +0000 + +linux-source-2.6.22 (2.6.22-9.24) gutsy; urgency=low + + [Colin Watson] + + * provide Provides for fs-*-modules udebs + + [Matthias Klose] + + * test $dilist before using it + + [Lamont Jones] + + * hppa: Update abi files + + -- Kyle McMartin Thu, 02 Aug 2007 18:26:34 +0000 + +linux-source-2.6.22 (2.6.22-9.23) gutsy; urgency=low + + [Ben Collins] + + * ubuntu: Add missing newline to module-check script + * ubuntu: Add lpia to linux-libc-dev. Should finally build now. + + -- Ben Collins Thu, 02 Aug 2007 13:10:23 -0400 + +linux-source-2.6.22 (2.6.22-9.22) gutsy; urgency=low + + [Ben Collins] + + * ubuntu: Use DEB_HOST_ARCH, not DEB_HOST_ARCH_CPU + + -- Ben Collins Thu, 02 Aug 2007 08:44:09 -0400 + +linux-source-2.6.22 (2.6.22-9.21) gutsy; urgency=low + + [Ben Collins] + + * lpia: Add build stuff for lpia architecture + + [LaMont Jones] + + * abi files for hppa + * UBUNTU-HPPA: configs that seem to work + * hppa: abi files for 9.20 + + -- Ben Collins Wed, 01 Aug 2007 11:12:59 -0400 + +linux-source-2.6.22 (2.6.22-9.20) gutsy; urgency=low + + [Ben Collins] + + * tulip: Fix for Uli5261 chipsets. + * tulip: Define ULI PCI ID's + * tulip: Let dmfe handle davicom on non-sparc + * input: Allow root to inject unknown scan codes. + * irda: Default to dongle type 9 on IBM hardware + * input/mouse/alps: Do not call psmouse_reset() for alps + * pcmcia: Do not insert pcmcia cards on resume + * ide-cd: Disable verbose errors. + * block: Make CDROMEJECT more robust + * pm: Config option to disable handling of console during suspend/resume. + * version: Implement version_signature proc file. + * update toshiba_acpi to 0.19a-dev + * xpad: Update to latest version from xbox-linux. + * ubuntu: Enable setting of CONFIG_VERSION_SIGNATURE at build time + * toshiba_acpi: Don't use init_MUTEX_LOCKED + + [Chuck Short] + + * [USB]: add ASUS LCM to the blacklist + * [NET]: Add mcp73 to forcedeth. + * [USB]: Added support for Sanwa PC5000 multimeter usb cable (KB-USB2). + * [ATA] Add support for Sb700 AHCI nor-raid5 and raid5 + + [Fabio M. Di Nitto] + + * drivers/char/vt.c: make promcon driver init a boot option. + + [Kyle McMartin] + + * Disable MMCONFIG by default + + [Phillip Lougher] + + * fix NFS mounting regression from Edgy->Feisty + * r8169: disable TSO by default for RTL8111/8168B chipsets. + + [Tim Gardner] + + * Catch nonsense keycodes and silently ignore + * Cause SoftMac to emit an association event when setting ESSID. + + -- Ben Collins Mon, 30 Jul 2007 12:01:43 -0400 + +linux-source-2.6.22 (2.6.22-9.19) gutsy; urgency=low + + [Amit Kucheria] + + * Fix for FTBFS bug 123178 + * Fix for FTBFS bug 123178 + * Add devices to USB quirks to prevent USB autosuspend + * More devices added to USB quirks + - LP: #85488 + * Support for ENE CB-712/4 SD card reader + * Reorder quirk list based on Vendor/Product ID + + [Ben Collins] + + * ubuntu: Enable HOTPLUG_CPU in sparc64-smp config. + * ubuntu: Add xen to amd64 custom builds + * ubuntu: Update real-time kernel to -rt4 + * rt: Patch from Alessio Igor Bogani for RT-8 + + [Chuck Short] + + * IDE: add MHV2080BH to NCQ blacklist + * XEN: update to 2.6.22 final and amd64 support. + * NET: Add more pci-ids to zd1211rw + * IDE: add new PCI ID + * USB: fix oops in ftdi_sio + + [Eric Piel] + + * ACPI: Allow custom DSDT tables to be loaded from initramfs + + [Ryan Lortie] + + * Macbook calibration loop fix + - LP: #54621 + + [Upstream Kernel Changes] + + * NETFILTER: {ip, nf}_conntrack_sctp: fix remotely triggerable NULL ptr + dereference (CVE-2007-2876) + * Linux 2.6.22.1 + * [SPARC64]: Use KERN_ERR in sun4v IRQ printk()'s. + * [SPARC64]: Add LDOM virtual channel driver and VIO device layer. + * [SPARC64]: Add Sun LDOM virtual network driver. + * [SPARC64]: Add Sun LDOM virtual disk driver. + * [SPARC64]: Create proper obppath sysfs files for VIO bus devices. + * [SPARC64] LDC: Do limited polled retry on setting RX queue head. + * [SUNVNET]: Validate RX descriptor size field. + * [SPARC64]: Add missing symbol exports for LDOM infrastructure. + * [SPARC64]: Temporary workaround for LDC INO double-delivery. + * [SPARC64]: Create 'devspec' nodes for vio devices. + * [SPARC64]: vdev->type can be NULL, handle this in devspec_show(). + * [SPARC64]: Assorted LDC bug cures. + * [SPARC64]: Add domain-services nodes to VIO device tree. + * [SPARC64]: Export powerd facilities for external entities. + * [SPARC64]: Initial domain-services driver. + * [SPARC64]: Use more mearningful names for IRQ registry. + * [SPARC64]: Abstract out mdesc accesses for better MD update handling. + * [SPARC64]: Fix MD property lifetime bugs. + * [SPARC64]: Fix setting of variables in LDOM guest. + * [SPARC64]: Initial LDOM cpu hotplug support. + * [SPARC64]: Unconditionally register vio_bus_type. + * [SPARC64]: Fix build regressions added by dr-cpu changes. + * [SPARC64]: mdesc.c needs linux/mm.h + * [SPARC64]: SMP build fixes. + * [SPARC64]: More sensible udelay implementation. + * [SPARC64]: Process dr-cpu events in a kthread instead of workqueue. + * [SPARC64]: Add ->set_affinity IRQ handlers. + * [SPARC64]: Fix leak when DR added cpu does not bootup. + * [SPARC64]: Clear cpu_{core,sibling}_map[] in + smp_fill_in_sib_core_maps() + * [SPARC64]: Give more accurate errors in dr_cpu_configure(). + * [SERIAL]: Fix console write locking in sparc drivers. + * [TIMER]: Fix clockevent notifications on 64-bit. + * [SPARC64]: dr-cpu unconfigure support. + * [SPARC64]: Fix UP build. + * [SPARC64]: SMP build fix. + * [SPARC64]: Fix race between MD update and dr-cpu add. + * [SERIAL] SUNHV: Fix jerky console on LDOM guests. + * [SPARC64]: Kill explicit %gl register reference. + * [SPARC64]: Add basic infrastructure for MD add/remove notification. + * [SPARC64]: Simplify VDC device probing. + * [SPARC64]: Simplify VNET probing. + * [SPARC64]: Massively simplify VIO device layer and support hot + add/remove. + * [SPARC64]: Handle LDC resets properly in domain-services driver. + * [SPARC64]: Handle reset events in vio_link_state_change(). + * [SPARC64]: Fix reset handling in VNET driver. + * [SPARC64]: Set vio->desc_buf to NULL after freeing. + * [SPARC64]: Fix MODULE_DEVICE_TABLE() specification in VDC and VNET. + * [SPARC64]: Fix device type matching in VIO's devspec_show(). + * Add empty + * Add dummy isa_(bus|virt)_to_(virt|bus) inlines + * Clean up sti_flush + * Do not allow STI_CONSOLE to be modular + * Use compat_sys_getdents + + -- Ben Collins Sat, 28 Jul 2007 12:30:53 -0400 + +linux-source-2.6.22 (2.6.22-8.18) gutsy; urgency=low + + [Ben Collins] + + * ubuntu: *sigh* update xen config to fix FTBFS + + -- Ben Collins Thu, 12 Jul 2007 14:23:20 +0100 + +linux-source-2.6.22 (2.6.22-8.17) gutsy; urgency=low + + [Ben Collins] + + * ubuntu: Actually enable the -xen build. + + -- Ben Collins Thu, 12 Jul 2007 09:51:01 +0100 + +linux-source-2.6.22 (2.6.22-8.16) gutsy; urgency=low + + * Removed CONFIG_BLINK from all configs and added to modules.ignore + * This fixes a build failure for 8.15 + + [Alexey Starikovskiy] + + * Fix ACPI battery detection on Asus + + [Amit Kucheria] + + * Export symbols required to build GFS1 in LUM + * Update configuration files + * 2.6.22-7.14 ABI + * Remove old ABI + * Update d-i modules to support Sparc LDOM + * Introducing the UME kernel flavour + + [Jacob Pan] + + * Poulsbo SMBus Controller + * Intel Poulsbo SCH IDE Controller + * Intel Poulsbo HD audio controller + + [Phillip Lougher] + + * xen: Update custom binary flavour (Xen 3.1 for 2.6.22-rc5) + * xen: Update xen/config.i386 to enable PAE + + [Upstream Kernel Changes] + + * [SCSI] fusion: fix for BZ 8426 - massive slowdown on SCSI CD/DVD drive + * [XFS] Update the MAINTAINERS file entry for XFS. + * IB/mlx4: Fix handling of wq->tail for send completions + * IB/mlx4: Fix warning in rounding up queue sizes + * [SCSI] ESP: Don't forget to clear ESP_FLAG_RESETTING. + * firewire: fix hang after card ejection + * ieee1394: fix to ether1394_tx in ether1394.c + * [ARM] Add support for pause_on_oops and display preempt/smp options + * sh: Fix restartable syscall arg5 clobbering. + * ACPI: gracefully print null trip-point device + * ACPICA: fix error path in new external package objects as method + arguments + * sh: oops_enter()/oops_exit() in die(). + * [ARM] Update show_regs/oops register format + * IB/mlx4: Handle new FW requirement for send request prefetching + * IB/mlx4: Get rid of max_inline_data calculation + * IB/mlx4: Handle buffer wraparound in __mlx4_ib_cq_clean() + * IB/mlx4: Handle FW command interface rev 3 + * Fix signalfd interaction with thread-private signals + * sched: fix SysRq-N (normalize RT tasks) + * Fix possible runqueue lock starvation in wait_task_inactive() + * sh: Handle -ERESTART_RESTARTBLOCK for restartable syscalls. + * sh64: Handle -ERESTART_RESTARTBLOCK for restartable syscalls. + * [POWERPC] Fix snd-powermac refcounting bugs + * [XFS] s/memclear_highpage_flush/zero_user_page/ + * [XFS] Update the MAINTAINERS file entry for XFS - change git repo name. + * [XFRM]: Fix MTU calculation for non-ESP SAs + * [IPVS]: Fix state variable on failure to start ipvs threads + * [AF_RXRPC]: Return the number of bytes buffered in rxrpc_send_data() + * [S390] Missing blank when appending cio_ignore kernel parameter + * [S390] Fix zfcpdump header + * [S390] Fix yet another two section mismatches. + * [S390] Print list of modules on die(). + * [S390] Add oops_enter()/oops_exit() calls to die(). + * [S390] Move psw_set_key. + * [POWERPC] rheap - eliminates internal fragments caused by alignment + * [POWERPC] PowerPC: Prevent data exception in kernel space (32-bit) + * [POWERPC] Fix powermac late initcall to only run on powermac + * [MIPS] Don't drag a platform specific header into generic arch code. + * x86_64: Fix readahead/sync_file_range/fadvise64 compat calls + * x86_64: Fix eventd/timerfd syscalls + * x86: Disable DAC on VIA bridges + * x86_64: Quieten Atari keyboard warnings in Kconfig + * x86: Only make Macintosh drivers default on Macs + * x86: Disable KPROBES with DEBUG_RODATA for now + * x86: change_page_attr bandaids + * x86_64: fix link warning between for .text and .init.text + * Fix up CREDIT entry ordering + * firewire: Only set client->iso_context if allocation was successful. + * spidernet: null out skb pointer after its been used. + * spidernet: Cure RX ram full bug + * spidernet: Don't terminate the RX ring + * spidernet: silence the ramfull messages + * spidernet: turn off descriptor chain end interrupt. + * spidernet: checksum and ethtool + * bonding: Fix use after free in unregister path + * bonding: Fix 802.3ad no carrier on "no partner found" instance + * s390: print correct level for HiperSockets devices + * s390: qeth driver does not recover + * s390: avoid inconsistent lock state in qeth + * s390: qeth: wrong packet length in qdio header + * s390: Use ccw_device_get_id() in qeth/claw drivers + * s390: don't call iucv_path_connect from tasklet context + * s390: netiucv spinlock initializer cleanup + * s390: netiucv inlining cleanup + * forcedeth: use unicast receive mode for WoL + * natsemi irq flags + * cxgb3 - fix skb->dev dereference + * cxgb3 - fix netpoll hanlder + * cxgb3 - Fix direct XAUI support + * cxgb3 - Stop mac RX when changing MTU + * cxgb3 - MAC watchdog update + * PATA: Add the MCP73/77 support to PATA driver + * pata_it821x: (partially) fix DMA in RAID mode + * libata: more NONCQ devices + * kerneldoc fix in libata + * ahci: fix PORTS_IMPL override + * fix module_param mistake in it821x + * Blackfin arch: update ANOMALY handling + * Blackfin arch: update printk to use KERN_EMERG and reformat crash + output + * Blackfin arch: add missing braces around array bfin serial init + * Blackfin arch: match kernel startup messaage with new linker script + * Blackfin arch: move cond_syscall() behind __KERNEL__ like all other + architectures + * Blackfin arch: Add definition of dma_mapping_error + * Blackfin arch: add proper const volatile to addr argument to the read + functions + * [AGPGART] intel_agp: don't load if no IGD and AGP port + * IB/umem: Fix possible hang on process exit + * IPoIB/cm: Initialize RX before moving QP to RTR + * IPoIB/cm: Fix interoperability when MTU doesn't match + * IPoIB/cm: Remove dead definition of struct ipoib_cm_id + * IB/mlx4: Correct max_srq_wr returned from mlx4_ib_query_device() + * [PARISC] stop lcd driver from stripping initial whitespace + * [PARISC] Handle wrapping in expand_upwards() + * [PARISC] Fix unwinder on 64-bit kernels + * [PARISC] unwinder improvements + * page_mapping must avoid slub pages + * posix-timers: Prevent softirq starvation by small intervals and SIG_IGN + * Allow DEBUG_RODATA and KPROBES to co-exist + * [NETFILTER]: nf_conntrack_sip: add missing message types containing RTP + info + * [NETFILTER]: nfctnetlink: Don't allow to change helper + * [IPV6] NDISC: Fix thinko to control Router Preference support. + * [IPV4]: include sysctl.h from inetdevice.h + * i386: Make CMPXCHG64 only dependent on PAE + * x86_64: Fix only make Macintosh drivers default on Macs + * x86_64: Ignore compat mode SYSCALL when IA32_EMULATION is not defined + * [AVR32] Fix bug in invalidate_dcache_region() + * [AVR32] NGW100, Remove relics of the old USART mapping scheme + * [AVR32] Initialize dma_mask and dma_coherent_mask + * [AVR32] Update defconfigs + * ACPI: fix 2.6.20 SMP boot regression + * [SKBUFF]: Fix incorrect config #ifdef around skb_copy_secmark + * [TIPC]: Fix infinite loop in netlink handler + * [PPP]: Revert 606f585e363527da9feaed79465132c0c661fd9e + * [PPP]: Fix osize too small errors when decoding mppe. + * [TCP] tcp_read_sock: Allow recv_actor() return return negative error + value. + * [NET]: Re-enable irqs before pushing pending DMA requests + * [NET]: Make skb_seq_read unmap the last fragment + * hwmon/coretemp: fix a broken error path + * fix refcounting of nsproxy object when unshared + * console UTF-8 fixes (fix) + * SM501: suspend support + * SM501: initialise SDRAM clock before bus clocks + * SM501: Fix sm501_init_reg() mask/set order + * SM501: Clock updates and checks + * SM501: Add Documentation/SM501.txt + * SM501: Check SM501 ID register on initialisation + * SLUB: fix behavior if the text output of list_locations overflows + PAGE_SIZE + * sched: fix next_interval determination in idle_balance() + * update checkpatch.pl to version 0.05 + * alpha: fix alignment problem in csum_ipv6_magic() + * Char: stallion, fix oops during init with ISA cards + * uml: use generic BUG + * uml: add asm/paravirt.h + * "volatile considered harmful" + * document nlink function + * slab allocators: MAX_ORDER one off fix + * update checkpatch.pl to version 0.06 + * x86_64: fix misplaced `continue' in mce.c + * ext2: disallow setting xip on remount + * audit: fix oops removing watch if audit disabled + * ext3: lost brelse in ext3_read_inode() + * ext4: lost brelse in ext4_read_inode() + * ACPI: preserve the ebx value in acpi_copy_wakeup_routine + * FUTEX: Restore the dropped ERSCH fix + * Linus 2.6.22-rc6 + * [ARM] 4452/1: Force the literal pool dump before reloc_end + * [ARM] 4449/1: more entries in arch/arm/boot/.gitignore + * fix nmi_watchdog=2 bootup hang + * [POWERPC] Update g5_defconfig + * [POWERPC] Update defconfigs + * [POWERPC] Fix VDSO gettimeofday() when called with NULL struct timeval + * [POWERPC] Fix subtle FP state corruption bug in signal return on SMP + * USB: g_file_storage: call allow_signal() + * USB: ti serial driver sleeps with spinlock held + * USB: memory leak in iowarrior.c + * USB: usblcd doesn't limit memory consumption during write + * USB: fix race leading to use after free in io_edgeport + * USB: add new device id to option driver + * USB: ftdio_sio: New IPlus device ID + * [MIPS] __ucmpdi2 arguments are unsigned long long. + * [MIPS] add io_map_base to pci_controller on Cobalt + * [MIPS] remove "support for" from system type entry + * [MIPS] Alchemy: Fix wrong cast + * [MIPS] Fix pb1500 reg B access + * [MIPS] AP/SP requires shadow registers, auto enable support. + * [MIPS] 20K: Handle WAIT related bugs according to errata information + * [MIPS] use compat_siginfo in rt_sigframe_n32 + * [MIPS] Remove a duplicated local variable in test_and_clear_bit() + * [MIPS] EMMA2RH: Disable GEN_RTC, it can't possibly work. + * [MIPS] SMTC and non-SMTC kernel and modules are incompatible + * [MIPS] Count timer interrupts correctly. + * x86_64: set the irq_chip name for lapic + * x86_64 irq: use mask/unmask and proper locking in fixup_irqs() + * [SPARC64]: Add irqs to mdesc_node. + * [SPARC64]: Fix VIRQ enabling. + * [SPARC64]: Need to set state to IDLE during sun4v IRQ enable. + * [SPARC64]: Add LDOM virtual channel driver and VIO device layer. + * [SPARC64]: Add Sun LDOM virtual network driver. + * [SPARC64]: Add Sun LDOM virtual disk driver. + * [SPARC64]: Create proper obppath sysfs files for VIO bus devices. + * [SPARC64] LDC: Do limited polled retry on setting RX queue head. + * [GFS2] Fix gfs2_block_truncate_page err return + * [DLM] Telnet to port 21064 can stop all lockspaces + * [GFS2] inode size inconsistency + * [GFS2] remounting w/o acl option leaves acls enabled + * [GFS2] System won't suspend with GFS2 file system mounted + * [GFS2] git-gfs2-nmw-build-fix + * [GFS2] Obtaining no_formal_ino from directory entry + * [GFS2] Remove i_mode passing from NFS File Handle + * [SUNVNET]: Validate RX descriptor size field. + * [SPARC64]: Add missing symbol exports for LDOM infrastructure. + * [SPARC64]: Temporary workaround for LDC INO double-delivery. + * [SPARC64]: Create 'devspec' nodes for vio devices. + * [SPARC64]: vdev->type can be NULL, handle this in devspec_show(). + + -- Amit Kucheria Mon, 09 Jul 2007 12:55:56 +0300 + +linux-source-2.6.22 (2.6.22-7.14) gutsy; urgency=low + + [Ben Collins] + + * build/vars: Provide ivtv-modules + * Bump ABI + * ubuntu/config: Enable Intermediate Functional Block device + * coredump: Fix typo in patch merge + * ubuntu/scripts: Make sure to symlink *.lds for ia64 builds + * ubuntu/config: Enable NO_HZ for server and sparc64 targets. + * ubuntu/config: Remove bigiron target, see if anyone complains + * ubuntu: Ok, really remove bigiron + * ubuntu/control-scripts: Fo sho, remove the debconf stuff from controls + scripts + * AppArmor: Enable exports and changes for AppArmor usage + * ubuntu: Add feisty changelog for historical purposes. + + [Colin Watson] + + * Move isofs to storage-core-modules udeb from fs-core-modules. + + [Upstream Kernel Changes] + + * [MTD] [MAPS] don't force uclinux mtd map to be root dev + * [MTD] generalise the handling of MTD-specific superblocks + * [SCSI] zfcp: avoid clutter in erp_dbf + * [SCSI] zfcp: IO stall after deleting and path checker changes after + reenabling zfcp devices + * [SCSI] ipr: Proper return codes for eh_dev_reset for SATA devices + * [SCSI] stex: fix id mapping issue + * [SCSI] stex: extend hard reset wait time + * [SCSI] stex: fix reset recovery for console device + * [SCSI] stex: minor cleanup and version update + * [SCSI] MegaRAID: Update MAINTAINERS email-id + * [SCSI] tgt: fix a rdma indirect transfer error bug + * [SCSI] NCR53C9x: correct spelling mistake in deprecation notice + * [SCSI] aacraid: Correct sa platform support. (Was: [Bug 8469] Bad EIP + value on pentium3 SMP kernel-2.6.21.1) + * [SCSI] aacraid: fix panic on short Inquiry + * [WATCHDOG] ks8695_wdt.c - new KS8695 watchdog driver + * [JFFS2] Fix BUG() caused by failing to discard xattrs on deleted files. + * [JFFS2] Fix potential memory leak of dead xattrs on unmount. + * [SCSI] sd: fix refcounting regression in suspend/resume routines + * [SCSI] aacraid: apply commit config for reset_devices flag + * [SCSI] aic7xxx: fix aicasm build failure with gcc-3.4.6 + * [SCSI] aic94xx: asd_clear_nexus should fail if the cleared task does + not complete + * [SCSI] fusion: Fix |/|| confusion + * parisc: make command_line[] static + * parisc: sync compat getdents + * [PARISC] Move #undef to end of syscall table + * [PARISC] Wire up kexec_load syscall + * parisc: convert /proc/gsc/pcxl_dma to seq_file + * [PARISC] Let PA-8900 processors boot + * [PARISC] Disable LWS debugging + * [PARISC] spelling fixes: arch/parisc/ + * sh: section mismatch fixes for system timer. + * [PARISC] ROUND_UP macro cleanup in arch/parisc + * [PARISC] ROUNDUP macro cleanup in drivers/parisc + * [PPC] Fix COMMON symbol warnings + * [PPC] Remove duplicate export of __div64_32. + * [POWERPC] 52xx: unbreak lite5200 dts (_pic vs. -pic) + * [POWERPC] QE: fix Kconfig 'select' warning with UCC_FAST + * [POWERPC] Fix Section mismatch warnings + * [POWERPC] Fix modpost warning + * [PPC] Fix modpost warning + * [CIFS] Fix oops on failed cifs mount (in kthread_stop) + * [POWERPC] Fix Kconfig warning + * [CIFS] typo in previous patch + * [SCSI] megaraid_sas: intercept cmd timeout and throttle io + * [WATCHDOG] clean-up watchdog documentation + * drm: Spinlock initializer cleanup + * drm/radeon: add more IGP chipset pci ids + * drm: make sure the drawable code doesn't call malloc(0). + * [PARISC] kobject is embedded in subsys, not kset + * [PARISC] Build fixes for power.c + * [ARM] 4401/1: S3C2443: Add definitions for port GPIOJ + * [ARM] 4402/1: S3C2443: Add physical address of HSMMC controller + * [ARM] 4403/1: Make the PXA-I2C driver work with lockdep validator + * [ARM] 4404/1: Trivial IXP42x Kconfig cleanup + * [ARM] 4405/1: NSLU2, DSM-G600 frequency fixup code + * [ARM] 4406/1: Trivial NSLU2 / NAS-100D header & setup code cleanup + * [ARM] remove unused header file: arch/arm/mach-s3c2410/bast.h + * [PARISC] fix lasi_82596 build + * [PARISC] fix section mismatch in parport_gsc + * [PARISC] fix section mismatch in parisc STI video drivers + * [PARISC] fix section mismatch in ccio-dma + * [PARISC] fix section mismatches in arch/parisc/kernel + * [PARISC] fix section mismatch in parisc eisa driver + * [PARISC] fix section mismatch in superio serial drivers + * [PARISC] Wire up utimensat/signalfd/timerfd/eventfd syscalls + * hwmon/ds1621: Fix swapped temperature limits + * hwmon/coretemp: Add more safety checks + * hwmon/w83627hf: Be quiet when no chip is found + * hwmon-vid: Don't spam the logs when VRM version is missing + * hwmon/applesmc: Simplify dependencies + * hwmon/applesmc: Handle name file creation error and deletion + * ieee1394: sbp2: include workqueue.h + * ieee1394: eth1394: remove bogus netif_wake_queue + * ieee1394: eth1394: handle tlabel exhaustion + * ieee1394: eth1394: bring back a parent device + * ieee1394: raw1394: Fix async send + * firewire: Add missing byteswapping for receive DMA programs. + * firewire: prefix modules with firewire- instead of fw- + * firewire: fix return code + * [libata] Add drive to NCQ blacklist + * [ARM] enable arbitary speed tty ioctls and split input/output speed + * Input: db9 - do not ignore dev2 module parameter + * Input: logips2pp - fix typo in Kconfig + * [XFS] Write at EOF may not update filesize correctly. + * [SCSI] pluto: Use wait_for_completion_timeout. + * [SPARC64]: Kill unused DIE_PAGE_FAULT enum value. + * [SPARC64]: Don't be picky about virtual-dma values on sun4v. + * [SPARC32]: Removes mismatch section warnigs in sparc time.c file + * [SERIAL] sunzilog: section mismatch fix + * [SPARC64]: PCI device scan is way too verbose by default. + * [SCSI] jazz_esp: Converted to use esp_core. + * [SCSI] ESP: Kill SCSI_ESP_CORE and link directly just like jazz_esp + * [SPARC64]: Fix typo in sun4v_hvapi_register error handling. + * [SPARC64]: Report proper system soft state to the hypervisor. + * [SPARC64]: Negotiate hypervisor API for PCI services. + * [SPARC64]: Use machine description and OBP properly for cpu probing. + * [SPARC64]: Eliminate NR_CPUS limitations. + * [SPARC64]: arch/sparc64/time.c doesn't compile on Ultra 1 (no PCI) + * [SPARC]: Linux always started with 9600 8N1 + * [SPARC64]: Fix _PAGE_EXEC_4U check in sun4u I-TLB miss handler. + * [SPARC]: Emulate cmpxchg like parisc + * [SPARC]: Mark as emulating cmpxchg, add appropriate depends for DRM. + * [SPARC64]: Fix two bugs wrt. kernel 4MB TSB. + * [SPARC64]: Fill holes in hypervisor APIs and fix KTSB registry. + * mac80211: fail back to use associate from reassociate + * mac80211: fix memory leak when defrag fragments + * mac80211: always set carrier status on open + * mac80211: avoid null ptr deref in ieee80211_ibss_add_sta + * prism54: fix monitor mode oops + * ieee80211: fix incomplete error message + * softmac: alloc_ieee80211() NULL check + * hostap: Allocate enough tailroom for TKIP + * sparc64: fix alignment bug in linker definition script + * USB: replace flush_workqueue with cancel_sync_work + * ACPICA: allow Load(OEMx) tables + * ACPI: thermal: Replace pointer with name in trip_points + * ACPI: extend "acpi_osi=" boot option + * IB/mthca: Fix handling of send CQE with error for QPs connected to SRQ + * IPoIB/cm: Fix performance regression on Mellanox + * IB/cm: Fix stale connection detection + * IB/mlx4: Fix last allocated object tracking in bitmap allocator + * NOHZ: prevent multiplication overflow - stop timer for huge timeouts + * random: fix error in entropy extraction + * random: fix seeding with zero entropy + * ACPI: Make _OSI(Linux) a special case + * ACPI: add __init to acpi_initialize_subsystem() + * [PARISC] fix "ENTRY" macro redefinition + * [PARISC] fix section mismatch in smp.c + * [PARISC] remove remnants of parisc-specific softirq code + * [PARISC] fix trivial spelling nit in asm/linkage.h + * [PARISC] fix null ptr deref in unwind.c + * [PARISC] fix "reduce size of task_struct on 64-bit machines" fallout + * [PARISC] be more defensive in process.c::get_wchan + * [ARM] use __used attribute + * [ARM] Fix stacktrace FP range checking + * [ARM] oprofile: avoid lockdep warnings on mpcore oprofile init + * [ARM] 4411/1: KS8695: Another serial driver fix + * [ARM] 4412/1: S3C2412: reset errata fix + * [ARM] 4414/1: S3C2443: sparse fix for clock.c + * [ARM] 4415/1: AML5900: fix sparse warnings from map_io + * [ARM] 4416/1: NWFPE: fix undeclared symbols + * [ARM] 4410/1: Remove extern declarations in coyote/ixdpg425-pci.c + * [ARM] 4394/1: ARMv7: Add the TLB range operations + * [ARM] 4417/1: Serial: Fix AMBA drivers locking + * sky2: dont set bogus bit in PHY register + * sky2: checksum offload plus vlan bug + * sky2: program proper register for fiber PHY + * defxx: Fix the handling of ioremap() failures + * e1000: restore netif_poll_enable call but make sure IRQs are off + * sky2: enable IRQ on duplex renegotiation + * ehea: Fixed multi queue RX bug + * [SCSI] fix CONFIG_SCSI_WAIT_SCAN=m + * [SCSI] qla2xxx: fix timeout in qla2x00_down_timeout + * [ARM] Fix some section mismatch warnings + * alpha: cleanup in bitops.h + * alpha: support new syscalls + * fix possible null ptr deref in kallsyms_lookup + * NFS: Fix a refcount leakage in O_DIRECT + * a bug in ramfs_nommu_resize function, passing old size to vmtruncate + * sh: Fix pcrel too far for in_nmi label. + * sh: Trivial fix for dma-api compile failure. + * sh: Fix vsyscall build failure. + * sh: trivial build cleanups. + * sh: support older gcc's + * [ALSA] HDA: Add support for Gateway NX860 + * [ALSA] HDA: Add more systems to Sigmatel codec + * [ALSA] HDA: Fix headphone mute issue on non-eapd Conexant systems + * [ALSA] hda-codec - Add support for ASUS A8J modem + * [ALSA] ali5451 - Fix possible NULL dereference + * [ALSA] hda-intel: fix ASUS M2V detection + * [ALSA] Fix ASoC s3c24xx-pcm spinlock bug + * [ALSA] hda-codec - Add quirk for MSI S420 + * [ALSA] hda-codec - Add quirk for Supermicro PDSBA to alc883_cfg_tbl[] + * [ALSA] hda-codec - Add support for MSI K9N Ultra + * [ALSA] hda-codec - Fix pin configs for Gateway MX6453 + * [ALSA] hda-codec - Fix input with STAC92xx + * [ALSA] hda-codec - Fix STAC922x capture boost level + * [CRYPTO] cryptd: Fix problem with cryptd and the freezer + * [CASSINI]: Fix printk message typo. + * [XFRM]: Allow XFRM_ACQ_EXPIRES to be tunable via sysctl. + * [XFRM]: xfrm_larval_drop sysctl should be __read_mostly. + * [IPSEC]: Fix IPv6 AH calculation in outbound + * [IPV6] ROUTE: No longer handle ::/0 specially. + * [NET]: parse ip:port strings correctly in in4_pton + * [IPSEC]: Fix panic when using inter address familiy IPsec on loopback. + * [IPV4]: Kill references to bogus non-existent CONFIG_IP_NOSIOCRT + * [AF_PACKET]: Kill bogus CONFIG_PACKET_MULTICAST + * [IPV6]: Fix build warning. + * [AF_PACKET]: Kill CONFIG_PACKET_SOCKET. + * [SOCK]: Shrink struct sock by 8 bytes on 64-bit. + * [TCP]: Consolidate checking for tcp orphan count being too big. + * [NET] napi: Call __netif_rx_complete in netif_rx_complete + * [IPV6] ADDRCONF: Fix conflicts in DEVCONF_xxx constant. + * [TCP] tcp_probe: a trivial fix for mismatched number of printl + arguments. + * [TCP] tcp_probe: use GCC printf attribute + * [BRIDGE]: Reduce frequency of forwarding cleanup timer in bridge. + * [BRIDGE]: Round off STP perodic timers. + * [IPSEC]: Add xfrm_sysctl.txt. + * [SPARC64]: Add missing NCS and SVC hypervisor interfaces. + * [SPARC32]: Build fix. + * [SPARC]: Missing #include in drivers/sbus/char/flash.c + * [ALSA] version 1.0.14 + * neofb: Fix pseudo_palette array overrun in neofb_setcolreg + * smpboot: fix cachesize comparison in smp_tune_scheduling() + * at91: fix enable/disable_irq_wake symmetry in pcmcia driver + * SLUB: More documentation + * pci-quirks: fix MSI disabling on RS400-200 and RS480 + * ntfs_init_locked_inode(): fix array indexing + * m68k: runtime patching infrastructure + * SLUB: Fix NUMA / SYSFS bootstrap issue + * afs: needs sched.h + * m68k: discontinuous memory support + * [S390] Add exception handler for diagnose 224 + * [S390] dasd_eer: use mutex instead of semaphore + * [S390] arch/s390/kernel/debug.c: use mutex instead of semaphore + * [S390] raw3270: use mutex instead of semaphore + * [S390] Fix section annotations. + * [S390] cio: Use device_schedule_callback() for removing disconnected + devices. + * [S390] cio: deregister ccw device when pgid disband failed + * ACPI: thinkpad-acpi: do not use named sysfs groups + * ieee1394: fix calculation of sysfs attribute "address" + * ieee1394: sbp2: offer SAM-conforming target port ID in sysfs + * firewire: fw-sbp2: implement sysfs ieee1394_id + * firewire: add to MAINTAINERS + * firewire: Implement suspend/resume PCI driver hooks. + * firewire: Change struct fw_cdev_iso_packet to not use bitfields. + * firewire: Install firewire-constants.h and firewire-cdev.h for + userspace. + * EXT4: Fix whitespace + * Remove unnecessary exported symbols. + * ext4: Extent overlap bugfix + * When ext4_ext_insert_extent() fails to insert new blocks + * Define/reserve new ext4 superblock fields + * msi: fix ARM compile + * PCI: disable MSI by default on systems with Serverworks HT1000 chips + * PCI: Fix pci_find_present + * PCI: i386: fixup for Siemens Nixdorf AG FSC Multiprocessor Interrupt + Controllers + * PCI: quirk disable MSI on via vt3351 + * [XTENSA] fix bit operations in bitops.h + * [XTENSA] Spelling fixes in arch/xtensa + * [XTENSA] fix sources using deprecated assembler directive + * [XTENSA] Remove multi-exported symbols from xtensa_ksyms.c + * [XTENSA] Use generic 64-bit division + * [XTENSA] clean-up header files + * [XTENSA] Move common sections into bss sections + * [XTENSA] Remove non-rt signal handling + * Xtensa: use asm-generic/fcntl.h + * [JFFS2] Fix buffer length calculations in jffs2_get_inode_nodes() + * Fix vmi.c compilation + * x86_64: allocate sparsemem memmap above 4G + * Add select PHYLIB to the UCC_GETH Kconfig option + * Fix possible UDF data corruption + * m68k: parenthesis balance + * msi: fix the ordering of msix irqs + * msi: mask the msix vector before we unmap it + * potential parse error in ifdef + * parse errors in ifdefs + * pci_ids: update patch for Intel ICH9M + * x86: fix oprofile double free + * Work around Dell E520 BIOS reboot bug + * fix compat futex code for private futexes + * skeletonfb: fix of xxxfb_setup ifdef + * vt8623fb: arkfb: null pointer dereference fix + * cfag12864bfb: Use sys_ instead of cfb_ framebuffer accessors + * fbdev: Move declaration of fb_class to + * misc/tifm_7xx1: replace deprecated irq flag + * add a trivial patch style checker + * Documentation: How to use GDB to decode OOPSes + * RTC: use fallback IRQ if PNP tables don't provide one + * memory hotplug: fix unnecessary calling of init_currenty_empty_zone() + * tty: fix leakage of -ERESTARTSYS to userland + * ISDN4Linux: fix maturity label + * Fix broken CLIR in isdn driver + * prism54: MAINTAINERS update + * atmel_spi dma address bugfix + * h8300 trival patches + * ALPHA: support graphics on non-zero PCI domains + * ALPHA: correct low-level I/O routines for sable-lynx + * ALPHA: misc fixes + * Better documentation for ERESTARTSYS + * serial_core.h: include + * SPI: Freescale iMX SPI controller driver fixes + * SLUB: fix locking for hotplug callbacks + * pm3fb: switching between X and fb fix + * microcode: fix section mismatch warning + * isdn: fix section mismatch warnings + * acpi: fix section mismatch warning in asus + toshiba + * kvm: fix section mismatch warning in kvm-intel.o + * net/hp100: fix section mismatch warning + * timer statistics: fix race + * timer stats: speedups + * [SCSI] aacraid: fix shutdown handler to also disable interrupts. + * [MTD] Fix error checking after get_mtd_device() in get_sb_mtd functions + * [JFFS2] Fix obsoletion of metadata nodes in jffs2_add_tn_to_tree() + * ACPI: Section mismatch ... acpi_map_pxm_to_node + * ACPICA: Support for external package objects as method arguments + * Pull now into release branch + * Pull osi-now into release branch + * [POWERPC] Update documentation for of_find_node_by_type() + * [POWERPC] Fix ppc32 single-stepping out of syscalls + * [POWERPC] Fix compiler/assembler flags for Ebony platform boot files + * [POWERPC] Fix possible access to free pages + * [POWERPC] ps3/interrupt.c uses get_hard_smp_processor_id + * [POWERPC] pasemi idle uses hard_smp_processor_id + * [POWERPC] Create a zImage for legacy iSeries + * [POWERPC] Don't use HOSTCFLAGS in BOOTCFLAGS + * [POWERPC] Fix compile warning in pseries xics code + * [POWERPC] Fix return from pte_alloc_one() in out-of-memory case + * [POWERPC] Compare irq numbers with NO_IRQ not IRQ_NONE + * [POWERPC] Don't allow PMAC_APM_EMU for 64-bit + * [POWERPC] Fix compile breakage for IBM/AMCC 4xx arch/ppc platforms + * [POWERPC] Fix zImage.coff generation for 32-bit pmac + * [ARM] 4392/2: Do not corrupt the SP register in compressed/head.S + * [ARM] 4418/1: AT91: Number of programmable clocks differs + * [ARM] 4419/1: AT91: SAM9 USB clocks check for suspending + * [ARM] 4422/1: Fix default value handling in gpio_direction_output (PXA) + * [ARM] Solve buggy smp_processor_id() usage + * qla3xxx: device doesnt do hardware checksumming. + * VLAN: kill_vid is only useful for VLAN filtering devices + * sky2: Fix VLAN unregistration + * 8139cp: fix VLAN unregistration + * atl1: eliminate unneeded kill_vid code + * network drivers: eliminate unneeded kill_vid code + * e1000: disable polling before registering netdevice + * smc91x: sh solution engine fixes. + * Update tulip maintainer email address + * NetXen: Removal of extra free_irq call + * myri10ge: report link up/down in standard ethtool way + * NET: add MAINTAINERS entry for ucc_geth driver + * [ARM] 4421/1: AT91: Value of _KEY fields. + * [PARISC] Fix bug when syscall nr is __NR_Linux_syscalls + * [AF_UNIX]: Make socket locking much less confusing. + * [TG3]: Fix link problem on Dell's onboard 5906. + * [AF_UNIX]: Fix datagram connect race causing an OOPS. + * [TCP]: Use default 32768-61000 outgoing port range in all cases. + * [ATM]: Fix warning. + * [NET]: Make net watchdog timers 1 sec jiffy aligned. + * [NET]: Fix comparisons of unsigned < 0. + * [TCP]: Fix GSO ignorance of pkts_acked arg (cong.cntrl modules) + * [NET] gso: Fix GSO feature mask in sk_setup_caps + * [IPV4]: Fix "ipOutNoRoutes" counter error for TCP and UDP + * [ICMP]: Fix icmp_errors_use_inbound_ifaddr sysctl + * [VIDEO]: XVR500 and XVR2500 require FB=y + * [ATA]: Don't allow to enable this for SPARC64 without PCI. + * sh: Fix in_nmi symbol build error. + * sh: microdev: Fix compile warnings. + * sh: Fix SH4-202 clock fwk set_rate() mismatch. + * sh: voyagergx: Fix build warnings. + * sh: ioremap() through PMB needs asm/mmu.h. + * sh: Fix se73180 platform device registration. + * Input: ucb1x00 - do not access input_dev->private directly + * Input: reduce raciness when input handlers disconnect + * [PARISC] Fix kernel panic in check_ivt + * [SCSI] atari_NCR5380: update_timeout removal + * [SCSI] JAZZ ESP and SUN ESP need SPI_ATTRS + * [CIFS] fix mempool destroy done in wrong order in cifs error path + * SPI dynamic busid generation bugfix + * mtrr atomicity fix + * vanishing ioctl handler debugging + * libata: always use polling SETXFER + * Linux 2.6.22-rc4 + * [SPARC64]: Move topology init code into new file, sysfs.c + * [SPARC64]: Export basic cpu properties via sysfs. + * [SPARC64]: Fix service channel hypervisor function names. + * [SPARC64]: Provide mmu statistics via sysfs. + * [SPARC64]: Proper multi-core scheduling support. + * [SPARC64]: Make core and sibling groups equal on UltraSPARC-IV. + * [SPARC64]: Fix {mc,smt}_capable(). + * [SPARC64]: Fill in gaps in non-PCI dma_*() NOP implementation. + * [ATA]: Back out bogus (SPARC64 && !PCI) Kconfig depends. + * [VIDEO]: Fix section mismatch warning in promcon. + * [CIFS] whitespace cleanup + * [ARM] Fix 4417/1: Serial: Fix AMBA drivers locking + * [VIDEO] ffb: The pseudo_palette is only 16 elements long + * [ARM] pxa: fix pxa27x keyboard driver + * [VIDEO] sunxvr2500fb: Fix pseudo_palette array size + * [VIDEO] sunxvr500fb: Fix pseudo_palette array size + * [CIFS] whitespace cleanup part 2 + * [CIFS] Missing flag on negprot needed for some servers to force packet + signing + * [MIPS] Atlas, Malta, SEAD: Remove scroll from interrupt handler. + * [MIPS] Remove duplicate fpu enable hazard code. + * [MIPS] EMMA2RH: remove dead KGDB code + * [MIPS] RM300: Fix MMIO problems by marking the PCI INT ACK region busy + * [MIPS] Fix VGA corruption on RM300C + * [MIPS] Drop __ARCH_WANT_SYS_FADVISE64 + * [MIPS] Make dma_map_sg handle sg elements which are longer than one + page + * [MIPS] Fix some system calls with long long arguments + * [MIPS] Remove prototype for deleted function qemu_handle_int + * [MIPS] Fix some minor typoes in arch/mips/Kconfig. + * [MIPS] Fix warning by moving do_default_vi into CONFIG_CPU_MIPSR2_SRS + * [AGPGART] intel_agp: cleanup intel private data + * [AGPGART] intel_agp: use table for device probe + * [AGPGART] intel_agp: add support for 965GME/GLE + * [AGPGART] intel_agp: add support for 945GME + * [AGPGART] intel_agp: Add support for G33, Q33 and Q35 chipsets + * ocfs2: Fix masklog breakage + * ocfs2: Fix invalid assertion during write on 64k pages + * [POWERPC] pasemi: Fix iommu + 64K PAGE_SIZE bug + * [POWERPC] spufs: Refuse to load the module when not running on cell + * [POWERPC] spufs: Hook up spufs_release_mem + * [POWERPC] spufs: Fix gang destroy leaks + * [POWERPC] spufs: Free mm if spufs_fill_dir() failed + * [POWERPC] spufs: Synchronize pte invalidation vs ps close + * [POWERPC] spufs scheduler: Fix wakeup races + * [POWERPC] Fix pci_setup_phb_io_dynamic for pci_iomap + * [POWERPC] cbe_cpufreq: Limit frequency via cpufreq notifier chain + * [POWERPC] scc_sio: Fix link failure + * [POWERPC] Fix typo in booting-without-of-txt section numbering + * [POWERPC] spufs: Don't yield nosched context + * [POWERPC] Add table of contents to booting-without-of.txt + * [POWERPC] spufs: Fix error handling in spufs_fill_dir() + * mmc-atmel: remove linux/mmc/protocol.h dependencies + * au1xmmc: Replace C code with call to ARRAY_SIZE() macro. + * mmc: fix broken if clause + * mmc: don't call switch on old cards + * [POWERPC] Fix building of COFF zImages + * checkpatch.pl: should be executable + * Restrict clearing TIF_SIGPENDING + * mlx4_core: Fix CQ context layout + * mlx4_core: Initialize ctx_list and ctx_lock earlier + * mlx4_core: Free catastrophic error MSI-X interrupt with correct dev_id + * IB/mthca, mlx4_core: Fix typo in comment + * [BNX2]: Fix netdev watchdog on 5708. + * [BNX2]: Add missing wait in bnx2_init_5709_context(). + * [BNX2]: Enable DMA on 5709. + * [BNX2]: Fix occasional counter corruption on 5708. + * [BNX2]: Update version and reldate. + * [TCP]: Honour sk_bound_dev_if in tcp_v4_send_ack + * [IPV4]: Only panic if inetdev_init fails for loopback + * [IPV4]: Convert IPv4 devconf to an array + * [IPV4]: Add default config support after inetdev_init + * [IPV4]: Restore old behaviour of default config values + * [RFKILL]: Make rfkill->name const + * [TCP]: Use LIMIT_NETDEBUG in tcp_retransmit_timer(). + * [TCP] tcp_probe: Attach printf attribute properly to printl(). + * [NETLINK]: Mark netlink policies const + * [RTNETLINK]: ifindex 0 does not exist + * [NETFILTER]: nf_conntrack: fix helper module unload races + * [NETFILTER]: ip_tables: fix compat related crash + * [NETFILTER]: nf_conntrack_amanda: fix textsearch_prepare() error check + * [AF_UNIX]: Fix stream recvmsg() race. + * [UDP]: Revert 2-pass hashing changes. + * [NET]: Avoid duplicate netlink notification when changing link state + * [NET_SCHED]: Fix filter double free + * xfrm: Add security check before flushing SAD/SPD + * [SPARC64]: Fix 2 bugs in PCI Sabre bus scanning. + * [SPARC64]: Fix SBUS IRQ regression caused by PCI-E driver. + * frv: build fix + * enable interrupts in user path of page fault. + * RAMFS NOMMU: missed POSIX UID/GID inode attribute checking + * [SPARC64]: Include instead of . + * [SPARC64]: Handle PCI bridges without 'ranges' property. + * mlx4_core: Check firmware command interface revision + * mlx4_core: Don't set MTT address in dMPT entries with PA set + * IB/mlx4: Fix zeroing of rnr_retry value in ib_modify_qp() + * RDMA/cma: Fix initialization of next_port + * IB/mlx4: Make sure RQ allocation is always valid + * splice: move inode size check into generic_file_splice_read() + * splice: remove do_splice_direct() symbol export + * pipe: move pipe_inode_info structure decleration up before it's used + * splice: move balance_dirty_pages_ratelimited() outside of splice actor + * splice: __generic_file_splice_read: fix i_size_read() length checks + * splice: __generic_file_splice_read: fix read/truncate race + * V4L/DVB (5702): Fix Kconfig items to avoid linkedition errors + * V4L/DVB (5700): Saa7111: fix picture settings cache bug + * V4L/DVB (5699): Cinergyt2: fix file release handler + * V4L/DVB (5675): Move big PIO accesses from the interrupt handler to a + workhandler + * V4L/DVB (5716): Tda10086,tda826x: fix tuning, STR/SNR values + * V4L/DVB (5720): Usbvision: fix urb allocation and submits + * V4L/DVB (5730): Remove unused V4L2_CAP_VIDEO_OUTPUT_POS + * V4L/DVB (5732): Add ivtv CROPCAP support and fix ivtv S_CROP for video + output. + * V4L/DVB (5736): Add V4L2_FBUF_CAP/FLAG_LOCAL/GLOBAL_INV_ALPHA + * V4L/DVB (5673): Fix audio stuttering for saa711x/ivtv when in radio + mode. + * V4L/DVB (5761): Fix broken b2c2 dependency on non x86 architectures + * V4L/DVB (5751): Ivtv: fix ia64 printk format warnings. + * serverworks: remove crappy code + * serverworks: fix CSB6 tuning logic + * it821x: RAID mode fixes + * ide: HPA detect from resume + * ide: generic IDE PCI driver, add another device exception + * hpt366: disallow Ultra133 for HPT374 + * Add the PATA controller device ID to pci_ids.h for MCP73/MCP77. + * ide: Add the MCP73/77 support to PATA driver + * [CIFS] CIFS should honour umask + * update Documentation/driver-model/platform.txt + * Driver core: keep PHYSDEV for old struct class_device + * Driver core: kill unused code + * kobject: use the proper printk level for kobject error + * firmware: remove orphaned Email + * [IPV4]: Do not remove idev when addresses are cleared + * [NetLabel]: consolidate the struct socket/sock handling to just struct + sock + * [CIPSO]: Fix several unaligned kernel accesses in the CIPSO engine. + * USB: set default y for CONFIG_USB_DEVICE_CLASS + * usblp: Don't let suspend to kill ->used + * USB: usb gadgets avoid le{16,32}_to_cpup() + * USB: UNUSUAL_DEV: Sync up some reported devices from Ubuntu + * USB: cxacru: add Documentation file + * USB: cxacru: create sysfs attributes in atm_start instead of bind + * USB: cxacru: ignore error trying to start ADSL in atm_start + * USB: Fix up bogus bInterval values in endpoint descriptors + * OHCI: Fix machine check in ohci_hub_status_data + * update checkpatch.pl to version 0.03 + * m68knommu: fix ColdFire timer off by 1 + * nommu: report correct errno in message + * loop: preallocate eight loop devices + * document Acked-by: + * update feature-removal-schedule.txt to include deprecated functions + * mount -t tmpfs -o mpol=: check nodes online + * slab: fix alien cache handling + * potential parse error in ifdef part 3 + * SLUB: return ZERO_SIZE_PTR for kmalloc(0) + * uml: fix kernel stack size on x86_64 + * Documentation/atomic_ops.txt typo fix + * Move three functions that are only needed for CONFIG_MEMORY_HOTPLUG + * Char: stallion, don't fail with less than max panels + * Char: stallion, alloc tty before pci devices init + * Char: stallion, proper fail return values + * uml: get declaration of simple_strtoul + * isdn/diva: fix section mismatch + * sata_promise: use TF interface for polling NODATA commands + * rt-mutex: fix stale return value + * rt-mutex: fix chain walk early wakeup bug + * pi-futex: fix exit races and locking problems + * fix sysrq-m oops + * x86_64: oops_begin() fix + * reiserfs: mailing list has moved + * checkpatch: produce fewer lines of output + * MAINTAINERS: corrections + * hexdump: more output formatting + * update checkpatch.pl to version 0.04 + * Protect from multiple inclusion + * [IrDA]: Fix Rx/Tx path race. + * [IrDA]: f-timer reloading when sending rejected frames. + * ibmveth: Fix h_free_logical_lan error on pool resize + * ibmveth: Automatically enable larger rx buffer pools for larger mtu + * typo in via-velocity.c + * NetXen: Fix ping issue after reboot on Blades with 3.4.19 firmware + * NetXen: Fix compile failure seen on PPC architecture + * ehea: Fixed possible kernel panic on VLAN packet recv + * phylib: add RGMII-ID mode to the Marvell m88e1111 PHY to fix broken + ucc_geth + * net: fix typo in drivers/net/usb/Kconfig + * remove unused variable in pata_isapnp + * libata: disable NCQ for HITACHI HTS541680J9SA00/SB21C7EP + * libata: fix probe time irq printouts + * libata: print device model and firmware revision for ATAPI devices + * libata: fix hw_sata_spd_limit initialization + * ahci: Add MCP73/MCP77 support to AHCI driver + * libata-core/sff: Fix multiple assumptions about DMA + * libata: Correct abuse of language + * libata passthru: update protocol numbers + * libata passthru: support PIO multi commands + * libata passthru: map UDMA protocols + * libata passthru: always enforce correct DEV bit + * libata passthru: update cached device paramters + * i915: add new pciids for 945GME, 965GME/GLE + * drm/i915: Add support for the G33, Q33, and Q35 chipsets. + * drm: fix radeon setparam on 32/64 bit systems. + * [ARM] VFP: fix section mismatch error + * libata: force PIO on IOMEGA ZIP 250 ATAPI + * libata: limit post SRST nsect/lbal wait to ~100ms + * Blackfin arch: remove defconfig file + * Blackfin arch: DMA code minor naming convention fix + * Blackfin arch: spelling fixes + * Blackfin arch: fix bug ad1836 fails to build properly for BF533-EZKIT + * Blackfin arch: all symbols were offset by 4k, since we didn't have the + __text label. + * Blackfin arch: mark our memory init functions with __init so they get + freed after init + * Blackfin arch: implement a basic /proc/sram file for L1 allocation + visibility + * Blackfin arch: fixup Blackfin MAINTIANERS team member list + * Blackfin arch: scrub old console defines + * Blackfin arch: update defconfigs + * Blackfin arch: unify differences between our diff head.S files -- no + functional changes + * Blackfin arch: move more of our startup code to .init so it can be + freed once we are up and running + * Blackfin arch: add proper ENDPROC() + * Blackfin arch: try to split up functions like this into smaller units + according to LKML review + * Blackfin arch: fix spelling typo in output + * Blackfin arch: As Mike pointed out range goes form m..MAX_BLACKFIN_GPIO + -1 + * Blackfin arch: add missing gpio.h header to fix compiling in some pm + configurations + * Blackfin arch: add support for Alon Bar-Lev's dynamic kernel + command-line + * Blackfin arch: fix bug can not wakeup from sleep via push buttons + * Blackfin arch: make sure we initialize our L1 Data B section properly + based on the linked kernel + * Blackfin arch: redo our linker script a bit + * Blackfin arch: move HI/LO macros into blackfin.h and punt the rest of + macros.h as it includes VDSP macros we never use + * Blackfin serial driver: hook up our UARTs STP bit with userspaces + CMSPAR + * Blackfin serial driver: ignore framing and parity errors + * Blackfin serial driver: actually implement the break_ctl() function + * Blackfin serial driver: decouple PARODD and CMSPAR checking from PARENB + * Blackfin RTC drivers: update MAINTAINERS information + * Blackfin SPI driver: tweak spi cleanup function to match newer kernel + changes + * [ARM] 4442/1: OSIRIS: Fix CPLD register definitions + * [ARM] 4443/1: OSIRIS: Add watchdog device to machine devices + * [ARM] 4444/2: OSIRIS: CPLD suspend fix + * [ARM] 4445/1: ANUBIS: Fix CPLD registers + * Blackfin SPI driver: fix bug SPI DMA incomplete transmission + * Blackfin SMC91X ethernet supporting driver: SMC91C111 LEDs are note + drived in the kernel like in uboot + * [MIPS] Fix KMODE for the R3000 + * [MIPS] SMTC: Don't set and restore irqregs ptr from self_ipi. + * [MIPS] Always install the DSP exception handler. + * [MIPS] Atlas: Fix build. + * [MIPS] Wire up utimensat, signalfd, timerfd, eventfd + * [MIPS] SMTC: Fix warning. + * [MIPS] SMTC: Don't continue in set_vi_srs_handler on detected bad + arguments. + * [MIPS] SMTC: The MT ASE requires to initialize c0_pagemask and + c0_wired. + * [MIPS] SMTC: Fix build error caused by nonsense code. + * [MIPS] Fix modpost warnings by making start_secondary __cpuinit + * [MIPS] Fix IP27 build + * [MIPS] Fix smp barriers in test_and_{change,clear,set}_bit + * libertas: scan two channels per scan command + * libertas: rename wlan_association_worker + * libertas: a debug output was missing a newline + * libertas: fix removal of all debugfs files + * libertas: remove deprecated pm_register and associated code + * libertas: remove __FILE__ from debug output + * libertas: remove unused/superfluous definitions of DEV_NAME_LEN + * libertas: move vendor & product id's into if_usb.c + * libertas: make libertas_wlan_data_rates static + * libertas: fix scanning from associate path + * libertas: exclude non-used code when PROC_DEBUG is not set + * libertas: make debug configurable + * libertas: tune debug code + * libertas: single out mesh code + * libertas: change debug output of libertas_interrupt() + * libertas: get rid of libertas_sbi_get_priv() + * libertas: fix SSID output + * libertas: changed some occurences of kmalloc() + memset(&a,0,sz) to + kzalloc() + * libertas: move reset_device() code main.c to if_usb.c + * libertas: split wlan_add_card() + * libertas: fixed transmission flow control on the mesh interface + * libertas: fix error handling of card initialization + * libertas: added transmission failures to mesh statistics + * libertas: wakeup both mesh and normal wakeup when getting out of scan + * libertas: indirect all hardware access via hw_XXXX functions + * libertas: move contents of fw.h to decl.h + * libertas: split module into two (libertas.ko and usb8xxx.ko) + * libertas: fix RESET logic at unload time + * libertas: let DRV_NAME be overridable + * libertas: remove unused variables in wlan_dev_t + * libertas: fixed incorrect assigment of fcs errors to frag errors + * libertas: add URB debug info + * libertas: fixed kernel oops on module/card removal + * libertas: call SET_NETDEV_DEV from common code + * libertas: replace 'macaddress' with 'bssid' + * libertas: correctly unregister mesh netdev on error + * libertas: don't tear down netdev in libertas_activate_card + * libertas: version bump (321p0) and cmds update for new fw (5.220.10.p0) + * libertas: updated mesh commands for 5.220.9.p11 + * libertas: make scan result handling more flexible + * libertas: fix 'keep previous scan' behavior + * libertas: cleanup of fwt_list_route processing + * libertas: fix oops on rmmod + * libertas: move channel changing into association framework + * libertas: make association paths consistent + * libertas: use MAC_FMT and MAC_ARG where appropriate + * libertas: use compare_ether_addr() rather than memcmp() where + appropriate + * libertas: fix debug enter/leave prints for + libertas_execute_next_command + * libertas: correctly balance locking in libertas_process_rx_command + * libertas: correct error report paths for wlan_fwt_list_ioctl + * libertas: fix deadlock SIOCGIWSCAN handler + * libertas: fix default adhoc channel + * libertas: honor specific channel requests during association + * libertas: send SIOCGIWSCAN event after partial scans too + * libertas: debug print spacing fixes in assoc.c + * libertas: add more verbose debugging to libertas_cmd_80211_authenticate + * libertas: Make WPA work through supplicant handshake + * libertas: updated readme file + * libertas: make mac address configuration work with mesh interface too + * libertas: split wext for eth and msh + * libertas: support for mesh autostart on firmware 5.220.11 + * libertas: fix character set in README + * libertas: sparse fixes + * libertas: first pass at fixing up endianness issues + * libertas: More endianness fixes. + * libertas: more endianness fixes, in tx.c this time + * libertas: don't byte-swap firmware version number. It's a byte array. + * libertas: fix big-endian associate command. + * libertas: tweak association debug output + * libertas: remove structure WLAN_802_11_SSID and libertas_escape_essid + * libertas: remove WPA_SUPPLICANT structure + * libertas: reduce SSID and BSSID mixed-case abuse + * kbuild: fix sh64 section mismatch problems + * cfg80211: fix signed macaddress in sysfs + * mac80211: fix debugfs tx power reduction output + * mac80211: Don't stop tx queue on master device while scanning. + * Input: usbtouchscreen - fix fallout caused by move from drivers/usb + * Input: i8042 - add ASUS P65UP5 to the noloop list + * Input: i8042 - add ULI EV4873 to noloop list + * [PARISC] remove global_ack_eiem + * libertas: pull current channel from firmware on mesh autostart + * libertas: deauthenticate from AP in channel switch + * libertas: actually send mesh frames to mesh netdev + * libertas: convert libertas_mpp into anycast_mask + * [PPP_MPPE]: Fix "osize too small" check. + * NetXen: Fix link status messages + * myri10ge: limit the number of recoveries + * myri10ge: report when the link partner is running in Myrinet mode + * myri10ge: update driver version + * sysfs: store sysfs inode nrs in s_ino to avoid readdir oopses + * sysfs: fix condition check in sysfs_drop_dentry() + * sysfs: fix race condition around sd->s_dentry, take#2 + * [TCP]: Fix left_out setting during FRTO + * Input: move input-polldev to drivers/input + * [SPARC64]: Wire up cookie based sun4v interrupt registry. + * [SPARC64]: Fix IO/MEM space sizing for PCI. + * [SPARC64]: Really fix parport. + * [SPARC64]: Fix args to sun4v_ldc_revoke(). + * [TCP]: Set initial_ssthresh default to zero in Cubic and BIC. + * mmc-omap: fix sd response type 6 vs. 1 + * mmc: get back read-only switch function + * [SCTP]: Correctly set daddr for IPv6 sockets during peeloff + * [SCTP]: Allow unspecified port in sctp_bindx() + * [SCTP] Fix leak in sctp_getsockopt_local_addrs when copy_to_user fails + * [SCTP] Update pmtu handling to be similar to tcp + * [SCTP] Flag a pmtu change request + * [SCTP] Don't disable PMTU discovery when mtu is small + * [POWERPC] Fix per-cpu allocation on oldworld SMP powermacs + * [POWERPC] Fix console output getting dropped on platforms without + udbg_putc + * [AVR32] ratelimit segfault reporting rate + * [AVR32] gpio_*_cansleep() fix + * [AVR32] STK1000: Set SPI_MODE_3 in the ltv350qv board info + * [AVR32] Define ARCH_KMALLOC_MINALIGN to L1_CACHE_BYTES + * [MIPS] Malta: Fix for SOCitSC based Maltas + * [MIPS] Separate performance counter interrupts + * [MIPS] Fix builds where MSC01E_xxx is undefined. + * [TCP]: Add missing break to TCP option parsing code + * [IPV6] addrconf: Fix IPv6 on tuntap tunnels + * [AGPGART] intel_agp: fix device probe + * KVM: Prevent guest fpu state from leaking into the host + * splice: adjust balance_dirty_pages_ratelimited() call + * splice: fix leak of pages on short splice to pipe + * splice: only check do_wakeup in splice_to_pipe() for a real pipe + * [TCP]: Congestion control API RTT sampling fix + * [TCP]: Fix logic breakage due to DSACK separation + * [RXRPC] net/rxrpc/ar-connection.c: fix NULL dereference + * block: always requeue !fs requests at the front + * mm: Fix memory/cpu hotplug section mismatch and oops. + * Resume from RAM on HPC nx6325 broken + * ide-scsi: fix OOPS in idescsi_expiry() + * fix radeon setparam on 32/64 systems, harder. + * tty: restore locked ioctl file op + * i386: fix NMI watchdog not reserving its MSRs + * i386: use the right wrapper to disable the NMI watchdog + * SLUB slab validation: Alloc while interrupts are disabled must use + GFP_ATOMIC + * Restore shmid as inode# to fix /proc/pid/maps ABI breakage + * i386 mm: use pte_update() in ptep_test_and_clear_dirty() + * cpuset: zero malloc - fix for old cpusets + * toshiba_acpi: fix section mismatch in allyesconfig + * swsusp: Fix userland interface + * perfctr-watchdog: fix interchanged parameters to + release_{evntsel,perfctr}_nmi + * fuse: ->fs_flags fixlet + * md: fix two raid10 bugs + * md: fix bug in error handling during raid1 repair + * spi doc updates + * uml: remove PAGE_SIZE from libc code + * uml: kill x86_64 STACK_TOP_MAX + * random: fix output buffer folding + * Rework ptep_set_access_flags and fix sun4c + * SLUB: minimum alignment fixes + * udf: fix possible leakage of blocks + * hugetlb: fix get_policy for stacked shared memory files + * shm: fix the filename of hugetlb sysv shared memory + * Linux 2.6.22-rc5 + * [GFS2] flush the glock completely in inode_go_sync + * [DLM] fix a couple of races + * [GFS2] kernel changes to support new gfs2_grow command + * [GFS2] Kernel changes to support new gfs2_grow command (part 2) + * [GFS2] use zero_user_page + * [GFS2] Addendum patch 2 for gfs2_grow + * [GFS2] Reduce size of struct gdlm_lock + * [GFS2] Clean up inode number handling + * [GFS2] Quotas non-functional - fix bug + * [DLM] keep dlm from panicing when traversing rsb list in debugfs + * [DLM] block scand during recovery [1/6] + * [DLM] add lock timeouts and warnings [2/6] + * [DLM] dlm_device interface changes [3/6] + * [DLM] cancel in conversion deadlock [4/6] + * [DLM] fix new_lockspace error exit [5/6] + * [DLM] wait for config check during join [6/6] + * [DLM] fix compile breakage + * [GFS2] latest gfs2-nmw headers break userland build + * [DLM] Compile fix + * [DLM] timeout fixes + * [DLM] canceling deadlocked lock + * [DLM] dumping master locks + * [DLM] show default protocol + * [GFS2] Quotas non-functional - fix another bug + * [GFS2] Make the log reserved blocks depend on block size + * [DLM] fix socket shutdown + * [GFS2] fix jdata issues + * [GFS2] Fix sign problem in quota/statfs and cleanup _host structures + * [GFS2] Add nanosecond timestamp feature + * [DLM] fix reference counting + * [DLM] variable allocation + * [GFS2] Fix typo in rename of directories + * [GFS2] Fix bug in error path of inode + * [GFS2] Can't mount GFS2 file system on AoE device + * [GFS2] Recovery for lost unlinked inodes + * [GFS2] gfs2_lookupi() uninitialised var fix + * [GFS2] set plock owner in GETLK info + * [GFS2] return conflicts for GETLK + * [GFS2] Fix deallocation issues + * [DLM] don't require FS flag on all nodes + * [GFS2] Journaled file write/unstuff bug + * [GFS2] Remove bogus '\0' in rgrp.c + * [GFS2] Use zero_user_page() in stuffed_readpage() + * [GFS2] assertion failure after writing to journaled file, umount + * [GFS2] Simplify multiple glock aquisition + * [GFS2] Addendum to the journaled file/unmount patch + + -- Ben Collins Fri, 01 Jun 2007 12:15:58 -0400 + +linux-source-2.6.22 (2.6.22-6.13) gutsy; urgency=low + + [Ben Collins] + + * Bump ABI + * build/scripts: Remove all remnants of debconf from control scripts + * build/config: Re-enable paravirt/vmi + * build/config: Build ide-core as a module + * i386/x86_64: Allow disabling the putstr's from compressed boot wrapper + * PM: Do not require dev spew to get PM_DEBUG + * RTC: Ratelimit "lost interrupts" message + * UNUSUAL_DEV: Sync up some reported devices from Ubuntu + * build/d-i: Include ide-core in storage-core udeb, not that it's modular + * build/d-i: Make ide-modules depend on storage-code-modules + * build/config: Enable CONFIG_TIMER_STATS on x86_64. + * build/config: Disable CONFIG_RTC_DRV_CMOS + * build/config: Enable TIMER_STATS everywhere. + * build/config: Enable SND_AC97_POWER_SAVE + - LP: #116679 + * kmod: Improve call_usermodehelper_pipe to handle data close + * coredump: Convert to new call_usermodehelper_pipe symantics + * PPC: Only set hwif stuff when ide-core is non-modular + * PPC/MEDIABAY: Export some functions for modular ide-core/ppc-ide + + [Colin Watson] + + * Move isofs to storage-core-modules udeb from fs-core-modules. + + [Upstream Kernel Changes] + + * Input: logips2pp - add type 72 (PS/2 TrackMan Marble) + * Input: adbhid - do not access input_dev->private directly + * sh: Shut up compiler warnings in __do_page_fault(). + * sh: Fix up psw build rules for r7780rp. + * sh: Kill off pmb slab cache destructor. + * sh: landisk: rtc-rs5c313 support. + * sh: landisk: Header cleanups. + * input: hp680_ts compile fixes. + * [ARM] 4375/1: sharpsl_pm: Fix compile warnings + * [ARM] 4376/1: Selects GENERIC_GPIO for ARCH_IXP4XX in Kconfig + * [ARM] 4378/1: KS8695: Serial driver fix + * [ARM] Remove Integrator/CP SMP platform support + * [ARM] 4382/1: iop13xx: fix msi support + * [ARM] 4383/1: iop: fix usage of '__init' and 'inline' in iop files + * [ARM] 4384/1: S3C2412/13 SPI registers offset correction + * [ARM] Update ARM syscalls + * [ARM] Silence OMAP kernel configuration warning + * [ARM] gic: Fix gic cascade irq handling + * [ARM] integrator: fix pci_v3 compile error with DEBUG_LL + * [ARM] ARMv6: add CPU_HAS_ASID configuration + * [CRYPTO] padlock: Make CRYPTO_DEV_PADLOCK a tristate again + * [CRYPTO] tcrypt: Add missing error check + * eventfd use waitqueue lock ... + * timerfd use waitqueue lock ... + * [IA64] Fix bogus messages about system calls not implemented. + * [IA64] Yet another section mismatch warning + * Fix roundup_pow_of_two(1) + * Further update of the i386 boot documentation + * cciss: Fix pci_driver.shutdown while device is still active + * Linux v2.6.22-rc2 + * [CRYPTO] api: Read module pointer before freeing algorithm + * powerpc: Fix the MODALIAS generation in modpost for of devices + * kbuild: include limits.h in sumversion.c for PATH_MAX + * kconfig: search harder for curses library in check-lxdialog.sh + * kbuild: make modpost section warnings clearer + * kbuild: make better section mismatch reports on i386, arm and mips + * kbuild: add "Section mismatch" warning whitelist for powerpc + * all-archs: consolidate .text section definition in asm-generic + * all-archs: consolidate .data section definition in asm-generic + * kbuild: introduce __init_refok/__initdata_refok to supress section + mismatch warnings + * init/main: use __init_refok to fix section mismatch + * mm: fix section mismatch warnings + * mm/slab: fix section mismatch warning + * IB/core: Free umem when mm is already gone + * IB/ipath: Fix potential deadlock with multicast spinlocks + * IB/core: Add helpers for uncached GID and P_Key searches + * IB/core: Use start_port() and end_port() + * IPoIB: Handle P_Key table reordering + * IB/ehca: Return proper error code if register_mr fails + * IB/mthca: Fix use-after-free on device restart + * IB/mlx4: Fix check of max_qp_dest_rdma in modify QP + * IB/mthca: Set GRH:HopLimit when building MLX headers + * IB/mlx4: Set GRH:HopLimit when sending globally routed MADs + * IB/mthca: Fix RESET to ERROR transition + * IB/mlx4: Fix RESET to RESET and RESET to ERROR transitions + * mlx4_core: Fix array overrun in dump_dev_cap_flags() + * IB/mlx4: Fix check of opcode in mlx4_ib_post_send() + * [IPV6]: Add ip6_tunnel.h to headers_install + * [RFKILL]: Fix check for correct rfkill allocation + * [NET]: Fix net/core/skbuff.c gcc-3.2.3 compilation error + * [TCP] FRTO: Add missing ECN CWR sending to one of the responses + * [TCP] FRTO: Prevent state inconsistency in corner cases + * [IPSEC] pfkey: Load specific algorithm in pfkey_add rather than all + * [NETFILTER]: nf_conntrack: fix use-after-free in helper destroy + callback invocation + * [NETFILTER]: nf_conntrack_ipv4: fix incorrect #ifdef config name + * [IPV4]: icmp: fix crash with sysctl_icmp_errors_use_inbound_ifaddr + * [NET]: Fix race condition about network device name allocation. + * IB/mlx4: Pass send queue sizes from userspace to kernel + * [ARM] 4387/1: fix /proc/cpuinfo formatting for pre-ARM7 parts + * [ARM] 4388/1: no need for arm/mm mmap range checks for non-mmu + * [ARM] 4395/1: S3C24XX: add include of to relevant + machines + * [ARM] 4396/1: S3C2443: Add missing HCLK clocks + * [ARM] 4397/1: S3C2443: remove SDI0/1 IRQ ambiguity + * [ARM] 4398/1: S3C2443: Fix watchdog IRQ number + * [ARM] 4399/2: S3C2443: Fix SMDK2443 nand timings + * [ARM] 4400/1: S3C24XX: Add high-speed MMC device definition + * [ARM] at91_adc parenthesis balance + * [ARM] spelling fixes + * IB/mlx4: Check if SRQ is full when posting receive + * spelling fixes: arch/sh/ + * sh: revert addition of page fault notifiers + * sh: Wire up signalfd/timerfd/eventfd syscalls. + * sh: Fix up various compile warnings for SE boards. + * sh: Fix page size alignment in __copy_user_page(). + * sh: Disable psw support for R7785RP. + * fs: Kill sh dependency for binfmt_flat. + * sh: disable genrtc support. + * sh: sr.bl toggling around idle sleep. + * sh: Wire up kdump crash kernel exec in die(). + * sh: Fix clock multiplier on SH7722. + * sh: Fix dreamcast build for IRQ changes. + * [S390] cio: Update documentation. + * [S390] Wire up sys_utimensat. + * [S390] Wire up signald, timerfd and eventfd syscalls. + * [S390] Make use of kretprobe_assert. + * [S390] More verbose show_mem() like other architectures. + * Fix "fs: convert core functions to zero_user_page" + * Detach sched.h from mm.h + * Blackfin arch: Add Workaround for ANOMALY 05000257 + * Blackfin arch: add SPI MMC driver support on bf533-stamp, tested on + STAMP-BF533 + * Blackfin arch: ISP1761 doesn't work for USB flash disk + * Blackfin arch: fix a few random warnings + * Blackfin arch: Add configuration data for ISP176x on BF561 + * Blackfin arch: mark a bunch of local functions as static + * Blackfin arch: Fix reserved map after we changed PORT_H definition + * Blackfin arch: Move write to VR_CTL closer to IDLE + * Blackfin arch: DMA operation cleanup + * Blackfin arch: GPIO fix some defines + * Blackfin arch: fix trace output for FLAT binaries + * Blackfin arch: Fix bug using usb keyboard crashes kernel + * Blackfin arch: initial tepla-bf561 board support + * Blackfin arch: make sure we declare the revid functions as pure (since + they are) + * Blackfin arch: dont clear status register bits in SWRST so we can + actually use it + * Blackfin arch: finish removing p* volatile defines for MMRs + * Blackfin arch: move board specific setup out of common init code and + into the board specific init code + * Blackfin arch: issue reset via SWRST so we dont clobber the watchdog + state + * Blackfin arch: document why we have to touch the UART peripheral in our + boot up code + * Blackfin arch: dma_memcpy borken for > 64K + * Blackfin arch: dont clear the bit that tells coreb to start booting + * Blackfin arch: make sure we use local labels + * Blackfin arch: update blackfin header files to latest one in VDSP. + * Blackfin arch: cache SWRST value at bootup so other things like + watchdog can non-destructively query it + * Blackfin arch: fix signal handling bug + * Blackfin arch: Change NO_ACCESS_CHECK to ACCESS_CHECK + * Blackfin arch: add board default configs to blackfin arch + * Blackfin arch: update defconfig files + * Blackfin arch: update pm.c according to power management API change. + * Blackfin serial driver: fix overhead issue + * Blackfin serial driver: implement support for ignoring parity/break + errors + * Blackfin SPI: cleanup according to David Brownell's review + * x86_64: Update defconfig + * i386: Update defconfig + * x86_64: Support x86_64 in make buildtar + * i386: Fix K8/core2 oprofile on multiple CPUs + * x86_64: Support gcc 5 properly + * i386: Clear MCE flag on AMD K6 + * i386: Fix wrong CPU error message in early boot path + * i386: Enable CX8/PGE CPUID bits early on VIA C3 + * x86_64: early_print kernel console should send CRLF not LFCR + * x86_64: vsyscall time() fix + * i386: fix PGE mask + * LDM: Fix for Windows Vista dynamic disks + * IB/ipoib: Fix typos in error messages + * IPoIB/cm: Fix SRQ WR leak + * IB/cm: Improve local id allocation + * e1000: Don't enable polling in open() (was: e1000: assertion hit in + e1000_clean(), kernel 2.6.21.1) + * declance: Remove a dangling spin_unlock_irq() thingy + * Add constant for FCS/CRC length (frame check sequence) + * ahci: disable 64bit dma on sb600 + * libata: Add Seagate STT20000A to DMA blacklist. + * pata_hpt366: Enable bits are unreliable so don't use them + * ata_piix: clean up + * libata: Kiss post_set_mode goodbye + * libata: Trim trailing whitespace + * partitions/LDM: build fix + * Make 'headerscheck' stop immediately on an error + * Fix headers check fallout + * [POWERPC] Fix smp_call_function to be preempt-safe + * [POWERPC] Add missing pmc_type fields in cpu_table + * [POWERPC] Fix typo: MMCR0_PMA0 != MMCR0_PMAO + * [POWERPC] Fix powerpc vmlinux.lds.S + * [POWERPC] Fix warning in 32-bit builds with CONFIG_HIGHMEM + * libertas: skb dereferenced after netif_rx + * drivers/net/wireless/libertas/fw.c: fix use-before-check + * drivers/net/wireless/libertas/rx.c: fix use-after-free + * [IA64] Improve unwind checking. + * [IA64] Only unwind non-running tasks. + * [IA64] fix kmalloc(0) in arch/ia64/pci/pci.c + * i2c: Legacy i2c drivers shouldn't issue uevents + * i2c-tiny-usb: Fix truncated adapter name + * i2c-s3c2410: Fix build warning + * V4L/DVB (5639): Fix Kconfig dependencies for ivtv + * V4L/DVB (5640): Fix: em28xx shouldn't be selecting VIDEO_BUF + * V4L/DVB (5670): Adding new fields to v4l2_pix_format broke the ABI, + reverted that change + * V4L/DVB (5639a): Fix dst usage count + * V4L/DVB (5630): Dvb-core: Handle failures to create devices + * V4L/DVB (5680): Tuner-simple.c fix suport for SECAM with FI1216MF + * V4L/DVB (5690): Cafe_ccic: Properly power down the sensor + * V4L/DVB (5691): Ov7670: reset clkrc in rgb565 mode + * [IPSEC]: Fix warnings with casting int to pointer + * [AF_RXRPC]: AF_RXRPC depends on IPv4 + * [AF_RXRPC]: Make call state names available if CONFIG_PROC_FS=n + * [RTNETLINK]: Allow changing of subsets of netdevice flags in + rtnl_setlink + * [RTNETLINK]: Remove remains of wireless extensions over rtnetlink + * Input: iforce - fix force feedback not working + * Input: iforce - minor clean-ups + * Input: ALPS - force stream mode + * Input: ucb1400_ts - use sched_setscheduler() + * Input: ucb1x00-ts - remove commented out code + * Input: input-polldev - add module info + * Input: ads7846 - document that it handles tsc2046 too + * Input: ads7846 - SPI_CPHA mode bugfix + * USB: fix omninet memory leak found by coverity + * USB: remove useless check in mos7840 found by coverity + * usb-storage: ignore Sitecom WL-117 USB-WLAN + * USB: fix more ftdi-elan/u132-hcd #include lossage + * USB: handle more rndis_host oddities + * USB: remove usb DocBook warnings + * USB: address FIXME in usbnet w.r.t drivers claiming multiple interfaces + * EHCI: fix problem with BIOS handoff + * USB: more autosuspend timer stuff + * USB: remove unneeded WARN_ON + * USB: New device PID for ftdi_sio driver + * USB: set the correct Interrupt interval in usb_bulk_msg + * USB: fsl_usb2_udc: Fix UMTI_WIDE support and a compile warning + * USB: auerswald: fix file release handler + * USB: Remove duplicate IDs from option card driver + * USB: Deref URB after usbmon is done with it + * USB: remove short initial timeout for device descriptor fetch + * USB: don't try to kzalloc 0 bytes + * USB: Onetouch - switch to using input_dev->dev.parent + * USB: Fix debug output of ark3116 + * USB: usblp: Use correct DMA address in case of probe error + * USB: Fix USB OHCI Subvendor for Toshiba Portege 4000 + * USB: make the autosuspend workqueue thread freezable + * USB: handle errors in power/level attribute + * USB: fix ratelimit call semantics + * USB: ftdi_sio: Add USB Product Id for OpenDCC + * USB: ldusb bugfix + * USB: Add support for Sierra Wireless Aircard 595U + * USB: Add support for Olimex arm-usb-ocd JTAG interface serial port + * IB/mlx4: Don't allocate RQ doorbell if using SRQ + * [IA64] start_secondary() and smp_callin() should be __cpuinit + * add the IDE device ID for ATI SB700 + * ide/pci/serverworks.c: Fix corruption/timeouts with MegaIDE + * Add two missing chipsets to drivers/ide/ide-proc.c + * Match DMA blacklist entries between ide-dma.c and libata-core.c + * ide serverworks warning fixes + * freezer: close potential race between refrigerator and thaw_tasks + * freezer: fix vfork problem + * freezer: take kernel_execve into consideration + * freezer: fix kthread_create vs freezer theoretical race + * freezer: fix PF_NOFREEZE vs freezeable race + * freezer: move frozen_process() to kernel/power/process.c + * Ignore bogus ACPI info for offline CPUs + * SLUB Debug: Fix object size calculation + * fuse: fix mknod of regular file + * mpc52xx_psc_spi: fix it for CONFIG_PPC_MERGE + * spi doc update: describe clock mode bits + * NOHZ: Rate limit the local softirq pending warning output + * genhd: expose AN to user space + * genhd: send async notification on media change + * capability.h warning fix + * spi/spidev: check message size before copying + * uml: improve PTRACE_SYSEMU checking + * prohibit rcutorture from being compiled into the kernel + * Documentation: fix the explanation of Kconfig files + * Avoid zero size allocation in cache_k8_northbridges() + * recalc_sigpending_tsk fixes + * optimize compat_core_sys_select() by a using stack space for small fd + sets + * spi: potential memleak in spidev_ioctl + * fbdev: cleanup of sparc FB options + * pm2fb: RDAC_WR barriers clean up + * pm3fb: various fixes + * w100fb: fix compile warnings + * ps3fb: use FB_SYS_* instead of FB_CFB_* + * imxfb: remove ifdefs + * imxfb: fix memory hole + * Missing 'const' from reiserfs MIN_KEY declaration. + * uselib: add missing MNT_NOEXEC check + * fuse: generic_write_checks() for direct_io + * fuse: delete inode on drop + * fix unused setup_nr_node_ids + * SLUB Debug: fix check for super sized slabs (>512k 64bit, >256k 32bit) + * Char: cyclades, fix deadlock + * simplify cleanup_workqueue_thread() + * phantom: move to unlocked_ioctl + * Misc: phantom, take care of pci posting + * power: Fix sizeof(PAGE_SIZE) typo + * update dontdiff file + * signalfd: retrieve multiple signals with one read() call + * i2o: destroy event queue only when drv->event is set + * i2o: fix notifiers when max_drivers is configured + * i2o: eliminate a peculiar constraint on i2o_max_drivers + * i386, x86-64: show that CONFIG_HOTPLUG_CPU is required for suspend on + SMP + * md: avoid overflow in raid0 calculation with large components + * md: don't write more than is required of the last page of a bitmap + * md: fix bug with linear hot-add and elsewhere + * documentation: Documentation/initrd.txt + * HiSax: fix error checking for hisax_register()] + * applesmc - sensors patch missing from 2.6.22-rc2 + * Off by one in floppy.c + * eCryptfs: delay writing 0's after llseek until write + * document clocksources + * ehci-fsl: fix cache coherency problem on system with large memory + * Prevent going idle with softirq pending + * i386: fix early usage of atomic_add_return and local_add_return on real + i386 + * Documentation/memory-barriers.txt: various fixes + * omap_uwire: SPI_CPHA mode bugfix + * capifunc warning fixes + * drivers/isdn/hardware/eicon/message.c warning fixes + * i386 bigsmp: section mismatch fixes + * boot documentation: clarifications + * mmc: clean up unused parts of block driver + * mmc: mark unmaintained drivers + * mmc: Add maintainers for TI OMAP MMC interface + * mmc: add maintainer for iMX MMC interface + * mmc: add maintainer for ARM Primecell controller + * [CRYPTO] geode: Fix in-place operations and set key + * [Bluetooth] Always send HCI_Reset for Broadcom devices + * [Bluetooth] Fix L2CAP configuration parameter handling + * NFS: Avoid a deadlock situation on write + * NFS: Fix handful of compiler warnings in direct.c + * NFS: Fix nfs_direct_dirty_pages() + * Don't call a warnign a bug. It's a warning. + * [IA64] Fix using uninitialized data in _PDC setup + * [IA64] Cleanup acpi header to reuse the generic _PDC defines + * Documentation: Fix up docs still talking about i_sem + * [IA64] acpi_get_sysname() should be __init + * IB/mlx4: Initialize send queue entry ownership bits + * IB/ehca: Fix number of send WRs reported for new QP + * IPoIB/cm: Fix timeout check in ipoib_cm_dev_stop() + * IPoIB/cm: Drain cq in ipoib_cm_dev_stop() + * ucc_geth: Fix MODULE_DEVICE_TABLE() duplication + * ucc_geth:trivial fix + * asix.c - Add Belkin F5D5055 ids + * fix compiler warning in fixed.c + * remove unnecessary dependency on VIA velocity config + * meth driver renovation + * spidernet: skb used after netif_receive_skb + * chelsio parenthesis fix + * forcedeth: fix cpu irq mask + * [NET_SCHED]: Fix qdisc_restart return value when dequeue is empty + * [IPV6]: Ignore ipv6 events on non-IPV6 capable devices. + * [ATM]: Use mutex instead of binary semaphore in idt77252 driver. + * [DCCP]: Use menuconfig objects. + * [IPVS]: Use menuconfig objects. + * [SCTP]: Use menuconfig objects. + * [TIPC]: Use menuconfig objects. + * [ARCNET]: Use menuconfig objects. + * [TR]: Use menuconfig objects. + * [RTNETLINK]: Fix sending netlink message when replace route. + * [TIPC]: Fixed erroneous introduction of for_each_netdev + * [DCCP]: Fix build warning when debugging is disabled. + * [NET_SCHED]: sch_htb: fix event cache time calculation + * [NETFILTER]: nf_conntrack_ftp: fix newline sequence number update + * [NETFILTER]: nf_conntrack_ftp: fix newline sequence number calculation + * [NETFILTER]: nf_conntrack_h323: fix ASN.1 types + * [NETFILTER]: nf_conntrack_h323: fix get_h225_addr() for IPv6 address + access + * [NETFILTER]: nf_conntrack_h323: remove unnecessary process of + Information signal + * [NETFILTER]: nf_conntrack_h323: add missing T.120 address in OLCA + * [NETFILTER]: nf_nat_h323: call set_h225_addr instead of + set_h225_addr_hook + * [NET]: "wrong timeout value" in sk_wait_data() v2 + * hpt3x2n: Correct revision boundary + * pata_sis: Fix and clean up some timing setups + * ata_piix: add short 40c quirk for Acer Aspire 2030, take #2 + * libata: don't consider 0xff as port empty if SStatus is available + * libata: -ENODEV during prereset isn't an error + * pata_via: Handle laptops via DMI + * [CASSINI]: Check pci_set_mwi() return value. + * [XFRM]: Allow packet drops during larval state resolution. + * [libata] sata_promise: fix flags typo + * [libata] sata_mv: add TODO list + * Fix build failure for drivers/ata/pata_scc.c + * libata: sata_sis fixes + * [libata] Fix decoding of 6-byte commands + * [libata] sata_via, pata_via: Add PCI IDs. + * ocfs2: trylock in ocfs2_readpage() + * ocfs2: unmap_mapping_range() in ocfs2_truncate() + * ocfs2: use zero_user_page + * ocfs2: fix inode leak + * ocfs2: use generic_segment_checks + * pata: Trivia + * pata_hpt37x: Further improvements based on the IDE updates and vendor + drivers + * fix compat console unimap regression + * Linux 2.6.22-rc3 + + -- Ben Collins Thu, 31 May 2007 12:35:44 -0400 + +linux-source-2.6.22 (2.6.22-5.11) gutsy; urgency=low + + [Ben Collins] + + * build/headers/ppc: Correct asm-ppc -> asm for arch symlink + * build/headers/ia64: Fix find command line to correctly pull in *.lds + files + * Bump ABI + + [Upstream Kernel Changes] + + * [IA64] spelling fixes: arch/ia64/ + * [AVR32] Remove bogus comment in arch/avr32/kernel/irq.c + * [AVR32] optimize pagefault path + * [AVR32] Wire up signalfd, timerfd and eventfd + * [IA64] wire up {signal,timer,event}fd syscalls + * [IA64] kdump on INIT needs multi-nodes sync-up (v.2) + * [IA64] s/scalibility/scalability/ + * [AVR32] Implement platform hooks for atmel_lcdfb driver + * [IA64] Fix section conflict of ia64_mlogbuf_finish + * [SPARC64]: Add hypervisor API negotiation and fix console bugs. + * pata_scc had been missed by ata_std_prereset() switch + * libata: separate out ata_dev_reread_id() + * libata: during revalidation, check n_sectors after device is configured + * libata-acpi: add ATA_FLAG_ACPI_SATA port flag + * libata: fix shutdown warning message printing + * libata: track spindown status and skip spindown_compat if possible + * [ALSA] usb-audio: another Logitech QuickCam ID + * [ALSA] hda-codec - Make the mixer capability check more robust + * [ALSA] ASoC AC97 static GPL symbol fix + * [ALSA] ASoC AC97 device reg bugfix + * [ALSA] hda-codec - Fix ALC882/861VD codec support on some laptops + * [ALSA] version 1.0.14rc4 + * [ALSA] Fix probe of non-PnP ISA devices + * [ALSA] Include quirks from Ubuntu Dapper/Edgy/Feisty + * [ALSA] usbaudio - Coping with short replies in usbmixer + * [IA64] optimize pagefaults a little + * Fix ACPI suspend / device suspend ordering problem + * AFS: write back dirty data on unmount + * SLUB: It is legit to allocate a slab of the maximum permitted size + * slub: don't confuse ctor and dtor + * AFS: Fix afs_prepare_write() + * spi: fix spidev for >sizeof(long)/32 devices + * parport_pc needs dma-mapping.h + * Fix: find_or_create_page skips cpuset memory spreading. + * slob: implement RCU freeing + * Slab allocators: Drop support for destructors + * SLUB: Remove depends on EXPERIMENTAL and !ARCH_USES_SLAB_PAGE_STRUCT + * SLAB: Move two remaining SLAB specific definitions to slab_def.h + * SLUB: Define functions for cpu slab handling instead of using + PageActive + * slab: warn on zero-length allocations + * slub: fix handling of oversized slabs + * SLUB: slabinfo fixes + * SLUB: Do our own flags based on PG_active and PG_error + * Remove SLAB_CTOR_CONSTRUCTOR + * SLUB: Simplify debug code + * Slab allocators: define common size limitations + * acpi: fix potential call to a freed memory section. + * i386/x86-64: fix section mismatch + * Make __vunmap static + * simplify compat_sys_timerfd + * Let smp_call_function_single return -EBUSY on UP + * Refine SCREEN_INFO sanity check for vgacon initialization + * make freezeable workqueues singlethread + * parport: mailing list is subscribers-only + * docbook: make kernel-locking table readable + * gpio interface loosens call restrictions + * rtc-omap build fix + * rtc kconfig clarification + * icom: add new sub-device-id to support new adapter + * make sysctl/kernel/core_pattern and fs/exec.c agree on maximum core + filename size + * ecryptfs: use zero_user_page + * i386: don't check_pgt_cache in flush_tlb_mm + * circular locking dependency found in QUOTA OFF + * swsusp: fix sysfs interface + * Fix page allocation flags in grow_dev_page() + * mm: more rmap checking + * NS16550A: Restore HS settings in EXCR2 on resume + * Fix incorrect prototype for ipxrtr_route_packet() + * sky2: remove Gigabyte 88e8056 restriction + * sky2: PHY register settings + * sky2: keep track of receive alloc failures + * sky2: MIB counter overflow handling + * sky2: remove dual port workaround + * sky2: memory barriers change + * small netdevices.txt fix + * ibm_emac: fix section mismatch warnings + * ibm_emac: improved PHY support + * ibm_emac: fix link speed detection change + * gianfar: Add I/O barriers when touching buffer descriptor ownership. + * spidernet: node-aware skbuff allocation + * NetXen: Fix NetXen driver ping on system-p + * ixgb: don't print error if pci_enable_msi() fails, cleanup minor leak + * e1000: Fix msi enable leak on error, don't print error message, cleanup + * drivers/ata: remove the wildcard from sata_nv driver + * sata_nv: fix fallout of devres conversion + * libata: remove libata.spindown_compat + * sata_via: pcim_iomap_regions() conversion missed BAR5 + + -- Ben Collins Thu, 17 May 2007 14:54:16 -0400 + +linux-source-2.6.22 (2.6.22-4.10) gutsy; urgency=low + + [Ben Collins] + + * Bump ABI + * build/config: Disable obsolete tsdev driver. + * build: Add tsdev to list of modules intentionally removed. + * build/headers: Include *.lds files (fixes ia64 headers). + * build/headers: Add arch/powerpc/include/asm symlink to get all headers. + * build/module-check: Fix logic for printed messages. + * build/maintainer: Use linux instead of upstream-linux for local diffs + * build/config: Enable SLUB slab allocator (vs. SLAB). + * build/config: Disable orinoco_nortel, use prefered hostap_plx + * build/config: Disable ir-usb in favor of irda-usb + * build/config: Disable sis5513(ide) in favor of pata_sis(libata) + * build/config: Disable piix(ide) in favour of pata_oldpiix, ata_piix and + pata_mpiix (libata) + * build/config: Disable zaurus driver in favour of the cdc_ether driver + * build/abi: Note a few modules intentionally removed. + * build/config: Disable mxb and dpc7146 driver in favour of hexium_orion + * build/config: Disable usbtest driver (for development only) + * build/config: Disable keyspan driver in favour of keyspan_pda + * build/abi: Add mxb and usbtest to list of removed modules. + + [Upstream Kernel Changes] + + * net: Trivial MLX4_DEBUG dependency fix. + * mlx4_core: Remove unused doorbell_lock + * [CPUFREQ] Support rev H AMD64s in powernow-k8 + * [CPUFREQ] powernow-k7: fix MHz rounding issue with perflib + * [AGPGART] Fix wrong ID in via-agp.c + * sh64: ROUND_UP macro cleanup in arch/sh64/kernel/pci_sh5.c + * spelling fixes: arch/sh64/ + * sh64: Wire up many new syscalls. + * sh64: Fixups for the irq_regs changes. + * sh64: dma-mapping updates. + * sh64: ppoll/pselect6() and restartable syscalls. + * sh64: Fixup sh-sci build. + * sh64: Update cayman defconfig. + * sh64: generic quicklist support. + * sh64: Add .gitignore entry for syscalltab. + * IB/mlx4: Fix uninitialized spinlock for 32-bit archs + * IB/ipath: Shadow the gpio_mask register + * IB/ehca: Serialize hypervisor calls in ehca_register_mr() + * IB/ehca: Correctly set GRH mask bit in ehca_modify_qp() + * IB/ehca: Fix AQP0/1 QP number + * IB/ehca: Remove _irqsave, move #ifdef + * IB/ehca: Beautify sysfs attribute code and fix compiler warnings + * IB/ehca: Disable scaling code by default, bump version number + * RDMA/cma: Simplify device removal handling code + * RDMA/cma: Fix synchronization with device removal in cma_iw_handler + * RDMA/cma: Add check to validate that cm_id is bound to a device + * IB/mthca: Fix posting >255 recv WRs for Tavor + * IB/mthca: Set cleaned CQEs back to HW ownership when cleaning CQ + * IPoIB/cm: Optimize stale connection detection + * [CPUFREQ] Correct revision mask for powernow-k8 + * fix epoll single pass code and add wait-exclusive flag + * epoll locks changes and cleanups + * epoll: fix some comments + * epoll: move kfree inside ep_free + * nommu: add ioremap_page_range() + * h8300 atomic.h update + * alpha: fix hard_smp_processor_id compile error + * m68k: implement __clear_user() + * Remove cpu hotplug defines for __INIT & __INITDATA + * i386: move common parts of smp into their own file + * i386: fix voyager build + * SLUB: CONFIG_LARGE_ALLOCS must consider MAX_ORDER limit + * ll_rw_blk: fix gcc 4.2 warning on current_io_context() + * pasemi_mac: Fix register defines + * pasemi_mac: Interrupt ack fixes + * pasemi_mac: Terminate PCI ID list + * pasemi_mac: Fix local-mac-address parsing + * smc911x: fix compilation breakage + * ucc_geth: eliminate max-speed, change interface-type to + phy-connection-type + * pdc202xx_old: rewrite mode programming code (v2) + * serverworks: PIO mode setup fixes + * sis5513: PIO mode setup fixes + * alim15x3: use ide_tune_dma() + * pdc202xx_new: use ide_tune_dma() + * ide: always disable DMA before tuning it + * cs5530/sc1200: add ->udma_filter methods + * ide: use ide_tune_dma() part #2 + * cs5530/sc1200: DMA support cleanup + * cs5530/sc1200: add ->speedproc support + * sl82c105: add speedproc() method and MWDMA0/1 support + * ide: remove ide_dma_enable() + * ide: add missing validity checks for identify words 62 and 63 + * ide: remove ide_use_dma() + * sl82c105: Switch to ref counting API + * Use menuconfig objects: IDE + * x86: Fix discontigmem + non-HIGHMEM compile + * missing mm.h in fw-ohci + * missing dependencies for USB drivers in input + * missing includes in mlx4 + * em28xx and ivtv should depend on PCI + * rpadlpar breakage - fallout of struct subsystem removal + * m32r: __xchg() should be always_inline + * audit_match_signal() and friends are used only if CONFIG_AUDITSYSCALL + is set + * fix uml-x86_64 + * arm: walk_stacktrace() needs to be exported + + -- Ben Collins Tue, 15 May 2007 10:13:23 -0400 + +linux-source-2.6.22 (2.6.22-3.9) gutsy; urgency=low + + * Fixup firmware-modules -> efi-modules in exclude files. + + [Ben Collins] + + * build/config: Enable CONFIG_TIMER_STATS + * build/config: Disable CONFIG_IRQBALANCE, handled in userspace now + * build: Update modules that have been deprecated + * sparc64: Get some drivers compiling, till patches get upstream. + * powerpc: Add 64-bit cmp op for 32-bit. + * build/config: Disable apm_emu, pasemi_mac and cbe_cpufreq on ppc64 + * build/d-i(cjwatson): Rename firmware-modules to efi-modules + + -- Ben Collins Fri, 11 May 2007 09:38:50 +0200 + +linux-source-2.6.22 (2.6.22-2.7) gutsy; urgency=low + + [Changes for 2.7] + + * Added some more modules going missing to ignore. + * Disable ADB_PMU_LED on powerpc64. FTBFS. + + [Ben Collins] + + * XXX: Well, xen and rt got disabled in this upload. Hopefully things will + get working again soon. + + * build: Add check for nrcpus on buildd's for CONCURRENCY_LEVEL + * build: No longer provide ndiswrapper or ivtv modules (l-u-m does). + * build/d-i: Remove firmware lists, since we no longer supply those udebs + * build: Remove more firmware stuff + * build/control: Build-dep on coreutils + * Update configuration files + * build/custom: Updated xen/rt patches and configs. + * build: Make sure to use /bin/bash for headers_install + * build: Add SHELL=/bin/bash to headers_install + * Update configuration files + * Bump ABI + * Update module lists to match module name changes and merges. + * build/rt: Trimmed down real-time patch from Alessio Igor Bogani. + * Update configuration files + * Update configuration files + * build/rt: Fix typo in diff + * Update configuration files + * build: make explicit binary-headers target + * Update configuration files + * build/control-scripts: Remove debconf from pre-rm script + * build/ia64: Compress and use vmlinuz for target install + * build/config: Diable OSS i810_audio driver (Alsa driver prefered) + * build/config: Disable OSS cs4232 driver (Alsa prefered) + * build/config: Disable OSS via82xx driver (Alsa prefered) + * build/config: Disable OSS trident driver (Alsa prefered) + * build/config: Disable OSS Sound Blaster driver (Alsa prefered) + * build/config: Disable IDE generic, ata_generic prefered + * build/config: Disable siimage, pata_sil680 prefered + * build/module-check: More robust module checking + * build: Call module-check with perl, not $SHELL + * Update configuration files + * build: Fixup calling conventions of module-check + * build: Add modules.ignore from 1.3 revision + * build/config: Disable obsolete MOXA_SMARTIO in favor of new driver. + * build/config: Disable orinoco_cs in favor of hostap_cs + * build/config: Disable orinoco_pci in favor of hostap_pci + * build/config: Disable orinoco_{plx,tmd} in favor of hostap_plx + * build/config: Disable sk98lin in favor of skge + * build: Add more modules intentionally removed since 1.3 + + -- Ben Collins Fri, 27 Apr 2007 09:04:29 -0400 + +linux-source-2.6.22 (2.6.22-1.3) gutsy; urgency=low + + [Ben Collins] + + * build: Only use bzip2 for linux-image, and pre-depend on proper dpkg + + [2.6.22-1.2] + + [Ben Collins] + + * build: Add build-arch target. FTBFS + + [2.6.22-1.1] + + [Ben Collins] + + * debian: New build system, from scratch + * debian: Rename place holder so debian/stamps/ sticks around + * debian: Create stamp-flavours at start of build (for build scripts) + * debian/abi: Add revision 0.0 bootstrap module list. + * debian: Fix backwards logic in module/abi checkers. + * debian: Add arch= to vars.* files + * Update configuration files + * build: Added control scripts for images + * build/config: Disable CONFIG_PARAVIRT for now + * build/config: Enable CONFIG_FB_VESA + * build: Take CONCURRENCY_LEVEL from env if it exists. + * build: Do not print SHAs by default for changelog + * build/config(i386): Disable NO_HZ on all but generic + * build: Implement udeb rules + * build/d-i: Remove speakup-modules udeb + * build/udebs: Fix a couple trivial errors in the build. + * build/config: Disable CONFIG_FB_IMSTT on powerpc64-smp (no NVRAM) + * build/config: Disable some modules for ppc64 that don't use DMA API + * build/config: Yet another module to disable on ppc64 + * build/tests: New test infrastructure + * build: Special kernel build infrastructure + * build: Fix typo from last commit + * build/custom: Move custom files for each flavour into subdir. + * build/config: Disable some drivers on sparc that don't support DMA API + * build/sparc: Add new compress_file config, and use it for sparc + * build: Fix typo in compress_file commit. + * build/schedcfs: Update to v6 of the patch. + * build: Fix control file generation for custom images + * build: Correct message in link-headers + * build: 2.6.21 is released, force our SUBLEVEL to .22 + * build/vars: kvm API is at 4, provide that. + * build/custom: Allow custom builds to override things like build_image + * build/custom: Fix type causing custom rules not to be included. + * build/custom: Hello Xen 3.0.5 + * build/custom: Remove sched-cfs. Superseded in use by rt. + * build/custom: Add 2.6.21-rt1 patch for -rt custom flavour + * build/link-headers: Make sure to copy new files for custom + + -- Ben Collins Fri, 27 Apr 2007 08:29:00 -0400 --- linux-2.6.28.orig/debian/control.stub +++ linux-2.6.28/debian/control.stub @@ -0,0 +1,474 @@ +Source: linux +Section: devel +Priority: optional +Maintainer: Ubuntu Kernel Team +Standards-Version: 3.6.1 +Build-Depends: debhelper (>= 3), module-init-tools, kernel-wedge (>= 2.24ubuntu1), makedumpfile [!armel] +Build-Depends-Indep: xmlto, docbook-utils, gs, transfig, bzip2, sharutils +Vcs-Git: http://kernel.ubuntu.com/git-repos/ubuntu/ubuntu-jaunty.git + +Package: linux-source-2.6.28 +Architecture: all +Section: devel +Priority: optional +Provides: linux-source, linux-source-2.6 +Depends: binutils, bzip2, coreutils | fileutils (>= 4.0) +Recommends: libc-dev, gcc, make +Suggests: libncurses-dev | ncurses-dev, kernel-package, libqt3-dev +Description: Linux kernel source for version 2.6.28 with Ubuntu patches + This package provides the source code for the Linux kernel version + 2.6.28. + . + This package is mainly meant for other packages to use, in order to build + custom flavours. + . + If you wish to use this package to create a custom Linux kernel, then it + is suggested that you investigate the package kernel-package, which has + been designed to ease the task of creating kernel image packages. + . + If you are simply trying to build third-party modules for your kernel, + you do not want this package. Install the appropriate linux-headers + package instead. + +Package: linux-doc-2.6.28 +Architecture: all +Section: doc +Priority: optional +Provides: linux-doc-2.6 +Conflicts: linux-doc-2.6 +Replaces: linux-doc-2.6 +Depends: coreutils | fileutils (>= 4.0) +Description: Linux kernel specific documentation for version 2.6.28 + This package provides the various readme's in the 2.6.28 kernel + Documentation/ subdirectory: these typically contain kernel-specific + installation notes for some drivers for example. See + /usr/share/doc/linux-doc-2.6.28/Documentation/00-INDEX for a list of what + is contained in each file. Please read the Changes file, as it contains + information about the problems, which may result by upgrading your + kernel. + +Package: linux-headers-2.6.28-11 +Architecture: all +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0) +Provides: linux-headers, linux-headers-2.6 +Description: Header files related to Linux kernel version 2.6.28 + This package provides kernel header files for version 2.6.28, for sites + that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-11/debian.README.gz for details + +Package: linux-libc-dev +Architecture: i386 amd64 armel lpia +Conflicts: libc6-dev (<< 2.3.2.ds1-6), libc6.1-dev (<< 2.3.2.ds1-6), dvb-dev (<< 1.0.1-6), amd64-libs-dev (<= 1.1), linux-kernel-headers +Replaces: libc6-dev (<< 2.3.2.ds1-6), libc6.1-dev (<< 2.3.2.ds1-6), dvb-dev (<< 1.0.1-6), linux-kernel-headers, libdrm-dev +Provides: linux-kernel-headers +Description: Linux Kernel Headers for development + This package provides headers from the Linux kernel. These headers + are used by the installed headers for GNU glibc and other system + libraries. They are NOT meant to be used to build third-party modules for + your kernel. Use linux-headers-* packages for that. + +Package: linux-image-2.6.28-11-generic +Architecture: i386 amd64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, redhat-cluster-modules, ivtv-modules, ndiswrapper-modules-1.9 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3), wireless-crda +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: grub | lilo (>= 19.1) +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on x86/x86_64 + This package contains the Linux kernel image for version 2.6.28 on + x86/x86_64. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Generic processors. + . + Geared toward desktop systems. + . + You likely do not want to install this package directly. Instead, install + the linux-generic meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.28-11-generic +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-11, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on x86/x86_64 + This package provides kernel header files for version 2.6.28 on + x86/x86_64. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-11/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-11-generic +Architecture: i386 amd64 +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on x86/x86_64 + This package provides a kernel debug image for version 2.6.28 on + x86/x86_64. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-11-imx51 +Architecture: armel +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3), wireless-crda +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: flash-kernel +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on I.MX51-based systems + This package contains the Linux kernel image for version 2.6.28 on + I.MX51-based systems. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports I.MX51 processors. + . + Babbage and 3-stack boards + . + You likely do not want to install this package directly. Instead, install + the linux-imx51 meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.28-11-imx51 +Architecture: armel +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-11, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on I.MX51-based systems + This package provides kernel header files for version 2.6.28 on + I.MX51-based systems. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-11/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-11-imx51 +Architecture: armel +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on I.MX51-based systems + This package provides a kernel debug image for version 2.6.28 on + I.MX51-based systems. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-11-iop32x +Architecture: armel +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3), wireless-crda +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: flash-kernel +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on IOP32x-based systems + This package contains the Linux kernel image for version 2.6.28 on + IOP32x-based systems. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports IOP32x processors. + . + Thecus N2100, etc. + . + You likely do not want to install this package directly. Instead, install + the linux-iop32x meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.28-11-iop32x +Architecture: armel +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-11, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on IOP32x-based systems + This package provides kernel header files for version 2.6.28 on + IOP32x-based systems. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-11/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-11-iop32x +Architecture: armel +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on IOP32x-based systems + This package provides a kernel debug image for version 2.6.28 on + IOP32x-based systems. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-11-ixp4xx +Architecture: armel +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3), wireless-crda +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: flash-kernel +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on IXP4xx-based systems + This package contains the Linux kernel image for version 2.6.28 on + IXP4xx-based systems. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports IXP4xx processors. + . + Linksys NSLU2, etc. + . + You likely do not want to install this package directly. Instead, install + the linux-ixp4xx meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.28-11-ixp4xx +Architecture: armel +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-11, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on IXP4xx-based systems + This package provides kernel header files for version 2.6.28 on + IXP4xx-based systems. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-11/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-11-ixp4xx +Architecture: armel +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on IXP4xx-based systems + This package provides a kernel debug image for version 2.6.28 on + IXP4xx-based systems. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-11-lpia +Architecture: lpia +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, kvm-api-4, redhat-cluster-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3), wireless-crda +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: lilo (>= 19.1) | grub +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on Intel Atom processors + This package contains the Linux kernel image for version 2.6.28 on + Intel Atom processors. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Intel Atom processors. + . + Geared toward LPIA-based mobile devices + . + You likely do not want to install this package directly. Instead, install + the linux-lpia meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.28-11-lpia +Architecture: lpia +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-11, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on Intel Atom processors + This package provides kernel header files for version 2.6.28 on + Intel Atom processors. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-11/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-11-lpia +Architecture: lpia +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on Intel Atom processors + This package provides a kernel debug image for version 2.6.28 on + Intel Atom processors. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-11-server +Architecture: i386 amd64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules, kvm-api-4, ivtv-modules, ndiswrapper-modules-1.9 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3), wireless-crda +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: grub | lilo (>= 19.1) +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on x86/x86_64 + This package contains the Linux kernel image for version 2.6.28 on + x86/x86_64. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Server processors. + . + Geared toward server systems. + . + You likely do not want to install this package directly. Instead, install + the linux-server meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.28-11-server +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-11, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on x86/x86_64 + This package provides kernel header files for version 2.6.28 on + x86/x86_64. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-11/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-11-server +Architecture: i386 amd64 +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on x86/x86_64 + This package provides a kernel debug image for version 2.6.28 on + x86/x86_64. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-11-versatile +Architecture: armel +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3), wireless-crda +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on Versatile-based systems + This package contains the Linux kernel image for version 2.6.28 on + Versatile-based systems. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Versatile processors. + . + PB, AB, Qemu, etc. + . + You likely do not want to install this package directly. Instead, install + the linux-versatile meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.28-11-versatile +Architecture: armel +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-11, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on Versatile-based systems + This package provides kernel header files for version 2.6.28 on + Versatile-based systems. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-11/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-11-versatile +Architecture: armel +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on Versatile-based systems + This package provides a kernel debug image for version 2.6.28 on + Versatile-based systems. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-11-virtual +Architecture: i386 amd64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1), linux-image-2.6.28-11-server +Recommends: grub | lilo (>= 19.1) +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on x86/x86_64 + This package contains the Linux kernel image for version 2.6.28 on + x86/x86_64. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports Virtual processors. + . + Geared toward virtual machine guests. + . + You likely do not want to install this package directly. Instead, install + the linux-virtual meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. --- linux-2.6.28.orig/debian/NOTES +++ linux-2.6.28/debian/NOTES @@ -0,0 +1,4 @@ +eSCO patch removed. Replaced upstream with a disable_esco module parm. +airprime: Module gone, use option driver instead +AppArmor: Patch is all there and ported. Ooops when enabled, so default + off (still can be enabled apparmor=1) --- linux-2.6.28.orig/debian/changelog +++ linux-2.6.28/debian/changelog @@ -0,0 +1,4737 @@ +linux (2.6.28-11.42) jaunty; urgency=low + + [ Tim Gardner ] + + * Enabled LPIA CONFIG_PACKET=y + - LP: #362071 + + [ Upstream Kernel Changes ] + + * ext4: fix bb_prealloc_list corruption due to wrong group locking + - LP: #348836 + + -- Stefan Bader Thu, 16 Apr 2009 08:10:55 +0200 + +linux (2.6.28-11.41) jaunty; urgency=low + + [ Amit Kucheria ] + + * ixp4xx: Enabled TCP SYN_COOKIES + - LP: #346378 + + [ Brad Figg ] + + * Change LPIA configuration to compile with CONFIG_NETFILTER_XT_MATCH_RECENT + - LP: #355291 + + [ Kay Sievers ] + + * SAUCE: driver core: allow non-root users to listen to uevents + - LP: #357124 + + [ Manoj Iyer ] + + * SAUCE: Added quirk to recognize GE0301 3G modem as an interface. + - LP: #348861 + + [ Tim Gardner ] + + * Revert "SAUCE: [i915] allocate MCHBAR space & enable if necessary" + Appears to cause hard locks in some cases. + - LP: #349314 + + [ Trond Myklebust ] + + * SAUCE: NFS: Fix the notifications when renaming onto an existing file + - LP: #224642 + + [ Upstream Kernel Changes ] + + * USB: option: add QUANTA HSDPA Data Card device ids + - LP: #353321 + * hwmon: (abituguru3) Match partial DMI board name strings + - LP: #298798 + * zd1211rw: adding Sitecom WL-603 (0df6:0036) to the USB id list + - LP: #339631 + * USB: unusual dev for Option N.V. ZeroCD modems + - LP: #348861 + + -- Tim Gardner Sat, 04 Apr 2009 08:42:14 -0600 + +linux (2.6.28-11.40) jaunty; urgency=low + + [ Amit Kucheria ] + + * Disable DEVKMEM for all archs on Jaunty + - LP: #354221 + + [ Andy Whitcroft ] + + * SAUCE: md: wait for possible pending deletes after stopping an array + - LP: #334994 + + [ Brad Figg ] + + * ARM: Setting the bootloader for imx51 flavour. + - LP: #348382 + * ARM: Add bootloader package Recomendation to iop32x and ixp4xx flavours + - LP: #348382 + + [ Tim Gardner ] + + * SAUCE: [i915] allocate MCHBAR space & enable if necessary + - LP: #349314 + + [ Upstream Kernel Changes ] + + * hpilo: open/close fix + - LP: #353496 + + -- Amit Kucheria Thu, 02 Apr 2009 11:26:22 -0400 + +linux (2.6.28-11.39) jaunty; urgency=low + + [ Alan Tull ] + + * SAUCE: mx51: fix to1.1 in mxc_iomux_set_input + - LP: #348333 + + [ Andy Whitcroft ] + + * SAUCE: acer: rfkill disable quirk for ACER Aspire One + - LP: #319825 + + [ Brad Figg ] + + * ARM: Increase CONFIG_BLK_DEV_RAM_SIZE for imx51 flavour. + - LP: #349842 + * ARM: Enable rtl8187 for imx51 + - LP: #349526 + * ARM: Unset CONFIG_USB_STORAGE_DEBUG for imx51 + - LP: #348504 + + [ Bryan Wu ] + + * build CRAMFS into kernel to support mounting CRAMFS initrd on iop32x + machine + - LP: #349104 + + [ Michael Casadevall ] + + * [lpia] Change ATA, SCSI, SD, ext2-4 modules into compiled-in components + - LP: #347458 + + [ Rob Herring ] + + * SAUCE: imx51: fec: fix cache operations for receive + - LP: #348333 + + [ Sam Yang ] + + * SAUCE: Revert ENGR00103870 FEC reopening causes network wdog timeout + - LP: #348333 + * SAUCE: imx51: fec cache flush functions are incorrect + - LP: #348333 + + [ Upstream Kernel Changes ] + + * Bluetooth: Add fine grained mem_flags usage to btusb driver + - LP: #268502 + * Bluetooth: Handle bulk URBs in btusb driver from notify callback + - LP: #268502 + * Bluetooth: Submit bulk URBs along with interrupt URBs + - LP: #268502 + + -- Tim Gardner Wed, 01 Apr 2009 17:37:32 -0600 + +linux (2.6.28-11.38) jaunty; urgency=low + + [ Brad Figg ] + + * When AppArmor is configured, securityfs must be as well. + - LP: #344370 + * ARM: Enable AA with SECURITYFS for imx51 + - LP: #344370 + + [ Bryan Wu ] + + * Add 3 missing files to prerm remove file list + - LP: #345623 + + [ Daniel T Chen ] + + * SAUCE: (drop after 2.6.28) Don't trust hw-ptr blindly + - LP: #330814 + * SAUCE: (drop after 2.6.28) Apply further pcm_lib updates for hw_ptr + - LP: #330814 + + [ Ike Panhc ] + + * Copy header files for various kernel media driver + - LP: #322732 + + [ Tim Gardner ] + + * Revert "Fix the VFP handling on the Feroceon CPU" + Only applied to mv78xx0 ARM flavour. + * Enabled drivers/staging/at76_usb + - LP: #152626 + + [ ubuntu@tjworld.net ] + + * SAUCE: ipw2200: Enable LED by default + - LP: #21367 + * SAUCE: wistron_btns: support Prestigio Wifi RF kill button over suspend + - LP: #346586 + + [ Upstream Kernel Changes ] + + * Build fix for __early_pfn_to_nid() undefined link error + * Fix misreporting of #cores as #hyperthreads for Q9550 + * eventfd: remove fput() call from possible IRQ context + * S390: __div64_31 broken for CONFIG_MARCH_G5 + * ALSA: Fix vunmap and free order in snd_free_sgbuf_pages() + * ALSA: mixart, fix lock imbalance + * ALSA: pcm_oss, fix locking typo + * ALSA: hda - Fix DMA mask for ATI controllers + * ALSA: hda - Workaround for buggy DMA position on ATI controllers + * ALSA: opl3sa2 - Fix NULL dereference when suspending snd_opl3sa2 + * nfsd: nfsd should drop CAP_MKNOD for non-root + * NFSD: provide encode routine for OP_OPENATTR + * dm ioctl: validate name length when renaming + * dm io: respect BIO_MAX_PAGES limit + * dm crypt: fix kcryptd_async_done parameter + * dm crypt: wait for endio to complete before destruction + * ata_piix: add workaround for Samsung DB-P70 + * V4L/DVB (10218): cx23885: Fix Oops for mixed install of analog and + digital only cards + * thinkpad-acpi: fix module autoloading for older models + * Add '-fwrapv' to gcc CFLAGS + * Move cc-option to below arch-specific setup + * USB: storage: Unusual USB device Prolific 2507 variation added + * USB: Add Vendor/Product ID for new CDMA U727 to option driver + * USB: option.c: add ZTE 622 modem device + * USB: Add device id for Option GTM380 to option driver + * USB: Option: let cdc-acm handle Sony Ericsson F3507g / Dell 5530 + * USB: Updated unusual-devs entry for USB mass storage on Nokia 6233 + * USB: unusual_devs: Add support for GI 0431 SD-Card interface + * USB: serial: add FTDI USB/Serial converter devices + * USB: serial: ftdi: enable UART detection on gnICE JTAG adaptors + blacklist interface0 + * USB: serial: new cp2101 device id + * USB: usbtmc: fix stupid bug in open() + * USB: usbtmc: add protocol 1 support + * USB: usbfs: keep async URBs until the device file is closed + * USB: EHCI: expedite unlinks when the root hub is suspended + * USB: EHCI: Fix isochronous URB leak + * powerpc: Remove extra semicolon in fsl_soc.c + * menu: fix embedded menu snafu + * Linux 2.6.28.9 + * Add '-fwrapv' to gcc CFLAGS + - LP: #348015 + * Move cc-option to below arch-specific setup + - LP: #348015 + * Revert Staging: at76_usb: update drivers/staging/at76_usb w/ mac80211 + port + - LP: #152626 + * Staging: at76_usb: fix bugs introduced by "Staging: at76_usb: cleanup + dma on stack issues" + - LP: #152626 + * Staging: at76_usb: Add support for OQO Model 01+ + - LP: #152626 + + -- Tim Gardner Mon, 23 Mar 2009 19:20:08 -0600 + +linux (2.6.28-11.37) jaunty; urgency=low + + [ Alex Deucher ] + + * SAUCE: radeon: add some new pci ids + - LP: #334101 + + [ Amit Kucheria ] + + * Updating configs - rip out orion5x and mv78xx0 flavours + + [ Andy Whitcroft ] + + * SAUCE: tone down the synaptics warning to avoid triggering kerneloops + - LP: #330606 + + [ Upstream Kernel Changes ] + + * ext4: fix header check in ext4_ext_search_right() for deep extent + trees. + - LP: #346194 + * eCryptfs: NULL crypt_stat dereference during lookup + - LP: #345766 + * eCryptfs: Allocate a variable number of pages for file headers + (CVE-2009-0787) + - LP: #345544 + + -- Tim Gardner Mon, 23 Mar 2009 09:24:32 -0600 + +linux (2.6.28-11.36) jaunty; urgency=low + + [ Amit Kucheria ] + + * Updating imx51 configs one more time + * Disable CONFIG_UEVENT_HELPER_PATH + + [ Anton Veretenenko ] + + * SAUCE: sony-laptop: add support for Sony Vaio FW series function/media + keys + - LP: #307592 + + [ Brad Figg ] + + * Have AUFS use current VFS APIs so it can build with or without + AppArmor. + + [ Bryan Wu ] + + * Build-in "Ram block device support" to boot up with initramfs + - LP: #329098 + * Remove brd module from iop32x modules list + - LP: #329098 + * Increase the CONFIG_BLK_DEV_RAM_SIZE to 8192 on i.MX51 + + [ Ike Panhc ] + + * SAUCE: Fixing symbol name in HECI module + - LP: #336549 + + [ Manoj Iyer ] + + * SAUCE: Added quirk for Ralink rt2870 802.11n USB driver + - LP: #326621 + + [ Upstream Kernel Changes ] + + * udf:SAUCE (drop after 2.6.30): Fix oops when invalid character in + filename occurs + - LP: #321606 + + -- Stefan Bader Fri, 20 Mar 2009 16:52:08 +0100 + +linux (2.6.28-11.35) jaunty; urgency=low + + [ Amit Kucheria ] + + * Updating imx51 configs + + [ Andy Whitcroft ] + + * SAUCE: hotkey quirks for various Zeptro Znote and Fujitsu Amilo laptops + - LP: #330259 + + [ Tim Gardner ] + + * Revert "SAUCE: (drop after 2.6.28) eCryptfs: Don't encrypt file key + with filename key". Use upstream commit. + * CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR set to upstream defaults. + 64K for x86'en, 32K for ARM + - LP: #344955 + + [ Upstream Kernel Changes ] + + * eCryptfs: don't encrypt file key with filename key + * libata: set NODEV_HINT for 0x7f status + - LP: #293218 + * USB: cdc-acm: Add another conexant modem to the quirks + - LP: #323829 + * Input: elantech - touchpad driver miss-recognising logitech mice + - LP: #318722 + + -- Tim Gardner Wed, 18 Mar 2009 08:52:46 -0600 + +linux (2.6.28-11.34) jaunty; urgency=low + + [ Alex Deucher ] + + * SAUCE: (drop after 2.6.28) radeon: add support for RS600, R6xx, and + R7xx GPUs + - LP: #334101 + + [ Aristeu Sergio Rozanski Filho ] + + * SAUCE: (drop after 2.6.28) ALSA: hda: add quirk for Lenovo X200 laptop + dock + + [ Shane Huang ] + + * SAUCE: (drop after 2.6.28) i2c-piix4: Add support to SB800 SMBus + changes + - LP: #338108 + + [ Upstream Kernel Changes ] + + * net: amend the fix for SO_BSDCOMPAT gsopt infoleak + * net: Kill skb_truesize_check(), it only catches false-positives. + * sparc64: Fix crashes in jbusmc_print_dimm() + * sparc64: Fix DAX handling via userspace access from kernel. + * vfs: separate FMODE_PREAD/FMODE_PWRITE into separate flags + * seq_file: properly cope with pread + * vt: Declare PIO_CMAP/GIO_CMAP as compatbile ioctls. + * timerfd: add flags check + * aoe: ignore vendor extension AoE responses + * mm: clean up for early_pfn_to_nid() + * mm: fix memmap init for handling memory hole + * Fix oops in cifs_strfromUCS_le mounting to servers which do not specify + their OS + * mm: fix lazy vmap purging (use-after-free error) + * mm: vmap fix overflow + * PCI quirk: enable MSI on 8132 + * SCSI: hptiop: Add new PCI device ID + * JFFS2: fix mount crash caused by removed nodes + * SCSI: sd: revive sd_index_lock + * USB: usb_get_string should check the descriptor type + * USB: usb-storage: add IGNORE_RESIDUE flag for Genesys Logic adapters + * USB: cdc-acm: add usb id for motomagx phones + * rtl8187: New USB ID's for RTL8187L + * WATCHDOG: ks8695_wdt.c: 'CLOCK_TICK_RATE' undeclared + * WATCHDOG: rc32434_wdt: fix watchdog driver + * WATCHDOG: rc32434_wdt: fix sections + * RDMA/nes: Don't allow userspace QPs to use STag zero + * USB: option: add BenQ 3g modem information + * md: avoid races when stopping resync. + * md/raid10: Don't call bitmap_cond_end_sync when we are doing recovery. + * md/raid10: Don't skip more than 1 bitmap-chunk at a time during + recovery. + * sound: virtuoso: revert "do not overwrite EEPROM on Xonar D2/D2X" + * ALSA: usb-audio - Fix non-continuous rate detection + * ALSA: usb-audio - Workaround for misdetected sample rate with CM6207 + * sound: usb-audio: fix uninitialized variable with M-Audio MIDI + interfaces + * ALSA: fix excessive background noise introduced by OSS emulation rate + shrink + * ALSA: hda - Fix digital mic on dell-m4-1 and dell-m4-3 + * ALSA: aw2: do not grab every saa7146 based device + * acer-wmi: fix regression in backlight detection + * vmalloc: call flush_cache_vunmap() from unmap_kernel_range() + * Fix fixpoint divide exception in acct_update_integrals + * 8250: fix boot hang with serial console when using with Serial Over Lan + port + * x86, vmi: TSC going backwards check in vmi clocksource + * HID: fix bus endianity in file2alias + * inotify: fix GFP_KERNEL related deadlock + * sdhci: fix led naming + * x86: oprofile: don't set counter width from cpuid on Core2 + * intel-agp: fix a panic with 1M of shared memory, no GTT entries + * mtd_dataflash: fix probing of AT45DB321C chips. + * proc: fix kflags to uflags copying in /proc/kpageflags + * fs: new inode i_state corruption fix + * PCIe: portdrv: call pci_disable_device during remove + * PCI: Enable PCIe AER only after checking firmware support + * jsm: additional device support + * libata: Don't trust current capacity values in identify words 57-58 + * mmc: fix data timeout for SEND_EXT_CSD + * s3cmci: Fix hangup in do_pio_write() + * mmc: s3cmci: fix s3c2410_dma_config() arguments. + * MMC: fix bug - SDHC card capacity not correct + * mmc_test: fix basic read test + * x86: tone down mtrr_trim_uncached_memory() warning + * selinux: Fix a panic in selinux_netlbl_inode_permission() + * selinux: Fix the NetLabel glue code for setsockopt() + * hpilo: new pci device + * x86-64: seccomp: fix 32/64 syscall hole + * x86-64: syscall-audit: fix 32/64 syscall hole + * xen: disable interrupts early, as start_kernel expects + * xen/blkfront: use blk_rq_map_sg to generate ring entries + * asix: new device ids + * cdc_ether: add usb id for Ericsson F3507g + * zaurus: add usb id for motomagx phones + * fore200: fix oops on failed firmware load + * PCI: Add PCI quirk to disable L0s ASPM state for 82575 and 82598 + * copy_process: fix CLONE_PARENT && parent_exec_id interaction + * proc: fix PG_locked reporting in /proc/kpageflags + * powerpc: Fix load/store float double alignment handler + * sdhci: Add quirk for controllers with no end-of-busy IRQ + * sdhci: Add NO_BUSY_IRQ quirk for Marvell CAFE host chip + * pipe_rdwr_fasync: fix the error handling to prevent the leak/crash + * DVB: s5h1409: Perform s5h1409 soft reset after tuning + * V4L: tda8290: fix TDA8290 + TDA18271 initialization + * V4L: ivtv: fix decoder crash regression + * x86/paravirt: make arch_flush_lazy_mmu/cpu disable preemption + * x86, hpet: fix for LS21 + HPET = boot hang + * x86: math_emu info cleanup + * x86: fix math_emu register frame access + * ide-iops: fix odd-length ATAPI PIO transfers + * HID: move tmff and zpff devices from ignore_list to blacklist + * ARM: Add i2c_board_info for RiscPC PCF8583 + * i2c: Timeouts reach -1 + * i2c: Fix misplaced parentheses + * ACPI: fix broken usage of name.ascii + * ACPI: fix broken usage of acpi_ut_get_node_name() + * crypto: api - Fix algorithm test race that broke aead initialisation + * hwmon: (f71882fg) Hide misleading error message + * MIPS: compat: Implement is_compat_task. + * hwmon: (it87) Properly decode -128 degrees C temperature + * Linux 2.6.28.8 + + -- Tim Gardner Tue, 17 Mar 2009 07:07:33 -0600 + +linux (2.6.28-10.33) jaunty; urgency=low + + [ Scott James Remnant ] + + * SAUCE: nbd: Change default partitions per device to 15 + - LP: #342563 + + [ Tejun Heo ] + + * SAUCE: libata: make sure port is thawed when skipping resets + - LP: #269652 + + [ Tim Gardner ] + + * Revert "SAUCE: Auto-load esp module when device opened." + This driver performs unsafe ISA probes (according to Alan Cox). + * Enable CONFIG_USB_GADGET_DUMMY_HCD + This facilitates gadget slave endpoints in virtual environments. + * Build ehci, uhci, and ohci into the i386/amd64 kernels + - LP: #296710 + + [ Upstream Kernel Changes ] + + * Add "thumbee" to the hwcap_str array + - LP: #343602 + * Add HWCAP_NEON to the ARM hwcap.h file + - LP: #343602 + * x86: mtrr: don't modify RdDram/WrDram bits of fixed MTRRs + - LP: #292619 + + -- Tim Gardner Mon, 16 Mar 2009 08:19:53 -0600 + +linux (2.6.28-10.32) jaunty; urgency=low + + [ Amit Kucheria ] + + * Delete prepare-ppa-source script + + [ Andy Isaacson ] + + * SAUCE: FSAM7400: select CHECK_SIGNATURE + * SAUCE: LIRC_PVR150: depends on VIDEO_IVTV + - LP: #341477 + + [ Ayaz Abdulla ] + + * SAUCE: forcedeth: msi interrupt fix + - LP: #288281 + + [ Brad Figg ] + + * Updating armel configs to remove PREEMPT + + [ Catalin Marinas ] + + * Fix the VFP handling on the Feroceon CPU + + [ Huaxu Wan ] + + * SAUCE: (drop after 2.6.28) [Jaunty] iwlagn: fix iwlagn DMA mapping + direction + + [ Ike Panhc ] + + * squashfs: correct misspelling + - LP: #322306 + + [ Theodore Ts'o ] + + * SAUCE: (drop after 2.6.28) ext4: add EXT4_IOC_ALLOC_DA_BLKS ioctl + * SAUCE: (drop after 2.6.28) ext4: Automatically allocate delay allocated + blocks on close + * SAUCE: (drop after 2.6.28) ext4: Automatically allocate delay allocated + blocks on rename + - LP: #317781 + + [ Tyler Hicks ] + + * SAUCE: (drop after 2.6.28) eCryptfs: Don't encrypt file key with + filename key + - LP: #342128 + + [ Upstream Kernel Changes ] + + * ALS: hda - Add support of iMac 24 Aluminium + * USB: fix broken OTG makefile reference + * ALSA: hda - add another MacBook Pro 3,1 SSID + * ALSA: hda - Add model entry for HP dv4 + * x86-64: fix int $0x80 -ENOSYS return + - LP: #339743 + + -- Tim Gardner Thu, 12 Mar 2009 19:16:07 -0600 + +linux (2.6.28-9.31) jaunty; urgency=low + + [ Andy Whitcroft ] + + * SAUCE: cpufreq-nforce2: probe failures are not errors + - LP: #332170 + * SAUCE: mmc: add MODALIAS linkage for MMC/SD devices + - LP: #30335 + * remove test-suspend script + - LP: #333856 + + [ Kees Cook ] + + * handle relative paths in modules.dep + Fixes 2.6.28-9.30 FTBS. + + [ Upstream Kernel Changes ] + + * ricoh_mmc: Handle newer models of Ricoh controllers + + -- Tim Gardner Wed, 11 Mar 2009 08:19:24 -0600 + +linux (2.6.28-9.30) jaunty; urgency=low + + [ Amit Kucheria ] + + * ARM:mx51 Add SoC and board support for mx51 platforms + * ARM:mx51 Add CONFIG_ARCH_MXC_CANONICAL to disable parts of Freescale's + code + * MMC: Add support for 8-bit cards + * Add ARM:MX51 SoC support to the build system + * ARM: Make ARM arch aware of ubuntu/ drivers + * ARM: Add imx51 configuration + * Disable d-i modules for imx51 and mv78xx0 + * Disable Apparmor on boot for ARM + * Updating imx51 config + + [ Jason Liu ] + + * Do not use OOB with MLC NAND + + [ Richard Zhu ] + + * Support the eMMC4.3 card + + [ Rob Herring ] + + * ARM: Add more cache memory types macros + + [ Tim Gardner ] + + * Set CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y for i386/amd64/lpia + + [ Manoj Iyer ] + + * Enable CONFIG_RTL8187SE=m + + [ Upstream Kernel Changes ] + + * USB: EHCI: slow down ITD reuse + - LP: #329437 + + -- Tim Gardner Sun, 08 Mar 2009 14:14:15 -0600 + +linux (2.6.28-9.29) jaunty; urgency=low + + [ Andy Whitcroft ] + + * link-headers -- only link directories which do not already exist + - LP: #315252 + + [ Daniel Marjamäki ] + + * SAUCE: (drop after 2.6.28) netxen: fix memory leak in + drivers/net/netxen_nic_init.c + - LP: #330813 + + [ Dhananjay Phadke ] + + * SAUCE: (drop after 2.6.28) netxen: fix endianness in firmware commands + - LP: #330813 + * SAUCE: (drop after 2.6.28) netxen: fix ipv6 offload and tx cleanup + - LP: #330813 + * SAUCE: (drop after 2.6.28) netxen: fix link speed reporting for some + boards + - LP: #330813 + * SAUCE: (drop after 2.6.28) netxen: firmware init fix + - LP: #330813 + * SAUCE: (drop after 2.6.28) netxen: cleanup mac list on driver unload + - LP: #330813 + * SAUCE: (drop after 2.6.28) netxen: hold tx lock while sending firmware + commands + - LP: #330813 + * SAUCE: (drop after 2.6.28) netxen: handle dma mapping failures + - LP: #330813 + * SAUCE: (drop after 2.6.28) netxen: avoid invalid iounmap + - LP: #330813 + * SAUCE: (drop after 2.6.28) netxen: include ipv6.h (fixes build failure) + - LP: #330813 + * SAUCE: (drop after 2.6.28) netxen: fix vlan tso/checksum offload + - LP: #330813 + * SAUCE: (drop after 2.6.28) netxen: reduce memory footprint + - LP: #330813 + * SAUCE: (drop after 2.6.28) netxen: revert jumbo ringsize + - LP: #330813 + * SAUCE: (drop after 2.6.28) netxen: fix msi-x interrupt handling + - LP: #330813 + * SAUCE: (drop after 2.6.28) netxen: remove pcie workaround + - LP: #330813 + + [ Hannes Eder ] + + * SAUCE: (drop after 2.6.28) drivers/net/netxen: fix sparse warnings: use + NULL pointer instead of plain integer + - LP: #330813 + + [ Huaxu Wan ] + + * SAUCE: report rfkill changes event if interface is down + - LP: #193970 + + [ Tim Gardner ] + + * MV78XX0 must specify a target in the vars definition. + + [ Upstream Kernel Changes ] + + * Revert "ext4: wait on all pending commits in ext4_sync_fs()" + * jbd2: Fix return value of jbd2_journal_start_commit() + * jbd2: Avoid possible NULL dereference in + jbd2_journal_begin_ordered_truncate() + * ext4: Fix to read empty directory blocks correctly in 64k + * ext4: Fix lockdep warning + * ext4: Initialize preallocation list_head's properly + * ext4: Implement range_cyclic in ext4_da_writepages instead of + write_cache_pages + * ext4: Fix NULL dereference in ext4_ext_migrate()'s error handling + * ext4: Add fallback for find_group_flex + * ext4: Fix deadlock in ext4_write_begin() and ext4_da_write_begin() + * Added mv78xx0 flavor + + -- Tim Gardner Fri, 06 Mar 2009 06:13:31 -0700 + +linux (2.6.28-8.28) jaunty; urgency=low + + [ Alexey Starikovskiy ] + + * SAUCE: ACPI: EC: Limit workaround for ASUS notebooks even more + - LP: #288385 + + [ Scott James Remnant ] + + * SAUCE: Auto-load esp module when device opened. + * SAUCE: Auto-load bridge module when socket opened. + * SAUCE: Auto-load af_netlink module when socket opened. + * SAUCE: Auto-load wanrouter module when socket opened. + * SAUCE: Auto-load ip_queue module when socket opened. + * SAUCE: Auto-load ip6_queue module when socket opened. + * SAUCE: Auto-load cn module when socket opened. + * SAUCE: Auto-load scsi_transport_iscsi module when socket opened. + * SAUCE: Auto-load ftl module when device opened. + * SAUCE: Auto-load pcd module when device opened. + * SAUCE: Auto-load pf module when device opened. + * SAUCE: Auto-load nftl module when device opened. + * SAUCE: Auto-load mousedev module when psaux device opened. + * SAUCE: Auto-load mousedev module when /dev/input/mice opened. + * SAUCE: Auto-load rng-core module when device opened. + * SAUCE: Auto-load openprom module when device opened. + * SAUCE: Auto-load applicom module when device opened. + * SAUCE: Auto-load toshiba module when device opened. + * SAUCE: Auto-load cyclades module when device opened. + * SAUCE: Auto-load riscom8 module when device opened. + * SAUCE: Auto-load specialix module when device opened. + * SAUCE: Auto-load videodev module when device opened. + * SAUCE: Auto-load i2c_dev module when device opened. + * SAUCE: Auto-load mtdchar module when device opened. + * SAUCE: Auto-load pt module when device opened. + * SAUCE: Auto-load pg module when device opened. + * SAUCE: Auto-load cdc_acm module when device opened. + * SAUCE: Auto-load msr module when device opened. + * SAUCE: Auto-load cpuid module when device opened. + * SAUCE: quickcam: Enable double-buffering by default + * SAUCE: libata: Ignore HPA by default. + * SAUCE: hostap: Change initial operation mode to managed (infra) + * SAUCE: floppy: Provide a PnP device table in the module. + - LP: #255651 + * SAUCE: Auto-load mwave module when device opened. + * Build CONFIG_FUSE_FS into kernel, not as module. + + [ Stefan Bader ] + + * Enable build of ext4 as a module on LPIA + - LP: #331848 + + [ Tim Gardner ] + + * Update configs to fix LPIA FTBS + + -- Tim Gardner Thu, 05 Mar 2009 10:43:24 -0700 + +linux (2.6.28-8.27) jaunty; urgency=low + + [ Amit Kucheria ] + + * Updating configs (arm:ixp4xx) + + [ Andy Whitcroft ] + + * SAUCE: enable Intel HDMI output + + [ Manoj Iyer ] + + * SAUCE: Added quirk for Linksys WUSB600N USB wifi-n networking adapter + - LP: #323473 + + [ Steve Beattie ] + + * fix apparmor memory leak on unlinked file ops + - LP: #329489 + + [ Tim Gardner ] + + * SAUCE: Dell XPS710 reboot quirk + - LP: #323592 + * SAUCE: (drop after 2.6.28) ieee80211: Add infrastructure to obsolete + scan results + - LP: #336055 + * Add modules.order to the linux-image package. + + [ Upstream Kernel Changes ] + + * iwlwifi: fix time interval misuse in iwl_poll_{direct_}bit + * x86: only scan the root bus in early PCI quirks + - LP: #267295 + * ALSA: hda - Intel HDMI audio support + * ALSA: hda - Fix unused function in patch_intelhdmi.c + * ALSA: handle SiI1392 HDMI codec in patch_intelhdmi.c + * ALSA: hda-intel: reorder HDMI audio enabling sequence + * ALSA: introduce snd_print_pcm_rates() + * ALSA: create hda_eld.c for ELD routines and proc interface + * ALSA: ELD proc interface for HDMI sinks + * ALSA: hda: make standalone hdmi_fill_audio_infoframe() + * ALSA: hda: make global snd_print_channel_allocation() + * ALSA: hda: HDMI channel allocations for audio infoframe + * ALSA: hda: HDMI channel mapping cleanups + * ALSA: hda: minor code cleanups + * ALSA: hda: rename sink_eld to hdmi_eld + * ALSA: hda - Release ELD proc file + * ALSA: hda - minor HDMI code cleanups + * ALSA: hda - report selected CA index for Audio InfoFrame + * ALSA: hda - Add Intel vendor id string + + -- Tim Gardner Wed, 25 Feb 2009 14:23:46 -0700 + +linux (2.6.28-8.26) jaunty; urgency=low + + [ Amit Kucheria ] + + * Updating configs (armel:ixp4xx) + - LP: #331510 + + [ Tim Gardner ] + + * Add more missing modules + + -- Tim Gardner Tue, 24 Feb 2009 06:58:53 -0700 + +linux (2.6.28-8.25) jaunty; urgency=low + + [ Scott James Remnant ] + + * SAUCE: Prefer powernow-k8 to acpi-cpufreq + * Change CONFIG_X86_P4_CLOCKMOD to be a module again. + + [ Tim Gardner ] + + * Revert "SAUCE: (revert before 2.6.28.y update) ext4: Initialize the new + group descriptor when resizing the filesystem" + * Revert "SAUCE: (revert before 2.6.28.y update) ext4: Add sanity check + to make_indexed_dir" + * Revert "SAUCE: (revert before 2.6.28.y update) ext4: only use + i_size_high for regular files" + * Revert "SAUCE: (revert before 2.6.28.y update) ext4: Add sanity checks + for the superblock before mounting the filesystem" + * Revert "SAUCE: (revert before 2.6.28.y update) ext4: Fix + s_dirty_blocks_counter if block allocation failed with nodelalloc" + * Revert "SAUCE: (revert before 2.6.28.y update) ext4: Init the complete + page while building buddy cache" + * Revert "SAUCE: (revert before 2.6.28.y update) ext4: Don't allow new + groups to be added during block allocation" + * Revert "SAUCE: (revert before 2.6.28.y update) ext4: mark the + blocks/inode bitmap beyond end of group as used" + * Revert "SAUCE: (revert before 2.6.28.y update) ext4: Use new + buffer_head flag to check uninit group bitmaps initialization" + * Revert "SAUCE: (revert before 2.6.28.y update) ext4: Fix the race + between read_inode_bitmap() and ext4_new_inode()" + * Revert "SAUCE: (revert before 2.6.28.y update) ext4: Fix race between + read_block_bitmap() and mark_diskspace_used()" + * Revert "SAUCE: (revert before 2.6.28.y update) ext4: don't use blocks + freed but not yet committed in buddy cache init" + * Revert "SAUCE: (revert before 2.6.28.y update) ext4: cleanup mballoc + header files" + * Revert "SAUCE: (revert before 2.6.28.y update) ext4: Use + EXT4_GROUP_INFO_NEED_INIT_BIT during resize" + * Revert "SAUCE: (revert before 2.6.28.y update) ext4: Add blocks added + during resize to bitmap" + * Revert "SAUCE: (revert before 2.6.28.y update) ext4: Don't overwrite + allocation_context ac_status" + * Revert "SAUCE: (revert before 2.6.28.y update) jbd2: Add barrier not + supported test to journal_wait_on_commit_record" + * Revert "SAUCE: (revert before 2.6.28.y update) ext4: Widen type of + ext4_sb_info.s_mb_maxs[]" + * Revert "SAUCE: (revert before 2.6.28.y update) ext4: avoid ext4_error + when mounting a fs with a single bg" + * Revert "SAUCE: (revert before 2.6.28.y update) ext4: Fix the delalloc + writepages to allocate blocks at the right offset." + * Revert "SAUCE: (revert before 2.6.28.y update) ext4: tone down + ext4_da_writepages warnings" + * Revert "SAUCE: (revert before 2.6.28.y update) ext4: Add support for + non-native signed/unsigned htree hash algorithms" + * Enabled X86_ACPI_CPUFREQ=y + + [ Upstream Kernel Changes ] + + * ath9k: quiet harmless ForceXPAon messages + - LP: #321474 + * [WATCHDOG] iTCO_wdt: fix SMI_EN regression 2 + - LP: #314050 + * pid: implement ns_of_pid + * mqueue: fix si_pid value in mqueue do_notify() + * powerpc/vsx: Fix VSX alignment handler for regs 32-63 + * sata_nv: give up hardreset on nf2 + * Fix Intel IOMMU write-buffer flushing + * SCSI: libiscsi: fix iscsi pool leak + * x86/cpa: make sure cpa is safe to call in lazy mmu mode + * sched: SCHED_OTHER vs SCHED_IDLE isolation + * x86, vm86: fix preemption bug + * Add support for VT6415 PCIE PATA IDE Host Controller + * ext2/xip: refuse to change xip flag during remount with busy inodes + * 3c505: do not set pcb->data.raw beyond its size + * Bluetooth: Fix TX error path in btsdio driver + * ext4: Add support for non-native signed/unsigned htree hash algorithms + * ext4: tone down ext4_da_writepages warnings + * ext4: Fix the delalloc writepages to allocate blocks at the right + offset. + * ext4: avoid ext4_error when mounting a fs with a single bg + * ext4: Widen type of ext4_sb_info.s_mb_maxs[] + * jbd2: Add barrier not supported test to journal_wait_on_commit_record + * ext4: Don't overwrite allocation_context ac_status + * ext4: Add blocks added during resize to bitmap + * ext4: Use EXT4_GROUP_INFO_NEED_INIT_BIT during resize + * ext4: cleanup mballoc header files + * ext4: don't use blocks freed but not yet committed in buddy cache init + * ext4: Fix race between read_block_bitmap() and mark_diskspace_used() + * ext4: Fix the race between read_inode_bitmap() and ext4_new_inode() + * ext4: Use new buffer_head flag to check uninit group bitmaps + initialization + * ext4: mark the blocks/inode bitmap beyond end of group as used + * ext4: Don't allow new groups to be added during block allocation + * ext4: Init the complete page while building buddy cache + * ext4: Fix s_dirty_blocks_counter if block allocation failed with + nodelalloc + * ext4: Add sanity checks for the superblock before mounting the + filesystem + * ext4: only use i_size_high for regular files + * ext4: Add sanity check to make_indexed_dir + * ext4: Initialize the new group descriptor when resizing the filesystem + * Fix longstanding "error: storage size of '__mod_dmi_device_table' isn't + known" + * Linux 2.6.28.7 + + -- Tim Gardner Thu, 19 Feb 2009 06:45:55 -0700 + +linux (2.6.28-8.24) jaunty; urgency=low + + [ Scott James Remnant ] + + * Change CPU_FREQ_DEFAULT_GOV_ONDEMAND to y + * SAUCE: Link acpi-cpufreq.o first + + [ Tim Gardner ] + + * Build in CPU Frequency scaling drivers + + -- Tim Gardner Wed, 18 Feb 2009 06:12:24 -0700 + +linux (2.6.28-8.23) jaunty; urgency=low + + [ Andy Whitcroft ] + + * include the kernel configuration in the sub-flavour images + - LP: #328859 + + [ Tim Gardner ] + + * Revert "SAUCE: (drop after 2.6.28) [eCryptfs] Regression in unencrypted + filename symlinks" in favor of upstream commit. + * Fix compile issues with qc-usb + * SAUCE: (remove after 2.6.28) V4L/DVB (10216): saa7127: fix broken + S-Video with saa7129 + - LP: #329267 + + [ Upstream Kernel Changes ] + + * Subject:SAUCE: LP#193970 iwlagn: fix hw-rfkill while the interface is + down + - LP: #193970 + * x86, vmi: put a missing paravirt_release_pmd in pgd_dtor + * nbd: fix I/O hang on disconnected nbds + * mac80211: restrict to AP in outgoing interface heuristic + * w1: w1 temp calculation overflow fix + * zd1211rw: adding 0ace:0xa211 as a ZD1211 device + * zd1211rw: treat MAXIM_NEW_RF(0x08) as UW2453_RF(0x09) for TP-Link + WN322/422G + * parport: parport_serial, don't bind netmos ibm 0299 + * syscall define: fix uml compile bug + * kernel-doc: fix syscall wrapper processing + * Fix page writeback thinko, causing Berkeley DB slowdown + * write-back: fix nr_to_write counter + * writeback: fix break condition + * mm: rearrange exit_mmap() to unlock before arch_exit_mmap + * powerpc/fsl-booke: Fix mapping functions to use phys_addr_t + * lockd: fix regression in lockd's handling of blocked locks + * sctp: Fix crc32c calculations on big-endian arhes. + * sctp: Correctly start rtx timer on new packet transmissions. + * sctp: Properly timestamp outgoing data chunks for rtx purposes + * net: Fix frag_list handling in skb_seq_read + * net: Fix OOPS in skb_seq_read(). + * drivers/net/skfp: if !capable(CAP_NET_ADMIN): inverted logic + * ipv4: fix infinite retry loop in IP-Config + * net: Fix userland breakage wrt. linux/if_tunnel.h + * net: packet socket packet_lookup_frame fix + * packet: Avoid lock_sock in mmap handler + * sungem: Soft lockup in sungem on Netra AC200 when switching interface + up + * udp: Fix UDP short packet false positive + * udp: increments sk_drops in __udp_queue_rcv_skb() + * ipv6: Disallow rediculious flowlabel option sizes. + * ipv6: Copy cork options in ip6_append_data + * net: 4 bytes kernel memory disclosure in SO_BSDCOMPAT gsopt try #2 + * sky2: fix hard hang with netconsoling and iface going up + * tun: Add some missing TUN compat ioctl translations. + * tun: Fix unicast filter overflow + * virtio_net: Fix MAX_PACKET_LEN to support 802.1Q VLANs + * tcp: splice as many packets as possible at once + * tcp: Fix length tcp_splice_data_recv passes to skb_splice_bits. + * sparc: Enable syscall wrappers for 64-bit (CVE-2009-0029) + * sparc64: Annotate sparc64 specific syscalls with SYSCALL_DEFINEx() + * ALSA: hda - Add missing terminator in slave dig-out array + * ALSA: mtpav - Fix initial value for input hwport + * HID: adjust report descriptor fixup for MS 1028 receiver + * ide/libata: fix ata_id_is_cfa() (take 4) + * libata: fix EH device failure handling + * netfilter: fix tuple inversion for Node information request + * netfilter: xt_sctp: sctp chunk mapping doesn't work + * x86: microcode_amd: fix wrong handling of equivalent CPU id + * ide-cd: fix DMA for non bio-backed requests + * net: Fix data corruption when splicing from sockets. + * Linux 2.6.28.6 + * eCryptfs: Regression in unencrypted filename symlinks + + -- Tim Gardner Mon, 16 Feb 2009 06:43:51 -0700 + +linux (2.6.28-8.22) jaunty; urgency=low + + [ Amit Kucheria ] + + * Remove perm-blacklist + + [ Andy Whitcroft ] + + * SAUCE: psmouse/synaptics: ensure we reset the device on resume + - LP: #317270 + + [ Tim Gardner ] + + * Add lpia to getabi script + * SAUCE: tracer for sreadahead + + -- Amit Kucheria Fri, 13 Feb 2009 15:23:21 +0200 + +linux (2.6.28-8.21) jaunty; urgency=low + + [ Andy Whitcroft ] + + * SAUCE: switch the Asus Pundit P1-AH2 to old acpi sleep ordering + - LP: #327267 + + [ Tim Gardner ] + + * Added LPIA arch support + * Added libdrm-dev as a 'Replaces' to linux-libc-dev + * SAUCE: LPIA support for 9202 HDA Sigmatel codec + * SAUCE: Add an X86_LPIA Kconfig option + * SAUCE: UHCI USB quirk for resume + * SAUCE: LPIA Reboot fix for Intel Crownbeach development boards + * SAUCE: LPIA Logical reset of USB port on resume + * Set CONFIG_WIRELESS_OLD_REGULATORY=n, added wireless-crda + as an install dependency. + + [ Upstream Kernel Changes ] + + * Revert "Revert "x86, early_ioremap: fix fencepost error"" + - LP: #312554 + * drm/i915: capture last_vblank count at IRQ uninstall time too + - LP: #320813 + * drm/i915: add get_vblank_counter function for GM45 + - LP: #320813 + * Staging: comedi: fix Kbuild + * Staging: meilhaus: fix Kbuild + * Staging: android: binder: fix arm build errors + * Staging: android: timed_gpio: Fix build to build on kernels after + 2.6.25. + * Staging: android: fix build error on 64bit boxes + * Staging: android: Add lowmemorykiller documentation. + * Staging: android: task_get_unused_fd_flags: fix the wrong usage of + tsk->signal + * staging: agnx: drivers/staging/agnx/agnx.h needs + * Staging: usbip: usbip_start_threads(): handle kernel_thread failure + * Staging: poch: fix verification of memory area + * Documentation: move DMA-mapping.txt to Doc/PCI/ + * sgi-xp: fix writing past the end of kzalloc()'d space + * do_wp_page: fix regression with execute in place + * wait: prevent exclusive waiter starvation + * shm: fix shmctl(SHM_INFO) lockup with !CONFIG_SHMEM + * revert "rlimit: permit setting RLIMIT_NOFILE to RLIM_INFINITY" + * prevent kprobes from catching spurious page faults + * sound: usb-audio: handle wMaxPacketSize for FIXED_ENDPOINT devices + * md: Ensure an md array never has too many devices. + * md: Fix a bug in linear.c causing which_dev() to return the wrong + device. + * ACPI: Enable bit 11 in _PDC to advertise hw coord + * ACPI: dock: Don't eval _STA on every show_docked sysfs read + * ieee1394: ohci1394: increase AT req. retries, fix ack_busy_X from + Panasonic camcorders and others + * firewire: ohci: increase AT req. retries, fix ack_busy_X from Panasonic + camcorders and others + * firewire: sbp2: fix DMA mapping leak on the failure path + * firewire: sbp2: add workarounds for 2nd and 3rd generation iPods + * ieee1394: sbp2: add workarounds for 2nd and 3rd generation iPods + * module: remove over-zealous check in __module_get() + * x86: APIC: enable workaround on AMD Fam10h CPUs + * eeepc-laptop: fix oops when changing backlight brightness during + eeepc-laptop init + * eeepc-laptop: Add support for extended hotkeys + * e1000: fix bug with shared interrupt during reset + * e1000: Fix PCI enable to honor the need_ioport flag + * agp/intel: Fix broken ® symbol in device name. + * ALSA: hda - Add quirk for FSC Amilo Xi2550 + * ALSA: hda - Add missing COEF initialization for ALC887 + * ALSA: hda - Add missing initialization for ALC272 + * asus_acpi: Add R1F support + * panasonic-laptop: fix X[ ARRAY_SIZE(X) ] + * ACPI: Skip the first two elements in the _BCL package + * ACPI: proc_dir_entry 'video/VGA' already registered + * ACPI: disable ACPI cleanly when bad RSDP found + * ACPICA: Fix table entry truncation calculation + * PCI: properly clean up ASPM link state on device remove + * PCI: return error on failure to read PCI ROMs + * seq_file: move traverse so it can be used from seq_read + * seq_file: fix big-enough lseek() + read() + * serial: set correct baud_base for Oxford Semiconductor Ltd EXSYS + EX-41092 Dual 16950 Serial adapter + * Add support for '8-port RS-232 MIC-3620 from advantech' + * mm: fix error case in mlock downgrade reversion + * elf core dump: fix get_user use + * ACPI: video: Fix reversed brightness behavior on ThinkPad SL series + * ipw2200: fix scanning while associated + * XFS: set b_error from bio error in xfs_buf_bio_end_io + * Revert USB: option: add Pantech cards + * USB: option: New mobile broadband modems to be supported + * USB: new id for ti_usb_3410_5052 driver + * USB: two more usb ids for ti_usb_3410_5052 + * USB: usb-storage: add Pentax to the bad-vendor list + * sata_via: Add VT8261 support + * nbd: do not allow two clients at the same time + * sctp: Fix another socket race during accept/peeloff + * Linux 2.6.28.5 + + -- Tim Gardner Mon, 09 Feb 2009 16:11:28 -0700 + +linux (2.6.28-7.20) jaunty; urgency=low + + [ Tim Gardner ] + + * SAUCE: Input: atkbd - Samsung NC10 key repeat fix + + [ Upstream Kernel Changes ] + + * Manually revert "mlock: downgrade mmap sem while populating mlocked + regions" + * xen: make sysfs files behave as their names suggest + * sata_mv: fix 8-port timeouts on 508x/6081 chips + * m68knommu: set NO_DMA + * PCI/MSI: bugfix/utilize for msi_capability_init() + * x86: use early clobbers in usercopy*.c + * netfilter: ctnetlink: fix scheduling while atomic + * orinoco: move kmalloc(..., GFP_KERNEL) outside spinlock in + orinoco_ioctl_set_genie + * fbdev/atyfb: Fix DSP config on some PowerMacs & PowerBooks + * kmalloc: return NULL instead of link failure + * sata_nv: rename nv_nf2_hardreset() + * sata_nv: fix MCP5x reset + * sata_nv: ck804 has borked hardreset too + * Fix memory corruption in console selection + * Add enable_ms to jsm driver + * nfsd: only set file_lock.fl_lmops in nfsd4_lockt if a stateowner is + found + * nfsd: Ensure nfsv4 calls the underlying filesystem on LOCKT + * iwlwifi: fix rs_get_rate WARN_ON() + * p54: fix lm87 checksum endianness + * p54: fix p54_read_eeprom to cope with tx_hdr_len + * p54usb: rewriting rx/tx routines to make use of usb_anchor's facilities + * minstrel: fix warning if lowest supported rate index is not 0 + * PCI: irq and pci_ids patch for Intel Tigerpoint DeviceIDs + * cpuidle: Add decaying history logic to menu idle predictor + * ACPI: Avoid array address overflow when _CST MWAIT hint bits are set + * video: always update the brightness when poking "brightness" + * Newly inserted battery might differ from one just removed, so update of + battery info fields is required. + * ACPI: Do not modify SCI_EN directly + * dlm: initialize file_lock struct in GETLK before copying conflicting + lock + * sata_mv: Fix chip type for Hightpoint RocketRaid 1740/1742 + * ACPICA: Allow multiple backslash prefix in namepaths + * Linux 2.6.28.4 + + -- Tim Gardner Sat, 07 Feb 2009 18:53:42 -0700 + +linux (2.6.28-7.19) jaunty; urgency=low + + * Fix missing modules FTBS + + -- Tim Gardner Thu, 05 Feb 2009 15:28:15 -0700 + +linux (2.6.28-7.18) jaunty; urgency=low + + [ Alok Kataria ] + + * SAUCE: (drop after 2.6.29) x86: add a synthetic TSC_RELIABLE feature + bit + - LP: #319945 + * SAUCE: (drop after 2.6.29) x86: add X86_FEATURE_HYPERVISOR feature bit + - LP: #319945 + * SAUCE: (drop after 2.6.29) x86: Hypervisor detection and get tsc_freq + from hypervisor + - LP: #319945 + * SAUCE: (drop after 2.6.29) x86: Add a synthetic TSC_RELIABLE feature + bit. + - LP: #319945 + * SAUCE: (drop after 2.6.29) x86: Skip verification by the watchdog for + TSC clocksource. + - LP: #319945 + * SAUCE: (drop after 2.6.29) x86: VMware: Fix vmware_get_tsc code + - LP: #319945 + * SAUCE: (drop after 2.6.29) x86: vmware: look for DMI string in the + product serial key + - LP: #319945 + + [ Andy Whitcroft ] + + * SAUCE: toshiba_acpi -- pull in current -dev version of driver + - LP: #269831 + * SAUCE: toshiba_acpi -- add acpi hotkey kernel thread + - LP: #269831 + * move toshiba laptops back from tlsup to toshiba_acpi + - LP: #269831 + + [ Aneesh Kumar K.V ] + + * SAUCE: (revert before 2.6.28.y update) ext4: Fix the delalloc + writepages to allocate blocks at the right offset. + * SAUCE: (revert before 2.6.28.y update) ext4: avoid ext4_error when + mounting a fs with a single bg + * SAUCE: (revert before 2.6.28.y update) ext4: Don't overwrite + allocation_context ac_status + * SAUCE: (revert before 2.6.28.y update) ext4: Add blocks added during + resize to bitmap + * SAUCE: (revert before 2.6.28.y update) ext4: Use + EXT4_GROUP_INFO_NEED_INIT_BIT during resize + * SAUCE: (revert before 2.6.28.y update) ext4: cleanup mballoc header + files + * SAUCE: (revert before 2.6.28.y update) ext4: don't use blocks freed but + not yet committed in buddy cache init + * SAUCE: (revert before 2.6.28.y update) ext4: Fix race between + read_block_bitmap() and mark_diskspace_used() + * SAUCE: (revert before 2.6.28.y update) ext4: Fix the race between + read_inode_bitmap() and ext4_new_inode() + * SAUCE: (revert before 2.6.28.y update) ext4: Use new buffer_head flag + to check uninit group bitmaps initialization + * SAUCE: (revert before 2.6.28.y update) ext4: mark the blocks/inode + bitmap beyond end of group as used + * SAUCE: (revert before 2.6.28.y update) ext4: Don't allow new groups to + be added during block allocation + * SAUCE: (revert before 2.6.28.y update) ext4: Init the complete page + while building buddy cache + * SAUCE: (revert before 2.6.28.y update) ext4: Fix s_dirty_blocks_counter + if block allocation failed with nodelalloc + + [ Hannes Eder ] + + * SAUCE: (drop after 2.6.29) x86: vmware - fix sparse warnings + - LP: #319945 + + [ Luke Yelavich ] + + * hid modules have hyphens instead of underscores in their names + + [ Mark Fasheh ] + + * SAUCE: (revert before 2.6.28.y update) jbd2: Add BH_JBDPrivateStart + + [ Theodore Ts'o ] + + * SAUCE: (revert before 2.6.28.y update) ext4: Add support for non-native + signed/unsigned htree hash algorithms + * SAUCE: (revert before 2.6.28.y update) ext4: tone down + ext4_da_writepages warnings + * SAUCE: (revert before 2.6.28.y update) jbd2: Add barrier not supported + test to journal_wait_on_commit_record + * SAUCE: (revert before 2.6.28.y update) ext4: Add sanity checks for the + superblock before mounting the filesystem + * SAUCE: (revert before 2.6.28.y update) ext4: only use i_size_high for + regular files + * SAUCE: (revert before 2.6.28.y update) ext4: Add sanity check to + make_indexed_dir + * SAUCE: (revert before 2.6.28.y update) jbd2: On a __journal_expect() + assertion failure printk "JBD2", not "EXT3-fs" + * SAUCE: (revert before 2.6.28.y update) ext4: Initialize the new group + descriptor when resizing the filesystem + + [ Tyler Hicks ] + + * SAUCE: (drop after 2.6.28) [eCryptfs] Regression in unencrypted + filename symlinks + - LP: #322532 + + [ Upstream Kernel Changes ] + + * Input: atkbd - broaden the Dell DMI signatures + - LP: #261721 + * ti_usb_3410_5052: support alternate firmware + * ath5k: fix mesh point operation + * mac80211: decrement ref count to netdev after launching mesh discovery + * inotify: clean up inotify_read and fix locking problems + * fuse: destroy bdi on umount + * fuse: fix missing fput on error + * fuse: fix NULL deref in fuse_file_alloc() + * x86, mm: fix pte_free() + * klist.c: bit 0 in pointer can't be used as flag + * sysfs: fix problems with binary files + * x86: fix page attribute corruption with cpa() + * USB: fix toggle mismatch in disable_endpoint paths + * sound: virtuoso: enable UART on Xonar HDAV1.3 + * USB: usbmon: Implement compat_ioctl + * USB: fix char-device disconnect handling + * USB: storage: add unusual devs entry + * alpha: nautilus - fix compile failure with gcc-4.3 + * alpha: fix vmalloc breakage + * resources: skip sanity check of busy resources + * rtl8187: Add termination packet to prevent stall + * it821x: Add ultra_mask quirk for Vortex86SX + * libata: pata_via: support VX855, future chips whose IDE controller use + 0x0571 + * serial_8250: support for Sealevel Systems Model 7803 COMM+8 + * drm: stash AGP include under the do-we-have-AGP ifdef + * Fix OOPS in mmap_region() when merging adjacent VM_LOCKED file segments + * bnx2x: Block nvram access when the device is inactive + * ext3: Add sanity check to make_indexed_dir + * rtl8187: Fix error in setting OFDM power settings for RTL8187L + * epoll: drop max_user_instances and rely only on max_user_watches + * gpiolib: fix request related issue + * sgi-xpc: Remove NULL pointer dereference. + * sgi-xpc: ensure flags are updated before bte_copy + * include/linux: Add bsg.h to the Kernel exported headers + * ALSA: hda - Fix PCM reference NID for STAC/IDT analog outputs + * ALSA: hda - add another MacBook Pro 4, 1 subsystem ID + * ALSA: hda - Add quirk for HP DV6700 laptop + * crypto: authenc - Fix zero-length IV crash + * crypto: ccm - Fix handling of null assoc data + * x86, pat: fix reserve_memtype() for legacy 1MB range + * x86, pat: fix PTE corruption issue while mapping RAM using /dev/mem + * PCI hotplug: fix lock imbalance in pciehp + * dmaengine: fix dependency chaining + * NET: net_namespace, fix lock imbalance + * relay: fix lock imbalance in relay_late_setup_files + * Linux 2.6.28.3 + * ALSA: Enable SPDIF output on ALC655 + * ALSA: hda - Add ASUS V1Sn support + * ALSA: hda - support detecting HD Audio devices with PCI class code + * ALSA: hda: alc883 model for ASUS P5Q-EM boards + * ALSA: hda - Add quirk for MSI 7260 mobo + * ALSA: hda - Add quirk for Sony VAIO VGN-SR19XN + * ALSA: oxygen: add Claro halo support + * ALSA: hda - Add a new function to seek for a codec ID + * ALSA: patch_sigmatel: Add missing Gateway entries and autodetection + * ALSA: hda - More fixes on Gateway entries + * ALSA: hda - Add MCP67 HDMI support + * ALSA: hda - fix name for ALC1200 + * LSA: hda - Add HP Acacia detection + * ALSA: hda - Add quirk for HP 2230s + * ALSA: hda - Add quirk for Dell Inspiron Mini9 + * ALSA: hda - add support for Intel DX58SO board + * ALSA: hda - Fix silent headphone output on Panasonic CF-74 + * ALSA: USB quirk for Logitech Quickcam Pro 9000 name + * ALSA: hda - add quirks for some 82801H variants to use ALC883_MITAC + + [ Yasunori Goto ] + + * SAUCE: (revert before 2.6.28.y update) ext4: Widen type of + ext4_sb_info.s_mb_maxs[] + + -- Tim Gardner Mon, 02 Feb 2009 23:07:13 -0700 + +linux (2.6.28-6.17) jaunty; urgency=low + + [ Amit Kucheria ] + + * Updating configs: ARMEL/versatile + + -- Amit Kucheria Fri, 30 Jan 2009 13:36:59 +0200 + +linux (2.6.28-6.16) jaunty; urgency=low + + [ Luke Yelavich ] + + * Add hid quirks to input-modules udeb + + [ Tim Gardner ] + + * Revert "[arm] Fix kexec on ARM by properly calling the relocation + function". This patch was deemed 'bogus' by Russell King on the + ARM mailing list. + + [ Upstream Kernel Changes ] + + * PCI: keep ASPM link state consistent throughout PCIe hierarchy + * security: introduce missing kfree + * rt2x00: add USB ID for the Linksys WUSB200. + * p54usb: Add USB ID for Thomson Speedtouch 121g + * lib/idr.c: use kmem_cache_zalloc() for the idr_layer cache + * sgi-xp: eliminate false detection of no heartbeat + * sched: fix update_min_vruntime + * IA64: Turn on CONFIG_HAVE_UNSTABLE_CLOCK + * sound: virtuoso: do not overwrite EEPROM on Xonar D2/D2X + * ALSA: hda - Add quirk for another HP dv5 + * ALSA: hda - Fix HP dv5 mic input + * ALSA: hda - Don't reset HP pinctl in patch_sigmatel.c + * ALSA: hda - make laptop-eapd model back for AD1986A + * drivers/net/irda/irda-usb.c: fix buffer overflow + * usb-storage: add last-sector hacks + * usb-storage: set CAPACITY_HEURISTICS flag for bad vendors + * pkt_sched: sch_htb: Fix deadlock in hrtimers triggered by HTB + * ipv6: Fix fib6_dump_table walker leak + * sctp: Avoid memory overflow while FWD-TSN chunk is received with bad + stream ID + * pkt_sched: cls_u32: Fix locking in u32_change() + * r6040: fix wrong logic in mdio code + * r6040: save and restore MIER correctly in the interrupt routine + * r6040: bump release number to 0.19 + * tcp: don't mask EOF and socket errors on nonblocking splice receive + * p54usb: fix traffic stalls / packet drop + * netfilter: x_tables: fix match/target revision lookup + * netfilter: ebtables: fix inversion in match code + * netfilter: nf_conntrack: fix ICMP/ICMPv6 timeout sysctls on big-endian + * dell_rbu: use scnprintf() instead of less secure sprintf() + * powerpc: is_hugepage_only_range() must account for both 4kB and 64kB + slices + * hwmon: (abituguru3) Fix CONFIG_DMI=n fallback to probe + * mm: write_cache_pages cyclic fix + * mm: write_cache_pages early loop termination + * mm: write_cache_pages writepage error fix + * mm: write_cache_pages integrity fix + * mm: write_cache_pages cleanups + * mm: write_cache_pages optimise page cleaning + * mm: write_cache_pages terminate quickly + * mm: write_cache_pages more terminate quickly + * mm: do_sync_mapping_range integrity fix + * mm: direct IO starvation improvement + * fs: remove WB_SYNC_HOLD + * fs: sync_sb_inodes fix + * fs: sys_sync fix + * Linux 2.6.28.2 + + -- Tim Gardner Sun, 25 Jan 2009 13:36:16 -0700 + +linux (2.6.28-5.15) jaunty; urgency=low + + [ Tim Gardner ] + + * Revert "Enabled CONFIG_PID_NS=y for i386/amd64" + Somehow this commit also reverted the 7 prior commits (which is bad). + * Enabled CONFIG_PID_NS=y for i386/amd64 (version 2) + + -- Tim Gardner Thu, 22 Jan 2009 13:48:34 -0700 + +linux (2.6.28-5.14) jaunty; urgency=low + + [ Ben Collins ] + + * lirc_gpio: Forward ported to current kernel (jaunty) + * configs: Enable LIRC_GPIO on 64-bit/32-bit x86 + - LP: #298791 + + [ Jeff Layton ] + + * SAUCE: cifs: make sure we allocate enough storage for socket address + - LP: #318565 + + [ Tim Gardner ] + + * check-abi: Return success when ABI skip is requested and no ABI files exist. + This ought to fix the armel FTBS. + + -- Tim Gardner Thu, 22 Jan 2009 06:42:49 -0700 + +linux (2.6.28-5.13) jaunty; urgency=low + + [ Andy Whitcroft ] + + * Revert "SAUCE: don't use buggy _BCL/_BCM/_BQC for backlight control" + + [ Tim Gardner ] + + * Fix udeb generation breakage caused by the previous armel versatile + flavour config update. + + -- Tim Gardner Wed, 21 Jan 2009 12:38:35 -0700 + +linux (2.6.28-5.12) jaunty; urgency=low + + [ Ante ] + + * Update drbd to 8.3.0 + + [ Dave Airlie ] + + * i915/drm: provide compat defines for userspace for certain struct + + [ Eric Anholt ] + + * drm/i915: Don't double-unpin buffers if we take a signal in + * drm/i915: Don't complain when interrupted while pinning in execbuffers. + * drm/i915: Don't allow objects to get bound while VT switched. + + [ Jani Monoses ] + + * Fix webcam having USB ID 0ac8:303b + - LP: #292086 + + [ Jesse Barnes ] + + * drm/i915: set vblank enabled flag correctly across IRQ + * drm/i915: don't enable vblanks on disabled pipes + + [ Michael Casadevall ] + + * [arm] Fix kexec on ARM by properly calling the relocation function + + [ Tim Gardner ] + + * Enabled CONFIG_PID_NS=y for i386/amd64 + * SAUCE: Increase ATA_TMOUT_PMP_SRST_WAIT to 5 seconds. + - LP: #318978 + * Update armel versatile config + - LP: #314789 + * Enabled CONFIG_RT2860=m for i386/amd64 + * Enabled CONFIG_RT2870=m for i386/amd64 + + [ Upstream Kernel Changes ] + + * Input: atkbd - add keyboard quirk for HP Pavilion ZV6100 laptop + - LP: #291878 + * ALSA: hda - Add quirk for another HP dv7 + * ALSA: hda - Add quirk for HP6730B laptop + * ALSA: caiaq - Fix Oops with MIDI + * ALSA: hda - Fix typos for AD1882 codecs + * x86: fix intel x86_64 llc_shared_map/cpu_llc_id anomolies + * x86: default to SWIOTLB=y on x86_64 + * CIFS: make sure that DFS pathnames are properly formed + * ring-buffer: prevent false positive warning + * ring-buffer: fix dangling commit race + * iwlwifi: use GFP_KERNEL to allocate Rx SKB memory + * tx493[89]ide: Fix length for __ide_flush_dcache_range + * tx4939ide: Do not use zero count PRD entry + * SCSI: eata: fix the data buffer accessors conversion regression + * USB: emi26: fix oops on load + * x86, UV: remove erroneous BAU initialization + * x86: fix incorrect __read_mostly on _boot_cpu_pda + * vmalloc.c: fix flushing in vmap_page_range() + * fs: symlink write_begin allocation context fix + * cgroups: fix a race between cgroup_clone and umount + * dm raid1: fix error count + * dm log: fix dm_io_client leak on error paths + * minix: fix add link's wrong position calculation + * md: fix bitmap-on-external-file bug. + * sched_clock: prevent scd->clock from moving backwards, take #2 + * devices cgroup: allow mkfifo + * SCSI: aha152x_cs: Fix regression that keeps driver from using shared + interrupts + * ioat: fix self test for multi-channel case + * USB: isp1760: use a specific PLX bridge instead of any bdridge + * USB: isp1760: Fix probe in PCI glue code + * USB: unusual_devs.h additions for Pentax K10D + * inotify: fix type errors in interfaces + * Move compat system call declarations to compat header file + * Convert all system calls to return a long + * Rename old_readdir to sys_old_readdir + * Remove __attribute__((weak)) from sys_pipe/sys_pipe2 + * Make sys_pselect7 static + * Make sys_syslog a conditional system call + * System call wrapper infrastructure + * powerpc: Enable syscall wrappers for 64-bit + * s390: enable system call wrappers + * System call wrapper special cases + * System call wrappers part 01 + * System call wrappers part 02 + * System call wrappers part 03 + * System call wrappers part 04 + * System call wrappers part 05 + * System call wrappers part 06 + * System call wrappers part 07 + * System call wrappers part 08 + * System call wrappers part 09 + * System call wrappers part 10 + * System call wrappers part 11 + * System call wrappers part 12 + * System call wrappers part 13 + * System call wrappers part 14 + * System call wrappers part 15 + * System call wrappers part 16 + * System call wrappers part 17 + * System call wrappers part 18 + * System call wrappers part 19 + * System call wrappers part 20 + * System call wrappers part 21 + * System call wrappers part 22 + * System call wrappers part 23 + * System call wrappers part 24 + * System call wrappers part 25 + * System call wrappers part 26 + * System call wrappers part 27 + * System call wrappers part 28 + * System call wrappers part 29 + * System call wrappers part 30 + * System call wrappers part 31 + * System call wrappers part 32 + * System call wrappers part 33 + * s390 specific system call wrappers + * x86: fix RIP printout in early_idt_handler + * Fix timeouts in sys_pselect7 + * USB: another unusual_devs entry for another bad Argosy storage device + * USB: storage: extend unusual range for 067b:3507 + * USB: storage: recognizing and enabling Nokia 5200 cell phoes + * HID: fix error condition propagation in hid-sony driver + * fix switch_names() breakage in short-to-short case + * nfs: remove redundant tests on reading new pages + * eCryptfs: check readlink result was not an error before using it + * mvsas: increase port type detection delay to suit Seagate's 10k6 drive ST3450856SS 0003 + * x86: avoid theoretical vmalloc fault loop + * ath9k: enable RXing of beacons on STA/IBSS + * mm lockless pagecache barrier fix + * powerpc: Disable Collaborative Memory Manager for kdump + * ibmvfc: Delay NPIV login retry and add retries + * ibmvfc: Improve async event handling + * getrusage: RUSAGE_THREAD should return ru_utime and ru_stime + * ath5k: ignore the return value of ath5k_hw_noise_floor_calibration + * mm: fix assertion + * XFS: truncate readdir offsets to signed 32 bit values + * Linux 2.6.28.1 + * eCryptfs: Filename Encryption: Tag 70 packets + * eCryptfs: Filename Encryption: Header updates + * eCryptfs: Filename Encryption: Encoding and encryption functions + * eCryptfs: Filename Encryption: filldir, lookup, and readlink + * eCryptfs: Filename Encryption: mount option + * eCryptfs: Replace %Z with %z + * eCryptfs: Fix data types (int/size_t) + * eCryptfs: kerneldoc for ecryptfs_parse_tag_70_packet() + * eCryptfs: Clean up ecryptfs_decode_from_filename() + * fs/ecryptfs/inode.c: cleanup kerneldoc + * staging-p80211: Kill directly reference of netdev->priv + * staging-slicoss: Kill directly reference of netdev->priv + * staging-winbond: Kill directly reference of netdev->priv + * Staging: go7007: fixes due to video_usercopy api change + * Staging: go7007: fixes due v4l2_file_operations api change + * staging: correct dubious use of !x & y + * Staging: w35und: make wb35_probe() and wb35_disconnect() funtions static + * Staging: w35und: remove unused wb35_open() and wb35_close() functions + * Staging: w35und: use msleep() and udelay() + * Staging: w35und: remove the no-op pa_stall_execution macro + * Staging: w35und: purb typedef removal + * Staging: w35und: reg queue struct typedef removal + * Staging: w35und: wb35reg struct typedef removal + * Staging: w35und: padapter struct typedef removal + * Staging: w35und: merge wblinux struct to adapter + * Staging: w35und: wb35_probe() cleanup + * Staging: w35und: remove usb_submit_urb wrapper function + * Staging: w35und: remove usb_alloc_urb wrapper function + * w35und: remove dead code from wbusb_f.h + * Staging: w35und: remove true/false boolean macros + * Staging: w35und: OS_MEMORY_ALLOC wrapper removal + * Staging: w35und: usb_put_dev() is missing from wb35_disconnect() + * Staging: w35und: remove macro magic from MLME_GetNextPacket() + * Staging: w35und: plug memory leak in wbsoft_tx() + * Staging: w35und: move supported band initialization out of wb35_probe() + * Staging: w35und: remove timer wrappers + * Staging: w35und: remove atomic op wrappers + * Staging: w35und: remove memcpy/memcmp wrappers + * Staging: w35und: remove abs() and BIT() macros + * Staging: w35und: remove unused macros from common.h + * Staging: w35und: remove unused link status code + * Staging: w35und: #include cleanup + * Staging: w35und: remove some dead code + * Staging: w35und: move source files to one directory + * Staging: w35und: move struct wbsoft_priv to core.h and use it + * Staging: w35und: remove ->adapter from struct _HW_DATA_T + * Staging: w35und: clean up adapter.h a bit + * Staging: w35und: merge struct wb35_adapter to struct wbsoft_priv + * Staging: w35und: remove global struct ieee80211_hw + * Staging: w35und: inline DRIVER_AUTHOR and DRIVER_DESC macros + * Staging: w35und: clean up wblinux.c a bit + * Staging: w35und: remove unused ->ShutDowned member from struct + LOCAL_PARA + * Staging: w35und: move global wbsoft_enabled to struct wbsoft_priv + * Staging: w35und: move packet_came() to wb35rx.c + * Staging: w35und: remove ->skb_array from struct wbsoft_priv + * Staging: w35und: remove ->shutdown from struct wbsoft_priv + * Staging: w35und: make functions local to mds.c static + * Staging: w35und: make functions local to mlmetxrx.c static + * Staging: w35und: remove dead code from mto.c + * Staging: w35und: make functions local to wb35rx.c static + * Staging: w35und: make functions local to wb35tx.c static + * Staging: w35und: remove dead code from wbhal.c + * Staging: w35und: remove rxisr.c as dead code + * Staging: w35und: fix Kconfig + * Staging: w35und: fix config build warnings + * Staging: wlan-ng: Remove PCI/PLX/PCMCIA files. + * Staging: wlan-ng: Update Help text to mention prism3 devices. + * Staging: wlan-ng: Delete PCI/PLX/PCMCIA-specific code. + * Staging: wlan-ng: Make wlan-ng use WEXT mode by default. + * Staging: wlan-ng: Eliminate more <2.6 kernel support. + * Staging: wlan-ng: Eliminate all backwards-compatibility for <2.6.13 kernels. + * Staging: wlan-ng: Eliminate a boatload of tertiaryAP-only code. + * Staging: wlan-ng: Remove AP-only code from MLME functions. + * Staging: wlan-ng: Get rid of the MTU tests in the rx conversion path. + * Staging: wlan-ng: Eliminate one more rx mtu test. + * Staging: wlan-ng: Eliminate local 'version.h' + * Staging: wlan-ng: Eliminate usage of procfs. + * Staging: wlan-ng: Use standard kernel integer (u32/s32/etc) types. + * Staging: wlan-ng: Eliminate all backwards-compatible kernel code. + * Staging: wlan-ng: Wireless Extension support is mandatory. + * Staging: wlan-ng: use WIRELESS_EXT, not CONFIG_WIRELESS_EXT + * Staging: wlan-ng: Delete a large pile of now-unused code. + * Staging: wlan-ng: Delete a pile of unused mibs. And fix WEXT SET_TXPOWER. + * Staging: wlan-ng: Consolidate wlan-ng into a single module. + * Staging: wlan-ng: Purge all MIBs not used internally. + * Staging: wlan-ng: p80211netdev.c fix netdev alloc to prevent oops on device start + * Staging: wlan-ng: prism2_usb.c always enable the card in probe_usb + * Staging: wlan-ng: hfa384x_usb.c use newest version of 384x_drvr_start + * Staging: wlan-ng: p80211wext.c add latest changes & remove extra nulls from wext_handlers + * Staging: wlan-ng: p80211wext don't set default key id twice + * Staging: wlan-ng: hfa384x_usbin_callback: check for hardware removed + * Staging: wlan-ng: p80211conv.c copy code from wlan-ng-devel branch to not drop packets + * Staging: wlan-ng: remove unused #include + * Staging: wlan-ng: p80211wext.c: use ARRAY_SIZE + * Staging: wlan-ng: fix compiler warnings + * Staging: wlan-ng: skb_p80211_to_ether() - payload_length is unsigned, check before subtraction + * Staging: at76_usb: update drivers/staging/at76_usb w/ mac80211 port + * Staging: at76_usb: fix build breakage + * Staging: at76_usb: remove compiler warnings + * Staging: at76_usb: fix up all remaining checkpatch.pl warnings + * Staging: at76_usb: cleanup dma on stack issues + * Staging: poch: Block size bug fix + * Staging: poch: Update TODO list + * Staging: poch: Correct pages from bytes. + * Staging: poch: minor fixes + * Staging: poch: Fix build warnings + * Staging: poch: Rx control register init + * Staging: poch: Fix user space protocol syncing + * Staging: poch: Fine grained locking + * Staging: sxg: remove typedefs + * Staging: sxg: break the build in a cleaner way when !x86 + * Staging: sxg: update README + * staging: struct device - replace bus_id with dev_name(), dev_set_name() + * Staging: echo: remove typedefs + * Staging: echo: Lindent drivers/staging/echo + * Staging: go7007: saa7134 updates + * Staging: go7007: add sensoray 2250/2251 support + * Staging: go7007: Convert driver to use video_ioctl2 + * Staging: go7007: annotate code pointers + * Staging: go7007: fix minor build warnings + * Staging: go7007: small cleanup + * Staging: go7007: add some more v4l2 ioctls + * Staging: et131x: Cleanup et131x_debug.h defines + * Staging: et131x: fix build failure + * Staging: et131x: remove unused variable in et1310_tx.c + * Staging: usbip: cleanup kerneldoc + * Staging: slicoss: use kzalloc + * Staging: slicoss: use correct type for memory allcations + * Staging: slicoss: use request_firmware + * Staging: add agnx wireless driver + * Staging: agnx: fix build errors due to ssid removal + * Staging: agnx: fix build errors due to rate control API changes + * Staging: agnx: fix build warnings + * Staging: add otus Atheros wireless network driver + * Staging: otus: fix netdev->priv usage + * Staging: otus: fix name clash + * Staging: otus: fix urb callback function type + * Staging: otus: remove dependence on kernel version + * Staging: add rt2860 wireless driver + * Staging: rt2860: disable root hack for reading files + * Staging: rt2860: fix up netdev->priv usage + * Staging: rt2860: use standard bit-reverse function + * Staging: rt2860: Fix minor compiler warnings + * Staging: rt2860: enable WPA_SUPPLICANT support + * Staging: Add ServerEngines benet 10Gb ethernet driver + * Staging: benet: fix netif api breakage + * Staging: benet: fix up netdev->priv change + * Staging: benet: build is broken unless CONFIG_NETPOLL is enabled + * Staging: benet: patch to remove subdirectories + * Staging: benet: fix build errors when CONFIG_NETPOLL is off + * Staging: benet: fix build error. + * Staging: benet: patch to use offsetof() instead of AMAP_BYTE_OFFSET() + * Staging: benet: fix problems reported by checkpatch + * Staging: benet: cleanup a check while posting rx buffers + * Staging: add comedi core + * Staging: comedi: fix up a lot of checkpatch.pl warnings + * Staging: comedi: fix checkpatch.pl errors in comedi_fops.c + * Staging: comedi: fix build error in comedilib.h + * Staging: comedi: add kcomedilib to the tree + * Staging: comedi: set up infrastructure for individual drivers + * Staging: comedi: add local copy of interrupt.h + * Staging: comedi: add pci and usb wrapper header files + * Staging: comedi: comedi driver common function module + * Staging: comedi: add mite comedi pci driver + * Staging: comedi: add usb usbdux driver + * Staging: comedi: add usb usbduxfast driver + * Staging: comedi: add usb dt9812 driver + * Staging: comedi: add comedi_bond driver + * Staging: comedi: add comedi_test driver + * Staging: comedi: add comedi_parport driver + * Staging: comedi: dt9812: fix up a lot of coding style issues + * Staging: comedi: dt9812: remove dt9812.h + * Staging: comedi: dt9812: remove typedefs + * Staging: comedi: dt9812: fix sparse warnings + * Staging: comedi: usbdux: remove kernel version checks + * Staging: comedi: usbdux: code style cleanups + * Staging: comedi: usbdux: remove // comments + * Staging: comedi: usbdux: fix up printk calls + * Staging: comedi: usbdux: remove checkpatch.pl warnings + * Staging: comedi: usbdux: remove typedef + * Staging: comedi: usbdux: remove comedi usb wrappers + * Staging: comedi: usbduxfast: remove comedi usb wrappers + * Staging: comedi: dt9812: remove #ifdef that is not needed + * Staging: comedi: remove usb wrappers + * Staging: comedi: remove PCI wrappers + * Staging: comedi: add icp_multi driver + * Staging: comedi: add me4000 driver + * Staging: comedi: fix checkpatch.pl issues in comedi_bond.c + * Staging: comedi: fix checkpatch.pl issues in comedi_fc.c + * Staging: comedi: remove typedefs from comedi_bond.c + * Staging: comedi: fix sparse issues in comedi_bond.c + * Staging: comedi: fix checkpatch.pl issues in comedi_test.c + * Staging: comedi: fix sparse issues in comedi_test.c + * Staging: comedi: remove typedefs from comedi_test.c + * Staging: comedi: fix comedi_parport.c checkpatch.pl issues. + * Staging: comedi: fix comedi_fc.h checkpatch.pl issues. + * Staging: comedi: fix comedi_pci.h checkpatch.pl issues. + * Staging: comedi: comedi_pci.h: remove unneeded wrapper + * Staging: comedi: comedi_pci.h: remove comedi_pci_enable_no_regions + * Staging: comedi: comedi_pci.h: remove comedi_pci_disable_no_regions + * Staging: comedi: add s626 driver + * Staging: comedi: add rtd520 driver + * Staging: comedi: add me_daq driver + * Staging: comedi: me_daq: fix checkpatch.pl issues + * Staging: comedi: me_daq: remove typedefs + * Staging: comedi: me_daq: fix sparse issues + * Staging: comedi: fix checkpatch.pl warning in interrupt.h + * Staging: comedi: fix build if CONFIG_PROC_FS is not set + * Staging: add asus_oled driver + * Staging: asus_oled: fix build dependancy + * Staging: Add the Meilhaus ME-IDS driver package + * Staging: meilhaus: fix __symbol_get problems + * Staging: add lcd-panel driver + * Staging: panel: major checkpatch cleanup + * Staging: panel: remove ifdefs and code for pre-2.6 kernels + * Staging: panel: remove support for smartcards + * Staging: add Driver for Altera PCI Express Chaining DMA reference design + * Staging: add rtl8187se driver + * Staging: rtl8187se: remove unneeded files + * Staging: rtl8187se: make the built module be the proper name + * Staging: rtl8187se: remove duplicate pci ids + * Staging: me4000: switch to list_for_each*() + * Staging: usbip: switch to list_for_each_entry() + * Staging: add princeton instruments usb camera driver + * Staging: add mimio xi driver + * Staging: add rt2870 wireless driver + * Staging: rt2870: disable root hack for reading files + * Staging: rt2870: fix up netdev->priv usage + * Staging: add frontier tranzport and alphatrack drivers + * Staging: frontier: remove unused alphatrack_sysfs.c file + * Staging: frontier: fix compiler warnings + * Staging: add epl stack + * Staging: epl: run Lindent on all kernel/*.h files + * Staging: epl: run Lindent on all user/*.h files + * Staging: epl: run Lindent on *.h files + * Staging: epl: run Lindent on *.c files + * Staging: epl: hr timers all run in hard irq context now + * Staging: epl: fix netdev->priv b0rkage + * Staging: add android framework + * Staging: android: add binder driver + * Staging: android: binder: Fix gcc warnings about improper format specifiers for size_t in printk + * staging: android: binder: Fix use of euid + * Staging: android: add logging driver + * Staging: android: add ram_console driver + * Staging: android: add timed_gpio driver + * Staging: android: timed_gpio: Rename android_timed_gpio to timed_gpio + * Staging: android: remove dummy android.c driver + * Staging: android: add lowmemorykiller driver + * Staging: android: binder: fix build errors + * staging: __FUNCTION__ is gcc-specific, use __func__ + * V4L/DVB (10176a): Switch remaining clear_user_page users over to + clear_user_highpage + + [ Zhenyu Wang ] + + * agp/intel: add support for G41 chipset + + -- Tim Gardner Sun, 18 Jan 2009 20:22:54 -0700 + +linux (2.6.28-4.11) jaunty; urgency=low + + [ Mario Limonciello ] + + * SAUCE: Enable HDMI audio codec on Studio XPS 1340 + - LP: #309508 + + [ Tim Gardner ] + + * Fix armel d-i FTBSs + + [ Upstream Kernel Changes ] + + * USB: re-enable interface after driver unbinds + + -- Tim Gardner Tue, 13 Jan 2009 16:33:08 -0700 + +linux (2.6.28-4.10) jaunty; urgency=low + + [ Andy Whitcroft ] + + * update kernel bootloader recommends: to prefer grub + - LP: #314004 + * SAUCE: don't use buggy _BCL/_BCM/_BQC for backlight control + - LP: #311716 + * SAUCE: test-suspend -- add the suspend test scripts + - LP: #316419 + + [ Colin Watson ] + + * Enable udebs for armel + + [ Tim Gardner ] + + * SAUCE: Dell laptop digital mic does not work, PCI 1028:0271 + - LP: #309508 + * Enable CIFS_XATTR=y and CONFIG_CIFS_POSIX=y + - LP: #220658 + + -- Tim Gardner Thu, 08 Jan 2009 10:38:22 -0700 + +linux (2.6.28-4.9) jaunty; urgency=low + + [ Tim Gardner ] + + * Restore DM_CRYPT, AES, ECB, and CBC as modules. This fixes + some installer issues with encrypted /home and Private directories. + * Take one more stab at building armel without module or ABI errors. + + -- Tim Gardner Tue, 06 Jan 2009 08:38:23 -0700 + +linux (2.6.28-4.8) jaunty; urgency=low + + * Fix i386/amd64 FTBS by ignoring all module and ABI changes, + not something you would normally do, but I'm sure the ABI + has not changed. This will probably also allow the ARM builds to complete. + + -- Tim Gardner Mon, 05 Jan 2009 14:42:58 -0700 + +linux (2.6.28-4.7) jaunty; urgency=low + + [ Tim Gardner ] + + * Enable CONFIG_ATH5K=m for i386/amd64 + - LP: #306719 + * Build all i386/amd64 AGP/DRM components as modules. + - LP: #312721 + * git commands are now installed outside the default $PATH + Use 'git CMD' instead of 'git-CMD'. + * Build in most PATA/SATA drivers. This should allow most i386/amd64 systems to boot + without an initramfs, though some support work is still required in initramfs-tools + and grub. + - LP: #311730 + + -- Tim Gardner Fri, 02 Jan 2009 07:33:09 -0700 + +linux (2.6.28-4.6) jaunty; urgency=low + + [ Tim Gardner ] + + * Enable CONFIG_X86_E_POWERSAVER=m for i386 generic + - LP: #237405 + * Build i386 AGP drivers as modules + - LP: #312721 + * Build i386 DRM as a module + - LP: #312721 + + [ Upstream Kernel Changes ] + + * drm/i915: Add missing userland definitions for gem init/execbuffer. + - LP: #308387 + + -- Tim Gardner Mon, 29 Dec 2008 09:16:47 -0700 + +linux (2.6.28-4.5) jaunty; urgency=low + + [ Andy Whitcroft ] + + * clean up module dependancy information on package removal/purge + - LP: #300773 + + [ Tim Gardner ] + + * Update iscsitarget to 0.4.17 + * Build in ext{234} + * Build in Crypto modules AES, CBC, ECB + * Build in ACPI AC,BATTERY,BUTTON,FAN,PCI_SLOT,PROCESSOR,SBS,THERMAL,WMI + * Build in AGP intel,via,sis,ali,amd,amd64,efficeon,nvidia,sworks + * Build in ata,dev_dm,dev_loop,dev_md,dev_sd,dev_sr + * Build in BT l2cap,rfcomm,sco + * Reduce CONFIG_LEGACY_PTY_COUNT to 0 + * Build in CDROM_PKTCDVD and CHR_DEV_SG + * Build in CPU_FREQ + GOV_CONSERVATIVE,GOV_ONDEMAND,GOV_POWERSAVE,GOV_USERSPACE,STAT,TABLE + * Build in DM CRYPT,MIRROR,MULTIPATH,SNAPSHOT + * Build in DRM + * Build in HID + * Build in HOTPLUG PCI,PCIE + * Build in I2C + * Build in IEEE1394 OHCI1394 + * Build in INPUT EVDEV + * Build in IPV6 + * Build in MMC + * Build in PACKET + * Enable both IEEE1394 (Firewire) stacks as modules + - LP: #276463 + * Disable SUNRPC_REGISTER_V4 + - LP: #306016 + * Enable dm-raid4-5 + - LP: #309378 + * Build in PPP + * Build in RFKILL + * Build in USB SERIAL + + [ Upstream Kernel Changes ] + + * Rebased to v2.6.28 + + -- Tim Gardner Thu, 18 Dec 2008 21:18:44 -0700 + +linux (2.6.28-3.4) jaunty; urgency=low + + [ Tim Gardner ] + + * Build ecryptfs into the kernel + - LP: #302870 + * Deprecated gnbd + + [ Upstream Kernel Changes ] + + * Rebased to v2.6.28-rc8 + + -- Tim Gardner Wed, 10 Dec 2008 22:45:13 -0700 + +linux (2.6.28-2.3) jaunty; urgency=low + + [ Andy Whitcroft ] + + * update the templates so that we have spaces following the title line + + [ Tim Gardner ] + + * Add upload number to kernel version signature. This has the side effect + of renaming kernel packages back to the original way, e.g., without '-ub' + in the name. + + -- Tim Gardner Thu, 04 Dec 2008 12:18:31 -0700 + +linux (2.6.28-2.2) jaunty; urgency=low + + [ Andy Whitcroft ] + + * Revert "SAUCE: (no-up) version: Implement version_signature proc file." + * SAUCE: (no-up) version: Implement version_signature proc file. + * SAUCE: serial: RS485 ioctl structure uses __u32 include linux/types.h + - LP: #303711 + + [ Tim Gardner ] + + * UBUNTU: Removed CONFIG_DRM_VIA_CHROME9 since it is upstream. + * UBUNTU: Removed ubuntu/via_chrome9 + + [ Upstream Kernel Changes ] + + * Rebased to v2.6.28-rc7 + + -- Tim Gardner Tue, 02 Dec 2008 07:33:32 -0700 + +linux (2.6.28-1.1) jaunty; urgency=low + + [ Amit Kucheria ] + + * SAUCE: make fc transport removal of target configurable + * SAUCE: pm: Config option to disable handling of console during + suspend/resume + * SAUCE: Adds support for COMPAL JHL90 webcam + * Map armel to arm to all editconfigs to work correctly + * Add armel to getabis for completeness sake + * Add -ub to our versioning to allow kerneloops.org to identify us + + [ Andy Whitcroft ] + + * Fix Vcs-Git path for the kernel repository. + - LP: #296915 + + [ Ben Collins ] + + * SAUCE: Lower warning level of some PCI messages + - LP: #159241 + * SAUCE: input/mouse/alps: Do not call psmouse_reset() for alps + * SAUCE: tulip: Let dmfe handle davicom on non-sparc + * SAUCE: tulip: Define ULI PCI ID's + * SAUCE: (no-up) version: Implement version_signature proc file. + * SAUCE: (no-up) connector.h: Add idx/val for drbd + * SAUCE: (no-up) swap: Add notify_swap_entry_free callback for compcache + * SAUCE: drivers: Remove some duplicate device entries in various modules + * SAUCE: (no-up) [AppArmor] merge with upstream subversion r1291 + * SAUCE: (no-up) Enable ubuntu extra subdirectory + * SAUCE: (no-up) ACPI: initramfs DSDT override support + * ubuntu: Add drbd module + * ubuntu: Add iscsitarget module + * ubuntu: Add BOM for iscsitarget + * ubuntu: Add squashfs driver + * SAUCE: (no-up) Check for squashfs superblock in initramfs mounting. + * ubuntu: Add aufs module + * ubuntu: Added atl2 driver + * ubuntu: Added et131x driver + * ubuntu: Add dm-raid4-5 driver + * ubuntu: Add ndiswrapper driver + * ubuntu: Added ram backed compressed swap module (compcache) + * ubuntu: Add misc drivers from hardy lum + * ubuntu: Add heci driver 3.2.0.24 + * ubuntu: Add ov511 and bt-sco drivers + * ubuntu: Add acx, prism2_usb wireless drivers + * ubuntu: Add at76 driver to build + * ubuntu: Add fsam7400 sw kill switch driver + * ubuntu: Added qc-usb driver + * ubuntu: e1000e: Upgraded module to 0.4.1.7 + * ubuntu: Added rfkill drivers + * ubuntu: VIA - Add VIA DRM Chrome9 3D engine + * ubuntu: unionfs: Added v1.4 module from hardy + * ubuntu: Add LIRC driver + * ubuntu: Add GFS driver + * ubuntu: New tlsup driver for toshiba laptops + * SAUCE: (no-up) Export lookup_has for aufs + * SAUCE: (no-up) Modularize vesafb + * ubuntu: Config files + * Disable some modules that need porting to 2.6.28 + * ubuntu: Fixup headers creation to include arch/*/include + * ubuntu/module-check: Ignore comment lines + + [ Chuck Short ] + + * SAUCE: ata: blacklist FUJITSU MHW2160BH PL + + [ cking ] + + * SAUCE: Enable speedstep for sonoma processors. + + [ Colin Ian King ] + + * ubuntu: Add dm-loop + * SAUCE: cx88: Support Leadtek WinFast DTV2000 H version J. + * SAUCE: fix kernel oops in VirtualBox during paravirt patching + * SAUCE: qc-usb: Enable Logitech QuickCam Messenger + * SAUCE: appleir: Enable driver for new MacBook Pro + + [ Colin Watson ] + + * Enable configfs, fuse, jfs, reiserfs, and xfs for armel + * Extend debian/d-i/ modules handling to make armel easier to support + * Create udebs for armel + + [ Fabio M. Di Nitto ] + + * ubuntu: update GFS Cluster File System + + [ Kees Cook ] + + * SAUCE: AppArmor: update to upstream subversion r1302 + + [ Leann Ogasawara ] + + * Add automatic model setting for Samsung Q45 + * Add Dell Dimension 9200 reboot quirk + + [ Mackenzie Morgan ] + + * SAUCE: Add quirk for ASUS Z37E to make sound audible after resume + + [ Matthew Garrett ] + + * SAUCE: hostap: send events on data interface as well as master + interface + + [ Michael Frey (Senior Manager, MID ] + + * SAUCE: Send HCI_RESET for Broadcomm 2046 + + [ Michael Haas ] + + * add proper aufs source tree from 20080922 + * Fix AUFS compilation in vfsub.c + * Add splice-2.6.23.patch from AUFS to export a symbol needed by AUFS + * Add put_filp.patch from AUFS to export a symbol needed by AUFS + * Add deny_write_access.patch from AUFS - export deny_write_access + * Add sec_perm-2.6.24.patch from AUFS - export security_inode_permission + * make sure TMPFS_MAGIC is defined in AUFS Makefile + * SAUCE: Revert aufs changes from AppArmor merge + + [ Mohamed Abbas ] + + * SAUCE: iwlagn -- fix rfkill when on when driver loaded + + [ Phillip Lougher ] + + * SAUCE: r8169: disable TSO by default for RTL8111/8168B chipsets. + + [ Stefan Bader ] + + * SAUCE: (no-up) Export dm_disk function of device-mapper + * SAUCE: Restore VT fonts on switch + * SAUCE: mmc: Increase power_up deleay to fix TI readers + * gfs1: GFS1 can't create more than 4kb file + * uvcvideo: Commit streaming parameters when enabling the video stream. + + [ Tim Gardner ] + + * SAUCE: Add extra headers to linux-libc-dev + * SAUCE: Catch nonsense keycodes and silently ignore + * SAUCE: Added support for HDAPS on various ThinkPads from Lenovo and IBM + * SAUCE: Guest OS does not recognize a lun with non zero target id on + Vmware ESX Server + * SAUCE: (no-up) Take care of orinoco_cs overlap with hostap_cs + * ubuntu: Add GNBD driver + * SAUCE: e1000e: Map NV RAM dynamically only when needed. + * SAUCE: Correctly blacklist Thinkpad r40e in ACPI + * SAUCE: Update Wacom tablet driver to 1.49 + * SAUCE: Fix Wacom tablet 1.49 porting errors + * SAUCE: Enable an e1000e Intel Corporation 82567 Gigabit controller + * SAUCE: Fix Oops in wlan_setup + * SAUCE: ipw2200: change default policy for auto-associate + * Dell Wireless 365 needs BTUSB_RESET quirk. + * ndiswrapper remote buffer overflows on long ESSIDs (CVE 2008-4395) + * Disabled ubuntu/e1000e config + + [ Upstream Kernel Changes ] + + * Revert "[Bluetooth] Eliminate checks for impossible conditions in IRQ + handler" + * Revert "x86, early_ioremap: fix fencepost error" + * mac80211: fix two issues in debugfs + * iwl3945: do not send scan command if channel count zero + + -- Ben Collins Fri, 07 Nov 2008 09:37:42 -0700 + +linux (2.6.27-8.17) intrepid-proposed; urgency=low + + [ John W. Linville ] + + * SAUCE: iwlagn: avoid sleep in softirq context + -LP: #286285 + + [ Tim Gardner ] + + * Dell Wireless 365 needs BTUSB_RESET quirk. + - LP: #293670 + * SAUCE: ALSA: hda: make a STAC_DELL_EQ option (version 2) + - LP: #293271 + + [ Upstream Kernel Changes ] + + * iwlagn: downgrade BUG_ON in interrupt + * Input: atkbd - expand Latitude's force release quirk to other Dells + * fbcon_set_all_vcs: fix kernel crash when switching the rotated consoles + * modules: fix module "notes" kobject leak + * Driver core: Fix cleanup in device_create_vargs(). + * Driver core: Clarify device cleanup. + * ath9k/mac80211: disallow fragmentation in ath9k, report to userspace + * md: Fix rdev_size_store with size == 0 + * xfs: fix remount rw with unrecognized options + * OHCI: Allow broken controllers to auto-stop + * USB: OHCI: fix endless polling behavior + * USB: Fix s3c2410_udc usb speed handling + * USB: EHCI: log a warning if ehci-hcd is not loaded first + * usb gadget: cdc ethernet notification bugfix + * usb: musb_hdrc build fixes + * drm/i915: fix ioremap of a user address for non-root (CVE-2008-3831) + * DVB: au0828: add support for another USB id for Hauppauge HVR950Q + * DVB: sms1xxx: support two new revisions of the Hauppauge WinTV + MiniStick + * security: avoid calling a NULL function pointer in + drivers/video/tvaudio.c + * Linux 2.6.27.3 + -LP: #294152 + + * gpiolib: fix oops in gpio_get_value_cansleep() + * edac cell: fix incorrect edac_mode + * x86 ACPI: fix breakage of resume on 64-bit UP systems with SMP kernel + * sched: fix the wrong mask_len + * USB: cdc-wdm: make module autoload work + * USB: don't rebind drivers after failed resume or reset + * USB: fix memory leak in cdc-acm + * USB: Speedtouch: add pre_reset and post_reset routines + * dm kcopyd: avoid queue shuffle + * dm snapshot: fix primary_pe race + * amd_iommu: fix nasty bug that caused ILLEGAL_DEVICE_TABLE_ENTRY errors + * CIFS: fix saving of resume key before CIFSFindNext + * netfilter: xt_iprange: fix range inversion match + * netfilter: snmp nat leaks memory in case of failure + * netfilter: restore lost ifdef guarding defrag exception + * anon_vma_prepare: properly lock even newly allocated entries + * hvc_console: Fix free_irq in spinlocked section + * ACPI Suspend: Enable ACPI during resume if SCI_EN is not set + * ACPI suspend: Blacklist HP xw4600 Workstation for old code ordering + * ACPI suspend: Always use the 32-bit waking vector + * proc: fix vma display mismatch between /proc/pid/{maps,smaps} + * SCSI: scsi_dh: add Dell product information into rdac device handler + * PCI hotplug: cpqphp: fix kernel NULL pointer dereference + * V4L/DVB (9300): pvrusb2: Fix deadlock problem + * Linux 2.6.27.4 + -LP: #294155 + + -- Tim Gardner Tue, 04 Nov 2008 12:16:07 -0700 + +linux (2.6.27-7.16) intrepid-security; urgency=low + + [ Tim Gardner ] + + * ndiswrapper remote buffer overflows on long ESSIDs (CVE 2008-4395) + - LP: #275860 + + [ Upstream Kernel Changes ] + + * ext[234]: Avoid printk floods in the face of directory corruption + (CVE-2008-3528) + + -- Tim Gardner Mon, 03 Nov 2008 13:34:42 -0700 + +linux (2.6.27-7.15) intrepid-security; urgency=low + + [ Upstream Kernel Changes ] + + * tcp: Restore ordering of TCP options for the sake of inter-operability + - LP: #264019 + + -- Tim Gardner Mon, 27 Oct 2008 19:28:06 -0600 + +linux (2.6.27-7.14) intrepid; urgency=low + + [ Tim Gardner ] + + * Disable ath5k in 2.6.27 + - LP: #288148 + + -- Tim Gardner Thu, 23 Oct 2008 07:40:43 -0600 + +linux (2.6.27-7.13) intrepid; urgency=low + + [ Stefan Bader ] + + * gfs1: GFS1 can't create more than 4kb file + + [ Tim Gardner ] + + * Revert "SAUCE: x86: Reserve FIRST_DEVICE_VECTOR in used_vectors + bitmap.". Use upstream commit to avoid future conflicts. + * Revert "STABLE queue: mac80211: fix two issues in debugfs". + Use upstream commit to avoid future conflicts. + * Revert "x86, early_ioremap: fix fencepost error" + Use upstream commit to avoid future conflicts. + + [ Upstream Kernel Changes ] + + * sched_rt.c: resch needed in rt_rq_enqueue() for the root rt_rq + * x86: Reserve FIRST_DEVICE_VECTOR in used_vectors bitmap. + * mac80211: fix two issues in debugfs + * Fix barrier fail detection in XFS + * tty: Termios locking - sort out real_tty confusions and lock reads + * CIFS: make sure we have the right resume info before calling + CIFSFindNext + * rfkill: update LEDs for all state changes + * libertas: clear current command on card removal + * b43legacy: Fix failure in rate-adjustment mechanism + * x86, early_ioremap: fix fencepost error + * x86: SB450: skip IRQ0 override if it is not routed to INT2 of IOAPIC + * x86: improve UP kernel when CPU-hotplug and SMP is enabled + * sky2: Fix WOL regression + * netdrvr: atl1e: Don't take the mdio_lock in atl1e_probe + * Linux 2.6.27.2 + + [ Amit Kucheria ] + + * Ubuntu: agp: Fix stolen memory counting on G4X. + -LP: 285572 + + [ Scott Remnant ] + + * add MODULE_ALIAS to load ipmi_devintf with ipmi_si + + -- Tim Gardner Sun, 19 Oct 2008 10:06:21 -0600 + +linux (2.6.27-7.12) intrepid; urgency=low + + [ Chuck Short ] + + * xen: Add xen modules to virtual flavours. + + [ Mario Limonciello ] + + * SAUCE: Add back in lost commit for Apple BT Wireless Keyboard + - LP: #162083 + + [ Tim Gardner ] + + * Remove depmod created files from packages. + - LP: #250511 + * Changed default TCP congestion algorithm to 'cubic' (again) + - LP: #278801 + * Update configs for 'disable CONFIG_DYNAMIC_FTRACE' + - LP: #263555 + + [ Upstream Kernel Changes ] + + * x86: register a platform RTC device if PNP doesn't describe it + * disable CONFIG_DYNAMIC_FTRACE due to possible memory corruption on + module unload + + -- Tim Gardner Fri, 17 Oct 2008 11:25:39 -0600 + +linux (2.6.27-7.11) intrepid; urgency=low + + [ Amit Kucheria ] + + * STABLE queue: mac80211: fix two issues in debugfs + - LP: #275227 + * SAUCE: Adds support for COMPAL JHL90 webcam + + [ Ben Collins ] + + * SAUCE: (no-up) x86: Quiet "Kernel alive" messages + - LP: #39985 + * SAUCE: (no-up) Modularize vesafb + * build/config: Enable vesafb module + * build: Switch to vesafb as preferred. + + [ Leann Ogasawara ] + + * Add Dell Dimension 9200 reboot quirk + - LP: #271370 + + [ Michael Haas ] + + * SAUCE: Revert aufs changes from AppArmor merge + + [ Tim Gardner ] + + * fix virtio udeb layout + - LP: #257739 + * Enabled CONFIG_EXT4DEV_FS=m + * Changed default TCP congestion algorithm to 'cubic' + - LP: #278801 + * SAUCE: ipw2200: change default policy for auto-associate + - LP: #264104 + + [ Upstream Kernel Changes ] + + * x86, early_ioremap: fix fencepost error + - LP: #263543 + + -- Tim Gardner Sat, 11 Oct 2008 08:07:42 -0600 + +linux (2.6.27-7.10) intrepid; urgency=low + + [ Alexey Starikovskiy ] + + * SAUCE: ACPI: EC: do transaction from interrupt context + - LP: #277802 + + [ Ben Collins ] + + * build/d-i: Change virtio-modules udeb to prio standard + + [ Colin Ian King ] + + * SAUCE: Blacklist IBM 2656 in serio/i8042 + - LP: #21558 + + [ Henrik Rydberg ] + + * Revert "SAUCE: applesmc: Add MacBookAir" + * SAUCE: [PATCH 1/5] hwmon: applesmc: Specified number of bytes to read + should match actual + * SAUCE: [PATCH 2/5] hwmon: applesmc: Fix the 'wait status failed: c != + 8' problem + * SAUCE: [PATCH 3/5] hwmon: applesmc: Prolong status wait + * SAUCE: [PATCH 4/5] hwmon: applesmc: Allow for variable ALV0 and ALV1 + package length + * SAUCE: [PATCH 5/5] hwmon: applesmc: Add support for Macbook Air + * SAUCE: hwmon: applesmc: Add support for Macbook Pro 4 + * SAUCE: hwmon: applesmc: Add support for Macbook Pro 3 + * SAUCE: hwmon: applesmc: Lighter wait mechanism, drastic improvement + + [ Leann Ogasawara ] + + * Add automatic model setting for Samsung Q45 + - LP: #200210 + + [ Tim Gardner ] + + * SAUCE: Correctly blacklist Thinkpad r40e in ACPI + - LP: #278794 + * SAUCE: Update Wacom tablet driver to 1.49 + - LP: #260675 + * SAUCE: ALPS touchpad for Dell Latitude E6500/E6400 + - LP: #270643 + * SAUCE: Fix Wacom tablet 1.49 porting errors + * SAUCE: Enable an e1000e Intel Corporation 82567 Gigabit controller + * SAUCE: Fix Oops in wlan_setup + - LP: #263309 + + [ Upstream Kernel Changes ] + + * ath9k: fix oops on trying to hold the wrong spinlock + * [Bluetooth] Fix double frees on error paths of btusb and bpa10x drivers + * [Bluetooth] Add reset quirk for new Targus and Belkin dongles + * [Bluetooth] Add reset quirk for A-Link BlueUSB21 dongle + * Revert "ax25: Fix std timer socket destroy handling." + * ax25: Quick fix for making sure unaccepted sockets get destroyed. + * netrom: Fix sock_orphan() use in nr_release + * Revert "V4L/DVB (8904): cx88: add missing unlock_kernel" + * SLOB: fix bogus ksize calculation + * net: only invoke dev->change_rx_flags when device is UP + * tcp: Fix possible double-ack w/ user dma + * net: Fix netdev_run_todo dead-lock + * tcp: Fix tcp_hybla zero congestion window growth with small rho and large cwnd. + * [MIPS] Sibyte: Register PIO PATA device only for Swarm and Litte Sur + * eeepc-laptop: Fix hwmon interface + * hwmon: (it87) Prevent power-off on Shuttle SN68PT + * hwmon: Define sysfs interface for energy consumption register + * hwmon: (adt7473) Fix some bogosity in documentation file + * hwmon: (abituguru3) Enable reading from AUX3 fan on Abit AT8 32X + * hwmon: (abituguru3) Enable DMI probing feature on Abit AT8 32X + * [CPUFREQ] correct broken links and email addresses + * SLOB: fix bogus ksize calculation fix + * Don't allow splice() to files opened with O_APPEND + * Linux 2.6.27 + + -- Tim Gardner Wed, 08 Oct 2008 21:19:34 -0600 + +linux (2.6.27-6.9) intrepid; urgency=low + + [ Kees Cook ] + + * SAUCE: AppArmor: update to upstream subversion r1302 + - LP: #269921 + + [ Stefan Bader ] + + * Update configuration files to be compliant to desktop specs + - LP: #279019 + + [ Tim Gardner ] + + * Add support in e1000e for a couple of ICH10 PCI IDs + * Enable CONFIG_INPUT_PCSPKR=m + - LP: #275453 + + [ Upstream Kernel Changes ] + + * V4L/DVB (8559a): Fix a merge conflict at gspca/sonixb + * V4L/DVB (8789): wm8739: remove wrong kfree + * V4L/DVB (8883): w9968cf: Fix order of usb_alloc_urb validation + * V4L/DVB (8884): em28xx-audio: fix memory leak + * V4L/DVB (8885): cpia2_usb: fix memory leak + * V4L/DVB (8886): ov511: fix memory leak + * V4L/DVB (8887): gspca: fix memory leak + * V4L/DVB (8892): pvrusb2: Handle USB ID 2040:2950 same as 2040:2900 + * V4L/DVB (8904): cx88: add missing unlock_kernel + * V4L/DVB (8905): ov511: fix exposure sysfs attribute bug + * V4L/DVB (8909): gspca: PAC 7302 webcam 093a:262a added. + * hrtimer: migrate pending list on cpu offline + * hrtimer: fix migration of CB_IRQSAFE_NO_SOFTIRQ hrtimers + * hrtimer: mark migration state + * hrtimer: prevent migration of per CPU hrtimers + * [IA64] Put the space for cpu0 per-cpu area into .data section + * powerpc: Fix PCI in Holly device tree + * powerpc: Fix failure to shutdown with CPU hotplug + * mfd: Fix Kconfig accroding to the new gpiolib symbols + * mfd: Fix asic3 compilation + * x86: fix typo in enable_mtrr_cleanup early parameter + * ipsec: Fix pskb_expand_head corruption in xfrm_state_check_space + * iucv: Fix mismerge again. + * ALSA: ASoC: Fix cs4270 error path + * ALSA: hda - Fix model for Dell Inspiron 1525 + * sctp: Fix kernel panic while process protocol violation parameter + * x86: Fix broken LDT access in VMI + * x86, vmi: fix broken LDT access + * tcp: Fix NULL dereference in tcp_4_send_ack() + * ipv6: NULL pointer dereferrence in tcp_v6_send_ack + * XFRM,IPv6: initialize ip6_dst_blackhole_ops.kmem_cachep + * af_key: Free dumping state on socket close + * dm: always allow one page in dm_merge_bvec + * dm: cope with access beyond end of device in dm_merge_bvec + * dm mpath: add missing path switching locking + * MN10300: Fix IRQ handling + * pxa2xx_spi: fix build breakage + * e1000e: write protect ICHx NVM to prevent malicious write/erase + * powerpc: Fix boot hang regression on MPC8544DS + * ASoC: Set correct name for WM8753 rec mixer output + * ALSA: snd-powermac: mixers for PowerMac G4 AGP + * ALSA: snd-powermac: HP detection for 1st iMac G3 SL + * fbcon: fix monochrome color value calculation + * inotify: fix lock ordering wrt do_page_fault's mmap_sem + * braille_console: only register notifiers when the braille console is used + * fix error-path NULL deref in alloc_posix_timer() + * memory hotplug: missing zone->lock in test_pages_isolated() + * mm: tiny-shmem nommu fix + * mm: handle initialising compound pages at orders greater than MAX_ORDER + * e1000e: reset swflag after resetting hardware + * e1000e: do not ever sleep in interrupt context + * e1000e: remove phy read from inside spinlock + * e1000e: drop stats lock + * e1000e: debug contention on NVM SWFLAG + * e1000e: update version from k4 to k6 + * Check mapped ranges on sysfs resource files + * e1000e: Fix incorrect debug warning + * [MIPS] Build fix: Fix irq flags type + * [MIPS] SMTC: Build fix: Fix filename in Makefile + * [MIPS] SMTC: Fix holes in SMTC and FPU affinity support. + * [MIPS] SMTC: Close tiny holes in the SMTC IPI replay system. + * [MIPS] SMTC: Fix SMTC dyntick support. + * [S390] nohz: Fix __udelay. + * [S390] qdio: prevent stack clobber + * Fix init/main.c to use regular printk with '%pF' for initcall fn + * x86 setup: correct segfault in generation of 32-bit reloc kernel + * selinux: Fix an uninitialized variable BUG/panic in selinux_secattr_to_sid() + * rtc: fix kernel panic on second use of SIGIO nofitication + * fbdev: fix recursive notifier and locking when fbdev console is blanked + * orion_spi: fix handling of default transfer speed + * include/linux/stacktrace.h: declare struct task_struct + * cpusets: remove pj from cpuset maintainers + * MAINTAINERS: add mailing list for man-pages + * SubmitChecklist: interfaces changes should CC linux-api@ + * Documentation/HOWTO: info about interface changes should CC linux-api@vger + * dw_dmac: fix copy/paste bug in tasklet + * leds-fsg: change order of initialization and deinitialization + * leds-pca955x: add proper error handling and fix bogus memory handling + * ACPI: Make /proc/acpi/wakeup interface handle PCI devices (again) + * clockevents: check broadcast tick device not the clock events device + * V4L/DVB (8919): cx18: Fix tuner audio input for Compro H900 cards + * V4L/DVB (8926): gspca: Bad fix of leak memory (changeset 43d2ead315b1). + * V4L/DVB (8933): gspca: Disable light frquency for zc3xx cs2102 Kokom. + * V4L/DVB (8935): em28xx-cards: Remove duplicate entry (EM2800_BOARD_KWORLD_USB2800) + * V4L/DVB (8955): bttv: Prevent NULL pointer dereference in radio_open + * V4L/DVB (8957): zr36067: Restore the default pixel format + * V4L/DVB (8958): zr36067: Return proper bytes-per-line value + * V4L/DVB (8960): drivers/media/video/cafe_ccic.c needs mm.h + * V4L/DVB (8961): zr36067: Fix RGBR pixel format + * V4L/DVB (8963): s2255drv field count fix + * V4L/DVB (8967): Use correct XC3028L firmware for AMD ATI TV Wonder 600 + * V4L/DVB (8978): sms1xxx: fix product name for Hauppauge WinTV MiniStick + * V4L/DVB (8979): sms1xxx: Add new USB product ID for Hauppauge WinTV MiniStick + * V4L/DVB (9029): Fix deadlock in demux code + * V4L/DVB (9037): Fix support for Hauppauge Nova-S SE + * V4L/DVB (9043): S5H1420: Fix size of shadow-array to avoid overflow + * V4L/DVB (9053): fix buffer overflow in uvc-video + * V4L/DVB (9075): gspca: Bad check of returned status in i2c_read() spca561. + * V4L/DVB (9080): gspca: Add a delay after writing to the sonixj sensors. + * V4L/DVB (9092): gspca: Bad init values for sonixj ov7660. + * V4L/DVB (9099): em28xx: Add detection for K-WORLD DVB-T 310U + * V4L/DVB (9103): em28xx: HVR-900 B3C0 - fix audio clicking issue + * x86: gart iommu have direct mapping when agp is present too + * ide-cd: temporary tray close fix + * ide-dma: fix ide_build_dmatable() for TRM290 + * IDE: Fix platform device registration in Swarm IDE driver (v2) + * ide-cd: Optiarc DVD RW AD-7200A does play audio + * ide: workaround for bogus gcc warning in ide_sysfs_register_port() + * [MIPS] Fix CMP Kconfig configuration and mark as broken. + * [MIPS] IP27: Fix build errors if CONFIG_MAPPED_KERNEL=y + * x86 ACPI: Blacklist two HP machines with buggy BIOSes + * kgdb, x86: Avoid invoking kgdb_nmicallback twice per NMI + * kgdb: call touch_softlockup_watchdog on resume + * atmel-mci: Initialize BLKR before sending data transfer command + * Marker depmod fix core kernel list + * Linux 2.6.27-rc9 + + -- Tim Gardner Sun, 05 Oct 2008 21:27:49 -0600 + +linux (2.6.27-5.8) intrepid; urgency=low + + [ Amit Kucheria ] + + * Update AUFS-related Kconfig + - LP: #264048 + + [ Michael Haas ] + + * add proper aufs source tree from 20080922 + * Fix AUFS compilation in vfsub.c + * Add splice-2.6.23.patch from AUFS to export a symbol needed by AUFS + * Add put_filp.patch from AUFS to export a symbol needed by AUFS + * apply (modified) lhash.patch from AUFS to export __lookup_hash() + * Add deny_write_access.patch from AUFS - export deny_write_access + * Add sec_perm-2.6.24.patch from AUFS - export security_inode_permission + * make sure TMPFS_MAGIC is defined in AUFS Makefile + + [ Tim Gardner ] + + * Enabled CONFIG_IPWIRELESS + - LP: #274748 + * Enabled CONFIG_E1000E, disabled CONFIG_E1000E_NEW + This takes advantage of the upstream NVM protection fix in + commit 4a7703582836f55a1cbad0e2c1c6ebbee3f9b3a7. + + [ Upstream Kernel Changes ] + + * Revert "[Bluetooth] Eliminate checks for impossible conditions in IRQ + handler" + * [SCSI] qla2xxx: Defer enablement of RISC interrupts until ISP + initialization completes. + * PCI: Fix pcie_aspm=force + * PCI: fix compiler warnings in pci_get_subsys() + * UBIFS: create the name of the background thread in every case + * UBIFS: TNC / GC race fixes + * UBIFS: remove incorrect assert + * UBIFS: fix printk format warnings + * AMD IOMMU: set iommu sunc flag after command queuing + * AMD IOMMU: protect completion wait loop with iommu lock + * sparc64: Fix disappearing PCI devices on e3500. + * x86, oprofile: BUG scheduling while atomic + * ALSA: ASoC: Fix at32-pcm build breakage with PM enabled + * ath9k: connectivity is lost after Group rekeying is done + * wireless: zd1211rw: add device ID fix wifi dongle "trust nw-3100" + * [IA64] Ski simulator doesn't need check_sal_cache_flush + * [IA64] kexec fails on systems with blocks of uncached memory + * ath9k: Fix IRQ nobody cared issue with ath9k + * [Bluetooth] Fix I/O errors on MacBooks with Broadcom chips + * [Bluetooth] Fix wrong URB handling of btusb driver + * [Bluetooth] Fix USB disconnect handling of btusb driver + * sparc64: Fix missing devices due to PCI bridge test in + of_create_pci_dev(). + * [WATCHDOG] ibmasr: remove unnecessary spin_unlock() + * [WATCHDOG] wdt285: fix sparse warnings + * [WATCHDOG] unlocked_ioctl changes + * x86: fix 27-rc crash on vsmp due to paravirt during module load + * sched: fix init_hrtick() section mismatch warning + * clockevents: prevent cpu online to interfere with nohz + * x86: prevent stale state of c1e_mask across CPU offline/online + * clockevents: prevent stale tick_next_period for onlining CPUs + * clockevents: check broadcast device not tick device + * clockevents: prevent mode mismatch on cpu online + * x86: prevent C-states hang on AMD C1E enabled machines + * x86: c1e_idle: don't mark TSC unstable if CPU has invariant TSC + * timers: fix build error in !oneshot case + * ALSA: ASoC: maintainers - update email address for Liam Girdwood + * ibmasr: remove unnecessary spin_unlock() + * smb.h: do not include linux/time.h in userspace + * kernel-doc: allow structs whose members are all private + * kexec: fix segmentation fault in kimage_add_entry + * Documentation/DMA-mapping.txt: update for pci_dma_mapping_error() + changes + * sys_paccept: disable paccept() until API design is resolved + * mm: tiny-shmem fix lock ordering: mmap_sem vs i_mutex + * Documentation/sysctl/kernel.txt: fix softlockup_thresh description + * memcg: check under limit at shrink_usage + * atmel_serial: update the powersave handler to match serial core + * [SCSI] Fix hang with split requests + * USB Storage: Sierra: Non-configurable TRU-Install + * USB Serial: Sierra: Device addition & version rev + * USB: ehci: fix some ehci hangs and crashes + * USB: Fix the Nokia 6300 storage-mode. + * USB: Correct Sierra Wireless USB EVDO Modem Device ID + * USB: fix hcd interrupt disabling + * USB: update of Documentation/usb/anchors.txt + * usb gadget: fix omap_udc DMA regression + * USB: Fixing Nokia 3310c in storage mode + * usb: musb: fix include path + * USB: fix EHCI periodic transfers + * usb-serial: Add Siemens EF81 to PL-2303 hack triggers + * USB: SERIAL CP2101 add device IDs + * USB: unusual_devs addition for RockChip MP3 player + * USB: fsl_usb2_udc: fix VDBG() format string + * usb serial: ti_usb_3410_5052 obviously broken by firmware changes + * USB: ftdi_sio: Add 0x5050/0x0900 USB IDs (Papouch Quido USB 4/4) + * USB: serial: add ZTE CDMA Tech id to option driver + * USB Serial: Sierra: Add MC8785 VID/PID + * USB: drivers/usb/musb/: disable it on SuperH + * usb: ftdi_sio: add support for Domintell devices + * usb: unusual devs patch for Nokia 5310 Music Xpress + * USB: revert recovery from transient errors + * [MIPS] au1000: Fix gpio direction + * [MIPS] Fixe the definition of PTRS_PER_PGD + * x86: prevent stale state of c1e_mask across CPU offline/online, fix + * x86: disable apm on the olpc + * i2c-powermac: Fix section for probe and remove functions + * i2c-dev: Return correct error code on class_create() failure + * i2c: Fix mailing lists in two MAINTAINERS entries + * ath9k: disable MIB interrupts to fix interrupt storm + * 9p: implement proper trans module refcounting and unregistration + * 9p-trans_fd: fix trans_fd::p9_conn_destroy() + * 9p-trans_fd: clean up p9_conn_create() + * 9p-trans_fd: don't do fs segment mangling in p9_fd_poll() + * 9p-trans_fd: fix and clean up module init/exit paths + * 9p: introduce missing kfree + * 9p: use an IS_ERR test rather than a NULL test + * 9p: fix put_data error handling + * netfilter: ip6t_{hbh,dst}: Rejects not-strict mode on rule insertion + * MN10300: Move asm-arm/cnt32_to_63.h to include/linux/ + * MN10300: Make sched_clock() report time since boot + * ALSA: fix locking in snd_pcm_open*() and snd_rawmidi_open*() + * ALSA: remove unneeded power_mutex lock in snd_pcm_drop + * IPoIB: Fix crash when path record fails after path flush + * [XFS] Fix extent list corruption in xfs_iext_irec_compact_full(). + * [XFS] Remove xfs_iext_irec_compact_full() + * kgdb: could not write to the last of valid memory with kgdb + * kgdb, x86, arm, mips, powerpc: ignore user space single stepping + * kgdb, x86_64: gdb serial has BX and DX reversed + * kgdb, x86_64: fix PS CS SS registers in gdb serial + * kgdboc,tty: Fix tty polling search to use name correctly + * ARM: Delete ARM's own cnt32_to_63.h + * m32r: remove the unused NOHIGHMEM option + * m32r: don't offer CONFIG_ISA + * m32r: export empty_zero_page + * m32r: export __ndelay + * m32r/kernel/: cleanups + * [MIPS] au1000: Make sure GPIO value is zero or one + * [MIPS] IP27: Switch to dynamic interrupt routing avoding panic on + error. + * [MIPS] BCM47xx: Fix build error due to missing PCI functions + * [SSB] Initialise dma_mask for SSB_BUSTYPE_SSB devices + * Swarm: Fix crash due to missing initialization + * ide-tape: fix vendor strings + * ide: note that IDE generic may prevent other drivers from attaching + * cdrom: update ioctl documentation + * [SCSI] qlogicpti: fix sg list traversal error in continuation entries + * sata_nv: reinstate nv_hardreset() for non generic controllers + * scsi: fix fall out of sg-chaining patch in qlogicpti + * ALSA: make the CS4270 driver a new-style I2C driver + * ALSA: ASoC: Fix another cs4270 error path + * Fix NULL pointer dereference in proc_sys_compare + * kconfig: fix silentoldconfig + * kconfig: readd lost change count + * mm owner: fix race between swapoff and exit + * Linux 2.6.27-rc8 + * e1000e: write protect ICHx NVM to prevent malicious write/erase + + -- Amit Kucheria Tue, 30 Sep 2008 18:22:35 +0300 + +linux (2.6.27-4.7) intrepid; urgency=low + + [ Ben Collins ] + + * build/abi: Add gfs1 to perm blacklist + * build/abi: Ignored changes in gfs2 symbols + + [ Fabio M. Di Nitto ] + + * Revert "SAUCE: Export gfs2 symbols required for gfs1 kernel module" + * ubuntu: update GFS Cluster File System + + [ Stefan Bader ] + + * SAUCE: x86: Reserve FIRST_DEVICE_VECTOR in used_vectors bitmap. + - LP: #276334 + + [ Tim Gardner ] + + * Revert "Disable e1000e until the NVRAM corruption problem is found." + * Add atl1e and atl2 to Debian installer bits + - LP: #273904 + * SAUCE: e1000e: Map NV RAM dynamically only when needed. + - LP: #263555 + + -- Tim Gardner Fri, 26 Sep 2008 20:51:22 -0600 + +linux (2.6.27-4.6) intrepid; urgency=low + + [ Tim Gardner ] + + * Disable e1000e until the NVRAM corruption problem is found. + - LP: #263555 + + [ Upstream Kernel Changes ] + + * Revert "[Bluetooth] Eliminate checks for impossible conditions in IRQ + handler" + + -- Ben Collins Tue, 23 Sep 2008 09:53:57 -0400 + +linux (2.6.27-4.5) intrepid; urgency=low + + [ Upstream Kernel Changes ] + + * Revert "b43/b43legacy: add RFKILL_STATE_HARD_BLOCKED support" + * udf: Fix lock inversion between iprune_mutex and alloc_mutex (v2) + * udf: Fix error paths in udf_new_inode() + * [SCSI] sd: select CRC_T10DIF only when necessary + * [SCSI] zfcp: Fix request queue locking + * [SCSI] zfcp: Correctly query end flag in gpn_ft response + * [SCSI] zfcp: Simplify ccw notify handler + * [SCSI] zfcp: Fix reference counter for remote ports + * [SCSI] zfcp: channel cannot be detached due to refcount imbalance + * [SCSI] zfcp: Remove duplicated unlikely() macros. + * [SCSI] scsi_dh: make check_sense return ADD_TO_MLQUEUE + * [SCSI] make scsi_check_sense HARDWARE_ERROR return ADD_TO_MLQUEUE on + retry + * [SCSI] fix check of PQ and PDT bits for WLUNs + * pcm037: add rts/cts support for serial port + * i.MX serial: fix init failure + * imx serial: set RXD mux bit on i.MX27 and i.MX31 + * imx serial: fix rts handling for non imx1 based hardware + * mlx4_core: Set RAE and init mtt_sz field in FRMR MPT entries + * udf: add llseek method + * PCI/iommu: blacklist DMAR on Intel G31/G33 chipsets + * PCI: Fix printk warnings in probe.c + * PCI: Fix printk warnings in setup-bus.c + * PCI Hotplug: fakephp: fix deadlock... again + * clockevents: remove WARN_ON which was used to gather information + * ocfs2: Fix a bug in direct IO read. + * arch/x86/kernel/kdebugfs.c: introduce missing kfree + * [IA64] fix compile failure with non modular builds + * [IA64] fix up bte.h + * [IA64] arch/ia64/sn/pci/tioca_provider.c: introduce missing kfree + * PCI: fix pciehp_free_irq() + * [IA64] prevent ia64 from invoking irq handlers on offline CPUs + * ide: Fix pointer arithmetic in hpt3xx driver code (3rd try) + * add deprecated ide-scsi to feature-removal-schedule.txt + * swiotlb: fix back-off path when memory allocation fails + * sparc64: Fix interrupt register calculations on Psycho and Sabre. + * VIDEO_SH_MOBILE_CEU should depend on HAS_DMA + * m68k: Update defconfigs for 2.6.27-rc6 + * sparc32: Fix function signature of of_bus_sbus_get_flags(). + * sched: fix 2.6.27-rc5 couldn't boot on tulsa machine randomly + * sched: fix deadlock in setting scheduler parameter to zero + * KVM: SVM: fix random segfaults with NPT enabled + * KVM: SVM: fix guest global tlb flushes with NPT + * KVM: VMX: Always return old for clear_flush_young() when using EPT + * clocksource, acpi_pm.c: fix check for monotonicity + * [ARM] OMAP: Fix MMC device data + * block: disable sysfs parts of the disk command filter + * ath9k: Assign seq# when mac80211 requests this + * sg: disable interrupts inside sg_copy_buffer + * MN10300: Change the fault handler to check in_atomic() not + in_interrupt() + * [Bluetooth] Fix regression from using default link policy + * netlink: fix overrun in attribute iteration + * x86: fix possible x86_64 and EFI regression + * sparc64: Fix PCI error interrupt registry on PSYCHO. + * sparc: Fix user_regset 'n' field values. + * niu: panic on reset + * PCI: re-add debug prints for unmodified BARs + * [ARM] 5245/1: Fix warning about unused return value in drivers/pcmcia + * [ARM] 5246/1: tosa: add proper clock alias for tc6393xb clock + * [ARM] 5247/1: tosa: SW_EAR_IN support + * [ARM] Fix PCI_DMA_BUS_IS_PHYS for ARM + * ata: duplicate variable sparse warning + * sata_inic162x: enable LED blinking + * [libata] LBA28/LBA48 off-by-one bug in ata.h + * proc: more debugging for "already registered" case + * include/linux/ioport.h: add missing macro argument for devm_release_* + family + * cpuset: avoid changing cpuset's cpus when -errno returned + * cpuset: hotplug documentation fix + * coredump_filter: add description of bit 4 + * bfs: fix Lockdep warning + * mm: ifdef Quicklists in /proc/meminfo + * spi_mpc83xx: fix clockrate calculation for low speed + * spi_mpc83xx: reject invalid transfer sizes + * pxa2xx_spi: chipselect bugfixes + * pxa2xx_spi: dma bugfixes + * mm: mark the correct zone as full when scanning zonelists + * Documentation/ABI: /sys/class/gpio + * MAINTAINERS: fix USB VIDEO CLASS mail list address + * ia64: fix panic during `modprobe -r xpc' + * atmel_lcdfb: disable LCD and DMA engines when suspending + * spi_s3c24xx: fix section warning + * rescan_partitions(): make device capacity errors non-fatal + * memstick: fix MSProHG 8-bit interface mode support + * Add Uwe Kleine-König to .mailmap + * xen: fix for xen guest with mem > 3.7G + * x86/paravirt: Remove duplicate paravirt_pagetable_setup_{start, done}() + * crypto: talitos - Avoid consecutive packets going out with same IV + * slub: fixed uninitialized counter in struct kmem_cache_node + * udp: Fix rcv socket locking + * IB/mlx4: Fix up fast register page list format + * [MIPS] VR41xx: unsigned irq cannot be negative + * x86: completely disable NOPL on 32 bits + * [S390] cio: Fix driver_data handling for ccwgroup devices. + * [S390] cio: fix orb initialization in cio_start_key + * sparc64: Fix OOPS in psycho_pcierr_intr_other(). + * sparc64: Fix SMP bootup with CONFIG_STACK_DEBUG or ftrace. + * RDMA/nes: Fix client side QP destroy + * IPoIB: Fix deadlock on RTNL between bcast join comp and ipoib_stop() + * clockevents: make device shutdown robust + * powerpc: Fix interrupt values for DMA2 in MPC8610 HPCD device tree + * hpplus: fix build regression + * Fix PNP build failure, bugzilla #11276 + * warn: Turn the netdev timeout WARN_ON() into a WARN() + * [XFS] Move memory allocations for log tracing out of the critical path + * [XFS] Fix regression introduced by remount fixup + * [XFS] Prevent direct I/O from mapping extents beyond eof + * [XFS] Fix barrier status change detection. + * [XFS] Prevent lockdep false positives when locking two inodes. + * [XFS] Fix use-after-free with buffers + * [XFS] Don't do I/O beyond eof when unreserving space + * powerpc: Holly board needs dtbImage target + * Fix compile failure with non modular builds + * [ARM] 5249/1: davinci: remove redundant check in davinci_psc_config() + * [ARM] omap: back out 'internal_clock' support + * sctp: set the skb->ip_summed correctly when sending over loopback. + * [ARM] 5255/1: Update jornada ssp to remove build errors/warnings + * sctp: do not enable peer features if we can't do them. + * sctp: Fix oops when INIT-ACK indicates that peer doesn't support AUTH + * bnx2: Promote vector field in bnx2_irq structure from u16 to unsigned + int + * forcedeth: call restore mac addr in nv_shutdown path + * e1000: prevent corruption of EEPROM/NVM + * e100: Use pci_pme_active to clear PME_Status and disable PME# + * md: Don't wait UNINTERRUPTIBLE for other resync to finish + * atstk1000: fix build breakage with BOARD_ATSTK100X_SW2_CUSTOM=y + * avr32: add .gitignore files + * avr32: add generic_find_next_le_bit bit function + * avr32: fix sys_sync_file_range() call convention + * avr32: nmi_enter() without nmi_exit() + * KVM: ia64: 'struct fdesc' build fix + * hwmon: (atxp1) Fix device detection logic + * hwmon: (it87) Fix fan tachometer reading in IT8712F rev 0x7 (I) + * hwmon: (ad7414) Make ad7414_update_device() static + * tmio_mmc: fix compilation with debug enabled + * atmel-mci: debugfs: enable clock before dumping regs + * atmel-mci: Fix memory leak in atmci_regs_show + * atmel-mci: Fix bogus debugfs file size + * atmel-mci: Set MMC_CAP_NEEDS_POLL if no detect_pin + * mmc_block: handle error from mmc_register_driver() + * mmc_test: initialize mmc_test_lock statically + * [MIPS] Fix 64-bit IP checksum code + * [MIPS] SMTC: Clear TIF_FPUBOUND on clone / fork. + * [MIPS] Fix potential latency problem due to non-atomic cpu_wait. + * [MIPS] vmlinux.lds.S: handle .text.* + * MAINTAINERS: Trivial whitespace cleanups + * MAINTAINERS: Various fixes + * Linux 2.6.27-rc7 + + -- Tim Gardner Sun, 21 Sep 2008 21:49:28 -0600 + +linux (2.6.27-3.4) intrepid; urgency=low + + [ Colin Ian King ] + + * SAUCE: fix kernel oops in VirtualBox during paravirt patching + - LP: #246067 + * SAUCE: qc-usb: Enable Logitech QuickCam Messenger + - LP: #209901 + * SAUCE: appleir: Enable driver for new MacBook Pro + - LP: #157919 + + [ Tim Gardner ] + + * Enabled CONFIG_DEBUG_RODATA=y + + [ Upstream Kernel Changes ] + + * Revert "ALSA: hda - Added model selection for iMac 24"" + * Revert "x86: fix HPET regression in 2.6.26 versus 2.6.25, check hpet + against BAR, v3" + * Revert "[ARM] use the new byteorder headers" + * Revert "mac80211: Use IWEVASSOCREQIE instead of IWEVCUSTOM" + * Revert "crypto: camellia - Use kernel-provided bitops, unaligned access + helpers" + * svcrdma: Fix race between svc_rdma_recvfrom thread and the dto_tasklet + * sched, cpuset: rework sched domains and CPU hotplug handling (v4) + * ACPI: Fix now signed module parameter. + * ACPI: Change package length error to warning + * ACPI: Fix now signed module parameter. + * ACPI: Fix typo in "Disable MWAIT via DMI on broken Compal board" + * acpi: add checking for NULL early param + * UBIFS: fix zero-length truncations + * Input: bcm5974 - add maintainer entry + * sh64: re-add the __strnlen_user() prototype + * sh: fix ptrace_64.c:user_disable_single_step() + * PNPACPI: ignore the producer/consumer bit for extended IRQ descriptors + * UBIFS: always read hashed-key nodes under TNC mutex + * UBIFS: allow for racing between GC and TNC + * [CIFS] Fix plaintext authentication + * sparc32: Implement smp_call_function_single(). + * sh: crash kernel resource fix + * sh: fix kexec entry point for crash kernels + * sh: fix platform_resource_setup_memory() section mismatch + * sh: update Migo-R defconfig + * sh: update AP325RXA defconfig + * sh: fix semtimedop syscall + * cifs: fix O_APPEND on directio mounts + * [CIFS] update cifs change log + * [CIFS] Turn off Unicode during session establishment for plaintext + authentication + * ACPI: thinkpad-acpi: wan radio control is not experimental + * sparc: Fix resource flags for PCI children in OF device tree. + * remove blk_register_filter and blk_unregister_filter in gendisk + * ALSA: oxygen: fix distorted output on AK4396-based cards + * ipv6: When we droped a packet, we should return NET_RX_DROP instead of + 0 + * pkt_sched: Fix locking of qdisc_root with qdisc_root_sleeping_lock() + * net: Unbreak userspace usage of linux/mroute.h + * Don't trigger softlockup detector on network fs blocked tasks + * Resource handling: add 'insert_resource_expand_to_fit()' function + * sparc64: setup_valid_addr_bitmap_from_pavail() should be __init + * UBIFS: do not update min_idx_lebs in stafs + * UBIFS: push empty flash hack down + * UBIFS: remove incorrect index space check + * UBIFS: improve statfs reporting + * UBIFS: fix assertion + * UBIFS: add forgotten gc_idx_lebs component + * UBIFS: introduce LEB overhead + * UBIFS: improve statfs reporting even more + * UBIFS: fill f_fsid + * drm/radeon: downgrade debug message from info to debug. + * Remove invalidate_partition call from do_md_stop. + * Fix problem with waiting while holding rcu read lock in md/bitmap.c + * ALSA: hda: Distortion fix for dell_m6_core_init + * ALSA: ASoC: fix pxa2xx-i2s clk_get call + * block: restore original behavior of /proc/partition when there's no + partition + * debugobjects: fix lockdep warning + * avr32: Fix lockup after Java stack underflow in user mode + * avr32: pm_standby low-power ram bug fix + * nfsd: fix compound state allocation error handling + * sunrpc: fix possible overrun on read of /proc/sys/sunrpc/transports + * nfsd: fix buffer overrun decoding NFSv4 acl + * audit: Moved variable declaration to beginning of function + * Fix modules_install on RO nfs-exported trees. + * Remove '#include ' from mm/page_isolation.c + * dabusb_fpga_download(): fix a memory leak + * [MTD] mtdchar.c: Fix regression in MEMGETREGIONINFO ioctl() + * ALSA: hda - Fix ALC663 auto-probe + * ALSA: hda - Add mic-boost controls to ALC662/663 auto configuration + * Un-break printk strings in x86 PCI probing code + * kernel/resource.c: fix new kernel-doc warning + * softlockup: minor cleanup, don't check task->state twice + * fix typo in arch/parisc/hpux/fs.c + * m68k: atari_keyb_init operator precedence fix + * ACPI: Fix typo in "Disable MWAIT via DMI on broken Compal board" + * don't diff generated firmware files + * IDE: compile fix for sff_dma_ops + * IDE: palm_bk3710: fix compile warning for unused variable + * ide: fix hwif_to_node() + * palm_bk3710: improve IDE registration + * ide-disk: remove stale init_idedisk_capacity() documentation + * ide/Kconfig: mark ide-scsi as deprecated + * net/wireless/Kconfig: clarify the description for + CONFIG_WIRELESS_EXT_SYSFS + * iwlwifi: do not use GFP_DMA in iwl_tx_queue_init + * iwlwifi: workaround interrupt handling no some platforms + * iwlwifi: fix apm_stop (wrong bit polarity for FLAG_INIT_DONE) + * iwlwifi: fix 64bit platform firmware loading + * orinoco: Multicast to the specified addresses + * wireless/libertas/if_cs.c: fix memory leaks + * mac80211: Fix debugfs union misuse and pointer corruption + * rt2x00: Compiler warning unmasked by fix of BUILD_BUG_ON + * ath9k: Incorrect key used when group and pairwise ciphers are + different. + * ath9: Fix ath_rx_flush_tid() for IRQs disabled kernel warning message. + * net/xfrm: Use an IS_ERR test rather than a NULL test + * ipv: Re-enable IP when MTU > 68 + * NTFS: update homepage + * mm: make setup_zone_migrate_reserve() aware of overlapping nodes + * VFS: fix dio write returning EIO when try_to_release_page fails + * acer-wmi: remove debugfs entries upon unloading + * mm/bootmem: silence section mismatch warning - + contig_page_data/bootmem_node_data + * MAINTAINERS: add a maintainer for the BCM5974 multitouch driver + * 8250: improve workaround for UARTs that don't re-assert THRE correctly + * mmc: at91_mci: don't use coherent dma buffers + * pid_ns: zap_pid_ns_processes: fix the ->child_reaper changing + * pid_ns: (BUG 11391) change ->child_reaper when init->group_leader exits + * cirrusfb: check_par fixes + * devcgroup: fix race against rmdir() + * mm: show quicklist usage in /proc/meminfo + * mm: size of quicklists shouldn't be proportional to the number of CPUs + * ipc: document the new auto_msgmni proc file + * hp-wmi: update to match current rfkill semantics + * hp-wmi: add proper hotkey support + * tdfxfb: fix SDRAM memory size detection + * tdfxfb: fix frame buffer name overrun + * rtc_time_to_tm: fix signed/unsigned arithmetic + * ibft: fix target info parsing in ibft module + * sysfs: document files in /sys/firmware/sgi_uv/ + * rtc-cmos: wake again from S5 + * pm_qos_requirement might sleep + * drivers/char/random.c: fix a race which can lead to a bogus BUG() + * ipsec: Fix deadlock in xfrm_state management. + * [x86] Fix TSC calibration issues + * tipc: Don't use structure names which easily globally conflict. + * sparc64: Fix IPI call locking. + * [ARM] omap: fix gpio.c build error + * sparc64: Prevent sparc64 from invoking irq handlers on offline CPUs + * powerpc: Fix uninitialised variable in VSX alignment code + * powerpc: Only make kernel text pages of linear mapping executable + * powerpc: Make sure _etext is after all kernel text + * powerpc: Work around gcc's -fno-omit-frame-pointer bug + * powerpc: Fix build error with 64K pages and !hugetlbfs + * powerpc: Fix for getting CPU number in power_save_ppc32_restore() + * UBIFS: amend f_fsid + * net/usb/pegasus: avoid hundreds of diagnostics + * ixgbe: initialize interrupt throttle rate + * pcnet-cs, axnet_cs: add new IDs, remove dup ID with less info + * netxen: Remove workaround for chipset quirk + * Split up PIT part of TSC calibration from native_calibrate_tsc + * iwlwifi: W/A for the TSF correction in IBSS + * iwlwifi: fix hidden ssid discovery in passive channels + * iwlwifi: remove false rxon if rx chain changes + * iwlwifi: fix station mimo power save values + * iwlwifi: fix rx_chain computation + * iwlwifi: fix Tx cmd memory allocation failure handling + * iwlwifi: call apm stop on exit + * iwlwifi: fix STATUS_EXIT_PENDING is not set on pci_remove + * ath9k: Fix TX status reporting + * ath9k: Fix TX control flag use for no ACK and RTS/CTS + * V4L/DVB (8555): au8522: add mechanism to configure IF frequency for vsb + and qam + * V4L/DVB (8556): au0828: add support for Hauppauge Woodbury + * V4L/DVB (8598): au8522: clean up function au8522_set_if + * V4L/DVB (8599): au8522: remove if frequency settings from vsb/qam + modulation tables + * V4L/DVB (8600): au0828: explicitly set 6 MHz IF frequency in + hauppauge_hvr950q_config + * V4L/DVB (8629): v4l2-ioctl: do not try to handle private V4L1 ioctls + * V4L/DVB (8633): ivtv: update ivtv version number + * V4L/DVB (8648): ivtv: improve CC support + * V4L/DVB (8660): gspca: Simplify the scan of URB packets in pac7311. + * V4L/DVB (8661): gspca: Bug in the previous changeset about pac7311. + * V4L/DVB (8663): gspca: Webcam 0c45:6128 added in sonixj. + * V4L/DVB (8664): gspca: The bridge/sensor of the webcam 093a:2621 is a + PAC 7302. + * V4L/DVB (8665): gspca: Fix the 640x480 resolution of the webcam + 093a:2621. + * V4L/DVB (8666): gspca: Bad scanning of frames in pac7311. + * V4L/DVB (8667): gspca: Bad probe of Z-Star/Vimicro webcams with pas106 + sensor. + * V4L/DVB (8668): gspca: Conflict GSPCA / ET61X251 for the webcam + 102c:6251. + * V4L/DVB (8669): gspca: Add white balance control for spca561 rev 012A. + * V4L/DVB (8671): gspca: Remove the unused field 'dev_name' of the device + structure. + * V4L/DVB (8672): gspca: Big rewrite of spca561. + * V4L/DVB (8673): gspca: Bad frame scanning again and bad init in + pac7311. + * V4L/DVB (8674): gspca: Webcam 0c45:612e added in sonixj. + * V4L/DVB (8675): gspca: Pixmap PJPG (Pixart 73xx JPEG) added, generated + by pac7311. + * V4L/DVB (8678): Remove the dead CONFIG_RADIO_MIROPCM20{,_RDS} code + * V4L/DVB (8681): v4l2-ioctl.c: fix warning + * V4L/DVB (8682): V4L: fix return value of register video func + * V4L/DVB (8701): cx18: Add missing lock for when the irq handler + manipulates the queues + * V4L/DVB (8703): gspca: Do controls work for spca561 revision 12a. + * V4L/DVB (8705): gspca: Adjust some control limits in spca561. + * V4L/DVB (8706): Make contrast and brightness work for pac7302. + * V4L/DVB (8707): gspca: Colors, hflip and vflip controls added for + pac7302. + * V4L/DVB (8709): gspca: Fix initialization and controls of sn9x110 - + ov7630. + * V4L/DVB (8710): gspca: Bad color control in sonixj. + * V4L/DVB (8711): gspca: Bad controls and quantization table of pac7311. + * V4L/DVB (8712): gspca: Bad start of sonixj webcams since changeset + a8779025e7e8. + * V4L/DVB (8713): gspca: Bad color control again in sonixj. + * V4L/DVB (8714): gspca: Bad start of sn9c110 and sensor om6802. + * V4L/DVB (8715): gspca: Change the name of some webcam in the gspca doc. + * V4L/DVB (8716): gspca: Bad start of sn9c110 and sensor ov7630. + * V4L/DVB (8717): gspca: Frame buffer too small for small resolutions + (sonixj and t613). + * V4L/DVB (8718): gspca: suspend/resume added. + * V4L/DVB (8719): gspca: Have VIDIOC_QUERYCTRL more compliant to the + spec. + * V4L/DVB (8720): gspca: V4L2_CAP_SENSOR_UPSIDE_DOWN added as a cap for + some webcams. + * V4L/DVB (8722): sms1xxx: fix typo in license header + * V4L/DVB (8726): link tuner before saa7134 + * V4L/DVB (8727): V4L1: make PMS not autoprobe when builtin. + * V4L/DVB (8728): 1-make-pms-not-autoprobe-when-builtin update + * V4L/DVB (8749): Fix error code, when camera is not turned on by sonypi + * V4L/DVB (8750): V4L: check inval in video_register_device_index() + * V4L/DVB (8751): vivi: Fix some issues at vivi register routine + * V4L/DVB (8757): v4l-dvb: fix a bunch of sparse warnings + * V4L/DVB (8769): cx18: Simplify queue flush logic to prevent oops in + cx18_flush_queues() + * V4L/DVB (8778): radio: fix incorrect video_register_device result check + * V4L/DVB (8779): v4l: fix more incorrect video_register_device result + checks + * V4L/DVB (8790): saa7115: call i2c_set_clientdata only when state != + NULL + * V4L/DVB (8803): s5h1409: Enable QAM_AUTO mode + * V4L/DVB (8804): s5h1411: Enable QAM_AUTO mode + * V4L/DVB (8805): Steven Toth email address change + * V4L/DVB (8809): gspca: Revert commit + 9a9335776548d01525141c6e8f0c12e86bbde982 + * V4L/DVB (8810): gspca: Compile error when CONFIG_PM not defined. + * V4L/DVB (8812): gspca: Do pac73xx webcams work. + * V4L/DVB (8813): gspca: Adjust SOF detection for pac73xx. + * V4L/DVB (8814): gspca: Set DISABLED the disabled controls at query + control time. + * V4L/DVB (8815): gspca: Fix problems with disabled controls. + * V4L/DVB (8816): gspca: Set disabled ctrls and fix a register pb with + ovxxxx in sonixb. + * V4L/DVB (8817): gspca: LED and proble changes in sonixb. + * V4L/DVB (8818): gspca: Reinitialize the device on resume. + * V4L/DVB (8819): gspca: Initialize the ov519 at open time and source + cleanup. + * V4L/DVB (8820): gspca: Change initialization and gamma of zc3xx - + pas106. + * V4L/DVB (8822): gspca: Change some subdriver functions for + suspend/resume. + * V4L/DVB (8823): gspca: H and V flips work for ov7670 only in ov519. + * V4L/DVB (8824): gspca: Too much code removed in the suspend/resume + changeset. + * V4L/DVB (8825): gspca: More controls for pac73xx and new webcam + 093a:2624. + * V4L/DVB (8826): gspca: Webcam Labtec 2200 (093a:2626) added in pac7311. + * V4L/DVB (8827): gspca: Stop pac7302 autogain oscillation. + * V4L/DVB (8828): gspca: Set the clock at the end of initialization in + sonixj. + * V4L/DVB (8829): gspca: Have a clean kmalloc-ated buffer for USB + exchanges. + * V4L/DVB (8830): gspca: Move some probe code to the new init function. + * V4L/DVB (8831): gspca: Resolve webcam conflicts between some drivers. + * V4L/DVB (8832): gspca: Bad pixelformat of vc0321 webcams. + * V4L/DVB (8833): gspca: Cleanup the sonixb code. + * V4L/DVB (8834): gspca: Have a bigger buffer for sn9c10x compressed + images. + * V4L/DVB (8835): gspca: Same pixfmt as the sn9c102 driver and raw Bayer + added in sonixb. + * V4L/DVB (8837): dvb: fix I2C adapters name size + * V4L/DVB (8839): dib0700: add comment to identify 35th USB id pair + * V4L/DVB (8840): dib0700: add basic support for Hauppauge Nova-TD-500 + (84xxx) + * V4L/DVB (8842): vivi_release(): fix use-after-free + * V4L/DVB (8843): tda10048_firmware_upload(): fix a memory leak + * V4L/DVB (8844): dabusb_fpga_download(): fix a memory leak + * bnx2x: Accessing un-mapped page + * SELinux: memory leak in security_context_to_sid_core + * x86: add io delay quirk for Presario F700 + * mmap: fix petty bug in anonymous shared mmap offset handling + * x86: Change warning message in TSC calibration. + * PCI: fix pbus_size_mem() resource alignment for CardBus controllers + * [ARM] omap: fix build error in ohci-omap.c + * [ARM] remove unused #include + * ACPI: Make Len Brown the ACPI maintainer again + * fujitsu-laptop: fix regression for P8010 in 2.6.27-rc + * ACPI: Avoid bogus timeout about SMbus check + * acer-wmi: remove debugfs entries upon unloading + * forgotten refcount on sysctl root table + * V4L/DVB (8868): gspca: Support for vga modes with sif sensors in + sonixb. + * V4L/DVB (8869): gspca: Move the Sonix webcams with TAS5110C1B from + sn9c102 to gspca. + * V4L/DVB (8870): gspca: Fix dark room problem with sonixb. + * V4L/DVB (8872): gspca: Bad image format and offset with rev072a of + spca561. + * V4L/DVB (8873): gspca: Bad image offset with rev012a of spca561 and + adjust exposure. + * V4L/DVB (8874): gspca: Adjust hstart for sn9c103/ov7630 and update + usb-id's. + * [ARM] omap: fix virtual vs physical address space confusions + * V4L/DVB (8876): budget: udelay changed to mdelay + * V4L/DVB (8877): b2c2 and bt8xx: udelay to mdelay + * V4L/DVB (8880): PATCH: Fix parents on some webcam drivers + * V4L/DVB (8881): gspca: After 'while (retry--) {...}', retry will be -1 + but not 0. + * powerpc/spufs: Fix multiple get_spu_context() + * powerpc/spufs: Fix race for a free SPU + * Input: bcm5974 - small formatting cleanup + * Input: bcm5974 - improve finger tracking and counting + * Input: bcm5974 - add BTN_TOUCH event for mousedev benefit + * Input: i8042 - make Lenovo 3000 N100 blacklist entry more specific + * sh: resume_kernel fix for kernel oops built with CONFIG_BKL_PREEMPT=y. + * sh64: resume_kernel fix for kernel oops built with + CONFIG_BKL_PREEMPT=y. + * i2c: fix i2c-sh_mobile timing issues + * clockevents: prevent clockevent event_handler ending up handler_noop + * clockevents: prevent endless loop in periodic broadcast handler + * clockevents: enforce reprogram in oneshot setup + * clockevents: prevent multiple init/shutdown + * clockevents: prevent endless loop lockup + * HPET: make minimum reprogramming delta useful + * [MTD] [NAND] tmio_nand: fix base address programming + * Fix conditional export of kvh.h and a.out.h to userspace. + * async_tx: fix the bug in async_tx_run_dependencies + * sched_clock: fix NOHZ interaction + * sched: fix process time monotonicity + * UBIFS: fix division by zero + * UBIFS: make minimum fanout 3 + * [MIPS] Fix data bus error recovery + * [MIPS] Fix WARNING: at kernel/smp.c:290 + * [MIPS] TXx9: Fix txx9_pcode initialization + * [MIPS] TX39xx: Add missing local_flush_icache_range initialization + * [MIPS] Probe initrd header only if explicitly specified + * res_counter: fix off-by-one bug in setting limit + * forcedeth: fix kexec regression + * atmel_lcdfb: fix oops in rmmod when framebuffer fails to register + * tracehook: comment pasto fixes + * drivers/mmc/card/block.c: fix refcount leak in mmc_block_open() + * x86: boot: stub out unimplemented CPU feature words + * x86: add NOPL as a synthetic CPU feature bit + * x86: use X86_FEATURE_NOPL in alternatives + * clockevents: broadcast fixup possible waiters + * x86: HPET fix moronic 32/64bit thinko + * x86: HPET: read back compare register before reading counter + * Fix CONFIG_AC97_BUS dependency + * [ARM] 5241/1: provide ioremap_wc() + * ntp: fix calculation of the next jiffie to trigger RTC sync + * clocksource, acpi_pm.c: use proper read function also in errata mode + * clocksource, acpi_pm.c: check for monotonicity + * x86: delay early cpu initialization until cpuid is done + * x86: move mtrr cpu cap setting early in early_init_xxxx + * sched: arch_reinit_sched_domains() must destroy domains to force + rebuild + * x86, xen: Use native_pte_flags instead of native_pte_val for .pte_flags + * x86: pda_init(): fix memory leak when using CPU hotplug + * x86: cpu_init(): fix memory leak when using CPU hotplug + * powerpc/spufs: Fix possible scheduling of a context to multiple SPEs + * netfilter: nf_conntrack_sip: de-static helper pointers + * netfilter: nf_conntrack_gre: more locking around keymap list + * netfilter: nf_conntrack_gre: nf_ct_gre_keymap_flush() fixlet + * netfilter: nf_conntrack_irc: make sure string is terminated before + calling simple_strtoul + * pkt_sched: Fix qdisc state in net_tx_action() + * powerpc: Fix rare boot build breakage + * ahci, pata_marvell: play nicely together + * sata_mv: add RocketRaid 1720 PCI ID to driver + * ahci: disable PMP for marvell ahcis + * sata_nv: disable hardreset for generic + * libata-sff: kill spurious WARN_ON() in ata_hsm_move() + * pata_sil680: remove duplicate pcim_enable_device + * ahci: RAID mode SATA patch for Intel Ibex Peak DeviceIDs + * [MIPS] IP22: Fix detection of second HPC3 on Challenge S + * xen: fix 2.6.27-rc5 xen balloon driver warnings + * x86: disable static NOPLs on 32 bits + * netns : fix kernel panic in timewait socket destruction + * bridge: don't allow setting hello time to zero + * NFS: Restore missing hunk in NFS mount option parser + * usb: fix null deferences in low level usb serial + * Fix format of MAINTAINERS + * sparc64: Disable timer interrupts in fixup_irqs(). + * [Bluetooth] Fix reference counting during ACL config stage + * [Bluetooth] Enforce correct authentication requirements + * [Bluetooth] Reject L2CAP connections on an insecure ACL link + * [S390] CVE-2008-1514: prevent ptrace padding area read/write in 31-bit + mode + * [S390] cio: Correct cleanup on error. + * [S390] cio: handle ssch() return codes correctly. + * [S390] cio: allow offline processing for disconnected devices + * ipsec: Restore larval states and socket policies in dump + * update Documentation/filesystems/Locking for 2.6.27 changes + * MAINTAINERS: add Atheros maintainer for atlx + * lib: Correct printk %pF to work on all architectures + * x86: fix memmap=exactmap boot argument + * clockevents: remove WARN_ON which was used to gather information + * ipv6: Fix OOPS in ip6_dst_lookup_tail(). + * Linux 2.6.27-rc6 + + -- Ben Collins Tue, 02 Sep 2008 12:45:56 -0400 + +linux (2.6.27-2.3) intrepid; urgency=low + + [ Ben Collins ] + + * build/retag: Make script save .orig of tags for later use + * ubuntu/lirc: Fix device_create call + * build/firmware: Put in-kernel firmware into version specific subdir + - LP: #262115 + * Rebase on linux-2.6 git. + * ABI bump + + [ Herton Ronaldo Krzesinski ] + + * SAUCE: (no-up) Apparmor warning fixes + + [ John Johansen ] + + * SAUCE: (no-up) Proper AppArmor ptrace updates for newer lsm API + + [ Mackenzie Morgan ] + + * SAUCE: Add quirk for ASUS Z37E to make sound audible after resume + - LP: #25896 + + -- Ben Collins Wed, 27 Aug 2008 14:03:05 -0400 + +linux (2.6.27-1.2) intrepid; urgency=low + + [ Amit Kucheria ] + + * SAUCE: make fc transport removal of target configurable + * SAUCE: pm: Config option to disable handling of console during + suspend/resume + + [ Ben Collins ] + + * SAUCE: Lower warning level of some PCI messages + * SAUCE: input/mouse/alps: Do not call psmouse_reset() for alps + * SAUCE: tulip: Let dmfe handle davicom on non-sparc + * SAUCE: tulip: Define ULI PCI ID's + * SAUCE: (no-up) version: Implement version_signature proc file. + * SAUCE: (no-up) connector.h: Add idx/val for drbd + * SAUCE: (no-up) swap: Add notify_swap_entry_free callback for compcache + * SAUCE: drivers: Remove some duplicate device entries in various modules + * SAUCE: (no-up) [AppArmor] merge with upstream subversion r1291 + * SAUCE: apparmor: Update for changes to ptrace lsm hooks + * SAUCE: (no-up) Enable ubuntu extra subdirectory + * SAUCE: applesmc: Add MacBookAir + * SAUCE: (no-up) ACPI: initramfs DSDT override support + * ubuntu: Add drbd module + * ubuntu: Add iscsitarget module + * ubuntu: Add BOM for iscsitarget + * ubuntu: Add squashfs driver + * SAUCE: (no-up) Check for squashfs superblock in initramfs mounting. + * ubuntu: Add aufs module + * ubuntu: Added atl2 driver + * ubuntu: Added et131x driver + * ubuntu: Add dm-raid4-5 driver + * ubuntu: Add ndiswrapper driver + * ubuntu: Added ram backed compressed swap module (compcache) + * ubuntu: Add misc drivers from hardy lum + * ubuntu: Add heci driver 3.2.0.24 + * ubuntu: Add ov511 and bt-sco drivers + * ubuntu: Add acx, prism2_usb wireless drivers + * ubuntu: Add at76 driver to build + * ubuntu: Add fsam7400 sw kill switch driver + * ubuntu: Added qc-usb driver + * ubuntu: e1000e: Upgraded module to 0.4.1.7 + * ubuntu: Added rfkill drivers + * ubuntu: VIA - Add VIA DRM Chrome9 3D engine + * ubuntu: unionfs: Added v1.4 module from hardy + * ubuntu: Add LIRC driver + * ubuntu: Add GFS driver + * ubuntu: New tlsup driver for toshiba laptops + * Update config files + * build/d-i: Remove obsolete dm modules + + [ Chuck Short ] + + * SAUCE: ata: blacklist FUJITSU MHW2160BH PL + + [ Colin Ian King ] + + * ubuntu: Add dm-loop + * SAUCE: Enable speedstep for sonoma processors. + + [ Dennis Noordsij ] + + * SAUCE: Work around ACPI corruption upon suspend on some Dell machines. + + [ Fabio M. Di Nitto ] + + * SAUCE: Export gfs2 symbols required for gfs1 kernel module + + [ Matthew Garrett ] + + * SAUCE: hostap: send events on data interface as well as master + interface + + [ Michael Frey (Senior Manager, MID ] + + * SAUCE: Send HCI_RESET for Broadcomm 2046 + + [ Phillip Lougher ] + + * SAUCE: r8169: disable TSO by default for RTL8111/8168B chipsets. + + [ Stefan Bader ] + + * SAUCE: (no-up) Export dm_disk function of device-mapper + * SAUCE: Restore VT fonts on switch + * SAUCE: mmc: Increase power_up deleay to fix TI readers + + [ Tim Gardner ] + + * SAUCE: Add extra headers to linux-libc-dev + * SAUCE: Catch nonsense keycodes and silently ignore + * SAUCE: Added support for HDAPS on various ThinkPads from Lenovo and IBM + * SAUCE: Guest OS does not recognize a lun with non zero target id on + Vmware ESX Server + * SAUCE: (no-up) Take care of orinoco_cs overlap with hostap_cs + * ubuntu: Add GNBD driver + + -- Ben Collins Sat, 23 Aug 2008 15:48:35 -0400 + +linux (2.6.27-0.0) intrepid; urgency=low + + * Not uploaded, placeholder for new release + + -- Ben Collins Sat, 23 Aug 2008 15:48:35 -0400 + +linux (2.6.26-5.17) intrepid; urgency=low + + [ Ben Collins ] + + * build/abi: Add tosh_smm symbol to blacklist + + -- Ben Collins Fri, 15 Aug 2008 09:29:34 -0400 + +linux (2.6.26-5.16) intrepid; urgency=low + + [ Ben Collins ] + + * Revert "SAUCE: toshiba_acpi: Rewrote most of the proc entry bits." + * Revert "SAUCE: Update toshiba_acpi.c to version 0.19a" + * build/config: Disable in-kernel toshiba driver(s) + * ubuntu/tlsup: New driver for toshiba laptops + * build/config: Enable TLSUP driver + * SAUCE: e1000e: Fix E1000E_ENABLED logic to check for our E1000E_NEW + driver as well + * ubuntu/e1000e: Remove E1000E_ENABLED option in local config + * build/config: Update configs to have E1000E_ENABLED set + * ubuntu/prism2: Remove duplicate device + + [ Fabio M. Di Nitto ] + + * SAUCE: Export gfs2 symbols required for gfs1 kernel module + + [ Stefan Bader ] + + * SAUCE: x86: HPET rework for SB700 + - LP: #255910 + + [ Tim Gardner ] + + * Add GNBD driver + * Enable GNBD driver + * SAUCE: Add GFS driver + * SAUCE: Enable gfs driver configs + * b43: Linksys WMP54G (BCM4306/3) card in a PCI format has an SPROM + coding + + [ Upstream Kernel Changes ] + + * KVM: x86 emulator: emulate clflush + * USB: quirk PLL power down mode + + -- Ben Collins Mon, 11 Aug 2008 13:19:28 -0400 + +linux (2.6.26-5.15) intrepid; urgency=low + + [ Ben Collins ] + + * Revert "SAUCE: Add blacklist support to fix Belkin bluetooth dongle." + - Superceded by upstream changes. + * build/config: New option enabled for uvcvideo + * build/control: Add Vcs-Git meta data to control file + * SAUCE: toshiba_acpi: Rewrote most of the new code + * abi/perm-blacklist: Add emu10k1 driver to blacklist + + [ Upstream Kernel Changes ] + + * pxamci: trivial fix of DMA alignment register bit clearing + * udplite: Protection against coverage value wrap-around + * ipv6: use timer pending + * ipv6: __KERNEL__ ifdef struct ipv6_devconf + * hdlcdrv: Fix CRC calculation. + * quota: fix possible infinite loop in quota code + * isofs: fix minor filesystem corruption + * KVM: VMX: Fix a wrong usage of vmcs_config + * KVM: SVM: fix suspend/resume support + * KVM: mmu_shrink: kvm_mmu_zap_page requires slots_lock to be held + * KVM: VMX: Add ept_sync_context in flush_tlb + * KVM: x86 emulator: Fix HLT instruction + * KVM: MMU: nuke shadowed pgtable pages and ptes on memslot destruction + * KVM: MMU: Fix potential race setting upper shadow ptes on nonpae hosts + * Patch Upstream: x86 ptrace: fix PTRACE_GETFPXREGS error + * rcu: fix rcu_try_flip_waitack_needed() to prevent grace-period stall + * Fix typos from signal_32/64.h merge + * x86 reboot quirks: add Dell Precision WorkStation T5400 + * USB: fix usb serial pm counter decrement for disconnected interfaces + * x86, suspend, acpi: enter Big Real Mode + * markers: fix duplicate modpost entry + * Fix build on COMPAT platforms when CONFIG_EPOLL is disabled + * proc: fix /proc/*/pagemap some more + * cpusets: fix wrong domain attr updates + * x86: fix crash due to missing debugctlmsr on AMD K6-3 + * ide-cd: fix oops when using growisofs + * rtc-at91rm9200: avoid spurious irqs + * vmlinux.lds: move __attribute__((__cold__)) functions back into final + .text section + * ARM: fix fls() for 64-bit arguments + * tcp: Clear probes_out more aggressively in tcp_ack(). + * sparc64: Fix lockdep issues in LDC protocol layer. + * sparc64: Fix cpufreq notifier registry. + * sparc64: Do not define BIO_VMERGE_BOUNDARY. + * iop-adma: fix platform driver hotplug/coldplug + * myri10ge: do not forget to setup the single slice pointers + * myri10ge: do not use mgp->max_intr_slots before loading the firmware + * ALSA: trident - pause s/pdif output + * V4L: cx18: Upgrade to newer firmware & update documentation + * DVB: dib0700: add support for Hauppauge Nova-TD Stick 52009 + * V4L: uvcvideo: Fix a buffer overflow in format descriptor parsing + * V4L: uvcvideo: Use GFP_NOIO when allocating memory during resume + * V4L: uvcvideo: Don't free URB buffers on suspend + * V4L: uvcvideo: Make input device support optional + * V4L: uvcvideo: Add support for Medion Akoya Mini E1210 integrated + webcam + * V4L: saa7134: Copy tuner data earlier to avoid overwriting manual tuner + type + * V4L: cx23885: Bugfix for concurrent use of /dev/video0 and /dev/video1 + * DVB: cx23885: Ensure PAD_CTRL is always reset to a sensible default + * DVB: cx23885: DVB Transport cards using DVB port VIDB/TS1 did not + stream + * DVB: cx23885: Reallocated the sram to avoid concurrent VIDB/C issues + * DVB: cx23885: SRAM changes for the 885 and 887 silicon parts + * x86: fix kernel_physical_mapping_init() for large x86 systems + * eCryptfs: use page_alloc not kmalloc to get a page of memory + * UML - Fix boot crash + * ixgbe: remove device ID for unsupported device + * mpc52xx_psc_spi: fix block transfer + * tmpfs: fix kernel BUG in shmem_delete_inode + * markers: fix markers read barrier for multiple probes + * VFS: increase pseudo-filesystem block size to PAGE_SIZE + * cpufreq acpi: only call _PPC after cpufreq ACPI init funcs got called + already + * b43legacy: Release mutex in error handling code + * ath5k: don't enable MSI, we cannot handle it yet + * Fix off-by-one error in iov_iter_advance() + * Linux 2.6.26.1 + * ftrace: remove unneeded documentation + * romfs_readpage: don't report errors for pages beyond i_size + * netfilter: nf_nat_sip: c= is optional for session + * SCSI: bsg: fix bsg_mutex hang with device removal + * x86: idle process - add checking for NULL early param + * x86: io delay - add checking for NULL early param + * Close race in md_probe + * Kprobe smoke test lockdep warning + * netfilter: xt_time: fix time's time_mt()'s use of do_div() + * linear: correct disk numbering error check + * SCSI: ch: fix ch_remove oops + * NFS: Ensure we zap only the access and acl caches when setting new acls + * jbd: fix race between free buffer and commit transaction + * Input: i8042 - add Intel D845PESV to nopnp list + * Input: i8042 - add Gericom Bellagio to nomux blacklist + * Input: i8042 - add Acer Aspire 1360 to nomux blacklist + * Bluetooth: Signal user-space for HIDP and BNEP socket errors + * Add compat handler for PTRACE_GETSIGINFO + * ALSA: hda - Fix wrong volumes in AD1988 auto-probe mode + * ALSA: hda - Fix DMA position inaccuracy + * ALSA: hda - Add missing Thinkpad Z60m support + * ALSA: emu10k1 - Fix inverted Analog/Digital mixer switch on Audigy2 + * vfs: fix lookup on deleted directory + * Ath5k: fix memory corruption + * Ath5k: kill tasklets on shutdown + * sound: ensure device number is valid in snd_seq_oss_synth_make_info + * Linux 2.6.26.2 + + -- Ben Collins Sun, 03 Aug 2008 13:25:02 -0400 + +linux (2.6.26-5.14) intrepid; urgency=low + + [ Ben Collins ] + + * SAUCE: applesmc: Add MacBookAir + * build: Do not build ddeb unless we are on the buildd + * build: control: Consistency in arch fields. + * SAUCE: Update toshiba_acpi.c to version 0.19a + - LP: #77026 + * build: Added perm blacklist support and per-module support to abi-check + - Blacklist p80211 module from abi checks + * ubuntu/lirc: Get rid of drivers symlink and use real include stuff + + + [ Colin Ian King ] + + * SAUCE: acerhk module - add support for Amilo A1650g keyboard + - LP: #84159 + * SAUCE: rt2x00: Fix OOPS on failed creation of rt2x00lib workqueue + - LP: #249242 + + [ Mario Limonciello ] + + * Add LIRC back in + + [ Tim Gardner ] + + * Makefile race condition can lead to ndiswrapper build failure + - LP: #241547 + * update linux-wlan-ng (prism2_usb) to upstream version 1861 + - LP: #245026 + + [ Upstream Kernel Changes ] + + * Fix typos from signal_32/64.h merge + + -- Ben Collins Fri, 01 Aug 2008 00:05:01 -0400 + +linux (2.6.26-5.13) intrepid; urgency=low + + [ Ben Collins ] + + * build: Make makedumpfile an amd64/i386 only build-dep + * ubuntu/acerhk: Fixup assembly to compile with newer binutils + + -- Ben Collins Sat, 26 Jul 2008 16:41:50 -0400 + +linux (2.6.26-4.12) intrepid; urgency=low + + [ Ben Collins ] + + * e1000e: Upgraded module to 0.4.1.7 upstream. Placed in ubuntu/, + in-kernel driver disabled + * config: Disable e1000e in-kernel, and enable newer driver in ubuntu/ + * rfkill: Update to 1.3 drivers, and move to common location + * ubuntu: Actually link kconfig/kbuild into rfkill subdir + * config: Enable loading dsdt from initramfs + - LP: #246222 + * ubuntu: [compcache] Update to fix crashes in improper BUG() + * build: Create a retag scripts to recover tags from rebases + * build: Updates for dbg pkg + * build: Make sure no empty lines show up in debian/files + * ubuntu: atl1e: Add new driver from 2.6.27-pre-rc1 + - LP: #243894 + * sys_getcwd: Fix some brokeness introduced by AppArmor __d_path + changes + - LP: #251223 + * ubuntu: unionfs: Added v1.4 module from hardy + * build: Add sub-flavour infrastructure, and virtual subflav + + [ Eric Piel ] + + * ACPI: Allow custom DSDT tables to be loaded from initramfs + + [ Kees Cook ] + + * AppArmor: Smack VFS patches + + [ Mario Limonciello ] + + * Work around ACPI corruption upon suspend on some Dell machines. + - LP: #183033 + + [ Tim Gardner ] + + * Export usbhid_modify_dquirk for LBM module bcm5974 + - LP: #250838 + * VIA - Add VIA DRM Chrome9 3D engine + - LP: #251862 + * Define TRUE/FALSE for VIA DRM driver. + + -- Ben Collins Tue, 15 Jul 2008 12:51:39 -0400 + +linux (2.6.26-4.11) intrepid; urgency=low + + [ Ben Collins ] + + * config: Enable bcm5974 driver in all configs + + [ 2.6.26-4.10 ] + + [ Amit Kucheria ] + + * Fix typo in GSPCA Makefile and make it compile + + [ Ben Collins ] + + * ubuntu: Remove UVC driver in favor of in-kernel one (-rc9) + * config: Updates for -rc9 + * ubuntu: Add acx, prism2_usb wireless drivers + * config: Enable prism2_usb and acx drivers. + * ubuntu: Add at76 driver to build + * config: Enable at76_usb driver. + * iscsitarget: Fix prototype for bi_end_io callback. + * acx: Fix section type mismatch warnings + * fsam7400: Add sw kill switch driver + * config: Enable fsam7400 driver + * qc-usb: Added new driver + * config: Enable qc-usb driver + * drbd: Remove built-in connector usage + * drbd: Do not define idx/val for connector here + * connector.h: Add idx/val for drbd + * bcm5974: Added new driver + + [ Kees Cook ] + + * SAUCE: [AppArmor] merge with upstream subversion r1291 + * SAUCE: [AppArmor] fix typo in selinux_inode_link + * SAUCE: [AppArmor] aufs patches + + [ Michael Frey (Senior Manager, MID ] + + * SAUCE: Send HCI_RESET for Broadcomm 2046 + - LP: #241749 + + [ Tim Gardner ] + + * SAUCE: Medion Akoya Mini E1210 + + [ Upstream Kernel Changes ] + + * Revert "BAST: Remove old IDE driver" + * ARM: OMAP: DMA: Don't mark channel active in omap_enable_channel_irq + * ARM: OMAP: Correcting the gpmc prefetch control register address + * debugobjects: fix lockdep warning + * [ARM] 5115/1: pxafb: fix ifdef for command line option handling + * [ARM] 5116/1: pxafb: cleanup and fix order of failure handling + * [ARM] 5109/1: Mark rtc sa1100 driver as wakeup source before + registering it + * [ARM] Export dma_sync_sg_for_device() + * fix cgroup-inflicted breakage in block_dev.c + * [patch for 2.6.26 2/4] vfs: utimensat(): be consistent with utime() for + immutable and append-only files + * [patch for 2.6.26 1/4] vfs: utimensat(): ignore tv_sec if tv_nsec == + UTIME_OMIT or UTIME_NOW + * [patch for 2.6.26 3/4] vfs: utimensat(): fix error checking for + {UTIME_NOW,UTIME_OMIT} case + * [patch for 2.6.26 4/4] vfs: utimensat(): fix write access check for + futimens() + * [patch 1/4] vfs: path_{get,put}() cleanups + * [patch 2/4] fs: make struct file arg to d_path const + * [patch 3/4] vfs: fix ERR_PTR abuse in generic_readlink + * [patch 4/4] flock: remove unused fields from file_lock_operations + * [patch 3/3] vfs: make d_path() consistent across mount operations + * [patch 1/3] vfs: dcache sparse fixes + * [patch 2/3] vfs: dcache cleanups + * udf: Fix regression in UDF anchor block detection + * [SCSI] ses: Fix timeout + * netfilter: ip6table_mangle: don't reroute in LOCAL_IN + * [SCSI] esp: Fix OOPS in esp_reset_cleanup(). + * kernel/audit.c: nlh->nlmsg_type is gotten more than once + * audit: fix kernel-doc parameter notation + * remove useless argument type in audit_filter_user() + * Blackfin arch: fix bug - kernel boot fails when Spinlock and rw-lock + debugging enabled + * Blackfin arch: fix up section mismatch warning + * mac80211: implement EU regulatory domain + * b43: Do not return TX_BUSY from op_tx + * b43legacy: Do not return TX_BUSY from op_tx + * b43: Fix possible MMIO access while device is down + * b43legacy: Fix possible NULL pointer dereference in DMA code + * rt2x00: Fix unbalanced mutex locking + * iwlwifi: improve scanning band selection management + * [SCSI] esp: tidy up target reference counting + * [ARM] 5117/1: pxafb: fix __devinit/exit annotations + * thermal: Create CONFIG_THERMAL_HWMON=n + * ACPI: don't walk tables if ACPI was disabled + * dock: bay: Don't call acpi_walk_namespace() when ACPI is disabled. + * x86: shift bits the right way in native_read_tscp + * x86: section/warning fixes + * V4L/DVB (8004): Fix INPUT dependency at budget-ci + * V4L/DVB (8005): Fix OOPS if frontend is null + * V4L/DVB (8007): cx18/cx25840: the S-Video LUMA input can use all + In1-In8 inputs + * V4L/DVB (8008): cx18: remove duplicate audio and video input enums + * V4L/DVB (8010): em28xx: Properly register extensions for already + attached devices + * V4L/DVB (8011): em28xx: enable DVB for HVR-900 + * V4L/DVB (8012): gl861: sleep a little to avoid I2C errors + * V4L/DVB (8013): gl861: remove useless identify_state + * V4L/DVB (8015): gl861: replace non critical msleep(0) with msleep(1) to + be on the safe side + * V4L/DVB (8017): Ensure em28xx extensions only get run against devs that + support them + * V4L/DVB (8018): Add em2860 chip ID + * V4L/DVB (8020): Fix callbacks functions of saa7134_empress + * V4L/DVB (8022): saa7134: fix race between opening and closing the + device + * V4L/DVB (8026): Avoids an OOPS if dev struct can't be successfully + recovered + * V4L/DVB (8027): saa7134: Avermedia A700: only s-video and composite + input are working + * V4L/DVB (8028): Improve error messages for tda1004x attach + * V4L/DVB (8029): Improve error message at tda1004x_attach + * V4L/DVB (8034): tda18271: fix IF notch frequency handling + * V4L/DVB (8035): tda18271: dont touch EB14 if rf_cal lookup is out of + range + * V4L/DVB (8036): tda18271: toggle rf agc speed mode on TDA18271HD/C2 + only + * V4L/DVB (8037): tda18271: ensure that the thermometer is off during + channel configuration + * V4L/DVB (8039): pxa-camera: fix platform_get_irq() error handling. + * V4L/DVB (8040): soc-camera: remove soc_camera_host_class class + * V4L/DVB (8042): DVB-USB UMT-010 channel scan oops + * V4L/DVB (8043): au0828: add support for additional USB device id's + * V4L/DVB (8044): au8522: tuning optimizations + * V4L/DVB (8048): saa7134: Fix entries for Avermedia A16d and Avermedia + E506 + * V4L/DVB (8061): cx18: only select tuner / frontend modules if + !DVB_FE_CUSTOMISE + * V4L/DVB (8063): cx18: Fix unintended auto configurations in + cx18-av-core + * V4L/DVB (8066): cx18: Fix audio mux input definitions for HVR-1600 Line + In 2 and FM radio + * V4L/DVB (8067): cx18: Fix firmware load for case when digital capture + happens first + * V4L/DVB (8068): cx18: Add I2C slave reset via GPIO upon initialization + * V4L/DVB (8069): cx18: Fix S-Video and Compsite inputs for the Yuan + MPC718 and enable card entry + * V4L/DVB (8071): tda10023: Fix possible kernel oops during + initialisation + * V4L/DVB (8073): av7110: Catch another type of ARM crash + * V4L/DVB (8074): av7110: OSD transfers should not be interrupted + * V4L/DVB (8075): stv0299: Uncorrected block count and bit error rate + fixed + * V4L/DVB (8092): videodev: simplify and fix standard enumeration + * V4L/DVB (8096): au8522: prevent false-positive lock status + * V4L/DVB (8097): xc5000: check device hardware state to determine if + firmware download is needed + * V4L/DVB (8100): V4L/vivi: fix possible memory leak in vivi_fillbuff + * V4L/DVB (8108): Fix open/close race in saa7134 + * s2io: fix documentation about intr_type + * tc35815: Mark carrier-off before starting PHY + * tc35815: Fix receiver hangup on Rx FIFO overflow + * ixgbe: fix EEH recovery during reset on PPC + * igb: fix EEH recovery during reset on PPC + * e1000e: fix EEH recovery during reset on PPC + * pcnet_cs, axnet_cs: clear bogus interrupt before request_irq + * drivers/net/r6040.c: Eliminate double sizeof + * ipg: fix jumbo frame compilation + * ipg: use NULL, not zero, for pointers + * [netdrvr] 3c59x: remove irqs_disabled warning from local_bh_enable + * [netdrvr] netxen: fix netxen_pci_tbl[] breakage + * e100: Do pci_dma_sync after skb_alloc for proper operation on ixp4xx + * e1000: only enable TSO6 via ethtool when using correct hardware + * [netdrvr] Fix IOMMU overflow checking in s2io.c + * qla3xxx: Hold RTNL while calling dev_close() + * Hold RTNL while calling dev_close() + * sata_uli: hardreset is broken + * rt2x00: Fix lock dependency errror + * prism: islpci_eth.c endianness fix + * mac80211: fix an oops in several failure paths in key allocation + * firewire: fw-sbp2: fix parsing of logical unit directories + * kbuild: fix a.out.h export to userspace with O= build. + * Ensure interrupted recovery completed properly (v1 metadata plus + bitmap) + * Don't acknowlege that stripe-expand is complete until it really is. + * Fix error paths if md_probe fails. + * hamradio: remove unused variable + * tcp: calculate tcp_mem based on low memory instead of all memory + * tcp: fix for splice receive when used with software LRO + * af_unix: fix 'poll for write'/connected DGRAM sockets + * netdevice: Fix typo of dev_unicast_add() comment + * pkt_sched: ERR_PTR() ususally encodes an negative errno, not positive. + * pkt_sched: Remove CONFIG_NET_SCH_RR + * include/linux/netdevice.h: don't export MAX_HEADER to userspace + * tcp: /proc/net/tcp rto,ato values not scaled properly (v2) + * netlink: Fix some doc comments in net/netlink/attr.c + * CONNECTOR: add a proc entry to list connectors + * inet fragments: fix race between inet_frag_find and + inet_frag_secret_rebuild + * net/inet_lro: remove setting skb->ip_summed when not LRO-able + * netlabel: Fix a problem when dumping the default IPv6 static labels + * ipv6 route: Convert rt6_device_match() to use RT6_LOOKUP_F_xxx flags. + * sched: fix cpu hotplug + * Fix and clean top .gitignore + * x86: fix cpu hotplug crash + * ptrace GET/SET FPXREGS broken + * Input: add KEY_MEDIA_REPEAT definition + * Input: fix locking in force-feedback core + * [ARM] 5131/1: Annotate platform_secondary_init with trace_hardirqs_off + * ide: fix /proc/ide/ide?/mate reporting + * netfilter: nf_conntrack_tcp: fixing to check the lower bound of valid + ACK + * textsearch: fix Boyer-Moore text search bug + * hostap: don't report useless WDS frames by default + * hostap: fix sparse warnings + * mac80211: don't accept WEP keys other than WEP40 and WEP104 + * V4L/DVB (8145a): USB Video Class driver + * [IA64] Bugfix for system with 32 cpus + * [IA64] export account_system_vtime + * sched: fix divide error when trying to configure rt_period to zero + * x86: fix NODES_SHIFT Kconfig range + * block: Fix the starving writes bug in the anticipatory IO scheduler + * Properly notify block layer of sync writes + * rcu: fix hotplug vs rcu race + * I2C: S3C2410: Check ACK on byte transmission + * I2C: S3C2410: Fixup error codes returned rom a transfer. + * I2C: S3C2410: Add MODULE_ALIAS() for s3c2440 device. + * PCI: Restrict VPD read permission to root + * powerpc/bootwrapper: update for initrd with simpleImage + * i2c: Documentation: fix device matching description + * i2c: Fix bad hint about irqs in i2c.h + * powerpc/legacy_serial: Bail if reg-offset/shift properties are present + * powerpc/mpc5200: Fix lite5200b suspend/resume + * ipv4: fix sysctl documentation of time related values + * net-sched: change tcf_destroy_chain() to clear start of filter list + * net-sched: fix filter destruction in atm/hfsc qdisc destruction + * netlink: Unneeded local variable + * net: Tyop of sk_filter() comment + * netdevice: Fix wrong string handle in kernel command line parsing + * net: fib_rules: fix error code for unsupported families + * dm crypt: use cond_resched + * V4L/DVB (8178): uvc: Fix compilation breakage for the other drivers, if + uvc is selected + * PCI: Limit VPD read/write lengths for Broadcom 5706, 5708, 5709 rev. + * PCI: acpiphp: cleanup notify handler on all root bridges + * drivers/input/ff-core.c needs + * DRM/i915: only use tiled blits on 965+ + * tty: Fix inverted logic in send_break + * x86: fix Intel Mac booting with EFI + * arch/x86/mm/init_64.c: early_memtest(): fix types + * 9p: fix O_APPEND in legacy mode + * slub: Do not use 192 byte sized cache if minimum alignment is 128 byte + * Do not overwrite nr_zones on !NUMA when initialising zlcache_ptr + * [MIPS] IP32: Fix unexpected irq 71 + * [MIPS] IP22: Fix crashes due to wrong L1_CACHE_BYTES + * [MIPS] cevt-txx9: Reset timer counter on initialization + * hrtimer: prevent migration for raising softirq + * svcrpc: fix handling of garbage args + * OHCI: Fix problem if SM501 and another platform driver is selected + * USB: fix cdc-acm resume() + * USB: ehci - fix timer regression + * USB: ohci - record data toggle after unlink + * USB: mass storage: new id for US_SC_CYP_ATACB + * sisusbvga: Fix oops on disconnect. + * USB: New device ID for ftdi_sio driver + * USB: fix interrupt disabling for HCDs with shared interrupt handlers + * USB: don't lose disconnections during suspend + * USB: another option device id + * USB: add a pl2303 device id + * USB: fix Oops on loading ipaq module since 2.6.26 + * USB: adding comment for ipaq forcing number of ports + * [MIPS] Fix bug in atomic_sub_if_positive. + * xen: fix address truncation in pte mfn<->pfn conversion + * sata_sil24: add DID for another adaptec flavor + * ahci: always clear all bits in irq_stat + * libata-sff: improve HSM violation reporting + * sata_mv: safer logic for limit_warnings + * Update maintainers for powerpc + * Christoph has moved + * mm: dirty page accounting vs VM_MIXEDMAP + * rtc: rtc_read_alarm() handles wraparound + * firmware: fix the request_firmware() dummy + * serial: fix serial_match_port() for dynamic major tty-device numbers + * get_user_pages(): fix possible page leak on oom + * rtc-x1205: Fix alarm set + * rtc: fix CMOS time error after writing /proc/acpi/alarm + * pci: VT3336 can't do MSI either + * Miguel Ojeda has moved + * ext3: add missing unlock to error path in ext3_quota_write() + * ext4: add missing unlock to an error path in ext4_quota_write() + * reiserfs: add missing unlock to an error path in reiserfs_quota_write() + * ecryptfs: remove unnecessary mux from ecryptfs_init_ecryptfs_miscdev() + * lib: taint kernel in common report_bug() WARN path. + * gpio: pca953x (i2c) handles max7310 too + * fsl_diu_fb: fix build with CONFIG_PM=y, plus fix some warnings + * Update taskstats-struct document for scaled time accounting + * cciss: fix regression that no device nodes are created if no logical + drives are configured. + * delay accounting: maintainer update + * Doc*/kernel-parameters.txt: fix stale references + * hdaps: add support for various newer Lenovo thinkpads + * mn10300: export certain arch symbols required to build allmodconfig + * mn10300: provide __ucmpdi2() for MN10300 + * Introduce rculist.h + * man-pages is supported + * ntfs: update help text + * add kernel-doc for simple_read_from_buffer and memory_read_from_buffer + * w100fb: do not depend on SHARPSL + * w100fb: add 80 MHz modeline + * MFD maintainer + * cgroups: document the effect of attaching PID 0 to a cgroup + * spi: fix the read path in spidev + * doc: doc maintainers + * security: filesystem capabilities: fix fragile setuid fixup code + * security: filesystem capabilities: fix CAP_SETPCAP handling + * Alpha Linux kernel fails with inconsistent kallsyms data + * cpusets: document proc status cpus and mems allowed lists + * MAINTAINERS: update the email address of Andreas Dilger + * cciss: read config to obtain max outstanding commands per controller + * olpc: sdhci: add quirk for the Marvell CaFe's vdd/powerup issue + * olpc: sdhci: add quirk for the Marvell CaFe's interrupt timeout + * cpumask: introduce new APIs + * mm: switch node meminfo Active & Inactive pages to Kbytes + * Update MAINTAINERS file for the TPM device driver + * devcgroup: fix odd behaviour when writing 'a' to devices.allow + * doc: document the relax_domain_level kernel boot argument + * mmc: don't use DMA on newer ENE controllers + * mempolicy: mask off internal flags for userspace API + * x86 ACPI: normalize segment descriptor register on resume + * x86 ACPI: fix resume from suspend to RAM on uniprocessor x86-64 + * softlockup: print a module list on being stuck + * ide: fix hwif->gendev refcounting + * ide: ide_unregister() warm-plug bugfix + * ide: ide_unregister() locking bugfix + * ahci: give another shot at clearing all bits in irq_stat + * Fix clear_refs_write() use of struct mm_walk + * Move _RET_IP_ and _THIS_IP_ to include/linux/kernel.h + * Fix pagemap_read() use of struct mm_walk + * Linux 2.6.26-rc9 + * Revert "USB: don't explicitly reenable root-hub status interrupts" + * Revert "PCI: Correct last two HP entries in the bfsort whitelist" + * iwlwifi: fix incorrect 5GHz rates reported in monitor mode + * iwlwifi: drop skb silently for Tx request in monitor mode + * libertas: support USB persistence on suspend/resume (resend) + * tcp: net/ipv4/tcp.c needs linux/scatterlist.h + * tcp: fix a size_t < 0 comparison in tcp_read_sock + * bridge: fix use-after-free in br_cleanup_bridges() + * Add missing skb->dev assignment in Frame Relay RX code + * forcedeth: fix lockdep warning on ethtool -s + * ehea: fix might sleep problem + * ehea: add MODULE_DEVICE_TABLE + * ehea: fix race condition + * ehea: Access iph->tot_len with correct endianness + * pasemi_mac: Access iph->tot_len with correct endianness + * ibm_newemac: Fixes kernel crashes when speed of cable connected changes + * ibm_newemac: Fixes entry of short packets + * fs_enet: restore promiscuous and multicast settings in restart() + * can: add sanity checks + * x86: KVM guest: Add memory clobber to hypercalls + * KVM: IOAPIC: Fix level-triggered irq injection hang + * [SCSI] erase invalid data returned by device + * pxamci: fix byte aligned DMA transfers + * vsprintf: split out '%s' handling logic + * vsprintf: split out '%p' handling logic + * vsprintf: add infrastructure support for extended '%p' specifiers + * vsprintf: add support for '%pS' and '%pF' pointer formats + * powerpc: Fix unterminated of_device_id array in legacy_serial.c + * [UML] fix gcc ICEs and unresolved externs + * ocfs2/dlm: Fixes oops in dlm_new_lockres() + * hostap_cs: correct poor NULL checks in suspend/resume routines + * drivers/net/wireless/iwlwifi/iwl-3945.c Fix type issue on 64bit + * mac80211: move netif_carrier_on to after + ieee80211_bss_info_change_notify + * mac80211: Only flush workqueue when last interface was removed + * zd1211rw: add ID for AirTies WUS-201 + * ssb-pcicore: Fix IRQ-vector init on embedded devices + * mac80211: don't report selected IBSS when not found + * crypto: tcrypt - Fix memory leak in test_cipher + * sctp: Mark the tsn as received after all allocations finish + * [S390] protect _PAGE_SPECIAL bit against mprotect + * irda: via-ircc proper dma freeing + * irda: New device ID for nsc-ircc + * irda: Fix netlink error path return value + * [SCSI] mptspi: fix oops in mptspi_dv_renegotiate_work() + * Correct hash flushing from huge_ptep_set_wrprotect() + * ide: add __ide_default_irq() inline helper + * palm_bk3710: fix IDECLK period calculation + * it8213: fix return value in it8213_init_one() + * [MIPS] Atlas, decstation: Fix section mismatches triggered by + defconfigs + * [MIPS] Fix 32bit kernels on R4k with 128 byte cache line size + * NFS: Fix readdir cache invalidation + * SUNRPC: Fix a double-free in rpcbind + * SUNRPC: Fix an rpcbind breakage for the case of IPv6 lookups + * reiserfs: discard prealloc in reiserfs_delete_inode + * Fix broken fix for fsl-diu-db + * RDMA/cxgb3: Fix regression caused by class_device -> device conversion + * ipv6: fix race between ipv6_del_addr and DAD timer + * sctp: Add documentation for sctp sysctl variable + * kernel/printk.c: Made printk_recursion_bug_msg static. + * powerpc: Add missing reference to coherent_dma_mask + * rc80211_pid: Fix fast_start parameter handling + * rt2x00: Disable synchronization during initialization + * zd1211rw: stop beacons on remove_interface + * libertas: fix memory alignment problems on the blackfin + * netfilter: nf_conntrack_tcp: fix endless loop + * netfilter: nf_nat_snmp_basic: fix a range check in NAT for SNMP + * md: ensure all blocks are uptodate or locked when syncing + * sched: fix cpu hotplug + * x86: fix /dev/mem compatibility under PAT + * crypto: chainiv - Invoke completion function + * ocfs2: Fix flags in ocfs2_file_lock + * kernel/kprobes.c: Made kprobe_blacklist static. + * arch/x86/kernel/.gitignore: Added vmlinux.lds to .gitignore file + because it shouldn't be tracked. + * ftrace: Documentation + * Fix PREEMPT_RCU without HOTPLUG_CPU + * sched: fix cpu hotplug, cleanup + * exec: fix stack excutability without PT_GNU_STACK + * slub: Fix use-after-preempt of per-CPU data structure + * Documentation: clarify tcp_{r,w}mem sysctl docs + * ip: sysctl documentation cleanup + * tcp: correct kcalloc usage + * ipv4: fib_trie: Fix lookup error return + * netlabel: netlink_unicast calls kfree_skb on error path by itself + * ipv6: missed namespace context in ipv6_rthdr_rcv + * xfrm: Add a XFRM_STATE_AF_UNSPEC flag to xfrm_usersa_info + * tun: Persistent devices can get stuck in xoff state + * tpm: add Intel TPM TIS device HID + * rapidio: fix device reference counting + * Fix name of Russell King in various comments + * rtc: fix reported IRQ rate for when HPET is enabled + * libata-acpi: filter out DIPM enable + * Added Targa Visionary 1000 IDE adapter to pata_sis.c + * libata-acpi: don't call sleeping function from invalid context + * Fix reference counting race on log buffers + * [SCSI] ipr: Fix HDIO_GET_IDENTITY oops for SATA devices + * IPMI: return correct value from ipmi_write + * x86: fix ldt limit for 64 bit + * [SCSI] fusion: default MSI to disabled for SPI and FC controllers + * [SCSI] bsg: fix oops on remove + * drivers/char/pcmcia/ipwireless/hardware.c fix resource leak + * drivers/isdn/i4l/isdn_common.c fix small resource leak + * fbdev: bugfix for multiprocess defio + * serial8250: sanity check nr_uarts on all paths. + * ov7670: clean up ov7670_read semantics + * rtc-fm3130: fix chip naming + * rtc-pcf8563: add chip id + * OProfile kernel maintainership changes + * frv: fix irqs_disabled() to return an int, not an unsigned long + * cifs: fix inode leak in cifs_get_inode_info_unix + * cifs: fix wksidarr declaration to be big-endian friendly + * cpusets, hotplug, scheduler: fix scheduler domain breakage + * Documentation/HOWTO: correct wrong kernel bugzilla FAQ URL + * devcgroup: always show positive major/minor num + * devcgroup: fix permission check when adding entry to child cgroup + * Linux 2.6.26 + + -- Ben Collins Mon, 14 Jul 2008 13:41:50 -0400 + +linux (2.6.26-3.9) intrepid; urgency=low + + * abi: Add dca and ioatdma to modules.ignore + + [ 2.6.26-3.8 ] + + [ Ben Collins ] + + * ubuntu: Add heci driver 3.2.0.24 + * ubuntu: Add heci to kconfig/kbuild + * config: Enable heci module on all flavours + * dm-bbr: Update to get it to compile with 2.6.26 + * config: Enable dm-bbr + * ubuntu: Add some media drivers + * config: Enable misc media drivers + * udeb: Switch to uvesafb in fb-modules + * abi: Add more modules to ignore (known) + + [ 2.6.26-3.7 ] + + [Amit Kucheria] + + * SAUCE: make fc transport removal of target configurable + - LP: #163075 + * SAUCE: pm: Config option to disable handling of console during + suspend/resume + + [Ben Collins] + + * SAUCE: input/mouse/alps: Do not call psmouse_reset() for alps + * SAUCE: irda: Default to dongle type 9 on IBM hardware + * SAUCE: tulip: Let dmfe handle davicom on non-sparc + * SAUCE: tulip: Define ULI PCI ID's + * SAUCE: version: Implement version_signature proc file. + * build: Cleanup arches + * build: Remove remnants of unused binary-custom infrastructure + * build: Remove disable_d_i (not needed) and cleanup ppa build stuff + * ubuntu: New modules, acer-acpi + * build: Remove -virtual, and rebuild configs + * ubuntu: Add drbd module + * acer-acpi: Fix makefile + * x86/Kconfig: Fix missing quote for ubuntu Kconfig source + * ubuntu: Add iscsitarget module + * ubuntu: Added Amiga FS driver + * ubuntu: Add squashfs driver + * ubuntu: Remove asfs (Amiga FS). Need to be in linux-ports instead + * squashfs: Move headers to real include directory + * build/configs: The Great Config Consistency Check of 2008 + * ubuntu: Move third-party includes to ubuntu/include + * ubuntu: Add aufs module + * ubuntu: Added atl2 driver + * ubuntu: Add dm-radi4-5 driver + * build: Add CONFIG_DEBUG_SECTION_MISMATCH=y to get old style warnings + from build + * ubuntu/Makefile: Fixup dm-raid4-5 and add kludge for kbuild + * squashfs: Fixes for VFS changes + * ubuntu/dm-raid4-5: Fixups for moved/renamed headers/functions in core + md + * ubuntu: Add ndiswrapper driver + * d-i: Update module listings + * build: Disable xd block device (ancient) + * ndiswrapper: Fixup makefile + * d-i: Remove efi-modules. The only module, efivars, is built-in + * build: Remove install-source, obsolete and caused build failure + * Ubuntu-2.6.26-1.3 + * build: linux-doc rules got broken when disabling html side. Fixed now. + * Ubuntu-2.6.26-1.4 + * x86: Update to -rc6 allows CONFIG_PCI_OLPC to work with PCI_GOANY + * d-i: Make virtio-ring optional (it's built-in on i386) + * Ubuntu-2.6.26-1.4 + * Ubuntu-2.6.26-1.5 + * config: Enable DVB devices + * ubuntu/aufs: Make aufs a bool config, since it needs to be built-in + * config: Build aufs into the kernels + * build: Fix arguments passed to link-headers script + * config: Disable early printk + * d-i: Move isofs to storage-core and kill st (scsi tape) from list + * config: Enable non-promiscuous access to /dev/mem + * x86: Add option to disable decompression info messages + * config: Enable no-bz-chatter config options + * build: Re-add linux-source package + * d-i: Re-add socket-modules. Accidentally removed + - LP: #241295 + * Ubuntu-2.6.26-2.6 + * Use makedumpfile to generate a vmcoreinfo file. + * build: Build-Depend on makedumpfile for vmcoreinfo generation + * build: Remove debug print from git-ubuntu-log + * Updated configs for -rc7 + * build: postinst, do not call depmod with -F + * config: Enable rtc-cmos as a built-in driver. + * control: Provide ndiswrapper-modules-1.9 + * build: Generate vmcoreinfo in image build for crashdumps without debug + image + * config: Disable vesafb, since we'll prefer uvesafb + * build: Copy uvesafb module to initrd mod directory + * abi-check: New, more robust script + * config: Enable heap randomization by default + * abi-check: Cleanup output and call with perl (not $SHELL) + * abi: Ignore missing vesafb (known) + * config: Disable pcspkr (in favor of snd-pcsp) + * swap: Add notify_swap_entry_free callback for compcache + * compcache: Added ram backed compressed swap module + * ubuntu: Enable kbuild and kconfig for compcache + * config: Enable compcache and tlsf allocator as modules + * config: Updated for -rc8. Disables XEN on i386 + * config: Switch i386-server to 64G, enable PAE, 64-bit res, and XEN + * ubuntu: Add misc drivers from hardy lum + * ubuntu: Enable build of misc/ subdir + * config: Enable misc drivers + * aufs: Fix warning about single non-string-literal arg to printf style + function + * drivers: Remove some duplicate device entries in various modules + * config: Disable some duplicate drivers + * keyspan: Remove duplicate device ID's + * check-aliases: Cleanup output, and fix rolling checks + * ubuntu: Disable dm-bbr for now + * dm-bbr: First cut at forward portiong. Still needs work. + * ubuntu: Disable dm-bbr in kbuild/kconfig + + [Chuck Short] + + * SAUCE: ata: blacklist FUJITSU MHW2160BH PL + - LP: #175834 + * SAUCE: [USB]: add ASUS LCM to the blacklist + + [Colin Ian King] + + * SAUCE: airprime.c supports more devices + - LP: #208250 + * SAUCE: Enable speedstep for sonoma processors. + - LP: #132271 + * Add dm-loop + * Add dm-loop BOM + + [Kyle McMartin] + + * SAUCE: fix orinoco_cs oops + + [Mario Limonciello] + + * SAUCE: Enable Reset and SCO workaround on Dell 410 BT adapter + + [Matthew Garrett] + + * SAUCE: hostap: send events on data interface as well as master + interface + + [Phillip Lougher] + + * SAUCE: r8169: disable TSO by default for RTL8111/8168B chipsets. + + [Stefan Bader] + + * SAUCE: Export dm_disk function of device-mapper + * SAUCE: Restore VT fonts on switch + * SAUCE: Always use SCO protocol (disable eSCO support) Bug: #39414 + * SAUCE: mmc: Increase power_up deleay to fix TI readers OriginalAuthor: + Pascal Terjan Bug: #137686 + * SAUCE: Add blacklist support to fix Belkin bluetooth dongle. Bug: + #140511 + * SAUCE: Lower warning level of pci resource allocation messages. Bug: + 159241 + * SAUCE: Lower message level for PCI memory and I/O allocation. + - LP: #159241 + * Modify log generation to catch bug numbers when adding with git-am. + + [Tim Gardner] + + * Added the debian directory. Ignore: yes + * Add support for UBUNTUINCLUDE Ignore: yes + * LUM headers go in /usr/src Ignore: yes + * First pass at 2.6.25 configs Ignore: yes + * i386 -generic builds. Ignore: yes + * SAUCE: Increase CONFIG_IDE_MAX_HWIFS to 8 (from 4) + * SAUCE: Add extra headers to linux-libc-dev OriginalAuthor: Soren Hansen + OriginalLocation: + https://lists.ubuntu.com/archives/kernel-team/2007-November/001891.html + * Set CONFIG_DEVKMEM=n Ignore: yes + * Enabled ALSA and CGROUPS for i386 Ignore: yes + * Enabled amd64 configs. Ignore: yes + * CONFIG_STANDALONE=n Ignore: yes + * CONFIG_BLK_DEV_4DRIVES=n for i386 Ignore: yes + * CONFIG: CONFIG_DEFAULT_RELATIME=y for all flavours. Ignore: yes + * Set CONFIG_EDD_OFF=y Ignore: yes + * SAUCE: Blacklist Bluetooth Dell Wireless 370 for SCO MTU + OriginalAuthor: Mario Limonciello Bug: + #209715 + * SAUCE: Catch nonsense keycodes and silently ignore + * SAUCE: frame buffer regression - screen blank except for blinking + cursor after fbcon vtswitch OriginalAuthor: Matthew Garrett + Bug: #201591 + * SAUCE: Added support for HDAPS on various ThinkPads from Lenovo and IBM + OriginalAuthor: Klaus S. Madsen + OriginalAuthor: Chuck Short + * SAUCE: Guest OS does not recognize a lun with non zero target id on + Vmware ESX Server + * SAUCE: orinoco_cs.ko missing + * Set CONFIG_FB_VESA=m for i386/amd64 Ignore: yes + * Set CONFIG_PM_DISABLE_CONSOLE=y for all flavours Ignore: yes + * Thorough review of amd64 -generic config Ignore: yes + * Build PPA packages for Hardy until the Intrepid archive is opened. + * Deleted obsolete flavours Ignore: yes + * Don't build docs for PPA Ignore: yes + * Build all standard packages in PPA. Ignore: yes + * Remove duplicate USB ids + * SAUCE: DVB-USB UMT-010 driver oops on install Bug: #115284 + * Update configs after rebase to 2.6.26-rc1 Ignore: yes + * Update configs after rebase Ignore: yes + * Disable V4L until the build issues get ironed out. Ignore: yes + * Update configs after rebase. Ignore: yes + * Another device enable pass Ignore: yes + * Update configs after merge. Ignore: yes + * SAUCE: fn key doesn't work in hardy with macbook pro fourth generation + (4,1) + - LP: #207127 + * Enabled CONFIG_CIFS_DFS_UPCALL=y and CONFIG_CIFS_UPCALL=y + - LP: #236830 + + [Upstream Kernel Changes] + + * Revert "[WATCHDOG] hpwdt: Add CFLAGS to get driver working" + * mac80211: detect driver tx bugs + * hwmon: (lm85) Fix function RANGE_TO_REG() + * hwmon: (adt7473) Initialize max_duty_at_overheat before use + * hwmon: Update the sysfs interface documentation + * hwmon: (abituguru3) Identify Abit AW8D board as such + * hwmon: (w83791d) new maintainer + * hwmon: (abituguru3) update driver detection + * hwmon: (lm75) sensor reading bugfix + * ipv6: Remove options header when setsockopt's optlen is 0 + * ipv6: Drop packets for loopback address from outside of the box. + * sched: rt: dont stop the period timer when there are tasks wanting to + run + * sched: fix wait_for_completion_timeout() spurious failure under heavy + load + * x86: fix NULL pointer deref in __switch_to + * xen: Use wmb instead of rmb in xen_evtchn_do_upcall(). + * xen: mask unwanted pte bits in __supported_pte_mask + * xen: don't drop NX bit + * sched: refactor wait_for_completion_timeout() + * Ext4: Fix online resize block group descriptor corruption + * [IA64] SN2: security hole in sn2_ptc_proc_write + * alpha: fix module load failures on smp (bug #10926) + * alpha: link failure fix + * alpha: fix compile failures with gcc-4.3 (bug #10438) + * alpha: resurrect Cypress IDE quirk + * pppoe: warning fix + * sctp: Make sure N * sizeof(union sctp_addr) does not overflow. + * netns: Don't receive new packets in a dead network namespace. + * Add return value to reserve_bootmem_node() + * Slab: Fix memory leak in fallback_alloc() + * Fix performance regression on lmbench select benchmark + * ALSA: aw2 - Fix Oops at initialization + * ALSA: sb - Fix wrong assertions + * futexes: fix fault handling in futex_lock_pi + * IB/mthca: Clear ICM pages before handing to FW + * tty_driver: Update required method documentation + * removed unused var real_tty on n_tty_ioctl() + * Fix ZERO_PAGE breakage with vmware + * mm: fix race in COW logic + * NFS: Reduce the NFS mount code stack usage. + * NFS: Fix filehandle size comparisons in the mount code + * NFS: nfs_updatepage(): don't mark page as dirty if an error occurred + * alpha: fix compile error in arch/alpha/mm/init.c + * KVM: Fix race between timer migration and vcpu migration + * KVM: close timer injection race window in __vcpu_run + * KVM: MMU: Fix rmap_write_protect() hugepage iteration bug + * KVM: MMU: large page update_pte issue with non-PAE 32-bit guests + (resend) + * KVM: MMU: Fix oops on guest userspace access to guest pagetable + * KVM: ioapic: fix lost interrupt when changing a device's irq + * KVM: VMX: Fix host msr corruption with preemption enabled + * [GFS2] BUG: unable to handle kernel paging request at ffff81002690e000 + * xen: remove support for non-PAE 32-bit + * kgdb: documentation update - remove kgdboe + * kgdb: sparse fix + * [IA64] Fix boot failure on ia64/sn2 + * [IA64] Handle count==0 in sn2_ptc_proc_write() + * [IA64] Eliminate NULL test after alloc_bootmem in iosapic_alloc_rte() + * [GFS2] fix gfs2 block allocation (cleaned up) + * x86: Add structs and functions for paravirt clocksource + * x86: Make xen use the paravirt clocksource structs and functions + * KVM: Make kvm host use the paravirt clocksource structs + * x86: KVM guest: Use the paravirt clocksource structs and functions + * KVM: Remove now unused structs from kvm_para.h + * enable bus mastering on i915 at resume time + * Linux 2.6.26-rc8 + * # Ubuntu external driver commit. + * # Ubuntu commit template. + + -- Ben Collins Sat, 21 Jun 2008 09:05:15 -0400 + +linux (2.6.26-2.6) intrepid; urgency=low + + [Ben Collins] + + * Revert "SAUCE: Export symbols for aufs (in lum) (not needed) + * config: Enable DVB devices + * ubuntu/aufs: Make aufs a bool config, since it needs to be built-in + * config: Build aufs into the kernels + * build: Fix arguments passed to link-headers script + * config: Disable early printk + * d-i: Move isofs to storage-core and kill st (scsi tape) from list + * config: Enable non-promiscuous access to /dev/mem + * x86: Add option to disable decompression info messages + * config: Enable no-bz-chatter config options + * build: Re-add linux-source package + * d-i: Re-add socket-modules. Accidentally removed + - LP: #241295 + + [Colin Ian King] + + * Add dm-loop + + [Tim Gardner] + + * Revert "SAUCE: USB bluetooth device 0x0e5e:0x6622 floods errors to + syslog (merged upstream) + + -- Ben Collins Mon, 16 Jun 2008 10:56:01 -0400 + +linux (2.6.26-1.5) intrepid; urgency=low + + * d-i: Make virtio-ring optional (it's built-in on i386) + * Rebased on 2.6.26-rc6 + + [Ubuntu-2.6.26-1.4 Changes below] + + * build: linux-doc rules got broken when disabling html side. Fixed now. + + [Ubuntu-2.6.26-1.3 Changes below] + + * build: Remove install-source, obsolete and caused build failure + + [Ubuntu-2.6.26-1.2 Changes below] + + * Remove efi-modules from d-i module list (efivars is built-in). Caused a + build failure. + * Patch to arch/x86/xen/time.c to remove __divdi3 usage (build failure on + i386). + + [Ubuntu-2.6.26-1.1 Changes below] + + [Amit Kucheria] + + * SAUCE: make fc transport removal of target configurable + * SAUCE: Add AGP support for Radeon Mobility 9000 chipset + * SAUCE: pm: Config option to disable handling of console during + suspend/resume + + [Ben Collins] + + * SAUCE: input/mouse/alps: Do not call psmouse_reset() for alps + * SAUCE: irda: Default to dongle type 9 on IBM hardware + * SAUCE: tulip: Let dmfe handle davicom on non-sparc + * SAUCE: tulip: Define ULI PCI ID's + * SAUCE: version: Implement version_signature proc file. + * build: Remove remnants of unused binary-custom infrastructure + * mmc_block: Fix bad allocation on 64-bit (zero len array) + * ubuntu: New modules, acer-acpi + * build: Remove -virtual, and rebuild configs + * ubuntu: Add drbd module + * ubuntu: Add iscsitarget module + * ubuntu: Add squashfs driver + * build/configs: The Great Config Consistency Check of 2008 + * ubuntu: Add aufs module + * ubuntu: Added atl2 driver + * ubuntu: Add dm-radi4-5 driver + * build: Add CONFIG_DEBUG_SECTION_MISMATCH=y to get old style warnings + from build + * squashfs: Fixes for VFS changes + * ubuntu/dm-raid4-5: Fixups for moved/renamed headers/functions in core + md + * ubuntu: Add ndiswrapper driver + * d-i: Update module listings + + [Chuck Short] + + * SAUCE: ata: blacklist FUJITSU MHW2160BH PL + * SAUCE: [USB]: add ASUS LCM to the blacklist + + [Colin Ian King] + + * SAUCE: Enable speedstep for sonoma processors. + * SAUCE: airprime.c supports more devices + + [Kyle McMartin] + + * SAUCE: fix orinoco_cs oops + + [Mario Limonciello] + + * SAUCE: Enable Reset and SCO workaround on Dell 410 BT adapter + + [Matthew Garrett] + + * SAUCE: hostap: send events on data interface as well as master + interface + + [Phillip Lougher] + + * SAUCE: r8169: disable TSO by default for RTL8111/8168B chipsets. + + [Stefan Bader] + + * SAUCE: Export dm_disk function of device-mapper + * SAUCE: Restore VT fonts on switch + * SAUCE: Always use SCO protocol (disable eSCO support) Bug: #39414 + * SAUCE: mmc: Increase power_up deleay to fix TI readers + * SAUCE: Add blacklist support to fix Belkin bluetooth dongle. + * SAUCE: Lower warning level of pci resource allocation messages. + * SAUCE: Lower message level for PCI memory and I/O allocation. + - LP: #159241 + * Modify log generation to catch bug numbers when adding with git-am. + + [Tim Gardner] + + * SAUCE: hdaps module does not load on Thinkpad T61P + * SAUCE: Add extra headers to linux-libc-dev + * SAUCE: Export symbols for aufs (in lum). + * SAUCE: USB bluetooth device 0x0e5e:0x6622 floods errors to syslog + * SAUCE: Blacklist Bluetooth Dell Wireless 370 for SCO MTU + * SAUCE: Catch nonsense keycodes and silently ignore + * SAUCE: frame buffer regression - screen blank except for blinking + cursor after fbcon vtswitch + * SAUCE: Added support for HDAPS on various ThinkPads from Lenovo and IBM + * SAUCE: Guest OS does not recognize a lun with non zero target id on + Vmware ESX Server + * SAUCE: Modualrize vesafb + * SAUCE: DVB-USB UMT-010 driver oops on install + * SAUCE: fn key doesn't work in hardy with macbook pro fourth generation + (4,1) + - LP: #207127 + + -- Ben Collins Wed, 11 Jun 2008 05:28:35 -0400 --- linux-2.6.28.orig/debian/control.stub.in +++ linux-2.6.28/debian/control.stub.in @@ -0,0 +1,70 @@ +Source: linux +Section: devel +Priority: optional +Maintainer: Ubuntu Kernel Team +Standards-Version: 3.6.1 +Build-Depends: debhelper (>= 3), module-init-tools, kernel-wedge (>= 2.24ubuntu1), makedumpfile [!armel] +Build-Depends-Indep: xmlto, docbook-utils, gs, transfig, bzip2, sharutils +Vcs-Git: http://kernel.ubuntu.com/git-repos/ubuntu/ubuntu-jaunty.git + +Package: linux-source-PKGVER +Architecture: all +Section: devel +Priority: optional +Provides: linux-source, linux-source-2.6 +Depends: binutils, bzip2, coreutils | fileutils (>= 4.0) +Recommends: libc-dev, gcc, make +Suggests: libncurses-dev | ncurses-dev, kernel-package, libqt3-dev +Description: Linux kernel source for version PKGVER with Ubuntu patches + This package provides the source code for the Linux kernel version + PKGVER. + . + This package is mainly meant for other packages to use, in order to build + custom flavours. + . + If you wish to use this package to create a custom Linux kernel, then it + is suggested that you investigate the package kernel-package, which has + been designed to ease the task of creating kernel image packages. + . + If you are simply trying to build third-party modules for your kernel, + you do not want this package. Install the appropriate linux-headers + package instead. + +Package: linux-doc-PKGVER +Architecture: all +Section: doc +Priority: optional +Provides: linux-doc-2.6 +Conflicts: linux-doc-2.6 +Replaces: linux-doc-2.6 +Depends: coreutils | fileutils (>= 4.0) +Description: Linux kernel specific documentation for version PKGVER + This package provides the various readme's in the PKGVER kernel + Documentation/ subdirectory: these typically contain kernel-specific + installation notes for some drivers for example. See + /usr/share/doc/linux-doc-PKGVER/Documentation/00-INDEX for a list of what + is contained in each file. Please read the Changes file, as it contains + information about the problems, which may result by upgrading your + kernel. + +Package: linux-headers-PKGVER-ABINUM +Architecture: all +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0) +Provides: linux-headers, linux-headers-2.6 +Description: Header files related to Linux kernel version PKGVER + This package provides kernel header files for version PKGVER, for sites + that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-PKGVER-ABINUM/debian.README.gz for details + +Package: linux-libc-dev +Architecture: i386 amd64 armel lpia +Conflicts: libc6-dev (<< 2.3.2.ds1-6), libc6.1-dev (<< 2.3.2.ds1-6), dvb-dev (<< 1.0.1-6), amd64-libs-dev (<= 1.1), linux-kernel-headers +Replaces: libc6-dev (<< 2.3.2.ds1-6), libc6.1-dev (<< 2.3.2.ds1-6), dvb-dev (<< 1.0.1-6), linux-kernel-headers, libdrm-dev +Provides: linux-kernel-headers +Description: Linux Kernel Headers for development + This package provides headers from the Linux kernel. These headers + are used by the installed headers for GNU glibc and other system + libraries. They are NOT meant to be used to build third-party modules for + your kernel. Use linux-headers-* packages for that. --- linux-2.6.28.orig/debian/sub-flavours/virtual.vars +++ linux-2.6.28/debian/sub-flavours/virtual.vars @@ -0,0 +1,11 @@ +# Based on server flavour +arch="i386 amd64" +supported="Virtual" +target="Geared toward virtual machine guests." +desc="x86/x86_64" +bootloader="grub | lilo (>= 19.1)" +is_sub="true" +based_on="server" +# The provides and conflicts are REQUIRED +provides="redhat-cluster-modules" +conflicts="linux-image-PKGVER-ABINUM-${based_on}" --- linux-2.6.28.orig/debian/sub-flavours/virtual.list +++ linux-2.6.28/debian/sub-flavours/virtual.list @@ -0,0 +1,109 @@ +arch/*/{crypto,kernel,oprofile} +crypto/* +drivers/acpi/* +drivers/ata/ata_generic.ko +drivers/ata/ata_piix.ko +drivers/ata/libata.ko +drivers/block/virtio_blk.ko +drivers/block/nbd.ko +drivers/block/loop.ko +drivers/block/floppy.ko +drivers/block/cryptoloop.ko +drivers/block/xen-blkfront.ko +drivers/cdrom/cdrom.ko +drivers/char/hangcheck-timer.ko +drivers/char/lp.ko +drivers/char/nvram.ko +drivers/char/ppdev.ko +drivers/char/raw.ko +drivers/input/evbug.ko +drivers/input/evdev.ko +drivers/input/gameport/gameport.ko +drivers/input/mouse/psmouse.ko +drivers/input/serio/serio_raw.ko +drivers/input/serio/serport.ko +drivers/input/joydev.ko +drivers/input/misc/uinput.ko +drivers/input/touchscreen/usbtouchscreen.ko +drivers/input/xen-kbdfront.ko +drivers/md/* +drivers/message/fusion* +drivers/misc/eeprom_93cx6.ko +drivers/net/8139too.ko +drivers/net/8139cp.ko +drivers/net/appletalk/ipddp.ko +drivers/net/bonding/bonding.ko +drivers/net/bsd_comp.ko +drivers/net/dummy.ko +drivers/net/e1000/e1000.ko +drivers/net/eql.ko +drivers/net/ifb.ko +drivers/net/mii.ko +drivers/net/ne2k-pci.ko +drivers/net/netconsole.ko +drivers/net/pcnet32.ko +drivers/net/ppp_async.ko +drivers/net/ppp_deflate.ko +drivers/net/ppp_generic.ko +drivers/net/ppp_mppe.ko +drivers/net/pppoe.ko +drivers/net/pppol2tp.ko +drivers/net/pppox.ko +drivers/net/ppp_synctty.ko +drivers/net/slhc.ko +drivers/net/slip.ko +drivers/net/tun.ko +drivers/net/veth.ko +drivers/net/virtio_net.ko +drivers/net/xen-netfront.ko +drivers/parport/parport.ko +drivers/parport/parport_pc.ko +drivers/net/tulip/tulip.ko +drivers/net/virtio_net.ko +drivers/scsi/BusLogic.ko +drivers/scsi/iscsi_tcp.ko +drivers/scsi/libiscsi.ko +drivers/scsi/libsas/* +drivers/scsi/libsas/libsas.ko +drivers/scsi/qla1280.ko +drivers/scsi/raid_class.ko +drivers/scsi/scsi_mod.ko +drivers/scsi/scsi_transport_fc.ko +drivers/scsi/scsi_transport_iscsi.ko +drivers/scsi/scsi_transport_sas.ko +drivers/scsi/scsi_transport_spi.ko +drivers/scsi/scsi_wait_scan.ko +drivers/scsi/sd_mod.ko +drivers/scsi/sg.ko +drivers/scsi/sr_mod.ko +drivers/usb/core/usbcore.ko +drivers/usb/storage/usb-storage.ko +drivers/video/cirrusfb.ko +drivers/video/console/bitblit.ko +drivers/video/console/fbcon.ko +drivers/video/console/font.ko +drivers/video/console/softcursor.ko +drivers/video/console/tileblit.ko +drivers/video/output.ko +drivers/video/syscopyarea.ko +drivers/video/sysfillrect.ko +drivers/video/sysimgblt.ko +drivers/video/vesafb.ko +drivers/video/vga16fb.ko +drivers/video/vgastate.ko +drivers/video/xen-fbfront.ko +drivers/virtio/virtio_balloon.ko +drivers/virtio/virtio.ko +drivers/virtio/virtio_pci.ko +drivers/virtio/virtio_ring.ko +drivers/watchdog/softdog.ko +drivers/xen/* +fs/* +lib/* +net/* +sound/core/* +sound/pci/snd-ens1370.ko +sound/drivers/pcsp/snd-pcsp.ko +ubuntu/e1000e/e1000e.ko +ubuntu/squashfs/squashfs.ko +ubuntu/iscsitarget/iscsi_trgt.ko --- linux-2.6.28.orig/debian/sub-flavours/README +++ linux-2.6.28/debian/sub-flavours/README @@ -0,0 +1,12 @@ +Sub flavours are flavours that are built based on other builds. IOW, they +are usually a subset of something else. + +Requirements: + +debian/sub-flavours/.list : The file list, uses glob syntax +debian/sub-flavours/.vars : The make vars, similar to normal flavours +debian/rules.d/.mk : Add _sub var listing the , e.g. + server_sub = virtual would mean virtual is + based on the server flavour. + +Note, the vars must include a conflicts with the flavour it was built on. --- linux-2.6.28.orig/debian/sub-flavours/control.stub +++ linux-2.6.28/debian/sub-flavours/control.stub @@ -0,0 +1,39 @@ +# Items that get replaced: +# FLAVOUR +# DESC +# ARCH +# SUPPORTED +# TARGET +# BOOTLOADER +# =PROVIDES= +# =CONFLICTS= +# +# Items marked with =FOO= are optional +# +# XXX: Leave the blank line before the first package!! + +Package: linux-image-PKGVER-ABINUM-FLAVOUR +Architecture: ARCH +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, =PROVIDES= +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1), =CONFLICTS= +Recommends: BOOTLOADER +Suggests: fdutils, linux-doc-PKGVER | linux-source-PKGVER +Description: Linux kernel image for version PKGVER on DESC + This package contains the Linux kernel image for version PKGVER on + DESC. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports SUPPORTED processors. + . + TARGET + . + You likely do not want to install this package directly. Instead, install + the linux-FLAVOUR meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. --- linux-2.6.28.orig/debian/control.d/vars.iop32x +++ linux-2.6.28/debian/control.d/vars.iop32x @@ -0,0 +1,8 @@ +arch="armel" +supported="IOP32x" +desc="IOP32x-based systems" +target="Thecus N2100, etc." +bootloader="flash-kernel" +provides="" +section_image="universe/base" +do_debug="Yes" --- linux-2.6.28.orig/debian/control.d/vars.server +++ linux-2.6.28/debian/control.d/vars.server @@ -0,0 +1,6 @@ +arch="i386 amd64" +supported="Server" +target="Geared toward server systems." +desc="x86/x86_64" +bootloader="grub | lilo (>= 19.1)" +provides="redhat-cluster-modules, kvm-api-4, ivtv-modules, ndiswrapper-modules-1.9" --- linux-2.6.28.orig/debian/control.d/flavour-control.stub +++ linux-2.6.28/debian/control.d/flavour-control.stub @@ -0,0 +1,66 @@ +# Items that get replaced: +# FLAVOUR +# DESC +# ARCH +# SUPPORTED +# TARGET +# BOOTLOADER +# =PROVIDES= +# +# Items marked with =FOO= are optional +# +# XXX: Leave the blank line before the first package!! + +Package: linux-image-PKGVER-ABINUM-FLAVOUR +Architecture: ARCH +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, =PROVIDES= +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3), wireless-crda +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: BOOTLOADER +Suggests: fdutils, linux-doc-PKGVER | linux-source-PKGVER +Description: Linux kernel image for version PKGVER on DESC + This package contains the Linux kernel image for version PKGVER on + DESC. + . + Also includes the corresponding System.map file, the modules built by the + packager, and scripts that try to ensure that the system is not left in an + unbootable state after an update. + . + Supports SUPPORTED processors. + . + TARGET + . + You likely do not want to install this package directly. Instead, install + the linux-FLAVOUR meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-PKGVER-ABINUM-FLAVOUR +Architecture: ARCH +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-PKGVER-ABINUM, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version PKGVER on DESC + This package provides kernel header files for version PKGVER on + DESC. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-PKGVER-ABINUM/debian.README.gz for details. + +Package: linux-image-debug-PKGVER-ABINUM-FLAVOUR +Architecture: ARCH +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version PKGVER on DESC + This package provides a kernel debug image for version PKGVER on + DESC. + . + This is for sites that wish to debug the kernel. + . + The kernel image contained in this package is NOT meant to boot from. It + is uncompressed, and unstripped. This package also includes the + unstripped modules. --- linux-2.6.28.orig/debian/control.d/vars.generic +++ linux-2.6.28/debian/control.d/vars.generic @@ -0,0 +1,6 @@ +arch="i386 amd64" +supported="Generic" +target="Geared toward desktop systems." +desc="x86/x86_64" +bootloader="grub | lilo (>= 19.1)" +provides="kvm-api-4, redhat-cluster-modules, ivtv-modules, ndiswrapper-modules-1.9" --- linux-2.6.28.orig/debian/control.d/vars.versatile +++ linux-2.6.28/debian/control.d/vars.versatile @@ -0,0 +1,8 @@ +arch="armel" +supported="Versatile" +desc="Versatile-based systems" +target="PB, AB, Qemu, etc." +bootloader="" +provides="" +section_image="universe/base" +do_debug="Yes" --- linux-2.6.28.orig/debian/control.d/vars.ixp4xx +++ linux-2.6.28/debian/control.d/vars.ixp4xx @@ -0,0 +1,8 @@ +arch="armel" +supported="IXP4xx" +desc="IXP4xx-based systems" +target="Linksys NSLU2, etc." +bootloader="flash-kernel" +provides="" +section_image="universe/base" +do_debug="Yes" --- linux-2.6.28.orig/debian/control.d/vars.lpia +++ linux-2.6.28/debian/control.d/vars.lpia @@ -0,0 +1,8 @@ +arch="lpia" +supported="Intel Atom" +desc="Intel Atom processors" +target="Geared toward LPIA-based mobile devices" +bootloader="lilo (>= 19.1) | grub" +provides="kvm-api-4, redhat-cluster-modules" +section_image="universe/base" +do_debug="Yes" --- linux-2.6.28.orig/debian/control.d/vars.imx51 +++ linux-2.6.28/debian/control.d/vars.imx51 @@ -0,0 +1,8 @@ +arch="armel" +supported="I.MX51" +desc="I.MX51-based systems" +target="Babbage and 3-stack boards" +bootloader="flash-kernel" +provides="" +section_image="universe/base" +do_debug="Yes" --- linux-2.6.28.orig/debian/stamps/keep-dir +++ linux-2.6.28/debian/stamps/keep-dir @@ -0,0 +1 @@ +Place holder --- linux-2.6.28.orig/debian/abi/perm-blacklist +++ linux-2.6.28/debian/abi/perm-blacklist @@ -0,0 +1 @@ + --- linux-2.6.28.orig/debian/abi/2.6.28-11.41/abiname +++ linux-2.6.28/debian/abi/2.6.28-11.41/abiname @@ -0,0 +1 @@ +11 --- linux-2.6.28.orig/debian/abi/2.6.28-11.41/i386/generic +++ linux-2.6.28/debian/abi/2.6.28-11.41/i386/generic @@ -0,0 +1,8643 @@ +EXPORT_SYMBOL arch/x86/kernel/scx200 0x254e5667 scx200_gpio_base +EXPORT_SYMBOL arch/x86/kernel/scx200 0x35a3c008 scx200_gpio_configure +EXPORT_SYMBOL arch/x86/kernel/scx200 0x8cfa375c scx200_gpio_shadow +EXPORT_SYMBOL arch/x86/kernel/scx200 0x907665bd scx200_cb_base +EXPORT_SYMBOL arch/x86/kvm/kvm 0x23e9276d kvm_read_guest_atomic +EXPORT_SYMBOL arch/x86/kvm/kvm 0x84819f08 kvm_cpu_has_pending_timer +EXPORT_SYMBOL crypto/gf128mul 0x0c2f123f gf128mul_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x1068004b gf128mul_bbe +EXPORT_SYMBOL crypto/gf128mul 0x2f2889a0 gf128mul_init_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0x3755f990 gf128mul_init_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x384ef9ce gf128mul_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x56af0dbd gf128mul_x_ble +EXPORT_SYMBOL crypto/gf128mul 0x83581089 gf128mul_init_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0x9b2560b9 gf128mul_init_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x9e13f6f6 gf128mul_lle +EXPORT_SYMBOL crypto/gf128mul 0xbd17a0df gf128mul_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0xc0890413 gf128mul_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0xd60736ec gf128mul_free_64k +EXPORT_SYMBOL crypto/xor 0x5b6c00e6 xor_blocks +EXPORT_SYMBOL drivers/atm/suni 0xae6dbfb1 suni_init +EXPORT_SYMBOL drivers/atm/uPD98402 0x9f47f8a6 uPD98402_init +EXPORT_SYMBOL drivers/block/paride/paride 0x2167fc98 pi_release +EXPORT_SYMBOL drivers/block/paride/paride 0x34dce774 pi_do_claimed +EXPORT_SYMBOL drivers/block/paride/paride 0x5f16350e paride_register +EXPORT_SYMBOL drivers/block/paride/paride 0x62fe05d2 pi_write_regr +EXPORT_SYMBOL drivers/block/paride/paride 0x9078d6a9 pi_read_block +EXPORT_SYMBOL drivers/block/paride/paride 0x9bd1c8c2 pi_read_regr +EXPORT_SYMBOL drivers/block/paride/paride 0xad07967c pi_init +EXPORT_SYMBOL drivers/block/paride/paride 0xcf585b28 paride_unregister +EXPORT_SYMBOL drivers/block/paride/paride 0xd1136219 pi_write_block +EXPORT_SYMBOL drivers/block/paride/paride 0xdc49fbac pi_connect +EXPORT_SYMBOL drivers/block/paride/paride 0xe12c3a87 pi_disconnect +EXPORT_SYMBOL drivers/block/paride/paride 0xf3af7039 pi_schedule_claimed +EXPORT_SYMBOL drivers/char/agp/agpgart 0x0553b642 agp_alloc_bridge +EXPORT_SYMBOL drivers/char/agp/agpgart 0x0b8edef0 agp_alloc_page_array +EXPORT_SYMBOL drivers/char/agp/agpgart 0x10a8b8c7 agp_generic_enable +EXPORT_SYMBOL drivers/char/agp/agpgart 0x13532cc1 agp_create_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0x1e2f5175 agp_generic_destroy_page +EXPORT_SYMBOL drivers/char/agp/agpgart 0x2c5e413c agp_generic_insert_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0x30226ddf agp_device_command +EXPORT_SYMBOL drivers/char/agp/agpgart 0x34e349ea agp_generic_alloc_pages +EXPORT_SYMBOL drivers/char/agp/agpgart 0x3bf5f8d0 agp_find_bridge +EXPORT_SYMBOL drivers/char/agp/agpgart 0x4b085dbf agp3_generic_configure +EXPORT_SYMBOL drivers/char/agp/agpgart 0x65b7f46a agp_generic_destroy_pages +EXPORT_SYMBOL drivers/char/agp/agpgart 0x673f815e agp_bridges +EXPORT_SYMBOL drivers/char/agp/agpgart 0x7538b132 agp_off +EXPORT_SYMBOL drivers/char/agp/agpgart 0x75898411 agp_generic_alloc_page +EXPORT_SYMBOL drivers/char/agp/agpgart 0x7627353b agp_backend_acquire +EXPORT_SYMBOL drivers/char/agp/agpgart 0x7f6c90e2 agp_generic_create_gatt_table +EXPORT_SYMBOL drivers/char/agp/agpgart 0x8081fcf2 agp_put_bridge +EXPORT_SYMBOL drivers/char/agp/agpgart 0x90d2a90a agp_generic_type_to_mask_type +EXPORT_SYMBOL drivers/char/agp/agpgart 0x98151541 agp_generic_alloc_user +EXPORT_SYMBOL drivers/char/agp/agpgart 0x98dc4696 agp_enable +EXPORT_SYMBOL drivers/char/agp/agpgart 0x99f1b1f8 agp_backend_release +EXPORT_SYMBOL drivers/char/agp/agpgart 0xa1b4d59f agp_bridge +EXPORT_SYMBOL drivers/char/agp/agpgart 0xa2c63c21 agp_generic_remove_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xa4d4f0e6 global_cache_flush +EXPORT_SYMBOL drivers/char/agp/agpgart 0xa754eaa0 agp_bind_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xaa47504a agp_copy_info +EXPORT_SYMBOL drivers/char/agp/agpgart 0xabb3b589 get_agp_version +EXPORT_SYMBOL drivers/char/agp/agpgart 0xae13a5fc agp_allocate_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xb04ea8f0 agp_rebind_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xb54c7e98 agp_flush_chipset +EXPORT_SYMBOL drivers/char/agp/agpgart 0xbdc90941 agp_generic_free_by_type +EXPORT_SYMBOL drivers/char/agp/agpgart 0xc2424641 agp3_generic_cleanup +EXPORT_SYMBOL drivers/char/agp/agpgart 0xc5563c47 agp_free_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xc5d9c46c agp_try_unsupported_boot +EXPORT_SYMBOL drivers/char/agp/agpgart 0xc65abeb7 agp3_generic_sizes +EXPORT_SYMBOL drivers/char/agp/agpgart 0xcca98ae1 agp_generic_alloc_by_type +EXPORT_SYMBOL drivers/char/agp/agpgart 0xd0fef3b2 agp_free_key +EXPORT_SYMBOL drivers/char/agp/agpgart 0xd7012aa1 agp_unbind_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xd7333e84 agp_generic_mask_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xde0a1f64 agp_collect_device_status +EXPORT_SYMBOL drivers/char/agp/agpgart 0xde9b17ed agp3_generic_fetch_size +EXPORT_SYMBOL drivers/char/agp/agpgart 0xec336e12 agp_generic_free_gatt_table +EXPORT_SYMBOL drivers/char/agp/agpgart 0xf3a9085b agp3_generic_tlbflush +EXPORT_SYMBOL drivers/char/agp/agpgart 0xfc656990 agp_free_page_array +EXPORT_SYMBOL drivers/char/generic_serial 0x1999f076 gs_flush_buffer +EXPORT_SYMBOL drivers/char/generic_serial 0x221902fd gs_block_til_ready +EXPORT_SYMBOL drivers/char/generic_serial 0x40c09549 gs_hangup +EXPORT_SYMBOL drivers/char/generic_serial 0x45ab1aed gs_stop +EXPORT_SYMBOL drivers/char/generic_serial 0x46e55fd6 gs_got_break +EXPORT_SYMBOL drivers/char/generic_serial 0x4a8bb591 gs_write_room +EXPORT_SYMBOL drivers/char/generic_serial 0x56adeb53 gs_write +EXPORT_SYMBOL drivers/char/generic_serial 0x6091becb gs_chars_in_buffer +EXPORT_SYMBOL drivers/char/generic_serial 0x6646d53c gs_set_termios +EXPORT_SYMBOL drivers/char/generic_serial 0x72c6ed6e gs_start +EXPORT_SYMBOL drivers/char/generic_serial 0x9cce53a8 gs_setserial +EXPORT_SYMBOL drivers/char/generic_serial 0x9ff86621 gs_init_port +EXPORT_SYMBOL drivers/char/generic_serial 0xa224e0ef gs_close +EXPORT_SYMBOL drivers/char/generic_serial 0xabbce0f3 gs_flush_chars +EXPORT_SYMBOL drivers/char/generic_serial 0xb43e4e55 gs_getserial +EXPORT_SYMBOL drivers/char/generic_serial 0xd624dc73 gs_put_char +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x06869a40 ipmi_destroy_user +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x11992637 ipmi_get_my_address +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x1858195d ipmi_set_maintenance_mode +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x361b3307 ipmi_smi_msg_received +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x40f2b10c ipmi_alloc_smi_msg +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x621d0f7f ipmi_smi_watcher_register +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x6e4318c4 ipmi_smi_add_proc_entry +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x7690f9c6 ipmi_register_smi +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x804f922a ipmi_addr_length +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x83759948 ipmi_unregister_smi +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x887d4075 ipmi_get_version +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x91abe476 ipmi_get_maintenance_mode +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x934da0c7 ipmi_set_my_LUN +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x9509b1f3 ipmi_unregister_for_cmd +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x991e80a3 ipmi_request_settime +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xad20092a ipmi_register_for_cmd +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xb4720eae ipmi_create_user +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xbfe6262a ipmi_smi_watcher_unregister +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xc023e985 ipmi_set_my_address +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xc87fb8ae ipmi_smi_watchdog_pretimeout +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xcdd10ad6 ipmi_free_recv_msg +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xd0d55457 ipmi_request_supply_msgs +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xd35c7480 ipmi_get_my_LUN +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xe4f4665b ipmi_validate_addr +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xe893bac3 ipmi_poll_interface +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xfbfaca5f ipmi_set_gets_events +EXPORT_SYMBOL drivers/char/nsc_gpio 0x772713c8 nsc_gpio_read +EXPORT_SYMBOL drivers/char/nsc_gpio 0xc664ec68 nsc_gpio_dump +EXPORT_SYMBOL drivers/char/nsc_gpio 0xecbf1421 nsc_gpio_write +EXPORT_SYMBOL drivers/char/nvram 0x0f28cb91 nvram_read_byte +EXPORT_SYMBOL drivers/char/nvram 0x17ff2c1d __nvram_read_byte +EXPORT_SYMBOL drivers/char/nvram 0x2adec1e0 __nvram_check_checksum +EXPORT_SYMBOL drivers/char/nvram 0x7da28f12 nvram_check_checksum +EXPORT_SYMBOL drivers/char/nvram 0x9ce3f83f nvram_write_byte +EXPORT_SYMBOL drivers/char/nvram 0xa8813189 __nvram_write_byte +EXPORT_SYMBOL drivers/edac/edac_core 0x8b067afb edac_mc_handle_fbd_ce +EXPORT_SYMBOL drivers/edac/edac_core 0x9a5200f7 edac_mc_handle_fbd_ue +EXPORT_SYMBOL drivers/edac/edac_core 0xefd55e08 edac_mc_find +EXPORT_SYMBOL drivers/firewire/firewire-core 0x144ce6e8 fw_card_add +EXPORT_SYMBOL drivers/firewire/firewire-core 0x2940c888 fw_core_initiate_bus_reset +EXPORT_SYMBOL drivers/firewire/firewire-core 0x2aef108c fw_send_response +EXPORT_SYMBOL drivers/firewire/firewire-core 0x3a89d578 fw_core_handle_bus_reset +EXPORT_SYMBOL drivers/firewire/firewire-core 0x3e57a659 fw_core_handle_response +EXPORT_SYMBOL drivers/firewire/firewire-core 0x4fbdea81 fw_bus_type +EXPORT_SYMBOL drivers/firewire/firewire-core 0x599e67c5 fw_core_add_address_handler +EXPORT_SYMBOL drivers/firewire/firewire-core 0x67ca6c03 fw_core_handle_request +EXPORT_SYMBOL drivers/firewire/firewire-core 0x6fb19fdb fw_fill_response +EXPORT_SYMBOL drivers/firewire/firewire-core 0x74ae0b41 fw_run_transaction +EXPORT_SYMBOL drivers/firewire/firewire-core 0x90863005 fw_high_memory_region +EXPORT_SYMBOL drivers/firewire/firewire-core 0x9adb1772 fw_card_initialize +EXPORT_SYMBOL drivers/firewire/firewire-core 0x9b72ce15 fw_device_enable_phys_dma +EXPORT_SYMBOL drivers/firewire/firewire-core 0xafc1c793 fw_csr_iterator_next +EXPORT_SYMBOL drivers/firewire/firewire-core 0xb047a2c6 fw_csr_iterator_init +EXPORT_SYMBOL drivers/firewire/firewire-core 0xb3ebedf1 fw_send_request +EXPORT_SYMBOL drivers/firewire/firewire-core 0xdec69ce8 fw_core_remove_card +EXPORT_SYMBOL drivers/firewire/firewire-core 0xe7d4075a fw_core_remove_address_handler +EXPORT_SYMBOL drivers/firewire/firewire-core 0xf07a4875 fw_cancel_transaction +EXPORT_SYMBOL drivers/gpu/drm/drm 0x0070e1ea drm_core_ioremapfree +EXPORT_SYMBOL drivers/gpu/drm/drm 0x03a8386c drm_agp_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x0411ae20 drm_agp_bind_pages +EXPORT_SYMBOL drivers/gpu/drm/drm 0x0836695c drm_sman_takedown +EXPORT_SYMBOL drivers/gpu/drm/drm 0x096d8e4a drm_unbind_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0x0b95e6c5 drm_addbufs_pci +EXPORT_SYMBOL drivers/gpu/drm/drm 0x0eec5bb3 drm_handle_vblank +EXPORT_SYMBOL drivers/gpu/drm/drm 0x148e1e3a drm_mm_search_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x1c7439c7 drm_agp_acquire +EXPORT_SYMBOL drivers/gpu/drm/drm 0x1ec2b3a2 drm_idlelock_take +EXPORT_SYMBOL drivers/gpu/drm/drm 0x20645642 drm_debug +EXPORT_SYMBOL drivers/gpu/drm/drm 0x21451ac4 drm_sman_owner_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2209bc9b drm_core_get_reg_ofs +EXPORT_SYMBOL drivers/gpu/drm/drm 0x226aba00 drm_clflush_pages +EXPORT_SYMBOL drivers/gpu/drm/drm 0x26ed0333 drm_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2916bf63 drm_sman_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2a108473 drm_vblank_get +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2eb2f903 drm_sman_free_key +EXPORT_SYMBOL drivers/gpu/drm/drm 0x3074f033 drm_order +EXPORT_SYMBOL drivers/gpu/drm/drm 0x3500482f drm_poll +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4a08e07d drm_pci_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4b8082b9 drm_mm_put_block +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4ea1f5a2 drm_gem_object_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4fc57129 drm_gem_object_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0x55c65ebe drm_pci_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0x55f060ee drm_sman_set_range +EXPORT_SYMBOL drivers/gpu/drm/drm 0x573939d7 drm_ati_pcigart_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x57684a4a drm_core_ioremap +EXPORT_SYMBOL drivers/gpu/drm/drm 0x59c088eb drm_vblank_put +EXPORT_SYMBOL drivers/gpu/drm/drm 0x620a2551 drm_agp_enable +EXPORT_SYMBOL drivers/gpu/drm/drm 0x6370b050 drm_mm_get_block +EXPORT_SYMBOL drivers/gpu/drm/drm 0x647c4439 drm_sg_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0x67a4ff5b drm_agp_info +EXPORT_SYMBOL drivers/gpu/drm/drm 0x67e246bc drm_exit +EXPORT_SYMBOL drivers/gpu/drm/drm 0x6cf4b965 drm_core_reclaim_buffers +EXPORT_SYMBOL drivers/gpu/drm/drm 0x75df2e3f drm_gem_object_lookup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x764640ed drm_idlelock_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0x77c78aba drm_mmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0x795f4c06 drm_rmmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0x84b93116 drm_ati_pcigart_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x8873dc30 drm_mm_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x894c5a1e drm_lock_take +EXPORT_SYMBOL drivers/gpu/drm/drm 0x8cc4e728 drm_i_have_hw_lock +EXPORT_SYMBOL drivers/gpu/drm/drm 0x921ecd89 drm_addmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0x924538fd drm_agp_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0x99d7e663 drm_ioctl +EXPORT_SYMBOL drivers/gpu/drm/drm 0x9bbed36e drm_core_ioremap_wc +EXPORT_SYMBOL drivers/gpu/drm/drm 0x9c25b192 drm_core_get_map_ofs +EXPORT_SYMBOL drivers/gpu/drm/drm 0x9fb76f81 drm_irq_uninstall +EXPORT_SYMBOL drivers/gpu/drm/drm 0xa424fc7a drm_addbufs_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0xa5e8a228 drm_fasync +EXPORT_SYMBOL drivers/gpu/drm/drm 0xa862916d drm_irq_install +EXPORT_SYMBOL drivers/gpu/drm/drm 0xaf29788e drm_sman_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0xaf51d1fd drm_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0xba712a36 drm_agp_unbind +EXPORT_SYMBOL drivers/gpu/drm/drm 0xc080eb9b drm_gem_object_handle_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0xc2dfd4e6 drm_get_resource_len +EXPORT_SYMBOL drivers/gpu/drm/drm 0xcb18de08 drm_agp_chipset_flush +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd1fe6ef8 drm_getsarea +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd3028e75 drm_sman_set_manager +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd382c1a5 drm_agp_bind +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd62bc955 drm_free_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe189d114 drm_vblank_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe1caf37a drm_open +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe38cb8c7 drm_lock_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe498dd46 drm_get_drawable_info +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe6409107 drm_get_resource_start +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe919dd5c drm_sman_owner_clean +EXPORT_SYMBOL drivers/gpu/drm/drm 0xecaebc4a drm_agp_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0xef103e28 drm_gem_handle_create +EXPORT_SYMBOL drivers/gpu/drm/drm 0xefa7e40a drm_vblank_count +EXPORT_SYMBOL drivers/gpu/drm/drm 0xfdfbad19 drm_sman_alloc +EXPORT_SYMBOL drivers/hwmon/hwmon-vid 0x0903c239 vid_from_reg +EXPORT_SYMBOL drivers/hwmon/hwmon-vid 0xef1c781c vid_which_vrm +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0x30271270 i2c_bit_add_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0x6f2f8be9 i2c_bit_add_numbered_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pca 0x6d5ab62f i2c_pca_add_numbered_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pca 0x70a620d0 i2c_pca_add_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pcf 0x14ced21a i2c_pcf_add_bus +EXPORT_SYMBOL drivers/i2c/busses/i2c-amd756 0x397a2847 amd756_smbus +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x02d4ad0f tps65013_set_low_pwr +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x28485130 tps65010_config_vregs1 +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x33739de7 tps65010_set_vib +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x9fd44c69 tps65010_set_led +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0xb14080cc tps65010_set_low_pwr +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0xd5bb106d tps65010_set_vbus_draw +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0xe99b3f36 tps65010_set_gpio_out_value +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0843deb4 hpsb_protocol_class +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0c6da941 csr1212_release_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0e5a659c csr1212_new_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0fc12d26 hpsb_free_tlabel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x13ad75e7 hpsb_iso_recv_release_packets +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x13b4a268 csr1212_attach_keyval_to_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x16bb3d53 hpsb_reset_bus +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x1858a48e hpsb_register_highlevel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x1c26b2b5 hpsb_iso_xmit_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x1f105ae4 hpsb_get_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x219cbabe dma_region_offset_to_bus +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x21f88879 hpsb_get_hostinfo_bykey +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x26a5880b hpsb_iso_recv_unlisten_channel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2752b9a8 csr1212_get_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2c55d7c2 dma_region_mmap +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2ea22873 hpsb_free_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2ef43846 hpsb_alloc_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x346b62f3 hpsb_unregister_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x348b86b5 hpsb_make_streampacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x36a0f1d7 hpsb_iso_recv_set_channel_mask +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x37a736c9 csr1212_read +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x37b7f652 hpsb_resume_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x42333443 hpsb_set_packet_complete_task +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x4459d8f2 hpsb_unregister_highlevel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x45433436 hpsb_iso_packet_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x48cd2fed hpsb_selfid_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x4cd6c9a1 hpsb_selfid_complete +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x4fecede1 hpsb_add_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x52346fd7 hpsb_iso_packet_sent +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x59dd7a06 hpsb_packet_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x5b79ed4e hpsb_iso_shutdown +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x63f4a170 hpsb_remove_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6590dafc hpsb_bus_reset +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x672ad148 dma_region_sync_for_device +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6b9be373 hpsb_packet_success +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6bf29da7 hpsb_iso_recv_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6c211d11 hpsb_write +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6e13c3a9 hpsb_allocate_and_register_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6f4d61d5 hpsb_iso_xmit_queue_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x7046e886 csr1212_parse_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x7068f091 hpsb_create_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x70d27011 hpsb_send_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x76bc1a5c dma_region_free +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x7f904bd7 hpsb_packet_sent +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x83bc93c9 hpsb_iso_n_ready +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x84c09863 hpsb_read_cycle_timer +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8879f8f0 dma_region_sync_for_cpu +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8b742a2b hpsb_iso_xmit_start +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8d684891 hpsb_node_write +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8e0df9ce hpsb_iso_wake +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8ec2b312 dma_region_alloc +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x94cba311 hpsb_make_lock64packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x979b3052 dma_prog_region_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x99d3a5de hpsb_iso_recv_start +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x9bee3c1a hpsb_make_phypacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xa924dac6 dma_prog_region_alloc +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xac19a9f6 hpsb_set_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb54d1207 hpsb_iso_recv_flush +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xbae9608c hpsb_make_writepacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xbba70620 dma_prog_region_free +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc621e31e hpsb_set_hostinfo_key +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc669a4d3 csr1212_detach_keyval_from_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc6b5f380 hpsb_register_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xcf2c9459 hpsb_update_config_rom +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xd337c8a0 hpsb_unregister_protocol +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xd8accd76 hpsb_destroy_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xe1dedf97 hpsb_get_tlabel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xe3831ae5 hpsb_make_readpacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xe3bd3a45 __hpsb_register_protocol +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xe3c06647 hpsb_make_lockpacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xe45b9dcb hpsb_iso_stop +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xea1137a2 hpsb_node_fill_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xea4152ff dma_region_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xf095e91e hpsb_update_config_rom_image +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfa9a4101 hpsb_iso_xmit_sync +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfb0f70c2 hpsb_iso_recv_listen_channel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfb9f1b18 hpsb_alloc_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfba57f51 hpsb_speedto_str +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfd269687 hpsb_read +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0x5fcf3042 ohci1394_stop_context +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0x88db4790 ohci1394_register_iso_tasklet +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0xb37ab086 ohci1394_init_iso_tasklet +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0xd1f39f9d ohci1394_unregister_iso_tasklet +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x5fd31f04 rdma_translate_ip +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x71de06c2 rdma_addr_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0xb374efc9 rdma_resolve_ip +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0xbe81bb46 rdma_addr_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0xe290ee4e rdma_addr_cancel +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0xff67d3f8 rdma_copy_addr +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x450296c3 ib_cm_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x4cb7603f ib_send_cm_dreq +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x6056aa90 ib_send_cm_apr +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x6cccdabf ib_cm_notify +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x81739d60 ib_send_cm_sidr_rep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x872e63c1 ib_send_cm_rej +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xa2b763d2 ib_destroy_cm_id +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xa71edc18 ib_send_cm_mra +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xa88e2668 ib_send_cm_rtu +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xaad1b6d9 ib_cm_listen +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xbce26088 ib_send_cm_rep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xbe5ec6a9 ib_send_cm_req +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xc1cbdf2e ib_create_cm_id +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xcd7101ad cm_class +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xd53290d2 ib_send_cm_sidr_req +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xdecd0395 ib_send_cm_drep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xe4f0f5b8 ib_send_cm_lap +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x086986ba ib_query_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x10be4465 ib_alloc_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x17c26c9e ib_reg_phys_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x190f8c46 ib_umem_get +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x1969dc6e ib_free_fast_reg_page_list +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x1ab0ce0a ib_destroy_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x1c8aaddc ib_destroy_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x1d602754 ib_modify_port +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x1e491a04 ib_unmap_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x21d8cc65 ib_find_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x29c7de19 ib_register_event_handler +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x2b79d6f9 ib_get_cached_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x30a690fb ib_attach_mcast +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x32c68693 ib_rereg_phys_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x32e342f0 ib_alloc_mw +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3526c544 ib_alloc_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3602098d ib_create_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3b6f941e ib_alloc_fast_reg_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3de7894a ib_query_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3ec905fc ib_fmr_pool_map_phys +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3f7567fd ib_rate_to_mult +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x45be3c2d ib_create_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x48d30148 ib_unregister_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x50678b77 ib_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x520b2638 ib_pack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x52176b20 ib_create_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x540a9a53 ib_dealloc_mw +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x54e2bf6a ib_umem_release +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x55b40948 ib_get_dma_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x55f315e4 ib_create_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x5d8ab154 ib_umem_page_count +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x60763148 ib_dealloc_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x60871888 ib_get_client_data +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x608cc302 ib_modify_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x627132a5 ib_find_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x695db0f2 ib_alloc_fast_reg_page_list +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x6a64d53b ib_destroy_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x758e5299 ib_register_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x7a9d9649 ib_dealloc_pd +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x7d30c3e2 ib_set_client_data +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8640eaeb ib_modify_qp_is_ok +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x87b614d8 ib_ud_header_pack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x87eec73b ib_modify_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x894cddf3 ib_unregister_event_handler +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8a82ac6a ib_query_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8a87c81f ib_resize_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8da3a4fd ib_init_ah_from_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x931a559b ib_query_port +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x959449ff ib_modify_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x96ce6c46 rdma_node_get_transport +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x99855cbb ib_find_cached_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9bcabedc ib_dealloc_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9d804fa1 mult_to_ib_rate +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9d8f1096 ib_query_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa5608770 ib_flush_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa790d6ef ib_destroy_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb0552fba ib_alloc_pd +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb1901f35 ib_query_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb1a312e1 ib_unpack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb208acaf ib_create_ah_from_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb7719536 ib_modify_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xc79e11b7 ib_create_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xcc12792e ib_dispatch_event +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd0060e61 ib_detach_mcast +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd17ba9d1 ib_ud_header_init +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd215a308 ib_query_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd2cf7e87 ib_fmr_pool_unmap +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd344b56a ib_find_cached_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd48a3bb5 ib_dereg_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xe8d59343 ib_get_cached_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xe92319fb ib_modify_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xeadb2e8a ib_destroy_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xef341da4 ib_get_cached_lmc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf36498b9 ib_ud_header_unpack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf38e745a ib_query_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xfb563dea ib_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x0f497256 ib_process_mad_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x196f1683 ib_free_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x22516e23 ib_get_rmpp_segment +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x2a9a9888 ib_create_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x633fb155 ib_free_recv_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6ef787ed ib_response_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6f077fcf ib_get_mad_data_offset +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x7b5d4b7a ib_is_mad_class_rmpp +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x7c00b631 ib_modify_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x8121237b ib_register_mad_snoop +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x8fb1b4a8 ib_unregister_mad_agent +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x99084efa ib_redirect_mad_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xbfc6a460 ib_register_mad_agent +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xde0399e5 ib_cancel_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xf749aee4 ib_post_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x16199856 ib_sa_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x360a94ad ib_init_ah_from_mcmember +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x41ce8130 ib_sa_get_mcmember_rec +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x46f3f81f ib_sa_join_multicast +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x512ba124 ib_sa_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x576fdbac ib_sa_free_multicast +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x62ed796d ib_sa_service_rec_query +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xaf0d0a87 ib_sa_path_rec_get +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xb8215d0e ib_init_ah_from_path +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xf29471fe ib_sa_cancel_query +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x02f847bc ib_copy_path_rec_from_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x07cf5a51 ib_copy_ah_attr_to_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x18382f6a ib_copy_path_rec_to_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x184f3575 ib_copy_qp_attr_to_user +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x0315b1bb iw_cm_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x079994a3 iw_cm_disconnect +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x494341a1 iw_cm_connect +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x77b5aeec iw_cm_accept +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x7922e36c iw_cm_listen +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x8e889817 iw_destroy_cm_id +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x9dad861d iw_cm_reject +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xc14629e8 iw_create_cm_id +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x0422a666 rdma_create_id +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x0f37d3f3 rdma_connect +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x1ac6a0c8 rdma_destroy_id +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x253b4997 rdma_listen +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x37f98af4 rdma_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x385378c0 rdma_notify +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x38ec5300 rdma_bind_addr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x4087cf7e rdma_resolve_addr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x521732fb rdma_destroy_qp +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x5f90566c rdma_accept +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x6d6a5779 rdma_leave_multicast +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x6e616adb rdma_disconnect +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xc8881248 rdma_set_service_type +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xe11439d4 rdma_create_qp +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xf77e68dc rdma_reject +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xf8a4aebd rdma_set_ib_paths +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xfd8a972e rdma_join_multicast +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xff488cd2 rdma_resolve_route +EXPORT_SYMBOL drivers/input/gameport/gameport 0x185d8e82 gameport_unregister_driver +EXPORT_SYMBOL drivers/input/gameport/gameport 0x22f2f139 gameport_start_polling +EXPORT_SYMBOL drivers/input/gameport/gameport 0x2c3d9edc gameport_set_phys +EXPORT_SYMBOL drivers/input/gameport/gameport 0x644ee725 gameport_open +EXPORT_SYMBOL drivers/input/gameport/gameport 0xaf0f3310 __gameport_register_port +EXPORT_SYMBOL drivers/input/gameport/gameport 0xafa32289 gameport_stop_polling +EXPORT_SYMBOL drivers/input/gameport/gameport 0xc368e82e gameport_unregister_port +EXPORT_SYMBOL drivers/input/gameport/gameport 0xcacd587c gameport_close +EXPORT_SYMBOL drivers/input/gameport/gameport 0xd0c17e6a __gameport_register_driver +EXPORT_SYMBOL drivers/input/input-polldev 0x1a16d207 input_unregister_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0x4aca6503 input_allocate_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0x8bd50e75 input_register_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0xb27fc7f2 input_free_polled_device +EXPORT_SYMBOL drivers/isdn/capi/capifs 0x2c54c957 capifs_free_ncci +EXPORT_SYMBOL drivers/isdn/capi/capifs 0xd0bc06ce capifs_new_ncci +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x04403fcf unregister_capi_driver +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x0ade9b37 detach_capi_ctr +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x14f2aa5a capi20_get_version +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x28626b8f capi_ctr_ready +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x2b8eab1f capilib_free_ncci +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x2baa6586 capilib_new_ncci +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x308e04c6 capi_ctr_handle_message +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x31c24aa4 capi20_isinstalled +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x3a63f766 capi20_put_message +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x47d3fc51 capi_info2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x50b33ca4 capi_cmsg2message +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x6057c6f3 capi_message2cmsg +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x62e32d43 capilib_data_b3_conf +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x71e8d5ba capilib_data_b3_req +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x756995e7 capi20_register +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x7a33596c capi20_get_serial +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x7e6f1307 capi20_get_manufacturer +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x89afe822 capi_ctr_reseted +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x8cc1d275 capi20_set_callback +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x8f699913 capilib_release +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x9bef1b44 capi20_release +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x9f823278 register_capi_driver +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xa7c4fd6c capi_message2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xaa165d27 capilib_release_appl +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xb19fda8d capi_cmd2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xb60e5e5f capi_cmsg_header +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xbda2952f capi_ctr_resume_output +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xc10fe128 cdebbuf_free +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xc9fb478e capi_ctr_suspend_output +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xe19a11ac capi20_get_profile +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xe8ad9bd1 capi_cmsg2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xed061606 capi20_manufacturer +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xff6c8a95 attach_capi_ctr +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x0930f0e4 b1_load_config +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x0bce73f1 b1_reset_ctr +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x1a04e5e7 b1_parse_version +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x3f73b08e b1_getrevision +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x786b17dc b1_send_message +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x85f09690 b1_irq_table +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x8f4558dd b1_alloc_card +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x96f9d2f4 b1_interrupt +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xc5a73832 b1_load_firmware +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xca2f6a40 b1_load_t4file +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xcc6794c8 b1_register_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xce2017d8 avmcard_dma_free +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xcf8ca1a8 b1_release_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xd1b4c6c4 b1_loaded +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xd5979773 b1ctl_read_proc +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xdfd28376 b1_detect +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xe642f4f6 avmcard_dma_alloc +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xe83027e4 b1_free_card +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x04dd82a3 b1dma_release_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x0cf2c45a b1dma_send_message +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x1f569ec8 b1dmactl_read_proc +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x2a386384 b1dma_interrupt +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x4050e7b6 b1dma_reset_ctr +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x4e4a1de7 b1dma_register_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x8fb6e6f0 b1dma_reset +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0xa09a9b89 b1pciv4_detect +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0xbc775905 t1pci_detect +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0xbff6dc97 b1dma_load_firmware +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0x29562993 b1pcmcia_delcard +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0xaec3240e b1pcmcia_addcard_m1 +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0xea620116 b1pcmcia_addcard_m2 +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0xf14bf8b1 b1pcmcia_addcard_b1 +EXPORT_SYMBOL drivers/isdn/hardware/eicon/divadidd 0x2974ead1 DIVA_DIDD_Read +EXPORT_SYMBOL drivers/isdn/hardware/eicon/divadidd 0x9da3eb3f proc_net_eicon +EXPORT_SYMBOL drivers/isdn/hardware/mISDN/hfcmulti 0x5293ed86 plx_lock +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x07f4f2ce hisax_unregister +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x148f0c99 FsmFree +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x2844a899 FsmInitTimer +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x93a64734 FsmChangeState +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x9df0cd27 FsmEvent +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xa294f2ba hisax_init_pcmcia +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xc0c558f9 FsmRestartTimer +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xd94696e8 FsmDelTimer +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xee93522c hisax_register +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xf0a16657 FsmNew +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xfc27303b HiSax_closecard +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x321104ff isac_setup +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x347b7b3e isac_irq +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x3f3b323a isac_d_l2l1 +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x49ff0627 isac_init +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x7daf8bbd isacsx_irq +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x9f0274bf isacsx_setup +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0x1ee629e2 isdnhdlc_rcv_init +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0x95aed401 isdnhdlc_decode +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0x9ffc8215 isdnhdlc_out_init +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0xf5c8131d isdnhdlc_encode +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0x9dd0e6a0 isdn_ppp_register_compressor +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0x9e12af1e register_isdn +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0xcc02ab2f isdn_ppp_unregister_compressor +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0xfa06820f isdn_register_divert +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x0f93babb recv_Dchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x1429c276 queue_ch_frame +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x1a35aec5 l1_event +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x2348cc3c mISDN_FsmFree +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x29d3019f mISDN_unregister_Bprotocol +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x3b9c386d dchannel_senddata +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x3ea336fd mISDN_FsmAddTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x429129f2 mISDN_FsmRestartTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x4537d6b3 mISDN_register_device +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x45eaf505 recv_Bchannel_skb +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x50c2230c mISDN_FsmChangeState +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x5842cb33 mISDN_freedchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x629a1d31 bchannel_senddata +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x7000c2bd mISDN_freebchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x70654f91 create_l1 +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x7ceee719 get_next_bframe +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x7e1f8d43 mISDN_unregister_device +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xa94a49a4 mISDN_initbchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xace35cae mISDN_FsmDelTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xae6cf489 mISDN_register_Bprotocol +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xb1421747 recv_Dchannel_skb +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xc1fdb3e3 recv_Bchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xc576f540 mISDN_initdchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xc732ad0b get_next_dframe +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xcb289a81 confirm_Bsend +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xd5145151 mISDN_FsmEvent +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xd9a7fbfd mISDN_FsmInitTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xf9e7832f mISDN_FsmNew +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0x4c2ec443 mISDN_dsp_element_register +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0x60721da7 dsp_audio_law_to_s32 +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0xa215f1b2 dsp_audio_s16_to_law +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0xd3a023b8 mISDN_dsp_element_unregister +EXPORT_SYMBOL drivers/media/common/tuners/mt2060 0xe89c0d44 mt2060_attach +EXPORT_SYMBOL drivers/media/common/tuners/mt2131 0xbe95ecbc mt2131_attach +EXPORT_SYMBOL drivers/media/common/tuners/mt2266 0xeebb0eb7 mt2266_attach +EXPORT_SYMBOL drivers/media/common/tuners/mxl5005s 0x90f978ea mxl5005s_attach +EXPORT_SYMBOL drivers/media/common/tuners/qt1010 0x5b489dd7 qt1010_attach +EXPORT_SYMBOL drivers/media/common/tuners/tuner-types 0x0cb4b189 tuners +EXPORT_SYMBOL drivers/media/common/tuners/tuner-types 0xc2821775 tuner_count +EXPORT_SYMBOL drivers/media/common/tuners/tuner-xc2028 0x372ba1da xc2028_attach +EXPORT_SYMBOL drivers/media/common/tuners/xc5000 0xf69f41d9 xc5000_attach +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x17bc18bc flexcop_dma_config_timer +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x21c7c2df flexcop_device_kmalloc +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x40913386 flexcop_device_exit +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x51e22839 flexcop_dma_free +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x52d9c1cb flexcop_dump_reg +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x564a6ed6 flexcop_device_initialize +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x619df7d1 flexcop_device_kfree +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x68eed548 flexcop_dma_control_size_irq +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x7be9c480 flexcop_dma_config +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x93a461bd flexcop_eeprom_check_mac_addr +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x99de5253 flexcop_wan_set_speed +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xa8688021 flexcop_sram_ctrl +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xcb3ce577 flexcop_dma_control_timer_irq +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xcbb36dc3 flexcop_sram_set_dest +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xcda5482a flexcop_pass_dmx_packets +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xd00d5d8d flexcop_dma_allocate +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xe3bfcfcd flexcop_dma_xfer_control +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xeebb2372 flexcop_i2c_request +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xef36934d flexcop_pass_dmx_data +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0x06d82d38 bt878_device_control +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0x1f6caaae bt878_start +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0x2bc51533 bt878 +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0x6b0a1b25 bt878_stop +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0xd5d0bdef bt878_num +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x0bcf698b dst_error_recovery +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x180c6b17 dst_pio_disable +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x3a7d6698 dst_attach +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x413205d9 dst_error_bailout +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x41e5a4dd dst_wait_dst_ready +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x56bc8a32 write_dst +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x57c74181 read_dst +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xacd4be61 dst_comm_init +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xc64b7a48 rdc_reset_state +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xe94b8c9c dst_check_sum +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst_ca 0xac6295c0 dst_ca_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x08e0f739 dvb_ca_en50221_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x0ed1c8db dvb_generic_open +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x14eb630c dvb_ringbuffer_free +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x19457db6 dvb_generic_ioctl +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x2b8d84dd dvb_register_adapter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x2d1862f0 dvb_frontend_reinitialise +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x36c8ea1f dvb_frontend_sleep_until +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x398fb18c dvb_dmxdev_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x635eb40e dvb_dmx_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x63ed26ff dvb_net_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x6b7a7422 dvb_register_device +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x6f7f7d73 dvb_ringbuffer_empty +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x6f9c72e3 dvb_ringbuffer_read +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x714f8749 dvb_unregister_adapter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x74a5a698 dvb_filter_pes2ts_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x80e3832d dvb_filter_get_ac3info +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x8959fa4b dvb_net_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x8b49a23f timeval_usec_diff +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x923aa88e dvb_ringbuffer_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x9cbff999 dvb_dmx_swfilter_204 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xac4ca1b0 intlog2 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb14f1dbb dvb_generic_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb2297831 dvb_ca_en50221_camchange_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb2db2592 dvb_ringbuffer_write +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb388c08d dvb_ca_en50221_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb56f0404 dvb_dmx_swfilter_packets +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb5b95805 dvb_ringbuffer_read_user +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb92192ad dvb_unregister_frontend +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xba1cfa2f dvb_unregister_device +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xbed559e1 dvb_dmx_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xbf7bfba7 dvb_ca_en50221_camready_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xc938e566 dvb_dmx_swfilter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xe26f1495 dvb_dmxdev_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xe2a4261f dvb_frontend_detach +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xe5ae8707 intlog10 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xe7949e59 dvb_ringbuffer_flush_spinlock_wakeup +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xe98b9f8a dvb_ca_en50221_frda_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xeb7daf80 dvb_ringbuffer_avail +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xed5decfc dvb_register_frontend +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf826deb0 dvb_filter_pes2ts +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x53e6a5ee dvb_usb_generic_rw +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x59939275 dvb_usb_generic_write +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x62ad06d1 dvb_usb_get_hexline +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xad20a098 dvb_usb_device_init +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xaf00322e usb_cypress_load_firmware +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xb91060a9 dvb_usb_device_exit +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xc4846115 dvb_usb_nec_rc_key_to_event +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0x1409e15e af9005_rc_decode +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0x2edc4728 af9005_rc_keys +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0xd3383957 af9005_rc_keys_size +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x202839de dibusb_rc_query +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x297e4496 dibusb_i2c_algo +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x33e6acc1 dibusb_pid_filter_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x3cd1a306 dibusb2_0_power_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x3f510d6a dibusb_power_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x810ce43e dibusb_streaming_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x92286caa dibusb_pid_filter +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xba625807 dibusb2_0_streaming_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xcc46af79 dibusb_dib3000mc_frontend_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xd4d3dddc dibusb_rc_keys +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xecdd63b2 dibusb_read_eeprom_byte +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xfa4c4265 dibusb_dib3000mc_tuner_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/af9013 0xf8c73866 af9013_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/au8522 0xa8cd478a au8522_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/bcm3510 0xa1eee913 bcm3510_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx22700 0x48c648a4 cx22700_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx22702 0x6858cb5d cx22702_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24110 0x19662c9b cx24110_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24116 0xc125a0fb cx24116_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24123 0x6147d5a0 cx24123_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24123 0xbbdd8745 cx24123_get_tuner_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/dib0070 0x170915f5 dib0070_wbd_offset +EXPORT_SYMBOL drivers/media/dvb/frontends/dib0070 0x6c54cb57 dib0070_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mb 0x5e78c332 dib3000mb_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x3012099b dib3000mc_set_config +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x32d2cb3c dib3000mc_get_tuner_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x3c2a8858 dib3000mc_pid_parse +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x411da0f1 dib3000mc_i2c_enumeration +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0xcc692146 dib3000mc_pid_control +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0xe33572e6 dib3000mc_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000m 0x182e47cb dib7000m_get_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000m 0x820bdf9b dib7000m_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x11395aed dib7000p_i2c_enumeration +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x251159d0 dib7000p_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x6899d688 dib7000p_set_wbd_ref +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x9673aa1d dib7000p_get_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xd34978ec dib7000p_set_gpio +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xfaf23f86 dib7000pc_detection +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0x40c972ae dibx000_get_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0x54749c35 dibx000_exit_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0xa1f2844c dibx000_init_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/drx397xD 0x0492a5b6 drx397xD_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dvb-pll 0x67f8a2d3 dvb_pll_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/isl6405 0xccf1c1fc isl6405_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/isl6421 0xa91c86c5 isl6421_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/itd1000 0x4f1225e0 itd1000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/l64781 0x9900e57c l64781_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lgdt330x 0x646a533d lgdt330x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lgs8gl5 0x293b3ccf lgs8gl5_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lnbp21 0xd1ea26c0 lnbp21_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/mt312 0x40cd04c4 mt312_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/mt352 0x06cfb58f mt352_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/nxt200x 0xfd81cbeb nxt200x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/nxt6000 0x2870365e nxt6000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/or51132 0xf94509da or51132_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/or51211 0x0bd524ba or51211_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1409 0x7a11d347 s5h1409_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1411 0xe803b9d7 s5h1411_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1420 0x5d7f20eb s5h1420_get_tuner_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1420 0xc91a3a84 s5h1420_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/si21xx 0x94b553c0 si21xx_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/sp8870 0xb54492fd sp8870_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/sp887x 0x0af6fc6b sp887x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stb6000 0x793620ab stb6000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0288 0x23da33fa stv0288_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0297 0x75bd83a5 stv0297_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0299 0xfdfcd65d stv0299_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10021 0xd7b4c0ea tda10021_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10023 0xb8f8222e tda10023_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10048 0xc2aea1ad tda10048_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda1004x 0x0573730a tda10046_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda1004x 0x2232cafa tda10045_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10086 0x037fb720 tda10086_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda8083 0x77f6c04a tda8083_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda826x 0xea7dcfd9 tda826x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tua6100 0x6245fb96 tua6100_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/ves1820 0x78b740ba ves1820_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/ves1x93 0x01d65760 ves1x93_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/zl10353 0x2f333fda zl10353_attach +EXPORT_SYMBOL drivers/media/dvb/ttpci/ttpci-eeprom 0xc809332a ttpci_eeprom_parse_mac +EXPORT_SYMBOL drivers/media/dvb/ttusb-dec/ttusbdecfe 0xc07808a0 ttusbdecfe_dvbt_attach +EXPORT_SYMBOL drivers/media/dvb/ttusb-dec/ttusbdecfe 0xebbf096a ttusbdecfe_dvbs_attach +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x063d76a0 bttv_sub_unregister +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x11dc4b6d bttv_gpio_enable +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x2c3b6db3 bttv_sub_register +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x49531811 bttv_get_pcidev +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x8ecf4acc bttv_write_gpio +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0xbcf2d2fb bttv_read_gpio +EXPORT_SYMBOL drivers/media/video/btcx-risc 0x2d1e5dc4 btcx_riscmem_alloc +EXPORT_SYMBOL drivers/media/video/btcx-risc 0x495e4b0c btcx_calc_skips +EXPORT_SYMBOL drivers/media/video/btcx-risc 0x6cb477c2 btcx_riscmem_free +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xad2fe38b btcx_sort_clips +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xc368f8e6 btcx_align +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xcda0ded2 btcx_screen_clips +EXPORT_SYMBOL drivers/media/video/cpia 0x4c4809bf cpia_register_camera +EXPORT_SYMBOL drivers/media/video/cpia 0xd74213ec cpia_unregister_camera +EXPORT_SYMBOL drivers/media/video/cx18/cx18 0x2cdea06d cx18_reset_ir_gpio +EXPORT_SYMBOL drivers/media/video/cx2341x 0x226b4360 cx2341x_ctrl_get_menu +EXPORT_SYMBOL drivers/media/video/cx2341x 0x484d9064 cx2341x_ctrl_query +EXPORT_SYMBOL drivers/media/video/cx2341x 0x61b38569 cx2341x_ext_ctrls +EXPORT_SYMBOL drivers/media/video/cx2341x 0x62f2c86b cx2341x_log_status +EXPORT_SYMBOL drivers/media/video/cx2341x 0x7f09da7c cx2341x_fill_defaults +EXPORT_SYMBOL drivers/media/video/cx2341x 0xcf8b77a4 cx2341x_mpeg_ctrls +EXPORT_SYMBOL drivers/media/video/cx2341x 0xe58ec2e3 cx2341x_update +EXPORT_SYMBOL drivers/media/video/cx88/cx88-vp3054-i2c 0x23da86fc vp3054_i2c_probe +EXPORT_SYMBOL drivers/media/video/cx88/cx88-vp3054-i2c 0xe930611f vp3054_i2c_remove +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x1b8483d8 cx88_get_control +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x1ea67ebb cx88_set_freq +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x41e32c1a cx8800_ctrl_query +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x86376a3f cx88_video_mux +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x9330b798 cx88_set_control +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xa6566e1e cx88_enum_input +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xac4e53b9 cx88_user_ctrls +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x40418029 cx8802_cancel_buffers +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x40778ecc cx8802_buf_queue +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x4eaa6ab0 cx8802_get_device +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x5d975447 cx8802_unregister_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x87a0e64c cx8802_register_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x9bde212a cx8802_get_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0xdc12bc16 cx8802_buf_prepare +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x02ed9e2b cx88_newstation +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x07084be7 cx88_core_irq +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x0e5607b1 cx88_get_stereo +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x1873de59 cx88_set_tvaudio +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x372badb9 cx88_sram_channel_setup +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x57fb8dc7 cx88_set_stereo +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x6141c8c5 cx88_tuner_callback +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x65b45803 cx88_risc_buffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x719f5639 cx88_reset +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x81afba54 cx88_free_buffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x8fd86941 cx88_risc_databuffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x904b8696 cx88_audio_thread +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x9b140fff cx88_sram_channels +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xa91b8614 cx88_vdev_init +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xb175afd4 cx88_set_scale +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xb47f6cda cx88_print_irqbits +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xb8936a2f cx88_ir_start +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xbd166112 cx88_sram_channel_dump +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xbda837ce cx88_risc_stopper +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xc597c19b cx88_ir_stop +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xc62c2e2e cx88_core_get +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xc9ddd44b cx88_core_put +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xcdb68881 cx88_wakeup +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xd5f067c5 cx88_call_i2c_clients +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xd9e9024e cx88_set_tvnorm +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xda32b644 cx88_shutdown +EXPORT_SYMBOL drivers/media/video/em28xx/em28xx 0x4047aafb em28xx_register_extension +EXPORT_SYMBOL drivers/media/video/em28xx/em28xx 0x9f5e4137 em28xx_unregister_extension +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x032cedf1 gspca_frame_add +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x0d3c9539 gspca_disconnect +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x2144b6ec gspca_dev_probe +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x6216e9a7 gspca_get_i_frame +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x8e0427b0 gspca_resume +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x9670af2c gspca_debug +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xc7826e0d gspca_auto_gain_n_exposure +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xe6e33145 gspca_suspend +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x038d654b ivtv_udma_alloc +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x0538e449 ivtv_cards_lock +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x14f67530 ivtv_debug +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x246953a9 ivtv_api +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x2d23c8bf ivtv_set_irq_mask +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x4557f683 ivtv_clear_irq_mask +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x4b88211b ivtv_udma_prepare +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x4e97239c ivtv_vapi_result +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x597dd684 ivtv_udma_unmap +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x5a9deec9 ivtv_reset_ir_gpio +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x69cf5cbf ivtv_cards +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x6af09d83 ivtv_saa7127 +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x70196ffb ivtv_cards_active +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x73d7e718 ivtv_vapi +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xbdadc04d ivtv_udma_setup +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xd422e439 ivtv_init_on_first_open +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x04e83446 saa7134_tuner_callback +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x1211df5d saa7134_devlist +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x1d22c9fd saa7134_dmasound_exit +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x26ee5f39 saa7134_pgtable_alloc +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x4707b40b saa7134_set_dmabits +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x5b923346 saa7134_ts_register +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x6bf85a82 saa7134_tvaudio_setmute +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x73b721e6 saa7134_i2c_call_clients +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x79a061ed saa7134_pgtable_build +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x8e6d66ab saa7134_dmasound_init +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x98af79c1 saa7134_boards +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xb5b9e88c saa7134_pgtable_free +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xcff044a6 saa7134_set_gpio +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xd46340e2 saa_dsp_writel +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xfefdb0f3 saa7134_ts_unregister +EXPORT_SYMBOL drivers/media/video/soc_camera 0x1744e8e4 soc_camera_device_register +EXPORT_SYMBOL drivers/media/video/soc_camera 0x4040fe78 soc_camera_device_unregister +EXPORT_SYMBOL drivers/media/video/soc_camera 0x4d0f0ae0 soc_camera_host_register +EXPORT_SYMBOL drivers/media/video/soc_camera 0x710d219a soc_camera_video_start +EXPORT_SYMBOL drivers/media/video/soc_camera 0x7c5f188c soc_camera_video_stop +EXPORT_SYMBOL drivers/media/video/soc_camera 0x9973eb01 soc_camera_host_unregister +EXPORT_SYMBOL drivers/media/video/tveeprom 0x56023ca7 tveeprom_read +EXPORT_SYMBOL drivers/media/video/tveeprom 0x6db257a1 tveeprom_hauppauge_analog +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x15a8a2d1 usbvideo_Deregister +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x16a2915c RingQueue_Dequeue +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x407a321c RingQueue_WakeUpInterruptible +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x9c2d0e77 usbvideo_AllocateDevice +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xb0422f1d usbvideo_TestPattern +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xbc783abb usbvideo_RegisterVideoDevice +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xcd460279 usbvideo_register +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xddecac6d RingQueue_Enqueue +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xf5011f67 RingQueue_Flush +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xfa835455 usbvideo_DeinterlaceFrame +EXPORT_SYMBOL drivers/media/video/v4l1-compat 0xa637cd5b v4l_compat_translate_ioctl +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x00973900 v4l2_chip_match_i2c_client +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x03165a85 v4l2_ctrl_get_menu +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x0dfb5e57 v4l2_prio_max +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x1c427ecb v4l2_ctrl_query_fill +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x2de2b633 v4l2_prio_check +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x2e9a955d v4l2_prio_close +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x42c8e001 v4l2_ctrl_next +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x495426ee v4l2_ctrl_get_name +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x50766d69 v4l2_ctrl_query_menu_valid_items +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x57abfbd8 v4l2_chip_match_host +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x57f3c1b8 v4l2_chip_ident_i2c_client +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x5fef1b4a v4l2_ctrl_query_fill_std +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x942892ab v4l2_prio_open +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xad3ee6b4 v4l2_i2c_attach +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xb2d1e17e v4l2_prio_change +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xc369097d v4l2_ctrl_check +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xd464e760 v4l2_ctrl_query_menu +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xe330bce9 v4l2_prio_init +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x09905bef videobuf_dvb_dealloc_frontends +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x39abcf09 videobuf_dvb_find_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x90321705 videobuf_dvb_unregister_bus +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0xa5f8fb8e videobuf_dvb_alloc_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0xa77843f7 videobuf_dvb_get_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0xaf304e9e videobuf_dvb_register_bus +EXPORT_SYMBOL drivers/media/video/videodev 0x123959a1 v4l2_type_names +EXPORT_SYMBOL drivers/media/video/videodev 0x163e8353 video_devdata +EXPORT_SYMBOL drivers/media/video/videodev 0x3adbd595 v4l2_field_names +EXPORT_SYMBOL drivers/media/video/videodev 0x5ebefe4b v4l_printk_ioctl +EXPORT_SYMBOL drivers/media/video/videodev 0x7211d804 __video_ioctl2 +EXPORT_SYMBOL drivers/media/video/videodev 0x77e36599 video_device_release +EXPORT_SYMBOL drivers/media/video/videodev 0x8c8883e6 video_device_alloc +EXPORT_SYMBOL drivers/media/video/videodev 0x8d7fa3aa video_ioctl2 +EXPORT_SYMBOL drivers/media/video/videodev 0x8db1a2c9 video_usercopy +EXPORT_SYMBOL drivers/media/video/videodev 0xb938b3af video_device_release_empty +EXPORT_SYMBOL drivers/media/video/videodev 0xc6849bf7 video_register_device +EXPORT_SYMBOL drivers/media/video/videodev 0xc987d1f5 video_unregister_device +EXPORT_SYMBOL drivers/media/video/videodev 0xcfd6e46b video_register_device_index +EXPORT_SYMBOL drivers/media/video/videodev 0xe2b92059 v4l2_video_std_construct +EXPORT_SYMBOL drivers/media/video/videodev 0xf3251e7b v4l2_norm_to_name +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0x5d940430 videocodec_register +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0x6068f54e videocodec_detach +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0xd4f479d5 videocodec_attach +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0xec014351 videocodec_unregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x0380f003 mpt_raid_phys_disk_pg0 +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x10498473 mpt_put_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x2273771b mpt_resume +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x25688c83 mpt_attach +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x2f548a8b mpt_free_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x313586bb mpt_HardResetHandler +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x375d8126 mpt_add_sge +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x4526289b mpt_event_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x532d29b2 mpt_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x591f2377 mpt_get_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x5fa40085 mpt_findImVolumes +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x67dadd13 mpt_event_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x6e7e8d27 mpt_config +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x7001bfb0 mpt_free_fw_memory +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x7aa91a61 mpt_reset_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x89de7807 mpt_detach +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x9f681d6a mpt_alloc_fw_memory +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xb552f306 mpt_device_driver_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xbd6887d7 mpt_put_msg_frame_hi_pri +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc0e69f82 mpt_device_driver_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc1d2cf95 mpt_suspend +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc47c22e8 mpt_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc67d3509 mpt_GetIocState +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xcc857747 mpt_verify_adapter +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xcfe0c19c mpt_print_ioc_summary +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xd9a92a75 mpt_reset_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xdd805159 ioc_list +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xe2de3d47 mpt_send_handshake_request +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xe878f2a6 mptbase_sas_persist_operation +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x0c76b6a6 mptscsih_remove +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x1226e7f9 mptscsih_info +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x18da7c9a mptscsih_taskmgmt_complete +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x22416150 mptscsih_abort +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x24e4f346 mptscsih_bios_param +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x25f345c5 mptscsih_raid_id_to_num +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x293fc3f0 mptscsih_bus_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x3723e47a mptscsih_shutdown +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x3ef822d7 mptscsih_slave_configure +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x3ff7b7d7 mptscsih_resume +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x51dd18c4 mptscsih_scandv_complete +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x5e2c055d mptscsih_TMHandler +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x64dd4f55 mptscsih_proc_info +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x693a4098 mptscsih_host_attrs +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x764ddf1a mptscsih_timer_expired +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x7b23de53 mptscsih_event_process +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x8e3249af mptscsih_ioc_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x99cde541 mptscsih_change_queue_depth +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xada5edcf mptscsih_host_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xbd0e04ca mptscsih_dev_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xd01bd5fc mptscsih_is_phys_disk +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xd67f8e44 mptscsih_io_done +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xdd228e23 mptscsih_qcmd +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xe5fa9158 mptscsih_slave_destroy +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xf9fb2ac8 mptscsih_suspend +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x12f1f798 i2o_driver_unregister +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x1f8cf8a3 i2o_driver_notify_device_remove_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x2a843bef i2o_dump_message +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x416a3c34 i2o_driver_notify_controller_remove_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x4e567c79 i2o_msg_get_wait +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x51e95161 i2o_find_iop +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x58c56a20 i2o_msg_post_wait_mem +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x7a09b3e8 i2o_driver_register +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x7d8d4efd i2o_driver_notify_controller_add_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x90242ccc i2o_parm_table_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xab72ae8f i2o_device_claim +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xac396cb3 i2o_parm_field_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xb2ddff8c i2o_exec_lct_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xb4c00dcf i2o_controllers +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xb8d4c7af i2o_status_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xc043794a i2o_driver_notify_device_add_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xca1cc66c i2o_iop_find_device +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xd30b6c1e i2o_event_register +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xd6bb55b5 i2o_device_claim_release +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xf32a9d97 i2o_parm_issue +EXPORT_SYMBOL drivers/mfd/htc-pasic3 0x700140c7 pasic3_write_register +EXPORT_SYMBOL drivers/mfd/htc-pasic3 0xb3243b9d pasic3_read_register +EXPORT_SYMBOL drivers/misc/c2port/core 0x1a00ddd2 c2port_device_register +EXPORT_SYMBOL drivers/misc/c2port/core 0xe686e8d5 c2port_device_unregister +EXPORT_SYMBOL drivers/misc/ioc4 0x73478aab ioc4_register_submodule +EXPORT_SYMBOL drivers/misc/ioc4 0xd2054eaf ioc4_unregister_submodule +EXPORT_SYMBOL drivers/misc/sony-laptop 0x5bb1e117 sony_pic_camera_command +EXPORT_SYMBOL drivers/misc/tifm_core 0x16e8c0c2 tifm_eject +EXPORT_SYMBOL drivers/misc/tifm_core 0x277e1280 tifm_register_driver +EXPORT_SYMBOL drivers/misc/tifm_core 0x374e1191 tifm_free_device +EXPORT_SYMBOL drivers/misc/tifm_core 0x39f86aa1 tifm_queue_work +EXPORT_SYMBOL drivers/misc/tifm_core 0x3f119795 tifm_unregister_driver +EXPORT_SYMBOL drivers/misc/tifm_core 0x4e4e12f9 tifm_alloc_device +EXPORT_SYMBOL drivers/misc/tifm_core 0x64fdf253 tifm_remove_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0x669a2366 tifm_free_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0x6ba41631 tifm_add_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0x930e6769 tifm_map_sg +EXPORT_SYMBOL drivers/misc/tifm_core 0xa9556330 tifm_unmap_sg +EXPORT_SYMBOL drivers/misc/tifm_core 0xd045a0bb tifm_alloc_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0xef11a039 tifm_has_ms_pif +EXPORT_SYMBOL drivers/mmc/card/mmc_block 0x64ca0f3e mmc_cleanup_queue +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0x4691a17a cfi_read_pri +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0xa971cd9f cfi_fixup +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0xbd8cd636 cfi_varsize_frob +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x4f314ab9 do_map_probe +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x6315abd1 map_destroy +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x78df02de unregister_mtd_chip_driver +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x9cdd55e3 register_mtd_chip_driver +EXPORT_SYMBOL drivers/mtd/chips/gen_probe 0x5d192190 mtd_do_chip_probe +EXPORT_SYMBOL drivers/mtd/maps/map_funcs 0x70582b3b simple_map_init +EXPORT_SYMBOL drivers/mtd/mtd 0x417901cb del_mtd_partitions +EXPORT_SYMBOL drivers/mtd/mtd 0xd74b0245 add_mtd_partitions +EXPORT_SYMBOL drivers/mtd/mtdconcat 0x83ab5364 mtd_concat_create +EXPORT_SYMBOL drivers/mtd/mtdconcat 0xf9ca865e mtd_concat_destroy +EXPORT_SYMBOL drivers/mtd/nand/nand 0x4ba5a176 nand_default_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand 0xa14e4112 nand_scan_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0x5930200b nand_correct_data +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0x5b8ad617 nand_calculate_ecc +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0x836bdb72 nand_flash_ids +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0xa336feb7 nand_manuf_ids +EXPORT_SYMBOL drivers/mtd/onenand/onenand 0x6bd19823 onenand_default_bbt +EXPORT_SYMBOL drivers/mtd/onenand/onenand 0xf31e665d onenand_scan_bbt +EXPORT_SYMBOL drivers/net/8390 0x4d99b509 ei_poll +EXPORT_SYMBOL drivers/net/8390 0x7d7e0dbc ei_interrupt +EXPORT_SYMBOL drivers/net/8390 0x9f2d5f39 ei_open +EXPORT_SYMBOL drivers/net/8390 0xa44dd2d6 ei_close +EXPORT_SYMBOL drivers/net/8390 0xc0b0fbc5 __alloc_ei_netdev +EXPORT_SYMBOL drivers/net/8390 0xed65c0c6 NS8390_init +EXPORT_SYMBOL drivers/net/8390p 0x07ec357c eip_close +EXPORT_SYMBOL drivers/net/8390p 0x288177e7 __alloc_eip_netdev +EXPORT_SYMBOL drivers/net/8390p 0x433b49cd eip_poll +EXPORT_SYMBOL drivers/net/8390p 0x4d8eb827 NS8390p_init +EXPORT_SYMBOL drivers/net/8390p 0x82ca815b eip_open +EXPORT_SYMBOL drivers/net/8390p 0x841bc69f eip_interrupt +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x0f60ea6e arcnet_unregister_proto +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x2f4247c9 arc_proto_map +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x4641bd7d arcnet_interrupt +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x48f83386 arc_bcast_proto +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x6534792a arcnet_debug +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x8147b40e arc_proto_default +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0xc62b617b arc_raw_proto +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0xd8399f51 alloc_arcdev +EXPORT_SYMBOL drivers/net/arcnet/com20020 0x3175a83c com20020_found +EXPORT_SYMBOL drivers/net/arcnet/com20020 0x56264de4 com20020_check +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x357a59b2 t3_l2t_send_event +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x5a472002 cxgb3_unregister_client +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x5ff4a7b0 cxgb3_insert_tid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x8227e967 t3_l2e_free +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x91699cf2 cxgb3_queue_tid_release +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x92ec4b65 cxgb3_register_client +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x93f2ab0f cxgb3_alloc_atid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x96a88e49 cxgb3_free_atid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x9a989ad4 cxgb3_alloc_stid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xb188d2dd t3_register_cpl_handler +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xc0aac85c cxgb3_ofld_send +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xc2217671 t3_l2t_get +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xc97301e8 t3_l2t_send_slow +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xca3b9332 cxgb3_remove_tid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xe7a1c508 cxgb3_free_stid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xf9980e80 dev2t3cdev +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0x51bf6289 hdlcdrv_register +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0x7b49dabd hdlcdrv_receiver +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0xb0b755e8 hdlcdrv_arbitrate +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0xcea033f3 hdlcdrv_unregister +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0xf2eb9b34 hdlcdrv_transmitter +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x01ced14d sirdev_raw_read +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x1644138e sirdev_write_complete +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x2f9067ac sirdev_raw_write +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x3da19d2c irda_register_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x86b551db sirdev_put_instance +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x8795d0d8 sirdev_get_instance +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x909c7aad sirdev_set_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xa8c14752 sirdev_set_dtr_rts +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xd1433b66 sirdev_receive +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xed41cd1f irda_unregister_dongle +EXPORT_SYMBOL drivers/net/mii 0x0aee56a0 mii_ethtool_gset +EXPORT_SYMBOL drivers/net/mii 0x32c9e168 mii_link_ok +EXPORT_SYMBOL drivers/net/mii 0x6b08d89b mii_check_gmii_support +EXPORT_SYMBOL drivers/net/mii 0xaa1b9a2a mii_nway_restart +EXPORT_SYMBOL drivers/net/mii 0xabffa3a9 mii_check_link +EXPORT_SYMBOL drivers/net/mii 0xb291bcf1 mii_ethtool_sset +EXPORT_SYMBOL drivers/net/mii 0xcfce12b5 mii_check_media +EXPORT_SYMBOL drivers/net/mii 0xfc3bf907 generic_mii_ioctl +EXPORT_SYMBOL drivers/net/phy/mdio-bitbang 0x45fec05b free_mdio_bitbang +EXPORT_SYMBOL drivers/net/phy/mdio-bitbang 0xf2940737 alloc_mdio_bitbang +EXPORT_SYMBOL drivers/net/pppox 0x354d21ac register_pppox_proto +EXPORT_SYMBOL drivers/net/pppox 0x8e7d83be pppox_ioctl +EXPORT_SYMBOL drivers/net/pppox 0xb2a1fa71 pppox_unbind_sock +EXPORT_SYMBOL drivers/net/pppox 0xe0ff7a18 unregister_pppox_proto +EXPORT_SYMBOL drivers/net/sungem_phy 0x8eba2b1c mii_phy_probe +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x518fcbfb tms380tr_interrupt +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x53f5b562 tmsdev_term +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x61acd617 tms380tr_open +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x684fcf16 tmsdev_init +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x78655e90 tms380tr_close +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0xd2328794 tms380tr_wait +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x38da4725 cycx_intr +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x62be23ea cycx_setup +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x66a4c4e6 cycx_down +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x968458a6 cycx_peek +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0xb6f383de cycx_poke +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0xfe7cd576 cycx_exec +EXPORT_SYMBOL drivers/net/wan/hdlc 0x28d33135 hdlc_ioctl +EXPORT_SYMBOL drivers/net/wan/hdlc 0x2e937a88 attach_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0x7a1a6a35 hdlc_close +EXPORT_SYMBOL drivers/net/wan/hdlc 0x811da8e1 detach_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0xa8eee9d4 hdlc_open +EXPORT_SYMBOL drivers/net/wan/hdlc 0xc02c1a28 register_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0xcbfc40e2 unregister_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0xf63b97b3 unregister_hdlc_device +EXPORT_SYMBOL drivers/net/wan/hdlc 0xf9089f41 alloc_hdlcdev +EXPORT_SYMBOL drivers/net/wan/syncppp 0x19659403 sppp_detach +EXPORT_SYMBOL drivers/net/wan/syncppp 0x292d8540 sppp_open +EXPORT_SYMBOL drivers/net/wan/syncppp 0x501290fd sppp_do_ioctl +EXPORT_SYMBOL drivers/net/wan/syncppp 0x643eb169 sppp_reopen +EXPORT_SYMBOL drivers/net/wan/syncppp 0x7b558de9 sppp_attach +EXPORT_SYMBOL drivers/net/wan/syncppp 0x8d221b94 sppp_close +EXPORT_SYMBOL drivers/net/wan/z85230 0x0e17b483 z8530_dma_sync +EXPORT_SYMBOL drivers/net/wan/z85230 0x10c78988 z8530_dead_port +EXPORT_SYMBOL drivers/net/wan/z85230 0x14e4c652 z8530_null_rx +EXPORT_SYMBOL drivers/net/wan/z85230 0x16210821 z8530_sync_txdma_close +EXPORT_SYMBOL drivers/net/wan/z85230 0x16e35b0a z8530_describe +EXPORT_SYMBOL drivers/net/wan/z85230 0x283e799e z8530_interrupt +EXPORT_SYMBOL drivers/net/wan/z85230 0x4aedaac9 z8530_queue_xmit +EXPORT_SYMBOL drivers/net/wan/z85230 0x5cd24d29 z8530_hdlc_kilostream +EXPORT_SYMBOL drivers/net/wan/z85230 0x6ec16fd5 z8530_sync_txdma_open +EXPORT_SYMBOL drivers/net/wan/z85230 0x7487bdb5 z8530_sync +EXPORT_SYMBOL drivers/net/wan/z85230 0x7db21934 z8530_shutdown +EXPORT_SYMBOL drivers/net/wan/z85230 0x846e5ce8 z8530_sync_dma_close +EXPORT_SYMBOL drivers/net/wan/z85230 0xb84920f0 z8530_nop +EXPORT_SYMBOL drivers/net/wan/z85230 0xc0ffc7c7 z8530_sync_open +EXPORT_SYMBOL drivers/net/wan/z85230 0xe3d80064 z8530_hdlc_kilostream_85230 +EXPORT_SYMBOL drivers/net/wan/z85230 0xe53647c1 z8530_sync_close +EXPORT_SYMBOL drivers/net/wan/z85230 0xf0a9f0ce z8530_channel_load +EXPORT_SYMBOL drivers/net/wan/z85230 0xf31b3d19 z8530_sync_dma_open +EXPORT_SYMBOL drivers/net/wan/z85230 0xf517d656 z8530_init +EXPORT_SYMBOL drivers/net/wan/z85230 0xf6af08bf z8530_txdma_sync +EXPORT_SYMBOL drivers/net/wireless/airo 0x5457f049 stop_airo_card +EXPORT_SYMBOL drivers/net/wireless/airo 0x8092c3ff init_airo_card +EXPORT_SYMBOL drivers/net/wireless/airo 0xe55b1106 reset_airo_card +EXPORT_SYMBOL drivers/net/wireless/atmel 0x5f7fa5d5 atmel_open +EXPORT_SYMBOL drivers/net/wireless/atmel 0xb5d4a22f init_atmel_card +EXPORT_SYMBOL drivers/net/wireless/atmel 0xebc5e53b stop_atmel_card +EXPORT_SYMBOL drivers/net/wireless/hermes 0x4196c38b hermes_write_ltv +EXPORT_SYMBOL drivers/net/wireless/hermes 0xa031d8e4 hermes_doicmd_wait +EXPORT_SYMBOL drivers/net/wireless/hermes 0xc60b5e9e hermes_bap_pwrite +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd38d8ae2 hermes_read_ltv +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd3f714e5 hermes_bap_pread +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd5168829 hermes_allocate +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd5336e5d hermes_init +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd54e219d hermes_docmd_wait +EXPORT_SYMBOL drivers/net/wireless/hermes 0xed47b224 hermes_struct_init +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x161a199c hermes_program +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x2e340491 hermesi_program_end +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x3e7d91b2 hermesi_program_init +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x79a2030e hermes_read_pda +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xc4026a52 hermes_apply_pda +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xcbd49cae hermes_apply_pda_with_defaults +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xeeef9f73 hermes_blocks_length +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x01c3666a hostap_get_stats +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x0204174b hostap_set_roaming +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x0ad69602 hostap_set_multicast_list_queue +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x0c3e8684 hostap_set_word +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x1dcde936 hostap_check_sta_fw_version +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x2d9abe17 hostap_free_data +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x451fcef0 hostap_80211_rx +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x561c351e hostap_set_hostapd +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x5e3c6b7e hostap_get_porttype +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x6903f16c hostap_80211_get_hdrlen +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x6ce9799a hostap_info_process +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x80fdaa7c hostap_set_hostapd_sta +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x8d815aab hostap_remove_proc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xa12ad27f hostap_dump_tx_header +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xa24129c5 hostap_init_data +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xa397f792 hostap_set_encryption +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xa9ee66ba hostap_set_antsel +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xa9ee82c1 hostap_info_init +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xac597671 hostap_master_start_xmit +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xafa7cdee hostap_init_proc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xb2a945e0 hostap_dump_rx_header +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xbaa6c3db hostap_handle_sta_tx_exc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xc6260863 hostap_set_string +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xcbb07a2d prism2_update_comms_qual +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xde8a9571 hostap_80211_ops +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xe4116edc hostap_remove_interface +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xe698bdbf hostap_init_ap_proc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xe6c14265 hostap_add_interface +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xf9bd0183 hostap_set_auth_algs +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xfe2574a2 hostap_setup_dev +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x0367e1c2 iwl_power_disable_management +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x052e2655 iwl_rfkill_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x05652cc6 iwl_init_sensitivity +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x0ae06472 iwl_dump_nic_error_log +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x100ab0eb iwl_rxon_add_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x105404bf iwl_hw_detect +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x199b484a iwl_setup_mac +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x1a3dfc69 iwl_scan_cancel +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x1a8e1681 iwl_is_fat_tx_allowed +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x1b65d466 iwl_power_cancel_timeout +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x1d3c3630 iwl_rfkill_set_hw_state +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x1d77b399 iwl_bcast_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x24fb7ae0 iwl_eeprom_query_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x25010731 iwl_init_drv +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x278d6376 iwl_rx_queue_restock +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x27b0cb4a iwl_set_rxon_chain +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2a380d39 iwl_eeprom_query16 +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2d08eaee iwl_sensitivity_calibration +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2f6b336e iwl_set_rxon_channel +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2fa84781 iwl_eeprom_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2fc56ee3 iwl_power_enable_management +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x329d4faa iwl_add_station_flags +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x337d4e39 iwl_scan_initiate +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x34fb1d27 iwlcore_eeprom_release_semaphore +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x36c92ff7 iwl_eeprom_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x386c09c3 iwl_eeprom_get_mac +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x3dc68716 iwl_leds_background +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x3e1f1340 iwl_txq_ctx_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x409119f8 iwl_setup_scan_deferred_work +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x41c0308a iwl_reset_run_time_calib +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x43711081 iwl_send_lq_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x4a1127d4 iwl_get_channel_info +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x4ab0c4a8 iwl_get_ra_sta_id +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x4fc7890b iwl_init_channel_map +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x51ef7878 iwl_rx_queue_reset +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x52b656d1 iwl_set_hw_params +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x582166ec iwl_txq_update_write_ptr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5b084db8 iwl_rx_queue_update_write_ptr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5f9cc70a iwl_rx_agg_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5ff4b7f9 iwlcore_eeprom_acquire_semaphore +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x60928297 iwl_send_add_sta +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x626b1a6c iwl_power_initialize +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x62727d56 iwl_calib_set +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x64cc55fb iwl_sta_modify_enable_tid_tx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x64dcc6e2 iwl_rx_missed_beacon_notif +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x66e45d85 iwl_set_dynamic_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x6cb70ee8 iwl_rx_queue_alloc +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x6fd14063 iwl_hw_txq_ctx_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x71704a52 iwl_tx_skb +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7460f797 iwl_radio_kill_sw_enable_radio +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x75d972ca iwl_alloc_all +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x770e76db iwl_leds_unregister +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7ac47403 iwl_rx_statistics +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7bafa05e iwl_remove_default_wep_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7beaaf0e iwl_find_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7f531817 iwl_tx_agg_start +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x82488cf0 iwlcore_eeprom_verify_signature +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x824e4b55 iwl_send_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8670273d iwl_hwrate_to_plcp_idx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x88fe7d37 iwl_hw_nic_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8b1687fa iwl_set_tx_power +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8c12f60c iwl_send_cmd_pdu_async +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8e14522d iwl_send_static_wepkey_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8ee7d2a6 iwl_rx_reply_rx_phy +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x904b4930 iwl_send_statistics_request +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x93df6ea5 iwl_rx_reply_rx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9c238a27 iwl_send_cmd_pdu +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9cde1f24 iwl_queue_space +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa217060f iwl_rx_replenish +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa49bf2b3 iwl_radio_kill_sw_disable_radio +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa9f48bf3 iwl_rf_kill_ct_config +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xaa105f6e iwl_rx_queue_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xabdd8200 iwl_hwrate_to_tx_control +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xaedee342 iwl_send_cmd_sync +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb1668edc iwl_verify_ucode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb5da4b5f iwl_dump_nic_event_log +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb7c0b55b iwlcore_eeprom_query_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb815529d iwl_tx_queue_reclaim +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb8161601 iwl_power_set_user_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb8b493bc iwl_chain_noise_calibration +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc232c81c iwl_rx_agg_start +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc27dc38a iwl_set_default_wep_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc2bed48b iwl_leds_register +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc711b025 iwl_reset_qos +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcb01ad7e iwl_setup_power_deferred_work +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcbaf4931 get_cmd_string +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcca6bc91 iwl_power_set_system_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcdec2abd iwl_scan_cancel_timeout +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcf550d1c iwl_clear_stations_table +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd850cf7c iwl_remove_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd9bb59fe iwl_tx_agg_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xda815b10 iwl_power_update_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xdcccbf35 iwl_power_temperature_change +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe08abd3f iwl_txq_check_empty +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe7ce5d70 iwl_rates +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe7e3992b iwl_remove_dynamic_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xec002ce6 iwl_rxq_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xec0577bd iwl_eeprom_check_version +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xec18742e iwl_setup_rx_scan_handlers +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xec6cc329 iwl_rx_reply_compressed_ba +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xed9888cd iwl_send_calib_results +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xefae0121 iwl_get_sta_id +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xf3d1753e iwl_rfkill_unregister +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xf693c8e9 iwl_tx_cmd_complete +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xf77eded5 iwl_uninit_drv +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xf7fee23e iwl_set_rxon_ht +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xf83f207c iwl_rx_queue_space +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x050025a5 alloc_orinocodev +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x1a9d334a orinoco_interrupt +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x340ea06c __orinoco_up +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x819ba2fc __orinoco_down +EXPORT_SYMBOL drivers/net/wireless/orinoco 0xaf663b0f free_orinocodev +EXPORT_SYMBOL drivers/net/wireless/orinoco 0xb93ccef2 orinoco_reinit_firmware +EXPORT_SYMBOL drivers/parport/parport 0x0984e3ab parport_ieee1284_ecp_read_data +EXPORT_SYMBOL drivers/parport/parport 0x18e24129 parport_wait_peripheral +EXPORT_SYMBOL drivers/parport/parport 0x19848867 parport_find_number +EXPORT_SYMBOL drivers/parport/parport 0x1b539f13 parport_claim_or_block +EXPORT_SYMBOL drivers/parport/parport 0x1c575c51 parport_release +EXPORT_SYMBOL drivers/parport/parport 0x1dbe8d84 parport_irq_handler +EXPORT_SYMBOL drivers/parport/parport 0x1e8e6dd5 parport_unregister_device +EXPORT_SYMBOL drivers/parport/parport 0x3b96b289 parport_ieee1284_epp_write_data +EXPORT_SYMBOL drivers/parport/parport 0x4b4a1ce4 parport_claim +EXPORT_SYMBOL drivers/parport/parport 0x4d2a941b parport_ieee1284_interrupt +EXPORT_SYMBOL drivers/parport/parport 0x5993de38 parport_read +EXPORT_SYMBOL drivers/parport/parport 0x5c796081 parport_ieee1284_epp_write_addr +EXPORT_SYMBOL drivers/parport/parport 0x696bd525 parport_ieee1284_epp_read_addr +EXPORT_SYMBOL drivers/parport/parport 0x6a3ab51a parport_wait_event +EXPORT_SYMBOL drivers/parport/parport 0x7428cb3f parport_announce_port +EXPORT_SYMBOL drivers/parport/parport 0x7a2ea54a parport_put_port +EXPORT_SYMBOL drivers/parport/parport 0x89475e1c parport_get_port +EXPORT_SYMBOL drivers/parport/parport 0x8ffeac80 parport_unregister_driver +EXPORT_SYMBOL drivers/parport/parport 0x9ad917e7 parport_register_port +EXPORT_SYMBOL drivers/parport/parport 0xa643da95 parport_ieee1284_epp_read_data +EXPORT_SYMBOL drivers/parport/parport 0xae82077b parport_ieee1284_ecp_write_data +EXPORT_SYMBOL drivers/parport/parport 0xc96dd573 parport_ieee1284_ecp_write_addr +EXPORT_SYMBOL drivers/parport/parport 0xc9a8cd7a parport_find_base +EXPORT_SYMBOL drivers/parport/parport 0xce06f8bf parport_register_device +EXPORT_SYMBOL drivers/parport/parport 0xe0cfedb0 parport_write +EXPORT_SYMBOL drivers/parport/parport 0xe7b458ce parport_register_driver +EXPORT_SYMBOL drivers/parport/parport 0xeb43e9fe parport_negotiate +EXPORT_SYMBOL drivers/parport/parport 0xf4a1b31c parport_set_timeout +EXPORT_SYMBOL drivers/parport/parport 0xf6627de9 parport_ieee1284_read_byte +EXPORT_SYMBOL drivers/parport/parport 0xf8fd919e parport_ieee1284_read_nibble +EXPORT_SYMBOL drivers/parport/parport 0xfab4a026 parport_remove_port +EXPORT_SYMBOL drivers/parport/parport 0xff849a79 parport_ieee1284_write_compat +EXPORT_SYMBOL drivers/parport/parport_pc 0x0b46cfa3 parport_pc_unregister_port +EXPORT_SYMBOL drivers/parport/parport_pc 0xfef06e8a parport_pc_probe_port +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x0e2c0b52 pcmcia_map_mem_page +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x21ba564e pcmcia_request_io +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x32d5c4eb pcmcia_disable_device +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x38bff47f pcmcia_request_irq +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x3a99246e pcmcia_get_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x4038d59c pcmcia_request_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x42398dae pcmcia_request_configuration +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x49e8e950 pcmcia_get_mem_page +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x4fd033a0 pcmcia_error_func +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x586f8eaa pcmcia_loop_config +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x71904bc5 pcmcia_register_driver +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x7d730954 pcmcia_release_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x8eee67db pcmcia_unregister_driver +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xb47431da pcmcia_dev_present +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xd45de837 pcmcia_modify_configuration +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xe71a74f8 pcmcia_access_configuration_register +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xf0a25e12 pcmcia_error_ret +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x02d819e4 pcmcia_reset_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x0712f7de pccard_get_next_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x0b93f75c pcmcia_find_io_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x0d51a1f8 pccard_read_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x119c34f8 pcmcia_get_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x1e9530a8 pcmcia_get_socket_by_nr +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x212db8d2 pcmcia_socket_list +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x33fcb415 pccard_validate_cis +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x3b483b2b pcmcia_eject_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x408bae40 pcmcia_socket_dev_suspend +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x4729418f destroy_cis_cache +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x4adfbe8f pcmcia_socket_class +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x4b3a566b pccard_get_tuple_data +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x55f801f4 pcmcia_unregister_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x63750b03 pcmcia_validate_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x701b6b90 pcmcia_write_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x723427d3 release_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x7c4d9a24 pccard_get_first_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x7c872749 pcmcia_insert_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x85c3de5f pcmcia_read_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xaa862dea pcmcia_register_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xadac1e6c pcmcia_adjust_io_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xb0f16f5b pcmcia_replace_cis +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xb91a0549 pcmcia_find_mem_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xbfe53b83 pcmcia_parse_events +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xc02ef2c8 pcmcia_parse_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xc368f687 pcmcia_socket_list_rwsem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xcf97f3bd dead_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xe3a7dffc pcmcia_socket_dev_resume +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xe6bc7c52 pcmcia_put_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xeded3ae1 pccard_register_pcmcia +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xf1e57548 pcmcia_suspend_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xf2f61fd9 pccard_static_ops +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xf35eb9f2 pcmcia_resume_card +EXPORT_SYMBOL drivers/pcmcia/rsrc_nonstatic 0x2f57a046 pccard_nonstatic_ops +EXPORT_SYMBOL drivers/scsi/53c700 0x1c0c4826 NCR_700_detect +EXPORT_SYMBOL drivers/scsi/53c700 0x5175c0f0 NCR_700_intr +EXPORT_SYMBOL drivers/scsi/53c700 0xac6e4de1 NCR_700_release +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0x16e98204 mraid_mm_register_adp +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0x2250c66e mraid_mm_adapter_app_handle +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0x512c956d mraid_mm_unregister_adp +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x118d087e qlogicfas408_biosparam +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x2bb89105 qlogicfas408_queuecommand +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x3fa8ccb5 qlogicfas408_disable_ints +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x3fd8cd71 qlogicfas408_detect +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x594f893c qlogicfas408_abort +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x5cd179e6 qlogicfas408_ihandl +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x71e97acc qlogicfas408_bus_reset +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x86381295 qlogicfas408_info +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xe76b3b20 qlogicfas408_get_chip_type +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xf2b95199 qlogicfas408_setup +EXPORT_SYMBOL drivers/scsi/raid_class 0x9fbc40be raid_class_attach +EXPORT_SYMBOL drivers/scsi/raid_class 0xa2a4dbc1 raid_component_add +EXPORT_SYMBOL drivers/scsi/raid_class 0xafa30736 raid_class_release +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x0faa7f72 fc_remote_port_rolechg +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x14b8d56f scsi_is_fc_rport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x1804d99d fc_host_post_event +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x4333263c fc_remove_host +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x49c4aa6c fc_remote_port_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x67ad9e61 fc_remote_port_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x7954b1ea fc_get_event_number +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x87bd0358 fc_host_post_vendor_event +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xb07b5f09 fc_vport_create +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xc0737c9b fc_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xd08c9d74 fc_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xda16903e scsi_is_fc_vport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xe5d037c9 fc_vport_terminate +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x02d24900 sas_port_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x1839cfab sas_port_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x1c3873a3 sas_remove_host +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x26590119 sas_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x282c32a8 sas_rphy_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x33a6583f sas_read_port_mode_page +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x3fd12fd4 sas_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x452eb70d sas_port_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x48e07efa sas_port_alloc_num +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x66efd0bf sas_phy_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x67fc5a2f sas_port_mark_backlink +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x6efa94dc sas_remove_children +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x728b7ff2 scsi_is_sas_port +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x73c81ff3 sas_phy_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x7d2aae2e sas_end_device_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x804c3b49 sas_rphy_remove +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x82d5b5bb sas_expander_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x96ce9a39 sas_port_add_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xa46c16bc sas_rphy_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xb55e5175 scsi_is_sas_rphy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xc3ca197f sas_phy_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xd5ac1c32 sas_phy_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xd74d7d1b sas_port_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xda69c1aa sas_port_delete_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xee112f22 scsi_is_sas_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xf292c99b sas_rphy_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x3668ff07 spi_dv_device +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x3686ea09 spi_print_msg +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x54dc739b spi_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x62397571 spi_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x63fe041a spi_schedule_dv_device +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x7893f946 spi_display_xfer_agreement +EXPORT_SYMBOL drivers/ssb/ssb 0x0671f0ff ssb_bus_may_powerdown +EXPORT_SYMBOL drivers/ssb/ssb 0x06b3f93f ssb_driver_unregister +EXPORT_SYMBOL drivers/ssb/ssb 0x318d02d1 ssb_device_is_enabled +EXPORT_SYMBOL drivers/ssb/ssb 0x31a87d38 ssb_bus_pcibus_register +EXPORT_SYMBOL drivers/ssb/ssb 0x5259097c ssb_device_enable +EXPORT_SYMBOL drivers/ssb/ssb 0x64facb3a ssb_set_devtypedata +EXPORT_SYMBOL drivers/ssb/ssb 0x754ae721 ssb_bus_unregister +EXPORT_SYMBOL drivers/ssb/ssb 0x7a02a228 ssb_bus_suspend +EXPORT_SYMBOL drivers/ssb/ssb 0x7bf39a25 __ssb_driver_register +EXPORT_SYMBOL drivers/ssb/ssb 0x85e1cdc2 ssb_dma_free_consistent +EXPORT_SYMBOL drivers/ssb/ssb 0x983dfc91 ssb_device_disable +EXPORT_SYMBOL drivers/ssb/ssb 0xa1dcf458 ssb_dma_alloc_consistent +EXPORT_SYMBOL drivers/ssb/ssb 0xa98005d3 ssb_pcicore_dev_irqvecs_enable +EXPORT_SYMBOL drivers/ssb/ssb 0xc0512e0f ssb_admatch_base +EXPORT_SYMBOL drivers/ssb/ssb 0xd481192b ssb_admatch_size +EXPORT_SYMBOL drivers/ssb/ssb 0xd5a5ef74 ssb_dma_set_mask +EXPORT_SYMBOL drivers/ssb/ssb 0xd7933ba9 ssb_clockspeed +EXPORT_SYMBOL drivers/ssb/ssb 0xdb3b297f ssb_bus_resume +EXPORT_SYMBOL drivers/ssb/ssb 0xea455f92 ssb_pcihost_register +EXPORT_SYMBOL drivers/ssb/ssb 0xf43dbcae ssb_dma_translation +EXPORT_SYMBOL drivers/ssb/ssb 0xf93e2568 ssb_bus_powerup +EXPORT_SYMBOL drivers/telephony/ixj 0x307289ea ixj_pcmcia_probe +EXPORT_SYMBOL drivers/telephony/phonedev 0x0d078c6a phone_unregister_device +EXPORT_SYMBOL drivers/telephony/phonedev 0xdee1e20c phone_register_device +EXPORT_SYMBOL drivers/usb/gadget/dummy_hcd 0x84970a0d usb_gadget_register_driver +EXPORT_SYMBOL drivers/usb/gadget/dummy_hcd 0xd4ac7935 usb_gadget_unregister_driver +EXPORT_SYMBOL drivers/usb/gadget/dummy_hcd 0xf479bd0d net2280_set_fifo_mode +EXPORT_SYMBOL drivers/usb/host/sl811-hcd 0x6917d995 sl811h_driver +EXPORT_SYMBOL drivers/video/backlight/corgi_bl 0xc86baa7c corgibl_limit_intensity +EXPORT_SYMBOL drivers/video/backlight/lcd 0x1237e6f5 lcd_device_unregister +EXPORT_SYMBOL drivers/video/backlight/lcd 0xbf261374 lcd_device_register +EXPORT_SYMBOL drivers/video/console/bitblit 0x581be589 fbcon_set_bitops +EXPORT_SYMBOL drivers/video/console/font 0x09c8eb55 font_vga_8x16 +EXPORT_SYMBOL drivers/video/console/font 0xbb99125c get_default_font +EXPORT_SYMBOL drivers/video/console/font 0xf7584a9c find_font +EXPORT_SYMBOL drivers/video/console/softcursor 0x97312da2 soft_cursor +EXPORT_SYMBOL drivers/video/console/tileblit 0xac5be818 fbcon_set_tileops +EXPORT_SYMBOL drivers/video/cyber2000fb 0x0cc3ede5 cyber2000fb_detach +EXPORT_SYMBOL drivers/video/cyber2000fb 0x31458ce5 cyber2000fb_disable_extregs +EXPORT_SYMBOL drivers/video/cyber2000fb 0x5c322ca3 cyber2000fb_attach +EXPORT_SYMBOL drivers/video/cyber2000fb 0xa1402678 cyber2000fb_enable_extregs +EXPORT_SYMBOL drivers/video/cyber2000fb 0xb8f6266e cyber2000fb_get_fb_var +EXPORT_SYMBOL drivers/video/display/display 0x4473724a display_device_register +EXPORT_SYMBOL drivers/video/display/display 0x6f2fbadc display_device_unregister +EXPORT_SYMBOL drivers/video/macmodes 0x08ed0b62 mac_vmode_to_var +EXPORT_SYMBOL drivers/video/macmodes 0x243fe270 mac_find_mode +EXPORT_SYMBOL drivers/video/macmodes 0xe2304303 mac_map_monitor_sense +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0x1f989d6f matroxfb_g450_setpll_cond +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0x1fdf78ea matroxfb_g450_setclk +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0x28aed771 g450_mnp2f +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0x1f2092de matrox_mystique +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0x5ccb1a65 DAC1064_global_restore +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0xe0ae1969 matrox_G100 +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0xfc724513 DAC1064_global_init +EXPORT_SYMBOL drivers/video/matrox/matroxfb_Ti3026 0x52662b98 matrox_millennium +EXPORT_SYMBOL drivers/video/matrox/matroxfb_accel 0x18afeffa matrox_cfbX_init +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0x269a47a5 matroxfb_register_driver +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0xc8039fc8 matroxfb_unregister_driver +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0xe3588e5b matroxfb_enable_irq +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0xf225664a matroxfb_wait_for_sync +EXPORT_SYMBOL drivers/video/matrox/matroxfb_g450 0x31e93f0a matroxfb_g450_connect +EXPORT_SYMBOL drivers/video/matrox/matroxfb_g450 0x6262935d matroxfb_g450_shutdown +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x25cf8049 matroxfb_PLL_calcclock +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x3193fbba matroxfb_vgaHWinit +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x4eae7470 matroxfb_read_pins +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x68f6d13c matroxfb_DAC_out +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x92fbe058 matroxfb_vgaHWrestore +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0xabd8e427 matroxfb_var2my +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0xc086b353 matroxfb_DAC_in +EXPORT_SYMBOL drivers/video/output 0x19b4508a video_output_register +EXPORT_SYMBOL drivers/video/output 0x2d8502e2 video_output_unregister +EXPORT_SYMBOL drivers/video/sis/sisfb 0x3037658e sis_malloc +EXPORT_SYMBOL drivers/video/sis/sisfb 0x454a3cf0 sis_free +EXPORT_SYMBOL drivers/video/svgalib 0x00d1fce9 svga_set_default_seq_regs +EXPORT_SYMBOL drivers/video/svgalib 0x07b3da30 svga_wseq_multi +EXPORT_SYMBOL drivers/video/svgalib 0x1b95c56a svga_check_timings +EXPORT_SYMBOL drivers/video/svgalib 0x47e5fb4f svga_tilecursor +EXPORT_SYMBOL drivers/video/svgalib 0x63e898d1 svga_set_default_crt_regs +EXPORT_SYMBOL drivers/video/svgalib 0x68381bcd svga_get_tilemax +EXPORT_SYMBOL drivers/video/svgalib 0x7a3ae959 svga_wcrt_multi +EXPORT_SYMBOL drivers/video/svgalib 0x80408443 svga_set_timings +EXPORT_SYMBOL drivers/video/svgalib 0x8fa8438b svga_set_textmode_vga_regs +EXPORT_SYMBOL drivers/video/svgalib 0xab3b22ad svga_set_default_gfx_regs +EXPORT_SYMBOL drivers/video/svgalib 0xbda16766 svga_settile +EXPORT_SYMBOL drivers/video/svgalib 0xc990be05 svga_tilecopy +EXPORT_SYMBOL drivers/video/svgalib 0xd5a7c94f svga_tileblit +EXPORT_SYMBOL drivers/video/svgalib 0xdad682b1 svga_set_default_atc_regs +EXPORT_SYMBOL drivers/video/svgalib 0xe936766e svga_get_caps +EXPORT_SYMBOL drivers/video/svgalib 0xec83c473 svga_match_format +EXPORT_SYMBOL drivers/video/svgalib 0xef774f5d svga_compute_pll +EXPORT_SYMBOL drivers/video/svgalib 0xf67ff8f6 svga_tilefill +EXPORT_SYMBOL drivers/video/syscopyarea 0x424b0896 sys_copyarea +EXPORT_SYMBOL drivers/video/sysfillrect 0x26c63c66 sys_fillrect +EXPORT_SYMBOL drivers/video/sysimgblt 0x3ef418da sys_imageblit +EXPORT_SYMBOL drivers/video/vgastate 0x686de290 restore_vga +EXPORT_SYMBOL drivers/video/vgastate 0xe7a2620e save_vga +EXPORT_SYMBOL drivers/w1/slaves/w1_bq27000 0x0ef147f8 w1_bq27000_write +EXPORT_SYMBOL drivers/w1/slaves/w1_bq27000 0x30766848 w1_bq27000_read +EXPORT_SYMBOL drivers/w1/slaves/w1_ds2760 0x0c58777b w1_ds2760_read +EXPORT_SYMBOL drivers/w1/slaves/w1_ds2760 0xed26f24f w1_ds2760_write +EXPORT_SYMBOL drivers/w1/wire 0x12a8cd92 w1_add_master_device +EXPORT_SYMBOL drivers/w1/wire 0x21ee92f7 w1_unregister_family +EXPORT_SYMBOL drivers/w1/wire 0x312fa342 w1_remove_master_device +EXPORT_SYMBOL drivers/w1/wire 0xb854d913 w1_register_family +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0x04e133fc iTCO_vendor_check_noreboot_on +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0x672c9d44 iTCO_vendor_pre_keepalive +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xa78bd894 iTCO_vendor_pre_set_heartbeat +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xa8d6daac iTCO_vendor_pre_start +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xd0efe320 iTCO_vendor_pre_stop +EXPORT_SYMBOL fs/configfs/configfs 0x09eec5b1 configfs_register_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0x26a95739 config_item_set_name +EXPORT_SYMBOL fs/configfs/configfs 0x42b70770 configfs_undepend_item +EXPORT_SYMBOL fs/configfs/configfs 0x6d1cd965 config_item_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0x72125a02 configfs_unregister_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0x7dd0c5f8 config_item_init +EXPORT_SYMBOL fs/configfs/configfs 0x8623b951 configfs_depend_item +EXPORT_SYMBOL fs/configfs/configfs 0xa0c47823 config_item_get +EXPORT_SYMBOL fs/configfs/configfs 0xa4d156a8 config_item_put +EXPORT_SYMBOL fs/configfs/configfs 0xc1344cb1 config_group_init +EXPORT_SYMBOL fs/configfs/configfs 0xe0969648 config_group_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0xf04aa220 config_group_find_item +EXPORT_SYMBOL fs/lockd/lockd 0xa7b91a7b lockd_down +EXPORT_SYMBOL fs/lockd/lockd 0xab2d5214 nlmsvc_ops +EXPORT_SYMBOL fs/lockd/lockd 0xf6933c48 lockd_up +EXPORT_SYMBOL fs/nfs_common/nfs_acl 0x963026b4 nfsacl_decode +EXPORT_SYMBOL fs/nfs_common/nfs_acl 0xc4ffda26 nfsacl_encode +EXPORT_SYMBOL fs/nfsd/nfsd 0x0f3e6e01 nfs4_acl_nfsv4_to_posix +EXPORT_SYMBOL fs/nfsd/nfsd 0x2095976a nfs4_acl_new +EXPORT_SYMBOL fs/nfsd/nfsd 0x35e33c1e nfs4_acl_write_who +EXPORT_SYMBOL fs/nfsd/nfsd 0x5a157ae4 nfs4_acl_get_whotype +EXPORT_SYMBOL fs/nfsd/nfsd 0x7ee78c79 nfs4_acl_posix_to_nfsv4 +EXPORT_SYMBOL fs/xfs/xfs 0xbf2db4c3 xfs_qmcore_xfs +EXPORT_SYMBOL lib/crc-ccitt 0x3771b461 crc_ccitt +EXPORT_SYMBOL lib/crc-ccitt 0x75811312 crc_ccitt_table +EXPORT_SYMBOL lib/crc-itu-t 0xd29b009f crc_itu_t_table +EXPORT_SYMBOL lib/crc-itu-t 0xf5b4a948 crc_itu_t +EXPORT_SYMBOL lib/crc7 0xa7587646 crc7 +EXPORT_SYMBOL lib/crc7 0xd80c3603 crc7_syndrome_table +EXPORT_SYMBOL lib/libcrc32c 0x2329b292 crc32c_be +EXPORT_SYMBOL lib/libcrc32c 0x37d0b921 crc32c_le +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0x315c65fd zlib_deflateInit2 +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0x48034724 zlib_deflateReset +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xaf64ad0d zlib_deflate +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xf0caf44b zlib_deflate_workspacesize +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xf741c793 zlib_deflateEnd +EXPORT_SYMBOL net/802/p8023 0x5d88e1b7 destroy_8023_client +EXPORT_SYMBOL net/802/p8023 0x826b880e make_8023_client +EXPORT_SYMBOL net/9p/9pnet 0x17dc20ef v9fs_get_default_trans +EXPORT_SYMBOL net/9p/9pnet 0x1b0f2e8f p9_client_version +EXPORT_SYMBOL net/9p/9pnet 0x30b0eada p9_client_walk +EXPORT_SYMBOL net/9p/9pnet 0x3455711e p9_idpool_destroy +EXPORT_SYMBOL net/9p/9pnet 0x3d73a797 p9_errstr2errno +EXPORT_SYMBOL net/9p/9pnet 0x510a1089 p9_client_auth +EXPORT_SYMBOL net/9p/9pnet 0x54ab106c p9_client_attach +EXPORT_SYMBOL net/9p/9pnet 0x6b754e6f p9_parse_header +EXPORT_SYMBOL net/9p/9pnet 0x710daef1 p9_client_stat +EXPORT_SYMBOL net/9p/9pnet 0x76b79bf1 p9stat_read +EXPORT_SYMBOL net/9p/9pnet 0x79b8170c p9_client_write +EXPORT_SYMBOL net/9p/9pnet 0x826334c5 p9_client_wstat +EXPORT_SYMBOL net/9p/9pnet 0x82fb3113 p9_client_cb +EXPORT_SYMBOL net/9p/9pnet 0x8c2cf0e3 v9fs_get_trans_by_name +EXPORT_SYMBOL net/9p/9pnet 0x90ade126 p9_client_read +EXPORT_SYMBOL net/9p/9pnet 0x920c01ef p9_client_fcreate +EXPORT_SYMBOL net/9p/9pnet 0x9992e841 v9fs_unregister_trans +EXPORT_SYMBOL net/9p/9pnet 0x9c964743 p9stat_free +EXPORT_SYMBOL net/9p/9pnet 0xaab8671a p9_idpool_get +EXPORT_SYMBOL net/9p/9pnet 0xb582da92 p9_tag_lookup +EXPORT_SYMBOL net/9p/9pnet 0xbae4dc47 p9_client_create +EXPORT_SYMBOL net/9p/9pnet 0xcae61af3 p9_idpool_create +EXPORT_SYMBOL net/9p/9pnet 0xcc5ef711 p9_client_remove +EXPORT_SYMBOL net/9p/9pnet 0xd0cd0ce9 v9fs_register_trans +EXPORT_SYMBOL net/9p/9pnet 0xd0faf92e p9_idpool_check +EXPORT_SYMBOL net/9p/9pnet 0xd331fc1d p9pdu_dump +EXPORT_SYMBOL net/9p/9pnet 0xda70a49d p9_client_clunk +EXPORT_SYMBOL net/9p/9pnet 0xe58a3360 p9_error_init +EXPORT_SYMBOL net/9p/9pnet 0xef01c6a6 p9_client_open +EXPORT_SYMBOL net/9p/9pnet 0xef7127b0 p9_idpool_put +EXPORT_SYMBOL net/9p/9pnet 0xf65e62e6 p9_client_disconnect +EXPORT_SYMBOL net/9p/9pnet 0xfefcd369 p9_client_destroy +EXPORT_SYMBOL net/appletalk/appletalk 0x432093fc alloc_ltalkdev +EXPORT_SYMBOL net/appletalk/appletalk 0x6e542468 atalk_find_dev_addr +EXPORT_SYMBOL net/appletalk/appletalk 0x8de23564 atrtr_get_dev +EXPORT_SYMBOL net/appletalk/appletalk 0xbba98795 aarp_send_ddp +EXPORT_SYMBOL net/ax25/ax25 0x1e84c62a ax25_linkfail_release +EXPORT_SYMBOL net/ax25/ax25 0x242852b9 ax25_uid_policy +EXPORT_SYMBOL net/ax25/ax25 0x3d2d82ec ax25_display_timer +EXPORT_SYMBOL net/ax25/ax25 0x4502c65a asc2ax +EXPORT_SYMBOL net/ax25/ax25 0x49ab5314 ax25_findbyuid +EXPORT_SYMBOL net/ax25/ax25 0x4a5baeb3 ax25_header_ops +EXPORT_SYMBOL net/ax25/ax25 0x4c23daa9 ax25_send_frame +EXPORT_SYMBOL net/ax25/ax25 0x5365c1d3 ax25_linkfail_register +EXPORT_SYMBOL net/ax25/ax25 0x53dea1ff ax2asc +EXPORT_SYMBOL net/ax25/ax25 0x555a23f4 ax25_find_cb +EXPORT_SYMBOL net/ax25/ax25 0x5fc9b5ea ax25_listen_release +EXPORT_SYMBOL net/ax25/ax25 0x6f6f1168 ax25_rebuild_header +EXPORT_SYMBOL net/ax25/ax25 0x8ede9e26 ax25_protocol_release +EXPORT_SYMBOL net/ax25/ax25 0x9a6df2cd ax25_listen_register +EXPORT_SYMBOL net/ax25/ax25 0xc1444946 ax25cmp +EXPORT_SYMBOL net/ax25/ax25 0xc76c8a26 ax25_hard_header +EXPORT_SYMBOL net/ax25/ax25 0xd43ecbf1 null_ax25_address +EXPORT_SYMBOL net/bridge/bridge 0xeb6b034f br_should_route_hook +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0x15dbc5cb ebt_unregister_table +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0x3c0719f8 ebt_do_table +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0x536a96a6 ebt_register_table +EXPORT_SYMBOL net/ieee80211/ieee80211 0x15345c6b ieee80211_set_geo +EXPORT_SYMBOL net/ieee80211/ieee80211 0x30421dc9 ieee80211_txb_free +EXPORT_SYMBOL net/ieee80211/ieee80211 0x40a27312 ieee80211_channel_to_index +EXPORT_SYMBOL net/ieee80211/ieee80211 0x49548346 ieee80211_get_geo +EXPORT_SYMBOL net/ieee80211/ieee80211 0x66ff0534 ieee80211_wx_get_scan +EXPORT_SYMBOL net/ieee80211/ieee80211 0x69c4ddd2 ieee80211_wx_get_encodeext +EXPORT_SYMBOL net/ieee80211/ieee80211 0x6dd8bd05 ieee80211_rx_mgt +EXPORT_SYMBOL net/ieee80211/ieee80211 0x72f8be91 ieee80211_channel_to_freq +EXPORT_SYMBOL net/ieee80211/ieee80211 0x76368633 alloc_ieee80211 +EXPORT_SYMBOL net/ieee80211/ieee80211 0x7ce001c4 ieee80211_wx_set_encode +EXPORT_SYMBOL net/ieee80211/ieee80211 0x9b05dfea ieee80211_rx +EXPORT_SYMBOL net/ieee80211/ieee80211 0xa9fb135f escape_essid +EXPORT_SYMBOL net/ieee80211/ieee80211 0xaa4c8969 ieee80211_is_valid_channel +EXPORT_SYMBOL net/ieee80211/ieee80211 0xacb0f060 ieee80211_networks_age +EXPORT_SYMBOL net/ieee80211/ieee80211 0xcd245938 ieee80211_get_channel +EXPORT_SYMBOL net/ieee80211/ieee80211 0xda6cc4e3 ieee80211_wx_set_encodeext +EXPORT_SYMBOL net/ieee80211/ieee80211 0xe15eed1c free_ieee80211 +EXPORT_SYMBOL net/ieee80211/ieee80211 0xea147c07 ieee80211_wx_get_encode +EXPORT_SYMBOL net/ieee80211/ieee80211 0xf3fbe444 ieee80211_get_channel_flags +EXPORT_SYMBOL net/ieee80211/ieee80211 0xff2f9913 ieee80211_freq_to_channel +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x05f809d1 ieee80211_get_crypto_ops +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x213c773c ieee80211_unregister_crypto_ops +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x279e265f ieee80211_crypt_deinit_handler +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x467220f7 ieee80211_register_crypto_ops +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0xb46160f7 ieee80211_crypt_quiescing +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0xbee8c96f ieee80211_crypt_deinit_entries +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0xd209e51f ieee80211_crypt_delayed_deinit +EXPORT_SYMBOL net/ipv4/inet_lro 0x00c275b4 lro_vlan_hwaccel_receive_skb +EXPORT_SYMBOL net/ipv4/inet_lro 0x577bcb6a lro_flush_all +EXPORT_SYMBOL net/ipv4/inet_lro 0x80f6fac7 lro_receive_skb +EXPORT_SYMBOL net/ipv4/inet_lro 0xbd3888b1 lro_vlan_hwaccel_receive_frags +EXPORT_SYMBOL net/ipv4/inet_lro 0xbd4c11e0 lro_receive_frags +EXPORT_SYMBOL net/ipv4/inet_lro 0xfd9a3860 lro_flush_pkt +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x1f87dcb4 arpt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0xafcd6608 arpt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0xc84b3f3d arpt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0x852040f1 ipt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0xbcf8cdee ipt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0xd08479c0 ipt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x09317cf3 nf_nat_protocol_unregister +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x093387d2 nf_nat_setup_info +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x4857ac26 nf_nat_mangle_tcp_packet +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x62b42a29 nf_nat_follow_master +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x8bb6bb0d nf_nat_mangle_udp_packet +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0xa6636ec6 nf_nat_protocol_register +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0xcf5f7ac6 nf_nat_used_tuple +EXPORT_SYMBOL net/ipv4/tunnel4 0x01a52666 xfrm4_tunnel_register +EXPORT_SYMBOL net/ipv4/tunnel4 0xe5753431 xfrm4_tunnel_deregister +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x1bae0744 ip6t_unregister_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x236c7c5a ipv6_find_hdr +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x82bf4fd3 ip6t_do_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xb30b5a48 ip6t_register_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xb8bddf33 ip6t_ext_hdr +EXPORT_SYMBOL net/ipv6/tunnel6 0x1d612fa1 xfrm6_tunnel_deregister +EXPORT_SYMBOL net/ipv6/tunnel6 0x5cfc6b15 xfrm6_tunnel_register +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0x9cd013f2 xfrm6_tunnel_alloc_spi +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0xab14e193 xfrm6_tunnel_free_spi +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0xdb1b42d1 xfrm6_tunnel_spi_lookup +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x024edb4b ircomm_control_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x248b47a4 ircomm_data_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x4badc273 ircomm_close +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x579321ca ircomm_open +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x58838bb3 ircomm_connect_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x6a4a04c8 ircomm_flow_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0xc7219ecb ircomm_disconnect_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0xece96f25 ircomm_connect_response +EXPORT_SYMBOL net/irda/irda 0x01d1fcdb hashbin_delete +EXPORT_SYMBOL net/irda/irda 0x03131a34 irttp_close_tsap +EXPORT_SYMBOL net/irda/irda 0x06a3ee58 irias_new_integer_value +EXPORT_SYMBOL net/irda/irda 0x072e026f irias_add_octseq_attrib +EXPORT_SYMBOL net/irda/irda 0x07d3647c irlmp_register_service +EXPORT_SYMBOL net/irda/irda 0x07eb957a irttp_connect_response +EXPORT_SYMBOL net/irda/irda 0x1a9f88d0 irttp_connect_request +EXPORT_SYMBOL net/irda/irda 0x2036ad06 irda_param_insert +EXPORT_SYMBOL net/irda/irda 0x2fda4d35 irlmp_connect_response +EXPORT_SYMBOL net/irda/irda 0x30792023 irlmp_connect_request +EXPORT_SYMBOL net/irda/irda 0x3462950f hashbin_remove +EXPORT_SYMBOL net/irda/irda 0x34df4a6c irttp_flow_request +EXPORT_SYMBOL net/irda/irda 0x38a20e5b irda_debug +EXPORT_SYMBOL net/irda/irda 0x448b8aaa irda_qos_bits_to_value +EXPORT_SYMBOL net/irda/irda 0x46c1c4a2 irlmp_unregister_service +EXPORT_SYMBOL net/irda/irda 0x53a8b270 async_wrap_skb +EXPORT_SYMBOL net/irda/irda 0x56447fe0 iriap_close +EXPORT_SYMBOL net/irda/irda 0x5aef62f0 irttp_disconnect_request +EXPORT_SYMBOL net/irda/irda 0x6339d96d iriap_getvaluebyclass_request +EXPORT_SYMBOL net/irda/irda 0x65b89880 irttp_open_tsap +EXPORT_SYMBOL net/irda/irda 0x6758f8ac irias_new_object +EXPORT_SYMBOL net/irda/irda 0x68b7447c hashbin_find +EXPORT_SYMBOL net/irda/irda 0x6b043eba irda_init_max_qos_capabilies +EXPORT_SYMBOL net/irda/irda 0x6d876be1 irlmp_open_lsap +EXPORT_SYMBOL net/irda/irda 0x6e369342 irlmp_data_request +EXPORT_SYMBOL net/irda/irda 0x70020f02 irlap_open +EXPORT_SYMBOL net/irda/irda 0x7042bc54 irlmp_register_client +EXPORT_SYMBOL net/irda/irda 0x747d6779 irias_delete_object +EXPORT_SYMBOL net/irda/irda 0x7621e908 hashbin_insert +EXPORT_SYMBOL net/irda/irda 0x76243bc9 irias_insert_object +EXPORT_SYMBOL net/irda/irda 0x763e54a4 irlmp_unregister_client +EXPORT_SYMBOL net/irda/irda 0x781e2db5 irias_find_object +EXPORT_SYMBOL net/irda/irda 0x7957f728 irlmp_update_client +EXPORT_SYMBOL net/irda/irda 0x7a57b6f3 hashbin_remove_this +EXPORT_SYMBOL net/irda/irda 0x80fdc3e7 alloc_irdadev +EXPORT_SYMBOL net/irda/irda 0x84556e74 irlmp_close_lsap +EXPORT_SYMBOL net/irda/irda 0x859a237c irlap_close +EXPORT_SYMBOL net/irda/irda 0x873edffd proc_irda +EXPORT_SYMBOL net/irda/irda 0x8f872718 irda_notify_init +EXPORT_SYMBOL net/irda/irda 0x91815586 irda_param_pack +EXPORT_SYMBOL net/irda/irda 0x993ad14b irda_param_extract_all +EXPORT_SYMBOL net/irda/irda 0x9c16f9c9 irttp_udata_request +EXPORT_SYMBOL net/irda/irda 0xa6c2c480 async_unwrap_char +EXPORT_SYMBOL net/irda/irda 0xac05657c iriap_open +EXPORT_SYMBOL net/irda/irda 0xb9394173 irias_delete_value +EXPORT_SYMBOL net/irda/irda 0xb9e3cd22 irda_device_set_media_busy +EXPORT_SYMBOL net/irda/irda 0xbcd3ef13 irias_object_change_attribute +EXPORT_SYMBOL net/irda/irda 0xbd7208e2 irttp_dup +EXPORT_SYMBOL net/irda/irda 0xbe40ace9 irlmp_discovery_request +EXPORT_SYMBOL net/irda/irda 0xc14e9b6a hashbin_get_next +EXPORT_SYMBOL net/irda/irda 0xc8611f13 irlmp_disconnect_request +EXPORT_SYMBOL net/irda/irda 0xcd41236c hashbin_new +EXPORT_SYMBOL net/irda/irda 0xd7172ff4 hashbin_get_first +EXPORT_SYMBOL net/irda/irda 0xd8bfb6d4 hashbin_lock_find +EXPORT_SYMBOL net/irda/irda 0xde4c6b3c irlmp_service_to_hint +EXPORT_SYMBOL net/irda/irda 0xe5260e0e irias_add_integer_attrib +EXPORT_SYMBOL net/irda/irda 0xec41fe7f irias_add_string_attrib +EXPORT_SYMBOL net/irda/irda 0xedd521c2 irlmp_get_discoveries +EXPORT_SYMBOL net/irda/irda 0xf39b7fe0 irda_setup_dma +EXPORT_SYMBOL net/irda/irda 0xfc90e743 irttp_data_request +EXPORT_SYMBOL net/lapb/lapb 0x0cad353a lapb_connect_request +EXPORT_SYMBOL net/lapb/lapb 0x286b46e7 lapb_unregister +EXPORT_SYMBOL net/lapb/lapb 0x37a30116 lapb_disconnect_request +EXPORT_SYMBOL net/lapb/lapb 0x3bfc4101 lapb_setparms +EXPORT_SYMBOL net/lapb/lapb 0x4c30c7a4 lapb_getparms +EXPORT_SYMBOL net/lapb/lapb 0xe48c1e8a lapb_data_request +EXPORT_SYMBOL net/lapb/lapb 0xea294ec8 lapb_register +EXPORT_SYMBOL net/lapb/lapb 0xf9359348 lapb_data_received +EXPORT_SYMBOL net/mac80211/mac80211 0x03609447 ieee80211_beacon_get +EXPORT_SYMBOL net/mac80211/mac80211 0x09395ded ieee80211_rts_duration +EXPORT_SYMBOL net/mac80211/mac80211 0x0e6dc734 ieee80211_register_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x2232a1b6 ieee80211_stop_queue +EXPORT_SYMBOL net/mac80211/mac80211 0x2629b347 ieee80211_rts_get +EXPORT_SYMBOL net/mac80211/mac80211 0x2d9eb749 ieee80211_wake_queues +EXPORT_SYMBOL net/mac80211/mac80211 0x2f1847a1 ieee80211_find_sta +EXPORT_SYMBOL net/mac80211/mac80211 0x30b76bd6 __ieee80211_get_radio_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x3677d511 ieee80211_wake_queue +EXPORT_SYMBOL net/mac80211/mac80211 0x46104482 ieee80211_start_tx_ba_session +EXPORT_SYMBOL net/mac80211/mac80211 0x46c4709d ieee80211_rate_control_unregister +EXPORT_SYMBOL net/mac80211/mac80211 0x5154532e ieee80211_scan_completed +EXPORT_SYMBOL net/mac80211/mac80211 0x55e2eef5 ieee80211_unregister_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x5d418cd3 ieee80211_free_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x6f1229c5 ieee80211_get_tkip_key +EXPORT_SYMBOL net/mac80211/mac80211 0x71f1d8cf ieee80211_get_hdrlen_from_skb +EXPORT_SYMBOL net/mac80211/mac80211 0x78742dce ieee80211_ctstoself_duration +EXPORT_SYMBOL net/mac80211/mac80211 0x793549cc ieee80211_stop_queues +EXPORT_SYMBOL net/mac80211/mac80211 0x79c40436 __ieee80211_get_rx_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x79f37080 ieee80211_rate_control_register +EXPORT_SYMBOL net/mac80211/mac80211 0x8141afdf __ieee80211_get_tx_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x8c35d732 ieee80211_hdrlen +EXPORT_SYMBOL net/mac80211/mac80211 0x91933794 ieee80211_ctstoself_get +EXPORT_SYMBOL net/mac80211/mac80211 0x9ae17384 ieee80211_rx_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x9b64ca1c ieee80211_get_buffered_bc +EXPORT_SYMBOL net/mac80211/mac80211 0xaa61b458 ieee80211_stop_tx_ba_cb_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0xacf5fc63 ieee80211_start_tx_ba_cb_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0xb4b9cae2 ieee80211_queue_stopped +EXPORT_SYMBOL net/mac80211/mac80211 0xb971a479 ieee80211_generic_frame_duration +EXPORT_SYMBOL net/mac80211/mac80211 0xbd0ea60d ieee80211_stop_tx_ba_session +EXPORT_SYMBOL net/mac80211/mac80211 0xbf4318cb wiphy_to_hw +EXPORT_SYMBOL net/mac80211/mac80211 0xcae405b4 ieee80211_tx_status +EXPORT_SYMBOL net/mac80211/mac80211 0xcd8d313e ieee80211_tx_status_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0xda8e5ece __ieee80211_get_assoc_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0xdb75cd06 ieee80211_start_tx_ba_cb +EXPORT_SYMBOL net/mac80211/mac80211 0xe4d9bebd ieee80211_stop_tx_ba_cb +EXPORT_SYMBOL net/mac80211/mac80211 0xebaa368b __ieee80211_rx +EXPORT_SYMBOL net/mac80211/mac80211 0xfe7205eb ieee80211_alloc_hw +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x0a05f64b ip_vs_conn_new +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x0f3e2d7b ip_vs_tcp_conn_listen +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x198756bf ip_vs_conn_out_get +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x3a9bdc0b register_ip_vs_scheduler +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x4cf7c4d4 ip_vs_conn_put +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x555005df register_ip_vs_app +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x5b2059df unregister_ip_vs_scheduler +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x7d4ddc1e unregister_ip_vs_app +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xa1dbc2d8 ip_vs_proto_name +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xe9bb0924 ip_vs_skb_replace +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xec8a529a register_ip_vs_app_inc +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xf1710207 ip_vs_conn_in_get +EXPORT_SYMBOL net/netfilter/nf_conntrack 0x8fb4ee7a __nf_ct_ext_destroy +EXPORT_SYMBOL net/netfilter/nf_conntrack 0xe372c1b6 __nf_ct_ext_add +EXPORT_SYMBOL net/netfilter/nf_conntrack_proto_gre 0x687f1452 nf_ct_gre_keymap_flush +EXPORT_SYMBOL net/netfilter/x_tables 0x0d0fc4bb xt_register_target +EXPORT_SYMBOL net/netfilter/x_tables 0x16a2220e xt_register_matches +EXPORT_SYMBOL net/netfilter/x_tables 0x3dcd58c5 xt_alloc_table_info +EXPORT_SYMBOL net/netfilter/x_tables 0x4d88994a xt_unregister_matches +EXPORT_SYMBOL net/netfilter/x_tables 0x56faafbd xt_unregister_targets +EXPORT_SYMBOL net/netfilter/x_tables 0x60eebe3f xt_unregister_target +EXPORT_SYMBOL net/netfilter/x_tables 0x641b92e9 xt_register_targets +EXPORT_SYMBOL net/netfilter/x_tables 0x77536f27 xt_register_match +EXPORT_SYMBOL net/netfilter/x_tables 0xbf8e24b2 xt_find_match +EXPORT_SYMBOL net/netfilter/x_tables 0xe7b5ac62 xt_find_target +EXPORT_SYMBOL net/netfilter/x_tables 0xf7037dc6 xt_free_table_info +EXPORT_SYMBOL net/netfilter/x_tables 0xfd1f5407 xt_unregister_match +EXPORT_SYMBOL net/phonet/phonet 0x1b1fb676 pn_sock_unhash +EXPORT_SYMBOL net/phonet/phonet 0x45bec524 phonet_header_ops +EXPORT_SYMBOL net/phonet/phonet 0x9fc31628 pn_skb_send +EXPORT_SYMBOL net/phonet/phonet 0xe4ca36f7 pn_sock_hash +EXPORT_SYMBOL net/phonet/phonet 0xf3532899 phonet_stream_ops +EXPORT_SYMBOL net/phonet/phonet 0xf49b3a77 pn_sock_get_port +EXPORT_SYMBOL net/phonet/phonet 0xf5ccd9b2 phonet_proto_unregister +EXPORT_SYMBOL net/phonet/phonet 0xfc7311fb phonet_proto_register +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x0bb32b61 rxrpc_kernel_get_abort_code +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x1021f0ae key_type_rxrpc +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x109e027c rxrpc_kernel_data_delivered +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x170d9a40 rxrpc_kernel_reject_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x5e971cd2 rxrpc_kernel_is_data_last +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x67a30039 rxrpc_kernel_intercept_rx_messages +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x7e62aa9a rxrpc_kernel_accept_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x7f152a23 rxrpc_kernel_free_skb +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xbdc3fbd9 rxrpc_kernel_end_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xbe15b063 rxrpc_kernel_send_data +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xc2490406 rxrpc_get_server_data_key +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xdafc761e rxrpc_kernel_get_error_number +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xec046e01 rxrpc_kernel_abort_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xf38d8b79 rxrpc_get_null_key +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xff7f48ec rxrpc_kernel_begin_call +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x00c52ef5 g_make_token_header +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x152f64e8 gss_mech_unregister +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x23ad7866 gss_mech_put +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x33aaac43 gss_mech_get +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x365e29d2 gss_svc_to_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x3e3a04e8 gss_mech_get_by_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x43f0c3e5 svcauth_gss_flavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x6a2eac00 gss_mech_register +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x6c291d66 gss_service_to_auth_domain_name +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x7f757e66 gss_mech_get_by_name +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x8c8e1a1b gss_pseudoflavor_to_service +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x8d1a827e svcauth_gss_register_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xb5dea7ef g_token_size +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xf8b2ff6e g_verify_token_header +EXPORT_SYMBOL net/sunrpc/sunrpc 0x029ef4d9 xdr_process_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0x05c74065 svc_exit_thread +EXPORT_SYMBOL net/sunrpc/sunrpc 0x05e807a9 xdr_encode_string +EXPORT_SYMBOL net/sunrpc/sunrpc 0x065994f1 xdr_encode_opaque_fixed +EXPORT_SYMBOL net/sunrpc/sunrpc 0x08c2d946 svc_process +EXPORT_SYMBOL net/sunrpc/sunrpc 0x098d12ab auth_domain_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0a43e471 cache_check +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0a58ebea svc_sock_names +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0d55e66f xdr_write_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0f668ba9 svc_auth_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x11fbad19 xdr_encode_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0x122dde40 svc_seq_show +EXPORT_SYMBOL net/sunrpc/sunrpc 0x12e280e3 svc_proc_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x161f92e1 svc_drop +EXPORT_SYMBOL net/sunrpc/sunrpc 0x1678f031 unix_domain_find +EXPORT_SYMBOL net/sunrpc/sunrpc 0x1914c7a3 svc_reserve +EXPORT_SYMBOL net/sunrpc/sunrpc 0x1a5924f6 xdr_buf_subsegment +EXPORT_SYMBOL net/sunrpc/sunrpc 0x1aedbcb4 sunrpc_cache_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0x256dc39c xdr_inline_decode +EXPORT_SYMBOL net/sunrpc/sunrpc 0x27ddbb9f svc_proc_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0x28aedd71 svc_authenticate +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2919b156 xdr_decode_string_inplace +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2a0e78d8 xdr_read_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2eec63c9 xdr_encode_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0x30e003db xdr_buf_read_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0x37ed71a4 rpc_unlink +EXPORT_SYMBOL net/sunrpc/sunrpc 0x3f9b22e5 xdr_encode_array2 +EXPORT_SYMBOL net/sunrpc/sunrpc 0x42c0e0c6 svc_recv +EXPORT_SYMBOL net/sunrpc/sunrpc 0x44d4bf16 auth_unix_forget_old +EXPORT_SYMBOL net/sunrpc/sunrpc 0x48be0400 svc_create +EXPORT_SYMBOL net/sunrpc/sunrpc 0x648cdeb8 xdr_decode_array2 +EXPORT_SYMBOL net/sunrpc/sunrpc 0x6edfa30a svcauth_unix_set_client +EXPORT_SYMBOL net/sunrpc/sunrpc 0x6eea229d svcauth_unix_purge +EXPORT_SYMBOL net/sunrpc/sunrpc 0x71fa908a cache_flush +EXPORT_SYMBOL net/sunrpc/sunrpc 0x7693da02 svc_sock_update_bufs +EXPORT_SYMBOL net/sunrpc/sunrpc 0x7a1b7636 cache_purge +EXPORT_SYMBOL net/sunrpc/sunrpc 0x7d830ea9 xdr_reserve_space +EXPORT_SYMBOL net/sunrpc/sunrpc 0x8bec1e50 svc_set_client +EXPORT_SYMBOL net/sunrpc/sunrpc 0x8ca854b4 rpc_queue_upcall +EXPORT_SYMBOL net/sunrpc/sunrpc 0x8ddbcd2c xdr_encode_word +EXPORT_SYMBOL net/sunrpc/sunrpc 0x8ed00eb2 cache_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x93b3ea31 auth_unix_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0x969b432b xdr_inline_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0x98dd99c7 svc_prepare_thread +EXPORT_SYMBOL net/sunrpc/sunrpc 0x997090e6 xdr_shift_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0x9c8eee0a svc_wake_up +EXPORT_SYMBOL net/sunrpc/sunrpc 0x9fc58b58 svc_create_pooled +EXPORT_SYMBOL net/sunrpc/sunrpc 0x9fd3d013 read_bytes_from_xdr_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0xafa88bb6 svc_set_num_threads +EXPORT_SYMBOL net/sunrpc/sunrpc 0xbfac9efc cache_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc1c697e4 sunrpc_cache_update +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc3880471 xdr_decode_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc393591e xdr_enter_page +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc8e96dea qword_addhex +EXPORT_SYMBOL net/sunrpc/sunrpc 0xce71f953 xdr_decode_word +EXPORT_SYMBOL net/sunrpc/sunrpc 0xd355d908 xdr_init_encode +EXPORT_SYMBOL net/sunrpc/sunrpc 0xd83a31c5 auth_domain_put +EXPORT_SYMBOL net/sunrpc/sunrpc 0xdb51e0c5 xdr_init_decode +EXPORT_SYMBOL net/sunrpc/sunrpc 0xdd7ab7bf auth_unix_add_addr +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe07b804b rpc_mkpipe +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe547e1ee auth_domain_find +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe5919cb1 xdr_encode_opaque +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe97f4ce5 qword_get +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe9a968f0 svc_destroy +EXPORT_SYMBOL net/sunrpc/sunrpc 0xedcf6be4 qword_add +EXPORT_SYMBOL net/sunrpc/sunrpc 0xeedeed56 svc_auth_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0xf7ee13be xdr_buf_from_iov +EXPORT_SYMBOL net/tipc/tipc 0x08acf310 tipc_available_nodes +EXPORT_SYMBOL net/tipc/tipc 0x10d40fcd tipc_isconnected +EXPORT_SYMBOL net/tipc/tipc 0x1472b270 tipc_disconnect +EXPORT_SYMBOL net/tipc/tipc 0x1479cb03 tipc_deleteport +EXPORT_SYMBOL net/tipc/tipc 0x15b5ecde tipc_set_portunreliable +EXPORT_SYMBOL net/tipc/tipc 0x16f27683 tipc_block_bearer +EXPORT_SYMBOL net/tipc/tipc 0x259b74f9 tipc_acknowledge +EXPORT_SYMBOL net/tipc/tipc 0x27d8bb58 tipc_send2port +EXPORT_SYMBOL net/tipc/tipc 0x310d1bc9 tipc_detach +EXPORT_SYMBOL net/tipc/tipc 0x36d72030 tipc_forward_buf2port +EXPORT_SYMBOL net/tipc/tipc 0x3712e340 tipc_portunreliable +EXPORT_SYMBOL net/tipc/tipc 0x3976041f tipc_set_portimportance +EXPORT_SYMBOL net/tipc/tipc 0x3d993d58 tipc_recv_msg +EXPORT_SYMBOL net/tipc/tipc 0x4b2243c6 tipc_portimportance +EXPORT_SYMBOL net/tipc/tipc 0x4ba3cfc8 tipc_send2name +EXPORT_SYMBOL net/tipc/tipc 0x538b228a tipc_withdraw +EXPORT_SYMBOL net/tipc/tipc 0x5637ed44 tipc_get_mode +EXPORT_SYMBOL net/tipc/tipc 0x56e52bc1 tipc_continue +EXPORT_SYMBOL net/tipc/tipc 0x5be86b08 tipc_reject_msg +EXPORT_SYMBOL net/tipc/tipc 0x5c0d4b5c tipc_ref_valid +EXPORT_SYMBOL net/tipc/tipc 0x62a681a3 tipc_portunreturnable +EXPORT_SYMBOL net/tipc/tipc 0x64357d3c tipc_multicast +EXPORT_SYMBOL net/tipc/tipc 0x6a618b83 tipc_send_buf2name +EXPORT_SYMBOL net/tipc/tipc 0x774f0ce5 tipc_createport +EXPORT_SYMBOL net/tipc/tipc 0x8001e3d7 tipc_forward2port +EXPORT_SYMBOL net/tipc/tipc 0x88b73627 tipc_get_addr +EXPORT_SYMBOL net/tipc/tipc 0x9c45558e tipc_enable_bearer +EXPORT_SYMBOL net/tipc/tipc 0xa936a24b tipc_get_port +EXPORT_SYMBOL net/tipc/tipc 0xa9f3bfee tipc_send_buf2port +EXPORT_SYMBOL net/tipc/tipc 0xadd203d0 tipc_connect2port +EXPORT_SYMBOL net/tipc/tipc 0xae0103c3 tipc_shutdown +EXPORT_SYMBOL net/tipc/tipc 0xb01ffc2c tipc_forward2name +EXPORT_SYMBOL net/tipc/tipc 0xb184b3f1 tipc_forward_buf2name +EXPORT_SYMBOL net/tipc/tipc 0xb35b672c tipc_publish +EXPORT_SYMBOL net/tipc/tipc 0xbb2b2504 tipc_send +EXPORT_SYMBOL net/tipc/tipc 0xcb2d56ca tipc_send_buf +EXPORT_SYMBOL net/tipc/tipc 0xcec8514a tipc_set_portunreturnable +EXPORT_SYMBOL net/tipc/tipc 0xd44731e5 tipc_ownidentity +EXPORT_SYMBOL net/tipc/tipc 0xda7f9d3f tipc_attach +EXPORT_SYMBOL net/tipc/tipc 0xdf5008fc tipc_peer +EXPORT_SYMBOL net/tipc/tipc 0xe125f75f tipc_send_buf_fast +EXPORT_SYMBOL net/tipc/tipc 0xe7aece47 tipc_ispublished +EXPORT_SYMBOL net/tipc/tipc 0xeefd49b3 tipc_get_handle +EXPORT_SYMBOL net/tipc/tipc 0xef50a1ef tipc_disable_bearer +EXPORT_SYMBOL net/tipc/tipc 0xf6c9c2f0 tipc_createport_raw +EXPORT_SYMBOL net/tipc/tipc 0xf9e3dfed tipc_register_media +EXPORT_SYMBOL net/wanrouter/wanrouter 0x0ebe03d1 unregister_wan_device +EXPORT_SYMBOL net/wanrouter/wanrouter 0xe4138e00 register_wan_device +EXPORT_SYMBOL net/wireless/cfg80211 0x03ffd882 wiphy_new +EXPORT_SYMBOL net/wireless/cfg80211 0x07e7ac5a ieee80211_radiotap_iterator_init +EXPORT_SYMBOL net/wireless/cfg80211 0x09c64fbd ieee80211_frequency_to_channel +EXPORT_SYMBOL net/wireless/cfg80211 0x9517b01e wiphy_register +EXPORT_SYMBOL net/wireless/cfg80211 0xb6d4aa74 regulatory_hint +EXPORT_SYMBOL net/wireless/cfg80211 0xbf130847 __ieee80211_get_channel +EXPORT_SYMBOL net/wireless/cfg80211 0xc4e85ec5 ieee80211_radiotap_iterator_next +EXPORT_SYMBOL net/wireless/cfg80211 0xccc291b3 ieee80211_channel_to_frequency +EXPORT_SYMBOL net/wireless/cfg80211 0xd7fe2a80 wiphy_free +EXPORT_SYMBOL net/wireless/cfg80211 0xd953a766 wiphy_unregister +EXPORT_SYMBOL sound/ac97_bus 0xfb83558c ac97_bus_type +EXPORT_SYMBOL sound/core/oss/snd-mixer-oss 0x251bc630 snd_mixer_oss_ioctl_card +EXPORT_SYMBOL sound/core/seq/snd-seq 0x1a724fcc snd_seq_kernel_client_ctl +EXPORT_SYMBOL sound/core/seq/snd-seq 0x206be216 snd_seq_kernel_client_enqueue_blocking +EXPORT_SYMBOL sound/core/seq/snd-seq 0x3061c52d snd_use_lock_sync_helper +EXPORT_SYMBOL sound/core/seq/snd-seq 0x3fb4d161 snd_seq_kernel_client_dispatch +EXPORT_SYMBOL sound/core/seq/snd-seq 0x4d87c101 snd_seq_kernel_client_write_poll +EXPORT_SYMBOL sound/core/seq/snd-seq 0x6bb71038 snd_seq_delete_kernel_client +EXPORT_SYMBOL sound/core/seq/snd-seq 0x7ac2f329 snd_seq_expand_var_event +EXPORT_SYMBOL sound/core/seq/snd-seq 0x7b8699eb snd_seq_event_port_detach +EXPORT_SYMBOL sound/core/seq/snd-seq 0xb8e448a0 snd_seq_set_queue_tempo +EXPORT_SYMBOL sound/core/seq/snd-seq 0xc001cdff snd_seq_event_port_attach +EXPORT_SYMBOL sound/core/seq/snd-seq 0xcac0a3be snd_seq_kernel_client_enqueue +EXPORT_SYMBOL sound/core/seq/snd-seq 0xe934da1d snd_seq_dump_var_event +EXPORT_SYMBOL sound/core/seq/snd-seq 0xf322151c snd_seq_create_kernel_client +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x0f4fa7d1 snd_seq_device_register_driver +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x15bcf88f snd_seq_device_new +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x3a57f235 snd_seq_autoload_unlock +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x6339b6d0 snd_seq_device_load_drivers +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xb90668b2 snd_seq_autoload_lock +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xc622fb29 snd_seq_device_unregister_driver +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0x6ea09972 snd_midi_channel_alloc_set +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0x833a3e07 snd_midi_channel_set_clear +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0xb9948d2c snd_midi_channel_free_set +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0xf0a1fdb3 snd_midi_process_event +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x17c15809 snd_midi_event_decode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x4ad3f518 snd_midi_event_reset_decode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x62384d3a snd_midi_event_encode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x8a348811 snd_midi_event_reset_encode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x9df7af8b snd_midi_event_free +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xc482499d snd_midi_event_new +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xd9072e1a snd_midi_event_no_status +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xe6df29c7 snd_midi_event_encode_byte +EXPORT_SYMBOL sound/core/seq/snd-seq-virmidi 0xab0061ec snd_virmidi_new +EXPORT_SYMBOL sound/core/snd 0x0102742f snd_ctl_remove +EXPORT_SYMBOL sound/core/snd 0x07557000 snd_mixer_oss_notify_callback +EXPORT_SYMBOL sound/core/snd 0x0bc338cb snd_component_add +EXPORT_SYMBOL sound/core/snd 0x0d74729f snd_device_register +EXPORT_SYMBOL sound/core/snd 0x15ab7b51 snd_ctl_add_slave +EXPORT_SYMBOL sound/core/snd 0x18e1683f snd_dma_program +EXPORT_SYMBOL sound/core/snd 0x191e88cf snd_dma_pointer +EXPORT_SYMBOL sound/core/snd 0x198788b4 snd_lookup_oss_minor_data +EXPORT_SYMBOL sound/core/snd 0x1adfdd29 snd_ctl_free_one +EXPORT_SYMBOL sound/core/snd 0x1d422a9b snd_ctl_remove_id +EXPORT_SYMBOL sound/core/snd 0x21ba4c4b snd_card_file_add +EXPORT_SYMBOL sound/core/snd 0x24a94b26 snd_info_get_line +EXPORT_SYMBOL sound/core/snd 0x2724b931 snd_device_new +EXPORT_SYMBOL sound/core/snd 0x3971b4df snd_ecards_limit +EXPORT_SYMBOL sound/core/snd 0x48ad8cc8 snd_ctl_notify +EXPORT_SYMBOL sound/core/snd 0x4a3ea5c0 snd_request_card +EXPORT_SYMBOL sound/core/snd 0x4e2852df snd_card_file_remove +EXPORT_SYMBOL sound/core/snd 0x4e3d3868 snd_ctl_new1 +EXPORT_SYMBOL sound/core/snd 0x5b673398 snd_ctl_make_virtual_master +EXPORT_SYMBOL sound/core/snd 0x5e6833cf snd_card_new +EXPORT_SYMBOL sound/core/snd 0x602c96f0 copy_to_user_fromio +EXPORT_SYMBOL sound/core/snd 0x6601b617 snd_card_free +EXPORT_SYMBOL sound/core/snd 0x6b41fb98 snd_ctl_rename_id +EXPORT_SYMBOL sound/core/snd 0x70c15ac1 snd_dma_disable +EXPORT_SYMBOL sound/core/snd 0x70c48cf5 snd_register_device_for_dev +EXPORT_SYMBOL sound/core/snd 0x71db85a7 snd_card_proc_new +EXPORT_SYMBOL sound/core/snd 0x762516b1 snd_ctl_add +EXPORT_SYMBOL sound/core/snd 0x8df3789f snd_oss_info_register +EXPORT_SYMBOL sound/core/snd 0x8ee3859a snd_card_free_when_closed +EXPORT_SYMBOL sound/core/snd 0x8f595b11 snd_major +EXPORT_SYMBOL sound/core/snd 0x91a42741 snd_unregister_device +EXPORT_SYMBOL sound/core/snd 0x9c92d5cd snd_register_oss_device +EXPORT_SYMBOL sound/core/snd 0xab2bee81 snd_info_free_entry +EXPORT_SYMBOL sound/core/snd 0xb213fe8b snd_info_get_str +EXPORT_SYMBOL sound/core/snd 0xb2cc2e0c snd_card_disconnect +EXPORT_SYMBOL sound/core/snd 0xb2e5ae4a snd_lookup_minor_data +EXPORT_SYMBOL sound/core/snd 0xbb52a2ae snd_ctl_boolean_mono_info +EXPORT_SYMBOL sound/core/snd 0xbeda9092 snd_ctl_boolean_stereo_info +EXPORT_SYMBOL sound/core/snd 0xc0d0822e snd_info_create_card_entry +EXPORT_SYMBOL sound/core/snd 0xc5528a69 snd_add_device_sysfs_file +EXPORT_SYMBOL sound/core/snd 0xc87349c8 snd_ctl_find_numid +EXPORT_SYMBOL sound/core/snd 0xce3ca308 copy_from_user_toio +EXPORT_SYMBOL sound/core/snd 0xd1157735 release_and_free_resource +EXPORT_SYMBOL sound/core/snd 0xd6f0808f snd_pci_quirk_lookup +EXPORT_SYMBOL sound/core/snd 0xdc6df095 snd_seq_root +EXPORT_SYMBOL sound/core/snd 0xdd462e02 snd_ctl_find_id +EXPORT_SYMBOL sound/core/snd 0xddeda150 snd_unregister_oss_device +EXPORT_SYMBOL sound/core/snd 0xe4108802 snd_card_register +EXPORT_SYMBOL sound/core/snd 0xe4854cea snd_iprintf +EXPORT_SYMBOL sound/core/snd 0xe98b5628 snd_info_create_module_entry +EXPORT_SYMBOL sound/core/snd 0xeb486ed0 snd_device_free +EXPORT_SYMBOL sound/core/snd 0xf09aa8f9 snd_cards +EXPORT_SYMBOL sound/core/snd 0xf3d4b323 snd_ctl_register_ioctl +EXPORT_SYMBOL sound/core/snd 0xf824c989 snd_power_wait +EXPORT_SYMBOL sound/core/snd 0xf9de88ff snd_ctl_unregister_ioctl +EXPORT_SYMBOL sound/core/snd 0xfca83d4f snd_info_register +EXPORT_SYMBOL sound/core/snd-hwdep 0x2d4706a2 snd_hwdep_new +EXPORT_SYMBOL sound/core/snd-page-alloc 0x06cdd4ab snd_dma_free_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0x0c879491 snd_dma_alloc_pages_fallback +EXPORT_SYMBOL sound/core/snd-page-alloc 0x3b91f3af snd_free_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0xade88e76 snd_malloc_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0xcc22de2d snd_dma_alloc_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0xcd128d00 snd_dma_get_reserved_buf +EXPORT_SYMBOL sound/core/snd-page-alloc 0xdd8d5cf1 snd_dma_reserve_buf +EXPORT_SYMBOL sound/core/snd-pcm 0x0294ac65 snd_pcm_lib_preallocate_free_for_all +EXPORT_SYMBOL sound/core/snd-pcm 0x04cda566 snd_interval_refine +EXPORT_SYMBOL sound/core/snd-pcm 0x1d027e4b snd_pcm_format_signed +EXPORT_SYMBOL sound/core/snd-pcm 0x1eb56bdb snd_pcm_limit_hw_rates +EXPORT_SYMBOL sound/core/snd-pcm 0x20978ddd snd_pcm_suspend +EXPORT_SYMBOL sound/core/snd-pcm 0x226aae0b snd_pcm_lib_free_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x249952e9 snd_pcm_hw_constraint_ratnums +EXPORT_SYMBOL sound/core/snd-pcm 0x29e34c01 snd_pcm_lib_ioctl +EXPORT_SYMBOL sound/core/snd-pcm 0x30639e5f snd_pcm_hw_constraint_step +EXPORT_SYMBOL sound/core/snd-pcm 0x35827960 snd_pcm_hw_constraint_list +EXPORT_SYMBOL sound/core/snd-pcm 0x3689034e snd_pcm_new +EXPORT_SYMBOL sound/core/snd-pcm 0x3796bdcc snd_pcm_format_little_endian +EXPORT_SYMBOL sound/core/snd-pcm 0x3ddc6829 snd_pcm_hw_constraint_integer +EXPORT_SYMBOL sound/core/snd-pcm 0x47f2b565 snd_pcm_hw_param_first +EXPORT_SYMBOL sound/core/snd-pcm 0x4cde676d snd_pcm_sgbuf_ops_page +EXPORT_SYMBOL sound/core/snd-pcm 0x4d9b6d35 snd_pcm_format_size +EXPORT_SYMBOL sound/core/snd-pcm 0x4f816e9b snd_pcm_format_big_endian +EXPORT_SYMBOL sound/core/snd-pcm 0x5172e3e2 snd_pcm_lib_preallocate_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x54d0e6ec snd_pcm_hw_constraint_msbits +EXPORT_SYMBOL sound/core/snd-pcm 0x5e7f4920 snd_pcm_format_set_silence +EXPORT_SYMBOL sound/core/snd-pcm 0x63f51c49 snd_pcm_hw_param_value +EXPORT_SYMBOL sound/core/snd-pcm 0x64589fb9 snd_pcm_suspend_all +EXPORT_SYMBOL sound/core/snd-pcm 0x650f8603 snd_pcm_format_silence_64 +EXPORT_SYMBOL sound/core/snd-pcm 0x68a24153 snd_pcm_format_physical_width +EXPORT_SYMBOL sound/core/snd-pcm 0x6ef8fcd8 snd_pcm_format_linear +EXPORT_SYMBOL sound/core/snd-pcm 0x6f1e7158 snd_pcm_hw_param_last +EXPORT_SYMBOL sound/core/snd-pcm 0x77b9ccac _snd_pcm_hw_param_setempty +EXPORT_SYMBOL sound/core/snd-pcm 0x795d2e9c snd_pcm_mmap_data +EXPORT_SYMBOL sound/core/snd-pcm 0x7efd7b2e snd_pcm_lib_read +EXPORT_SYMBOL sound/core/snd-pcm 0x800a1a72 snd_pcm_hw_refine +EXPORT_SYMBOL sound/core/snd-pcm 0x8072f05f snd_pcm_lib_write +EXPORT_SYMBOL sound/core/snd-pcm 0x88cc66cc snd_pcm_link_rwlock +EXPORT_SYMBOL sound/core/snd-pcm 0x8e440f2e snd_pcm_lib_readv +EXPORT_SYMBOL sound/core/snd-pcm 0x9403e7f6 snd_pcm_release_substream +EXPORT_SYMBOL sound/core/snd-pcm 0x952d5f21 _snd_pcm_hw_params_any +EXPORT_SYMBOL sound/core/snd-pcm 0x9ec28981 snd_pcm_stop +EXPORT_SYMBOL sound/core/snd-pcm 0x9f62db25 snd_pcm_set_sync +EXPORT_SYMBOL sound/core/snd-pcm 0xa61aa028 snd_pcm_format_unsigned +EXPORT_SYMBOL sound/core/snd-pcm 0xa8301b7a snd_pcm_hw_constraint_pow2 +EXPORT_SYMBOL sound/core/snd-pcm 0xafac2389 snd_pcm_lib_malloc_pages +EXPORT_SYMBOL sound/core/snd-pcm 0xb031a17a snd_pcm_hw_rule_add +EXPORT_SYMBOL sound/core/snd-pcm 0xb156643d snd_pcm_lib_writev +EXPORT_SYMBOL sound/core/snd-pcm 0xb58d5035 snd_pcm_set_ops +EXPORT_SYMBOL sound/core/snd-pcm 0xb72f1738 snd_pcm_new_stream +EXPORT_SYMBOL sound/core/snd-pcm 0xb9638db4 snd_pcm_rate_to_rate_bit +EXPORT_SYMBOL sound/core/snd-pcm 0xba7ba420 snd_pcm_kernel_ioctl +EXPORT_SYMBOL sound/core/snd-pcm 0xc610a641 snd_pcm_lib_mmap_iomem +EXPORT_SYMBOL sound/core/snd-pcm 0xc9521719 snd_pcm_notify +EXPORT_SYMBOL sound/core/snd-pcm 0xd0b9b8b8 snd_interval_list +EXPORT_SYMBOL sound/core/snd-pcm 0xd34d3fcd snd_pcm_sgbuf_get_chunk_size +EXPORT_SYMBOL sound/core/snd-pcm 0xd5191cf7 snd_pcm_lib_preallocate_pages_for_all +EXPORT_SYMBOL sound/core/snd-pcm 0xd7dc0dbe snd_pcm_hw_constraint_minmax +EXPORT_SYMBOL sound/core/snd-pcm 0xe4cb73a7 snd_pcm_hw_constraint_ratdens +EXPORT_SYMBOL sound/core/snd-pcm 0xe56a9336 snd_pcm_format_width +EXPORT_SYMBOL sound/core/snd-pcm 0xf3797152 snd_interval_ratnum +EXPORT_SYMBOL sound/core/snd-pcm 0xfbbdf0b8 snd_pcm_period_elapsed +EXPORT_SYMBOL sound/core/snd-pcm 0xffd039ba snd_pcm_open_substream +EXPORT_SYMBOL sound/core/snd-rawmidi 0x07c14df5 snd_rawmidi_transmit_peek +EXPORT_SYMBOL sound/core/snd-rawmidi 0x11d6ad07 snd_rawmidi_drop_output +EXPORT_SYMBOL sound/core/snd-rawmidi 0x239d58ce snd_rawmidi_transmit_ack +EXPORT_SYMBOL sound/core/snd-rawmidi 0x24ae8ee6 snd_rawmidi_transmit +EXPORT_SYMBOL sound/core/snd-rawmidi 0x28f686d2 snd_rawmidi_set_ops +EXPORT_SYMBOL sound/core/snd-rawmidi 0x299949d5 snd_rawmidi_new +EXPORT_SYMBOL sound/core/snd-rawmidi 0x561f3127 snd_rawmidi_kernel_release +EXPORT_SYMBOL sound/core/snd-rawmidi 0x63348f43 snd_rawmidi_kernel_open +EXPORT_SYMBOL sound/core/snd-rawmidi 0x643f1372 snd_rawmidi_drain_input +EXPORT_SYMBOL sound/core/snd-rawmidi 0x6cdfa5c1 snd_rawmidi_kernel_read +EXPORT_SYMBOL sound/core/snd-rawmidi 0xa85b1dd4 snd_rawmidi_transmit_empty +EXPORT_SYMBOL sound/core/snd-rawmidi 0xb3ab103d snd_rawmidi_input_params +EXPORT_SYMBOL sound/core/snd-rawmidi 0xbcceaa3b snd_rawmidi_kernel_write +EXPORT_SYMBOL sound/core/snd-rawmidi 0xd0eda9e8 snd_rawmidi_output_params +EXPORT_SYMBOL sound/core/snd-rawmidi 0xd3b7e0b6 snd_rawmidi_info_select +EXPORT_SYMBOL sound/core/snd-rawmidi 0xde4744b9 snd_rawmidi_receive +EXPORT_SYMBOL sound/core/snd-rawmidi 0xf9f33590 snd_rawmidi_drain_output +EXPORT_SYMBOL sound/core/snd-timer 0x0f8a6772 snd_timer_global_free +EXPORT_SYMBOL sound/core/snd-timer 0x12c766e5 snd_timer_new +EXPORT_SYMBOL sound/core/snd-timer 0x16566c21 snd_timer_resolution +EXPORT_SYMBOL sound/core/snd-timer 0x3f054073 snd_timer_continue +EXPORT_SYMBOL sound/core/snd-timer 0x635e254e snd_timer_open +EXPORT_SYMBOL sound/core/snd-timer 0x85ff5759 snd_timer_notify +EXPORT_SYMBOL sound/core/snd-timer 0x9c62227a snd_timer_interrupt +EXPORT_SYMBOL sound/core/snd-timer 0xaf0cb4be snd_timer_start +EXPORT_SYMBOL sound/core/snd-timer 0xb850e5c0 snd_timer_global_new +EXPORT_SYMBOL sound/core/snd-timer 0xcfabe9f3 snd_timer_global_register +EXPORT_SYMBOL sound/core/snd-timer 0xd2d447e9 snd_timer_stop +EXPORT_SYMBOL sound/core/snd-timer 0xda752c7c snd_timer_pause +EXPORT_SYMBOL sound/core/snd-timer 0xe7c03bfd snd_timer_close +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0x6ad7f000 snd_mpu401_uart_new +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0x73c4c993 snd_mpu401_uart_interrupt_tx +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0xfe618b58 snd_mpu401_uart_interrupt +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x05060a19 snd_opl3_regmap +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x308ec70b snd_opl3_load_patch +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x411e2b63 snd_opl3_interrupt +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x5b14d84e snd_opl3_reset +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x67562169 snd_opl3_create +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x6f4a1988 snd_opl3_find_patch +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x99cf7300 snd_opl3_new +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x9ed29020 snd_opl3_hwdep_new +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0xa053e0ff snd_opl3_timer_new +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0xe70ffd27 snd_opl3_init +EXPORT_SYMBOL sound/drivers/opl4/snd-opl4-lib 0x107ad359 snd_opl4_create +EXPORT_SYMBOL sound/drivers/opl4/snd-opl4-lib 0x1dc32ae4 snd_opl4_read +EXPORT_SYMBOL sound/drivers/opl4/snd-opl4-lib 0x26dd1a22 snd_opl4_read_memory +EXPORT_SYMBOL sound/drivers/opl4/snd-opl4-lib 0x71eae5c9 snd_opl4_write +EXPORT_SYMBOL sound/drivers/opl4/snd-opl4-lib 0xebcf5be3 snd_opl4_write_memory +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x1cadb14b snd_vx_irq_handler +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x3039ca11 snd_vx_resume +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x3245a62e snd_vx_free_firmware +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x3cf917d5 snd_vx_suspend +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x69526950 snd_vx_create +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x9784c862 snd_vx_dsp_boot +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xad66865b snd_vx_dsp_load +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xb94dc313 snd_vx_check_reg_bit +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xcdd6136f snd_vx_setup_firmware +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xe49e7c1b snd_vx_load_boot_image +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x47043852 snd_ak4114_reg_write +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x5fb78795 snd_ak4114_create +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x8d621ad2 snd_ak4114_reinit +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0xb18b7413 snd_ak4114_external_rate +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0xcdbed0cd snd_ak4114_check_rate_and_errors +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0xe6c2bcfa snd_ak4114_build +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0x231eab3a snd_ak4117_check_rate_and_errors +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0x85c7384b snd_ak4117_reinit +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0x9875c05c snd_ak4117_create +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xc17238ad snd_ak4117_external_rate +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xd1c5f100 snd_ak4117_reg_write +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xd5861cf2 snd_ak4117_build +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0x02ab25f6 snd_akm4xxx_reset +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0x339b74db snd_akm4xxx_build_controls +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0x66a541a6 snd_akm4xxx_init +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0x8051b362 snd_akm4xxx_write +EXPORT_SYMBOL sound/i2c/other/snd-pt2258 0x468ebb90 snd_pt2258_reset +EXPORT_SYMBOL sound/i2c/other/snd-pt2258 0xa11b5ca7 snd_pt2258_build_controls +EXPORT_SYMBOL sound/i2c/other/snd-tea575x-tuner 0x4f773b3a snd_tea575x_exit +EXPORT_SYMBOL sound/i2c/other/snd-tea575x-tuner 0x9cbc0be3 snd_tea575x_init +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x20a96610 snd_cs8427_reg_write +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x448113e5 snd_cs8427_iec958_pcm +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x4750388e snd_cs8427_create +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x6335cc42 snd_cs8427_iec958_active +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x96267b3a snd_cs8427_iec958_build +EXPORT_SYMBOL sound/i2c/snd-i2c 0x1fdd6c4e snd_i2c_sendbytes +EXPORT_SYMBOL sound/i2c/snd-i2c 0x2d7d3961 snd_i2c_device_free +EXPORT_SYMBOL sound/i2c/snd-i2c 0x30b26163 snd_i2c_probeaddr +EXPORT_SYMBOL sound/i2c/snd-i2c 0x38d757a5 snd_i2c_readbytes +EXPORT_SYMBOL sound/i2c/snd-i2c 0x45ea2cef snd_i2c_bus_create +EXPORT_SYMBOL sound/i2c/snd-i2c 0xf552ad14 snd_i2c_device_create +EXPORT_SYMBOL sound/i2c/snd-tea6330t 0x86a1983b snd_tea6330t_detect +EXPORT_SYMBOL sound/i2c/snd-tea6330t 0xaa4d1916 snd_tea6330t_update_mixer +EXPORT_SYMBOL sound/isa/cs423x/snd-cs4236-lib 0x1c61b35b snd_cs4236_mixer +EXPORT_SYMBOL sound/isa/cs423x/snd-cs4236-lib 0x3e22c571 snd_cs4236_create +EXPORT_SYMBOL sound/isa/cs423x/snd-cs4236-lib 0xa95da323 snd_cs4236_pcm +EXPORT_SYMBOL sound/isa/es1688/snd-es1688-lib 0x17aa8840 snd_es1688_pcm +EXPORT_SYMBOL sound/isa/es1688/snd-es1688-lib 0x865b3d3e snd_es1688_create +EXPORT_SYMBOL sound/isa/es1688/snd-es1688-lib 0x8fb396e0 snd_es1688_mixer_write +EXPORT_SYMBOL sound/isa/es1688/snd-es1688-lib 0xc020de11 snd_es1688_mixer +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x1e89b24f snd_gf1_translate_freq +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x20bf35b4 snd_gf1_rawmidi_new +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x246aab04 snd_gus_initialize +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x286557a2 snd_gf1_dram_addr +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x2e386f52 snd_gf1_ctrl_stop +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x2fa81343 snd_gf1_look8 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x313a5bde snd_gus_use_dec +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x34f593c1 snd_gf1_i_write8 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x351f0c8c snd_gf1_delay +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x353f65c8 snd_gf1_write8 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x39017267 snd_gus_create +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x3b67dff5 snd_gf1_alloc_voice +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x46db8d67 snd_gf1_lvol_to_gvol_raw +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x57ff2151 snd_gf1_pcm_new +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x6c11e18b snd_gf1_write_addr +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x7f71362d snd_gus_dram_read +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x806dca94 snd_gf1_i_look16 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x90cd0503 snd_gf1_i_look8 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x9d09b32d snd_gf1_poke +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x9e11611c snd_gf1_write16 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xbcf1aec9 snd_gus_dram_write +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xc31af61d snd_gf1_mem_alloc +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xc39588e0 snd_gf1_look16 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xc43a5527 snd_gf1_atten_table +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xc9419e19 snd_gf1_stop_voice +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xd85053ba snd_gf1_mem_free +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xdb252880 snd_gf1_mem_xfree +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xe46d1bd8 snd_gf1_peek +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xe55e53bf snd_gus_use_inc +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xeca2dd3e snd_gf1_mem_lock +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xf0ce311b snd_gf1_new_mixer +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xf963a997 snd_gus_interrupt +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xfdc69a09 snd_gf1_free_voice +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x15e6ab8f snd_sbmixer_write +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x1ff0682b snd_sbmixer_suspend +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x688fb1d5 snd_sbdsp_create +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x7b89ba4a snd_sbdsp_get_byte +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xa35b93eb snd_sbmixer_add_ctl +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xb163b8d6 snd_sbmixer_read +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xcea62470 snd_sbmixer_new +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xd11914d3 snd_sbdsp_reset +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xf237c9f8 snd_sbmixer_resume +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xf5d44447 snd_sbdsp_command +EXPORT_SYMBOL sound/isa/sb/snd-sb16-csp 0x788fb93d snd_sb_csp_new +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0x04bda3bc snd_sb16dsp_pcm +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0x0ba4ef1d snd_sb16dsp_interrupt +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0x2761340c snd_sb16dsp_configure +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0xc84a882a snd_sb16dsp_get_pcm_ops +EXPORT_SYMBOL sound/isa/sb/snd-sb8-dsp 0x4cd8722d snd_sb8dsp_pcm +EXPORT_SYMBOL sound/isa/sb/snd-sb8-dsp 0x7055f856 snd_sb8dsp_midi_interrupt +EXPORT_SYMBOL sound/isa/sb/snd-sb8-dsp 0xa9b73be6 snd_sb8dsp_interrupt +EXPORT_SYMBOL sound/isa/sb/snd-sb8-dsp 0xabb3a152 snd_sb8dsp_midi +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0x17f6bd47 snd_emu8000_load_reverb_fx +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0x29e70410 snd_emu8000_update_reverb_mode +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0x30ebaccd snd_emu8000_dma_chan +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0x3349b21e snd_emu8000_poke +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0x5cebcd88 snd_emu8000_init_fm +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0xc05f90fc snd_emu8000_peek +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0xc5baa82b snd_emu8000_poke_dw +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0xca182bc5 snd_emu8000_peek_dw +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0xce56df8e snd_emu8000_update_chorus_mode +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0xe543d899 snd_emu8000_load_chorus_fx +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0xecbb9863 snd_emu8000_update_equalizer +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x0cb962cc snd_wss_mixer +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x0da95ff0 snd_wss_mce_down +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x15b652e3 snd_wss_get_double +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x1d022635 snd_wss_create +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x36b3cc79 snd_wss_info_single +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x42b3b4a2 snd_wss_overrange +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x4ccadcf3 snd_wss_get_pcm_ops +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x631d5980 snd_wss_put_single +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x87261425 snd_cs4236_ext_out +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x92b7594c snd_wss_mce_up +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x95c65f8d snd_cs4236_ext_in +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x9e5f6eb7 snd_wss_interrupt +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xa14211da snd_wss_get_single +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xa179f8e8 snd_wss_pcm +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xc904d385 snd_wss_timer +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xc94ec285 snd_wss_info_double +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xd7e91ab9 snd_wss_put_double +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xde104a3c snd_wss_in +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xebbe474e snd_wss_chip_id +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xfd0dad2d snd_wss_out +EXPORT_SYMBOL sound/oss/ad1848 0x2b5d9dae ad1848_detect +EXPORT_SYMBOL sound/oss/ad1848 0x3969935f attach_ms_sound +EXPORT_SYMBOL sound/oss/ad1848 0x9bf1cc62 ad1848_unload +EXPORT_SYMBOL sound/oss/ad1848 0xa3040913 ad1848_init +EXPORT_SYMBOL sound/oss/ad1848 0xa3e16c6b probe_ms_sound +EXPORT_SYMBOL sound/oss/ad1848 0xb29a9148 unload_ms_sound +EXPORT_SYMBOL sound/oss/ad1848 0xc04f6f67 ad1848_control +EXPORT_SYMBOL sound/oss/mpu401 0x5febf284 unload_mpu401 +EXPORT_SYMBOL sound/oss/mpu401 0x61641749 probe_mpu401 +EXPORT_SYMBOL sound/oss/mpu401 0xe62d0345 attach_mpu401 +EXPORT_SYMBOL sound/oss/msnd 0x1186f48f msnd_fifo_read +EXPORT_SYMBOL sound/oss/msnd 0x234f64e0 msnd_register +EXPORT_SYMBOL sound/oss/msnd 0x340a3ddf msnd_init_queue +EXPORT_SYMBOL sound/oss/msnd 0x54230dc1 msnd_fifo_write +EXPORT_SYMBOL sound/oss/msnd 0x5fb94ecb msnd_unregister +EXPORT_SYMBOL sound/oss/msnd 0x6587640b msnd_disable_irq +EXPORT_SYMBOL sound/oss/msnd 0x6601493b msnd_fifo_make_empty +EXPORT_SYMBOL sound/oss/msnd 0x8e3c524b msnd_send_dsp_cmd +EXPORT_SYMBOL sound/oss/msnd 0x9274d677 msnd_fifo_free +EXPORT_SYMBOL sound/oss/msnd 0x95d37486 msnd_upload_host +EXPORT_SYMBOL sound/oss/msnd 0xa1bcc420 msnd_send_word +EXPORT_SYMBOL sound/oss/msnd 0xade99e25 msnd_fifo_alloc +EXPORT_SYMBOL sound/oss/msnd 0xb3520772 msnd_fifo_init +EXPORT_SYMBOL sound/oss/msnd 0xdf0f59eb msnd_fifo_write_io +EXPORT_SYMBOL sound/oss/msnd 0xefdd1843 msnd_enable_irq +EXPORT_SYMBOL sound/oss/msnd 0xf4c4f662 msnd_fifo_read_io +EXPORT_SYMBOL sound/oss/sb_lib 0x42424109 sb_be_quiet +EXPORT_SYMBOL sound/oss/sb_lib 0x450f9aea smw_free +EXPORT_SYMBOL sound/oss/sb_lib 0x74afd69c unload_sbmpu +EXPORT_SYMBOL sound/oss/sb_lib 0x7af9b449 probe_sbmpu +EXPORT_SYMBOL sound/oss/sb_lib 0xc4884969 sb_dsp_unload +EXPORT_SYMBOL sound/oss/sb_lib 0xcf624990 sb_dsp_init +EXPORT_SYMBOL sound/oss/sb_lib 0xd8a2731c sb_dsp_detect +EXPORT_SYMBOL sound/oss/sound 0x04c87ec8 compute_finetune +EXPORT_SYMBOL sound/oss/sound 0x06339815 sound_unload_synthdev +EXPORT_SYMBOL sound/oss/sound 0x0f280035 conf_printf +EXPORT_SYMBOL sound/oss/sound 0x17ba231d seq_input_event +EXPORT_SYMBOL sound/oss/sound 0x1b3df3cf sound_alloc_mixerdev +EXPORT_SYMBOL sound/oss/sound 0x1f395686 MIDIbuf_avail +EXPORT_SYMBOL sound/oss/sound 0x2161d5e8 sound_timer_init +EXPORT_SYMBOL sound/oss/sound 0x24b65fe6 sound_install_audiodrv +EXPORT_SYMBOL sound/oss/sound 0x2aa31695 midi_synth_kill_note +EXPORT_SYMBOL sound/oss/sound 0x32241eb7 sound_install_mixer +EXPORT_SYMBOL sound/oss/sound 0x394cb088 sound_free_dma +EXPORT_SYMBOL sound/oss/sound 0x418f5fbe sound_close_dma +EXPORT_SYMBOL sound/oss/sound 0x467c1b54 audio_devs +EXPORT_SYMBOL sound/oss/sound 0x4cd01bdd num_audiodevs +EXPORT_SYMBOL sound/oss/sound 0x4f91d6a5 midi_devs +EXPORT_SYMBOL sound/oss/sound 0x4ff47e9d midi_synth_setup_voice +EXPORT_SYMBOL sound/oss/sound 0x51e354b2 sound_alloc_timerdev +EXPORT_SYMBOL sound/oss/sound 0x56504ca2 midi_synth_reset +EXPORT_SYMBOL sound/oss/sound 0x5d986fc9 note_to_freq +EXPORT_SYMBOL sound/oss/sound 0x6db77284 mixer_devs +EXPORT_SYMBOL sound/oss/sound 0x7679ee76 seq_copy_to_input +EXPORT_SYMBOL sound/oss/sound 0x7b5f840f synth_devs +EXPORT_SYMBOL sound/oss/sound 0x7bdf0907 conf_printf2 +EXPORT_SYMBOL sound/oss/sound 0x892093e0 midi_synth_controller +EXPORT_SYMBOL sound/oss/sound 0x90bd9714 sequencer_timer +EXPORT_SYMBOL sound/oss/sound 0x987bcf12 DMAbuf_outputintr +EXPORT_SYMBOL sound/oss/sound 0x9a95733f sound_alloc_dma +EXPORT_SYMBOL sound/oss/sound 0x9bdaf24d midi_synth_start_note +EXPORT_SYMBOL sound/oss/sound 0x9d845b18 num_mixers +EXPORT_SYMBOL sound/oss/sound 0xa1d5f04f load_mixer_volumes +EXPORT_SYMBOL sound/oss/sound 0xa1eae7cf num_midis +EXPORT_SYMBOL sound/oss/sound 0xa41ead5f sound_unload_timerdev +EXPORT_SYMBOL sound/oss/sound 0xa51c913b sound_unload_mixerdev +EXPORT_SYMBOL sound/oss/sound 0xa6bb414c sound_unload_mididev +EXPORT_SYMBOL sound/oss/sound 0xa948751e sound_unload_audiodev +EXPORT_SYMBOL sound/oss/sound 0xad45df73 midi_synth_close +EXPORT_SYMBOL sound/oss/sound 0xaef743b2 midi_synth_ioctl +EXPORT_SYMBOL sound/oss/sound 0xb14b22cd midi_synth_hw_control +EXPORT_SYMBOL sound/oss/sound 0xb51587f6 do_midi_msg +EXPORT_SYMBOL sound/oss/sound 0xba413f87 sound_alloc_mididev +EXPORT_SYMBOL sound/oss/sound 0xba7dd041 midi_synth_bender +EXPORT_SYMBOL sound/oss/sound 0xc748d109 sound_alloc_synthdev +EXPORT_SYMBOL sound/oss/sound 0xc8f82de0 sound_timer_devs +EXPORT_SYMBOL sound/oss/sound 0xcc4b8797 sound_open_dma +EXPORT_SYMBOL sound/oss/sound 0xd85be938 midi_synth_set_instr +EXPORT_SYMBOL sound/oss/sound 0xdb400afa midi_synth_panning +EXPORT_SYMBOL sound/oss/sound 0xe056b71c DMAbuf_start_dma +EXPORT_SYMBOL sound/oss/sound 0xe2675a79 sound_timer_interrupt +EXPORT_SYMBOL sound/oss/sound 0xeb315d99 DMAbuf_inputintr +EXPORT_SYMBOL sound/oss/sound 0xf1ea8a20 midi_synth_aftertouch +EXPORT_SYMBOL sound/oss/sound 0xf6b3a2fb midi_synth_open +EXPORT_SYMBOL sound/oss/sound 0xf7426da3 midi_synth_load_patch +EXPORT_SYMBOL sound/oss/sound 0xf78f6363 sequencer_init +EXPORT_SYMBOL sound/oss/sound 0xfa6871be sound_timer_syncinterval +EXPORT_SYMBOL sound/oss/sound 0xfddcbfb3 midi_synth_send_sysex +EXPORT_SYMBOL sound/oss/uart401 0x46248c57 uart401intr +EXPORT_SYMBOL sound/oss/uart401 0xcbf9050a probe_uart401 +EXPORT_SYMBOL sound/oss/uart401 0xecfdd9c9 unload_uart401 +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x0d164136 snd_ac97_pcm_open +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x1503582e snd_ac97_pcm_close +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x18571580 snd_ac97_update_power +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x22567086 snd_ac97_bus +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x276f99c2 snd_ac97_set_rate +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x3fcba589 snd_ac97_tune_hardware +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x545fb560 snd_ac97_get_short_name +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x69b56726 snd_ac97_update_bits +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x85885048 snd_ac97_pcm_double_rate_rules +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x89cb955a snd_ac97_suspend +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x8cdee975 snd_ac97_write +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x8f6245c1 snd_ac97_write_cache +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xa605a321 snd_ac97_resume +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xcdfdde9e snd_ac97_mixer +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xd5167bdd snd_ac97_pcm_assign +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xee6f2abb snd_ac97_read +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xfac239de snd_ac97_update +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x18700b0f snd_emu10k1_voice_free +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x3e02a307 snd_emu10k1_synth_copy_from_user +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x5291f43e snd_emu10k1_synth_bzero +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x6573ff29 snd_emu10k1_synth_alloc +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x672c5bcc snd_emu10k1_ptr_read +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x7551a837 snd_emu10k1_synth_free +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x885df681 snd_emu10k1_memblk_map +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x88ba4861 snd_emu10k1_voice_alloc +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xd51f973d snd_emu10k1_ptr_write +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0x3af9bfc3 snd_ice1712_akm4xxx_build_controls +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0xca9253e0 snd_ice1712_akm4xxx_init +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0xfe233493 snd_ice1712_akm4xxx_free +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x1f57bc9e oxygen_pci_probe +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x25d89b89 oxygen_reset_uart +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x39df7e62 oxygen_write_ac97_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x3fb19ca2 oxygen_read32 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x41dd327f oxygen_read_ac97 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x4dd435c5 oxygen_read8 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x5a50e08a oxygen_write32_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x6ad89ef1 oxygen_read16 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x6e510e7b oxygen_pci_suspend +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x7bf26b05 oxygen_pci_resume +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x827dc955 oxygen_write8 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x8b9e0f0f oxygen_write_uart +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xd06f7365 oxygen_write16 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xd5456d6f oxygen_pci_remove +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xd691a414 oxygen_write_ac97 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xea13fad1 oxygen_write_spi +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xf11e3358 oxygen_write16_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xf2508929 oxygen_write32 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xf74c03fd oxygen_write8_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xfa3dbe4f oxygen_write_i2c +EXPORT_SYMBOL sound/pci/trident/snd-trident 0x09cfebf1 snd_trident_write_voice_regs +EXPORT_SYMBOL sound/pci/trident/snd-trident 0x93577e2b snd_trident_start_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0xed3633d1 snd_trident_stop_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0xeebfca19 snd_trident_alloc_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0xfacb7c59 snd_trident_free_voice +EXPORT_SYMBOL sound/sound_firmware 0x39e3dd23 mod_firmware_load +EXPORT_SYMBOL sound/soundcore 0x31747f22 register_sound_mixer +EXPORT_SYMBOL sound/soundcore 0x6f9a1a95 register_sound_special_device +EXPORT_SYMBOL sound/soundcore 0x7afc9d8a unregister_sound_mixer +EXPORT_SYMBOL sound/soundcore 0x7f998dee register_sound_special +EXPORT_SYMBOL sound/soundcore 0x99c95fa5 unregister_sound_special +EXPORT_SYMBOL sound/soundcore 0xafd93ae6 register_sound_dsp +EXPORT_SYMBOL sound/soundcore 0xcd083b10 unregister_sound_dsp +EXPORT_SYMBOL sound/soundcore 0xf25823c2 register_sound_midi +EXPORT_SYMBOL sound/soundcore 0xf82ab2f2 sound_class +EXPORT_SYMBOL sound/soundcore 0xfdab6de3 unregister_sound_midi +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x0774d695 snd_emux_terminate_all +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x655cb202 snd_sf_linear_to_log +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x84f9c5ea snd_emux_unlock_voice +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x8f1b5d8e snd_emux_free +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0xc4a44987 snd_emux_lock_voice +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0xe16cf511 snd_emux_new +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0xec20279a snd_emux_register +EXPORT_SYMBOL sound/synth/snd-util-mem 0x20d65978 snd_util_memhdr_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0x24886293 __snd_util_mem_alloc +EXPORT_SYMBOL sound/synth/snd-util-mem 0x569d614e snd_util_mem_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0x7a007343 snd_util_memhdr_new +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd197c5db __snd_util_memblk_new +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd34b56e4 __snd_util_mem_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd8b55e81 snd_util_mem_alloc +EXPORT_SYMBOL sound/synth/snd-util-mem 0xf158252c snd_util_mem_avail +EXPORT_SYMBOL sound/usb/snd-usb-lib 0x16756dc0 snd_usbmidi_input_start +EXPORT_SYMBOL sound/usb/snd-usb-lib 0x1afa73b9 snd_usb_create_midi_interface +EXPORT_SYMBOL sound/usb/snd-usb-lib 0x63343b1d snd_usbmidi_input_stop +EXPORT_SYMBOL sound/usb/snd-usb-lib 0xd9d2bb03 snd_usbmidi_disconnect +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x0613e803 dm_mem_cache_shrink +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x1752e3e1 dm_mem_cache_free +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x6477419b dm_mem_cache_grow +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x8d5fa9fc dm_mem_cache_client_destroy +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xae81e0bd dm_mem_cache_client_create +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xb1e9637e dm_mem_cache_alloc +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-message 0x920a7a41 dm_message_parse +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x0329d132 rh_sector_to_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x03b8fb58 rh_init +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x108f2649 rh_dec +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x1924c972 rh_delay +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x275fdd04 rh_recovery_start +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x2c1f04d5 rh_delay_by_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x40955bcc rh_inc_pending +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x5c2a0632 rh_recovery_end +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x601ed253 rh_bio_to_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x62842029 rh_flush +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x8252ef05 rh_state +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x8821f9a7 rh_region_to_sector +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xa4a7321f rh_get_region_key +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xa923d788 rh_start_recovery +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xac274ed3 rh_stop_recovery +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xb513be98 rh_update_states +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xbb748327 rh_reg_set_context +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc4fdf256 rh_recovery_prepare +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc4ff7745 rh_reg_get_context +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc57bafec rh_exit +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xd99f0978 rh_inc +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xda581f7b rh_get_region_size +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x29c887a9 set_tx_channels +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x60b2e316 cmdir_read +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x7789312a cmdir_write +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0x33343ac8 lirc_register_plugin +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0xc6c9984e lirc_get_pdata +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0xe96379eb lirc_unregister_plugin +EXPORT_SYMBOL ubuntu/misc/media/ov511/ov511 0x229426de ov511_register_decomp_module +EXPORT_SYMBOL ubuntu/misc/media/ov511/ov511 0x7db9be3c ov511_deregister_decomp_module +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x06382656 p80211netdev_rx +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x1a00d360 p80211_resume +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x384db71a p80211skb_free +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x5019ce90 p80211_allow_ioctls +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x585e6681 wlan_setup +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x63a52b5a p80211skb_rxmeta_attach +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x803f8771 p80211_suspend +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x8aa9341f wlan_unsetup +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x97476e0c unregister_wlandev +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x9d36f807 p80211wext_event_associated +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xb0af0799 wlan_wext_write +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xe80a8316 p80211netdev_hwremoved +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xffd02087 register_wlandev +EXPORT_SYMBOL vmlinux 0x00000000 per_cpu__softirq_work_list +EXPORT_SYMBOL vmlinux 0x00112f51 groups_alloc +EXPORT_SYMBOL vmlinux 0x0064a179 __scm_send +EXPORT_SYMBOL vmlinux 0x00701c0f put_io_context +EXPORT_SYMBOL vmlinux 0x00801678 flush_scheduled_work +EXPORT_SYMBOL vmlinux 0x0080fcd6 tcf_hash_release +EXPORT_SYMBOL vmlinux 0x009d258f _write_lock +EXPORT_SYMBOL vmlinux 0x00ae2206 cfb_imageblit +EXPORT_SYMBOL vmlinux 0x00b5f72f names_cachep +EXPORT_SYMBOL vmlinux 0x00b726fa dm_io +EXPORT_SYMBOL vmlinux 0x00c6ab69 hci_free_dev +EXPORT_SYMBOL vmlinux 0x00c920a7 pci_set_consistent_dma_mask +EXPORT_SYMBOL vmlinux 0x00e8097b csum_partial_copy_fromiovecend +EXPORT_SYMBOL vmlinux 0x00e8b2cc pci_request_selected_regions +EXPORT_SYMBOL vmlinux 0x00ff6b40 dm_get_mapinfo +EXPORT_SYMBOL vmlinux 0x01139ffc max_mapnr +EXPORT_SYMBOL vmlinux 0x012098cb skb_copy_expand +EXPORT_SYMBOL vmlinux 0x0186d073 percpu_counter_set +EXPORT_SYMBOL vmlinux 0x01902adf netpoll_trap +EXPORT_SYMBOL vmlinux 0x01a4aab6 set_irq_chip_data +EXPORT_SYMBOL vmlinux 0x01c0cc2d eth_type_trans +EXPORT_SYMBOL vmlinux 0x01d19038 acpi_enable_subsystem +EXPORT_SYMBOL vmlinux 0x0203cab8 qdisc_reset +EXPORT_SYMBOL vmlinux 0x02124474 ip_send_check +EXPORT_SYMBOL vmlinux 0x02138f9d bioset_integrity_create +EXPORT_SYMBOL vmlinux 0x0237b57a arch_unregister_cpu +EXPORT_SYMBOL vmlinux 0x0239b029 set_disk_ro +EXPORT_SYMBOL vmlinux 0x025277f6 profile_pc +EXPORT_SYMBOL vmlinux 0x0256389f bit_waitqueue +EXPORT_SYMBOL vmlinux 0x02649054 security_sock_rcv_skb +EXPORT_SYMBOL vmlinux 0x02882123 usb_serial_suspend +EXPORT_SYMBOL vmlinux 0x029319cb mca_bus_type +EXPORT_SYMBOL vmlinux 0x029444f0 native_read_tsc +EXPORT_SYMBOL vmlinux 0x02a18c74 nf_conntrack_destroy +EXPORT_SYMBOL vmlinux 0x02a6ce5a crc16_table +EXPORT_SYMBOL vmlinux 0x02aff2f4 acpi_install_gpe_handler +EXPORT_SYMBOL vmlinux 0x02beaede scsi_is_host_device +EXPORT_SYMBOL vmlinux 0x02d81845 audit_log_task_context +EXPORT_SYMBOL vmlinux 0x02e76253 iput +EXPORT_SYMBOL vmlinux 0x02ee26c1 free_pages_exact +EXPORT_SYMBOL vmlinux 0x03094153 prepare_binprm +EXPORT_SYMBOL vmlinux 0x0309648a generic_file_readonly_mmap +EXPORT_SYMBOL vmlinux 0x032ca4c1 fifo_create_dflt +EXPORT_SYMBOL vmlinux 0x0334da4e scsi_command_size_tbl +EXPORT_SYMBOL vmlinux 0x03569e3b vfs_quota_off +EXPORT_SYMBOL vmlinux 0x037a0cba kfree +EXPORT_SYMBOL vmlinux 0x038a08ff inet_register_protosw +EXPORT_SYMBOL vmlinux 0x038ad577 acpi_get_hp_hw_control_from_firmware +EXPORT_SYMBOL vmlinux 0x03a99c3b rb_prev +EXPORT_SYMBOL vmlinux 0x03c06156 bitmap_fold +EXPORT_SYMBOL vmlinux 0x03c1b5a6 inet_listen +EXPORT_SYMBOL vmlinux 0x03fcfe5b kobject_init +EXPORT_SYMBOL vmlinux 0x03fd2571 vm_unmap_ram +EXPORT_SYMBOL vmlinux 0x04219014 register_sysrq_key +EXPORT_SYMBOL vmlinux 0x0422fe4a inet_csk_timer_bug_msg +EXPORT_SYMBOL vmlinux 0x044a44f6 tcf_exts_destroy +EXPORT_SYMBOL vmlinux 0x044fbf49 mempool_kzalloc +EXPORT_SYMBOL vmlinux 0x045796f6 xfrm_init_state +EXPORT_SYMBOL vmlinux 0x0487f831 fb_find_best_display +EXPORT_SYMBOL vmlinux 0x049b2995 blk_queue_max_phys_segments +EXPORT_SYMBOL vmlinux 0x04a1032e dmam_free_coherent +EXPORT_SYMBOL vmlinux 0x04bc8668 inet_proto_csum_replace4 +EXPORT_SYMBOL vmlinux 0x04cf8da0 tcf_exts_dump +EXPORT_SYMBOL vmlinux 0x04d8c750 release_perfctr_nmi +EXPORT_SYMBOL vmlinux 0x04dc2ae5 uart_update_timeout +EXPORT_SYMBOL vmlinux 0x04e237af i2c_add_adapter +EXPORT_SYMBOL vmlinux 0x050cad4f skb_recycle_check +EXPORT_SYMBOL vmlinux 0x052918cb dev_unicast_unsync +EXPORT_SYMBOL vmlinux 0x053391e0 uart_match_port +EXPORT_SYMBOL vmlinux 0x054632ec serio_rescan +EXPORT_SYMBOL vmlinux 0x055fd3ac nobh_write_begin +EXPORT_SYMBOL vmlinux 0x0560cdeb xfrm_state_flush +EXPORT_SYMBOL vmlinux 0x057ce975 hex_dump_to_buffer +EXPORT_SYMBOL vmlinux 0x057ff5da mca_device_transform_memory +EXPORT_SYMBOL vmlinux 0x058c75d9 acpi_get_pci_id +EXPORT_SYMBOL vmlinux 0x05b384c2 vfs_follow_link +EXPORT_SYMBOL vmlinux 0x05b57631 remove_proc_entry +EXPORT_SYMBOL vmlinux 0x05bba8c1 scsi_add_host +EXPORT_SYMBOL vmlinux 0x05c5f4d6 lock_rename +EXPORT_SYMBOL vmlinux 0x05cc6da8 unregister_netdevice +EXPORT_SYMBOL vmlinux 0x05e27fbd bio_split +EXPORT_SYMBOL vmlinux 0x05e28d43 __first_cpu +EXPORT_SYMBOL vmlinux 0x061651be strcat +EXPORT_SYMBOL vmlinux 0x0623e5ab __set_page_dirty_buffers +EXPORT_SYMBOL vmlinux 0x063ae75e phy_print_status +EXPORT_SYMBOL vmlinux 0x06689659 jbd2_journal_ack_err +EXPORT_SYMBOL vmlinux 0x067d8d35 security_release_secctx +EXPORT_SYMBOL vmlinux 0x0692f390 rfkill_free +EXPORT_SYMBOL vmlinux 0x06949c21 elv_abort_queue +EXPORT_SYMBOL vmlinux 0x06bd3bbf netpoll_parse_options +EXPORT_SYMBOL vmlinux 0x06d728b1 tcp_parse_md5sig_option +EXPORT_SYMBOL vmlinux 0x06eb4eac mmc_suspend_host +EXPORT_SYMBOL vmlinux 0x06ee1f39 flush_tlb_page +EXPORT_SYMBOL vmlinux 0x06f30855 mmc_wait_for_app_cmd +EXPORT_SYMBOL vmlinux 0x06fe3b14 default_grn +EXPORT_SYMBOL vmlinux 0x0708a407 mmc_align_data_size +EXPORT_SYMBOL vmlinux 0x07178a77 mca_device_set_name +EXPORT_SYMBOL vmlinux 0x0727c4f3 iowrite8 +EXPORT_SYMBOL vmlinux 0x072d7276 write_one_page +EXPORT_SYMBOL vmlinux 0x073dfa12 generate_resume_trace +EXPORT_SYMBOL vmlinux 0x07455f2e fddi_type_trans +EXPORT_SYMBOL vmlinux 0x07608604 acpi_get_vendor_resource +EXPORT_SYMBOL vmlinux 0x07699746 set_device_ro +EXPORT_SYMBOL vmlinux 0x0793c689 nf_setsockopt +EXPORT_SYMBOL vmlinux 0x0799aca4 local_bh_enable +EXPORT_SYMBOL vmlinux 0x079cd7f1 ns_to_timeval +EXPORT_SYMBOL vmlinux 0x07a890c8 fb_alloc_cmap +EXPORT_SYMBOL vmlinux 0x07bf670a inet_getname +EXPORT_SYMBOL vmlinux 0x07cc4a5d printk_timed_ratelimit +EXPORT_SYMBOL vmlinux 0x07d50a24 csum_partial +EXPORT_SYMBOL vmlinux 0x07d8477d pneigh_lookup +EXPORT_SYMBOL vmlinux 0x07d9b783 scsi_nl_send_vendor_msg +EXPORT_SYMBOL vmlinux 0x08015581 ipv6_setsockopt +EXPORT_SYMBOL vmlinux 0x080b157a block_write_full_page +EXPORT_SYMBOL vmlinux 0x082c3213 pci_root_buses +EXPORT_SYMBOL vmlinux 0x083a9e70 i2c_probe +EXPORT_SYMBOL vmlinux 0x08790e6a per_cpu__cpu_info +EXPORT_SYMBOL vmlinux 0x089a4e1b atm_dev_deregister +EXPORT_SYMBOL vmlinux 0x0933aae1 efi_enabled +EXPORT_SYMBOL vmlinux 0x093e24e6 inet_accept +EXPORT_SYMBOL vmlinux 0x093e947e posix_acl_create_masq +EXPORT_SYMBOL vmlinux 0x0948cde9 num_physpages +EXPORT_SYMBOL vmlinux 0x09775cdc kref_get +EXPORT_SYMBOL vmlinux 0x098b71c6 fb_dealloc_cmap +EXPORT_SYMBOL vmlinux 0x09baa4e2 nf_log_unregister +EXPORT_SYMBOL vmlinux 0x09c55cec schedule_timeout_interruptible +EXPORT_SYMBOL vmlinux 0x09d30151 neigh_table_init +EXPORT_SYMBOL vmlinux 0x09d44df9 in_lock_functions +EXPORT_SYMBOL vmlinux 0x0a2487e0 unblock_all_signals +EXPORT_SYMBOL vmlinux 0x0a29eac4 inode_change_ok +EXPORT_SYMBOL vmlinux 0x0a2c23b6 blk_start_queue +EXPORT_SYMBOL vmlinux 0x0a3131f6 strnchr +EXPORT_SYMBOL vmlinux 0x0a456e91 pci_bus_write_config_dword +EXPORT_SYMBOL vmlinux 0x0a4747ff allocate_resource +EXPORT_SYMBOL vmlinux 0x0a511acd blk_dump_rq_flags +EXPORT_SYMBOL vmlinux 0x0a575d4d scsi_execute +EXPORT_SYMBOL vmlinux 0x0aa711f2 kmem_cache_size +EXPORT_SYMBOL vmlinux 0x0acb1a3c __bitmap_shift_right +EXPORT_SYMBOL vmlinux 0x0af7baee register_gifconf +EXPORT_SYMBOL vmlinux 0x0af8daa8 alloc_fddidev +EXPORT_SYMBOL vmlinux 0x0b1beb31 vmalloc_32_user +EXPORT_SYMBOL vmlinux 0x0b3a1f2c sock_wmalloc +EXPORT_SYMBOL vmlinux 0x0b40b224 dev_queue_xmit +EXPORT_SYMBOL vmlinux 0x0b742fd7 simple_strtol +EXPORT_SYMBOL vmlinux 0x0b758e75 dma_release_declared_memory +EXPORT_SYMBOL vmlinux 0x0bf8e710 inet_stream_connect +EXPORT_SYMBOL vmlinux 0x0bfc2c22 pnp_unregister_driver +EXPORT_SYMBOL vmlinux 0x0c003689 end_buffer_write_sync +EXPORT_SYMBOL vmlinux 0x0c0d2adf sock_no_getname +EXPORT_SYMBOL vmlinux 0x0c17bec4 file_fsync +EXPORT_SYMBOL vmlinux 0x0c1e2c50 vc_cons +EXPORT_SYMBOL vmlinux 0x0c55e87c rfkill_force_state +EXPORT_SYMBOL vmlinux 0x0c5ef91b per_cpu__vm_event_states +EXPORT_SYMBOL vmlinux 0x0c65e73c scsi_normalize_sense +EXPORT_SYMBOL vmlinux 0x0c8c9e99 scsi_show_extd_sense +EXPORT_SYMBOL vmlinux 0x0c94df4e iov_iter_copy_from_user +EXPORT_SYMBOL vmlinux 0x0cd5d880 mca_device_transform_irq +EXPORT_SYMBOL vmlinux 0x0ce9585f fb_is_primary_device +EXPORT_SYMBOL vmlinux 0x0d07438a flock_lock_file_wait +EXPORT_SYMBOL vmlinux 0x0d1c24b0 jbd2_journal_clear_features +EXPORT_SYMBOL vmlinux 0x0d20522a jbd2_journal_abort +EXPORT_SYMBOL vmlinux 0x0d26a76d _write_lock_irq +EXPORT_SYMBOL vmlinux 0x0d3858c5 mb_cache_shrink +EXPORT_SYMBOL vmlinux 0x0d3dda14 acpi_get_type +EXPORT_SYMBOL vmlinux 0x0d4b77b7 gen_pool_add +EXPORT_SYMBOL vmlinux 0x0d4f46c4 pcim_iounmap_regions +EXPORT_SYMBOL vmlinux 0x0d4f6975 blk_queue_merge_bvec +EXPORT_SYMBOL vmlinux 0x0d542439 __ipv6_addr_type +EXPORT_SYMBOL vmlinux 0x0d62cb6e nla_append +EXPORT_SYMBOL vmlinux 0x0d6c963c copy_from_user +EXPORT_SYMBOL vmlinux 0x0d7c3b44 tcf_em_register +EXPORT_SYMBOL vmlinux 0x0d8ab500 param_set_copystring +EXPORT_SYMBOL vmlinux 0x0da10ec3 security_sock_graft +EXPORT_SYMBOL vmlinux 0x0dbef837 nobh_writepage +EXPORT_SYMBOL vmlinux 0x0de57b02 scsi_register_interface +EXPORT_SYMBOL vmlinux 0x0de89d8c pci_set_mwi +EXPORT_SYMBOL vmlinux 0x0e11900d __dev_get_by_name +EXPORT_SYMBOL vmlinux 0x0e4272ee thermal_cooling_device_unregister +EXPORT_SYMBOL vmlinux 0x0e480e30 get_sb_nodev +EXPORT_SYMBOL vmlinux 0x0e52592a panic +EXPORT_SYMBOL vmlinux 0x0e53c8c8 set_pages_wb +EXPORT_SYMBOL vmlinux 0x0e650f2e xfrm_stateonly_find +EXPORT_SYMBOL vmlinux 0x0e6d6e78 block_prepare_write +EXPORT_SYMBOL vmlinux 0x0e762d6e request_module +EXPORT_SYMBOL vmlinux 0x0eee402a simple_link +EXPORT_SYMBOL vmlinux 0x0ef62686 neigh_parms_release +EXPORT_SYMBOL vmlinux 0x0f0f277a bio_add_pc_page +EXPORT_SYMBOL vmlinux 0x0f3217bb register_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0x0f3fab64 qdisc_list_del +EXPORT_SYMBOL vmlinux 0x0fa7361b journal_extend +EXPORT_SYMBOL vmlinux 0x0fab02d4 alloc_fcdev +EXPORT_SYMBOL vmlinux 0x0faef0ed __tasklet_schedule +EXPORT_SYMBOL vmlinux 0x0fb232f9 fb_validate_mode +EXPORT_SYMBOL vmlinux 0x0fce8aaf fsync_bdev +EXPORT_SYMBOL vmlinux 0x0fd00a68 acpi_clear_event +EXPORT_SYMBOL vmlinux 0x0feb1be6 blk_queue_bounce_limit +EXPORT_SYMBOL vmlinux 0x0ff2b602 slhc_compress +EXPORT_SYMBOL vmlinux 0x1004a192 ip_ct_attach +EXPORT_SYMBOL vmlinux 0x100883ab sock_i_uid +EXPORT_SYMBOL vmlinux 0x102ecda9 pci_disable_msi +EXPORT_SYMBOL vmlinux 0x1030e450 follow_up +EXPORT_SYMBOL vmlinux 0x10695259 blk_execute_rq +EXPORT_SYMBOL vmlinux 0x10771d9c sk_stream_wait_close +EXPORT_SYMBOL vmlinux 0x107ed2eb textsearch_prepare +EXPORT_SYMBOL vmlinux 0x10820ba3 generic_writepages +EXPORT_SYMBOL vmlinux 0x1082f71f set_pages_nx +EXPORT_SYMBOL vmlinux 0x10bf0e77 init_file +EXPORT_SYMBOL vmlinux 0x10d32718 uart_resume_port +EXPORT_SYMBOL vmlinux 0x10dd37c4 kblockd_schedule_work +EXPORT_SYMBOL vmlinux 0x10df1101 search_binary_handler +EXPORT_SYMBOL vmlinux 0x10e7079f journal_errno +EXPORT_SYMBOL vmlinux 0x10ee20bb default_blu +EXPORT_SYMBOL vmlinux 0x10f8bcfb security_inode_init_security +EXPORT_SYMBOL vmlinux 0x1111f78f scsi_host_set_state +EXPORT_SYMBOL vmlinux 0x111e179a pci_enable_wake +EXPORT_SYMBOL vmlinux 0x11267875 scsi_extd_sense_format +EXPORT_SYMBOL vmlinux 0x1163f0a7 blk_max_low_pfn +EXPORT_SYMBOL vmlinux 0x1168d49b blk_complete_request +EXPORT_SYMBOL vmlinux 0x117093be qdisc_class_hash_init +EXPORT_SYMBOL vmlinux 0x118f01ea putname +EXPORT_SYMBOL vmlinux 0x118f551c open_exec +EXPORT_SYMBOL vmlinux 0x11a18b14 __wake_up_bit +EXPORT_SYMBOL vmlinux 0x11f33889 nf_unregister_hook +EXPORT_SYMBOL vmlinux 0x120507ac idr_get_new +EXPORT_SYMBOL vmlinux 0x12250e0f genphy_config_advert +EXPORT_SYMBOL vmlinux 0x12337215 jbd2_log_wait_commit +EXPORT_SYMBOL vmlinux 0x125fbca7 cad_pid +EXPORT_SYMBOL vmlinux 0x1260fdb0 scsi_dma_map +EXPORT_SYMBOL vmlinux 0x126970ed param_set_uint +EXPORT_SYMBOL vmlinux 0x1292f144 mmc_alloc_host +EXPORT_SYMBOL vmlinux 0x129d28af set_page_dirty +EXPORT_SYMBOL vmlinux 0x12a88a1e vfs_quota_on_path +EXPORT_SYMBOL vmlinux 0x12c97552 create_proc_entry +EXPORT_SYMBOL vmlinux 0x12da5bb2 __kmalloc +EXPORT_SYMBOL vmlinux 0x12f99022 inet_frags_init_net +EXPORT_SYMBOL vmlinux 0x12fd1253 jbd2_journal_revoke +EXPORT_SYMBOL vmlinux 0x132932dc blk_integrity_compare +EXPORT_SYMBOL vmlinux 0x132f45f2 cookie_check_timestamp +EXPORT_SYMBOL vmlinux 0x1378e714 acpi_video_display_switch_support +EXPORT_SYMBOL vmlinux 0x139f4660 simple_dir_operations +EXPORT_SYMBOL vmlinux 0x13a11469 locks_remove_posix +EXPORT_SYMBOL vmlinux 0x13a68ab5 set_page_dirty_lock +EXPORT_SYMBOL vmlinux 0x13d68b5e phy_driver_register +EXPORT_SYMBOL vmlinux 0x13f71731 tcf_hash_lookup +EXPORT_SYMBOL vmlinux 0x1430e6e0 unregister_acpi_notifier +EXPORT_SYMBOL vmlinux 0x1446003d netdev_bonding_change +EXPORT_SYMBOL vmlinux 0x1449ca28 dma_sync_wait +EXPORT_SYMBOL vmlinux 0x1454215b ipv6_chk_addr +EXPORT_SYMBOL vmlinux 0x1477c728 flow_cache_lookup +EXPORT_SYMBOL vmlinux 0x148b4489 xfrm6_rcv_spi +EXPORT_SYMBOL vmlinux 0x149afc08 phy_start_aneg +EXPORT_SYMBOL vmlinux 0x14af0cf7 gen_pool_destroy +EXPORT_SYMBOL vmlinux 0x14b4ca65 security_task_getsecid +EXPORT_SYMBOL vmlinux 0x14f332ea up_read +EXPORT_SYMBOL vmlinux 0x1508a0ab generic_file_open +EXPORT_SYMBOL vmlinux 0x153fd1b8 arp_send +EXPORT_SYMBOL vmlinux 0x15445a23 km_state_notify +EXPORT_SYMBOL vmlinux 0x1544aad4 genl_register_mc_group +EXPORT_SYMBOL vmlinux 0x1551dc51 bitmap_find_free_region +EXPORT_SYMBOL vmlinux 0x156565d0 xfrm4_rcv_encap +EXPORT_SYMBOL vmlinux 0x15ddba93 neigh_lookup +EXPORT_SYMBOL vmlinux 0x15de6a2f proc_net_netfilter +EXPORT_SYMBOL vmlinux 0x15de939d get_fs_type +EXPORT_SYMBOL vmlinux 0x15ef2dd9 kfifo_free +EXPORT_SYMBOL vmlinux 0x16747c0d kern_path +EXPORT_SYMBOL vmlinux 0x167e7f9d __get_user_1 +EXPORT_SYMBOL vmlinux 0x167ea1d8 blk_queue_find_tag +EXPORT_SYMBOL vmlinux 0x16a35878 _read_unlock +EXPORT_SYMBOL vmlinux 0x16b0b86c mmc_request_done +EXPORT_SYMBOL vmlinux 0x16c7fe73 scsi_free_host_dev +EXPORT_SYMBOL vmlinux 0x16d47ae1 generic_file_direct_write +EXPORT_SYMBOL vmlinux 0x16ee8a16 __mod_zone_page_state +EXPORT_SYMBOL vmlinux 0x16ef850b dev_mc_add +EXPORT_SYMBOL vmlinux 0x16f30d6a journal_release_buffer +EXPORT_SYMBOL vmlinux 0x17052027 thermal_zone_unbind_cooling_device +EXPORT_SYMBOL vmlinux 0x170c25ee acpi_get_next_object +EXPORT_SYMBOL vmlinux 0x172ed4d7 __vmalloc +EXPORT_SYMBOL vmlinux 0x1741a87f dma_async_client_register +EXPORT_SYMBOL vmlinux 0x174b7a7f devm_ioremap_nocache +EXPORT_SYMBOL vmlinux 0x175a298d acpi_set_firmware_waking_vector +EXPORT_SYMBOL vmlinux 0x178d732c sock_recvmsg +EXPORT_SYMBOL vmlinux 0x178da189 block_truncate_page +EXPORT_SYMBOL vmlinux 0x17a76e71 rb_first +EXPORT_SYMBOL vmlinux 0x17c20fef mdiobus_alloc +EXPORT_SYMBOL vmlinux 0x17df17bc sysctl_tcp_ecn +EXPORT_SYMBOL vmlinux 0x17df2046 bd_release +EXPORT_SYMBOL vmlinux 0x17e5cb9b tcp_md5_hash_skb_data +EXPORT_SYMBOL vmlinux 0x18154643 nf_afinfo +EXPORT_SYMBOL vmlinux 0x181773e8 register_binfmt +EXPORT_SYMBOL vmlinux 0x1819f00b unregister_binfmt +EXPORT_SYMBOL vmlinux 0x181b6ff2 mempool_resize +EXPORT_SYMBOL vmlinux 0x182c97bb tcf_generic_walker +EXPORT_SYMBOL vmlinux 0x183cd7d8 acpi_bus_add +EXPORT_SYMBOL vmlinux 0x183fa88b mempool_alloc_slab +EXPORT_SYMBOL vmlinux 0x184041d7 inet_csk_reset_keepalive_timer +EXPORT_SYMBOL vmlinux 0x1845e7c5 acpi_evaluate_integer +EXPORT_SYMBOL vmlinux 0x18496855 __devm_request_region +EXPORT_SYMBOL vmlinux 0x187fea42 acpi_check_resource_conflict +EXPORT_SYMBOL vmlinux 0x18872fc4 __dst_free +EXPORT_SYMBOL vmlinux 0x188d9fef blk_queue_stack_limits +EXPORT_SYMBOL vmlinux 0x18dde6c0 pcie_port_service_unregister +EXPORT_SYMBOL vmlinux 0x18e018da udp_prot +EXPORT_SYMBOL vmlinux 0x18ef0e50 set_binfmt +EXPORT_SYMBOL vmlinux 0x193ad3ca unregister_nls +EXPORT_SYMBOL vmlinux 0x194c4ecc km_new_mapping +EXPORT_SYMBOL vmlinux 0x195ec348 netlink_kernel_create +EXPORT_SYMBOL vmlinux 0x19601037 dev_set_mtu +EXPORT_SYMBOL vmlinux 0x1985ed3c prepare_to_wait_exclusive +EXPORT_SYMBOL vmlinux 0x198a12f1 block_is_partially_uptodate +EXPORT_SYMBOL vmlinux 0x199ed0cd net_disable_timestamp +EXPORT_SYMBOL vmlinux 0x19c12345 i2c_smbus_read_i2c_block_data +EXPORT_SYMBOL vmlinux 0x19d5d20a acpi_walk_namespace +EXPORT_SYMBOL vmlinux 0x19d64cc3 journal_start_commit +EXPORT_SYMBOL vmlinux 0x19dd64ac __fatal_signal_pending +EXPORT_SYMBOL vmlinux 0x19f5d6f0 thermal_cooling_device_register +EXPORT_SYMBOL vmlinux 0x19fc9ca8 ppp_input +EXPORT_SYMBOL vmlinux 0x1a0c3381 cdrom_release +EXPORT_SYMBOL vmlinux 0x1a1ab15d tty_mutex +EXPORT_SYMBOL vmlinux 0x1a1d7bed dm_io_client_create +EXPORT_SYMBOL vmlinux 0x1a45cb6c acpi_disabled +EXPORT_SYMBOL vmlinux 0x1a75caa3 _read_lock +EXPORT_SYMBOL vmlinux 0x1a7f2ab2 tcf_exts_validate +EXPORT_SYMBOL vmlinux 0x1a854228 get_io_context +EXPORT_SYMBOL vmlinux 0x1a8a845e idle_nomwait +EXPORT_SYMBOL vmlinux 0x1a8efe67 dm_table_get_size +EXPORT_SYMBOL vmlinux 0x1aa25358 ethtool_op_set_ufo +EXPORT_SYMBOL vmlinux 0x1ace138d bitmap_allocate_region +EXPORT_SYMBOL vmlinux 0x1ace4031 ethtool_op_set_tx_csum +EXPORT_SYMBOL vmlinux 0x1ae17de4 uart_get_divisor +EXPORT_SYMBOL vmlinux 0x1ae8d7dc param_set_invbool +EXPORT_SYMBOL vmlinux 0x1b015d25 bitmap_parselist +EXPORT_SYMBOL vmlinux 0x1b1df3c4 genl_unregister_ops +EXPORT_SYMBOL vmlinux 0x1b2fa8f0 follow_down +EXPORT_SYMBOL vmlinux 0x1b3c678a gen_new_estimator +EXPORT_SYMBOL vmlinux 0x1b571e00 atm_dev_register +EXPORT_SYMBOL vmlinux 0x1b6314fd in_aton +EXPORT_SYMBOL vmlinux 0x1b6c95a2 kick_iocb +EXPORT_SYMBOL vmlinux 0x1b794857 in6_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0x1b7953dd iw_handler_get_thrspy +EXPORT_SYMBOL vmlinux 0x1b89419f add_wait_queue_exclusive +EXPORT_SYMBOL vmlinux 0x1b8b5cf0 generic_shutdown_super +EXPORT_SYMBOL vmlinux 0x1b9981cc set_irq_wake +EXPORT_SYMBOL vmlinux 0x1b9e0ff1 scsilun_to_int +EXPORT_SYMBOL vmlinux 0x1b9eace9 tty_name +EXPORT_SYMBOL vmlinux 0x1c039b7c xfrm_policy_insert +EXPORT_SYMBOL vmlinux 0x1c0a74f7 filemap_fdatawrite +EXPORT_SYMBOL vmlinux 0x1c0e94c6 tty_driver_flush_buffer +EXPORT_SYMBOL vmlinux 0x1c1a55af phy_start_interrupts +EXPORT_SYMBOL vmlinux 0x1c3361d6 neigh_create +EXPORT_SYMBOL vmlinux 0x1c963375 __getblk +EXPORT_SYMBOL vmlinux 0x1c9633dd textsearch_register +EXPORT_SYMBOL vmlinux 0x1ca4b84d sock_no_sendmsg +EXPORT_SYMBOL vmlinux 0x1ca8099e __tcp_get_md5sig_pool +EXPORT_SYMBOL vmlinux 0x1cc6719a register_reboot_notifier +EXPORT_SYMBOL vmlinux 0x1cd30e13 xfrm_dst_ifdown +EXPORT_SYMBOL vmlinux 0x1cd6fbe4 __mpage_writepage +EXPORT_SYMBOL vmlinux 0x1ce1e467 load_nls_default +EXPORT_SYMBOL vmlinux 0x1cefe352 wait_for_completion +EXPORT_SYMBOL vmlinux 0x1d30b70c rwsem_wake +EXPORT_SYMBOL vmlinux 0x1d360a4c redirty_page_for_writepage +EXPORT_SYMBOL vmlinux 0x1dc36131 fb_destroy_modedb +EXPORT_SYMBOL vmlinux 0x1dd571e6 fb_copy_cmap +EXPORT_SYMBOL vmlinux 0x1e0a2a42 thaw_process +EXPORT_SYMBOL vmlinux 0x1e210839 netpoll_setup +EXPORT_SYMBOL vmlinux 0x1e2e427f cpumask_next_and +EXPORT_SYMBOL vmlinux 0x1e6d26a8 strstr +EXPORT_SYMBOL vmlinux 0x1ea0c050 f_setown +EXPORT_SYMBOL vmlinux 0x1eade071 jbd2_journal_lock_updates +EXPORT_SYMBOL vmlinux 0x1eb922a3 IO_APIC_get_PCI_irq_vector +EXPORT_SYMBOL vmlinux 0x1ed5bab4 sock_setsockopt +EXPORT_SYMBOL vmlinux 0x1efe283f __cap_full_set +EXPORT_SYMBOL vmlinux 0x1f008c8f fput +EXPORT_SYMBOL vmlinux 0x1f27d6d7 _write_unlock +EXPORT_SYMBOL vmlinux 0x1f280ca6 cancel_dirty_page +EXPORT_SYMBOL vmlinux 0x1f4ac055 acpi_processor_preregister_performance +EXPORT_SYMBOL vmlinux 0x1f5a01b5 sockfd_lookup +EXPORT_SYMBOL vmlinux 0x1f9211fd input_unregister_handle +EXPORT_SYMBOL vmlinux 0x1fdbf985 scsi_unregister +EXPORT_SYMBOL vmlinux 0x1fe5ede6 per_cpu__irq_stat +EXPORT_SYMBOL vmlinux 0x1ff0bb79 dcache_readdir +EXPORT_SYMBOL vmlinux 0x20000329 simple_strtoul +EXPORT_SYMBOL vmlinux 0x2005e68a acpi_remove_fixed_event_handler +EXPORT_SYMBOL vmlinux 0x200efa1d scsi_remove_target +EXPORT_SYMBOL vmlinux 0x20412694 inode_get_bytes +EXPORT_SYMBOL vmlinux 0x205ea071 acpi_get_physical_pci_device +EXPORT_SYMBOL vmlinux 0x206e6f85 qdisc_class_hash_grow +EXPORT_SYMBOL vmlinux 0x208739f6 acpi_load_table +EXPORT_SYMBOL vmlinux 0x2090ce89 tty_port_tty_set +EXPORT_SYMBOL vmlinux 0x209a7164 __dev_get_by_index +EXPORT_SYMBOL vmlinux 0x20c8fc33 pci_osc_control_set +EXPORT_SYMBOL vmlinux 0x20c98fe5 inet_frag_find +EXPORT_SYMBOL vmlinux 0x20e6c3a7 xfrm4_rcv +EXPORT_SYMBOL vmlinux 0x20fdfd5c dma_async_memcpy_buf_to_buf +EXPORT_SYMBOL vmlinux 0x210fd9ae ppp_unit_number +EXPORT_SYMBOL vmlinux 0x21297ce9 uart_register_driver +EXPORT_SYMBOL vmlinux 0x213b742b ppp_register_compressor +EXPORT_SYMBOL vmlinux 0x2154eaae generic_file_splice_write +EXPORT_SYMBOL vmlinux 0x215ebd78 bitrev16 +EXPORT_SYMBOL vmlinux 0x215fa59f udp_flush_pending_frames +EXPORT_SYMBOL vmlinux 0x218480f6 mca_register_driver_integrated +EXPORT_SYMBOL vmlinux 0x2186ffba neigh_changeaddr +EXPORT_SYMBOL vmlinux 0x21cc9591 have_submounts +EXPORT_SYMBOL vmlinux 0x21e0ea22 acpi_get_id +EXPORT_SYMBOL vmlinux 0x21ede2fd neigh_parms_alloc +EXPORT_SYMBOL vmlinux 0x21f1b5b7 dev_set_mac_address +EXPORT_SYMBOL vmlinux 0x21f7dd3b skb_find_text +EXPORT_SYMBOL vmlinux 0x222e7ce2 sysfs_streq +EXPORT_SYMBOL vmlinux 0x226e86a9 audit_log +EXPORT_SYMBOL vmlinux 0x2270e67b mca_device_write_pos +EXPORT_SYMBOL vmlinux 0x2273a982 tcf_em_tree_destroy +EXPORT_SYMBOL vmlinux 0x2288378f system_state +EXPORT_SYMBOL vmlinux 0x229ac0c6 input_set_capability +EXPORT_SYMBOL vmlinux 0x22a73912 __tcp_put_md5sig_pool +EXPORT_SYMBOL vmlinux 0x22b325d5 kd_mksound +EXPORT_SYMBOL vmlinux 0x22b61dc4 pci_bus_find_capability +EXPORT_SYMBOL vmlinux 0x22b6533b xfrm_sad_getinfo +EXPORT_SYMBOL vmlinux 0x22d24ddc mark_info_dirty +EXPORT_SYMBOL vmlinux 0x22da3351 jbd2_journal_destroy +EXPORT_SYMBOL vmlinux 0x22ffb579 dm_table_get +EXPORT_SYMBOL vmlinux 0x22ffd14b sg_miter_stop +EXPORT_SYMBOL vmlinux 0x231f3a66 __kfifo_put +EXPORT_SYMBOL vmlinux 0x23269a13 strict_strtoul +EXPORT_SYMBOL vmlinux 0x23349332 phy_stop +EXPORT_SYMBOL vmlinux 0x233a84bf kill_litter_super +EXPORT_SYMBOL vmlinux 0x23620721 dev_alloc_skb +EXPORT_SYMBOL vmlinux 0x2368be6d posix_acl_to_xattr +EXPORT_SYMBOL vmlinux 0x23882705 mod_zone_page_state +EXPORT_SYMBOL vmlinux 0x23a4c689 mmc_wait_for_cmd +EXPORT_SYMBOL vmlinux 0x23ad070a set_current_groups +EXPORT_SYMBOL vmlinux 0x23b4e1e4 skb_copy_and_csum_dev +EXPORT_SYMBOL vmlinux 0x23c8f257 slhc_uncompress +EXPORT_SYMBOL vmlinux 0x23fd3028 vmalloc_node +EXPORT_SYMBOL vmlinux 0x240860aa __set_page_dirty_nobuffers +EXPORT_SYMBOL vmlinux 0x2416be4f sock_no_recvmsg +EXPORT_SYMBOL vmlinux 0x24204103 kill_fasync +EXPORT_SYMBOL vmlinux 0x2423395a skb_copy_and_csum_datagram_iovec +EXPORT_SYMBOL vmlinux 0x243ffddc idr_destroy +EXPORT_SYMBOL vmlinux 0x24428be5 strncpy_from_user +EXPORT_SYMBOL vmlinux 0x2459bbcc console_set_on_cmdline +EXPORT_SYMBOL vmlinux 0x245b3e38 i2c_detach_client +EXPORT_SYMBOL vmlinux 0x2472b34f make_bad_inode +EXPORT_SYMBOL vmlinux 0x2475471c should_remove_suid +EXPORT_SYMBOL vmlinux 0x2477b535 misc_register +EXPORT_SYMBOL vmlinux 0x24b006c2 nf_unregister_hooks +EXPORT_SYMBOL vmlinux 0x24dbf7f4 sock_no_socketpair +EXPORT_SYMBOL vmlinux 0x24e2cc64 n_tty_ioctl_helper +EXPORT_SYMBOL vmlinux 0x24f7ccd0 journal_clear_err +EXPORT_SYMBOL vmlinux 0x24fb43f3 simple_write_end +EXPORT_SYMBOL vmlinux 0x24fdac79 wake_bit_function +EXPORT_SYMBOL vmlinux 0x250113b4 memory_read_from_buffer +EXPORT_SYMBOL vmlinux 0x2528c667 call_usermodehelper_pipe +EXPORT_SYMBOL vmlinux 0x25383762 __netdev_alloc_page +EXPORT_SYMBOL vmlinux 0x25618c96 dm_dirty_log_type_register +EXPORT_SYMBOL vmlinux 0x256887e1 warn_slowpath +EXPORT_SYMBOL vmlinux 0x2578749f read_cache_page_async +EXPORT_SYMBOL vmlinux 0x25820c64 fs_overflowuid +EXPORT_SYMBOL vmlinux 0x258355b4 fb_find_best_mode +EXPORT_SYMBOL vmlinux 0x2596feff dmam_release_declared_memory +EXPORT_SYMBOL vmlinux 0x25b30970 nf_reinject +EXPORT_SYMBOL vmlinux 0x25d81960 posix_acl_equiv_mode +EXPORT_SYMBOL vmlinux 0x260c381a dmam_alloc_noncoherent +EXPORT_SYMBOL vmlinux 0x262c3f55 nf_getsockopt +EXPORT_SYMBOL vmlinux 0x26364de4 call_usermodehelper_setcleanup +EXPORT_SYMBOL vmlinux 0x264c3d7c journal_create +EXPORT_SYMBOL vmlinux 0x2658a956 seq_printf +EXPORT_SYMBOL vmlinux 0x26769412 tty_write_room +EXPORT_SYMBOL vmlinux 0x268cc6a2 sys_close +EXPORT_SYMBOL vmlinux 0x269a101d seq_putc +EXPORT_SYMBOL vmlinux 0x26aad335 tty_set_operations +EXPORT_SYMBOL vmlinux 0x26e76fb8 sysctl_udp_wmem_min +EXPORT_SYMBOL vmlinux 0x2703befc sb_has_dirty_inodes +EXPORT_SYMBOL vmlinux 0x2716e4e3 blk_alloc_queue +EXPORT_SYMBOL vmlinux 0x272d394e mtrr_del +EXPORT_SYMBOL vmlinux 0x272e7488 cond_resched_softirq +EXPORT_SYMBOL vmlinux 0x273f066e _write_unlock_irq +EXPORT_SYMBOL vmlinux 0x2783a253 sock_common_recvmsg +EXPORT_SYMBOL vmlinux 0x27864d57 memparse +EXPORT_SYMBOL vmlinux 0x2794a83d inode_set_bytes +EXPORT_SYMBOL vmlinux 0x27a9a7eb ns_to_timespec +EXPORT_SYMBOL vmlinux 0x27b460ea ___pskb_trim +EXPORT_SYMBOL vmlinux 0x27bbf221 disable_irq_nosync +EXPORT_SYMBOL vmlinux 0x27c61ece qdisc_put_stab +EXPORT_SYMBOL vmlinux 0x27c6b9db skb_over_panic +EXPORT_SYMBOL vmlinux 0x27d11324 tc_classify_compat +EXPORT_SYMBOL vmlinux 0x2802570e inet_sock_destruct +EXPORT_SYMBOL vmlinux 0x2825b5ae hci_send_acl +EXPORT_SYMBOL vmlinux 0x28597492 input_inject_event +EXPORT_SYMBOL vmlinux 0x285ac517 strict_strtoll +EXPORT_SYMBOL vmlinux 0x285d5ab1 scsi_prep_state_check +EXPORT_SYMBOL vmlinux 0x28a2ed02 scsi_build_sense_buffer +EXPORT_SYMBOL vmlinux 0x28b715a6 isapnp_cfg_end +EXPORT_SYMBOL vmlinux 0x28bd1a07 netdev_set_master +EXPORT_SYMBOL vmlinux 0x28dcf25c udplite_hash +EXPORT_SYMBOL vmlinux 0x29223100 tty_insert_flip_string_flags +EXPORT_SYMBOL vmlinux 0x29258143 kunmap +EXPORT_SYMBOL vmlinux 0x29325632 d_invalidate +EXPORT_SYMBOL vmlinux 0x294f2300 inet_release +EXPORT_SYMBOL vmlinux 0x29537c9e alloc_chrdev_region +EXPORT_SYMBOL vmlinux 0x296104d0 scsi_adjust_queue_depth +EXPORT_SYMBOL vmlinux 0x296555c4 skb_split +EXPORT_SYMBOL vmlinux 0x29b1c366 __sg_alloc_table +EXPORT_SYMBOL vmlinux 0x29b61dc4 vfs_quota_on +EXPORT_SYMBOL vmlinux 0x29bd4c46 __cap_init_eff_set +EXPORT_SYMBOL vmlinux 0x29d14c1b bio_get_nr_vecs +EXPORT_SYMBOL vmlinux 0x29f1bda4 aio_complete +EXPORT_SYMBOL vmlinux 0x2a01eb45 __skb_recv_datagram +EXPORT_SYMBOL vmlinux 0x2a048422 find_get_pages_tag +EXPORT_SYMBOL vmlinux 0x2a142a4e jbd2_journal_init_inode +EXPORT_SYMBOL vmlinux 0x2a156a25 check_disk_change +EXPORT_SYMBOL vmlinux 0x2a303d4d check_signature +EXPORT_SYMBOL vmlinux 0x2a71dec1 write_cache_pages +EXPORT_SYMBOL vmlinux 0x2a768fed xfrm_state_update +EXPORT_SYMBOL vmlinux 0x2a872717 log_wait_commit +EXPORT_SYMBOL vmlinux 0x2a9b7e26 i2c_smbus_read_byte_data +EXPORT_SYMBOL vmlinux 0x2aa0e4fc strncasecmp +EXPORT_SYMBOL vmlinux 0x2ae8cb33 sync_blockdev +EXPORT_SYMBOL vmlinux 0x2aeb2800 mempool_create_node +EXPORT_SYMBOL vmlinux 0x2af7a332 pcie_port_service_register +EXPORT_SYMBOL vmlinux 0x2b01f3d7 do_sync_write +EXPORT_SYMBOL vmlinux 0x2b0ba2b0 scsi_sense_desc_find +EXPORT_SYMBOL vmlinux 0x2b27c240 devm_iounmap +EXPORT_SYMBOL vmlinux 0x2b2dc6c4 page_readlink +EXPORT_SYMBOL vmlinux 0x2b380aff blk_queue_invalidate_tags +EXPORT_SYMBOL vmlinux 0x2b6aac8c tcp_sockets_allocated +EXPORT_SYMBOL vmlinux 0x2b71cb92 sk_stream_wait_memory +EXPORT_SYMBOL vmlinux 0x2b770958 tcp_v4_md5_do_del +EXPORT_SYMBOL vmlinux 0x2b83875a seq_read +EXPORT_SYMBOL vmlinux 0x2ba707a8 sysctl_tcp_low_latency +EXPORT_SYMBOL vmlinux 0x2bb0c322 alloc_netdev_mq +EXPORT_SYMBOL vmlinux 0x2bb55d6e acpi_remove_notify_handler +EXPORT_SYMBOL vmlinux 0x2bc95bd4 memset +EXPORT_SYMBOL vmlinux 0x2bd18001 bt_sock_recvmsg +EXPORT_SYMBOL vmlinux 0x2be09893 _atomic_dec_and_lock +EXPORT_SYMBOL vmlinux 0x2bf1ae12 ps2_handle_response +EXPORT_SYMBOL vmlinux 0x2bfeb410 acpi_get_handle +EXPORT_SYMBOL vmlinux 0x2c11364b sk_receive_skb +EXPORT_SYMBOL vmlinux 0x2c41a50d truncate_inode_pages +EXPORT_SYMBOL vmlinux 0x2c4bcfb0 qdisc_watchdog_init +EXPORT_SYMBOL vmlinux 0x2c55907f gnet_stats_copy_queue +EXPORT_SYMBOL vmlinux 0x2c5749e6 acpi_clear_gpe +EXPORT_SYMBOL vmlinux 0x2c80d9bd inet6_ioctl +EXPORT_SYMBOL vmlinux 0x2c814adf bdev_read_only +EXPORT_SYMBOL vmlinux 0x2c891788 generic_setlease +EXPORT_SYMBOL vmlinux 0x2c89bc37 request_key +EXPORT_SYMBOL vmlinux 0x2c8f5989 acpi_remove_address_space_handler +EXPORT_SYMBOL vmlinux 0x2c953fc9 free_buffer_head +EXPORT_SYMBOL vmlinux 0x2c9874fe ida_remove +EXPORT_SYMBOL vmlinux 0x2c9b319a kmalloc_caches +EXPORT_SYMBOL vmlinux 0x2ca5a6e2 hci_get_route +EXPORT_SYMBOL vmlinux 0x2cb6c072 sk_dst_check +EXPORT_SYMBOL vmlinux 0x2cc2d52d vcc_hash +EXPORT_SYMBOL vmlinux 0x2cd9e459 param_set_short +EXPORT_SYMBOL vmlinux 0x2cf190e3 request_irq +EXPORT_SYMBOL vmlinux 0x2cf1ce02 journal_check_used_features +EXPORT_SYMBOL vmlinux 0x2d066290 bio_integrity_endio +EXPORT_SYMBOL vmlinux 0x2d0935aa ps2_init +EXPORT_SYMBOL vmlinux 0x2d15389d tcp_getsockopt +EXPORT_SYMBOL vmlinux 0x2d443121 tcp_parse_options +EXPORT_SYMBOL vmlinux 0x2d5eb479 pnp_stop_dev +EXPORT_SYMBOL vmlinux 0x2d724104 bdi_register_dev +EXPORT_SYMBOL vmlinux 0x2d89342a scsi_show_sense_hdr +EXPORT_SYMBOL vmlinux 0x2d9e72c5 con_is_bound +EXPORT_SYMBOL vmlinux 0x2dd16564 arch_register_cpu +EXPORT_SYMBOL vmlinux 0x2de9f66f param_get_long +EXPORT_SYMBOL vmlinux 0x2dedc4c2 acpi_format_exception +EXPORT_SYMBOL vmlinux 0x2def7f76 rtc_cmos_write +EXPORT_SYMBOL vmlinux 0x2e0535b3 dcache_dir_lseek +EXPORT_SYMBOL vmlinux 0x2e269db3 sock_release +EXPORT_SYMBOL vmlinux 0x2e2ce9e0 sysctl_tcp_syncookies +EXPORT_SYMBOL vmlinux 0x2e4a39f8 sysctl_udp_mem +EXPORT_SYMBOL vmlinux 0x2e60bace memcpy +EXPORT_SYMBOL vmlinux 0x2e677d42 mb_cache_entry_insert +EXPORT_SYMBOL vmlinux 0x2e97859f rwsem_downgrade_wake +EXPORT_SYMBOL vmlinux 0x2ea96e68 hci_conn_switch_role +EXPORT_SYMBOL vmlinux 0x2eb9a0e8 _read_lock_irq +EXPORT_SYMBOL vmlinux 0x2ec8db52 inet_addr_type +EXPORT_SYMBOL vmlinux 0x2ee829cb xfrm6_prepare_output +EXPORT_SYMBOL vmlinux 0x2eee1a98 rtnl_set_sk_err +EXPORT_SYMBOL vmlinux 0x2f12233f __brelse +EXPORT_SYMBOL vmlinux 0x2f287f0d copy_to_user +EXPORT_SYMBOL vmlinux 0x2f2dac4f jbd2_journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0x2f42ffac task_pgrp_nr_ns +EXPORT_SYMBOL vmlinux 0x2fae80d8 phy_ethtool_sset +EXPORT_SYMBOL vmlinux 0x2fb48ffb eth_header +EXPORT_SYMBOL vmlinux 0x2fe5b660 drop_super +EXPORT_SYMBOL vmlinux 0x2ff7efaa tcf_hash_new_index +EXPORT_SYMBOL vmlinux 0x3000af19 bmap +EXPORT_SYMBOL vmlinux 0x30123eb5 icmpv6_statistics +EXPORT_SYMBOL vmlinux 0x302a741d keyring_clear +EXPORT_SYMBOL vmlinux 0x30622d21 neigh_seq_start +EXPORT_SYMBOL vmlinux 0x30b8d09e journal_get_undo_access +EXPORT_SYMBOL vmlinux 0x30da8da8 dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0x30e4de72 cap_netlink_recv +EXPORT_SYMBOL vmlinux 0x30e74134 tty_termios_copy_hw +EXPORT_SYMBOL vmlinux 0x30f77433 sock_i_ino +EXPORT_SYMBOL vmlinux 0x31028486 ilookup +EXPORT_SYMBOL vmlinux 0x310917fe sort +EXPORT_SYMBOL vmlinux 0x3145216f pci_dev_present +EXPORT_SYMBOL vmlinux 0x3147857d default_red +EXPORT_SYMBOL vmlinux 0x3147b4d8 dma_alloc_from_coherent +EXPORT_SYMBOL vmlinux 0x315296c4 ether_setup +EXPORT_SYMBOL vmlinux 0x3191f109 __krealloc +EXPORT_SYMBOL vmlinux 0x31bec1de pci_reenable_device +EXPORT_SYMBOL vmlinux 0x31c069eb dm_table_get_mode +EXPORT_SYMBOL vmlinux 0x31d3ab84 bio_integrity_advance +EXPORT_SYMBOL vmlinux 0x31e76b57 recalibrate_cpu_khz +EXPORT_SYMBOL vmlinux 0x31f5fae8 skb_prepare_seq_read +EXPORT_SYMBOL vmlinux 0x31faef26 tcp_disconnect +EXPORT_SYMBOL vmlinux 0x3217e285 remap_pfn_range +EXPORT_SYMBOL vmlinux 0x321c1923 register_netdevice +EXPORT_SYMBOL vmlinux 0x323b5062 acpi_bus_unregister_driver +EXPORT_SYMBOL vmlinux 0x327f7ded ps2_sendbyte +EXPORT_SYMBOL vmlinux 0x32c14efd xfrm_register_type +EXPORT_SYMBOL vmlinux 0x32d01fec acpi_attach_data +EXPORT_SYMBOL vmlinux 0x32ed920b i2c_master_send +EXPORT_SYMBOL vmlinux 0x33123c4d simple_fill_super +EXPORT_SYMBOL vmlinux 0x333567e0 bio_alloc_bioset +EXPORT_SYMBOL vmlinux 0x33510591 __kfree_skb +EXPORT_SYMBOL vmlinux 0x3360a963 param_set_ulong +EXPORT_SYMBOL vmlinux 0x337a37ca ip_route_output_key +EXPORT_SYMBOL vmlinux 0x33812f2f __dec_zone_page_state +EXPORT_SYMBOL vmlinux 0x3385bb1b kill_anon_super +EXPORT_SYMBOL vmlinux 0x3385c8cb per_cpu__this_cpu_off +EXPORT_SYMBOL vmlinux 0x33d507bd generic_unplug_device +EXPORT_SYMBOL vmlinux 0x33d92f9a prepare_to_wait +EXPORT_SYMBOL vmlinux 0x33f6d014 contig_page_data +EXPORT_SYMBOL vmlinux 0x3410688e pci_find_capability +EXPORT_SYMBOL vmlinux 0x3415cc28 xfrm_input_resume +EXPORT_SYMBOL vmlinux 0x3417a92c pid_task +EXPORT_SYMBOL vmlinux 0x342f60fe apm_info +EXPORT_SYMBOL vmlinux 0x342fb37c __serio_register_port +EXPORT_SYMBOL vmlinux 0x343a3232 genl_register_ops +EXPORT_SYMBOL vmlinux 0x34600462 genl_sock +EXPORT_SYMBOL vmlinux 0x34908c14 print_hex_dump_bytes +EXPORT_SYMBOL vmlinux 0x349cba85 strchr +EXPORT_SYMBOL vmlinux 0x34a07262 unregister_8022_client +EXPORT_SYMBOL vmlinux 0x34cbcfb4 mark_buffer_dirty_inode +EXPORT_SYMBOL vmlinux 0x34d7bce0 xfrm_state_unregister_afinfo +EXPORT_SYMBOL vmlinux 0x34e4648f isapnp_protocol +EXPORT_SYMBOL vmlinux 0x34ed7cc9 pci_unmap_rom +EXPORT_SYMBOL vmlinux 0x35aa055e kernel_sendpage +EXPORT_SYMBOL vmlinux 0x35b70c8c bh_uptodate_or_lock +EXPORT_SYMBOL vmlinux 0x35c05887 dm_register_target +EXPORT_SYMBOL vmlinux 0x35c2ba9e refrigerator +EXPORT_SYMBOL vmlinux 0x35eb8a4b tcp_ioctl +EXPORT_SYMBOL vmlinux 0x35f0faa2 acpi_evaluate_object +EXPORT_SYMBOL vmlinux 0x35f7e154 mmc_remove_host +EXPORT_SYMBOL vmlinux 0x36009d96 unregister_netdev +EXPORT_SYMBOL vmlinux 0x360b1afe probe_irq_mask +EXPORT_SYMBOL vmlinux 0x361c4219 bt_accept_enqueue +EXPORT_SYMBOL vmlinux 0x3635d417 kmem_cache_create +EXPORT_SYMBOL vmlinux 0x363ad247 cap_set_effective +EXPORT_SYMBOL vmlinux 0x364b8729 bio_alloc +EXPORT_SYMBOL vmlinux 0x3656bf5a lock_kernel +EXPORT_SYMBOL vmlinux 0x365d5f70 tcf_em_tree_validate +EXPORT_SYMBOL vmlinux 0x3662a181 __alloc_skb +EXPORT_SYMBOL vmlinux 0x36ad57b3 put_disk +EXPORT_SYMBOL vmlinux 0x36c5d209 d_find_alias +EXPORT_SYMBOL vmlinux 0x36f0dc02 nobh_write_end +EXPORT_SYMBOL vmlinux 0x3725ffc5 inet_frag_kill +EXPORT_SYMBOL vmlinux 0x3744cf36 vmalloc_to_pfn +EXPORT_SYMBOL vmlinux 0x374ed073 scnprintf +EXPORT_SYMBOL vmlinux 0x377e2b75 iget_failed +EXPORT_SYMBOL vmlinux 0x37894ec0 netdev_rx_csum_fault +EXPORT_SYMBOL vmlinux 0x3789aca6 set_user_nice +EXPORT_SYMBOL vmlinux 0x379d65f5 gen_pool_alloc +EXPORT_SYMBOL vmlinux 0x37afe3a2 per_cpu__current_task +EXPORT_SYMBOL vmlinux 0x37befc70 jiffies_to_msecs +EXPORT_SYMBOL vmlinux 0x37ca2c4a vm_insert_page +EXPORT_SYMBOL vmlinux 0x37e74642 get_jiffies_64 +EXPORT_SYMBOL vmlinux 0x38116f01 sock_no_shutdown +EXPORT_SYMBOL vmlinux 0x38203ca1 __init_rwsem +EXPORT_SYMBOL vmlinux 0x385f3848 shrink_dcache_sb +EXPORT_SYMBOL vmlinux 0x387c0967 vfs_lstat +EXPORT_SYMBOL vmlinux 0x387e75ca bio_init +EXPORT_SYMBOL vmlinux 0x388f9128 xfrm_state_walk_done +EXPORT_SYMBOL vmlinux 0x38b129be xrlim_allow +EXPORT_SYMBOL vmlinux 0x38b92846 llc_remove_pack +EXPORT_SYMBOL vmlinux 0x38ea99cd dma_async_memcpy_buf_to_pg +EXPORT_SYMBOL vmlinux 0x392fe982 kill_pgrp +EXPORT_SYMBOL vmlinux 0x3960d9bb scsi_unblock_requests +EXPORT_SYMBOL vmlinux 0x3980aac1 unregister_reboot_notifier +EXPORT_SYMBOL vmlinux 0x399f8bce pci_scan_bridge +EXPORT_SYMBOL vmlinux 0x39a99af9 sock_alloc_send_skb +EXPORT_SYMBOL vmlinux 0x39c645a2 schedule_delayed_work_on +EXPORT_SYMBOL vmlinux 0x39cf6e5e cdev_alloc +EXPORT_SYMBOL vmlinux 0x39dcf80c i2c_smbus_write_byte_data +EXPORT_SYMBOL vmlinux 0x3a06de33 bt_sock_link +EXPORT_SYMBOL vmlinux 0x3a18dae6 grab_cache_page_nowait +EXPORT_SYMBOL vmlinux 0x3a2204c6 security_netlink_recv +EXPORT_SYMBOL vmlinux 0x3a9b6fb9 blk_unregister_region +EXPORT_SYMBOL vmlinux 0x3aa1dbcf _spin_unlock_bh +EXPORT_SYMBOL vmlinux 0x3aa7b3ad journal_ack_err +EXPORT_SYMBOL vmlinux 0x3ad063a6 unregister_sysrq_key +EXPORT_SYMBOL vmlinux 0x3af98f9e ioremap_nocache +EXPORT_SYMBOL vmlinux 0x3b3016d3 cpufreq_unregister_notifier +EXPORT_SYMBOL vmlinux 0x3b344468 phy_ethtool_gset +EXPORT_SYMBOL vmlinux 0x3b3bc00b sock_init_data +EXPORT_SYMBOL vmlinux 0x3b93fb5f __pskb_pull_tail +EXPORT_SYMBOL vmlinux 0x3b94fba8 dev_mc_sync +EXPORT_SYMBOL vmlinux 0x3ba237c2 mmc_release_host +EXPORT_SYMBOL vmlinux 0x3bd1b1f6 msecs_to_jiffies +EXPORT_SYMBOL vmlinux 0x3c0d7a79 scsi_put_command +EXPORT_SYMBOL vmlinux 0x3c21a2ed jbd2_journal_start_commit +EXPORT_SYMBOL vmlinux 0x3c2c5af5 sprintf +EXPORT_SYMBOL vmlinux 0x3c7227bf complete_all +EXPORT_SYMBOL vmlinux 0x3c9d1211 string_get_size +EXPORT_SYMBOL vmlinux 0x3ca35086 inet_sendmsg +EXPORT_SYMBOL vmlinux 0x3cb17f90 sock_get_timestamp +EXPORT_SYMBOL vmlinux 0x3cb8a495 param_get_string +EXPORT_SYMBOL vmlinux 0x3cc0a3bb xfrm_spd_getinfo +EXPORT_SYMBOL vmlinux 0x3cda7be8 input_get_keycode +EXPORT_SYMBOL vmlinux 0x3ce4ca6f disable_irq +EXPORT_SYMBOL vmlinux 0x3d042018 fifo_set_limit +EXPORT_SYMBOL vmlinux 0x3d07fa95 ethtool_op_set_sg +EXPORT_SYMBOL vmlinux 0x3d2af2a3 x86_dma_fallback_dev +EXPORT_SYMBOL vmlinux 0x3d2fe042 phy_enable_interrupts +EXPORT_SYMBOL vmlinux 0x3d4cbbcc nf_log_packet +EXPORT_SYMBOL vmlinux 0x3da171f9 pci_mem_start +EXPORT_SYMBOL vmlinux 0x3da5eb6d kfifo_alloc +EXPORT_SYMBOL vmlinux 0x3da619b4 __blk_run_queue +EXPORT_SYMBOL vmlinux 0x3db3b969 pci_set_dma_max_seg_size +EXPORT_SYMBOL vmlinux 0x3dd4e796 serio_reconnect +EXPORT_SYMBOL vmlinux 0x3df40020 locks_init_lock +EXPORT_SYMBOL vmlinux 0x3e14a41d bio_kmalloc +EXPORT_SYMBOL vmlinux 0x3e1f073d wait_for_completion_timeout +EXPORT_SYMBOL vmlinux 0x3e219de6 try_wait_for_completion +EXPORT_SYMBOL vmlinux 0x3e2ae3a8 acpi_release_global_lock +EXPORT_SYMBOL vmlinux 0x3e383385 nf_hooks +EXPORT_SYMBOL vmlinux 0x3e45e9ff register_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x3e540e63 fb_pan_display +EXPORT_SYMBOL vmlinux 0x3e9cb7a5 d_delete +EXPORT_SYMBOL vmlinux 0x3ed63055 zlib_inflateReset +EXPORT_SYMBOL vmlinux 0x3ee459f9 xfrm_state_insert +EXPORT_SYMBOL vmlinux 0x3ee562fb pnpbios_protocol +EXPORT_SYMBOL vmlinux 0x3f0546a8 ioread32_rep +EXPORT_SYMBOL vmlinux 0x3f1899f1 up +EXPORT_SYMBOL vmlinux 0x3f35f1dc __scsi_device_lookup +EXPORT_SYMBOL vmlinux 0x3f39b162 up_write +EXPORT_SYMBOL vmlinux 0x3f4547a7 put_unused_fd +EXPORT_SYMBOL vmlinux 0x3f62ecfb bd_set_size +EXPORT_SYMBOL vmlinux 0x3f65f167 journal_start +EXPORT_SYMBOL vmlinux 0x3ff62317 local_bh_disable +EXPORT_SYMBOL vmlinux 0x40422fa5 jbd2_journal_get_undo_access +EXPORT_SYMBOL vmlinux 0x4059792f print_hex_dump +EXPORT_SYMBOL vmlinux 0x405c1144 get_seconds +EXPORT_SYMBOL vmlinux 0x4086ad07 pci_disable_device +EXPORT_SYMBOL vmlinux 0x409873e3 tty_termios_baud_rate +EXPORT_SYMBOL vmlinux 0x40c89d46 acpi_get_table_by_index +EXPORT_SYMBOL vmlinux 0x40ca1314 simple_release_fs +EXPORT_SYMBOL vmlinux 0x40ff0e3a inet_csk_init_xmit_timers +EXPORT_SYMBOL vmlinux 0x4108e69a fb_match_mode +EXPORT_SYMBOL vmlinux 0x4117afb4 pci_find_bus +EXPORT_SYMBOL vmlinux 0x412f507c unlock_rename +EXPORT_SYMBOL vmlinux 0x41482d8b strndup_user +EXPORT_SYMBOL vmlinux 0x416983d9 netdev_fix_features +EXPORT_SYMBOL vmlinux 0x417430d3 sk_filter +EXPORT_SYMBOL vmlinux 0x4185cf4b radix_tree_lookup_slot +EXPORT_SYMBOL vmlinux 0x41885662 thermal_zone_bind_cooling_device +EXPORT_SYMBOL vmlinux 0x4188d439 neigh_rand_reach_time +EXPORT_SYMBOL vmlinux 0x41993475 hci_register_cb +EXPORT_SYMBOL vmlinux 0x41a9c68d _spin_trylock_bh +EXPORT_SYMBOL vmlinux 0x41c3a43c register_8022_client +EXPORT_SYMBOL vmlinux 0x41c845bc blk_alloc_queue_node +EXPORT_SYMBOL vmlinux 0x41e0d832 kobject_get +EXPORT_SYMBOL vmlinux 0x41fa4ec5 bitmap_start_sync +EXPORT_SYMBOL vmlinux 0x4211c3c1 zlib_inflateInit2 +EXPORT_SYMBOL vmlinux 0x42224298 sscanf +EXPORT_SYMBOL vmlinux 0x422c05d0 acpi_get_data +EXPORT_SYMBOL vmlinux 0x42313f92 kernel_getsockname +EXPORT_SYMBOL vmlinux 0x423cffba blk_rq_unmap_user +EXPORT_SYMBOL vmlinux 0x4260a094 fb_set_var +EXPORT_SYMBOL vmlinux 0x426a787d md_write_end +EXPORT_SYMBOL vmlinux 0x4292364c schedule +EXPORT_SYMBOL vmlinux 0x4302d0eb free_pages +EXPORT_SYMBOL vmlinux 0x4321e9e9 get_sb_single +EXPORT_SYMBOL vmlinux 0x43385ad9 acpi_pci_unregister_driver +EXPORT_SYMBOL vmlinux 0x434fa55c release_console_sem +EXPORT_SYMBOL vmlinux 0x435b566d _spin_unlock +EXPORT_SYMBOL vmlinux 0x436c2179 iowrite32 +EXPORT_SYMBOL vmlinux 0x43b40de7 kunmap_atomic +EXPORT_SYMBOL vmlinux 0x43c48543 generic_read_dir +EXPORT_SYMBOL vmlinux 0x43c66a24 generic_file_aio_write_nolock +EXPORT_SYMBOL vmlinux 0x44161c19 unregister_shrinker +EXPORT_SYMBOL vmlinux 0x441d77bd i2c_transfer +EXPORT_SYMBOL vmlinux 0x44314efb radix_tree_gang_lookup_tag_slot +EXPORT_SYMBOL vmlinux 0x444298ae tcp_init_xmit_timers +EXPORT_SYMBOL vmlinux 0x444779c4 nla_find +EXPORT_SYMBOL vmlinux 0x447e7afe pci_request_regions +EXPORT_SYMBOL vmlinux 0x44aaf30f tsc_khz +EXPORT_SYMBOL vmlinux 0x44ab984a ip_mc_dec_group +EXPORT_SYMBOL vmlinux 0x44b09844 mark_page_accessed +EXPORT_SYMBOL vmlinux 0x44b911c3 rb_replace_node +EXPORT_SYMBOL vmlinux 0x44e9a829 match_token +EXPORT_SYMBOL vmlinux 0x44edde89 journal_restart +EXPORT_SYMBOL vmlinux 0x44f21bea idr_for_each +EXPORT_SYMBOL vmlinux 0x450eb6bf acpi_processor_notify_smm +EXPORT_SYMBOL vmlinux 0x45364c89 filp_close +EXPORT_SYMBOL vmlinux 0x4550ba8a register_cpu_notifier +EXPORT_SYMBOL vmlinux 0x455fd57d acpi_set_register +EXPORT_SYMBOL vmlinux 0x456c90f5 posix_lock_file +EXPORT_SYMBOL vmlinux 0x457d6a57 tcp_alloc_md5sig_pool +EXPORT_SYMBOL vmlinux 0x45bb123e try_to_del_timer_sync +EXPORT_SYMBOL vmlinux 0x45c5a5a8 ip6_route_output +EXPORT_SYMBOL vmlinux 0x45c9e83f sock_create +EXPORT_SYMBOL vmlinux 0x45d11c43 down_interruptible +EXPORT_SYMBOL vmlinux 0x45d6ae85 generic_show_options +EXPORT_SYMBOL vmlinux 0x45d766a4 kset_unregister +EXPORT_SYMBOL vmlinux 0x45e00832 __sk_dst_check +EXPORT_SYMBOL vmlinux 0x45e38dca dmam_alloc_coherent +EXPORT_SYMBOL vmlinux 0x462a2e75 match_strlcpy +EXPORT_SYMBOL vmlinux 0x462f6fab sget +EXPORT_SYMBOL vmlinux 0x463de5f0 phy_sanitize_settings +EXPORT_SYMBOL vmlinux 0x464635c7 phy_register_fixup_for_id +EXPORT_SYMBOL vmlinux 0x466c14a7 __delay +EXPORT_SYMBOL vmlinux 0x46838172 unregister_framebuffer +EXPORT_SYMBOL vmlinux 0x469bbb39 __elv_add_request +EXPORT_SYMBOL vmlinux 0x46a07879 in_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0x46abe180 scsi_block_when_processing_errors +EXPORT_SYMBOL vmlinux 0x46ac4920 kernel_sendmsg +EXPORT_SYMBOL vmlinux 0x46c54d8c mmc_wait_for_req +EXPORT_SYMBOL vmlinux 0x46d07033 tty_unregister_driver +EXPORT_SYMBOL vmlinux 0x46fbd6a0 acpi_unlock_ac_dir +EXPORT_SYMBOL vmlinux 0x47163cc0 ppp_output_wakeup +EXPORT_SYMBOL vmlinux 0x472d2a9a radix_tree_lookup +EXPORT_SYMBOL vmlinux 0x4730246f inet_ioctl +EXPORT_SYMBOL vmlinux 0x474c7583 scm_detach_fds +EXPORT_SYMBOL vmlinux 0x475100c2 inet_get_local_port_range +EXPORT_SYMBOL vmlinux 0x475f010b acpi_purge_cached_objects +EXPORT_SYMBOL vmlinux 0x47767f88 mapping_tagged +EXPORT_SYMBOL vmlinux 0x478021d5 bio_sector_offset +EXPORT_SYMBOL vmlinux 0x478d10b2 ht_destroy_irq +EXPORT_SYMBOL vmlinux 0x47939e0d __tasklet_hi_schedule +EXPORT_SYMBOL vmlinux 0x479c3c86 find_next_zero_bit +EXPORT_SYMBOL vmlinux 0x479e9579 scsi_target_quiesce +EXPORT_SYMBOL vmlinux 0x47c62d70 xfrm_policy_flush +EXPORT_SYMBOL vmlinux 0x47e45d9e vfs_get_dqblk +EXPORT_SYMBOL vmlinux 0x4816bc7f pci_set_dma_mask +EXPORT_SYMBOL vmlinux 0x481cb9ab acpi_enter_sleep_state_prep +EXPORT_SYMBOL vmlinux 0x48216b0a pci_get_subsys +EXPORT_SYMBOL vmlinux 0x4859b8bb rtc_year_days +EXPORT_SYMBOL vmlinux 0x485ab9df skb_dequeue_tail +EXPORT_SYMBOL vmlinux 0x486b6407 hweight64 +EXPORT_SYMBOL vmlinux 0x4893aebb pci_dev_get +EXPORT_SYMBOL vmlinux 0x48a69f57 module_refcount +EXPORT_SYMBOL vmlinux 0x48b2aa4d free_task +EXPORT_SYMBOL vmlinux 0x48b3d616 jbd2_journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0x48e6348e pnp_start_dev +EXPORT_SYMBOL vmlinux 0x48f145d8 pagecache_write_end +EXPORT_SYMBOL vmlinux 0x48fb9ec6 inode_sub_bytes +EXPORT_SYMBOL vmlinux 0x4910169e vcc_release_async +EXPORT_SYMBOL vmlinux 0x492328a3 netpoll_print_options +EXPORT_SYMBOL vmlinux 0x49293b2e unregister_filesystem +EXPORT_SYMBOL vmlinux 0x493489eb bitmap_endwrite +EXPORT_SYMBOL vmlinux 0x493e25e1 udp_hash +EXPORT_SYMBOL vmlinux 0x49603fb8 security_sb_copy_data +EXPORT_SYMBOL vmlinux 0x49815ea1 blk_queue_max_sectors +EXPORT_SYMBOL vmlinux 0x498eca1a uart_add_one_port +EXPORT_SYMBOL vmlinux 0x4991a053 kmem_cache_name +EXPORT_SYMBOL vmlinux 0x49a1a2c1 current_fs_time +EXPORT_SYMBOL vmlinux 0x49da9a9a _read_unlock_bh +EXPORT_SYMBOL vmlinux 0x4a358252 __bitmap_subset +EXPORT_SYMBOL vmlinux 0x4a38c4a2 dev_change_flags +EXPORT_SYMBOL vmlinux 0x4a8d8dc4 pci_set_power_state +EXPORT_SYMBOL vmlinux 0x4a971ec7 radix_tree_delete +EXPORT_SYMBOL vmlinux 0x4ab287d5 jbd2_journal_check_available_features +EXPORT_SYMBOL vmlinux 0x4acfab03 mmc_detect_change +EXPORT_SYMBOL vmlinux 0x4aea0700 vcc_insert_socket +EXPORT_SYMBOL vmlinux 0x4afe9a77 scsi_partsize +EXPORT_SYMBOL vmlinux 0x4b02a44b input_unregister_handler +EXPORT_SYMBOL vmlinux 0x4b07e779 _spin_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x4b082ef9 pci_save_state +EXPORT_SYMBOL vmlinux 0x4b2f14b4 jiffies_to_timespec +EXPORT_SYMBOL vmlinux 0x4b332060 pci_bus_add_devices +EXPORT_SYMBOL vmlinux 0x4b34fbf5 block_all_signals +EXPORT_SYMBOL vmlinux 0x4b3e1f5c kernel_connect +EXPORT_SYMBOL vmlinux 0x4b4b20ef pci_wake_from_d3 +EXPORT_SYMBOL vmlinux 0x4b77c0d1 tcf_hash_insert +EXPORT_SYMBOL vmlinux 0x4b79a5e9 bio_pair_release +EXPORT_SYMBOL vmlinux 0x4bbc3e5f pm_flags +EXPORT_SYMBOL vmlinux 0x4bf9d2f4 dev_add_pack +EXPORT_SYMBOL vmlinux 0x4bfad961 xfrm_unregister_type +EXPORT_SYMBOL vmlinux 0x4bfddb44 pci_clear_mwi +EXPORT_SYMBOL vmlinux 0x4c1182cb bitmap_scnprintf +EXPORT_SYMBOL vmlinux 0x4c719e21 register_snap_client +EXPORT_SYMBOL vmlinux 0x4c75675f backlight_device_register +EXPORT_SYMBOL vmlinux 0x4c77dbac vfs_path_lookup +EXPORT_SYMBOL vmlinux 0x4cbbd171 __bitmap_weight +EXPORT_SYMBOL vmlinux 0x4cbf7ff9 seq_puts +EXPORT_SYMBOL vmlinux 0x4cd0f203 try_to_release_page +EXPORT_SYMBOL vmlinux 0x4cd21a88 dev_close +EXPORT_SYMBOL vmlinux 0x4cf369a8 scsi_host_lookup +EXPORT_SYMBOL vmlinux 0x4d07ea80 give_up_console +EXPORT_SYMBOL vmlinux 0x4d2dc830 acpi_get_object_info +EXPORT_SYMBOL vmlinux 0x4d3c153f sigprocmask +EXPORT_SYMBOL vmlinux 0x4d86da66 nf_unregister_sockopt +EXPORT_SYMBOL vmlinux 0x4d91c4c7 llc_add_pack +EXPORT_SYMBOL vmlinux 0x4d9efb78 key_task_permission +EXPORT_SYMBOL vmlinux 0x4dc918c8 blk_init_queue +EXPORT_SYMBOL vmlinux 0x4dd295fe rfkill_register +EXPORT_SYMBOL vmlinux 0x4ddc4b9f utf8_mbtowc +EXPORT_SYMBOL vmlinux 0x4de05bc1 pci_pme_active +EXPORT_SYMBOL vmlinux 0x4df119fa __bitmap_parse +EXPORT_SYMBOL vmlinux 0x4e100f60 _spin_unlock_irq +EXPORT_SYMBOL vmlinux 0x4e1aecec ip_mc_inc_group +EXPORT_SYMBOL vmlinux 0x4e3567f7 match_int +EXPORT_SYMBOL vmlinux 0x4e4dce74 blk_register_region +EXPORT_SYMBOL vmlinux 0x4e5c8ed2 page_symlink +EXPORT_SYMBOL vmlinux 0x4e67177a d_add_ci +EXPORT_SYMBOL vmlinux 0x4e6e8ea7 fg_console +EXPORT_SYMBOL vmlinux 0x4e76d7ea hub_port_logical_disconnect +EXPORT_SYMBOL vmlinux 0x4e7aca99 bio_map_user +EXPORT_SYMBOL vmlinux 0x4e830a3e strnicmp +EXPORT_SYMBOL vmlinux 0x4eb7140e dquot_transfer +EXPORT_SYMBOL vmlinux 0x4ee0a5fb tty_unregister_device +EXPORT_SYMBOL vmlinux 0x4f476e96 init_cdrom_command +EXPORT_SYMBOL vmlinux 0x4f5438c1 idle_halt +EXPORT_SYMBOL vmlinux 0x4f635988 sock_common_getsockopt +EXPORT_SYMBOL vmlinux 0x4faebffa __nla_put_nohdr +EXPORT_SYMBOL vmlinux 0x4fdee897 i8042_command +EXPORT_SYMBOL vmlinux 0x4fffe72b con_set_default_unimap +EXPORT_SYMBOL vmlinux 0x500bd210 neigh_connected_output +EXPORT_SYMBOL vmlinux 0x500c8a07 ndisc_mc_map +EXPORT_SYMBOL vmlinux 0x501dd595 jbd2_journal_restart +EXPORT_SYMBOL vmlinux 0x50211ee3 tcp_free_md5sig_pool +EXPORT_SYMBOL vmlinux 0x5024a468 tcp_v4_md5_lookup +EXPORT_SYMBOL vmlinux 0x5028e2ad i2c_put_adapter +EXPORT_SYMBOL vmlinux 0x50368c3c invalidate_bdev +EXPORT_SYMBOL vmlinux 0x504ba23e dm_unregister_target +EXPORT_SYMBOL vmlinux 0x504fcd6f i2c_smbus_read_word_data +EXPORT_SYMBOL vmlinux 0x50a7b4ad input_open_device +EXPORT_SYMBOL vmlinux 0x50dc978b ppp_channel_index +EXPORT_SYMBOL vmlinux 0x510a36a8 neigh_event_ns +EXPORT_SYMBOL vmlinux 0x5118c382 secure_dccp_sequence_number +EXPORT_SYMBOL vmlinux 0x5152e605 memcmp +EXPORT_SYMBOL vmlinux 0x517b1692 remap_vmalloc_range +EXPORT_SYMBOL vmlinux 0x518eb764 per_cpu__cpu_number +EXPORT_SYMBOL vmlinux 0x51ba507f end_request +EXPORT_SYMBOL vmlinux 0x51d12d4e acpi_pci_disabled +EXPORT_SYMBOL vmlinux 0x51d7a776 acpi_detach_data +EXPORT_SYMBOL vmlinux 0x51db3ed4 dev_set_allmulti +EXPORT_SYMBOL vmlinux 0x51dce73b xfrm_state_walk_init +EXPORT_SYMBOL vmlinux 0x51ef33b8 kstrndup +EXPORT_SYMBOL vmlinux 0x52026cdf security_sb_parse_opts_str +EXPORT_SYMBOL vmlinux 0x520f0dbd skb_recv_datagram +EXPORT_SYMBOL vmlinux 0x5211e7de vfs_symlink +EXPORT_SYMBOL vmlinux 0x52205f37 input_event +EXPORT_SYMBOL vmlinux 0x5224e3ca jbd2_journal_unlock_updates +EXPORT_SYMBOL vmlinux 0x5226e668 dev_set_promiscuity +EXPORT_SYMBOL vmlinux 0x5242e20c dget_locked +EXPORT_SYMBOL vmlinux 0x526bce23 blk_plug_device_unlocked +EXPORT_SYMBOL vmlinux 0x528367cc i2c_verify_client +EXPORT_SYMBOL vmlinux 0x528c709d simple_read_from_buffer +EXPORT_SYMBOL vmlinux 0x529ec5a6 proc_dointvec_ms_jiffies +EXPORT_SYMBOL vmlinux 0x52a58c24 ifla_policy +EXPORT_SYMBOL vmlinux 0x52c94c30 try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x52cc2e74 llc_set_station_handler +EXPORT_SYMBOL vmlinux 0x52d7b2fd llc_sap_list +EXPORT_SYMBOL vmlinux 0x52e24296 key_validate +EXPORT_SYMBOL vmlinux 0x52efd338 framebuffer_alloc +EXPORT_SYMBOL vmlinux 0x530b1e98 pm_suspend +EXPORT_SYMBOL vmlinux 0x530ce749 simple_statfs +EXPORT_SYMBOL vmlinux 0x531b604e __virt_addr_valid +EXPORT_SYMBOL vmlinux 0x532f2924 param_get_byte +EXPORT_SYMBOL vmlinux 0x53326531 mempool_alloc_pages +EXPORT_SYMBOL vmlinux 0x5374393c inet6_add_protocol +EXPORT_SYMBOL vmlinux 0x538383c0 unregister_inet6addr_notifier +EXPORT_SYMBOL vmlinux 0x53c0767c sk_chk_filter +EXPORT_SYMBOL vmlinux 0x541cfd7d md_wait_for_blocked_rdev +EXPORT_SYMBOL vmlinux 0x5429029e pci_release_selected_regions +EXPORT_SYMBOL vmlinux 0x54290dc9 nla_validate +EXPORT_SYMBOL vmlinux 0x5436acc2 __ht_create_irq +EXPORT_SYMBOL vmlinux 0x543affb5 per_cpu__kstat +EXPORT_SYMBOL vmlinux 0x543f9bff pci_bus_assign_resources +EXPORT_SYMBOL vmlinux 0x5447bd47 netlink_unicast +EXPORT_SYMBOL vmlinux 0x5466b2c5 xfrm_bundle_ok +EXPORT_SYMBOL vmlinux 0x5487cc3a dma_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0x54895032 ethtool_op_get_flags +EXPORT_SYMBOL vmlinux 0x548ba347 kernel_getsockopt +EXPORT_SYMBOL vmlinux 0x54935666 acpi_os_read_port +EXPORT_SYMBOL vmlinux 0x54b31c82 dentry_unhash +EXPORT_SYMBOL vmlinux 0x54b81541 init_timer_deferrable +EXPORT_SYMBOL vmlinux 0x54c2f6d0 end_buffer_read_sync +EXPORT_SYMBOL vmlinux 0x54cb0bfa __find_get_block +EXPORT_SYMBOL vmlinux 0x54ce5cd3 phy_mii_ioctl +EXPORT_SYMBOL vmlinux 0x54d4f1a7 clear_inode +EXPORT_SYMBOL vmlinux 0x54e6fcdd net_enable_timestamp +EXPORT_SYMBOL vmlinux 0x552ddb9a tcp_check_req +EXPORT_SYMBOL vmlinux 0x553f9dd3 down_read_trylock +EXPORT_SYMBOL vmlinux 0x558005cb uart_remove_one_port +EXPORT_SYMBOL vmlinux 0x558098c4 generic_fillattr +EXPORT_SYMBOL vmlinux 0x5594be03 bitmap_remap +EXPORT_SYMBOL vmlinux 0x55facd3d clear_bdi_congested +EXPORT_SYMBOL vmlinux 0x5600904f fb_get_color_depth +EXPORT_SYMBOL vmlinux 0x5614b010 xfrm_policy_walk_done +EXPORT_SYMBOL vmlinux 0x5635a60a vmalloc_user +EXPORT_SYMBOL vmlinux 0x56430e5e lookup_one_len +EXPORT_SYMBOL vmlinux 0x5644c0ca vfs_permission +EXPORT_SYMBOL vmlinux 0x56b8c3c5 __inc_zone_page_state +EXPORT_SYMBOL vmlinux 0x56bd0249 tcp_make_synack +EXPORT_SYMBOL vmlinux 0x56c0e675 blk_stop_queue +EXPORT_SYMBOL vmlinux 0x56c4b428 scsi_setup_fs_cmnd +EXPORT_SYMBOL vmlinux 0x56c8799d scsi_kunmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x56dbb8d4 inet_add_protocol +EXPORT_SYMBOL vmlinux 0x56e9af2d freeze_bdev +EXPORT_SYMBOL vmlinux 0x56eac227 __sk_mem_reclaim +EXPORT_SYMBOL vmlinux 0x56f494e0 smp_call_function +EXPORT_SYMBOL vmlinux 0x570e1089 tcf_action_dump_1 +EXPORT_SYMBOL vmlinux 0x572e85d4 blk_lookup_devt +EXPORT_SYMBOL vmlinux 0x577cc638 mutex_unlock +EXPORT_SYMBOL vmlinux 0x57a6504e vsnprintf +EXPORT_SYMBOL vmlinux 0x57d54df1 lock_may_write +EXPORT_SYMBOL vmlinux 0x57d7e41f may_umount +EXPORT_SYMBOL vmlinux 0x580677b4 pci_get_device +EXPORT_SYMBOL vmlinux 0x58139840 eth_header_cache +EXPORT_SYMBOL vmlinux 0x582617a6 ppp_input_error +EXPORT_SYMBOL vmlinux 0x5838f6c9 rtc_valid_tm +EXPORT_SYMBOL vmlinux 0x584738f9 rdmsr_safe_on_cpu +EXPORT_SYMBOL vmlinux 0x5857b225 ioread16_rep +EXPORT_SYMBOL vmlinux 0x58853cac set_blocksize +EXPORT_SYMBOL vmlinux 0x589f2bd3 scsi_host_put +EXPORT_SYMBOL vmlinux 0x58a2490e rtnl_notify +EXPORT_SYMBOL vmlinux 0x58a5bf26 tcp_md5_hash_key +EXPORT_SYMBOL vmlinux 0x58d3c2c3 fasync_helper +EXPORT_SYMBOL vmlinux 0x58d4475e jbd2_journal_flush +EXPORT_SYMBOL vmlinux 0x58df3602 open_by_devnum +EXPORT_SYMBOL vmlinux 0x58ebbb76 dquot_commit_info +EXPORT_SYMBOL vmlinux 0x58fef6f8 ist_info +EXPORT_SYMBOL vmlinux 0x5906f556 kernel_bind +EXPORT_SYMBOL vmlinux 0x590b1fb1 security_sb_set_mnt_opts +EXPORT_SYMBOL vmlinux 0x59128910 skb_dma_map +EXPORT_SYMBOL vmlinux 0x5934392b fb_register_client +EXPORT_SYMBOL vmlinux 0x5948e139 scsi_eh_prep_cmnd +EXPORT_SYMBOL vmlinux 0x594bf15b ioport_map +EXPORT_SYMBOL vmlinux 0x5952beff inode_needs_sync +EXPORT_SYMBOL vmlinux 0x5964c4ec tcp_recvmsg +EXPORT_SYMBOL vmlinux 0x59706f79 nf_log_unregister_pf +EXPORT_SYMBOL vmlinux 0x597d0ca3 dquot_release +EXPORT_SYMBOL vmlinux 0x5984e4fd acpi_processor_register_performance +EXPORT_SYMBOL vmlinux 0x59865431 inet_sk_rebuild_header +EXPORT_SYMBOL vmlinux 0x5996dac7 generic_permission +EXPORT_SYMBOL vmlinux 0x59d696b6 register_module_notifier +EXPORT_SYMBOL vmlinux 0x59d8223a ioport_resource +EXPORT_SYMBOL vmlinux 0x59dcc412 pci_unregister_driver +EXPORT_SYMBOL vmlinux 0x59ea5fb9 bt_sock_wait_state +EXPORT_SYMBOL vmlinux 0x59f66f69 xfrm_unregister_km +EXPORT_SYMBOL vmlinux 0x5a03fda2 destroy_EII_client +EXPORT_SYMBOL vmlinux 0x5a12892e kobject_put +EXPORT_SYMBOL vmlinux 0x5a4896a8 __put_user_2 +EXPORT_SYMBOL vmlinux 0x5a4d5b18 dma_async_client_unregister +EXPORT_SYMBOL vmlinux 0x5a6b1f2b skb_copy +EXPORT_SYMBOL vmlinux 0x5a71ce50 generic_file_splice_read +EXPORT_SYMBOL vmlinux 0x5a744b86 netlink_set_nonroot +EXPORT_SYMBOL vmlinux 0x5a7cda5d bio_copy_user +EXPORT_SYMBOL vmlinux 0x5aa3c0c6 alloc_pci_dev +EXPORT_SYMBOL vmlinux 0x5abeeebe udp_proc_unregister +EXPORT_SYMBOL vmlinux 0x5ac376a5 acpi_install_fixed_event_handler +EXPORT_SYMBOL vmlinux 0x5aee4ffa dev_load +EXPORT_SYMBOL vmlinux 0x5b19634d div_s64_rem +EXPORT_SYMBOL vmlinux 0x5b261dac scsi_allocate_command +EXPORT_SYMBOL vmlinux 0x5b31c584 __rta_fill +EXPORT_SYMBOL vmlinux 0x5b51c6a7 acpi_walk_resources +EXPORT_SYMBOL vmlinux 0x5b6cf6dc netpoll_cleanup +EXPORT_SYMBOL vmlinux 0x5b933fab register_nls +EXPORT_SYMBOL vmlinux 0x5c265cba sg_init_one +EXPORT_SYMBOL vmlinux 0x5c2f0ffd bio_integrity_add_page +EXPORT_SYMBOL vmlinux 0x5c30557f scsi_is_target_device +EXPORT_SYMBOL vmlinux 0x5c68705b mca_read_pos +EXPORT_SYMBOL vmlinux 0x5cb86eb2 remove_inode_hash +EXPORT_SYMBOL vmlinux 0x5cc3f1ef audit_log_format +EXPORT_SYMBOL vmlinux 0x5ce6514c pv_mmu_ops +EXPORT_SYMBOL vmlinux 0x5d05d9b8 scsi_dma_unmap +EXPORT_SYMBOL vmlinux 0x5d0f93f3 deregister_atm_ioctl +EXPORT_SYMBOL vmlinux 0x5d58ddd7 bitmap_end_sync +EXPORT_SYMBOL vmlinux 0x5d5eb073 vfs_quota_sync +EXPORT_SYMBOL vmlinux 0x5d73b5f8 km_waitq +EXPORT_SYMBOL vmlinux 0x5d9ac134 journal_get_write_access +EXPORT_SYMBOL vmlinux 0x5dbcfa4f boot_cpu_physical_apicid +EXPORT_SYMBOL vmlinux 0x5dc96efc vfs_rename +EXPORT_SYMBOL vmlinux 0x5e26fcde do_splice_from +EXPORT_SYMBOL vmlinux 0x5e671d75 blkdev_issue_flush +EXPORT_SYMBOL vmlinux 0x5e76101c dma_async_client_chan_request +EXPORT_SYMBOL vmlinux 0x5e79ebec gen_replace_estimator +EXPORT_SYMBOL vmlinux 0x5e8af1da dmam_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0x5e93a7fb make_EII_client +EXPORT_SYMBOL vmlinux 0x5e95eb9f scsi_command_normalize_sense +EXPORT_SYMBOL vmlinux 0x5ea520c5 tcp_select_initial_window +EXPORT_SYMBOL vmlinux 0x5ec82d13 kmem_cache_shrink +EXPORT_SYMBOL vmlinux 0x5ed040b0 pm_set_vt_switch +EXPORT_SYMBOL vmlinux 0x5ed59c2e dma_supported +EXPORT_SYMBOL vmlinux 0x5ed61705 sysctl_data +EXPORT_SYMBOL vmlinux 0x5edd0762 bin2bcd +EXPORT_SYMBOL vmlinux 0x5f08cbe1 linkwatch_fire_event +EXPORT_SYMBOL vmlinux 0x5f160f08 __page_symlink +EXPORT_SYMBOL vmlinux 0x5f1bd579 mca_find_adapter +EXPORT_SYMBOL vmlinux 0x5f4323d7 do_mmap_pgoff +EXPORT_SYMBOL vmlinux 0x5f4a3b3f skb_queue_purge +EXPORT_SYMBOL vmlinux 0x5f9a00fe jbd2_journal_clear_err +EXPORT_SYMBOL vmlinux 0x5fa88e16 tcp_initialize_rcv_mss +EXPORT_SYMBOL vmlinux 0x5fc2eff6 igrab +EXPORT_SYMBOL vmlinux 0x5fc41507 seq_path +EXPORT_SYMBOL vmlinux 0x5ff42b08 acpi_video_get_capabilities +EXPORT_SYMBOL vmlinux 0x60036754 sync_page_range +EXPORT_SYMBOL vmlinux 0x6005137c inet_frags_fini +EXPORT_SYMBOL vmlinux 0x600683d3 do_unblank_screen +EXPORT_SYMBOL vmlinux 0x602d9308 icmp_send +EXPORT_SYMBOL vmlinux 0x608c2831 warn_on_slowpath +EXPORT_SYMBOL vmlinux 0x609f1c7e synchronize_net +EXPORT_SYMBOL vmlinux 0x609f82c4 inet6_unregister_protosw +EXPORT_SYMBOL vmlinux 0x60a32ea9 pm_power_off +EXPORT_SYMBOL vmlinux 0x60ac6393 proc_dointvec_userhz_jiffies +EXPORT_SYMBOL vmlinux 0x60bb63c7 dma_set_mask +EXPORT_SYMBOL vmlinux 0x60c4b5d5 scsi_device_lookup +EXPORT_SYMBOL vmlinux 0x60fa9e1c __seq_open_private +EXPORT_SYMBOL vmlinux 0x6111e1bc init_timer +EXPORT_SYMBOL vmlinux 0x612390ad netpoll_set_trap +EXPORT_SYMBOL vmlinux 0x61692175 single_release +EXPORT_SYMBOL vmlinux 0x618d8299 set_notify_swap_entry_free +EXPORT_SYMBOL vmlinux 0x61b7b126 simple_strtoull +EXPORT_SYMBOL vmlinux 0x61bc15af dm_table_event +EXPORT_SYMBOL vmlinux 0x61ed06bf __sk_mem_schedule +EXPORT_SYMBOL vmlinux 0x61f46825 simple_write_begin +EXPORT_SYMBOL vmlinux 0x61fbac5d filemap_write_and_wait +EXPORT_SYMBOL vmlinux 0x62049256 acpi_disable +EXPORT_SYMBOL vmlinux 0x6228c60d ioctl_by_bdev +EXPORT_SYMBOL vmlinux 0x6229d705 lock_sock_nested +EXPORT_SYMBOL vmlinux 0x6237f6b5 acpi_enable_event +EXPORT_SYMBOL vmlinux 0x623bb74b dm_table_get_md +EXPORT_SYMBOL vmlinux 0x6241a2ab __copy_from_user_ll_nocache +EXPORT_SYMBOL vmlinux 0x6241fd2c acpi_install_address_space_handler +EXPORT_SYMBOL vmlinux 0x62467542 page_symlink_inode_operations +EXPORT_SYMBOL vmlinux 0x6252d2d0 dst_destroy +EXPORT_SYMBOL vmlinux 0x62737e1d sock_unregister +EXPORT_SYMBOL vmlinux 0x62827bec security_secctx_to_secid +EXPORT_SYMBOL vmlinux 0x62c439ad blk_run_queue +EXPORT_SYMBOL vmlinux 0x62e49ece d_alloc_root +EXPORT_SYMBOL vmlinux 0x631b235a do_SAK +EXPORT_SYMBOL vmlinux 0x632135d8 find_task_by_pid_ns +EXPORT_SYMBOL vmlinux 0x632b1014 dev_mc_delete +EXPORT_SYMBOL vmlinux 0x634aabe9 simple_dir_inode_operations +EXPORT_SYMBOL vmlinux 0x636a5691 acpi_register_ioapic +EXPORT_SYMBOL vmlinux 0x63c9e930 dev_get_flags +EXPORT_SYMBOL vmlinux 0x63ecad53 register_netdevice_notifier +EXPORT_SYMBOL vmlinux 0x63f0a361 sock_no_getsockopt +EXPORT_SYMBOL vmlinux 0x6403e338 tcp_memory_pressure +EXPORT_SYMBOL vmlinux 0x642e54ac __wake_up +EXPORT_SYMBOL vmlinux 0x6451294b posix_acl_valid +EXPORT_SYMBOL vmlinux 0x6466a1e6 mempool_alloc +EXPORT_SYMBOL vmlinux 0x64748ecb neigh_for_each +EXPORT_SYMBOL vmlinux 0x6478134c ec_burst_enable +EXPORT_SYMBOL vmlinux 0x6484aa1d module_put +EXPORT_SYMBOL vmlinux 0x64999478 congestion_wait +EXPORT_SYMBOL vmlinux 0x649f0b79 __lock_buffer +EXPORT_SYMBOL vmlinux 0x64cd5d16 init_waitqueue_head +EXPORT_SYMBOL vmlinux 0x64cf1e89 blkdev_put +EXPORT_SYMBOL vmlinux 0x64eae7ad set_memory_array_wb +EXPORT_SYMBOL vmlinux 0x64ef5e7e loop_register_transfer +EXPORT_SYMBOL vmlinux 0x650128e7 br_fdb_get_hook +EXPORT_SYMBOL vmlinux 0x6508d20d bt_accept_unlink +EXPORT_SYMBOL vmlinux 0x650fb346 add_wait_queue +EXPORT_SYMBOL vmlinux 0x651a4139 test_taint +EXPORT_SYMBOL vmlinux 0x65408378 zlib_inflate_blob +EXPORT_SYMBOL vmlinux 0x65414e67 dev_valid_name +EXPORT_SYMBOL vmlinux 0x6559569a llc_sap_open +EXPORT_SYMBOL vmlinux 0x6567ae60 key_link +EXPORT_SYMBOL vmlinux 0x6571b549 mark_buffer_async_write +EXPORT_SYMBOL vmlinux 0x6599ed6e mb_cache_entry_find_next +EXPORT_SYMBOL vmlinux 0x65b0177c __dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0x65b68e33 inode_init_once +EXPORT_SYMBOL vmlinux 0x65bc1498 scsi_cmd_ioctl +EXPORT_SYMBOL vmlinux 0x65ffb510 blk_put_request +EXPORT_SYMBOL vmlinux 0x6608c883 inet6_getname +EXPORT_SYMBOL vmlinux 0x660dc7f7 copy_strings_kernel +EXPORT_SYMBOL vmlinux 0x6611e69a security_d_instantiate +EXPORT_SYMBOL vmlinux 0x66299407 tty_port_alloc_xmit_buf +EXPORT_SYMBOL vmlinux 0x6658a3c4 xfrm_state_walk +EXPORT_SYMBOL vmlinux 0x668badb5 xfrm_policy_destroy +EXPORT_SYMBOL vmlinux 0x668da8d5 zlib_inflateIncomp +EXPORT_SYMBOL vmlinux 0x669901ca mnt_unpin +EXPORT_SYMBOL vmlinux 0x66da08ab seq_release_private +EXPORT_SYMBOL vmlinux 0x6702b228 __locks_copy_lock +EXPORT_SYMBOL vmlinux 0x670de276 pcix_get_mmrbc +EXPORT_SYMBOL vmlinux 0x6729d3df __get_user_4 +EXPORT_SYMBOL vmlinux 0x6762ef18 km_policy_expired +EXPORT_SYMBOL vmlinux 0x67b27ec1 tty_std_termios +EXPORT_SYMBOL vmlinux 0x67b490b4 dev_getbyhwaddr +EXPORT_SYMBOL vmlinux 0x67bbe014 __inet6_hash +EXPORT_SYMBOL vmlinux 0x67e71b77 __mutex_init +EXPORT_SYMBOL vmlinux 0x67ea871a xfrm_user_policy +EXPORT_SYMBOL vmlinux 0x688850a9 jbd2_journal_invalidatepage +EXPORT_SYMBOL vmlinux 0x689a1101 acpi_bus_get_status +EXPORT_SYMBOL vmlinux 0x68b1ef6b find_get_page +EXPORT_SYMBOL vmlinux 0x690de276 atm_dev_lookup +EXPORT_SYMBOL vmlinux 0x691697e4 xfrm_state_lookup +EXPORT_SYMBOL vmlinux 0x691d2d0d blk_plug_device +EXPORT_SYMBOL vmlinux 0x692c2d9c __request_region +EXPORT_SYMBOL vmlinux 0x692e235f ip6_frag_match +EXPORT_SYMBOL vmlinux 0x6971447a rtc_month_days +EXPORT_SYMBOL vmlinux 0x69927dff try_acquire_console_sem +EXPORT_SYMBOL vmlinux 0x69a0ca7d iowrite16be +EXPORT_SYMBOL vmlinux 0x69c8c1d5 security_req_classify_flow +EXPORT_SYMBOL vmlinux 0x69d043e7 nf_ct_attach +EXPORT_SYMBOL vmlinux 0x69d09bd3 kernel_accept +EXPORT_SYMBOL vmlinux 0x69d2575f efi +EXPORT_SYMBOL vmlinux 0x69d38ed9 __scsi_print_sense +EXPORT_SYMBOL vmlinux 0x69e27c7a bitmap_copy_le +EXPORT_SYMBOL vmlinux 0x69f26828 kobject_set_name +EXPORT_SYMBOL vmlinux 0x6a037cf1 mempool_kfree +EXPORT_SYMBOL vmlinux 0x6a27bfce csum_partial_copy_generic +EXPORT_SYMBOL vmlinux 0x6a47571d __set_personality +EXPORT_SYMBOL vmlinux 0x6a6cc4bb key_payload_reserve +EXPORT_SYMBOL vmlinux 0x6a753f0c __nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0x6a881535 file_update_time +EXPORT_SYMBOL vmlinux 0x6a89ab83 __mark_inode_dirty +EXPORT_SYMBOL vmlinux 0x6acb973d iowrite32be +EXPORT_SYMBOL vmlinux 0x6ad85887 acpi_enable_gpe +EXPORT_SYMBOL vmlinux 0x6add5c9a dmi_find_device +EXPORT_SYMBOL vmlinux 0x6aeb180f generic_listxattr +EXPORT_SYMBOL vmlinux 0x6b1b67d3 __bdevname +EXPORT_SYMBOL vmlinux 0x6b1e3d35 sk_stream_error +EXPORT_SYMBOL vmlinux 0x6b2dc060 dump_stack +EXPORT_SYMBOL vmlinux 0x6b545d4d misc_deregister +EXPORT_SYMBOL vmlinux 0x6b7eae91 block_read_full_page +EXPORT_SYMBOL vmlinux 0x6b89d86d remove_arg_zero +EXPORT_SYMBOL vmlinux 0x6b937ffb mca_mark_as_used +EXPORT_SYMBOL vmlinux 0x6b9b88f3 sleep_on +EXPORT_SYMBOL vmlinux 0x6ba66437 hci_suspend_dev +EXPORT_SYMBOL vmlinux 0x6bab184e ethtool_op_get_ufo +EXPORT_SYMBOL vmlinux 0x6baf5124 sock_sendmsg +EXPORT_SYMBOL vmlinux 0x6bafbced mod_timer +EXPORT_SYMBOL vmlinux 0x6bca46df fb_blank +EXPORT_SYMBOL vmlinux 0x6bdcfd99 qdisc_class_hash_remove +EXPORT_SYMBOL vmlinux 0x6c0ec405 bdi_init +EXPORT_SYMBOL vmlinux 0x6c1ce5ce strcspn +EXPORT_SYMBOL vmlinux 0x6c24b778 scsi_block_requests +EXPORT_SYMBOL vmlinux 0x6c2e3320 strncmp +EXPORT_SYMBOL vmlinux 0x6c308358 load_nls +EXPORT_SYMBOL vmlinux 0x6c389761 acpi_bus_get_private_data +EXPORT_SYMBOL vmlinux 0x6c4258c8 xfrm6_input_addr +EXPORT_SYMBOL vmlinux 0x6c456c44 phy_stop_interrupts +EXPORT_SYMBOL vmlinux 0x6c484da8 rtnetlink_put_metrics +EXPORT_SYMBOL vmlinux 0x6c4f4d13 netdev_boot_setup_check +EXPORT_SYMBOL vmlinux 0x6c505329 tcf_action_exec +EXPORT_SYMBOL vmlinux 0x6c61c5d7 inode_setattr +EXPORT_SYMBOL vmlinux 0x6c61ce70 num_registered_fb +EXPORT_SYMBOL vmlinux 0x6c702af7 sysctl_udp_rmem_min +EXPORT_SYMBOL vmlinux 0x6c92bea9 uart_unregister_driver +EXPORT_SYMBOL vmlinux 0x6c9cff86 __xfrm_policy_check +EXPORT_SYMBOL vmlinux 0x6ca378e7 bio_map_kern +EXPORT_SYMBOL vmlinux 0x6caf2fb7 sock_kfree_s +EXPORT_SYMBOL vmlinux 0x6cd2a5c5 unregister_console +EXPORT_SYMBOL vmlinux 0x6cdc5c6b nla_strlcpy +EXPORT_SYMBOL vmlinux 0x6cf5f38b proto_register +EXPORT_SYMBOL vmlinux 0x6d0da34c param_get_short +EXPORT_SYMBOL vmlinux 0x6d10832b key_put +EXPORT_SYMBOL vmlinux 0x6d12d51c ____pagevec_lru_add +EXPORT_SYMBOL vmlinux 0x6d1ced27 vcc_sklist_lock +EXPORT_SYMBOL vmlinux 0x6d27ef64 __bitmap_empty +EXPORT_SYMBOL vmlinux 0x6d288375 radix_tree_next_hole +EXPORT_SYMBOL vmlinux 0x6d294e43 clock_t_to_jiffies +EXPORT_SYMBOL vmlinux 0x6d2ca139 bt_sock_register +EXPORT_SYMBOL vmlinux 0x6d340f64 tty_termios_input_baud_rate +EXPORT_SYMBOL vmlinux 0x6d464175 __sg_free_table +EXPORT_SYMBOL vmlinux 0x6d56994a cmpxchg_486_u64 +EXPORT_SYMBOL vmlinux 0x6d669a0f journal_abort +EXPORT_SYMBOL vmlinux 0x6d6a8e31 test_set_page_writeback +EXPORT_SYMBOL vmlinux 0x6d83523a find_or_create_page +EXPORT_SYMBOL vmlinux 0x6dc0c24b complete_and_exit +EXPORT_SYMBOL vmlinux 0x6dcfd380 boot_cpu_data +EXPORT_SYMBOL vmlinux 0x6dee7be5 dump_fpu +EXPORT_SYMBOL vmlinux 0x6def2db2 half_md4_transform +EXPORT_SYMBOL vmlinux 0x6e07a54e acpi_get_gpe_status +EXPORT_SYMBOL vmlinux 0x6e1a4bbb udp_hash_lock +EXPORT_SYMBOL vmlinux 0x6e440b58 memcpy_fromiovecend +EXPORT_SYMBOL vmlinux 0x6e6d3dff default_unplug_io_fn +EXPORT_SYMBOL vmlinux 0x6e720ff2 rtnl_unlock +EXPORT_SYMBOL vmlinux 0x6e80268f pagecache_write_begin +EXPORT_SYMBOL vmlinux 0x6e9dd606 __symbol_put +EXPORT_SYMBOL vmlinux 0x6ead242b cond_resched_lock +EXPORT_SYMBOL vmlinux 0x6ecec04e truncate_inode_pages_range +EXPORT_SYMBOL vmlinux 0x6eec3746 pcim_enable_device +EXPORT_SYMBOL vmlinux 0x6f3dacee sysctl_string +EXPORT_SYMBOL vmlinux 0x6f779935 unregister_snap_client +EXPORT_SYMBOL vmlinux 0x6f7d520f save_mount_options +EXPORT_SYMBOL vmlinux 0x6f982379 unbind_con_driver +EXPORT_SYMBOL vmlinux 0x6faecd7a atm_init_aal5 +EXPORT_SYMBOL vmlinux 0x6fcb87a1 touch_softlockup_watchdog +EXPORT_SYMBOL vmlinux 0x6ff0a6f8 tcp_v4_conn_request +EXPORT_SYMBOL vmlinux 0x7008a9b7 timespec_to_jiffies +EXPORT_SYMBOL vmlinux 0x701d0ebd snprintf +EXPORT_SYMBOL vmlinux 0x703cc4d1 udplite_prot +EXPORT_SYMBOL vmlinux 0x70461a22 key_revoke +EXPORT_SYMBOL vmlinux 0x7054a3e4 request_dma +EXPORT_SYMBOL vmlinux 0x705a9b95 dev_unicast_delete +EXPORT_SYMBOL vmlinux 0x7063159c dm_dirty_log_create +EXPORT_SYMBOL vmlinux 0x707081b3 thermal_zone_device_unregister +EXPORT_SYMBOL vmlinux 0x7072bb63 blk_rq_map_sg +EXPORT_SYMBOL vmlinux 0x7081aa66 simple_sync_file +EXPORT_SYMBOL vmlinux 0x708e38a4 tty_shutdown +EXPORT_SYMBOL vmlinux 0x7094f8ae bt_err +EXPORT_SYMBOL vmlinux 0x709db1f1 kernel_setsockopt +EXPORT_SYMBOL vmlinux 0x70bc1446 backlight_device_unregister +EXPORT_SYMBOL vmlinux 0x70d1f8f3 strncat +EXPORT_SYMBOL vmlinux 0x70d8ab82 acpi_acquire_global_lock +EXPORT_SYMBOL vmlinux 0x70e0d61f cpu_all_bits +EXPORT_SYMBOL vmlinux 0x7126a53c register_exec_domain +EXPORT_SYMBOL vmlinux 0x7129e5f8 hex_asc +EXPORT_SYMBOL vmlinux 0x712aa29b _spin_lock_irqsave +EXPORT_SYMBOL vmlinux 0x71356fba remove_wait_queue +EXPORT_SYMBOL vmlinux 0x7143b3f5 __inet6_lookup_established +EXPORT_SYMBOL vmlinux 0x714c7a81 acpi_check_mem_region +EXPORT_SYMBOL vmlinux 0x7171121c overflowgid +EXPORT_SYMBOL vmlinux 0x7181014a mdiobus_unregister +EXPORT_SYMBOL vmlinux 0x71907357 keyring_search +EXPORT_SYMBOL vmlinux 0x719b2fe7 xfrm_lookup +EXPORT_SYMBOL vmlinux 0x71a50dbc register_blkdev +EXPORT_SYMBOL vmlinux 0x71ddc595 jbd2_journal_stop +EXPORT_SYMBOL vmlinux 0x71dfebf5 ip_getsockopt +EXPORT_SYMBOL vmlinux 0x72150358 mca_device_set_claim +EXPORT_SYMBOL vmlinux 0x7215aee7 starget_for_each_device +EXPORT_SYMBOL vmlinux 0x72270e35 do_gettimeofday +EXPORT_SYMBOL vmlinux 0x725918b2 alloc_etherdev_mq +EXPORT_SYMBOL vmlinux 0x725dc6df clocksource_register +EXPORT_SYMBOL vmlinux 0x726a34f2 block_write_begin +EXPORT_SYMBOL vmlinux 0x728b0b39 pnp_release_card_device +EXPORT_SYMBOL vmlinux 0x7299bd8e mark_buffer_dirty +EXPORT_SYMBOL vmlinux 0x72b243d4 free_dma +EXPORT_SYMBOL vmlinux 0x72b373f5 tc_classify +EXPORT_SYMBOL vmlinux 0x72b3e946 xfrm_state_add +EXPORT_SYMBOL vmlinux 0x72bf2140 mtrr_add +EXPORT_SYMBOL vmlinux 0x72d06920 register_netdev +EXPORT_SYMBOL vmlinux 0x72ea7b2d scsi_device_type +EXPORT_SYMBOL vmlinux 0x73064479 struct_module +EXPORT_SYMBOL vmlinux 0x731ec35b sock_common_setsockopt +EXPORT_SYMBOL vmlinux 0x73213fe1 pci_release_regions +EXPORT_SYMBOL vmlinux 0x7338b707 jbd2_journal_errno +EXPORT_SYMBOL vmlinux 0x734e1e05 blk_rq_map_kern +EXPORT_SYMBOL vmlinux 0x735a0bd5 native_io_delay +EXPORT_SYMBOL vmlinux 0x7361cf6f generic_make_request +EXPORT_SYMBOL vmlinux 0x738803e6 strnlen +EXPORT_SYMBOL vmlinux 0x7389c9a8 acpi_bus_get_power +EXPORT_SYMBOL vmlinux 0x73e152de netlink_kernel_release +EXPORT_SYMBOL vmlinux 0x73e20c1c strlcpy +EXPORT_SYMBOL vmlinux 0x73fa647f journal_flush +EXPORT_SYMBOL vmlinux 0x740a1b95 reserve_evntsel_nmi +EXPORT_SYMBOL vmlinux 0x7413793a EISA_bus +EXPORT_SYMBOL vmlinux 0x7428758d scsi_eh_restore_cmnd +EXPORT_SYMBOL vmlinux 0x7460ee6c pcix_set_mmrbc +EXPORT_SYMBOL vmlinux 0x7485e15e unregister_chrdev_region +EXPORT_SYMBOL vmlinux 0x74875bbf ip_fragment +EXPORT_SYMBOL vmlinux 0x748caf40 down +EXPORT_SYMBOL vmlinux 0x74a3b234 sk_stop_timer +EXPORT_SYMBOL vmlinux 0x74cc1cbe unregister_cpu_notifier +EXPORT_SYMBOL vmlinux 0x74cc238d current_kernel_time +EXPORT_SYMBOL vmlinux 0x74deea1e km_query +EXPORT_SYMBOL vmlinux 0x74e30288 neigh_table_clear +EXPORT_SYMBOL vmlinux 0x75271716 save_processor_state +EXPORT_SYMBOL vmlinux 0x753c3971 cdrom_number_of_slots +EXPORT_SYMBOL vmlinux 0x75566739 complete_request_key +EXPORT_SYMBOL vmlinux 0x7587e27f md_check_recovery +EXPORT_SYMBOL vmlinux 0x758a15ba register_key_type +EXPORT_SYMBOL vmlinux 0x758febb9 pci_pme_capable +EXPORT_SYMBOL vmlinux 0x75ac6962 sync_page_range_nolock +EXPORT_SYMBOL vmlinux 0x75c24c80 ppp_unregister_compressor +EXPORT_SYMBOL vmlinux 0x75c7fd9e call_usermodehelper_setup +EXPORT_SYMBOL vmlinux 0x75d56f55 vmalloc_to_page +EXPORT_SYMBOL vmlinux 0x75d681f2 sk_stream_wait_connect +EXPORT_SYMBOL vmlinux 0x75d8212d unlock_super +EXPORT_SYMBOL vmlinux 0x75d99f89 vfs_mkdir +EXPORT_SYMBOL vmlinux 0x760a0f4f yield +EXPORT_SYMBOL vmlinux 0x760b437a unregister_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x762e3ff9 arp_tbl +EXPORT_SYMBOL vmlinux 0x76406e31 devm_ioremap +EXPORT_SYMBOL vmlinux 0x76457587 nf_register_queue_handler +EXPORT_SYMBOL vmlinux 0x767ddb02 set_memory_wc +EXPORT_SYMBOL vmlinux 0x76b0b971 mdiobus_scan +EXPORT_SYMBOL vmlinux 0x76b0f8f8 bad_dma_address +EXPORT_SYMBOL vmlinux 0x76bf656d __bitmap_shift_left +EXPORT_SYMBOL vmlinux 0x76d3cd60 laptop_mode +EXPORT_SYMBOL vmlinux 0x76f3f8a5 num_k8_northbridges +EXPORT_SYMBOL vmlinux 0x770a0036 isapnp_cfg_begin +EXPORT_SYMBOL vmlinux 0x7714330a tcp_v4_destroy_sock +EXPORT_SYMBOL vmlinux 0x771cda88 bitmap_cond_end_sync +EXPORT_SYMBOL vmlinux 0x772964cc ipv6_dev_get_saddr +EXPORT_SYMBOL vmlinux 0x7730c36b notify_change +EXPORT_SYMBOL vmlinux 0x7759c852 dentry_open +EXPORT_SYMBOL vmlinux 0x7772220d rfkill_switch_all +EXPORT_SYMBOL vmlinux 0x779f2ead input_grab_device +EXPORT_SYMBOL vmlinux 0x77a108df _write_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x77abcf55 vlan_ioctl_set +EXPORT_SYMBOL vmlinux 0x77e91ab4 call_usermodehelper_setkeys +EXPORT_SYMBOL vmlinux 0x77ecac9f zlib_inflateEnd +EXPORT_SYMBOL vmlinux 0x78305efe udp_sendmsg +EXPORT_SYMBOL vmlinux 0x7861936f dm_put_device +EXPORT_SYMBOL vmlinux 0x7867749b netif_rx +EXPORT_SYMBOL vmlinux 0x788fe103 iomem_resource +EXPORT_SYMBOL vmlinux 0x78a484c9 _read_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x78cb2783 down_write_trylock +EXPORT_SYMBOL vmlinux 0x78df6bd7 no_pci_devices +EXPORT_SYMBOL vmlinux 0x78e9332a dma_pool_alloc +EXPORT_SYMBOL vmlinux 0x790908bc vm_map_ram +EXPORT_SYMBOL vmlinux 0x79146796 tty_port_init +EXPORT_SYMBOL vmlinux 0x79319493 eth_header_cache_update +EXPORT_SYMBOL vmlinux 0x794487ee disable_hlt +EXPORT_SYMBOL vmlinux 0x795b3069 deny_write_access +EXPORT_SYMBOL vmlinux 0x796fc5ce scsi_get_sense_info_fld +EXPORT_SYMBOL vmlinux 0x799af696 rtnl_unicast +EXPORT_SYMBOL vmlinux 0x79aa04a2 get_random_bytes +EXPORT_SYMBOL vmlinux 0x79f64a16 rt6_lookup +EXPORT_SYMBOL vmlinux 0x7a088ef5 devm_free_irq +EXPORT_SYMBOL vmlinux 0x7a2a837d strict_strtol +EXPORT_SYMBOL vmlinux 0x7a5c0691 dev_open +EXPORT_SYMBOL vmlinux 0x7a66c287 sock_map_fd +EXPORT_SYMBOL vmlinux 0x7a70fc66 skb_seq_read +EXPORT_SYMBOL vmlinux 0x7a789caa simple_unlink +EXPORT_SYMBOL vmlinux 0x7a848702 _read_lock_irqsave +EXPORT_SYMBOL vmlinux 0x7a988e6f d_move +EXPORT_SYMBOL vmlinux 0x7ade905b scsi_add_device +EXPORT_SYMBOL vmlinux 0x7aec9089 clear_user +EXPORT_SYMBOL vmlinux 0x7afe20d3 proc_create_data +EXPORT_SYMBOL vmlinux 0x7b0c84c4 acpi_remove_table_handler +EXPORT_SYMBOL vmlinux 0x7b1282e1 elv_add_request +EXPORT_SYMBOL vmlinux 0x7b134ddf acpi_get_name +EXPORT_SYMBOL vmlinux 0x7b3e56f6 xfrm6_rcv +EXPORT_SYMBOL vmlinux 0x7b52a859 wrmsr_safe_on_cpu +EXPORT_SYMBOL vmlinux 0x7b576326 __xfrm_lookup +EXPORT_SYMBOL vmlinux 0x7b69467e posix_acl_from_xattr +EXPORT_SYMBOL vmlinux 0x7b86a8ec scsi_init_io +EXPORT_SYMBOL vmlinux 0x7bc52287 devm_ioport_map +EXPORT_SYMBOL vmlinux 0x7bc5ca03 acpi_processor_unregister_performance +EXPORT_SYMBOL vmlinux 0x7bcaa1ba proc_doulongvec_minmax +EXPORT_SYMBOL vmlinux 0x7bdfefed elv_queue_empty +EXPORT_SYMBOL vmlinux 0x7c0edd7d acpi_check_region +EXPORT_SYMBOL vmlinux 0x7c1c4308 vfs_create +EXPORT_SYMBOL vmlinux 0x7c24b961 rtnl_create_link +EXPORT_SYMBOL vmlinux 0x7c2ecca7 skb_kill_datagram +EXPORT_SYMBOL vmlinux 0x7c45af4e xfrm6_find_1stfragopt +EXPORT_SYMBOL vmlinux 0x7c46233a cpufreq_quick_get +EXPORT_SYMBOL vmlinux 0x7c60d66e getname +EXPORT_SYMBOL vmlinux 0x7c904ded unregister_module_notifier +EXPORT_SYMBOL vmlinux 0x7ca3cdf5 mb_cache_entry_find_first +EXPORT_SYMBOL vmlinux 0x7cb1ae69 cpu_down +EXPORT_SYMBOL vmlinux 0x7cb2724f pci_get_class +EXPORT_SYMBOL vmlinux 0x7cb39667 scsi_finish_command +EXPORT_SYMBOL vmlinux 0x7ce13c0b stop_tty +EXPORT_SYMBOL vmlinux 0x7d047e7e acpi_ut_exception +EXPORT_SYMBOL vmlinux 0x7d0814ba sysctl_ms_jiffies +EXPORT_SYMBOL vmlinux 0x7d11c268 jiffies +EXPORT_SYMBOL vmlinux 0x7d19ca07 bdput +EXPORT_SYMBOL vmlinux 0x7d1d8f3c tcp_v4_connect +EXPORT_SYMBOL vmlinux 0x7d407018 nla_put +EXPORT_SYMBOL vmlinux 0x7d69b957 rfkill_unregister +EXPORT_SYMBOL vmlinux 0x7d6f555b get_sb_bdev +EXPORT_SYMBOL vmlinux 0x7d79a978 request_key_with_auxdata +EXPORT_SYMBOL vmlinux 0x7d7a0844 tcf_em_unregister +EXPORT_SYMBOL vmlinux 0x7d850612 utf8_mbstowcs +EXPORT_SYMBOL vmlinux 0x7da9e65d eisa_driver_register +EXPORT_SYMBOL vmlinux 0x7db960e2 register_framebuffer +EXPORT_SYMBOL vmlinux 0x7dceceac capable +EXPORT_SYMBOL vmlinux 0x7de5455b netlink_change_ngroups +EXPORT_SYMBOL vmlinux 0x7e06a0a8 blk_rq_count_integrity_sg +EXPORT_SYMBOL vmlinux 0x7e76cbd1 tcp_v4_send_check +EXPORT_SYMBOL vmlinux 0x7e7aacf8 del_gendisk +EXPORT_SYMBOL vmlinux 0x7e9ebb05 kernel_thread +EXPORT_SYMBOL vmlinux 0x7ed410ea filemap_fault +EXPORT_SYMBOL vmlinux 0x7ee91c1d _spin_trylock +EXPORT_SYMBOL vmlinux 0x7ef933ba tcp_sync_mss +EXPORT_SYMBOL vmlinux 0x7ef970dc scsi_print_command +EXPORT_SYMBOL vmlinux 0x7f087fec proc_dointvec +EXPORT_SYMBOL vmlinux 0x7f1103dc lease_modify +EXPORT_SYMBOL vmlinux 0x7f12574b kfree_skb +EXPORT_SYMBOL vmlinux 0x7f1543db register_sysctl_paths +EXPORT_SYMBOL vmlinux 0x7f24de73 jiffies_to_usecs +EXPORT_SYMBOL vmlinux 0x7f263240 i2c_attach_client +EXPORT_SYMBOL vmlinux 0x7f29adc1 simple_set_mnt +EXPORT_SYMBOL vmlinux 0x7f71d9e3 d_prune_aliases +EXPORT_SYMBOL vmlinux 0x7f8723bd pcie_mch_quirk +EXPORT_SYMBOL vmlinux 0x7fbe9989 pci_remove_bus_device +EXPORT_SYMBOL vmlinux 0x7fc95ea3 set_trace_device +EXPORT_SYMBOL vmlinux 0x7fd0804e pci_bus_read_config_dword +EXPORT_SYMBOL vmlinux 0x7fd2aacb blk_rq_map_integrity_sg +EXPORT_SYMBOL vmlinux 0x7fe47a93 mb_cache_entry_release +EXPORT_SYMBOL vmlinux 0x7fe6cd31 journal_unlock_updates +EXPORT_SYMBOL vmlinux 0x802da724 journal_set_features +EXPORT_SYMBOL vmlinux 0x805dbbd2 dma_release_from_coherent +EXPORT_SYMBOL vmlinux 0x8063f83d radix_tree_gang_lookup +EXPORT_SYMBOL vmlinux 0x80644a75 dm_get_device +EXPORT_SYMBOL vmlinux 0x8093ea30 __alloc_pages_internal +EXPORT_SYMBOL vmlinux 0x80b0a22a bio_unmap_user +EXPORT_SYMBOL vmlinux 0x80bda67d nla_reserve +EXPORT_SYMBOL vmlinux 0x80eb207f blk_queue_free_tags +EXPORT_SYMBOL vmlinux 0x80fc942b pci_enable_msix +EXPORT_SYMBOL vmlinux 0x81235040 bdi_register +EXPORT_SYMBOL vmlinux 0x8124ed74 __nla_reserve +EXPORT_SYMBOL vmlinux 0x8136ac6d path_put +EXPORT_SYMBOL vmlinux 0x81472677 acpi_get_table +EXPORT_SYMBOL vmlinux 0x814e7730 nf_ct_destroy +EXPORT_SYMBOL vmlinux 0x815b5dd4 match_octal +EXPORT_SYMBOL vmlinux 0x815f2897 empty_zero_page +EXPORT_SYMBOL vmlinux 0x816826b5 __neigh_for_each_release +EXPORT_SYMBOL vmlinux 0x81793d2c blk_integrity_register +EXPORT_SYMBOL vmlinux 0x81799cee vscnprintf +EXPORT_SYMBOL vmlinux 0x8181295d pcibios_set_irq_routing +EXPORT_SYMBOL vmlinux 0x819d2ded journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0x81bacd0e ip_nat_decode_session +EXPORT_SYMBOL vmlinux 0x81c0c0e3 __inode_dir_notify +EXPORT_SYMBOL vmlinux 0x81d751bd simple_empty +EXPORT_SYMBOL vmlinux 0x81e6b37f dmi_get_system_info +EXPORT_SYMBOL vmlinux 0x81eedee2 km_state_expired +EXPORT_SYMBOL vmlinux 0x8204431b mdiobus_write +EXPORT_SYMBOL vmlinux 0x82072614 tasklet_kill +EXPORT_SYMBOL vmlinux 0x820d225f print_mac +EXPORT_SYMBOL vmlinux 0x8212e73c blk_get_backing_dev_info +EXPORT_SYMBOL vmlinux 0x8235805b memmove +EXPORT_SYMBOL vmlinux 0x82454da2 __lookup_hash +EXPORT_SYMBOL vmlinux 0x8251bcc3 bitmap_release_region +EXPORT_SYMBOL vmlinux 0x82619e53 fget +EXPORT_SYMBOL vmlinux 0x82673561 schedule_delayed_work +EXPORT_SYMBOL vmlinux 0x827155d1 cdev_add +EXPORT_SYMBOL vmlinux 0x8271d1d9 splice_direct_to_actor +EXPORT_SYMBOL vmlinux 0x827c71e4 unlock_new_inode +EXPORT_SYMBOL vmlinux 0x828f6b2b request_key_async +EXPORT_SYMBOL vmlinux 0x82996421 dma_pool_create +EXPORT_SYMBOL vmlinux 0x829c845d path_get +EXPORT_SYMBOL vmlinux 0x82d0ff23 i2c_del_driver +EXPORT_SYMBOL vmlinux 0x82dea7b6 generic_osync_inode +EXPORT_SYMBOL vmlinux 0x82e0de77 sk_stream_kill_queues +EXPORT_SYMBOL vmlinux 0x82f65633 dm_io_client_resize +EXPORT_SYMBOL vmlinux 0x8317e20a completion_done +EXPORT_SYMBOL vmlinux 0x832bb7f5 dcache_dir_close +EXPORT_SYMBOL vmlinux 0x834814b7 jbd2_journal_wipe +EXPORT_SYMBOL vmlinux 0x83628b4f generic_file_llseek +EXPORT_SYMBOL vmlinux 0x836397d4 elv_dispatch_add_tail +EXPORT_SYMBOL vmlinux 0x836961c8 page_follow_link_light +EXPORT_SYMBOL vmlinux 0x8377dc9e vc_resize +EXPORT_SYMBOL vmlinux 0x83800bfa kref_init +EXPORT_SYMBOL vmlinux 0x838ec0f9 atm_proc_root +EXPORT_SYMBOL vmlinux 0x83a476ce bitmap_scnlistprintf +EXPORT_SYMBOL vmlinux 0x83a5efc2 security_sb_clone_mnt_opts +EXPORT_SYMBOL vmlinux 0x83dd0d8f bio_free +EXPORT_SYMBOL vmlinux 0x83f82465 fb_firmware_edid +EXPORT_SYMBOL vmlinux 0x840924aa ipv4_specific +EXPORT_SYMBOL vmlinux 0x84265db3 pnp_device_attach +EXPORT_SYMBOL vmlinux 0x842f310c elv_rb_former_request +EXPORT_SYMBOL vmlinux 0x84989b68 noop_qdisc +EXPORT_SYMBOL vmlinux 0x84a7211c register_cdrom +EXPORT_SYMBOL vmlinux 0x84cb6f7f nf_ip6_checksum +EXPORT_SYMBOL vmlinux 0x84d2ee64 jbd2_journal_release_jbd_inode +EXPORT_SYMBOL vmlinux 0x84dfc57d seq_bitmap +EXPORT_SYMBOL vmlinux 0x84f24cfa da903x_query_status +EXPORT_SYMBOL vmlinux 0x8536fabc elv_next_request +EXPORT_SYMBOL vmlinux 0x8540657f cdev_del +EXPORT_SYMBOL vmlinux 0x85670f1d rtnl_is_locked +EXPORT_SYMBOL vmlinux 0x85da65b4 qdisc_create_dflt +EXPORT_SYMBOL vmlinux 0x85df9b6c strsep +EXPORT_SYMBOL vmlinux 0x85e7deb2 iov_iter_fault_in_readable +EXPORT_SYMBOL vmlinux 0x8611f05f fb_set_cmap +EXPORT_SYMBOL vmlinux 0x8613316c journal_revoke +EXPORT_SYMBOL vmlinux 0x863cb91a utf8_wcstombs +EXPORT_SYMBOL vmlinux 0x8664f62e cpufreq_update_policy +EXPORT_SYMBOL vmlinux 0x867efd80 xfrm_state_alloc +EXPORT_SYMBOL vmlinux 0x8681e4d7 tty_flip_buffer_push +EXPORT_SYMBOL vmlinux 0x868acba5 get_options +EXPORT_SYMBOL vmlinux 0x86956fe1 acpi_bus_register_driver +EXPORT_SYMBOL vmlinux 0x86b1864d tcp_sendpage +EXPORT_SYMBOL vmlinux 0x86e6b8e3 tcp_v4_syn_recv_sock +EXPORT_SYMBOL vmlinux 0x86f9ef46 pnp_get_resource +EXPORT_SYMBOL vmlinux 0x86fb9b05 bitmap_parse_user +EXPORT_SYMBOL vmlinux 0x8707b9a4 ipv6_push_nfrag_opts +EXPORT_SYMBOL vmlinux 0x8712c28b pci_fixup_device +EXPORT_SYMBOL vmlinux 0x871c0a7e fiemap_check_flags +EXPORT_SYMBOL vmlinux 0x8733e9a3 sleep_on_timeout +EXPORT_SYMBOL vmlinux 0x873806a6 udp_ioctl +EXPORT_SYMBOL vmlinux 0x874df003 pnp_device_detach +EXPORT_SYMBOL vmlinux 0x876dafc3 ec_write +EXPORT_SYMBOL vmlinux 0x8785725d param_set_charp +EXPORT_SYMBOL vmlinux 0x878ab3ce sysctl_tcp_adv_win_scale +EXPORT_SYMBOL vmlinux 0x878ac511 pci_enable_bridges +EXPORT_SYMBOL vmlinux 0x87976491 tcp_v4_do_rcv +EXPORT_SYMBOL vmlinux 0x87abd9d7 bt_accept_dequeue +EXPORT_SYMBOL vmlinux 0x87c20f16 sg_miter_next +EXPORT_SYMBOL vmlinux 0x87c655e1 arp_find +EXPORT_SYMBOL vmlinux 0x87d65cf8 scsi_execute_req +EXPORT_SYMBOL vmlinux 0x87e6d267 unregister_exec_domain +EXPORT_SYMBOL vmlinux 0x87f193e4 input_free_device +EXPORT_SYMBOL vmlinux 0x881039d0 zlib_inflate +EXPORT_SYMBOL vmlinux 0x8823401c ilookup5 +EXPORT_SYMBOL vmlinux 0x882f2acf __starget_for_each_device +EXPORT_SYMBOL vmlinux 0x8836d5d5 tcp_v4_md5_do_add +EXPORT_SYMBOL vmlinux 0x888853bf blk_init_tags +EXPORT_SYMBOL vmlinux 0x889549bf tcf_destroy_chain +EXPORT_SYMBOL vmlinux 0x88e86e33 mca_device_read_pos +EXPORT_SYMBOL vmlinux 0x88e88136 ioremap_prot +EXPORT_SYMBOL vmlinux 0x8903a3ee scsi_prep_return +EXPORT_SYMBOL vmlinux 0x892b26a0 set_memory_nx +EXPORT_SYMBOL vmlinux 0x892c05aa registered_fb +EXPORT_SYMBOL vmlinux 0x89368404 mca_device_status +EXPORT_SYMBOL vmlinux 0x893928d9 scsi_setup_blk_pc_cmnd +EXPORT_SYMBOL vmlinux 0x893ff045 serio_unregister_driver +EXPORT_SYMBOL vmlinux 0x8941125a dmam_free_noncoherent +EXPORT_SYMBOL vmlinux 0x8949858b schedule_work +EXPORT_SYMBOL vmlinux 0x8953bb27 del_timer +EXPORT_SYMBOL vmlinux 0x8969b997 ida_get_new +EXPORT_SYMBOL vmlinux 0x896be901 ip6_xmit +EXPORT_SYMBOL vmlinux 0x897473df mktime +EXPORT_SYMBOL vmlinux 0x897d1caa shrink_dcache_parent +EXPORT_SYMBOL vmlinux 0x898b1fec mutex_trylock +EXPORT_SYMBOL vmlinux 0x89949018 down_timeout +EXPORT_SYMBOL vmlinux 0x89adbfec skb_under_panic +EXPORT_SYMBOL vmlinux 0x89d5538d fb_pad_aligned_buffer +EXPORT_SYMBOL vmlinux 0x89d66811 build_ehash_secret +EXPORT_SYMBOL vmlinux 0x89f5bd54 inet_del_protocol +EXPORT_SYMBOL vmlinux 0x8a0b1191 brioctl_set +EXPORT_SYMBOL vmlinux 0x8a292183 scsi_device_quiesce +EXPORT_SYMBOL vmlinux 0x8a3eabf0 __wait_on_bit +EXPORT_SYMBOL vmlinux 0x8a405628 __module_put_and_exit +EXPORT_SYMBOL vmlinux 0x8a4081b5 neigh_ifdown +EXPORT_SYMBOL vmlinux 0x8a7d1c31 high_memory +EXPORT_SYMBOL vmlinux 0x8a7d248d ethtool_op_set_tx_hw_csum +EXPORT_SYMBOL vmlinux 0x8a99a016 mempool_free_slab +EXPORT_SYMBOL vmlinux 0x8aaf8654 mutex_lock +EXPORT_SYMBOL vmlinux 0x8acd72a5 nf_log_register +EXPORT_SYMBOL vmlinux 0x8b18496f __copy_to_user_ll +EXPORT_SYMBOL vmlinux 0x8b325b50 generic_block_fiemap +EXPORT_SYMBOL vmlinux 0x8b3a8438 xfrm_unregister_mode +EXPORT_SYMBOL vmlinux 0x8b44d32e bio_put +EXPORT_SYMBOL vmlinux 0x8b50bd1c udp_memory_allocated +EXPORT_SYMBOL vmlinux 0x8b57e096 gnet_stats_copy_app +EXPORT_SYMBOL vmlinux 0x8b5f3ffd blk_queue_dma_pad +EXPORT_SYMBOL vmlinux 0x8b618d08 overflowuid +EXPORT_SYMBOL vmlinux 0x8b660e49 mpage_bio_submit +EXPORT_SYMBOL vmlinux 0x8b7b56fd dma_async_device_unregister +EXPORT_SYMBOL vmlinux 0x8b83b2a1 scsicam_bios_param +EXPORT_SYMBOL vmlinux 0x8b8f90f1 is_bad_inode +EXPORT_SYMBOL vmlinux 0x8b989cf9 acpi_bus_can_wakeup +EXPORT_SYMBOL vmlinux 0x8bd062f7 seq_open_private +EXPORT_SYMBOL vmlinux 0x8bd19d42 tcp_proc_unregister +EXPORT_SYMBOL vmlinux 0x8bf8051b sk_alloc +EXPORT_SYMBOL vmlinux 0x8c0576ab bio_integrity_enabled +EXPORT_SYMBOL vmlinux 0x8c183cbe iowrite16 +EXPORT_SYMBOL vmlinux 0x8c268b15 fb_find_mode +EXPORT_SYMBOL vmlinux 0x8c2893b1 start_tty +EXPORT_SYMBOL vmlinux 0x8c2902dc __skb_checksum_complete +EXPORT_SYMBOL vmlinux 0x8c78cb54 netif_carrier_on +EXPORT_SYMBOL vmlinux 0x8c9994f6 journal_get_create_access +EXPORT_SYMBOL vmlinux 0x8c9b65bc llc_build_and_send_ui_pkt +EXPORT_SYMBOL vmlinux 0x8c9caf3c vfs_set_dqinfo +EXPORT_SYMBOL vmlinux 0x8c9ef6a6 scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0x8cc226bb simple_lookup +EXPORT_SYMBOL vmlinux 0x8cc79cab iowrite16_rep +EXPORT_SYMBOL vmlinux 0x8d0841ee unregister_con_driver +EXPORT_SYMBOL vmlinux 0x8d0a14ce key_type_keyring +EXPORT_SYMBOL vmlinux 0x8d0af735 nla_put_nohdr +EXPORT_SYMBOL vmlinux 0x8d1f39d4 tty_register_driver +EXPORT_SYMBOL vmlinux 0x8d20a086 pci_enable_device_io +EXPORT_SYMBOL vmlinux 0x8d2d95c1 init_task +EXPORT_SYMBOL vmlinux 0x8d2f04e9 skb_trim +EXPORT_SYMBOL vmlinux 0x8d37f690 mca_device_read_stored_pos +EXPORT_SYMBOL vmlinux 0x8d3894f2 _ctype +EXPORT_SYMBOL vmlinux 0x8d3da283 dma_ops +EXPORT_SYMBOL vmlinux 0x8d4c9b61 mca_register_driver +EXPORT_SYMBOL vmlinux 0x8d551bef sysctl_tcp_rmem +EXPORT_SYMBOL vmlinux 0x8d6f81b4 __div64_32 +EXPORT_SYMBOL vmlinux 0x8d7d2043 jbd2_journal_load +EXPORT_SYMBOL vmlinux 0x8d861acc blk_queue_start_tag +EXPORT_SYMBOL vmlinux 0x8d8d7432 __splice_from_pipe +EXPORT_SYMBOL vmlinux 0x8d8d96c6 acpi_get_sleep_type_data +EXPORT_SYMBOL vmlinux 0x8da234c0 dm_kcopyd_copy +EXPORT_SYMBOL vmlinux 0x8db456eb d_instantiate_unique +EXPORT_SYMBOL vmlinux 0x8dc6e564 restore_processor_state +EXPORT_SYMBOL vmlinux 0x8dca832f __percpu_counter_sum +EXPORT_SYMBOL vmlinux 0x8dcdd743 tcp_simple_retransmit +EXPORT_SYMBOL vmlinux 0x8e002cda acpi_remove_gpe_block +EXPORT_SYMBOL vmlinux 0x8e0637ba i8253_lock +EXPORT_SYMBOL vmlinux 0x8e0b7743 ipv6_ext_hdr +EXPORT_SYMBOL vmlinux 0x8e763ae1 send_remote_softirq +EXPORT_SYMBOL vmlinux 0x8e818d1e kmem_ptr_validate +EXPORT_SYMBOL vmlinux 0x8e88e530 get_disk +EXPORT_SYMBOL vmlinux 0x8eea456c pci_setup_cardbus +EXPORT_SYMBOL vmlinux 0x8ef05955 bitmap_startwrite +EXPORT_SYMBOL vmlinux 0x8ef29a16 inet6_bind +EXPORT_SYMBOL vmlinux 0x8efccb5f xfrm_alloc_spi +EXPORT_SYMBOL vmlinux 0x8f000627 get_empty_filp +EXPORT_SYMBOL vmlinux 0x8f16772a alloc_file +EXPORT_SYMBOL vmlinux 0x8f390a9d tcf_em_tree_dump +EXPORT_SYMBOL vmlinux 0x8f435ba4 nf_hook_slow +EXPORT_SYMBOL vmlinux 0x8f61ac9d ethtool_op_get_link +EXPORT_SYMBOL vmlinux 0x8f6b7950 set_irq_data +EXPORT_SYMBOL vmlinux 0x8f7140eb bdi_set_max_ratio +EXPORT_SYMBOL vmlinux 0x8f9c199c __get_user_2 +EXPORT_SYMBOL vmlinux 0x8fb477e4 sk_reset_timer +EXPORT_SYMBOL vmlinux 0x8ffdb3b8 crc16 +EXPORT_SYMBOL vmlinux 0x90035333 secure_tcpv6_sequence_number +EXPORT_SYMBOL vmlinux 0x900b610a bt_sock_unlink +EXPORT_SYMBOL vmlinux 0x902c142e __scsi_add_device +EXPORT_SYMBOL vmlinux 0x902f6098 d_splice_alias +EXPORT_SYMBOL vmlinux 0x9044f70e skb_insert +EXPORT_SYMBOL vmlinux 0x90466ff6 bdget_disk +EXPORT_SYMBOL vmlinux 0x906d76bf icmpv6_send +EXPORT_SYMBOL vmlinux 0x90728a55 console_start +EXPORT_SYMBOL vmlinux 0x907d3d86 pci_do_scan_bus +EXPORT_SYMBOL vmlinux 0x908ded97 nlmsg_notify +EXPORT_SYMBOL vmlinux 0x90a1601f dmi_check_system +EXPORT_SYMBOL vmlinux 0x90a4343e textsearch_destroy +EXPORT_SYMBOL vmlinux 0x90a943ba nmi_active +EXPORT_SYMBOL vmlinux 0x90b4aaa3 proc_symlink +EXPORT_SYMBOL vmlinux 0x90d5bd59 netdev_features_change +EXPORT_SYMBOL vmlinux 0x90e86dde blk_queue_softirq_done +EXPORT_SYMBOL vmlinux 0x90eafd44 blk_get_request +EXPORT_SYMBOL vmlinux 0x9134e47c jbd2_journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x9138bb6a mmc_free_host +EXPORT_SYMBOL vmlinux 0x9144a8e2 ec_burst_disable +EXPORT_SYMBOL vmlinux 0x91481982 __ratelimit +EXPORT_SYMBOL vmlinux 0x91607d95 set_memory_wb +EXPORT_SYMBOL vmlinux 0x919f8fbc uart_suspend_port +EXPORT_SYMBOL vmlinux 0x91ca8959 acpi_get_register +EXPORT_SYMBOL vmlinux 0x91d6df07 pci_choose_state +EXPORT_SYMBOL vmlinux 0x91e04ea0 unregister_sysctl_table +EXPORT_SYMBOL vmlinux 0x91f476dc sock_no_poll +EXPORT_SYMBOL vmlinux 0x9202b27f task_tgid_nr_ns +EXPORT_SYMBOL vmlinux 0x922b9eaf pnp_disable_dev +EXPORT_SYMBOL vmlinux 0x922ff447 eisa_bus_type +EXPORT_SYMBOL vmlinux 0x924011d6 __bforget +EXPORT_SYMBOL vmlinux 0x92549b69 mdiobus_free +EXPORT_SYMBOL vmlinux 0x92888bec sock_no_ioctl +EXPORT_SYMBOL vmlinux 0x92897e3d default_idle +EXPORT_SYMBOL vmlinux 0x9299ea0b scsi_nonblockable_ioctl +EXPORT_SYMBOL vmlinux 0x92a73aac phy_register_fixup_for_uid +EXPORT_SYMBOL vmlinux 0x92a90241 seq_bitmap_list +EXPORT_SYMBOL vmlinux 0x92c28753 pci_bus_read_config_word +EXPORT_SYMBOL vmlinux 0x930268c9 __scm_destroy +EXPORT_SYMBOL vmlinux 0x9305e6b3 skb_unlink +EXPORT_SYMBOL vmlinux 0x9305f8e6 cpufreq_get +EXPORT_SYMBOL vmlinux 0x9328f5a7 register_con_driver +EXPORT_SYMBOL vmlinux 0x932c2752 tty_vhangup +EXPORT_SYMBOL vmlinux 0x9330cb9f sg_alloc_table +EXPORT_SYMBOL vmlinux 0x933c2fe5 ethtool_op_get_tso +EXPORT_SYMBOL vmlinux 0x93763e34 unregister_cdrom +EXPORT_SYMBOL vmlinux 0x938131d9 skb_add_rx_frag +EXPORT_SYMBOL vmlinux 0x938d57b7 kmap +EXPORT_SYMBOL vmlinux 0x93a6e0b2 io_schedule +EXPORT_SYMBOL vmlinux 0x93afa72e vm_get_page_prot +EXPORT_SYMBOL vmlinux 0x93b8ef56 mutex_lock_interruptible +EXPORT_SYMBOL vmlinux 0x93c69acf param_set_byte +EXPORT_SYMBOL vmlinux 0x93cbd1ec _spin_lock_bh +EXPORT_SYMBOL vmlinux 0x93f2cdf0 tcp_prot +EXPORT_SYMBOL vmlinux 0x93fca811 __get_free_pages +EXPORT_SYMBOL vmlinux 0x9401cef6 kernel_read +EXPORT_SYMBOL vmlinux 0x9422df43 scsi_scan_target +EXPORT_SYMBOL vmlinux 0x9424df1c init_net +EXPORT_SYMBOL vmlinux 0x942a9eb0 __scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0x948bc806 iunique +EXPORT_SYMBOL vmlinux 0x948c12a2 create_empty_buffers +EXPORT_SYMBOL vmlinux 0x948f29e7 mmc_resume_host +EXPORT_SYMBOL vmlinux 0x94961283 vunmap +EXPORT_SYMBOL vmlinux 0x94c0ecd0 seq_open +EXPORT_SYMBOL vmlinux 0x94fa6a0c tcp_setsockopt +EXPORT_SYMBOL vmlinux 0x94fcf08e bioset_create +EXPORT_SYMBOL vmlinux 0x9505e7a9 wait_on_sync_kiocb +EXPORT_SYMBOL vmlinux 0x950abbf0 kunmap_high +EXPORT_SYMBOL vmlinux 0x951e4d06 blk_queue_update_dma_alignment +EXPORT_SYMBOL vmlinux 0x952482b2 xfrm_policy_delete +EXPORT_SYMBOL vmlinux 0x954488a4 syncookie_secret +EXPORT_SYMBOL vmlinux 0x9545af6d tasklet_init +EXPORT_SYMBOL vmlinux 0x954c8af3 dm_io_client_destroy +EXPORT_SYMBOL vmlinux 0x954cbb26 vsprintf +EXPORT_SYMBOL vmlinux 0x9550ebfc pci_add_new_bus +EXPORT_SYMBOL vmlinux 0x956fe037 bio_integrity_get_tag +EXPORT_SYMBOL vmlinux 0x95871d5d gnet_stats_start_copy_compat +EXPORT_SYMBOL vmlinux 0x958cee6e ipv6_skip_exthdr +EXPORT_SYMBOL vmlinux 0x958d3219 bio_uncopy_user +EXPORT_SYMBOL vmlinux 0x958fa1d0 bdi_unregister +EXPORT_SYMBOL vmlinux 0x9594e729 poll_initwait +EXPORT_SYMBOL vmlinux 0x95a95f06 atm_alloc_charge +EXPORT_SYMBOL vmlinux 0x95be4f07 input_register_device +EXPORT_SYMBOL vmlinux 0x95cec6ec inet6_register_protosw +EXPORT_SYMBOL vmlinux 0x95eaba58 mca_unregister_driver +EXPORT_SYMBOL vmlinux 0x95ef4a39 pci_restore_state +EXPORT_SYMBOL vmlinux 0x95f638d5 posix_acl_chmod_masq +EXPORT_SYMBOL vmlinux 0x9615d1df d_validate +EXPORT_SYMBOL vmlinux 0x9634498a rfkill_allocate +EXPORT_SYMBOL vmlinux 0x96481cc7 per_cpu__x86_cpu_to_apicid +EXPORT_SYMBOL vmlinux 0x96898769 sysfs_format_mac +EXPORT_SYMBOL vmlinux 0x96962202 pci_lost_interrupt +EXPORT_SYMBOL vmlinux 0x96c10dd7 blkdev_issue_discard +EXPORT_SYMBOL vmlinux 0x96cd2b04 scsi_sense_key_string +EXPORT_SYMBOL vmlinux 0x97031de3 bitmap_close_sync +EXPORT_SYMBOL vmlinux 0x97138a6a skb_make_writable +EXPORT_SYMBOL vmlinux 0x97149a92 sync_dirty_buffer +EXPORT_SYMBOL vmlinux 0x971d9c3d jbd2_journal_check_used_features +EXPORT_SYMBOL vmlinux 0x972030d5 scsi_device_set_state +EXPORT_SYMBOL vmlinux 0x972574c8 kmem_cache_alloc +EXPORT_SYMBOL vmlinux 0x97260524 generic_file_aio_read +EXPORT_SYMBOL vmlinux 0x973873ab _spin_lock +EXPORT_SYMBOL vmlinux 0x9751cb13 tcp_hashinfo +EXPORT_SYMBOL vmlinux 0x9754ec10 radix_tree_preload +EXPORT_SYMBOL vmlinux 0x9781aff8 unlock_buffer +EXPORT_SYMBOL vmlinux 0x97adea39 iget5_locked +EXPORT_SYMBOL vmlinux 0x97ae9397 scsi_is_sdev_device +EXPORT_SYMBOL vmlinux 0x97d3b5a0 neigh_sysctl_unregister +EXPORT_SYMBOL vmlinux 0x97de0ddd acpi_install_gpe_block +EXPORT_SYMBOL vmlinux 0x981026f6 km_report +EXPORT_SYMBOL vmlinux 0x9855ce91 i2c_release_client +EXPORT_SYMBOL vmlinux 0x986e6135 fb_pad_unaligned_buffer +EXPORT_SYMBOL vmlinux 0x98884059 pnp_register_driver +EXPORT_SYMBOL vmlinux 0x988ed85d set_memory_x +EXPORT_SYMBOL vmlinux 0x989cc325 write_inode_now +EXPORT_SYMBOL vmlinux 0x989d8dee skb_copy_bits +EXPORT_SYMBOL vmlinux 0x98b5b8b1 vfs_dq_transfer +EXPORT_SYMBOL vmlinux 0x98e301fc sk_wait_data +EXPORT_SYMBOL vmlinux 0x98ffc3ac register_sysctl_table +EXPORT_SYMBOL vmlinux 0x99052a84 acpi_os_write_port +EXPORT_SYMBOL vmlinux 0x9906428d kill_block_super +EXPORT_SYMBOL vmlinux 0x9912cd3f tr_type_trans +EXPORT_SYMBOL vmlinux 0x991d00bb fib_default_rule_add +EXPORT_SYMBOL vmlinux 0x9938895e ps2_cmd_aborted +EXPORT_SYMBOL vmlinux 0x996c9cd4 dst_discard +EXPORT_SYMBOL vmlinux 0x9980231d vfs_llseek +EXPORT_SYMBOL vmlinux 0x998207f7 dev_alloc_name +EXPORT_SYMBOL vmlinux 0x9994c0ca ps2_is_keyboard_id +EXPORT_SYMBOL vmlinux 0x999e8297 vfree +EXPORT_SYMBOL vmlinux 0x99a67669 d_alloc +EXPORT_SYMBOL vmlinux 0x99aadb21 param_get_ulong +EXPORT_SYMBOL vmlinux 0x99abb57a tty_devnum +EXPORT_SYMBOL vmlinux 0x99bfbe39 get_unused_fd +EXPORT_SYMBOL vmlinux 0x99c3c0b0 vfs_fstat +EXPORT_SYMBOL vmlinux 0x99cdc86b sysctl_tcp_reordering +EXPORT_SYMBOL vmlinux 0x99ea12ce panic_blink +EXPORT_SYMBOL vmlinux 0x9a154bf4 framebuffer_release +EXPORT_SYMBOL vmlinux 0x9a1dfd65 strpbrk +EXPORT_SYMBOL vmlinux 0x9a2d8fe4 netlink_dump_start +EXPORT_SYMBOL vmlinux 0x9a4642bf scsi_get_command +EXPORT_SYMBOL vmlinux 0x9a505cbb dev_disable_lro +EXPORT_SYMBOL vmlinux 0x9a6a83f9 cmos_lock +EXPORT_SYMBOL vmlinux 0x9a6eb5ba per_cpu__cpu_core_map +EXPORT_SYMBOL vmlinux 0x9a9985be percpu_counter_destroy +EXPORT_SYMBOL vmlinux 0x9ac72c28 thermal_zone_device_register +EXPORT_SYMBOL vmlinux 0x9ae07617 pci_disable_msix +EXPORT_SYMBOL vmlinux 0x9b15ed6f md_write_start +EXPORT_SYMBOL vmlinux 0x9b388444 get_zeroed_page +EXPORT_SYMBOL vmlinux 0x9b4a7813 dmam_pool_create +EXPORT_SYMBOL vmlinux 0x9b4c33f4 phy_register_fixup +EXPORT_SYMBOL vmlinux 0x9b4de8eb idr_replace +EXPORT_SYMBOL vmlinux 0x9ba7089d argv_split +EXPORT_SYMBOL vmlinux 0x9bce482f __release_region +EXPORT_SYMBOL vmlinux 0x9bd3cd93 blkdev_dequeue_request +EXPORT_SYMBOL vmlinux 0x9be6ecaf llc_sap_find +EXPORT_SYMBOL vmlinux 0x9bee14f3 acpi_bus_generate_proc_event +EXPORT_SYMBOL vmlinux 0x9c012508 fb_parse_edid +EXPORT_SYMBOL vmlinux 0x9c114661 simple_pin_fs +EXPORT_SYMBOL vmlinux 0x9c22a4b8 inet_frag_evictor +EXPORT_SYMBOL vmlinux 0x9c231196 scsi_mode_sense +EXPORT_SYMBOL vmlinux 0x9c23181a dquot_alloc_inode +EXPORT_SYMBOL vmlinux 0x9c2c944a __copy_from_user_ll_nocache_nozero +EXPORT_SYMBOL vmlinux 0x9c5413c3 pci_map_rom +EXPORT_SYMBOL vmlinux 0x9c5e1c17 audit_log_start +EXPORT_SYMBOL vmlinux 0x9c6ebf5e release_sock +EXPORT_SYMBOL vmlinux 0x9c7077bd enable_hlt +EXPORT_SYMBOL vmlinux 0x9c9c868c file_remove_suid +EXPORT_SYMBOL vmlinux 0x9ca1a8ef wake_up_process +EXPORT_SYMBOL vmlinux 0x9cb96e92 qdisc_put_rtab +EXPORT_SYMBOL vmlinux 0x9cc36965 fb_set_suspend +EXPORT_SYMBOL vmlinux 0x9ccb2622 finish_wait +EXPORT_SYMBOL vmlinux 0x9ceb163c memcpy_toiovec +EXPORT_SYMBOL vmlinux 0x9ced38aa down_trylock +EXPORT_SYMBOL vmlinux 0x9cfd56c5 scsi_print_status +EXPORT_SYMBOL vmlinux 0x9d33ef5e acpi_enable +EXPORT_SYMBOL vmlinux 0x9d5b7d34 pnp_possible_config +EXPORT_SYMBOL vmlinux 0x9d5ddd39 inode_add_bytes +EXPORT_SYMBOL vmlinux 0x9d711f1f percpu_counter_init +EXPORT_SYMBOL vmlinux 0x9d9f0d41 rwsem_down_write_failed +EXPORT_SYMBOL vmlinux 0x9da143e3 cdrom_mode_select +EXPORT_SYMBOL vmlinux 0x9dad2ca1 __scsi_put_command +EXPORT_SYMBOL vmlinux 0x9dae1996 pci_bus_alloc_resource +EXPORT_SYMBOL vmlinux 0x9db1279e scsi_host_alloc +EXPORT_SYMBOL vmlinux 0x9dd405fd __xfrm_state_destroy +EXPORT_SYMBOL vmlinux 0x9e050226 arch_acpi_processor_init_pdc +EXPORT_SYMBOL vmlinux 0x9e09129f invalidate_inode_buffers +EXPORT_SYMBOL vmlinux 0x9e329fc0 ip_setsockopt +EXPORT_SYMBOL vmlinux 0x9e363b6b acpi_disable_gpe +EXPORT_SYMBOL vmlinux 0x9e3cc838 devm_ioport_unmap +EXPORT_SYMBOL vmlinux 0x9e4a6835 bitmap_unplug +EXPORT_SYMBOL vmlinux 0x9e64fbfe rtc_cmos_read +EXPORT_SYMBOL vmlinux 0x9e672ff6 scsi_kmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x9e76c472 get_super +EXPORT_SYMBOL vmlinux 0x9e7d6bd0 __udelay +EXPORT_SYMBOL vmlinux 0x9e890792 tcf_exts_dump_stats +EXPORT_SYMBOL vmlinux 0x9e89c7f9 vfs_mknod +EXPORT_SYMBOL vmlinux 0x9eaa12e7 dec_zone_page_state +EXPORT_SYMBOL vmlinux 0x9ec87c2d iget_locked +EXPORT_SYMBOL vmlinux 0x9ed685ee iov_iter_advance +EXPORT_SYMBOL vmlinux 0x9eecde16 do_brk +EXPORT_SYMBOL vmlinux 0x9ef23af6 sock_no_accept +EXPORT_SYMBOL vmlinux 0x9ef42842 pnp_unregister_card_driver +EXPORT_SYMBOL vmlinux 0x9ef749e2 unregister_chrdev +EXPORT_SYMBOL vmlinux 0x9f0ba79e dma_mark_declared_memory_occupied +EXPORT_SYMBOL vmlinux 0x9f100139 jiffies_to_clock_t +EXPORT_SYMBOL vmlinux 0x9f2bdaac __bitmap_or +EXPORT_SYMBOL vmlinux 0x9f7c0c35 new_inode +EXPORT_SYMBOL vmlinux 0x9f984513 strrchr +EXPORT_SYMBOL vmlinux 0x9fa274b4 dq_data_lock +EXPORT_SYMBOL vmlinux 0x9fb3dd30 memcpy_fromiovec +EXPORT_SYMBOL vmlinux 0x9fc5e57e acpi_unlock_battery_dir +EXPORT_SYMBOL vmlinux 0x9fcaa970 netlink_broadcast +EXPORT_SYMBOL vmlinux 0x9fdbc8cf dm_kcopyd_client_destroy +EXPORT_SYMBOL vmlinux 0x9feaf287 sonet_subtract_stats +EXPORT_SYMBOL vmlinux 0x9fec4b5e d_lookup +EXPORT_SYMBOL vmlinux 0xa0238053 sock_register +EXPORT_SYMBOL vmlinux 0xa03523d5 security_unix_stream_connect +EXPORT_SYMBOL vmlinux 0xa04a01bd qdisc_class_hash_insert +EXPORT_SYMBOL vmlinux 0xa05c03df mempool_kmalloc +EXPORT_SYMBOL vmlinux 0xa06f8cfa i2c_smbus_process_call +EXPORT_SYMBOL vmlinux 0xa07f5904 deactivate_super +EXPORT_SYMBOL vmlinux 0xa0b04675 vmalloc_32 +EXPORT_SYMBOL vmlinux 0xa0c47221 netpoll_poll +EXPORT_SYMBOL vmlinux 0xa0cb8851 phy_scan_fixups +EXPORT_SYMBOL vmlinux 0xa0ceef51 out_of_line_wait_on_bit +EXPORT_SYMBOL vmlinux 0xa0d80355 bt_sock_ioctl +EXPORT_SYMBOL vmlinux 0xa0fbac79 wake_up_bit +EXPORT_SYMBOL vmlinux 0xa108eb4d sysctl_optmem_max +EXPORT_SYMBOL vmlinux 0xa10dcc13 getrawmonotonic +EXPORT_SYMBOL vmlinux 0xa120d33c tty_unregister_ldisc +EXPORT_SYMBOL vmlinux 0xa124dcff inet_dev_addr_type +EXPORT_SYMBOL vmlinux 0xa13798f8 printk_ratelimit +EXPORT_SYMBOL vmlinux 0xa13ce72d mb_cache_create +EXPORT_SYMBOL vmlinux 0xa13f4b3f __scsi_iterate_devices +EXPORT_SYMBOL vmlinux 0xa157c5e4 scsi_calculate_bounce_limit +EXPORT_SYMBOL vmlinux 0xa1a20fa1 task_session_nr_ns +EXPORT_SYMBOL vmlinux 0xa1b759ce fb_add_videomode +EXPORT_SYMBOL vmlinux 0xa1c76e0a _cond_resched +EXPORT_SYMBOL vmlinux 0xa1dc3757 sb_min_blocksize +EXPORT_SYMBOL vmlinux 0xa1dd25fd simple_rename +EXPORT_SYMBOL vmlinux 0xa1ed7439 serial8250_register_port +EXPORT_SYMBOL vmlinux 0xa2076e8a redraw_screen +EXPORT_SYMBOL vmlinux 0xa20ce1b8 net_msg_warn +EXPORT_SYMBOL vmlinux 0xa217d065 dma_async_device_register +EXPORT_SYMBOL vmlinux 0xa2186ab8 invalidate_mapping_pages +EXPORT_SYMBOL vmlinux 0xa2a1e5c9 _write_lock_bh +EXPORT_SYMBOL vmlinux 0xa2a277f3 sk_run_filter +EXPORT_SYMBOL vmlinux 0xa2a5fd77 inet_ehash_secret +EXPORT_SYMBOL vmlinux 0xa2bd867f tty_check_change +EXPORT_SYMBOL vmlinux 0xa2f27b16 pci_try_set_mwi +EXPORT_SYMBOL vmlinux 0xa2f6de45 blk_sync_queue +EXPORT_SYMBOL vmlinux 0xa2fee563 udp_proc_register +EXPORT_SYMBOL vmlinux 0xa301c5ec pci_find_parent_resource +EXPORT_SYMBOL vmlinux 0xa316799c hci_register_proto +EXPORT_SYMBOL vmlinux 0xa329f07e register_shrinker +EXPORT_SYMBOL vmlinux 0xa34f1ef5 crc32_le +EXPORT_SYMBOL vmlinux 0xa350a8f8 set_memory_array_uc +EXPORT_SYMBOL vmlinux 0xa352798e generic_block_bmap +EXPORT_SYMBOL vmlinux 0xa35c1f05 acpi_extract_package +EXPORT_SYMBOL vmlinux 0xa35de80f ipv4_config +EXPORT_SYMBOL vmlinux 0xa3a6a372 find_task_by_pid_type_ns +EXPORT_SYMBOL vmlinux 0xa3ab7a5a skb_append +EXPORT_SYMBOL vmlinux 0xa3bbcd80 acpi_set_gpe_type +EXPORT_SYMBOL vmlinux 0xa3d19b6b scsi_test_unit_ready +EXPORT_SYMBOL vmlinux 0xa3db164e inet6_del_protocol +EXPORT_SYMBOL vmlinux 0xa3e4ba8d blk_integrity_unregister +EXPORT_SYMBOL vmlinux 0xa3ea2b0e filemap_fdatawrite_range +EXPORT_SYMBOL vmlinux 0xa422b36f kset_register +EXPORT_SYMBOL vmlinux 0xa44072fc posix_acl_alloc +EXPORT_SYMBOL vmlinux 0xa44ad274 wait_for_completion_interruptible_timeout +EXPORT_SYMBOL vmlinux 0xa453a998 elv_rb_find +EXPORT_SYMBOL vmlinux 0xa469c3ce vfs_dq_quota_on_remount +EXPORT_SYMBOL vmlinux 0xa48a9643 netdev_class_remove_file +EXPORT_SYMBOL vmlinux 0xa498eb02 seq_escape +EXPORT_SYMBOL vmlinux 0xa4b18a12 md_wakeup_thread +EXPORT_SYMBOL vmlinux 0xa4b8139a sock_no_listen +EXPORT_SYMBOL vmlinux 0xa4b94fea iowrite8_rep +EXPORT_SYMBOL vmlinux 0xa4c621e7 blk_rq_map_user +EXPORT_SYMBOL vmlinux 0xa4cb2c6b cdrom_media_changed +EXPORT_SYMBOL vmlinux 0xa4d98c46 netdev_class_create_file +EXPORT_SYMBOL vmlinux 0xa4df1151 kref_set +EXPORT_SYMBOL vmlinux 0xa5162979 cdrom_get_last_written +EXPORT_SYMBOL vmlinux 0xa51cdfe8 __FIXADDR_TOP +EXPORT_SYMBOL vmlinux 0xa530838f register_chrdev +EXPORT_SYMBOL vmlinux 0xa530faae touch_atime +EXPORT_SYMBOL vmlinux 0xa5373be6 kobject_del +EXPORT_SYMBOL vmlinux 0xa538b48a pnp_find_dev +EXPORT_SYMBOL vmlinux 0xa53fc020 init_buffer +EXPORT_SYMBOL vmlinux 0xa5423cc4 param_get_int +EXPORT_SYMBOL vmlinux 0xa545b717 jbd2_journal_init_jbd_inode +EXPORT_SYMBOL vmlinux 0xa5693df7 posix_acl_clone +EXPORT_SYMBOL vmlinux 0xa56f1315 mempool_free +EXPORT_SYMBOL vmlinux 0xa5889994 pci_dev_put +EXPORT_SYMBOL vmlinux 0xa58b6804 nla_parse +EXPORT_SYMBOL vmlinux 0xa5922bb1 kfifo_init +EXPORT_SYMBOL vmlinux 0xa598e29c vesa_modes +EXPORT_SYMBOL vmlinux 0xa5a633b9 sg_last +EXPORT_SYMBOL vmlinux 0xa5bb5e7e scsi_set_medium_removal +EXPORT_SYMBOL vmlinux 0xa5caeb68 pnp_activate_dev +EXPORT_SYMBOL vmlinux 0xa5cef8ad release_resource +EXPORT_SYMBOL vmlinux 0xa5d029a9 dquot_free_space +EXPORT_SYMBOL vmlinux 0xa5da0abd acpi_enter_sleep_state_s4bios +EXPORT_SYMBOL vmlinux 0xa5ee05ec d_instantiate +EXPORT_SYMBOL vmlinux 0xa601a0e2 ip_xfrm_me_harder +EXPORT_SYMBOL vmlinux 0xa60f093c journal_init_inode +EXPORT_SYMBOL vmlinux 0xa619684b pskb_expand_head +EXPORT_SYMBOL vmlinux 0xa6265113 neigh_seq_stop +EXPORT_SYMBOL vmlinux 0xa63d85ab slhc_remember +EXPORT_SYMBOL vmlinux 0xa645b566 ps2_drain +EXPORT_SYMBOL vmlinux 0xa6484eae smp_call_function_mask +EXPORT_SYMBOL vmlinux 0xa68124fa hweight8 +EXPORT_SYMBOL vmlinux 0xa6814433 groups_free +EXPORT_SYMBOL vmlinux 0xa681fe88 generate_random_uuid +EXPORT_SYMBOL vmlinux 0xa68c9c1b netlink_ack +EXPORT_SYMBOL vmlinux 0xa6dcc773 rb_insert_color +EXPORT_SYMBOL vmlinux 0xa6e615b7 read_cache_pages +EXPORT_SYMBOL vmlinux 0xa6ed791f __lock_page +EXPORT_SYMBOL vmlinux 0xa7046549 vprintk +EXPORT_SYMBOL vmlinux 0xa70fabbe release_evntsel_nmi +EXPORT_SYMBOL vmlinux 0xa72f881d dma_pool_free +EXPORT_SYMBOL vmlinux 0xa7384fb9 i2c_clients_command +EXPORT_SYMBOL vmlinux 0xa7502f48 jiffies_to_timeval +EXPORT_SYMBOL vmlinux 0xa768bc14 sk_stream_write_space +EXPORT_SYMBOL vmlinux 0xa770b803 kblockd_flush_work +EXPORT_SYMBOL vmlinux 0xa77a5e3b tcp_v4_md5_hash_skb +EXPORT_SYMBOL vmlinux 0xa7c35c6b getnstimeofday +EXPORT_SYMBOL vmlinux 0xa7d47d2a br_handle_frame_hook +EXPORT_SYMBOL vmlinux 0xa83322e0 audit_log_end +EXPORT_SYMBOL vmlinux 0xa860bd96 dev_unicast_add +EXPORT_SYMBOL vmlinux 0xa8618efe path_permission +EXPORT_SYMBOL vmlinux 0xa86aa3fe pci_enable_device +EXPORT_SYMBOL vmlinux 0xa88bcb5f tcp_read_sock +EXPORT_SYMBOL vmlinux 0xa89acbb3 acpi_evaluate_reference +EXPORT_SYMBOL vmlinux 0xa8a039e4 __bio_clone +EXPORT_SYMBOL vmlinux 0xa8a395e5 bio_clone +EXPORT_SYMBOL vmlinux 0xa8c7c929 netif_carrier_off +EXPORT_SYMBOL vmlinux 0xa8e681de bio_copy_kern +EXPORT_SYMBOL vmlinux 0xa8fef7bb security_unix_may_send +EXPORT_SYMBOL vmlinux 0xa90e1105 blk_queue_hardsect_size +EXPORT_SYMBOL vmlinux 0xa912774b pci_get_bus_and_slot +EXPORT_SYMBOL vmlinux 0xa915fb35 llc_mac_hdr_init +EXPORT_SYMBOL vmlinux 0xa91b5561 acpi_video_backlight_support +EXPORT_SYMBOL vmlinux 0xa925899a param_set_bool +EXPORT_SYMBOL vmlinux 0xa92bba38 cpufreq_get_policy +EXPORT_SYMBOL vmlinux 0xa948f457 blkdev_get +EXPORT_SYMBOL vmlinux 0xa94c6bf4 sock_wfree +EXPORT_SYMBOL vmlinux 0xa9651009 inet_csk_accept +EXPORT_SYMBOL vmlinux 0xa995e48c sk_common_release +EXPORT_SYMBOL vmlinux 0xa9a14377 unregister_key_type +EXPORT_SYMBOL vmlinux 0xa9ca656d cfb_copyarea +EXPORT_SYMBOL vmlinux 0xa9d479df hci_conn_check_link_mode +EXPORT_SYMBOL vmlinux 0xa9d85236 pci_request_region +EXPORT_SYMBOL vmlinux 0xa9e56605 set_irq_chip +EXPORT_SYMBOL vmlinux 0xa9fcf31d wait_for_completion_interruptible +EXPORT_SYMBOL vmlinux 0xaa024146 sonet_copy_stats +EXPORT_SYMBOL vmlinux 0xaa549e1b md_done_sync +EXPORT_SYMBOL vmlinux 0xaa7ce124 xfrm_register_mode +EXPORT_SYMBOL vmlinux 0xaa84a8ae acpi_processor_power_init_bm_check +EXPORT_SYMBOL vmlinux 0xaa8ab19e cpu_online_map +EXPORT_SYMBOL vmlinux 0xaaaed6c1 input_allocate_device +EXPORT_SYMBOL vmlinux 0xaab06af8 _write_lock_irqsave +EXPORT_SYMBOL vmlinux 0xaac88b01 pci_assign_resource +EXPORT_SYMBOL vmlinux 0xaae20937 tcp_connect +EXPORT_SYMBOL vmlinux 0xaae8ab0e acpi_bus_power_manageable +EXPORT_SYMBOL vmlinux 0xaaebe34f mca_write_pos +EXPORT_SYMBOL vmlinux 0xaaf2fe8d kernel_recvmsg +EXPORT_SYMBOL vmlinux 0xaafd17f9 sg_miter_start +EXPORT_SYMBOL vmlinux 0xaafdc258 strcasecmp +EXPORT_SYMBOL vmlinux 0xaaffb9a5 acpi_bus_private_data_handler +EXPORT_SYMBOL vmlinux 0xab347b8b generic_cont_expand_simple +EXPORT_SYMBOL vmlinux 0xab471003 param_array_set +EXPORT_SYMBOL vmlinux 0xab600421 probe_irq_off +EXPORT_SYMBOL vmlinux 0xab65ed80 set_memory_uc +EXPORT_SYMBOL vmlinux 0xab6e3ec8 datagram_poll +EXPORT_SYMBOL vmlinux 0xabca722c tty_port_free_xmit_buf +EXPORT_SYMBOL vmlinux 0xabd0c91c rtc_time_to_tm +EXPORT_SYMBOL vmlinux 0xabd898ca nobh_truncate_page +EXPORT_SYMBOL vmlinux 0xabe9fde3 scsi_track_queue_full +EXPORT_SYMBOL vmlinux 0xabf12c75 bio_integrity_tag_size +EXPORT_SYMBOL vmlinux 0xac0c22b3 skb_gso_segment +EXPORT_SYMBOL vmlinux 0xac3b3cee __bitmap_and +EXPORT_SYMBOL vmlinux 0xac3f8eaf thaw_bdev +EXPORT_SYMBOL vmlinux 0xac46f498 register_qdisc +EXPORT_SYMBOL vmlinux 0xac58ea5e acpi_unload_table_id +EXPORT_SYMBOL vmlinux 0xac8db263 bio_integrity_alloc_bioset +EXPORT_SYMBOL vmlinux 0xacbbaa74 scsi_remove_host +EXPORT_SYMBOL vmlinux 0xacc1fd13 dcache_dir_open +EXPORT_SYMBOL vmlinux 0xacc2a888 i2c_use_client +EXPORT_SYMBOL vmlinux 0xacc74e42 xfrm_policy_bysel_ctx +EXPORT_SYMBOL vmlinux 0xaccabc6a in4_pton +EXPORT_SYMBOL vmlinux 0xaccf933c unregister_qdisc +EXPORT_SYMBOL vmlinux 0xacd07285 bio_integrity_set_tag +EXPORT_SYMBOL vmlinux 0xacf4d843 match_strdup +EXPORT_SYMBOL vmlinux 0xad0413d4 match_hex +EXPORT_SYMBOL vmlinux 0xad0e0703 d_path +EXPORT_SYMBOL vmlinux 0xad13c689 acpi_os_execute +EXPORT_SYMBOL vmlinux 0xad2e8a01 dump_trace +EXPORT_SYMBOL vmlinux 0xadaa2657 cpufreq_register_notifier +EXPORT_SYMBOL vmlinux 0xae120533 task_pid_nr_ns +EXPORT_SYMBOL vmlinux 0xae4595c5 neigh_seq_next +EXPORT_SYMBOL vmlinux 0xae4e9eb8 user_path_at +EXPORT_SYMBOL vmlinux 0xae6ecdbb scsi_print_result +EXPORT_SYMBOL vmlinux 0xae75f004 ida_destroy +EXPORT_SYMBOL vmlinux 0xae7b452f put_tty_driver +EXPORT_SYMBOL vmlinux 0xaec655c7 alloc_pages_exact +EXPORT_SYMBOL vmlinux 0xaec7783b skb_pad +EXPORT_SYMBOL vmlinux 0xaed66b80 ll_rw_block +EXPORT_SYMBOL vmlinux 0xaee0a5b3 generic_readlink +EXPORT_SYMBOL vmlinux 0xaeec95ba skb_checksum +EXPORT_SYMBOL vmlinux 0xaef03606 inet_dgram_connect +EXPORT_SYMBOL vmlinux 0xaf106d18 acpi_lock_battery_dir +EXPORT_SYMBOL vmlinux 0xaf2f32a4 ip_route_input +EXPORT_SYMBOL vmlinux 0xaf3dd7dc scsi_logging_level +EXPORT_SYMBOL vmlinux 0xaf3e6e7f put_filp +EXPORT_SYMBOL vmlinux 0xaf4b1540 acpi_get_irq_routing_table +EXPORT_SYMBOL vmlinux 0xaf52c2d3 iommu_bio_merge +EXPORT_SYMBOL vmlinux 0xaf5f7c18 udp_poll +EXPORT_SYMBOL vmlinux 0xaf9bfe69 bh_submit_read +EXPORT_SYMBOL vmlinux 0xafa5ca1b netlink_rcv_skb +EXPORT_SYMBOL vmlinux 0xafe01377 down_read +EXPORT_SYMBOL vmlinux 0xb0005b9d mpage_readpages +EXPORT_SYMBOL vmlinux 0xb0394ba1 inet_csk_clear_xmit_timers +EXPORT_SYMBOL vmlinux 0xb047dca9 kthread_create +EXPORT_SYMBOL vmlinux 0xb05d62d0 read_cache_page +EXPORT_SYMBOL vmlinux 0xb077ef32 acpi_enter_sleep_state +EXPORT_SYMBOL vmlinux 0xb07a686a neigh_destroy +EXPORT_SYMBOL vmlinux 0xb07dfb3d acpi_remove_gpe_handler +EXPORT_SYMBOL vmlinux 0xb08f76ad gen_pool_free +EXPORT_SYMBOL vmlinux 0xb0b847ac __bitmap_full +EXPORT_SYMBOL vmlinux 0xb0dc0cad request_firmware_nowait +EXPORT_SYMBOL vmlinux 0xb0e10781 get_option +EXPORT_SYMBOL vmlinux 0xb0f78252 nf_unregister_queue_handler +EXPORT_SYMBOL vmlinux 0xb121390a probe_irq_on +EXPORT_SYMBOL vmlinux 0xb1228d8d bt_sock_poll +EXPORT_SYMBOL vmlinux 0xb136c666 qdisc_tree_decrease_qlen +EXPORT_SYMBOL vmlinux 0xb13ad181 skb_dma_unmap +EXPORT_SYMBOL vmlinux 0xb13c4dba down_write +EXPORT_SYMBOL vmlinux 0xb19760c3 bitmap_onto +EXPORT_SYMBOL vmlinux 0xb1a38c11 jbd2_journal_get_create_access +EXPORT_SYMBOL vmlinux 0xb1c3a01a oops_in_progress +EXPORT_SYMBOL vmlinux 0xb1cdbf7f blk_rq_init +EXPORT_SYMBOL vmlinux 0xb1cfad22 rdmsr_on_cpu +EXPORT_SYMBOL vmlinux 0xb1f975aa unlock_kernel +EXPORT_SYMBOL vmlinux 0xb2017c1d per_cpu__x86_bios_cpu_apicid +EXPORT_SYMBOL vmlinux 0xb2116f6d generic_ro_fops +EXPORT_SYMBOL vmlinux 0xb22fe6a3 netdev_increment_features +EXPORT_SYMBOL vmlinux 0xb279da12 pv_lock_ops +EXPORT_SYMBOL vmlinux 0xb29bc8bd idr_remove +EXPORT_SYMBOL vmlinux 0xb2be638a dma_chan_cleanup +EXPORT_SYMBOL vmlinux 0xb2c724ce free_netdev +EXPORT_SYMBOL vmlinux 0xb2ecb7fb bio_integrity_clone +EXPORT_SYMBOL vmlinux 0xb2efb6be mca_read_stored_pos +EXPORT_SYMBOL vmlinux 0xb2fd5ceb __put_user_4 +EXPORT_SYMBOL vmlinux 0xb3050652 pci_target_state +EXPORT_SYMBOL vmlinux 0xb305353f vfs_readdir +EXPORT_SYMBOL vmlinux 0xb30543ef kmap_atomic +EXPORT_SYMBOL vmlinux 0xb30abf8d idr_get_new_above +EXPORT_SYMBOL vmlinux 0xb312f05a gnet_stats_finish_copy +EXPORT_SYMBOL vmlinux 0xb31526ee sg_copy_from_buffer +EXPORT_SYMBOL vmlinux 0xb31855dd qdisc_watchdog_cancel +EXPORT_SYMBOL vmlinux 0xb31e194c ip_dev_find +EXPORT_SYMBOL vmlinux 0xb3205415 wait_for_completion_killable +EXPORT_SYMBOL vmlinux 0xb3284531 acpi_dbg_layer +EXPORT_SYMBOL vmlinux 0xb34d4c2e acpi_terminate +EXPORT_SYMBOL vmlinux 0xb352177e find_first_bit +EXPORT_SYMBOL vmlinux 0xb3692eb4 ioremap_wc +EXPORT_SYMBOL vmlinux 0xb376d79d radix_tree_tagged +EXPORT_SYMBOL vmlinux 0xb3a307c6 si_meminfo +EXPORT_SYMBOL vmlinux 0xb3b5c118 set_pages_uc +EXPORT_SYMBOL vmlinux 0xb3bbc123 i2c_smbus_read_block_data +EXPORT_SYMBOL vmlinux 0xb3e0590d acpi_set_current_resources +EXPORT_SYMBOL vmlinux 0xb3fae115 blk_cleanup_queue +EXPORT_SYMBOL vmlinux 0xb4012c82 I_BDEV +EXPORT_SYMBOL vmlinux 0xb4034cae generic_file_llseek_unlocked +EXPORT_SYMBOL vmlinux 0xb407bb29 update_region +EXPORT_SYMBOL vmlinux 0xb40baa01 xfrm_find_acq +EXPORT_SYMBOL vmlinux 0xb418dc67 inet_bind +EXPORT_SYMBOL vmlinux 0xb423dba1 console_blanked +EXPORT_SYMBOL vmlinux 0xb429410a posix_acl_from_mode +EXPORT_SYMBOL vmlinux 0xb43408c0 neigh_compat_output +EXPORT_SYMBOL vmlinux 0xb4468f18 lock_may_read +EXPORT_SYMBOL vmlinux 0xb45578b8 memscan +EXPORT_SYMBOL vmlinux 0xb45b24f6 k8_nb_ids +EXPORT_SYMBOL vmlinux 0xb465c120 input_register_handler +EXPORT_SYMBOL vmlinux 0xb4695322 __netdev_alloc_skb +EXPORT_SYMBOL vmlinux 0xb4848fff tcf_exts_change +EXPORT_SYMBOL vmlinux 0xb494e82a br_fdb_put_hook +EXPORT_SYMBOL vmlinux 0xb4aaae55 cont_write_begin +EXPORT_SYMBOL vmlinux 0xb4b9db31 vfs_readv +EXPORT_SYMBOL vmlinux 0xb4ca9447 __kfifo_get +EXPORT_SYMBOL vmlinux 0xb4eaa7b6 jbd2_journal_begin_ordered_truncate +EXPORT_SYMBOL vmlinux 0xb4fb8c7f xfrm_state_register_afinfo +EXPORT_SYMBOL vmlinux 0xb5044271 vsscanf +EXPORT_SYMBOL vmlinux 0xb510ff6f dev_unicast_sync +EXPORT_SYMBOL vmlinux 0xb5185fe8 inet_unregister_protosw +EXPORT_SYMBOL vmlinux 0xb52a0e86 udp_lib_get_port +EXPORT_SYMBOL vmlinux 0xb5372a8c get_unmapped_area +EXPORT_SYMBOL vmlinux 0xb54533f7 usecs_to_jiffies +EXPORT_SYMBOL vmlinux 0xb55b1fb0 blk_free_tags +EXPORT_SYMBOL vmlinux 0xb5656104 genphy_restart_aneg +EXPORT_SYMBOL vmlinux 0xb576bb5f sock_wake_async +EXPORT_SYMBOL vmlinux 0xb59b83c3 elv_rb_del +EXPORT_SYMBOL vmlinux 0xb59c77ad generic_delete_inode +EXPORT_SYMBOL vmlinux 0xb5a459dc unregister_blkdev +EXPORT_SYMBOL vmlinux 0xb5abfb81 journal_init_dev +EXPORT_SYMBOL vmlinux 0xb5aff5e5 proc_dointvec_minmax +EXPORT_SYMBOL vmlinux 0xb5ca1c46 slhc_free +EXPORT_SYMBOL vmlinux 0xb5d52c27 ec_transaction +EXPORT_SYMBOL vmlinux 0xb5f28b5f __any_online_cpu +EXPORT_SYMBOL vmlinux 0xb60e34a8 nla_memcpy +EXPORT_SYMBOL vmlinux 0xb6100390 force_sig +EXPORT_SYMBOL vmlinux 0xb612606f close_bdev_exclusive +EXPORT_SYMBOL vmlinux 0xb678366f int_sqrt +EXPORT_SYMBOL vmlinux 0xb689153c mb_cache_entry_free +EXPORT_SYMBOL vmlinux 0xb6896671 crc_t10dif +EXPORT_SYMBOL vmlinux 0xb68dcfcf vfs_dq_drop +EXPORT_SYMBOL vmlinux 0xb6a61a86 qdisc_get_rtab +EXPORT_SYMBOL vmlinux 0xb6c5a973 scsi_show_result +EXPORT_SYMBOL vmlinux 0xb6cc43be filemap_fdatawait +EXPORT_SYMBOL vmlinux 0xb6e227aa rtc_lock +EXPORT_SYMBOL vmlinux 0xb6ed1e53 strncpy +EXPORT_SYMBOL vmlinux 0xb703911e release_firmware +EXPORT_SYMBOL vmlinux 0xb70e4599 unlock_page +EXPORT_SYMBOL vmlinux 0xb714a981 console_print +EXPORT_SYMBOL vmlinux 0xb71f887c devm_request_irq +EXPORT_SYMBOL vmlinux 0xb72397d5 printk +EXPORT_SYMBOL vmlinux 0xb72f3869 ip_mc_rejoin_group +EXPORT_SYMBOL vmlinux 0xb7350b31 seq_release +EXPORT_SYMBOL vmlinux 0xb7548d92 blk_start_queueing +EXPORT_SYMBOL vmlinux 0xb7555f12 timeval_to_jiffies +EXPORT_SYMBOL vmlinux 0xb758b225 acpi_disable_event +EXPORT_SYMBOL vmlinux 0xb77a9080 cpu_sysdev_class +EXPORT_SYMBOL vmlinux 0xb797666c ethtool_op_set_tso +EXPORT_SYMBOL vmlinux 0xb79ba2f1 ip6_frag_init +EXPORT_SYMBOL vmlinux 0xb7b61546 crc32_be +EXPORT_SYMBOL vmlinux 0xb7c1db6c blk_insert_request +EXPORT_SYMBOL vmlinux 0xb7d13f4d unload_nls +EXPORT_SYMBOL vmlinux 0xb7dc7aa3 dev_get_by_index +EXPORT_SYMBOL vmlinux 0xb7f1739e hci_unregister_cb +EXPORT_SYMBOL vmlinux 0xb7f5c2f8 inode_permission +EXPORT_SYMBOL vmlinux 0xb802a70c mmc_set_data_timeout +EXPORT_SYMBOL vmlinux 0xb80a7467 scsi_ioctl +EXPORT_SYMBOL vmlinux 0xb828c786 per_cpu__cpu_sibling_map +EXPORT_SYMBOL vmlinux 0xb85b2bac vm_stat +EXPORT_SYMBOL vmlinux 0xb86e4ab9 random32 +EXPORT_SYMBOL vmlinux 0xb894926d schedule_work_on +EXPORT_SYMBOL vmlinux 0xb89af9bf srandom32 +EXPORT_SYMBOL vmlinux 0xb8aa2342 __check_region +EXPORT_SYMBOL vmlinux 0xb8afd801 setup_arg_pages +EXPORT_SYMBOL vmlinux 0xb8b1c6d3 phy_disable_interrupts +EXPORT_SYMBOL vmlinux 0xb8e7ce2c __put_user_8 +EXPORT_SYMBOL vmlinux 0xb905ad82 icmpv6_err_convert +EXPORT_SYMBOL vmlinux 0xb9086cf6 secpath_dup +EXPORT_SYMBOL vmlinux 0xb92c6002 blk_queue_max_hw_segments +EXPORT_SYMBOL vmlinux 0xb92d2a35 __dev_remove_pack +EXPORT_SYMBOL vmlinux 0xb93ce908 vmtruncate +EXPORT_SYMBOL vmlinux 0xb9502f41 dev_get_by_flags +EXPORT_SYMBOL vmlinux 0xb9761f35 iov_iter_copy_from_user_atomic +EXPORT_SYMBOL vmlinux 0xb97c1689 pci_bus_write_config_word +EXPORT_SYMBOL vmlinux 0xb98a0185 rtc_tm_to_time +EXPORT_SYMBOL vmlinux 0xb99eec8c tcp_rcv_established +EXPORT_SYMBOL vmlinux 0xb9b865e6 inet_frags_init +EXPORT_SYMBOL vmlinux 0xb9c74bf1 gen_kill_estimator +EXPORT_SYMBOL vmlinux 0xb9cbd96e pci_iomap +EXPORT_SYMBOL vmlinux 0xb9f7ed33 scm_fp_dup +EXPORT_SYMBOL vmlinux 0xb9fd2205 add_efi_memmap +EXPORT_SYMBOL vmlinux 0xba2529e7 eth_rebuild_header +EXPORT_SYMBOL vmlinux 0xba2b3135 skb_realloc_headroom +EXPORT_SYMBOL vmlinux 0xba2d8594 ec_read +EXPORT_SYMBOL vmlinux 0xba452787 nonseekable_open +EXPORT_SYMBOL vmlinux 0xba497f13 loops_per_jiffy +EXPORT_SYMBOL vmlinux 0xba550d8f call_usermodehelper_freeinfo +EXPORT_SYMBOL vmlinux 0xba87361f block_write_end +EXPORT_SYMBOL vmlinux 0xba9f9f78 pagevec_lookup +EXPORT_SYMBOL vmlinux 0xbabcee56 bfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0xbae4407a send_sig +EXPORT_SYMBOL vmlinux 0xbae46970 generic_file_splice_write_nolock +EXPORT_SYMBOL vmlinux 0xbb167766 fb_var_to_videomode +EXPORT_SYMBOL vmlinux 0xbb189cad disallow_signal +EXPORT_SYMBOL vmlinux 0xbb5d343d xfrm_get_acqseq +EXPORT_SYMBOL vmlinux 0xbb83bd29 xfrm_cfg_mutex +EXPORT_SYMBOL vmlinux 0xbb89de17 ida_init +EXPORT_SYMBOL vmlinux 0xbb8e43de pci_set_master +EXPORT_SYMBOL vmlinux 0xbbc49136 pcix_get_max_mmrbc +EXPORT_SYMBOL vmlinux 0xbbc8e804 param_set_ushort +EXPORT_SYMBOL vmlinux 0xbc1be54e task_nice +EXPORT_SYMBOL vmlinux 0xbc26ec7a xfrm_policy_alloc +EXPORT_SYMBOL vmlinux 0xbc8d1bfd sync_mapping_buffers +EXPORT_SYMBOL vmlinux 0xbcc308bb strnlen_user +EXPORT_SYMBOL vmlinux 0xbcc5ed13 tcp_splice_read +EXPORT_SYMBOL vmlinux 0xbccd887b scsi_rescan_device +EXPORT_SYMBOL vmlinux 0xbcefda58 __napi_schedule +EXPORT_SYMBOL vmlinux 0xbd0a9035 pci_bus_size_bridges +EXPORT_SYMBOL vmlinux 0xbd18e4cf journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0xbd1e1903 jbd2_journal_force_commit +EXPORT_SYMBOL vmlinux 0xbd361fb8 blk_queue_init_tags +EXPORT_SYMBOL vmlinux 0xbd7f2264 clip_tbl_hook +EXPORT_SYMBOL vmlinux 0xbd83a16f __xfrm_decode_session +EXPORT_SYMBOL vmlinux 0xbdaa22ec hci_conn_change_link_key +EXPORT_SYMBOL vmlinux 0xbdae08a1 generic_file_mmap +EXPORT_SYMBOL vmlinux 0xbdfc265c arp_xmit +EXPORT_SYMBOL vmlinux 0xbe0e5118 nla_memcmp +EXPORT_SYMBOL vmlinux 0xbe2207ab skb_queue_tail +EXPORT_SYMBOL vmlinux 0xbe2e7821 jbd2_journal_init_dev +EXPORT_SYMBOL vmlinux 0xbe3e31fb arch_debugfs_dir +EXPORT_SYMBOL vmlinux 0xbe63a800 aio_put_req +EXPORT_SYMBOL vmlinux 0xbe63ee40 request_resource +EXPORT_SYMBOL vmlinux 0xbe892fba fb_class +EXPORT_SYMBOL vmlinux 0xbe8d07cd elv_rb_latter_request +EXPORT_SYMBOL vmlinux 0xbe9426ea __wait_on_buffer +EXPORT_SYMBOL vmlinux 0xbea70e50 inet_csk_delete_keepalive_timer +EXPORT_SYMBOL vmlinux 0xbeb5cd32 pcim_iomap_regions_request_all +EXPORT_SYMBOL vmlinux 0xbebec6cd sock_rfree +EXPORT_SYMBOL vmlinux 0xbec979cc xfrm_state_check_expire +EXPORT_SYMBOL vmlinux 0xbee8247e phy_disconnect +EXPORT_SYMBOL vmlinux 0xbee84b6b kthread_bind +EXPORT_SYMBOL vmlinux 0xbef43296 console_conditional_schedule +EXPORT_SYMBOL vmlinux 0xbf13b163 rwsem_down_read_failed +EXPORT_SYMBOL vmlinux 0xbf16eab1 bio_integrity_free +EXPORT_SYMBOL vmlinux 0xbf1d30da vfs_read +EXPORT_SYMBOL vmlinux 0xbf1f225a block_invalidatepage +EXPORT_SYMBOL vmlinux 0xbf20fa06 i2c_get_adapter +EXPORT_SYMBOL vmlinux 0xbf257482 __break_lease +EXPORT_SYMBOL vmlinux 0xbf3342af __insert_inode_hash +EXPORT_SYMBOL vmlinux 0xbf6cf2ee textsearch_find_continuous +EXPORT_SYMBOL vmlinux 0xbf7523de blk_queue_resize_tags +EXPORT_SYMBOL vmlinux 0xbf7fd2f5 schedule_timeout_killable +EXPORT_SYMBOL vmlinux 0xbf8b39e9 isapnp_present +EXPORT_SYMBOL vmlinux 0xbf9bcc8d __cap_empty_set +EXPORT_SYMBOL vmlinux 0xbfbe79f9 vmap +EXPORT_SYMBOL vmlinux 0xbfc177bc iowrite32_rep +EXPORT_SYMBOL vmlinux 0xbfc228e0 __vlan_hwaccel_rx +EXPORT_SYMBOL vmlinux 0xbfe22100 read_dev_sector +EXPORT_SYMBOL vmlinux 0xbfe438d7 __nla_put +EXPORT_SYMBOL vmlinux 0xbfee3ad5 loop_unregister_transfer +EXPORT_SYMBOL vmlinux 0xbff4a732 poll_freewait +EXPORT_SYMBOL vmlinux 0xc003c637 __strncpy_from_user +EXPORT_SYMBOL vmlinux 0xc01eed33 __copy_from_user_ll_nozero +EXPORT_SYMBOL vmlinux 0xc02a05b8 pnp_is_active +EXPORT_SYMBOL vmlinux 0xc0342c19 cdrom_open +EXPORT_SYMBOL vmlinux 0xc045ad4e timespec_trunc +EXPORT_SYMBOL vmlinux 0xc048ca5f blk_queue_ordered +EXPORT_SYMBOL vmlinux 0xc0580937 rb_erase +EXPORT_SYMBOL vmlinux 0xc05a2d23 simple_rmdir +EXPORT_SYMBOL vmlinux 0xc0792831 jbd2_journal_start +EXPORT_SYMBOL vmlinux 0xc0862120 journal_stop +EXPORT_SYMBOL vmlinux 0xc09b8879 tty_wait_until_sent +EXPORT_SYMBOL vmlinux 0xc0a3d105 find_next_bit +EXPORT_SYMBOL vmlinux 0xc0ab3dfd __xfrm_state_delete +EXPORT_SYMBOL vmlinux 0xc0ab4dda scsi_bios_ptable +EXPORT_SYMBOL vmlinux 0xc0b6e7b4 simple_transaction_release +EXPORT_SYMBOL vmlinux 0xc0bb8ce3 dquot_initialize +EXPORT_SYMBOL vmlinux 0xc0c277ab blk_queue_set_discard +EXPORT_SYMBOL vmlinux 0xc0f65988 machine_real_restart +EXPORT_SYMBOL vmlinux 0xc0fad4ac proc_doulongvec_ms_jiffies_minmax +EXPORT_SYMBOL vmlinux 0xc1056a85 tcp_create_openreq_child +EXPORT_SYMBOL vmlinux 0xc11d8093 iov_shorten +EXPORT_SYMBOL vmlinux 0xc12bdcdf tcf_hash_check +EXPORT_SYMBOL vmlinux 0xc12c3c1f ip_mc_join_group +EXPORT_SYMBOL vmlinux 0xc1388486 jbd2_journal_extend +EXPORT_SYMBOL vmlinux 0xc1579fd7 is_container_init +EXPORT_SYMBOL vmlinux 0xc1ce2d53 gnet_stats_copy_basic +EXPORT_SYMBOL vmlinux 0xc1cfd2f1 kernel_getpeername +EXPORT_SYMBOL vmlinux 0xc2066af0 batostr +EXPORT_SYMBOL vmlinux 0xc20a295d pci_scan_slot +EXPORT_SYMBOL vmlinux 0xc254af48 dcache_lock +EXPORT_SYMBOL vmlinux 0xc256e762 __bitmap_equal +EXPORT_SYMBOL vmlinux 0xc280a525 __copy_from_user_ll +EXPORT_SYMBOL vmlinux 0xc280e666 skb_put +EXPORT_SYMBOL vmlinux 0xc2d711e1 krealloc +EXPORT_SYMBOL vmlinux 0xc2d99d60 tty_kref_put +EXPORT_SYMBOL vmlinux 0xc2e587d1 reset_devices +EXPORT_SYMBOL vmlinux 0xc2fdfccd scsi_print_sense +EXPORT_SYMBOL vmlinux 0xc32238dd set_pages_x +EXPORT_SYMBOL vmlinux 0xc33f6f4c on_each_cpu +EXPORT_SYMBOL vmlinux 0xc34360c9 generic_setxattr +EXPORT_SYMBOL vmlinux 0xc34ce885 xfrm_input +EXPORT_SYMBOL vmlinux 0xc34e2602 kill_pid +EXPORT_SYMBOL vmlinux 0xc37aa4f5 nf_ip_checksum +EXPORT_SYMBOL vmlinux 0xc37fc694 posix_test_lock +EXPORT_SYMBOL vmlinux 0xc39cf649 ps2_command +EXPORT_SYMBOL vmlinux 0xc3a1b315 inet_shutdown +EXPORT_SYMBOL vmlinux 0xc3aaf0a9 __put_user_1 +EXPORT_SYMBOL vmlinux 0xc3b39508 jbd2_journal_update_format +EXPORT_SYMBOL vmlinux 0xc3c16108 tty_insert_flip_string +EXPORT_SYMBOL vmlinux 0xc3cf1128 in_group_p +EXPORT_SYMBOL vmlinux 0xc3dbd2d0 netpoll_send_udp +EXPORT_SYMBOL vmlinux 0xc3fa6a59 memchr +EXPORT_SYMBOL vmlinux 0xc40278ec dquot_mark_dquot_dirty +EXPORT_SYMBOL vmlinux 0xc402cc99 register_acpi_notifier +EXPORT_SYMBOL vmlinux 0xc499ae1e kstrdup +EXPORT_SYMBOL vmlinux 0xc4b2eb91 netdev_state_change +EXPORT_SYMBOL vmlinux 0xc4bbcaf4 pcim_iomap +EXPORT_SYMBOL vmlinux 0xc4c8f5c1 neigh_update +EXPORT_SYMBOL vmlinux 0xc4d0febb pci_enable_msi +EXPORT_SYMBOL vmlinux 0xc4ebd7f1 dev_remove_pack +EXPORT_SYMBOL vmlinux 0xc4fd1f30 input_flush_device +EXPORT_SYMBOL vmlinux 0xc507715e __free_pages +EXPORT_SYMBOL vmlinux 0xc518f967 block_commit_write +EXPORT_SYMBOL vmlinux 0xc52f5714 fb_videomode_to_var +EXPORT_SYMBOL vmlinux 0xc5306c86 scsi_free_command +EXPORT_SYMBOL vmlinux 0xc5534d64 ioread16 +EXPORT_SYMBOL vmlinux 0xc55f7dc7 _write_trylock +EXPORT_SYMBOL vmlinux 0xc56f7903 acpi_get_physical_device +EXPORT_SYMBOL vmlinux 0xc5718627 sg_copy_to_buffer +EXPORT_SYMBOL vmlinux 0xc5844fb8 __per_cpu_offset +EXPORT_SYMBOL vmlinux 0xc59c21b1 scsi_register +EXPORT_SYMBOL vmlinux 0xc5bfd9e8 netif_rx_ni +EXPORT_SYMBOL vmlinux 0xc5dc29cf __scsi_alloc_queue +EXPORT_SYMBOL vmlinux 0xc5e3d6d0 find_vma +EXPORT_SYMBOL vmlinux 0xc5fd31ee jbd2_journal_get_write_access +EXPORT_SYMBOL vmlinux 0xc600a9f0 tcp_mtup_init +EXPORT_SYMBOL vmlinux 0xc61984d7 inetdev_by_index +EXPORT_SYMBOL vmlinux 0xc62f2a43 dquot_acquire +EXPORT_SYMBOL vmlinux 0xc63e1ef9 i2c_del_adapter +EXPORT_SYMBOL vmlinux 0xc642fd42 scsi_remove_device +EXPORT_SYMBOL vmlinux 0xc64c97bf tty_free_termios +EXPORT_SYMBOL vmlinux 0xc65298a8 dev_get_by_name +EXPORT_SYMBOL vmlinux 0xc67a8864 ethtool_op_get_tx_csum +EXPORT_SYMBOL vmlinux 0xc68c0dc4 ip_queue_xmit +EXPORT_SYMBOL vmlinux 0xc6934204 qdisc_watchdog_schedule +EXPORT_SYMBOL vmlinux 0xc69963cd bio_endio +EXPORT_SYMBOL vmlinux 0xc6bc7479 blk_queue_max_segment_size +EXPORT_SYMBOL vmlinux 0xc6f5e5a8 __pagevec_release +EXPORT_SYMBOL vmlinux 0xc7131591 pcibios_align_resource +EXPORT_SYMBOL vmlinux 0xc71c0f52 invalidate_partition +EXPORT_SYMBOL vmlinux 0xc71fd120 wait_on_page_bit +EXPORT_SYMBOL vmlinux 0xc7208c3a serial8250_resume_port +EXPORT_SYMBOL vmlinux 0xc744e8b5 call_usermodehelper_stdinpipe +EXPORT_SYMBOL vmlinux 0xc79806db jbd2_journal_file_inode +EXPORT_SYMBOL vmlinux 0xc79bcd36 dm_vcalloc +EXPORT_SYMBOL vmlinux 0xc7a2ac1f scsi_target_resume +EXPORT_SYMBOL vmlinux 0xc7a4fbed rtnl_lock +EXPORT_SYMBOL vmlinux 0xc7d39a64 __kill_fasync +EXPORT_SYMBOL vmlinux 0xc7ec6c27 strspn +EXPORT_SYMBOL vmlinux 0xc7f905d9 xfrm_policy_unregister_afinfo +EXPORT_SYMBOL vmlinux 0xc81a0611 unregister_md_personality +EXPORT_SYMBOL vmlinux 0xc821a954 pskb_copy +EXPORT_SYMBOL vmlinux 0xc836fc96 pcim_iounmap +EXPORT_SYMBOL vmlinux 0xc848f598 skb_copy_and_csum_bits +EXPORT_SYMBOL vmlinux 0xc8559dba ppp_unregister_channel +EXPORT_SYMBOL vmlinux 0xc8649da8 tcp_v4_remember_stamp +EXPORT_SYMBOL vmlinux 0xc866c61e seq_lseek +EXPORT_SYMBOL vmlinux 0xc877639c ipv6_chk_prefix +EXPORT_SYMBOL vmlinux 0xc87f24af kmem_cache_free +EXPORT_SYMBOL vmlinux 0xc8934523 bdget +EXPORT_SYMBOL vmlinux 0xc896c2f5 mmc_register_driver +EXPORT_SYMBOL vmlinux 0xc8a857ce dmam_pool_destroy +EXPORT_SYMBOL vmlinux 0xc8a9eec7 pcim_pin_device +EXPORT_SYMBOL vmlinux 0xc8b57c27 autoremove_wake_function +EXPORT_SYMBOL vmlinux 0xc8ca3e25 acpi_get_child +EXPORT_SYMBOL vmlinux 0xc8d93c3f sock_no_setsockopt +EXPORT_SYMBOL vmlinux 0xc9138fe2 skb_queue_head +EXPORT_SYMBOL vmlinux 0xc91caaa3 phy_connect +EXPORT_SYMBOL vmlinux 0xc9490cd2 tty_register_device +EXPORT_SYMBOL vmlinux 0xc949dcb8 scsi_device_put +EXPORT_SYMBOL vmlinux 0xc94c6ef0 jbd2_journal_forget +EXPORT_SYMBOL vmlinux 0xc971e198 journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0xc998d641 icmp_err_convert +EXPORT_SYMBOL vmlinux 0xc9ab2eef acpi_os_wait_events_complete +EXPORT_SYMBOL vmlinux 0xc9af7c05 sock_no_connect +EXPORT_SYMBOL vmlinux 0xc9bd4ea2 pci_prepare_to_sleep +EXPORT_SYMBOL vmlinux 0xc9c3f786 arp_broken_ops +EXPORT_SYMBOL vmlinux 0xc9e9de19 sock_no_mmap +EXPORT_SYMBOL vmlinux 0xc9f25f4a i2c_smbus_write_word_data +EXPORT_SYMBOL vmlinux 0xc9f82cbc iw_handler_set_thrspy +EXPORT_SYMBOL vmlinux 0xca5dbc50 scsi_print_sense_hdr +EXPORT_SYMBOL vmlinux 0xca8acc78 acpi_dbg_level +EXPORT_SYMBOL vmlinux 0xcaa46217 lookup_bdev +EXPORT_SYMBOL vmlinux 0xcac06a57 skb_checksum_help +EXPORT_SYMBOL vmlinux 0xcac6c5ba journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0xcacc7028 journal_lock_updates +EXPORT_SYMBOL vmlinux 0xcaf08699 genphy_config_aneg +EXPORT_SYMBOL vmlinux 0xcb147014 tcf_hash_search +EXPORT_SYMBOL vmlinux 0xcb2f9df2 pagevec_lookup_tag +EXPORT_SYMBOL vmlinux 0xcb32da10 param_set_int +EXPORT_SYMBOL vmlinux 0xcb5ff912 tcp_md5_hash_header +EXPORT_SYMBOL vmlinux 0xcb67f976 xfrm_nl +EXPORT_SYMBOL vmlinux 0xcb6beb40 hweight32 +EXPORT_SYMBOL vmlinux 0xcb7131fb fb_get_options +EXPORT_SYMBOL vmlinux 0xcb733bf2 acpi_bus_set_power +EXPORT_SYMBOL vmlinux 0xcb8a1860 hci_conn_encrypt +EXPORT_SYMBOL vmlinux 0xcbc16fb5 xfrm_policy_walk +EXPORT_SYMBOL vmlinux 0xcbf48873 pci_bus_write_config_byte +EXPORT_SYMBOL vmlinux 0xcc1fb551 baswap +EXPORT_SYMBOL vmlinux 0xcc248d26 serial8250_suspend_port +EXPORT_SYMBOL vmlinux 0xcc29bef6 udp_disconnect +EXPORT_SYMBOL vmlinux 0xcc2bac49 journal_force_commit +EXPORT_SYMBOL vmlinux 0xcc36f32e fb_unregister_client +EXPORT_SYMBOL vmlinux 0xcc5005fe msleep_interruptible +EXPORT_SYMBOL vmlinux 0xcc51ee50 dma_spin_lock +EXPORT_SYMBOL vmlinux 0xcc6a997c mpage_writepage +EXPORT_SYMBOL vmlinux 0xcc753fdf page_zero_new_buffers +EXPORT_SYMBOL vmlinux 0xcc7fa952 local_bh_enable_ip +EXPORT_SYMBOL vmlinux 0xccb12770 pci_dev_driver +EXPORT_SYMBOL vmlinux 0xccbdfb5f pcim_iomap_regions +EXPORT_SYMBOL vmlinux 0xccceaf8e dev_driver_string +EXPORT_SYMBOL vmlinux 0xccd74751 vfs_getattr +EXPORT_SYMBOL vmlinux 0xccfe3efa user_revoke +EXPORT_SYMBOL vmlinux 0xcd3a302f input_register_handle +EXPORT_SYMBOL vmlinux 0xcd41663f xfrm_find_acq_byseq +EXPORT_SYMBOL vmlinux 0xcd47519d cfb_fillrect +EXPORT_SYMBOL vmlinux 0xcd4c883f skb_store_bits +EXPORT_SYMBOL vmlinux 0xcd5924bb get_sb_pseudo +EXPORT_SYMBOL vmlinux 0xcd7e2745 journal_update_format +EXPORT_SYMBOL vmlinux 0xcd93ea96 inet_twsk_deschedule +EXPORT_SYMBOL vmlinux 0xcd9befb0 blk_remove_plug +EXPORT_SYMBOL vmlinux 0xcdb2afa9 bio_integrity_trim +EXPORT_SYMBOL vmlinux 0xcdcd07c2 locks_mandatory_area +EXPORT_SYMBOL vmlinux 0xcdea2a8a tty_register_ldisc +EXPORT_SYMBOL vmlinux 0xcdee7368 tcp_child_process +EXPORT_SYMBOL vmlinux 0xce063481 scsi_register_driver +EXPORT_SYMBOL vmlinux 0xce0818f1 sk_send_sigurg +EXPORT_SYMBOL vmlinux 0xce19bac5 register_inet6addr_notifier +EXPORT_SYMBOL vmlinux 0xce36ded6 sysctl_tcp_mem +EXPORT_SYMBOL vmlinux 0xce4904a4 acpi_leave_sleep_state +EXPORT_SYMBOL vmlinux 0xce5ac24f zlib_inflate_workspacesize +EXPORT_SYMBOL vmlinux 0xce6381df inode_double_lock +EXPORT_SYMBOL vmlinux 0xce7313cd dst_alloc +EXPORT_SYMBOL vmlinux 0xce7ce8a0 __secpath_destroy +EXPORT_SYMBOL vmlinux 0xceef2e40 dquot_commit +EXPORT_SYMBOL vmlinux 0xcef588e0 call_usermodehelper_exec +EXPORT_SYMBOL vmlinux 0xcefcd99a serial8250_unregister_port +EXPORT_SYMBOL vmlinux 0xcf2f7df7 page_address +EXPORT_SYMBOL vmlinux 0xcf4457fe handle_sysrq +EXPORT_SYMBOL vmlinux 0xcf6e868f alloc_hippi_dev +EXPORT_SYMBOL vmlinux 0xcf8e36e7 get_user_pages +EXPORT_SYMBOL vmlinux 0xcf8f5c1d check_disk_size_change +EXPORT_SYMBOL vmlinux 0xcf903f57 sb_set_blocksize +EXPORT_SYMBOL vmlinux 0xcfadd723 __percpu_counter_add +EXPORT_SYMBOL vmlinux 0xcfd3018e set_normalized_timespec +EXPORT_SYMBOL vmlinux 0xd0181f4f __bitmap_xor +EXPORT_SYMBOL vmlinux 0xd02cc869 __bitmap_andnot +EXPORT_SYMBOL vmlinux 0xd067960c tcp_close +EXPORT_SYMBOL vmlinux 0xd0753a85 journal_wipe +EXPORT_SYMBOL vmlinux 0xd08197fa acpi_load_tables +EXPORT_SYMBOL vmlinux 0xd0839ed9 usb_serial_resume +EXPORT_SYMBOL vmlinux 0xd0d8621b strlen +EXPORT_SYMBOL vmlinux 0xd0e4315d end_page_writeback +EXPORT_SYMBOL vmlinux 0xd0ee38b8 schedule_timeout_uninterruptible +EXPORT_SYMBOL vmlinux 0xd100fd63 input_set_keycode +EXPORT_SYMBOL vmlinux 0xd116d5e1 dma_async_memcpy_pg_to_pg +EXPORT_SYMBOL vmlinux 0xd128e7d3 tty_port_tty_get +EXPORT_SYMBOL vmlinux 0xd1472061 acpi_pci_register_driver +EXPORT_SYMBOL vmlinux 0xd151a199 pcim_iomap_table +EXPORT_SYMBOL vmlinux 0xd15a611d blk_verify_command +EXPORT_SYMBOL vmlinux 0xd170439e __breadahead +EXPORT_SYMBOL vmlinux 0xd17eecb0 jbd2_journal_set_features +EXPORT_SYMBOL vmlinux 0xd18b6eb2 acpi_unmap_lsapic +EXPORT_SYMBOL vmlinux 0xd1a83a3b dev_mc_unsync +EXPORT_SYMBOL vmlinux 0xd1ce4693 block_page_mkwrite +EXPORT_SYMBOL vmlinux 0xd1f6c5f3 smp_num_siblings +EXPORT_SYMBOL vmlinux 0xd1f91bcd dev_base_lock +EXPORT_SYMBOL vmlinux 0xd20fbc5b kmap_high +EXPORT_SYMBOL vmlinux 0xd24ca12f skb_free_datagram +EXPORT_SYMBOL vmlinux 0xd251d7b0 security_socket_getpeersec_dgram +EXPORT_SYMBOL vmlinux 0xd2555f19 jiffies_64_to_clock_t +EXPORT_SYMBOL vmlinux 0xd25b5856 inet_frags_exit_net +EXPORT_SYMBOL vmlinux 0xd25bd018 qdisc_destroy +EXPORT_SYMBOL vmlinux 0xd25d4f74 console_blank_hook +EXPORT_SYMBOL vmlinux 0xd25e951a proc_dostring +EXPORT_SYMBOL vmlinux 0xd267d42c down_killable +EXPORT_SYMBOL vmlinux 0xd26d12ec proc_mkdir +EXPORT_SYMBOL vmlinux 0xd275907e skb_copy_datagram_iovec +EXPORT_SYMBOL vmlinux 0xd27980b6 con_copy_unimap +EXPORT_SYMBOL vmlinux 0xd27dde01 pci_bus_read_config_byte +EXPORT_SYMBOL vmlinux 0xd2965f6f kthread_should_stop +EXPORT_SYMBOL vmlinux 0xd2981b51 request_key_async_with_auxdata +EXPORT_SYMBOL vmlinux 0xd2a941d4 sg_init_table +EXPORT_SYMBOL vmlinux 0xd2a94681 hci_recv_fragment +EXPORT_SYMBOL vmlinux 0xd2ab41d7 blk_queue_end_tag +EXPORT_SYMBOL vmlinux 0xd2ca2918 neigh_table_init_no_netlink +EXPORT_SYMBOL vmlinux 0xd2cf38a2 scsi_get_host_dev +EXPORT_SYMBOL vmlinux 0xd34f0c62 gen_pool_create +EXPORT_SYMBOL vmlinux 0xd363bdea pnp_request_card_device +EXPORT_SYMBOL vmlinux 0xd3951da4 acpi_resource_to_address64 +EXPORT_SYMBOL vmlinux 0xd3c4bc72 mem_map +EXPORT_SYMBOL vmlinux 0xd3ca1cad vm_insert_pfn +EXPORT_SYMBOL vmlinux 0xd3f3f6ea __f_setown +EXPORT_SYMBOL vmlinux 0xd3f74cf1 interruptible_sleep_on_timeout +EXPORT_SYMBOL vmlinux 0xd407424e __tcf_em_tree_match +EXPORT_SYMBOL vmlinux 0xd418e1c0 adjust_resource +EXPORT_SYMBOL vmlinux 0xd42b7232 _write_unlock_bh +EXPORT_SYMBOL vmlinux 0xd45cbb15 ethtool_op_get_sg +EXPORT_SYMBOL vmlinux 0xd4a064bf __devm_release_region +EXPORT_SYMBOL vmlinux 0xd4a7fe74 inet_frag_destroy +EXPORT_SYMBOL vmlinux 0xd4e26892 vfs_get_dqinfo +EXPORT_SYMBOL vmlinux 0xd50b246c dm_dirty_log_type_unregister +EXPORT_SYMBOL vmlinux 0xd5263820 mb_cache_destroy +EXPORT_SYMBOL vmlinux 0xd5266651 clear_page_dirty_for_io +EXPORT_SYMBOL vmlinux 0xd52fa696 i2c_smbus_read_byte +EXPORT_SYMBOL vmlinux 0xd5388d6f elevator_exit +EXPORT_SYMBOL vmlinux 0xd53aec49 cpu_possible_map +EXPORT_SYMBOL vmlinux 0xd54e72c3 pci_remove_behind_bridge +EXPORT_SYMBOL vmlinux 0xd5688a7a radix_tree_insert +EXPORT_SYMBOL vmlinux 0xd5717360 hci_conn_auth +EXPORT_SYMBOL vmlinux 0xd5799204 zero_fill_bio +EXPORT_SYMBOL vmlinux 0xd5b037e1 kref_put +EXPORT_SYMBOL vmlinux 0xd5dfbec6 ip_defrag +EXPORT_SYMBOL vmlinux 0xd5e1cd16 fd_install +EXPORT_SYMBOL vmlinux 0xd6035d05 do_settimeofday +EXPORT_SYMBOL vmlinux 0xd6140029 hippi_type_trans +EXPORT_SYMBOL vmlinux 0xd62c833f schedule_timeout +EXPORT_SYMBOL vmlinux 0xd64ea896 dm_dirty_log_destroy +EXPORT_SYMBOL vmlinux 0xd650535b compute_creds +EXPORT_SYMBOL vmlinux 0xd688b16c vfs_set_dqblk +EXPORT_SYMBOL vmlinux 0xd6a78d08 smp_call_function_single +EXPORT_SYMBOL vmlinux 0xd6b33026 cpu_khz +EXPORT_SYMBOL vmlinux 0xd6bb8f9f unmap_mapping_range +EXPORT_SYMBOL vmlinux 0xd6ee688f vmalloc +EXPORT_SYMBOL vmlinux 0xd709f608 udp_lib_setsockopt +EXPORT_SYMBOL vmlinux 0xd71c90ff posix_lock_file_wait +EXPORT_SYMBOL vmlinux 0xd71f957a __pci_register_driver +EXPORT_SYMBOL vmlinux 0xd73ccc31 journal_load +EXPORT_SYMBOL vmlinux 0xd73fc10a generic_file_buffered_write +EXPORT_SYMBOL vmlinux 0xd75c4d91 cdrom_mode_sense +EXPORT_SYMBOL vmlinux 0xd79b5a02 allow_signal +EXPORT_SYMBOL vmlinux 0xd79f8c59 key_unlink +EXPORT_SYMBOL vmlinux 0xd7a6fafa panic_notifier_list +EXPORT_SYMBOL vmlinux 0xd7a988fc directly_mappable_cdev_bdi +EXPORT_SYMBOL vmlinux 0xd7c7b17c kernel_sock_ioctl +EXPORT_SYMBOL vmlinux 0xd7d36d1a idr_find +EXPORT_SYMBOL vmlinux 0xd7dd777b reserve_perfctr_nmi +EXPORT_SYMBOL vmlinux 0xd7df260b serio_unregister_port +EXPORT_SYMBOL vmlinux 0xd7f105c2 scsi_scan_host +EXPORT_SYMBOL vmlinux 0xd7f4c8b9 iw_handler_set_spy +EXPORT_SYMBOL vmlinux 0xd7ff023d page_put_link +EXPORT_SYMBOL vmlinux 0xd820d4d3 km_policy_notify +EXPORT_SYMBOL vmlinux 0xd84f77b1 do_munmap +EXPORT_SYMBOL vmlinux 0xd874469f scsi_device_resume +EXPORT_SYMBOL vmlinux 0xd88f695a __mod_timer +EXPORT_SYMBOL vmlinux 0xd89da37f movable_zone +EXPORT_SYMBOL vmlinux 0xd8a2ab95 in_egroup_p +EXPORT_SYMBOL vmlinux 0xd8b9df7e dev_kfree_skb_any +EXPORT_SYMBOL vmlinux 0xd8c3b854 phy_driver_unregister +EXPORT_SYMBOL vmlinux 0xd8e484f0 register_chrdev_region +EXPORT_SYMBOL vmlinux 0xd9091363 acpi_install_notify_handler +EXPORT_SYMBOL vmlinux 0xd9395a5d inet_csk_destroy_sock +EXPORT_SYMBOL vmlinux 0xd93e7890 ip_route_me_harder +EXPORT_SYMBOL vmlinux 0xd970c291 scsi_device_get +EXPORT_SYMBOL vmlinux 0xd985dc99 mempool_free_pages +EXPORT_SYMBOL vmlinux 0xd986ba23 take_over_console +EXPORT_SYMBOL vmlinux 0xd996d859 idr_pre_get +EXPORT_SYMBOL vmlinux 0xd9aec663 ethtool_op_set_flags +EXPORT_SYMBOL vmlinux 0xd9bf885c i2c_smbus_xfer +EXPORT_SYMBOL vmlinux 0xd9c272aa mca_mark_as_unused +EXPORT_SYMBOL vmlinux 0xd9c6dd82 elevator_init +EXPORT_SYMBOL vmlinux 0xd9d9a7d1 mmc_add_host +EXPORT_SYMBOL vmlinux 0xd9e4307b vfs_unlink +EXPORT_SYMBOL vmlinux 0xd9ec7d9d d_alloc_name +EXPORT_SYMBOL vmlinux 0xd9fd7a3f i2c_smbus_write_byte +EXPORT_SYMBOL vmlinux 0xda08c0d7 pcibios_get_irq_routing_table +EXPORT_SYMBOL vmlinux 0xda0a6b0e acpi_map_lsapic +EXPORT_SYMBOL vmlinux 0xda1a7335 kasprintf +EXPORT_SYMBOL vmlinux 0xda2fe664 input_close_device +EXPORT_SYMBOL vmlinux 0xda3f5017 scsi_eh_finish_cmd +EXPORT_SYMBOL vmlinux 0xda4f96e0 genphy_read_status +EXPORT_SYMBOL vmlinux 0xda65eb50 grab_cache_page_write_begin +EXPORT_SYMBOL vmlinux 0xda7ca6cb fb_mode_is_equal +EXPORT_SYMBOL vmlinux 0xda8af7ad fb_find_nearest_mode +EXPORT_SYMBOL vmlinux 0xda8fd495 isapnp_write_byte +EXPORT_SYMBOL vmlinux 0xda928914 nmi_watchdog +EXPORT_SYMBOL vmlinux 0xdaa2c83e proc_dointvec_jiffies +EXPORT_SYMBOL vmlinux 0xdaa57ec3 totalhigh_pages +EXPORT_SYMBOL vmlinux 0xdacf7446 __mmc_claim_host +EXPORT_SYMBOL vmlinux 0xdad3881d nf_register_hook +EXPORT_SYMBOL vmlinux 0xdaebc28a ppp_register_channel +EXPORT_SYMBOL vmlinux 0xdb0f2b34 serio_open +EXPORT_SYMBOL vmlinux 0xdb1e03b4 block_sync_page +EXPORT_SYMBOL vmlinux 0xdb377be1 register_filesystem +EXPORT_SYMBOL vmlinux 0xdb3bf5ab pfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0xdb3f679a tcp_tso_segment +EXPORT_SYMBOL vmlinux 0xdb433021 acpi_notifier_call_chain +EXPORT_SYMBOL vmlinux 0xdb6ce750 copy_io_context +EXPORT_SYMBOL vmlinux 0xdb864d65 iov_iter_single_seg_count +EXPORT_SYMBOL vmlinux 0xdb8f8bf6 mca_device_claimed +EXPORT_SYMBOL vmlinux 0xdb9b6483 pci_scan_single_device +EXPORT_SYMBOL vmlinux 0xdbaab93b mpage_readpage +EXPORT_SYMBOL vmlinux 0xdbcd416e sysctl_ip_nonlocal_bind +EXPORT_SYMBOL vmlinux 0xdc0cdf56 proto_unregister +EXPORT_SYMBOL vmlinux 0xdc14eda7 pci_pci_problems +EXPORT_SYMBOL vmlinux 0xdc2adb35 add_taint +EXPORT_SYMBOL vmlinux 0xdc30d756 pnp_register_card_driver +EXPORT_SYMBOL vmlinux 0xdc43a9c8 daemonize +EXPORT_SYMBOL vmlinux 0xdc538cb3 md_register_thread +EXPORT_SYMBOL vmlinux 0xdc873a70 screen_info +EXPORT_SYMBOL vmlinux 0xdc94a5ac set_bh_page +EXPORT_SYMBOL vmlinux 0xdccb0d50 pci_back_from_sleep +EXPORT_SYMBOL vmlinux 0xdccc2f19 scsi_host_get +EXPORT_SYMBOL vmlinux 0xdcce36bb sock_queue_rcv_skb +EXPORT_SYMBOL vmlinux 0xdd09c7f6 wireless_spy_update +EXPORT_SYMBOL vmlinux 0xdd0a2ba2 strlcat +EXPORT_SYMBOL vmlinux 0xdd24f7db ip_generic_getfrag +EXPORT_SYMBOL vmlinux 0xdd52bdcf tcf_hash_create +EXPORT_SYMBOL vmlinux 0xdd584a72 alloc_disk +EXPORT_SYMBOL vmlinux 0xdd66e4b6 vfs_quota_on_mount +EXPORT_SYMBOL vmlinux 0xdd6bfccd radix_tree_tag_set +EXPORT_SYMBOL vmlinux 0xdd87279e __skb_checksum_complete_head +EXPORT_SYMBOL vmlinux 0xdda37d08 i2c_smbus_write_i2c_block_data +EXPORT_SYMBOL vmlinux 0xddc1ac11 bioset_integrity_free +EXPORT_SYMBOL vmlinux 0xddeef053 vfs_stat +EXPORT_SYMBOL vmlinux 0xde032cbe open_bdev_exclusive +EXPORT_SYMBOL vmlinux 0xde1059d0 register_md_personality +EXPORT_SYMBOL vmlinux 0xde1afc3a elv_rb_add +EXPORT_SYMBOL vmlinux 0xde3f5ac9 posix_acl_permission +EXPORT_SYMBOL vmlinux 0xde6ac833 alloc_disk_node +EXPORT_SYMBOL vmlinux 0xde75b689 set_irq_type +EXPORT_SYMBOL vmlinux 0xde8ba6ac tcp_sendmsg +EXPORT_SYMBOL vmlinux 0xde9360ba totalram_pages +EXPORT_SYMBOL vmlinux 0xde9922ef input_unregister_device +EXPORT_SYMBOL vmlinux 0xde9e9182 key_alloc +EXPORT_SYMBOL vmlinux 0xde9edf84 sysctl_jiffies +EXPORT_SYMBOL vmlinux 0xdeb7c2d5 tty_schedule_flip +EXPORT_SYMBOL vmlinux 0xdeccf2a5 posix_unblock_lock +EXPORT_SYMBOL vmlinux 0xded21ef8 dst_release +EXPORT_SYMBOL vmlinux 0xded52372 qdisc_calculate_pkt_len +EXPORT_SYMBOL vmlinux 0xdee92ceb dput +EXPORT_SYMBOL vmlinux 0xdf0da3cc acpi_get_devices +EXPORT_SYMBOL vmlinux 0xdf4bd11a pci_iounmap +EXPORT_SYMBOL vmlinux 0xdf60cc27 __print_symbol +EXPORT_SYMBOL vmlinux 0xdf82aa75 jbd2_journal_create +EXPORT_SYMBOL vmlinux 0xdf8c695a __ndelay +EXPORT_SYMBOL vmlinux 0xdf929370 fs_overflowgid +EXPORT_SYMBOL vmlinux 0xdfc5169b slhc_init +EXPORT_SYMBOL vmlinux 0xdfc87eab balance_dirty_pages_ratelimited_nr +EXPORT_SYMBOL vmlinux 0xdfe4b370 journal_dirty_data +EXPORT_SYMBOL vmlinux 0xdffe79b6 submit_bio +EXPORT_SYMBOL vmlinux 0xe0206dc4 skb_abort_seq_read +EXPORT_SYMBOL vmlinux 0xe02da435 dquot_alloc_space +EXPORT_SYMBOL vmlinux 0xe06b4431 wait_for_key_construction +EXPORT_SYMBOL vmlinux 0xe075d6eb iter_div_u64_rem +EXPORT_SYMBOL vmlinux 0xe094ef39 sg_next +EXPORT_SYMBOL vmlinux 0xe0a501e3 idr_remove_all +EXPORT_SYMBOL vmlinux 0xe0ac8bd2 acpi_bus_generate_netlink_event +EXPORT_SYMBOL vmlinux 0xe0b13336 argv_free +EXPORT_SYMBOL vmlinux 0xe118f798 mpage_writepages +EXPORT_SYMBOL vmlinux 0xe137eea1 bdevname +EXPORT_SYMBOL vmlinux 0xe13cd8a7 dmi_name_in_vendors +EXPORT_SYMBOL vmlinux 0xe15aeee2 downgrade_write +EXPORT_SYMBOL vmlinux 0xe16f8a79 per_cpu__irq_regs +EXPORT_SYMBOL vmlinux 0xe1761617 security_inet_conn_request +EXPORT_SYMBOL vmlinux 0xe1a81c3a icmpv6msg_statistics +EXPORT_SYMBOL vmlinux 0xe1c43414 journal_forget +EXPORT_SYMBOL vmlinux 0xe1cf5ef1 uart_write_wakeup +EXPORT_SYMBOL vmlinux 0xe1d50381 acpi_bus_start +EXPORT_SYMBOL vmlinux 0xe1ddd61f sysctl_intvec +EXPORT_SYMBOL vmlinux 0xe1e4e70c simple_transaction_get +EXPORT_SYMBOL vmlinux 0xe1e6854a alloc_trdev +EXPORT_SYMBOL vmlinux 0xe1ed2aae serio_close +EXPORT_SYMBOL vmlinux 0xe238002d journal_invalidatepage +EXPORT_SYMBOL vmlinux 0xe24d3a97 jiffies_64 +EXPORT_SYMBOL vmlinux 0xe25c4fdf kernel_sock_shutdown +EXPORT_SYMBOL vmlinux 0xe2606e2b cdrom_get_media_event +EXPORT_SYMBOL vmlinux 0xe2748f76 __neigh_event_send +EXPORT_SYMBOL vmlinux 0xe278da36 ps2_handle_ack +EXPORT_SYMBOL vmlinux 0xe2c7c2a1 find_get_pages_contig +EXPORT_SYMBOL vmlinux 0xe2d5255a strcmp +EXPORT_SYMBOL vmlinux 0xe2fae716 kmemdup +EXPORT_SYMBOL vmlinux 0xe30c5510 phy_detach +EXPORT_SYMBOL vmlinux 0xe312c2a4 pnp_find_card +EXPORT_SYMBOL vmlinux 0xe321b52b lease_get_mtime +EXPORT_SYMBOL vmlinux 0xe329b746 blk_rq_map_user_iov +EXPORT_SYMBOL vmlinux 0xe33bfc73 inet_select_addr +EXPORT_SYMBOL vmlinux 0xe34ffc10 set_bdi_congested +EXPORT_SYMBOL vmlinux 0xe351633f genl_register_family +EXPORT_SYMBOL vmlinux 0xe363d14b alloc_buffer_head +EXPORT_SYMBOL vmlinux 0xe385aaf2 hci_unregister_proto +EXPORT_SYMBOL vmlinux 0xe3a87bc7 filp_open +EXPORT_SYMBOL vmlinux 0xe3fbe148 acpi_install_table_handler +EXPORT_SYMBOL vmlinux 0xe43617f7 acpi_gbl_FADT +EXPORT_SYMBOL vmlinux 0xe44dc846 invalidate_inodes +EXPORT_SYMBOL vmlinux 0xe456bd3a complete +EXPORT_SYMBOL vmlinux 0xe457f4a4 pci_remove_bus +EXPORT_SYMBOL vmlinux 0xe4698529 find_lock_page +EXPORT_SYMBOL vmlinux 0xe484e35f ioread32 +EXPORT_SYMBOL vmlinux 0xe4870354 _read_trylock +EXPORT_SYMBOL vmlinux 0xe48a2d2a xfrm_policy_register_afinfo +EXPORT_SYMBOL vmlinux 0xe48f3039 ida_get_new_above +EXPORT_SYMBOL vmlinux 0xe49a9db8 gnet_stats_start_copy +EXPORT_SYMBOL vmlinux 0xe4b24b8c __next_cpu +EXPORT_SYMBOL vmlinux 0xe4c1df3e _read_lock_bh +EXPORT_SYMBOL vmlinux 0xe4d48ae7 xfrm_state_lookup_byaddr +EXPORT_SYMBOL vmlinux 0xe5098ccb find_task_by_vpid +EXPORT_SYMBOL vmlinux 0xe5122890 flow_cache_genid +EXPORT_SYMBOL vmlinux 0xe513b92d tty_driver_kref_put +EXPORT_SYMBOL vmlinux 0xe5185cd4 path_lookup +EXPORT_SYMBOL vmlinux 0xe523ad75 synchronize_irq +EXPORT_SYMBOL vmlinux 0xe5330208 netif_receive_skb +EXPORT_SYMBOL vmlinux 0xe53f121c inet_put_port +EXPORT_SYMBOL vmlinux 0xe54ceb38 hci_alloc_dev +EXPORT_SYMBOL vmlinux 0xe5512dce mca_device_transform_ioport +EXPORT_SYMBOL vmlinux 0xe5546d2d ipv6_getsockopt +EXPORT_SYMBOL vmlinux 0xe56a5487 arp_create +EXPORT_SYMBOL vmlinux 0xe57878a1 in6_pton +EXPORT_SYMBOL vmlinux 0xe57a6cc2 ip6_route_me_harder +EXPORT_SYMBOL vmlinux 0xe581661e pci_find_device +EXPORT_SYMBOL vmlinux 0xe5844107 cpu_present_map +EXPORT_SYMBOL vmlinux 0xe5867808 dlci_ioctl_set +EXPORT_SYMBOL vmlinux 0xe5b89aa9 bio_integrity_prep +EXPORT_SYMBOL vmlinux 0xe5c78a99 do_blank_screen +EXPORT_SYMBOL vmlinux 0xe5e219f1 pci_release_region +EXPORT_SYMBOL vmlinux 0xe5e9c9b3 generic_splice_sendpage +EXPORT_SYMBOL vmlinux 0xe5ed5467 xfrm_policy_walk_init +EXPORT_SYMBOL vmlinux 0xe6148add skb_append_datato_frags +EXPORT_SYMBOL vmlinux 0xe624da77 hci_register_dev +EXPORT_SYMBOL vmlinux 0xe6252bed flush_signals +EXPORT_SYMBOL vmlinux 0xe64c0d3d revalidate_disk +EXPORT_SYMBOL vmlinux 0xe64ca24d pcie_set_readrq +EXPORT_SYMBOL vmlinux 0xe64eb6eb __serio_register_driver +EXPORT_SYMBOL vmlinux 0xe6639045 generic_file_aio_write +EXPORT_SYMBOL vmlinux 0xe671cd36 journal_check_available_features +EXPORT_SYMBOL vmlinux 0xe67e4e50 bio_integrity_alloc +EXPORT_SYMBOL vmlinux 0xe690b8fd __ipv6_isatap_ifid +EXPORT_SYMBOL vmlinux 0xe6b0f2dd dm_kcopyd_client_create +EXPORT_SYMBOL vmlinux 0xe6ebc016 key_create_or_update +EXPORT_SYMBOL vmlinux 0xe6fbe430 can_do_mlock +EXPORT_SYMBOL vmlinux 0xe6fc21b0 may_umount_tree +EXPORT_SYMBOL vmlinux 0xe716baed acpi_unregister_ioapic +EXPORT_SYMBOL vmlinux 0xe7525c06 do_sync_read +EXPORT_SYMBOL vmlinux 0xe75ffe04 do_splice_to +EXPORT_SYMBOL vmlinux 0xe78ad1e7 blk_queue_update_dma_pad +EXPORT_SYMBOL vmlinux 0xe7a200c0 key_negate_and_link +EXPORT_SYMBOL vmlinux 0xe7ae317f tcf_unregister_action +EXPORT_SYMBOL vmlinux 0xe7d2aca1 security_sk_classify_flow +EXPORT_SYMBOL vmlinux 0xe7d4daac seq_list_next +EXPORT_SYMBOL vmlinux 0xe7ecb8eb skb_clone +EXPORT_SYMBOL vmlinux 0xe80937c1 tty_hangup +EXPORT_SYMBOL vmlinux 0xe80ce219 sysctl_tcp_dma_copybreak +EXPORT_SYMBOL vmlinux 0xe812cfc9 llc_sap_close +EXPORT_SYMBOL vmlinux 0xe8152e40 jbd2_journal_release_buffer +EXPORT_SYMBOL vmlinux 0xe82b728d sock_get_timestampns +EXPORT_SYMBOL vmlinux 0xe8427ea5 kobject_add +EXPORT_SYMBOL vmlinux 0xe84d7f27 __skb_warn_lro_forwarding +EXPORT_SYMBOL vmlinux 0xe87438a3 inet_stream_ops +EXPORT_SYMBOL vmlinux 0xe8794ce1 slhc_toss +EXPORT_SYMBOL vmlinux 0xe8a3605f acpi_processor_set_thermal_limit +EXPORT_SYMBOL vmlinux 0xe8ba5d67 acpi_root_dir +EXPORT_SYMBOL vmlinux 0xe8cd902e hweight16 +EXPORT_SYMBOL vmlinux 0xe90f2dd3 elv_rq_merge_ok +EXPORT_SYMBOL vmlinux 0xe910b532 del_timer_sync +EXPORT_SYMBOL vmlinux 0xe914e41e strcpy +EXPORT_SYMBOL vmlinux 0xe9447ea7 dma_async_tx_descriptor_init +EXPORT_SYMBOL vmlinux 0xe9456a5a sysctl_xfrm_aevent_rseqth +EXPORT_SYMBOL vmlinux 0xe97ebba5 xfrm_policy_byid +EXPORT_SYMBOL vmlinux 0xe98be4ed pci_get_slot +EXPORT_SYMBOL vmlinux 0xe997667b wrmsr_on_cpu +EXPORT_SYMBOL vmlinux 0xe9a92715 register_quota_format +EXPORT_SYMBOL vmlinux 0xe9b410c6 phy_attach +EXPORT_SYMBOL vmlinux 0xe9d1b50d generic_removexattr +EXPORT_SYMBOL vmlinux 0xe9d4ae39 kernel_listen +EXPORT_SYMBOL vmlinux 0xe9dac7e1 find_inode_number +EXPORT_SYMBOL vmlinux 0xe9e059ea nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0xea10212a int_to_scsilun +EXPORT_SYMBOL vmlinux 0xea10655a __bitmap_intersects +EXPORT_SYMBOL vmlinux 0xea21cd31 phy_device_create +EXPORT_SYMBOL vmlinux 0xea2d33a2 radix_tree_gang_lookup_slot +EXPORT_SYMBOL vmlinux 0xea2ec4ef neigh_resolve_output +EXPORT_SYMBOL vmlinux 0xea30c191 sock_create_kern +EXPORT_SYMBOL vmlinux 0xea389b29 d_namespace_path +EXPORT_SYMBOL vmlinux 0xea6fcdaa genl_unregister_family +EXPORT_SYMBOL vmlinux 0xea7987f1 key_update +EXPORT_SYMBOL vmlinux 0xea858cb5 radix_tree_gang_lookup_tag +EXPORT_SYMBOL vmlinux 0xea926da1 genphy_update_link +EXPORT_SYMBOL vmlinux 0xea9f554d generic_write_end +EXPORT_SYMBOL vmlinux 0xead4bfed jbd2_journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0xead7dcf9 alloc_tty_driver +EXPORT_SYMBOL vmlinux 0xeae3dfd6 __const_udelay +EXPORT_SYMBOL vmlinux 0xeaee7517 ip4_datagram_connect +EXPORT_SYMBOL vmlinux 0xeafbbdc0 dquot_drop +EXPORT_SYMBOL vmlinux 0xeb012f6a pv_cpu_ops +EXPORT_SYMBOL vmlinux 0xeb1fabf6 interruptible_sleep_on +EXPORT_SYMBOL vmlinux 0xeb395084 param_get_invbool +EXPORT_SYMBOL vmlinux 0xeb3d7999 scsi_report_bus_reset +EXPORT_SYMBOL vmlinux 0xeb4c0527 input_release_device +EXPORT_SYMBOL vmlinux 0xeb5d9bca kthread_stop +EXPORT_SYMBOL vmlinux 0xeb8f54b3 strstrip +EXPORT_SYMBOL vmlinux 0xeb9423f7 get_write_access +EXPORT_SYMBOL vmlinux 0xebccc4d1 pcie_get_readrq +EXPORT_SYMBOL vmlinux 0xebd273a6 strict_strtoull +EXPORT_SYMBOL vmlinux 0xebd80937 locks_copy_lock +EXPORT_SYMBOL vmlinux 0xebde63a1 skb_dequeue +EXPORT_SYMBOL vmlinux 0xebe0ec77 mntput_no_expire +EXPORT_SYMBOL vmlinux 0xebfd11ac xfrm_state_delete +EXPORT_SYMBOL vmlinux 0xec2c66ad tcp_enter_memory_pressure +EXPORT_SYMBOL vmlinux 0xec4ebd12 vfs_write +EXPORT_SYMBOL vmlinux 0xec794ba0 __send_remote_softirq +EXPORT_SYMBOL vmlinux 0xec80d755 vfs_rmdir +EXPORT_SYMBOL vmlinux 0xec860422 bioset_free +EXPORT_SYMBOL vmlinux 0xecb778b0 textsearch_unregister +EXPORT_SYMBOL vmlinux 0xecd80ab4 set_anon_super +EXPORT_SYMBOL vmlinux 0xecde1418 _spin_lock_irq +EXPORT_SYMBOL vmlinux 0xecf86113 generic_getxattr +EXPORT_SYMBOL vmlinux 0xecf87244 scsi_reset_provider +EXPORT_SYMBOL vmlinux 0xecf981a0 vm_insert_mixed +EXPORT_SYMBOL vmlinux 0xed1073d8 mb_cache_entry_alloc +EXPORT_SYMBOL vmlinux 0xed122ecf vfs_writev +EXPORT_SYMBOL vmlinux 0xed183a4c sock_no_bind +EXPORT_SYMBOL vmlinux 0xed55991b pci_set_dma_seg_boundary +EXPORT_SYMBOL vmlinux 0xed61bf41 blk_init_queue_node +EXPORT_SYMBOL vmlinux 0xed633abc pv_irq_ops +EXPORT_SYMBOL vmlinux 0xed6ec325 generic_write_checks +EXPORT_SYMBOL vmlinux 0xed9199d1 cdrom_ioctl +EXPORT_SYMBOL vmlinux 0xed91ee1e dev_kfree_skb_irq +EXPORT_SYMBOL vmlinux 0xedbaee5e nla_strcmp +EXPORT_SYMBOL vmlinux 0xedc03953 iounmap +EXPORT_SYMBOL vmlinux 0xedd14538 param_get_uint +EXPORT_SYMBOL vmlinux 0xedd8e03a md_error +EXPORT_SYMBOL vmlinux 0xedda7993 gnet_stats_copy_rate_est +EXPORT_SYMBOL vmlinux 0xee221d75 send_sig_info +EXPORT_SYMBOL vmlinux 0xee2d0fc7 _local_bh_enable +EXPORT_SYMBOL vmlinux 0xee473da8 xfrm_state_delete_tunnel +EXPORT_SYMBOL vmlinux 0xee502e67 i2c_master_recv +EXPORT_SYMBOL vmlinux 0xee7eb9e1 pnp_platform_devices +EXPORT_SYMBOL vmlinux 0xeea935ce hci_resume_dev +EXPORT_SYMBOL vmlinux 0xeea9dbaf bitmap_bitremap +EXPORT_SYMBOL vmlinux 0xeeb1717c param_array_get +EXPORT_SYMBOL vmlinux 0xeebc8844 ht_create_irq +EXPORT_SYMBOL vmlinux 0xeee7e529 per_cpu__softnet_data +EXPORT_SYMBOL vmlinux 0xeee80ec0 iw_handler_get_spy +EXPORT_SYMBOL vmlinux 0xef26a295 init_special_inode +EXPORT_SYMBOL vmlinux 0xef3bd862 mca_find_unused_adapter +EXPORT_SYMBOL vmlinux 0xef82a7bf atm_charge +EXPORT_SYMBOL vmlinux 0xef9967ee pci_find_next_bus +EXPORT_SYMBOL vmlinux 0xef9aedfc boot_option_idle_override +EXPORT_SYMBOL vmlinux 0xef9f8b76 pci_find_slot +EXPORT_SYMBOL vmlinux 0xefaf01db tty_unthrottle +EXPORT_SYMBOL vmlinux 0xefdd70ce security_secid_to_secctx +EXPORT_SYMBOL vmlinux 0xefe099c3 acpi_get_event_status +EXPORT_SYMBOL vmlinux 0xeff14be9 ioremap_cache +EXPORT_SYMBOL vmlinux 0xeffb7093 serio_interrupt +EXPORT_SYMBOL vmlinux 0xf0009fee put_pages_list +EXPORT_SYMBOL vmlinux 0xf00ad598 mdio_bus_type +EXPORT_SYMBOL vmlinux 0xf00e8bff bd_claim +EXPORT_SYMBOL vmlinux 0xf0284b24 bio_phys_segments +EXPORT_SYMBOL vmlinux 0xf02ade6c tcp_timewait_state_process +EXPORT_SYMBOL vmlinux 0xf0324c02 journal_destroy +EXPORT_SYMBOL vmlinux 0xf04864df cdev_init +EXPORT_SYMBOL vmlinux 0xf054fcc5 flush_old_exec +EXPORT_SYMBOL vmlinux 0xf065f629 ioread16be +EXPORT_SYMBOL vmlinux 0xf0682364 elv_dispatch_sort +EXPORT_SYMBOL vmlinux 0xf0ad5e05 unregister_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0xf0b57c68 param_set_long +EXPORT_SYMBOL vmlinux 0xf0f1246c kvasprintf +EXPORT_SYMBOL vmlinux 0xf10de535 ioread8 +EXPORT_SYMBOL vmlinux 0xf11526c1 inode_double_unlock +EXPORT_SYMBOL vmlinux 0xf11543ff find_first_zero_bit +EXPORT_SYMBOL vmlinux 0xf1396c6c blk_queue_dma_alignment +EXPORT_SYMBOL vmlinux 0xf157a7bc skb_pull +EXPORT_SYMBOL vmlinux 0xf15df0c7 pneigh_enqueue +EXPORT_SYMBOL vmlinux 0xf162fe2d sysctl_xfrm_aevent_etime +EXPORT_SYMBOL vmlinux 0xf174ed48 acquire_console_sem +EXPORT_SYMBOL vmlinux 0xf19294db bt_sock_unregister +EXPORT_SYMBOL vmlinux 0xf195c682 fb_invert_cmaps +EXPORT_SYMBOL vmlinux 0xf1a3f7db blk_recount_segments +EXPORT_SYMBOL vmlinux 0xf1b2b5d8 neigh_lookup_nodev +EXPORT_SYMBOL vmlinux 0xf1deabf2 div64_u64 +EXPORT_SYMBOL vmlinux 0xf1e98c74 avenrun +EXPORT_SYMBOL vmlinux 0xf1f06d0b tcp_proc_register +EXPORT_SYMBOL vmlinux 0xf20dabd8 free_irq +EXPORT_SYMBOL vmlinux 0xf21833fc fb_get_buffer_offset +EXPORT_SYMBOL vmlinux 0xf21f6286 dquot_free_inode +EXPORT_SYMBOL vmlinux 0xf23754af tty_hung_up_p +EXPORT_SYMBOL vmlinux 0xf246de13 tcf_hash_destroy +EXPORT_SYMBOL vmlinux 0xf288eecb bio_add_page +EXPORT_SYMBOL vmlinux 0xf2997713 tty_termios_hw_change +EXPORT_SYMBOL vmlinux 0xf2a6d2bf xfrm_policy_count +EXPORT_SYMBOL vmlinux 0xf2afa595 param_get_charp +EXPORT_SYMBOL vmlinux 0xf2cd31f2 sock_no_sendpage +EXPORT_SYMBOL vmlinux 0xf2e74040 mca_set_adapter_name +EXPORT_SYMBOL vmlinux 0xf313da4e sha_transform +EXPORT_SYMBOL vmlinux 0xf31cdd22 tcf_register_action +EXPORT_SYMBOL vmlinux 0xf32374da hci_send_sco +EXPORT_SYMBOL vmlinux 0xf32931aa tcp_rcv_state_process +EXPORT_SYMBOL vmlinux 0xf3341268 __clear_user +EXPORT_SYMBOL vmlinux 0xf338d4c3 netlink_unregister_notifier +EXPORT_SYMBOL vmlinux 0xf346231f seq_list_start_head +EXPORT_SYMBOL vmlinux 0xf394c960 pci_scan_bus_parented +EXPORT_SYMBOL vmlinux 0xf39a246a bio_integrity_split +EXPORT_SYMBOL vmlinux 0xf39bf4d9 put_cmsg +EXPORT_SYMBOL vmlinux 0xf3acb17d kmem_cache_destroy +EXPORT_SYMBOL vmlinux 0xf3b98c29 md_unregister_thread +EXPORT_SYMBOL vmlinux 0xf3bb2c55 mmc_unregister_driver +EXPORT_SYMBOL vmlinux 0xf3bf0bce __bitmap_complement +EXPORT_SYMBOL vmlinux 0xf3e0d7a2 netif_device_detach +EXPORT_SYMBOL vmlinux 0xf3f3de0e blk_queue_bounce +EXPORT_SYMBOL vmlinux 0xf402f0af skb_push +EXPORT_SYMBOL vmlinux 0xf4074881 ilookup5_nowait +EXPORT_SYMBOL vmlinux 0xf407dbb6 scsi_cmd_print_sense_hdr +EXPORT_SYMBOL vmlinux 0xf441ac43 ioread8_rep +EXPORT_SYMBOL vmlinux 0xf455311a nf_register_sockopt +EXPORT_SYMBOL vmlinux 0xf468aa79 hci_connect +EXPORT_SYMBOL vmlinux 0xf48a2c4c MCA_bus +EXPORT_SYMBOL vmlinux 0xf49bc67a atm_pcr_goal +EXPORT_SYMBOL vmlinux 0xf4a5c213 avail_to_resrv_perfctr_nmi_bit +EXPORT_SYMBOL vmlinux 0xf4ae9d51 ida_pre_get +EXPORT_SYMBOL vmlinux 0xf4c863db i2c_register_driver +EXPORT_SYMBOL vmlinux 0xf4d4f703 d_genocide +EXPORT_SYMBOL vmlinux 0xf4e62832 register_atm_ioctl +EXPORT_SYMBOL vmlinux 0xf4f14de6 rtnl_trylock +EXPORT_SYMBOL vmlinux 0xf4f52f93 dqstats +EXPORT_SYMBOL vmlinux 0xf502d273 acpi_get_current_resources +EXPORT_SYMBOL vmlinux 0xf51ae235 touch_nmi_watchdog +EXPORT_SYMBOL vmlinux 0xf525c487 ip_cmsg_recv +EXPORT_SYMBOL vmlinux 0xf52c4e37 udp_lib_getsockopt +EXPORT_SYMBOL vmlinux 0xf535b717 register_console +EXPORT_SYMBOL vmlinux 0xf53b7996 d_rehash +EXPORT_SYMBOL vmlinux 0xf53d4c26 qdisc_class_hash_destroy +EXPORT_SYMBOL vmlinux 0xf5546ae9 no_llseek +EXPORT_SYMBOL vmlinux 0xf5550429 dma_pool_destroy +EXPORT_SYMBOL vmlinux 0xf559c55c __xfrm_route_forward +EXPORT_SYMBOL vmlinux 0xf56caf8b blk_requeue_request +EXPORT_SYMBOL vmlinux 0xf56dcd86 tcp_poll +EXPORT_SYMBOL vmlinux 0xf571d7ce pci_enable_device_mem +EXPORT_SYMBOL vmlinux 0xf578f587 vfs_readlink +EXPORT_SYMBOL vmlinux 0xf5792814 sk_release_kernel +EXPORT_SYMBOL vmlinux 0xf5be9e5c uart_get_baud_rate +EXPORT_SYMBOL vmlinux 0xf5c05914 generic_segment_checks +EXPORT_SYMBOL vmlinux 0xf5cb448b inet_dgram_ops +EXPORT_SYMBOL vmlinux 0xf5ce9811 tcp_memory_allocated +EXPORT_SYMBOL vmlinux 0xf5d2600f key_instantiate_and_link +EXPORT_SYMBOL vmlinux 0xf5d5723b inet6_release +EXPORT_SYMBOL vmlinux 0xf5d90e4f simple_transaction_read +EXPORT_SYMBOL vmlinux 0xf5dbe3b7 tty_get_baud_rate +EXPORT_SYMBOL vmlinux 0xf5fe98a6 add_to_page_cache_locked +EXPORT_SYMBOL vmlinux 0xf60828c5 __ip_select_ident +EXPORT_SYMBOL vmlinux 0xf6262324 filemap_flush +EXPORT_SYMBOL vmlinux 0xf6272dbb eisa_driver_unregister +EXPORT_SYMBOL vmlinux 0xf62901b9 wireless_send_event +EXPORT_SYMBOL vmlinux 0xf6529d7f put_page +EXPORT_SYMBOL vmlinux 0xf6622b93 acpi_lock_ac_dir +EXPORT_SYMBOL vmlinux 0xf6645b57 netlink_clear_multicast_users +EXPORT_SYMBOL vmlinux 0xf670b4cd neigh_sysctl_register +EXPORT_SYMBOL vmlinux 0xf68d5a00 mb_cache_entry_get +EXPORT_SYMBOL vmlinux 0xf694b442 dm_table_unplug_all +EXPORT_SYMBOL vmlinux 0xf69b3871 unmap_underlying_metadata +EXPORT_SYMBOL vmlinux 0xf6bb4729 color_table +EXPORT_SYMBOL vmlinux 0xf6ebc03b net_ratelimit +EXPORT_SYMBOL vmlinux 0xf7373e57 serio_unregister_child_port +EXPORT_SYMBOL vmlinux 0xf7623914 radix_tree_tag_clear +EXPORT_SYMBOL vmlinux 0xf77eac61 console_stop +EXPORT_SYMBOL vmlinux 0xf786ef5e idr_init +EXPORT_SYMBOL vmlinux 0xf78d04ab netlink_register_notifier +EXPORT_SYMBOL vmlinux 0xf79c6076 sync_inode +EXPORT_SYMBOL vmlinux 0xf7ef745f __bread +EXPORT_SYMBOL vmlinux 0xf811e69d scsi_eh_flush_done_q +EXPORT_SYMBOL vmlinux 0xf8241492 lock_super +EXPORT_SYMBOL vmlinux 0xf82abc1d isa_dma_bridge_buggy +EXPORT_SYMBOL vmlinux 0xf82b4077 tty_throttle +EXPORT_SYMBOL vmlinux 0xf82e3d47 acpi_initialize_objects +EXPORT_SYMBOL vmlinux 0xf82f1109 utf8_wctomb +EXPORT_SYMBOL vmlinux 0xf835db16 default_llseek +EXPORT_SYMBOL vmlinux 0xf8814f73 rb_last +EXPORT_SYMBOL vmlinux 0xf88e0ee2 acpi_get_table_header +EXPORT_SYMBOL vmlinux 0xf890fe7f pm_idle +EXPORT_SYMBOL vmlinux 0xf895ef97 acpi_match_device_ids +EXPORT_SYMBOL vmlinux 0xf8aa47ae mutex_lock_killable +EXPORT_SYMBOL vmlinux 0xf8b30e93 mempool_create +EXPORT_SYMBOL vmlinux 0xf8b477d7 __blockdev_direct_IO +EXPORT_SYMBOL vmlinux 0xf8ceb5c3 blk_rq_append_bio +EXPORT_SYMBOL vmlinux 0xf8cf9ee5 abort_exclusive_wait +EXPORT_SYMBOL vmlinux 0xf8d312de fb_show_logo +EXPORT_SYMBOL vmlinux 0xf8ed750c mdiobus_register +EXPORT_SYMBOL vmlinux 0xf9107be5 pci_select_bars +EXPORT_SYMBOL vmlinux 0xf92653e0 simple_getattr +EXPORT_SYMBOL vmlinux 0xf93d556b xfrm_register_km +EXPORT_SYMBOL vmlinux 0xf9a482f9 msleep +EXPORT_SYMBOL vmlinux 0xf9b32de5 pci_bus_type +EXPORT_SYMBOL vmlinux 0xf9e07d63 ethtool_op_set_tx_ipv6_csum +EXPORT_SYMBOL vmlinux 0xf9f039be sk_free +EXPORT_SYMBOL vmlinux 0xfa0564fc __wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0xfa0d78fa tty_chars_in_buffer +EXPORT_SYMBOL vmlinux 0xfa2cb99c mdiobus_read +EXPORT_SYMBOL vmlinux 0xfa33c2b2 pci_match_id +EXPORT_SYMBOL vmlinux 0xfa7efcce skb_copy_datagram_from_iovec +EXPORT_SYMBOL vmlinux 0xfaa68969 single_open +EXPORT_SYMBOL vmlinux 0xfabf4548 hci_unregister_dev +EXPORT_SYMBOL vmlinux 0xfad96b79 i2c_smbus_write_block_data +EXPORT_SYMBOL vmlinux 0xfade5962 scsi_report_device_reset +EXPORT_SYMBOL vmlinux 0xfaf14e52 blk_queue_prep_rq +EXPORT_SYMBOL vmlinux 0xfaf98462 bitrev32 +EXPORT_SYMBOL vmlinux 0xfb038d63 cpu_mask_all +EXPORT_SYMBOL vmlinux 0xfb0443fb acpi_get_parent +EXPORT_SYMBOL vmlinux 0xfb0cf2e9 touch_all_softlockup_watchdogs +EXPORT_SYMBOL vmlinux 0xfb291241 scsi_release_buffers +EXPORT_SYMBOL vmlinux 0xfb3f9f08 tcp_shutdown +EXPORT_SYMBOL vmlinux 0xfb4ecd6d xfrm4_prepare_output +EXPORT_SYMBOL vmlinux 0xfb6af58d recalc_sigpending +EXPORT_SYMBOL vmlinux 0xfb6f1903 blk_queue_segment_boundary +EXPORT_SYMBOL vmlinux 0xfb7b9051 xfrm_prepare_input +EXPORT_SYMBOL vmlinux 0xfb93fe0d inc_zone_page_state +EXPORT_SYMBOL vmlinux 0xfba0c2e0 llc_sap_list_lock +EXPORT_SYMBOL vmlinux 0xfba42ec5 eth_header_parse +EXPORT_SYMBOL vmlinux 0xfba6b7e8 vfs_statfs +EXPORT_SYMBOL vmlinux 0xfbd104c1 unregister_quota_format +EXPORT_SYMBOL vmlinux 0xfbf92453 param_get_bool +EXPORT_SYMBOL vmlinux 0xfbfa664b request_firmware +EXPORT_SYMBOL vmlinux 0xfc02b7ad sysctl_tcp_wmem +EXPORT_SYMBOL vmlinux 0xfc309c3e cancel_delayed_work_sync +EXPORT_SYMBOL vmlinux 0xfc31fe88 l2cap_load +EXPORT_SYMBOL vmlinux 0xfc38be1a __netif_schedule +EXPORT_SYMBOL vmlinux 0xfc39e32f ioport_unmap +EXPORT_SYMBOL vmlinux 0xfc906263 submit_bh +EXPORT_SYMBOL vmlinux 0xfcaa04a0 out_of_line_wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0xfcda63a3 node_states +EXPORT_SYMBOL vmlinux 0xfcdd8cf6 param_get_ushort +EXPORT_SYMBOL vmlinux 0xfcec0987 enable_irq +EXPORT_SYMBOL vmlinux 0xfcfa03ff fb_videomode_to_modelist +EXPORT_SYMBOL vmlinux 0xfd288d67 bdi_destroy +EXPORT_SYMBOL vmlinux 0xfd7d3a4e blk_unplug +EXPORT_SYMBOL vmlinux 0xfd98879a rb_next +EXPORT_SYMBOL vmlinux 0xfda3a13f acpi_is_video_device +EXPORT_SYMBOL vmlinux 0xfda8a6de phy_start +EXPORT_SYMBOL vmlinux 0xfdb9b629 ioread32be +EXPORT_SYMBOL vmlinux 0xfde2145a boot_tvec_bases +EXPORT_SYMBOL vmlinux 0xfde9f1f2 sock_kmalloc +EXPORT_SYMBOL vmlinux 0xfdfc0b3b fiemap_fill_next_extent +EXPORT_SYMBOL vmlinux 0xfdff0e97 netif_device_attach +EXPORT_SYMBOL vmlinux 0xfe5d4bb2 sys_tz +EXPORT_SYMBOL vmlinux 0xfe639efa vfs_link +EXPORT_SYMBOL vmlinux 0xfe6450de __invalidate_device +EXPORT_SYMBOL vmlinux 0xfe769456 unregister_netdevice_notifier +EXPORT_SYMBOL vmlinux 0xfe7c4287 nr_cpu_ids +EXPORT_SYMBOL vmlinux 0xfebdb1e5 file_permission +EXPORT_SYMBOL vmlinux 0xfec3c2f2 bcd2bin +EXPORT_SYMBOL vmlinux 0xfedd35fc console_suspend_enabled +EXPORT_SYMBOL vmlinux 0xfef96e23 __scsi_print_command +EXPORT_SYMBOL vmlinux 0xff0205e7 sock_create_lite +EXPORT_SYMBOL vmlinux 0xff1e9dd8 seq_list_start +EXPORT_SYMBOL vmlinux 0xff31bb82 nf_register_hooks +EXPORT_SYMBOL vmlinux 0xff4a9b50 blk_queue_make_request +EXPORT_SYMBOL vmlinux 0xff6878cf fb_default_cmap +EXPORT_SYMBOL vmlinux 0xff708fd3 mempool_destroy +EXPORT_SYMBOL vmlinux 0xff9312df mnt_pin +EXPORT_SYMBOL vmlinux 0xff982bbd acpi_bus_get_device +EXPORT_SYMBOL vmlinux 0xff9ca065 fb_edid_to_monspecs +EXPORT_SYMBOL vmlinux 0xffa7762c add_disk +EXPORT_SYMBOL vmlinux 0xffafdc5c _read_unlock_irq +EXPORT_SYMBOL vmlinux 0xffb3703a k8_northbridges +EXPORT_SYMBOL vmlinux 0xffc21a9e dm_table_put +EXPORT_SYMBOL vmlinux 0xffd5a395 default_wake_function +EXPORT_SYMBOL vmlinux 0xffdb82bc sg_free_table +EXPORT_SYMBOL vmlinux 0xffea3d00 fb_get_mode +EXPORT_SYMBOL vmlinux 0xffeabb15 get_phy_id +EXPORT_SYMBOL vmlinux 0xffeaf635 simple_readpage +EXPORT_SYMBOL_GPL arch/x86/kernel/microcode 0xdf66ca81 ucode_cpu_info +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x00aaf935 kvm_disable_tdp +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x00d0d27c kvm_resched +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x094ac8f4 kvm_get_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x120cbd1a kvm_set_memory_region +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x12d1b23b kvm_release_pfn_clean +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1324f698 kvm_vcpu_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1765ca36 kvm_release_page_clean +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1e4580bb kvm_release_pfn_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x2285713a kvm_release_page_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x2322e039 kvm_set_pfn_accessed +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x27046576 kvm_exit +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x317f9e6b kvm_enable_efer_bits +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x32d5e10f kvm_cpu_has_interrupt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x34977ba7 gfn_to_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x3738def9 kvm_read_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x37577553 kvm_set_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x394f6ce4 kvm_clear_guest +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x3ac94269 kvm_set_cr3 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x3da6c00e kvm_get_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x4790cc80 kvm_timer_intr_post +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x4a7cbe69 is_error_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x507f3379 kvm_lapic_reset +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x50a924ef kvm_is_visible_gfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x577262ec load_pdptrs +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x599086dd kvm_handle_fault_on_reboot +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x5a6bda4a kvm_lapic_enabled +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x611d6219 kvm_inject_nmi +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x626628a1 gfn_to_hva +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x64c43da1 kvm_mmu_load +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x695cb746 kvm_mmu_reset_context +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x6a221069 emulator_write_emulated +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x6b6e3f28 fx_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x6bda2c46 kvm_lapic_set_tpr +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x6f8c9789 kvm_read_guest +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x72e6920d kvm_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x743cef86 kvm_put_kvm +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x767ad4df kvm_put_guest_fpu +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x76b41dda kvm_set_msr_common +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x76b57aa8 kvm_write_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x836c80c7 kvm_get_kvm +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x88b90354 kvm_task_switch +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8b11570e kvm_get_apic_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8ce4f3ab kvm_enable_tdp +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8d0d6c65 kvm_lapic_get_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8e7f9b47 segment_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x91240ec7 kvm_report_emulation_failure +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x936224de kvm_emulate_cpuid +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x96122d4e kvm_cpu_get_interrupt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x96728cf5 kvm_mmu_invlpg +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x9936c089 kvm_set_cr4 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x9c5902ca kvm_load_guest_fpu +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x9f8146ad kvm_set_page_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa361bc65 kvm_set_pfn_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa4dabf89 kvm_vcpu_uninit +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa68485e7 kvm_get_msr_common +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa84ea415 __kvm_set_memory_region +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa87e8ac2 kvm_queue_exception +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xafab2198 gfn_to_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbd377dc9 kvm_mmu_set_nonpresent_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbd94103b kvm_mmu_set_base_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbf174bde kvm_mmu_page_fault +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xc03a26f6 kvm_set_apic_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xc1e471a4 emulate_instruction +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xc378281e kvm_emulate_pio_string +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xc378779d kvm_create_lapic +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xcc242787 kvm_emulate_hypercall +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xccf45fea kvm_get_cs_db_l_bits +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xcf30913e kvm_clear_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd0b2727a kvm_mmu_set_mask_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd1c41054 kvm_emulate_halt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd296def9 kvm_is_error_hva +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd6e302e4 kvm_queue_exception_e +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd7d13b89 kvm_emulate_pio +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd84abeae kvm_vcpu_cache +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xdcbd7645 emulator_read_std +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xdcc64517 kvm_inject_pending_timer_irqs +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xdee453f6 kvm_x86_ops +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xe1e4100c is_error_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xe8b6ea65 kvm_lapic_find_highest_irr +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xe9a6127c kvm_mmu_unprotect_page_virt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xfce9ac3f kvm_set_cr0 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xfd5942b5 kvm_lmsw +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xfee80e8f kvm_lapic_get_cr8 +EXPORT_SYMBOL_GPL crypto/aes_generic 0x1381bf2d crypto_ft_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x22894d94 crypto_il_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x3339118e crypto_aes_set_key +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5f943003 crypto_it_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5fe743de crypto_aes_expand_key +EXPORT_SYMBOL_GPL crypto/aes_generic 0x6e9cc2ba crypto_fl_tab +EXPORT_SYMBOL_GPL crypto/async_tx/async_memcpy 0xed9c603d async_memcpy +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x69f821a7 async_tx_submit +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x6b4a6db2 async_tx_issue_pending_all +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x938c180a async_tx_quiesce +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0xac3915aa async_trigger_callback +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0xe097dfd9 __async_tx_find_channel +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0xf72afdfe async_tx_run_dependencies +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0xff9fa147 dma_wait_for_async_tx +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0x3dac3030 async_xor_zero_sum +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0x6fceb0ce async_xor +EXPORT_SYMBOL_GPL crypto/des_generic 0xcfd9a2c0 des_ekey +EXPORT_SYMBOL_GPL crypto/twofish_common 0xe8e4dd13 twofish_setkey +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x02ff9464 cfag12864b_isinited +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x0ecb2e5d cfag12864b_disable +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x305dc3c6 cfag12864b_isenabled +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x3389f926 cfag12864b_enable +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x9522a342 cfag12864b_getrate +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0xc48e9d95 cfag12864b_buffer +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x14102f23 ks0108_displaystate +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x48a70518 ks0108_writedata +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x4f506333 ks0108_startline +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x6edae968 ks0108_isinited +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xbf4774db ks0108_writecontrol +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xedde6df2 ks0108_page +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xfee8ef7b ks0108_address +EXPORT_SYMBOL_GPL drivers/char/agp/agpgart 0x2fd40275 agp_remove_bridge +EXPORT_SYMBOL_GPL drivers/char/agp/agpgart 0xd6feefa5 agp_num_entries +EXPORT_SYMBOL_GPL drivers/char/agp/agpgart 0xe089cfcc agp_memory_reserved +EXPORT_SYMBOL_GPL drivers/char/agp/agpgart 0xe38ed4b1 agp_add_bridge +EXPORT_SYMBOL_GPL drivers/char/scx200_gpio 0x8a726d3c scx200_gpio_ops +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x0523e41b tpm_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x1551b99e tpm_show_pcrs +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x18366fef tpm_show_temp_deactivated +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x26573db3 tpm_write +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x31247a25 tpm_calc_ordinal_duration +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x42b9ab90 tpm_register_hardware +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x4f2293c9 tpm_store_cancel +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x5927140c tpm_dev_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x74293d64 tpm_open +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x8182a2f2 tpm_show_enabled +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x8a8ca072 tpm_pm_suspend +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x96d367e2 tpm_show_pubek +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x9cea0911 tpm_show_active +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x9fd5b480 tpm_show_caps +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xae49062c tpm_gen_interrupt +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xb2face37 tpm_continue_selftest +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xcad20523 tpm_remove_hardware +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xd6769b31 tpm_read +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xe0274911 tpm_show_caps_1_2 +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xe2a4fc61 tpm_show_owned +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xe971fc74 tpm_dev_vendor_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xe9ac4564 tpm_pm_resume +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xf54cf356 tpm_get_timeouts +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm_bios 0x11bed228 tpm_bios_log_setup +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm_bios 0x51a3bd9b tpm_bios_log_teardown +EXPORT_SYMBOL_GPL drivers/dca/dca 0x2e471f01 dca_register_notify +EXPORT_SYMBOL_GPL drivers/dca/dca 0x31a2c8df dca_get_tag +EXPORT_SYMBOL_GPL drivers/dca/dca 0x44a721c8 free_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0x61ebf42f dca_remove_requester +EXPORT_SYMBOL_GPL drivers/dca/dca 0x6823cd90 register_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0x8006c614 dca_unregister_notify +EXPORT_SYMBOL_GPL drivers/dca/dca 0x889a364d dca3_get_tag +EXPORT_SYMBOL_GPL drivers/dca/dca 0xad8910ba dca_add_requester +EXPORT_SYMBOL_GPL drivers/dca/dca 0xc785f6ed alloc_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0xddb923c3 unregister_dca_provider +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x11a4340f edac_pci_handle_npe +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x2845730d edac_device_free_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x294e5ace edac_pci_free_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x2bb6f925 edac_device_add_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x458bbecd edac_device_alloc_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x4841991d edac_pci_handle_pe +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x4f0cc8c1 edac_pci_del_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x500d5bee edac_mc_del_mc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x554d5758 edac_mc_alloc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x668fbfd1 edac_device_handle_ce +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x73f65efe edac_pci_create_generic_ctl +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x91eaa81c edac_pci_add_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x9d2d1ecd edac_mc_find_csrow_by_page +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xa098a88d edac_mc_handle_ce_no_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xa1fc5be1 edac_mc_handle_ce +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xab889d5e edac_device_handle_ue +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xb2447616 edac_mc_free +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xb73ddfe1 edac_mc_handle_ue +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xba4f11a1 edac_mc_handle_ue_no_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xbef155a0 edac_mc_add_mc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xc029461c edac_device_del_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xc9db4639 edac_pci_reset_delay_period +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xdf77a7a7 edac_pci_release_generic_ctl +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xf7384c10 edac_pci_alloc_ctl_info +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x01fd453e usbhid_lookup_quirk +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x02df65bf hiddev_hid_event +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x57b9d8ea usbhid_submit_report +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0xb1f99af3 usbhid_set_leds +EXPORT_SYMBOL_GPL drivers/i2c/busses/i2c-nforce2 0x2ecaca04 nforce2_smbus +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0x466bf223 hpsb_config_rom_ip1394_add +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0xec8d18cf hpsb_disable_irm +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0xed5730b4 hpsb_config_rom_ip1394_remove +EXPORT_SYMBOL_GPL drivers/input/ff-memless 0xc9888c56 input_ff_create_memless +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x08b28cf8 wm9713_codec +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x338090a6 wm97xx_config_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x55afcdef wm97xx_set_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x6cba7bcc wm97xx_reg_read +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x7c50238c wm97xx_get_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x92de5f66 wm97xx_reg_write +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xb051adf9 wm97xx_unregister_mach_ops +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xc4188c66 wm9712_codec +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xcb87f5a1 wm97xx_read_aux_adc +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xd802c09c wm97xx_register_mach_ops +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xd9a6913c wm9705_codec +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xdb5b7fee wm97xx_set_suspend_mode +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x01aa6bd0 gigaset_freecs +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x19f9e984 gigaset_skb_sent +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x2f57d131 gigaset_add_event +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x38aa9012 gigaset_initdriver +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x443acae9 gigaset_handle_modem_response +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x454aa44f gigaset_debuglevel +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x46918217 gigaset_m10x_send_skb +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x4e792275 gigaset_dbg_buffer +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x6ad39b2c gigaset_fill_inbuf +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x88dcc0dd gigaset_stop +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x9c26be46 gigaset_start +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x9d0be809 gigaset_initcs +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x9facd002 gigaset_shutdown +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xa250ee87 gigaset_freedriver +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xd7de9a01 gigaset_blockdriver +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xe9490780 gigaset_if_receive +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xfd0f2bac gigaset_m10x_input +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x001a452c led_classdev_suspend +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x3477a6c5 led_classdev_register +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x4d02026f led_classdev_resume +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x834bd65a led_classdev_unregister +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x04662e0f ir_codes_fusionhdtv_mce +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x07e92917 ir_codes_avermedia_a16d +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x083661f9 ir_codes_avertv_303 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x088631b9 ir_codes_behold +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x1cb148f5 ir_extract_bits +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2456e513 ir_decode_pulsedistance +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2a4852cc ir_codes_dntv_live_dvb_t +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2af1a608 ir_codes_proteus_2309 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x3811daea ir_codes_manli +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x3c93e96b ir_input_init +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x43c89ef4 ir_decode_biphase +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x45b08f68 ir_codes_pinnacle_grey +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4740e7a3 ir_codes_empty +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4beb7618 ir_codes_encore_enltv_fm53 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4ea698a2 ir_codes_purpletv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x55338dda ir_codes_pixelview_new +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x589cad50 ir_codes_apac_viewcomp +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x5db13554 ir_codes_encore_enltv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6606596a ir_rc5_timer_keyup +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6adc476d ir_codes_powercolor_real_angel +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6aefdbea ir_codes_npgtech +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6b87c69d ir_codes_iodata_bctv7e +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6d6511e7 ir_dump_samples +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6e2a1870 ir_codes_adstech_dvb_t_pci +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x7277973d ir_codes_pctv_sedna +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x75e89cc3 ir_codes_flydvb +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x772a30a2 ir_codes_nebula +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x7b38143b ir_codes_encore_enltv2 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x85d37490 ir_codes_dntv_live_dvbt_pro +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x89cc1189 ir_codes_winfast +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x902a3cd2 ir_codes_hauppauge_new +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x933d0bb3 ir_codes_msi_tvanywhere +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x9451e232 ir_codes_behold_columbus +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x96470cab ir_codes_cinergy +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb1f4eb35 ir_codes_avermedia_dvbt +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb50812de ir_codes_real_audio_220_32_keys +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb64beea7 ir_input_nokey +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb6cd4666 ir_codes_eztv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xbb08d146 ir_codes_msi_tvanywhere_plus +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xbdce6594 ir_codes_tt_1500 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc1fea0c1 ir_codes_pv951 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc42bd037 ir_codes_budget_ci_old +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc6c5a7a1 ir_codes_em_terratec +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xcdf2859f ir_codes_avermedia_m135a +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd1e0258a ir_codes_flyvideo +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd55e6891 ir_codes_gotview7135 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd9c7f010 ir_codes_rc5_tv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xdaa041ad ir_codes_cinergy_1400 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xdfcf23df ir_codes_norwood +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xe2da5734 ir_input_keydown +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xee2f5e0e ir_codes_pinnacle_pctv_hd +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf07533a1 ir_codes_videomate_tv_pvr +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf0fc9374 ir_codes_avermedia +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf2b421aa ir_codes_genius_tvgo_a11mce +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf4f7a4d6 ir_rc5_timer_end +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfa177653 ir_codes_pixelview +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfb981300 ir_codes_pinnacle_color +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfc54a5cd ir_codes_asus_pc39 +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x17a998dc saa7146_unregister_extension +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x37d62e0c saa7146_pgtable_build_single +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x395ebf2c saa7146_i2c_adapter_prepare +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x73566b5a saa7146_vmalloc_build_pgtable +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xad1cc9ea saa7146_pgtable_free +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xc98faf20 saa7146_devices_lock +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xcf683cf2 saa7146_devices +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xd62d8b10 saa7146_setgpio +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xe0afc86d saa7146_vfree_destroy_pgtable +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xe3cd9b5c saa7146_debug +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xed37cb1f saa7146_wait_for_debi_done +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xf5a1a1f1 saa7146_pgtable_alloc +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xf984fa75 saa7146_register_extension +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x1c751d5e saa7146_start_preview +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x23529a8a saa7146_set_hps_source_and_sync +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x310a2d2c saa7146_register_device +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x440f6cb5 saa7146_stop_preview +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xafb88102 saa7146_unregister_device +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xbb5103fc saa7146_vv_init +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xc5b22c6f saa7146_vv_release +EXPORT_SYMBOL_GPL drivers/media/common/tuners/mt20xx 0x1edaa2f4 microtune_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/mxl5007t 0x70a28944 mxl5007t_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda18271 0xf1765e2c tda18271_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda827x 0x61918787 tda827x_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda8290 0xc53f09b4 tda829x_probe +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda8290 0xd878abf7 tda829x_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda9887 0x6c7147bc tda9887_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5761 0x1a1e45fe tea5761_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5761 0x229b91a8 tea5761_autodetection +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5767 0x61cfedd5 tea5767_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5767 0xb13ede2d tea5767_autodetection +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tuner-simple 0xfb9a8ff8 simple_tuner_attach +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x027aad69 ttpci_budget_init_hooks +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x1161cc28 ttpci_budget_deinit +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x321b270b ttpci_budget_debiwrite +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x7948c222 budget_debug +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x833a23b6 ttpci_budget_irq10_handler +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x90f13606 ttpci_budget_debiread +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xa3acd634 ttpci_budget_init +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xc7c82907 ttpci_budget_set_video_port +EXPORT_SYMBOL_GPL drivers/media/video/compat_ioctl32 0x92e0208f v4l_compat_ioctl32 +EXPORT_SYMBOL_GPL drivers/media/video/cx88/cx88xx 0x5a14a58c cx88_setup_xc3028 +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x7fc8652c em28xx_tuner_callback +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0xa35f9112 em28xx_uninit_isoc +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0xc5095987 em28xx_set_mode +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0xd17baca0 em28xx_audio_analog_set +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0xe95ea2cc em28xx_init_isoc +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x1eabab52 saa7134_i2c_call_saa6752 +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x3c362545 saa7134_s_ctrl_internal +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x69e33941 saa7134_queryctrl +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0xc48bdafe saa7134_ts_qops +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0xddf3f105 saa7134_g_ctrl_internal +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0xe89e2f96 saa7134_s_std_internal +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0x81bd0c45 v4l2_int_device_register +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xa5228b24 v4l2_int_device_try_attach_all +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xab9d0e9d v4l2_int_ioctl_1 +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xba7ba394 v4l2_int_device_unregister +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xdfcc42de v4l2_int_ioctl_0 +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x05e60d55 videobuf_streamon +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x0dd98205 videobuf_queue_is_busy +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x1769ec74 videobuf_querybuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x1daee886 videobuf_next_field +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x2273126a videobuf_iolock +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x23340aa8 videobuf_waiton +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x3cc11301 videobuf_queue_to_vmalloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x598c1a57 videobuf_read_start +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x5ce99d03 videobuf_read_stream +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x65a8eb77 videobuf_cgmbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x675c0560 videobuf_mmap_mapper +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x68dff634 videobuf_reqbufs +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x716d3649 videobuf_queue_core_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x850435c7 videobuf_read_stop +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x8f9bc521 videobuf_mmap_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x92566ff5 videobuf_stop +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x95b231dd videobuf_streamoff +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x9ad35d46 videobuf_dqbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xa235f4b8 __videobuf_mmap_setup +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xb14e4d2f videobuf_read_one +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xc4bb06f2 videobuf_queue_cancel +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xd770d7d2 videobuf_poll_stream +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xe3e86cb1 videobuf_alloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xe9ac4923 videobuf_mmap_setup +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xfbaedc80 videobuf_qbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-contig 0x124eeaeb videobuf_to_dma_contig +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-contig 0x6e5d1a2a videobuf_dma_contig_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-contig 0x81f4f0f9 videobuf_queue_dma_contig_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x06bf21c8 videobuf_dma_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x30fa20d5 videobuf_dma_unmap +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x3b81cd32 videobuf_sg_dma_unmap +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x4444c29d videobuf_dma_sync +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x57ebd78d videobuf_dma_init_kernel +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x6edc5835 videobuf_sg_dma_map +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x74a642c2 videobuf_dma_map +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x844415b7 videobuf_dma_init_user +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x92f3f7ef videobuf_queue_sg_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xa4e148ca videobuf_dma_init_overlay +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xa825c75b videobuf_sg_alloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xe8a24336 videobuf_vmalloc_to_sg +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xf4c5fae6 videobuf_to_dma +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xff693236 videobuf_dma_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0x43e5c5e4 videobuf_to_vmalloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0x88f6136c videobuf_vmalloc_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0xa34e6009 videobuf_queue_vmalloc_init +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x0c28d894 i2o_pool_alloc +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x32256dd1 i2o_sg_tablesize +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x6f4551c7 i2o_dma_map_sg +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x98d97244 i2o_dma_free +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xc2d9008a i2o_dma_realloc +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xd82d6f8b i2o_dma_alloc +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xf03dba09 i2o_dma_map_single +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xff582359 i2o_pool_free +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x0c43fec0 sm501_unit_power +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x2499d603 sm501_misc_control +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x3e258eea sm501_set_clock +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0xad3cd42c sm501_modify_reg +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0xc07f9ca1 sm501_find_clock +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x1ae12594 wm8350_block_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x20d0ccab wm8350_device_exit +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x24dec154 wm8350_register_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x2baf07d2 wm8350_reg_write +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x3633d683 wm8350_clear_bits +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x4574d3f4 wm8350_reg_unlock +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x4578ce38 wm8350_reg_lock +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x4a9a6dd5 wm8350_reg_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x70c56086 wm8350_mask_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x7b087a51 wm8350_gpio_config +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x853943a0 wm8350_free_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xa040bf01 wm8350_set_bits +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xcea38f7c wm8350_unmask_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xd9361fff wm8350_block_write +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xfb813635 wm8350_device_init +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x0bb54e6b wm8400_set_bits +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x16b0884f wm8400_block_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x35bc9a65 wm8400_reset_codec_reg_cache +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x87a2cab8 wm8400_reg_read +EXPORT_SYMBOL_GPL drivers/misc/eeprom_93cx6 0x2df115d4 eeprom_93cx6_multiread +EXPORT_SYMBOL_GPL drivers/misc/eeprom_93cx6 0x63d14d2f eeprom_93cx6_read +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x3f99015a enclosure_for_each_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x4029c968 enclosure_register +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x5169a604 enclosure_unregister +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x80bda328 enclosure_find +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0xb6417eaa enclosure_remove_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0xd062078b enclosure_add_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0xdea09b14 enclosure_component_register +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x3b004f8f sdhci_free_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x67cebf1d sdhci_resume_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x9b2f70e1 sdhci_remove_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0xbb5628e7 sdhci_suspend_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0xc008afde sdhci_alloc_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0xe55ff185 sdhci_add_host +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0x48c7d4ff cfi_cmdset_0001 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0xba8a6fa2 cfi_cmdset_0200 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0xd183ad73 cfi_cmdset_0003 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0002 0x9d2191b5 cfi_cmdset_0002 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0020 0xe0f2634b cfi_cmdset_0020 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0xb83d9f7a cfi_qry_present +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0xc3c3cb2a cfi_qry_mode_off +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0xe7dfc967 cfi_qry_mode_on +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2000 0xb3639d52 DoC2k_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2001 0xad91d591 DoCMil_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2001plus 0xef1b13eb DoCMilPlus_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/docecc 0x45937659 doc_decode_ecc +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x13797368 put_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x2af2e64e register_mtd_user +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x334c31b1 add_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x3f796bce del_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x4761687b mtd_erase_callback +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x5b8b14d7 register_mtd_parser +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x5c72622e get_sb_mtd +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x62fa23d3 kill_mtd_super +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x6692d8ff parse_mtd_partitions +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x81c51c95 unregister_mtd_user +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xa0292e35 deregister_mtd_parser +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xb4684a97 default_mtd_writev +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xcca76c15 get_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xd442aed2 get_mtd_device_nm +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xeff64be1 mtd_table_mutex +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xf9cfef72 mtd_table +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0x064f5663 del_mtd_blktrans_dev +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0x1a3845cb add_mtd_blktrans_dev +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0x492426ed register_mtd_blktrans +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0xd2042e7f deregister_mtd_blktrans +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x168de54d nand_wait_ready +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x827d7a6a nand_scan_tail +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xa65bdd79 nand_release +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xc214c6d0 nand_scan_ident +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xc2d98888 nand_scan +EXPORT_SYMBOL_GPL drivers/mtd/onenand/onenand 0x00db2f33 onenand_release +EXPORT_SYMBOL_GPL drivers/mtd/onenand/onenand 0x8d873735 onenand_scan +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x158b1839 ubi_leb_change +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x22d96e3b ubi_leb_erase +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x3a9470ee ubi_leb_read +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x42801d20 ubi_sync +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x78a3c0b0 ubi_is_mapped +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x7a1512e3 ubi_open_volume +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x88892278 ubi_leb_write +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xa0831495 ubi_get_volume_info +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xbc505df4 ubi_get_device_info +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xe456e3b7 ubi_leb_map +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xe4844988 ubi_close_volume +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xf41e71dc ubi_open_volume_nm +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xf44b65cd ubi_leb_unmap +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0385b3b5 mlx4_qp_remove +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0e05d510 mlx4_mtt_init +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0e970be6 mlx4_qp_reserve_range +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0f8fbaf8 mlx4_cq_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x11fbbce9 mlx4_qp_release_range +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x1e1d6808 mlx4_register_interface +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x1f74337f mlx4_unregister_interface +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x1fc33d87 mlx4_buf_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x28e8a810 mlx4_cq_resize +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x3604f801 __mlx4_cmd +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x367a0ca3 mlx4_mr_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x392bb997 mlx4_register_mac +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x39a77d92 mlx4_mtt_addr +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x3ac35d08 mlx4_fmr_unmap +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x40bb8d8e mlx4_fmr_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x4ae49dbe mlx4_write_mtt +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x4fc0c00e mlx4_buf_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5299b0c3 mlx4_mtt_cleanup +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x540ad9d7 mlx4_pd_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5733ee3c mlx4_mr_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5a1bac3f mlx4_CLOSE_PORT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5adbf23b mlx4_register_vlan +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5fcbe6cc mlx4_SYNC_TPT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x6102a025 mlx4_qp_query +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x62de7405 mlx4_qp_to_ready +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x68aa376e mlx4_INIT_PORT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x6a1d70e6 mlx4_mr_enable +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x78b52ad0 mlx4_free_cmd_mailbox +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x82698db7 mlx4_qp_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x857bdd9f mlx4_map_phys_fmr +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x8bdeb575 mlx4_uar_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x8cf7660e mlx4_qp_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x95b1bd1e mlx4_srq_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xa563a2ae mlx4_db_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xa6412be9 mlx4_srq_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xaa0c87f9 mlx4_srq_query +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xb2596162 mlx4_unregister_vlan +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xb3e94154 mlx4_db_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xb888cfd0 mlx4_uar_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xc3e92d0e mlx4_fmr_enable +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xcef12d83 mlx4_pd_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xd29acbc1 mlx4_qp_modify +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xd6a0dc01 mlx4_multicast_attach +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xd6b3facb mlx4_free_hwq_res +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xd7286a01 mlx4_cq_modify +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xd99365fb mlx4_cq_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xda766c22 mlx4_multicast_detach +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xdcd3ab04 mlx4_srq_arm +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xe28c14d6 mlx4_alloc_hwq_res +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xed35ec69 mlx4_unregister_mac +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xedf1fdba mlx4_buf_write_mtt +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf4aec2b0 mlx4_fmr_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf4ee704e mlx4_alloc_cmd_mailbox +EXPORT_SYMBOL_GPL drivers/net/usb/cdc_ether 0x7f929d1b usbnet_generic_cdc_bind +EXPORT_SYMBOL_GPL drivers/net/usb/cdc_ether 0xf00303aa usbnet_cdc_unbind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x4e3e8b96 rndis_command +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x67d2b25c rndis_unbind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x6f1c3a91 rndis_status +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xa536288a generic_rndis_bind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xa685a602 rndis_rx_fixup +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xc4bf1e35 rndis_tx_fixup +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x009b32cb usbnet_set_settings +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x013799f4 usbnet_resume +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x1317e48e usbnet_skb_return +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x1f146302 usbnet_disconnect +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x20fec5b3 usbnet_get_drvinfo +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x2b22be6f usbnet_get_link +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xa6e76fbb usbnet_suspend +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xa92b1c02 usbnet_get_endpoints +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xb07d70af usbnet_unlink_rx_urbs +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xbd11944a usbnet_defer_kevent +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xc4f64b59 usbnet_get_msglevel +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xc794059b usbnet_get_settings +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xcab0d4ac usbnet_probe +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xf094b1c7 usbnet_nway_reset +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xfd2894ce usbnet_set_msglevel +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x0072f025 lbs_stop_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x0d3ac0e6 lbs_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x0e901196 lbs_remove_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x116c6a1a lbs_process_rxed_packet +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x24cd6274 lbs_notify_command_response +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x3c8654d0 lbs_queue_event +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x4ec3db11 lbs_cmd_802_11_rate_adapt_rateset +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x5407e70e lbs_send_tx_feedback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x853849cf lbs_start_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x95957d21 lbs_add_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xa323cecb __lbs_cmd +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xb17f040d lbs_host_sleep_cfg +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xdbb75d8a lbs_cmd_copyback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xe8414f72 lbs_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xea66e480 lbs_host_to_card_done +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xf64277de lbs_debug +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x0bbfb424 lbtf_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x192ba27e lbtf_cmd_response_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x3e6b9e39 lbtf_remove_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x674f5445 __lbtf_cmd +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x69655cc1 lbtf_send_tx_feedback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x798ea19a lbtf_bcn_sent +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xc3a02a41 lbtf_add_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xf6b69372 lbtf_cmd_copyback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf_usb 0x3937c738 if_usb_reset_device +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf_usb 0xf351eb07 if_usb_prog_firmware +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x1bf3194c p54_parse_firmware +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x24be1a39 p54_read_eeprom +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x2d9fc7f8 p54_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x3c34d947 p54_free_common +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0xbbdf846a p54_init_common +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x1cbb892f rt2x00lib_probe_dev +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x2cfc4201 rt2x00lib_rxdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x32c51aa5 rt2x00mac_stop +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x4978b7ee rt2x00queue_get_entry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x4d2ce5f5 rt2x00queue_get_queue +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x570d415e rt2x00mac_add_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x57bfb359 rt2x00mac_config_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x6dea856b rt2x00mac_get_tx_stats +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x75e784f3 rt2x00lib_txdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x791d2349 rt2x00lib_beacondone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x83399aa3 rt2x00lib_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x836a7c6f rt2x00lib_remove_dev +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x86c15b86 rt2x00mac_conf_tx +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x98877520 rt2x00mac_remove_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xa21a5192 rt2x00mac_tx +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xaa4ea34a rt2x00mac_bss_info_changed +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xaa6cd1ca rt2x00mac_set_key +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xc8783423 rt2x00mac_config +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xcf8ad64c rt2x00mac_start +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xd1d91346 rt2x00mac_configure_filter +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xefee3240 rt2x00mac_get_stats +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xf1beb874 rt2x00queue_map_txskb +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xf48540c8 rt2x00lib_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x2c2e94d0 rt2x00pci_probe +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x4fe4086b rt2x00pci_initialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x56abda3e rt2x00pci_rxdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0xb2cae05c rt2x00pci_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0xc85448ca rt2x00pci_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0xe58c3d1f rt2x00pci_uninitialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0xe75fff61 rt2x00pci_write_tx_data +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0xf12ca73e rt2x00pci_remove +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x00214ba3 rt2x00usb_write_tx_data +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x0108cee4 rt2x00usb_disconnect +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x055cb409 rt2x00usb_initialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x12e1bff7 rt2x00usb_kick_tx_queue +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x22b3a721 rt2x00usb_disable_radio +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x257352e9 rt2x00usb_vendor_request +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x4539f309 rt2x00usb_init_rxentry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x4a864875 rt2x00usb_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x70908125 rt2x00usb_uninitialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x92ed88c8 rt2x00usb_vendor_req_buff_lock +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xa4ab196f rt2x00usb_vendor_request_buff +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xacce5140 rt2x00usb_probe +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xb1308ded rt2x00usb_init_txentry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xc279b897 rt2x00usb_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xc50e0a6b rt2x00usb_vendor_request_large_buff +EXPORT_SYMBOL_GPL drivers/pci/hotplug/acpiphp 0x6e2d4da7 acpiphp_register_attention +EXPORT_SYMBOL_GPL drivers/pci/hotplug/acpiphp 0xed3e8f8c acpiphp_unregister_attention +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0x3feb1adb wm8350_dcdc25_set_mode +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0x566fb831 wm8350_register_regulator +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0xa627279d wm8350_ldo_set_slot +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0xde755ba5 wm8350_isink_set_flash +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0xe37ba48e wm8350_dcdc_set_slot +EXPORT_SYMBOL_GPL drivers/regulator/wm8400-regulator 0xb1c0b6af wm8400_register_regulator +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x0233f349 iscsi_pool_init +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x0af6b734 iscsi_queuecommand +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x1af40e4e iscsi_suspend_tx +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x240449d2 iscsi_session_setup +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x2b504f86 iscsi_itt_to_ctask +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x3146c1cb __iscsi_complete_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x31b9f4de iscsi_session_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x34cc7b2c iscsi_host_remove +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x41ba1d14 iscsi_pool_free +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x48475293 iscsi_session_recovery_timedout +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x5fe68dcc iscsi_conn_teardown +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x5feaaa00 iscsi_eh_target_reset +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x658c94de iscsi_conn_send_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x70a99c63 iscsi_requeue_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x734c554c iscsi_host_set_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x7645ade4 iscsi_conn_stop +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x82bb970f iscsi_change_queue_depth +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x8a2e2b0f iscsi_prep_unsolicit_data_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x99fb8b34 iscsi_host_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xa3116d97 iscsi_set_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xbbd2ae24 iscsi_host_free +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xbd947ee9 iscsi_session_teardown +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xc0ab0c6a iscsi_host_add +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xc390802f iscsi_update_cmdsn +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xc62f6fde iscsi_conn_failure +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xc9913c9f iscsi_conn_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xcc02ffb7 iscsi_host_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xd1098bb5 iscsi_eh_abort +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xd2f2e70a iscsi_conn_bind +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xe295eea7 iscsi_verify_itt +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xe512358f iscsi_conn_start +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xe90d3123 iscsi_session_failure +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xed419a6b iscsi_conn_setup +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xedf20220 iscsi_eh_device_reset +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xf480994f iscsi_put_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xf7e3ef8b __iscsi_get_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xff956d2c iscsi_complete_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x02903dc4 sas_task_abort +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x05b8fd97 __sas_task_abort +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x1d07e569 sas_target_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x22b93bae sas_slave_configure +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x25706b7f sas_ioctl +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x26cb376b sas_slave_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x293a85c0 sas_phy_enable +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x2bc1feb9 sas_eh_bus_reset_handler +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x664ee7ab sas_slave_destroy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x67789792 sas_target_destroy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x887bae1b sas_find_local_phy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x8df527ef sas_phy_reset +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x8e35511a sas_change_queue_type +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x9c36166e sas_domain_release_transport +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xa59ab4e5 sas_unregister_ha +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xcbedb89c sas_domain_attach_transport +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xce56c959 sas_eh_device_reset_handler +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xd62ed029 sas_queuecommand +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xd8d0aef6 sas_request_addr +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xe64f843f sas_change_queue_depth +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xf5e36b21 sas_bios_param +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xf714e1c1 sas_ssp_task_response +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xfb0f71c8 sas_register_ha +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x04c846ea srp_iu_put +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x09653e90 srp_transfer_data +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x24b587a0 srp_target_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x62e74107 srp_cmd_queue +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x9db72d8a srp_target_free +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0xc94d9473 srp_iu_get +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x162a64f0 scsi_host_put_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x294b0c61 scsi_tgt_tsk_mgmt_request +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x404091a2 scsi_tgt_alloc_queue +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x78298baf scsi_tgt_queue_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x8008dbfd scsi_host_get_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xa52376e3 scsi_tgt_free_queue +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xb5259391 scsi_tgt_cmd_to_host +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xd4837328 scsi_tgt_it_nexus_destroy +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xe5749969 scsi_tgt_it_nexus_create +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x02c336df iscsi_conn_error_event +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x107e2c5b iscsi_destroy_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x179faf08 iscsi_host_for_each_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x2e103c46 iscsi_recv_pdu +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x333a57c6 iscsi_destroy_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x39d1888d iscsi_create_conn +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x3f95af7f iscsi_session_event +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x582de462 iscsi_alloc_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x611fc6e3 iscsi_unblock_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x633b1eb3 iscsi_remove_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x6ca05727 iscsi_lookup_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x8c1c135a iscsi_scan_finished +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x93c26145 iscsi_session_chkready +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x959f134e iscsi_block_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x9701dad5 iscsi_destroy_conn +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xa7376b17 iscsi_add_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xaa354775 iscsi_free_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xbd78db1b iscsi_create_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xd1e6210f iscsi_unregister_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xecb8a669 iscsi_create_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xf349b22c iscsi_register_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0x0ef06974 spi_populate_ppr_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0xa0c71dac spi_populate_sync_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0xcffa2aff spi_populate_width_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x12179e92 srp_remove_host +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x68ffe854 srp_rport_del +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x78b07519 srp_rport_add +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x95aff7ec srp_release_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0xd6889238 srp_attach_transport +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x041028d6 spi_bitbang_setup_transfer +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x06f28585 spi_bitbang_cleanup +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x1c5e6024 spi_bitbang_stop +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x470938e5 spi_bitbang_start +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0xcbeae7ad spi_bitbang_transfer +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0xf894712f spi_bitbang_setup +EXPORT_SYMBOL_GPL drivers/uio/uio 0x6f0e18d1 __uio_register_device +EXPORT_SYMBOL_GPL drivers/uio/uio 0xcd2893e7 uio_event_notify +EXPORT_SYMBOL_GPL drivers/uio/uio 0xe5eaf771 uio_unregister_device +EXPORT_SYMBOL_GPL drivers/usb/atm/usbatm 0xc4e46304 usbatm_usb_disconnect +EXPORT_SYMBOL_GPL drivers/usb/atm/usbatm 0xc527da0f usbatm_usb_probe +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x031acdce usb_ftdi_elan_edset_single +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x14c038cd ftdi_elan_gone_away +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x1b417b8e usb_ftdi_elan_edset_output +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x25df8b36 usb_ftdi_elan_edset_flush +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x8340b0d5 usb_ftdi_elan_edset_setup +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xb3a3c2dd usb_ftdi_elan_edset_input +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xe09d9bcb usb_ftdi_elan_edset_empty +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xe78901ca usb_ftdi_elan_write_pcimem +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xfa5166a9 usb_ftdi_elan_read_pcimem +EXPORT_SYMBOL_GPL drivers/usb/misc/phidget 0x13a0b2da phidget_class +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x02769402 rpipe_ep_disable +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x087c2b44 __wa_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x4e9e2a11 wa_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x6ac7ef9f wa_urb_dequeue +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xcb55ad58 rpipe_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xdf7ad78c wa_urb_enqueue +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xf4654c3f wa_urb_enqueue_run +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x0bb6bf5e wusb_cluster_id_get +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x0c5a6eae wusbhc_b_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x0ebffa88 wusbhc_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x1222b8e5 wusbhc_rh_status_data +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x135be3a9 wusbhc_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x1869e077 wusbhc_handle_dn +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x25182a08 __wusb_dev_get_by_usb_dev +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x25c2c58c wusbhc_giveback_urb +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x39aa6e17 wusbhc_b_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x44288e71 wusbhc_mmcie_set +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x4f266c96 wusbhc_reset_all +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x56924b01 wusbhc_rh_suspend +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x5815d521 wusbhc_rh_resume +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x5ac264ec wusbhc_stop +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x7de9541e wusbhc_mmcie_rm +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x7f0b7631 wusb_dev_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x96e7d7e3 wusbhc_rh_start_port_reset +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xa1c766b5 wusbhc_rh_control +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xb725d128 wusb_cluster_id_put +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xf770a6b4 wusbd +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xfe2e17d7 wusb_et_name +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xff7b294c wusbhc_chid_set +EXPORT_SYMBOL_GPL drivers/uwb/i1480/dfu/i1480-dfu-usb 0x132a9b94 i1480_fw_upload +EXPORT_SYMBOL_GPL drivers/uwb/i1480/dfu/i1480-dfu-usb 0x419cbede i1480_rceb_check +EXPORT_SYMBOL_GPL drivers/uwb/i1480/dfu/i1480-dfu-usb 0xcca0de85 i1480_cmd +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x344d22ac uwb_rts_cts_show +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x34dc4993 uwb_pca_base_priority_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x5c794c64 uwb_ack_policy_show +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x75f2678c uwb_ack_policy_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x789aec33 uwb_rts_cts_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x88f453af uwb_phy_rate_show +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x965032cc uwb_phy_rate_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0xd0ec3c3f uwb_pca_base_priority_show +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x1ee5bb71 umc_device_unregister +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x2ed7a2ec umc_driver_unregister +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x53b07df9 umc_device_register +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x5dca06a3 umc_bus_type +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x7c936bc2 __umc_driver_register +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x8d06fb19 umc_controller_reset +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x9fe595a8 umc_match_pci_id +EXPORT_SYMBOL_GPL drivers/uwb/umc 0xe85a63c6 umc_device_create +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x0b8aad57 uwb_est_unregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x1563ecf1 uwb_rc_add +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x182e11b4 uwb_rc_dev_addr_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x18ce48c0 uwb_rc_get_by_dev +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x19a26b41 uwb_rc_mac_addr_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x1a243c4c uwb_rc_get_ie +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x1af4cf76 uwb_rc_neh_grok +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x28ccd00d uwb_rc_ie_add +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x2b44d2d0 uwb_rc_rm +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x2e5d17f9 uwb_rc_neh_error +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x30539dcf uwb_notifs_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x3de5f6cf uwb_rc_cmd_async +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x40fa3779 uwb_rc_alloc +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x444b4580 uwb_rc_reset_all +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x484ed37a uwb_pal_init +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4ab0809a uwb_rc_init +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4aef23a2 uwb_rsv_establish +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4d57ae3c uwb_rsv_type_str +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x5e4bc088 __uwb_addr_print +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x5e8dd11d uwb_pal_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x68e5f1ec uwb_bg_joined +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x757a56a8 uwb_rc_ie_rm +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7613c0e2 uwb_rsv_state_str +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7dcfcd23 uwb_ie_next +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7e9eca5f __uwb_rc_try_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x853f2936 uwb_rc_vcmd +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x88a2774f uwb_dev_try_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x88e4909f uwb_rsv_accept +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa189aaf8 dump_bytes +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa408eab8 uwb_rc_cmd +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa529f6c3 uwb_ie_dump_hex +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xb52e58ec uwb_rc_put +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xb783e96c uwb_rsv_terminate +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xbff20dce uwb_dev_for_each +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xc36192c4 uwb_ie_for_each +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe1716f06 uwb_est_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe17e49b4 uwb_rsv_modify +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe1b3c43d uwb_notifs_deregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe4b8c29c uwb_rc_get_by_grandpa +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe625e3a5 uwb_est_find_size +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xebb145d1 uwb_pal_unregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xfa251ecf uwb_rsv_create +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xffe82870 uwb_rsv_destroy +EXPORT_SYMBOL_GPL drivers/uwb/whci 0x26dd0259 whci_wait_for +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x04403357 wlp_reset_all +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x1930e93a wlp_dev_serial_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x1b7e9107 wlp_uuid_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x1e924fac wlp_dev_prim_category_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x2305439b wlp_wss_activate_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x2e34611f wlp_setup +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x39815255 wlp_dev_prim_subcat_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x3ea1ed35 wlp_dev_manufacturer_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x3f9c30ef wlp_dev_serial_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x43f0d20c wlp_dev_prim_OUI_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x5b8dc790 wlp_dev_name_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x60a6e060 wlp_dev_prim_OUI_sub_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x686378e2 wlp_receive_frame +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x6aa0a4ea wlp_dev_model_name_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x6b229b76 wlp_wss_setup +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x785c6d55 wlp_dev_prim_subcat_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x7b2e41a1 wlp_prepare_tx_frame +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x7e595283 wlp_dev_prim_OUI_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x7f32dfca wlp_dev_model_name_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x8dc94de3 wlp_dev_manufacturer_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xa2b999bc wlp_eda_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xa7d5c54c wlp_dev_name_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xacff3530 wlp_dev_prim_OUI_sub_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xb01a1c84 wlp_dev_model_nr_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xb2aebabb wlp_wss_remove +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xb3993d9e wlp_neighborhood_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xbe827498 wlp_eda_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xc11db327 wlp_dev_model_nr_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xc594de38 wlp_remove +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xe065c579 wlp_dev_prim_category_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xe0e376c3 wlp_wss_activate_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xe4653644 wlp_uuid_store +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x10b1c9cf ili9320_resume +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x20af9bc6 ili9320_shutdown +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x2dbbb4f3 ili9320_write_regs +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x6bc7a199 ili9320_suspend +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0xa98e0b53 ili9320_write +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0xd0c09712 ili9320_remove +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0xdd460386 ili9320_probe_spi +EXPORT_SYMBOL_GPL drivers/video/fb_ddc 0x8186dd1d fb_ddc_read +EXPORT_SYMBOL_GPL drivers/video/fb_sys_fops 0x6bcb683d fb_sys_read +EXPORT_SYMBOL_GPL drivers/video/fb_sys_fops 0x7da31dd9 fb_sys_write +EXPORT_SYMBOL_GPL drivers/video/sis/sisfb 0x7ae038ea sis_free_new +EXPORT_SYMBOL_GPL drivers/video/sis/sisfb 0xb6c86295 sis_malloc_new +EXPORT_SYMBOL_GPL drivers/video/vermilion/vmlfb 0x016e6c20 vmlfb_unregister_subsys +EXPORT_SYMBOL_GPL drivers/video/vermilion/vmlfb 0x90c018c6 vmlfb_register_subsys +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x1685ea99 unregister_virtio_driver +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x3bb6f505 unregister_virtio_device +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x4af3a22d virtio_check_driver_offered_feature +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x5c30d55a register_virtio_driver +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0xa104c3a3 register_virtio_device +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x03c4687d vring_interrupt +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x2fb6c405 vring_new_virtqueue +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x974ad0b5 vring_transport_features +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x9febb2c1 vring_del_virtqueue +EXPORT_SYMBOL_GPL drivers/w1/wire 0x4530aa8d w1_reset_bus +EXPORT_SYMBOL_GPL drivers/w1/wire 0x5bfb4dbc w1_next_pullup +EXPORT_SYMBOL_GPL drivers/w1/wire 0x5c1323fa w1_read_8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0x7c2f2afb w1_calc_crc8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0x891c90f3 w1_write_block +EXPORT_SYMBOL_GPL drivers/w1/wire 0xa36ac307 w1_write_8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0xb68c805f w1_read_block +EXPORT_SYMBOL_GPL drivers/w1/wire 0xbf3c2589 w1_reset_select_slave +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x439ff041 dlm_posix_unlock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x9321df95 dlm_lock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xb3c67bd2 dlm_posix_lock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xcf9f3328 dlm_release_lockspace +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xda9151cd dlm_posix_get +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xdc583c08 dlm_unlock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xdf3c14de dlm_new_lockspace +EXPORT_SYMBOL_GPL fs/exportfs/exportfs 0x19b6161a exportfs_encode_fh +EXPORT_SYMBOL_GPL fs/exportfs/exportfs 0xbfe29d04 exportfs_decode_fh +EXPORT_SYMBOL_GPL fs/fat/fat 0x02422303 fat_detach +EXPORT_SYMBOL_GPL fs/fat/fat 0x05abd7e0 fat_attach +EXPORT_SYMBOL_GPL fs/fat/fat 0x1409ad57 fat_setattr +EXPORT_SYMBOL_GPL fs/fat/fat 0x18643142 fat_fs_panic +EXPORT_SYMBOL_GPL fs/fat/fat 0x356d29b4 fat_build_inode +EXPORT_SYMBOL_GPL fs/fat/fat 0x3e7ce801 fat_getattr +EXPORT_SYMBOL_GPL fs/fat/fat 0x520d4ae4 fat_remove_entries +EXPORT_SYMBOL_GPL fs/fat/fat 0x5cc4caaa fat_time_unix2fat +EXPORT_SYMBOL_GPL fs/fat/fat 0x6be9de55 fat_fill_super +EXPORT_SYMBOL_GPL fs/fat/fat 0x758d3eca fat_add_entries +EXPORT_SYMBOL_GPL fs/fat/fat 0x767d19c5 fat_get_dotdot_entry +EXPORT_SYMBOL_GPL fs/fat/fat 0x8c6e7dfa fat_scan +EXPORT_SYMBOL_GPL fs/fat/fat 0xab42f041 fat_search_long +EXPORT_SYMBOL_GPL fs/fat/fat 0xb403d52f fat_free_clusters +EXPORT_SYMBOL_GPL fs/fat/fat 0xc1da79a0 fat_dir_empty +EXPORT_SYMBOL_GPL fs/fat/fat 0xd32b4531 fat_alloc_new_dir +EXPORT_SYMBOL_GPL fs/fat/fat 0xefd551e3 fat_sync_inode +EXPORT_SYMBOL_GPL fs/fat/fat 0xf64b0be8 fat_flush_inodes +EXPORT_SYMBOL_GPL fs/gfs2/gfs2 0x225cbd41 gfs2_unregister_lockproto +EXPORT_SYMBOL_GPL fs/gfs2/gfs2 0xb617017b gfs2_register_lockproto +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x17ce645d locks_end_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x1a618932 nlmsvc_unlock_all_by_ip +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x5bed62ff nlmsvc_unlock_all_by_sb +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x60534715 nlmclnt_proc +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x6f959b35 locks_in_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x96877ac4 locks_start_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0xa003a1be nlmclnt_init +EXPORT_SYMBOL_GPL fs/lockd/lockd 0xd2dfaaaf nlmclnt_done +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x1b89c6ee o2hb_fill_node_map +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x1cb231d0 mlog_not_bits +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x1d747ce3 o2hb_check_node_heartbeating +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x36418553 o2net_send_message +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x3b0188d1 o2nm_get_node_by_num +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x4900035b o2hb_stop_all_regions +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x687f6251 mlog_and_bits +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x80d41ccf o2nm_get_node_by_ip +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x9f4c0e22 o2hb_setup_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xa82a8645 o2nm_this_node +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xa87bc9e7 o2nm_configured_node_map +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xa9f5379a o2net_send_message_vec +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xae808bac o2net_register_handler +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xbaeb4700 o2hb_check_node_heartbeating_from_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xc6af9bfd o2hb_register_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xd60f2c6c o2hb_check_local_node_heartbeating +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xe3325719 o2hb_unregister_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xf1a5611d o2net_unregister_handler_list +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xf7164040 o2nm_node_put +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xff4e2f7e o2nm_node_get +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x40e044d1 dlm_unregister_domain +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x7a1211f8 dlm_setup_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x963ae1a4 dlm_register_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x9bf30183 dlmunlock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xa76c513b dlm_register_domain +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xb61db5bc dlmlock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xcbc0b1f5 dlm_print_one_lock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xd7ba575e dlm_errmsg +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xd8fa57a6 dlm_unregister_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xfb86b96f dlm_errname +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x0562c415 ocfs2_cluster_this_node +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x0e27f909 ocfs2_dlm_lock +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x1ea73a10 ocfs2_stack_glue_unregister +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x21db5b88 ocfs2_cluster_disconnect +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x4a1f6fe9 ocfs2_cluster_connect +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x4d3af7fa ocfs2_cluster_hangup +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x81c85a68 ocfs2_dlm_lock_status +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x91fab465 ocfs2_dlm_lvb +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x963932a3 ocfs2_stack_glue_set_locking_protocol +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xa7d5c1c0 ocfs2_dlm_unlock +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xbbc4ef97 ocfs2_stack_supports_plocks +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xbf7d2c20 ocfs2_plock +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xd066711e ocfs2_dlm_dump_lksb +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xd40c63b1 ocfs2_stack_glue_register +EXPORT_SYMBOL_GPL lib/lzo/lzo_compress 0x56b63670 lzo1x_1_compress +EXPORT_SYMBOL_GPL lib/lzo/lzo_decompress 0xf30fda27 lzo1x_decompress_safe +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0x300d7e57 free_rs +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0x6fbb3bd9 init_rs_non_canonical +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0xabda1e2e decode_rs16 +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0xb050f329 init_rs +EXPORT_SYMBOL_GPL net/802/garp 0x1685bad3 garp_uninit_applicant +EXPORT_SYMBOL_GPL net/802/garp 0x305f7a9d garp_register_application +EXPORT_SYMBOL_GPL net/802/garp 0x5fceae09 garp_init_applicant +EXPORT_SYMBOL_GPL net/802/garp 0x8217e5ab garp_unregister_application +EXPORT_SYMBOL_GPL net/802/garp 0x90f84c0a garp_request_leave +EXPORT_SYMBOL_GPL net/802/garp 0xdf0adc9b garp_request_join +EXPORT_SYMBOL_GPL net/802/stp 0xab5bc153 stp_proto_unregister +EXPORT_SYMBOL_GPL net/802/stp 0xf610f689 stp_proto_register +EXPORT_SYMBOL_GPL net/ax25/ax25 0xac93ae05 ax25_bcast +EXPORT_SYMBOL_GPL net/ax25/ax25 0xaeb7451e ax25_defaddr +EXPORT_SYMBOL_GPL net/ax25/ax25 0xc0c59dd2 ax25_register_pid +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x09c5ed3c tfrc_tx_hist_purge +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x0a487ea5 tfrc_calc_x +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x0face1a7 tfrc_rx_hist_duplicate +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x106fe6d3 tfrc_tx_hist_rtt +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x69ec5731 tfrc_tx_hist_add +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x6c252d29 tfrc_calc_x_reverse_lookup +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x8a913529 tfrc_rx_hist_sample_rtt +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x8b626083 tfrc_lh_interval_add +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x902206f0 tfrc_lh_cleanup +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x92285650 tfrc_rx_hist_alloc +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xabebdde2 tfrc_rx_handle_loss +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xbc08e4ea tfrc_lh_update_i_mean +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xc612a5b6 tfrc_rx_hist_purge +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xf80801cd tfrc_rx_hist_add_packet +EXPORT_SYMBOL_GPL net/dccp/dccp 0x11ac7088 dccp_connect +EXPORT_SYMBOL_GPL net/dccp/dccp 0x169081e1 dccp_reqsk_send_ack +EXPORT_SYMBOL_GPL net/dccp/dccp 0x1896f692 dccp_setsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x1d99d49a dccp_timestamp +EXPORT_SYMBOL_GPL net/dccp/dccp 0x27d6c65f dccp_child_process +EXPORT_SYMBOL_GPL net/dccp/dccp 0x27df629d dccp_sendmsg +EXPORT_SYMBOL_GPL net/dccp/dccp 0x2ed17ee8 dccp_feat_change_recv +EXPORT_SYMBOL_GPL net/dccp/dccp 0x34c7fc22 dccp_poll +EXPORT_SYMBOL_GPL net/dccp/dccp 0x3b3c0b1b dccp_feat_clean +EXPORT_SYMBOL_GPL net/dccp/dccp 0x3bfc678a ccid_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0x4654880b dccp_insert_option_elapsed_time +EXPORT_SYMBOL_GPL net/dccp/dccp 0x4836ebb4 dccp_make_response +EXPORT_SYMBOL_GPL net/dccp/dccp 0x4b3d9e93 dccp_insert_option +EXPORT_SYMBOL_GPL net/dccp/dccp 0x4fed51a1 dccp_check_req +EXPORT_SYMBOL_GPL net/dccp/dccp 0x56ea266a dccp_state_name +EXPORT_SYMBOL_GPL net/dccp/dccp 0x5cc80952 dccp_death_row +EXPORT_SYMBOL_GPL net/dccp/dccp 0x66608d35 ccid_hc_tx_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0x6a026c77 dccp_sync_mss +EXPORT_SYMBOL_GPL net/dccp/dccp 0x6b27fe00 dccp_set_state +EXPORT_SYMBOL_GPL net/dccp/dccp 0x6fd67a4f dccp_done +EXPORT_SYMBOL_GPL net/dccp/dccp 0x71053ffd dccp_ctl_make_reset +EXPORT_SYMBOL_GPL net/dccp/dccp 0x74886b32 dccp_recvmsg +EXPORT_SYMBOL_GPL net/dccp/dccp 0x74ef080f dccp_destroy_sock +EXPORT_SYMBOL_GPL net/dccp/dccp 0x7541bf1a ccid_hc_tx_delete +EXPORT_SYMBOL_GPL net/dccp/dccp 0x7a1b9b6c dccp_parse_options +EXPORT_SYMBOL_GPL net/dccp/dccp 0x7adc14d9 inet_dccp_listen +EXPORT_SYMBOL_GPL net/dccp/dccp 0x86be7924 dccp_packet_name +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8b7d8caf dccp_statistics +EXPORT_SYMBOL_GPL net/dccp/dccp 0x9880b837 ccid_hc_rx_delete +EXPORT_SYMBOL_GPL net/dccp/dccp 0x9a082d74 dccp_feat_confirm_recv +EXPORT_SYMBOL_GPL net/dccp/dccp 0x9af7ce6f dccp_close +EXPORT_SYMBOL_GPL net/dccp/dccp 0x9b593d7e dccp_ioctl +EXPORT_SYMBOL_GPL net/dccp/dccp 0x9d6a3846 dccp_orphan_count +EXPORT_SYMBOL_GPL net/dccp/dccp 0xacf9f70f dccp_send_ack +EXPORT_SYMBOL_GPL net/dccp/dccp 0xb87db19a ccid_unregister +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbe4cf010 dccp_feat_init +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbf6b58ba dccp_feat_change +EXPORT_SYMBOL_GPL net/dccp/dccp 0xc68788f1 dccp_send_sync +EXPORT_SYMBOL_GPL net/dccp/dccp 0xc7247c45 dccp_init_sock +EXPORT_SYMBOL_GPL net/dccp/dccp 0xcb64ce7a dccp_getsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0xd42e1967 dccp_reqsk_init +EXPORT_SYMBOL_GPL net/dccp/dccp 0xd68b13af dccp_sample_rtt +EXPORT_SYMBOL_GPL net/dccp/dccp 0xd8a2f11a dccp_rcv_state_process +EXPORT_SYMBOL_GPL net/dccp/dccp 0xdc263946 dccp_hashinfo +EXPORT_SYMBOL_GPL net/dccp/dccp 0xdc2738a0 dccp_rcv_established +EXPORT_SYMBOL_GPL net/dccp/dccp 0xdebf3527 dccp_create_openreq_child +EXPORT_SYMBOL_GPL net/dccp/dccp 0xdf051c76 dccp_shutdown +EXPORT_SYMBOL_GPL net/dccp/dccp 0xeba36806 ccid_register +EXPORT_SYMBOL_GPL net/dccp/dccp 0xf35263dd ccid_hc_rx_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0xf41bded2 dccp_feat_clone +EXPORT_SYMBOL_GPL net/dccp/dccp 0xfafd9240 dccp_disconnect +EXPORT_SYMBOL_GPL net/dccp/dccp 0xffde6cf0 dccp_insert_option_timestamp +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x13a20e7e dccp_invalid_packet +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x13be4dd8 dccp_v4_request_recv_sock +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x2ae0a527 dccp_v4_connect +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x4a1c5567 dccp_v4_send_check +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x4f845030 dccp_v4_conn_request +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0xf9b74c6f dccp_v4_do_rcv +EXPORT_SYMBOL_GPL net/ieee80211/ieee80211 0x05963960 ieee80211_rx_any +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_conntrack_ipv4 0x27f2608c nf_nat_seq_adjust_hook +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_conntrack_ipv4 0x6d40a921 need_ipv4_conntrack +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_defrag_ipv4 0x6b6c3d10 nf_defrag_ipv4_enable +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x07ae60b6 nf_nat_proto_in_range +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x1b63142d nf_nat_icmp_reply_translation +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x468cfa3f nf_nat_packet +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x59c3072f nf_nat_proto_unique_tuple +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x5b4050ee nf_nat_proto_range_to_nlattr +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x94a08134 nf_nat_proto_nlattr_to_range +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0xbd15c1b1 nf_nat_proto_find_get +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0xff1a341b nf_nat_proto_put +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat_proto_gre 0x636b12c8 nf_nat_need_gre +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x01c8a3cf tcp_vegas_cwnd_event +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x23adef06 tcp_vegas_get_info +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x45ac1cab tcp_vegas_state +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x5e0bcb41 tcp_vegas_pkts_acked +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x699f17cd tcp_vegas_init +EXPORT_SYMBOL_GPL net/mac80211/mac80211 0x2df8b4d5 ieee80211_iterate_active_interfaces +EXPORT_SYMBOL_GPL net/mac80211/mac80211 0x891848f6 ieee80211_iterate_active_interfaces_atomic +EXPORT_SYMBOL_GPL net/netfilter/ipvs/ip_vs 0xe6476b4a net_vs_ctl_path +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x041013fd nf_conntrack_lock +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x045072cd nf_ct_port_nla_policy +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x0b1a2814 nf_conntrack_l4proto_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x0c156049 __nf_ct_expect_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x118ad365 nf_conntrack_helper_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x1283d711 nf_ct_expect_unregister_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x15c10b0b nf_conntrack_unregister_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x25a27e18 print_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x261031c8 nf_ct_expect_init +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x26e7d38f nf_ct_get_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x28d24c59 nf_ct_expect_alloc +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x38630158 nf_conntrack_tuple_taken +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x38c9440b nf_ct_extend_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3cac60f2 nf_conntrack_helper_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3f078b70 nf_ct_invert_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3f5b1415 nf_ct_port_nlattr_to_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x40387ccf __nf_ct_event_cache_init +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x4ba41c33 nf_ct_l3proto_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x50e17c1f nf_conntrack_l3proto_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x55f2e591 nf_ct_iterate_cleanup +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x5b6b92f9 __nf_ct_kill_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x60283701 nf_ct_l4proto_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x60d19fcb nf_conntrack_l3proto_generic +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x6b3f662b nf_ct_l3proto_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x6cd31b00 nf_conntrack_l3proto_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x6e224a7a need_conntrack +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x72836f4a nf_conntrack_free +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x72f6d643 __nf_ct_l4proto_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x77aadb54 nf_conntrack_alter_reply +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x78468ac8 nf_ct_expect_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x78f9b710 nf_ct_l3proto_try_module_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x79b2528c nf_ct_unlink_expect +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x79ca2e53 nf_ct_expect_chain +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x7f19600b nf_conntrack_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x817c5544 seq_print_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x82d9b7b6 nf_ct_unexpect_related +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x84426de5 __nf_conntrack_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x8ffe7e89 nf_conntrack_htable_size +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x90f0f80a nf_ct_l4proto_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x90ff6c9f nf_ct_invert_tuplepr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x95f232cd nf_conntrack_tcp_update +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x97d9ebe7 nf_ct_expect_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x9eb6a6ef nf_conntrack_in +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa4b701b7 nf_ct_port_tuple_to_nlattr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa6f62ec0 nf_conntrack_set_hashsize +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xaf57e66f nf_ct_extend_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb602c57e nf_ct_l3proto_module_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbc887e16 nf_ct_expect_register_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbdf477d5 nf_ct_expect_related +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc044befe nf_ct_free_hashtable +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc18ab981 __nf_conntrack_confirm +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc18ac88d nf_ct_expect_hsize +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc35a7a3e nf_conntrack_chain +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc44bdc14 nf_conntrack_l4proto_tcp6 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc454b53c __nf_conntrack_helper_find_byname +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc5336fb3 nf_ct_get_tuplepr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc7b64d79 nf_conntrack_hash_insert +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xcbf7fd2a nf_conntrack_register_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd0f3718c nf_conntrack_l4proto_udp6 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd50a96a2 nf_ct_alloc_hashtable +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd9efb053 nf_ct_deliver_cached_events +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xe0b2c592 nf_conntrack_alloc +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xe2c5130e nf_conntrack_l4proto_udp4 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xebaf6b67 nf_conntrack_l4proto_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf1115378 __nf_ct_refresh_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf15c9dc7 __nf_ct_helper_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf67dbe96 nf_conntrack_l4proto_tcp4 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf88cd61f nf_conntrack_flush +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf9ae81a1 nf_conntrack_max +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfa06c25c nf_ct_l3protos +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfa169dac nf_conntrack_untracked +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfb33708d nf_ct_helper_ext_add +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfb839673 nf_ct_remove_expectations +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xff9e9fc3 nfnetlink_parse_nat_setup_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_amanda 0xfc709c1c nf_nat_amanda_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_ftp 0x383cda9c nf_nat_ftp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x264c0cf3 get_h225_addr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x4377c77c set_h245_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x5f9d13d1 set_h225_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x878377c1 set_ras_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x97ceff87 nat_callforwarding_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xa43727cd nat_q931_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xdc6ed5a1 nat_h245_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xe079f8e3 nat_t120_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xe40dd92c nat_rtp_rtcp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xed599fe8 set_sig_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_irc 0x1b7799b3 nf_nat_irc_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x617761c7 nf_nat_pptp_hook_outbound +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x66712039 nf_nat_pptp_hook_inbound +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x7172c883 nf_nat_pptp_hook_expectfn +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x7ad53633 nf_nat_pptp_hook_exp_gre +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_proto_gre 0x05f8e58c nf_ct_gre_keymap_destroy +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_proto_gre 0x6f59d77c nf_ct_gre_keymap_add +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x13169b79 ct_sip_parse_request +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x21bfee89 nf_nat_sdp_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x3c2058a6 ct_sip_parse_numerical_param +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x4409eb3a nf_nat_sdp_port_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x5333cb69 ct_sip_parse_header_uri +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x5343611e ct_sip_get_sdp_header +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x56ad8f6e ct_sip_parse_address_param +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x73005c75 nf_nat_sdp_session_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x965b3f54 nf_nat_sdp_media_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xa70e71a1 nf_nat_sip_expect_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xb34edc05 nf_nat_sip_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xf8b610ea ct_sip_get_header +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_tftp 0x19cb8435 nf_nat_tftp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_tproxy_core 0x1a59f3ad nf_tproxy_assign_sock +EXPORT_SYMBOL_GPL net/netfilter/nf_tproxy_core 0x71f5eb8a nf_tproxy_get_sock_v4 +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x1f58e71b nfnl_lock +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x3895cd7a nfnl_unlock +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x4549234d nfnetlink_unicast +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x56eeb3be nfnetlink_subsys_register +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x84dcf5fd nfnetlink_subsys_unregister +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xe6f22632 nfnetlink_send +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xeca95329 nfnetlink_has_listeners +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x01203124 xt_find_table_lock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x0e330069 xt_register_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x40728a63 xt_find_revision +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x8e62da86 xt_check_match +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x9ecdd6ba xt_unregister_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xa2c38cd6 xt_check_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xcb25ecbd xt_table_unlock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xe06fd3e4 xt_proto_init +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xe5b249e1 xt_proto_fini +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xf3686bb1 xt_request_find_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xff2c5bd2 xt_replace_table +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0xc177bee0 xt_rateest_put +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0xdb8418cc xt_rateest_lookup +EXPORT_SYMBOL_GPL net/rxrpc/af-rxrpc 0x8916b6fc rxrpc_register_security +EXPORT_SYMBOL_GPL net/rxrpc/af-rxrpc 0x927b72ec rxrpc_unregister_security +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x0a0b0751 xdr_partial_copy_from_skb +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x0db2163f svc_find_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x15a6d1b9 rpc_call_sync +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x18174364 rpc_wake_up_next +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1b34dd35 svc_xprt_names +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1da582fb rpcauth_destroy_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x291e5552 rpc_force_rebind +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2aa17774 rpc_free_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x31a89d59 rpc_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x32ff5904 xprt_release_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x368d293d rpc_call_null +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x39a01d81 svc_xprt_copy_addrs +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3fbd1a07 svc_xprt_put +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x4336ff34 xprt_release_rqst_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x48249e3e xprt_set_retrans_timeout_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x486a9cac rpc_call_async +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x48ebc8b5 xprt_adjust_cwnd +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x48faff52 xprt_update_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x4ae0d8d7 rpcb_getport_async +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x4d573924 __rpc_wait_for_completion_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x53445f68 nlm_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x53e8b591 rpc_setbufsize +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x550547a3 rpc_destroy_wait_queue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5bd26000 rpc_proc_unregister +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5c3c0c5e svc_print_addr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5d58e14b rpc_exit_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5e918b18 xprt_complete_rqst +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x607b60e4 xprt_reserve_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6c5304c5 rpcb_getport_sync +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6c985720 rpc_peeraddr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6dc0d74c xprt_set_retrans_timeout_def +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6f99be7f rpc_killall_tasks +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x70838a64 xprt_lookup_rqst +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x71152909 rpc_put_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x719270c0 svc_xprt_enqueue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x74407193 svc_close_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7de53067 rpc_init_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x87093fcc rpc_bind_new_program +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8811c2d1 rpc_lookup_machine_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x9176f7a9 rpc_print_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x994ab2e9 rpc_create +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xa2678e25 rpc_max_payload +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xa348221c xprt_register_transport +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xa576a67e xprt_wake_pending_tasks +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xa637c405 rpc_peeraddr2str +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xab5ccff9 rpc_sleep_on +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xaf5bf6ef nfs_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb023cdfa rpcauth_generic_bind_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb0c6f405 xprt_disconnect_done +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb387b246 rpc_wake_up_status +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbaebd5b1 xprt_reserve_xprt_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbafa49be rpc_delay +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbbc5bdb8 svc_unreg_xprt_class +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbf9d1b96 nfsd_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbfe4c29a rpcauth_init_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc12435e3 rpc_calc_rto +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc1498551 svc_xprt_received +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc2adc555 rpcauth_register +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc2de1d7f rpcauth_unregister +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc5076daf svc_create_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc8f0f3e8 xprt_write_space +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xcb00b28e rpc_call_start +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xce34939a rpcauth_init_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xcf3e1b18 rpc_shutdown_client +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xcfe44ae1 rpc_restart_call +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd13b6ecb svc_addsock +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd6d5bc35 rpcauth_create +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd82c728e rpc_init_wait_queue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd82f071f svc_reg_xprt_class +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xdabddbbc rpc_malloc +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xde2471ea csum_partial_copy_to_xdr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xdee09588 rpc_proc_register +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xdfbf146b svc_xprt_init +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe12ddf4a rpc_lookup_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe1cdd907 xdr_skb_read_bits +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe328abbc rpc_run_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe3dfee50 xprt_release_xprt_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe74ca2cb xprt_wait_for_buffer_space +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe7b77527 rpc_wake_up_queued_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xeb2318e5 rpc_alloc_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xecacc514 rpcauth_lookup_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xedd1ba52 rpc_wake_up +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xeeacab69 rpc_update_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xef24116a xprt_unregister_transport +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xef953be0 rpc_clone_client +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xf2b3d830 put_rpccred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xf9d1164c rpc_free +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xfee74105 svc_max_payload +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0x573a466e ipcomp_init_state +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0x7b93dc1e ipcomp_output +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0xafb3b8a2 ipcomp_destroy +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0xcb69e2f6 ipcomp_input +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ad73311 0x1a9d44de ad73311_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ad73311 0x9ef28089 soc_codec_dev_ad73311 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ak4535 0x043e282e soc_codec_dev_ak4535 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ak4535 0x1db8f890 ak4535_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-cs4270 0x9de6b28b soc_codec_device_cs4270 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-cs4270 0xdfea3cf4 cs4270_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ssm2602 0x8f51df78 soc_codec_dev_ssm2602 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ssm2602 0xac3d9349 ssm2602_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic23 0x24eb3b69 tlv320aic23_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic23 0xccd40268 soc_codec_dev_tlv320aic23 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic26 0x6018b156 aic26_soc_codec_dev +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic26 0xd14758e9 aic26_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0x42623841 aic3x_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0x83f122d9 aic3x_set_gpio +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0xbca3216c soc_codec_dev_aic3x +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0xc3881a60 aic3x_headset_detected +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0xf68bf9bb aic3x_get_gpio +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-uda1380 0x294b256c uda1380_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-uda1380 0xd0de0d1c soc_codec_dev_uda1380 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8510 0x6d6aafed soc_codec_dev_wm8510 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8510 0x7783f5d1 wm8510_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8580 0x62bb9462 soc_codec_dev_wm8580 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8580 0xb91b6cdb wm8580_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8731 0x69653020 wm8731_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8731 0xddfc8249 soc_codec_dev_wm8731 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8750 0xc06acfba soc_codec_dev_wm8750 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8750 0xc1e9d6bf wm8750_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8753 0xe1f308e4 wm8753_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8753 0xeb479c79 soc_codec_dev_wm8753 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8900 0x267e7a62 soc_codec_dev_wm8900 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8900 0x865beb2a wm8900_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8903 0x00cf9984 wm8903_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8903 0x0d5329a1 soc_codec_dev_wm8903 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8971 0x3a2a5da6 soc_codec_dev_wm8971 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8971 0x88a00601 wm8971_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8990 0x13c3aef9 wm8990_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8990 0x29af41ed soc_codec_dev_wm8990 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x056f0910 snd_soc_dapm_sync +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x06446005 snd_soc_dapm_disable_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x0d600574 snd_soc_dapm_get_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x0fefca8f snd_soc_dapm_stream_event +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x14a18a87 snd_soc_dapm_enable_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x1850ea2a snd_soc_dapm_nc_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x2cd57e05 snd_soc_put_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x30acd9dc snd_soc_dai_set_clkdiv +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x31d69eb1 snd_soc_update_bits +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x3303e8bc snd_soc_info_enum_ext +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x3475f6dc snd_soc_register_card +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x3c3a8008 snd_soc_info_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x40dc0340 snd_soc_dai_set_fmt +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x4908c098 snd_soc_dapm_new_widgets +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x4d5fc0ec snd_soc_get_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x53cec8ae snd_soc_dapm_connect_input +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x5c0bf34a snd_soc_get_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x5fd067c3 snd_soc_put_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x68c893bb snd_soc_free_ac97_codec +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x6ceabb9d snd_soc_dapm_put_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x6f64ea16 snd_soc_cnew +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x75c82b2d snd_soc_dapm_free +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x78fd2449 snd_soc_dapm_add_routes +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x7ca8287d snd_soc_dai_set_tristate +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x7f0aeeb3 snd_soc_new_ac97_codec +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x7fa604dc snd_soc_info_volsw_ext +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x83a2a260 snd_soc_dai_digital_mute +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x87b767ac snd_soc_set_runtime_hwparams +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x8d13f10c snd_soc_put_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x8ec86585 snd_soc_get_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x9213c2df snd_soc_get_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x9498553e snd_soc_dapm_new_control +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x953d9437 snd_soc_dapm_get_pin_status +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x9a01546d snd_soc_dapm_get_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x9fac403e snd_soc_dai_set_pll +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xa6ae1e53 snd_soc_info_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xa8706165 snd_soc_free_pcms +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xae1cf06c snd_soc_dai_set_sysclk +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xc75ec9a8 snd_soc_put_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xcf4c5f1a snd_soc_dapm_put_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xd72677d2 dapm_reg_event +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xe136cd45 snd_soc_info_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xe334303b snd_soc_new_pcms +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xf229b22e snd_soc_info_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xf3d77b3a snd_soc_dai_set_tdm_slot +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xf5ed565d snd_soc_dapm_new_controls +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xfe055028 snd_soc_test_bits +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x1584fdb9 tlsf_destroy_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x42a50f11 tlsf_malloc +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x66da3d8f tlsf_create_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xe6acc368 tlsf_free +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xee6c65c9 tlsf_get_used_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xeec8caeb tlsf_get_total_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xf9805f1b tlsf_calloc +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x02500586 thinkpad_ec_unlock +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x0dc7484e thinkpad_ec_try_read_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x2552d213 thinkpad_ec_lock +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x3dbfef12 thinkpad_ec_read_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x8dbbd831 thinkpad_ec_invalidate +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0xa3042743 thinkpad_ec_prefetch_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0xfb5aa917 thinkpad_ec_try_lock +EXPORT_SYMBOL_GPL vmlinux 0x00566d8f inotify_get_cookie +EXPORT_SYMBOL_GPL vmlinux 0x0067df75 ata_tf_from_fis +EXPORT_SYMBOL_GPL vmlinux 0x006d7cad srcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x0089e6fb rtc_update_irq +EXPORT_SYMBOL_GPL vmlinux 0x00a61516 sata_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x00ebcb5d ata_id_string +EXPORT_SYMBOL_GPL vmlinux 0x00f1d4eb bus_rescan_devices +EXPORT_SYMBOL_GPL vmlinux 0x0110b3d1 register_hotplug_dock_device +EXPORT_SYMBOL_GPL vmlinux 0x01848a8e local_apic_timer_c2_ok +EXPORT_SYMBOL_GPL vmlinux 0x018d137b usb_autopm_put_interface +EXPORT_SYMBOL_GPL vmlinux 0x0198ce08 ata_cable_sata +EXPORT_SYMBOL_GPL vmlinux 0x01a4ea6d unregister_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x01e1a8de kgdb_breakpoint +EXPORT_SYMBOL_GPL vmlinux 0x01f80c10 devm_kzalloc +EXPORT_SYMBOL_GPL vmlinux 0x021eb672 devres_get +EXPORT_SYMBOL_GPL vmlinux 0x0220fb8b device_create_vargs +EXPORT_SYMBOL_GPL vmlinux 0x02445c83 unregister_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0x02976d8b lookup_create +EXPORT_SYMBOL_GPL vmlinux 0x02a4fa61 driver_attach +EXPORT_SYMBOL_GPL vmlinux 0x02accf1f skb_segment +EXPORT_SYMBOL_GPL vmlinux 0x02b8831b regulator_set_mode +EXPORT_SYMBOL_GPL vmlinux 0x02ccea56 lock_policy_rwsem_write +EXPORT_SYMBOL_GPL vmlinux 0x02eb8a7e ata_sff_irq_clear +EXPORT_SYMBOL_GPL vmlinux 0x0300fad5 bus_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x03252e43 usb_get_current_frame_number +EXPORT_SYMBOL_GPL vmlinux 0x03365098 pci_create_slot +EXPORT_SYMBOL_GPL vmlinux 0x0343bdf1 __i2c_board_list +EXPORT_SYMBOL_GPL vmlinux 0x03e358fe led_trigger_set_default +EXPORT_SYMBOL_GPL vmlinux 0x03e3686c ata_timing_cycle2mode +EXPORT_SYMBOL_GPL vmlinux 0x04136bca klist_init +EXPORT_SYMBOL_GPL vmlinux 0x041d4d10 usb_driver_claim_interface +EXPORT_SYMBOL_GPL vmlinux 0x04486e88 rcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x04566c7f init_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x0493afc2 inet_csk_listen_start +EXPORT_SYMBOL_GPL vmlinux 0x04bcc029 ata_sff_tf_read +EXPORT_SYMBOL_GPL vmlinux 0x0531dcb8 ata_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0x054e550b kernel_halt +EXPORT_SYMBOL_GPL vmlinux 0x05c4f50d __trace_note_message +EXPORT_SYMBOL_GPL vmlinux 0x05cabb1d skb_cow_data +EXPORT_SYMBOL_GPL vmlinux 0x05d497c0 led_trigger_store +EXPORT_SYMBOL_GPL vmlinux 0x05fc29d5 ezusb_set_reset +EXPORT_SYMBOL_GPL vmlinux 0x060d1064 set_memory_ro +EXPORT_SYMBOL_GPL vmlinux 0x063d70ab put_device +EXPORT_SYMBOL_GPL vmlinux 0x064db59f __rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x064db9a5 mark_mounts_for_expiry +EXPORT_SYMBOL_GPL vmlinux 0x065dc840 dm_register_path_selector +EXPORT_SYMBOL_GPL vmlinux 0x0684e6a7 led_trigger_show +EXPORT_SYMBOL_GPL vmlinux 0x06d222f8 device_resume +EXPORT_SYMBOL_GPL vmlinux 0x074352b5 do_sync_mapping_range +EXPORT_SYMBOL_GPL vmlinux 0x07b52e38 rtnl_unregister +EXPORT_SYMBOL_GPL vmlinux 0x08048bfd usb_interrupt_msg +EXPORT_SYMBOL_GPL vmlinux 0x084a9905 sdio_release_irq +EXPORT_SYMBOL_GPL vmlinux 0x0875d991 regulator_get_current_limit +EXPORT_SYMBOL_GPL vmlinux 0x089b3e5b bus_register +EXPORT_SYMBOL_GPL vmlinux 0x08a3e5d1 net_ipv6_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0x09037d61 rtc_read_alarm +EXPORT_SYMBOL_GPL vmlinux 0x09187295 __inet_twsk_hashdance +EXPORT_SYMBOL_GPL vmlinux 0x091eb9b4 round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0x0953ac6a sysfs_schedule_callback +EXPORT_SYMBOL_GPL vmlinux 0x0959f22e hid_add_device +EXPORT_SYMBOL_GPL vmlinux 0x09bd30e5 hrtimer_init +EXPORT_SYMBOL_GPL vmlinux 0x0a2519b1 fsstack_copy_attr_all +EXPORT_SYMBOL_GPL vmlinux 0x0a8ab374 dm_rh_start_recovery +EXPORT_SYMBOL_GPL vmlinux 0x0a959dc3 ata_sff_post_internal_cmd +EXPORT_SYMBOL_GPL vmlinux 0x0ad5c33f acpi_smbus_register_callback +EXPORT_SYMBOL_GPL vmlinux 0x0afc88f8 usb_get_status +EXPORT_SYMBOL_GPL vmlinux 0x0b2f1fb6 sata_scr_write_flush +EXPORT_SYMBOL_GPL vmlinux 0x0b53a167 device_move +EXPORT_SYMBOL_GPL vmlinux 0x0b8191f5 ata_ehi_clear_desc +EXPORT_SYMBOL_GPL vmlinux 0x0b9d29cc devres_close_group +EXPORT_SYMBOL_GPL vmlinux 0x0be02477 ata_host_activate +EXPORT_SYMBOL_GPL vmlinux 0x0c1437b5 rtnl_kill_links +EXPORT_SYMBOL_GPL vmlinux 0x0c17e274 xfrm_aalg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x0c204cd5 inet_csk_clone +EXPORT_SYMBOL_GPL vmlinux 0x0c236dba sysdev_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x0c4717f7 srcu_init_notifier_head +EXPORT_SYMBOL_GPL vmlinux 0x0c611cb9 net_assign_generic +EXPORT_SYMBOL_GPL vmlinux 0x0c657018 sdio_readl +EXPORT_SYMBOL_GPL vmlinux 0x0cd592a9 inotify_destroy +EXPORT_SYMBOL_GPL vmlinux 0x0d1f3c07 blk_trace_setup +EXPORT_SYMBOL_GPL vmlinux 0x0d6e5c1a relay_file_operations +EXPORT_SYMBOL_GPL vmlinux 0x0d814646 klist_add_head +EXPORT_SYMBOL_GPL vmlinux 0x0daaf953 ata_bmdma_setup +EXPORT_SYMBOL_GPL vmlinux 0x0e37422d rt_mutex_lock_interruptible +EXPORT_SYMBOL_GPL vmlinux 0x0ec6e5a6 pci_restore_msi_state +EXPORT_SYMBOL_GPL vmlinux 0x0f0a38a6 dma_get_required_mask +EXPORT_SYMBOL_GPL vmlinux 0x0f617888 hvc_alloc +EXPORT_SYMBOL_GPL vmlinux 0x0f6703b2 __inet_inherit_port +EXPORT_SYMBOL_GPL vmlinux 0x0faa5222 crypto_grab_aead +EXPORT_SYMBOL_GPL vmlinux 0x100c13c6 usb_kill_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x100c48a2 unregister_dock_notifier +EXPORT_SYMBOL_GPL vmlinux 0x102ea928 destroy_workqueue +EXPORT_SYMBOL_GPL vmlinux 0x11020e22 usb_mon_register +EXPORT_SYMBOL_GPL vmlinux 0x113ca178 relay_open +EXPORT_SYMBOL_GPL vmlinux 0x113ce972 dm_rh_delay +EXPORT_SYMBOL_GPL vmlinux 0x11720b8a ip6_dst_blackhole +EXPORT_SYMBOL_GPL vmlinux 0x117d6c8b klist_add_after +EXPORT_SYMBOL_GPL vmlinux 0x11f32d93 ata_sff_busy_sleep +EXPORT_SYMBOL_GPL vmlinux 0x11f447ce __gpio_to_irq +EXPORT_SYMBOL_GPL vmlinux 0x12150c94 class_interface_unregister +EXPORT_SYMBOL_GPL vmlinux 0x124f2056 crypto_get_attr_type +EXPORT_SYMBOL_GPL vmlinux 0x1251d30f call_rcu +EXPORT_SYMBOL_GPL vmlinux 0x12ec3d6a usb_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0x12f436c8 regulator_set_current_limit +EXPORT_SYMBOL_GPL vmlinux 0x13354608 scatterwalk_map_and_copy +EXPORT_SYMBOL_GPL vmlinux 0x1354f88a __hid_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x13605cb1 spi_alloc_master +EXPORT_SYMBOL_GPL vmlinux 0x13b2a946 register_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x13e59997 crypto_spawn_tfm +EXPORT_SYMBOL_GPL vmlinux 0x13f2b874 devres_find +EXPORT_SYMBOL_GPL vmlinux 0x13fa25e3 sdio_writeb +EXPORT_SYMBOL_GPL vmlinux 0x14247ea8 uhci_check_and_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0x14260608 crypto_rng_type +EXPORT_SYMBOL_GPL vmlinux 0x143bcd6d debugfs_create_u16 +EXPORT_SYMBOL_GPL vmlinux 0x1457eab6 sysdev_register +EXPORT_SYMBOL_GPL vmlinux 0x145eebd0 device_power_up +EXPORT_SYMBOL_GPL vmlinux 0x1485f0b3 usb_register_device_driver +EXPORT_SYMBOL_GPL vmlinux 0x149156c8 scsi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x149db923 selinux_string_to_sid +EXPORT_SYMBOL_GPL vmlinux 0x14fea65b usb_create_hcd +EXPORT_SYMBOL_GPL vmlinux 0x1561de5c usb_remove_hcd +EXPORT_SYMBOL_GPL vmlinux 0x1577733a device_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x158c2ad0 acpi_smbus_unregister_callback +EXPORT_SYMBOL_GPL vmlinux 0x1598dc9d unregister_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x15b0606e e820_any_mapped +EXPORT_SYMBOL_GPL vmlinux 0x15cb37fa bus_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x16283fee vfs_setxattr +EXPORT_SYMBOL_GPL vmlinux 0x16836e04 speedstep_detect_processor +EXPORT_SYMBOL_GPL vmlinux 0x1695e237 pci_bus_add_device +EXPORT_SYMBOL_GPL vmlinux 0x16db7e64 ata_dev_pair +EXPORT_SYMBOL_GPL vmlinux 0x16f76869 probe_kernel_read +EXPORT_SYMBOL_GPL vmlinux 0x172e72d4 vdso_enabled +EXPORT_SYMBOL_GPL vmlinux 0x17322b52 rtc_irq_set_state +EXPORT_SYMBOL_GPL vmlinux 0x174e20f1 sysdev_driver_register +EXPORT_SYMBOL_GPL vmlinux 0x17a463e6 hidinput_connect +EXPORT_SYMBOL_GPL vmlinux 0x17c2a605 disk_part_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x18088d6e ata_scsi_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0x1821a982 tcp_reno_min_cwnd +EXPORT_SYMBOL_GPL vmlinux 0x1865869e sysfs_create_link +EXPORT_SYMBOL_GPL vmlinux 0x18674aa5 anon_transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x1878f62b edac_err_assert +EXPORT_SYMBOL_GPL vmlinux 0x18c29075 pci_scan_child_bus +EXPORT_SYMBOL_GPL vmlinux 0x18d53420 kgdb_register_io_module +EXPORT_SYMBOL_GPL vmlinux 0x191653dd crypto_mod_put +EXPORT_SYMBOL_GPL vmlinux 0x194e0499 tcp_done +EXPORT_SYMBOL_GPL vmlinux 0x198dd3f8 vlan_dev_vlan_id +EXPORT_SYMBOL_GPL vmlinux 0x199de746 sdio_f0_readb +EXPORT_SYMBOL_GPL vmlinux 0x19a0aed5 kill_pid_info_as_uid +EXPORT_SYMBOL_GPL vmlinux 0x19a304ba usb_disabled +EXPORT_SYMBOL_GPL vmlinux 0x19ab1a73 xfrm_output_resume +EXPORT_SYMBOL_GPL vmlinux 0x1a0ac44d crypto_init_spawn +EXPORT_SYMBOL_GPL vmlinux 0x1a2d59ad pci_find_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0x1a43c332 unregister_jprobe +EXPORT_SYMBOL_GPL vmlinux 0x1a938737 atomic_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x1acda5b2 atomic_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x1ad3b491 acpi_root_bridge +EXPORT_SYMBOL_GPL vmlinux 0x1aebfc67 page_cache_async_readahead +EXPORT_SYMBOL_GPL vmlinux 0x1b22c82d do_add_mount +EXPORT_SYMBOL_GPL vmlinux 0x1b59a8dd sata_scr_write +EXPORT_SYMBOL_GPL vmlinux 0x1b9aca3f jprobe_return +EXPORT_SYMBOL_GPL vmlinux 0x1c16e474 driver_find +EXPORT_SYMBOL_GPL vmlinux 0x1c3a336b tcp_death_row +EXPORT_SYMBOL_GPL vmlinux 0x1c6fae65 usb_hcd_pci_suspend +EXPORT_SYMBOL_GPL vmlinux 0x1c7a062f file_ra_state_init +EXPORT_SYMBOL_GPL vmlinux 0x1c8375d6 tcp_get_info +EXPORT_SYMBOL_GPL vmlinux 0x1c87a811 __round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x1cc7b8ab debugfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x1ce6a0ad usb_sg_wait +EXPORT_SYMBOL_GPL vmlinux 0x1d023170 schedule_hrtimeout +EXPORT_SYMBOL_GPL vmlinux 0x1d25d163 regulator_disable +EXPORT_SYMBOL_GPL vmlinux 0x1d5967f1 scsi_target_unblock +EXPORT_SYMBOL_GPL vmlinux 0x1d5d882e ata_eh_thaw_port +EXPORT_SYMBOL_GPL vmlinux 0x1d8daa2c ata_host_init +EXPORT_SYMBOL_GPL vmlinux 0x1dd0809f regulator_set_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x1dd70100 dmi_walk +EXPORT_SYMBOL_GPL vmlinux 0x1e5f9880 regulator_is_enabled +EXPORT_SYMBOL_GPL vmlinux 0x1e7bbcb3 kernel_restart +EXPORT_SYMBOL_GPL vmlinux 0x1eabb723 platform_device_del +EXPORT_SYMBOL_GPL vmlinux 0x1eb9516e round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x1ecc6d1c crypto_hash_type +EXPORT_SYMBOL_GPL vmlinux 0x1ee5bc25 scsi_dh_attach +EXPORT_SYMBOL_GPL vmlinux 0x1eeda530 platform_device_put +EXPORT_SYMBOL_GPL vmlinux 0x1f232cd1 kmap_atomic_pfn +EXPORT_SYMBOL_GPL vmlinux 0x1f435bdf pci_execute_reset_function +EXPORT_SYMBOL_GPL vmlinux 0x1f8ec1b3 acpi_get_pci_rootbridge_handle +EXPORT_SYMBOL_GPL vmlinux 0x1f9a0fbf hpet_unregister_irq_handler +EXPORT_SYMBOL_GPL vmlinux 0x1fb71217 hidinput_find_field +EXPORT_SYMBOL_GPL vmlinux 0x1fcece42 inet_twdr_twcal_tick +EXPORT_SYMBOL_GPL vmlinux 0x1ffa0d44 power_supply_register +EXPORT_SYMBOL_GPL vmlinux 0x1fff3d2b inotify_rm_watch +EXPORT_SYMBOL_GPL vmlinux 0x202b5000 rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0x20577ea2 xfrm_ealg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x208b0b30 audit_log_vformat +EXPORT_SYMBOL_GPL vmlinux 0x20aa1094 usb_find_interface +EXPORT_SYMBOL_GPL vmlinux 0x20b82470 hpet_register_irq_handler +EXPORT_SYMBOL_GPL vmlinux 0x20bc3470 orderly_poweroff +EXPORT_SYMBOL_GPL vmlinux 0x20cd788f __ftrace_printk +EXPORT_SYMBOL_GPL vmlinux 0x21102f6f pci_reset_function +EXPORT_SYMBOL_GPL vmlinux 0x212291b5 usb_hcd_giveback_urb +EXPORT_SYMBOL_GPL vmlinux 0x213c1513 klist_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x21467f9b tcp_unregister_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0x215c64b7 blk_end_request_callback +EXPORT_SYMBOL_GPL vmlinux 0x216fc1bc __inet_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0x219d7afa unregister_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0x2201cfa5 skb_morph +EXPORT_SYMBOL_GPL vmlinux 0x221c48ea sysfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x22472bf4 xfrm_calg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x2296c00d crypto_attr_u32 +EXPORT_SYMBOL_GPL vmlinux 0x22e2c591 inet_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0x231c3932 xfrm_audit_state_icvfail +EXPORT_SYMBOL_GPL vmlinux 0x23679939 __iowrite32_copy +EXPORT_SYMBOL_GPL vmlinux 0x237d7840 usb_get_hcd +EXPORT_SYMBOL_GPL vmlinux 0x23864ce7 cpuset_mem_spread_node +EXPORT_SYMBOL_GPL vmlinux 0x2387bdf9 usb_get_intf +EXPORT_SYMBOL_GPL vmlinux 0x23ad3ae9 vfs_lock_file +EXPORT_SYMBOL_GPL vmlinux 0x23e55145 usb_control_msg +EXPORT_SYMBOL_GPL vmlinux 0x2409cf40 platform_device_add_data +EXPORT_SYMBOL_GPL vmlinux 0x24196ba2 init_uts_ns +EXPORT_SYMBOL_GPL vmlinux 0x243dccb2 usb_get_from_anchor +EXPORT_SYMBOL_GPL vmlinux 0x2447533c ktime_get_real +EXPORT_SYMBOL_GPL vmlinux 0x24de6c0d driver_add_kobj +EXPORT_SYMBOL_GPL vmlinux 0x24eb7e32 leds_list +EXPORT_SYMBOL_GPL vmlinux 0x251e649f crypto_free_tfm +EXPORT_SYMBOL_GPL vmlinux 0x259c9eef rtc_set_alarm +EXPORT_SYMBOL_GPL vmlinux 0x26c90ea4 scsi_eh_get_sense +EXPORT_SYMBOL_GPL vmlinux 0x26e2e9e7 blk_abort_request +EXPORT_SYMBOL_GPL vmlinux 0x2731c259 i2c_unregister_device +EXPORT_SYMBOL_GPL vmlinux 0x273f1b67 __scsi_get_command +EXPORT_SYMBOL_GPL vmlinux 0x2759d499 sdio_set_block_size +EXPORT_SYMBOL_GPL vmlinux 0x279a15f6 regulator_get_voltage +EXPORT_SYMBOL_GPL vmlinux 0x27a56304 sata_pmp_qc_defer_cmd_switch +EXPORT_SYMBOL_GPL vmlinux 0x27f2dfd6 aead_geniv_exit +EXPORT_SYMBOL_GPL vmlinux 0x27f316fd regulator_get_mode +EXPORT_SYMBOL_GPL vmlinux 0x28088f0f pv_time_ops +EXPORT_SYMBOL_GPL vmlinux 0x281a277c crypto_larval_alloc +EXPORT_SYMBOL_GPL vmlinux 0x284053b6 inotify_remove_watch_locked +EXPORT_SYMBOL_GPL vmlinux 0x28460865 dnotify_parent +EXPORT_SYMBOL_GPL vmlinux 0x288d9eca disk_get_part +EXPORT_SYMBOL_GPL vmlinux 0x28961016 init_user_ns +EXPORT_SYMBOL_GPL vmlinux 0x28a9a858 crypto_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x28bd70a5 ata_do_eh +EXPORT_SYMBOL_GPL vmlinux 0x28bdacde hrtimer_start_range_ns +EXPORT_SYMBOL_GPL vmlinux 0x28d664ff __raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x28e23139 xfrm_probe_algs +EXPORT_SYMBOL_GPL vmlinux 0x296792f5 relay_buf_full +EXPORT_SYMBOL_GPL vmlinux 0x297835fa sock_prot_inuse_add +EXPORT_SYMBOL_GPL vmlinux 0x2a1f6555 kobject_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0x2a678a13 __suspend_report_result +EXPORT_SYMBOL_GPL vmlinux 0x2a9c4dd2 cpci_hp_unregister_controller +EXPORT_SYMBOL_GPL vmlinux 0x2aa10c29 hwmon_device_register +EXPORT_SYMBOL_GPL vmlinux 0x2b142d16 inet_csk_route_req +EXPORT_SYMBOL_GPL vmlinux 0x2b9f8e23 nf_net_ipv4_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x2ba75e8a usb_get_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x2bd662df nf_unregister_afinfo +EXPORT_SYMBOL_GPL vmlinux 0x2be3e94a ata_base_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x2c16ed76 xfrm_calg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x2c208607 power_supply_is_system_supplied +EXPORT_SYMBOL_GPL vmlinux 0x2cb1afd2 spi_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x2cd1a55e rdev_get_id +EXPORT_SYMBOL_GPL vmlinux 0x2cf56e8e fib_rules_unregister +EXPORT_SYMBOL_GPL vmlinux 0x2d45bcda crypto_alg_sem +EXPORT_SYMBOL_GPL vmlinux 0x2d59c954 edac_handlers +EXPORT_SYMBOL_GPL vmlinux 0x2d63775d sata_async_notification +EXPORT_SYMBOL_GPL vmlinux 0x2d6932f7 ata_link_online +EXPORT_SYMBOL_GPL vmlinux 0x2d7d843d tcp_twsk_unique +EXPORT_SYMBOL_GPL vmlinux 0x2d9f2ce3 sched_clock_idle_wakeup_event +EXPORT_SYMBOL_GPL vmlinux 0x2de4b6b4 inotify_inode_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x2e1a38d5 tracepoint_iter_reset +EXPORT_SYMBOL_GPL vmlinux 0x2e2ff51e drop_file_write_access +EXPORT_SYMBOL_GPL vmlinux 0x2e3aa486 dm_rh_region_context +EXPORT_SYMBOL_GPL vmlinux 0x2e9359a7 usb_hc_died +EXPORT_SYMBOL_GPL vmlinux 0x2e9f1ffe dev_attr_em_message_type +EXPORT_SYMBOL_GPL vmlinux 0x2eac1137 sysfs_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x2eb91dfe scatterwalk_map +EXPORT_SYMBOL_GPL vmlinux 0x2ee359d0 rtnl_put_cacheinfo +EXPORT_SYMBOL_GPL vmlinux 0x2f1935a0 transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x2f2c607d vfs_test_lock +EXPORT_SYMBOL_GPL vmlinux 0x2f47d8c7 cpufreq_frequency_get_table +EXPORT_SYMBOL_GPL vmlinux 0x2f4dfcee platform_driver_probe +EXPORT_SYMBOL_GPL vmlinux 0x2fa74e5f get_task_mm +EXPORT_SYMBOL_GPL vmlinux 0x2fc296f1 inet6_csk_xmit +EXPORT_SYMBOL_GPL vmlinux 0x2fda3515 sdio_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x2fdaf798 devres_open_group +EXPORT_SYMBOL_GPL vmlinux 0x2fea31a0 cpufreq_register_governor +EXPORT_SYMBOL_GPL vmlinux 0x300a2893 kernel_kobj +EXPORT_SYMBOL_GPL vmlinux 0x30133d9d usb_put_hcd +EXPORT_SYMBOL_GPL vmlinux 0x302f0f5b crypto_aead_setauthsize +EXPORT_SYMBOL_GPL vmlinux 0x3031149b ata_pio_need_iordy +EXPORT_SYMBOL_GPL vmlinux 0x303be15d page_mkclean +EXPORT_SYMBOL_GPL vmlinux 0x307494fc sysfs_remove_file_from_group +EXPORT_SYMBOL_GPL vmlinux 0x309424e0 debugfs_remove_recursive +EXPORT_SYMBOL_GPL vmlinux 0x318920b1 register_dock_notifier +EXPORT_SYMBOL_GPL vmlinux 0x31de65cb ata_eh_qc_retry +EXPORT_SYMBOL_GPL vmlinux 0x31e4b754 ata_sff_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0x31f6f9dd raw_seq_open +EXPORT_SYMBOL_GPL vmlinux 0x3200050d ata_timing_compute +EXPORT_SYMBOL_GPL vmlinux 0x3208a5b1 inet6_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0x3212ebda bd_release_from_disk +EXPORT_SYMBOL_GPL vmlinux 0x321936c2 da903x_update +EXPORT_SYMBOL_GPL vmlinux 0x32254264 init_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0x336eef4a get_driver +EXPORT_SYMBOL_GPL vmlinux 0x337c7d17 ata_port_abort +EXPORT_SYMBOL_GPL vmlinux 0x337d08f2 usb_serial_probe +EXPORT_SYMBOL_GPL vmlinux 0x33b6e752 acpi_ec_remove_query_handler +EXPORT_SYMBOL_GPL vmlinux 0x33e5a7c1 ata_pci_sff_prepare_host +EXPORT_SYMBOL_GPL vmlinux 0x3441c3d6 gpio_set_value_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x34de5c6b ata_pci_bmdma_clear_simplex +EXPORT_SYMBOL_GPL vmlinux 0x34fd079e udp4_lib_lookup +EXPORT_SYMBOL_GPL vmlinux 0x352f869d unregister_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0x3539a5c1 rtc_class_close +EXPORT_SYMBOL_GPL vmlinux 0x357d4d31 rdev_get_dev +EXPORT_SYMBOL_GPL vmlinux 0x35aae00b inet6_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0x35ccae06 relay_flush +EXPORT_SYMBOL_GPL vmlinux 0x35d8c94a sdev_evt_alloc +EXPORT_SYMBOL_GPL vmlinux 0x36160b25 sata_sff_hardreset +EXPORT_SYMBOL_GPL vmlinux 0x361e2bcc save_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0x362e23ec call_rcu_bh +EXPORT_SYMBOL_GPL vmlinux 0x363df896 hid_input_report +EXPORT_SYMBOL_GPL vmlinux 0x366522ea unregister_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0x3684ba31 pci_disable_rom +EXPORT_SYMBOL_GPL vmlinux 0x36d69a7a regulator_register +EXPORT_SYMBOL_GPL vmlinux 0x3740b493 ata_port_probe +EXPORT_SYMBOL_GPL vmlinux 0x3747326e dev_attr_unload_heads +EXPORT_SYMBOL_GPL vmlinux 0x374dd09a usb_autopm_set_interface +EXPORT_SYMBOL_GPL vmlinux 0x3779596c ata_host_alloc_pinfo +EXPORT_SYMBOL_GPL vmlinux 0x37dcc3e0 queue_work +EXPORT_SYMBOL_GPL vmlinux 0x3895233b srcu_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x38f9553f spi_busnum_to_master +EXPORT_SYMBOL_GPL vmlinux 0x3904ca70 ata_dev_disable +EXPORT_SYMBOL_GPL vmlinux 0x39138d95 inet_ctl_sock_create +EXPORT_SYMBOL_GPL vmlinux 0x3914a31f ip_route_output_flow +EXPORT_SYMBOL_GPL vmlinux 0x39238b57 klist_del +EXPORT_SYMBOL_GPL vmlinux 0x396d9b53 rt_mutex_unlock +EXPORT_SYMBOL_GPL vmlinux 0x39e52add __cpufreq_driver_target +EXPORT_SYMBOL_GPL vmlinux 0x3a7f8b86 __local_bh_enable +EXPORT_SYMBOL_GPL vmlinux 0x3b0886ab driver_register +EXPORT_SYMBOL_GPL vmlinux 0x3b394c79 sdio_release_host +EXPORT_SYMBOL_GPL vmlinux 0x3b874458 ata_sas_port_alloc +EXPORT_SYMBOL_GPL vmlinux 0x3ba33ae4 blkdev_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x3ba44308 usb_hcd_pci_remove +EXPORT_SYMBOL_GPL vmlinux 0x3be7af02 get_max_files +EXPORT_SYMBOL_GPL vmlinux 0x3be89d3c usb_register_notify +EXPORT_SYMBOL_GPL vmlinux 0x3bf76aed blkcipher_walk_phys +EXPORT_SYMBOL_GPL vmlinux 0x3c7f3150 inet6_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0x3c942368 profile_event_unregister +EXPORT_SYMBOL_GPL vmlinux 0x3cbdf48b ata_sff_dma_pause +EXPORT_SYMBOL_GPL vmlinux 0x3cc42d49 rt_mutex_lock +EXPORT_SYMBOL_GPL vmlinux 0x3cd06035 add_input_randomness +EXPORT_SYMBOL_GPL vmlinux 0x3cfedb3f register_pm_notifier +EXPORT_SYMBOL_GPL vmlinux 0x3d5b7ee3 cpufreq_cpu_get +EXPORT_SYMBOL_GPL vmlinux 0x3d810d81 simple_attr_read +EXPORT_SYMBOL_GPL vmlinux 0x3d99fef2 register_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0x3db49e7e usb_serial_deregister +EXPORT_SYMBOL_GPL vmlinux 0x3e02d902 __mmdrop +EXPORT_SYMBOL_GPL vmlinux 0x3ec50122 pci_find_next_capability +EXPORT_SYMBOL_GPL vmlinux 0x3ecf6cfc wmi_install_notify_handler +EXPORT_SYMBOL_GPL vmlinux 0x3edad223 usb_usual_clear_present +EXPORT_SYMBOL_GPL vmlinux 0x3ef39179 bt_class +EXPORT_SYMBOL_GPL vmlinux 0x3efb35c9 get_online_cpus +EXPORT_SYMBOL_GPL vmlinux 0x3f01570a probe_kernel_write +EXPORT_SYMBOL_GPL vmlinux 0x3f238101 dcookie_register +EXPORT_SYMBOL_GPL vmlinux 0x3f588432 power_supply_changed +EXPORT_SYMBOL_GPL vmlinux 0x3f6e5b8d crypto_givcipher_type +EXPORT_SYMBOL_GPL vmlinux 0x3f810a12 led_trigger_register +EXPORT_SYMBOL_GPL vmlinux 0x3f8262d6 page_cache_sync_readahead +EXPORT_SYMBOL_GPL vmlinux 0x3fb0bbe3 device_del +EXPORT_SYMBOL_GPL vmlinux 0x3fd4ca70 crypto_nivaead_type +EXPORT_SYMBOL_GPL vmlinux 0x4000bd25 tty_get_pgrp +EXPORT_SYMBOL_GPL vmlinux 0x40380ad6 hrtimer_cancel +EXPORT_SYMBOL_GPL vmlinux 0x4094ecd8 ata_acpi_stm +EXPORT_SYMBOL_GPL vmlinux 0x40af0dec ata_xfer_mode2mask +EXPORT_SYMBOL_GPL vmlinux 0x40b0303f tcp_reno_cong_avoid +EXPORT_SYMBOL_GPL vmlinux 0x414255ed platform_bus +EXPORT_SYMBOL_GPL vmlinux 0x41743094 dm_region_hash_destroy +EXPORT_SYMBOL_GPL vmlinux 0x41b2ba22 hid_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0x41f3cc90 xfrm_aalg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x4216f634 platform_add_devices +EXPORT_SYMBOL_GPL vmlinux 0x4261b545 sysfs_put +EXPORT_SYMBOL_GPL vmlinux 0x42955276 skb_icv_walk +EXPORT_SYMBOL_GPL vmlinux 0x42b364ef scatterwalk_done +EXPORT_SYMBOL_GPL vmlinux 0x42ce12aa rtc_irq_register +EXPORT_SYMBOL_GPL vmlinux 0x42ebad19 raw_unhash_sk +EXPORT_SYMBOL_GPL vmlinux 0x43298015 debugfs_create_bool +EXPORT_SYMBOL_GPL vmlinux 0x432fd7f6 __gpio_set_value +EXPORT_SYMBOL_GPL vmlinux 0x43ed351a security_inode_permission +EXPORT_SYMBOL_GPL vmlinux 0x43f56e82 ata_xfer_mode2shift +EXPORT_SYMBOL_GPL vmlinux 0x4407541c crypto_ablkcipher_type +EXPORT_SYMBOL_GPL vmlinux 0x445ce03a raw_seq_next +EXPORT_SYMBOL_GPL vmlinux 0x447f7f35 xfrm_audit_state_add +EXPORT_SYMBOL_GPL vmlinux 0x44a65d5c lock_policy_rwsem_read +EXPORT_SYMBOL_GPL vmlinux 0x450f41c5 cpufreq_frequency_table_target +EXPORT_SYMBOL_GPL vmlinux 0x455f360b sysfs_remove_link +EXPORT_SYMBOL_GPL vmlinux 0x457594fa crypto_alg_list +EXPORT_SYMBOL_GPL vmlinux 0x45bf1fc7 blk_queue_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0x45bf1ff3 crypto_inc +EXPORT_SYMBOL_GPL vmlinux 0x460f31aa rodata_test_data +EXPORT_SYMBOL_GPL vmlinux 0x461c3e30 transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x46304edc ezusb_writememory +EXPORT_SYMBOL_GPL vmlinux 0x463d87a4 dev_attr_em_message +EXPORT_SYMBOL_GPL vmlinux 0x4689bc88 klist_node_attached +EXPORT_SYMBOL_GPL vmlinux 0x46aa0234 hidinput_disconnect +EXPORT_SYMBOL_GPL vmlinux 0x46aed911 ata_sff_host_intr +EXPORT_SYMBOL_GPL vmlinux 0x46bf02a6 usb_hcd_resume_root_hub +EXPORT_SYMBOL_GPL vmlinux 0x46fb8ec4 pci_unblock_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0x47005c63 md_new_event +EXPORT_SYMBOL_GPL vmlinux 0x47229b5c gpio_request +EXPORT_SYMBOL_GPL vmlinux 0x480a7e0f usb_ifnum_to_if +EXPORT_SYMBOL_GPL vmlinux 0x4819a3e1 free_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x4827ad0b ata_sg_init +EXPORT_SYMBOL_GPL vmlinux 0x4843b940 platform_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0x4889749f ata_pci_device_suspend +EXPORT_SYMBOL_GPL vmlinux 0x493f1218 cpci_hp_unregister_bus +EXPORT_SYMBOL_GPL vmlinux 0x49485e2c copy_fs_struct +EXPORT_SYMBOL_GPL vmlinux 0x494f4d44 usb_root_hub_lost_power +EXPORT_SYMBOL_GPL vmlinux 0x499043d3 crypto_init_queue +EXPORT_SYMBOL_GPL vmlinux 0x49eb4af4 sock_prot_inuse_get +EXPORT_SYMBOL_GPL vmlinux 0x4a49a0a4 inotify_init +EXPORT_SYMBOL_GPL vmlinux 0x4a7e30d9 marker_probe_unregister_private_data +EXPORT_SYMBOL_GPL vmlinux 0x4aa5575b sdio_memcpy_toio +EXPORT_SYMBOL_GPL vmlinux 0x4ab4c4b3 dequeue_signal +EXPORT_SYMBOL_GPL vmlinux 0x4ad4e6b6 ata_qc_complete_multiple +EXPORT_SYMBOL_GPL vmlinux 0x4ae2986f user_describe +EXPORT_SYMBOL_GPL vmlinux 0x4bcef498 dev_set_name +EXPORT_SYMBOL_GPL vmlinux 0x4bcf1c02 blk_execute_rq_nowait +EXPORT_SYMBOL_GPL vmlinux 0x4c1bb689 class_dev_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x4c32215e power_supply_unregister +EXPORT_SYMBOL_GPL vmlinux 0x4c6b58a5 tty_prepare_flip_string +EXPORT_SYMBOL_GPL vmlinux 0x4c759827 byte_rev_table +EXPORT_SYMBOL_GPL vmlinux 0x4ccfed1f transport_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0x4cd5459f scsi_queue_work +EXPORT_SYMBOL_GPL vmlinux 0x4cdb4bd0 speedstep_get_processor_frequency +EXPORT_SYMBOL_GPL vmlinux 0x4cf06b68 sysdev_create_file +EXPORT_SYMBOL_GPL vmlinux 0x4d2d9e1b sysfs_create_group +EXPORT_SYMBOL_GPL vmlinux 0x4d68f37a get_user_pages_fast +EXPORT_SYMBOL_GPL vmlinux 0x4d9c6bbf i2c_new_probed_device +EXPORT_SYMBOL_GPL vmlinux 0x4dc03834 ipv6_find_tlv +EXPORT_SYMBOL_GPL vmlinux 0x4dc3829f usb_buffer_free +EXPORT_SYMBOL_GPL vmlinux 0x4df09230 hvc_poll +EXPORT_SYMBOL_GPL vmlinux 0x4eb0acc7 __cpufreq_driver_getavg +EXPORT_SYMBOL_GPL vmlinux 0x4efc28c9 rtc_set_time +EXPORT_SYMBOL_GPL vmlinux 0x4f1d014b usb_hcd_poll_rh_status +EXPORT_SYMBOL_GPL vmlinux 0x4fdc945d sata_deb_timing_normal +EXPORT_SYMBOL_GPL vmlinux 0x502ea6d3 xfrm_audit_state_delete +EXPORT_SYMBOL_GPL vmlinux 0x50320bb9 usb_reset_device +EXPORT_SYMBOL_GPL vmlinux 0x504acde3 device_find_child +EXPORT_SYMBOL_GPL vmlinux 0x507c6f88 cpufreq_driver_target +EXPORT_SYMBOL_GPL vmlinux 0x5086ac3a alg_test +EXPORT_SYMBOL_GPL vmlinux 0x50b67174 xfrm_ealg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x50d359b5 macvlan_handle_frame_hook +EXPORT_SYMBOL_GPL vmlinux 0x50e7193a __i2c_first_dynamic_bus_num +EXPORT_SYMBOL_GPL vmlinux 0x50fad434 round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x5108b3fc acpi_os_map_memory +EXPORT_SYMBOL_GPL vmlinux 0x5112f5da transport_configure_device +EXPORT_SYMBOL_GPL vmlinux 0x511f3e1f apic_ops +EXPORT_SYMBOL_GPL vmlinux 0x518c2fc6 hpet_rtc_dropped_irq +EXPORT_SYMBOL_GPL vmlinux 0x519a8d54 cpci_hp_register_controller +EXPORT_SYMBOL_GPL vmlinux 0x51cafbbc cpuidle_enable_device +EXPORT_SYMBOL_GPL vmlinux 0x51dd6488 xfrm_aalg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x52561a9c bus_create_file +EXPORT_SYMBOL_GPL vmlinux 0x526b867a acpi_smbus_read +EXPORT_SYMBOL_GPL vmlinux 0x526ea172 user_destroy +EXPORT_SYMBOL_GPL vmlinux 0x527a2b6e usb_put_intf +EXPORT_SYMBOL_GPL vmlinux 0x52b036ea driver_find_device +EXPORT_SYMBOL_GPL vmlinux 0x52d111ea pm_qos_update_requirement +EXPORT_SYMBOL_GPL vmlinux 0x52d55863 posix_timer_event +EXPORT_SYMBOL_GPL vmlinux 0x52d7288d usb_driver_set_configuration +EXPORT_SYMBOL_GPL vmlinux 0x5324acc0 usb_ep0_reinit +EXPORT_SYMBOL_GPL vmlinux 0x533ed38a inet_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0x53614269 get_cpu_idle_time_us +EXPORT_SYMBOL_GPL vmlinux 0x5372dede unregister_acpi_bus_notifier +EXPORT_SYMBOL_GPL vmlinux 0x53986488 register_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x53a7f3eb fib_rules_cleanup_ops +EXPORT_SYMBOL_GPL vmlinux 0x53af7a0f audit_log_d_path +EXPORT_SYMBOL_GPL vmlinux 0x545e768e led_trigger_unregister +EXPORT_SYMBOL_GPL vmlinux 0x546c6d05 d_materialise_unique +EXPORT_SYMBOL_GPL vmlinux 0x547b0bba generic_fh_to_dentry +EXPORT_SYMBOL_GPL vmlinux 0x547cc3dd usb_serial_register +EXPORT_SYMBOL_GPL vmlinux 0x54a9e27b tcp_set_state +EXPORT_SYMBOL_GPL vmlinux 0x54bf4158 usb_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x55cd2a13 ata_std_bios_param +EXPORT_SYMBOL_GPL vmlinux 0x55e09dfe inotify_inode_is_dead +EXPORT_SYMBOL_GPL vmlinux 0x55fb926d usb_hub_tt_clear_buffer +EXPORT_SYMBOL_GPL vmlinux 0x56389a95 regulator_bulk_free +EXPORT_SYMBOL_GPL vmlinux 0x56398615 mark_tsc_unstable +EXPORT_SYMBOL_GPL vmlinux 0x5641485b tty_termios_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x565b2ecd proc_net_remove +EXPORT_SYMBOL_GPL vmlinux 0x568bc7d4 rt_mutex_destroy +EXPORT_SYMBOL_GPL vmlinux 0x56aaa37a usb_get_dev +EXPORT_SYMBOL_GPL vmlinux 0x56cbdcd9 alloc_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x56d40cb5 crypto_dequeue_request +EXPORT_SYMBOL_GPL vmlinux 0x57192dbd platform_device_register +EXPORT_SYMBOL_GPL vmlinux 0x579e0bf5 rtnl_unregister_all +EXPORT_SYMBOL_GPL vmlinux 0x57a70fbc ata_sff_postreset +EXPORT_SYMBOL_GPL vmlinux 0x57b49126 dm_rh_recovery_start +EXPORT_SYMBOL_GPL vmlinux 0x58baf735 ata_host_detach +EXPORT_SYMBOL_GPL vmlinux 0x58be68c0 inet_twsk_put +EXPORT_SYMBOL_GPL vmlinux 0x58c0ff21 user_instantiate +EXPORT_SYMBOL_GPL vmlinux 0x59172f01 fb_deferred_io_init +EXPORT_SYMBOL_GPL vmlinux 0x593a36c2 scsi_dh_handler_exist +EXPORT_SYMBOL_GPL vmlinux 0x594a0ec5 crypto_drop_spawn +EXPORT_SYMBOL_GPL vmlinux 0x59735115 debugfs_create_symlink +EXPORT_SYMBOL_GPL vmlinux 0x597f3bc3 marker_get_private_data +EXPORT_SYMBOL_GPL vmlinux 0x59858afd proc_net_fops_create +EXPORT_SYMBOL_GPL vmlinux 0x59a3af1c device_for_each_child +EXPORT_SYMBOL_GPL vmlinux 0x5a0ff50d sysfs_notify +EXPORT_SYMBOL_GPL vmlinux 0x5a6f5cff cpufreq_freq_attr_scaling_available_freqs +EXPORT_SYMBOL_GPL vmlinux 0x5a7bfe41 crypto_probing_notify +EXPORT_SYMBOL_GPL vmlinux 0x5a91126a scsi_dh_activate +EXPORT_SYMBOL_GPL vmlinux 0x5aa45eaa debugfs_create_u32 +EXPORT_SYMBOL_GPL vmlinux 0x5ac8c6b7 unregister_kprobes +EXPORT_SYMBOL_GPL vmlinux 0x5b18ae11 cpufreq_unregister_governor +EXPORT_SYMBOL_GPL vmlinux 0x5b527e9a crypto_register_instance +EXPORT_SYMBOL_GPL vmlinux 0x5b5ae159 cpufreq_cpu_put +EXPORT_SYMBOL_GPL vmlinux 0x5b87739e sdio_writesb +EXPORT_SYMBOL_GPL vmlinux 0x5bd9c256 security_inode_setattr +EXPORT_SYMBOL_GPL vmlinux 0x5bfc03c3 unregister_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5c6378c5 device_release_driver +EXPORT_SYMBOL_GPL vmlinux 0x5ca8e79f __ip_route_output_key +EXPORT_SYMBOL_GPL vmlinux 0x5cfcf0f1 percpu_free +EXPORT_SYMBOL_GPL vmlinux 0x5cff954c apply_to_page_range +EXPORT_SYMBOL_GPL vmlinux 0x5d0f6f57 kbd_table +EXPORT_SYMBOL_GPL vmlinux 0x5d39aa22 ata_pci_sff_init_host +EXPORT_SYMBOL_GPL vmlinux 0x5d4e594c kobject_uevent +EXPORT_SYMBOL_GPL vmlinux 0x5d51bcf7 scatterwalk_start +EXPORT_SYMBOL_GPL vmlinux 0x5d730e7b raw_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5d87c067 register_acpi_bus_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5dd67618 register_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5de29200 unregister_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0x5e099c16 transport_remove_device +EXPORT_SYMBOL_GPL vmlinux 0x5ed71e34 raw_seq_stop +EXPORT_SYMBOL_GPL vmlinux 0x5f2da8c4 check_tsc_unstable +EXPORT_SYMBOL_GPL vmlinux 0x5f3142e7 generic_sync_sb_inodes +EXPORT_SYMBOL_GPL vmlinux 0x5f4a3ed9 dm_rh_update_states +EXPORT_SYMBOL_GPL vmlinux 0x5f6b7087 usb_sg_init +EXPORT_SYMBOL_GPL vmlinux 0x5f6ce3d9 pci_find_ext_capability +EXPORT_SYMBOL_GPL vmlinux 0x5f8532e7 skcipher_geniv_free +EXPORT_SYMBOL_GPL vmlinux 0x5f90d1cc ata_cable_80wire +EXPORT_SYMBOL_GPL vmlinux 0x600e7073 ata_bmdma_stop +EXPORT_SYMBOL_GPL vmlinux 0x6043da29 sched_setscheduler +EXPORT_SYMBOL_GPL vmlinux 0x605ff123 klist_add_tail +EXPORT_SYMBOL_GPL vmlinux 0x6062168b blk_queue_rq_timeout +EXPORT_SYMBOL_GPL vmlinux 0x6091797f synchronize_rcu +EXPORT_SYMBOL_GPL vmlinux 0x60a13e90 rcu_barrier +EXPORT_SYMBOL_GPL vmlinux 0x610ee73a sdev_evt_send +EXPORT_SYMBOL_GPL vmlinux 0x619625d3 sata_scr_valid +EXPORT_SYMBOL_GPL vmlinux 0x61d5f003 class_destroy +EXPORT_SYMBOL_GPL vmlinux 0x622f1923 sysfs_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x632d1300 crypto_unregister_template +EXPORT_SYMBOL_GPL vmlinux 0x63ae27d6 add_nops +EXPORT_SYMBOL_GPL vmlinux 0x64084a1c dev_attr_link_power_management_policy +EXPORT_SYMBOL_GPL vmlinux 0x6423a008 sata_pmp_error_handler +EXPORT_SYMBOL_GPL vmlinux 0x6447a3bf input_ff_destroy +EXPORT_SYMBOL_GPL vmlinux 0x6479dd8a disk_part_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x64b0b508 tty_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x64ebe677 wmi_query_block +EXPORT_SYMBOL_GPL vmlinux 0x6515d51a preempt_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x6584948d ata_host_alloc +EXPORT_SYMBOL_GPL vmlinux 0x65acbde4 da903x_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x65ccb6f0 call_netevent_notifiers +EXPORT_SYMBOL_GPL vmlinux 0x65d6d0f0 gpio_direction_input +EXPORT_SYMBOL_GPL vmlinux 0x65e9ed95 regulator_get +EXPORT_SYMBOL_GPL vmlinux 0x6610ad99 synchronize_srcu +EXPORT_SYMBOL_GPL vmlinux 0x661601de sprint_symbol +EXPORT_SYMBOL_GPL vmlinux 0x6650034b rtc_irq_set_freq +EXPORT_SYMBOL_GPL vmlinux 0x668402aa crypto_put_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x66b2a859 nr_free_buffer_pages +EXPORT_SYMBOL_GPL vmlinux 0x66d87d38 symbol_put_addr +EXPORT_SYMBOL_GPL vmlinux 0x6724d3d4 crypto_hash_walk_first +EXPORT_SYMBOL_GPL vmlinux 0x677aaa6c ata_host_suspend +EXPORT_SYMBOL_GPL vmlinux 0x67893266 vlan_dev_real_dev +EXPORT_SYMBOL_GPL vmlinux 0x678e7618 ata_common_sdev_attrs +EXPORT_SYMBOL_GPL vmlinux 0x67955ce6 profile_hits +EXPORT_SYMBOL_GPL vmlinux 0x684b4f1e crypto_register_alg +EXPORT_SYMBOL_GPL vmlinux 0x686c703f xfrm_count_auth_supported +EXPORT_SYMBOL_GPL vmlinux 0x6875d38c klist_next +EXPORT_SYMBOL_GPL vmlinux 0x687f8aee __inet_hash_nolisten +EXPORT_SYMBOL_GPL vmlinux 0x6892088c unregister_pm_notifier +EXPORT_SYMBOL_GPL vmlinux 0x68a7cb94 input_ff_upload +EXPORT_SYMBOL_GPL vmlinux 0x69022920 scsi_nl_sock +EXPORT_SYMBOL_GPL vmlinux 0x690fc251 gpiochip_add +EXPORT_SYMBOL_GPL vmlinux 0x6918a433 audit_log_untrustedstring +EXPORT_SYMBOL_GPL vmlinux 0x691d1975 map_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x69290c5c usb_match_id +EXPORT_SYMBOL_GPL vmlinux 0x69349c63 schedule_hrtimeout_range +EXPORT_SYMBOL_GPL vmlinux 0x696fcdf1 flush_workqueue +EXPORT_SYMBOL_GPL vmlinux 0x698484c0 skcipher_geniv_alloc +EXPORT_SYMBOL_GPL vmlinux 0x698713dd led_trigger_remove +EXPORT_SYMBOL_GPL vmlinux 0x698dabb8 pci_hp_register +EXPORT_SYMBOL_GPL vmlinux 0x69a31b4c ata_eh_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0x69b584af pci_hp_change_slot_info +EXPORT_SYMBOL_GPL vmlinux 0x69b93fb1 sata_link_hardreset +EXPORT_SYMBOL_GPL vmlinux 0x69bac3e9 driver_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x69dc1738 fs_kobj +EXPORT_SYMBOL_GPL vmlinux 0x69e9a2cb ata_scsi_slave_config +EXPORT_SYMBOL_GPL vmlinux 0x69ef030f usb_deregister_dev +EXPORT_SYMBOL_GPL vmlinux 0x6a2fe472 bus_get_device_klist +EXPORT_SYMBOL_GPL vmlinux 0x6a8441be cpci_hp_start +EXPORT_SYMBOL_GPL vmlinux 0x6abb68fb tcp_slow_start +EXPORT_SYMBOL_GPL vmlinux 0x6ae6e3f8 device_attach +EXPORT_SYMBOL_GPL vmlinux 0x6b164d5b get_current_tty +EXPORT_SYMBOL_GPL vmlinux 0x6b2376a3 xattr_getsecurity +EXPORT_SYMBOL_GPL vmlinux 0x6b33bbb1 sysfs_chmod_file +EXPORT_SYMBOL_GPL vmlinux 0x6b7e339c ata_sff_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x6befc0bd sata_link_resume +EXPORT_SYMBOL_GPL vmlinux 0x6bf3018a ata_sas_port_start +EXPORT_SYMBOL_GPL vmlinux 0x6bf86cff aead_geniv_init +EXPORT_SYMBOL_GPL vmlinux 0x6c11059b __srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x6c49c4f2 clockevents_notify +EXPORT_SYMBOL_GPL vmlinux 0x6c570807 md_allow_write +EXPORT_SYMBOL_GPL vmlinux 0x6c5eca9e fsstack_copy_inode_size +EXPORT_SYMBOL_GPL vmlinux 0x6c770acc scsi_unregister_device_handler +EXPORT_SYMBOL_GPL vmlinux 0x6c8d5ae8 __gpio_get_value +EXPORT_SYMBOL_GPL vmlinux 0x6cbca557 screen_glyph +EXPORT_SYMBOL_GPL vmlinux 0x6cdc7f79 scsi_eh_ready_devs +EXPORT_SYMBOL_GPL vmlinux 0x6d2fc5a6 net_namespace_list +EXPORT_SYMBOL_GPL vmlinux 0x6d71235c ata_sas_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0x6d72c728 tty_ldisc_ref_wait +EXPORT_SYMBOL_GPL vmlinux 0x6d8e3512 inet_twsk_schedule +EXPORT_SYMBOL_GPL vmlinux 0x6db38310 register_net_sysctl_rotable +EXPORT_SYMBOL_GPL vmlinux 0x6dce94bf usb_bus_list_lock +EXPORT_SYMBOL_GPL vmlinux 0x6e0595fc blk_rq_bytes +EXPORT_SYMBOL_GPL vmlinux 0x6e3eaca2 inet6_sk_rebuild_header +EXPORT_SYMBOL_GPL vmlinux 0x6e4b4d16 usb_buffer_map_sg +EXPORT_SYMBOL_GPL vmlinux 0x6e5d923b uart_console_write +EXPORT_SYMBOL_GPL vmlinux 0x6efc70cb dm_rh_recovery_prepare +EXPORT_SYMBOL_GPL vmlinux 0x6f5958d6 bus_find_device_by_name +EXPORT_SYMBOL_GPL vmlinux 0x6f78b6f8 ata_sff_wait_ready +EXPORT_SYMBOL_GPL vmlinux 0x6f9c2efe marker_probe_cb +EXPORT_SYMBOL_GPL vmlinux 0x6ff607b6 crypto_get_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x702a12cc klist_iter_init_node +EXPORT_SYMBOL_GPL vmlinux 0x7037d79d k8_flush_garts +EXPORT_SYMBOL_GPL vmlinux 0x7051fc62 vfs_listxattr +EXPORT_SYMBOL_GPL vmlinux 0x706b3a33 cpufreq_frequency_table_get_attr +EXPORT_SYMBOL_GPL vmlinux 0x7075e5e3 ata_sff_error_handler +EXPORT_SYMBOL_GPL vmlinux 0x707ff1bb ata_xfer_mask2mode +EXPORT_SYMBOL_GPL vmlinux 0x70cbba54 fib_rules_register +EXPORT_SYMBOL_GPL vmlinux 0x70ef9cc3 sk_clone +EXPORT_SYMBOL_GPL vmlinux 0x711518f4 debugfs_create_u64 +EXPORT_SYMBOL_GPL vmlinux 0x717a5907 debugfs_create_blob +EXPORT_SYMBOL_GPL vmlinux 0x718869ef ata_sff_softreset +EXPORT_SYMBOL_GPL vmlinux 0x71c8bc95 kgdb_unregister_io_module +EXPORT_SYMBOL_GPL vmlinux 0x72084f21 input_ff_erase +EXPORT_SYMBOL_GPL vmlinux 0x722c4f65 usb_scuttle_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x7278d328 all_vm_events +EXPORT_SYMBOL_GPL vmlinux 0x7286fc94 find_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0x72d11bd6 fb_bl_default_curve +EXPORT_SYMBOL_GPL vmlinux 0x734ea682 device_destroy +EXPORT_SYMBOL_GPL vmlinux 0x73a48b4a ata_sff_std_ports +EXPORT_SYMBOL_GPL vmlinux 0x73b1f76d do_posix_clock_nosettime +EXPORT_SYMBOL_GPL vmlinux 0x73fe9c01 da903x_clr_bits +EXPORT_SYMBOL_GPL vmlinux 0x743a165e ata_pack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0x74abdafa task_handoff_register +EXPORT_SYMBOL_GPL vmlinux 0x74bf085e crypto_unregister_alg +EXPORT_SYMBOL_GPL vmlinux 0x74d61a4d get_dcookie +EXPORT_SYMBOL_GPL vmlinux 0x74deb10c used_vectors +EXPORT_SYMBOL_GPL vmlinux 0x7521afb6 leave_mm +EXPORT_SYMBOL_GPL vmlinux 0x753ff790 ip6_dst_lookup +EXPORT_SYMBOL_GPL vmlinux 0x7568b92e register_jprobes +EXPORT_SYMBOL_GPL vmlinux 0x75c3736c devres_release_group +EXPORT_SYMBOL_GPL vmlinux 0x75c8a11c inet_twdr_twkill_work +EXPORT_SYMBOL_GPL vmlinux 0x75e8f3c3 crypto_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x75f43152 blk_update_request +EXPORT_SYMBOL_GPL vmlinux 0x760a1dc5 __rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0x7681ce56 usb_alloc_urb +EXPORT_SYMBOL_GPL vmlinux 0x76a14472 ata_pci_remove_one +EXPORT_SYMBOL_GPL vmlinux 0x76f0ddc0 driver_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x7701f7b6 pid_vnr +EXPORT_SYMBOL_GPL vmlinux 0x7751aae0 user_update +EXPORT_SYMBOL_GPL vmlinux 0x7789abff inet_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0x7804f40d klist_remove +EXPORT_SYMBOL_GPL vmlinux 0x788850aa ata_bmdma_status +EXPORT_SYMBOL_GPL vmlinux 0x78b44e08 get_device +EXPORT_SYMBOL_GPL vmlinux 0x78c36155 pci_slots_kset +EXPORT_SYMBOL_GPL vmlinux 0x78e91ade scsi_nl_add_driver +EXPORT_SYMBOL_GPL vmlinux 0x794dd69c usb_get_urb +EXPORT_SYMBOL_GPL vmlinux 0x797423ac klist_add_before +EXPORT_SYMBOL_GPL vmlinux 0x79c9687b tcp_register_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0x79d4044d usb_hcd_link_urb_to_ep +EXPORT_SYMBOL_GPL vmlinux 0x7a2cfb0a xfrm_audit_state_notfound +EXPORT_SYMBOL_GPL vmlinux 0x7a4c1438 pv_info +EXPORT_SYMBOL_GPL vmlinux 0x7ae1ae8e cpufreq_frequency_table_put_attr +EXPORT_SYMBOL_GPL vmlinux 0x7ae496e6 blkcipher_walk_virt_block +EXPORT_SYMBOL_GPL vmlinux 0x7b1d544d edac_handler_set +EXPORT_SYMBOL_GPL vmlinux 0x7b344622 ata_sff_dev_select +EXPORT_SYMBOL_GPL vmlinux 0x7b614dcf crypto_blkcipher_type +EXPORT_SYMBOL_GPL vmlinux 0x7b85a346 pci_renumber_slot +EXPORT_SYMBOL_GPL vmlinux 0x7b8a3cbd pskb_put +EXPORT_SYMBOL_GPL vmlinux 0x7bbf27dd ata_host_register +EXPORT_SYMBOL_GPL vmlinux 0x7bca83c9 crypto_larval_kill +EXPORT_SYMBOL_GPL vmlinux 0x7bda6705 ata_sff_port_start +EXPORT_SYMBOL_GPL vmlinux 0x7c126ba3 hid_report_raw_event +EXPORT_SYMBOL_GPL vmlinux 0x7c14dea5 scsi_register_device_handler +EXPORT_SYMBOL_GPL vmlinux 0x7c19adf4 ata_sff_exec_command +EXPORT_SYMBOL_GPL vmlinux 0x7cf2b9cc devres_destroy +EXPORT_SYMBOL_GPL vmlinux 0x7d1ea4aa mnt_drop_write +EXPORT_SYMBOL_GPL vmlinux 0x7d94be41 pci_enable_rom +EXPORT_SYMBOL_GPL vmlinux 0x7da8d037 marker_probe_register +EXPORT_SYMBOL_GPL vmlinux 0x7dafe0be bd_claim_by_disk +EXPORT_SYMBOL_GPL vmlinux 0x7dc5d0b6 crypto_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x7dcb38c6 usb_hcd_pci_probe +EXPORT_SYMBOL_GPL vmlinux 0x7e275ea8 scsi_complete_async_scans +EXPORT_SYMBOL_GPL vmlinux 0x7e64181d usb_calc_bus_time +EXPORT_SYMBOL_GPL vmlinux 0x7e698a51 unregister_jprobes +EXPORT_SYMBOL_GPL vmlinux 0x7ee93659 platform_device_alloc +EXPORT_SYMBOL_GPL vmlinux 0x7f00ec83 ip6_local_out +EXPORT_SYMBOL_GPL vmlinux 0x7f192c3a usb_register_dev +EXPORT_SYMBOL_GPL vmlinux 0x7f19c836 unlock_policy_rwsem_write +EXPORT_SYMBOL_GPL vmlinux 0x7f6f5005 ata_host_resume +EXPORT_SYMBOL_GPL vmlinux 0x7fc326e9 usb_init_urb +EXPORT_SYMBOL_GPL vmlinux 0x7ff10ccf raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x800050d4 usb_hcd_unlink_urb_from_ep +EXPORT_SYMBOL_GPL vmlinux 0x800b10bf rtc_set_mmss +EXPORT_SYMBOL_GPL vmlinux 0x802ef5ac usb_buffer_alloc +EXPORT_SYMBOL_GPL vmlinux 0x8039d043 selinux_secmark_relabel_packet_permission +EXPORT_SYMBOL_GPL vmlinux 0x803e4900 sysdev_class_register +EXPORT_SYMBOL_GPL vmlinux 0x808ec1a3 crypto_alg_tested +EXPORT_SYMBOL_GPL vmlinux 0x80a6690c sk_setup_caps +EXPORT_SYMBOL_GPL vmlinux 0x80ee55c3 selinux_secmark_refcount_inc +EXPORT_SYMBOL_GPL vmlinux 0x812c7fac hrtimer_try_to_cancel +EXPORT_SYMBOL_GPL vmlinux 0x81e770b3 debugfs_remove +EXPORT_SYMBOL_GPL vmlinux 0x81fe8bcd hidraw_connect +EXPORT_SYMBOL_GPL vmlinux 0x820f8dcb scsi_execute_async +EXPORT_SYMBOL_GPL vmlinux 0x82207061 cpufreq_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x8226642f __gpio_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x825f1c69 inotify_add_watch +EXPORT_SYMBOL_GPL vmlinux 0x826360fd do_posix_clock_nonanosleep +EXPORT_SYMBOL_GPL vmlinux 0x8268ead4 iounmap_atomic +EXPORT_SYMBOL_GPL vmlinux 0x82692207 inet_unhash +EXPORT_SYMBOL_GPL vmlinux 0x826c53b6 blk_trace_remove +EXPORT_SYMBOL_GPL vmlinux 0x82742a6b attribute_container_register +EXPORT_SYMBOL_GPL vmlinux 0x82beefaa inet_twsk_alloc +EXPORT_SYMBOL_GPL vmlinux 0x82c204d7 gpiochip_remove +EXPORT_SYMBOL_GPL vmlinux 0x82d736f0 ata_sff_hsm_move +EXPORT_SYMBOL_GPL vmlinux 0x82d79b51 sysctl_vfs_cache_pressure +EXPORT_SYMBOL_GPL vmlinux 0x82f5273b register_timer_hook +EXPORT_SYMBOL_GPL vmlinux 0x82f776b7 gpio_export +EXPORT_SYMBOL_GPL vmlinux 0x83089c6d inet6_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0x830b1398 find_vpid +EXPORT_SYMBOL_GPL vmlinux 0x83368956 device_create +EXPORT_SYMBOL_GPL vmlinux 0x83751e80 ata_sas_port_destroy +EXPORT_SYMBOL_GPL vmlinux 0x83b2e956 register_rfkill_notifier +EXPORT_SYMBOL_GPL vmlinux 0x83c2bc46 tracepoint_iter_stop +EXPORT_SYMBOL_GPL vmlinux 0x83cf1f24 class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x84834145 hrtimer_get_remaining +EXPORT_SYMBOL_GPL vmlinux 0x852a4513 usb_serial_disconnect +EXPORT_SYMBOL_GPL vmlinux 0x85478a0b inet6_hash_frag +EXPORT_SYMBOL_GPL vmlinux 0x8547d5c5 usb_unanchor_urb +EXPORT_SYMBOL_GPL vmlinux 0x85c10896 rcu_batches_completed_bh +EXPORT_SYMBOL_GPL vmlinux 0x85d7edfd hpet_set_periodic_freq +EXPORT_SYMBOL_GPL vmlinux 0x85e5a3db ktime_get_ts +EXPORT_SYMBOL_GPL vmlinux 0x8670e61d __ata_port_next_link +EXPORT_SYMBOL_GPL vmlinux 0x867c684a setup_APIC_eilvt_ibs +EXPORT_SYMBOL_GPL vmlinux 0x867d6ddc ata_cable_ignore +EXPORT_SYMBOL_GPL vmlinux 0x868784cb __symbol_get +EXPORT_SYMBOL_GPL vmlinux 0x86b10394 ehci_cf_port_reset_rwsem +EXPORT_SYMBOL_GPL vmlinux 0x86b1667d hwrng_unregister +EXPORT_SYMBOL_GPL vmlinux 0x86c722f8 rfkill_epo +EXPORT_SYMBOL_GPL vmlinux 0x870404b8 crypto_chain +EXPORT_SYMBOL_GPL vmlinux 0x8736c400 crypto_aead_type +EXPORT_SYMBOL_GPL vmlinux 0x873fbaea edac_atomic_assert_error +EXPORT_SYMBOL_GPL vmlinux 0x874efcae ata_dummy_port_info +EXPORT_SYMBOL_GPL vmlinux 0x8764f7a9 rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x876d0d8c ata_link_offline +EXPORT_SYMBOL_GPL vmlinux 0x87754115 raw_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x87793349 dm_rh_mark_nosync +EXPORT_SYMBOL_GPL vmlinux 0x8805167d __mmu_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x880b189a __atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x8810ad5e crypto_xor +EXPORT_SYMBOL_GPL vmlinux 0x885142a6 nf_net_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x886736fc olpc_platform_info +EXPORT_SYMBOL_GPL vmlinux 0x889e0191 isa_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x88b8daec platform_get_resource_byname +EXPORT_SYMBOL_GPL vmlinux 0x88c19f5a tty_ldisc_deref +EXPORT_SYMBOL_GPL vmlinux 0x8911a43a rtc_device_register +EXPORT_SYMBOL_GPL vmlinux 0x891e2046 rtc_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x895bdb93 ata_pci_device_do_suspend +EXPORT_SYMBOL_GPL vmlinux 0x89d4dbaf usb_usual_check_type +EXPORT_SYMBOL_GPL vmlinux 0x89e3fc6d xfrm_audit_state_replay_overflow +EXPORT_SYMBOL_GPL vmlinux 0x89fe9eac aead_geniv_alloc +EXPORT_SYMBOL_GPL vmlinux 0x8a1c739e usb_deregister +EXPORT_SYMBOL_GPL vmlinux 0x8abed13d xfrm_aead_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x8ad69bb8 acpi_get_hp_params_from_firmware +EXPORT_SYMBOL_GPL vmlinux 0x8b277706 ata_port_desc +EXPORT_SYMBOL_GPL vmlinux 0x8b752ac1 ata_tf_to_fis +EXPORT_SYMBOL_GPL vmlinux 0x8b995595 dm_rh_get_region_key +EXPORT_SYMBOL_GPL vmlinux 0x8bb8692c usb_kill_urb +EXPORT_SYMBOL_GPL vmlinux 0x8be75d85 sysdev_show_ulong +EXPORT_SYMBOL_GPL vmlinux 0x8bf05aaa inotify_find_update_watch +EXPORT_SYMBOL_GPL vmlinux 0x8c103671 bus_unregister +EXPORT_SYMBOL_GPL vmlinux 0x8c81695b ata_acpi_gtm_xfermask +EXPORT_SYMBOL_GPL vmlinux 0x8ceb4816 register_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0x8cf4aa48 dm_rh_dirty_log +EXPORT_SYMBOL_GPL vmlinux 0x8cf7b442 tcp_twsk_destructor +EXPORT_SYMBOL_GPL vmlinux 0x8d0009bc usb_lock_device_for_reset +EXPORT_SYMBOL_GPL vmlinux 0x8d0e45d7 sdio_f0_writeb +EXPORT_SYMBOL_GPL vmlinux 0x8d2cf55c scsi_target_block +EXPORT_SYMBOL_GPL vmlinux 0x8d376de8 spi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x8da17b42 scatterwalk_copychunks +EXPORT_SYMBOL_GPL vmlinux 0x8dd1fc37 kern_mount_data +EXPORT_SYMBOL_GPL vmlinux 0x8dd78d25 blocking_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x8eb58c6e __wake_up_sync +EXPORT_SYMBOL_GPL vmlinux 0x8eee05b8 class_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x8ef51d90 platform_get_resource +EXPORT_SYMBOL_GPL vmlinux 0x8f569c8c __get_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x8f699702 ata_sff_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x8f6cee77 __round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x8f96a000 device_initialize +EXPORT_SYMBOL_GPL vmlinux 0x8fcf4cf7 __sock_recv_timestamp +EXPORT_SYMBOL_GPL vmlinux 0x8fedd982 rt_mutex_trylock +EXPORT_SYMBOL_GPL vmlinux 0x8ff8dbcd blocking_notifier_chain_cond_register +EXPORT_SYMBOL_GPL vmlinux 0x9009602a acpi_bus_get_ejd +EXPORT_SYMBOL_GPL vmlinux 0x901468d9 hid_allocate_device +EXPORT_SYMBOL_GPL vmlinux 0x90210ea3 ata_sff_thaw +EXPORT_SYMBOL_GPL vmlinux 0x906b805e srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x90811115 device_add +EXPORT_SYMBOL_GPL vmlinux 0x90a1004a crypto_has_alg +EXPORT_SYMBOL_GPL vmlinux 0x90c860b1 crypto_lookup_template +EXPORT_SYMBOL_GPL vmlinux 0x90e62d78 device_create_file +EXPORT_SYMBOL_GPL vmlinux 0x91482eef usb_anchor_empty +EXPORT_SYMBOL_GPL vmlinux 0x914c9ea5 register_posix_clock +EXPORT_SYMBOL_GPL vmlinux 0x9159b9d6 profile_event_register +EXPORT_SYMBOL_GPL vmlinux 0x91894270 fb_deferred_io_cleanup +EXPORT_SYMBOL_GPL vmlinux 0x91947dc8 zap_vma_ptes +EXPORT_SYMBOL_GPL vmlinux 0x91b9a453 ata_std_qc_defer +EXPORT_SYMBOL_GPL vmlinux 0x91dacaa2 acpi_processor_ffh_cstate_probe +EXPORT_SYMBOL_GPL vmlinux 0x9241c3ee device_power_down +EXPORT_SYMBOL_GPL vmlinux 0x92445aee hrtimer_get_res +EXPORT_SYMBOL_GPL vmlinux 0x924b8865 blk_abort_queue +EXPORT_SYMBOL_GPL vmlinux 0x92ccc5ae usb_serial_generic_write_bulk_callback +EXPORT_SYMBOL_GPL vmlinux 0x92cf8a2e ata_sff_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0x92d11ce7 usb_bulk_msg +EXPORT_SYMBOL_GPL vmlinux 0x92d31cfb fixed_phy_add +EXPORT_SYMBOL_GPL vmlinux 0x92fb217b dcookie_unregister +EXPORT_SYMBOL_GPL vmlinux 0x9308c817 pci_destroy_slot +EXPORT_SYMBOL_GPL vmlinux 0x9326e436 crypto_alloc_aead +EXPORT_SYMBOL_GPL vmlinux 0x933740ca cancel_work_sync +EXPORT_SYMBOL_GPL vmlinux 0x93520f5e debugfs_create_x16 +EXPORT_SYMBOL_GPL vmlinux 0x93713786 pci_intx +EXPORT_SYMBOL_GPL vmlinux 0x93aaa5bd crypto_shoot_alg +EXPORT_SYMBOL_GPL vmlinux 0x93d2422d snmp_mib_free +EXPORT_SYMBOL_GPL vmlinux 0x9422247b platform_driver_register +EXPORT_SYMBOL_GPL vmlinux 0x942c1704 cleanup_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x944cbf18 crypto_larval_lookup +EXPORT_SYMBOL_GPL vmlinux 0x94a68723 ata_scsi_slave_destroy +EXPORT_SYMBOL_GPL vmlinux 0x94dc62d2 ata_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x94deb77b dev_attr_sw_activity +EXPORT_SYMBOL_GPL vmlinux 0x94ef4d05 cpci_hp_stop +EXPORT_SYMBOL_GPL vmlinux 0x952664c5 do_exit +EXPORT_SYMBOL_GPL vmlinux 0x956a91ba gpio_get_value_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x9577271c hpet_rtc_interrupt +EXPORT_SYMBOL_GPL vmlinux 0x9587cd3e dm_put +EXPORT_SYMBOL_GPL vmlinux 0x95f5c1c1 dm_region_hash_create +EXPORT_SYMBOL_GPL vmlinux 0x961a8cd3 unlock_policy_rwsem_read +EXPORT_SYMBOL_GPL vmlinux 0x969aca5f default_backing_dev_info +EXPORT_SYMBOL_GPL vmlinux 0x96cbcf31 pm_qos_add_notifier +EXPORT_SYMBOL_GPL vmlinux 0x96d78150 sysfs_update_group +EXPORT_SYMBOL_GPL vmlinux 0x977f92a8 blkcipher_walk_done +EXPORT_SYMBOL_GPL vmlinux 0x97c4a562 dm_rh_inc_pending +EXPORT_SYMBOL_GPL vmlinux 0x97e9eb21 usb_set_interface +EXPORT_SYMBOL_GPL vmlinux 0x982362fb disk_part_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x9833bc0c hvc_kick +EXPORT_SYMBOL_GPL vmlinux 0x9862d0e3 anon_transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x988e4bf6 driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0x98adb824 hrtimer_forward +EXPORT_SYMBOL_GPL vmlinux 0x98b681f4 tty_ldisc_ref +EXPORT_SYMBOL_GPL vmlinux 0x990eda18 usb_buffer_unmap_sg +EXPORT_SYMBOL_GPL vmlinux 0x9924c496 __usb_get_extra_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x994db339 inet_twsk_purge +EXPORT_SYMBOL_GPL vmlinux 0x995d1071 prof_on +EXPORT_SYMBOL_GPL vmlinux 0x9985af36 __blkdev_driver_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x999d7673 usb_driver_release_interface +EXPORT_SYMBOL_GPL vmlinux 0x99d944e6 ata_cable_40wire +EXPORT_SYMBOL_GPL vmlinux 0x99fceef5 bus_get_kset +EXPORT_SYMBOL_GPL vmlinux 0x9a07bdf2 set_cpus_allowed_ptr +EXPORT_SYMBOL_GPL vmlinux 0x9a11a0fc crypto_attr_alg_name +EXPORT_SYMBOL_GPL vmlinux 0x9a15111e scsi_dh_detach +EXPORT_SYMBOL_GPL vmlinux 0x9a398f5c xfrm_ealg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x9a45482c hid_set_field +EXPORT_SYMBOL_GPL vmlinux 0x9a58c100 debugfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0x9a752c07 class_dev_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x9aac86f8 bus_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x9af14948 device_schedule_callback_owner +EXPORT_SYMBOL_GPL vmlinux 0x9af940d5 usb_clear_halt +EXPORT_SYMBOL_GPL vmlinux 0x9b0a7058 attribute_container_classdev_to_container +EXPORT_SYMBOL_GPL vmlinux 0x9b4f3e7f acpi_bus_trim +EXPORT_SYMBOL_GPL vmlinux 0x9ba0501e unregister_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0x9bc47866 devres_remove +EXPORT_SYMBOL_GPL vmlinux 0x9bc95cd9 register_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0x9c288532 regulator_enable +EXPORT_SYMBOL_GPL vmlinux 0x9c970675 sata_set_spd +EXPORT_SYMBOL_GPL vmlinux 0x9c9cb0d5 blkcipher_walk_virt +EXPORT_SYMBOL_GPL vmlinux 0x9cb7d4ba console_drivers +EXPORT_SYMBOL_GPL vmlinux 0x9cb8037b xfrm_count_enc_supported +EXPORT_SYMBOL_GPL vmlinux 0x9d227c06 blk_insert_cloned_request +EXPORT_SYMBOL_GPL vmlinux 0x9db1cb6f mmu_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x9e711ad2 pm_qos_requirement +EXPORT_SYMBOL_GPL vmlinux 0x9e7b7952 hrtimer_start +EXPORT_SYMBOL_GPL vmlinux 0x9ec7d45a pciserial_init_ports +EXPORT_SYMBOL_GPL vmlinux 0x9f22a25a debugfs_rename +EXPORT_SYMBOL_GPL vmlinux 0x9f3076ef ata_bmdma_mode_filter +EXPORT_SYMBOL_GPL vmlinux 0x9f4283d8 invalidate_inode_pages2 +EXPORT_SYMBOL_GPL vmlinux 0x9f8b450e usb_hcd_check_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0x9fab32cb dm_disk +EXPORT_SYMBOL_GPL vmlinux 0x9fac0139 ata_sff_qc_fill_rtf +EXPORT_SYMBOL_GPL vmlinux 0x9fce80db fb_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x9fd32062 firmware_kobj +EXPORT_SYMBOL_GPL vmlinux 0xa00f3e4c cpufreq_frequency_table_verify +EXPORT_SYMBOL_GPL vmlinux 0xa0255440 net_ipv4_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0xa041bddd sdio_readsb +EXPORT_SYMBOL_GPL vmlinux 0xa0899aba ata_sas_slave_configure +EXPORT_SYMBOL_GPL vmlinux 0xa0eaba9a blk_trace_startstop +EXPORT_SYMBOL_GPL vmlinux 0xa1008562 blk_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0xa1594ec1 blk_set_cmd_filter_defaults +EXPORT_SYMBOL_GPL vmlinux 0xa1596d98 acpi_processor_ffh_cstate_enter +EXPORT_SYMBOL_GPL vmlinux 0xa1892a45 dm_rh_recovery_end +EXPORT_SYMBOL_GPL vmlinux 0xa1ab3866 cpuidle_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0xa1b37339 nf_register_afinfo +EXPORT_SYMBOL_GPL vmlinux 0xa262c71b dm_rh_bio_to_region +EXPORT_SYMBOL_GPL vmlinux 0xa2845e70 netlink_has_listeners +EXPORT_SYMBOL_GPL vmlinux 0xa28d8527 usb_poison_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xa293e856 task_current_syscall +EXPORT_SYMBOL_GPL vmlinux 0xa2d261d8 input_ff_event +EXPORT_SYMBOL_GPL vmlinux 0xa2e67f08 acpi_bus_generate_proc_event4 +EXPORT_SYMBOL_GPL vmlinux 0xa32f41f2 gpiochip_is_requested +EXPORT_SYMBOL_GPL vmlinux 0xa3aa34d9 ata_sas_port_stop +EXPORT_SYMBOL_GPL vmlinux 0xa3b7b867 xfrm_audit_policy_add +EXPORT_SYMBOL_GPL vmlinux 0xa3fa60da usb_submit_urb +EXPORT_SYMBOL_GPL vmlinux 0xa3fc96f0 marker_probe_cb_noarg +EXPORT_SYMBOL_GPL vmlinux 0xa4345c93 simple_attr_write +EXPORT_SYMBOL_GPL vmlinux 0xa4505c2f ata_port_disable +EXPORT_SYMBOL_GPL vmlinux 0xa452c297 hpet_mask_rtc_irq_bit +EXPORT_SYMBOL_GPL vmlinux 0xa4667c45 queue_work_on +EXPORT_SYMBOL_GPL vmlinux 0xa4792069 dm_rh_flush +EXPORT_SYMBOL_GPL vmlinux 0xa4857100 bus_find_device +EXPORT_SYMBOL_GPL vmlinux 0xa4b83be0 vfs_removexattr +EXPORT_SYMBOL_GPL vmlinux 0xa50dca92 regulator_bulk_enable +EXPORT_SYMBOL_GPL vmlinux 0xa539eb08 dm_path_uevent +EXPORT_SYMBOL_GPL vmlinux 0xa56e2152 inet_csk_listen_stop +EXPORT_SYMBOL_GPL vmlinux 0xa5bf5c3e pm_qos_add_requirement +EXPORT_SYMBOL_GPL vmlinux 0xa5c36cec inotify_unmount_inodes +EXPORT_SYMBOL_GPL vmlinux 0xa5f1173a __blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0xa5fc8172 seq_open_net +EXPORT_SYMBOL_GPL vmlinux 0xa63f3c23 ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0xa64ccd3d pv_apic_ops +EXPORT_SYMBOL_GPL vmlinux 0xa6b940ae pci_block_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0xa6f4320d unregister_rfkill_notifier +EXPORT_SYMBOL_GPL vmlinux 0xa789e515 sysdev_show_int +EXPORT_SYMBOL_GPL vmlinux 0xa78a073b sysdev_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xa7e4734f put_driver +EXPORT_SYMBOL_GPL vmlinux 0xa80f4003 securityfs_remove +EXPORT_SYMBOL_GPL vmlinux 0xa80fcdb7 sysdev_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0xa8305e11 device_rename +EXPORT_SYMBOL_GPL vmlinux 0xa87326b4 tcp_init_congestion_ops +EXPORT_SYMBOL_GPL vmlinux 0xa8f3834e __inet_lookup_established +EXPORT_SYMBOL_GPL vmlinux 0xa8f59416 gpio_direction_output +EXPORT_SYMBOL_GPL vmlinux 0xa8fb5903 uart_set_options +EXPORT_SYMBOL_GPL vmlinux 0xa9126bff hpet_set_rtc_irq_bit +EXPORT_SYMBOL_GPL vmlinux 0xa92122da securityfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0xa956a362 register_jprobe +EXPORT_SYMBOL_GPL vmlinux 0xa963f49c tcp_orphan_count +EXPORT_SYMBOL_GPL vmlinux 0xa986f846 tty_find_polling_driver +EXPORT_SYMBOL_GPL vmlinux 0xa9b7afd8 wmi_set_block +EXPORT_SYMBOL_GPL vmlinux 0xa9c530b8 unregister_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xaa2a72bf __iowrite64_copy +EXPORT_SYMBOL_GPL vmlinux 0xaa4c2bb5 ata_std_postreset +EXPORT_SYMBOL_GPL vmlinux 0xaa668d67 uhci_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0xaa73dcba dm_send_uevents +EXPORT_SYMBOL_GPL vmlinux 0xaa8c4696 cpu_clock +EXPORT_SYMBOL_GPL vmlinux 0xaa9e5380 sdio_disable_func +EXPORT_SYMBOL_GPL vmlinux 0xaae449f7 simple_attr_open +EXPORT_SYMBOL_GPL vmlinux 0xaaff1cb1 __mnt_is_readonly +EXPORT_SYMBOL_GPL vmlinux 0xab206121 crypto_register_template +EXPORT_SYMBOL_GPL vmlinux 0xab55efa4 tty_buffer_request_room +EXPORT_SYMBOL_GPL vmlinux 0xab57e311 tracepoint_probe_register +EXPORT_SYMBOL_GPL vmlinux 0xac0292be blocking_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0xac2058ad crypto_enqueue_request +EXPORT_SYMBOL_GPL vmlinux 0xac48984f ata_port_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0xac5ae2c6 platform_device_add +EXPORT_SYMBOL_GPL vmlinux 0xac9e08d7 ata_pci_device_do_resume +EXPORT_SYMBOL_GPL vmlinux 0xacb301a6 class_find_device +EXPORT_SYMBOL_GPL vmlinux 0xacc19485 ibft_addr +EXPORT_SYMBOL_GPL vmlinux 0xaccfc678 cpu_bit_bitmap +EXPORT_SYMBOL_GPL vmlinux 0xace5c0fc usb_bus_list +EXPORT_SYMBOL_GPL vmlinux 0xacecf702 ata_slave_link_init +EXPORT_SYMBOL_GPL vmlinux 0xad9ebad8 vfs_setlease +EXPORT_SYMBOL_GPL vmlinux 0xae0c87ee pm_qos_remove_notifier +EXPORT_SYMBOL_GPL vmlinux 0xae0dbaa2 scsi_mode_select +EXPORT_SYMBOL_GPL vmlinux 0xae45356a sysdev_store_int +EXPORT_SYMBOL_GPL vmlinux 0xae495b14 vfs_getxattr +EXPORT_SYMBOL_GPL vmlinux 0xae50147a ata_link_abort +EXPORT_SYMBOL_GPL vmlinux 0xae66b19d hvc_instantiate +EXPORT_SYMBOL_GPL vmlinux 0xaeb7f977 __blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xaed913c7 aead_geniv_free +EXPORT_SYMBOL_GPL vmlinux 0xaf14f80d __rt_mutex_init +EXPORT_SYMBOL_GPL vmlinux 0xaf2d64b6 ata_sff_pause +EXPORT_SYMBOL_GPL vmlinux 0xafc7c996 usb_unlink_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xb0290245 dm_unregister_path_selector +EXPORT_SYMBOL_GPL vmlinux 0xb04c04bd ipv6_opt_accepted +EXPORT_SYMBOL_GPL vmlinux 0xb09a9ee8 iomap_atomic_prot_pfn +EXPORT_SYMBOL_GPL vmlinux 0xb0aa812e fips_enabled +EXPORT_SYMBOL_GPL vmlinux 0xb0ab9f8c flush_work +EXPORT_SYMBOL_GPL vmlinux 0xb0bbac35 platform_get_irq +EXPORT_SYMBOL_GPL vmlinux 0xb0c5c8dc i2c_new_device +EXPORT_SYMBOL_GPL vmlinux 0xb0e6259b device_bind_driver +EXPORT_SYMBOL_GPL vmlinux 0xb0eedea9 usb_wait_anchor_empty_timeout +EXPORT_SYMBOL_GPL vmlinux 0xb0f27411 ata_sff_check_status +EXPORT_SYMBOL_GPL vmlinux 0xb10d55bc cn_netlink_send +EXPORT_SYMBOL_GPL vmlinux 0xb1226d11 pci_disable_pcie_error_reporting +EXPORT_SYMBOL_GPL vmlinux 0xb12794a8 class_interface_register +EXPORT_SYMBOL_GPL vmlinux 0xb13f3000 ata_std_error_handler +EXPORT_SYMBOL_GPL vmlinux 0xb14ab568 blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0xb19d24fa ip_build_and_send_pkt +EXPORT_SYMBOL_GPL vmlinux 0xb1a3cca3 sdio_claim_irq +EXPORT_SYMBOL_GPL vmlinux 0xb1acbcce rcu_barrier_sched +EXPORT_SYMBOL_GPL vmlinux 0xb1b69ded disk_map_sector_rcu +EXPORT_SYMBOL_GPL vmlinux 0xb236aab6 elv_register +EXPORT_SYMBOL_GPL vmlinux 0xb26c085a pci_set_pcie_reset_state +EXPORT_SYMBOL_GPL vmlinux 0xb27005f5 device_suspend +EXPORT_SYMBOL_GPL vmlinux 0xb285066c hidraw_report_event +EXPORT_SYMBOL_GPL vmlinux 0xb2da3557 regulator_set_voltage +EXPORT_SYMBOL_GPL vmlinux 0xb2deabb2 sg_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xb2eb757f single_open_net +EXPORT_SYMBOL_GPL vmlinux 0xb30c8997 rtc_irq_unregister +EXPORT_SYMBOL_GPL vmlinux 0xb313a59e unregister_kprobe +EXPORT_SYMBOL_GPL vmlinux 0xb3253ed9 hpet_rtc_timer_init +EXPORT_SYMBOL_GPL vmlinux 0xb34d9e83 inet_hash +EXPORT_SYMBOL_GPL vmlinux 0xb370ef30 relay_close +EXPORT_SYMBOL_GPL vmlinux 0xb37d7544 class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xb38e82ef sdio_writel +EXPORT_SYMBOL_GPL vmlinux 0xb3d5e527 acpi_smbus_write +EXPORT_SYMBOL_GPL vmlinux 0xb3d63c60 da903x_read +EXPORT_SYMBOL_GPL vmlinux 0xb41cb079 mm_kobj +EXPORT_SYMBOL_GPL vmlinux 0xb461630c da903x_write +EXPORT_SYMBOL_GPL vmlinux 0xb469ce67 crypto_alg_mod_lookup +EXPORT_SYMBOL_GPL vmlinux 0xb476fbc1 cpufreq_frequency_table_cpuinfo +EXPORT_SYMBOL_GPL vmlinux 0xb48b9c9d crypto_tfm_in_queue +EXPORT_SYMBOL_GPL vmlinux 0xb4e6fe72 usb_poison_urb +EXPORT_SYMBOL_GPL vmlinux 0xb4ea7cf7 kgdb_connected +EXPORT_SYMBOL_GPL vmlinux 0xb51fbd64 edac_op_state +EXPORT_SYMBOL_GPL vmlinux 0xb53ae573 cpu_idle_wait +EXPORT_SYMBOL_GPL vmlinux 0xb53cd806 ata_pci_device_resume +EXPORT_SYMBOL_GPL vmlinux 0xb59cd04c da903x_set_bits +EXPORT_SYMBOL_GPL vmlinux 0xb5a6ebe2 wmi_remove_notify_handler +EXPORT_SYMBOL_GPL vmlinux 0xb5c7caba inet_diag_register +EXPORT_SYMBOL_GPL vmlinux 0xb63550f5 __i2c_board_lock +EXPORT_SYMBOL_GPL vmlinux 0xb65091b3 selinux_secmark_refcount_dec +EXPORT_SYMBOL_GPL vmlinux 0xb668cd0f inet_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0xb693f7ae preempt_notifier_unregister +EXPORT_SYMBOL_GPL vmlinux 0xb6aeb661 ata_id_c_string +EXPORT_SYMBOL_GPL vmlinux 0xb6d12048 alloc_page_buffers +EXPORT_SYMBOL_GPL vmlinux 0xb71032d4 __create_workqueue_key +EXPORT_SYMBOL_GPL vmlinux 0xb7425e4b ata_sff_data_xfer_noirq +EXPORT_SYMBOL_GPL vmlinux 0xb79d4923 ata_sff_irq_on +EXPORT_SYMBOL_GPL vmlinux 0xb7ba6928 driver_create_file +EXPORT_SYMBOL_GPL vmlinux 0xb7bb4fb1 tcp_reno_ssthresh +EXPORT_SYMBOL_GPL vmlinux 0xb7d7c12e hpet_set_alarm_time +EXPORT_SYMBOL_GPL vmlinux 0xb822c3a6 sdio_claim_host +EXPORT_SYMBOL_GPL vmlinux 0xb8624d01 ata_dummy_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xb8a1e39d inet_csk_get_port +EXPORT_SYMBOL_GPL vmlinux 0xb955f19f blk_end_bidi_request +EXPORT_SYMBOL_GPL vmlinux 0xb97dfc4e kobject_uevent_env +EXPORT_SYMBOL_GPL vmlinux 0xb9b95b95 inet6_lookup +EXPORT_SYMBOL_GPL vmlinux 0xb9eb3aa9 add_uevent_var +EXPORT_SYMBOL_GPL vmlinux 0xb9fed9b0 regulator_get_init_drvdata +EXPORT_SYMBOL_GPL vmlinux 0xba164f47 scsi_internal_device_block +EXPORT_SYMBOL_GPL vmlinux 0xba17258b __crypto_alloc_tfm +EXPORT_SYMBOL_GPL vmlinux 0xba356aa7 devres_alloc +EXPORT_SYMBOL_GPL vmlinux 0xba46e07b scsi_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0xba539feb regulator_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0xba600639 xfrm_audit_policy_delete +EXPORT_SYMBOL_GPL vmlinux 0xba698916 __percpu_alloc_mask +EXPORT_SYMBOL_GPL vmlinux 0xbaa219a7 sysfs_get_dirent +EXPORT_SYMBOL_GPL vmlinux 0xbae34c27 scsi_nl_remove_transport +EXPORT_SYMBOL_GPL vmlinux 0xbb08f210 k_handler +EXPORT_SYMBOL_GPL vmlinux 0xbb0b9ae7 get_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0xbb113eca pciserial_suspend_ports +EXPORT_SYMBOL_GPL vmlinux 0xbba7cc86 input_ff_create +EXPORT_SYMBOL_GPL vmlinux 0xbbb8517c hid_connect +EXPORT_SYMBOL_GPL vmlinux 0xbbb98859 edid_info +EXPORT_SYMBOL_GPL vmlinux 0xbbd4b518 hid_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0xbbfcd9cf usb_serial_port_softint +EXPORT_SYMBOL_GPL vmlinux 0xbc2648cc anon_inode_getfd +EXPORT_SYMBOL_GPL vmlinux 0xbc9a4533 led_trigger_event +EXPORT_SYMBOL_GPL vmlinux 0xbccd92c8 skb_partial_csum_set +EXPORT_SYMBOL_GPL vmlinux 0xbcd8e07a tty_ldisc_flush +EXPORT_SYMBOL_GPL vmlinux 0xbd506a46 unregister_hotplug_dock_device +EXPORT_SYMBOL_GPL vmlinux 0xbd8b72f4 d_obtain_alias +EXPORT_SYMBOL_GPL vmlinux 0xbd8f9e1f usb_reset_configuration +EXPORT_SYMBOL_GPL vmlinux 0xbdcce1b1 register_kprobe +EXPORT_SYMBOL_GPL vmlinux 0xbdd295f0 trace_vprintk +EXPORT_SYMBOL_GPL vmlinux 0xbe0a5350 pci_hp_deregister +EXPORT_SYMBOL_GPL vmlinux 0xbe16708c blk_rq_check_limits +EXPORT_SYMBOL_GPL vmlinux 0xbe1887e4 ata_unpack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xbe413599 tracepoint_iter_start +EXPORT_SYMBOL_GPL vmlinux 0xbe579305 inet6_destroy_sock +EXPORT_SYMBOL_GPL vmlinux 0xbe8e6306 md_do_sync +EXPORT_SYMBOL_GPL vmlinux 0xbeedc61f skb_pull_rcsum +EXPORT_SYMBOL_GPL vmlinux 0xbfa415bc spi_unregister_master +EXPORT_SYMBOL_GPL vmlinux 0xbfb064c2 dm_device_name +EXPORT_SYMBOL_GPL vmlinux 0xbfd4da78 transport_setup_device +EXPORT_SYMBOL_GPL vmlinux 0xbff02bdb ata_sas_port_init +EXPORT_SYMBOL_GPL vmlinux 0xc053e27f raw_hash_sk +EXPORT_SYMBOL_GPL vmlinux 0xc06756af usb_hcd_pci_shutdown +EXPORT_SYMBOL_GPL vmlinux 0xc104075e inet_diag_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc1193db9 attribute_container_find_class_device +EXPORT_SYMBOL_GPL vmlinux 0xc17515d7 usb_hcds_loaded +EXPORT_SYMBOL_GPL vmlinux 0xc17ab07c tty_prepare_flip_string_flags +EXPORT_SYMBOL_GPL vmlinux 0xc180dce2 sdio_align_size +EXPORT_SYMBOL_GPL vmlinux 0xc1a8556c crypto_alloc_instance +EXPORT_SYMBOL_GPL vmlinux 0xc1b9670d leds_list_lock +EXPORT_SYMBOL_GPL vmlinux 0xc200cf96 seq_release_net +EXPORT_SYMBOL_GPL vmlinux 0xc22a3091 vm_unmap_aliases +EXPORT_SYMBOL_GPL vmlinux 0xc279e2f7 ata_acpi_cbl_80wire +EXPORT_SYMBOL_GPL vmlinux 0xc2bdcdb0 ata_eh_analyze_ncq_error +EXPORT_SYMBOL_GPL vmlinux 0xc2c54ea7 ata_std_prereset +EXPORT_SYMBOL_GPL vmlinux 0xc3150e13 find_get_pid +EXPORT_SYMBOL_GPL vmlinux 0xc34efe27 snmp_fold_field +EXPORT_SYMBOL_GPL vmlinux 0xc35229c1 ata_pci_bmdma_init +EXPORT_SYMBOL_GPL vmlinux 0xc364cbd7 kobject_init_and_add +EXPORT_SYMBOL_GPL vmlinux 0xc399468f scsi_nl_remove_driver +EXPORT_SYMBOL_GPL vmlinux 0xc3a39467 ata_sff_prereset +EXPORT_SYMBOL_GPL vmlinux 0xc428068d sata_deb_timing_long +EXPORT_SYMBOL_GPL vmlinux 0xc48b7ccf ata_mode_string +EXPORT_SYMBOL_GPL vmlinux 0xc4b33aa6 tracepoint_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc4c552d7 stop_machine +EXPORT_SYMBOL_GPL vmlinux 0xc4eacbe9 ata_bus_reset +EXPORT_SYMBOL_GPL vmlinux 0xc512626a __supported_pte_mask +EXPORT_SYMBOL_GPL vmlinux 0xc532b91c rtc_class_open +EXPORT_SYMBOL_GPL vmlinux 0xc537b9b6 sysfs_add_file_to_group +EXPORT_SYMBOL_GPL vmlinux 0xc564144a crypto_mod_get +EXPORT_SYMBOL_GPL vmlinux 0xc57e8c8b dm_rh_stop_recovery +EXPORT_SYMBOL_GPL vmlinux 0xc58cdb60 lookup_address +EXPORT_SYMBOL_GPL vmlinux 0xc5b83f66 devres_remove_group +EXPORT_SYMBOL_GPL vmlinux 0xc5e3dddf wmi_get_event_data +EXPORT_SYMBOL_GPL vmlinux 0xc63f43c7 spi_write_then_read +EXPORT_SYMBOL_GPL vmlinux 0xc65288d9 single_release_net +EXPORT_SYMBOL_GPL vmlinux 0xc672b154 mmu_notifier_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc6730fc2 klist_iter_init +EXPORT_SYMBOL_GPL vmlinux 0xc673e23e ata_scsi_change_queue_depth +EXPORT_SYMBOL_GPL vmlinux 0xc6d33851 inverse_translate +EXPORT_SYMBOL_GPL vmlinux 0xc6d4e72c debugfs_create_x8 +EXPORT_SYMBOL_GPL vmlinux 0xc73a06c9 ata_sff_qc_issue +EXPORT_SYMBOL_GPL vmlinux 0xc7504484 tracepoint_get_iter_range +EXPORT_SYMBOL_GPL vmlinux 0xc751c582 spi_add_device +EXPORT_SYMBOL_GPL vmlinux 0xc75ca24f ip_local_out +EXPORT_SYMBOL_GPL vmlinux 0xc78b232d dm_rh_get_state +EXPORT_SYMBOL_GPL vmlinux 0xc7ec11f6 atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xc8654f08 get_cpu_sysdev +EXPORT_SYMBOL_GPL vmlinux 0xc87b1609 fib_rules_lookup +EXPORT_SYMBOL_GPL vmlinux 0xc87c1f84 ktime_get +EXPORT_SYMBOL_GPL vmlinux 0xc87e487a sched_clock_idle_sleep_event +EXPORT_SYMBOL_GPL vmlinux 0xc9561772 fb_destroy_modelist +EXPORT_SYMBOL_GPL vmlinux 0xc9d4b474 __pneigh_lookup +EXPORT_SYMBOL_GPL vmlinux 0xc9d4d6d1 wmi_has_guid +EXPORT_SYMBOL_GPL vmlinux 0xc9dd32d8 regulator_force_disable +EXPORT_SYMBOL_GPL vmlinux 0xc9e37865 isa_register_driver +EXPORT_SYMBOL_GPL vmlinux 0xca354dc6 pci_cleanup_aer_uncorrect_error_status +EXPORT_SYMBOL_GPL vmlinux 0xca874e7f raw_seq_start +EXPORT_SYMBOL_GPL vmlinux 0xca8c181f inotify_init_watch +EXPORT_SYMBOL_GPL vmlinux 0xcabe04de cpuidle_resume_and_unlock +EXPORT_SYMBOL_GPL vmlinux 0xcb28ed86 sdio_writew +EXPORT_SYMBOL_GPL vmlinux 0xcb53195c simple_attr_release +EXPORT_SYMBOL_GPL vmlinux 0xcb544a3a regulator_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xcb7196b0 sata_link_debounce +EXPORT_SYMBOL_GPL vmlinux 0xcb774621 crypto_alloc_ablkcipher +EXPORT_SYMBOL_GPL vmlinux 0xcb8c118d cpufreq_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0xcbf06015 hid_output_report +EXPORT_SYMBOL_GPL vmlinux 0xcc1f1c3d inet_twdr_hangman +EXPORT_SYMBOL_GPL vmlinux 0xcc2c5085 register_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0xcc4071d4 crypto_alg_lookup +EXPORT_SYMBOL_GPL vmlinux 0xcc56ce06 sdev_evt_send_simple +EXPORT_SYMBOL_GPL vmlinux 0xcc6ab305 is_dock_device +EXPORT_SYMBOL_GPL vmlinux 0xcccaa5f2 debugfs_create_u8 +EXPORT_SYMBOL_GPL vmlinux 0xcccfb2fa sata_deb_timing_hotplug +EXPORT_SYMBOL_GPL vmlinux 0xcd9991a9 usb_usual_set_present +EXPORT_SYMBOL_GPL vmlinux 0xcd9b8531 rt_mutex_timed_lock +EXPORT_SYMBOL_GPL vmlinux 0xcdca3691 nr_irqs +EXPORT_SYMBOL_GPL vmlinux 0xcdd6550e register_kprobes +EXPORT_SYMBOL_GPL vmlinux 0xce4aa154 bus_sort_breadthfirst +EXPORT_SYMBOL_GPL vmlinux 0xce608d6f xfrm_inner_extract_output +EXPORT_SYMBOL_GPL vmlinux 0xceb06d36 device_register +EXPORT_SYMBOL_GPL vmlinux 0xcee44482 sysdev_store_ulong +EXPORT_SYMBOL_GPL vmlinux 0xcf00f826 xfrm_audit_state_notfound_simple +EXPORT_SYMBOL_GPL vmlinux 0xcf0bfd12 start_thread +EXPORT_SYMBOL_GPL vmlinux 0xcf82bff5 power_supply_class +EXPORT_SYMBOL_GPL vmlinux 0xcfc5e7be blk_queue_rq_timed_out +EXPORT_SYMBOL_GPL vmlinux 0xcfcc83ad register_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0xd027a07d marker_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xd03a483f ata_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0xd03c7700 secure_ipv4_port_ephemeral +EXPORT_SYMBOL_GPL vmlinux 0xd0bbd670 ata_port_start +EXPORT_SYMBOL_GPL vmlinux 0xd0c05159 emergency_restart +EXPORT_SYMBOL_GPL vmlinux 0xd0d342a1 smp_ops +EXPORT_SYMBOL_GPL vmlinux 0xd0de4e51 device_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xd12ac59b olpc_ec_cmd +EXPORT_SYMBOL_GPL vmlinux 0xd15b1b15 bdi_writeout_inc +EXPORT_SYMBOL_GPL vmlinux 0xd15cfce9 invalidate_inode_pages2_range +EXPORT_SYMBOL_GPL vmlinux 0xd16712f3 crypto_check_attr_type +EXPORT_SYMBOL_GPL vmlinux 0xd183fdd6 inet_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0xd1b90119 skcipher_geniv_init +EXPORT_SYMBOL_GPL vmlinux 0xd2038761 hidinput_report_event +EXPORT_SYMBOL_GPL vmlinux 0xd231fc93 relay_subbufs_consumed +EXPORT_SYMBOL_GPL vmlinux 0xd24da1cb transport_add_device +EXPORT_SYMBOL_GPL vmlinux 0xd25cc89f input_class +EXPORT_SYMBOL_GPL vmlinux 0xd273b1b1 __round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xd27d2d95 kobject_rename +EXPORT_SYMBOL_GPL vmlinux 0xd2839371 sdio_enable_func +EXPORT_SYMBOL_GPL vmlinux 0xd2a8caf0 work_on_cpu +EXPORT_SYMBOL_GPL vmlinux 0xd2e1c506 regulator_set_optimum_mode +EXPORT_SYMBOL_GPL vmlinux 0xd2ebc7fb ata_sff_freeze +EXPORT_SYMBOL_GPL vmlinux 0xd330cf33 ata_do_dev_read_id +EXPORT_SYMBOL_GPL vmlinux 0xd336a9a8 tty_put_char +EXPORT_SYMBOL_GPL vmlinux 0xd33dd4c4 dm_rh_get_region_size +EXPORT_SYMBOL_GPL vmlinux 0xd35c07a9 elv_unregister +EXPORT_SYMBOL_GPL vmlinux 0xd3b4d9d3 sysfs_get +EXPORT_SYMBOL_GPL vmlinux 0xd3e47be1 ata_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0xd4605677 devres_add +EXPORT_SYMBOL_GPL vmlinux 0xd4794797 __blk_put_request +EXPORT_SYMBOL_GPL vmlinux 0xd494ee54 speedstep_get_freqs +EXPORT_SYMBOL_GPL vmlinux 0xd55ce3e0 usb_altnum_to_altsetting +EXPORT_SYMBOL_GPL vmlinux 0xd57d4e70 sdio_readw +EXPORT_SYMBOL_GPL vmlinux 0xd594407e regulator_put +EXPORT_SYMBOL_GPL vmlinux 0xd5b7f54d sis_info133_for_sata +EXPORT_SYMBOL_GPL vmlinux 0xd680e49c device_reprobe +EXPORT_SYMBOL_GPL vmlinux 0xd691214c relay_switch_subbuf +EXPORT_SYMBOL_GPL vmlinux 0xd69e72ca fixed_phy_set_link_update +EXPORT_SYMBOL_GPL vmlinux 0xd6eb74a7 led_trigger_register_simple +EXPORT_SYMBOL_GPL vmlinux 0xd76fe17a inotify_rm_wd +EXPORT_SYMBOL_GPL vmlinux 0xd79e81df dm_rh_region_to_sector +EXPORT_SYMBOL_GPL vmlinux 0xd7b54b93 dm_rh_recovery_in_flight +EXPORT_SYMBOL_GPL vmlinux 0xd7d79132 put_online_cpus +EXPORT_SYMBOL_GPL vmlinux 0xd83242e6 sysfs_remove_group +EXPORT_SYMBOL_GPL vmlinux 0xd84cd7f4 ata_timing_find_mode +EXPORT_SYMBOL_GPL vmlinux 0xd88ffb45 ata_pci_sff_activate_host +EXPORT_SYMBOL_GPL vmlinux 0xd8eaae05 tty_mode_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xd951a804 sysdev_class_create_file +EXPORT_SYMBOL_GPL vmlinux 0xd98f8004 usb_autopm_get_interface +EXPORT_SYMBOL_GPL vmlinux 0xd9f73a4c ata_host_start +EXPORT_SYMBOL_GPL vmlinux 0xda0bf1d0 sysctl_pathname +EXPORT_SYMBOL_GPL vmlinux 0xda2ffb60 platform_device_register_simple +EXPORT_SYMBOL_GPL vmlinux 0xda9a27d1 led_trigger_unregister_simple +EXPORT_SYMBOL_GPL vmlinux 0xdacf9a69 dm_rh_dec +EXPORT_SYMBOL_GPL vmlinux 0xdaf4dfb3 fb_mode_option +EXPORT_SYMBOL_GPL vmlinux 0xdb269c8b pci_stop_bus_device +EXPORT_SYMBOL_GPL vmlinux 0xdbb71ecc usb_hcd_pci_resume +EXPORT_SYMBOL_GPL vmlinux 0xdc579146 crypto_hash_walk_done +EXPORT_SYMBOL_GPL vmlinux 0xdc5b488d register_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0xdc77327d ata_port_freeze +EXPORT_SYMBOL_GPL vmlinux 0xdcb4b97c usb_sg_cancel +EXPORT_SYMBOL_GPL vmlinux 0xdd41dceb inet6_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0xdd5c4942 srcu_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0xdd8ba2f2 usb_store_new_id +EXPORT_SYMBOL_GPL vmlinux 0xddaec9a3 regulator_unregister +EXPORT_SYMBOL_GPL vmlinux 0xddcd9c99 debugfs_create_x32 +EXPORT_SYMBOL_GPL vmlinux 0xddd8b5e9 attribute_container_unregister +EXPORT_SYMBOL_GPL vmlinux 0xddf87039 sata_scr_read +EXPORT_SYMBOL_GPL vmlinux 0xde013bee proc_net_mkdir +EXPORT_SYMBOL_GPL vmlinux 0xde134c69 storage_usb_ids +EXPORT_SYMBOL_GPL vmlinux 0xde4b43b3 spi_alloc_device +EXPORT_SYMBOL_GPL vmlinux 0xde7f8b30 platform_get_irq_byname +EXPORT_SYMBOL_GPL vmlinux 0xdeac8f7e ata_scsi_simulate +EXPORT_SYMBOL_GPL vmlinux 0xdf08b8d0 do_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0xdf3022b2 ata_sff_interrupt +EXPORT_SYMBOL_GPL vmlinux 0xdf3c19ec cn_add_callback +EXPORT_SYMBOL_GPL vmlinux 0xdf5c43e7 regulator_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0xdfceba91 regulator_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0xdfec82f6 save_stack_trace_tsk +EXPORT_SYMBOL_GPL vmlinux 0xdffaa1db spi_sync +EXPORT_SYMBOL_GPL vmlinux 0xe0406b5a blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xe06812b4 ata_noop_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0xe0f4e243 ipv6_dup_options +EXPORT_SYMBOL_GPL vmlinux 0xe148c7dc sdio_memcpy_fromio +EXPORT_SYMBOL_GPL vmlinux 0xe1c813d9 led_trigger_set +EXPORT_SYMBOL_GPL vmlinux 0xe1c892cf fb_deferred_io_open +EXPORT_SYMBOL_GPL vmlinux 0xe2426710 wmi_evaluate_method +EXPORT_SYMBOL_GPL vmlinux 0xe295c0ff is_hpet_enabled +EXPORT_SYMBOL_GPL vmlinux 0xe2cd2e26 exit_fs +EXPORT_SYMBOL_GPL vmlinux 0xe351f1bc usb_serial_generic_open +EXPORT_SYMBOL_GPL vmlinux 0xe3562661 usb_free_urb +EXPORT_SYMBOL_GPL vmlinux 0xe3846ed1 kset_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0xe46cc4fb ata_eh_freeze_port +EXPORT_SYMBOL_GPL vmlinux 0xe48d5eac acpi_ec_add_query_handler +EXPORT_SYMBOL_GPL vmlinux 0xe49ff3b0 ata_wait_register +EXPORT_SYMBOL_GPL vmlinux 0xe4c331b6 acpi_os_unmap_memory +EXPORT_SYMBOL_GPL vmlinux 0xe4d18217 register_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0xe4da633b platform_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xe513afc0 cache_k8_northbridges +EXPORT_SYMBOL_GPL vmlinux 0xe529fae8 scsi_nl_add_transport +EXPORT_SYMBOL_GPL vmlinux 0xe530071c pm_qos_remove_requirement +EXPORT_SYMBOL_GPL vmlinux 0xe5641b1a unregister_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0xe57967cb skcipher_geniv_exit +EXPORT_SYMBOL_GPL vmlinux 0xe5f2ec13 ata_acpi_gtm +EXPORT_SYMBOL_GPL vmlinux 0xe61a6d2f gpio_unexport +EXPORT_SYMBOL_GPL vmlinux 0xe6488b47 cpufreq_notify_transition +EXPORT_SYMBOL_GPL vmlinux 0xe674a5cb srcu_read_lock +EXPORT_SYMBOL_GPL vmlinux 0xe67ab8c2 securityfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0xe7a6e174 kobject_get_path +EXPORT_SYMBOL_GPL vmlinux 0xe7c55dc4 fnotify_change +EXPORT_SYMBOL_GPL vmlinux 0xe7f1f3fd i2c_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xe7f45316 fb_deferred_io_fsync +EXPORT_SYMBOL_GPL vmlinux 0xe7fa47ad srcu_read_unlock +EXPORT_SYMBOL_GPL vmlinux 0xe81d1bd8 pciserial_remove_ports +EXPORT_SYMBOL_GPL vmlinux 0xe84dc69c rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0xe8c40509 rdev_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0xe8df0db7 lookup_instantiate_filp +EXPORT_SYMBOL_GPL vmlinux 0xe939d558 usb_unpoison_urb +EXPORT_SYMBOL_GPL vmlinux 0xe93e49c3 devres_free +EXPORT_SYMBOL_GPL vmlinux 0xe9587909 usb_unregister_notify +EXPORT_SYMBOL_GPL vmlinux 0xe971d29a ata_cable_unknown +EXPORT_SYMBOL_GPL vmlinux 0xe9f032ff skb_to_sgvec +EXPORT_SYMBOL_GPL vmlinux 0xea065e01 task_handoff_unregister +EXPORT_SYMBOL_GPL vmlinux 0xea18c44f cpci_hp_register_bus +EXPORT_SYMBOL_GPL vmlinux 0xea418e0f atapi_cmd_type +EXPORT_SYMBOL_GPL vmlinux 0xea503d01 bus_for_each_drv +EXPORT_SYMBOL_GPL vmlinux 0xea8c86b7 crypto_grab_skcipher +EXPORT_SYMBOL_GPL vmlinux 0xeae74760 scsi_nl_send_transport_msg +EXPORT_SYMBOL_GPL vmlinux 0xeb0c093f inet6_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0xec1ac813 put_pid +EXPORT_SYMBOL_GPL vmlinux 0xec1b043e regulator_suspend_prepare +EXPORT_SYMBOL_GPL vmlinux 0xec9024e4 unregister_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0xecce638e hwmon_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xecd9e2e7 usb_anchor_urb +EXPORT_SYMBOL_GPL vmlinux 0xed2e4930 tty_wakeup +EXPORT_SYMBOL_GPL vmlinux 0xed3d59fe dm_set_device_limits +EXPORT_SYMBOL_GPL vmlinux 0xed794eee tcp_is_cwnd_limited +EXPORT_SYMBOL_GPL vmlinux 0xedb1488e hid_parse_report +EXPORT_SYMBOL_GPL vmlinux 0xedd96a7e shmem_file_setup +EXPORT_SYMBOL_GPL vmlinux 0xee30c74e usb_hcd_platform_shutdown +EXPORT_SYMBOL_GPL vmlinux 0xeeb930ca pci_test_config_bits +EXPORT_SYMBOL_GPL vmlinux 0xeecc5cc0 pcie_port_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xeeeb7523 regulator_bulk_get +EXPORT_SYMBOL_GPL vmlinux 0xeef77484 platform_device_add_resources +EXPORT_SYMBOL_GPL vmlinux 0xef184e8c i2c_new_dummy +EXPORT_SYMBOL_GPL vmlinux 0xef1e2bf3 user_read +EXPORT_SYMBOL_GPL vmlinux 0xef3bfb89 ip6_sk_dst_lookup +EXPORT_SYMBOL_GPL vmlinux 0xef511be3 ata_sff_tf_load +EXPORT_SYMBOL_GPL vmlinux 0xef55e66e ata_do_set_mode +EXPORT_SYMBOL_GPL vmlinux 0xef6c3f70 round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xefd099aa cpuidle_unregister_device +EXPORT_SYMBOL_GPL vmlinux 0xefe0cab3 __class_create +EXPORT_SYMBOL_GPL vmlinux 0xefe21106 snmp_mib_init +EXPORT_SYMBOL_GPL vmlinux 0xf0054c72 mmput +EXPORT_SYMBOL_GPL vmlinux 0xf0a7c66e device_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xf0b20e3e user_match +EXPORT_SYMBOL_GPL vmlinux 0xf0cbfbc2 xfrm_output +EXPORT_SYMBOL_GPL vmlinux 0xf0d831e4 scsi_flush_work +EXPORT_SYMBOL_GPL vmlinux 0xf15ceed7 i2c_add_numbered_adapter +EXPORT_SYMBOL_GPL vmlinux 0xf184d189 kernel_power_off +EXPORT_SYMBOL_GPL vmlinux 0xf1ee5814 vfs_cancel_lock +EXPORT_SYMBOL_GPL vmlinux 0xf222d91a ata_bmdma_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xf22a27ce __rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0xf27156f5 tty_perform_flush +EXPORT_SYMBOL_GPL vmlinux 0xf2fca922 uart_parse_options +EXPORT_SYMBOL_GPL vmlinux 0xf32994e2 register_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0xf3378a4a crypto_alloc_base +EXPORT_SYMBOL_GPL vmlinux 0xf340d476 queue_delayed_work +EXPORT_SYMBOL_GPL vmlinux 0xf39e13bc bus_for_each_dev +EXPORT_SYMBOL_GPL vmlinux 0xf3a640d1 blk_queue_dma_drain +EXPORT_SYMBOL_GPL vmlinux 0xf3d524fd sysfs_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xf3d5cc13 ata_timing_merge +EXPORT_SYMBOL_GPL vmlinux 0xf41d7383 generic_fh_to_parent +EXPORT_SYMBOL_GPL vmlinux 0xf4487223 __audit_inode_child +EXPORT_SYMBOL_GPL vmlinux 0xf453fae5 cpuidle_register_driver +EXPORT_SYMBOL_GPL vmlinux 0xf467c8d5 rtc_read_time +EXPORT_SYMBOL_GPL vmlinux 0xf4794546 inotify_dentry_parent_queue_event +EXPORT_SYMBOL_GPL vmlinux 0xf4961df9 __ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0xf499fdb2 rcu_barrier_bh +EXPORT_SYMBOL_GPL vmlinux 0xf4b2e27d inet_csk_reqsk_queue_prune +EXPORT_SYMBOL_GPL vmlinux 0xf4d5028c vfs_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0xf52c3e02 devm_kfree +EXPORT_SYMBOL_GPL vmlinux 0xf54423c4 usb_deregister_device_driver +EXPORT_SYMBOL_GPL vmlinux 0xf553318d cpuidle_pause_and_lock +EXPORT_SYMBOL_GPL vmlinux 0xf5a5ee70 platform_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xf5a691cd invalidate_bh_lrus +EXPORT_SYMBOL_GPL vmlinux 0xf5a86513 key_type_user +EXPORT_SYMBOL_GPL vmlinux 0xf5b54370 sdio_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0xf5d0fd39 mnt_want_write +EXPORT_SYMBOL_GPL vmlinux 0xf5d2eb19 class_dev_iter_init +EXPORT_SYMBOL_GPL vmlinux 0xf5df06c1 __class_register +EXPORT_SYMBOL_GPL vmlinux 0xf5ec7448 sysdev_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf5fc6d69 usb_string +EXPORT_SYMBOL_GPL vmlinux 0xf65b9513 sysdev_class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xf68d3da1 ata_port_pbar_desc +EXPORT_SYMBOL_GPL vmlinux 0xf696f1f3 pciserial_resume_ports +EXPORT_SYMBOL_GPL vmlinux 0xf69cef98 usb_add_hcd +EXPORT_SYMBOL_GPL vmlinux 0xf6b2c8aa spi_new_device +EXPORT_SYMBOL_GPL vmlinux 0xf6bcbd73 hwrng_register +EXPORT_SYMBOL_GPL vmlinux 0xf70e8175 fl6_sock_lookup +EXPORT_SYMBOL_GPL vmlinux 0xf71271b0 class_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf7386a4f generic_drop_inode +EXPORT_SYMBOL_GPL vmlinux 0xf74f7c8e usb_put_dev +EXPORT_SYMBOL_GPL vmlinux 0xf79e7abb pci_find_next_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0xf7ddb5f3 blk_rq_cur_bytes +EXPORT_SYMBOL_GPL vmlinux 0xf7fb2346 pci_enable_pcie_error_reporting +EXPORT_SYMBOL_GPL vmlinux 0xf82f16b3 execute_in_process_context +EXPORT_SYMBOL_GPL vmlinux 0xf84f7143 power_supply_am_i_supplied +EXPORT_SYMBOL_GPL vmlinux 0xf8802492 print_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0xf8b66770 spi_register_master +EXPORT_SYMBOL_GPL vmlinux 0xf8f3a0fb ata_ratelimit +EXPORT_SYMBOL_GPL vmlinux 0xf8f4dc21 queue_delayed_work_on +EXPORT_SYMBOL_GPL vmlinux 0xf972e196 rfkill_restore_states +EXPORT_SYMBOL_GPL vmlinux 0xf97666a0 set_memory_rw +EXPORT_SYMBOL_GPL vmlinux 0xf97916c9 crypto_attr_alg +EXPORT_SYMBOL_GPL vmlinux 0xf97f37d4 inotify_find_watch +EXPORT_SYMBOL_GPL vmlinux 0xf9a054b5 __round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0xf9ca3160 ata_id_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xfa66dc05 ata_sff_dumb_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0xfa95f137 pci_bus_max_busnr +EXPORT_SYMBOL_GPL vmlinux 0xfa974b29 nf_unregister_queue_handlers +EXPORT_SYMBOL_GPL vmlinux 0xfaee9f85 crypto_ahash_type +EXPORT_SYMBOL_GPL vmlinux 0xfb2a3293 math_state_restore +EXPORT_SYMBOL_GPL vmlinux 0xfb41e026 regulator_bulk_disable +EXPORT_SYMBOL_GPL vmlinux 0xfb815413 device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xfba16fd8 da903x_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0xfbebee1c sata_pmp_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xfbf9be5d register_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xfc084d7c sata_std_hardreset +EXPORT_SYMBOL_GPL vmlinux 0xfc6df88a ata_pci_sff_init_one +EXPORT_SYMBOL_GPL vmlinux 0xfcc989a7 scsi_internal_device_unblock +EXPORT_SYMBOL_GPL vmlinux 0xfcce694c rfkill_set_default +EXPORT_SYMBOL_GPL vmlinux 0xfcf2dc70 put_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0xfd3930d7 unregister_timer_hook +EXPORT_SYMBOL_GPL vmlinux 0xfd734132 ata_bmdma_start +EXPORT_SYMBOL_GPL vmlinux 0xfde0b92c crypto_larval_error +EXPORT_SYMBOL_GPL vmlinux 0xfde9ffb4 sync_page_io +EXPORT_SYMBOL_GPL vmlinux 0xfdf1c041 per_cpu__gdt_page +EXPORT_SYMBOL_GPL vmlinux 0xfe182518 usb_serial_generic_read_bulk_callback +EXPORT_SYMBOL_GPL vmlinux 0xfe287e90 sysfs_notify_dirent +EXPORT_SYMBOL_GPL vmlinux 0xfe323496 cpuidle_register_device +EXPORT_SYMBOL_GPL vmlinux 0xfe8fd14f hidraw_disconnect +EXPORT_SYMBOL_GPL vmlinux 0xfe990052 gpio_free +EXPORT_SYMBOL_GPL vmlinux 0xfebc7e1d usb_match_one_id +EXPORT_SYMBOL_GPL vmlinux 0xfecbff96 __mark_empty_function +EXPORT_SYMBOL_GPL vmlinux 0xfed11ed1 usb_mon_deregister +EXPORT_SYMBOL_GPL vmlinux 0xfed93be5 tracepoint_iter_next +EXPORT_SYMBOL_GPL vmlinux 0xfee9a70f ata_sff_data_xfer +EXPORT_SYMBOL_GPL vmlinux 0xfefdf9d0 cpuidle_disable_device +EXPORT_SYMBOL_GPL vmlinux 0xff44aec8 sdio_readb +EXPORT_SYMBOL_GPL vmlinux 0xff5a8cfe cn_del_callback +EXPORT_SYMBOL_GPL vmlinux 0xff820720 __blk_add_trace +EXPORT_SYMBOL_GPL vmlinux 0xffc21f5a relay_reset +EXPORT_SYMBOL_GPL vmlinux 0xffdb65dc part_round_stats +EXPORT_SYMBOL_GPL vmlinux 0xfff51481 dm_noflush_suspending +EXPORT_UNUSED_SYMBOL vmlinux 0x00000000 init_mm +EXPORT_UNUSED_SYMBOL vmlinux 0x00000000 simple_prepare_write --- linux-2.6.28.orig/debian/abi/2.6.28-11.41/i386/server +++ linux-2.6.28/debian/abi/2.6.28-11.41/i386/server @@ -0,0 +1,8679 @@ +EXPORT_SYMBOL arch/x86/kernel/scx200 0x254e5667 scx200_gpio_base +EXPORT_SYMBOL arch/x86/kernel/scx200 0x35a3c008 scx200_gpio_configure +EXPORT_SYMBOL arch/x86/kernel/scx200 0x8cfa375c scx200_gpio_shadow +EXPORT_SYMBOL arch/x86/kernel/scx200 0x907665bd scx200_cb_base +EXPORT_SYMBOL arch/x86/kvm/kvm 0x039e0406 kvm_read_guest_atomic +EXPORT_SYMBOL arch/x86/kvm/kvm 0x30208c11 kvm_cpu_has_pending_timer +EXPORT_SYMBOL crypto/gf128mul 0x0c2f123f gf128mul_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x1068004b gf128mul_bbe +EXPORT_SYMBOL crypto/gf128mul 0x2f2889a0 gf128mul_init_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0x3755f990 gf128mul_init_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x384ef9ce gf128mul_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x56af0dbd gf128mul_x_ble +EXPORT_SYMBOL crypto/gf128mul 0x83581089 gf128mul_init_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0x9b2560b9 gf128mul_init_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x9e13f6f6 gf128mul_lle +EXPORT_SYMBOL crypto/gf128mul 0xbd17a0df gf128mul_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0xc0890413 gf128mul_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0xd60736ec gf128mul_free_64k +EXPORT_SYMBOL crypto/xor 0x5b6c00e6 xor_blocks +EXPORT_SYMBOL drivers/atm/suni 0x72ae249e suni_init +EXPORT_SYMBOL drivers/atm/uPD98402 0x022a1c60 uPD98402_init +EXPORT_SYMBOL drivers/block/paride/paride 0x03c3aa5e paride_unregister +EXPORT_SYMBOL drivers/block/paride/paride 0x2039858e pi_write_regr +EXPORT_SYMBOL drivers/block/paride/paride 0x20542a69 pi_read_regr +EXPORT_SYMBOL drivers/block/paride/paride 0x33fdc045 pi_connect +EXPORT_SYMBOL drivers/block/paride/paride 0x8325597e pi_write_block +EXPORT_SYMBOL drivers/block/paride/paride 0x9000cd18 paride_register +EXPORT_SYMBOL drivers/block/paride/paride 0x9d7c1299 pi_init +EXPORT_SYMBOL drivers/block/paride/paride 0x9e4e2071 pi_do_claimed +EXPORT_SYMBOL drivers/block/paride/paride 0xbf4afe31 pi_schedule_claimed +EXPORT_SYMBOL drivers/block/paride/paride 0xc9bba62a pi_release +EXPORT_SYMBOL drivers/block/paride/paride 0xf5dcd364 pi_disconnect +EXPORT_SYMBOL drivers/block/paride/paride 0xfa430d5e pi_read_block +EXPORT_SYMBOL drivers/char/agp/agpgart 0x040574f7 agp_find_bridge +EXPORT_SYMBOL drivers/char/agp/agpgart 0x0d36dda4 agp_generic_enable +EXPORT_SYMBOL drivers/char/agp/agpgart 0x102c0c18 get_agp_version +EXPORT_SYMBOL drivers/char/agp/agpgart 0x1e2f5175 agp_generic_destroy_page +EXPORT_SYMBOL drivers/char/agp/agpgart 0x2381e616 agp_backend_acquire +EXPORT_SYMBOL drivers/char/agp/agpgart 0x30226ddf agp_device_command +EXPORT_SYMBOL drivers/char/agp/agpgart 0x31db0def agp_free_page_array +EXPORT_SYMBOL drivers/char/agp/agpgart 0x36f1ec4e agp_enable +EXPORT_SYMBOL drivers/char/agp/agpgart 0x39a2b6f7 agp_generic_alloc_pages +EXPORT_SYMBOL drivers/char/agp/agpgart 0x3c8c6f90 agp_generic_insert_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0x3ff5767d agp_put_bridge +EXPORT_SYMBOL drivers/char/agp/agpgart 0x42524fc8 agp_flush_chipset +EXPORT_SYMBOL drivers/char/agp/agpgart 0x4b085dbf agp3_generic_configure +EXPORT_SYMBOL drivers/char/agp/agpgart 0x4cf91606 agp_unbind_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0x52b37a54 agp_generic_free_by_type +EXPORT_SYMBOL drivers/char/agp/agpgart 0x59493b94 agp_generic_remove_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0x59b9faf1 agp_alloc_bridge +EXPORT_SYMBOL drivers/char/agp/agpgart 0x5a77593c agp_backend_release +EXPORT_SYMBOL drivers/char/agp/agpgart 0x5b01972b agp_generic_type_to_mask_type +EXPORT_SYMBOL drivers/char/agp/agpgart 0x5ee0f43b agp_alloc_page_array +EXPORT_SYMBOL drivers/char/agp/agpgart 0x5ef6c6f0 agp_generic_free_gatt_table +EXPORT_SYMBOL drivers/char/agp/agpgart 0x673f815e agp_bridges +EXPORT_SYMBOL drivers/char/agp/agpgart 0x7538b132 agp_off +EXPORT_SYMBOL drivers/char/agp/agpgart 0x7ceac30b agp_generic_alloc_by_type +EXPORT_SYMBOL drivers/char/agp/agpgart 0x90e067c6 agp_generic_create_gatt_table +EXPORT_SYMBOL drivers/char/agp/agpgart 0xa2d942e9 agp_generic_alloc_user +EXPORT_SYMBOL drivers/char/agp/agpgart 0xa4d4f0e6 global_cache_flush +EXPORT_SYMBOL drivers/char/agp/agpgart 0xadfbf106 agp_create_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xb04ea8f0 agp_rebind_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xb38517db agp_free_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xc02b7db7 agp_allocate_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xc06b40d7 agp_generic_destroy_pages +EXPORT_SYMBOL drivers/char/agp/agpgart 0xc2424641 agp3_generic_cleanup +EXPORT_SYMBOL drivers/char/agp/agpgart 0xc5d9c46c agp_try_unsupported_boot +EXPORT_SYMBOL drivers/char/agp/agpgart 0xc65abeb7 agp3_generic_sizes +EXPORT_SYMBOL drivers/char/agp/agpgart 0xcb4f1e10 agp3_generic_tlbflush +EXPORT_SYMBOL drivers/char/agp/agpgart 0xd0fef3b2 agp_free_key +EXPORT_SYMBOL drivers/char/agp/agpgart 0xdd5bd0a5 agp_generic_alloc_page +EXPORT_SYMBOL drivers/char/agp/agpgart 0xdd9f423d agp_generic_mask_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xddd3843d agp_copy_info +EXPORT_SYMBOL drivers/char/agp/agpgart 0xde9b17ed agp3_generic_fetch_size +EXPORT_SYMBOL drivers/char/agp/agpgart 0xe74708ce agp_bridge +EXPORT_SYMBOL drivers/char/agp/agpgart 0xeff6bb63 agp_collect_device_status +EXPORT_SYMBOL drivers/char/agp/agpgart 0xfb7e9a63 agp_bind_memory +EXPORT_SYMBOL drivers/char/generic_serial 0x1d7c7b36 gs_flush_buffer +EXPORT_SYMBOL drivers/char/generic_serial 0x208778ca gs_set_termios +EXPORT_SYMBOL drivers/char/generic_serial 0x2afd2938 gs_start +EXPORT_SYMBOL drivers/char/generic_serial 0x66630529 gs_chars_in_buffer +EXPORT_SYMBOL drivers/char/generic_serial 0x78f3bce3 gs_setserial +EXPORT_SYMBOL drivers/char/generic_serial 0x796f0965 gs_flush_chars +EXPORT_SYMBOL drivers/char/generic_serial 0x850119ae gs_init_port +EXPORT_SYMBOL drivers/char/generic_serial 0x8adcfff6 gs_write_room +EXPORT_SYMBOL drivers/char/generic_serial 0x9c7bd828 gs_put_char +EXPORT_SYMBOL drivers/char/generic_serial 0x9d77700b gs_got_break +EXPORT_SYMBOL drivers/char/generic_serial 0xa7ac0f11 gs_block_til_ready +EXPORT_SYMBOL drivers/char/generic_serial 0xa8a9b4d7 gs_write +EXPORT_SYMBOL drivers/char/generic_serial 0xb076df3e gs_stop +EXPORT_SYMBOL drivers/char/generic_serial 0xd29911fe gs_hangup +EXPORT_SYMBOL drivers/char/generic_serial 0xe38e5f8f gs_close +EXPORT_SYMBOL drivers/char/generic_serial 0xe559fb43 gs_getserial +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x01e4d87c ipmi_smi_add_proc_entry +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x1825d458 ipmi_get_my_address +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x1eca7089 ipmi_free_recv_msg +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x22acfcb6 ipmi_set_my_address +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x2641a0ed ipmi_register_smi +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x3ac32b34 ipmi_register_for_cmd +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x402fcdb4 ipmi_request_supply_msgs +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x40f2b10c ipmi_alloc_smi_msg +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x50a51e32 ipmi_request_settime +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x53c999b8 ipmi_create_user +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x5d6893fc ipmi_unregister_for_cmd +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x7808fb06 ipmi_poll_interface +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x804f922a ipmi_addr_length +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x8b9f6723 ipmi_set_maintenance_mode +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xa3634389 ipmi_destroy_user +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xa374ce58 ipmi_set_gets_events +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xaa05e332 ipmi_get_maintenance_mode +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xb512c2c4 ipmi_get_my_LUN +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xb9a63411 ipmi_unregister_smi +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xbc7d3739 ipmi_set_my_LUN +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xbd4f2088 ipmi_smi_watchdog_pretimeout +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xe374c5a4 ipmi_smi_msg_received +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xe4f4665b ipmi_validate_addr +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xefe67a0c ipmi_smi_watcher_unregister +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xf1233c0e ipmi_get_version +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xfd3d881f ipmi_smi_watcher_register +EXPORT_SYMBOL drivers/char/nsc_gpio 0x772713c8 nsc_gpio_read +EXPORT_SYMBOL drivers/char/nsc_gpio 0xc664ec68 nsc_gpio_dump +EXPORT_SYMBOL drivers/char/nsc_gpio 0xecbf1421 nsc_gpio_write +EXPORT_SYMBOL drivers/char/nvram 0x0f28cb91 nvram_read_byte +EXPORT_SYMBOL drivers/char/nvram 0x17ff2c1d __nvram_read_byte +EXPORT_SYMBOL drivers/char/nvram 0x2adec1e0 __nvram_check_checksum +EXPORT_SYMBOL drivers/char/nvram 0x7da28f12 nvram_check_checksum +EXPORT_SYMBOL drivers/char/nvram 0x9ce3f83f nvram_write_byte +EXPORT_SYMBOL drivers/char/nvram 0xa8813189 __nvram_write_byte +EXPORT_SYMBOL drivers/edac/edac_core 0x707294f9 edac_mc_handle_fbd_ce +EXPORT_SYMBOL drivers/edac/edac_core 0xcc415bf5 edac_mc_find +EXPORT_SYMBOL drivers/edac/edac_core 0xcfa0cc26 edac_mc_handle_fbd_ue +EXPORT_SYMBOL drivers/firewire/firewire-core 0x0b6fa66b fw_run_transaction +EXPORT_SYMBOL drivers/firewire/firewire-core 0x1daabb78 fw_core_handle_response +EXPORT_SYMBOL drivers/firewire/firewire-core 0x2ccb1b7b fw_device_enable_phys_dma +EXPORT_SYMBOL drivers/firewire/firewire-core 0x3dadbd29 fw_core_initiate_bus_reset +EXPORT_SYMBOL drivers/firewire/firewire-core 0x573188c9 fw_fill_response +EXPORT_SYMBOL drivers/firewire/firewire-core 0x5b9f6303 fw_core_add_address_handler +EXPORT_SYMBOL drivers/firewire/firewire-core 0x7c6901a2 fw_cancel_transaction +EXPORT_SYMBOL drivers/firewire/firewire-core 0x8334c31a fw_bus_type +EXPORT_SYMBOL drivers/firewire/firewire-core 0x85c056fc fw_card_add +EXPORT_SYMBOL drivers/firewire/firewire-core 0x90863005 fw_high_memory_region +EXPORT_SYMBOL drivers/firewire/firewire-core 0xafc1c793 fw_csr_iterator_next +EXPORT_SYMBOL drivers/firewire/firewire-core 0xb047a2c6 fw_csr_iterator_init +EXPORT_SYMBOL drivers/firewire/firewire-core 0xb4459dcb fw_core_handle_bus_reset +EXPORT_SYMBOL drivers/firewire/firewire-core 0xc0267d49 fw_send_request +EXPORT_SYMBOL drivers/firewire/firewire-core 0xd0643cd8 fw_core_handle_request +EXPORT_SYMBOL drivers/firewire/firewire-core 0xd70a1240 fw_core_remove_card +EXPORT_SYMBOL drivers/firewire/firewire-core 0xf51cf3d3 fw_core_remove_address_handler +EXPORT_SYMBOL drivers/firewire/firewire-core 0xf722ae6c fw_card_initialize +EXPORT_SYMBOL drivers/firewire/firewire-core 0xfe8ab439 fw_send_response +EXPORT_SYMBOL drivers/gpu/drm/drm 0x06dd138f drm_irq_uninstall +EXPORT_SYMBOL drivers/gpu/drm/drm 0x0836695c drm_sman_takedown +EXPORT_SYMBOL drivers/gpu/drm/drm 0x091e6889 drm_agp_bind_pages +EXPORT_SYMBOL drivers/gpu/drm/drm 0x096d8e4a drm_unbind_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0x0f42fc69 drm_vblank_put +EXPORT_SYMBOL drivers/gpu/drm/drm 0x1083218b drm_handle_vblank +EXPORT_SYMBOL drivers/gpu/drm/drm 0x1267700d drm_core_ioremapfree +EXPORT_SYMBOL drivers/gpu/drm/drm 0x148e1e3a drm_mm_search_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x14d0b3c2 drm_pci_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0x165e3ae4 drm_ati_pcigart_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x194d5903 drm_agp_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0x197476ed drm_addbufs_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0x1e9fdbb0 drm_vblank_get +EXPORT_SYMBOL drivers/gpu/drm/drm 0x20645642 drm_debug +EXPORT_SYMBOL drivers/gpu/drm/drm 0x211494de drm_getsarea +EXPORT_SYMBOL drivers/gpu/drm/drm 0x21451ac4 drm_sman_owner_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x25f9bdcf drm_agp_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x26cbe0a6 drm_fasync +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2916bf63 drm_sman_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2eb2f903 drm_sman_free_key +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2ec68648 drm_sg_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0x3074f033 drm_order +EXPORT_SYMBOL drivers/gpu/drm/drm 0x35bb8827 drm_agp_bind +EXPORT_SYMBOL drivers/gpu/drm/drm 0x3d3d23d6 drm_vblank_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4123a1bb drm_poll +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4ab5df76 drm_gem_object_lookup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4b8082b9 drm_mm_put_block +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4ea1f5a2 drm_gem_object_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x55f060ee drm_sman_set_range +EXPORT_SYMBOL drivers/gpu/drm/drm 0x62619857 drm_addmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0x62cd576d drm_gem_object_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0x6370b050 drm_mm_get_block +EXPORT_SYMBOL drivers/gpu/drm/drm 0x683fb374 drm_core_reclaim_buffers +EXPORT_SYMBOL drivers/gpu/drm/drm 0x6e129635 drm_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0x72a19f6d drm_idlelock_take +EXPORT_SYMBOL drivers/gpu/drm/drm 0x753708e6 drm_clflush_pages +EXPORT_SYMBOL drivers/gpu/drm/drm 0x7e8c2746 drm_agp_acquire +EXPORT_SYMBOL drivers/gpu/drm/drm 0x7fb52675 drm_agp_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0x842d9140 drm_addbufs_pci +EXPORT_SYMBOL drivers/gpu/drm/drm 0x85e664c2 drm_agp_enable +EXPORT_SYMBOL drivers/gpu/drm/drm 0x8873dc30 drm_mm_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x8a6ae994 drm_idlelock_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0x8ab28277 drm_core_ioremap_wc +EXPORT_SYMBOL drivers/gpu/drm/drm 0x933de4a9 drm_pci_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x93978e0b drm_get_resource_len +EXPORT_SYMBOL drivers/gpu/drm/drm 0x982aee4c drm_get_resource_start +EXPORT_SYMBOL drivers/gpu/drm/drm 0x9c25b192 drm_core_get_map_ofs +EXPORT_SYMBOL drivers/gpu/drm/drm 0xaf29788e drm_sman_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0xb8debc2b drm_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0xbc731b22 drm_core_ioremap +EXPORT_SYMBOL drivers/gpu/drm/drm 0xbdb628fc drm_vblank_count +EXPORT_SYMBOL drivers/gpu/drm/drm 0xc080eb9b drm_gem_object_handle_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0xc5f39a9f drm_agp_chipset_flush +EXPORT_SYMBOL drivers/gpu/drm/drm 0xc6228d7c drm_gem_handle_create +EXPORT_SYMBOL drivers/gpu/drm/drm 0xca7a4834 drm_irq_install +EXPORT_SYMBOL drivers/gpu/drm/drm 0xccfd8076 drm_agp_info +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd250940f drm_ati_pcigart_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd3028e75 drm_sman_set_manager +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd62bc955 drm_free_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0xde0f61a5 drm_ioctl +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe06588c6 drm_mmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe919dd5c drm_sman_owner_clean +EXPORT_SYMBOL drivers/gpu/drm/drm 0xebebe6f7 drm_lock_take +EXPORT_SYMBOL drivers/gpu/drm/drm 0xec0f8622 drm_i_have_hw_lock +EXPORT_SYMBOL drivers/gpu/drm/drm 0xec6740fc drm_exit +EXPORT_SYMBOL drivers/gpu/drm/drm 0xf0d2844c drm_core_get_reg_ofs +EXPORT_SYMBOL drivers/gpu/drm/drm 0xf6001fa2 drm_open +EXPORT_SYMBOL drivers/gpu/drm/drm 0xf6ff97d3 drm_get_drawable_info +EXPORT_SYMBOL drivers/gpu/drm/drm 0xf8b552ad drm_agp_unbind +EXPORT_SYMBOL drivers/gpu/drm/drm 0xfc6fc9ff drm_lock_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0xfdfbad19 drm_sman_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0xff1a34b7 drm_rmmap +EXPORT_SYMBOL drivers/hwmon/hwmon-vid 0x0903c239 vid_from_reg +EXPORT_SYMBOL drivers/hwmon/hwmon-vid 0xef1c781c vid_which_vrm +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0x52fc381f i2c_bit_add_numbered_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0xc5036e7c i2c_bit_add_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pca 0x58f8b58f i2c_pca_add_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pca 0x6171c6b4 i2c_pca_add_numbered_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pcf 0xdb72f388 i2c_pcf_add_bus +EXPORT_SYMBOL drivers/i2c/busses/i2c-amd756 0x76492e50 amd756_smbus +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x02d4ad0f tps65013_set_low_pwr +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x28485130 tps65010_config_vregs1 +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x33739de7 tps65010_set_vib +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x9fd44c69 tps65010_set_led +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0xb14080cc tps65010_set_low_pwr +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0xd5bb106d tps65010_set_vbus_draw +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0xe99b3f36 tps65010_set_gpio_out_value +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0b234c4e dma_prog_region_alloc +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0c6da941 csr1212_release_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0d6f23e7 hpsb_destroy_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0e5a659c csr1212_new_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0e66b069 hpsb_iso_recv_release_packets +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x1300dd69 hpsb_iso_packet_sent +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x13b4a268 csr1212_attach_keyval_to_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x158ac548 dma_region_offset_to_bus +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x197607c6 hpsb_make_streampacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x1c1d8eb9 hpsb_packet_success +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x1f0cb38c hpsb_iso_recv_unlisten_channel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x203d2d70 hpsb_unregister_highlevel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x260af6cb hpsb_make_writepacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2752b9a8 csr1212_get_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x289d8ec3 hpsb_alloc_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x29f7ff42 hpsb_unregister_protocol +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2ebf6e5a dma_prog_region_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x35c22fb6 hpsb_iso_xmit_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x37a736c9 csr1212_read +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x3e55b0b8 hpsb_resume_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x421600a4 hpsb_iso_recv_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x4259c88f hpsb_register_highlevel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x43a7d258 hpsb_get_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x46d752fa hpsb_iso_recv_set_channel_mask +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x4902ed99 hpsb_write +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x49dc2d4f hpsb_iso_shutdown +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x5336da4d hpsb_get_hostinfo_bykey +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x5d02e731 hpsb_iso_xmit_queue_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x5e9596fd hpsb_set_packet_complete_task +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6106ba5d hpsb_make_phypacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6175f944 hpsb_iso_packet_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x66247a6d dma_region_mmap +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x672ad148 dma_region_sync_for_device +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6a3d48e8 hpsb_free_tlabel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6f7798ce hpsb_allocate_and_register_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x7046e886 csr1212_parse_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x735e6607 hpsb_protocol_class +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x76bc1a5c dma_region_free +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x7bf8d2f2 hpsb_unregister_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8879f8f0 dma_region_sync_for_cpu +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x89d418af hpsb_iso_stop +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8d299de3 hpsb_node_write +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8ec2b312 dma_region_alloc +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x92c833eb hpsb_iso_n_ready +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x93e8e087 hpsb_make_readpacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x946c2b9a hpsb_selfid_complete +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x9faf4690 hpsb_reset_bus +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xa63851e1 hpsb_selfid_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xa7307598 hpsb_iso_wake +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xa76b3415 hpsb_iso_xmit_start +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xa87ec9be hpsb_send_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xa98fe813 hpsb_alloc_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xad0ef000 hpsb_free_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb5d44404 hpsb_iso_recv_flush +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xbd7a0fdb hpsb_set_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xbfad88de hpsb_make_lock64packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc42b7ab9 __hpsb_register_protocol +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc669a4d3 csr1212_detach_keyval_from_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc809a94a hpsb_bus_reset +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc8a64d88 hpsb_make_lockpacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xcbe6405d hpsb_register_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xcd951389 hpsb_get_tlabel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xcd9e772b dma_prog_region_free +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xce7dadd0 hpsb_create_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xcf196d0d hpsb_read +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xd068cde0 hpsb_iso_recv_listen_channel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xd817072d hpsb_read_cycle_timer +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xdbc1e9f2 hpsb_remove_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xdc64fb3a hpsb_update_config_rom_image +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xde5fd821 hpsb_node_fill_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xe10979fa hpsb_iso_xmit_sync +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xe6e1ccb6 hpsb_set_hostinfo_key +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xea3674f4 hpsb_packet_sent +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xea4152ff dma_region_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xecdaa7d7 hpsb_packet_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xef271a67 hpsb_iso_recv_start +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xf28c5e82 hpsb_add_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xf4392af9 hpsb_update_config_rom +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfba57f51 hpsb_speedto_str +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0x1ae10caa ohci1394_register_iso_tasklet +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0xb36e4982 ohci1394_unregister_iso_tasklet +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0xb37ab086 ohci1394_init_iso_tasklet +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0xb82bb5cc ohci1394_stop_context +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x6a7daf88 rdma_translate_ip +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x71de06c2 rdma_addr_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x73c8f319 rdma_addr_cancel +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0xbe81bb46 rdma_addr_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0xdc2d97ce rdma_resolve_ip +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0xdc790292 rdma_copy_addr +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x02e1cbc8 ib_send_cm_rej +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x315f2a47 cm_class +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x31a23ce1 ib_create_cm_id +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x34f51538 ib_destroy_cm_id +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x3d35116e ib_cm_notify +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x68de4fae ib_send_cm_sidr_rep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x83447af2 ib_cm_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x85ebf70b ib_send_cm_mra +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x8e746760 ib_send_cm_apr +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xa9c6e49c ib_send_cm_drep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xacb26914 ib_send_cm_sidr_req +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xb0d831d2 ib_send_cm_lap +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xbef71f73 ib_send_cm_rep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xc3b27fa3 ib_send_cm_req +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xc52fbc02 ib_send_cm_dreq +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xe6821096 ib_send_cm_rtu +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xe696f8a7 ib_cm_listen +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x0422e6b4 ib_dispatch_event +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x04230dcc ib_destroy_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x0b481fde ib_modify_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x0ea234ff ib_alloc_fast_reg_page_list +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x1e491a04 ib_unmap_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x23b2a78d ib_fmr_pool_unmap +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x2672c71f ib_alloc_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x28af0a39 ib_query_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x2c955610 ib_get_cached_lmc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x340aa3a3 ib_free_fast_reg_page_list +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3624f8e3 ib_get_dma_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x36ff9dbb ib_dealloc_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x392db943 ib_get_cached_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3a5dad5f ib_dealloc_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3efa6499 ib_register_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3f7567fd ib_rate_to_mult +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x401a8d54 ib_query_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x43ae59ab ib_resize_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x478a55b5 ib_init_ah_from_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x487690fa ib_query_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x4ed5185b ib_destroy_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x520b2638 ib_pack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x5423113a ib_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x549a5906 ib_reg_phys_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x5898a6cb ib_alloc_fast_reg_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x5c1a0d8f ib_dealloc_pd +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x647438af ib_query_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x64a9ae76 ib_modify_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x65e3f821 ib_destroy_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x6782e508 ib_find_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x679d835c ib_create_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x6e924ff8 ib_flush_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x7b814a65 ib_query_port +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x856b108f ib_modify_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8640eaeb ib_modify_qp_is_ok +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x87b614d8 ib_ud_header_pack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x88889f74 ib_alloc_pd +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8b2e708f ib_rereg_phys_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x960a0968 ib_get_client_data +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9678f58b ib_modify_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x96b0c89e ib_query_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x96ce6c46 rdma_node_get_transport +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x97bde09a ib_modify_port +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9ca0354b ib_query_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9d804fa1 mult_to_ib_rate +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa0f15e74 ib_find_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa1171a58 ib_destroy_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa255e5d8 ib_dereg_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa500ed92 ib_create_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa9a26c4c ib_destroy_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xab8cd8fd ib_fmr_pool_map_phys +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xaba30816 ib_create_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb1a312e1 ib_unpack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb26c1194 ib_register_event_handler +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb367887b ib_set_client_data +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb54dbb02 ib_create_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb879e87a ib_detach_mcast +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xbc77dbee ib_unregister_event_handler +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xbd1bb08d ib_umem_get +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xbd30f2e5 ib_find_cached_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xc16208a9 ib_get_cached_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xc2e1ffed ib_umem_page_count +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd17ba9d1 ib_ud_header_init +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd2ea6b21 ib_unregister_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd40d884e ib_umem_release +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd451b17b ib_alloc_mw +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd89752a0 ib_dealloc_mw +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xdb1c642e ib_alloc_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xdd1ef044 ib_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xe1374ea7 ib_modify_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xe435f758 ib_create_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xe6d33ad3 ib_create_ah_from_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xe7d7f901 ib_query_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xee601453 ib_find_cached_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf36498b9 ib_ud_header_unpack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xfa5f343f ib_attach_mcast +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x05cffb54 ib_unregister_mad_agent +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x1cd5fd58 ib_register_mad_snoop +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x274aa892 ib_free_recv_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x278074ab ib_free_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6ef787ed ib_response_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6f077fcf ib_get_mad_data_offset +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6faf079f ib_cancel_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x7b5d4b7a ib_is_mad_class_rmpp +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x82710b38 ib_redirect_mad_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x8827e03e ib_get_rmpp_segment +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x9564d954 ib_register_mad_agent +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xa3914e53 ib_create_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xd74e8eb7 ib_modify_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xdf9387d3 ib_post_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xf1586366 ib_process_mad_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x16199856 ib_sa_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x2bf58dfa ib_init_ah_from_mcmember +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x512ba124 ib_sa_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x576fdbac ib_sa_free_multicast +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x5ec2b1ea ib_sa_join_multicast +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x732ae351 ib_sa_path_rec_get +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xcd3e5e9b ib_sa_service_rec_query +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xd570bd6f ib_sa_get_mcmember_rec +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xf58fe770 ib_init_ah_from_path +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xf5e7c693 ib_sa_cancel_query +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x02f847bc ib_copy_path_rec_from_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x07cf5a51 ib_copy_ah_attr_to_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x18382f6a ib_copy_path_rec_to_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x184f3575 ib_copy_qp_attr_to_user +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x05508689 iw_create_cm_id +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x4965b425 iw_cm_reject +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x4c38fb45 iw_cm_disconnect +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x8a836816 iw_cm_connect +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xbf7c8fbb iw_destroy_cm_id +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xd0262d74 iw_cm_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xf38f8fbe iw_cm_listen +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xfaf1ff25 iw_cm_accept +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x11af7fe7 rdma_create_qp +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x227c9d3e rdma_accept +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x3675313e rdma_connect +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x3aacc5e9 rdma_leave_multicast +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x3d4637e5 rdma_create_id +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x4d51cdc6 rdma_resolve_route +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x68a664e1 rdma_destroy_id +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x784ea8b8 rdma_disconnect +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x8c4c89a1 rdma_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x8f98785d rdma_set_service_type +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x9201654b rdma_reject +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x9fe512f7 rdma_bind_addr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xa151ed1a rdma_resolve_addr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xa1bf57ee rdma_set_ib_paths +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xb634b257 rdma_notify +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xbb86ec8e rdma_destroy_qp +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xbddf6391 rdma_listen +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xde9a0b9c rdma_join_multicast +EXPORT_SYMBOL drivers/input/gameport/gameport 0x0053cd5b gameport_close +EXPORT_SYMBOL drivers/input/gameport/gameport 0x2b42519c __gameport_register_port +EXPORT_SYMBOL drivers/input/gameport/gameport 0x36314106 gameport_stop_polling +EXPORT_SYMBOL drivers/input/gameport/gameport 0x6c6b6b2a gameport_unregister_port +EXPORT_SYMBOL drivers/input/gameport/gameport 0x7d09399e gameport_open +EXPORT_SYMBOL drivers/input/gameport/gameport 0x9936da6d gameport_start_polling +EXPORT_SYMBOL drivers/input/gameport/gameport 0xbe384996 __gameport_register_driver +EXPORT_SYMBOL drivers/input/gameport/gameport 0xdb88163f gameport_unregister_driver +EXPORT_SYMBOL drivers/input/gameport/gameport 0xfccd2eeb gameport_set_phys +EXPORT_SYMBOL drivers/input/input-polldev 0x1a16d207 input_unregister_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0x4aca6503 input_allocate_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0x8bd50e75 input_register_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0xb27fc7f2 input_free_polled_device +EXPORT_SYMBOL drivers/isdn/capi/capifs 0x2c54c957 capifs_free_ncci +EXPORT_SYMBOL drivers/isdn/capi/capifs 0xd0bc06ce capifs_new_ncci +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x04403fcf unregister_capi_driver +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x04a45b85 capi_ctr_handle_message +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x14f2aa5a capi20_get_version +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x2b8eab1f capilib_free_ncci +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x2baa6586 capilib_new_ncci +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x31c24aa4 capi20_isinstalled +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x44628f6b capi_ctr_ready +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x47d3fc51 capi_info2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x50b33ca4 capi_cmsg2message +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x56a3cc69 detach_capi_ctr +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x6057c6f3 capi_message2cmsg +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x62e32d43 capilib_data_b3_conf +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x6b48ff32 capi_ctr_suspend_output +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x71e8d5ba capilib_data_b3_req +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x7a33596c capi20_get_serial +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x7e6f1307 capi20_get_manufacturer +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x856dde8a attach_capi_ctr +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x8e422e7f capi20_release +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x8f699913 capilib_release +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x9f823278 register_capi_driver +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xa7c4fd6c capi_message2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xaa165d27 capilib_release_appl +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xac67f4e1 capi20_register +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xb19fda8d capi_cmd2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xb60e5e5f capi_cmsg_header +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xbc795c59 capi20_put_message +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xbe4f9cfc capi_ctr_reseted +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xc10fe128 cdebbuf_free +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xc6bdd1fb capi_ctr_resume_output +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xe19a11ac capi20_get_profile +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xe8ad9bd1 capi_cmsg2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xed061606 capi20_manufacturer +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xfad5ab53 capi20_set_callback +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x2d229122 b1_register_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x2f86127e b1_release_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x341e37c4 b1_send_message +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x35b5dbe0 avmcard_dma_free +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x54842fd1 avmcard_dma_alloc +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x605121f2 b1_load_t4file +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x7d4fb24d b1_alloc_card +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x85f09690 b1_irq_table +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x85f24530 b1_getrevision +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x862edccd b1_load_firmware +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x96f9d2f4 b1_interrupt +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xa5cf4bd7 b1_load_config +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xab20e887 b1_parse_version +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xb30394ca b1_free_card +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xb43f68eb b1_reset_ctr +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xc5024f98 b1ctl_read_proc +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xd384891e b1_loaded +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xdfd28376 b1_detect +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x2a386384 b1dma_interrupt +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x404835f6 b1dmactl_read_proc +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x4d423187 b1dma_load_firmware +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x97502f5d b1dma_reset_ctr +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x9968756e b1pciv4_detect +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0xb71fe4eb b1dma_send_message +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0xcb662b09 b1dma_release_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0xd43db9d3 t1pci_detect +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0xe8f97d07 b1dma_reset +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0xec517b1b b1dma_register_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0x29562993 b1pcmcia_delcard +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0xaec3240e b1pcmcia_addcard_m1 +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0xea620116 b1pcmcia_addcard_m2 +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0xf14bf8b1 b1pcmcia_addcard_b1 +EXPORT_SYMBOL drivers/isdn/hardware/eicon/divadidd 0x2974ead1 DIVA_DIDD_Read +EXPORT_SYMBOL drivers/isdn/hardware/eicon/divadidd 0x404dfcec proc_net_eicon +EXPORT_SYMBOL drivers/isdn/hardware/mISDN/hfcmulti 0x5293ed86 plx_lock +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x07f4f2ce hisax_unregister +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x148f0c99 FsmFree +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x2844a899 FsmInitTimer +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x93a64734 FsmChangeState +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x9c49eecd hisax_init_pcmcia +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x9df0cd27 FsmEvent +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xc0c558f9 FsmRestartTimer +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xd94696e8 FsmDelTimer +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xee93522c hisax_register +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xf0a16657 FsmNew +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xfc27303b HiSax_closecard +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x0b0fc6c2 isac_init +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x3f3b323a isac_d_l2l1 +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x8b4b67d1 isac_setup +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x9cecf463 isacsx_irq +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x9dbeef64 isacsx_setup +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0xd24d9160 isac_irq +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0x1ee629e2 isdnhdlc_rcv_init +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0x95aed401 isdnhdlc_decode +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0x9ffc8215 isdnhdlc_out_init +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0xf5c8131d isdnhdlc_encode +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0x17d02c91 isdn_ppp_register_compressor +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0x25b9640b isdn_ppp_unregister_compressor +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0x3dec0878 register_isdn +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0xfa06820f isdn_register_divert +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x024a7c77 confirm_Bsend +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x05e12e80 recv_Dchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x11489a7f mISDN_initbchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x1444c646 mISDN_initdchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x1e204eac recv_Bchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x2348cc3c mISDN_FsmFree +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x3ea336fd mISDN_FsmAddTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x429129f2 mISDN_FsmRestartTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x50c2230c mISDN_FsmChangeState +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x56d0ab47 mISDN_unregister_Bprotocol +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x6813609d mISDN_freedchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x6a9a1b6e dchannel_senddata +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x70cd5617 get_next_dframe +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x712a0af7 mISDN_register_device +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x9f383371 create_l1 +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xa89c1b3a mISDN_freebchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xa9212c21 get_next_bframe +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xace35cae mISDN_FsmDelTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xae7c9c5a recv_Bchannel_skb +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xc84b91cf l1_event +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xd5145151 mISDN_FsmEvent +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xd880aee8 recv_Dchannel_skb +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xd9a7fbfd mISDN_FsmInitTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xdc35196a mISDN_unregister_device +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xee035204 bchannel_senddata +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xf1f0a602 queue_ch_frame +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xf52abf72 mISDN_register_Bprotocol +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xf9e7832f mISDN_FsmNew +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0x4c2ec443 mISDN_dsp_element_register +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0x60721da7 dsp_audio_law_to_s32 +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0xa215f1b2 dsp_audio_s16_to_law +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0xd3a023b8 mISDN_dsp_element_unregister +EXPORT_SYMBOL drivers/media/common/tuners/mt2060 0x0cef7757 mt2060_attach +EXPORT_SYMBOL drivers/media/common/tuners/mt2131 0x5ae696af mt2131_attach +EXPORT_SYMBOL drivers/media/common/tuners/mt2266 0x0ce47b57 mt2266_attach +EXPORT_SYMBOL drivers/media/common/tuners/mxl5005s 0x1fbbffdc mxl5005s_attach +EXPORT_SYMBOL drivers/media/common/tuners/qt1010 0xb917e837 qt1010_attach +EXPORT_SYMBOL drivers/media/common/tuners/tuner-types 0x0cb4b189 tuners +EXPORT_SYMBOL drivers/media/common/tuners/tuner-types 0xc2821775 tuner_count +EXPORT_SYMBOL drivers/media/common/tuners/tuner-xc2028 0x02ef6e34 xc2028_attach +EXPORT_SYMBOL drivers/media/common/tuners/xc5000 0x3cbebcda xc5000_attach +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x0e1de14b flexcop_dma_xfer_control +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x1497c7fb flexcop_dma_control_timer_irq +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x35185233 flexcop_device_kfree +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x3c867f5e flexcop_device_initialize +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x3dc20cee flexcop_device_kmalloc +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x3e645b47 flexcop_device_exit +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x4b6d24ee flexcop_sram_set_dest +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x4c9cf1aa flexcop_dma_allocate +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x867aeb67 flexcop_eeprom_check_mac_addr +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x90c63e72 flexcop_sram_ctrl +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x9877df2f flexcop_dma_config_timer +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xada89a01 flexcop_dma_config +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xae7c2607 flexcop_pass_dmx_packets +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xb04c2c51 flexcop_dma_control_size_irq +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xb4101947 flexcop_i2c_request +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xbbbe9202 flexcop_wan_set_speed +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xce6e9b56 flexcop_dump_reg +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xd1fc824b flexcop_pass_dmx_data +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xe9f2b18a flexcop_dma_free +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0x23bbb51a bt878_start +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0xb3510062 bt878_device_control +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0xd5d0bdef bt878_num +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0xe05e560d bt878 +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0xff0d0f25 bt878_stop +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x0774ee0c read_dst +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x287738bf dst_wait_dst_ready +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x3e334920 dst_error_recovery +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x935d0e66 dst_attach +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xb5be8eba dst_pio_disable +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xc26de72c write_dst +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xd746f20a rdc_reset_state +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xe2fb64bd dst_error_bailout +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xe94b8c9c dst_check_sum +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xf3260970 dst_comm_init +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst_ca 0x797db60a dst_ca_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x02465233 dvb_register_adapter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x04495507 dvb_ca_en50221_frda_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x052a0393 dvb_register_device +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x057e09aa dvb_register_frontend +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x0b8dad4a dvb_generic_open +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x0fbb41d8 dvb_net_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x14eb630c dvb_ringbuffer_free +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x36c8ea1f dvb_frontend_sleep_until +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x4999a1b0 dvb_generic_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x4baaec92 dvb_frontend_detach +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x4c545ef3 dvb_frontend_reinitialise +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x635eb40e dvb_dmx_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x67691797 dvb_generic_ioctl +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x6f7f7d73 dvb_ringbuffer_empty +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x6f9c72e3 dvb_ringbuffer_read +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x74a5a698 dvb_filter_pes2ts_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x80e3832d dvb_filter_get_ac3info +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x83dddcea dvb_ca_en50221_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x8900d737 dvb_unregister_adapter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x8b49a23f timeval_usec_diff +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x923aa88e dvb_ringbuffer_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x9cbff999 dvb_dmx_swfilter_204 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x9f78538b dvb_dmxdev_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xa3b6264a dvb_unregister_device +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xa7c87f4a dvb_ca_en50221_camchange_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xac4ca1b0 intlog2 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb2c543c1 dvb_net_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb2db2592 dvb_ringbuffer_write +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb56f0404 dvb_dmx_swfilter_packets +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb5b95805 dvb_ringbuffer_read_user +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xbed559e1 dvb_dmx_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xc6f84ea1 dvb_dmxdev_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xc6fbfdaf dvb_unregister_frontend +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xc938e566 dvb_dmx_swfilter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xca163a47 dvb_ca_en50221_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xd698a043 dvb_ca_en50221_camready_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xe5ae8707 intlog10 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xe7949e59 dvb_ringbuffer_flush_spinlock_wakeup +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xeb7daf80 dvb_ringbuffer_avail +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf826deb0 dvb_filter_pes2ts +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x15a9bc53 dvb_usb_nec_rc_key_to_event +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x41a4fdbb usb_cypress_load_firmware +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x546d144d dvb_usb_generic_rw +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x62ad06d1 dvb_usb_get_hexline +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x6be6b3fe dvb_usb_generic_write +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xa74c164a dvb_usb_device_init +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xd72ff99c dvb_usb_device_exit +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0x2edc4728 af9005_rc_keys +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0x35f5e253 af9005_rc_decode +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0xd3383957 af9005_rc_keys_size +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x2835fd20 dibusb2_0_streaming_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x3774934c dibusb_pid_filter_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x6b5e31e8 dibusb_dib3000mc_tuner_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x6bea3223 dibusb_streaming_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x78419558 dibusb_rc_query +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x805ef891 dibusb_i2c_algo +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x87d6cdde dibusb2_0_power_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x8ec2c7e5 dibusb_pid_filter +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xa9ddc3bf dibusb_power_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xd4d3dddc dibusb_rc_keys +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xd952e43f dibusb_read_eeprom_byte +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xf2a058a1 dibusb_dib3000mc_frontend_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/af9013 0x66b77ae0 af9013_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/au8522 0x4eaf24ef au8522_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/bcm3510 0xacf5ebe4 bcm3510_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx22700 0x2f7886a6 cx22700_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx22702 0x6826dac9 cx22702_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24110 0x7ed8e299 cx24110_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24116 0xa8d0d23f cx24116_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24123 0x67e38330 cx24123_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24123 0xb7cb732a cx24123_get_tuner_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/dib0070 0x5c070b5c dib0070_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib0070 0x63a686eb dib0070_wbd_offset +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mb 0xf4d9a47a dib3000mb_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x2d0e1023 dib3000mc_pid_parse +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x645971a5 dib3000mc_get_tuner_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x69f4d8f7 dib3000mc_pid_control +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x88d9fc48 dib3000mc_i2c_enumeration +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0xd96a905d dib3000mc_set_config +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0xec2582b7 dib3000mc_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000m 0x3fb36db1 dib7000m_get_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000m 0x4e99d80f dib7000m_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x130cedff dib7000p_i2c_enumeration +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x5484f0e0 dib7000p_set_gpio +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x70d45051 dib7000p_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xa052c934 dib7000pc_detection +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xb1ee8067 dib7000p_get_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xf66f588a dib7000p_set_wbd_ref +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0x1519efd0 dibx000_get_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0xa57c7090 dibx000_init_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0xfb445aeb dibx000_exit_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/drx397xD 0xd1662e64 drx397xD_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dvb-pll 0x9af4eed5 dvb_pll_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/isl6405 0x1bd3bb4a isl6405_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/isl6421 0x7e3efc73 isl6421_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/itd1000 0x3103b1e0 itd1000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/l64781 0x1ba2a761 l64781_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lgdt330x 0x9f3a770c lgdt330x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lgs8gl5 0x4e85f2cd lgs8gl5_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lnbp21 0x06755158 lnbp21_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/mt312 0x7bfba37d mt312_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/mt352 0xda8f0c14 mt352_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/nxt200x 0xafe8c311 nxt200x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/nxt6000 0x733b779e nxt6000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/or51132 0xab2c0120 or51132_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/or51211 0xa17443f2 or51211_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1409 0xa5c3a187 s5h1409_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1411 0x55ff199d s5h1411_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1420 0x51689480 s5h1420_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1420 0x5169d484 s5h1420_get_tuner_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/si21xx 0x94cb4254 si21xx_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/sp8870 0x01cc88bd sp8870_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/sp887x 0xbe7ee62b sp887x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stb6000 0x867c7aaa stb6000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0288 0x562b2b76 stv0288_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0297 0x74574f16 stv0297_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0299 0xd8f69a43 stv0299_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10021 0xa829af78 tda10021_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10023 0x5c831c3d tda10023_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10048 0x2ff4f4ca tda10048_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda1004x 0x4dfc7338 tda10045_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda1004x 0x6abdcac8 tda10046_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10086 0x2fc09949 tda10086_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda8083 0x10480e48 tda8083_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda826x 0x19b347a2 tda826x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tua6100 0x9d0fa197 tua6100_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/ves1820 0x65189bbd ves1820_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/ves1x93 0xeeeb665d ves1x93_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/zl10353 0x72094dd0 zl10353_attach +EXPORT_SYMBOL drivers/media/dvb/ttpci/ttpci-eeprom 0xc56bb38c ttpci_eeprom_parse_mac +EXPORT_SYMBOL drivers/media/dvb/ttusb-dec/ttusbdecfe 0x59b83119 ttusbdecfe_dvbt_attach +EXPORT_SYMBOL drivers/media/dvb/ttusb-dec/ttusbdecfe 0x727f30d3 ttusbdecfe_dvbs_attach +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x11dc4b6d bttv_gpio_enable +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x25d8e75b bttv_sub_unregister +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x8ecf4acc bttv_write_gpio +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0xbcf2d2fb bttv_read_gpio +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0xd6283e92 bttv_get_pcidev +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0xd74777b2 bttv_sub_register +EXPORT_SYMBOL drivers/media/video/btcx-risc 0x0f53f0aa btcx_riscmem_alloc +EXPORT_SYMBOL drivers/media/video/btcx-risc 0x495e4b0c btcx_calc_skips +EXPORT_SYMBOL drivers/media/video/btcx-risc 0x52e0d490 btcx_riscmem_free +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xad2fe38b btcx_sort_clips +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xc368f8e6 btcx_align +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xcda0ded2 btcx_screen_clips +EXPORT_SYMBOL drivers/media/video/cpia 0x4cf1b1d7 cpia_unregister_camera +EXPORT_SYMBOL drivers/media/video/cpia 0xd71f9fd2 cpia_register_camera +EXPORT_SYMBOL drivers/media/video/cx18/cx18 0x2cdea06d cx18_reset_ir_gpio +EXPORT_SYMBOL drivers/media/video/cx2341x 0x226b4360 cx2341x_ctrl_get_menu +EXPORT_SYMBOL drivers/media/video/cx2341x 0x484d9064 cx2341x_ctrl_query +EXPORT_SYMBOL drivers/media/video/cx2341x 0x61b38569 cx2341x_ext_ctrls +EXPORT_SYMBOL drivers/media/video/cx2341x 0x62f2c86b cx2341x_log_status +EXPORT_SYMBOL drivers/media/video/cx2341x 0x7f09da7c cx2341x_fill_defaults +EXPORT_SYMBOL drivers/media/video/cx2341x 0xcf8b77a4 cx2341x_mpeg_ctrls +EXPORT_SYMBOL drivers/media/video/cx2341x 0xe58ec2e3 cx2341x_update +EXPORT_SYMBOL drivers/media/video/cx88/cx88-vp3054-i2c 0x27fda75d vp3054_i2c_probe +EXPORT_SYMBOL drivers/media/video/cx88/cx88-vp3054-i2c 0xbabaf451 vp3054_i2c_remove +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x01a72e9b cx8800_ctrl_query +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x4a09648e cx88_get_control +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xa743c850 cx88_set_control +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xac4e53b9 cx88_user_ctrls +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xb4d04185 cx88_video_mux +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xcd1a1528 cx88_set_freq +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xe9b45d9d cx88_enum_input +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x32c730ea cx8802_unregister_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x796243bf cx8802_register_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0xae4f7448 cx8802_get_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0xc7aecfc7 cx8802_buf_prepare +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0xde90662b cx8802_get_device +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0xe0e94467 cx8802_cancel_buffers +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0xe7724628 cx8802_buf_queue +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x02399ae9 cx88_vdev_init +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x02899539 cx88_risc_buffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x0573b2fe cx88_core_irq +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x069db5e4 cx88_free_buffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x06c5ae3a cx88_risc_databuffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x072710aa cx88_core_put +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x1d2ed4b9 cx88_reset +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x209ae4b1 cx88_set_tvnorm +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x3127e3e7 cx88_get_stereo +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x3ce68798 cx88_sram_channel_dump +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x5178ffa9 cx88_wakeup +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x5cb2017c cx88_ir_start +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x5e6d9e0b cx88_set_scale +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x6141c8c5 cx88_tuner_callback +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x71773ed1 cx88_ir_stop +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x722f19b9 cx88_call_i2c_clients +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x904b8696 cx88_audio_thread +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x9b140fff cx88_sram_channels +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x9c0144ca cx88_core_get +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xb47f6cda cx88_print_irqbits +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xb6eee8cf cx88_shutdown +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xb75c06d7 cx88_set_stereo +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xc9484111 cx88_sram_channel_setup +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xe4fa4e9b cx88_set_tvaudio +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xee3fd166 cx88_newstation +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xf34d30a1 cx88_risc_stopper +EXPORT_SYMBOL drivers/media/video/em28xx/em28xx 0xf203a616 em28xx_register_extension +EXPORT_SYMBOL drivers/media/video/em28xx/em28xx 0xf67cfc47 em28xx_unregister_extension +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x160d8f88 gspca_auto_gain_n_exposure +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x33273056 gspca_get_i_frame +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x4034d140 gspca_suspend +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x6466c6fa gspca_dev_probe +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x84201801 gspca_frame_add +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x9670af2c gspca_debug +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xb4365687 gspca_disconnect +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xef3cb91d gspca_resume +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x0538e449 ivtv_cards_lock +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x142bba8a ivtv_api +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x14f67530 ivtv_debug +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x237ed804 ivtv_reset_ir_gpio +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x2de76ada ivtv_cards +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x45b93633 ivtv_vapi +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x4e43b2fa ivtv_udma_setup +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x5353c4dd ivtv_vapi_result +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x6379d34f ivtv_udma_prepare +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x70196ffb ivtv_cards_active +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xa09d0856 ivtv_set_irq_mask +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xa22ef0d9 ivtv_init_on_first_open +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xa95c0128 ivtv_udma_unmap +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xd09010a1 ivtv_udma_alloc +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xd7f47af2 ivtv_clear_irq_mask +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xe6cc3139 ivtv_saa7127 +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x04e83446 saa7134_tuner_callback +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x1211df5d saa7134_devlist +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x13800b8c saa7134_pgtable_alloc +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x2120d934 saa_dsp_writel +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x23d52a64 saa7134_set_gpio +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x270dc858 saa7134_pgtable_free +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x77e28727 saa7134_dmasound_init +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x98af79c1 saa7134_boards +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x99a39c90 saa7134_i2c_call_clients +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xa7edcbc8 saa7134_dmasound_exit +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xacd53588 saa7134_ts_register +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xb9877e74 saa7134_pgtable_build +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xd9778fc9 saa7134_tvaudio_setmute +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xef6a3650 saa7134_ts_unregister +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xf2beb523 saa7134_set_dmabits +EXPORT_SYMBOL drivers/media/video/soc_camera 0x1685a2b9 soc_camera_device_unregister +EXPORT_SYMBOL drivers/media/video/soc_camera 0x3d43d9dc soc_camera_device_register +EXPORT_SYMBOL drivers/media/video/soc_camera 0x7773b873 soc_camera_host_unregister +EXPORT_SYMBOL drivers/media/video/soc_camera 0xaf0d16f7 soc_camera_video_start +EXPORT_SYMBOL drivers/media/video/soc_camera 0xb2a6201e soc_camera_host_register +EXPORT_SYMBOL drivers/media/video/soc_camera 0xd6e1c092 soc_camera_video_stop +EXPORT_SYMBOL drivers/media/video/tveeprom 0x061bdd8f tveeprom_read +EXPORT_SYMBOL drivers/media/video/tveeprom 0xe1022d4e tveeprom_hauppauge_analog +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x07cd8833 usbvideo_Deregister +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x16a2915c RingQueue_Dequeue +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x16b1f416 usbvideo_register +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x303c1202 usbvideo_RegisterVideoDevice +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x407a321c RingQueue_WakeUpInterruptible +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x4c9d4d90 usbvideo_TestPattern +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xa74b7f3a usbvideo_AllocateDevice +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xddecac6d RingQueue_Enqueue +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xe1e55201 usbvideo_DeinterlaceFrame +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xf5011f67 RingQueue_Flush +EXPORT_SYMBOL drivers/media/video/v4l1-compat 0xbdee49b5 v4l_compat_translate_ioctl +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x03165a85 v4l2_ctrl_get_menu +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x0dfb5e57 v4l2_prio_max +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x131190d6 v4l2_chip_match_i2c_client +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x137509d1 v4l2_i2c_attach +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x1c427ecb v4l2_ctrl_query_fill +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x2de2b633 v4l2_prio_check +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x2e9a955d v4l2_prio_close +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x42c8e001 v4l2_ctrl_next +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x495426ee v4l2_ctrl_get_name +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x50766d69 v4l2_ctrl_query_menu_valid_items +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x57abfbd8 v4l2_chip_match_host +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x5fef1b4a v4l2_ctrl_query_fill_std +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x942892ab v4l2_prio_open +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xb2d1e17e v4l2_prio_change +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xbcddeffb v4l2_chip_ident_i2c_client +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xc369097d v4l2_ctrl_check +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xd464e760 v4l2_ctrl_query_menu +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xe330bce9 v4l2_prio_init +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x0b255a79 videobuf_dvb_register_bus +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x5101bdaa videobuf_dvb_alloc_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x56e2d808 videobuf_dvb_get_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x9ed68dca videobuf_dvb_find_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0xb99aab7f videobuf_dvb_unregister_bus +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0xe3ffaee5 videobuf_dvb_dealloc_frontends +EXPORT_SYMBOL drivers/media/video/videodev 0x123959a1 v4l2_type_names +EXPORT_SYMBOL drivers/media/video/videodev 0x1b058616 video_register_device +EXPORT_SYMBOL drivers/media/video/videodev 0x226ae8f1 video_devdata +EXPORT_SYMBOL drivers/media/video/videodev 0x32ed58ba video_device_alloc +EXPORT_SYMBOL drivers/media/video/videodev 0x3adbd595 v4l2_field_names +EXPORT_SYMBOL drivers/media/video/videodev 0x5ebefe4b v4l_printk_ioctl +EXPORT_SYMBOL drivers/media/video/videodev 0x7186a692 video_device_release_empty +EXPORT_SYMBOL drivers/media/video/videodev 0x8b6941e8 video_unregister_device +EXPORT_SYMBOL drivers/media/video/videodev 0xa3f7a4f1 __video_ioctl2 +EXPORT_SYMBOL drivers/media/video/videodev 0xabe0fd41 video_device_release +EXPORT_SYMBOL drivers/media/video/videodev 0xba4bcd7b video_ioctl2 +EXPORT_SYMBOL drivers/media/video/videodev 0xe2b92059 v4l2_video_std_construct +EXPORT_SYMBOL drivers/media/video/videodev 0xf3251e7b v4l2_norm_to_name +EXPORT_SYMBOL drivers/media/video/videodev 0xfc85ccfc video_usercopy +EXPORT_SYMBOL drivers/media/video/videodev 0xff21f9d4 video_register_device_index +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0x5d940430 videocodec_register +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0x6068f54e videocodec_detach +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0xd4f479d5 videocodec_attach +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0xec014351 videocodec_unregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x09735de2 mpt_GetIocState +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x0d71f792 mpt_send_handshake_request +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x105d4f47 mpt_add_sge +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x1f568dab mpt_free_fw_memory +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x27352748 mpt_config +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x3ec978a5 mpt_raid_phys_disk_pg0 +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x400eea72 mpt_verify_adapter +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x44e837ee mpt_HardResetHandler +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x4526289b mpt_event_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x5877e1c2 mpt_attach +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x76fa6cf1 mpt_alloc_fw_memory +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x8015b009 mpt_put_msg_frame_hi_pri +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x80526d7b mpt_findImVolumes +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x8e9fda74 mpt_detach +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x91bd4cf8 mpt_suspend +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x97d436c4 mpt_print_ioc_summary +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x98f79906 mpt_resume +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xa6dde024 mpt_reset_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xabfce77f mpt_device_driver_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xaca3d33f mpt_get_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xad5a20a9 mpt_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc0e69f82 mpt_device_driver_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc47c22e8 mpt_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc587f368 mptbase_sas_persist_operation +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xd1565b89 mpt_put_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xd9a92a75 mpt_reset_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xdd805159 ioc_list +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xdf19edd0 mpt_event_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xf1ee768b mpt_free_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x131d0efc mptscsih_bus_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x1355862e mptscsih_remove +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x144ed76b mptscsih_proc_info +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x16659f70 mptscsih_raid_id_to_num +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x16e1ce9e mptscsih_info +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x16e1d262 mptscsih_is_phys_disk +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x1a52c51d mptscsih_shutdown +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x405bdc14 mptscsih_slave_destroy +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x522f71a2 mptscsih_ioc_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x58e641aa mptscsih_TMHandler +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x6d104bbb mptscsih_qcmd +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x764ddf1a mptscsih_timer_expired +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x7a644977 mptscsih_scandv_complete +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x83b62f21 mptscsih_change_queue_depth +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x94709a5d mptscsih_io_done +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x963bf874 mptscsih_dev_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x9647f2e5 mptscsih_suspend +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xa0d8d5fe mptscsih_host_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xa14589d9 mptscsih_bios_param +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xb23e0a15 mptscsih_event_process +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xd46f41f3 mptscsih_resume +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xd9358465 mptscsih_abort +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xe8464cba mptscsih_host_attrs +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xe9df3736 mptscsih_slave_configure +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xfc2b3cb7 mptscsih_taskmgmt_complete +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x0ac650eb i2o_find_iop +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x2a843bef i2o_dump_message +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x2d74ee57 i2o_msg_get_wait +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x349d5099 i2o_driver_notify_device_remove_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x3b1f5e6d i2o_driver_register +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x5b8b1c5f i2o_msg_post_wait_mem +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x629e6ee4 i2o_event_register +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x672a04e9 i2o_driver_notify_controller_remove_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x68aa2ce5 i2o_device_claim_release +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x6bc259ef i2o_driver_unregister +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x6e81f4bc i2o_exec_lct_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x6f72def9 i2o_driver_notify_controller_add_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x996d96a7 i2o_parm_field_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xa662eb92 i2o_driver_notify_device_add_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xae20bd0e i2o_iop_find_device +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xb4c00dcf i2o_controllers +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xb6806aa1 i2o_parm_issue +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xba232d88 i2o_parm_table_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xca28df2b i2o_status_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xdb5bcbc3 i2o_device_claim +EXPORT_SYMBOL drivers/mfd/htc-pasic3 0x7587e69e pasic3_write_register +EXPORT_SYMBOL drivers/mfd/htc-pasic3 0x8d08ec07 pasic3_read_register +EXPORT_SYMBOL drivers/misc/c2port/core 0x820bd39a c2port_device_register +EXPORT_SYMBOL drivers/misc/c2port/core 0xe235d08b c2port_device_unregister +EXPORT_SYMBOL drivers/misc/ioc4 0x2ad5b885 ioc4_unregister_submodule +EXPORT_SYMBOL drivers/misc/ioc4 0x5d4a07a4 ioc4_register_submodule +EXPORT_SYMBOL drivers/misc/sony-laptop 0x5bb1e117 sony_pic_camera_command +EXPORT_SYMBOL drivers/misc/tifm_core 0x179af519 tifm_register_driver +EXPORT_SYMBOL drivers/misc/tifm_core 0x39f86aa1 tifm_queue_work +EXPORT_SYMBOL drivers/misc/tifm_core 0x55f83f0c tifm_free_device +EXPORT_SYMBOL drivers/misc/tifm_core 0x6269cdff tifm_unmap_sg +EXPORT_SYMBOL drivers/misc/tifm_core 0x7d345cd7 tifm_alloc_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0x8be46c0f tifm_map_sg +EXPORT_SYMBOL drivers/misc/tifm_core 0xa0c21404 tifm_add_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0xa4aa9690 tifm_alloc_device +EXPORT_SYMBOL drivers/misc/tifm_core 0xa9b74cd4 tifm_eject +EXPORT_SYMBOL drivers/misc/tifm_core 0xb2ebf411 tifm_has_ms_pif +EXPORT_SYMBOL drivers/misc/tifm_core 0xb8bcf517 tifm_unregister_driver +EXPORT_SYMBOL drivers/misc/tifm_core 0xe6290274 tifm_remove_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0xe8879282 tifm_free_adapter +EXPORT_SYMBOL drivers/mmc/card/mmc_block 0x4c57037c mmc_cleanup_queue +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0x58e78b00 cfi_fixup +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0xb8193dba cfi_read_pri +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0xbcb87af8 cfi_varsize_frob +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x05df204e unregister_mtd_chip_driver +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x33ea9711 register_mtd_chip_driver +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x9f65ba4e do_map_probe +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0xbc4fa889 map_destroy +EXPORT_SYMBOL drivers/mtd/chips/gen_probe 0x90123e20 mtd_do_chip_probe +EXPORT_SYMBOL drivers/mtd/maps/map_funcs 0xc5e32a35 simple_map_init +EXPORT_SYMBOL drivers/mtd/mtd 0x6eacd476 del_mtd_partitions +EXPORT_SYMBOL drivers/mtd/mtd 0x911b5afb add_mtd_partitions +EXPORT_SYMBOL drivers/mtd/mtdconcat 0x21151446 mtd_concat_create +EXPORT_SYMBOL drivers/mtd/mtdconcat 0xaee594ea mtd_concat_destroy +EXPORT_SYMBOL drivers/mtd/nand/nand 0x874bf508 nand_scan_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand 0xd9cac8bc nand_default_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0x28cfbfd7 nand_correct_data +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0x422fdb02 nand_calculate_ecc +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0x836bdb72 nand_flash_ids +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0xa336feb7 nand_manuf_ids +EXPORT_SYMBOL drivers/mtd/onenand/onenand 0xae914bd9 onenand_scan_bbt +EXPORT_SYMBOL drivers/mtd/onenand/onenand 0xf5a8fa24 onenand_default_bbt +EXPORT_SYMBOL drivers/net/8390 0x66222f55 ei_close +EXPORT_SYMBOL drivers/net/8390 0x7d7e0dbc ei_interrupt +EXPORT_SYMBOL drivers/net/8390 0xb13c69e6 NS8390_init +EXPORT_SYMBOL drivers/net/8390 0xd1434560 ei_open +EXPORT_SYMBOL drivers/net/8390 0xe83230b5 ei_poll +EXPORT_SYMBOL drivers/net/8390 0xf665a844 __alloc_ei_netdev +EXPORT_SYMBOL drivers/net/8390p 0x4ba9df32 eip_open +EXPORT_SYMBOL drivers/net/8390p 0x6a58d4bc eip_poll +EXPORT_SYMBOL drivers/net/8390p 0x841bc69f eip_interrupt +EXPORT_SYMBOL drivers/net/8390p 0xb2081102 __alloc_eip_netdev +EXPORT_SYMBOL drivers/net/8390p 0xb84cd5ea NS8390p_init +EXPORT_SYMBOL drivers/net/8390p 0xe3ddf517 eip_close +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x4036f637 arcnet_unregister_proto +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x4641bd7d arcnet_interrupt +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x6534792a arcnet_debug +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x85db15ae arc_proto_map +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x99b67f23 arc_raw_proto +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x9e09b512 alloc_arcdev +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0xa67da50b arc_proto_default +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0xc0958624 arc_bcast_proto +EXPORT_SYMBOL drivers/net/arcnet/com20020 0x753934bb com20020_check +EXPORT_SYMBOL drivers/net/arcnet/com20020 0x7b9a98c6 com20020_found +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x1f9159bc dev2t3cdev +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x2ea6c2fd cxgb3_alloc_stid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x38e02134 cxgb3_queue_tid_release +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x6baa0e87 cxgb3_free_atid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x74d8e3a2 cxgb3_register_client +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x9eac94ac cxgb3_alloc_atid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xa28ce407 cxgb3_ofld_send +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xb5cb83e1 t3_l2t_get +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xbc9698f9 t3_register_cpl_handler +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xcb4aa0ab cxgb3_remove_tid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xe80da33a t3_l2t_send_event +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xea8ffa04 cxgb3_unregister_client +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xeec2fed1 t3_l2t_send_slow +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xf685a0f9 cxgb3_insert_tid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xf7c2c615 t3_l2e_free +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xfa7cf0c3 cxgb3_free_stid +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0x1d8a3f69 hdlcdrv_arbitrate +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0x3045919e hdlcdrv_unregister +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0x392231b2 hdlcdrv_register +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0x71ee9c12 hdlcdrv_transmitter +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0xe5e52958 hdlcdrv_receiver +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x103c361f sirdev_get_instance +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x128861db irda_unregister_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x1a70a95b sirdev_receive +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x355f7f49 sirdev_set_dtr_rts +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x3cfb2c10 sirdev_set_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x83974c00 sirdev_write_complete +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x92e23c5b irda_register_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x9563244a sirdev_raw_write +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xa8f8cd56 sirdev_raw_read +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xbe9f9c68 sirdev_put_instance +EXPORT_SYMBOL drivers/net/mii 0x3f65be29 mii_check_link +EXPORT_SYMBOL drivers/net/mii 0x4066e022 mii_ethtool_gset +EXPORT_SYMBOL drivers/net/mii 0x5fb883da mii_link_ok +EXPORT_SYMBOL drivers/net/mii 0x7cda66e1 mii_check_media +EXPORT_SYMBOL drivers/net/mii 0x8873e94c mii_check_gmii_support +EXPORT_SYMBOL drivers/net/mii 0xa22e4502 generic_mii_ioctl +EXPORT_SYMBOL drivers/net/mii 0xa2bb958c mii_ethtool_sset +EXPORT_SYMBOL drivers/net/mii 0xea317747 mii_nway_restart +EXPORT_SYMBOL drivers/net/phy/mdio-bitbang 0x45fec05b free_mdio_bitbang +EXPORT_SYMBOL drivers/net/phy/mdio-bitbang 0xf2940737 alloc_mdio_bitbang +EXPORT_SYMBOL drivers/net/pppox 0x0e93fd97 pppox_ioctl +EXPORT_SYMBOL drivers/net/pppox 0xb1ce1593 pppox_unbind_sock +EXPORT_SYMBOL drivers/net/pppox 0xe0ff7a18 unregister_pppox_proto +EXPORT_SYMBOL drivers/net/pppox 0xfd63cde6 register_pppox_proto +EXPORT_SYMBOL drivers/net/sungem_phy 0x78ab254c mii_phy_probe +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x518fcbfb tms380tr_interrupt +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x57b612a9 tmsdev_init +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x8a025b79 tms380tr_close +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x92c54fa1 tms380tr_open +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0xb629b48c tmsdev_term +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0xd2328794 tms380tr_wait +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x38da4725 cycx_intr +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x62be23ea cycx_setup +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x66a4c4e6 cycx_down +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x968458a6 cycx_peek +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0xb6f383de cycx_poke +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0xfe7cd576 cycx_exec +EXPORT_SYMBOL drivers/net/wan/hdlc 0x1e0dd3ed detach_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0x27eb0bb4 unregister_hdlc_device +EXPORT_SYMBOL drivers/net/wan/hdlc 0x2b7680ac hdlc_ioctl +EXPORT_SYMBOL drivers/net/wan/hdlc 0x472c39b3 hdlc_open +EXPORT_SYMBOL drivers/net/wan/hdlc 0x6434153c attach_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0xd5ccdf8c register_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0xe74a6f35 unregister_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0xec24759d alloc_hdlcdev +EXPORT_SYMBOL drivers/net/wan/hdlc 0xefdf191f hdlc_close +EXPORT_SYMBOL drivers/net/wan/syncppp 0x03e00c19 sppp_reopen +EXPORT_SYMBOL drivers/net/wan/syncppp 0x1e920b0f sppp_detach +EXPORT_SYMBOL drivers/net/wan/syncppp 0x23b91ae4 sppp_close +EXPORT_SYMBOL drivers/net/wan/syncppp 0x649b4122 sppp_do_ioctl +EXPORT_SYMBOL drivers/net/wan/syncppp 0x952a814d sppp_open +EXPORT_SYMBOL drivers/net/wan/syncppp 0xbec80bf8 sppp_attach +EXPORT_SYMBOL drivers/net/wan/z85230 0x0e045f77 z8530_dma_sync +EXPORT_SYMBOL drivers/net/wan/z85230 0x10c78988 z8530_dead_port +EXPORT_SYMBOL drivers/net/wan/z85230 0x12d0490c z8530_init +EXPORT_SYMBOL drivers/net/wan/z85230 0x1a96deec z8530_describe +EXPORT_SYMBOL drivers/net/wan/z85230 0x27baa573 z8530_sync_dma_open +EXPORT_SYMBOL drivers/net/wan/z85230 0x283e799e z8530_interrupt +EXPORT_SYMBOL drivers/net/wan/z85230 0x36ee32bc z8530_sync_dma_close +EXPORT_SYMBOL drivers/net/wan/z85230 0x38ff7481 z8530_sync_close +EXPORT_SYMBOL drivers/net/wan/z85230 0x5cd24d29 z8530_hdlc_kilostream +EXPORT_SYMBOL drivers/net/wan/z85230 0x6dbf8792 z8530_sync_txdma_close +EXPORT_SYMBOL drivers/net/wan/z85230 0x83d2be8e z8530_shutdown +EXPORT_SYMBOL drivers/net/wan/z85230 0xa8a196cc z8530_sync_txdma_open +EXPORT_SYMBOL drivers/net/wan/z85230 0xb1a717e5 z8530_txdma_sync +EXPORT_SYMBOL drivers/net/wan/z85230 0xbe8d9af7 z8530_nop +EXPORT_SYMBOL drivers/net/wan/z85230 0xcb0ce35b z8530_queue_xmit +EXPORT_SYMBOL drivers/net/wan/z85230 0xdbc376c5 z8530_channel_load +EXPORT_SYMBOL drivers/net/wan/z85230 0xe3d80064 z8530_hdlc_kilostream_85230 +EXPORT_SYMBOL drivers/net/wan/z85230 0xeae5ecac z8530_sync +EXPORT_SYMBOL drivers/net/wan/z85230 0xed74aa7b z8530_sync_open +EXPORT_SYMBOL drivers/net/wan/z85230 0xf113a1aa z8530_null_rx +EXPORT_SYMBOL drivers/net/wireless/airo 0x2d55bebb reset_airo_card +EXPORT_SYMBOL drivers/net/wireless/airo 0x4a6b037f stop_airo_card +EXPORT_SYMBOL drivers/net/wireless/airo 0xb90013e9 init_airo_card +EXPORT_SYMBOL drivers/net/wireless/atmel 0x09d389c0 init_atmel_card +EXPORT_SYMBOL drivers/net/wireless/atmel 0x68ef63c2 stop_atmel_card +EXPORT_SYMBOL drivers/net/wireless/atmel 0xf2befc4c atmel_open +EXPORT_SYMBOL drivers/net/wireless/hermes 0x4196c38b hermes_write_ltv +EXPORT_SYMBOL drivers/net/wireless/hermes 0xa031d8e4 hermes_doicmd_wait +EXPORT_SYMBOL drivers/net/wireless/hermes 0xc60b5e9e hermes_bap_pwrite +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd38d8ae2 hermes_read_ltv +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd3f714e5 hermes_bap_pread +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd5168829 hermes_allocate +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd5336e5d hermes_init +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd54e219d hermes_docmd_wait +EXPORT_SYMBOL drivers/net/wireless/hermes 0xed47b224 hermes_struct_init +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x161a199c hermes_program +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x2e340491 hermesi_program_end +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x3e7d91b2 hermesi_program_init +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x79a2030e hermes_read_pda +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xc4026a52 hermes_apply_pda +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xcbd49cae hermes_apply_pda_with_defaults +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xeeef9f73 hermes_blocks_length +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x0ad69602 hostap_set_multicast_list_queue +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x0ee40864 prism2_update_comms_qual +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x214310df hostap_set_word +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x41d28a67 hostap_init_proc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x471ea86a hostap_init_data +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x4c6e1f20 hostap_set_hostapd +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x53988eca hostap_remove_interface +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x6844b058 hostap_free_data +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x6903f16c hostap_80211_get_hdrlen +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x7c9fc1f0 hostap_master_start_xmit +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x7d109b00 hostap_remove_proc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x8bf23424 hostap_set_antsel +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x9cc41a01 hostap_add_interface +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xa031689b hostap_set_encryption +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xa12ad27f hostap_dump_tx_header +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xa73f7a79 hostap_setup_dev +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xb288085a hostap_get_porttype +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xb2a945e0 hostap_dump_rx_header +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xb6dc6e4e hostap_info_init +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xbaec2ada hostap_set_roaming +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xbd421582 hostap_check_sta_fw_version +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xc7130971 hostap_handle_sta_tx_exc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xcd480aa3 hostap_set_string +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xd55f11a2 hostap_set_auth_algs +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xdea901f8 hostap_80211_ops +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xe914f279 hostap_set_hostapd_sta +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xe93dadaf hostap_80211_rx +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xeeaf1bf6 hostap_info_process +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xf6eabdec hostap_get_stats +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xf6eeb893 hostap_init_ap_proc +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x06f05274 iwl_add_station_flags +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x08305d2b iwlcore_eeprom_query_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x089b9a4d iwl_dump_nic_event_log +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x0bd7bbb7 iwl_reset_qos +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x0e02c6bd iwl_power_initialize +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x11a0e66f iwl_hw_txq_ctx_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x1354b105 iwlcore_eeprom_verify_signature +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x150473fe iwl_remove_dynamic_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x15b6d403 iwl_rx_statistics +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x18b073d0 iwl_power_update_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x18c3412d iwlcore_eeprom_release_semaphore +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x1a446bf8 iwl_chain_noise_calibration +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x1a920a7d iwl_send_add_sta +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x1d77b399 iwl_bcast_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x1e28cabb iwl_txq_ctx_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x23ede4ef iwl_init_channel_map +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2434ab10 iwl_rx_reply_compressed_ba +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2500d48c iwl_power_temperature_change +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x27ab9346 iwl_sensitivity_calibration +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2840bd5b iwl_init_sensitivity +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2998a767 iwl_rx_queue_restock +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2eff34c7 iwl_eeprom_check_version +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x332aecae iwl_leds_register +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x341c03ed iwl_rxq_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x34efdc84 iwl_setup_rx_scan_handlers +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x34f0aafd iwl_send_cmd_pdu +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x39d2e99f iwl_send_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x3b8c9902 iwl_rx_queue_alloc +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x3dfa081b iwl_rx_agg_start +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x3e1f8b33 iwl_setup_scan_deferred_work +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x40183e77 iwl_verify_ucode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x4170e849 iwl_set_rxon_ht +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x41af0f40 iwl_hw_nic_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x4356e36a iwl_setup_mac +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x439ebc4a iwl_reset_run_time_calib +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x44f7b782 iwl_power_disable_management +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x454121f7 iwl_scan_initiate +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x49615cb5 iwl_eeprom_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x4f22ee6f iwl_set_rxon_chain +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x50f8f6af iwl_send_lq_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5121626e iwl_rx_agg_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x54754f66 iwl_rx_queue_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x576bd623 iwl_rx_replenish +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x58972527 iwl_rx_missed_beacon_notif +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5d590853 iwl_alloc_all +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5eb668fb iwl_txq_check_empty +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x60774702 iwl_queue_space +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x62727d56 iwl_calib_set +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x66a01381 iwl_uninit_drv +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x71aee1a4 iwl_tx_agg_start +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x750204f9 iwl_rx_queue_space +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7929702d iwl_eeprom_query_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7a8aefdf iwl_eeprom_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7ab171cd iwl_init_drv +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7e6aff6e iwl_set_default_wep_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x84cfb799 iwl_sta_modify_enable_tid_tx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x84ea22b9 iwl_set_hw_params +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8670273d iwl_hwrate_to_plcp_idx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9230b31b iwl_remove_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x96525347 iwl_is_fat_tx_allowed +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa1149a41 iwl_power_set_system_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa1386495 iwl_rf_kill_ct_config +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa516edd9 iwl_leds_unregister +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa5e067ba iwl_rfkill_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa95eb5cd iwlcore_eeprom_acquire_semaphore +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa98564b3 iwl_get_channel_info +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa9c4cba0 iwl_rxon_add_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xaa1a2487 iwl_rx_queue_update_write_ptr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xaa6299a0 iwl_send_static_wepkey_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xabc36b59 iwl_rx_reply_rx_phy +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xad440f10 iwl_power_cancel_timeout +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xadab102e iwl_tx_skb +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xae92e464 iwl_radio_kill_sw_enable_radio +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb0010eb2 iwl_send_cmd_sync +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb35a2b26 iwl_clear_stations_table +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb35b9ccf iwl_rfkill_set_hw_state +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xbaa7a545 iwl_set_dynamic_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xbc7da7ca iwl_power_set_user_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xbfac3811 iwl_hw_detect +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc24bdd74 iwl_rfkill_unregister +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc2aea72a iwl_hwrate_to_tx_control +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc667ca3e iwl_txq_update_write_ptr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc97e8ab6 iwl_find_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcbaf4931 get_cmd_string +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcc827591 iwl_tx_queue_reclaim +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd3b357cf iwl_set_tx_power +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd42f00fa iwl_setup_power_deferred_work +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd7a708c7 iwl_remove_default_wep_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd80910f9 iwl_rx_queue_reset +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xdbe978af iwl_get_sta_id +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xdcea1f6a iwl_send_statistics_request +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xdf04655a iwl_scan_cancel_timeout +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe4e3818e iwl_dump_nic_error_log +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe6cd4b72 iwl_set_rxon_channel +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe7ce5d70 iwl_rates +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe823ff0e iwl_radio_kill_sw_disable_radio +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe9063cd9 iwl_send_calib_results +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe96bdef8 iwl_power_enable_management +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xeb79c67b iwl_eeprom_get_mac +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xec3e5653 iwl_tx_agg_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xeccd58b1 iwl_scan_cancel +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xf0c72837 iwl_tx_cmd_complete +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xf6a3e5ea iwl_eeprom_query16 +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xf9f0c17a iwl_send_cmd_pdu_async +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xfb2b23be iwl_get_ra_sta_id +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xfbe95572 iwl_rx_reply_rx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xfd772371 iwl_leds_background +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x1a9d334a orinoco_interrupt +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x24822c97 __orinoco_up +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x2878e55f __orinoco_down +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x72ceec16 alloc_orinocodev +EXPORT_SYMBOL drivers/net/wireless/orinoco 0xfa550bef orinoco_reinit_firmware +EXPORT_SYMBOL drivers/net/wireless/orinoco 0xfcec1a77 free_orinocodev +EXPORT_SYMBOL drivers/parport/parport 0x12f159ef parport_set_timeout +EXPORT_SYMBOL drivers/parport/parport 0x1dbe8d84 parport_irq_handler +EXPORT_SYMBOL drivers/parport/parport 0x1f9daec4 parport_wait_peripheral +EXPORT_SYMBOL drivers/parport/parport 0x27ca6ea0 parport_ieee1284_ecp_read_data +EXPORT_SYMBOL drivers/parport/parport 0x2a172bc6 parport_read +EXPORT_SYMBOL drivers/parport/parport 0x2c4f443a parport_put_port +EXPORT_SYMBOL drivers/parport/parport 0x2f0d1b70 parport_ieee1284_ecp_write_data +EXPORT_SYMBOL drivers/parport/parport 0x323d4ee0 parport_announce_port +EXPORT_SYMBOL drivers/parport/parport 0x33af3a8b parport_claim_or_block +EXPORT_SYMBOL drivers/parport/parport 0x39925fd7 parport_ieee1284_epp_write_addr +EXPORT_SYMBOL drivers/parport/parport 0x4401119a parport_register_port +EXPORT_SYMBOL drivers/parport/parport 0x4d2a941b parport_ieee1284_interrupt +EXPORT_SYMBOL drivers/parport/parport 0x4da55a78 parport_ieee1284_epp_read_data +EXPORT_SYMBOL drivers/parport/parport 0x52f4cba3 parport_unregister_driver +EXPORT_SYMBOL drivers/parport/parport 0x6733e412 parport_ieee1284_epp_write_data +EXPORT_SYMBOL drivers/parport/parport 0x715de052 parport_get_port +EXPORT_SYMBOL drivers/parport/parport 0x71aca0b5 parport_ieee1284_ecp_write_addr +EXPORT_SYMBOL drivers/parport/parport 0x77ac438a parport_ieee1284_read_byte +EXPORT_SYMBOL drivers/parport/parport 0x83106958 parport_negotiate +EXPORT_SYMBOL drivers/parport/parport 0x881750c3 parport_ieee1284_write_compat +EXPORT_SYMBOL drivers/parport/parport 0x889057c3 parport_register_driver +EXPORT_SYMBOL drivers/parport/parport 0x9b15e6c3 parport_register_device +EXPORT_SYMBOL drivers/parport/parport 0xaa45136e parport_remove_port +EXPORT_SYMBOL drivers/parport/parport 0xaac48277 parport_release +EXPORT_SYMBOL drivers/parport/parport 0xabb92251 parport_ieee1284_epp_read_addr +EXPORT_SYMBOL drivers/parport/parport 0xb1bb607f parport_write +EXPORT_SYMBOL drivers/parport/parport 0xb61aee4f parport_find_number +EXPORT_SYMBOL drivers/parport/parport 0xbdfb48ef parport_ieee1284_read_nibble +EXPORT_SYMBOL drivers/parport/parport 0xd389040b parport_claim +EXPORT_SYMBOL drivers/parport/parport 0xde46b232 parport_find_base +EXPORT_SYMBOL drivers/parport/parport 0xf367e3ac parport_unregister_device +EXPORT_SYMBOL drivers/parport/parport 0xf3db046c parport_wait_event +EXPORT_SYMBOL drivers/parport/parport_pc 0x30c748b0 parport_pc_probe_port +EXPORT_SYMBOL drivers/parport/parport_pc 0xc77b3636 parport_pc_unregister_port +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x074bbc90 pcmcia_request_configuration +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x16fd745d pcmcia_unregister_driver +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x2f8597ba pcmcia_get_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x31573757 pcmcia_release_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x49d34bea pcmcia_loop_config +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x4fd033a0 pcmcia_error_func +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x51747ba6 pcmcia_access_configuration_register +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x570c7bcc pcmcia_register_driver +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x5b299f70 pcmcia_disable_device +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x889b12ee pcmcia_map_mem_page +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x9c961d52 pcmcia_request_io +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xa1cfa7a2 pcmcia_request_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xb1ebf1e8 pcmcia_get_mem_page +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xb54270a9 pcmcia_dev_present +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xb7378059 pcmcia_request_irq +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xe823b26f pcmcia_modify_configuration +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xf0a25e12 pcmcia_error_ret +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x139a16f7 pcmcia_get_socket_by_nr +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x146ae495 pcmcia_register_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x1b2279ce pccard_validate_cis +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x212db8d2 pcmcia_socket_list +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x2b8b5d36 pccard_get_first_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x2e9df318 pcmcia_validate_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x2ee2e483 pcmcia_insert_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x3334a0d9 pcmcia_parse_events +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x33b5fee1 destroy_cis_cache +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x471b712c pcmcia_get_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x5502c493 pcmcia_socket_class +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x559beb04 pcmcia_unregister_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x57686761 pcmcia_read_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x589c7114 release_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x591f87ab pcmcia_socket_dev_suspend +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x8354be76 pcmcia_replace_cis +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x86cfcf0c pcmcia_eject_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x88605c7c pcmcia_find_mem_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x89124303 pccard_static_ops +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x91d275e1 pcmcia_suspend_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x97f46ac8 pcmcia_adjust_io_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x9b2aad2d pcmcia_resume_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xa66b7ddf pccard_get_next_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xaa307f90 pccard_get_tuple_data +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xafd819e5 pccard_register_pcmcia +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xbe901d4a pcmcia_write_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xc02ef2c8 pcmcia_parse_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xc368f687 pcmcia_socket_list_rwsem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xcf97f3bd dead_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xd8e97fd8 pcmcia_socket_dev_resume +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xed8729bf pcmcia_reset_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xef58f3c1 pcmcia_find_io_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xf3f9f7b4 pcmcia_put_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xfe6c64f6 pccard_read_tuple +EXPORT_SYMBOL drivers/pcmcia/rsrc_nonstatic 0x1e2024e2 pccard_nonstatic_ops +EXPORT_SYMBOL drivers/scsi/53c700 0x5175c0f0 NCR_700_intr +EXPORT_SYMBOL drivers/scsi/53c700 0x5d1a4190 NCR_700_detect +EXPORT_SYMBOL drivers/scsi/53c700 0xf42e464c NCR_700_release +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0x2250c66e mraid_mm_adapter_app_handle +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0x512c956d mraid_mm_unregister_adp +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0xb5e315e8 mraid_mm_register_adp +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x158eebf6 qlogicfas408_disable_ints +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x20d42364 qlogicfas408_queuecommand +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x3fd8cd71 qlogicfas408_detect +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x54900e67 qlogicfas408_info +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x5cd179e6 qlogicfas408_ihandl +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xb8eaa670 qlogicfas408_bus_reset +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xe48abd38 qlogicfas408_biosparam +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xe76b3b20 qlogicfas408_get_chip_type +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xf2b95199 qlogicfas408_setup +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xf68307f5 qlogicfas408_abort +EXPORT_SYMBOL drivers/scsi/raid_class 0x1b4d72d2 raid_class_release +EXPORT_SYMBOL drivers/scsi/raid_class 0xc7aacbae raid_component_add +EXPORT_SYMBOL drivers/scsi/raid_class 0xdff00e73 raid_class_attach +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x1fc34cf9 fc_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x2b51eceb fc_vport_create +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x586c9349 fc_remove_host +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x68b284e2 fc_host_post_vendor_event +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x7954b1ea fc_get_event_number +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x8487019e scsi_is_fc_rport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xa58cf52e scsi_is_fc_vport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xd5f59e37 fc_remote_port_rolechg +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xde4464ac fc_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xed442b07 fc_remote_port_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xf362a40e fc_vport_terminate +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xf6f855f3 fc_host_post_event +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xfcb0ecef fc_remote_port_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x16cb66fb scsi_is_sas_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x176ab89b sas_port_alloc_num +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x22c2a396 sas_expander_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x28cc5a94 sas_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x2bb21683 sas_phy_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x2d45c890 sas_port_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x39906ef7 scsi_is_sas_rphy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x40c81966 sas_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x454c6a40 sas_phy_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x4bcfd5e4 sas_port_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x52bc84a9 sas_rphy_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x5991cdd9 sas_port_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x5b17af4c sas_rphy_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x724e97f4 sas_phy_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x874f8695 sas_read_port_mode_page +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xa95bc781 sas_end_device_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xb02262da sas_port_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xb479e3fd sas_rphy_remove +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xc372949f sas_remove_host +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xc755c453 sas_rphy_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xcfb58002 sas_port_delete_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xda4683f4 scsi_is_sas_port +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xdad4ccfb sas_port_mark_backlink +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xed1b3f07 sas_phy_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xf3a54c1c sas_port_add_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xfbb2d706 sas_remove_children +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x25f2dbb6 spi_display_xfer_agreement +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x3686ea09 spi_print_msg +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x6b63957b spi_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x8ae06afa spi_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0xa55c09b1 spi_dv_device +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0xcbf7e068 spi_schedule_dv_device +EXPORT_SYMBOL drivers/ssb/ssb 0x06a1c592 ssb_bus_suspend +EXPORT_SYMBOL drivers/ssb/ssb 0x0e39198c ssb_device_disable +EXPORT_SYMBOL drivers/ssb/ssb 0x1e92002a ssb_driver_unregister +EXPORT_SYMBOL drivers/ssb/ssb 0x21afa8ef __ssb_driver_register +EXPORT_SYMBOL drivers/ssb/ssb 0x2dc095e1 ssb_clockspeed +EXPORT_SYMBOL drivers/ssb/ssb 0x37aa4682 ssb_device_is_enabled +EXPORT_SYMBOL drivers/ssb/ssb 0x39071ba2 ssb_pcihost_register +EXPORT_SYMBOL drivers/ssb/ssb 0x39be8840 ssb_dma_free_consistent +EXPORT_SYMBOL drivers/ssb/ssb 0x3f45c479 ssb_set_devtypedata +EXPORT_SYMBOL drivers/ssb/ssb 0x52fed7af ssb_bus_powerup +EXPORT_SYMBOL drivers/ssb/ssb 0x636bf571 ssb_dma_translation +EXPORT_SYMBOL drivers/ssb/ssb 0x645d59be ssb_bus_may_powerdown +EXPORT_SYMBOL drivers/ssb/ssb 0x8b9f2773 ssb_device_enable +EXPORT_SYMBOL drivers/ssb/ssb 0x945f94e6 ssb_bus_unregister +EXPORT_SYMBOL drivers/ssb/ssb 0x9e0be4a2 ssb_bus_resume +EXPORT_SYMBOL drivers/ssb/ssb 0xa1193871 ssb_dma_alloc_consistent +EXPORT_SYMBOL drivers/ssb/ssb 0xa7763add ssb_bus_pcibus_register +EXPORT_SYMBOL drivers/ssb/ssb 0xc0512e0f ssb_admatch_base +EXPORT_SYMBOL drivers/ssb/ssb 0xd3005046 ssb_pcicore_dev_irqvecs_enable +EXPORT_SYMBOL drivers/ssb/ssb 0xd481192b ssb_admatch_size +EXPORT_SYMBOL drivers/ssb/ssb 0xe8695ef3 ssb_dma_set_mask +EXPORT_SYMBOL drivers/telephony/ixj 0x7cfeb1eb ixj_pcmcia_probe +EXPORT_SYMBOL drivers/telephony/phonedev 0x6dfa4517 phone_unregister_device +EXPORT_SYMBOL drivers/telephony/phonedev 0x70f9ac5b phone_register_device +EXPORT_SYMBOL drivers/usb/gadget/dummy_hcd 0x1a88923d usb_gadget_unregister_driver +EXPORT_SYMBOL drivers/usb/gadget/dummy_hcd 0x7ab9db0d net2280_set_fifo_mode +EXPORT_SYMBOL drivers/usb/gadget/dummy_hcd 0xdf0bebbf usb_gadget_register_driver +EXPORT_SYMBOL drivers/usb/host/sl811-hcd 0xefd12004 sl811h_driver +EXPORT_SYMBOL drivers/video/backlight/corgi_bl 0xc86baa7c corgibl_limit_intensity +EXPORT_SYMBOL drivers/video/backlight/lcd 0x60440361 lcd_device_unregister +EXPORT_SYMBOL drivers/video/backlight/lcd 0xe5a19e12 lcd_device_register +EXPORT_SYMBOL drivers/video/console/bitblit 0x0a115ce0 fbcon_set_bitops +EXPORT_SYMBOL drivers/video/console/font 0x09c8eb55 font_vga_8x16 +EXPORT_SYMBOL drivers/video/console/font 0xbb99125c get_default_font +EXPORT_SYMBOL drivers/video/console/font 0xf7584a9c find_font +EXPORT_SYMBOL drivers/video/console/softcursor 0x93c59a75 soft_cursor +EXPORT_SYMBOL drivers/video/console/tileblit 0x5fff3630 fbcon_set_tileops +EXPORT_SYMBOL drivers/video/cyber2000fb 0x0cc3ede5 cyber2000fb_detach +EXPORT_SYMBOL drivers/video/cyber2000fb 0x9ed7fbd6 cyber2000fb_disable_extregs +EXPORT_SYMBOL drivers/video/cyber2000fb 0xb9eb1904 cyber2000fb_enable_extregs +EXPORT_SYMBOL drivers/video/cyber2000fb 0xcc28b480 cyber2000fb_attach +EXPORT_SYMBOL drivers/video/cyber2000fb 0xf22fa61b cyber2000fb_get_fb_var +EXPORT_SYMBOL drivers/video/display/display 0x4473724a display_device_register +EXPORT_SYMBOL drivers/video/display/display 0x6f2fbadc display_device_unregister +EXPORT_SYMBOL drivers/video/macmodes 0x08ed0b62 mac_vmode_to_var +EXPORT_SYMBOL drivers/video/macmodes 0x4b088cc4 mac_find_mode +EXPORT_SYMBOL drivers/video/macmodes 0xe2304303 mac_map_monitor_sense +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0x0c8ad82e matroxfb_g450_setpll_cond +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0x597085a9 g450_mnp2f +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0xd6af0980 matroxfb_g450_setclk +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0x9bfdc41a DAC1064_global_restore +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0xc25dbfc7 matrox_mystique +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0xc7b117ca DAC1064_global_init +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0xffc6780d matrox_G100 +EXPORT_SYMBOL drivers/video/matrox/matroxfb_Ti3026 0x8cb90388 matrox_millennium +EXPORT_SYMBOL drivers/video/matrox/matroxfb_accel 0x2b320ad1 matrox_cfbX_init +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0x0933b856 matroxfb_wait_for_sync +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0x3f67c608 matroxfb_enable_irq +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0xb24af8cb matroxfb_register_driver +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0xe90caee4 matroxfb_unregister_driver +EXPORT_SYMBOL drivers/video/matrox/matroxfb_g450 0xf5bfff54 matroxfb_g450_shutdown +EXPORT_SYMBOL drivers/video/matrox/matroxfb_g450 0xfcf5ce3e matroxfb_g450_connect +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x1aed50f6 matroxfb_DAC_in +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x25cf8049 matroxfb_PLL_calcclock +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x2ebafb87 matroxfb_vgaHWinit +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x7fb6f006 matroxfb_read_pins +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x96e91745 matroxfb_DAC_out +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x9f28c1f4 matroxfb_vgaHWrestore +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0xabd8e427 matroxfb_var2my +EXPORT_SYMBOL drivers/video/output 0x19b4508a video_output_register +EXPORT_SYMBOL drivers/video/output 0x2d8502e2 video_output_unregister +EXPORT_SYMBOL drivers/video/sis/sisfb 0x3037658e sis_malloc +EXPORT_SYMBOL drivers/video/sis/sisfb 0x454a3cf0 sis_free +EXPORT_SYMBOL drivers/video/svgalib 0x00d1fce9 svga_set_default_seq_regs +EXPORT_SYMBOL drivers/video/svgalib 0x07b3da30 svga_wseq_multi +EXPORT_SYMBOL drivers/video/svgalib 0x1b95c56a svga_check_timings +EXPORT_SYMBOL drivers/video/svgalib 0x1de3f2c9 svga_tilecursor +EXPORT_SYMBOL drivers/video/svgalib 0x63e898d1 svga_set_default_crt_regs +EXPORT_SYMBOL drivers/video/svgalib 0x7a3ae959 svga_wcrt_multi +EXPORT_SYMBOL drivers/video/svgalib 0x7f4f0c2f svga_tilefill +EXPORT_SYMBOL drivers/video/svgalib 0x80408443 svga_set_timings +EXPORT_SYMBOL drivers/video/svgalib 0x8fa8438b svga_set_textmode_vga_regs +EXPORT_SYMBOL drivers/video/svgalib 0x9f1b70c6 svga_settile +EXPORT_SYMBOL drivers/video/svgalib 0xab3b22ad svga_set_default_gfx_regs +EXPORT_SYMBOL drivers/video/svgalib 0xb17e6cfc svga_get_caps +EXPORT_SYMBOL drivers/video/svgalib 0xc15189ae svga_get_tilemax +EXPORT_SYMBOL drivers/video/svgalib 0xcd935366 svga_tileblit +EXPORT_SYMBOL drivers/video/svgalib 0xdad682b1 svga_set_default_atc_regs +EXPORT_SYMBOL drivers/video/svgalib 0xec83c473 svga_match_format +EXPORT_SYMBOL drivers/video/svgalib 0xef774f5d svga_compute_pll +EXPORT_SYMBOL drivers/video/svgalib 0xf558155b svga_tilecopy +EXPORT_SYMBOL drivers/video/syscopyarea 0xf5f3d5dd sys_copyarea +EXPORT_SYMBOL drivers/video/sysfillrect 0xc242c7ef sys_fillrect +EXPORT_SYMBOL drivers/video/sysimgblt 0xda4611ff sys_imageblit +EXPORT_SYMBOL drivers/video/vgastate 0x686de290 restore_vga +EXPORT_SYMBOL drivers/video/vgastate 0xe7a2620e save_vga +EXPORT_SYMBOL drivers/w1/slaves/w1_bq27000 0x0ef147f8 w1_bq27000_write +EXPORT_SYMBOL drivers/w1/slaves/w1_bq27000 0x30766848 w1_bq27000_read +EXPORT_SYMBOL drivers/w1/slaves/w1_ds2760 0x0c58777b w1_ds2760_read +EXPORT_SYMBOL drivers/w1/slaves/w1_ds2760 0xed26f24f w1_ds2760_write +EXPORT_SYMBOL drivers/w1/wire 0x04692075 w1_register_family +EXPORT_SYMBOL drivers/w1/wire 0x369ebaaf w1_remove_master_device +EXPORT_SYMBOL drivers/w1/wire 0x5e7150e0 w1_unregister_family +EXPORT_SYMBOL drivers/w1/wire 0xd58c0ee8 w1_add_master_device +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0x04e133fc iTCO_vendor_check_noreboot_on +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0x672c9d44 iTCO_vendor_pre_keepalive +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xa78bd894 iTCO_vendor_pre_set_heartbeat +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xa8d6daac iTCO_vendor_pre_start +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xd0efe320 iTCO_vendor_pre_stop +EXPORT_SYMBOL fs/configfs/configfs 0x09eec5b1 configfs_register_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0x26a95739 config_item_set_name +EXPORT_SYMBOL fs/configfs/configfs 0x42b70770 configfs_undepend_item +EXPORT_SYMBOL fs/configfs/configfs 0x6d1cd965 config_item_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0x72125a02 configfs_unregister_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0x7dd0c5f8 config_item_init +EXPORT_SYMBOL fs/configfs/configfs 0x8623b951 configfs_depend_item +EXPORT_SYMBOL fs/configfs/configfs 0xa0c47823 config_item_get +EXPORT_SYMBOL fs/configfs/configfs 0xa4d156a8 config_item_put +EXPORT_SYMBOL fs/configfs/configfs 0xc1344cb1 config_group_init +EXPORT_SYMBOL fs/configfs/configfs 0xe0969648 config_group_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0xf04aa220 config_group_find_item +EXPORT_SYMBOL fs/lockd/lockd 0x6af55eb2 nlmsvc_ops +EXPORT_SYMBOL fs/lockd/lockd 0xa7b91a7b lockd_down +EXPORT_SYMBOL fs/lockd/lockd 0xf6933c48 lockd_up +EXPORT_SYMBOL fs/nfs_common/nfs_acl 0x1c5c47e6 nfsacl_decode +EXPORT_SYMBOL fs/nfs_common/nfs_acl 0xf4b552e6 nfsacl_encode +EXPORT_SYMBOL fs/nfsd/nfsd 0x0f3e6e01 nfs4_acl_nfsv4_to_posix +EXPORT_SYMBOL fs/nfsd/nfsd 0x2095976a nfs4_acl_new +EXPORT_SYMBOL fs/nfsd/nfsd 0x35e33c1e nfs4_acl_write_who +EXPORT_SYMBOL fs/nfsd/nfsd 0x5a157ae4 nfs4_acl_get_whotype +EXPORT_SYMBOL fs/nfsd/nfsd 0x7ee78c79 nfs4_acl_posix_to_nfsv4 +EXPORT_SYMBOL fs/xfs/xfs 0x8c171983 xfs_qmcore_xfs +EXPORT_SYMBOL lib/crc-ccitt 0x3771b461 crc_ccitt +EXPORT_SYMBOL lib/crc-ccitt 0x75811312 crc_ccitt_table +EXPORT_SYMBOL lib/crc-itu-t 0xd29b009f crc_itu_t_table +EXPORT_SYMBOL lib/crc-itu-t 0xf5b4a948 crc_itu_t +EXPORT_SYMBOL lib/crc7 0xa7587646 crc7 +EXPORT_SYMBOL lib/crc7 0xd80c3603 crc7_syndrome_table +EXPORT_SYMBOL lib/libcrc32c 0x2329b292 crc32c_be +EXPORT_SYMBOL lib/libcrc32c 0x37d0b921 crc32c_le +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0x315c65fd zlib_deflateInit2 +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0x48034724 zlib_deflateReset +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xaf64ad0d zlib_deflate +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xf0caf44b zlib_deflate_workspacesize +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xf741c793 zlib_deflateEnd +EXPORT_SYMBOL net/802/p8023 0xc090c20a make_8023_client +EXPORT_SYMBOL net/802/p8023 0xde2a8bc9 destroy_8023_client +EXPORT_SYMBOL net/9p/9pnet 0x0a98d574 p9_client_read +EXPORT_SYMBOL net/9p/9pnet 0x0ecba411 p9_client_remove +EXPORT_SYMBOL net/9p/9pnet 0x17dc20ef v9fs_get_default_trans +EXPORT_SYMBOL net/9p/9pnet 0x1b84afe3 p9_client_destroy +EXPORT_SYMBOL net/9p/9pnet 0x25b98192 p9_client_create +EXPORT_SYMBOL net/9p/9pnet 0x2613cf26 p9_tag_lookup +EXPORT_SYMBOL net/9p/9pnet 0x276ee008 p9_client_attach +EXPORT_SYMBOL net/9p/9pnet 0x335b3d59 p9_client_auth +EXPORT_SYMBOL net/9p/9pnet 0x3455711e p9_idpool_destroy +EXPORT_SYMBOL net/9p/9pnet 0x3d73a797 p9_errstr2errno +EXPORT_SYMBOL net/9p/9pnet 0x42b78736 p9_client_disconnect +EXPORT_SYMBOL net/9p/9pnet 0x47e1034e p9_client_write +EXPORT_SYMBOL net/9p/9pnet 0x4e16a0c8 p9_client_stat +EXPORT_SYMBOL net/9p/9pnet 0x4e863840 p9_client_walk +EXPORT_SYMBOL net/9p/9pnet 0x6b754e6f p9_parse_header +EXPORT_SYMBOL net/9p/9pnet 0x76b79bf1 p9stat_read +EXPORT_SYMBOL net/9p/9pnet 0x8c2cf0e3 v9fs_get_trans_by_name +EXPORT_SYMBOL net/9p/9pnet 0x9992e841 v9fs_unregister_trans +EXPORT_SYMBOL net/9p/9pnet 0x9c964743 p9stat_free +EXPORT_SYMBOL net/9p/9pnet 0x9fd46e71 p9_client_cb +EXPORT_SYMBOL net/9p/9pnet 0xa1b6ae6b p9_client_open +EXPORT_SYMBOL net/9p/9pnet 0xaab8671a p9_idpool_get +EXPORT_SYMBOL net/9p/9pnet 0xb0547f74 p9_client_fcreate +EXPORT_SYMBOL net/9p/9pnet 0xc016aca6 p9_client_clunk +EXPORT_SYMBOL net/9p/9pnet 0xcae61af3 p9_idpool_create +EXPORT_SYMBOL net/9p/9pnet 0xd0cd0ce9 v9fs_register_trans +EXPORT_SYMBOL net/9p/9pnet 0xd0faf92e p9_idpool_check +EXPORT_SYMBOL net/9p/9pnet 0xd331fc1d p9pdu_dump +EXPORT_SYMBOL net/9p/9pnet 0xd8303d55 p9_client_wstat +EXPORT_SYMBOL net/9p/9pnet 0xe46e96c9 p9_client_version +EXPORT_SYMBOL net/9p/9pnet 0xe58a3360 p9_error_init +EXPORT_SYMBOL net/9p/9pnet 0xef7127b0 p9_idpool_put +EXPORT_SYMBOL net/appletalk/appletalk 0x0c19e8c2 aarp_send_ddp +EXPORT_SYMBOL net/appletalk/appletalk 0x1b95a280 atalk_find_dev_addr +EXPORT_SYMBOL net/appletalk/appletalk 0x2320ad5c atrtr_get_dev +EXPORT_SYMBOL net/appletalk/appletalk 0x2df7aaca alloc_ltalkdev +EXPORT_SYMBOL net/ax25/ax25 0x18add2d9 ax25_header_ops +EXPORT_SYMBOL net/ax25/ax25 0x242852b9 ax25_uid_policy +EXPORT_SYMBOL net/ax25/ax25 0x2cdb504d ax25_rebuild_header +EXPORT_SYMBOL net/ax25/ax25 0x33febd7f ax25_send_frame +EXPORT_SYMBOL net/ax25/ax25 0x3d2d82ec ax25_display_timer +EXPORT_SYMBOL net/ax25/ax25 0x4502c65a asc2ax +EXPORT_SYMBOL net/ax25/ax25 0x49ab5314 ax25_findbyuid +EXPORT_SYMBOL net/ax25/ax25 0x53dea1ff ax2asc +EXPORT_SYMBOL net/ax25/ax25 0x6f969a50 ax25_linkfail_register +EXPORT_SYMBOL net/ax25/ax25 0x8ede9e26 ax25_protocol_release +EXPORT_SYMBOL net/ax25/ax25 0xa7809a45 ax25_find_cb +EXPORT_SYMBOL net/ax25/ax25 0xb2b2938d ax25_hard_header +EXPORT_SYMBOL net/ax25/ax25 0xc1444946 ax25cmp +EXPORT_SYMBOL net/ax25/ax25 0xd43ecbf1 null_ax25_address +EXPORT_SYMBOL net/ax25/ax25 0xd82fad88 ax25_listen_release +EXPORT_SYMBOL net/ax25/ax25 0xdcd83bb5 ax25_linkfail_release +EXPORT_SYMBOL net/ax25/ax25 0xeddcdc71 ax25_listen_register +EXPORT_SYMBOL net/bridge/bridge 0xfed3c89b br_should_route_hook +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0x23332c16 ebt_do_table +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0x4909dc20 ebt_unregister_table +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0x8de6d185 ebt_register_table +EXPORT_SYMBOL net/ieee80211/ieee80211 0x177574ea ieee80211_wx_set_encode +EXPORT_SYMBOL net/ieee80211/ieee80211 0x19ab1c26 ieee80211_channel_to_freq +EXPORT_SYMBOL net/ieee80211/ieee80211 0x2a5823f0 ieee80211_get_channel_flags +EXPORT_SYMBOL net/ieee80211/ieee80211 0x343b1eb1 ieee80211_wx_get_encode +EXPORT_SYMBOL net/ieee80211/ieee80211 0x36399230 ieee80211_get_geo +EXPORT_SYMBOL net/ieee80211/ieee80211 0x38a035d2 ieee80211_wx_get_encodeext +EXPORT_SYMBOL net/ieee80211/ieee80211 0x38ea161e ieee80211_wx_get_scan +EXPORT_SYMBOL net/ieee80211/ieee80211 0x3fb5058c ieee80211_set_geo +EXPORT_SYMBOL net/ieee80211/ieee80211 0x544c11f6 alloc_ieee80211 +EXPORT_SYMBOL net/ieee80211/ieee80211 0x563f1b1a ieee80211_wx_set_encodeext +EXPORT_SYMBOL net/ieee80211/ieee80211 0x74da7b9c ieee80211_txb_free +EXPORT_SYMBOL net/ieee80211/ieee80211 0x84b029fe ieee80211_is_valid_channel +EXPORT_SYMBOL net/ieee80211/ieee80211 0xa37e25fa free_ieee80211 +EXPORT_SYMBOL net/ieee80211/ieee80211 0xa7225771 ieee80211_networks_age +EXPORT_SYMBOL net/ieee80211/ieee80211 0xa9fb135f escape_essid +EXPORT_SYMBOL net/ieee80211/ieee80211 0xaca99a54 ieee80211_rx_mgt +EXPORT_SYMBOL net/ieee80211/ieee80211 0xb51725a3 ieee80211_freq_to_channel +EXPORT_SYMBOL net/ieee80211/ieee80211 0xcec47a35 ieee80211_rx +EXPORT_SYMBOL net/ieee80211/ieee80211 0xe23409f1 ieee80211_channel_to_index +EXPORT_SYMBOL net/ieee80211/ieee80211 0xe80f308e ieee80211_get_channel +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x052986db ieee80211_unregister_crypto_ops +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x2049b1a4 ieee80211_crypt_delayed_deinit +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x279e265f ieee80211_crypt_deinit_handler +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x38a404f0 ieee80211_crypt_deinit_entries +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0xaf47f075 ieee80211_crypt_quiescing +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0xb337b0f1 ieee80211_get_crypto_ops +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0xb960919a ieee80211_register_crypto_ops +EXPORT_SYMBOL net/ipv4/inet_lro 0x3bd7f239 lro_flush_all +EXPORT_SYMBOL net/ipv4/inet_lro 0x4046639a lro_vlan_hwaccel_receive_frags +EXPORT_SYMBOL net/ipv4/inet_lro 0x4bc87ad6 lro_receive_frags +EXPORT_SYMBOL net/ipv4/inet_lro 0x7f70be6b lro_vlan_hwaccel_receive_skb +EXPORT_SYMBOL net/ipv4/inet_lro 0xa1fbc9c5 lro_flush_pkt +EXPORT_SYMBOL net/ipv4/inet_lro 0xb72977ca lro_receive_skb +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x16767799 arpt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x4f76dd2e arpt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0xa75253b0 arpt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0x2a60c36f ipt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0x47162347 ipt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0xa8a9284c ipt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x093387d2 nf_nat_setup_info +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x20a95f29 nf_nat_follow_master +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x23d2f7d1 nf_nat_protocol_unregister +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x459310aa nf_nat_mangle_udp_packet +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x5c2a7278 nf_nat_protocol_register +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0xb92a85f0 nf_nat_mangle_tcp_packet +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0xcf5f7ac6 nf_nat_used_tuple +EXPORT_SYMBOL net/ipv4/tunnel4 0xcb73bf15 xfrm4_tunnel_register +EXPORT_SYMBOL net/ipv4/tunnel4 0xd0f20028 xfrm4_tunnel_deregister +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x00e25ff5 ip6t_do_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x62ffd607 ipv6_find_hdr +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x99eab92a ip6t_unregister_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xb8bddf33 ip6t_ext_hdr +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xc1bb0da8 ip6t_register_table +EXPORT_SYMBOL net/ipv6/tunnel6 0x0a484489 xfrm6_tunnel_register +EXPORT_SYMBOL net/ipv6/tunnel6 0x25cd754e xfrm6_tunnel_deregister +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0x9cd013f2 xfrm6_tunnel_alloc_spi +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0xab14e193 xfrm6_tunnel_free_spi +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0xdb1b42d1 xfrm6_tunnel_spi_lookup +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x02a8fa94 ircomm_connect_response +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x368d63b2 ircomm_flow_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x38071d07 ircomm_data_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x5cab06e5 ircomm_connect_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x92cbb855 ircomm_close +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x95f67fa5 ircomm_disconnect_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0xa7f09137 ircomm_control_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0xe2a888f4 ircomm_open +EXPORT_SYMBOL net/irda/irda 0x00dfb06d irttp_disconnect_request +EXPORT_SYMBOL net/irda/irda 0x01d1fcdb hashbin_delete +EXPORT_SYMBOL net/irda/irda 0x06a3ee58 irias_new_integer_value +EXPORT_SYMBOL net/irda/irda 0x072e026f irias_add_octseq_attrib +EXPORT_SYMBOL net/irda/irda 0x07d3647c irlmp_register_service +EXPORT_SYMBOL net/irda/irda 0x1c8ced78 irlmp_connect_response +EXPORT_SYMBOL net/irda/irda 0x2036ad06 irda_param_insert +EXPORT_SYMBOL net/irda/irda 0x20a52af7 iriap_getvaluebyclass_request +EXPORT_SYMBOL net/irda/irda 0x239a94dc iriap_close +EXPORT_SYMBOL net/irda/irda 0x24e2c762 irda_notify_init +EXPORT_SYMBOL net/irda/irda 0x2900b456 irttp_connect_request +EXPORT_SYMBOL net/irda/irda 0x2ff97195 irlmp_close_lsap +EXPORT_SYMBOL net/irda/irda 0x3462950f hashbin_remove +EXPORT_SYMBOL net/irda/irda 0x38a20e5b irda_debug +EXPORT_SYMBOL net/irda/irda 0x3acabd3b irttp_connect_response +EXPORT_SYMBOL net/irda/irda 0x410278d8 irlap_close +EXPORT_SYMBOL net/irda/irda 0x448b8aaa irda_qos_bits_to_value +EXPORT_SYMBOL net/irda/irda 0x46c1c4a2 irlmp_unregister_service +EXPORT_SYMBOL net/irda/irda 0x4d785d6c irlmp_open_lsap +EXPORT_SYMBOL net/irda/irda 0x4e24533e irttp_flow_request +EXPORT_SYMBOL net/irda/irda 0x6758f8ac irias_new_object +EXPORT_SYMBOL net/irda/irda 0x68b7447c hashbin_find +EXPORT_SYMBOL net/irda/irda 0x6b043eba irda_init_max_qos_capabilies +EXPORT_SYMBOL net/irda/irda 0x6ef37839 iriap_open +EXPORT_SYMBOL net/irda/irda 0x7042bc54 irlmp_register_client +EXPORT_SYMBOL net/irda/irda 0x747d6779 irias_delete_object +EXPORT_SYMBOL net/irda/irda 0x74941562 async_wrap_skb +EXPORT_SYMBOL net/irda/irda 0x7621e908 hashbin_insert +EXPORT_SYMBOL net/irda/irda 0x76243bc9 irias_insert_object +EXPORT_SYMBOL net/irda/irda 0x763e54a4 irlmp_unregister_client +EXPORT_SYMBOL net/irda/irda 0x781e2db5 irias_find_object +EXPORT_SYMBOL net/irda/irda 0x7957f728 irlmp_update_client +EXPORT_SYMBOL net/irda/irda 0x7a57b6f3 hashbin_remove_this +EXPORT_SYMBOL net/irda/irda 0x7e7d076b irttp_udata_request +EXPORT_SYMBOL net/irda/irda 0x8501265b irlmp_disconnect_request +EXPORT_SYMBOL net/irda/irda 0x91815586 irda_param_pack +EXPORT_SYMBOL net/irda/irda 0x993ad14b irda_param_extract_all +EXPORT_SYMBOL net/irda/irda 0x9b4dc637 irlap_open +EXPORT_SYMBOL net/irda/irda 0x9fcf1eec alloc_irdadev +EXPORT_SYMBOL net/irda/irda 0xb3c6d951 async_unwrap_char +EXPORT_SYMBOL net/irda/irda 0xb9394173 irias_delete_value +EXPORT_SYMBOL net/irda/irda 0xbcd3ef13 irias_object_change_attribute +EXPORT_SYMBOL net/irda/irda 0xbe40ace9 irlmp_discovery_request +EXPORT_SYMBOL net/irda/irda 0xc1218842 irda_device_set_media_busy +EXPORT_SYMBOL net/irda/irda 0xc14e9b6a hashbin_get_next +EXPORT_SYMBOL net/irda/irda 0xc1f99197 irlmp_connect_request +EXPORT_SYMBOL net/irda/irda 0xc4c2b839 proc_irda +EXPORT_SYMBOL net/irda/irda 0xc5fc4695 irttp_open_tsap +EXPORT_SYMBOL net/irda/irda 0xc81e5c48 irttp_dup +EXPORT_SYMBOL net/irda/irda 0xccc4b7af irttp_close_tsap +EXPORT_SYMBOL net/irda/irda 0xcd41236c hashbin_new +EXPORT_SYMBOL net/irda/irda 0xcfd38b1e irttp_data_request +EXPORT_SYMBOL net/irda/irda 0xd6deeaae irda_setup_dma +EXPORT_SYMBOL net/irda/irda 0xd7172ff4 hashbin_get_first +EXPORT_SYMBOL net/irda/irda 0xd8bfb6d4 hashbin_lock_find +EXPORT_SYMBOL net/irda/irda 0xde4c6b3c irlmp_service_to_hint +EXPORT_SYMBOL net/irda/irda 0xe5260e0e irias_add_integer_attrib +EXPORT_SYMBOL net/irda/irda 0xec41fe7f irias_add_string_attrib +EXPORT_SYMBOL net/irda/irda 0xedd521c2 irlmp_get_discoveries +EXPORT_SYMBOL net/irda/irda 0xf5800be1 irlmp_data_request +EXPORT_SYMBOL net/lapb/lapb 0x10b72594 lapb_setparms +EXPORT_SYMBOL net/lapb/lapb 0x7121d6ad lapb_register +EXPORT_SYMBOL net/lapb/lapb 0x84171180 lapb_data_request +EXPORT_SYMBOL net/lapb/lapb 0x948fabd2 lapb_unregister +EXPORT_SYMBOL net/lapb/lapb 0x9ad803c4 lapb_connect_request +EXPORT_SYMBOL net/lapb/lapb 0xb4412ce8 lapb_disconnect_request +EXPORT_SYMBOL net/lapb/lapb 0xe9bfccbf lapb_data_received +EXPORT_SYMBOL net/lapb/lapb 0xf4104473 lapb_getparms +EXPORT_SYMBOL net/mac80211/mac80211 0x0f1dc4fa __ieee80211_get_rx_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x1754471b ieee80211_stop_tx_ba_cb_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x1bfa037e ieee80211_wake_queue +EXPORT_SYMBOL net/mac80211/mac80211 0x1ed8b08e ieee80211_ctstoself_get +EXPORT_SYMBOL net/mac80211/mac80211 0x1ef00368 ieee80211_queue_stopped +EXPORT_SYMBOL net/mac80211/mac80211 0x205f72b4 __ieee80211_get_radio_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x479a2413 ieee80211_rts_duration +EXPORT_SYMBOL net/mac80211/mac80211 0x51617aeb ieee80211_stop_queue +EXPORT_SYMBOL net/mac80211/mac80211 0x5a222528 __ieee80211_rx +EXPORT_SYMBOL net/mac80211/mac80211 0x5ee587db ieee80211_unregister_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x6bbb4f98 ieee80211_scan_completed +EXPORT_SYMBOL net/mac80211/mac80211 0x6be37750 ieee80211_wake_queues +EXPORT_SYMBOL net/mac80211/mac80211 0x6cecf931 ieee80211_tx_status_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x6d7463e9 ieee80211_rts_get +EXPORT_SYMBOL net/mac80211/mac80211 0x83489bef ieee80211_rate_control_unregister +EXPORT_SYMBOL net/mac80211/mac80211 0x8c35d732 ieee80211_hdrlen +EXPORT_SYMBOL net/mac80211/mac80211 0x955e0c59 ieee80211_find_sta +EXPORT_SYMBOL net/mac80211/mac80211 0x96f371c0 ieee80211_alloc_hw +EXPORT_SYMBOL net/mac80211/mac80211 0xa98b2921 ieee80211_get_buffered_bc +EXPORT_SYMBOL net/mac80211/mac80211 0xab1e5899 ieee80211_beacon_get +EXPORT_SYMBOL net/mac80211/mac80211 0xb187ed09 __ieee80211_get_assoc_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0xba96d2bc ieee80211_tx_status +EXPORT_SYMBOL net/mac80211/mac80211 0xbf8f416d ieee80211_ctstoself_duration +EXPORT_SYMBOL net/mac80211/mac80211 0xc7d77143 ieee80211_get_tkip_key +EXPORT_SYMBOL net/mac80211/mac80211 0xcff99e2e wiphy_to_hw +EXPORT_SYMBOL net/mac80211/mac80211 0xd0ce5217 ieee80211_stop_queues +EXPORT_SYMBOL net/mac80211/mac80211 0xe0532e42 ieee80211_rate_control_register +EXPORT_SYMBOL net/mac80211/mac80211 0xe1d417ee ieee80211_start_tx_ba_cb_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0xe38fc755 ieee80211_register_hw +EXPORT_SYMBOL net/mac80211/mac80211 0xe4fd4bc1 ieee80211_free_hw +EXPORT_SYMBOL net/mac80211/mac80211 0xeb642560 ieee80211_start_tx_ba_session +EXPORT_SYMBOL net/mac80211/mac80211 0xef1b59cc ieee80211_get_hdrlen_from_skb +EXPORT_SYMBOL net/mac80211/mac80211 0xf2a6b78a __ieee80211_get_tx_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0xf2a707b1 ieee80211_stop_tx_ba_session +EXPORT_SYMBOL net/mac80211/mac80211 0xf6f92751 ieee80211_start_tx_ba_cb +EXPORT_SYMBOL net/mac80211/mac80211 0xf78c2c22 ieee80211_generic_frame_duration +EXPORT_SYMBOL net/mac80211/mac80211 0xfd0f2c12 ieee80211_stop_tx_ba_cb +EXPORT_SYMBOL net/mac80211/mac80211 0xfd6fb48b ieee80211_rx_irqsafe +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x54e18015 ip_vs_conn_new +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x585bde9b ip_vs_tcp_conn_listen +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x623076e0 register_ip_vs_scheduler +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x7467e285 register_ip_vs_app +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x7b172319 ip_vs_conn_in_get +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x8d0d6d5e ip_vs_skb_replace +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x95e26da5 register_ip_vs_app_inc +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xa1dbc2d8 ip_vs_proto_name +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xb4c7c8cc unregister_ip_vs_scheduler +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xc6250655 ip_vs_conn_put +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xe1f7eddd unregister_ip_vs_app +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xe3020dfd ip_vs_conn_out_get +EXPORT_SYMBOL net/netfilter/nf_conntrack 0x8fb4ee7a __nf_ct_ext_destroy +EXPORT_SYMBOL net/netfilter/nf_conntrack 0xe372c1b6 __nf_ct_ext_add +EXPORT_SYMBOL net/netfilter/nf_conntrack_proto_gre 0x1ae40c43 nf_ct_gre_keymap_flush +EXPORT_SYMBOL net/netfilter/x_tables 0x25c93bb3 xt_register_matches +EXPORT_SYMBOL net/netfilter/x_tables 0x2941912a xt_register_match +EXPORT_SYMBOL net/netfilter/x_tables 0x35ad5873 xt_unregister_matches +EXPORT_SYMBOL net/netfilter/x_tables 0x3dcd58c5 xt_alloc_table_info +EXPORT_SYMBOL net/netfilter/x_tables 0x72575f8a xt_register_targets +EXPORT_SYMBOL net/netfilter/x_tables 0x74b5fe83 xt_unregister_match +EXPORT_SYMBOL net/netfilter/x_tables 0xb72eeb66 xt_find_match +EXPORT_SYMBOL net/netfilter/x_tables 0xc69cb649 xt_unregister_targets +EXPORT_SYMBOL net/netfilter/x_tables 0xd985dc27 xt_unregister_target +EXPORT_SYMBOL net/netfilter/x_tables 0xe02dc2fe xt_find_target +EXPORT_SYMBOL net/netfilter/x_tables 0xeb629a58 xt_register_target +EXPORT_SYMBOL net/netfilter/x_tables 0xf7037dc6 xt_free_table_info +EXPORT_SYMBOL net/phonet/phonet 0x022380f4 pn_sock_hash +EXPORT_SYMBOL net/phonet/phonet 0x1bcfdf5d pn_sock_get_port +EXPORT_SYMBOL net/phonet/phonet 0x61b9d8b8 pn_sock_unhash +EXPORT_SYMBOL net/phonet/phonet 0x8c48a117 phonet_stream_ops +EXPORT_SYMBOL net/phonet/phonet 0xa5ab2ad4 phonet_proto_unregister +EXPORT_SYMBOL net/phonet/phonet 0xe9024d6e phonet_proto_register +EXPORT_SYMBOL net/phonet/phonet 0xf902d747 phonet_header_ops +EXPORT_SYMBOL net/phonet/phonet 0xff0699cd pn_skb_send +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x075b043c rxrpc_kernel_get_abort_code +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x1021f0ae key_type_rxrpc +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x282cd64b rxrpc_kernel_send_data +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x3d576a0c rxrpc_get_server_data_key +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x3df79e63 rxrpc_kernel_is_data_last +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x58fe4cd4 rxrpc_kernel_begin_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x7941dd4d rxrpc_kernel_accept_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x8d19fa9e rxrpc_kernel_reject_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x9492e10f rxrpc_kernel_data_delivered +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x95101e55 rxrpc_kernel_intercept_rx_messages +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x9819258b rxrpc_kernel_get_error_number +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xa404a35a rxrpc_kernel_abort_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xaaeaeb34 rxrpc_kernel_end_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xdad6d2f0 rxrpc_kernel_free_skb +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xf38d8b79 rxrpc_get_null_key +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x00c52ef5 g_make_token_header +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x01920d15 gss_mech_unregister +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x085361f6 gss_mech_get_by_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x2f0ba2f0 gss_pseudoflavor_to_service +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x47519db7 gss_mech_put +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x4a4e8119 gss_service_to_auth_domain_name +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x854c2a60 gss_mech_get_by_name +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x8d1a827e svcauth_gss_register_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xb5dea7ef g_token_size +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xcf11b978 gss_svc_to_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xda333022 gss_mech_get +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xdbc0518b gss_mech_register +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xedad6468 svcauth_gss_flavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xf8b2ff6e g_verify_token_header +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0093fa2e xdr_enter_page +EXPORT_SYMBOL net/sunrpc/sunrpc 0x05e807a9 xdr_encode_string +EXPORT_SYMBOL net/sunrpc/sunrpc 0x065994f1 xdr_encode_opaque_fixed +EXPORT_SYMBOL net/sunrpc/sunrpc 0x069d34e4 xdr_decode_array2 +EXPORT_SYMBOL net/sunrpc/sunrpc 0x083d7794 xdr_buf_read_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0f668ba9 svc_auth_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x12e280e3 svc_proc_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x17326767 xdr_decode_word +EXPORT_SYMBOL net/sunrpc/sunrpc 0x1d899b8e xdr_init_decode +EXPORT_SYMBOL net/sunrpc/sunrpc 0x1e74a27c cache_purge +EXPORT_SYMBOL net/sunrpc/sunrpc 0x25c56b07 xdr_init_encode +EXPORT_SYMBOL net/sunrpc/sunrpc 0x25c6597f svc_destroy +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2919b156 xdr_decode_string_inplace +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2b5ce146 svc_reserve +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2bae4e6e sunrpc_cache_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2eec63c9 xdr_encode_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0x344c3bcd svc_proc_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0x36bb6de4 auth_domain_find +EXPORT_SYMBOL net/sunrpc/sunrpc 0x39b6c8fd xdr_write_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0x42c5a10a svc_recv +EXPORT_SYMBOL net/sunrpc/sunrpc 0x4370d361 unix_domain_find +EXPORT_SYMBOL net/sunrpc/sunrpc 0x43f3873d xdr_read_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0x46a0300e xdr_shift_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0x50574739 rpc_queue_upcall +EXPORT_SYMBOL net/sunrpc/sunrpc 0x5910a7dd svc_set_num_threads +EXPORT_SYMBOL net/sunrpc/sunrpc 0x5a62019d auth_domain_put +EXPORT_SYMBOL net/sunrpc/sunrpc 0x5b5236f2 auth_domain_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0x5b6160c5 xdr_buf_from_iov +EXPORT_SYMBOL net/sunrpc/sunrpc 0x5c74e911 rpc_mkpipe +EXPORT_SYMBOL net/sunrpc/sunrpc 0x66c70258 xdr_inline_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0x6a001950 xdr_encode_array2 +EXPORT_SYMBOL net/sunrpc/sunrpc 0x6b55b6cc xdr_process_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0x6eea229d svcauth_unix_purge +EXPORT_SYMBOL net/sunrpc/sunrpc 0x71fa908a cache_flush +EXPORT_SYMBOL net/sunrpc/sunrpc 0x75159dd8 svc_exit_thread +EXPORT_SYMBOL net/sunrpc/sunrpc 0x7576dff8 read_bytes_from_xdr_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0x7ced2676 svc_seq_show +EXPORT_SYMBOL net/sunrpc/sunrpc 0x7f59082f rpc_unlink +EXPORT_SYMBOL net/sunrpc/sunrpc 0x8fdf894a sunrpc_cache_update +EXPORT_SYMBOL net/sunrpc/sunrpc 0x90b73cf7 auth_unix_forget_old +EXPORT_SYMBOL net/sunrpc/sunrpc 0x94e6f449 svc_sock_names +EXPORT_SYMBOL net/sunrpc/sunrpc 0x9542dfa5 svcauth_unix_set_client +EXPORT_SYMBOL net/sunrpc/sunrpc 0x9c453824 svc_wake_up +EXPORT_SYMBOL net/sunrpc/sunrpc 0x9e37646e svc_process +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa11619a2 xdr_inline_decode +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa28aeb9b xdr_buf_subsegment +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa5ae64ee svc_authenticate +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa6afff5e cache_check +EXPORT_SYMBOL net/sunrpc/sunrpc 0xaaf56993 cache_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0xaf093129 svc_auth_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0xb3234b72 cache_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0xb6369c60 xdr_encode_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0xb8e46f4a xdr_encode_word +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc33b065d svc_create_pooled +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc3880471 xdr_decode_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc773d8ed svc_prepare_thread +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc8e96dea qword_addhex +EXPORT_SYMBOL net/sunrpc/sunrpc 0xdfe4c81a xdr_reserve_space +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe116d0cf auth_unix_add_addr +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe5919cb1 xdr_encode_opaque +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe979d07c auth_unix_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe97f4ce5 qword_get +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe9be3408 svc_sock_update_bufs +EXPORT_SYMBOL net/sunrpc/sunrpc 0xeb3e410a svc_drop +EXPORT_SYMBOL net/sunrpc/sunrpc 0xedcf6be4 qword_add +EXPORT_SYMBOL net/sunrpc/sunrpc 0xee145992 svc_create +EXPORT_SYMBOL net/sunrpc/sunrpc 0xf9fabdac svc_set_client +EXPORT_SYMBOL net/tipc/tipc 0x005bfae6 tipc_forward_buf2port +EXPORT_SYMBOL net/tipc/tipc 0x08acf310 tipc_available_nodes +EXPORT_SYMBOL net/tipc/tipc 0x10d40fcd tipc_isconnected +EXPORT_SYMBOL net/tipc/tipc 0x1472b270 tipc_disconnect +EXPORT_SYMBOL net/tipc/tipc 0x1479cb03 tipc_deleteport +EXPORT_SYMBOL net/tipc/tipc 0x15b5ecde tipc_set_portunreliable +EXPORT_SYMBOL net/tipc/tipc 0x16f27683 tipc_block_bearer +EXPORT_SYMBOL net/tipc/tipc 0x1e08abe5 tipc_createport_raw +EXPORT_SYMBOL net/tipc/tipc 0x259b74f9 tipc_acknowledge +EXPORT_SYMBOL net/tipc/tipc 0x27d8bb58 tipc_send2port +EXPORT_SYMBOL net/tipc/tipc 0x310d1bc9 tipc_detach +EXPORT_SYMBOL net/tipc/tipc 0x3712e340 tipc_portunreliable +EXPORT_SYMBOL net/tipc/tipc 0x3976041f tipc_set_portimportance +EXPORT_SYMBOL net/tipc/tipc 0x3fdb404f tipc_send_buf2name +EXPORT_SYMBOL net/tipc/tipc 0x4b2243c6 tipc_portimportance +EXPORT_SYMBOL net/tipc/tipc 0x4ba3cfc8 tipc_send2name +EXPORT_SYMBOL net/tipc/tipc 0x538b228a tipc_withdraw +EXPORT_SYMBOL net/tipc/tipc 0x5637ed44 tipc_get_mode +EXPORT_SYMBOL net/tipc/tipc 0x56e52bc1 tipc_continue +EXPORT_SYMBOL net/tipc/tipc 0x5a8dc71b tipc_send_buf2port +EXPORT_SYMBOL net/tipc/tipc 0x5c0d4b5c tipc_ref_valid +EXPORT_SYMBOL net/tipc/tipc 0x62a681a3 tipc_portunreturnable +EXPORT_SYMBOL net/tipc/tipc 0x64357d3c tipc_multicast +EXPORT_SYMBOL net/tipc/tipc 0x7b8d1799 tipc_reject_msg +EXPORT_SYMBOL net/tipc/tipc 0x8001e3d7 tipc_forward2port +EXPORT_SYMBOL net/tipc/tipc 0x88b73627 tipc_get_addr +EXPORT_SYMBOL net/tipc/tipc 0x9063c531 tipc_recv_msg +EXPORT_SYMBOL net/tipc/tipc 0x9c45558e tipc_enable_bearer +EXPORT_SYMBOL net/tipc/tipc 0xa5f730fd tipc_createport +EXPORT_SYMBOL net/tipc/tipc 0xa936a24b tipc_get_port +EXPORT_SYMBOL net/tipc/tipc 0xadd203d0 tipc_connect2port +EXPORT_SYMBOL net/tipc/tipc 0xae0103c3 tipc_shutdown +EXPORT_SYMBOL net/tipc/tipc 0xb01ffc2c tipc_forward2name +EXPORT_SYMBOL net/tipc/tipc 0xb35b672c tipc_publish +EXPORT_SYMBOL net/tipc/tipc 0xbb15572f tipc_send_buf_fast +EXPORT_SYMBOL net/tipc/tipc 0xbb2b2504 tipc_send +EXPORT_SYMBOL net/tipc/tipc 0xcec8514a tipc_set_portunreturnable +EXPORT_SYMBOL net/tipc/tipc 0xd1a519c7 tipc_forward_buf2name +EXPORT_SYMBOL net/tipc/tipc 0xd44731e5 tipc_ownidentity +EXPORT_SYMBOL net/tipc/tipc 0xda7f9d3f tipc_attach +EXPORT_SYMBOL net/tipc/tipc 0xdd34a46d tipc_register_media +EXPORT_SYMBOL net/tipc/tipc 0xdf5008fc tipc_peer +EXPORT_SYMBOL net/tipc/tipc 0xe1a711eb tipc_send_buf +EXPORT_SYMBOL net/tipc/tipc 0xe7aece47 tipc_ispublished +EXPORT_SYMBOL net/tipc/tipc 0xeefd49b3 tipc_get_handle +EXPORT_SYMBOL net/tipc/tipc 0xef50a1ef tipc_disable_bearer +EXPORT_SYMBOL net/wanrouter/wanrouter 0x06dbf23d register_wan_device +EXPORT_SYMBOL net/wanrouter/wanrouter 0x0ebe03d1 unregister_wan_device +EXPORT_SYMBOL net/wireless/cfg80211 0x021d4439 wiphy_unregister +EXPORT_SYMBOL net/wireless/cfg80211 0x07e7ac5a ieee80211_radiotap_iterator_init +EXPORT_SYMBOL net/wireless/cfg80211 0x09c64fbd ieee80211_frequency_to_channel +EXPORT_SYMBOL net/wireless/cfg80211 0x55372e18 wiphy_register +EXPORT_SYMBOL net/wireless/cfg80211 0x6c53f729 regulatory_hint +EXPORT_SYMBOL net/wireless/cfg80211 0xc2927f6e __ieee80211_get_channel +EXPORT_SYMBOL net/wireless/cfg80211 0xc4e85ec5 ieee80211_radiotap_iterator_next +EXPORT_SYMBOL net/wireless/cfg80211 0xccc291b3 ieee80211_channel_to_frequency +EXPORT_SYMBOL net/wireless/cfg80211 0xd34820b4 wiphy_new +EXPORT_SYMBOL net/wireless/cfg80211 0xf47c1b73 wiphy_free +EXPORT_SYMBOL sound/ac97_bus 0xfb83558c ac97_bus_type +EXPORT_SYMBOL sound/core/oss/snd-mixer-oss 0x64c9de5f snd_mixer_oss_ioctl_card +EXPORT_SYMBOL sound/core/seq/snd-seq 0x14c878aa snd_seq_create_kernel_client +EXPORT_SYMBOL sound/core/seq/snd-seq 0x1a724fcc snd_seq_kernel_client_ctl +EXPORT_SYMBOL sound/core/seq/snd-seq 0x3061c52d snd_use_lock_sync_helper +EXPORT_SYMBOL sound/core/seq/snd-seq 0x3fb4d161 snd_seq_kernel_client_dispatch +EXPORT_SYMBOL sound/core/seq/snd-seq 0x539ea57b snd_seq_kernel_client_write_poll +EXPORT_SYMBOL sound/core/seq/snd-seq 0x6bb71038 snd_seq_delete_kernel_client +EXPORT_SYMBOL sound/core/seq/snd-seq 0x7ac2f329 snd_seq_expand_var_event +EXPORT_SYMBOL sound/core/seq/snd-seq 0x7b8699eb snd_seq_event_port_detach +EXPORT_SYMBOL sound/core/seq/snd-seq 0xb8e448a0 snd_seq_set_queue_tempo +EXPORT_SYMBOL sound/core/seq/snd-seq 0xcac0a3be snd_seq_kernel_client_enqueue +EXPORT_SYMBOL sound/core/seq/snd-seq 0xe47a7b16 snd_seq_event_port_attach +EXPORT_SYMBOL sound/core/seq/snd-seq 0xe934da1d snd_seq_dump_var_event +EXPORT_SYMBOL sound/core/seq/snd-seq 0xefbdcf79 snd_seq_kernel_client_enqueue_blocking +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x3a57f235 snd_seq_autoload_unlock +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x492a5df7 snd_seq_device_new +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x6339b6d0 snd_seq_device_load_drivers +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xb90668b2 snd_seq_autoload_lock +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xc622fb29 snd_seq_device_unregister_driver +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xc90dfec4 snd_seq_device_register_driver +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0x6ea09972 snd_midi_channel_alloc_set +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0x833a3e07 snd_midi_channel_set_clear +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0xb9948d2c snd_midi_channel_free_set +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0xf0a1fdb3 snd_midi_process_event +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x17c15809 snd_midi_event_decode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x4ad3f518 snd_midi_event_reset_decode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x62384d3a snd_midi_event_encode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x8a348811 snd_midi_event_reset_encode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x9df7af8b snd_midi_event_free +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xc482499d snd_midi_event_new +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xd9072e1a snd_midi_event_no_status +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xe6df29c7 snd_midi_event_encode_byte +EXPORT_SYMBOL sound/core/seq/snd-seq-virmidi 0x536a5959 snd_virmidi_new +EXPORT_SYMBOL sound/core/snd 0x07e46312 snd_ctl_register_ioctl +EXPORT_SYMBOL sound/core/snd 0x0c0fcad7 snd_unregister_oss_device +EXPORT_SYMBOL sound/core/snd 0x0d08dbf4 snd_ctl_free_one +EXPORT_SYMBOL sound/core/snd 0x101ea90c snd_component_add +EXPORT_SYMBOL sound/core/snd 0x18e1683f snd_dma_program +EXPORT_SYMBOL sound/core/snd 0x191e88cf snd_dma_pointer +EXPORT_SYMBOL sound/core/snd 0x198788b4 snd_lookup_oss_minor_data +EXPORT_SYMBOL sound/core/snd 0x1f19b967 snd_ctl_find_numid +EXPORT_SYMBOL sound/core/snd 0x2049e6ff snd_card_disconnect +EXPORT_SYMBOL sound/core/snd 0x24a94b26 snd_info_get_line +EXPORT_SYMBOL sound/core/snd 0x26e1af1b snd_ctl_rename_id +EXPORT_SYMBOL sound/core/snd 0x2aade57f snd_ctl_boolean_mono_info +EXPORT_SYMBOL sound/core/snd 0x2ae3deaa release_and_free_resource +EXPORT_SYMBOL sound/core/snd 0x2c61339a snd_device_free +EXPORT_SYMBOL sound/core/snd 0x34687c0e snd_ctl_remove +EXPORT_SYMBOL sound/core/snd 0x3540e2bf snd_device_register +EXPORT_SYMBOL sound/core/snd 0x3971b4df snd_ecards_limit +EXPORT_SYMBOL sound/core/snd 0x39cd4849 snd_ctl_find_id +EXPORT_SYMBOL sound/core/snd 0x3aa0a51f snd_ctl_make_virtual_master +EXPORT_SYMBOL sound/core/snd 0x3ce19874 snd_card_proc_new +EXPORT_SYMBOL sound/core/snd 0x4a3ea5c0 snd_request_card +EXPORT_SYMBOL sound/core/snd 0x4acc373f snd_info_create_module_entry +EXPORT_SYMBOL sound/core/snd 0x602c96f0 copy_to_user_fromio +EXPORT_SYMBOL sound/core/snd 0x6397e339 snd_info_create_card_entry +EXPORT_SYMBOL sound/core/snd 0x6745cd2a snd_info_register +EXPORT_SYMBOL sound/core/snd 0x68de334e snd_card_free +EXPORT_SYMBOL sound/core/snd 0x6c141d66 snd_ctl_add +EXPORT_SYMBOL sound/core/snd 0x70c15ac1 snd_dma_disable +EXPORT_SYMBOL sound/core/snd 0x75c9f259 snd_add_device_sysfs_file +EXPORT_SYMBOL sound/core/snd 0x834e6c84 snd_card_free_when_closed +EXPORT_SYMBOL sound/core/snd 0x8df3789f snd_oss_info_register +EXPORT_SYMBOL sound/core/snd 0x8f595b11 snd_major +EXPORT_SYMBOL sound/core/snd 0x8f9fdd99 snd_ctl_unregister_ioctl +EXPORT_SYMBOL sound/core/snd 0x9040e2c1 snd_power_wait +EXPORT_SYMBOL sound/core/snd 0x9b0287dd snd_pci_quirk_lookup +EXPORT_SYMBOL sound/core/snd 0xa0bccb7a snd_card_new +EXPORT_SYMBOL sound/core/snd 0xa53b3814 snd_card_file_add +EXPORT_SYMBOL sound/core/snd 0xaf2abd2c snd_mixer_oss_notify_callback +EXPORT_SYMBOL sound/core/snd 0xb1b20153 snd_ctl_remove_id +EXPORT_SYMBOL sound/core/snd 0xb213fe8b snd_info_get_str +EXPORT_SYMBOL sound/core/snd 0xb2e5ae4a snd_lookup_minor_data +EXPORT_SYMBOL sound/core/snd 0xbcbfb50b snd_seq_root +EXPORT_SYMBOL sound/core/snd 0xc12db712 snd_register_oss_device +EXPORT_SYMBOL sound/core/snd 0xce3ca308 copy_from_user_toio +EXPORT_SYMBOL sound/core/snd 0xd03f6cca snd_info_free_entry +EXPORT_SYMBOL sound/core/snd 0xd63b3042 snd_card_file_remove +EXPORT_SYMBOL sound/core/snd 0xd75b6342 snd_card_register +EXPORT_SYMBOL sound/core/snd 0xdb4297c4 snd_register_device_for_dev +EXPORT_SYMBOL sound/core/snd 0xe0de48d2 snd_unregister_device +EXPORT_SYMBOL sound/core/snd 0xe0e10bae snd_device_new +EXPORT_SYMBOL sound/core/snd 0xe4854cea snd_iprintf +EXPORT_SYMBOL sound/core/snd 0xe4d6bbdf snd_ctl_add_slave +EXPORT_SYMBOL sound/core/snd 0xe882c5dd snd_ctl_boolean_stereo_info +EXPORT_SYMBOL sound/core/snd 0xef4ae5e5 snd_ctl_notify +EXPORT_SYMBOL sound/core/snd 0xfd94377a snd_cards +EXPORT_SYMBOL sound/core/snd 0xfd98be3f snd_ctl_new1 +EXPORT_SYMBOL sound/core/snd-hwdep 0xb504f756 snd_hwdep_new +EXPORT_SYMBOL sound/core/snd-page-alloc 0x0fc33a41 snd_dma_reserve_buf +EXPORT_SYMBOL sound/core/snd-page-alloc 0x3b91f3af snd_free_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0x846710b4 snd_dma_alloc_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0x9abb9712 snd_dma_free_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0xade88e76 snd_malloc_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0xfb3a8515 snd_dma_get_reserved_buf +EXPORT_SYMBOL sound/core/snd-page-alloc 0xfc6629d9 snd_dma_alloc_pages_fallback +EXPORT_SYMBOL sound/core/snd-pcm 0x0137e619 snd_pcm_lib_read +EXPORT_SYMBOL sound/core/snd-pcm 0x01cacd84 snd_pcm_lib_preallocate_pages_for_all +EXPORT_SYMBOL sound/core/snd-pcm 0x0204ebb2 snd_pcm_suspend_all +EXPORT_SYMBOL sound/core/snd-pcm 0x02061a77 snd_pcm_new +EXPORT_SYMBOL sound/core/snd-pcm 0x03c50db1 snd_pcm_hw_refine +EXPORT_SYMBOL sound/core/snd-pcm 0x04cda566 snd_interval_refine +EXPORT_SYMBOL sound/core/snd-pcm 0x119b2bd3 snd_pcm_lib_writev +EXPORT_SYMBOL sound/core/snd-pcm 0x1c3092ad snd_pcm_hw_constraint_minmax +EXPORT_SYMBOL sound/core/snd-pcm 0x1d027e4b snd_pcm_format_signed +EXPORT_SYMBOL sound/core/snd-pcm 0x210a859c snd_pcm_release_substream +EXPORT_SYMBOL sound/core/snd-pcm 0x3796bdcc snd_pcm_format_little_endian +EXPORT_SYMBOL sound/core/snd-pcm 0x3fdfd8f3 snd_pcm_stop +EXPORT_SYMBOL sound/core/snd-pcm 0x44106239 snd_pcm_open_substream +EXPORT_SYMBOL sound/core/snd-pcm 0x47e182f5 snd_pcm_lib_free_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x4a03ca6b snd_pcm_notify +EXPORT_SYMBOL sound/core/snd-pcm 0x4bad38d2 snd_pcm_lib_write +EXPORT_SYMBOL sound/core/snd-pcm 0x4d3bd429 snd_pcm_hw_constraint_step +EXPORT_SYMBOL sound/core/snd-pcm 0x4d9b6d35 snd_pcm_format_size +EXPORT_SYMBOL sound/core/snd-pcm 0x4f816e9b snd_pcm_format_big_endian +EXPORT_SYMBOL sound/core/snd-pcm 0x51f16c64 snd_pcm_lib_preallocate_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x5568c9bf snd_pcm_hw_param_first +EXPORT_SYMBOL sound/core/snd-pcm 0x5cd114e9 snd_pcm_set_sync +EXPORT_SYMBOL sound/core/snd-pcm 0x5e7f4920 snd_pcm_format_set_silence +EXPORT_SYMBOL sound/core/snd-pcm 0x63f51c49 snd_pcm_hw_param_value +EXPORT_SYMBOL sound/core/snd-pcm 0x650f8603 snd_pcm_format_silence_64 +EXPORT_SYMBOL sound/core/snd-pcm 0x68a24153 snd_pcm_format_physical_width +EXPORT_SYMBOL sound/core/snd-pcm 0x6ef8fcd8 snd_pcm_format_linear +EXPORT_SYMBOL sound/core/snd-pcm 0x77b9ccac _snd_pcm_hw_param_setempty +EXPORT_SYMBOL sound/core/snd-pcm 0x79942566 snd_pcm_kernel_ioctl +EXPORT_SYMBOL sound/core/snd-pcm 0x7c7363ec snd_pcm_lib_preallocate_free_for_all +EXPORT_SYMBOL sound/core/snd-pcm 0x8678095b snd_pcm_hw_constraint_ratdens +EXPORT_SYMBOL sound/core/snd-pcm 0x88cc66cc snd_pcm_link_rwlock +EXPORT_SYMBOL sound/core/snd-pcm 0x90359987 snd_pcm_hw_constraint_ratnums +EXPORT_SYMBOL sound/core/snd-pcm 0x92800f22 snd_pcm_mmap_data +EXPORT_SYMBOL sound/core/snd-pcm 0x9459e48b snd_pcm_suspend +EXPORT_SYMBOL sound/core/snd-pcm 0x952d5f21 _snd_pcm_hw_params_any +EXPORT_SYMBOL sound/core/snd-pcm 0x98471499 snd_pcm_new_stream +EXPORT_SYMBOL sound/core/snd-pcm 0x9f003353 snd_pcm_lib_mmap_iomem +EXPORT_SYMBOL sound/core/snd-pcm 0xa61aa028 snd_pcm_format_unsigned +EXPORT_SYMBOL sound/core/snd-pcm 0xad80a438 snd_pcm_hw_constraint_list +EXPORT_SYMBOL sound/core/snd-pcm 0xada5668d snd_pcm_hw_rule_add +EXPORT_SYMBOL sound/core/snd-pcm 0xb9638db4 snd_pcm_rate_to_rate_bit +EXPORT_SYMBOL sound/core/snd-pcm 0xbd1528ba snd_pcm_sgbuf_get_chunk_size +EXPORT_SYMBOL sound/core/snd-pcm 0xc346d5a5 snd_pcm_sgbuf_ops_page +EXPORT_SYMBOL sound/core/snd-pcm 0xc462f352 snd_pcm_period_elapsed +EXPORT_SYMBOL sound/core/snd-pcm 0xcb76081a snd_pcm_hw_constraint_msbits +EXPORT_SYMBOL sound/core/snd-pcm 0xcba79156 snd_pcm_lib_readv +EXPORT_SYMBOL sound/core/snd-pcm 0xcf3e32be snd_pcm_hw_param_last +EXPORT_SYMBOL sound/core/snd-pcm 0xd02a5741 snd_pcm_lib_malloc_pages +EXPORT_SYMBOL sound/core/snd-pcm 0xd0b9b8b8 snd_interval_list +EXPORT_SYMBOL sound/core/snd-pcm 0xd1e70b10 snd_pcm_limit_hw_rates +EXPORT_SYMBOL sound/core/snd-pcm 0xd2c6eb1b snd_pcm_hw_constraint_pow2 +EXPORT_SYMBOL sound/core/snd-pcm 0xda511723 snd_pcm_set_ops +EXPORT_SYMBOL sound/core/snd-pcm 0xdf5d683c snd_pcm_hw_constraint_integer +EXPORT_SYMBOL sound/core/snd-pcm 0xe56a9336 snd_pcm_format_width +EXPORT_SYMBOL sound/core/snd-pcm 0xf3797152 snd_interval_ratnum +EXPORT_SYMBOL sound/core/snd-pcm 0xf6639106 snd_pcm_lib_ioctl +EXPORT_SYMBOL sound/core/snd-rawmidi 0x086d4206 snd_rawmidi_drain_output +EXPORT_SYMBOL sound/core/snd-rawmidi 0x21c5e1ff snd_rawmidi_drop_output +EXPORT_SYMBOL sound/core/snd-rawmidi 0x285872b1 snd_rawmidi_transmit_ack +EXPORT_SYMBOL sound/core/snd-rawmidi 0x2daec104 snd_rawmidi_kernel_write +EXPORT_SYMBOL sound/core/snd-rawmidi 0x3c0887e3 snd_rawmidi_kernel_open +EXPORT_SYMBOL sound/core/snd-rawmidi 0x54cceb9b snd_rawmidi_output_params +EXPORT_SYMBOL sound/core/snd-rawmidi 0x58b5f4a5 snd_rawmidi_set_ops +EXPORT_SYMBOL sound/core/snd-rawmidi 0x64e440c2 snd_rawmidi_receive +EXPORT_SYMBOL sound/core/snd-rawmidi 0x81b514b5 snd_rawmidi_info_select +EXPORT_SYMBOL sound/core/snd-rawmidi 0x8d11a774 snd_rawmidi_transmit_empty +EXPORT_SYMBOL sound/core/snd-rawmidi 0x9961aabf snd_rawmidi_kernel_read +EXPORT_SYMBOL sound/core/snd-rawmidi 0xa3510800 snd_rawmidi_new +EXPORT_SYMBOL sound/core/snd-rawmidi 0xb52cd6fe snd_rawmidi_drain_input +EXPORT_SYMBOL sound/core/snd-rawmidi 0xc1c5f486 snd_rawmidi_transmit_peek +EXPORT_SYMBOL sound/core/snd-rawmidi 0xc3e74b4c snd_rawmidi_kernel_release +EXPORT_SYMBOL sound/core/snd-rawmidi 0xe4c6badf snd_rawmidi_input_params +EXPORT_SYMBOL sound/core/snd-rawmidi 0xec1bac06 snd_rawmidi_transmit +EXPORT_SYMBOL sound/core/snd-timer 0x331734ba snd_timer_pause +EXPORT_SYMBOL sound/core/snd-timer 0x393acc24 snd_timer_continue +EXPORT_SYMBOL sound/core/snd-timer 0x41c43226 snd_timer_new +EXPORT_SYMBOL sound/core/snd-timer 0x4206c812 snd_timer_resolution +EXPORT_SYMBOL sound/core/snd-timer 0x6289dd14 snd_timer_open +EXPORT_SYMBOL sound/core/snd-timer 0x666a148b snd_timer_interrupt +EXPORT_SYMBOL sound/core/snd-timer 0x7711f3bf snd_timer_global_free +EXPORT_SYMBOL sound/core/snd-timer 0x8133bcb9 snd_timer_close +EXPORT_SYMBOL sound/core/snd-timer 0x969b9f24 snd_timer_global_register +EXPORT_SYMBOL sound/core/snd-timer 0xba86ee02 snd_timer_start +EXPORT_SYMBOL sound/core/snd-timer 0xc245f0ef snd_timer_stop +EXPORT_SYMBOL sound/core/snd-timer 0xe09c68db snd_timer_notify +EXPORT_SYMBOL sound/core/snd-timer 0xee33c76c snd_timer_global_new +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0x73c4c993 snd_mpu401_uart_interrupt_tx +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0x8d6d5f41 snd_mpu401_uart_new +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0xfe618b58 snd_mpu401_uart_interrupt +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x05060a19 snd_opl3_regmap +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x081382cb snd_opl3_hwdep_new +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x1e33502a snd_opl3_create +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x2ad14922 snd_opl3_find_patch +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x3efabc3d snd_opl3_load_patch +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x788292db snd_opl3_new +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0xb0166194 snd_opl3_interrupt +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0xb21f85ee snd_opl3_timer_new +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0xce2fb9c0 snd_opl3_reset +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0xf4f5279a snd_opl3_init +EXPORT_SYMBOL sound/drivers/opl4/snd-opl4-lib 0x0253ed40 snd_opl4_create +EXPORT_SYMBOL sound/drivers/opl4/snd-opl4-lib 0x4c2fe80e snd_opl4_write +EXPORT_SYMBOL sound/drivers/opl4/snd-opl4-lib 0x67f5114e snd_opl4_write_memory +EXPORT_SYMBOL sound/drivers/opl4/snd-opl4-lib 0x7d7b1512 snd_opl4_read_memory +EXPORT_SYMBOL sound/drivers/opl4/snd-opl4-lib 0xc4d47c4e snd_opl4_read +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x1cadb14b snd_vx_irq_handler +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x228fe905 snd_vx_free_firmware +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x3c1f1346 snd_vx_load_boot_image +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x6decba78 snd_vx_check_reg_bit +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x86122aba snd_vx_suspend +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xa1cebd3c snd_vx_resume +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xb8f87f2b snd_vx_dsp_boot +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xbcfb9ae0 snd_vx_dsp_load +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xd6c9c9e3 snd_vx_setup_firmware +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xee0a3816 snd_vx_create +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x0bd2878f snd_ak4114_reinit +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x1fcbb49b snd_ak4114_check_rate_and_errors +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x73865684 snd_ak4114_external_rate +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x7cec8341 snd_ak4114_reg_write +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0xa93d5048 snd_ak4114_create +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0xf6452924 snd_ak4114_build +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0x18039411 snd_ak4117_create +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0x4a670bbe snd_ak4117_build +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xa90710e8 snd_ak4117_check_rate_and_errors +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xcf458585 snd_ak4117_external_rate +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xdb232bd9 snd_ak4117_reg_write +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xff9f470d snd_ak4117_reinit +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0x0e9a1b25 snd_akm4xxx_reset +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0x35939f20 snd_akm4xxx_write +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0x5b8842db snd_akm4xxx_build_controls +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0xf41264ac snd_akm4xxx_init +EXPORT_SYMBOL sound/i2c/other/snd-pt2258 0x29c666bf snd_pt2258_build_controls +EXPORT_SYMBOL sound/i2c/other/snd-pt2258 0x41d7d219 snd_pt2258_reset +EXPORT_SYMBOL sound/i2c/other/snd-tea575x-tuner 0x90c437d6 snd_tea575x_init +EXPORT_SYMBOL sound/i2c/other/snd-tea575x-tuner 0xaf236a69 snd_tea575x_exit +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x56220d16 snd_cs8427_iec958_build +EXPORT_SYMBOL sound/i2c/snd-cs8427 0xa82baafd snd_cs8427_iec958_active +EXPORT_SYMBOL sound/i2c/snd-cs8427 0xc1a344b1 snd_cs8427_create +EXPORT_SYMBOL sound/i2c/snd-cs8427 0xc2feb208 snd_cs8427_reg_write +EXPORT_SYMBOL sound/i2c/snd-cs8427 0xfb9de50f snd_cs8427_iec958_pcm +EXPORT_SYMBOL sound/i2c/snd-i2c 0x238dcdcb snd_i2c_probeaddr +EXPORT_SYMBOL sound/i2c/snd-i2c 0x7159bdb5 snd_i2c_readbytes +EXPORT_SYMBOL sound/i2c/snd-i2c 0x71fc228f snd_i2c_device_create +EXPORT_SYMBOL sound/i2c/snd-i2c 0x78c39b7a snd_i2c_device_free +EXPORT_SYMBOL sound/i2c/snd-i2c 0x8053bb94 snd_i2c_bus_create +EXPORT_SYMBOL sound/i2c/snd-i2c 0xa6557b37 snd_i2c_sendbytes +EXPORT_SYMBOL sound/i2c/snd-tea6330t 0x9872ddf5 snd_tea6330t_update_mixer +EXPORT_SYMBOL sound/i2c/snd-tea6330t 0xb52194d4 snd_tea6330t_detect +EXPORT_SYMBOL sound/isa/cs423x/snd-cs4236-lib 0x68ae67ec snd_cs4236_pcm +EXPORT_SYMBOL sound/isa/cs423x/snd-cs4236-lib 0xc3f6736a snd_cs4236_create +EXPORT_SYMBOL sound/isa/cs423x/snd-cs4236-lib 0xedb60344 snd_cs4236_mixer +EXPORT_SYMBOL sound/isa/es1688/snd-es1688-lib 0x6a55c146 snd_es1688_create +EXPORT_SYMBOL sound/isa/es1688/snd-es1688-lib 0x72251fdf snd_es1688_mixer +EXPORT_SYMBOL sound/isa/es1688/snd-es1688-lib 0xc116d012 snd_es1688_pcm +EXPORT_SYMBOL sound/isa/es1688/snd-es1688-lib 0xc8c51168 snd_es1688_mixer_write +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x0144b31f snd_gus_use_dec +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x04e04ffb snd_gf1_delay +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x07aa8d23 snd_gf1_alloc_voice +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x0b7f4f81 snd_gus_create +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x23c7e74f snd_gf1_ctrl_stop +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x241a182b snd_gf1_pcm_new +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x29654f84 snd_gf1_new_mixer +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x3fba0378 snd_gf1_write8 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x40f15d06 snd_gf1_peek +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x46db8d67 snd_gf1_lvol_to_gvol_raw +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x50400f8a snd_gus_dram_write +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x57b272ee snd_gf1_stop_voice +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x58ea573a snd_gf1_write16 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x5bfa2992 snd_gf1_write_addr +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x691b834e snd_gf1_i_look16 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x6f994247 snd_gf1_free_voice +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x76f5bcd0 snd_gf1_rawmidi_new +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x8aadd92f snd_gf1_dram_addr +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x8f38054c snd_gf1_i_write8 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xad21e17e snd_gf1_i_look8 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xbad05a2d snd_gf1_poke +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xc31af61d snd_gf1_mem_alloc +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xc43a5527 snd_gf1_atten_table +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xd2c9aff7 snd_gus_use_inc +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xd85053ba snd_gf1_mem_free +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xdb252880 snd_gf1_mem_xfree +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xe10d5e83 snd_gus_initialize +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xe1fd5d93 snd_gf1_look16 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xeca2dd3e snd_gf1_mem_lock +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xf86dcae0 snd_gf1_translate_freq +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xf963a997 snd_gus_interrupt +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xfa575433 snd_gf1_look8 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xfd8ca52f snd_gus_dram_read +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x0a62927c snd_sbmixer_write +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x39d37f42 snd_sbmixer_suspend +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x4dbfaff1 snd_sbmixer_add_ctl +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x70ff323c snd_sbmixer_new +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x74de1e64 snd_sbmixer_read +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x78a8537f snd_sbdsp_get_byte +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xb65b1fe9 snd_sbmixer_resume +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xba82489e snd_sbdsp_create +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xd3a15b2c snd_sbdsp_reset +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xf4ce04b4 snd_sbdsp_command +EXPORT_SYMBOL sound/isa/sb/snd-sb16-csp 0x99f07085 snd_sb_csp_new +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0x0ba4ef1d snd_sb16dsp_interrupt +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0x72ba0bd2 snd_sb16dsp_get_pcm_ops +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0x8034bc84 snd_sb16dsp_pcm +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0xd449f250 snd_sb16dsp_configure +EXPORT_SYMBOL sound/isa/sb/snd-sb8-dsp 0x258ec651 snd_sb8dsp_midi +EXPORT_SYMBOL sound/isa/sb/snd-sb8-dsp 0x40e48bde snd_sb8dsp_pcm +EXPORT_SYMBOL sound/isa/sb/snd-sb8-dsp 0xbefb5ab0 snd_sb8dsp_interrupt +EXPORT_SYMBOL sound/isa/sb/snd-sb8-dsp 0xf25c1bdd snd_sb8dsp_midi_interrupt +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0x26482c08 snd_emu8000_poke_dw +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0x4232396c snd_emu8000_init_fm +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0x43769178 snd_emu8000_load_chorus_fx +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0x483f3094 snd_emu8000_dma_chan +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0x6e8fb096 snd_emu8000_peek_dw +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0x8977ef74 snd_emu8000_peek +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0x9327ffa2 snd_emu8000_update_equalizer +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0x935c47d9 snd_emu8000_load_reverb_fx +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0xa336c977 snd_emu8000_update_reverb_mode +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0xb706a252 snd_emu8000_update_chorus_mode +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0xc5306a42 snd_emu8000_poke +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x00f39d41 snd_wss_timer +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x01d775b8 snd_wss_put_single +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x06a41d8c snd_wss_get_pcm_ops +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x0ba04774 snd_wss_mixer +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x1b5d58d9 snd_wss_get_single +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x1bd7fcfe snd_wss_in +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x426a8bfd snd_wss_mce_up +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x55799b01 snd_cs4236_ext_out +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x5c3834c9 snd_wss_pcm +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x62d56339 snd_wss_out +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x64e913e1 snd_wss_info_double +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x83e01e09 snd_wss_info_single +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x951eb72d snd_wss_chip_id +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x954f4676 snd_wss_overrange +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x9e5f6eb7 snd_wss_interrupt +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xafe116ff snd_wss_put_double +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xb41c1da2 snd_wss_create +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xb56b3b9e snd_wss_get_double +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xbad4b51f snd_cs4236_ext_in +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xdb5a6302 snd_wss_mce_down +EXPORT_SYMBOL sound/oss/ad1848 0x26c427ee ad1848_detect +EXPORT_SYMBOL sound/oss/ad1848 0x55262c70 probe_ms_sound +EXPORT_SYMBOL sound/oss/ad1848 0x9bf1cc62 ad1848_unload +EXPORT_SYMBOL sound/oss/ad1848 0xb29a9148 unload_ms_sound +EXPORT_SYMBOL sound/oss/ad1848 0xbd61b085 ad1848_init +EXPORT_SYMBOL sound/oss/ad1848 0xc04f6f67 ad1848_control +EXPORT_SYMBOL sound/oss/ad1848 0xc3dfbb28 attach_ms_sound +EXPORT_SYMBOL sound/oss/mpu401 0x0230d742 attach_mpu401 +EXPORT_SYMBOL sound/oss/mpu401 0x5febf284 unload_mpu401 +EXPORT_SYMBOL sound/oss/mpu401 0xd9ec5db4 probe_mpu401 +EXPORT_SYMBOL sound/oss/msnd 0x1186f48f msnd_fifo_read +EXPORT_SYMBOL sound/oss/msnd 0x234f64e0 msnd_register +EXPORT_SYMBOL sound/oss/msnd 0x340a3ddf msnd_init_queue +EXPORT_SYMBOL sound/oss/msnd 0x54230dc1 msnd_fifo_write +EXPORT_SYMBOL sound/oss/msnd 0x5fb94ecb msnd_unregister +EXPORT_SYMBOL sound/oss/msnd 0x6587640b msnd_disable_irq +EXPORT_SYMBOL sound/oss/msnd 0x6601493b msnd_fifo_make_empty +EXPORT_SYMBOL sound/oss/msnd 0x8e3c524b msnd_send_dsp_cmd +EXPORT_SYMBOL sound/oss/msnd 0x9274d677 msnd_fifo_free +EXPORT_SYMBOL sound/oss/msnd 0x95d37486 msnd_upload_host +EXPORT_SYMBOL sound/oss/msnd 0xa1bcc420 msnd_send_word +EXPORT_SYMBOL sound/oss/msnd 0xade99e25 msnd_fifo_alloc +EXPORT_SYMBOL sound/oss/msnd 0xb3520772 msnd_fifo_init +EXPORT_SYMBOL sound/oss/msnd 0xdf0f59eb msnd_fifo_write_io +EXPORT_SYMBOL sound/oss/msnd 0xefdd1843 msnd_enable_irq +EXPORT_SYMBOL sound/oss/msnd 0xf4c4f662 msnd_fifo_read_io +EXPORT_SYMBOL sound/oss/sb_lib 0x42424109 sb_be_quiet +EXPORT_SYMBOL sound/oss/sb_lib 0x450f9aea smw_free +EXPORT_SYMBOL sound/oss/sb_lib 0x74afd69c unload_sbmpu +EXPORT_SYMBOL sound/oss/sb_lib 0xc2928a14 sb_dsp_init +EXPORT_SYMBOL sound/oss/sb_lib 0xc4884969 sb_dsp_unload +EXPORT_SYMBOL sound/oss/sb_lib 0xd8a2731c sb_dsp_detect +EXPORT_SYMBOL sound/oss/sb_lib 0xff1ce503 probe_sbmpu +EXPORT_SYMBOL sound/oss/sound 0x04c87ec8 compute_finetune +EXPORT_SYMBOL sound/oss/sound 0x06339815 sound_unload_synthdev +EXPORT_SYMBOL sound/oss/sound 0x0bee83e9 mixer_devs +EXPORT_SYMBOL sound/oss/sound 0x0f280035 conf_printf +EXPORT_SYMBOL sound/oss/sound 0x17ba231d seq_input_event +EXPORT_SYMBOL sound/oss/sound 0x191a85e3 sound_timer_devs +EXPORT_SYMBOL sound/oss/sound 0x1b3df3cf sound_alloc_mixerdev +EXPORT_SYMBOL sound/oss/sound 0x1f395686 MIDIbuf_avail +EXPORT_SYMBOL sound/oss/sound 0x2161d5e8 sound_timer_init +EXPORT_SYMBOL sound/oss/sound 0x2aa31695 midi_synth_kill_note +EXPORT_SYMBOL sound/oss/sound 0x36664bda midi_devs +EXPORT_SYMBOL sound/oss/sound 0x394cb088 sound_free_dma +EXPORT_SYMBOL sound/oss/sound 0x418f5fbe sound_close_dma +EXPORT_SYMBOL sound/oss/sound 0x4cd01bdd num_audiodevs +EXPORT_SYMBOL sound/oss/sound 0x4ff47e9d midi_synth_setup_voice +EXPORT_SYMBOL sound/oss/sound 0x51e354b2 sound_alloc_timerdev +EXPORT_SYMBOL sound/oss/sound 0x56504ca2 midi_synth_reset +EXPORT_SYMBOL sound/oss/sound 0x5d986fc9 note_to_freq +EXPORT_SYMBOL sound/oss/sound 0x62841fd8 synth_devs +EXPORT_SYMBOL sound/oss/sound 0x7327e401 audio_devs +EXPORT_SYMBOL sound/oss/sound 0x7679ee76 seq_copy_to_input +EXPORT_SYMBOL sound/oss/sound 0x7bdf0907 conf_printf2 +EXPORT_SYMBOL sound/oss/sound 0x892093e0 midi_synth_controller +EXPORT_SYMBOL sound/oss/sound 0x90bd9714 sequencer_timer +EXPORT_SYMBOL sound/oss/sound 0x987bcf12 DMAbuf_outputintr +EXPORT_SYMBOL sound/oss/sound 0x9a4afdb7 sound_install_mixer +EXPORT_SYMBOL sound/oss/sound 0x9a95733f sound_alloc_dma +EXPORT_SYMBOL sound/oss/sound 0x9bdaf24d midi_synth_start_note +EXPORT_SYMBOL sound/oss/sound 0x9d845b18 num_mixers +EXPORT_SYMBOL sound/oss/sound 0xa1d5f04f load_mixer_volumes +EXPORT_SYMBOL sound/oss/sound 0xa1eae7cf num_midis +EXPORT_SYMBOL sound/oss/sound 0xa41ead5f sound_unload_timerdev +EXPORT_SYMBOL sound/oss/sound 0xa50b0378 sound_install_audiodrv +EXPORT_SYMBOL sound/oss/sound 0xa51c913b sound_unload_mixerdev +EXPORT_SYMBOL sound/oss/sound 0xa6bb414c sound_unload_mididev +EXPORT_SYMBOL sound/oss/sound 0xa948751e sound_unload_audiodev +EXPORT_SYMBOL sound/oss/sound 0xad45df73 midi_synth_close +EXPORT_SYMBOL sound/oss/sound 0xaef743b2 midi_synth_ioctl +EXPORT_SYMBOL sound/oss/sound 0xb14b22cd midi_synth_hw_control +EXPORT_SYMBOL sound/oss/sound 0xb51587f6 do_midi_msg +EXPORT_SYMBOL sound/oss/sound 0xba413f87 sound_alloc_mididev +EXPORT_SYMBOL sound/oss/sound 0xba7dd041 midi_synth_bender +EXPORT_SYMBOL sound/oss/sound 0xc748d109 sound_alloc_synthdev +EXPORT_SYMBOL sound/oss/sound 0xcc4b8797 sound_open_dma +EXPORT_SYMBOL sound/oss/sound 0xd85be938 midi_synth_set_instr +EXPORT_SYMBOL sound/oss/sound 0xdb400afa midi_synth_panning +EXPORT_SYMBOL sound/oss/sound 0xe056b71c DMAbuf_start_dma +EXPORT_SYMBOL sound/oss/sound 0xe2675a79 sound_timer_interrupt +EXPORT_SYMBOL sound/oss/sound 0xeb315d99 DMAbuf_inputintr +EXPORT_SYMBOL sound/oss/sound 0xf1ea8a20 midi_synth_aftertouch +EXPORT_SYMBOL sound/oss/sound 0xf6b3a2fb midi_synth_open +EXPORT_SYMBOL sound/oss/sound 0xf7426da3 midi_synth_load_patch +EXPORT_SYMBOL sound/oss/sound 0xf78f6363 sequencer_init +EXPORT_SYMBOL sound/oss/sound 0xfa6871be sound_timer_syncinterval +EXPORT_SYMBOL sound/oss/sound 0xfddcbfb3 midi_synth_send_sysex +EXPORT_SYMBOL sound/oss/uart401 0x46248c57 uart401intr +EXPORT_SYMBOL sound/oss/uart401 0x55f3f2c0 probe_uart401 +EXPORT_SYMBOL sound/oss/uart401 0xecfdd9c9 unload_uart401 +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x07d0491b snd_ac97_update +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x135df60d snd_ac97_pcm_assign +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x2ab265d7 snd_ac97_update_power +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x2e47ca64 snd_ac97_mixer +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x4f834053 snd_ac97_resume +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x51a419bc snd_ac97_update_bits +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x54685988 snd_ac97_bus +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x9076e26d snd_ac97_pcm_open +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xb2291c60 snd_ac97_write_cache +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xb7e0931a snd_ac97_tune_hardware +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xbfcf3d42 snd_ac97_read +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xc092bd10 snd_ac97_get_short_name +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xc113b470 snd_ac97_write +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xdc43423d snd_ac97_pcm_double_rate_rules +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xea07c171 snd_ac97_pcm_close +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xf276018e snd_ac97_set_rate +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xffff44f4 snd_ac97_suspend +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x1547f386 snd_emu10k1_synth_free +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x19ea1155 snd_emu10k1_synth_alloc +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x3a8529b7 snd_emu10k1_ptr_write +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x446252b3 snd_emu10k1_ptr_read +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x64bd75c6 snd_emu10k1_voice_free +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x6dfebe1c snd_emu10k1_synth_copy_from_user +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x9ee7eba4 snd_emu10k1_voice_alloc +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xc2629908 snd_emu10k1_memblk_map +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xf2e33385 snd_emu10k1_synth_bzero +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0x2b8b4349 snd_ice1712_akm4xxx_build_controls +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0x52ca75b7 snd_ice1712_akm4xxx_init +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0x87e74b30 snd_ice1712_akm4xxx_free +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x004e60bb oxygen_reset_uart +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x0243c9e7 oxygen_read32 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x0ca23b7e oxygen_pci_suspend +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x16a9b308 oxygen_write_spi +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x1c0803a6 oxygen_pci_probe +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x3ddc34bc oxygen_write32_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x48613def oxygen_write_uart +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x7fc9f892 oxygen_write_i2c +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x8e9689f6 oxygen_write32 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x90ab4b7d oxygen_write8 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x97b67c1a oxygen_pci_resume +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x97c2bca5 oxygen_write16_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xa11392b6 oxygen_write16 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xa86fe3d3 oxygen_read_ac97 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xad3bc982 oxygen_read8 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xb31f0037 oxygen_write_ac97_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xd914aa38 oxygen_write_ac97 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xf493e979 oxygen_pci_remove +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xf5eebd86 oxygen_read16 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xfabaf40d oxygen_write8_masked +EXPORT_SYMBOL sound/pci/trident/snd-trident 0x1866124b snd_trident_start_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0x41eb318d snd_trident_free_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0xc19a3161 snd_trident_alloc_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0xc698cbdd snd_trident_write_voice_regs +EXPORT_SYMBOL sound/pci/trident/snd-trident 0xcc6f9ab0 snd_trident_stop_voice +EXPORT_SYMBOL sound/sound_firmware 0x39e3dd23 mod_firmware_load +EXPORT_SYMBOL sound/soundcore 0x028db83a register_sound_special_device +EXPORT_SYMBOL sound/soundcore 0x30b79201 register_sound_special +EXPORT_SYMBOL sound/soundcore 0x50d5aee5 register_sound_mixer +EXPORT_SYMBOL sound/soundcore 0x7afc9d8a unregister_sound_mixer +EXPORT_SYMBOL sound/soundcore 0x910a037e register_sound_dsp +EXPORT_SYMBOL sound/soundcore 0x99c95fa5 unregister_sound_special +EXPORT_SYMBOL sound/soundcore 0xc80c1045 register_sound_midi +EXPORT_SYMBOL sound/soundcore 0xcd083b10 unregister_sound_dsp +EXPORT_SYMBOL sound/soundcore 0xf82ab2f2 sound_class +EXPORT_SYMBOL sound/soundcore 0xfdab6de3 unregister_sound_midi +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x1acebb01 snd_emux_lock_voice +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x655cb202 snd_sf_linear_to_log +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x89fcb7ee snd_emux_free +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x96449317 snd_emux_terminate_all +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0xc34e5329 snd_emux_unlock_voice +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0xdbbd3272 snd_emux_register +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0xf15404f2 snd_emux_new +EXPORT_SYMBOL sound/synth/snd-util-mem 0x20d65978 snd_util_memhdr_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0x24886293 __snd_util_mem_alloc +EXPORT_SYMBOL sound/synth/snd-util-mem 0x569d614e snd_util_mem_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0x7a007343 snd_util_memhdr_new +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd197c5db __snd_util_memblk_new +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd34b56e4 __snd_util_mem_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd8b55e81 snd_util_mem_alloc +EXPORT_SYMBOL sound/synth/snd-util-mem 0xf158252c snd_util_mem_avail +EXPORT_SYMBOL sound/usb/snd-usb-lib 0x16756dc0 snd_usbmidi_input_start +EXPORT_SYMBOL sound/usb/snd-usb-lib 0x63343b1d snd_usbmidi_input_stop +EXPORT_SYMBOL sound/usb/snd-usb-lib 0xca3a0e40 snd_usb_create_midi_interface +EXPORT_SYMBOL sound/usb/snd-usb-lib 0xd9d2bb03 snd_usbmidi_disconnect +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x3541cd28 dm_mem_cache_alloc +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x3d9b762d dm_mem_cache_client_destroy +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x5ef875d9 dm_mem_cache_shrink +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x613cce2f dm_mem_cache_client_create +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x66941b42 dm_mem_cache_grow +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xbdcabaf3 dm_mem_cache_free +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-message 0x920a7a41 dm_message_parse +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x0329d132 rh_sector_to_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x071ba874 rh_delay +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x108f2649 rh_dec +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x275fdd04 rh_recovery_start +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x37ba31fe rh_init +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x5c2a0632 rh_recovery_end +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x62842029 rh_flush +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x8252ef05 rh_state +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x8821f9a7 rh_region_to_sector +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xa045ea28 rh_delay_by_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xa4a7321f rh_get_region_key +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xa923d788 rh_start_recovery +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xac274ed3 rh_stop_recovery +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xb513be98 rh_update_states +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xbb748327 rh_reg_set_context +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc4fdf256 rh_recovery_prepare +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc4ff7745 rh_reg_get_context +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc57bafec rh_exit +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xd99f0978 rh_inc +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xda581f7b rh_get_region_size +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xdd661695 rh_inc_pending +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xf6f56ea2 rh_bio_to_region +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x29c887a9 set_tx_channels +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x60b2e316 cmdir_read +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x7789312a cmdir_write +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0x9282e30e lirc_register_plugin +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0x9c1332f0 lirc_get_pdata +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0xe96379eb lirc_unregister_plugin +EXPORT_SYMBOL ubuntu/misc/media/ov511/ov511 0x7db9be3c ov511_deregister_decomp_module +EXPORT_SYMBOL ubuntu/misc/media/ov511/ov511 0xbf3ebe36 ov511_register_decomp_module +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x075c8ca1 wlan_unsetup +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x165f76cf p80211skb_free +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x1cd50203 p80211netdev_rx +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x2aca7867 p80211wext_event_associated +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x2b943f12 p80211skb_rxmeta_attach +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x3f5966e1 register_wlandev +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x4767bc2c p80211_allow_ioctls +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x48b79742 p80211_resume +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x680996c9 unregister_wlandev +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xb0af0799 wlan_wext_write +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xbffa17d5 p80211_suspend +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xd3e82267 p80211netdev_hwremoved +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xff57ec15 wlan_setup +EXPORT_SYMBOL vmlinux 0x00000000 per_cpu__softirq_work_list +EXPORT_SYMBOL vmlinux 0x0000f396 submit_bh +EXPORT_SYMBOL vmlinux 0x00112f51 groups_alloc +EXPORT_SYMBOL vmlinux 0x0026f148 mnt_pin +EXPORT_SYMBOL vmlinux 0x00701c0f put_io_context +EXPORT_SYMBOL vmlinux 0x00801678 flush_scheduled_work +EXPORT_SYMBOL vmlinux 0x0080fcd6 tcf_hash_release +EXPORT_SYMBOL vmlinux 0x0087659a scsi_get_host_dev +EXPORT_SYMBOL vmlinux 0x00920163 dma_alloc_from_coherent +EXPORT_SYMBOL vmlinux 0x009d258f _write_lock +EXPORT_SYMBOL vmlinux 0x00e8097b csum_partial_copy_fromiovecend +EXPORT_SYMBOL vmlinux 0x00f89e51 xfrm6_find_1stfragopt +EXPORT_SYMBOL vmlinux 0x01139ffc max_mapnr +EXPORT_SYMBOL vmlinux 0x01173790 invalidate_bdev +EXPORT_SYMBOL vmlinux 0x0121d2a9 block_truncate_page +EXPORT_SYMBOL vmlinux 0x0125caad get_write_access +EXPORT_SYMBOL vmlinux 0x0165de3b read_cache_page +EXPORT_SYMBOL vmlinux 0x0186d073 percpu_counter_set +EXPORT_SYMBOL vmlinux 0x01902adf netpoll_trap +EXPORT_SYMBOL vmlinux 0x01a4aab6 set_irq_chip_data +EXPORT_SYMBOL vmlinux 0x01d19038 acpi_enable_subsystem +EXPORT_SYMBOL vmlinux 0x01e38357 scsi_dma_map +EXPORT_SYMBOL vmlinux 0x01ef5510 rt6_lookup +EXPORT_SYMBOL vmlinux 0x02124474 ip_send_check +EXPORT_SYMBOL vmlinux 0x02125e04 journal_extend +EXPORT_SYMBOL vmlinux 0x02138f9d bioset_integrity_create +EXPORT_SYMBOL vmlinux 0x0237b57a arch_unregister_cpu +EXPORT_SYMBOL vmlinux 0x023ca4a3 __dev_get_by_name +EXPORT_SYMBOL vmlinux 0x025277f6 profile_pc +EXPORT_SYMBOL vmlinux 0x0256389f bit_waitqueue +EXPORT_SYMBOL vmlinux 0x02649054 security_sock_rcv_skb +EXPORT_SYMBOL vmlinux 0x027128d3 sync_inode +EXPORT_SYMBOL vmlinux 0x02740802 tcp_splice_read +EXPORT_SYMBOL vmlinux 0x029319cb mca_bus_type +EXPORT_SYMBOL vmlinux 0x029444f0 native_read_tsc +EXPORT_SYMBOL vmlinux 0x02a18c74 nf_conntrack_destroy +EXPORT_SYMBOL vmlinux 0x02a6ce5a crc16_table +EXPORT_SYMBOL vmlinux 0x02aff2f4 acpi_install_gpe_handler +EXPORT_SYMBOL vmlinux 0x02d14144 vm_get_page_prot +EXPORT_SYMBOL vmlinux 0x02d81845 audit_log_task_context +EXPORT_SYMBOL vmlinux 0x02e1cd41 cfb_fillrect +EXPORT_SYMBOL vmlinux 0x02ee26c1 free_pages_exact +EXPORT_SYMBOL vmlinux 0x0328f46d xfrm_state_lookup +EXPORT_SYMBOL vmlinux 0x032b7528 bdi_unregister +EXPORT_SYMBOL vmlinux 0x0334da4e scsi_command_size_tbl +EXPORT_SYMBOL vmlinux 0x037a0cba kfree +EXPORT_SYMBOL vmlinux 0x037a29da dev_set_allmulti +EXPORT_SYMBOL vmlinux 0x037e6785 scsi_free_host_dev +EXPORT_SYMBOL vmlinux 0x03a99c3b rb_prev +EXPORT_SYMBOL vmlinux 0x03b03df9 dma_pool_alloc +EXPORT_SYMBOL vmlinux 0x03c06156 bitmap_fold +EXPORT_SYMBOL vmlinux 0x03f72731 __netdev_alloc_skb +EXPORT_SYMBOL vmlinux 0x03fcf11e vfs_statfs +EXPORT_SYMBOL vmlinux 0x03fcfe5b kobject_init +EXPORT_SYMBOL vmlinux 0x03fd2571 vm_unmap_ram +EXPORT_SYMBOL vmlinux 0x04112916 is_container_init +EXPORT_SYMBOL vmlinux 0x0422fe4a inet_csk_timer_bug_msg +EXPORT_SYMBOL vmlinux 0x043d5eb8 bio_endio +EXPORT_SYMBOL vmlinux 0x044fbf49 mempool_kzalloc +EXPORT_SYMBOL vmlinux 0x045fccf1 dev_get_flags +EXPORT_SYMBOL vmlinux 0x0460aa4c datagram_poll +EXPORT_SYMBOL vmlinux 0x04688794 in_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0x0487f831 fb_find_best_display +EXPORT_SYMBOL vmlinux 0x049692d0 lock_may_read +EXPORT_SYMBOL vmlinux 0x04996902 fget +EXPORT_SYMBOL vmlinux 0x04d8c750 release_perfctr_nmi +EXPORT_SYMBOL vmlinux 0x0504ab3a rtnl_notify +EXPORT_SYMBOL vmlinux 0x05324ee9 dev_queue_xmit +EXPORT_SYMBOL vmlinux 0x054dfb53 pci_find_capability +EXPORT_SYMBOL vmlinux 0x0560cdeb xfrm_state_flush +EXPORT_SYMBOL vmlinux 0x0563d251 __lookup_hash +EXPORT_SYMBOL vmlinux 0x05672814 pci_bus_find_capability +EXPORT_SYMBOL vmlinux 0x0577b826 sock_common_recvmsg +EXPORT_SYMBOL vmlinux 0x057ce975 hex_dump_to_buffer +EXPORT_SYMBOL vmlinux 0x057ff5da mca_device_transform_memory +EXPORT_SYMBOL vmlinux 0x05822cb7 call_usermodehelper_setup +EXPORT_SYMBOL vmlinux 0x058366c6 tcf_em_unregister +EXPORT_SYMBOL vmlinux 0x058c75d9 acpi_get_pci_id +EXPORT_SYMBOL vmlinux 0x05bc1f3e proc_doulongvec_minmax +EXPORT_SYMBOL vmlinux 0x05e28d43 __first_cpu +EXPORT_SYMBOL vmlinux 0x05ed249a pcie_set_readrq +EXPORT_SYMBOL vmlinux 0x0615ed39 cdev_add +EXPORT_SYMBOL vmlinux 0x061651be strcat +EXPORT_SYMBOL vmlinux 0x0616f20c hci_free_dev +EXPORT_SYMBOL vmlinux 0x063da332 journal_init_inode +EXPORT_SYMBOL vmlinux 0x0657b0dc arp_send +EXPORT_SYMBOL vmlinux 0x0672ac82 vfs_get_dqinfo +EXPORT_SYMBOL vmlinux 0x067bbed8 blk_queue_max_segment_size +EXPORT_SYMBOL vmlinux 0x067d823a journal_destroy +EXPORT_SYMBOL vmlinux 0x067d8d35 security_release_secctx +EXPORT_SYMBOL vmlinux 0x067e786c vfs_set_dqblk +EXPORT_SYMBOL vmlinux 0x068c7263 ioremap_cache +EXPORT_SYMBOL vmlinux 0x0692f390 rfkill_free +EXPORT_SYMBOL vmlinux 0x06a0a192 kmap +EXPORT_SYMBOL vmlinux 0x06d52625 xfrm_state_delete +EXPORT_SYMBOL vmlinux 0x06d728b1 tcp_parse_md5sig_option +EXPORT_SYMBOL vmlinux 0x06ec31e3 kernel_sendpage +EXPORT_SYMBOL vmlinux 0x06fe3b14 default_grn +EXPORT_SYMBOL vmlinux 0x07070d9b mpage_writepages +EXPORT_SYMBOL vmlinux 0x07178a77 mca_device_set_name +EXPORT_SYMBOL vmlinux 0x0727c4f3 iowrite8 +EXPORT_SYMBOL vmlinux 0x073dfa12 generate_resume_trace +EXPORT_SYMBOL vmlinux 0x074f5de7 force_sig +EXPORT_SYMBOL vmlinux 0x07608604 acpi_get_vendor_resource +EXPORT_SYMBOL vmlinux 0x078266c4 llc_sap_find +EXPORT_SYMBOL vmlinux 0x078f804e pcie_get_readrq +EXPORT_SYMBOL vmlinux 0x07960700 pci_get_class +EXPORT_SYMBOL vmlinux 0x0799aca4 local_bh_enable +EXPORT_SYMBOL vmlinux 0x079cd7f1 ns_to_timeval +EXPORT_SYMBOL vmlinux 0x07a890c8 fb_alloc_cmap +EXPORT_SYMBOL vmlinux 0x07c5d54b __alloc_pages_internal +EXPORT_SYMBOL vmlinux 0x07cc4a5d printk_timed_ratelimit +EXPORT_SYMBOL vmlinux 0x07d50a24 csum_partial +EXPORT_SYMBOL vmlinux 0x07d9b783 scsi_nl_send_vendor_msg +EXPORT_SYMBOL vmlinux 0x07fe981d fb_find_mode +EXPORT_SYMBOL vmlinux 0x08054bc3 dquot_mark_dquot_dirty +EXPORT_SYMBOL vmlinux 0x08071850 scsi_register_driver +EXPORT_SYMBOL vmlinux 0x082c3213 pci_root_buses +EXPORT_SYMBOL vmlinux 0x083fb539 elv_queue_empty +EXPORT_SYMBOL vmlinux 0x08790e6a per_cpu__cpu_info +EXPORT_SYMBOL vmlinux 0x089466dc bt_sock_recvmsg +EXPORT_SYMBOL vmlinux 0x089fc770 blk_requeue_request +EXPORT_SYMBOL vmlinux 0x08ab2efd icmp_send +EXPORT_SYMBOL vmlinux 0x08ac66d9 pcie_port_service_unregister +EXPORT_SYMBOL vmlinux 0x08b3299f acpi_lock_battery_dir +EXPORT_SYMBOL vmlinux 0x08d41e79 bio_integrity_alloc_bioset +EXPORT_SYMBOL vmlinux 0x08f06feb blk_rq_count_integrity_sg +EXPORT_SYMBOL vmlinux 0x08f6348c page_symlink_inode_operations +EXPORT_SYMBOL vmlinux 0x08ff2852 unmap_underlying_metadata +EXPORT_SYMBOL vmlinux 0x09240286 block_page_mkwrite +EXPORT_SYMBOL vmlinux 0x0933aae1 efi_enabled +EXPORT_SYMBOL vmlinux 0x093e947e posix_acl_create_masq +EXPORT_SYMBOL vmlinux 0x0948cde9 num_physpages +EXPORT_SYMBOL vmlinux 0x096372c6 ethtool_op_set_sg +EXPORT_SYMBOL vmlinux 0x0966da5a vfs_quota_on_path +EXPORT_SYMBOL vmlinux 0x09775cdc kref_get +EXPORT_SYMBOL vmlinux 0x098b71c6 fb_dealloc_cmap +EXPORT_SYMBOL vmlinux 0x09c55cec schedule_timeout_interruptible +EXPORT_SYMBOL vmlinux 0x09d2dcf1 bio_add_pc_page +EXPORT_SYMBOL vmlinux 0x09d44df9 in_lock_functions +EXPORT_SYMBOL vmlinux 0x0a2487e0 unblock_all_signals +EXPORT_SYMBOL vmlinux 0x0a3131f6 strnchr +EXPORT_SYMBOL vmlinux 0x0a447c8d test_set_page_writeback +EXPORT_SYMBOL vmlinux 0x0a48c6c9 default_llseek +EXPORT_SYMBOL vmlinux 0x0a528e4b acpi_get_physical_pci_device +EXPORT_SYMBOL vmlinux 0x0a561e20 sock_no_recvmsg +EXPORT_SYMBOL vmlinux 0x0a63a3d4 unregister_exec_domain +EXPORT_SYMBOL vmlinux 0x0a6a3c11 md_done_sync +EXPORT_SYMBOL vmlinux 0x0aa9c713 scsi_put_command +EXPORT_SYMBOL vmlinux 0x0aaf7a56 blk_queue_bounce_limit +EXPORT_SYMBOL vmlinux 0x0ab90f16 journal_restart +EXPORT_SYMBOL vmlinux 0x0ac4b8ed xfrm_state_check_expire +EXPORT_SYMBOL vmlinux 0x0acb1a3c __bitmap_shift_right +EXPORT_SYMBOL vmlinux 0x0b1beb31 vmalloc_32_user +EXPORT_SYMBOL vmlinux 0x0b742fd7 simple_strtol +EXPORT_SYMBOL vmlinux 0x0b758e75 dma_release_declared_memory +EXPORT_SYMBOL vmlinux 0x0bacbcd2 pid_task +EXPORT_SYMBOL vmlinux 0x0bc34e3a dev_get_by_index +EXPORT_SYMBOL vmlinux 0x0bfc2c22 pnp_unregister_driver +EXPORT_SYMBOL vmlinux 0x0c24132b netif_rx +EXPORT_SYMBOL vmlinux 0x0c2bada9 gnet_stats_start_copy_compat +EXPORT_SYMBOL vmlinux 0x0c350018 unbind_con_driver +EXPORT_SYMBOL vmlinux 0x0c55e87c rfkill_force_state +EXPORT_SYMBOL vmlinux 0x0c5ef91b per_cpu__vm_event_states +EXPORT_SYMBOL vmlinux 0x0c65e73c scsi_normalize_sense +EXPORT_SYMBOL vmlinux 0x0c8c9e99 scsi_show_extd_sense +EXPORT_SYMBOL vmlinux 0x0c981917 tty_name +EXPORT_SYMBOL vmlinux 0x0ca7b7a8 acpi_check_region +EXPORT_SYMBOL vmlinux 0x0cbe39e6 i2c_put_adapter +EXPORT_SYMBOL vmlinux 0x0cc57ae7 mmc_alloc_host +EXPORT_SYMBOL vmlinux 0x0cd5d880 mca_device_transform_irq +EXPORT_SYMBOL vmlinux 0x0d26a76d _write_lock_irq +EXPORT_SYMBOL vmlinux 0x0d367be3 __xfrm_policy_check +EXPORT_SYMBOL vmlinux 0x0d384c76 inet_frag_evictor +EXPORT_SYMBOL vmlinux 0x0d3dda14 acpi_get_type +EXPORT_SYMBOL vmlinux 0x0d4b77b7 gen_pool_add +EXPORT_SYMBOL vmlinux 0x0d542439 __ipv6_addr_type +EXPORT_SYMBOL vmlinux 0x0d6c963c copy_from_user +EXPORT_SYMBOL vmlinux 0x0d791415 skb_dma_unmap +EXPORT_SYMBOL vmlinux 0x0d8ab500 param_set_copystring +EXPORT_SYMBOL vmlinux 0x0d8bdf99 pci_unregister_driver +EXPORT_SYMBOL vmlinux 0x0da10ec3 security_sock_graft +EXPORT_SYMBOL vmlinux 0x0dfdcd67 nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0x0e1173ee nf_reinject +EXPORT_SYMBOL vmlinux 0x0e12e4cf alloc_fddidev +EXPORT_SYMBOL vmlinux 0x0e4272ee thermal_cooling_device_unregister +EXPORT_SYMBOL vmlinux 0x0e52592a panic +EXPORT_SYMBOL vmlinux 0x0e644f4c llc_sap_close +EXPORT_SYMBOL vmlinux 0x0e64bcd6 inet6_register_protosw +EXPORT_SYMBOL vmlinux 0x0e762d6e request_module +EXPORT_SYMBOL vmlinux 0x0e7b075d dentry_unhash +EXPORT_SYMBOL vmlinux 0x0e8d697c __getblk +EXPORT_SYMBOL vmlinux 0x0ec714e6 skb_queue_tail +EXPORT_SYMBOL vmlinux 0x0eda623d skb_under_panic +EXPORT_SYMBOL vmlinux 0x0ef8c248 tcp_md5_hash_header +EXPORT_SYMBOL vmlinux 0x0f1413bc find_inode_number +EXPORT_SYMBOL vmlinux 0x0f29107c vfs_quota_sync +EXPORT_SYMBOL vmlinux 0x0f29655c vlan_ioctl_set +EXPORT_SYMBOL vmlinux 0x0f478cab acpi_processor_notify_smm +EXPORT_SYMBOL vmlinux 0x0f47be89 blk_remove_plug +EXPORT_SYMBOL vmlinux 0x0f798b75 get_empty_filp +EXPORT_SYMBOL vmlinux 0x0f7aa74b mem_map +EXPORT_SYMBOL vmlinux 0x0f8e3246 dev_change_flags +EXPORT_SYMBOL vmlinux 0x0f94a07f mmc_request_done +EXPORT_SYMBOL vmlinux 0x0f98000f simple_lookup +EXPORT_SYMBOL vmlinux 0x0fac297c page_follow_link_light +EXPORT_SYMBOL vmlinux 0x0faef0ed __tasklet_schedule +EXPORT_SYMBOL vmlinux 0x0fd00a68 acpi_clear_event +EXPORT_SYMBOL vmlinux 0x0feb1690 cdrom_release +EXPORT_SYMBOL vmlinux 0x0ff2b602 slhc_compress +EXPORT_SYMBOL vmlinux 0x0ffd0dc0 proc_mkdir +EXPORT_SYMBOL vmlinux 0x10322033 scsi_free_command +EXPORT_SYMBOL vmlinux 0x104b6936 tty_wait_until_sent +EXPORT_SYMBOL vmlinux 0x105eb298 netdev_bonding_change +EXPORT_SYMBOL vmlinux 0x106bfb8f register_8022_client +EXPORT_SYMBOL vmlinux 0x107972fa hci_alloc_dev +EXPORT_SYMBOL vmlinux 0x107ed2eb textsearch_prepare +EXPORT_SYMBOL vmlinux 0x1087359c pci_remove_bus +EXPORT_SYMBOL vmlinux 0x10a1ff12 eth_rebuild_header +EXPORT_SYMBOL vmlinux 0x10cf6de1 inet_frags_init +EXPORT_SYMBOL vmlinux 0x10d900ee ipv6_chk_addr +EXPORT_SYMBOL vmlinux 0x10edf638 eth_header_parse +EXPORT_SYMBOL vmlinux 0x10ee20bb default_blu +EXPORT_SYMBOL vmlinux 0x1115694b generic_show_options +EXPORT_SYMBOL vmlinux 0x11267875 scsi_extd_sense_format +EXPORT_SYMBOL vmlinux 0x1153920e tr_type_trans +EXPORT_SYMBOL vmlinux 0x1163f0a7 blk_max_low_pfn +EXPORT_SYMBOL vmlinux 0x1168a35f d_genocide +EXPORT_SYMBOL vmlinux 0x117093be qdisc_class_hash_init +EXPORT_SYMBOL vmlinux 0x1173871d netpoll_poll +EXPORT_SYMBOL vmlinux 0x11773975 bio_get_nr_vecs +EXPORT_SYMBOL vmlinux 0x118f01ea putname +EXPORT_SYMBOL vmlinux 0x11a18b14 __wake_up_bit +EXPORT_SYMBOL vmlinux 0x11b19296 d_instantiate_unique +EXPORT_SYMBOL vmlinux 0x11ff8146 inet_accept +EXPORT_SYMBOL vmlinux 0x120507ac idr_get_new +EXPORT_SYMBOL vmlinux 0x12153684 ip_mc_join_group +EXPORT_SYMBOL vmlinux 0x121630a5 __xfrm_route_forward +EXPORT_SYMBOL vmlinux 0x1229c819 sock_no_shutdown +EXPORT_SYMBOL vmlinux 0x122cd082 sync_page_range_nolock +EXPORT_SYMBOL vmlinux 0x12496f71 call_usermodehelper_exec +EXPORT_SYMBOL vmlinux 0x125be454 input_free_device +EXPORT_SYMBOL vmlinux 0x125fbca7 cad_pid +EXPORT_SYMBOL vmlinux 0x126970ed param_set_uint +EXPORT_SYMBOL vmlinux 0x1279d6d9 pcim_pin_device +EXPORT_SYMBOL vmlinux 0x12884c2b dquot_free_inode +EXPORT_SYMBOL vmlinux 0x12ad4d4e f_setown +EXPORT_SYMBOL vmlinux 0x12c89c70 scsi_setup_fs_cmnd +EXPORT_SYMBOL vmlinux 0x12d65b68 devm_request_irq +EXPORT_SYMBOL vmlinux 0x12da5bb2 __kmalloc +EXPORT_SYMBOL vmlinux 0x12f22c82 bio_phys_segments +EXPORT_SYMBOL vmlinux 0x12f99022 inet_frags_init_net +EXPORT_SYMBOL vmlinux 0x12fe8319 fb_blank +EXPORT_SYMBOL vmlinux 0x132f45f2 cookie_check_timestamp +EXPORT_SYMBOL vmlinux 0x133cd11f mmc_register_driver +EXPORT_SYMBOL vmlinux 0x135c8278 generic_file_splice_read +EXPORT_SYMBOL vmlinux 0x13781784 gnet_stats_finish_copy +EXPORT_SYMBOL vmlinux 0x1378e714 acpi_video_display_switch_support +EXPORT_SYMBOL vmlinux 0x1382795b should_remove_suid +EXPORT_SYMBOL vmlinux 0x139e5322 kernel_listen +EXPORT_SYMBOL vmlinux 0x13a748d7 nobh_write_end +EXPORT_SYMBOL vmlinux 0x13b0fd4b blk_rq_append_bio +EXPORT_SYMBOL vmlinux 0x13f71731 tcf_hash_lookup +EXPORT_SYMBOL vmlinux 0x1429b38c scm_fp_dup +EXPORT_SYMBOL vmlinux 0x1430e6e0 unregister_acpi_notifier +EXPORT_SYMBOL vmlinux 0x1436d8f7 pci_bus_write_config_dword +EXPORT_SYMBOL vmlinux 0x1446c5a9 bio_map_kern +EXPORT_SYMBOL vmlinux 0x1477c728 flow_cache_lookup +EXPORT_SYMBOL vmlinux 0x14910c47 generic_file_llseek_unlocked +EXPORT_SYMBOL vmlinux 0x14af0cf7 gen_pool_destroy +EXPORT_SYMBOL vmlinux 0x14bdc6e5 simple_set_mnt +EXPORT_SYMBOL vmlinux 0x14dfb3a1 con_copy_unimap +EXPORT_SYMBOL vmlinux 0x14f332ea up_read +EXPORT_SYMBOL vmlinux 0x15086261 dm_unregister_target +EXPORT_SYMBOL vmlinux 0x15104dfa arch_debugfs_dir +EXPORT_SYMBOL vmlinux 0x152cf215 ppp_unregister_channel +EXPORT_SYMBOL vmlinux 0x1544aad4 genl_register_mc_group +EXPORT_SYMBOL vmlinux 0x1551dc51 bitmap_find_free_region +EXPORT_SYMBOL vmlinux 0x15622607 lookup_bdev +EXPORT_SYMBOL vmlinux 0x15820333 nf_register_hook +EXPORT_SYMBOL vmlinux 0x15a371a4 netif_device_attach +EXPORT_SYMBOL vmlinux 0x15c3ded6 register_sysctl_paths +EXPORT_SYMBOL vmlinux 0x15de939d get_fs_type +EXPORT_SYMBOL vmlinux 0x15ef2dd9 kfifo_free +EXPORT_SYMBOL vmlinux 0x16167344 bd_set_size +EXPORT_SYMBOL vmlinux 0x1670b12c nf_register_queue_handler +EXPORT_SYMBOL vmlinux 0x1675606f bad_dma_address +EXPORT_SYMBOL vmlinux 0x167e7f9d __get_user_1 +EXPORT_SYMBOL vmlinux 0x167fbe3c unregister_cdrom +EXPORT_SYMBOL vmlinux 0x16a35878 _read_unlock +EXPORT_SYMBOL vmlinux 0x16c43374 tcp_disconnect +EXPORT_SYMBOL vmlinux 0x16e0e9d4 xfrm6_rcv +EXPORT_SYMBOL vmlinux 0x17020bac llc_sap_open +EXPORT_SYMBOL vmlinux 0x17047b44 scsicam_bios_param +EXPORT_SYMBOL vmlinux 0x17052027 thermal_zone_unbind_cooling_device +EXPORT_SYMBOL vmlinux 0x1705cd06 d_alloc_root +EXPORT_SYMBOL vmlinux 0x170c25ee acpi_get_next_object +EXPORT_SYMBOL vmlinux 0x1741cfd2 make_EII_client +EXPORT_SYMBOL vmlinux 0x175a298d acpi_set_firmware_waking_vector +EXPORT_SYMBOL vmlinux 0x17907cda blk_queue_dma_pad +EXPORT_SYMBOL vmlinux 0x17a24539 scsi_reset_provider +EXPORT_SYMBOL vmlinux 0x17a76e71 rb_first +EXPORT_SYMBOL vmlinux 0x17ad6a26 pnp_possible_config +EXPORT_SYMBOL vmlinux 0x17b4ba9f dmam_free_noncoherent +EXPORT_SYMBOL vmlinux 0x17cab5b3 pcix_get_max_mmrbc +EXPORT_SYMBOL vmlinux 0x17df17bc sysctl_tcp_ecn +EXPORT_SYMBOL vmlinux 0x17ec114a inet_getname +EXPORT_SYMBOL vmlinux 0x17efeec1 __lock_buffer +EXPORT_SYMBOL vmlinux 0x181b6ff2 mempool_resize +EXPORT_SYMBOL vmlinux 0x18208a79 sock_kfree_s +EXPORT_SYMBOL vmlinux 0x18219be2 blk_verify_command +EXPORT_SYMBOL vmlinux 0x183fa88b mempool_alloc_slab +EXPORT_SYMBOL vmlinux 0x1845e7c5 acpi_evaluate_integer +EXPORT_SYMBOL vmlinux 0x1867e78d alloc_trdev +EXPORT_SYMBOL vmlinux 0x1877b764 lock_may_write +EXPORT_SYMBOL vmlinux 0x1899b992 bt_accept_unlink +EXPORT_SYMBOL vmlinux 0x189b0ec7 __scsi_put_command +EXPORT_SYMBOL vmlinux 0x189d2373 locks_mandatory_area +EXPORT_SYMBOL vmlinux 0x18a94b80 tcp_v4_md5_hash_skb +EXPORT_SYMBOL vmlinux 0x18d88473 pcix_set_mmrbc +EXPORT_SYMBOL vmlinux 0x18e2781a send_sig_info +EXPORT_SYMBOL vmlinux 0x190bd0ce pci_request_regions +EXPORT_SYMBOL vmlinux 0x190d6198 mb_cache_entry_free +EXPORT_SYMBOL vmlinux 0x190f67cf redirty_page_for_writepage +EXPORT_SYMBOL vmlinux 0x192bd6cb nf_getsockopt +EXPORT_SYMBOL vmlinux 0x193ad3ca unregister_nls +EXPORT_SYMBOL vmlinux 0x19649730 tcf_em_register +EXPORT_SYMBOL vmlinux 0x196997d9 module_refcount +EXPORT_SYMBOL vmlinux 0x196d5da0 scsi_print_command +EXPORT_SYMBOL vmlinux 0x1985ed3c prepare_to_wait_exclusive +EXPORT_SYMBOL vmlinux 0x198f78a9 blk_queue_invalidate_tags +EXPORT_SYMBOL vmlinux 0x199ed0cd net_disable_timestamp +EXPORT_SYMBOL vmlinux 0x19d5d20a acpi_walk_namespace +EXPORT_SYMBOL vmlinux 0x19f5d6f0 thermal_cooling_device_register +EXPORT_SYMBOL vmlinux 0x19fcf24a scsi_bios_ptable +EXPORT_SYMBOL vmlinux 0x1a1ab15d tty_mutex +EXPORT_SYMBOL vmlinux 0x1a1d7bed dm_io_client_create +EXPORT_SYMBOL vmlinux 0x1a33b99c udp_disconnect +EXPORT_SYMBOL vmlinux 0x1a436ce1 unmap_mapping_range +EXPORT_SYMBOL vmlinux 0x1a45cb6c acpi_disabled +EXPORT_SYMBOL vmlinux 0x1a565efb elv_dispatch_sort +EXPORT_SYMBOL vmlinux 0x1a62d947 tcf_destroy_chain +EXPORT_SYMBOL vmlinux 0x1a72f085 scsi_eh_prep_cmnd +EXPORT_SYMBOL vmlinux 0x1a75caa3 _read_lock +EXPORT_SYMBOL vmlinux 0x1a854228 get_io_context +EXPORT_SYMBOL vmlinux 0x1a8a845e idle_nomwait +EXPORT_SYMBOL vmlinux 0x1a9b2417 phy_driver_register +EXPORT_SYMBOL vmlinux 0x1accf842 register_md_personality +EXPORT_SYMBOL vmlinux 0x1ace138d bitmap_allocate_region +EXPORT_SYMBOL vmlinux 0x1ad016fc mb_cache_entry_release +EXPORT_SYMBOL vmlinux 0x1ae8d7dc param_set_invbool +EXPORT_SYMBOL vmlinux 0x1b015d25 bitmap_parselist +EXPORT_SYMBOL vmlinux 0x1b3235ef blk_queue_find_tag +EXPORT_SYMBOL vmlinux 0x1b3c678a gen_new_estimator +EXPORT_SYMBOL vmlinux 0x1b517730 ____pagevec_lru_add +EXPORT_SYMBOL vmlinux 0x1b6314fd in_aton +EXPORT_SYMBOL vmlinux 0x1b89419f add_wait_queue_exclusive +EXPORT_SYMBOL vmlinux 0x1b97b686 generic_file_direct_write +EXPORT_SYMBOL vmlinux 0x1b9981cc set_irq_wake +EXPORT_SYMBOL vmlinux 0x1b9e0ff1 scsilun_to_int +EXPORT_SYMBOL vmlinux 0x1bddbbb2 journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x1c4652e2 __nla_put_nohdr +EXPORT_SYMBOL vmlinux 0x1c51a9b8 xfrm_user_policy +EXPORT_SYMBOL vmlinux 0x1c61de8b elv_rb_former_request +EXPORT_SYMBOL vmlinux 0x1c68e604 netlink_change_ngroups +EXPORT_SYMBOL vmlinux 0x1c78cf69 sock_wfree +EXPORT_SYMBOL vmlinux 0x1c9633dd textsearch_register +EXPORT_SYMBOL vmlinux 0x1c9d52de task_nice +EXPORT_SYMBOL vmlinux 0x1ca45916 dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0x1cb049aa phy_print_status +EXPORT_SYMBOL vmlinux 0x1cc6719a register_reboot_notifier +EXPORT_SYMBOL vmlinux 0x1ccb9ad3 elv_rb_add +EXPORT_SYMBOL vmlinux 0x1cd7d68d input_close_device +EXPORT_SYMBOL vmlinux 0x1ce1e467 load_nls_default +EXPORT_SYMBOL vmlinux 0x1ceec98e sock_no_sendpage +EXPORT_SYMBOL vmlinux 0x1cefe352 wait_for_completion +EXPORT_SYMBOL vmlinux 0x1d0015dd drop_super +EXPORT_SYMBOL vmlinux 0x1d30b70c rwsem_wake +EXPORT_SYMBOL vmlinux 0x1d6a6275 put_page +EXPORT_SYMBOL vmlinux 0x1d786079 bio_integrity_endio +EXPORT_SYMBOL vmlinux 0x1d965133 __dec_zone_page_state +EXPORT_SYMBOL vmlinux 0x1dad8789 blk_queue_dma_alignment +EXPORT_SYMBOL vmlinux 0x1dc36131 fb_destroy_modedb +EXPORT_SYMBOL vmlinux 0x1dd571e6 fb_copy_cmap +EXPORT_SYMBOL vmlinux 0x1de3f249 open_exec +EXPORT_SYMBOL vmlinux 0x1dea7b44 tty_driver_kref_put +EXPORT_SYMBOL vmlinux 0x1e2bcb6d bio_map_user +EXPORT_SYMBOL vmlinux 0x1e2e427f cpumask_next_and +EXPORT_SYMBOL vmlinux 0x1e6b82c4 scsi_device_put +EXPORT_SYMBOL vmlinux 0x1e6d26a8 strstr +EXPORT_SYMBOL vmlinux 0x1e6e40a7 generic_getxattr +EXPORT_SYMBOL vmlinux 0x1e810e47 input_open_device +EXPORT_SYMBOL vmlinux 0x1e962db3 ethtool_op_get_tx_csum +EXPORT_SYMBOL vmlinux 0x1ea943a2 bio_free +EXPORT_SYMBOL vmlinux 0x1eb922a3 IO_APIC_get_PCI_irq_vector +EXPORT_SYMBOL vmlinux 0x1ec10d1e bmap +EXPORT_SYMBOL vmlinux 0x1efe283f __cap_full_set +EXPORT_SYMBOL vmlinux 0x1f08f630 filemap_fdatawait +EXPORT_SYMBOL vmlinux 0x1f27d6d7 _write_unlock +EXPORT_SYMBOL vmlinux 0x1f4ab211 __mmc_claim_host +EXPORT_SYMBOL vmlinux 0x1f4ac055 acpi_processor_preregister_performance +EXPORT_SYMBOL vmlinux 0x1f4e0962 blk_queue_bounce +EXPORT_SYMBOL vmlinux 0x1f5e27cc inet_csk_accept +EXPORT_SYMBOL vmlinux 0x1f762f88 register_framebuffer +EXPORT_SYMBOL vmlinux 0x1f97899f genphy_restart_aneg +EXPORT_SYMBOL vmlinux 0x1fd7029f scsi_allocate_command +EXPORT_SYMBOL vmlinux 0x1fd7b2a1 acpi_match_device_ids +EXPORT_SYMBOL vmlinux 0x1fe15b72 truncate_inode_pages_range +EXPORT_SYMBOL vmlinux 0x1fe5ede6 per_cpu__irq_stat +EXPORT_SYMBOL vmlinux 0x1ff86e47 mdio_bus_type +EXPORT_SYMBOL vmlinux 0x20000329 simple_strtoul +EXPORT_SYMBOL vmlinux 0x2005e68a acpi_remove_fixed_event_handler +EXPORT_SYMBOL vmlinux 0x208739f6 acpi_load_table +EXPORT_SYMBOL vmlinux 0x20949e73 blk_queue_max_hw_segments +EXPORT_SYMBOL vmlinux 0x20c8fc33 pci_osc_control_set +EXPORT_SYMBOL vmlinux 0x20e1adbe handle_sysrq +EXPORT_SYMBOL vmlinux 0x211306d6 input_register_handle +EXPORT_SYMBOL vmlinux 0x2121b725 dst_discard +EXPORT_SYMBOL vmlinux 0x215ebd78 bitrev16 +EXPORT_SYMBOL vmlinux 0x2165f2a5 scsi_dma_unmap +EXPORT_SYMBOL vmlinux 0x217ea524 dev_mc_add +EXPORT_SYMBOL vmlinux 0x218480f6 mca_register_driver_integrated +EXPORT_SYMBOL vmlinux 0x21c0b641 jbd2_journal_clear_features +EXPORT_SYMBOL vmlinux 0x21e0ea22 acpi_get_id +EXPORT_SYMBOL vmlinux 0x220da9ae have_submounts +EXPORT_SYMBOL vmlinux 0x2211da2d bfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0x22213d24 jbd2_journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x2227523a tty_check_change +EXPORT_SYMBOL vmlinux 0x2228e781 iw_handler_get_thrspy +EXPORT_SYMBOL vmlinux 0x222e7ce2 sysfs_streq +EXPORT_SYMBOL vmlinux 0x22392ba9 shrink_dcache_sb +EXPORT_SYMBOL vmlinux 0x225cfd6e blk_plug_device +EXPORT_SYMBOL vmlinux 0x226cb7f5 scsi_target_resume +EXPORT_SYMBOL vmlinux 0x226e86a9 audit_log +EXPORT_SYMBOL vmlinux 0x2270515b cdrom_get_last_written +EXPORT_SYMBOL vmlinux 0x2270e67b mca_device_write_pos +EXPORT_SYMBOL vmlinux 0x227e92be bio_alloc +EXPORT_SYMBOL vmlinux 0x2288378f system_state +EXPORT_SYMBOL vmlinux 0x22a4a2aa tcp_v4_do_rcv +EXPORT_SYMBOL vmlinux 0x22a73912 __tcp_put_md5sig_pool +EXPORT_SYMBOL vmlinux 0x22b325d5 kd_mksound +EXPORT_SYMBOL vmlinux 0x22b6533b xfrm_sad_getinfo +EXPORT_SYMBOL vmlinux 0x22d2ae25 init_buffer +EXPORT_SYMBOL vmlinux 0x22d584b7 journal_stop +EXPORT_SYMBOL vmlinux 0x231f3a66 __kfifo_put +EXPORT_SYMBOL vmlinux 0x232056d1 br_handle_frame_hook +EXPORT_SYMBOL vmlinux 0x23269a13 strict_strtoul +EXPORT_SYMBOL vmlinux 0x2334ff91 vmtruncate +EXPORT_SYMBOL vmlinux 0x23532f9c journal_invalidatepage +EXPORT_SYMBOL vmlinux 0x23623f9e tcp_initialize_rcv_mss +EXPORT_SYMBOL vmlinux 0x2365861d proc_dostring +EXPORT_SYMBOL vmlinux 0x2368be6d posix_acl_to_xattr +EXPORT_SYMBOL vmlinux 0x2378eb72 phy_start_aneg +EXPORT_SYMBOL vmlinux 0x237bd96d netlink_broadcast +EXPORT_SYMBOL vmlinux 0x238909c7 open_by_devnum +EXPORT_SYMBOL vmlinux 0x23ad070a set_current_groups +EXPORT_SYMBOL vmlinux 0x23aebf6d mdiobus_write +EXPORT_SYMBOL vmlinux 0x23c212cc set_anon_super +EXPORT_SYMBOL vmlinux 0x23c8f257 slhc_uncompress +EXPORT_SYMBOL vmlinux 0x23fd3028 vmalloc_node +EXPORT_SYMBOL vmlinux 0x241afbb3 tcp_v4_conn_request +EXPORT_SYMBOL vmlinux 0x241c1ca4 tcp_sync_mss +EXPORT_SYMBOL vmlinux 0x243ffddc idr_destroy +EXPORT_SYMBOL vmlinux 0x24428be5 strncpy_from_user +EXPORT_SYMBOL vmlinux 0x2459bbcc console_set_on_cmdline +EXPORT_SYMBOL vmlinux 0x24a484e8 blk_queue_softirq_done +EXPORT_SYMBOL vmlinux 0x24a695cd ethtool_op_set_tx_hw_csum +EXPORT_SYMBOL vmlinux 0x24b362ae alloc_hippi_dev +EXPORT_SYMBOL vmlinux 0x24d4fd42 security_task_getsecid +EXPORT_SYMBOL vmlinux 0x24d56edf mpage_bio_submit +EXPORT_SYMBOL vmlinux 0x24db11cc nf_log_register +EXPORT_SYMBOL vmlinux 0x24f48f85 remove_inode_hash +EXPORT_SYMBOL vmlinux 0x24fdac79 wake_bit_function +EXPORT_SYMBOL vmlinux 0x250113b4 memory_read_from_buffer +EXPORT_SYMBOL vmlinux 0x25357e99 dquot_free_space +EXPORT_SYMBOL vmlinux 0x2544f8b3 xfrm6_prepare_output +EXPORT_SYMBOL vmlinux 0x25661290 inet_csk_clear_xmit_timers +EXPORT_SYMBOL vmlinux 0x256887e1 warn_slowpath +EXPORT_SYMBOL vmlinux 0x257d762d __devm_release_region +EXPORT_SYMBOL vmlinux 0x257dff1c md_unregister_thread +EXPORT_SYMBOL vmlinux 0x25820c64 fs_overflowuid +EXPORT_SYMBOL vmlinux 0x258355b4 fb_find_best_mode +EXPORT_SYMBOL vmlinux 0x2596feff dmam_release_declared_memory +EXPORT_SYMBOL vmlinux 0x25a37219 genphy_read_status +EXPORT_SYMBOL vmlinux 0x25bc8dd4 vm_map_ram +EXPORT_SYMBOL vmlinux 0x25d81960 posix_acl_equiv_mode +EXPORT_SYMBOL vmlinux 0x25f46c22 vc_cons +EXPORT_SYMBOL vmlinux 0x262a5d1c skb_queue_purge +EXPORT_SYMBOL vmlinux 0x2658a956 seq_printf +EXPORT_SYMBOL vmlinux 0x2658e4eb proc_create_data +EXPORT_SYMBOL vmlinux 0x2679a2a5 scsi_set_medium_removal +EXPORT_SYMBOL vmlinux 0x2679ff59 serio_unregister_driver +EXPORT_SYMBOL vmlinux 0x2685c3d7 __sg_alloc_table +EXPORT_SYMBOL vmlinux 0x268cc6a2 sys_close +EXPORT_SYMBOL vmlinux 0x269a101d seq_putc +EXPORT_SYMBOL vmlinux 0x26a2efa0 kernel_getsockopt +EXPORT_SYMBOL vmlinux 0x26c3e84a elv_rb_latter_request +EXPORT_SYMBOL vmlinux 0x26d85c3e inet6_add_protocol +EXPORT_SYMBOL vmlinux 0x26e76fb8 sysctl_udp_wmem_min +EXPORT_SYMBOL vmlinux 0x26fef3e9 tcf_exts_change +EXPORT_SYMBOL vmlinux 0x270e2814 bitmap_start_sync +EXPORT_SYMBOL vmlinux 0x271f32e1 mpage_readpage +EXPORT_SYMBOL vmlinux 0x272d394e mtrr_del +EXPORT_SYMBOL vmlinux 0x272e7488 cond_resched_softirq +EXPORT_SYMBOL vmlinux 0x273f066e _write_unlock_irq +EXPORT_SYMBOL vmlinux 0x27864d57 memparse +EXPORT_SYMBOL vmlinux 0x27a3b1c4 dget_locked +EXPORT_SYMBOL vmlinux 0x27a9a7eb ns_to_timespec +EXPORT_SYMBOL vmlinux 0x27bbf221 disable_irq_nosync +EXPORT_SYMBOL vmlinux 0x27c61ece qdisc_put_stab +EXPORT_SYMBOL vmlinux 0x27de886e get_sb_nodev +EXPORT_SYMBOL vmlinux 0x280d4ca5 qdisc_reset +EXPORT_SYMBOL vmlinux 0x280e4670 xfrm_find_acq +EXPORT_SYMBOL vmlinux 0x28270b64 scsi_report_device_reset +EXPORT_SYMBOL vmlinux 0x285ac517 strict_strtoll +EXPORT_SYMBOL vmlinux 0x28a2ed02 scsi_build_sense_buffer +EXPORT_SYMBOL vmlinux 0x28b715a6 isapnp_cfg_end +EXPORT_SYMBOL vmlinux 0x28dcf25c udplite_hash +EXPORT_SYMBOL vmlinux 0x2931f504 igrab +EXPORT_SYMBOL vmlinux 0x29537c9e alloc_chrdev_region +EXPORT_SYMBOL vmlinux 0x297ea781 mmc_release_host +EXPORT_SYMBOL vmlinux 0x29bd4c46 __cap_init_eff_set +EXPORT_SYMBOL vmlinux 0x29cacfdc jbd2_journal_wipe +EXPORT_SYMBOL vmlinux 0x29d64fd2 dev_remove_pack +EXPORT_SYMBOL vmlinux 0x2a1dea4e netdev_class_create_file +EXPORT_SYMBOL vmlinux 0x2a303d4d check_signature +EXPORT_SYMBOL vmlinux 0x2a62e08a tcp_v4_syn_recv_sock +EXPORT_SYMBOL vmlinux 0x2a958a10 inet_sk_rebuild_header +EXPORT_SYMBOL vmlinux 0x2aa0e4fc strncasecmp +EXPORT_SYMBOL vmlinux 0x2acda10a security_sb_clone_mnt_opts +EXPORT_SYMBOL vmlinux 0x2ae403fd start_tty +EXPORT_SYMBOL vmlinux 0x2aeb2800 mempool_create_node +EXPORT_SYMBOL vmlinux 0x2afd340a mmc_wait_for_cmd +EXPORT_SYMBOL vmlinux 0x2b04c3eb find_get_pages_tag +EXPORT_SYMBOL vmlinux 0x2b0ba2b0 scsi_sense_desc_find +EXPORT_SYMBOL vmlinux 0x2b172114 d_invalidate +EXPORT_SYMBOL vmlinux 0x2b27c240 devm_iounmap +EXPORT_SYMBOL vmlinux 0x2b6263db blkdev_get +EXPORT_SYMBOL vmlinux 0x2b650989 udp_poll +EXPORT_SYMBOL vmlinux 0x2b6aac8c tcp_sockets_allocated +EXPORT_SYMBOL vmlinux 0x2b827c8e truncate_inode_pages +EXPORT_SYMBOL vmlinux 0x2b83875a seq_read +EXPORT_SYMBOL vmlinux 0x2ba707a8 sysctl_tcp_low_latency +EXPORT_SYMBOL vmlinux 0x2bb55d6e acpi_remove_notify_handler +EXPORT_SYMBOL vmlinux 0x2bc95bd4 memset +EXPORT_SYMBOL vmlinux 0x2bdcfb62 tty_set_operations +EXPORT_SYMBOL vmlinux 0x2be09893 _atomic_dec_and_lock +EXPORT_SYMBOL vmlinux 0x2beb6f1e skb_unlink +EXPORT_SYMBOL vmlinux 0x2bfeb410 acpi_get_handle +EXPORT_SYMBOL vmlinux 0x2c4c68b4 __ht_create_irq +EXPORT_SYMBOL vmlinux 0x2c4fe1f9 pci_enable_bridges +EXPORT_SYMBOL vmlinux 0x2c5749e6 acpi_clear_gpe +EXPORT_SYMBOL vmlinux 0x2c721777 register_sysrq_key +EXPORT_SYMBOL vmlinux 0x2c89bc37 request_key +EXPORT_SYMBOL vmlinux 0x2c8f5989 acpi_remove_address_space_handler +EXPORT_SYMBOL vmlinux 0x2c905056 dmam_alloc_coherent +EXPORT_SYMBOL vmlinux 0x2c9874fe ida_remove +EXPORT_SYMBOL vmlinux 0x2c9fd306 i2c_add_adapter +EXPORT_SYMBOL vmlinux 0x2cc2d52d vcc_hash +EXPORT_SYMBOL vmlinux 0x2cc63438 tcp_check_req +EXPORT_SYMBOL vmlinux 0x2ccd8d61 blk_recount_segments +EXPORT_SYMBOL vmlinux 0x2cd9e459 param_set_short +EXPORT_SYMBOL vmlinux 0x2cf03239 dev_mc_unsync +EXPORT_SYMBOL vmlinux 0x2cf190e3 request_irq +EXPORT_SYMBOL vmlinux 0x2cfc6333 scsi_eh_restore_cmnd +EXPORT_SYMBOL vmlinux 0x2d1fe666 mmc_detect_change +EXPORT_SYMBOL vmlinux 0x2d3733f1 neigh_resolve_output +EXPORT_SYMBOL vmlinux 0x2d4b93aa i2c_get_adapter +EXPORT_SYMBOL vmlinux 0x2d5eb479 pnp_stop_dev +EXPORT_SYMBOL vmlinux 0x2d67138d phy_register_fixup_for_id +EXPORT_SYMBOL vmlinux 0x2d89342a scsi_show_sense_hdr +EXPORT_SYMBOL vmlinux 0x2dae9f1d invalidate_inode_buffers +EXPORT_SYMBOL vmlinux 0x2dbafbe3 pcibios_align_resource +EXPORT_SYMBOL vmlinux 0x2dbc28ae ps2_drain +EXPORT_SYMBOL vmlinux 0x2dbd56b8 kernel_recvmsg +EXPORT_SYMBOL vmlinux 0x2dd16564 arch_register_cpu +EXPORT_SYMBOL vmlinux 0x2de9f66f param_get_long +EXPORT_SYMBOL vmlinux 0x2dedc4c2 acpi_format_exception +EXPORT_SYMBOL vmlinux 0x2def7f76 rtc_cmos_write +EXPORT_SYMBOL vmlinux 0x2e28be03 mdiobus_read +EXPORT_SYMBOL vmlinux 0x2e2ce9e0 sysctl_tcp_syncookies +EXPORT_SYMBOL vmlinux 0x2e3b09dc __nla_reserve +EXPORT_SYMBOL vmlinux 0x2e4a39f8 sysctl_udp_mem +EXPORT_SYMBOL vmlinux 0x2e5e46cc i2c_release_client +EXPORT_SYMBOL vmlinux 0x2e60bace memcpy +EXPORT_SYMBOL vmlinux 0x2e84ef98 bio_integrity_tag_size +EXPORT_SYMBOL vmlinux 0x2e97859f rwsem_downgrade_wake +EXPORT_SYMBOL vmlinux 0x2eb0991f dm_table_put +EXPORT_SYMBOL vmlinux 0x2eb9a0e8 _read_lock_irq +EXPORT_SYMBOL vmlinux 0x2ecf7b2c netpoll_parse_options +EXPORT_SYMBOL vmlinux 0x2ef031ce release_sock +EXPORT_SYMBOL vmlinux 0x2ef90485 nlmsg_notify +EXPORT_SYMBOL vmlinux 0x2f287f0d copy_to_user +EXPORT_SYMBOL vmlinux 0x2fcbc471 qdisc_list_del +EXPORT_SYMBOL vmlinux 0x2fdc4d11 input_unregister_handler +EXPORT_SYMBOL vmlinux 0x2ff7efaa tcf_hash_new_index +EXPORT_SYMBOL vmlinux 0x30123eb5 icmpv6_statistics +EXPORT_SYMBOL vmlinux 0x302a4441 mark_buffer_dirty_inode +EXPORT_SYMBOL vmlinux 0x302a741d keyring_clear +EXPORT_SYMBOL vmlinux 0x305466b7 pci_lost_interrupt +EXPORT_SYMBOL vmlinux 0x3057de7b udp_lib_get_port +EXPORT_SYMBOL vmlinux 0x306c2eb5 hci_unregister_cb +EXPORT_SYMBOL vmlinux 0x30e74134 tty_termios_copy_hw +EXPORT_SYMBOL vmlinux 0x30f69d0b xfrm4_rcv_encap +EXPORT_SYMBOL vmlinux 0x310797ef dm_table_get +EXPORT_SYMBOL vmlinux 0x310917fe sort +EXPORT_SYMBOL vmlinux 0x3145216f pci_dev_present +EXPORT_SYMBOL vmlinux 0x3147857d default_red +EXPORT_SYMBOL vmlinux 0x315cdfae km_new_mapping +EXPORT_SYMBOL vmlinux 0x3165c202 atm_proc_root +EXPORT_SYMBOL vmlinux 0x317223d6 ip_route_output_key +EXPORT_SYMBOL vmlinux 0x317a9666 __scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0x3180a8aa i2c_smbus_xfer +EXPORT_SYMBOL vmlinux 0x31840bf9 do_sync_write +EXPORT_SYMBOL vmlinux 0x3191f109 __krealloc +EXPORT_SYMBOL vmlinux 0x31958966 i2c_verify_client +EXPORT_SYMBOL vmlinux 0x31cb14d4 tcf_register_action +EXPORT_SYMBOL vmlinux 0x31cb422f end_buffer_read_sync +EXPORT_SYMBOL vmlinux 0x31df0670 kmalloc_caches +EXPORT_SYMBOL vmlinux 0x31e76b57 recalibrate_cpu_khz +EXPORT_SYMBOL vmlinux 0x3272a8a4 shrink_dcache_parent +EXPORT_SYMBOL vmlinux 0x32798250 dm_table_event +EXPORT_SYMBOL vmlinux 0x3294b908 framebuffer_alloc +EXPORT_SYMBOL vmlinux 0x3294c30d devm_ioremap +EXPORT_SYMBOL vmlinux 0x32965a74 dma_pool_destroy +EXPORT_SYMBOL vmlinux 0x32a70dfe generic_listxattr +EXPORT_SYMBOL vmlinux 0x32c060a9 ipv6_setsockopt +EXPORT_SYMBOL vmlinux 0x32d01fec acpi_attach_data +EXPORT_SYMBOL vmlinux 0x32f0576d bio_integrity_get_tag +EXPORT_SYMBOL vmlinux 0x330511e3 __kill_fasync +EXPORT_SYMBOL vmlinux 0x333490c4 tty_hangup +EXPORT_SYMBOL vmlinux 0x333620f5 unregister_framebuffer +EXPORT_SYMBOL vmlinux 0x3355095d sock_no_getname +EXPORT_SYMBOL vmlinux 0x3360a963 param_set_ulong +EXPORT_SYMBOL vmlinux 0x33792939 tty_kref_put +EXPORT_SYMBOL vmlinux 0x3385c8cb per_cpu__this_cpu_off +EXPORT_SYMBOL vmlinux 0x33ae6a34 pci_enable_wake +EXPORT_SYMBOL vmlinux 0x33d3b7cb revalidate_disk +EXPORT_SYMBOL vmlinux 0x33d92f9a prepare_to_wait +EXPORT_SYMBOL vmlinux 0x340d03bd ip_queue_xmit +EXPORT_SYMBOL vmlinux 0x341d0ec9 sync_mapping_buffers +EXPORT_SYMBOL vmlinux 0x34213cba dev_kfree_skb_irq +EXPORT_SYMBOL vmlinux 0x342f60fe apm_info +EXPORT_SYMBOL vmlinux 0x34908c14 print_hex_dump_bytes +EXPORT_SYMBOL vmlinux 0x349cba85 strchr +EXPORT_SYMBOL vmlinux 0x34b0e73a find_get_page +EXPORT_SYMBOL vmlinux 0x34c510a6 ps2_handle_ack +EXPORT_SYMBOL vmlinux 0x34e4648f isapnp_protocol +EXPORT_SYMBOL vmlinux 0x34e4ab3b skb_split +EXPORT_SYMBOL vmlinux 0x34fcca58 scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0x3522d963 tty_insert_flip_string_flags +EXPORT_SYMBOL vmlinux 0x3550df73 cfb_copyarea +EXPORT_SYMBOL vmlinux 0x357b12eb kfree_skb +EXPORT_SYMBOL vmlinux 0x35954fa2 jbd2_journal_errno +EXPORT_SYMBOL vmlinux 0x35993c5c scsi_mode_sense +EXPORT_SYMBOL vmlinux 0x35b65714 input_flush_device +EXPORT_SYMBOL vmlinux 0x35c2ba9e refrigerator +EXPORT_SYMBOL vmlinux 0x35dd0c04 ppp_unregister_compressor +EXPORT_SYMBOL vmlinux 0x35f0faa2 acpi_evaluate_object +EXPORT_SYMBOL vmlinux 0x35f16543 pcibios_set_irq_routing +EXPORT_SYMBOL vmlinux 0x35faab51 pci_find_slot +EXPORT_SYMBOL vmlinux 0x35fd59e4 ps2_cmd_aborted +EXPORT_SYMBOL vmlinux 0x35fea3b6 set_page_dirty +EXPORT_SYMBOL vmlinux 0x360b1afe probe_irq_mask +EXPORT_SYMBOL vmlinux 0x3630c327 generic_file_splice_write_nolock +EXPORT_SYMBOL vmlinux 0x363ad247 cap_set_effective +EXPORT_SYMBOL vmlinux 0x3656bf5a lock_kernel +EXPORT_SYMBOL vmlinux 0x36eaa955 phy_stop +EXPORT_SYMBOL vmlinux 0x373e61a9 pagecache_write_begin +EXPORT_SYMBOL vmlinux 0x3744cf36 vmalloc_to_pfn +EXPORT_SYMBOL vmlinux 0x374ed073 scnprintf +EXPORT_SYMBOL vmlinux 0x375d8891 inet_register_protosw +EXPORT_SYMBOL vmlinux 0x378983a8 blk_run_queue +EXPORT_SYMBOL vmlinux 0x378dc9fb xfrm_state_unregister_afinfo +EXPORT_SYMBOL vmlinux 0x379d65f5 gen_pool_alloc +EXPORT_SYMBOL vmlinux 0x37a24b9d __vlan_hwaccel_rx +EXPORT_SYMBOL vmlinux 0x37a6413f bdevname +EXPORT_SYMBOL vmlinux 0x37befc70 jiffies_to_msecs +EXPORT_SYMBOL vmlinux 0x37bf08fb clear_bdi_congested +EXPORT_SYMBOL vmlinux 0x37c1e309 proc_dointvec_minmax +EXPORT_SYMBOL vmlinux 0x37c89581 xfrm_policy_register_afinfo +EXPORT_SYMBOL vmlinux 0x37ce1916 jbd2_journal_file_inode +EXPORT_SYMBOL vmlinux 0x37ced827 inet_csk_reset_keepalive_timer +EXPORT_SYMBOL vmlinux 0x37e08d81 tcp_v4_md5_do_del +EXPORT_SYMBOL vmlinux 0x37e74642 get_jiffies_64 +EXPORT_SYMBOL vmlinux 0x37fbc874 mmc_align_data_size +EXPORT_SYMBOL vmlinux 0x3801be8a inet6_unregister_protosw +EXPORT_SYMBOL vmlinux 0x381df079 may_umount_tree +EXPORT_SYMBOL vmlinux 0x38203ca1 __init_rwsem +EXPORT_SYMBOL vmlinux 0x3847f15e blk_init_queue +EXPORT_SYMBOL vmlinux 0x3871f179 journal_wipe +EXPORT_SYMBOL vmlinux 0x387c0967 vfs_lstat +EXPORT_SYMBOL vmlinux 0x3882aa4d tcf_em_tree_validate +EXPORT_SYMBOL vmlinux 0x388f9128 xfrm_state_walk_done +EXPORT_SYMBOL vmlinux 0x38b92846 llc_remove_pack +EXPORT_SYMBOL vmlinux 0x38be3492 do_splice_from +EXPORT_SYMBOL vmlinux 0x392e20e7 mmc_unregister_driver +EXPORT_SYMBOL vmlinux 0x395dfc01 inet_stream_ops +EXPORT_SYMBOL vmlinux 0x3964d041 bio_integrity_prep +EXPORT_SYMBOL vmlinux 0x39699cac journal_forget +EXPORT_SYMBOL vmlinux 0x3980aac1 unregister_reboot_notifier +EXPORT_SYMBOL vmlinux 0x39c1c05f __bio_clone +EXPORT_SYMBOL vmlinux 0x39c645a2 schedule_delayed_work_on +EXPORT_SYMBOL vmlinux 0x39ca530c mmc_wait_for_app_cmd +EXPORT_SYMBOL vmlinux 0x39d54552 jbd2_journal_start_commit +EXPORT_SYMBOL vmlinux 0x39db5f54 journal_check_used_features +EXPORT_SYMBOL vmlinux 0x39e3a89e set_pages_nx +EXPORT_SYMBOL vmlinux 0x39e94d01 add_disk +EXPORT_SYMBOL vmlinux 0x3a06810a kmem_cache_alloc +EXPORT_SYMBOL vmlinux 0x3a0ab791 pci_request_region +EXPORT_SYMBOL vmlinux 0x3a140950 names_cachep +EXPORT_SYMBOL vmlinux 0x3a2204c6 security_netlink_recv +EXPORT_SYMBOL vmlinux 0x3a9a4ead bh_uptodate_or_lock +EXPORT_SYMBOL vmlinux 0x3a9b6fb9 blk_unregister_region +EXPORT_SYMBOL vmlinux 0x3aa1dbcf _spin_unlock_bh +EXPORT_SYMBOL vmlinux 0x3ae524d1 tcp_rcv_state_process +EXPORT_SYMBOL vmlinux 0x3aef256c fb_validate_mode +EXPORT_SYMBOL vmlinux 0x3af526cf ip_dev_find +EXPORT_SYMBOL vmlinux 0x3b3016d3 cpufreq_unregister_notifier +EXPORT_SYMBOL vmlinux 0x3b36dcc6 jbd2_journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0x3b647792 bdev_read_only +EXPORT_SYMBOL vmlinux 0x3b71c44d scsi_add_device +EXPORT_SYMBOL vmlinux 0x3b7e4b55 loop_register_transfer +EXPORT_SYMBOL vmlinux 0x3baf02aa page_symlink +EXPORT_SYMBOL vmlinux 0x3bbe5f11 xfrm_policy_delete +EXPORT_SYMBOL vmlinux 0x3bc43aea llc_build_and_send_ui_pkt +EXPORT_SYMBOL vmlinux 0x3bd1b1f6 msecs_to_jiffies +EXPORT_SYMBOL vmlinux 0x3be36c06 wireless_send_event +EXPORT_SYMBOL vmlinux 0x3bef183c blk_queue_set_discard +EXPORT_SYMBOL vmlinux 0x3c2c5af5 sprintf +EXPORT_SYMBOL vmlinux 0x3c2da4ba dquot_alloc_inode +EXPORT_SYMBOL vmlinux 0x3c7227bf complete_all +EXPORT_SYMBOL vmlinux 0x3c8cc3f4 invalidate_mapping_pages +EXPORT_SYMBOL vmlinux 0x3c922bd5 d_namespace_path +EXPORT_SYMBOL vmlinux 0x3c9d1211 string_get_size +EXPORT_SYMBOL vmlinux 0x3cb3931b sg_copy_to_buffer +EXPORT_SYMBOL vmlinux 0x3cb8a495 param_get_string +EXPORT_SYMBOL vmlinux 0x3cc0a3bb xfrm_spd_getinfo +EXPORT_SYMBOL vmlinux 0x3ce4ca6f disable_irq +EXPORT_SYMBOL vmlinux 0x3d135bc3 sock_create_kern +EXPORT_SYMBOL vmlinux 0x3d2c06ad journal_get_write_access +EXPORT_SYMBOL vmlinux 0x3d5a39fa block_prepare_write +EXPORT_SYMBOL vmlinux 0x3d6d9058 tty_register_device +EXPORT_SYMBOL vmlinux 0x3d929eb4 phy_scan_fixups +EXPORT_SYMBOL vmlinux 0x3da171f9 pci_mem_start +EXPORT_SYMBOL vmlinux 0x3da5eb6d kfifo_alloc +EXPORT_SYMBOL vmlinux 0x3e01bf15 jbd2_journal_create +EXPORT_SYMBOL vmlinux 0x3e14924a usb_serial_resume +EXPORT_SYMBOL vmlinux 0x3e1f073d wait_for_completion_timeout +EXPORT_SYMBOL vmlinux 0x3e219de6 try_wait_for_completion +EXPORT_SYMBOL vmlinux 0x3e2ae3a8 acpi_release_global_lock +EXPORT_SYMBOL vmlinux 0x3e329f7b devm_free_irq +EXPORT_SYMBOL vmlinux 0x3e36fdd7 page_put_link +EXPORT_SYMBOL vmlinux 0x3e383385 nf_hooks +EXPORT_SYMBOL vmlinux 0x3e3a0fbb pci_back_from_sleep +EXPORT_SYMBOL vmlinux 0x3e45e9ff register_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x3e5b48d0 setup_arg_pages +EXPORT_SYMBOL vmlinux 0x3e5c8349 nf_ct_attach +EXPORT_SYMBOL vmlinux 0x3e60643b inetdev_by_index +EXPORT_SYMBOL vmlinux 0x3e656a30 serio_open +EXPORT_SYMBOL vmlinux 0x3e76654a acpi_get_hp_hw_control_from_firmware +EXPORT_SYMBOL vmlinux 0x3ec5f73c sk_run_filter +EXPORT_SYMBOL vmlinux 0x3ed63055 zlib_inflateReset +EXPORT_SYMBOL vmlinux 0x3f0546a8 ioread32_rep +EXPORT_SYMBOL vmlinux 0x3f0881d8 call_usermodehelper_setcleanup +EXPORT_SYMBOL vmlinux 0x3f1899f1 up +EXPORT_SYMBOL vmlinux 0x3f241408 ethtool_op_set_flags +EXPORT_SYMBOL vmlinux 0x3f27fad0 qdisc_create_dflt +EXPORT_SYMBOL vmlinux 0x3f2c4102 iget_locked +EXPORT_SYMBOL vmlinux 0x3f39b162 up_write +EXPORT_SYMBOL vmlinux 0x3f4547a7 put_unused_fd +EXPORT_SYMBOL vmlinux 0x3f6c6734 kmem_cache_destroy +EXPORT_SYMBOL vmlinux 0x3f9d69ff journal_get_create_access +EXPORT_SYMBOL vmlinux 0x3fa6a814 d_instantiate +EXPORT_SYMBOL vmlinux 0x3fa7510b netif_receive_skb +EXPORT_SYMBOL vmlinux 0x3fac41d7 vfs_readlink +EXPORT_SYMBOL vmlinux 0x3fb0e0b2 alloc_netdev_mq +EXPORT_SYMBOL vmlinux 0x3fe447f4 vfs_path_lookup +EXPORT_SYMBOL vmlinux 0x3fec048f sg_next +EXPORT_SYMBOL vmlinux 0x3ff62317 local_bh_disable +EXPORT_SYMBOL vmlinux 0x3ff6de14 cdev_del +EXPORT_SYMBOL vmlinux 0x40010d26 bt_accept_enqueue +EXPORT_SYMBOL vmlinux 0x405354e0 ppp_input_error +EXPORT_SYMBOL vmlinux 0x4059792f print_hex_dump +EXPORT_SYMBOL vmlinux 0x405c1144 get_seconds +EXPORT_SYMBOL vmlinux 0x40927f7b set_bh_page +EXPORT_SYMBOL vmlinux 0x4094de2b con_is_bound +EXPORT_SYMBOL vmlinux 0x409873e3 tty_termios_baud_rate +EXPORT_SYMBOL vmlinux 0x4099a5a8 brioctl_set +EXPORT_SYMBOL vmlinux 0x40a1b568 bt_sock_unlink +EXPORT_SYMBOL vmlinux 0x40b8107e generic_block_bmap +EXPORT_SYMBOL vmlinux 0x40c89d46 acpi_get_table_by_index +EXPORT_SYMBOL vmlinux 0x40ed265b jbd2_journal_get_create_access +EXPORT_SYMBOL vmlinux 0x4105966a inode_double_unlock +EXPORT_SYMBOL vmlinux 0x4108e69a fb_match_mode +EXPORT_SYMBOL vmlinux 0x41482d8b strndup_user +EXPORT_SYMBOL vmlinux 0x415d0b62 ip_mc_rejoin_group +EXPORT_SYMBOL vmlinux 0x416983d9 netdev_fix_features +EXPORT_SYMBOL vmlinux 0x4185cf4b radix_tree_lookup_slot +EXPORT_SYMBOL vmlinux 0x41885662 thermal_zone_bind_cooling_device +EXPORT_SYMBOL vmlinux 0x4188d439 neigh_rand_reach_time +EXPORT_SYMBOL vmlinux 0x418c64fa skb_make_writable +EXPORT_SYMBOL vmlinux 0x41a9c68d _spin_trylock_bh +EXPORT_SYMBOL vmlinux 0x41af8866 phy_ethtool_gset +EXPORT_SYMBOL vmlinux 0x41cd589c simple_readpage +EXPORT_SYMBOL vmlinux 0x41cd9bb8 tcp_connect +EXPORT_SYMBOL vmlinux 0x41d49968 icmpv6_send +EXPORT_SYMBOL vmlinux 0x41e0d832 kobject_get +EXPORT_SYMBOL vmlinux 0x41f780ec fifo_create_dflt +EXPORT_SYMBOL vmlinux 0x41fc1ebf simple_statfs +EXPORT_SYMBOL vmlinux 0x4211c3c1 zlib_inflateInit2 +EXPORT_SYMBOL vmlinux 0x42224298 sscanf +EXPORT_SYMBOL vmlinux 0x42296c0a uart_unregister_driver +EXPORT_SYMBOL vmlinux 0x422a7ff1 dev_get_by_flags +EXPORT_SYMBOL vmlinux 0x422c05d0 acpi_get_data +EXPORT_SYMBOL vmlinux 0x425e6c9e key_task_permission +EXPORT_SYMBOL vmlinux 0x426abd86 inet_stream_connect +EXPORT_SYMBOL vmlinux 0x4292364c schedule +EXPORT_SYMBOL vmlinux 0x42c8de35 ioremap_nocache +EXPORT_SYMBOL vmlinux 0x42dfcbfa generic_unplug_device +EXPORT_SYMBOL vmlinux 0x42ee0051 contig_page_data +EXPORT_SYMBOL vmlinux 0x4300088b scsi_command_normalize_sense +EXPORT_SYMBOL vmlinux 0x4300301d d_alloc_name +EXPORT_SYMBOL vmlinux 0x4302d0eb free_pages +EXPORT_SYMBOL vmlinux 0x432481c1 d_find_alias +EXPORT_SYMBOL vmlinux 0x43385ad9 acpi_pci_unregister_driver +EXPORT_SYMBOL vmlinux 0x4338b57e dma_pool_free +EXPORT_SYMBOL vmlinux 0x434fa55c release_console_sem +EXPORT_SYMBOL vmlinux 0x435b566d _spin_unlock +EXPORT_SYMBOL vmlinux 0x436c2179 iowrite32 +EXPORT_SYMBOL vmlinux 0x436dab89 simple_getattr +EXPORT_SYMBOL vmlinux 0x43884405 xfrm_register_mode +EXPORT_SYMBOL vmlinux 0x4396c1d0 pfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0x43b40de7 kunmap_atomic +EXPORT_SYMBOL vmlinux 0x43c79c0e sock_common_getsockopt +EXPORT_SYMBOL vmlinux 0x43e4fd39 nf_unregister_sockopt +EXPORT_SYMBOL vmlinux 0x4409f15e neigh_table_init_no_netlink +EXPORT_SYMBOL vmlinux 0x44161c19 unregister_shrinker +EXPORT_SYMBOL vmlinux 0x44314efb radix_tree_gang_lookup_tag_slot +EXPORT_SYMBOL vmlinux 0x44430f45 backlight_device_register +EXPORT_SYMBOL vmlinux 0x444779c4 nla_find +EXPORT_SYMBOL vmlinux 0x44650226 inet6_release +EXPORT_SYMBOL vmlinux 0x447ee129 call_usermodehelper_setkeys +EXPORT_SYMBOL vmlinux 0x44aaf30f tsc_khz +EXPORT_SYMBOL vmlinux 0x44b38d03 lock_rename +EXPORT_SYMBOL vmlinux 0x44b911c3 rb_replace_node +EXPORT_SYMBOL vmlinux 0x44bcb6b7 pci_get_device +EXPORT_SYMBOL vmlinux 0x44c3f220 vfs_follow_link +EXPORT_SYMBOL vmlinux 0x44c41f98 register_qdisc +EXPORT_SYMBOL vmlinux 0x44db5e5a path_put +EXPORT_SYMBOL vmlinux 0x44e9a829 match_token +EXPORT_SYMBOL vmlinux 0x44f21bea idr_for_each +EXPORT_SYMBOL vmlinux 0x4500cfe7 sg_miter_stop +EXPORT_SYMBOL vmlinux 0x45060858 dev_set_mtu +EXPORT_SYMBOL vmlinux 0x4523463c simple_transaction_release +EXPORT_SYMBOL vmlinux 0x453ecf6b __inet6_lookup_established +EXPORT_SYMBOL vmlinux 0x4550ba8a register_cpu_notifier +EXPORT_SYMBOL vmlinux 0x455fd57d acpi_set_register +EXPORT_SYMBOL vmlinux 0x457f8b45 remap_vmalloc_range +EXPORT_SYMBOL vmlinux 0x4581b9c4 skb_recycle_check +EXPORT_SYMBOL vmlinux 0x45bb123e try_to_del_timer_sync +EXPORT_SYMBOL vmlinux 0x45d11c43 down_interruptible +EXPORT_SYMBOL vmlinux 0x45d2b60f search_binary_handler +EXPORT_SYMBOL vmlinux 0x45d766a4 kset_unregister +EXPORT_SYMBOL vmlinux 0x45e56523 misc_register +EXPORT_SYMBOL vmlinux 0x46285e7a acpi_is_video_device +EXPORT_SYMBOL vmlinux 0x462a2e75 match_strlcpy +EXPORT_SYMBOL vmlinux 0x463ab003 mdiobus_alloc +EXPORT_SYMBOL vmlinux 0x466c14a7 __delay +EXPORT_SYMBOL vmlinux 0x467a6f5d phy_register_fixup_for_uid +EXPORT_SYMBOL vmlinux 0x46d5fbc4 bitmap_close_sync +EXPORT_SYMBOL vmlinux 0x46e15256 bio_integrity_free +EXPORT_SYMBOL vmlinux 0x4728099c scsi_test_unit_ready +EXPORT_SYMBOL vmlinux 0x472d2a9a radix_tree_lookup +EXPORT_SYMBOL vmlinux 0x4737d690 xfrm_policy_destroy +EXPORT_SYMBOL vmlinux 0x473aed05 bt_accept_dequeue +EXPORT_SYMBOL vmlinux 0x475100c2 inet_get_local_port_range +EXPORT_SYMBOL vmlinux 0x475f010b acpi_purge_cached_objects +EXPORT_SYMBOL vmlinux 0x47658965 tcp_md5_hash_skb_data +EXPORT_SYMBOL vmlinux 0x47711465 kmem_cache_free +EXPORT_SYMBOL vmlinux 0x47831af6 del_gendisk +EXPORT_SYMBOL vmlinux 0x478d10b2 ht_destroy_irq +EXPORT_SYMBOL vmlinux 0x47939e0d __tasklet_hi_schedule +EXPORT_SYMBOL vmlinux 0x479c3c86 find_next_zero_bit +EXPORT_SYMBOL vmlinux 0x47b61d32 ppp_channel_index +EXPORT_SYMBOL vmlinux 0x47c62d70 xfrm_policy_flush +EXPORT_SYMBOL vmlinux 0x481cb9ab acpi_enter_sleep_state_prep +EXPORT_SYMBOL vmlinux 0x4859b8bb rtc_year_days +EXPORT_SYMBOL vmlinux 0x486653fe kthread_create +EXPORT_SYMBOL vmlinux 0x486b6407 hweight64 +EXPORT_SYMBOL vmlinux 0x4879276b ppp_input +EXPORT_SYMBOL vmlinux 0x488d90d2 set_bdi_congested +EXPORT_SYMBOL vmlinux 0x489b5ff5 tty_unregister_driver +EXPORT_SYMBOL vmlinux 0x48ce3fe7 scsi_calculate_bounce_limit +EXPORT_SYMBOL vmlinux 0x48e6348e pnp_start_dev +EXPORT_SYMBOL vmlinux 0x48efd0ca ioctl_by_bdev +EXPORT_SYMBOL vmlinux 0x490c1cb8 llc_add_pack +EXPORT_SYMBOL vmlinux 0x49293b2e unregister_filesystem +EXPORT_SYMBOL vmlinux 0x493e25e1 udp_hash +EXPORT_SYMBOL vmlinux 0x494aa699 sync_blockdev +EXPORT_SYMBOL vmlinux 0x49603fb8 security_sb_copy_data +EXPORT_SYMBOL vmlinux 0x49719ead sock_register +EXPORT_SYMBOL vmlinux 0x4993e71b put_disk +EXPORT_SYMBOL vmlinux 0x499d172e i2c_smbus_read_i2c_block_data +EXPORT_SYMBOL vmlinux 0x49da9a9a _read_unlock_bh +EXPORT_SYMBOL vmlinux 0x49e9e671 pcim_enable_device +EXPORT_SYMBOL vmlinux 0x49eae432 mb_cache_entry_find_next +EXPORT_SYMBOL vmlinux 0x49ef4f3c iget_failed +EXPORT_SYMBOL vmlinux 0x49f9c5c8 sock_wmalloc +EXPORT_SYMBOL vmlinux 0x4a2115bb deny_write_access +EXPORT_SYMBOL vmlinux 0x4a30e6a7 __scsi_alloc_queue +EXPORT_SYMBOL vmlinux 0x4a358252 __bitmap_subset +EXPORT_SYMBOL vmlinux 0x4a506bb0 scsi_finish_command +EXPORT_SYMBOL vmlinux 0x4a6564fb filp_open +EXPORT_SYMBOL vmlinux 0x4a81ecbc elevator_init +EXPORT_SYMBOL vmlinux 0x4a971ec7 radix_tree_delete +EXPORT_SYMBOL vmlinux 0x4acd93d3 release_resource +EXPORT_SYMBOL vmlinux 0x4ad0c874 journal_clear_err +EXPORT_SYMBOL vmlinux 0x4af9cb96 splice_direct_to_actor +EXPORT_SYMBOL vmlinux 0x4afae8ad unlock_buffer +EXPORT_SYMBOL vmlinux 0x4afe9a77 scsi_partsize +EXPORT_SYMBOL vmlinux 0x4b040b9f sk_stream_wait_close +EXPORT_SYMBOL vmlinux 0x4b07e779 _spin_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x4b290386 bdi_set_max_ratio +EXPORT_SYMBOL vmlinux 0x4b2f14b4 jiffies_to_timespec +EXPORT_SYMBOL vmlinux 0x4b34fbf5 block_all_signals +EXPORT_SYMBOL vmlinux 0x4b439997 fib_default_rule_add +EXPORT_SYMBOL vmlinux 0x4b53b315 journal_unlock_updates +EXPORT_SYMBOL vmlinux 0x4b56abca vfs_read +EXPORT_SYMBOL vmlinux 0x4b77c0d1 tcf_hash_insert +EXPORT_SYMBOL vmlinux 0x4bbc1a5e unregister_sysctl_table +EXPORT_SYMBOL vmlinux 0x4bbc3e5f pm_flags +EXPORT_SYMBOL vmlinux 0x4bbe47d4 flush_tlb_page +EXPORT_SYMBOL vmlinux 0x4bf48912 tty_port_tty_set +EXPORT_SYMBOL vmlinux 0x4c1182cb bitmap_scnprintf +EXPORT_SYMBOL vmlinux 0x4c27a1d2 vfs_get_dqblk +EXPORT_SYMBOL vmlinux 0x4c323adc skb_kill_datagram +EXPORT_SYMBOL vmlinux 0x4c606467 bitmap_startwrite +EXPORT_SYMBOL vmlinux 0x4c776ec6 new_inode +EXPORT_SYMBOL vmlinux 0x4ca9023a gnet_stats_copy_rate_est +EXPORT_SYMBOL vmlinux 0x4cbbd171 __bitmap_weight +EXPORT_SYMBOL vmlinux 0x4cbf7ff9 seq_puts +EXPORT_SYMBOL vmlinux 0x4ce16c5a free_netdev +EXPORT_SYMBOL vmlinux 0x4cf1f3b6 sock_no_listen +EXPORT_SYMBOL vmlinux 0x4d2674ca scsi_remove_device +EXPORT_SYMBOL vmlinux 0x4d287566 unregister_qdisc +EXPORT_SYMBOL vmlinux 0x4d2dc830 acpi_get_object_info +EXPORT_SYMBOL vmlinux 0x4d33bfcf is_bad_inode +EXPORT_SYMBOL vmlinux 0x4d3c153f sigprocmask +EXPORT_SYMBOL vmlinux 0x4dc2a022 get_sb_pseudo +EXPORT_SYMBOL vmlinux 0x4dd295fe rfkill_register +EXPORT_SYMBOL vmlinux 0x4ddc4b9f utf8_mbtowc +EXPORT_SYMBOL vmlinux 0x4dddcd58 acpi_root_dir +EXPORT_SYMBOL vmlinux 0x4de5d94f wait_on_page_bit +EXPORT_SYMBOL vmlinux 0x4df119fa __bitmap_parse +EXPORT_SYMBOL vmlinux 0x4e100f60 _spin_unlock_irq +EXPORT_SYMBOL vmlinux 0x4e3567f7 match_int +EXPORT_SYMBOL vmlinux 0x4e3b1f58 tty_unthrottle +EXPORT_SYMBOL vmlinux 0x4e3bbfc1 jbd2_journal_check_used_features +EXPORT_SYMBOL vmlinux 0x4e59573d pci_set_dma_mask +EXPORT_SYMBOL vmlinux 0x4e6e8ea7 fg_console +EXPORT_SYMBOL vmlinux 0x4e830a3e strnicmp +EXPORT_SYMBOL vmlinux 0x4e8f36a9 pci_disable_device +EXPORT_SYMBOL vmlinux 0x4ed03b8f send_sig +EXPORT_SYMBOL vmlinux 0x4ef2f284 key_alloc +EXPORT_SYMBOL vmlinux 0x4f184e90 i2c_probe +EXPORT_SYMBOL vmlinux 0x4f3449a9 journal_load +EXPORT_SYMBOL vmlinux 0x4f476e96 init_cdrom_command +EXPORT_SYMBOL vmlinux 0x4f5438c1 idle_halt +EXPORT_SYMBOL vmlinux 0x4f671cc8 i2c_smbus_read_byte_data +EXPORT_SYMBOL vmlinux 0x4fd24acb iw_handler_set_spy +EXPORT_SYMBOL vmlinux 0x4fdee897 i8042_command +EXPORT_SYMBOL vmlinux 0x4ff2dbe5 netlink_clear_multicast_users +EXPORT_SYMBOL vmlinux 0x5004e1d6 hci_conn_auth +EXPORT_SYMBOL vmlinux 0x50100f5a tcp_child_process +EXPORT_SYMBOL vmlinux 0x50104f25 bio_clone +EXPORT_SYMBOL vmlinux 0x50211ee3 tcp_free_md5sig_pool +EXPORT_SYMBOL vmlinux 0x50424da5 scsi_is_host_device +EXPORT_SYMBOL vmlinux 0x505910b1 xfrm_state_lookup_byaddr +EXPORT_SYMBOL vmlinux 0x50597dab vfs_write +EXPORT_SYMBOL vmlinux 0x5099af98 dev_disable_lro +EXPORT_SYMBOL vmlinux 0x509ac417 __devm_request_region +EXPORT_SYMBOL vmlinux 0x5118c382 secure_dccp_sequence_number +EXPORT_SYMBOL vmlinux 0x511e8174 ethtool_op_set_tx_ipv6_csum +EXPORT_SYMBOL vmlinux 0x51283648 blk_queue_prep_rq +EXPORT_SYMBOL vmlinux 0x5142204e bio_add_page +EXPORT_SYMBOL vmlinux 0x5152e605 memcmp +EXPORT_SYMBOL vmlinux 0x518eb764 per_cpu__cpu_number +EXPORT_SYMBOL vmlinux 0x51d12d4e acpi_pci_disabled +EXPORT_SYMBOL vmlinux 0x51d7a776 acpi_detach_data +EXPORT_SYMBOL vmlinux 0x51dce73b xfrm_state_walk_init +EXPORT_SYMBOL vmlinux 0x51e8fb06 remove_arg_zero +EXPORT_SYMBOL vmlinux 0x51ef33b8 kstrndup +EXPORT_SYMBOL vmlinux 0x51ef575e grab_cache_page_nowait +EXPORT_SYMBOL vmlinux 0x51f49cec scsi_cmd_ioctl +EXPORT_SYMBOL vmlinux 0x52026cdf security_sb_parse_opts_str +EXPORT_SYMBOL vmlinux 0x5205745e jbd2_journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0x5210998a tcp_prot +EXPORT_SYMBOL vmlinux 0x52138767 blk_rq_map_integrity_sg +EXPORT_SYMBOL vmlinux 0x52209015 vfs_quota_on +EXPORT_SYMBOL vmlinux 0x528c709d simple_read_from_buffer +EXPORT_SYMBOL vmlinux 0x52a58c24 ifla_policy +EXPORT_SYMBOL vmlinux 0x52d7b2fd llc_sap_list +EXPORT_SYMBOL vmlinux 0x52e24296 key_validate +EXPORT_SYMBOL vmlinux 0x52e38148 skb_checksum_help +EXPORT_SYMBOL vmlinux 0x53043afd sock_recvmsg +EXPORT_SYMBOL vmlinux 0x530b1e98 pm_suspend +EXPORT_SYMBOL vmlinux 0x530c58ef nf_unregister_queue_handler +EXPORT_SYMBOL vmlinux 0x531b604e __virt_addr_valid +EXPORT_SYMBOL vmlinux 0x53253e8c scsi_host_lookup +EXPORT_SYMBOL vmlinux 0x532f2924 param_get_byte +EXPORT_SYMBOL vmlinux 0x53326531 mempool_alloc_pages +EXPORT_SYMBOL vmlinux 0x5334a277 blk_rq_unmap_user +EXPORT_SYMBOL vmlinux 0x533600c6 vfs_getattr +EXPORT_SYMBOL vmlinux 0x53758a9e elevator_exit +EXPORT_SYMBOL vmlinux 0x538383c0 unregister_inet6addr_notifier +EXPORT_SYMBOL vmlinux 0x539a2954 unregister_netdev +EXPORT_SYMBOL vmlinux 0x53c0767c sk_chk_filter +EXPORT_SYMBOL vmlinux 0x53dd49eb do_sync_read +EXPORT_SYMBOL vmlinux 0x53f1cd25 grab_cache_page_write_begin +EXPORT_SYMBOL vmlinux 0x54050514 posix_acl_permission +EXPORT_SYMBOL vmlinux 0x54290dc9 nla_validate +EXPORT_SYMBOL vmlinux 0x54394f8d bio_copy_kern +EXPORT_SYMBOL vmlinux 0x543affb5 per_cpu__kstat +EXPORT_SYMBOL vmlinux 0x544c99ad xfrm6_input_addr +EXPORT_SYMBOL vmlinux 0x546f4271 dev_alloc_name +EXPORT_SYMBOL vmlinux 0x54794c25 kernel_bind +EXPORT_SYMBOL vmlinux 0x54935666 acpi_os_read_port +EXPORT_SYMBOL vmlinux 0x549caecc sock_wake_async +EXPORT_SYMBOL vmlinux 0x54b81541 init_timer_deferrable +EXPORT_SYMBOL vmlinux 0x54c2f156 fb_set_var +EXPORT_SYMBOL vmlinux 0x54e6fcdd net_enable_timestamp +EXPORT_SYMBOL vmlinux 0x54f6ee6b register_binfmt +EXPORT_SYMBOL vmlinux 0x54f99c56 free_buffer_head +EXPORT_SYMBOL vmlinux 0x5522eb16 task_pgrp_nr_ns +EXPORT_SYMBOL vmlinux 0x553f9dd3 down_read_trylock +EXPORT_SYMBOL vmlinux 0x5542dfb5 mapping_tagged +EXPORT_SYMBOL vmlinux 0x5542e3d7 pcim_iounmap_regions +EXPORT_SYMBOL vmlinux 0x557b297b dmam_pool_create +EXPORT_SYMBOL vmlinux 0x55895ee2 sock_i_ino +EXPORT_SYMBOL vmlinux 0x5594be03 bitmap_remap +EXPORT_SYMBOL vmlinux 0x55c28c00 security_d_instantiate +EXPORT_SYMBOL vmlinux 0x55d5aa30 __alloc_skb +EXPORT_SYMBOL vmlinux 0x55e12f0a sock_init_data +EXPORT_SYMBOL vmlinux 0x5600904f fb_get_color_depth +EXPORT_SYMBOL vmlinux 0x5600ef54 skb_copy_datagram_from_iovec +EXPORT_SYMBOL vmlinux 0x5611b1c0 ip6_route_output +EXPORT_SYMBOL vmlinux 0x5614b010 xfrm_policy_walk_done +EXPORT_SYMBOL vmlinux 0x562800f1 may_umount +EXPORT_SYMBOL vmlinux 0x562d4f8f inet_listen +EXPORT_SYMBOL vmlinux 0x562e0bd6 init_file +EXPORT_SYMBOL vmlinux 0x5635a60a vmalloc_user +EXPORT_SYMBOL vmlinux 0x5645edfa eth_header_cache_update +EXPORT_SYMBOL vmlinux 0x5658fcff ip_cmsg_recv +EXPORT_SYMBOL vmlinux 0x565dbcc2 neigh_event_ns +EXPORT_SYMBOL vmlinux 0x56774390 udp_flush_pending_frames +EXPORT_SYMBOL vmlinux 0x567e652a ethtool_op_get_sg +EXPORT_SYMBOL vmlinux 0x567f0382 generic_write_checks +EXPORT_SYMBOL vmlinux 0x56c8799d scsi_kunmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x56f494e0 smp_call_function +EXPORT_SYMBOL vmlinux 0x5707982f jbd2_journal_start +EXPORT_SYMBOL vmlinux 0x57087464 tc_classify_compat +EXPORT_SYMBOL vmlinux 0x571a0ef7 pci_try_set_mwi +EXPORT_SYMBOL vmlinux 0x572e85d4 blk_lookup_devt +EXPORT_SYMBOL vmlinux 0x57345415 pci_clear_mwi +EXPORT_SYMBOL vmlinux 0x576c9354 skb_pad +EXPORT_SYMBOL vmlinux 0x577cc638 mutex_unlock +EXPORT_SYMBOL vmlinux 0x578f94e8 __scsi_iterate_devices +EXPORT_SYMBOL vmlinux 0x57a6504e vsnprintf +EXPORT_SYMBOL vmlinux 0x57ae17d8 input_set_keycode +EXPORT_SYMBOL vmlinux 0x57f6d969 tty_port_init +EXPORT_SYMBOL vmlinux 0x5838f6c9 rtc_valid_tm +EXPORT_SYMBOL vmlinux 0x5842ce8e kick_iocb +EXPORT_SYMBOL vmlinux 0x5844bd0a __pskb_pull_tail +EXPORT_SYMBOL vmlinux 0x584738f9 rdmsr_safe_on_cpu +EXPORT_SYMBOL vmlinux 0x5857b225 ioread16_rep +EXPORT_SYMBOL vmlinux 0x586415ec llc_set_station_handler +EXPORT_SYMBOL vmlinux 0x58d3e547 arp_xmit +EXPORT_SYMBOL vmlinux 0x58e7a88a secpath_dup +EXPORT_SYMBOL vmlinux 0x58fef6f8 ist_info +EXPORT_SYMBOL vmlinux 0x590e40df uart_register_driver +EXPORT_SYMBOL vmlinux 0x591219d1 thaw_process +EXPORT_SYMBOL vmlinux 0x592634ba skb_copy_and_csum_datagram_iovec +EXPORT_SYMBOL vmlinux 0x5934392b fb_register_client +EXPORT_SYMBOL vmlinux 0x5942b444 xfrm4_prepare_output +EXPORT_SYMBOL vmlinux 0x594bf15b ioport_map +EXPORT_SYMBOL vmlinux 0x59706f79 nf_log_unregister_pf +EXPORT_SYMBOL vmlinux 0x5984e4fd acpi_processor_register_performance +EXPORT_SYMBOL vmlinux 0x598cb6ea dst_alloc +EXPORT_SYMBOL vmlinux 0x59a5fd6a tcp_init_xmit_timers +EXPORT_SYMBOL vmlinux 0x59d696b6 register_module_notifier +EXPORT_SYMBOL vmlinux 0x59e3f9e8 inet_addr_type +EXPORT_SYMBOL vmlinux 0x59e4af13 sk_release_kernel +EXPORT_SYMBOL vmlinux 0x59f04351 jbd2_journal_revoke +EXPORT_SYMBOL vmlinux 0x59f06a85 set_device_ro +EXPORT_SYMBOL vmlinux 0x5a12892e kobject_put +EXPORT_SYMBOL vmlinux 0x5a4896a8 __put_user_2 +EXPORT_SYMBOL vmlinux 0x5a562885 phy_mii_ioctl +EXPORT_SYMBOL vmlinux 0x5a5d884a security_inode_init_security +EXPORT_SYMBOL vmlinux 0x5a69274c sock_get_timestamp +EXPORT_SYMBOL vmlinux 0x5a744b86 netlink_set_nonroot +EXPORT_SYMBOL vmlinux 0x5a7ce15a xfrm_state_delete_tunnel +EXPORT_SYMBOL vmlinux 0x5a8466f1 skb_dequeue +EXPORT_SYMBOL vmlinux 0x5aa3d78c kernel_setsockopt +EXPORT_SYMBOL vmlinux 0x5aa5927c proc_symlink +EXPORT_SYMBOL vmlinux 0x5abe665b __scm_send +EXPORT_SYMBOL vmlinux 0x5ac376a5 acpi_install_fixed_event_handler +EXPORT_SYMBOL vmlinux 0x5ad2f5f1 blk_sync_queue +EXPORT_SYMBOL vmlinux 0x5b02efaa pci_save_state +EXPORT_SYMBOL vmlinux 0x5b0b820f dma_set_mask +EXPORT_SYMBOL vmlinux 0x5b0cc7da scsi_nonblockable_ioctl +EXPORT_SYMBOL vmlinux 0x5b19634d div_s64_rem +EXPORT_SYMBOL vmlinux 0x5b51c6a7 acpi_walk_resources +EXPORT_SYMBOL vmlinux 0x5b5c2d06 __bread +EXPORT_SYMBOL vmlinux 0x5b933fab register_nls +EXPORT_SYMBOL vmlinux 0x5b9b135b tcp_sendpage +EXPORT_SYMBOL vmlinux 0x5bf1e2f3 dm_dirty_log_type_unregister +EXPORT_SYMBOL vmlinux 0x5c1e6e84 ipv6_push_nfrag_opts +EXPORT_SYMBOL vmlinux 0x5c20f294 jbd2_journal_init_inode +EXPORT_SYMBOL vmlinux 0x5c27708a vfs_quota_on_mount +EXPORT_SYMBOL vmlinux 0x5c564cc5 __brelse +EXPORT_SYMBOL vmlinux 0x5c59d542 __elv_add_request +EXPORT_SYMBOL vmlinux 0x5c68705b mca_read_pos +EXPORT_SYMBOL vmlinux 0x5c9d1555 noop_qdisc +EXPORT_SYMBOL vmlinux 0x5cd37b3a simple_link +EXPORT_SYMBOL vmlinux 0x5cd9a8c5 pci_iounmap +EXPORT_SYMBOL vmlinux 0x5d02f3a9 blk_queue_init_tags +EXPORT_SYMBOL vmlinux 0x5d0b8abc tcp_poll +EXPORT_SYMBOL vmlinux 0x5d13e6c4 blk_init_queue_node +EXPORT_SYMBOL vmlinux 0x5d24c202 i2c_transfer +EXPORT_SYMBOL vmlinux 0x5d46b10e jbd2_journal_begin_ordered_truncate +EXPORT_SYMBOL vmlinux 0x5d73b5f8 km_waitq +EXPORT_SYMBOL vmlinux 0x5d8c4bb6 sysctl_string +EXPORT_SYMBOL vmlinux 0x5d8e5a68 xrlim_allow +EXPORT_SYMBOL vmlinux 0x5d991093 inet_frags_fini +EXPORT_SYMBOL vmlinux 0x5d99eb6b blk_rq_map_user +EXPORT_SYMBOL vmlinux 0x5daedf24 check_disk_change +EXPORT_SYMBOL vmlinux 0x5dbcfa4f boot_cpu_physical_apicid +EXPORT_SYMBOL vmlinux 0x5dde3d9e tcp_alloc_md5sig_pool +EXPORT_SYMBOL vmlinux 0x5e0762fd dev_set_mac_address +EXPORT_SYMBOL vmlinux 0x5e2e8b35 block_is_partially_uptodate +EXPORT_SYMBOL vmlinux 0x5e2f0384 register_exec_domain +EXPORT_SYMBOL vmlinux 0x5e4582ed blk_insert_request +EXPORT_SYMBOL vmlinux 0x5e7381dc generic_file_llseek +EXPORT_SYMBOL vmlinux 0x5e79ebec gen_replace_estimator +EXPORT_SYMBOL vmlinux 0x5e8218e7 dev_kfree_skb_any +EXPORT_SYMBOL vmlinux 0x5e92ecf3 register_con_driver +EXPORT_SYMBOL vmlinux 0x5ea520c5 tcp_select_initial_window +EXPORT_SYMBOL vmlinux 0x5ea9f02d blkdev_issue_flush +EXPORT_SYMBOL vmlinux 0x5eab03f5 i2c_register_driver +EXPORT_SYMBOL vmlinux 0x5ed040b0 pm_set_vt_switch +EXPORT_SYMBOL vmlinux 0x5ed878fc __bforget +EXPORT_SYMBOL vmlinux 0x5edd0762 bin2bcd +EXPORT_SYMBOL vmlinux 0x5f043316 bitmap_unplug +EXPORT_SYMBOL vmlinux 0x5f12887b vfs_rename +EXPORT_SYMBOL vmlinux 0x5f13cc17 clear_page_dirty_for_io +EXPORT_SYMBOL vmlinux 0x5f1bd579 mca_find_adapter +EXPORT_SYMBOL vmlinux 0x5f23a8fc generic_file_splice_write +EXPORT_SYMBOL vmlinux 0x5f4042df pcim_iomap_regions_request_all +EXPORT_SYMBOL vmlinux 0x5f4d66b5 udp_lib_getsockopt +EXPORT_SYMBOL vmlinux 0x5f5fb54c sk_stream_write_space +EXPORT_SYMBOL vmlinux 0x5f6a3695 kernel_read +EXPORT_SYMBOL vmlinux 0x5f7439e1 xfrm_policy_unregister_afinfo +EXPORT_SYMBOL vmlinux 0x5f8d5549 locks_copy_lock +EXPORT_SYMBOL vmlinux 0x5fc41507 seq_path +EXPORT_SYMBOL vmlinux 0x5ff42b08 acpi_video_get_capabilities +EXPORT_SYMBOL vmlinux 0x5ffb0993 scsi_unregister +EXPORT_SYMBOL vmlinux 0x600683d3 do_unblank_screen +EXPORT_SYMBOL vmlinux 0x602187e8 vfs_mknod +EXPORT_SYMBOL vmlinux 0x6068e2b5 d_prune_aliases +EXPORT_SYMBOL vmlinux 0x60731078 udp_proc_register +EXPORT_SYMBOL vmlinux 0x608c2831 warn_on_slowpath +EXPORT_SYMBOL vmlinux 0x609ba936 vfs_llseek +EXPORT_SYMBOL vmlinux 0x609f1c7e synchronize_net +EXPORT_SYMBOL vmlinux 0x60a32ea9 pm_power_off +EXPORT_SYMBOL vmlinux 0x60c39d5e scsi_release_buffers +EXPORT_SYMBOL vmlinux 0x60cc4b27 ilookup5_nowait +EXPORT_SYMBOL vmlinux 0x60f74944 bh_submit_read +EXPORT_SYMBOL vmlinux 0x60fa9e1c __seq_open_private +EXPORT_SYMBOL vmlinux 0x6111e1bc init_timer +EXPORT_SYMBOL vmlinux 0x611310b9 tty_unregister_device +EXPORT_SYMBOL vmlinux 0x61209d86 tty_flip_buffer_push +EXPORT_SYMBOL vmlinux 0x612390ad netpoll_set_trap +EXPORT_SYMBOL vmlinux 0x6154e8d2 __dev_remove_pack +EXPORT_SYMBOL vmlinux 0x6156ff01 km_policy_notify +EXPORT_SYMBOL vmlinux 0x61692175 single_release +EXPORT_SYMBOL vmlinux 0x616ee933 sock_map_fd +EXPORT_SYMBOL vmlinux 0x618d8299 set_notify_swap_entry_free +EXPORT_SYMBOL vmlinux 0x61b6a4c9 alloc_file +EXPORT_SYMBOL vmlinux 0x61b7b126 simple_strtoull +EXPORT_SYMBOL vmlinux 0x61ed0811 set_pages_wb +EXPORT_SYMBOL vmlinux 0x61ef4802 __blk_run_queue +EXPORT_SYMBOL vmlinux 0x62049256 acpi_disable +EXPORT_SYMBOL vmlinux 0x62251885 bt_sock_link +EXPORT_SYMBOL vmlinux 0x62257c92 tcf_action_exec +EXPORT_SYMBOL vmlinux 0x6237f6b5 acpi_enable_event +EXPORT_SYMBOL vmlinux 0x6241a2ab __copy_from_user_ll_nocache +EXPORT_SYMBOL vmlinux 0x6241fd2c acpi_install_address_space_handler +EXPORT_SYMBOL vmlinux 0x62737e1d sock_unregister +EXPORT_SYMBOL vmlinux 0x62797ca7 bio_unmap_user +EXPORT_SYMBOL vmlinux 0x62827bec security_secctx_to_secid +EXPORT_SYMBOL vmlinux 0x62922b4c acpi_bus_generate_proc_event +EXPORT_SYMBOL vmlinux 0x62bd776a __mod_zone_page_state +EXPORT_SYMBOL vmlinux 0x62c3876a atm_dev_register +EXPORT_SYMBOL vmlinux 0x62e0f340 mb_cache_entry_get +EXPORT_SYMBOL vmlinux 0x62f3c361 cdev_init +EXPORT_SYMBOL vmlinux 0x635b8f84 __nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0x636a5691 acpi_register_ioapic +EXPORT_SYMBOL vmlinux 0x63c3ec8f page_zero_new_buffers +EXPORT_SYMBOL vmlinux 0x63ecad53 register_netdevice_notifier +EXPORT_SYMBOL vmlinux 0x63f55c72 input_get_keycode +EXPORT_SYMBOL vmlinux 0x6403e338 tcp_memory_pressure +EXPORT_SYMBOL vmlinux 0x642e54ac __wake_up +EXPORT_SYMBOL vmlinux 0x6451294b posix_acl_valid +EXPORT_SYMBOL vmlinux 0x6466a1e6 mempool_alloc +EXPORT_SYMBOL vmlinux 0x6478134c ec_burst_enable +EXPORT_SYMBOL vmlinux 0x6485a830 find_or_create_page +EXPORT_SYMBOL vmlinux 0x64999478 congestion_wait +EXPORT_SYMBOL vmlinux 0x64a46d8d per_cpu__softnet_data +EXPORT_SYMBOL vmlinux 0x64cd5d16 init_waitqueue_head +EXPORT_SYMBOL vmlinux 0x64dc5bb8 jbd2_journal_stop +EXPORT_SYMBOL vmlinux 0x64eae7ad set_memory_array_wb +EXPORT_SYMBOL vmlinux 0x650128e7 br_fdb_get_hook +EXPORT_SYMBOL vmlinux 0x650fb346 add_wait_queue +EXPORT_SYMBOL vmlinux 0x651a3deb jbd2_journal_get_write_access +EXPORT_SYMBOL vmlinux 0x651a4139 test_taint +EXPORT_SYMBOL vmlinux 0x65241670 xfrm_input +EXPORT_SYMBOL vmlinux 0x6534f2da md_write_end +EXPORT_SYMBOL vmlinux 0x653696c8 d_lookup +EXPORT_SYMBOL vmlinux 0x65408378 zlib_inflate_blob +EXPORT_SYMBOL vmlinux 0x65414e67 dev_valid_name +EXPORT_SYMBOL vmlinux 0x6554a697 sk_filter +EXPORT_SYMBOL vmlinux 0x6565d33f scsi_kmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x6567ae60 key_link +EXPORT_SYMBOL vmlinux 0x656f7cd5 xfrm_register_km +EXPORT_SYMBOL vmlinux 0x657ef0ad __netdev_alloc_page +EXPORT_SYMBOL vmlinux 0x659458b1 skb_pull +EXPORT_SYMBOL vmlinux 0x65946dfb dquot_transfer +EXPORT_SYMBOL vmlinux 0x65a4cb48 blk_queue_update_dma_pad +EXPORT_SYMBOL vmlinux 0x6615a33c pci_bus_read_config_byte +EXPORT_SYMBOL vmlinux 0x661a36eb generic_cont_expand_simple +EXPORT_SYMBOL vmlinux 0x661cb96a pci_release_selected_regions +EXPORT_SYMBOL vmlinux 0x66525acf __sk_mem_reclaim +EXPORT_SYMBOL vmlinux 0x66724ae2 inet_unregister_protosw +EXPORT_SYMBOL vmlinux 0x667c7e6b flush_signals +EXPORT_SYMBOL vmlinux 0x668da8d5 zlib_inflateIncomp +EXPORT_SYMBOL vmlinux 0x66da08ab seq_release_private +EXPORT_SYMBOL vmlinux 0x66edfba9 find_vma +EXPORT_SYMBOL vmlinux 0x6729d3df __get_user_4 +EXPORT_SYMBOL vmlinux 0x6730a642 gnet_stats_start_copy +EXPORT_SYMBOL vmlinux 0x6760897c inode_add_bytes +EXPORT_SYMBOL vmlinux 0x6768172f inet_dgram_ops +EXPORT_SYMBOL vmlinux 0x676a37c1 ip6_route_me_harder +EXPORT_SYMBOL vmlinux 0x676c0659 scsi_prep_state_check +EXPORT_SYMBOL vmlinux 0x676ce3e6 get_unmapped_area +EXPORT_SYMBOL vmlinux 0x67795e73 mmc_resume_host +EXPORT_SYMBOL vmlinux 0x677a71c7 hci_unregister_dev +EXPORT_SYMBOL vmlinux 0x6782ca33 k8_northbridges +EXPORT_SYMBOL vmlinux 0x67837810 mb_cache_entry_insert +EXPORT_SYMBOL vmlinux 0x679831f9 dev_set_promiscuity +EXPORT_SYMBOL vmlinux 0x67b27ec1 tty_std_termios +EXPORT_SYMBOL vmlinux 0x67e51408 tcp_simple_retransmit +EXPORT_SYMBOL vmlinux 0x67e71b77 __mutex_init +EXPORT_SYMBOL vmlinux 0x6803b632 nf_unregister_hook +EXPORT_SYMBOL vmlinux 0x680501a0 d_rehash +EXPORT_SYMBOL vmlinux 0x68303e4f alloc_tty_driver +EXPORT_SYMBOL vmlinux 0x6835afc9 posix_unblock_lock +EXPORT_SYMBOL vmlinux 0x686641ab tty_free_termios +EXPORT_SYMBOL vmlinux 0x68885501 mmc_set_data_timeout +EXPORT_SYMBOL vmlinux 0x688a53e4 nla_append +EXPORT_SYMBOL vmlinux 0x688fc309 dm_put_device +EXPORT_SYMBOL vmlinux 0x68ac1763 mdiobus_scan +EXPORT_SYMBOL vmlinux 0x68cf75d5 dcache_dir_close +EXPORT_SYMBOL vmlinux 0x68d5c42b journal_flush +EXPORT_SYMBOL vmlinux 0x68eac508 pci_set_dma_max_seg_size +EXPORT_SYMBOL vmlinux 0x690f9490 tty_get_baud_rate +EXPORT_SYMBOL vmlinux 0x690fda12 qdisc_destroy +EXPORT_SYMBOL vmlinux 0x6963ab0e nla_put +EXPORT_SYMBOL vmlinux 0x69674298 vfs_readv +EXPORT_SYMBOL vmlinux 0x6971447a rtc_month_days +EXPORT_SYMBOL vmlinux 0x69927dff try_acquire_console_sem +EXPORT_SYMBOL vmlinux 0x699848fe __ip_select_ident +EXPORT_SYMBOL vmlinux 0x699ba2a3 tty_driver_flush_buffer +EXPORT_SYMBOL vmlinux 0x69a0ca7d iowrite16be +EXPORT_SYMBOL vmlinux 0x69a358a6 iomem_resource +EXPORT_SYMBOL vmlinux 0x69c8c1d5 security_req_classify_flow +EXPORT_SYMBOL vmlinux 0x69d2575f efi +EXPORT_SYMBOL vmlinux 0x69d38ed9 __scsi_print_sense +EXPORT_SYMBOL vmlinux 0x69e27c7a bitmap_copy_le +EXPORT_SYMBOL vmlinux 0x69f26828 kobject_set_name +EXPORT_SYMBOL vmlinux 0x6a037cf1 mempool_kfree +EXPORT_SYMBOL vmlinux 0x6a18b6ff register_atm_ioctl +EXPORT_SYMBOL vmlinux 0x6a2579a5 eth_header +EXPORT_SYMBOL vmlinux 0x6a27bfce csum_partial_copy_generic +EXPORT_SYMBOL vmlinux 0x6a294557 alloc_pci_dev +EXPORT_SYMBOL vmlinux 0x6a308b68 udp_sendmsg +EXPORT_SYMBOL vmlinux 0x6a3b908c ppp_register_compressor +EXPORT_SYMBOL vmlinux 0x6a47571d __set_personality +EXPORT_SYMBOL vmlinux 0x6a6cc4bb key_payload_reserve +EXPORT_SYMBOL vmlinux 0x6aae09de gnet_stats_copy_basic +EXPORT_SYMBOL vmlinux 0x6acb973d iowrite32be +EXPORT_SYMBOL vmlinux 0x6ad21909 udp_ioctl +EXPORT_SYMBOL vmlinux 0x6ad85887 acpi_enable_gpe +EXPORT_SYMBOL vmlinux 0x6add5c9a dmi_find_device +EXPORT_SYMBOL vmlinux 0x6af6c2e2 blk_unplug +EXPORT_SYMBOL vmlinux 0x6afe0652 input_set_capability +EXPORT_SYMBOL vmlinux 0x6b004a1b i2c_smbus_write_block_data +EXPORT_SYMBOL vmlinux 0x6b1b67d3 __bdevname +EXPORT_SYMBOL vmlinux 0x6b2d83c3 fb_get_mode +EXPORT_SYMBOL vmlinux 0x6b2dc060 dump_stack +EXPORT_SYMBOL vmlinux 0x6b35cf5e inet_frag_kill +EXPORT_SYMBOL vmlinux 0x6b76f1cd write_cache_pages +EXPORT_SYMBOL vmlinux 0x6b937ffb mca_mark_as_used +EXPORT_SYMBOL vmlinux 0x6b9b88f3 sleep_on +EXPORT_SYMBOL vmlinux 0x6bafbced mod_timer +EXPORT_SYMBOL vmlinux 0x6bc64745 qdisc_tree_decrease_qlen +EXPORT_SYMBOL vmlinux 0x6bdcfd99 qdisc_class_hash_remove +EXPORT_SYMBOL vmlinux 0x6be56669 blkdev_dequeue_request +EXPORT_SYMBOL vmlinux 0x6c1ce5ce strcspn +EXPORT_SYMBOL vmlinux 0x6c1ffe33 kmap_atomic +EXPORT_SYMBOL vmlinux 0x6c2e3320 strncmp +EXPORT_SYMBOL vmlinux 0x6c308358 load_nls +EXPORT_SYMBOL vmlinux 0x6c389761 acpi_bus_get_private_data +EXPORT_SYMBOL vmlinux 0x6c61ce70 num_registered_fb +EXPORT_SYMBOL vmlinux 0x6c702af7 sysctl_udp_rmem_min +EXPORT_SYMBOL vmlinux 0x6c896295 tcp_close +EXPORT_SYMBOL vmlinux 0x6c91264f neigh_parms_alloc +EXPORT_SYMBOL vmlinux 0x6cb07257 dcache_readdir +EXPORT_SYMBOL vmlinux 0x6cd193ce i2c_smbus_write_byte +EXPORT_SYMBOL vmlinux 0x6cd55b11 bio_integrity_enabled +EXPORT_SYMBOL vmlinux 0x6cd6ccbf tcp_proc_unregister +EXPORT_SYMBOL vmlinux 0x6cdc5c6b nla_strlcpy +EXPORT_SYMBOL vmlinux 0x6cee1e0e elv_rq_merge_ok +EXPORT_SYMBOL vmlinux 0x6cfeff51 dquot_release +EXPORT_SYMBOL vmlinux 0x6d0da34c param_get_short +EXPORT_SYMBOL vmlinux 0x6d10832b key_put +EXPORT_SYMBOL vmlinux 0x6d1ced27 vcc_sklist_lock +EXPORT_SYMBOL vmlinux 0x6d27ef64 __bitmap_empty +EXPORT_SYMBOL vmlinux 0x6d288375 radix_tree_next_hole +EXPORT_SYMBOL vmlinux 0x6d294e43 clock_t_to_jiffies +EXPORT_SYMBOL vmlinux 0x6d340f64 tty_termios_input_baud_rate +EXPORT_SYMBOL vmlinux 0x6d3834fc scsi_report_bus_reset +EXPORT_SYMBOL vmlinux 0x6d56c008 locks_remove_posix +EXPORT_SYMBOL vmlinux 0x6d6d3108 phy_detach +EXPORT_SYMBOL vmlinux 0x6d9ee3ee lock_super +EXPORT_SYMBOL vmlinux 0x6dc0c24b complete_and_exit +EXPORT_SYMBOL vmlinux 0x6dc3c672 acpi_bus_unregister_driver +EXPORT_SYMBOL vmlinux 0x6dc9481e bio_kmalloc +EXPORT_SYMBOL vmlinux 0x6dcfd380 boot_cpu_data +EXPORT_SYMBOL vmlinux 0x6ddc8699 register_sysctl_table +EXPORT_SYMBOL vmlinux 0x6de18f5a dm_table_get_size +EXPORT_SYMBOL vmlinux 0x6dee7be5 dump_fpu +EXPORT_SYMBOL vmlinux 0x6def2db2 half_md4_transform +EXPORT_SYMBOL vmlinux 0x6df575ad neigh_ifdown +EXPORT_SYMBOL vmlinux 0x6df7f89a sock_no_ioctl +EXPORT_SYMBOL vmlinux 0x6e07a54e acpi_get_gpe_status +EXPORT_SYMBOL vmlinux 0x6e1a4bbb udp_hash_lock +EXPORT_SYMBOL vmlinux 0x6e440b58 memcpy_fromiovecend +EXPORT_SYMBOL vmlinux 0x6e6ec639 tcp_v4_md5_lookup +EXPORT_SYMBOL vmlinux 0x6e720ff2 rtnl_unlock +EXPORT_SYMBOL vmlinux 0x6e9dd606 __symbol_put +EXPORT_SYMBOL vmlinux 0x6ead242b cond_resched_lock +EXPORT_SYMBOL vmlinux 0x6eecbb64 filemap_flush +EXPORT_SYMBOL vmlinux 0x6f0a6b8d jbd2_journal_init_dev +EXPORT_SYMBOL vmlinux 0x6f19ab56 pci_bus_size_bridges +EXPORT_SYMBOL vmlinux 0x6f29c359 __skb_checksum_complete +EXPORT_SYMBOL vmlinux 0x6f566740 pagevec_lookup +EXPORT_SYMBOL vmlinux 0x6f633b10 nf_log_unregister +EXPORT_SYMBOL vmlinux 0x6f87d242 xfrm_dst_ifdown +EXPORT_SYMBOL vmlinux 0x6f96d551 inet_bind +EXPORT_SYMBOL vmlinux 0x6fa7235d dev_add_pack +EXPORT_SYMBOL vmlinux 0x6fc32354 scsi_prep_return +EXPORT_SYMBOL vmlinux 0x6fcb87a1 touch_softlockup_watchdog +EXPORT_SYMBOL vmlinux 0x6ffce45a skb_put +EXPORT_SYMBOL vmlinux 0x7000c428 blk_queue_ordered +EXPORT_SYMBOL vmlinux 0x7008a9b7 timespec_to_jiffies +EXPORT_SYMBOL vmlinux 0x701d0ebd snprintf +EXPORT_SYMBOL vmlinux 0x70275e45 __wait_on_buffer +EXPORT_SYMBOL vmlinux 0x70461a22 key_revoke +EXPORT_SYMBOL vmlinux 0x70526628 ___pskb_trim +EXPORT_SYMBOL vmlinux 0x7054a3e4 request_dma +EXPORT_SYMBOL vmlinux 0x707081b3 thermal_zone_device_unregister +EXPORT_SYMBOL vmlinux 0x7094f8ae bt_err +EXPORT_SYMBOL vmlinux 0x70b21c36 phy_ethtool_sset +EXPORT_SYMBOL vmlinux 0x70b3a116 ip6_frag_match +EXPORT_SYMBOL vmlinux 0x70c00c8e compute_creds +EXPORT_SYMBOL vmlinux 0x70c7ea5f tc_classify +EXPORT_SYMBOL vmlinux 0x70d1f8f3 strncat +EXPORT_SYMBOL vmlinux 0x70d8ab82 acpi_acquire_global_lock +EXPORT_SYMBOL vmlinux 0x70e0d61f cpu_all_bits +EXPORT_SYMBOL vmlinux 0x70f334c3 kunmap +EXPORT_SYMBOL vmlinux 0x71002f3b dma_mark_declared_memory_occupied +EXPORT_SYMBOL vmlinux 0x710f48f7 xfrm_register_type +EXPORT_SYMBOL vmlinux 0x7129e5f8 hex_asc +EXPORT_SYMBOL vmlinux 0x712aa29b _spin_lock_irqsave +EXPORT_SYMBOL vmlinux 0x71356fba remove_wait_queue +EXPORT_SYMBOL vmlinux 0x715b222b deregister_atm_ioctl +EXPORT_SYMBOL vmlinux 0x7171121c overflowgid +EXPORT_SYMBOL vmlinux 0x71907357 keyring_search +EXPORT_SYMBOL vmlinux 0x71a50dbc register_blkdev +EXPORT_SYMBOL vmlinux 0x71b3d98b generic_permission +EXPORT_SYMBOL vmlinux 0x71b95dac tcp_create_openreq_child +EXPORT_SYMBOL vmlinux 0x71bb2d5b blk_execute_rq +EXPORT_SYMBOL vmlinux 0x71fc833e filemap_fault +EXPORT_SYMBOL vmlinux 0x720d6476 hci_conn_switch_role +EXPORT_SYMBOL vmlinux 0x72150358 mca_device_set_claim +EXPORT_SYMBOL vmlinux 0x72234e66 pci_scan_slot +EXPORT_SYMBOL vmlinux 0x72270e35 do_gettimeofday +EXPORT_SYMBOL vmlinux 0x7249b2f4 phy_driver_unregister +EXPORT_SYMBOL vmlinux 0x7258b612 hci_send_acl +EXPORT_SYMBOL vmlinux 0x725dc6df clocksource_register +EXPORT_SYMBOL vmlinux 0x728732ac tty_port_free_xmit_buf +EXPORT_SYMBOL vmlinux 0x728b0b39 pnp_release_card_device +EXPORT_SYMBOL vmlinux 0x72a69901 set_pages_uc +EXPORT_SYMBOL vmlinux 0x72b243d4 free_dma +EXPORT_SYMBOL vmlinux 0x72bf2140 mtrr_add +EXPORT_SYMBOL vmlinux 0x72d57346 xfrm_input_resume +EXPORT_SYMBOL vmlinux 0x72ea7b2d scsi_device_type +EXPORT_SYMBOL vmlinux 0x72fca66e skb_checksum +EXPORT_SYMBOL vmlinux 0x72fcd9ac tcp_hashinfo +EXPORT_SYMBOL vmlinux 0x731851b7 simple_dir_operations +EXPORT_SYMBOL vmlinux 0x733bbab1 inc_zone_page_state +EXPORT_SYMBOL vmlinux 0x733f8d79 i2c_smbus_write_byte_data +EXPORT_SYMBOL vmlinux 0x7349f951 try_to_release_page +EXPORT_SYMBOL vmlinux 0x735a0bd5 native_io_delay +EXPORT_SYMBOL vmlinux 0x7380e91e netdev_set_master +EXPORT_SYMBOL vmlinux 0x738803e6 strnlen +EXPORT_SYMBOL vmlinux 0x7389c9a8 acpi_bus_get_power +EXPORT_SYMBOL vmlinux 0x73a18a9f input_register_device +EXPORT_SYMBOL vmlinux 0x73cb7ae3 jbd2_journal_clear_err +EXPORT_SYMBOL vmlinux 0x73e20c1c strlcpy +EXPORT_SYMBOL vmlinux 0x73ead0de simple_sync_file +EXPORT_SYMBOL vmlinux 0x740a1b95 reserve_evntsel_nmi +EXPORT_SYMBOL vmlinux 0x740aa942 jbd2_journal_check_available_features +EXPORT_SYMBOL vmlinux 0x7413793a EISA_bus +EXPORT_SYMBOL vmlinux 0x7416cdb4 pci_map_rom +EXPORT_SYMBOL vmlinux 0x746a0df0 inet_sendmsg +EXPORT_SYMBOL vmlinux 0x746f9b2c input_release_device +EXPORT_SYMBOL vmlinux 0x747a67e9 netlink_dump_start +EXPORT_SYMBOL vmlinux 0x7485e15e unregister_chrdev_region +EXPORT_SYMBOL vmlinux 0x748caf40 down +EXPORT_SYMBOL vmlinux 0x74cc1cbe unregister_cpu_notifier +EXPORT_SYMBOL vmlinux 0x74cc238d current_kernel_time +EXPORT_SYMBOL vmlinux 0x74e230e8 pv_mmu_ops +EXPORT_SYMBOL vmlinux 0x750accac xfrm_unregister_km +EXPORT_SYMBOL vmlinux 0x75166031 hci_register_proto +EXPORT_SYMBOL vmlinux 0x7517f2a3 pci_setup_cardbus +EXPORT_SYMBOL vmlinux 0x75271716 save_processor_state +EXPORT_SYMBOL vmlinux 0x7536a49a acpi_bus_register_driver +EXPORT_SYMBOL vmlinux 0x753ef1e6 set_pages_x +EXPORT_SYMBOL vmlinux 0x755047fa inode_permission +EXPORT_SYMBOL vmlinux 0x75566739 complete_request_key +EXPORT_SYMBOL vmlinux 0x757d6ce2 simple_write_end +EXPORT_SYMBOL vmlinux 0x757ed943 inode_setattr +EXPORT_SYMBOL vmlinux 0x7586af96 module_put +EXPORT_SYMBOL vmlinux 0x75880ab1 clear_inode +EXPORT_SYMBOL vmlinux 0x758a15ba register_key_type +EXPORT_SYMBOL vmlinux 0x75bf7a6b set_trace_device +EXPORT_SYMBOL vmlinux 0x75f39668 qdisc_watchdog_cancel +EXPORT_SYMBOL vmlinux 0x7605d8cc scsi_host_alloc +EXPORT_SYMBOL vmlinux 0x760a0f4f yield +EXPORT_SYMBOL vmlinux 0x760b437a unregister_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x761f5fd9 scsi_is_sdev_device +EXPORT_SYMBOL vmlinux 0x762ef005 blk_rq_map_sg +EXPORT_SYMBOL vmlinux 0x764bd77c request_resource +EXPORT_SYMBOL vmlinux 0x7652293e nf_unregister_hooks +EXPORT_SYMBOL vmlinux 0x765af5b1 qdisc_watchdog_schedule +EXPORT_SYMBOL vmlinux 0x767ddb02 set_memory_wc +EXPORT_SYMBOL vmlinux 0x76a12e40 __pagevec_release +EXPORT_SYMBOL vmlinux 0x76bf656d __bitmap_shift_left +EXPORT_SYMBOL vmlinux 0x76c41869 journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0x76d3cd60 laptop_mode +EXPORT_SYMBOL vmlinux 0x76df9df4 blk_queue_segment_boundary +EXPORT_SYMBOL vmlinux 0x76f3f8a5 num_k8_northbridges +EXPORT_SYMBOL vmlinux 0x7705b849 d_path +EXPORT_SYMBOL vmlinux 0x7708f146 struct_module +EXPORT_SYMBOL vmlinux 0x770a0036 isapnp_cfg_begin +EXPORT_SYMBOL vmlinux 0x7726a683 hci_register_cb +EXPORT_SYMBOL vmlinux 0x774845de jbd2_journal_invalidatepage +EXPORT_SYMBOL vmlinux 0x7761d75b sock_common_setsockopt +EXPORT_SYMBOL vmlinux 0x7772220d rfkill_switch_all +EXPORT_SYMBOL vmlinux 0x777d5da7 kthread_bind +EXPORT_SYMBOL vmlinux 0x77887ac3 add_to_page_cache_locked +EXPORT_SYMBOL vmlinux 0x779f94e8 create_empty_buffers +EXPORT_SYMBOL vmlinux 0x77a108df _write_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x77a299af skb_insert +EXPORT_SYMBOL vmlinux 0x77de7191 bio_init +EXPORT_SYMBOL vmlinux 0x77e7975a inet_put_port +EXPORT_SYMBOL vmlinux 0x77eac9fc netdev_class_remove_file +EXPORT_SYMBOL vmlinux 0x77ecac9f zlib_inflateEnd +EXPORT_SYMBOL vmlinux 0x77eed19d __sk_mem_schedule +EXPORT_SYMBOL vmlinux 0x781620ac set_disk_ro +EXPORT_SYMBOL vmlinux 0x781e2017 mdiobus_unregister +EXPORT_SYMBOL vmlinux 0x781e56e1 mnt_unpin +EXPORT_SYMBOL vmlinux 0x784d7e97 register_snap_client +EXPORT_SYMBOL vmlinux 0x785756f2 bdi_destroy +EXPORT_SYMBOL vmlinux 0x786b7529 inet_csk_init_xmit_timers +EXPORT_SYMBOL vmlinux 0x78875ff7 uart_suspend_port +EXPORT_SYMBOL vmlinux 0x78897c77 vfs_writev +EXPORT_SYMBOL vmlinux 0x78a484c9 _read_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x78cb2783 down_write_trylock +EXPORT_SYMBOL vmlinux 0x78df6bd7 no_pci_devices +EXPORT_SYMBOL vmlinux 0x78eaae98 pci_pme_active +EXPORT_SYMBOL vmlinux 0x78eb9f32 inet_release +EXPORT_SYMBOL vmlinux 0x791d4f3a ip_xfrm_me_harder +EXPORT_SYMBOL vmlinux 0x794487ee disable_hlt +EXPORT_SYMBOL vmlinux 0x795b7e13 generic_removexattr +EXPORT_SYMBOL vmlinux 0x796fc5ce scsi_get_sense_info_fld +EXPORT_SYMBOL vmlinux 0x7979b316 pci_remove_behind_bridge +EXPORT_SYMBOL vmlinux 0x79844a7e posix_test_lock +EXPORT_SYMBOL vmlinux 0x79a31be0 __skb_recv_datagram +EXPORT_SYMBOL vmlinux 0x79aa04a2 get_random_bytes +EXPORT_SYMBOL vmlinux 0x79bb2b85 default_unplug_io_fn +EXPORT_SYMBOL vmlinux 0x79d40bcf put_tty_driver +EXPORT_SYMBOL vmlinux 0x7a1f6e15 acpi_unlock_battery_dir +EXPORT_SYMBOL vmlinux 0x7a215732 register_quota_format +EXPORT_SYMBOL vmlinux 0x7a220b10 ip_nat_decode_session +EXPORT_SYMBOL vmlinux 0x7a2a837d strict_strtol +EXPORT_SYMBOL vmlinux 0x7a34c8be file_remove_suid +EXPORT_SYMBOL vmlinux 0x7a82923d bd_claim +EXPORT_SYMBOL vmlinux 0x7a848702 _read_lock_irqsave +EXPORT_SYMBOL vmlinux 0x7a90c385 journal_force_commit +EXPORT_SYMBOL vmlinux 0x7aaf14f5 dev_mc_sync +EXPORT_SYMBOL vmlinux 0x7acc3659 phy_start_interrupts +EXPORT_SYMBOL vmlinux 0x7ae379ac pci_scan_single_device +EXPORT_SYMBOL vmlinux 0x7ae5f9b1 dev_unicast_unsync +EXPORT_SYMBOL vmlinux 0x7aec9089 clear_user +EXPORT_SYMBOL vmlinux 0x7b0c84c4 acpi_remove_table_handler +EXPORT_SYMBOL vmlinux 0x7b134ddf acpi_get_name +EXPORT_SYMBOL vmlinux 0x7b2d006e neigh_seq_start +EXPORT_SYMBOL vmlinux 0x7b2d9da6 skb_realloc_headroom +EXPORT_SYMBOL vmlinux 0x7b477e57 __napi_schedule +EXPORT_SYMBOL vmlinux 0x7b52a859 wrmsr_safe_on_cpu +EXPORT_SYMBOL vmlinux 0x7b5ed097 i2c_smbus_read_byte +EXPORT_SYMBOL vmlinux 0x7b69467e posix_acl_from_xattr +EXPORT_SYMBOL vmlinux 0x7b7573f8 vfs_create +EXPORT_SYMBOL vmlinux 0x7b8dce6c pci_target_state +EXPORT_SYMBOL vmlinux 0x7b9220a7 jbd2_journal_release_buffer +EXPORT_SYMBOL vmlinux 0x7b9cd0a9 page_address +EXPORT_SYMBOL vmlinux 0x7bc52287 devm_ioport_map +EXPORT_SYMBOL vmlinux 0x7bc5ca03 acpi_processor_unregister_performance +EXPORT_SYMBOL vmlinux 0x7bda1bbf inode_needs_sync +EXPORT_SYMBOL vmlinux 0x7bf129b3 tty_chars_in_buffer +EXPORT_SYMBOL vmlinux 0x7bf7088e mpage_writepage +EXPORT_SYMBOL vmlinux 0x7c31275a fifo_set_limit +EXPORT_SYMBOL vmlinux 0x7c387860 dentry_open +EXPORT_SYMBOL vmlinux 0x7c46233a cpufreq_quick_get +EXPORT_SYMBOL vmlinux 0x7c60d66e getname +EXPORT_SYMBOL vmlinux 0x7c61340c __release_region +EXPORT_SYMBOL vmlinux 0x7c635176 journal_errno +EXPORT_SYMBOL vmlinux 0x7c84456a scsi_remove_host +EXPORT_SYMBOL vmlinux 0x7c878af2 sock_create_lite +EXPORT_SYMBOL vmlinux 0x7c904ded unregister_module_notifier +EXPORT_SYMBOL vmlinux 0x7c948d65 pci_find_device +EXPORT_SYMBOL vmlinux 0x7ca13345 blk_queue_max_phys_segments +EXPORT_SYMBOL vmlinux 0x7cb1ae69 cpu_down +EXPORT_SYMBOL vmlinux 0x7cd50527 pci_get_slot +EXPORT_SYMBOL vmlinux 0x7cdeab5e generic_setlease +EXPORT_SYMBOL vmlinux 0x7d047e7e acpi_ut_exception +EXPORT_SYMBOL vmlinux 0x7d078e11 qdisc_calculate_pkt_len +EXPORT_SYMBOL vmlinux 0x7d11c268 jiffies +EXPORT_SYMBOL vmlinux 0x7d47fde0 netdev_state_change +EXPORT_SYMBOL vmlinux 0x7d6839e7 blk_queue_hardsect_size +EXPORT_SYMBOL vmlinux 0x7d69b957 rfkill_unregister +EXPORT_SYMBOL vmlinux 0x7d6f1e45 acpi_bus_start +EXPORT_SYMBOL vmlinux 0x7d79a978 request_key_with_auxdata +EXPORT_SYMBOL vmlinux 0x7d82b0f0 poll_initwait +EXPORT_SYMBOL vmlinux 0x7d850612 utf8_mbstowcs +EXPORT_SYMBOL vmlinux 0x7d937c4c d_alloc +EXPORT_SYMBOL vmlinux 0x7da9e65d eisa_driver_register +EXPORT_SYMBOL vmlinux 0x7dceceac capable +EXPORT_SYMBOL vmlinux 0x7dcf3ea2 read_cache_page_async +EXPORT_SYMBOL vmlinux 0x7dd4c1dc dev_unicast_delete +EXPORT_SYMBOL vmlinux 0x7df0a83c pci_enable_device +EXPORT_SYMBOL vmlinux 0x7e393bb0 simple_dir_inode_operations +EXPORT_SYMBOL vmlinux 0x7e9ebb05 kernel_thread +EXPORT_SYMBOL vmlinux 0x7ec785cb input_unregister_handle +EXPORT_SYMBOL vmlinux 0x7ed96f6b sk_receive_skb +EXPORT_SYMBOL vmlinux 0x7ee91c1d _spin_trylock +EXPORT_SYMBOL vmlinux 0x7f10b2e3 phy_attach +EXPORT_SYMBOL vmlinux 0x7f24de73 jiffies_to_usecs +EXPORT_SYMBOL vmlinux 0x7f4b4716 arp_broken_ops +EXPORT_SYMBOL vmlinux 0x7f640703 misc_deregister +EXPORT_SYMBOL vmlinux 0x7f76395b skb_dma_map +EXPORT_SYMBOL vmlinux 0x7f866939 km_query +EXPORT_SYMBOL vmlinux 0x7f8723bd pcie_mch_quirk +EXPORT_SYMBOL vmlinux 0x7f8d7f6d sk_stream_wait_connect +EXPORT_SYMBOL vmlinux 0x7fc5c36c mntput_no_expire +EXPORT_SYMBOL vmlinux 0x80265b34 bdget_disk +EXPORT_SYMBOL vmlinux 0x8047e2d3 skb_copy_bits +EXPORT_SYMBOL vmlinux 0x805dbbd2 dma_release_from_coherent +EXPORT_SYMBOL vmlinux 0x8063f83d radix_tree_gang_lookup +EXPORT_SYMBOL vmlinux 0x806e9abc xfrm6_rcv_spi +EXPORT_SYMBOL vmlinux 0x80c5e6e3 pci_bus_assign_resources +EXPORT_SYMBOL vmlinux 0x81472677 acpi_get_table +EXPORT_SYMBOL vmlinux 0x814e7730 nf_ct_destroy +EXPORT_SYMBOL vmlinux 0x815b5dd4 match_octal +EXPORT_SYMBOL vmlinux 0x815f2897 empty_zero_page +EXPORT_SYMBOL vmlinux 0x81799cee vscnprintf +EXPORT_SYMBOL vmlinux 0x817a185a atm_init_aal5 +EXPORT_SYMBOL vmlinux 0x8190962e cdrom_media_changed +EXPORT_SYMBOL vmlinux 0x81e3801a journal_start +EXPORT_SYMBOL vmlinux 0x81e6b37f dmi_get_system_info +EXPORT_SYMBOL vmlinux 0x81f859e2 get_user_pages +EXPORT_SYMBOL vmlinux 0x81fb9cb0 phy_register_fixup +EXPORT_SYMBOL vmlinux 0x82072614 tasklet_kill +EXPORT_SYMBOL vmlinux 0x820d225f print_mac +EXPORT_SYMBOL vmlinux 0x8235805b memmove +EXPORT_SYMBOL vmlinux 0x8246090b bdput +EXPORT_SYMBOL vmlinux 0x82462d30 hci_send_sco +EXPORT_SYMBOL vmlinux 0x8251bcc3 bitmap_release_region +EXPORT_SYMBOL vmlinux 0x825c2a03 mmc_wait_for_req +EXPORT_SYMBOL vmlinux 0x82673561 schedule_delayed_work +EXPORT_SYMBOL vmlinux 0x826a753d xfrm_state_insert +EXPORT_SYMBOL vmlinux 0x828f6b2b request_key_async +EXPORT_SYMBOL vmlinux 0x82aa70f1 kern_path +EXPORT_SYMBOL vmlinux 0x82ba5d10 blk_queue_merge_bvec +EXPORT_SYMBOL vmlinux 0x82bbd5fe blk_queue_make_request +EXPORT_SYMBOL vmlinux 0x82d86918 ether_setup +EXPORT_SYMBOL vmlinux 0x82f65633 dm_io_client_resize +EXPORT_SYMBOL vmlinux 0x830e547b ioremap_prot +EXPORT_SYMBOL vmlinux 0x8310e4d1 locks_init_lock +EXPORT_SYMBOL vmlinux 0x8317e20a completion_done +EXPORT_SYMBOL vmlinux 0x831b3327 mb_cache_create +EXPORT_SYMBOL vmlinux 0x8323e4c6 km_policy_expired +EXPORT_SYMBOL vmlinux 0x834858a7 ip_fragment +EXPORT_SYMBOL vmlinux 0x835b06bc cancel_dirty_page +EXPORT_SYMBOL vmlinux 0x83800bfa kref_init +EXPORT_SYMBOL vmlinux 0x8392b23c ipv6_getsockopt +EXPORT_SYMBOL vmlinux 0x83a476ce bitmap_scnlistprintf +EXPORT_SYMBOL vmlinux 0x83c8f239 check_disk_size_change +EXPORT_SYMBOL vmlinux 0x83d20ca9 skb_store_bits +EXPORT_SYMBOL vmlinux 0x83ed1f35 unregister_8022_client +EXPORT_SYMBOL vmlinux 0x84028ae8 skb_trim +EXPORT_SYMBOL vmlinux 0x840ebae4 qdisc_class_hash_grow +EXPORT_SYMBOL vmlinux 0x84265db3 pnp_device_attach +EXPORT_SYMBOL vmlinux 0x843dedaa vcc_insert_socket +EXPORT_SYMBOL vmlinux 0x84a024bc make_bad_inode +EXPORT_SYMBOL vmlinux 0x84ae234f ipv6_chk_prefix +EXPORT_SYMBOL vmlinux 0x84dd2390 cpufreq_get_policy +EXPORT_SYMBOL vmlinux 0x84dfc57d seq_bitmap +EXPORT_SYMBOL vmlinux 0x851d4f46 kill_litter_super +EXPORT_SYMBOL vmlinux 0x85312eb9 udp_lib_setsockopt +EXPORT_SYMBOL vmlinux 0x85414f17 journal_ack_err +EXPORT_SYMBOL vmlinux 0x855daa64 xfrm_policy_walk +EXPORT_SYMBOL vmlinux 0x85642e5e tty_insert_flip_string +EXPORT_SYMBOL vmlinux 0x85670f1d rtnl_is_locked +EXPORT_SYMBOL vmlinux 0x8568f737 simple_pin_fs +EXPORT_SYMBOL vmlinux 0x8578d714 cpu_sysdev_class +EXPORT_SYMBOL vmlinux 0x85852470 xfrm_policy_alloc +EXPORT_SYMBOL vmlinux 0x8593eb2c netdev_rx_csum_fault +EXPORT_SYMBOL vmlinux 0x85aeeb56 i2c_clients_command +EXPORT_SYMBOL vmlinux 0x85caddc6 input_inject_event +EXPORT_SYMBOL vmlinux 0x85df9b6c strsep +EXPORT_SYMBOL vmlinux 0x85e7deb2 iov_iter_fault_in_readable +EXPORT_SYMBOL vmlinux 0x85f2cdbd vm_insert_pfn +EXPORT_SYMBOL vmlinux 0x85fbf5f6 pci_set_mwi +EXPORT_SYMBOL vmlinux 0x8611a14b pci_restore_state +EXPORT_SYMBOL vmlinux 0x862059c4 sb_has_dirty_inodes +EXPORT_SYMBOL vmlinux 0x863c254a blk_queue_resize_tags +EXPORT_SYMBOL vmlinux 0x863cb91a utf8_wcstombs +EXPORT_SYMBOL vmlinux 0x865d0901 serio_close +EXPORT_SYMBOL vmlinux 0x8664f62e cpufreq_update_policy +EXPORT_SYMBOL vmlinux 0x8673c28c page_readlink +EXPORT_SYMBOL vmlinux 0x868acba5 get_options +EXPORT_SYMBOL vmlinux 0x86fb9b05 bitmap_parse_user +EXPORT_SYMBOL vmlinux 0x871c0a7e fiemap_check_flags +EXPORT_SYMBOL vmlinux 0x8733e9a3 sleep_on_timeout +EXPORT_SYMBOL vmlinux 0x8734fb4f fsync_bdev +EXPORT_SYMBOL vmlinux 0x874df003 pnp_device_detach +EXPORT_SYMBOL vmlinux 0x876dafc3 ec_write +EXPORT_SYMBOL vmlinux 0x8774ca1c I_BDEV +EXPORT_SYMBOL vmlinux 0x8785725d param_set_charp +EXPORT_SYMBOL vmlinux 0x878ab3ce sysctl_tcp_adv_win_scale +EXPORT_SYMBOL vmlinux 0x879ce75b kunmap_high +EXPORT_SYMBOL vmlinux 0x87a880bb tty_port_tty_get +EXPORT_SYMBOL vmlinux 0x87b407e7 iov_iter_copy_from_user +EXPORT_SYMBOL vmlinux 0x87cdda15 try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x87ee31d2 bd_release +EXPORT_SYMBOL vmlinux 0x881039d0 zlib_inflate +EXPORT_SYMBOL vmlinux 0x88275987 register_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0x885742ad mark_buffer_async_write +EXPORT_SYMBOL vmlinux 0x886045f4 close_bdev_exclusive +EXPORT_SYMBOL vmlinux 0x88e174b9 ps2_command +EXPORT_SYMBOL vmlinux 0x88e23bd5 skb_recv_datagram +EXPORT_SYMBOL vmlinux 0x88e86e33 mca_device_read_pos +EXPORT_SYMBOL vmlinux 0x88ef1825 phy_device_create +EXPORT_SYMBOL vmlinux 0x88ef8a7a pcim_iomap +EXPORT_SYMBOL vmlinux 0x88fdc52e follow_down +EXPORT_SYMBOL vmlinux 0x892b26a0 set_memory_nx +EXPORT_SYMBOL vmlinux 0x8932dafb proc_dointvec +EXPORT_SYMBOL vmlinux 0x89368404 mca_device_status +EXPORT_SYMBOL vmlinux 0x89419025 get_super +EXPORT_SYMBOL vmlinux 0x8949858b schedule_work +EXPORT_SYMBOL vmlinux 0x8953bb27 del_timer +EXPORT_SYMBOL vmlinux 0x8969b997 ida_get_new +EXPORT_SYMBOL vmlinux 0x8971b8fb netpoll_setup +EXPORT_SYMBOL vmlinux 0x897473df mktime +EXPORT_SYMBOL vmlinux 0x898b1fec mutex_trylock +EXPORT_SYMBOL vmlinux 0x898eda8b gnet_stats_copy_app +EXPORT_SYMBOL vmlinux 0x89937292 dmam_pool_destroy +EXPORT_SYMBOL vmlinux 0x89949018 down_timeout +EXPORT_SYMBOL vmlinux 0x899ce1b9 journal_create +EXPORT_SYMBOL vmlinux 0x89ad44f1 current_fs_time +EXPORT_SYMBOL vmlinux 0x89aed83b i2c_master_recv +EXPORT_SYMBOL vmlinux 0x89bea2bf mdiobus_register +EXPORT_SYMBOL vmlinux 0x89c49eb9 journal_start_commit +EXPORT_SYMBOL vmlinux 0x89d5538d fb_pad_aligned_buffer +EXPORT_SYMBOL vmlinux 0x89d66811 build_ehash_secret +EXPORT_SYMBOL vmlinux 0x8a09379d blk_init_tags +EXPORT_SYMBOL vmlinux 0x8a33a16c block_sync_page +EXPORT_SYMBOL vmlinux 0x8a394520 nf_register_hooks +EXPORT_SYMBOL vmlinux 0x8a3eabf0 __wait_on_bit +EXPORT_SYMBOL vmlinux 0x8a7d1c31 high_memory +EXPORT_SYMBOL vmlinux 0x8a99a016 mempool_free_slab +EXPORT_SYMBOL vmlinux 0x8a9bf6f9 generic_setxattr +EXPORT_SYMBOL vmlinux 0x8aaf8654 mutex_lock +EXPORT_SYMBOL vmlinux 0x8acc0ed8 jbd2_journal_flush +EXPORT_SYMBOL vmlinux 0x8ad42082 tcp_ioctl +EXPORT_SYMBOL vmlinux 0x8b18496f __copy_to_user_ll +EXPORT_SYMBOL vmlinux 0x8b298e52 __xfrm_decode_session +EXPORT_SYMBOL vmlinux 0x8b35e873 sg_last +EXPORT_SYMBOL vmlinux 0x8b4300d3 arp_find +EXPORT_SYMBOL vmlinux 0x8b50bd1c udp_memory_allocated +EXPORT_SYMBOL vmlinux 0x8b618d08 overflowuid +EXPORT_SYMBOL vmlinux 0x8b6934ca get_sb_single +EXPORT_SYMBOL vmlinux 0x8b923945 tcf_exts_validate +EXPORT_SYMBOL vmlinux 0x8b989cf9 acpi_bus_can_wakeup +EXPORT_SYMBOL vmlinux 0x8bd062f7 seq_open_private +EXPORT_SYMBOL vmlinux 0x8bfb8942 pci_bus_write_config_word +EXPORT_SYMBOL vmlinux 0x8c183cbe iowrite16 +EXPORT_SYMBOL vmlinux 0x8c36b31a skb_clone +EXPORT_SYMBOL vmlinux 0x8c37fbe7 inet_dev_addr_type +EXPORT_SYMBOL vmlinux 0x8c43d338 pci_do_scan_bus +EXPORT_SYMBOL vmlinux 0x8c453a3b kernel_sendmsg +EXPORT_SYMBOL vmlinux 0x8c4e0bad jbd2_log_wait_commit +EXPORT_SYMBOL vmlinux 0x8c8b4aad __scsi_add_device +EXPORT_SYMBOL vmlinux 0x8cb4b127 bio_integrity_add_page +EXPORT_SYMBOL vmlinux 0x8cba5411 jbd2_journal_force_commit +EXPORT_SYMBOL vmlinux 0x8cc79cab iowrite16_rep +EXPORT_SYMBOL vmlinux 0x8d06e368 dev_get_by_name +EXPORT_SYMBOL vmlinux 0x8d0a14ce key_type_keyring +EXPORT_SYMBOL vmlinux 0x8d2a9570 tty_register_driver +EXPORT_SYMBOL vmlinux 0x8d37f690 mca_device_read_stored_pos +EXPORT_SYMBOL vmlinux 0x8d3894f2 _ctype +EXPORT_SYMBOL vmlinux 0x8d4c9b61 mca_register_driver +EXPORT_SYMBOL vmlinux 0x8d551bef sysctl_tcp_rmem +EXPORT_SYMBOL vmlinux 0x8d5d4f05 skb_over_panic +EXPORT_SYMBOL vmlinux 0x8d6f81b4 __div64_32 +EXPORT_SYMBOL vmlinux 0x8d8d96c6 acpi_get_sleep_type_data +EXPORT_SYMBOL vmlinux 0x8db51870 skb_append +EXPORT_SYMBOL vmlinux 0x8dc6e564 restore_processor_state +EXPORT_SYMBOL vmlinux 0x8dca832f __percpu_counter_sum +EXPORT_SYMBOL vmlinux 0x8dcbcf7a uart_add_one_port +EXPORT_SYMBOL vmlinux 0x8dee6c54 netlink_kernel_release +EXPORT_SYMBOL vmlinux 0x8e002cda acpi_remove_gpe_block +EXPORT_SYMBOL vmlinux 0x8e0637ba i8253_lock +EXPORT_SYMBOL vmlinux 0x8e0b7743 ipv6_ext_hdr +EXPORT_SYMBOL vmlinux 0x8e10b4b0 pci_bus_alloc_resource +EXPORT_SYMBOL vmlinux 0x8e19a3c9 pci_select_bars +EXPORT_SYMBOL vmlinux 0x8e34fd78 blk_queue_max_sectors +EXPORT_SYMBOL vmlinux 0x8e58f952 __set_page_dirty_buffers +EXPORT_SYMBOL vmlinux 0x8e6c4022 proc_dointvec_userhz_jiffies +EXPORT_SYMBOL vmlinux 0x8e763ae1 send_remote_softirq +EXPORT_SYMBOL vmlinux 0x8e7d7adf dev_unicast_sync +EXPORT_SYMBOL vmlinux 0x8e95c4e7 genphy_config_aneg +EXPORT_SYMBOL vmlinux 0x8eb41415 notify_change +EXPORT_SYMBOL vmlinux 0x8ec13624 pci_scan_bridge +EXPORT_SYMBOL vmlinux 0x8ecb932d ipv4_specific +EXPORT_SYMBOL vmlinux 0x8ee63f0c proto_unregister +EXPORT_SYMBOL vmlinux 0x8f0133d4 set_blocksize +EXPORT_SYMBOL vmlinux 0x8f056386 pcim_iomap_regions +EXPORT_SYMBOL vmlinux 0x8f3ce266 genl_register_ops +EXPORT_SYMBOL vmlinux 0x8f42be5f uart_remove_one_port +EXPORT_SYMBOL vmlinux 0x8f5ffc4f netif_rx_ni +EXPORT_SYMBOL vmlinux 0x8f6b7950 set_irq_data +EXPORT_SYMBOL vmlinux 0x8f9c199c __get_user_2 +EXPORT_SYMBOL vmlinux 0x8fd07392 scsi_device_quiesce +EXPORT_SYMBOL vmlinux 0x8fd38de2 __set_page_dirty_nobuffers +EXPORT_SYMBOL vmlinux 0x8fd61e2a sk_stream_wait_memory +EXPORT_SYMBOL vmlinux 0x8ffdb3b8 crc16 +EXPORT_SYMBOL vmlinux 0x90035333 secure_tcpv6_sequence_number +EXPORT_SYMBOL vmlinux 0x9013d84a scsi_print_sense +EXPORT_SYMBOL vmlinux 0x905718b8 sk_alloc +EXPORT_SYMBOL vmlinux 0x90821d73 tcf_action_dump_1 +EXPORT_SYMBOL vmlinux 0x90a1601f dmi_check_system +EXPORT_SYMBOL vmlinux 0x90a4343e textsearch_destroy +EXPORT_SYMBOL vmlinux 0x90a943ba nmi_active +EXPORT_SYMBOL vmlinux 0x91089de2 cdev_alloc +EXPORT_SYMBOL vmlinux 0x910afb7a arp_create +EXPORT_SYMBOL vmlinux 0x91336795 kill_pgrp +EXPORT_SYMBOL vmlinux 0x9141bf1c d_validate +EXPORT_SYMBOL vmlinux 0x9144a8e2 ec_burst_disable +EXPORT_SYMBOL vmlinux 0x91481982 __ratelimit +EXPORT_SYMBOL vmlinux 0x91607d95 set_memory_wb +EXPORT_SYMBOL vmlinux 0x918f86a3 dquot_drop +EXPORT_SYMBOL vmlinux 0x9193a53e xfrm_state_add +EXPORT_SYMBOL vmlinux 0x91ca8959 acpi_get_register +EXPORT_SYMBOL vmlinux 0x91cd7c93 jbd2_journal_lock_updates +EXPORT_SYMBOL vmlinux 0x92000825 __breadahead +EXPORT_SYMBOL vmlinux 0x9228ffaa simple_transaction_get +EXPORT_SYMBOL vmlinux 0x922b9eaf pnp_disable_dev +EXPORT_SYMBOL vmlinux 0x922ff447 eisa_bus_type +EXPORT_SYMBOL vmlinux 0x9260e35f xfrm_stateonly_find +EXPORT_SYMBOL vmlinux 0x92897e3d default_idle +EXPORT_SYMBOL vmlinux 0x92a90241 seq_bitmap_list +EXPORT_SYMBOL vmlinux 0x9305f8e6 cpufreq_get +EXPORT_SYMBOL vmlinux 0x930cb86e neigh_parms_release +EXPORT_SYMBOL vmlinux 0x9312ef2b dmam_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0x937a0e1a inet_shutdown +EXPORT_SYMBOL vmlinux 0x9387e5ac hci_register_dev +EXPORT_SYMBOL vmlinux 0x939dd4a0 update_region +EXPORT_SYMBOL vmlinux 0x93a6e0b2 io_schedule +EXPORT_SYMBOL vmlinux 0x93b8ef56 mutex_lock_interruptible +EXPORT_SYMBOL vmlinux 0x93c69acf param_set_byte +EXPORT_SYMBOL vmlinux 0x93cbd1ec _spin_lock_bh +EXPORT_SYMBOL vmlinux 0x93fbd3ed proto_register +EXPORT_SYMBOL vmlinux 0x93fca811 __get_free_pages +EXPORT_SYMBOL vmlinux 0x93fd0c6a dev_getbyhwaddr +EXPORT_SYMBOL vmlinux 0x9420cd71 take_over_console +EXPORT_SYMBOL vmlinux 0x9434e0a3 sk_stream_kill_queues +EXPORT_SYMBOL vmlinux 0x94661b75 vmap +EXPORT_SYMBOL vmlinux 0x946fea85 tcp_enter_memory_pressure +EXPORT_SYMBOL vmlinux 0x948e9653 bio_integrity_split +EXPORT_SYMBOL vmlinux 0x94961283 vunmap +EXPORT_SYMBOL vmlinux 0x94c0ecd0 seq_open +EXPORT_SYMBOL vmlinux 0x94d86e98 ip4_datagram_connect +EXPORT_SYMBOL vmlinux 0x94f6714b cdrom_mode_sense +EXPORT_SYMBOL vmlinux 0x94fcf08e bioset_create +EXPORT_SYMBOL vmlinux 0x9518f21c xfrm_state_register_afinfo +EXPORT_SYMBOL vmlinux 0x95352ea9 acpi_check_mem_region +EXPORT_SYMBOL vmlinux 0x954488a4 syncookie_secret +EXPORT_SYMBOL vmlinux 0x9545af6d tasklet_init +EXPORT_SYMBOL vmlinux 0x954c8af3 dm_io_client_destroy +EXPORT_SYMBOL vmlinux 0x954cbb26 vsprintf +EXPORT_SYMBOL vmlinux 0x9566e6dc read_dev_sector +EXPORT_SYMBOL vmlinux 0x958a6521 bitmap_endwrite +EXPORT_SYMBOL vmlinux 0x95afe519 elv_add_request +EXPORT_SYMBOL vmlinux 0x95ba36b1 atm_alloc_charge +EXPORT_SYMBOL vmlinux 0x95c83000 unlock_page +EXPORT_SYMBOL vmlinux 0x95dc66e7 hci_conn_check_link_mode +EXPORT_SYMBOL vmlinux 0x95de274d bio_put +EXPORT_SYMBOL vmlinux 0x95eaba58 mca_unregister_driver +EXPORT_SYMBOL vmlinux 0x95ed9a8e fd_install +EXPORT_SYMBOL vmlinux 0x95f638d5 posix_acl_chmod_masq +EXPORT_SYMBOL vmlinux 0x9616e888 __serio_register_port +EXPORT_SYMBOL vmlinux 0x9624741f simple_rename +EXPORT_SYMBOL vmlinux 0x9634498a rfkill_allocate +EXPORT_SYMBOL vmlinux 0x96481cc7 per_cpu__x86_cpu_to_apicid +EXPORT_SYMBOL vmlinux 0x965b0be2 vfs_readdir +EXPORT_SYMBOL vmlinux 0x96898769 sysfs_format_mac +EXPORT_SYMBOL vmlinux 0x9697d894 dm_dirty_log_destroy +EXPORT_SYMBOL vmlinux 0x96cd2b04 scsi_sense_key_string +EXPORT_SYMBOL vmlinux 0x96e79570 iw_handler_get_spy +EXPORT_SYMBOL vmlinux 0x96ee004f xfrm_init_state +EXPORT_SYMBOL vmlinux 0x97198d9a pci_dev_get +EXPORT_SYMBOL vmlinux 0x972ebf4a tty_devnum +EXPORT_SYMBOL vmlinux 0x973873ab _spin_lock +EXPORT_SYMBOL vmlinux 0x9739f1d4 jbd2_journal_forget +EXPORT_SYMBOL vmlinux 0x9754ec10 radix_tree_preload +EXPORT_SYMBOL vmlinux 0x979b2ad8 __module_put_and_exit +EXPORT_SYMBOL vmlinux 0x97bc5578 no_llseek +EXPORT_SYMBOL vmlinux 0x97de0ddd acpi_install_gpe_block +EXPORT_SYMBOL vmlinux 0x9809bd54 d_splice_alias +EXPORT_SYMBOL vmlinux 0x981026f6 km_report +EXPORT_SYMBOL vmlinux 0x983e2097 inode_double_lock +EXPORT_SYMBOL vmlinux 0x985c91d8 skb_copy_and_csum_bits +EXPORT_SYMBOL vmlinux 0x985ddc75 rtnl_set_sk_err +EXPORT_SYMBOL vmlinux 0x986e6135 fb_pad_unaligned_buffer +EXPORT_SYMBOL vmlinux 0x9873caa8 fb_set_cmap +EXPORT_SYMBOL vmlinux 0x9878cb73 tcp_mtup_init +EXPORT_SYMBOL vmlinux 0x987e272c generic_file_buffered_write +EXPORT_SYMBOL vmlinux 0x98884059 pnp_register_driver +EXPORT_SYMBOL vmlinux 0x988ed85d set_memory_x +EXPORT_SYMBOL vmlinux 0x98e2c734 mb_cache_entry_alloc +EXPORT_SYMBOL vmlinux 0x99052a84 acpi_os_write_port +EXPORT_SYMBOL vmlinux 0x99381fa2 security_sb_set_mnt_opts +EXPORT_SYMBOL vmlinux 0x993db61a skb_append_datato_frags +EXPORT_SYMBOL vmlinux 0x994d6b11 eth_header_cache +EXPORT_SYMBOL vmlinux 0x99877352 hippi_type_trans +EXPORT_SYMBOL vmlinux 0x9994c0ca ps2_is_keyboard_id +EXPORT_SYMBOL vmlinux 0x999e8297 vfree +EXPORT_SYMBOL vmlinux 0x99aadb21 param_get_ulong +EXPORT_SYMBOL vmlinux 0x99bfbe39 get_unused_fd +EXPORT_SYMBOL vmlinux 0x99c3c0b0 vfs_fstat +EXPORT_SYMBOL vmlinux 0x99cdc86b sysctl_tcp_reordering +EXPORT_SYMBOL vmlinux 0x99d3c689 __xfrm_lookup +EXPORT_SYMBOL vmlinux 0x99dfac62 inet_proto_csum_replace4 +EXPORT_SYMBOL vmlinux 0x99ea12ce panic_blink +EXPORT_SYMBOL vmlinux 0x99fe140a stop_tty +EXPORT_SYMBOL vmlinux 0x9a032d1a skb_copy_expand +EXPORT_SYMBOL vmlinux 0x9a140901 filp_close +EXPORT_SYMBOL vmlinux 0x9a1dfd65 strpbrk +EXPORT_SYMBOL vmlinux 0x9a365f7f i2c_smbus_read_block_data +EXPORT_SYMBOL vmlinux 0x9a5581f6 ethtool_op_set_tx_csum +EXPORT_SYMBOL vmlinux 0x9a6a83f9 cmos_lock +EXPORT_SYMBOL vmlinux 0x9a6eb5ba per_cpu__cpu_core_map +EXPORT_SYMBOL vmlinux 0x9a9985be percpu_counter_destroy +EXPORT_SYMBOL vmlinux 0x9aa2f490 i2c_use_client +EXPORT_SYMBOL vmlinux 0x9aa73a4d journal_abort +EXPORT_SYMBOL vmlinux 0x9ac72c28 thermal_zone_device_register +EXPORT_SYMBOL vmlinux 0x9ad41d9c unregister_quota_format +EXPORT_SYMBOL vmlinux 0x9ad56239 n_tty_ioctl_helper +EXPORT_SYMBOL vmlinux 0x9af1a545 pcie_port_service_register +EXPORT_SYMBOL vmlinux 0x9b278a75 scsi_execute +EXPORT_SYMBOL vmlinux 0x9b2caa45 unlock_rename +EXPORT_SYMBOL vmlinux 0x9b38063a dm_get_mapinfo +EXPORT_SYMBOL vmlinux 0x9b388444 get_zeroed_page +EXPORT_SYMBOL vmlinux 0x9b486158 pci_bus_add_devices +EXPORT_SYMBOL vmlinux 0x9b4de8eb idr_replace +EXPORT_SYMBOL vmlinux 0x9b801caa scsi_device_set_state +EXPORT_SYMBOL vmlinux 0x9b936a19 neigh_connected_output +EXPORT_SYMBOL vmlinux 0x9b9c7faa xfrm_state_walk +EXPORT_SYMBOL vmlinux 0x9ba7089d argv_split +EXPORT_SYMBOL vmlinux 0x9bc3e2ce pci_bus_read_config_word +EXPORT_SYMBOL vmlinux 0x9bc6e7fe uart_update_timeout +EXPORT_SYMBOL vmlinux 0x9c012508 fb_parse_edid +EXPORT_SYMBOL vmlinux 0x9c2c944a __copy_from_user_ll_nocache_nozero +EXPORT_SYMBOL vmlinux 0x9c3d99ff pci_dev_put +EXPORT_SYMBOL vmlinux 0x9c491f60 sg_alloc_table +EXPORT_SYMBOL vmlinux 0x9c7077bd enable_hlt +EXPORT_SYMBOL vmlinux 0x9c92d053 jbd2_journal_set_features +EXPORT_SYMBOL vmlinux 0x9c96b588 scsi_host_set_state +EXPORT_SYMBOL vmlinux 0x9cb96e92 qdisc_put_rtab +EXPORT_SYMBOL vmlinux 0x9cb9985b skb_free_datagram +EXPORT_SYMBOL vmlinux 0x9cc4b030 simple_release_fs +EXPORT_SYMBOL vmlinux 0x9ccb2622 finish_wait +EXPORT_SYMBOL vmlinux 0x9ceb163c memcpy_toiovec +EXPORT_SYMBOL vmlinux 0x9ced38aa down_trylock +EXPORT_SYMBOL vmlinux 0x9cfd56c5 scsi_print_status +EXPORT_SYMBOL vmlinux 0x9d33ef5e acpi_enable +EXPORT_SYMBOL vmlinux 0x9d711f1f percpu_counter_init +EXPORT_SYMBOL vmlinux 0x9d985ef7 invalidate_inodes +EXPORT_SYMBOL vmlinux 0x9d9f0d41 rwsem_down_write_failed +EXPORT_SYMBOL vmlinux 0x9df83706 per_cpu__current_task +EXPORT_SYMBOL vmlinux 0x9e2c6c3f generic_file_aio_write_nolock +EXPORT_SYMBOL vmlinux 0x9e363b6b acpi_disable_gpe +EXPORT_SYMBOL vmlinux 0x9e3cc838 devm_ioport_unmap +EXPORT_SYMBOL vmlinux 0x9e48aef9 __dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0x9e4b3747 sg_copy_from_buffer +EXPORT_SYMBOL vmlinux 0x9e64fbfe rtc_cmos_read +EXPORT_SYMBOL vmlinux 0x9e7d6bd0 __udelay +EXPORT_SYMBOL vmlinux 0x9e887db3 tty_register_ldisc +EXPORT_SYMBOL vmlinux 0x9ea0ad49 __sg_free_table +EXPORT_SYMBOL vmlinux 0x9ea92dfa tcp_read_sock +EXPORT_SYMBOL vmlinux 0x9ebd4c04 adjust_resource +EXPORT_SYMBOL vmlinux 0x9ec5b1c5 acpi_bus_add +EXPORT_SYMBOL vmlinux 0x9ed685ee iov_iter_advance +EXPORT_SYMBOL vmlinux 0x9eecde16 do_brk +EXPORT_SYMBOL vmlinux 0x9eee6590 llc_mac_hdr_init +EXPORT_SYMBOL vmlinux 0x9ef42842 pnp_unregister_card_driver +EXPORT_SYMBOL vmlinux 0x9ef749e2 unregister_chrdev +EXPORT_SYMBOL vmlinux 0x9efc4923 phy_enable_interrupts +EXPORT_SYMBOL vmlinux 0x9f100139 jiffies_to_clock_t +EXPORT_SYMBOL vmlinux 0x9f16258b dma_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0x9f2bdaac __bitmap_or +EXPORT_SYMBOL vmlinux 0x9f36d231 pci_find_parent_resource +EXPORT_SYMBOL vmlinux 0x9f5db2d5 bio_pair_release +EXPORT_SYMBOL vmlinux 0x9f61c247 generic_shutdown_super +EXPORT_SYMBOL vmlinux 0x9f83c786 submit_bio +EXPORT_SYMBOL vmlinux 0x9f984513 strrchr +EXPORT_SYMBOL vmlinux 0x9fa274b4 dq_data_lock +EXPORT_SYMBOL vmlinux 0x9fb3dd30 memcpy_fromiovec +EXPORT_SYMBOL vmlinux 0x9fc32439 __rta_fill +EXPORT_SYMBOL vmlinux 0x9feaf287 sonet_subtract_stats +EXPORT_SYMBOL vmlinux 0x9ff889ba inet_ioctl +EXPORT_SYMBOL vmlinux 0x9ffc9904 xfrm_prepare_input +EXPORT_SYMBOL vmlinux 0xa02c4543 kmem_cache_shrink +EXPORT_SYMBOL vmlinux 0xa02d9885 dec_zone_page_state +EXPORT_SYMBOL vmlinux 0xa03523d5 security_unix_stream_connect +EXPORT_SYMBOL vmlinux 0xa03e8eee cap_netlink_recv +EXPORT_SYMBOL vmlinux 0xa0480007 block_write_begin +EXPORT_SYMBOL vmlinux 0xa04a01bd qdisc_class_hash_insert +EXPORT_SYMBOL vmlinux 0xa04e0309 netif_device_detach +EXPORT_SYMBOL vmlinux 0xa05c03df mempool_kmalloc +EXPORT_SYMBOL vmlinux 0xa0794b37 __inode_dir_notify +EXPORT_SYMBOL vmlinux 0xa0b04675 vmalloc_32 +EXPORT_SYMBOL vmlinux 0xa0bb843d scsi_is_target_device +EXPORT_SYMBOL vmlinux 0xa0ceef51 out_of_line_wait_on_bit +EXPORT_SYMBOL vmlinux 0xa0d5df5b clip_tbl_hook +EXPORT_SYMBOL vmlinux 0xa0dcfe42 blk_rq_map_user_iov +EXPORT_SYMBOL vmlinux 0xa0fbac79 wake_up_bit +EXPORT_SYMBOL vmlinux 0xa108eb4d sysctl_optmem_max +EXPORT_SYMBOL vmlinux 0xa10dcc13 getrawmonotonic +EXPORT_SYMBOL vmlinux 0xa120d33c tty_unregister_ldisc +EXPORT_SYMBOL vmlinux 0xa13798f8 printk_ratelimit +EXPORT_SYMBOL vmlinux 0xa19571fc proc_dointvec_ms_jiffies +EXPORT_SYMBOL vmlinux 0xa1ad089d __dev_get_by_index +EXPORT_SYMBOL vmlinux 0xa1b759ce fb_add_videomode +EXPORT_SYMBOL vmlinux 0xa1bbe163 dst_destroy +EXPORT_SYMBOL vmlinux 0xa1bd7dcf filemap_fdatawrite_range +EXPORT_SYMBOL vmlinux 0xa1c1a59d task_session_nr_ns +EXPORT_SYMBOL vmlinux 0xa1c76e0a _cond_resched +EXPORT_SYMBOL vmlinux 0xa1fcc4b9 in6_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0xa20ce1b8 net_msg_warn +EXPORT_SYMBOL vmlinux 0xa2881ac4 tcp_sendmsg +EXPORT_SYMBOL vmlinux 0xa2a1e5c9 _write_lock_bh +EXPORT_SYMBOL vmlinux 0xa2a5fd77 inet_ehash_secret +EXPORT_SYMBOL vmlinux 0xa2c8458f xfrm_state_update +EXPORT_SYMBOL vmlinux 0xa2f7b9a2 neigh_sysctl_register +EXPORT_SYMBOL vmlinux 0xa317caf8 tcf_exts_dump +EXPORT_SYMBOL vmlinux 0xa329f07e register_shrinker +EXPORT_SYMBOL vmlinux 0xa34f1ef5 crc32_le +EXPORT_SYMBOL vmlinux 0xa350a8f8 set_memory_array_uc +EXPORT_SYMBOL vmlinux 0xa35c1f05 acpi_extract_package +EXPORT_SYMBOL vmlinux 0xa35de80f ipv4_config +EXPORT_SYMBOL vmlinux 0xa372dafd dm_get_device +EXPORT_SYMBOL vmlinux 0xa3bbcd80 acpi_set_gpe_type +EXPORT_SYMBOL vmlinux 0xa3bc355e audit_log_end +EXPORT_SYMBOL vmlinux 0xa3f1edb1 blk_queue_free_tags +EXPORT_SYMBOL vmlinux 0xa3fba2a5 pskb_copy +EXPORT_SYMBOL vmlinux 0xa401ac43 input_register_handler +EXPORT_SYMBOL vmlinux 0xa4191051 skb_push +EXPORT_SYMBOL vmlinux 0xa422b36f kset_register +EXPORT_SYMBOL vmlinux 0xa4235338 sock_setsockopt +EXPORT_SYMBOL vmlinux 0xa44072fc posix_acl_alloc +EXPORT_SYMBOL vmlinux 0xa44ad274 wait_for_completion_interruptible_timeout +EXPORT_SYMBOL vmlinux 0xa47d35a4 nf_log_packet +EXPORT_SYMBOL vmlinux 0xa49869f3 blk_get_request +EXPORT_SYMBOL vmlinux 0xa498eb02 seq_escape +EXPORT_SYMBOL vmlinux 0xa4b94fea iowrite8_rep +EXPORT_SYMBOL vmlinux 0xa4cf151d __lock_page +EXPORT_SYMBOL vmlinux 0xa4df1151 kref_set +EXPORT_SYMBOL vmlinux 0xa50c0476 pci_enable_msix +EXPORT_SYMBOL vmlinux 0xa51cdfe8 __FIXADDR_TOP +EXPORT_SYMBOL vmlinux 0xa51e8e2c generic_file_mmap +EXPORT_SYMBOL vmlinux 0xa5373be6 kobject_del +EXPORT_SYMBOL vmlinux 0xa538b48a pnp_find_dev +EXPORT_SYMBOL vmlinux 0xa5423cc4 param_get_int +EXPORT_SYMBOL vmlinux 0xa55b9fc4 journal_check_available_features +EXPORT_SYMBOL vmlinux 0xa560688d genl_sock +EXPORT_SYMBOL vmlinux 0xa5693df7 posix_acl_clone +EXPORT_SYMBOL vmlinux 0xa56f1315 mempool_free +EXPORT_SYMBOL vmlinux 0xa5767d5f generic_delete_inode +EXPORT_SYMBOL vmlinux 0xa58b6804 nla_parse +EXPORT_SYMBOL vmlinux 0xa5922bb1 kfifo_init +EXPORT_SYMBOL vmlinux 0xa598e29c vesa_modes +EXPORT_SYMBOL vmlinux 0xa5caeb68 pnp_activate_dev +EXPORT_SYMBOL vmlinux 0xa5d043fa neigh_destroy +EXPORT_SYMBOL vmlinux 0xa5da0abd acpi_enter_sleep_state_s4bios +EXPORT_SYMBOL vmlinux 0xa6170b4a tcf_generic_walker +EXPORT_SYMBOL vmlinux 0xa6265113 neigh_seq_stop +EXPORT_SYMBOL vmlinux 0xa63d85ab slhc_remember +EXPORT_SYMBOL vmlinux 0xa6464355 sb_min_blocksize +EXPORT_SYMBOL vmlinux 0xa6484eae smp_call_function_mask +EXPORT_SYMBOL vmlinux 0xa68124fa hweight8 +EXPORT_SYMBOL vmlinux 0xa6814433 groups_free +EXPORT_SYMBOL vmlinux 0xa681fe88 generate_random_uuid +EXPORT_SYMBOL vmlinux 0xa6a20645 sockfd_lookup +EXPORT_SYMBOL vmlinux 0xa6a509ab init_net +EXPORT_SYMBOL vmlinux 0xa6b3f0d6 journal_init_dev +EXPORT_SYMBOL vmlinux 0xa6cba521 proc_dointvec_jiffies +EXPORT_SYMBOL vmlinux 0xa6cd810e kernel_getsockname +EXPORT_SYMBOL vmlinux 0xa6dcc773 rb_insert_color +EXPORT_SYMBOL vmlinux 0xa6f4e8af init_special_inode +EXPORT_SYMBOL vmlinux 0xa6f9c6e4 scsi_init_io +EXPORT_SYMBOL vmlinux 0xa7046549 vprintk +EXPORT_SYMBOL vmlinux 0xa709e221 netlink_ack +EXPORT_SYMBOL vmlinux 0xa70fa989 inet6_del_protocol +EXPORT_SYMBOL vmlinux 0xa70fabbe release_evntsel_nmi +EXPORT_SYMBOL vmlinux 0xa721968b ip6_frag_init +EXPORT_SYMBOL vmlinux 0xa72c0b1f vmalloc_to_page +EXPORT_SYMBOL vmlinux 0xa730e733 __dst_free +EXPORT_SYMBOL vmlinux 0xa7502f48 jiffies_to_timeval +EXPORT_SYMBOL vmlinux 0xa770b803 kblockd_flush_work +EXPORT_SYMBOL vmlinux 0xa786e4a5 unregister_console +EXPORT_SYMBOL vmlinux 0xa7c35c6b getnstimeofday +EXPORT_SYMBOL vmlinux 0xa7ce9a03 sock_no_getsockopt +EXPORT_SYMBOL vmlinux 0xa87c9074 journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0xa89acbb3 acpi_evaluate_reference +EXPORT_SYMBOL vmlinux 0xa8a6f639 __check_region +EXPORT_SYMBOL vmlinux 0xa8c89e1a hci_conn_encrypt +EXPORT_SYMBOL vmlinux 0xa8ec002f xfrm_policy_byid +EXPORT_SYMBOL vmlinux 0xa8fef7bb security_unix_may_send +EXPORT_SYMBOL vmlinux 0xa90f7390 dm_table_get_mode +EXPORT_SYMBOL vmlinux 0xa91b5561 acpi_video_backlight_support +EXPORT_SYMBOL vmlinux 0xa925899a param_set_bool +EXPORT_SYMBOL vmlinux 0xa93ad3b7 remap_pfn_range +EXPORT_SYMBOL vmlinux 0xa94d9c78 aio_put_req +EXPORT_SYMBOL vmlinux 0xa95b6f8e put_filp +EXPORT_SYMBOL vmlinux 0xa98ce7f1 nobh_writepage +EXPORT_SYMBOL vmlinux 0xa9918e54 vc_resize +EXPORT_SYMBOL vmlinux 0xa9a14377 unregister_key_type +EXPORT_SYMBOL vmlinux 0xa9b560ed con_set_default_unimap +EXPORT_SYMBOL vmlinux 0xa9e56605 set_irq_chip +EXPORT_SYMBOL vmlinux 0xa9fcf31d wait_for_completion_interruptible +EXPORT_SYMBOL vmlinux 0xaa024146 sonet_copy_stats +EXPORT_SYMBOL vmlinux 0xaa075915 sock_release +EXPORT_SYMBOL vmlinux 0xaa190d0e ip_mc_inc_group +EXPORT_SYMBOL vmlinux 0xaa463d9e generic_file_open +EXPORT_SYMBOL vmlinux 0xaa6220b0 dst_release +EXPORT_SYMBOL vmlinux 0xaa82af91 scsi_scan_target +EXPORT_SYMBOL vmlinux 0xaa836569 tcp_getsockopt +EXPORT_SYMBOL vmlinux 0xaa84a8ae acpi_processor_power_init_bm_check +EXPORT_SYMBOL vmlinux 0xaa8ab19e cpu_online_map +EXPORT_SYMBOL vmlinux 0xaa9462b8 acpi_bus_get_device +EXPORT_SYMBOL vmlinux 0xaab06af8 _write_lock_irqsave +EXPORT_SYMBOL vmlinux 0xaad4100d framebuffer_release +EXPORT_SYMBOL vmlinux 0xaad41263 input_grab_device +EXPORT_SYMBOL vmlinux 0xaae8ab0e acpi_bus_power_manageable +EXPORT_SYMBOL vmlinux 0xaaebe34f mca_write_pos +EXPORT_SYMBOL vmlinux 0xaaedf70f kill_pid +EXPORT_SYMBOL vmlinux 0xaafdc258 strcasecmp +EXPORT_SYMBOL vmlinux 0xaaffb9a5 acpi_bus_private_data_handler +EXPORT_SYMBOL vmlinux 0xab322f7b register_console +EXPORT_SYMBOL vmlinux 0xab471003 param_array_set +EXPORT_SYMBOL vmlinux 0xab4edd96 __pci_register_driver +EXPORT_SYMBOL vmlinux 0xab57c591 fb_is_primary_device +EXPORT_SYMBOL vmlinux 0xab600421 probe_irq_off +EXPORT_SYMBOL vmlinux 0xab65ed80 set_memory_uc +EXPORT_SYMBOL vmlinux 0xaba9ff34 allocate_resource +EXPORT_SYMBOL vmlinux 0xabd0c91c rtc_time_to_tm +EXPORT_SYMBOL vmlinux 0xac04ec52 destroy_EII_client +EXPORT_SYMBOL vmlinux 0xac3b3cee __bitmap_and +EXPORT_SYMBOL vmlinux 0xac4eeb7f nf_ip6_checksum +EXPORT_SYMBOL vmlinux 0xac58ea5e acpi_unload_table_id +EXPORT_SYMBOL vmlinux 0xacb4f0a4 mdiobus_free +EXPORT_SYMBOL vmlinux 0xacc6a67d sk_free +EXPORT_SYMBOL vmlinux 0xaccabc6a in4_pton +EXPORT_SYMBOL vmlinux 0xaccd18f4 neigh_for_each +EXPORT_SYMBOL vmlinux 0xaccf86b1 vfs_dq_transfer +EXPORT_SYMBOL vmlinux 0xacd1d253 dquot_commit +EXPORT_SYMBOL vmlinux 0xacd307b4 scsi_adjust_queue_depth +EXPORT_SYMBOL vmlinux 0xacec289a blk_get_backing_dev_info +EXPORT_SYMBOL vmlinux 0xacf10e3d tcp_v4_remember_stamp +EXPORT_SYMBOL vmlinux 0xacf4d843 match_strdup +EXPORT_SYMBOL vmlinux 0xacfa5ca0 file_update_time +EXPORT_SYMBOL vmlinux 0xad0413d4 match_hex +EXPORT_SYMBOL vmlinux 0xad13c689 acpi_os_execute +EXPORT_SYMBOL vmlinux 0xad93ff95 fasync_helper +EXPORT_SYMBOL vmlinux 0xad963763 vfs_dq_drop +EXPORT_SYMBOL vmlinux 0xadaa2657 cpufreq_register_notifier +EXPORT_SYMBOL vmlinux 0xadffb85b ilookup +EXPORT_SYMBOL vmlinux 0xae38e0f4 mb_cache_shrink +EXPORT_SYMBOL vmlinux 0xae4595c5 neigh_seq_next +EXPORT_SYMBOL vmlinux 0xae4a9292 journal_revoke +EXPORT_SYMBOL vmlinux 0xae640156 netlink_kernel_create +EXPORT_SYMBOL vmlinux 0xae750e91 remove_proc_entry +EXPORT_SYMBOL vmlinux 0xae75f004 ida_destroy +EXPORT_SYMBOL vmlinux 0xae93e25e iput +EXPORT_SYMBOL vmlinux 0xaeba0f2f i2c_smbus_write_word_data +EXPORT_SYMBOL vmlinux 0xaec655c7 alloc_pages_exact +EXPORT_SYMBOL vmlinux 0xaef98836 sock_no_sendmsg +EXPORT_SYMBOL vmlinux 0xaf2bd890 blk_put_request +EXPORT_SYMBOL vmlinux 0xaf35a278 nf_setsockopt +EXPORT_SYMBOL vmlinux 0xaf3dd7dc scsi_logging_level +EXPORT_SYMBOL vmlinux 0xaf4b1540 acpi_get_irq_routing_table +EXPORT_SYMBOL vmlinux 0xaf52c2d3 iommu_bio_merge +EXPORT_SYMBOL vmlinux 0xaf65d836 jbd2_journal_load +EXPORT_SYMBOL vmlinux 0xaf9e7b48 sock_no_connect +EXPORT_SYMBOL vmlinux 0xafc6a8c2 dquot_commit_info +EXPORT_SYMBOL vmlinux 0xafe01377 down_read +EXPORT_SYMBOL vmlinux 0xafe651ab linkwatch_fire_event +EXPORT_SYMBOL vmlinux 0xb067dbfc get_disk +EXPORT_SYMBOL vmlinux 0xb076aedd bt_sock_poll +EXPORT_SYMBOL vmlinux 0xb077ef32 acpi_enter_sleep_state +EXPORT_SYMBOL vmlinux 0xb07dfb3d acpi_remove_gpe_handler +EXPORT_SYMBOL vmlinux 0xb08f76ad gen_pool_free +EXPORT_SYMBOL vmlinux 0xb0b847ac __bitmap_full +EXPORT_SYMBOL vmlinux 0xb0e10781 get_option +EXPORT_SYMBOL vmlinux 0xb121390a probe_irq_on +EXPORT_SYMBOL vmlinux 0xb13c4dba down_write +EXPORT_SYMBOL vmlinux 0xb15b7152 dmam_alloc_noncoherent +EXPORT_SYMBOL vmlinux 0xb1645a2e sg_free_table +EXPORT_SYMBOL vmlinux 0xb19760c3 bitmap_onto +EXPORT_SYMBOL vmlinux 0xb1c3a01a oops_in_progress +EXPORT_SYMBOL vmlinux 0xb1c971d0 x86_dma_fallback_dev +EXPORT_SYMBOL vmlinux 0xb1cfad22 rdmsr_on_cpu +EXPORT_SYMBOL vmlinux 0xb1e2a817 nla_put_nohdr +EXPORT_SYMBOL vmlinux 0xb1f975aa unlock_kernel +EXPORT_SYMBOL vmlinux 0xb2017c1d per_cpu__x86_bios_cpu_apicid +EXPORT_SYMBOL vmlinux 0xb2130cd1 scsi_block_requests +EXPORT_SYMBOL vmlinux 0xb226949a inet_dgram_connect +EXPORT_SYMBOL vmlinux 0xb22fe6a3 netdev_increment_features +EXPORT_SYMBOL vmlinux 0xb23698ec neigh_table_clear +EXPORT_SYMBOL vmlinux 0xb23bb5fb nf_register_sockopt +EXPORT_SYMBOL vmlinux 0xb27409c2 __sk_dst_check +EXPORT_SYMBOL vmlinux 0xb279da12 pv_lock_ops +EXPORT_SYMBOL vmlinux 0xb288c60f pci_pme_capable +EXPORT_SYMBOL vmlinux 0xb2989398 dput +EXPORT_SYMBOL vmlinux 0xb29bc8bd idr_remove +EXPORT_SYMBOL vmlinux 0xb29fda21 pci_set_power_state +EXPORT_SYMBOL vmlinux 0xb2bd10a3 netpoll_print_options +EXPORT_SYMBOL vmlinux 0xb2efb6be mca_read_stored_pos +EXPORT_SYMBOL vmlinux 0xb2f4bb0f pcix_get_mmrbc +EXPORT_SYMBOL vmlinux 0xb2fd5ceb __put_user_4 +EXPORT_SYMBOL vmlinux 0xb30abf8d idr_get_new_above +EXPORT_SYMBOL vmlinux 0xb3205415 wait_for_completion_killable +EXPORT_SYMBOL vmlinux 0xb3284531 acpi_dbg_layer +EXPORT_SYMBOL vmlinux 0xb34d4c2e acpi_terminate +EXPORT_SYMBOL vmlinux 0xb352177e find_first_bit +EXPORT_SYMBOL vmlinux 0xb356082b scsi_rescan_device +EXPORT_SYMBOL vmlinux 0xb3692eb4 ioremap_wc +EXPORT_SYMBOL vmlinux 0xb36d267f vm_insert_page +EXPORT_SYMBOL vmlinux 0xb376d79d radix_tree_tagged +EXPORT_SYMBOL vmlinux 0xb378e340 sk_stop_timer +EXPORT_SYMBOL vmlinux 0xb3995b13 mark_info_dirty +EXPORT_SYMBOL vmlinux 0xb3a307c6 si_meminfo +EXPORT_SYMBOL vmlinux 0xb3e0590d acpi_set_current_resources +EXPORT_SYMBOL vmlinux 0xb3fa0b83 find_get_pages_contig +EXPORT_SYMBOL vmlinux 0xb4179476 __splice_from_pipe +EXPORT_SYMBOL vmlinux 0xb41e871a xfrm_state_alloc +EXPORT_SYMBOL vmlinux 0xb423dba1 console_blanked +EXPORT_SYMBOL vmlinux 0xb429410a posix_acl_from_mode +EXPORT_SYMBOL vmlinux 0xb44df7b9 pci_unmap_rom +EXPORT_SYMBOL vmlinux 0xb45578b8 memscan +EXPORT_SYMBOL vmlinux 0xb45b24f6 k8_nb_ids +EXPORT_SYMBOL vmlinux 0xb46c285a xfrm_policy_bysel_ctx +EXPORT_SYMBOL vmlinux 0xb475e8d5 init_task +EXPORT_SYMBOL vmlinux 0xb477238e sock_no_accept +EXPORT_SYMBOL vmlinux 0xb494e82a br_fdb_put_hook +EXPORT_SYMBOL vmlinux 0xb4a69ed9 pci_release_regions +EXPORT_SYMBOL vmlinux 0xb4abac65 inode_change_ok +EXPORT_SYMBOL vmlinux 0xb4ac6180 acpi_get_physical_device +EXPORT_SYMBOL vmlinux 0xb4ca9447 __kfifo_get +EXPORT_SYMBOL vmlinux 0xb4ce4ef8 serio_reconnect +EXPORT_SYMBOL vmlinux 0xb5044271 vsscanf +EXPORT_SYMBOL vmlinux 0xb5112623 bio_integrity_clone +EXPORT_SYMBOL vmlinux 0xb51dabcb inet_add_protocol +EXPORT_SYMBOL vmlinux 0xb54533f7 usecs_to_jiffies +EXPORT_SYMBOL vmlinux 0xb556d2dc simple_fill_super +EXPORT_SYMBOL vmlinux 0xb5a459dc unregister_blkdev +EXPORT_SYMBOL vmlinux 0xb5c1350f tcf_hash_create +EXPORT_SYMBOL vmlinux 0xb5ca1c46 slhc_free +EXPORT_SYMBOL vmlinux 0xb5d52c27 ec_transaction +EXPORT_SYMBOL vmlinux 0xb5dcbc61 dm_kcopyd_client_destroy +EXPORT_SYMBOL vmlinux 0xb5f28b5f __any_online_cpu +EXPORT_SYMBOL vmlinux 0xb606f4f6 ip_route_me_harder +EXPORT_SYMBOL vmlinux 0xb60e34a8 nla_memcpy +EXPORT_SYMBOL vmlinux 0xb6244511 sg_init_one +EXPORT_SYMBOL vmlinux 0xb62fafa5 __skb_warn_lro_forwarding +EXPORT_SYMBOL vmlinux 0xb63e4e74 xfrm_lookup +EXPORT_SYMBOL vmlinux 0xb650a5cf __secpath_destroy +EXPORT_SYMBOL vmlinux 0xb660d927 serio_interrupt +EXPORT_SYMBOL vmlinux 0xb678366f int_sqrt +EXPORT_SYMBOL vmlinux 0xb6896671 crc_t10dif +EXPORT_SYMBOL vmlinux 0xb6a61a86 qdisc_get_rtab +EXPORT_SYMBOL vmlinux 0xb6c5a973 scsi_show_result +EXPORT_SYMBOL vmlinux 0xb6c6eb70 console_start +EXPORT_SYMBOL vmlinux 0xb6cfd7e7 netif_carrier_off +EXPORT_SYMBOL vmlinux 0xb6e227aa rtc_lock +EXPORT_SYMBOL vmlinux 0xb6ed1e53 strncpy +EXPORT_SYMBOL vmlinux 0xb703911e release_firmware +EXPORT_SYMBOL vmlinux 0xb714a981 console_print +EXPORT_SYMBOL vmlinux 0xb72397d5 printk +EXPORT_SYMBOL vmlinux 0xb7350b31 seq_release +EXPORT_SYMBOL vmlinux 0xb7555f12 timeval_to_jiffies +EXPORT_SYMBOL vmlinux 0xb758b225 acpi_disable_event +EXPORT_SYMBOL vmlinux 0xb7660c45 blk_integrity_register +EXPORT_SYMBOL vmlinux 0xb7b2256c __neigh_event_send +EXPORT_SYMBOL vmlinux 0xb7b61546 crc32_be +EXPORT_SYMBOL vmlinux 0xb7d13f4d unload_nls +EXPORT_SYMBOL vmlinux 0xb7db0df2 hci_suspend_dev +EXPORT_SYMBOL vmlinux 0xb7dfd4ff __insert_inode_hash +EXPORT_SYMBOL vmlinux 0xb7f75d48 journal_lock_updates +EXPORT_SYMBOL vmlinux 0xb8025e99 pci_add_new_bus +EXPORT_SYMBOL vmlinux 0xb811ba0e __vmalloc +EXPORT_SYMBOL vmlinux 0xb828c786 per_cpu__cpu_sibling_map +EXPORT_SYMBOL vmlinux 0xb82e6f92 vfs_permission +EXPORT_SYMBOL vmlinux 0xb85b2bac vm_stat +EXPORT_SYMBOL vmlinux 0xb86e4ab9 random32 +EXPORT_SYMBOL vmlinux 0xb8769958 input_allocate_device +EXPORT_SYMBOL vmlinux 0xb894926d schedule_work_on +EXPORT_SYMBOL vmlinux 0xb89af9bf srandom32 +EXPORT_SYMBOL vmlinux 0xb8af7910 dquot_initialize +EXPORT_SYMBOL vmlinux 0xb8c290e6 generic_splice_sendpage +EXPORT_SYMBOL vmlinux 0xb8e7ce2c __put_user_8 +EXPORT_SYMBOL vmlinux 0xb905ad82 icmpv6_err_convert +EXPORT_SYMBOL vmlinux 0xb91b5c89 md_wait_for_blocked_rdev +EXPORT_SYMBOL vmlinux 0xb92febc4 blk_queue_start_tag +EXPORT_SYMBOL vmlinux 0xb93320a3 create_proc_entry +EXPORT_SYMBOL vmlinux 0xb93a4996 blk_rq_map_kern +EXPORT_SYMBOL vmlinux 0xb94027ce generic_ro_fops +EXPORT_SYMBOL vmlinux 0xb9859789 dma_ops +EXPORT_SYMBOL vmlinux 0xb9889104 simple_rmdir +EXPORT_SYMBOL vmlinux 0xb98a0185 rtc_tm_to_time +EXPORT_SYMBOL vmlinux 0xb9ad0419 xfrm_bundle_ok +EXPORT_SYMBOL vmlinux 0xb9c2cd3d rtnl_unicast +EXPORT_SYMBOL vmlinux 0xb9c74bf1 gen_kill_estimator +EXPORT_SYMBOL vmlinux 0xb9c83a6e udp_prot +EXPORT_SYMBOL vmlinux 0xb9fd2205 add_efi_memmap +EXPORT_SYMBOL vmlinux 0xba05b984 __xfrm_state_destroy +EXPORT_SYMBOL vmlinux 0xba095aa0 ilookup5 +EXPORT_SYMBOL vmlinux 0xba2d8594 ec_read +EXPORT_SYMBOL vmlinux 0xba40d60f da903x_query_status +EXPORT_SYMBOL vmlinux 0xba497f13 loops_per_jiffy +EXPORT_SYMBOL vmlinux 0xba4daf9f blkdev_put +EXPORT_SYMBOL vmlinux 0xba7cbb42 pci_set_master +EXPORT_SYMBOL vmlinux 0xba7cf13d km_state_notify +EXPORT_SYMBOL vmlinux 0xbae98afb lease_get_mtime +EXPORT_SYMBOL vmlinux 0xbaf10f77 __serio_register_driver +EXPORT_SYMBOL vmlinux 0xbb167766 fb_var_to_videomode +EXPORT_SYMBOL vmlinux 0xbb189cad disallow_signal +EXPORT_SYMBOL vmlinux 0xbb1cb7a5 sysctl_jiffies +EXPORT_SYMBOL vmlinux 0xbb20cbc9 blk_complete_request +EXPORT_SYMBOL vmlinux 0xbb30eb5a iw_handler_set_thrspy +EXPORT_SYMBOL vmlinux 0xbb50f8a4 fput +EXPORT_SYMBOL vmlinux 0xbb5d343d xfrm_get_acqseq +EXPORT_SYMBOL vmlinux 0xbb755c33 vfs_quota_off +EXPORT_SYMBOL vmlinux 0xbb7b97ef sb_set_blocksize +EXPORT_SYMBOL vmlinux 0xbb83bd29 xfrm_cfg_mutex +EXPORT_SYMBOL vmlinux 0xbb89de17 ida_init +EXPORT_SYMBOL vmlinux 0xbb96d60e save_mount_options +EXPORT_SYMBOL vmlinux 0xbbb40e56 serio_rescan +EXPORT_SYMBOL vmlinux 0xbbc8e804 param_set_ushort +EXPORT_SYMBOL vmlinux 0xbc2924d7 sock_no_bind +EXPORT_SYMBOL vmlinux 0xbc318a2e bitmap_cond_end_sync +EXPORT_SYMBOL vmlinux 0xbc35ff8a acpi_lock_ac_dir +EXPORT_SYMBOL vmlinux 0xbc6f1210 neigh_compat_output +EXPORT_SYMBOL vmlinux 0xbc76daa6 sk_common_release +EXPORT_SYMBOL vmlinux 0xbc88685d dma_supported +EXPORT_SYMBOL vmlinux 0xbc9fd4af pci_get_bus_and_slot +EXPORT_SYMBOL vmlinux 0xbcc308bb strnlen_user +EXPORT_SYMBOL vmlinux 0xbcd088a8 tcp_md5_hash_key +EXPORT_SYMBOL vmlinux 0xbcf662be mpage_readpages +EXPORT_SYMBOL vmlinux 0xbd15c327 vm_insert_mixed +EXPORT_SYMBOL vmlinux 0xbd200210 task_pid_nr_ns +EXPORT_SYMBOL vmlinux 0xbd379a3a inet_csk_delete_keepalive_timer +EXPORT_SYMBOL vmlinux 0xbd540601 pci_remove_bus_device +EXPORT_SYMBOL vmlinux 0xbd5634f4 sg_miter_next +EXPORT_SYMBOL vmlinux 0xbd8b0f86 backlight_device_unregister +EXPORT_SYMBOL vmlinux 0xbd8ec826 blk_dump_rq_flags +EXPORT_SYMBOL vmlinux 0xbde1a853 ip6_xmit +EXPORT_SYMBOL vmlinux 0xbe07ca58 block_write_end +EXPORT_SYMBOL vmlinux 0xbe0e5118 nla_memcmp +EXPORT_SYMBOL vmlinux 0xbe211547 balance_dirty_pages_ratelimited_nr +EXPORT_SYMBOL vmlinux 0xbe66c552 atm_charge +EXPORT_SYMBOL vmlinux 0xbeae4924 ip_getsockopt +EXPORT_SYMBOL vmlinux 0xbebcc142 dev_load +EXPORT_SYMBOL vmlinux 0xbecc2b00 bdget +EXPORT_SYMBOL vmlinux 0xbecc4556 lease_modify +EXPORT_SYMBOL vmlinux 0xbed98fb1 dm_kcopyd_client_create +EXPORT_SYMBOL vmlinux 0xbef43296 console_conditional_schedule +EXPORT_SYMBOL vmlinux 0xbf0c1a28 mmc_remove_host +EXPORT_SYMBOL vmlinux 0xbf109092 __find_get_block +EXPORT_SYMBOL vmlinux 0xbf13b163 rwsem_down_read_failed +EXPORT_SYMBOL vmlinux 0xbf42b224 dev_mc_delete +EXPORT_SYMBOL vmlinux 0xbf6cf2ee textsearch_find_continuous +EXPORT_SYMBOL vmlinux 0xbf6ecfb3 netlink_rcv_skb +EXPORT_SYMBOL vmlinux 0xbf7f161f kmem_cache_size +EXPORT_SYMBOL vmlinux 0xbf7fd2f5 schedule_timeout_killable +EXPORT_SYMBOL vmlinux 0xbf82003f scsi_get_command +EXPORT_SYMBOL vmlinux 0xbf89cc6b neigh_update +EXPORT_SYMBOL vmlinux 0xbf8b39e9 isapnp_present +EXPORT_SYMBOL vmlinux 0xbf9a3e37 bio_integrity_alloc +EXPORT_SYMBOL vmlinux 0xbf9bcc8d __cap_empty_set +EXPORT_SYMBOL vmlinux 0xbfc177bc iowrite32_rep +EXPORT_SYMBOL vmlinux 0xbfc4f0b4 block_read_full_page +EXPORT_SYMBOL vmlinux 0xbfee3ad5 loop_unregister_transfer +EXPORT_SYMBOL vmlinux 0xc003c637 __strncpy_from_user +EXPORT_SYMBOL vmlinux 0xc011c5ab xfrm_unregister_mode +EXPORT_SYMBOL vmlinux 0xc01eed33 __copy_from_user_ll_nozero +EXPORT_SYMBOL vmlinux 0xc02787ba ip_setsockopt +EXPORT_SYMBOL vmlinux 0xc02a05b8 pnp_is_active +EXPORT_SYMBOL vmlinux 0xc03137a8 set_user_nice +EXPORT_SYMBOL vmlinux 0xc045ad4e timespec_trunc +EXPORT_SYMBOL vmlinux 0xc054699d kmem_ptr_validate +EXPORT_SYMBOL vmlinux 0xc0580937 rb_erase +EXPORT_SYMBOL vmlinux 0xc05eb8fa tcf_em_tree_destroy +EXPORT_SYMBOL vmlinux 0xc0a3d105 find_next_bit +EXPORT_SYMBOL vmlinux 0xc0a80822 sget +EXPORT_SYMBOL vmlinux 0xc0af935c vfs_set_dqinfo +EXPORT_SYMBOL vmlinux 0xc0e56ff9 unregister_sysrq_key +EXPORT_SYMBOL vmlinux 0xc0f65988 machine_real_restart +EXPORT_SYMBOL vmlinux 0xc108a8fc journal_set_features +EXPORT_SYMBOL vmlinux 0xc11d8093 iov_shorten +EXPORT_SYMBOL vmlinux 0xc155b7fc alloc_disk +EXPORT_SYMBOL vmlinux 0xc175d2ec tcp_parse_options +EXPORT_SYMBOL vmlinux 0xc17a11ee blk_queue_update_dma_alignment +EXPORT_SYMBOL vmlinux 0xc17aad18 md_error +EXPORT_SYMBOL vmlinux 0xc1a19da7 dm_dirty_log_create +EXPORT_SYMBOL vmlinux 0xc1d00452 simple_write_begin +EXPORT_SYMBOL vmlinux 0xc1d9b5d7 phy_connect +EXPORT_SYMBOL vmlinux 0xc2066af0 batostr +EXPORT_SYMBOL vmlinux 0xc2344e88 task_tgid_nr_ns +EXPORT_SYMBOL vmlinux 0xc254af48 dcache_lock +EXPORT_SYMBOL vmlinux 0xc255a509 gnet_stats_copy_queue +EXPORT_SYMBOL vmlinux 0xc256e762 __bitmap_equal +EXPORT_SYMBOL vmlinux 0xc26df2c5 dm_register_target +EXPORT_SYMBOL vmlinux 0xc280a525 __copy_from_user_ll +EXPORT_SYMBOL vmlinux 0xc2d711e1 krealloc +EXPORT_SYMBOL vmlinux 0xc2e587d1 reset_devices +EXPORT_SYMBOL vmlinux 0xc2f79168 cdrom_get_media_event +EXPORT_SYMBOL vmlinux 0xc2f8a65d sock_no_socketpair +EXPORT_SYMBOL vmlinux 0xc2f8efc4 inet6_ioctl +EXPORT_SYMBOL vmlinux 0xc33d0fa7 sk_dst_check +EXPORT_SYMBOL vmlinux 0xc33f6f4c on_each_cpu +EXPORT_SYMBOL vmlinux 0xc34223e2 mmc_suspend_host +EXPORT_SYMBOL vmlinux 0xc3459741 dquot_alloc_space +EXPORT_SYMBOL vmlinux 0xc35df2ef hci_get_route +EXPORT_SYMBOL vmlinux 0xc37f49c4 end_page_writeback +EXPORT_SYMBOL vmlinux 0xc386bf75 d_delete +EXPORT_SYMBOL vmlinux 0xc3aaf0a9 __put_user_1 +EXPORT_SYMBOL vmlinux 0xc3ae683d dm_table_unplug_all +EXPORT_SYMBOL vmlinux 0xc3cf1128 in_group_p +EXPORT_SYMBOL vmlinux 0xc3cf5c55 skb_find_text +EXPORT_SYMBOL vmlinux 0xc3fa6a59 memchr +EXPORT_SYMBOL vmlinux 0xc402cc99 register_acpi_notifier +EXPORT_SYMBOL vmlinux 0xc41412b0 alloc_disk_node +EXPORT_SYMBOL vmlinux 0xc42376a4 tcp_setsockopt +EXPORT_SYMBOL vmlinux 0xc43215a0 pci_find_next_bus +EXPORT_SYMBOL vmlinux 0xc455098c acpi_bus_get_status +EXPORT_SYMBOL vmlinux 0xc4551660 __locks_copy_lock +EXPORT_SYMBOL vmlinux 0xc499ae1e kstrdup +EXPORT_SYMBOL vmlinux 0xc4a44cd0 scsi_ioctl +EXPORT_SYMBOL vmlinux 0xc4c751fb __nla_put +EXPORT_SYMBOL vmlinux 0xc4ee0f05 wait_on_sync_kiocb +EXPORT_SYMBOL vmlinux 0xc5056e00 inet_twsk_deschedule +EXPORT_SYMBOL vmlinux 0xc52f5714 fb_videomode_to_var +EXPORT_SYMBOL vmlinux 0xc5534d64 ioread16 +EXPORT_SYMBOL vmlinux 0xc55a7a8d d_add_ci +EXPORT_SYMBOL vmlinux 0xc55f7dc7 _write_trylock +EXPORT_SYMBOL vmlinux 0xc5844fb8 __per_cpu_offset +EXPORT_SYMBOL vmlinux 0xc594bd03 scsi_device_lookup +EXPORT_SYMBOL vmlinux 0xc5b8ec2c bio_integrity_advance +EXPORT_SYMBOL vmlinux 0xc6099a68 bio_copy_user +EXPORT_SYMBOL vmlinux 0xc6a40294 dm_dirty_log_type_register +EXPORT_SYMBOL vmlinux 0xc6bce394 dquot_acquire +EXPORT_SYMBOL vmlinux 0xc6c1d08e nf_afinfo +EXPORT_SYMBOL vmlinux 0xc6e0c3eb simple_empty +EXPORT_SYMBOL vmlinux 0xc6e5745a kernel_sock_ioctl +EXPORT_SYMBOL vmlinux 0xc7036771 call_usermodehelper_stdinpipe +EXPORT_SYMBOL vmlinux 0xc708eb68 inode_sub_bytes +EXPORT_SYMBOL vmlinux 0xc7194411 fb_pan_display +EXPORT_SYMBOL vmlinux 0xc71eaa30 __starget_for_each_device +EXPORT_SYMBOL vmlinux 0xc7208c3a serial8250_resume_port +EXPORT_SYMBOL vmlinux 0xc79bcd36 dm_vcalloc +EXPORT_SYMBOL vmlinux 0xc7a4fbed rtnl_lock +EXPORT_SYMBOL vmlinux 0xc7bd1792 inet_frag_find +EXPORT_SYMBOL vmlinux 0xc7ec6c27 strspn +EXPORT_SYMBOL vmlinux 0xc7f7fa04 elv_dispatch_add_tail +EXPORT_SYMBOL vmlinux 0xc7faaa4f tcp_proc_register +EXPORT_SYMBOL vmlinux 0xc80a3d95 path_permission +EXPORT_SYMBOL vmlinux 0xc83eb942 pci_find_bus +EXPORT_SYMBOL vmlinux 0xc866c61e seq_lseek +EXPORT_SYMBOL vmlinux 0xc876cf1c phy_start +EXPORT_SYMBOL vmlinux 0xc8770698 skb_copy_and_csum_dev +EXPORT_SYMBOL vmlinux 0xc886c26b ps2_init +EXPORT_SYMBOL vmlinux 0xc88a8256 ethtool_op_set_ufo +EXPORT_SYMBOL vmlinux 0xc897c382 sg_init_table +EXPORT_SYMBOL vmlinux 0xc8aaf7c3 mark_page_accessed +EXPORT_SYMBOL vmlinux 0xc8b57c27 autoremove_wake_function +EXPORT_SYMBOL vmlinux 0xc8ca3e25 acpi_get_child +EXPORT_SYMBOL vmlinux 0xc8cf212f generic_file_aio_read +EXPORT_SYMBOL vmlinux 0xc8d46868 bt_sock_wait_state +EXPORT_SYMBOL vmlinux 0xc8e3c248 __scm_destroy +EXPORT_SYMBOL vmlinux 0xc8fdb123 alloc_etherdev_mq +EXPORT_SYMBOL vmlinux 0xc90f050e rtnetlink_put_metrics +EXPORT_SYMBOL vmlinux 0xc92f4988 xfrm_alloc_spi +EXPORT_SYMBOL vmlinux 0xc947edb0 hci_resume_dev +EXPORT_SYMBOL vmlinux 0xc95eb680 posix_lock_file_wait +EXPORT_SYMBOL vmlinux 0xc969bba7 inode_get_bytes +EXPORT_SYMBOL vmlinux 0xc99598dd arp_tbl +EXPORT_SYMBOL vmlinux 0xc998d641 icmp_err_convert +EXPORT_SYMBOL vmlinux 0xc9ab2eef acpi_os_wait_events_complete +EXPORT_SYMBOL vmlinux 0xc9bd220c phy_disconnect +EXPORT_SYMBOL vmlinux 0xc9d39e4c phy_sanitize_settings +EXPORT_SYMBOL vmlinux 0xca0d362c vcc_release_async +EXPORT_SYMBOL vmlinux 0xca34282d netdev_boot_setup_check +EXPORT_SYMBOL vmlinux 0xca4e90ad block_write_full_page +EXPORT_SYMBOL vmlinux 0xca5dbc50 scsi_print_sense_hdr +EXPORT_SYMBOL vmlinux 0xca6c2d1e do_mmap_pgoff +EXPORT_SYMBOL vmlinux 0xca72aa2d skb_prepare_seq_read +EXPORT_SYMBOL vmlinux 0xca8acc78 acpi_dbg_level +EXPORT_SYMBOL vmlinux 0xca8c9e9d audit_log_format +EXPORT_SYMBOL vmlinux 0xcae8b9a8 iov_iter_copy_from_user_atomic +EXPORT_SYMBOL vmlinux 0xcaf5298f jbd2_journal_release_jbd_inode +EXPORT_SYMBOL vmlinux 0xcb123cf1 touch_atime +EXPORT_SYMBOL vmlinux 0xcb32da10 param_set_int +EXPORT_SYMBOL vmlinux 0xcb4e59d3 pci_set_consistent_dma_mask +EXPORT_SYMBOL vmlinux 0xcb648458 dcache_dir_lseek +EXPORT_SYMBOL vmlinux 0xcb6beb40 hweight32 +EXPORT_SYMBOL vmlinux 0xcb7131fb fb_get_options +EXPORT_SYMBOL vmlinux 0xcb733bf2 acpi_bus_set_power +EXPORT_SYMBOL vmlinux 0xcbbea244 jbd2_journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0xcbeabee6 sync_page_range +EXPORT_SYMBOL vmlinux 0xcc0235e2 blk_start_queue +EXPORT_SYMBOL vmlinux 0xcc1fb551 baswap +EXPORT_SYMBOL vmlinux 0xcc248d26 serial8250_suspend_port +EXPORT_SYMBOL vmlinux 0xcc326563 block_commit_write +EXPORT_SYMBOL vmlinux 0xcc36f32e fb_unregister_client +EXPORT_SYMBOL vmlinux 0xcc5005fe msleep_interruptible +EXPORT_SYMBOL vmlinux 0xcc51ee50 dma_spin_lock +EXPORT_SYMBOL vmlinux 0xcc6041d7 end_buffer_write_sync +EXPORT_SYMBOL vmlinux 0xcc69faa9 bio_split +EXPORT_SYMBOL vmlinux 0xcc7fa952 local_bh_enable_ip +EXPORT_SYMBOL vmlinux 0xcc849002 filemap_write_and_wait +EXPORT_SYMBOL vmlinux 0xcc8e2120 generic_file_readonly_mmap +EXPORT_SYMBOL vmlinux 0xccb720c2 poll_freewait +EXPORT_SYMBOL vmlinux 0xccceaf8e dev_driver_string +EXPORT_SYMBOL vmlinux 0xccd42f97 file_fsync +EXPORT_SYMBOL vmlinux 0xccf6e983 phy_stop_interrupts +EXPORT_SYMBOL vmlinux 0xccfe3efa user_revoke +EXPORT_SYMBOL vmlinux 0xcd156018 follow_up +EXPORT_SYMBOL vmlinux 0xcd21546e i2c_del_driver +EXPORT_SYMBOL vmlinux 0xcd8b3729 ht_create_irq +EXPORT_SYMBOL vmlinux 0xcdbc51d5 kernel_sock_shutdown +EXPORT_SYMBOL vmlinux 0xcdbdc5d4 pci_match_id +EXPORT_SYMBOL vmlinux 0xcdc1d401 pnp_get_resource +EXPORT_SYMBOL vmlinux 0xcdc48e32 blk_integrity_unregister +EXPORT_SYMBOL vmlinux 0xce19bac5 register_inet6addr_notifier +EXPORT_SYMBOL vmlinux 0xce36ba64 dev_unicast_add +EXPORT_SYMBOL vmlinux 0xce36ded6 sysctl_tcp_mem +EXPORT_SYMBOL vmlinux 0xce4904a4 acpi_leave_sleep_state +EXPORT_SYMBOL vmlinux 0xce5ac24f zlib_inflate_workspacesize +EXPORT_SYMBOL vmlinux 0xce807307 __inc_zone_page_state +EXPORT_SYMBOL vmlinux 0xce88aad1 register_netdev +EXPORT_SYMBOL vmlinux 0xce90b10d neigh_lookup_nodev +EXPORT_SYMBOL vmlinux 0xcebd41bb fb_firmware_edid +EXPORT_SYMBOL vmlinux 0xcefb2d8c path_lookup +EXPORT_SYMBOL vmlinux 0xcefcd99a serial8250_unregister_port +EXPORT_SYMBOL vmlinux 0xcf1015b6 prepare_binprm +EXPORT_SYMBOL vmlinux 0xcf1b16e2 __skb_checksum_complete_head +EXPORT_SYMBOL vmlinux 0xcf4acd3d sync_dirty_buffer +EXPORT_SYMBOL vmlinux 0xcf5ed63c ipv6_dev_get_saddr +EXPORT_SYMBOL vmlinux 0xcf5f02a3 tcp_v4_connect +EXPORT_SYMBOL vmlinux 0xcf942f05 dm_table_get_md +EXPORT_SYMBOL vmlinux 0xcfadd723 __percpu_counter_add +EXPORT_SYMBOL vmlinux 0xcfd3018e set_normalized_timespec +EXPORT_SYMBOL vmlinux 0xcff04c1a wake_up_process +EXPORT_SYMBOL vmlinux 0xd0181f4f __bitmap_xor +EXPORT_SYMBOL vmlinux 0xd0220dbb skb_abort_seq_read +EXPORT_SYMBOL vmlinux 0xd0283299 dump_trace +EXPORT_SYMBOL vmlinux 0xd02cc869 __bitmap_andnot +EXPORT_SYMBOL vmlinux 0xd034557d generic_write_end +EXPORT_SYMBOL vmlinux 0xd0454e44 log_wait_commit +EXPORT_SYMBOL vmlinux 0xd07007a6 blk_rq_init +EXPORT_SYMBOL vmlinux 0xd0731f69 cfb_imageblit +EXPORT_SYMBOL vmlinux 0xd08197fa acpi_load_tables +EXPORT_SYMBOL vmlinux 0xd08b3b15 scsi_remove_target +EXPORT_SYMBOL vmlinux 0xd093f02d blkdev_issue_discard +EXPORT_SYMBOL vmlinux 0xd0c6bece kill_block_super +EXPORT_SYMBOL vmlinux 0xd0d8621b strlen +EXPORT_SYMBOL vmlinux 0xd0ee38b8 schedule_timeout_uninterruptible +EXPORT_SYMBOL vmlinux 0xd11d5d48 fb_set_suspend +EXPORT_SYMBOL vmlinux 0xd1472061 acpi_pci_register_driver +EXPORT_SYMBOL vmlinux 0xd18b6eb2 acpi_unmap_lsapic +EXPORT_SYMBOL vmlinux 0xd19fccc8 ethtool_op_set_tso +EXPORT_SYMBOL vmlinux 0xd1b535ec kthread_stop +EXPORT_SYMBOL vmlinux 0xd1f10ce5 input_unregister_device +EXPORT_SYMBOL vmlinux 0xd1f6c5f3 smp_num_siblings +EXPORT_SYMBOL vmlinux 0xd1f91bcd dev_base_lock +EXPORT_SYMBOL vmlinux 0xd217b35c __page_symlink +EXPORT_SYMBOL vmlinux 0xd22c9356 dma_pool_create +EXPORT_SYMBOL vmlinux 0xd251d7b0 security_socket_getpeersec_dgram +EXPORT_SYMBOL vmlinux 0xd2555f19 jiffies_64_to_clock_t +EXPORT_SYMBOL vmlinux 0xd25d4f74 console_blank_hook +EXPORT_SYMBOL vmlinux 0xd267d42c down_killable +EXPORT_SYMBOL vmlinux 0xd28b85e7 unlock_new_inode +EXPORT_SYMBOL vmlinux 0xd2965f6f kthread_should_stop +EXPORT_SYMBOL vmlinux 0xd2973271 cdrom_mode_select +EXPORT_SYMBOL vmlinux 0xd2981b51 request_key_async_with_auxdata +EXPORT_SYMBOL vmlinux 0xd2ab69ad ethtool_op_get_flags +EXPORT_SYMBOL vmlinux 0xd2c689df iget5_locked +EXPORT_SYMBOL vmlinux 0xd2cb19e6 dev_close +EXPORT_SYMBOL vmlinux 0xd2f94add hci_conn_change_link_key +EXPORT_SYMBOL vmlinux 0xd30366ff call_usermodehelper_freeinfo +EXPORT_SYMBOL vmlinux 0xd34f0c62 gen_pool_create +EXPORT_SYMBOL vmlinux 0xd363bdea pnp_request_card_device +EXPORT_SYMBOL vmlinux 0xd36c3147 sysctl_intvec +EXPORT_SYMBOL vmlinux 0xd36ec14c pci_request_selected_regions +EXPORT_SYMBOL vmlinux 0xd3951da4 acpi_resource_to_address64 +EXPORT_SYMBOL vmlinux 0xd395f2e4 usb_serial_suspend +EXPORT_SYMBOL vmlinux 0xd3a3425f sock_no_setsockopt +EXPORT_SYMBOL vmlinux 0xd3afc596 sysctl_data +EXPORT_SYMBOL vmlinux 0xd3d9a6ac unregister_netdevice +EXPORT_SYMBOL vmlinux 0xd3e2258d phy_disable_interrupts +EXPORT_SYMBOL vmlinux 0xd3e367b2 unregister_snap_client +EXPORT_SYMBOL vmlinux 0xd3f74cf1 interruptible_sleep_on_timeout +EXPORT_SYMBOL vmlinux 0xd4139072 bdi_init +EXPORT_SYMBOL vmlinux 0xd42b7232 _write_unlock_bh +EXPORT_SYMBOL vmlinux 0xd430fb24 blk_free_tags +EXPORT_SYMBOL vmlinux 0xd474f8f3 __f_setown +EXPORT_SYMBOL vmlinux 0xd4987a2d sock_i_uid +EXPORT_SYMBOL vmlinux 0xd4a14de5 bitmap_end_sync +EXPORT_SYMBOL vmlinux 0xd4dd7b45 netpoll_cleanup +EXPORT_SYMBOL vmlinux 0xd4f9647b acpi_unlock_ac_dir +EXPORT_SYMBOL vmlinux 0xd508c25b jbd2_journal_init_jbd_inode +EXPORT_SYMBOL vmlinux 0xd51487b4 xfrm_unregister_type +EXPORT_SYMBOL vmlinux 0xd5263820 mb_cache_destroy +EXPORT_SYMBOL vmlinux 0xd52c567e alloc_buffer_head +EXPORT_SYMBOL vmlinux 0xd5376914 elv_abort_queue +EXPORT_SYMBOL vmlinux 0xd53aec49 cpu_possible_map +EXPORT_SYMBOL vmlinux 0xd55e2fbf fddi_type_trans +EXPORT_SYMBOL vmlinux 0xd567862c bio_sector_offset +EXPORT_SYMBOL vmlinux 0xd5688a7a radix_tree_insert +EXPORT_SYMBOL vmlinux 0xd59b0c4e netlink_unicast +EXPORT_SYMBOL vmlinux 0xd5adf4cb nf_hook_slow +EXPORT_SYMBOL vmlinux 0xd5b037e1 kref_put +EXPORT_SYMBOL vmlinux 0xd5b89e77 scsi_unblock_requests +EXPORT_SYMBOL vmlinux 0xd5ba4880 __neigh_for_each_release +EXPORT_SYMBOL vmlinux 0xd5df96f6 bt_sock_ioctl +EXPORT_SYMBOL vmlinux 0xd5eca001 flock_lock_file_wait +EXPORT_SYMBOL vmlinux 0xd6035d05 do_settimeofday +EXPORT_SYMBOL vmlinux 0xd62c833f schedule_timeout +EXPORT_SYMBOL vmlinux 0xd6363c06 journal_release_buffer +EXPORT_SYMBOL vmlinux 0xd638dad6 nobh_truncate_page +EXPORT_SYMBOL vmlinux 0xd679dcaf skb_queue_head +EXPORT_SYMBOL vmlinux 0xd6a78d08 smp_call_function_single +EXPORT_SYMBOL vmlinux 0xd6b33026 cpu_khz +EXPORT_SYMBOL vmlinux 0xd6b764f0 jbd2_journal_destroy +EXPORT_SYMBOL vmlinux 0xd6d9e7b7 pci_release_region +EXPORT_SYMBOL vmlinux 0xd6ee688f vmalloc +EXPORT_SYMBOL vmlinux 0xd6fb32bb i2c_master_send +EXPORT_SYMBOL vmlinux 0xd72a8486 i2c_detach_client +EXPORT_SYMBOL vmlinux 0xd730c59a register_netdevice +EXPORT_SYMBOL vmlinux 0xd747dede pagecache_write_end +EXPORT_SYMBOL vmlinux 0xd75e3b83 sock_rfree +EXPORT_SYMBOL vmlinux 0xd78d655a tcp_recvmsg +EXPORT_SYMBOL vmlinux 0xd79b5a02 allow_signal +EXPORT_SYMBOL vmlinux 0xd79f8c59 key_unlink +EXPORT_SYMBOL vmlinux 0xd7a6fafa panic_notifier_list +EXPORT_SYMBOL vmlinux 0xd7d36d1a idr_find +EXPORT_SYMBOL vmlinux 0xd7d9bf3e kmap_high +EXPORT_SYMBOL vmlinux 0xd7dd777b reserve_perfctr_nmi +EXPORT_SYMBOL vmlinux 0xd7eb7436 bio_uncopy_user +EXPORT_SYMBOL vmlinux 0xd7f821de sock_sendmsg +EXPORT_SYMBOL vmlinux 0xd7fe6d78 tty_schedule_flip +EXPORT_SYMBOL vmlinux 0xd827a4ea i2c_del_adapter +EXPORT_SYMBOL vmlinux 0xd8832dbf blk_stop_queue +EXPORT_SYMBOL vmlinux 0xd88f695a __mod_timer +EXPORT_SYMBOL vmlinux 0xd89da37f movable_zone +EXPORT_SYMBOL vmlinux 0xd8a2ab95 in_egroup_p +EXPORT_SYMBOL vmlinux 0xd8b337d0 xfrm_policy_insert +EXPORT_SYMBOL vmlinux 0xd8e484f0 register_chrdev_region +EXPORT_SYMBOL vmlinux 0xd9091363 acpi_install_notify_handler +EXPORT_SYMBOL vmlinux 0xd9455e4e vfs_symlink +EXPORT_SYMBOL vmlinux 0xd9539424 input_event +EXPORT_SYMBOL vmlinux 0xd958b17b sock_no_mmap +EXPORT_SYMBOL vmlinux 0xd95af39b scsi_eh_finish_cmd +EXPORT_SYMBOL vmlinux 0xd985dc99 mempool_free_pages +EXPORT_SYMBOL vmlinux 0xd996d859 idr_pre_get +EXPORT_SYMBOL vmlinux 0xd9c272aa mca_mark_as_unused +EXPORT_SYMBOL vmlinux 0xd9f0484b __invalidate_device +EXPORT_SYMBOL vmlinux 0xd9f5b5a6 pskb_expand_head +EXPORT_SYMBOL vmlinux 0xda08c0d7 pcibios_get_irq_routing_table +EXPORT_SYMBOL vmlinux 0xda0a6b0e acpi_map_lsapic +EXPORT_SYMBOL vmlinux 0xda1a7335 kasprintf +EXPORT_SYMBOL vmlinux 0xda398535 pagevec_lookup_tag +EXPORT_SYMBOL vmlinux 0xda77953f register_gifconf +EXPORT_SYMBOL vmlinux 0xda7ca6cb fb_mode_is_equal +EXPORT_SYMBOL vmlinux 0xda7ec047 bio_integrity_trim +EXPORT_SYMBOL vmlinux 0xda8af7ad fb_find_nearest_mode +EXPORT_SYMBOL vmlinux 0xda8fd495 isapnp_write_byte +EXPORT_SYMBOL vmlinux 0xda928914 nmi_watchdog +EXPORT_SYMBOL vmlinux 0xda9db7e7 simple_unlink +EXPORT_SYMBOL vmlinux 0xdaa57ec3 totalhigh_pages +EXPORT_SYMBOL vmlinux 0xdada670f md_check_recovery +EXPORT_SYMBOL vmlinux 0xdae7292d bio_integrity_set_tag +EXPORT_SYMBOL vmlinux 0xdae9c8a1 atm_dev_lookup +EXPORT_SYMBOL vmlinux 0xdaeec0fd sk_reset_timer +EXPORT_SYMBOL vmlinux 0xdb377be1 register_filesystem +EXPORT_SYMBOL vmlinux 0xdb4e259e xfrm_nl +EXPORT_SYMBOL vmlinux 0xdb4fad71 unregister_binfmt +EXPORT_SYMBOL vmlinux 0xdb55f76e scsi_host_put +EXPORT_SYMBOL vmlinux 0xdb5e4d7e iunique +EXPORT_SYMBOL vmlinux 0xdb62b2b9 skb_dequeue_tail +EXPORT_SYMBOL vmlinux 0xdb6ce750 copy_io_context +EXPORT_SYMBOL vmlinux 0xdb864d65 iov_iter_single_seg_count +EXPORT_SYMBOL vmlinux 0xdb8f8bf6 mca_device_claimed +EXPORT_SYMBOL vmlinux 0xdbcd416e sysctl_ip_nonlocal_bind +EXPORT_SYMBOL vmlinux 0xdc14eda7 pci_pci_problems +EXPORT_SYMBOL vmlinux 0xdc2adb35 add_taint +EXPORT_SYMBOL vmlinux 0xdc30d756 pnp_register_card_driver +EXPORT_SYMBOL vmlinux 0xdc43a9c8 daemonize +EXPORT_SYMBOL vmlinux 0xdc78bacb generic_file_aio_write +EXPORT_SYMBOL vmlinux 0xdc809ba4 i2c_smbus_read_word_data +EXPORT_SYMBOL vmlinux 0xdc873a70 screen_info +EXPORT_SYMBOL vmlinux 0xdc9e554c pci_scan_bus_parented +EXPORT_SYMBOL vmlinux 0xdcc7e145 scsi_register +EXPORT_SYMBOL vmlinux 0xdce0e523 i2c_smbus_process_call +EXPORT_SYMBOL vmlinux 0xdd0a2ba2 strlcat +EXPORT_SYMBOL vmlinux 0xdd4d5ae1 thaw_bdev +EXPORT_SYMBOL vmlinux 0xdd53132a ll_rw_block +EXPORT_SYMBOL vmlinux 0xdd5a18d4 wireless_spy_update +EXPORT_SYMBOL vmlinux 0xdd6bfccd radix_tree_tag_set +EXPORT_SYMBOL vmlinux 0xdd8ca626 scm_detach_fds +EXPORT_SYMBOL vmlinux 0xdd8df969 hci_unregister_proto +EXPORT_SYMBOL vmlinux 0xddb79333 uart_get_baud_rate +EXPORT_SYMBOL vmlinux 0xddba0639 elv_next_request +EXPORT_SYMBOL vmlinux 0xddbe0e08 unregister_md_personality +EXPORT_SYMBOL vmlinux 0xddc1ac11 bioset_integrity_free +EXPORT_SYMBOL vmlinux 0xdddaae2b pcim_iounmap +EXPORT_SYMBOL vmlinux 0xddeef053 vfs_stat +EXPORT_SYMBOL vmlinux 0xde23c3c6 __mpage_writepage +EXPORT_SYMBOL vmlinux 0xde2eb03d scsi_register_interface +EXPORT_SYMBOL vmlinux 0xde72325e tty_vhangup +EXPORT_SYMBOL vmlinux 0xde75b689 set_irq_type +EXPORT_SYMBOL vmlinux 0xde9360ba totalram_pages +EXPORT_SYMBOL vmlinux 0xdf0da3cc acpi_get_devices +EXPORT_SYMBOL vmlinux 0xdf44fe33 tcp_shutdown +EXPORT_SYMBOL vmlinux 0xdf60cc27 __print_symbol +EXPORT_SYMBOL vmlinux 0xdf62eb5d kernel_getpeername +EXPORT_SYMBOL vmlinux 0xdf6d7fcb pci_bus_write_config_byte +EXPORT_SYMBOL vmlinux 0xdf7e19cb lookup_one_len +EXPORT_SYMBOL vmlinux 0xdf8c695a __ndelay +EXPORT_SYMBOL vmlinux 0xdf929370 fs_overflowgid +EXPORT_SYMBOL vmlinux 0xdfa74c2d md_wakeup_thread +EXPORT_SYMBOL vmlinux 0xdfb7bada acpi_check_resource_conflict +EXPORT_SYMBOL vmlinux 0xdfc5169b slhc_init +EXPORT_SYMBOL vmlinux 0xdff80b1b find_task_by_pid_type_ns +EXPORT_SYMBOL vmlinux 0xe0091886 devm_ioremap_nocache +EXPORT_SYMBOL vmlinux 0xe0596263 generic_osync_inode +EXPORT_SYMBOL vmlinux 0xe06b4431 wait_for_key_construction +EXPORT_SYMBOL vmlinux 0xe0727bc2 xfrm4_rcv +EXPORT_SYMBOL vmlinux 0xe075d6eb iter_div_u64_rem +EXPORT_SYMBOL vmlinux 0xe0a501e3 idr_remove_all +EXPORT_SYMBOL vmlinux 0xe0ac8bd2 acpi_bus_generate_netlink_event +EXPORT_SYMBOL vmlinux 0xe0b13336 argv_free +EXPORT_SYMBOL vmlinux 0xe0bc1b20 do_munmap +EXPORT_SYMBOL vmlinux 0xe0c9c85f pci_choose_state +EXPORT_SYMBOL vmlinux 0xe0cae26c simple_transaction_read +EXPORT_SYMBOL vmlinux 0xe0d01d9f scsi_host_get +EXPORT_SYMBOL vmlinux 0xe0dca00e jbd2_journal_get_undo_access +EXPORT_SYMBOL vmlinux 0xe0f5994e tcf_em_tree_dump +EXPORT_SYMBOL vmlinux 0xe1023d91 ip_generic_getfrag +EXPORT_SYMBOL vmlinux 0xe1386059 tcp_timewait_state_process +EXPORT_SYMBOL vmlinux 0xe13cd8a7 dmi_name_in_vendors +EXPORT_SYMBOL vmlinux 0xe1419303 fb_class +EXPORT_SYMBOL vmlinux 0xe145c8fa jbd2_journal_unlock_updates +EXPORT_SYMBOL vmlinux 0xe15aeee2 downgrade_write +EXPORT_SYMBOL vmlinux 0xe16f8a79 per_cpu__irq_regs +EXPORT_SYMBOL vmlinux 0xe1761617 security_inet_conn_request +EXPORT_SYMBOL vmlinux 0xe184ea99 uart_resume_port +EXPORT_SYMBOL vmlinux 0xe18d51ce bio_alloc_bioset +EXPORT_SYMBOL vmlinux 0xe1a81c3a icmpv6msg_statistics +EXPORT_SYMBOL vmlinux 0xe1e831f8 __xfrm_state_delete +EXPORT_SYMBOL vmlinux 0xe1e9e593 pci_reenable_device +EXPORT_SYMBOL vmlinux 0xe1f7acd7 zero_fill_bio +EXPORT_SYMBOL vmlinux 0xe20aa0f5 sock_get_timestampns +EXPORT_SYMBOL vmlinux 0xe22ae837 tcf_hash_search +EXPORT_SYMBOL vmlinux 0xe2463850 eth_type_trans +EXPORT_SYMBOL vmlinux 0xe24b2509 sock_alloc_send_skb +EXPORT_SYMBOL vmlinux 0xe24d3a97 jiffies_64 +EXPORT_SYMBOL vmlinux 0xe24d6bca inet6_bind +EXPORT_SYMBOL vmlinux 0xe251e39f rtnl_create_link +EXPORT_SYMBOL vmlinux 0xe27243be end_request +EXPORT_SYMBOL vmlinux 0xe2d5255a strcmp +EXPORT_SYMBOL vmlinux 0xe2f048bb cdrom_ioctl +EXPORT_SYMBOL vmlinux 0xe2f0ea03 genphy_update_link +EXPORT_SYMBOL vmlinux 0xe2fae716 kmemdup +EXPORT_SYMBOL vmlinux 0xe312c2a4 pnp_find_card +EXPORT_SYMBOL vmlinux 0xe349bce4 dm_io +EXPORT_SYMBOL vmlinux 0xe351633f genl_register_family +EXPORT_SYMBOL vmlinux 0xe35bbecc neigh_lookup +EXPORT_SYMBOL vmlinux 0xe3a377d0 fb_show_logo +EXPORT_SYMBOL vmlinux 0xe3c83414 scsi_target_quiesce +EXPORT_SYMBOL vmlinux 0xe3c9b7be bt_sock_register +EXPORT_SYMBOL vmlinux 0xe3db2d55 scsi_block_when_processing_errors +EXPORT_SYMBOL vmlinux 0xe3fbe148 acpi_install_table_handler +EXPORT_SYMBOL vmlinux 0xe432a51c unregister_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0xe43617f7 acpi_gbl_FADT +EXPORT_SYMBOL vmlinux 0xe43d27ac arch_acpi_processor_init_pdc +EXPORT_SYMBOL vmlinux 0xe440f75e inet_csk_destroy_sock +EXPORT_SYMBOL vmlinux 0xe456bd3a complete +EXPORT_SYMBOL vmlinux 0xe45e5385 register_cdrom +EXPORT_SYMBOL vmlinux 0xe484e35f ioread32 +EXPORT_SYMBOL vmlinux 0xe4870354 _read_trylock +EXPORT_SYMBOL vmlinux 0xe48f3039 ida_get_new_above +EXPORT_SYMBOL vmlinux 0xe49627d2 fb_get_buffer_offset +EXPORT_SYMBOL vmlinux 0xe496539f jbd2_journal_abort +EXPORT_SYMBOL vmlinux 0xe4b24b8c __next_cpu +EXPORT_SYMBOL vmlinux 0xe4b471e2 get_phy_id +EXPORT_SYMBOL vmlinux 0xe4c1df3e _read_lock_bh +EXPORT_SYMBOL vmlinux 0xe4f7daf5 scsi_scan_host +EXPORT_SYMBOL vmlinux 0xe4fecbd1 open_bdev_exclusive +EXPORT_SYMBOL vmlinux 0xe503d65c scsi_add_host +EXPORT_SYMBOL vmlinux 0xe5122890 flow_cache_genid +EXPORT_SYMBOL vmlinux 0xe523ad75 synchronize_irq +EXPORT_SYMBOL vmlinux 0xe5512dce mca_device_transform_ioport +EXPORT_SYMBOL vmlinux 0xe552c401 serio_unregister_port +EXPORT_SYMBOL vmlinux 0xe57878a1 in6_pton +EXPORT_SYMBOL vmlinux 0xe5844107 cpu_present_map +EXPORT_SYMBOL vmlinux 0xe5867808 dlci_ioctl_set +EXPORT_SYMBOL vmlinux 0xe58d1032 tty_write_room +EXPORT_SYMBOL vmlinux 0xe597441f netif_carrier_on +EXPORT_SYMBOL vmlinux 0xe5991afe vfs_mkdir +EXPORT_SYMBOL vmlinux 0xe5c78a99 do_blank_screen +EXPORT_SYMBOL vmlinux 0xe5e1defb blk_queue_end_tag +EXPORT_SYMBOL vmlinux 0xe5ed5467 xfrm_policy_walk_init +EXPORT_SYMBOL vmlinux 0xe6033e25 tty_hung_up_p +EXPORT_SYMBOL vmlinux 0xe68cbe27 __scsi_device_lookup +EXPORT_SYMBOL vmlinux 0xe690b8fd __ipv6_isatap_ifid +EXPORT_SYMBOL vmlinux 0xe6b40ec1 hub_port_logical_disconnect +EXPORT_SYMBOL vmlinux 0xe6b48327 unlock_super +EXPORT_SYMBOL vmlinux 0xe6bc8fd5 invalidate_partition +EXPORT_SYMBOL vmlinux 0xe6d39289 inet6_getname +EXPORT_SYMBOL vmlinux 0xe6e7b9d5 blk_alloc_queue +EXPORT_SYMBOL vmlinux 0xe6ebc016 key_create_or_update +EXPORT_SYMBOL vmlinux 0xe6f45cd8 atm_dev_deregister +EXPORT_SYMBOL vmlinux 0xe6fbe430 can_do_mlock +EXPORT_SYMBOL vmlinux 0xe70fe1c1 write_one_page +EXPORT_SYMBOL vmlinux 0xe716baed acpi_unregister_ioapic +EXPORT_SYMBOL vmlinux 0xe71856e6 km_state_expired +EXPORT_SYMBOL vmlinux 0xe7250c64 tty_port_alloc_xmit_buf +EXPORT_SYMBOL vmlinux 0xe7262ebc posix_lock_file +EXPORT_SYMBOL vmlinux 0xe737af17 md_register_thread +EXPORT_SYMBOL vmlinux 0xe74ba194 generic_read_dir +EXPORT_SYMBOL vmlinux 0xe77dff08 registered_fb +EXPORT_SYMBOL vmlinux 0xe79f0d55 inode_set_bytes +EXPORT_SYMBOL vmlinux 0xe7a200c0 key_negate_and_link +EXPORT_SYMBOL vmlinux 0xe7d2aca1 security_sk_classify_flow +EXPORT_SYMBOL vmlinux 0xe7d4daac seq_list_next +EXPORT_SYMBOL vmlinux 0xe802ee79 block_invalidatepage +EXPORT_SYMBOL vmlinux 0xe8427ea5 kobject_add +EXPORT_SYMBOL vmlinux 0xe8794ce1 slhc_toss +EXPORT_SYMBOL vmlinux 0xe8987502 elv_rb_del +EXPORT_SYMBOL vmlinux 0xe8a3605f acpi_processor_set_thermal_limit +EXPORT_SYMBOL vmlinux 0xe8c372ee cdrom_open +EXPORT_SYMBOL vmlinux 0xe8ca5a9c inet_del_protocol +EXPORT_SYMBOL vmlinux 0xe8cd902e hweight16 +EXPORT_SYMBOL vmlinux 0xe8feb594 tcf_exts_dump_stats +EXPORT_SYMBOL vmlinux 0xe9053bd3 ipv6_skip_exthdr +EXPORT_SYMBOL vmlinux 0xe910b532 del_timer_sync +EXPORT_SYMBOL vmlinux 0xe914e41e strcpy +EXPORT_SYMBOL vmlinux 0xe9389b3f jbd2_journal_ack_err +EXPORT_SYMBOL vmlinux 0xe9456a5a sysctl_xfrm_aevent_rseqth +EXPORT_SYMBOL vmlinux 0xe98320c1 generic_make_request +EXPORT_SYMBOL vmlinux 0xe997667b wrmsr_on_cpu +EXPORT_SYMBOL vmlinux 0xe9b1df44 ppp_output_wakeup +EXPORT_SYMBOL vmlinux 0xe9ba4328 sock_kmalloc +EXPORT_SYMBOL vmlinux 0xe9ea3154 pci_disable_msix +EXPORT_SYMBOL vmlinux 0xe9ec0b40 inet_frag_destroy +EXPORT_SYMBOL vmlinux 0xea10212a int_to_scsilun +EXPORT_SYMBOL vmlinux 0xea10655a __bitmap_intersects +EXPORT_SYMBOL vmlinux 0xea153bab sysctl_ms_jiffies +EXPORT_SYMBOL vmlinux 0xea226f9d pneigh_lookup +EXPORT_SYMBOL vmlinux 0xea2d33a2 radix_tree_gang_lookup_slot +EXPORT_SYMBOL vmlinux 0xea404e7d pci_wake_from_d3 +EXPORT_SYMBOL vmlinux 0xea5f6001 pci_fixup_device +EXPORT_SYMBOL vmlinux 0xea6fcdaa genl_unregister_family +EXPORT_SYMBOL vmlinux 0xea7987f1 key_update +EXPORT_SYMBOL vmlinux 0xea858cb5 radix_tree_gang_lookup_tag +EXPORT_SYMBOL vmlinux 0xea89e239 dev_open +EXPORT_SYMBOL vmlinux 0xeaa8c5a3 set_binfmt +EXPORT_SYMBOL vmlinux 0xeab56589 neigh_create +EXPORT_SYMBOL vmlinux 0xeabe1049 pci_iomap +EXPORT_SYMBOL vmlinux 0xeacc1a70 copy_strings_kernel +EXPORT_SYMBOL vmlinux 0xeaded4ef console_stop +EXPORT_SYMBOL vmlinux 0xeadfe4e1 unregister_con_driver +EXPORT_SYMBOL vmlinux 0xeae3dfd6 __const_udelay +EXPORT_SYMBOL vmlinux 0xeb012f6a pv_cpu_ops +EXPORT_SYMBOL vmlinux 0xeb0ba016 scsi_execute_req +EXPORT_SYMBOL vmlinux 0xeb17adf1 skb_gso_segment +EXPORT_SYMBOL vmlinux 0xeb19baf7 proc_doulongvec_ms_jiffies_minmax +EXPORT_SYMBOL vmlinux 0xeb1fabf6 interruptible_sleep_on +EXPORT_SYMBOL vmlinux 0xeb20e724 give_up_console +EXPORT_SYMBOL vmlinux 0xeb395084 param_get_invbool +EXPORT_SYMBOL vmlinux 0xeb39546b journal_get_undo_access +EXPORT_SYMBOL vmlinux 0xeb7bffb6 skb_seq_read +EXPORT_SYMBOL vmlinux 0xeb8053bf serial8250_register_port +EXPORT_SYMBOL vmlinux 0xeb832a67 inet_select_addr +EXPORT_SYMBOL vmlinux 0xeb8f54b3 strstrip +EXPORT_SYMBOL vmlinux 0xeb9b8b28 vfs_link +EXPORT_SYMBOL vmlinux 0xebc02953 tcf_hash_check +EXPORT_SYMBOL vmlinux 0xebd273a6 strict_strtoull +EXPORT_SYMBOL vmlinux 0xebde3945 scsi_print_result +EXPORT_SYMBOL vmlinux 0xebffaac0 tcp_rcv_established +EXPORT_SYMBOL vmlinux 0xec14489b genl_unregister_ops +EXPORT_SYMBOL vmlinux 0xec467184 netdev_features_change +EXPORT_SYMBOL vmlinux 0xec794ba0 __send_remote_softirq +EXPORT_SYMBOL vmlinux 0xec860422 bioset_free +EXPORT_SYMBOL vmlinux 0xec957b56 __inet6_hash +EXPORT_SYMBOL vmlinux 0xec991f90 udplite_prot +EXPORT_SYMBOL vmlinux 0xecb1d683 vfs_unlink +EXPORT_SYMBOL vmlinux 0xecb590db tcf_unregister_action +EXPORT_SYMBOL vmlinux 0xecb5fec4 cont_write_begin +EXPORT_SYMBOL vmlinux 0xecb778b0 textsearch_unregister +EXPORT_SYMBOL vmlinux 0xecb836c0 generic_fillattr +EXPORT_SYMBOL vmlinux 0xecbeaba6 cdrom_number_of_slots +EXPORT_SYMBOL vmlinux 0xecc6c203 __break_lease +EXPORT_SYMBOL vmlinux 0xecde1418 _spin_lock_irq +EXPORT_SYMBOL vmlinux 0xeced9665 mod_zone_page_state +EXPORT_SYMBOL vmlinux 0xed37f961 hci_connect +EXPORT_SYMBOL vmlinux 0xed426ebc directly_mappable_cdev_bdi +EXPORT_SYMBOL vmlinux 0xed4c3a8d netpoll_send_udp +EXPORT_SYMBOL vmlinux 0xed633abc pv_irq_ops +EXPORT_SYMBOL vmlinux 0xed7be9b1 inet_frags_exit_net +EXPORT_SYMBOL vmlinux 0xed89f571 audit_log_start +EXPORT_SYMBOL vmlinux 0xedbaee5e nla_strcmp +EXPORT_SYMBOL vmlinux 0xedc03953 iounmap +EXPORT_SYMBOL vmlinux 0xedd14538 param_get_uint +EXPORT_SYMBOL vmlinux 0xee01f6f8 md_write_start +EXPORT_SYMBOL vmlinux 0xee039bb9 ip_defrag +EXPORT_SYMBOL vmlinux 0xee0bb965 do_SAK +EXPORT_SYMBOL vmlinux 0xee2d0fc7 _local_bh_enable +EXPORT_SYMBOL vmlinux 0xee37e814 d_move +EXPORT_SYMBOL vmlinux 0xee69e67e qdisc_watchdog_init +EXPORT_SYMBOL vmlinux 0xee7eb9e1 pnp_platform_devices +EXPORT_SYMBOL vmlinux 0xeea9dbaf bitmap_bitremap +EXPORT_SYMBOL vmlinux 0xeeb1717c param_array_get +EXPORT_SYMBOL vmlinux 0xeeb17207 kernel_connect +EXPORT_SYMBOL vmlinux 0xeeb2d5e4 lock_sock_nested +EXPORT_SYMBOL vmlinux 0xeef37776 vfs_dq_quota_on_remount +EXPORT_SYMBOL vmlinux 0xef1b3e49 kill_fasync +EXPORT_SYMBOL vmlinux 0xef3bd862 mca_find_unused_adapter +EXPORT_SYMBOL vmlinux 0xef5784c9 __free_pages +EXPORT_SYMBOL vmlinux 0xef6a96be register_chrdev +EXPORT_SYMBOL vmlinux 0xef9aedfc boot_option_idle_override +EXPORT_SYMBOL vmlinux 0xefd8bcfe pci_enable_device_mem +EXPORT_SYMBOL vmlinux 0xefdc8768 blk_cleanup_queue +EXPORT_SYMBOL vmlinux 0xefdd70ce security_secid_to_secctx +EXPORT_SYMBOL vmlinux 0xefe099c3 acpi_get_event_status +EXPORT_SYMBOL vmlinux 0xefe93fdd dev_alloc_skb +EXPORT_SYMBOL vmlinux 0xf0009fee put_pages_list +EXPORT_SYMBOL vmlinux 0xf008acec read_cache_pages +EXPORT_SYMBOL vmlinux 0xf00a1d4c request_firmware +EXPORT_SYMBOL vmlinux 0xf0148766 pci_set_dma_seg_boundary +EXPORT_SYMBOL vmlinux 0xf03921d4 sk_wait_data +EXPORT_SYMBOL vmlinux 0xf0392cf7 pci_get_subsys +EXPORT_SYMBOL vmlinux 0xf0465b0f ethtool_op_get_link +EXPORT_SYMBOL vmlinux 0xf0580822 ethtool_op_get_ufo +EXPORT_SYMBOL vmlinux 0xf065f629 ioread16be +EXPORT_SYMBOL vmlinux 0xf0b57c68 param_set_long +EXPORT_SYMBOL vmlinux 0xf0df5825 get_sb_bdev +EXPORT_SYMBOL vmlinux 0xf0f1246c kvasprintf +EXPORT_SYMBOL vmlinux 0xf10de535 ioread8 +EXPORT_SYMBOL vmlinux 0xf11543ff find_first_zero_bit +EXPORT_SYMBOL vmlinux 0xf11f6f9e ndisc_mc_map +EXPORT_SYMBOL vmlinux 0xf128b4bf set_page_dirty_lock +EXPORT_SYMBOL vmlinux 0xf12cf388 nobh_write_begin +EXPORT_SYMBOL vmlinux 0xf13f8ae6 tcp_make_synack +EXPORT_SYMBOL vmlinux 0xf15288a3 hci_recv_fragment +EXPORT_SYMBOL vmlinux 0xf15fbdb8 deactivate_super +EXPORT_SYMBOL vmlinux 0xf162fe2d sysctl_xfrm_aevent_etime +EXPORT_SYMBOL vmlinux 0xf174ed48 acquire_console_sem +EXPORT_SYMBOL vmlinux 0xf1752afe __request_region +EXPORT_SYMBOL vmlinux 0xf186fa0a starget_for_each_device +EXPORT_SYMBOL vmlinux 0xf18d101c __tcf_em_tree_match +EXPORT_SYMBOL vmlinux 0xf19294db bt_sock_unregister +EXPORT_SYMBOL vmlinux 0xf195c682 fb_invert_cmaps +EXPORT_SYMBOL vmlinux 0xf1ab1eb4 __fatal_signal_pending +EXPORT_SYMBOL vmlinux 0xf1bbf8aa ip_mc_dec_group +EXPORT_SYMBOL vmlinux 0xf1deabf2 div64_u64 +EXPORT_SYMBOL vmlinux 0xf1e98c74 avenrun +EXPORT_SYMBOL vmlinux 0xf20dabd8 free_irq +EXPORT_SYMBOL vmlinux 0xf211e9dc kmem_cache_create +EXPORT_SYMBOL vmlinux 0xf246de13 tcf_hash_destroy +EXPORT_SYMBOL vmlinux 0xf253ff38 journal_dirty_data +EXPORT_SYMBOL vmlinux 0xf25af888 inode_init_once +EXPORT_SYMBOL vmlinux 0xf279bd17 scsi_device_get +EXPORT_SYMBOL vmlinux 0xf2997713 tty_termios_hw_change +EXPORT_SYMBOL vmlinux 0xf2a6d2bf xfrm_policy_count +EXPORT_SYMBOL vmlinux 0xf2afa595 param_get_charp +EXPORT_SYMBOL vmlinux 0xf2b0da65 find_task_by_pid_ns +EXPORT_SYMBOL vmlinux 0xf2e74040 mca_set_adapter_name +EXPORT_SYMBOL vmlinux 0xf313da4e sha_transform +EXPORT_SYMBOL vmlinux 0xf32e69ff kblockd_schedule_work +EXPORT_SYMBOL vmlinux 0xf3341268 __clear_user +EXPORT_SYMBOL vmlinux 0xf338d4c3 netlink_unregister_notifier +EXPORT_SYMBOL vmlinux 0xf346231f seq_list_start_head +EXPORT_SYMBOL vmlinux 0xf367d8ac nla_reserve +EXPORT_SYMBOL vmlinux 0xf370831d kmem_cache_name +EXPORT_SYMBOL vmlinux 0xf3773093 proc_net_netfilter +EXPORT_SYMBOL vmlinux 0xf39bf4d9 put_cmsg +EXPORT_SYMBOL vmlinux 0xf3bf0bce __bitmap_complement +EXPORT_SYMBOL vmlinux 0xf3c7104f sk_send_sigurg +EXPORT_SYMBOL vmlinux 0xf3c8ec1c jbd2_journal_update_format +EXPORT_SYMBOL vmlinux 0xf3d5776c blk_integrity_compare +EXPORT_SYMBOL vmlinux 0xf441ac43 ioread8_rep +EXPORT_SYMBOL vmlinux 0xf454b193 neigh_changeaddr +EXPORT_SYMBOL vmlinux 0xf4578a5d mmc_add_host +EXPORT_SYMBOL vmlinux 0xf4579b66 nf_ip_checksum +EXPORT_SYMBOL vmlinux 0xf48a2c4c MCA_bus +EXPORT_SYMBOL vmlinux 0xf49bc67a atm_pcr_goal +EXPORT_SYMBOL vmlinux 0xf4a5c213 avail_to_resrv_perfctr_nmi_bit +EXPORT_SYMBOL vmlinux 0xf4ae9d51 ida_pre_get +EXPORT_SYMBOL vmlinux 0xf4cfab89 pcim_iomap_table +EXPORT_SYMBOL vmlinux 0xf4f14de6 rtnl_trylock +EXPORT_SYMBOL vmlinux 0xf4f52f93 dqstats +EXPORT_SYMBOL vmlinux 0xf4f6760c tcp_v4_md5_do_add +EXPORT_SYMBOL vmlinux 0xf5015b2c mb_cache_entry_find_first +EXPORT_SYMBOL vmlinux 0xf502d273 acpi_get_current_resources +EXPORT_SYMBOL vmlinux 0xf507c0eb scsi_track_queue_full +EXPORT_SYMBOL vmlinux 0xf51ae235 touch_nmi_watchdog +EXPORT_SYMBOL vmlinux 0xf51e3f10 dcache_dir_open +EXPORT_SYMBOL vmlinux 0xf53d4c26 qdisc_class_hash_destroy +EXPORT_SYMBOL vmlinux 0xf557593a ppp_unit_number +EXPORT_SYMBOL vmlinux 0xf5616adb __netif_schedule +EXPORT_SYMBOL vmlinux 0xf5995139 neigh_table_init +EXPORT_SYMBOL vmlinux 0xf5b2b74e sock_create +EXPORT_SYMBOL vmlinux 0xf5c05914 generic_segment_checks +EXPORT_SYMBOL vmlinux 0xf5ce9811 tcp_memory_allocated +EXPORT_SYMBOL vmlinux 0xf5d2600f key_instantiate_and_link +EXPORT_SYMBOL vmlinux 0xf5d7fc9b file_permission +EXPORT_SYMBOL vmlinux 0xf5f9af20 sock_queue_rcv_skb +EXPORT_SYMBOL vmlinux 0xf6272dbb eisa_driver_unregister +EXPORT_SYMBOL vmlinux 0xf62a6013 alloc_fcdev +EXPORT_SYMBOL vmlinux 0xf63faeed xfrm_find_acq_byseq +EXPORT_SYMBOL vmlinux 0xf6498fcb scsi_device_resume +EXPORT_SYMBOL vmlinux 0xf64a3e1f pci_prepare_to_sleep +EXPORT_SYMBOL vmlinux 0xf6517edf dmam_free_coherent +EXPORT_SYMBOL vmlinux 0xf65c8946 tcp_v4_send_check +EXPORT_SYMBOL vmlinux 0xf6792c16 genphy_config_advert +EXPORT_SYMBOL vmlinux 0xf6aa33b7 udp_proc_unregister +EXPORT_SYMBOL vmlinux 0xf6bb4729 color_table +EXPORT_SYMBOL vmlinux 0xf6bf2441 do_splice_to +EXPORT_SYMBOL vmlinux 0xf6bf3929 redraw_screen +EXPORT_SYMBOL vmlinux 0xf6c65efc pci_dev_driver +EXPORT_SYMBOL vmlinux 0xf6ebc03b net_ratelimit +EXPORT_SYMBOL vmlinux 0xf7006f9c user_path_at +EXPORT_SYMBOL vmlinux 0xf7158acf jbd2_journal_restart +EXPORT_SYMBOL vmlinux 0xf7431e23 tcp_tso_segment +EXPORT_SYMBOL vmlinux 0xf744ddf2 freeze_bdev +EXPORT_SYMBOL vmlinux 0xf74e1ef4 tcp_v4_destroy_sock +EXPORT_SYMBOL vmlinux 0xf74f6053 request_firmware_nowait +EXPORT_SYMBOL vmlinux 0xf75ad2d1 skb_add_rx_frag +EXPORT_SYMBOL vmlinux 0xf7623914 radix_tree_tag_clear +EXPORT_SYMBOL vmlinux 0xf786ef5e idr_init +EXPORT_SYMBOL vmlinux 0xf78d04ab netlink_register_notifier +EXPORT_SYMBOL vmlinux 0xf7a0ef7d vfs_rmdir +EXPORT_SYMBOL vmlinux 0xf7cedaf4 generic_readlink +EXPORT_SYMBOL vmlinux 0xf81111c4 nonseekable_open +EXPORT_SYMBOL vmlinux 0xf811e69d scsi_eh_flush_done_q +EXPORT_SYMBOL vmlinux 0xf81ff364 mark_buffer_dirty +EXPORT_SYMBOL vmlinux 0xf828118e flush_old_exec +EXPORT_SYMBOL vmlinux 0xf82abc1d isa_dma_bridge_buggy +EXPORT_SYMBOL vmlinux 0xf82e3d47 acpi_initialize_objects +EXPORT_SYMBOL vmlinux 0xf82f1109 utf8_wctomb +EXPORT_SYMBOL vmlinux 0xf83d53fc pci_bus_read_config_dword +EXPORT_SYMBOL vmlinux 0xf859e543 find_lock_page +EXPORT_SYMBOL vmlinux 0xf8814f73 rb_last +EXPORT_SYMBOL vmlinux 0xf88e0ee2 acpi_get_table_header +EXPORT_SYMBOL vmlinux 0xf890fe7f pm_idle +EXPORT_SYMBOL vmlinux 0xf894f272 scsi_cmd_print_sense_hdr +EXPORT_SYMBOL vmlinux 0xf8aa47ae mutex_lock_killable +EXPORT_SYMBOL vmlinux 0xf8acc78d sg_miter_start +EXPORT_SYMBOL vmlinux 0xf8b30e93 mempool_create +EXPORT_SYMBOL vmlinux 0xf8cf9ee5 abort_exclusive_wait +EXPORT_SYMBOL vmlinux 0xf8d114e6 serio_unregister_child_port +EXPORT_SYMBOL vmlinux 0xf8dc0526 __mark_inode_dirty +EXPORT_SYMBOL vmlinux 0xf923db68 pci_enable_msi +EXPORT_SYMBOL vmlinux 0xf92a62f7 free_task +EXPORT_SYMBOL vmlinux 0xf99e53ea ethtool_op_get_tso +EXPORT_SYMBOL vmlinux 0xf9a482f9 msleep +EXPORT_SYMBOL vmlinux 0xf9f83c53 jbd2_journal_extend +EXPORT_SYMBOL vmlinux 0xfa0564fc __wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0xfa25fad1 uart_match_port +EXPORT_SYMBOL vmlinux 0xfa323f40 pneigh_enqueue +EXPORT_SYMBOL vmlinux 0xfa5e75e7 uart_write_wakeup +EXPORT_SYMBOL vmlinux 0xfa6a6c3f mmc_free_host +EXPORT_SYMBOL vmlinux 0xfa751ead ip_ct_attach +EXPORT_SYMBOL vmlinux 0xfa7c596b blk_alloc_queue_node +EXPORT_SYMBOL vmlinux 0xfa87de56 path_get +EXPORT_SYMBOL vmlinux 0xfaa68969 single_open +EXPORT_SYMBOL vmlinux 0xfab77d0b bdi_register +EXPORT_SYMBOL vmlinux 0xfacf4c51 tty_shutdown +EXPORT_SYMBOL vmlinux 0xfad594ab pci_assign_resource +EXPORT_SYMBOL vmlinux 0xfaf98462 bitrev32 +EXPORT_SYMBOL vmlinux 0xfb038d63 cpu_mask_all +EXPORT_SYMBOL vmlinux 0xfb0443fb acpi_get_parent +EXPORT_SYMBOL vmlinux 0xfb0cf2e9 touch_all_softlockup_watchdogs +EXPORT_SYMBOL vmlinux 0xfb1f0ece kernel_accept +EXPORT_SYMBOL vmlinux 0xfb5a45bf call_usermodehelper_pipe +EXPORT_SYMBOL vmlinux 0xfb6af58d recalc_sigpending +EXPORT_SYMBOL vmlinux 0xfb9dca4a blk_register_region +EXPORT_SYMBOL vmlinux 0xfba0c2e0 llc_sap_list_lock +EXPORT_SYMBOL vmlinux 0xfba766bd pci_enable_device_io +EXPORT_SYMBOL vmlinux 0xfbb4d3c6 sk_stream_error +EXPORT_SYMBOL vmlinux 0xfbd41e68 blk_queue_stack_limits +EXPORT_SYMBOL vmlinux 0xfbd4ce0e pci_disable_msi +EXPORT_SYMBOL vmlinux 0xfbf92453 param_get_bool +EXPORT_SYMBOL vmlinux 0xfc02b7ad sysctl_tcp_wmem +EXPORT_SYMBOL vmlinux 0xfc1721d9 bdi_register_dev +EXPORT_SYMBOL vmlinux 0xfc2199f9 pci_bus_type +EXPORT_SYMBOL vmlinux 0xfc309c3e cancel_delayed_work_sync +EXPORT_SYMBOL vmlinux 0xfc31fe88 l2cap_load +EXPORT_SYMBOL vmlinux 0xfc39e32f ioport_unmap +EXPORT_SYMBOL vmlinux 0xfc3d71cc filemap_fdatawrite +EXPORT_SYMBOL vmlinux 0xfc42800d uart_get_divisor +EXPORT_SYMBOL vmlinux 0xfc61c121 kill_anon_super +EXPORT_SYMBOL vmlinux 0xfcaa04a0 out_of_line_wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0xfcda63a3 node_states +EXPORT_SYMBOL vmlinux 0xfcdd8cf6 param_get_ushort +EXPORT_SYMBOL vmlinux 0xfcdf551d elv_rb_find +EXPORT_SYMBOL vmlinux 0xfcec0987 enable_irq +EXPORT_SYMBOL vmlinux 0xfcfa03ff fb_videomode_to_modelist +EXPORT_SYMBOL vmlinux 0xfd03d5a4 journal_update_format +EXPORT_SYMBOL vmlinux 0xfd1c6a51 i2c_attach_client +EXPORT_SYMBOL vmlinux 0xfd1cb54d skb_copy_datagram_iovec +EXPORT_SYMBOL vmlinux 0xfd39ef56 tcf_exts_destroy +EXPORT_SYMBOL vmlinux 0xfd66d8bc blk_plug_device_unlocked +EXPORT_SYMBOL vmlinux 0xfd8c332c ps2_sendbyte +EXPORT_SYMBOL vmlinux 0xfd98879a rb_next +EXPORT_SYMBOL vmlinux 0xfdac7bf6 neigh_sysctl_unregister +EXPORT_SYMBOL vmlinux 0xfdb9b629 ioread32be +EXPORT_SYMBOL vmlinux 0xfdce83ad aio_complete +EXPORT_SYMBOL vmlinux 0xfde2145a boot_tvec_bases +EXPORT_SYMBOL vmlinux 0xfde4a11a dm_kcopyd_copy +EXPORT_SYMBOL vmlinux 0xfdfc0b3b fiemap_fill_next_extent +EXPORT_SYMBOL vmlinux 0xfe049a42 generic_writepages +EXPORT_SYMBOL vmlinux 0xfe1940fe scsi_setup_blk_pc_cmnd +EXPORT_SYMBOL vmlinux 0xfe25d1ab __blockdev_direct_IO +EXPORT_SYMBOL vmlinux 0xfe29e34d skb_copy +EXPORT_SYMBOL vmlinux 0xfe4c8e9a pnpbios_protocol +EXPORT_SYMBOL vmlinux 0xfe5d4bb2 sys_tz +EXPORT_SYMBOL vmlinux 0xfe769456 unregister_netdevice_notifier +EXPORT_SYMBOL vmlinux 0xfe7c4287 nr_cpu_ids +EXPORT_SYMBOL vmlinux 0xfe9acdb7 tty_throttle +EXPORT_SYMBOL vmlinux 0xfebf2e76 inet_sock_destruct +EXPORT_SYMBOL vmlinux 0xfec3c2f2 bcd2bin +EXPORT_SYMBOL vmlinux 0xfece8943 write_inode_now +EXPORT_SYMBOL vmlinux 0xfedd35fc console_suspend_enabled +EXPORT_SYMBOL vmlinux 0xfee71a5e ps2_handle_response +EXPORT_SYMBOL vmlinux 0xfeeca37e i2c_smbus_write_i2c_block_data +EXPORT_SYMBOL vmlinux 0xfef96e23 __scsi_print_command +EXPORT_SYMBOL vmlinux 0xff1e9dd8 seq_list_start +EXPORT_SYMBOL vmlinux 0xff2c46ef find_task_by_vpid +EXPORT_SYMBOL vmlinux 0xff3b4945 __tcp_get_md5sig_pool +EXPORT_SYMBOL vmlinux 0xff5c1ff5 blk_start_queueing +EXPORT_SYMBOL vmlinux 0xff6878cf fb_default_cmap +EXPORT_SYMBOL vmlinux 0xff708fd3 mempool_destroy +EXPORT_SYMBOL vmlinux 0xff7559e4 ioport_resource +EXPORT_SYMBOL vmlinux 0xff839d81 __kfree_skb +EXPORT_SYMBOL vmlinux 0xff9351d4 ip_route_input +EXPORT_SYMBOL vmlinux 0xff9ca065 fb_edid_to_monspecs +EXPORT_SYMBOL vmlinux 0xffa40b91 journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0xffafdc5c _read_unlock_irq +EXPORT_SYMBOL vmlinux 0xffc346e2 ppp_register_channel +EXPORT_SYMBOL vmlinux 0xffca0de7 sock_no_poll +EXPORT_SYMBOL vmlinux 0xffd5a395 default_wake_function +EXPORT_SYMBOL vmlinux 0xffec0387 generic_block_fiemap +EXPORT_SYMBOL vmlinux 0xffef3593 acpi_notifier_call_chain +EXPORT_SYMBOL_GPL arch/x86/kernel/microcode 0xdf66ca81 ucode_cpu_info +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x00aaf935 kvm_disable_tdp +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x01ab7508 kvm_mmu_invlpg +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x034fa837 kvm_lapic_get_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x04008f2e kvm_x86_ops +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x073a79cd kvm_put_guest_fpu +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x094ac8f4 kvm_get_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x12d1b23b kvm_release_pfn_clean +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x19e28c10 kvm_vcpu_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1a5f38d3 kvm_vcpu_uninit +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1a8854ac kvm_cpu_get_interrupt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1bbc8cc1 kvm_get_cs_db_l_bits +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1e4580bb kvm_release_pfn_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x21f19bb5 kvm_put_kvm +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x22e1174f kvm_get_msr_common +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x2322e039 kvm_set_pfn_accessed +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x27046576 kvm_exit +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x2f25db32 gfn_to_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x317f9e6b kvm_enable_efer_bits +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x322b4cd8 kvm_inject_pending_timer_irqs +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x3714ea19 kvm_emulate_halt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x3cd32eaf kvm_create_lapic +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x3ee1018b kvm_lapic_reset +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x3f99ee70 kvm_cpu_has_interrupt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x40a1981b emulator_write_emulated +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x453cf62e kvm_set_memory_region +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x46d0b61e kvm_write_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x46ef3282 emulator_read_std +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x48270e69 kvm_get_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x4908623d kvm_set_cr0 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x4a7cbe69 is_error_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x4f4b145e gfn_to_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x5955b8a3 is_error_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x599086dd kvm_handle_fault_on_reboot +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x5a628b16 kvm_resched +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x5cae8f02 kvm_read_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x616c7e2e kvm_release_page_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x63256184 __kvm_set_memory_region +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x665c3e98 kvm_read_guest +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x6960797c kvm_get_kvm +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x6b0ca4ce kvm_queue_exception_e +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x6b7de40a kvm_set_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x7cbe4bc9 kvm_vcpu_cache +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x7d0d90bb kvm_task_switch +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x7eb593be kvm_set_cr3 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8135e230 kvm_release_page_clean +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x82403fa0 load_pdptrs +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8273feb8 kvm_set_msr_common +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x856b5476 kvm_mmu_page_fault +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8ce4f3ab kvm_enable_tdp +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8e7f9b47 segment_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x9a117eeb kvm_emulate_pio_string +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x9fb852e2 gfn_to_hva +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa147a5fc kvm_timer_intr_post +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa1bf7133 kvm_lapic_get_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa2e131ab kvm_mmu_reset_context +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa361bc65 kvm_set_pfn_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa5d38e24 kvm_emulate_cpuid +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa964ab60 kvm_emulate_pio +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa9a29414 kvm_clear_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xaa80d268 emulate_instruction +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xae175e94 kvm_get_apic_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb242fa31 kvm_lapic_find_highest_irr +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb58a2206 kvm_set_cr4 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb79cdb71 kvm_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbb3ea4a8 kvm_clear_guest +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbce08f6d kvm_queue_exception +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbd377dc9 kvm_mmu_set_nonpresent_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbd94103b kvm_mmu_set_base_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xc0af1321 kvm_mmu_unprotect_page_virt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xc2e670c1 kvm_is_visible_gfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xc328e0f4 kvm_load_guest_fpu +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xc5fb4221 kvm_lapic_set_tpr +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xcf97f74e kvm_set_apic_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd0b2727a kvm_mmu_set_mask_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd296def9 kvm_is_error_hva +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd97e80ac kvm_lmsw +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xda138fad kvm_inject_nmi +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xe67d2b9e kvm_mmu_load +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xeda73339 kvm_set_page_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf0b8a0b5 fx_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf189e721 kvm_report_emulation_failure +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xfcb744a9 kvm_lapic_enabled +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xfe47b271 kvm_emulate_hypercall +EXPORT_SYMBOL_GPL crypto/aes_generic 0x1381bf2d crypto_ft_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x22894d94 crypto_il_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x3339118e crypto_aes_set_key +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5f943003 crypto_it_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5fe743de crypto_aes_expand_key +EXPORT_SYMBOL_GPL crypto/aes_generic 0x6e9cc2ba crypto_fl_tab +EXPORT_SYMBOL_GPL crypto/async_tx/async_memcpy 0x95d1db72 async_memcpy +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x08633e1b async_tx_submit +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x3fdcbcd2 async_trigger_callback +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x7aa5367c async_tx_quiesce +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0xbae4e29a async_xor_zero_sum +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0xd49d333c async_xor +EXPORT_SYMBOL_GPL crypto/des_generic 0xcfd9a2c0 des_ekey +EXPORT_SYMBOL_GPL crypto/twofish_common 0xe8e4dd13 twofish_setkey +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x02ff9464 cfag12864b_isinited +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x0ecb2e5d cfag12864b_disable +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x305dc3c6 cfag12864b_isenabled +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x3389f926 cfag12864b_enable +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x9522a342 cfag12864b_getrate +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0xc48e9d95 cfag12864b_buffer +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x14102f23 ks0108_displaystate +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x48a70518 ks0108_writedata +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x4f506333 ks0108_startline +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x6edae968 ks0108_isinited +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xbf4774db ks0108_writecontrol +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xedde6df2 ks0108_page +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xfee8ef7b ks0108_address +EXPORT_SYMBOL_GPL drivers/char/agp/agpgart 0x704f8eb9 agp_remove_bridge +EXPORT_SYMBOL_GPL drivers/char/agp/agpgart 0xb6631693 agp_add_bridge +EXPORT_SYMBOL_GPL drivers/char/agp/agpgart 0xd6feefa5 agp_num_entries +EXPORT_SYMBOL_GPL drivers/char/agp/agpgart 0xe089cfcc agp_memory_reserved +EXPORT_SYMBOL_GPL drivers/char/scx200_gpio 0x3ab976ed scx200_gpio_ops +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x16aa623d tpm_pm_resume +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x26c2fd69 tpm_show_temp_deactivated +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x2e2541f0 tpm_dev_vendor_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x32291acc tpm_open +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x39aae94a tpm_get_timeouts +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x3a3d7448 tpm_dev_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x4845c111 tpm_show_owned +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x6b7ff3c4 tpm_pm_suspend +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x74553deb tpm_store_cancel +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x74cb1977 tpm_show_caps +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x7e5731b2 tpm_calc_ordinal_duration +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x85524b03 tpm_show_pcrs +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x894418b4 tpm_gen_interrupt +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x932d74bb tpm_register_hardware +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xa1f4b211 tpm_remove_hardware +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xa4301fc6 tpm_show_active +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xbe56c875 tpm_show_caps_1_2 +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xc2e2183d tpm_write +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xc2e58dbd tpm_show_pubek +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xc683be8a tpm_show_enabled +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xe805c16a tpm_continue_selftest +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xebb0b3fc tpm_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xee435b6c tpm_read +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm_bios 0x92d0b50a tpm_bios_log_setup +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm_bios 0xcb05ad07 tpm_bios_log_teardown +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x053d692a edac_pci_reset_delay_period +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x0c3a6ca8 edac_device_add_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x2ae86246 edac_mc_add_mc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x2f4694e1 edac_mc_handle_ue_no_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x2fa5d929 edac_mc_handle_ce_no_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x462d76c8 edac_pci_release_generic_ctl +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x559e4b8e edac_mc_handle_ue +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x584966de edac_device_del_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x5ced7b0a edac_mc_free +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x6de2bfd1 edac_mc_alloc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x70a72465 edac_pci_handle_pe +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x824d0e52 edac_mc_find_csrow_by_page +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x86f14ae1 edac_pci_free_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x9767b4ee edac_device_free_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x9a7d3d33 edac_device_handle_ce +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xa0e8c774 edac_pci_create_generic_ctl +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xada137d0 edac_mc_handle_ce +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xb36f77de edac_device_alloc_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xb99a6c52 edac_pci_handle_npe +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xd58b7577 edac_device_handle_ue +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xe0a1625c edac_pci_add_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xe36394b4 edac_mc_del_mc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xf50ece06 edac_pci_alloc_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xfd1883c0 edac_pci_del_device +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x01fd453e usbhid_lookup_quirk +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x317a815a usbhid_submit_report +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x3ca433c4 hiddev_hid_event +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x9e36e406 usbhid_set_leds +EXPORT_SYMBOL_GPL drivers/i2c/busses/i2c-nforce2 0xde29b92e nforce2_smbus +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0xb092636a hpsb_config_rom_ip1394_remove +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0xc0e68aa5 hpsb_config_rom_ip1394_add +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0xec8d18cf hpsb_disable_irm +EXPORT_SYMBOL_GPL drivers/input/ff-memless 0xc9888c56 input_ff_create_memless +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x05171ec4 wm97xx_read_aux_adc +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x328d0aba wm97xx_reg_read +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x386a361a wm9713_codec +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x3e3afbd9 wm97xx_get_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x71949af6 wm97xx_set_suspend_mode +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x7229266b wm97xx_reg_write +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xb13f1be4 wm97xx_unregister_mach_ops +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xd1b7e6ae wm97xx_set_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xdbbde0ae wm97xx_register_mach_ops +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xe97e2bde wm9705_codec +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xf4c03684 wm9712_codec +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xf9a87152 wm97xx_config_gpio +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x05be02b6 gigaset_m10x_input +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x1d1e9ef7 gigaset_handle_modem_response +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x2105df9f gigaset_fill_inbuf +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x454aa44f gigaset_debuglevel +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x481fcf0f gigaset_if_receive +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x4999ba39 gigaset_m10x_send_skb +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x4e792275 gigaset_dbg_buffer +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x78e170cd gigaset_stop +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x94dbeb8d gigaset_add_event +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xb161ccf3 gigaset_initcs +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xb54d0dba gigaset_freecs +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xb83d0e67 gigaset_skb_sent +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xbbb4ce9d gigaset_initdriver +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xc8511662 gigaset_start +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xe7fbd766 gigaset_blockdriver +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xfd72056c gigaset_freedriver +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xff21646e gigaset_shutdown +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x001a452c led_classdev_suspend +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x3477a6c5 led_classdev_register +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x4d02026f led_classdev_resume +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x834bd65a led_classdev_unregister +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x04662e0f ir_codes_fusionhdtv_mce +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x07e92917 ir_codes_avermedia_a16d +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x083661f9 ir_codes_avertv_303 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x088631b9 ir_codes_behold +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x1cb148f5 ir_extract_bits +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2456e513 ir_decode_pulsedistance +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2a4852cc ir_codes_dntv_live_dvb_t +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2af1a608 ir_codes_proteus_2309 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x3811daea ir_codes_manli +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x40ebfad6 ir_input_keydown +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x43c89ef4 ir_decode_biphase +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x45b08f68 ir_codes_pinnacle_grey +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4740e7a3 ir_codes_empty +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4beb7618 ir_codes_encore_enltv_fm53 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4e8ae507 ir_input_init +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4ea698a2 ir_codes_purpletv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x55338dda ir_codes_pixelview_new +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x589cad50 ir_codes_apac_viewcomp +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x5bd86ce0 ir_input_nokey +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x5db13554 ir_codes_encore_enltv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6606596a ir_rc5_timer_keyup +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6adc476d ir_codes_powercolor_real_angel +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6aefdbea ir_codes_npgtech +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6b87c69d ir_codes_iodata_bctv7e +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6d6511e7 ir_dump_samples +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6e2a1870 ir_codes_adstech_dvb_t_pci +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x7277973d ir_codes_pctv_sedna +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x75e89cc3 ir_codes_flydvb +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x772a30a2 ir_codes_nebula +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x7b38143b ir_codes_encore_enltv2 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x85d37490 ir_codes_dntv_live_dvbt_pro +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x89cc1189 ir_codes_winfast +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x902a3cd2 ir_codes_hauppauge_new +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x933d0bb3 ir_codes_msi_tvanywhere +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x9451e232 ir_codes_behold_columbus +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x96470cab ir_codes_cinergy +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb1f4eb35 ir_codes_avermedia_dvbt +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb50812de ir_codes_real_audio_220_32_keys +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb6cd4666 ir_codes_eztv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xbb08d146 ir_codes_msi_tvanywhere_plus +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xbdce6594 ir_codes_tt_1500 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc1fea0c1 ir_codes_pv951 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc42bd037 ir_codes_budget_ci_old +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc6c5a7a1 ir_codes_em_terratec +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xcdf2859f ir_codes_avermedia_m135a +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd1e0258a ir_codes_flyvideo +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd55e6891 ir_codes_gotview7135 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd9c7f010 ir_codes_rc5_tv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xdaa041ad ir_codes_cinergy_1400 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xdfcf23df ir_codes_norwood +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xee2f5e0e ir_codes_pinnacle_pctv_hd +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf07533a1 ir_codes_videomate_tv_pvr +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf0fc9374 ir_codes_avermedia +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf2b421aa ir_codes_genius_tvgo_a11mce +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf4f7a4d6 ir_rc5_timer_end +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfa177653 ir_codes_pixelview +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfb981300 ir_codes_pinnacle_color +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfc54a5cd ir_codes_asus_pc39 +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x1684a8a6 saa7146_i2c_adapter_prepare +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x5b65bbeb saa7146_vmalloc_build_pgtable +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x85e9a97b saa7146_pgtable_free +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x87616855 saa7146_pgtable_build_single +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x8cfd9ea3 saa7146_register_extension +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x997dbd4d saa7146_setgpio +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xa475d95c saa7146_vfree_destroy_pgtable +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xa5e3a7fa saa7146_wait_for_debi_done +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xc98faf20 saa7146_devices_lock +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xcf683cf2 saa7146_devices +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xdab5c0b5 saa7146_unregister_extension +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xe3cd9b5c saa7146_debug +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xe84b4663 saa7146_pgtable_alloc +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x19a12c52 saa7146_vv_init +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x19badfc3 saa7146_vv_release +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x61db8e56 saa7146_register_device +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x8a7c53d4 saa7146_stop_preview +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xc792c768 saa7146_set_hps_source_and_sync +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xf3c61401 saa7146_start_preview +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xf5f4379a saa7146_unregister_device +EXPORT_SYMBOL_GPL drivers/media/common/tuners/mt20xx 0x6922d838 microtune_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/mxl5007t 0x8d101032 mxl5007t_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda18271 0xa4fb3537 tda18271_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda827x 0x05e75fc7 tda827x_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda8290 0x8a11a30d tda829x_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda8290 0xe3a38a9b tda829x_probe +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda9887 0x3334cdc2 tda9887_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5761 0x5f2e3427 tea5761_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5761 0xa77e5c10 tea5761_autodetection +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5767 0x24ff9c0c tea5767_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5767 0xe1417a1a tea5767_autodetection +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tuner-simple 0x18468258 simple_tuner_attach +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x19264d93 ttpci_budget_debiread +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x4426b64e ttpci_budget_init_hooks +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x7948c222 budget_debug +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x7b12749c ttpci_budget_deinit +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x9aedc5cb ttpci_budget_debiwrite +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xca700268 ttpci_budget_set_video_port +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xe67608f9 ttpci_budget_irq10_handler +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xf41bd23e ttpci_budget_init +EXPORT_SYMBOL_GPL drivers/media/video/compat_ioctl32 0x2423bd4a v4l_compat_ioctl32 +EXPORT_SYMBOL_GPL drivers/media/video/cx88/cx88xx 0x47a682a5 cx88_setup_xc3028 +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x1c0d789c em28xx_init_isoc +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x21428b29 em28xx_uninit_isoc +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x7fc8652c em28xx_tuner_callback +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x9ec45756 em28xx_audio_analog_set +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0xdcc63fb7 em28xx_set_mode +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x2da0edd7 saa7134_ts_qops +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x378c7b0d saa7134_g_ctrl_internal +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x98a84c9c saa7134_i2c_call_saa6752 +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0xe07a4670 saa7134_queryctrl +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0xf64d064d saa7134_s_ctrl_internal +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0xfc73f475 saa7134_s_std_internal +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0x84e7a2e0 v4l2_int_device_register +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xa5228b24 v4l2_int_device_try_attach_all +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xba1a7547 v4l2_int_ioctl_1 +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xe108fa90 v4l2_int_ioctl_0 +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xe707a298 v4l2_int_device_unregister +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x13c0c829 videobuf_poll_stream +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x14430db2 videobuf_read_stream +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x1d2ec7e8 videobuf_alloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x21adc965 videobuf_mmap_mapper +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x407d9c38 videobuf_mmap_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x61964a6e videobuf_reqbufs +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x673a3597 videobuf_iolock +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x7531c536 videobuf_queue_to_vmalloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x84cf35c8 videobuf_streamon +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x902d4885 videobuf_querybuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x97854633 videobuf_dqbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x99239bc1 videobuf_read_stop +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xad04ffad videobuf_qbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xaf028423 videobuf_waiton +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xb70e8d3e videobuf_queue_core_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xb7d25d74 videobuf_stop +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xc7af5812 videobuf_read_start +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xc92eceed videobuf_streamoff +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xcbeaa18c __videobuf_mmap_setup +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xd581d5f4 videobuf_read_one +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xd9496a77 videobuf_queue_is_busy +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xdb216e78 videobuf_cgmbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xe6c3cb0f videobuf_mmap_setup +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xf43a3f7a videobuf_queue_cancel +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xfe8b8d43 videobuf_next_field +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-contig 0x4117d18f videobuf_dma_contig_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-contig 0xb570e108 videobuf_queue_dma_contig_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-contig 0xe5977625 videobuf_to_dma_contig +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x1348e536 videobuf_dma_init_overlay +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x1a825456 videobuf_dma_init_kernel +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x30766a12 videobuf_dma_map +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x35a31026 videobuf_dma_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x4a38894b videobuf_sg_dma_map +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x72cb12d8 videobuf_sg_dma_unmap +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x77137bdd videobuf_to_dma +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x8521cbec videobuf_queue_sg_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x933dfb43 videobuf_vmalloc_to_sg +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x9ac4b7ec videobuf_dma_sync +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xa825c75b videobuf_sg_alloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xc8a02ce1 videobuf_dma_init_user +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xd4c57db5 videobuf_dma_unmap +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xd573806b videobuf_dma_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0x64bf5cc6 videobuf_vmalloc_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0xacd62357 videobuf_to_vmalloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0xfae257af videobuf_queue_vmalloc_init +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x0c28d894 i2o_pool_alloc +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x23f59268 i2o_dma_map_single +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x48503872 i2o_dma_map_sg +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x520d2108 i2o_dma_realloc +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x6748cc58 i2o_dma_free +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xa1a4e3fb i2o_dma_alloc +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xb1f19ea5 i2o_sg_tablesize +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xff582359 i2o_pool_free +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x045c9a4f sm501_misc_control +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x04788cd0 sm501_unit_power +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x92c93a69 sm501_set_clock +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0xc6b5e8c5 sm501_find_clock +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0xdf1cace8 sm501_modify_reg +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x098cb984 wm8350_device_exit +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x109aba52 wm8350_reg_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x1a97318e wm8350_mask_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x24a84606 wm8350_gpio_config +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x2760bb31 wm8350_register_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x3550f09e wm8350_clear_bits +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x568f277f wm8350_unmask_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x5d532780 wm8350_free_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x61489ec9 wm8350_reg_lock +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x8b859947 wm8350_block_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x91a281db wm8350_reg_write +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x95eed844 wm8350_set_bits +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xa3a0224b wm8350_device_init +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xcc964d4d wm8350_block_write +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xf35e4a1b wm8350_reg_unlock +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x29bf5d89 wm8400_reg_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x3fb720a5 wm8400_block_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x67c2b561 wm8400_set_bits +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0xeeae0231 wm8400_reset_codec_reg_cache +EXPORT_SYMBOL_GPL drivers/misc/eeprom_93cx6 0x2df115d4 eeprom_93cx6_multiread +EXPORT_SYMBOL_GPL drivers/misc/eeprom_93cx6 0x63d14d2f eeprom_93cx6_read +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x3f99015a enclosure_for_each_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x4029c968 enclosure_register +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x5169a604 enclosure_unregister +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x80bda328 enclosure_find +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0xb6417eaa enclosure_remove_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0xd062078b enclosure_add_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0xdea09b14 enclosure_component_register +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x1c2757be sdhci_suspend_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x3bb835e6 sdhci_alloc_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x66b42b82 sdhci_resume_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0xae1f4175 sdhci_free_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0xb87e0544 sdhci_remove_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0xf09e228c sdhci_add_host +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0x36cf58b3 cfi_cmdset_0001 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0xaf8b213f cfi_cmdset_0003 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0xc482e3ee cfi_cmdset_0200 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0002 0xe3291df9 cfi_cmdset_0002 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0020 0x9efaef07 cfi_cmdset_0020 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0x25ee4eb2 cfi_qry_mode_on +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0x2e00cf86 cfi_qry_present +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0x3de6068d cfi_qry_mode_off +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2000 0x42139018 DoC2k_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2001 0x6d37cad4 DoCMil_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2001plus 0x5021f6f9 DoCMilPlus_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/docecc 0x45937659 doc_decode_ecc +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x0518010a mtd_erase_callback +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x0e0fdabf get_mtd_device_nm +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x2dcac5d0 mtd_table +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x374240ee del_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x406b214e put_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x743a78b7 register_mtd_parser +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x7bfc8e20 parse_mtd_partitions +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x8f9a55dd unregister_mtd_user +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x9ad42fa6 deregister_mtd_parser +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xbdf371f4 get_sb_mtd +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xc1e37c07 add_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xd035a681 default_mtd_writev +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xd9185060 kill_mtd_super +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xe993a2bd register_mtd_user +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xefed530d get_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xeff64be1 mtd_table_mutex +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0x105de705 del_mtd_blktrans_dev +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0x1b171288 add_mtd_blktrans_dev +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0x636a42d5 register_mtd_blktrans +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0x6763264b deregister_mtd_blktrans +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x4c300f5d nand_scan +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x5fe8e95f nand_release +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x6cbc65fb nand_wait_ready +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xa74e27f3 nand_scan_tail +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xc7882412 nand_scan_ident +EXPORT_SYMBOL_GPL drivers/mtd/onenand/onenand 0x4d0b64df onenand_release +EXPORT_SYMBOL_GPL drivers/mtd/onenand/onenand 0x86cadce3 onenand_scan +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x31ea2b83 ubi_get_volume_info +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x37754d9a ubi_leb_change +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x42801d20 ubi_sync +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x554128cb ubi_open_volume +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x5e5cb3e4 ubi_leb_erase +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x6242abee ubi_leb_unmap +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x8a41fbf8 ubi_leb_write +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x8da2f0dd ubi_leb_read +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xb3782dde ubi_leb_map +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xb6e98360 ubi_close_volume +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xbc505df4 ubi_get_device_info +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xcd51a402 ubi_open_volume_nm +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xf38950a5 ubi_is_mapped +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x006d3228 mlx4_cq_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0f04dbaa mlx4_SYNC_TPT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x115dd3fd mlx4_srq_arm +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x13842f57 mlx4_unregister_vlan +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x1be2a78b mlx4_uar_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x1c032c87 mlx4_unregister_interface +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x266292fd mlx4_fmr_unmap +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x270b814b mlx4_srq_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x2b9d0ed1 mlx4_alloc_hwq_res +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x303e8b69 mlx4_CLOSE_PORT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x31a5073a mlx4_alloc_cmd_mailbox +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x33763e3e mlx4_unregister_mac +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x36317ee5 mlx4_cq_modify +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x372516a5 mlx4_buf_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x3a1764ee mlx4_qp_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x422770b4 mlx4_mr_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x4f7bf728 mlx4_free_cmd_mailbox +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x55f435d7 mlx4_INIT_PORT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5674535c mlx4_map_phys_fmr +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5b9e9a7e mlx4_mtt_cleanup +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x66f8d5ae mlx4_register_vlan +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x72180bb3 mlx4_buf_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x7cc27174 mlx4_mr_enable +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x7d0ade5e mlx4_pd_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x809e7039 mlx4_mr_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x80b92740 mlx4_qp_remove +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x820a14ac mlx4_db_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x83ab7d9b mlx4_buf_write_mtt +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x870660cc mlx4_uar_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x8ee5889b mlx4_register_mac +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x93515c3c mlx4_mtt_init +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x9662d538 mlx4_free_hwq_res +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x976e5500 mlx4_multicast_attach +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xa2d00bd4 mlx4_qp_reserve_range +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xa7571951 mlx4_db_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xa78ac9a4 mlx4_mtt_addr +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xabc606a4 mlx4_cq_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xb6569f92 mlx4_fmr_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xb863eeb6 mlx4_multicast_detach +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xb988ab2e mlx4_srq_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xbb08c44f mlx4_qp_to_ready +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xbe4b8854 mlx4_pd_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xc2b3cb83 mlx4_write_mtt +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xcf3458c1 __mlx4_cmd +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xcfdd91f9 mlx4_srq_query +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xd16c3488 mlx4_cq_resize +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xd1a0bc91 mlx4_register_interface +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xd8b1235f mlx4_qp_modify +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xd941aa3f mlx4_qp_query +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xe0690c1d mlx4_fmr_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xe6bce53c mlx4_qp_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf8afec43 mlx4_fmr_enable +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xfe5ae10e mlx4_qp_release_range +EXPORT_SYMBOL_GPL drivers/net/usb/cdc_ether 0x15626221 usbnet_cdc_unbind +EXPORT_SYMBOL_GPL drivers/net/usb/cdc_ether 0xefa088b0 usbnet_generic_cdc_bind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x03abdde4 generic_rndis_bind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x4cd23ea6 rndis_unbind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x6ae025b6 rndis_tx_fixup +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x7d1d3bac rndis_command +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xba5db297 rndis_status +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xf946640c rndis_rx_fixup +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x13f402f7 usbnet_set_settings +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x18e6e845 usbnet_get_drvinfo +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x1c530b7b usbnet_defer_kevent +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x2f4dfe87 usbnet_get_link +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x4750256c usbnet_get_settings +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x5b5cf601 usbnet_get_msglevel +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x61bab6ed usbnet_skb_return +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x6a549f1d usbnet_suspend +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x78ab9316 usbnet_unlink_rx_urbs +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x7b55b807 usbnet_probe +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xa1d06e8f usbnet_resume +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xb513bf11 usbnet_nway_reset +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xb80b4983 usbnet_get_endpoints +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xb8295521 usbnet_disconnect +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xf34a3b4a usbnet_set_msglevel +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x0e041a26 lbs_send_tx_feedback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x0e7a2375 lbs_cmd_copyback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x34c417ca __lbs_cmd +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x4708ebb1 lbs_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x62ecbc14 lbs_remove_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x657a0fb1 lbs_host_sleep_cfg +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x83f8806b lbs_start_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x881af006 lbs_host_to_card_done +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x95cb8bea lbs_queue_event +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xa41e1dbe lbs_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xa8667be3 lbs_cmd_802_11_rate_adapt_rateset +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xc93d6939 lbs_add_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xe8bc6a06 lbs_notify_command_response +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xe96b93e4 lbs_stop_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xeb4f7306 lbs_process_rxed_packet +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xf64277de lbs_debug +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x1bf80cc0 lbtf_send_tx_feedback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x26197b90 lbtf_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x716d868f lbtf_cmd_copyback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x88ac81a9 lbtf_add_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x990ff013 lbtf_bcn_sent +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xac3ba74e lbtf_remove_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xc89b9f0a lbtf_cmd_response_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xef37e38b __lbtf_cmd +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf_usb 0x232c8824 if_usb_reset_device +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf_usb 0x3ed9ab98 if_usb_prog_firmware +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x0524d50c p54_read_eeprom +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x263573ad p54_parse_firmware +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x52d0e0ba p54_free_common +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x9ec3c17e p54_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0xc1d951da p54_init_common +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x1ef34a69 rt2x00mac_get_tx_stats +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x3f257af9 rt2x00mac_add_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x44ac6468 rt2x00queue_get_entry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x44e2ab2a rt2x00mac_conf_tx +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x4c612f81 rt2x00lib_beacondone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x4fc80d3b rt2x00queue_get_queue +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x510793c9 rt2x00lib_remove_dev +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x6c7d19fb rt2x00mac_configure_filter +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x77bde2f5 rt2x00mac_start +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x78975dd6 rt2x00lib_rxdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x7c3801b4 rt2x00mac_stop +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x84b0dcf1 rt2x00mac_get_stats +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x8c186daf rt2x00mac_config_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x92ceda6b rt2x00mac_remove_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x9e2b390b rt2x00lib_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x9fbec646 rt2x00lib_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xa28f654e rt2x00mac_set_key +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xb0bb86d2 rt2x00queue_map_txskb +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xcef42dfb rt2x00mac_bss_info_changed +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xcfba580f rt2x00mac_config +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xda0e5dbf rt2x00lib_txdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xe3a30650 rt2x00mac_tx +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xf0871a74 rt2x00lib_probe_dev +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x01daa4c0 rt2x00pci_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x0526222e rt2x00pci_write_tx_data +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x20c41adf rt2x00pci_remove +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x567dabb2 rt2x00pci_uninitialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x6ea15e55 rt2x00pci_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x7fac3c08 rt2x00pci_rxdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x8eafa28a rt2x00pci_probe +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0xb443a8e3 rt2x00pci_initialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x020805fc rt2x00usb_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x0dc8537b rt2x00usb_vendor_request +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x0e2bebef rt2x00usb_vendor_request_large_buff +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x25ae5986 rt2x00usb_initialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x2e2536c7 rt2x00usb_disconnect +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x39cf438e rt2x00usb_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x4fc3a366 rt2x00usb_disable_radio +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x5edfc094 rt2x00usb_init_rxentry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x6dc02786 rt2x00usb_init_txentry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x6e5a4747 rt2x00usb_kick_tx_queue +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x758a17a6 rt2x00usb_probe +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x7c533b19 rt2x00usb_vendor_req_buff_lock +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x844d6737 rt2x00usb_uninitialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xd100128b rt2x00usb_write_tx_data +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xdc3ac27d rt2x00usb_vendor_request_buff +EXPORT_SYMBOL_GPL drivers/pci/hotplug/acpiphp 0x57b9222a acpiphp_unregister_attention +EXPORT_SYMBOL_GPL drivers/pci/hotplug/acpiphp 0x91e2f602 acpiphp_register_attention +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0x1ae3c1b8 wm8350_dcdc_set_slot +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0x44c14274 wm8350_isink_set_flash +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0x4a4b91de wm8350_dcdc25_set_mode +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0x51b8d34f wm8350_ldo_set_slot +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0x6202c71c wm8350_register_regulator +EXPORT_SYMBOL_GPL drivers/regulator/wm8400-regulator 0xe0e6f27b wm8400_register_regulator +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x0233f349 iscsi_pool_init +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x1442243e iscsi_set_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x20a0b29a iscsi_conn_stop +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x20fa6de2 iscsi_itt_to_ctask +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x218065bf iscsi_conn_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x3f8c03ef iscsi_host_set_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x41ba1d14 iscsi_pool_free +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x43c1a643 iscsi_host_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x4dde4db2 iscsi_conn_start +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x5241c84f iscsi_eh_target_reset +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x5ff6fff6 iscsi_requeue_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x66165de8 iscsi_complete_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x6c16db8f iscsi_conn_bind +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x717e8495 iscsi_put_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x752ee892 iscsi_host_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x7f117d87 iscsi_host_remove +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x846295f1 iscsi_verify_itt +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x84e46450 iscsi_prep_unsolicit_data_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x9077f828 iscsi_conn_setup +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x922aa5ab iscsi_conn_teardown +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x925b0d63 iscsi_session_recovery_timedout +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x9c64cd2e iscsi_session_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x9edd87db iscsi_change_queue_depth +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xa3d95579 iscsi_session_teardown +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xadf30505 iscsi_update_cmdsn +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xb0610dd5 iscsi_host_free +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xb50c59f8 iscsi_eh_abort +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xc0656dda iscsi_queuecommand +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xc16e2bb5 iscsi_conn_failure +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xc4d193d4 iscsi_session_setup +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xd1a59d86 iscsi_suspend_tx +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xe97b0adf iscsi_conn_send_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xec0b01f4 iscsi_session_failure +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xf1aed9d8 __iscsi_complete_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xf1c92591 iscsi_host_add +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xf268b5be __iscsi_get_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xfbd333c8 iscsi_eh_device_reset +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x092bb3d9 sas_eh_device_reset_handler +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x22d236c2 sas_task_abort +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x238a1bb2 sas_register_ha +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x333b45a6 sas_ioctl +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x344c1c31 sas_slave_configure +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x37c9104a sas_slave_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x40c08a96 sas_find_local_phy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x46f91ad2 sas_target_destroy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x49fa4cf7 sas_phy_reset +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x55724a62 sas_change_queue_depth +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x61550be5 sas_request_addr +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x642a5dd8 sas_target_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x6fab4bd5 sas_domain_release_transport +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x85a4ea9f sas_bios_param +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x9fee3542 sas_change_queue_type +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xaf43c617 sas_domain_attach_transport +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xb167d640 sas_eh_bus_reset_handler +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xc0ee290b sas_unregister_ha +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xc39732b0 sas_phy_enable +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xd1aad2b5 sas_queuecommand +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xe8dabe09 sas_slave_destroy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xeddb45c8 sas_ssp_task_response +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xf05aefa1 __sas_task_abort +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x09db7469 srp_target_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x8e68a713 srp_target_free +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x94e49133 srp_cmd_queue +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x9cf82cdb srp_transfer_data +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0xcf8313c8 srp_iu_put +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0xebc8dbc5 srp_iu_get +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x08bcd765 scsi_tgt_cmd_to_host +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x39f43803 scsi_host_put_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x84fbfebf scsi_tgt_tsk_mgmt_request +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x8cf234a3 scsi_tgt_it_nexus_destroy +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xb0a4877b scsi_tgt_free_queue +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xec083cdd scsi_tgt_it_nexus_create +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xf245cb72 scsi_tgt_queue_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xfbf5c568 scsi_tgt_alloc_queue +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xfec8e092 scsi_host_get_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x079efa74 iscsi_free_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x07dd212d iscsi_lookup_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x0b9bfac1 iscsi_unregister_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x190fc7c5 iscsi_create_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x286ea5dc iscsi_destroy_conn +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x2bbaa0b7 iscsi_block_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x30c1d466 iscsi_conn_error_event +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x3186131c iscsi_alloc_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x5a87b87b iscsi_unblock_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x6ea16e86 iscsi_destroy_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x87c5d063 iscsi_create_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x900ce6d5 iscsi_session_event +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x9d411f10 iscsi_add_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x9dbb7007 iscsi_host_for_each_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xa6a1900e iscsi_destroy_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xbf37b0de iscsi_register_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xc2cfa4d8 iscsi_scan_finished +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xd7e29f02 iscsi_create_conn +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xd8168b7a iscsi_session_chkready +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xdbbc3e39 iscsi_recv_pdu +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xf883a9b7 iscsi_remove_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0x0ef06974 spi_populate_ppr_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0xa0c71dac spi_populate_sync_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0xcffa2aff spi_populate_width_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x22f1b4fb srp_rport_add +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x4ee7f457 srp_release_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x79de753c srp_attach_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0xb273b8dd srp_rport_del +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0xfc711d48 srp_remove_host +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x2611e191 spi_bitbang_start +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x9c498e1f spi_bitbang_setup +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0xacac8642 spi_bitbang_cleanup +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0xad4f6d47 spi_bitbang_setup_transfer +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0xb04a158d spi_bitbang_stop +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0xfb76220e spi_bitbang_transfer +EXPORT_SYMBOL_GPL drivers/uio/uio 0x03371f6b uio_unregister_device +EXPORT_SYMBOL_GPL drivers/uio/uio 0x7b37a7d3 uio_event_notify +EXPORT_SYMBOL_GPL drivers/uio/uio 0xe036ef5d __uio_register_device +EXPORT_SYMBOL_GPL drivers/usb/atm/usbatm 0x5bbb8c8c usbatm_usb_probe +EXPORT_SYMBOL_GPL drivers/usb/atm/usbatm 0x7b617394 usbatm_usb_disconnect +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x37e0584e usb_ftdi_elan_write_pcimem +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x793e037a usb_ftdi_elan_edset_setup +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x89eef424 usb_ftdi_elan_edset_single +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xa8cbdbf8 usb_ftdi_elan_edset_output +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xb639b8fc usb_ftdi_elan_read_pcimem +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xb81bad35 ftdi_elan_gone_away +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xb952db12 usb_ftdi_elan_edset_empty +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xc0a18072 usb_ftdi_elan_edset_input +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xe2d5302f usb_ftdi_elan_edset_flush +EXPORT_SYMBOL_GPL drivers/usb/misc/phidget 0x13a0b2da phidget_class +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x36c58928 wa_urb_dequeue +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x436be4dd wa_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x5620a158 rpipe_ep_disable +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x8a5096a4 wa_urb_enqueue +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xc5b5a2bd __wa_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xcb55ad58 rpipe_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xf4654c3f wa_urb_enqueue_run +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x080fa58c wusbhc_handle_dn +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x0bb6bf5e wusb_cluster_id_get +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x0be3cc0e wusbhc_stop +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x23459141 wusbhc_reset_all +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x312d313f wusbhc_giveback_urb +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x3e8af3b1 wusbhc_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x4811f965 wusbhc_rh_suspend +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x4fcc1ccf wusbhc_mmcie_rm +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x7f0b7631 wusb_dev_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xa4900371 wusbhc_b_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xac4cc77f wusbhc_mmcie_set +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xb5715745 wusbhc_b_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xb61c15d1 __wusb_dev_get_by_usb_dev +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xb725d128 wusb_cluster_id_put +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xd75740f0 wusbhc_rh_resume +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xd9430b30 wusbhc_chid_set +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xdab5a979 wusbhc_rh_control +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xed6fa83a wusbhc_rh_start_port_reset +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xf01c3a3b wusbhc_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xf770a6b4 wusbd +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xfe25a58f wusbhc_rh_status_data +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xfe2e17d7 wusb_et_name +EXPORT_SYMBOL_GPL drivers/uwb/i1480/dfu/i1480-dfu-usb 0x132a9b94 i1480_fw_upload +EXPORT_SYMBOL_GPL drivers/uwb/i1480/dfu/i1480-dfu-usb 0x419cbede i1480_rceb_check +EXPORT_SYMBOL_GPL drivers/uwb/i1480/dfu/i1480-dfu-usb 0xcca0de85 i1480_cmd +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x344d22ac uwb_rts_cts_show +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x34dc4993 uwb_pca_base_priority_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x5c794c64 uwb_ack_policy_show +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x75f2678c uwb_ack_policy_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x789aec33 uwb_rts_cts_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x88f453af uwb_phy_rate_show +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x965032cc uwb_phy_rate_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0xd0ec3c3f uwb_pca_base_priority_show +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x24b6392a umc_match_pci_id +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x5dca06a3 umc_bus_type +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x67a37cf3 umc_device_register +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x6ca83800 umc_device_unregister +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x70178485 umc_device_create +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x8820089a umc_controller_reset +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x9cb4f0f9 umc_driver_unregister +EXPORT_SYMBOL_GPL drivers/uwb/umc 0xe11abc58 __umc_driver_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x0b8aad57 uwb_est_unregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x0d652d13 uwb_rc_rm +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x1a243c4c uwb_rc_get_ie +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x1af4cf76 uwb_rc_neh_grok +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x28ccd00d uwb_rc_ie_add +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x2e5d17f9 uwb_rc_neh_error +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x30539dcf uwb_notifs_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x3de5f6cf uwb_rc_cmd_async +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x444b4580 uwb_rc_reset_all +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x484ed37a uwb_pal_init +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4aef23a2 uwb_rsv_establish +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4d57ae3c uwb_rsv_type_str +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x5e4bc088 __uwb_addr_print +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x5e8dd11d uwb_pal_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x6768a2f7 uwb_rc_init +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x68e5f1ec uwb_bg_joined +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x757a56a8 uwb_rc_ie_rm +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7613c0e2 uwb_rsv_state_str +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7dcfcd23 uwb_ie_next +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x853f2936 uwb_rc_vcmd +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x88a2774f uwb_dev_try_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x88e4909f uwb_rsv_accept +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x96e66c70 uwb_rc_get_by_grandpa +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x978d1f04 uwb_rc_mac_addr_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x9b1e8a0e uwb_rc_put +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa189aaf8 dump_bytes +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa408eab8 uwb_rc_cmd +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa529f6c3 uwb_ie_dump_hex +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xb75a20f4 __uwb_rc_try_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xb783e96c uwb_rsv_terminate +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xbff20dce uwb_dev_for_each +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xc36192c4 uwb_ie_for_each +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xd85d36ed uwb_rc_add +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xdb6b0891 uwb_rc_get_by_dev +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xdd0a884b uwb_rc_dev_addr_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xdd400785 uwb_rc_alloc +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe1716f06 uwb_est_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe17e49b4 uwb_rsv_modify +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe1b3c43d uwb_notifs_deregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe625e3a5 uwb_est_find_size +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xebb145d1 uwb_pal_unregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xfa251ecf uwb_rsv_create +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xffe82870 uwb_rsv_destroy +EXPORT_SYMBOL_GPL drivers/uwb/whci 0x26dd0259 whci_wait_for +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x031513a4 wlp_dev_serial_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x05004678 wlp_dev_model_name_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x0db3f08a wlp_dev_name_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x0ef9ef48 wlp_wss_remove +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x19ee5f5b wlp_dev_prim_subcat_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x2027cc4c wlp_dev_serial_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x22df29af wlp_reset_all +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x2c2157ce wlp_setup +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x30da8f40 wlp_wss_setup +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x338ff9b8 wlp_eda_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x466d4e87 wlp_dev_name_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x4745bd2c wlp_uuid_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x49ac6efa wlp_eda_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x4c417103 wlp_dev_prim_OUI_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x73cf544f wlp_dev_model_nr_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x79c2a151 wlp_receive_frame +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x7ec75807 wlp_uuid_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x812b1e44 wlp_dev_prim_subcat_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x82017185 wlp_dev_model_nr_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x8864828a wlp_wss_activate_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x92cd3c16 wlp_prepare_tx_frame +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xb7157d34 wlp_dev_manufacturer_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xb72dac57 wlp_wss_activate_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xb8586c0a wlp_dev_prim_category_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xbb0f199e wlp_dev_prim_OUI_sub_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xbff8255c wlp_dev_prim_OUI_sub_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xc2d324f3 wlp_dev_prim_category_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xd4464172 wlp_neighborhood_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xd513a0ea wlp_dev_prim_OUI_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xd877e788 wlp_remove +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xec4bed71 wlp_dev_model_name_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xf51fdf87 wlp_dev_manufacturer_show +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x3d2d3d9c ili9320_write +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x4c121b8c ili9320_remove +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x4e66e916 ili9320_write_regs +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x50bc4684 ili9320_probe_spi +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x5eb9a4b9 ili9320_shutdown +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0xb02c701a ili9320_suspend +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0xf0a2cbfc ili9320_resume +EXPORT_SYMBOL_GPL drivers/video/fb_ddc 0xba75c278 fb_ddc_read +EXPORT_SYMBOL_GPL drivers/video/fb_sys_fops 0x502ade47 fb_sys_write +EXPORT_SYMBOL_GPL drivers/video/fb_sys_fops 0x9cf1aec8 fb_sys_read +EXPORT_SYMBOL_GPL drivers/video/sis/sisfb 0x1babe2aa sis_free_new +EXPORT_SYMBOL_GPL drivers/video/sis/sisfb 0xb5cbea1e sis_malloc_new +EXPORT_SYMBOL_GPL drivers/video/vermilion/vmlfb 0x016e6c20 vmlfb_unregister_subsys +EXPORT_SYMBOL_GPL drivers/video/vermilion/vmlfb 0x90c018c6 vmlfb_register_subsys +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x1c062519 register_virtio_driver +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x2ca05ede unregister_virtio_device +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x3954c1f9 virtio_check_driver_offered_feature +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x56b31ada unregister_virtio_driver +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0xb6126878 register_virtio_device +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x03c4687d vring_interrupt +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x16c07e42 vring_del_virtqueue +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x49323c8d vring_new_virtqueue +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x805c7b6e vring_transport_features +EXPORT_SYMBOL_GPL drivers/w1/wire 0x4530aa8d w1_reset_bus +EXPORT_SYMBOL_GPL drivers/w1/wire 0x5bfb4dbc w1_next_pullup +EXPORT_SYMBOL_GPL drivers/w1/wire 0x5c1323fa w1_read_8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0x7c2f2afb w1_calc_crc8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0x891c90f3 w1_write_block +EXPORT_SYMBOL_GPL drivers/w1/wire 0xa36ac307 w1_write_8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0xb68c805f w1_read_block +EXPORT_SYMBOL_GPL drivers/w1/wire 0xbf3c2589 w1_reset_select_slave +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x66ffbe6d dlm_posix_get +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x9321df95 dlm_lock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x99ee8ea8 dlm_posix_unlock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xb3565bee dlm_posix_lock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xcf9f3328 dlm_release_lockspace +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xdc583c08 dlm_unlock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xdf3c14de dlm_new_lockspace +EXPORT_SYMBOL_GPL fs/exportfs/exportfs 0x19b6161a exportfs_encode_fh +EXPORT_SYMBOL_GPL fs/exportfs/exportfs 0xbfe29d04 exportfs_decode_fh +EXPORT_SYMBOL_GPL fs/fat/fat 0x0d5657b4 fat_build_inode +EXPORT_SYMBOL_GPL fs/fat/fat 0x0de9483f fat_time_unix2fat +EXPORT_SYMBOL_GPL fs/fat/fat 0x1279ce74 fat_scan +EXPORT_SYMBOL_GPL fs/fat/fat 0x14b91f7a fat_add_entries +EXPORT_SYMBOL_GPL fs/fat/fat 0x224134d5 fat_fs_panic +EXPORT_SYMBOL_GPL fs/fat/fat 0x34385ce8 fat_remove_entries +EXPORT_SYMBOL_GPL fs/fat/fat 0x44fa3ec8 fat_detach +EXPORT_SYMBOL_GPL fs/fat/fat 0x4501f71d fat_free_clusters +EXPORT_SYMBOL_GPL fs/fat/fat 0x4dd96be1 fat_dir_empty +EXPORT_SYMBOL_GPL fs/fat/fat 0x543f36ac fat_search_long +EXPORT_SYMBOL_GPL fs/fat/fat 0x5f648204 fat_alloc_new_dir +EXPORT_SYMBOL_GPL fs/fat/fat 0x667a103b fat_sync_inode +EXPORT_SYMBOL_GPL fs/fat/fat 0x7d071dd2 fat_get_dotdot_entry +EXPORT_SYMBOL_GPL fs/fat/fat 0x7e4b69c9 fat_attach +EXPORT_SYMBOL_GPL fs/fat/fat 0x8cb201ad fat_fill_super +EXPORT_SYMBOL_GPL fs/fat/fat 0xa45be82e fat_flush_inodes +EXPORT_SYMBOL_GPL fs/fat/fat 0xd51e78e0 fat_getattr +EXPORT_SYMBOL_GPL fs/fat/fat 0xea4c18cb fat_setattr +EXPORT_SYMBOL_GPL fs/gfs2/gfs2 0x9ab8f120 gfs2_register_lockproto +EXPORT_SYMBOL_GPL fs/gfs2/gfs2 0xe7ce347e gfs2_unregister_lockproto +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x17ce645d locks_end_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x1a618932 nlmsvc_unlock_all_by_ip +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x6f162ff4 nlmclnt_done +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x6f959b35 locks_in_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x96877ac4 locks_start_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0xb6becbf8 nlmclnt_init +EXPORT_SYMBOL_GPL fs/lockd/lockd 0xbcd48c41 nlmsvc_unlock_all_by_sb +EXPORT_SYMBOL_GPL fs/lockd/lockd 0xeed7b6d9 nlmclnt_proc +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x1b89c6ee o2hb_fill_node_map +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x1cb231d0 mlog_not_bits +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x1d747ce3 o2hb_check_node_heartbeating +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x1e990261 o2nm_get_node_by_ip +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x293b5cf3 o2nm_node_put +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x36418553 o2net_send_message +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x47aac245 o2hb_setup_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x4900035b o2hb_stop_all_regions +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x512dfd02 o2nm_node_get +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x687f6251 mlog_and_bits +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x73fc7239 o2hb_unregister_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x88a4b0cb o2hb_register_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x977cc762 o2nm_get_node_by_num +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xa82a8645 o2nm_this_node +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xa87bc9e7 o2nm_configured_node_map +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xa9f5379a o2net_send_message_vec +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xae808bac o2net_register_handler +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xbaeb4700 o2hb_check_node_heartbeating_from_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xd60f2c6c o2hb_check_local_node_heartbeating +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xf1a5611d o2net_unregister_handler_list +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x2381abf3 dlm_unregister_domain +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x3bc5be47 dlmunlock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x4b3c79f3 dlmlock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x7a1211f8 dlm_setup_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x93eb072c dlm_register_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xcbc0b1f5 dlm_print_one_lock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xd7ba575e dlm_errmsg +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xd8fa57a6 dlm_unregister_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xdd19f42b dlm_register_domain +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xfb86b96f dlm_errname +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x0562c415 ocfs2_cluster_this_node +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x0e27f909 ocfs2_dlm_lock +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x1ea73a10 ocfs2_stack_glue_unregister +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x21db5b88 ocfs2_cluster_disconnect +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x4a1f6fe9 ocfs2_cluster_connect +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x4d3af7fa ocfs2_cluster_hangup +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x81c85a68 ocfs2_dlm_lock_status +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x91fab465 ocfs2_dlm_lvb +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x963932a3 ocfs2_stack_glue_set_locking_protocol +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xa7d5c1c0 ocfs2_dlm_unlock +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xbbc4ef97 ocfs2_stack_supports_plocks +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xbf7d2c20 ocfs2_plock +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xd066711e ocfs2_dlm_dump_lksb +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xd40c63b1 ocfs2_stack_glue_register +EXPORT_SYMBOL_GPL lib/lzo/lzo_compress 0x56b63670 lzo1x_1_compress +EXPORT_SYMBOL_GPL lib/lzo/lzo_decompress 0xf30fda27 lzo1x_decompress_safe +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0x300d7e57 free_rs +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0x6fbb3bd9 init_rs_non_canonical +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0xabda1e2e decode_rs16 +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0xb050f329 init_rs +EXPORT_SYMBOL_GPL net/802/garp 0x18194b28 garp_register_application +EXPORT_SYMBOL_GPL net/802/garp 0x21782acf garp_request_leave +EXPORT_SYMBOL_GPL net/802/garp 0x28fa95b2 garp_request_join +EXPORT_SYMBOL_GPL net/802/garp 0x41d77153 garp_init_applicant +EXPORT_SYMBOL_GPL net/802/garp 0x788bc214 garp_uninit_applicant +EXPORT_SYMBOL_GPL net/802/garp 0xff8a5c50 garp_unregister_application +EXPORT_SYMBOL_GPL net/802/stp 0x2a7d95ae stp_proto_unregister +EXPORT_SYMBOL_GPL net/802/stp 0xf0eff685 stp_proto_register +EXPORT_SYMBOL_GPL net/ax25/ax25 0x0450ce7b ax25_register_pid +EXPORT_SYMBOL_GPL net/ax25/ax25 0xac93ae05 ax25_bcast +EXPORT_SYMBOL_GPL net/ax25/ax25 0xaeb7451e ax25_defaddr +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x09c5ed3c tfrc_tx_hist_purge +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x0a487ea5 tfrc_calc_x +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x0c0c8b5c tfrc_rx_handle_loss +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x106fe6d3 tfrc_tx_hist_rtt +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x2a3fae38 tfrc_lh_interval_add +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x3c74838d tfrc_rx_hist_sample_rtt +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x69799bbd tfrc_rx_hist_duplicate +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x69ec5731 tfrc_tx_hist_add +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x6c252d29 tfrc_calc_x_reverse_lookup +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x902206f0 tfrc_lh_cleanup +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x92285650 tfrc_rx_hist_alloc +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xaad283c1 tfrc_lh_update_i_mean +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xb2611065 tfrc_rx_hist_add_packet +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xc612a5b6 tfrc_rx_hist_purge +EXPORT_SYMBOL_GPL net/dccp/dccp 0x01922c38 dccp_insert_option +EXPORT_SYMBOL_GPL net/dccp/dccp 0x01c489bc dccp_parse_options +EXPORT_SYMBOL_GPL net/dccp/dccp 0x02a58d1e inet_dccp_listen +EXPORT_SYMBOL_GPL net/dccp/dccp 0x07b1c7c9 dccp_close +EXPORT_SYMBOL_GPL net/dccp/dccp 0x12a2294d dccp_sync_mss +EXPORT_SYMBOL_GPL net/dccp/dccp 0x152406b9 dccp_sendmsg +EXPORT_SYMBOL_GPL net/dccp/dccp 0x196ab2ac dccp_rcv_established +EXPORT_SYMBOL_GPL net/dccp/dccp 0x19db42e2 dccp_child_process +EXPORT_SYMBOL_GPL net/dccp/dccp 0x1b63678a dccp_ioctl +EXPORT_SYMBOL_GPL net/dccp/dccp 0x1d99d49a dccp_timestamp +EXPORT_SYMBOL_GPL net/dccp/dccp 0x2bc54bc5 ccid_register +EXPORT_SYMBOL_GPL net/dccp/dccp 0x2e19d534 dccp_rcv_state_process +EXPORT_SYMBOL_GPL net/dccp/dccp 0x33284350 ccid_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0x36532d5f dccp_getsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x3b3c0b1b dccp_feat_clean +EXPORT_SYMBOL_GPL net/dccp/dccp 0x3d9ffff9 dccp_insert_option_elapsed_time +EXPORT_SYMBOL_GPL net/dccp/dccp 0x3ee92c0d dccp_done +EXPORT_SYMBOL_GPL net/dccp/dccp 0x405072f3 dccp_insert_option_timestamp +EXPORT_SYMBOL_GPL net/dccp/dccp 0x4cad4c9e dccp_recvmsg +EXPORT_SYMBOL_GPL net/dccp/dccp 0x4dfabc56 dccp_sample_rtt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x5182cccc dccp_create_openreq_child +EXPORT_SYMBOL_GPL net/dccp/dccp 0x56ea266a dccp_state_name +EXPORT_SYMBOL_GPL net/dccp/dccp 0x62a82b29 dccp_init_sock +EXPORT_SYMBOL_GPL net/dccp/dccp 0x63998172 dccp_setsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x63c80ab6 dccp_feat_clone +EXPORT_SYMBOL_GPL net/dccp/dccp 0x64fdc610 dccp_feat_change_recv +EXPORT_SYMBOL_GPL net/dccp/dccp 0x6afe0101 dccp_make_response +EXPORT_SYMBOL_GPL net/dccp/dccp 0x6dfa3c85 dccp_reqsk_send_ack +EXPORT_SYMBOL_GPL net/dccp/dccp 0x6eb4a9ef ccid_hc_tx_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0x774c788a dccp_check_req +EXPORT_SYMBOL_GPL net/dccp/dccp 0x7e5eec6a ccid_hc_tx_delete +EXPORT_SYMBOL_GPL net/dccp/dccp 0x7f7d59af dccp_disconnect +EXPORT_SYMBOL_GPL net/dccp/dccp 0x828d09c0 dccp_death_row +EXPORT_SYMBOL_GPL net/dccp/dccp 0x86be7924 dccp_packet_name +EXPORT_SYMBOL_GPL net/dccp/dccp 0x871d3a49 dccp_hashinfo +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8b7d8caf dccp_statistics +EXPORT_SYMBOL_GPL net/dccp/dccp 0x925318d1 ccid_hc_rx_delete +EXPORT_SYMBOL_GPL net/dccp/dccp 0x95653b52 dccp_set_state +EXPORT_SYMBOL_GPL net/dccp/dccp 0x9d6a3846 dccp_orphan_count +EXPORT_SYMBOL_GPL net/dccp/dccp 0xa0e0e118 dccp_send_ack +EXPORT_SYMBOL_GPL net/dccp/dccp 0xa533c50f dccp_shutdown +EXPORT_SYMBOL_GPL net/dccp/dccp 0xa7894934 dccp_poll +EXPORT_SYMBOL_GPL net/dccp/dccp 0xba437135 dccp_destroy_sock +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbe4cf010 dccp_feat_init +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbf6b58ba dccp_feat_change +EXPORT_SYMBOL_GPL net/dccp/dccp 0xcc84fa55 dccp_send_sync +EXPORT_SYMBOL_GPL net/dccp/dccp 0xceed6ef7 dccp_connect +EXPORT_SYMBOL_GPL net/dccp/dccp 0xd5c297a8 ccid_unregister +EXPORT_SYMBOL_GPL net/dccp/dccp 0xd70deb73 dccp_ctl_make_reset +EXPORT_SYMBOL_GPL net/dccp/dccp 0xec1a754f dccp_feat_confirm_recv +EXPORT_SYMBOL_GPL net/dccp/dccp 0xfabb0a54 dccp_reqsk_init +EXPORT_SYMBOL_GPL net/dccp/dccp 0xfb864707 ccid_hc_rx_new +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x0b370a05 dccp_v4_send_check +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x3cd17543 dccp_v4_do_rcv +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x49fe978a dccp_invalid_packet +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x64ddcc64 dccp_v4_conn_request +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x6dab3f10 dccp_v4_request_recv_sock +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0xb99bb4b3 dccp_v4_connect +EXPORT_SYMBOL_GPL net/ieee80211/ieee80211 0x8f53b70f ieee80211_rx_any +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_conntrack_ipv4 0x649df6a2 nf_nat_seq_adjust_hook +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_conntrack_ipv4 0x6d40a921 need_ipv4_conntrack +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_defrag_ipv4 0x6b6c3d10 nf_defrag_ipv4_enable +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x07ae60b6 nf_nat_proto_in_range +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x270188c9 nf_nat_icmp_reply_translation +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x3b3cf902 nf_nat_packet +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x59c3072f nf_nat_proto_unique_tuple +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x7358760f nf_nat_proto_find_get +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x94a08134 nf_nat_proto_nlattr_to_range +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x99ddbb76 nf_nat_proto_range_to_nlattr +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0xcd08a143 nf_nat_proto_put +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat_proto_gre 0x636b12c8 nf_nat_need_gre +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x4a5cf076 tcp_vegas_cwnd_event +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x768149a6 tcp_vegas_pkts_acked +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0xc5dbde7f tcp_vegas_init +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0xd02866d4 tcp_vegas_state +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0xf3de151e tcp_vegas_get_info +EXPORT_SYMBOL_GPL net/mac80211/mac80211 0x01cfd840 ieee80211_iterate_active_interfaces_atomic +EXPORT_SYMBOL_GPL net/mac80211/mac80211 0xa89330a1 ieee80211_iterate_active_interfaces +EXPORT_SYMBOL_GPL net/netfilter/ipvs/ip_vs 0xe6476b4a net_vs_ctl_path +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x041013fd nf_conntrack_lock +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x045072cd nf_ct_port_nla_policy +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x1283d711 nf_ct_expect_unregister_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x15c10b0b nf_conntrack_unregister_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x1e653fce nf_ct_l3protos +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x2532145e __nf_ct_kill_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x28c2d298 nf_ct_expect_alloc +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x337d773f nf_ct_helper_ext_add +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x357d4119 nf_conntrack_l4proto_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x38630158 nf_conntrack_tuple_taken +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x38c9440b nf_ct_extend_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3f5b1415 nf_ct_port_nlattr_to_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x40387ccf __nf_ct_event_cache_init +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x421c3f65 nf_conntrack_l3proto_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x484c7cbc nf_conntrack_helper_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x4b0d49a6 nf_conntrack_tcp_update +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x4b289bf6 nf_conntrack_l4proto_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x4b5fe820 nf_ct_l4proto_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x4eb68c9f nf_ct_unlink_expect +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x52199866 nf_ct_invert_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x526be2e8 nf_conntrack_alloc +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x544f43a8 nf_conntrack_l4proto_udp4 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x5b481830 nf_ct_iterate_cleanup +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x61d0bca8 nf_ct_get_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x65fb25e2 nf_ct_expect_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x6679212a nf_conntrack_l4proto_udp6 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x6e224a7a need_conntrack +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x6e5fd84d nf_ct_get_tuplepr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x72836f4a nf_conntrack_free +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x77aadb54 nf_conntrack_alter_reply +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x78f9b710 nf_ct_l3proto_try_module_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x79ca2e53 nf_ct_expect_chain +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x79d715a7 nf_conntrack_in +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x817c5544 seq_print_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x84e30ce7 nf_conntrack_l3proto_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x88fd453d __nf_conntrack_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x8ffe7e89 nf_conntrack_htable_size +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x90ff6c9f nf_ct_invert_tuplepr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x9528aa9e __nf_conntrack_helper_find_byname +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x9c7b8ac7 __nf_ct_helper_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x9e7a6c33 __nf_conntrack_confirm +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x9f3d2c44 __nf_ct_expect_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa16a5c30 nf_conntrack_helper_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa6f62ec0 nf_conntrack_set_hashsize +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa9e1cd08 nf_ct_expect_init +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xaa56b35f __nf_ct_l4proto_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xaf15c24a nf_ct_unexpect_related +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xaf57e66f nf_ct_extend_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb0564abe nf_ct_port_tuple_to_nlattr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb2826a16 nf_ct_expect_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb602c57e nf_ct_l3proto_module_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbc887e16 nf_ct_expect_register_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc044befe nf_ct_free_hashtable +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc18ac88d nf_ct_expect_hsize +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc272c727 nf_conntrack_l4proto_tcp6 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc35a7a3e nf_conntrack_chain +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc7b64d79 nf_conntrack_hash_insert +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc99f8122 nf_conntrack_l3proto_generic +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xcbf7fd2a nf_conntrack_register_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xce753afd nf_ct_expect_related +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd0e22ed0 nf_ct_l4proto_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd50a96a2 nf_ct_alloc_hashtable +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd72ebf28 nf_conntrack_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd9efb053 nf_ct_deliver_cached_events +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xebf4cd41 nf_conntrack_flush +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xee11b0fb print_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xef101ab5 nf_ct_l3proto_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf044a5a5 nf_conntrack_l4proto_tcp4 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf628d40c __nf_ct_refresh_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf9ae81a1 nf_conntrack_max +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfa169dac nf_conntrack_untracked +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfac18b4f nf_ct_l3proto_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfb839673 nf_ct_remove_expectations +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xff9e9fc3 nfnetlink_parse_nat_setup_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_amanda 0x78ade53e nf_nat_amanda_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_ftp 0xed610db4 nf_nat_ftp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x1b0a7472 nat_callforwarding_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x1c767b5b set_h225_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x264c0cf3 get_h225_addr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x30d4ed83 set_sig_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x45b0de89 set_ras_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x70f52b97 set_h245_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x773e9edb nat_rtp_rtcp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xabec4eb5 nat_t120_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xb55b725f nat_q931_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xeca75efe nat_h245_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_irc 0x83ddec96 nf_nat_irc_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x28cab8c5 nf_nat_pptp_hook_inbound +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x67f3cd79 nf_nat_pptp_hook_outbound +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x92837ba2 nf_nat_pptp_hook_exp_gre +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0xee8d866c nf_nat_pptp_hook_expectfn +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_proto_gre 0x05f8e58c nf_ct_gre_keymap_destroy +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_proto_gre 0x6f59d77c nf_ct_gre_keymap_add +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x13169b79 ct_sip_parse_request +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x1fd5e464 nf_nat_sdp_media_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x3c2058a6 ct_sip_parse_numerical_param +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x5333cb69 ct_sip_parse_header_uri +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x5343611e ct_sip_get_sdp_header +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x56ad8f6e ct_sip_parse_address_param +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x5f66d1af nf_nat_sip_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xbaa86f48 nf_nat_sdp_port_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xc1d5e08e nf_nat_sdp_session_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xeaef555b nf_nat_sdp_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xf8b610ea ct_sip_get_header +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xfc9d1e72 nf_nat_sip_expect_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_tftp 0xf017f3fa nf_nat_tftp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_tproxy_core 0x631d831f nf_tproxy_assign_sock +EXPORT_SYMBOL_GPL net/netfilter/nf_tproxy_core 0xc2ffc0c6 nf_tproxy_get_sock_v4 +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x1f58e71b nfnl_lock +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x3895cd7a nfnl_unlock +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x45e55b7d nfnetlink_send +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xc62fe626 nfnetlink_subsys_unregister +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xe2eb9105 nfnetlink_subsys_register +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xeca95329 nfnetlink_has_listeners +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xff6275e6 nfnetlink_unicast +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x0ea81550 xt_table_unlock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x13dbb589 xt_request_find_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x40728a63 xt_find_revision +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x5cb227c9 xt_register_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x60b932ae xt_proto_fini +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x778eb3be xt_find_table_lock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x9e948f0d xt_unregister_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xa64ea23c xt_check_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xb7da82e8 xt_proto_init +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xbf586984 xt_check_match +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xdf753e3c xt_replace_table +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0xc177bee0 xt_rateest_put +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0xdb8418cc xt_rateest_lookup +EXPORT_SYMBOL_GPL net/rxrpc/af-rxrpc 0x616f71d4 rxrpc_register_security +EXPORT_SYMBOL_GPL net/rxrpc/af-rxrpc 0xd7f02673 rxrpc_unregister_security +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x07802b41 __rpc_wait_for_completion_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x0c583b1d xdr_partial_copy_from_skb +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x0f9c1bdf rpc_bind_new_program +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x129779eb rpc_call_null +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1ca0257f svc_xprt_put +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2711b46a svc_xprt_names +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x286ec67b rpc_killall_tasks +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2a3401c7 rpc_run_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2aa17774 rpc_free_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x31a89d59 rpc_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x37071e59 svc_create_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3a777e6f xprt_unregister_transport +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3c209048 xprt_register_transport +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3db15202 xprt_disconnect_done +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3eebb665 svc_unreg_xprt_class +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x406ea47f xprt_set_retrans_timeout_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x49085915 xprt_set_retrans_timeout_def +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x499f7491 rpc_proc_register +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x4a6974bd rpc_lookup_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x4e8c80e5 rpc_peeraddr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5124443e xdr_skb_read_bits +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x53445f68 nlm_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x550547a3 rpc_destroy_wait_queue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x56570bc1 rpc_shutdown_client +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5b855b14 rpc_force_rebind +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5bd26000 rpc_proc_unregister +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x60fb7867 xprt_complete_rqst +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x654d6895 rpcb_getport_async +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x658e89a5 rpc_restart_call +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x680fe654 svc_xprt_enqueue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x68ddecf6 xprt_reserve_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x693bdba8 rpc_create +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6994a965 rpc_exit_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6c5304c5 rpcb_getport_sync +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6e6e4b6f rpc_sleep_on +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x70da2282 rpcauth_create +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x759282c4 svc_xprt_copy_addrs +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x781d4540 svc_xprt_init +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x790010df svc_print_addr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7de49b82 rpcauth_lookup_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7de53067 rpc_init_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7edd2971 put_rpccred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8359b707 xprt_write_space +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8493b9cb xprt_wait_for_buffer_space +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8bb067e0 xprt_reserve_xprt_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8ca28ced rpc_clone_client +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8d2c37e9 rpc_call_start +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8e7db5b6 xprt_update_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x9001bd85 rpc_delay +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x97fcaded rpcauth_register +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x9ac05a40 rpc_malloc +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x9c61192b xprt_lookup_rqst +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x9da1281b rpcauth_destroy_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xa9238c65 svc_max_payload +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xab2dbeeb rpc_lookup_machine_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xad0ff2f1 rpc_setbufsize +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xad5db2bb svc_reg_xprt_class +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xaf5bf6ef nfs_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb1be1bee svc_xprt_received +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb387b246 rpc_wake_up_status +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb91dd0eb rpcauth_init_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb9fc7a9e rpc_wake_up_next +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbf9d1b96 nfsd_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbfa9d59a csum_partial_copy_to_xdr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc02f3df3 rpc_wake_up_queued_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc12435e3 rpc_calc_rto +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc2b134ed svc_addsock +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc3cbd1ed xprt_release_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc7a69acb rpc_alloc_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc7b798c1 xprt_adjust_cwnd +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xce85a4d4 rpc_peeraddr2str +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd3415043 rpcauth_generic_bind_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd5b073e5 xprt_release_xprt_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd6f34959 rpc_max_payload +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd82c728e rpc_init_wait_queue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd9db8434 rpcauth_init_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xdc52e14d xprt_wake_pending_tasks +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xdf2eb11e svc_find_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe3e276e9 rpcauth_unregister +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe5afa65f rpc_call_sync +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe86a906b xprt_release_rqst_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xedd1ba52 rpc_wake_up +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xee64fdf6 svc_close_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xeeacab69 rpc_update_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xef0eba2f rpc_call_async +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xf845bb51 rpc_put_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xf9d1164c rpc_free +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xfccbee8f rpc_print_iostats +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0x2a4c2fdf ipcomp_init_state +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0xab52d3f7 ipcomp_input +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0xc1c24d4f ipcomp_output +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0xd42d4ec7 ipcomp_destroy +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ad73311 0x8a5a8cc0 ad73311_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ad73311 0xb8446d43 soc_codec_dev_ad73311 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ak4535 0x656d779f ak4535_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ak4535 0x6be34e1e soc_codec_dev_ak4535 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-cs4270 0x7248353c soc_codec_device_cs4270 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-cs4270 0xa73fb3fb cs4270_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ssm2602 0x3cfa5b57 ssm2602_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ssm2602 0xa9e732b2 soc_codec_dev_ssm2602 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic23 0x148cc33a soc_codec_dev_tlv320aic23 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic23 0x7f250ef0 tlv320aic23_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic26 0x0301f5a1 aic26_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic26 0x0d096080 aic26_soc_codec_dev +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0x3ad6cebe aic3x_get_gpio +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0x845bee7c aic3x_headset_detected +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0x90249509 aic3x_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0xd1b2f0ba soc_codec_dev_aic3x +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0xf53f4062 aic3x_set_gpio +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-uda1380 0xdf7b8bd2 uda1380_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-uda1380 0xf668e0d6 soc_codec_dev_uda1380 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8510 0x02b7c9dd soc_codec_dev_wm8510 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8510 0x0f567ade wm8510_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8580 0x0d66f252 soc_codec_dev_wm8580 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8580 0xa980e864 wm8580_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8731 0x11b0bf2f wm8731_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8731 0xb221e479 soc_codec_dev_wm8731 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8750 0xafb7a98a soc_codec_dev_wm8750 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8750 0xb93c59b0 wm8750_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8753 0x687bed31 wm8753_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8753 0x849afa49 soc_codec_dev_wm8753 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8900 0x49a31c52 soc_codec_dev_wm8900 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8900 0xfe8e6425 wm8900_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8903 0x628e4f91 soc_codec_dev_wm8903 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8903 0x781a168b wm8903_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8971 0x55f73b96 soc_codec_dev_wm8971 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8971 0xf075890e wm8971_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8990 0x467227dd soc_codec_dev_wm8990 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8990 0x6b1621f6 wm8990_dai +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x0e44d7d0 snd_soc_dai_set_tristate +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x211d8d45 snd_soc_test_bits +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x28de5eb3 snd_soc_dapm_sync +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x298df1d2 snd_soc_dapm_new_widgets +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x2bc7ccf7 snd_soc_register_card +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x2c57813e snd_soc_dapm_get_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x3049586b snd_soc_get_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x36c47caf snd_soc_dapm_new_control +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x36caa38c snd_soc_dai_digital_mute +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x37f25cf7 snd_soc_free_pcms +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x39631e0c snd_soc_dapm_put_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x401f230b snd_soc_put_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x463df764 snd_soc_dapm_connect_input +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x4fccbffc snd_soc_update_bits +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x57085918 snd_soc_dapm_add_routes +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x6d51dbc1 snd_soc_info_volsw_ext +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x72402545 snd_soc_info_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x75feb1dc snd_soc_dapm_disable_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x771e4e88 snd_soc_dapm_stream_event +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x787e471d snd_soc_info_enum_ext +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x7f0b8236 snd_soc_dai_set_fmt +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x812a212f snd_soc_dapm_nc_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x863c72ec snd_soc_dapm_enable_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x87c10467 snd_soc_dai_set_tdm_slot +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x8b299fbc snd_soc_dai_set_sysclk +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x99579cdc snd_soc_dapm_new_controls +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xa478c7af snd_soc_new_pcms +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xaae67459 snd_soc_dapm_free +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xab0a27a6 snd_soc_put_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xabcd5565 snd_soc_dapm_put_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xb09d7080 snd_soc_get_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xb794bc75 snd_soc_cnew +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xc0cb0be0 snd_soc_put_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xc30f05d0 snd_soc_info_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xce0547cc snd_soc_new_ac97_codec +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xce4136e4 snd_soc_set_runtime_hwparams +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xd44a3fac snd_soc_get_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xd48d4d6f snd_soc_dapm_get_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xd49b5c2b snd_soc_dapm_get_pin_status +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xda3d2742 snd_soc_info_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xdcfd553e snd_soc_free_ac97_codec +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xe8c70735 snd_soc_put_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xebc6d285 snd_soc_info_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xedaf332c snd_soc_dai_set_clkdiv +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xfa66e971 snd_soc_dai_set_pll +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xfdf39807 snd_soc_get_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xfefcec47 dapm_reg_event +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x1584fdb9 tlsf_destroy_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x42a50f11 tlsf_malloc +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x66da3d8f tlsf_create_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xe6acc368 tlsf_free +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xee6c65c9 tlsf_get_used_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xeec8caeb tlsf_get_total_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xf9805f1b tlsf_calloc +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x02500586 thinkpad_ec_unlock +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x0dc7484e thinkpad_ec_try_read_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x2552d213 thinkpad_ec_lock +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x3dbfef12 thinkpad_ec_read_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x8dbbd831 thinkpad_ec_invalidate +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0xa3042743 thinkpad_ec_prefetch_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0xfb5aa917 thinkpad_ec_try_lock +EXPORT_SYMBOL_GPL vmlinux 0x00087a2a rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x0045b789 dm_rh_get_region_size +EXPORT_SYMBOL_GPL vmlinux 0x00566d8f inotify_get_cookie +EXPORT_SYMBOL_GPL vmlinux 0x0067df75 ata_tf_from_fis +EXPORT_SYMBOL_GPL vmlinux 0x006d7cad srcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x00b2c692 xenbus_grant_ring +EXPORT_SYMBOL_GPL vmlinux 0x00eb4a85 device_attach +EXPORT_SYMBOL_GPL vmlinux 0x00ebcb5d ata_id_string +EXPORT_SYMBOL_GPL vmlinux 0x00f1d4eb bus_rescan_devices +EXPORT_SYMBOL_GPL vmlinux 0x010ee8e0 blk_queue_rq_timed_out +EXPORT_SYMBOL_GPL vmlinux 0x0110b3d1 register_hotplug_dock_device +EXPORT_SYMBOL_GPL vmlinux 0x012a431f ata_sff_tf_load +EXPORT_SYMBOL_GPL vmlinux 0x01848a8e local_apic_timer_c2_ok +EXPORT_SYMBOL_GPL vmlinux 0x01a4ea6d unregister_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x01e1a8de kgdb_breakpoint +EXPORT_SYMBOL_GPL vmlinux 0x01f80c10 devm_kzalloc +EXPORT_SYMBOL_GPL vmlinux 0x021eb672 devres_get +EXPORT_SYMBOL_GPL vmlinux 0x0220fb8b device_create_vargs +EXPORT_SYMBOL_GPL vmlinux 0x02482556 crypto_unregister_template +EXPORT_SYMBOL_GPL vmlinux 0x0274fee5 usb_reset_configuration +EXPORT_SYMBOL_GPL vmlinux 0x0279a997 sata_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x02ccea56 lock_policy_rwsem_write +EXPORT_SYMBOL_GPL vmlinux 0x02fb59e7 __scsi_get_command +EXPORT_SYMBOL_GPL vmlinux 0x02ffd0a5 i2c_add_numbered_adapter +EXPORT_SYMBOL_GPL vmlinux 0x0300fad5 bus_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x0343bdf1 __i2c_board_list +EXPORT_SYMBOL_GPL vmlinux 0x03530fb4 usb_get_current_frame_number +EXPORT_SYMBOL_GPL vmlinux 0x03c768c7 ata_port_abort +EXPORT_SYMBOL_GPL vmlinux 0x03e358fe led_trigger_set_default +EXPORT_SYMBOL_GPL vmlinux 0x03e3686c ata_timing_cycle2mode +EXPORT_SYMBOL_GPL vmlinux 0x0406ef39 dev_attr_sw_activity +EXPORT_SYMBOL_GPL vmlinux 0x0410156e crypto_register_alg +EXPORT_SYMBOL_GPL vmlinux 0x04136bca klist_init +EXPORT_SYMBOL_GPL vmlinux 0x04486e88 rcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x04566c7f init_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x0462ad78 securityfs_remove +EXPORT_SYMBOL_GPL vmlinux 0x04928c40 sdio_readb +EXPORT_SYMBOL_GPL vmlinux 0x04aaaae3 kern_mount_data +EXPORT_SYMBOL_GPL vmlinux 0x04c3f2c1 gnttab_empty_grant_references +EXPORT_SYMBOL_GPL vmlinux 0x04c72d5d regulator_disable +EXPORT_SYMBOL_GPL vmlinux 0x05159542 usb_poison_urb +EXPORT_SYMBOL_GPL vmlinux 0x0531dcb8 ata_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0x054e550b kernel_halt +EXPORT_SYMBOL_GPL vmlinux 0x05997e13 bd_claim_by_disk +EXPORT_SYMBOL_GPL vmlinux 0x059b75f3 usb_driver_set_configuration +EXPORT_SYMBOL_GPL vmlinux 0x05d2e820 usb_lock_device_for_reset +EXPORT_SYMBOL_GPL vmlinux 0x05d497c0 led_trigger_store +EXPORT_SYMBOL_GPL vmlinux 0x060d1064 set_memory_ro +EXPORT_SYMBOL_GPL vmlinux 0x063d70ab put_device +EXPORT_SYMBOL_GPL vmlinux 0x064db9a5 mark_mounts_for_expiry +EXPORT_SYMBOL_GPL vmlinux 0x0684e6a7 led_trigger_show +EXPORT_SYMBOL_GPL vmlinux 0x068b37f4 driver_attach +EXPORT_SYMBOL_GPL vmlinux 0x06b26105 uhci_check_and_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0x06c9b43e ata_host_register +EXPORT_SYMBOL_GPL vmlinux 0x06d222f8 device_resume +EXPORT_SYMBOL_GPL vmlinux 0x06fcc889 hvc_poll +EXPORT_SYMBOL_GPL vmlinux 0x074f9143 crypto_nivaead_type +EXPORT_SYMBOL_GPL vmlinux 0x07a98296 scsi_target_unblock +EXPORT_SYMBOL_GPL vmlinux 0x07b52e38 rtnl_unregister +EXPORT_SYMBOL_GPL vmlinux 0x07da59d1 sdio_writew +EXPORT_SYMBOL_GPL vmlinux 0x07ff4aea xenbus_scanf +EXPORT_SYMBOL_GPL vmlinux 0x081bdab8 tty_put_char +EXPORT_SYMBOL_GPL vmlinux 0x08657395 rdev_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x086db9a3 rtc_read_time +EXPORT_SYMBOL_GPL vmlinux 0x087aae65 usb_match_one_id +EXPORT_SYMBOL_GPL vmlinux 0x089b3e5b bus_register +EXPORT_SYMBOL_GPL vmlinux 0x08a3e5d1 net_ipv6_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0x08f97169 usb_buffer_free +EXPORT_SYMBOL_GPL vmlinux 0x091eb9b4 round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0x096b19f9 usb_hcd_link_urb_to_ep +EXPORT_SYMBOL_GPL vmlinux 0x09965db9 ata_pci_sff_activate_host +EXPORT_SYMBOL_GPL vmlinux 0x09a5a2a2 aead_geniv_alloc +EXPORT_SYMBOL_GPL vmlinux 0x09bd30e5 hrtimer_init +EXPORT_SYMBOL_GPL vmlinux 0x0a1faf8d crypto_init_spawn +EXPORT_SYMBOL_GPL vmlinux 0x0a2519b1 fsstack_copy_attr_all +EXPORT_SYMBOL_GPL vmlinux 0x0a611cf7 ata_sff_irq_on +EXPORT_SYMBOL_GPL vmlinux 0x0ad5c33f acpi_smbus_register_callback +EXPORT_SYMBOL_GPL vmlinux 0x0ad7de87 usb_deregister_dev +EXPORT_SYMBOL_GPL vmlinux 0x0b3be6b5 da903x_read +EXPORT_SYMBOL_GPL vmlinux 0x0b53a167 device_move +EXPORT_SYMBOL_GPL vmlinux 0x0b7b008c regulator_set_optimum_mode +EXPORT_SYMBOL_GPL vmlinux 0x0b9d29cc devres_close_group +EXPORT_SYMBOL_GPL vmlinux 0x0ba9b723 xfrm_audit_state_replay_overflow +EXPORT_SYMBOL_GPL vmlinux 0x0c17e274 xfrm_aalg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x0c236dba sysdev_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x0c4717f7 srcu_init_notifier_head +EXPORT_SYMBOL_GPL vmlinux 0x0d4d085a usb_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0x0d814646 klist_add_head +EXPORT_SYMBOL_GPL vmlinux 0x0da952f1 ipv6_opt_accepted +EXPORT_SYMBOL_GPL vmlinux 0x0e1ab075 blk_update_request +EXPORT_SYMBOL_GPL vmlinux 0x0e2a304a rtc_read_alarm +EXPORT_SYMBOL_GPL vmlinux 0x0e382e5c dm_unregister_path_selector +EXPORT_SYMBOL_GPL vmlinux 0x0e9b4272 usb_anchor_urb +EXPORT_SYMBOL_GPL vmlinux 0x0eafc157 tcp_reno_min_cwnd +EXPORT_SYMBOL_GPL vmlinux 0x0ec210b8 xen_start_info +EXPORT_SYMBOL_GPL vmlinux 0x0ee473df platform_device_register +EXPORT_SYMBOL_GPL vmlinux 0x0f0a38a6 dma_get_required_mask +EXPORT_SYMBOL_GPL vmlinux 0x0f1a5477 platform_driver_probe +EXPORT_SYMBOL_GPL vmlinux 0x0f2de14a blkcipher_walk_done +EXPORT_SYMBOL_GPL vmlinux 0x0f2f925e put_pid +EXPORT_SYMBOL_GPL vmlinux 0x0f42ebc3 crypto_enqueue_request +EXPORT_SYMBOL_GPL vmlinux 0x0f7ac1a1 get_user_pages_fast +EXPORT_SYMBOL_GPL vmlinux 0x0fe2d570 xenbus_directory +EXPORT_SYMBOL_GPL vmlinux 0x10036fe8 usb_get_hcd +EXPORT_SYMBOL_GPL vmlinux 0x100c13c6 usb_kill_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x100c48a2 unregister_dock_notifier +EXPORT_SYMBOL_GPL vmlinux 0x1045b9ed sdio_readsb +EXPORT_SYMBOL_GPL vmlinux 0x105f3d0a pci_bus_add_device +EXPORT_SYMBOL_GPL vmlinux 0x10aea57b set_cpus_allowed_ptr +EXPORT_SYMBOL_GPL vmlinux 0x10b4affb skb_to_sgvec +EXPORT_SYMBOL_GPL vmlinux 0x1138c751 elv_register +EXPORT_SYMBOL_GPL vmlinux 0x117d6c8b klist_add_after +EXPORT_SYMBOL_GPL vmlinux 0x11c490ea unregister_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0x11df97f5 pci_set_pcie_reset_state +EXPORT_SYMBOL_GPL vmlinux 0x11eaf951 sdio_disable_func +EXPORT_SYMBOL_GPL vmlinux 0x11f447ce __gpio_to_irq +EXPORT_SYMBOL_GPL vmlinux 0x1207c27c pci_disable_pcie_error_reporting +EXPORT_SYMBOL_GPL vmlinux 0x12150c94 class_interface_unregister +EXPORT_SYMBOL_GPL vmlinux 0x124f2056 crypto_get_attr_type +EXPORT_SYMBOL_GPL vmlinux 0x1251d30f call_rcu +EXPORT_SYMBOL_GPL vmlinux 0x128d63e6 ata_sff_hsm_move +EXPORT_SYMBOL_GPL vmlinux 0x12ba6094 xenbus_map_ring +EXPORT_SYMBOL_GPL vmlinux 0x131940ca usb_serial_port_softint +EXPORT_SYMBOL_GPL vmlinux 0x1325d4f0 vfs_cancel_lock +EXPORT_SYMBOL_GPL vmlinux 0x13605cb1 spi_alloc_master +EXPORT_SYMBOL_GPL vmlinux 0x138caf20 flush_workqueue +EXPORT_SYMBOL_GPL vmlinux 0x13b2a946 register_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x13c0cfdc inverse_translate +EXPORT_SYMBOL_GPL vmlinux 0x13f2b874 devres_find +EXPORT_SYMBOL_GPL vmlinux 0x14260608 crypto_rng_type +EXPORT_SYMBOL_GPL vmlinux 0x1457eab6 sysdev_register +EXPORT_SYMBOL_GPL vmlinux 0x145eebd0 device_power_up +EXPORT_SYMBOL_GPL vmlinux 0x149db923 selinux_string_to_sid +EXPORT_SYMBOL_GPL vmlinux 0x14cb49fd usb_clear_halt +EXPORT_SYMBOL_GPL vmlinux 0x152a5e3e rtc_device_register +EXPORT_SYMBOL_GPL vmlinux 0x15568631 lookup_address +EXPORT_SYMBOL_GPL vmlinux 0x1577733a device_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x158c2ad0 acpi_smbus_unregister_callback +EXPORT_SYMBOL_GPL vmlinux 0x1598dc9d unregister_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x15b0606e e820_any_mapped +EXPORT_SYMBOL_GPL vmlinux 0x15cb37fa bus_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x15ee5e6b usb_put_intf +EXPORT_SYMBOL_GPL vmlinux 0x16010964 k_handler +EXPORT_SYMBOL_GPL vmlinux 0x16836e04 speedstep_detect_processor +EXPORT_SYMBOL_GPL vmlinux 0x169c8161 usb_string +EXPORT_SYMBOL_GPL vmlinux 0x16c54ceb exit_fs +EXPORT_SYMBOL_GPL vmlinux 0x16f372aa tcp_reno_ssthresh +EXPORT_SYMBOL_GPL vmlinux 0x16f76869 probe_kernel_read +EXPORT_SYMBOL_GPL vmlinux 0x172e72d4 vdso_enabled +EXPORT_SYMBOL_GPL vmlinux 0x174e20f1 sysdev_driver_register +EXPORT_SYMBOL_GPL vmlinux 0x17589cf0 scsi_mode_select +EXPORT_SYMBOL_GPL vmlinux 0x17731c84 put_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0x1780d7ea sdio_readw +EXPORT_SYMBOL_GPL vmlinux 0x17a463e6 hidinput_connect +EXPORT_SYMBOL_GPL vmlinux 0x17babe37 screen_glyph +EXPORT_SYMBOL_GPL vmlinux 0x18085c5f sdio_memcpy_toio +EXPORT_SYMBOL_GPL vmlinux 0x1865869e sysfs_create_link +EXPORT_SYMBOL_GPL vmlinux 0x18674aa5 anon_transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x1878f62b edac_err_assert +EXPORT_SYMBOL_GPL vmlinux 0x188912aa ata_host_start +EXPORT_SYMBOL_GPL vmlinux 0x189f8039 pid_vnr +EXPORT_SYMBOL_GPL vmlinux 0x18b4874a usb_control_msg +EXPORT_SYMBOL_GPL vmlinux 0x18b9f41e usb_serial_register +EXPORT_SYMBOL_GPL vmlinux 0x18d53420 kgdb_register_io_module +EXPORT_SYMBOL_GPL vmlinux 0x18f20817 inet_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0x18f83fab gnttab_grant_foreign_access_ref +EXPORT_SYMBOL_GPL vmlinux 0x193517af hid_add_device +EXPORT_SYMBOL_GPL vmlinux 0x19659367 tty_find_polling_driver +EXPORT_SYMBOL_GPL vmlinux 0x199231be platform_get_resource +EXPORT_SYMBOL_GPL vmlinux 0x19a304ba usb_disabled +EXPORT_SYMBOL_GPL vmlinux 0x1a2da82c ata_pci_device_do_resume +EXPORT_SYMBOL_GPL vmlinux 0x1a43c332 unregister_jprobe +EXPORT_SYMBOL_GPL vmlinux 0x1a44bda3 ata_pci_sff_prepare_host +EXPORT_SYMBOL_GPL vmlinux 0x1a938737 atomic_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x1acda5b2 atomic_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x1ad3b491 acpi_root_bridge +EXPORT_SYMBOL_GPL vmlinux 0x1af09a54 blk_queue_rq_timeout +EXPORT_SYMBOL_GPL vmlinux 0x1af929f2 crypto_grab_skcipher +EXPORT_SYMBOL_GPL vmlinux 0x1b281f9c sdio_writesb +EXPORT_SYMBOL_GPL vmlinux 0x1b4437a2 blkcipher_walk_virt +EXPORT_SYMBOL_GPL vmlinux 0x1b801545 sdio_enable_func +EXPORT_SYMBOL_GPL vmlinux 0x1b9aca3f jprobe_return +EXPORT_SYMBOL_GPL vmlinux 0x1bcc3cea hidraw_connect +EXPORT_SYMBOL_GPL vmlinux 0x1bed0fb3 sata_async_notification +EXPORT_SYMBOL_GPL vmlinux 0x1c16e474 driver_find +EXPORT_SYMBOL_GPL vmlinux 0x1c87a811 __round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x1cc3fcfb platform_driver_register +EXPORT_SYMBOL_GPL vmlinux 0x1cd416ef sata_link_hardreset +EXPORT_SYMBOL_GPL vmlinux 0x1d023170 schedule_hrtimeout +EXPORT_SYMBOL_GPL vmlinux 0x1dd70100 dmi_walk +EXPORT_SYMBOL_GPL vmlinux 0x1deb31f0 xenbus_alloc_evtchn +EXPORT_SYMBOL_GPL vmlinux 0x1e0e669e usb_unpoison_urb +EXPORT_SYMBOL_GPL vmlinux 0x1e7bbcb3 kernel_restart +EXPORT_SYMBOL_GPL vmlinux 0x1eb9516e round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x1f232cd1 kmap_atomic_pfn +EXPORT_SYMBOL_GPL vmlinux 0x1f8ec1b3 acpi_get_pci_rootbridge_handle +EXPORT_SYMBOL_GPL vmlinux 0x1f9a0fbf hpet_unregister_irq_handler +EXPORT_SYMBOL_GPL vmlinux 0x1fb71217 hidinput_find_field +EXPORT_SYMBOL_GPL vmlinux 0x1fb74477 inet_csk_listen_stop +EXPORT_SYMBOL_GPL vmlinux 0x1fcece42 inet_twdr_twcal_tick +EXPORT_SYMBOL_GPL vmlinux 0x1fe5c236 input_ff_upload +EXPORT_SYMBOL_GPL vmlinux 0x1fec9366 crypto_larval_alloc +EXPORT_SYMBOL_GPL vmlinux 0x1ffa0d44 power_supply_register +EXPORT_SYMBOL_GPL vmlinux 0x20577ea2 xfrm_ealg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x20b82470 hpet_register_irq_handler +EXPORT_SYMBOL_GPL vmlinux 0x20bc3470 orderly_poweroff +EXPORT_SYMBOL_GPL vmlinux 0x20cd788f __ftrace_printk +EXPORT_SYMBOL_GPL vmlinux 0x20dc8f9b ip6_local_out +EXPORT_SYMBOL_GPL vmlinux 0x213c1513 klist_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x217854ab dev_attr_em_message +EXPORT_SYMBOL_GPL vmlinux 0x21e13994 usb_free_urb +EXPORT_SYMBOL_GPL vmlinux 0x222475a3 proc_net_fops_create +EXPORT_SYMBOL_GPL vmlinux 0x22293a64 hvc_instantiate +EXPORT_SYMBOL_GPL vmlinux 0x22472bf4 xfrm_calg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x22830aec usb_hc_died +EXPORT_SYMBOL_GPL vmlinux 0x2296c00d crypto_attr_u32 +EXPORT_SYMBOL_GPL vmlinux 0x22d89e3a ata_host_detach +EXPORT_SYMBOL_GPL vmlinux 0x22ded86d sock_prot_inuse_get +EXPORT_SYMBOL_GPL vmlinux 0x230a1056 pciserial_init_ports +EXPORT_SYMBOL_GPL vmlinux 0x235a9ad5 proc_net_remove +EXPORT_SYMBOL_GPL vmlinux 0x23679939 __iowrite32_copy +EXPORT_SYMBOL_GPL vmlinux 0x236e082d blk_rq_cur_bytes +EXPORT_SYMBOL_GPL vmlinux 0x23864ce7 cpuset_mem_spread_node +EXPORT_SYMBOL_GPL vmlinux 0x2398636a crypto_unregister_alg +EXPORT_SYMBOL_GPL vmlinux 0x23b52435 rdev_get_id +EXPORT_SYMBOL_GPL vmlinux 0x24196ba2 init_uts_ns +EXPORT_SYMBOL_GPL vmlinux 0x2447533c ktime_get_real +EXPORT_SYMBOL_GPL vmlinux 0x24c7698a xenbus_write +EXPORT_SYMBOL_GPL vmlinux 0x24de6c0d driver_add_kobj +EXPORT_SYMBOL_GPL vmlinux 0x24eb7e32 leds_list +EXPORT_SYMBOL_GPL vmlinux 0x2545c170 unregister_xenbus_watch +EXPORT_SYMBOL_GPL vmlinux 0x25466985 __mnt_is_readonly +EXPORT_SYMBOL_GPL vmlinux 0x25f5dca9 pci_enable_rom +EXPORT_SYMBOL_GPL vmlinux 0x260b4f16 sk_setup_caps +EXPORT_SYMBOL_GPL vmlinux 0x26231b4d pci_reset_function +EXPORT_SYMBOL_GPL vmlinux 0x26c90ea4 scsi_eh_get_sense +EXPORT_SYMBOL_GPL vmlinux 0x26df03ce pci_find_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0x26eee649 usb_root_hub_lost_power +EXPORT_SYMBOL_GPL vmlinux 0x27143e1a xfrm_audit_state_add +EXPORT_SYMBOL_GPL vmlinux 0x271cf0a8 aead_geniv_exit +EXPORT_SYMBOL_GPL vmlinux 0x27417edf regulator_enable +EXPORT_SYMBOL_GPL vmlinux 0x2778c46a dm_rh_update_states +EXPORT_SYMBOL_GPL vmlinux 0x279dade2 usb_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x27d4c329 inotify_add_watch +EXPORT_SYMBOL_GPL vmlinux 0x27f07c68 inet6_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0x28088f0f pv_time_ops +EXPORT_SYMBOL_GPL vmlinux 0x28961016 init_user_ns +EXPORT_SYMBOL_GPL vmlinux 0x28a6952b vfs_test_lock +EXPORT_SYMBOL_GPL vmlinux 0x28a9a858 crypto_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x28bdacde hrtimer_start_range_ns +EXPORT_SYMBOL_GPL vmlinux 0x28d664ff __raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x28e23139 xfrm_probe_algs +EXPORT_SYMBOL_GPL vmlinux 0x28e4d6e8 vfs_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0x29206168 __inet_lookup_established +EXPORT_SYMBOL_GPL vmlinux 0x29754236 usb_register_dev +EXPORT_SYMBOL_GPL vmlinux 0x29d1b66e usb_get_from_anchor +EXPORT_SYMBOL_GPL vmlinux 0x29f88a21 inet_csk_reqsk_queue_prune +EXPORT_SYMBOL_GPL vmlinux 0x2a1f6555 kobject_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0x2a21de37 sdio_release_irq +EXPORT_SYMBOL_GPL vmlinux 0x2a518830 cpuidle_enable_device +EXPORT_SYMBOL_GPL vmlinux 0x2a63dcde ata_sff_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x2a678a13 __suspend_report_result +EXPORT_SYMBOL_GPL vmlinux 0x2aa10c29 hwmon_device_register +EXPORT_SYMBOL_GPL vmlinux 0x2ab324c7 debugfs_rename +EXPORT_SYMBOL_GPL vmlinux 0x2abe3754 acpi_bus_trim +EXPORT_SYMBOL_GPL vmlinux 0x2ac20d06 usb_driver_release_interface +EXPORT_SYMBOL_GPL vmlinux 0x2ae33d43 dm_register_path_selector +EXPORT_SYMBOL_GPL vmlinux 0x2ae8555f sdio_memcpy_fromio +EXPORT_SYMBOL_GPL vmlinux 0x2af906a0 blk_abort_queue +EXPORT_SYMBOL_GPL vmlinux 0x2afbf00c regulator_get_init_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x2b53b07d xfrm_audit_state_icvfail +EXPORT_SYMBOL_GPL vmlinux 0x2b9f8e23 nf_net_ipv4_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x2bc9ce99 relay_file_operations +EXPORT_SYMBOL_GPL vmlinux 0x2be5fce6 ata_bmdma_setup +EXPORT_SYMBOL_GPL vmlinux 0x2bee04fa tty_get_pgrp +EXPORT_SYMBOL_GPL vmlinux 0x2c16ed76 xfrm_calg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x2c208607 power_supply_is_system_supplied +EXPORT_SYMBOL_GPL vmlinux 0x2c22a632 device_release_driver +EXPORT_SYMBOL_GPL vmlinux 0x2cb1afd2 spi_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x2cc8758c inotify_init +EXPORT_SYMBOL_GPL vmlinux 0x2d01c42b security_inode_permission +EXPORT_SYMBOL_GPL vmlinux 0x2d45bcda crypto_alg_sem +EXPORT_SYMBOL_GPL vmlinux 0x2d59c954 edac_handlers +EXPORT_SYMBOL_GPL vmlinux 0x2d76c350 scsi_target_block +EXPORT_SYMBOL_GPL vmlinux 0x2d9f2ce3 sched_clock_idle_wakeup_event +EXPORT_SYMBOL_GPL vmlinux 0x2dcf2809 securityfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0x2ddc2c40 __cpufreq_driver_getavg +EXPORT_SYMBOL_GPL vmlinux 0x2df564fc sk_clone +EXPORT_SYMBOL_GPL vmlinux 0x2e1a38d5 tracepoint_iter_reset +EXPORT_SYMBOL_GPL vmlinux 0x2e2b5218 ata_port_start +EXPORT_SYMBOL_GPL vmlinux 0x2eac1137 sysfs_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x2eca51d5 tty_ldisc_deref +EXPORT_SYMBOL_GPL vmlinux 0x2ed298a0 ata_port_desc +EXPORT_SYMBOL_GPL vmlinux 0x2f1935a0 transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x2f47d8c7 cpufreq_frequency_get_table +EXPORT_SYMBOL_GPL vmlinux 0x2f97a04a regulator_bulk_disable +EXPORT_SYMBOL_GPL vmlinux 0x2fa33e93 input_ff_event +EXPORT_SYMBOL_GPL vmlinux 0x2fba8773 dnotify_parent +EXPORT_SYMBOL_GPL vmlinux 0x2fd24b91 relay_switch_subbuf +EXPORT_SYMBOL_GPL vmlinux 0x2fdaf798 devres_open_group +EXPORT_SYMBOL_GPL vmlinux 0x30719ee4 queue_delayed_work +EXPORT_SYMBOL_GPL vmlinux 0x3082c3d5 usb_register_device_driver +EXPORT_SYMBOL_GPL vmlinux 0x3102e053 ata_link_abort +EXPORT_SYMBOL_GPL vmlinux 0x3122e3e3 ata_host_init +EXPORT_SYMBOL_GPL vmlinux 0x31846207 debugfs_create_x8 +EXPORT_SYMBOL_GPL vmlinux 0x318920b1 register_dock_notifier +EXPORT_SYMBOL_GPL vmlinux 0x31bdc41f pci_test_config_bits +EXPORT_SYMBOL_GPL vmlinux 0x322f8378 pci_renumber_slot +EXPORT_SYMBOL_GPL vmlinux 0x324694b4 save_stack_trace_tsk +EXPORT_SYMBOL_GPL vmlinux 0x325e677c gnttab_grant_foreign_transfer_ref +EXPORT_SYMBOL_GPL vmlinux 0x32924a4d scatterwalk_copychunks +EXPORT_SYMBOL_GPL vmlinux 0x3299dfd6 crypto_free_tfm +EXPORT_SYMBOL_GPL vmlinux 0x332d3ee2 usb_sg_wait +EXPORT_SYMBOL_GPL vmlinux 0x336eef4a get_driver +EXPORT_SYMBOL_GPL vmlinux 0x33a85fe7 simple_attr_open +EXPORT_SYMBOL_GPL vmlinux 0x33b6e752 acpi_ec_remove_query_handler +EXPORT_SYMBOL_GPL vmlinux 0x341413f8 pci_cleanup_aer_uncorrect_error_status +EXPORT_SYMBOL_GPL vmlinux 0x3441c3d6 gpio_set_value_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x3478d140 cpufreq_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x3498ba6f nf_unregister_queue_handlers +EXPORT_SYMBOL_GPL vmlinux 0x35250e5f usb_buffer_map_sg +EXPORT_SYMBOL_GPL vmlinux 0x354c8afd ezusb_set_reset +EXPORT_SYMBOL_GPL vmlinux 0x359b91ce zap_vma_ptes +EXPORT_SYMBOL_GPL vmlinux 0x35c1988c usb_hcd_check_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0x35c8d7e6 blkcipher_walk_virt_block +EXPORT_SYMBOL_GPL vmlinux 0x35d8c94a sdev_evt_alloc +EXPORT_SYMBOL_GPL vmlinux 0x3615a240 find_vpid +EXPORT_SYMBOL_GPL vmlinux 0x361e2bcc save_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0x362e23ec call_rcu_bh +EXPORT_SYMBOL_GPL vmlinux 0x366fe10f debugfs_create_x32 +EXPORT_SYMBOL_GPL vmlinux 0x36a0af4c usb_hcd_pci_remove +EXPORT_SYMBOL_GPL vmlinux 0x36f9f71d ata_sff_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0x3718143d kobject_uevent +EXPORT_SYMBOL_GPL vmlinux 0x372acfe4 scsi_queue_work +EXPORT_SYMBOL_GPL vmlinux 0x37665e4c xenbus_dev_fatal +EXPORT_SYMBOL_GPL vmlinux 0x377a0ee6 ata_sff_port_start +EXPORT_SYMBOL_GPL vmlinux 0x377cd861 __rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0x37c22868 alloc_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x37eb3b43 regulator_register +EXPORT_SYMBOL_GPL vmlinux 0x380a1203 fs_kobj +EXPORT_SYMBOL_GPL vmlinux 0x388d63f3 inotify_inode_is_dead +EXPORT_SYMBOL_GPL vmlinux 0x388d7649 cpufreq_driver_target +EXPORT_SYMBOL_GPL vmlinux 0x3895233b srcu_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x38b3aa4f usb_sg_init +EXPORT_SYMBOL_GPL vmlinux 0x38f8eb4b ata_sas_port_stop +EXPORT_SYMBOL_GPL vmlinux 0x38f9553f spi_busnum_to_master +EXPORT_SYMBOL_GPL vmlinux 0x39238b57 klist_del +EXPORT_SYMBOL_GPL vmlinux 0x392e78c3 da903x_update +EXPORT_SYMBOL_GPL vmlinux 0x39990ab5 rtc_set_time +EXPORT_SYMBOL_GPL vmlinux 0x3a56cc3d raw_hash_sk +EXPORT_SYMBOL_GPL vmlinux 0x3a7f8b86 __local_bh_enable +EXPORT_SYMBOL_GPL vmlinux 0x3a888919 ata_pci_device_resume +EXPORT_SYMBOL_GPL vmlinux 0x3a8edb44 sata_link_resume +EXPORT_SYMBOL_GPL vmlinux 0x3aabaa36 ata_do_eh +EXPORT_SYMBOL_GPL vmlinux 0x3b0886ab driver_register +EXPORT_SYMBOL_GPL vmlinux 0x3b0bf870 ata_eh_thaw_port +EXPORT_SYMBOL_GPL vmlinux 0x3b1feed3 usb_altnum_to_altsetting +EXPORT_SYMBOL_GPL vmlinux 0x3b5df58e inet6_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0x3b696217 sdio_f0_readb +EXPORT_SYMBOL_GPL vmlinux 0x3b9a20d9 debugfs_create_u8 +EXPORT_SYMBOL_GPL vmlinux 0x3be7af02 get_max_files +EXPORT_SYMBOL_GPL vmlinux 0x3be89d3c usb_register_notify +EXPORT_SYMBOL_GPL vmlinux 0x3bf5f9bd tcp_register_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0x3c03c6d7 hidraw_report_event +EXPORT_SYMBOL_GPL vmlinux 0x3c7a6986 relay_reset +EXPORT_SYMBOL_GPL vmlinux 0x3c942368 profile_event_unregister +EXPORT_SYMBOL_GPL vmlinux 0x3c969855 __ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0x3cd06035 add_input_randomness +EXPORT_SYMBOL_GPL vmlinux 0x3cfedb3f register_pm_notifier +EXPORT_SYMBOL_GPL vmlinux 0x3d2cc3f9 usb_hub_tt_clear_buffer +EXPORT_SYMBOL_GPL vmlinux 0x3d7ea99a gnttab_grant_foreign_transfer +EXPORT_SYMBOL_GPL vmlinux 0x3d94b716 inet_csk_route_req +EXPORT_SYMBOL_GPL vmlinux 0x3dc8bbf2 inet_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0x3ddca14a ata_bmdma_start +EXPORT_SYMBOL_GPL vmlinux 0x3e2606d7 debugfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x3e3cc192 uhci_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0x3ea967a4 fib_rules_register +EXPORT_SYMBOL_GPL vmlinux 0x3eaca631 ata_bus_reset +EXPORT_SYMBOL_GPL vmlinux 0x3ecf6cfc wmi_install_notify_handler +EXPORT_SYMBOL_GPL vmlinux 0x3edad223 usb_usual_clear_present +EXPORT_SYMBOL_GPL vmlinux 0x3ef5275b register_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0x3efb35c9 get_online_cpus +EXPORT_SYMBOL_GPL vmlinux 0x3f01570a probe_kernel_write +EXPORT_SYMBOL_GPL vmlinux 0x3f0adade ata_sff_post_internal_cmd +EXPORT_SYMBOL_GPL vmlinux 0x3f238101 dcookie_register +EXPORT_SYMBOL_GPL vmlinux 0x3f3d6465 platform_add_devices +EXPORT_SYMBOL_GPL vmlinux 0x3f588432 power_supply_changed +EXPORT_SYMBOL_GPL vmlinux 0x3f7bfdbb inet_ctl_sock_create +EXPORT_SYMBOL_GPL vmlinux 0x3f810a12 led_trigger_register +EXPORT_SYMBOL_GPL vmlinux 0x3f84d4c9 gnttab_release_grant_reference +EXPORT_SYMBOL_GPL vmlinux 0x3fb0bbe3 device_del +EXPORT_SYMBOL_GPL vmlinux 0x3fc218c1 xfrm_output +EXPORT_SYMBOL_GPL vmlinux 0x3fd40062 usb_sg_cancel +EXPORT_SYMBOL_GPL vmlinux 0x40380ad6 hrtimer_cancel +EXPORT_SYMBOL_GPL vmlinux 0x4076ed28 pci_enable_pcie_error_reporting +EXPORT_SYMBOL_GPL vmlinux 0x40af0dec ata_xfer_mode2mask +EXPORT_SYMBOL_GPL vmlinux 0x40b3c2c0 dm_path_uevent +EXPORT_SYMBOL_GPL vmlinux 0x414255ed platform_bus +EXPORT_SYMBOL_GPL vmlinux 0x41f3cc90 xfrm_aalg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x424acc6d scatterwalk_done +EXPORT_SYMBOL_GPL vmlinux 0x424b4562 crypto_mod_get +EXPORT_SYMBOL_GPL vmlinux 0x42950942 __get_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x42d16cda xenbus_free_evtchn +EXPORT_SYMBOL_GPL vmlinux 0x432fd7f6 __gpio_set_value +EXPORT_SYMBOL_GPL vmlinux 0x43779aaa inotify_init_watch +EXPORT_SYMBOL_GPL vmlinux 0x43dcbf2b dm_rh_bio_to_region +EXPORT_SYMBOL_GPL vmlinux 0x43f56e82 ata_xfer_mode2shift +EXPORT_SYMBOL_GPL vmlinux 0x44016d08 uart_set_options +EXPORT_SYMBOL_GPL vmlinux 0x445ce03a raw_seq_next +EXPORT_SYMBOL_GPL vmlinux 0x44a65d5c lock_policy_rwsem_read +EXPORT_SYMBOL_GPL vmlinux 0x44d62cc1 fb_deferred_io_init +EXPORT_SYMBOL_GPL vmlinux 0x44dad0b1 regulator_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x450f41c5 cpufreq_frequency_table_target +EXPORT_SYMBOL_GPL vmlinux 0x4533f56b xenbus_watch_path +EXPORT_SYMBOL_GPL vmlinux 0x455f360b sysfs_remove_link +EXPORT_SYMBOL_GPL vmlinux 0x457594fa crypto_alg_list +EXPORT_SYMBOL_GPL vmlinux 0x45bf1ff3 crypto_inc +EXPORT_SYMBOL_GPL vmlinux 0x45d14bdf hypercall_page +EXPORT_SYMBOL_GPL vmlinux 0x45d4dc62 blk_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0x45ff8813 pci_find_ext_capability +EXPORT_SYMBOL_GPL vmlinux 0x460f31aa rodata_test_data +EXPORT_SYMBOL_GPL vmlinux 0x461c3e30 transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x466870d9 sata_scr_read +EXPORT_SYMBOL_GPL vmlinux 0x4689bc88 klist_node_attached +EXPORT_SYMBOL_GPL vmlinux 0x46aa0234 hidinput_disconnect +EXPORT_SYMBOL_GPL vmlinux 0x46e2ded2 usb_find_interface +EXPORT_SYMBOL_GPL vmlinux 0x46f1a647 ata_eh_qc_retry +EXPORT_SYMBOL_GPL vmlinux 0x4709aa14 ata_pci_bmdma_init +EXPORT_SYMBOL_GPL vmlinux 0x4710fb52 platform_device_put +EXPORT_SYMBOL_GPL vmlinux 0x47229b5c gpio_request +EXPORT_SYMBOL_GPL vmlinux 0x4756e941 platform_device_del +EXPORT_SYMBOL_GPL vmlinux 0x475ec8b4 find_get_pid +EXPORT_SYMBOL_GPL vmlinux 0x477737cc anon_inode_getfd +EXPORT_SYMBOL_GPL vmlinux 0x47be279c sysfs_get +EXPORT_SYMBOL_GPL vmlinux 0x483426c0 single_open_net +EXPORT_SYMBOL_GPL vmlinux 0x489149c8 dm_region_hash_destroy +EXPORT_SYMBOL_GPL vmlinux 0x48d33260 tty_prepare_flip_string +EXPORT_SYMBOL_GPL vmlinux 0x49335453 crypto_tfm_in_queue +EXPORT_SYMBOL_GPL vmlinux 0x4958e390 seq_open_net +EXPORT_SYMBOL_GPL vmlinux 0x4962eeb1 fb_deferred_io_fsync +EXPORT_SYMBOL_GPL vmlinux 0x496574d5 sysfs_chmod_file +EXPORT_SYMBOL_GPL vmlinux 0x499043d3 crypto_init_queue +EXPORT_SYMBOL_GPL vmlinux 0x49a3b1ab device_bind_driver +EXPORT_SYMBOL_GPL vmlinux 0x49ef68c3 unregister_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0x49fe6675 ata_acpi_gtm_xfermask +EXPORT_SYMBOL_GPL vmlinux 0x4a11a4fb bind_virq_to_irqhandler +EXPORT_SYMBOL_GPL vmlinux 0x4a7e30d9 marker_probe_unregister_private_data +EXPORT_SYMBOL_GPL vmlinux 0x4ac2e6d3 ata_sff_dumb_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x4ae2986f user_describe +EXPORT_SYMBOL_GPL vmlinux 0x4ae56161 inotify_find_update_watch +EXPORT_SYMBOL_GPL vmlinux 0x4af39f2a platform_get_irq +EXPORT_SYMBOL_GPL vmlinux 0x4b35b9c4 generic_fh_to_dentry +EXPORT_SYMBOL_GPL vmlinux 0x4b611448 page_cache_sync_readahead +EXPORT_SYMBOL_GPL vmlinux 0x4b8d2b9b __trace_note_message +EXPORT_SYMBOL_GPL vmlinux 0x4bc21f9b scsi_register_device_handler +EXPORT_SYMBOL_GPL vmlinux 0x4bcef498 dev_set_name +EXPORT_SYMBOL_GPL vmlinux 0x4c1bb689 class_dev_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x4c32215e power_supply_unregister +EXPORT_SYMBOL_GPL vmlinux 0x4c759827 byte_rev_table +EXPORT_SYMBOL_GPL vmlinux 0x4c969899 regulator_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x4cca5a1d d_obtain_alias +EXPORT_SYMBOL_GPL vmlinux 0x4ccfed1f transport_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0x4cdb4bd0 speedstep_get_processor_frequency +EXPORT_SYMBOL_GPL vmlinux 0x4cf06b68 sysdev_create_file +EXPORT_SYMBOL_GPL vmlinux 0x4d2d9e1b sysfs_create_group +EXPORT_SYMBOL_GPL vmlinux 0x4d66daa2 ata_sg_init +EXPORT_SYMBOL_GPL vmlinux 0x4dda3de6 sdio_f0_writeb +EXPORT_SYMBOL_GPL vmlinux 0x4ddd4356 generic_sync_sb_inodes +EXPORT_SYMBOL_GPL vmlinux 0x4e286c01 elv_unregister +EXPORT_SYMBOL_GPL vmlinux 0x4ee67985 usb_hcd_platform_shutdown +EXPORT_SYMBOL_GPL vmlinux 0x4f2b0ce7 pci_find_next_capability +EXPORT_SYMBOL_GPL vmlinux 0x4f7971d9 crypto_ablkcipher_type +EXPORT_SYMBOL_GPL vmlinux 0x4f9e2c69 xenbus_frontend_closed +EXPORT_SYMBOL_GPL vmlinux 0x4fdc945d sata_deb_timing_normal +EXPORT_SYMBOL_GPL vmlinux 0x4fec414f i2c_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x50024dee ata_common_sdev_attrs +EXPORT_SYMBOL_GPL vmlinux 0x50144a10 pci_disable_rom +EXPORT_SYMBOL_GPL vmlinux 0x5039e882 sdio_readl +EXPORT_SYMBOL_GPL vmlinux 0x504acde3 device_find_child +EXPORT_SYMBOL_GPL vmlinux 0x506fa35f shmem_file_setup +EXPORT_SYMBOL_GPL vmlinux 0x5086ac3a alg_test +EXPORT_SYMBOL_GPL vmlinux 0x50b4b658 page_cache_async_readahead +EXPORT_SYMBOL_GPL vmlinux 0x50b67174 xfrm_ealg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x50d56df2 ata_acpi_cbl_80wire +EXPORT_SYMBOL_GPL vmlinux 0x50e7193a __i2c_first_dynamic_bus_num +EXPORT_SYMBOL_GPL vmlinux 0x50fad434 round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x5108b3fc acpi_os_map_memory +EXPORT_SYMBOL_GPL vmlinux 0x5112f5da transport_configure_device +EXPORT_SYMBOL_GPL vmlinux 0x511bc7dd file_ra_state_init +EXPORT_SYMBOL_GPL vmlinux 0x511f3e1f apic_ops +EXPORT_SYMBOL_GPL vmlinux 0x5164cdb3 inet_csk_clone +EXPORT_SYMBOL_GPL vmlinux 0x516949ab sata_set_spd +EXPORT_SYMBOL_GPL vmlinux 0x518c2fc6 hpet_rtc_dropped_irq +EXPORT_SYMBOL_GPL vmlinux 0x51cf44c7 nf_unregister_afinfo +EXPORT_SYMBOL_GPL vmlinux 0x51d39b00 sysfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x51dbbd74 usb_hcd_unlink_urb_from_ep +EXPORT_SYMBOL_GPL vmlinux 0x51dd6488 xfrm_aalg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x520e3562 skb_pull_rcsum +EXPORT_SYMBOL_GPL vmlinux 0x52402803 usb_autopm_get_interface +EXPORT_SYMBOL_GPL vmlinux 0x52561a9c bus_create_file +EXPORT_SYMBOL_GPL vmlinux 0x5264aa41 __blk_put_request +EXPORT_SYMBOL_GPL vmlinux 0x526b867a acpi_smbus_read +EXPORT_SYMBOL_GPL vmlinux 0x526d80ad sata_scr_write_flush +EXPORT_SYMBOL_GPL vmlinux 0x526ea172 user_destroy +EXPORT_SYMBOL_GPL vmlinux 0x52b036ea driver_find_device +EXPORT_SYMBOL_GPL vmlinux 0x52d111ea pm_qos_update_requirement +EXPORT_SYMBOL_GPL vmlinux 0x53614269 get_cpu_idle_time_us +EXPORT_SYMBOL_GPL vmlinux 0x5372dede unregister_acpi_bus_notifier +EXPORT_SYMBOL_GPL vmlinux 0x53986488 register_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x53a1dac5 do_add_mount +EXPORT_SYMBOL_GPL vmlinux 0x53c91281 do_sync_mapping_range +EXPORT_SYMBOL_GPL vmlinux 0x53eafba9 xfrm_inner_extract_output +EXPORT_SYMBOL_GPL vmlinux 0x53fbb4f0 dequeue_signal +EXPORT_SYMBOL_GPL vmlinux 0x545e768e led_trigger_unregister +EXPORT_SYMBOL_GPL vmlinux 0x549f5411 usb_serial_probe +EXPORT_SYMBOL_GPL vmlinux 0x54a709a9 dm_rh_recovery_start +EXPORT_SYMBOL_GPL vmlinux 0x55526907 xen_features +EXPORT_SYMBOL_GPL vmlinux 0x555a58e3 __inet_twsk_hashdance +EXPORT_SYMBOL_GPL vmlinux 0x555d6792 skb_cow_data +EXPORT_SYMBOL_GPL vmlinux 0x55941ab3 ata_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0x55a6ef39 inotify_destroy +EXPORT_SYMBOL_GPL vmlinux 0x55d38be1 ata_port_probe +EXPORT_SYMBOL_GPL vmlinux 0x55df4626 usb_hcd_resume_root_hub +EXPORT_SYMBOL_GPL vmlinux 0x56398615 mark_tsc_unstable +EXPORT_SYMBOL_GPL vmlinux 0x5641485b tty_termios_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x569cf357 fib_rules_lookup +EXPORT_SYMBOL_GPL vmlinux 0x56a56030 xenbus_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x56d94e93 crypto_alloc_aead +EXPORT_SYMBOL_GPL vmlinux 0x5779d445 xenbus_exists +EXPORT_SYMBOL_GPL vmlinux 0x579e0bf5 rtnl_unregister_all +EXPORT_SYMBOL_GPL vmlinux 0x58345857 ipv6_dup_options +EXPORT_SYMBOL_GPL vmlinux 0x58457e0a ata_cable_sata +EXPORT_SYMBOL_GPL vmlinux 0x58c0ff21 user_instantiate +EXPORT_SYMBOL_GPL vmlinux 0x58e77aa7 register_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0x58fd91ed __xenbus_register_frontend +EXPORT_SYMBOL_GPL vmlinux 0x593a36c2 scsi_dh_handler_exist +EXPORT_SYMBOL_GPL vmlinux 0x5953e55d ata_std_error_handler +EXPORT_SYMBOL_GPL vmlinux 0x597f3bc3 marker_get_private_data +EXPORT_SYMBOL_GPL vmlinux 0x59a3af1c device_for_each_child +EXPORT_SYMBOL_GPL vmlinux 0x59ad6f26 sysfs_add_file_to_group +EXPORT_SYMBOL_GPL vmlinux 0x5a2b1b67 gnttab_free_grant_reference +EXPORT_SYMBOL_GPL vmlinux 0x5a5756f6 ata_std_prereset +EXPORT_SYMBOL_GPL vmlinux 0x5a6f5cff cpufreq_freq_attr_scaling_available_freqs +EXPORT_SYMBOL_GPL vmlinux 0x5a7bfe41 crypto_probing_notify +EXPORT_SYMBOL_GPL vmlinux 0x5aae1419 debugfs_create_bool +EXPORT_SYMBOL_GPL vmlinux 0x5ac8c6b7 unregister_kprobes +EXPORT_SYMBOL_GPL vmlinux 0x5aec879c ata_base_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x5af03a28 gnttab_claim_grant_reference +EXPORT_SYMBOL_GPL vmlinux 0x5afd2c9e raw_seq_open +EXPORT_SYMBOL_GPL vmlinux 0x5b579cb8 ata_sff_irq_clear +EXPORT_SYMBOL_GPL vmlinux 0x5bd9171f crypto_register_template +EXPORT_SYMBOL_GPL vmlinux 0x5bfc03c3 unregister_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5c064e54 simple_attr_write +EXPORT_SYMBOL_GPL vmlinux 0x5c20dfe1 ata_acpi_stm +EXPORT_SYMBOL_GPL vmlinux 0x5c461f42 get_cpu_sysdev +EXPORT_SYMBOL_GPL vmlinux 0x5c953546 rt_mutex_lock +EXPORT_SYMBOL_GPL vmlinux 0x5ce426cb usb_put_hcd +EXPORT_SYMBOL_GPL vmlinux 0x5cfcf0f1 percpu_free +EXPORT_SYMBOL_GPL vmlinux 0x5d07819b dm_put +EXPORT_SYMBOL_GPL vmlinux 0x5d0f6f57 kbd_table +EXPORT_SYMBOL_GPL vmlinux 0x5d1e3f23 usb_add_hcd +EXPORT_SYMBOL_GPL vmlinux 0x5d366dec gnttab_cancel_free_callback +EXPORT_SYMBOL_GPL vmlinux 0x5d5aa7d0 xfrm_audit_policy_add +EXPORT_SYMBOL_GPL vmlinux 0x5d5ea4c6 hid_output_report +EXPORT_SYMBOL_GPL vmlinux 0x5d70b8c7 regulator_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5d730e7b raw_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5d76fd7f i2c_new_probed_device +EXPORT_SYMBOL_GPL vmlinux 0x5d87c067 register_acpi_bus_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5dd67618 register_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5e099c16 transport_remove_device +EXPORT_SYMBOL_GPL vmlinux 0x5e59156b hid_parse_report +EXPORT_SYMBOL_GPL vmlinux 0x5e83f2c6 scsi_flush_work +EXPORT_SYMBOL_GPL vmlinux 0x5e9e8bac i2c_unregister_device +EXPORT_SYMBOL_GPL vmlinux 0x5ed71e34 raw_seq_stop +EXPORT_SYMBOL_GPL vmlinux 0x5ef17f6f ata_dev_pair +EXPORT_SYMBOL_GPL vmlinux 0x5f1355e9 ata_port_freeze +EXPORT_SYMBOL_GPL vmlinux 0x5f1f3fdc relay_open +EXPORT_SYMBOL_GPL vmlinux 0x5f2da8c4 check_tsc_unstable +EXPORT_SYMBOL_GPL vmlinux 0x5f504cc7 cpci_hp_unregister_controller +EXPORT_SYMBOL_GPL vmlinux 0x601a5ba5 usb_serial_generic_read_bulk_callback +EXPORT_SYMBOL_GPL vmlinux 0x605ff123 klist_add_tail +EXPORT_SYMBOL_GPL vmlinux 0x6091797f synchronize_rcu +EXPORT_SYMBOL_GPL vmlinux 0x6097431d scsi_internal_device_unblock +EXPORT_SYMBOL_GPL vmlinux 0x60a13e90 rcu_barrier +EXPORT_SYMBOL_GPL vmlinux 0x60a38453 pci_unblock_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0x60bc1fb5 usb_get_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x610ed487 usb_autopm_set_interface +EXPORT_SYMBOL_GPL vmlinux 0x611414f9 blk_queue_dma_drain +EXPORT_SYMBOL_GPL vmlinux 0x61aa9d29 sata_pmp_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x61d5f003 class_destroy +EXPORT_SYMBOL_GPL vmlinux 0x62159070 inotify_remove_watch_locked +EXPORT_SYMBOL_GPL vmlinux 0x62645eae __mmu_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x62858385 inet_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0x629c2abf usb_serial_generic_write_bulk_callback +EXPORT_SYMBOL_GPL vmlinux 0x62c33066 sdio_set_block_size +EXPORT_SYMBOL_GPL vmlinux 0x631b7e9c usb_unanchor_urb +EXPORT_SYMBOL_GPL vmlinux 0x634e4a1e inet_unhash +EXPORT_SYMBOL_GPL vmlinux 0x63ae27d6 add_nops +EXPORT_SYMBOL_GPL vmlinux 0x63b39b26 blk_insert_cloned_request +EXPORT_SYMBOL_GPL vmlinux 0x63b924c7 rtc_set_alarm +EXPORT_SYMBOL_GPL vmlinux 0x642be060 sysfs_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x643547c2 rt_mutex_unlock +EXPORT_SYMBOL_GPL vmlinux 0x64367bf9 ata_qc_complete_multiple +EXPORT_SYMBOL_GPL vmlinux 0x6459e265 regulator_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x6468b9bb ata_std_postreset +EXPORT_SYMBOL_GPL vmlinux 0x649e69a3 fib_rules_cleanup_ops +EXPORT_SYMBOL_GPL vmlinux 0x64be98e1 ata_ehi_clear_desc +EXPORT_SYMBOL_GPL vmlinux 0x64ebe677 wmi_query_block +EXPORT_SYMBOL_GPL vmlinux 0x655e523d unregister_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0x6583df24 usb_get_urb +EXPORT_SYMBOL_GPL vmlinux 0x65c15e47 usb_ep0_reinit +EXPORT_SYMBOL_GPL vmlinux 0x65ccb6f0 call_netevent_notifiers +EXPORT_SYMBOL_GPL vmlinux 0x65d6d0f0 gpio_direction_input +EXPORT_SYMBOL_GPL vmlinux 0x65f578c2 tcp_reno_cong_avoid +EXPORT_SYMBOL_GPL vmlinux 0x6610ad99 synchronize_srcu +EXPORT_SYMBOL_GPL vmlinux 0x661601de sprint_symbol +EXPORT_SYMBOL_GPL vmlinux 0x66482f41 sdio_writel +EXPORT_SYMBOL_GPL vmlinux 0x668402aa crypto_put_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x66b2a859 nr_free_buffer_pages +EXPORT_SYMBOL_GPL vmlinux 0x66c9e6bb pci_scan_child_bus +EXPORT_SYMBOL_GPL vmlinux 0x66d87d38 symbol_put_addr +EXPORT_SYMBOL_GPL vmlinux 0x67955ce6 profile_hits +EXPORT_SYMBOL_GPL vmlinux 0x679c2d0b pci_hp_change_slot_info +EXPORT_SYMBOL_GPL vmlinux 0x67e2e77b inet_hash +EXPORT_SYMBOL_GPL vmlinux 0x67ea50a2 ata_sff_busy_sleep +EXPORT_SYMBOL_GPL vmlinux 0x686c703f xfrm_count_auth_supported +EXPORT_SYMBOL_GPL vmlinux 0x6875d38c klist_next +EXPORT_SYMBOL_GPL vmlinux 0x6892088c unregister_pm_notifier +EXPORT_SYMBOL_GPL vmlinux 0x68a28433 usb_submit_urb +EXPORT_SYMBOL_GPL vmlinux 0x68b452c5 inotify_rm_watch +EXPORT_SYMBOL_GPL vmlinux 0x68ccf555 blk_rq_bytes +EXPORT_SYMBOL_GPL vmlinux 0x690cf923 blk_abort_request +EXPORT_SYMBOL_GPL vmlinux 0x690fc251 gpiochip_add +EXPORT_SYMBOL_GPL vmlinux 0x69349c63 schedule_hrtimeout_range +EXPORT_SYMBOL_GPL vmlinux 0x69720c81 ata_dev_disable +EXPORT_SYMBOL_GPL vmlinux 0x6976c4ee skb_segment +EXPORT_SYMBOL_GPL vmlinux 0x698713dd led_trigger_remove +EXPORT_SYMBOL_GPL vmlinux 0x6987c5fd blk_trace_setup +EXPORT_SYMBOL_GPL vmlinux 0x69895fe7 ata_pci_device_suspend +EXPORT_SYMBOL_GPL vmlinux 0x69bac3e9 driver_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x69e9a2cb ata_scsi_slave_config +EXPORT_SYMBOL_GPL vmlinux 0x6a2fe472 bus_get_device_klist +EXPORT_SYMBOL_GPL vmlinux 0x6a3cf8ba generic_drop_inode +EXPORT_SYMBOL_GPL vmlinux 0x6a8441be cpci_hp_start +EXPORT_SYMBOL_GPL vmlinux 0x6aa560ad xfrm_output_resume +EXPORT_SYMBOL_GPL vmlinux 0x6af1b735 crypto_grab_aead +EXPORT_SYMBOL_GPL vmlinux 0x6b5f6b46 seq_release_net +EXPORT_SYMBOL_GPL vmlinux 0x6b6cc5a5 sdev_evt_send +EXPORT_SYMBOL_GPL vmlinux 0x6b9178b3 xenbus_strstate +EXPORT_SYMBOL_GPL vmlinux 0x6ba0dd66 input_ff_create +EXPORT_SYMBOL_GPL vmlinux 0x6beef274 inotify_dentry_parent_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x6bfa7ff9 scsi_nl_add_transport +EXPORT_SYMBOL_GPL vmlinux 0x6c0ac4a6 aead_geniv_free +EXPORT_SYMBOL_GPL vmlinux 0x6c11059b __srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x6c49c4f2 clockevents_notify +EXPORT_SYMBOL_GPL vmlinux 0x6c55453c crypto_alloc_base +EXPORT_SYMBOL_GPL vmlinux 0x6c5eca9e fsstack_copy_inode_size +EXPORT_SYMBOL_GPL vmlinux 0x6c8d5ae8 __gpio_get_value +EXPORT_SYMBOL_GPL vmlinux 0x6cafc159 regulator_get_mode +EXPORT_SYMBOL_GPL vmlinux 0x6d2d71c9 apply_to_page_range +EXPORT_SYMBOL_GPL vmlinux 0x6d2fc5a6 net_namespace_list +EXPORT_SYMBOL_GPL vmlinux 0x6d8bfc32 scsi_unregister_device_handler +EXPORT_SYMBOL_GPL vmlinux 0x6d944951 pci_find_next_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0x6dc65c6d ata_dummy_port_info +EXPORT_SYMBOL_GPL vmlinux 0x6dce94bf usb_bus_list_lock +EXPORT_SYMBOL_GPL vmlinux 0x6de348bd cpuidle_disable_device +EXPORT_SYMBOL_GPL vmlinux 0x6e573b5b crypto_hash_walk_first +EXPORT_SYMBOL_GPL vmlinux 0x6e58ddf0 gnttab_end_foreign_transfer_ref +EXPORT_SYMBOL_GPL vmlinux 0x6ebef329 sdio_claim_host +EXPORT_SYMBOL_GPL vmlinux 0x6efb5bcc ata_cable_40wire +EXPORT_SYMBOL_GPL vmlinux 0x6f1a542b rtc_irq_set_freq +EXPORT_SYMBOL_GPL vmlinux 0x6f5958d6 bus_find_device_by_name +EXPORT_SYMBOL_GPL vmlinux 0x6f8d6cfe ata_port_pbar_desc +EXPORT_SYMBOL_GPL vmlinux 0x6f9c2efe marker_probe_cb +EXPORT_SYMBOL_GPL vmlinux 0x6facf710 dm_rh_recovery_in_flight +EXPORT_SYMBOL_GPL vmlinux 0x6fb83d89 usb_match_id +EXPORT_SYMBOL_GPL vmlinux 0x6ff607b6 crypto_get_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x70183981 input_ff_destroy +EXPORT_SYMBOL_GPL vmlinux 0x702a12cc klist_iter_init_node +EXPORT_SYMBOL_GPL vmlinux 0x7037d79d k8_flush_garts +EXPORT_SYMBOL_GPL vmlinux 0x706b3a33 cpufreq_frequency_table_get_attr +EXPORT_SYMBOL_GPL vmlinux 0x707ff1bb ata_xfer_mask2mode +EXPORT_SYMBOL_GPL vmlinux 0x70dc64e3 hid_connect +EXPORT_SYMBOL_GPL vmlinux 0x715a8435 sata_scr_write +EXPORT_SYMBOL_GPL vmlinux 0x71a91483 ata_sff_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x71c8bc95 kgdb_unregister_io_module +EXPORT_SYMBOL_GPL vmlinux 0x721dadd6 crypto_ahash_type +EXPORT_SYMBOL_GPL vmlinux 0x722c4f65 usb_scuttle_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x7238bdb2 pciserial_remove_ports +EXPORT_SYMBOL_GPL vmlinux 0x7256f1b3 bt_class +EXPORT_SYMBOL_GPL vmlinux 0x725d2cd4 input_class +EXPORT_SYMBOL_GPL vmlinux 0x7270bd5c relay_flush +EXPORT_SYMBOL_GPL vmlinux 0x7278d328 all_vm_events +EXPORT_SYMBOL_GPL vmlinux 0x731dba7a xen_domain_type +EXPORT_SYMBOL_GPL vmlinux 0x7323af2d disk_part_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x734ea682 device_destroy +EXPORT_SYMBOL_GPL vmlinux 0x73a48b4a ata_sff_std_ports +EXPORT_SYMBOL_GPL vmlinux 0x73b1f76d do_posix_clock_nosettime +EXPORT_SYMBOL_GPL vmlinux 0x73cc7e10 xfrm_audit_state_notfound_simple +EXPORT_SYMBOL_GPL vmlinux 0x7403f55a dm_rh_region_to_sector +EXPORT_SYMBOL_GPL vmlinux 0x743a165e ata_pack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0x7479bc03 disk_part_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x747c5237 invalidate_inode_pages2_range +EXPORT_SYMBOL_GPL vmlinux 0x74abdafa task_handoff_register +EXPORT_SYMBOL_GPL vmlinux 0x74d61a4d get_dcookie +EXPORT_SYMBOL_GPL vmlinux 0x74deb10c used_vectors +EXPORT_SYMBOL_GPL vmlinux 0x750b3dc1 blk_trace_startstop +EXPORT_SYMBOL_GPL vmlinux 0x7521afb6 leave_mm +EXPORT_SYMBOL_GPL vmlinux 0x754d4a17 __blk_add_trace +EXPORT_SYMBOL_GPL vmlinux 0x754ef135 relay_buf_full +EXPORT_SYMBOL_GPL vmlinux 0x7568b92e register_jprobes +EXPORT_SYMBOL_GPL vmlinux 0x75736727 queue_work +EXPORT_SYMBOL_GPL vmlinux 0x75a88f26 fb_bl_default_curve +EXPORT_SYMBOL_GPL vmlinux 0x75c3736c devres_release_group +EXPORT_SYMBOL_GPL vmlinux 0x75c8a11c inet_twdr_twkill_work +EXPORT_SYMBOL_GPL vmlinux 0x75e8f3c3 crypto_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x7640070a rt_mutex_lock_interruptible +EXPORT_SYMBOL_GPL vmlinux 0x76f0ddc0 driver_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x7712771a unbind_from_irqhandler +EXPORT_SYMBOL_GPL vmlinux 0x77300dbe default_backing_dev_info +EXPORT_SYMBOL_GPL vmlinux 0x7733009e __ata_port_next_link +EXPORT_SYMBOL_GPL vmlinux 0x7751aae0 user_update +EXPORT_SYMBOL_GPL vmlinux 0x7804f40d klist_remove +EXPORT_SYMBOL_GPL vmlinux 0x7861e543 ata_acpi_gtm +EXPORT_SYMBOL_GPL vmlinux 0x78991cf7 xenbus_switch_state +EXPORT_SYMBOL_GPL vmlinux 0x78b44e08 get_device +EXPORT_SYMBOL_GPL vmlinux 0x78c36155 pci_slots_kset +EXPORT_SYMBOL_GPL vmlinux 0x78d79d62 ata_link_offline +EXPORT_SYMBOL_GPL vmlinux 0x78da6ee7 xenbus_unmap_ring_vfree +EXPORT_SYMBOL_GPL vmlinux 0x78f072c8 debugfs_create_x16 +EXPORT_SYMBOL_GPL vmlinux 0x793c8803 skcipher_geniv_init +EXPORT_SYMBOL_GPL vmlinux 0x795aa846 find_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0x796205dc __audit_inode_child +EXPORT_SYMBOL_GPL vmlinux 0x796ad5fb ata_scsi_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0x797423ac klist_add_before +EXPORT_SYMBOL_GPL vmlinux 0x79cd7358 rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0x7a354347 crypto_dequeue_request +EXPORT_SYMBOL_GPL vmlinux 0x7a45d49c ata_sff_thaw +EXPORT_SYMBOL_GPL vmlinux 0x7a4c1438 pv_info +EXPORT_SYMBOL_GPL vmlinux 0x7a683020 blk_rq_check_limits +EXPORT_SYMBOL_GPL vmlinux 0x7abe31e6 part_round_stats +EXPORT_SYMBOL_GPL vmlinux 0x7acdf241 audit_log_vformat +EXPORT_SYMBOL_GPL vmlinux 0x7ae1ae8e cpufreq_frequency_table_put_attr +EXPORT_SYMBOL_GPL vmlinux 0x7b086370 blkdev_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x7b1d335e ata_noop_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x7b1d544d edac_handler_set +EXPORT_SYMBOL_GPL vmlinux 0x7b2f8258 sdev_evt_send_simple +EXPORT_SYMBOL_GPL vmlinux 0x7b4d38e5 dm_rh_inc_pending +EXPORT_SYMBOL_GPL vmlinux 0x7b81b780 xenbus_bind_evtchn +EXPORT_SYMBOL_GPL vmlinux 0x7ba37462 register_posix_clock +EXPORT_SYMBOL_GPL vmlinux 0x7c7123b3 vfs_lock_file +EXPORT_SYMBOL_GPL vmlinux 0x7cf2b9cc devres_destroy +EXPORT_SYMBOL_GPL vmlinux 0x7d55de1d __pneigh_lookup +EXPORT_SYMBOL_GPL vmlinux 0x7da8d037 marker_probe_register +EXPORT_SYMBOL_GPL vmlinux 0x7dc5d0b6 crypto_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x7e23f8ac da903x_write +EXPORT_SYMBOL_GPL vmlinux 0x7e275ea8 scsi_complete_async_scans +EXPORT_SYMBOL_GPL vmlinux 0x7e314a60 __hid_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x7e64181d usb_calc_bus_time +EXPORT_SYMBOL_GPL vmlinux 0x7e698a51 unregister_jprobes +EXPORT_SYMBOL_GPL vmlinux 0x7eca511d mmu_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x7efaaa20 __rt_mutex_init +EXPORT_SYMBOL_GPL vmlinux 0x7f19c836 unlock_policy_rwsem_write +EXPORT_SYMBOL_GPL vmlinux 0x7f3213d6 udp4_lib_lookup +EXPORT_SYMBOL_GPL vmlinux 0x7f6c283b register_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0x7f6d5bf2 usb_get_intf +EXPORT_SYMBOL_GPL vmlinux 0x7ff10ccf raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x800ea3c6 vlan_dev_real_dev +EXPORT_SYMBOL_GPL vmlinux 0x8039d043 selinux_secmark_relabel_packet_permission +EXPORT_SYMBOL_GPL vmlinux 0x803e4900 sysdev_class_register +EXPORT_SYMBOL_GPL vmlinux 0x80665428 usb_interrupt_msg +EXPORT_SYMBOL_GPL vmlinux 0x808ec1a3 crypto_alg_tested +EXPORT_SYMBOL_GPL vmlinux 0x80d067ba ata_sff_postreset +EXPORT_SYMBOL_GPL vmlinux 0x80ee55c3 selinux_secmark_refcount_inc +EXPORT_SYMBOL_GPL vmlinux 0x812c7fac hrtimer_try_to_cancel +EXPORT_SYMBOL_GPL vmlinux 0x813eade6 da903x_clr_bits +EXPORT_SYMBOL_GPL vmlinux 0x81ad0f0a inet_twsk_purge +EXPORT_SYMBOL_GPL vmlinux 0x8226642f __gpio_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x826360fd do_posix_clock_nonanosleep +EXPORT_SYMBOL_GPL vmlinux 0x8268ead4 iounmap_atomic +EXPORT_SYMBOL_GPL vmlinux 0x82703d80 preempt_notifier_unregister +EXPORT_SYMBOL_GPL vmlinux 0x82742a6b attribute_container_register +EXPORT_SYMBOL_GPL vmlinux 0x82c204d7 gpiochip_remove +EXPORT_SYMBOL_GPL vmlinux 0x82cd19f3 register_xenstore_notifier +EXPORT_SYMBOL_GPL vmlinux 0x82d79b51 sysctl_vfs_cache_pressure +EXPORT_SYMBOL_GPL vmlinux 0x82e2596c fb_deferred_io_open +EXPORT_SYMBOL_GPL vmlinux 0x82f5273b register_timer_hook +EXPORT_SYMBOL_GPL vmlinux 0x82f776b7 gpio_export +EXPORT_SYMBOL_GPL vmlinux 0x83368956 device_create +EXPORT_SYMBOL_GPL vmlinux 0x83373639 ata_sff_dma_pause +EXPORT_SYMBOL_GPL vmlinux 0x83b2e956 register_rfkill_notifier +EXPORT_SYMBOL_GPL vmlinux 0x83c2bc46 tracepoint_iter_stop +EXPORT_SYMBOL_GPL vmlinux 0x83cf1f24 class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x84834145 hrtimer_get_remaining +EXPORT_SYMBOL_GPL vmlinux 0x8486869a rtc_update_irq +EXPORT_SYMBOL_GPL vmlinux 0x848aac91 ata_sff_host_intr +EXPORT_SYMBOL_GPL vmlinux 0x85478a0b inet6_hash_frag +EXPORT_SYMBOL_GPL vmlinux 0x856361b6 xattr_getsecurity +EXPORT_SYMBOL_GPL vmlinux 0x85c10896 rcu_batches_completed_bh +EXPORT_SYMBOL_GPL vmlinux 0x85d7edfd hpet_set_periodic_freq +EXPORT_SYMBOL_GPL vmlinux 0x85e5a3db ktime_get_ts +EXPORT_SYMBOL_GPL vmlinux 0x85e738d0 inet6_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0x8646d598 tty_buffer_request_room +EXPORT_SYMBOL_GPL vmlinux 0x86623fd7 notify_remote_via_irq +EXPORT_SYMBOL_GPL vmlinux 0x867c684a setup_APIC_eilvt_ibs +EXPORT_SYMBOL_GPL vmlinux 0x868784cb __symbol_get +EXPORT_SYMBOL_GPL vmlinux 0x8696bb21 __rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x86a51007 gnttab_end_foreign_transfer +EXPORT_SYMBOL_GPL vmlinux 0x86b10394 ehci_cf_port_reset_rwsem +EXPORT_SYMBOL_GPL vmlinux 0x86b1667d hwrng_unregister +EXPORT_SYMBOL_GPL vmlinux 0x86c722f8 rfkill_epo +EXPORT_SYMBOL_GPL vmlinux 0x86e9722c hid_set_field +EXPORT_SYMBOL_GPL vmlinux 0x870404b8 crypto_chain +EXPORT_SYMBOL_GPL vmlinux 0x873fbaea edac_atomic_assert_error +EXPORT_SYMBOL_GPL vmlinux 0x876ae825 sched_setscheduler +EXPORT_SYMBOL_GPL vmlinux 0x87754115 raw_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x879f503b sata_sff_hardreset +EXPORT_SYMBOL_GPL vmlinux 0x87bbeb77 dm_rh_start_recovery +EXPORT_SYMBOL_GPL vmlinux 0x880b189a __atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x8810ad5e crypto_xor +EXPORT_SYMBOL_GPL vmlinux 0x882e0b09 regulator_bulk_get +EXPORT_SYMBOL_GPL vmlinux 0x885142a6 nf_net_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x886736fc olpc_platform_info +EXPORT_SYMBOL_GPL vmlinux 0x889e0191 isa_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x88ead3db register_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0x8984cb49 xenbus_map_ring_valloc +EXPORT_SYMBOL_GPL vmlinux 0x89bb4854 blk_execute_rq_nowait +EXPORT_SYMBOL_GPL vmlinux 0x89cc3f64 task_current_syscall +EXPORT_SYMBOL_GPL vmlinux 0x89d4dbaf usb_usual_check_type +EXPORT_SYMBOL_GPL vmlinux 0x89edb4f1 crypto_alloc_instance +EXPORT_SYMBOL_GPL vmlinux 0x8abed13d xfrm_aead_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x8acfc6c9 free_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x8b752ac1 ata_tf_to_fis +EXPORT_SYMBOL_GPL vmlinux 0x8b77eaac regulator_bulk_enable +EXPORT_SYMBOL_GPL vmlinux 0x8b9b03c4 register_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0x8be75d85 sysdev_show_ulong +EXPORT_SYMBOL_GPL vmlinux 0x8c06a108 xenbus_transaction_start +EXPORT_SYMBOL_GPL vmlinux 0x8c103671 bus_unregister +EXPORT_SYMBOL_GPL vmlinux 0x8c182e90 crypto_mod_put +EXPORT_SYMBOL_GPL vmlinux 0x8c38074a unregister_xenstore_notifier +EXPORT_SYMBOL_GPL vmlinux 0x8d314ff4 single_release_net +EXPORT_SYMBOL_GPL vmlinux 0x8d376de8 spi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x8d3fdcf6 ata_sff_exec_command +EXPORT_SYMBOL_GPL vmlinux 0x8d48ef99 mnt_want_write +EXPORT_SYMBOL_GPL vmlinux 0x8d68922d blk_trace_remove +EXPORT_SYMBOL_GPL vmlinux 0x8dbf714f inet_diag_register +EXPORT_SYMBOL_GPL vmlinux 0x8dd78d25 blocking_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x8df87d36 disk_part_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x8e9d93de pci_hp_register +EXPORT_SYMBOL_GPL vmlinux 0x8eb58c6e __wake_up_sync +EXPORT_SYMBOL_GPL vmlinux 0x8eee05b8 class_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x8f6cee77 __round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x8f951ac8 xfrm_audit_state_notfound +EXPORT_SYMBOL_GPL vmlinux 0x8f96a000 device_initialize +EXPORT_SYMBOL_GPL vmlinux 0x8fadd78b regulator_unregister +EXPORT_SYMBOL_GPL vmlinux 0x8fd4a7b7 netlink_has_listeners +EXPORT_SYMBOL_GPL vmlinux 0x8ff8dbcd blocking_notifier_chain_cond_register +EXPORT_SYMBOL_GPL vmlinux 0x9009602a acpi_bus_get_ejd +EXPORT_SYMBOL_GPL vmlinux 0x9022792a pci_restore_msi_state +EXPORT_SYMBOL_GPL vmlinux 0x90503f9d sdio_writeb +EXPORT_SYMBOL_GPL vmlinux 0x906b805e srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x907a524a ata_sff_qc_issue +EXPORT_SYMBOL_GPL vmlinux 0x90811115 device_add +EXPORT_SYMBOL_GPL vmlinux 0x909c5cd7 inotify_inode_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x90a1004a crypto_has_alg +EXPORT_SYMBOL_GPL vmlinux 0x90e62d78 device_create_file +EXPORT_SYMBOL_GPL vmlinux 0x91015b36 usb_serial_deregister +EXPORT_SYMBOL_GPL vmlinux 0x9103723a relay_close +EXPORT_SYMBOL_GPL vmlinux 0x91482eef usb_anchor_empty +EXPORT_SYMBOL_GPL vmlinux 0x9159b9d6 profile_event_register +EXPORT_SYMBOL_GPL vmlinux 0x916fcd5b regulator_put +EXPORT_SYMBOL_GPL vmlinux 0x91cdb55f __ip_route_output_key +EXPORT_SYMBOL_GPL vmlinux 0x91dacaa2 acpi_processor_ffh_cstate_probe +EXPORT_SYMBOL_GPL vmlinux 0x9241c3ee device_power_down +EXPORT_SYMBOL_GPL vmlinux 0x92445aee hrtimer_get_res +EXPORT_SYMBOL_GPL vmlinux 0x9292dd5e dm_send_uevents +EXPORT_SYMBOL_GPL vmlinux 0x92a584a6 rtc_class_close +EXPORT_SYMBOL_GPL vmlinux 0x92abc502 rtc_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x92d31cfb fixed_phy_add +EXPORT_SYMBOL_GPL vmlinux 0x92d59c97 console_drivers +EXPORT_SYMBOL_GPL vmlinux 0x92fb217b dcookie_unregister +EXPORT_SYMBOL_GPL vmlinux 0x93217c93 scsi_nl_sock +EXPORT_SYMBOL_GPL vmlinux 0x93222924 crypto_aead_setauthsize +EXPORT_SYMBOL_GPL vmlinux 0x933740ca cancel_work_sync +EXPORT_SYMBOL_GPL vmlinux 0x934c4ff2 fib_rules_unregister +EXPORT_SYMBOL_GPL vmlinux 0x934d2bb9 pci_stop_bus_device +EXPORT_SYMBOL_GPL vmlinux 0x93d2422d snmp_mib_free +EXPORT_SYMBOL_GPL vmlinux 0x942c1704 cleanup_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x948c9f67 sis_info133_for_sata +EXPORT_SYMBOL_GPL vmlinux 0x9497b58e ata_eh_analyze_ncq_error +EXPORT_SYMBOL_GPL vmlinux 0x94a68723 ata_scsi_slave_destroy +EXPORT_SYMBOL_GPL vmlinux 0x94aab897 usb_serial_generic_open +EXPORT_SYMBOL_GPL vmlinux 0x94dc62d2 ata_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x94ef4d05 cpci_hp_stop +EXPORT_SYMBOL_GPL vmlinux 0x94f53916 acpi_get_hp_params_from_firmware +EXPORT_SYMBOL_GPL vmlinux 0x950900b1 ata_sas_slave_configure +EXPORT_SYMBOL_GPL vmlinux 0x952664c5 do_exit +EXPORT_SYMBOL_GPL vmlinux 0x956a91ba gpio_get_value_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x9577271c hpet_rtc_interrupt +EXPORT_SYMBOL_GPL vmlinux 0x961a8cd3 unlock_policy_rwsem_read +EXPORT_SYMBOL_GPL vmlinux 0x964d3155 crypto_alg_lookup +EXPORT_SYMBOL_GPL vmlinux 0x9650a607 invalidate_inode_pages2 +EXPORT_SYMBOL_GPL vmlinux 0x9663390c ata_sff_freeze +EXPORT_SYMBOL_GPL vmlinux 0x9667a6c5 kobject_uevent_env +EXPORT_SYMBOL_GPL vmlinux 0x9667f36a cpufreq_register_governor +EXPORT_SYMBOL_GPL vmlinux 0x966de890 crypto_aead_type +EXPORT_SYMBOL_GPL vmlinux 0x96a0968a tty_perform_flush +EXPORT_SYMBOL_GPL vmlinux 0x96cbcf31 pm_qos_add_notifier +EXPORT_SYMBOL_GPL vmlinux 0x96d78150 sysfs_update_group +EXPORT_SYMBOL_GPL vmlinux 0x9781f43a destroy_workqueue +EXPORT_SYMBOL_GPL vmlinux 0x979d1a00 nf_register_afinfo +EXPORT_SYMBOL_GPL vmlinux 0x9833bc0c hvc_kick +EXPORT_SYMBOL_GPL vmlinux 0x9862d0e3 anon_transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x988e4bf6 driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0x98adb824 hrtimer_forward +EXPORT_SYMBOL_GPL vmlinux 0x9924c496 __usb_get_extra_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x99361f65 vlan_dev_vlan_id +EXPORT_SYMBOL_GPL vmlinux 0x995d1071 prof_on +EXPORT_SYMBOL_GPL vmlinux 0x99fceef5 bus_get_kset +EXPORT_SYMBOL_GPL vmlinux 0x99fcfb6f ata_eh_freeze_port +EXPORT_SYMBOL_GPL vmlinux 0x9a11a0fc crypto_attr_alg_name +EXPORT_SYMBOL_GPL vmlinux 0x9a199e8d sata_pmp_error_handler +EXPORT_SYMBOL_GPL vmlinux 0x9a398f5c xfrm_ealg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x9a752c07 class_dev_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x9a94bf42 crypto_givcipher_type +EXPORT_SYMBOL_GPL vmlinux 0x9aac86f8 bus_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x9ab76562 debugfs_create_u64 +EXPORT_SYMBOL_GPL vmlinux 0x9af14948 device_schedule_callback_owner +EXPORT_SYMBOL_GPL vmlinux 0x9b0a7058 attribute_container_classdev_to_container +EXPORT_SYMBOL_GPL vmlinux 0x9ba0501e unregister_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0x9bc47866 devres_remove +EXPORT_SYMBOL_GPL vmlinux 0x9bcb24a8 ip_route_output_flow +EXPORT_SYMBOL_GPL vmlinux 0x9c3d81ea __blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0x9c81ffb8 tcp_is_cwnd_limited +EXPORT_SYMBOL_GPL vmlinux 0x9cb8037b xfrm_count_enc_supported +EXPORT_SYMBOL_GPL vmlinux 0x9ccdd24a disk_map_sector_rcu +EXPORT_SYMBOL_GPL vmlinux 0x9cfef8d0 hidraw_disconnect +EXPORT_SYMBOL_GPL vmlinux 0x9d06688b register_xenbus_watch +EXPORT_SYMBOL_GPL vmlinux 0x9d1cbbf3 tcp_twsk_destructor +EXPORT_SYMBOL_GPL vmlinux 0x9d216be1 dm_set_device_limits +EXPORT_SYMBOL_GPL vmlinux 0x9d3850e1 gnttab_alloc_grant_references +EXPORT_SYMBOL_GPL vmlinux 0x9da3d828 scsi_internal_device_block +EXPORT_SYMBOL_GPL vmlinux 0x9de71d66 scsi_dh_attach +EXPORT_SYMBOL_GPL vmlinux 0x9df44dde rtnl_put_cacheinfo +EXPORT_SYMBOL_GPL vmlinux 0x9e04fbb4 skb_morph +EXPORT_SYMBOL_GPL vmlinux 0x9e711ad2 pm_qos_requirement +EXPORT_SYMBOL_GPL vmlinux 0x9e7b7952 hrtimer_start +EXPORT_SYMBOL_GPL vmlinux 0x9e7d3442 xenbus_resume +EXPORT_SYMBOL_GPL vmlinux 0x9ea3f8ce ata_bmdma_mode_filter +EXPORT_SYMBOL_GPL vmlinux 0x9ebd7969 ata_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0x9f289bb1 usb_get_dev +EXPORT_SYMBOL_GPL vmlinux 0x9f4ec080 ata_pci_sff_init_host +EXPORT_SYMBOL_GPL vmlinux 0x9f837700 preempt_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x9fce80db fb_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x9fd32062 firmware_kobj +EXPORT_SYMBOL_GPL vmlinux 0x9fdde5dc dm_rh_stop_recovery +EXPORT_SYMBOL_GPL vmlinux 0x9fdf171f platform_device_add_data +EXPORT_SYMBOL_GPL vmlinux 0xa00eae4f ip6_dst_lookup +EXPORT_SYMBOL_GPL vmlinux 0xa00f3e4c cpufreq_frequency_table_verify +EXPORT_SYMBOL_GPL vmlinux 0xa0255440 net_ipv4_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0xa0492faf sysfs_notify_dirent +EXPORT_SYMBOL_GPL vmlinux 0xa081f561 usb_set_interface +EXPORT_SYMBOL_GPL vmlinux 0xa0ffe0e2 inet6_sk_rebuild_header +EXPORT_SYMBOL_GPL vmlinux 0xa1596d98 acpi_processor_ffh_cstate_enter +EXPORT_SYMBOL_GPL vmlinux 0xa199f61c ata_std_qc_defer +EXPORT_SYMBOL_GPL vmlinux 0xa1ab3866 cpuidle_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0xa1f14844 disk_get_part +EXPORT_SYMBOL_GPL vmlinux 0xa236b8d3 inet6_destroy_sock +EXPORT_SYMBOL_GPL vmlinux 0xa242e739 ata_sff_prereset +EXPORT_SYMBOL_GPL vmlinux 0xa28d8527 usb_poison_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xa29742ba sdio_claim_irq +EXPORT_SYMBOL_GPL vmlinux 0xa2c03841 bind_evtchn_to_irqhandler +EXPORT_SYMBOL_GPL vmlinux 0xa2e67f08 acpi_bus_generate_proc_event4 +EXPORT_SYMBOL_GPL vmlinux 0xa2ef8778 sdio_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0xa3064c2e scsi_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0xa32f41f2 gpiochip_is_requested +EXPORT_SYMBOL_GPL vmlinux 0xa353fffc xenbus_rm +EXPORT_SYMBOL_GPL vmlinux 0xa36c50d3 usb_deregister_device_driver +EXPORT_SYMBOL_GPL vmlinux 0xa3e63fbe scsi_nl_add_driver +EXPORT_SYMBOL_GPL vmlinux 0xa3fc96f0 marker_probe_cb_noarg +EXPORT_SYMBOL_GPL vmlinux 0xa400b0e5 inet_twsk_put +EXPORT_SYMBOL_GPL vmlinux 0xa40b5c4a ata_bmdma_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xa41644cd regulator_set_mode +EXPORT_SYMBOL_GPL vmlinux 0xa452c297 hpet_mask_rtc_irq_bit +EXPORT_SYMBOL_GPL vmlinux 0xa4857100 bus_find_device +EXPORT_SYMBOL_GPL vmlinux 0xa495fee5 crypto_spawn_tfm +EXPORT_SYMBOL_GPL vmlinux 0xa4b0521a scsi_dh_activate +EXPORT_SYMBOL_GPL vmlinux 0xa4efb3c9 ata_sff_tf_read +EXPORT_SYMBOL_GPL vmlinux 0xa50352f4 __sock_recv_timestamp +EXPORT_SYMBOL_GPL vmlinux 0xa543c3a4 unregister_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0xa58c57b6 ata_sas_port_destroy +EXPORT_SYMBOL_GPL vmlinux 0xa59db0f8 md_new_event +EXPORT_SYMBOL_GPL vmlinux 0xa5bf5c3e pm_qos_add_requirement +EXPORT_SYMBOL_GPL vmlinux 0xa5c36cec inotify_unmount_inodes +EXPORT_SYMBOL_GPL vmlinux 0xa5f66099 platform_device_add_resources +EXPORT_SYMBOL_GPL vmlinux 0xa6196f6e tcp_get_info +EXPORT_SYMBOL_GPL vmlinux 0xa64ccd3d pv_apic_ops +EXPORT_SYMBOL_GPL vmlinux 0xa65e66c6 sock_prot_inuse_add +EXPORT_SYMBOL_GPL vmlinux 0xa669f63c ata_host_alloc_pinfo +EXPORT_SYMBOL_GPL vmlinux 0xa6f4320d unregister_rfkill_notifier +EXPORT_SYMBOL_GPL vmlinux 0xa789e515 sysdev_show_int +EXPORT_SYMBOL_GPL vmlinux 0xa78a073b sysdev_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xa7e4734f put_driver +EXPORT_SYMBOL_GPL vmlinux 0xa80fcdb7 sysdev_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0xa827a8e6 ata_sff_dev_select +EXPORT_SYMBOL_GPL vmlinux 0xa8305e11 device_rename +EXPORT_SYMBOL_GPL vmlinux 0xa83cd13e pci_destroy_slot +EXPORT_SYMBOL_GPL vmlinux 0xa8f59416 gpio_direction_output +EXPORT_SYMBOL_GPL vmlinux 0xa9126bff hpet_set_rtc_irq_bit +EXPORT_SYMBOL_GPL vmlinux 0xa920db97 da903x_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0xa956a362 register_jprobe +EXPORT_SYMBOL_GPL vmlinux 0xa963f49c tcp_orphan_count +EXPORT_SYMBOL_GPL vmlinux 0xa9b7afd8 wmi_set_block +EXPORT_SYMBOL_GPL vmlinux 0xa9c530b8 unregister_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xa9e50ae8 tcp_init_congestion_ops +EXPORT_SYMBOL_GPL vmlinux 0xa9fa7f16 ata_eh_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0xaa0ff5b1 inet_twsk_alloc +EXPORT_SYMBOL_GPL vmlinux 0xaa2a72bf __iowrite64_copy +EXPORT_SYMBOL_GPL vmlinux 0xaa8c4696 cpu_clock +EXPORT_SYMBOL_GPL vmlinux 0xaac33651 sysfs_schedule_callback +EXPORT_SYMBOL_GPL vmlinux 0xaada3825 rtc_irq_unregister +EXPORT_SYMBOL_GPL vmlinux 0xaafec277 inet_csk_get_port +EXPORT_SYMBOL_GPL vmlinux 0xab01acbe gnttab_request_free_callback +EXPORT_SYMBOL_GPL vmlinux 0xab24e132 securityfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0xab57e311 tracepoint_probe_register +EXPORT_SYMBOL_GPL vmlinux 0xab6eac9d usb_buffer_unmap_sg +EXPORT_SYMBOL_GPL vmlinux 0xab913902 crypto_drop_spawn +EXPORT_SYMBOL_GPL vmlinux 0xabe5f8e7 usb_hcd_pci_suspend +EXPORT_SYMBOL_GPL vmlinux 0xac0292be blocking_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0xac2e6ad7 ata_do_dev_read_id +EXPORT_SYMBOL_GPL vmlinux 0xac7a2398 hid_allocate_device +EXPORT_SYMBOL_GPL vmlinux 0xacb301a6 class_find_device +EXPORT_SYMBOL_GPL vmlinux 0xacc19485 ibft_addr +EXPORT_SYMBOL_GPL vmlinux 0xaccfc678 cpu_bit_bitmap +EXPORT_SYMBOL_GPL vmlinux 0xacde2487 dm_device_name +EXPORT_SYMBOL_GPL vmlinux 0xace5c0fc usb_bus_list +EXPORT_SYMBOL_GPL vmlinux 0xace80105 ata_sff_data_xfer_noirq +EXPORT_SYMBOL_GPL vmlinux 0xad096363 xenbus_printf +EXPORT_SYMBOL_GPL vmlinux 0xad971dc7 md_do_sync +EXPORT_SYMBOL_GPL vmlinux 0xada3a5f6 ata_sff_softreset +EXPORT_SYMBOL_GPL vmlinux 0xae0c87ee pm_qos_remove_notifier +EXPORT_SYMBOL_GPL vmlinux 0xae45356a sysdev_store_int +EXPORT_SYMBOL_GPL vmlinux 0xae52fdd0 fb_deferred_io_cleanup +EXPORT_SYMBOL_GPL vmlinux 0xaeaa885b ata_host_resume +EXPORT_SYMBOL_GPL vmlinux 0xaeb7f977 __blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xaebff904 usb_get_status +EXPORT_SYMBOL_GPL vmlinux 0xaf01744c debugfs_create_symlink +EXPORT_SYMBOL_GPL vmlinux 0xaf05ca8a dev_attr_unload_heads +EXPORT_SYMBOL_GPL vmlinux 0xaf06545e crypto_alg_mod_lookup +EXPORT_SYMBOL_GPL vmlinux 0xaf1145b3 sata_pmp_qc_defer_cmd_switch +EXPORT_SYMBOL_GPL vmlinux 0xaf1b424c usb_buffer_alloc +EXPORT_SYMBOL_GPL vmlinux 0xaf906517 tty_prepare_flip_string_flags +EXPORT_SYMBOL_GPL vmlinux 0xafa55c34 regulator_set_current_limit +EXPORT_SYMBOL_GPL vmlinux 0xafc7c996 usb_unlink_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xafcd70bd ata_sff_wait_ready +EXPORT_SYMBOL_GPL vmlinux 0xafdabc24 usb_reset_device +EXPORT_SYMBOL_GPL vmlinux 0xafe61f03 ata_sff_data_xfer +EXPORT_SYMBOL_GPL vmlinux 0xb0aa812e fips_enabled +EXPORT_SYMBOL_GPL vmlinux 0xb0ab9f8c flush_work +EXPORT_SYMBOL_GPL vmlinux 0xb0ce4d77 inotify_find_watch +EXPORT_SYMBOL_GPL vmlinux 0xb0eedea9 usb_wait_anchor_empty_timeout +EXPORT_SYMBOL_GPL vmlinux 0xb106233c debugfs_create_u32 +EXPORT_SYMBOL_GPL vmlinux 0xb10d55bc cn_netlink_send +EXPORT_SYMBOL_GPL vmlinux 0xb127837a lookup_instantiate_filp +EXPORT_SYMBOL_GPL vmlinux 0xb12794a8 class_interface_register +EXPORT_SYMBOL_GPL vmlinux 0xb1643813 get_current_tty +EXPORT_SYMBOL_GPL vmlinux 0xb1acbcce rcu_barrier_sched +EXPORT_SYMBOL_GPL vmlinux 0xb1ca9b10 tcp_unregister_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0xb27005f5 device_suspend +EXPORT_SYMBOL_GPL vmlinux 0xb293ad27 dm_rh_region_context +EXPORT_SYMBOL_GPL vmlinux 0xb313a59e unregister_kprobe +EXPORT_SYMBOL_GPL vmlinux 0xb315e198 dm_rh_get_region_key +EXPORT_SYMBOL_GPL vmlinux 0xb3253ed9 hpet_rtc_timer_init +EXPORT_SYMBOL_GPL vmlinux 0xb3273be1 usb_alloc_urb +EXPORT_SYMBOL_GPL vmlinux 0xb32edb10 do_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0xb33585bf debugfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0xb37d7544 class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xb3d5e527 acpi_smbus_write +EXPORT_SYMBOL_GPL vmlinux 0xb406434b ata_cable_80wire +EXPORT_SYMBOL_GPL vmlinux 0xb413a2d3 ata_sas_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0xb41cb079 mm_kobj +EXPORT_SYMBOL_GPL vmlinux 0xb445b138 __create_workqueue_key +EXPORT_SYMBOL_GPL vmlinux 0xb4606374 scsi_execute_async +EXPORT_SYMBOL_GPL vmlinux 0xb476fbc1 cpufreq_frequency_table_cpuinfo +EXPORT_SYMBOL_GPL vmlinux 0xb4869af7 regulator_get_current_limit +EXPORT_SYMBOL_GPL vmlinux 0xb4e14553 gnttab_query_foreign_access +EXPORT_SYMBOL_GPL vmlinux 0xb4ea7cf7 kgdb_connected +EXPORT_SYMBOL_GPL vmlinux 0xb4f6e301 ata_std_bios_param +EXPORT_SYMBOL_GPL vmlinux 0xb51fbd64 edac_op_state +EXPORT_SYMBOL_GPL vmlinux 0xb53ae573 cpu_idle_wait +EXPORT_SYMBOL_GPL vmlinux 0xb5428d03 dm_rh_recovery_end +EXPORT_SYMBOL_GPL vmlinux 0xb5a6ebe2 wmi_remove_notify_handler +EXPORT_SYMBOL_GPL vmlinux 0xb5b26283 tty_ldisc_ref +EXPORT_SYMBOL_GPL vmlinux 0xb61cb94e mmput +EXPORT_SYMBOL_GPL vmlinux 0xb6230f1f gnttab_grant_foreign_access +EXPORT_SYMBOL_GPL vmlinux 0xb63550f5 __i2c_board_lock +EXPORT_SYMBOL_GPL vmlinux 0xb65091b3 selinux_secmark_refcount_dec +EXPORT_SYMBOL_GPL vmlinux 0xb6aeb661 ata_id_c_string +EXPORT_SYMBOL_GPL vmlinux 0xb6bc49a9 __supported_pte_mask +EXPORT_SYMBOL_GPL vmlinux 0xb6fdd557 simple_attr_read +EXPORT_SYMBOL_GPL vmlinux 0xb74d5a1a xfrm_audit_state_delete +EXPORT_SYMBOL_GPL vmlinux 0xb78c53d6 unregister_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0xb7ba6928 driver_create_file +EXPORT_SYMBOL_GPL vmlinux 0xb7d7c12e hpet_set_alarm_time +EXPORT_SYMBOL_GPL vmlinux 0xb806da8f vfs_setxattr +EXPORT_SYMBOL_GPL vmlinux 0xb8441bc1 skb_partial_csum_set +EXPORT_SYMBOL_GPL vmlinux 0xb903674c scatterwalk_map_and_copy +EXPORT_SYMBOL_GPL vmlinux 0xb99cfecf regulator_set_drvdata +EXPORT_SYMBOL_GPL vmlinux 0xb99d5837 xenbus_read +EXPORT_SYMBOL_GPL vmlinux 0xb9eb3aa9 add_uevent_var +EXPORT_SYMBOL_GPL vmlinux 0xba29cb85 uart_console_write +EXPORT_SYMBOL_GPL vmlinux 0xba356aa7 devres_alloc +EXPORT_SYMBOL_GPL vmlinux 0xba698916 __percpu_alloc_mask +EXPORT_SYMBOL_GPL vmlinux 0xbaa219a7 sysfs_get_dirent +EXPORT_SYMBOL_GPL vmlinux 0xbab22f79 skb_icv_walk +EXPORT_SYMBOL_GPL vmlinux 0xbae34c27 scsi_nl_remove_transport +EXPORT_SYMBOL_GPL vmlinux 0xbb60dc29 inet6_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0xbb7a4c4f sata_link_debounce +EXPORT_SYMBOL_GPL vmlinux 0xbba21e56 inet6_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0xbbb98859 edid_info +EXPORT_SYMBOL_GPL vmlinux 0xbc26cbc4 pci_intx +EXPORT_SYMBOL_GPL vmlinux 0xbc38ac10 skcipher_geniv_free +EXPORT_SYMBOL_GPL vmlinux 0xbc6ee384 dev_attr_link_power_management_policy +EXPORT_SYMBOL_GPL vmlinux 0xbc95c62d usb_hcd_pci_resume +EXPORT_SYMBOL_GPL vmlinux 0xbc9a4533 led_trigger_event +EXPORT_SYMBOL_GPL vmlinux 0xbd273d59 platform_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xbd506a46 unregister_hotplug_dock_device +EXPORT_SYMBOL_GPL vmlinux 0xbd897b97 usb_create_hcd +EXPORT_SYMBOL_GPL vmlinux 0xbdbe66c5 sdio_release_host +EXPORT_SYMBOL_GPL vmlinux 0xbdcce1b1 register_kprobe +EXPORT_SYMBOL_GPL vmlinux 0xbdd295f0 trace_vprintk +EXPORT_SYMBOL_GPL vmlinux 0xbe1887e4 ata_unpack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xbe2a6779 iomap_atomic_prot_pfn +EXPORT_SYMBOL_GPL vmlinux 0xbe316ab8 ata_sff_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0xbe413599 tracepoint_iter_start +EXPORT_SYMBOL_GPL vmlinux 0xbe53a254 regulator_set_voltage +EXPORT_SYMBOL_GPL vmlinux 0xbe83b34b __inet_inherit_port +EXPORT_SYMBOL_GPL vmlinux 0xbf0b5d53 dm_rh_recovery_prepare +EXPORT_SYMBOL_GPL vmlinux 0xbf39695a ata_dummy_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xbf6b95ea hvc_alloc +EXPORT_SYMBOL_GPL vmlinux 0xbf6f6a00 ata_sff_pause +EXPORT_SYMBOL_GPL vmlinux 0xbfa415bc spi_unregister_master +EXPORT_SYMBOL_GPL vmlinux 0xbfac7ca5 sysfs_remove_file_from_group +EXPORT_SYMBOL_GPL vmlinux 0xbfcc73aa cpuidle_unregister_device +EXPORT_SYMBOL_GPL vmlinux 0xbfd4da78 transport_setup_device +EXPORT_SYMBOL_GPL vmlinux 0xc02c4392 security_inode_setattr +EXPORT_SYMBOL_GPL vmlinux 0xc0614436 usb_hcd_poll_rh_status +EXPORT_SYMBOL_GPL vmlinux 0xc069ce45 crypto_shoot_alg +EXPORT_SYMBOL_GPL vmlinux 0xc099b023 __mmdrop +EXPORT_SYMBOL_GPL vmlinux 0xc0a261c0 platform_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc0b268ea regulator_get +EXPORT_SYMBOL_GPL vmlinux 0xc1193db9 attribute_container_find_class_device +EXPORT_SYMBOL_GPL vmlinux 0xc17515d7 usb_hcds_loaded +EXPORT_SYMBOL_GPL vmlinux 0xc1b9670d leds_list_lock +EXPORT_SYMBOL_GPL vmlinux 0xc1ea9ebd page_mkclean +EXPORT_SYMBOL_GPL vmlinux 0xc1f9f65e mnt_drop_write +EXPORT_SYMBOL_GPL vmlinux 0xc22a3091 vm_unmap_aliases +EXPORT_SYMBOL_GPL vmlinux 0xc248bb31 ip6_dst_blackhole +EXPORT_SYMBOL_GPL vmlinux 0xc26351f8 bind_evtchn_to_irq +EXPORT_SYMBOL_GPL vmlinux 0xc26ec1c0 platform_get_irq_byname +EXPORT_SYMBOL_GPL vmlinux 0xc27c3305 vfs_getxattr +EXPORT_SYMBOL_GPL vmlinux 0xc34efe27 snmp_fold_field +EXPORT_SYMBOL_GPL vmlinux 0xc364cbd7 kobject_init_and_add +EXPORT_SYMBOL_GPL vmlinux 0xc36f1a72 regulator_get_voltage +EXPORT_SYMBOL_GPL vmlinux 0xc399468f scsi_nl_remove_driver +EXPORT_SYMBOL_GPL vmlinux 0xc40744d5 pciserial_suspend_ports +EXPORT_SYMBOL_GPL vmlinux 0xc428068d sata_deb_timing_long +EXPORT_SYMBOL_GPL vmlinux 0xc42f2f94 xenbus_read_driver_state +EXPORT_SYMBOL_GPL vmlinux 0xc48b7ccf ata_mode_string +EXPORT_SYMBOL_GPL vmlinux 0xc4b33aa6 tracepoint_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc4b3475e ata_do_set_mode +EXPORT_SYMBOL_GPL vmlinux 0xc4c32c13 dev_attr_em_message_type +EXPORT_SYMBOL_GPL vmlinux 0xc4c552d7 stop_machine +EXPORT_SYMBOL_GPL vmlinux 0xc4f3caf5 posix_timer_event +EXPORT_SYMBOL_GPL vmlinux 0xc5397da6 xenbus_mkdir +EXPORT_SYMBOL_GPL vmlinux 0xc569e712 tty_ldisc_ref_wait +EXPORT_SYMBOL_GPL vmlinux 0xc57b8beb inet_diag_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc5b83f66 devres_remove_group +EXPORT_SYMBOL_GPL vmlinux 0xc5c23d62 sysfs_put +EXPORT_SYMBOL_GPL vmlinux 0xc5e3dddf wmi_get_event_data +EXPORT_SYMBOL_GPL vmlinux 0xc62bc247 usb_serial_disconnect +EXPORT_SYMBOL_GPL vmlinux 0xc63f43c7 spi_write_then_read +EXPORT_SYMBOL_GPL vmlinux 0xc6730fc2 klist_iter_init +EXPORT_SYMBOL_GPL vmlinux 0xc673e23e ata_scsi_change_queue_depth +EXPORT_SYMBOL_GPL vmlinux 0xc6f8b68e blkcipher_walk_phys +EXPORT_SYMBOL_GPL vmlinux 0xc7504484 tracepoint_get_iter_range +EXPORT_SYMBOL_GPL vmlinux 0xc751c582 spi_add_device +EXPORT_SYMBOL_GPL vmlinux 0xc76a7130 scsi_dh_detach +EXPORT_SYMBOL_GPL vmlinux 0xc798da2f usb_hcd_pci_shutdown +EXPORT_SYMBOL_GPL vmlinux 0xc7a488a7 raw_unhash_sk +EXPORT_SYMBOL_GPL vmlinux 0xc7ec11f6 atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xc8227061 rt_mutex_destroy +EXPORT_SYMBOL_GPL vmlinux 0xc868733d relay_subbufs_consumed +EXPORT_SYMBOL_GPL vmlinux 0xc869a978 d_materialise_unique +EXPORT_SYMBOL_GPL vmlinux 0xc87c1f84 ktime_get +EXPORT_SYMBOL_GPL vmlinux 0xc87e487a sched_clock_idle_sleep_event +EXPORT_SYMBOL_GPL vmlinux 0xc917dc12 drop_file_write_access +EXPORT_SYMBOL_GPL vmlinux 0xc9561772 fb_destroy_modelist +EXPORT_SYMBOL_GPL vmlinux 0xc9a17225 mmu_notifier_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc9d4d6d1 wmi_has_guid +EXPORT_SYMBOL_GPL vmlinux 0xc9e37865 isa_register_driver +EXPORT_SYMBOL_GPL vmlinux 0xca81ea9a xenbus_transaction_end +EXPORT_SYMBOL_GPL vmlinux 0xca874e7f raw_seq_start +EXPORT_SYMBOL_GPL vmlinux 0xca96924b ata_cable_unknown +EXPORT_SYMBOL_GPL vmlinux 0xcaa4abea xenbus_watch_pathfmt +EXPORT_SYMBOL_GPL vmlinux 0xcabe04de cpuidle_resume_and_unlock +EXPORT_SYMBOL_GPL vmlinux 0xcb0ddf1b register_net_sysctl_rotable +EXPORT_SYMBOL_GPL vmlinux 0xcb155698 skcipher_geniv_alloc +EXPORT_SYMBOL_GPL vmlinux 0xcb55321f ata_host_alloc +EXPORT_SYMBOL_GPL vmlinux 0xcb6cea8e sync_page_io +EXPORT_SYMBOL_GPL vmlinux 0xcb88c4e9 cpufreq_cpu_get +EXPORT_SYMBOL_GPL vmlinux 0xcbafb1cb ata_bmdma_status +EXPORT_SYMBOL_GPL vmlinux 0xcbb40d2f dm_rh_dec +EXPORT_SYMBOL_GPL vmlinux 0xcbb48c4e inet_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0xcbfab04e ata_scsi_simulate +EXPORT_SYMBOL_GPL vmlinux 0xcc1f1c3d inet_twdr_hangman +EXPORT_SYMBOL_GPL vmlinux 0xcc6ab305 is_dock_device +EXPORT_SYMBOL_GPL vmlinux 0xcccfb2fa sata_deb_timing_hotplug +EXPORT_SYMBOL_GPL vmlinux 0xcce2e553 ata_sff_check_status +EXPORT_SYMBOL_GPL vmlinux 0xcd06d369 kill_pid_info_as_uid +EXPORT_SYMBOL_GPL vmlinux 0xcd42feed __inet_hash_nolisten +EXPORT_SYMBOL_GPL vmlinux 0xcd43d3b4 crypto_lookup_template +EXPORT_SYMBOL_GPL vmlinux 0xcd7aefa7 map_vm_area +EXPORT_SYMBOL_GPL vmlinux 0xcd7ecbc2 inet6_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0xcd9991a9 usb_usual_set_present +EXPORT_SYMBOL_GPL vmlinux 0xcdb4faa1 platform_device_register_simple +EXPORT_SYMBOL_GPL vmlinux 0xcdca3691 nr_irqs +EXPORT_SYMBOL_GPL vmlinux 0xcdd6550e register_kprobes +EXPORT_SYMBOL_GPL vmlinux 0xce04a978 ata_sff_error_handler +EXPORT_SYMBOL_GPL vmlinux 0xce4aa154 bus_sort_breadthfirst +EXPORT_SYMBOL_GPL vmlinux 0xce54bfb5 tty_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0xce6022e1 get_task_mm +EXPORT_SYMBOL_GPL vmlinux 0xceb06d36 device_register +EXPORT_SYMBOL_GPL vmlinux 0xcee44482 sysdev_store_ulong +EXPORT_SYMBOL_GPL vmlinux 0xcf0bfd12 start_thread +EXPORT_SYMBOL_GPL vmlinux 0xcf16b474 debugfs_create_blob +EXPORT_SYMBOL_GPL vmlinux 0xcf82bff5 power_supply_class +EXPORT_SYMBOL_GPL vmlinux 0xcfcc83ad register_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0xd00a38c9 ip6_sk_dst_lookup +EXPORT_SYMBOL_GPL vmlinux 0xd027a07d marker_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xd03c7700 secure_ipv4_port_ephemeral +EXPORT_SYMBOL_GPL vmlinux 0xd0c05159 emergency_restart +EXPORT_SYMBOL_GPL vmlinux 0xd0d342a1 smp_ops +EXPORT_SYMBOL_GPL vmlinux 0xd0dc1a83 usb_autopm_put_interface +EXPORT_SYMBOL_GPL vmlinux 0xd0de4e51 device_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xd1019d54 inet_csk_listen_start +EXPORT_SYMBOL_GPL vmlinux 0xd12461f2 cpci_hp_unregister_bus +EXPORT_SYMBOL_GPL vmlinux 0xd12ac59b olpc_ec_cmd +EXPORT_SYMBOL_GPL vmlinux 0xd16712f3 crypto_check_attr_type +EXPORT_SYMBOL_GPL vmlinux 0xd2038761 hidinput_report_event +EXPORT_SYMBOL_GPL vmlinux 0xd22eec85 platform_get_resource_byname +EXPORT_SYMBOL_GPL vmlinux 0xd231c2fa hid_report_raw_event +EXPORT_SYMBOL_GPL vmlinux 0xd23da1be xenbus_dev_error +EXPORT_SYMBOL_GPL vmlinux 0xd24da1cb transport_add_device +EXPORT_SYMBOL_GPL vmlinux 0xd259f625 vfs_listxattr +EXPORT_SYMBOL_GPL vmlinux 0xd2633917 __cpufreq_driver_target +EXPORT_SYMBOL_GPL vmlinux 0xd273b1b1 __round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xd27d2d95 kobject_rename +EXPORT_SYMBOL_GPL vmlinux 0xd2853d81 blk_set_cmd_filter_defaults +EXPORT_SYMBOL_GPL vmlinux 0xd29f8ff1 rtc_set_mmss +EXPORT_SYMBOL_GPL vmlinux 0xd2a8caf0 work_on_cpu +EXPORT_SYMBOL_GPL vmlinux 0xd30d273c macvlan_handle_frame_hook +EXPORT_SYMBOL_GPL vmlinux 0xd35276d2 audit_log_d_path +EXPORT_SYMBOL_GPL vmlinux 0xd383e979 sata_scr_valid +EXPORT_SYMBOL_GPL vmlinux 0xd3b78da3 xenbus_suspend_cancel +EXPORT_SYMBOL_GPL vmlinux 0xd4605677 devres_add +EXPORT_SYMBOL_GPL vmlinux 0xd46935a0 scsi_eh_ready_devs +EXPORT_SYMBOL_GPL vmlinux 0xd47eb245 sdio_align_size +EXPORT_SYMBOL_GPL vmlinux 0xd494ee54 speedstep_get_freqs +EXPORT_SYMBOL_GPL vmlinux 0xd4a1c453 cpci_hp_register_bus +EXPORT_SYMBOL_GPL vmlinux 0xd5c89fee register_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0xd5cfdba7 dm_rh_mark_nosync +EXPORT_SYMBOL_GPL vmlinux 0xd5dcccd2 dm_rh_flush +EXPORT_SYMBOL_GPL vmlinux 0xd680e49c device_reprobe +EXPORT_SYMBOL_GPL vmlinux 0xd6980e67 bdi_writeout_inc +EXPORT_SYMBOL_GPL vmlinux 0xd69e72ca fixed_phy_set_link_update +EXPORT_SYMBOL_GPL vmlinux 0xd6d13de7 sata_std_hardreset +EXPORT_SYMBOL_GPL vmlinux 0xd6eb74a7 led_trigger_register_simple +EXPORT_SYMBOL_GPL vmlinux 0xd7564b77 input_ff_erase +EXPORT_SYMBOL_GPL vmlinux 0xd77b4b55 hid_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0xd7d79132 put_online_cpus +EXPORT_SYMBOL_GPL vmlinux 0xd817721f usb_deregister +EXPORT_SYMBOL_GPL vmlinux 0xd83242e6 sysfs_remove_group +EXPORT_SYMBOL_GPL vmlinux 0xd84cd7f4 ata_timing_find_mode +EXPORT_SYMBOL_GPL vmlinux 0xd8606d92 ata_port_disable +EXPORT_SYMBOL_GPL vmlinux 0xd8cc1326 bd_release_from_disk +EXPORT_SYMBOL_GPL vmlinux 0xd8f7b32f queue_work_on +EXPORT_SYMBOL_GPL vmlinux 0xd9042fa8 scatterwalk_map +EXPORT_SYMBOL_GPL vmlinux 0xd951a804 sysdev_class_create_file +EXPORT_SYMBOL_GPL vmlinux 0xd9c0e86d ata_slave_link_init +EXPORT_SYMBOL_GPL vmlinux 0xd9c22624 usb_remove_hcd +EXPORT_SYMBOL_GPL vmlinux 0xda11cb03 rdev_get_dev +EXPORT_SYMBOL_GPL vmlinux 0xda88e772 ip_local_out +EXPORT_SYMBOL_GPL vmlinux 0xda9a27d1 led_trigger_unregister_simple +EXPORT_SYMBOL_GPL vmlinux 0xdaf4dfb3 fb_mode_option +EXPORT_SYMBOL_GPL vmlinux 0xdb0ff973 tcp_slow_start +EXPORT_SYMBOL_GPL vmlinux 0xdba8f376 kernel_kobj +EXPORT_SYMBOL_GPL vmlinux 0xdbab20fb cpufreq_register_driver +EXPORT_SYMBOL_GPL vmlinux 0xdbb19520 da903x_set_bits +EXPORT_SYMBOL_GPL vmlinux 0xdbb763b8 proc_net_mkdir +EXPORT_SYMBOL_GPL vmlinux 0xdc4e7888 cpufreq_unregister_governor +EXPORT_SYMBOL_GPL vmlinux 0xdc4f3fde rtnl_kill_links +EXPORT_SYMBOL_GPL vmlinux 0xdc8def51 pci_execute_reset_function +EXPORT_SYMBOL_GPL vmlinux 0xdcd8ad65 copy_fs_struct +EXPORT_SYMBOL_GPL vmlinux 0xdce73312 vfs_removexattr +EXPORT_SYMBOL_GPL vmlinux 0xdcf9ac96 crypto_hash_type +EXPORT_SYMBOL_GPL vmlinux 0xdd0901cb pci_bus_max_busnr +EXPORT_SYMBOL_GPL vmlinux 0xdd5c4942 srcu_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0xdd9e2cda tcp_set_state +EXPORT_SYMBOL_GPL vmlinux 0xddac0b06 dm_region_hash_create +EXPORT_SYMBOL_GPL vmlinux 0xddd8b5e9 attribute_container_unregister +EXPORT_SYMBOL_GPL vmlinux 0xde0ba4f6 ata_pio_need_iordy +EXPORT_SYMBOL_GPL vmlinux 0xde134c69 storage_usb_ids +EXPORT_SYMBOL_GPL vmlinux 0xde29534f ipv6_find_tlv +EXPORT_SYMBOL_GPL vmlinux 0xde4b43b3 spi_alloc_device +EXPORT_SYMBOL_GPL vmlinux 0xde9ba900 crypto_blkcipher_type +EXPORT_SYMBOL_GPL vmlinux 0xded3706d ata_sff_qc_fill_rtf +EXPORT_SYMBOL_GPL vmlinux 0xdf3022b2 ata_sff_interrupt +EXPORT_SYMBOL_GPL vmlinux 0xdf3c19ec cn_add_callback +EXPORT_SYMBOL_GPL vmlinux 0xdf612b16 __blkdev_driver_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xdffaa1db spi_sync +EXPORT_SYMBOL_GPL vmlinux 0xe0205574 net_assign_generic +EXPORT_SYMBOL_GPL vmlinux 0xe0406b5a blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xe17a2796 cpufreq_cpu_put +EXPORT_SYMBOL_GPL vmlinux 0xe19a43a1 inet6_csk_xmit +EXPORT_SYMBOL_GPL vmlinux 0xe1c813d9 led_trigger_set +EXPORT_SYMBOL_GPL vmlinux 0xe231fe27 sysfs_notify +EXPORT_SYMBOL_GPL vmlinux 0xe2426710 wmi_evaluate_method +EXPORT_SYMBOL_GPL vmlinux 0xe28c6025 blk_end_bidi_request +EXPORT_SYMBOL_GPL vmlinux 0xe295c0ff is_hpet_enabled +EXPORT_SYMBOL_GPL vmlinux 0xe2a46486 tcp_death_row +EXPORT_SYMBOL_GPL vmlinux 0xe2e7c4ba crypto_larval_kill +EXPORT_SYMBOL_GPL vmlinux 0xe341cd5f audit_log_untrustedstring +EXPORT_SYMBOL_GPL vmlinux 0xe3846ed1 kset_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0xe3c5e3c1 queue_delayed_work_on +EXPORT_SYMBOL_GPL vmlinux 0xe3d8a0e0 usb_store_new_id +EXPORT_SYMBOL_GPL vmlinux 0xe402a403 usb_put_dev +EXPORT_SYMBOL_GPL vmlinux 0xe42664f5 ata_port_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0xe4426555 md_allow_write +EXPORT_SYMBOL_GPL vmlinux 0xe48d5eac acpi_ec_add_query_handler +EXPORT_SYMBOL_GPL vmlinux 0xe49ff3b0 ata_wait_register +EXPORT_SYMBOL_GPL vmlinux 0xe4c331b6 acpi_os_unmap_memory +EXPORT_SYMBOL_GPL vmlinux 0xe4caca89 get_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0xe4cb99e2 crypto_hash_walk_done +EXPORT_SYMBOL_GPL vmlinux 0xe513afc0 cache_k8_northbridges +EXPORT_SYMBOL_GPL vmlinux 0xe530071c pm_qos_remove_requirement +EXPORT_SYMBOL_GPL vmlinux 0xe55bb129 dm_rh_dirty_log +EXPORT_SYMBOL_GPL vmlinux 0xe5b7c9a6 dm_noflush_suspending +EXPORT_SYMBOL_GPL vmlinux 0xe5cf19fb rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0xe602862e init_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0xe61a6d2f gpio_unexport +EXPORT_SYMBOL_GPL vmlinux 0xe6488b47 cpufreq_notify_transition +EXPORT_SYMBOL_GPL vmlinux 0xe674a5cb srcu_read_lock +EXPORT_SYMBOL_GPL vmlinux 0xe69fa847 debugfs_remove +EXPORT_SYMBOL_GPL vmlinux 0xe6ae44a7 usb_hcd_giveback_urb +EXPORT_SYMBOL_GPL vmlinux 0xe6b84dbf ata_host_activate +EXPORT_SYMBOL_GPL vmlinux 0xe6be8291 i2c_new_dummy +EXPORT_SYMBOL_GPL vmlinux 0xe721e9e9 sg_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xe7241ff0 usb_mon_register +EXPORT_SYMBOL_GPL vmlinux 0xe776c324 ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0xe79e62de debugfs_remove_recursive +EXPORT_SYMBOL_GPL vmlinux 0xe7a6e174 kobject_get_path +EXPORT_SYMBOL_GPL vmlinux 0xe7fa47ad srcu_read_unlock +EXPORT_SYMBOL_GPL vmlinux 0xe8061bbb ata_sas_port_start +EXPORT_SYMBOL_GPL vmlinux 0xe9098eb1 usb_ifnum_to_if +EXPORT_SYMBOL_GPL vmlinux 0xe93e49c3 devres_free +EXPORT_SYMBOL_GPL vmlinux 0xe9582b7a dm_rh_delay +EXPORT_SYMBOL_GPL vmlinux 0xe9587909 usb_unregister_notify +EXPORT_SYMBOL_GPL vmlinux 0xea065e01 task_handoff_unregister +EXPORT_SYMBOL_GPL vmlinux 0xea295a75 ata_bmdma_stop +EXPORT_SYMBOL_GPL vmlinux 0xea409292 hid_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0xea418e0f atapi_cmd_type +EXPORT_SYMBOL_GPL vmlinux 0xea503d01 bus_for_each_drv +EXPORT_SYMBOL_GPL vmlinux 0xeab29c74 tcp_twsk_unique +EXPORT_SYMBOL_GPL vmlinux 0xeae74760 scsi_nl_send_transport_msg +EXPORT_SYMBOL_GPL vmlinux 0xeb4e9dfb regulator_is_enabled +EXPORT_SYMBOL_GPL vmlinux 0xeb53c1fd generic_fh_to_parent +EXPORT_SYMBOL_GPL vmlinux 0xeb5b6ac3 blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0xec1b043e regulator_suspend_prepare +EXPORT_SYMBOL_GPL vmlinux 0xec84053c fnotify_change +EXPORT_SYMBOL_GPL vmlinux 0xecad31f0 alloc_page_buffers +EXPORT_SYMBOL_GPL vmlinux 0xeccadbe4 register_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0xecce638e hwmon_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xed6692e5 tty_mode_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xedbc6f67 gnttab_end_foreign_access +EXPORT_SYMBOL_GPL vmlinux 0xee2db21c ata_cable_ignore +EXPORT_SYMBOL_GPL vmlinux 0xee5e8888 __rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0xee88e430 __inet_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0xeeb7e3ba regulator_force_disable +EXPORT_SYMBOL_GPL vmlinux 0xeeb91083 platform_device_alloc +EXPORT_SYMBOL_GPL vmlinux 0xeecc5cc0 pcie_port_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xef06218d ata_pci_remove_one +EXPORT_SYMBOL_GPL vmlinux 0xef1e2bf3 user_read +EXPORT_SYMBOL_GPL vmlinux 0xef6c3f70 round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xefab9b11 i2c_new_device +EXPORT_SYMBOL_GPL vmlinux 0xefd4477e ata_sas_port_init +EXPORT_SYMBOL_GPL vmlinux 0xefe0cab3 __class_create +EXPORT_SYMBOL_GPL vmlinux 0xefe21106 snmp_mib_init +EXPORT_SYMBOL_GPL vmlinux 0xefe7b3ce simple_attr_release +EXPORT_SYMBOL_GPL vmlinux 0xf0404067 scsi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xf041c0cf aead_geniv_init +EXPORT_SYMBOL_GPL vmlinux 0xf04798c6 tty_ldisc_flush +EXPORT_SYMBOL_GPL vmlinux 0xf0873417 pci_hp_deregister +EXPORT_SYMBOL_GPL vmlinux 0xf0a1e056 skcipher_geniv_exit +EXPORT_SYMBOL_GPL vmlinux 0xf0a7c66e device_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xf0b20e3e user_match +EXPORT_SYMBOL_GPL vmlinux 0xf0d32ea4 pci_block_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0xf0fd1d48 pci_create_slot +EXPORT_SYMBOL_GPL vmlinux 0xf184d189 kernel_power_off +EXPORT_SYMBOL_GPL vmlinux 0xf18808a9 ata_timing_compute +EXPORT_SYMBOL_GPL vmlinux 0xf1944465 rtc_irq_register +EXPORT_SYMBOL_GPL vmlinux 0xf2485189 usb_init_urb +EXPORT_SYMBOL_GPL vmlinux 0xf276baa0 rtc_class_open +EXPORT_SYMBOL_GPL vmlinux 0xf2fca922 uart_parse_options +EXPORT_SYMBOL_GPL vmlinux 0xf31cfe7c ata_pci_sff_init_one +EXPORT_SYMBOL_GPL vmlinux 0xf33b3862 lookup_create +EXPORT_SYMBOL_GPL vmlinux 0xf387a89a fl6_sock_lookup +EXPORT_SYMBOL_GPL vmlinux 0xf39e13bc bus_for_each_dev +EXPORT_SYMBOL_GPL vmlinux 0xf3b44acb blk_queue_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0xf3bca830 ip_build_and_send_pkt +EXPORT_SYMBOL_GPL vmlinux 0xf3d524fd sysfs_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xf3d5cc13 ata_timing_merge +EXPORT_SYMBOL_GPL vmlinux 0xf453fae5 cpuidle_register_driver +EXPORT_SYMBOL_GPL vmlinux 0xf46bb7a7 inotify_rm_wd +EXPORT_SYMBOL_GPL vmlinux 0xf4750b97 pskb_put +EXPORT_SYMBOL_GPL vmlinux 0xf499fdb2 rcu_barrier_bh +EXPORT_SYMBOL_GPL vmlinux 0xf4aebdc3 xenbus_suspend +EXPORT_SYMBOL_GPL vmlinux 0xf4e41fad inet6_lookup +EXPORT_SYMBOL_GPL vmlinux 0xf52c3e02 devm_kfree +EXPORT_SYMBOL_GPL vmlinux 0xf553318d cpuidle_pause_and_lock +EXPORT_SYMBOL_GPL vmlinux 0xf5945bac gnttab_free_grant_references +EXPORT_SYMBOL_GPL vmlinux 0xf5a5ee70 platform_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xf5a691cd invalidate_bh_lrus +EXPORT_SYMBOL_GPL vmlinux 0xf5a7bca4 platform_device_add +EXPORT_SYMBOL_GPL vmlinux 0xf5a86513 key_type_user +EXPORT_SYMBOL_GPL vmlinux 0xf5b76273 xenbus_unmap_ring +EXPORT_SYMBOL_GPL vmlinux 0xf5d2eb19 class_dev_iter_init +EXPORT_SYMBOL_GPL vmlinux 0xf5df06c1 __class_register +EXPORT_SYMBOL_GPL vmlinux 0xf5e62444 rt_mutex_timed_lock +EXPORT_SYMBOL_GPL vmlinux 0xf5ec7448 sysdev_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf65b9513 sysdev_class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xf6ae60a9 cpci_hp_register_controller +EXPORT_SYMBOL_GPL vmlinux 0xf6b2c8aa spi_new_device +EXPORT_SYMBOL_GPL vmlinux 0xf6bcbd73 hwrng_register +EXPORT_SYMBOL_GPL vmlinux 0xf7016530 xenbus_gather +EXPORT_SYMBOL_GPL vmlinux 0xf7045eba usb_bulk_msg +EXPORT_SYMBOL_GPL vmlinux 0xf71271b0 class_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf725edd8 hid_input_report +EXPORT_SYMBOL_GPL vmlinux 0xf7285aa3 usb_kill_urb +EXPORT_SYMBOL_GPL vmlinux 0xf72c9f8d ata_link_online +EXPORT_SYMBOL_GPL vmlinux 0xf777ee94 unregister_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0xf7d8ac5a ezusb_writememory +EXPORT_SYMBOL_GPL vmlinux 0xf7eba087 xfrm_audit_policy_delete +EXPORT_SYMBOL_GPL vmlinux 0xf82f16b3 execute_in_process_context +EXPORT_SYMBOL_GPL vmlinux 0xf84f7143 power_supply_am_i_supplied +EXPORT_SYMBOL_GPL vmlinux 0xf8802492 print_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0xf8b66770 spi_register_master +EXPORT_SYMBOL_GPL vmlinux 0xf8ea5997 vfs_setlease +EXPORT_SYMBOL_GPL vmlinux 0xf8f3a0fb ata_ratelimit +EXPORT_SYMBOL_GPL vmlinux 0xf94408c1 ata_sas_port_alloc +EXPORT_SYMBOL_GPL vmlinux 0xf972e196 rfkill_restore_states +EXPORT_SYMBOL_GPL vmlinux 0xf97666a0 set_memory_rw +EXPORT_SYMBOL_GPL vmlinux 0xf978b306 crypto_register_instance +EXPORT_SYMBOL_GPL vmlinux 0xf9842194 sysctl_pathname +EXPORT_SYMBOL_GPL vmlinux 0xf9a054b5 __round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0xf9a66045 tcp_done +EXPORT_SYMBOL_GPL vmlinux 0xf9ca3160 ata_id_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xf9ec90c0 ata_pci_device_do_suspend +EXPORT_SYMBOL_GPL vmlinux 0xfa1f4662 scatterwalk_start +EXPORT_SYMBOL_GPL vmlinux 0xfa4e7a9f crypto_attr_alg +EXPORT_SYMBOL_GPL vmlinux 0xfa73fd4d crypto_larval_lookup +EXPORT_SYMBOL_GPL vmlinux 0xfab07716 rtc_irq_set_state +EXPORT_SYMBOL_GPL vmlinux 0xfaeca1f9 tty_wakeup +EXPORT_SYMBOL_GPL vmlinux 0xfb2a3293 math_state_restore +EXPORT_SYMBOL_GPL vmlinux 0xfb37416d regulator_bulk_free +EXPORT_SYMBOL_GPL vmlinux 0xfb815413 device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xfb900cac inet_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0xfbf976af usb_hcd_pci_probe +EXPORT_SYMBOL_GPL vmlinux 0xfbf9be5d register_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xfc056b9a rt_mutex_trylock +EXPORT_SYMBOL_GPL vmlinux 0xfc174c6e __crypto_alloc_tfm +EXPORT_SYMBOL_GPL vmlinux 0xfc78438e pciserial_resume_ports +EXPORT_SYMBOL_GPL vmlinux 0xfc814c5c unregister_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0xfc97df37 crypto_alloc_ablkcipher +EXPORT_SYMBOL_GPL vmlinux 0xfcce694c rfkill_set_default +EXPORT_SYMBOL_GPL vmlinux 0xfce66fae dm_rh_get_state +EXPORT_SYMBOL_GPL vmlinux 0xfcf26b18 inet_twsk_schedule +EXPORT_SYMBOL_GPL vmlinux 0xfcf5a3b7 sdio_register_driver +EXPORT_SYMBOL_GPL vmlinux 0xfd114ec5 cpuidle_register_device +EXPORT_SYMBOL_GPL vmlinux 0xfd3930d7 unregister_timer_hook +EXPORT_SYMBOL_GPL vmlinux 0xfd4136c7 usb_driver_claim_interface +EXPORT_SYMBOL_GPL vmlinux 0xfd44db01 dm_disk +EXPORT_SYMBOL_GPL vmlinux 0xfd51b281 gnttab_end_foreign_access_ref +EXPORT_SYMBOL_GPL vmlinux 0xfde0b92c crypto_larval_error +EXPORT_SYMBOL_GPL vmlinux 0xfdf1c041 per_cpu__gdt_page +EXPORT_SYMBOL_GPL vmlinux 0xfe38eb9e da903x_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0xfe727411 get_phys_to_machine +EXPORT_SYMBOL_GPL vmlinux 0xfe990052 gpio_free +EXPORT_SYMBOL_GPL vmlinux 0xfecbff96 __mark_empty_function +EXPORT_SYMBOL_GPL vmlinux 0xfed11ed1 usb_mon_deregister +EXPORT_SYMBOL_GPL vmlinux 0xfed93be5 tracepoint_iter_next +EXPORT_SYMBOL_GPL vmlinux 0xfedc994c ata_pci_bmdma_clear_simplex +EXPORT_SYMBOL_GPL vmlinux 0xff5a8cfe cn_del_callback +EXPORT_SYMBOL_GPL vmlinux 0xff7f86b2 ata_host_suspend +EXPORT_SYMBOL_GPL vmlinux 0xff99b0fb debugfs_create_u16 +EXPORT_SYMBOL_GPL vmlinux 0xffa2a016 blk_end_request_callback +EXPORT_UNUSED_SYMBOL vmlinux 0x00000000 init_mm +EXPORT_UNUSED_SYMBOL vmlinux 0x00000000 simple_prepare_write --- linux-2.6.28.orig/debian/abi/2.6.28-11.41/i386/generic.modules +++ linux-2.6.28/debian/abi/2.6.28-11.41/i386/generic.modules @@ -0,0 +1,2292 @@ +3c359 +3c501 +3c503 +3c505 +3c507 +3c509 +3c515 +3c523 +3c527 +3c574_cs +3c589_cs +3c59x +3w-9xxx +3w-xxxx +53c700 +6pack +8021q +8139cp +8139too +8250_accent +8250_boca +8250_exar_st16c554 +8250_fourport +8250_hub6 +8250_mca +82596 +8390 +8390p +9p +9pnet +9pnet_rdma +9pnet_virtio +a100u2w +a3d +aacraid +abituguru +abituguru3 +abyss +ac3200 +ac97_bus +acecad +acenic +acerhk +acer-wmi +acpiphp +acpiphp_ibm +acquirewdt +act2000 +act200l-sir +act_gact +act_ipt +actisys-sir +act_mirred +act_nat +act_pedit +act_police +act_simple +act_skbedit +acx +ad1848 +ad7414 +ad7418 +adcxx +adfs +adi +adm1021 +adm1025 +adm1026 +adm1029 +adm1031 +adm8211 +adm9240 +ads7828 +ads7846 +adt7462 +adt7470 +adt7473 +adutux +adv7170 +adv7175 +advansys +advantechwdt +aedsp16 +aes_generic +aes-i586 +af9013 +affs +af_key +af-rxrpc +agpgart +ah4 +ah6 +aha152x +aha152x_cs +aha1542 +aha1740 +aic79xx +aic7xxx +aic94xx +aiptek +aircable +airo +airo_cs +alauda +ali-agp +ali-ircc +alim1535_wdt +alim7101_wdt +ambassador +amd64-agp +amd76x_edac +amd76xrom +amd8111e +amd-k7-agp +amd-rng +analog +ansi_cprng +anubis +aoe +apm +appledisplay +appleir +applesmc +appletalk +appletouch +applicom +ar7part +arc4 +arcfb +arcmsr +arcnet +arc-rawmode +arc-rimi +ark3116 +arkfb +arlan +arptable_filter +arp_tables +arpt_mangle +asb100 +asix +asus-laptop +async_memcpy +async_tx +async_xor +at1700 +at24 +at25 +at76_usb +aten +ath5k +ath9k +ati-agp +ati_remote +ati_remote2 +atl1 +atl1e +atl2 +atlas_btns +atmel +atmel_cs +atmel_pci +atmtcp +atp +atp870u +atxp1 +aty128fb +atyfb +au0828 +au8522 +aufs +authenc +auth_rpcgss +autofs +autofs4 +av5100 +avma1_cs +avm_cs +ax25 +axnet_cs +b1 +b1dma +b1isa +b1pci +b1pcmcia +b2c2-flexcop +b2c2-flexcop-pci +b2c2-flexcop-usb +b43 +b43legacy +b44 +bas_gigaset +baycom_epp +baycom_par +baycom_ser_fdx +baycom_ser_hdx +bcm203x +bcm3510 +bcm5974 +befs +belkin_sa +berry_charge +bfs +bfusb +binfmt_aout +binfmt_misc +bitblit +block2mtd +blowfish +bluecard_cs +bnep +bnx2 +bnx2x +bonding +bpa10x +bpck +bpck6 +bpqether +bq24022 +bq27x00_battery +br2684 +bridge +broadcom +bsd_comp +bt3c_cs +bt819 +bt856 +bt878 +btcx-risc +btsdio +bttv +btuart_cs +btusb +budget +budget-av +budget-ci +budget-core +budget-patch +BusLogic +bw-qcam +c101 +c2port-duramar2150 +c4 +c67x00 +cafe_ccic +cafe_nand +camellia +capi +capidrv +capifs +capmode +carminefb +cassini +cast5 +cast6 +catc +cbc +cciss +ccm +cdc-acm +cdc_ether +cdc_subset +cdc-wdm +cfag12864b +cfag12864bfb +cfg80211 +cfi_cmdset_0001 +cfi_cmdset_0002 +cfi_cmdset_0020 +cfi_probe +cfi_util +ch +ch341 +chipreg +cicada +cifs +cirrusfb +ck804xrom +cls_basic +cls_fw +cls_route +cls_rsvp +cls_rsvp6 +cls_tcindex +cls_u32 +cm109 +cm4000_cs +cm4040_cs +cmtp +cobra +coda +com20020 +com20020_cs +com20020-isa +com20020-pci +com90io +com90xx +comm +commandir +compal-laptop +compat_ioctl32 +compcache +configfs +core +coretemp +corgi_bl +cosa +cp2101 +cpcihp_generic +cpcihp_zt5550 +cpia +cpia2 +cpia_pp +cpia_usb +cpqarray +cpqphp +cpu5wdt +cpuid +c-qcam +cr_bllcd +crc32c +crc32c-intel +crc7 +crc-ccitt +crc-itu-t +crvml +cryptd +cryptoloop +crypto_null +cs5345 +cs53l32a +cs5535_gpio +cs553x_nand +cs89x0 +ct82c710 +ctr +cts +cx18 +cx22700 +cx22702 +cx2341x +cx23885 +cx24110 +cx24116 +cx24123 +cx25840 +cx8800 +cx8802 +cx88-alsa +cx88-blackbird +cx88-dvb +cx88-vp3054-i2c +cx88xx +cxacru +cxgb +cxgb3 +cyber2000fb +cyberjack +cyblafb +cyclades +cyclomx +cycx_drv +cypress_cy7c63 +cypress_m8 +cytherm +da903x +DAC960 +davicom +db9 +dc395x +dca +dccp +dccp_ccid2 +dccp_ccid3 +dccp_diag +dccp_ipv4 +dccp_ipv6 +dccp_probe +dccp_tfrc_lib +dcdbas +de2104x +de4x5 +de600 +de620 +decnet +deflate +defxx +dell_rbu +depca +des_generic +dib0070 +dib3000mb +dib3000mc +dib7000m +dib7000p +dibx000_common +digi_acceleport +dilnetpc +diskonchip +display +divacapi +divadidd +diva_idi +diva_mnt +divas +dlci +dlm +dm1105 +dm9601 +dm-bbr +dm-crypt +dme1737 +dmfe +dm-loop +dm-mem-cache +dm-message +dm-raid4-5 +dm-region_hash +dmx3191d +dm-zero +dn_rtmsg +doc2000 +doc2001 +doc2001plus +docecc +docprobe +donauboe +dpt_i2o +drbd +drm +drx397xD +ds1621 +ds1682 +ds2482 +ds2490 +ds2760_battery +dsbr100 +dscc4 +dss1_divert +dst +dst_ca +dstr +dtc +dtl1_cs +dtlk +dummy +dummy_hcd +dv1394 +dvb-bt8xx +dvb-core +dvb-pll +dvb-ttpci +dvb-ttusb-budget +dvb-usb +dvb-usb-a800 +dvb-usb-af9005 +dvb-usb-af9005-remote +dvb-usb-af9015 +dvb-usb-anysee +dvb-usb-au6610 +dvb-usb-cinergyT2 +dvb-usb-cxusb +dvb-usb-dib0700 +dvb-usb-dibusb-common +dvb-usb-dibusb-mb +dvb-usb-dibusb-mc +dvb-usb-digitv +dvb-usb-dtt200u +dvb-usb-dtv5100 +dvb-usb-dw2102 +dvb-usb-gl861 +dvb-usb-gp8psk +dvb-usb-m920x +dvb-usb-nova-t-usb2 +dvb-usb-opera +dvb-usb-ttusb2 +dvb-usb-umt-010 +dvb-usb-vp702x +dvb-usb-vp7045 +e100 +e1000 +e1000e +e2100 +e752x_edac +e7xxx_edac +eata +ebt_802_3 +ebtable_broute +ebtable_filter +ebtable_nat +ebtables +ebt_among +ebt_arp +ebt_arpreply +ebt_dnat +ebt_ip +ebt_ip6 +ebt_limit +ebt_log +ebt_mark +ebt_mark_m +ebt_nflog +ebt_pkttype +ebt_redirect +ebt_snat +ebt_stp +ebt_ulog +ebt_vlan +ecb +econet +edac_core +eeepc-laptop +eepro +eepro100 +eeprom +eeprom_93cx6 +eexpress +efficeon-agp +efs +elo +elsa_cs +em28xx +em28xx-alsa +em28xx-dvb +em_cmp +emi26 +emi62 +em_meta +em_nbyte +empeg +em_text +emu10k1-gp +em_u32 +enclosure +eni +enic +epat +epca +epia +epic100 +e_powersaver +eql +es3210 +esb2rom +esi-sir +esp +esp4 +esp6 +et131x +et61x251 +eth1394 +eth16i +eurotechwdt +evbug +ewrk3 +exportfs +f71805f +f71882fg +f75375s +fakephp +farsync +fat +faulty +fbcon +fb_ddc +fb_sys_fops +fcrypt +fd_mcs +fdomain +fdomain_cs +fealnx +ff-memless +firestream +firewire-core +firewire-ohci +firewire-sbp2 +fit2 +fit3 +floppy +fm801-gp +fmvj18x_cs +font +forcedeth +fore_200e +freevxfs +friq +frpw +fsam7400 +fscher +fschmd +fscpos +ftdi-elan +ftdi_sio +ftl +fujitsu-laptop +fujitsu_ts +funsoft +g450_pll +gadgetfs +gamecon +gameport +garmin_gps +garp +g_cdc +gcm +gdth +generic_serial +gen_probe +geode-aes +geode-rng +g_ether +gf128mul +gf2k +g_file_storage +gfs2 +gigaset +girbil-sir +gl518sm +gl520sm +gl620a +g_NCR5380 +g_NCR5380_mmio +gpio_keys +gpio_mouse +grip +grip_mp +g_serial +gspca_conex +gspca_etoms +gspca_finepix +gspca_m5602 +gspca_main +gspca_mars +gspca_ov519 +gspca_pac207 +gspca_pac7311 +gspca_sonixb +gspca_sonixj +gspca_spca500 +gspca_spca501 +gspca_spca505 +gspca_spca506 +gspca_spca508 +gspca_spca561 +gspca_stk014 +gspca_sunplus +gspca_t613 +gspca_tv8532 +gspca_vc032x +gspca_zc3xx +gtco +guillemot +gunze +gx1fb +gxfb +g_zero +hamachi +hangcheck-timer +hci_uart +hci_vhci +hdaps +hdlc +hdlc_cisco +hdlcdrv +hdlc_fr +hdlc_ppp +hdlc_raw +hdlc_raw_eth +hdlc_x25 +he +heci +hecubafb +hermes +hermes_dld +hexium_gemini +hexium_orion +hfc4s8s_l1 +hfcmulti +hfcpci +hfc_usb +hfs +hfsplus +hgafb +hid-a4tech +hid-apple +hid-belkin +hid-bright +hid-cherry +hid-chicony +hid-cypress +hid-dell +hid-ezkey +hid-gyration +hid-logitech +hid-microsoft +hid-monterey +hidp +hid-petalynx +hid-pl +hid-samsung +hid-sony +hid-sunplus +hid-tmff +hid-zpff +hifn_795x +hisax +hisax_fcpcipnp +hisax_isac +hisax_st5481 +horizon +hostap +hostap_cs +hostap_pci +hostap_plx +hostess_sv11 +hp +hp100 +hp4x +hpfs +hpilo +hp-plus +hptiop +hp-wmi +hso +htc-pasic3 +htcpen +hwa-hc +hwa-rc +hwmon-vid +hysdn +i1480-dfu-usb +i1480-est +i1480u-wlp +i2c-algo-bit +i2c-algo-pca +i2c-algo-pcf +i2c-ali1535 +i2c-ali1563 +i2c-ali15x3 +i2c-amd756 +i2c-amd756-s4882 +i2c-amd8111 +i2c-dev +i2c-gpio +i2c-i801 +i2c-isch +i2c-matroxfb +i2c-nforce2 +i2c-nforce2-s4985 +i2c-ocores +i2c-parport +i2c-parport-light +i2c-pca-isa +i2c-pca-platform +i2c-piix4 +i2c-simtec +i2c-sis5595 +i2c-sis630 +i2c-sis96x +i2c-stub +i2c-taos-evm +i2c-tiny-usb +i2c-via +i2c-viapro +i2c-voodoo3 +i2o_block +i2o_bus +i2o_config +i2o_core +i2o_proc +i2o_scsi +i3000_edac +i5000_edac +i5100_edac +i5k_amb +i6300esb +i810 +i810fb +i82092 +i82365 +i82860_edac +i82875p_edac +i82975x_edac +i830 +i8k +i915 +ib700wdt +ib_addr +ib_cm +ib_core +ib_ipoib +ib_iser +ib_mad +ibmaem +ibmasm +ibmasr +ibmcam +ibmlana +ibmmca +ibmpex +ibmphp +ib_mthca +ibmtr +ibmtr_cs +ib_sa +ib_srp +ib_ucm +ib_umad +ib_uverbs +ichxrom +icn +icplus +ics932s401 +idmouse +idt77252 +ieee1394 +ieee80211 +ieee80211_crypt +ieee80211_crypt_ccmp +ieee80211_crypt_tkip +ieee80211_crypt_wep +ifb +iforce +igb +ili9320 +imm +in2000 +inet_lro +inexio +inftl +initio +inport +input-polldev +intel-agp +intelfb +intel_menlow +intel-rng +intel_vr_nor +interact +ioatdma +ioc4 +io_edgeport +io_ti +iowarrior +ip2 +ip6_queue +ip6table_filter +ip6table_mangle +ip6table_raw +ip6_tables +ip6table_security +ip6t_ah +ip6t_eui64 +ip6t_frag +ip6t_hbh +ip6t_hl +ip6t_HL +ip6t_ipv6header +ip6t_LOG +ip6t_mh +ip6t_REJECT +ip6t_rt +ip6_tunnel +ipaq +ipcomp +ipcomp6 +ipddp +ipg +ip_gre +iphase +ipip +ipmi_devintf +ipmi_msghandler +ipmi_poweroff +ipmi_si +ipmi_watchdog +ip_queue +ipr +ips +iptable_filter +iptable_mangle +iptable_nat +iptable_raw +ip_tables +iptable_security +ipt_addrtype +ipt_ah +ipt_CLUSTERIP +ipt_ecn +ipt_ECN +ipt_LOG +ipt_MASQUERADE +ipt_NETMAP +ipt_REDIRECT +ipt_REJECT +ipt_ttl +ipt_TTL +ipt_ULOG +ip_vs +ip_vs_dh +ip_vs_ftp +ip_vs_lblc +ip_vs_lblcr +ip_vs_lc +ip_vs_nq +ip_vs_rr +ip_vs_sed +ip_vs_sh +ip_vs_wlc +ip_vs_wrr +ipw +ipw2100 +ipw2200 +ipwireless +ipx +ircomm +ir-common +ircomm-tty +irda +irda-usb +ir-kbd-i2c +irlan +irnet +irtty-sir +iscsi_ibft +iscsi_tcp +iscsi_trgt +isdn +isdn_bsdcomp +isdnhdlc +isight_firmware +isl6405 +isl6421 +isofs +isp116x-hcd +isp1760 +istallion +it87 +it8712f_wdt +it87_wdt +iTCO_vendor_support +iTCO_wdt +itd1000 +ivtv +ivtvfb +iw_c2 +iw_cm +iw_cxgb3 +iwl3945 +iwlagn +iwlcore +ixgb +ixgbe +ixj +ixj_pcmcia +jedec_probe +jffs2 +jfs +jme +joydev +joydump +jsm +k8temp +kafs +kahlua +kaweth +kb3886_bl +kbic +kbtab +kernelcapi +keyspan +keyspan_pda +keyspan_remote +khazad +kingsun-sir +kl5kusb105 +kobil_sct +konicawc +ks0108 +ks0127 +ks959-sir +ksdazzle-sir +ktti +kvm +kvm-amd +kvm-intel +kyrofb +l1oip +l440gx +l64781 +lanai +lance +lanstreamer +lapb +lapbether +lcd +ldusb +lec +led-class +leds-da903x +leds-gpio +leds-hp-disk +leds-net48xx +leds-pca9532 +leds-pca955x +leds-wrap +ledtrig-backlight +ledtrig-default-on +ledtrig-heartbeat +ledtrig-timer +legousbtower +lgdt330x +lgs8gl5 +libcrc32c +libertas +libertas_cs +libertas_sdio +libertas_tf +libertas_tf_usb +libiscsi +libsas +libsrp +lightning +linear +lirc_atiusb +lirc_bt829 +lirc_cmdir +lirc_dev +lirc_gpio +lirc_i2c +lirc_igorplugusb +lirc_imon +lirc_it87 +lirc_mceusb +lirc_mceusb2 +lirc_pvr150 +lirc_sasem +lirc_serial +lirc_serial_igor +lirc_sir +lirc_streamzap +lirc_ttusbir +lis3lv02d +litelink-sir +lkkbd +llc2 +lm63 +lm70 +lm75 +lm77 +lm78 +lm80 +lm83 +lm85 +lm87 +lm90 +lm92 +lm93 +lmc +lmpcm_usb +lnbp21 +lne390 +lockd +lock_dlm +logibm +lp +lp486e +lpfc +lrw +ltpc +ltv350qv +lxfb +lxt +lzo +lzo_compress +lzo_decompress +m25p80 +m52790 +ma600-sir +mac80211 +machzwd +macmodes +macvlan +madgemc +magellan +map_absent +map_funcs +map_ram +map_rom +marvell +matroxfb_accel +matroxfb_base +matroxfb_crtc2 +matroxfb_DAC1064 +matroxfb_g450 +matroxfb_maven +matroxfb_misc +matroxfb_Ti3026 +matrox_w1 +max1111 +max1619 +max6650 +max6875 +max7301 +max732x +mb862xxfb +mbp_nvidia_bl +mcp2120-sir +mcp23s08 +mcs7780 +mcs7830 +mct_u232 +md4 +mdacon +mdc800 +mdio-bitbang +megaraid +megaraid_mbox +megaraid_mm +megaraid_sas +metronomefb +meye +mga +michael_mic +microcode +microtek +mii +minix +mISDN_core +mISDN_dsp +mixcomwd +mk712 +mkiss +mlx4_core +mlx4_en +mlx4_ib +mmc_block +mos7720 +mos7840 +moto_modem +moxa +mpoa +mptbase +mptctl +mptfc +mptlan +mptsas +mptscsih +mptspi +mpu401 +msdos +msi-laptop +msnd +msnd_classic +msnd_pinnacle +msp3400 +msr +mt2060 +mt20xx +mt2131 +mt2266 +mt312 +mt352 +mt9m001 +mt9m111 +mt9v022 +mtd +mtd_blkdevs +mtdblock +mtdblock_ro +mtdchar +mtdconcat +mtd_dataflash +mtdoops +mtdram +mtouch +multipath +mwave +mxb +mxl5005s +mxl5007t +mxser +myri10ge +n2 +nand +nand_ecc +nand_ids +nandsim +natsemi +navman +nbd +ncpfs +NCR53c406a +NCR_D700 +NCR_Q720_mod +ndiswrapper +ne +ne2 +ne2k-pci +ne3210 +neofb +net1080 +netconsole +netrom +netsc520 +nettel +netwave_cs +netxen_nic +newtonkbd +nf_conntrack +nf_conntrack_amanda +nf_conntrack_ftp +nf_conntrack_h323 +nf_conntrack_ipv4 +nf_conntrack_ipv6 +nf_conntrack_irc +nf_conntrack_netbios_ns +nf_conntrack_netlink +nf_conntrack_pptp +nf_conntrack_proto_gre +nf_conntrack_proto_sctp +nf_conntrack_proto_udplite +nf_conntrack_sip +nf_conntrack_tftp +nf_defrag_ipv4 +nf_nat +nf_nat_amanda +nf_nat_ftp +nf_nat_h323 +nf_nat_irc +nf_nat_pptp +nf_nat_proto_gre +nf_nat_proto_sctp +nf_nat_proto_udplite +nf_nat_sip +nf_nat_snmp_basic +nf_nat_tftp +nfnetlink +nfnetlink_log +nfnetlink_queue +nfs +nfs_acl +nfsd +nftl +nf_tproxy_core +n_hdlc +ni52 +ni65 +nicstar +niu +nls_ascii +nls_cp1250 +nls_cp1251 +nls_cp1255 +nls_cp437 +nls_cp737 +nls_cp775 +nls_cp850 +nls_cp852 +nls_cp855 +nls_cp857 +nls_cp860 +nls_cp861 +nls_cp862 +nls_cp863 +nls_cp864 +nls_cp865 +nls_cp866 +nls_cp869 +nls_cp874 +nls_cp932 +nls_cp936 +nls_cp949 +nls_cp950 +nls_euc-jp +nls_iso8859-1 +nls_iso8859-13 +nls_iso8859-14 +nls_iso8859-15 +nls_iso8859-2 +nls_iso8859-3 +nls_iso8859-4 +nls_iso8859-5 +nls_iso8859-6 +nls_iso8859-7 +nls_iso8859-9 +nls_koi8-r +nls_koi8-ru +nls_koi8-u +nls_utf8 +nmclan_cs +nozomi +n_r3964 +ns558 +ns83820 +nsc_gpio +nsc-ircc +nsp32 +nsp_cs +ntfs +nvidia-agp +nvidiafb +nvram +nxt200x +nxt6000 +ocfs2 +ocfs2_dlm +ocfs2_dlmfs +ocfs2_nodemanager +ocfs2_stackglue +ocfs2_stack_o2cb +ocfs2_stack_user +ohci1394 +old_belkin-sir +olpc_battery +olympic +omfs +omninet +on20 +on26 +onenand +onenand_sim +opl3 +oprofile +option +or51132 +or51211 +orinoco +orinoco_cs +orinoco_nortel +orinoco_pci +orinoco_plx +orinoco_tmd +osst +oti6858 +output +ov511 +ov511_decomp +ov518_decomp +ov7670 +ovcamchip +p4-clockmod +p54common +p54pci +p54usb +p80211 +p8023 +padlock-aes +padlock-sha +panasonic-laptop +paride +parkbd +parport +parport_ax88796 +parport_cs +parport_pc +parport_serial +pas16 +pas2 +pata_cs5535 +pata_cypress +pata_hpt37x +pata_isapnp +pata_it8213 +pata_legacy +pata_ninja32 +pata_oldpiix +pata_opti +pata_optidma +pata_pcmcia +pata_radisys +pata_winbond +pbe5 +pc110pad +pc87360 +pc8736x_gpio +pc87413_wdt +pc87427 +pca953x +pcbc +pcbit +pcd +pcf857x +pcf8591 +pci +pci200syn +pcilynx +pcips2 +pcmcia +pcmcia_core +pcnet32 +pcnet_cs +pcspkr +pcwd +pcwd_pci +pcwd_usb +pd +pd6729 +pda_power +pegasus +penmount +pf +pg +phantom +phidget +phidgetkit +phidgetmotorcontrol +phidgetservo +phonedev +phonet +phram +physmap +pktgen +pl2303 +platform_lcd +plat_nand +plat-ram +plip +plusb +pluto2 +pm2fb +pm3fb +pmc551 +pms +pn_pep +powermate +ppa +ppdev +ppp_async +ppp_deflate +ppp_mppe +pppoatm +pppoe +pppol2tp +pppox +ppp_synctty +prism2_usb +prism54 +progear_bl +proteon +psmouse +pss +pt +pvrusb2 +pwc +qla1280 +qla2xxx +qla3xxx +qla4xxx +qlge +qlogic_cs +qlogicfas +qlogicfas408 +qnx4 +qsemi +qt1010 +quickcam +quickcam_messenger +quota_v1 +quota_v2 +r128 +r8169 +r82600_edac +r8a66597-hcd +radeon +radeonfb +radio-aimslab +radio-aztech +radio-cadet +radio-gemtek +radio-gemtek-pci +radio-maestro +radio-maxiradio +radio-mr800 +radio-rtrack2 +radio-sf16fmi +radio-sf16fmr2 +radio-si470x +radio-terratec +radio-trust +radio-typhoon +radio-zoltrix +raid0 +raid1 +raid10 +raid456 +raid_class +raw +raw1394 +ray_cs +rdma_cm +rdma_ucm +redboot +reed_solomon +reiserfs +rfc1051 +rfc1201 +rfd_ftl +rfkill-input +ricoh_mmc +rio +rio500 +riscom8 +rivafb +rmd128 +rmd160 +rmd256 +rmd320 +rndis_host +rndis_wlan +rocket +romfs +rose +rpcsec_gss_krb5 +rpcsec_gss_spkm3 +rrunner +rsrc_nonstatic +rt2400pci +rt2500pci +rt2500usb +rt2860sta +rt2870sta +rt2x00lib +rt2x00pci +rt2x00usb +rt61pci +rt73usb +rtc-bq4802 +rtc-ds1286 +rtc-ds1305 +rtc-ds1307 +rtc-ds1374 +rtc-ds1390 +rtc-ds1553 +rtc-ds1672 +rtc-ds1742 +rtc-ds3234 +rtc-fm3130 +rtc-isl1208 +rtc-m41t80 +rtc-m41t94 +rtc-m48t35 +rtc-m48t59 +rtc-m48t86 +rtc-max6900 +rtc-max6902 +rtc-pcf8563 +rtc-pcf8583 +rtc-rs5c348 +rtc-rs5c372 +rtc-rx8581 +rtc-stk17ta8 +rtc-test +rtc-v3020 +rtc-wm8350 +rtc-x1205 +rtl8150 +rtl8180 +rtl8187 +rtl8187se +rxkad +s1d13xxxfb +s2255drv +s2io +s3fb +s5h1409 +s5h1411 +s5h1420 +saa5246a +saa5249 +saa6588 +saa6752hs +saa7110 +saa7111 +saa7114 +saa7115 +saa7127 +saa7134 +saa7134-alsa +saa7134-dvb +saa7134-empress +saa7146 +saa7146_vv +saa717x +saa7185 +safe_serial +salsa20_generic +salsa20-i586 +sata_mv +sata_sx4 +savage +savagefb +sb +sb1000 +sbc60xxwdt +sbc7240_wdt +sbc8360 +sbc_epx_c3 +sbc_gxx +sb_lib +sbni +sbp2 +sc +sc1200wdt +sc520cdp +sc520_wdt +sc92031 +scb2_flash +scc +sch_atm +sch_cbq +sch_dsmark +sch_gred +sch_hfsc +sch_htb +sch_ingress +sch_multiq +sch_netem +sch_prio +sch_red +sch_sfq +sch_tbf +sch_teql +scsi_debug +scsi_dh_alua +scsi_dh_emc +scsi_dh_hp_sw +scsi_dh_rdac +scsi_tgt +scsi_transport_fc +scsi_transport_iscsi +scsi_transport_sas +scsi_transport_spi +scsi_transport_srp +scsi_wait_scan +sctp +scx200 +scx200_acb +scx200_docflash +scx200_gpio +scx200_hrt +scx200_i2c +scx200_wdt +sdhci +sdhci-pci +sdio_uart +sdla +sdricoh_cs +se401 +sealevel +sedlbauer_cs +seed +seeq8005 +seqiv +ser_gigaset +serial_cs +serio_raw +sermouse +serpent +serport +ses +sfc +sha1_generic +sha256_generic +sha512_generic +sh_mobile_ceu_camera +shpchp +si21xx +sidewinder +sierra +sim710 +sir-dev +sis +sis190 +sis5595 +sis900 +sis-agp +sisfb +sisusbvga +sit +skfp +skge +skisa +sky2 +sl811_cs +sl811-hcd +slip +slram +sm501 +sm501fb +smbfs +smc9194 +smc91c92_cs +smc-mca +smctr +smc-ultra +smc-ultra32 +sms1xxx +smsc +smsc37b787_wdt +smsc47b397 +smsc47m1 +smsc47m192 +smsc95xx +smsc-ircc2 +sn9c102 +snd +snd-ac97-codec +snd-ad1816a +snd-ad1848 +snd-ad1889 +snd-adlib +snd-ak4114 +snd-ak4117 +snd-ak4xxx-adda +snd-ali5451 +snd-als100 +snd-als300 +snd-als4000 +snd-atiixp +snd-atiixp-modem +snd-au8810 +snd-au8820 +snd-au8830 +snd-aw2 +snd-azt2320 +snd-azt3328 +snd-bt87x +snd-ca0106 +snd-cmi8330 +snd-cmipci +snd-cs4231 +snd-cs4232 +snd-cs4236 +snd-cs4236-lib +snd-cs4281 +snd-cs46xx +snd-cs5530 +snd-cs5535audio +snd-cs8427 +snd-darla20 +snd-darla24 +snd-dt019x +snd-dummy +snd-echo3g +snd-emu10k1 +snd-emu10k1-synth +snd-emu10k1x +snd-emu8000-synth +snd-emux-synth +snd-ens1370 +snd-ens1371 +snd-es1688 +snd-es1688-lib +snd-es18xx +snd-es1938 +snd-es1968 +snd-es968 +snd-fm801 +snd-gina20 +snd-gina24 +snd-gusclassic +snd-gusextreme +snd-gus-lib +snd-gusmax +snd-hda-intel +snd-hdsp +snd-hdspm +snd-hifier +snd-hwdep +snd-i2c +snd-ice1712 +snd-ice1724 +snd-ice17xx-ak4xxx +snd-indigo +snd-indigodj +snd-indigoio +snd-intel8x0 +snd-intel8x0m +snd-interwave +snd-interwave-stb +snd-korg1212 +snd-layla20 +snd-layla24 +snd-maestro3 +snd-mia +snd-miro +snd-mixart +snd-mixer-oss +snd-mona +snd-mpu401 +snd-mpu401-uart +snd-mtpav +snd-mts64 +snd-nm256 +snd-opl3-lib +snd-opl3sa2 +snd-opl3-synth +snd-opl4-lib +snd-opl4-synth +snd-opti92x-ad1848 +snd-opti92x-cs4231 +snd-opti93x +snd-oxygen +snd-oxygen-lib +snd-page-alloc +snd-pcm +snd-pcm-oss +snd-pcsp +snd-pcxhr +snd-pdaudiocf +snd-portman2x4 +snd-pt2258 +snd-rawmidi +snd-riptide +snd-rme32 +snd-rme96 +snd-rme9652 +snd-sb16 +snd-sb16-csp +snd-sb16-dsp +snd-sb8 +snd-sb8-dsp +snd-sbawe +snd-sb-common +snd-sc6000 +snd-seq +snd-seq-device +snd-seq-dummy +snd-seq-midi +snd-seq-midi-emul +snd-seq-midi-event +snd-seq-oss +snd-seq-virmidi +snd-serial-u16550 +snd-sgalaxy +snd-sis7019 +snd-soc-ad73311 +snd-soc-ak4535 +snd-soc-core +snd-soc-cs4270 +snd-soc-ssm2602 +snd-soc-tlv320aic23 +snd-soc-tlv320aic26 +snd-soc-tlv320aic3x +snd-soc-uda1380 +snd-soc-wm8510 +snd-soc-wm8580 +snd-soc-wm8731 +snd-soc-wm8750 +snd-soc-wm8753 +snd-soc-wm8900 +snd-soc-wm8903 +snd-soc-wm8971 +snd-soc-wm8990 +snd-sonicvibes +snd-sscape +snd-tea575x-tuner +snd-tea6330t +snd-timer +snd-trident +snd-usb-audio +snd-usb-caiaq +snd-usb-lib +snd-usb-us122l +snd-usb-usx2y +snd-util-mem +snd-via82xx +snd-via82xx-modem +snd-virmidi +snd-virtuoso +snd-vx222 +snd-vx-lib +snd-vxpocket +snd-wavefront +snd-wss-lib +snd-ymfpci +soc_camera +soc_camera_platform +softcursor +softdog +sony-laptop +sonypi +sound +soundcore +sound_firmware +sp8870 +sp887x +spaceball +spaceorb +spcp8x5 +specialix +spectrum_cs +speedtch +spi_bitbang +spi_butterfly +spidev +spi_lm70llp +squashfs +ssb +sscape +ssfdc +sstfb +st +stallion +starfire +stb6000 +stex +stinger +stir4200 +stkwebcam +stowaway +stp +stradis +strip +stv0288 +stv0297 +stv0299 +stv680 +sundance +sungem +sungem_phy +sunhme +suni +sunkbd +sunrpc +svcrdma +svgalib +sworks-agp +sx +sx8 +sym53c416 +sym53c500_cs +sym53c8xx +synclink +synclink_cs +synclink_gt +synclinkmp +syncppp +syscopyarea +sysfillrect +sysimgblt +sysv +t128 +t1isa +t1pci +tc1100-wmi +tcic +tcp_bic +tcp_highspeed +tcp_htcp +tcp_hybla +tcp_illinois +tcp_lp +tcp_probe +tcp_scalable +tcp_vegas +tcp_veno +tcp_westwood +tcp_yeah +tcrypt +tda10021 +tda10023 +tda10048 +tda1004x +tda10086 +tda18271 +tda7432 +tda8083 +tda826x +tda827x +tda8290 +tda9840 +tda9875 +tda9887 +tdfx +tdfxfb +tdo24m +tea +tea5761 +tea5767 +tea6415c +tea6420 +tehuti +tekram-sir +teles_cs +tg3 +tgr192 +thinkpad_acpi +thinkpad_ec +thmc50 +tifm_7xx1 +tifm_core +tifm_sd +tileblit +tipc +ti_usb_3410_5052 +tlan +tlclk +tle62x0 +tlsf +tmdc +tms380tr +tmscsim +tmspci +toshiba_acpi +touchit213 +touchright +touchwin +tpm +tpm_atmel +tpm_bios +tpm_infineon +tpm_nsc +tpm_tis +tps65010 +tp_smapi +trancevibrator +tridentfb +trix +ts5500_flash +ts_bm +ts_fsm +ts_kmp +tsl2550 +ttpci-eeprom +ttusb_dec +ttusbdecfe +tua6100 +tulip +tun +tuner +tuner-simple +tuner-types +tuner-xc2028 +tunnel4 +tunnel6 +turbografx +tvaudio +tveeprom +tvp5150 +twidjoy +twofish +twofish_common +twofish-i586 +typhoon +u132-hcd +u14-34f +uart401 +uart6850 +ub +ubi +ubifs +ucb1400_core +ucb1400_ts +udf +ueagle-atm +ufs +uinput +uio +uio_cif +uio_pdrv +uio_pdrv_genirq +uio_sercos3 +uio_smx +uli526x +ultracam +ultrastor +umc +umem +unionfs +upd64031a +upd64083 +uPD98402 +usb8xxx +usbatm +usb_debug +usb_gigaset +usbhid +usbkbd +usblcd +usbled +usblp +usbmouse +usbnet +usbsevseg +usb-storage +usbtmc +usbtouchscreen +usbvideo +usbvision +uss720 +uvcvideo +uvesafb +uwb +v4l1-compat +v4l2-common +v4l2-int-device +ves1820 +ves1x93 +vesafb +veth +vfat +vga16fb +vgastate +vgg2432a4 +via +via686a +via-agp +viafb +via-ircc +via-rhine +via-rng +via-velocity +vicam +video +video1394 +videobuf-core +videobuf-dma-contig +videobuf-dma-sg +videobuf-dvb +videobuf-vmalloc +videocodec +videodev +virtio +virtio_balloon +virtio_blk +virtio_console +virtio_net +virtio_pci +virtio_ring +virtio-rng +virtual +visor +vitesse +vivi +vlsi_ir +v_midi +vmlfb +vp27smpx +vpx3220 +vstusb +vsxxxaa +vt1211 +vt8231 +vt8623fb +w1_bq27000 +w1_ds2433 +w1_ds2760 +w1-gpio +w1_smem +w1_therm +w83627ehf +w83627hf +w83627hf_wdt +w83697hf_wdt +w83697ug_wdt +w83781d +w83791d +w83792d +w83793 +w83877f_wdt +w83977af_ir +w83977f_wdt +w83l785ts +w83l786ng +w9966 +w9968cf +wacom +wafer5823wdt +wanrouter +wanxl +warrior +wavelan +wavelan_cs +wbsd +wd +wd7000 +wdt +wdt_pci +whci +whci-hcd +whc-rc +whiteheat +winbond-840 +wire +wistron_btns +wl3501_cs +wlp +wm8350 +wm8350-i2c +wm8350-regulator +wm8400-core +wm8400-regulator +wm8739 +wm8775 +wm97xx-ts +wp512 +wusb-cbaf +wusbcore +wusb-wa +x25 +x25_asy +x38_edac +xc5000 +xcbc +xfrm4_mode_beet +xfrm4_mode_transport +xfrm4_mode_tunnel +xfrm4_tunnel +xfrm6_mode_beet +xfrm6_mode_ro +xfrm6_mode_transport +xfrm6_mode_tunnel +xfrm6_tunnel +xfrm_ipcomp +xfrm_user +xfs +xirc2ps_cs +xircom_cb +xor +xpad +xprtrdma +x_tables +xt_CLASSIFY +xt_comment +xt_connbytes +xt_connlimit +xt_connmark +xt_CONNMARK +xt_CONNSECMARK +xt_conntrack +xt_dccp +xt_dscp +xt_DSCP +xt_esp +xt_hashlimit +xt_helper +xt_iprange +xtkbd +xt_length +xt_limit +xt_mac +xt_mark +xt_MARK +xt_multiport +xt_NFLOG +xt_NFQUEUE +xt_NOTRACK +xt_owner +xt_physdev +xt_pkttype +xt_policy +xt_quota +xt_rateest +xt_RATEEST +xt_realm +xt_recent +xts +xt_sctp +xt_SECMARK +xt_socket +xt_state +xt_statistic +xt_string +xt_tcpmss +xt_TCPMSS +xt_tcpudp +xt_time +xt_TPROXY +xt_TRACE +xt_u32 +xusbatm +yam +yealink +yellowfin +yenta_socket +z85230 +zatm +zaurus +zc0301 +zd1201 +zd1211rw +zhenhua +zl10353 +zlib_deflate +znet +zr36016 +zr36050 +zr36060 +zr36067 +zr364xx --- linux-2.6.28.orig/debian/abi/2.6.28-11.41/i386/server.modules +++ linux-2.6.28/debian/abi/2.6.28-11.41/i386/server.modules @@ -0,0 +1,2293 @@ +3c359 +3c501 +3c503 +3c505 +3c507 +3c509 +3c515 +3c523 +3c527 +3c574_cs +3c589_cs +3c59x +3w-9xxx +3w-xxxx +53c700 +6pack +8021q +8139cp +8139too +8250_accent +8250_boca +8250_exar_st16c554 +8250_fourport +8250_hub6 +8250_mca +82596 +8390 +8390p +9p +9pnet +9pnet_rdma +9pnet_virtio +a100u2w +a3d +aacraid +abituguru +abituguru3 +abyss +ac3200 +ac97_bus +acecad +acenic +acerhk +acer-wmi +acpiphp +acpiphp_ibm +acquirewdt +act2000 +act200l-sir +act_gact +act_ipt +actisys-sir +act_mirred +act_nat +act_pedit +act_police +act_simple +act_skbedit +acx +ad1848 +ad7414 +ad7418 +adcxx +adfs +adi +adm1021 +adm1025 +adm1026 +adm1029 +adm1031 +adm8211 +adm9240 +ads7828 +ads7846 +adt7462 +adt7470 +adt7473 +adutux +adv7170 +adv7175 +advansys +advantechwdt +aedsp16 +aes_generic +aes-i586 +af9013 +affs +af_key +af-rxrpc +agpgart +ah4 +ah6 +aha152x +aha152x_cs +aha1542 +aha1740 +aic79xx +aic7xxx +aic94xx +aiptek +aircable +airo +airo_cs +alauda +ali-agp +ali-ircc +alim1535_wdt +alim7101_wdt +ambassador +amd64-agp +amd76x_edac +amd76xrom +amd8111e +amd-k7-agp +amd-rng +analog +ansi_cprng +anubis +aoe +apm +appledisplay +appleir +applesmc +appletalk +appletouch +applicom +ar7part +arc4 +arcfb +arcmsr +arcnet +arc-rawmode +arc-rimi +ark3116 +arkfb +arlan +arptable_filter +arp_tables +arpt_mangle +asb100 +asix +asus-laptop +async_memcpy +async_tx +async_xor +at1700 +at24 +at25 +at76_usb +aten +ath5k +ath9k +ati-agp +ati_remote +ati_remote2 +atl1 +atl1e +atl2 +atlas_btns +atmel +atmel_cs +atmel_pci +atmtcp +atp +atp870u +atxp1 +aty128fb +atyfb +au0828 +au8522 +aufs +authenc +auth_rpcgss +autofs +autofs4 +av5100 +avma1_cs +avm_cs +ax25 +axnet_cs +b1 +b1dma +b1isa +b1pci +b1pcmcia +b2c2-flexcop +b2c2-flexcop-pci +b2c2-flexcop-usb +b43 +b43legacy +b44 +bas_gigaset +baycom_epp +baycom_par +baycom_ser_fdx +baycom_ser_hdx +bcm203x +bcm3510 +bcm5974 +befs +belkin_sa +berry_charge +bfs +bfusb +binfmt_aout +binfmt_misc +bitblit +block2mtd +blowfish +bluecard_cs +bnep +bnx2 +bnx2x +bonding +bpa10x +bpck +bpck6 +bpqether +bq24022 +bq27x00_battery +br2684 +bridge +broadcom +bsd_comp +bt3c_cs +bt819 +bt856 +bt878 +btcx-risc +btsdio +bttv +btuart_cs +btusb +budget +budget-av +budget-ci +budget-core +budget-patch +BusLogic +bw-qcam +c101 +c2port-duramar2150 +c4 +c67x00 +cafe_ccic +cafe_nand +camellia +capi +capidrv +capifs +capmode +carminefb +cassini +cast5 +cast6 +catc +cbc +cciss +ccm +cdc-acm +cdc_ether +cdc_subset +cdc-wdm +cfag12864b +cfag12864bfb +cfg80211 +cfi_cmdset_0001 +cfi_cmdset_0002 +cfi_cmdset_0020 +cfi_probe +cfi_util +ch +ch341 +chipreg +cicada +cifs +cirrusfb +ck804xrom +cls_basic +cls_fw +cls_route +cls_rsvp +cls_rsvp6 +cls_tcindex +cls_u32 +cm109 +cm4000_cs +cm4040_cs +cmtp +cobra +coda +com20020 +com20020_cs +com20020-isa +com20020-pci +com90io +com90xx +comm +commandir +compal-laptop +compat_ioctl32 +compcache +configfs +core +coretemp +corgi_bl +cosa +cp2101 +cpcihp_generic +cpcihp_zt5550 +cpia +cpia2 +cpia_pp +cpia_usb +cpqarray +cpqphp +cpu5wdt +cpuid +c-qcam +cr_bllcd +crc32c +crc32c-intel +crc7 +crc-ccitt +crc-itu-t +crvml +cryptd +cryptoloop +crypto_null +cs5345 +cs53l32a +cs5535_gpio +cs553x_nand +cs89x0 +ct82c710 +ctr +cts +cx18 +cx22700 +cx22702 +cx2341x +cx23885 +cx24110 +cx24116 +cx24123 +cx25840 +cx8800 +cx8802 +cx88-alsa +cx88-blackbird +cx88-dvb +cx88-vp3054-i2c +cx88xx +cxacru +cxgb +cxgb3 +cyber2000fb +cyberjack +cyblafb +cyclades +cyclomx +cycx_drv +cypress_cy7c63 +cypress_m8 +cytherm +da903x +DAC960 +davicom +db9 +dc395x +dccp +dccp_ccid2 +dccp_ccid3 +dccp_diag +dccp_ipv4 +dccp_ipv6 +dccp_probe +dccp_tfrc_lib +dcdbas +de2104x +de4x5 +de600 +de620 +decnet +deflate +defxx +dell_rbu +depca +des_generic +dib0070 +dib3000mb +dib3000mc +dib7000m +dib7000p +dibx000_common +digi_acceleport +dilnetpc +diskonchip +display +divacapi +divadidd +diva_idi +diva_mnt +divas +dlci +dlm +dm1105 +dm9601 +dm-bbr +dm-crypt +dme1737 +dmfe +dm-loop +dm-mem-cache +dm-message +dm-raid4-5 +dm-region_hash +dmx3191d +dm-zero +dn_rtmsg +doc2000 +doc2001 +doc2001plus +docecc +docprobe +donauboe +dpt_i2o +drbd +drm +drx397xD +ds1621 +ds1682 +ds2482 +ds2490 +ds2760_battery +dsbr100 +dscc4 +dss1_divert +dst +dst_ca +dstr +dtc +dtl1_cs +dtlk +dummy +dummy_hcd +dv1394 +dvb-bt8xx +dvb-core +dvb-pll +dvb-ttpci +dvb-ttusb-budget +dvb-usb +dvb-usb-a800 +dvb-usb-af9005 +dvb-usb-af9005-remote +dvb-usb-af9015 +dvb-usb-anysee +dvb-usb-au6610 +dvb-usb-cinergyT2 +dvb-usb-cxusb +dvb-usb-dib0700 +dvb-usb-dibusb-common +dvb-usb-dibusb-mb +dvb-usb-dibusb-mc +dvb-usb-digitv +dvb-usb-dtt200u +dvb-usb-dtv5100 +dvb-usb-dw2102 +dvb-usb-gl861 +dvb-usb-gp8psk +dvb-usb-m920x +dvb-usb-nova-t-usb2 +dvb-usb-opera +dvb-usb-ttusb2 +dvb-usb-umt-010 +dvb-usb-vp702x +dvb-usb-vp7045 +e100 +e1000 +e1000e +e2100 +e752x_edac +e7xxx_edac +eata +ebt_802_3 +ebtable_broute +ebtable_filter +ebtable_nat +ebtables +ebt_among +ebt_arp +ebt_arpreply +ebt_dnat +ebt_ip +ebt_ip6 +ebt_limit +ebt_log +ebt_mark +ebt_mark_m +ebt_nflog +ebt_pkttype +ebt_redirect +ebt_snat +ebt_stp +ebt_ulog +ebt_vlan +ecb +econet +edac_core +eeepc-laptop +eepro +eepro100 +eeprom +eeprom_93cx6 +eexpress +efficeon-agp +efs +elo +elsa_cs +em28xx +em28xx-alsa +em28xx-dvb +em_cmp +emi26 +emi62 +em_meta +em_nbyte +empeg +em_text +emu10k1-gp +em_u32 +enclosure +eni +enic +epat +epca +epia +epic100 +eql +es3210 +esb2rom +esi-sir +esp +esp4 +esp6 +et131x +et61x251 +eth1394 +eth16i +eurotechwdt +evbug +ewrk3 +exportfs +f71805f +f71882fg +f75375s +fakephp +farsync +fat +faulty +fbcon +fb_ddc +fb_sys_fops +fcrypt +fd_mcs +fdomain +fdomain_cs +fealnx +ff-memless +firestream +firewire-core +firewire-ohci +firewire-sbp2 +fit2 +fit3 +floppy +fm801-gp +fmvj18x_cs +font +forcedeth +fore_200e +freevxfs +friq +frpw +fsam7400 +fscher +fschmd +fscpos +ftdi-elan +ftdi_sio +ftl +fujitsu-laptop +fujitsu_ts +funsoft +g450_pll +gadgetfs +gamecon +gameport +garmin_gps +garp +g_cdc +gcm +gdth +generic_serial +gen_probe +geode-aes +geode-rng +g_ether +gf128mul +gf2k +g_file_storage +gfs2 +gigaset +girbil-sir +gl518sm +gl520sm +gl620a +g_NCR5380 +g_NCR5380_mmio +gpio_keys +gpio_mouse +grip +grip_mp +g_serial +gspca_conex +gspca_etoms +gspca_finepix +gspca_m5602 +gspca_main +gspca_mars +gspca_ov519 +gspca_pac207 +gspca_pac7311 +gspca_sonixb +gspca_sonixj +gspca_spca500 +gspca_spca501 +gspca_spca505 +gspca_spca506 +gspca_spca508 +gspca_spca561 +gspca_stk014 +gspca_sunplus +gspca_t613 +gspca_tv8532 +gspca_vc032x +gspca_zc3xx +gtco +guillemot +gunze +gx1fb +gxfb +g_zero +hamachi +hangcheck-timer +hci_uart +hci_vhci +hdaps +hdlc +hdlc_cisco +hdlcdrv +hdlc_fr +hdlc_ppp +hdlc_raw +hdlc_raw_eth +hdlc_x25 +he +heci +hecubafb +hermes +hermes_dld +hexium_gemini +hexium_orion +hfc4s8s_l1 +hfcmulti +hfcpci +hfc_usb +hfs +hfsplus +hgafb +hid-a4tech +hid-apple +hid-belkin +hid-bright +hid-cherry +hid-chicony +hid-cypress +hid-dell +hid-ezkey +hid-gyration +hid-logitech +hid-microsoft +hid-monterey +hidp +hid-petalynx +hid-pl +hid-samsung +hid-sony +hid-sunplus +hid-tmff +hid-zpff +hifn_795x +hisax +hisax_fcpcipnp +hisax_isac +hisax_st5481 +horizon +hostap +hostap_cs +hostap_pci +hostap_plx +hostess_sv11 +hp +hp100 +hp4x +hpfs +hpilo +hp-plus +hptiop +hp-wmi +hso +htc-pasic3 +htcpen +hwa-hc +hwa-rc +hwmon-vid +hysdn +i1480-dfu-usb +i1480-est +i1480u-wlp +i2c-algo-bit +i2c-algo-pca +i2c-algo-pcf +i2c-ali1535 +i2c-ali1563 +i2c-ali15x3 +i2c-amd756 +i2c-amd756-s4882 +i2c-amd8111 +i2c-dev +i2c-gpio +i2c-i801 +i2c-isch +i2c-matroxfb +i2c-nforce2 +i2c-nforce2-s4985 +i2c-ocores +i2c-parport +i2c-parport-light +i2c-pca-isa +i2c-pca-platform +i2c-piix4 +i2c-simtec +i2c-sis5595 +i2c-sis630 +i2c-sis96x +i2c-stub +i2c-taos-evm +i2c-tiny-usb +i2c-via +i2c-viapro +i2c-voodoo3 +i2o_block +i2o_bus +i2o_config +i2o_core +i2o_proc +i2o_scsi +i3000_edac +i5000_edac +i5100_edac +i5k_amb +i6300esb +i810 +i810fb +i82092 +i82365 +i82860_edac +i82875p_edac +i82975x_edac +i830 +i8k +i915 +ib700wdt +ib_addr +ib_cm +ib_core +ib_ipoib +ib_iser +ib_mad +ibmaem +ibmasm +ibmasr +ibmcam +ibmlana +ibmmca +ibmpex +ibmphp +ib_mthca +ibmtr +ibmtr_cs +ib_sa +ib_srp +ib_ucm +ib_umad +ib_uverbs +ichxrom +icn +icplus +ics932s401 +idmouse +idt77252 +ieee1394 +ieee80211 +ieee80211_crypt +ieee80211_crypt_ccmp +ieee80211_crypt_tkip +ieee80211_crypt_wep +ifb +iforce +igb +ili9320 +imm +in2000 +inet_lro +inexio +inftl +initio +inport +input-polldev +intel-agp +intelfb +intel_menlow +intel-rng +intel_vr_nor +interact +ioc4 +io_edgeport +io_ti +iowarrior +ip2 +ip6_queue +ip6table_filter +ip6table_mangle +ip6table_raw +ip6_tables +ip6table_security +ip6t_ah +ip6t_eui64 +ip6t_frag +ip6t_hbh +ip6t_hl +ip6t_HL +ip6t_ipv6header +ip6t_LOG +ip6t_mh +ip6t_REJECT +ip6t_rt +ip6_tunnel +ipaq +ipcomp +ipcomp6 +ipddp +ipg +ip_gre +iphase +ipip +ipmi_devintf +ipmi_msghandler +ipmi_poweroff +ipmi_si +ipmi_watchdog +ip_queue +ipr +ips +iptable_filter +iptable_mangle +iptable_nat +iptable_raw +ip_tables +iptable_security +ipt_addrtype +ipt_ah +ipt_CLUSTERIP +ipt_ecn +ipt_ECN +ipt_LOG +ipt_MASQUERADE +ipt_NETMAP +ipt_REDIRECT +ipt_REJECT +ipt_ttl +ipt_TTL +ipt_ULOG +ip_vs +ip_vs_dh +ip_vs_ftp +ip_vs_lblc +ip_vs_lblcr +ip_vs_lc +ip_vs_nq +ip_vs_rr +ip_vs_sed +ip_vs_sh +ip_vs_wlc +ip_vs_wrr +ipw +ipw2100 +ipw2200 +ipwireless +ipx +ircomm +ir-common +ircomm-tty +irda +irda-usb +ir-kbd-i2c +irlan +irnet +irtty-sir +iscsi_ibft +iscsi_tcp +iscsi_trgt +isdn +isdn_bsdcomp +isdnhdlc +isight_firmware +isl6405 +isl6421 +isofs +isp116x-hcd +isp1760 +istallion +it87 +it8712f_wdt +it87_wdt +iTCO_vendor_support +iTCO_wdt +itd1000 +ivtv +ivtvfb +iw_c2 +iw_cm +iw_cxgb3 +iwl3945 +iwlagn +iwlcore +ixgb +ixgbe +ixj +ixj_pcmcia +jedec_probe +jffs2 +jfs +jme +joydev +joydump +jsm +k8temp +kafs +kahlua +kaweth +kb3886_bl +kbic +kbtab +kernelcapi +keyspan +keyspan_pda +keyspan_remote +khazad +kingsun-sir +kl5kusb105 +kobil_sct +konicawc +ks0108 +ks0127 +ks959-sir +ksdazzle-sir +ktti +kvm +kvm-amd +kvm-intel +kyrofb +l1oip +l440gx +l64781 +lanai +lance +lanstreamer +lapb +lapbether +lcd +ldusb +lec +led-class +leds-da903x +leds-gpio +leds-hp-disk +leds-net48xx +leds-pca9532 +leds-pca955x +leds-wrap +ledtrig-backlight +ledtrig-default-on +ledtrig-heartbeat +ledtrig-timer +legousbtower +lgdt330x +lgs8gl5 +libcrc32c +libertas +libertas_cs +libertas_sdio +libertas_tf +libertas_tf_usb +libiscsi +libsas +libsrp +lightning +linear +lirc_atiusb +lirc_bt829 +lirc_cmdir +lirc_dev +lirc_gpio +lirc_i2c +lirc_igorplugusb +lirc_imon +lirc_it87 +lirc_mceusb +lirc_mceusb2 +lirc_pvr150 +lirc_sasem +lirc_serial +lirc_serial_igor +lirc_sir +lirc_streamzap +lirc_ttusbir +lis3lv02d +litelink-sir +lkkbd +llc2 +lm63 +lm70 +lm75 +lm77 +lm78 +lm80 +lm83 +lm85 +lm87 +lm90 +lm92 +lm93 +lmc +lmpcm_usb +lnbp21 +lne390 +lockd +lock_dlm +logibm +lp +lp486e +lpfc +lrw +ltpc +ltv350qv +lxfb +lxt +lzo +lzo_compress +lzo_decompress +m25p80 +m52790 +ma600-sir +mac80211 +machzwd +macmodes +macvlan +madgemc +magellan +map_absent +map_funcs +map_ram +map_rom +marvell +matroxfb_accel +matroxfb_base +matroxfb_crtc2 +matroxfb_DAC1064 +matroxfb_g450 +matroxfb_maven +matroxfb_misc +matroxfb_Ti3026 +matrox_w1 +max1111 +max1619 +max6650 +max6875 +max7301 +max732x +mb862xxfb +mbp_nvidia_bl +mcp2120-sir +mcp23s08 +mcs7780 +mcs7830 +mct_u232 +md4 +mdacon +mdc800 +mdio-bitbang +megaraid +megaraid_mbox +megaraid_mm +megaraid_sas +metronomefb +meye +mga +michael_mic +microcode +microtek +mii +minix +mISDN_core +mISDN_dsp +mixcomwd +mk712 +mkiss +mlx4_core +mlx4_en +mlx4_ib +mmc_block +mos7720 +mos7840 +moto_modem +moxa +mpoa +mptbase +mptctl +mptfc +mptlan +mptsas +mptscsih +mptspi +mpu401 +msdos +msi-laptop +msnd +msnd_classic +msnd_pinnacle +msp3400 +msr +mt2060 +mt20xx +mt2131 +mt2266 +mt312 +mt352 +mt9m001 +mt9m111 +mt9v022 +mtd +mtd_blkdevs +mtdblock +mtdblock_ro +mtdchar +mtdconcat +mtd_dataflash +mtdoops +mtdram +mtouch +multipath +mwave +mxb +mxl5005s +mxl5007t +mxser +myri10ge +n2 +nand +nand_ecc +nand_ids +nandsim +natsemi +navman +nbd +ncpfs +NCR53c406a +NCR_D700 +NCR_Q720_mod +ndiswrapper +ne +ne2 +ne2k-pci +ne3210 +neofb +net1080 +netconsole +netrom +netsc520 +nettel +netwave_cs +netxen_nic +newtonkbd +nf_conntrack +nf_conntrack_amanda +nf_conntrack_ftp +nf_conntrack_h323 +nf_conntrack_ipv4 +nf_conntrack_ipv6 +nf_conntrack_irc +nf_conntrack_netbios_ns +nf_conntrack_netlink +nf_conntrack_pptp +nf_conntrack_proto_gre +nf_conntrack_proto_sctp +nf_conntrack_proto_udplite +nf_conntrack_sip +nf_conntrack_tftp +nf_defrag_ipv4 +nf_nat +nf_nat_amanda +nf_nat_ftp +nf_nat_h323 +nf_nat_irc +nf_nat_pptp +nf_nat_proto_gre +nf_nat_proto_sctp +nf_nat_proto_udplite +nf_nat_sip +nf_nat_snmp_basic +nf_nat_tftp +nfnetlink +nfnetlink_log +nfnetlink_queue +nfs +nfs_acl +nfsd +nftl +nf_tproxy_core +n_hdlc +ni52 +ni65 +nicstar +niu +nls_ascii +nls_cp1250 +nls_cp1251 +nls_cp1255 +nls_cp437 +nls_cp737 +nls_cp775 +nls_cp850 +nls_cp852 +nls_cp855 +nls_cp857 +nls_cp860 +nls_cp861 +nls_cp862 +nls_cp863 +nls_cp864 +nls_cp865 +nls_cp866 +nls_cp869 +nls_cp874 +nls_cp932 +nls_cp936 +nls_cp949 +nls_cp950 +nls_euc-jp +nls_iso8859-1 +nls_iso8859-13 +nls_iso8859-14 +nls_iso8859-15 +nls_iso8859-2 +nls_iso8859-3 +nls_iso8859-4 +nls_iso8859-5 +nls_iso8859-6 +nls_iso8859-7 +nls_iso8859-9 +nls_koi8-r +nls_koi8-ru +nls_koi8-u +nls_utf8 +nmclan_cs +nozomi +n_r3964 +ns558 +ns83820 +nsc_gpio +nsc-ircc +nsp32 +nsp_cs +ntfs +nvidia-agp +nvidiafb +nvram +nxt200x +nxt6000 +ocfs2 +ocfs2_dlm +ocfs2_dlmfs +ocfs2_nodemanager +ocfs2_stackglue +ocfs2_stack_o2cb +ocfs2_stack_user +ohci1394 +old_belkin-sir +olpc_battery +olympic +omfs +omninet +on20 +on26 +onenand +onenand_sim +opl3 +oprofile +option +or51132 +or51211 +orinoco +orinoco_cs +orinoco_nortel +orinoco_pci +orinoco_plx +orinoco_tmd +osst +oti6858 +output +ov511 +ov511_decomp +ov518_decomp +ov7670 +ovcamchip +p4-clockmod +p54common +p54pci +p54usb +p80211 +p8023 +padlock-aes +padlock-sha +panasonic-laptop +paride +parkbd +parport +parport_ax88796 +parport_cs +parport_pc +parport_serial +pas16 +pas2 +pata_cs5535 +pata_cypress +pata_hpt37x +pata_isapnp +pata_it8213 +pata_legacy +pata_ninja32 +pata_oldpiix +pata_opti +pata_optidma +pata_pcmcia +pata_radisys +pata_winbond +pbe5 +pc110pad +pc87360 +pc8736x_gpio +pc87413_wdt +pc87427 +pca953x +pcbc +pcbit +pcd +pcf857x +pcf8591 +pci +pci200syn +pcilynx +pcips2 +pcmcia +pcmcia_core +pcnet32 +pcnet_cs +pcspkr +pcwd +pcwd_pci +pcwd_usb +pd +pd6729 +pda_power +pegasus +penmount +pf +pg +phantom +phidget +phidgetkit +phidgetmotorcontrol +phidgetservo +phonedev +phonet +phram +physmap +pktgen +pl2303 +platform_lcd +plat_nand +plat-ram +plip +plusb +pluto2 +pm2fb +pm3fb +pmc551 +pms +pn_pep +powermate +ppa +ppdev +ppp_async +ppp_deflate +ppp_mppe +pppoatm +pppoe +pppol2tp +pppox +ppp_synctty +prism2_usb +prism54 +progear_bl +proteon +psmouse +pss +pt +pvrusb2 +pwc +qla1280 +qla2xxx +qla3xxx +qla4xxx +qlge +qlogic_cs +qlogicfas +qlogicfas408 +qnx4 +qsemi +qt1010 +quickcam +quickcam_messenger +quota_v1 +quota_v2 +r128 +r8169 +r82600_edac +r8a66597-hcd +radeon +radeonfb +radio-aimslab +radio-aztech +radio-cadet +radio-gemtek +radio-gemtek-pci +radio-maestro +radio-maxiradio +radio-mr800 +radio-rtrack2 +radio-sf16fmi +radio-sf16fmr2 +radio-si470x +radio-terratec +radio-trust +radio-typhoon +radio-zoltrix +raid0 +raid1 +raid10 +raid456 +raid_class +raw +raw1394 +ray_cs +rdma_cm +rdma_ucm +redboot +reed_solomon +reiserfs +rfc1051 +rfc1201 +rfd_ftl +rfkill-input +ricoh_mmc +rio +rio500 +riscom8 +rivafb +rmd128 +rmd160 +rmd256 +rmd320 +rndis_host +rndis_wlan +rocket +romfs +rose +rpcsec_gss_krb5 +rpcsec_gss_spkm3 +rrunner +rsrc_nonstatic +rt2400pci +rt2500pci +rt2500usb +rt2860sta +rt2870sta +rt2x00lib +rt2x00pci +rt2x00usb +rt61pci +rt73usb +rtc-bq4802 +rtc-ds1286 +rtc-ds1305 +rtc-ds1307 +rtc-ds1374 +rtc-ds1390 +rtc-ds1553 +rtc-ds1672 +rtc-ds1742 +rtc-ds3234 +rtc-fm3130 +rtc-isl1208 +rtc-m41t80 +rtc-m41t94 +rtc-m48t35 +rtc-m48t59 +rtc-m48t86 +rtc-max6900 +rtc-max6902 +rtc-pcf8563 +rtc-pcf8583 +rtc-rs5c348 +rtc-rs5c372 +rtc-rx8581 +rtc-stk17ta8 +rtc-test +rtc-v3020 +rtc-wm8350 +rtc-x1205 +rtl8150 +rtl8180 +rtl8187 +rtl8187se +rxkad +s1d13xxxfb +s2255drv +s2io +s3fb +s5h1409 +s5h1411 +s5h1420 +saa5246a +saa5249 +saa6588 +saa6752hs +saa7110 +saa7111 +saa7114 +saa7115 +saa7127 +saa7134 +saa7134-alsa +saa7134-dvb +saa7134-empress +saa7146 +saa7146_vv +saa717x +saa7185 +safe_serial +salsa20_generic +salsa20-i586 +sata_mv +sata_sx4 +savage +savagefb +sb +sb1000 +sbc60xxwdt +sbc7240_wdt +sbc8360 +sbc_epx_c3 +sbc_gxx +sb_lib +sbni +sbp2 +sc +sc1200wdt +sc520cdp +sc520_wdt +sc92031 +scb2_flash +scc +sch_atm +sch_cbq +sch_dsmark +sch_gred +sch_hfsc +sch_htb +sch_ingress +sch_multiq +sch_netem +sch_prio +sch_red +sch_sfq +sch_tbf +sch_teql +scsi_debug +scsi_dh_alua +scsi_dh_emc +scsi_dh_hp_sw +scsi_dh_rdac +scsi_tgt +scsi_transport_fc +scsi_transport_iscsi +scsi_transport_sas +scsi_transport_spi +scsi_transport_srp +scsi_wait_scan +sctp +scx200 +scx200_acb +scx200_docflash +scx200_gpio +scx200_hrt +scx200_i2c +scx200_wdt +sdhci +sdhci-pci +sdio_uart +sdla +sdricoh_cs +se401 +sealevel +sedlbauer_cs +seed +seeq8005 +seqiv +ser_gigaset +serial_cs +serio_raw +sermouse +serpent +serport +ses +sfc +sha1_generic +sha256_generic +sha512_generic +sh_mobile_ceu_camera +shpchp +si21xx +sidewinder +sierra +sim710 +sir-dev +sis +sis190 +sis5595 +sis900 +sis-agp +sisfb +sisusbvga +sit +skfp +skge +skisa +sky2 +sl811_cs +sl811-hcd +slip +slram +sm501 +sm501fb +smbfs +smc9194 +smc91c92_cs +smc-mca +smctr +smc-ultra +smc-ultra32 +sms1xxx +smsc +smsc37b787_wdt +smsc47b397 +smsc47m1 +smsc47m192 +smsc95xx +smsc-ircc2 +sn9c102 +snd +snd-ac97-codec +snd-ad1816a +snd-ad1848 +snd-ad1889 +snd-adlib +snd-ak4114 +snd-ak4117 +snd-ak4xxx-adda +snd-ali5451 +snd-als100 +snd-als300 +snd-als4000 +snd-atiixp +snd-atiixp-modem +snd-au8810 +snd-au8820 +snd-au8830 +snd-aw2 +snd-azt2320 +snd-azt3328 +snd-bt87x +snd-ca0106 +snd-cmi8330 +snd-cmipci +snd-cs4231 +snd-cs4232 +snd-cs4236 +snd-cs4236-lib +snd-cs4281 +snd-cs46xx +snd-cs5530 +snd-cs5535audio +snd-cs8427 +snd-darla20 +snd-darla24 +snd-dt019x +snd-dummy +snd-echo3g +snd-emu10k1 +snd-emu10k1-synth +snd-emu10k1x +snd-emu8000-synth +snd-emux-synth +snd-ens1370 +snd-ens1371 +snd-es1688 +snd-es1688-lib +snd-es18xx +snd-es1938 +snd-es1968 +snd-es968 +snd-fm801 +snd-gina20 +snd-gina24 +snd-gusclassic +snd-gusextreme +snd-gus-lib +snd-gusmax +snd-hda-intel +snd-hdsp +snd-hdspm +snd-hifier +snd-hwdep +snd-i2c +snd-ice1712 +snd-ice1724 +snd-ice17xx-ak4xxx +snd-indigo +snd-indigodj +snd-indigoio +snd-intel8x0 +snd-intel8x0m +snd-interwave +snd-interwave-stb +snd-korg1212 +snd-layla20 +snd-layla24 +snd-maestro3 +snd-mia +snd-miro +snd-mixart +snd-mixer-oss +snd-mona +snd-mpu401 +snd-mpu401-uart +snd-mtpav +snd-mts64 +snd-nm256 +snd-opl3-lib +snd-opl3sa2 +snd-opl3-synth +snd-opl4-lib +snd-opl4-synth +snd-opti92x-ad1848 +snd-opti92x-cs4231 +snd-opti93x +snd-oxygen +snd-oxygen-lib +snd-page-alloc +snd-pcm +snd-pcm-oss +snd-pcsp +snd-pcxhr +snd-pdaudiocf +snd-portman2x4 +snd-pt2258 +snd-rawmidi +snd-riptide +snd-rme32 +snd-rme96 +snd-rme9652 +snd-sb16 +snd-sb16-csp +snd-sb16-dsp +snd-sb8 +snd-sb8-dsp +snd-sbawe +snd-sb-common +snd-sc6000 +snd-seq +snd-seq-device +snd-seq-dummy +snd-seq-midi +snd-seq-midi-emul +snd-seq-midi-event +snd-seq-oss +snd-seq-virmidi +snd-serial-u16550 +snd-sgalaxy +snd-sis7019 +snd-soc-ad73311 +snd-soc-ak4535 +snd-soc-core +snd-soc-cs4270 +snd-soc-ssm2602 +snd-soc-tlv320aic23 +snd-soc-tlv320aic26 +snd-soc-tlv320aic3x +snd-soc-uda1380 +snd-soc-wm8510 +snd-soc-wm8580 +snd-soc-wm8731 +snd-soc-wm8750 +snd-soc-wm8753 +snd-soc-wm8900 +snd-soc-wm8903 +snd-soc-wm8971 +snd-soc-wm8990 +snd-sonicvibes +snd-sscape +snd-tea575x-tuner +snd-tea6330t +snd-timer +snd-trident +snd-usb-audio +snd-usb-caiaq +snd-usb-lib +snd-usb-us122l +snd-usb-usx2y +snd-util-mem +snd-via82xx +snd-via82xx-modem +snd-virmidi +snd-virtuoso +snd-vx222 +snd-vx-lib +snd-vxpocket +snd-wavefront +snd-wss-lib +snd-ymfpci +soc_camera +soc_camera_platform +softcursor +softdog +sony-laptop +sonypi +sound +soundcore +sound_firmware +sp8870 +sp887x +spaceball +spaceorb +spcp8x5 +specialix +spectrum_cs +speedtch +spi_bitbang +spi_butterfly +spidev +spi_lm70llp +squashfs +ssb +sscape +ssfdc +sstfb +st +stallion +starfire +stb6000 +stex +stinger +stir4200 +stkwebcam +stowaway +stp +stradis +strip +stv0288 +stv0297 +stv0299 +stv680 +sundance +sungem +sungem_phy +sunhme +suni +sunkbd +sunrpc +svcrdma +svgalib +sworks-agp +sx +sx8 +sym53c416 +sym53c500_cs +sym53c8xx +synclink +synclink_cs +synclink_gt +synclinkmp +syncppp +syscopyarea +sysfillrect +sysimgblt +sysv +t128 +t1isa +t1pci +tc1100-wmi +tcic +tcp_bic +tcp_highspeed +tcp_htcp +tcp_hybla +tcp_illinois +tcp_lp +tcp_probe +tcp_scalable +tcp_vegas +tcp_veno +tcp_westwood +tcp_yeah +tcrypt +tda10021 +tda10023 +tda10048 +tda1004x +tda10086 +tda18271 +tda7432 +tda8083 +tda826x +tda827x +tda8290 +tda9840 +tda9875 +tda9887 +tdfx +tdfxfb +tdo24m +tea +tea5761 +tea5767 +tea6415c +tea6420 +tehuti +tekram-sir +teles_cs +tg3 +tgr192 +thinkpad_acpi +thinkpad_ec +thmc50 +tifm_7xx1 +tifm_core +tifm_sd +tileblit +tipc +ti_usb_3410_5052 +tlan +tlclk +tle62x0 +tlsf +tmdc +tms380tr +tmscsim +tmspci +toshiba_acpi +touchit213 +touchright +touchwin +tpm +tpm_atmel +tpm_bios +tpm_infineon +tpm_nsc +tpm_tis +tps65010 +tp_smapi +trancevibrator +tridentfb +trix +ts5500_flash +ts_bm +ts_fsm +ts_kmp +tsl2550 +ttpci-eeprom +ttusb_dec +ttusbdecfe +tua6100 +tulip +tun +tuner +tuner-simple +tuner-types +tuner-xc2028 +tunnel4 +tunnel6 +turbografx +tvaudio +tveeprom +tvp5150 +twidjoy +twofish +twofish_common +twofish-i586 +typhoon +u132-hcd +u14-34f +uart401 +uart6850 +ub +ubi +ubifs +ucb1400_core +ucb1400_ts +udf +ueagle-atm +ufs +uinput +uio +uio_cif +uio_pdrv +uio_pdrv_genirq +uio_sercos3 +uio_smx +uli526x +ultracam +ultrastor +umc +umem +unionfs +upd64031a +upd64083 +uPD98402 +usb8xxx +usbatm +usb_debug +usb_gigaset +usbhid +usbkbd +usblcd +usbled +usblp +usbmouse +usbnet +usbsevseg +usb-storage +usbtmc +usbtouchscreen +usbvideo +usbvision +uss720 +uvcvideo +uvesafb +uwb +v4l1-compat +v4l2-common +v4l2-int-device +ves1820 +ves1x93 +vesafb +veth +vfat +vga16fb +vgastate +vgg2432a4 +via +via686a +via-agp +viafb +via-ircc +via-rhine +via-rng +via-velocity +vicam +video +video1394 +videobuf-core +videobuf-dma-contig +videobuf-dma-sg +videobuf-dvb +videobuf-vmalloc +videocodec +videodev +virtio +virtio_balloon +virtio_blk +virtio_console +virtio_net +virtio_pci +virtio_ring +virtio-rng +virtual +visor +vitesse +vivi +vlsi_ir +v_midi +vmlfb +vp27smpx +vpx3220 +vstusb +vsxxxaa +vt1211 +vt8231 +vt8623fb +w1_bq27000 +w1_ds2433 +w1_ds2760 +w1-gpio +w1_smem +w1_therm +w83627ehf +w83627hf +w83627hf_wdt +w83697hf_wdt +w83697ug_wdt +w83781d +w83791d +w83792d +w83793 +w83877f_wdt +w83977af_ir +w83977f_wdt +w83l785ts +w83l786ng +w9966 +w9968cf +wacom +wafer5823wdt +wanrouter +wanxl +warrior +wavelan +wavelan_cs +wbsd +wd +wd7000 +wdt +wdt_pci +whci +whci-hcd +whc-rc +whiteheat +winbond-840 +wire +wistron_btns +wl3501_cs +wlp +wm8350 +wm8350-i2c +wm8350-regulator +wm8400-core +wm8400-regulator +wm8739 +wm8775 +wm97xx-ts +wp512 +wusb-cbaf +wusbcore +wusb-wa +x25 +x25_asy +x38_edac +xc5000 +xcbc +xen-blkfront +xen-fbfront +xen-kbdfront +xen-netfront +xfrm4_mode_beet +xfrm4_mode_transport +xfrm4_mode_tunnel +xfrm4_tunnel +xfrm6_mode_beet +xfrm6_mode_ro +xfrm6_mode_transport +xfrm6_mode_tunnel +xfrm6_tunnel +xfrm_ipcomp +xfrm_user +xfs +xirc2ps_cs +xircom_cb +xor +xpad +xprtrdma +x_tables +xt_CLASSIFY +xt_comment +xt_connbytes +xt_connlimit +xt_connmark +xt_CONNMARK +xt_CONNSECMARK +xt_conntrack +xt_dccp +xt_dscp +xt_DSCP +xt_esp +xt_hashlimit +xt_helper +xt_iprange +xtkbd +xt_length +xt_limit +xt_mac +xt_mark +xt_MARK +xt_multiport +xt_NFLOG +xt_NFQUEUE +xt_NOTRACK +xt_owner +xt_physdev +xt_pkttype +xt_policy +xt_quota +xt_rateest +xt_RATEEST +xt_realm +xt_recent +xts +xt_sctp +xt_SECMARK +xt_socket +xt_state +xt_statistic +xt_string +xt_tcpmss +xt_TCPMSS +xt_tcpudp +xt_time +xt_TPROXY +xt_TRACE +xt_u32 +xusbatm +yam +yealink +yellowfin +yenta_socket +z85230 +zatm +zaurus +zc0301 +zd1201 +zd1211rw +zhenhua +zl10353 +zlib_deflate +znet +zr36016 +zr36050 +zr36060 +zr36067 +zr364xx --- linux-2.6.28.orig/debian/abi/2.6.28-11.41/armel/imx51 +++ linux-2.6.28/debian/abi/2.6.28-11.41/armel/imx51 @@ -0,0 +1,5624 @@ +EXPORT_SYMBOL crypto/gf128mul 0x0c2f123f gf128mul_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x1068004b gf128mul_bbe +EXPORT_SYMBOL crypto/gf128mul 0x2f2889a0 gf128mul_init_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0x3755f990 gf128mul_init_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x384ef9ce gf128mul_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x56af0dbd gf128mul_x_ble +EXPORT_SYMBOL crypto/gf128mul 0x83581089 gf128mul_init_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0x9b2560b9 gf128mul_init_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x9e13f6f6 gf128mul_lle +EXPORT_SYMBOL crypto/gf128mul 0xbd17a0df gf128mul_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0xc0890413 gf128mul_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0xd60736ec gf128mul_free_64k +EXPORT_SYMBOL crypto/xor 0x5b6c00e6 xor_blocks +EXPORT_SYMBOL drivers/cdrom/cdrom 0x2a24388f unregister_cdrom +EXPORT_SYMBOL drivers/cdrom/cdrom 0x44c6b1d9 cdrom_get_media_event +EXPORT_SYMBOL drivers/cdrom/cdrom 0x45e261ce cdrom_mode_sense +EXPORT_SYMBOL drivers/cdrom/cdrom 0x4ae1a7c5 cdrom_ioctl +EXPORT_SYMBOL drivers/cdrom/cdrom 0x4f476e96 init_cdrom_command +EXPORT_SYMBOL drivers/cdrom/cdrom 0x683af2e8 cdrom_media_changed +EXPORT_SYMBOL drivers/cdrom/cdrom 0x6efbc657 cdrom_open +EXPORT_SYMBOL drivers/cdrom/cdrom 0x76e56882 cdrom_mode_select +EXPORT_SYMBOL drivers/cdrom/cdrom 0x9cfc8536 cdrom_number_of_slots +EXPORT_SYMBOL drivers/cdrom/cdrom 0xb7b1b574 cdrom_get_last_written +EXPORT_SYMBOL drivers/cdrom/cdrom 0xcf212d26 register_cdrom +EXPORT_SYMBOL drivers/cdrom/cdrom 0xef0a40e1 cdrom_release +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x07aa3454 ipmi_get_version +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x0d5be584 ipmi_get_my_LUN +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x0dab2bb7 ipmi_unregister_for_cmd +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x0de400f0 ipmi_register_for_cmd +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x23485191 ipmi_set_maintenance_mode +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x2d9ffd98 ipmi_get_my_address +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x2e125176 ipmi_set_my_address +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x30d9517d ipmi_request_settime +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x32fb5421 ipmi_smi_watcher_unregister +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x40f2b10c ipmi_alloc_smi_msg +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x578d68f3 ipmi_destroy_user +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x6c2f3636 ipmi_poll_interface +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x7ce1da23 ipmi_set_my_LUN +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x804f922a ipmi_addr_length +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x8676cc0f ipmi_smi_watcher_register +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x8f0f0d3f ipmi_smi_add_proc_entry +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x90a1d303 ipmi_unregister_smi +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xa528bbd9 ipmi_request_supply_msgs +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xabcf2c92 ipmi_set_gets_events +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xbda10d09 ipmi_get_maintenance_mode +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xcb91df2d ipmi_register_smi +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xd267e51b ipmi_create_user +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xe4f4665b ipmi_validate_addr +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xe6173f13 ipmi_smi_watchdog_pretimeout +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xf70154f2 ipmi_free_recv_msg +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xfc2226bb ipmi_smi_msg_received +EXPORT_SYMBOL drivers/input/input-polldev 0x188740a6 input_allocate_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0x392d810f input_unregister_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0x6fb6a214 input_register_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0xe42540ca input_free_polled_device +EXPORT_SYMBOL drivers/input/serio/libps2 0x1c4f4d91 ps2_init +EXPORT_SYMBOL drivers/input/serio/libps2 0x3b144b12 ps2_cmd_aborted +EXPORT_SYMBOL drivers/input/serio/libps2 0x44884bee ps2_handle_ack +EXPORT_SYMBOL drivers/input/serio/libps2 0x50670af1 ps2_command +EXPORT_SYMBOL drivers/input/serio/libps2 0x9994c0ca ps2_is_keyboard_id +EXPORT_SYMBOL drivers/input/serio/libps2 0xc90b799d ps2_drain +EXPORT_SYMBOL drivers/input/serio/libps2 0xdd04492c ps2_sendbyte +EXPORT_SYMBOL drivers/input/serio/libps2 0xff00f935 ps2_handle_response +EXPORT_SYMBOL drivers/input/serio/serio 0x3bf6c21b serio_reconnect +EXPORT_SYMBOL drivers/input/serio/serio 0x57edd65a serio_rescan +EXPORT_SYMBOL drivers/input/serio/serio 0x5bb5e12d serio_unregister_child_port +EXPORT_SYMBOL drivers/input/serio/serio 0x5d8b24d7 __serio_register_port +EXPORT_SYMBOL drivers/input/serio/serio 0x96985a7b __serio_register_driver +EXPORT_SYMBOL drivers/input/serio/serio 0xabba2821 serio_unregister_driver +EXPORT_SYMBOL drivers/input/serio/serio 0xb064cbdd serio_interrupt +EXPORT_SYMBOL drivers/input/serio/serio 0xc95a9d8b serio_open +EXPORT_SYMBOL drivers/input/serio/serio 0xe4e03870 serio_unregister_port +EXPORT_SYMBOL drivers/input/serio/serio 0xf49c08e4 serio_close +EXPORT_SYMBOL drivers/md/dm-log 0x5250e144 dm_dirty_log_create +EXPORT_SYMBOL drivers/md/dm-log 0x52b18da8 dm_dirty_log_type_register +EXPORT_SYMBOL drivers/md/dm-log 0xe8be4991 dm_dirty_log_type_unregister +EXPORT_SYMBOL drivers/md/dm-log 0xee590d80 dm_dirty_log_destroy +EXPORT_SYMBOL drivers/md/dm-mod 0x10b0d437 dm_table_get_mode +EXPORT_SYMBOL drivers/md/dm-mod 0x1f0c6ef0 dm_io_client_resize +EXPORT_SYMBOL drivers/md/dm-mod 0x2852b52a dm_table_put +EXPORT_SYMBOL drivers/md/dm-mod 0x39726f42 dm_table_unplug_all +EXPORT_SYMBOL drivers/md/dm-mod 0x4a06ec5c dm_io_client_create +EXPORT_SYMBOL drivers/md/dm-mod 0x62ba7553 dm_put_device +EXPORT_SYMBOL drivers/md/dm-mod 0x6491171d dm_get_mapinfo +EXPORT_SYMBOL drivers/md/dm-mod 0x6649c2a0 dm_kcopyd_client_destroy +EXPORT_SYMBOL drivers/md/dm-mod 0x6d1c0f34 dm_unregister_target +EXPORT_SYMBOL drivers/md/dm-mod 0x7e18cfd6 dm_table_get +EXPORT_SYMBOL drivers/md/dm-mod 0x89f6e3ea dm_register_target +EXPORT_SYMBOL drivers/md/dm-mod 0xa8cf7bb0 dm_table_get_md +EXPORT_SYMBOL drivers/md/dm-mod 0xba181508 dm_table_get_size +EXPORT_SYMBOL drivers/md/dm-mod 0xbfbb9b7f dm_table_event +EXPORT_SYMBOL drivers/md/dm-mod 0xc61d032f dm_io_client_destroy +EXPORT_SYMBOL drivers/md/dm-mod 0xc79bcd36 dm_vcalloc +EXPORT_SYMBOL drivers/md/dm-mod 0xd4fb6013 dm_kcopyd_copy +EXPORT_SYMBOL drivers/md/dm-mod 0xd5ae06fb dm_io +EXPORT_SYMBOL drivers/md/dm-mod 0xdc355d1e dm_get_device +EXPORT_SYMBOL drivers/md/dm-mod 0xfbaa9988 dm_kcopyd_client_create +EXPORT_SYMBOL drivers/md/md-mod 0x021bb825 md_wait_for_blocked_rdev +EXPORT_SYMBOL drivers/md/md-mod 0x0a7fb9ea md_done_sync +EXPORT_SYMBOL drivers/md/md-mod 0x183d6729 md_wakeup_thread +EXPORT_SYMBOL drivers/md/md-mod 0x1f61a0e3 md_unregister_thread +EXPORT_SYMBOL drivers/md/md-mod 0x20c650e9 bitmap_endwrite +EXPORT_SYMBOL drivers/md/md-mod 0x2eb2e729 register_md_personality +EXPORT_SYMBOL drivers/md/md-mod 0x3072d8d8 bitmap_start_sync +EXPORT_SYMBOL drivers/md/md-mod 0x3c8ac043 md_error +EXPORT_SYMBOL drivers/md/md-mod 0x3d858e05 bitmap_unplug +EXPORT_SYMBOL drivers/md/md-mod 0x4d9b66a0 md_write_start +EXPORT_SYMBOL drivers/md/md-mod 0x549729dd bitmap_close_sync +EXPORT_SYMBOL drivers/md/md-mod 0x6359ce20 md_register_thread +EXPORT_SYMBOL drivers/md/md-mod 0x7d8a1227 bitmap_cond_end_sync +EXPORT_SYMBOL drivers/md/md-mod 0x9d03674f unregister_md_personality +EXPORT_SYMBOL drivers/md/md-mod 0xa1a09efd md_check_recovery +EXPORT_SYMBOL drivers/md/md-mod 0xa7fb1697 md_write_end +EXPORT_SYMBOL drivers/md/md-mod 0xb355ec38 bitmap_end_sync +EXPORT_SYMBOL drivers/md/md-mod 0xbc34d4b8 bitmap_startwrite +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x1183cf28 flexcop_i2c_request +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x3b42aa1b flexcop_dump_reg +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x3c5ae875 flexcop_device_initialize +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x3c8c7873 flexcop_sram_ctrl +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x3ca02c3e flexcop_device_kmalloc +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x4659a07f flexcop_wan_set_speed +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x49bd2489 flexcop_eeprom_check_mac_addr +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x558f5280 flexcop_pass_dmx_packets +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x73583d3a flexcop_device_exit +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x8f9c31ed flexcop_sram_set_dest +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xbbc423ac flexcop_device_kfree +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xc6cada57 flexcop_pass_dmx_data +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x00cbdc37 dvb_ringbuffer_flush_spinlock_wakeup +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x04284f70 dvb_dmx_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x0925b618 dvb_register_adapter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x0cbaa9c6 dvb_dmx_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x13ee8494 dvb_ringbuffer_free +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x14c136db dvb_ringbuffer_empty +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x17206765 dvb_dmxdev_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x2bc3d7b0 dvb_ca_en50221_camchange_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x36c8ea1f dvb_frontend_sleep_until +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x3add409e dvb_ca_en50221_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x41f8da4f dvb_ca_en50221_frda_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x4a5ad2b0 dvb_ringbuffer_read_user +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x4d860310 dvb_net_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x509efc7d dvb_ca_en50221_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x645606cc dvb_register_frontend +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x6b00c62c dvb_ringbuffer_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x6e8eb108 dvb_generic_open +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x72db3322 dvb_frontend_detach +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x74a5a698 dvb_filter_pes2ts_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x75fd1a2c dvb_unregister_device +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x7d829007 dvb_net_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x80e3832d dvb_filter_get_ac3info +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x8b49a23f timeval_usec_diff +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x9169d5f6 dvb_generic_ioctl +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x9856dd05 dvb_dmx_swfilter_204 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xac4ca1b0 intlog2 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb43a698e dvb_register_device +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xc9cb9b3e dvb_frontend_reinitialise +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xcc41083f dvb_ringbuffer_write +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xd2b248f2 dvb_dmx_swfilter_packets +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xd4e6af58 dvb_unregister_frontend +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xd6fd77bc dvb_ca_en50221_camready_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xe54b83ca dvb_ringbuffer_read +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xe5ae8707 intlog10 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xe8074fa5 dvb_ringbuffer_avail +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xeb0f4fc2 dvb_generic_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf826deb0 dvb_filter_pes2ts +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf9e55cda dvb_dmxdev_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xfa16b4e3 dvb_dmx_swfilter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xffe61979 dvb_unregister_adapter +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x26dc22b2 dvb_usb_generic_write +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x27eab7a0 dvb_usb_device_init +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x5881fbcb dvb_usb_nec_rc_key_to_event +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x62ad06d1 dvb_usb_get_hexline +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x6c3f0034 usb_cypress_load_firmware +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x7c59ac96 dvb_usb_device_exit +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xf5f55665 dvb_usb_generic_rw +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0x2edc4728 af9005_rc_keys +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0x32085461 af9005_rc_decode +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0xd3383957 af9005_rc_keys_size +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x16f4d23a dibusb2_0_streaming_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x20870426 dibusb_i2c_algo +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x2a03c616 dibusb2_0_power_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x37b5fbf3 dibusb_dib3000mc_tuner_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x508dd542 dibusb_dib3000mc_frontend_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x65a940e1 dibusb_streaming_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x66d1ca78 dibusb_rc_query +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xa8bf9308 dibusb_read_eeprom_byte +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xc6920020 dibusb_power_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xd0f18949 dibusb_pid_filter +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xd4d3dddc dibusb_rc_keys +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xf099f3df dibusb_pid_filter_ctrl +EXPORT_SYMBOL drivers/media/dvb/frontends/af9013 0xf12e52c6 af9013_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/bcm3510 0x17e6fc65 bcm3510_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx22700 0xe1f9bbf8 cx22700_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx22702 0x656abfac cx22702_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24110 0xb059dfc7 cx24110_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24116 0x89bb9be4 cx24116_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24123 0x275c8e34 cx24123_get_tuner_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24123 0x5668cc17 cx24123_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib0070 0xbac1396c dib0070_wbd_offset +EXPORT_SYMBOL drivers/media/dvb/frontends/dib0070 0xf970db04 dib0070_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mb 0x48739e12 dib3000mb_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x24d28655 dib3000mc_get_tuner_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x33d38def dib3000mc_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x576210ae dib3000mc_pid_parse +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x97eb25f5 dib3000mc_pid_control +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0xe1a0a40a dib3000mc_set_config +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0xf9830324 dib3000mc_i2c_enumeration +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000m 0x971d4126 dib7000m_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000m 0x99ebcd6b dib7000m_get_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x17addf50 dib7000p_i2c_enumeration +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x17b620bd dib7000p_get_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x65e72a10 dib7000p_set_gpio +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x9b56a74b dib7000p_set_wbd_ref +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xc0e22f98 dib7000pc_detection +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xdf7db9c2 dib7000p_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0x7180b092 dibx000_get_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0xcde9c34e dibx000_init_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0xceecf6d8 dibx000_exit_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dvb-pll 0x6734c3bd dvb_pll_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/isl6421 0xc42a85f3 isl6421_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/itd1000 0x100cea6a itd1000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lgdt330x 0xfbd3076e lgdt330x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lnbp21 0xf591c5e3 lnbp21_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/mt312 0xbba490ef mt312_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/mt352 0x8cf059db mt352_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/nxt200x 0x2b1d61f1 nxt200x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/nxt6000 0xb2b4b4a5 nxt6000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1409 0xcb352274 s5h1409_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1411 0xc864b929 s5h1411_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1420 0xc1fe299a s5h1420_get_tuner_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1420 0xd56c9a24 s5h1420_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/si21xx 0x99872731 si21xx_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stb6000 0x666175b5 stb6000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0288 0x1d0b2564 stv0288_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0297 0x3fb47105 stv0297_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0299 0x0d1d1ffe stv0299_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10023 0xaf714d7b tda10023_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10048 0x3e34cc79 tda10048_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda1004x 0x0c5c73c4 tda10046_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda1004x 0x2b1dca34 tda10045_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10086 0x319588e8 tda10086_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda8083 0xdec93316 tda8083_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda826x 0x62f23fdf tda826x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/ves1820 0x6e921ee3 ves1820_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/zl10353 0xd2875a0a zl10353_attach +EXPORT_SYMBOL drivers/media/dvb/ttusb-dec/ttusbdecfe 0xc3234ad1 ttusbdecfe_dvbs_attach +EXPORT_SYMBOL drivers/media/dvb/ttusb-dec/ttusbdecfe 0xe8e44b1b ttusbdecfe_dvbt_attach +EXPORT_SYMBOL drivers/media/video/cx2341x 0x226b4360 cx2341x_ctrl_get_menu +EXPORT_SYMBOL drivers/media/video/cx2341x 0x484d9064 cx2341x_ctrl_query +EXPORT_SYMBOL drivers/media/video/cx2341x 0x61b38569 cx2341x_ext_ctrls +EXPORT_SYMBOL drivers/media/video/cx2341x 0x62f2c86b cx2341x_log_status +EXPORT_SYMBOL drivers/media/video/cx2341x 0x7f09da7c cx2341x_fill_defaults +EXPORT_SYMBOL drivers/media/video/cx2341x 0xcf8b77a4 cx2341x_mpeg_ctrls +EXPORT_SYMBOL drivers/media/video/cx2341x 0xe58ec2e3 cx2341x_update +EXPORT_SYMBOL drivers/media/video/em28xx/em28xx 0x3b769171 em28xx_unregister_extension +EXPORT_SYMBOL drivers/media/video/em28xx/em28xx 0xd5670442 em28xx_register_extension +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x39ab43f8 gspca_disconnect +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x3dab5d72 gspca_suspend +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x9670af2c gspca_debug +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xa4148c9a gspca_frame_add +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xb45632bb gspca_get_i_frame +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xbd86f3e1 gspca_auto_gain_n_exposure +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xbdafb56c gspca_resume +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xe057238e gspca_dev_probe +EXPORT_SYMBOL drivers/media/video/mxc/capture/ipu_prp_enc 0x0c77a97a prp_enc_deselect +EXPORT_SYMBOL drivers/media/video/mxc/capture/ipu_prp_enc 0xafd9dc5e prp_enc_select +EXPORT_SYMBOL drivers/media/video/mxc/capture/ipu_prp_vf_sdc 0x68ecdfbb prp_vf_sdc_deselect +EXPORT_SYMBOL drivers/media/video/mxc/capture/ipu_prp_vf_sdc 0x7e4b81ce prp_vf_sdc_select +EXPORT_SYMBOL drivers/media/video/mxc/capture/ipu_prp_vf_sdc_bg 0x5eb1c988 prp_vf_sdc_select_bg +EXPORT_SYMBOL drivers/media/video/mxc/capture/ipu_prp_vf_sdc_bg 0x600125b4 prp_vf_sdc_deselect_bg +EXPORT_SYMBOL drivers/media/video/mxc/capture/ipu_still 0x761b20eb prp_still_deselect +EXPORT_SYMBOL drivers/media/video/mxc/capture/ipu_still 0xca55481b prp_still_select +EXPORT_SYMBOL drivers/media/video/mxc/capture/ov3640_camera 0x262439a2 set_mclk_rate +EXPORT_SYMBOL drivers/media/video/tveeprom 0x760bc376 tveeprom_hauppauge_analog +EXPORT_SYMBOL drivers/media/video/tveeprom 0xd2df554e tveeprom_read +EXPORT_SYMBOL drivers/media/video/v4l1-compat 0x1ee17843 v4l_compat_translate_ioctl +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x03165a85 v4l2_ctrl_get_menu +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x1c427ecb v4l2_ctrl_query_fill +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x1dcaa0c8 v4l2_prio_max +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x2f639468 v4l2_prio_check +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x42c8e001 v4l2_ctrl_next +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x495426ee v4l2_ctrl_get_name +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x50766d69 v4l2_ctrl_query_menu_valid_items +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x57abfbd8 v4l2_chip_match_host +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x5fef1b4a v4l2_ctrl_query_fill_std +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x66a9d694 v4l2_i2c_attach +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x76ba9a9a v4l2_prio_open +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x7a9a1c1c v4l2_chip_ident_i2c_client +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x95284709 v4l2_prio_close +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x9c7de443 v4l2_prio_change +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xbecd2858 v4l2_prio_init +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xc369097d v4l2_ctrl_check +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xd464e760 v4l2_ctrl_query_menu +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xe02ac886 v4l2_chip_match_i2c_client +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x1d40e5dc videobuf_dvb_get_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x2a94d9ae videobuf_dvb_find_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x4e9dc089 videobuf_dvb_unregister_bus +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x6bf2ca1b videobuf_dvb_register_bus +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x78682d6f videobuf_dvb_dealloc_frontends +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0xec3dba02 videobuf_dvb_alloc_frontend +EXPORT_SYMBOL drivers/media/video/videodev 0x032eec34 video_device_release +EXPORT_SYMBOL drivers/media/video/videodev 0x123959a1 v4l2_type_names +EXPORT_SYMBOL drivers/media/video/videodev 0x3adbd595 v4l2_field_names +EXPORT_SYMBOL drivers/media/video/videodev 0x45ada5de video_device_alloc +EXPORT_SYMBOL drivers/media/video/videodev 0x5ebefe4b v4l_printk_ioctl +EXPORT_SYMBOL drivers/media/video/videodev 0x68f60573 video_unregister_device +EXPORT_SYMBOL drivers/media/video/videodev 0x97ac070e __video_ioctl2 +EXPORT_SYMBOL drivers/media/video/videodev 0x9be1ab80 video_usercopy +EXPORT_SYMBOL drivers/media/video/videodev 0xa925ced1 video_register_device +EXPORT_SYMBOL drivers/media/video/videodev 0xca075059 video_register_device_index +EXPORT_SYMBOL drivers/media/video/videodev 0xdc14d2fa video_devdata +EXPORT_SYMBOL drivers/media/video/videodev 0xe2b92059 v4l2_video_std_construct +EXPORT_SYMBOL drivers/media/video/videodev 0xf3251e7b v4l2_norm_to_name +EXPORT_SYMBOL drivers/media/video/videodev 0xf792fd23 video_device_release_empty +EXPORT_SYMBOL drivers/media/video/videodev 0xfe199bdd video_ioctl2 +EXPORT_SYMBOL drivers/mmc/card/unifi_fs/unifi_fs 0x305c692c fs_sdio_writeb +EXPORT_SYMBOL drivers/mmc/card/unifi_fs/unifi_fs 0x38a132a2 fs_sdio_set_block_size +EXPORT_SYMBOL drivers/mmc/card/unifi_fs/unifi_fs 0x397ec9d4 fs_sdio_readb +EXPORT_SYMBOL drivers/mmc/card/unifi_fs/unifi_fs 0x3e4e5443 fs_sdio_block_rw +EXPORT_SYMBOL drivers/mmc/card/unifi_fs/unifi_fs 0x54e5182a fs_sdio_hard_reset +EXPORT_SYMBOL drivers/mmc/card/unifi_fs/unifi_fs 0x94a356ef fs_sdio_unregister_driver +EXPORT_SYMBOL drivers/mmc/card/unifi_fs/unifi_fs 0xcae1b944 fs_sdio_register_driver +EXPORT_SYMBOL drivers/mmc/card/unifi_fs/unifi_fs 0xcdb8a020 fs_sdio_enable_interrupt +EXPORT_SYMBOL drivers/mmc/card/unifi_fs/unifi_fs 0xdeee02ec fs_sdio_enable +EXPORT_SYMBOL drivers/mmc/card/unifi_fs/unifi_fs 0xe7bbb1ab fs_sdio_set_max_clock_speed +EXPORT_SYMBOL drivers/mtd/onenand/onenand 0x1658e6d2 onenand_default_bbt +EXPORT_SYMBOL drivers/mtd/onenand/onenand 0xe473a26e onenand_scan_bbt +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x1df5294b sirdev_get_instance +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x564e4970 sirdev_raw_read +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x64785ecd sirdev_write_complete +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x74a731b3 sirdev_set_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x7962cda4 sirdev_receive +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x7aba70a0 irda_register_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x9fb10470 irda_unregister_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xa8d5d078 sirdev_set_dtr_rts +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xc67f18f7 sirdev_raw_write +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xf4e868dc sirdev_put_instance +EXPORT_SYMBOL drivers/net/phy/libphy 0x0c21ca91 phy_disable_interrupts +EXPORT_SYMBOL drivers/net/phy/libphy 0x0fc11eaf phy_attach +EXPORT_SYMBOL drivers/net/phy/libphy 0x1da1268d phy_driver_register +EXPORT_SYMBOL drivers/net/phy/libphy 0x1fd1247f phy_stop +EXPORT_SYMBOL drivers/net/phy/libphy 0x22004799 phy_start_interrupts +EXPORT_SYMBOL drivers/net/phy/libphy 0x22ceabb3 phy_ethtool_sset +EXPORT_SYMBOL drivers/net/phy/libphy 0x519bd071 mdiobus_free +EXPORT_SYMBOL drivers/net/phy/libphy 0x533cb9ce phy_register_fixup_for_id +EXPORT_SYMBOL drivers/net/phy/libphy 0x53523dc3 phy_connect +EXPORT_SYMBOL drivers/net/phy/libphy 0x5b10e9c0 mdiobus_register +EXPORT_SYMBOL drivers/net/phy/libphy 0x5eb6ae2d phy_ethtool_gset +EXPORT_SYMBOL drivers/net/phy/libphy 0x6269ef97 phy_driver_unregister +EXPORT_SYMBOL drivers/net/phy/libphy 0x63bc0396 phy_scan_fixups +EXPORT_SYMBOL drivers/net/phy/libphy 0x6f11f672 mdiobus_scan +EXPORT_SYMBOL drivers/net/phy/libphy 0x7082dfd6 phy_mii_ioctl +EXPORT_SYMBOL drivers/net/phy/libphy 0x74c86900 phy_register_fixup_for_uid +EXPORT_SYMBOL drivers/net/phy/libphy 0x751ea488 genphy_update_link +EXPORT_SYMBOL drivers/net/phy/libphy 0x7a0ded32 genphy_read_status +EXPORT_SYMBOL drivers/net/phy/libphy 0x7a960478 mdiobus_read +EXPORT_SYMBOL drivers/net/phy/libphy 0x7cf10a60 genphy_config_advert +EXPORT_SYMBOL drivers/net/phy/libphy 0x854bd7ac phy_stop_interrupts +EXPORT_SYMBOL drivers/net/phy/libphy 0x86ec4e54 mdio_bus_type +EXPORT_SYMBOL drivers/net/phy/libphy 0x89a39f8e phy_start +EXPORT_SYMBOL drivers/net/phy/libphy 0x8c594bb2 phy_device_create +EXPORT_SYMBOL drivers/net/phy/libphy 0x8eb5c753 phy_enable_interrupts +EXPORT_SYMBOL drivers/net/phy/libphy 0x98d56358 phy_start_aneg +EXPORT_SYMBOL drivers/net/phy/libphy 0xa1b7822e get_phy_id +EXPORT_SYMBOL drivers/net/phy/libphy 0xa246cc0c mdiobus_write +EXPORT_SYMBOL drivers/net/phy/libphy 0xa5c3adfd mdiobus_unregister +EXPORT_SYMBOL drivers/net/phy/libphy 0xb04ab830 phy_disconnect +EXPORT_SYMBOL drivers/net/phy/libphy 0xbc5b556a phy_sanitize_settings +EXPORT_SYMBOL drivers/net/phy/libphy 0xcceb3626 phy_detach +EXPORT_SYMBOL drivers/net/phy/libphy 0xcdd7450f genphy_restart_aneg +EXPORT_SYMBOL drivers/net/phy/libphy 0xe0614195 phy_print_status +EXPORT_SYMBOL drivers/net/phy/libphy 0xe38b200a genphy_config_aneg +EXPORT_SYMBOL drivers/net/phy/libphy 0xf8ae0f13 phy_register_fixup +EXPORT_SYMBOL drivers/net/phy/libphy 0xfe213b58 mdiobus_alloc +EXPORT_SYMBOL drivers/net/ppp_generic 0x25a3ea85 ppp_unregister_channel +EXPORT_SYMBOL drivers/net/ppp_generic 0x3d6edae2 ppp_register_compressor +EXPORT_SYMBOL drivers/net/ppp_generic 0x45375dfd ppp_input_error +EXPORT_SYMBOL drivers/net/ppp_generic 0x46dae07e ppp_output_wakeup +EXPORT_SYMBOL drivers/net/ppp_generic 0x5ec2bd0f ppp_channel_index +EXPORT_SYMBOL drivers/net/ppp_generic 0x8103634b ppp_unit_number +EXPORT_SYMBOL drivers/net/ppp_generic 0x871356ef ppp_unregister_compressor +EXPORT_SYMBOL drivers/net/ppp_generic 0xb2a6474c ppp_input +EXPORT_SYMBOL drivers/net/ppp_generic 0xcab06c99 ppp_register_channel +EXPORT_SYMBOL drivers/net/pppox 0x28704bc7 pppox_ioctl +EXPORT_SYMBOL drivers/net/pppox 0x85055dc5 pppox_unbind_sock +EXPORT_SYMBOL drivers/net/pppox 0xc3298cce register_pppox_proto +EXPORT_SYMBOL drivers/net/pppox 0xe0ff7a18 unregister_pppox_proto +EXPORT_SYMBOL drivers/net/slhc 0x0ff2b602 slhc_compress +EXPORT_SYMBOL drivers/net/slhc 0x23c8f257 slhc_uncompress +EXPORT_SYMBOL drivers/net/slhc 0xa63d85ab slhc_remember +EXPORT_SYMBOL drivers/net/slhc 0xb5ca1c46 slhc_free +EXPORT_SYMBOL drivers/net/slhc 0xdfc5169b slhc_init +EXPORT_SYMBOL drivers/net/slhc 0xe8794ce1 slhc_toss +EXPORT_SYMBOL drivers/scsi/raid_class 0x15a4f27a raid_class_release +EXPORT_SYMBOL drivers/scsi/raid_class 0x1d4ac059 raid_class_attach +EXPORT_SYMBOL drivers/scsi/raid_class 0x94bf087c raid_component_add +EXPORT_SYMBOL drivers/usb/host/sl811-hcd 0xe211ff10 sl811h_driver +EXPORT_SYMBOL drivers/usb/serial/usbserial 0x597ecd59 usb_serial_resume +EXPORT_SYMBOL drivers/usb/serial/usbserial 0xa0616d0b usb_serial_suspend +EXPORT_SYMBOL drivers/w1/wire 0x4d1418a8 w1_add_master_device +EXPORT_SYMBOL drivers/w1/wire 0x4dca6d29 w1_register_family +EXPORT_SYMBOL drivers/w1/wire 0xd531690f w1_unregister_family +EXPORT_SYMBOL drivers/w1/wire 0xe67f95e1 w1_remove_master_device +EXPORT_SYMBOL fs/configfs/configfs 0x65d2cd48 configfs_register_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0x7f23f1b3 config_item_put +EXPORT_SYMBOL fs/configfs/configfs 0x810c5fe5 config_group_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0x87bd02ce configfs_undepend_item +EXPORT_SYMBOL fs/configfs/configfs 0x88647419 config_item_get +EXPORT_SYMBOL fs/configfs/configfs 0x903e8585 configfs_unregister_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0xa5063ce7 config_group_init +EXPORT_SYMBOL fs/configfs/configfs 0xa953447e config_item_init +EXPORT_SYMBOL fs/configfs/configfs 0xc465e3c8 config_item_set_name +EXPORT_SYMBOL fs/configfs/configfs 0xcae1db9d config_item_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0xd94c33f9 config_group_find_item +EXPORT_SYMBOL fs/configfs/configfs 0xdbecf705 configfs_depend_item +EXPORT_SYMBOL fs/jbd2/jbd2 0x0e9fdaa4 jbd2_journal_release_jbd_inode +EXPORT_SYMBOL fs/jbd2/jbd2 0x1a3e108c jbd2_journal_errno +EXPORT_SYMBOL fs/jbd2/jbd2 0x1b2c6759 jbd2_journal_unlock_updates +EXPORT_SYMBOL fs/jbd2/jbd2 0x1e8626db jbd2_journal_init_dev +EXPORT_SYMBOL fs/jbd2/jbd2 0x3b375483 jbd2_journal_flush +EXPORT_SYMBOL fs/jbd2/jbd2 0x3d5ffb50 jbd2_journal_release_buffer +EXPORT_SYMBOL fs/jbd2/jbd2 0x409f98f4 jbd2_journal_update_format +EXPORT_SYMBOL fs/jbd2/jbd2 0x414bf73d jbd2_journal_forget +EXPORT_SYMBOL fs/jbd2/jbd2 0x4361427e jbd2_journal_init_jbd_inode +EXPORT_SYMBOL fs/jbd2/jbd2 0x4aef9303 jbd2_journal_dirty_metadata +EXPORT_SYMBOL fs/jbd2/jbd2 0x4f8c536b jbd2_journal_revoke +EXPORT_SYMBOL fs/jbd2/jbd2 0x58a904c0 jbd2_journal_start +EXPORT_SYMBOL fs/jbd2/jbd2 0x58b1a81e jbd2_journal_force_commit +EXPORT_SYMBOL fs/jbd2/jbd2 0x5e66ed7d jbd2_journal_check_used_features +EXPORT_SYMBOL fs/jbd2/jbd2 0x687ceb06 jbd2_journal_lock_updates +EXPORT_SYMBOL fs/jbd2/jbd2 0x6aea05fb jbd2_journal_clear_err +EXPORT_SYMBOL fs/jbd2/jbd2 0x72801046 jbd2_journal_create +EXPORT_SYMBOL fs/jbd2/jbd2 0x7937fda6 jbd2_journal_destroy +EXPORT_SYMBOL fs/jbd2/jbd2 0x7cbe5420 jbd2_journal_wipe +EXPORT_SYMBOL fs/jbd2/jbd2 0x7f6cf36f jbd2_journal_check_available_features +EXPORT_SYMBOL fs/jbd2/jbd2 0x877de407 jbd2_journal_load +EXPORT_SYMBOL fs/jbd2/jbd2 0x87f19771 jbd2_journal_extend +EXPORT_SYMBOL fs/jbd2/jbd2 0x8ab0fcea jbd2_journal_get_undo_access +EXPORT_SYMBOL fs/jbd2/jbd2 0x95b7eaf7 jbd2_journal_blocks_per_page +EXPORT_SYMBOL fs/jbd2/jbd2 0x9c16f3d8 jbd2_journal_get_write_access +EXPORT_SYMBOL fs/jbd2/jbd2 0x9c6e27ce jbd2_journal_abort +EXPORT_SYMBOL fs/jbd2/jbd2 0x9f606e9a jbd2_journal_set_features +EXPORT_SYMBOL fs/jbd2/jbd2 0xa6583a9f jbd2_journal_invalidatepage +EXPORT_SYMBOL fs/jbd2/jbd2 0xae24ac66 jbd2_journal_get_create_access +EXPORT_SYMBOL fs/jbd2/jbd2 0xb60a0851 jbd2_journal_file_inode +EXPORT_SYMBOL fs/jbd2/jbd2 0xba6a4622 jbd2_log_wait_commit +EXPORT_SYMBOL fs/jbd2/jbd2 0xc0c87b6a jbd2_journal_begin_ordered_truncate +EXPORT_SYMBOL fs/jbd2/jbd2 0xc6ad128c jbd2_journal_ack_err +EXPORT_SYMBOL fs/jbd2/jbd2 0xcba02c8b jbd2_journal_stop +EXPORT_SYMBOL fs/jbd2/jbd2 0xce00db53 jbd2_journal_init_inode +EXPORT_SYMBOL fs/jbd2/jbd2 0xdc5cb199 jbd2_journal_start_commit +EXPORT_SYMBOL fs/jbd2/jbd2 0xde626602 jbd2_journal_clear_features +EXPORT_SYMBOL fs/jbd2/jbd2 0xe98ff98e jbd2_journal_restart +EXPORT_SYMBOL fs/jbd2/jbd2 0xf750cbb3 jbd2_journal_force_commit_nested +EXPORT_SYMBOL fs/jbd2/jbd2 0xfbc5d7cd jbd2_journal_try_to_free_buffers +EXPORT_SYMBOL fs/lockd/lockd 0x4a97b69b nlmsvc_ops +EXPORT_SYMBOL fs/lockd/lockd 0xa7b91a7b lockd_down +EXPORT_SYMBOL fs/lockd/lockd 0xf6933c48 lockd_up +EXPORT_SYMBOL fs/nfs_common/nfs_acl 0xc770d1c5 nfsacl_encode +EXPORT_SYMBOL fs/nfs_common/nfs_acl 0xf12b6572 nfsacl_decode +EXPORT_SYMBOL fs/nfsd/nfsd 0x0e195c1c nfs4_acl_nfsv4_to_posix +EXPORT_SYMBOL fs/nfsd/nfsd 0x2095976a nfs4_acl_new +EXPORT_SYMBOL fs/nfsd/nfsd 0x28fb929b nfs4_acl_posix_to_nfsv4 +EXPORT_SYMBOL fs/nfsd/nfsd 0x35e33c1e nfs4_acl_write_who +EXPORT_SYMBOL fs/nfsd/nfsd 0x5a157ae4 nfs4_acl_get_whotype +EXPORT_SYMBOL fs/xfs/xfs 0xde91aafa xfs_qmcore_xfs +EXPORT_SYMBOL lib/crc-ccitt 0x3771b461 crc_ccitt +EXPORT_SYMBOL lib/crc-ccitt 0x75811312 crc_ccitt_table +EXPORT_SYMBOL lib/crc-itu-t 0xd29b009f crc_itu_t_table +EXPORT_SYMBOL lib/crc-itu-t 0xf5b4a948 crc_itu_t +EXPORT_SYMBOL lib/crc7 0xa7587646 crc7 +EXPORT_SYMBOL lib/crc7 0xd80c3603 crc7_syndrome_table +EXPORT_SYMBOL lib/libcrc32c 0x2329b292 crc32c_be +EXPORT_SYMBOL lib/libcrc32c 0x37d0b921 crc32c_le +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0x315c65fd zlib_deflateInit2 +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0x48034724 zlib_deflateReset +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xaf64ad0d zlib_deflate +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xf0caf44b zlib_deflate_workspacesize +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xf741c793 zlib_deflateEnd +EXPORT_SYMBOL net/802/p8022 0x458f1d71 unregister_8022_client +EXPORT_SYMBOL net/802/p8022 0xe466cd0f register_8022_client +EXPORT_SYMBOL net/802/p8023 0x61d9865d destroy_8023_client +EXPORT_SYMBOL net/802/p8023 0xc8325cd4 make_8023_client +EXPORT_SYMBOL net/802/psnap 0x7b74eb40 unregister_snap_client +EXPORT_SYMBOL net/802/psnap 0x8c748748 register_snap_client +EXPORT_SYMBOL net/bluetooth/bluetooth 0x196723cf hci_register_dev +EXPORT_SYMBOL net/bluetooth/bluetooth 0x24584cc7 hci_send_sco +EXPORT_SYMBOL net/bluetooth/bluetooth 0x3d84e3e8 bt_sock_recvmsg +EXPORT_SYMBOL net/bluetooth/bluetooth 0x4233510a hci_suspend_dev +EXPORT_SYMBOL net/bluetooth/bluetooth 0x494366cf hci_register_proto +EXPORT_SYMBOL net/bluetooth/bluetooth 0x4c93623a hci_resume_dev +EXPORT_SYMBOL net/bluetooth/bluetooth 0x597a4232 hci_conn_change_link_key +EXPORT_SYMBOL net/bluetooth/bluetooth 0x6cdbb836 hci_unregister_dev +EXPORT_SYMBOL net/bluetooth/bluetooth 0x7094f8ae bt_err +EXPORT_SYMBOL net/bluetooth/bluetooth 0x84c580ad bt_accept_unlink +EXPORT_SYMBOL net/bluetooth/bluetooth 0x9f3122c9 hci_unregister_proto +EXPORT_SYMBOL net/bluetooth/bluetooth 0xa0d2efc6 hci_conn_check_link_mode +EXPORT_SYMBOL net/bluetooth/bluetooth 0xa2da2893 hci_get_route +EXPORT_SYMBOL net/bluetooth/bluetooth 0xaf874e2d hci_send_acl +EXPORT_SYMBOL net/bluetooth/bluetooth 0xafd63093 hci_conn_encrypt +EXPORT_SYMBOL net/bluetooth/bluetooth 0xb5542b24 bt_sock_wait_state +EXPORT_SYMBOL net/bluetooth/bluetooth 0xb906f0ae hci_recv_fragment +EXPORT_SYMBOL net/bluetooth/bluetooth 0xbb3a1a85 bt_sock_link +EXPORT_SYMBOL net/bluetooth/bluetooth 0xbc7d4798 hci_connect +EXPORT_SYMBOL net/bluetooth/bluetooth 0xbec7b2a7 bt_accept_enqueue +EXPORT_SYMBOL net/bluetooth/bluetooth 0xc2066af0 batostr +EXPORT_SYMBOL net/bluetooth/bluetooth 0xc3b068c9 hci_free_dev +EXPORT_SYMBOL net/bluetooth/bluetooth 0xcc1fb551 baswap +EXPORT_SYMBOL net/bluetooth/bluetooth 0xd1949367 bt_accept_dequeue +EXPORT_SYMBOL net/bluetooth/bluetooth 0xdc2a9b74 bt_sock_poll +EXPORT_SYMBOL net/bluetooth/bluetooth 0xdd4173a8 hci_alloc_dev +EXPORT_SYMBOL net/bluetooth/bluetooth 0xdd68cf68 hci_register_cb +EXPORT_SYMBOL net/bluetooth/bluetooth 0xe8b6ddc0 bt_sock_register +EXPORT_SYMBOL net/bluetooth/bluetooth 0xe8f2b6ce hci_unregister_cb +EXPORT_SYMBOL net/bluetooth/bluetooth 0xec2b057e hci_conn_auth +EXPORT_SYMBOL net/bluetooth/bluetooth 0xee346a75 hci_conn_switch_role +EXPORT_SYMBOL net/bluetooth/bluetooth 0xf19294db bt_sock_unregister +EXPORT_SYMBOL net/bluetooth/bluetooth 0xfdf740f2 bt_sock_ioctl +EXPORT_SYMBOL net/bluetooth/bluetooth 0xfef8d4b8 bt_sock_unlink +EXPORT_SYMBOL net/bluetooth/l2cap 0xfc31fe88 l2cap_load +EXPORT_SYMBOL net/bridge/bridge 0xb24ef382 br_should_route_hook +EXPORT_SYMBOL net/ipv4/inet_lro 0x288d4956 lro_receive_frags +EXPORT_SYMBOL net/ipv4/inet_lro 0x45056f82 lro_receive_skb +EXPORT_SYMBOL net/ipv4/inet_lro 0x6c3b6ea7 lro_flush_pkt +EXPORT_SYMBOL net/ipv4/inet_lro 0xacc8725b lro_vlan_hwaccel_receive_frags +EXPORT_SYMBOL net/ipv4/inet_lro 0xaeffdf52 lro_vlan_hwaccel_receive_skb +EXPORT_SYMBOL net/ipv4/inet_lro 0xe61c0aa8 lro_flush_all +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x63603017 arpt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x8329020b arpt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x8c923dce arpt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0x239b5fbb ipt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0x55a3410c ipt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0x71ea08d5 ipt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x1e43b25e nf_nat_follow_master +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x3f5a1aaf nf_nat_protocol_unregister +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x4f7f5e87 nf_nat_setup_info +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x5ac946cf nf_nat_mangle_tcp_packet +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0xe6d0b6a0 nf_nat_used_tuple +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0xed0a6e15 nf_nat_mangle_udp_packet +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0xf81cff54 nf_nat_protocol_register +EXPORT_SYMBOL net/ipv4/tunnel4 0x0d32b600 xfrm4_tunnel_deregister +EXPORT_SYMBOL net/ipv4/tunnel4 0x8c171440 xfrm4_tunnel_register +EXPORT_SYMBOL net/ipv6/ipv6 0x012a4b89 inet6_del_protocol +EXPORT_SYMBOL net/ipv6/ipv6 0x2c018280 inet6_add_protocol +EXPORT_SYMBOL net/ipv6/ipv6 0x2d966d43 inet6_getname +EXPORT_SYMBOL net/ipv6/ipv6 0x2f20bd5b inet6_ioctl +EXPORT_SYMBOL net/ipv6/ipv6 0x30123eb5 icmpv6_statistics +EXPORT_SYMBOL net/ipv6/ipv6 0x30a3b128 ip6_route_me_harder +EXPORT_SYMBOL net/ipv6/ipv6 0x39194c4c ip6_frag_init +EXPORT_SYMBOL net/ipv6/ipv6 0x3a76054a ipv6_chk_prefix +EXPORT_SYMBOL net/ipv6/ipv6 0x3ca4eda2 ipv6_setsockopt +EXPORT_SYMBOL net/ipv6/ipv6 0x4da5d319 xfrm6_find_1stfragopt +EXPORT_SYMBOL net/ipv6/ipv6 0x4fa4867e rt6_lookup +EXPORT_SYMBOL net/ipv6/ipv6 0x503db397 nf_ip6_checksum +EXPORT_SYMBOL net/ipv6/ipv6 0x538383c0 unregister_inet6addr_notifier +EXPORT_SYMBOL net/ipv6/ipv6 0x5b209e43 ipv6_getsockopt +EXPORT_SYMBOL net/ipv6/ipv6 0x66403b4c ip6_xmit +EXPORT_SYMBOL net/ipv6/ipv6 0x702c13ec inet6_release +EXPORT_SYMBOL net/ipv6/ipv6 0x75e0caf3 inet6_unregister_protosw +EXPORT_SYMBOL net/ipv6/ipv6 0x7ca3eb3c ip6_route_output +EXPORT_SYMBOL net/ipv6/ipv6 0x7ecd3886 rawv6_mh_filter_register +EXPORT_SYMBOL net/ipv6/ipv6 0x88fc9e22 inet6_bind +EXPORT_SYMBOL net/ipv6/ipv6 0x89982539 in6_dev_finish_destroy +EXPORT_SYMBOL net/ipv6/ipv6 0x92aae903 inet6_register_protosw +EXPORT_SYMBOL net/ipv6/ipv6 0x9fc9e92a xfrm6_rcv_spi +EXPORT_SYMBOL net/ipv6/ipv6 0xa0c468a8 ipv6_push_nfrag_opts +EXPORT_SYMBOL net/ipv6/ipv6 0xa335c9f1 ndisc_mc_map +EXPORT_SYMBOL net/ipv6/ipv6 0xa52e9b41 ipv6_dev_get_saddr +EXPORT_SYMBOL net/ipv6/ipv6 0xb905ad82 icmpv6_err_convert +EXPORT_SYMBOL net/ipv6/ipv6 0xc0b11a8d icmpv6_send +EXPORT_SYMBOL net/ipv6/ipv6 0xce19bac5 register_inet6addr_notifier +EXPORT_SYMBOL net/ipv6/ipv6 0xdbd5be3c xfrm6_input_addr +EXPORT_SYMBOL net/ipv6/ipv6 0xdd66307e rawv6_mh_filter_unregister +EXPORT_SYMBOL net/ipv6/ipv6 0xdef376fd ip6_frag_match +EXPORT_SYMBOL net/ipv6/ipv6 0xe1a81c3a icmpv6msg_statistics +EXPORT_SYMBOL net/ipv6/ipv6 0xe690b8fd __ipv6_isatap_ifid +EXPORT_SYMBOL net/ipv6/ipv6 0xe91f8b4c ipv6_chk_addr +EXPORT_SYMBOL net/ipv6/ipv6 0xf457c35e xfrm6_rcv +EXPORT_SYMBOL net/ipv6/ipv6 0xfb9a3896 xfrm6_prepare_output +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x0da551ac ipv6_find_hdr +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x4c3b4a81 ip6t_unregister_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x746267d0 ip6t_do_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xb8bddf33 ip6t_ext_hdr +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xe15912b9 ip6t_register_table +EXPORT_SYMBOL net/ipv6/tunnel6 0x70156de9 xfrm6_tunnel_register +EXPORT_SYMBOL net/ipv6/tunnel6 0xd9b78621 xfrm6_tunnel_deregister +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0x9cd013f2 xfrm6_tunnel_alloc_spi +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0xab14e193 xfrm6_tunnel_free_spi +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0xdb1b42d1 xfrm6_tunnel_spi_lookup +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x05b7f30c ircomm_close +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x4c4e6487 ircomm_disconnect_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x674c4ae5 ircomm_control_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x86350e50 ircomm_data_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x95a81b14 ircomm_connect_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x98332dcc ircomm_connect_response +EXPORT_SYMBOL net/irda/ircomm/ircomm 0xa8434908 ircomm_open +EXPORT_SYMBOL net/irda/ircomm/ircomm 0xe9c740d4 ircomm_flow_request +EXPORT_SYMBOL net/irda/irda 0x05d7cfe5 irias_add_octseq_attrib +EXPORT_SYMBOL net/irda/irda 0x06a3ee58 irias_new_integer_value +EXPORT_SYMBOL net/irda/irda 0x07d3647c irlmp_register_service +EXPORT_SYMBOL net/irda/irda 0x08aca008 irda_device_set_media_busy +EXPORT_SYMBOL net/irda/irda 0x0bf27bc5 irlmp_disconnect_request +EXPORT_SYMBOL net/irda/irda 0x1676870f irttp_flow_request +EXPORT_SYMBOL net/irda/irda 0x19d79c82 hashbin_lock_find +EXPORT_SYMBOL net/irda/irda 0x1c51e992 hashbin_delete +EXPORT_SYMBOL net/irda/irda 0x2036ad06 irda_param_insert +EXPORT_SYMBOL net/irda/irda 0x22b0f52d hashbin_insert +EXPORT_SYMBOL net/irda/irda 0x23970a8d iriap_getvaluebyclass_request +EXPORT_SYMBOL net/irda/irda 0x2b346ed4 irttp_open_tsap +EXPORT_SYMBOL net/irda/irda 0x30827e1c irias_insert_object +EXPORT_SYMBOL net/irda/irda 0x356ea54f proc_irda +EXPORT_SYMBOL net/irda/irda 0x3b2e9df9 hashbin_remove +EXPORT_SYMBOL net/irda/irda 0x42c7c5ce irias_find_object +EXPORT_SYMBOL net/irda/irda 0x448b8aaa irda_qos_bits_to_value +EXPORT_SYMBOL net/irda/irda 0x46c1c4a2 irlmp_unregister_service +EXPORT_SYMBOL net/irda/irda 0x47b0317f irttp_connect_request +EXPORT_SYMBOL net/irda/irda 0x4f008518 irttp_dup +EXPORT_SYMBOL net/irda/irda 0x519118cc irias_add_integer_attrib +EXPORT_SYMBOL net/irda/irda 0x538fe1e0 hashbin_get_first +EXPORT_SYMBOL net/irda/irda 0x5504cf7c hashbin_new +EXPORT_SYMBOL net/irda/irda 0x56a04482 irttp_disconnect_request +EXPORT_SYMBOL net/irda/irda 0x57fb1ed2 hashbin_remove_this +EXPORT_SYMBOL net/irda/irda 0x5aad87aa irias_delete_object +EXPORT_SYMBOL net/irda/irda 0x5d609063 irias_new_object +EXPORT_SYMBOL net/irda/irda 0x5dd44c31 alloc_irdadev +EXPORT_SYMBOL net/irda/irda 0x656be9ce irlmp_connect_response +EXPORT_SYMBOL net/irda/irda 0x6621aa8a hashbin_find +EXPORT_SYMBOL net/irda/irda 0x6b043eba irda_init_max_qos_capabilies +EXPORT_SYMBOL net/irda/irda 0x6e6ae195 irttp_close_tsap +EXPORT_SYMBOL net/irda/irda 0x701e028e irias_add_string_attrib +EXPORT_SYMBOL net/irda/irda 0x7042bc54 irlmp_register_client +EXPORT_SYMBOL net/irda/irda 0x763e54a4 irlmp_unregister_client +EXPORT_SYMBOL net/irda/irda 0x7957f728 irlmp_update_client +EXPORT_SYMBOL net/irda/irda 0x7dfbf458 irttp_connect_response +EXPORT_SYMBOL net/irda/irda 0x8b530528 irttp_data_request +EXPORT_SYMBOL net/irda/irda 0x91815586 irda_param_pack +EXPORT_SYMBOL net/irda/irda 0x940aae8c irttp_udata_request +EXPORT_SYMBOL net/irda/irda 0x993ad14b irda_param_extract_all +EXPORT_SYMBOL net/irda/irda 0x9fb5da8a irlmp_close_lsap +EXPORT_SYMBOL net/irda/irda 0xa214edeb async_unwrap_char +EXPORT_SYMBOL net/irda/irda 0xac3271cf iriap_open +EXPORT_SYMBOL net/irda/irda 0xad1dd4d5 irlmp_data_request +EXPORT_SYMBOL net/irda/irda 0xb4530d84 irlap_open +EXPORT_SYMBOL net/irda/irda 0xb6bf83fc iriap_close +EXPORT_SYMBOL net/irda/irda 0xb9394173 irias_delete_value +EXPORT_SYMBOL net/irda/irda 0xbb998a0d irlap_close +EXPORT_SYMBOL net/irda/irda 0xbcd3ef13 irias_object_change_attribute +EXPORT_SYMBOL net/irda/irda 0xbe40ace9 irlmp_discovery_request +EXPORT_SYMBOL net/irda/irda 0xc898af9a async_wrap_skb +EXPORT_SYMBOL net/irda/irda 0xd7833660 irlmp_connect_request +EXPORT_SYMBOL net/irda/irda 0xde4c6b3c irlmp_service_to_hint +EXPORT_SYMBOL net/irda/irda 0xe2f84c82 hashbin_get_next +EXPORT_SYMBOL net/irda/irda 0xe8e96e94 irlmp_open_lsap +EXPORT_SYMBOL net/irda/irda 0xedd521c2 irlmp_get_discoveries +EXPORT_SYMBOL net/irda/irda 0xf39e3fb9 irda_notify_init +EXPORT_SYMBOL net/llc/llc 0x0a9e01f4 llc_sap_find +EXPORT_SYMBOL net/llc/llc 0x279f0869 llc_add_pack +EXPORT_SYMBOL net/llc/llc 0x297dce66 llc_sap_open +EXPORT_SYMBOL net/llc/llc 0x31f9b79c llc_build_and_send_ui_pkt +EXPORT_SYMBOL net/llc/llc 0x38b92846 llc_remove_pack +EXPORT_SYMBOL net/llc/llc 0x508c7700 llc_mac_hdr_init +EXPORT_SYMBOL net/llc/llc 0x52d7b2fd llc_sap_list +EXPORT_SYMBOL net/llc/llc 0x556643e3 llc_sap_list_lock +EXPORT_SYMBOL net/llc/llc 0x5cb986a9 llc_sap_close +EXPORT_SYMBOL net/llc/llc 0x6d52d63d llc_set_station_handler +EXPORT_SYMBOL net/mac80211/mac80211 0x013e5bd1 ieee80211_register_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x1be75ba1 ieee80211_tx_status_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x21c97b50 ieee80211_tx_status +EXPORT_SYMBOL net/mac80211/mac80211 0x232bc9d3 ieee80211_rate_control_register +EXPORT_SYMBOL net/mac80211/mac80211 0x24543b8b ieee80211_wake_queues +EXPORT_SYMBOL net/mac80211/mac80211 0x25036aee __ieee80211_rx +EXPORT_SYMBOL net/mac80211/mac80211 0x2bbedeb8 ieee80211_rate_control_unregister +EXPORT_SYMBOL net/mac80211/mac80211 0x3d36e7a6 ieee80211_stop_tx_ba_cb +EXPORT_SYMBOL net/mac80211/mac80211 0x3e130415 ieee80211_get_tkip_key +EXPORT_SYMBOL net/mac80211/mac80211 0x3fe602c3 ieee80211_beacon_get +EXPORT_SYMBOL net/mac80211/mac80211 0x41e9f2c9 ieee80211_ctstoself_get +EXPORT_SYMBOL net/mac80211/mac80211 0x4243a9ed ieee80211_stop_queues +EXPORT_SYMBOL net/mac80211/mac80211 0x46630942 ieee80211_unregister_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x4b727730 __ieee80211_get_assoc_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x5b97db0a ieee80211_get_hdrlen_from_skb +EXPORT_SYMBOL net/mac80211/mac80211 0x65d7910e ieee80211_ctstoself_duration +EXPORT_SYMBOL net/mac80211/mac80211 0x65f860bb ieee80211_start_tx_ba_cb +EXPORT_SYMBOL net/mac80211/mac80211 0x79ad93dc ieee80211_queue_stopped +EXPORT_SYMBOL net/mac80211/mac80211 0x7a9a9096 __ieee80211_get_tx_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x84f19423 ieee80211_free_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x850c6d18 ieee80211_rts_get +EXPORT_SYMBOL net/mac80211/mac80211 0x860c19a8 __ieee80211_get_radio_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x89c08b49 ieee80211_stop_tx_ba_cb_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x8c35d732 ieee80211_hdrlen +EXPORT_SYMBOL net/mac80211/mac80211 0xa323b63a __ieee80211_get_rx_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0xa3f9b0ed ieee80211_rts_duration +EXPORT_SYMBOL net/mac80211/mac80211 0xb288115b ieee80211_start_tx_ba_session +EXPORT_SYMBOL net/mac80211/mac80211 0xc360a8cb ieee80211_wake_queue +EXPORT_SYMBOL net/mac80211/mac80211 0xc3de447f ieee80211_stop_tx_ba_session +EXPORT_SYMBOL net/mac80211/mac80211 0xc4f785ce ieee80211_rx_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0xd1627cfb ieee80211_get_buffered_bc +EXPORT_SYMBOL net/mac80211/mac80211 0xd263901e ieee80211_scan_completed +EXPORT_SYMBOL net/mac80211/mac80211 0xd3213eb0 ieee80211_find_sta +EXPORT_SYMBOL net/mac80211/mac80211 0xe62a2733 ieee80211_alloc_hw +EXPORT_SYMBOL net/mac80211/mac80211 0xe8957add ieee80211_stop_queue +EXPORT_SYMBOL net/mac80211/mac80211 0xec910505 ieee80211_start_tx_ba_cb_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0xf5955a39 wiphy_to_hw +EXPORT_SYMBOL net/mac80211/mac80211 0xf8578042 ieee80211_generic_frame_duration +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x0e2842fb ip_vs_tcp_conn_listen +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x10628e56 ip_vs_conn_put +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x12008e8c ip_vs_conn_in_get +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x4e50490a register_ip_vs_app +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x630e7d9b ip_vs_conn_out_get +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x7176a134 ip_vs_get_debug_level +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x74fe86eb ip_vs_conn_new +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x8e2c373b unregister_ip_vs_scheduler +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xa1dbc2d8 ip_vs_proto_name +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xa235feb8 ip_vs_skb_replace +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xcd7786e2 register_ip_vs_app_inc +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xe8b62c38 unregister_ip_vs_app +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xf8200899 register_ip_vs_scheduler +EXPORT_SYMBOL net/netfilter/nf_conntrack 0x124a9b6a __nf_ct_ext_add +EXPORT_SYMBOL net/netfilter/nf_conntrack 0x7fd82c0b __nf_ct_ext_destroy +EXPORT_SYMBOL net/netfilter/nf_conntrack_proto_gre 0x208b2e58 nf_ct_gre_keymap_flush +EXPORT_SYMBOL net/netfilter/x_tables 0x0b5263c3 xt_find_match +EXPORT_SYMBOL net/netfilter/x_tables 0x0d630a5a xt_unregister_targets +EXPORT_SYMBOL net/netfilter/x_tables 0x18b88185 xt_register_match +EXPORT_SYMBOL net/netfilter/x_tables 0x3dcd58c5 xt_alloc_table_info +EXPORT_SYMBOL net/netfilter/x_tables 0x506ffb99 xt_register_matches +EXPORT_SYMBOL net/netfilter/x_tables 0x57a21eaf xt_find_target +EXPORT_SYMBOL net/netfilter/x_tables 0x8b9bd9fa xt_unregister_target +EXPORT_SYMBOL net/netfilter/x_tables 0xb290d1d2 xt_register_targets +EXPORT_SYMBOL net/netfilter/x_tables 0xbfb9aa9f xt_register_target +EXPORT_SYMBOL net/netfilter/x_tables 0xc145ad25 xt_unregister_match +EXPORT_SYMBOL net/netfilter/x_tables 0xcaa6291a xt_unregister_matches +EXPORT_SYMBOL net/netfilter/x_tables 0xf7037dc6 xt_free_table_info +EXPORT_SYMBOL net/rfkill/rfkill 0x24e7c82f rfkill_unregister +EXPORT_SYMBOL net/rfkill/rfkill 0x31bb463e rfkill_allocate +EXPORT_SYMBOL net/rfkill/rfkill 0x383f82df rfkill_register +EXPORT_SYMBOL net/rfkill/rfkill 0x7772220d rfkill_switch_all +EXPORT_SYMBOL net/rfkill/rfkill 0xcde97c56 rfkill_free +EXPORT_SYMBOL net/rfkill/rfkill 0xdefece88 rfkill_force_state +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x12e0e556 rxrpc_kernel_free_skb +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x1ba9fef0 rxrpc_kernel_is_data_last +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x3cce11b6 rxrpc_get_server_data_key +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x469b1a85 rxrpc_kernel_accept_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x57b42b7d rxrpc_kernel_data_delivered +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x6e92b62b rxrpc_kernel_get_abort_code +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x788183b8 rxrpc_kernel_reject_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x8e931a2e key_type_rxrpc +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x91e19625 rxrpc_get_null_key +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x9e59c349 rxrpc_kernel_send_data +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xb1a07956 rxrpc_kernel_get_error_number +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xcc6fa27a rxrpc_kernel_end_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xd6a0f21c rxrpc_kernel_intercept_rx_messages +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xdd612d36 rxrpc_kernel_begin_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xe7d8484a rxrpc_kernel_abort_call +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x00c52ef5 g_make_token_header +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x273f913e gss_pseudoflavor_to_service +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x29ad99c5 svcauth_gss_flavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x411225bc gss_service_to_auth_domain_name +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x5b2cf4c1 gss_mech_get_by_name +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x7b3cc382 gss_mech_get +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x89eec501 gss_mech_register +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x8d1a827e svcauth_gss_register_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xa088abb3 gss_mech_unregister +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xa823d698 gss_mech_put +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xb5dea7ef g_token_size +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xd313051b gss_mech_get_by_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xf5d6bfa1 gss_svc_to_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xf8b2ff6e g_verify_token_header +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0055ee17 xdr_reserve_space +EXPORT_SYMBOL net/sunrpc/sunrpc 0x012638a5 auth_unix_add_addr +EXPORT_SYMBOL net/sunrpc/sunrpc 0x03ebaaff unix_domain_find +EXPORT_SYMBOL net/sunrpc/sunrpc 0x05e807a9 xdr_encode_string +EXPORT_SYMBOL net/sunrpc/sunrpc 0x065994f1 xdr_encode_opaque_fixed +EXPORT_SYMBOL net/sunrpc/sunrpc 0x07deeb3d rpc_mkpipe +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0919ba72 auth_unix_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0b851f0d xdr_init_decode +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0f668ba9 svc_auth_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x11003fce xdr_encode_array2 +EXPORT_SYMBOL net/sunrpc/sunrpc 0x12e280e3 svc_proc_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x13b84a79 xdr_decode_array2 +EXPORT_SYMBOL net/sunrpc/sunrpc 0x1672b468 cache_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x18400135 svc_prepare_thread +EXPORT_SYMBOL net/sunrpc/sunrpc 0x1ec2e6a8 xdr_buf_read_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0x241456b1 xdr_enter_page +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2919b156 xdr_decode_string_inplace +EXPORT_SYMBOL net/sunrpc/sunrpc 0x29ef7891 xdr_process_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2ae064b5 svc_authenticate +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2c179572 svcauth_unix_set_client +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2db0b402 svc_set_client +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2eec63c9 xdr_encode_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0x3020ca60 svc_reserve +EXPORT_SYMBOL net/sunrpc/sunrpc 0x35148bf2 svc_auth_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0x3984c879 auth_domain_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0x39b7a834 auth_unix_forget_old +EXPORT_SYMBOL net/sunrpc/sunrpc 0x3c5b036f sunrpc_cache_update +EXPORT_SYMBOL net/sunrpc/sunrpc 0x4c9c7c27 svc_process +EXPORT_SYMBOL net/sunrpc/sunrpc 0x4d9743b0 rpc_queue_upcall +EXPORT_SYMBOL net/sunrpc/sunrpc 0x54be7649 xdr_decode_word +EXPORT_SYMBOL net/sunrpc/sunrpc 0x55252289 auth_domain_put +EXPORT_SYMBOL net/sunrpc/sunrpc 0x6eea229d svcauth_unix_purge +EXPORT_SYMBOL net/sunrpc/sunrpc 0x71fa908a cache_flush +EXPORT_SYMBOL net/sunrpc/sunrpc 0x7556b76d svc_exit_thread +EXPORT_SYMBOL net/sunrpc/sunrpc 0x76c5081a read_bytes_from_xdr_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0x7a98a16a svc_create +EXPORT_SYMBOL net/sunrpc/sunrpc 0x822b6ee9 svc_proc_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0x83ba26a2 svc_set_num_threads +EXPORT_SYMBOL net/sunrpc/sunrpc 0x913dfcb1 cache_purge +EXPORT_SYMBOL net/sunrpc/sunrpc 0x969b2275 cache_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0x975eba21 xdr_shift_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0x99ce7a23 xdr_buf_from_iov +EXPORT_SYMBOL net/sunrpc/sunrpc 0x9c8c5eea svc_destroy +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa349321a xdr_inline_decode +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa545df21 auth_domain_find +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa9f058ce svc_drop +EXPORT_SYMBOL net/sunrpc/sunrpc 0xab12b93e xdr_read_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0xb38092d4 sunrpc_cache_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc0454d10 rpc_unlink +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc21f996c xdr_encode_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc3880471 xdr_decode_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc8e96dea qword_addhex +EXPORT_SYMBOL net/sunrpc/sunrpc 0xcbdfa334 xdr_init_encode +EXPORT_SYMBOL net/sunrpc/sunrpc 0xd1329bb0 xdr_inline_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0xd60d91b2 svc_seq_show +EXPORT_SYMBOL net/sunrpc/sunrpc 0xdc6c1a65 xdr_buf_subsegment +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe0a9118b xdr_write_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe1671a09 svc_sock_update_bufs +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe5919cb1 xdr_encode_opaque +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe5deff7f svc_create_pooled +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe84cc883 cache_check +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe8885dd2 svc_wake_up +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe97f4ce5 qword_get +EXPORT_SYMBOL net/sunrpc/sunrpc 0xeca9fc3a svc_sock_names +EXPORT_SYMBOL net/sunrpc/sunrpc 0xedcf6be4 qword_add +EXPORT_SYMBOL net/sunrpc/sunrpc 0xef0d6ffb svc_recv +EXPORT_SYMBOL net/sunrpc/sunrpc 0xfe257331 xdr_encode_word +EXPORT_SYMBOL net/tipc/tipc 0x01591c57 tipc_send_buf2name +EXPORT_SYMBOL net/tipc/tipc 0x08acf310 tipc_available_nodes +EXPORT_SYMBOL net/tipc/tipc 0x0d884103 tipc_forward_buf2name +EXPORT_SYMBOL net/tipc/tipc 0x10d40fcd tipc_isconnected +EXPORT_SYMBOL net/tipc/tipc 0x1472b270 tipc_disconnect +EXPORT_SYMBOL net/tipc/tipc 0x1479cb03 tipc_deleteport +EXPORT_SYMBOL net/tipc/tipc 0x15b5ecde tipc_set_portunreliable +EXPORT_SYMBOL net/tipc/tipc 0x16f27683 tipc_block_bearer +EXPORT_SYMBOL net/tipc/tipc 0x1f909f65 tipc_send_buf +EXPORT_SYMBOL net/tipc/tipc 0x259b74f9 tipc_acknowledge +EXPORT_SYMBOL net/tipc/tipc 0x27d8bb58 tipc_send2port +EXPORT_SYMBOL net/tipc/tipc 0x310d1bc9 tipc_detach +EXPORT_SYMBOL net/tipc/tipc 0x3712e340 tipc_portunreliable +EXPORT_SYMBOL net/tipc/tipc 0x3976041f tipc_set_portimportance +EXPORT_SYMBOL net/tipc/tipc 0x3e93b677 tipc_continue +EXPORT_SYMBOL net/tipc/tipc 0x4218efa8 tipc_reject_msg +EXPORT_SYMBOL net/tipc/tipc 0x4b2243c6 tipc_portimportance +EXPORT_SYMBOL net/tipc/tipc 0x4ba3cfc8 tipc_send2name +EXPORT_SYMBOL net/tipc/tipc 0x4e796163 tipc_get_port +EXPORT_SYMBOL net/tipc/tipc 0x52a6d884 tipc_createport_raw +EXPORT_SYMBOL net/tipc/tipc 0x538b228a tipc_withdraw +EXPORT_SYMBOL net/tipc/tipc 0x558d5996 tipc_register_media +EXPORT_SYMBOL net/tipc/tipc 0x5637ed44 tipc_get_mode +EXPORT_SYMBOL net/tipc/tipc 0x56a2c5e3 tipc_createport +EXPORT_SYMBOL net/tipc/tipc 0x59eb5ee3 tipc_recv_msg +EXPORT_SYMBOL net/tipc/tipc 0x5c0d4b5c tipc_ref_valid +EXPORT_SYMBOL net/tipc/tipc 0x62a681a3 tipc_portunreturnable +EXPORT_SYMBOL net/tipc/tipc 0x64357d3c tipc_multicast +EXPORT_SYMBOL net/tipc/tipc 0x75ea4182 tipc_send_buf2port +EXPORT_SYMBOL net/tipc/tipc 0x788bdcf9 tipc_forward_buf2port +EXPORT_SYMBOL net/tipc/tipc 0x8001e3d7 tipc_forward2port +EXPORT_SYMBOL net/tipc/tipc 0x88b73627 tipc_get_addr +EXPORT_SYMBOL net/tipc/tipc 0x8af0cc8f tipc_send_buf_fast +EXPORT_SYMBOL net/tipc/tipc 0x9c45558e tipc_enable_bearer +EXPORT_SYMBOL net/tipc/tipc 0xadd203d0 tipc_connect2port +EXPORT_SYMBOL net/tipc/tipc 0xae0103c3 tipc_shutdown +EXPORT_SYMBOL net/tipc/tipc 0xb01ffc2c tipc_forward2name +EXPORT_SYMBOL net/tipc/tipc 0xb35b672c tipc_publish +EXPORT_SYMBOL net/tipc/tipc 0xbb2b2504 tipc_send +EXPORT_SYMBOL net/tipc/tipc 0xcec8514a tipc_set_portunreturnable +EXPORT_SYMBOL net/tipc/tipc 0xd44731e5 tipc_ownidentity +EXPORT_SYMBOL net/tipc/tipc 0xda7f9d3f tipc_attach +EXPORT_SYMBOL net/tipc/tipc 0xdf5008fc tipc_peer +EXPORT_SYMBOL net/tipc/tipc 0xe7aece47 tipc_ispublished +EXPORT_SYMBOL net/tipc/tipc 0xeefd49b3 tipc_get_handle +EXPORT_SYMBOL net/tipc/tipc 0xef50a1ef tipc_disable_bearer +EXPORT_SYMBOL net/wireless/cfg80211 0x07e7ac5a ieee80211_radiotap_iterator_init +EXPORT_SYMBOL net/wireless/cfg80211 0x09c64fbd ieee80211_frequency_to_channel +EXPORT_SYMBOL net/wireless/cfg80211 0x4847a03e wiphy_free +EXPORT_SYMBOL net/wireless/cfg80211 0x54891cd7 wiphy_register +EXPORT_SYMBOL net/wireless/cfg80211 0x5937b14b wiphy_new +EXPORT_SYMBOL net/wireless/cfg80211 0xa26ec161 regulatory_hint +EXPORT_SYMBOL net/wireless/cfg80211 0xb36a6d06 wiphy_unregister +EXPORT_SYMBOL net/wireless/cfg80211 0xc4e85ec5 ieee80211_radiotap_iterator_next +EXPORT_SYMBOL net/wireless/cfg80211 0xc891f45a __ieee80211_get_channel +EXPORT_SYMBOL net/wireless/cfg80211 0xccc291b3 ieee80211_channel_to_frequency +EXPORT_SYMBOL sound/core/oss/snd-mixer-oss 0x056dbd1a snd_mixer_oss_ioctl_card +EXPORT_SYMBOL sound/core/seq/snd-seq 0x15ed78d0 snd_seq_kernel_client_write_poll +EXPORT_SYMBOL sound/core/seq/snd-seq 0x1a724fcc snd_seq_kernel_client_ctl +EXPORT_SYMBOL sound/core/seq/snd-seq 0x3fb4d161 snd_seq_kernel_client_dispatch +EXPORT_SYMBOL sound/core/seq/snd-seq 0x64546671 snd_seq_create_kernel_client +EXPORT_SYMBOL sound/core/seq/snd-seq 0x65490e84 snd_seq_kernel_client_enqueue_blocking +EXPORT_SYMBOL sound/core/seq/snd-seq 0x6bb71038 snd_seq_delete_kernel_client +EXPORT_SYMBOL sound/core/seq/snd-seq 0x7ac2f329 snd_seq_expand_var_event +EXPORT_SYMBOL sound/core/seq/snd-seq 0x7b8699eb snd_seq_event_port_detach +EXPORT_SYMBOL sound/core/seq/snd-seq 0xb8e448a0 snd_seq_set_queue_tempo +EXPORT_SYMBOL sound/core/seq/snd-seq 0xcac0a3be snd_seq_kernel_client_enqueue +EXPORT_SYMBOL sound/core/seq/snd-seq 0xe934da1d snd_seq_dump_var_event +EXPORT_SYMBOL sound/core/seq/snd-seq 0xfda5d843 snd_seq_event_port_attach +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x3a57f235 snd_seq_autoload_unlock +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x5fb02528 snd_seq_device_new +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x6339b6d0 snd_seq_device_load_drivers +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x83163896 snd_seq_device_register_driver +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xb90668b2 snd_seq_autoload_lock +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xc622fb29 snd_seq_device_unregister_driver +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x3b55d387 snd_midi_event_encode_byte +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x68b9bd07 snd_midi_event_free +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x7adfa053 snd_midi_event_encode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x998f2126 snd_midi_event_new +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x9b1825a9 snd_midi_event_no_status +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xb6327286 snd_midi_event_decode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xbc51650a snd_midi_event_reset_decode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xe58d6519 snd_midi_event_reset_encode +EXPORT_SYMBOL sound/core/seq/snd-seq-virmidi 0xb0af4811 snd_virmidi_new +EXPORT_SYMBOL sound/core/snd-rawmidi 0x0b08c90c snd_rawmidi_transmit_peek +EXPORT_SYMBOL sound/core/snd-rawmidi 0x0c58babf snd_rawmidi_kernel_write +EXPORT_SYMBOL sound/core/snd-rawmidi 0x2e35b3d6 snd_rawmidi_transmit_ack +EXPORT_SYMBOL sound/core/snd-rawmidi 0x6ec03cc9 snd_rawmidi_drain_input +EXPORT_SYMBOL sound/core/snd-rawmidi 0x73adcad4 snd_rawmidi_output_params +EXPORT_SYMBOL sound/core/snd-rawmidi 0x7caf6b59 snd_rawmidi_info_select +EXPORT_SYMBOL sound/core/snd-rawmidi 0x88a4a645 snd_rawmidi_kernel_release +EXPORT_SYMBOL sound/core/snd-rawmidi 0x8af83c2e snd_rawmidi_drain_output +EXPORT_SYMBOL sound/core/snd-rawmidi 0x8be487e2 snd_rawmidi_set_ops +EXPORT_SYMBOL sound/core/snd-rawmidi 0xaa24c9aa snd_rawmidi_new +EXPORT_SYMBOL sound/core/snd-rawmidi 0xb678ff79 snd_rawmidi_drop_output +EXPORT_SYMBOL sound/core/snd-rawmidi 0xb73d07ba snd_rawmidi_receive +EXPORT_SYMBOL sound/core/snd-rawmidi 0xc084b4b1 snd_rawmidi_kernel_read +EXPORT_SYMBOL sound/core/snd-rawmidi 0xd4db9cad snd_rawmidi_transmit_empty +EXPORT_SYMBOL sound/core/snd-rawmidi 0xf90fc61e snd_rawmidi_input_params +EXPORT_SYMBOL sound/core/snd-rawmidi 0xf9d5d219 snd_rawmidi_kernel_open +EXPORT_SYMBOL sound/core/snd-rawmidi 0xfe72c762 snd_rawmidi_transmit +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0x73c4c993 snd_mpu401_uart_interrupt_tx +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0x87233b80 snd_mpu401_uart_new +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0xfe618b58 snd_mpu401_uart_interrupt +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x3cb62b4a dm_mem_cache_client_create +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x9f60a20b dm_mem_cache_shrink +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xbeac983d dm_mem_cache_grow +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xdb26f1cd dm_mem_cache_alloc +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xed429b9b dm_mem_cache_free +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xfa469e76 dm_mem_cache_client_destroy +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-message 0x920a7a41 dm_message_parse +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x0329d132 rh_sector_to_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x05b77177 rh_delay +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x108f2649 rh_dec +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x1384f187 rh_delay_by_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x275fdd04 rh_recovery_start +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x48cf6536 rh_bio_to_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x5c2a0632 rh_recovery_end +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x62842029 rh_flush +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x8252ef05 rh_state +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x8821f9a7 rh_region_to_sector +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xa4a7321f rh_get_region_key +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xa923d788 rh_start_recovery +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xac274ed3 rh_stop_recovery +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xb513be98 rh_update_states +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xbb748327 rh_reg_set_context +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc4fdf256 rh_recovery_prepare +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc4ff7745 rh_reg_get_context +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc57bafec rh_exit +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xcbe7957e rh_inc_pending +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xd99f0978 rh_inc +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xda581f7b rh_get_region_size +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xe7f0eeed rh_init +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x29c887a9 set_tx_channels +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x60b2e316 cmdir_read +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x7789312a cmdir_write +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0x8598dabb lirc_get_pdata +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0xe6947927 lirc_register_plugin +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0xe96379eb lirc_unregister_plugin +EXPORT_SYMBOL vmlinux 0x00000000 fp_printk +EXPORT_SYMBOL vmlinux 0x00000000 fp_send_sig +EXPORT_SYMBOL vmlinux 0x00000000 kern_fp_enter +EXPORT_SYMBOL vmlinux 0x00000000 per_cpu__softirq_work_list +EXPORT_SYMBOL vmlinux 0x001698d8 fb_firmware_edid +EXPORT_SYMBOL vmlinux 0x0034d78f xfrm_state_register_afinfo +EXPORT_SYMBOL vmlinux 0x003ab179 tcp_getsockopt +EXPORT_SYMBOL vmlinux 0x00433c40 sync_page_range_nolock +EXPORT_SYMBOL vmlinux 0x00471729 inet_dgram_connect +EXPORT_SYMBOL vmlinux 0x00501d8c iget_failed +EXPORT_SYMBOL vmlinux 0x0057c792 find_vma +EXPORT_SYMBOL vmlinux 0x00801678 flush_scheduled_work +EXPORT_SYMBOL vmlinux 0x0087de1b ipu_csi_set_window_pos +EXPORT_SYMBOL vmlinux 0x008c09fc ipu_select_buffer +EXPORT_SYMBOL vmlinux 0x00e13015 pskb_expand_head +EXPORT_SYMBOL vmlinux 0x00e8097b csum_partial_copy_fromiovecend +EXPORT_SYMBOL vmlinux 0x01000e51 schedule +EXPORT_SYMBOL vmlinux 0x01035b57 bio_add_pc_page +EXPORT_SYMBOL vmlinux 0x010370da do_system_keystore_slot_alloc +EXPORT_SYMBOL vmlinux 0x010595ed seq_path +EXPORT_SYMBOL vmlinux 0x01139ffc max_mapnr +EXPORT_SYMBOL vmlinux 0x012415c4 tcp_proc_unregister +EXPORT_SYMBOL vmlinux 0x012d2c2a inode_permission +EXPORT_SYMBOL vmlinux 0x01902adf netpoll_trap +EXPORT_SYMBOL vmlinux 0x0197060a skb_queue_tail +EXPORT_SYMBOL vmlinux 0x01a4aab6 set_irq_chip_data +EXPORT_SYMBOL vmlinux 0x01b62ae8 scm_fp_dup +EXPORT_SYMBOL vmlinux 0x01c64b3e del_mtd_partitions +EXPORT_SYMBOL vmlinux 0x01d15a70 skb_insert +EXPORT_SYMBOL vmlinux 0x01f1b302 simple_fill_super +EXPORT_SYMBOL vmlinux 0x01f53de2 lock_may_write +EXPORT_SYMBOL vmlinux 0x01ff169e eth_header_cache_update +EXPORT_SYMBOL vmlinux 0x02124474 ip_send_check +EXPORT_SYMBOL vmlinux 0x021657aa udp_proc_unregister +EXPORT_SYMBOL vmlinux 0x02196324 __aeabi_idiv +EXPORT_SYMBOL vmlinux 0x0256b569 proto_unregister +EXPORT_SYMBOL vmlinux 0x02649054 security_sock_rcv_skb +EXPORT_SYMBOL vmlinux 0x027533fc noop_qdisc +EXPORT_SYMBOL vmlinux 0x02891319 blk_queue_find_tag +EXPORT_SYMBOL vmlinux 0x02a6ce5a crc16_table +EXPORT_SYMBOL vmlinux 0x02b6864a contig_page_data +EXPORT_SYMBOL vmlinux 0x02ba91a7 devm_free_irq +EXPORT_SYMBOL vmlinux 0x02cc809d input_allocate_device +EXPORT_SYMBOL vmlinux 0x02e1a347 elv_next_request +EXPORT_SYMBOL vmlinux 0x02e5cdbb netif_carrier_on +EXPORT_SYMBOL vmlinux 0x02ee26c1 free_pages_exact +EXPORT_SYMBOL vmlinux 0x030ec695 ipu_csi_get_window_size +EXPORT_SYMBOL vmlinux 0x0334da4e scsi_command_size_tbl +EXPORT_SYMBOL vmlinux 0x03506dc1 sk_release_kernel +EXPORT_SYMBOL vmlinux 0x0350e2f4 up_read +EXPORT_SYMBOL vmlinux 0x0372f985 dev_open +EXPORT_SYMBOL vmlinux 0x0374ab8d inet_listen +EXPORT_SYMBOL vmlinux 0x037a0cba kfree +EXPORT_SYMBOL vmlinux 0x03867ad0 tcf_em_register +EXPORT_SYMBOL vmlinux 0x0386d43f pmic_adc_convert_8x +EXPORT_SYMBOL vmlinux 0x03a99c3b rb_prev +EXPORT_SYMBOL vmlinux 0x03af172f set_page_dirty_lock +EXPORT_SYMBOL vmlinux 0x03ba2a6c redraw_screen +EXPORT_SYMBOL vmlinux 0x03c06156 bitmap_fold +EXPORT_SYMBOL vmlinux 0x03c6f668 unregister_qdisc +EXPORT_SYMBOL vmlinux 0x03fd2571 vm_unmap_ram +EXPORT_SYMBOL vmlinux 0x04162201 xfrm_policy_walk +EXPORT_SYMBOL vmlinux 0x041f8cc6 seq_release +EXPORT_SYMBOL vmlinux 0x0422fe4a inet_csk_timer_bug_msg +EXPORT_SYMBOL vmlinux 0x042a3318 generic_block_bmap +EXPORT_SYMBOL vmlinux 0x043b8483 __kfifo_get +EXPORT_SYMBOL vmlinux 0x044fbf49 mempool_kzalloc +EXPORT_SYMBOL vmlinux 0x0487f831 fb_find_best_display +EXPORT_SYMBOL vmlinux 0x04c1ca56 scc_allocate_partition +EXPORT_SYMBOL vmlinux 0x04cda566 snd_interval_refine +EXPORT_SYMBOL vmlinux 0x04ce72af uart_match_port +EXPORT_SYMBOL vmlinux 0x04e47b1b inet_put_port +EXPORT_SYMBOL vmlinux 0x04f2bf2e tcf_hash_new_index +EXPORT_SYMBOL vmlinux 0x04fe32fc __neigh_event_send +EXPORT_SYMBOL vmlinux 0x051abbc7 skb_over_panic +EXPORT_SYMBOL vmlinux 0x0528bd62 scsi_report_bus_reset +EXPORT_SYMBOL vmlinux 0x052b2967 kblockd_flush_work +EXPORT_SYMBOL vmlinux 0x053d29a9 sk_filter +EXPORT_SYMBOL vmlinux 0x0544dc5d nf_reinject +EXPORT_SYMBOL vmlinux 0x0560cdeb xfrm_state_flush +EXPORT_SYMBOL vmlinux 0x056a719c mxc_dma_enable +EXPORT_SYMBOL vmlinux 0x057ce975 hex_dump_to_buffer +EXPORT_SYMBOL vmlinux 0x057cf150 set_bdi_congested +EXPORT_SYMBOL vmlinux 0x057dbfe9 gpio_uart_inactive +EXPORT_SYMBOL vmlinux 0x058abc40 sb_has_dirty_inodes +EXPORT_SYMBOL vmlinux 0x059a3493 blk_rq_map_kern +EXPORT_SYMBOL vmlinux 0x05b9955f __vlan_hwaccel_rx +EXPORT_SYMBOL vmlinux 0x05d5bdc3 xfrm_bundle_ok +EXPORT_SYMBOL vmlinux 0x05dd2e16 inet_sock_destruct +EXPORT_SYMBOL vmlinux 0x05e4d37b elv_rb_del +EXPORT_SYMBOL vmlinux 0x05fda88c blk_rq_count_integrity_sg +EXPORT_SYMBOL vmlinux 0x06090de7 __sg_free_table +EXPORT_SYMBOL vmlinux 0x0609d69d mmc_request_done +EXPORT_SYMBOL vmlinux 0x0611e1b6 end_request +EXPORT_SYMBOL vmlinux 0x061651be strcat +EXPORT_SYMBOL vmlinux 0x0618e633 dump_fpu +EXPORT_SYMBOL vmlinux 0x0620a002 simple_getattr +EXPORT_SYMBOL vmlinux 0x062aba95 mempool_free +EXPORT_SYMBOL vmlinux 0x065c0be3 __rta_fill +EXPORT_SYMBOL vmlinux 0x0665a032 scsi_is_target_device +EXPORT_SYMBOL vmlinux 0x067b5b3c input_unregister_handler +EXPORT_SYMBOL vmlinux 0x067d8d35 security_release_secctx +EXPORT_SYMBOL vmlinux 0x0695c7d9 fsl_shw_auth_decrypt +EXPORT_SYMBOL vmlinux 0x06aa0531 block_commit_write +EXPORT_SYMBOL vmlinux 0x06cb34e5 init_waitqueue_head +EXPORT_SYMBOL vmlinux 0x06d8bae1 idr_get_new +EXPORT_SYMBOL vmlinux 0x06fabccf journal_abort +EXPORT_SYMBOL vmlinux 0x06fe3b14 default_grn +EXPORT_SYMBOL vmlinux 0x072dd5bc ipu_csi_init_interface +EXPORT_SYMBOL vmlinux 0x0748741c usb_gadget_register_driver +EXPORT_SYMBOL vmlinux 0x0788fb67 scsi_host_lookup +EXPORT_SYMBOL vmlinux 0x0799aca4 local_bh_enable +EXPORT_SYMBOL vmlinux 0x079cd7f1 ns_to_timeval +EXPORT_SYMBOL vmlinux 0x07a890c8 fb_alloc_cmap +EXPORT_SYMBOL vmlinux 0x07cc4a5d printk_timed_ratelimit +EXPORT_SYMBOL vmlinux 0x07dd4ffb igrab +EXPORT_SYMBOL vmlinux 0x0822dd47 pfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0x085d680f qdisc_create_dflt +EXPORT_SYMBOL vmlinux 0x08b37534 do_map_probe +EXPORT_SYMBOL vmlinux 0x08cc7bf3 snd_pcm_period_elapsed +EXPORT_SYMBOL vmlinux 0x08d9477c journal_get_create_access +EXPORT_SYMBOL vmlinux 0x08edbfa5 sah_add_in_key_desc +EXPORT_SYMBOL vmlinux 0x092b007a sleep_on_timeout +EXPORT_SYMBOL vmlinux 0x093bb7c7 cpu_user +EXPORT_SYMBOL vmlinux 0x0948cde9 num_physpages +EXPORT_SYMBOL vmlinux 0x09646162 do_splice_to +EXPORT_SYMBOL vmlinux 0x0969a82e snd_timer_continue +EXPORT_SYMBOL vmlinux 0x09783700 console_stop +EXPORT_SYMBOL vmlinux 0x098b71c6 fb_dealloc_cmap +EXPORT_SYMBOL vmlinux 0x09a0ecab xfrm_prepare_input +EXPORT_SYMBOL vmlinux 0x09b921dc ethtool_op_set_tx_ipv6_csum +EXPORT_SYMBOL vmlinux 0x09c55cec schedule_timeout_interruptible +EXPORT_SYMBOL vmlinux 0x09c8eb55 font_vga_8x16 +EXPORT_SYMBOL vmlinux 0x09d45c21 down_timeout +EXPORT_SYMBOL vmlinux 0x09e40a02 simple_empty +EXPORT_SYMBOL vmlinux 0x09e60628 filp_close +EXPORT_SYMBOL vmlinux 0x09f00772 proc_dointvec_userhz_jiffies +EXPORT_SYMBOL vmlinux 0x09fdb937 input_get_keycode +EXPORT_SYMBOL vmlinux 0x0a090f56 nf_log_register +EXPORT_SYMBOL vmlinux 0x0a1bebc5 kernel_execve +EXPORT_SYMBOL vmlinux 0x0a2487e0 unblock_all_signals +EXPORT_SYMBOL vmlinux 0x0a29803c tty_chars_in_buffer +EXPORT_SYMBOL vmlinux 0x0a3131f6 strnchr +EXPORT_SYMBOL vmlinux 0x0a4747ff allocate_resource +EXPORT_SYMBOL vmlinux 0x0a548805 textsearch_destroy +EXPORT_SYMBOL vmlinux 0x0a5d13e8 blk_integrity_compare +EXPORT_SYMBOL vmlinux 0x0a9bda39 register_sound_special +EXPORT_SYMBOL vmlinux 0x0aa13d05 __raw_readsw +EXPORT_SYMBOL vmlinux 0x0aba9d5c xfrm_state_unregister_afinfo +EXPORT_SYMBOL vmlinux 0x0acb1a3c __bitmap_shift_right +EXPORT_SYMBOL vmlinux 0x0b1beb31 vmalloc_32_user +EXPORT_SYMBOL vmlinux 0x0b5f2d2c sg_next +EXPORT_SYMBOL vmlinux 0x0b742fd7 simple_strtol +EXPORT_SYMBOL vmlinux 0x0b9b30d4 unmap_underlying_metadata +EXPORT_SYMBOL vmlinux 0x0bafeefd filemap_fdatawrite_range +EXPORT_SYMBOL vmlinux 0x0c3f5925 ethtool_op_get_tso +EXPORT_SYMBOL vmlinux 0x0c50f56f clk_set_parent +EXPORT_SYMBOL vmlinux 0x0c5cc893 tty_port_tty_set +EXPORT_SYMBOL vmlinux 0x0c5ef91b per_cpu__vm_event_states +EXPORT_SYMBOL vmlinux 0x0c622486 find_inode_number +EXPORT_SYMBOL vmlinux 0x0c65e73c scsi_normalize_sense +EXPORT_SYMBOL vmlinux 0x0c68268b dmam_pool_destroy +EXPORT_SYMBOL vmlinux 0x0c8c9e99 scsi_show_extd_sense +EXPORT_SYMBOL vmlinux 0x0cd79312 snd_dma_reserve_buf +EXPORT_SYMBOL vmlinux 0x0d19c1f8 proc_create_data +EXPORT_SYMBOL vmlinux 0x0d3def21 idr_pre_get +EXPORT_SYMBOL vmlinux 0x0d3f57a2 _find_next_bit_le +EXPORT_SYMBOL vmlinux 0x0d483b97 unregister_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0x0d542439 __ipv6_addr_type +EXPORT_SYMBOL vmlinux 0x0d583ee6 gpio_uart_active +EXPORT_SYMBOL vmlinux 0x0d82c36b uart_update_timeout +EXPORT_SYMBOL vmlinux 0x0d8ab500 param_set_copystring +EXPORT_SYMBOL vmlinux 0x0d9f5cbe gnet_stats_start_copy_compat +EXPORT_SYMBOL vmlinux 0x0da10ec3 security_sock_graft +EXPORT_SYMBOL vmlinux 0x0ddbe4c5 dma_pool_destroy +EXPORT_SYMBOL vmlinux 0x0dfbea86 destroy_EII_client +EXPORT_SYMBOL vmlinux 0x0e0957eb gpio_spdif_active +EXPORT_SYMBOL vmlinux 0x0e269625 sock_no_socketpair +EXPORT_SYMBOL vmlinux 0x0e376541 mxc_dma_stop +EXPORT_SYMBOL vmlinux 0x0e52592a panic +EXPORT_SYMBOL vmlinux 0x0e60709e poll_freewait +EXPORT_SYMBOL vmlinux 0x0e75b3e3 __f_setown +EXPORT_SYMBOL vmlinux 0x0e762d6e request_module +EXPORT_SYMBOL vmlinux 0x0e7ff482 tty_vhangup +EXPORT_SYMBOL vmlinux 0x0ead7bdb keyring_search +EXPORT_SYMBOL vmlinux 0x0eed6b21 tcp_v4_destroy_sock +EXPORT_SYMBOL vmlinux 0x0efef5e7 skb_push +EXPORT_SYMBOL vmlinux 0x0f0cb5a6 dev_change_flags +EXPORT_SYMBOL vmlinux 0x0f0db1eb tcp_init_xmit_timers +EXPORT_SYMBOL vmlinux 0x0f1c0be8 mc13892_bklit_set_ramp +EXPORT_SYMBOL vmlinux 0x0f1ef871 posix_acl_alloc +EXPORT_SYMBOL vmlinux 0x0f1f15ef fsl_platform_set_test_mode +EXPORT_SYMBOL vmlinux 0x0f365851 tcp_v4_send_check +EXPORT_SYMBOL vmlinux 0x0f41d0f2 fsl_shw_hmac +EXPORT_SYMBOL vmlinux 0x0f5d2693 netif_rx_ni +EXPORT_SYMBOL vmlinux 0x0f60b631 snd_pcm_hw_constraint_minmax +EXPORT_SYMBOL vmlinux 0x0f7bb626 load_nls_default +EXPORT_SYMBOL vmlinux 0x0f84c221 snd_pcm_lib_ioctl +EXPORT_SYMBOL vmlinux 0x0fa2a45e __memzero +EXPORT_SYMBOL vmlinux 0x0fc586ba down_trylock +EXPORT_SYMBOL vmlinux 0x0fc6d054 netpoll_setup +EXPORT_SYMBOL vmlinux 0x0fdf3d94 sock_no_connect +EXPORT_SYMBOL vmlinux 0x0ff178f6 __aeabi_idivmod +EXPORT_SYMBOL vmlinux 0x0ffaa2a9 misc_deregister +EXPORT_SYMBOL vmlinux 0x0fff387d request_firmware_nowait +EXPORT_SYMBOL vmlinux 0x100c5152 inet_csk_init_xmit_timers +EXPORT_SYMBOL vmlinux 0x1020e311 bdi_register_dev +EXPORT_SYMBOL vmlinux 0x10579454 sg_copy_from_buffer +EXPORT_SYMBOL vmlinux 0x105b160b journal_lock_updates +EXPORT_SYMBOL vmlinux 0x106b49f9 mxc_dma_get_bd_intr +EXPORT_SYMBOL vmlinux 0x1072a394 csum_partial_copy_from_user +EXPORT_SYMBOL vmlinux 0x10847e15 bdget_disk +EXPORT_SYMBOL vmlinux 0x108c2232 d_splice_alias +EXPORT_SYMBOL vmlinux 0x109350e8 sah_insert_mdha_algorithm +EXPORT_SYMBOL vmlinux 0x10e4384d sg_miter_stop +EXPORT_SYMBOL vmlinux 0x10ee20bb default_blu +EXPORT_SYMBOL vmlinux 0x10fea93e snd_pcm_open_substream +EXPORT_SYMBOL vmlinux 0x1107054f unregister_console +EXPORT_SYMBOL vmlinux 0x111bcb2c groups_free +EXPORT_SYMBOL vmlinux 0x11267875 scsi_extd_sense_format +EXPORT_SYMBOL vmlinux 0x1163f0a7 blk_max_low_pfn +EXPORT_SYMBOL vmlinux 0x117093be qdisc_class_hash_init +EXPORT_SYMBOL vmlinux 0x119b50e7 elf_check_arch +EXPORT_SYMBOL vmlinux 0x11a90301 sah_Append_Desc +EXPORT_SYMBOL vmlinux 0x11ba48c5 ipu_csi_set_test_generator +EXPORT_SYMBOL vmlinux 0x11bc451b register_chrdev +EXPORT_SYMBOL vmlinux 0x11cd8fb8 sk_send_sigurg +EXPORT_SYMBOL vmlinux 0x11d740f5 block_invalidatepage +EXPORT_SYMBOL vmlinux 0x11fc3842 xfrm_init_state +EXPORT_SYMBOL vmlinux 0x1267a9ca snd_card_file_remove +EXPORT_SYMBOL vmlinux 0x126970ed param_set_uint +EXPORT_SYMBOL vmlinux 0x126b45fa unregister_binfmt +EXPORT_SYMBOL vmlinux 0x1272d72b kthread_stop +EXPORT_SYMBOL vmlinux 0x12bb737f fsl_shw_add_entropy +EXPORT_SYMBOL vmlinux 0x12cc131f tcp_initialize_rcv_mss +EXPORT_SYMBOL vmlinux 0x12da5bb2 __kmalloc +EXPORT_SYMBOL vmlinux 0x12db51ac task_tgid_nr_ns +EXPORT_SYMBOL vmlinux 0x1316dcb3 set_user_nice +EXPORT_SYMBOL vmlinux 0x132f45f2 cookie_check_timestamp +EXPORT_SYMBOL vmlinux 0x1330e685 fsl_shw_get_capabilities +EXPORT_SYMBOL vmlinux 0x134223dd netpoll_print_options +EXPORT_SYMBOL vmlinux 0x136f0568 kset_unregister +EXPORT_SYMBOL vmlinux 0x138ccd8e blk_insert_request +EXPORT_SYMBOL vmlinux 0x13cf8169 alloc_etherdev_mq +EXPORT_SYMBOL vmlinux 0x13f42a4c mii_ethtool_gset +EXPORT_SYMBOL vmlinux 0x13f489c1 register_gifconf +EXPORT_SYMBOL vmlinux 0x140d790b sound_class +EXPORT_SYMBOL vmlinux 0x144ed3a1 dev_base_lock +EXPORT_SYMBOL vmlinux 0x1466d59a tty_insert_flip_string +EXPORT_SYMBOL vmlinux 0x1467f2f4 cap_netlink_recv +EXPORT_SYMBOL vmlinux 0x146fe388 uart_get_baud_rate +EXPORT_SYMBOL vmlinux 0x14b6cca8 neigh_create +EXPORT_SYMBOL vmlinux 0x14b97606 snd_pcm_hw_constraint_pow2 +EXPORT_SYMBOL vmlinux 0x14c25739 fb_find_mode +EXPORT_SYMBOL vmlinux 0x14d32f92 dma_alloc_writecombine +EXPORT_SYMBOL vmlinux 0x1523ab17 kill_pgrp +EXPORT_SYMBOL vmlinux 0x1544aad4 genl_register_mc_group +EXPORT_SYMBOL vmlinux 0x1551dc51 bitmap_find_free_region +EXPORT_SYMBOL vmlinux 0x1592c3a3 gpio_keypad_inactive +EXPORT_SYMBOL vmlinux 0x1593842c simple_rmdir +EXPORT_SYMBOL vmlinux 0x15c68bdc module_put +EXPORT_SYMBOL vmlinux 0x15d7ee8d blk_execute_rq +EXPORT_SYMBOL vmlinux 0x1600b3f0 fsl_shw_sstatus +EXPORT_SYMBOL vmlinux 0x16262be2 dev_unicast_sync +EXPORT_SYMBOL vmlinux 0x163df2e0 udplite_prot +EXPORT_SYMBOL vmlinux 0x16411456 clear_page_dirty_for_io +EXPORT_SYMBOL vmlinux 0x16479e8f panic_notifier_list +EXPORT_SYMBOL vmlinux 0x1655675e blk_queue_make_request +EXPORT_SYMBOL vmlinux 0x166e74a2 cpu_v7_set_pte_ext +EXPORT_SYMBOL vmlinux 0x1672ded2 netdev_class_create_file +EXPORT_SYMBOL vmlinux 0x1695bd04 blk_register_region +EXPORT_SYMBOL vmlinux 0x16a2bad2 block_page_mkwrite +EXPORT_SYMBOL vmlinux 0x16abcc47 wireless_spy_update +EXPORT_SYMBOL vmlinux 0x1748286d tcf_hash_search +EXPORT_SYMBOL vmlinux 0x1761f70a scsi_command_normalize_sense +EXPORT_SYMBOL vmlinux 0x177c10db gpio_sdhc_inactive +EXPORT_SYMBOL vmlinux 0x178a3059 otg_set_serial_peripheral +EXPORT_SYMBOL vmlinux 0x17922a48 elv_add_request +EXPORT_SYMBOL vmlinux 0x17a76e71 rb_first +EXPORT_SYMBOL vmlinux 0x17d10324 d_genocide +EXPORT_SYMBOL vmlinux 0x17df17bc sysctl_tcp_ecn +EXPORT_SYMBOL vmlinux 0x17e77f02 security_sb_set_mnt_opts +EXPORT_SYMBOL vmlinux 0x17ed4aab blk_rq_map_user_iov +EXPORT_SYMBOL vmlinux 0x180b7ab1 skb_checksum +EXPORT_SYMBOL vmlinux 0x181511d1 journal_stop +EXPORT_SYMBOL vmlinux 0x1837a549 pmic_read_reg +EXPORT_SYMBOL vmlinux 0x183fa88b mempool_alloc_slab +EXPORT_SYMBOL vmlinux 0x18804aa6 simple_release_fs +EXPORT_SYMBOL vmlinux 0x18872f81 kmem_cache_name +EXPORT_SYMBOL vmlinux 0x189e2040 gpio_config +EXPORT_SYMBOL vmlinux 0x18c69d4d sk_common_release +EXPORT_SYMBOL vmlinux 0x1922e695 neigh_lookup_nodev +EXPORT_SYMBOL vmlinux 0x1928ecc2 skb_dma_unmap +EXPORT_SYMBOL vmlinux 0x1951a28d clk_register +EXPORT_SYMBOL vmlinux 0x197d2c40 netlink_change_ngroups +EXPORT_SYMBOL vmlinux 0x198788b4 snd_lookup_oss_minor_data +EXPORT_SYMBOL vmlinux 0x19974084 drop_super +EXPORT_SYMBOL vmlinux 0x199ed0cd net_disable_timestamp +EXPORT_SYMBOL vmlinux 0x19aacf1d nf_register_sockopt +EXPORT_SYMBOL vmlinux 0x19c95139 sah_add_key_out_desc +EXPORT_SYMBOL vmlinux 0x19c996f7 alloc_disk +EXPORT_SYMBOL vmlinux 0x19f743c9 sget +EXPORT_SYMBOL vmlinux 0x1a276ab0 __insert_inode_hash +EXPORT_SYMBOL vmlinux 0x1a4bd090 ip_queue_xmit +EXPORT_SYMBOL vmlinux 0x1a5a02df fb_set_suspend +EXPORT_SYMBOL vmlinux 0x1a65f4ad __arm_ioremap_pfn +EXPORT_SYMBOL vmlinux 0x1a6683f8 tcf_destroy_chain +EXPORT_SYMBOL vmlinux 0x1a6c8d76 default_unplug_io_fn +EXPORT_SYMBOL vmlinux 0x1a6ef17d mmc_resume_host +EXPORT_SYMBOL vmlinux 0x1a811716 vfs_readv +EXPORT_SYMBOL vmlinux 0x1a8169f6 xfrm_user_policy +EXPORT_SYMBOL vmlinux 0x1aa0775e mxc_request_gpio +EXPORT_SYMBOL vmlinux 0x1aa12637 vfs_permission +EXPORT_SYMBOL vmlinux 0x1aa95cc0 blk_remove_plug +EXPORT_SYMBOL vmlinux 0x1aaa497e vfs_read +EXPORT_SYMBOL vmlinux 0x1aba651c blk_integrity_register +EXPORT_SYMBOL vmlinux 0x1abb226a tcf_em_tree_destroy +EXPORT_SYMBOL vmlinux 0x1acd07ae tcf_action_exec +EXPORT_SYMBOL vmlinux 0x1ace138d bitmap_allocate_region +EXPORT_SYMBOL vmlinux 0x1acfc6f1 scsi_allocate_command +EXPORT_SYMBOL vmlinux 0x1ad1f2e7 _memcpy_fromio +EXPORT_SYMBOL vmlinux 0x1ae8d7dc param_set_invbool +EXPORT_SYMBOL vmlinux 0x1b015d25 bitmap_parselist +EXPORT_SYMBOL vmlinux 0x1b17603a shrink_dcache_parent +EXPORT_SYMBOL vmlinux 0x1b1b1431 key_type_keyring +EXPORT_SYMBOL vmlinux 0x1b42de42 dma_sync_sg_for_device +EXPORT_SYMBOL vmlinux 0x1b60b8f4 pagevec_lookup_tag +EXPORT_SYMBOL vmlinux 0x1b6314fd in_aton +EXPORT_SYMBOL vmlinux 0x1b9981cc set_irq_wake +EXPORT_SYMBOL vmlinux 0x1b9e0ff1 scsilun_to_int +EXPORT_SYMBOL vmlinux 0x1b9ed1c6 vfs_writev +EXPORT_SYMBOL vmlinux 0x1ba030d5 locks_mandatory_area +EXPORT_SYMBOL vmlinux 0x1ba189ca get_sb_single +EXPORT_SYMBOL vmlinux 0x1bd08e0d kernel_sendpage +EXPORT_SYMBOL vmlinux 0x1bd7e19c skb_find_text +EXPORT_SYMBOL vmlinux 0x1bdbbcbd copy_strings_kernel +EXPORT_SYMBOL vmlinux 0x1c0485c7 simple_lookup +EXPORT_SYMBOL vmlinux 0x1c0e51f2 key_link +EXPORT_SYMBOL vmlinux 0x1c324357 idr_replace +EXPORT_SYMBOL vmlinux 0x1c91d6df xfrm_state_check_expire +EXPORT_SYMBOL vmlinux 0x1cc6719a register_reboot_notifier +EXPORT_SYMBOL vmlinux 0x1cd48bf9 nf_register_hook +EXPORT_SYMBOL vmlinux 0x1cfd40cf unregister_sysrq_key +EXPORT_SYMBOL vmlinux 0x1d027e4b snd_pcm_format_signed +EXPORT_SYMBOL vmlinux 0x1d0aaf41 scsi_kmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x1d136bbc page_symlink +EXPORT_SYMBOL vmlinux 0x1d2f77f4 __inode_dir_notify +EXPORT_SYMBOL vmlinux 0x1d3140ff sock_get_timestamp +EXPORT_SYMBOL vmlinux 0x1d5817ed neigh_lookup +EXPORT_SYMBOL vmlinux 0x1d635a35 inet_csk_clear_xmit_timers +EXPORT_SYMBOL vmlinux 0x1db3e08a tcp_enter_memory_pressure +EXPORT_SYMBOL vmlinux 0x1db7a55c blk_queue_stack_limits +EXPORT_SYMBOL vmlinux 0x1dc36131 fb_destroy_modedb +EXPORT_SYMBOL vmlinux 0x1dd571e6 fb_copy_cmap +EXPORT_SYMBOL vmlinux 0x1e097b03 pmic_adc_deinit +EXPORT_SYMBOL vmlinux 0x1e2b1ac1 mb_cache_entry_find_next +EXPORT_SYMBOL vmlinux 0x1e49daa8 sg_init_one +EXPORT_SYMBOL vmlinux 0x1e6d26a8 strstr +EXPORT_SYMBOL vmlinux 0x1e723d20 fsl_platform_perform_remote_wakeup +EXPORT_SYMBOL vmlinux 0x1e79919b page_readlink +EXPORT_SYMBOL vmlinux 0x1e8a8f99 mxc_set_gpio_direction +EXPORT_SYMBOL vmlinux 0x1e995c4f snd_info_create_module_entry +EXPORT_SYMBOL vmlinux 0x1ea2dd82 blk_init_queue +EXPORT_SYMBOL vmlinux 0x1eb7ca14 kernel_bind +EXPORT_SYMBOL vmlinux 0x1ecb9943 posix_acl_to_xattr +EXPORT_SYMBOL vmlinux 0x1edc9598 _atomic_dec_and_lock +EXPORT_SYMBOL vmlinux 0x1eeddd3a locks_init_lock +EXPORT_SYMBOL vmlinux 0x1efe283f __cap_full_set +EXPORT_SYMBOL vmlinux 0x1eff9067 invalidate_inodes +EXPORT_SYMBOL vmlinux 0x1f0141ca netdev_bonding_change +EXPORT_SYMBOL vmlinux 0x1f411b7c lock_super +EXPORT_SYMBOL vmlinux 0x1f423be3 mmc_wait_for_app_cmd +EXPORT_SYMBOL vmlinux 0x1f5a85e1 d_path +EXPORT_SYMBOL vmlinux 0x1f70d32d dma_cache_maint +EXPORT_SYMBOL vmlinux 0x1f7cc628 mempool_create +EXPORT_SYMBOL vmlinux 0x1f9b3c8c blk_rq_unmap_user +EXPORT_SYMBOL vmlinux 0x1fae7a0b wait_for_completion_timeout +EXPORT_SYMBOL vmlinux 0x1faeed17 scsi_device_set_state +EXPORT_SYMBOL vmlinux 0x1fb8ab5a open_exec +EXPORT_SYMBOL vmlinux 0x1fc91fb2 request_irq +EXPORT_SYMBOL vmlinux 0x1ff74b3b fb_blank +EXPORT_SYMBOL vmlinux 0x20000329 simple_strtoul +EXPORT_SYMBOL vmlinux 0x2006ba17 do_SAK +EXPORT_SYMBOL vmlinux 0x203c47e3 nf_log_unregister +EXPORT_SYMBOL vmlinux 0x205c7bdb snd_pcm_release_substream +EXPORT_SYMBOL vmlinux 0x20b21eb9 simple_dir_operations +EXPORT_SYMBOL vmlinux 0x20cc3b82 inet_frag_evictor +EXPORT_SYMBOL vmlinux 0x20f95f60 uart_register_driver +EXPORT_SYMBOL vmlinux 0x20fc3f40 skb_queue_head +EXPORT_SYMBOL vmlinux 0x210fa914 sysctl_intvec +EXPORT_SYMBOL vmlinux 0x211331fa __divsi3 +EXPORT_SYMBOL vmlinux 0x21244b4f netpoll_poll +EXPORT_SYMBOL vmlinux 0x215ebd78 bitrev16 +EXPORT_SYMBOL vmlinux 0x2192ba05 journal_check_available_features +EXPORT_SYMBOL vmlinux 0x219308a1 km_state_notify +EXPORT_SYMBOL vmlinux 0x219664b4 security_sb_clone_mnt_opts +EXPORT_SYMBOL vmlinux 0x21aff108 set_bh_page +EXPORT_SYMBOL vmlinux 0x21ba737e aio_put_req +EXPORT_SYMBOL vmlinux 0x21c4f11c skb_under_panic +EXPORT_SYMBOL vmlinux 0x21f47810 scsi_register_interface +EXPORT_SYMBOL vmlinux 0x222e7ce2 sysfs_streq +EXPORT_SYMBOL vmlinux 0x22533121 skb_abort_seq_read +EXPORT_SYMBOL vmlinux 0x22604579 snd_ctl_new1 +EXPORT_SYMBOL vmlinux 0x226e86a9 audit_log +EXPORT_SYMBOL vmlinux 0x22766ca3 kobject_add +EXPORT_SYMBOL vmlinux 0x2288378f system_state +EXPORT_SYMBOL vmlinux 0x229cfd5b gen_new_estimator +EXPORT_SYMBOL vmlinux 0x22b325d5 kd_mksound +EXPORT_SYMBOL vmlinux 0x22b6533b xfrm_sad_getinfo +EXPORT_SYMBOL vmlinux 0x22d302bb __sk_dst_check +EXPORT_SYMBOL vmlinux 0x231cf494 up_write +EXPORT_SYMBOL vmlinux 0x23259616 path_get +EXPORT_SYMBOL vmlinux 0x23269a13 strict_strtoul +EXPORT_SYMBOL vmlinux 0x2326a5c0 sah_Alloc_Descriptor +EXPORT_SYMBOL vmlinux 0x233b4df8 free_buffer_head +EXPORT_SYMBOL vmlinux 0x2374eee5 mxc_mmc_force_detect +EXPORT_SYMBOL vmlinux 0x23838107 __down_write +EXPORT_SYMBOL vmlinux 0x2384f063 elv_rb_find +EXPORT_SYMBOL vmlinux 0x23c021ec remap_vmalloc_range +EXPORT_SYMBOL vmlinux 0x23dd4b2d inode_double_lock +EXPORT_SYMBOL vmlinux 0x23e42b28 otg_set_serial_host +EXPORT_SYMBOL vmlinux 0x23ef29f6 kernel_getpeername +EXPORT_SYMBOL vmlinux 0x23fd3028 vmalloc_node +EXPORT_SYMBOL vmlinux 0x241ef7fe skb_store_bits +EXPORT_SYMBOL vmlinux 0x24403e29 set_anon_super +EXPORT_SYMBOL vmlinux 0x244f68c2 fb_pan_display +EXPORT_SYMBOL vmlinux 0x2455c156 __clear_user +EXPORT_SYMBOL vmlinux 0x2459bbcc console_set_on_cmdline +EXPORT_SYMBOL vmlinux 0x245c165d sock_no_recvmsg +EXPORT_SYMBOL vmlinux 0x24697d46 sah_Append_Link +EXPORT_SYMBOL vmlinux 0x24734fde ethtool_op_set_tx_hw_csum +EXPORT_SYMBOL vmlinux 0x24770b1f key_instantiate_and_link +EXPORT_SYMBOL vmlinux 0x24a94b26 snd_info_get_line +EXPORT_SYMBOL vmlinux 0x24b0df0d blk_queue_end_tag +EXPORT_SYMBOL vmlinux 0x24bc2131 blk_queue_set_discard +EXPORT_SYMBOL vmlinux 0x24cce783 sk_stream_write_space +EXPORT_SYMBOL vmlinux 0x24da68fb kmem_cache_shrink +EXPORT_SYMBOL vmlinux 0x24fdac79 wake_bit_function +EXPORT_SYMBOL vmlinux 0x250113b4 memory_read_from_buffer +EXPORT_SYMBOL vmlinux 0x251c4018 sock_no_shutdown +EXPORT_SYMBOL vmlinux 0x2537bacb tcf_hash_destroy +EXPORT_SYMBOL vmlinux 0x256887e1 warn_slowpath +EXPORT_SYMBOL vmlinux 0x257ba836 skb_copy_datagram_from_iovec +EXPORT_SYMBOL vmlinux 0x25820c64 fs_overflowuid +EXPORT_SYMBOL vmlinux 0x258355b4 fb_find_best_mode +EXPORT_SYMBOL vmlinux 0x25928c63 gen_replace_estimator +EXPORT_SYMBOL vmlinux 0x25a6be60 snd_ctl_free_one +EXPORT_SYMBOL vmlinux 0x25ba121c mempool_resize +EXPORT_SYMBOL vmlinux 0x25cd3521 netif_receive_skb +EXPORT_SYMBOL vmlinux 0x25cfb844 mxc_sdma_get_channel_params +EXPORT_SYMBOL vmlinux 0x25e2284d sah_register +EXPORT_SYMBOL vmlinux 0x25fa6f17 wait_for_completion +EXPORT_SYMBOL vmlinux 0x261c1766 __backtrace +EXPORT_SYMBOL vmlinux 0x2629671c arp_xmit +EXPORT_SYMBOL vmlinux 0x26477c07 __vmalloc +EXPORT_SYMBOL vmlinux 0x265721bd skb_kill_datagram +EXPORT_SYMBOL vmlinux 0x26606553 __xfrm_route_forward +EXPORT_SYMBOL vmlinux 0x266359d7 tty_free_termios +EXPORT_SYMBOL vmlinux 0x267fc65b __tasklet_hi_schedule +EXPORT_SYMBOL vmlinux 0x26da1051 tc_classify +EXPORT_SYMBOL vmlinux 0x26e76fb8 sysctl_udp_wmem_min +EXPORT_SYMBOL vmlinux 0x26f50280 unregister_netdevice +EXPORT_SYMBOL vmlinux 0x26f6ce1b get_write_access +EXPORT_SYMBOL vmlinux 0x26fddd93 km_state_expired +EXPORT_SYMBOL vmlinux 0x27285492 dcache_dir_lseek +EXPORT_SYMBOL vmlinux 0x272e7488 cond_resched_softirq +EXPORT_SYMBOL vmlinux 0x273dc449 scsi_rescan_device +EXPORT_SYMBOL vmlinux 0x273ee298 snd_pcm_lib_readv +EXPORT_SYMBOL vmlinux 0x274a00a5 journal_restart +EXPORT_SYMBOL vmlinux 0x274e11e9 ethtool_op_get_ufo +EXPORT_SYMBOL vmlinux 0x2765b034 neigh_seq_stop +EXPORT_SYMBOL vmlinux 0x277b7d41 input_register_handle +EXPORT_SYMBOL vmlinux 0x27864d57 memparse +EXPORT_SYMBOL vmlinux 0x278e92a1 posix_test_lock +EXPORT_SYMBOL vmlinux 0x27a9a7eb ns_to_timespec +EXPORT_SYMBOL vmlinux 0x27af436b fsync_bdev +EXPORT_SYMBOL vmlinux 0x27bbf221 disable_irq_nosync +EXPORT_SYMBOL vmlinux 0x27c61ece qdisc_put_stab +EXPORT_SYMBOL vmlinux 0x27d729d6 journal_create +EXPORT_SYMBOL vmlinux 0x27f7dd90 snd_card_proc_new +EXPORT_SYMBOL vmlinux 0x28118cb6 __get_user_1 +EXPORT_SYMBOL vmlinux 0x2846deee request_key_with_auxdata +EXPORT_SYMBOL vmlinux 0x285ac517 strict_strtoll +EXPORT_SYMBOL vmlinux 0x28617471 br_handle_frame_hook +EXPORT_SYMBOL vmlinux 0x2869b3bf dcache_readdir +EXPORT_SYMBOL vmlinux 0x287df63e dma_pool_alloc +EXPORT_SYMBOL vmlinux 0x2898ebc8 ipu_enable_irq +EXPORT_SYMBOL vmlinux 0x28a2ed02 scsi_build_sense_buffer +EXPORT_SYMBOL vmlinux 0x28ce4668 linkwatch_fire_event +EXPORT_SYMBOL vmlinux 0x28dcf25c udplite_hash +EXPORT_SYMBOL vmlinux 0x28dff016 scsi_device_put +EXPORT_SYMBOL vmlinux 0x290826cf vfs_link +EXPORT_SYMBOL vmlinux 0x29148969 schedule_delayed_work +EXPORT_SYMBOL vmlinux 0x29497067 netlink_kernel_create +EXPORT_SYMBOL vmlinux 0x29537c9e alloc_chrdev_region +EXPORT_SYMBOL vmlinux 0x297c537f sock_wmalloc +EXPORT_SYMBOL vmlinux 0x2991ea5d blkdev_issue_flush +EXPORT_SYMBOL vmlinux 0x29ab641f ethtool_op_set_sg +EXPORT_SYMBOL vmlinux 0x29bd4c46 __cap_init_eff_set +EXPORT_SYMBOL vmlinux 0x2a6f0335 mxc_sdma_write_ipcv2 +EXPORT_SYMBOL vmlinux 0x2a915725 xfrm_policy_bysel_ctx +EXPORT_SYMBOL vmlinux 0x2aa0e4fc strncasecmp +EXPORT_SYMBOL vmlinux 0x2ab8ecf9 kill_block_super +EXPORT_SYMBOL vmlinux 0x2ac8f9cd proto_register +EXPORT_SYMBOL vmlinux 0x2b0ba2b0 scsi_sense_desc_find +EXPORT_SYMBOL vmlinux 0x2b40baff __down_write_nested +EXPORT_SYMBOL vmlinux 0x2b570dc0 ida_pre_get +EXPORT_SYMBOL vmlinux 0x2b8646fb thaw_process +EXPORT_SYMBOL vmlinux 0x2b982ca1 __sk_mem_reclaim +EXPORT_SYMBOL vmlinux 0x2ba707a8 sysctl_tcp_low_latency +EXPORT_SYMBOL vmlinux 0x2bc55b91 gpio_fec_inactive +EXPORT_SYMBOL vmlinux 0x2bcb3683 do_splice_from +EXPORT_SYMBOL vmlinux 0x2bd3f93f nf_register_hooks +EXPORT_SYMBOL vmlinux 0x2c03c03d bmap +EXPORT_SYMBOL vmlinux 0x2c171608 __dev_get_by_index +EXPORT_SYMBOL vmlinux 0x2c4521b2 xfrm_policy_unregister_afinfo +EXPORT_SYMBOL vmlinux 0x2c6d50fc input_inject_event +EXPORT_SYMBOL vmlinux 0x2c84eea9 skb_checksum_help +EXPORT_SYMBOL vmlinux 0x2ca5704e bdget +EXPORT_SYMBOL vmlinux 0x2cb875fa rtnl_set_sk_err +EXPORT_SYMBOL vmlinux 0x2cbe1133 pneigh_enqueue +EXPORT_SYMBOL vmlinux 0x2ccf253b cdev_alloc +EXPORT_SYMBOL vmlinux 0x2cd42a62 neigh_destroy +EXPORT_SYMBOL vmlinux 0x2cd9e459 param_set_short +EXPORT_SYMBOL vmlinux 0x2cf45337 neigh_parms_release +EXPORT_SYMBOL vmlinux 0x2d139a73 blk_sync_queue +EXPORT_SYMBOL vmlinux 0x2d1b4aa8 cfb_copyarea +EXPORT_SYMBOL vmlinux 0x2d252d77 tty_register_device +EXPORT_SYMBOL vmlinux 0x2d2c3f23 clk_set_rate +EXPORT_SYMBOL vmlinux 0x2d3fae9a i2c_smbus_write_byte +EXPORT_SYMBOL vmlinux 0x2d4cd5d7 call_usermodehelper_setcleanup +EXPORT_SYMBOL vmlinux 0x2d53be63 snd_ctl_boolean_mono_info +EXPORT_SYMBOL vmlinux 0x2d6507b5 _find_next_zero_bit_le +EXPORT_SYMBOL vmlinux 0x2d6b6172 unload_nls +EXPORT_SYMBOL vmlinux 0x2d7f86e0 remove_arg_zero +EXPORT_SYMBOL vmlinux 0x2d81ab3c kernel_connect +EXPORT_SYMBOL vmlinux 0x2d89342a scsi_show_sense_hdr +EXPORT_SYMBOL vmlinux 0x2d9eb926 netpoll_parse_options +EXPORT_SYMBOL vmlinux 0x2de9f66f param_get_long +EXPORT_SYMBOL vmlinux 0x2dfa9905 __mxc_ioremap +EXPORT_SYMBOL vmlinux 0x2e15a0af __seq_open_private +EXPORT_SYMBOL vmlinux 0x2e2ce9e0 sysctl_tcp_syncookies +EXPORT_SYMBOL vmlinux 0x2e3217f1 generic_removexattr +EXPORT_SYMBOL vmlinux 0x2e4a39f8 sysctl_udp_mem +EXPORT_SYMBOL vmlinux 0x2e925f74 ipu_set_csc_coefficients +EXPORT_SYMBOL vmlinux 0x2ea89937 ilookup5_nowait +EXPORT_SYMBOL vmlinux 0x2ec9752c scsi_target_quiesce +EXPORT_SYMBOL vmlinux 0x2ece640d ip_route_input +EXPORT_SYMBOL vmlinux 0x2ef83b09 write_inode_now +EXPORT_SYMBOL vmlinux 0x2f3694ed __xfrm_state_destroy +EXPORT_SYMBOL vmlinux 0x2f49a7d3 tcp_mtup_init +EXPORT_SYMBOL vmlinux 0x2f60b830 generic_mii_ioctl +EXPORT_SYMBOL vmlinux 0x2fd2c8ef sk_stop_timer +EXPORT_SYMBOL vmlinux 0x2fec7cbe tty_port_tty_get +EXPORT_SYMBOL vmlinux 0x2ff96d7f sah_Create_Key_Link +EXPORT_SYMBOL vmlinux 0x3065cda4 dev_remove_pack +EXPORT_SYMBOL vmlinux 0x30b50f3d generic_file_aio_write +EXPORT_SYMBOL vmlinux 0x30b8cb12 bio_get_nr_vecs +EXPORT_SYMBOL vmlinux 0x30e74134 tty_termios_copy_hw +EXPORT_SYMBOL vmlinux 0x310917fe sort +EXPORT_SYMBOL vmlinux 0x311eba5d scsi_init_io +EXPORT_SYMBOL vmlinux 0x311f03c6 mc13892_bklit_get_ramp +EXPORT_SYMBOL vmlinux 0x31255d18 fb_get_buffer_offset +EXPORT_SYMBOL vmlinux 0x31326bd6 sg_miter_start +EXPORT_SYMBOL vmlinux 0x313341a3 _set_bit_le +EXPORT_SYMBOL vmlinux 0x3147857d default_red +EXPORT_SYMBOL vmlinux 0x3147d51e mmc_wait_for_cmd +EXPORT_SYMBOL vmlinux 0x3151a6a1 pmic_get_version +EXPORT_SYMBOL vmlinux 0x316a43ef journal_start_commit +EXPORT_SYMBOL vmlinux 0x31750739 do_sync_write +EXPORT_SYMBOL vmlinux 0x31b31f5c csum_partial_copy_nocheck +EXPORT_SYMBOL vmlinux 0x31b5419a secpath_dup +EXPORT_SYMBOL vmlinux 0x31bd1080 nla_reserve +EXPORT_SYMBOL vmlinux 0x31cd4420 d_invalidate +EXPORT_SYMBOL vmlinux 0x31d0ceb5 nonseekable_open +EXPORT_SYMBOL vmlinux 0x320fc930 cfb_imageblit +EXPORT_SYMBOL vmlinux 0x323222ba mutex_unlock +EXPORT_SYMBOL vmlinux 0x32753e0a skb_make_writable +EXPORT_SYMBOL vmlinux 0x328a05f1 strncpy +EXPORT_SYMBOL vmlinux 0x32923c96 tty_register_driver +EXPORT_SYMBOL vmlinux 0x32c40146 tty_flip_buffer_push +EXPORT_SYMBOL vmlinux 0x32ce623a sg_last +EXPORT_SYMBOL vmlinux 0x32f90856 udp_proc_register +EXPORT_SYMBOL vmlinux 0x33015f17 tty_hangup +EXPORT_SYMBOL vmlinux 0x33274530 seq_release_private +EXPORT_SYMBOL vmlinux 0x33379231 alloc_buffer_head +EXPORT_SYMBOL vmlinux 0x3338ff2c blk_queue_start_tag +EXPORT_SYMBOL vmlinux 0x334be70c generic_setxattr +EXPORT_SYMBOL vmlinux 0x3360a963 param_set_ulong +EXPORT_SYMBOL vmlinux 0x3383d734 mb_cache_entry_free +EXPORT_SYMBOL vmlinux 0x338fb105 sync_mapping_buffers +EXPORT_SYMBOL vmlinux 0x33a0287f input_flush_device +EXPORT_SYMBOL vmlinux 0x33aed425 mmc_align_data_size +EXPORT_SYMBOL vmlinux 0x33cf3fa0 blk_recount_segments +EXPORT_SYMBOL vmlinux 0x33e7d7c9 generic_file_splice_write_nolock +EXPORT_SYMBOL vmlinux 0x33ed3f29 __xfrm_lookup +EXPORT_SYMBOL vmlinux 0x347a87c7 skb_recycle_check +EXPORT_SYMBOL vmlinux 0x3485c2bd nf_unregister_hook +EXPORT_SYMBOL vmlinux 0x34908c14 print_hex_dump_bytes +EXPORT_SYMBOL vmlinux 0x349cba85 strchr +EXPORT_SYMBOL vmlinux 0x34a2299d registered_fb +EXPORT_SYMBOL vmlinux 0x34adcaf9 unmap_mapping_range +EXPORT_SYMBOL vmlinux 0x34e2ae24 mxc_iomux_set_pad +EXPORT_SYMBOL vmlinux 0x3501945c bio_copy_user +EXPORT_SYMBOL vmlinux 0x3506f87f gnet_stats_copy_basic +EXPORT_SYMBOL vmlinux 0x350dda42 blk_start_queue +EXPORT_SYMBOL vmlinux 0x3524cd9f dma_release_from_coherent +EXPORT_SYMBOL vmlinux 0x35326646 key_validate +EXPORT_SYMBOL vmlinux 0x353e3fa5 __get_user_4 +EXPORT_SYMBOL vmlinux 0x355b3b2d blk_rq_map_user +EXPORT_SYMBOL vmlinux 0x35731fdd proc_dostring +EXPORT_SYMBOL vmlinux 0x35a512b9 scsi_track_queue_full +EXPORT_SYMBOL vmlinux 0x35c2ba9e refrigerator +EXPORT_SYMBOL vmlinux 0x35fa506d mc13892_bklit_get_blink_p +EXPORT_SYMBOL vmlinux 0x360b1afe probe_irq_mask +EXPORT_SYMBOL vmlinux 0x360f02d2 snd_pcm_notify +EXPORT_SYMBOL vmlinux 0x36232e02 read_cache_page +EXPORT_SYMBOL vmlinux 0x36309d0b input_unregister_device +EXPORT_SYMBOL vmlinux 0x363ad247 cap_set_effective +EXPORT_SYMBOL vmlinux 0x366bdeaa init_timer +EXPORT_SYMBOL vmlinux 0x367538c0 genl_sock +EXPORT_SYMBOL vmlinux 0x367cec0d netif_device_detach +EXPORT_SYMBOL vmlinux 0x36a00afd netlink_clear_multicast_users +EXPORT_SYMBOL vmlinux 0x36b141ac gpio_nand_inactive +EXPORT_SYMBOL vmlinux 0x36cd4b87 generic_file_llseek_unlocked +EXPORT_SYMBOL vmlinux 0x36d4ec90 tcf_register_action +EXPORT_SYMBOL vmlinux 0x36e47222 remove_wait_queue +EXPORT_SYMBOL vmlinux 0x3744cf36 vmalloc_to_pfn +EXPORT_SYMBOL vmlinux 0x374bd534 init_buffer +EXPORT_SYMBOL vmlinux 0x374ed073 scnprintf +EXPORT_SYMBOL vmlinux 0x375680b2 xfrm_unregister_mode +EXPORT_SYMBOL vmlinux 0x377b9e86 ipu_free_irq +EXPORT_SYMBOL vmlinux 0x3782cea7 vfs_symlink +EXPORT_SYMBOL vmlinux 0x379627f0 mxc_free_dma +EXPORT_SYMBOL vmlinux 0x3796bdcc snd_pcm_format_little_endian +EXPORT_SYMBOL vmlinux 0x379955b8 sk_free +EXPORT_SYMBOL vmlinux 0x37a86556 simple_write_end +EXPORT_SYMBOL vmlinux 0x37af6a0a abort_exclusive_wait +EXPORT_SYMBOL vmlinux 0x37befc70 jiffies_to_msecs +EXPORT_SYMBOL vmlinux 0x37c28849 snd_info_create_card_entry +EXPORT_SYMBOL vmlinux 0x37e74642 get_jiffies_64 +EXPORT_SYMBOL vmlinux 0x380c841c sock_i_ino +EXPORT_SYMBOL vmlinux 0x38429b3d mb_cache_entry_release +EXPORT_SYMBOL vmlinux 0x384b7835 xfrm_lookup +EXPORT_SYMBOL vmlinux 0x387c0967 vfs_lstat +EXPORT_SYMBOL vmlinux 0x388554fe scsi_calculate_bounce_limit +EXPORT_SYMBOL vmlinux 0x388ebf18 dev_mc_add +EXPORT_SYMBOL vmlinux 0x388f9128 xfrm_state_walk_done +EXPORT_SYMBOL vmlinux 0x38b56ec7 d_find_alias +EXPORT_SYMBOL vmlinux 0x38e8378d pgprot_kernel +EXPORT_SYMBOL vmlinux 0x38fcc17f __mark_inode_dirty +EXPORT_SYMBOL vmlinux 0x393e9495 mxc_set_gpio_dataout +EXPORT_SYMBOL vmlinux 0x3944696a blk_alloc_queue +EXPORT_SYMBOL vmlinux 0x395e287f snd_pcm_link_rwlock +EXPORT_SYMBOL vmlinux 0x3971b4df snd_ecards_limit +EXPORT_SYMBOL vmlinux 0x3980aac1 unregister_reboot_notifier +EXPORT_SYMBOL vmlinux 0x3986cbe4 vfs_rmdir +EXPORT_SYMBOL vmlinux 0x39b355ba blk_unplug +EXPORT_SYMBOL vmlinux 0x39d5d770 __set_page_dirty_nobuffers +EXPORT_SYMBOL vmlinux 0x39d66430 mc13892_bklit_get_current +EXPORT_SYMBOL vmlinux 0x39ecfd8c netlink_dump_start +EXPORT_SYMBOL vmlinux 0x3a0822d3 simple_transaction_release +EXPORT_SYMBOL vmlinux 0x3a1228c1 sock_no_getsockopt +EXPORT_SYMBOL vmlinux 0x3a2204c6 security_netlink_recv +EXPORT_SYMBOL vmlinux 0x3a4ff296 scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0x3a596899 sb_set_blocksize +EXPORT_SYMBOL vmlinux 0x3a9b6fb9 blk_unregister_region +EXPORT_SYMBOL vmlinux 0x3ab2d174 down_killable +EXPORT_SYMBOL vmlinux 0x3ab3eb1d eth_type_trans +EXPORT_SYMBOL vmlinux 0x3abb2554 __xfrm_decode_session +EXPORT_SYMBOL vmlinux 0x3ac7dbe4 invalidate_bdev +EXPORT_SYMBOL vmlinux 0x3adc15b9 posix_acl_from_mode +EXPORT_SYMBOL vmlinux 0x3ae831b6 kref_init +EXPORT_SYMBOL vmlinux 0x3aeacfa9 ip_mc_rejoin_group +EXPORT_SYMBOL vmlinux 0x3b23a3ff task_nice +EXPORT_SYMBOL vmlinux 0x3b2ad8ac dma_release_declared_memory +EXPORT_SYMBOL vmlinux 0x3b3016d3 cpufreq_unregister_notifier +EXPORT_SYMBOL vmlinux 0x3b34b881 journal_set_features +EXPORT_SYMBOL vmlinux 0x3b415afb journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0x3b87813e new_inode +EXPORT_SYMBOL vmlinux 0x3b91f3af snd_free_pages +EXPORT_SYMBOL vmlinux 0x3ba7ed7b snd_pcm_new +EXPORT_SYMBOL vmlinux 0x3bd1b1f6 msecs_to_jiffies +EXPORT_SYMBOL vmlinux 0x3c2c5af5 sprintf +EXPORT_SYMBOL vmlinux 0x3c6632d2 inet_del_protocol +EXPORT_SYMBOL vmlinux 0x3c6c436c arp_send +EXPORT_SYMBOL vmlinux 0x3c78355e scsi_prep_state_check +EXPORT_SYMBOL vmlinux 0x3c9d1211 string_get_size +EXPORT_SYMBOL vmlinux 0x3c9e25d7 input_event +EXPORT_SYMBOL vmlinux 0x3cb8a495 param_get_string +EXPORT_SYMBOL vmlinux 0x3cbfb7dc scsi_scan_host +EXPORT_SYMBOL vmlinux 0x3cc0a3bb xfrm_spd_getinfo +EXPORT_SYMBOL vmlinux 0x3cd7d252 mmc_add_host +EXPORT_SYMBOL vmlinux 0x3ce4ca6f disable_irq +EXPORT_SYMBOL vmlinux 0x3ce82b25 scsi_test_unit_ready +EXPORT_SYMBOL vmlinux 0x3d0deeef sock_common_getsockopt +EXPORT_SYMBOL vmlinux 0x3d1d12d6 clocksource_register +EXPORT_SYMBOL vmlinux 0x3d1e3bf9 task_pid_nr_ns +EXPORT_SYMBOL vmlinux 0x3d2bdcc1 vfs_unlink +EXPORT_SYMBOL vmlinux 0x3d3c540f elf_hwcap +EXPORT_SYMBOL vmlinux 0x3d68bd4b flow_cache_genid +EXPORT_SYMBOL vmlinux 0x3d8d97c1 snd_pcm_hw_constraint_msbits +EXPORT_SYMBOL vmlinux 0x3db4c4ff inet_csk_reset_keepalive_timer +EXPORT_SYMBOL vmlinux 0x3db7c4cf blk_queue_resize_tags +EXPORT_SYMBOL vmlinux 0x3dd845f9 dev_unicast_delete +EXPORT_SYMBOL vmlinux 0x3de6970a dev_set_mtu +EXPORT_SYMBOL vmlinux 0x3df2c32a ipu_init_channel +EXPORT_SYMBOL vmlinux 0x3e32f841 tcf_action_dump_1 +EXPORT_SYMBOL vmlinux 0x3e383385 nf_hooks +EXPORT_SYMBOL vmlinux 0x3e45e9ff register_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x3e6012a8 sah_DePhysicalise_Descriptors +EXPORT_SYMBOL vmlinux 0x3e6c9d23 nf_unregister_hooks +EXPORT_SYMBOL vmlinux 0x3e6caebd add_wait_queue_exclusive +EXPORT_SYMBOL vmlinux 0x3ec0d0ad __page_symlink +EXPORT_SYMBOL vmlinux 0x3ec76b2d mb_cache_entry_insert +EXPORT_SYMBOL vmlinux 0x3ecf851b snd_ctl_boolean_stereo_info +EXPORT_SYMBOL vmlinux 0x3ed63055 zlib_inflateReset +EXPORT_SYMBOL vmlinux 0x3efc486b sk_run_filter +EXPORT_SYMBOL vmlinux 0x3f0dcd2c netlink_kernel_release +EXPORT_SYMBOL vmlinux 0x3f2c0f6d ethtool_op_set_ufo +EXPORT_SYMBOL vmlinux 0x3f3943bf dma_alloc_from_coherent +EXPORT_SYMBOL vmlinux 0x3f4547a7 put_unused_fd +EXPORT_SYMBOL vmlinux 0x3f9ae1e8 scsi_free_command +EXPORT_SYMBOL vmlinux 0x3f9fc877 __skb_warn_lro_forwarding +EXPORT_SYMBOL vmlinux 0x3fa16c9a fsl_usb_host_init +EXPORT_SYMBOL vmlinux 0x3fc3ba25 dev_get_by_flags +EXPORT_SYMBOL vmlinux 0x3ff62317 local_bh_disable +EXPORT_SYMBOL vmlinux 0x40123aeb idr_for_each +EXPORT_SYMBOL vmlinux 0x4059792f print_hex_dump +EXPORT_SYMBOL vmlinux 0x405c1144 get_seconds +EXPORT_SYMBOL vmlinux 0x407136b1 __put_user_8 +EXPORT_SYMBOL vmlinux 0x409873e3 tty_termios_baud_rate +EXPORT_SYMBOL vmlinux 0x40a6f522 __arm_ioremap +EXPORT_SYMBOL vmlinux 0x40dbdc07 do_scc_encrypt_region +EXPORT_SYMBOL vmlinux 0x40e3eeac scsi_device_quiesce +EXPORT_SYMBOL vmlinux 0x40e8e73e snd_add_device_sysfs_file +EXPORT_SYMBOL vmlinux 0x40f07981 __ashldi3 +EXPORT_SYMBOL vmlinux 0x40f3fe21 I_BDEV +EXPORT_SYMBOL vmlinux 0x4108e69a fb_match_mode +EXPORT_SYMBOL vmlinux 0x41166725 inet_frags_init_net +EXPORT_SYMBOL vmlinux 0x412ddc0c dcache_lock +EXPORT_SYMBOL vmlinux 0x4143e3f8 register_netdev +EXPORT_SYMBOL vmlinux 0x41482d8b strndup_user +EXPORT_SYMBOL vmlinux 0x4148472b vmalloc_to_page +EXPORT_SYMBOL vmlinux 0x416983d9 netdev_fix_features +EXPORT_SYMBOL vmlinux 0x4185cf4b radix_tree_lookup_slot +EXPORT_SYMBOL vmlinux 0x4188d439 neigh_rand_reach_time +EXPORT_SYMBOL vmlinux 0x418bb528 tcp_timewait_state_process +EXPORT_SYMBOL vmlinux 0x41975d5a xfrm_state_lookup_byaddr +EXPORT_SYMBOL vmlinux 0x41e45f65 ip_setsockopt +EXPORT_SYMBOL vmlinux 0x4211c3c1 zlib_inflateInit2 +EXPORT_SYMBOL vmlinux 0x42124e81 mmc_detect_change +EXPORT_SYMBOL vmlinux 0x42224298 sscanf +EXPORT_SYMBOL vmlinux 0x42263d81 journal_invalidatepage +EXPORT_SYMBOL vmlinux 0x424e2944 unregister_sysctl_table +EXPORT_SYMBOL vmlinux 0x425c6f24 genl_unregister_ops +EXPORT_SYMBOL vmlinux 0x425fb9bb ipu_reset_disp_panel +EXPORT_SYMBOL vmlinux 0x428f4d02 poll_initwait +EXPORT_SYMBOL vmlinux 0x428fd093 blk_init_queue_node +EXPORT_SYMBOL vmlinux 0x42ecff33 tcf_exts_validate +EXPORT_SYMBOL vmlinux 0x43019d82 proc_doulongvec_ms_jiffies_minmax +EXPORT_SYMBOL vmlinux 0x430205aa __sg_alloc_table +EXPORT_SYMBOL vmlinux 0x4302d0eb free_pages +EXPORT_SYMBOL vmlinux 0x434fa55c release_console_sem +EXPORT_SYMBOL vmlinux 0x437c5365 dentry_unhash +EXPORT_SYMBOL vmlinux 0x43858c5a i2c_add_adapter +EXPORT_SYMBOL vmlinux 0x438e01b6 xfrm_state_insert +EXPORT_SYMBOL vmlinux 0x43badf94 touch_atime +EXPORT_SYMBOL vmlinux 0x43c96036 snd_pcm_suspend +EXPORT_SYMBOL vmlinux 0x43f83838 aio_complete +EXPORT_SYMBOL vmlinux 0x44161c19 unregister_shrinker +EXPORT_SYMBOL vmlinux 0x44314efb radix_tree_gang_lookup_tag_slot +EXPORT_SYMBOL vmlinux 0x444779c4 nla_find +EXPORT_SYMBOL vmlinux 0x44643b93 __aeabi_lmul +EXPORT_SYMBOL vmlinux 0x4492d3be snd_pcm_hw_refine +EXPORT_SYMBOL vmlinux 0x44b911c3 rb_replace_node +EXPORT_SYMBOL vmlinux 0x44c214d1 __wake_up_bit +EXPORT_SYMBOL vmlinux 0x44d6a071 blk_queue_segment_boundary +EXPORT_SYMBOL vmlinux 0x44da5d0f __csum_ipv6_magic +EXPORT_SYMBOL vmlinux 0x44e9a829 match_token +EXPORT_SYMBOL vmlinux 0x44fa4ce7 tcf_hash_check +EXPORT_SYMBOL vmlinux 0x454fb04c vm_insert_pfn +EXPORT_SYMBOL vmlinux 0x45a55ec8 __iounmap +EXPORT_SYMBOL vmlinux 0x45bc9d3e eth_rebuild_header +EXPORT_SYMBOL vmlinux 0x45bda0d5 system_serial_low +EXPORT_SYMBOL vmlinux 0x45d53a19 scsi_finish_command +EXPORT_SYMBOL vmlinux 0x45d81331 __skb_checksum_complete_head +EXPORT_SYMBOL vmlinux 0x461185c7 adaptor_Exec_Descriptor_Chain +EXPORT_SYMBOL vmlinux 0x4622ea1f fd_install +EXPORT_SYMBOL vmlinux 0x46281637 mark_page_accessed +EXPORT_SYMBOL vmlinux 0x462a2e75 match_strlcpy +EXPORT_SYMBOL vmlinux 0x463f7865 devm_ioport_unmap +EXPORT_SYMBOL vmlinux 0x465bef97 clk_round_rate +EXPORT_SYMBOL vmlinux 0x4663a1ad block_sync_page +EXPORT_SYMBOL vmlinux 0x4675f5fa nla_put +EXPORT_SYMBOL vmlinux 0x46d3b28c __div0 +EXPORT_SYMBOL vmlinux 0x46e86cce wireless_send_event +EXPORT_SYMBOL vmlinux 0x47149aa6 ip_mc_inc_group +EXPORT_SYMBOL vmlinux 0x4719ba4e kfifo_free +EXPORT_SYMBOL vmlinux 0x4726c03c posix_unblock_lock +EXPORT_SYMBOL vmlinux 0x472ba9c0 find_get_pages_contig +EXPORT_SYMBOL vmlinux 0x472d2a9a radix_tree_lookup +EXPORT_SYMBOL vmlinux 0x475100c2 inet_get_local_port_range +EXPORT_SYMBOL vmlinux 0x477314ab module_refcount +EXPORT_SYMBOL vmlinux 0x477d4a3e find_get_pages_tag +EXPORT_SYMBOL vmlinux 0x47acd910 scsi_put_command +EXPORT_SYMBOL vmlinux 0x47b9e1ea bdev_read_only +EXPORT_SYMBOL vmlinux 0x47c62d70 xfrm_policy_flush +EXPORT_SYMBOL vmlinux 0x47d00264 i2c_smbus_read_block_data +EXPORT_SYMBOL vmlinux 0x47ea7661 snd_dma_alloc_pages +EXPORT_SYMBOL vmlinux 0x47f757de elf_platform +EXPORT_SYMBOL vmlinux 0x48111be3 make_bad_inode +EXPORT_SYMBOL vmlinux 0x48350523 get_sb_pseudo +EXPORT_SYMBOL vmlinux 0x4859b8bb rtc_year_days +EXPORT_SYMBOL vmlinux 0x486b6407 hweight64 +EXPORT_SYMBOL vmlinux 0x48a5b067 __machine_arch_type +EXPORT_SYMBOL vmlinux 0x48f9f12d complete_all +EXPORT_SYMBOL vmlinux 0x49168121 elv_abort_queue +EXPORT_SYMBOL vmlinux 0x493e25e1 udp_hash +EXPORT_SYMBOL vmlinux 0x4955a4c5 file_update_time +EXPORT_SYMBOL vmlinux 0x4959ad80 qdisc_destroy +EXPORT_SYMBOL vmlinux 0x49603fb8 security_sb_copy_data +EXPORT_SYMBOL vmlinux 0x498cd473 sysctl_jiffies +EXPORT_SYMBOL vmlinux 0x499d1709 nobh_write_end +EXPORT_SYMBOL vmlinux 0x49df9307 gnet_stats_copy_rate_est +EXPORT_SYMBOL vmlinux 0x49e984f2 get_unmapped_area +EXPORT_SYMBOL vmlinux 0x49f104cb scsi_free_host_dev +EXPORT_SYMBOL vmlinux 0x4a19f87f neigh_for_each +EXPORT_SYMBOL vmlinux 0x4a358252 __bitmap_subset +EXPORT_SYMBOL vmlinux 0x4a3ea5c0 snd_request_card +EXPORT_SYMBOL vmlinux 0x4a5cb0c6 bio_sector_offset +EXPORT_SYMBOL vmlinux 0x4a7af2dd kick_iocb +EXPORT_SYMBOL vmlinux 0x4a971ec7 radix_tree_delete +EXPORT_SYMBOL vmlinux 0x4ab0480d dma_sync_sg_for_cpu +EXPORT_SYMBOL vmlinux 0x4ab7d369 xfrm_state_add +EXPORT_SYMBOL vmlinux 0x4acfd8ad down_interruptible +EXPORT_SYMBOL vmlinux 0x4ae5a191 __mpage_writepage +EXPORT_SYMBOL vmlinux 0x4aea4791 __strncpy_from_user +EXPORT_SYMBOL vmlinux 0x4af7a4ef gpio_owire_inactive +EXPORT_SYMBOL vmlinux 0x4afe9a77 scsi_partsize +EXPORT_SYMBOL vmlinux 0x4b13e595 xfrm_state_walk +EXPORT_SYMBOL vmlinux 0x4b2cc7e6 netdev_boot_setup_check +EXPORT_SYMBOL vmlinux 0x4b2f14b4 jiffies_to_timespec +EXPORT_SYMBOL vmlinux 0x4b34fbf5 block_all_signals +EXPORT_SYMBOL vmlinux 0x4b4293d2 snd_pcm_limit_hw_rates +EXPORT_SYMBOL vmlinux 0x4b676a0d netdev_set_master +EXPORT_SYMBOL vmlinux 0x4b767836 usbotg_init +EXPORT_SYMBOL vmlinux 0x4b8edde9 complete_and_exit +EXPORT_SYMBOL vmlinux 0x4b9822b8 ip_defrag +EXPORT_SYMBOL vmlinux 0x4b9f3684 kfifo_init +EXPORT_SYMBOL vmlinux 0x4bbc3e5f pm_flags +EXPORT_SYMBOL vmlinux 0x4bedda7c icmp_send +EXPORT_SYMBOL vmlinux 0x4c0198c0 __starget_for_each_device +EXPORT_SYMBOL vmlinux 0x4c01da8b __scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0x4c1182cb bitmap_scnprintf +EXPORT_SYMBOL vmlinux 0x4c4aa730 neigh_resolve_output +EXPORT_SYMBOL vmlinux 0x4c51fa93 qdisc_watchdog_init +EXPORT_SYMBOL vmlinux 0x4c5c630a ipu_clear_irq +EXPORT_SYMBOL vmlinux 0x4c9d0237 scsi_ioctl +EXPORT_SYMBOL vmlinux 0x4cb51382 scc_set_sw_alarm +EXPORT_SYMBOL vmlinux 0x4cbbd171 __bitmap_weight +EXPORT_SYMBOL vmlinux 0x4cc457b5 cdev_add +EXPORT_SYMBOL vmlinux 0x4d027177 dev_set_mac_address +EXPORT_SYMBOL vmlinux 0x4d0d163d copy_page +EXPORT_SYMBOL vmlinux 0x4d153ab7 dma_pool_free +EXPORT_SYMBOL vmlinux 0x4d3bc1ae kill_anon_super +EXPORT_SYMBOL vmlinux 0x4d3c153f sigprocmask +EXPORT_SYMBOL vmlinux 0x4d6214d7 boot_tvec_bases +EXPORT_SYMBOL vmlinux 0x4d80c1b9 security_inode_init_security +EXPORT_SYMBOL vmlinux 0x4d9b6d35 snd_pcm_format_size +EXPORT_SYMBOL vmlinux 0x4dd34949 seq_lseek +EXPORT_SYMBOL vmlinux 0x4ddc4b9f utf8_mbtowc +EXPORT_SYMBOL vmlinux 0x4dec6038 memscan +EXPORT_SYMBOL vmlinux 0x4deea87f ipu_disp_set_global_alpha +EXPORT_SYMBOL vmlinux 0x4df119fa __bitmap_parse +EXPORT_SYMBOL vmlinux 0x4e0009da idr_get_new_above +EXPORT_SYMBOL vmlinux 0x4e0f857a journal_get_write_access +EXPORT_SYMBOL vmlinux 0x4e33ae4e unregister_filesystem +EXPORT_SYMBOL vmlinux 0x4e3567f7 match_int +EXPORT_SYMBOL vmlinux 0x4e6e8ea7 fg_console +EXPORT_SYMBOL vmlinux 0x4e830a3e strnicmp +EXPORT_SYMBOL vmlinux 0x4ea24f12 __wait_on_buffer +EXPORT_SYMBOL vmlinux 0x4eac7948 tcp_splice_read +EXPORT_SYMBOL vmlinux 0x4eca3ac7 unregister_framebuffer +EXPORT_SYMBOL vmlinux 0x4eea174a mxc_dma_callback_set +EXPORT_SYMBOL vmlinux 0x4f0ea0c0 up +EXPORT_SYMBOL vmlinux 0x4f5118f1 blk_queue_invalidate_tags +EXPORT_SYMBOL vmlinux 0x4f5651c3 tcp_sockets_allocated +EXPORT_SYMBOL vmlinux 0x4f6cafda nf_setsockopt +EXPORT_SYMBOL vmlinux 0x4f816e9b snd_pcm_format_big_endian +EXPORT_SYMBOL vmlinux 0x4fb7004e bio_phys_segments +EXPORT_SYMBOL vmlinux 0x4fb831e3 sock_queue_rcv_skb +EXPORT_SYMBOL vmlinux 0x4fde31ac inet_addr_type +EXPORT_SYMBOL vmlinux 0x50382c2e sk_wait_data +EXPORT_SYMBOL vmlinux 0x504fd8ed proc_dointvec_minmax +EXPORT_SYMBOL vmlinux 0x5093fa82 _clear_bit_le +EXPORT_SYMBOL vmlinux 0x50b4d354 scsi_print_command +EXPORT_SYMBOL vmlinux 0x50b5b9dd ipu_init_channel_buffer +EXPORT_SYMBOL vmlinux 0x50c1e68e ioctl_by_bdev +EXPORT_SYMBOL vmlinux 0x50d6faff get_sb_bdev +EXPORT_SYMBOL vmlinux 0x50ec822f gpio_ata_inactive +EXPORT_SYMBOL vmlinux 0x50f99812 vfs_follow_link +EXPORT_SYMBOL vmlinux 0x5118c382 secure_dccp_sequence_number +EXPORT_SYMBOL vmlinux 0x5142c898 tcp_v4_connect +EXPORT_SYMBOL vmlinux 0x51493d94 finish_wait +EXPORT_SYMBOL vmlinux 0x515d02f8 mmc_set_data_timeout +EXPORT_SYMBOL vmlinux 0x5166c77e kill_pid +EXPORT_SYMBOL vmlinux 0x516790b4 clk_get_usecount +EXPORT_SYMBOL vmlinux 0x517f8c82 call_usermodehelper_setkeys +EXPORT_SYMBOL vmlinux 0x51908eb8 __raw_writesl +EXPORT_SYMBOL vmlinux 0x51b24404 do_system_keystore_slot_encrypt +EXPORT_SYMBOL vmlinux 0x51c34b13 scc_engage_partition +EXPORT_SYMBOL vmlinux 0x51cd47e2 groups_alloc +EXPORT_SYMBOL vmlinux 0x51dce73b xfrm_state_walk_init +EXPORT_SYMBOL vmlinux 0x51ef33b8 kstrndup +EXPORT_SYMBOL vmlinux 0x51f9b2a1 skb_copy_and_csum_datagram_iovec +EXPORT_SYMBOL vmlinux 0x52026cdf security_sb_parse_opts_str +EXPORT_SYMBOL vmlinux 0x5204eaf2 tty_check_change +EXPORT_SYMBOL vmlinux 0x5232f2d6 mii_check_gmii_support +EXPORT_SYMBOL vmlinux 0x52354a0b mutex_trylock +EXPORT_SYMBOL vmlinux 0x5239ad20 clk_unregister +EXPORT_SYMBOL vmlinux 0x5267b3df mxc_pg_enable +EXPORT_SYMBOL vmlinux 0x52698983 snd_pcm_sgbuf_get_chunk_size +EXPORT_SYMBOL vmlinux 0x5287f213 i2c_transfer +EXPORT_SYMBOL vmlinux 0x528826e0 i2c_master_send +EXPORT_SYMBOL vmlinux 0x528c709d simple_read_from_buffer +EXPORT_SYMBOL vmlinux 0x52a58c24 ifla_policy +EXPORT_SYMBOL vmlinux 0x52bb56f7 sb_min_blocksize +EXPORT_SYMBOL vmlinux 0x52f1c0e4 blk_queue_prep_rq +EXPORT_SYMBOL vmlinux 0x52f52f2a bio_init +EXPORT_SYMBOL vmlinux 0x530b1e98 pm_suspend +EXPORT_SYMBOL vmlinux 0x532f2924 param_get_byte +EXPORT_SYMBOL vmlinux 0x53326531 mempool_alloc_pages +EXPORT_SYMBOL vmlinux 0x534e88a2 __lock_buffer +EXPORT_SYMBOL vmlinux 0x536d08cf no_llseek +EXPORT_SYMBOL vmlinux 0x53755fa3 hub_port_logical_disconnect +EXPORT_SYMBOL vmlinux 0x53786958 journal_dirty_data +EXPORT_SYMBOL vmlinux 0x53a3a902 scsi_remove_target +EXPORT_SYMBOL vmlinux 0x53abbfd6 __bforget +EXPORT_SYMBOL vmlinux 0x53c0767c sk_chk_filter +EXPORT_SYMBOL vmlinux 0x53d515c2 fsl_shw_get_results +EXPORT_SYMBOL vmlinux 0x53ed27bf elv_rb_latter_request +EXPORT_SYMBOL vmlinux 0x540817ab lock_rename +EXPORT_SYMBOL vmlinux 0x54198e3f path_permission +EXPORT_SYMBOL vmlinux 0x54290dc9 nla_validate +EXPORT_SYMBOL vmlinux 0x549994ed mpage_writepages +EXPORT_SYMBOL vmlinux 0x54b91688 __tcf_em_tree_match +EXPORT_SYMBOL vmlinux 0x54c8f935 neigh_table_init +EXPORT_SYMBOL vmlinux 0x54d42936 seq_printf +EXPORT_SYMBOL vmlinux 0x54e6fcdd net_enable_timestamp +EXPORT_SYMBOL vmlinux 0x5512e2b0 uart_add_one_port +EXPORT_SYMBOL vmlinux 0x55150f24 unregister_con_driver +EXPORT_SYMBOL vmlinux 0x5545dfd4 file_fsync +EXPORT_SYMBOL vmlinux 0x5547162c ipu_init_sync_panel +EXPORT_SYMBOL vmlinux 0x555f8f6b set_blocksize +EXPORT_SYMBOL vmlinux 0x5584901d keyring_clear +EXPORT_SYMBOL vmlinux 0x5585263d netif_carrier_off +EXPORT_SYMBOL vmlinux 0x5594be03 bitmap_remap +EXPORT_SYMBOL vmlinux 0x55a9c28c tcp_sync_mss +EXPORT_SYMBOL vmlinux 0x55d597e3 __scsi_iterate_devices +EXPORT_SYMBOL vmlinux 0x5600904f fb_get_color_depth +EXPORT_SYMBOL vmlinux 0x56100773 journal_wipe +EXPORT_SYMBOL vmlinux 0x5614b010 xfrm_policy_walk_done +EXPORT_SYMBOL vmlinux 0x5633950a tcp_make_synack +EXPORT_SYMBOL vmlinux 0x5635a60a vmalloc_user +EXPORT_SYMBOL vmlinux 0x5636ada8 xfrm4_rcv_encap +EXPORT_SYMBOL vmlinux 0x5669483d scsi_remove_device +EXPORT_SYMBOL vmlinux 0x56c8799d scsi_kunmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x56f24a4f __scsi_add_device +EXPORT_SYMBOL vmlinux 0x572e85d4 blk_lookup_devt +EXPORT_SYMBOL vmlinux 0x573704ae mpage_readpages +EXPORT_SYMBOL vmlinux 0x573a65b0 skb_dequeue +EXPORT_SYMBOL vmlinux 0x57806f2f per_cpu____irq_regs +EXPORT_SYMBOL vmlinux 0x57a6504e vsnprintf +EXPORT_SYMBOL vmlinux 0x57e52676 __inet6_hash +EXPORT_SYMBOL vmlinux 0x57f1e388 dev_set_promiscuity +EXPORT_SYMBOL vmlinux 0x580691d9 mii_check_link +EXPORT_SYMBOL vmlinux 0x583692b8 key_negate_and_link +EXPORT_SYMBOL vmlinux 0x5838f6c9 rtc_valid_tm +EXPORT_SYMBOL vmlinux 0x58431ce3 security_task_getsecid +EXPORT_SYMBOL vmlinux 0x5868dba0 clk_disable +EXPORT_SYMBOL vmlinux 0x587621b1 fsl_shw_establish_key +EXPORT_SYMBOL vmlinux 0x58e0c277 key_put +EXPORT_SYMBOL vmlinux 0x58fe8d0e flush_signals +EXPORT_SYMBOL vmlinux 0x5934392b fb_register_client +EXPORT_SYMBOL vmlinux 0x594bf15b ioport_map +EXPORT_SYMBOL vmlinux 0x594e1317 __modsi3 +EXPORT_SYMBOL vmlinux 0x5960c778 gnet_stats_start_copy +EXPORT_SYMBOL vmlinux 0x59706f79 nf_log_unregister_pf +EXPORT_SYMBOL vmlinux 0x59b5f07a test_set_page_writeback +EXPORT_SYMBOL vmlinux 0x59d696b6 register_module_notifier +EXPORT_SYMBOL vmlinux 0x59d8223a ioport_resource +EXPORT_SYMBOL vmlinux 0x59e5070d __do_div64 +EXPORT_SYMBOL vmlinux 0x59eb6826 scc_decrypt_region +EXPORT_SYMBOL vmlinux 0x5a34f22d nf_afinfo +EXPORT_SYMBOL vmlinux 0x5a4c17a9 sock_no_sendmsg +EXPORT_SYMBOL vmlinux 0x5a68f4e8 dev_unicast_unsync +EXPORT_SYMBOL vmlinux 0x5a744b86 netlink_set_nonroot +EXPORT_SYMBOL vmlinux 0x5a9f08fd struct_module +EXPORT_SYMBOL vmlinux 0x5adeb691 snd_card_free_when_closed +EXPORT_SYMBOL vmlinux 0x5b0c5399 usb_gadget_unregister_driver +EXPORT_SYMBOL vmlinux 0x5b19634d div_s64_rem +EXPORT_SYMBOL vmlinux 0x5b1ac308 dma_mmap_writecombine +EXPORT_SYMBOL vmlinux 0x5b1db8e7 skb_pad +EXPORT_SYMBOL vmlinux 0x5b56839b bdput +EXPORT_SYMBOL vmlinux 0x5b641934 generic_file_llseek +EXPORT_SYMBOL vmlinux 0x5c10c55d nf_unregister_sockopt +EXPORT_SYMBOL vmlinux 0x5c121dbb snd_register_oss_device +EXPORT_SYMBOL vmlinux 0x5c18d72b gpio_usbotg_hs_active +EXPORT_SYMBOL vmlinux 0x5c325ec2 dget_locked +EXPORT_SYMBOL vmlinux 0x5c673bc8 tty_mutex +EXPORT_SYMBOL vmlinux 0x5c6b667f i2c_detach_client +EXPORT_SYMBOL vmlinux 0x5c6f9bb2 scsi_execute +EXPORT_SYMBOL vmlinux 0x5c89d954 sock_no_mmap +EXPORT_SYMBOL vmlinux 0x5c8dd63b generic_file_aio_write_nolock +EXPORT_SYMBOL vmlinux 0x5c906eb1 deny_write_access +EXPORT_SYMBOL vmlinux 0x5c9284a0 processor_id +EXPORT_SYMBOL vmlinux 0x5c9ee203 fib_default_rule_add +EXPORT_SYMBOL vmlinux 0x5cbffc03 dev_mc_sync +EXPORT_SYMBOL vmlinux 0x5cd164c9 skb_append_datato_frags +EXPORT_SYMBOL vmlinux 0x5ce08719 tcp_close +EXPORT_SYMBOL vmlinux 0x5d09c870 pid_task +EXPORT_SYMBOL vmlinux 0x5d39ea25 gpio_ata_active +EXPORT_SYMBOL vmlinux 0x5d43329c tty_insert_flip_string_flags +EXPORT_SYMBOL vmlinux 0x5d5a4a62 mark_buffer_dirty_inode +EXPORT_SYMBOL vmlinux 0x5d81d349 __lock_page +EXPORT_SYMBOL vmlinux 0x5df6ad9c dev_kfree_skb_any +EXPORT_SYMBOL vmlinux 0x5e05383d vm_map_ram +EXPORT_SYMBOL vmlinux 0x5e0ca79d release_sock +EXPORT_SYMBOL vmlinux 0x5e10f39c dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0x5e3498e1 cpu_sysdev_class +EXPORT_SYMBOL vmlinux 0x5e4d4902 key_alloc +EXPORT_SYMBOL vmlinux 0x5e53b9af iget_locked +EXPORT_SYMBOL vmlinux 0x5e5e5244 mxc_dma_config +EXPORT_SYMBOL vmlinux 0x5e7f4920 snd_pcm_format_set_silence +EXPORT_SYMBOL vmlinux 0x5e8494e0 tty_wait_until_sent +EXPORT_SYMBOL vmlinux 0x5ea520c5 tcp_select_initial_window +EXPORT_SYMBOL vmlinux 0x5ebb56fb down_read +EXPORT_SYMBOL vmlinux 0x5ed040b0 pm_set_vt_switch +EXPORT_SYMBOL vmlinux 0x5edd0762 bin2bcd +EXPORT_SYMBOL vmlinux 0x5f1ff161 i2c_smbus_write_byte_data +EXPORT_SYMBOL vmlinux 0x5f2f261f nla_append +EXPORT_SYMBOL vmlinux 0x5f754e5a memset +EXPORT_SYMBOL vmlinux 0x5f999434 sync_page_range +EXPORT_SYMBOL vmlinux 0x5fb89d91 tty_port_free_xmit_buf +EXPORT_SYMBOL vmlinux 0x5ffd9d7d blk_queue_max_phys_segments +EXPORT_SYMBOL vmlinux 0x600683d3 do_unblank_screen +EXPORT_SYMBOL vmlinux 0x600e1fea mxc_dma_setup_channel +EXPORT_SYMBOL vmlinux 0x602c96f0 copy_to_user_fromio +EXPORT_SYMBOL vmlinux 0x602d47c0 cancel_delayed_work_sync +EXPORT_SYMBOL vmlinux 0x605970dc sock_common_setsockopt +EXPORT_SYMBOL vmlinux 0x6067cd33 grab_cache_page_nowait +EXPORT_SYMBOL vmlinux 0x608c2831 warn_on_slowpath +EXPORT_SYMBOL vmlinux 0x609f1c7e synchronize_net +EXPORT_SYMBOL vmlinux 0x60a32ea9 pm_power_off +EXPORT_SYMBOL vmlinux 0x60a4efe2 ida_get_new +EXPORT_SYMBOL vmlinux 0x60be9396 vfs_readdir +EXPORT_SYMBOL vmlinux 0x612390ad netpoll_set_trap +EXPORT_SYMBOL vmlinux 0x61243d70 netdev_rx_csum_fault +EXPORT_SYMBOL vmlinux 0x612eb075 seq_open +EXPORT_SYMBOL vmlinux 0x6136d14f pagecache_write_begin +EXPORT_SYMBOL vmlinux 0x61485e6b bio_uncopy_user +EXPORT_SYMBOL vmlinux 0x61593b72 __mod_timer +EXPORT_SYMBOL vmlinux 0x616a348f blk_free_tags +EXPORT_SYMBOL vmlinux 0x61840d52 read_cache_pages +EXPORT_SYMBOL vmlinux 0x618d8299 set_notify_swap_entry_free +EXPORT_SYMBOL vmlinux 0x61aaac22 tcp_ioctl +EXPORT_SYMBOL vmlinux 0x61aec1e8 seq_bitmap +EXPORT_SYMBOL vmlinux 0x61b7b126 simple_strtoull +EXPORT_SYMBOL vmlinux 0x61c7c457 netlink_ack +EXPORT_SYMBOL vmlinux 0x61d3d91c sah_insert_skha_algorithm +EXPORT_SYMBOL vmlinux 0x621ed725 rtnl_unicast +EXPORT_SYMBOL vmlinux 0x625dc4d8 tcf_em_tree_dump +EXPORT_SYMBOL vmlinux 0x626c4f18 netdev_class_remove_file +EXPORT_SYMBOL vmlinux 0x626efe7f xfrm_dst_ifdown +EXPORT_SYMBOL vmlinux 0x62737e1d sock_unregister +EXPORT_SYMBOL vmlinux 0x62827bec security_secctx_to_secid +EXPORT_SYMBOL vmlinux 0x62927770 sk_dst_check +EXPORT_SYMBOL vmlinux 0x62abd750 inet_csk_delete_keepalive_timer +EXPORT_SYMBOL vmlinux 0x62b1975c snd_pcm_new_stream +EXPORT_SYMBOL vmlinux 0x62b3e0ef d_namespace_path +EXPORT_SYMBOL vmlinux 0x62c7f09e __locks_copy_lock +EXPORT_SYMBOL vmlinux 0x62e57ab2 proc_net_netfilter +EXPORT_SYMBOL vmlinux 0x62ee1989 block_truncate_page +EXPORT_SYMBOL vmlinux 0x632638bd mii_check_media +EXPORT_SYMBOL vmlinux 0x63cc9d3d ____pagevec_lru_add +EXPORT_SYMBOL vmlinux 0x63d257d3 inet_select_addr +EXPORT_SYMBOL vmlinux 0x63ecad53 register_netdevice_notifier +EXPORT_SYMBOL vmlinux 0x63f51c49 snd_pcm_hw_param_value +EXPORT_SYMBOL vmlinux 0x6403e338 tcp_memory_pressure +EXPORT_SYMBOL vmlinux 0x640a7078 posix_acl_create_masq +EXPORT_SYMBOL vmlinux 0x6444119b clk_get_parent +EXPORT_SYMBOL vmlinux 0x646370c0 scsi_is_host_device +EXPORT_SYMBOL vmlinux 0x64852540 scsi_register +EXPORT_SYMBOL vmlinux 0x648a97c1 nf_register_queue_handler +EXPORT_SYMBOL vmlinux 0x64999478 congestion_wait +EXPORT_SYMBOL vmlinux 0x64b4bc15 do_system_keystore_slot_read +EXPORT_SYMBOL vmlinux 0x64d5d567 grab_cache_page_write_begin +EXPORT_SYMBOL vmlinux 0x64f2981a request_key_async +EXPORT_SYMBOL vmlinux 0x650128e7 br_fdb_get_hook +EXPORT_SYMBOL vmlinux 0x6509f11a sock_no_setsockopt +EXPORT_SYMBOL vmlinux 0x650f8603 snd_pcm_format_silence_64 +EXPORT_SYMBOL vmlinux 0x651a4139 test_taint +EXPORT_SYMBOL vmlinux 0x652a310d generic_file_splice_write +EXPORT_SYMBOL vmlinux 0x65408378 zlib_inflate_blob +EXPORT_SYMBOL vmlinux 0x65414e67 dev_valid_name +EXPORT_SYMBOL vmlinux 0x6572fdfb set_irq_chip +EXPORT_SYMBOL vmlinux 0x659c47ad arp_broken_ops +EXPORT_SYMBOL vmlinux 0x65a5c3a2 cpu_present_map +EXPORT_SYMBOL vmlinux 0x65ae0b69 unlock_page +EXPORT_SYMBOL vmlinux 0x65bdc183 vfs_path_lookup +EXPORT_SYMBOL vmlinux 0x65cb5674 fsl_usb_xcvr_register +EXPORT_SYMBOL vmlinux 0x65eff84a filemap_fdatawrite +EXPORT_SYMBOL vmlinux 0x65f8e2aa blk_queue_merge_bvec +EXPORT_SYMBOL vmlinux 0x66017424 register_console +EXPORT_SYMBOL vmlinux 0x66029cc3 __pskb_pull_tail +EXPORT_SYMBOL vmlinux 0x6628a19a check_disk_change +EXPORT_SYMBOL vmlinux 0x662f5f9c kern_path +EXPORT_SYMBOL vmlinux 0x66494877 mxc_iomux_set_input +EXPORT_SYMBOL vmlinux 0x668da8d5 zlib_inflateIncomp +EXPORT_SYMBOL vmlinux 0x66cbc2d2 gpio_spi_active +EXPORT_SYMBOL vmlinux 0x673673f9 snd_timer_global_register +EXPORT_SYMBOL vmlinux 0x67733b7e snd_ctl_rename_id +EXPORT_SYMBOL vmlinux 0x6779caff ipu_uninit_channel +EXPORT_SYMBOL vmlinux 0x67b27ec1 tty_std_termios +EXPORT_SYMBOL vmlinux 0x67c2fa54 __copy_to_user +EXPORT_SYMBOL vmlinux 0x67d0476d bio_kmalloc +EXPORT_SYMBOL vmlinux 0x67d2df12 lookup_one_len +EXPORT_SYMBOL vmlinux 0x67dd28df uart_remove_one_port +EXPORT_SYMBOL vmlinux 0x67e32e86 lock_sock_nested +EXPORT_SYMBOL vmlinux 0x6861055c uart_suspend_port +EXPORT_SYMBOL vmlinux 0x68720b5d __invalidate_device +EXPORT_SYMBOL vmlinux 0x687ba1d5 mxc_dma_reset +EXPORT_SYMBOL vmlinux 0x689863d7 snd_pcm_lib_read +EXPORT_SYMBOL vmlinux 0x6898a756 sg_init_table +EXPORT_SYMBOL vmlinux 0x6898d029 __skb_checksum_complete +EXPORT_SYMBOL vmlinux 0x68a24153 snd_pcm_format_physical_width +EXPORT_SYMBOL vmlinux 0x68e63531 dev_get_flags +EXPORT_SYMBOL vmlinux 0x68f93d07 xfrm_find_acq_byseq +EXPORT_SYMBOL vmlinux 0x690c048c get_super +EXPORT_SYMBOL vmlinux 0x691b6cca journal_get_undo_access +EXPORT_SYMBOL vmlinux 0x6927d67a __dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0x692c2d9c __request_region +EXPORT_SYMBOL vmlinux 0x6936013c __nla_put_nohdr +EXPORT_SYMBOL vmlinux 0x69496641 mod_timer +EXPORT_SYMBOL vmlinux 0x694f117e elv_rb_former_request +EXPORT_SYMBOL vmlinux 0x6954d124 sdma_malloc +EXPORT_SYMBOL vmlinux 0x6971447a rtc_month_days +EXPORT_SYMBOL vmlinux 0x697a331b input_register_device +EXPORT_SYMBOL vmlinux 0x69927dff try_acquire_console_sem +EXPORT_SYMBOL vmlinux 0x69a5c6ba bfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0x69acaa9a nobh_truncate_page +EXPORT_SYMBOL vmlinux 0x69af2327 idr_init +EXPORT_SYMBOL vmlinux 0x69c8c1d5 security_req_classify_flow +EXPORT_SYMBOL vmlinux 0x69d38ed9 __scsi_print_sense +EXPORT_SYMBOL vmlinux 0x69e27c7a bitmap_copy_le +EXPORT_SYMBOL vmlinux 0x69f43196 bioset_free +EXPORT_SYMBOL vmlinux 0x69f89216 xfrm_register_type +EXPORT_SYMBOL vmlinux 0x69fce541 sock_no_sendpage +EXPORT_SYMBOL vmlinux 0x6a030781 lease_modify +EXPORT_SYMBOL vmlinux 0x6a037cf1 mempool_kfree +EXPORT_SYMBOL vmlinux 0x6a23afb0 current_fs_time +EXPORT_SYMBOL vmlinux 0x6a47571d __set_personality +EXPORT_SYMBOL vmlinux 0x6a7cb599 write_cache_pages +EXPORT_SYMBOL vmlinux 0x6ab3c0fe neigh_table_clear +EXPORT_SYMBOL vmlinux 0x6ac45c28 __up_write +EXPORT_SYMBOL vmlinux 0x6adf930f bio_unmap_user +EXPORT_SYMBOL vmlinux 0x6afaf2ca fsl_usb_xcvr_unregister +EXPORT_SYMBOL vmlinux 0x6b05622c __neigh_for_each_release +EXPORT_SYMBOL vmlinux 0x6b0a86fe blk_alloc_queue_node +EXPORT_SYMBOL vmlinux 0x6b0ac740 mxc_dma_free +EXPORT_SYMBOL vmlinux 0x6b1b67d3 __bdevname +EXPORT_SYMBOL vmlinux 0x6b2dc060 dump_stack +EXPORT_SYMBOL vmlinux 0x6b4b3ef5 input_set_keycode +EXPORT_SYMBOL vmlinux 0x6bd27895 blk_stop_queue +EXPORT_SYMBOL vmlinux 0x6bdcfd99 qdisc_class_hash_remove +EXPORT_SYMBOL vmlinux 0x6c174106 __mmc_claim_host +EXPORT_SYMBOL vmlinux 0x6c1ce5ce strcspn +EXPORT_SYMBOL vmlinux 0x6c36a5c1 __mutex_init +EXPORT_SYMBOL vmlinux 0x6c44909a sync_inode +EXPORT_SYMBOL vmlinux 0x6c61ce70 num_registered_fb +EXPORT_SYMBOL vmlinux 0x6c702af7 sysctl_udp_rmem_min +EXPORT_SYMBOL vmlinux 0x6c8986da netif_device_attach +EXPORT_SYMBOL vmlinux 0x6c942200 d_alloc_root +EXPORT_SYMBOL vmlinux 0x6ccb5b02 alloc_netdev_mq +EXPORT_SYMBOL vmlinux 0x6cdc5c6b nla_strlcpy +EXPORT_SYMBOL vmlinux 0x6cef247f __strnlen_user +EXPORT_SYMBOL vmlinux 0x6cf8f6d7 snd_pcm_lib_free_pages +EXPORT_SYMBOL vmlinux 0x6d0da34c param_get_short +EXPORT_SYMBOL vmlinux 0x6d27ef64 __bitmap_empty +EXPORT_SYMBOL vmlinux 0x6d288375 radix_tree_next_hole +EXPORT_SYMBOL vmlinux 0x6d294e43 clock_t_to_jiffies +EXPORT_SYMBOL vmlinux 0x6d340f64 tty_termios_input_baud_rate +EXPORT_SYMBOL vmlinux 0x6d662533 _find_first_bit_le +EXPORT_SYMBOL vmlinux 0x6d77391c kblockd_schedule_work +EXPORT_SYMBOL vmlinux 0x6da7cf5e snd_ctl_remove_id +EXPORT_SYMBOL vmlinux 0x6dce1b58 nobh_writepage +EXPORT_SYMBOL vmlinux 0x6de093e2 mxc_request_iomux +EXPORT_SYMBOL vmlinux 0x6def2db2 half_md4_transform +EXPORT_SYMBOL vmlinux 0x6e127b51 ipu_link_channels +EXPORT_SYMBOL vmlinux 0x6e440b58 memcpy_fromiovecend +EXPORT_SYMBOL vmlinux 0x6e53a2dd inet_frags_exit_net +EXPORT_SYMBOL vmlinux 0x6e54d9e1 init_file +EXPORT_SYMBOL vmlinux 0x6e68e750 block_write_begin +EXPORT_SYMBOL vmlinux 0x6e720ff2 rtnl_unlock +EXPORT_SYMBOL vmlinux 0x6e767c9a bio_map_user +EXPORT_SYMBOL vmlinux 0x6e798677 alloc_file +EXPORT_SYMBOL vmlinux 0x6e84a85c save_time_delta +EXPORT_SYMBOL vmlinux 0x6e9dd606 __symbol_put +EXPORT_SYMBOL vmlinux 0x6eb47b50 sah_add_in_out_desc +EXPORT_SYMBOL vmlinux 0x6eb62a64 i2c_probe +EXPORT_SYMBOL vmlinux 0x6ed8df63 tty_kref_put +EXPORT_SYMBOL vmlinux 0x6ef8fcd8 snd_pcm_format_linear +EXPORT_SYMBOL vmlinux 0x6f72e05b block_prepare_write +EXPORT_SYMBOL vmlinux 0x6f8eedf0 kernel_getsockopt +EXPORT_SYMBOL vmlinux 0x6f8f7db6 scsi_dma_map +EXPORT_SYMBOL vmlinux 0x6fa8f45d journal_clear_err +EXPORT_SYMBOL vmlinux 0x6fcb87a1 touch_softlockup_watchdog +EXPORT_SYMBOL vmlinux 0x6fd92dc1 generic_file_splice_read +EXPORT_SYMBOL vmlinux 0x7008a9b7 timespec_to_jiffies +EXPORT_SYMBOL vmlinux 0x70185bab __brelse +EXPORT_SYMBOL vmlinux 0x701d0ebd snprintf +EXPORT_SYMBOL vmlinux 0x70775b98 check_disk_size_change +EXPORT_SYMBOL vmlinux 0x70b901cb mmc_alloc_host +EXPORT_SYMBOL vmlinux 0x70d5a81b vm_insert_mixed +EXPORT_SYMBOL vmlinux 0x70ef5d34 put_tty_driver +EXPORT_SYMBOL vmlinux 0x70f5b3fc bio_integrity_get_tag +EXPORT_SYMBOL vmlinux 0x7109a817 generic_show_options +EXPORT_SYMBOL vmlinux 0x7129e5f8 hex_asc +EXPORT_SYMBOL vmlinux 0x713b32d5 bdi_set_max_ratio +EXPORT_SYMBOL vmlinux 0x713cd1d2 nobh_write_begin +EXPORT_SYMBOL vmlinux 0x7144ea25 inet_shutdown +EXPORT_SYMBOL vmlinux 0x7171121c overflowgid +EXPORT_SYMBOL vmlinux 0x719deee4 snd_timer_open +EXPORT_SYMBOL vmlinux 0x71a50dbc register_blkdev +EXPORT_SYMBOL vmlinux 0x71b580b7 inet_getname +EXPORT_SYMBOL vmlinux 0x71c41f89 __dst_free +EXPORT_SYMBOL vmlinux 0x71c90087 memcmp +EXPORT_SYMBOL vmlinux 0x71d27de1 fsl_usb_host_uninit +EXPORT_SYMBOL vmlinux 0x71d2e01f set_page_dirty +EXPORT_SYMBOL vmlinux 0x72270e35 do_gettimeofday +EXPORT_SYMBOL vmlinux 0x72364346 __scsi_device_lookup +EXPORT_SYMBOL vmlinux 0x72493903 snd_dma_alloc_pages_fallback +EXPORT_SYMBOL vmlinux 0x724b7a11 __lookup_hash +EXPORT_SYMBOL vmlinux 0x727fa70e generic_listxattr +EXPORT_SYMBOL vmlinux 0x727fe0c3 tcp_v4_remember_stamp +EXPORT_SYMBOL vmlinux 0x729e039b tcp_disconnect +EXPORT_SYMBOL vmlinux 0x72b044d0 tty_register_ldisc +EXPORT_SYMBOL vmlinux 0x72d2039f audit_log_format +EXPORT_SYMBOL vmlinux 0x72d5af61 try_wait_for_completion +EXPORT_SYMBOL vmlinux 0x72e6a74d inet_frag_find +EXPORT_SYMBOL vmlinux 0x72ea7b2d scsi_device_type +EXPORT_SYMBOL vmlinux 0x72fbae28 set_current_groups +EXPORT_SYMBOL vmlinux 0x7301c131 udp_flush_pending_frames +EXPORT_SYMBOL vmlinux 0x73069aac cpu_possible_map +EXPORT_SYMBOL vmlinux 0x73154c6f scsi_get_command +EXPORT_SYMBOL vmlinux 0x73440e45 bio_integrity_enabled +EXPORT_SYMBOL vmlinux 0x73afa77a journal_start +EXPORT_SYMBOL vmlinux 0x73c32e6e iw_handler_set_thrspy +EXPORT_SYMBOL vmlinux 0x73cc7bc8 tcp_rcv_state_process +EXPORT_SYMBOL vmlinux 0x73e20c1c strlcpy +EXPORT_SYMBOL vmlinux 0x7459e033 gpio_clear_int +EXPORT_SYMBOL vmlinux 0x745da020 bioset_create +EXPORT_SYMBOL vmlinux 0x7485e15e unregister_chrdev_region +EXPORT_SYMBOL vmlinux 0x748a6677 sah_Free_Descriptor +EXPORT_SYMBOL vmlinux 0x748e208a splice_direct_to_actor +EXPORT_SYMBOL vmlinux 0x749bccab blk_integrity_unregister +EXPORT_SYMBOL vmlinux 0x74b0bd0f __blockdev_direct_IO +EXPORT_SYMBOL vmlinux 0x74cc238d current_kernel_time +EXPORT_SYMBOL vmlinux 0x74e74534 page_zero_new_buffers +EXPORT_SYMBOL vmlinux 0x750f6c9c dev_load +EXPORT_SYMBOL vmlinux 0x758ba000 generic_make_request +EXPORT_SYMBOL vmlinux 0x758c0e25 skb_append +EXPORT_SYMBOL vmlinux 0x75a4c34e soft_cursor +EXPORT_SYMBOL vmlinux 0x75babf35 mxc_pg_disable +EXPORT_SYMBOL vmlinux 0x75bff807 sk_stream_wait_connect +EXPORT_SYMBOL vmlinux 0x75fee7fd __raw_writesb +EXPORT_SYMBOL vmlinux 0x760a0f4f yield +EXPORT_SYMBOL vmlinux 0x760b437a unregister_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x764362dc mxc_dma_sg_config +EXPORT_SYMBOL vmlinux 0x765f75fb pgprot_user +EXPORT_SYMBOL vmlinux 0x76708b53 dev_set_allmulti +EXPORT_SYMBOL vmlinux 0x769ec091 inode_setattr +EXPORT_SYMBOL vmlinux 0x76bf656d __bitmap_shift_left +EXPORT_SYMBOL vmlinux 0x76cf47f6 __aeabi_llsl +EXPORT_SYMBOL vmlinux 0x76d3cd60 laptop_mode +EXPORT_SYMBOL vmlinux 0x76f41354 inet_twsk_deschedule +EXPORT_SYMBOL vmlinux 0x770deede cfb_fillrect +EXPORT_SYMBOL vmlinux 0x77110604 del_gendisk +EXPORT_SYMBOL vmlinux 0x7714b1c5 snd_pcm_hw_constraint_ratdens +EXPORT_SYMBOL vmlinux 0x77326aa6 udp_disconnect +EXPORT_SYMBOL vmlinux 0x77603ba8 sock_init_data +EXPORT_SYMBOL vmlinux 0x777375ac simple_dir_inode_operations +EXPORT_SYMBOL vmlinux 0x77824a96 blk_queue_init_tags +EXPORT_SYMBOL vmlinux 0x77b9ccac _snd_pcm_hw_param_setempty +EXPORT_SYMBOL vmlinux 0x77e7d017 redirty_page_for_writepage +EXPORT_SYMBOL vmlinux 0x77ecac9f zlib_inflateEnd +EXPORT_SYMBOL vmlinux 0x781685b0 start_tty +EXPORT_SYMBOL vmlinux 0x782e18f7 tty_port_alloc_xmit_buf +EXPORT_SYMBOL vmlinux 0x78572692 filemap_fdatawait +EXPORT_SYMBOL vmlinux 0x786e28a5 snd_mixer_oss_notify_callback +EXPORT_SYMBOL vmlinux 0x7885994b config_uartdma_event +EXPORT_SYMBOL vmlinux 0x788fe103 iomem_resource +EXPORT_SYMBOL vmlinux 0x78c593f0 locks_copy_lock +EXPORT_SYMBOL vmlinux 0x78ed4e2b __kfree_skb +EXPORT_SYMBOL vmlinux 0x78edd180 pmic_adc_convert +EXPORT_SYMBOL vmlinux 0x792e3153 file_permission +EXPORT_SYMBOL vmlinux 0x794487ee disable_hlt +EXPORT_SYMBOL vmlinux 0x79454f27 sdma_virt_to_phys +EXPORT_SYMBOL vmlinux 0x794a36ec do_sync_read +EXPORT_SYMBOL vmlinux 0x79600d4a wait_for_completion_killable +EXPORT_SYMBOL vmlinux 0x796fc5ce scsi_get_sense_info_fld +EXPORT_SYMBOL vmlinux 0x7987cc4f snd_ctl_notify +EXPORT_SYMBOL vmlinux 0x798e2a04 invalidate_partition +EXPORT_SYMBOL vmlinux 0x79aa04a2 get_random_bytes +EXPORT_SYMBOL vmlinux 0x79ad224b tasklet_kill +EXPORT_SYMBOL vmlinux 0x79b8a735 kernel_sendmsg +EXPORT_SYMBOL vmlinux 0x79bd984d wake_up_process +EXPORT_SYMBOL vmlinux 0x79de83dd bioset_integrity_create +EXPORT_SYMBOL vmlinux 0x7a0cef9a dev_driver_string +EXPORT_SYMBOL vmlinux 0x7a2a837d strict_strtol +EXPORT_SYMBOL vmlinux 0x7a387096 udp_lib_get_port +EXPORT_SYMBOL vmlinux 0x7a55a2ae eth_header_cache +EXPORT_SYMBOL vmlinux 0x7a600857 scsi_host_put +EXPORT_SYMBOL vmlinux 0x7a70adf6 bio_integrity_endio +EXPORT_SYMBOL vmlinux 0x7a7582a2 path_lookup +EXPORT_SYMBOL vmlinux 0x7a8c1589 generic_cont_expand_simple +EXPORT_SYMBOL vmlinux 0x7ab91fd5 seq_read +EXPORT_SYMBOL vmlinux 0x7afc9d8a unregister_sound_mixer +EXPORT_SYMBOL vmlinux 0x7afd92c2 scsi_eh_restore_cmnd +EXPORT_SYMBOL vmlinux 0x7b157d9c xfrm_policy_register_afinfo +EXPORT_SYMBOL vmlinux 0x7b2e9d2b __module_put_and_exit +EXPORT_SYMBOL vmlinux 0x7b3d7d54 fb_set_cmap +EXPORT_SYMBOL vmlinux 0x7bd88334 snd_pcm_stop +EXPORT_SYMBOL vmlinux 0x7bde2d9a gpio_nand_active +EXPORT_SYMBOL vmlinux 0x7c46233a cpufreq_quick_get +EXPORT_SYMBOL vmlinux 0x7c4b9d99 gnet_stats_finish_copy +EXPORT_SYMBOL vmlinux 0x7c516be5 sah_Create_Link +EXPORT_SYMBOL vmlinux 0x7c60d66e getname +EXPORT_SYMBOL vmlinux 0x7c645b0d __alloc_pages_internal +EXPORT_SYMBOL vmlinux 0x7c6c2577 fbcon_set_bitops +EXPORT_SYMBOL vmlinux 0x7c87ec3e snd_timer_resolution +EXPORT_SYMBOL vmlinux 0x7c904ded unregister_module_notifier +EXPORT_SYMBOL vmlinux 0x7c9719b1 scsi_device_resume +EXPORT_SYMBOL vmlinux 0x7cc035a7 __ucmpdi2 +EXPORT_SYMBOL vmlinux 0x7d02ff39 kfree_skb +EXPORT_SYMBOL vmlinux 0x7d04a779 register_sysctl_table +EXPORT_SYMBOL vmlinux 0x7d099c67 gpio_fec_active +EXPORT_SYMBOL vmlinux 0x7d11c268 jiffies +EXPORT_SYMBOL vmlinux 0x7d30458a simple_unlink +EXPORT_SYMBOL vmlinux 0x7d51329a __blk_run_queue +EXPORT_SYMBOL vmlinux 0x7d5ceadd skb_unlink +EXPORT_SYMBOL vmlinux 0x7d850612 utf8_mbstowcs +EXPORT_SYMBOL vmlinux 0x7dceceac capable +EXPORT_SYMBOL vmlinux 0x7df2f651 __scm_destroy +EXPORT_SYMBOL vmlinux 0x7e172681 cpufreq_get_policy +EXPORT_SYMBOL vmlinux 0x7e2cdd15 blk_queue_max_segment_size +EXPORT_SYMBOL vmlinux 0x7e531cde del_timer +EXPORT_SYMBOL vmlinux 0x7e573e67 nand_correct_data +EXPORT_SYMBOL vmlinux 0x7e7b4256 xrlim_allow +EXPORT_SYMBOL vmlinux 0x7e8b22d1 bio_clone +EXPORT_SYMBOL vmlinux 0x7e9385a7 tty_get_baud_rate +EXPORT_SYMBOL vmlinux 0x7e96ec53 register_key_type +EXPORT_SYMBOL vmlinux 0x7e9ebb05 kernel_thread +EXPORT_SYMBOL vmlinux 0x7ec21005 end_buffer_read_sync +EXPORT_SYMBOL vmlinux 0x7f24de73 jiffies_to_usecs +EXPORT_SYMBOL vmlinux 0x7f2eeadf sock_rfree +EXPORT_SYMBOL vmlinux 0x7f3a472f set_disk_ro +EXPORT_SYMBOL vmlinux 0x7f45cf07 elv_queue_empty +EXPORT_SYMBOL vmlinux 0x7f548a0c register_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0x7f627e35 blkdev_issue_discard +EXPORT_SYMBOL vmlinux 0x7f63b31e _memcpy_toio +EXPORT_SYMBOL vmlinux 0x7f67e115 snd_pcm_lib_preallocate_pages_for_all +EXPORT_SYMBOL vmlinux 0x7f9861bb xfrm_find_acq +EXPORT_SYMBOL vmlinux 0x7fc68b02 kernel_listen +EXPORT_SYMBOL vmlinux 0x7fd6efd3 clk_get +EXPORT_SYMBOL vmlinux 0x7feab686 inet_release +EXPORT_SYMBOL vmlinux 0x8006bbcb fifo_set_limit +EXPORT_SYMBOL vmlinux 0x80093940 con_copy_unimap +EXPORT_SYMBOL vmlinux 0x800e4ffa __muldi3 +EXPORT_SYMBOL vmlinux 0x8063f83d radix_tree_gang_lookup +EXPORT_SYMBOL vmlinux 0x8085c7b1 prepare_to_wait +EXPORT_SYMBOL vmlinux 0x808adb94 bio_free +EXPORT_SYMBOL vmlinux 0x80c29ec0 empty_zero_page +EXPORT_SYMBOL vmlinux 0x80e26a7c blk_queue_update_dma_alignment +EXPORT_SYMBOL vmlinux 0x80f91afa mmc_suspend_host +EXPORT_SYMBOL vmlinux 0x8115341d sah_Physicalise_Descriptors +EXPORT_SYMBOL vmlinux 0x8135f5a5 bio_put +EXPORT_SYMBOL vmlinux 0x814371b0 d_instantiate +EXPORT_SYMBOL vmlinux 0x8144fd5d skb_put +EXPORT_SYMBOL vmlinux 0x8151052a kernel_getsockname +EXPORT_SYMBOL vmlinux 0x815b5dd4 match_octal +EXPORT_SYMBOL vmlinux 0x81799cee vscnprintf +EXPORT_SYMBOL vmlinux 0x81c4fc8f i2c_smbus_read_word_data +EXPORT_SYMBOL vmlinux 0x81d856fc mem_map +EXPORT_SYMBOL vmlinux 0x81ea3d3d give_up_console +EXPORT_SYMBOL vmlinux 0x820d024c journal_force_commit +EXPORT_SYMBOL vmlinux 0x820d225f print_mac +EXPORT_SYMBOL vmlinux 0x8213073e request_firmware +EXPORT_SYMBOL vmlinux 0x821bdae5 inet_proto_csum_replace4 +EXPORT_SYMBOL vmlinux 0x82311389 rtnetlink_put_metrics +EXPORT_SYMBOL vmlinux 0x824087a1 __mxc_iounmap +EXPORT_SYMBOL vmlinux 0x8247f414 gpio_activate_audio_ports +EXPORT_SYMBOL vmlinux 0x8248f795 freeze_bdev +EXPORT_SYMBOL vmlinux 0x8251bcc3 bitmap_release_region +EXPORT_SYMBOL vmlinux 0x82561e99 init_special_inode +EXPORT_SYMBOL vmlinux 0x82629de5 simple_set_mnt +EXPORT_SYMBOL vmlinux 0x8266e336 notify_change +EXPORT_SYMBOL vmlinux 0x82692209 kref_set +EXPORT_SYMBOL vmlinux 0x8269e8e4 sock_map_fd +EXPORT_SYMBOL vmlinux 0x82890acb i2c_smbus_xfer +EXPORT_SYMBOL vmlinux 0x829529a5 page_symlink_inode_operations +EXPORT_SYMBOL vmlinux 0x82e5a238 vm_get_page_prot +EXPORT_SYMBOL vmlinux 0x83006046 qdisc_list_del +EXPORT_SYMBOL vmlinux 0x831185a5 dev_unicast_add +EXPORT_SYMBOL vmlinux 0x8320bea8 __umodsi3 +EXPORT_SYMBOL vmlinux 0x832820a6 get_user_pages +EXPORT_SYMBOL vmlinux 0x83572933 __free_pages +EXPORT_SYMBOL vmlinux 0x835889c9 fsl_shw_init_keystore +EXPORT_SYMBOL vmlinux 0x835a41a5 default_llseek +EXPORT_SYMBOL vmlinux 0x836202b1 mc13892_bklit_set_blink_p +EXPORT_SYMBOL vmlinux 0x836bdb72 nand_flash_ids +EXPORT_SYMBOL vmlinux 0x8379dfaf key_unlink +EXPORT_SYMBOL vmlinux 0x83a476ce bitmap_scnlistprintf +EXPORT_SYMBOL vmlinux 0x83ac93d5 sah_add_two_in_desc +EXPORT_SYMBOL vmlinux 0x83dfe4b1 register_sound_mixer +EXPORT_SYMBOL vmlinux 0x83f30749 take_over_console +EXPORT_SYMBOL vmlinux 0x8424946c fsl_shw_symmetric_decrypt +EXPORT_SYMBOL vmlinux 0x8427967d mntput_no_expire +EXPORT_SYMBOL vmlinux 0x8434def2 journal_update_format +EXPORT_SYMBOL vmlinux 0x844822db textsearch_prepare +EXPORT_SYMBOL vmlinux 0x845f6b56 dev_get_by_name +EXPORT_SYMBOL vmlinux 0x84b183ae strncmp +EXPORT_SYMBOL vmlinux 0x850c30c0 inet_csk_destroy_sock +EXPORT_SYMBOL vmlinux 0x852f7fbb framebuffer_release +EXPORT_SYMBOL vmlinux 0x85465b71 snd_register_device_for_dev +EXPORT_SYMBOL vmlinux 0x85670f1d rtnl_is_locked +EXPORT_SYMBOL vmlinux 0x856d7e2a have_submounts +EXPORT_SYMBOL vmlinux 0x85ac7f10 posix_acl_from_xattr +EXPORT_SYMBOL vmlinux 0x85c24e81 console_start +EXPORT_SYMBOL vmlinux 0x85df9b6c strsep +EXPORT_SYMBOL vmlinux 0x85e7deb2 iov_iter_fault_in_readable +EXPORT_SYMBOL vmlinux 0x85e92616 gpio_i2c_active +EXPORT_SYMBOL vmlinux 0x863cb91a utf8_wcstombs +EXPORT_SYMBOL vmlinux 0x86497f74 journal_unlock_updates +EXPORT_SYMBOL vmlinux 0x864e4b28 dev_disable_lro +EXPORT_SYMBOL vmlinux 0x8664f62e cpufreq_update_policy +EXPORT_SYMBOL vmlinux 0x8666a85b posix_acl_permission +EXPORT_SYMBOL vmlinux 0x867097e0 lease_get_mtime +EXPORT_SYMBOL vmlinux 0x867c7e09 d_rehash +EXPORT_SYMBOL vmlinux 0x868acba5 get_options +EXPORT_SYMBOL vmlinux 0x86933bed do_system_keystore_slot_load +EXPORT_SYMBOL vmlinux 0x869b5632 ipu_unlink_channels +EXPORT_SYMBOL vmlinux 0x86bce62f fsl_shw_extract_key +EXPORT_SYMBOL vmlinux 0x86d29516 pmic_event_unsubscribe +EXPORT_SYMBOL vmlinux 0x86fb9b05 bitmap_parse_user +EXPORT_SYMBOL vmlinux 0x871c0a7e fiemap_check_flags +EXPORT_SYMBOL vmlinux 0x87203d68 inode_double_unlock +EXPORT_SYMBOL vmlinux 0x8785725d param_set_charp +EXPORT_SYMBOL vmlinux 0x878ab3ce sysctl_tcp_adv_win_scale +EXPORT_SYMBOL vmlinux 0x87b87641 vfs_rename +EXPORT_SYMBOL vmlinux 0x87ccfc89 fput +EXPORT_SYMBOL vmlinux 0x87daccc7 gpio_i2c_hs_active +EXPORT_SYMBOL vmlinux 0x87f5361d mii_nway_restart +EXPORT_SYMBOL vmlinux 0x881039d0 zlib_inflate +EXPORT_SYMBOL vmlinux 0x881d7bd3 scsi_release_buffers +EXPORT_SYMBOL vmlinux 0x881dc24e sah_Alloc_Link +EXPORT_SYMBOL vmlinux 0x8859614f simple_pin_fs +EXPORT_SYMBOL vmlinux 0x886c4cf6 follow_down +EXPORT_SYMBOL vmlinux 0x887a0dc3 journal_revoke +EXPORT_SYMBOL vmlinux 0x88883a3e __elv_add_request +EXPORT_SYMBOL vmlinux 0x888c1bec tty_set_operations +EXPORT_SYMBOL vmlinux 0x889b7393 bh_uptodate_or_lock +EXPORT_SYMBOL vmlinux 0x88c0ea87 clear_inode +EXPORT_SYMBOL vmlinux 0x88ddab48 gnet_stats_copy_queue +EXPORT_SYMBOL vmlinux 0x88e8e5f2 xfrm4_rcv +EXPORT_SYMBOL vmlinux 0x88f8eaae skb_copy +EXPORT_SYMBOL vmlinux 0x89006baf xfrm_state_lookup +EXPORT_SYMBOL vmlinux 0x890615c0 scc_release_partition +EXPORT_SYMBOL vmlinux 0x891e32b8 wait_for_completion_interruptible +EXPORT_SYMBOL vmlinux 0x891ec6f1 neigh_event_ns +EXPORT_SYMBOL vmlinux 0x892fb6e1 mapping_tagged +EXPORT_SYMBOL vmlinux 0x89422e8e cont_write_begin +EXPORT_SYMBOL vmlinux 0x895174d0 kmem_cache_size +EXPORT_SYMBOL vmlinux 0x8960223c do_munmap +EXPORT_SYMBOL vmlinux 0x896b96df tcf_hash_lookup +EXPORT_SYMBOL vmlinux 0x897473df mktime +EXPORT_SYMBOL vmlinux 0x89a890fa do_scc_decrypt_region +EXPORT_SYMBOL vmlinux 0x89b34e24 fsl_shw_hmac_precompute +EXPORT_SYMBOL vmlinux 0x89d5538d fb_pad_aligned_buffer +EXPORT_SYMBOL vmlinux 0x89d5cc6e read_cache_page_async +EXPORT_SYMBOL vmlinux 0x89d66811 build_ehash_secret +EXPORT_SYMBOL vmlinux 0x89e10e3f scsi_get_host_dev +EXPORT_SYMBOL vmlinux 0x8a04a4d4 tc_classify_compat +EXPORT_SYMBOL vmlinux 0x8a1203a9 kref_get +EXPORT_SYMBOL vmlinux 0x8a14f85c alloc_tty_driver +EXPORT_SYMBOL vmlinux 0x8a253fb1 sah_get_results +EXPORT_SYMBOL vmlinux 0x8a29d5f3 nf_hook_slow +EXPORT_SYMBOL vmlinux 0x8a3977eb blk_plug_device +EXPORT_SYMBOL vmlinux 0x8a4fa83b __aeabi_llsr +EXPORT_SYMBOL vmlinux 0x8a5bda92 netlink_broadcast +EXPORT_SYMBOL vmlinux 0x8a7d1c31 high_memory +EXPORT_SYMBOL vmlinux 0x8a99a016 mempool_free_slab +EXPORT_SYMBOL vmlinux 0x8aa028ab generic_read_dir +EXPORT_SYMBOL vmlinux 0x8aa76bff snd_pcm_hw_param_first +EXPORT_SYMBOL vmlinux 0x8b01eb05 input_register_handler +EXPORT_SYMBOL vmlinux 0x8b2b1d44 scsi_is_sdev_device +EXPORT_SYMBOL vmlinux 0x8b618d08 overflowuid +EXPORT_SYMBOL vmlinux 0x8b9a4149 ida_destroy +EXPORT_SYMBOL vmlinux 0x8b9c9d14 ethtool_op_get_sg +EXPORT_SYMBOL vmlinux 0x8ba7bc49 call_usermodehelper_freeinfo +EXPORT_SYMBOL vmlinux 0x8bbbda53 eth_header +EXPORT_SYMBOL vmlinux 0x8bbfa2b9 flow_cache_lookup +EXPORT_SYMBOL vmlinux 0x8bd3bb42 user_path_at +EXPORT_SYMBOL vmlinux 0x8c7bc348 ida_remove +EXPORT_SYMBOL vmlinux 0x8c8374ed d_alloc_name +EXPORT_SYMBOL vmlinux 0x8c84069c restore_time_delta +EXPORT_SYMBOL vmlinux 0x8c9b917d tty_throttle +EXPORT_SYMBOL vmlinux 0x8cb27269 register_qdisc +EXPORT_SYMBOL vmlinux 0x8cdb8cbe filemap_fault +EXPORT_SYMBOL vmlinux 0x8ce11233 sdma_free +EXPORT_SYMBOL vmlinux 0x8d22932e neigh_sysctl_register +EXPORT_SYMBOL vmlinux 0x8d3894f2 _ctype +EXPORT_SYMBOL vmlinux 0x8d4794a0 clear_bdi_congested +EXPORT_SYMBOL vmlinux 0x8d551bef sysctl_tcp_rmem +EXPORT_SYMBOL vmlinux 0x8d5642fc wait_for_completion_interruptible_timeout +EXPORT_SYMBOL vmlinux 0x8d5bfe01 fsl_shw_register_user +EXPORT_SYMBOL vmlinux 0x8d5c44f4 kobject_init +EXPORT_SYMBOL vmlinux 0x8d6f81b4 __div64_32 +EXPORT_SYMBOL vmlinux 0x8dc1d2ef elevator_exit +EXPORT_SYMBOL vmlinux 0x8dcb5c27 idr_remove +EXPORT_SYMBOL vmlinux 0x8de07c1f skb_clone +EXPORT_SYMBOL vmlinux 0x8df3789f snd_oss_info_register +EXPORT_SYMBOL vmlinux 0x8e05d84c ipu_disp_set_window_pos +EXPORT_SYMBOL vmlinux 0x8e0b7743 ipv6_ext_hdr +EXPORT_SYMBOL vmlinux 0x8e102496 scsi_set_medium_removal +EXPORT_SYMBOL vmlinux 0x8e3c9cc3 vprintk +EXPORT_SYMBOL vmlinux 0x8e434942 scsi_block_requests +EXPORT_SYMBOL vmlinux 0x8e5f5b29 snd_pcm_lib_malloc_pages +EXPORT_SYMBOL vmlinux 0x8e605f97 skb_free_datagram +EXPORT_SYMBOL vmlinux 0x8e6a3209 skb_copy_bits +EXPORT_SYMBOL vmlinux 0x8e737c29 clk_enable +EXPORT_SYMBOL vmlinux 0x8e763ae1 send_remote_softirq +EXPORT_SYMBOL vmlinux 0x8e866998 sock_alloc_send_skb +EXPORT_SYMBOL vmlinux 0x8ecd97db sk_reset_timer +EXPORT_SYMBOL vmlinux 0x8ef67c70 __breadahead +EXPORT_SYMBOL vmlinux 0x8f07d8ca __wait_on_bit +EXPORT_SYMBOL vmlinux 0x8f0bdbdf neigh_changeaddr +EXPORT_SYMBOL vmlinux 0x8f111c44 inet_stream_connect +EXPORT_SYMBOL vmlinux 0x8f595b11 snd_major +EXPORT_SYMBOL vmlinux 0x8f6b3d01 sah_insert_skha_modulus +EXPORT_SYMBOL vmlinux 0x8f6b7950 set_irq_data +EXPORT_SYMBOL vmlinux 0x8f7b17d7 close_bdev_exclusive +EXPORT_SYMBOL vmlinux 0x8f96f75b dst_destroy +EXPORT_SYMBOL vmlinux 0x8f9b86b2 kfifo_alloc +EXPORT_SYMBOL vmlinux 0x8fb66fe2 blk_queue_free_tags +EXPORT_SYMBOL vmlinux 0x8fbf3e3e dev_mc_unsync +EXPORT_SYMBOL vmlinux 0x8ffdb3b8 crc16 +EXPORT_SYMBOL vmlinux 0x90035333 secure_tcpv6_sequence_number +EXPORT_SYMBOL vmlinux 0x900b5c84 inet_register_protosw +EXPORT_SYMBOL vmlinux 0x902eaaa3 mmc_release_host +EXPORT_SYMBOL vmlinux 0x904091df fsl_shw_smalloc +EXPORT_SYMBOL vmlinux 0x904279f9 dst_alloc +EXPORT_SYMBOL vmlinux 0x90635ea0 flush_old_exec +EXPORT_SYMBOL vmlinux 0x906ad67c request_key_async_with_auxdata +EXPORT_SYMBOL vmlinux 0x907665f6 netdev_features_change +EXPORT_SYMBOL vmlinux 0x9080020c unlock_rename +EXPORT_SYMBOL vmlinux 0x90c390d7 sysctl_data +EXPORT_SYMBOL vmlinux 0x90dc6bed n_tty_ioctl_helper +EXPORT_SYMBOL vmlinux 0x90e93cb4 wait_for_key_construction +EXPORT_SYMBOL vmlinux 0x911f74d9 __secpath_destroy +EXPORT_SYMBOL vmlinux 0x913451d7 inet_sk_rebuild_header +EXPORT_SYMBOL vmlinux 0x91481982 __ratelimit +EXPORT_SYMBOL vmlinux 0x9153b984 gpio_keypad_active +EXPORT_SYMBOL vmlinux 0x91820805 i2c_put_adapter +EXPORT_SYMBOL vmlinux 0x919029aa __readwrite_bug +EXPORT_SYMBOL vmlinux 0x9191199b tcp_setsockopt +EXPORT_SYMBOL vmlinux 0x91f5a161 blk_run_queue +EXPORT_SYMBOL vmlinux 0x923e0685 elv_dispatch_sort +EXPORT_SYMBOL vmlinux 0x926401f2 sg_copy_to_buffer +EXPORT_SYMBOL vmlinux 0x926b7d94 blk_queue_bounce_limit +EXPORT_SYMBOL vmlinux 0x92945b42 find_task_by_pid_ns +EXPORT_SYMBOL vmlinux 0x92d65920 blk_queue_update_dma_pad +EXPORT_SYMBOL vmlinux 0x9302966b journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x9305f8e6 cpufreq_get +EXPORT_SYMBOL vmlinux 0x935438f4 invalidate_inode_buffers +EXPORT_SYMBOL vmlinux 0x936aa9d1 tcp_rcv_established +EXPORT_SYMBOL vmlinux 0x9381e4aa bio_copy_kern +EXPORT_SYMBOL vmlinux 0x9387bcba scsi_unblock_requests +EXPORT_SYMBOL vmlinux 0x93a6e0b2 io_schedule +EXPORT_SYMBOL vmlinux 0x93c69acf param_set_byte +EXPORT_SYMBOL vmlinux 0x93f6b1b8 spba_take_ownership +EXPORT_SYMBOL vmlinux 0x93fca811 __get_free_pages +EXPORT_SYMBOL vmlinux 0x942f340c snd_power_wait +EXPORT_SYMBOL vmlinux 0x9481947d gpio_sdhc_active +EXPORT_SYMBOL vmlinux 0x94847b23 nf_ct_destroy +EXPORT_SYMBOL vmlinux 0x94893197 scc_monitor_security_failure +EXPORT_SYMBOL vmlinux 0x94961283 vunmap +EXPORT_SYMBOL vmlinux 0x94990adc kernel_sock_ioctl +EXPORT_SYMBOL vmlinux 0x94a171ea dentry_open +EXPORT_SYMBOL vmlinux 0x94f72ffe mark_buffer_dirty +EXPORT_SYMBOL vmlinux 0x9501d078 __wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0x95054627 journal_ack_err +EXPORT_SYMBOL vmlinux 0x950996c0 d_delete +EXPORT_SYMBOL vmlinux 0x951d18be bdi_init +EXPORT_SYMBOL vmlinux 0x952d5f21 _snd_pcm_hw_params_any +EXPORT_SYMBOL vmlinux 0x95335be7 fsl_shw_release_key +EXPORT_SYMBOL vmlinux 0x95408777 kobject_del +EXPORT_SYMBOL vmlinux 0x954488a4 syncookie_secret +EXPORT_SYMBOL vmlinux 0x9545bd70 ip_route_me_harder +EXPORT_SYMBOL vmlinux 0x95477fc5 generic_readlink +EXPORT_SYMBOL vmlinux 0x9549c458 blk_get_request +EXPORT_SYMBOL vmlinux 0x954cbb26 vsprintf +EXPORT_SYMBOL vmlinux 0x955e839e __xfrm_policy_check +EXPORT_SYMBOL vmlinux 0x9574e84d load_nls +EXPORT_SYMBOL vmlinux 0x958738a4 snd_ctl_remove +EXPORT_SYMBOL vmlinux 0x95cd62ba dev_queue_xmit +EXPORT_SYMBOL vmlinux 0x95dbe078 __get_user_2 +EXPORT_SYMBOL vmlinux 0x95ff73e0 find_task_by_pid_type_ns +EXPORT_SYMBOL vmlinux 0x963f4a12 gpio_set_data +EXPORT_SYMBOL vmlinux 0x96453248 neigh_connected_output +EXPORT_SYMBOL vmlinux 0x96685577 __find_get_block +EXPORT_SYMBOL vmlinux 0x9668f3d0 fb_show_logo +EXPORT_SYMBOL vmlinux 0x968117b1 register_con_driver +EXPORT_SYMBOL vmlinux 0x96898769 sysfs_format_mac +EXPORT_SYMBOL vmlinux 0x96cd2b04 scsi_sense_key_string +EXPORT_SYMBOL vmlinux 0x96df5482 walk_stackframe +EXPORT_SYMBOL vmlinux 0x96f03286 scc_write_register +EXPORT_SYMBOL vmlinux 0x971c6503 snd_ctl_add +EXPORT_SYMBOL vmlinux 0x97255bdf strlen +EXPORT_SYMBOL vmlinux 0x97314f71 backlight_device_register +EXPORT_SYMBOL vmlinux 0x973ec66e tcf_generic_walker +EXPORT_SYMBOL vmlinux 0x974957dd simple_readpage +EXPORT_SYMBOL vmlinux 0x9754ec10 radix_tree_preload +EXPORT_SYMBOL vmlinux 0x976d5881 bio_pair_release +EXPORT_SYMBOL vmlinux 0x977b9262 scsi_host_alloc +EXPORT_SYMBOL vmlinux 0x978eb69a vmtruncate +EXPORT_SYMBOL vmlinux 0x97ab7471 input_open_device +EXPORT_SYMBOL vmlinux 0x97dc0546 follow_up +EXPORT_SYMBOL vmlinux 0x981026f6 km_report +EXPORT_SYMBOL vmlinux 0x9810a53d get_unifi_plat_data +EXPORT_SYMBOL vmlinux 0x9829f079 unbind_con_driver +EXPORT_SYMBOL vmlinux 0x983dc10d dcache_dir_close +EXPORT_SYMBOL vmlinux 0x98593ccd devm_ioremap_nocache +EXPORT_SYMBOL vmlinux 0x985eedb7 fsl_shw_release_keystore +EXPORT_SYMBOL vmlinux 0x986e6135 fb_pad_unaligned_buffer +EXPORT_SYMBOL vmlinux 0x98a4a668 unregister_nls +EXPORT_SYMBOL vmlinux 0x98c16212 i2c_smbus_read_byte_data +EXPORT_SYMBOL vmlinux 0x98cddaee mxc_snoop_get_status +EXPORT_SYMBOL vmlinux 0x98ddbcdb fb_set_var +EXPORT_SYMBOL vmlinux 0x9901c6f0 wait_on_sync_kiocb +EXPORT_SYMBOL vmlinux 0x9907e703 inet_ioctl +EXPORT_SYMBOL vmlinux 0x993b4d4f tcp_read_sock +EXPORT_SYMBOL vmlinux 0x999c3148 __raw_readsb +EXPORT_SYMBOL vmlinux 0x999e8297 vfree +EXPORT_SYMBOL vmlinux 0x99aadb21 param_get_ulong +EXPORT_SYMBOL vmlinux 0x99b40685 i2c_register_driver +EXPORT_SYMBOL vmlinux 0x99bb8806 memmove +EXPORT_SYMBOL vmlinux 0x99bfbe39 get_unused_fd +EXPORT_SYMBOL vmlinux 0x99c3c0b0 vfs_fstat +EXPORT_SYMBOL vmlinux 0x99c95fa5 unregister_sound_special +EXPORT_SYMBOL vmlinux 0x99cdc86b sysctl_tcp_reordering +EXPORT_SYMBOL vmlinux 0x99ea12ce panic_blink +EXPORT_SYMBOL vmlinux 0x99f07292 __nla_put +EXPORT_SYMBOL vmlinux 0x99fe1b43 ipu_update_channel_buffer +EXPORT_SYMBOL vmlinux 0x9a108cd3 tcf_hash_release +EXPORT_SYMBOL vmlinux 0x9a1dfd65 strpbrk +EXPORT_SYMBOL vmlinux 0x9a2e7f20 nf_unregister_queue_handler +EXPORT_SYMBOL vmlinux 0x9a458f51 register_nls +EXPORT_SYMBOL vmlinux 0x9a584b52 sah_Descriptor_Chain_Execute +EXPORT_SYMBOL vmlinux 0x9a94ea67 tcp_child_process +EXPORT_SYMBOL vmlinux 0x9aa2a308 compute_creds +EXPORT_SYMBOL vmlinux 0x9aa41042 mb_cache_entry_find_first +EXPORT_SYMBOL vmlinux 0x9ab53fc5 tcf_exts_destroy +EXPORT_SYMBOL vmlinux 0x9b388444 get_zeroed_page +EXPORT_SYMBOL vmlinux 0x9b49dde8 devm_ioremap +EXPORT_SYMBOL vmlinux 0x9b4bdaff security_d_instantiate +EXPORT_SYMBOL vmlinux 0x9b680569 tcp_recvmsg +EXPORT_SYMBOL vmlinux 0x9ba7089d argv_split +EXPORT_SYMBOL vmlinux 0x9bce482f __release_region +EXPORT_SYMBOL vmlinux 0x9bd35664 send_sig_info +EXPORT_SYMBOL vmlinux 0x9bd38f02 gpio_pmic_active +EXPORT_SYMBOL vmlinux 0x9be8eba4 pmic_adc_get_touch_mode +EXPORT_SYMBOL vmlinux 0x9bff71ac set_binfmt +EXPORT_SYMBOL vmlinux 0x9c012508 fb_parse_edid +EXPORT_SYMBOL vmlinux 0x9c10162e mc13892_bklit_set_dutycycle +EXPORT_SYMBOL vmlinux 0x9c1a34b7 i2c_del_adapter +EXPORT_SYMBOL vmlinux 0x9c2571f4 __down_read +EXPORT_SYMBOL vmlinux 0x9c257477 mpage_readpage +EXPORT_SYMBOL vmlinux 0x9c5a3907 may_umount +EXPORT_SYMBOL vmlinux 0x9c7077bd enable_hlt +EXPORT_SYMBOL vmlinux 0x9c876139 kernel_sock_shutdown +EXPORT_SYMBOL vmlinux 0x9c8d0123 d_validate +EXPORT_SYMBOL vmlinux 0x9c8ed8a6 scsi_prep_return +EXPORT_SYMBOL vmlinux 0x9c93a85a blk_dump_rq_flags +EXPORT_SYMBOL vmlinux 0x9c9ef3d8 init_net +EXPORT_SYMBOL vmlinux 0x9ca63438 __getblk +EXPORT_SYMBOL vmlinux 0x9cb0691b bio_endio +EXPORT_SYMBOL vmlinux 0x9cb96e92 qdisc_put_rtab +EXPORT_SYMBOL vmlinux 0x9cbd8b64 generic_getxattr +EXPORT_SYMBOL vmlinux 0x9cd2139c ip_mc_join_group +EXPORT_SYMBOL vmlinux 0x9ceb163c memcpy_toiovec +EXPORT_SYMBOL vmlinux 0x9cf460b4 input_release_device +EXPORT_SYMBOL vmlinux 0x9cfd56c5 scsi_print_status +EXPORT_SYMBOL vmlinux 0x9d2bd5e2 blk_queue_dma_alignment +EXPORT_SYMBOL vmlinux 0x9d5eb87e tcp_sendpage +EXPORT_SYMBOL vmlinux 0x9d64e8f8 dma_map_sg +EXPORT_SYMBOL vmlinux 0x9d669763 memcpy +EXPORT_SYMBOL vmlinux 0x9d9ee70e invalidate_mapping_pages +EXPORT_SYMBOL vmlinux 0x9da7ace7 dmam_pool_create +EXPORT_SYMBOL vmlinux 0x9dad79f4 fifo_create_dflt +EXPORT_SYMBOL vmlinux 0x9df1c97a get_fs_type +EXPORT_SYMBOL vmlinux 0x9dfe9ab4 bh_submit_read +EXPORT_SYMBOL vmlinux 0x9e109faf i2c_smbus_write_word_data +EXPORT_SYMBOL vmlinux 0x9e120414 ida_get_new_above +EXPORT_SYMBOL vmlinux 0x9e1fbc9c snd_ctl_find_numid +EXPORT_SYMBOL vmlinux 0x9e5091a8 scsi_reset_provider +EXPORT_SYMBOL vmlinux 0x9e61fef1 init_mm +EXPORT_SYMBOL vmlinux 0x9e7c5610 scc_encrypt_region +EXPORT_SYMBOL vmlinux 0x9e7d6bd0 __udelay +EXPORT_SYMBOL vmlinux 0x9e8a9062 netlink_unicast +EXPORT_SYMBOL vmlinux 0x9e8cac3c blk_rq_append_bio +EXPORT_SYMBOL vmlinux 0x9ed4973e names_cachep +EXPORT_SYMBOL vmlinux 0x9ed685ee iov_iter_advance +EXPORT_SYMBOL vmlinux 0x9eecde16 do_brk +EXPORT_SYMBOL vmlinux 0x9ef2664f per_cpu__softnet_data +EXPORT_SYMBOL vmlinux 0x9ef43f9e generic_osync_inode +EXPORT_SYMBOL vmlinux 0x9ef749e2 unregister_chrdev +EXPORT_SYMBOL vmlinux 0x9f100139 jiffies_to_clock_t +EXPORT_SYMBOL vmlinux 0x9f2bdaac __bitmap_or +EXPORT_SYMBOL vmlinux 0x9f36f192 put_filp +EXPORT_SYMBOL vmlinux 0x9f50a47e tcp_prot +EXPORT_SYMBOL vmlinux 0x9f587078 register_filesystem +EXPORT_SYMBOL vmlinux 0x9f68f0b1 journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0x9f956994 ipu_get_irq_status +EXPORT_SYMBOL vmlinux 0x9f984513 strrchr +EXPORT_SYMBOL vmlinux 0x9fb3dd30 memcpy_fromiovec +EXPORT_SYMBOL vmlinux 0x9fd6cf48 unregister_key_type +EXPORT_SYMBOL vmlinux 0xa0160818 skb_queue_purge +EXPORT_SYMBOL vmlinux 0xa03523d5 security_unix_stream_connect +EXPORT_SYMBOL vmlinux 0xa04a01bd qdisc_class_hash_insert +EXPORT_SYMBOL vmlinux 0xa054bf94 simple_sync_file +EXPORT_SYMBOL vmlinux 0xa05c03df mempool_kmalloc +EXPORT_SYMBOL vmlinux 0xa07a8d22 sleep_on +EXPORT_SYMBOL vmlinux 0xa07ac24b irq_stat +EXPORT_SYMBOL vmlinux 0xa087772d neigh_table_init_no_netlink +EXPORT_SYMBOL vmlinux 0xa09abd95 __dev_get_by_name +EXPORT_SYMBOL vmlinux 0xa0b04675 vmalloc_32 +EXPORT_SYMBOL vmlinux 0xa0bceac0 generic_write_end +EXPORT_SYMBOL vmlinux 0xa0ceef51 out_of_line_wait_on_bit +EXPORT_SYMBOL vmlinux 0xa0f69f28 tty_write_room +EXPORT_SYMBOL vmlinux 0xa0fbac79 wake_up_bit +EXPORT_SYMBOL vmlinux 0xa0fef47b nand_calculate_ecc +EXPORT_SYMBOL vmlinux 0xa108ddaa tcf_unregister_action +EXPORT_SYMBOL vmlinux 0xa108eb4d sysctl_optmem_max +EXPORT_SYMBOL vmlinux 0xa10dcc13 getrawmonotonic +EXPORT_SYMBOL vmlinux 0xa118603c dma_unmap_sg +EXPORT_SYMBOL vmlinux 0xa120d33c tty_unregister_ldisc +EXPORT_SYMBOL vmlinux 0xa13798f8 printk_ratelimit +EXPORT_SYMBOL vmlinux 0xa13bd439 block_is_partially_uptodate +EXPORT_SYMBOL vmlinux 0xa15e1bab udp_prot +EXPORT_SYMBOL vmlinux 0xa168abe7 tcp_proc_register +EXPORT_SYMBOL vmlinux 0xa188ecea bio_integrity_add_page +EXPORT_SYMBOL vmlinux 0xa192c3ed scsi_dma_unmap +EXPORT_SYMBOL vmlinux 0xa1b759ce fb_add_videomode +EXPORT_SYMBOL vmlinux 0xa1c76e0a _cond_resched +EXPORT_SYMBOL vmlinux 0xa1d14970 udp_lib_getsockopt +EXPORT_SYMBOL vmlinux 0xa1e2a3c4 blk_queue_ordered +EXPORT_SYMBOL vmlinux 0xa20ce1b8 net_msg_warn +EXPORT_SYMBOL vmlinux 0xa218bf61 complete +EXPORT_SYMBOL vmlinux 0xa22d6da0 pskb_copy +EXPORT_SYMBOL vmlinux 0xa25ad4ef dmam_release_declared_memory +EXPORT_SYMBOL vmlinux 0xa25f62a7 starget_for_each_device +EXPORT_SYMBOL vmlinux 0xa28ff2ca __bread +EXPORT_SYMBOL vmlinux 0xa29b1708 tcp_memory_allocated +EXPORT_SYMBOL vmlinux 0xa2a5fd77 inet_ehash_secret +EXPORT_SYMBOL vmlinux 0xa2ac3da4 inet_frags_fini +EXPORT_SYMBOL vmlinux 0xa2db955a is_pmic_adc_ready +EXPORT_SYMBOL vmlinux 0xa2ecf3d0 blk_verify_command +EXPORT_SYMBOL vmlinux 0xa329f07e register_shrinker +EXPORT_SYMBOL vmlinux 0xa336feb7 nand_manuf_ids +EXPORT_SYMBOL vmlinux 0xa3459e2c neigh_sysctl_unregister +EXPORT_SYMBOL vmlinux 0xa34f1ef5 crc32_le +EXPORT_SYMBOL vmlinux 0xa35de80f ipv4_config +EXPORT_SYMBOL vmlinux 0xa364c3ce kmem_cache_destroy +EXPORT_SYMBOL vmlinux 0xa37ed7af mb_cache_create +EXPORT_SYMBOL vmlinux 0xa3a4ed03 cond_resched_lock +EXPORT_SYMBOL vmlinux 0xa3f3035d inode_sub_bytes +EXPORT_SYMBOL vmlinux 0xa41d2b90 __scm_send +EXPORT_SYMBOL vmlinux 0xa432c01a scsi_add_host +EXPORT_SYMBOL vmlinux 0xa4502a43 tcp_poll +EXPORT_SYMBOL vmlinux 0xa4602783 blkdev_get +EXPORT_SYMBOL vmlinux 0xa47d967e gpio_usbh2_setback_stp +EXPORT_SYMBOL vmlinux 0xa5423cc4 param_get_int +EXPORT_SYMBOL vmlinux 0xa57c6485 __scsi_put_command +EXPORT_SYMBOL vmlinux 0xa5808bbf tasklet_init +EXPORT_SYMBOL vmlinux 0xa58b6804 nla_parse +EXPORT_SYMBOL vmlinux 0xa5a05d3e qdisc_tree_decrease_qlen +EXPORT_SYMBOL vmlinux 0xa5a87983 dev_get_by_index +EXPORT_SYMBOL vmlinux 0xa5cda817 ipu_csi_enable_mclk +EXPORT_SYMBOL vmlinux 0xa5cef8ad release_resource +EXPORT_SYMBOL vmlinux 0xa5d49c14 pagecache_write_end +EXPORT_SYMBOL vmlinux 0xa5fb7f3a filemap_write_and_wait +EXPORT_SYMBOL vmlinux 0xa6087201 scsi_setup_blk_pc_cmnd +EXPORT_SYMBOL vmlinux 0xa61aa028 snd_pcm_format_unsigned +EXPORT_SYMBOL vmlinux 0xa61c1015 unlock_buffer +EXPORT_SYMBOL vmlinux 0xa65c4537 ip_nat_decode_session +EXPORT_SYMBOL vmlinux 0xa667da06 mxc_dma_set_callback +EXPORT_SYMBOL vmlinux 0xa6747b91 block_write_full_page +EXPORT_SYMBOL vmlinux 0xa68124fa hweight8 +EXPORT_SYMBOL vmlinux 0xa681fe88 generate_random_uuid +EXPORT_SYMBOL vmlinux 0xa689b9fa udp_sendmsg +EXPORT_SYMBOL vmlinux 0xa6949f22 ethtool_op_get_flags +EXPORT_SYMBOL vmlinux 0xa6aaa9e9 user_revoke +EXPORT_SYMBOL vmlinux 0xa6c65877 snd_pcm_hw_constraint_list +EXPORT_SYMBOL vmlinux 0xa6dcc773 rb_insert_color +EXPORT_SYMBOL vmlinux 0xa6e9345f bio_add_page +EXPORT_SYMBOL vmlinux 0xa7046670 netdev_state_change +EXPORT_SYMBOL vmlinux 0xa72bc035 ip_fragment +EXPORT_SYMBOL vmlinux 0xa7502f48 jiffies_to_timeval +EXPORT_SYMBOL vmlinux 0xa76aa13c nf_ct_attach +EXPORT_SYMBOL vmlinux 0xa7800479 snd_pcm_suspend_all +EXPORT_SYMBOL vmlinux 0xa7c35c6b getnstimeofday +EXPORT_SYMBOL vmlinux 0xa805f9c0 snd_pcm_mmap_data +EXPORT_SYMBOL vmlinux 0xa81bc721 inet_csk_accept +EXPORT_SYMBOL vmlinux 0xa8590023 uart_write_wakeup +EXPORT_SYMBOL vmlinux 0xa87aa3af journal_init_dev +EXPORT_SYMBOL vmlinux 0xa889cbeb gpio_usbotg_hs_inactive +EXPORT_SYMBOL vmlinux 0xa8959f2d bio_integrity_split +EXPORT_SYMBOL vmlinux 0xa8c291e7 mb_cache_entry_alloc +EXPORT_SYMBOL vmlinux 0xa8d15ebe request_key +EXPORT_SYMBOL vmlinux 0xa8fef7bb security_unix_may_send +EXPORT_SYMBOL vmlinux 0xa925899a param_set_bool +EXPORT_SYMBOL vmlinux 0xa96a7d2d brioctl_set +EXPORT_SYMBOL vmlinux 0xa9741390 proc_doulongvec_minmax +EXPORT_SYMBOL vmlinux 0xa97b32ee inet_accept +EXPORT_SYMBOL vmlinux 0xa98b62e9 uart_get_divisor +EXPORT_SYMBOL vmlinux 0xa9a5ea23 mxc_sdma_read_ipcv2 +EXPORT_SYMBOL vmlinux 0xa9c14dce uart_unregister_driver +EXPORT_SYMBOL vmlinux 0xa9ebc221 d_instantiate_unique +EXPORT_SYMBOL vmlinux 0xa9f1ed23 bit_waitqueue +EXPORT_SYMBOL vmlinux 0xa9f5dc15 inet_frag_destroy +EXPORT_SYMBOL vmlinux 0xaa21f366 xfrm_policy_insert +EXPORT_SYMBOL vmlinux 0xaa35da1c ___pskb_trim +EXPORT_SYMBOL vmlinux 0xaa4040e7 ipv4_specific +EXPORT_SYMBOL vmlinux 0xaa527612 __kfifo_put +EXPORT_SYMBOL vmlinux 0xaa648e80 iw_handler_set_spy +EXPORT_SYMBOL vmlinux 0xaa95b16b mxc_request_dma +EXPORT_SYMBOL vmlinux 0xaab7f708 kill_litter_super +EXPORT_SYMBOL vmlinux 0xaadf8182 snd_info_free_entry +EXPORT_SYMBOL vmlinux 0xaafdc258 strcasecmp +EXPORT_SYMBOL vmlinux 0xab471003 param_array_set +EXPORT_SYMBOL vmlinux 0xab53b0a8 mempool_alloc +EXPORT_SYMBOL vmlinux 0xab5c2cf8 scsi_target_resume +EXPORT_SYMBOL vmlinux 0xab600421 probe_irq_off +EXPORT_SYMBOL vmlinux 0xab613d4a iov_iter_copy_from_user +EXPORT_SYMBOL vmlinux 0xab64527d mutex_lock_interruptible +EXPORT_SYMBOL vmlinux 0xab680c96 __down_read_trylock +EXPORT_SYMBOL vmlinux 0xab7778a7 i2c_master_recv +EXPORT_SYMBOL vmlinux 0xab8b111b snd_timer_close +EXPORT_SYMBOL vmlinux 0xab967d0a ip_route_output_key +EXPORT_SYMBOL vmlinux 0xabad83d7 udp_hash_lock +EXPORT_SYMBOL vmlinux 0xabb6d55f submit_bh +EXPORT_SYMBOL vmlinux 0xabbd558e pmic_write_reg +EXPORT_SYMBOL vmlinux 0xabd0c91c rtc_time_to_tm +EXPORT_SYMBOL vmlinux 0xabe15e2e km_query +EXPORT_SYMBOL vmlinux 0xac0313bf fsl_platform_set_vbus_power +EXPORT_SYMBOL vmlinux 0xac296646 clk_put +EXPORT_SYMBOL vmlinux 0xac3b3cee __bitmap_and +EXPORT_SYMBOL vmlinux 0xac3fa684 inode_init_once +EXPORT_SYMBOL vmlinux 0xac54fc9f mempool_destroy +EXPORT_SYMBOL vmlinux 0xac56bf35 i2c_smbus_write_block_data +EXPORT_SYMBOL vmlinux 0xac5be5e8 blkdev_put +EXPORT_SYMBOL vmlinux 0xac5f113d cpu_all_bits +EXPORT_SYMBOL vmlinux 0xac6a38e6 bio_map_kern +EXPORT_SYMBOL vmlinux 0xac7d4072 snd_info_register +EXPORT_SYMBOL vmlinux 0xac7f5587 snd_card_new +EXPORT_SYMBOL vmlinux 0xac8a9f68 scsi_print_result +EXPORT_SYMBOL vmlinux 0xac8c216d blk_cleanup_queue +EXPORT_SYMBOL vmlinux 0xacac755f skb_copy_datagram_iovec +EXPORT_SYMBOL vmlinux 0xacadac7e d_add_ci +EXPORT_SYMBOL vmlinux 0xaccabc6a in4_pton +EXPORT_SYMBOL vmlinux 0xacf13be8 fsl_shw_get_random +EXPORT_SYMBOL vmlinux 0xacf4d843 match_strdup +EXPORT_SYMBOL vmlinux 0xad025af4 zero_fill_bio +EXPORT_SYMBOL vmlinux 0xad0413d4 match_hex +EXPORT_SYMBOL vmlinux 0xad0a374d dma_alloc_coherent +EXPORT_SYMBOL vmlinux 0xad275a63 tcf_exts_change +EXPORT_SYMBOL vmlinux 0xad28090a dev_add_pack +EXPORT_SYMBOL vmlinux 0xad4328c6 vfs_mknod +EXPORT_SYMBOL vmlinux 0xad845960 tcp_hashinfo +EXPORT_SYMBOL vmlinux 0xadaa2657 cpufreq_register_notifier +EXPORT_SYMBOL vmlinux 0xadb792c2 prepare_to_wait_exclusive +EXPORT_SYMBOL vmlinux 0xade88e76 snd_malloc_pages +EXPORT_SYMBOL vmlinux 0xae378882 generic_permission +EXPORT_SYMBOL vmlinux 0xae4d60a8 i2c_smbus_process_call +EXPORT_SYMBOL vmlinux 0xae61ca6a kthread_create +EXPORT_SYMBOL vmlinux 0xae7fcfeb generic_file_direct_write +EXPORT_SYMBOL vmlinux 0xae879422 bd_set_size +EXPORT_SYMBOL vmlinux 0xaec655c7 alloc_pages_exact +EXPORT_SYMBOL vmlinux 0xaed013b9 posix_acl_valid +EXPORT_SYMBOL vmlinux 0xaeedf127 iunique +EXPORT_SYMBOL vmlinux 0xaeff1fde call_usermodehelper_exec +EXPORT_SYMBOL vmlinux 0xaf1973c3 dev_kfree_skb_irq +EXPORT_SYMBOL vmlinux 0xaf35916a xfrm_register_mode +EXPORT_SYMBOL vmlinux 0xaf4c4207 scsi_block_when_processing_errors +EXPORT_SYMBOL vmlinux 0xaf50e76d elf_set_personality +EXPORT_SYMBOL vmlinux 0xaf8aa518 system_rev +EXPORT_SYMBOL vmlinux 0xafc225c1 flock_lock_file_wait +EXPORT_SYMBOL vmlinux 0xafc453dd is_bad_inode +EXPORT_SYMBOL vmlinux 0xafefd3e5 sysctl_string +EXPORT_SYMBOL vmlinux 0xb000aae8 tcp_v4_syn_recv_sock +EXPORT_SYMBOL vmlinux 0xb01e5153 d_alloc +EXPORT_SYMBOL vmlinux 0xb0236d87 km_policy_notify +EXPORT_SYMBOL vmlinux 0xb02d8306 sock_no_listen +EXPORT_SYMBOL vmlinux 0xb0341fd2 sdma_phys_to_virt +EXPORT_SYMBOL vmlinux 0xb045e4ee gpio_spdif_inactive +EXPORT_SYMBOL vmlinux 0xb0461659 snd_pcm_kernel_ioctl +EXPORT_SYMBOL vmlinux 0xb06aed27 scsi_execute_req +EXPORT_SYMBOL vmlinux 0xb082ea5c unregister_netdev +EXPORT_SYMBOL vmlinux 0xb0b847ac __bitmap_full +EXPORT_SYMBOL vmlinux 0xb0c8ff49 truncate_inode_pages_range +EXPORT_SYMBOL vmlinux 0xb0e10781 get_option +EXPORT_SYMBOL vmlinux 0xb121390a probe_irq_on +EXPORT_SYMBOL vmlinux 0xb1489175 inet_frag_kill +EXPORT_SYMBOL vmlinux 0xb14ae0e3 bio_integrity_alloc +EXPORT_SYMBOL vmlinux 0xb1693250 skb_copy_and_csum_dev +EXPORT_SYMBOL vmlinux 0xb19760c3 bitmap_onto +EXPORT_SYMBOL vmlinux 0xb1a1400e tcp_simple_retransmit +EXPORT_SYMBOL vmlinux 0xb1aaf0ba tty_driver_kref_put +EXPORT_SYMBOL vmlinux 0xb1c3a01a oops_in_progress +EXPORT_SYMBOL vmlinux 0xb211400a vfs_write +EXPORT_SYMBOL vmlinux 0xb213fe8b snd_info_get_str +EXPORT_SYMBOL vmlinux 0xb22fe6a3 netdev_increment_features +EXPORT_SYMBOL vmlinux 0xb23bb1d1 tcp_sendmsg +EXPORT_SYMBOL vmlinux 0xb2668bcd seq_puts +EXPORT_SYMBOL vmlinux 0xb287d9c2 __alloc_skb +EXPORT_SYMBOL vmlinux 0xb2906944 key_payload_reserve +EXPORT_SYMBOL vmlinux 0xb294d733 xfrm_alloc_spi +EXPORT_SYMBOL vmlinux 0xb2a31e66 nf_log_packet +EXPORT_SYMBOL vmlinux 0xb2a50a61 ip_getsockopt +EXPORT_SYMBOL vmlinux 0xb2bf1312 __up_read +EXPORT_SYMBOL vmlinux 0xb2cf4247 find_get_page +EXPORT_SYMBOL vmlinux 0xb2cf636d gpio_request_irq +EXPORT_SYMBOL vmlinux 0xb2cfa014 backlight_device_unregister +EXPORT_SYMBOL vmlinux 0xb2e54f6e netpoll_cleanup +EXPORT_SYMBOL vmlinux 0xb2e5ae4a snd_lookup_minor_data +EXPORT_SYMBOL vmlinux 0xb2e7a7c4 xfrm_unregister_type +EXPORT_SYMBOL vmlinux 0xb3212a2e __netdev_alloc_skb +EXPORT_SYMBOL vmlinux 0xb351109a journal_extend +EXPORT_SYMBOL vmlinux 0xb3567a8a __nla_reserve +EXPORT_SYMBOL vmlinux 0xb376d79d radix_tree_tagged +EXPORT_SYMBOL vmlinux 0xb38fb65c scsi_mode_sense +EXPORT_SYMBOL vmlinux 0xb39a8ac7 journal_errno +EXPORT_SYMBOL vmlinux 0xb3a307c6 si_meminfo +EXPORT_SYMBOL vmlinux 0xb3bbf655 sock_create_lite +EXPORT_SYMBOL vmlinux 0xb3d30aea ethtool_op_set_tso +EXPORT_SYMBOL vmlinux 0xb3f25c4e ip_dev_find +EXPORT_SYMBOL vmlinux 0xb3fe02b1 down_write +EXPORT_SYMBOL vmlinux 0xb4042cbd tcp_shutdown +EXPORT_SYMBOL vmlinux 0xb4159180 bio_integrity_clone +EXPORT_SYMBOL vmlinux 0xb41a617f gpio_i2c_inactive +EXPORT_SYMBOL vmlinux 0xb41edacc __fatal_signal_pending +EXPORT_SYMBOL vmlinux 0xb423dba1 console_blanked +EXPORT_SYMBOL vmlinux 0xb44fc4cd bio_alloc_bioset +EXPORT_SYMBOL vmlinux 0xb46a7481 snd_device_new +EXPORT_SYMBOL vmlinux 0xb494e82a br_fdb_put_hook +EXPORT_SYMBOL vmlinux 0xb4a0e989 init_timer_deferrable +EXPORT_SYMBOL vmlinux 0xb4acc3ec simple_write_begin +EXPORT_SYMBOL vmlinux 0xb4b34497 gnet_stats_copy_app +EXPORT_SYMBOL vmlinux 0xb4bf8965 inetdev_by_index +EXPORT_SYMBOL vmlinux 0xb4c7510e scc_get_configuration +EXPORT_SYMBOL vmlinux 0xb4e5dbb8 kernel_recvmsg +EXPORT_SYMBOL vmlinux 0xb4f45c19 i2c_del_driver +EXPORT_SYMBOL vmlinux 0xb5044271 vsscanf +EXPORT_SYMBOL vmlinux 0xb534763c sg_free_table +EXPORT_SYMBOL vmlinux 0xb54355d3 iget5_locked +EXPORT_SYMBOL vmlinux 0xb54533f7 usecs_to_jiffies +EXPORT_SYMBOL vmlinux 0xb54e537a __nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0xb551236f snd_pcm_hw_constraint_step +EXPORT_SYMBOL vmlinux 0xb57c170a single_release +EXPORT_SYMBOL vmlinux 0xb598bc74 elv_rq_merge_ok +EXPORT_SYMBOL vmlinux 0xb5a459dc unregister_blkdev +EXPORT_SYMBOL vmlinux 0xb5b3c826 blk_complete_request +EXPORT_SYMBOL vmlinux 0xb5b7ec96 iov_iter_copy_from_user_atomic +EXPORT_SYMBOL vmlinux 0xb60e34a8 nla_memcpy +EXPORT_SYMBOL vmlinux 0xb618d128 add_mtd_partitions +EXPORT_SYMBOL vmlinux 0xb64f61fd ethtool_op_get_link +EXPORT_SYMBOL vmlinux 0xb66e5ebc read_dev_sector +EXPORT_SYMBOL vmlinux 0xb671c5ff blk_rq_map_sg +EXPORT_SYMBOL vmlinux 0xb678366f int_sqrt +EXPORT_SYMBOL vmlinux 0xb6896671 crc_t10dif +EXPORT_SYMBOL vmlinux 0xb689781d tcp_v4_conn_request +EXPORT_SYMBOL vmlinux 0xb691662e sk_stream_wait_close +EXPORT_SYMBOL vmlinux 0xb6a61a86 qdisc_get_rtab +EXPORT_SYMBOL vmlinux 0xb6b14d4f may_umount_tree +EXPORT_SYMBOL vmlinux 0xb6b38654 nla_put_nohdr +EXPORT_SYMBOL vmlinux 0xb6c5a973 scsi_show_result +EXPORT_SYMBOL vmlinux 0xb6c70a7d __wake_up +EXPORT_SYMBOL vmlinux 0xb6f437d0 snd_card_disconnect +EXPORT_SYMBOL vmlinux 0xb703911e release_firmware +EXPORT_SYMBOL vmlinux 0xb7094151 inet_frags_init +EXPORT_SYMBOL vmlinux 0xb714a981 console_print +EXPORT_SYMBOL vmlinux 0xb7234ff0 scc_diminish_permissions +EXPORT_SYMBOL vmlinux 0xb746577a ll_rw_block +EXPORT_SYMBOL vmlinux 0xb7555f12 timeval_to_jiffies +EXPORT_SYMBOL vmlinux 0xb75ad7db snd_pcm_hw_constraint_integer +EXPORT_SYMBOL vmlinux 0xb76770ea seq_bitmap_list +EXPORT_SYMBOL vmlinux 0xb770c145 skb_dma_map +EXPORT_SYMBOL vmlinux 0xb7ad3321 ida_init +EXPORT_SYMBOL vmlinux 0xb7aecd4a open_bdev_exclusive +EXPORT_SYMBOL vmlinux 0xb7b61546 crc32_be +EXPORT_SYMBOL vmlinux 0xb7f6fd94 mmc_wait_for_req +EXPORT_SYMBOL vmlinux 0xb859f38b krealloc +EXPORT_SYMBOL vmlinux 0xb85f1254 usbotg_uninit +EXPORT_SYMBOL vmlinux 0xb86e4ab9 random32 +EXPORT_SYMBOL vmlinux 0xb87099d9 scc_read_register +EXPORT_SYMBOL vmlinux 0xb8738ba7 block_read_full_page +EXPORT_SYMBOL vmlinux 0xb89af9bf srandom32 +EXPORT_SYMBOL vmlinux 0xb8aa2342 __check_region +EXPORT_SYMBOL vmlinux 0xb8e6bfc2 tty_unregister_driver +EXPORT_SYMBOL vmlinux 0xb8eff1ee scsi_device_lookup +EXPORT_SYMBOL vmlinux 0xb91a441d qdisc_watchdog_cancel +EXPORT_SYMBOL vmlinux 0xb91ba3ff init_task +EXPORT_SYMBOL vmlinux 0xb920bad1 directly_mappable_cdev_bdi +EXPORT_SYMBOL vmlinux 0xb95e03dd bio_integrity_set_tag +EXPORT_SYMBOL vmlinux 0xb95f98d6 _memset_io +EXPORT_SYMBOL vmlinux 0xb9638db4 snd_pcm_rate_to_rate_bit +EXPORT_SYMBOL vmlinux 0xb97d4c9c mutex_lock +EXPORT_SYMBOL vmlinux 0xb98a0185 rtc_tm_to_time +EXPORT_SYMBOL vmlinux 0xb98ef804 vm_stat +EXPORT_SYMBOL vmlinux 0xb99f4696 dmam_alloc_noncoherent +EXPORT_SYMBOL vmlinux 0xb9acd3d9 __put_user_2 +EXPORT_SYMBOL vmlinux 0xb9adb033 snd_device_free +EXPORT_SYMBOL vmlinux 0xb9c74bf1 gen_kill_estimator +EXPORT_SYMBOL vmlinux 0xb9e8c2dc iput +EXPORT_SYMBOL vmlinux 0xb9eafb56 journal_check_used_features +EXPORT_SYMBOL vmlinux 0xb9f4bb3c generic_splice_sendpage +EXPORT_SYMBOL vmlinux 0xba3bda2a __downgrade_write +EXPORT_SYMBOL vmlinux 0xba497f13 loops_per_jiffy +EXPORT_SYMBOL vmlinux 0xba8f8b68 completion_done +EXPORT_SYMBOL vmlinux 0xbaba703c complete_request_key +EXPORT_SYMBOL vmlinux 0xbb155b10 d_prune_aliases +EXPORT_SYMBOL vmlinux 0xbb167766 fb_var_to_videomode +EXPORT_SYMBOL vmlinux 0xbb189cad disallow_signal +EXPORT_SYMBOL vmlinux 0xbb2343f9 dma_mark_declared_memory_occupied +EXPORT_SYMBOL vmlinux 0xbb372376 arp_tbl +EXPORT_SYMBOL vmlinux 0xbb45d8ee unregister_exec_domain +EXPORT_SYMBOL vmlinux 0xbb5d343d xfrm_get_acqseq +EXPORT_SYMBOL vmlinux 0xbb72d4fe __put_user_1 +EXPORT_SYMBOL vmlinux 0xbb7784ce simple_transaction_get +EXPORT_SYMBOL vmlinux 0xbb99125c get_default_font +EXPORT_SYMBOL vmlinux 0xbbc8e804 param_set_ushort +EXPORT_SYMBOL vmlinux 0xbbe89387 vfs_statfs +EXPORT_SYMBOL vmlinux 0xbc10dd97 __put_user_4 +EXPORT_SYMBOL vmlinux 0xbc1cd833 log_wait_commit +EXPORT_SYMBOL vmlinux 0xbc2c89b5 open_by_devnum +EXPORT_SYMBOL vmlinux 0xbc2e69c6 remove_proc_entry +EXPORT_SYMBOL vmlinux 0xbc8b6398 __netdev_alloc_page +EXPORT_SYMBOL vmlinux 0xbcb358e3 add_disk +EXPORT_SYMBOL vmlinux 0xbcb7bba5 neigh_parms_alloc +EXPORT_SYMBOL vmlinux 0xbcc2c8e5 balance_dirty_pages_ratelimited_nr +EXPORT_SYMBOL vmlinux 0xbcd1170a tcf_exts_dump +EXPORT_SYMBOL vmlinux 0xbcebb676 gpio_spi_inactive +EXPORT_SYMBOL vmlinux 0xbcec8df8 tcf_em_tree_validate +EXPORT_SYMBOL vmlinux 0xbd8de59b generic_block_fiemap +EXPORT_SYMBOL vmlinux 0xbd9c1d26 mii_link_ok +EXPORT_SYMBOL vmlinux 0xbd9e162d clk_get_rate +EXPORT_SYMBOL vmlinux 0xbdb999c4 inet_sendmsg +EXPORT_SYMBOL vmlinux 0xbde8d4d7 skb_recv_datagram +EXPORT_SYMBOL vmlinux 0xbdea23a8 kobject_get +EXPORT_SYMBOL vmlinux 0xbdefc2b0 kernel_accept +EXPORT_SYMBOL vmlinux 0xbdf2580d __raw_readsl +EXPORT_SYMBOL vmlinux 0xbe0e5118 nla_memcmp +EXPORT_SYMBOL vmlinux 0xbe476f8d copy_io_context +EXPORT_SYMBOL vmlinux 0xbe4bbfd9 arp_find +EXPORT_SYMBOL vmlinux 0xbe63ee40 request_resource +EXPORT_SYMBOL vmlinux 0xbe82135b cad_pid +EXPORT_SYMBOL vmlinux 0xbe93e6e3 dev_alloc_skb +EXPORT_SYMBOL vmlinux 0xbeb65bff scsi_bios_ptable +EXPORT_SYMBOL vmlinux 0xbec8672d __set_page_dirty_buffers +EXPORT_SYMBOL vmlinux 0xbedfbe3f free_task +EXPORT_SYMBOL vmlinux 0xbef32199 alloc_disk_node +EXPORT_SYMBOL vmlinux 0xbef43296 console_conditional_schedule +EXPORT_SYMBOL vmlinux 0xbeff3078 get_io_context +EXPORT_SYMBOL vmlinux 0xbf25fce9 kernel_setsockopt +EXPORT_SYMBOL vmlinux 0xbf346fc9 sk_stream_error +EXPORT_SYMBOL vmlinux 0xbf43e651 con_set_default_unimap +EXPORT_SYMBOL vmlinux 0xbf5ff5ec search_binary_handler +EXPORT_SYMBOL vmlinux 0xbf73d6d5 kset_register +EXPORT_SYMBOL vmlinux 0xbf7fd2f5 schedule_timeout_killable +EXPORT_SYMBOL vmlinux 0xbf9bcc8d __cap_empty_set +EXPORT_SYMBOL vmlinux 0xbfc0004a pmic_event_subscribe +EXPORT_SYMBOL vmlinux 0xbfcb8c85 inet_dev_addr_type +EXPORT_SYMBOL vmlinux 0xbfee3ad5 loop_unregister_transfer +EXPORT_SYMBOL vmlinux 0xc03a5ed2 nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0xc045ad4e timespec_trunc +EXPORT_SYMBOL vmlinux 0xc051f614 skb_realloc_headroom +EXPORT_SYMBOL vmlinux 0xc0527e2e sah_insert_skha_mode +EXPORT_SYMBOL vmlinux 0xc0580937 rb_erase +EXPORT_SYMBOL vmlinux 0xc06265ec mmc_free_host +EXPORT_SYMBOL vmlinux 0xc0c61276 snd_pcm_lib_preallocate_pages +EXPORT_SYMBOL vmlinux 0xc11d8093 iov_shorten +EXPORT_SYMBOL vmlinux 0xc15fea6c mxc_iomux_get_pad +EXPORT_SYMBOL vmlinux 0xc1601a4f _change_bit_le +EXPORT_SYMBOL vmlinux 0xc1a39fd8 scsi_cmd_ioctl +EXPORT_SYMBOL vmlinux 0xc1ae8e18 kmalloc_caches +EXPORT_SYMBOL vmlinux 0xc1bdd52d neigh_compat_output +EXPORT_SYMBOL vmlinux 0xc1d6c3a7 try_to_release_page +EXPORT_SYMBOL vmlinux 0xc1e6ecff generic_file_buffered_write +EXPORT_SYMBOL vmlinux 0xc1f70a13 fsl_shw_init_keystore_default +EXPORT_SYMBOL vmlinux 0xc1fc4511 _test_and_change_bit_le +EXPORT_SYMBOL vmlinux 0xc22616f1 __init_rwsem +EXPORT_SYMBOL vmlinux 0xc2358e61 __inet6_lookup_established +EXPORT_SYMBOL vmlinux 0xc256e762 __bitmap_equal +EXPORT_SYMBOL vmlinux 0xc260beeb xfrm_state_update +EXPORT_SYMBOL vmlinux 0xc26b9df3 __dev_remove_pack +EXPORT_SYMBOL vmlinux 0xc27487dd __bug +EXPORT_SYMBOL vmlinux 0xc2d01070 rtnl_notify +EXPORT_SYMBOL vmlinux 0xc2d9a5ee flush_dcache_page +EXPORT_SYMBOL vmlinux 0xc2e587d1 reset_devices +EXPORT_SYMBOL vmlinux 0xc359fb65 abort +EXPORT_SYMBOL vmlinux 0xc3b822d3 bio_integrity_trim +EXPORT_SYMBOL vmlinux 0xc3c19d02 seq_putc +EXPORT_SYMBOL vmlinux 0xc3cf1128 in_group_p +EXPORT_SYMBOL vmlinux 0xc3d3f5ab find_task_by_vpid +EXPORT_SYMBOL vmlinux 0xc3ef4a31 generic_file_mmap +EXPORT_SYMBOL vmlinux 0xc40cf771 uart_resume_port +EXPORT_SYMBOL vmlinux 0xc440c451 sg_alloc_table +EXPORT_SYMBOL vmlinux 0xc446d59a snd_pcm_lib_write +EXPORT_SYMBOL vmlinux 0xc476573f expio_intr_fec +EXPORT_SYMBOL vmlinux 0xc488a61f xfrm_nl +EXPORT_SYMBOL vmlinux 0xc499ae1e kstrdup +EXPORT_SYMBOL vmlinux 0xc5153c28 xfrm_state_delete +EXPORT_SYMBOL vmlinux 0xc525bea2 register_netdevice +EXPORT_SYMBOL vmlinux 0xc529dd97 is_container_init +EXPORT_SYMBOL vmlinux 0xc52f5714 fb_videomode_to_var +EXPORT_SYMBOL vmlinux 0xc538a454 blk_rq_init +EXPORT_SYMBOL vmlinux 0xc5f6c494 xfrm_stateonly_find +EXPORT_SYMBOL vmlinux 0xc62379c0 generic_file_aio_read +EXPORT_SYMBOL vmlinux 0xc633495b schedule_work +EXPORT_SYMBOL vmlinux 0xc658b445 skb_copy_and_csum_bits +EXPORT_SYMBOL vmlinux 0xc65d9f36 km_policy_expired +EXPORT_SYMBOL vmlinux 0xc67ed0c8 blk_queue_max_sectors +EXPORT_SYMBOL vmlinux 0xc68b28dc fsl_usb_xcvr_suspend +EXPORT_SYMBOL vmlinux 0xc6f3537c key_task_permission +EXPORT_SYMBOL vmlinux 0xc7082fba xfrm4_prepare_output +EXPORT_SYMBOL vmlinux 0xc722227e posix_acl_clone +EXPORT_SYMBOL vmlinux 0xc74211df register_sound_dsp +EXPORT_SYMBOL vmlinux 0xc74520a6 skb_pull +EXPORT_SYMBOL vmlinux 0xc757bc03 posix_lock_file_wait +EXPORT_SYMBOL vmlinux 0xc77d4398 journal_destroy +EXPORT_SYMBOL vmlinux 0xc7a4fbed rtnl_lock +EXPORT_SYMBOL vmlinux 0xc7cf35c2 ethtool_op_get_tx_csum +EXPORT_SYMBOL vmlinux 0xc7e66777 inode_get_bytes +EXPORT_SYMBOL vmlinux 0xc7ec6c27 strspn +EXPORT_SYMBOL vmlinux 0xc7f8874b seq_escape +EXPORT_SYMBOL vmlinux 0xc7fc952d cdev_del +EXPORT_SYMBOL vmlinux 0xc80756e2 dma_free_coherent +EXPORT_SYMBOL vmlinux 0xc80de694 down_write_trylock +EXPORT_SYMBOL vmlinux 0xc8495027 snd_ctl_unregister_ioctl +EXPORT_SYMBOL vmlinux 0xc862286e generic_delete_inode +EXPORT_SYMBOL vmlinux 0xc8760da1 dev_alloc_name +EXPORT_SYMBOL vmlinux 0xc8b57c27 autoremove_wake_function +EXPORT_SYMBOL vmlinux 0xc9022276 sk_alloc +EXPORT_SYMBOL vmlinux 0xc95b9179 tty_name +EXPORT_SYMBOL vmlinux 0xc96b74f0 snd_device_register +EXPORT_SYMBOL vmlinux 0xc9710260 pmic_adc_set_touch_mode +EXPORT_SYMBOL vmlinux 0xc998d641 icmp_err_convert +EXPORT_SYMBOL vmlinux 0xc9c977f9 snd_pcm_lib_preallocate_free_for_all +EXPORT_SYMBOL vmlinux 0xca29699b nf_ip_checksum +EXPORT_SYMBOL vmlinux 0xca4e85df neigh_update +EXPORT_SYMBOL vmlinux 0xca564528 tty_devnum +EXPORT_SYMBOL vmlinux 0xca5dbc50 scsi_print_sense_hdr +EXPORT_SYMBOL vmlinux 0xcac40926 proc_dointvec +EXPORT_SYMBOL vmlinux 0xcaf553ed sock_i_uid +EXPORT_SYMBOL vmlinux 0xcb01d7ed skb_copy_expand +EXPORT_SYMBOL vmlinux 0xcb168965 get_sb_nodev +EXPORT_SYMBOL vmlinux 0xcb25eeea scsi_unregister +EXPORT_SYMBOL vmlinux 0xcb32da10 param_set_int +EXPORT_SYMBOL vmlinux 0xcb522be6 sock_create +EXPORT_SYMBOL vmlinux 0xcb6beb40 hweight32 +EXPORT_SYMBOL vmlinux 0xcb7131fb fb_get_options +EXPORT_SYMBOL vmlinux 0xcb92c6ec seq_open_private +EXPORT_SYMBOL vmlinux 0xcb98c38e input_grab_device +EXPORT_SYMBOL vmlinux 0xcba803cd __scsi_alloc_queue +EXPORT_SYMBOL vmlinux 0xcba95a21 d_move +EXPORT_SYMBOL vmlinux 0xcbaa47e8 eth_header_parse +EXPORT_SYMBOL vmlinux 0xcbab1b51 mpage_bio_submit +EXPORT_SYMBOL vmlinux 0xcbd9dd4c generic_ro_fops +EXPORT_SYMBOL vmlinux 0xcc11d1f2 skb_add_rx_frag +EXPORT_SYMBOL vmlinux 0xcc36f32e fb_unregister_client +EXPORT_SYMBOL vmlinux 0xcc5005fe msleep_interruptible +EXPORT_SYMBOL vmlinux 0xcc7fa952 local_bh_enable_ip +EXPORT_SYMBOL vmlinux 0xcc82a356 snd_timer_interrupt +EXPORT_SYMBOL vmlinux 0xcc89c159 bio_split +EXPORT_SYMBOL vmlinux 0xcc9c8f27 vc_resize +EXPORT_SYMBOL vmlinux 0xccb3c63a netif_rx +EXPORT_SYMBOL vmlinux 0xcccca482 _test_and_clear_bit_le +EXPORT_SYMBOL vmlinux 0xcd083b10 unregister_sound_dsp +EXPORT_SYMBOL vmlinux 0xcd33d86e call_usermodehelper_stdinpipe +EXPORT_SYMBOL vmlinux 0xcd3abb3c snd_pcm_set_sync +EXPORT_SYMBOL vmlinux 0xcd63c845 __aeabi_lasr +EXPORT_SYMBOL vmlinux 0xcda8b024 scsi_remove_host +EXPORT_SYMBOL vmlinux 0xcddaeb19 create_empty_buffers +EXPORT_SYMBOL vmlinux 0xce04c1ec tty_unthrottle +EXPORT_SYMBOL vmlinux 0xce062208 input_set_capability +EXPORT_SYMBOL vmlinux 0xce119858 skb_split +EXPORT_SYMBOL vmlinux 0xce36ded6 sysctl_tcp_mem +EXPORT_SYMBOL vmlinux 0xce3ca308 copy_from_user_toio +EXPORT_SYMBOL vmlinux 0xce5ac24f zlib_inflate_workspacesize +EXPORT_SYMBOL vmlinux 0xce6da55e remove_inode_hash +EXPORT_SYMBOL vmlinux 0xce99551b gpio_owire_active +EXPORT_SYMBOL vmlinux 0xce9b49f3 mnt_pin +EXPORT_SYMBOL vmlinux 0xce9c1eec fsl_shw_gen_encrypt +EXPORT_SYMBOL vmlinux 0xcea50aaf ip_generic_getfrag +EXPORT_SYMBOL vmlinux 0xcea52c6f inet_stream_ops +EXPORT_SYMBOL vmlinux 0xceda66f5 ethtool_op_set_tx_csum +EXPORT_SYMBOL vmlinux 0xcf0534b4 sah_Alloc_Head_Descriptor +EXPORT_SYMBOL vmlinux 0xcf2c1426 snd_timer_pause +EXPORT_SYMBOL vmlinux 0xcfd3018e set_normalized_timespec +EXPORT_SYMBOL vmlinux 0xcfd96151 ipu_request_irq +EXPORT_SYMBOL vmlinux 0xcff53400 kref_put +EXPORT_SYMBOL vmlinux 0xd0087083 snd_timer_stop +EXPORT_SYMBOL vmlinux 0xd0181f4f __bitmap_xor +EXPORT_SYMBOL vmlinux 0xd029e5d0 i2c_clients_command +EXPORT_SYMBOL vmlinux 0xd02cc869 __bitmap_andnot +EXPORT_SYMBOL vmlinux 0xd073782b snd_pcm_sgbuf_ops_page +EXPORT_SYMBOL vmlinux 0xd0a0c677 register_sysctl_paths +EXPORT_SYMBOL vmlinux 0xd0a98efd simple_transaction_read +EXPORT_SYMBOL vmlinux 0xd0b9b8b8 snd_interval_list +EXPORT_SYMBOL vmlinux 0xd0ee38b8 schedule_timeout_uninterruptible +EXPORT_SYMBOL vmlinux 0xd100c273 km_new_mapping +EXPORT_SYMBOL vmlinux 0xd1118010 input_unregister_handle +EXPORT_SYMBOL vmlinux 0xd1157735 release_and_free_resource +EXPORT_SYMBOL vmlinux 0xd11ff939 save_mount_options +EXPORT_SYMBOL vmlinux 0xd12552f6 deactivate_super +EXPORT_SYMBOL vmlinux 0xd145cd74 proc_symlink +EXPORT_SYMBOL vmlinux 0xd16fdfa0 sock_setsockopt +EXPORT_SYMBOL vmlinux 0xd1894673 stop_tty +EXPORT_SYMBOL vmlinux 0xd18a28bd register_sound_special_device +EXPORT_SYMBOL vmlinux 0xd18d1695 scsi_add_device +EXPORT_SYMBOL vmlinux 0xd21741b1 dmam_free_noncoherent +EXPORT_SYMBOL vmlinux 0xd2323e2c inet_add_protocol +EXPORT_SYMBOL vmlinux 0xd2397c02 tcf_hash_create +EXPORT_SYMBOL vmlinux 0xd251d7b0 security_socket_getpeersec_dgram +EXPORT_SYMBOL vmlinux 0xd2555f19 jiffies_64_to_clock_t +EXPORT_SYMBOL vmlinux 0xd25d4f74 console_blank_hook +EXPORT_SYMBOL vmlinux 0xd25e2c20 skb_seq_read +EXPORT_SYMBOL vmlinux 0xd26a9205 mc13892_bklit_get_dutycycle +EXPORT_SYMBOL vmlinux 0xd26c5e7f devm_ioport_map +EXPORT_SYMBOL vmlinux 0xd274c337 inet_unregister_protosw +EXPORT_SYMBOL vmlinux 0xd288c25a unlock_super +EXPORT_SYMBOL vmlinux 0xd28aaa67 snd_pcm_hw_param_last +EXPORT_SYMBOL vmlinux 0xd28f0c1a fsl_shw_read_key +EXPORT_SYMBOL vmlinux 0xd2965f6f kthread_should_stop +EXPORT_SYMBOL vmlinux 0xd298af43 gpio_usbh1_setback_stp +EXPORT_SYMBOL vmlinux 0xd2e23a37 neigh_ifdown +EXPORT_SYMBOL vmlinux 0xd2ec70c5 fget +EXPORT_SYMBOL vmlinux 0xd2fd600c ip_mc_dec_group +EXPORT_SYMBOL vmlinux 0xd305f34e sock_common_recvmsg +EXPORT_SYMBOL vmlinux 0xd30ae9eb snd_seq_root +EXPORT_SYMBOL vmlinux 0xd31acbf5 mb_cache_entry_get +EXPORT_SYMBOL vmlinux 0xd32e52c7 posix_acl_chmod_masq +EXPORT_SYMBOL vmlinux 0xd3427f73 mempool_create_node +EXPORT_SYMBOL vmlinux 0xd3b2e92d snd_ctl_find_id +EXPORT_SYMBOL vmlinux 0xd3b4027f netpoll_send_udp +EXPORT_SYMBOL vmlinux 0xd3dbfbc4 _find_first_zero_bit_le +EXPORT_SYMBOL vmlinux 0xd417fb7f kill_fasync +EXPORT_SYMBOL vmlinux 0xd418e1c0 adjust_resource +EXPORT_SYMBOL vmlinux 0xd46f1711 nand_scan_bbt +EXPORT_SYMBOL vmlinux 0xd48e37ce xfrm_policy_destroy +EXPORT_SYMBOL vmlinux 0xd5263820 mb_cache_destroy +EXPORT_SYMBOL vmlinux 0xd526f239 xfrm_state_alloc +EXPORT_SYMBOL vmlinux 0xd55bcffe datagram_poll +EXPORT_SYMBOL vmlinux 0xd56389b9 scc_zeroize_memories +EXPORT_SYMBOL vmlinux 0xd5688a7a radix_tree_insert +EXPORT_SYMBOL vmlinux 0xd5c78068 vfs_readlink +EXPORT_SYMBOL vmlinux 0xd5ecddb1 mxc_free_gpio +EXPORT_SYMBOL vmlinux 0xd5ffcef6 tty_port_init +EXPORT_SYMBOL vmlinux 0xd6035d05 do_settimeofday +EXPORT_SYMBOL vmlinux 0xd603ea97 snd_card_free +EXPORT_SYMBOL vmlinux 0xd60b2e6f ipu_disable_channel +EXPORT_SYMBOL vmlinux 0xd627480b strncat +EXPORT_SYMBOL vmlinux 0xd62ac1f9 skb_dequeue_tail +EXPORT_SYMBOL vmlinux 0xd62c833f schedule_timeout +EXPORT_SYMBOL vmlinux 0xd6630d4c setup_arg_pages +EXPORT_SYMBOL vmlinux 0xd666c267 devm_request_irq +EXPORT_SYMBOL vmlinux 0xd66b9767 find_lock_page +EXPORT_SYMBOL vmlinux 0xd66c6228 down_read_trylock +EXPORT_SYMBOL vmlinux 0xd68a2a69 mxc_get_gpio_datain +EXPORT_SYMBOL vmlinux 0xd6b8ce1b kobject_set_name +EXPORT_SYMBOL vmlinux 0xd6d00813 scsi_host_set_state +EXPORT_SYMBOL vmlinux 0xd6ee688f vmalloc +EXPORT_SYMBOL vmlinux 0xd706cdd3 free_netdev +EXPORT_SYMBOL vmlinux 0xd75c8baa scsi_host_get +EXPORT_SYMBOL vmlinux 0xd763e9d2 kobject_put +EXPORT_SYMBOL vmlinux 0xd77b59f6 con_is_bound +EXPORT_SYMBOL vmlinux 0xd78ccf8b neigh_seq_next +EXPORT_SYMBOL vmlinux 0xd79b5a02 allow_signal +EXPORT_SYMBOL vmlinux 0xd7b69fae idr_find +EXPORT_SYMBOL vmlinux 0xd7bc8961 qdisc_class_hash_grow +EXPORT_SYMBOL vmlinux 0xd7da27a9 sock_register +EXPORT_SYMBOL vmlinux 0xd7dcefe5 journal_forget +EXPORT_SYMBOL vmlinux 0xd7f47216 submit_bio +EXPORT_SYMBOL vmlinux 0xd8026362 mmc_cleanup_queue +EXPORT_SYMBOL vmlinux 0xd80315f5 dst_release +EXPORT_SYMBOL vmlinux 0xd8282ff0 posix_acl_equiv_mode +EXPORT_SYMBOL vmlinux 0xd83791bc nf_conntrack_destroy +EXPORT_SYMBOL vmlinux 0xd86e7c57 tcp_check_req +EXPORT_SYMBOL vmlinux 0xd8a2ab95 in_egroup_p +EXPORT_SYMBOL vmlinux 0xd8b9e6ed elv_rb_add +EXPORT_SYMBOL vmlinux 0xd8e23c9f make_EII_client +EXPORT_SYMBOL vmlinux 0xd8e484f0 register_chrdev_region +EXPORT_SYMBOL vmlinux 0xd8f7872f block_write_end +EXPORT_SYMBOL vmlinux 0xd9371f57 dev_mc_delete +EXPORT_SYMBOL vmlinux 0xd94d1e1a skb_prepare_seq_read +EXPORT_SYMBOL vmlinux 0xd955ac78 tcp_create_openreq_child +EXPORT_SYMBOL vmlinux 0xd985dc99 mempool_free_pages +EXPORT_SYMBOL vmlinux 0xd99576a0 journal_release_buffer +EXPORT_SYMBOL vmlinux 0xd9ace705 __sk_mem_schedule +EXPORT_SYMBOL vmlinux 0xd9ce8f0c strnlen +EXPORT_SYMBOL vmlinux 0xd9e5b2b1 tty_hung_up_p +EXPORT_SYMBOL vmlinux 0xd9f88f64 dma_pool_create +EXPORT_SYMBOL vmlinux 0xda14c87d single_open +EXPORT_SYMBOL vmlinux 0xda1a7335 kasprintf +EXPORT_SYMBOL vmlinux 0xda1c0a8d bio_integrity_prep +EXPORT_SYMBOL vmlinux 0xda1d7d62 remap_pfn_range +EXPORT_SYMBOL vmlinux 0xda1fc224 cpu_cache +EXPORT_SYMBOL vmlinux 0xda3fc93d qdisc_watchdog_schedule +EXPORT_SYMBOL vmlinux 0xda533631 bio_integrity_alloc_bioset +EXPORT_SYMBOL vmlinux 0xda55efe6 revalidate_disk +EXPORT_SYMBOL vmlinux 0xda5ea696 _test_and_set_bit_le +EXPORT_SYMBOL vmlinux 0xda6e7988 scsi_register_driver +EXPORT_SYMBOL vmlinux 0xda7ca6cb fb_mode_is_equal +EXPORT_SYMBOL vmlinux 0xda81014d ip_ct_attach +EXPORT_SYMBOL vmlinux 0xda8af7ad fb_find_nearest_mode +EXPORT_SYMBOL vmlinux 0xda8b5096 xfrm_cfg_mutex +EXPORT_SYMBOL vmlinux 0xdafc3fc2 scsi_report_device_reset +EXPORT_SYMBOL vmlinux 0xdb0eeae6 input_close_device +EXPORT_SYMBOL vmlinux 0xdb21e527 loop_register_transfer +EXPORT_SYMBOL vmlinux 0xdb336ace do_system_keystore_slot_decrypt +EXPORT_SYMBOL vmlinux 0xdb33f274 journal_init_inode +EXPORT_SYMBOL vmlinux 0xdb40059f xfrm_input +EXPORT_SYMBOL vmlinux 0xdb44614b dev_close +EXPORT_SYMBOL vmlinux 0xdb49882b misc_register +EXPORT_SYMBOL vmlinux 0xdb4a68e6 vfs_llseek +EXPORT_SYMBOL vmlinux 0xdb685e90 journal_flush +EXPORT_SYMBOL vmlinux 0xdb7fd8ea shrink_dcache_sb +EXPORT_SYMBOL vmlinux 0xdb864d65 iov_iter_single_seg_count +EXPORT_SYMBOL vmlinux 0xdb8b2bcf sah_Free_Link +EXPORT_SYMBOL vmlinux 0xdbcd416e sysctl_ip_nonlocal_bind +EXPORT_SYMBOL vmlinux 0xdbe3c7a9 simple_link +EXPORT_SYMBOL vmlinux 0xdc053205 udp_memory_allocated +EXPORT_SYMBOL vmlinux 0xdc0eaff0 generic_write_checks +EXPORT_SYMBOL vmlinux 0xdc24a3b9 mxc_dma_get_config +EXPORT_SYMBOL vmlinux 0xdc2adb35 add_taint +EXPORT_SYMBOL vmlinux 0xdc35ba3e force_sig +EXPORT_SYMBOL vmlinux 0xdc4071ca sock_get_timestampns +EXPORT_SYMBOL vmlinux 0xdc43a9c8 daemonize +EXPORT_SYMBOL vmlinux 0xdc4682ae blk_put_request +EXPORT_SYMBOL vmlinux 0xdc6e5402 wait_on_page_bit +EXPORT_SYMBOL vmlinux 0xdc738c20 kmem_ptr_validate +EXPORT_SYMBOL vmlinux 0xdca981ea netlink_rcv_skb +EXPORT_SYMBOL vmlinux 0xdcabf050 filemap_flush +EXPORT_SYMBOL vmlinux 0xdcb0349b sys_close +EXPORT_SYMBOL vmlinux 0xdd066797 proc_dointvec_ms_jiffies +EXPORT_SYMBOL vmlinux 0xdd0a2ba2 strlcat +EXPORT_SYMBOL vmlinux 0xdd10dae6 scsi_setup_fs_cmnd +EXPORT_SYMBOL vmlinux 0xdd27fa87 memchr +EXPORT_SYMBOL vmlinux 0xdd356697 kthread_bind +EXPORT_SYMBOL vmlinux 0xdd48685f __skb_recv_datagram +EXPORT_SYMBOL vmlinux 0xdd6bfccd radix_tree_tag_set +EXPORT_SYMBOL vmlinux 0xdd8dc983 dev_getbyhwaddr +EXPORT_SYMBOL vmlinux 0xdda100e8 ip4_datagram_connect +EXPORT_SYMBOL vmlinux 0xdda27ee7 call_usermodehelper_setup +EXPORT_SYMBOL vmlinux 0xddbf5213 bioset_integrity_free +EXPORT_SYMBOL vmlinux 0xddc8bc39 thaw_bdev +EXPORT_SYMBOL vmlinux 0xddcc9f87 xfrm_input_resume +EXPORT_SYMBOL vmlinux 0xddced9fb sysctl_ms_jiffies +EXPORT_SYMBOL vmlinux 0xddd289b2 mxc_free_iomux +EXPORT_SYMBOL vmlinux 0xdded987d genl_register_ops +EXPORT_SYMBOL vmlinux 0xddeef053 vfs_stat +EXPORT_SYMBOL vmlinux 0xddf51d3f journal_load +EXPORT_SYMBOL vmlinux 0xde377cb6 generic_unplug_device +EXPORT_SYMBOL vmlinux 0xde75b689 set_irq_type +EXPORT_SYMBOL vmlinux 0xde78880f ethtool_op_set_flags +EXPORT_SYMBOL vmlinux 0xde9360ba totalram_pages +EXPORT_SYMBOL vmlinux 0xdecb0379 tcp_connect +EXPORT_SYMBOL vmlinux 0xded679d3 mxc_dma_set_bd_intr +EXPORT_SYMBOL vmlinux 0xdf0a2a72 snd_unregister_oss_device +EXPORT_SYMBOL vmlinux 0xdf49c4d9 register_exec_domain +EXPORT_SYMBOL vmlinux 0xdf51248c mmc_register_driver +EXPORT_SYMBOL vmlinux 0xdf60cc27 __print_symbol +EXPORT_SYMBOL vmlinux 0xdf684869 snd_pcm_set_ops +EXPORT_SYMBOL vmlinux 0xdf7dcb51 __devm_request_region +EXPORT_SYMBOL vmlinux 0xdf8aa442 ip_xfrm_me_harder +EXPORT_SYMBOL vmlinux 0xdf929370 fs_overflowgid +EXPORT_SYMBOL vmlinux 0xdf9ea9cf snd_pcm_hw_constraint_ratnums +EXPORT_SYMBOL vmlinux 0xdfb01a80 cpu_v7_dcache_clean_area +EXPORT_SYMBOL vmlinux 0xdfb8405b sock_create_kern +EXPORT_SYMBOL vmlinux 0xdfecbdcb gpio_sensor_active +EXPORT_SYMBOL vmlinux 0xe075d6eb iter_div_u64_rem +EXPORT_SYMBOL vmlinux 0xe0878bfe __krealloc +EXPORT_SYMBOL vmlinux 0xe0a87a56 mii_ethtool_sset +EXPORT_SYMBOL vmlinux 0xe0b13336 argv_free +EXPORT_SYMBOL vmlinux 0xe0b439bf scsi_cmd_print_sense_hdr +EXPORT_SYMBOL vmlinux 0xe0c0119a scsi_print_sense +EXPORT_SYMBOL vmlinux 0xe0c0be5d generic_setlease +EXPORT_SYMBOL vmlinux 0xe0e33c25 lock_may_read +EXPORT_SYMBOL vmlinux 0xe113bbbc csum_partial +EXPORT_SYMBOL vmlinux 0xe11bae5f sock_sendmsg +EXPORT_SYMBOL vmlinux 0xe132e714 blk_queue_bounce +EXPORT_SYMBOL vmlinux 0xe1338783 page_put_link +EXPORT_SYMBOL vmlinux 0xe13e110d snd_unregister_device +EXPORT_SYMBOL vmlinux 0xe14c4a1a rtnl_create_link +EXPORT_SYMBOL vmlinux 0xe14ee8f4 sock_kfree_s +EXPORT_SYMBOL vmlinux 0xe158f83d fasync_helper +EXPORT_SYMBOL vmlinux 0xe16a06b5 tcf_exts_dump_stats +EXPORT_SYMBOL vmlinux 0xe1761617 security_inet_conn_request +EXPORT_SYMBOL vmlinux 0xe195e7c0 blk_rq_map_integrity_sg +EXPORT_SYMBOL vmlinux 0xe1ac56ba i2c_release_client +EXPORT_SYMBOL vmlinux 0xe1b235c5 dmam_alloc_coherent +EXPORT_SYMBOL vmlinux 0xe1b84998 posix_lock_file +EXPORT_SYMBOL vmlinux 0xe1c77f0f mxc_dma_disable +EXPORT_SYMBOL vmlinux 0xe1d24f6f devm_iounmap +EXPORT_SYMBOL vmlinux 0xe1e22175 snd_timer_global_new +EXPORT_SYMBOL vmlinux 0xe2043b06 sock_wfree +EXPORT_SYMBOL vmlinux 0xe21782e7 __bio_clone +EXPORT_SYMBOL vmlinux 0xe24d3a97 jiffies_64 +EXPORT_SYMBOL vmlinux 0xe257282e __kill_fasync +EXPORT_SYMBOL vmlinux 0xe2941762 call_usermodehelper_pipe +EXPORT_SYMBOL vmlinux 0xe29dac05 ip_cmsg_recv +EXPORT_SYMBOL vmlinux 0xe2a8d4c8 add_to_page_cache_locked +EXPORT_SYMBOL vmlinux 0xe2bcd4d0 bio_integrity_advance +EXPORT_SYMBOL vmlinux 0xe2d2802c elevator_init +EXPORT_SYMBOL vmlinux 0xe2d433c8 f_setown +EXPORT_SYMBOL vmlinux 0xe2d5255a strcmp +EXPORT_SYMBOL vmlinux 0xe2d694d8 __xfrm_state_delete +EXPORT_SYMBOL vmlinux 0xe2fae716 kmemdup +EXPORT_SYMBOL vmlinux 0xe3299ef6 scsi_eh_prep_cmnd +EXPORT_SYMBOL vmlinux 0xe351633f genl_register_family +EXPORT_SYMBOL vmlinux 0xe393efa2 snd_timer_notify +EXPORT_SYMBOL vmlinux 0xe39482cf fsl_shw_symmetric_encrypt +EXPORT_SYMBOL vmlinux 0xe3ac7926 vfs_getattr +EXPORT_SYMBOL vmlinux 0xe3c7a2a0 input_free_device +EXPORT_SYMBOL vmlinux 0xe3e6dad8 blk_queue_max_hw_segments +EXPORT_SYMBOL vmlinux 0xe4095a6a ipu_disp_direct_write +EXPORT_SYMBOL vmlinux 0xe427adba ipv6_skip_exthdr +EXPORT_SYMBOL vmlinux 0xe437f383 unlock_new_inode +EXPORT_SYMBOL vmlinux 0xe44e5130 inet_bind +EXPORT_SYMBOL vmlinux 0xe44f5033 fsl_shw_hash +EXPORT_SYMBOL vmlinux 0xe45300d8 textsearch_unregister +EXPORT_SYMBOL vmlinux 0xe4854cea snd_iprintf +EXPORT_SYMBOL vmlinux 0xe4a3678a proc_dointvec_jiffies +EXPORT_SYMBOL vmlinux 0xe4a97c71 __down_write_trylock +EXPORT_SYMBOL vmlinux 0xe4b593af sock_wake_async +EXPORT_SYMBOL vmlinux 0xe4b6923d scsi_adjust_queue_depth +EXPORT_SYMBOL vmlinux 0xe4be04a4 blk_queue_dma_pad +EXPORT_SYMBOL vmlinux 0xe4c80097 cacheid +EXPORT_SYMBOL vmlinux 0xe4d0bc0b sock_no_getname +EXPORT_SYMBOL vmlinux 0xe4d3b4ec put_page +EXPORT_SYMBOL vmlinux 0xe4d7424e bdi_register +EXPORT_SYMBOL vmlinux 0xe4eea403 sah_deregister +EXPORT_SYMBOL vmlinux 0xe4fefed0 vm_insert_page +EXPORT_SYMBOL vmlinux 0xe50bb1f6 __pagevec_release +EXPORT_SYMBOL vmlinux 0xe5385075 xfrm_policy_byid +EXPORT_SYMBOL vmlinux 0xe56a9336 snd_pcm_format_width +EXPORT_SYMBOL vmlinux 0xe57878a1 in6_pton +EXPORT_SYMBOL vmlinux 0xe5859246 mnt_unpin +EXPORT_SYMBOL vmlinux 0xe5867808 dlci_ioctl_set +EXPORT_SYMBOL vmlinux 0xe5c78a99 do_blank_screen +EXPORT_SYMBOL vmlinux 0xe5cb45d7 snd_timer_start +EXPORT_SYMBOL vmlinux 0xe5ed5467 xfrm_policy_walk_init +EXPORT_SYMBOL vmlinux 0xe606dd88 pneigh_lookup +EXPORT_SYMBOL vmlinux 0xe6355660 scsicam_bios_param +EXPORT_SYMBOL vmlinux 0xe6a46565 task_session_nr_ns +EXPORT_SYMBOL vmlinux 0xe6a92b49 __ip_select_ident +EXPORT_SYMBOL vmlinux 0xe6a9ab34 snd_ctl_register_ioctl +EXPORT_SYMBOL vmlinux 0xe6c034a8 ipu_disable_irq +EXPORT_SYMBOL vmlinux 0xe6c3ebb0 __raw_writesw +EXPORT_SYMBOL vmlinux 0xe6ebc016 key_create_or_update +EXPORT_SYMBOL vmlinux 0xe6f16478 mark_buffer_async_write +EXPORT_SYMBOL vmlinux 0xe6fb7511 tty_driver_flush_buffer +EXPORT_SYMBOL vmlinux 0xe6fbe430 can_do_mlock +EXPORT_SYMBOL vmlinux 0xe70366af dmam_free_coherent +EXPORT_SYMBOL vmlinux 0xe707d823 __aeabi_uidiv +EXPORT_SYMBOL vmlinux 0xe73f8302 tcp_v4_do_rcv +EXPORT_SYMBOL vmlinux 0xe7636f17 fb_validate_mode +EXPORT_SYMBOL vmlinux 0xe7d2aca1 security_sk_classify_flow +EXPORT_SYMBOL vmlinux 0xe7d4c2f9 create_proc_entry +EXPORT_SYMBOL vmlinux 0xe7d4daac seq_list_next +EXPORT_SYMBOL vmlinux 0xe7fb8dfe pmic_adc_get_touch_sample +EXPORT_SYMBOL vmlinux 0xe7fcd350 kernel_read +EXPORT_SYMBOL vmlinux 0xe8094c92 bdi_destroy +EXPORT_SYMBOL vmlinux 0xe80b2918 in_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0xe811c08a skb_trim +EXPORT_SYMBOL vmlinux 0xe81f3af6 schedule_delayed_work_on +EXPORT_SYMBOL vmlinux 0xe82caa7c scm_detach_fds +EXPORT_SYMBOL vmlinux 0xe842f965 proc_mkdir +EXPORT_SYMBOL vmlinux 0xe88306c0 sk_receive_skb +EXPORT_SYMBOL vmlinux 0xe885a55a qdisc_reset +EXPORT_SYMBOL vmlinux 0xe8cd902e hweight16 +EXPORT_SYMBOL vmlinux 0xe8e64fbc bytes_per_pixel +EXPORT_SYMBOL vmlinux 0xe8ebbdd0 gpio_sensor_inactive +EXPORT_SYMBOL vmlinux 0xe8f19de2 do_mmap_pgoff +EXPORT_SYMBOL vmlinux 0xe8f3178d mc13892_bklit_set_current +EXPORT_SYMBOL vmlinux 0xe8f37518 xfrm_unregister_km +EXPORT_SYMBOL vmlinux 0xe8f8e6ed end_page_writeback +EXPORT_SYMBOL vmlinux 0xe914e41e strcpy +EXPORT_SYMBOL vmlinux 0xe91ff972 audit_log_end +EXPORT_SYMBOL vmlinux 0xe93240d8 snd_dma_free_pages +EXPORT_SYMBOL vmlinux 0xe9456a5a sysctl_xfrm_aevent_rseqth +EXPORT_SYMBOL vmlinux 0xe98d3fbc snd_pcm_lib_writev +EXPORT_SYMBOL vmlinux 0xe9cc9e46 blk_get_backing_dev_info +EXPORT_SYMBOL vmlinux 0xe9df1ab2 pmic_adc_init +EXPORT_SYMBOL vmlinux 0xe9e28577 d_lookup +EXPORT_SYMBOL vmlinux 0xe9f370a3 scsi_device_get +EXPORT_SYMBOL vmlinux 0xea067fd4 blk_plug_device_unlocked +EXPORT_SYMBOL vmlinux 0xea10212a int_to_scsilun +EXPORT_SYMBOL vmlinux 0xea10655a __bitmap_intersects +EXPORT_SYMBOL vmlinux 0xea147363 printk +EXPORT_SYMBOL vmlinux 0xea1cebde generic_fillattr +EXPORT_SYMBOL vmlinux 0xea2d33a2 radix_tree_gang_lookup_slot +EXPORT_SYMBOL vmlinux 0xea402368 snd_component_add +EXPORT_SYMBOL vmlinux 0xea556e3c __napi_schedule +EXPORT_SYMBOL vmlinux 0xea6fcdaa genl_unregister_family +EXPORT_SYMBOL vmlinux 0xea7987f1 key_update +EXPORT_SYMBOL vmlinux 0xea858cb5 radix_tree_gang_lookup_tag +EXPORT_SYMBOL vmlinux 0xead3a83f sah_add_two_out_desc +EXPORT_SYMBOL vmlinux 0xeae3dfd6 __const_udelay +EXPORT_SYMBOL vmlinux 0xeafd00de iw_handler_get_thrspy +EXPORT_SYMBOL vmlinux 0xeb172b0a fsl_shw_sfree +EXPORT_SYMBOL vmlinux 0xeb395084 param_get_invbool +EXPORT_SYMBOL vmlinux 0xeb8f54b3 strstrip +EXPORT_SYMBOL vmlinux 0xebd05923 path_put +EXPORT_SYMBOL vmlinux 0xebd273a6 strict_strtoull +EXPORT_SYMBOL vmlinux 0xebdec22e bio_integrity_free +EXPORT_SYMBOL vmlinux 0xebe973ee key_revoke +EXPORT_SYMBOL vmlinux 0xebfdcbdf system_serial_high +EXPORT_SYMBOL vmlinux 0xec1737d7 mb_cache_shrink +EXPORT_SYMBOL vmlinux 0xec2a6ab6 ipu_disp_set_color_key +EXPORT_SYMBOL vmlinux 0xec3a5028 gpio_free_irq +EXPORT_SYMBOL vmlinux 0xec794ba0 __send_remote_softirq +EXPORT_SYMBOL vmlinux 0xec7c765d tcp_tso_segment +EXPORT_SYMBOL vmlinux 0xec8300d6 vlan_ioctl_set +EXPORT_SYMBOL vmlinux 0xeca8bf38 xfrm_policy_alloc +EXPORT_SYMBOL vmlinux 0xecc0fe6b bdevname +EXPORT_SYMBOL vmlinux 0xecd4bdb2 kmem_cache_create +EXPORT_SYMBOL vmlinux 0xecff4184 journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0xed1a94f9 i2c_attach_client +EXPORT_SYMBOL vmlinux 0xed1b1c77 xfrm_policy_delete +EXPORT_SYMBOL vmlinux 0xed499141 bio_integrity_tag_size +EXPORT_SYMBOL vmlinux 0xed4e7e3e elv_dispatch_add_tail +EXPORT_SYMBOL vmlinux 0xed586d6e udp_poll +EXPORT_SYMBOL vmlinux 0xed652d60 i2c_use_client +EXPORT_SYMBOL vmlinux 0xed77ca46 fsl_shw_diminish_perms +EXPORT_SYMBOL vmlinux 0xed852aca sync_blockdev +EXPORT_SYMBOL vmlinux 0xed8c37a0 sah_Destroy_Link +EXPORT_SYMBOL vmlinux 0xedbaee5e nla_strcmp +EXPORT_SYMBOL vmlinux 0xedc779d2 ilookup +EXPORT_SYMBOL vmlinux 0xedd14538 param_get_uint +EXPORT_SYMBOL vmlinux 0xedd9106d __ashrdi3 +EXPORT_SYMBOL vmlinux 0xedf10553 unregister_mtd_chip_driver +EXPORT_SYMBOL vmlinux 0xee2d0fc7 _local_bh_enable +EXPORT_SYMBOL vmlinux 0xee345200 nand_default_bbt +EXPORT_SYMBOL vmlinux 0xee6e07cd mmc_unregister_driver +EXPORT_SYMBOL vmlinux 0xee6fdf0b cpu_online_map +EXPORT_SYMBOL vmlinux 0xee8db8b6 blk_requeue_request +EXPORT_SYMBOL vmlinux 0xee94583c map_destroy +EXPORT_SYMBOL vmlinux 0xeea94c5f gpio_i2c_hs_inactive +EXPORT_SYMBOL vmlinux 0xeea9dbaf bitmap_bitremap +EXPORT_SYMBOL vmlinux 0xeeb1717c param_array_get +EXPORT_SYMBOL vmlinux 0xeeb54351 skb_gso_segment +EXPORT_SYMBOL vmlinux 0xeec1df12 sah_Free_Head_Descriptor +EXPORT_SYMBOL vmlinux 0xef0c7ad1 inode_add_bytes +EXPORT_SYMBOL vmlinux 0xef1a1668 km_waitq +EXPORT_SYMBOL vmlinux 0xef1c6d28 bio_alloc +EXPORT_SYMBOL vmlinux 0xef2f16ee snd_pcm_hw_rule_add +EXPORT_SYMBOL vmlinux 0xef89108d dmam_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0xefa60090 vc_cons +EXPORT_SYMBOL vmlinux 0xefa9b449 get_empty_filp +EXPORT_SYMBOL vmlinux 0xefb7b8df i2c_smbus_write_i2c_block_data +EXPORT_SYMBOL vmlinux 0xefb7d941 sync_dirty_buffer +EXPORT_SYMBOL vmlinux 0xefbb28ca mpage_writepage +EXPORT_SYMBOL vmlinux 0xefc407e3 blkdev_dequeue_request +EXPORT_SYMBOL vmlinux 0xefdd70ce security_secid_to_secctx +EXPORT_SYMBOL vmlinux 0xefeddf47 tcp_parse_options +EXPORT_SYMBOL vmlinux 0xeff1fc38 vfs_mkdir +EXPORT_SYMBOL vmlinux 0xf0009fee put_pages_list +EXPORT_SYMBOL vmlinux 0xf01516e9 xfrm_state_delete_tunnel +EXPORT_SYMBOL vmlinux 0xf01d79b1 tcf_hash_insert +EXPORT_SYMBOL vmlinux 0xf0545556 generic_file_open +EXPORT_SYMBOL vmlinux 0xf071f075 snd_card_register +EXPORT_SYMBOL vmlinux 0xf09833eb sk_stream_kill_queues +EXPORT_SYMBOL vmlinux 0xf0aaaddb blk_queue_softirq_done +EXPORT_SYMBOL vmlinux 0xf0b57c68 param_set_long +EXPORT_SYMBOL vmlinux 0xf0cb2923 get_disk +EXPORT_SYMBOL vmlinux 0xf0f1246c kvasprintf +EXPORT_SYMBOL vmlinux 0xf127b577 lookup_bdev +EXPORT_SYMBOL vmlinux 0xf162fe2d sysctl_xfrm_aevent_etime +EXPORT_SYMBOL vmlinux 0xf174ed48 acquire_console_sem +EXPORT_SYMBOL vmlinux 0xf176a394 sah_Descriptor_Chain_Destroy +EXPORT_SYMBOL vmlinux 0xf17cef67 i2c_verify_client +EXPORT_SYMBOL vmlinux 0xf195c682 fb_invert_cmaps +EXPORT_SYMBOL vmlinux 0xf196ac35 ipu_init_async_panel +EXPORT_SYMBOL vmlinux 0xf19d9e69 __break_lease +EXPORT_SYMBOL vmlinux 0xf1ada036 put_disk +EXPORT_SYMBOL vmlinux 0xf1b12cba scsi_eh_finish_cmd +EXPORT_SYMBOL vmlinux 0xf1b29d9d task_pgrp_nr_ns +EXPORT_SYMBOL vmlinux 0xf1deabf2 div64_u64 +EXPORT_SYMBOL vmlinux 0xf1e98c74 avenrun +EXPORT_SYMBOL vmlinux 0xf20dabd8 free_irq +EXPORT_SYMBOL vmlinux 0xf22b67e9 update_region +EXPORT_SYMBOL vmlinux 0xf238db4b sock_no_accept +EXPORT_SYMBOL vmlinux 0xf2678e39 sock_no_ioctl +EXPORT_SYMBOL vmlinux 0xf2878892 generic_file_readonly_mmap +EXPORT_SYMBOL vmlinux 0xf297da75 fb_class +EXPORT_SYMBOL vmlinux 0xf2997713 tty_termios_hw_change +EXPORT_SYMBOL vmlinux 0xf2a1d6d2 register_binfmt +EXPORT_SYMBOL vmlinux 0xf2a6d2bf xfrm_policy_count +EXPORT_SYMBOL vmlinux 0xf2afa595 param_get_charp +EXPORT_SYMBOL vmlinux 0xf2ba6c53 i2c_smbus_read_i2c_block_data +EXPORT_SYMBOL vmlinux 0xf2d17379 spba_rel_ownership +EXPORT_SYMBOL vmlinux 0xf2e77e69 inode_change_ok +EXPORT_SYMBOL vmlinux 0xf3023758 mxc_dma_set_config +EXPORT_SYMBOL vmlinux 0xf313da4e sha_transform +EXPORT_SYMBOL vmlinux 0xf338d4c3 netlink_unregister_notifier +EXPORT_SYMBOL vmlinux 0xf33f3473 bdi_unregister +EXPORT_SYMBOL vmlinux 0xf346231f seq_list_start_head +EXPORT_SYMBOL vmlinux 0xf3797152 snd_interval_ratnum +EXPORT_SYMBOL vmlinux 0xf397b9aa __tasklet_schedule +EXPORT_SYMBOL vmlinux 0xf39bf4d9 put_cmsg +EXPORT_SYMBOL vmlinux 0xf3a247ff snd_timer_new +EXPORT_SYMBOL vmlinux 0xf3bf0bce __bitmap_complement +EXPORT_SYMBOL vmlinux 0xf3c714d8 tty_schedule_flip +EXPORT_SYMBOL vmlinux 0xf3dab186 scsi_scan_target +EXPORT_SYMBOL vmlinux 0xf3f30271 textsearch_find_continuous +EXPORT_SYMBOL vmlinux 0xf3fb9e84 dst_discard +EXPORT_SYMBOL vmlinux 0xf3fd55a4 dma_mmap_coherent +EXPORT_SYMBOL vmlinux 0xf403288f ilookup5 +EXPORT_SYMBOL vmlinux 0xf407121a generic_shutdown_super +EXPORT_SYMBOL vmlinux 0xf42b6501 mxc_dma_request +EXPORT_SYMBOL vmlinux 0xf45a665d tty_unregister_device +EXPORT_SYMBOL vmlinux 0xf46cf81e blk_queue_hardsect_size +EXPORT_SYMBOL vmlinux 0xf4b74fc3 prepare_binprm +EXPORT_SYMBOL vmlinux 0xf4c85afb sg_miter_next +EXPORT_SYMBOL vmlinux 0xf4d6a972 fsl_shw_establish_keystore +EXPORT_SYMBOL vmlinux 0xf4da485d vmap +EXPORT_SYMBOL vmlinux 0xf4f14de6 rtnl_trylock +EXPORT_SYMBOL vmlinux 0xf511cf3e framebuffer_alloc +EXPORT_SYMBOL vmlinux 0xf51c639f interruptible_sleep_on_timeout +EXPORT_SYMBOL vmlinux 0xf53d4c26 qdisc_class_hash_destroy +EXPORT_SYMBOL vmlinux 0xf564412a __aeabi_ulcmp +EXPORT_SYMBOL vmlinux 0xf598fa55 scsi_nonblockable_ioctl +EXPORT_SYMBOL vmlinux 0xf5c05914 generic_segment_checks +EXPORT_SYMBOL vmlinux 0xf61e5ade dcache_dir_open +EXPORT_SYMBOL vmlinux 0xf6556747 sockfd_lookup +EXPORT_SYMBOL vmlinux 0xf66e9779 i2c_get_adapter +EXPORT_SYMBOL vmlinux 0xf678cf54 send_sig +EXPORT_SYMBOL vmlinux 0xf67b87e6 __splice_from_pipe +EXPORT_SYMBOL vmlinux 0xf6b178da register_framebuffer +EXPORT_SYMBOL vmlinux 0xf6b90893 sock_kmalloc +EXPORT_SYMBOL vmlinux 0xf6bb4729 color_table +EXPORT_SYMBOL vmlinux 0xf6e4ab85 __netif_schedule +EXPORT_SYMBOL vmlinux 0xf6ebc03b net_ratelimit +EXPORT_SYMBOL vmlinux 0xf6fc2cb9 sock_release +EXPORT_SYMBOL vmlinux 0xf7384f52 downgrade_write +EXPORT_SYMBOL vmlinux 0xf7584a9c find_font +EXPORT_SYMBOL vmlinux 0xf7623914 radix_tree_tag_clear +EXPORT_SYMBOL vmlinux 0xf76581b3 bd_release +EXPORT_SYMBOL vmlinux 0xf77fbb46 idr_remove_all +EXPORT_SYMBOL vmlinux 0xf7802486 __aeabi_uidivmod +EXPORT_SYMBOL vmlinux 0xf78d04ab netlink_register_notifier +EXPORT_SYMBOL vmlinux 0xf7cc7b1a cdev_init +EXPORT_SYMBOL vmlinux 0xf7fc95ba ipu_enable_channel +EXPORT_SYMBOL vmlinux 0xf80e6fa6 inode_needs_sync +EXPORT_SYMBOL vmlinux 0xf811e69d scsi_eh_flush_done_q +EXPORT_SYMBOL vmlinux 0xf81affaf mxc_snoop_set_config +EXPORT_SYMBOL vmlinux 0xf82a0954 snd_timer_global_free +EXPORT_SYMBOL vmlinux 0xf82f1109 utf8_wctomb +EXPORT_SYMBOL vmlinux 0xf8389e3e simple_statfs +EXPORT_SYMBOL vmlinux 0xf86d636b mxc_get_static_channels +EXPORT_SYMBOL vmlinux 0xf8814f73 rb_last +EXPORT_SYMBOL vmlinux 0xf88c871a tty_shutdown +EXPORT_SYMBOL vmlinux 0xf890fe7f pm_idle +EXPORT_SYMBOL vmlinux 0xf89c8682 generic_writepages +EXPORT_SYMBOL vmlinux 0xf8f114a3 pagevec_lookup +EXPORT_SYMBOL vmlinux 0xf8fbb4f0 __bad_xchg +EXPORT_SYMBOL vmlinux 0xf919a287 put_io_context +EXPORT_SYMBOL vmlinux 0xf91c5dfa qdisc_calculate_pkt_len +EXPORT_SYMBOL vmlinux 0xf95bd87f dma_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0xf96543a5 fb_get_mode +EXPORT_SYMBOL vmlinux 0xf96aa92b nf_getsockopt +EXPORT_SYMBOL vmlinux 0xf97f3e82 snd_dma_get_reserved_buf +EXPORT_SYMBOL vmlinux 0xf99ec6d3 register_sound_midi +EXPORT_SYMBOL vmlinux 0xf9a45005 gpio_get_data +EXPORT_SYMBOL vmlinux 0xf9a482f9 msleep +EXPORT_SYMBOL vmlinux 0xf9a67d4c sk_stream_wait_memory +EXPORT_SYMBOL vmlinux 0xf9b28bac interruptible_sleep_on +EXPORT_SYMBOL vmlinux 0xf9bfce74 mxc_dma_set_channel_priority +EXPORT_SYMBOL vmlinux 0xf9c4711c snd_cards +EXPORT_SYMBOL vmlinux 0xf9cc1d20 blk_start_queueing +EXPORT_SYMBOL vmlinux 0xf9d89988 ether_setup +EXPORT_SYMBOL vmlinux 0xfa16bbfb mmc_remove_host +EXPORT_SYMBOL vmlinux 0xfa2d1f98 audit_log_start +EXPORT_SYMBOL vmlinux 0xfaadbbc2 snd_card_file_add +EXPORT_SYMBOL vmlinux 0xfac41377 blk_init_tags +EXPORT_SYMBOL vmlinux 0xfac68eba arm_elf_read_implies_exec +EXPORT_SYMBOL vmlinux 0xfae25a3b nlmsg_notify +EXPORT_SYMBOL vmlinux 0xfaf01557 filp_open +EXPORT_SYMBOL vmlinux 0xfaf98462 bitrev32 +EXPORT_SYMBOL vmlinux 0xfb0cf2e9 touch_all_softlockup_watchdogs +EXPORT_SYMBOL vmlinux 0xfb1a8b5d set_device_ro +EXPORT_SYMBOL vmlinux 0xfb2b4deb register_sysrq_key +EXPORT_SYMBOL vmlinux 0xfb326a5d down +EXPORT_SYMBOL vmlinux 0xfb394c71 sock_no_poll +EXPORT_SYMBOL vmlinux 0xfb61feb0 file_remove_suid +EXPORT_SYMBOL vmlinux 0xfb6af58d recalc_sigpending +EXPORT_SYMBOL vmlinux 0xfb7d9c45 __udivsi3 +EXPORT_SYMBOL vmlinux 0xfb8a410d do_system_keystore_slot_dealloc +EXPORT_SYMBOL vmlinux 0xfbc2e0f0 try_to_free_buffers +EXPORT_SYMBOL vmlinux 0xfbc74f64 __copy_from_user +EXPORT_SYMBOL vmlinux 0xfbd3518a kmem_cache_alloc +EXPORT_SYMBOL vmlinux 0xfbf92453 param_get_bool +EXPORT_SYMBOL vmlinux 0xfc02b7ad sysctl_tcp_wmem +EXPORT_SYMBOL vmlinux 0xfc10c21d register_mtd_chip_driver +EXPORT_SYMBOL vmlinux 0xfc1c3afc sock_recvmsg +EXPORT_SYMBOL vmlinux 0xfc28a89a write_one_page +EXPORT_SYMBOL vmlinux 0xfc39e32f ioport_unmap +EXPORT_SYMBOL vmlinux 0xfc4537f3 textsearch_register +EXPORT_SYMBOL vmlinux 0xfc533f85 schedule_work_on +EXPORT_SYMBOL vmlinux 0xfc936601 sock_no_bind +EXPORT_SYMBOL vmlinux 0xfcaa04a0 out_of_line_wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0xfcb10464 iw_handler_get_spy +EXPORT_SYMBOL vmlinux 0xfcb42aa1 udp_ioctl +EXPORT_SYMBOL vmlinux 0xfcb7783d udp_lib_setsockopt +EXPORT_SYMBOL vmlinux 0xfcbd662b locks_remove_posix +EXPORT_SYMBOL vmlinux 0xfcda63a3 node_states +EXPORT_SYMBOL vmlinux 0xfcdd8cf6 param_get_ushort +EXPORT_SYMBOL vmlinux 0xfcec0987 enable_irq +EXPORT_SYMBOL vmlinux 0xfcf4dc15 fsl_shw_deregister_user +EXPORT_SYMBOL vmlinux 0xfcfa03ff fb_videomode_to_modelist +EXPORT_SYMBOL vmlinux 0xfd043431 scc_stop_monitoring_security_failure +EXPORT_SYMBOL vmlinux 0xfd5b5b0b ipu_csi_set_window_size +EXPORT_SYMBOL vmlinux 0xfd8c503f per_cpu__kstat +EXPORT_SYMBOL vmlinux 0xfd8dba4c add_wait_queue +EXPORT_SYMBOL vmlinux 0xfd8ea9ac neigh_seq_start +EXPORT_SYMBOL vmlinux 0xfd98879a rb_next +EXPORT_SYMBOL vmlinux 0xfd9ceb64 mxc_dma_start +EXPORT_SYMBOL vmlinux 0xfdab6de3 unregister_sound_midi +EXPORT_SYMBOL vmlinux 0xfdef24bb inet_dgram_ops +EXPORT_SYMBOL vmlinux 0xfdfb1d34 simple_rename +EXPORT_SYMBOL vmlinux 0xfdfc0b3b fiemap_fill_next_extent +EXPORT_SYMBOL vmlinux 0xfe098193 page_follow_link_light +EXPORT_SYMBOL vmlinux 0xfe16775f idr_destroy +EXPORT_SYMBOL vmlinux 0xfe271510 mutex_lock_killable +EXPORT_SYMBOL vmlinux 0xfe4b3b78 end_buffer_write_sync +EXPORT_SYMBOL vmlinux 0xfe50e3d3 tcf_em_unregister +EXPORT_SYMBOL vmlinux 0xfe5d4bb2 sys_tz +EXPORT_SYMBOL vmlinux 0xfe6e01fa should_remove_suid +EXPORT_SYMBOL vmlinux 0xfe769456 unregister_netdevice_notifier +EXPORT_SYMBOL vmlinux 0xfe813ead bd_claim +EXPORT_SYMBOL vmlinux 0xfe948aee cancel_dirty_page +EXPORT_SYMBOL vmlinux 0xfea15786 find_or_create_page +EXPORT_SYMBOL vmlinux 0xfeabf321 inode_set_bytes +EXPORT_SYMBOL vmlinux 0xfec0cc2f handle_sysrq +EXPORT_SYMBOL vmlinux 0xfec3c2f2 bcd2bin +EXPORT_SYMBOL vmlinux 0xfec541e5 arp_create +EXPORT_SYMBOL vmlinux 0xfed01b21 vfs_create +EXPORT_SYMBOL vmlinux 0xfedd35fc console_suspend_enabled +EXPORT_SYMBOL vmlinux 0xfeef2daa i2c_smbus_read_byte +EXPORT_SYMBOL vmlinux 0xfef96e23 __scsi_print_command +EXPORT_SYMBOL vmlinux 0xff0a934d __devm_release_region +EXPORT_SYMBOL vmlinux 0xff1e9dd8 seq_list_start +EXPORT_SYMBOL vmlinux 0xff667d5c kmem_cache_free +EXPORT_SYMBOL vmlinux 0xff67b37f __lshrdi3 +EXPORT_SYMBOL vmlinux 0xff6878cf fb_default_cmap +EXPORT_SYMBOL vmlinux 0xff9ca065 fb_edid_to_monspecs +EXPORT_SYMBOL vmlinux 0xff9f83fb dput +EXPORT_SYMBOL vmlinux 0xffbe2daa truncate_inode_pages +EXPORT_SYMBOL vmlinux 0xffd5a395 default_wake_function +EXPORT_SYMBOL vmlinux 0xffe8a523 xfrm_register_km +EXPORT_SYMBOL_GPL crypto/aes_generic 0x1381bf2d crypto_ft_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x22894d94 crypto_il_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5f943003 crypto_it_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5fe743de crypto_aes_expand_key +EXPORT_SYMBOL_GPL crypto/aes_generic 0x6e9cc2ba crypto_fl_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x991f3489 crypto_aes_set_key +EXPORT_SYMBOL_GPL crypto/async_tx/async_memcpy 0x74765193 async_memcpy +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x557868e8 async_tx_quiesce +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x63ba737b async_trigger_callback +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0xe709bfd3 async_tx_submit +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0xaee53441 async_xor_zero_sum +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0xfdcfd4dc async_xor +EXPORT_SYMBOL_GPL crypto/twofish_common 0x0b1af6c3 twofish_setkey +EXPORT_SYMBOL_GPL drivers/ata/pata_platform 0xc756fd99 __pata_platform_probe +EXPORT_SYMBOL_GPL drivers/ata/pata_platform 0xea67e528 __pata_platform_remove +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0x63147260 dm_disk +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0x6ec4476e dm_send_uevents +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0x9a675848 dm_put +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0xb7490a85 dm_noflush_suspending +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0xbe895d83 dm_set_device_limits +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0xc04d2ef2 dm_device_name +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0xefa4b451 dm_path_uevent +EXPORT_SYMBOL_GPL drivers/md/dm-multipath 0x577e27be dm_unregister_path_selector +EXPORT_SYMBOL_GPL drivers/md/dm-multipath 0xb26410df dm_register_path_selector +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x09c4a440 dm_rh_dec +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x0d62156e dm_rh_recovery_end +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x22d96513 dm_rh_update_states +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x28cfe423 dm_rh_flush +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x2ccdf034 dm_rh_region_context +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x390d38b1 dm_rh_start_recovery +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x54250113 dm_rh_dirty_log +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x5ee30a86 dm_rh_delay +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x5fdffc9b dm_rh_bio_to_region +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x685eacd9 dm_rh_recovery_start +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x77306501 dm_rh_region_to_sector +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x8b998b76 dm_rh_stop_recovery +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x9153495e dm_rh_inc_pending +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x997faa97 dm_rh_get_state +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x9ba8f42c dm_rh_recovery_prepare +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x9e7bc895 dm_rh_recovery_in_flight +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xbc293903 dm_region_hash_create +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xced1dd78 dm_rh_get_region_key +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xd27d8baa dm_rh_mark_nosync +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xe53f93cb dm_rh_get_region_size +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xfc2b5c69 dm_region_hash_destroy +EXPORT_SYMBOL_GPL drivers/md/md-mod 0x13b3d49c md_allow_write +EXPORT_SYMBOL_GPL drivers/md/md-mod 0x34778686 sync_page_io +EXPORT_SYMBOL_GPL drivers/md/md-mod 0x55b61e18 md_do_sync +EXPORT_SYMBOL_GPL drivers/md/md-mod 0xc54389f8 md_new_event +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x04662e0f ir_codes_fusionhdtv_mce +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x07e92917 ir_codes_avermedia_a16d +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x083661f9 ir_codes_avertv_303 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x088631b9 ir_codes_behold +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x1cb148f5 ir_extract_bits +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2456e513 ir_decode_pulsedistance +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2a4852cc ir_codes_dntv_live_dvb_t +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2af1a608 ir_codes_proteus_2309 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2e6a78e7 ir_input_keydown +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x3811daea ir_codes_manli +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x43c89ef4 ir_decode_biphase +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x45b08f68 ir_codes_pinnacle_grey +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4740e7a3 ir_codes_empty +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4beb7618 ir_codes_encore_enltv_fm53 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4ea698a2 ir_codes_purpletv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x55338dda ir_codes_pixelview_new +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x589cad50 ir_codes_apac_viewcomp +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x5db13554 ir_codes_encore_enltv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6606596a ir_rc5_timer_keyup +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6adc476d ir_codes_powercolor_real_angel +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6aefdbea ir_codes_npgtech +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6b87c69d ir_codes_iodata_bctv7e +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6d6511e7 ir_dump_samples +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6e2a1870 ir_codes_adstech_dvb_t_pci +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6eaff03d ir_input_nokey +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x7277973d ir_codes_pctv_sedna +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x75e89cc3 ir_codes_flydvb +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x772a30a2 ir_codes_nebula +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x7b38143b ir_codes_encore_enltv2 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x85d37490 ir_codes_dntv_live_dvbt_pro +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x89cc1189 ir_codes_winfast +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x902a3cd2 ir_codes_hauppauge_new +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x933d0bb3 ir_codes_msi_tvanywhere +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x9451e232 ir_codes_behold_columbus +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x96470cab ir_codes_cinergy +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb1f4eb35 ir_codes_avermedia_dvbt +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb50812de ir_codes_real_audio_220_32_keys +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb6cd4666 ir_codes_eztv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xbb08d146 ir_codes_msi_tvanywhere_plus +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xbdce6594 ir_codes_tt_1500 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc1fea0c1 ir_codes_pv951 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc42bd037 ir_codes_budget_ci_old +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc6c5a7a1 ir_codes_em_terratec +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xcdf2859f ir_codes_avermedia_m135a +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd1e0258a ir_codes_flyvideo +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd3bfee77 ir_input_init +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd55e6891 ir_codes_gotview7135 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd9c7f010 ir_codes_rc5_tv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xdaa041ad ir_codes_cinergy_1400 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xdfcf23df ir_codes_norwood +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xee2f5e0e ir_codes_pinnacle_pctv_hd +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf07533a1 ir_codes_videomate_tv_pvr +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf0fc9374 ir_codes_avermedia +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf2b421aa ir_codes_genius_tvgo_a11mce +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf4f7a4d6 ir_rc5_timer_end +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfa177653 ir_codes_pixelview +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfb981300 ir_codes_pinnacle_color +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfc54a5cd ir_codes_asus_pc39 +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda18271 0x55b37afe tda18271_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda827x 0x6802f0b6 tda827x_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda8290 0x0ee401ed tda829x_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda8290 0xbd459f87 tda829x_probe +EXPORT_SYMBOL_GPL drivers/media/video/compat_ioctl32 0x8ef3f5c0 v4l_compat_ioctl32 +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x34147a28 em28xx_set_mode +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x52a65d79 em28xx_init_isoc +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x5c9feb14 em28xx_uninit_isoc +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x61832e83 em28xx_audio_analog_set +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x7fc8652c em28xx_tuner_callback +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0x1b4b8f35 v4l2_int_device_register +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0x686a871a v4l2_int_device_unregister +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xa5228b24 v4l2_int_device_try_attach_all +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xbeb10caf v4l2_int_ioctl_0 +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xe66812c9 v4l2_int_ioctl_1 +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x08ac1794 videobuf_next_field +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x1521ad33 videobuf_waiton +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x2fd29b53 videobuf_poll_stream +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x575e1a94 videobuf_queue_to_vmalloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x68f955b5 videobuf_mmap_mapper +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x6d25929a __videobuf_mmap_setup +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x6e32134c videobuf_stop +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x73606fd8 videobuf_streamoff +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x87cdb731 videobuf_mmap_setup +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x8c30f38f videobuf_streamon +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x9d6cbc61 videobuf_alloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xa5a3fd5d videobuf_qbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xa90fbb90 videobuf_queue_core_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xb7e8e6d0 videobuf_queue_cancel +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xb7f014cb videobuf_querybuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xb9ad0384 videobuf_dqbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xc07b762d videobuf_queue_is_busy +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xc6c71f64 videobuf_mmap_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xd2c41b6b videobuf_read_stream +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xdedbe3ee videobuf_cgmbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xe4d08bbe videobuf_read_stop +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xf45445b5 videobuf_read_one +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xf5e1b175 videobuf_read_start +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xfc982550 videobuf_reqbufs +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xfd921f7e videobuf_iolock +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0x3587f373 videobuf_to_vmalloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0x46f09f01 videobuf_vmalloc_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0x4df184a4 videobuf_queue_vmalloc_init +EXPORT_SYMBOL_GPL drivers/misc/eeprom_93cx6 0x2df115d4 eeprom_93cx6_multiread +EXPORT_SYMBOL_GPL drivers/misc/eeprom_93cx6 0x63d14d2f eeprom_93cx6_read +EXPORT_SYMBOL_GPL drivers/mtd/onenand/onenand 0xced6337c onenand_scan +EXPORT_SYMBOL_GPL drivers/mtd/onenand/onenand 0xdaab80e9 onenand_release +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x1179182d ubi_leb_unmap +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x156372d0 ubi_leb_map +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x42801d20 ubi_sync +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x6e258f9c ubi_open_volume_nm +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x7316d1da ubi_leb_read +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x9372f944 ubi_leb_erase +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xbc505df4 ubi_get_device_info +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xd2e033d8 ubi_get_volume_info +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xdf4df4a0 ubi_leb_write +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xebeea474 ubi_open_volume +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xed17d5c8 ubi_is_mapped +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xf0152821 ubi_close_volume +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xfe719624 ubi_leb_change +EXPORT_SYMBOL_GPL drivers/net/usb/cdc_ether 0x376a24ff usbnet_generic_cdc_bind +EXPORT_SYMBOL_GPL drivers/net/usb/cdc_ether 0xf4324f27 usbnet_cdc_unbind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x4243c65b rndis_rx_fixup +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x4d454143 rndis_status +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x7132b89d rndis_command +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x893f8fa7 rndis_tx_fixup +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xc33619f0 rndis_unbind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xe45eb0b6 generic_rndis_bind +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x18607f5a usbnet_unlink_rx_urbs +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x312008fb usbnet_get_drvinfo +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x412cd70b usbnet_resume +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x49e78aaf usbnet_set_settings +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x4d3a1927 usbnet_set_msglevel +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x57d2ac4a usbnet_defer_kevent +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x5b338a10 usbnet_get_link +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x6af720e9 usbnet_skb_return +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x7384387b usbnet_probe +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x9487e849 usbnet_suspend +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x9e1d0fba usbnet_disconnect +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xb04ba951 usbnet_get_msglevel +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xbe844263 usbnet_get_settings +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xd1c44549 usbnet_get_endpoints +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xd4c4d6fd usbnet_nway_reset +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x11d72394 lbs_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x266b716b lbs_notify_command_response +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x322ddcb8 lbs_process_rxed_packet +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x7a1883ef lbs_host_sleep_cfg +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x81c8f606 lbs_cmd_802_11_rate_adapt_rateset +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x89decca5 lbs_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x8a767e8f lbs_remove_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x903118ff lbs_add_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xa1ab983a lbs_start_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xb8d63b50 __lbs_cmd +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xbd2032de lbs_send_tx_feedback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xbe2a3f2e lbs_cmd_copyback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xd4381450 lbs_host_to_card_done +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xee05a1e0 lbs_stop_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xf64277de lbs_debug +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xfa17a728 lbs_queue_event +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x0e90b711 lbtf_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x3e53be31 __lbtf_cmd +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x92b8e13e lbtf_bcn_sent +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xafe7faed lbtf_cmd_response_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xbd62151c lbtf_remove_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xce8150df lbtf_cmd_copyback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xd38ad344 lbtf_add_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xf3537e67 lbtf_send_tx_feedback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf_usb 0x3e241d1c if_usb_reset_device +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf_usb 0x981550fc if_usb_prog_firmware +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x0b4bedb1 rt2x00lib_probe_dev +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x1d9b5149 rt2x00mac_add_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x1f677980 rt2x00lib_rxdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x2f8bf81a rt2x00lib_remove_dev +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x38f5e762 rt2x00mac_set_key +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x3ef0e61d rt2x00mac_conf_tx +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x4cfff648 rt2x00mac_get_stats +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x65d5ef93 rt2x00queue_get_entry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x6cfb6339 rt2x00mac_stop +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x7c0b3a6d rt2x00lib_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x8ab40af0 rt2x00lib_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x8c7671d8 rt2x00mac_config_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x8f2766a1 rt2x00mac_config +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x9739d863 rt2x00mac_bss_info_changed +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xa9d38176 rt2x00queue_map_txskb +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xab994917 rt2x00lib_beacondone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xcd7fd0f4 rt2x00lib_txdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xd84241f6 rt2x00queue_get_queue +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xdcb4c8a6 rt2x00mac_configure_filter +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xdf17d177 rt2x00mac_remove_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xe661b23a rt2x00mac_start +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xfe329e2e rt2x00mac_tx +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xffd7925f rt2x00mac_get_tx_stats +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x010b775a rt2x00usb_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x074cf9a3 rt2x00usb_probe +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x199ecca8 rt2x00usb_vendor_request_large_buff +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x41141b9c rt2x00usb_disconnect +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x43c1a7a5 rt2x00usb_uninitialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x487eb1be rt2x00usb_initialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x50ba10e3 rt2x00usb_write_tx_data +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x61d5d773 rt2x00usb_kick_tx_queue +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x6c093bf5 rt2x00usb_init_txentry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x92ca9a53 rt2x00usb_vendor_req_buff_lock +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xac2b1fc5 rt2x00usb_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xaff0bb42 rt2x00usb_vendor_request +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xcf1dbf97 rt2x00usb_init_rxentry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xe4556204 rt2x00usb_disable_radio +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xee5a88e8 rt2x00usb_vendor_request_buff +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x20323545 scsi_tgt_cmd_to_host +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x5d77bfd9 scsi_tgt_tsk_mgmt_request +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x70819f42 scsi_tgt_queue_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x71e68e7a scsi_tgt_free_queue +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x7928d6c7 scsi_tgt_alloc_queue +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xa9c0cb50 scsi_host_get_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xdb247722 scsi_tgt_it_nexus_destroy +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xe106c174 scsi_host_put_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xee1f1eb7 scsi_tgt_it_nexus_create +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x09ba7fb3 usb_ftdi_elan_edset_flush +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x3527c6a4 usb_ftdi_elan_edset_empty +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x6c4e5d23 usb_ftdi_elan_edset_single +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x8017eb42 usb_ftdi_elan_read_pcimem +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x812815d6 ftdi_elan_gone_away +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x88ebdb25 usb_ftdi_elan_edset_setup +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xafdfa66b usb_ftdi_elan_edset_input +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xb771c6dd usb_ftdi_elan_write_pcimem +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xebc63cb6 usb_ftdi_elan_edset_output +EXPORT_SYMBOL_GPL drivers/usb/misc/phidget 0xda681f31 phidget_class +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0x260be22a ezusb_writememory +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0x554ab986 usb_serial_deregister +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0x5db5305b usb_serial_generic_open +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0x8d2e0340 usb_serial_generic_read_bulk_callback +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0x97b70fd0 usb_serial_register +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0xa547a662 usb_serial_generic_write_bulk_callback +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0xac5c3829 usb_serial_port_softint +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0xbbbb92d9 ezusb_set_reset +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0xbdea28f7 usb_serial_disconnect +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0xe63faca8 usb_serial_probe +EXPORT_SYMBOL_GPL drivers/w1/wire 0x0021a2e6 w1_read_block +EXPORT_SYMBOL_GPL drivers/w1/wire 0x24edc1b2 w1_reset_bus +EXPORT_SYMBOL_GPL drivers/w1/wire 0x7bf04324 w1_write_8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0x7c2f2afb w1_calc_crc8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0xb7044168 w1_reset_select_slave +EXPORT_SYMBOL_GPL drivers/w1/wire 0xc99adbe5 w1_write_block +EXPORT_SYMBOL_GPL drivers/w1/wire 0xec04ec8f w1_read_8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0xfe9d243b w1_next_pullup +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x9321df95 dlm_lock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xa235fb37 dlm_posix_unlock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xad8af60a dlm_posix_lock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xcf9f3328 dlm_release_lockspace +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xd3dff67d dlm_posix_get +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xdc583c08 dlm_unlock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xdf3c14de dlm_new_lockspace +EXPORT_SYMBOL_GPL fs/exportfs/exportfs 0x44a8d2c8 exportfs_encode_fh +EXPORT_SYMBOL_GPL fs/exportfs/exportfs 0x4740ce37 exportfs_decode_fh +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x17ce645d locks_end_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x1a618932 nlmsvc_unlock_all_by_ip +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x283d002e nlmsvc_unlock_all_by_sb +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x6f959b35 locks_in_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x9260baed nlmclnt_proc +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x96877ac4 locks_start_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0xab37c7eb nlmclnt_init +EXPORT_SYMBOL_GPL fs/lockd/lockd 0xb33782fe nlmclnt_done +EXPORT_SYMBOL_GPL lib/lzo/lzo_compress 0x56b63670 lzo1x_1_compress +EXPORT_SYMBOL_GPL lib/lzo/lzo_decompress 0xf30fda27 lzo1x_decompress_safe +EXPORT_SYMBOL_GPL net/802/garp 0x43b79d5c garp_request_join +EXPORT_SYMBOL_GPL net/802/garp 0x86770113 garp_register_application +EXPORT_SYMBOL_GPL net/802/garp 0x86f75c40 garp_unregister_application +EXPORT_SYMBOL_GPL net/802/garp 0xab5a62f9 garp_uninit_applicant +EXPORT_SYMBOL_GPL net/802/garp 0xbb2f67b3 garp_init_applicant +EXPORT_SYMBOL_GPL net/802/garp 0xc224a674 garp_request_leave +EXPORT_SYMBOL_GPL net/802/stp 0xc6055df1 stp_proto_unregister +EXPORT_SYMBOL_GPL net/802/stp 0xfa325b6f stp_proto_register +EXPORT_SYMBOL_GPL net/bluetooth/bluetooth 0x6943b09c bt_class +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x0627e3ae tfrc_tx_hist_add +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x06b6b291 tfrc_rx_hist_sample_rtt +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x0a487ea5 tfrc_calc_x +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x13b7fc44 tfrc_rx_hist_add_packet +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x1f58bdae tfrc_tx_hist_rtt +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x44443863 tfrc_rx_hist_duplicate +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x6c252d29 tfrc_calc_x_reverse_lookup +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x7393ae09 tfrc_lh_interval_add +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x8807aa35 tfrc_rx_hist_alloc +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x8dd3af8f tfrc_rx_hist_purge +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x902206f0 tfrc_lh_cleanup +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x9c2d0314 tfrc_rx_handle_loss +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xb90cf12c tfrc_tx_hist_purge +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xf30a7c0c tfrc_lh_update_i_mean +EXPORT_SYMBOL_GPL net/dccp/dccp 0x0553eb06 ccid_hc_rx_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0x0b26ec38 dccp_getsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x0eea6ad7 dccp_make_response +EXPORT_SYMBOL_GPL net/dccp/dccp 0x1510cc52 dccp_hashinfo +EXPORT_SYMBOL_GPL net/dccp/dccp 0x1668afb1 dccp_destroy_sock +EXPORT_SYMBOL_GPL net/dccp/dccp 0x168b5391 dccp_insert_option_timestamp +EXPORT_SYMBOL_GPL net/dccp/dccp 0x1d6a63ed dccp_recvmsg +EXPORT_SYMBOL_GPL net/dccp/dccp 0x1d99d49a dccp_timestamp +EXPORT_SYMBOL_GPL net/dccp/dccp 0x231a9d67 dccp_reqsk_init +EXPORT_SYMBOL_GPL net/dccp/dccp 0x25ac00ea dccp_send_sync +EXPORT_SYMBOL_GPL net/dccp/dccp 0x2a859910 dccp_feat_change_recv +EXPORT_SYMBOL_GPL net/dccp/dccp 0x364ec239 dccp_shutdown +EXPORT_SYMBOL_GPL net/dccp/dccp 0x37942a56 ccid_register +EXPORT_SYMBOL_GPL net/dccp/dccp 0x3b3c0b1b dccp_feat_clean +EXPORT_SYMBOL_GPL net/dccp/dccp 0x403ace78 dccp_connect +EXPORT_SYMBOL_GPL net/dccp/dccp 0x455746ed dccp_init_sock +EXPORT_SYMBOL_GPL net/dccp/dccp 0x4da08392 dccp_disconnect +EXPORT_SYMBOL_GPL net/dccp/dccp 0x4eabe141 dccp_feat_confirm_recv +EXPORT_SYMBOL_GPL net/dccp/dccp 0x56ea266a dccp_state_name +EXPORT_SYMBOL_GPL net/dccp/dccp 0x578523e3 dccp_close +EXPORT_SYMBOL_GPL net/dccp/dccp 0x5e994fe0 ccid_hc_tx_delete +EXPORT_SYMBOL_GPL net/dccp/dccp 0x70536d02 dccp_create_openreq_child +EXPORT_SYMBOL_GPL net/dccp/dccp 0x86be7924 dccp_packet_name +EXPORT_SYMBOL_GPL net/dccp/dccp 0x86dc1c89 dccp_ioctl +EXPORT_SYMBOL_GPL net/dccp/dccp 0x887289b0 dccp_sendmsg +EXPORT_SYMBOL_GPL net/dccp/dccp 0x89019120 dccp_setsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8b7d8caf dccp_statistics +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8cb3498f dccp_orphan_count +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8da82544 dccp_rcv_state_process +EXPORT_SYMBOL_GPL net/dccp/dccp 0x906105ee ccid_hc_tx_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0x916af9ac dccp_insert_option +EXPORT_SYMBOL_GPL net/dccp/dccp 0x9fe5c436 dccp_rcv_established +EXPORT_SYMBOL_GPL net/dccp/dccp 0xa61d35b3 inet_dccp_listen +EXPORT_SYMBOL_GPL net/dccp/dccp 0xaa1b28aa dccp_death_row +EXPORT_SYMBOL_GPL net/dccp/dccp 0xaab5ac0b dccp_check_req +EXPORT_SYMBOL_GPL net/dccp/dccp 0xb95d7ca3 dccp_set_state +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbe4cf010 dccp_feat_init +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbeccbc4a dccp_sample_rtt +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbf6b58ba dccp_feat_change +EXPORT_SYMBOL_GPL net/dccp/dccp 0xc2cb3a92 dccp_insert_option_elapsed_time +EXPORT_SYMBOL_GPL net/dccp/dccp 0xc33140f9 dccp_child_process +EXPORT_SYMBOL_GPL net/dccp/dccp 0xca97f67c ccid_hc_rx_delete +EXPORT_SYMBOL_GPL net/dccp/dccp 0xcace07a5 dccp_parse_options +EXPORT_SYMBOL_GPL net/dccp/dccp 0xcad4c13e dccp_send_ack +EXPORT_SYMBOL_GPL net/dccp/dccp 0xcc4c07da dccp_poll +EXPORT_SYMBOL_GPL net/dccp/dccp 0xcdfdef51 ccid_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0xd1976fae ccid_unregister +EXPORT_SYMBOL_GPL net/dccp/dccp 0xd26413c2 dccp_done +EXPORT_SYMBOL_GPL net/dccp/dccp 0xd2ebc14e dccp_feat_clone +EXPORT_SYMBOL_GPL net/dccp/dccp 0xd3999da6 dccp_sync_mss +EXPORT_SYMBOL_GPL net/dccp/dccp 0xd821ab67 dccp_reqsk_send_ack +EXPORT_SYMBOL_GPL net/dccp/dccp 0xf8a1e582 dccp_ctl_make_reset +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x03de4c37 dccp_v4_do_rcv +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x4953cf28 dccp_v4_conn_request +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x6685ce45 dccp_v4_send_check +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x9abefd7a dccp_invalid_packet +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0xa676d3db dccp_v4_connect +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0xba0ddeba dccp_v4_request_recv_sock +EXPORT_SYMBOL_GPL net/ipv4/inet_diag 0x3aa09363 inet_diag_unregister +EXPORT_SYMBOL_GPL net/ipv4/inet_diag 0x812d042a inet_diag_register +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_conntrack_ipv4 0x6d40a921 need_ipv4_conntrack +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_conntrack_ipv4 0xad48e726 nf_nat_seq_adjust_hook +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_defrag_ipv4 0x6b6c3d10 nf_defrag_ipv4_enable +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x07ae60b6 nf_nat_proto_in_range +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x0b471a10 nf_nat_proto_find_get +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x234299f2 nf_nat_packet +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x407ef1be nf_nat_proto_unique_tuple +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x8087e798 nf_nat_proto_put +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x94a08134 nf_nat_proto_nlattr_to_range +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0xc84df01d nf_nat_proto_range_to_nlattr +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0xf639a38b nf_nat_icmp_reply_translation +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat_proto_gre 0x636b12c8 nf_nat_need_gre +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x024257e7 ip6_local_out +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x067605f7 fl6_sock_lookup +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x08a3e5d1 net_ipv6_ctl_path +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x120034ec ip6_sk_dst_lookup +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x141dc677 inet6_csk_search_req +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x23c98a97 inet6_sk_rebuild_header +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x278c87f7 inet6_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x7573bbae ipv6_find_tlv +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x7657f1c2 ipv6_opt_accepted +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x7d4eebd7 inet6_csk_bind_conflict +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x85478a0b inet6_hash_frag +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0xa2a46bf3 ip6_dst_lookup +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0xa4c0bc93 inet6_csk_xmit +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0xb6138500 inet6_destroy_sock +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0xe056ebf2 ipv6_dup_options +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0xf0953026 ip6_dst_blackhole +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0xf540e774 inet6_csk_addr2sockaddr +EXPORT_SYMBOL_GPL net/mac80211/mac80211 0x7f997805 ieee80211_iterate_active_interfaces_atomic +EXPORT_SYMBOL_GPL net/mac80211/mac80211 0xe19c47c2 ieee80211_iterate_active_interfaces +EXPORT_SYMBOL_GPL net/netfilter/ipvs/ip_vs 0xe6476b4a net_vs_ctl_path +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x02c77069 nf_conntrack_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x045072cd nf_ct_port_nla_policy +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x0491a658 print_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x0ecaa01d nf_ct_iterate_cleanup +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x1283d711 nf_ct_expect_unregister_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x14b4f27e nf_ct_remove_expectations +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x15c10b0b nf_conntrack_unregister_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x1c7f6306 nf_ct_helper_ext_add +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x2a695671 nf_conntrack_tuple_taken +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x31860958 nf_ct_invert_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3933e80d __nf_ct_refresh_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3f5b1415 nf_ct_port_nlattr_to_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x4323a400 nf_conntrack_chain +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x452d460f __nf_ct_expect_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x4a20abe8 nf_conntrack_l4proto_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x4a497102 __nf_ct_helper_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x4ab99af9 __nf_conntrack_confirm +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x518b5b24 nf_conntrack_l4proto_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x5ddfa52f nfnetlink_parse_nat_setup_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x5eb040ca nf_ct_l4proto_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x62a17298 nf_conntrack_l3proto_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x69d1fb57 nf_conntrack_in +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x6c32b9e9 nf_conntrack_free +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x6e224a7a need_conntrack +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x735a17c3 nf_ct_l3protos +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x78f9b710 nf_ct_l3proto_try_module_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x7bd75bab nf_ct_l3proto_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x805293a8 nf_conntrack_l4proto_tcp6 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x871878b8 nf_ct_expect_init +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x8e536bff nf_conntrack_l4proto_udp4 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x8ffe7e89 nf_conntrack_htable_size +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x90ff6c9f nf_ct_invert_tuplepr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x9406fb5b nf_conntrack_alloc +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x9790b655 __nf_ct_event_cache_init +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x9a5d1477 __nf_ct_l4proto_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x9c453c75 __nf_conntrack_helper_find_byname +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa38558d0 __nf_ct_kill_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa3edd525 nf_ct_unexpect_related +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa5332c7a nf_ct_l4proto_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa6f62ec0 nf_conntrack_set_hashsize +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa82df195 nf_ct_expect_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb264f12a nf_conntrack_l4proto_tcp4 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb555b5bd nf_conntrack_helper_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb602c57e nf_ct_l3proto_module_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xba147d47 nf_conntrack_untracked +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbc65097d nf_conntrack_l4proto_udp6 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbc887e16 nf_ct_expect_register_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc044befe nf_ct_free_hashtable +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc0c8d9ff nf_conntrack_hash_insert +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc18ac88d nf_ct_expect_hsize +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc39ffac8 nf_ct_extend_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc55a6e1f nf_ct_extend_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xcbf7fd2a nf_conntrack_register_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xcc4aa03c nf_conntrack_helper_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xcd11feff nf_conntrack_l3proto_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd3c987f3 nf_ct_l3proto_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd50a96a2 nf_ct_alloc_hashtable +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd7ea4e9e seq_print_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd9dc7751 nf_ct_get_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd9f9a3ab nf_conntrack_flush +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xdbd079a9 nf_ct_deliver_cached_events +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xdbef8b57 nf_conntrack_lock +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xdf34401b nf_ct_expect_alloc +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xe7ae2355 nf_ct_get_tuplepr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xe92c9d66 nf_conntrack_alter_reply +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf098dd0e nf_ct_port_tuple_to_nlattr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf3e4164b nf_ct_expect_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf6a73d95 nf_conntrack_tcp_update +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf804fd61 nf_conntrack_l3proto_generic +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf9ae81a1 nf_conntrack_max +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf9b3f06d nf_ct_expect_chain +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfa658bb6 nf_ct_expect_related +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfaed9b40 __nf_conntrack_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfbb12a08 nf_ct_unlink_expect +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_amanda 0xfd8258ee nf_nat_amanda_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_ftp 0xc7f0cc86 nf_nat_ftp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x04644f3b set_sig_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x0a3e61ab nat_t120_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x208a5f05 nat_h245_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x24d446fd nat_q931_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x3478f296 set_h225_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x36f22718 set_ras_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x5e77445a get_h225_addr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x94102279 set_h245_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x9e22ff51 nat_callforwarding_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xea50cc30 nat_rtp_rtcp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_irc 0xeaea1949 nf_nat_irc_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x2a0eb831 nf_nat_pptp_hook_outbound +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x2e2525bf nf_nat_pptp_hook_expectfn +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x7b69dd14 nf_nat_pptp_hook_exp_gre +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0xaa8ebef3 nf_nat_pptp_hook_inbound +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_proto_gre 0x7e02766c nf_ct_gre_keymap_add +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_proto_gre 0xeef7aa99 nf_ct_gre_keymap_destroy +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x0cd5cbd0 nf_nat_sdp_session_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x16927cb5 nf_nat_sip_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x31f69c45 ct_sip_parse_address_param +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x81edf527 nf_nat_sip_expect_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x839e47c1 ct_sip_parse_header_uri +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xa5fa5f13 ct_sip_parse_numerical_param +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xa905dfa4 nf_nat_sdp_media_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xaeffdeab ct_sip_get_sdp_header +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xc239ccef ct_sip_get_header +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xda23410b nf_nat_sdp_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xfecb3403 ct_sip_parse_request +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xffe49e29 nf_nat_sdp_port_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_tftp 0xa61d8a0f nf_nat_tftp_hook +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x0de5895c nfnetlink_send +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x1f58e71b nfnl_lock +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x369bb9a7 nfnetlink_subsys_unregister +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x3895cd7a nfnl_unlock +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x792d3a4d nfnetlink_unicast +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xe3d698c5 nfnetlink_subsys_register +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xeca95329 nfnetlink_has_listeners +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x0c12530b xt_find_table_lock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x398925ad xt_register_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x40728a63 xt_find_revision +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x526d5c83 xt_proto_init +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x7f91b409 xt_replace_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x9348fc05 xt_proto_fini +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xab355de9 xt_request_find_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xc2c4af3a xt_check_match +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xf61a4e4e xt_check_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xfb1283f7 xt_table_unlock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xfba76cd2 xt_unregister_table +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0x01ca27cf xt_rateest_lookup +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0xe62aee08 xt_rateest_put +EXPORT_SYMBOL_GPL net/rfkill/rfkill 0x83b2e956 register_rfkill_notifier +EXPORT_SYMBOL_GPL net/rfkill/rfkill 0x86c722f8 rfkill_epo +EXPORT_SYMBOL_GPL net/rfkill/rfkill 0xa6f4320d unregister_rfkill_notifier +EXPORT_SYMBOL_GPL net/rfkill/rfkill 0xf972e196 rfkill_restore_states +EXPORT_SYMBOL_GPL net/rfkill/rfkill 0xfcce694c rfkill_set_default +EXPORT_SYMBOL_GPL net/rxrpc/af-rxrpc 0x4ca1ae66 rxrpc_register_security +EXPORT_SYMBOL_GPL net/rxrpc/af-rxrpc 0xb0d16144 rxrpc_unregister_security +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x0145b72c xprt_release_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x045676c1 rpc_exit_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x06bbfd3b rpcauth_register +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x07560c4c rpc_call_async +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x0c525099 xprt_release_xprt_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x0c5b48ce rpc_call_start +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x14e13027 rpc_sleep_on +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1a1a1e73 rpc_setbufsize +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1bbc53a5 rpc_max_payload +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2062e9bf rpc_peeraddr2str +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x25a8de2e xprt_unregister_transport +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x296e74a2 rpc_killall_tasks +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x29f38228 rpc_restart_call +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2aa17774 rpc_free_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2af71196 rpcauth_init_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x31a89d59 rpc_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3239dfa4 rpc_wake_up_status +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x32854af4 xprt_update_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x35cf63ff rpc_init_wait_queue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x371c309c xprt_register_transport +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x38c33e4e rpc_lookup_machine_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x45657b78 rpc_wake_up +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x4869d9c7 xprt_lookup_rqst +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x4b6975cc xdr_skb_read_bits +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x4dbc88a1 rpc_put_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x502b8ffa rpc_clone_client +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x51580bce xdr_partial_copy_from_skb +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x53445f68 nlm_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5bd26000 rpc_proc_unregister +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5ea3740b rpc_alloc_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x658a78f8 svc_reg_xprt_class +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x65dceb9e xprt_complete_rqst +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6826892e rpc_bind_new_program +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6b2dcfde svc_xprt_names +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6c5304c5 rpcb_getport_sync +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6cba6af7 xprt_reserve_xprt_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6f9421e0 svc_xprt_init +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7418ce00 xprt_write_space +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x77687643 svc_print_addr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x79f2fdeb __rpc_wait_for_completion_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7de53067 rpc_init_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7f4fe586 rpcauth_destroy_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x80939b5d svc_close_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x85075cd8 xprt_reserve_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x86002523 rpcauth_generic_bind_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8cb46933 csum_partial_copy_to_xdr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8e109a09 svc_xprt_enqueue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8e73ac9e rpc_proc_register +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x9044b21f xprt_disconnect_done +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x9400f49a rpc_shutdown_client +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x9852be22 xprt_release_rqst_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x993e76fe rpcauth_lookup_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x9e344061 rpc_create +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x9e661e1a rpc_wake_up_queued_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x9ed1524e rpc_print_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xa1c108d8 svc_addsock +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xa70b90d8 rpc_call_sync +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xaab19124 rpc_run_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xacc9282b svc_xprt_copy_addrs +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xaf5bf6ef nfs_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb9f1db09 svc_unreg_xprt_class +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbb34a813 svc_xprt_received +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbc159390 svc_create_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbf9d1b96 nfsd_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc12435e3 rpc_calc_rto +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc36deb8c rpc_peeraddr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc4158a65 rpcb_getport_async +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc4d577c2 svc_max_payload +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xcaf1f59c rpcauth_create +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xcb68b613 rpcauth_init_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xcc3188c1 xprt_set_retrans_timeout_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd1d06d35 xprt_wait_for_buffer_space +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd260da2b xprt_adjust_cwnd +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd5f2252b rpc_call_null +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd7989952 svc_xprt_put +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xda979895 rpc_delay +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xdb668d53 xprt_wake_pending_tasks +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe4f7c74e svc_find_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xeac19478 rpc_force_rebind +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xeb00a48b rpc_wake_up_next +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xeb9c16df put_rpccred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xeeacab69 rpc_update_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xef233ba3 rpc_destroy_wait_queue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xf6a36524 xprt_set_retrans_timeout_def +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xf9d1164c rpc_free +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xfc0936d3 rpcauth_unregister +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xfc849577 rpc_malloc +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xfde8b5be rpc_lookup_cred +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0x4600200e ipcomp_init_state +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0x6ca4e456 ipcomp_output +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0x982c233f ipcomp_input +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0xb824c61d ipcomp_destroy +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x1584fdb9 tlsf_destroy_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x42a50f11 tlsf_malloc +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x66da3d8f tlsf_create_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xe6acc368 tlsf_free +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xee6c65c9 tlsf_get_used_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xeec8caeb tlsf_get_total_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xf9805f1b tlsf_calloc +EXPORT_SYMBOL_GPL vmlinux 0x00566d8f inotify_get_cookie +EXPORT_SYMBOL_GPL vmlinux 0x0067df75 ata_tf_from_fis +EXPORT_SYMBOL_GPL vmlinux 0x006af71c regulator_bulk_get +EXPORT_SYMBOL_GPL vmlinux 0x00ebcb5d ata_id_string +EXPORT_SYMBOL_GPL vmlinux 0x00fb7419 fat_alloc_new_dir +EXPORT_SYMBOL_GPL vmlinux 0x0100c51a relay_file_operations +EXPORT_SYMBOL_GPL vmlinux 0x01380cf9 sysdev_show_ulong +EXPORT_SYMBOL_GPL vmlinux 0x0188ce36 blk_update_request +EXPORT_SYMBOL_GPL vmlinux 0x01a4ea6d unregister_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x01cbea8b alloc_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x01fd453e usbhid_lookup_quirk +EXPORT_SYMBOL_GPL vmlinux 0x02615b99 attribute_container_unregister +EXPORT_SYMBOL_GPL vmlinux 0x02a2614b platform_device_add_resources +EXPORT_SYMBOL_GPL vmlinux 0x02c3d9bd blkcipher_walk_virt_block +EXPORT_SYMBOL_GPL vmlinux 0x02ccea56 lock_policy_rwsem_write +EXPORT_SYMBOL_GPL vmlinux 0x02ff2bbe tcp_get_info +EXPORT_SYMBOL_GPL vmlinux 0x0343bdf1 __i2c_board_list +EXPORT_SYMBOL_GPL vmlinux 0x03e3686c ata_timing_cycle2mode +EXPORT_SYMBOL_GPL vmlinux 0x03ef30cd sysctl_pathname +EXPORT_SYMBOL_GPL vmlinux 0x043bf506 blk_abort_request +EXPORT_SYMBOL_GPL vmlinux 0x04486e88 rcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x046b9dc7 tty_ldisc_ref_wait +EXPORT_SYMBOL_GPL vmlinux 0x0531dcb8 ata_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0x0533054f inet_csk_clone +EXPORT_SYMBOL_GPL vmlinux 0x0548560a ata_port_desc +EXPORT_SYMBOL_GPL vmlinux 0x054e550b kernel_halt +EXPORT_SYMBOL_GPL vmlinux 0x056c3e0f securityfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x059c2395 __get_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x06178a52 register_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0x061c9967 devm_kzalloc +EXPORT_SYMBOL_GPL vmlinux 0x06406452 platform_get_resource_byname +EXPORT_SYMBOL_GPL vmlinux 0x064db9a5 mark_mounts_for_expiry +EXPORT_SYMBOL_GPL vmlinux 0x067e8f1f sysfs_create_link +EXPORT_SYMBOL_GPL vmlinux 0x06837f59 audit_log_vformat +EXPORT_SYMBOL_GPL vmlinux 0x0690a022 get_mtd_device_nm +EXPORT_SYMBOL_GPL vmlinux 0x0694a3e5 single_release_net +EXPORT_SYMBOL_GPL vmlinux 0x06d222f8 device_resume +EXPORT_SYMBOL_GPL vmlinux 0x06d97296 tcp_register_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0x070bb13b crypto_drop_spawn +EXPORT_SYMBOL_GPL vmlinux 0x0746db16 device_attach +EXPORT_SYMBOL_GPL vmlinux 0x0765d484 usb_get_current_frame_number +EXPORT_SYMBOL_GPL vmlinux 0x07b52e38 rtnl_unregister +EXPORT_SYMBOL_GPL vmlinux 0x07db081d spi_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x081a65bf crypto_spawn_tfm +EXPORT_SYMBOL_GPL vmlinux 0x085e0f25 devm_kfree +EXPORT_SYMBOL_GPL vmlinux 0x08600d7e sdio_writew +EXPORT_SYMBOL_GPL vmlinux 0x086ab268 klist_init +EXPORT_SYMBOL_GPL vmlinux 0x08f0288c spi_unregister_master +EXPORT_SYMBOL_GPL vmlinux 0x08f170d6 spi_bitbang_setup_transfer +EXPORT_SYMBOL_GPL vmlinux 0x091eb9b4 round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0x09518c76 rtc_set_time +EXPORT_SYMBOL_GPL vmlinux 0x0990cc8c device_schedule_callback_owner +EXPORT_SYMBOL_GPL vmlinux 0x099b6387 usb_interrupt_msg +EXPORT_SYMBOL_GPL vmlinux 0x09e7c11a fat_dir_empty +EXPORT_SYMBOL_GPL vmlinux 0x0a12b6be platform_get_irq_byname +EXPORT_SYMBOL_GPL vmlinux 0x0a42c47b ata_do_set_mode +EXPORT_SYMBOL_GPL vmlinux 0x0a5127dc ata_sff_thaw +EXPORT_SYMBOL_GPL vmlinux 0x0a92d031 usb_get_from_anchor +EXPORT_SYMBOL_GPL vmlinux 0x0ac02613 spi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x0b379886 crypto_unregister_template +EXPORT_SYMBOL_GPL vmlinux 0x0b40d67d snd_soc_free_ac97_codec +EXPORT_SYMBOL_GPL vmlinux 0x0b4cb7b1 ata_std_bios_param +EXPORT_SYMBOL_GPL vmlinux 0x0b5bc37a inet_unhash +EXPORT_SYMBOL_GPL vmlinux 0x0b6b11dc tcp_set_state +EXPORT_SYMBOL_GPL vmlinux 0x0b766360 relay_subbufs_consumed +EXPORT_SYMBOL_GPL vmlinux 0x0bd31d4f __i2c_board_lock +EXPORT_SYMBOL_GPL vmlinux 0x0beae2d0 rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x0c17e274 xfrm_aalg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x0c58e41a sdio_readb +EXPORT_SYMBOL_GPL vmlinux 0x0cae0c55 ata_bmdma_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x0cd0f914 platform_add_devices +EXPORT_SYMBOL_GPL vmlinux 0x0cd47edb usb_match_id +EXPORT_SYMBOL_GPL vmlinux 0x0d02b3fb blk_queue_dma_drain +EXPORT_SYMBOL_GPL vmlinux 0x0d98db3d crypto_alloc_ablkcipher +EXPORT_SYMBOL_GPL vmlinux 0x0d9e1644 device_register +EXPORT_SYMBOL_GPL vmlinux 0x0e0873e3 get_dcookie +EXPORT_SYMBOL_GPL vmlinux 0x0e430a49 spi_bitbang_transfer +EXPORT_SYMBOL_GPL vmlinux 0x0e8836b7 queue_delayed_work_on +EXPORT_SYMBOL_GPL vmlinux 0x0ec00f80 unregister_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0x0edbb86f hid_input_report +EXPORT_SYMBOL_GPL vmlinux 0x0eec61ea page_cache_sync_readahead +EXPORT_SYMBOL_GPL vmlinux 0x0f285465 ata_sff_data_xfer_noirq +EXPORT_SYMBOL_GPL vmlinux 0x0fac45a9 snd_soc_dapm_connect_input +EXPORT_SYMBOL_GPL vmlinux 0x0fd661f8 security_inode_setattr +EXPORT_SYMBOL_GPL vmlinux 0x0ffcde83 snd_soc_dai_set_tdm_slot +EXPORT_SYMBOL_GPL vmlinux 0x10277d19 crypto_alloc_base +EXPORT_SYMBOL_GPL vmlinux 0x106660be hwmon_device_register +EXPORT_SYMBOL_GPL vmlinux 0x106d186a usb_driver_set_configuration +EXPORT_SYMBOL_GPL vmlinux 0x107922df spi_bitbang_start +EXPORT_SYMBOL_GPL vmlinux 0x10a09be5 snd_soc_dapm_get_pin_status +EXPORT_SYMBOL_GPL vmlinux 0x10f58c15 nf_unregister_afinfo +EXPORT_SYMBOL_GPL vmlinux 0x113ce4b6 user_instantiate +EXPORT_SYMBOL_GPL vmlinux 0x1191c3d3 tty_put_char +EXPORT_SYMBOL_GPL vmlinux 0x119ee07f fat_get_dotdot_entry +EXPORT_SYMBOL_GPL vmlinux 0x11c4dd39 inotify_inode_is_dead +EXPORT_SYMBOL_GPL vmlinux 0x120e2009 usb_hub_tt_clear_buffer +EXPORT_SYMBOL_GPL vmlinux 0x1212ddf5 ata_noop_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x122dad1d inet_ctl_sock_create +EXPORT_SYMBOL_GPL vmlinux 0x1248abf1 fat_build_inode +EXPORT_SYMBOL_GPL vmlinux 0x124f2056 crypto_get_attr_type +EXPORT_SYMBOL_GPL vmlinux 0x1251d30f call_rcu +EXPORT_SYMBOL_GPL vmlinux 0x13473578 sysfs_remove_file_from_group +EXPORT_SYMBOL_GPL vmlinux 0x13481c1c usb_register_dev +EXPORT_SYMBOL_GPL vmlinux 0x1351f3a9 file_ra_state_init +EXPORT_SYMBOL_GPL vmlinux 0x13b2a946 register_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x13b49a3a snd_soc_dapm_free +EXPORT_SYMBOL_GPL vmlinux 0x13c63403 snd_soc_get_volsw_s8 +EXPORT_SYMBOL_GPL vmlinux 0x14085f08 scsi_queue_work +EXPORT_SYMBOL_GPL vmlinux 0x142fddb6 scsi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x145eebd0 device_power_up +EXPORT_SYMBOL_GPL vmlinux 0x14795c7a snd_soc_get_volsw +EXPORT_SYMBOL_GPL vmlinux 0x14ebd46d fsstack_copy_attr_all +EXPORT_SYMBOL_GPL vmlinux 0x14f9f0c2 ata_sas_port_start +EXPORT_SYMBOL_GPL vmlinux 0x15853e2b usb_deregister_device_driver +EXPORT_SYMBOL_GPL vmlinux 0x1598dc9d unregister_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x15d33e26 platform_device_add_data +EXPORT_SYMBOL_GPL vmlinux 0x16d22391 disk_map_sector_rcu +EXPORT_SYMBOL_GPL vmlinux 0x16f5b125 usb_match_one_id +EXPORT_SYMBOL_GPL vmlinux 0x16f76869 probe_kernel_read +EXPORT_SYMBOL_GPL vmlinux 0x17238210 regulator_bulk_disable +EXPORT_SYMBOL_GPL vmlinux 0x17649b3a ata_port_start +EXPORT_SYMBOL_GPL vmlinux 0x18c81bad raw_hash_sk +EXPORT_SYMBOL_GPL vmlinux 0x18e9e1da simple_attr_open +EXPORT_SYMBOL_GPL vmlinux 0x19126e13 ata_sas_port_alloc +EXPORT_SYMBOL_GPL vmlinux 0x1916dcc0 key_type_user +EXPORT_SYMBOL_GPL vmlinux 0x191fb096 srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x19a304ba usb_disabled +EXPORT_SYMBOL_GPL vmlinux 0x1a6fcc8b relay_open +EXPORT_SYMBOL_GPL vmlinux 0x1a748122 rtc_irq_set_state +EXPORT_SYMBOL_GPL vmlinux 0x1a81b355 i2c_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x1aa01d62 bus_for_each_dev +EXPORT_SYMBOL_GPL vmlinux 0x1b74409a sgtl5000_dai +EXPORT_SYMBOL_GPL vmlinux 0x1b8a7043 ata_bmdma_start +EXPORT_SYMBOL_GPL vmlinux 0x1bd84162 tty_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x1c5bc262 sysfs_remove_link +EXPORT_SYMBOL_GPL vmlinux 0x1c642f67 seq_open_net +EXPORT_SYMBOL_GPL vmlinux 0x1c87a811 __round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x1c889e21 disk_part_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x1c8e19e8 i2c_new_probed_device +EXPORT_SYMBOL_GPL vmlinux 0x1cee6e76 debugfs_remove +EXPORT_SYMBOL_GPL vmlinux 0x1d536236 sysdev_create_file +EXPORT_SYMBOL_GPL vmlinux 0x1d9dd230 kill_pid_info_as_uid +EXPORT_SYMBOL_GPL vmlinux 0x1dee6a6a ata_eh_qc_retry +EXPORT_SYMBOL_GPL vmlinux 0x1e4ba0f9 blk_trace_setup +EXPORT_SYMBOL_GPL vmlinux 0x1e56688f sdio_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x1e7bbcb3 kernel_restart +EXPORT_SYMBOL_GPL vmlinux 0x1eb9516e round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x1ecb9673 driver_find +EXPORT_SYMBOL_GPL vmlinux 0x1f007434 hrtimer_forward +EXPORT_SYMBOL_GPL vmlinux 0x1f37c41f disk_part_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x1f698e46 destroy_workqueue +EXPORT_SYMBOL_GPL vmlinux 0x1fcece42 inet_twdr_twcal_tick +EXPORT_SYMBOL_GPL vmlinux 0x1fcfa9b9 led_trigger_store +EXPORT_SYMBOL_GPL vmlinux 0x20577ea2 xfrm_ealg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x20596565 usb_wait_anchor_empty_timeout +EXPORT_SYMBOL_GPL vmlinux 0x2092d3be snd_soc_dapm_sync +EXPORT_SYMBOL_GPL vmlinux 0x20bc3470 orderly_poweroff +EXPORT_SYMBOL_GPL vmlinux 0x214097da blk_end_request_callback +EXPORT_SYMBOL_GPL vmlinux 0x21d1d60e ata_eh_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0x22391923 device_reprobe +EXPORT_SYMBOL_GPL vmlinux 0x22472bf4 xfrm_calg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x22526d1d hrtimer_try_to_cancel +EXPORT_SYMBOL_GPL vmlinux 0x2296c00d crypto_attr_u32 +EXPORT_SYMBOL_GPL vmlinux 0x22b02819 snd_soc_dapm_put_volsw +EXPORT_SYMBOL_GPL vmlinux 0x22ba74be proc_net_fops_create +EXPORT_SYMBOL_GPL vmlinux 0x22e2c20b atomic_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x2338ced1 device_find_child +EXPORT_SYMBOL_GPL vmlinux 0x23679939 __iowrite32_copy +EXPORT_SYMBOL_GPL vmlinux 0x237a141d bus_create_file +EXPORT_SYMBOL_GPL vmlinux 0x23869dc7 cancel_work_sync +EXPORT_SYMBOL_GPL vmlinux 0x239d7f0c usb_register_device_driver +EXPORT_SYMBOL_GPL vmlinux 0x23a3b815 usb_hcd_link_urb_to_ep +EXPORT_SYMBOL_GPL vmlinux 0x2493e81c relay_switch_subbuf +EXPORT_SYMBOL_GPL vmlinux 0x24c5feae inotify_add_watch +EXPORT_SYMBOL_GPL vmlinux 0x24eb7e32 leds_list +EXPORT_SYMBOL_GPL vmlinux 0x254cc475 ata_scsi_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0x25b854c7 rtc_read_time +EXPORT_SYMBOL_GPL vmlinux 0x2624dc87 simple_attr_write +EXPORT_SYMBOL_GPL vmlinux 0x267ed753 get_task_mm +EXPORT_SYMBOL_GPL vmlinux 0x26a5197b nf_register_afinfo +EXPORT_SYMBOL_GPL vmlinux 0x26c90ea4 scsi_eh_get_sense +EXPORT_SYMBOL_GPL vmlinux 0x26e1ceb1 platform_driver_register +EXPORT_SYMBOL_GPL vmlinux 0x26e39f59 sdio_writel +EXPORT_SYMBOL_GPL vmlinux 0x2711ff88 sdio_readw +EXPORT_SYMBOL_GPL vmlinux 0x272e29b1 __class_create +EXPORT_SYMBOL_GPL vmlinux 0x280bf661 crypto_ablkcipher_type +EXPORT_SYMBOL_GPL vmlinux 0x2859639f usb_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x28b2cc80 atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x28d664ff __raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x28e23139 xfrm_probe_algs +EXPORT_SYMBOL_GPL vmlinux 0x291c1e3f ata_sff_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x2966384c debugfs_create_x8 +EXPORT_SYMBOL_GPL vmlinux 0x29735a58 regulator_put +EXPORT_SYMBOL_GPL vmlinux 0x29e47191 sdio_memcpy_fromio +EXPORT_SYMBOL_GPL vmlinux 0x2a2579e3 d_obtain_alias +EXPORT_SYMBOL_GPL vmlinux 0x2a2d93b7 klist_add_before +EXPORT_SYMBOL_GPL vmlinux 0x2a2ec165 dequeue_signal +EXPORT_SYMBOL_GPL vmlinux 0x2a48f112 skb_pull_rcsum +EXPORT_SYMBOL_GPL vmlinux 0x2a678a13 __suspend_report_result +EXPORT_SYMBOL_GPL vmlinux 0x2a7e0caa sysfs_chmod_file +EXPORT_SYMBOL_GPL vmlinux 0x2acae6da scsi_mode_select +EXPORT_SYMBOL_GPL vmlinux 0x2b36c965 crypto_mod_put +EXPORT_SYMBOL_GPL vmlinux 0x2b3a5115 usb_ep0_reinit +EXPORT_SYMBOL_GPL vmlinux 0x2b4fa141 hidinput_disconnect +EXPORT_SYMBOL_GPL vmlinux 0x2b9f8e23 nf_net_ipv4_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x2c16ed76 xfrm_calg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x2c208607 power_supply_is_system_supplied +EXPORT_SYMBOL_GPL vmlinux 0x2c4ef669 snd_soc_set_runtime_hwparams +EXPORT_SYMBOL_GPL vmlinux 0x2c84ac6f securityfs_remove +EXPORT_SYMBOL_GPL vmlinux 0x2ce62475 snd_soc_update_bits +EXPORT_SYMBOL_GPL vmlinux 0x2cfdf9e6 register_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0x2d69b659 ata_sff_freeze +EXPORT_SYMBOL_GPL vmlinux 0x2e3d08b9 crypto_chain +EXPORT_SYMBOL_GPL vmlinux 0x2e8ce857 fat_time_unix2fat +EXPORT_SYMBOL_GPL vmlinux 0x2e90475f hid_allocate_device +EXPORT_SYMBOL_GPL vmlinux 0x2f47d8c7 cpufreq_frequency_get_table +EXPORT_SYMBOL_GPL vmlinux 0x2f4f6bad usbhid_set_leds +EXPORT_SYMBOL_GPL vmlinux 0x2f7a87c4 scsi_eh_ready_devs +EXPORT_SYMBOL_GPL vmlinux 0x2ff688e4 ata_host_detach +EXPORT_SYMBOL_GPL vmlinux 0x3041b617 crypto_init_spawn +EXPORT_SYMBOL_GPL vmlinux 0x30584d81 snd_soc_put_enum_double +EXPORT_SYMBOL_GPL vmlinux 0x30a6293c hid_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0x3103ae9c ata_sff_pause +EXPORT_SYMBOL_GPL vmlinux 0x310a8718 dev_attr_sw_activity +EXPORT_SYMBOL_GPL vmlinux 0x313b3d12 usb_hcd_resume_root_hub +EXPORT_SYMBOL_GPL vmlinux 0x31446181 usb_buffer_map_sg +EXPORT_SYMBOL_GPL vmlinux 0x317d72e8 led_trigger_register +EXPORT_SYMBOL_GPL vmlinux 0x31b047ee hidinput_find_field +EXPORT_SYMBOL_GPL vmlinux 0x31e47bb9 device_initialize +EXPORT_SYMBOL_GPL vmlinux 0x32a589d1 snd_soc_free_pcms +EXPORT_SYMBOL_GPL vmlinux 0x32d7743b usb_root_hub_lost_power +EXPORT_SYMBOL_GPL vmlinux 0x32f1b8c2 macvlan_handle_frame_hook +EXPORT_SYMBOL_GPL vmlinux 0x32f34299 usb_free_urb +EXPORT_SYMBOL_GPL vmlinux 0x3413b609 devres_get +EXPORT_SYMBOL_GPL vmlinux 0x347cc9ac hwmon_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x347eb87f put_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0x34cb61a7 debugfs_create_x32 +EXPORT_SYMBOL_GPL vmlinux 0x34fbdaf9 crypto_tfm_in_queue +EXPORT_SYMBOL_GPL vmlinux 0x35358d98 ip_build_and_send_pkt +EXPORT_SYMBOL_GPL vmlinux 0x35427701 crypto_mod_get +EXPORT_SYMBOL_GPL vmlinux 0x3559cbd9 crypto_givcipher_type +EXPORT_SYMBOL_GPL vmlinux 0x357942a1 debugfs_create_symlink +EXPORT_SYMBOL_GPL vmlinux 0x35b98bc8 dev_attr_link_power_management_policy +EXPORT_SYMBOL_GPL vmlinux 0x35d8c94a sdev_evt_alloc +EXPORT_SYMBOL_GPL vmlinux 0x35ec7fcb klist_next +EXPORT_SYMBOL_GPL vmlinux 0x361e2bcc save_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0x362e23ec call_rcu_bh +EXPORT_SYMBOL_GPL vmlinux 0x3649b8eb sysfs_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x36c56818 rt_mutex_destroy +EXPORT_SYMBOL_GPL vmlinux 0x374c35c1 transport_add_device +EXPORT_SYMBOL_GPL vmlinux 0x37952164 cpufreq_cpu_put +EXPORT_SYMBOL_GPL vmlinux 0x37de3a2d unregister_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0x3879e20a ata_cable_unknown +EXPORT_SYMBOL_GPL vmlinux 0x38d60d8c sata_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x39819646 atomic_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x39f3010d ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0x3a0b1edd platform_get_resource +EXPORT_SYMBOL_GPL vmlinux 0x3a7f8b86 __local_bh_enable +EXPORT_SYMBOL_GPL vmlinux 0x3ab05be6 hidinput_connect +EXPORT_SYMBOL_GPL vmlinux 0x3afed6af crypto_grab_skcipher +EXPORT_SYMBOL_GPL vmlinux 0x3b65d5f5 blkcipher_walk_virt +EXPORT_SYMBOL_GPL vmlinux 0x3b7e75c8 crypto_larval_alloc +EXPORT_SYMBOL_GPL vmlinux 0x3bc33f65 cleanup_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x3be7af02 get_max_files +EXPORT_SYMBOL_GPL vmlinux 0x3be89d3c usb_register_notify +EXPORT_SYMBOL_GPL vmlinux 0x3c042a07 dnotify_parent +EXPORT_SYMBOL_GPL vmlinux 0x3c4ec2eb spi_sync +EXPORT_SYMBOL_GPL vmlinux 0x3c942368 profile_event_unregister +EXPORT_SYMBOL_GPL vmlinux 0x3ca6b63b inotify_dentry_parent_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x3cd06035 add_input_randomness +EXPORT_SYMBOL_GPL vmlinux 0x3cfedb3f register_pm_notifier +EXPORT_SYMBOL_GPL vmlinux 0x3d0a2284 driver_create_file +EXPORT_SYMBOL_GPL vmlinux 0x3d30d2c9 devres_open_group +EXPORT_SYMBOL_GPL vmlinux 0x3defd602 vlan_dev_real_dev +EXPORT_SYMBOL_GPL vmlinux 0x3e0e9a35 audit_log_untrustedstring +EXPORT_SYMBOL_GPL vmlinux 0x3e0fa0d8 free_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x3e5dc171 register_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0x3ea55b84 fat_remove_entries +EXPORT_SYMBOL_GPL vmlinux 0x3ed80945 sdio_writesb +EXPORT_SYMBOL_GPL vmlinux 0x3edad223 usb_usual_clear_present +EXPORT_SYMBOL_GPL vmlinux 0x3f01570a probe_kernel_write +EXPORT_SYMBOL_GPL vmlinux 0x3f238101 dcookie_register +EXPORT_SYMBOL_GPL vmlinux 0x3f450389 imx_ssi_dai +EXPORT_SYMBOL_GPL vmlinux 0x40ae675f class_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x40af0dec ata_xfer_mode2mask +EXPORT_SYMBOL_GPL vmlinux 0x40b26945 snd_soc_put_volsw +EXPORT_SYMBOL_GPL vmlinux 0x40e0f685 simple_attr_read +EXPORT_SYMBOL_GPL vmlinux 0x41040b75 rtc_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x414f58ac usb_hcd_giveback_urb +EXPORT_SYMBOL_GPL vmlinux 0x41f3cc90 xfrm_aalg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x4290c050 skcipher_geniv_free +EXPORT_SYMBOL_GPL vmlinux 0x42ec0441 tcp_twsk_unique +EXPORT_SYMBOL_GPL vmlinux 0x42ef68f0 usb_remove_hcd +EXPORT_SYMBOL_GPL vmlinux 0x432e2ecf ata_dummy_port_info +EXPORT_SYMBOL_GPL vmlinux 0x43819187 ata_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0x43f56e82 ata_xfer_mode2shift +EXPORT_SYMBOL_GPL vmlinux 0x44247598 user_match +EXPORT_SYMBOL_GPL vmlinux 0x446c6c57 map_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x44a65d5c lock_policy_rwsem_read +EXPORT_SYMBOL_GPL vmlinux 0x44bc148a get_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0x44f5a311 mnt_drop_write +EXPORT_SYMBOL_GPL vmlinux 0x457594fa crypto_alg_list +EXPORT_SYMBOL_GPL vmlinux 0x45a6d459 usb_buffer_unmap_sg +EXPORT_SYMBOL_GPL vmlinux 0x45bf1ff3 crypto_inc +EXPORT_SYMBOL_GPL vmlinux 0x46549d16 tty_mode_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x469aeccd sdio_readl +EXPORT_SYMBOL_GPL vmlinux 0x46a14617 default_backing_dev_info +EXPORT_SYMBOL_GPL vmlinux 0x46c72860 usb_bus_list_lock +EXPORT_SYMBOL_GPL vmlinux 0x46d2ca92 ata_sff_port_start +EXPORT_SYMBOL_GPL vmlinux 0x46d780e3 sdio_writeb +EXPORT_SYMBOL_GPL vmlinux 0x470cd4b0 ata_eh_analyze_ncq_error +EXPORT_SYMBOL_GPL vmlinux 0x48062930 put_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0x48148fa4 blkcipher_walk_phys +EXPORT_SYMBOL_GPL vmlinux 0x4894517a usb_unpoison_urb +EXPORT_SYMBOL_GPL vmlinux 0x48b010e9 rtc_set_mmss +EXPORT_SYMBOL_GPL vmlinux 0x490547e6 tcp_is_cwnd_limited +EXPORT_SYMBOL_GPL vmlinux 0x4906cb75 kill_mtd_super +EXPORT_SYMBOL_GPL vmlinux 0x499043d3 crypto_init_queue +EXPORT_SYMBOL_GPL vmlinux 0x49d5cd0e blk_queue_rq_timed_out +EXPORT_SYMBOL_GPL vmlinux 0x4a2acc2b platform_device_add +EXPORT_SYMBOL_GPL vmlinux 0x4b438b5b __ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0x4b4d2445 sysdev_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x4b864822 tty_prepare_flip_string +EXPORT_SYMBOL_GPL vmlinux 0x4b92aad5 device_create +EXPORT_SYMBOL_GPL vmlinux 0x4bd63065 regulator_get +EXPORT_SYMBOL_GPL vmlinux 0x4be9468f tty_ldisc_flush +EXPORT_SYMBOL_GPL vmlinux 0x4c2e0b43 sysdev_class_register +EXPORT_SYMBOL_GPL vmlinux 0x4c759827 byte_rev_table +EXPORT_SYMBOL_GPL vmlinux 0x4c8d6d89 ata_dummy_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x4d8d17b4 inet_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0x4dc22de5 snd_soc_cnew +EXPORT_SYMBOL_GPL vmlinux 0x4e2f9f54 tty_get_pgrp +EXPORT_SYMBOL_GPL vmlinux 0x4e489b0f platform_driver_probe +EXPORT_SYMBOL_GPL vmlinux 0x4e5ed55b input_ff_upload +EXPORT_SYMBOL_GPL vmlinux 0x4f2fcc0b devres_close_group +EXPORT_SYMBOL_GPL vmlinux 0x4f35ac9d blkdev_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x4f3e63b1 platform_device_put +EXPORT_SYMBOL_GPL vmlinux 0x4f455d05 sysfs_notify_dirent +EXPORT_SYMBOL_GPL vmlinux 0x4f814971 ata_link_online +EXPORT_SYMBOL_GPL vmlinux 0x4f90adef nand_scan +EXPORT_SYMBOL_GPL vmlinux 0x4fceb18d sysdev_class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x4fdc945d sata_deb_timing_normal +EXPORT_SYMBOL_GPL vmlinux 0x504dc48c sysfs_create_group +EXPORT_SYMBOL_GPL vmlinux 0x506173b7 class_find_device +EXPORT_SYMBOL_GPL vmlinux 0x5086ac3a alg_test +EXPORT_SYMBOL_GPL vmlinux 0x50b67174 xfrm_ealg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x50e7193a __i2c_first_dynamic_bus_num +EXPORT_SYMBOL_GPL vmlinux 0x50fad434 round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x51dd6488 xfrm_aalg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x52106afb regulator_register +EXPORT_SYMBOL_GPL vmlinux 0x5221cba5 flush_workqueue +EXPORT_SYMBOL_GPL vmlinux 0x525a39a9 usb_find_interface +EXPORT_SYMBOL_GPL vmlinux 0x52bd673e ata_std_postreset +EXPORT_SYMBOL_GPL vmlinux 0x52d111ea pm_qos_update_requirement +EXPORT_SYMBOL_GPL vmlinux 0x52d342a2 cpufreq_register_governor +EXPORT_SYMBOL_GPL vmlinux 0x53614269 get_cpu_idle_time_us +EXPORT_SYMBOL_GPL vmlinux 0x53986488 register_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5424c5e9 lookup_instantiate_filp +EXPORT_SYMBOL_GPL vmlinux 0x545d9104 lookup_create +EXPORT_SYMBOL_GPL vmlinux 0x54c9645c ata_dev_disable +EXPORT_SYMBOL_GPL vmlinux 0x54cf04dd ata_sff_data_xfer +EXPORT_SYMBOL_GPL vmlinux 0x54ecd7da __mnt_is_readonly +EXPORT_SYMBOL_GPL vmlinux 0x553feeb8 inotify_find_update_watch +EXPORT_SYMBOL_GPL vmlinux 0x5542b913 cpu_bit_bitmap +EXPORT_SYMBOL_GPL vmlinux 0x557571a3 crypto_larval_lookup +EXPORT_SYMBOL_GPL vmlinux 0x55b1e7e1 synchronize_srcu +EXPORT_SYMBOL_GPL vmlinux 0x55feef9e __rt_mutex_init +EXPORT_SYMBOL_GPL vmlinux 0x5641485b tty_termios_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x566fa1c4 sata_link_debounce +EXPORT_SYMBOL_GPL vmlinux 0x56d42418 thread_notify_head +EXPORT_SYMBOL_GPL vmlinux 0x56d7a995 usb_sg_init +EXPORT_SYMBOL_GPL vmlinux 0x56dd5044 led_trigger_show +EXPORT_SYMBOL_GPL vmlinux 0x56e31e72 imx_soc_platform +EXPORT_SYMBOL_GPL vmlinux 0x5705e5c9 crypto_dequeue_request +EXPORT_SYMBOL_GPL vmlinux 0x57602a05 get_current_tty +EXPORT_SYMBOL_GPL vmlinux 0x576bf7be inet6_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0x579e0bf5 rtnl_unregister_all +EXPORT_SYMBOL_GPL vmlinux 0x57e34d11 snd_soc_info_volsw +EXPORT_SYMBOL_GPL vmlinux 0x57fa53da tcp_init_congestion_ops +EXPORT_SYMBOL_GPL vmlinux 0x58157640 scatterwalk_map +EXPORT_SYMBOL_GPL vmlinux 0x5864d096 shmem_file_setup +EXPORT_SYMBOL_GPL vmlinux 0x58a91330 ata_sff_busy_sleep +EXPORT_SYMBOL_GPL vmlinux 0x58e65523 cpufreq_cpu_get +EXPORT_SYMBOL_GPL vmlinux 0x59063cba usb_get_dev +EXPORT_SYMBOL_GPL vmlinux 0x591a7502 xfrm_output_resume +EXPORT_SYMBOL_GPL vmlinux 0x5938c0c3 snd_soc_put_volsw_2r +EXPORT_SYMBOL_GPL vmlinux 0x5965967a spi_register_master +EXPORT_SYMBOL_GPL vmlinux 0x59723d3b driver_find_device +EXPORT_SYMBOL_GPL vmlinux 0x598f8ca5 bus_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x59ca3224 inet_twdr_twkill_work +EXPORT_SYMBOL_GPL vmlinux 0x59cdb183 nand_wait_ready +EXPORT_SYMBOL_GPL vmlinux 0x59da3424 attribute_container_find_class_device +EXPORT_SYMBOL_GPL vmlinux 0x5a7bfe41 crypto_probing_notify +EXPORT_SYMBOL_GPL vmlinux 0x5a8edb3f debugfs_create_u8 +EXPORT_SYMBOL_GPL vmlinux 0x5aa8c1a4 uart_set_options +EXPORT_SYMBOL_GPL vmlinux 0x5aac1199 hrtimer_start_range_ns +EXPORT_SYMBOL_GPL vmlinux 0x5ab4fbb8 sata_link_hardreset +EXPORT_SYMBOL_GPL vmlinux 0x5b7dae12 ehci_cf_port_reset_rwsem +EXPORT_SYMBOL_GPL vmlinux 0x5b9866c7 ata_eh_freeze_port +EXPORT_SYMBOL_GPL vmlinux 0x5bfc03c3 unregister_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5c002a65 queue_work +EXPORT_SYMBOL_GPL vmlinux 0x5c0b87d0 sdio_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x5c58ffec klist_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x5ca4a2fc sata_async_notification +EXPORT_SYMBOL_GPL vmlinux 0x5cc44f7e klist_add_head +EXPORT_SYMBOL_GPL vmlinux 0x5d0f6f57 kbd_table +EXPORT_SYMBOL_GPL vmlinux 0x5d4a4572 ktime_sub_ns +EXPORT_SYMBOL_GPL vmlinux 0x5d730e7b raw_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5d7e2f70 klist_add_tail +EXPORT_SYMBOL_GPL vmlinux 0x5dd58899 xfrm_inner_extract_output +EXPORT_SYMBOL_GPL vmlinux 0x5dd67618 register_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5df100bd input_class +EXPORT_SYMBOL_GPL vmlinux 0x5e70da27 usb_deregister +EXPORT_SYMBOL_GPL vmlinux 0x5ed527f9 crypto_enqueue_request +EXPORT_SYMBOL_GPL vmlinux 0x5f1cced5 scatterwalk_start +EXPORT_SYMBOL_GPL vmlinux 0x5f99baef user_read +EXPORT_SYMBOL_GPL vmlinux 0x5ff73dfb usb_sg_wait +EXPORT_SYMBOL_GPL vmlinux 0x602dba4f queue_work_on +EXPORT_SYMBOL_GPL vmlinux 0x605c1b25 blkcipher_walk_done +EXPORT_SYMBOL_GPL vmlinux 0x607e3f0c inet_twsk_purge +EXPORT_SYMBOL_GPL vmlinux 0x608ff5ff dev_attr_em_message_type +EXPORT_SYMBOL_GPL vmlinux 0x6091797f synchronize_rcu +EXPORT_SYMBOL_GPL vmlinux 0x609a0501 sdio_release_host +EXPORT_SYMBOL_GPL vmlinux 0x60a13e90 rcu_barrier +EXPORT_SYMBOL_GPL vmlinux 0x61018aed blk_end_bidi_request +EXPORT_SYMBOL_GPL vmlinux 0x6133dfac crypto_alloc_instance +EXPORT_SYMBOL_GPL vmlinux 0x618c90e6 blk_rq_bytes +EXPORT_SYMBOL_GPL vmlinux 0x61c8ea20 raw_seq_start +EXPORT_SYMBOL_GPL vmlinux 0x6211df71 relay_reset +EXPORT_SYMBOL_GPL vmlinux 0x622a3f1d sdio_disable_func +EXPORT_SYMBOL_GPL vmlinux 0x622b3e2c srcu_read_lock +EXPORT_SYMBOL_GPL vmlinux 0x623de095 driver_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x625bcf23 init_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0x628c80f0 ata_port_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0x62bc58d8 class_dev_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x62bf5bf9 rt_mutex_lock +EXPORT_SYMBOL_GPL vmlinux 0x62d5c2e4 i2c_new_device +EXPORT_SYMBOL_GPL vmlinux 0x63510f52 inet_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0x639692f5 kset_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0x63cf2349 inet_csk_reqsk_queue_prune +EXPORT_SYMBOL_GPL vmlinux 0x6502b525 platform_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x65062c86 usb_set_interface +EXPORT_SYMBOL_GPL vmlinux 0x650ebfc8 led_trigger_event +EXPORT_SYMBOL_GPL vmlinux 0x653da709 inet6_lookup +EXPORT_SYMBOL_GPL vmlinux 0x65c97ea3 regulator_force_disable +EXPORT_SYMBOL_GPL vmlinux 0x65ccb6f0 call_netevent_notifiers +EXPORT_SYMBOL_GPL vmlinux 0x661601de sprint_symbol +EXPORT_SYMBOL_GPL vmlinux 0x664c2064 snd_soc_get_enum_double +EXPORT_SYMBOL_GPL vmlinux 0x665af291 class_dev_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x6680e3c7 kernel_kobj +EXPORT_SYMBOL_GPL vmlinux 0x668402aa crypto_put_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x66b2a859 nr_free_buffer_pages +EXPORT_SYMBOL_GPL vmlinux 0x66cb7c88 inotify_rm_wd +EXPORT_SYMBOL_GPL vmlinux 0x66d87d38 symbol_put_addr +EXPORT_SYMBOL_GPL vmlinux 0x66ee6d00 inet_twsk_schedule +EXPORT_SYMBOL_GPL vmlinux 0x6718ae36 class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x67322170 skb_icv_walk +EXPORT_SYMBOL_GPL vmlinux 0x67955ce6 profile_hits +EXPORT_SYMBOL_GPL vmlinux 0x6806b933 __blk_put_request +EXPORT_SYMBOL_GPL vmlinux 0x684b24f8 platform_bus +EXPORT_SYMBOL_GPL vmlinux 0x686c703f xfrm_count_auth_supported +EXPORT_SYMBOL_GPL vmlinux 0x6892088c unregister_pm_notifier +EXPORT_SYMBOL_GPL vmlinux 0x68a00beb skb_segment +EXPORT_SYMBOL_GPL vmlinux 0x68c48c7a usb_reset_device +EXPORT_SYMBOL_GPL vmlinux 0x68ee6d03 fat_free_clusters +EXPORT_SYMBOL_GPL vmlinux 0x690ae640 elv_register +EXPORT_SYMBOL_GPL vmlinux 0x69119a3f device_create_file +EXPORT_SYMBOL_GPL vmlinux 0x69a8a5a1 sdio_claim_irq +EXPORT_SYMBOL_GPL vmlinux 0x69c7665e devres_remove +EXPORT_SYMBOL_GPL vmlinux 0x69e98cf3 fib_rules_unregister +EXPORT_SYMBOL_GPL vmlinux 0x69e9a2cb ata_scsi_slave_config +EXPORT_SYMBOL_GPL vmlinux 0x69fcd0d4 ata_do_dev_read_id +EXPORT_SYMBOL_GPL vmlinux 0x6a1206ab driver_add_kobj +EXPORT_SYMBOL_GPL vmlinux 0x6a1e529e __ata_port_next_link +EXPORT_SYMBOL_GPL vmlinux 0x6a8817c7 __ip_route_output_key +EXPORT_SYMBOL_GPL vmlinux 0x6a934337 ata_bus_reset +EXPORT_SYMBOL_GPL vmlinux 0x6ad5708b tty_perform_flush +EXPORT_SYMBOL_GPL vmlinux 0x6af736c2 __rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0x6b1f1eb5 crypto_nivaead_type +EXPORT_SYMBOL_GPL vmlinux 0x6bb4645d kobject_uevent +EXPORT_SYMBOL_GPL vmlinux 0x6bb50e89 regulator_enable +EXPORT_SYMBOL_GPL vmlinux 0x6bed5972 hid_set_field +EXPORT_SYMBOL_GPL vmlinux 0x6c36bb30 usb_string +EXPORT_SYMBOL_GPL vmlinux 0x6c49c4f2 clockevents_notify +EXPORT_SYMBOL_GPL vmlinux 0x6d2c1d34 ata_port_disable +EXPORT_SYMBOL_GPL vmlinux 0x6d2fc5a6 net_namespace_list +EXPORT_SYMBOL_GPL vmlinux 0x6d4fa50d ip_local_out +EXPORT_SYMBOL_GPL vmlinux 0x6d620493 alloc_page_buffers +EXPORT_SYMBOL_GPL vmlinux 0x6d7dbe94 snd_soc_dapm_new_widgets +EXPORT_SYMBOL_GPL vmlinux 0x6df1411e copy_fs_struct +EXPORT_SYMBOL_GPL vmlinux 0x6df3f522 device_move +EXPORT_SYMBOL_GPL vmlinux 0x6e07ccf9 ata_std_error_handler +EXPORT_SYMBOL_GPL vmlinux 0x6e07d9fb usbhid_submit_report +EXPORT_SYMBOL_GPL vmlinux 0x6e401a07 klist_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x6e835c53 sdev_evt_send_simple +EXPORT_SYMBOL_GPL vmlinux 0x6ef015e9 inotify_inode_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x6f1aad23 rtc_irq_unregister +EXPORT_SYMBOL_GPL vmlinux 0x6fb7a43e ata_link_abort +EXPORT_SYMBOL_GPL vmlinux 0x6ff607b6 crypto_get_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x702e452e device_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x7033f9cf d_materialise_unique +EXPORT_SYMBOL_GPL vmlinux 0x7034a366 power_supply_changed +EXPORT_SYMBOL_GPL vmlinux 0x7049e749 hid_add_device +EXPORT_SYMBOL_GPL vmlinux 0x704e3296 skb_to_sgvec +EXPORT_SYMBOL_GPL vmlinux 0x706b3a33 cpufreq_frequency_table_get_attr +EXPORT_SYMBOL_GPL vmlinux 0x707ff1bb ata_xfer_mask2mode +EXPORT_SYMBOL_GPL vmlinux 0x70941360 apply_to_page_range +EXPORT_SYMBOL_GPL vmlinux 0x71196147 tcp_orphan_count +EXPORT_SYMBOL_GPL vmlinux 0x7156dd9b crypto_blkcipher_type +EXPORT_SYMBOL_GPL vmlinux 0x715cba1f ata_sff_error_handler +EXPORT_SYMBOL_GPL vmlinux 0x71b21368 crypto_register_instance +EXPORT_SYMBOL_GPL vmlinux 0x71f9246a leds_list_lock +EXPORT_SYMBOL_GPL vmlinux 0x7221aa5f platform_device_alloc +EXPORT_SYMBOL_GPL vmlinux 0x7231f0c4 inet_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0x72462d2f user_destroy +EXPORT_SYMBOL_GPL vmlinux 0x7278d328 all_vm_events +EXPORT_SYMBOL_GPL vmlinux 0x72e6a5d6 inet_csk_get_port +EXPORT_SYMBOL_GPL vmlinux 0x72ecb970 usb_lock_device_for_reset +EXPORT_SYMBOL_GPL vmlinux 0x73114f2d put_device +EXPORT_SYMBOL_GPL vmlinux 0x731a581c ata_ehi_clear_desc +EXPORT_SYMBOL_GPL vmlinux 0x73a48b4a ata_sff_std_ports +EXPORT_SYMBOL_GPL vmlinux 0x73b1f76d do_posix_clock_nosettime +EXPORT_SYMBOL_GPL vmlinux 0x74047621 crypto_aead_setauthsize +EXPORT_SYMBOL_GPL vmlinux 0x742ab35c regulator_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x743a165e ata_pack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0x744531ab ata_sff_postreset +EXPORT_SYMBOL_GPL vmlinux 0x7452d72a part_round_stats +EXPORT_SYMBOL_GPL vmlinux 0x7453f0cb snd_soc_info_enum_double +EXPORT_SYMBOL_GPL vmlinux 0x747e55d4 bus_register +EXPORT_SYMBOL_GPL vmlinux 0x7486289a init_uts_ns +EXPORT_SYMBOL_GPL vmlinux 0x74abdafa task_handoff_register +EXPORT_SYMBOL_GPL vmlinux 0x74b2349d ata_sff_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0x74e90e57 usb_get_hcd +EXPORT_SYMBOL_GPL vmlinux 0x74ecf341 platform_get_irq +EXPORT_SYMBOL_GPL vmlinux 0x752d6785 __cpufreq_driver_getavg +EXPORT_SYMBOL_GPL vmlinux 0x757781d7 snd_soc_dai_set_fmt +EXPORT_SYMBOL_GPL vmlinux 0x759a536d sysfs_add_file_to_group +EXPORT_SYMBOL_GPL vmlinux 0x75e8f3c3 crypto_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x7612bf3f blk_rq_check_limits +EXPORT_SYMBOL_GPL vmlinux 0x76195209 ata_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0x762d57e7 single_open_net +EXPORT_SYMBOL_GPL vmlinux 0x763d90be tcp_death_row +EXPORT_SYMBOL_GPL vmlinux 0x763d97d9 tty_ldisc_deref +EXPORT_SYMBOL_GPL vmlinux 0x766c549b blk_abort_queue +EXPORT_SYMBOL_GPL vmlinux 0x767b1d26 snd_soc_dapm_get_volsw +EXPORT_SYMBOL_GPL vmlinux 0x76f4f9cc vfs_listxattr +EXPORT_SYMBOL_GPL vmlinux 0x76f61e19 rtnl_put_cacheinfo +EXPORT_SYMBOL_GPL vmlinux 0x7746a633 blk_rq_cur_bytes +EXPORT_SYMBOL_GPL vmlinux 0x7750bef8 class_destroy +EXPORT_SYMBOL_GPL vmlinux 0x77fec453 ata_sas_slave_configure +EXPORT_SYMBOL_GPL vmlinux 0x78986f99 ata_bmdma_stop +EXPORT_SYMBOL_GPL vmlinux 0x78af7c8f init_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x79255294 put_driver +EXPORT_SYMBOL_GPL vmlinux 0x793ef2d2 spi_write_then_read +EXPORT_SYMBOL_GPL vmlinux 0x7948d109 srcu_read_unlock +EXPORT_SYMBOL_GPL vmlinux 0x79968db0 usb_kill_urb +EXPORT_SYMBOL_GPL vmlinux 0x79c87978 regulator_bulk_enable +EXPORT_SYMBOL_GPL vmlinux 0x79d2f8a1 usb_anchor_empty +EXPORT_SYMBOL_GPL vmlinux 0x79ec1211 snd_soc_dapm_add_routes +EXPORT_SYMBOL_GPL vmlinux 0x7a296c44 ata_sff_tf_load +EXPORT_SYMBOL_GPL vmlinux 0x7a4045e6 sdio_readsb +EXPORT_SYMBOL_GPL vmlinux 0x7a54f260 debugfs_create_x16 +EXPORT_SYMBOL_GPL vmlinux 0x7ae1ae8e cpufreq_frequency_table_put_attr +EXPORT_SYMBOL_GPL vmlinux 0x7afba48c device_destroy +EXPORT_SYMBOL_GPL vmlinux 0x7b3d39f9 raw_seq_stop +EXPORT_SYMBOL_GPL vmlinux 0x7b5085b2 anon_transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x7b56bc74 blk_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0x7b5f1d61 sysfs_update_group +EXPORT_SYMBOL_GPL vmlinux 0x7b941420 sata_sff_hardreset +EXPORT_SYMBOL_GPL vmlinux 0x7ba50b34 get_user_pages_fast +EXPORT_SYMBOL_GPL vmlinux 0x7baaaab9 cpufreq_frequency_table_cpuinfo +EXPORT_SYMBOL_GPL vmlinux 0x7bb88959 page_mkclean +EXPORT_SYMBOL_GPL vmlinux 0x7c174acd spi_add_device +EXPORT_SYMBOL_GPL vmlinux 0x7c6784ef ktime_get_real +EXPORT_SYMBOL_GPL vmlinux 0x7caf0a13 generic_fh_to_dentry +EXPORT_SYMBOL_GPL vmlinux 0x7cc8b87a get_device +EXPORT_SYMBOL_GPL vmlinux 0x7cd5a542 user_describe +EXPORT_SYMBOL_GPL vmlinux 0x7cf8be18 blk_set_cmd_filter_defaults +EXPORT_SYMBOL_GPL vmlinux 0x7cfc1d34 ata_bmdma_mode_filter +EXPORT_SYMBOL_GPL vmlinux 0x7d1353d7 fat_fill_super +EXPORT_SYMBOL_GPL vmlinux 0x7d3cac21 devres_find +EXPORT_SYMBOL_GPL vmlinux 0x7d87b50e ata_sff_dev_select +EXPORT_SYMBOL_GPL vmlinux 0x7dc5d0b6 crypto_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x7e275ea8 scsi_complete_async_scans +EXPORT_SYMBOL_GPL vmlinux 0x7e3fc0ba class_interface_register +EXPORT_SYMBOL_GPL vmlinux 0x7e5c097b skcipher_geniv_exit +EXPORT_SYMBOL_GPL vmlinux 0x7e64181d usb_calc_bus_time +EXPORT_SYMBOL_GPL vmlinux 0x7e97a705 sysfs_remove_group +EXPORT_SYMBOL_GPL vmlinux 0x7f19c836 unlock_policy_rwsem_write +EXPORT_SYMBOL_GPL vmlinux 0x7f214cfd tty_prepare_flip_string_flags +EXPORT_SYMBOL_GPL vmlinux 0x7f64c570 snd_soc_dai_digital_mute +EXPORT_SYMBOL_GPL vmlinux 0x7ff10ccf raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x80024c3b snd_soc_dapm_new_controls +EXPORT_SYMBOL_GPL vmlinux 0x804f98a1 ip_route_output_flow +EXPORT_SYMBOL_GPL vmlinux 0x808ec1a3 crypto_alg_tested +EXPORT_SYMBOL_GPL vmlinux 0x80961635 debugfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x80af19c0 rtc_read_alarm +EXPORT_SYMBOL_GPL vmlinux 0x80bc54dc led_trigger_set_default +EXPORT_SYMBOL_GPL vmlinux 0x80e70c93 regulator_set_optimum_mode +EXPORT_SYMBOL_GPL vmlinux 0x812b9323 skb_cow_data +EXPORT_SYMBOL_GPL vmlinux 0x813b34d1 snd_soc_info_volsw_ext +EXPORT_SYMBOL_GPL vmlinux 0x81718ead led_trigger_register_simple +EXPORT_SYMBOL_GPL vmlinux 0x817c7e58 platform_device_del +EXPORT_SYMBOL_GPL vmlinux 0x818a814e zap_vma_ptes +EXPORT_SYMBOL_GPL vmlinux 0x8197b231 ata_sff_wait_ready +EXPORT_SYMBOL_GPL vmlinux 0x81b5fe10 register_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0x81d9d16e aead_geniv_exit +EXPORT_SYMBOL_GPL vmlinux 0x82008782 regulator_get_voltage +EXPORT_SYMBOL_GPL vmlinux 0x8251d387 register_posix_clock +EXPORT_SYMBOL_GPL vmlinux 0x826360fd do_posix_clock_nonanosleep +EXPORT_SYMBOL_GPL vmlinux 0x82925308 rtc_irq_register +EXPORT_SYMBOL_GPL vmlinux 0x82a19b43 debugfs_create_bool +EXPORT_SYMBOL_GPL vmlinux 0x82d79b51 sysctl_vfs_cache_pressure +EXPORT_SYMBOL_GPL vmlinux 0x82efffb5 sdio_f0_readb +EXPORT_SYMBOL_GPL vmlinux 0x83553786 scatterwalk_copychunks +EXPORT_SYMBOL_GPL vmlinux 0x83564465 ata_std_qc_defer +EXPORT_SYMBOL_GPL vmlinux 0x836d2cc9 __blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x83b56f6d deregister_mtd_parser +EXPORT_SYMBOL_GPL vmlinux 0x83c63783 platform_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x83dd982e hid_connect +EXPORT_SYMBOL_GPL vmlinux 0x8412e3c5 srcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x842afcd2 vfs_test_lock +EXPORT_SYMBOL_GPL vmlinux 0x8449318b schedule_hrtimeout +EXPORT_SYMBOL_GPL vmlinux 0x8518e53e cpufreq_freq_attr_scaling_available_freqs +EXPORT_SYMBOL_GPL vmlinux 0x8561cbe9 usb_poison_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x85c10896 rcu_batches_completed_bh +EXPORT_SYMBOL_GPL vmlinux 0x85d0d5fb ata_qc_complete_multiple +EXPORT_SYMBOL_GPL vmlinux 0x85e5a3db ktime_get_ts +EXPORT_SYMBOL_GPL vmlinux 0x86401519 del_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0x868784cb __symbol_get +EXPORT_SYMBOL_GPL vmlinux 0x86b1667d hwrng_unregister +EXPORT_SYMBOL_GPL vmlinux 0x86c33bb6 __inet_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0x86de7f36 aead_geniv_free +EXPORT_SYMBOL_GPL vmlinux 0x86eb9a58 ata_host_suspend +EXPORT_SYMBOL_GPL vmlinux 0x86ffd0a5 transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x87754115 raw_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x87a0f1a7 ata_sff_hsm_move +EXPORT_SYMBOL_GPL vmlinux 0x8801aaa5 sysfs_get_dirent +EXPORT_SYMBOL_GPL vmlinux 0x8807d2d7 __blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0x8810ad5e crypto_xor +EXPORT_SYMBOL_GPL vmlinux 0x885142a6 nf_net_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x88659c91 ata_eh_thaw_port +EXPORT_SYMBOL_GPL vmlinux 0x89020865 spi_alloc_master +EXPORT_SYMBOL_GPL vmlinux 0x8957dbf7 snd_soc_dai_set_clkdiv +EXPORT_SYMBOL_GPL vmlinux 0x895a6c94 register_mtd_parser +EXPORT_SYMBOL_GPL vmlinux 0x89bd9e14 ata_timing_compute +EXPORT_SYMBOL_GPL vmlinux 0x89d4dbaf usb_usual_check_type +EXPORT_SYMBOL_GPL vmlinux 0x8a90d125 usb_add_hcd +EXPORT_SYMBOL_GPL vmlinux 0x8abed13d xfrm_aead_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x8ac0bdf8 __rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0x8ae356a1 sysdev_class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x8ae9c211 fat_attach +EXPORT_SYMBOL_GPL vmlinux 0x8b178231 sysdev_store_ulong +EXPORT_SYMBOL_GPL vmlinux 0x8b752ac1 ata_tf_to_fis +EXPORT_SYMBOL_GPL vmlinux 0x8b8e151f dapm_reg_event +EXPORT_SYMBOL_GPL vmlinux 0x8b9c4ad3 attribute_container_register +EXPORT_SYMBOL_GPL vmlinux 0x8bbed0c8 snd_soc_test_bits +EXPORT_SYMBOL_GPL vmlinux 0x8bc32617 relay_flush +EXPORT_SYMBOL_GPL vmlinux 0x8bd09505 device_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x8c1b9e83 sysdev_show_int +EXPORT_SYMBOL_GPL vmlinux 0x8c507550 tcp_twsk_destructor +EXPORT_SYMBOL_GPL vmlinux 0x8c6ed477 ata_cable_sata +EXPORT_SYMBOL_GPL vmlinux 0x8ce80f30 regulator_set_voltage +EXPORT_SYMBOL_GPL vmlinux 0x8ceb6767 bus_for_each_drv +EXPORT_SYMBOL_GPL vmlinux 0x8d16a382 ata_sff_irq_on +EXPORT_SYMBOL_GPL vmlinux 0x8d2831ad usb_unlink_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x8dba394a rtnl_kill_links +EXPORT_SYMBOL_GPL vmlinux 0x8dd65bfc vfs_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0x8de28a80 ata_sff_prereset +EXPORT_SYMBOL_GPL vmlinux 0x8e15a461 sata_scr_read +EXPORT_SYMBOL_GPL vmlinux 0x8e5d5f92 inotify_init_watch +EXPORT_SYMBOL_GPL vmlinux 0x8ee517b6 usb_deregister_dev +EXPORT_SYMBOL_GPL vmlinux 0x8f3d0c37 spi_new_device +EXPORT_SYMBOL_GPL vmlinux 0x8f6c601c fsstack_copy_inode_size +EXPORT_SYMBOL_GPL vmlinux 0x8f6cee77 __round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x8f82294b exit_fs +EXPORT_SYMBOL_GPL vmlinux 0x8fb7b7f6 dma_get_required_mask +EXPORT_SYMBOL_GPL vmlinux 0x8fd35fac class_interface_unregister +EXPORT_SYMBOL_GPL vmlinux 0x8fdbdd7a snd_soc_register_card +EXPORT_SYMBOL_GPL vmlinux 0x90a1004a crypto_has_alg +EXPORT_SYMBOL_GPL vmlinux 0x9159b9d6 profile_event_register +EXPORT_SYMBOL_GPL vmlinux 0x918b5347 sata_scr_write_flush +EXPORT_SYMBOL_GPL vmlinux 0x918d6b05 sysdev_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x918fb67c vfs_lock_file +EXPORT_SYMBOL_GPL vmlinux 0x9241c3ee device_power_down +EXPORT_SYMBOL_GPL vmlinux 0x92445aee hrtimer_get_res +EXPORT_SYMBOL_GPL vmlinux 0x92764f74 snd_soc_put_volsw_s8 +EXPORT_SYMBOL_GPL vmlinux 0x9299fc45 kern_mount_data +EXPORT_SYMBOL_GPL vmlinux 0x92fb217b dcookie_unregister +EXPORT_SYMBOL_GPL vmlinux 0x931be270 ata_sff_dma_pause +EXPORT_SYMBOL_GPL vmlinux 0x935b6743 attribute_container_classdev_to_container +EXPORT_SYMBOL_GPL vmlinux 0x93d2422d snmp_mib_free +EXPORT_SYMBOL_GPL vmlinux 0x93deddff uart_console_write +EXPORT_SYMBOL_GPL vmlinux 0x9418abcd mtd_table +EXPORT_SYMBOL_GPL vmlinux 0x943aba53 sysdev_register +EXPORT_SYMBOL_GPL vmlinux 0x947cbaeb ata_dev_pair +EXPORT_SYMBOL_GPL vmlinux 0x94a68723 ata_scsi_slave_destroy +EXPORT_SYMBOL_GPL vmlinux 0x94dc62d2 ata_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x950f7679 usb_unanchor_urb +EXPORT_SYMBOL_GPL vmlinux 0x95263264 get_cpu_sysdev +EXPORT_SYMBOL_GPL vmlinux 0x952664c5 do_exit +EXPORT_SYMBOL_GPL vmlinux 0x95c17033 register_mtd_user +EXPORT_SYMBOL_GPL vmlinux 0x961a8cd3 unlock_policy_rwsem_read +EXPORT_SYMBOL_GPL vmlinux 0x969f17ee ata_sff_exec_command +EXPORT_SYMBOL_GPL vmlinux 0x96b184fb sysfs_notify +EXPORT_SYMBOL_GPL vmlinux 0x96cbcf31 pm_qos_add_notifier +EXPORT_SYMBOL_GPL vmlinux 0x96cdb26f soc_codec_dev_sgtl5000 +EXPORT_SYMBOL_GPL vmlinux 0x9732b041 usb_hcd_poll_rh_status +EXPORT_SYMBOL_GPL vmlinux 0x97947de8 usb_submit_urb +EXPORT_SYMBOL_GPL vmlinux 0x979a0800 rtc_device_register +EXPORT_SYMBOL_GPL vmlinux 0x97d7bfa3 sysdev_store_int +EXPORT_SYMBOL_GPL vmlinux 0x9813e5ca debugfs_create_u64 +EXPORT_SYMBOL_GPL vmlinux 0x98196f5b blocking_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x982320c7 snd_soc_dapm_stream_event +EXPORT_SYMBOL_GPL vmlinux 0x983e9296 bus_find_device_by_name +EXPORT_SYMBOL_GPL vmlinux 0x9869d4b2 class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x986b15dd usb_anchor_urb +EXPORT_SYMBOL_GPL vmlinux 0x98b88f83 dev_attr_em_message +EXPORT_SYMBOL_GPL vmlinux 0x98f872f1 sysfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x9904bee9 blk_trace_remove +EXPORT_SYMBOL_GPL vmlinux 0x991b1fbe cpufreq_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x9924c496 __usb_get_extra_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x99273092 generic_sync_sb_inodes +EXPORT_SYMBOL_GPL vmlinux 0x995d1071 prof_on +EXPORT_SYMBOL_GPL vmlinux 0x999c698c ata_std_prereset +EXPORT_SYMBOL_GPL vmlinux 0x99a2f9d0 regulator_get_current_limit +EXPORT_SYMBOL_GPL vmlinux 0x99c94ed4 snd_soc_dapm_get_enum_double +EXPORT_SYMBOL_GPL vmlinux 0x99da4c36 fib_rules_lookup +EXPORT_SYMBOL_GPL vmlinux 0x99fa148b find_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0x9a11a0fc crypto_attr_alg_name +EXPORT_SYMBOL_GPL vmlinux 0x9a398f5c xfrm_ealg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x9a6d4b88 tcp_reno_ssthresh +EXPORT_SYMBOL_GPL vmlinux 0x9af17753 devres_remove_group +EXPORT_SYMBOL_GPL vmlinux 0x9b191efa ata_cable_ignore +EXPORT_SYMBOL_GPL vmlinux 0x9b284f61 crypto_alg_lookup +EXPORT_SYMBOL_GPL vmlinux 0x9b3123ae kobject_rename +EXPORT_SYMBOL_GPL vmlinux 0x9b5e6d7c usb_hcd_unlink_urb_from_ep +EXPORT_SYMBOL_GPL vmlinux 0x9b683b45 scatterwalk_done +EXPORT_SYMBOL_GPL vmlinux 0x9b949409 hrtimer_init +EXPORT_SYMBOL_GPL vmlinux 0x9ba0501e unregister_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0x9bd670ec raw_seq_open +EXPORT_SYMBOL_GPL vmlinux 0x9cb67899 ata_scsi_simulate +EXPORT_SYMBOL_GPL vmlinux 0x9cb8037b xfrm_count_enc_supported +EXPORT_SYMBOL_GPL vmlinux 0x9cc9f805 skb_partial_csum_set +EXPORT_SYMBOL_GPL vmlinux 0x9ceab8c7 put_pid +EXPORT_SYMBOL_GPL vmlinux 0x9d05ffbd crypto_alg_sem +EXPORT_SYMBOL_GPL vmlinux 0x9d46a0aa crypto_rng_type +EXPORT_SYMBOL_GPL vmlinux 0x9d4c5c50 bus_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x9d81da40 del_mtd_blktrans_dev +EXPORT_SYMBOL_GPL vmlinux 0x9d8f0106 generic_drop_inode +EXPORT_SYMBOL_GPL vmlinux 0x9db11422 rtc_update_irq +EXPORT_SYMBOL_GPL vmlinux 0x9db943c5 input_ff_event +EXPORT_SYMBOL_GPL vmlinux 0x9dd3173c usb_driver_claim_interface +EXPORT_SYMBOL_GPL vmlinux 0x9dd3c5c3 unregister_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0x9dd98840 find_get_pid +EXPORT_SYMBOL_GPL vmlinux 0x9df5657e crypto_unregister_alg +EXPORT_SYMBOL_GPL vmlinux 0x9dffdf1f regulator_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x9e686618 transport_setup_device +EXPORT_SYMBOL_GPL vmlinux 0x9e711ad2 pm_qos_requirement +EXPORT_SYMBOL_GPL vmlinux 0x9e79e4a6 __sock_recv_timestamp +EXPORT_SYMBOL_GPL vmlinux 0x9f24e5c6 add_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0x9f5714a2 vfs_setlease +EXPORT_SYMBOL_GPL vmlinux 0x9f6b9737 posix_timer_event +EXPORT_SYMBOL_GPL vmlinux 0x9f6d2af0 regulator_unregister +EXPORT_SYMBOL_GPL vmlinux 0x9fab20b9 kobject_get_path +EXPORT_SYMBOL_GPL vmlinux 0x9fce80db fb_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xa0255440 net_ipv4_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0xa0587c7a device_rename +EXPORT_SYMBOL_GPL vmlinux 0xa0c3e691 unregister_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0xa0ec8586 tcp_reno_min_cwnd +EXPORT_SYMBOL_GPL vmlinux 0xa1446ba7 usb_put_dev +EXPORT_SYMBOL_GPL vmlinux 0xa243f139 spi_busnum_to_master +EXPORT_SYMBOL_GPL vmlinux 0xa2734576 platform_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xa282d37a tty_ldisc_ref +EXPORT_SYMBOL_GPL vmlinux 0xa29a1214 usb_scuttle_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xa338f8f7 drop_file_write_access +EXPORT_SYMBOL_GPL vmlinux 0xa3f5c84e inet_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0xa46e16df init_user_ns +EXPORT_SYMBOL_GPL vmlinux 0xa4a5b2a3 snd_soc_dai_set_tristate +EXPORT_SYMBOL_GPL vmlinux 0xa4c2b3f1 blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0xa4f09479 arm_pm_restart +EXPORT_SYMBOL_GPL vmlinux 0xa5364b2e tcp_slow_start +EXPORT_SYMBOL_GPL vmlinux 0xa56841ef snd_soc_info_enum_ext +EXPORT_SYMBOL_GPL vmlinux 0xa57afc74 ktime_get +EXPORT_SYMBOL_GPL vmlinux 0xa5bf5c3e pm_qos_add_requirement +EXPORT_SYMBOL_GPL vmlinux 0xa5c36cec inotify_unmount_inodes +EXPORT_SYMBOL_GPL vmlinux 0xa65f9329 raw_seq_next +EXPORT_SYMBOL_GPL vmlinux 0xa664caf1 ata_sff_post_internal_cmd +EXPORT_SYMBOL_GPL vmlinux 0xa67128f6 snd_soc_dapm_nc_pin +EXPORT_SYMBOL_GPL vmlinux 0xa6806696 platform_device_register_simple +EXPORT_SYMBOL_GPL vmlinux 0xa6d6cd53 hid_parse_report +EXPORT_SYMBOL_GPL vmlinux 0xa7349eaf led_classdev_suspend +EXPORT_SYMBOL_GPL vmlinux 0xa76770a4 driver_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xa88a13bd pskb_put +EXPORT_SYMBOL_GPL vmlinux 0xa892a3af fat_fs_panic +EXPORT_SYMBOL_GPL vmlinux 0xa8f7cb78 hrtimer_cancel +EXPORT_SYMBOL_GPL vmlinux 0xa95479e8 unregister_timer_hook +EXPORT_SYMBOL_GPL vmlinux 0xa9c530b8 unregister_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xa9d13cbb sock_prot_inuse_get +EXPORT_SYMBOL_GPL vmlinux 0xa9df6c24 snd_soc_new_ac97_codec +EXPORT_SYMBOL_GPL vmlinux 0xa9f542c7 rt_mutex_timed_lock +EXPORT_SYMBOL_GPL vmlinux 0xaa03231c power_supply_class +EXPORT_SYMBOL_GPL vmlinux 0xaa08170b inverse_translate +EXPORT_SYMBOL_GPL vmlinux 0xaa120072 deregister_mtd_blktrans +EXPORT_SYMBOL_GPL vmlinux 0xaa2a72bf __iowrite64_copy +EXPORT_SYMBOL_GPL vmlinux 0xaa4463fb hidinput_report_event +EXPORT_SYMBOL_GPL vmlinux 0xaa7a8382 debugfs_rename +EXPORT_SYMBOL_GPL vmlinux 0xaa8c4696 cpu_clock +EXPORT_SYMBOL_GPL vmlinux 0xab7a66d3 sg_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xab839d82 crypto_default_rng +EXPORT_SYMBOL_GPL vmlinux 0xabeda814 regulator_disable +EXPORT_SYMBOL_GPL vmlinux 0xac394349 inet_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0xac513492 sdio_claim_host +EXPORT_SYMBOL_GPL vmlinux 0xac58c093 default_mtd_writev +EXPORT_SYMBOL_GPL vmlinux 0xac7359ad sdio_align_size +EXPORT_SYMBOL_GPL vmlinux 0xac767951 do_sync_mapping_range +EXPORT_SYMBOL_GPL vmlinux 0xac84aa08 mmput +EXPORT_SYMBOL_GPL vmlinux 0xacc56a6d __crypto_alloc_tfm +EXPORT_SYMBOL_GPL vmlinux 0xaccc36a0 bus_get_kset +EXPORT_SYMBOL_GPL vmlinux 0xace5c0fc usb_bus_list +EXPORT_SYMBOL_GPL vmlinux 0xacf20f7a snd_soc_dai_set_sysclk +EXPORT_SYMBOL_GPL vmlinux 0xad703c01 input_ff_destroy +EXPORT_SYMBOL_GPL vmlinux 0xadbb2197 klist_add_after +EXPORT_SYMBOL_GPL vmlinux 0xadee5c7f unregister_mtd_user +EXPORT_SYMBOL_GPL vmlinux 0xae0c87ee pm_qos_remove_notifier +EXPORT_SYMBOL_GPL vmlinux 0xae891098 anon_inode_getfd +EXPORT_SYMBOL_GPL vmlinux 0xaea8b131 ata_port_abort +EXPORT_SYMBOL_GPL vmlinux 0xaed95830 rdev_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0xaedfa622 ata_sff_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0xaf0a0526 blk_insert_cloned_request +EXPORT_SYMBOL_GPL vmlinux 0xaf421106 power_supply_register +EXPORT_SYMBOL_GPL vmlinux 0xaf547b43 vlan_dev_vlan_id +EXPORT_SYMBOL_GPL vmlinux 0xaf8f2eeb sysdev_driver_register +EXPORT_SYMBOL_GPL vmlinux 0xaf98c0ce vfs_cancel_lock +EXPORT_SYMBOL_GPL vmlinux 0xb0147b97 led_trigger_unregister_simple +EXPORT_SYMBOL_GPL vmlinux 0xb0388b60 __inet_lookup_established +EXPORT_SYMBOL_GPL vmlinux 0xb08f150d ata_bmdma_status +EXPORT_SYMBOL_GPL vmlinux 0xb0aa812e fips_enabled +EXPORT_SYMBOL_GPL vmlinux 0xb10d55bc cn_netlink_send +EXPORT_SYMBOL_GPL vmlinux 0xb12830e1 unregister_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0xb181a5b9 usb_buffer_alloc +EXPORT_SYMBOL_GPL vmlinux 0xb18cb34d ata_host_init +EXPORT_SYMBOL_GPL vmlinux 0xb1acbcce rcu_barrier_sched +EXPORT_SYMBOL_GPL vmlinux 0xb1de4444 __pneigh_lookup +EXPORT_SYMBOL_GPL vmlinux 0xb1e6870f ata_sff_irq_clear +EXPORT_SYMBOL_GPL vmlinux 0xb1fc0b37 sdio_set_block_size +EXPORT_SYMBOL_GPL vmlinux 0xb20e436c fib_rules_cleanup_ops +EXPORT_SYMBOL_GPL vmlinux 0xb242838c nand_release +EXPORT_SYMBOL_GPL vmlinux 0xb27005f5 device_suspend +EXPORT_SYMBOL_GPL vmlinux 0xb2f1a4f0 invalidate_inode_pages2_range +EXPORT_SYMBOL_GPL vmlinux 0xb2f90dc5 snd_soc_new_pcms +EXPORT_SYMBOL_GPL vmlinux 0xb36393a2 securityfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0xb3a2a394 debugfs_create_u32 +EXPORT_SYMBOL_GPL vmlinux 0xb3e65719 __inet_hash_nolisten +EXPORT_SYMBOL_GPL vmlinux 0xb4188c8e inotify_remove_watch_locked +EXPORT_SYMBOL_GPL vmlinux 0xb449ed11 mtd_table_mutex +EXPORT_SYMBOL_GPL vmlinux 0xb49a846e ata_host_start +EXPORT_SYMBOL_GPL vmlinux 0xb4a4b9fb blocking_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0xb4ad180b __create_workqueue_key +EXPORT_SYMBOL_GPL vmlinux 0xb4e012cd rt_mutex_trylock +EXPORT_SYMBOL_GPL vmlinux 0xb52a73d7 ata_host_alloc_pinfo +EXPORT_SYMBOL_GPL vmlinux 0xb5374da8 crypto_register_alg +EXPORT_SYMBOL_GPL vmlinux 0xb55889fd raw_unhash_sk +EXPORT_SYMBOL_GPL vmlinux 0xb64babce class_unregister +EXPORT_SYMBOL_GPL vmlinux 0xb6563a3b scsi_execute_async +EXPORT_SYMBOL_GPL vmlinux 0xb6aeb661 ata_id_c_string +EXPORT_SYMBOL_GPL vmlinux 0xb74f9fcb get_driver +EXPORT_SYMBOL_GPL vmlinux 0xb766bae9 sysfs_get +EXPORT_SYMBOL_GPL vmlinux 0xb799f8b2 ata_bmdma_setup +EXPORT_SYMBOL_GPL vmlinux 0xb7de5260 fs_kobj +EXPORT_SYMBOL_GPL vmlinux 0xb8714b33 ata_sff_dumb_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0xb8759c2c srcu_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0xb883c758 regulator_get_init_drvdata +EXPORT_SYMBOL_GPL vmlinux 0xb8c82889 crypto_lookup_template +EXPORT_SYMBOL_GPL vmlinux 0xb8e5ad16 anon_transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0xb8fee532 blocking_notifier_chain_cond_register +EXPORT_SYMBOL_GPL vmlinux 0xb970a524 inotify_init +EXPORT_SYMBOL_GPL vmlinux 0xb9eb3aa9 add_uevent_var +EXPORT_SYMBOL_GPL vmlinux 0xb9f289b7 ata_sas_port_init +EXPORT_SYMBOL_GPL vmlinux 0xba240ffc get_sb_mtd +EXPORT_SYMBOL_GPL vmlinux 0xbac393a7 dev_set_name +EXPORT_SYMBOL_GPL vmlinux 0xbaf09ec0 klist_del +EXPORT_SYMBOL_GPL vmlinux 0xbb9a2c75 ktime_add_ns +EXPORT_SYMBOL_GPL vmlinux 0xbb9ae789 spi_bitbang_cleanup +EXPORT_SYMBOL_GPL vmlinux 0xbbbf6b95 i2c_add_numbered_adapter +EXPORT_SYMBOL_GPL vmlinux 0xbc78bda8 device_add +EXPORT_SYMBOL_GPL vmlinux 0xbcc36e62 scsi_target_unblock +EXPORT_SYMBOL_GPL vmlinux 0xbd5283be simple_attr_release +EXPORT_SYMBOL_GPL vmlinux 0xbd8cc405 led_classdev_unregister +EXPORT_SYMBOL_GPL vmlinux 0xbdde7dfb blk_queue_rq_timeout +EXPORT_SYMBOL_GPL vmlinux 0xbe01b196 led_classdev_resume +EXPORT_SYMBOL_GPL vmlinux 0xbe1887e4 ata_unpack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xbe232c45 register_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0xbe32ef54 console_drivers +EXPORT_SYMBOL_GPL vmlinux 0xbe392e78 ata_do_eh +EXPORT_SYMBOL_GPL vmlinux 0xbe7fc48d pid_vnr +EXPORT_SYMBOL_GPL vmlinux 0xbeea7a2b srcu_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0xbeff88b3 page_cache_async_readahead +EXPORT_SYMBOL_GPL vmlinux 0xbf1d24c5 rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0xbf85e6bd proc_net_mkdir +EXPORT_SYMBOL_GPL vmlinux 0xbf98cd26 __class_register +EXPORT_SYMBOL_GPL vmlinux 0xbfc5ce6c ata_sff_qc_issue +EXPORT_SYMBOL_GPL vmlinux 0xbfe7385b usb_kill_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xc00784db ata_sas_port_destroy +EXPORT_SYMBOL_GPL vmlinux 0xc068b703 disk_part_iter_next +EXPORT_SYMBOL_GPL vmlinux 0xc0da07d8 inotify_destroy +EXPORT_SYMBOL_GPL vmlinux 0xc17515d7 usb_hcds_loaded +EXPORT_SYMBOL_GPL vmlinux 0xc1e8c629 spi_bitbang_stop +EXPORT_SYMBOL_GPL vmlinux 0xc1f1f681 security_inode_permission +EXPORT_SYMBOL_GPL vmlinux 0xc1fa312b sysdev_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc1fd00a9 usb_hcd_platform_shutdown +EXPORT_SYMBOL_GPL vmlinux 0xc22a3091 vm_unmap_aliases +EXPORT_SYMBOL_GPL vmlinux 0xc2416e3d nf_unregister_queue_handlers +EXPORT_SYMBOL_GPL vmlinux 0xc2c1bb68 usb_put_hcd +EXPORT_SYMBOL_GPL vmlinux 0xc2cc26ac ata_slave_link_init +EXPORT_SYMBOL_GPL vmlinux 0xc3091110 rt_mutex_unlock +EXPORT_SYMBOL_GPL vmlinux 0xc34263a0 blk_queue_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0xc34efe27 snmp_fold_field +EXPORT_SYMBOL_GPL vmlinux 0xc3568967 hid_output_report +EXPORT_SYMBOL_GPL vmlinux 0xc39ec260 vfs_getxattr +EXPORT_SYMBOL_GPL vmlinux 0xc4194543 sata_set_spd +EXPORT_SYMBOL_GPL vmlinux 0xc428068d sata_deb_timing_long +EXPORT_SYMBOL_GPL vmlinux 0xc42c474d sdio_memcpy_toio +EXPORT_SYMBOL_GPL vmlinux 0xc46fd087 fat_sync_inode +EXPORT_SYMBOL_GPL vmlinux 0xc48b7ccf ata_mode_string +EXPORT_SYMBOL_GPL vmlinux 0xc5278adb sata_std_hardreset +EXPORT_SYMBOL_GPL vmlinux 0xc57d126d hid_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0xc5871336 audit_log_d_path +EXPORT_SYMBOL_GPL vmlinux 0xc5e6981c usb_get_descriptor +EXPORT_SYMBOL_GPL vmlinux 0xc673e23e ata_scsi_change_queue_depth +EXPORT_SYMBOL_GPL vmlinux 0xc6965bf0 sysfs_put +EXPORT_SYMBOL_GPL vmlinux 0xc6d8ceec tcp_reno_cong_avoid +EXPORT_SYMBOL_GPL vmlinux 0xc7106250 usb_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0xc739580b rtc_irq_set_freq +EXPORT_SYMBOL_GPL vmlinux 0xc7ead0be debugfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0xc8528522 kobject_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0xc86ef7eb inet_twsk_alloc +EXPORT_SYMBOL_GPL vmlinux 0xc875c53a firmware_kobj +EXPORT_SYMBOL_GPL vmlinux 0xc8a48f11 power_supply_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc923832a rtc_class_close +EXPORT_SYMBOL_GPL vmlinux 0xc9318c52 sysdev_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc9335040 transport_configure_device +EXPORT_SYMBOL_GPL vmlinux 0xc9561772 fb_destroy_modelist +EXPORT_SYMBOL_GPL vmlinux 0xca364a59 usb_clear_halt +EXPORT_SYMBOL_GPL vmlinux 0xcaaa4abc inet6_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0xcab38525 kobject_init_and_add +EXPORT_SYMBOL_GPL vmlinux 0xcaddce6b inet_csk_listen_stop +EXPORT_SYMBOL_GPL vmlinux 0xcb08e840 ata_sff_check_status +EXPORT_SYMBOL_GPL vmlinux 0xcb0c2ebf __srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xcb869239 transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0xcbddf28c platform_device_register +EXPORT_SYMBOL_GPL vmlinux 0xcbdfe166 bus_sort_breadthfirst +EXPORT_SYMBOL_GPL vmlinux 0xcbe8196a debugfs_create_blob +EXPORT_SYMBOL_GPL vmlinux 0xcc0ad3d9 xfrm_output +EXPORT_SYMBOL_GPL vmlinux 0xcc1dd876 sdev_evt_send +EXPORT_SYMBOL_GPL vmlinux 0xcc1f1c3d inet_twdr_hangman +EXPORT_SYMBOL_GPL vmlinux 0xcc612489 seq_release_net +EXPORT_SYMBOL_GPL vmlinux 0xcca0c0c8 schedule_hrtimeout_range +EXPORT_SYMBOL_GPL vmlinux 0xcccfb2fa sata_deb_timing_hotplug +EXPORT_SYMBOL_GPL vmlinux 0xcd03d785 devres_destroy +EXPORT_SYMBOL_GPL vmlinux 0xcd0484ff driver_attach +EXPORT_SYMBOL_GPL vmlinux 0xcd3b6514 rdev_get_dev +EXPORT_SYMBOL_GPL vmlinux 0xcd503af7 skb_morph +EXPORT_SYMBOL_GPL vmlinux 0xcd55c0e0 udp4_lib_lookup +EXPORT_SYMBOL_GPL vmlinux 0xcd9991a9 usb_usual_set_present +EXPORT_SYMBOL_GPL vmlinux 0xcda32a94 klist_remove +EXPORT_SYMBOL_GPL vmlinux 0xcdb3cff0 klist_iter_init_node +EXPORT_SYMBOL_GPL vmlinux 0xcdca3691 nr_irqs +EXPORT_SYMBOL_GPL vmlinux 0xcded2eca i2c_new_dummy +EXPORT_SYMBOL_GPL vmlinux 0xcdfd8441 driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xce1bb978 cpufreq_driver_target +EXPORT_SYMBOL_GPL vmlinux 0xce312e35 register_net_sysctl_rotable +EXPORT_SYMBOL_GPL vmlinux 0xce347a27 spi_alloc_device +EXPORT_SYMBOL_GPL vmlinux 0xce6c15b7 __scsi_get_command +EXPORT_SYMBOL_GPL vmlinux 0xce731ddf cpufreq_frequency_table_target +EXPORT_SYMBOL_GPL vmlinux 0xceb32aa2 cpufreq_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0xceb80b38 spi_bitbang_setup +EXPORT_SYMBOL_GPL vmlinux 0xcebde213 ata_cable_80wire +EXPORT_SYMBOL_GPL vmlinux 0xcec98380 bus_find_device +EXPORT_SYMBOL_GPL vmlinux 0xcedb0a2c hrtimer_get_remaining +EXPORT_SYMBOL_GPL vmlinux 0xcf2715a9 debugfs_remove_recursive +EXPORT_SYMBOL_GPL vmlinux 0xcf30921f get_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0xcfad3dfd usb_hc_died +EXPORT_SYMBOL_GPL vmlinux 0xcfc87e6e __blk_add_trace +EXPORT_SYMBOL_GPL vmlinux 0xcfcc83ad register_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0xcfd9a2c0 des_ekey +EXPORT_SYMBOL_GPL vmlinux 0xcfdab093 ata_link_offline +EXPORT_SYMBOL_GPL vmlinux 0xcfdd2331 snd_soc_dapm_put_enum_double +EXPORT_SYMBOL_GPL vmlinux 0xd033b160 ata_sff_qc_fill_rtf +EXPORT_SYMBOL_GPL vmlinux 0xd0388085 do_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0xd03c7700 secure_ipv4_port_ephemeral +EXPORT_SYMBOL_GPL vmlinux 0xd04c2a04 led_trigger_set +EXPORT_SYMBOL_GPL vmlinux 0xd0811fd9 sata_scr_valid +EXPORT_SYMBOL_GPL vmlinux 0xd082ad1d ata_port_probe +EXPORT_SYMBOL_GPL vmlinux 0xd0c05159 emergency_restart +EXPORT_SYMBOL_GPL vmlinux 0xd16712f3 crypto_check_attr_type +EXPORT_SYMBOL_GPL vmlinux 0xd18e0410 usb_hcd_check_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0xd195582d mnt_want_write +EXPORT_SYMBOL_GPL vmlinux 0xd1e02c53 skcipher_geniv_init +EXPORT_SYMBOL_GPL vmlinux 0xd2096a13 sock_prot_inuse_add +EXPORT_SYMBOL_GPL vmlinux 0xd268714e devres_release_group +EXPORT_SYMBOL_GPL vmlinux 0xd273b1b1 __round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xd29c789e ata_sff_tf_read +EXPORT_SYMBOL_GPL vmlinux 0xd3053741 ata_host_activate +EXPORT_SYMBOL_GPL vmlinux 0xd33038d1 ata_sff_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0xd336d931 fat_detach +EXPORT_SYMBOL_GPL vmlinux 0xd38672ac bus_unregister +EXPORT_SYMBOL_GPL vmlinux 0xd38d2652 ata_host_register +EXPORT_SYMBOL_GPL vmlinux 0xd3f0d43c proc_net_remove +EXPORT_SYMBOL_GPL vmlinux 0xd4049800 rtc_set_alarm +EXPORT_SYMBOL_GPL vmlinux 0xd455f9c8 crypto_grab_aead +EXPORT_SYMBOL_GPL vmlinux 0xd45b68bd snd_soc_info_volsw_s8 +EXPORT_SYMBOL_GPL vmlinux 0xd45c91b0 regulator_set_mode +EXPORT_SYMBOL_GPL vmlinux 0xd4c22031 scsi_internal_device_block +EXPORT_SYMBOL_GPL vmlinux 0xd5468bac device_del +EXPORT_SYMBOL_GPL vmlinux 0xd549b282 sk_clone +EXPORT_SYMBOL_GPL vmlinux 0xd552305f usb_sg_cancel +EXPORT_SYMBOL_GPL vmlinux 0xd5b77f4c regulator_set_current_limit +EXPORT_SYMBOL_GPL vmlinux 0xd5c8b908 fnotify_change +EXPORT_SYMBOL_GPL vmlinux 0xd5d96376 net_assign_generic +EXPORT_SYMBOL_GPL vmlinux 0xd5f02eff nand_scan_ident +EXPORT_SYMBOL_GPL vmlinux 0xd61fe5fc devres_add +EXPORT_SYMBOL_GPL vmlinux 0xd64d3d23 usb_ifnum_to_if +EXPORT_SYMBOL_GPL vmlinux 0xd65c713a netlink_has_listeners +EXPORT_SYMBOL_GPL vmlinux 0xd6630cba input_ff_erase +EXPORT_SYMBOL_GPL vmlinux 0xd66a81db sata_link_resume +EXPORT_SYMBOL_GPL vmlinux 0xd6a8f996 device_for_each_child +EXPORT_SYMBOL_GPL vmlinux 0xd70def78 transport_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0xd72ee5a9 aead_geniv_init +EXPORT_SYMBOL_GPL vmlinux 0xd741cfcf blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xd751c46e cpufreq_unregister_governor +EXPORT_SYMBOL_GPL vmlinux 0xd75f634f fat_setattr +EXPORT_SYMBOL_GPL vmlinux 0xd763855d class_dev_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0xd7ccc236 ata_sg_init +EXPORT_SYMBOL_GPL vmlinux 0xd7f0505d usb_alloc_urb +EXPORT_SYMBOL_GPL vmlinux 0xd8205d57 crypto_hash_walk_first +EXPORT_SYMBOL_GPL vmlinux 0xd836f879 kobject_uevent_env +EXPORT_SYMBOL_GPL vmlinux 0xd84cd7f4 ata_timing_find_mode +EXPORT_SYMBOL_GPL vmlinux 0xd888bbb4 snd_soc_get_volsw_2r +EXPORT_SYMBOL_GPL vmlinux 0xd8c2c535 usb_create_hcd +EXPORT_SYMBOL_GPL vmlinux 0xd940a33d usb_get_urb +EXPORT_SYMBOL_GPL vmlinux 0xd96e3ce3 relay_close +EXPORT_SYMBOL_GPL vmlinux 0xd9e8859d bd_release_from_disk +EXPORT_SYMBOL_GPL vmlinux 0xda1b428e sata_scr_write +EXPORT_SYMBOL_GPL vmlinux 0xdaf4dfb3 fb_mode_option +EXPORT_SYMBOL_GPL vmlinux 0xdb5ed668 fib_rules_register +EXPORT_SYMBOL_GPL vmlinux 0xdb5feb5f tcp_unregister_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0xdb738475 tty_buffer_request_room +EXPORT_SYMBOL_GPL vmlinux 0xdb7bf096 inet_twsk_put +EXPORT_SYMBOL_GPL vmlinux 0xdbb29042 user_update +EXPORT_SYMBOL_GPL vmlinux 0xdbb338cd scsi_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0xdbc32bcb crypto_alloc_aead +EXPORT_SYMBOL_GPL vmlinux 0xdbd33b0d register_mtd_blktrans +EXPORT_SYMBOL_GPL vmlinux 0xdcc9722a generic_fh_to_parent +EXPORT_SYMBOL_GPL vmlinux 0xdce9c235 snd_soc_dai_set_pll +EXPORT_SYMBOL_GPL vmlinux 0xdd511a2d ata_sff_softreset +EXPORT_SYMBOL_GPL vmlinux 0xdd526fdd crypto_attr_alg +EXPORT_SYMBOL_GPL vmlinux 0xddd88837 ata_sas_port_stop +EXPORT_SYMBOL_GPL vmlinux 0xdde303ef parse_mtd_partitions +EXPORT_SYMBOL_GPL vmlinux 0xde134c69 storage_usb_ids +EXPORT_SYMBOL_GPL vmlinux 0xde87de44 sched_setscheduler +EXPORT_SYMBOL_GPL vmlinux 0xde887ed9 device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xdec82625 __trace_note_message +EXPORT_SYMBOL_GPL vmlinux 0xdef77767 mc13892_register_regulator +EXPORT_SYMBOL_GPL vmlinux 0xdf0e45d3 sdio_enable_func +EXPORT_SYMBOL_GPL vmlinux 0xdf3022b2 ata_sff_interrupt +EXPORT_SYMBOL_GPL vmlinux 0xdf3c19ec cn_add_callback +EXPORT_SYMBOL_GPL vmlinux 0xdf6a1763 ata_common_sdev_attrs +EXPORT_SYMBOL_GPL vmlinux 0xdfb44392 __cpufreq_driver_target +EXPORT_SYMBOL_GPL vmlinux 0xdffea989 nand_scan_tail +EXPORT_SYMBOL_GPL vmlinux 0xe01e75f9 ata_cable_40wire +EXPORT_SYMBOL_GPL vmlinux 0xe072caaa find_vpid +EXPORT_SYMBOL_GPL vmlinux 0xe08b3fef bus_get_device_klist +EXPORT_SYMBOL_GPL vmlinux 0xe0a7ce1a scsi_internal_device_unblock +EXPORT_SYMBOL_GPL vmlinux 0xe12db797 rt_mutex_lock_interruptible +EXPORT_SYMBOL_GPL vmlinux 0xe170abda i2c_unregister_device +EXPORT_SYMBOL_GPL vmlinux 0xe1895a94 usb_put_intf +EXPORT_SYMBOL_GPL vmlinux 0xe1b0baf3 hrtimer_start +EXPORT_SYMBOL_GPL vmlinux 0xe1dc3953 input_ff_create +EXPORT_SYMBOL_GPL vmlinux 0xe2669f4f crypto_hash_type +EXPORT_SYMBOL_GPL vmlinux 0xe27d2ca8 bd_claim_by_disk +EXPORT_SYMBOL_GPL vmlinux 0xe2e1dc22 ata_host_resume +EXPORT_SYMBOL_GPL vmlinux 0xe2f82657 snd_soc_dapm_disable_pin +EXPORT_SYMBOL_GPL vmlinux 0xe359d6bc dev_attr_unload_heads +EXPORT_SYMBOL_GPL vmlinux 0xe373f9a3 blk_trace_startstop +EXPORT_SYMBOL_GPL vmlinux 0xe3784ff6 usb_control_msg +EXPORT_SYMBOL_GPL vmlinux 0xe390a929 usb_store_new_id +EXPORT_SYMBOL_GPL vmlinux 0xe393979d fat_getattr +EXPORT_SYMBOL_GPL vmlinux 0xe3c0ef5c queue_delayed_work +EXPORT_SYMBOL_GPL vmlinux 0xe3f4aca5 __rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0xe4117da2 device_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xe4950910 ata_pio_need_iordy +EXPORT_SYMBOL_GPL vmlinux 0xe49ff3b0 ata_wait_register +EXPORT_SYMBOL_GPL vmlinux 0xe4c896b8 usb_altnum_to_altsetting +EXPORT_SYMBOL_GPL vmlinux 0xe4dd12be crypto_ahash_type +EXPORT_SYMBOL_GPL vmlinux 0xe4e0c65a mm_kobj +EXPORT_SYMBOL_GPL vmlinux 0xe530071c pm_qos_remove_requirement +EXPORT_SYMBOL_GPL vmlinux 0xe538e988 usb_get_status +EXPORT_SYMBOL_GPL vmlinux 0xe54571e7 vfs_setxattr +EXPORT_SYMBOL_GPL vmlinux 0xe55c87b8 crypto_hash_walk_done +EXPORT_SYMBOL_GPL vmlinux 0xe59333db ata_port_freeze +EXPORT_SYMBOL_GPL vmlinux 0xe5c431c4 usb_reset_configuration +EXPORT_SYMBOL_GPL vmlinux 0xe5fa4ea6 usb_bulk_msg +EXPORT_SYMBOL_GPL vmlinux 0xe60e3bc8 regulator_bulk_free +EXPORT_SYMBOL_GPL vmlinux 0xe6488b47 cpufreq_notify_transition +EXPORT_SYMBOL_GPL vmlinux 0xe6e2f24f xattr_getsecurity +EXPORT_SYMBOL_GPL vmlinux 0xe747f0c0 scsi_flush_work +EXPORT_SYMBOL_GPL vmlinux 0xe7f51dc0 bus_rescan_devices +EXPORT_SYMBOL_GPL vmlinux 0xe812a157 crypto_larval_kill +EXPORT_SYMBOL_GPL vmlinux 0xe81b9dad crypto_alg_mod_lookup +EXPORT_SYMBOL_GPL vmlinux 0xe8790926 inet_csk_listen_start +EXPORT_SYMBOL_GPL vmlinux 0xe91eb9fa rtc_class_open +EXPORT_SYMBOL_GPL vmlinux 0xe93e49c3 devres_free +EXPORT_SYMBOL_GPL vmlinux 0xe9587909 usb_unregister_notify +EXPORT_SYMBOL_GPL vmlinux 0xea065e01 task_handoff_unregister +EXPORT_SYMBOL_GPL vmlinux 0xea3fffb0 register_timer_hook +EXPORT_SYMBOL_GPL vmlinux 0xea418e0f atapi_cmd_type +EXPORT_SYMBOL_GPL vmlinux 0xea45bf51 led_trigger_remove +EXPORT_SYMBOL_GPL vmlinux 0xeac886fb hid_report_raw_event +EXPORT_SYMBOL_GPL vmlinux 0xeaea1a51 crypto_shoot_alg +EXPORT_SYMBOL_GPL vmlinux 0xeb990cf9 regulator_get_mode +EXPORT_SYMBOL_GPL vmlinux 0xec16db2a ata_base_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xec1b043e regulator_suspend_prepare +EXPORT_SYMBOL_GPL vmlinux 0xec4f2842 snd_soc_dapm_enable_pin +EXPORT_SYMBOL_GPL vmlinux 0xec6f2f31 inotify_rm_watch +EXPORT_SYMBOL_GPL vmlinux 0xecb33671 __mmdrop +EXPORT_SYMBOL_GPL vmlinux 0xecdec1e2 invalidate_inode_pages2 +EXPORT_SYMBOL_GPL vmlinux 0xed973e92 devres_alloc +EXPORT_SYMBOL_GPL vmlinux 0xee2be258 device_bind_driver +EXPORT_SYMBOL_GPL vmlinux 0xee621f89 regulator_is_enabled +EXPORT_SYMBOL_GPL vmlinux 0xef4e963e __atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xef552531 __inet_inherit_port +EXPORT_SYMBOL_GPL vmlinux 0xef662261 usb_buffer_free +EXPORT_SYMBOL_GPL vmlinux 0xef6c3f70 round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xef82fdba srcu_init_notifier_head +EXPORT_SYMBOL_GPL vmlinux 0xefd57365 usb_driver_release_interface +EXPORT_SYMBOL_GPL vmlinux 0xefe21106 snmp_mib_init +EXPORT_SYMBOL_GPL vmlinux 0xf071a4fb fat_add_entries +EXPORT_SYMBOL_GPL vmlinux 0xf0e21799 __hid_register_driver +EXPORT_SYMBOL_GPL vmlinux 0xf0e979d7 inet_csk_route_req +EXPORT_SYMBOL_GPL vmlinux 0xf11a1b4b screen_glyph +EXPORT_SYMBOL_GPL vmlinux 0xf1388e2b __inet_twsk_hashdance +EXPORT_SYMBOL_GPL vmlinux 0xf140b00e bdi_writeout_inc +EXPORT_SYMBOL_GPL vmlinux 0xf1463412 execute_in_process_context +EXPORT_SYMBOL_GPL vmlinux 0xf157563d usb_init_urb +EXPORT_SYMBOL_GPL vmlinux 0xf184d189 kernel_power_off +EXPORT_SYMBOL_GPL vmlinux 0xf1a3c6e6 cpufreq_frequency_table_verify +EXPORT_SYMBOL_GPL vmlinux 0xf1f9e501 sdio_f0_writeb +EXPORT_SYMBOL_GPL vmlinux 0xf21c38ce tty_wakeup +EXPORT_SYMBOL_GPL vmlinux 0xf259585b inet_hash +EXPORT_SYMBOL_GPL vmlinux 0xf2641b8b sysfs_schedule_callback +EXPORT_SYMBOL_GPL vmlinux 0xf2a25fc4 ata_host_alloc +EXPORT_SYMBOL_GPL vmlinux 0xf2adbd9e usb_poison_urb +EXPORT_SYMBOL_GPL vmlinux 0xf2bf7a1e tcp_done +EXPORT_SYMBOL_GPL vmlinux 0xf2e08f73 add_mtd_blktrans_dev +EXPORT_SYMBOL_GPL vmlinux 0xf2fca922 uart_parse_options +EXPORT_SYMBOL_GPL vmlinux 0xf321f9a9 ata_sff_host_intr +EXPORT_SYMBOL_GPL vmlinux 0xf375dfa1 regulator_set_drvdata +EXPORT_SYMBOL_GPL vmlinux 0xf3d5cc13 ata_timing_merge +EXPORT_SYMBOL_GPL vmlinux 0xf3dd586c rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf44ed21f transport_remove_device +EXPORT_SYMBOL_GPL vmlinux 0xf47b9ea1 crypto_register_template +EXPORT_SYMBOL_GPL vmlinux 0xf499fdb2 rcu_barrier_bh +EXPORT_SYMBOL_GPL vmlinux 0xf4ecd1d0 led_classdev_register +EXPORT_SYMBOL_GPL vmlinux 0xf52152e7 driver_register +EXPORT_SYMBOL_GPL vmlinux 0xf53cfe2b klist_node_attached +EXPORT_SYMBOL_GPL vmlinux 0xf55bbd36 snd_soc_dapm_new_control +EXPORT_SYMBOL_GPL vmlinux 0xf5a691cd invalidate_bh_lrus +EXPORT_SYMBOL_GPL vmlinux 0xf5b48e7c crypto_aead_type +EXPORT_SYMBOL_GPL vmlinux 0xf5d598b6 led_trigger_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf692bb9a sk_setup_caps +EXPORT_SYMBOL_GPL vmlinux 0xf6a9f2e3 sysfs_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xf6bcbd73 hwrng_register +EXPORT_SYMBOL_GPL vmlinux 0xf6cb86f0 fat_scan +EXPORT_SYMBOL_GPL vmlinux 0xf706dd28 regulator_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0xf807fd65 scatterwalk_map_and_copy +EXPORT_SYMBOL_GPL vmlinux 0xf824b6c8 inotify_find_watch +EXPORT_SYMBOL_GPL vmlinux 0xf863e82a flush_work +EXPORT_SYMBOL_GPL vmlinux 0xf8684e48 regulator_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xf8802492 print_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0xf89ae761 blk_execute_rq_nowait +EXPORT_SYMBOL_GPL vmlinux 0xf8f3a0fb ata_ratelimit +EXPORT_SYMBOL_GPL vmlinux 0xf907e1ab usb_get_intf +EXPORT_SYMBOL_GPL vmlinux 0xf911fea2 aead_geniv_alloc +EXPORT_SYMBOL_GPL vmlinux 0xf9348740 scsi_target_block +EXPORT_SYMBOL_GPL vmlinux 0xf96ebfdc k_handler +EXPORT_SYMBOL_GPL vmlinux 0xf97cfbeb power_supply_am_i_supplied +EXPORT_SYMBOL_GPL vmlinux 0xf984d86c fat_flush_inodes +EXPORT_SYMBOL_GPL vmlinux 0xf9a054b5 __round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0xf9b2a5ae device_release_driver +EXPORT_SYMBOL_GPL vmlinux 0xf9c769fe sdio_release_irq +EXPORT_SYMBOL_GPL vmlinux 0xf9ca3160 ata_id_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xfa06bc1e __blkdev_driver_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xfa312965 elv_unregister +EXPORT_SYMBOL_GPL vmlinux 0xfa7df5ef vfs_removexattr +EXPORT_SYMBOL_GPL vmlinux 0xfb43de70 relay_buf_full +EXPORT_SYMBOL_GPL vmlinux 0xfb4b25ea bus_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0xfb5c760a ata_sas_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0xfb5e1447 crypto_free_tfm +EXPORT_SYMBOL_GPL vmlinux 0xfb67530d snd_soc_info_volsw_2r +EXPORT_SYMBOL_GPL vmlinux 0xfbf9be5d register_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xfc5a13f5 mtd_erase_callback +EXPORT_SYMBOL_GPL vmlinux 0xfd3d3053 debugfs_create_u16 +EXPORT_SYMBOL_GPL vmlinux 0xfd441be3 disk_get_part +EXPORT_SYMBOL_GPL vmlinux 0xfde0b92c crypto_larval_error +EXPORT_SYMBOL_GPL vmlinux 0xfe606895 rdev_get_id +EXPORT_SYMBOL_GPL vmlinux 0xfe624267 skcipher_geniv_alloc +EXPORT_SYMBOL_GPL vmlinux 0xfed62bea fat_search_long +EXPORT_SYMBOL_GPL vmlinux 0xfef2899a device_create_vargs +EXPORT_SYMBOL_GPL vmlinux 0xff240407 do_add_mount +EXPORT_SYMBOL_GPL vmlinux 0xff5a8cfe cn_del_callback +EXPORT_SYMBOL_GPL vmlinux 0xffaf7bbb __wake_up_sync +EXPORT_SYMBOL_GPL vmlinux 0xffe81157 sysfs_remove_bin_file --- linux-2.6.28.orig/debian/abi/2.6.28-11.41/armel/versatile +++ linux-2.6.28/debian/abi/2.6.28-11.41/armel/versatile @@ -0,0 +1,3729 @@ +EXPORT_SYMBOL drivers/cdrom/cdrom 0x1a6cd44a cdrom_mode_select +EXPORT_SYMBOL drivers/cdrom/cdrom 0x1e99192b cdrom_release +EXPORT_SYMBOL drivers/cdrom/cdrom 0x4f476e96 init_cdrom_command +EXPORT_SYMBOL drivers/cdrom/cdrom 0x5f20502c register_cdrom +EXPORT_SYMBOL drivers/cdrom/cdrom 0x86c814b4 unregister_cdrom +EXPORT_SYMBOL drivers/cdrom/cdrom 0x8d666a9d cdrom_get_media_event +EXPORT_SYMBOL drivers/cdrom/cdrom 0x90e4410b cdrom_number_of_slots +EXPORT_SYMBOL drivers/cdrom/cdrom 0xa8c9fd42 cdrom_get_last_written +EXPORT_SYMBOL drivers/cdrom/cdrom 0xad7aa4b6 cdrom_mode_sense +EXPORT_SYMBOL drivers/cdrom/cdrom 0xc43f5c1c cdrom_ioctl +EXPORT_SYMBOL drivers/cdrom/cdrom 0xfe0fb691 cdrom_media_changed +EXPORT_SYMBOL drivers/cdrom/cdrom 0xffdc5b6d cdrom_open +EXPORT_SYMBOL drivers/md/dm-log 0x1a849bdd dm_dirty_log_create +EXPORT_SYMBOL drivers/md/dm-log 0x29673466 dm_dirty_log_type_unregister +EXPORT_SYMBOL drivers/md/dm-log 0x7b3b43e5 dm_dirty_log_type_register +EXPORT_SYMBOL drivers/md/dm-log 0x82eff27a dm_dirty_log_destroy +EXPORT_SYMBOL drivers/serial/8250 0x189a3369 serial8250_register_port +EXPORT_SYMBOL drivers/serial/8250 0xc7208c3a serial8250_resume_port +EXPORT_SYMBOL drivers/serial/8250 0xcc248d26 serial8250_suspend_port +EXPORT_SYMBOL drivers/serial/8250 0xcefcd99a serial8250_unregister_port +EXPORT_SYMBOL fs/nls/nls_base 0x0f7bb626 load_nls_default +EXPORT_SYMBOL fs/nls/nls_base 0x2d6b6172 unload_nls +EXPORT_SYMBOL fs/nls/nls_base 0x4ddc4b9f utf8_mbtowc +EXPORT_SYMBOL fs/nls/nls_base 0x7d850612 utf8_mbstowcs +EXPORT_SYMBOL fs/nls/nls_base 0x863cb91a utf8_wcstombs +EXPORT_SYMBOL fs/nls/nls_base 0x9574e84d load_nls +EXPORT_SYMBOL fs/nls/nls_base 0x98a4a668 unregister_nls +EXPORT_SYMBOL fs/nls/nls_base 0x9a458f51 register_nls +EXPORT_SYMBOL fs/nls/nls_base 0xf82f1109 utf8_wctomb +EXPORT_SYMBOL sound/ac97_bus 0x4485c2c8 ac97_bus_type +EXPORT_SYMBOL sound/core/oss/snd-mixer-oss 0xd05e1bcc snd_mixer_oss_ioctl_card +EXPORT_SYMBOL sound/core/snd 0x03c2c8e1 snd_info_create_module_entry +EXPORT_SYMBOL sound/core/snd 0x093baa2d snd_ctl_new1 +EXPORT_SYMBOL sound/core/snd 0x0a0298ea snd_device_free +EXPORT_SYMBOL sound/core/snd 0x0b38a91d snd_ctl_register_ioctl +EXPORT_SYMBOL sound/core/snd 0x198788b4 snd_lookup_oss_minor_data +EXPORT_SYMBOL sound/core/snd 0x1cdbc192 snd_device_new +EXPORT_SYMBOL sound/core/snd 0x24a94b26 snd_info_get_line +EXPORT_SYMBOL sound/core/snd 0x24e0ffa5 snd_seq_root +EXPORT_SYMBOL sound/core/snd 0x2a991ce7 snd_info_create_card_entry +EXPORT_SYMBOL sound/core/snd 0x2ace9227 snd_card_proc_new +EXPORT_SYMBOL sound/core/snd 0x34c07eb9 snd_card_file_add +EXPORT_SYMBOL sound/core/snd 0x3839aeb4 snd_unregister_oss_device +EXPORT_SYMBOL sound/core/snd 0x396f2198 snd_info_free_entry +EXPORT_SYMBOL sound/core/snd 0x3971b4df snd_ecards_limit +EXPORT_SYMBOL sound/core/snd 0x3cd0d94d snd_component_add +EXPORT_SYMBOL sound/core/snd 0x42133978 snd_ctl_rename_id +EXPORT_SYMBOL sound/core/snd 0x48b7625f snd_mixer_oss_notify_callback +EXPORT_SYMBOL sound/core/snd 0x4a3ea5c0 snd_request_card +EXPORT_SYMBOL sound/core/snd 0x4b93dd83 snd_ctl_unregister_ioctl +EXPORT_SYMBOL sound/core/snd 0x53d38422 snd_pci_quirk_lookup +EXPORT_SYMBOL sound/core/snd 0x5432ab92 snd_ctl_boolean_mono_info +EXPORT_SYMBOL sound/core/snd 0x5aa194d4 snd_card_new +EXPORT_SYMBOL sound/core/snd 0x602c96f0 copy_to_user_fromio +EXPORT_SYMBOL sound/core/snd 0x66e3558c snd_register_device_for_dev +EXPORT_SYMBOL sound/core/snd 0x74ca9e67 snd_ctl_notify +EXPORT_SYMBOL sound/core/snd 0x7a68a1a6 snd_ctl_add +EXPORT_SYMBOL sound/core/snd 0x818bae04 snd_device_register +EXPORT_SYMBOL sound/core/snd 0x84889ae6 snd_ctl_remove_id +EXPORT_SYMBOL sound/core/snd 0x8df3789f snd_oss_info_register +EXPORT_SYMBOL sound/core/snd 0x8dfde44b snd_card_free +EXPORT_SYMBOL sound/core/snd 0x8f595b11 snd_major +EXPORT_SYMBOL sound/core/snd 0x99404527 snd_ctl_free_one +EXPORT_SYMBOL sound/core/snd 0xa7a989a1 snd_info_register +EXPORT_SYMBOL sound/core/snd 0xa7b91620 snd_ctl_find_id +EXPORT_SYMBOL sound/core/snd 0xa8835dfd snd_ctl_boolean_stereo_info +EXPORT_SYMBOL sound/core/snd 0xa8a81be8 snd_ctl_make_virtual_master +EXPORT_SYMBOL sound/core/snd 0xb213fe8b snd_info_get_str +EXPORT_SYMBOL sound/core/snd 0xb29b0733 snd_register_oss_device +EXPORT_SYMBOL sound/core/snd 0xb2e5ae4a snd_lookup_minor_data +EXPORT_SYMBOL sound/core/snd 0xb363a992 snd_add_device_sysfs_file +EXPORT_SYMBOL sound/core/snd 0xb72afc7c snd_card_file_remove +EXPORT_SYMBOL sound/core/snd 0xcaa93e5a snd_unregister_device +EXPORT_SYMBOL sound/core/snd 0xccdf82a5 snd_card_register +EXPORT_SYMBOL sound/core/snd 0xce3ca308 copy_from_user_toio +EXPORT_SYMBOL sound/core/snd 0xd1157735 release_and_free_resource +EXPORT_SYMBOL sound/core/snd 0xd37c5a6c snd_ctl_remove +EXPORT_SYMBOL sound/core/snd 0xd49dc4db snd_cards +EXPORT_SYMBOL sound/core/snd 0xd9c29af4 snd_ctl_add_slave +EXPORT_SYMBOL sound/core/snd 0xe25120f9 snd_power_wait +EXPORT_SYMBOL sound/core/snd 0xe4854cea snd_iprintf +EXPORT_SYMBOL sound/core/snd 0xeacc3760 snd_ctl_find_numid +EXPORT_SYMBOL sound/core/snd 0xf9fbc32a snd_card_free_when_closed +EXPORT_SYMBOL sound/core/snd 0xfca7e029 snd_card_disconnect +EXPORT_SYMBOL sound/core/snd-page-alloc 0x3b91f3af snd_free_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0x3e468aeb snd_dma_alloc_pages_fallback +EXPORT_SYMBOL sound/core/snd-page-alloc 0x5b5b2c2b snd_dma_get_reserved_buf +EXPORT_SYMBOL sound/core/snd-page-alloc 0x5f05709c snd_dma_alloc_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0x832a322f snd_dma_free_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0xade88e76 snd_malloc_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0xc86c4b8c snd_dma_reserve_buf +EXPORT_SYMBOL sound/core/snd-pcm 0x04cda566 snd_interval_refine +EXPORT_SYMBOL sound/core/snd-pcm 0x08eef3c1 snd_pcm_lib_writev +EXPORT_SYMBOL sound/core/snd-pcm 0x11bdad02 snd_pcm_hw_constraint_integer +EXPORT_SYMBOL sound/core/snd-pcm 0x1751b17b snd_pcm_open_substream +EXPORT_SYMBOL sound/core/snd-pcm 0x17c56606 snd_pcm_set_ops +EXPORT_SYMBOL sound/core/snd-pcm 0x1d027e4b snd_pcm_format_signed +EXPORT_SYMBOL sound/core/snd-pcm 0x2dfac730 snd_pcm_set_sync +EXPORT_SYMBOL sound/core/snd-pcm 0x375bba17 snd_pcm_suspend +EXPORT_SYMBOL sound/core/snd-pcm 0x3796bdcc snd_pcm_format_little_endian +EXPORT_SYMBOL sound/core/snd-pcm 0x395e287f snd_pcm_link_rwlock +EXPORT_SYMBOL sound/core/snd-pcm 0x39fd492a snd_pcm_suspend_all +EXPORT_SYMBOL sound/core/snd-pcm 0x3b677255 snd_pcm_lib_read +EXPORT_SYMBOL sound/core/snd-pcm 0x439ef7a1 snd_pcm_lib_preallocate_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x43bbe091 snd_pcm_lib_ioctl +EXPORT_SYMBOL sound/core/snd-pcm 0x4d9b6d35 snd_pcm_format_size +EXPORT_SYMBOL sound/core/snd-pcm 0x4dff9279 snd_pcm_notify +EXPORT_SYMBOL sound/core/snd-pcm 0x4f816e9b snd_pcm_format_big_endian +EXPORT_SYMBOL sound/core/snd-pcm 0x511e2b42 snd_pcm_hw_constraint_ratnums +EXPORT_SYMBOL sound/core/snd-pcm 0x51b7cf9e snd_pcm_stop +EXPORT_SYMBOL sound/core/snd-pcm 0x56a5b9bb snd_pcm_period_elapsed +EXPORT_SYMBOL sound/core/snd-pcm 0x5c406628 snd_pcm_lib_preallocate_free_for_all +EXPORT_SYMBOL sound/core/snd-pcm 0x5e7f4920 snd_pcm_format_set_silence +EXPORT_SYMBOL sound/core/snd-pcm 0x63f51c49 snd_pcm_hw_param_value +EXPORT_SYMBOL sound/core/snd-pcm 0x650f8603 snd_pcm_format_silence_64 +EXPORT_SYMBOL sound/core/snd-pcm 0x68a24153 snd_pcm_format_physical_width +EXPORT_SYMBOL sound/core/snd-pcm 0x6ce9463d snd_pcm_kernel_ioctl +EXPORT_SYMBOL sound/core/snd-pcm 0x6ef8fcd8 snd_pcm_format_linear +EXPORT_SYMBOL sound/core/snd-pcm 0x70188f25 snd_pcm_hw_constraint_ratdens +EXPORT_SYMBOL sound/core/snd-pcm 0x718f383f snd_pcm_lib_free_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x77b9ccac _snd_pcm_hw_param_setempty +EXPORT_SYMBOL sound/core/snd-pcm 0x7ec57766 snd_pcm_new_stream +EXPORT_SYMBOL sound/core/snd-pcm 0x808fa5f5 snd_pcm_sgbuf_get_chunk_size +EXPORT_SYMBOL sound/core/snd-pcm 0x821f6f62 snd_pcm_limit_hw_rates +EXPORT_SYMBOL sound/core/snd-pcm 0x83c0a51f snd_pcm_hw_param_first +EXPORT_SYMBOL sound/core/snd-pcm 0x84581b82 snd_pcm_hw_constraint_msbits +EXPORT_SYMBOL sound/core/snd-pcm 0x87a6161a snd_pcm_lib_malloc_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x952d5f21 _snd_pcm_hw_params_any +EXPORT_SYMBOL sound/core/snd-pcm 0xa0b87d49 snd_pcm_lib_write +EXPORT_SYMBOL sound/core/snd-pcm 0xa50240a0 snd_pcm_hw_rule_add +EXPORT_SYMBOL sound/core/snd-pcm 0xa61aa028 snd_pcm_format_unsigned +EXPORT_SYMBOL sound/core/snd-pcm 0xb9638db4 snd_pcm_rate_to_rate_bit +EXPORT_SYMBOL sound/core/snd-pcm 0xc0057008 snd_pcm_hw_constraint_pow2 +EXPORT_SYMBOL sound/core/snd-pcm 0xc078beb8 snd_pcm_sgbuf_ops_page +EXPORT_SYMBOL sound/core/snd-pcm 0xc2856717 snd_pcm_release_substream +EXPORT_SYMBOL sound/core/snd-pcm 0xccec783c snd_pcm_mmap_data +EXPORT_SYMBOL sound/core/snd-pcm 0xd0b9b8b8 snd_interval_list +EXPORT_SYMBOL sound/core/snd-pcm 0xd36108b7 snd_pcm_hw_constraint_step +EXPORT_SYMBOL sound/core/snd-pcm 0xd3cdf3f6 snd_pcm_lib_readv +EXPORT_SYMBOL sound/core/snd-pcm 0xe1e8c9eb snd_pcm_hw_constraint_minmax +EXPORT_SYMBOL sound/core/snd-pcm 0xe29ca47a snd_pcm_new +EXPORT_SYMBOL sound/core/snd-pcm 0xe56a9336 snd_pcm_format_width +EXPORT_SYMBOL sound/core/snd-pcm 0xe8039e78 snd_pcm_hw_constraint_list +EXPORT_SYMBOL sound/core/snd-pcm 0xeeb4043a snd_pcm_lib_preallocate_pages_for_all +EXPORT_SYMBOL sound/core/snd-pcm 0xf3797152 snd_interval_ratnum +EXPORT_SYMBOL sound/core/snd-pcm 0xf8dd2b0c snd_pcm_hw_refine +EXPORT_SYMBOL sound/core/snd-pcm 0xf92edd6f snd_pcm_hw_param_last +EXPORT_SYMBOL sound/core/snd-timer 0x09b410df snd_timer_global_free +EXPORT_SYMBOL sound/core/snd-timer 0x37c34e9c snd_timer_notify +EXPORT_SYMBOL sound/core/snd-timer 0x4c0f222a snd_timer_close +EXPORT_SYMBOL sound/core/snd-timer 0x7a2197e4 snd_timer_new +EXPORT_SYMBOL sound/core/snd-timer 0x7f97b7ec snd_timer_open +EXPORT_SYMBOL sound/core/snd-timer 0x9d6ed2f0 snd_timer_interrupt +EXPORT_SYMBOL sound/core/snd-timer 0x9e2f11cc snd_timer_stop +EXPORT_SYMBOL sound/core/snd-timer 0xa80b46b0 snd_timer_global_new +EXPORT_SYMBOL sound/core/snd-timer 0xced6fe85 snd_timer_resolution +EXPORT_SYMBOL sound/core/snd-timer 0xd40a1287 snd_timer_global_register +EXPORT_SYMBOL sound/core/snd-timer 0xdc562456 snd_timer_start +EXPORT_SYMBOL sound/core/snd-timer 0xe11a10ed snd_timer_pause +EXPORT_SYMBOL sound/core/snd-timer 0xfd563699 snd_timer_continue +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x031f9e1a snd_ac97_read +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x2e8c5e6c snd_ac97_pcm_open +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x378a216d snd_ac97_bus +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x3f83da63 snd_ac97_get_short_name +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x552bd7d1 snd_ac97_pcm_close +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x5d08c428 snd_ac97_write +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x650067c1 snd_ac97_pcm_double_rate_rules +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x766dfc0d snd_ac97_update +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x8b54b7ea snd_ac97_update_bits +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xaf5c96b0 snd_ac97_suspend +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xb25af9ed snd_ac97_set_rate +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xc3d37903 snd_ac97_tune_hardware +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xcb3c1df3 snd_ac97_pcm_assign +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xf563b4bd snd_ac97_mixer +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xfbc9ccef snd_ac97_write_cache +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xfca81afd snd_ac97_resume +EXPORT_SYMBOL vmlinux 0x00000000 fp_printk +EXPORT_SYMBOL vmlinux 0x00000000 fp_send_sig +EXPORT_SYMBOL vmlinux 0x00000000 kern_fp_enter +EXPORT_SYMBOL vmlinux 0x00000000 per_cpu__softirq_work_list +EXPORT_SYMBOL vmlinux 0x0006250b mmc_suspend_host +EXPORT_SYMBOL vmlinux 0x00103187 nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0x002029cf tty_unregister_driver +EXPORT_SYMBOL vmlinux 0x00801678 flush_scheduled_work +EXPORT_SYMBOL vmlinux 0x008563fa vfs_path_lookup +EXPORT_SYMBOL vmlinux 0x008ccc8a i2c_del_driver +EXPORT_SYMBOL vmlinux 0x00ac875b __scsi_alloc_queue +EXPORT_SYMBOL vmlinux 0x00c222a4 skb_copy_and_csum_bits +EXPORT_SYMBOL vmlinux 0x00d0ec2f cpu_arm926_dcache_clean_area +EXPORT_SYMBOL vmlinux 0x00e8097b csum_partial_copy_fromiovecend +EXPORT_SYMBOL vmlinux 0x01000e51 schedule +EXPORT_SYMBOL vmlinux 0x01079bbf inet_add_protocol +EXPORT_SYMBOL vmlinux 0x01104174 module_refcount +EXPORT_SYMBOL vmlinux 0x01139ffc max_mapnr +EXPORT_SYMBOL vmlinux 0x011d2628 dma_unmap_sg +EXPORT_SYMBOL vmlinux 0x013f8fae kernel_sendmsg +EXPORT_SYMBOL vmlinux 0x013fd381 proc_dointvec_ms_jiffies +EXPORT_SYMBOL vmlinux 0x01574bae inet_release +EXPORT_SYMBOL vmlinux 0x015f0cbe amba_device_unregister +EXPORT_SYMBOL vmlinux 0x01634f9e bio_pair_release +EXPORT_SYMBOL vmlinux 0x016ecb3c sock_no_recvmsg +EXPORT_SYMBOL vmlinux 0x017feb3f call_usermodehelper_setkeys +EXPORT_SYMBOL vmlinux 0x0199de58 audit_log_end +EXPORT_SYMBOL vmlinux 0x01a4aab6 set_irq_chip_data +EXPORT_SYMBOL vmlinux 0x01bb0c2d xfrm_register_km +EXPORT_SYMBOL vmlinux 0x01bf6790 md_error +EXPORT_SYMBOL vmlinux 0x01c64b3e del_mtd_partitions +EXPORT_SYMBOL vmlinux 0x01ecece0 scsi_device_set_state +EXPORT_SYMBOL vmlinux 0x01fecae2 svc_prepare_thread +EXPORT_SYMBOL vmlinux 0x020c4d7e end_buffer_write_sync +EXPORT_SYMBOL vmlinux 0x02101dd8 auth_domain_find +EXPORT_SYMBOL vmlinux 0x02122d3c dev_unicast_delete +EXPORT_SYMBOL vmlinux 0x02124474 ip_send_check +EXPORT_SYMBOL vmlinux 0x02196324 __aeabi_idiv +EXPORT_SYMBOL vmlinux 0x024f21b8 tcp_enter_memory_pressure +EXPORT_SYMBOL vmlinux 0x02608255 dma_sync_sg_for_cpu +EXPORT_SYMBOL vmlinux 0x02649054 security_sock_rcv_skb +EXPORT_SYMBOL vmlinux 0x027a127e neigh_for_each +EXPORT_SYMBOL vmlinux 0x0294e460 spi_display_xfer_agreement +EXPORT_SYMBOL vmlinux 0x02bffd8d bio_split +EXPORT_SYMBOL vmlinux 0x02ee26c1 free_pages_exact +EXPORT_SYMBOL vmlinux 0x030c1b48 pci_fixup_device +EXPORT_SYMBOL vmlinux 0x03281eb7 __scsi_device_lookup +EXPORT_SYMBOL vmlinux 0x0329d71f set_disk_ro +EXPORT_SYMBOL vmlinux 0x0334da4e scsi_command_size_tbl +EXPORT_SYMBOL vmlinux 0x0350e2f4 up_read +EXPORT_SYMBOL vmlinux 0x03542861 sk_reset_timer +EXPORT_SYMBOL vmlinux 0x037a0cba kfree +EXPORT_SYMBOL vmlinux 0x0380c0e1 scsi_cmd_ioctl +EXPORT_SYMBOL vmlinux 0x03a99c3b rb_prev +EXPORT_SYMBOL vmlinux 0x03c06156 bitmap_fold +EXPORT_SYMBOL vmlinux 0x03e6bb64 close_bdev_exclusive +EXPORT_SYMBOL vmlinux 0x03e9a885 pci_scan_bus_parented +EXPORT_SYMBOL vmlinux 0x03ef2f54 get_fs_type +EXPORT_SYMBOL vmlinux 0x03fd2571 vm_unmap_ram +EXPORT_SYMBOL vmlinux 0x0422fe4a inet_csk_timer_bug_msg +EXPORT_SYMBOL vmlinux 0x042cfc40 audit_log_format +EXPORT_SYMBOL vmlinux 0x043b8483 __kfifo_get +EXPORT_SYMBOL vmlinux 0x044fbf49 mempool_kzalloc +EXPORT_SYMBOL vmlinux 0x045155bd skb_copy_expand +EXPORT_SYMBOL vmlinux 0x047e8535 mmc_wait_for_cmd +EXPORT_SYMBOL vmlinux 0x0487f831 fb_find_best_display +EXPORT_SYMBOL vmlinux 0x04b02a88 mmc_remove_host +EXPORT_SYMBOL vmlinux 0x04d7cbff seq_release_private +EXPORT_SYMBOL vmlinux 0x04f5904d locks_copy_lock +EXPORT_SYMBOL vmlinux 0x04fbe2b9 devm_ioport_map +EXPORT_SYMBOL vmlinux 0x0509604a get_sb_nodev +EXPORT_SYMBOL vmlinux 0x052660a2 auth_unix_lookup +EXPORT_SYMBOL vmlinux 0x052b2967 kblockd_flush_work +EXPORT_SYMBOL vmlinux 0x0535c1a8 no_llseek +EXPORT_SYMBOL vmlinux 0x0554a6cc __pagevec_release +EXPORT_SYMBOL vmlinux 0x0560cdeb xfrm_state_flush +EXPORT_SYMBOL vmlinux 0x057ce975 hex_dump_to_buffer +EXPORT_SYMBOL vmlinux 0x05b6501f blk_queue_max_segment_size +EXPORT_SYMBOL vmlinux 0x05e807a9 xdr_encode_string +EXPORT_SYMBOL vmlinux 0x06090de7 __sg_free_table +EXPORT_SYMBOL vmlinux 0x061651be strcat +EXPORT_SYMBOL vmlinux 0x0618e633 dump_fpu +EXPORT_SYMBOL vmlinux 0x062aba95 mempool_free +EXPORT_SYMBOL vmlinux 0x065994f1 xdr_encode_opaque_fixed +EXPORT_SYMBOL vmlinux 0x067d8d35 security_release_secctx +EXPORT_SYMBOL vmlinux 0x06cb34e5 init_waitqueue_head +EXPORT_SYMBOL vmlinux 0x06d8bae1 idr_get_new +EXPORT_SYMBOL vmlinux 0x06dcc6ba kernel_connect +EXPORT_SYMBOL vmlinux 0x06ef2a7d inet_frag_destroy +EXPORT_SYMBOL vmlinux 0x06f5507e dev_unicast_add +EXPORT_SYMBOL vmlinux 0x06f6e3ee scsi_execute +EXPORT_SYMBOL vmlinux 0x06fe3b14 default_grn +EXPORT_SYMBOL vmlinux 0x071897e2 xdr_encode_pages +EXPORT_SYMBOL vmlinux 0x073cfb19 __lock_buffer +EXPORT_SYMBOL vmlinux 0x07431a2f clk_round_rate +EXPORT_SYMBOL vmlinux 0x076d4912 clear_page_dirty_for_io +EXPORT_SYMBOL vmlinux 0x07718ba1 udp_lib_getsockopt +EXPORT_SYMBOL vmlinux 0x078531a2 alloc_file +EXPORT_SYMBOL vmlinux 0x0799aca4 local_bh_enable +EXPORT_SYMBOL vmlinux 0x079cd7f1 ns_to_timeval +EXPORT_SYMBOL vmlinux 0x07a890c8 fb_alloc_cmap +EXPORT_SYMBOL vmlinux 0x07bedd20 netif_carrier_on +EXPORT_SYMBOL vmlinux 0x07cc4a5d printk_timed_ratelimit +EXPORT_SYMBOL vmlinux 0x07f91be3 inet_unregister_protosw +EXPORT_SYMBOL vmlinux 0x0806193b netdev_features_change +EXPORT_SYMBOL vmlinux 0x082c3213 pci_root_buses +EXPORT_SYMBOL vmlinux 0x08345c83 tcp_sendmsg +EXPORT_SYMBOL vmlinux 0x084c3575 generic_permission +EXPORT_SYMBOL vmlinux 0x08728140 malloc_sizes +EXPORT_SYMBOL vmlinux 0x087599fe find_get_page +EXPORT_SYMBOL vmlinux 0x088c3783 __insert_inode_hash +EXPORT_SYMBOL vmlinux 0x088f07ee amba_find_device +EXPORT_SYMBOL vmlinux 0x08b37534 do_map_probe +EXPORT_SYMBOL vmlinux 0x092b007a sleep_on_timeout +EXPORT_SYMBOL vmlinux 0x0948cde9 num_physpages +EXPORT_SYMBOL vmlinux 0x0965e36c elv_rb_add +EXPORT_SYMBOL vmlinux 0x0987932b i2c_attach_client +EXPORT_SYMBOL vmlinux 0x098b71c6 fb_dealloc_cmap +EXPORT_SYMBOL vmlinux 0x09c55cec schedule_timeout_interruptible +EXPORT_SYMBOL vmlinux 0x09c8eb55 font_vga_8x16 +EXPORT_SYMBOL vmlinux 0x09d45c21 down_timeout +EXPORT_SYMBOL vmlinux 0x0a1bebc5 kernel_execve +EXPORT_SYMBOL vmlinux 0x0a2487e0 unblock_all_signals +EXPORT_SYMBOL vmlinux 0x0a3131f6 strnchr +EXPORT_SYMBOL vmlinux 0x0a3ab6df skb_copy +EXPORT_SYMBOL vmlinux 0x0a4747ff allocate_resource +EXPORT_SYMBOL vmlinux 0x0a551143 scsi_get_command +EXPORT_SYMBOL vmlinux 0x0a7dbcad unregister_sysrq_key +EXPORT_SYMBOL vmlinux 0x0a7dc665 eth_rebuild_header +EXPORT_SYMBOL vmlinux 0x0a8cf174 path_put +EXPORT_SYMBOL vmlinux 0x0a993fe3 ilookup5 +EXPORT_SYMBOL vmlinux 0x0aa13d05 __raw_readsw +EXPORT_SYMBOL vmlinux 0x0aa57898 cdev_alloc +EXPORT_SYMBOL vmlinux 0x0abc0f4a xfrm_register_type +EXPORT_SYMBOL vmlinux 0x0ac64191 mpage_readpages +EXPORT_SYMBOL vmlinux 0x0acb1a3c __bitmap_shift_right +EXPORT_SYMBOL vmlinux 0x0af6520b sg_miter_stop +EXPORT_SYMBOL vmlinux 0x0affaee3 __xfrm_route_forward +EXPORT_SYMBOL vmlinux 0x0b1b9b27 iget_failed +EXPORT_SYMBOL vmlinux 0x0b1beb31 vmalloc_32_user +EXPORT_SYMBOL vmlinux 0x0b1ef84e pci_map_rom +EXPORT_SYMBOL vmlinux 0x0b25c930 try_to_release_page +EXPORT_SYMBOL vmlinux 0x0b5f2d2c sg_next +EXPORT_SYMBOL vmlinux 0x0b742fd7 simple_strtol +EXPORT_SYMBOL vmlinux 0x0ba13f31 journal_set_features +EXPORT_SYMBOL vmlinux 0x0c1c3e08 sysctl_data +EXPORT_SYMBOL vmlinux 0x0c3cb740 d_alloc_name +EXPORT_SYMBOL vmlinux 0x0c3dea35 clk_enable +EXPORT_SYMBOL vmlinux 0x0c5ef91b per_cpu__vm_event_states +EXPORT_SYMBOL vmlinux 0x0c65e73c scsi_normalize_sense +EXPORT_SYMBOL vmlinux 0x0c8c9e99 scsi_show_extd_sense +EXPORT_SYMBOL vmlinux 0x0d3def21 idr_pre_get +EXPORT_SYMBOL vmlinux 0x0d3f57a2 _find_next_bit_le +EXPORT_SYMBOL vmlinux 0x0d57a968 blk_queue_invalidate_tags +EXPORT_SYMBOL vmlinux 0x0d8ab500 param_set_copystring +EXPORT_SYMBOL vmlinux 0x0d8d8db6 udp_poll +EXPORT_SYMBOL vmlinux 0x0da10ec3 security_sock_graft +EXPORT_SYMBOL vmlinux 0x0dccf4dd framebuffer_alloc +EXPORT_SYMBOL vmlinux 0x0ddc45c0 ethtool_op_get_tso +EXPORT_SYMBOL vmlinux 0x0dde42db proc_mkdir +EXPORT_SYMBOL vmlinux 0x0dee0908 devm_request_irq +EXPORT_SYMBOL vmlinux 0x0dfc1b14 inet_dev_addr_type +EXPORT_SYMBOL vmlinux 0x0e1526c2 sk_free +EXPORT_SYMBOL vmlinux 0x0e52592a panic +EXPORT_SYMBOL vmlinux 0x0e5b3fc0 blk_queue_set_discard +EXPORT_SYMBOL vmlinux 0x0e5de29a neigh_sysctl_register +EXPORT_SYMBOL vmlinux 0x0e762d6e request_module +EXPORT_SYMBOL vmlinux 0x0e811a57 nobh_truncate_page +EXPORT_SYMBOL vmlinux 0x0e86158d xfrm4_rcv_encap +EXPORT_SYMBOL vmlinux 0x0eab07fd dcache_dir_lseek +EXPORT_SYMBOL vmlinux 0x0ead7bdb keyring_search +EXPORT_SYMBOL vmlinux 0x0ebbb8fd scsi_host_lookup +EXPORT_SYMBOL vmlinux 0x0f1ef871 posix_acl_alloc +EXPORT_SYMBOL vmlinux 0x0f43897e sock_register +EXPORT_SYMBOL vmlinux 0x0f668ba9 svc_auth_unregister +EXPORT_SYMBOL vmlinux 0x0fa2a45e __memzero +EXPORT_SYMBOL vmlinux 0x0fc586ba down_trylock +EXPORT_SYMBOL vmlinux 0x0fd65e2a xfrm_state_update +EXPORT_SYMBOL vmlinux 0x0ff178f6 __aeabi_idivmod +EXPORT_SYMBOL vmlinux 0x103ce1d8 netlink_kernel_create +EXPORT_SYMBOL vmlinux 0x10579454 sg_copy_from_buffer +EXPORT_SYMBOL vmlinux 0x1072a394 csum_partial_copy_from_user +EXPORT_SYMBOL vmlinux 0x10d734c3 sock_no_mmap +EXPORT_SYMBOL vmlinux 0x10dc0535 dmam_free_noncoherent +EXPORT_SYMBOL vmlinux 0x10ee20bb default_blu +EXPORT_SYMBOL vmlinux 0x11154150 wake_up_process +EXPORT_SYMBOL vmlinux 0x111bcb2c groups_free +EXPORT_SYMBOL vmlinux 0x11267875 scsi_extd_sense_format +EXPORT_SYMBOL vmlinux 0x113483e7 uart_write_wakeup +EXPORT_SYMBOL vmlinux 0x115b2ce4 alloc_disk_node +EXPORT_SYMBOL vmlinux 0x1163f0a7 blk_max_low_pfn +EXPORT_SYMBOL vmlinux 0x117cb631 read_cache_page_async +EXPORT_SYMBOL vmlinux 0x119b50e7 elf_check_arch +EXPORT_SYMBOL vmlinux 0x11ba0257 tcp_sync_mss +EXPORT_SYMBOL vmlinux 0x11ca9b84 neigh_parms_alloc +EXPORT_SYMBOL vmlinux 0x11ef67c9 devm_ioport_unmap +EXPORT_SYMBOL vmlinux 0x11f46c77 mpage_writepage +EXPORT_SYMBOL vmlinux 0x123d576a d_alloc +EXPORT_SYMBOL vmlinux 0x124e7305 amba_driver_unregister +EXPORT_SYMBOL vmlinux 0x12662301 xfrm_input +EXPORT_SYMBOL vmlinux 0x126970ed param_set_uint +EXPORT_SYMBOL vmlinux 0x1283388d generic_getxattr +EXPORT_SYMBOL vmlinux 0x129e3d2d dma_release_declared_memory +EXPORT_SYMBOL vmlinux 0x12da5bb2 __kmalloc +EXPORT_SYMBOL vmlinux 0x12e280e3 svc_proc_unregister +EXPORT_SYMBOL vmlinux 0x13266092 put_io_context +EXPORT_SYMBOL vmlinux 0x132e62b3 drop_super +EXPORT_SYMBOL vmlinux 0x1362c016 ps2_sendbyte +EXPORT_SYMBOL vmlinux 0x136f0568 kset_unregister +EXPORT_SYMBOL vmlinux 0x137d6678 xfrm_state_delete +EXPORT_SYMBOL vmlinux 0x13b388ba igrab +EXPORT_SYMBOL vmlinux 0x13b6835b tcp_rcv_established +EXPORT_SYMBOL vmlinux 0x13f01fb0 genl_unregister_ops +EXPORT_SYMBOL vmlinux 0x13f6afea bdi_destroy +EXPORT_SYMBOL vmlinux 0x14008cfe n_tty_ioctl_helper +EXPORT_SYMBOL vmlinux 0x141407bb create_empty_buffers +EXPORT_SYMBOL vmlinux 0x1431a175 fsync_bdev +EXPORT_SYMBOL vmlinux 0x144ed3a1 dev_base_lock +EXPORT_SYMBOL vmlinux 0x14548818 __nla_reserve +EXPORT_SYMBOL vmlinux 0x1459ccb7 pci_setup_cardbus +EXPORT_SYMBOL vmlinux 0x148121e8 add_disk +EXPORT_SYMBOL vmlinux 0x14a1824b sock_release +EXPORT_SYMBOL vmlinux 0x14d6ad19 mb_cache_entry_find_next +EXPORT_SYMBOL vmlinux 0x14eec476 lookup_one_len +EXPORT_SYMBOL vmlinux 0x151cfcc6 put_disk +EXPORT_SYMBOL vmlinux 0x152888d8 per_cpu__kstat +EXPORT_SYMBOL vmlinux 0x1544aad4 genl_register_mc_group +EXPORT_SYMBOL vmlinux 0x1551dc51 bitmap_find_free_region +EXPORT_SYMBOL vmlinux 0x1557fc82 sock_common_getsockopt +EXPORT_SYMBOL vmlinux 0x15594f11 pci_enable_device_io +EXPORT_SYMBOL vmlinux 0x158639d7 find_or_create_page +EXPORT_SYMBOL vmlinux 0x158ee7cd set_blocksize +EXPORT_SYMBOL vmlinux 0x15b84971 posix_lock_file +EXPORT_SYMBOL vmlinux 0x15d73213 __breadahead +EXPORT_SYMBOL vmlinux 0x15e42f45 dmam_pool_create +EXPORT_SYMBOL vmlinux 0x15fa5692 dmam_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0x160d69e1 sk_wait_data +EXPORT_SYMBOL vmlinux 0x1610f295 filemap_fdatawrite +EXPORT_SYMBOL vmlinux 0x162ebc64 generic_unplug_device +EXPORT_SYMBOL vmlinux 0x16316c5d pcim_iounmap +EXPORT_SYMBOL vmlinux 0x16479e8f panic_notifier_list +EXPORT_SYMBOL vmlinux 0x167e33c2 thaw_bdev +EXPORT_SYMBOL vmlinux 0x16c162f4 sysctl_intvec +EXPORT_SYMBOL vmlinux 0x16d4d557 netlink_unicast +EXPORT_SYMBOL vmlinux 0x16f751fc generic_splice_sendpage +EXPORT_SYMBOL vmlinux 0x173f3123 udp_proc_register +EXPORT_SYMBOL vmlinux 0x178783ca rtnl_notify +EXPORT_SYMBOL vmlinux 0x17a76e71 rb_first +EXPORT_SYMBOL vmlinux 0x17b51f04 ps2_drain +EXPORT_SYMBOL vmlinux 0x17b75580 input_close_device +EXPORT_SYMBOL vmlinux 0x17d4d8c8 skb_dma_map +EXPORT_SYMBOL vmlinux 0x17df17bc sysctl_tcp_ecn +EXPORT_SYMBOL vmlinux 0x180fb743 pci_bus_write_config_word +EXPORT_SYMBOL vmlinux 0x1815c4fb kernel_accept +EXPORT_SYMBOL vmlinux 0x183fa88b mempool_alloc_slab +EXPORT_SYMBOL vmlinux 0x18640050 serio_unregister_port +EXPORT_SYMBOL vmlinux 0x18b9b6f7 inet_del_protocol +EXPORT_SYMBOL vmlinux 0x18ead6ad genl_register_ops +EXPORT_SYMBOL vmlinux 0x1904f4a4 block_write_begin +EXPORT_SYMBOL vmlinux 0x199ed0cd net_disable_timestamp +EXPORT_SYMBOL vmlinux 0x19cf4205 call_usermodehelper_stdinpipe +EXPORT_SYMBOL vmlinux 0x19dfdf4b dm_table_unplug_all +EXPORT_SYMBOL vmlinux 0x1a06c5f1 cancel_dirty_page +EXPORT_SYMBOL vmlinux 0x1a0c644a ll_rw_block +EXPORT_SYMBOL vmlinux 0x1a65f4ad __arm_ioremap_pfn +EXPORT_SYMBOL vmlinux 0x1a9a9728 kernel_listen +EXPORT_SYMBOL vmlinux 0x1ab296dc pci_get_bus_and_slot +EXPORT_SYMBOL vmlinux 0x1abbc514 netdev_boot_setup_check +EXPORT_SYMBOL vmlinux 0x1ace138d bitmap_allocate_region +EXPORT_SYMBOL vmlinux 0x1ad1f2e7 _memcpy_fromio +EXPORT_SYMBOL vmlinux 0x1ae8d7dc param_set_invbool +EXPORT_SYMBOL vmlinux 0x1af88955 page_symlink_inode_operations +EXPORT_SYMBOL vmlinux 0x1af91b9d journal_restart +EXPORT_SYMBOL vmlinux 0x1b015d25 bitmap_parselist +EXPORT_SYMBOL vmlinux 0x1b122b93 sock_no_poll +EXPORT_SYMBOL vmlinux 0x1b1b1431 key_type_keyring +EXPORT_SYMBOL vmlinux 0x1b24bcfe elv_rb_del +EXPORT_SYMBOL vmlinux 0x1b258aac kernel_sendpage +EXPORT_SYMBOL vmlinux 0x1b2d0ef1 find_task_by_pid_ns +EXPORT_SYMBOL vmlinux 0x1b2dc19b sock_i_ino +EXPORT_SYMBOL vmlinux 0x1b6314fd in_aton +EXPORT_SYMBOL vmlinux 0x1b6cb1ef do_splice_to +EXPORT_SYMBOL vmlinux 0x1b7b9895 sock_i_uid +EXPORT_SYMBOL vmlinux 0x1b9981cc set_irq_wake +EXPORT_SYMBOL vmlinux 0x1b9e0ff1 scsilun_to_int +EXPORT_SYMBOL vmlinux 0x1bb8aede vm_map_ram +EXPORT_SYMBOL vmlinux 0x1be827b5 i2c_smbus_xfer +EXPORT_SYMBOL vmlinux 0x1bfbb536 unlock_rename +EXPORT_SYMBOL vmlinux 0x1c0e51f2 key_link +EXPORT_SYMBOL vmlinux 0x1c26ae18 neigh_table_clear +EXPORT_SYMBOL vmlinux 0x1c324357 idr_replace +EXPORT_SYMBOL vmlinux 0x1c62e81d netif_rx_ni +EXPORT_SYMBOL vmlinux 0x1c8271af skb_dequeue_tail +EXPORT_SYMBOL vmlinux 0x1cab998e inet_frag_evictor +EXPORT_SYMBOL vmlinux 0x1cc6719a register_reboot_notifier +EXPORT_SYMBOL vmlinux 0x1cef177c tcp_v4_connect +EXPORT_SYMBOL vmlinux 0x1d0aaf41 scsi_kmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x1d80cb47 blkdev_put +EXPORT_SYMBOL vmlinux 0x1d8dc65b update_region +EXPORT_SYMBOL vmlinux 0x1dadde38 arp_find +EXPORT_SYMBOL vmlinux 0x1dc36131 fb_destroy_modedb +EXPORT_SYMBOL vmlinux 0x1dd571e6 fb_copy_cmap +EXPORT_SYMBOL vmlinux 0x1ded6f7e d_find_alias +EXPORT_SYMBOL vmlinux 0x1dede132 uart_suspend_port +EXPORT_SYMBOL vmlinux 0x1e176b64 scsi_device_put +EXPORT_SYMBOL vmlinux 0x1e49daa8 sg_init_one +EXPORT_SYMBOL vmlinux 0x1e53412e sock_alloc_send_skb +EXPORT_SYMBOL vmlinux 0x1e6d26a8 strstr +EXPORT_SYMBOL vmlinux 0x1ecb9943 posix_acl_to_xattr +EXPORT_SYMBOL vmlinux 0x1ecdea37 tcp_hashinfo +EXPORT_SYMBOL vmlinux 0x1edc9598 _atomic_dec_and_lock +EXPORT_SYMBOL vmlinux 0x1efe283f __cap_full_set +EXPORT_SYMBOL vmlinux 0x1f008528 scsi_set_medium_removal +EXPORT_SYMBOL vmlinux 0x1f36c0b6 gnet_stats_copy_basic +EXPORT_SYMBOL vmlinux 0x1f41b658 read_cache_pages +EXPORT_SYMBOL vmlinux 0x1f4462b5 tcp_getsockopt +EXPORT_SYMBOL vmlinux 0x1f48bc76 __locks_copy_lock +EXPORT_SYMBOL vmlinux 0x1f5941ac tcp_splice_read +EXPORT_SYMBOL vmlinux 0x1f70d32d dma_cache_maint +EXPORT_SYMBOL vmlinux 0x1f776d60 starget_for_each_device +EXPORT_SYMBOL vmlinux 0x1f7cc628 mempool_create +EXPORT_SYMBOL vmlinux 0x1fae7a0b wait_for_completion_timeout +EXPORT_SYMBOL vmlinux 0x1fc91fb2 request_irq +EXPORT_SYMBOL vmlinux 0x20000329 simple_strtoul +EXPORT_SYMBOL vmlinux 0x201378f5 scsi_block_requests +EXPORT_SYMBOL vmlinux 0x20184cbe generic_listxattr +EXPORT_SYMBOL vmlinux 0x202db258 pci_request_region +EXPORT_SYMBOL vmlinux 0x203a9d6c blk_queue_merge_bvec +EXPORT_SYMBOL vmlinux 0x203c1e91 proc_symlink +EXPORT_SYMBOL vmlinux 0x2058ad70 misc_register +EXPORT_SYMBOL vmlinux 0x2066fa27 block_write_full_page +EXPORT_SYMBOL vmlinux 0x206d4ca8 proc_dointvec_userhz_jiffies +EXPORT_SYMBOL vmlinux 0x20868116 __scsi_put_command +EXPORT_SYMBOL vmlinux 0x20b3d74b invalidate_inode_buffers +EXPORT_SYMBOL vmlinux 0x20d5528f simple_transaction_read +EXPORT_SYMBOL vmlinux 0x20dbbc56 register_sysrq_key +EXPORT_SYMBOL vmlinux 0x20e54114 single_release +EXPORT_SYMBOL vmlinux 0x210c0fe9 proc_dostring +EXPORT_SYMBOL vmlinux 0x210cc8fc icst307_khz +EXPORT_SYMBOL vmlinux 0x211331fa __divsi3 +EXPORT_SYMBOL vmlinux 0x2117c969 skb_dequeue +EXPORT_SYMBOL vmlinux 0x215ebd78 bitrev16 +EXPORT_SYMBOL vmlinux 0x21742864 __scm_destroy +EXPORT_SYMBOL vmlinux 0x21903a9a request_firmware_nowait +EXPORT_SYMBOL vmlinux 0x219495cc block_commit_write +EXPORT_SYMBOL vmlinux 0x21ac0dbb input_set_keycode +EXPORT_SYMBOL vmlinux 0x21b72f06 pci_pme_capable +EXPORT_SYMBOL vmlinux 0x21b8c344 __pci_register_driver +EXPORT_SYMBOL vmlinux 0x21bcb775 dma_alloc_coherent +EXPORT_SYMBOL vmlinux 0x21d1d356 __dev_get_by_index +EXPORT_SYMBOL vmlinux 0x21fa4113 aio_put_req +EXPORT_SYMBOL vmlinux 0x222b3db4 register_sysctl_paths +EXPORT_SYMBOL vmlinux 0x222e7ce2 sysfs_streq +EXPORT_SYMBOL vmlinux 0x224bef9b filemap_flush +EXPORT_SYMBOL vmlinux 0x226e86a9 audit_log +EXPORT_SYMBOL vmlinux 0x22766ca3 kobject_add +EXPORT_SYMBOL vmlinux 0x2288378f system_state +EXPORT_SYMBOL vmlinux 0x228c8010 simple_statfs +EXPORT_SYMBOL vmlinux 0x229cfd5b gen_new_estimator +EXPORT_SYMBOL vmlinux 0x229f1ece posix_acl_permission +EXPORT_SYMBOL vmlinux 0x22b325d5 kd_mksound +EXPORT_SYMBOL vmlinux 0x22b6533b xfrm_sad_getinfo +EXPORT_SYMBOL vmlinux 0x22becfec xfrm_user_policy +EXPORT_SYMBOL vmlinux 0x22f7d5a3 register_gifconf +EXPORT_SYMBOL vmlinux 0x23000eae scsi_calculate_bounce_limit +EXPORT_SYMBOL vmlinux 0x231cf494 up_write +EXPORT_SYMBOL vmlinux 0x23269a13 strict_strtoul +EXPORT_SYMBOL vmlinux 0x2364506f input_grab_device +EXPORT_SYMBOL vmlinux 0x23838107 __down_write +EXPORT_SYMBOL vmlinux 0x23a9326f journal_init_inode +EXPORT_SYMBOL vmlinux 0x23b7ad6c pci_clear_mwi +EXPORT_SYMBOL vmlinux 0x23fd3028 vmalloc_node +EXPORT_SYMBOL vmlinux 0x24480ea9 __skb_warn_lro_forwarding +EXPORT_SYMBOL vmlinux 0x2455c156 __clear_user +EXPORT_SYMBOL vmlinux 0x2459bbcc console_set_on_cmdline +EXPORT_SYMBOL vmlinux 0x246ce45c __netdev_alloc_page +EXPORT_SYMBOL vmlinux 0x24770b1f key_instantiate_and_link +EXPORT_SYMBOL vmlinux 0x24d950f3 dev_change_flags +EXPORT_SYMBOL vmlinux 0x24db2e5c inet_shutdown +EXPORT_SYMBOL vmlinux 0x24e28675 unregister_framebuffer +EXPORT_SYMBOL vmlinux 0x24fdac79 wake_bit_function +EXPORT_SYMBOL vmlinux 0x250113b4 memory_read_from_buffer +EXPORT_SYMBOL vmlinux 0x254b42ff key_task_permission +EXPORT_SYMBOL vmlinux 0x256576bc tcp_create_openreq_child +EXPORT_SYMBOL vmlinux 0x256887e1 warn_slowpath +EXPORT_SYMBOL vmlinux 0x257b629a neigh_lookup +EXPORT_SYMBOL vmlinux 0x25820c64 fs_overflowuid +EXPORT_SYMBOL vmlinux 0x258355b4 fb_find_best_mode +EXPORT_SYMBOL vmlinux 0x259200d4 inet_twsk_deschedule +EXPORT_SYMBOL vmlinux 0x25928c63 gen_replace_estimator +EXPORT_SYMBOL vmlinux 0x25ba121c mempool_resize +EXPORT_SYMBOL vmlinux 0x25bec159 input_get_keycode +EXPORT_SYMBOL vmlinux 0x25cf131d mii_nway_restart +EXPORT_SYMBOL vmlinux 0x25f6a57b cap_netlink_recv +EXPORT_SYMBOL vmlinux 0x25fa6f17 wait_for_completion +EXPORT_SYMBOL vmlinux 0x261c1766 __backtrace +EXPORT_SYMBOL vmlinux 0x263e4d23 blk_get_backing_dev_info +EXPORT_SYMBOL vmlinux 0x264658df pci_bus_type +EXPORT_SYMBOL vmlinux 0x26477c07 __vmalloc +EXPORT_SYMBOL vmlinux 0x264d2416 mmc_set_data_timeout +EXPORT_SYMBOL vmlinux 0x267fc65b __tasklet_hi_schedule +EXPORT_SYMBOL vmlinux 0x268023a6 unregister_con_driver +EXPORT_SYMBOL vmlinux 0x269dc109 tty_kref_put +EXPORT_SYMBOL vmlinux 0x26e76fb8 sysctl_udp_wmem_min +EXPORT_SYMBOL vmlinux 0x270ffa3d file_fsync +EXPORT_SYMBOL vmlinux 0x272e7488 cond_resched_softirq +EXPORT_SYMBOL vmlinux 0x274cddf4 scsi_test_unit_ready +EXPORT_SYMBOL vmlinux 0x275c0180 redirty_page_for_writepage +EXPORT_SYMBOL vmlinux 0x2765b034 neigh_seq_stop +EXPORT_SYMBOL vmlinux 0x2780446a xfrm_state_lookup_byaddr +EXPORT_SYMBOL vmlinux 0x27864d57 memparse +EXPORT_SYMBOL vmlinux 0x278909cf blk_queue_hardsect_size +EXPORT_SYMBOL vmlinux 0x27a2653f xfrm_state_lookup +EXPORT_SYMBOL vmlinux 0x27a9a7eb ns_to_timespec +EXPORT_SYMBOL vmlinux 0x27bbf221 disable_irq_nosync +EXPORT_SYMBOL vmlinux 0x27d2aa72 remove_inode_hash +EXPORT_SYMBOL vmlinux 0x27dd9398 sock_no_getsockopt +EXPORT_SYMBOL vmlinux 0x27e082ee blkdev_dequeue_request +EXPORT_SYMBOL vmlinux 0x27e12932 vfs_permission +EXPORT_SYMBOL vmlinux 0x280f3085 fb_pan_display +EXPORT_SYMBOL vmlinux 0x28118cb6 __get_user_1 +EXPORT_SYMBOL vmlinux 0x28395ee5 arm926_flush_kern_cache_all +EXPORT_SYMBOL vmlinux 0x2846deee request_key_with_auxdata +EXPORT_SYMBOL vmlinux 0x28593267 scsi_track_queue_full +EXPORT_SYMBOL vmlinux 0x285ac517 strict_strtoll +EXPORT_SYMBOL vmlinux 0x285b55b1 skb_prepare_seq_read +EXPORT_SYMBOL vmlinux 0x288f44dd neigh_event_ns +EXPORT_SYMBOL vmlinux 0x2897e436 i2c_detach_client +EXPORT_SYMBOL vmlinux 0x28a24ae9 svc_auth_register +EXPORT_SYMBOL vmlinux 0x28a2ed02 scsi_build_sense_buffer +EXPORT_SYMBOL vmlinux 0x28c87211 i2c_clients_command +EXPORT_SYMBOL vmlinux 0x28dcf25c udplite_hash +EXPORT_SYMBOL vmlinux 0x28ee3a78 seq_open_private +EXPORT_SYMBOL vmlinux 0x28f38014 simple_rename +EXPORT_SYMBOL vmlinux 0x29029e73 filp_close +EXPORT_SYMBOL vmlinux 0x2913eea8 mem_map +EXPORT_SYMBOL vmlinux 0x29148969 schedule_delayed_work +EXPORT_SYMBOL vmlinux 0x2919b156 xdr_decode_string_inplace +EXPORT_SYMBOL vmlinux 0x29537c9e alloc_chrdev_region +EXPORT_SYMBOL vmlinux 0x295a0c46 read_bytes_from_xdr_buf +EXPORT_SYMBOL vmlinux 0x29670fcf tcp_poll +EXPORT_SYMBOL vmlinux 0x296ae230 i2c_add_adapter +EXPORT_SYMBOL vmlinux 0x29733ba9 i2c_master_recv +EXPORT_SYMBOL vmlinux 0x29a947af xdr_encode_array2 +EXPORT_SYMBOL vmlinux 0x29b780c7 uart_get_divisor +EXPORT_SYMBOL vmlinux 0x29bd4c46 __cap_init_eff_set +EXPORT_SYMBOL vmlinux 0x2a26af71 pcix_get_max_mmrbc +EXPORT_SYMBOL vmlinux 0x2a4d92e4 mark_buffer_async_write +EXPORT_SYMBOL vmlinux 0x2a7c0105 __wait_on_buffer +EXPORT_SYMBOL vmlinux 0x2a861585 tcp_proc_unregister +EXPORT_SYMBOL vmlinux 0x2a9370c6 bdi_unregister +EXPORT_SYMBOL vmlinux 0x2a9b4b6f journal_destroy +EXPORT_SYMBOL vmlinux 0x2aa0e4fc strncasecmp +EXPORT_SYMBOL vmlinux 0x2aadedd9 sk_stream_wait_connect +EXPORT_SYMBOL vmlinux 0x2ae1351d grab_cache_page_write_begin +EXPORT_SYMBOL vmlinux 0x2ae89326 input_flush_device +EXPORT_SYMBOL vmlinux 0x2af2fb13 dcache_readdir +EXPORT_SYMBOL vmlinux 0x2b0ba2b0 scsi_sense_desc_find +EXPORT_SYMBOL vmlinux 0x2b0d0011 dma_mark_declared_memory_occupied +EXPORT_SYMBOL vmlinux 0x2b40baff __down_write_nested +EXPORT_SYMBOL vmlinux 0x2b521dbe blk_queue_start_tag +EXPORT_SYMBOL vmlinux 0x2b570dc0 ida_pre_get +EXPORT_SYMBOL vmlinux 0x2b6a6061 sk_stream_wait_memory +EXPORT_SYMBOL vmlinux 0x2b7c48ef inode_setattr +EXPORT_SYMBOL vmlinux 0x2ba707a8 sysctl_tcp_low_latency +EXPORT_SYMBOL vmlinux 0x2bc9f1b4 vfs_read +EXPORT_SYMBOL vmlinux 0x2c1c8dba kernel_sock_shutdown +EXPORT_SYMBOL vmlinux 0x2c227bd7 elv_dispatch_add_tail +EXPORT_SYMBOL vmlinux 0x2c3eaa1c blk_queue_softirq_done +EXPORT_SYMBOL vmlinux 0x2c482774 __devm_release_region +EXPORT_SYMBOL vmlinux 0x2c569d93 __serio_register_driver +EXPORT_SYMBOL vmlinux 0x2c95b9df neigh_create +EXPORT_SYMBOL vmlinux 0x2ca3be67 xfrm_policy_insert +EXPORT_SYMBOL vmlinux 0x2ca42f9e dev_open +EXPORT_SYMBOL vmlinux 0x2cd3db04 simple_transaction_release +EXPORT_SYMBOL vmlinux 0x2cd9e459 param_set_short +EXPORT_SYMBOL vmlinux 0x2d6507b5 _find_next_zero_bit_le +EXPORT_SYMBOL vmlinux 0x2d89342a scsi_show_sense_hdr +EXPORT_SYMBOL vmlinux 0x2da2c4ce dmam_free_coherent +EXPORT_SYMBOL vmlinux 0x2dcc55b6 send_sig +EXPORT_SYMBOL vmlinux 0x2dd0cb35 gnet_stats_start_copy_compat +EXPORT_SYMBOL vmlinux 0x2ddec466 nlmsvc_ops +EXPORT_SYMBOL vmlinux 0x2de8ee7e xfrm_stateonly_find +EXPORT_SYMBOL vmlinux 0x2de9f66f param_get_long +EXPORT_SYMBOL vmlinux 0x2df8edd6 inet_csk_clear_xmit_timers +EXPORT_SYMBOL vmlinux 0x2e1b19fc cfb_copyarea +EXPORT_SYMBOL vmlinux 0x2e2ce9e0 sysctl_tcp_syncookies +EXPORT_SYMBOL vmlinux 0x2e313804 take_over_console +EXPORT_SYMBOL vmlinux 0x2e359d5f md_wait_for_blocked_rdev +EXPORT_SYMBOL vmlinux 0x2e4a39f8 sysctl_udp_mem +EXPORT_SYMBOL vmlinux 0x2e6d4fdf proto_unregister +EXPORT_SYMBOL vmlinux 0x2e7bce99 notify_change +EXPORT_SYMBOL vmlinux 0x2e9a7958 mmc_release_host +EXPORT_SYMBOL vmlinux 0x2eb436cc xfrm_state_unregister_afinfo +EXPORT_SYMBOL vmlinux 0x2eb9543f i2c_verify_client +EXPORT_SYMBOL vmlinux 0x2ebe4cd9 block_invalidatepage +EXPORT_SYMBOL vmlinux 0x2eec63c9 xdr_encode_netobj +EXPORT_SYMBOL vmlinux 0x2f2e5906 inode_init_once +EXPORT_SYMBOL vmlinux 0x2f463268 start_tty +EXPORT_SYMBOL vmlinux 0x2f78b1d8 km_new_mapping +EXPORT_SYMBOL vmlinux 0x2ff54e07 rpc_mkpipe +EXPORT_SYMBOL vmlinux 0x3000b2b7 __pskb_pull_tail +EXPORT_SYMBOL vmlinux 0x30844fed journal_force_commit +EXPORT_SYMBOL vmlinux 0x30870e6e i2c_smbus_write_byte +EXPORT_SYMBOL vmlinux 0x3096be16 names_cachep +EXPORT_SYMBOL vmlinux 0x30e74134 tty_termios_copy_hw +EXPORT_SYMBOL vmlinux 0x3108c9b3 splice_direct_to_actor +EXPORT_SYMBOL vmlinux 0x310917fe sort +EXPORT_SYMBOL vmlinux 0x313341a3 _set_bit_le +EXPORT_SYMBOL vmlinux 0x313ff945 md_write_end +EXPORT_SYMBOL vmlinux 0x3145216f pci_dev_present +EXPORT_SYMBOL vmlinux 0x3147857d default_red +EXPORT_SYMBOL vmlinux 0x315add6e init_mm +EXPORT_SYMBOL vmlinux 0x315c65fd zlib_deflateInit2 +EXPORT_SYMBOL vmlinux 0x3166dfc2 register_console +EXPORT_SYMBOL vmlinux 0x31705d25 ____pagevec_lru_add +EXPORT_SYMBOL vmlinux 0x31b31f5c csum_partial_copy_nocheck +EXPORT_SYMBOL vmlinux 0x31b6b50e scsi_add_device +EXPORT_SYMBOL vmlinux 0x31e3d49a elevator_exit +EXPORT_SYMBOL vmlinux 0x31ff149f tty_insert_flip_string +EXPORT_SYMBOL vmlinux 0x321a3c31 vfs_follow_link +EXPORT_SYMBOL vmlinux 0x322b8862 tcp_proc_register +EXPORT_SYMBOL vmlinux 0x323222ba mutex_unlock +EXPORT_SYMBOL vmlinux 0x3247eedc skb_abort_seq_read +EXPORT_SYMBOL vmlinux 0x3283961f skb_under_panic +EXPORT_SYMBOL vmlinux 0x328a05f1 strncpy +EXPORT_SYMBOL vmlinux 0x329199b6 inet_sendmsg +EXPORT_SYMBOL vmlinux 0x329ce8c9 filemap_write_and_wait +EXPORT_SYMBOL vmlinux 0x32bfa3f4 dm_get_mapinfo +EXPORT_SYMBOL vmlinux 0x32ce623a sg_last +EXPORT_SYMBOL vmlinux 0x330a6522 iget5_locked +EXPORT_SYMBOL vmlinux 0x33435322 dev_get_by_flags +EXPORT_SYMBOL vmlinux 0x3360a963 param_set_ulong +EXPORT_SYMBOL vmlinux 0x33663e32 inet_csk_accept +EXPORT_SYMBOL vmlinux 0x336ad2ca clk_disable +EXPORT_SYMBOL vmlinux 0x3379253b revalidate_disk +EXPORT_SYMBOL vmlinux 0x33a1f7b4 bio_init +EXPORT_SYMBOL vmlinux 0x33c80d48 cache_purge +EXPORT_SYMBOL vmlinux 0x33c88228 xdr_write_pages +EXPORT_SYMBOL vmlinux 0x33d77d8e devm_free_irq +EXPORT_SYMBOL vmlinux 0x33d8b8df arp_create +EXPORT_SYMBOL vmlinux 0x340dec34 do_mmap_pgoff +EXPORT_SYMBOL vmlinux 0x340f84c6 release_sock +EXPORT_SYMBOL vmlinux 0x34417205 bd_release +EXPORT_SYMBOL vmlinux 0x3464f9d4 nla_put_nohdr +EXPORT_SYMBOL vmlinux 0x346b482f __kill_fasync +EXPORT_SYMBOL vmlinux 0x34908c14 print_hex_dump_bytes +EXPORT_SYMBOL vmlinux 0x349cba85 strchr +EXPORT_SYMBOL vmlinux 0x34c465b3 fbcon_set_bitops +EXPORT_SYMBOL vmlinux 0x35326646 key_validate +EXPORT_SYMBOL vmlinux 0x353e3fa5 __get_user_4 +EXPORT_SYMBOL vmlinux 0x354192c4 dcache_dir_close +EXPORT_SYMBOL vmlinux 0x35493661 neigh_resolve_output +EXPORT_SYMBOL vmlinux 0x354dc357 scsi_release_buffers +EXPORT_SYMBOL vmlinux 0x3569a6cf generic_setxattr +EXPORT_SYMBOL vmlinux 0x359103fe bioset_create +EXPORT_SYMBOL vmlinux 0x3595eb9b blk_unplug +EXPORT_SYMBOL vmlinux 0x359c8778 nobh_write_begin +EXPORT_SYMBOL vmlinux 0x35c60a02 mnt_unpin +EXPORT_SYMBOL vmlinux 0x35da3bcc scsi_report_device_reset +EXPORT_SYMBOL vmlinux 0x360b1afe probe_irq_mask +EXPORT_SYMBOL vmlinux 0x3622b2dc lock_sock_nested +EXPORT_SYMBOL vmlinux 0x363ad247 cap_set_effective +EXPORT_SYMBOL vmlinux 0x366bdeaa init_timer +EXPORT_SYMBOL vmlinux 0x366e14d4 open_bdev_exclusive +EXPORT_SYMBOL vmlinux 0x3686ea09 spi_print_msg +EXPORT_SYMBOL vmlinux 0x36afa673 amba_request_regions +EXPORT_SYMBOL vmlinux 0x36c96579 dm_kcopyd_client_create +EXPORT_SYMBOL vmlinux 0x36e47222 remove_wait_queue +EXPORT_SYMBOL vmlinux 0x36ebe42d kmem_cache_free +EXPORT_SYMBOL vmlinux 0x36f3bb1a fb_firmware_edid +EXPORT_SYMBOL vmlinux 0x370ad803 kthread_create +EXPORT_SYMBOL vmlinux 0x3744cf36 vmalloc_to_pfn +EXPORT_SYMBOL vmlinux 0x374ed073 scnprintf +EXPORT_SYMBOL vmlinux 0x375370c6 sock_get_timestampns +EXPORT_SYMBOL vmlinux 0x37698140 pci_find_bus +EXPORT_SYMBOL vmlinux 0x3788eb5d page_put_link +EXPORT_SYMBOL vmlinux 0x378c72ce proto_register +EXPORT_SYMBOL vmlinux 0x37a93b4a skb_copy_bits +EXPORT_SYMBOL vmlinux 0x37af6a0a abort_exclusive_wait +EXPORT_SYMBOL vmlinux 0x37befc70 jiffies_to_msecs +EXPORT_SYMBOL vmlinux 0x37d0ffea bitmap_cond_end_sync +EXPORT_SYMBOL vmlinux 0x37e74642 get_jiffies_64 +EXPORT_SYMBOL vmlinux 0x37f743a1 pci_find_next_bus +EXPORT_SYMBOL vmlinux 0x380a59b5 i2c_get_adapter +EXPORT_SYMBOL vmlinux 0x382126eb genl_sock +EXPORT_SYMBOL vmlinux 0x383c50ed xdr_decode_word +EXPORT_SYMBOL vmlinux 0x385395b1 input_unregister_handle +EXPORT_SYMBOL vmlinux 0x386dc97c prepare_binprm +EXPORT_SYMBOL vmlinux 0x387c0967 vfs_lstat +EXPORT_SYMBOL vmlinux 0x388f9128 xfrm_state_walk_done +EXPORT_SYMBOL vmlinux 0x38e8378d pgprot_kernel +EXPORT_SYMBOL vmlinux 0x390608dd bio_get_nr_vecs +EXPORT_SYMBOL vmlinux 0x390df5ff udp_lib_get_port +EXPORT_SYMBOL vmlinux 0x3975d415 simple_getattr +EXPORT_SYMBOL vmlinux 0x39784fce security_d_instantiate +EXPORT_SYMBOL vmlinux 0x3980aac1 unregister_reboot_notifier +EXPORT_SYMBOL vmlinux 0x39c6075e fb_blank +EXPORT_SYMBOL vmlinux 0x39c8ff3d d_lookup +EXPORT_SYMBOL vmlinux 0x39fd35d5 __kfree_skb +EXPORT_SYMBOL vmlinux 0x3a2204c6 security_netlink_recv +EXPORT_SYMBOL vmlinux 0x3a244289 neigh_sysctl_unregister +EXPORT_SYMBOL vmlinux 0x3a2667ac scsi_register_interface +EXPORT_SYMBOL vmlinux 0x3a2e30c2 copy_io_context +EXPORT_SYMBOL vmlinux 0x3a84849a ps2_command +EXPORT_SYMBOL vmlinux 0x3a9b6fb9 blk_unregister_region +EXPORT_SYMBOL vmlinux 0x3aab1ff2 remap_vmalloc_range +EXPORT_SYMBOL vmlinux 0x3ab2d174 down_killable +EXPORT_SYMBOL vmlinux 0x3ac80820 set_page_dirty +EXPORT_SYMBOL vmlinux 0x3adc15b9 posix_acl_from_mode +EXPORT_SYMBOL vmlinux 0x3ae831b6 kref_init +EXPORT_SYMBOL vmlinux 0x3b13b037 proc_doulongvec_minmax +EXPORT_SYMBOL vmlinux 0x3b2b58ca sk_stream_write_space +EXPORT_SYMBOL vmlinux 0x3b7b0ead unlock_buffer +EXPORT_SYMBOL vmlinux 0x3b7ec636 scsi_unregister +EXPORT_SYMBOL vmlinux 0x3bb2816c sock_kmalloc +EXPORT_SYMBOL vmlinux 0x3bc9be86 pci_find_capability +EXPORT_SYMBOL vmlinux 0x3bd1b1f6 msecs_to_jiffies +EXPORT_SYMBOL vmlinux 0x3c0e331d pskb_expand_head +EXPORT_SYMBOL vmlinux 0x3c2c5af5 sprintf +EXPORT_SYMBOL vmlinux 0x3c628a9c serio_close +EXPORT_SYMBOL vmlinux 0x3c6335b3 xdr_reserve_space +EXPORT_SYMBOL vmlinux 0x3c651d72 task_pgrp_nr_ns +EXPORT_SYMBOL vmlinux 0x3c9d1211 string_get_size +EXPORT_SYMBOL vmlinux 0x3cb8a495 param_get_string +EXPORT_SYMBOL vmlinux 0x3cc0a3bb xfrm_spd_getinfo +EXPORT_SYMBOL vmlinux 0x3cca7a8f dst_alloc +EXPORT_SYMBOL vmlinux 0x3cce7de2 inode_needs_sync +EXPORT_SYMBOL vmlinux 0x3cde0f2c journal_check_used_features +EXPORT_SYMBOL vmlinux 0x3ce4ca6f disable_irq +EXPORT_SYMBOL vmlinux 0x3cfeb818 generic_file_splice_write_nolock +EXPORT_SYMBOL vmlinux 0x3d1d12d6 clocksource_register +EXPORT_SYMBOL vmlinux 0x3d3c540f elf_hwcap +EXPORT_SYMBOL vmlinux 0x3d4bc2eb remove_proc_entry +EXPORT_SYMBOL vmlinux 0x3d68a2ae generic_writepages +EXPORT_SYMBOL vmlinux 0x3d68bd4b flow_cache_genid +EXPORT_SYMBOL vmlinux 0x3d8038ca d_invalidate +EXPORT_SYMBOL vmlinux 0x3d9176b3 input_register_handle +EXPORT_SYMBOL vmlinux 0x3e0cef78 blk_plug_device_unlocked +EXPORT_SYMBOL vmlinux 0x3e0e0c3a neigh_changeaddr +EXPORT_SYMBOL vmlinux 0x3e45e9ff register_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x3e6caebd add_wait_queue_exclusive +EXPORT_SYMBOL vmlinux 0x3ed63055 zlib_inflateReset +EXPORT_SYMBOL vmlinux 0x3ef210f7 bh_uptodate_or_lock +EXPORT_SYMBOL vmlinux 0x3f2de089 blk_queue_make_request +EXPORT_SYMBOL vmlinux 0x3f4547a7 put_unused_fd +EXPORT_SYMBOL vmlinux 0x3f4a9465 mark_buffer_dirty +EXPORT_SYMBOL vmlinux 0x3fad242d vfs_llseek +EXPORT_SYMBOL vmlinux 0x3fd00b8c open_by_devnum +EXPORT_SYMBOL vmlinux 0x3fd14fa7 mntput_no_expire +EXPORT_SYMBOL vmlinux 0x3fe1a245 contig_page_data +EXPORT_SYMBOL vmlinux 0x3ff62317 local_bh_disable +EXPORT_SYMBOL vmlinux 0x40123aeb idr_for_each +EXPORT_SYMBOL vmlinux 0x401a4855 i2c_put_adapter +EXPORT_SYMBOL vmlinux 0x4059792f print_hex_dump +EXPORT_SYMBOL vmlinux 0x405c1144 get_seconds +EXPORT_SYMBOL vmlinux 0x407136b1 __put_user_8 +EXPORT_SYMBOL vmlinux 0x409873e3 tty_termios_baud_rate +EXPORT_SYMBOL vmlinux 0x40a6f522 __arm_ioremap +EXPORT_SYMBOL vmlinux 0x40ba9b1b __page_symlink +EXPORT_SYMBOL vmlinux 0x40c8ac9c skb_checksum_help +EXPORT_SYMBOL vmlinux 0x40e6e8e2 journal_invalidatepage +EXPORT_SYMBOL vmlinux 0x40f07981 __ashldi3 +EXPORT_SYMBOL vmlinux 0x4108e69a fb_match_mode +EXPORT_SYMBOL vmlinux 0x41166725 inet_frags_init_net +EXPORT_SYMBOL vmlinux 0x412ddc0c dcache_lock +EXPORT_SYMBOL vmlinux 0x4132d555 __dev_get_by_name +EXPORT_SYMBOL vmlinux 0x41482d8b strndup_user +EXPORT_SYMBOL vmlinux 0x4169018b blk_queue_ordered +EXPORT_SYMBOL vmlinux 0x416983d9 netdev_fix_features +EXPORT_SYMBOL vmlinux 0x4185cf4b radix_tree_lookup_slot +EXPORT_SYMBOL vmlinux 0x4188d439 neigh_rand_reach_time +EXPORT_SYMBOL vmlinux 0x41b2baa5 ethtool_op_get_flags +EXPORT_SYMBOL vmlinux 0x41b7b9ae register_netdevice +EXPORT_SYMBOL vmlinux 0x41be44e5 xfrm_policy_byid +EXPORT_SYMBOL vmlinux 0x41d298a5 page_symlink +EXPORT_SYMBOL vmlinux 0x4211c3c1 zlib_inflateInit2 +EXPORT_SYMBOL vmlinux 0x42224298 sscanf +EXPORT_SYMBOL vmlinux 0x4274dc4b inode_permission +EXPORT_SYMBOL vmlinux 0x42848f4e simple_dir_inode_operations +EXPORT_SYMBOL vmlinux 0x428616cb d_move +EXPORT_SYMBOL vmlinux 0x42a06e42 seq_release +EXPORT_SYMBOL vmlinux 0x42d02b2f mii_ethtool_sset +EXPORT_SYMBOL vmlinux 0x42e76dbc make_bad_inode +EXPORT_SYMBOL vmlinux 0x42ffd0d5 dmam_release_declared_memory +EXPORT_SYMBOL vmlinux 0x430205aa __sg_alloc_table +EXPORT_SYMBOL vmlinux 0x4302d0eb free_pages +EXPORT_SYMBOL vmlinux 0x43219801 __set_page_dirty_nobuffers +EXPORT_SYMBOL vmlinux 0x434fa55c release_console_sem +EXPORT_SYMBOL vmlinux 0x43620235 input_release_device +EXPORT_SYMBOL vmlinux 0x439c5f39 sget +EXPORT_SYMBOL vmlinux 0x43a26522 bio_uncopy_user +EXPORT_SYMBOL vmlinux 0x43ce64a0 tcp_v4_syn_recv_sock +EXPORT_SYMBOL vmlinux 0x43fc0617 elv_next_request +EXPORT_SYMBOL vmlinux 0x44161c19 unregister_shrinker +EXPORT_SYMBOL vmlinux 0x442e9562 tcp_timewait_state_process +EXPORT_SYMBOL vmlinux 0x4430486f pci_match_id +EXPORT_SYMBOL vmlinux 0x44314efb radix_tree_gang_lookup_tag_slot +EXPORT_SYMBOL vmlinux 0x44323cd8 scsi_print_sense +EXPORT_SYMBOL vmlinux 0x44402fdd blk_rq_append_bio +EXPORT_SYMBOL vmlinux 0x444071e8 sock_common_recvmsg +EXPORT_SYMBOL vmlinux 0x444779c4 nla_find +EXPORT_SYMBOL vmlinux 0x44643b93 __aeabi_lmul +EXPORT_SYMBOL vmlinux 0x446d3eca may_umount_tree +EXPORT_SYMBOL vmlinux 0x44a22168 ___pskb_trim +EXPORT_SYMBOL vmlinux 0x44ae7f76 arp_xmit +EXPORT_SYMBOL vmlinux 0x44b911c3 rb_replace_node +EXPORT_SYMBOL vmlinux 0x44c214d1 __wake_up_bit +EXPORT_SYMBOL vmlinux 0x44c3698a nla_reserve +EXPORT_SYMBOL vmlinux 0x44da5d0f __csum_ipv6_magic +EXPORT_SYMBOL vmlinux 0x44e9a829 match_token +EXPORT_SYMBOL vmlinux 0x450e291e seq_lseek +EXPORT_SYMBOL vmlinux 0x45a55ec8 __iounmap +EXPORT_SYMBOL vmlinux 0x45bda0d5 system_serial_low +EXPORT_SYMBOL vmlinux 0x45cc2a35 vfs_link +EXPORT_SYMBOL vmlinux 0x45e2dab9 i2c_release_client +EXPORT_SYMBOL vmlinux 0x45f381d1 sock_no_ioctl +EXPORT_SYMBOL vmlinux 0x45fe3d18 journal_get_undo_access +EXPORT_SYMBOL vmlinux 0x46061f72 generic_file_mmap +EXPORT_SYMBOL vmlinux 0x460af589 auth_domain_put +EXPORT_SYMBOL vmlinux 0x462a2e75 match_strlcpy +EXPORT_SYMBOL vmlinux 0x4673628c netlink_clear_multicast_users +EXPORT_SYMBOL vmlinux 0x469ba3c9 set_anon_super +EXPORT_SYMBOL vmlinux 0x46d3b28c __div0 +EXPORT_SYMBOL vmlinux 0x46d7c023 register_netdev +EXPORT_SYMBOL vmlinux 0x4719ba4e kfifo_free +EXPORT_SYMBOL vmlinux 0x472d2a9a radix_tree_lookup +EXPORT_SYMBOL vmlinux 0x473a10f8 xfrm4_prepare_output +EXPORT_SYMBOL vmlinux 0x474c33f1 deactivate_super +EXPORT_SYMBOL vmlinux 0x475100c2 inet_get_local_port_range +EXPORT_SYMBOL vmlinux 0x478968e4 get_sb_single +EXPORT_SYMBOL vmlinux 0x478e8a48 vfs_mknod +EXPORT_SYMBOL vmlinux 0x479875c2 tty_port_tty_get +EXPORT_SYMBOL vmlinux 0x479f427c generic_readlink +EXPORT_SYMBOL vmlinux 0x47b4ff85 mb_cache_entry_insert +EXPORT_SYMBOL vmlinux 0x47c62d70 xfrm_policy_flush +EXPORT_SYMBOL vmlinux 0x47d0fd5a scsi_host_set_state +EXPORT_SYMBOL vmlinux 0x47e15ae3 km_policy_notify +EXPORT_SYMBOL vmlinux 0x47f757de elf_platform +EXPORT_SYMBOL vmlinux 0x47fbc1b4 ethtool_op_get_ufo +EXPORT_SYMBOL vmlinux 0x48034724 zlib_deflateReset +EXPORT_SYMBOL vmlinux 0x4812e360 md_check_recovery +EXPORT_SYMBOL vmlinux 0x48443f8c file_remove_suid +EXPORT_SYMBOL vmlinux 0x4859b8bb rtc_year_days +EXPORT_SYMBOL vmlinux 0x485d2d23 vfs_create +EXPORT_SYMBOL vmlinux 0x486b6407 hweight64 +EXPORT_SYMBOL vmlinux 0x48a5b067 __machine_arch_type +EXPORT_SYMBOL vmlinux 0x48ac0cd9 scsi_device_quiesce +EXPORT_SYMBOL vmlinux 0x48ba28e6 simple_readpage +EXPORT_SYMBOL vmlinux 0x48f9f12d complete_all +EXPORT_SYMBOL vmlinux 0x4915264d scsi_init_io +EXPORT_SYMBOL vmlinux 0x493e25e1 udp_hash +EXPORT_SYMBOL vmlinux 0x49603fb8 security_sb_copy_data +EXPORT_SYMBOL vmlinux 0x49633078 inetdev_by_index +EXPORT_SYMBOL vmlinux 0x4981cbe9 scsi_setup_fs_cmnd +EXPORT_SYMBOL vmlinux 0x49a593ac blk_queue_max_hw_segments +EXPORT_SYMBOL vmlinux 0x49cc23b9 d_alloc_root +EXPORT_SYMBOL vmlinux 0x4a358252 __bitmap_subset +EXPORT_SYMBOL vmlinux 0x4a4ad860 uart_register_driver +EXPORT_SYMBOL vmlinux 0x4a4c23bf brioctl_set +EXPORT_SYMBOL vmlinux 0x4a5b9063 elv_add_request +EXPORT_SYMBOL vmlinux 0x4a5f7ee3 mii_check_link +EXPORT_SYMBOL vmlinux 0x4a73037b inet_bind +EXPORT_SYMBOL vmlinux 0x4a971ec7 radix_tree_delete +EXPORT_SYMBOL vmlinux 0x4aa78ae8 sb_set_blocksize +EXPORT_SYMBOL vmlinux 0x4aaabd04 pci_reenable_device +EXPORT_SYMBOL vmlinux 0x4abd5fe4 block_sync_page +EXPORT_SYMBOL vmlinux 0x4ac42259 dm_get_device +EXPORT_SYMBOL vmlinux 0x4acfd8ad down_interruptible +EXPORT_SYMBOL vmlinux 0x4ae56528 create_proc_entry +EXPORT_SYMBOL vmlinux 0x4aea4791 __strncpy_from_user +EXPORT_SYMBOL vmlinux 0x4af7bc5a pcibios_bus_to_resource +EXPORT_SYMBOL vmlinux 0x4afe9a77 scsi_partsize +EXPORT_SYMBOL vmlinux 0x4b0e60e5 generic_ro_fops +EXPORT_SYMBOL vmlinux 0x4b1c166c bio_put +EXPORT_SYMBOL vmlinux 0x4b2f14b4 jiffies_to_timespec +EXPORT_SYMBOL vmlinux 0x4b34fbf5 block_all_signals +EXPORT_SYMBOL vmlinux 0x4b57898e dm_table_get +EXPORT_SYMBOL vmlinux 0x4b5a5235 scsi_reset_provider +EXPORT_SYMBOL vmlinux 0x4b89ce1f __sk_mem_schedule +EXPORT_SYMBOL vmlinux 0x4b8edde9 complete_and_exit +EXPORT_SYMBOL vmlinux 0x4b9f3684 kfifo_init +EXPORT_SYMBOL vmlinux 0x4bbc3e5f pm_flags +EXPORT_SYMBOL vmlinux 0x4bdde6e3 pcim_iomap_regions_request_all +EXPORT_SYMBOL vmlinux 0x4bfdc42f inet_frags_exit_net +EXPORT_SYMBOL vmlinux 0x4c1182cb bitmap_scnprintf +EXPORT_SYMBOL vmlinux 0x4c259e83 get_super +EXPORT_SYMBOL vmlinux 0x4c5e5cf5 skb_gso_segment +EXPORT_SYMBOL vmlinux 0x4c61abaa netif_rx +EXPORT_SYMBOL vmlinux 0x4cbbd171 __bitmap_weight +EXPORT_SYMBOL vmlinux 0x4d0d163d copy_page +EXPORT_SYMBOL vmlinux 0x4d2dbbe4 nla_put +EXPORT_SYMBOL vmlinux 0x4d2fbd32 generic_make_request +EXPORT_SYMBOL vmlinux 0x4d3c153f sigprocmask +EXPORT_SYMBOL vmlinux 0x4d6214d7 boot_tvec_bases +EXPORT_SYMBOL vmlinux 0x4d65cb6c arm926_coherent_kern_range +EXPORT_SYMBOL vmlinux 0x4d93719d netdev_class_remove_file +EXPORT_SYMBOL vmlinux 0x4d9bc465 log_wait_commit +EXPORT_SYMBOL vmlinux 0x4dc785f0 skb_append_datato_frags +EXPORT_SYMBOL vmlinux 0x4dde4ecd tty_write_room +EXPORT_SYMBOL vmlinux 0x4de203c6 security_inode_init_security +EXPORT_SYMBOL vmlinux 0x4dec6038 memscan +EXPORT_SYMBOL vmlinux 0x4df119fa __bitmap_parse +EXPORT_SYMBOL vmlinux 0x4e0009da idr_get_new_above +EXPORT_SYMBOL vmlinux 0x4e0afbc4 scsi_remove_target +EXPORT_SYMBOL vmlinux 0x4e3567f7 match_int +EXPORT_SYMBOL vmlinux 0x4e398697 neigh_table_init +EXPORT_SYMBOL vmlinux 0x4e62da40 kernel_read +EXPORT_SYMBOL vmlinux 0x4e6e8ea7 fg_console +EXPORT_SYMBOL vmlinux 0x4e830a3e strnicmp +EXPORT_SYMBOL vmlinux 0x4e835671 journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0x4e91d0a1 udp_ioctl +EXPORT_SYMBOL vmlinux 0x4e9389ae scsi_free_command +EXPORT_SYMBOL vmlinux 0x4f0ea0c0 up +EXPORT_SYMBOL vmlinux 0x4f398858 mb_cache_shrink +EXPORT_SYMBOL vmlinux 0x4f5651c3 tcp_sockets_allocated +EXPORT_SYMBOL vmlinux 0x4f767689 xdr_buf_from_iov +EXPORT_SYMBOL vmlinux 0x4fb0c254 register_con_driver +EXPORT_SYMBOL vmlinux 0x4ff55698 unregister_sysctl_table +EXPORT_SYMBOL vmlinux 0x4ffdff11 del_gendisk +EXPORT_SYMBOL vmlinux 0x503c1dfd set_binfmt +EXPORT_SYMBOL vmlinux 0x50472181 test_set_page_writeback +EXPORT_SYMBOL vmlinux 0x504e7a47 blk_queue_stack_limits +EXPORT_SYMBOL vmlinux 0x5093fa82 _clear_bit_le +EXPORT_SYMBOL vmlinux 0x50a31a5c skb_find_text +EXPORT_SYMBOL vmlinux 0x50cd0834 tty_chars_in_buffer +EXPORT_SYMBOL vmlinux 0x50e37e66 bio_endio +EXPORT_SYMBOL vmlinux 0x50f27aa9 pci_bus_read_config_word +EXPORT_SYMBOL vmlinux 0x50f5ca01 simple_release_fs +EXPORT_SYMBOL vmlinux 0x5148c5ab input_allocate_device +EXPORT_SYMBOL vmlinux 0x51493d94 finish_wait +EXPORT_SYMBOL vmlinux 0x516a372d icmp_send +EXPORT_SYMBOL vmlinux 0x51908eb8 __raw_writesl +EXPORT_SYMBOL vmlinux 0x51bd563d locks_mandatory_area +EXPORT_SYMBOL vmlinux 0x51cd47e2 groups_alloc +EXPORT_SYMBOL vmlinux 0x51cf0278 audit_log_start +EXPORT_SYMBOL vmlinux 0x51dce73b xfrm_state_walk_init +EXPORT_SYMBOL vmlinux 0x51ef33b8 kstrndup +EXPORT_SYMBOL vmlinux 0x52026cdf security_sb_parse_opts_str +EXPORT_SYMBOL vmlinux 0x52150c9c sock_create_lite +EXPORT_SYMBOL vmlinux 0x52354a0b mutex_trylock +EXPORT_SYMBOL vmlinux 0x5267a27b tty_insert_flip_string_flags +EXPORT_SYMBOL vmlinux 0x528c709d simple_read_from_buffer +EXPORT_SYMBOL vmlinux 0x52a58c24 ifla_policy +EXPORT_SYMBOL vmlinux 0x52dbe630 poll_freewait +EXPORT_SYMBOL vmlinux 0x531cd4c1 __starget_for_each_device +EXPORT_SYMBOL vmlinux 0x532f2924 param_get_byte +EXPORT_SYMBOL vmlinux 0x53326531 mempool_alloc_pages +EXPORT_SYMBOL vmlinux 0x534d5236 bio_unmap_user +EXPORT_SYMBOL vmlinux 0x53958d61 dm_io_client_destroy +EXPORT_SYMBOL vmlinux 0x53a193d6 qdisc_destroy +EXPORT_SYMBOL vmlinux 0x53c0767c sk_chk_filter +EXPORT_SYMBOL vmlinux 0x53dd4609 blkdev_issue_discard +EXPORT_SYMBOL vmlinux 0x53fe8b8a inet_sk_rebuild_header +EXPORT_SYMBOL vmlinux 0x540ef9e9 register_filesystem +EXPORT_SYMBOL vmlinux 0x54290dc9 nla_validate +EXPORT_SYMBOL vmlinux 0x54492fc8 scsi_get_host_dev +EXPORT_SYMBOL vmlinux 0x544caeff sock_get_timestamp +EXPORT_SYMBOL vmlinux 0x54560e5a ps2_cmd_aborted +EXPORT_SYMBOL vmlinux 0x54cfdc5c sock_wake_async +EXPORT_SYMBOL vmlinux 0x54d42936 seq_printf +EXPORT_SYMBOL vmlinux 0x54e6fcdd net_enable_timestamp +EXPORT_SYMBOL vmlinux 0x54f4fa88 sk_stream_error +EXPORT_SYMBOL vmlinux 0x55171b24 mtd_do_chip_probe +EXPORT_SYMBOL vmlinux 0x551c36ca sunrpc_cache_update +EXPORT_SYMBOL vmlinux 0x553012d3 proc_dointvec_minmax +EXPORT_SYMBOL vmlinux 0x55317976 xfrm_nl +EXPORT_SYMBOL vmlinux 0x5548bb0b clk_set_rate +EXPORT_SYMBOL vmlinux 0x557aee13 vfs_unlink +EXPORT_SYMBOL vmlinux 0x5584901d keyring_clear +EXPORT_SYMBOL vmlinux 0x558a8669 block_read_full_page +EXPORT_SYMBOL vmlinux 0x5594be03 bitmap_remap +EXPORT_SYMBOL vmlinux 0x55956dc3 bio_alloc_bioset +EXPORT_SYMBOL vmlinux 0x55acada3 __set_page_dirty_buffers +EXPORT_SYMBOL vmlinux 0x55cb6cd8 serio_open +EXPORT_SYMBOL vmlinux 0x55f92cbd pci_bus_size_bridges +EXPORT_SYMBOL vmlinux 0x5600904f fb_get_color_depth +EXPORT_SYMBOL vmlinux 0x5614b010 xfrm_policy_walk_done +EXPORT_SYMBOL vmlinux 0x5616e378 km_state_expired +EXPORT_SYMBOL vmlinux 0x5627f0d0 arp_tbl +EXPORT_SYMBOL vmlinux 0x562bae06 pci_release_regions +EXPORT_SYMBOL vmlinux 0x5635a60a vmalloc_user +EXPORT_SYMBOL vmlinux 0x564a7248 skb_recycle_check +EXPORT_SYMBOL vmlinux 0x56580777 sync_dirty_buffer +EXPORT_SYMBOL vmlinux 0x56618435 open_exec +EXPORT_SYMBOL vmlinux 0x5668caf0 icst307_khz_to_vco +EXPORT_SYMBOL vmlinux 0x568fe37c journal_stop +EXPORT_SYMBOL vmlinux 0x56c8799d scsi_kunmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x56f4d8fc pci_back_from_sleep +EXPORT_SYMBOL vmlinux 0x57016f92 skb_queue_purge +EXPORT_SYMBOL vmlinux 0x572e85d4 blk_lookup_devt +EXPORT_SYMBOL vmlinux 0x5756ab1b pcie_get_readrq +EXPORT_SYMBOL vmlinux 0x577712a0 bio_kmalloc +EXPORT_SYMBOL vmlinux 0x57806f2f per_cpu____irq_regs +EXPORT_SYMBOL vmlinux 0x57a6504e vsnprintf +EXPORT_SYMBOL vmlinux 0x5830e3f6 bd_set_size +EXPORT_SYMBOL vmlinux 0x583692b8 key_negate_and_link +EXPORT_SYMBOL vmlinux 0x583843ff tcp_simple_retransmit +EXPORT_SYMBOL vmlinux 0x5838f6c9 rtc_valid_tm +EXPORT_SYMBOL vmlinux 0x585aecb6 eth_header +EXPORT_SYMBOL vmlinux 0x58a0d1ef alloc_netdev_mq +EXPORT_SYMBOL vmlinux 0x58c46acc journal_clear_err +EXPORT_SYMBOL vmlinux 0x58c52f96 svc_destroy +EXPORT_SYMBOL vmlinux 0x58e0c277 key_put +EXPORT_SYMBOL vmlinux 0x59133cd6 pci_wake_from_d3 +EXPORT_SYMBOL vmlinux 0x59252ae9 uart_unregister_driver +EXPORT_SYMBOL vmlinux 0x5934392b fb_register_client +EXPORT_SYMBOL vmlinux 0x594311fc inet_frag_kill +EXPORT_SYMBOL vmlinux 0x594bf15b ioport_map +EXPORT_SYMBOL vmlinux 0x594e1317 __modsi3 +EXPORT_SYMBOL vmlinux 0x5953438e kill_block_super +EXPORT_SYMBOL vmlinux 0x59a584ac i2c_smbus_read_byte_data +EXPORT_SYMBOL vmlinux 0x59cc77b3 vm_insert_mixed +EXPORT_SYMBOL vmlinux 0x59d696b6 register_module_notifier +EXPORT_SYMBOL vmlinux 0x59d8223a ioport_resource +EXPORT_SYMBOL vmlinux 0x59e5070d __do_div64 +EXPORT_SYMBOL vmlinux 0x59fd8df9 lock_may_write +EXPORT_SYMBOL vmlinux 0x5a037936 sockfd_lookup +EXPORT_SYMBOL vmlinux 0x5a49a936 skb_recv_datagram +EXPORT_SYMBOL vmlinux 0x5a4e94de input_open_device +EXPORT_SYMBOL vmlinux 0x5a744b86 netlink_set_nonroot +EXPORT_SYMBOL vmlinux 0x5a940b6e request_firmware +EXPORT_SYMBOL vmlinux 0x5a94aeb4 mapping_tagged +EXPORT_SYMBOL vmlinux 0x5a9d18ef vmap +EXPORT_SYMBOL vmlinux 0x5abbe713 kill_pgrp +EXPORT_SYMBOL vmlinux 0x5af73c47 blk_dump_rq_flags +EXPORT_SYMBOL vmlinux 0x5b19634d div_s64_rem +EXPORT_SYMBOL vmlinux 0x5b1ba780 xfrm_state_insert +EXPORT_SYMBOL vmlinux 0x5b38dfa9 dma_sync_sg_for_device +EXPORT_SYMBOL vmlinux 0x5b730666 journal_abort +EXPORT_SYMBOL vmlinux 0x5b885f5f netif_receive_skb +EXPORT_SYMBOL vmlinux 0x5b92368d dma_alloc_writecombine +EXPORT_SYMBOL vmlinux 0x5b9975c7 noop_qdisc +EXPORT_SYMBOL vmlinux 0x5b99f126 generic_cont_expand_simple +EXPORT_SYMBOL vmlinux 0x5bc7e118 dmam_alloc_coherent +EXPORT_SYMBOL vmlinux 0x5c11d8c0 register_sound_mixer +EXPORT_SYMBOL vmlinux 0x5c673bc8 tty_mutex +EXPORT_SYMBOL vmlinux 0x5c77c566 scsi_dma_map +EXPORT_SYMBOL vmlinux 0x5c9284a0 processor_id +EXPORT_SYMBOL vmlinux 0x5cc6b96c input_register_handler +EXPORT_SYMBOL vmlinux 0x5cfeecd1 dmam_alloc_noncoherent +EXPORT_SYMBOL vmlinux 0x5d0f65fc tty_port_alloc_xmit_buf +EXPORT_SYMBOL vmlinux 0x5d4e0e71 inet_register_protosw +EXPORT_SYMBOL vmlinux 0x5d542a7c pskb_copy +EXPORT_SYMBOL vmlinux 0x5d6a89b3 devm_iounmap +EXPORT_SYMBOL vmlinux 0x5d8d6880 unregister_exec_domain +EXPORT_SYMBOL vmlinux 0x5d90e27e gnet_stats_finish_copy +EXPORT_SYMBOL vmlinux 0x5d945ac0 __lookup_hash +EXPORT_SYMBOL vmlinux 0x5da47805 sb_min_blocksize +EXPORT_SYMBOL vmlinux 0x5dd231e0 should_remove_suid +EXPORT_SYMBOL vmlinux 0x5dfa2160 serio_unregister_driver +EXPORT_SYMBOL vmlinux 0x5e061c34 scsi_execute_req +EXPORT_SYMBOL vmlinux 0x5e1f326e seq_open +EXPORT_SYMBOL vmlinux 0x5e5277ed journal_init_dev +EXPORT_SYMBOL vmlinux 0x5e8bf400 iget_locked +EXPORT_SYMBOL vmlinux 0x5e9fadd3 generic_file_aio_write_nolock +EXPORT_SYMBOL vmlinux 0x5ea520c5 tcp_select_initial_window +EXPORT_SYMBOL vmlinux 0x5ebb56fb down_read +EXPORT_SYMBOL vmlinux 0x5eda8f4e elevator_init +EXPORT_SYMBOL vmlinux 0x5edd0762 bin2bcd +EXPORT_SYMBOL vmlinux 0x5f0a6d37 dma_map_sg +EXPORT_SYMBOL vmlinux 0x5f181b41 set_bdi_congested +EXPORT_SYMBOL vmlinux 0x5f23b982 vfs_symlink +EXPORT_SYMBOL vmlinux 0x5f754e5a memset +EXPORT_SYMBOL vmlinux 0x5f845724 in_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0x5f8baa4c task_tgid_nr_ns +EXPORT_SYMBOL vmlinux 0x5f9099f6 init_file +EXPORT_SYMBOL vmlinux 0x5fe22e4e pci_set_master +EXPORT_SYMBOL vmlinux 0x5feb00fa tcp_parse_options +EXPORT_SYMBOL vmlinux 0x600683d3 do_unblank_screen +EXPORT_SYMBOL vmlinux 0x6018141d dm_put_device +EXPORT_SYMBOL vmlinux 0x602d47c0 cancel_delayed_work_sync +EXPORT_SYMBOL vmlinux 0x606d91cf get_sb_bdev +EXPORT_SYMBOL vmlinux 0x608c2831 warn_on_slowpath +EXPORT_SYMBOL vmlinux 0x609f1c7e synchronize_net +EXPORT_SYMBOL vmlinux 0x60a32ea9 pm_power_off +EXPORT_SYMBOL vmlinux 0x60a4efe2 ida_get_new +EXPORT_SYMBOL vmlinux 0x60b27473 write_inode_now +EXPORT_SYMBOL vmlinux 0x60bd9a5f skb_dma_unmap +EXPORT_SYMBOL vmlinux 0x60d5fbce con_set_default_unimap +EXPORT_SYMBOL vmlinux 0x60f5283c sock_init_data +EXPORT_SYMBOL vmlinux 0x612aceaa copy_strings_kernel +EXPORT_SYMBOL vmlinux 0x61593b72 __mod_timer +EXPORT_SYMBOL vmlinux 0x618d8299 set_notify_swap_entry_free +EXPORT_SYMBOL vmlinux 0x619c0f7a amba_driver_register +EXPORT_SYMBOL vmlinux 0x61aec1e8 seq_bitmap +EXPORT_SYMBOL vmlinux 0x61b7b126 simple_strtoull +EXPORT_SYMBOL vmlinux 0x61ff9b35 blk_free_tags +EXPORT_SYMBOL vmlinux 0x6210dae0 blk_rq_unmap_user +EXPORT_SYMBOL vmlinux 0x6224e944 sb_has_dirty_inodes +EXPORT_SYMBOL vmlinux 0x6254b23b try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x62665d85 __ip_select_ident +EXPORT_SYMBOL vmlinux 0x62737e1d sock_unregister +EXPORT_SYMBOL vmlinux 0x62827bec security_secctx_to_secid +EXPORT_SYMBOL vmlinux 0x62995533 elv_rb_find +EXPORT_SYMBOL vmlinux 0x62c8b7a7 inet_csk_reset_keepalive_timer +EXPORT_SYMBOL vmlinux 0x6336ae7f i2c_bit_add_bus +EXPORT_SYMBOL vmlinux 0x635d4be7 inet_addr_type +EXPORT_SYMBOL vmlinux 0x638102e7 page_zero_new_buffers +EXPORT_SYMBOL vmlinux 0x63aa5bab blk_queue_free_tags +EXPORT_SYMBOL vmlinux 0x63c5db38 i2c_master_send +EXPORT_SYMBOL vmlinux 0x63db71a4 skb_insert +EXPORT_SYMBOL vmlinux 0x63ecad53 register_netdevice_notifier +EXPORT_SYMBOL vmlinux 0x6403e338 tcp_memory_pressure +EXPORT_SYMBOL vmlinux 0x640a7078 posix_acl_create_masq +EXPORT_SYMBOL vmlinux 0x641a11f4 module_put +EXPORT_SYMBOL vmlinux 0x6422d136 tcp_rcv_state_process +EXPORT_SYMBOL vmlinux 0x64547a96 pcim_enable_device +EXPORT_SYMBOL vmlinux 0x646c2694 find_lock_page +EXPORT_SYMBOL vmlinux 0x64787994 fput +EXPORT_SYMBOL vmlinux 0x64999478 congestion_wait +EXPORT_SYMBOL vmlinux 0x64b6507b arp_broken_ops +EXPORT_SYMBOL vmlinux 0x64dba8a5 __splice_from_pipe +EXPORT_SYMBOL vmlinux 0x64f2981a request_key_async +EXPORT_SYMBOL vmlinux 0x651a4139 test_taint +EXPORT_SYMBOL vmlinux 0x65408378 zlib_inflate_blob +EXPORT_SYMBOL vmlinux 0x65414e67 dev_valid_name +EXPORT_SYMBOL vmlinux 0x656290b8 init_buffer +EXPORT_SYMBOL vmlinux 0x6572fdfb set_irq_chip +EXPORT_SYMBOL vmlinux 0x65a5c3a2 cpu_present_map +EXPORT_SYMBOL vmlinux 0x65e4bf7e pci_bus_write_config_dword +EXPORT_SYMBOL vmlinux 0x661d69ad unlock_super +EXPORT_SYMBOL vmlinux 0x661e6ec8 bioset_free +EXPORT_SYMBOL vmlinux 0x66303052 bdev_read_only +EXPORT_SYMBOL vmlinux 0x664487b8 blk_queue_resize_tags +EXPORT_SYMBOL vmlinux 0x6688609f cdev_init +EXPORT_SYMBOL vmlinux 0x668da8d5 zlib_inflateIncomp +EXPORT_SYMBOL vmlinux 0x668fb64e ethtool_op_get_link +EXPORT_SYMBOL vmlinux 0x66d04f72 __skb_recv_datagram +EXPORT_SYMBOL vmlinux 0x67028167 ip_fragment +EXPORT_SYMBOL vmlinux 0x6752c351 have_submounts +EXPORT_SYMBOL vmlinux 0x67b27ec1 tty_std_termios +EXPORT_SYMBOL vmlinux 0x67b664e4 skb_trim +EXPORT_SYMBOL vmlinux 0x67c2fa54 __copy_to_user +EXPORT_SYMBOL vmlinux 0x67c813b2 pci_unregister_driver +EXPORT_SYMBOL vmlinux 0x684600bc generic_show_options +EXPORT_SYMBOL vmlinux 0x6861db27 scsi_prep_return +EXPORT_SYMBOL vmlinux 0x6898a756 sg_init_table +EXPORT_SYMBOL vmlinux 0x689ca508 pcix_set_mmrbc +EXPORT_SYMBOL vmlinux 0x68a1cdf4 inet_csk_delete_keepalive_timer +EXPORT_SYMBOL vmlinux 0x68c896a1 pci_restore_state +EXPORT_SYMBOL vmlinux 0x68d904ed svcauth_unix_set_client +EXPORT_SYMBOL vmlinux 0x68edbda1 sock_sendmsg +EXPORT_SYMBOL vmlinux 0x6902b729 xdr_init_encode +EXPORT_SYMBOL vmlinux 0x691bd020 arm926_flush_user_cache_all +EXPORT_SYMBOL vmlinux 0x692c2d9c __request_region +EXPORT_SYMBOL vmlinux 0x69496641 mod_timer +EXPORT_SYMBOL vmlinux 0x69585969 sk_run_filter +EXPORT_SYMBOL vmlinux 0x6971447a rtc_month_days +EXPORT_SYMBOL vmlinux 0x69733c09 tcp_initialize_rcv_mss +EXPORT_SYMBOL vmlinux 0x697c182f clk_get +EXPORT_SYMBOL vmlinux 0x697e28c0 nlmsg_notify +EXPORT_SYMBOL vmlinux 0x69927dff try_acquire_console_sem +EXPORT_SYMBOL vmlinux 0x699d889d mb_cache_entry_release +EXPORT_SYMBOL vmlinux 0x69af2327 idr_init +EXPORT_SYMBOL vmlinux 0x69c8c1d5 security_req_classify_flow +EXPORT_SYMBOL vmlinux 0x69d38ed9 __scsi_print_sense +EXPORT_SYMBOL vmlinux 0x69e27c7a bitmap_copy_le +EXPORT_SYMBOL vmlinux 0x6a037cf1 mempool_kfree +EXPORT_SYMBOL vmlinux 0x6a14da5c vfs_rmdir +EXPORT_SYMBOL vmlinux 0x6a39ab87 user_path_at +EXPORT_SYMBOL vmlinux 0x6a47571d __set_personality +EXPORT_SYMBOL vmlinux 0x6a8cf947 scsi_device_lookup +EXPORT_SYMBOL vmlinux 0x6ac45c28 __up_write +EXPORT_SYMBOL vmlinux 0x6b1b67d3 __bdevname +EXPORT_SYMBOL vmlinux 0x6b29e0cf svc_set_num_threads +EXPORT_SYMBOL vmlinux 0x6b2dc060 dump_stack +EXPORT_SYMBOL vmlinux 0x6b90a903 elv_abort_queue +EXPORT_SYMBOL vmlinux 0x6bc56a14 scsi_eh_restore_cmnd +EXPORT_SYMBOL vmlinux 0x6be9d935 xdr_init_decode +EXPORT_SYMBOL vmlinux 0x6c07c2e4 cdev_del +EXPORT_SYMBOL vmlinux 0x6c15bf49 scsi_remove_device +EXPORT_SYMBOL vmlinux 0x6c1ce5ce strcspn +EXPORT_SYMBOL vmlinux 0x6c36a5c1 __mutex_init +EXPORT_SYMBOL vmlinux 0x6c3e40fb scsi_report_bus_reset +EXPORT_SYMBOL vmlinux 0x6c5cd59f journal_start_commit +EXPORT_SYMBOL vmlinux 0x6c61ce70 num_registered_fb +EXPORT_SYMBOL vmlinux 0x6c701840 __alloc_skb +EXPORT_SYMBOL vmlinux 0x6c702af7 sysctl_udp_rmem_min +EXPORT_SYMBOL vmlinux 0x6c89f1fb pcibios_fixup_bus +EXPORT_SYMBOL vmlinux 0x6cb29efc rtnl_create_link +EXPORT_SYMBOL vmlinux 0x6cc1eb1f bdevname +EXPORT_SYMBOL vmlinux 0x6cc5da48 put_tty_driver +EXPORT_SYMBOL vmlinux 0x6cdc5c6b nla_strlcpy +EXPORT_SYMBOL vmlinux 0x6cef247f __strnlen_user +EXPORT_SYMBOL vmlinux 0x6cfeda06 struct_module +EXPORT_SYMBOL vmlinux 0x6d0da34c param_get_short +EXPORT_SYMBOL vmlinux 0x6d27ef64 __bitmap_empty +EXPORT_SYMBOL vmlinux 0x6d288375 radix_tree_next_hole +EXPORT_SYMBOL vmlinux 0x6d28ac89 proc_dointvec_jiffies +EXPORT_SYMBOL vmlinux 0x6d294e43 clock_t_to_jiffies +EXPORT_SYMBOL vmlinux 0x6d340f64 tty_termios_input_baud_rate +EXPORT_SYMBOL vmlinux 0x6d498500 journal_lock_updates +EXPORT_SYMBOL vmlinux 0x6d5247d2 simple_lookup +EXPORT_SYMBOL vmlinux 0x6d662533 _find_first_bit_le +EXPORT_SYMBOL vmlinux 0x6d750037 dev_set_mac_address +EXPORT_SYMBOL vmlinux 0x6da02418 xdr_buf_subsegment +EXPORT_SYMBOL vmlinux 0x6dbe3d71 scsi_device_get +EXPORT_SYMBOL vmlinux 0x6def2db2 half_md4_transform +EXPORT_SYMBOL vmlinux 0x6e17973c sock_no_accept +EXPORT_SYMBOL vmlinux 0x6e440b58 memcpy_fromiovecend +EXPORT_SYMBOL vmlinux 0x6e46c452 scsi_unblock_requests +EXPORT_SYMBOL vmlinux 0x6e720ff2 rtnl_unlock +EXPORT_SYMBOL vmlinux 0x6e7212f8 netdev_set_master +EXPORT_SYMBOL vmlinux 0x6e73a275 proc_doulongvec_ms_jiffies_minmax +EXPORT_SYMBOL vmlinux 0x6e84a85c save_time_delta +EXPORT_SYMBOL vmlinux 0x6e9dd606 __symbol_put +EXPORT_SYMBOL vmlinux 0x6eea229d svcauth_unix_purge +EXPORT_SYMBOL vmlinux 0x6ef3cc51 kernel_getsockname +EXPORT_SYMBOL vmlinux 0x6f0936cc __dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0x6f264712 pneigh_enqueue +EXPORT_SYMBOL vmlinux 0x6f4be2a8 pci_bus_read_config_byte +EXPORT_SYMBOL vmlinux 0x6f4e4172 pci_set_consistent_dma_mask +EXPORT_SYMBOL vmlinux 0x6f77c8e5 setup_arg_pages +EXPORT_SYMBOL vmlinux 0x6f8b856e scsi_add_host +EXPORT_SYMBOL vmlinux 0x6fbb2ed3 skb_pull +EXPORT_SYMBOL vmlinux 0x6fbfc2fd scsi_ioctl +EXPORT_SYMBOL vmlinux 0x6fcb87a1 touch_softlockup_watchdog +EXPORT_SYMBOL vmlinux 0x70002ef4 pci_assign_resource +EXPORT_SYMBOL vmlinux 0x7008a9b7 timespec_to_jiffies +EXPORT_SYMBOL vmlinux 0x7018e256 ether_setup +EXPORT_SYMBOL vmlinux 0x701c2db1 __neigh_for_each_release +EXPORT_SYMBOL vmlinux 0x701d0ebd snprintf +EXPORT_SYMBOL vmlinux 0x7027c69c blk_rq_map_sg +EXPORT_SYMBOL vmlinux 0x703f2ae9 scm_detach_fds +EXPORT_SYMBOL vmlinux 0x704dc9ad scsicam_bios_param +EXPORT_SYMBOL vmlinux 0x706a0dcf journal_forget +EXPORT_SYMBOL vmlinux 0x706a7de6 netlink_rcv_skb +EXPORT_SYMBOL vmlinux 0x70aa202c proc_dointvec +EXPORT_SYMBOL vmlinux 0x70c32316 svc_create +EXPORT_SYMBOL vmlinux 0x7118d4c8 blk_verify_command +EXPORT_SYMBOL vmlinux 0x7129e5f8 hex_asc +EXPORT_SYMBOL vmlinux 0x7171121c overflowgid +EXPORT_SYMBOL vmlinux 0x7176b08f tty_devnum +EXPORT_SYMBOL vmlinux 0x71771cda serio_unregister_child_port +EXPORT_SYMBOL vmlinux 0x71940683 __neigh_event_send +EXPORT_SYMBOL vmlinux 0x71a50dbc register_blkdev +EXPORT_SYMBOL vmlinux 0x71a7e96e uart_add_one_port +EXPORT_SYMBOL vmlinux 0x71a8aa6b alloc_tty_driver +EXPORT_SYMBOL vmlinux 0x71c90087 memcmp +EXPORT_SYMBOL vmlinux 0x71cd1ed0 rtnl_set_sk_err +EXPORT_SYMBOL vmlinux 0x71fa908a cache_flush +EXPORT_SYMBOL vmlinux 0x7220b3a0 flush_old_exec +EXPORT_SYMBOL vmlinux 0x72270e35 do_gettimeofday +EXPORT_SYMBOL vmlinux 0x72608616 dev_mc_add +EXPORT_SYMBOL vmlinux 0x726a6d3d mb_cache_entry_alloc +EXPORT_SYMBOL vmlinux 0x72993bc3 skb_clone +EXPORT_SYMBOL vmlinux 0x72d5af61 try_wait_for_completion +EXPORT_SYMBOL vmlinux 0x72ea7b2d scsi_device_type +EXPORT_SYMBOL vmlinux 0x72fbae28 set_current_groups +EXPORT_SYMBOL vmlinux 0x7304b9d9 inet_stream_connect +EXPORT_SYMBOL vmlinux 0x73069aac cpu_possible_map +EXPORT_SYMBOL vmlinux 0x73265563 vlan_ioctl_set +EXPORT_SYMBOL vmlinux 0x7354a573 do_SAK +EXPORT_SYMBOL vmlinux 0x73572086 amba_device_register +EXPORT_SYMBOL vmlinux 0x737f3bba sock_wfree +EXPORT_SYMBOL vmlinux 0x7389da0d pid_task +EXPORT_SYMBOL vmlinux 0x739e734b mii_check_media +EXPORT_SYMBOL vmlinux 0x73a21680 unlock_new_inode +EXPORT_SYMBOL vmlinux 0x73e20c1c strlcpy +EXPORT_SYMBOL vmlinux 0x73fc6683 secpath_dup +EXPORT_SYMBOL vmlinux 0x747496f8 clk_register +EXPORT_SYMBOL vmlinux 0x7485e15e unregister_chrdev_region +EXPORT_SYMBOL vmlinux 0x74c825fc free_buffer_head +EXPORT_SYMBOL vmlinux 0x74cc238d current_kernel_time +EXPORT_SYMBOL vmlinux 0x74cd0097 filemap_fault +EXPORT_SYMBOL vmlinux 0x74f5bbb2 i2c_smbus_write_block_data +EXPORT_SYMBOL vmlinux 0x750be9b5 rtnl_unicast +EXPORT_SYMBOL vmlinux 0x7520afc5 ip_dev_find +EXPORT_SYMBOL vmlinux 0x752c1fda dst_release +EXPORT_SYMBOL vmlinux 0x7530cf9c pci_add_new_bus +EXPORT_SYMBOL vmlinux 0x7545f6da inode_get_bytes +EXPORT_SYMBOL vmlinux 0x7561520f invalidate_mapping_pages +EXPORT_SYMBOL vmlinux 0x756ac948 __xfrm_state_delete +EXPORT_SYMBOL vmlinux 0x7571b77a eth_header_parse +EXPORT_SYMBOL vmlinux 0x75823d79 find_task_by_pid_type_ns +EXPORT_SYMBOL vmlinux 0x75b5e78a xfrm_state_register_afinfo +EXPORT_SYMBOL vmlinux 0x75c21cd7 blk_rq_init +EXPORT_SYMBOL vmlinux 0x75fe16f7 end_buffer_read_sync +EXPORT_SYMBOL vmlinux 0x75fee7fd __raw_writesb +EXPORT_SYMBOL vmlinux 0x760a0f4f yield +EXPORT_SYMBOL vmlinux 0x760b2465 icst307_ps_to_vco +EXPORT_SYMBOL vmlinux 0x760b437a unregister_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x7636bfcc pci_set_dma_seg_boundary +EXPORT_SYMBOL vmlinux 0x765f75fb pgprot_user +EXPORT_SYMBOL vmlinux 0x76881360 leds_event +EXPORT_SYMBOL vmlinux 0x769437d4 pci_get_device +EXPORT_SYMBOL vmlinux 0x76aa5826 dm_table_get_size +EXPORT_SYMBOL vmlinux 0x76bf656d __bitmap_shift_left +EXPORT_SYMBOL vmlinux 0x76ca9817 dm_io_client_resize +EXPORT_SYMBOL vmlinux 0x76cf47f6 __aeabi_llsl +EXPORT_SYMBOL vmlinux 0x76d1205b nobh_write_end +EXPORT_SYMBOL vmlinux 0x76d297b1 scsi_target_quiesce +EXPORT_SYMBOL vmlinux 0x76d3cd60 laptop_mode +EXPORT_SYMBOL vmlinux 0x7758ca42 __scm_send +EXPORT_SYMBOL vmlinux 0x77669883 netlink_change_ngroups +EXPORT_SYMBOL vmlinux 0x776f2a6f netlink_kernel_release +EXPORT_SYMBOL vmlinux 0x7782bbf0 netif_device_detach +EXPORT_SYMBOL vmlinux 0x779b9858 wait_on_sync_kiocb +EXPORT_SYMBOL vmlinux 0x77ecac9f zlib_inflateEnd +EXPORT_SYMBOL vmlinux 0x78309a6a dev_mc_sync +EXPORT_SYMBOL vmlinux 0x78380b40 ps2_handle_response +EXPORT_SYMBOL vmlinux 0x7840867a scsi_cmd_print_sense_hdr +EXPORT_SYMBOL vmlinux 0x78540b7e fb_get_mode +EXPORT_SYMBOL vmlinux 0x7889b29e file_permission +EXPORT_SYMBOL vmlinux 0x788fe103 iomem_resource +EXPORT_SYMBOL vmlinux 0x78940162 __invalidate_device +EXPORT_SYMBOL vmlinux 0x78df6bd7 no_pci_devices +EXPORT_SYMBOL vmlinux 0x793dc9b2 block_truncate_page +EXPORT_SYMBOL vmlinux 0x794487ee disable_hlt +EXPORT_SYMBOL vmlinux 0x79600d4a wait_for_completion_killable +EXPORT_SYMBOL vmlinux 0x796a5f7b dget_locked +EXPORT_SYMBOL vmlinux 0x796fc5ce scsi_get_sense_info_fld +EXPORT_SYMBOL vmlinux 0x798769ce generic_write_end +EXPORT_SYMBOL vmlinux 0x799a6647 inet_ioctl +EXPORT_SYMBOL vmlinux 0x799cef42 cache_unregister +EXPORT_SYMBOL vmlinux 0x79a7f4d1 ethtool_op_set_sg +EXPORT_SYMBOL vmlinux 0x79aa04a2 get_random_bytes +EXPORT_SYMBOL vmlinux 0x79ad224b tasklet_kill +EXPORT_SYMBOL vmlinux 0x79c0f638 mmc_cleanup_queue +EXPORT_SYMBOL vmlinux 0x7a2a837d strict_strtol +EXPORT_SYMBOL vmlinux 0x7a784450 skb_copy_datagram_iovec +EXPORT_SYMBOL vmlinux 0x7aadd8e3 remap_pfn_range +EXPORT_SYMBOL vmlinux 0x7afc9d8a unregister_sound_mixer +EXPORT_SYMBOL vmlinux 0x7b0ea44b generic_file_readonly_mmap +EXPORT_SYMBOL vmlinux 0x7b21d686 pci_set_dma_mask +EXPORT_SYMBOL vmlinux 0x7b51dd4c cfi_fixup +EXPORT_SYMBOL vmlinux 0x7b701dc3 register_sound_special +EXPORT_SYMBOL vmlinux 0x7b81f4f9 neigh_seq_start +EXPORT_SYMBOL vmlinux 0x7b8fbead sysctl_ms_jiffies +EXPORT_SYMBOL vmlinux 0x7ba67901 inode_add_bytes +EXPORT_SYMBOL vmlinux 0x7c1c9e7c directly_mappable_cdev_bdi +EXPORT_SYMBOL vmlinux 0x7c60d66e getname +EXPORT_SYMBOL vmlinux 0x7c8cc644 svc_authenticate +EXPORT_SYMBOL vmlinux 0x7c904ded unregister_module_notifier +EXPORT_SYMBOL vmlinux 0x7c97ad82 inet_select_addr +EXPORT_SYMBOL vmlinux 0x7ca2e51d dev_unicast_unsync +EXPORT_SYMBOL vmlinux 0x7caef676 wait_on_page_bit +EXPORT_SYMBOL vmlinux 0x7cc035a7 __ucmpdi2 +EXPORT_SYMBOL vmlinux 0x7cc13115 input_set_capability +EXPORT_SYMBOL vmlinux 0x7cfb6477 misc_deregister +EXPORT_SYMBOL vmlinux 0x7d0b52cf deny_write_access +EXPORT_SYMBOL vmlinux 0x7d11c268 jiffies +EXPORT_SYMBOL vmlinux 0x7d276d2a give_up_console +EXPORT_SYMBOL vmlinux 0x7d2e8bd0 udp_sendmsg +EXPORT_SYMBOL vmlinux 0x7d49571a input_inject_event +EXPORT_SYMBOL vmlinux 0x7d5ea0fb dm_table_event +EXPORT_SYMBOL vmlinux 0x7d94d56b uart_get_baud_rate +EXPORT_SYMBOL vmlinux 0x7dceceac capable +EXPORT_SYMBOL vmlinux 0x7dd0ba31 blkdev_get +EXPORT_SYMBOL vmlinux 0x7df11c9e free_task +EXPORT_SYMBOL vmlinux 0x7df5d305 clear_bdi_congested +EXPORT_SYMBOL vmlinux 0x7df781e4 v4wb_clear_user_page +EXPORT_SYMBOL vmlinux 0x7e3db6b7 bitmap_end_sync +EXPORT_SYMBOL vmlinux 0x7e4ad0c1 sock_wmalloc +EXPORT_SYMBOL vmlinux 0x7e531cde del_timer +EXPORT_SYMBOL vmlinux 0x7e83e042 tcp_init_xmit_timers +EXPORT_SYMBOL vmlinux 0x7e96ec53 register_key_type +EXPORT_SYMBOL vmlinux 0x7e9ebb05 kernel_thread +EXPORT_SYMBOL vmlinux 0x7ea2c64f input_event +EXPORT_SYMBOL vmlinux 0x7ee44838 pci_enable_bridges +EXPORT_SYMBOL vmlinux 0x7ee662cc dev_driver_string +EXPORT_SYMBOL vmlinux 0x7f0ca7ca file_update_time +EXPORT_SYMBOL vmlinux 0x7f1ec751 mnt_pin +EXPORT_SYMBOL vmlinux 0x7f24de73 jiffies_to_usecs +EXPORT_SYMBOL vmlinux 0x7f503a2a bd_claim +EXPORT_SYMBOL vmlinux 0x7f5406c2 pci_disable_device +EXPORT_SYMBOL vmlinux 0x7f63b31e _memcpy_toio +EXPORT_SYMBOL vmlinux 0x7f8723bd pcie_mch_quirk +EXPORT_SYMBOL vmlinux 0x7fc169d4 ip_cmsg_recv +EXPORT_SYMBOL vmlinux 0x7fd968d9 sock_create +EXPORT_SYMBOL vmlinux 0x7ffefb0c scsi_put_command +EXPORT_SYMBOL vmlinux 0x800e4ffa __muldi3 +EXPORT_SYMBOL vmlinux 0x800edbed xfrm_policy_destroy +EXPORT_SYMBOL vmlinux 0x80136eb3 bitmap_close_sync +EXPORT_SYMBOL vmlinux 0x8043617a pcim_iomap +EXPORT_SYMBOL vmlinux 0x8058d5c6 rpc_unlink +EXPORT_SYMBOL vmlinux 0x8063f83d radix_tree_gang_lookup +EXPORT_SYMBOL vmlinux 0x806999a3 bh_submit_read +EXPORT_SYMBOL vmlinux 0x8085c7b1 prepare_to_wait +EXPORT_SYMBOL vmlinux 0x80944824 tcp_v4_conn_request +EXPORT_SYMBOL vmlinux 0x80bd6410 mii_ethtool_gset +EXPORT_SYMBOL vmlinux 0x80e22fdf blk_queue_prep_rq +EXPORT_SYMBOL vmlinux 0x80fe6ad1 sk_receive_skb +EXPORT_SYMBOL vmlinux 0x815b5dd4 match_octal +EXPORT_SYMBOL vmlinux 0x8162d3a0 ilookup5_nowait +EXPORT_SYMBOL vmlinux 0x81630028 vm_insert_pfn +EXPORT_SYMBOL vmlinux 0x81799cee vscnprintf +EXPORT_SYMBOL vmlinux 0x81b8ec4c ip4_datagram_connect +EXPORT_SYMBOL vmlinux 0x820d225f print_mac +EXPORT_SYMBOL vmlinux 0x82281edd i2c_smbus_process_call +EXPORT_SYMBOL vmlinux 0x8251bcc3 bitmap_release_region +EXPORT_SYMBOL vmlinux 0x82692209 kref_set +EXPORT_SYMBOL vmlinux 0x82ba155b simple_set_mnt +EXPORT_SYMBOL vmlinux 0x82c5ab1a force_sig +EXPORT_SYMBOL vmlinux 0x82e5a238 vm_get_page_prot +EXPORT_SYMBOL vmlinux 0x83021f20 sk_stream_wait_close +EXPORT_SYMBOL vmlinux 0x831cab7f journal_errno +EXPORT_SYMBOL vmlinux 0x8320bea8 __umodsi3 +EXPORT_SYMBOL vmlinux 0x8346a1ac dm_io_client_create +EXPORT_SYMBOL vmlinux 0x835b7cda xfrm_policy_unregister_afinfo +EXPORT_SYMBOL vmlinux 0x83632b40 bio_add_pc_page +EXPORT_SYMBOL vmlinux 0x8379dfaf key_unlink +EXPORT_SYMBOL vmlinux 0x8387c59c tcp_close +EXPORT_SYMBOL vmlinux 0x83a476ce bitmap_scnlistprintf +EXPORT_SYMBOL vmlinux 0x83f46a6d __sk_mem_reclaim +EXPORT_SYMBOL vmlinux 0x848602ad fb_get_buffer_offset +EXPORT_SYMBOL vmlinux 0x8487c206 fb_validate_mode +EXPORT_SYMBOL vmlinux 0x84b183ae strncmp +EXPORT_SYMBOL vmlinux 0x84c91879 elv_rq_merge_ok +EXPORT_SYMBOL vmlinux 0x85158239 tty_register_device +EXPORT_SYMBOL vmlinux 0x8539b178 cont_write_begin +EXPORT_SYMBOL vmlinux 0x85670f1d rtnl_is_locked +EXPORT_SYMBOL vmlinux 0x85770815 skb_realloc_headroom +EXPORT_SYMBOL vmlinux 0x857a4b9c inet_sock_destruct +EXPORT_SYMBOL vmlinux 0x85ac7f10 posix_acl_from_xattr +EXPORT_SYMBOL vmlinux 0x85d84059 vfs_write +EXPORT_SYMBOL vmlinux 0x85df9b6c strsep +EXPORT_SYMBOL vmlinux 0x85e7deb2 iov_iter_fault_in_readable +EXPORT_SYMBOL vmlinux 0x860f5881 dma_mmap_coherent +EXPORT_SYMBOL vmlinux 0x8639ebd6 pcie_set_readrq +EXPORT_SYMBOL vmlinux 0x864c9755 per_cpu__softnet_data +EXPORT_SYMBOL vmlinux 0x8685f85f blk_remove_plug +EXPORT_SYMBOL vmlinux 0x868acba5 get_options +EXPORT_SYMBOL vmlinux 0x86a96fbd __secpath_destroy +EXPORT_SYMBOL vmlinux 0x86b29b55 mark_page_accessed +EXPORT_SYMBOL vmlinux 0x86f79c5a kill_litter_super +EXPORT_SYMBOL vmlinux 0x86fb9b05 bitmap_parse_user +EXPORT_SYMBOL vmlinux 0x871c0a7e fiemap_check_flags +EXPORT_SYMBOL vmlinux 0x87200570 seq_path +EXPORT_SYMBOL vmlinux 0x872a85ae scsi_block_when_processing_errors +EXPORT_SYMBOL vmlinux 0x873b3379 pci_dev_get +EXPORT_SYMBOL vmlinux 0x8743d639 simple_pin_fs +EXPORT_SYMBOL vmlinux 0x8747deda handle_sysrq +EXPORT_SYMBOL vmlinux 0x87719daa mii_link_ok +EXPORT_SYMBOL vmlinux 0x8785725d param_set_charp +EXPORT_SYMBOL vmlinux 0x878ab3ce sysctl_tcp_adv_win_scale +EXPORT_SYMBOL vmlinux 0x87dc0386 scsi_print_result +EXPORT_SYMBOL vmlinux 0x87fb407a put_filp +EXPORT_SYMBOL vmlinux 0x880a311d i2c_use_client +EXPORT_SYMBOL vmlinux 0x880ce78a register_chrdev +EXPORT_SYMBOL vmlinux 0x881039d0 zlib_inflate +EXPORT_SYMBOL vmlinux 0x88244286 ip_mc_rejoin_group +EXPORT_SYMBOL vmlinux 0x882c037d skb_unlink +EXPORT_SYMBOL vmlinux 0x88f24621 __xfrm_state_destroy +EXPORT_SYMBOL vmlinux 0x8909ae7d kernel_getpeername +EXPORT_SYMBOL vmlinux 0x890e718f invalidate_partition +EXPORT_SYMBOL vmlinux 0x891e32b8 wait_for_completion_interruptible +EXPORT_SYMBOL vmlinux 0x897473df mktime +EXPORT_SYMBOL vmlinux 0x89867f4b pci_unmap_rom +EXPORT_SYMBOL vmlinux 0x89ac1d7b pci_scan_single_device +EXPORT_SYMBOL vmlinux 0x89d5538d fb_pad_aligned_buffer +EXPORT_SYMBOL vmlinux 0x89d66811 build_ehash_secret +EXPORT_SYMBOL vmlinux 0x89e19da0 do_munmap +EXPORT_SYMBOL vmlinux 0x8a01d2fd sock_no_socketpair +EXPORT_SYMBOL vmlinux 0x8a1203a9 kref_get +EXPORT_SYMBOL vmlinux 0x8a4fa83b __aeabi_llsr +EXPORT_SYMBOL vmlinux 0x8a7d1c31 high_memory +EXPORT_SYMBOL vmlinux 0x8a97da09 neigh_destroy +EXPORT_SYMBOL vmlinux 0x8a99a016 mempool_free_slab +EXPORT_SYMBOL vmlinux 0x8ab48206 __elv_add_request +EXPORT_SYMBOL vmlinux 0x8abbb879 udp_flush_pending_frames +EXPORT_SYMBOL vmlinux 0x8adf8432 tty_get_baud_rate +EXPORT_SYMBOL vmlinux 0x8ae01ef1 vfs_statfs +EXPORT_SYMBOL vmlinux 0x8b01926c vfs_rename +EXPORT_SYMBOL vmlinux 0x8b36e557 __mpage_writepage +EXPORT_SYMBOL vmlinux 0x8b53e459 scsi_is_sdev_device +EXPORT_SYMBOL vmlinux 0x8b618d08 overflowuid +EXPORT_SYMBOL vmlinux 0x8b7d00a6 vmalloc_to_page +EXPORT_SYMBOL vmlinux 0x8b9a4149 ida_destroy +EXPORT_SYMBOL vmlinux 0x8bbfa2b9 flow_cache_lookup +EXPORT_SYMBOL vmlinux 0x8c59445b ps2_handle_ack +EXPORT_SYMBOL vmlinux 0x8c7bc348 ida_remove +EXPORT_SYMBOL vmlinux 0x8c7f2df0 path_lookup +EXPORT_SYMBOL vmlinux 0x8c84069c restore_time_delta +EXPORT_SYMBOL vmlinux 0x8c9f41ca current_fs_time +EXPORT_SYMBOL vmlinux 0x8ced48ce tty_register_driver +EXPORT_SYMBOL vmlinux 0x8d2d9dbc sk_release_kernel +EXPORT_SYMBOL vmlinux 0x8d3345ee blk_queue_update_dma_pad +EXPORT_SYMBOL vmlinux 0x8d3894f2 _ctype +EXPORT_SYMBOL vmlinux 0x8d551bef sysctl_tcp_rmem +EXPORT_SYMBOL vmlinux 0x8d5642fc wait_for_completion_interruptible_timeout +EXPORT_SYMBOL vmlinux 0x8d5c44f4 kobject_init +EXPORT_SYMBOL vmlinux 0x8d6f81b4 __div64_32 +EXPORT_SYMBOL vmlinux 0x8d72be9e ethtool_op_set_tx_ipv6_csum +EXPORT_SYMBOL vmlinux 0x8d90bac0 iov_iter_copy_from_user_atomic +EXPORT_SYMBOL vmlinux 0x8da00761 tty_port_init +EXPORT_SYMBOL vmlinux 0x8da6df5b ip_mc_join_group +EXPORT_SYMBOL vmlinux 0x8dcb5c27 idr_remove +EXPORT_SYMBOL vmlinux 0x8dec5235 serio_rescan +EXPORT_SYMBOL vmlinux 0x8e0393f9 bio_map_kern +EXPORT_SYMBOL vmlinux 0x8e3c9cc3 vprintk +EXPORT_SYMBOL vmlinux 0x8e763ae1 send_remote_softirq +EXPORT_SYMBOL vmlinux 0x8e90772a svc_proc_register +EXPORT_SYMBOL vmlinux 0x8e95f86a svc_create_pooled +EXPORT_SYMBOL vmlinux 0x8eea2d13 blk_get_request +EXPORT_SYMBOL vmlinux 0x8f07d8ca __wait_on_bit +EXPORT_SYMBOL vmlinux 0x8f111be5 sk_common_release +EXPORT_SYMBOL vmlinux 0x8f4a4787 sock_common_setsockopt +EXPORT_SYMBOL vmlinux 0x8f6b13dd __brelse +EXPORT_SYMBOL vmlinux 0x8f6b7950 set_irq_data +EXPORT_SYMBOL vmlinux 0x8f7e5774 register_md_personality +EXPORT_SYMBOL vmlinux 0x8f9b86b2 kfifo_alloc +EXPORT_SYMBOL vmlinux 0x8fc606fd i2c_smbus_write_byte_data +EXPORT_SYMBOL vmlinux 0x8fff59bc sock_recvmsg +EXPORT_SYMBOL vmlinux 0x9013a386 xfrm_init_state +EXPORT_SYMBOL vmlinux 0x902cd3d0 inode_double_lock +EXPORT_SYMBOL vmlinux 0x90442ced scsi_mode_sense +EXPORT_SYMBOL vmlinux 0x906ad67c request_key_async_with_auxdata +EXPORT_SYMBOL vmlinux 0x9089bb3f md_unregister_thread +EXPORT_SYMBOL vmlinux 0x90a52e1b generic_mii_ioctl +EXPORT_SYMBOL vmlinux 0x90c91fa4 inet_accept +EXPORT_SYMBOL vmlinux 0x90e93cb4 wait_for_key_construction +EXPORT_SYMBOL vmlinux 0x91024af0 scsi_scan_host +EXPORT_SYMBOL vmlinux 0x9110798b init_net +EXPORT_SYMBOL vmlinux 0x913b39bf register_framebuffer +EXPORT_SYMBOL vmlinux 0x91433e0b spi_release_transport +EXPORT_SYMBOL vmlinux 0x91481982 __ratelimit +EXPORT_SYMBOL vmlinux 0x916e3609 kill_anon_super +EXPORT_SYMBOL vmlinux 0x919029aa __readwrite_bug +EXPORT_SYMBOL vmlinux 0x9215e247 mmc_free_host +EXPORT_SYMBOL vmlinux 0x9221cbbc dma_pool_create +EXPORT_SYMBOL vmlinux 0x92592e40 add_to_page_cache_locked +EXPORT_SYMBOL vmlinux 0x925c55a9 get_user_pages +EXPORT_SYMBOL vmlinux 0x926401f2 sg_copy_to_buffer +EXPORT_SYMBOL vmlinux 0x927bacc1 fb_set_suspend +EXPORT_SYMBOL vmlinux 0x92a0b4a7 elv_rb_former_request +EXPORT_SYMBOL vmlinux 0x92aa37c3 kthread_bind +EXPORT_SYMBOL vmlinux 0x92f64ec0 shrink_dcache_sb +EXPORT_SYMBOL vmlinux 0x938e2760 kblockd_schedule_work +EXPORT_SYMBOL vmlinux 0x93a6e0b2 io_schedule +EXPORT_SYMBOL vmlinux 0x93c35d77 nla_append +EXPORT_SYMBOL vmlinux 0x93c69acf param_set_byte +EXPORT_SYMBOL vmlinux 0x93d85e83 __xfrm_decode_session +EXPORT_SYMBOL vmlinux 0x93e2d091 tcp_setsockopt +EXPORT_SYMBOL vmlinux 0x93fca811 __get_free_pages +EXPORT_SYMBOL vmlinux 0x94061a0b __blockdev_direct_IO +EXPORT_SYMBOL vmlinux 0x9406e743 spi_dv_device +EXPORT_SYMBOL vmlinux 0x940ba99e kthread_stop +EXPORT_SYMBOL vmlinux 0x941688cf check_disk_change +EXPORT_SYMBOL vmlinux 0x9472f990 skb_pad +EXPORT_SYMBOL vmlinux 0x947c83d8 get_sb_pseudo +EXPORT_SYMBOL vmlinux 0x94961283 vunmap +EXPORT_SYMBOL vmlinux 0x949c320b tcp_v4_do_rcv +EXPORT_SYMBOL vmlinux 0x94a86a5b get_disk +EXPORT_SYMBOL vmlinux 0x94b53d5d rtnetlink_put_metrics +EXPORT_SYMBOL vmlinux 0x94cbba85 blkdev_issue_flush +EXPORT_SYMBOL vmlinux 0x94f8f390 blk_queue_find_tag +EXPORT_SYMBOL vmlinux 0x9501d078 __wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0x95408777 kobject_del +EXPORT_SYMBOL vmlinux 0x954cbb26 vsprintf +EXPORT_SYMBOL vmlinux 0x956ed9a9 f_setown +EXPORT_SYMBOL vmlinux 0x95819e2c svc_sock_names +EXPORT_SYMBOL vmlinux 0x95894046 cfi_varsize_frob +EXPORT_SYMBOL vmlinux 0x95a86c47 simple_link +EXPORT_SYMBOL vmlinux 0x95bd1cb9 generic_file_llseek +EXPORT_SYMBOL vmlinux 0x95db6bd5 dev_alloc_skb +EXPORT_SYMBOL vmlinux 0x95dbe078 __get_user_2 +EXPORT_SYMBOL vmlinux 0x95ff50e3 i2c_register_driver +EXPORT_SYMBOL vmlinux 0x96049d49 journal_revoke +EXPORT_SYMBOL vmlinux 0x9612b020 input_unregister_device +EXPORT_SYMBOL vmlinux 0x9636d661 __f_setown +EXPORT_SYMBOL vmlinux 0x965339ba dmam_pool_destroy +EXPORT_SYMBOL vmlinux 0x965b5238 netif_carrier_off +EXPORT_SYMBOL vmlinux 0x9666adbc devm_ioremap_nocache +EXPORT_SYMBOL vmlinux 0x96898769 sysfs_format_mac +EXPORT_SYMBOL vmlinux 0x96bc451c xfrm_policy_alloc +EXPORT_SYMBOL vmlinux 0x96c1f47d d_instantiate +EXPORT_SYMBOL vmlinux 0x96cd2b04 scsi_sense_key_string +EXPORT_SYMBOL vmlinux 0x96df5482 walk_stackframe +EXPORT_SYMBOL vmlinux 0x970dcf7c tty_unregister_device +EXPORT_SYMBOL vmlinux 0x972232b0 __nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0x97255bdf strlen +EXPORT_SYMBOL vmlinux 0x9745b460 blk_plug_device +EXPORT_SYMBOL vmlinux 0x9754ec10 radix_tree_preload +EXPORT_SYMBOL vmlinux 0x975e5e8b inet_dgram_ops +EXPORT_SYMBOL vmlinux 0x976650bf block_write_end +EXPORT_SYMBOL vmlinux 0x978590eb sunrpc_cache_lookup +EXPORT_SYMBOL vmlinux 0x97864b51 xfrm_find_acq +EXPORT_SYMBOL vmlinux 0x97fc62a5 find_vma +EXPORT_SYMBOL vmlinux 0x9809b308 xfrm_unregister_mode +EXPORT_SYMBOL vmlinux 0x981026f6 km_report +EXPORT_SYMBOL vmlinux 0x98211805 sysctl_string +EXPORT_SYMBOL vmlinux 0x9834106c tty_vhangup +EXPORT_SYMBOL vmlinux 0x98443eaf mmc_detect_change +EXPORT_SYMBOL vmlinux 0x986e6135 fb_pad_unaligned_buffer +EXPORT_SYMBOL vmlinux 0x988a905b filemap_fdatawrite_range +EXPORT_SYMBOL vmlinux 0x988b8f64 inet_csk_destroy_sock +EXPORT_SYMBOL vmlinux 0x989337ba neigh_parms_release +EXPORT_SYMBOL vmlinux 0x989b7075 scm_fp_dup +EXPORT_SYMBOL vmlinux 0x98f1e8f6 kern_path +EXPORT_SYMBOL vmlinux 0x99124017 skb_queue_head +EXPORT_SYMBOL vmlinux 0x99189d7d xfrm_state_add +EXPORT_SYMBOL vmlinux 0x99553368 __bio_clone +EXPORT_SYMBOL vmlinux 0x997dee07 __sk_dst_check +EXPORT_SYMBOL vmlinux 0x9981f69e scsi_allocate_command +EXPORT_SYMBOL vmlinux 0x9994c0ca ps2_is_keyboard_id +EXPORT_SYMBOL vmlinux 0x999c3148 __raw_readsb +EXPORT_SYMBOL vmlinux 0x999e8297 vfree +EXPORT_SYMBOL vmlinux 0x99aadb21 param_get_ulong +EXPORT_SYMBOL vmlinux 0x99bb8806 memmove +EXPORT_SYMBOL vmlinux 0x99bfbe39 get_unused_fd +EXPORT_SYMBOL vmlinux 0x99c3c0b0 vfs_fstat +EXPORT_SYMBOL vmlinux 0x99c95fa5 unregister_sound_special +EXPORT_SYMBOL vmlinux 0x99cd6886 tty_hangup +EXPORT_SYMBOL vmlinux 0x99cdc86b sysctl_tcp_reordering +EXPORT_SYMBOL vmlinux 0x99dae5e3 vfs_mkdir +EXPORT_SYMBOL vmlinux 0x99ea12ce panic_blink +EXPORT_SYMBOL vmlinux 0x99f92fe6 console_start +EXPORT_SYMBOL vmlinux 0x99f9da8e mmc_wait_for_req +EXPORT_SYMBOL vmlinux 0x9a044cd8 skb_push +EXPORT_SYMBOL vmlinux 0x9a1dfd65 strpbrk +EXPORT_SYMBOL vmlinux 0x9a2b0013 iput +EXPORT_SYMBOL vmlinux 0x9a3f6184 dev_mc_delete +EXPORT_SYMBOL vmlinux 0x9a80e95a tty_driver_kref_put +EXPORT_SYMBOL vmlinux 0x9abf0c48 __nla_put +EXPORT_SYMBOL vmlinux 0x9abf7c41 sk_stream_kill_queues +EXPORT_SYMBOL vmlinux 0x9ac14424 skb_copy_datagram_from_iovec +EXPORT_SYMBOL vmlinux 0x9ae39bfb fb_find_mode +EXPORT_SYMBOL vmlinux 0x9ae3dd00 journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0x9b1cd621 tty_set_operations +EXPORT_SYMBOL vmlinux 0x9b2183cf sock_queue_rcv_skb +EXPORT_SYMBOL vmlinux 0x9b2e58a4 fb_set_cmap +EXPORT_SYMBOL vmlinux 0x9b36c612 gnet_stats_copy_app +EXPORT_SYMBOL vmlinux 0x9b388444 get_zeroed_page +EXPORT_SYMBOL vmlinux 0x9b699329 generic_file_splice_read +EXPORT_SYMBOL vmlinux 0x9b9e12e0 svc_recv +EXPORT_SYMBOL vmlinux 0x9ba7089d argv_split +EXPORT_SYMBOL vmlinux 0x9bb612e4 soft_cursor +EXPORT_SYMBOL vmlinux 0x9bce482f __release_region +EXPORT_SYMBOL vmlinux 0x9bf94e9b md_register_thread +EXPORT_SYMBOL vmlinux 0x9c012508 fb_parse_edid +EXPORT_SYMBOL vmlinux 0x9c190df7 kill_fasync +EXPORT_SYMBOL vmlinux 0x9c2571f4 __down_read +EXPORT_SYMBOL vmlinux 0x9c7077bd enable_hlt +EXPORT_SYMBOL vmlinux 0x9c7e3537 journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x9c85cd64 xdr_inline_pages +EXPORT_SYMBOL vmlinux 0x9c87c05a blk_requeue_request +EXPORT_SYMBOL vmlinux 0x9ca8eddf xfrm_prepare_input +EXPORT_SYMBOL vmlinux 0x9ceb163c memcpy_toiovec +EXPORT_SYMBOL vmlinux 0x9cfd56c5 scsi_print_status +EXPORT_SYMBOL vmlinux 0x9d0b5f94 tty_unthrottle +EXPORT_SYMBOL vmlinux 0x9d144a0f tcp_connect +EXPORT_SYMBOL vmlinux 0x9d1be5b9 framebuffer_release +EXPORT_SYMBOL vmlinux 0x9d669763 memcpy +EXPORT_SYMBOL vmlinux 0x9d7b4234 bdi_init +EXPORT_SYMBOL vmlinux 0x9dcf9a11 scsi_remove_host +EXPORT_SYMBOL vmlinux 0x9e120414 ida_get_new_above +EXPORT_SYMBOL vmlinux 0x9e26e50c blk_queue_dma_pad +EXPORT_SYMBOL vmlinux 0x9e4209b4 clk_put +EXPORT_SYMBOL vmlinux 0x9e62d222 __scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0x9e7d6bd0 __udelay +EXPORT_SYMBOL vmlinux 0x9e91c457 journal_extend +EXPORT_SYMBOL vmlinux 0x9e95c63b neigh_compat_output +EXPORT_SYMBOL vmlinux 0x9ec5fd81 blk_rq_map_kern +EXPORT_SYMBOL vmlinux 0x9ed685ee iov_iter_advance +EXPORT_SYMBOL vmlinux 0x9ee70a89 sync_page_range_nolock +EXPORT_SYMBOL vmlinux 0x9eecde16 do_brk +EXPORT_SYMBOL vmlinux 0x9ef749e2 unregister_chrdev +EXPORT_SYMBOL vmlinux 0x9f00feb8 xfrm_input_resume +EXPORT_SYMBOL vmlinux 0x9f100139 jiffies_to_clock_t +EXPORT_SYMBOL vmlinux 0x9f2bdaac __bitmap_or +EXPORT_SYMBOL vmlinux 0x9f2c6508 lease_modify +EXPORT_SYMBOL vmlinux 0x9f6a0f0a may_umount +EXPORT_SYMBOL vmlinux 0x9f766dc8 bmap +EXPORT_SYMBOL vmlinux 0x9f984513 strrchr +EXPORT_SYMBOL vmlinux 0x9fb3dd30 memcpy_fromiovec +EXPORT_SYMBOL vmlinux 0x9fb6ea0b netlink_dump_start +EXPORT_SYMBOL vmlinux 0x9fbc6e4f blk_execute_rq +EXPORT_SYMBOL vmlinux 0x9fd6cf48 unregister_key_type +EXPORT_SYMBOL vmlinux 0x9fdf49ec __alloc_pages_internal +EXPORT_SYMBOL vmlinux 0x9ff2d0c3 tcp_ioctl +EXPORT_SYMBOL vmlinux 0xa0014ba8 __scsi_add_device +EXPORT_SYMBOL vmlinux 0xa0307dd9 xdr_inline_decode +EXPORT_SYMBOL vmlinux 0xa03523d5 security_unix_stream_connect +EXPORT_SYMBOL vmlinux 0xa05c03df mempool_kmalloc +EXPORT_SYMBOL vmlinux 0xa07a8d22 sleep_on +EXPORT_SYMBOL vmlinux 0xa07ac24b irq_stat +EXPORT_SYMBOL vmlinux 0xa0b04675 vmalloc_32 +EXPORT_SYMBOL vmlinux 0xa0ceef51 out_of_line_wait_on_bit +EXPORT_SYMBOL vmlinux 0xa0fbac79 wake_up_bit +EXPORT_SYMBOL vmlinux 0xa108eb4d sysctl_optmem_max +EXPORT_SYMBOL vmlinux 0xa10a35f1 default_unplug_io_fn +EXPORT_SYMBOL vmlinux 0xa10dcc13 getrawmonotonic +EXPORT_SYMBOL vmlinux 0xa120d33c tty_unregister_ldisc +EXPORT_SYMBOL vmlinux 0xa13798f8 printk_ratelimit +EXPORT_SYMBOL vmlinux 0xa1483685 scsi_register +EXPORT_SYMBOL vmlinux 0xa16a04bd compute_creds +EXPORT_SYMBOL vmlinux 0xa1b759ce fb_add_videomode +EXPORT_SYMBOL vmlinux 0xa1c76e0a _cond_resched +EXPORT_SYMBOL vmlinux 0xa1edfa27 scsi_host_put +EXPORT_SYMBOL vmlinux 0xa1f03bd5 touch_atime +EXPORT_SYMBOL vmlinux 0xa1f6b923 ethtool_op_set_tso +EXPORT_SYMBOL vmlinux 0xa1f7ff7c __find_get_block +EXPORT_SYMBOL vmlinux 0xa20ce1b8 net_msg_warn +EXPORT_SYMBOL vmlinux 0xa218bf61 complete +EXPORT_SYMBOL vmlinux 0xa22f919e journal_release_buffer +EXPORT_SYMBOL vmlinux 0xa2375ff5 dm_register_target +EXPORT_SYMBOL vmlinux 0xa299e41f bitmap_endwrite +EXPORT_SYMBOL vmlinux 0xa29b1708 tcp_memory_allocated +EXPORT_SYMBOL vmlinux 0xa2a5fd77 inet_ehash_secret +EXPORT_SYMBOL vmlinux 0xa2b72301 cfb_fillrect +EXPORT_SYMBOL vmlinux 0xa2e17125 unregister_netdevice +EXPORT_SYMBOL vmlinux 0xa2f7204e blk_start_queue +EXPORT_SYMBOL vmlinux 0xa3045902 find_get_pages_tag +EXPORT_SYMBOL vmlinux 0xa311693e send_sig_info +EXPORT_SYMBOL vmlinux 0xa329f07e register_shrinker +EXPORT_SYMBOL vmlinux 0xa337c6c5 pcix_get_mmrbc +EXPORT_SYMBOL vmlinux 0xa34a0337 kill_pid +EXPORT_SYMBOL vmlinux 0xa34b69a0 xfrm_state_alloc +EXPORT_SYMBOL vmlinux 0xa34f1ef5 crc32_le +EXPORT_SYMBOL vmlinux 0xa35de80f ipv4_config +EXPORT_SYMBOL vmlinux 0xa3a07811 d_add_ci +EXPORT_SYMBOL vmlinux 0xa3a4ed03 cond_resched_lock +EXPORT_SYMBOL vmlinux 0xa3bf8ba9 eth_header_cache_update +EXPORT_SYMBOL vmlinux 0xa3e44807 generic_write_checks +EXPORT_SYMBOL vmlinux 0xa4144036 bdget_disk +EXPORT_SYMBOL vmlinux 0xa4301e7d inode_double_unlock +EXPORT_SYMBOL vmlinux 0xa44e3dbf bdput +EXPORT_SYMBOL vmlinux 0xa48584d4 filemap_fdatawait +EXPORT_SYMBOL vmlinux 0xa4f33334 lease_get_mtime +EXPORT_SYMBOL vmlinux 0xa4f807bf lookup_bdev +EXPORT_SYMBOL vmlinux 0xa5068a7c i2c_smbus_read_i2c_block_data +EXPORT_SYMBOL vmlinux 0xa52a00fc cpu_sysdev_class +EXPORT_SYMBOL vmlinux 0xa5350e58 ethtool_op_get_tx_csum +EXPORT_SYMBOL vmlinux 0xa5423cc4 param_get_int +EXPORT_SYMBOL vmlinux 0xa548357a scsi_host_alloc +EXPORT_SYMBOL vmlinux 0xa54f2357 __devm_request_region +EXPORT_SYMBOL vmlinux 0xa5692003 simple_write_begin +EXPORT_SYMBOL vmlinux 0xa5808bbf tasklet_init +EXPORT_SYMBOL vmlinux 0xa58b6804 nla_parse +EXPORT_SYMBOL vmlinux 0xa58c455e __mark_inode_dirty +EXPORT_SYMBOL vmlinux 0xa5cef8ad release_resource +EXPORT_SYMBOL vmlinux 0xa5dbfa90 unmap_mapping_range +EXPORT_SYMBOL vmlinux 0xa67e4cca ipv4_specific +EXPORT_SYMBOL vmlinux 0xa68124fa hweight8 +EXPORT_SYMBOL vmlinux 0xa681fe88 generate_random_uuid +EXPORT_SYMBOL vmlinux 0xa6887fe9 dm_kcopyd_copy +EXPORT_SYMBOL vmlinux 0xa6928d11 cfi_read_pri +EXPORT_SYMBOL vmlinux 0xa6aaa9e9 user_revoke +EXPORT_SYMBOL vmlinux 0xa6dcc773 rb_insert_color +EXPORT_SYMBOL vmlinux 0xa6e27356 inet_listen +EXPORT_SYMBOL vmlinux 0xa7502f48 jiffies_to_timeval +EXPORT_SYMBOL vmlinux 0xa759db96 vfs_readlink +EXPORT_SYMBOL vmlinux 0xa7b91a7b lockd_down +EXPORT_SYMBOL vmlinux 0xa7c35c6b getnstimeofday +EXPORT_SYMBOL vmlinux 0xa7eac248 invalidate_inodes +EXPORT_SYMBOL vmlinux 0xa8028266 elv_rb_latter_request +EXPORT_SYMBOL vmlinux 0xa80d51be __bread +EXPORT_SYMBOL vmlinux 0xa81f0e7b pci_try_set_mwi +EXPORT_SYMBOL vmlinux 0xa8b44a13 tty_port_free_xmit_buf +EXPORT_SYMBOL vmlinux 0xa8d15ebe request_key +EXPORT_SYMBOL vmlinux 0xa8eca6a6 mmc_align_data_size +EXPORT_SYMBOL vmlinux 0xa8fa4602 console_stop +EXPORT_SYMBOL vmlinux 0xa8fef7bb security_unix_may_send +EXPORT_SYMBOL vmlinux 0xa924baf1 bitmap_startwrite +EXPORT_SYMBOL vmlinux 0xa925899a param_set_bool +EXPORT_SYMBOL vmlinux 0xa93a1fd6 scsi_rescan_device +EXPORT_SYMBOL vmlinux 0xa94dbe1b blk_init_queue +EXPORT_SYMBOL vmlinux 0xa951c6ef pci_dev_driver +EXPORT_SYMBOL vmlinux 0xa96e89aa netlink_broadcast +EXPORT_SYMBOL vmlinux 0xa995bdfa remove_arg_zero +EXPORT_SYMBOL vmlinux 0xa9bea8ce find_inode_number +EXPORT_SYMBOL vmlinux 0xa9e807d9 bio_phys_segments +EXPORT_SYMBOL vmlinux 0xa9f1ed23 bit_waitqueue +EXPORT_SYMBOL vmlinux 0xaa527612 __kfifo_put +EXPORT_SYMBOL vmlinux 0xaa94b19c dput +EXPORT_SYMBOL vmlinux 0xaab844d5 blk_cleanup_queue +EXPORT_SYMBOL vmlinux 0xaafb49fe clk_get_rate +EXPORT_SYMBOL vmlinux 0xaafdc258 strcasecmp +EXPORT_SYMBOL vmlinux 0xab36a804 search_binary_handler +EXPORT_SYMBOL vmlinux 0xab41c897 free_netdev +EXPORT_SYMBOL vmlinux 0xab471003 param_array_set +EXPORT_SYMBOL vmlinux 0xab4c6225 ethtool_op_set_ufo +EXPORT_SYMBOL vmlinux 0xab53b0a8 mempool_alloc +EXPORT_SYMBOL vmlinux 0xab600421 probe_irq_off +EXPORT_SYMBOL vmlinux 0xab64527d mutex_lock_interruptible +EXPORT_SYMBOL vmlinux 0xab680c96 __down_read_trylock +EXPORT_SYMBOL vmlinux 0xab944d68 skb_add_rx_frag +EXPORT_SYMBOL vmlinux 0xaba316f7 tty_register_ldisc +EXPORT_SYMBOL vmlinux 0xabad3311 neigh_connected_output +EXPORT_SYMBOL vmlinux 0xabad83d7 udp_hash_lock +EXPORT_SYMBOL vmlinux 0xabc4e1ba i2c_del_adapter +EXPORT_SYMBOL vmlinux 0xabd0c91c rtc_time_to_tm +EXPORT_SYMBOL vmlinux 0xabdede55 filp_open +EXPORT_SYMBOL vmlinux 0xabe47863 unregister_netdev +EXPORT_SYMBOL vmlinux 0xabebe479 pci_set_dma_max_seg_size +EXPORT_SYMBOL vmlinux 0xabf94efe dma_release_from_coherent +EXPORT_SYMBOL vmlinux 0xabfe5a84 sync_page_range +EXPORT_SYMBOL vmlinux 0xac3ad673 __xfrm_lookup +EXPORT_SYMBOL vmlinux 0xac3b3cee __bitmap_and +EXPORT_SYMBOL vmlinux 0xac4461db xfrm_policy_delete +EXPORT_SYMBOL vmlinux 0xac48ca36 spi_attach_transport +EXPORT_SYMBOL vmlinux 0xac54fc9f mempool_destroy +EXPORT_SYMBOL vmlinux 0xac5da09f kmem_cache_create +EXPORT_SYMBOL vmlinux 0xac5f113d cpu_all_bits +EXPORT_SYMBOL vmlinux 0xacc0142f posix_test_lock +EXPORT_SYMBOL vmlinux 0xacc04d44 sync_inode +EXPORT_SYMBOL vmlinux 0xacc9b05b generic_removexattr +EXPORT_SYMBOL vmlinux 0xaccabc6a in4_pton +EXPORT_SYMBOL vmlinux 0xacd6af7c pci_remove_bus_device +EXPORT_SYMBOL vmlinux 0xacefe153 set_bh_page +EXPORT_SYMBOL vmlinux 0xacf4d843 match_strdup +EXPORT_SYMBOL vmlinux 0xad0413d4 match_hex +EXPORT_SYMBOL vmlinux 0xad05dce7 netdev_bonding_change +EXPORT_SYMBOL vmlinux 0xad1facaf locks_init_lock +EXPORT_SYMBOL vmlinux 0xad293b6f blk_complete_request +EXPORT_SYMBOL vmlinux 0xad40b6e3 d_genocide +EXPORT_SYMBOL vmlinux 0xad63e3ac find_get_pages_contig +EXPORT_SYMBOL vmlinux 0xad733126 register_sysctl_table +EXPORT_SYMBOL vmlinux 0xad9ab66c path_permission +EXPORT_SYMBOL vmlinux 0xadad3e00 submit_bio +EXPORT_SYMBOL vmlinux 0xadb792c2 prepare_to_wait_exclusive +EXPORT_SYMBOL vmlinux 0xade881d4 tcp_child_process +EXPORT_SYMBOL vmlinux 0xadea4349 bdi_register_dev +EXPORT_SYMBOL vmlinux 0xae047b73 ethtool_op_get_sg +EXPORT_SYMBOL vmlinux 0xae192297 mpage_readpage +EXPORT_SYMBOL vmlinux 0xae5dc4e2 elv_queue_empty +EXPORT_SYMBOL vmlinux 0xaec17864 write_one_page +EXPORT_SYMBOL vmlinux 0xaec655c7 alloc_pages_exact +EXPORT_SYMBOL vmlinux 0xaed013b9 posix_acl_valid +EXPORT_SYMBOL vmlinux 0xaee7a835 pcim_iomap_regions +EXPORT_SYMBOL vmlinux 0xaf09cbbb fb_show_logo +EXPORT_SYMBOL vmlinux 0xaf14659d call_usermodehelper_setcleanup +EXPORT_SYMBOL vmlinux 0xaf48b11e mb_cache_entry_find_first +EXPORT_SYMBOL vmlinux 0xaf4ce802 journal_update_format +EXPORT_SYMBOL vmlinux 0xaf50e76d elf_set_personality +EXPORT_SYMBOL vmlinux 0xaf6408c4 skb_checksum +EXPORT_SYMBOL vmlinux 0xaf64ad0d zlib_deflate +EXPORT_SYMBOL vmlinux 0xaf782f08 __dev_remove_pack +EXPORT_SYMBOL vmlinux 0xaf8aa518 system_rev +EXPORT_SYMBOL vmlinux 0xafa730f5 xfrm_find_acq_byseq +EXPORT_SYMBOL vmlinux 0xafb09396 eth_header_cache +EXPORT_SYMBOL vmlinux 0xafc17d7c inet_frags_init +EXPORT_SYMBOL vmlinux 0xb01cd37a journal_flush +EXPORT_SYMBOL vmlinux 0xb051e4cd mmc_add_host +EXPORT_SYMBOL vmlinux 0xb069f255 pci_scan_bridge +EXPORT_SYMBOL vmlinux 0xb07ef56e simple_rmdir +EXPORT_SYMBOL vmlinux 0xb0925d3c sk_send_sigurg +EXPORT_SYMBOL vmlinux 0xb0a2b6e3 auth_unix_forget_old +EXPORT_SYMBOL vmlinux 0xb0a379a7 journal_create +EXPORT_SYMBOL vmlinux 0xb0b847ac __bitmap_full +EXPORT_SYMBOL vmlinux 0xb0e10781 get_option +EXPORT_SYMBOL vmlinux 0xb0fce61e tcp_v4_destroy_sock +EXPORT_SYMBOL vmlinux 0xb10c5bd0 fd_install +EXPORT_SYMBOL vmlinux 0xb121390a probe_irq_on +EXPORT_SYMBOL vmlinux 0xb15a8a0a svc_seq_show +EXPORT_SYMBOL vmlinux 0xb16ad164 dev_set_promiscuity +EXPORT_SYMBOL vmlinux 0xb1958e61 tty_port_tty_set +EXPORT_SYMBOL vmlinux 0xb19760c3 bitmap_onto +EXPORT_SYMBOL vmlinux 0xb1c3a01a oops_in_progress +EXPORT_SYMBOL vmlinux 0xb21160d1 xfrm_state_delete_tunnel +EXPORT_SYMBOL vmlinux 0xb22fe6a3 netdev_increment_features +EXPORT_SYMBOL vmlinux 0xb2313bad flush_signals +EXPORT_SYMBOL vmlinux 0xb248b96e lock_may_read +EXPORT_SYMBOL vmlinux 0xb2583620 xdr_shift_buf +EXPORT_SYMBOL vmlinux 0xb2668bcd seq_puts +EXPORT_SYMBOL vmlinux 0xb27b622f auth_unix_add_addr +EXPORT_SYMBOL vmlinux 0xb2906944 key_payload_reserve +EXPORT_SYMBOL vmlinux 0xb29c3d90 scsi_is_host_device +EXPORT_SYMBOL vmlinux 0xb2bf1312 __up_read +EXPORT_SYMBOL vmlinux 0xb34259cf inode_change_ok +EXPORT_SYMBOL vmlinux 0xb343d44b mmc_alloc_host +EXPORT_SYMBOL vmlinux 0xb3506961 task_session_nr_ns +EXPORT_SYMBOL vmlinux 0xb3647363 unregister_binfmt +EXPORT_SYMBOL vmlinux 0xb36e04c3 register_binfmt +EXPORT_SYMBOL vmlinux 0xb376d79d radix_tree_tagged +EXPORT_SYMBOL vmlinux 0xb3924e31 uart_remove_one_port +EXPORT_SYMBOL vmlinux 0xb3a307c6 si_meminfo +EXPORT_SYMBOL vmlinux 0xb3ac62aa unregister_console +EXPORT_SYMBOL vmlinux 0xb3f23b89 journal_ack_err +EXPORT_SYMBOL vmlinux 0xb3fdb2d9 kick_iocb +EXPORT_SYMBOL vmlinux 0xb3fe02b1 down_write +EXPORT_SYMBOL vmlinux 0xb40cf83f pci_set_mwi +EXPORT_SYMBOL vmlinux 0xb423dba1 console_blanked +EXPORT_SYMBOL vmlinux 0xb434e2c0 neigh_table_init_no_netlink +EXPORT_SYMBOL vmlinux 0xb478671f sock_no_getname +EXPORT_SYMBOL vmlinux 0xb492c108 generic_osync_inode +EXPORT_SYMBOL vmlinux 0xb496b036 journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0xb4a0e989 init_timer_deferrable +EXPORT_SYMBOL vmlinux 0xb4ad85f5 sock_kfree_s +EXPORT_SYMBOL vmlinux 0xb4b86a90 key_alloc +EXPORT_SYMBOL vmlinux 0xb5044271 vsscanf +EXPORT_SYMBOL vmlinux 0xb534763c sg_free_table +EXPORT_SYMBOL vmlinux 0xb53aa4ad lock_rename +EXPORT_SYMBOL vmlinux 0xb54533f7 usecs_to_jiffies +EXPORT_SYMBOL vmlinux 0xb54c2a3f bitmap_unplug +EXPORT_SYMBOL vmlinux 0xb555186f single_open +EXPORT_SYMBOL vmlinux 0xb55edafc set_user_nice +EXPORT_SYMBOL vmlinux 0xb57b21d6 pcibios_resource_to_bus +EXPORT_SYMBOL vmlinux 0xb5a459dc unregister_blkdev +EXPORT_SYMBOL vmlinux 0xb5a7403e generic_file_buffered_write +EXPORT_SYMBOL vmlinux 0xb5c5f674 pneigh_lookup +EXPORT_SYMBOL vmlinux 0xb5daa65f xfrm_lookup +EXPORT_SYMBOL vmlinux 0xb6057d77 __fatal_signal_pending +EXPORT_SYMBOL vmlinux 0xb60e34a8 nla_memcpy +EXPORT_SYMBOL vmlinux 0xb618d128 add_mtd_partitions +EXPORT_SYMBOL vmlinux 0xb65f7b6e blk_queue_init_tags +EXPORT_SYMBOL vmlinux 0xb678366f int_sqrt +EXPORT_SYMBOL vmlinux 0xb6896671 crc_t10dif +EXPORT_SYMBOL vmlinux 0xb6b3b3da call_usermodehelper_setup +EXPORT_SYMBOL vmlinux 0xb6c5a973 scsi_show_result +EXPORT_SYMBOL vmlinux 0xb6c70a7d __wake_up +EXPORT_SYMBOL vmlinux 0xb6cc8164 mmc_register_driver +EXPORT_SYMBOL vmlinux 0xb6e9106a xdr_process_buf +EXPORT_SYMBOL vmlinux 0xb7031e6c mark_buffer_dirty_inode +EXPORT_SYMBOL vmlinux 0xb703911e release_firmware +EXPORT_SYMBOL vmlinux 0xb70f1e7c __break_lease +EXPORT_SYMBOL vmlinux 0xb714a981 console_print +EXPORT_SYMBOL vmlinux 0xb734e54a read_dev_sector +EXPORT_SYMBOL vmlinux 0xb7469afd xfrm_register_mode +EXPORT_SYMBOL vmlinux 0xb7555f12 timeval_to_jiffies +EXPORT_SYMBOL vmlinux 0xb76770ea seq_bitmap_list +EXPORT_SYMBOL vmlinux 0xb7764ef3 netlink_ack +EXPORT_SYMBOL vmlinux 0xb79166c2 scsi_prep_state_check +EXPORT_SYMBOL vmlinux 0xb798898c __napi_schedule +EXPORT_SYMBOL vmlinux 0xb7a1e020 unix_domain_find +EXPORT_SYMBOL vmlinux 0xb7aa1ee1 get_io_context +EXPORT_SYMBOL vmlinux 0xb7ad3321 ida_init +EXPORT_SYMBOL vmlinux 0xb7b61546 crc32_be +EXPORT_SYMBOL vmlinux 0xb7bb792d scsi_nonblockable_ioctl +EXPORT_SYMBOL vmlinux 0xb7da82d2 submit_bh +EXPORT_SYMBOL vmlinux 0xb7e93e3d con_is_bound +EXPORT_SYMBOL vmlinux 0xb7f8a864 vfs_getattr +EXPORT_SYMBOL vmlinux 0xb8156dbd ethtool_op_set_flags +EXPORT_SYMBOL vmlinux 0xb828a412 neigh_ifdown +EXPORT_SYMBOL vmlinux 0xb830f5e7 pci_prepare_to_sleep +EXPORT_SYMBOL vmlinux 0xb859f38b krealloc +EXPORT_SYMBOL vmlinux 0xb85e7b77 get_unmapped_area +EXPORT_SYMBOL vmlinux 0xb86e4ab9 random32 +EXPORT_SYMBOL vmlinux 0xb89af9bf srandom32 +EXPORT_SYMBOL vmlinux 0xb8aa2342 __check_region +EXPORT_SYMBOL vmlinux 0xb9462d7c pci_bus_write_config_byte +EXPORT_SYMBOL vmlinux 0xb95f98d6 _memset_io +EXPORT_SYMBOL vmlinux 0xb969be6d inode_set_bytes +EXPORT_SYMBOL vmlinux 0xb97d4c9c mutex_lock +EXPORT_SYMBOL vmlinux 0xb98a0185 rtc_tm_to_time +EXPORT_SYMBOL vmlinux 0xb98c2a7d scsi_adjust_queue_depth +EXPORT_SYMBOL vmlinux 0xb98ef804 vm_stat +EXPORT_SYMBOL vmlinux 0xb9ac3620 sg_miter_start +EXPORT_SYMBOL vmlinux 0xb9acd3d9 __put_user_2 +EXPORT_SYMBOL vmlinux 0xb9c1d9c8 sock_rfree +EXPORT_SYMBOL vmlinux 0xb9c74bf1 gen_kill_estimator +EXPORT_SYMBOL vmlinux 0xb9d67e43 dma_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0xba1a69b0 alloc_etherdev_mq +EXPORT_SYMBOL vmlinux 0xba1ad049 init_task +EXPORT_SYMBOL vmlinux 0xba1f5666 dev_kfree_skb_any +EXPORT_SYMBOL vmlinux 0xba340ddc block_is_partially_uptodate +EXPORT_SYMBOL vmlinux 0xba3bda2a __downgrade_write +EXPORT_SYMBOL vmlinux 0xba497f13 loops_per_jiffy +EXPORT_SYMBOL vmlinux 0xba8f8b68 completion_done +EXPORT_SYMBOL vmlinux 0xbaba703c complete_request_key +EXPORT_SYMBOL vmlinux 0xbaebff08 dm_table_get_mode +EXPORT_SYMBOL vmlinux 0xbb11183e poll_initwait +EXPORT_SYMBOL vmlinux 0xbb16707f do_splice_from +EXPORT_SYMBOL vmlinux 0xbb167766 fb_var_to_videomode +EXPORT_SYMBOL vmlinux 0xbb189cad disallow_signal +EXPORT_SYMBOL vmlinux 0xbb5d343d xfrm_get_acqseq +EXPORT_SYMBOL vmlinux 0xbb72d4fe __put_user_1 +EXPORT_SYMBOL vmlinux 0xbb7d0f37 tty_wait_until_sent +EXPORT_SYMBOL vmlinux 0xbb8d944c blk_queue_max_sectors +EXPORT_SYMBOL vmlinux 0xbb91dcba d_namespace_path +EXPORT_SYMBOL vmlinux 0xbb99125c get_default_font +EXPORT_SYMBOL vmlinux 0xbbb0ccb2 dm_io +EXPORT_SYMBOL vmlinux 0xbbc8e804 param_set_ushort +EXPORT_SYMBOL vmlinux 0xbbd7e59d i2c_smbus_write_i2c_block_data +EXPORT_SYMBOL vmlinux 0xbbdf653a skb_store_bits +EXPORT_SYMBOL vmlinux 0xbbe32306 journal_wipe +EXPORT_SYMBOL vmlinux 0xbbeed9d8 pagecache_write_end +EXPORT_SYMBOL vmlinux 0xbc10dd97 __put_user_4 +EXPORT_SYMBOL vmlinux 0xbc21f7a5 block_page_mkwrite +EXPORT_SYMBOL vmlinux 0xbca87f40 md_wakeup_thread +EXPORT_SYMBOL vmlinux 0xbcde56e9 bio_sector_offset +EXPORT_SYMBOL vmlinux 0xbd1217bd udp_prot +EXPORT_SYMBOL vmlinux 0xbd29477c vfs_readv +EXPORT_SYMBOL vmlinux 0xbd2efef9 bio_clone +EXPORT_SYMBOL vmlinux 0xbd43af6c __netdev_alloc_skb +EXPORT_SYMBOL vmlinux 0xbd520126 cdev_add +EXPORT_SYMBOL vmlinux 0xbd54e24f generic_block_fiemap +EXPORT_SYMBOL vmlinux 0xbddfe35a dev_mc_unsync +EXPORT_SYMBOL vmlinux 0xbdea23a8 kobject_get +EXPORT_SYMBOL vmlinux 0xbdf2580d __raw_readsl +EXPORT_SYMBOL vmlinux 0xbe0e5118 nla_memcmp +EXPORT_SYMBOL vmlinux 0xbe21a5ee ip_mc_dec_group +EXPORT_SYMBOL vmlinux 0xbe314424 sock_no_connect +EXPORT_SYMBOL vmlinux 0xbe42c1da blk_queue_bounce_limit +EXPORT_SYMBOL vmlinux 0xbe63ee40 request_resource +EXPORT_SYMBOL vmlinux 0xbe69f8fc generic_file_aio_read +EXPORT_SYMBOL vmlinux 0xbe82135b cad_pid +EXPORT_SYMBOL vmlinux 0xbee49412 sock_map_fd +EXPORT_SYMBOL vmlinux 0xbef43296 console_conditional_schedule +EXPORT_SYMBOL vmlinux 0xbf0b4f94 uart_update_timeout +EXPORT_SYMBOL vmlinux 0xbf73d6d5 kset_register +EXPORT_SYMBOL vmlinux 0xbf783c30 pci_lost_interrupt +EXPORT_SYMBOL vmlinux 0xbf7fd2f5 schedule_timeout_killable +EXPORT_SYMBOL vmlinux 0xbf91b581 simple_dir_operations +EXPORT_SYMBOL vmlinux 0xbf9bcc8d __cap_empty_set +EXPORT_SYMBOL vmlinux 0xbfa708a3 dev_close +EXPORT_SYMBOL vmlinux 0xbfb96317 sk_alloc +EXPORT_SYMBOL vmlinux 0xbfee3ad5 loop_unregister_transfer +EXPORT_SYMBOL vmlinux 0xc045ad4e timespec_trunc +EXPORT_SYMBOL vmlinux 0xc04b0613 blk_rq_map_user +EXPORT_SYMBOL vmlinux 0xc0580937 rb_erase +EXPORT_SYMBOL vmlinux 0xc0a98975 new_inode +EXPORT_SYMBOL vmlinux 0xc0c702fe md_done_sync +EXPORT_SYMBOL vmlinux 0xc1058ea0 __skb_checksum_complete_head +EXPORT_SYMBOL vmlinux 0xc10e7824 sock_no_bind +EXPORT_SYMBOL vmlinux 0xc11d8093 iov_shorten +EXPORT_SYMBOL vmlinux 0xc143e156 mmc_request_done +EXPORT_SYMBOL vmlinux 0xc149b887 dev_load +EXPORT_SYMBOL vmlinux 0xc158f29f auth_domain_lookup +EXPORT_SYMBOL vmlinux 0xc15e0383 v4wb_copy_user_page +EXPORT_SYMBOL vmlinux 0xc1601a4f _change_bit_le +EXPORT_SYMBOL vmlinux 0xc17862b7 kfree_skb +EXPORT_SYMBOL vmlinux 0xc1e33c8d pagevec_lookup +EXPORT_SYMBOL vmlinux 0xc1fc4511 _test_and_change_bit_le +EXPORT_SYMBOL vmlinux 0xc20da852 default_llseek +EXPORT_SYMBOL vmlinux 0xc22616f1 __init_rwsem +EXPORT_SYMBOL vmlinux 0xc23b6555 mb_cache_entry_get +EXPORT_SYMBOL vmlinux 0xc256e762 __bitmap_equal +EXPORT_SYMBOL vmlinux 0xc27487dd __bug +EXPORT_SYMBOL vmlinux 0xc2b3e3ca inet_put_port +EXPORT_SYMBOL vmlinux 0xc2c3cebf blk_stop_queue +EXPORT_SYMBOL vmlinux 0xc2e587d1 reset_devices +EXPORT_SYMBOL vmlinux 0xc30bcf99 mpage_writepages +EXPORT_SYMBOL vmlinux 0xc359f28b i2c_bit_add_numbered_bus +EXPORT_SYMBOL vmlinux 0xc359fb65 abort +EXPORT_SYMBOL vmlinux 0xc3880471 xdr_decode_netobj +EXPORT_SYMBOL vmlinux 0xc3923e38 nonseekable_open +EXPORT_SYMBOL vmlinux 0xc398a957 sk_dst_check +EXPORT_SYMBOL vmlinux 0xc3a5c437 xfrm_alloc_spi +EXPORT_SYMBOL vmlinux 0xc3c19d02 seq_putc +EXPORT_SYMBOL vmlinux 0xc3cf1128 in_group_p +EXPORT_SYMBOL vmlinux 0xc3e091ca register_exec_domain +EXPORT_SYMBOL vmlinux 0xc4033412 bdi_register +EXPORT_SYMBOL vmlinux 0xc42151d0 input_register_device +EXPORT_SYMBOL vmlinux 0xc426c933 xfrm_unregister_km +EXPORT_SYMBOL vmlinux 0xc440c451 sg_alloc_table +EXPORT_SYMBOL vmlinux 0xc44d517f end_request +EXPORT_SYMBOL vmlinux 0xc4519e76 dev_unicast_sync +EXPORT_SYMBOL vmlinux 0xc463a578 d_path +EXPORT_SYMBOL vmlinux 0xc46dbdc6 freeze_bdev +EXPORT_SYMBOL vmlinux 0xc499ae1e kstrdup +EXPORT_SYMBOL vmlinux 0xc4be4955 dev_disable_lro +EXPORT_SYMBOL vmlinux 0xc4cbe373 elv_dispatch_sort +EXPORT_SYMBOL vmlinux 0xc528f327 register_sound_midi +EXPORT_SYMBOL vmlinux 0xc52f5714 fb_videomode_to_var +EXPORT_SYMBOL vmlinux 0xc577482a pci_release_region +EXPORT_SYMBOL vmlinux 0xc59916a9 xfrm_dst_ifdown +EXPORT_SYMBOL vmlinux 0xc5c58f28 flush_dcache_page +EXPORT_SYMBOL vmlinux 0xc5c809de bdi_set_max_ratio +EXPORT_SYMBOL vmlinux 0xc60b3504 call_usermodehelper_freeinfo +EXPORT_SYMBOL vmlinux 0xc60f4ad5 unregister_filesystem +EXPORT_SYMBOL vmlinux 0xc6144a0f kmem_cache_size +EXPORT_SYMBOL vmlinux 0xc6237a1f __inode_dir_notify +EXPORT_SYMBOL vmlinux 0xc633495b schedule_work +EXPORT_SYMBOL vmlinux 0xc66e29aa __serio_register_port +EXPORT_SYMBOL vmlinux 0xc67d0ae8 skb_over_panic +EXPORT_SYMBOL vmlinux 0xc6bb1ea6 pci_find_parent_resource +EXPORT_SYMBOL vmlinux 0xc6c0f44d page_follow_link_light +EXPORT_SYMBOL vmlinux 0xc6f80e80 con_copy_unimap +EXPORT_SYMBOL vmlinux 0xc722227e posix_acl_clone +EXPORT_SYMBOL vmlinux 0xc725baba xfrm4_rcv +EXPORT_SYMBOL vmlinux 0xc732c754 pci_get_slot +EXPORT_SYMBOL vmlinux 0xc73c263b seq_read +EXPORT_SYMBOL vmlinux 0xc76c1547 xrlim_allow +EXPORT_SYMBOL vmlinux 0xc771a31d pci_get_subsys +EXPORT_SYMBOL vmlinux 0xc78fc2b3 scsi_host_get +EXPORT_SYMBOL vmlinux 0xc795178a eth_type_trans +EXPORT_SYMBOL vmlinux 0xc79bcd36 dm_vcalloc +EXPORT_SYMBOL vmlinux 0xc7a4fbed rtnl_lock +EXPORT_SYMBOL vmlinux 0xc7ec6c27 strspn +EXPORT_SYMBOL vmlinux 0xc7f8874b seq_escape +EXPORT_SYMBOL vmlinux 0xc80de694 down_write_trylock +EXPORT_SYMBOL vmlinux 0xc811340d netdev_rx_csum_fault +EXPORT_SYMBOL vmlinux 0xc839bfc0 scsi_finish_command +EXPORT_SYMBOL vmlinux 0xc8a45291 fasync_helper +EXPORT_SYMBOL vmlinux 0xc8b57c27 autoremove_wake_function +EXPORT_SYMBOL vmlinux 0xc8d047f3 dev_get_by_name +EXPORT_SYMBOL vmlinux 0xc8e96dea qword_addhex +EXPORT_SYMBOL vmlinux 0xc938fd21 security_sb_clone_mnt_opts +EXPORT_SYMBOL vmlinux 0xc978eb1d vc_cons +EXPORT_SYMBOL vmlinux 0xc998d641 icmp_err_convert +EXPORT_SYMBOL vmlinux 0xc9c5eb8e vm_insert_page +EXPORT_SYMBOL vmlinux 0xca02d6a6 d_validate +EXPORT_SYMBOL vmlinux 0xca5dbc50 scsi_print_sense_hdr +EXPORT_SYMBOL vmlinux 0xcaa75db5 pci_remove_behind_bridge +EXPORT_SYMBOL vmlinux 0xcaaab00b tty_driver_flush_buffer +EXPORT_SYMBOL vmlinux 0xcacaf525 d_rehash +EXPORT_SYMBOL vmlinux 0xcadaceaf pci_enable_device_mem +EXPORT_SYMBOL vmlinux 0xcadd4067 km_state_notify +EXPORT_SYMBOL vmlinux 0xcafa14ff generic_file_llseek_unlocked +EXPORT_SYMBOL vmlinux 0xcb21c437 I_BDEV +EXPORT_SYMBOL vmlinux 0xcb30ae40 alloc_buffer_head +EXPORT_SYMBOL vmlinux 0xcb32da10 param_set_int +EXPORT_SYMBOL vmlinux 0xcb519edf devm_ioremap +EXPORT_SYMBOL vmlinux 0xcb6ba465 uart_resume_port +EXPORT_SYMBOL vmlinux 0xcb6beb40 hweight32 +EXPORT_SYMBOL vmlinux 0xcb71084d get_write_access +EXPORT_SYMBOL vmlinux 0xcb7131fb fb_get_options +EXPORT_SYMBOL vmlinux 0xcb831cc4 dev_get_flags +EXPORT_SYMBOL vmlinux 0xcb933ed8 tcp_read_sock +EXPORT_SYMBOL vmlinux 0xcb999c84 tcp_shutdown +EXPORT_SYMBOL vmlinux 0xcbbb4fe6 gnet_stats_copy_queue +EXPORT_SYMBOL vmlinux 0xcbbbca90 dst_discard +EXPORT_SYMBOL vmlinux 0xcbbd78eb blk_sync_queue +EXPORT_SYMBOL vmlinux 0xcbc1f587 vmtruncate +EXPORT_SYMBOL vmlinux 0xcbc403be __getblk +EXPORT_SYMBOL vmlinux 0xcc36f32e fb_unregister_client +EXPORT_SYMBOL vmlinux 0xcc5005fe msleep_interruptible +EXPORT_SYMBOL vmlinux 0xcc64b2f2 __seq_open_private +EXPORT_SYMBOL vmlinux 0xcc7fa952 local_bh_enable_ip +EXPORT_SYMBOL vmlinux 0xcc828595 kernel_sock_ioctl +EXPORT_SYMBOL vmlinux 0xcccca482 _test_and_clear_bit_le +EXPORT_SYMBOL vmlinux 0xccd041a8 sock_no_listen +EXPORT_SYMBOL vmlinux 0xccd4fc6b skb_kill_datagram +EXPORT_SYMBOL vmlinux 0xccffd1b1 pci_save_state +EXPORT_SYMBOL vmlinux 0xcd083b10 unregister_sound_dsp +EXPORT_SYMBOL vmlinux 0xcd39472b arm926_flush_user_cache_range +EXPORT_SYMBOL vmlinux 0xcd3c252d call_usermodehelper_exec +EXPORT_SYMBOL vmlinux 0xcd63c845 __aeabi_lasr +EXPORT_SYMBOL vmlinux 0xce16afc8 scsi_register_driver +EXPORT_SYMBOL vmlinux 0xce21c044 pci_get_class +EXPORT_SYMBOL vmlinux 0xce2a74c1 dentry_open +EXPORT_SYMBOL vmlinux 0xce2e4788 kmem_cache_shrink +EXPORT_SYMBOL vmlinux 0xce36ded6 sysctl_tcp_mem +EXPORT_SYMBOL vmlinux 0xce5ac24f zlib_inflate_workspacesize +EXPORT_SYMBOL vmlinux 0xce86e8e8 dma_pool_alloc +EXPORT_SYMBOL vmlinux 0xce890c6a input_free_device +EXPORT_SYMBOL vmlinux 0xce90a866 xfrm_policy_bysel_ctx +EXPORT_SYMBOL vmlinux 0xce9f0cea blk_queue_end_tag +EXPORT_SYMBOL vmlinux 0xceac293e udp_proc_unregister +EXPORT_SYMBOL vmlinux 0xcec0fc7b sock_setsockopt +EXPORT_SYMBOL vmlinux 0xcf0893ec do_sync_write +EXPORT_SYMBOL vmlinux 0xcf11ba02 d_delete +EXPORT_SYMBOL vmlinux 0xcf1824eb dev_getbyhwaddr +EXPORT_SYMBOL vmlinux 0xcf3e0541 __xfrm_policy_check +EXPORT_SYMBOL vmlinux 0xcf91e025 xdr_buf_read_netobj +EXPORT_SYMBOL vmlinux 0xcfd3018e set_normalized_timespec +EXPORT_SYMBOL vmlinux 0xcfe4b64e spi_schedule_dv_device +EXPORT_SYMBOL vmlinux 0xcff53400 kref_put +EXPORT_SYMBOL vmlinux 0xcffe6981 pci_bus_assign_resources +EXPORT_SYMBOL vmlinux 0xd0181f4f __bitmap_xor +EXPORT_SYMBOL vmlinux 0xd02cc869 __bitmap_andnot +EXPORT_SYMBOL vmlinux 0xd04fb6e1 inet_frags_fini +EXPORT_SYMBOL vmlinux 0xd0db2dda inet_dgram_connect +EXPORT_SYMBOL vmlinux 0xd0ee38b8 schedule_timeout_uninterruptible +EXPORT_SYMBOL vmlinux 0xd0f1a615 security_sb_set_mnt_opts +EXPORT_SYMBOL vmlinux 0xd144f0da alloc_disk +EXPORT_SYMBOL vmlinux 0xd1679c0e lock_super +EXPORT_SYMBOL vmlinux 0xd1a565b1 blk_queue_update_dma_alignment +EXPORT_SYMBOL vmlinux 0xd1b83864 clear_inode +EXPORT_SYMBOL vmlinux 0xd1f1d9e5 proc_create_data +EXPORT_SYMBOL vmlinux 0xd2162941 is_bad_inode +EXPORT_SYMBOL vmlinux 0xd21e79dc dma_free_coherent +EXPORT_SYMBOL vmlinux 0xd226eef5 pci_dev_put +EXPORT_SYMBOL vmlinux 0xd2395021 aio_complete +EXPORT_SYMBOL vmlinux 0xd251d7b0 security_socket_getpeersec_dgram +EXPORT_SYMBOL vmlinux 0xd2555f19 jiffies_64_to_clock_t +EXPORT_SYMBOL vmlinux 0xd25d4f74 console_blank_hook +EXPORT_SYMBOL vmlinux 0xd2715e52 page_readlink +EXPORT_SYMBOL vmlinux 0xd284f2bc unlock_page +EXPORT_SYMBOL vmlinux 0xd2965f6f kthread_should_stop +EXPORT_SYMBOL vmlinux 0xd2c4ce94 netif_device_attach +EXPORT_SYMBOL vmlinux 0xd324d1bb inet_frag_find +EXPORT_SYMBOL vmlinux 0xd32e52c7 posix_acl_chmod_masq +EXPORT_SYMBOL vmlinux 0xd3371758 __netif_schedule +EXPORT_SYMBOL vmlinux 0xd3427f73 mempool_create_node +EXPORT_SYMBOL vmlinux 0xd37201d1 fget +EXPORT_SYMBOL vmlinux 0xd3a1eeb3 mmc_resume_host +EXPORT_SYMBOL vmlinux 0xd3d6673d blk_queue_dma_alignment +EXPORT_SYMBOL vmlinux 0xd3dbfbc4 _find_first_zero_bit_le +EXPORT_SYMBOL vmlinux 0xd418e1c0 adjust_resource +EXPORT_SYMBOL vmlinux 0xd4873485 inet_proto_csum_replace4 +EXPORT_SYMBOL vmlinux 0xd4914c2e simple_transaction_get +EXPORT_SYMBOL vmlinux 0xd491ab73 input_unregister_handler +EXPORT_SYMBOL vmlinux 0xd49b42ff i2c_smbus_read_byte +EXPORT_SYMBOL vmlinux 0xd4e73118 sound_class +EXPORT_SYMBOL vmlinux 0xd5263820 mb_cache_destroy +EXPORT_SYMBOL vmlinux 0xd53ca526 arp_send +EXPORT_SYMBOL vmlinux 0xd546e992 blk_run_queue +EXPORT_SYMBOL vmlinux 0xd5688a7a radix_tree_insert +EXPORT_SYMBOL vmlinux 0xd59af934 locks_remove_posix +EXPORT_SYMBOL vmlinux 0xd5a3ca44 ip_generic_getfrag +EXPORT_SYMBOL vmlinux 0xd5e65265 journal_load +EXPORT_SYMBOL vmlinux 0xd6035d05 do_settimeofday +EXPORT_SYMBOL vmlinux 0xd627480b strncat +EXPORT_SYMBOL vmlinux 0xd62c833f schedule_timeout +EXPORT_SYMBOL vmlinux 0xd66c6228 down_read_trylock +EXPORT_SYMBOL vmlinux 0xd6b88ef3 dm_table_put +EXPORT_SYMBOL vmlinux 0xd6b8ce1b kobject_set_name +EXPORT_SYMBOL vmlinux 0xd6ee688f vmalloc +EXPORT_SYMBOL vmlinux 0xd6f5b2db follow_down +EXPORT_SYMBOL vmlinux 0xd6fd45bb tty_schedule_flip +EXPORT_SYMBOL vmlinux 0xd72b4177 unregister_md_personality +EXPORT_SYMBOL vmlinux 0xd7368913 __skb_checksum_complete +EXPORT_SYMBOL vmlinux 0xd763e9d2 kobject_put +EXPORT_SYMBOL vmlinux 0xd78ccf8b neigh_seq_next +EXPORT_SYMBOL vmlinux 0xd79b5a02 allow_signal +EXPORT_SYMBOL vmlinux 0xd7b65661 do_sync_read +EXPORT_SYMBOL vmlinux 0xd7b69fae idr_find +EXPORT_SYMBOL vmlinux 0xd7c5d553 tty_throttle +EXPORT_SYMBOL vmlinux 0xd7e276a4 scsi_eh_finish_cmd +EXPORT_SYMBOL vmlinux 0xd807a582 stop_tty +EXPORT_SYMBOL vmlinux 0xd8282ff0 posix_acl_equiv_mode +EXPORT_SYMBOL vmlinux 0xd87c85bf pcim_pin_device +EXPORT_SYMBOL vmlinux 0xd87f3c40 svc_sock_update_bufs +EXPORT_SYMBOL vmlinux 0xd8a2ab95 in_egroup_p +EXPORT_SYMBOL vmlinux 0xd8e484f0 register_chrdev_region +EXPORT_SYMBOL vmlinux 0xd8ec1efa skb_split +EXPORT_SYMBOL vmlinux 0xd8efaeb0 generic_read_dir +EXPORT_SYMBOL vmlinux 0xd941e1d0 dev_remove_pack +EXPORT_SYMBOL vmlinux 0xd9762878 tcp_sendpage +EXPORT_SYMBOL vmlinux 0xd985dc99 mempool_free_pages +EXPORT_SYMBOL vmlinux 0xd9990ade dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0xd9c23ebc pci_bus_add_devices +EXPORT_SYMBOL vmlinux 0xd9ce8f0c strnlen +EXPORT_SYMBOL vmlinux 0xda071d23 find_task_by_vpid +EXPORT_SYMBOL vmlinux 0xda0ab154 dev_queue_xmit +EXPORT_SYMBOL vmlinux 0xda0fff84 task_pid_nr_ns +EXPORT_SYMBOL vmlinux 0xda1a7335 kasprintf +EXPORT_SYMBOL vmlinux 0xda258ec6 pci_remove_bus +EXPORT_SYMBOL vmlinux 0xda265599 __dst_free +EXPORT_SYMBOL vmlinux 0xda3b1628 blk_queue_max_phys_segments +EXPORT_SYMBOL vmlinux 0xda4abb5f cache_register +EXPORT_SYMBOL vmlinux 0xda5ea696 _test_and_set_bit_le +EXPORT_SYMBOL vmlinux 0xda67c6f7 skb_append +EXPORT_SYMBOL vmlinux 0xda7ca6cb fb_mode_is_equal +EXPORT_SYMBOL vmlinux 0xda8af7ad fb_find_nearest_mode +EXPORT_SYMBOL vmlinux 0xda8b5096 xfrm_cfg_mutex +EXPORT_SYMBOL vmlinux 0xdaa1a597 sg_miter_next +EXPORT_SYMBOL vmlinux 0xdadb4768 mb_cache_create +EXPORT_SYMBOL vmlinux 0xdaf56d8f put_page +EXPORT_SYMBOL vmlinux 0xdb3ee128 ethtool_op_set_tx_csum +EXPORT_SYMBOL vmlinux 0xdb660423 d_instantiate_unique +EXPORT_SYMBOL vmlinux 0xdb7b43ec redraw_screen +EXPORT_SYMBOL vmlinux 0xdb864d65 iov_iter_single_seg_count +EXPORT_SYMBOL vmlinux 0xdb9410dd journal_get_create_access +EXPORT_SYMBOL vmlinux 0xdbcd416e sysctl_ip_nonlocal_bind +EXPORT_SYMBOL vmlinux 0xdbf5aaac dev_get_by_index +EXPORT_SYMBOL vmlinux 0xdc053205 udp_memory_allocated +EXPORT_SYMBOL vmlinux 0xdc14eda7 pci_pci_problems +EXPORT_SYMBOL vmlinux 0xdc1ac5ab unmap_underlying_metadata +EXPORT_SYMBOL vmlinux 0xdc1d3301 scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0xdc2adb35 add_taint +EXPORT_SYMBOL vmlinux 0xdc43a9c8 daemonize +EXPORT_SYMBOL vmlinux 0xdc4629e1 flock_lock_file_wait +EXPORT_SYMBOL vmlinux 0xdc74cc24 kmem_cache_alloc +EXPORT_SYMBOL vmlinux 0xdc9e4bd6 pci_enable_wake +EXPORT_SYMBOL vmlinux 0xdcb0349b sys_close +EXPORT_SYMBOL vmlinux 0xdcc0bc06 scsi_bios_ptable +EXPORT_SYMBOL vmlinux 0xdcd4b139 journal_get_write_access +EXPORT_SYMBOL vmlinux 0xdcde99c5 gnet_stats_copy_rate_est +EXPORT_SYMBOL vmlinux 0xdcfc5312 inet_getname +EXPORT_SYMBOL vmlinux 0xdcfd9597 blk_queue_segment_boundary +EXPORT_SYMBOL vmlinux 0xdd018a58 tcp_v4_send_check +EXPORT_SYMBOL vmlinux 0xdd0a2ba2 strlcat +EXPORT_SYMBOL vmlinux 0xdd10bd28 generic_file_aio_write +EXPORT_SYMBOL vmlinux 0xdd12c2cb register_sound_special_device +EXPORT_SYMBOL vmlinux 0xdd279603 svc_exit_thread +EXPORT_SYMBOL vmlinux 0xdd27fa87 memchr +EXPORT_SYMBOL vmlinux 0xdd3759f1 pagevec_lookup_tag +EXPORT_SYMBOL vmlinux 0xdd46ace0 xdr_encode_word +EXPORT_SYMBOL vmlinux 0xdd6bfccd radix_tree_tag_set +EXPORT_SYMBOL vmlinux 0xddc03256 dm_table_get_md +EXPORT_SYMBOL vmlinux 0xddc1ebb0 kernel_setsockopt +EXPORT_SYMBOL vmlinux 0xddd974d9 xfrm_state_walk +EXPORT_SYMBOL vmlinux 0xddeef053 vfs_stat +EXPORT_SYMBOL vmlinux 0xde0b2bb4 dma_pool_free +EXPORT_SYMBOL vmlinux 0xde2743c6 xfrm_policy_register_afinfo +EXPORT_SYMBOL vmlinux 0xde4cc4f9 tty_check_change +EXPORT_SYMBOL vmlinux 0xde75b689 set_irq_type +EXPORT_SYMBOL vmlinux 0xde9360ba totalram_pages +EXPORT_SYMBOL vmlinux 0xdeb174e9 end_page_writeback +EXPORT_SYMBOL vmlinux 0xdece58fc generic_file_open +EXPORT_SYMBOL vmlinux 0xdeee3167 write_cache_pages +EXPORT_SYMBOL vmlinux 0xdf024e4b md_write_start +EXPORT_SYMBOL vmlinux 0xdf4296fe pci_iomap +EXPORT_SYMBOL vmlinux 0xdf60cc27 __print_symbol +EXPORT_SYMBOL vmlinux 0xdf929370 fs_overflowgid +EXPORT_SYMBOL vmlinux 0xdf94e56c mpage_bio_submit +EXPORT_SYMBOL vmlinux 0xdfbb98f3 scsi_setup_blk_pc_cmnd +EXPORT_SYMBOL vmlinux 0xdfc278e5 init_special_inode +EXPORT_SYMBOL vmlinux 0xdfd0893b xfrm_bundle_ok +EXPORT_SYMBOL vmlinux 0xe031c1ca scsi_device_resume +EXPORT_SYMBOL vmlinux 0xe0560333 tcp_tso_segment +EXPORT_SYMBOL vmlinux 0xe075d6eb iter_div_u64_rem +EXPORT_SYMBOL vmlinux 0xe07df061 save_mount_options +EXPORT_SYMBOL vmlinux 0xe083f142 grab_cache_page_nowait +EXPORT_SYMBOL vmlinux 0xe084a807 udplite_prot +EXPORT_SYMBOL vmlinux 0xe0878bfe __krealloc +EXPORT_SYMBOL vmlinux 0xe0893dc2 __scsi_iterate_devices +EXPORT_SYMBOL vmlinux 0xe0b13336 argv_free +EXPORT_SYMBOL vmlinux 0xe0b224ba fb_class +EXPORT_SYMBOL vmlinux 0xe0d2d803 iunique +EXPORT_SYMBOL vmlinux 0xe0e95cbf km_policy_expired +EXPORT_SYMBOL vmlinux 0xe113bbbc csum_partial +EXPORT_SYMBOL vmlinux 0xe1761617 security_inet_conn_request +EXPORT_SYMBOL vmlinux 0xe194798e invalidate_bdev +EXPORT_SYMBOL vmlinux 0xe1b1cc3b xfrm_policy_walk +EXPORT_SYMBOL vmlinux 0xe1d7f2aa pcim_iounmap_regions +EXPORT_SYMBOL vmlinux 0xe23ff855 security_task_getsecid +EXPORT_SYMBOL vmlinux 0xe24d3a97 jiffies_64 +EXPORT_SYMBOL vmlinux 0xe261971e bio_copy_user +EXPORT_SYMBOL vmlinux 0xe2955537 neigh_lookup_nodev +EXPORT_SYMBOL vmlinux 0xe2a78e6d ilookup +EXPORT_SYMBOL vmlinux 0xe2ad56b0 register_sound_dsp +EXPORT_SYMBOL vmlinux 0xe2d5255a strcmp +EXPORT_SYMBOL vmlinux 0xe2fae716 kmemdup +EXPORT_SYMBOL vmlinux 0xe3158640 dm_unregister_target +EXPORT_SYMBOL vmlinux 0xe351633f genl_register_family +EXPORT_SYMBOL vmlinux 0xe385b7b3 empty_zero_page +EXPORT_SYMBOL vmlinux 0xe38b0d6b amba_release_regions +EXPORT_SYMBOL vmlinux 0xe3900523 scsi_command_normalize_sense +EXPORT_SYMBOL vmlinux 0xe3b931b5 blk_init_queue_node +EXPORT_SYMBOL vmlinux 0xe3eb26e3 tcp_recvmsg +EXPORT_SYMBOL vmlinux 0xe3f64e78 __nla_put_nohdr +EXPORT_SYMBOL vmlinux 0xe4181c84 task_nice +EXPORT_SYMBOL vmlinux 0xe4515d34 sock_no_setsockopt +EXPORT_SYMBOL vmlinux 0xe48af358 i2c_smbus_read_block_data +EXPORT_SYMBOL vmlinux 0xe4a97c71 __down_write_trylock +EXPORT_SYMBOL vmlinux 0xe4c80097 cacheid +EXPORT_SYMBOL vmlinux 0xe4df7d4d journal_check_available_features +EXPORT_SYMBOL vmlinux 0xe4eb8bec pci_pme_active +EXPORT_SYMBOL vmlinux 0xe51c91df blk_init_tags +EXPORT_SYMBOL vmlinux 0xe53cfd02 dev_set_allmulti +EXPORT_SYMBOL vmlinux 0xe552c396 ip_setsockopt +EXPORT_SYMBOL vmlinux 0xe56b2f39 dev_set_mtu +EXPORT_SYMBOL vmlinux 0xe57878a1 in6_pton +EXPORT_SYMBOL vmlinux 0xe5867808 dlci_ioctl_set +EXPORT_SYMBOL vmlinux 0xe5919cb1 xdr_encode_opaque +EXPORT_SYMBOL vmlinux 0xe5c78a99 do_blank_screen +EXPORT_SYMBOL vmlinux 0xe5c85def pci_bus_find_capability +EXPORT_SYMBOL vmlinux 0xe5e8f93b xdr_decode_array2 +EXPORT_SYMBOL vmlinux 0xe5ea6ce4 uart_match_port +EXPORT_SYMBOL vmlinux 0xe5ed5467 xfrm_policy_walk_init +EXPORT_SYMBOL vmlinux 0xe5f5dd7a dm_kcopyd_client_destroy +EXPORT_SYMBOL vmlinux 0xe6052328 get_empty_filp +EXPORT_SYMBOL vmlinux 0xe60b7ebe balance_dirty_pages_ratelimited_nr +EXPORT_SYMBOL vmlinux 0xe68122d4 journal_dirty_data +EXPORT_SYMBOL vmlinux 0xe6822ebd netdev_class_create_file +EXPORT_SYMBOL vmlinux 0xe6a59304 simple_unlink +EXPORT_SYMBOL vmlinux 0xe6b378c5 __lock_page +EXPORT_SYMBOL vmlinux 0xe6bb68eb skb_seq_read +EXPORT_SYMBOL vmlinux 0xe6c3ebb0 __raw_writesw +EXPORT_SYMBOL vmlinux 0xe6df22ac tcp_check_req +EXPORT_SYMBOL vmlinux 0xe6ebc016 key_create_or_update +EXPORT_SYMBOL vmlinux 0xe6eec42d registered_fb +EXPORT_SYMBOL vmlinux 0xe6efbf7a tty_shutdown +EXPORT_SYMBOL vmlinux 0xe6fbe430 can_do_mlock +EXPORT_SYMBOL vmlinux 0xe707d823 __aeabi_uidiv +EXPORT_SYMBOL vmlinux 0xe78c6424 ethtool_op_set_tx_hw_csum +EXPORT_SYMBOL vmlinux 0xe7926419 pci_request_regions +EXPORT_SYMBOL vmlinux 0xe7d2aca1 security_sk_classify_flow +EXPORT_SYMBOL vmlinux 0xe7d4daac seq_list_next +EXPORT_SYMBOL vmlinux 0xe7d9932c dma_mmap_writecombine +EXPORT_SYMBOL vmlinux 0xe7f5c8f5 blk_recount_segments +EXPORT_SYMBOL vmlinux 0xe816adb9 inet_stream_ops +EXPORT_SYMBOL vmlinux 0xe81f3af6 schedule_delayed_work_on +EXPORT_SYMBOL vmlinux 0xe84c6ac6 sync_mapping_buffers +EXPORT_SYMBOL vmlinux 0xe8607768 pci_bus_read_config_dword +EXPORT_SYMBOL vmlinux 0xe8a0b3e6 blk_alloc_queue +EXPORT_SYMBOL vmlinux 0xe8a10b42 bio_add_page +EXPORT_SYMBOL vmlinux 0xe8a111da skb_free_datagram +EXPORT_SYMBOL vmlinux 0xe8a527d4 tcp_make_synack +EXPORT_SYMBOL vmlinux 0xe8b1e49b tty_hung_up_p +EXPORT_SYMBOL vmlinux 0xe8cd902e hweight16 +EXPORT_SYMBOL vmlinux 0xe8ea6002 simple_empty +EXPORT_SYMBOL vmlinux 0xe8fa852a skb_put +EXPORT_SYMBOL vmlinux 0xe914e41e strcpy +EXPORT_SYMBOL vmlinux 0xe9456a5a sysctl_xfrm_aevent_rseqth +EXPORT_SYMBOL vmlinux 0xe9593789 __bforget +EXPORT_SYMBOL vmlinux 0xe97a5b00 ip_route_output_key +EXPORT_SYMBOL vmlinux 0xe97f4ce5 qword_get +EXPORT_SYMBOL vmlinux 0xe98feb20 dma_pool_destroy +EXPORT_SYMBOL vmlinux 0xe9b1f8c0 sysctl_jiffies +EXPORT_SYMBOL vmlinux 0xe9c96fb6 __blk_run_queue +EXPORT_SYMBOL vmlinux 0xe9e86979 ip_queue_xmit +EXPORT_SYMBOL vmlinux 0xe9f3206f xdr_enter_page +EXPORT_SYMBOL vmlinux 0xe9f8c400 svc_wake_up +EXPORT_SYMBOL vmlinux 0xea06aa73 cpu_arm926_set_pte_ext +EXPORT_SYMBOL vmlinux 0xea10212a int_to_scsilun +EXPORT_SYMBOL vmlinux 0xea10655a __bitmap_intersects +EXPORT_SYMBOL vmlinux 0xea147363 printk +EXPORT_SYMBOL vmlinux 0xea2d33a2 radix_tree_gang_lookup_slot +EXPORT_SYMBOL vmlinux 0xea2dd2dc dev_add_pack +EXPORT_SYMBOL vmlinux 0xea5d2f89 qdisc_create_dflt +EXPORT_SYMBOL vmlinux 0xea6fcdaa genl_unregister_family +EXPORT_SYMBOL vmlinux 0xea7987f1 key_update +EXPORT_SYMBOL vmlinux 0xea7a216e pagecache_write_begin +EXPORT_SYMBOL vmlinux 0xea858cb5 radix_tree_gang_lookup_tag +EXPORT_SYMBOL vmlinux 0xeaa82a0a bitmap_start_sync +EXPORT_SYMBOL vmlinux 0xeadc8585 scsi_free_host_dev +EXPORT_SYMBOL vmlinux 0xeae3dfd6 __const_udelay +EXPORT_SYMBOL vmlinux 0xeaea3eed dev_kfree_skb_irq +EXPORT_SYMBOL vmlinux 0xeaf6967a posix_unblock_lock +EXPORT_SYMBOL vmlinux 0xeb19102a netdev_state_change +EXPORT_SYMBOL vmlinux 0xeb366ad7 svc_process +EXPORT_SYMBOL vmlinux 0xeb395084 param_get_invbool +EXPORT_SYMBOL vmlinux 0xeb3f38ed xdr_read_pages +EXPORT_SYMBOL vmlinux 0xeb697205 gnet_stats_start_copy +EXPORT_SYMBOL vmlinux 0xeb7ef1d6 mb_cache_entry_free +EXPORT_SYMBOL vmlinux 0xeb8f54b3 strstrip +EXPORT_SYMBOL vmlinux 0xeb913aea loop_register_transfer +EXPORT_SYMBOL vmlinux 0xebd273a6 strict_strtoull +EXPORT_SYMBOL vmlinux 0xebe973ee key_revoke +EXPORT_SYMBOL vmlinux 0xebfdcbdf system_serial_high +EXPORT_SYMBOL vmlinux 0xec2e6257 sk_stop_timer +EXPORT_SYMBOL vmlinux 0xec408350 cache_check +EXPORT_SYMBOL vmlinux 0xec794ba0 __send_remote_softirq +EXPORT_SYMBOL vmlinux 0xec916742 truncate_inode_pages +EXPORT_SYMBOL vmlinux 0xecf198a3 serio_reconnect +EXPORT_SYMBOL vmlinux 0xed02efe3 serio_interrupt +EXPORT_SYMBOL vmlinux 0xed29c159 vfs_readdir +EXPORT_SYMBOL vmlinux 0xed5a5644 dentry_unhash +EXPORT_SYMBOL vmlinux 0xeda7939f sk_filter +EXPORT_SYMBOL vmlinux 0xedbaee5e nla_strcmp +EXPORT_SYMBOL vmlinux 0xedcced1c read_cache_page +EXPORT_SYMBOL vmlinux 0xedcf6be4 qword_add +EXPORT_SYMBOL vmlinux 0xedd14538 param_get_uint +EXPORT_SYMBOL vmlinux 0xedd3267d neigh_update +EXPORT_SYMBOL vmlinux 0xedd9106d __ashrdi3 +EXPORT_SYMBOL vmlinux 0xede64cc8 zero_fill_bio +EXPORT_SYMBOL vmlinux 0xedeb550d svc_reserve +EXPORT_SYMBOL vmlinux 0xedf10553 unregister_mtd_chip_driver +EXPORT_SYMBOL vmlinux 0xedf230c3 journal_unlock_updates +EXPORT_SYMBOL vmlinux 0xee2d0fc7 _local_bh_enable +EXPORT_SYMBOL vmlinux 0xee37d7de clk_unregister +EXPORT_SYMBOL vmlinux 0xee44f923 blk_register_region +EXPORT_SYMBOL vmlinux 0xee678606 blk_start_queueing +EXPORT_SYMBOL vmlinux 0xee6fdf0b cpu_online_map +EXPORT_SYMBOL vmlinux 0xee785ae3 tcp_mtup_init +EXPORT_SYMBOL vmlinux 0xee94583c map_destroy +EXPORT_SYMBOL vmlinux 0xee94feea vc_resize +EXPORT_SYMBOL vmlinux 0xeea9dbaf bitmap_bitremap +EXPORT_SYMBOL vmlinux 0xeeb1717c param_array_get +EXPORT_SYMBOL vmlinux 0xeeb521c4 i2c_transfer +EXPORT_SYMBOL vmlinux 0xeeb7acf3 posix_lock_file_wait +EXPORT_SYMBOL vmlinux 0xeed70b35 svc_set_client +EXPORT_SYMBOL vmlinux 0xeee50740 ip_getsockopt +EXPORT_SYMBOL vmlinux 0xeee74aa2 pci_release_selected_regions +EXPORT_SYMBOL vmlinux 0xef0474e7 skb_copy_and_csum_dev +EXPORT_SYMBOL vmlinux 0xef07a599 dma_alloc_from_coherent +EXPORT_SYMBOL vmlinux 0xef09a5ef pcim_iomap_table +EXPORT_SYMBOL vmlinux 0xef0dc0ca set_device_ro +EXPORT_SYMBOL vmlinux 0xef1a1668 km_waitq +EXPORT_SYMBOL vmlinux 0xef28acd2 pci_choose_state +EXPORT_SYMBOL vmlinux 0xef310e81 __mmc_claim_host +EXPORT_SYMBOL vmlinux 0xef3cc4ec pci_target_state +EXPORT_SYMBOL vmlinux 0xef4c5b49 ip_mc_inc_group +EXPORT_SYMBOL vmlinux 0xef6c7d9f iov_iter_copy_from_user +EXPORT_SYMBOL vmlinux 0xef73f864 skb_queue_tail +EXPORT_SYMBOL vmlinux 0xefd59b29 bio_copy_kern +EXPORT_SYMBOL vmlinux 0xefdd70ce security_secid_to_secctx +EXPORT_SYMBOL vmlinux 0xefede730 xfrm_unregister_type +EXPORT_SYMBOL vmlinux 0xf0009fee put_pages_list +EXPORT_SYMBOL vmlinux 0xf065afe6 vfs_writev +EXPORT_SYMBOL vmlinux 0xf07b47a3 sock_create_kern +EXPORT_SYMBOL vmlinux 0xf0b57c68 param_set_long +EXPORT_SYMBOL vmlinux 0xf0bd72d1 generic_file_direct_write +EXPORT_SYMBOL vmlinux 0xf0caf44b zlib_deflate_workspacesize +EXPORT_SYMBOL vmlinux 0xf0e640a7 qdisc_reset +EXPORT_SYMBOL vmlinux 0xf0f1246c kvasprintf +EXPORT_SYMBOL vmlinux 0xf162fe2d sysctl_xfrm_aevent_etime +EXPORT_SYMBOL vmlinux 0xf1639693 kernel_bind +EXPORT_SYMBOL vmlinux 0xf174ed48 acquire_console_sem +EXPORT_SYMBOL vmlinux 0xf195c682 fb_invert_cmaps +EXPORT_SYMBOL vmlinux 0xf1c31fa1 dcache_dir_open +EXPORT_SYMBOL vmlinux 0xf1deabf2 div64_u64 +EXPORT_SYMBOL vmlinux 0xf1e5a17a svc_drop +EXPORT_SYMBOL vmlinux 0xf1e98c74 avenrun +EXPORT_SYMBOL vmlinux 0xf20dabd8 free_irq +EXPORT_SYMBOL vmlinux 0xf216a6d7 mmc_wait_for_app_cmd +EXPORT_SYMBOL vmlinux 0xf2645054 inode_sub_bytes +EXPORT_SYMBOL vmlinux 0xf27d5f57 bio_map_user +EXPORT_SYMBOL vmlinux 0xf2997713 tty_termios_hw_change +EXPORT_SYMBOL vmlinux 0xf2a6d2bf xfrm_policy_count +EXPORT_SYMBOL vmlinux 0xf2afa595 param_get_charp +EXPORT_SYMBOL vmlinux 0xf2d1d271 bio_alloc +EXPORT_SYMBOL vmlinux 0xf30876a1 __rta_fill +EXPORT_SYMBOL vmlinux 0xf313da4e sha_transform +EXPORT_SYMBOL vmlinux 0xf3284d04 d_prune_aliases +EXPORT_SYMBOL vmlinux 0xf338d4c3 netlink_unregister_notifier +EXPORT_SYMBOL vmlinux 0xf346231f seq_list_start_head +EXPORT_SYMBOL vmlinux 0xf352ff25 generic_setlease +EXPORT_SYMBOL vmlinux 0xf397b9aa __tasklet_schedule +EXPORT_SYMBOL vmlinux 0xf39bf4d9 put_cmsg +EXPORT_SYMBOL vmlinux 0xf3a2cb9e scsi_eh_prep_cmnd +EXPORT_SYMBOL vmlinux 0xf3af9843 blk_alloc_queue_node +EXPORT_SYMBOL vmlinux 0xf3bf0bce __bitmap_complement +EXPORT_SYMBOL vmlinux 0xf3e85a16 udp_disconnect +EXPORT_SYMBOL vmlinux 0xf3fdc5b2 tcp_prot +EXPORT_SYMBOL vmlinux 0xf40cc6bc ps2_init +EXPORT_SYMBOL vmlinux 0xf449f65a ioctl_by_bdev +EXPORT_SYMBOL vmlinux 0xf47cab5e scsi_is_target_device +EXPORT_SYMBOL vmlinux 0xf482fe29 kernel_recvmsg +EXPORT_SYMBOL vmlinux 0xf4a79e43 datagram_poll +EXPORT_SYMBOL vmlinux 0xf4e993e8 is_container_init +EXPORT_SYMBOL vmlinux 0xf4f14de6 rtnl_trylock +EXPORT_SYMBOL vmlinux 0xf51c639f interruptible_sleep_on_timeout +EXPORT_SYMBOL vmlinux 0xf5389382 i2c_smbus_read_word_data +EXPORT_SYMBOL vmlinux 0xf548af2f pci_select_bars +EXPORT_SYMBOL vmlinux 0xf54c780f bio_free +EXPORT_SYMBOL vmlinux 0xf564412a __aeabi_ulcmp +EXPORT_SYMBOL vmlinux 0xf5a34f85 journal_start +EXPORT_SYMBOL vmlinux 0xf5c05914 generic_segment_checks +EXPORT_SYMBOL vmlinux 0xf5c0b61f tty_free_termios +EXPORT_SYMBOL vmlinux 0xf5db9287 set_page_dirty_lock +EXPORT_SYMBOL vmlinux 0xf5dd1128 tcp_v4_remember_stamp +EXPORT_SYMBOL vmlinux 0xf5e2355e blk_put_request +EXPORT_SYMBOL vmlinux 0xf5ecf637 generic_delete_inode +EXPORT_SYMBOL vmlinux 0xf5f7bccc blk_rq_map_user_iov +EXPORT_SYMBOL vmlinux 0xf606ae09 bdget +EXPORT_SYMBOL vmlinux 0xf67caa4a dev_alloc_name +EXPORT_SYMBOL vmlinux 0xf6933c48 lockd_up +EXPORT_SYMBOL vmlinux 0xf6a25fc4 pci_bus_alloc_resource +EXPORT_SYMBOL vmlinux 0xf6bb4729 color_table +EXPORT_SYMBOL vmlinux 0xf6c3f26e rpc_queue_upcall +EXPORT_SYMBOL vmlinux 0xf6ebc03b net_ratelimit +EXPORT_SYMBOL vmlinux 0xf6ff4261 blk_insert_request +EXPORT_SYMBOL vmlinux 0xf701bcfa check_disk_size_change +EXPORT_SYMBOL vmlinux 0xf705269a nobh_writepage +EXPORT_SYMBOL vmlinux 0xf70fbc53 truncate_inode_pages_range +EXPORT_SYMBOL vmlinux 0xf725bcc7 generic_shutdown_super +EXPORT_SYMBOL vmlinux 0xf7384f52 downgrade_write +EXPORT_SYMBOL vmlinux 0xf741c793 zlib_deflateEnd +EXPORT_SYMBOL vmlinux 0xf748c1b0 generic_file_splice_write +EXPORT_SYMBOL vmlinux 0xf7584a9c find_font +EXPORT_SYMBOL vmlinux 0xf75b33c1 pci_iounmap +EXPORT_SYMBOL vmlinux 0xf7623914 radix_tree_tag_clear +EXPORT_SYMBOL vmlinux 0xf76ba89e d_splice_alias +EXPORT_SYMBOL vmlinux 0xf77fbb46 idr_remove_all +EXPORT_SYMBOL vmlinux 0xf7802486 __aeabi_uidivmod +EXPORT_SYMBOL vmlinux 0xf78d04ab netlink_register_notifier +EXPORT_SYMBOL vmlinux 0xf7c1d078 kernel_getsockopt +EXPORT_SYMBOL vmlinux 0xf7f735c0 block_prepare_write +EXPORT_SYMBOL vmlinux 0xf811e69d scsi_eh_flush_done_q +EXPORT_SYMBOL vmlinux 0xf82abc1d isa_dma_bridge_buggy +EXPORT_SYMBOL vmlinux 0xf84252f6 inet_csk_init_xmit_timers +EXPORT_SYMBOL vmlinux 0xf8814f73 rb_last +EXPORT_SYMBOL vmlinux 0xf890fe7f pm_idle +EXPORT_SYMBOL vmlinux 0xf8c8fb17 simple_write_end +EXPORT_SYMBOL vmlinux 0xf8cc33ed __module_put_and_exit +EXPORT_SYMBOL vmlinux 0xf8fbb4f0 __bad_xchg +EXPORT_SYMBOL vmlinux 0xf94dffc2 scsi_dma_unmap +EXPORT_SYMBOL vmlinux 0xf95206f8 skb_copy_and_csum_datagram_iovec +EXPORT_SYMBOL vmlinux 0xf95c7346 mii_check_gmii_support +EXPORT_SYMBOL vmlinux 0xf96cbcaa sock_no_sendpage +EXPORT_SYMBOL vmlinux 0xf9a482f9 msleep +EXPORT_SYMBOL vmlinux 0xf9b1cb2a generic_fillattr +EXPORT_SYMBOL vmlinux 0xf9b28bac interruptible_sleep_on +EXPORT_SYMBOL vmlinux 0xf9bb0d18 tty_name +EXPORT_SYMBOL vmlinux 0xf9c1ea2f dst_destroy +EXPORT_SYMBOL vmlinux 0xf9dec89e scsi_print_command +EXPORT_SYMBOL vmlinux 0xfa029835 fb_set_var +EXPORT_SYMBOL vmlinux 0xfa301ddd i2c_probe +EXPORT_SYMBOL vmlinux 0xfa78ebc6 shrink_dcache_parent +EXPORT_SYMBOL vmlinux 0xfa7f633b call_usermodehelper_pipe +EXPORT_SYMBOL vmlinux 0xfabde30d scsi_target_resume +EXPORT_SYMBOL vmlinux 0xfac68eba arm_elf_read_implies_exec +EXPORT_SYMBOL vmlinux 0xfad718ed km_query +EXPORT_SYMBOL vmlinux 0xfae0e8d5 generic_block_bmap +EXPORT_SYMBOL vmlinux 0xfae38091 pci_set_power_state +EXPORT_SYMBOL vmlinux 0xfaf4e935 sock_no_sendmsg +EXPORT_SYMBOL vmlinux 0xfaf98462 bitrev32 +EXPORT_SYMBOL vmlinux 0xfafd19d2 linkwatch_fire_event +EXPORT_SYMBOL vmlinux 0xfb0cf2e9 touch_all_softlockup_watchdogs +EXPORT_SYMBOL vmlinux 0xfb24a1a2 cfb_imageblit +EXPORT_SYMBOL vmlinux 0xfb326a5d down +EXPORT_SYMBOL vmlinux 0xfb580c11 ip_route_input +EXPORT_SYMBOL vmlinux 0xfb6af58d recalc_sigpending +EXPORT_SYMBOL vmlinux 0xfb7d9c45 __udivsi3 +EXPORT_SYMBOL vmlinux 0xfba5db08 xfrm_state_check_expire +EXPORT_SYMBOL vmlinux 0xfbb9406f sync_blockdev +EXPORT_SYMBOL vmlinux 0xfbc74f64 __copy_from_user +EXPORT_SYMBOL vmlinux 0xfbdf07c0 kmem_cache_destroy +EXPORT_SYMBOL vmlinux 0xfbe82a89 scsi_scan_target +EXPORT_SYMBOL vmlinux 0xfbf3242e mmc_unregister_driver +EXPORT_SYMBOL vmlinux 0xfbf92453 param_get_bool +EXPORT_SYMBOL vmlinux 0xfc02b7ad sysctl_tcp_wmem +EXPORT_SYMBOL vmlinux 0xfc0d3a90 tty_flip_buffer_push +EXPORT_SYMBOL vmlinux 0xfc10c21d register_mtd_chip_driver +EXPORT_SYMBOL vmlinux 0xfc39e32f ioport_unmap +EXPORT_SYMBOL vmlinux 0xfc533f85 schedule_work_on +EXPORT_SYMBOL vmlinux 0xfc5f3f6e path_get +EXPORT_SYMBOL vmlinux 0xfc61f2d6 ip_defrag +EXPORT_SYMBOL vmlinux 0xfcaa04a0 out_of_line_wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0xfcb0dfbf i2c_smbus_write_word_data +EXPORT_SYMBOL vmlinux 0xfcda63a3 node_states +EXPORT_SYMBOL vmlinux 0xfcdd8cf6 param_get_ushort +EXPORT_SYMBOL vmlinux 0xfcec0987 enable_irq +EXPORT_SYMBOL vmlinux 0xfcfa03ff fb_videomode_to_modelist +EXPORT_SYMBOL vmlinux 0xfd8704b2 sock_no_shutdown +EXPORT_SYMBOL vmlinux 0xfd8dba4c add_wait_queue +EXPORT_SYMBOL vmlinux 0xfd98879a rb_next +EXPORT_SYMBOL vmlinux 0xfdab6de3 unregister_sound_midi +EXPORT_SYMBOL vmlinux 0xfdfc0b3b fiemap_fill_next_extent +EXPORT_SYMBOL vmlinux 0xfe16775f idr_destroy +EXPORT_SYMBOL vmlinux 0xfe271510 mutex_lock_killable +EXPORT_SYMBOL vmlinux 0xfe3dd98d tcp_disconnect +EXPORT_SYMBOL vmlinux 0xfe4a3852 pci_request_selected_regions +EXPORT_SYMBOL vmlinux 0xfe5d4bb2 sys_tz +EXPORT_SYMBOL vmlinux 0xfe769456 unregister_netdevice_notifier +EXPORT_SYMBOL vmlinux 0xfec0a7cf __free_pages +EXPORT_SYMBOL vmlinux 0xfec12a94 simple_sync_file +EXPORT_SYMBOL vmlinux 0xfec3c2f2 bcd2bin +EXPORT_SYMBOL vmlinux 0xfedd35fc console_suspend_enabled +EXPORT_SYMBOL vmlinux 0xfef96e23 __scsi_print_command +EXPORT_SYMBOL vmlinux 0xfefb2f32 pci_enable_device +EXPORT_SYMBOL vmlinux 0xff1e9dd8 seq_list_start +EXPORT_SYMBOL vmlinux 0xff5d560e udp_lib_setsockopt +EXPORT_SYMBOL vmlinux 0xff67b37f __lshrdi3 +EXPORT_SYMBOL vmlinux 0xff6878cf fb_default_cmap +EXPORT_SYMBOL vmlinux 0xff6c4099 simple_fill_super +EXPORT_SYMBOL vmlinux 0xff9ca065 fb_edid_to_monspecs +EXPORT_SYMBOL vmlinux 0xffa35b78 follow_up +EXPORT_SYMBOL vmlinux 0xffd3c5e3 pci_scan_slot +EXPORT_SYMBOL vmlinux 0xffd5a395 default_wake_function +EXPORT_SYMBOL vmlinux 0xffff9c09 alloc_pci_dev +EXPORT_SYMBOL_GPL crypto/aead 0x2f62e141 crypto_grab_aead +EXPORT_SYMBOL_GPL crypto/aead 0x3eed17fe crypto_nivaead_type +EXPORT_SYMBOL_GPL crypto/aead 0x504d45eb aead_geniv_alloc +EXPORT_SYMBOL_GPL crypto/aead 0x6b6767be crypto_alloc_aead +EXPORT_SYMBOL_GPL crypto/aead 0x743f421c crypto_aead_type +EXPORT_SYMBOL_GPL crypto/aead 0x8708ec35 aead_geniv_exit +EXPORT_SYMBOL_GPL crypto/aead 0x895f93e9 crypto_aead_setauthsize +EXPORT_SYMBOL_GPL crypto/aead 0x94109d73 aead_geniv_free +EXPORT_SYMBOL_GPL crypto/aead 0xc0a78602 aead_geniv_init +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x101bc8be crypto_unregister_template +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x11fe931c crypto_enqueue_request +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x124f2056 crypto_get_attr_type +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x17cc513f crypto_tfm_in_queue +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x190873a5 crypto_register_instance +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x2296c00d crypto_attr_u32 +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x321a3aff crypto_lookup_template +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x45bf1ff3 crypto_inc +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x499043d3 crypto_init_queue +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x4a8b17cc crypto_alloc_instance +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x58157640 scatterwalk_map +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x5f1cced5 scatterwalk_start +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x733c3dfe crypto_register_template +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x75e8f3c3 crypto_register_notifier +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x7dc5d0b6 crypto_unregister_notifier +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x808ec1a3 crypto_alg_tested +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x83553786 scatterwalk_copychunks +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x8810ad5e crypto_xor +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x8a52b393 crypto_init_spawn +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x8f0db8b1 crypto_spawn_tfm +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x977924b1 crypto_dequeue_request +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x9a11a0fc crypto_attr_alg_name +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x9b683b45 scatterwalk_done +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xa77bf454 crypto_attr_alg +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xcc11420e crypto_unregister_alg +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xd16712f3 crypto_check_attr_type +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xdf636e91 crypto_register_alg +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xf807fd65 scatterwalk_map_and_copy +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xfc985fae crypto_drop_spawn +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xfde0b92c crypto_larval_error +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x092a9083 skcipher_geniv_init +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x19736468 skcipher_geniv_exit +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x1d046404 blkcipher_walk_phys +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x3b77b217 blkcipher_walk_virt_block +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x5e9046ea skcipher_geniv_alloc +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x5eb810f9 crypto_alloc_ablkcipher +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x65632486 blkcipher_walk_done +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x6f00604f crypto_ablkcipher_type +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x8c009a37 crypto_givcipher_type +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x982a1da3 blkcipher_walk_virt +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0xb66b4cd9 skcipher_geniv_free +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0xc80f8c75 crypto_blkcipher_type +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0xe14cbd88 crypto_grab_skcipher +EXPORT_SYMBOL_GPL crypto/crypto_hash 0x5c495be3 crypto_hash_walk_done +EXPORT_SYMBOL_GPL crypto/crypto_hash 0x7d14b8bf crypto_ahash_type +EXPORT_SYMBOL_GPL crypto/crypto_hash 0x81b924da crypto_hash_type +EXPORT_SYMBOL_GPL crypto/crypto_hash 0xfd780f1f crypto_hash_walk_first +EXPORT_SYMBOL_GPL crypto/cryptomgr 0x5086ac3a alg_test +EXPORT_SYMBOL_GPL crypto/rng 0x0b51636b crypto_default_rng +EXPORT_SYMBOL_GPL crypto/rng 0x668402aa crypto_put_default_rng +EXPORT_SYMBOL_GPL crypto/rng 0x6ff607b6 crypto_get_default_rng +EXPORT_SYMBOL_GPL crypto/rng 0xd43b0bef crypto_rng_type +EXPORT_SYMBOL_GPL drivers/char/hw_random/rng-core 0x86b1667d hwrng_unregister +EXPORT_SYMBOL_GPL drivers/char/hw_random/rng-core 0xf6bcbd73 hwrng_register +EXPORT_SYMBOL_GPL drivers/md/dm-multipath 0x8d79a36d dm_unregister_path_selector +EXPORT_SYMBOL_GPL drivers/md/dm-multipath 0xd16687c8 dm_register_path_selector +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x0db4998a dm_rh_update_states +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x1a66a2a3 dm_rh_dirty_log +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x1fe8877b dm_rh_mark_nosync +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x254e5dc0 dm_rh_inc_pending +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x2836a486 dm_rh_stop_recovery +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x2b56b927 dm_rh_get_region_key +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x36b3dbb5 dm_region_hash_destroy +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x3fc07e8b dm_rh_flush +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x446e57ea dm_rh_get_region_size +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x5b1a10bd dm_rh_region_to_sector +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x745aece1 dm_rh_bio_to_region +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x94e9595a dm_rh_delay +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x94eb5901 dm_rh_recovery_in_flight +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xacd08b63 dm_rh_start_recovery +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xbba46972 dm_rh_region_context +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xbc95279e dm_rh_dec +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xc6b41ca5 dm_rh_recovery_end +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xd8ad45fd dm_region_hash_create +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xebf46f71 dm_rh_get_state +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xeeabdb81 dm_rh_recovery_start +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xfeac6522 dm_rh_recovery_prepare +EXPORT_SYMBOL_GPL drivers/serial/8250_pci 0x244120c3 pciserial_init_ports +EXPORT_SYMBOL_GPL drivers/serial/8250_pci 0x6be7d952 pciserial_suspend_ports +EXPORT_SYMBOL_GPL drivers/serial/8250_pci 0xb9de3134 pciserial_resume_ports +EXPORT_SYMBOL_GPL drivers/serial/8250_pci 0xc47bff9f pciserial_remove_ports +EXPORT_SYMBOL_GPL fs/fat/fat 0x1665f717 fat_remove_entries +EXPORT_SYMBOL_GPL fs/fat/fat 0x340155fb fat_getattr +EXPORT_SYMBOL_GPL fs/fat/fat 0x35b3d562 fat_get_dotdot_entry +EXPORT_SYMBOL_GPL fs/fat/fat 0x3f0b7de0 fat_sync_inode +EXPORT_SYMBOL_GPL fs/fat/fat 0x453a0150 fat_flush_inodes +EXPORT_SYMBOL_GPL fs/fat/fat 0x4a5877a0 fat_scan +EXPORT_SYMBOL_GPL fs/fat/fat 0x4d62077e fat_time_unix2fat +EXPORT_SYMBOL_GPL fs/fat/fat 0x5166ac82 fat_fill_super +EXPORT_SYMBOL_GPL fs/fat/fat 0x5674c1d7 fat_add_entries +EXPORT_SYMBOL_GPL fs/fat/fat 0x593fc117 fat_alloc_new_dir +EXPORT_SYMBOL_GPL fs/fat/fat 0x8dc5eb4f fat_detach +EXPORT_SYMBOL_GPL fs/fat/fat 0x9e8b0569 fat_dir_empty +EXPORT_SYMBOL_GPL fs/fat/fat 0xa57f84d7 fat_build_inode +EXPORT_SYMBOL_GPL fs/fat/fat 0xae2f0d01 fat_search_long +EXPORT_SYMBOL_GPL fs/fat/fat 0xbea849c0 fat_setattr +EXPORT_SYMBOL_GPL fs/fat/fat 0xc1953189 fat_attach +EXPORT_SYMBOL_GPL fs/fat/fat 0xc2b61736 fat_free_clusters +EXPORT_SYMBOL_GPL fs/fat/fat 0xdefed758 fat_fs_panic +EXPORT_SYMBOL_GPL lib/lzo/lzo_compress 0x56b63670 lzo1x_1_compress +EXPORT_SYMBOL_GPL lib/lzo/lzo_decompress 0xf30fda27 lzo1x_decompress_safe +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x1584fdb9 tlsf_destroy_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x42a50f11 tlsf_malloc +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x66da3d8f tlsf_create_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xe6acc368 tlsf_free +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xee6c65c9 tlsf_get_used_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xeec8caeb tlsf_get_total_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xf9805f1b tlsf_calloc +EXPORT_SYMBOL_GPL vmlinux 0x001d38e4 bus_create_file +EXPORT_SYMBOL_GPL vmlinux 0x004e8db8 ata_sg_init +EXPORT_SYMBOL_GPL vmlinux 0x00566d8f inotify_get_cookie +EXPORT_SYMBOL_GPL vmlinux 0x0067df75 ata_tf_from_fis +EXPORT_SYMBOL_GPL vmlinux 0x009f8333 blk_set_cmd_filter_defaults +EXPORT_SYMBOL_GPL vmlinux 0x00ebcb5d ata_id_string +EXPORT_SYMBOL_GPL vmlinux 0x01380cf9 sysdev_show_ulong +EXPORT_SYMBOL_GPL vmlinux 0x017be276 register_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0x01a4ea6d unregister_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x02be3fcd d_materialise_unique +EXPORT_SYMBOL_GPL vmlinux 0x02fa4b38 pci_destroy_slot +EXPORT_SYMBOL_GPL vmlinux 0x031937e1 platform_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x0343bdf1 __i2c_board_list +EXPORT_SYMBOL_GPL vmlinux 0x034733d0 rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x03e3686c ata_timing_cycle2mode +EXPORT_SYMBOL_GPL vmlinux 0x04486e88 rcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x04f8b56e ata_port_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0x05049828 platform_get_irq_byname +EXPORT_SYMBOL_GPL vmlinux 0x0531dcb8 ata_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0x054e550b kernel_halt +EXPORT_SYMBOL_GPL vmlinux 0x0592cec9 crypto_free_tfm +EXPORT_SYMBOL_GPL vmlinux 0x05d54ecf tcp_twsk_destructor +EXPORT_SYMBOL_GPL vmlinux 0x064db9a5 mark_mounts_for_expiry +EXPORT_SYMBOL_GPL vmlinux 0x06cdbbbc disk_part_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x0702fa46 pid_vnr +EXPORT_SYMBOL_GPL vmlinux 0x07b52e38 rtnl_unregister +EXPORT_SYMBOL_GPL vmlinux 0x082eef90 sata_async_notification +EXPORT_SYMBOL_GPL vmlinux 0x086ab268 klist_init +EXPORT_SYMBOL_GPL vmlinux 0x086bebc9 ata_host_resume +EXPORT_SYMBOL_GPL vmlinux 0x091eb9b4 round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0x093b0361 console_drivers +EXPORT_SYMBOL_GPL vmlinux 0x09510eac exit_fs +EXPORT_SYMBOL_GPL vmlinux 0x09b55bd2 sdio_align_size +EXPORT_SYMBOL_GPL vmlinux 0x0a16f97c sdio_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x0a4b3a84 sdio_release_irq +EXPORT_SYMBOL_GPL vmlinux 0x0a575dd9 sdio_f0_writeb +EXPORT_SYMBOL_GPL vmlinux 0x0ac81b07 driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0x0ad35820 __blk_put_request +EXPORT_SYMBOL_GPL vmlinux 0x0b28d79a blk_rq_bytes +EXPORT_SYMBOL_GPL vmlinux 0x0b2d47da bus_unregister +EXPORT_SYMBOL_GPL vmlinux 0x0b99b40a put_device +EXPORT_SYMBOL_GPL vmlinux 0x0bd31d4f __i2c_board_lock +EXPORT_SYMBOL_GPL vmlinux 0x0c17e274 xfrm_aalg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x0caf3419 __mnt_is_readonly +EXPORT_SYMBOL_GPL vmlinux 0x0cce6521 bdi_writeout_inc +EXPORT_SYMBOL_GPL vmlinux 0x0d25b336 xdr_partial_copy_from_skb +EXPORT_SYMBOL_GPL vmlinux 0x0d4d0814 vfs_cancel_lock +EXPORT_SYMBOL_GPL vmlinux 0x0dc09ed2 unregister_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0x0dd571cc bd_claim_by_disk +EXPORT_SYMBOL_GPL vmlinux 0x0dd86741 devres_release_group +EXPORT_SYMBOL_GPL vmlinux 0x0ed26421 vfs_setxattr +EXPORT_SYMBOL_GPL vmlinux 0x0ef06974 spi_populate_ppr_msg +EXPORT_SYMBOL_GPL vmlinux 0x0f17ee80 rtc_set_mmss +EXPORT_SYMBOL_GPL vmlinux 0x0f70e0a3 ata_pci_device_suspend +EXPORT_SYMBOL_GPL vmlinux 0x0f884196 transport_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0x0ffe7821 ata_host_activate +EXPORT_SYMBOL_GPL vmlinux 0x1089c48d xprt_reserve_xprt +EXPORT_SYMBOL_GPL vmlinux 0x10e7ffb8 rpc_call_start +EXPORT_SYMBOL_GPL vmlinux 0x11003a9f blk_execute_rq_nowait +EXPORT_SYMBOL_GPL vmlinux 0x113725f4 dm_put +EXPORT_SYMBOL_GPL vmlinux 0x113ce4b6 user_instantiate +EXPORT_SYMBOL_GPL vmlinux 0x11455ede default_backing_dev_info +EXPORT_SYMBOL_GPL vmlinux 0x118445fe lookup_instantiate_filp +EXPORT_SYMBOL_GPL vmlinux 0x1192617c pci_bus_add_device +EXPORT_SYMBOL_GPL vmlinux 0x1251d30f call_rcu +EXPORT_SYMBOL_GPL vmlinux 0x131f4d36 xprt_write_space +EXPORT_SYMBOL_GPL vmlinux 0x1388c794 tcp_reno_min_cwnd +EXPORT_SYMBOL_GPL vmlinux 0x13b2a946 register_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x1423612b do_add_mount +EXPORT_SYMBOL_GPL vmlinux 0x14b50350 vfs_listxattr +EXPORT_SYMBOL_GPL vmlinux 0x15284bb9 dev_attr_link_power_management_policy +EXPORT_SYMBOL_GPL vmlinux 0x1561c044 tty_mode_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x1578c881 generic_fh_to_parent +EXPORT_SYMBOL_GPL vmlinux 0x1598dc9d unregister_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x15c033aa drop_file_write_access +EXPORT_SYMBOL_GPL vmlinux 0x16445dc0 class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x1672b430 xprt_register_transport +EXPORT_SYMBOL_GPL vmlinux 0x16f76869 probe_kernel_read +EXPORT_SYMBOL_GPL vmlinux 0x16fdcf3e rpc_restart_call +EXPORT_SYMBOL_GPL vmlinux 0x173f64dd ata_eh_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0x1765e57d rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0x17993ef9 get_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0x17ce645d locks_end_grace +EXPORT_SYMBOL_GPL vmlinux 0x17da4341 blk_abort_request +EXPORT_SYMBOL_GPL vmlinux 0x1871a19d svc_reg_xprt_class +EXPORT_SYMBOL_GPL vmlinux 0x18acce42 audit_log_d_path +EXPORT_SYMBOL_GPL vmlinux 0x18bd1c31 ata_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0x18d55693 tty_ldisc_ref +EXPORT_SYMBOL_GPL vmlinux 0x190fb1b4 bus_find_device_by_name +EXPORT_SYMBOL_GPL vmlinux 0x1916dcc0 key_type_user +EXPORT_SYMBOL_GPL vmlinux 0x191fb096 srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x192e98a9 __get_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x194a3010 rtc_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x1963fb25 sysfs_add_file_to_group +EXPORT_SYMBOL_GPL vmlinux 0x1a618932 nlmsvc_unlock_all_by_ip +EXPORT_SYMBOL_GPL vmlinux 0x1b775b1e pci_execute_reset_function +EXPORT_SYMBOL_GPL vmlinux 0x1c53d2d3 platform_device_put +EXPORT_SYMBOL_GPL vmlinux 0x1c87a811 __round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x1c9e595d proc_net_mkdir +EXPORT_SYMBOL_GPL vmlinux 0x1ca4e0bf rpc_peeraddr +EXPORT_SYMBOL_GPL vmlinux 0x1cf56fac xprt_lookup_rqst +EXPORT_SYMBOL_GPL vmlinux 0x1d536236 sysdev_create_file +EXPORT_SYMBOL_GPL vmlinux 0x1d87f9db bus_for_each_drv +EXPORT_SYMBOL_GPL vmlinux 0x1dd45a23 sdio_readsb +EXPORT_SYMBOL_GPL vmlinux 0x1e141fed sysfs_remove_link +EXPORT_SYMBOL_GPL vmlinux 0x1e7bbcb3 kernel_restart +EXPORT_SYMBOL_GPL vmlinux 0x1eb9516e round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x1fcece42 inet_twdr_twcal_tick +EXPORT_SYMBOL_GPL vmlinux 0x204e0e8a do_sync_mapping_range +EXPORT_SYMBOL_GPL vmlinux 0x20577ea2 xfrm_ealg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x207e4fc8 bd_release_from_disk +EXPORT_SYMBOL_GPL vmlinux 0x20bc3470 orderly_poweroff +EXPORT_SYMBOL_GPL vmlinux 0x20cfd3fb bus_register +EXPORT_SYMBOL_GPL vmlinux 0x20fdd69a sata_link_debounce +EXPORT_SYMBOL_GPL vmlinux 0x22472bf4 xfrm_calg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x224b30be ata_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0x2257818e ata_do_set_mode +EXPORT_SYMBOL_GPL vmlinux 0x2276a2ca vfs_lock_file +EXPORT_SYMBOL_GPL vmlinux 0x22a2db87 class_destroy +EXPORT_SYMBOL_GPL vmlinux 0x22ac5ce5 class_dev_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x22e2c20b atomic_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x22eb3c18 hrtimer_try_to_cancel +EXPORT_SYMBOL_GPL vmlinux 0x233e68da device_find_child +EXPORT_SYMBOL_GPL vmlinux 0x23679939 __iowrite32_copy +EXPORT_SYMBOL_GPL vmlinux 0x23869dc7 cancel_work_sync +EXPORT_SYMBOL_GPL vmlinux 0x23bd4f2d __ip_route_output_key +EXPORT_SYMBOL_GPL vmlinux 0x247c1b88 init_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0x251aba7c inotify_init +EXPORT_SYMBOL_GPL vmlinux 0x25b6e7da sdio_readl +EXPORT_SYMBOL_GPL vmlinux 0x26147964 skb_partial_csum_set +EXPORT_SYMBOL_GPL vmlinux 0x264ed4bd hrtimer_start_range_ns +EXPORT_SYMBOL_GPL vmlinux 0x26c90ea4 scsi_eh_get_sense +EXPORT_SYMBOL_GPL vmlinux 0x26edb50c crypto_mod_get +EXPORT_SYMBOL_GPL vmlinux 0x2754dc39 svc_unreg_xprt_class +EXPORT_SYMBOL_GPL vmlinux 0x27c52e7e sysfs_notify_dirent +EXPORT_SYMBOL_GPL vmlinux 0x28b2cc80 atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x28bd44ff ata_port_pbar_desc +EXPORT_SYMBOL_GPL vmlinux 0x28d664ff __raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x28ddf90c dev_set_name +EXPORT_SYMBOL_GPL vmlinux 0x28e23139 xfrm_probe_algs +EXPORT_SYMBOL_GPL vmlinux 0x29546126 ata_cable_40wire +EXPORT_SYMBOL_GPL vmlinux 0x298543dc dequeue_signal +EXPORT_SYMBOL_GPL vmlinux 0x29915d17 tcp_is_cwnd_limited +EXPORT_SYMBOL_GPL vmlinux 0x29bb90ca devres_open_group +EXPORT_SYMBOL_GPL vmlinux 0x29c13863 scsi_flush_work +EXPORT_SYMBOL_GPL vmlinux 0x2a2d93b7 klist_add_before +EXPORT_SYMBOL_GPL vmlinux 0x2a4d0d7b ata_cable_ignore +EXPORT_SYMBOL_GPL vmlinux 0x2aa17774 rpc_free_iostats +EXPORT_SYMBOL_GPL vmlinux 0x2aed9924 k_handler +EXPORT_SYMBOL_GPL vmlinux 0x2b8299cd crypto_larval_lookup +EXPORT_SYMBOL_GPL vmlinux 0x2c16ed76 xfrm_calg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x2c5b1562 rtc_update_irq +EXPORT_SYMBOL_GPL vmlinux 0x2ca8bc4d inet_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0x2d2c265c sched_setscheduler +EXPORT_SYMBOL_GPL vmlinux 0x2d4fa7de tcp_get_info +EXPORT_SYMBOL_GPL vmlinux 0x2e3d08b9 crypto_chain +EXPORT_SYMBOL_GPL vmlinux 0x2e78ead2 register_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0x2f3967a0 ata_eh_analyze_ncq_error +EXPORT_SYMBOL_GPL vmlinux 0x2f5a6019 rpc_setbufsize +EXPORT_SYMBOL_GPL vmlinux 0x2fafcf2e __rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0x3094bb77 blk_queue_dma_drain +EXPORT_SYMBOL_GPL vmlinux 0x31051243 disk_get_part +EXPORT_SYMBOL_GPL vmlinux 0x31a89d59 rpc_debug +EXPORT_SYMBOL_GPL vmlinux 0x31b33a8d rtc_device_register +EXPORT_SYMBOL_GPL vmlinux 0x32155baf scsi_target_unblock +EXPORT_SYMBOL_GPL vmlinux 0x321be924 lookup_create +EXPORT_SYMBOL_GPL vmlinux 0x3239dfa4 rpc_wake_up_status +EXPORT_SYMBOL_GPL vmlinux 0x32727b17 rpcauth_init_cred +EXPORT_SYMBOL_GPL vmlinux 0x32ddee2c ata_eh_freeze_port +EXPORT_SYMBOL_GPL vmlinux 0x32f3e790 sdio_readw +EXPORT_SYMBOL_GPL vmlinux 0x330f1764 devm_kfree +EXPORT_SYMBOL_GPL vmlinux 0x33481af7 device_reprobe +EXPORT_SYMBOL_GPL vmlinux 0x336190ef dma_get_required_mask +EXPORT_SYMBOL_GPL vmlinux 0x34f80ba1 inet_csk_route_req +EXPORT_SYMBOL_GPL vmlinux 0x350af7a3 put_rpccred +EXPORT_SYMBOL_GPL vmlinux 0x352b013f pci_stop_bus_device +EXPORT_SYMBOL_GPL vmlinux 0x35cf63ff rpc_init_wait_queue +EXPORT_SYMBOL_GPL vmlinux 0x35d8c94a sdev_evt_alloc +EXPORT_SYMBOL_GPL vmlinux 0x35ec7fcb klist_next +EXPORT_SYMBOL_GPL vmlinux 0x3608bc1d input_ff_destroy +EXPORT_SYMBOL_GPL vmlinux 0x3618f892 sysfs_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x362e23ec call_rcu_bh +EXPORT_SYMBOL_GPL vmlinux 0x36bffc3f dev_attr_em_message +EXPORT_SYMBOL_GPL vmlinux 0x3740d2b8 pci_create_slot +EXPORT_SYMBOL_GPL vmlinux 0x3757d6ad xprt_complete_rqst +EXPORT_SYMBOL_GPL vmlinux 0x376574b2 kernel_kobj +EXPORT_SYMBOL_GPL vmlinux 0x3783f420 __rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0x378c44d6 disk_part_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x37b46f24 dnotify_parent +EXPORT_SYMBOL_GPL vmlinux 0x38197dbc sdio_release_host +EXPORT_SYMBOL_GPL vmlinux 0x38dc3ead fsstack_copy_inode_size +EXPORT_SYMBOL_GPL vmlinux 0x38eebce6 driver_find_device +EXPORT_SYMBOL_GPL vmlinux 0x39283362 add_mtd_blktrans_dev +EXPORT_SYMBOL_GPL vmlinux 0x394a8e26 disk_part_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x39819646 atomic_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x3998057a ata_slave_link_init +EXPORT_SYMBOL_GPL vmlinux 0x39cb64bd free_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x39f69472 hrtimer_forward +EXPORT_SYMBOL_GPL vmlinux 0x3a7f8b86 __local_bh_enable +EXPORT_SYMBOL_GPL vmlinux 0x3a86d005 ata_qc_complete_multiple +EXPORT_SYMBOL_GPL vmlinux 0x3bc33f65 cleanup_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x3be7af02 get_max_files +EXPORT_SYMBOL_GPL vmlinux 0x3c31c8d9 ata_cable_sata +EXPORT_SYMBOL_GPL vmlinux 0x3c8a4d46 bus_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x3cd06035 add_input_randomness +EXPORT_SYMBOL_GPL vmlinux 0x3d886554 device_bind_driver +EXPORT_SYMBOL_GPL vmlinux 0x3ddff22a inotify_remove_watch_locked +EXPORT_SYMBOL_GPL vmlinux 0x3e54122f rtc_irq_unregister +EXPORT_SYMBOL_GPL vmlinux 0x3e9b4d09 vfs_getxattr +EXPORT_SYMBOL_GPL vmlinux 0x3efbb0f5 simple_attr_read +EXPORT_SYMBOL_GPL vmlinux 0x3f01570a probe_kernel_write +EXPORT_SYMBOL_GPL vmlinux 0x40364977 __class_create +EXPORT_SYMBOL_GPL vmlinux 0x4071e1c3 xprt_release_rqst_cong +EXPORT_SYMBOL_GPL vmlinux 0x40af0dec ata_xfer_mode2mask +EXPORT_SYMBOL_GPL vmlinux 0x40b63405 inotify_inode_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x40e07a3e ata_link_abort +EXPORT_SYMBOL_GPL vmlinux 0x418f4025 sysfs_get_dirent +EXPORT_SYMBOL_GPL vmlinux 0x41f3cc90 xfrm_aalg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x421a500c sysctl_pathname +EXPORT_SYMBOL_GPL vmlinux 0x425d5cc9 platform_device_del +EXPORT_SYMBOL_GPL vmlinux 0x426f261a crypto_alg_mod_lookup +EXPORT_SYMBOL_GPL vmlinux 0x429d8393 tcp_register_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0x42f5369f sdio_writeb +EXPORT_SYMBOL_GPL vmlinux 0x433e3263 device_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x43a50c7e scsi_internal_device_block +EXPORT_SYMBOL_GPL vmlinux 0x43f56e82 ata_xfer_mode2shift +EXPORT_SYMBOL_GPL vmlinux 0x44247598 user_match +EXPORT_SYMBOL_GPL vmlinux 0x44421389 rt_mutex_timed_lock +EXPORT_SYMBOL_GPL vmlinux 0x4482c007 rtc_set_time +EXPORT_SYMBOL_GPL vmlinux 0x44f56cd9 simple_attr_open +EXPORT_SYMBOL_GPL vmlinux 0x44f9d171 device_schedule_callback_owner +EXPORT_SYMBOL_GPL vmlinux 0x451de426 netlink_has_listeners +EXPORT_SYMBOL_GPL vmlinux 0x4526ab55 svc_print_addr +EXPORT_SYMBOL_GPL vmlinux 0x45657b78 rpc_wake_up +EXPORT_SYMBOL_GPL vmlinux 0x457594fa crypto_alg_list +EXPORT_SYMBOL_GPL vmlinux 0x45a5e839 platform_device_add +EXPORT_SYMBOL_GPL vmlinux 0x45a77905 platform_bus +EXPORT_SYMBOL_GPL vmlinux 0x45bc8d4e posix_timer_event +EXPORT_SYMBOL_GPL vmlinux 0x463d3c70 inet_csk_reqsk_queue_prune +EXPORT_SYMBOL_GPL vmlinux 0x4660054c find_get_pid +EXPORT_SYMBOL_GPL vmlinux 0x46ec82e9 sysfs_remove_file_from_group +EXPORT_SYMBOL_GPL vmlinux 0x475273cb sg_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x475f042f xprt_disconnect_done +EXPORT_SYMBOL_GPL vmlinux 0x4772e115 pci_block_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0x47ca3d9d sdio_claim_host +EXPORT_SYMBOL_GPL vmlinux 0x48001782 rpc_killall_tasks +EXPORT_SYMBOL_GPL vmlinux 0x49c5e180 udp4_lib_lookup +EXPORT_SYMBOL_GPL vmlinux 0x49dcba62 rpc_delay +EXPORT_SYMBOL_GPL vmlinux 0x49e551b4 rpcauth_init_credcache +EXPORT_SYMBOL_GPL vmlinux 0x4a4265a8 get_cpu_sysdev +EXPORT_SYMBOL_GPL vmlinux 0x4a56cabf ata_host_alloc_pinfo +EXPORT_SYMBOL_GPL vmlinux 0x4a589d15 blk_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0x4a97a37f platform_add_devices +EXPORT_SYMBOL_GPL vmlinux 0x4b4d2445 sysdev_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x4b5c5b48 driver_find +EXPORT_SYMBOL_GPL vmlinux 0x4ba2448b __sock_recv_timestamp +EXPORT_SYMBOL_GPL vmlinux 0x4bc62189 ata_pci_remove_one +EXPORT_SYMBOL_GPL vmlinux 0x4bd1bcf0 rpc_print_iostats +EXPORT_SYMBOL_GPL vmlinux 0x4c2e0b43 sysdev_class_register +EXPORT_SYMBOL_GPL vmlinux 0x4c759827 byte_rev_table +EXPORT_SYMBOL_GPL vmlinux 0x4c7b8645 rpc_max_payload +EXPORT_SYMBOL_GPL vmlinux 0x4e4faecd sata_scr_write_flush +EXPORT_SYMBOL_GPL vmlinux 0x4eeedc88 blk_queue_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0x4fceb18d sysdev_class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x4fdb8ca5 pci_find_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0x4fdc945d sata_deb_timing_normal +EXPORT_SYMBOL_GPL vmlinux 0x504dc48c sysfs_create_group +EXPORT_SYMBOL_GPL vmlinux 0x507ae0ef ata_eh_thaw_port +EXPORT_SYMBOL_GPL vmlinux 0x50b67174 xfrm_ealg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x50d42d3f ata_host_start +EXPORT_SYMBOL_GPL vmlinux 0x50e7193a __i2c_first_dynamic_bus_num +EXPORT_SYMBOL_GPL vmlinux 0x50fad434 round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x513b3afb tty_put_char +EXPORT_SYMBOL_GPL vmlinux 0x51a10f72 ata_common_sdev_attrs +EXPORT_SYMBOL_GPL vmlinux 0x51d7bd4a cfi_cmdset_0001 +EXPORT_SYMBOL_GPL vmlinux 0x51dd6488 xfrm_aalg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x51ff3d27 security_inode_setattr +EXPORT_SYMBOL_GPL vmlinux 0x52209557 ata_host_init +EXPORT_SYMBOL_GPL vmlinux 0x52b05686 ata_std_bios_param +EXPORT_SYMBOL_GPL vmlinux 0x52d111ea pm_qos_update_requirement +EXPORT_SYMBOL_GPL vmlinux 0x53445f68 nlm_debug +EXPORT_SYMBOL_GPL vmlinux 0x5394d710 bus_find_device +EXPORT_SYMBOL_GPL vmlinux 0x53986488 register_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5435f54d page_cache_async_readahead +EXPORT_SYMBOL_GPL vmlinux 0x5471f34b xprt_wake_pending_tasks +EXPORT_SYMBOL_GPL vmlinux 0x549e5996 sdio_disable_func +EXPORT_SYMBOL_GPL vmlinux 0x5517cc21 inotify_find_watch +EXPORT_SYMBOL_GPL vmlinux 0x5542b913 cpu_bit_bitmap +EXPORT_SYMBOL_GPL vmlinux 0x554c9c1c cfi_qry_mode_on +EXPORT_SYMBOL_GPL vmlinux 0x557c6a75 transport_configure_device +EXPORT_SYMBOL_GPL vmlinux 0x55b1e7e1 synchronize_srcu +EXPORT_SYMBOL_GPL vmlinux 0x5636ccf6 dm_device_name +EXPORT_SYMBOL_GPL vmlinux 0x5641485b tty_termios_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x5651f040 blk_queue_rq_timeout +EXPORT_SYMBOL_GPL vmlinux 0x56d42418 thread_notify_head +EXPORT_SYMBOL_GPL vmlinux 0x56e6cdde uhci_check_and_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0x570fcb5b do_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0x573d3855 mmput +EXPORT_SYMBOL_GPL vmlinux 0x577d8483 map_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x57879739 rpc_force_rebind +EXPORT_SYMBOL_GPL vmlinux 0x579caff2 device_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x579defb9 __rpc_wait_for_completion_task +EXPORT_SYMBOL_GPL vmlinux 0x579e0bf5 rtnl_unregister_all +EXPORT_SYMBOL_GPL vmlinux 0x58194bc8 unregister_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0x584c8064 invalidate_inode_pages2_range +EXPORT_SYMBOL_GPL vmlinux 0x587e8252 del_mtd_blktrans_dev +EXPORT_SYMBOL_GPL vmlinux 0x596a0d88 hrtimer_start +EXPORT_SYMBOL_GPL vmlinux 0x5971968d blk_end_bidi_request +EXPORT_SYMBOL_GPL vmlinux 0x597c6ae3 proc_net_fops_create +EXPORT_SYMBOL_GPL vmlinux 0x59ca3224 inet_twdr_twkill_work +EXPORT_SYMBOL_GPL vmlinux 0x5a4744b9 tcp_set_state +EXPORT_SYMBOL_GPL vmlinux 0x5a7bfe41 crypto_probing_notify +EXPORT_SYMBOL_GPL vmlinux 0x5a973a79 sdio_memcpy_toio +EXPORT_SYMBOL_GPL vmlinux 0x5b0e431c securityfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0x5b3a94cf tcp_slow_start +EXPORT_SYMBOL_GPL vmlinux 0x5bcaf1e3 scsi_execute_async +EXPORT_SYMBOL_GPL vmlinux 0x5bd26000 rpc_proc_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5bfc03c3 unregister_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5c58ffec klist_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x5cbec92a ata_ehi_clear_desc +EXPORT_SYMBOL_GPL vmlinux 0x5cc44f7e klist_add_head +EXPORT_SYMBOL_GPL vmlinux 0x5d0f6f57 kbd_table +EXPORT_SYMBOL_GPL vmlinux 0x5d4a4572 ktime_sub_ns +EXPORT_SYMBOL_GPL vmlinux 0x5d730e7b raw_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5d7e2f70 klist_add_tail +EXPORT_SYMBOL_GPL vmlinux 0x5dd67618 register_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5e014fcb xprt_release_xprt_cong +EXPORT_SYMBOL_GPL vmlinux 0x5ec79570 sdio_claim_irq +EXPORT_SYMBOL_GPL vmlinux 0x5f37efb5 crypto_larval_alloc +EXPORT_SYMBOL_GPL vmlinux 0x5f4ce8c7 blk_insert_cloned_request +EXPORT_SYMBOL_GPL vmlinux 0x5f99baef user_read +EXPORT_SYMBOL_GPL vmlinux 0x5faedc64 pci_unblock_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0x602c5ce6 ata_sas_port_init +EXPORT_SYMBOL_GPL vmlinux 0x607cfa6c inotify_inode_is_dead +EXPORT_SYMBOL_GPL vmlinux 0x6091797f synchronize_rcu +EXPORT_SYMBOL_GPL vmlinux 0x60a13e90 rcu_barrier +EXPORT_SYMBOL_GPL vmlinux 0x61c8ea20 raw_seq_start +EXPORT_SYMBOL_GPL vmlinux 0x6201c921 rpc_alloc_iostats +EXPORT_SYMBOL_GPL vmlinux 0x6210ee3c inet_csk_clone +EXPORT_SYMBOL_GPL vmlinux 0x6225b989 dev_attr_unload_heads +EXPORT_SYMBOL_GPL vmlinux 0x62282f8d page_mkclean +EXPORT_SYMBOL_GPL vmlinux 0x622b3e2c srcu_read_lock +EXPORT_SYMBOL_GPL vmlinux 0x6230bcef sysfs_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x62a4fa5e blk_abort_queue +EXPORT_SYMBOL_GPL vmlinux 0x62ae538f class_dev_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x62d85ae1 sysfs_get +EXPORT_SYMBOL_GPL vmlinux 0x6394e5f6 part_round_stats +EXPORT_SYMBOL_GPL vmlinux 0x639692f5 kset_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0x63ee7333 nlmsvc_unlock_all_by_sb +EXPORT_SYMBOL_GPL vmlinux 0x647b390b queue_work +EXPORT_SYMBOL_GPL vmlinux 0x64a38ee8 pci_scan_child_bus +EXPORT_SYMBOL_GPL vmlinux 0x651a95c2 rpc_proc_register +EXPORT_SYMBOL_GPL vmlinux 0x65ccb6f0 call_netevent_notifiers +EXPORT_SYMBOL_GPL vmlinux 0x661601de sprint_symbol +EXPORT_SYMBOL_GPL vmlinux 0x663483f4 ata_host_alloc +EXPORT_SYMBOL_GPL vmlinux 0x66496e8d ata_port_probe +EXPORT_SYMBOL_GPL vmlinux 0x6675e61f __rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x66b2a859 nr_free_buffer_pages +EXPORT_SYMBOL_GPL vmlinux 0x66cd8486 crypto_alloc_base +EXPORT_SYMBOL_GPL vmlinux 0x66cdfe56 device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x66d87d38 symbol_put_addr +EXPORT_SYMBOL_GPL vmlinux 0x6700e450 rpc_call_sync +EXPORT_SYMBOL_GPL vmlinux 0x67112138 pci_bus_max_busnr +EXPORT_SYMBOL_GPL vmlinux 0x672d5e8e bus_sort_breadthfirst +EXPORT_SYMBOL_GPL vmlinux 0x67d5d69e rpc_wake_up_queued_task +EXPORT_SYMBOL_GPL vmlinux 0x682579dc d_obtain_alias +EXPORT_SYMBOL_GPL vmlinux 0x68398b4d ata_port_abort +EXPORT_SYMBOL_GPL vmlinux 0x686c703f xfrm_count_auth_supported +EXPORT_SYMBOL_GPL vmlinux 0x68a80a66 sysfs_notify +EXPORT_SYMBOL_GPL vmlinux 0x68b4e42f svc_find_xprt +EXPORT_SYMBOL_GPL vmlinux 0x68e45681 sdio_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x6914847b ata_scsi_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0x693a52c1 scsi_eh_ready_devs +EXPORT_SYMBOL_GPL vmlinux 0x6952ff99 __ata_port_next_link +EXPORT_SYMBOL_GPL vmlinux 0x69da8d74 platform_device_register +EXPORT_SYMBOL_GPL vmlinux 0x69e9a2cb ata_scsi_slave_config +EXPORT_SYMBOL_GPL vmlinux 0x6a4115f2 inotify_add_watch +EXPORT_SYMBOL_GPL vmlinux 0x6a9f87c2 pci_renumber_slot +EXPORT_SYMBOL_GPL vmlinux 0x6ace9eb1 __crypto_alloc_tfm +EXPORT_SYMBOL_GPL vmlinux 0x6af566aa rpc_clone_client +EXPORT_SYMBOL_GPL vmlinux 0x6bc7aba4 sata_link_hardreset +EXPORT_SYMBOL_GPL vmlinux 0x6c07dfeb devres_remove +EXPORT_SYMBOL_GPL vmlinux 0x6c49c4f2 clockevents_notify +EXPORT_SYMBOL_GPL vmlinux 0x6c5304c5 rpcb_getport_sync +EXPORT_SYMBOL_GPL vmlinux 0x6ce878a8 transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x6d25c1f9 pci_enable_rom +EXPORT_SYMBOL_GPL vmlinux 0x6d2fc5a6 net_namespace_list +EXPORT_SYMBOL_GPL vmlinux 0x6d48195f pci_reset_function +EXPORT_SYMBOL_GPL vmlinux 0x6da4bcd7 init_user_ns +EXPORT_SYMBOL_GPL vmlinux 0x6db168f3 sdev_evt_send +EXPORT_SYMBOL_GPL vmlinux 0x6de3ee6e rpcauth_create +EXPORT_SYMBOL_GPL vmlinux 0x6e401a07 klist_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x6f84a3ce rpc_shutdown_client +EXPORT_SYMBOL_GPL vmlinux 0x6f959b35 locks_in_grace +EXPORT_SYMBOL_GPL vmlinux 0x6fcbc931 i2c_new_device +EXPORT_SYMBOL_GPL vmlinux 0x6ff5f866 __create_workqueue_key +EXPORT_SYMBOL_GPL vmlinux 0x702a0acb skb_to_sgvec +EXPORT_SYMBOL_GPL vmlinux 0x707776a6 xprt_update_rtt +EXPORT_SYMBOL_GPL vmlinux 0x707ff1bb ata_xfer_mask2mode +EXPORT_SYMBOL_GPL vmlinux 0x709b91d3 find_vpid +EXPORT_SYMBOL_GPL vmlinux 0x70a82d4c device_initialize +EXPORT_SYMBOL_GPL vmlinux 0x70ba7dcb fnotify_change +EXPORT_SYMBOL_GPL vmlinux 0x71196147 tcp_orphan_count +EXPORT_SYMBOL_GPL vmlinux 0x71d04dca tcp_reno_cong_avoid +EXPORT_SYMBOL_GPL vmlinux 0x71d1b61f device_create_vargs +EXPORT_SYMBOL_GPL vmlinux 0x723f49a8 register_net_sysctl_rotable +EXPORT_SYMBOL_GPL vmlinux 0x72462d2f user_destroy +EXPORT_SYMBOL_GPL vmlinux 0x7261e1ab i2c_new_probed_device +EXPORT_SYMBOL_GPL vmlinux 0x7278d328 all_vm_events +EXPORT_SYMBOL_GPL vmlinux 0x72a162b1 sata_scr_read +EXPORT_SYMBOL_GPL vmlinux 0x73b1f76d do_posix_clock_nosettime +EXPORT_SYMBOL_GPL vmlinux 0x743a165e ata_pack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0x7486289a init_uts_ns +EXPORT_SYMBOL_GPL vmlinux 0x74ca4962 net_assign_generic +EXPORT_SYMBOL_GPL vmlinux 0x74cbadaa sata_scr_valid +EXPORT_SYMBOL_GPL vmlinux 0x74d10b70 destroy_workqueue +EXPORT_SYMBOL_GPL vmlinux 0x7547dcf4 pci_find_ext_capability +EXPORT_SYMBOL_GPL vmlinux 0x75875169 input_class +EXPORT_SYMBOL_GPL vmlinux 0x759f4661 fs_kobj +EXPORT_SYMBOL_GPL vmlinux 0x75cab7ec ata_pio_need_iordy +EXPORT_SYMBOL_GPL vmlinux 0x75dc439b rt_mutex_trylock +EXPORT_SYMBOL_GPL vmlinux 0x7639623b inet_unhash +EXPORT_SYMBOL_GPL vmlinux 0x77140ac0 register_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0x77688642 rpc_lookup_cred +EXPORT_SYMBOL_GPL vmlinux 0x77ca6b4f queue_work_on +EXPORT_SYMBOL_GPL vmlinux 0x782725d4 sata_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x78af7c8f init_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x78f44e38 attribute_container_find_class_device +EXPORT_SYMBOL_GPL vmlinux 0x7948d109 srcu_read_unlock +EXPORT_SYMBOL_GPL vmlinux 0x79abafb7 proc_net_remove +EXPORT_SYMBOL_GPL vmlinux 0x7a23e90a svc_xprt_names +EXPORT_SYMBOL_GPL vmlinux 0x7a44f95a unregister_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0x7a69c869 ata_noop_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x7a82ef40 inotify_rm_watch +EXPORT_SYMBOL_GPL vmlinux 0x7ac7fc44 blk_rq_cur_bytes +EXPORT_SYMBOL_GPL vmlinux 0x7ae4823d class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x7af93c44 i2c_unregister_device +EXPORT_SYMBOL_GPL vmlinux 0x7b13cb35 generic_drop_inode +EXPORT_SYMBOL_GPL vmlinux 0x7b3d39f9 raw_seq_stop +EXPORT_SYMBOL_GPL vmlinux 0x7b5f1d61 sysfs_update_group +EXPORT_SYMBOL_GPL vmlinux 0x7b6dc8d3 tcp_done +EXPORT_SYMBOL_GPL vmlinux 0x7b95ee26 register_posix_clock +EXPORT_SYMBOL_GPL vmlinux 0x7be1ad5a skb_icv_walk +EXPORT_SYMBOL_GPL vmlinux 0x7c1de9b6 vfs_test_lock +EXPORT_SYMBOL_GPL vmlinux 0x7c51e998 rpc_call_null +EXPORT_SYMBOL_GPL vmlinux 0x7c6784ef ktime_get_real +EXPORT_SYMBOL_GPL vmlinux 0x7cc09f26 ata_link_online +EXPORT_SYMBOL_GPL vmlinux 0x7cd5a542 user_describe +EXPORT_SYMBOL_GPL vmlinux 0x7ce249db transport_remove_device +EXPORT_SYMBOL_GPL vmlinux 0x7d7a1e5b ata_sas_port_alloc +EXPORT_SYMBOL_GPL vmlinux 0x7de53067 rpc_init_rtt +EXPORT_SYMBOL_GPL vmlinux 0x7e06b214 apply_to_page_range +EXPORT_SYMBOL_GPL vmlinux 0x7e275ea8 scsi_complete_async_scans +EXPORT_SYMBOL_GPL vmlinux 0x7e97a705 sysfs_remove_group +EXPORT_SYMBOL_GPL vmlinux 0x7f3c49d1 rpcauth_generic_bind_cred +EXPORT_SYMBOL_GPL vmlinux 0x7fefe988 pci_set_pcie_reset_state +EXPORT_SYMBOL_GPL vmlinux 0x7ff10ccf raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x80165ff9 pci_test_config_bits +EXPORT_SYMBOL_GPL vmlinux 0x805db29f md_allow_write +EXPORT_SYMBOL_GPL vmlinux 0x80aca7d7 add_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0x80ad4085 del_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0x80dfe5a5 crypto_shoot_alg +EXPORT_SYMBOL_GPL vmlinux 0x8162e45b alloc_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x818fcf9b elv_unregister +EXPORT_SYMBOL_GPL vmlinux 0x81e928a8 crypto_larval_kill +EXPORT_SYMBOL_GPL vmlinux 0x82088e26 tcp_init_congestion_ops +EXPORT_SYMBOL_GPL vmlinux 0x826360fd do_posix_clock_nonanosleep +EXPORT_SYMBOL_GPL vmlinux 0x82d79b51 sysctl_vfs_cache_pressure +EXPORT_SYMBOL_GPL vmlinux 0x82e5b815 ata_dummy_port_info +EXPORT_SYMBOL_GPL vmlinux 0x8309df16 put_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0x830ada37 svc_create_xprt +EXPORT_SYMBOL_GPL vmlinux 0x8321c333 __mmdrop +EXPORT_SYMBOL_GPL vmlinux 0x836d2cc9 __blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x83b56f6d deregister_mtd_parser +EXPORT_SYMBOL_GPL vmlinux 0x840a5be7 tty_buffer_request_room +EXPORT_SYMBOL_GPL vmlinux 0x8412e3c5 srcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x843ee603 kill_mtd_super +EXPORT_SYMBOL_GPL vmlinux 0x8449318b schedule_hrtimeout +EXPORT_SYMBOL_GPL vmlinux 0x844accd2 tty_ldisc_deref +EXPORT_SYMBOL_GPL vmlinux 0x847a0bd5 driver_attach +EXPORT_SYMBOL_GPL vmlinux 0x84e6890f sdio_set_block_size +EXPORT_SYMBOL_GPL vmlinux 0x85c10896 rcu_batches_completed_bh +EXPORT_SYMBOL_GPL vmlinux 0x85e5a3db ktime_get_ts +EXPORT_SYMBOL_GPL vmlinux 0x85e695fd xprt_unregister_transport +EXPORT_SYMBOL_GPL vmlinux 0x861afb9c vfs_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0x863ddba6 inotify_rm_wd +EXPORT_SYMBOL_GPL vmlinux 0x868784cb __symbol_get +EXPORT_SYMBOL_GPL vmlinux 0x86988ba2 register_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0x86e03eed input_ff_create +EXPORT_SYMBOL_GPL vmlinux 0x87754115 raw_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x8821508e driver_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x885accbf invalidate_inode_pages2 +EXPORT_SYMBOL_GPL vmlinux 0x88dfbdfe __class_register +EXPORT_SYMBOL_GPL vmlinux 0x89329bb9 seq_release_net +EXPORT_SYMBOL_GPL vmlinux 0x8953162b inet_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0x895a6c94 register_mtd_parser +EXPORT_SYMBOL_GPL vmlinux 0x899c875d raw_unhash_sk +EXPORT_SYMBOL_GPL vmlinux 0x89c6d380 tty_prepare_flip_string_flags +EXPORT_SYMBOL_GPL vmlinux 0x89d1f75e sata_std_hardreset +EXPORT_SYMBOL_GPL vmlinux 0x89f9469c device_move +EXPORT_SYMBOL_GPL vmlinux 0x8a1cc456 kobject_uevent_env +EXPORT_SYMBOL_GPL vmlinux 0x8a427508 sata_link_resume +EXPORT_SYMBOL_GPL vmlinux 0x8a518d72 default_mtd_writev +EXPORT_SYMBOL_GPL vmlinux 0x8a95326a kmem_cache_name +EXPORT_SYMBOL_GPL vmlinux 0x8aa7c938 input_ff_upload +EXPORT_SYMBOL_GPL vmlinux 0x8abed13d xfrm_aead_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x8ae356a1 sysdev_class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x8b178231 sysdev_store_ulong +EXPORT_SYMBOL_GPL vmlinux 0x8b752ac1 ata_tf_to_fis +EXPORT_SYMBOL_GPL vmlinux 0x8b8cb2d6 queue_delayed_work +EXPORT_SYMBOL_GPL vmlinux 0x8c02c802 class_dev_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x8c1b9e83 sysdev_show_int +EXPORT_SYMBOL_GPL vmlinux 0x8c9e171c rpcauth_register +EXPORT_SYMBOL_GPL vmlinux 0x8cf0f826 rpc_wake_up_next +EXPORT_SYMBOL_GPL vmlinux 0x8cf10067 tty_ldisc_ref_wait +EXPORT_SYMBOL_GPL vmlinux 0x8d5ac0fb ata_std_qc_defer +EXPORT_SYMBOL_GPL vmlinux 0x8d771dce platform_get_resource_byname +EXPORT_SYMBOL_GPL vmlinux 0x8d8718e1 get_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0x8db4a6d0 svc_addsock +EXPORT_SYMBOL_GPL vmlinux 0x8df6273f devm_kzalloc +EXPORT_SYMBOL_GPL vmlinux 0x8e04b9f2 tty_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x8ec2e3db ata_pci_device_resume +EXPORT_SYMBOL_GPL vmlinux 0x8ef446c8 skb_pull_rcsum +EXPORT_SYMBOL_GPL vmlinux 0x8f508498 inotify_find_update_watch +EXPORT_SYMBOL_GPL vmlinux 0x8f6cee77 __round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x8f9a13fd anon_transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x8fdd287a rtc_irq_register +EXPORT_SYMBOL_GPL vmlinux 0x90197153 exportfs_encode_fh +EXPORT_SYMBOL_GPL vmlinux 0x9075dd20 inotify_dentry_parent_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x90a1004a crypto_has_alg +EXPORT_SYMBOL_GPL vmlinux 0x90bdbe79 platform_driver_probe +EXPORT_SYMBOL_GPL vmlinux 0x90e24df5 simple_attr_write +EXPORT_SYMBOL_GPL vmlinux 0x90e7ee95 sync_page_io +EXPORT_SYMBOL_GPL vmlinux 0x910416e1 devres_destroy +EXPORT_SYMBOL_GPL vmlinux 0x914b7f6b ata_link_offline +EXPORT_SYMBOL_GPL vmlinux 0x918d6b05 sysdev_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x9204cd47 get_sb_mtd +EXPORT_SYMBOL_GPL vmlinux 0x92445aee hrtimer_get_res +EXPORT_SYMBOL_GPL vmlinux 0x927fe3e5 devres_find +EXPORT_SYMBOL_GPL vmlinux 0x92d7b66b rpc_exit_task +EXPORT_SYMBOL_GPL vmlinux 0x935c5013 blk_update_request +EXPORT_SYMBOL_GPL vmlinux 0x9364e11d inverse_translate +EXPORT_SYMBOL_GPL vmlinux 0x93d19324 ata_host_register +EXPORT_SYMBOL_GPL vmlinux 0x93d2422d snmp_mib_free +EXPORT_SYMBOL_GPL vmlinux 0x93edc8c5 inet_twsk_put +EXPORT_SYMBOL_GPL vmlinux 0x943aba53 sysdev_register +EXPORT_SYMBOL_GPL vmlinux 0x947918e4 __inet_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0x94a59a7b crypto_alg_lookup +EXPORT_SYMBOL_GPL vmlinux 0x94a68723 ata_scsi_slave_destroy +EXPORT_SYMBOL_GPL vmlinux 0x94dc62d2 ata_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x950020e1 file_ra_state_init +EXPORT_SYMBOL_GPL vmlinux 0x95026bd4 inet_csk_listen_stop +EXPORT_SYMBOL_GPL vmlinux 0x9523eca6 blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0x952664c5 do_exit +EXPORT_SYMBOL_GPL vmlinux 0x959c7945 tty_perform_flush +EXPORT_SYMBOL_GPL vmlinux 0x96877ac4 locks_start_grace +EXPORT_SYMBOL_GPL vmlinux 0x96c11073 platform_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0x96cbcf31 pm_qos_add_notifier +EXPORT_SYMBOL_GPL vmlinux 0x972eb49c attribute_container_register +EXPORT_SYMBOL_GPL vmlinux 0x975a19a9 register_mtd_user +EXPORT_SYMBOL_GPL vmlinux 0x97cb5797 ata_port_disable +EXPORT_SYMBOL_GPL vmlinux 0x97d615f1 audit_log_untrustedstring +EXPORT_SYMBOL_GPL vmlinux 0x97d7bfa3 sysdev_store_int +EXPORT_SYMBOL_GPL vmlinux 0x97d94c37 skb_segment +EXPORT_SYMBOL_GPL vmlinux 0x97dcf46e tcp_twsk_unique +EXPORT_SYMBOL_GPL vmlinux 0x98196f5b blocking_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x9889c190 queue_delayed_work_on +EXPORT_SYMBOL_GPL vmlinux 0x98f0833e put_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0x999f7bcb put_driver +EXPORT_SYMBOL_GPL vmlinux 0x99ac3b8f unregister_mtd_user +EXPORT_SYMBOL_GPL vmlinux 0x9a351a75 i2c_add_numbered_adapter +EXPORT_SYMBOL_GPL vmlinux 0x9a398f5c xfrm_ealg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x9a9187d7 anon_transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x9b3123ae kobject_rename +EXPORT_SYMBOL_GPL vmlinux 0x9b38db49 device_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x9ba0501e unregister_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0x9cb8037b xfrm_count_enc_supported +EXPORT_SYMBOL_GPL vmlinux 0x9d05ffbd crypto_alg_sem +EXPORT_SYMBOL_GPL vmlinux 0x9dafa0af sysfs_schedule_callback +EXPORT_SYMBOL_GPL vmlinux 0x9dd50668 ip_build_and_send_pkt +EXPORT_SYMBOL_GPL vmlinux 0x9e711ad2 pm_qos_requirement +EXPORT_SYMBOL_GPL vmlinux 0x9e92462c ata_sas_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0x9ec3879f copy_fs_struct +EXPORT_SYMBOL_GPL vmlinux 0x9edb45c4 devres_get +EXPORT_SYMBOL_GPL vmlinux 0x9f47ae0b ata_sas_slave_configure +EXPORT_SYMBOL_GPL vmlinux 0x9fab20b9 kobject_get_path +EXPORT_SYMBOL_GPL vmlinux 0x9faec38d rpcb_getport_async +EXPORT_SYMBOL_GPL vmlinux 0x9fce80db fb_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xa00b88c6 platform_driver_register +EXPORT_SYMBOL_GPL vmlinux 0xa0109e93 __inet_twsk_hashdance +EXPORT_SYMBOL_GPL vmlinux 0xa0255440 net_ipv4_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0xa073f683 inet_csk_get_port +EXPORT_SYMBOL_GPL vmlinux 0xa07b50b9 rpc_sleep_on +EXPORT_SYMBOL_GPL vmlinux 0xa0a2cb22 device_destroy +EXPORT_SYMBOL_GPL vmlinux 0xa0c71dac spi_populate_sync_msg +EXPORT_SYMBOL_GPL vmlinux 0xa1471ecd find_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0xa14b6a94 tcp_death_row +EXPORT_SYMBOL_GPL vmlinux 0xa351b13f cfi_cmdset_0200 +EXPORT_SYMBOL_GPL vmlinux 0xa3a4800e unregister_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0xa3fa379c xfrm_inner_extract_output +EXPORT_SYMBOL_GPL vmlinux 0xa4500897 ata_port_desc +EXPORT_SYMBOL_GPL vmlinux 0xa4f09479 arm_pm_restart +EXPORT_SYMBOL_GPL vmlinux 0xa4f66874 sdio_writesb +EXPORT_SYMBOL_GPL vmlinux 0xa57afc74 ktime_get +EXPORT_SYMBOL_GPL vmlinux 0xa591da34 rt_mutex_unlock +EXPORT_SYMBOL_GPL vmlinux 0xa5bf5c3e pm_qos_add_requirement +EXPORT_SYMBOL_GPL vmlinux 0xa5c36cec inotify_unmount_inodes +EXPORT_SYMBOL_GPL vmlinux 0xa65f9329 raw_seq_next +EXPORT_SYMBOL_GPL vmlinux 0xa678fd57 rpc_put_task +EXPORT_SYMBOL_GPL vmlinux 0xa6b92a1d tty_wakeup +EXPORT_SYMBOL_GPL vmlinux 0xa6d99ba3 bus_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0xa70615ac deregister_mtd_blktrans +EXPORT_SYMBOL_GPL vmlinux 0xa709a60a svc_xprt_enqueue +EXPORT_SYMBOL_GPL vmlinux 0xa743edec mnt_want_write +EXPORT_SYMBOL_GPL vmlinux 0xa7699e22 svc_max_payload +EXPORT_SYMBOL_GPL vmlinux 0xa7fe30aa crypto_mod_put +EXPORT_SYMBOL_GPL vmlinux 0xa812a2ee tcp_unregister_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0xa824286b kern_mount_data +EXPORT_SYMBOL_GPL vmlinux 0xa84bc439 rpc_bind_new_program +EXPORT_SYMBOL_GPL vmlinux 0xa8c46d71 ata_host_suspend +EXPORT_SYMBOL_GPL vmlinux 0xa8e7f03e screen_glyph +EXPORT_SYMBOL_GPL vmlinux 0xa919ac8a svc_xprt_copy_addrs +EXPORT_SYMBOL_GPL vmlinux 0xa937a7c8 raw_hash_sk +EXPORT_SYMBOL_GPL vmlinux 0xa9c530b8 unregister_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xa9ed0d9e device_register +EXPORT_SYMBOL_GPL vmlinux 0xaa16868c rtnl_put_cacheinfo +EXPORT_SYMBOL_GPL vmlinux 0xaa1f760d devres_remove_group +EXPORT_SYMBOL_GPL vmlinux 0xaa2a72bf __iowrite64_copy +EXPORT_SYMBOL_GPL vmlinux 0xaa58a126 inet_csk_listen_start +EXPORT_SYMBOL_GPL vmlinux 0xaa8c4696 cpu_clock +EXPORT_SYMBOL_GPL vmlinux 0xaaa13376 nlmclnt_init +EXPORT_SYMBOL_GPL vmlinux 0xab10895a driver_add_kobj +EXPORT_SYMBOL_GPL vmlinux 0xab1e3767 blkdev_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xab7c31f2 scsi_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0xabeada74 xprt_release_xprt +EXPORT_SYMBOL_GPL vmlinux 0xac46a91e xfrm_output +EXPORT_SYMBOL_GPL vmlinux 0xac5464ff inet_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0xadbb2197 klist_add_after +EXPORT_SYMBOL_GPL vmlinux 0xadfb79b0 xprt_wait_for_buffer_space +EXPORT_SYMBOL_GPL vmlinux 0xae0c87ee pm_qos_remove_notifier +EXPORT_SYMBOL_GPL vmlinux 0xae0f1b53 rtc_set_alarm +EXPORT_SYMBOL_GPL vmlinux 0xae35d363 platform_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xae42f73c inet_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0xae4b0933 raw_seq_open +EXPORT_SYMBOL_GPL vmlinux 0xae871167 platform_device_alloc +EXPORT_SYMBOL_GPL vmlinux 0xaee006f5 sdio_writew +EXPORT_SYMBOL_GPL vmlinux 0xaee57723 rtc_irq_set_state +EXPORT_SYMBOL_GPL vmlinux 0xaf5bf6ef nfs_debug +EXPORT_SYMBOL_GPL vmlinux 0xaf7af870 ata_dev_pair +EXPORT_SYMBOL_GPL vmlinux 0xaf8a7a53 ata_base_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xaf8f2eeb sysdev_driver_register +EXPORT_SYMBOL_GPL vmlinux 0xafaf8133 sata_set_spd +EXPORT_SYMBOL_GPL vmlinux 0xafe2cda1 rtc_class_open +EXPORT_SYMBOL_GPL vmlinux 0xb02faa9a __inet_lookup_established +EXPORT_SYMBOL_GPL vmlinux 0xb05564f7 sdio_f0_readb +EXPORT_SYMBOL_GPL vmlinux 0xb0b874f4 security_inode_permission +EXPORT_SYMBOL_GPL vmlinux 0xb1930784 attribute_container_unregister +EXPORT_SYMBOL_GPL vmlinux 0xb1acbcce rcu_barrier_sched +EXPORT_SYMBOL_GPL vmlinux 0xb1fafc73 blk_rq_check_limits +EXPORT_SYMBOL_GPL vmlinux 0xb2a2d3ab rt_mutex_lock +EXPORT_SYMBOL_GPL vmlinux 0xb449ed11 mtd_table_mutex +EXPORT_SYMBOL_GPL vmlinux 0xb4834eb2 mnt_drop_write +EXPORT_SYMBOL_GPL vmlinux 0xb4a4b9fb blocking_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0xb4eec3df generic_sync_sb_inodes +EXPORT_SYMBOL_GPL vmlinux 0xb4efa8d6 ata_pci_device_do_suspend +EXPORT_SYMBOL_GPL vmlinux 0xb4f1452b ata_std_error_handler +EXPORT_SYMBOL_GPL vmlinux 0xb51eb0b8 generic_fh_to_dentry +EXPORT_SYMBOL_GPL vmlinux 0xb6232466 cfi_qry_mode_off +EXPORT_SYMBOL_GPL vmlinux 0xb6245f22 devres_alloc +EXPORT_SYMBOL_GPL vmlinux 0xb624a601 i2c_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xb6aeb661 ata_id_c_string +EXPORT_SYMBOL_GPL vmlinux 0xb72c489b __scsi_get_command +EXPORT_SYMBOL_GPL vmlinux 0xb73033d7 rpc_create +EXPORT_SYMBOL_GPL vmlinux 0xb806c933 alloc_page_buffers +EXPORT_SYMBOL_GPL vmlinux 0xb808b787 sdev_evt_send_simple +EXPORT_SYMBOL_GPL vmlinux 0xb87332ce device_del +EXPORT_SYMBOL_GPL vmlinux 0xb8759c2c srcu_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0xb8a44263 xprt_adjust_cwnd +EXPORT_SYMBOL_GPL vmlinux 0xb8ee30b5 ata_std_postreset +EXPORT_SYMBOL_GPL vmlinux 0xb8fee532 blocking_notifier_chain_cond_register +EXPORT_SYMBOL_GPL vmlinux 0xb9852601 get_device +EXPORT_SYMBOL_GPL vmlinux 0xb995edca ata_cable_unknown +EXPORT_SYMBOL_GPL vmlinux 0xb9e573b2 sk_clone +EXPORT_SYMBOL_GPL vmlinux 0xb9eb3aa9 add_uevent_var +EXPORT_SYMBOL_GPL vmlinux 0xba04b3c9 ata_host_detach +EXPORT_SYMBOL_GPL vmlinux 0xba96d571 sata_scr_write +EXPORT_SYMBOL_GPL vmlinux 0xbaeb5db6 securityfs_remove +EXPORT_SYMBOL_GPL vmlinux 0xbaf09ec0 klist_del +EXPORT_SYMBOL_GPL vmlinux 0xbb0e4490 get_task_mm +EXPORT_SYMBOL_GPL vmlinux 0xbb29cb59 input_ff_event +EXPORT_SYMBOL_GPL vmlinux 0xbb578578 hrtimer_cancel +EXPORT_SYMBOL_GPL vmlinux 0xbb71f66d sysfs_chmod_file +EXPORT_SYMBOL_GPL vmlinux 0xbb9a2c75 ktime_add_ns +EXPORT_SYMBOL_GPL vmlinux 0xbbb1fcaf xprt_reserve_xprt_cong +EXPORT_SYMBOL_GPL vmlinux 0xbc1a2562 sock_prot_inuse_get +EXPORT_SYMBOL_GPL vmlinux 0xbc1b658b single_open_net +EXPORT_SYMBOL_GPL vmlinux 0xbc94b195 __inet_hash_nolisten +EXPORT_SYMBOL_GPL vmlinux 0xbccdb99c ip_route_output_flow +EXPORT_SYMBOL_GPL vmlinux 0xbcdf3084 pci_disable_rom +EXPORT_SYMBOL_GPL vmlinux 0xbd0ec0cd md_new_event +EXPORT_SYMBOL_GPL vmlinux 0xbe1887e4 ata_unpack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xbeea7a2b srcu_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0xbf9d1b96 nfsd_debug +EXPORT_SYMBOL_GPL vmlinux 0xc028fccf sock_prot_inuse_add +EXPORT_SYMBOL_GPL vmlinux 0xc05e7cbf bus_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0xc06e8780 xattr_getsecurity +EXPORT_SYMBOL_GPL vmlinux 0xc0d939a3 flush_workqueue +EXPORT_SYMBOL_GPL vmlinux 0xc12435e3 rpc_calc_rto +EXPORT_SYMBOL_GPL vmlinux 0xc1b825df ata_port_start +EXPORT_SYMBOL_GPL vmlinux 0xc1fa312b sysdev_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc20f4939 dm_disk +EXPORT_SYMBOL_GPL vmlinux 0xc2268b75 inotify_init_watch +EXPORT_SYMBOL_GPL vmlinux 0xc22a3091 vm_unmap_aliases +EXPORT_SYMBOL_GPL vmlinux 0xc34efe27 snmp_fold_field +EXPORT_SYMBOL_GPL vmlinux 0xc35041ac rpcauth_destroy_credcache +EXPORT_SYMBOL_GPL vmlinux 0xc37eac52 kobject_uevent +EXPORT_SYMBOL_GPL vmlinux 0xc397e00f class_interface_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc3b5ac61 ip_local_out +EXPORT_SYMBOL_GPL vmlinux 0xc428068d sata_deb_timing_long +EXPORT_SYMBOL_GPL vmlinux 0xc48b7ccf ata_mode_string +EXPORT_SYMBOL_GPL vmlinux 0xc61bf554 driver_register +EXPORT_SYMBOL_GPL vmlinux 0xc64b28f3 sysfs_put +EXPORT_SYMBOL_GPL vmlinux 0xc673e23e ata_scsi_change_queue_depth +EXPORT_SYMBOL_GPL vmlinux 0xc6b4d837 ata_pci_device_do_resume +EXPORT_SYMBOL_GPL vmlinux 0xc6e045dd get_driver +EXPORT_SYMBOL_GPL vmlinux 0xc7051e29 single_release_net +EXPORT_SYMBOL_GPL vmlinux 0xc8003119 __rt_mutex_init +EXPORT_SYMBOL_GPL vmlinux 0xc8528522 kobject_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0xc86dc291 mtd_table +EXPORT_SYMBOL_GPL vmlinux 0xc875c53a firmware_kobj +EXPORT_SYMBOL_GPL vmlinux 0xc9318c52 sysdev_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc9561772 fb_destroy_modelist +EXPORT_SYMBOL_GPL vmlinux 0xc9f68800 class_create_file +EXPORT_SYMBOL_GPL vmlinux 0xca1fd8a4 platform_device_add_resources +EXPORT_SYMBOL_GPL vmlinux 0xca445a9d register_mtd_blktrans +EXPORT_SYMBOL_GPL vmlinux 0xcab38525 kobject_init_and_add +EXPORT_SYMBOL_GPL vmlinux 0xcb0c2ebf __srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xcb6800e6 bus_get_device_klist +EXPORT_SYMBOL_GPL vmlinux 0xcb8c568a scsi_queue_work +EXPORT_SYMBOL_GPL vmlinux 0xcbfdb4af ata_do_dev_read_id +EXPORT_SYMBOL_GPL vmlinux 0xcc1f1c3d inet_twdr_hangman +EXPORT_SYMBOL_GPL vmlinux 0xcc795d11 ata_port_freeze +EXPORT_SYMBOL_GPL vmlinux 0xcca0c0c8 schedule_hrtimeout_range +EXPORT_SYMBOL_GPL vmlinux 0xcccecba3 device_rename +EXPORT_SYMBOL_GPL vmlinux 0xcccfb2fa sata_deb_timing_hotplug +EXPORT_SYMBOL_GPL vmlinux 0xcd008c47 platform_get_resource +EXPORT_SYMBOL_GPL vmlinux 0xcd2c3b66 put_pid +EXPORT_SYMBOL_GPL vmlinux 0xcd39eff5 rpc_call_async +EXPORT_SYMBOL_GPL vmlinux 0xcd519809 pci_intx +EXPORT_SYMBOL_GPL vmlinux 0xcda08dfd inet_twsk_schedule +EXPORT_SYMBOL_GPL vmlinux 0xcda32a94 klist_remove +EXPORT_SYMBOL_GPL vmlinux 0xcdb3cff0 klist_iter_init_node +EXPORT_SYMBOL_GPL vmlinux 0xcdca3691 nr_irqs +EXPORT_SYMBOL_GPL vmlinux 0xce283ee9 uhci_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0xce2d66ed nlmclnt_proc +EXPORT_SYMBOL_GPL vmlinux 0xce382f3a skb_morph +EXPORT_SYMBOL_GPL vmlinux 0xce6cd8a9 rtc_read_alarm +EXPORT_SYMBOL_GPL vmlinux 0xcf026416 rtc_irq_set_freq +EXPORT_SYMBOL_GPL vmlinux 0xcf31d115 blk_queue_rq_timed_out +EXPORT_SYMBOL_GPL vmlinux 0xcf399e45 audit_log_vformat +EXPORT_SYMBOL_GPL vmlinux 0xcf5289a1 rpcauth_lookup_credcache +EXPORT_SYMBOL_GPL vmlinux 0xcf7bb156 hrtimer_init +EXPORT_SYMBOL_GPL vmlinux 0xcf7ec2de vfs_setlease +EXPORT_SYMBOL_GPL vmlinux 0xcfcc83ad register_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0xcffa2aff spi_populate_width_msg +EXPORT_SYMBOL_GPL vmlinux 0xd03c7700 secure_ipv4_port_ephemeral +EXPORT_SYMBOL_GPL vmlinux 0xd0417198 get_current_tty +EXPORT_SYMBOL_GPL vmlinux 0xd0699057 seq_open_net +EXPORT_SYMBOL_GPL vmlinux 0xd06a7396 transport_setup_device +EXPORT_SYMBOL_GPL vmlinux 0xd0c05159 emergency_restart +EXPORT_SYMBOL_GPL vmlinux 0xd17d45b6 class_interface_register +EXPORT_SYMBOL_GPL vmlinux 0xd1922d49 rtnl_kill_links +EXPORT_SYMBOL_GPL vmlinux 0xd195c228 zap_vma_ptes +EXPORT_SYMBOL_GPL vmlinux 0xd1dfd9ec cfi_cmdset_0003 +EXPORT_SYMBOL_GPL vmlinux 0xd1fa48de pci_find_next_capability +EXPORT_SYMBOL_GPL vmlinux 0xd257b3fc tty_prepare_flip_string +EXPORT_SYMBOL_GPL vmlinux 0xd273b1b1 __round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xd2b0a0a4 simple_attr_release +EXPORT_SYMBOL_GPL vmlinux 0xd2d6afe6 __blkdev_driver_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xd316db11 ata_dummy_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xd353fddb sdio_readb +EXPORT_SYMBOL_GPL vmlinux 0xd465dd63 sdio_memcpy_fromio +EXPORT_SYMBOL_GPL vmlinux 0xd528deec inet_twsk_alloc +EXPORT_SYMBOL_GPL vmlinux 0xd56a0e95 pci_slots_kset +EXPORT_SYMBOL_GPL vmlinux 0xd69a92d8 platform_device_add_data +EXPORT_SYMBOL_GPL vmlinux 0xd6f36bf9 dm_set_device_limits +EXPORT_SYMBOL_GPL vmlinux 0xd6f9fb62 register_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0xd741cfcf blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xd78f1f98 rpc_peeraddr2str +EXPORT_SYMBOL_GPL vmlinux 0xd84cd7f4 ata_timing_find_mode +EXPORT_SYMBOL_GPL vmlinux 0xd8ddcd07 get_user_pages_fast +EXPORT_SYMBOL_GPL vmlinux 0xd9278a86 cfi_qry_present +EXPORT_SYMBOL_GPL vmlinux 0xda18b9af xfrm_output_resume +EXPORT_SYMBOL_GPL vmlinux 0xda60f031 __inet_inherit_port +EXPORT_SYMBOL_GPL vmlinux 0xdaf4dfb3 fb_mode_option +EXPORT_SYMBOL_GPL vmlinux 0xdb24b2db page_cache_sync_readahead +EXPORT_SYMBOL_GPL vmlinux 0xdb49a78f anon_inode_getfd +EXPORT_SYMBOL_GPL vmlinux 0xdb9a700f devres_add +EXPORT_SYMBOL_GPL vmlinux 0xdbb29042 user_update +EXPORT_SYMBOL_GPL vmlinux 0xdc4075fb device_create +EXPORT_SYMBOL_GPL vmlinux 0xdd400eb6 devres_close_group +EXPORT_SYMBOL_GPL vmlinux 0xddafa0e4 dm_noflush_suspending +EXPORT_SYMBOL_GPL vmlinux 0xdde303ef parse_mtd_partitions +EXPORT_SYMBOL_GPL vmlinux 0xde45aaa1 scsi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xdedc025a svc_xprt_put +EXPORT_SYMBOL_GPL vmlinux 0xdefb2721 driver_create_file +EXPORT_SYMBOL_GPL vmlinux 0xdf10d5f9 ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0xdf1a5f11 device_attach +EXPORT_SYMBOL_GPL vmlinux 0xdf424c32 class_find_device +EXPORT_SYMBOL_GPL vmlinux 0xe01c07cd rpc_malloc +EXPORT_SYMBOL_GPL vmlinux 0xe0531f21 device_create_file +EXPORT_SYMBOL_GPL vmlinux 0xe1c4dbf2 ata_sas_port_destroy +EXPORT_SYMBOL_GPL vmlinux 0xe1c85a51 ata_do_eh +EXPORT_SYMBOL_GPL vmlinux 0xe303a57b rpcauth_unregister +EXPORT_SYMBOL_GPL vmlinux 0xe343f886 rpc_run_task +EXPORT_SYMBOL_GPL vmlinux 0xe3f84854 __ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0xe4480a09 uart_console_write +EXPORT_SYMBOL_GPL vmlinux 0xe48f7b80 device_release_driver +EXPORT_SYMBOL_GPL vmlinux 0xe49ff3b0 ata_wait_register +EXPORT_SYMBOL_GPL vmlinux 0xe4d21adb ata_scsi_simulate +EXPORT_SYMBOL_GPL vmlinux 0xe4e0c65a mm_kobj +EXPORT_SYMBOL_GPL vmlinux 0xe4eb4497 rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0xe527052a kill_pid_info_as_uid +EXPORT_SYMBOL_GPL vmlinux 0xe530071c pm_qos_remove_requirement +EXPORT_SYMBOL_GPL vmlinux 0xe65e36e2 vfs_removexattr +EXPORT_SYMBOL_GPL vmlinux 0xe781cdf2 device_add +EXPORT_SYMBOL_GPL vmlinux 0xe9149f36 input_ff_erase +EXPORT_SYMBOL_GPL vmlinux 0xe93e49c3 devres_free +EXPORT_SYMBOL_GPL vmlinux 0xe94dd0d8 tty_ldisc_flush +EXPORT_SYMBOL_GPL vmlinux 0xe95990f3 tcp_reno_ssthresh +EXPORT_SYMBOL_GPL vmlinux 0xe9b78a2a sysfs_create_link +EXPORT_SYMBOL_GPL vmlinux 0xe9e00baa ata_sas_port_stop +EXPORT_SYMBOL_GPL vmlinux 0xea0b674e ata_dev_disable +EXPORT_SYMBOL_GPL vmlinux 0xea418e0f atapi_cmd_type +EXPORT_SYMBOL_GPL vmlinux 0xea62c60c hrtimer_get_remaining +EXPORT_SYMBOL_GPL vmlinux 0xeaa0a810 driver_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0xebb672a3 ata_timing_compute +EXPORT_SYMBOL_GPL vmlinux 0xebfb6cd1 exportfs_decode_fh +EXPORT_SYMBOL_GPL vmlinux 0xec6a3c6f rpc_lookup_machine_cred +EXPORT_SYMBOL_GPL vmlinux 0xec6a4735 rt_mutex_lock_interruptible +EXPORT_SYMBOL_GPL vmlinux 0xecec38c7 ata_sas_port_start +EXPORT_SYMBOL_GPL vmlinux 0xed10df4f tty_get_pgrp +EXPORT_SYMBOL_GPL vmlinux 0xed8ec1f7 __blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0xee32a7d2 shmem_file_setup +EXPORT_SYMBOL_GPL vmlinux 0xeeacab69 rpc_update_rtt +EXPORT_SYMBOL_GPL vmlinux 0xef233ba3 rpc_destroy_wait_queue +EXPORT_SYMBOL_GPL vmlinux 0xef4e963e __atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xef6c3f70 round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xef82fdba srcu_init_notifier_head +EXPORT_SYMBOL_GPL vmlinux 0xef8eb28f ata_std_prereset +EXPORT_SYMBOL_GPL vmlinux 0xefe21106 snmp_mib_init +EXPORT_SYMBOL_GPL vmlinux 0xf013103f nlmclnt_done +EXPORT_SYMBOL_GPL vmlinux 0xf0727b4c transport_add_device +EXPORT_SYMBOL_GPL vmlinux 0xf07e1e46 platform_device_register_simple +EXPORT_SYMBOL_GPL vmlinux 0xf0d5dadf bus_get_kset +EXPORT_SYMBOL_GPL vmlinux 0xf0dababa skb_cow_data +EXPORT_SYMBOL_GPL vmlinux 0xf0f92ab8 unregister_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0xf1463412 execute_in_process_context +EXPORT_SYMBOL_GPL vmlinux 0xf184d189 kernel_power_off +EXPORT_SYMBOL_GPL vmlinux 0xf218a4c8 i2c_new_dummy +EXPORT_SYMBOL_GPL vmlinux 0xf247055a get_mtd_device_nm +EXPORT_SYMBOL_GPL vmlinux 0xf282aec3 svc_xprt_init +EXPORT_SYMBOL_GPL vmlinux 0xf28883cd csum_partial_copy_to_xdr +EXPORT_SYMBOL_GPL vmlinux 0xf2c7510b device_for_each_child +EXPORT_SYMBOL_GPL vmlinux 0xf2fca922 uart_parse_options +EXPORT_SYMBOL_GPL vmlinux 0xf3737fcc dev_attr_sw_activity +EXPORT_SYMBOL_GPL vmlinux 0xf39a4334 sdio_enable_func +EXPORT_SYMBOL_GPL vmlinux 0xf3d5cc13 ata_timing_merge +EXPORT_SYMBOL_GPL vmlinux 0xf43041a4 inet_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0xf499fdb2 rcu_barrier_bh +EXPORT_SYMBOL_GPL vmlinux 0xf4b01ed9 ata_eh_qc_retry +EXPORT_SYMBOL_GPL vmlinux 0xf4e012d9 securityfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0xf53cfe2b klist_node_attached +EXPORT_SYMBOL_GPL vmlinux 0xf578f729 scsi_internal_device_unblock +EXPORT_SYMBOL_GPL vmlinux 0xf591b3da inotify_destroy +EXPORT_SYMBOL_GPL vmlinux 0xf5a691cd invalidate_bh_lrus +EXPORT_SYMBOL_GPL vmlinux 0xf619e4f8 sk_setup_caps +EXPORT_SYMBOL_GPL vmlinux 0xf654dc3b attribute_container_classdev_to_container +EXPORT_SYMBOL_GPL vmlinux 0xf6dae56b md_do_sync +EXPORT_SYMBOL_GPL vmlinux 0xf722b6c6 xprt_set_retrans_timeout_def +EXPORT_SYMBOL_GPL vmlinux 0xf772fd49 bus_rescan_devices +EXPORT_SYMBOL_GPL vmlinux 0xf7bc85de inet_ctl_sock_create +EXPORT_SYMBOL_GPL vmlinux 0xf7e2b0d0 transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0xf863e82a flush_work +EXPORT_SYMBOL_GPL vmlinux 0xf8984c77 ata_cable_80wire +EXPORT_SYMBOL_GPL vmlinux 0xf8a1e7fd uart_set_options +EXPORT_SYMBOL_GPL vmlinux 0xf8f3a0fb ata_ratelimit +EXPORT_SYMBOL_GPL vmlinux 0xf91d56c9 sdio_writel +EXPORT_SYMBOL_GPL vmlinux 0xf98d81de bus_for_each_dev +EXPORT_SYMBOL_GPL vmlinux 0xf9a054b5 __round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0xf9b31d6e sysfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0xf9ca3160 ata_id_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xf9d1164c rpc_free +EXPORT_SYMBOL_GPL vmlinux 0xf9d457c0 xdr_skb_read_bits +EXPORT_SYMBOL_GPL vmlinux 0xf9f9987a dev_attr_em_message_type +EXPORT_SYMBOL_GPL vmlinux 0xfa2ce1da fsstack_copy_attr_all +EXPORT_SYMBOL_GPL vmlinux 0xfa72aaf3 xprt_set_retrans_timeout_rtt +EXPORT_SYMBOL_GPL vmlinux 0xfadafac6 svc_close_xprt +EXPORT_SYMBOL_GPL vmlinux 0xfae848b3 sysfs_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xfb07023d blk_end_request_callback +EXPORT_SYMBOL_GPL vmlinux 0xfb2417c7 rtc_read_time +EXPORT_SYMBOL_GPL vmlinux 0xfb6021a3 inet_hash +EXPORT_SYMBOL_GPL vmlinux 0xfbd85969 scsi_target_block +EXPORT_SYMBOL_GPL vmlinux 0xfbf9be5d register_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xfc220ec9 rt_mutex_destroy +EXPORT_SYMBOL_GPL vmlinux 0xfc5a13f5 mtd_erase_callback +EXPORT_SYMBOL_GPL vmlinux 0xfc8e986c __pneigh_lookup +EXPORT_SYMBOL_GPL vmlinux 0xfc954e9a pci_find_next_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0xfda30b9c platform_get_irq +EXPORT_SYMBOL_GPL vmlinux 0xfe4e821b elv_register +EXPORT_SYMBOL_GPL vmlinux 0xfe6cd8f4 svc_xprt_received +EXPORT_SYMBOL_GPL vmlinux 0xfe917181 inet_twsk_purge +EXPORT_SYMBOL_GPL vmlinux 0xfeb4aa7f scsi_mode_select +EXPORT_SYMBOL_GPL vmlinux 0xfebb82e5 rtc_class_close +EXPORT_SYMBOL_GPL vmlinux 0xff5af72f disk_map_sector_rcu +EXPORT_SYMBOL_GPL vmlinux 0xffaf7bbb __wake_up_sync +EXPORT_SYMBOL_GPL vmlinux 0xffd6d5a5 class_for_each_device --- linux-2.6.28.orig/debian/abi/2.6.28-11.41/armel/iop32x.modules +++ linux-2.6.28/debian/abi/2.6.28-11.41/armel/iop32x.modules @@ -0,0 +1,190 @@ +act_gact +act_ipt +act_mirred +act_nat +act_pedit +act_police +act_simple +act_skbedit +aead +aes_generic +anubis +arc4 +arptable_filter +arp_tables +arpt_mangle +async_memcpy +async_xor +aufs +blowfish +cast5 +cast6 +cbc +cdrom +chainiv +cls_basic +cls_flow +cls_fw +cls_route +cls_rsvp +cls_rsvp6 +cls_tcindex +cls_u32 +compcache +configfs +crc16 +crc32c +crc-itu-t +crc-t10dif +crypto_algapi +crypto_blkcipher +crypto_hash +cryptoloop +cryptomgr +crypto_null +deflate +des_generic +dm-mod +ecb +eseqiv +gf128mul +hid-belkin +hid-bright +hid-cherry +hid-chicony +hid-cypress +hid-dell +hid-ezkey +hid-gyration +hid-logitech +hid-microsoft +hid-monterey +hid-petalynx +hid-pl +hid-samsung +hid-sony +hid-sunplus +hmac +hwa-hc +hwa-rc +i2c-algo-bit +i2c-gpio +ide-cd_mod +ide-pci-generic +ide-tape +ifb +iptable_filter +iptable_mangle +iptable_raw +ip_tables +ipt_addrtype +ipt_ah +ipt_ecn +ipt_ECN +ipt_LOG +ipt_REJECT +ipt_ttl +ipt_TTL +ipt_ULOG +isofs +jfs +khazad +krng +libcrc32c +lrw +lzo_compress +lzo_decompress +md4 +md5 +md-mod +michael_mic +msdos +nand +nand_ecc +nand_ids +nbd +pcbc +phonet +plat_nand +pn_pep +raid0 +raid1 +raid10 +raid456 +reiserfs +rng +rng-core +sch_cbq +sch_dsmark +sch_gred +sch_htb +sch_ingress +sch_prio +sch_red +sch_sfq +sch_tbf +sch_teql +scsi_wait_scan +serpent +sg +sha1_generic +sha256_generic +sha512_generic +sit +squashfs +tea +tgr192 +tlsf +ts_bm +ts_fsm +ts_kmp +tunnel4 +twofish +twofish_common +udf +uwb +virtual +wp512 +wusb-cbaf +wusbcore +wusb-wa +xcbc +xfrm6_mode_beet +xfrm6_mode_transport +xfrm6_mode_tunnel +xfs +xor +x_tables +xt_CLASSIFY +xt_comment +xt_dccp +xt_dscp +xt_DSCP +xt_esp +xt_hashlimit +xt_iprange +xt_length +xt_limit +xt_mac +xt_mark +xt_MARK +xt_multiport +xt_NFLOG +xt_NFQUEUE +xt_owner +xt_pkttype +xt_policy +xt_quota +xt_rateest +xt_RATEEST +xt_realm +xt_recent +xt_statistic +xt_string +xt_tcpmss +xt_TCPMSS +xt_TCPOPTSTRIP +xt_tcpudp +xt_time +xt_TRACE +xt_u32 --- linux-2.6.28.orig/debian/abi/2.6.28-11.41/armel/versatile.modules +++ linux-2.6.28/debian/abi/2.6.28-11.41/armel/versatile.modules @@ -0,0 +1,47 @@ +8250 +8250_pci +ac97_bus +aead +aufs +cbc +cdrom +chainiv +compcache +crypto_algapi +crypto_blkcipher +crypto_hash +cryptomgr +dm-crypt +dm-log +dm-mirror +dm-multipath +dm-region-hash +dm-round-robin +dm-snapshot +dm-zero +eeprom +eseqiv +fat +i2c-dev +krng +lzo_compress +lzo_decompress +mmci +nls_base +nls_cp850 +nls_iso8859-1 +rng +rng-core +scsi_wait_scan +snd +snd-aaci +snd-ac97-codec +snd-mixer-oss +snd-page-alloc +snd-pcm +snd-pcm-oss +snd-timer +squashfs +sr_mod +tlsf +vfat --- linux-2.6.28.orig/debian/abi/2.6.28-11.41/armel/iop32x +++ linux-2.6.28/debian/abi/2.6.28-11.41/armel/iop32x @@ -0,0 +1,4075 @@ +EXPORT_SYMBOL crypto/gf128mul 0x0c2f123f gf128mul_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x1068004b gf128mul_bbe +EXPORT_SYMBOL crypto/gf128mul 0x2f2889a0 gf128mul_init_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0x3755f990 gf128mul_init_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x384ef9ce gf128mul_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x56af0dbd gf128mul_x_ble +EXPORT_SYMBOL crypto/gf128mul 0x83581089 gf128mul_init_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0x9b2560b9 gf128mul_init_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x9e13f6f6 gf128mul_lle +EXPORT_SYMBOL crypto/gf128mul 0xbd17a0df gf128mul_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0xc0890413 gf128mul_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0xd60736ec gf128mul_free_64k +EXPORT_SYMBOL crypto/xor 0x5b6c00e6 xor_blocks +EXPORT_SYMBOL drivers/cdrom/cdrom 0x15c40c34 cdrom_number_of_slots +EXPORT_SYMBOL drivers/cdrom/cdrom 0x32a820f0 cdrom_release +EXPORT_SYMBOL drivers/cdrom/cdrom 0x443b99a4 cdrom_get_media_event +EXPORT_SYMBOL drivers/cdrom/cdrom 0x4f476e96 init_cdrom_command +EXPORT_SYMBOL drivers/cdrom/cdrom 0x6beb15c3 cdrom_mode_select +EXPORT_SYMBOL drivers/cdrom/cdrom 0x6fb4d14d register_cdrom +EXPORT_SYMBOL drivers/cdrom/cdrom 0x753c2b3e cdrom_get_last_written +EXPORT_SYMBOL drivers/cdrom/cdrom 0xa240e304 cdrom_open +EXPORT_SYMBOL drivers/cdrom/cdrom 0xca51b83b cdrom_ioctl +EXPORT_SYMBOL drivers/cdrom/cdrom 0xd3cb10e0 cdrom_mode_sense +EXPORT_SYMBOL drivers/cdrom/cdrom 0xf1d7e776 unregister_cdrom +EXPORT_SYMBOL drivers/cdrom/cdrom 0xf50b92e8 cdrom_media_changed +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0xe533e3e3 i2c_bit_add_numbered_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0xec329de6 i2c_bit_add_bus +EXPORT_SYMBOL drivers/md/dm-mod 0x192e7a1b dm_put_device +EXPORT_SYMBOL drivers/md/dm-mod 0x1f2ed415 dm_table_get_md +EXPORT_SYMBOL drivers/md/dm-mod 0x240aca62 dm_unregister_target +EXPORT_SYMBOL drivers/md/dm-mod 0x297c4f19 dm_kcopyd_client_destroy +EXPORT_SYMBOL drivers/md/dm-mod 0x3f775915 dm_table_unplug_all +EXPORT_SYMBOL drivers/md/dm-mod 0x53958d61 dm_io_client_destroy +EXPORT_SYMBOL drivers/md/dm-mod 0x76ca9817 dm_io_client_resize +EXPORT_SYMBOL drivers/md/dm-mod 0x8346a1ac dm_io_client_create +EXPORT_SYMBOL drivers/md/dm-mod 0x8d719073 dm_io +EXPORT_SYMBOL drivers/md/dm-mod 0x99f51cf1 dm_get_mapinfo +EXPORT_SYMBOL drivers/md/dm-mod 0x9b2e1a72 dm_kcopyd_client_create +EXPORT_SYMBOL drivers/md/dm-mod 0x9eaf090f dm_table_put +EXPORT_SYMBOL drivers/md/dm-mod 0xa6ae065f dm_table_get +EXPORT_SYMBOL drivers/md/dm-mod 0xaa22d0de dm_table_get_mode +EXPORT_SYMBOL drivers/md/dm-mod 0xb5a96654 dm_table_get_size +EXPORT_SYMBOL drivers/md/dm-mod 0xc79bcd36 dm_vcalloc +EXPORT_SYMBOL drivers/md/dm-mod 0xe1d2c23d dm_kcopyd_copy +EXPORT_SYMBOL drivers/md/dm-mod 0xe357ca62 dm_register_target +EXPORT_SYMBOL drivers/md/dm-mod 0xf55ad2ec dm_table_event +EXPORT_SYMBOL drivers/md/dm-mod 0xf6f75931 dm_get_device +EXPORT_SYMBOL drivers/md/md-mod 0x0055d768 md_wait_for_blocked_rdev +EXPORT_SYMBOL drivers/md/md-mod 0x028c108a unregister_md_personality +EXPORT_SYMBOL drivers/md/md-mod 0x10711242 md_wakeup_thread +EXPORT_SYMBOL drivers/md/md-mod 0x24938a8f md_write_end +EXPORT_SYMBOL drivers/md/md-mod 0x264ee1ff bitmap_startwrite +EXPORT_SYMBOL drivers/md/md-mod 0x2f2f482a bitmap_close_sync +EXPORT_SYMBOL drivers/md/md-mod 0x34550f12 md_error +EXPORT_SYMBOL drivers/md/md-mod 0x36082ef2 bitmap_end_sync +EXPORT_SYMBOL drivers/md/md-mod 0x47c9ec2b md_write_start +EXPORT_SYMBOL drivers/md/md-mod 0x5228c754 bitmap_start_sync +EXPORT_SYMBOL drivers/md/md-mod 0x60f76162 register_md_personality +EXPORT_SYMBOL drivers/md/md-mod 0x6b8d0e00 md_check_recovery +EXPORT_SYMBOL drivers/md/md-mod 0x75d9c831 md_register_thread +EXPORT_SYMBOL drivers/md/md-mod 0x827db1e1 bitmap_endwrite +EXPORT_SYMBOL drivers/md/md-mod 0x915e041e bitmap_cond_end_sync +EXPORT_SYMBOL drivers/md/md-mod 0x9ae68c4c md_done_sync +EXPORT_SYMBOL drivers/md/md-mod 0xaf245e6b md_unregister_thread +EXPORT_SYMBOL drivers/md/md-mod 0xc6dfa3ec bitmap_unplug +EXPORT_SYMBOL drivers/mtd/nand/nand 0x73b58cc8 nand_scan_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand 0xcd6c8aa5 nand_default_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0x078d057c nand_calculate_ecc +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0x35e6cfc5 nand_correct_data +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0x836bdb72 nand_flash_ids +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0xa336feb7 nand_manuf_ids +EXPORT_SYMBOL fs/configfs/configfs 0x2fdeb8e9 config_group_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0x35c21432 config_item_init +EXPORT_SYMBOL fs/configfs/configfs 0x3ac0af51 config_group_init +EXPORT_SYMBOL fs/configfs/configfs 0x8227b346 config_item_get +EXPORT_SYMBOL fs/configfs/configfs 0x93644469 config_group_find_item +EXPORT_SYMBOL fs/configfs/configfs 0x9c5c0889 config_item_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0xb02d59c7 configfs_undepend_item +EXPORT_SYMBOL fs/configfs/configfs 0xb372685e configfs_unregister_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0xbaf097bb configfs_depend_item +EXPORT_SYMBOL fs/configfs/configfs 0xcb02d8f3 config_item_put +EXPORT_SYMBOL fs/configfs/configfs 0xe43724c1 configfs_register_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0xf031d1b5 config_item_set_name +EXPORT_SYMBOL fs/xfs/xfs 0x4effde86 xfs_qmcore_xfs +EXPORT_SYMBOL lib/crc-itu-t 0xd29b009f crc_itu_t_table +EXPORT_SYMBOL lib/crc-itu-t 0xf5b4a948 crc_itu_t +EXPORT_SYMBOL lib/crc-t10dif 0xb6896671 crc_t10dif +EXPORT_SYMBOL lib/crc16 0x02a6ce5a crc16_table +EXPORT_SYMBOL lib/crc16 0x8ffdb3b8 crc16 +EXPORT_SYMBOL lib/libcrc32c 0x2329b292 crc32c_be +EXPORT_SYMBOL lib/libcrc32c 0x37d0b921 crc32c_le +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x97772891 arpt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0xddda15c4 arpt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0xec33aa5b arpt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0x2d43bfe1 ipt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0xce097106 ipt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0xf1ff2230 ipt_register_table +EXPORT_SYMBOL net/ipv4/tunnel4 0xa21d7192 xfrm4_tunnel_deregister +EXPORT_SYMBOL net/ipv4/tunnel4 0xf6f931fb xfrm4_tunnel_register +EXPORT_SYMBOL net/netfilter/x_tables 0x08cdd7f1 xt_register_match +EXPORT_SYMBOL net/netfilter/x_tables 0x1de71e46 xt_unregister_matches +EXPORT_SYMBOL net/netfilter/x_tables 0x38b3ece0 xt_unregister_targets +EXPORT_SYMBOL net/netfilter/x_tables 0x3dcd58c5 xt_alloc_table_info +EXPORT_SYMBOL net/netfilter/x_tables 0x5cf16fda xt_unregister_target +EXPORT_SYMBOL net/netfilter/x_tables 0x6c8638f9 xt_find_match +EXPORT_SYMBOL net/netfilter/x_tables 0x70d5df49 xt_register_targets +EXPORT_SYMBOL net/netfilter/x_tables 0x7ccb9992 xt_unregister_match +EXPORT_SYMBOL net/netfilter/x_tables 0x89d5b511 xt_find_target +EXPORT_SYMBOL net/netfilter/x_tables 0xcb10c5c0 xt_register_target +EXPORT_SYMBOL net/netfilter/x_tables 0xe25dfa31 xt_register_matches +EXPORT_SYMBOL net/netfilter/x_tables 0xf7037dc6 xt_free_table_info +EXPORT_SYMBOL net/phonet/phonet 0x26a2f271 phonet_header_ops +EXPORT_SYMBOL net/phonet/phonet 0x325e7235 pn_sock_get_port +EXPORT_SYMBOL net/phonet/phonet 0x3aa7f2cd pn_skb_send +EXPORT_SYMBOL net/phonet/phonet 0x9b6dc528 pn_sock_unhash +EXPORT_SYMBOL net/phonet/phonet 0xa526ee5a phonet_stream_ops +EXPORT_SYMBOL net/phonet/phonet 0xa59bbee6 phonet_proto_register +EXPORT_SYMBOL net/phonet/phonet 0xbf24fd13 phonet_proto_unregister +EXPORT_SYMBOL net/phonet/phonet 0xe1cd249a pn_sock_hash +EXPORT_SYMBOL vmlinux 0x00000000 fp_printk +EXPORT_SYMBOL vmlinux 0x00000000 fp_send_sig +EXPORT_SYMBOL vmlinux 0x00000000 kern_fp_enter +EXPORT_SYMBOL vmlinux 0x00000000 per_cpu__softirq_work_list +EXPORT_SYMBOL vmlinux 0x00244f86 dev_get_by_name +EXPORT_SYMBOL vmlinux 0x0027d957 register_netdev +EXPORT_SYMBOL vmlinux 0x003f544c lock_may_write +EXPORT_SYMBOL vmlinux 0x0060c3bd cache_purge +EXPORT_SYMBOL vmlinux 0x0078bbcf xfrm_lookup +EXPORT_SYMBOL vmlinux 0x007c37c8 sk_stream_write_space +EXPORT_SYMBOL vmlinux 0x00801678 flush_scheduled_work +EXPORT_SYMBOL vmlinux 0x0083e088 end_request +EXPORT_SYMBOL vmlinux 0x009e79fa sock_no_connect +EXPORT_SYMBOL vmlinux 0x00dd7df7 blk_unplug +EXPORT_SYMBOL vmlinux 0x00e8097b csum_partial_copy_fromiovecend +EXPORT_SYMBOL vmlinux 0x01000e51 schedule +EXPORT_SYMBOL vmlinux 0x01139ffc max_mapnr +EXPORT_SYMBOL vmlinux 0x019df99e del_gendisk +EXPORT_SYMBOL vmlinux 0x01a4aab6 set_irq_chip_data +EXPORT_SYMBOL vmlinux 0x01df4d55 skb_pull +EXPORT_SYMBOL vmlinux 0x01e02bcf __nla_reserve +EXPORT_SYMBOL vmlinux 0x01e1a1c9 dma_map_sg +EXPORT_SYMBOL vmlinux 0x01fcbe8e dev_unicast_add +EXPORT_SYMBOL vmlinux 0x020dad82 km_query +EXPORT_SYMBOL vmlinux 0x02124474 ip_send_check +EXPORT_SYMBOL vmlinux 0x02196324 __aeabi_idiv +EXPORT_SYMBOL vmlinux 0x02479c44 skb_dma_map +EXPORT_SYMBOL vmlinux 0x02649054 security_sock_rcv_skb +EXPORT_SYMBOL vmlinux 0x027d6bb8 journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x029e89a7 udp_ioctl +EXPORT_SYMBOL vmlinux 0x02c611a7 scsi_allocate_command +EXPORT_SYMBOL vmlinux 0x02c7a059 follow_down +EXPORT_SYMBOL vmlinux 0x02cc0fd3 pci_select_bars +EXPORT_SYMBOL vmlinux 0x02ee26c1 free_pages_exact +EXPORT_SYMBOL vmlinux 0x031bc0da pci_bus_add_devices +EXPORT_SYMBOL vmlinux 0x0334da4e scsi_command_size_tbl +EXPORT_SYMBOL vmlinux 0x0350e2f4 up_read +EXPORT_SYMBOL vmlinux 0x037a0cba kfree +EXPORT_SYMBOL vmlinux 0x0388ec4a blk_queue_stack_limits +EXPORT_SYMBOL vmlinux 0x03a99c3b rb_prev +EXPORT_SYMBOL vmlinux 0x03c06156 bitmap_fold +EXPORT_SYMBOL vmlinux 0x03c59706 xdr_inline_pages +EXPORT_SYMBOL vmlinux 0x03fd2571 vm_unmap_ram +EXPORT_SYMBOL vmlinux 0x0422fe4a inet_csk_timer_bug_msg +EXPORT_SYMBOL vmlinux 0x043b8483 __kfifo_get +EXPORT_SYMBOL vmlinux 0x044fbf49 mempool_kzalloc +EXPORT_SYMBOL vmlinux 0x04c4f45f handle_sysrq +EXPORT_SYMBOL vmlinux 0x04f2bf2e tcf_hash_new_index +EXPORT_SYMBOL vmlinux 0x0506a514 task_session_nr_ns +EXPORT_SYMBOL vmlinux 0x050d6de7 dev_unicast_delete +EXPORT_SYMBOL vmlinux 0x051c7baf neigh_create +EXPORT_SYMBOL vmlinux 0x052b2967 kblockd_flush_work +EXPORT_SYMBOL vmlinux 0x0559f0d0 xdr_decode_array2 +EXPORT_SYMBOL vmlinux 0x055f44b5 inet_shutdown +EXPORT_SYMBOL vmlinux 0x0560cdeb xfrm_state_flush +EXPORT_SYMBOL vmlinux 0x056e0219 xfrm_unregister_km +EXPORT_SYMBOL vmlinux 0x05757bf8 flush_dcache_page +EXPORT_SYMBOL vmlinux 0x057ce975 hex_dump_to_buffer +EXPORT_SYMBOL vmlinux 0x05a4c36f sock_common_recvmsg +EXPORT_SYMBOL vmlinux 0x05a9637a dmam_alloc_coherent +EXPORT_SYMBOL vmlinux 0x05c771d1 textsearch_find_continuous +EXPORT_SYMBOL vmlinux 0x05de155e lock_may_read +EXPORT_SYMBOL vmlinux 0x05e807a9 xdr_encode_string +EXPORT_SYMBOL vmlinux 0x05f039c5 skb_kill_datagram +EXPORT_SYMBOL vmlinux 0x06090de7 __sg_free_table +EXPORT_SYMBOL vmlinux 0x061651be strcat +EXPORT_SYMBOL vmlinux 0x0618e633 dump_fpu +EXPORT_SYMBOL vmlinux 0x062aba95 mempool_free +EXPORT_SYMBOL vmlinux 0x065994f1 xdr_encode_opaque_fixed +EXPORT_SYMBOL vmlinux 0x0672dfd8 __bforget +EXPORT_SYMBOL vmlinux 0x067805d4 call_usermodehelper_stdinpipe +EXPORT_SYMBOL vmlinux 0x067d8d35 security_release_secctx +EXPORT_SYMBOL vmlinux 0x069aea95 i2c_smbus_read_byte_data +EXPORT_SYMBOL vmlinux 0x06a5c1b7 __free_pages +EXPORT_SYMBOL vmlinux 0x06be01f1 nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0x06cb34e5 init_waitqueue_head +EXPORT_SYMBOL vmlinux 0x06d8bae1 idr_get_new +EXPORT_SYMBOL vmlinux 0x06f389b9 scm_detach_fds +EXPORT_SYMBOL vmlinux 0x06fe3b14 default_grn +EXPORT_SYMBOL vmlinux 0x07296227 linkwatch_fire_event +EXPORT_SYMBOL vmlinux 0x075dc3ee skb_free_datagram +EXPORT_SYMBOL vmlinux 0x07831218 audit_log_format +EXPORT_SYMBOL vmlinux 0x0799aca4 local_bh_enable +EXPORT_SYMBOL vmlinux 0x079baaa0 tcp_sendmsg +EXPORT_SYMBOL vmlinux 0x079cd7f1 ns_to_timeval +EXPORT_SYMBOL vmlinux 0x07abb1a0 generic_listxattr +EXPORT_SYMBOL vmlinux 0x07cc4a5d printk_timed_ratelimit +EXPORT_SYMBOL vmlinux 0x07eee53d journal_get_create_access +EXPORT_SYMBOL vmlinux 0x08134276 tc_classify +EXPORT_SYMBOL vmlinux 0x081e7de2 __fatal_signal_pending +EXPORT_SYMBOL vmlinux 0x082b4474 scsi_add_device +EXPORT_SYMBOL vmlinux 0x082c3213 pci_root_buses +EXPORT_SYMBOL vmlinux 0x0836f206 bfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0x08ab83ae pci_disable_device +EXPORT_SYMBOL vmlinux 0x08ecca24 ip_mc_inc_group +EXPORT_SYMBOL vmlinux 0x08f068cc xdr_reserve_space +EXPORT_SYMBOL vmlinux 0x090a3f5e key_alloc +EXPORT_SYMBOL vmlinux 0x09130743 d_invalidate +EXPORT_SYMBOL vmlinux 0x0924e70f eth_header_cache_update +EXPORT_SYMBOL vmlinux 0x092b007a sleep_on_timeout +EXPORT_SYMBOL vmlinux 0x0948cde9 num_physpages +EXPORT_SYMBOL vmlinux 0x0977c951 neigh_table_clear +EXPORT_SYMBOL vmlinux 0x09816c74 send_sig +EXPORT_SYMBOL vmlinux 0x0991d932 sync_page_range_nolock +EXPORT_SYMBOL vmlinux 0x09c55cec schedule_timeout_interruptible +EXPORT_SYMBOL vmlinux 0x09d45c21 down_timeout +EXPORT_SYMBOL vmlinux 0x09f4c856 bh_uptodate_or_lock +EXPORT_SYMBOL vmlinux 0x0a10d36d deny_write_access +EXPORT_SYMBOL vmlinux 0x0a1bebc5 kernel_execve +EXPORT_SYMBOL vmlinux 0x0a235bf7 svc_sock_names +EXPORT_SYMBOL vmlinux 0x0a2487e0 unblock_all_signals +EXPORT_SYMBOL vmlinux 0x0a3131f6 strnchr +EXPORT_SYMBOL vmlinux 0x0a4747ff allocate_resource +EXPORT_SYMBOL vmlinux 0x0a70c744 hub_port_logical_disconnect +EXPORT_SYMBOL vmlinux 0x0aa13d05 __raw_readsw +EXPORT_SYMBOL vmlinux 0x0abf293b sk_wait_data +EXPORT_SYMBOL vmlinux 0x0ac0ef11 i2c_smbus_read_i2c_block_data +EXPORT_SYMBOL vmlinux 0x0ac4dda1 xfrm_policy_delete +EXPORT_SYMBOL vmlinux 0x0acb1a3c __bitmap_shift_right +EXPORT_SYMBOL vmlinux 0x0af46a3a skb_add_rx_frag +EXPORT_SYMBOL vmlinux 0x0b01f423 dentry_unhash +EXPORT_SYMBOL vmlinux 0x0b0f18c4 dma_release_declared_memory +EXPORT_SYMBOL vmlinux 0x0b173a64 rtnl_set_sk_err +EXPORT_SYMBOL vmlinux 0x0b1beb31 vmalloc_32_user +EXPORT_SYMBOL vmlinux 0x0b5f2d2c sg_next +EXPORT_SYMBOL vmlinux 0x0b742fd7 simple_strtol +EXPORT_SYMBOL vmlinux 0x0ba1bf4d find_inode_number +EXPORT_SYMBOL vmlinux 0x0bc1af55 __sk_mem_schedule +EXPORT_SYMBOL vmlinux 0x0bd380a5 nlmsvc_ops +EXPORT_SYMBOL vmlinux 0x0bf82e63 vc_resize +EXPORT_SYMBOL vmlinux 0x0c0c5316 rpc_unlink +EXPORT_SYMBOL vmlinux 0x0c2222e0 scsi_release_buffers +EXPORT_SYMBOL vmlinux 0x0c5ef91b per_cpu__vm_event_states +EXPORT_SYMBOL vmlinux 0x0c65e73c scsi_normalize_sense +EXPORT_SYMBOL vmlinux 0x0c7a7be3 block_prepare_write +EXPORT_SYMBOL vmlinux 0x0c7e5ae6 lock_sock_nested +EXPORT_SYMBOL vmlinux 0x0c893ee2 __mpage_writepage +EXPORT_SYMBOL vmlinux 0x0c8c9e99 scsi_show_extd_sense +EXPORT_SYMBOL vmlinux 0x0cce8a98 blk_queue_set_discard +EXPORT_SYMBOL vmlinux 0x0cd95ded netif_rx_ni +EXPORT_SYMBOL vmlinux 0x0cf2a0ea neigh_lookup +EXPORT_SYMBOL vmlinux 0x0d1a888d qdisc_watchdog_cancel +EXPORT_SYMBOL vmlinux 0x0d3c225e sock_register +EXPORT_SYMBOL vmlinux 0x0d3d1354 filp_close +EXPORT_SYMBOL vmlinux 0x0d3d8a67 __xfrm_lookup +EXPORT_SYMBOL vmlinux 0x0d3def21 idr_pre_get +EXPORT_SYMBOL vmlinux 0x0d3f57a2 _find_next_bit_le +EXPORT_SYMBOL vmlinux 0x0d542439 __ipv6_addr_type +EXPORT_SYMBOL vmlinux 0x0d8ab500 param_set_copystring +EXPORT_SYMBOL vmlinux 0x0da10ec3 security_sock_graft +EXPORT_SYMBOL vmlinux 0x0dc7bcfe submit_bh +EXPORT_SYMBOL vmlinux 0x0dd79833 ip_getsockopt +EXPORT_SYMBOL vmlinux 0x0e2fdae8 fget +EXPORT_SYMBOL vmlinux 0x0e52592a panic +EXPORT_SYMBOL vmlinux 0x0e58df1d d_genocide +EXPORT_SYMBOL vmlinux 0x0e762d6e request_module +EXPORT_SYMBOL vmlinux 0x0e7b575a tty_check_change +EXPORT_SYMBOL vmlinux 0x0e7f4782 blk_remove_plug +EXPORT_SYMBOL vmlinux 0x0ead7bdb keyring_search +EXPORT_SYMBOL vmlinux 0x0eb70cf9 nla_put_nohdr +EXPORT_SYMBOL vmlinux 0x0f1ef871 posix_acl_alloc +EXPORT_SYMBOL vmlinux 0x0f28d994 unregister_mtd_chip_driver +EXPORT_SYMBOL vmlinux 0x0f3cd739 journal_create +EXPORT_SYMBOL vmlinux 0x0f5855f3 i2c_release_client +EXPORT_SYMBOL vmlinux 0x0f668ba9 svc_auth_unregister +EXPORT_SYMBOL vmlinux 0x0fa2a45e __memzero +EXPORT_SYMBOL vmlinux 0x0fa35501 ipv6_skip_exthdr +EXPORT_SYMBOL vmlinux 0x0faa4138 bio_free +EXPORT_SYMBOL vmlinux 0x0fc0a1ec open_bdev_exclusive +EXPORT_SYMBOL vmlinux 0x0fc586ba down_trylock +EXPORT_SYMBOL vmlinux 0x0fec61fd vfs_unlink +EXPORT_SYMBOL vmlinux 0x0ff178f6 __aeabi_idivmod +EXPORT_SYMBOL vmlinux 0x10055957 __devm_release_region +EXPORT_SYMBOL vmlinux 0x101d8efd scsi_remove_device +EXPORT_SYMBOL vmlinux 0x10579454 sg_copy_from_buffer +EXPORT_SYMBOL vmlinux 0x1072a394 csum_partial_copy_from_user +EXPORT_SYMBOL vmlinux 0x107ed103 xfrm_unregister_mode +EXPORT_SYMBOL vmlinux 0x10ee20bb default_blu +EXPORT_SYMBOL vmlinux 0x10f7a6c8 __lookup_hash +EXPORT_SYMBOL vmlinux 0x11056a55 pneigh_enqueue +EXPORT_SYMBOL vmlinux 0x111bcb2c groups_free +EXPORT_SYMBOL vmlinux 0x11267875 scsi_extd_sense_format +EXPORT_SYMBOL vmlinux 0x1163f0a7 blk_max_low_pfn +EXPORT_SYMBOL vmlinux 0x117093be qdisc_class_hash_init +EXPORT_SYMBOL vmlinux 0x117c930d pci_bus_assign_resources +EXPORT_SYMBOL vmlinux 0x119b50e7 elf_check_arch +EXPORT_SYMBOL vmlinux 0x11c34cd4 scsi_setup_fs_cmnd +EXPORT_SYMBOL vmlinux 0x11cfdde2 page_follow_link_light +EXPORT_SYMBOL vmlinux 0x11d6a2ec neigh_event_ns +EXPORT_SYMBOL vmlinux 0x11d97caa shrink_dcache_sb +EXPORT_SYMBOL vmlinux 0x11eba01c single_release +EXPORT_SYMBOL vmlinux 0x1208ed08 simple_getattr +EXPORT_SYMBOL vmlinux 0x12345896 mii_link_ok +EXPORT_SYMBOL vmlinux 0x125ead66 skb_put +EXPORT_SYMBOL vmlinux 0x126970ed param_set_uint +EXPORT_SYMBOL vmlinux 0x12772edd proc_doulongvec_ms_jiffies_minmax +EXPORT_SYMBOL vmlinux 0x129badc6 pci_scan_bridge +EXPORT_SYMBOL vmlinux 0x12a1e57f kernel_sock_shutdown +EXPORT_SYMBOL vmlinux 0x12d91341 generic_file_splice_read +EXPORT_SYMBOL vmlinux 0x12da5bb2 __kmalloc +EXPORT_SYMBOL vmlinux 0x12e280e3 svc_proc_unregister +EXPORT_SYMBOL vmlinux 0x13167d11 generic_permission +EXPORT_SYMBOL vmlinux 0x13266092 put_io_context +EXPORT_SYMBOL vmlinux 0x1333ea3d xfrm6_rcv_spi +EXPORT_SYMBOL vmlinux 0x13554e30 ipv6_chk_addr +EXPORT_SYMBOL vmlinux 0x135ccf88 udp_disconnect +EXPORT_SYMBOL vmlinux 0x137f6d33 write_one_page +EXPORT_SYMBOL vmlinux 0x13c3cc5d inode_permission +EXPORT_SYMBOL vmlinux 0x13c78a6e dma_pool_destroy +EXPORT_SYMBOL vmlinux 0x13cb345b lock_super +EXPORT_SYMBOL vmlinux 0x13d9d989 kobject_set_name +EXPORT_SYMBOL vmlinux 0x1414d307 xfrm_stateonly_find +EXPORT_SYMBOL vmlinux 0x1428078a skb_insert +EXPORT_SYMBOL vmlinux 0x142c2bc8 simple_sync_file +EXPORT_SYMBOL vmlinux 0x143743ac tcp_v4_send_check +EXPORT_SYMBOL vmlinux 0x143a17bf pci_assign_resource +EXPORT_SYMBOL vmlinux 0x143d4dee input_unregister_device +EXPORT_SYMBOL vmlinux 0x1443d4f6 simple_unlink +EXPORT_SYMBOL vmlinux 0x144ed3a1 dev_base_lock +EXPORT_SYMBOL vmlinux 0x146f40fe cdev_alloc +EXPORT_SYMBOL vmlinux 0x148224f1 generic_getxattr +EXPORT_SYMBOL vmlinux 0x14b9cf9f skb_copy +EXPORT_SYMBOL vmlinux 0x1502d40d xscale_flush_user_cache_range +EXPORT_SYMBOL vmlinux 0x1544aad4 genl_register_mc_group +EXPORT_SYMBOL vmlinux 0x1551dc51 bitmap_find_free_region +EXPORT_SYMBOL vmlinux 0x157464cb xdr_init_decode +EXPORT_SYMBOL vmlinux 0x15860542 ip_xfrm_me_harder +EXPORT_SYMBOL vmlinux 0x15863519 __alloc_skb +EXPORT_SYMBOL vmlinux 0x1592dcb1 bio_split +EXPORT_SYMBOL vmlinux 0x15f42858 bdev_read_only +EXPORT_SYMBOL vmlinux 0x15fca11d block_write_full_page +EXPORT_SYMBOL vmlinux 0x160c094f eth_header +EXPORT_SYMBOL vmlinux 0x1629228b mpage_readpages +EXPORT_SYMBOL vmlinux 0x16479e8f panic_notifier_list +EXPORT_SYMBOL vmlinux 0x1675d546 tc_classify_compat +EXPORT_SYMBOL vmlinux 0x16c315d3 neigh_parms_release +EXPORT_SYMBOL vmlinux 0x16e3be51 sk_stream_kill_queues +EXPORT_SYMBOL vmlinux 0x17055567 dma_alloc_coherent +EXPORT_SYMBOL vmlinux 0x174b0a73 alloc_netdev_mq +EXPORT_SYMBOL vmlinux 0x1776d697 tcp_simple_retransmit +EXPORT_SYMBOL vmlinux 0x178056b8 clear_page_dirty_for_io +EXPORT_SYMBOL vmlinux 0x178c519a bio_copy_kern +EXPORT_SYMBOL vmlinux 0x178cfdd4 __module_put_and_exit +EXPORT_SYMBOL vmlinux 0x17a76e71 rb_first +EXPORT_SYMBOL vmlinux 0x17a977ec netif_rx +EXPORT_SYMBOL vmlinux 0x17b94585 blk_queue_segment_boundary +EXPORT_SYMBOL vmlinux 0x17bbe7c0 __f_setown +EXPORT_SYMBOL vmlinux 0x17cbbe48 kernel_getsockname +EXPORT_SYMBOL vmlinux 0x17dad85b touch_atime +EXPORT_SYMBOL vmlinux 0x17df17bc sysctl_tcp_ecn +EXPORT_SYMBOL vmlinux 0x17e1fa38 mb_cache_entry_insert +EXPORT_SYMBOL vmlinux 0x182db5c3 netlink_rcv_skb +EXPORT_SYMBOL vmlinux 0x183fa88b mempool_alloc_slab +EXPORT_SYMBOL vmlinux 0x188e7610 igrab +EXPORT_SYMBOL vmlinux 0x18b85491 sunrpc_cache_lookup +EXPORT_SYMBOL vmlinux 0x18c89000 add_to_page_cache_locked +EXPORT_SYMBOL vmlinux 0x18dc5ed8 dput +EXPORT_SYMBOL vmlinux 0x19005594 blk_queue_prep_rq +EXPORT_SYMBOL vmlinux 0x197d9706 cap_netlink_recv +EXPORT_SYMBOL vmlinux 0x199ed0cd net_disable_timestamp +EXPORT_SYMBOL vmlinux 0x19c837e9 inet_ioctl +EXPORT_SYMBOL vmlinux 0x19d1aee4 scsi_mode_sense +EXPORT_SYMBOL vmlinux 0x19fbff52 iov_iter_copy_from_user_atomic +EXPORT_SYMBOL vmlinux 0x1a14c83f inet_frags_exit_net +EXPORT_SYMBOL vmlinux 0x1a50799d inode_needs_sync +EXPORT_SYMBOL vmlinux 0x1a65f4ad __arm_ioremap_pfn +EXPORT_SYMBOL vmlinux 0x1a7a3e61 pci_unmap_rom +EXPORT_SYMBOL vmlinux 0x1a7f2f4f scsi_dma_unmap +EXPORT_SYMBOL vmlinux 0x1ace138d bitmap_allocate_region +EXPORT_SYMBOL vmlinux 0x1ad1f2e7 _memcpy_fromio +EXPORT_SYMBOL vmlinux 0x1ae8d7dc param_set_invbool +EXPORT_SYMBOL vmlinux 0x1aecd508 dma_async_memcpy_pg_to_pg +EXPORT_SYMBOL vmlinux 0x1b015d25 bitmap_parselist +EXPORT_SYMBOL vmlinux 0x1b1b1431 key_type_keyring +EXPORT_SYMBOL vmlinux 0x1b6314fd in_aton +EXPORT_SYMBOL vmlinux 0x1b9981cc set_irq_wake +EXPORT_SYMBOL vmlinux 0x1b9adca8 console_stop +EXPORT_SYMBOL vmlinux 0x1b9d4222 tcp_shutdown +EXPORT_SYMBOL vmlinux 0x1b9e0ff1 scsilun_to_int +EXPORT_SYMBOL vmlinux 0x1bb52f80 sock_no_recvmsg +EXPORT_SYMBOL vmlinux 0x1bf65e36 elevator_exit +EXPORT_SYMBOL vmlinux 0x1c0b0415 proc_dointvec_jiffies +EXPORT_SYMBOL vmlinux 0x1c0e51f2 key_link +EXPORT_SYMBOL vmlinux 0x1c160351 tcp_mtup_init +EXPORT_SYMBOL vmlinux 0x1c2402c6 ip_mc_dec_group +EXPORT_SYMBOL vmlinux 0x1c324357 idr_replace +EXPORT_SYMBOL vmlinux 0x1c45a83d pcim_iomap_regions +EXPORT_SYMBOL vmlinux 0x1c68c6bd nf_register_sockopt +EXPORT_SYMBOL vmlinux 0x1c814b54 pci_get_slot +EXPORT_SYMBOL vmlinux 0x1c89493a pci_dev_driver +EXPORT_SYMBOL vmlinux 0x1cacebec xfrm_state_register_afinfo +EXPORT_SYMBOL vmlinux 0x1cc6719a register_reboot_notifier +EXPORT_SYMBOL vmlinux 0x1ccf813d dma_async_memcpy_buf_to_buf +EXPORT_SYMBOL vmlinux 0x1cde4150 skb_copy_and_csum_dev +EXPORT_SYMBOL vmlinux 0x1d0aaf41 scsi_kmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x1da11820 __dev_get_by_name +EXPORT_SYMBOL vmlinux 0x1e0b6f79 journal_extend +EXPORT_SYMBOL vmlinux 0x1e10f533 kthread_create +EXPORT_SYMBOL vmlinux 0x1e49daa8 sg_init_one +EXPORT_SYMBOL vmlinux 0x1e6d26a8 strstr +EXPORT_SYMBOL vmlinux 0x1e78da84 __nla_put_nohdr +EXPORT_SYMBOL vmlinux 0x1ea347e1 scsi_host_get +EXPORT_SYMBOL vmlinux 0x1ecb9943 posix_acl_to_xattr +EXPORT_SYMBOL vmlinux 0x1edc9598 _atomic_dec_and_lock +EXPORT_SYMBOL vmlinux 0x1ef2e12b kobject_get +EXPORT_SYMBOL vmlinux 0x1efe283f __cap_full_set +EXPORT_SYMBOL vmlinux 0x1f0e2159 tcp_parse_options +EXPORT_SYMBOL vmlinux 0x1f437748 journal_force_commit +EXPORT_SYMBOL vmlinux 0x1f70d32d dma_cache_maint +EXPORT_SYMBOL vmlinux 0x1f7cc628 mempool_create +EXPORT_SYMBOL vmlinux 0x1f8a45b0 xfrm_state_walk +EXPORT_SYMBOL vmlinux 0x1fae7a0b wait_for_completion_timeout +EXPORT_SYMBOL vmlinux 0x1fc91fb2 request_irq +EXPORT_SYMBOL vmlinux 0x1fca0fce i2c_probe +EXPORT_SYMBOL vmlinux 0x1fe4d7a1 dst_discard +EXPORT_SYMBOL vmlinux 0x1ff9f7ad pagevec_lookup +EXPORT_SYMBOL vmlinux 0x20000329 simple_strtoul +EXPORT_SYMBOL vmlinux 0x20687458 set_user_nice +EXPORT_SYMBOL vmlinux 0x2094ff35 proc_symlink +EXPORT_SYMBOL vmlinux 0x20bf7b79 security_task_getsecid +EXPORT_SYMBOL vmlinux 0x211331fa __divsi3 +EXPORT_SYMBOL vmlinux 0x2129738f mb_cache_entry_free +EXPORT_SYMBOL vmlinux 0x214fbfef inet_unregister_protosw +EXPORT_SYMBOL vmlinux 0x215ebd78 bitrev16 +EXPORT_SYMBOL vmlinux 0x21e84e65 uart_add_one_port +EXPORT_SYMBOL vmlinux 0x21fb5473 skb_push +EXPORT_SYMBOL vmlinux 0x21fe6d79 generic_file_aio_read +EXPORT_SYMBOL vmlinux 0x222e7ce2 sysfs_streq +EXPORT_SYMBOL vmlinux 0x226e86a9 audit_log +EXPORT_SYMBOL vmlinux 0x22764b29 skb_find_text +EXPORT_SYMBOL vmlinux 0x2288378f system_state +EXPORT_SYMBOL vmlinux 0x22947d6d alloc_etherdev_mq +EXPORT_SYMBOL vmlinux 0x229cfd5b gen_new_estimator +EXPORT_SYMBOL vmlinux 0x22b325d5 kd_mksound +EXPORT_SYMBOL vmlinux 0x22b6533b xfrm_sad_getinfo +EXPORT_SYMBOL vmlinux 0x231746b8 qdisc_destroy +EXPORT_SYMBOL vmlinux 0x231cf494 up_write +EXPORT_SYMBOL vmlinux 0x23269a13 strict_strtoul +EXPORT_SYMBOL vmlinux 0x236395bd sock_no_setsockopt +EXPORT_SYMBOL vmlinux 0x237341cd __elv_add_request +EXPORT_SYMBOL vmlinux 0x23838107 __down_write +EXPORT_SYMBOL vmlinux 0x23d70621 simple_transaction_release +EXPORT_SYMBOL vmlinux 0x23d9d5d7 module_put +EXPORT_SYMBOL vmlinux 0x23fd3028 vmalloc_node +EXPORT_SYMBOL vmlinux 0x240f3cc6 auth_domain_find +EXPORT_SYMBOL vmlinux 0x24128d7f __pagevec_release +EXPORT_SYMBOL vmlinux 0x2455c156 __clear_user +EXPORT_SYMBOL vmlinux 0x2459bbcc console_set_on_cmdline +EXPORT_SYMBOL vmlinux 0x24770b1f key_instantiate_and_link +EXPORT_SYMBOL vmlinux 0x249c44e8 scsi_device_lookup +EXPORT_SYMBOL vmlinux 0x24c6b6a2 dma_sync_wait +EXPORT_SYMBOL vmlinux 0x24fdac79 wake_bit_function +EXPORT_SYMBOL vmlinux 0x24fff9fa gnet_stats_finish_copy +EXPORT_SYMBOL vmlinux 0x250113b4 memory_read_from_buffer +EXPORT_SYMBOL vmlinux 0x251574bf eth_header_cache +EXPORT_SYMBOL vmlinux 0x252b4301 nf_register_hook +EXPORT_SYMBOL vmlinux 0x2537bacb tcf_hash_destroy +EXPORT_SYMBOL vmlinux 0x254400d5 ethtool_op_get_flags +EXPORT_SYMBOL vmlinux 0x25570294 sysctl_ms_jiffies +EXPORT_SYMBOL vmlinux 0x256887e1 warn_slowpath +EXPORT_SYMBOL vmlinux 0x25813efa tcf_hash_create +EXPORT_SYMBOL vmlinux 0x25820c64 fs_overflowuid +EXPORT_SYMBOL vmlinux 0x258d31af journal_get_undo_access +EXPORT_SYMBOL vmlinux 0x25928c63 gen_replace_estimator +EXPORT_SYMBOL vmlinux 0x25ba121c mempool_resize +EXPORT_SYMBOL vmlinux 0x25e5c57a __scsi_alloc_queue +EXPORT_SYMBOL vmlinux 0x25fa6f17 wait_for_completion +EXPORT_SYMBOL vmlinux 0x261c1766 __backtrace +EXPORT_SYMBOL vmlinux 0x26477c07 __vmalloc +EXPORT_SYMBOL vmlinux 0x26500a2d search_binary_handler +EXPORT_SYMBOL vmlinux 0x265bb22c qdisc_reset +EXPORT_SYMBOL vmlinux 0x266110a6 kobject_del +EXPORT_SYMBOL vmlinux 0x267ea568 dmam_alloc_noncoherent +EXPORT_SYMBOL vmlinux 0x267fc65b __tasklet_hi_schedule +EXPORT_SYMBOL vmlinux 0x2687b0bc ip4_datagram_connect +EXPORT_SYMBOL vmlinux 0x26e64ce4 ___pskb_trim +EXPORT_SYMBOL vmlinux 0x26e76fb8 sysctl_udp_wmem_min +EXPORT_SYMBOL vmlinux 0x26ea655c inet_sock_destruct +EXPORT_SYMBOL vmlinux 0x272e7488 cond_resched_softirq +EXPORT_SYMBOL vmlinux 0x27412c5f blk_queue_resize_tags +EXPORT_SYMBOL vmlinux 0x2765b034 neigh_seq_stop +EXPORT_SYMBOL vmlinux 0x27864d57 memparse +EXPORT_SYMBOL vmlinux 0x2794acc7 get_super +EXPORT_SYMBOL vmlinux 0x27a9a7eb ns_to_timespec +EXPORT_SYMBOL vmlinux 0x27bbf221 disable_irq_nosync +EXPORT_SYMBOL vmlinux 0x27c61ece qdisc_put_stab +EXPORT_SYMBOL vmlinux 0x27d66ecd vmap +EXPORT_SYMBOL vmlinux 0x27f293f4 iw_handler_set_thrspy +EXPORT_SYMBOL vmlinux 0x27f6413a register_console +EXPORT_SYMBOL vmlinux 0x28118cb6 __get_user_1 +EXPORT_SYMBOL vmlinux 0x2846deee request_key_with_auxdata +EXPORT_SYMBOL vmlinux 0x285ac517 strict_strtoll +EXPORT_SYMBOL vmlinux 0x2861c394 inet_csk_destroy_sock +EXPORT_SYMBOL vmlinux 0x28942e4c tcp_poll +EXPORT_SYMBOL vmlinux 0x28a2ed02 scsi_build_sense_buffer +EXPORT_SYMBOL vmlinux 0x28dcf25c udplite_hash +EXPORT_SYMBOL vmlinux 0x28fbc3e9 sock_common_getsockopt +EXPORT_SYMBOL vmlinux 0x29148969 schedule_delayed_work +EXPORT_SYMBOL vmlinux 0x2919b156 xdr_decode_string_inplace +EXPORT_SYMBOL vmlinux 0x293096c4 i2c_clients_command +EXPORT_SYMBOL vmlinux 0x29537c9e alloc_chrdev_region +EXPORT_SYMBOL vmlinux 0x2975ba2c ethtool_op_get_link +EXPORT_SYMBOL vmlinux 0x298d5519 blk_queue_start_tag +EXPORT_SYMBOL vmlinux 0x29ac22fe kmem_cache_destroy +EXPORT_SYMBOL vmlinux 0x29b611aa scsi_bios_ptable +EXPORT_SYMBOL vmlinux 0x29bd4c46 __cap_init_eff_set +EXPORT_SYMBOL vmlinux 0x29d8e6d5 inet_csk_init_xmit_timers +EXPORT_SYMBOL vmlinux 0x29fb8f19 dev_set_mac_address +EXPORT_SYMBOL vmlinux 0x2a25b56e inet_proto_csum_replace4 +EXPORT_SYMBOL vmlinux 0x2a438f7d register_nls +EXPORT_SYMBOL vmlinux 0x2a579b1f blk_queue_hardsect_size +EXPORT_SYMBOL vmlinux 0x2a6931de i2c_del_adapter +EXPORT_SYMBOL vmlinux 0x2a874dff tcp_enter_memory_pressure +EXPORT_SYMBOL vmlinux 0x2a905686 skb_queue_head +EXPORT_SYMBOL vmlinux 0x2aa0e4fc strncasecmp +EXPORT_SYMBOL vmlinux 0x2ab49860 scsi_put_command +EXPORT_SYMBOL vmlinux 0x2ac88346 mii_check_gmii_support +EXPORT_SYMBOL vmlinux 0x2ae5072d file_update_time +EXPORT_SYMBOL vmlinux 0x2ae97a42 elevator_init +EXPORT_SYMBOL vmlinux 0x2af9516b pcim_iounmap_regions +EXPORT_SYMBOL vmlinux 0x2afa8997 remove_proc_entry +EXPORT_SYMBOL vmlinux 0x2b0ba2b0 scsi_sense_desc_find +EXPORT_SYMBOL vmlinux 0x2b1538c4 truncate_inode_pages +EXPORT_SYMBOL vmlinux 0x2b40baff __down_write_nested +EXPORT_SYMBOL vmlinux 0x2b56417a get_fs_type +EXPORT_SYMBOL vmlinux 0x2b570dc0 ida_pre_get +EXPORT_SYMBOL vmlinux 0x2b5f6cfc __brelse +EXPORT_SYMBOL vmlinux 0x2b9e71ea simple_rmdir +EXPORT_SYMBOL vmlinux 0x2ba613b4 __scm_send +EXPORT_SYMBOL vmlinux 0x2ba707a8 sysctl_tcp_low_latency +EXPORT_SYMBOL vmlinux 0x2c1512eb block_invalidatepage +EXPORT_SYMBOL vmlinux 0x2c57dc94 skb_prepare_seq_read +EXPORT_SYMBOL vmlinux 0x2c6c4c1e icmpv6_send +EXPORT_SYMBOL vmlinux 0x2c70243a auth_domain_lookup +EXPORT_SYMBOL vmlinux 0x2c74821f pci_get_bus_and_slot +EXPORT_SYMBOL vmlinux 0x2c8ef039 cancel_dirty_page +EXPORT_SYMBOL vmlinux 0x2ca1b10f pci_remove_bus +EXPORT_SYMBOL vmlinux 0x2cabb846 scsi_register_interface +EXPORT_SYMBOL vmlinux 0x2cb9a396 seq_lseek +EXPORT_SYMBOL vmlinux 0x2cd9e459 param_set_short +EXPORT_SYMBOL vmlinux 0x2d25ac47 __kfree_skb +EXPORT_SYMBOL vmlinux 0x2d42c485 scsi_scan_target +EXPORT_SYMBOL vmlinux 0x2d6507b5 _find_next_zero_bit_le +EXPORT_SYMBOL vmlinux 0x2d819d64 tty_unthrottle +EXPORT_SYMBOL vmlinux 0x2d89342a scsi_show_sense_hdr +EXPORT_SYMBOL vmlinux 0x2d8caf76 bio_kmalloc +EXPORT_SYMBOL vmlinux 0x2d8d7a0e nobh_writepage +EXPORT_SYMBOL vmlinux 0x2d959c3d pci_release_selected_regions +EXPORT_SYMBOL vmlinux 0x2d98ce3f blk_init_tags +EXPORT_SYMBOL vmlinux 0x2ddbd2c0 find_task_by_pid_ns +EXPORT_SYMBOL vmlinux 0x2de9f66f param_get_long +EXPORT_SYMBOL vmlinux 0x2e03bf1f neigh_resolve_output +EXPORT_SYMBOL vmlinux 0x2e2ce9e0 sysctl_tcp_syncookies +EXPORT_SYMBOL vmlinux 0x2e4a39f8 sysctl_udp_mem +EXPORT_SYMBOL vmlinux 0x2e5c61f8 xfrm_state_delete_tunnel +EXPORT_SYMBOL vmlinux 0x2eec63c9 xdr_encode_netobj +EXPORT_SYMBOL vmlinux 0x2f3a62ad sock_no_mmap +EXPORT_SYMBOL vmlinux 0x2f48b77c scsi_dma_map +EXPORT_SYMBOL vmlinux 0x2f5d58af set_page_dirty +EXPORT_SYMBOL vmlinux 0x2fca29cb inet_accept +EXPORT_SYMBOL vmlinux 0x3009608f __lock_buffer +EXPORT_SYMBOL vmlinux 0x30123eb5 icmpv6_statistics +EXPORT_SYMBOL vmlinux 0x3045cfa1 ip_generic_getfrag +EXPORT_SYMBOL vmlinux 0x305ab72e simple_rename +EXPORT_SYMBOL vmlinux 0x30648b9d mii_ethtool_sset +EXPORT_SYMBOL vmlinux 0x308bab79 scsi_block_requests +EXPORT_SYMBOL vmlinux 0x30a8835b sockfd_lookup +EXPORT_SYMBOL vmlinux 0x30e74134 tty_termios_copy_hw +EXPORT_SYMBOL vmlinux 0x30f298a6 kmalloc_caches +EXPORT_SYMBOL vmlinux 0x3102737b inet_select_addr +EXPORT_SYMBOL vmlinux 0x310917fe sort +EXPORT_SYMBOL vmlinux 0x31191d30 inet_add_protocol +EXPORT_SYMBOL vmlinux 0x313341a3 _set_bit_le +EXPORT_SYMBOL vmlinux 0x313fe79b scsi_get_host_dev +EXPORT_SYMBOL vmlinux 0x3145216f pci_dev_present +EXPORT_SYMBOL vmlinux 0x3147857d default_red +EXPORT_SYMBOL vmlinux 0x315c65fd zlib_deflateInit2 +EXPORT_SYMBOL vmlinux 0x317cee73 sunrpc_cache_update +EXPORT_SYMBOL vmlinux 0x31b31f5c csum_partial_copy_nocheck +EXPORT_SYMBOL vmlinux 0x31c5aac3 blk_stop_queue +EXPORT_SYMBOL vmlinux 0x31e354ba dev_getbyhwaddr +EXPORT_SYMBOL vmlinux 0x31f027d8 register_chrdev +EXPORT_SYMBOL vmlinux 0x32075566 xdr_buf_from_iov +EXPORT_SYMBOL vmlinux 0x320daa6f cpu_sysdev_class +EXPORT_SYMBOL vmlinux 0x323222ba mutex_unlock +EXPORT_SYMBOL vmlinux 0x3233ef72 loop_register_transfer +EXPORT_SYMBOL vmlinux 0x3234b02d grab_cache_page_write_begin +EXPORT_SYMBOL vmlinux 0x325897ed kmem_cache_name +EXPORT_SYMBOL vmlinux 0x328a05f1 strncpy +EXPORT_SYMBOL vmlinux 0x32bdc0b1 ethtool_op_set_flags +EXPORT_SYMBOL vmlinux 0x32ce623a sg_last +EXPORT_SYMBOL vmlinux 0x32d6aca2 devm_ioremap_nocache +EXPORT_SYMBOL vmlinux 0x33143e39 skb_make_writable +EXPORT_SYMBOL vmlinux 0x332052f6 xfrm_policy_insert +EXPORT_SYMBOL vmlinux 0x3360a963 param_set_ulong +EXPORT_SYMBOL vmlinux 0x3363cd22 input_set_keycode +EXPORT_SYMBOL vmlinux 0x3366206b iw_handler_get_spy +EXPORT_SYMBOL vmlinux 0x338b4b79 pagecache_write_end +EXPORT_SYMBOL vmlinux 0x339cd01f journal_update_format +EXPORT_SYMBOL vmlinux 0x341d804b sock_no_accept +EXPORT_SYMBOL vmlinux 0x3437149b dst_alloc +EXPORT_SYMBOL vmlinux 0x3437ff14 vfs_permission +EXPORT_SYMBOL vmlinux 0x3438b356 blk_queue_end_tag +EXPORT_SYMBOL vmlinux 0x3473ed7a scsi_free_host_dev +EXPORT_SYMBOL vmlinux 0x34779780 release_sock +EXPORT_SYMBOL vmlinux 0x348e2a0d f_setown +EXPORT_SYMBOL vmlinux 0x34908c14 print_hex_dump_bytes +EXPORT_SYMBOL vmlinux 0x34978100 input_close_device +EXPORT_SYMBOL vmlinux 0x349cba85 strchr +EXPORT_SYMBOL vmlinux 0x34cd6d53 neigh_changeaddr +EXPORT_SYMBOL vmlinux 0x351f63f1 __skb_checksum_complete +EXPORT_SYMBOL vmlinux 0x35326646 key_validate +EXPORT_SYMBOL vmlinux 0x353e3fa5 __get_user_4 +EXPORT_SYMBOL vmlinux 0x3561e266 inet_addr_type +EXPORT_SYMBOL vmlinux 0x359103fe bioset_create +EXPORT_SYMBOL vmlinux 0x3593727a input_flush_device +EXPORT_SYMBOL vmlinux 0x35c4886c clear_bdi_congested +EXPORT_SYMBOL vmlinux 0x35d74067 cfi_varsize_frob +EXPORT_SYMBOL vmlinux 0x35f00f5f dma_async_device_unregister +EXPORT_SYMBOL vmlinux 0x35f18272 scsi_device_quiesce +EXPORT_SYMBOL vmlinux 0x35f99919 pci_remove_bus_device +EXPORT_SYMBOL vmlinux 0x360b1afe probe_irq_mask +EXPORT_SYMBOL vmlinux 0x363ad247 cap_set_effective +EXPORT_SYMBOL vmlinux 0x366bdeaa init_timer +EXPORT_SYMBOL vmlinux 0x3675917d uart_match_port +EXPORT_SYMBOL vmlinux 0x36991d3a tty_register_device +EXPORT_SYMBOL vmlinux 0x36aa8254 nla_reserve +EXPORT_SYMBOL vmlinux 0x36d021a6 may_umount +EXPORT_SYMBOL vmlinux 0x36e47222 remove_wait_queue +EXPORT_SYMBOL vmlinux 0x36f3361d uart_write_wakeup +EXPORT_SYMBOL vmlinux 0x36fe3b14 ip6_frag_match +EXPORT_SYMBOL vmlinux 0x370a67c3 ilookup +EXPORT_SYMBOL vmlinux 0x371273a5 nf_log_register +EXPORT_SYMBOL vmlinux 0x371c98f5 blk_register_region +EXPORT_SYMBOL vmlinux 0x371e6002 neigh_for_each +EXPORT_SYMBOL vmlinux 0x3744cf36 vmalloc_to_pfn +EXPORT_SYMBOL vmlinux 0x37458bab journal_unlock_updates +EXPORT_SYMBOL vmlinux 0x374ed073 scnprintf +EXPORT_SYMBOL vmlinux 0x3750425e blk_start_queueing +EXPORT_SYMBOL vmlinux 0x37728f0b mnt_unpin +EXPORT_SYMBOL vmlinux 0x3781ff61 tcp_disconnect +EXPORT_SYMBOL vmlinux 0x37a035c0 filp_open +EXPORT_SYMBOL vmlinux 0x37af6a0a abort_exclusive_wait +EXPORT_SYMBOL vmlinux 0x37befc70 jiffies_to_msecs +EXPORT_SYMBOL vmlinux 0x37c9c485 save_mount_options +EXPORT_SYMBOL vmlinux 0x37e74642 get_jiffies_64 +EXPORT_SYMBOL vmlinux 0x37f59c8e neigh_ifdown +EXPORT_SYMBOL vmlinux 0x37feda2f pci_lost_interrupt +EXPORT_SYMBOL vmlinux 0x3808474e init_special_inode +EXPORT_SYMBOL vmlinux 0x380c8e6e redirty_page_for_writepage +EXPORT_SYMBOL vmlinux 0x382b3848 generic_file_splice_write_nolock +EXPORT_SYMBOL vmlinux 0x38329efa arp_create +EXPORT_SYMBOL vmlinux 0x383d1175 pci_dev_get +EXPORT_SYMBOL vmlinux 0x3872e699 nf_unregister_hooks +EXPORT_SYMBOL vmlinux 0x387c0967 vfs_lstat +EXPORT_SYMBOL vmlinux 0x388546c9 simple_statfs +EXPORT_SYMBOL vmlinux 0x388f9128 xfrm_state_walk_done +EXPORT_SYMBOL vmlinux 0x38a5c4e7 svc_authenticate +EXPORT_SYMBOL vmlinux 0x38d54d4f inet_dgram_connect +EXPORT_SYMBOL vmlinux 0x38e8378d pgprot_kernel +EXPORT_SYMBOL vmlinux 0x38eed2f7 journal_abort +EXPORT_SYMBOL vmlinux 0x3942a691 prepare_binprm +EXPORT_SYMBOL vmlinux 0x39442c9b sync_inode +EXPORT_SYMBOL vmlinux 0x395141f1 register_sysctl_table +EXPORT_SYMBOL vmlinux 0x3980aac1 unregister_reboot_notifier +EXPORT_SYMBOL vmlinux 0x399e35d2 iov_iter_copy_from_user +EXPORT_SYMBOL vmlinux 0x39ab4967 task_nice +EXPORT_SYMBOL vmlinux 0x3a16c59e tcf_exts_destroy +EXPORT_SYMBOL vmlinux 0x3a174487 rtnl_notify +EXPORT_SYMBOL vmlinux 0x3a2204c6 security_netlink_recv +EXPORT_SYMBOL vmlinux 0x3a2e30c2 copy_io_context +EXPORT_SYMBOL vmlinux 0x3a32e69d unregister_netdev +EXPORT_SYMBOL vmlinux 0x3a39fe38 kset_unregister +EXPORT_SYMBOL vmlinux 0x3a59351b netdev_boot_setup_check +EXPORT_SYMBOL vmlinux 0x3a88ea52 xdr_read_pages +EXPORT_SYMBOL vmlinux 0x3a94d19b simple_set_mnt +EXPORT_SYMBOL vmlinux 0x3a9b6fb9 blk_unregister_region +EXPORT_SYMBOL vmlinux 0x3ab2d174 down_killable +EXPORT_SYMBOL vmlinux 0x3adc15b9 posix_acl_from_mode +EXPORT_SYMBOL vmlinux 0x3ae21462 __kill_fasync +EXPORT_SYMBOL vmlinux 0x3ae831b6 kref_init +EXPORT_SYMBOL vmlinux 0x3b0242f3 key_task_permission +EXPORT_SYMBOL vmlinux 0x3b1bcc6a __xfrm_decode_session +EXPORT_SYMBOL vmlinux 0x3b1ce514 blk_requeue_request +EXPORT_SYMBOL vmlinux 0x3b230c23 nf_ip6_checksum +EXPORT_SYMBOL vmlinux 0x3b34b8e9 in6_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0x3b3f629e posix_unblock_lock +EXPORT_SYMBOL vmlinux 0x3b8ff146 input_unregister_handler +EXPORT_SYMBOL vmlinux 0x3bb6a0c2 journal_dirty_data +EXPORT_SYMBOL vmlinux 0x3bbade81 sock_alloc_send_skb +EXPORT_SYMBOL vmlinux 0x3bd1b1f6 msecs_to_jiffies +EXPORT_SYMBOL vmlinux 0x3c1ebc0d task_pgrp_nr_ns +EXPORT_SYMBOL vmlinux 0x3c281933 new_inode +EXPORT_SYMBOL vmlinux 0x3c2c5af5 sprintf +EXPORT_SYMBOL vmlinux 0x3c3a2f09 do_splice_to +EXPORT_SYMBOL vmlinux 0x3c3fd326 read_cache_page +EXPORT_SYMBOL vmlinux 0x3c81e01c blk_alloc_queue +EXPORT_SYMBOL vmlinux 0x3c84aac4 pci_bus_read_config_word +EXPORT_SYMBOL vmlinux 0x3c9d1211 string_get_size +EXPORT_SYMBOL vmlinux 0x3cb8a495 param_get_string +EXPORT_SYMBOL vmlinux 0x3cc0a3bb xfrm_spd_getinfo +EXPORT_SYMBOL vmlinux 0x3cd45345 pci_request_region +EXPORT_SYMBOL vmlinux 0x3ce4ca6f disable_irq +EXPORT_SYMBOL vmlinux 0x3d1d12d6 clocksource_register +EXPORT_SYMBOL vmlinux 0x3d3bb19b fput +EXPORT_SYMBOL vmlinux 0x3d3c540f elf_hwcap +EXPORT_SYMBOL vmlinux 0x3d68bd4b flow_cache_genid +EXPORT_SYMBOL vmlinux 0x3d70b49a ll_rw_block +EXPORT_SYMBOL vmlinux 0x3da44d1a scsi_calculate_bounce_limit +EXPORT_SYMBOL vmlinux 0x3daeb03d dma_unmap_sg +EXPORT_SYMBOL vmlinux 0x3deb88f3 scsi_device_resume +EXPORT_SYMBOL vmlinux 0x3df4a6d2 i2c_master_send +EXPORT_SYMBOL vmlinux 0x3df90950 make_bad_inode +EXPORT_SYMBOL vmlinux 0x3e222e01 dma_mmap_coherent +EXPORT_SYMBOL vmlinux 0x3e2d1f60 ide_end_request +EXPORT_SYMBOL vmlinux 0x3e383385 nf_hooks +EXPORT_SYMBOL vmlinux 0x3e40a9cb current_fs_time +EXPORT_SYMBOL vmlinux 0x3e45e9ff register_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x3e6caebd add_wait_queue_exclusive +EXPORT_SYMBOL vmlinux 0x3e821f10 pci_enable_device +EXPORT_SYMBOL vmlinux 0x3e83d806 xdr_buf_subsegment +EXPORT_SYMBOL vmlinux 0x3e9dc0e5 bdevname +EXPORT_SYMBOL vmlinux 0x3ecca66a pcie_get_readrq +EXPORT_SYMBOL vmlinux 0x3ed63055 zlib_inflateReset +EXPORT_SYMBOL vmlinux 0x3ee916c1 scsi_execute_req +EXPORT_SYMBOL vmlinux 0x3f1b1e1e tcf_hash_check +EXPORT_SYMBOL vmlinux 0x3f206e33 pid_task +EXPORT_SYMBOL vmlinux 0x3f4547a7 put_unused_fd +EXPORT_SYMBOL vmlinux 0x3f5f7759 end_page_writeback +EXPORT_SYMBOL vmlinux 0x3f7a4454 dmam_free_coherent +EXPORT_SYMBOL vmlinux 0x3fe34bda dma_release_from_coherent +EXPORT_SYMBOL vmlinux 0x3ff62317 local_bh_disable +EXPORT_SYMBOL vmlinux 0x40123aeb idr_for_each +EXPORT_SYMBOL vmlinux 0x401b4945 xfrm_bundle_ok +EXPORT_SYMBOL vmlinux 0x4036b281 dev_mc_sync +EXPORT_SYMBOL vmlinux 0x403e687f devm_free_irq +EXPORT_SYMBOL vmlinux 0x4059792f print_hex_dump +EXPORT_SYMBOL vmlinux 0x405c1144 get_seconds +EXPORT_SYMBOL vmlinux 0x407136b1 __put_user_8 +EXPORT_SYMBOL vmlinux 0x4088d4f1 skb_seq_read +EXPORT_SYMBOL vmlinux 0x408d9244 find_vma +EXPORT_SYMBOL vmlinux 0x409873e3 tty_termios_baud_rate +EXPORT_SYMBOL vmlinux 0x409fe097 neigh_connected_output +EXPORT_SYMBOL vmlinux 0x40a41d24 auth_unix_add_addr +EXPORT_SYMBOL vmlinux 0x40a6f522 __arm_ioremap +EXPORT_SYMBOL vmlinux 0x40f07981 __ashldi3 +EXPORT_SYMBOL vmlinux 0x40f9e667 dentry_open +EXPORT_SYMBOL vmlinux 0x4101a975 ide_fixstring +EXPORT_SYMBOL vmlinux 0x4106aff1 simple_pin_fs +EXPORT_SYMBOL vmlinux 0x410d4458 proc_mkdir +EXPORT_SYMBOL vmlinux 0x41166725 inet_frags_init_net +EXPORT_SYMBOL vmlinux 0x411b52c1 __skb_checksum_complete_head +EXPORT_SYMBOL vmlinux 0x412ddc0c dcache_lock +EXPORT_SYMBOL vmlinux 0x412dea23 uart_remove_one_port +EXPORT_SYMBOL vmlinux 0x413bda11 bh_submit_read +EXPORT_SYMBOL vmlinux 0x41482d8b strndup_user +EXPORT_SYMBOL vmlinux 0x416983d9 netdev_fix_features +EXPORT_SYMBOL vmlinux 0x4185cf4b radix_tree_lookup_slot +EXPORT_SYMBOL vmlinux 0x4188d439 neigh_rand_reach_time +EXPORT_SYMBOL vmlinux 0x41c26d5d pci_release_region +EXPORT_SYMBOL vmlinux 0x41c87ca3 scsi_prep_return +EXPORT_SYMBOL vmlinux 0x41cb001c udp_lib_getsockopt +EXPORT_SYMBOL vmlinux 0x41d220df blk_queue_max_sectors +EXPORT_SYMBOL vmlinux 0x41e235cf xdr_write_pages +EXPORT_SYMBOL vmlinux 0x41f3235f blk_sync_queue +EXPORT_SYMBOL vmlinux 0x4203f788 iw_handler_set_spy +EXPORT_SYMBOL vmlinux 0x42042489 journal_init_dev +EXPORT_SYMBOL vmlinux 0x420f437d d_alloc +EXPORT_SYMBOL vmlinux 0x4211c3c1 zlib_inflateInit2 +EXPORT_SYMBOL vmlinux 0x421ecc11 dcache_dir_close +EXPORT_SYMBOL vmlinux 0x42224298 sscanf +EXPORT_SYMBOL vmlinux 0x423e3726 alloc_file +EXPORT_SYMBOL vmlinux 0x4250b629 del_mtd_partitions +EXPORT_SYMBOL vmlinux 0x42768eea ndisc_mc_map +EXPORT_SYMBOL vmlinux 0x427a6005 i2c_detach_client +EXPORT_SYMBOL vmlinux 0x42e58dbb mb_cache_create +EXPORT_SYMBOL vmlinux 0x430205aa __sg_alloc_table +EXPORT_SYMBOL vmlinux 0x4302d0eb free_pages +EXPORT_SYMBOL vmlinux 0x431cb032 posix_acl_permission +EXPORT_SYMBOL vmlinux 0x434fa55c release_console_sem +EXPORT_SYMBOL vmlinux 0x4358431f ip_cmsg_recv +EXPORT_SYMBOL vmlinux 0x436a5a2e tty_flip_buffer_push +EXPORT_SYMBOL vmlinux 0x437af4fa scsi_report_device_reset +EXPORT_SYMBOL vmlinux 0x43a276cd do_mmap_pgoff +EXPORT_SYMBOL vmlinux 0x4406dc20 nf_getsockopt +EXPORT_SYMBOL vmlinux 0x44161c19 unregister_shrinker +EXPORT_SYMBOL vmlinux 0x44314efb radix_tree_gang_lookup_tag_slot +EXPORT_SYMBOL vmlinux 0x444779c4 nla_find +EXPORT_SYMBOL vmlinux 0x44643b93 __aeabi_lmul +EXPORT_SYMBOL vmlinux 0x447c0191 splice_direct_to_actor +EXPORT_SYMBOL vmlinux 0x448c5043 bdi_register_dev +EXPORT_SYMBOL vmlinux 0x44902581 i2c_smbus_read_block_data +EXPORT_SYMBOL vmlinux 0x44b911c3 rb_replace_node +EXPORT_SYMBOL vmlinux 0x44c214d1 __wake_up_bit +EXPORT_SYMBOL vmlinux 0x44d94a4d bio_copy_user +EXPORT_SYMBOL vmlinux 0x44da5d0f __csum_ipv6_magic +EXPORT_SYMBOL vmlinux 0x44e9a829 match_token +EXPORT_SYMBOL vmlinux 0x44ec18ad vfs_rmdir +EXPORT_SYMBOL vmlinux 0x44f80ff0 udp_poll +EXPORT_SYMBOL vmlinux 0x44ff112e tcp_setsockopt +EXPORT_SYMBOL vmlinux 0x450be4ae tty_free_termios +EXPORT_SYMBOL vmlinux 0x45390c22 file_permission +EXPORT_SYMBOL vmlinux 0x45485b52 pci_release_regions +EXPORT_SYMBOL vmlinux 0x45604dd8 scsi_device_set_state +EXPORT_SYMBOL vmlinux 0x4580fe5f try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x45883f93 xrlim_allow +EXPORT_SYMBOL vmlinux 0x45a55ec8 __iounmap +EXPORT_SYMBOL vmlinux 0x45bda0d5 system_serial_low +EXPORT_SYMBOL vmlinux 0x45f553fb skb_over_panic +EXPORT_SYMBOL vmlinux 0x4606efd9 scm_fp_dup +EXPORT_SYMBOL vmlinux 0x46215020 con_set_default_unimap +EXPORT_SYMBOL vmlinux 0x462a2e75 match_strlcpy +EXPORT_SYMBOL vmlinux 0x46d3b28c __div0 +EXPORT_SYMBOL vmlinux 0x4700720c xdr_enter_page +EXPORT_SYMBOL vmlinux 0x4719ba4e kfifo_free +EXPORT_SYMBOL vmlinux 0x472665ca call_usermodehelper_setkeys +EXPORT_SYMBOL vmlinux 0x472d2a9a radix_tree_lookup +EXPORT_SYMBOL vmlinux 0x4746e074 dev_mc_unsync +EXPORT_SYMBOL vmlinux 0x475100c2 inet_get_local_port_range +EXPORT_SYMBOL vmlinux 0x4773a2b0 alloc_tty_driver +EXPORT_SYMBOL vmlinux 0x47b4e009 blkdev_dequeue_request +EXPORT_SYMBOL vmlinux 0x47c5fe1a nla_put +EXPORT_SYMBOL vmlinux 0x47c62d70 xfrm_policy_flush +EXPORT_SYMBOL vmlinux 0x47f757de elf_platform +EXPORT_SYMBOL vmlinux 0x48034724 zlib_deflateReset +EXPORT_SYMBOL vmlinux 0x4814d5a5 unload_nls +EXPORT_SYMBOL vmlinux 0x48287021 d_instantiate +EXPORT_SYMBOL vmlinux 0x4828be8e vfs_mknod +EXPORT_SYMBOL vmlinux 0x4859b8bb rtc_year_days +EXPORT_SYMBOL vmlinux 0x485aafa6 sock_i_ino +EXPORT_SYMBOL vmlinux 0x486b6407 hweight64 +EXPORT_SYMBOL vmlinux 0x4870ab12 svc_reserve +EXPORT_SYMBOL vmlinux 0x48994cfd __xfrm_state_delete +EXPORT_SYMBOL vmlinux 0x48a5b067 __machine_arch_type +EXPORT_SYMBOL vmlinux 0x48ad41c7 xfrm6_rcv +EXPORT_SYMBOL vmlinux 0x48dcfd67 init_task +EXPORT_SYMBOL vmlinux 0x48f9f12d complete_all +EXPORT_SYMBOL vmlinux 0x4928b8df journal_check_available_features +EXPORT_SYMBOL vmlinux 0x493e25e1 udp_hash +EXPORT_SYMBOL vmlinux 0x493e943d netif_device_detach +EXPORT_SYMBOL vmlinux 0x49603fb8 security_sb_copy_data +EXPORT_SYMBOL vmlinux 0x49664f30 freeze_bdev +EXPORT_SYMBOL vmlinux 0x496c56fd pci_pme_capable +EXPORT_SYMBOL vmlinux 0x498ef45c unregister_nls +EXPORT_SYMBOL vmlinux 0x49ab59ac page_put_link +EXPORT_SYMBOL vmlinux 0x49d7d9ec vfs_create +EXPORT_SYMBOL vmlinux 0x49dabdfe xfrm_find_acq_byseq +EXPORT_SYMBOL vmlinux 0x49f257c7 sock_rfree +EXPORT_SYMBOL vmlinux 0x49fbe8ac dma_async_client_register +EXPORT_SYMBOL vmlinux 0x4a1265f2 __seq_open_private +EXPORT_SYMBOL vmlinux 0x4a358252 __bitmap_subset +EXPORT_SYMBOL vmlinux 0x4a4198d2 netdev_rx_csum_fault +EXPORT_SYMBOL vmlinux 0x4a6fa03f xfrm_state_lookup +EXPORT_SYMBOL vmlinux 0x4a95b910 skb_split +EXPORT_SYMBOL vmlinux 0x4a971ec7 radix_tree_delete +EXPORT_SYMBOL vmlinux 0x4ab00459 sb_min_blocksize +EXPORT_SYMBOL vmlinux 0x4ab1b67f xdr_init_encode +EXPORT_SYMBOL vmlinux 0x4ac7145f dev_load +EXPORT_SYMBOL vmlinux 0x4acfd8ad down_interruptible +EXPORT_SYMBOL vmlinux 0x4ad93d90 inet_sk_rebuild_header +EXPORT_SYMBOL vmlinux 0x4ad9a6fe xscale_mc_copy_user_page +EXPORT_SYMBOL vmlinux 0x4aea4791 __strncpy_from_user +EXPORT_SYMBOL vmlinux 0x4afe9a77 scsi_partsize +EXPORT_SYMBOL vmlinux 0x4aff1d3f journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0x4b0baaed submit_bio +EXPORT_SYMBOL vmlinux 0x4b0e8d9d pci_set_master +EXPORT_SYMBOL vmlinux 0x4b162e15 d_rehash +EXPORT_SYMBOL vmlinux 0x4b2e20eb __netdev_alloc_page +EXPORT_SYMBOL vmlinux 0x4b2f14b4 jiffies_to_timespec +EXPORT_SYMBOL vmlinux 0x4b34fbf5 block_all_signals +EXPORT_SYMBOL vmlinux 0x4b7b58e3 call_usermodehelper_setcleanup +EXPORT_SYMBOL vmlinux 0x4b8edde9 complete_and_exit +EXPORT_SYMBOL vmlinux 0x4b9f3684 kfifo_init +EXPORT_SYMBOL vmlinux 0x4bdcced9 copy_strings_kernel +EXPORT_SYMBOL vmlinux 0x4c09607e rt6_lookup +EXPORT_SYMBOL vmlinux 0x4c1182cb bitmap_scnprintf +EXPORT_SYMBOL vmlinux 0x4c374f17 inet_csk_clear_xmit_timers +EXPORT_SYMBOL vmlinux 0x4c5b9213 dev_unicast_unsync +EXPORT_SYMBOL vmlinux 0x4cbbd171 __bitmap_weight +EXPORT_SYMBOL vmlinux 0x4cc93afd i2c_smbus_xfer +EXPORT_SYMBOL vmlinux 0x4cea26e6 path_lookup +EXPORT_SYMBOL vmlinux 0x4cf020b0 scsi_set_medium_removal +EXPORT_SYMBOL vmlinux 0x4d0d163d copy_page +EXPORT_SYMBOL vmlinux 0x4d2e7bb1 set_page_dirty_lock +EXPORT_SYMBOL vmlinux 0x4d3c153f sigprocmask +EXPORT_SYMBOL vmlinux 0x4d6214d7 boot_tvec_bases +EXPORT_SYMBOL vmlinux 0x4d898341 elv_rb_del +EXPORT_SYMBOL vmlinux 0x4d8ae814 mii_ethtool_gset +EXPORT_SYMBOL vmlinux 0x4db05540 gnet_stats_copy_basic +EXPORT_SYMBOL vmlinux 0x4ddc4b9f utf8_mbtowc +EXPORT_SYMBOL vmlinux 0x4dec6038 memscan +EXPORT_SYMBOL vmlinux 0x4dedeb12 block_page_mkwrite +EXPORT_SYMBOL vmlinux 0x4df119fa __bitmap_parse +EXPORT_SYMBOL vmlinux 0x4e0009da idr_get_new_above +EXPORT_SYMBOL vmlinux 0x4e059bba inet_getname +EXPORT_SYMBOL vmlinux 0x4e2a3af2 free_buffer_head +EXPORT_SYMBOL vmlinux 0x4e3567f7 match_int +EXPORT_SYMBOL vmlinux 0x4e6e8ea7 fg_console +EXPORT_SYMBOL vmlinux 0x4e830a3e strnicmp +EXPORT_SYMBOL vmlinux 0x4ec6ffd3 blk_queue_max_phys_segments +EXPORT_SYMBOL vmlinux 0x4ef65946 sock_wfree +EXPORT_SYMBOL vmlinux 0x4efd0370 may_umount_tree +EXPORT_SYMBOL vmlinux 0x4f0ea0c0 up +EXPORT_SYMBOL vmlinux 0x4f10664b svc_seq_show +EXPORT_SYMBOL vmlinux 0x4f265881 drop_super +EXPORT_SYMBOL vmlinux 0x4f28eda1 d_instantiate_unique +EXPORT_SYMBOL vmlinux 0x4f31d80c d_validate +EXPORT_SYMBOL vmlinux 0x4f4ec390 tcp_timewait_state_process +EXPORT_SYMBOL vmlinux 0x4f544eea register_netdevice +EXPORT_SYMBOL vmlinux 0x4f5651c3 tcp_sockets_allocated +EXPORT_SYMBOL vmlinux 0x4f70521f dev_add_pack +EXPORT_SYMBOL vmlinux 0x4f780b76 unix_domain_find +EXPORT_SYMBOL vmlinux 0x5006eedd add_mtd_partitions +EXPORT_SYMBOL vmlinux 0x502698c0 generic_make_request +EXPORT_SYMBOL vmlinux 0x5051e6fc xfrm_prepare_input +EXPORT_SYMBOL vmlinux 0x505e6e8a xdr_encode_array2 +EXPORT_SYMBOL vmlinux 0x5069d66e skb_copy_datagram_from_iovec +EXPORT_SYMBOL vmlinux 0x5093fa82 _clear_bit_le +EXPORT_SYMBOL vmlinux 0x50a5f4ec sock_no_ioctl +EXPORT_SYMBOL vmlinux 0x50d02982 tcp_rcv_established +EXPORT_SYMBOL vmlinux 0x50d13b70 sk_stream_wait_close +EXPORT_SYMBOL vmlinux 0x5109d0b1 sb_has_dirty_inodes +EXPORT_SYMBOL vmlinux 0x51489446 unlock_new_inode +EXPORT_SYMBOL vmlinux 0x51493d94 finish_wait +EXPORT_SYMBOL vmlinux 0x514bc560 arp_xmit +EXPORT_SYMBOL vmlinux 0x514f9a32 __neigh_for_each_release +EXPORT_SYMBOL vmlinux 0x51908eb8 __raw_writesl +EXPORT_SYMBOL vmlinux 0x51ccad68 ip_route_me_harder +EXPORT_SYMBOL vmlinux 0x51cd47e2 groups_alloc +EXPORT_SYMBOL vmlinux 0x51dce73b xfrm_state_walk_init +EXPORT_SYMBOL vmlinux 0x51e8a9d2 call_usermodehelper_freeinfo +EXPORT_SYMBOL vmlinux 0x51ec2682 is_container_init +EXPORT_SYMBOL vmlinux 0x51ef33b8 kstrndup +EXPORT_SYMBOL vmlinux 0x52026cdf security_sb_parse_opts_str +EXPORT_SYMBOL vmlinux 0x521d7b1c __alloc_pages_internal +EXPORT_SYMBOL vmlinux 0x52354a0b mutex_trylock +EXPORT_SYMBOL vmlinux 0x524827cf redraw_screen +EXPORT_SYMBOL vmlinux 0x526efed0 __sk_dst_check +EXPORT_SYMBOL vmlinux 0x527edd88 block_is_partially_uptodate +EXPORT_SYMBOL vmlinux 0x52808922 tcf_exts_dump_stats +EXPORT_SYMBOL vmlinux 0x528c709d simple_read_from_buffer +EXPORT_SYMBOL vmlinux 0x52a58c24 ifla_policy +EXPORT_SYMBOL vmlinux 0x52b63231 tty_port_tty_set +EXPORT_SYMBOL vmlinux 0x532f2924 param_get_byte +EXPORT_SYMBOL vmlinux 0x53326531 mempool_alloc_pages +EXPORT_SYMBOL vmlinux 0x534910b6 tcp_make_synack +EXPORT_SYMBOL vmlinux 0x538383c0 unregister_inet6addr_notifier +EXPORT_SYMBOL vmlinux 0x538fc473 blk_start_queue +EXPORT_SYMBOL vmlinux 0x53ae8d14 vfs_readv +EXPORT_SYMBOL vmlinux 0x53c0767c sk_chk_filter +EXPORT_SYMBOL vmlinux 0x540936fd cache_check +EXPORT_SYMBOL vmlinux 0x541ce778 tty_schedule_flip +EXPORT_SYMBOL vmlinux 0x54290dc9 nla_validate +EXPORT_SYMBOL vmlinux 0x542f5179 inode_add_bytes +EXPORT_SYMBOL vmlinux 0x54460b1d request_firmware_nowait +EXPORT_SYMBOL vmlinux 0x544871ea sync_mapping_buffers +EXPORT_SYMBOL vmlinux 0x549b0aa1 check_disk_size_change +EXPORT_SYMBOL vmlinux 0x54a33eda sock_init_data +EXPORT_SYMBOL vmlinux 0x54c96932 tcp_rcv_state_process +EXPORT_SYMBOL vmlinux 0x54d42936 seq_printf +EXPORT_SYMBOL vmlinux 0x54df887c ipv6_getsockopt +EXPORT_SYMBOL vmlinux 0x54e6fcdd net_enable_timestamp +EXPORT_SYMBOL vmlinux 0x5514df46 sk_alloc +EXPORT_SYMBOL vmlinux 0x5545c676 filemap_fault +EXPORT_SYMBOL vmlinux 0x554ec53c i2c_smbus_read_byte +EXPORT_SYMBOL vmlinux 0x55696307 default_llseek +EXPORT_SYMBOL vmlinux 0x5584901d keyring_clear +EXPORT_SYMBOL vmlinux 0x5594be03 bitmap_remap +EXPORT_SYMBOL vmlinux 0x55c763f9 create_empty_buffers +EXPORT_SYMBOL vmlinux 0x55d692c3 nf_unregister_queue_handler +EXPORT_SYMBOL vmlinux 0x5614b010 xfrm_policy_walk_done +EXPORT_SYMBOL vmlinux 0x5615b07c deactivate_super +EXPORT_SYMBOL vmlinux 0x5635a60a vmalloc_user +EXPORT_SYMBOL vmlinux 0x56485850 netif_receive_skb +EXPORT_SYMBOL vmlinux 0x5649a746 clear_inode +EXPORT_SYMBOL vmlinux 0x567dc01e skb_realloc_headroom +EXPORT_SYMBOL vmlinux 0x569ccb1f __invalidate_device +EXPORT_SYMBOL vmlinux 0x56c8799d scsi_kunmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x56f2569c get_sb_single +EXPORT_SYMBOL vmlinux 0x570a2867 __nla_put +EXPORT_SYMBOL vmlinux 0x571f03c6 cpu_xscale_set_pte_ext +EXPORT_SYMBOL vmlinux 0x5725b937 auth_unix_forget_old +EXPORT_SYMBOL vmlinux 0x572e85d4 blk_lookup_devt +EXPORT_SYMBOL vmlinux 0x57465025 scsi_is_target_device +EXPORT_SYMBOL vmlinux 0x5754ac47 bd_claim +EXPORT_SYMBOL vmlinux 0x57806f2f per_cpu____irq_regs +EXPORT_SYMBOL vmlinux 0x57816d69 skb_copy_expand +EXPORT_SYMBOL vmlinux 0x57963594 bio_endio +EXPORT_SYMBOL vmlinux 0x57a628b1 sync_page_range +EXPORT_SYMBOL vmlinux 0x57a6504e vsnprintf +EXPORT_SYMBOL vmlinux 0x5824e453 seq_path +EXPORT_SYMBOL vmlinux 0x583692b8 key_negate_and_link +EXPORT_SYMBOL vmlinux 0x5838f6c9 rtc_valid_tm +EXPORT_SYMBOL vmlinux 0x584496c8 notify_change +EXPORT_SYMBOL vmlinux 0x588699c4 nf_afinfo +EXPORT_SYMBOL vmlinux 0x58978f2f block_sync_page +EXPORT_SYMBOL vmlinux 0x58bac7a6 unmap_mapping_range +EXPORT_SYMBOL vmlinux 0x58e0c277 key_put +EXPORT_SYMBOL vmlinux 0x58fe0a67 mb_cache_entry_release +EXPORT_SYMBOL vmlinux 0x591d6a4e blk_queue_make_request +EXPORT_SYMBOL vmlinux 0x592e2805 eth_header_parse +EXPORT_SYMBOL vmlinux 0x5934392b fb_register_client +EXPORT_SYMBOL vmlinux 0x594bf15b ioport_map +EXPORT_SYMBOL vmlinux 0x594e1317 __modsi3 +EXPORT_SYMBOL vmlinux 0x5950bdf9 inet_stream_ops +EXPORT_SYMBOL vmlinux 0x59706f79 nf_log_unregister_pf +EXPORT_SYMBOL vmlinux 0x5983aec6 blk_queue_invalidate_tags +EXPORT_SYMBOL vmlinux 0x59d696b6 register_module_notifier +EXPORT_SYMBOL vmlinux 0x59d8223a ioport_resource +EXPORT_SYMBOL vmlinux 0x59e5070d __do_div64 +EXPORT_SYMBOL vmlinux 0x59f94415 blk_queue_update_dma_alignment +EXPORT_SYMBOL vmlinux 0x5a091d5d generic_file_open +EXPORT_SYMBOL vmlinux 0x5a3df66a sk_reset_timer +EXPORT_SYMBOL vmlinux 0x5a3ea64b pci_request_regions +EXPORT_SYMBOL vmlinux 0x5a7127df sk_common_release +EXPORT_SYMBOL vmlinux 0x5a744b86 netlink_set_nonroot +EXPORT_SYMBOL vmlinux 0x5aa1da70 blk_verify_command +EXPORT_SYMBOL vmlinux 0x5aa9328e __neigh_event_send +EXPORT_SYMBOL vmlinux 0x5aeb3066 generic_file_buffered_write +EXPORT_SYMBOL vmlinux 0x5b19634d div_s64_rem +EXPORT_SYMBOL vmlinux 0x5b2810f9 mem_map +EXPORT_SYMBOL vmlinux 0x5b65a8e8 scsi_remove_host +EXPORT_SYMBOL vmlinux 0x5b714f30 ethtool_op_get_tx_csum +EXPORT_SYMBOL vmlinux 0x5ba6146a sock_get_timestampns +EXPORT_SYMBOL vmlinux 0x5ba75b3f pci_bus_size_bridges +EXPORT_SYMBOL vmlinux 0x5bc5c5b2 force_sig +EXPORT_SYMBOL vmlinux 0x5c563452 generic_shutdown_super +EXPORT_SYMBOL vmlinux 0x5c586fd5 pcim_pin_device +EXPORT_SYMBOL vmlinux 0x5c673bc8 tty_mutex +EXPORT_SYMBOL vmlinux 0x5c695894 i2c_register_driver +EXPORT_SYMBOL vmlinux 0x5c6af6bf get_sb_bdev +EXPORT_SYMBOL vmlinux 0x5c9284a0 processor_id +EXPORT_SYMBOL vmlinux 0x5cee8bdd misc_register +EXPORT_SYMBOL vmlinux 0x5d07353b sync_dirty_buffer +EXPORT_SYMBOL vmlinux 0x5d078730 tcp_read_sock +EXPORT_SYMBOL vmlinux 0x5d2b5efd tty_port_tty_get +EXPORT_SYMBOL vmlinux 0x5d72af99 sk_release_kernel +EXPORT_SYMBOL vmlinux 0x5d7a107f netlink_kernel_release +EXPORT_SYMBOL vmlinux 0x5d8eeb19 directly_mappable_cdev_bdi +EXPORT_SYMBOL vmlinux 0x5da065a9 tcp_splice_read +EXPORT_SYMBOL vmlinux 0x5da334e0 blk_rq_append_bio +EXPORT_SYMBOL vmlinux 0x5daa6ce4 dcache_dir_open +EXPORT_SYMBOL vmlinux 0x5e225d78 tty_vhangup +EXPORT_SYMBOL vmlinux 0x5e262d4e set_device_ro +EXPORT_SYMBOL vmlinux 0x5e3f48db generic_removexattr +EXPORT_SYMBOL vmlinux 0x5ea520c5 tcp_select_initial_window +EXPORT_SYMBOL vmlinux 0x5ebb56fb down_read +EXPORT_SYMBOL vmlinux 0x5edd0762 bin2bcd +EXPORT_SYMBOL vmlinux 0x5f337a21 skb_dma_unmap +EXPORT_SYMBOL vmlinux 0x5f48cf1d bdi_unregister +EXPORT_SYMBOL vmlinux 0x5f59a800 lock_rename +EXPORT_SYMBOL vmlinux 0x5f5a15b5 qdisc_tree_decrease_qlen +EXPORT_SYMBOL vmlinux 0x5f725fc8 xfrm_unregister_type +EXPORT_SYMBOL vmlinux 0x5f754e5a memset +EXPORT_SYMBOL vmlinux 0x5fdcd406 wireless_send_event +EXPORT_SYMBOL vmlinux 0x5ffa8d8f i2c_smbus_process_call +EXPORT_SYMBOL vmlinux 0x600683d3 do_unblank_screen +EXPORT_SYMBOL vmlinux 0x6012abaa pcix_get_mmrbc +EXPORT_SYMBOL vmlinux 0x602d47c0 cancel_delayed_work_sync +EXPORT_SYMBOL vmlinux 0x608c2831 warn_on_slowpath +EXPORT_SYMBOL vmlinux 0x609010a3 try_to_release_page +EXPORT_SYMBOL vmlinux 0x609f1c7e synchronize_net +EXPORT_SYMBOL vmlinux 0x60a32ea9 pm_power_off +EXPORT_SYMBOL vmlinux 0x60a4efe2 ida_get_new +EXPORT_SYMBOL vmlinux 0x60b4e1cb xfrm_state_delete +EXPORT_SYMBOL vmlinux 0x60d57e4a ip6_frag_init +EXPORT_SYMBOL vmlinux 0x61593b72 __mod_timer +EXPORT_SYMBOL vmlinux 0x61662bef register_qdisc +EXPORT_SYMBOL vmlinux 0x617c20b4 free_netdev +EXPORT_SYMBOL vmlinux 0x617eeb94 __dst_free +EXPORT_SYMBOL vmlinux 0x618d8299 set_notify_swap_entry_free +EXPORT_SYMBOL vmlinux 0x61947924 i2c_put_adapter +EXPORT_SYMBOL vmlinux 0x61a99793 scsi_device_put +EXPORT_SYMBOL vmlinux 0x61a9f51e mapping_tagged +EXPORT_SYMBOL vmlinux 0x61aec1e8 seq_bitmap +EXPORT_SYMBOL vmlinux 0x61b7b126 simple_strtoull +EXPORT_SYMBOL vmlinux 0x61b82439 sock_recvmsg +EXPORT_SYMBOL vmlinux 0x61ec2621 d_path +EXPORT_SYMBOL vmlinux 0x626d1f52 load_nls_default +EXPORT_SYMBOL vmlinux 0x62737e1d sock_unregister +EXPORT_SYMBOL vmlinux 0x62827bec security_secctx_to_secid +EXPORT_SYMBOL vmlinux 0x6289c1e3 __lock_page +EXPORT_SYMBOL vmlinux 0x6318e9b0 sock_no_listen +EXPORT_SYMBOL vmlinux 0x634caa7f inet_sendmsg +EXPORT_SYMBOL vmlinux 0x6364e346 lookup_bdev +EXPORT_SYMBOL vmlinux 0x6396acbf tcp_prot +EXPORT_SYMBOL vmlinux 0x63a2cb03 get_sb_pseudo +EXPORT_SYMBOL vmlinux 0x63ad3e7a vfs_path_lookup +EXPORT_SYMBOL vmlinux 0x63b23d85 dcache_dir_lseek +EXPORT_SYMBOL vmlinux 0x63b8c624 remap_pfn_range +EXPORT_SYMBOL vmlinux 0x63bf6109 xfrm_policy_register_afinfo +EXPORT_SYMBOL vmlinux 0x63cb2a04 nonseekable_open +EXPORT_SYMBOL vmlinux 0x63ecad53 register_netdevice_notifier +EXPORT_SYMBOL vmlinux 0x63ee027b ethtool_op_set_tso +EXPORT_SYMBOL vmlinux 0x6403e338 tcp_memory_pressure +EXPORT_SYMBOL vmlinux 0x640a7078 posix_acl_create_masq +EXPORT_SYMBOL vmlinux 0x64108551 udp_sendmsg +EXPORT_SYMBOL vmlinux 0x64209cae kernel_sock_ioctl +EXPORT_SYMBOL vmlinux 0x64375f86 tcp_recvmsg +EXPORT_SYMBOL vmlinux 0x6480e797 xfrm_register_mode +EXPORT_SYMBOL vmlinux 0x64999478 congestion_wait +EXPORT_SYMBOL vmlinux 0x649bc786 skb_copy_bits +EXPORT_SYMBOL vmlinux 0x64b8afe3 tcp_proc_register +EXPORT_SYMBOL vmlinux 0x64d4e4bc find_lock_page +EXPORT_SYMBOL vmlinux 0x64f2981a request_key_async +EXPORT_SYMBOL vmlinux 0x6518ba68 journal_errno +EXPORT_SYMBOL vmlinux 0x651a4139 test_taint +EXPORT_SYMBOL vmlinux 0x652ceec8 tcp_v4_remember_stamp +EXPORT_SYMBOL vmlinux 0x65408378 zlib_inflate_blob +EXPORT_SYMBOL vmlinux 0x65414e67 dev_valid_name +EXPORT_SYMBOL vmlinux 0x6572fdfb set_irq_chip +EXPORT_SYMBOL vmlinux 0x659a7e34 input_register_handler +EXPORT_SYMBOL vmlinux 0x65a5c3a2 cpu_present_map +EXPORT_SYMBOL vmlinux 0x660fde89 netdev_set_master +EXPORT_SYMBOL vmlinux 0x661e6ec8 bioset_free +EXPORT_SYMBOL vmlinux 0x6656bf95 ioctl_by_bdev +EXPORT_SYMBOL vmlinux 0x668da8d5 zlib_inflateIncomp +EXPORT_SYMBOL vmlinux 0x668f77f9 tty_hung_up_p +EXPORT_SYMBOL vmlinux 0x66935d3a ethtool_op_set_tx_csum +EXPORT_SYMBOL vmlinux 0x66ab6622 unregister_exec_domain +EXPORT_SYMBOL vmlinux 0x66d67873 journal_revoke +EXPORT_SYMBOL vmlinux 0x66dd2492 __xfrm_policy_check +EXPORT_SYMBOL vmlinux 0x66fddc6d xfrm_state_update +EXPORT_SYMBOL vmlinux 0x67082f6e tcp_v4_syn_recv_sock +EXPORT_SYMBOL vmlinux 0x670b971b grab_cache_page_nowait +EXPORT_SYMBOL vmlinux 0x676a6abb invalidate_inodes +EXPORT_SYMBOL vmlinux 0x67a49c91 sk_dst_check +EXPORT_SYMBOL vmlinux 0x67b27ec1 tty_std_termios +EXPORT_SYMBOL vmlinux 0x67c2fa54 __copy_to_user +EXPORT_SYMBOL vmlinux 0x6819a9df cdev_del +EXPORT_SYMBOL vmlinux 0x6819e3bb skb_append_datato_frags +EXPORT_SYMBOL vmlinux 0x681a9498 udp_proc_unregister +EXPORT_SYMBOL vmlinux 0x682438ba eth_rebuild_header +EXPORT_SYMBOL vmlinux 0x68434407 netlink_change_ngroups +EXPORT_SYMBOL vmlinux 0x68561fda scsi_register +EXPORT_SYMBOL vmlinux 0x687d14c8 do_sync_write +EXPORT_SYMBOL vmlinux 0x68975744 skb_checksum +EXPORT_SYMBOL vmlinux 0x6898a756 sg_init_table +EXPORT_SYMBOL vmlinux 0x68a614d1 scsi_unblock_requests +EXPORT_SYMBOL vmlinux 0x68e57ad6 simple_transaction_read +EXPORT_SYMBOL vmlinux 0x6903026f neigh_seq_start +EXPORT_SYMBOL vmlinux 0x69277bd3 inet6_unregister_protosw +EXPORT_SYMBOL vmlinux 0x692c2d9c __request_region +EXPORT_SYMBOL vmlinux 0x69496641 mod_timer +EXPORT_SYMBOL vmlinux 0x6971447a rtc_month_days +EXPORT_SYMBOL vmlinux 0x69927dff try_acquire_console_sem +EXPORT_SYMBOL vmlinux 0x69af2327 idr_init +EXPORT_SYMBOL vmlinux 0x69b1e9fb pfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0x69c8c1d5 security_req_classify_flow +EXPORT_SYMBOL vmlinux 0x69d38ed9 __scsi_print_sense +EXPORT_SYMBOL vmlinux 0x69dee58c i2c_smbus_write_byte_data +EXPORT_SYMBOL vmlinux 0x69e27c7a bitmap_copy_le +EXPORT_SYMBOL vmlinux 0x69e5debd tcp_v4_connect +EXPORT_SYMBOL vmlinux 0x69f7cce8 neigh_destroy +EXPORT_SYMBOL vmlinux 0x6a037cf1 mempool_kfree +EXPORT_SYMBOL vmlinux 0x6a47571d __set_personality +EXPORT_SYMBOL vmlinux 0x6a4a73a5 kthread_stop +EXPORT_SYMBOL vmlinux 0x6a5cdcae skb_copy_and_csum_bits +EXPORT_SYMBOL vmlinux 0x6ac45c28 __up_write +EXPORT_SYMBOL vmlinux 0x6ac88d21 pci_set_consistent_dma_mask +EXPORT_SYMBOL vmlinux 0x6ad4fe3d ipv6_push_nfrag_opts +EXPORT_SYMBOL vmlinux 0x6b1b67d3 __bdevname +EXPORT_SYMBOL vmlinux 0x6b2dc060 dump_stack +EXPORT_SYMBOL vmlinux 0x6b3149fe ide_raw_taskfile +EXPORT_SYMBOL vmlinux 0x6b32544e __locks_copy_lock +EXPORT_SYMBOL vmlinux 0x6b32f162 tcp_ioctl +EXPORT_SYMBOL vmlinux 0x6b5229f0 __dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0x6b9159a4 noop_qdisc +EXPORT_SYMBOL vmlinux 0x6b9c40f3 __bio_clone +EXPORT_SYMBOL vmlinux 0x6ba17b39 lease_modify +EXPORT_SYMBOL vmlinux 0x6bcdab8b inet_del_protocol +EXPORT_SYMBOL vmlinux 0x6bdcfd99 qdisc_class_hash_remove +EXPORT_SYMBOL vmlinux 0x6bf30fd0 dev_kfree_skb_any +EXPORT_SYMBOL vmlinux 0x6bfeec29 posix_lock_file +EXPORT_SYMBOL vmlinux 0x6c0456f3 xscale_mc_clear_user_page +EXPORT_SYMBOL vmlinux 0x6c09801a skb_under_panic +EXPORT_SYMBOL vmlinux 0x6c0f84ca xfrm_state_lookup_byaddr +EXPORT_SYMBOL vmlinux 0x6c1ce5ce strcspn +EXPORT_SYMBOL vmlinux 0x6c353f57 xfrm6_find_1stfragopt +EXPORT_SYMBOL vmlinux 0x6c36a5c1 __mutex_init +EXPORT_SYMBOL vmlinux 0x6c4428e6 input_set_capability +EXPORT_SYMBOL vmlinux 0x6c4e6405 nobh_write_begin +EXPORT_SYMBOL vmlinux 0x6c552ab7 register_filesystem +EXPORT_SYMBOL vmlinux 0x6c702af7 sysctl_udp_rmem_min +EXPORT_SYMBOL vmlinux 0x6cc0ec78 dma_async_client_chan_request +EXPORT_SYMBOL vmlinux 0x6cdc5c6b nla_strlcpy +EXPORT_SYMBOL vmlinux 0x6cef247f __strnlen_user +EXPORT_SYMBOL vmlinux 0x6cf99234 i2c_smbus_read_word_data +EXPORT_SYMBOL vmlinux 0x6d0da34c param_get_short +EXPORT_SYMBOL vmlinux 0x6d247ed8 generic_fillattr +EXPORT_SYMBOL vmlinux 0x6d27ef64 __bitmap_empty +EXPORT_SYMBOL vmlinux 0x6d288375 radix_tree_next_hole +EXPORT_SYMBOL vmlinux 0x6d294e43 clock_t_to_jiffies +EXPORT_SYMBOL vmlinux 0x6d2f04e2 ide_dump_status +EXPORT_SYMBOL vmlinux 0x6d340f64 tty_termios_input_baud_rate +EXPORT_SYMBOL vmlinux 0x6d662533 _find_first_bit_le +EXPORT_SYMBOL vmlinux 0x6d83cfa4 mpage_readpage +EXPORT_SYMBOL vmlinux 0x6d8b43b2 pci_bus_type +EXPORT_SYMBOL vmlinux 0x6dbc9f09 xfrm_policy_destroy +EXPORT_SYMBOL vmlinux 0x6dec5899 pci_setup_cardbus +EXPORT_SYMBOL vmlinux 0x6def2db2 half_md4_transform +EXPORT_SYMBOL vmlinux 0x6dfc0341 generic_unplug_device +EXPORT_SYMBOL vmlinux 0x6e273649 netdev_state_change +EXPORT_SYMBOL vmlinux 0x6e3dded1 generic_file_mmap +EXPORT_SYMBOL vmlinux 0x6e440b58 memcpy_fromiovecend +EXPORT_SYMBOL vmlinux 0x6e57fb33 xfrm_policy_alloc +EXPORT_SYMBOL vmlinux 0x6e720ff2 rtnl_unlock +EXPORT_SYMBOL vmlinux 0x6e8092e5 unlock_super +EXPORT_SYMBOL vmlinux 0x6e84a85c save_time_delta +EXPORT_SYMBOL vmlinux 0x6e9dd606 __symbol_put +EXPORT_SYMBOL vmlinux 0x6eb6e727 dev_disable_lro +EXPORT_SYMBOL vmlinux 0x6eea229d svcauth_unix_purge +EXPORT_SYMBOL vmlinux 0x6eecb8d4 sysctl_intvec +EXPORT_SYMBOL vmlinux 0x6f3a1e71 pci_match_id +EXPORT_SYMBOL vmlinux 0x6f3c346c sock_kmalloc +EXPORT_SYMBOL vmlinux 0x6f5d6a9e blk_dump_rq_flags +EXPORT_SYMBOL vmlinux 0x6f687719 blk_queue_free_tags +EXPORT_SYMBOL vmlinux 0x6fa68e41 dev_set_mtu +EXPORT_SYMBOL vmlinux 0x6fb65767 pagevec_lookup_tag +EXPORT_SYMBOL vmlinux 0x6fcb87a1 touch_softlockup_watchdog +EXPORT_SYMBOL vmlinux 0x6fd71f0c neigh_parms_alloc +EXPORT_SYMBOL vmlinux 0x6fdecaae scsi_get_command +EXPORT_SYMBOL vmlinux 0x6fff9c0a struct_module +EXPORT_SYMBOL vmlinux 0x7000b394 bio_get_nr_vecs +EXPORT_SYMBOL vmlinux 0x7008a9b7 timespec_to_jiffies +EXPORT_SYMBOL vmlinux 0x701d0ebd snprintf +EXPORT_SYMBOL vmlinux 0x7025510b blk_plug_device +EXPORT_SYMBOL vmlinux 0x7027418d dmam_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0x702c8cc1 skb_copy_datagram_iovec +EXPORT_SYMBOL vmlinux 0x709d5d61 dev_queue_xmit +EXPORT_SYMBOL vmlinux 0x70b5e2f3 sysctl_data +EXPORT_SYMBOL vmlinux 0x70ca6eec pci_bus_write_config_word +EXPORT_SYMBOL vmlinux 0x70d0bdc0 generic_ro_fops +EXPORT_SYMBOL vmlinux 0x71104645 __skb_recv_datagram +EXPORT_SYMBOL vmlinux 0x7129e5f8 hex_asc +EXPORT_SYMBOL vmlinux 0x7132369b vfs_symlink +EXPORT_SYMBOL vmlinux 0x7138eb1b ipv6_chk_prefix +EXPORT_SYMBOL vmlinux 0x7171121c overflowgid +EXPORT_SYMBOL vmlinux 0x71a50dbc register_blkdev +EXPORT_SYMBOL vmlinux 0x71a76913 dev_remove_pack +EXPORT_SYMBOL vmlinux 0x71c3ce3f bio_alloc +EXPORT_SYMBOL vmlinux 0x71c90087 memcmp +EXPORT_SYMBOL vmlinux 0x71e39f60 eth_type_trans +EXPORT_SYMBOL vmlinux 0x71fa908a cache_flush +EXPORT_SYMBOL vmlinux 0x72270e35 do_gettimeofday +EXPORT_SYMBOL vmlinux 0x726ce7b3 tcf_exts_validate +EXPORT_SYMBOL vmlinux 0x729173ce scsi_cmd_ioctl +EXPORT_SYMBOL vmlinux 0x72d5af61 try_wait_for_completion +EXPORT_SYMBOL vmlinux 0x72e68a83 bio_alloc_bioset +EXPORT_SYMBOL vmlinux 0x72ea7b2d scsi_device_type +EXPORT_SYMBOL vmlinux 0x72fbae28 set_current_groups +EXPORT_SYMBOL vmlinux 0x73069aac cpu_possible_map +EXPORT_SYMBOL vmlinux 0x7311fbc0 elv_rb_add +EXPORT_SYMBOL vmlinux 0x731227be inet_csk_delete_keepalive_timer +EXPORT_SYMBOL vmlinux 0x7334186d arp_broken_ops +EXPORT_SYMBOL vmlinux 0x73538d76 cdev_init +EXPORT_SYMBOL vmlinux 0x7366d96a wait_on_sync_kiocb +EXPORT_SYMBOL vmlinux 0x739cf8c7 cfi_fixup +EXPORT_SYMBOL vmlinux 0x73aa47ee read_bytes_from_xdr_buf +EXPORT_SYMBOL vmlinux 0x73b34e32 xfrm_state_alloc +EXPORT_SYMBOL vmlinux 0x73bd1d30 pci_set_dma_seg_boundary +EXPORT_SYMBOL vmlinux 0x73d3237c journal_init_inode +EXPORT_SYMBOL vmlinux 0x73e063a3 km_state_expired +EXPORT_SYMBOL vmlinux 0x73e20c1c strlcpy +EXPORT_SYMBOL vmlinux 0x741ea8f0 unregister_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0x7481d377 inet6_release +EXPORT_SYMBOL vmlinux 0x74844fd3 sock_wmalloc +EXPORT_SYMBOL vmlinux 0x7485e15e unregister_chrdev_region +EXPORT_SYMBOL vmlinux 0x74cc238d current_kernel_time +EXPORT_SYMBOL vmlinux 0x74ffec01 pskb_expand_head +EXPORT_SYMBOL vmlinux 0x751ea88d bd_release +EXPORT_SYMBOL vmlinux 0x751ef24c journal_clear_err +EXPORT_SYMBOL vmlinux 0x752980bf pci_try_set_mwi +EXPORT_SYMBOL vmlinux 0x754508a9 xfrm_register_type +EXPORT_SYMBOL vmlinux 0x7577c675 pci_enable_device_io +EXPORT_SYMBOL vmlinux 0x75f9c864 nf_register_queue_handler +EXPORT_SYMBOL vmlinux 0x75fee7fd __raw_writesb +EXPORT_SYMBOL vmlinux 0x760a0f4f yield +EXPORT_SYMBOL vmlinux 0x760b437a unregister_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x76503d4c dev_unicast_sync +EXPORT_SYMBOL vmlinux 0x765f75fb pgprot_user +EXPORT_SYMBOL vmlinux 0x76adcf67 __inet6_hash +EXPORT_SYMBOL vmlinux 0x76b3c3a7 kmem_cache_alloc +EXPORT_SYMBOL vmlinux 0x76bf656d __bitmap_shift_left +EXPORT_SYMBOL vmlinux 0x76cf47f6 __aeabi_llsl +EXPORT_SYMBOL vmlinux 0x76d3cd60 laptop_mode +EXPORT_SYMBOL vmlinux 0x76e208ad xdr_inline_decode +EXPORT_SYMBOL vmlinux 0x76ee1e67 d_alloc_name +EXPORT_SYMBOL vmlinux 0x76ef1112 tcp_close +EXPORT_SYMBOL vmlinux 0x76f3a4f6 ip_route_output_key +EXPORT_SYMBOL vmlinux 0x77428f6e qdisc_list_del +EXPORT_SYMBOL vmlinux 0x774fe963 kernel_getpeername +EXPORT_SYMBOL vmlinux 0x7782b372 end_buffer_write_sync +EXPORT_SYMBOL vmlinux 0x77ba41df inode_change_ok +EXPORT_SYMBOL vmlinux 0x77ce5e31 sock_create_kern +EXPORT_SYMBOL vmlinux 0x77ecac9f zlib_inflateEnd +EXPORT_SYMBOL vmlinux 0x77ed2774 pci_choose_state +EXPORT_SYMBOL vmlinux 0x784b19e5 scsi_print_result +EXPORT_SYMBOL vmlinux 0x788039ff invalidate_partition +EXPORT_SYMBOL vmlinux 0x788fe103 iomem_resource +EXPORT_SYMBOL vmlinux 0x78939188 skb_abort_seq_read +EXPORT_SYMBOL vmlinux 0x7893f565 nf_hook_slow +EXPORT_SYMBOL vmlinux 0x78df6bd7 no_pci_devices +EXPORT_SYMBOL vmlinux 0x7943b2c6 generic_show_options +EXPORT_SYMBOL vmlinux 0x794487ee disable_hlt +EXPORT_SYMBOL vmlinux 0x794e553d scsi_add_host +EXPORT_SYMBOL vmlinux 0x79592242 rtnetlink_put_metrics +EXPORT_SYMBOL vmlinux 0x795f6b0d bd_set_size +EXPORT_SYMBOL vmlinux 0x79600d4a wait_for_completion_killable +EXPORT_SYMBOL vmlinux 0x79689f39 udp_proc_register +EXPORT_SYMBOL vmlinux 0x796fc5ce scsi_get_sense_info_fld +EXPORT_SYMBOL vmlinux 0x79714c34 tty_port_free_xmit_buf +EXPORT_SYMBOL vmlinux 0x79aa04a2 get_random_bytes +EXPORT_SYMBOL vmlinux 0x79ad224b tasklet_kill +EXPORT_SYMBOL vmlinux 0x7a084893 vfs_rename +EXPORT_SYMBOL vmlinux 0x7a0cd945 find_get_pages_contig +EXPORT_SYMBOL vmlinux 0x7a2a837d strict_strtol +EXPORT_SYMBOL vmlinux 0x7ad5f3de __getblk +EXPORT_SYMBOL vmlinux 0x7bb50931 dma_pool_create +EXPORT_SYMBOL vmlinux 0x7bbc3822 xfrm4_prepare_output +EXPORT_SYMBOL vmlinux 0x7bcd2f13 add_disk +EXPORT_SYMBOL vmlinux 0x7c185f7a put_disk +EXPORT_SYMBOL vmlinux 0x7c46b2ef blk_queue_update_dma_pad +EXPORT_SYMBOL vmlinux 0x7c4aeb93 blk_rq_map_user +EXPORT_SYMBOL vmlinux 0x7c56cf3c generic_mii_ioctl +EXPORT_SYMBOL vmlinux 0x7c595d0d poll_freewait +EXPORT_SYMBOL vmlinux 0x7c60d66e getname +EXPORT_SYMBOL vmlinux 0x7c698046 ip_setsockopt +EXPORT_SYMBOL vmlinux 0x7c6a2118 vm_insert_page +EXPORT_SYMBOL vmlinux 0x7c6fefac pci_bus_write_config_byte +EXPORT_SYMBOL vmlinux 0x7c75800f locks_mandatory_area +EXPORT_SYMBOL vmlinux 0x7c82881b get_disk +EXPORT_SYMBOL vmlinux 0x7c904ded unregister_module_notifier +EXPORT_SYMBOL vmlinux 0x7ca77095 datagram_poll +EXPORT_SYMBOL vmlinux 0x7cc035a7 __ucmpdi2 +EXPORT_SYMBOL vmlinux 0x7cd6b988 tcp_create_openreq_child +EXPORT_SYMBOL vmlinux 0x7d053899 alloc_buffer_head +EXPORT_SYMBOL vmlinux 0x7d11c268 jiffies +EXPORT_SYMBOL vmlinux 0x7d3286ca vfs_mkdir +EXPORT_SYMBOL vmlinux 0x7d5ce6d0 blk_insert_request +EXPORT_SYMBOL vmlinux 0x7d850612 utf8_mbstowcs +EXPORT_SYMBOL vmlinux 0x7d8ee848 d_namespace_path +EXPORT_SYMBOL vmlinux 0x7d983e29 flush_signals +EXPORT_SYMBOL vmlinux 0x7db4159e page_readlink +EXPORT_SYMBOL vmlinux 0x7dc3cbdb svc_destroy +EXPORT_SYMBOL vmlinux 0x7dceceac capable +EXPORT_SYMBOL vmlinux 0x7e058bfb xscale_coherent_kern_range +EXPORT_SYMBOL vmlinux 0x7e531cde del_timer +EXPORT_SYMBOL vmlinux 0x7e54aeeb dev_alloc_skb +EXPORT_SYMBOL vmlinux 0x7e96ec53 register_key_type +EXPORT_SYMBOL vmlinux 0x7e990140 dev_get_flags +EXPORT_SYMBOL vmlinux 0x7e9ebb05 kernel_thread +EXPORT_SYMBOL vmlinux 0x7f11f7e4 neigh_table_init +EXPORT_SYMBOL vmlinux 0x7f1cff63 blk_queue_max_segment_size +EXPORT_SYMBOL vmlinux 0x7f24de73 jiffies_to_usecs +EXPORT_SYMBOL vmlinux 0x7f34cdcc proc_dointvec_ms_jiffies +EXPORT_SYMBOL vmlinux 0x7f397058 sock_no_sendpage +EXPORT_SYMBOL vmlinux 0x7f3cb359 flush_old_exec +EXPORT_SYMBOL vmlinux 0x7f483c0e generic_setlease +EXPORT_SYMBOL vmlinux 0x7f63b31e _memcpy_toio +EXPORT_SYMBOL vmlinux 0x7f8723bd pcie_mch_quirk +EXPORT_SYMBOL vmlinux 0x7fa534d2 simple_write_end +EXPORT_SYMBOL vmlinux 0x7fb8eff6 init_mm +EXPORT_SYMBOL vmlinux 0x7fc6ff98 scsi_reset_provider +EXPORT_SYMBOL vmlinux 0x7fdd1ecb blk_queue_ordered +EXPORT_SYMBOL vmlinux 0x7fe8cc59 svc_process +EXPORT_SYMBOL vmlinux 0x7ff73b73 iw_handler_get_thrspy +EXPORT_SYMBOL vmlinux 0x7ffdeb0a mtd_do_chip_probe +EXPORT_SYMBOL vmlinux 0x800e4ffa __muldi3 +EXPORT_SYMBOL vmlinux 0x8042aee5 gpio_line_get +EXPORT_SYMBOL vmlinux 0x8063f83d radix_tree_gang_lookup +EXPORT_SYMBOL vmlinux 0x80733b83 filemap_write_and_wait +EXPORT_SYMBOL vmlinux 0x807439d5 ipv4_specific +EXPORT_SYMBOL vmlinux 0x8084dbff register_gifconf +EXPORT_SYMBOL vmlinux 0x8085c7b1 prepare_to_wait +EXPORT_SYMBOL vmlinux 0x80bcb5e9 generic_file_llseek_unlocked +EXPORT_SYMBOL vmlinux 0x80f4e2cc tty_name +EXPORT_SYMBOL vmlinux 0x81347729 skb_store_bits +EXPORT_SYMBOL vmlinux 0x814e5b83 skb_checksum_help +EXPORT_SYMBOL vmlinux 0x815858ec __scsi_put_command +EXPORT_SYMBOL vmlinux 0x815b5dd4 match_octal +EXPORT_SYMBOL vmlinux 0x815cda67 inet6_del_protocol +EXPORT_SYMBOL vmlinux 0x8165479c scsi_eh_restore_cmnd +EXPORT_SYMBOL vmlinux 0x81799cee vscnprintf +EXPORT_SYMBOL vmlinux 0x81a9d567 console_start +EXPORT_SYMBOL vmlinux 0x81c11865 generic_setxattr +EXPORT_SYMBOL vmlinux 0x820d225f print_mac +EXPORT_SYMBOL vmlinux 0x8251bcc3 bitmap_release_region +EXPORT_SYMBOL vmlinux 0x82604a33 kernel_connect +EXPORT_SYMBOL vmlinux 0x826627e1 tcf_unregister_action +EXPORT_SYMBOL vmlinux 0x82692209 kref_set +EXPORT_SYMBOL vmlinux 0x8293174c tty_driver_kref_put +EXPORT_SYMBOL vmlinux 0x82b6edb0 path_get +EXPORT_SYMBOL vmlinux 0x82d1d4d3 __dev_remove_pack +EXPORT_SYMBOL vmlinux 0x82e5a238 vm_get_page_prot +EXPORT_SYMBOL vmlinux 0x82e8d5d4 pcix_get_max_mmrbc +EXPORT_SYMBOL vmlinux 0x82fad6c8 security_inode_init_security +EXPORT_SYMBOL vmlinux 0x8320bea8 __umodsi3 +EXPORT_SYMBOL vmlinux 0x83437d49 generic_file_direct_write +EXPORT_SYMBOL vmlinux 0x835a2e45 dma_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0x83695e5d simple_fill_super +EXPORT_SYMBOL vmlinux 0x8379dfaf key_unlink +EXPORT_SYMBOL vmlinux 0x83884d1c seq_release +EXPORT_SYMBOL vmlinux 0x83a476ce bitmap_scnlistprintf +EXPORT_SYMBOL vmlinux 0x83bd1775 vfs_readlink +EXPORT_SYMBOL vmlinux 0x83dbb526 bio_map_user +EXPORT_SYMBOL vmlinux 0x8475ee36 scsi_execute +EXPORT_SYMBOL vmlinux 0x84870dc5 textsearch_destroy +EXPORT_SYMBOL vmlinux 0x8487f69a scsi_target_quiesce +EXPORT_SYMBOL vmlinux 0x84b183ae strncmp +EXPORT_SYMBOL vmlinux 0x8525fc69 netlink_unicast +EXPORT_SYMBOL vmlinux 0x8566cd06 sock_i_uid +EXPORT_SYMBOL vmlinux 0x85670f1d rtnl_is_locked +EXPORT_SYMBOL vmlinux 0x85721888 tcp_proc_unregister +EXPORT_SYMBOL vmlinux 0x8589bfe3 svc_drop +EXPORT_SYMBOL vmlinux 0x85a3e3e5 pci_enable_wake +EXPORT_SYMBOL vmlinux 0x85ac48c8 mb_cache_shrink +EXPORT_SYMBOL vmlinux 0x85ac6d5f poll_initwait +EXPORT_SYMBOL vmlinux 0x85ac7f10 posix_acl_from_xattr +EXPORT_SYMBOL vmlinux 0x85d7474b dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0x85df9b6c strsep +EXPORT_SYMBOL vmlinux 0x85e5ee9f gnet_stats_copy_rate_est +EXPORT_SYMBOL vmlinux 0x85e7deb2 iov_iter_fault_in_readable +EXPORT_SYMBOL vmlinux 0x8604441a dmam_pool_create +EXPORT_SYMBOL vmlinux 0x86045448 set_bdi_congested +EXPORT_SYMBOL vmlinux 0x8609da1d d_prune_aliases +EXPORT_SYMBOL vmlinux 0x8618c42b mntput_no_expire +EXPORT_SYMBOL vmlinux 0x863cb91a utf8_wcstombs +EXPORT_SYMBOL vmlinux 0x86875851 pci_target_state +EXPORT_SYMBOL vmlinux 0x868acba5 get_options +EXPORT_SYMBOL vmlinux 0x8692e74e __splice_from_pipe +EXPORT_SYMBOL vmlinux 0x86c03f0c blk_init_queue_node +EXPORT_SYMBOL vmlinux 0x86ce434c scsi_host_set_state +EXPORT_SYMBOL vmlinux 0x86e30247 scsi_target_resume +EXPORT_SYMBOL vmlinux 0x86fb9b05 bitmap_parse_user +EXPORT_SYMBOL vmlinux 0x871c0a7e fiemap_check_flags +EXPORT_SYMBOL vmlinux 0x875bb6c5 ethtool_op_set_tx_hw_csum +EXPORT_SYMBOL vmlinux 0x87728f74 cdev_add +EXPORT_SYMBOL vmlinux 0x87781d57 init_net +EXPORT_SYMBOL vmlinux 0x8785725d param_set_charp +EXPORT_SYMBOL vmlinux 0x878ab3ce sysctl_tcp_adv_win_scale +EXPORT_SYMBOL vmlinux 0x87b3fa50 scsi_is_sdev_device +EXPORT_SYMBOL vmlinux 0x87cdf5c3 __wait_on_buffer +EXPORT_SYMBOL vmlinux 0x881039d0 zlib_inflate +EXPORT_SYMBOL vmlinux 0x8820bea3 blk_queue_bounce_limit +EXPORT_SYMBOL vmlinux 0x88266cf2 svc_prepare_thread +EXPORT_SYMBOL vmlinux 0x882e994d blk_get_request +EXPORT_SYMBOL vmlinux 0x8852fcc6 put_tty_driver +EXPORT_SYMBOL vmlinux 0x885a37f3 journal_release_buffer +EXPORT_SYMBOL vmlinux 0x887964e5 elv_rb_latter_request +EXPORT_SYMBOL vmlinux 0x88a67abb con_copy_unimap +EXPORT_SYMBOL vmlinux 0x88da5400 vm_insert_mixed +EXPORT_SYMBOL vmlinux 0x8915523f ether_setup +EXPORT_SYMBOL vmlinux 0x891e32b8 wait_for_completion_interruptible +EXPORT_SYMBOL vmlinux 0x894f28bd tty_kref_put +EXPORT_SYMBOL vmlinux 0x896b96df tcf_hash_lookup +EXPORT_SYMBOL vmlinux 0x897473df mktime +EXPORT_SYMBOL vmlinux 0x89d66811 build_ehash_secret +EXPORT_SYMBOL vmlinux 0x89df328e bdget +EXPORT_SYMBOL vmlinux 0x8a0ed75b pcim_iomap +EXPORT_SYMBOL vmlinux 0x8a1203a9 kref_get +EXPORT_SYMBOL vmlinux 0x8a16db27 pci_set_mwi +EXPORT_SYMBOL vmlinux 0x8a4c84cc bdput +EXPORT_SYMBOL vmlinux 0x8a4fa83b __aeabi_llsr +EXPORT_SYMBOL vmlinux 0x8a63b010 scsi_print_command +EXPORT_SYMBOL vmlinux 0x8a7d1c31 high_memory +EXPORT_SYMBOL vmlinux 0x8a99a016 mempool_free_slab +EXPORT_SYMBOL vmlinux 0x8ae9a7ad journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0x8b368b27 dev_get_by_index +EXPORT_SYMBOL vmlinux 0x8b618d08 overflowuid +EXPORT_SYMBOL vmlinux 0x8b7437a1 kfree_skb +EXPORT_SYMBOL vmlinux 0x8b89cc81 sb_set_blocksize +EXPORT_SYMBOL vmlinux 0x8b9a4149 ida_destroy +EXPORT_SYMBOL vmlinux 0x8b9e5146 blk_free_tags +EXPORT_SYMBOL vmlinux 0x8baa8428 sock_get_timestamp +EXPORT_SYMBOL vmlinux 0x8bbfa2b9 flow_cache_lookup +EXPORT_SYMBOL vmlinux 0x8bf1e142 gpio_line_set +EXPORT_SYMBOL vmlinux 0x8c2a8104 sk_free +EXPORT_SYMBOL vmlinux 0x8c3183f8 scsi_unregister +EXPORT_SYMBOL vmlinux 0x8c52d6d3 mnt_pin +EXPORT_SYMBOL vmlinux 0x8c63292d sock_no_getname +EXPORT_SYMBOL vmlinux 0x8c7bc348 ida_remove +EXPORT_SYMBOL vmlinux 0x8c84069c restore_time_delta +EXPORT_SYMBOL vmlinux 0x8c878cba textsearch_register +EXPORT_SYMBOL vmlinux 0x8c977795 km_policy_expired +EXPORT_SYMBOL vmlinux 0x8cdf4017 write_inode_now +EXPORT_SYMBOL vmlinux 0x8cf073f9 blk_cleanup_queue +EXPORT_SYMBOL vmlinux 0x8cf35127 bio_put +EXPORT_SYMBOL vmlinux 0x8d1e52c1 register_binfmt +EXPORT_SYMBOL vmlinux 0x8d3894f2 _ctype +EXPORT_SYMBOL vmlinux 0x8d551bef sysctl_tcp_rmem +EXPORT_SYMBOL vmlinux 0x8d5642fc wait_for_completion_interruptible_timeout +EXPORT_SYMBOL vmlinux 0x8d6dad86 register_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0x8d6f81b4 __div64_32 +EXPORT_SYMBOL vmlinux 0x8d7062b3 blk_rq_map_kern +EXPORT_SYMBOL vmlinux 0x8dcb5c27 idr_remove +EXPORT_SYMBOL vmlinux 0x8dd3ae81 lease_get_mtime +EXPORT_SYMBOL vmlinux 0x8dd93edf posix_lock_file_wait +EXPORT_SYMBOL vmlinux 0x8ddd7cea sock_no_getsockopt +EXPORT_SYMBOL vmlinux 0x8decfb08 bdi_init +EXPORT_SYMBOL vmlinux 0x8def42b1 mark_page_accessed +EXPORT_SYMBOL vmlinux 0x8e0b7743 ipv6_ext_hdr +EXPORT_SYMBOL vmlinux 0x8e1e8fd4 scsi_init_io +EXPORT_SYMBOL vmlinux 0x8e20153f xfrm_state_add +EXPORT_SYMBOL vmlinux 0x8e3c9cc3 vprintk +EXPORT_SYMBOL vmlinux 0x8e4ac28e bmap +EXPORT_SYMBOL vmlinux 0x8e6916c1 xfrm_policy_walk +EXPORT_SYMBOL vmlinux 0x8e763ae1 send_remote_softirq +EXPORT_SYMBOL vmlinux 0x8ed85e1a __xfrm_state_destroy +EXPORT_SYMBOL vmlinux 0x8ee2cb75 journal_forget +EXPORT_SYMBOL vmlinux 0x8ee88fd7 pcix_set_mmrbc +EXPORT_SYMBOL vmlinux 0x8f07d8ca __wait_on_bit +EXPORT_SYMBOL vmlinux 0x8f30c7a0 nf_register_hooks +EXPORT_SYMBOL vmlinux 0x8f3b0ef9 dma_pool_alloc +EXPORT_SYMBOL vmlinux 0x8f518e90 tcp_check_req +EXPORT_SYMBOL vmlinux 0x8f6b7950 set_irq_data +EXPORT_SYMBOL vmlinux 0x8f707b60 generic_block_bmap +EXPORT_SYMBOL vmlinux 0x8f816b7a ide_wait_stat +EXPORT_SYMBOL vmlinux 0x8f928bd9 page_zero_new_buffers +EXPORT_SYMBOL vmlinux 0x8f9b86b2 kfifo_alloc +EXPORT_SYMBOL vmlinux 0x8f9e8d47 kern_path +EXPORT_SYMBOL vmlinux 0x8fb59383 sock_map_fd +EXPORT_SYMBOL vmlinux 0x8fdf5f58 generic_delete_inode +EXPORT_SYMBOL vmlinux 0x8fe9ef8c kick_iocb +EXPORT_SYMBOL vmlinux 0x90035333 secure_tcpv6_sequence_number +EXPORT_SYMBOL vmlinux 0x901d4f27 pci_scan_slot +EXPORT_SYMBOL vmlinux 0x904e9477 close_bdev_exclusive +EXPORT_SYMBOL vmlinux 0x9052a72c blk_recount_segments +EXPORT_SYMBOL vmlinux 0x906ad67c request_key_async_with_auxdata +EXPORT_SYMBOL vmlinux 0x9077b7bf nf_setsockopt +EXPORT_SYMBOL vmlinux 0x907f8ceb journal_flush +EXPORT_SYMBOL vmlinux 0x909b6d35 generic_file_readonly_mmap +EXPORT_SYMBOL vmlinux 0x90d1d034 textsearch_unregister +EXPORT_SYMBOL vmlinux 0x90d5b459 filemap_fdatawait +EXPORT_SYMBOL vmlinux 0x90dac48f scsi_ioctl +EXPORT_SYMBOL vmlinux 0x90e93cb4 wait_for_key_construction +EXPORT_SYMBOL vmlinux 0x90f7ab9f page_symlink +EXPORT_SYMBOL vmlinux 0x91202971 xfrm_register_km +EXPORT_SYMBOL vmlinux 0x91481982 __ratelimit +EXPORT_SYMBOL vmlinux 0x914966ee pcim_iomap_table +EXPORT_SYMBOL vmlinux 0x9185fd02 inet_release +EXPORT_SYMBOL vmlinux 0x919029aa __readwrite_bug +EXPORT_SYMBOL vmlinux 0x920ef731 kernel_sendpage +EXPORT_SYMBOL vmlinux 0x9239ce01 dma_sync_sg_for_device +EXPORT_SYMBOL vmlinux 0x925d9cd3 i2c_use_client +EXPORT_SYMBOL vmlinux 0x926401f2 sg_copy_to_buffer +EXPORT_SYMBOL vmlinux 0x92c2f172 locks_init_lock +EXPORT_SYMBOL vmlinux 0x92cf724c tcp_initialize_rcv_mss +EXPORT_SYMBOL vmlinux 0x92e8c2c3 udp_lib_get_port +EXPORT_SYMBOL vmlinux 0x930b8619 netif_carrier_off +EXPORT_SYMBOL vmlinux 0x9321c7db scsi_setup_blk_pc_cmnd +EXPORT_SYMBOL vmlinux 0x9367bd88 scsi_remove_target +EXPORT_SYMBOL vmlinux 0x936a49eb pci_enable_bridges +EXPORT_SYMBOL vmlinux 0x93803e81 load_nls +EXPORT_SYMBOL vmlinux 0x9394f495 pci_add_new_bus +EXPORT_SYMBOL vmlinux 0x9398ff7c kill_pgrp +EXPORT_SYMBOL vmlinux 0x93a6e0b2 io_schedule +EXPORT_SYMBOL vmlinux 0x93c69acf param_set_byte +EXPORT_SYMBOL vmlinux 0x93fca811 __get_free_pages +EXPORT_SYMBOL vmlinux 0x94476940 stop_tty +EXPORT_SYMBOL vmlinux 0x944f21f3 tcf_register_action +EXPORT_SYMBOL vmlinux 0x9459186d blk_complete_request +EXPORT_SYMBOL vmlinux 0x9478d339 neigh_update +EXPORT_SYMBOL vmlinux 0x947aff9f vm_insert_pfn +EXPORT_SYMBOL vmlinux 0x9490ee8f inet_dev_addr_type +EXPORT_SYMBOL vmlinux 0x94961283 vunmap +EXPORT_SYMBOL vmlinux 0x94d617d6 register_sysrq_key +EXPORT_SYMBOL vmlinux 0x94e4c322 tcp_child_process +EXPORT_SYMBOL vmlinux 0x94f5852a vfs_getattr +EXPORT_SYMBOL vmlinux 0x94fa2ac7 bio_init +EXPORT_SYMBOL vmlinux 0x9501d078 __wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0x951cb42c uart_resume_port +EXPORT_SYMBOL vmlinux 0x9542164f pcim_enable_device +EXPORT_SYMBOL vmlinux 0x954729af nf_reinject +EXPORT_SYMBOL vmlinux 0x954cbb26 vsprintf +EXPORT_SYMBOL vmlinux 0x95531f77 pci_find_parent_resource +EXPORT_SYMBOL vmlinux 0x95a1fa3d call_usermodehelper_pipe +EXPORT_SYMBOL vmlinux 0x95b72d0b pci_find_next_bus +EXPORT_SYMBOL vmlinux 0x95dbe078 __get_user_2 +EXPORT_SYMBOL vmlinux 0x963028ed read_dev_sector +EXPORT_SYMBOL vmlinux 0x96737b32 serial8250_register_port +EXPORT_SYMBOL vmlinux 0x96836589 start_tty +EXPORT_SYMBOL vmlinux 0x96898769 sysfs_format_mac +EXPORT_SYMBOL vmlinux 0x96a115e9 skb_recycle_check +EXPORT_SYMBOL vmlinux 0x96cd2b04 scsi_sense_key_string +EXPORT_SYMBOL vmlinux 0x96d9e4fd dev_set_promiscuity +EXPORT_SYMBOL vmlinux 0x96ddcfe4 sock_create_lite +EXPORT_SYMBOL vmlinux 0x96df5482 walk_stackframe +EXPORT_SYMBOL vmlinux 0x96e3a57c mii_nway_restart +EXPORT_SYMBOL vmlinux 0x96fb9162 kthread_bind +EXPORT_SYMBOL vmlinux 0x97255bdf strlen +EXPORT_SYMBOL vmlinux 0x973a06b6 svc_recv +EXPORT_SYMBOL vmlinux 0x9754ec10 radix_tree_preload +EXPORT_SYMBOL vmlinux 0x97dc7cee xfrm_policy_bysel_ctx +EXPORT_SYMBOL vmlinux 0x97ff2d3d mark_buffer_async_write +EXPORT_SYMBOL vmlinux 0x981026f6 km_report +EXPORT_SYMBOL vmlinux 0x98286817 tcp_sync_mss +EXPORT_SYMBOL vmlinux 0x985c801f elv_next_request +EXPORT_SYMBOL vmlinux 0x986fe749 mark_buffer_dirty_inode +EXPORT_SYMBOL vmlinux 0x988d3d39 xfrm_nl +EXPORT_SYMBOL vmlinux 0x98a66714 bdget_disk +EXPORT_SYMBOL vmlinux 0x98dc16b3 tcp_tso_segment +EXPORT_SYMBOL vmlinux 0x98e9d9c9 file_fsync +EXPORT_SYMBOL vmlinux 0x98f872d4 input_unregister_handle +EXPORT_SYMBOL vmlinux 0x9937f494 skb_append +EXPORT_SYMBOL vmlinux 0x999488b6 pci_set_dma_mask +EXPORT_SYMBOL vmlinux 0x999c3148 __raw_readsb +EXPORT_SYMBOL vmlinux 0x999e8297 vfree +EXPORT_SYMBOL vmlinux 0x99aadb21 param_get_ulong +EXPORT_SYMBOL vmlinux 0x99bb8806 memmove +EXPORT_SYMBOL vmlinux 0x99bfbe39 get_unused_fd +EXPORT_SYMBOL vmlinux 0x99c3c0b0 vfs_fstat +EXPORT_SYMBOL vmlinux 0x99cdc86b sysctl_tcp_reordering +EXPORT_SYMBOL vmlinux 0x99ea12ce panic_blink +EXPORT_SYMBOL vmlinux 0x99eb7a17 pcie_set_readrq +EXPORT_SYMBOL vmlinux 0x9a108cd3 tcf_hash_release +EXPORT_SYMBOL vmlinux 0x9a1dfd65 strpbrk +EXPORT_SYMBOL vmlinux 0x9a1eff5b skb_queue_purge +EXPORT_SYMBOL vmlinux 0x9ae12c6b __scm_destroy +EXPORT_SYMBOL vmlinux 0x9b388444 get_zeroed_page +EXPORT_SYMBOL vmlinux 0x9b39a536 sg_miter_start +EXPORT_SYMBOL vmlinux 0x9b58560a wireless_spy_update +EXPORT_SYMBOL vmlinux 0x9b85b9b0 scsi_test_unit_ready +EXPORT_SYMBOL vmlinux 0x9ba7089d argv_split +EXPORT_SYMBOL vmlinux 0x9bbbbdb2 arp_tbl +EXPORT_SYMBOL vmlinux 0x9bce482f __release_region +EXPORT_SYMBOL vmlinux 0x9bd0f692 pci_bus_read_config_dword +EXPORT_SYMBOL vmlinux 0x9c2571f4 __down_read +EXPORT_SYMBOL vmlinux 0x9c323639 pci_find_slot +EXPORT_SYMBOL vmlinux 0x9c3d33b7 d_find_alias +EXPORT_SYMBOL vmlinux 0x9c4cb24f put_page +EXPORT_SYMBOL vmlinux 0x9c53dc60 d_lookup +EXPORT_SYMBOL vmlinux 0x9c605d8e input_register_device +EXPORT_SYMBOL vmlinux 0x9c63f3c6 blk_plug_device_unlocked +EXPORT_SYMBOL vmlinux 0x9c6e63ca cache_register +EXPORT_SYMBOL vmlinux 0x9c7077bd enable_hlt +EXPORT_SYMBOL vmlinux 0x9cb96e92 qdisc_put_rtab +EXPORT_SYMBOL vmlinux 0x9cbabca0 n_tty_ioctl_helper +EXPORT_SYMBOL vmlinux 0x9cbbefd7 pci_remove_behind_bridge +EXPORT_SYMBOL vmlinux 0x9ceb163c memcpy_toiovec +EXPORT_SYMBOL vmlinux 0x9cfd56c5 scsi_print_status +EXPORT_SYMBOL vmlinux 0x9d11490d write_cache_pages +EXPORT_SYMBOL vmlinux 0x9d2296a7 sock_kfree_s +EXPORT_SYMBOL vmlinux 0x9d4e4905 pci_unregister_driver +EXPORT_SYMBOL vmlinux 0x9d552f01 pci_prepare_to_sleep +EXPORT_SYMBOL vmlinux 0x9d569e32 set_disk_ro +EXPORT_SYMBOL vmlinux 0x9d57ba01 dma_sync_sg_for_cpu +EXPORT_SYMBOL vmlinux 0x9d669763 memcpy +EXPORT_SYMBOL vmlinux 0x9d6cd147 __break_lease +EXPORT_SYMBOL vmlinux 0x9d6e8d2f qdisc_watchdog_init +EXPORT_SYMBOL vmlinux 0x9ddce69d i2c_del_driver +EXPORT_SYMBOL vmlinux 0x9e09593d skb_dequeue_tail +EXPORT_SYMBOL vmlinux 0x9e120414 ida_get_new_above +EXPORT_SYMBOL vmlinux 0x9e2f718d inet6_getname +EXPORT_SYMBOL vmlinux 0x9e6f838e bio_sector_offset +EXPORT_SYMBOL vmlinux 0x9e7d6bd0 __udelay +EXPORT_SYMBOL vmlinux 0x9e835fde tty_devnum +EXPORT_SYMBOL vmlinux 0x9e89a240 uart_unregister_driver +EXPORT_SYMBOL vmlinux 0x9e9c7172 journal_stop +EXPORT_SYMBOL vmlinux 0x9ead4303 wait_on_page_bit +EXPORT_SYMBOL vmlinux 0x9eb0c534 generic_write_checks +EXPORT_SYMBOL vmlinux 0x9eb811c4 journal_destroy +EXPORT_SYMBOL vmlinux 0x9ed685ee iov_iter_advance +EXPORT_SYMBOL vmlinux 0x9ee2176e generic_write_end +EXPORT_SYMBOL vmlinux 0x9eeb3a51 blk_execute_rq +EXPORT_SYMBOL vmlinux 0x9eecde16 do_brk +EXPORT_SYMBOL vmlinux 0x9ef749e2 unregister_chrdev +EXPORT_SYMBOL vmlinux 0x9efdfb0d gpio_line_config +EXPORT_SYMBOL vmlinux 0x9f100139 jiffies_to_clock_t +EXPORT_SYMBOL vmlinux 0x9f2bdaac __bitmap_or +EXPORT_SYMBOL vmlinux 0x9f673fb0 __scsi_device_lookup +EXPORT_SYMBOL vmlinux 0x9f6d43c9 __xfrm_route_forward +EXPORT_SYMBOL vmlinux 0x9f6dfcaf xfrm_dst_ifdown +EXPORT_SYMBOL vmlinux 0x9f984513 strrchr +EXPORT_SYMBOL vmlinux 0x9faabf90 ip_defrag +EXPORT_SYMBOL vmlinux 0x9faae70e truncate_inode_pages_range +EXPORT_SYMBOL vmlinux 0x9fb3dd30 memcpy_fromiovec +EXPORT_SYMBOL vmlinux 0x9fc91fa3 ethtool_op_get_ufo +EXPORT_SYMBOL vmlinux 0x9fd6cf48 unregister_key_type +EXPORT_SYMBOL vmlinux 0x9ff2b9ef pci_enable_device_mem +EXPORT_SYMBOL vmlinux 0xa000b57d tty_shutdown +EXPORT_SYMBOL vmlinux 0xa02e8ff6 inet_csk_accept +EXPORT_SYMBOL vmlinux 0xa03523d5 security_unix_stream_connect +EXPORT_SYMBOL vmlinux 0xa04a01bd qdisc_class_hash_insert +EXPORT_SYMBOL vmlinux 0xa05c03df mempool_kmalloc +EXPORT_SYMBOL vmlinux 0xa063cfb2 sk_stream_wait_memory +EXPORT_SYMBOL vmlinux 0xa07a8d22 sleep_on +EXPORT_SYMBOL vmlinux 0xa07ac24b irq_stat +EXPORT_SYMBOL vmlinux 0xa094fda4 __set_page_dirty_buffers +EXPORT_SYMBOL vmlinux 0xa0b04675 vmalloc_32 +EXPORT_SYMBOL vmlinux 0xa0c49850 dev_change_flags +EXPORT_SYMBOL vmlinux 0xa0ceef51 out_of_line_wait_on_bit +EXPORT_SYMBOL vmlinux 0xa0fbac79 wake_up_bit +EXPORT_SYMBOL vmlinux 0xa108eb4d sysctl_optmem_max +EXPORT_SYMBOL vmlinux 0xa10dcc13 getrawmonotonic +EXPORT_SYMBOL vmlinux 0xa120d33c tty_unregister_ldisc +EXPORT_SYMBOL vmlinux 0xa13798f8 printk_ratelimit +EXPORT_SYMBOL vmlinux 0xa15d22c5 give_up_console +EXPORT_SYMBOL vmlinux 0xa1689d7b d_move +EXPORT_SYMBOL vmlinux 0xa19fe427 svc_wake_up +EXPORT_SYMBOL vmlinux 0xa1a2de08 tcp_init_xmit_timers +EXPORT_SYMBOL vmlinux 0xa1c76e0a _cond_resched +EXPORT_SYMBOL vmlinux 0xa1ee1051 pcim_iounmap +EXPORT_SYMBOL vmlinux 0xa1f5644b input_inject_event +EXPORT_SYMBOL vmlinux 0xa20ce1b8 net_msg_warn +EXPORT_SYMBOL vmlinux 0xa218bf61 complete +EXPORT_SYMBOL vmlinux 0xa22b2744 sk_stream_error +EXPORT_SYMBOL vmlinux 0xa25c6e98 input_grab_device +EXPORT_SYMBOL vmlinux 0xa270dc1e inet_stream_connect +EXPORT_SYMBOL vmlinux 0xa278f4fc ide_do_reset +EXPORT_SYMBOL vmlinux 0xa29b1708 tcp_memory_allocated +EXPORT_SYMBOL vmlinux 0xa2a323cc dma_alloc_from_coherent +EXPORT_SYMBOL vmlinux 0xa2a5fd77 inet_ehash_secret +EXPORT_SYMBOL vmlinux 0xa2bdf31a netdev_bonding_change +EXPORT_SYMBOL vmlinux 0xa2dadff8 task_pid_nr_ns +EXPORT_SYMBOL vmlinux 0xa329f07e register_shrinker +EXPORT_SYMBOL vmlinux 0xa33ed4f0 unregister_filesystem +EXPORT_SYMBOL vmlinux 0xa34f1ef5 crc32_le +EXPORT_SYMBOL vmlinux 0xa35de80f ipv4_config +EXPORT_SYMBOL vmlinux 0xa375a08f skb_queue_tail +EXPORT_SYMBOL vmlinux 0xa3a4ed03 cond_resched_lock +EXPORT_SYMBOL vmlinux 0xa3c0e72b i2c_verify_client +EXPORT_SYMBOL vmlinux 0xa3e759e4 journal_set_features +EXPORT_SYMBOL vmlinux 0xa3eddea6 blk_queue_merge_bvec +EXPORT_SYMBOL vmlinux 0xa404cd15 elv_dispatch_add_tail +EXPORT_SYMBOL vmlinux 0xa43173ab pci_reenable_device +EXPORT_SYMBOL vmlinux 0xa43c2822 tcp_v4_destroy_sock +EXPORT_SYMBOL vmlinux 0xa474f307 generic_file_splice_write +EXPORT_SYMBOL vmlinux 0xa4d99f0c kmem_cache_size +EXPORT_SYMBOL vmlinux 0xa4e622ee scsi_print_sense +EXPORT_SYMBOL vmlinux 0xa522f2be seq_open_private +EXPORT_SYMBOL vmlinux 0xa5261022 dev_alloc_name +EXPORT_SYMBOL vmlinux 0xa52c7806 find_or_create_page +EXPORT_SYMBOL vmlinux 0xa5337ce0 fd_install +EXPORT_SYMBOL vmlinux 0xa5423cc4 param_get_int +EXPORT_SYMBOL vmlinux 0xa5808bbf tasklet_init +EXPORT_SYMBOL vmlinux 0xa58b6804 nla_parse +EXPORT_SYMBOL vmlinux 0xa5aa88d2 __scsi_iterate_devices +EXPORT_SYMBOL vmlinux 0xa5c6670e __skb_warn_lro_forwarding +EXPORT_SYMBOL vmlinux 0xa5cef8ad release_resource +EXPORT_SYMBOL vmlinux 0xa611df63 security_sb_clone_mnt_opts +EXPORT_SYMBOL vmlinux 0xa620b844 test_set_page_writeback +EXPORT_SYMBOL vmlinux 0xa6315223 path_permission +EXPORT_SYMBOL vmlinux 0xa64ac513 i2c_attach_client +EXPORT_SYMBOL vmlinux 0xa66d81d5 unmap_underlying_metadata +EXPORT_SYMBOL vmlinux 0xa6777e20 bio_pair_release +EXPORT_SYMBOL vmlinux 0xa68124fa hweight8 +EXPORT_SYMBOL vmlinux 0xa681fe88 generate_random_uuid +EXPORT_SYMBOL vmlinux 0xa68f5cfc __netdev_alloc_skb +EXPORT_SYMBOL vmlinux 0xa6aaa9e9 user_revoke +EXPORT_SYMBOL vmlinux 0xa6c684c1 __iop3xx_ioremap +EXPORT_SYMBOL vmlinux 0xa6c914d0 generic_cont_expand_simple +EXPORT_SYMBOL vmlinux 0xa6dcc773 rb_insert_color +EXPORT_SYMBOL vmlinux 0xa6e1c268 seq_read +EXPORT_SYMBOL vmlinux 0xa7502f48 jiffies_to_timeval +EXPORT_SYMBOL vmlinux 0xa758a6d0 tcf_hash_search +EXPORT_SYMBOL vmlinux 0xa77899eb do_sync_read +EXPORT_SYMBOL vmlinux 0xa7816d1e simple_write_begin +EXPORT_SYMBOL vmlinux 0xa795decd unlock_rename +EXPORT_SYMBOL vmlinux 0xa7b263ec kill_pid +EXPORT_SYMBOL vmlinux 0xa7b91a7b lockd_down +EXPORT_SYMBOL vmlinux 0xa7d5fc4b kmem_cache_create +EXPORT_SYMBOL vmlinux 0xa81d6e54 audit_log_end +EXPORT_SYMBOL vmlinux 0xa82693e1 __secpath_destroy +EXPORT_SYMBOL vmlinux 0xa8306568 inode_get_bytes +EXPORT_SYMBOL vmlinux 0xa832250a unregister_sysrq_key +EXPORT_SYMBOL vmlinux 0xa85d8364 scsi_device_get +EXPORT_SYMBOL vmlinux 0xa8610e9e unlock_buffer +EXPORT_SYMBOL vmlinux 0xa8bd018a filemap_fdatawrite +EXPORT_SYMBOL vmlinux 0xa8d15ebe request_key +EXPORT_SYMBOL vmlinux 0xa8d94e01 dmam_free_noncoherent +EXPORT_SYMBOL vmlinux 0xa8e5ee22 do_munmap +EXPORT_SYMBOL vmlinux 0xa8f95954 journal_restart +EXPORT_SYMBOL vmlinux 0xa8fef7bb security_unix_may_send +EXPORT_SYMBOL vmlinux 0xa9006079 remove_inode_hash +EXPORT_SYMBOL vmlinux 0xa9087467 blk_queue_softirq_done +EXPORT_SYMBOL vmlinux 0xa925899a param_set_bool +EXPORT_SYMBOL vmlinux 0xa9270575 ip_nat_decode_session +EXPORT_SYMBOL vmlinux 0xa93d0b4f devm_ioport_map +EXPORT_SYMBOL vmlinux 0xa969aa2a ip_route_input +EXPORT_SYMBOL vmlinux 0xa9ad27c2 tcf_generic_walker +EXPORT_SYMBOL vmlinux 0xa9bac471 revalidate_disk +EXPORT_SYMBOL vmlinux 0xa9bd21e9 d_delete +EXPORT_SYMBOL vmlinux 0xa9e4752c uart_update_timeout +EXPORT_SYMBOL vmlinux 0xa9f1ed23 bit_waitqueue +EXPORT_SYMBOL vmlinux 0xaa2853fa netdev_class_create_file +EXPORT_SYMBOL vmlinux 0xaa2dff9c tty_port_init +EXPORT_SYMBOL vmlinux 0xaa527612 __kfifo_put +EXPORT_SYMBOL vmlinux 0xaa79ac51 get_write_access +EXPORT_SYMBOL vmlinux 0xaaa6791b skb_dequeue +EXPORT_SYMBOL vmlinux 0xaac10712 iput +EXPORT_SYMBOL vmlinux 0xaacba1e6 tty_throttle +EXPORT_SYMBOL vmlinux 0xaafdc258 strcasecmp +EXPORT_SYMBOL vmlinux 0xab065277 request_firmware +EXPORT_SYMBOL vmlinux 0xab345171 simple_link +EXPORT_SYMBOL vmlinux 0xab471003 param_array_set +EXPORT_SYMBOL vmlinux 0xab53b0a8 mempool_alloc +EXPORT_SYMBOL vmlinux 0xab5bdc17 scsi_nonblockable_ioctl +EXPORT_SYMBOL vmlinux 0xab600421 probe_irq_off +EXPORT_SYMBOL vmlinux 0xab64527d mutex_lock_interruptible +EXPORT_SYMBOL vmlinux 0xab680c96 __down_read_trylock +EXPORT_SYMBOL vmlinux 0xab6abab7 inet_frag_find +EXPORT_SYMBOL vmlinux 0xab8942d9 mii_check_link +EXPORT_SYMBOL vmlinux 0xab9662f1 tty_chars_in_buffer +EXPORT_SYMBOL vmlinux 0xabad83d7 udp_hash_lock +EXPORT_SYMBOL vmlinux 0xabd0c91c rtc_time_to_tm +EXPORT_SYMBOL vmlinux 0xabf8a71b blk_rq_map_sg +EXPORT_SYMBOL vmlinux 0xac27959d svc_sock_update_bufs +EXPORT_SYMBOL vmlinux 0xac3b3cee __bitmap_and +EXPORT_SYMBOL vmlinux 0xac54fc9f mempool_destroy +EXPORT_SYMBOL vmlinux 0xac5f113d cpu_all_bits +EXPORT_SYMBOL vmlinux 0xac609a51 unregister_sysctl_table +EXPORT_SYMBOL vmlinux 0xac84f137 dev_driver_string +EXPORT_SYMBOL vmlinux 0xac89602c __devm_request_region +EXPORT_SYMBOL vmlinux 0xacabba87 xfrm6_input_addr +EXPORT_SYMBOL vmlinux 0xaccabc6a in4_pton +EXPORT_SYMBOL vmlinux 0xacf4d843 match_strdup +EXPORT_SYMBOL vmlinux 0xad0413d4 match_hex +EXPORT_SYMBOL vmlinux 0xad497ee8 udp_flush_pending_frames +EXPORT_SYMBOL vmlinux 0xad5970c8 bdi_set_max_ratio +EXPORT_SYMBOL vmlinux 0xad5dbaf6 pci_bus_read_config_byte +EXPORT_SYMBOL vmlinux 0xadb792c2 prepare_to_wait_exclusive +EXPORT_SYMBOL vmlinux 0xadbda899 con_is_bound +EXPORT_SYMBOL vmlinux 0xadc91e21 __iop3xx_iounmap +EXPORT_SYMBOL vmlinux 0xadd15b4f bio_phys_segments +EXPORT_SYMBOL vmlinux 0xade5e50e pci_find_capability +EXPORT_SYMBOL vmlinux 0xadf4eee0 mb_cache_entry_alloc +EXPORT_SYMBOL vmlinux 0xae066e36 inet_twsk_deschedule +EXPORT_SYMBOL vmlinux 0xae5157bf skb_recv_datagram +EXPORT_SYMBOL vmlinux 0xae7a6554 bdi_destroy +EXPORT_SYMBOL vmlinux 0xae7a7628 xfrm_find_acq +EXPORT_SYMBOL vmlinux 0xaec655c7 alloc_pages_exact +EXPORT_SYMBOL vmlinux 0xaed013b9 posix_acl_valid +EXPORT_SYMBOL vmlinux 0xaf45f3e0 __mark_inode_dirty +EXPORT_SYMBOL vmlinux 0xaf50e76d elf_set_personality +EXPORT_SYMBOL vmlinux 0xaf64ad0d zlib_deflate +EXPORT_SYMBOL vmlinux 0xaf7752fc call_usermodehelper_exec +EXPORT_SYMBOL vmlinux 0xaf802d5b proc_dointvec_userhz_jiffies +EXPORT_SYMBOL vmlinux 0xaf8aa518 system_rev +EXPORT_SYMBOL vmlinux 0xafa4aafe audit_log_start +EXPORT_SYMBOL vmlinux 0xafa67f2d bio_unmap_user +EXPORT_SYMBOL vmlinux 0xafdc3ee0 dma_mark_declared_memory_occupied +EXPORT_SYMBOL vmlinux 0xafe47395 names_cachep +EXPORT_SYMBOL vmlinux 0xb019fdb2 thaw_bdev +EXPORT_SYMBOL vmlinux 0xb06d610b inode_sub_bytes +EXPORT_SYMBOL vmlinux 0xb086b81e inet6_ioctl +EXPORT_SYMBOL vmlinux 0xb0ab3db1 elv_abort_queue +EXPORT_SYMBOL vmlinux 0xb0b209f3 qdisc_calculate_pkt_len +EXPORT_SYMBOL vmlinux 0xb0b7b1fe find_get_page +EXPORT_SYMBOL vmlinux 0xb0b81632 sock_release +EXPORT_SYMBOL vmlinux 0xb0b847ac __bitmap_full +EXPORT_SYMBOL vmlinux 0xb0c84363 tty_register_driver +EXPORT_SYMBOL vmlinux 0xb0e10781 get_option +EXPORT_SYMBOL vmlinux 0xb110e0f8 fasync_helper +EXPORT_SYMBOL vmlinux 0xb121390a probe_irq_on +EXPORT_SYMBOL vmlinux 0xb142e8be dev_close +EXPORT_SYMBOL vmlinux 0xb15f8b4d netdev_features_change +EXPORT_SYMBOL vmlinux 0xb17ab335 netlink_broadcast +EXPORT_SYMBOL vmlinux 0xb18c01ca ethtool_op_set_ufo +EXPORT_SYMBOL vmlinux 0xb18f3f06 ide_xfer_verbose +EXPORT_SYMBOL vmlinux 0xb19760c3 bitmap_onto +EXPORT_SYMBOL vmlinux 0xb1bba137 blk_get_backing_dev_info +EXPORT_SYMBOL vmlinux 0xb1c0cfc1 inet_listen +EXPORT_SYMBOL vmlinux 0xb1c3a01a oops_in_progress +EXPORT_SYMBOL vmlinux 0xb1e66993 tty_write_room +EXPORT_SYMBOL vmlinux 0xb2141585 __bread +EXPORT_SYMBOL vmlinux 0xb2147253 read_cache_page_async +EXPORT_SYMBOL vmlinux 0xb227b57b rtnl_unicast +EXPORT_SYMBOL vmlinux 0xb22fe6a3 netdev_increment_features +EXPORT_SYMBOL vmlinux 0xb2668bcd seq_puts +EXPORT_SYMBOL vmlinux 0xb2906944 key_payload_reserve +EXPORT_SYMBOL vmlinux 0xb29ebd4e neigh_lookup_nodev +EXPORT_SYMBOL vmlinux 0xb2bf1312 __up_read +EXPORT_SYMBOL vmlinux 0xb2db5224 elv_rb_former_request +EXPORT_SYMBOL vmlinux 0xb2fd4e56 ____pagevec_lru_add +EXPORT_SYMBOL vmlinux 0xb307c1bb pci_save_state +EXPORT_SYMBOL vmlinux 0xb30c6cf2 bio_add_pc_page +EXPORT_SYMBOL vmlinux 0xb36a980a kernel_setsockopt +EXPORT_SYMBOL vmlinux 0xb36ffc9b open_by_devnum +EXPORT_SYMBOL vmlinux 0xb372607a kernel_listen +EXPORT_SYMBOL vmlinux 0xb376d79d radix_tree_tagged +EXPORT_SYMBOL vmlinux 0xb37ad437 per_cpu__kstat +EXPORT_SYMBOL vmlinux 0xb3817818 inet_register_protosw +EXPORT_SYMBOL vmlinux 0xb3a307c6 si_meminfo +EXPORT_SYMBOL vmlinux 0xb3d7ce7c generic_file_aio_write_nolock +EXPORT_SYMBOL vmlinux 0xb3db81cd dev_get_by_flags +EXPORT_SYMBOL vmlinux 0xb3fe02b1 down_write +EXPORT_SYMBOL vmlinux 0xb423dba1 console_blanked +EXPORT_SYMBOL vmlinux 0xb43518af tcf_action_dump_1 +EXPORT_SYMBOL vmlinux 0xb44818c0 devm_iounmap +EXPORT_SYMBOL vmlinux 0xb4547540 scsi_register_driver +EXPORT_SYMBOL vmlinux 0xb4637e56 unregister_qdisc +EXPORT_SYMBOL vmlinux 0xb46cb915 journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0xb4773434 remove_arg_zero +EXPORT_SYMBOL vmlinux 0xb4993bdc pci_back_from_sleep +EXPORT_SYMBOL vmlinux 0xb4a0e989 init_timer_deferrable +EXPORT_SYMBOL vmlinux 0xb4e5bca0 get_sb_nodev +EXPORT_SYMBOL vmlinux 0xb5044271 vsscanf +EXPORT_SYMBOL vmlinux 0xb51227eb xfrm_policy_byid +EXPORT_SYMBOL vmlinux 0xb51a7b5d pci_request_selected_regions +EXPORT_SYMBOL vmlinux 0xb534763c sg_free_table +EXPORT_SYMBOL vmlinux 0xb53ba8f8 ipv6_setsockopt +EXPORT_SYMBOL vmlinux 0xb54533f7 usecs_to_jiffies +EXPORT_SYMBOL vmlinux 0xb5a459dc unregister_blkdev +EXPORT_SYMBOL vmlinux 0xb5cfd24b __dev_get_by_index +EXPORT_SYMBOL vmlinux 0xb5e12535 posix_test_lock +EXPORT_SYMBOL vmlinux 0xb60e34a8 nla_memcpy +EXPORT_SYMBOL vmlinux 0xb64742a1 tcf_exts_change +EXPORT_SYMBOL vmlinux 0xb678366f int_sqrt +EXPORT_SYMBOL vmlinux 0xb6811663 scsi_host_put +EXPORT_SYMBOL vmlinux 0xb6a61a86 qdisc_get_rtab +EXPORT_SYMBOL vmlinux 0xb6b720bb iunique +EXPORT_SYMBOL vmlinux 0xb6c5a973 scsi_show_result +EXPORT_SYMBOL vmlinux 0xb6c70a7d __wake_up +EXPORT_SYMBOL vmlinux 0xb703911e release_firmware +EXPORT_SYMBOL vmlinux 0xb714a981 console_print +EXPORT_SYMBOL vmlinux 0xb72fdd5f genl_unregister_ops +EXPORT_SYMBOL vmlinux 0xb746827a put_filp +EXPORT_SYMBOL vmlinux 0xb7555f12 timeval_to_jiffies +EXPORT_SYMBOL vmlinux 0xb76770ea seq_bitmap_list +EXPORT_SYMBOL vmlinux 0xb7772e1d pagecache_write_begin +EXPORT_SYMBOL vmlinux 0xb798898c __napi_schedule +EXPORT_SYMBOL vmlinux 0xb79b977e tcp_connect +EXPORT_SYMBOL vmlinux 0xb7aa1ee1 get_io_context +EXPORT_SYMBOL vmlinux 0xb7ad3321 ida_init +EXPORT_SYMBOL vmlinux 0xb7aee3c3 arp_find +EXPORT_SYMBOL vmlinux 0xb7b61546 crc32_be +EXPORT_SYMBOL vmlinux 0xb813070b drive_is_ready +EXPORT_SYMBOL vmlinux 0xb8158dcd end_buffer_read_sync +EXPORT_SYMBOL vmlinux 0xb81c95e6 iget_locked +EXPORT_SYMBOL vmlinux 0xb859f38b krealloc +EXPORT_SYMBOL vmlinux 0xb86e4ab9 random32 +EXPORT_SYMBOL vmlinux 0xb89af9bf srandom32 +EXPORT_SYMBOL vmlinux 0xb8aa2342 __check_region +EXPORT_SYMBOL vmlinux 0xb8af4f9e pci_fixup_device +EXPORT_SYMBOL vmlinux 0xb8bb63b6 ethtool_op_set_sg +EXPORT_SYMBOL vmlinux 0xb8e1c18f auth_domain_put +EXPORT_SYMBOL vmlinux 0xb8e88ec5 __ip_select_ident +EXPORT_SYMBOL vmlinux 0xb8ff8d57 kill_fasync +EXPORT_SYMBOL vmlinux 0xb905ad82 icmpv6_err_convert +EXPORT_SYMBOL vmlinux 0xb918bb8f blk_put_request +EXPORT_SYMBOL vmlinux 0xb91a8bfc vfs_read +EXPORT_SYMBOL vmlinux 0xb9383a8c sk_stream_wait_connect +EXPORT_SYMBOL vmlinux 0xb939d33b elv_rb_find +EXPORT_SYMBOL vmlinux 0xb94494ff blk_queue_max_hw_segments +EXPORT_SYMBOL vmlinux 0xb95f98d6 _memset_io +EXPORT_SYMBOL vmlinux 0xb97c3398 ip6_xmit +EXPORT_SYMBOL vmlinux 0xb97d4c9c mutex_lock +EXPORT_SYMBOL vmlinux 0xb97e5a94 uart_get_divisor +EXPORT_SYMBOL vmlinux 0xb98a0185 rtc_tm_to_time +EXPORT_SYMBOL vmlinux 0xb98ef804 vm_stat +EXPORT_SYMBOL vmlinux 0xb9acd3d9 __put_user_2 +EXPORT_SYMBOL vmlinux 0xb9b0f312 __blockdev_direct_IO +EXPORT_SYMBOL vmlinux 0xb9c74bf1 gen_kill_estimator +EXPORT_SYMBOL vmlinux 0xb9ddab34 alloc_disk_node +EXPORT_SYMBOL vmlinux 0xb9ffc822 input_get_keycode +EXPORT_SYMBOL vmlinux 0xba0e8e12 dst_destroy +EXPORT_SYMBOL vmlinux 0xba103723 scsi_track_queue_full +EXPORT_SYMBOL vmlinux 0xba3bda2a __downgrade_write +EXPORT_SYMBOL vmlinux 0xba497f13 loops_per_jiffy +EXPORT_SYMBOL vmlinux 0xba5078fd xscale_flush_kern_cache_all +EXPORT_SYMBOL vmlinux 0xba8f8b68 completion_done +EXPORT_SYMBOL vmlinux 0xbaba703c complete_request_key +EXPORT_SYMBOL vmlinux 0xbacd9655 nf_log_unregister +EXPORT_SYMBOL vmlinux 0xbad26e3d skb_trim +EXPORT_SYMBOL vmlinux 0xbae166c1 block_read_full_page +EXPORT_SYMBOL vmlinux 0xbae46304 vfs_llseek +EXPORT_SYMBOL vmlinux 0xbb0fae42 fifo_create_dflt +EXPORT_SYMBOL vmlinux 0xbb189cad disallow_signal +EXPORT_SYMBOL vmlinux 0xbb1960d4 ethtool_op_get_sg +EXPORT_SYMBOL vmlinux 0xbb4c3c39 skb_gso_segment +EXPORT_SYMBOL vmlinux 0xbb53541a input_release_device +EXPORT_SYMBOL vmlinux 0xbb54dc25 pci_clear_mwi +EXPORT_SYMBOL vmlinux 0xbb5d343d xfrm_get_acqseq +EXPORT_SYMBOL vmlinux 0xbb72d4fe __put_user_1 +EXPORT_SYMBOL vmlinux 0xbb91259a generic_writepages +EXPORT_SYMBOL vmlinux 0xbbc8e804 param_set_ushort +EXPORT_SYMBOL vmlinux 0xbbd2c0d0 journal_check_used_features +EXPORT_SYMBOL vmlinux 0xbbdf0fb6 gnet_stats_start_copy_compat +EXPORT_SYMBOL vmlinux 0xbc10dd97 __put_user_4 +EXPORT_SYMBOL vmlinux 0xbcb6cf7e tty_register_ldisc +EXPORT_SYMBOL vmlinux 0xbd10b2c4 cfi_read_pri +EXPORT_SYMBOL vmlinux 0xbd498eb7 mii_check_media +EXPORT_SYMBOL vmlinux 0xbd5fc9af journal_invalidatepage +EXPORT_SYMBOL vmlinux 0xbd7fd44c blkdev_issue_flush +EXPORT_SYMBOL vmlinux 0xbda38f43 xfrm_state_check_expire +EXPORT_SYMBOL vmlinux 0xbdaa7584 xfrm_input +EXPORT_SYMBOL vmlinux 0xbdc5c9e3 dma_free_coherent +EXPORT_SYMBOL vmlinux 0xbdf2580d __raw_readsl +EXPORT_SYMBOL vmlinux 0xbdf53b18 rpc_mkpipe +EXPORT_SYMBOL vmlinux 0xbe0e5118 nla_memcmp +EXPORT_SYMBOL vmlinux 0xbe3bcede sock_no_poll +EXPORT_SYMBOL vmlinux 0xbe4668c2 pci_find_bus +EXPORT_SYMBOL vmlinux 0xbe56b751 vmalloc_to_page +EXPORT_SYMBOL vmlinux 0xbe63ee40 request_resource +EXPORT_SYMBOL vmlinux 0xbe82135b cad_pid +EXPORT_SYMBOL vmlinux 0xbedb476c dma_async_device_register +EXPORT_SYMBOL vmlinux 0xbedc4434 svc_create +EXPORT_SYMBOL vmlinux 0xbef43296 console_conditional_schedule +EXPORT_SYMBOL vmlinux 0xbf555fef devm_ioremap +EXPORT_SYMBOL vmlinux 0xbf5f27ca svc_create_pooled +EXPORT_SYMBOL vmlinux 0xbf7fd2f5 schedule_timeout_killable +EXPORT_SYMBOL vmlinux 0xbf95d1bf tty_unregister_device +EXPORT_SYMBOL vmlinux 0xbf98015d single_open +EXPORT_SYMBOL vmlinux 0xbf9bcc8d __cap_empty_set +EXPORT_SYMBOL vmlinux 0xbfa08d74 __starget_for_each_device +EXPORT_SYMBOL vmlinux 0xbfb95707 tcp_getsockopt +EXPORT_SYMBOL vmlinux 0xbfee3ad5 loop_unregister_transfer +EXPORT_SYMBOL vmlinux 0xbffcd9fe take_over_console +EXPORT_SYMBOL vmlinux 0xbfffc81a scsi_free_command +EXPORT_SYMBOL vmlinux 0xc0083efc default_unplug_io_fn +EXPORT_SYMBOL vmlinux 0xc045ad4e timespec_trunc +EXPORT_SYMBOL vmlinux 0xc0580937 rb_erase +EXPORT_SYMBOL vmlinux 0xc05ddd5f aio_put_req +EXPORT_SYMBOL vmlinux 0xc0651343 scsi_rescan_device +EXPORT_SYMBOL vmlinux 0xc0af9505 mb_cache_entry_find_next +EXPORT_SYMBOL vmlinux 0xc0b92264 dma_async_tx_descriptor_init +EXPORT_SYMBOL vmlinux 0xc0cacb0e kernel_recvmsg +EXPORT_SYMBOL vmlinux 0xc0ec0143 neigh_table_init_no_netlink +EXPORT_SYMBOL vmlinux 0xc0ede45f wake_up_process +EXPORT_SYMBOL vmlinux 0xc11d8093 iov_shorten +EXPORT_SYMBOL vmlinux 0xc13be716 ipv6_dev_get_saddr +EXPORT_SYMBOL vmlinux 0xc13c2acd nobh_truncate_page +EXPORT_SYMBOL vmlinux 0xc1601a4f _change_bit_le +EXPORT_SYMBOL vmlinux 0xc1615561 scsi_is_host_device +EXPORT_SYMBOL vmlinux 0xc17ab904 sk_receive_skb +EXPORT_SYMBOL vmlinux 0xc180b93a ip_mc_rejoin_group +EXPORT_SYMBOL vmlinux 0xc1c435e4 xdr_encode_word +EXPORT_SYMBOL vmlinux 0xc1fc4511 _test_and_change_bit_le +EXPORT_SYMBOL vmlinux 0xc1fcd53a ip_fragment +EXPORT_SYMBOL vmlinux 0xc22616f1 __init_rwsem +EXPORT_SYMBOL vmlinux 0xc24c2ede pci_bus_write_config_dword +EXPORT_SYMBOL vmlinux 0xc256e762 __bitmap_equal +EXPORT_SYMBOL vmlinux 0xc2617f1e blk_queue_dma_pad +EXPORT_SYMBOL vmlinux 0xc2677d5f dmam_pool_destroy +EXPORT_SYMBOL vmlinux 0xc27487dd __bug +EXPORT_SYMBOL vmlinux 0xc2e587d1 reset_devices +EXPORT_SYMBOL vmlinux 0xc303aa7a mpage_writepage +EXPORT_SYMBOL vmlinux 0xc3458cb8 proc_dointvec +EXPORT_SYMBOL vmlinux 0xc359fb65 abort +EXPORT_SYMBOL vmlinux 0xc37e5b7d sock_no_socketpair +EXPORT_SYMBOL vmlinux 0xc380c838 km_policy_notify +EXPORT_SYMBOL vmlinux 0xc3880471 xdr_decode_netobj +EXPORT_SYMBOL vmlinux 0xc3c19d02 seq_putc +EXPORT_SYMBOL vmlinux 0xc3cf1128 in_group_p +EXPORT_SYMBOL vmlinux 0xc41fc953 gnet_stats_start_copy +EXPORT_SYMBOL vmlinux 0xc43cdd21 bdi_register +EXPORT_SYMBOL vmlinux 0xc43f5bc9 set_binfmt +EXPORT_SYMBOL vmlinux 0xc440c451 sg_alloc_table +EXPORT_SYMBOL vmlinux 0xc458424f inode_setattr +EXPORT_SYMBOL vmlinux 0xc499ae1e kstrdup +EXPORT_SYMBOL vmlinux 0xc4bda4ff proto_unregister +EXPORT_SYMBOL vmlinux 0xc4ce1db3 blk_rq_map_user_iov +EXPORT_SYMBOL vmlinux 0xc507fcd2 free_task +EXPORT_SYMBOL vmlinux 0xc534c7dc journal_ack_err +EXPORT_SYMBOL vmlinux 0xc565508a scsi_report_bus_reset +EXPORT_SYMBOL vmlinux 0xc57ad0e4 pcibios_fixup_bus +EXPORT_SYMBOL vmlinux 0xc5921465 netdev_class_remove_file +EXPORT_SYMBOL vmlinux 0xc5dea5ed input_open_device +EXPORT_SYMBOL vmlinux 0xc5e27537 unregister_con_driver +EXPORT_SYMBOL vmlinux 0xc633495b schedule_work +EXPORT_SYMBOL vmlinux 0xc651dfef __netif_schedule +EXPORT_SYMBOL vmlinux 0xc686ea5d tty_wait_until_sent +EXPORT_SYMBOL vmlinux 0xc6974279 xfrm_alloc_spi +EXPORT_SYMBOL vmlinux 0xc6d826ba tcp_sendpage +EXPORT_SYMBOL vmlinux 0xc70e49d5 vc_cons +EXPORT_SYMBOL vmlinux 0xc7208c3a serial8250_resume_port +EXPORT_SYMBOL vmlinux 0xc722227e posix_acl_clone +EXPORT_SYMBOL vmlinux 0xc766cad8 alloc_pci_dev +EXPORT_SYMBOL vmlinux 0xc77b465d mpage_bio_submit +EXPORT_SYMBOL vmlinux 0xc7a4fbed rtnl_lock +EXPORT_SYMBOL vmlinux 0xc7b84983 neigh_sysctl_unregister +EXPORT_SYMBOL vmlinux 0xc7cde85e ide_end_drive_cmd +EXPORT_SYMBOL vmlinux 0xc7eb2c41 __pci_register_driver +EXPORT_SYMBOL vmlinux 0xc7ec6c27 strspn +EXPORT_SYMBOL vmlinux 0xc7f8874b seq_escape +EXPORT_SYMBOL vmlinux 0xc7ffd897 i2c_add_adapter +EXPORT_SYMBOL vmlinux 0xc80de694 down_write_trylock +EXPORT_SYMBOL vmlinux 0xc814b4cd inet_frag_destroy +EXPORT_SYMBOL vmlinux 0xc81c7f70 d_alloc_root +EXPORT_SYMBOL vmlinux 0xc84180c7 ip6_route_output +EXPORT_SYMBOL vmlinux 0xc8581a3b km_new_mapping +EXPORT_SYMBOL vmlinux 0xc8611bc3 xfrm_policy_unregister_afinfo +EXPORT_SYMBOL vmlinux 0xc8734158 dev_mc_delete +EXPORT_SYMBOL vmlinux 0xc8893d1d simple_transaction_get +EXPORT_SYMBOL vmlinux 0xc8b57c27 autoremove_wake_function +EXPORT_SYMBOL vmlinux 0xc8be701e map_destroy +EXPORT_SYMBOL vmlinux 0xc8e96dea qword_addhex +EXPORT_SYMBOL vmlinux 0xc8f761e8 find_task_by_pid_type_ns +EXPORT_SYMBOL vmlinux 0xc911616a devm_request_irq +EXPORT_SYMBOL vmlinux 0xc91822f0 netlink_dump_start +EXPORT_SYMBOL vmlinux 0xc92e6910 blk_queue_init_tags +EXPORT_SYMBOL vmlinux 0xc933f34d netlink_ack +EXPORT_SYMBOL vmlinux 0xc96d7e9a locks_copy_lock +EXPORT_SYMBOL vmlinux 0xc998d641 icmp_err_convert +EXPORT_SYMBOL vmlinux 0xc99e045b devm_ioport_unmap +EXPORT_SYMBOL vmlinux 0xc9abc170 genl_register_ops +EXPORT_SYMBOL vmlinux 0xc9b9a39c follow_up +EXPORT_SYMBOL vmlinux 0xc9bad557 skb_unlink +EXPORT_SYMBOL vmlinux 0xc9ebe32b tcp_v4_do_rcv +EXPORT_SYMBOL vmlinux 0xca1e6060 ethtool_op_get_tso +EXPORT_SYMBOL vmlinux 0xca5dbc50 scsi_print_sense_hdr +EXPORT_SYMBOL vmlinux 0xcb32da10 param_set_int +EXPORT_SYMBOL vmlinux 0xcb6beb40 hweight32 +EXPORT_SYMBOL vmlinux 0xcb7cb7ab inet_frag_evictor +EXPORT_SYMBOL vmlinux 0xcb85d567 ide_set_handler +EXPORT_SYMBOL vmlinux 0xcb966c37 pci_restore_state +EXPORT_SYMBOL vmlinux 0xcbbb1c1f ip_dev_find +EXPORT_SYMBOL vmlinux 0xcc199a63 skb_clone +EXPORT_SYMBOL vmlinux 0xcc248d26 serial8250_suspend_port +EXPORT_SYMBOL vmlinux 0xcc36f32e fb_unregister_client +EXPORT_SYMBOL vmlinux 0xcc4cb3a5 i2c_smbus_write_block_data +EXPORT_SYMBOL vmlinux 0xcc5005fe msleep_interruptible +EXPORT_SYMBOL vmlinux 0xcc726aa0 read_cache_pages +EXPORT_SYMBOL vmlinux 0xcc7bfaf7 arp_send +EXPORT_SYMBOL vmlinux 0xcc7fa952 local_bh_enable_ip +EXPORT_SYMBOL vmlinux 0xcca9184f vfs_follow_link +EXPORT_SYMBOL vmlinux 0xcccca482 _test_and_clear_bit_le +EXPORT_SYMBOL vmlinux 0xcd0c143f update_region +EXPORT_SYMBOL vmlinux 0xcd63c845 __aeabi_lasr +EXPORT_SYMBOL vmlinux 0xcdc51f2d sock_no_bind +EXPORT_SYMBOL vmlinux 0xce0579de auth_unix_lookup +EXPORT_SYMBOL vmlinux 0xce0740b6 pci_bus_alloc_resource +EXPORT_SYMBOL vmlinux 0xce19bac5 register_inet6addr_notifier +EXPORT_SYMBOL vmlinux 0xce36ded6 sysctl_tcp_mem +EXPORT_SYMBOL vmlinux 0xce5ac24f zlib_inflate_workspacesize +EXPORT_SYMBOL vmlinux 0xce682171 ide_stall_queue +EXPORT_SYMBOL vmlinux 0xced40ff0 pci_dev_put +EXPORT_SYMBOL vmlinux 0xcee024d0 alloc_disk +EXPORT_SYMBOL vmlinux 0xcef201cd get_iop_tick_rate +EXPORT_SYMBOL vmlinux 0xcefa73c8 pci_get_class +EXPORT_SYMBOL vmlinux 0xcefcd99a serial8250_unregister_port +EXPORT_SYMBOL vmlinux 0xcf3d833a nf_unregister_sockopt +EXPORT_SYMBOL vmlinux 0xcf6409b0 inode_init_once +EXPORT_SYMBOL vmlinux 0xcf691c51 proc_dointvec_minmax +EXPORT_SYMBOL vmlinux 0xcfd3018e set_normalized_timespec +EXPORT_SYMBOL vmlinux 0xcff53400 kref_put +EXPORT_SYMBOL vmlinux 0xcffc1a01 inet_frag_kill +EXPORT_SYMBOL vmlinux 0xd0181f4f __bitmap_xor +EXPORT_SYMBOL vmlinux 0xd018ed20 inet6_bind +EXPORT_SYMBOL vmlinux 0xd02cc869 __bitmap_andnot +EXPORT_SYMBOL vmlinux 0xd057ec78 bio_uncopy_user +EXPORT_SYMBOL vmlinux 0xd0726f8d __scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0xd08b7899 icmp_send +EXPORT_SYMBOL vmlinux 0xd0ae14cc inet_frags_init +EXPORT_SYMBOL vmlinux 0xd0c1b193 netif_device_attach +EXPORT_SYMBOL vmlinux 0xd0ee38b8 schedule_timeout_uninterruptible +EXPORT_SYMBOL vmlinux 0xd10fa297 vlan_ioctl_set +EXPORT_SYMBOL vmlinux 0xd1162f72 dcache_readdir +EXPORT_SYMBOL vmlinux 0xd15b6f0a __page_symlink +EXPORT_SYMBOL vmlinux 0xd168d8b9 cpu_xscale_dcache_clean_area +EXPORT_SYMBOL vmlinux 0xd18669cb kmem_cache_free +EXPORT_SYMBOL vmlinux 0xd1b4df64 scsi_scan_host +EXPORT_SYMBOL vmlinux 0xd1b51e96 uart_suspend_port +EXPORT_SYMBOL vmlinux 0xd1bdc1d4 block_commit_write +EXPORT_SYMBOL vmlinux 0xd1da8458 gnet_stats_copy_app +EXPORT_SYMBOL vmlinux 0xd1f62639 xfrm4_rcv_encap +EXPORT_SYMBOL vmlinux 0xd2075d17 bio_add_page +EXPORT_SYMBOL vmlinux 0xd23765b0 ip_mc_join_group +EXPORT_SYMBOL vmlinux 0xd243fe98 scsi_finish_command +EXPORT_SYMBOL vmlinux 0xd251d7b0 security_socket_getpeersec_dgram +EXPORT_SYMBOL vmlinux 0xd2555f19 jiffies_64_to_clock_t +EXPORT_SYMBOL vmlinux 0xd25d4f74 console_blank_hook +EXPORT_SYMBOL vmlinux 0xd26d43ac tcf_action_exec +EXPORT_SYMBOL vmlinux 0xd2965f6f kthread_should_stop +EXPORT_SYMBOL vmlinux 0xd2a30421 __pskb_pull_tail +EXPORT_SYMBOL vmlinux 0xd2a7f5d2 sysctl_jiffies +EXPORT_SYMBOL vmlinux 0xd2b9fe8d generic_file_llseek +EXPORT_SYMBOL vmlinux 0xd2bf6e3f pci_find_device +EXPORT_SYMBOL vmlinux 0xd30cb83f svc_proc_register +EXPORT_SYMBOL vmlinux 0xd32d7f67 kset_register +EXPORT_SYMBOL vmlinux 0xd32e52c7 posix_acl_chmod_masq +EXPORT_SYMBOL vmlinux 0xd3427f73 mempool_create_node +EXPORT_SYMBOL vmlinux 0xd3625716 generic_file_aio_write +EXPORT_SYMBOL vmlinux 0xd3c0b998 uart_register_driver +EXPORT_SYMBOL vmlinux 0xd3dbfbc4 _find_first_zero_bit_le +EXPORT_SYMBOL vmlinux 0xd3f0774e locks_remove_posix +EXPORT_SYMBOL vmlinux 0xd418e1c0 adjust_resource +EXPORT_SYMBOL vmlinux 0xd434d1d3 pci_set_power_state +EXPORT_SYMBOL vmlinux 0xd43e796e xdr_process_buf +EXPORT_SYMBOL vmlinux 0xd446751f scsi_block_when_processing_errors +EXPORT_SYMBOL vmlinux 0xd46f86d2 qdisc_create_dflt +EXPORT_SYMBOL vmlinux 0xd4a29f65 kmem_cache_shrink +EXPORT_SYMBOL vmlinux 0xd4cddc5c path_put +EXPORT_SYMBOL vmlinux 0xd4f6e741 i2c_smbus_write_byte +EXPORT_SYMBOL vmlinux 0xd51e9b43 cont_write_begin +EXPORT_SYMBOL vmlinux 0xd5263820 mb_cache_destroy +EXPORT_SYMBOL vmlinux 0xd5376b9d __breadahead +EXPORT_SYMBOL vmlinux 0xd53be617 blk_rq_init +EXPORT_SYMBOL vmlinux 0xd5688a7a radix_tree_insert +EXPORT_SYMBOL vmlinux 0xd57c4006 vfs_writev +EXPORT_SYMBOL vmlinux 0xd5924aaf sock_create +EXPORT_SYMBOL vmlinux 0xd5d91505 generic_ide_ioctl +EXPORT_SYMBOL vmlinux 0xd5ddf8e7 set_bh_page +EXPORT_SYMBOL vmlinux 0xd6035d05 do_settimeofday +EXPORT_SYMBOL vmlinux 0xd610afd1 journal_load +EXPORT_SYMBOL vmlinux 0xd627480b strncat +EXPORT_SYMBOL vmlinux 0xd62c833f schedule_timeout +EXPORT_SYMBOL vmlinux 0xd6488f01 tty_insert_flip_string +EXPORT_SYMBOL vmlinux 0xd649498e kernel_read +EXPORT_SYMBOL vmlinux 0xd66c6228 down_read_trylock +EXPORT_SYMBOL vmlinux 0xd695ef6d invalidate_inode_buffers +EXPORT_SYMBOL vmlinux 0xd6ee688f vmalloc +EXPORT_SYMBOL vmlinux 0xd72e1199 vfs_write +EXPORT_SYMBOL vmlinux 0xd732a097 qdisc_watchdog_schedule +EXPORT_SYMBOL vmlinux 0xd74c6523 journal_start_commit +EXPORT_SYMBOL vmlinux 0xd76122fc seq_release_private +EXPORT_SYMBOL vmlinux 0xd77208a4 __sk_mem_reclaim +EXPORT_SYMBOL vmlinux 0xd7832914 vm_map_ram +EXPORT_SYMBOL vmlinux 0xd7837aaf qdisc_class_hash_grow +EXPORT_SYMBOL vmlinux 0xd78ccf8b neigh_seq_next +EXPORT_SYMBOL vmlinux 0xd79b5a02 allow_signal +EXPORT_SYMBOL vmlinux 0xd7b69fae idr_find +EXPORT_SYMBOL vmlinux 0xd8094ec9 do_map_probe +EXPORT_SYMBOL vmlinux 0xd81af100 __rta_fill +EXPORT_SYMBOL vmlinux 0xd8282ff0 posix_acl_equiv_mode +EXPORT_SYMBOL vmlinux 0xd8a2ab95 in_egroup_p +EXPORT_SYMBOL vmlinux 0xd8b83685 udplite_prot +EXPORT_SYMBOL vmlinux 0xd8c1bca9 block_write_end +EXPORT_SYMBOL vmlinux 0xd8e484f0 register_chrdev_region +EXPORT_SYMBOL vmlinux 0xd90fd291 nf_log_packet +EXPORT_SYMBOL vmlinux 0xd93cd7a9 sg_miter_next +EXPORT_SYMBOL vmlinux 0xd947aecb vfs_link +EXPORT_SYMBOL vmlinux 0xd985dc99 mempool_free_pages +EXPORT_SYMBOL vmlinux 0xd9987476 vfs_readdir +EXPORT_SYMBOL vmlinux 0xd9b90c9a register_sysctl_paths +EXPORT_SYMBOL vmlinux 0xd9be6543 sock_no_shutdown +EXPORT_SYMBOL vmlinux 0xd9ce8f0c strnlen +EXPORT_SYMBOL vmlinux 0xda1a7335 kasprintf +EXPORT_SYMBOL vmlinux 0xda5898bd pci_iounmap +EXPORT_SYMBOL vmlinux 0xda5ea696 _test_and_set_bit_le +EXPORT_SYMBOL vmlinux 0xda816a1a zero_fill_bio +EXPORT_SYMBOL vmlinux 0xda8b5096 xfrm_cfg_mutex +EXPORT_SYMBOL vmlinux 0xdaa73ab0 inet_dgram_ops +EXPORT_SYMBOL vmlinux 0xdad92593 scsi_host_alloc +EXPORT_SYMBOL vmlinux 0xdafe2bbf inet6_add_protocol +EXPORT_SYMBOL vmlinux 0xdb1be968 ide_execute_command +EXPORT_SYMBOL vmlinux 0xdb2f4319 tcf_destroy_chain +EXPORT_SYMBOL vmlinux 0xdb41cca5 inode_double_lock +EXPORT_SYMBOL vmlinux 0xdb428d5d dst_release +EXPORT_SYMBOL vmlinux 0xdb4454f0 log_wait_commit +EXPORT_SYMBOL vmlinux 0xdb4a6ffa blkdev_issue_discard +EXPORT_SYMBOL vmlinux 0xdb578301 skb_copy_and_csum_datagram_iovec +EXPORT_SYMBOL vmlinux 0xdb5bd858 d_add_ci +EXPORT_SYMBOL vmlinux 0xdb864d65 iov_iter_single_seg_count +EXPORT_SYMBOL vmlinux 0xdbcd416e sysctl_ip_nonlocal_bind +EXPORT_SYMBOL vmlinux 0xdbd4c637 tcp_hashinfo +EXPORT_SYMBOL vmlinux 0xdbd88ad2 simple_lookup +EXPORT_SYMBOL vmlinux 0xdc053205 udp_memory_allocated +EXPORT_SYMBOL vmlinux 0xdc126bad kernel_accept +EXPORT_SYMBOL vmlinux 0xdc14eda7 pci_pci_problems +EXPORT_SYMBOL vmlinux 0xdc28c40f should_remove_suid +EXPORT_SYMBOL vmlinux 0xdc2adb35 add_taint +EXPORT_SYMBOL vmlinux 0xdc3f6d82 pci_iomap +EXPORT_SYMBOL vmlinux 0xdc43a9c8 daemonize +EXPORT_SYMBOL vmlinux 0xdc44a20d tty_unregister_driver +EXPORT_SYMBOL vmlinux 0xdc477d66 __nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0xdc4b4b01 i2c_smbus_write_word_data +EXPORT_SYMBOL vmlinux 0xdca89019 pci_bus_find_capability +EXPORT_SYMBOL vmlinux 0xdcb0349b sys_close +EXPORT_SYMBOL vmlinux 0xdcbd204f km_state_notify +EXPORT_SYMBOL vmlinux 0xdcd76eb9 pcim_iomap_regions_request_all +EXPORT_SYMBOL vmlinux 0xdd0a2ba2 strlcat +EXPORT_SYMBOL vmlinux 0xdd17f5d0 elv_queue_empty +EXPORT_SYMBOL vmlinux 0xdd27fa87 memchr +EXPORT_SYMBOL vmlinux 0xdd3d74e6 blk_alloc_queue_node +EXPORT_SYMBOL vmlinux 0xdd5384cc inode_double_unlock +EXPORT_SYMBOL vmlinux 0xdd6bfccd radix_tree_tag_set +EXPORT_SYMBOL vmlinux 0xdd735293 open_exec +EXPORT_SYMBOL vmlinux 0xdd75cc87 uart_get_baud_rate +EXPORT_SYMBOL vmlinux 0xdd871edc tty_port_alloc_xmit_buf +EXPORT_SYMBOL vmlinux 0xddb2b4c3 setup_arg_pages +EXPORT_SYMBOL vmlinux 0xddc38c55 __insert_inode_hash +EXPORT_SYMBOL vmlinux 0xddcd1b43 i2c_master_recv +EXPORT_SYMBOL vmlinux 0xddeef053 vfs_stat +EXPORT_SYMBOL vmlinux 0xde0c4fd0 elv_rq_merge_ok +EXPORT_SYMBOL vmlinux 0xde43f2fb file_remove_suid +EXPORT_SYMBOL vmlinux 0xde5fbde1 pci_wake_from_d3 +EXPORT_SYMBOL vmlinux 0xde6943fd do_SAK +EXPORT_SYMBOL vmlinux 0xde72cf31 register_exec_domain +EXPORT_SYMBOL vmlinux 0xde734cf4 dev_open +EXPORT_SYMBOL vmlinux 0xde75b689 set_irq_type +EXPORT_SYMBOL vmlinux 0xde7a4418 tty_hangup +EXPORT_SYMBOL vmlinux 0xde820204 seq_open +EXPORT_SYMBOL vmlinux 0xde9360ba totalram_pages +EXPORT_SYMBOL vmlinux 0xdea0f209 xfrm6_prepare_output +EXPORT_SYMBOL vmlinux 0xdeed0c95 scsicam_bios_param +EXPORT_SYMBOL vmlinux 0xdef583ca call_usermodehelper_setup +EXPORT_SYMBOL vmlinux 0xdf0715f5 proto_register +EXPORT_SYMBOL vmlinux 0xdf1d17cd kill_block_super +EXPORT_SYMBOL vmlinux 0xdf2cf1d6 kill_litter_super +EXPORT_SYMBOL vmlinux 0xdf60cc27 __print_symbol +EXPORT_SYMBOL vmlinux 0xdf929370 fs_overflowgid +EXPORT_SYMBOL vmlinux 0xdfcd7ae1 aio_complete +EXPORT_SYMBOL vmlinux 0xe00cc225 sysctl_string +EXPORT_SYMBOL vmlinux 0xe02baa90 I_BDEV +EXPORT_SYMBOL vmlinux 0xe05f3537 ip_queue_xmit +EXPORT_SYMBOL vmlinux 0xe075d6eb iter_div_u64_rem +EXPORT_SYMBOL vmlinux 0xe0878bfe __krealloc +EXPORT_SYMBOL vmlinux 0xe08b15cb blk_run_queue +EXPORT_SYMBOL vmlinux 0xe08cb4fa kobject_add +EXPORT_SYMBOL vmlinux 0xe096d680 pci_set_dma_max_seg_size +EXPORT_SYMBOL vmlinux 0xe09b108d nlmsg_notify +EXPORT_SYMBOL vmlinux 0xe0b13336 argv_free +EXPORT_SYMBOL vmlinux 0xe0bc349f iget_failed +EXPORT_SYMBOL vmlinux 0xe10046b8 inet_csk_reset_keepalive_timer +EXPORT_SYMBOL vmlinux 0xe113bbbc csum_partial +EXPORT_SYMBOL vmlinux 0xe1242a1b proc_doulongvec_minmax +EXPORT_SYMBOL vmlinux 0xe1310a68 ide_do_drive_cmd +EXPORT_SYMBOL vmlinux 0xe13f6820 contig_page_data +EXPORT_SYMBOL vmlinux 0xe14aa18f pneigh_lookup +EXPORT_SYMBOL vmlinux 0xe1761617 security_inet_conn_request +EXPORT_SYMBOL vmlinux 0xe1a81c3a icmpv6msg_statistics +EXPORT_SYMBOL vmlinux 0xe1b25e78 inet6_register_protosw +EXPORT_SYMBOL vmlinux 0xe1d44a1d svc_auth_register +EXPORT_SYMBOL vmlinux 0xe20249f6 dma_async_memcpy_buf_to_pg +EXPORT_SYMBOL vmlinux 0xe204c128 create_proc_entry +EXPORT_SYMBOL vmlinux 0xe212f64f find_get_pages_tag +EXPORT_SYMBOL vmlinux 0xe24af4a6 svc_set_num_threads +EXPORT_SYMBOL vmlinux 0xe24d3a97 jiffies_64 +EXPORT_SYMBOL vmlinux 0xe24de4b6 ilookup5 +EXPORT_SYMBOL vmlinux 0xe283918c get_user_pages +EXPORT_SYMBOL vmlinux 0xe2b25970 neigh_compat_output +EXPORT_SYMBOL vmlinux 0xe2c60c09 svcauth_unix_set_client +EXPORT_SYMBOL vmlinux 0xe2d5255a strcmp +EXPORT_SYMBOL vmlinux 0xe2dd6400 neigh_sysctl_register +EXPORT_SYMBOL vmlinux 0xe2fae716 kmemdup +EXPORT_SYMBOL vmlinux 0xe31f6503 gnet_stats_copy_queue +EXPORT_SYMBOL vmlinux 0xe33f53a4 kmem_ptr_validate +EXPORT_SYMBOL vmlinux 0xe351633f genl_register_family +EXPORT_SYMBOL vmlinux 0xe39e2077 unregister_binfmt +EXPORT_SYMBOL vmlinux 0xe3ba9e1d scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0xe3d48bdc pskb_copy +EXPORT_SYMBOL vmlinux 0xe3d4eb0e fifo_set_limit +EXPORT_SYMBOL vmlinux 0xe3f16695 blkdev_put +EXPORT_SYMBOL vmlinux 0xe44164ba blk_queue_find_tag +EXPORT_SYMBOL vmlinux 0xe4a97c71 __down_write_trylock +EXPORT_SYMBOL vmlinux 0xe4c425c7 tcp_v4_conn_request +EXPORT_SYMBOL vmlinux 0xe4c80097 cacheid +EXPORT_SYMBOL vmlinux 0xe4dcedc1 xfrm_state_insert +EXPORT_SYMBOL vmlinux 0xe500ce1d pci_get_subsys +EXPORT_SYMBOL vmlinux 0xe57878a1 in6_pton +EXPORT_SYMBOL vmlinux 0xe5867808 dlci_ioctl_set +EXPORT_SYMBOL vmlinux 0xe5919cb1 xdr_encode_opaque +EXPORT_SYMBOL vmlinux 0xe5c78a99 do_blank_screen +EXPORT_SYMBOL vmlinux 0xe5e68f85 udp_lib_setsockopt +EXPORT_SYMBOL vmlinux 0xe5ed5467 xfrm_policy_walk_init +EXPORT_SYMBOL vmlinux 0xe623f4a5 inet_put_port +EXPORT_SYMBOL vmlinux 0xe62a0c62 sock_queue_rcv_skb +EXPORT_SYMBOL vmlinux 0xe66f9391 unregister_netdevice +EXPORT_SYMBOL vmlinux 0xe690b8fd __ipv6_isatap_ifid +EXPORT_SYMBOL vmlinux 0xe6c3ebb0 __raw_writesw +EXPORT_SYMBOL vmlinux 0xe6c850cb empty_zero_page +EXPORT_SYMBOL vmlinux 0xe6db2c40 xfrm_state_unregister_afinfo +EXPORT_SYMBOL vmlinux 0xe6ebc016 key_create_or_update +EXPORT_SYMBOL vmlinux 0xe6f38023 xfrm4_rcv +EXPORT_SYMBOL vmlinux 0xe6fbe430 can_do_mlock +EXPORT_SYMBOL vmlinux 0xe707d823 __aeabi_uidiv +EXPORT_SYMBOL vmlinux 0xe7b1dba9 sock_sendmsg +EXPORT_SYMBOL vmlinux 0xe7c84912 ilookup5_nowait +EXPORT_SYMBOL vmlinux 0xe7d2aca1 security_sk_classify_flow +EXPORT_SYMBOL vmlinux 0xe7d4daac seq_list_next +EXPORT_SYMBOL vmlinux 0xe80fe999 bio_clone +EXPORT_SYMBOL vmlinux 0xe81f3af6 schedule_delayed_work_on +EXPORT_SYMBOL vmlinux 0xe832a847 d_splice_alias +EXPORT_SYMBOL vmlinux 0xe83b0750 vfs_statfs +EXPORT_SYMBOL vmlinux 0xe84a17d7 journal_start +EXPORT_SYMBOL vmlinux 0xe88c3284 xdr_encode_pages +EXPORT_SYMBOL vmlinux 0xe8aed63c filemap_fdatawrite_range +EXPORT_SYMBOL vmlinux 0xe8b77730 kernel_getsockopt +EXPORT_SYMBOL vmlinux 0xe8c61347 sk_send_sigurg +EXPORT_SYMBOL vmlinux 0xe8c8d8f4 check_disk_change +EXPORT_SYMBOL vmlinux 0xe8cd902e hweight16 +EXPORT_SYMBOL vmlinux 0xe8fe562e rpc_queue_upcall +EXPORT_SYMBOL vmlinux 0xe914e41e strcpy +EXPORT_SYMBOL vmlinux 0xe9152325 pcibios_resource_to_bus +EXPORT_SYMBOL vmlinux 0xe9456a5a sysctl_xfrm_aevent_rseqth +EXPORT_SYMBOL vmlinux 0xe9574be7 dev_kfree_skb_irq +EXPORT_SYMBOL vmlinux 0xe9724e67 have_submounts +EXPORT_SYMBOL vmlinux 0xe97f088d scsi_eh_finish_cmd +EXPORT_SYMBOL vmlinux 0xe97f4ce5 qword_get +EXPORT_SYMBOL vmlinux 0xe982f29e task_tgid_nr_ns +EXPORT_SYMBOL vmlinux 0xe98304ec inode_set_bytes +EXPORT_SYMBOL vmlinux 0xe999ab41 genl_sock +EXPORT_SYMBOL vmlinux 0xe9d5103a proc_dostring +EXPORT_SYMBOL vmlinux 0xe9d7c6c5 sync_blockdev +EXPORT_SYMBOL vmlinux 0xe9d8ae1c svc_exit_thread +EXPORT_SYMBOL vmlinux 0xe9e1b9a6 netlink_kernel_create +EXPORT_SYMBOL vmlinux 0xe9e5c283 kobject_init +EXPORT_SYMBOL vmlinux 0xea10212a int_to_scsilun +EXPORT_SYMBOL vmlinux 0xea10655a __bitmap_intersects +EXPORT_SYMBOL vmlinux 0xea147363 printk +EXPORT_SYMBOL vmlinux 0xea2d33a2 radix_tree_gang_lookup_slot +EXPORT_SYMBOL vmlinux 0xea2e3e34 simple_dir_operations +EXPORT_SYMBOL vmlinux 0xea512c5a page_symlink_inode_operations +EXPORT_SYMBOL vmlinux 0xea566a21 svc_set_client +EXPORT_SYMBOL vmlinux 0xea5856e0 input_free_device +EXPORT_SYMBOL vmlinux 0xea5bea12 __set_page_dirty_nobuffers +EXPORT_SYMBOL vmlinux 0xea65adaa iget5_locked +EXPORT_SYMBOL vmlinux 0xea6fcdaa genl_unregister_family +EXPORT_SYMBOL vmlinux 0xea7987f1 key_update +EXPORT_SYMBOL vmlinux 0xea858cb5 radix_tree_gang_lookup_tag +EXPORT_SYMBOL vmlinux 0xeab787b1 generic_read_dir +EXPORT_SYMBOL vmlinux 0xeacb163a sock_setsockopt +EXPORT_SYMBOL vmlinux 0xeae3dfd6 __const_udelay +EXPORT_SYMBOL vmlinux 0xeaf92bdc unlock_page +EXPORT_SYMBOL vmlinux 0xeb395084 param_get_invbool +EXPORT_SYMBOL vmlinux 0xeb710593 xdr_buf_read_netobj +EXPORT_SYMBOL vmlinux 0xeb7abe7a set_blocksize +EXPORT_SYMBOL vmlinux 0xeb7eafd9 blkdev_get +EXPORT_SYMBOL vmlinux 0xeb8f54b3 strstrip +EXPORT_SYMBOL vmlinux 0xeb9e3a7d misc_deregister +EXPORT_SYMBOL vmlinux 0xebc7f0b7 find_task_by_vpid +EXPORT_SYMBOL vmlinux 0xebd273a6 strict_strtoull +EXPORT_SYMBOL vmlinux 0xebe973ee key_revoke +EXPORT_SYMBOL vmlinux 0xebfdcbdf system_serial_high +EXPORT_SYMBOL vmlinux 0xec0d376e pci_pme_active +EXPORT_SYMBOL vmlinux 0xec379e11 textsearch_prepare +EXPORT_SYMBOL vmlinux 0xec3b1ffa set_anon_super +EXPORT_SYMBOL vmlinux 0xec65dbc7 sk_filter +EXPORT_SYMBOL vmlinux 0xec794ba0 __send_remote_softirq +EXPORT_SYMBOL vmlinux 0xec7d89f2 xfrm_user_policy +EXPORT_SYMBOL vmlinux 0xeca43807 kobject_put +EXPORT_SYMBOL vmlinux 0xecc18017 block_write_begin +EXPORT_SYMBOL vmlinux 0xecc4d5fa dma_alloc_writecombine +EXPORT_SYMBOL vmlinux 0xecfc38fa nla_append +EXPORT_SYMBOL vmlinux 0xed0d418c secpath_dup +EXPORT_SYMBOL vmlinux 0xed2694e5 __scsi_add_device +EXPORT_SYMBOL vmlinux 0xed41c7df netlink_clear_multicast_users +EXPORT_SYMBOL vmlinux 0xed56321b nf_unregister_hook +EXPORT_SYMBOL vmlinux 0xed66e21f invalidate_mapping_pages +EXPORT_SYMBOL vmlinux 0xed686b86 per_cpu__softnet_data +EXPORT_SYMBOL vmlinux 0xed6a228b xdr_shift_buf +EXPORT_SYMBOL vmlinux 0xedbaee5e nla_strcmp +EXPORT_SYMBOL vmlinux 0xedcf6be4 qword_add +EXPORT_SYMBOL vmlinux 0xedd14538 param_get_uint +EXPORT_SYMBOL vmlinux 0xedd9106d __ashrdi3 +EXPORT_SYMBOL vmlinux 0xedea84d7 module_refcount +EXPORT_SYMBOL vmlinux 0xedef2f2d udp_prot +EXPORT_SYMBOL vmlinux 0xedf512d6 xdr_decode_word +EXPORT_SYMBOL vmlinux 0xee188e70 user_path_at +EXPORT_SYMBOL vmlinux 0xee1b1bdd tty_set_operations +EXPORT_SYMBOL vmlinux 0xee2d0fc7 _local_bh_enable +EXPORT_SYMBOL vmlinux 0xee33f5f1 dev_mc_add +EXPORT_SYMBOL vmlinux 0xee6fdf0b cpu_online_map +EXPORT_SYMBOL vmlinux 0xeea5ec71 tty_driver_flush_buffer +EXPORT_SYMBOL vmlinux 0xeea9d92b proc_net_netfilter +EXPORT_SYMBOL vmlinux 0xeea9dbaf bitmap_bitremap +EXPORT_SYMBOL vmlinux 0xeeb1717c param_array_get +EXPORT_SYMBOL vmlinux 0xeecb96ca journal_get_write_access +EXPORT_SYMBOL vmlinux 0xef00d9e6 skb_pad +EXPORT_SYMBOL vmlinux 0xef1a1668 km_waitq +EXPORT_SYMBOL vmlinux 0xef7691ba do_splice_from +EXPORT_SYMBOL vmlinux 0xefdd70ce security_secid_to_secctx +EXPORT_SYMBOL vmlinux 0xeffe6cb4 get_unmapped_area +EXPORT_SYMBOL vmlinux 0xf0009fee put_pages_list +EXPORT_SYMBOL vmlinux 0xf0148ebd kblockd_schedule_work +EXPORT_SYMBOL vmlinux 0xf01d38f8 security_d_instantiate +EXPORT_SYMBOL vmlinux 0xf01d79b1 tcf_hash_insert +EXPORT_SYMBOL vmlinux 0xf03c09f4 mb_cache_entry_find_first +EXPORT_SYMBOL vmlinux 0xf04f9584 __find_get_block +EXPORT_SYMBOL vmlinux 0xf075a2b9 i2c_smbus_write_i2c_block_data +EXPORT_SYMBOL vmlinux 0xf085b577 balance_dirty_pages_ratelimited_nr +EXPORT_SYMBOL vmlinux 0xf0953903 sock_common_setsockopt +EXPORT_SYMBOL vmlinux 0xf0b57c68 param_set_long +EXPORT_SYMBOL vmlinux 0xf0caf44b zlib_deflate_workspacesize +EXPORT_SYMBOL vmlinux 0xf0f1246c kvasprintf +EXPORT_SYMBOL vmlinux 0xf122e77a simple_readpage +EXPORT_SYMBOL vmlinux 0xf162fe2d sysctl_xfrm_aevent_etime +EXPORT_SYMBOL vmlinux 0xf174ed48 acquire_console_sem +EXPORT_SYMBOL vmlinux 0xf185ea9c bio_map_kern +EXPORT_SYMBOL vmlinux 0xf1a7d313 sock_no_sendmsg +EXPORT_SYMBOL vmlinux 0xf1dced4c ide_lock +EXPORT_SYMBOL vmlinux 0xf1deabf2 div64_u64 +EXPORT_SYMBOL vmlinux 0xf1e98c74 avenrun +EXPORT_SYMBOL vmlinux 0xf1ec5783 generic_readlink +EXPORT_SYMBOL vmlinux 0xf1f77d1f generic_block_fiemap +EXPORT_SYMBOL vmlinux 0xf20dabd8 free_irq +EXPORT_SYMBOL vmlinux 0xf22db36f ip6_route_me_harder +EXPORT_SYMBOL vmlinux 0xf2446e88 scsi_prep_state_check +EXPORT_SYMBOL vmlinux 0xf27c98fd proc_create_data +EXPORT_SYMBOL vmlinux 0xf2997713 tty_termios_hw_change +EXPORT_SYMBOL vmlinux 0xf2a6d2bf xfrm_policy_count +EXPORT_SYMBOL vmlinux 0xf2afa595 param_get_charp +EXPORT_SYMBOL vmlinux 0xf2ee1b61 simple_empty +EXPORT_SYMBOL vmlinux 0xf313da4e sha_transform +EXPORT_SYMBOL vmlinux 0xf338d4c3 netlink_unregister_notifier +EXPORT_SYMBOL vmlinux 0xf346231f seq_list_start_head +EXPORT_SYMBOL vmlinux 0xf38d7cb4 blk_rq_unmap_user +EXPORT_SYMBOL vmlinux 0xf397b9aa __tasklet_schedule +EXPORT_SYMBOL vmlinux 0xf39bf4d9 put_cmsg +EXPORT_SYMBOL vmlinux 0xf3a49f9e mark_buffer_dirty +EXPORT_SYMBOL vmlinux 0xf3a7e560 scsi_command_normalize_sense +EXPORT_SYMBOL vmlinux 0xf3abbe4e send_sig_info +EXPORT_SYMBOL vmlinux 0xf3b71991 scsi_cmd_print_sense_hdr +EXPORT_SYMBOL vmlinux 0xf3bf0bce __bitmap_complement +EXPORT_SYMBOL vmlinux 0xf3e3f424 __inet6_lookup_established +EXPORT_SYMBOL vmlinux 0xf3f931f7 brioctl_set +EXPORT_SYMBOL vmlinux 0xf45b241d shrink_dcache_parent +EXPORT_SYMBOL vmlinux 0xf4643614 scsi_host_lookup +EXPORT_SYMBOL vmlinux 0xf4749cc3 sget +EXPORT_SYMBOL vmlinux 0xf484066a elv_dispatch_sort +EXPORT_SYMBOL vmlinux 0xf48fdd13 starget_for_each_device +EXPORT_SYMBOL vmlinux 0xf498433c register_mtd_chip_driver +EXPORT_SYMBOL vmlinux 0xf4b9f0e2 dmam_release_declared_memory +EXPORT_SYMBOL vmlinux 0xf4f14de6 rtnl_trylock +EXPORT_SYMBOL vmlinux 0xf51c639f interruptible_sleep_on_timeout +EXPORT_SYMBOL vmlinux 0xf5222eb3 kernel_bind +EXPORT_SYMBOL vmlinux 0xf52c4eb8 register_con_driver +EXPORT_SYMBOL vmlinux 0xf5389ec5 inetdev_by_index +EXPORT_SYMBOL vmlinux 0xf53d4c26 qdisc_class_hash_destroy +EXPORT_SYMBOL vmlinux 0xf5562d69 pci_get_device +EXPORT_SYMBOL vmlinux 0xf564412a __aeabi_ulcmp +EXPORT_SYMBOL vmlinux 0xf5762db7 generic_splice_sendpage +EXPORT_SYMBOL vmlinux 0xf5b7e0c1 netif_carrier_on +EXPORT_SYMBOL vmlinux 0xf5c05914 generic_segment_checks +EXPORT_SYMBOL vmlinux 0xf5d32dbe i2c_get_adapter +EXPORT_SYMBOL vmlinux 0xf6003429 filemap_flush +EXPORT_SYMBOL vmlinux 0xf63e0bc2 block_truncate_page +EXPORT_SYMBOL vmlinux 0xf6876c57 kernel_sendmsg +EXPORT_SYMBOL vmlinux 0xf6933c48 lockd_up +EXPORT_SYMBOL vmlinux 0xf6bb4729 color_table +EXPORT_SYMBOL vmlinux 0xf6c15938 sk_run_filter +EXPORT_SYMBOL vmlinux 0xf6d65581 __inode_dir_notify +EXPORT_SYMBOL vmlinux 0xf6ebc03b net_ratelimit +EXPORT_SYMBOL vmlinux 0xf7212ea6 invalidate_bdev +EXPORT_SYMBOL vmlinux 0xf735d0ea dma_mmap_writecombine +EXPORT_SYMBOL vmlinux 0xf7384f52 downgrade_write +EXPORT_SYMBOL vmlinux 0xf741c793 zlib_deflateEnd +EXPORT_SYMBOL vmlinux 0xf7623914 radix_tree_tag_clear +EXPORT_SYMBOL vmlinux 0xf7656c9c kill_anon_super +EXPORT_SYMBOL vmlinux 0xf769f56f journal_lock_updates +EXPORT_SYMBOL vmlinux 0xf770811c vmtruncate +EXPORT_SYMBOL vmlinux 0xf77fbb46 idr_remove_all +EXPORT_SYMBOL vmlinux 0xf7802486 __aeabi_uidivmod +EXPORT_SYMBOL vmlinux 0xf78d04ab netlink_register_notifier +EXPORT_SYMBOL vmlinux 0xf79b9b79 inet_bind +EXPORT_SYMBOL vmlinux 0xf80b977e tty_insert_flip_string_flags +EXPORT_SYMBOL vmlinux 0xf81034c9 scsi_adjust_queue_depth +EXPORT_SYMBOL vmlinux 0xf811e69d scsi_eh_flush_done_q +EXPORT_SYMBOL vmlinux 0xf825eb41 input_register_handle +EXPORT_SYMBOL vmlinux 0xf82abc1d isa_dma_bridge_buggy +EXPORT_SYMBOL vmlinux 0xf82f1109 utf8_wctomb +EXPORT_SYMBOL vmlinux 0xf833c108 nf_ip_checksum +EXPORT_SYMBOL vmlinux 0xf851bc65 xfrm_init_state +EXPORT_SYMBOL vmlinux 0xf852e695 simple_release_fs +EXPORT_SYMBOL vmlinux 0xf86becf2 inet_frags_fini +EXPORT_SYMBOL vmlinux 0xf8814f73 rb_last +EXPORT_SYMBOL vmlinux 0xf890fe7f pm_idle +EXPORT_SYMBOL vmlinux 0xf89f5759 init_file +EXPORT_SYMBOL vmlinux 0xf8ba03b2 dget_locked +EXPORT_SYMBOL vmlinux 0xf8ba8fa3 sock_wake_async +EXPORT_SYMBOL vmlinux 0xf8cb1f53 xfrm_input_resume +EXPORT_SYMBOL vmlinux 0xf8db08da flock_lock_file_wait +EXPORT_SYMBOL vmlinux 0xf8dedc08 no_llseek +EXPORT_SYMBOL vmlinux 0xf8fbb4f0 __bad_xchg +EXPORT_SYMBOL vmlinux 0xf90d1a7a simple_dir_inode_operations +EXPORT_SYMBOL vmlinux 0xf97a26dc lookup_one_len +EXPORT_SYMBOL vmlinux 0xf97fe3ca pci_scan_bus_parented +EXPORT_SYMBOL vmlinux 0xf9807893 get_empty_filp +EXPORT_SYMBOL vmlinux 0xf9948510 pci_map_rom +EXPORT_SYMBOL vmlinux 0xf9a482f9 msleep +EXPORT_SYMBOL vmlinux 0xf9a7848a dma_pool_free +EXPORT_SYMBOL vmlinux 0xf9b28bac interruptible_sleep_on +EXPORT_SYMBOL vmlinux 0xf9c6ee46 mpage_writepages +EXPORT_SYMBOL vmlinux 0xf9cd6607 sk_stop_timer +EXPORT_SYMBOL vmlinux 0xfa69c7eb journal_wipe +EXPORT_SYMBOL vmlinux 0xfac68eba arm_elf_read_implies_exec +EXPORT_SYMBOL vmlinux 0xfae6722a pcibios_bus_to_resource +EXPORT_SYMBOL vmlinux 0xfaf98462 bitrev32 +EXPORT_SYMBOL vmlinux 0xfb0cf2e9 touch_all_softlockup_watchdogs +EXPORT_SYMBOL vmlinux 0xfb17a245 security_sb_set_mnt_opts +EXPORT_SYMBOL vmlinux 0xfb326a5d down +EXPORT_SYMBOL vmlinux 0xfb5378ff input_allocate_device +EXPORT_SYMBOL vmlinux 0xfb6af58d recalc_sigpending +EXPORT_SYMBOL vmlinux 0xfb72f638 xscale_flush_user_cache_all +EXPORT_SYMBOL vmlinux 0xfb7d9c45 __udivsi3 +EXPORT_SYMBOL vmlinux 0xfb89b28e fsync_bdev +EXPORT_SYMBOL vmlinux 0xfb9a1f66 pci_scan_single_device +EXPORT_SYMBOL vmlinux 0xfbc74f64 __copy_from_user +EXPORT_SYMBOL vmlinux 0xfbc94228 nobh_write_end +EXPORT_SYMBOL vmlinux 0xfbdaed72 sg_miter_stop +EXPORT_SYMBOL vmlinux 0xfbf92453 param_get_bool +EXPORT_SYMBOL vmlinux 0xfc02b7ad sysctl_tcp_wmem +EXPORT_SYMBOL vmlinux 0xfc39e32f ioport_unmap +EXPORT_SYMBOL vmlinux 0xfc533f85 schedule_work_on +EXPORT_SYMBOL vmlinux 0xfc765058 elv_add_request +EXPORT_SYMBOL vmlinux 0xfc7fc1b3 is_bad_inode +EXPORT_SYMBOL vmlinux 0xfc866977 rtnl_create_link +EXPORT_SYMBOL vmlinux 0xfcaa04a0 out_of_line_wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0xfcbd4f8b ethtool_op_set_tx_ipv6_csum +EXPORT_SYMBOL vmlinux 0xfcda63a3 node_states +EXPORT_SYMBOL vmlinux 0xfcdd8cf6 param_get_ushort +EXPORT_SYMBOL vmlinux 0xfce20133 blk_init_queue +EXPORT_SYMBOL vmlinux 0xfcea4808 mb_cache_entry_get +EXPORT_SYMBOL vmlinux 0xfcec0987 enable_irq +EXPORT_SYMBOL vmlinux 0xfd26ef93 blk_queue_dma_alignment +EXPORT_SYMBOL vmlinux 0xfd2fc4db generic_osync_inode +EXPORT_SYMBOL vmlinux 0xfd8dba4c add_wait_queue +EXPORT_SYMBOL vmlinux 0xfd9301b1 __blk_run_queue +EXPORT_SYMBOL vmlinux 0xfd98879a rb_next +EXPORT_SYMBOL vmlinux 0xfde1ff9b unregister_console +EXPORT_SYMBOL vmlinux 0xfdfc0b3b fiemap_fill_next_extent +EXPORT_SYMBOL vmlinux 0xfe14de20 init_buffer +EXPORT_SYMBOL vmlinux 0xfe16775f idr_destroy +EXPORT_SYMBOL vmlinux 0xfe271510 mutex_lock_killable +EXPORT_SYMBOL vmlinux 0xfe2b5e7c tcf_exts_dump +EXPORT_SYMBOL vmlinux 0xfe3f436a dma_chan_cleanup +EXPORT_SYMBOL vmlinux 0xfe5d4bb2 sys_tz +EXPORT_SYMBOL vmlinux 0xfe69758c i2c_transfer +EXPORT_SYMBOL vmlinux 0xfe769456 unregister_netdevice_notifier +EXPORT_SYMBOL vmlinux 0xfeb0ab3c compute_creds +EXPORT_SYMBOL vmlinux 0xfec3c2f2 bcd2bin +EXPORT_SYMBOL vmlinux 0xfedd35fc console_suspend_enabled +EXPORT_SYMBOL vmlinux 0xfef39c53 input_event +EXPORT_SYMBOL vmlinux 0xfef715c6 in_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0xfef96e23 __scsi_print_command +EXPORT_SYMBOL vmlinux 0xfefc301e dma_async_client_unregister +EXPORT_SYMBOL vmlinux 0xff036caf scsi_eh_prep_cmnd +EXPORT_SYMBOL vmlinux 0xff072f4c dev_set_allmulti +EXPORT_SYMBOL vmlinux 0xff1e9dd8 seq_list_start +EXPORT_SYMBOL vmlinux 0xff5f469e tty_get_baud_rate +EXPORT_SYMBOL vmlinux 0xff67b37f __lshrdi3 +EXPORT_SYMBOL vmlinux 0xffd5a395 default_wake_function +EXPORT_SYMBOL vmlinux 0xffe5629c remap_vmalloc_range +EXPORT_SYMBOL vmlinux 0xffe8e685 cache_unregister +EXPORT_SYMBOL_GPL crypto/aead 0x0bedcd98 aead_geniv_free +EXPORT_SYMBOL_GPL crypto/aead 0x0eda6fe7 crypto_alloc_aead +EXPORT_SYMBOL_GPL crypto/aead 0x2a257b13 aead_geniv_alloc +EXPORT_SYMBOL_GPL crypto/aead 0x49fa65de crypto_aead_type +EXPORT_SYMBOL_GPL crypto/aead 0x9d0dd1b7 crypto_nivaead_type +EXPORT_SYMBOL_GPL crypto/aead 0xbfe465f1 crypto_grab_aead +EXPORT_SYMBOL_GPL crypto/aead 0xf6cbc4ca crypto_aead_setauthsize +EXPORT_SYMBOL_GPL crypto/aead 0xfabf7046 aead_geniv_exit +EXPORT_SYMBOL_GPL crypto/aead 0xffe9d061 aead_geniv_init +EXPORT_SYMBOL_GPL crypto/aes_generic 0x1381bf2d crypto_ft_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x22894d94 crypto_il_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5f943003 crypto_it_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5fe743de crypto_aes_expand_key +EXPORT_SYMBOL_GPL crypto/aes_generic 0x6e9cc2ba crypto_fl_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0xd30f3c33 crypto_aes_set_key +EXPORT_SYMBOL_GPL crypto/async_tx/async_memcpy 0x7b848176 async_memcpy +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0x0224a4a1 async_xor +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0xea4c11ce async_xor_zero_sum +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x124f2056 crypto_get_attr_type +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x150233ec crypto_alloc_instance +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x2296c00d crypto_attr_u32 +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x2e8320c1 crypto_register_template +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x348b5faa crypto_spawn_tfm +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x3e345581 crypto_lookup_template +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x45bf1ff3 crypto_inc +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x499043d3 crypto_init_queue +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x58157640 scatterwalk_map +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x5f1cced5 scatterwalk_start +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x635fccba crypto_drop_spawn +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x6a39222f crypto_register_instance +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x75e8f3c3 crypto_register_notifier +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x7dc5d0b6 crypto_unregister_notifier +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x7ff20713 crypto_attr_alg +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x808ec1a3 crypto_alg_tested +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x83553786 scatterwalk_copychunks +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x8810ad5e crypto_xor +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x8b76d9ac crypto_unregister_template +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x9a11a0fc crypto_attr_alg_name +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x9b683b45 scatterwalk_done +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xa0f46593 crypto_dequeue_request +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xa69e6ea6 crypto_unregister_alg +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xc6421398 crypto_enqueue_request +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xc906db6f crypto_register_alg +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xcdf2d35d crypto_tfm_in_queue +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xd16712f3 crypto_check_attr_type +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xe6ea66f4 crypto_init_spawn +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xf807fd65 scatterwalk_map_and_copy +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xfde0b92c crypto_larval_error +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x264eab7b skcipher_geniv_alloc +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x2e095f27 skcipher_geniv_free +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x2e4845fc blkcipher_walk_done +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x6b1910a6 blkcipher_walk_virt_block +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x6cdc3a25 crypto_grab_skcipher +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x8c1b3f45 blkcipher_walk_virt +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x90042f7d blkcipher_walk_phys +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x979d1175 skcipher_geniv_exit +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x9c081926 crypto_alloc_ablkcipher +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x9d77519d crypto_blkcipher_type +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0xa28705aa skcipher_geniv_init +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0xc18472d8 crypto_ablkcipher_type +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0xd97847df crypto_givcipher_type +EXPORT_SYMBOL_GPL crypto/crypto_hash 0x05fc9a75 crypto_hash_type +EXPORT_SYMBOL_GPL crypto/crypto_hash 0x38d35b30 crypto_hash_walk_first +EXPORT_SYMBOL_GPL crypto/crypto_hash 0x4da06cef crypto_hash_walk_done +EXPORT_SYMBOL_GPL crypto/crypto_hash 0xcbde5916 crypto_ahash_type +EXPORT_SYMBOL_GPL crypto/cryptomgr 0x5086ac3a alg_test +EXPORT_SYMBOL_GPL crypto/des_generic 0xcfd9a2c0 des_ekey +EXPORT_SYMBOL_GPL crypto/rng 0x000d4108 crypto_rng_type +EXPORT_SYMBOL_GPL crypto/rng 0x668402aa crypto_put_default_rng +EXPORT_SYMBOL_GPL crypto/rng 0x6ff607b6 crypto_get_default_rng +EXPORT_SYMBOL_GPL crypto/rng 0xe040099c crypto_default_rng +EXPORT_SYMBOL_GPL crypto/twofish_common 0xf9eba494 twofish_setkey +EXPORT_SYMBOL_GPL drivers/char/hw_random/rng-core 0x86b1667d hwrng_unregister +EXPORT_SYMBOL_GPL drivers/char/hw_random/rng-core 0xf6bcbd73 hwrng_register +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0x0e8b8373 dm_put +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0x16b23361 dm_device_name +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0x1e10fb48 dm_noflush_suspending +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0x4982516d dm_set_device_limits +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0xb6e556a3 dm_disk +EXPORT_SYMBOL_GPL drivers/md/md-mod 0x2729a7ee md_do_sync +EXPORT_SYMBOL_GPL drivers/md/md-mod 0x2b9c32c2 sync_page_io +EXPORT_SYMBOL_GPL drivers/md/md-mod 0xa9f858a1 md_allow_write +EXPORT_SYMBOL_GPL drivers/md/md-mod 0xd3fbc318 md_new_event +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x2e557b67 nand_wait_ready +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x7896f44e nand_release +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xad464f4e nand_scan_tail +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xdee805f9 nand_scan +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xea4add24 nand_scan_ident +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x09f3c921 wa_urb_enqueue_run +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x38ff0a80 wa_urb_dequeue +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x7f66fda9 rpipe_ep_disable +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x800f4e9c wa_urb_enqueue +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x8668d134 rpipe_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xa06fdb30 wa_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xe171a620 __wa_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x051aa05b wusbhc_mmcie_rm +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x06495c8c wusbhc_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x077a0f68 wusbhc_chid_set +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x0bb6bf5e wusb_cluster_id_get +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x17cb370d wusbhc_stop +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x360e19e0 wusbhc_reset_all +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x4d03956d wusbhc_mmcie_set +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x63bb10d9 wusbhc_b_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x6ea9720e wusbhc_rh_control +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x7384cf95 __wusb_dev_get_by_usb_dev +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x82d4dca3 wusbhc_b_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x8a369e74 wusbhc_rh_status_data +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x924110e7 wusbhc_handle_dn +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xb725d128 wusb_cluster_id_put +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xdf6e4f08 wusb_dev_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xe81b875c wusbhc_giveback_urb +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xeb0204f0 wusbhc_rh_start_port_reset +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xec735bea wusbhc_rh_resume +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xf770a6b4 wusbd +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xfca39028 wusbhc_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xfe2e17d7 wusb_et_name +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xff78826f wusbhc_rh_suspend +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x043bb2c9 uwb_rc_mac_addr_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x09117f5d __uwb_rc_try_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x0b8aad57 uwb_est_unregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x10b612e6 uwb_rc_dev_addr_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x1d74e88f uwb_rc_get_ie +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x2b121aec uwb_notifs_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x2ca2059f uwb_pal_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x3085c14e uwb_ie_dump_hex +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x32028d96 uwb_dev_try_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x3c4f8887 uwb_rc_add +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4774aa7f uwb_pal_unregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4a38798f uwb_rc_alloc +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4d57ae3c uwb_rsv_type_str +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x54015343 uwb_rc_rm +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x5e4bc088 __uwb_addr_print +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x64538cc7 uwb_rc_get_by_dev +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x6b50d3e6 uwb_rc_ie_rm +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x71d92223 uwb_rc_put +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7613c0e2 uwb_rsv_state_str +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7674f8a6 uwb_pal_init +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x77608b24 uwb_rc_cmd_async +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7dcfcd23 uwb_ie_next +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x82a9ddde uwb_rsv_establish +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x887cba51 uwb_rc_vcmd +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x92e0eff2 uwb_notifs_deregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x94b2c0b5 uwb_bg_joined +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x967db4cc uwb_rsv_accept +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x968c38cf uwb_rc_init +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x97561d9d uwb_ie_for_each +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa6da6e8a uwb_rc_reset_all +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xaa8bd5ab uwb_rsv_create +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xaf9f370c uwb_rc_neh_error +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xbd2f97f6 uwb_rc_neh_grok +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xc1b2c924 uwb_rc_cmd +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xcb726c37 uwb_rc_get_by_grandpa +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xcbe6ded5 uwb_rsv_destroy +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xd1c67a1f uwb_rsv_terminate +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xd44f6860 uwb_dev_for_each +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xdeb58584 dump_bytes +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe1716f06 uwb_est_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe4dca2ba uwb_rsv_modify +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe94e2826 uwb_est_find_size +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xf77be771 uwb_rc_ie_add +EXPORT_SYMBOL_GPL lib/lzo/lzo_compress 0x56b63670 lzo1x_1_compress +EXPORT_SYMBOL_GPL lib/lzo/lzo_decompress 0xf30fda27 lzo1x_decompress_safe +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x0d07e2a9 xt_request_find_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x0f4fcfa0 xt_proto_init +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x17c620ec xt_table_unlock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x2322637a xt_replace_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x40728a63 xt_find_revision +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x477f0204 xt_register_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x58722428 xt_proto_fini +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x5cc24144 xt_unregister_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x7c5e65a7 xt_check_match +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xae74c847 xt_check_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xec3ad1fe xt_find_table_lock +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0x01ca27cf xt_rateest_lookup +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0xe62aee08 xt_rateest_put +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x1584fdb9 tlsf_destroy_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x42a50f11 tlsf_malloc +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x66da3d8f tlsf_create_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xe6acc368 tlsf_free +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xee6c65c9 tlsf_get_used_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xeec8caeb tlsf_get_total_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xf9805f1b tlsf_calloc +EXPORT_SYMBOL_GPL vmlinux 0x00566d8f inotify_get_cookie +EXPORT_SYMBOL_GPL vmlinux 0x0067df75 ata_tf_from_fis +EXPORT_SYMBOL_GPL vmlinux 0x009c95dc xattr_getsecurity +EXPORT_SYMBOL_GPL vmlinux 0x00ebcb5d ata_id_string +EXPORT_SYMBOL_GPL vmlinux 0x0131663e ata_sff_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0x01338d7b generic_fh_to_parent +EXPORT_SYMBOL_GPL vmlinux 0x01423bba rpc_clone_client +EXPORT_SYMBOL_GPL vmlinux 0x016acdf3 ide_device_put +EXPORT_SYMBOL_GPL vmlinux 0x01a4ea6d unregister_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x01fd453e usbhid_lookup_quirk +EXPORT_SYMBOL_GPL vmlinux 0x024047dd transport_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0x028b2222 ata_std_prereset +EXPORT_SYMBOL_GPL vmlinux 0x02edcb60 pci_destroy_slot +EXPORT_SYMBOL_GPL vmlinux 0x0343bdf1 __i2c_board_list +EXPORT_SYMBOL_GPL vmlinux 0x03480fe8 put_pid +EXPORT_SYMBOL_GPL vmlinux 0x03e274cb ata_pci_sff_init_host +EXPORT_SYMBOL_GPL vmlinux 0x03e3686c ata_timing_cycle2mode +EXPORT_SYMBOL_GPL vmlinux 0x03e548e9 fat_getattr +EXPORT_SYMBOL_GPL vmlinux 0x03ecec13 svc_addsock +EXPORT_SYMBOL_GPL vmlinux 0x04486e88 rcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x04590f5b platform_device_put +EXPORT_SYMBOL_GPL vmlinux 0x047f8b2a usb_hcd_check_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0x048941ef sata_sff_hardreset +EXPORT_SYMBOL_GPL vmlinux 0x04bcaaf1 ide_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x04e54f64 get_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0x04ecbf38 rpc_shutdown_client +EXPORT_SYMBOL_GPL vmlinux 0x052baac2 disk_map_sector_rcu +EXPORT_SYMBOL_GPL vmlinux 0x0531dcb8 ata_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0x05370c14 ata_sff_data_xfer_noirq +EXPORT_SYMBOL_GPL vmlinux 0x054e550b kernel_halt +EXPORT_SYMBOL_GPL vmlinux 0x056f8089 hidinput_find_field +EXPORT_SYMBOL_GPL vmlinux 0x0584a3b1 usb_hcd_pci_shutdown +EXPORT_SYMBOL_GPL vmlinux 0x05cc5f3b ata_do_eh +EXPORT_SYMBOL_GPL vmlinux 0x0602f3ea platform_device_register_simple +EXPORT_SYMBOL_GPL vmlinux 0x0606e124 ata_sff_irq_on +EXPORT_SYMBOL_GPL vmlinux 0x0647124d ata_port_start +EXPORT_SYMBOL_GPL vmlinux 0x064db9a5 mark_mounts_for_expiry +EXPORT_SYMBOL_GPL vmlinux 0x068a972f queue_work_on +EXPORT_SYMBOL_GPL vmlinux 0x06b2f393 ata_sff_error_handler +EXPORT_SYMBOL_GPL vmlinux 0x06be11c2 __inet_inherit_port +EXPORT_SYMBOL_GPL vmlinux 0x077ca194 ip_local_out +EXPORT_SYMBOL_GPL vmlinux 0x07836117 fat_fill_super +EXPORT_SYMBOL_GPL vmlinux 0x07b52e38 rtnl_unregister +EXPORT_SYMBOL_GPL vmlinux 0x08394527 debugfs_create_x16 +EXPORT_SYMBOL_GPL vmlinux 0x083e8f51 dev_set_name +EXPORT_SYMBOL_GPL vmlinux 0x086ab268 klist_init +EXPORT_SYMBOL_GPL vmlinux 0x08a0d711 xprt_wake_pending_tasks +EXPORT_SYMBOL_GPL vmlinux 0x08a3e5d1 net_ipv6_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0x08c1d970 fat_build_inode +EXPORT_SYMBOL_GPL vmlinux 0x08f5811c ata_std_qc_defer +EXPORT_SYMBOL_GPL vmlinux 0x090b183f proc_net_fops_create +EXPORT_SYMBOL_GPL vmlinux 0x091eb9b4 round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0x09653538 ata_sff_pause +EXPORT_SYMBOL_GPL vmlinux 0x0965b1c4 ata_sff_data_xfer +EXPORT_SYMBOL_GPL vmlinux 0x09f8fb78 ip6_dst_lookup +EXPORT_SYMBOL_GPL vmlinux 0x0a86c2a1 input_ff_create +EXPORT_SYMBOL_GPL vmlinux 0x0a8f874f unregister_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0x0ac062c8 regulator_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x0ae30707 unregister_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0x0b75336f rpcauth_init_credcache +EXPORT_SYMBOL_GPL vmlinux 0x0baed1c8 rtc_class_close +EXPORT_SYMBOL_GPL vmlinux 0x0bca75da rpcauth_unregister +EXPORT_SYMBOL_GPL vmlinux 0x0bd31d4f __i2c_board_lock +EXPORT_SYMBOL_GPL vmlinux 0x0c17e274 xfrm_aalg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x0d157ae3 ata_port_disable +EXPORT_SYMBOL_GPL vmlinux 0x0d16c643 input_ff_erase +EXPORT_SYMBOL_GPL vmlinux 0x0d2d8117 ata_sas_port_start +EXPORT_SYMBOL_GPL vmlinux 0x0d384c80 crypto_shoot_alg +EXPORT_SYMBOL_GPL vmlinux 0x0d7cfe6e device_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x0d87bb7e inet_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0x0daa99d2 ata_sff_thaw +EXPORT_SYMBOL_GPL vmlinux 0x0dd006d2 ata_sff_postreset +EXPORT_SYMBOL_GPL vmlinux 0x0e0a2314 screen_glyph +EXPORT_SYMBOL_GPL vmlinux 0x0e4766fb sysdev_store_ulong +EXPORT_SYMBOL_GPL vmlinux 0x0e9a56ac crypto_larval_lookup +EXPORT_SYMBOL_GPL vmlinux 0x0e9c1460 sched_setscheduler +EXPORT_SYMBOL_GPL vmlinux 0x0fd2753d fat_flush_inodes +EXPORT_SYMBOL_GPL vmlinux 0x104f46d6 ata_pci_remove_one +EXPORT_SYMBOL_GPL vmlinux 0x10534165 simple_attr_release +EXPORT_SYMBOL_GPL vmlinux 0x10671485 cfi_cmdset_0200 +EXPORT_SYMBOL_GPL vmlinux 0x107387dc rtc_device_register +EXPORT_SYMBOL_GPL vmlinux 0x108de8d3 kobject_rename +EXPORT_SYMBOL_GPL vmlinux 0x10a624fc rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0x10c089d4 d_obtain_alias +EXPORT_SYMBOL_GPL vmlinux 0x113ce4b6 user_instantiate +EXPORT_SYMBOL_GPL vmlinux 0x1181f793 kern_mount_data +EXPORT_SYMBOL_GPL vmlinux 0x1196a6c3 xdr_skb_read_bits +EXPORT_SYMBOL_GPL vmlinux 0x119ea33d usb_string +EXPORT_SYMBOL_GPL vmlinux 0x11a10013 find_get_pid +EXPORT_SYMBOL_GPL vmlinux 0x11e4f7a0 sata_async_notification +EXPORT_SYMBOL_GPL vmlinux 0x11f447ce __gpio_to_irq +EXPORT_SYMBOL_GPL vmlinux 0x11f80a30 ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0x121003da ata_host_start +EXPORT_SYMBOL_GPL vmlinux 0x1251d30f call_rcu +EXPORT_SYMBOL_GPL vmlinux 0x129404e2 apply_to_page_range +EXPORT_SYMBOL_GPL vmlinux 0x12a74518 find_vpid +EXPORT_SYMBOL_GPL vmlinux 0x12b038e5 rpcauth_generic_bind_cred +EXPORT_SYMBOL_GPL vmlinux 0x12eafdfe devres_destroy +EXPORT_SYMBOL_GPL vmlinux 0x13b2a946 register_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x13cdc98d del_mtd_blktrans_dev +EXPORT_SYMBOL_GPL vmlinux 0x1416007e dev_attr_unload_heads +EXPORT_SYMBOL_GPL vmlinux 0x1446ed4e usb_register_device_driver +EXPORT_SYMBOL_GPL vmlinux 0x14b4f456 class_dev_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x150bf2f4 inet_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0x15407dfa gpiochip_remove +EXPORT_SYMBOL_GPL vmlinux 0x1551940f do_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0x1585bbe5 inet6_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0x1598dc9d unregister_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x15d2f69a ide_wait_not_busy +EXPORT_SYMBOL_GPL vmlinux 0x16094912 hid_add_device +EXPORT_SYMBOL_GPL vmlinux 0x1612b2a2 blk_end_bidi_request +EXPORT_SYMBOL_GPL vmlinux 0x16269196 i2c_new_dummy +EXPORT_SYMBOL_GPL vmlinux 0x16d401ee svc_xprt_init +EXPORT_SYMBOL_GPL vmlinux 0x16f76869 probe_kernel_read +EXPORT_SYMBOL_GPL vmlinux 0x16ff2111 inotify_inode_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x172fd7b2 inotify_destroy +EXPORT_SYMBOL_GPL vmlinux 0x1736cb0c ata_sg_init +EXPORT_SYMBOL_GPL vmlinux 0x17433679 inotify_init_watch +EXPORT_SYMBOL_GPL vmlinux 0x17b8d73e sysdev_show_int +EXPORT_SYMBOL_GPL vmlinux 0x17ce645d locks_end_grace +EXPORT_SYMBOL_GPL vmlinux 0x186e09c9 securityfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x1916dcc0 key_type_user +EXPORT_SYMBOL_GPL vmlinux 0x191b433b ata_do_set_mode +EXPORT_SYMBOL_GPL vmlinux 0x191fb096 srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x19a304ba usb_disabled +EXPORT_SYMBOL_GPL vmlinux 0x19abe7ec register_mtd_parser +EXPORT_SYMBOL_GPL vmlinux 0x19c6abd9 ata_pci_sff_init_one +EXPORT_SYMBOL_GPL vmlinux 0x1a12f05c regulator_get +EXPORT_SYMBOL_GPL vmlinux 0x1a581973 usb_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x1a60f7ed scsi_internal_device_unblock +EXPORT_SYMBOL_GPL vmlinux 0x1a618932 nlmsvc_unlock_all_by_ip +EXPORT_SYMBOL_GPL vmlinux 0x1aa8f04f pci_slots_kset +EXPORT_SYMBOL_GPL vmlinux 0x1aa96db3 inet_diag_register +EXPORT_SYMBOL_GPL vmlinux 0x1b214e8d ata_pio_need_iordy +EXPORT_SYMBOL_GPL vmlinux 0x1b6c0eba sata_set_spd +EXPORT_SYMBOL_GPL vmlinux 0x1b8fcf20 regulator_get_current_limit +EXPORT_SYMBOL_GPL vmlinux 0x1b9aca3f jprobe_return +EXPORT_SYMBOL_GPL vmlinux 0x1bc8967c dev_attr_em_message +EXPORT_SYMBOL_GPL vmlinux 0x1c01a587 debugfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x1c87a811 __round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x1c8b188c dev_attr_sw_activity +EXPORT_SYMBOL_GPL vmlinux 0x1cc732c8 xprt_set_retrans_timeout_rtt +EXPORT_SYMBOL_GPL vmlinux 0x1d591404 nlmclnt_init +EXPORT_SYMBOL_GPL vmlinux 0x1da3b334 blk_rq_cur_bytes +EXPORT_SYMBOL_GPL vmlinux 0x1ddfdb54 fat_setattr +EXPORT_SYMBOL_GPL vmlinux 0x1e61df21 inet_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0x1e7bbcb3 kernel_restart +EXPORT_SYMBOL_GPL vmlinux 0x1eb001b4 register_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0x1eb9516e round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x1f44b6da rpc_peeraddr2str +EXPORT_SYMBOL_GPL vmlinux 0x1f647f8a uhci_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0x1f9b9f8e tty_ldisc_ref +EXPORT_SYMBOL_GPL vmlinux 0x1fcece42 inet_twdr_twcal_tick +EXPORT_SYMBOL_GPL vmlinux 0x2043f684 rpc_bind_new_program +EXPORT_SYMBOL_GPL vmlinux 0x20577ea2 xfrm_ealg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x20596565 usb_wait_anchor_empty_timeout +EXPORT_SYMBOL_GPL vmlinux 0x206a943f ata_sff_tf_load +EXPORT_SYMBOL_GPL vmlinux 0x20bc3470 orderly_poweroff +EXPORT_SYMBOL_GPL vmlinux 0x20cd788f __ftrace_printk +EXPORT_SYMBOL_GPL vmlinux 0x20d6b777 tty_ldisc_flush +EXPORT_SYMBOL_GPL vmlinux 0x21092b43 ata_sff_exec_command +EXPORT_SYMBOL_GPL vmlinux 0x21b4330f tty_wakeup +EXPORT_SYMBOL_GPL vmlinux 0x222f1cd4 securityfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0x22472bf4 xfrm_calg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x226e1055 platform_device_add_resources +EXPORT_SYMBOL_GPL vmlinux 0x22e2c20b atomic_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x22eb3c18 hrtimer_try_to_cancel +EXPORT_SYMBOL_GPL vmlinux 0x231b20eb rpc_create +EXPORT_SYMBOL_GPL vmlinux 0x233821da sysfs_create_link +EXPORT_SYMBOL_GPL vmlinux 0x23679939 __iowrite32_copy +EXPORT_SYMBOL_GPL vmlinux 0x23869dc7 cancel_work_sync +EXPORT_SYMBOL_GPL vmlinux 0x23af18a3 platform_get_irq +EXPORT_SYMBOL_GPL vmlinux 0x247c89c4 ata_port_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0x24905e10 zap_vma_ptes +EXPORT_SYMBOL_GPL vmlinux 0x24cda041 ide_vlb_clk +EXPORT_SYMBOL_GPL vmlinux 0x24eb7e32 leds_list +EXPORT_SYMBOL_GPL vmlinux 0x250846d0 ide_no_data_taskfile +EXPORT_SYMBOL_GPL vmlinux 0x256310b5 rpc_proc_register +EXPORT_SYMBOL_GPL vmlinux 0x2590e23c xprt_release_rqst_cong +EXPORT_SYMBOL_GPL vmlinux 0x25913fc3 device_create_file +EXPORT_SYMBOL_GPL vmlinux 0x2600545b bus_register +EXPORT_SYMBOL_GPL vmlinux 0x261bb55a console_drivers +EXPORT_SYMBOL_GPL vmlinux 0x264c4709 usb_put_dev +EXPORT_SYMBOL_GPL vmlinux 0x264c4aba ide_do_test_unit_ready +EXPORT_SYMBOL_GPL vmlinux 0x264ed4bd hrtimer_start_range_ns +EXPORT_SYMBOL_GPL vmlinux 0x26c90ea4 scsi_eh_get_sense +EXPORT_SYMBOL_GPL vmlinux 0x2719177c ata_pci_bmdma_init +EXPORT_SYMBOL_GPL vmlinux 0x272d518d rtnl_kill_links +EXPORT_SYMBOL_GPL vmlinux 0x2731f9fc bd_claim_by_disk +EXPORT_SYMBOL_GPL vmlinux 0x27439f30 ide_read_sff_dma_status +EXPORT_SYMBOL_GPL vmlinux 0x27a27332 cfi_qry_mode_off +EXPORT_SYMBOL_GPL vmlinux 0x27e52b87 ide_host_free +EXPORT_SYMBOL_GPL vmlinux 0x283f188a csum_partial_copy_to_xdr +EXPORT_SYMBOL_GPL vmlinux 0x28aa6cf4 debugfs_create_blob +EXPORT_SYMBOL_GPL vmlinux 0x28b2cc80 atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x28b61559 ide_host_remove +EXPORT_SYMBOL_GPL vmlinux 0x28c59cd4 rpc_lookup_cred +EXPORT_SYMBOL_GPL vmlinux 0x28d664ff __raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x28dc5e93 platform_bus +EXPORT_SYMBOL_GPL vmlinux 0x28e23139 xfrm_probe_algs +EXPORT_SYMBOL_GPL vmlinux 0x2934e6d9 fat_search_long +EXPORT_SYMBOL_GPL vmlinux 0x293c700b ide_device_get +EXPORT_SYMBOL_GPL vmlinux 0x2959ed97 skb_segment +EXPORT_SYMBOL_GPL vmlinux 0x297c6a2b rtc_set_alarm +EXPORT_SYMBOL_GPL vmlinux 0x297dc8a3 tcp_register_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0x2995467b nf_register_afinfo +EXPORT_SYMBOL_GPL vmlinux 0x29a79362 anon_inode_getfd +EXPORT_SYMBOL_GPL vmlinux 0x29aadf81 free_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x29b45966 sysfs_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x29e5c64d usb_hub_tt_clear_buffer +EXPORT_SYMBOL_GPL vmlinux 0x2a2d93b7 klist_add_before +EXPORT_SYMBOL_GPL vmlinux 0x2a434650 tty_ldisc_deref +EXPORT_SYMBOL_GPL vmlinux 0x2a81c4d5 tty_ldisc_ref_wait +EXPORT_SYMBOL_GPL vmlinux 0x2aa17774 rpc_free_iostats +EXPORT_SYMBOL_GPL vmlinux 0x2ad441c5 async_tx_quiesce +EXPORT_SYMBOL_GPL vmlinux 0x2aef3e9f rpc_exit_task +EXPORT_SYMBOL_GPL vmlinux 0x2afb3b35 rdev_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x2b178537 ide_map_sg +EXPORT_SYMBOL_GPL vmlinux 0x2b9f8e23 nf_net_ipv4_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x2bdce430 ata_bmdma_mode_filter +EXPORT_SYMBOL_GPL vmlinux 0x2c16ed76 xfrm_calg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x2c2bc86b ata_pci_sff_activate_host +EXPORT_SYMBOL_GPL vmlinux 0x2c4d64e6 crypto_mod_put +EXPORT_SYMBOL_GPL vmlinux 0x2cf9f466 rtc_read_alarm +EXPORT_SYMBOL_GPL vmlinux 0x2d32c22f regulator_set_voltage +EXPORT_SYMBOL_GPL vmlinux 0x2d469b5a anon_transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x2d70e61c driver_attach +EXPORT_SYMBOL_GPL vmlinux 0x2d7af224 usb_get_urb +EXPORT_SYMBOL_GPL vmlinux 0x2d82fdf7 device_del +EXPORT_SYMBOL_GPL vmlinux 0x2dd6b797 sysfs_create_group +EXPORT_SYMBOL_GPL vmlinux 0x2e3d08b9 crypto_chain +EXPORT_SYMBOL_GPL vmlinux 0x2e48bb32 inotify_rm_watch +EXPORT_SYMBOL_GPL vmlinux 0x2e8bdb17 rt_mutex_destroy +EXPORT_SYMBOL_GPL vmlinux 0x2edd7702 simple_attr_write +EXPORT_SYMBOL_GPL vmlinux 0x2edea14c led_trigger_register +EXPORT_SYMBOL_GPL vmlinux 0x2f603ea5 input_ff_event +EXPORT_SYMBOL_GPL vmlinux 0x2fe1a4e1 ide_unregister_region +EXPORT_SYMBOL_GPL vmlinux 0x3006feef rpc_run_task +EXPORT_SYMBOL_GPL vmlinux 0x30537659 blkdev_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x3070c94e nlmsvc_unlock_all_by_sb +EXPORT_SYMBOL_GPL vmlinux 0x307334e6 ip6_dst_blackhole +EXPORT_SYMBOL_GPL vmlinux 0x308ca230 sysdev_show_ulong +EXPORT_SYMBOL_GPL vmlinux 0x30be52d6 usb_anchor_urb +EXPORT_SYMBOL_GPL vmlinux 0x310c5d19 tty_prepare_flip_string_flags +EXPORT_SYMBOL_GPL vmlinux 0x314f8c14 led_trigger_show +EXPORT_SYMBOL_GPL vmlinux 0x3175d0ae ide_pci_init_two +EXPORT_SYMBOL_GPL vmlinux 0x31a89d59 rpc_debug +EXPORT_SYMBOL_GPL vmlinux 0x3239dfa4 rpc_wake_up_status +EXPORT_SYMBOL_GPL vmlinux 0x329bde31 sysfs_notify +EXPORT_SYMBOL_GPL vmlinux 0x32e26579 usb_create_hcd +EXPORT_SYMBOL_GPL vmlinux 0x32e7cd61 inet_csk_clone +EXPORT_SYMBOL_GPL vmlinux 0x32f6b6d2 ata_port_desc +EXPORT_SYMBOL_GPL vmlinux 0x33286ff2 transport_add_device +EXPORT_SYMBOL_GPL vmlinux 0x334faddb __hid_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x3408bb89 usb_get_hcd +EXPORT_SYMBOL_GPL vmlinux 0x3433dc32 put_device +EXPORT_SYMBOL_GPL vmlinux 0x3441c3d6 gpio_set_value_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x34442f5f tracepoint_iter_stop +EXPORT_SYMBOL_GPL vmlinux 0x34626d32 sysfs_remove_link +EXPORT_SYMBOL_GPL vmlinux 0x347c7993 anon_transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x34a25166 scsi_flush_work +EXPORT_SYMBOL_GPL vmlinux 0x34edd1e2 inet6_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0x351b8aed __ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0x353ac1ad hidinput_report_event +EXPORT_SYMBOL_GPL vmlinux 0x3559bd46 ide_queue_pc_tail +EXPORT_SYMBOL_GPL vmlinux 0x3564caaf hid_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x35bf72a3 ide_tf_load +EXPORT_SYMBOL_GPL vmlinux 0x35cf63ff rpc_init_wait_queue +EXPORT_SYMBOL_GPL vmlinux 0x35d8c94a sdev_evt_alloc +EXPORT_SYMBOL_GPL vmlinux 0x35d8e3d6 platform_device_add_data +EXPORT_SYMBOL_GPL vmlinux 0x35d9df5b ata_port_probe +EXPORT_SYMBOL_GPL vmlinux 0x35de7571 usb_get_status +EXPORT_SYMBOL_GPL vmlinux 0x35dfb297 skb_to_sgvec +EXPORT_SYMBOL_GPL vmlinux 0x35ec7fcb klist_next +EXPORT_SYMBOL_GPL vmlinux 0x361e2bcc save_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0x362e23ec call_rcu_bh +EXPORT_SYMBOL_GPL vmlinux 0x369e6dcb led_trigger_register_simple +EXPORT_SYMBOL_GPL vmlinux 0x36abcaa0 simple_attr_read +EXPORT_SYMBOL_GPL vmlinux 0x374fdd1e inotify_find_update_watch +EXPORT_SYMBOL_GPL vmlinux 0x37897eff ata_bmdma_start +EXPORT_SYMBOL_GPL vmlinux 0x37f3fdfa usb_hcd_giveback_urb +EXPORT_SYMBOL_GPL vmlinux 0x383245dc rt_mutex_trylock +EXPORT_SYMBOL_GPL vmlinux 0x3873f421 xprt_adjust_cwnd +EXPORT_SYMBOL_GPL vmlinux 0x38dc74ed rtc_irq_unregister +EXPORT_SYMBOL_GPL vmlinux 0x39819646 atomic_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x39f69472 hrtimer_forward +EXPORT_SYMBOL_GPL vmlinux 0x3a084e98 seq_release_net +EXPORT_SYMBOL_GPL vmlinux 0x3a2fc74d ata_sff_tf_read +EXPORT_SYMBOL_GPL vmlinux 0x3a7f8b86 __local_bh_enable +EXPORT_SYMBOL_GPL vmlinux 0x3a8e5e34 do_rw_taskfile +EXPORT_SYMBOL_GPL vmlinux 0x3a90c6ac regulator_bulk_enable +EXPORT_SYMBOL_GPL vmlinux 0x3b693795 inotify_init +EXPORT_SYMBOL_GPL vmlinux 0x3b7405ab rpc_wake_up_queued_task +EXPORT_SYMBOL_GPL vmlinux 0x3b8088f3 svc_find_xprt +EXPORT_SYMBOL_GPL vmlinux 0x3bad0ae7 ipv6_opt_accepted +EXPORT_SYMBOL_GPL vmlinux 0x3bc33f65 cleanup_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x3bc66b26 device_schedule_callback_owner +EXPORT_SYMBOL_GPL vmlinux 0x3be7af02 get_max_files +EXPORT_SYMBOL_GPL vmlinux 0x3be89d3c usb_register_notify +EXPORT_SYMBOL_GPL vmlinux 0x3bf5d801 driver_find_device +EXPORT_SYMBOL_GPL vmlinux 0x3c39b7f5 ide_do_start_stop +EXPORT_SYMBOL_GPL vmlinux 0x3c89dafe blk_update_request +EXPORT_SYMBOL_GPL vmlinux 0x3c9032f4 generic_sync_sb_inodes +EXPORT_SYMBOL_GPL vmlinux 0x3cd06035 add_input_randomness +EXPORT_SYMBOL_GPL vmlinux 0x3ce63c22 unregister_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0x3d0eb042 proc_net_remove +EXPORT_SYMBOL_GPL vmlinux 0x3d5beac2 fsstack_copy_attr_all +EXPORT_SYMBOL_GPL vmlinux 0x3d8618fa transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x3da7da4f usb_buffer_free +EXPORT_SYMBOL_GPL vmlinux 0x3de41323 usb_buffer_map_sg +EXPORT_SYMBOL_GPL vmlinux 0x3e69a190 ata_sff_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x3e806709 gpiochip_add +EXPORT_SYMBOL_GPL vmlinux 0x3eaeb974 class_find_device +EXPORT_SYMBOL_GPL vmlinux 0x3ef54874 ide_get_lba_addr +EXPORT_SYMBOL_GPL vmlinux 0x3f01570a probe_kernel_write +EXPORT_SYMBOL_GPL vmlinux 0x3fbab952 sysfs_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x3fdc9422 blk_queue_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0x404038a7 __crypto_alloc_tfm +EXPORT_SYMBOL_GPL vmlinux 0x404de2cb raw_seq_open +EXPORT_SYMBOL_GPL vmlinux 0x40af0dec ata_xfer_mode2mask +EXPORT_SYMBOL_GPL vmlinux 0x412e6ee2 hwmon_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x4173cf4c bus_sort_breadthfirst +EXPORT_SYMBOL_GPL vmlinux 0x41f3cc90 xfrm_aalg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x4200d617 uart_console_write +EXPORT_SYMBOL_GPL vmlinux 0x4216f721 add_mtd_blktrans_dev +EXPORT_SYMBOL_GPL vmlinux 0x42b7d216 crypto_larval_alloc +EXPORT_SYMBOL_GPL vmlinux 0x42bbf778 driver_register +EXPORT_SYMBOL_GPL vmlinux 0x42c3fad2 platform_add_devices +EXPORT_SYMBOL_GPL vmlinux 0x432fd7f6 __gpio_set_value +EXPORT_SYMBOL_GPL vmlinux 0x4362e364 hidinput_disconnect +EXPORT_SYMBOL_GPL vmlinux 0x43f56e82 ata_xfer_mode2shift +EXPORT_SYMBOL_GPL vmlinux 0x43f7926e regulator_get_init_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x441c4780 usb_store_new_id +EXPORT_SYMBOL_GPL vmlinux 0x44247598 user_match +EXPORT_SYMBOL_GPL vmlinux 0x442d08bd regulator_set_mode +EXPORT_SYMBOL_GPL vmlinux 0x454d29d8 devres_open_group +EXPORT_SYMBOL_GPL vmlinux 0x45657b78 rpc_wake_up +EXPORT_SYMBOL_GPL vmlinux 0x457594fa crypto_alg_list +EXPORT_SYMBOL_GPL vmlinux 0x4595a7b6 ide_execute_pkt_cmd +EXPORT_SYMBOL_GPL vmlinux 0x45fcc1b3 ata_pci_sff_prepare_host +EXPORT_SYMBOL_GPL vmlinux 0x46a6d6e0 debugfs_create_x32 +EXPORT_SYMBOL_GPL vmlinux 0x46c6ce31 rt_mutex_lock +EXPORT_SYMBOL_GPL vmlinux 0x46c72860 usb_bus_list_lock +EXPORT_SYMBOL_GPL vmlinux 0x47229b5c gpio_request +EXPORT_SYMBOL_GPL vmlinux 0x4730abb1 ide_input_data +EXPORT_SYMBOL_GPL vmlinux 0x47406659 platform_get_irq_byname +EXPORT_SYMBOL_GPL vmlinux 0x477a95a0 class_interface_unregister +EXPORT_SYMBOL_GPL vmlinux 0x47983c05 __inet_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0x47b53180 i2c_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x47bd436e usb_bulk_msg +EXPORT_SYMBOL_GPL vmlinux 0x47c28c20 queue_delayed_work_on +EXPORT_SYMBOL_GPL vmlinux 0x47c392a3 shmem_file_setup +EXPORT_SYMBOL_GPL vmlinux 0x47e2155d ip_build_and_send_pkt +EXPORT_SYMBOL_GPL vmlinux 0x47e6960c lookup_create +EXPORT_SYMBOL_GPL vmlinux 0x4860f39d ata_sas_port_stop +EXPORT_SYMBOL_GPL vmlinux 0x48769263 hid_report_raw_event +EXPORT_SYMBOL_GPL vmlinux 0x489f7214 usb_find_interface +EXPORT_SYMBOL_GPL vmlinux 0x48dcaa3b single_open_net +EXPORT_SYMBOL_GPL vmlinux 0x48e2d76e rpc_peeraddr +EXPORT_SYMBOL_GPL vmlinux 0x495b18c1 driver_create_file +EXPORT_SYMBOL_GPL vmlinux 0x49c5e8e6 raw_unhash_sk +EXPORT_SYMBOL_GPL vmlinux 0x4a3d6260 inet_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0x4a54d32c ata_bmdma_status +EXPORT_SYMBOL_GPL vmlinux 0x4a7e30d9 marker_probe_unregister_private_data +EXPORT_SYMBOL_GPL vmlinux 0x4a80db75 ata_slave_link_init +EXPORT_SYMBOL_GPL vmlinux 0x4a82a668 ata_link_online +EXPORT_SYMBOL_GPL vmlinux 0x4a8a4229 xprt_update_rtt +EXPORT_SYMBOL_GPL vmlinux 0x4a96fd0c rpc_force_rebind +EXPORT_SYMBOL_GPL vmlinux 0x4af8fb86 ata_sff_dma_pause +EXPORT_SYMBOL_GPL vmlinux 0x4afac55a get_current_tty +EXPORT_SYMBOL_GPL vmlinux 0x4b26e01d ata_sff_wait_ready +EXPORT_SYMBOL_GPL vmlinux 0x4b351467 class_interface_register +EXPORT_SYMBOL_GPL vmlinux 0x4b4dc7c7 blk_queue_dma_drain +EXPORT_SYMBOL_GPL vmlinux 0x4b73f8ff ata_eh_analyze_ncq_error +EXPORT_SYMBOL_GPL vmlinux 0x4b9cab1d inverse_translate +EXPORT_SYMBOL_GPL vmlinux 0x4bbc2dc7 rpc_setbufsize +EXPORT_SYMBOL_GPL vmlinux 0x4bc12285 ata_sas_slave_configure +EXPORT_SYMBOL_GPL vmlinux 0x4c759827 byte_rev_table +EXPORT_SYMBOL_GPL vmlinux 0x4d805ad6 ata_host_alloc_pinfo +EXPORT_SYMBOL_GPL vmlinux 0x4d850f07 inet6_lookup +EXPORT_SYMBOL_GPL vmlinux 0x4dd9f3ec rpc_alloc_iostats +EXPORT_SYMBOL_GPL vmlinux 0x4ddc8c5f pci_bus_max_busnr +EXPORT_SYMBOL_GPL vmlinux 0x4e26573e nf_unregister_afinfo +EXPORT_SYMBOL_GPL vmlinux 0x4e8c1f1b put_driver +EXPORT_SYMBOL_GPL vmlinux 0x4f867221 regulator_bulk_free +EXPORT_SYMBOL_GPL vmlinux 0x4fb2b92e exportfs_decode_fh +EXPORT_SYMBOL_GPL vmlinux 0x4fdc945d sata_deb_timing_normal +EXPORT_SYMBOL_GPL vmlinux 0x4fe36b52 elv_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5002e63c ide_pci_remove +EXPORT_SYMBOL_GPL vmlinux 0x5013f010 register_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0x50247427 pciserial_remove_ports +EXPORT_SYMBOL_GPL vmlinux 0x502a3b55 gpiochip_is_requested +EXPORT_SYMBOL_GPL vmlinux 0x50b67174 xfrm_ealg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x50c3707b tcp_twsk_destructor +EXPORT_SYMBOL_GPL vmlinux 0x50cd4c41 scsi_eh_ready_devs +EXPORT_SYMBOL_GPL vmlinux 0x50e7193a __i2c_first_dynamic_bus_num +EXPORT_SYMBOL_GPL vmlinux 0x50ea7e7d inet6_csk_xmit +EXPORT_SYMBOL_GPL vmlinux 0x50fad434 round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x515a86c6 register_kprobe +EXPORT_SYMBOL_GPL vmlinux 0x516eac6b inotify_inode_is_dead +EXPORT_SYMBOL_GPL vmlinux 0x51a9e388 do_sync_mapping_range +EXPORT_SYMBOL_GPL vmlinux 0x51dd6488 xfrm_aalg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x51fa9dff disk_part_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x52354429 vfs_setlease +EXPORT_SYMBOL_GPL vmlinux 0x5289923f svc_xprt_put +EXPORT_SYMBOL_GPL vmlinux 0x52b3e377 usb_hcd_unlink_urb_from_ep +EXPORT_SYMBOL_GPL vmlinux 0x52be6912 dev_attr_link_power_management_policy +EXPORT_SYMBOL_GPL vmlinux 0x52d111ea pm_qos_update_requirement +EXPORT_SYMBOL_GPL vmlinux 0x533e4f08 svc_xprt_received +EXPORT_SYMBOL_GPL vmlinux 0x53445f68 nlm_debug +EXPORT_SYMBOL_GPL vmlinux 0x53986488 register_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x53bf388b pci_stop_bus_device +EXPORT_SYMBOL_GPL vmlinux 0x53c7b551 rpc_delay +EXPORT_SYMBOL_GPL vmlinux 0x53e637bf i2c_new_probed_device +EXPORT_SYMBOL_GPL vmlinux 0x53ec386e platform_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0x543f5c21 rt_mutex_timed_lock +EXPORT_SYMBOL_GPL vmlinux 0x54628cf0 svc_print_addr +EXPORT_SYMBOL_GPL vmlinux 0x551fb7bb transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5542b913 cpu_bit_bitmap +EXPORT_SYMBOL_GPL vmlinux 0x554c2190 tcp_reno_cong_avoid +EXPORT_SYMBOL_GPL vmlinux 0x55b1e7e1 synchronize_srcu +EXPORT_SYMBOL_GPL vmlinux 0x55f4ca99 alloc_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x56063248 ata_sas_port_init +EXPORT_SYMBOL_GPL vmlinux 0x561d8df1 disk_get_part +EXPORT_SYMBOL_GPL vmlinux 0x5641485b tty_termios_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x56541901 __inet_hash_nolisten +EXPORT_SYMBOL_GPL vmlinux 0x569560e5 i2c_new_device +EXPORT_SYMBOL_GPL vmlinux 0x5697017b led_trigger_event +EXPORT_SYMBOL_GPL vmlinux 0x56cd23dd usb_sg_init +EXPORT_SYMBOL_GPL vmlinux 0x56d370ce ipv6_dup_options +EXPORT_SYMBOL_GPL vmlinux 0x56d42418 thread_notify_head +EXPORT_SYMBOL_GPL vmlinux 0x56ee91c9 ata_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0x577d3642 register_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0x579c7bfd svc_unreg_xprt_class +EXPORT_SYMBOL_GPL vmlinux 0x579e0bf5 rtnl_unregister_all +EXPORT_SYMBOL_GPL vmlinux 0x57aee411 sata_link_debounce +EXPORT_SYMBOL_GPL vmlinux 0x57b146d6 device_register +EXPORT_SYMBOL_GPL vmlinux 0x57b2ecdd devres_add +EXPORT_SYMBOL_GPL vmlinux 0x5809fd26 inet_unhash +EXPORT_SYMBOL_GPL vmlinux 0x586c6269 ata_dev_disable +EXPORT_SYMBOL_GPL vmlinux 0x596a0d88 hrtimer_start +EXPORT_SYMBOL_GPL vmlinux 0x596c7d78 __ip_route_output_key +EXPORT_SYMBOL_GPL vmlinux 0x597f3bc3 marker_get_private_data +EXPORT_SYMBOL_GPL vmlinux 0x59933a5b usb_poison_urb +EXPORT_SYMBOL_GPL vmlinux 0x59ca3224 inet_twdr_twkill_work +EXPORT_SYMBOL_GPL vmlinux 0x59d576ef device_find_child +EXPORT_SYMBOL_GPL vmlinux 0x59d700f4 driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5a29015d pci_disable_rom +EXPORT_SYMBOL_GPL vmlinux 0x5a7bfe41 crypto_probing_notify +EXPORT_SYMBOL_GPL vmlinux 0x5ae3d7f0 usb_altnum_to_altsetting +EXPORT_SYMBOL_GPL vmlinux 0x5b0bca3e sysdev_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5b0e06a0 rpc_call_async +EXPORT_SYMBOL_GPL vmlinux 0x5b72bb0c devm_kfree +EXPORT_SYMBOL_GPL vmlinux 0x5b785652 rpcauth_create +EXPORT_SYMBOL_GPL vmlinux 0x5b7dae12 ehci_cf_port_reset_rwsem +EXPORT_SYMBOL_GPL vmlinux 0x5bc8f197 ata_sff_port_start +EXPORT_SYMBOL_GPL vmlinux 0x5bca8d7f tcp_death_row +EXPORT_SYMBOL_GPL vmlinux 0x5bd26000 rpc_proc_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5bfc03c3 unregister_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5c58ffec klist_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x5c749dc6 tcp_is_cwnd_limited +EXPORT_SYMBOL_GPL vmlinux 0x5c900139 ata_link_offline +EXPORT_SYMBOL_GPL vmlinux 0x5ca24215 pci_enable_rom +EXPORT_SYMBOL_GPL vmlinux 0x5cc44f7e klist_add_head +EXPORT_SYMBOL_GPL vmlinux 0x5cd71b56 get_sb_mtd +EXPORT_SYMBOL_GPL vmlinux 0x5cfad36f skb_icv_walk +EXPORT_SYMBOL_GPL vmlinux 0x5d0f6f57 kbd_table +EXPORT_SYMBOL_GPL vmlinux 0x5d4a4572 ktime_sub_ns +EXPORT_SYMBOL_GPL vmlinux 0x5d4e6065 put_rpccred +EXPORT_SYMBOL_GPL vmlinux 0x5d730e7b raw_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5d7e2f70 klist_add_tail +EXPORT_SYMBOL_GPL vmlinux 0x5d860d30 class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x5d9aed30 sata_scr_write +EXPORT_SYMBOL_GPL vmlinux 0x5dd67618 register_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5ddcda83 register_posix_clock +EXPORT_SYMBOL_GPL vmlinux 0x5de2b7fb rtc_class_open +EXPORT_SYMBOL_GPL vmlinux 0x5e0b518c class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5e13ef52 xprt_wait_for_buffer_space +EXPORT_SYMBOL_GPL vmlinux 0x5e2577c1 led_classdev_suspend +EXPORT_SYMBOL_GPL vmlinux 0x5e3b100d class_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x5efb0c42 ip6_local_out +EXPORT_SYMBOL_GPL vmlinux 0x5f6dd946 ata_host_detach +EXPORT_SYMBOL_GPL vmlinux 0x5f99baef user_read +EXPORT_SYMBOL_GPL vmlinux 0x5fa016ee kernel_kobj +EXPORT_SYMBOL_GPL vmlinux 0x6046e199 alloc_page_buffers +EXPORT_SYMBOL_GPL vmlinux 0x607e5062 ide_init_sg_cmd +EXPORT_SYMBOL_GPL vmlinux 0x6091797f synchronize_rcu +EXPORT_SYMBOL_GPL vmlinux 0x60a13e90 rcu_barrier +EXPORT_SYMBOL_GPL vmlinux 0x60a4a9f3 exit_fs +EXPORT_SYMBOL_GPL vmlinux 0x60d9c95f async_trigger_callback +EXPORT_SYMBOL_GPL vmlinux 0x61a4685e usb_get_dev +EXPORT_SYMBOL_GPL vmlinux 0x61c8ea20 raw_seq_start +EXPORT_SYMBOL_GPL vmlinux 0x622b3e2c srcu_read_lock +EXPORT_SYMBOL_GPL vmlinux 0x62e48f68 ide_init_disk +EXPORT_SYMBOL_GPL vmlinux 0x62e97c56 cfi_cmdset_0003 +EXPORT_SYMBOL_GPL vmlinux 0x632c7cd2 __create_workqueue_key +EXPORT_SYMBOL_GPL vmlinux 0x63505c05 usb_buffer_alloc +EXPORT_SYMBOL_GPL vmlinux 0x6357f047 tcp_unregister_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0x63719293 inotify_add_watch +EXPORT_SYMBOL_GPL vmlinux 0x63a948dc ata_port_abort +EXPORT_SYMBOL_GPL vmlinux 0x63c6caa9 attribute_container_find_class_device +EXPORT_SYMBOL_GPL vmlinux 0x63cfa0f8 ide_create_request_sense_cmd +EXPORT_SYMBOL_GPL vmlinux 0x63d7d611 fs_kobj +EXPORT_SYMBOL_GPL vmlinux 0x63f39f75 sysfs_remove_group +EXPORT_SYMBOL_GPL vmlinux 0x65366eff ipv6_find_tlv +EXPORT_SYMBOL_GPL vmlinux 0x65390d1b xprt_release_xprt_cong +EXPORT_SYMBOL_GPL vmlinux 0x653e92d4 device_initialize +EXPORT_SYMBOL_GPL vmlinux 0x656505c6 inet_csk_route_req +EXPORT_SYMBOL_GPL vmlinux 0x656c5411 __class_create +EXPORT_SYMBOL_GPL vmlinux 0x659121b3 usb_buffer_unmap_sg +EXPORT_SYMBOL_GPL vmlinux 0x65ccb6f0 call_netevent_notifiers +EXPORT_SYMBOL_GPL vmlinux 0x65d6d0f0 gpio_direction_input +EXPORT_SYMBOL_GPL vmlinux 0x661601de sprint_symbol +EXPORT_SYMBOL_GPL vmlinux 0x6674e2a8 inotify_dentry_parent_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x66b2a859 nr_free_buffer_pages +EXPORT_SYMBOL_GPL vmlinux 0x66cbf5ec tcp_init_congestion_ops +EXPORT_SYMBOL_GPL vmlinux 0x66d87d38 symbol_put_addr +EXPORT_SYMBOL_GPL vmlinux 0x66f91fe8 usbhid_submit_report +EXPORT_SYMBOL_GPL vmlinux 0x66ffe0e7 usb_add_hcd +EXPORT_SYMBOL_GPL vmlinux 0x6714b539 rpc_put_task +EXPORT_SYMBOL_GPL vmlinux 0x67271407 get_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0x67b50927 usb_reset_configuration +EXPORT_SYMBOL_GPL vmlinux 0x67f7dbd5 invalidate_inode_pages2 +EXPORT_SYMBOL_GPL vmlinux 0x68644fae vfs_cancel_lock +EXPORT_SYMBOL_GPL vmlinux 0x686c703f xfrm_count_auth_supported +EXPORT_SYMBOL_GPL vmlinux 0x68cf6069 ide_port_scan +EXPORT_SYMBOL_GPL vmlinux 0x693b711b securityfs_remove +EXPORT_SYMBOL_GPL vmlinux 0x69450a72 hid_input_report +EXPORT_SYMBOL_GPL vmlinux 0x695a903b blk_queue_rq_timed_out +EXPORT_SYMBOL_GPL vmlinux 0x69918bc7 inotify_find_watch +EXPORT_SYMBOL_GPL vmlinux 0x69951d5e __inet_lookup_established +EXPORT_SYMBOL_GPL vmlinux 0x69bc3480 kobject_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0x69c948e1 __rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x69e51ad0 tty_prepare_flip_string +EXPORT_SYMBOL_GPL vmlinux 0x69e60533 posix_timer_event +EXPORT_SYMBOL_GPL vmlinux 0x69e9a2cb ata_scsi_slave_config +EXPORT_SYMBOL_GPL vmlinux 0x69f89fdc i2c_unregister_device +EXPORT_SYMBOL_GPL vmlinux 0x6a1dca64 vfs_removexattr +EXPORT_SYMBOL_GPL vmlinux 0x6a51c1a5 regulator_unregister +EXPORT_SYMBOL_GPL vmlinux 0x6a6b22c7 debugfs_create_bool +EXPORT_SYMBOL_GPL vmlinux 0x6b220992 bus_rescan_devices +EXPORT_SYMBOL_GPL vmlinux 0x6b2c3acd hid_allocate_device +EXPORT_SYMBOL_GPL vmlinux 0x6b4a6db2 async_tx_issue_pending_all +EXPORT_SYMBOL_GPL vmlinux 0x6b80a7d4 blk_rq_check_limits +EXPORT_SYMBOL_GPL vmlinux 0x6bbd5b90 page_cache_async_readahead +EXPORT_SYMBOL_GPL vmlinux 0x6be27bba rtc_set_time +EXPORT_SYMBOL_GPL vmlinux 0x6bf5a7e9 device_release_driver +EXPORT_SYMBOL_GPL vmlinux 0x6c22eefa fat_fs_panic +EXPORT_SYMBOL_GPL vmlinux 0x6c5304c5 rpcb_getport_sync +EXPORT_SYMBOL_GPL vmlinux 0x6c8d5ae8 __gpio_get_value +EXPORT_SYMBOL_GPL vmlinux 0x6c8d7bc8 class_destroy +EXPORT_SYMBOL_GPL vmlinux 0x6c8e1106 ide_tf_read +EXPORT_SYMBOL_GPL vmlinux 0x6ca32b77 inet6_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0x6cb49f7c nlmclnt_proc +EXPORT_SYMBOL_GPL vmlinux 0x6ceae65f led_trigger_set +EXPORT_SYMBOL_GPL vmlinux 0x6d10f491 usb_get_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x6d28d86e inet_csk_listen_stop +EXPORT_SYMBOL_GPL vmlinux 0x6d2fc5a6 net_namespace_list +EXPORT_SYMBOL_GPL vmlinux 0x6d68b63f platform_device_del +EXPORT_SYMBOL_GPL vmlinux 0x6d7057d8 rpc_killall_tasks +EXPORT_SYMBOL_GPL vmlinux 0x6da4bcd7 init_user_ns +EXPORT_SYMBOL_GPL vmlinux 0x6e401a07 klist_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x6e89ed5a pci_reset_function +EXPORT_SYMBOL_GPL vmlinux 0x6edc9cf6 devres_find +EXPORT_SYMBOL_GPL vmlinux 0x6edee8e3 tcp_reno_min_cwnd +EXPORT_SYMBOL_GPL vmlinux 0x6f0fea0d pci_scan_child_bus +EXPORT_SYMBOL_GPL vmlinux 0x6f1adcab xfrm_inner_extract_output +EXPORT_SYMBOL_GPL vmlinux 0x6f346e5b hid_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0x6f959b35 locks_in_grace +EXPORT_SYMBOL_GPL vmlinux 0x6f9c2efe marker_probe_cb +EXPORT_SYMBOL_GPL vmlinux 0x6fd45b4a ide_end_dequeued_request +EXPORT_SYMBOL_GPL vmlinux 0x6fe01a7e rtc_irq_set_freq +EXPORT_SYMBOL_GPL vmlinux 0x703cae87 usbhid_set_leds +EXPORT_SYMBOL_GPL vmlinux 0x706161b2 device_destroy +EXPORT_SYMBOL_GPL vmlinux 0x707ff1bb ata_xfer_mask2mode +EXPORT_SYMBOL_GPL vmlinux 0x70b7bcdd disk_part_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x70c3d222 map_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x70f7ff09 queue_delayed_work +EXPORT_SYMBOL_GPL vmlinux 0x71196147 tcp_orphan_count +EXPORT_SYMBOL_GPL vmlinux 0x7148d185 fat_get_dotdot_entry +EXPORT_SYMBOL_GPL vmlinux 0x71f9246a leds_list_lock +EXPORT_SYMBOL_GPL vmlinux 0x7202a292 scsi_target_unblock +EXPORT_SYMBOL_GPL vmlinux 0x72462d2f user_destroy +EXPORT_SYMBOL_GPL vmlinux 0x724f7e43 bus_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x725c37c8 vfs_setxattr +EXPORT_SYMBOL_GPL vmlinux 0x7278d328 all_vm_events +EXPORT_SYMBOL_GPL vmlinux 0x72ea8963 register_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0x7329025b usb_driver_release_interface +EXPORT_SYMBOL_GPL vmlinux 0x73555b55 attribute_container_classdev_to_container +EXPORT_SYMBOL_GPL vmlinux 0x73a3d8bb dma_wait_for_async_tx +EXPORT_SYMBOL_GPL vmlinux 0x73a48b4a ata_sff_std_ports +EXPORT_SYMBOL_GPL vmlinux 0x73b1f76d do_posix_clock_nosettime +EXPORT_SYMBOL_GPL vmlinux 0x73e9e1c5 blk_abort_request +EXPORT_SYMBOL_GPL vmlinux 0x743a165e ata_pack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0x745bfcb0 devres_remove +EXPORT_SYMBOL_GPL vmlinux 0x746f40a8 blk_set_cmd_filter_defaults +EXPORT_SYMBOL_GPL vmlinux 0x7486289a init_uts_ns +EXPORT_SYMBOL_GPL vmlinux 0x748f46bd led_trigger_unregister +EXPORT_SYMBOL_GPL vmlinux 0x74938483 sysfs_get_dirent +EXPORT_SYMBOL_GPL vmlinux 0x74d7146b __blk_put_request +EXPORT_SYMBOL_GPL vmlinux 0x75ce628c inotify_remove_watch_locked +EXPORT_SYMBOL_GPL vmlinux 0x76748438 default_mtd_writev +EXPORT_SYMBOL_GPL vmlinux 0x769c4621 platform_device_register +EXPORT_SYMBOL_GPL vmlinux 0x76ba3c30 fl6_sock_lookup +EXPORT_SYMBOL_GPL vmlinux 0x76e3f0e8 ata_sff_prereset +EXPORT_SYMBOL_GPL vmlinux 0x777cd130 security_inode_permission +EXPORT_SYMBOL_GPL vmlinux 0x7794a010 platform_driver_probe +EXPORT_SYMBOL_GPL vmlinux 0x77ead783 hwmon_device_register +EXPORT_SYMBOL_GPL vmlinux 0x7843dd13 sata_scr_read +EXPORT_SYMBOL_GPL vmlinux 0x784f7bac proc_net_mkdir +EXPORT_SYMBOL_GPL vmlinux 0x786a4842 ata_sff_post_internal_cmd +EXPORT_SYMBOL_GPL vmlinux 0x78af7c8f init_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x78e5acdc xprt_reserve_xprt +EXPORT_SYMBOL_GPL vmlinux 0x78ff6f1b crypto_alg_mod_lookup +EXPORT_SYMBOL_GPL vmlinux 0x7948d109 srcu_read_unlock +EXPORT_SYMBOL_GPL vmlinux 0x7976f5bb ata_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0x79d2f8a1 usb_anchor_empty +EXPORT_SYMBOL_GPL vmlinux 0x79f1b275 usb_unpoison_urb +EXPORT_SYMBOL_GPL vmlinux 0x7ac5acc6 ata_eh_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0x7b39f274 inet_ctl_sock_create +EXPORT_SYMBOL_GPL vmlinux 0x7b3d39f9 raw_seq_stop +EXPORT_SYMBOL_GPL vmlinux 0x7c4ea1dd vfs_test_lock +EXPORT_SYMBOL_GPL vmlinux 0x7c6784ef ktime_get_real +EXPORT_SYMBOL_GPL vmlinux 0x7c84a708 xprt_write_space +EXPORT_SYMBOL_GPL vmlinux 0x7cbba573 ide_setting_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x7cbbba6f rpc_call_null +EXPORT_SYMBOL_GPL vmlinux 0x7cd5a542 user_describe +EXPORT_SYMBOL_GPL vmlinux 0x7cf12ff5 ata_sff_host_intr +EXPORT_SYMBOL_GPL vmlinux 0x7d1530e3 usb_clear_halt +EXPORT_SYMBOL_GPL vmlinux 0x7da8d037 marker_probe_register +EXPORT_SYMBOL_GPL vmlinux 0x7db42c6b inotify_rm_wd +EXPORT_SYMBOL_GPL vmlinux 0x7dd84bdf inet_csk_get_port +EXPORT_SYMBOL_GPL vmlinux 0x7de53067 rpc_init_rtt +EXPORT_SYMBOL_GPL vmlinux 0x7dec8a7d scsi_queue_work +EXPORT_SYMBOL_GPL vmlinux 0x7e0c2da9 lookup_instantiate_filp +EXPORT_SYMBOL_GPL vmlinux 0x7e275ea8 scsi_complete_async_scans +EXPORT_SYMBOL_GPL vmlinux 0x7e2d29ec ide_pci_clk +EXPORT_SYMBOL_GPL vmlinux 0x7e64181d usb_calc_bus_time +EXPORT_SYMBOL_GPL vmlinux 0x7f31fa36 register_jprobes +EXPORT_SYMBOL_GPL vmlinux 0x7f402850 inet_csk_reqsk_queue_prune +EXPORT_SYMBOL_GPL vmlinux 0x7f42c1c4 attribute_container_unregister +EXPORT_SYMBOL_GPL vmlinux 0x7fa6e5e4 sysdev_create_file +EXPORT_SYMBOL_GPL vmlinux 0x7fa8a773 __get_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x7ff10ccf raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x7fffe4ff ata_std_postreset +EXPORT_SYMBOL_GPL vmlinux 0x800b6b71 regulator_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x805788c0 regulator_put +EXPORT_SYMBOL_GPL vmlinux 0x805dfa3a bus_for_each_dev +EXPORT_SYMBOL_GPL vmlinux 0x8095ef1b unregister_jprobe +EXPORT_SYMBOL_GPL vmlinux 0x809bd225 input_ff_upload +EXPORT_SYMBOL_GPL vmlinux 0x80da970d disk_part_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x817b6f7e bus_create_file +EXPORT_SYMBOL_GPL vmlinux 0x8226642f __gpio_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x824f14c8 platform_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x826360fd do_posix_clock_nonanosleep +EXPORT_SYMBOL_GPL vmlinux 0x826b2e52 rtc_irq_register +EXPORT_SYMBOL_GPL vmlinux 0x8277b76c audit_log_untrustedstring +EXPORT_SYMBOL_GPL vmlinux 0x8278551a copy_fs_struct +EXPORT_SYMBOL_GPL vmlinux 0x827f0e5c tcp_reno_ssthresh +EXPORT_SYMBOL_GPL vmlinux 0x828d3747 pci_find_ext_capability +EXPORT_SYMBOL_GPL vmlinux 0x82d79b51 sysctl_vfs_cache_pressure +EXPORT_SYMBOL_GPL vmlinux 0x82f37ac8 rpc_call_start +EXPORT_SYMBOL_GPL vmlinux 0x82f776b7 gpio_export +EXPORT_SYMBOL_GPL vmlinux 0x83036235 vfs_lock_file +EXPORT_SYMBOL_GPL vmlinux 0x836d2cc9 __blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x83aad31d xprt_lookup_rqst +EXPORT_SYMBOL_GPL vmlinux 0x83cf0f13 xprt_complete_rqst +EXPORT_SYMBOL_GPL vmlinux 0x8412e3c5 srcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x8449318b schedule_hrtimeout +EXPORT_SYMBOL_GPL vmlinux 0x8469a972 ata_cable_unknown +EXPORT_SYMBOL_GPL vmlinux 0x8470042d register_mtd_blktrans +EXPORT_SYMBOL_GPL vmlinux 0x848082d7 ide_host_add +EXPORT_SYMBOL_GPL vmlinux 0x8492be65 scsi_execute_async +EXPORT_SYMBOL_GPL vmlinux 0x84b3bebe skb_pull_rcsum +EXPORT_SYMBOL_GPL vmlinux 0x85478a0b inet6_hash_frag +EXPORT_SYMBOL_GPL vmlinux 0x854c88fc led_trigger_store +EXPORT_SYMBOL_GPL vmlinux 0x8561cbe9 usb_poison_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x858f8776 bd_release_from_disk +EXPORT_SYMBOL_GPL vmlinux 0x85c10896 rcu_batches_completed_bh +EXPORT_SYMBOL_GPL vmlinux 0x85e5a3db ktime_get_ts +EXPORT_SYMBOL_GPL vmlinux 0x8601d3ca tty_buffer_request_room +EXPORT_SYMBOL_GPL vmlinux 0x864e2966 add_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0x868784cb __symbol_get +EXPORT_SYMBOL_GPL vmlinux 0x8690dee3 ide_exec_command +EXPORT_SYMBOL_GPL vmlinux 0x87754115 raw_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x885142a6 nf_net_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x887eaab1 ide_scsi_expiry +EXPORT_SYMBOL_GPL vmlinux 0x888cce9d sysdev_class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x88a1a339 usb_lock_device_for_reset +EXPORT_SYMBOL_GPL vmlinux 0x88d11259 sata_link_resume +EXPORT_SYMBOL_GPL vmlinux 0x88d605ed driver_add_kobj +EXPORT_SYMBOL_GPL vmlinux 0x88e21c72 inet6_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0x8938d3e5 devres_alloc +EXPORT_SYMBOL_GPL vmlinux 0x8983787e register_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0x8a0fa885 sysfs_update_group +EXPORT_SYMBOL_GPL vmlinux 0x8a3fb58b i2c_add_numbered_adapter +EXPORT_SYMBOL_GPL vmlinux 0x8a895ac6 device_create +EXPORT_SYMBOL_GPL vmlinux 0x8aa219a4 drop_file_write_access +EXPORT_SYMBOL_GPL vmlinux 0x8aa8895a usb_put_hcd +EXPORT_SYMBOL_GPL vmlinux 0x8abd44ed ide_host_register +EXPORT_SYMBOL_GPL vmlinux 0x8abed13d xfrm_aead_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x8ad7cc6f unregister_jprobes +EXPORT_SYMBOL_GPL vmlinux 0x8b65c3f2 pciserial_suspend_ports +EXPORT_SYMBOL_GPL vmlinux 0x8b752ac1 ata_tf_to_fis +EXPORT_SYMBOL_GPL vmlinux 0x8b8189c0 ide_legacy_device_add +EXPORT_SYMBOL_GPL vmlinux 0x8ba473f7 rpcauth_destroy_credcache +EXPORT_SYMBOL_GPL vmlinux 0x8c76c163 pci_execute_reset_function +EXPORT_SYMBOL_GPL vmlinux 0x8c9ccb00 usb_deregister_device_driver +EXPORT_SYMBOL_GPL vmlinux 0x8ce339ba ata_sff_qc_issue +EXPORT_SYMBOL_GPL vmlinux 0x8d07bbe3 ip_route_output_flow +EXPORT_SYMBOL_GPL vmlinux 0x8d2831ad usb_unlink_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x8d2f9e32 pid_vnr +EXPORT_SYMBOL_GPL vmlinux 0x8d3c48cf sk_clone +EXPORT_SYMBOL_GPL vmlinux 0x8d78f29b scsi_mode_select +EXPORT_SYMBOL_GPL vmlinux 0x8dce0b8d ata_cable_80wire +EXPORT_SYMBOL_GPL vmlinux 0x8dff60b8 driver_find +EXPORT_SYMBOL_GPL vmlinux 0x8e6b56f1 pciserial_init_ports +EXPORT_SYMBOL_GPL vmlinux 0x8ecbf441 ata_sff_qc_fill_rtf +EXPORT_SYMBOL_GPL vmlinux 0x8ede0edd attribute_container_register +EXPORT_SYMBOL_GPL vmlinux 0x8efbee89 kill_mtd_super +EXPORT_SYMBOL_GPL vmlinux 0x8f31be64 fat_free_clusters +EXPORT_SYMBOL_GPL vmlinux 0x8f508714 debugfs_create_u16 +EXPORT_SYMBOL_GPL vmlinux 0x8f55cb90 blk_queue_rq_timeout +EXPORT_SYMBOL_GPL vmlinux 0x8f6cee77 __round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x8fcfbeb8 get_device +EXPORT_SYMBOL_GPL vmlinux 0x903b82d3 del_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0x903d4359 device_create_vargs +EXPORT_SYMBOL_GPL vmlinux 0x90a1004a crypto_has_alg +EXPORT_SYMBOL_GPL vmlinux 0x910ee9a8 device_move +EXPORT_SYMBOL_GPL vmlinux 0x9189c0f3 skb_cow_data +EXPORT_SYMBOL_GPL vmlinux 0x9195aeff __ide_error +EXPORT_SYMBOL_GPL vmlinux 0x91a9cb2d device_for_each_child +EXPORT_SYMBOL_GPL vmlinux 0x91aa786e __blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0x923c2f69 unregister_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0x92445aee hrtimer_get_res +EXPORT_SYMBOL_GPL vmlinux 0x92c9a528 tracepoint_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x92f1440b usb_submit_urb +EXPORT_SYMBOL_GPL vmlinux 0x932aadb3 get_cpu_sysdev +EXPORT_SYMBOL_GPL vmlinux 0x934d4e1b do_add_mount +EXPORT_SYMBOL_GPL vmlinux 0x936757b6 tcp_slow_start +EXPORT_SYMBOL_GPL vmlinux 0x93a75da3 led_trigger_set_default +EXPORT_SYMBOL_GPL vmlinux 0x93ab891b usb_driver_claim_interface +EXPORT_SYMBOL_GPL vmlinux 0x93b76636 usb_get_intf +EXPORT_SYMBOL_GPL vmlinux 0x93c5df2c sata_scr_write_flush +EXPORT_SYMBOL_GPL vmlinux 0x93d2422d snmp_mib_free +EXPORT_SYMBOL_GPL vmlinux 0x94619fce ata_host_alloc +EXPORT_SYMBOL_GPL vmlinux 0x948007a1 ata_eh_qc_retry +EXPORT_SYMBOL_GPL vmlinux 0x9490c7c6 dnotify_parent +EXPORT_SYMBOL_GPL vmlinux 0x94a68723 ata_scsi_slave_destroy +EXPORT_SYMBOL_GPL vmlinux 0x94dc62d2 ata_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x94e5f671 debugfs_create_symlink +EXPORT_SYMBOL_GPL vmlinux 0x950565db register_net_sysctl_rotable +EXPORT_SYMBOL_GPL vmlinux 0x950dd805 rtc_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x952664c5 do_exit +EXPORT_SYMBOL_GPL vmlinux 0x953ca8b7 unregister_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0x956a91ba gpio_get_value_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x959e4e48 seq_open_net +EXPORT_SYMBOL_GPL vmlinux 0x95f3bc0f uart_set_options +EXPORT_SYMBOL_GPL vmlinux 0x96877ac4 locks_start_grace +EXPORT_SYMBOL_GPL vmlinux 0x96bf68f0 devres_get +EXPORT_SYMBOL_GPL vmlinux 0x96cbcf31 pm_qos_add_notifier +EXPORT_SYMBOL_GPL vmlinux 0x96f0d64f d_materialise_unique +EXPORT_SYMBOL_GPL vmlinux 0x96f17aa9 ata_do_dev_read_id +EXPORT_SYMBOL_GPL vmlinux 0x9732f417 ata_std_error_handler +EXPORT_SYMBOL_GPL vmlinux 0x976c7d49 ip6_sk_dst_lookup +EXPORT_SYMBOL_GPL vmlinux 0x9772c2d8 udp4_lib_lookup +EXPORT_SYMBOL_GPL vmlinux 0x9784e6b4 register_kprobes +EXPORT_SYMBOL_GPL vmlinux 0x97eeb2f6 register_jprobe +EXPORT_SYMBOL_GPL vmlinux 0x98196f5b blocking_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x982651c6 rpc_call_sync +EXPORT_SYMBOL_GPL vmlinux 0x982a1ea5 ata_bus_reset +EXPORT_SYMBOL_GPL vmlinux 0x98a4c5ff ata_noop_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x98b2b6d3 xprt_register_transport +EXPORT_SYMBOL_GPL vmlinux 0x98b39935 rdev_get_id +EXPORT_SYMBOL_GPL vmlinux 0x991a620d inet6_destroy_sock +EXPORT_SYMBOL_GPL vmlinux 0x9924c496 __usb_get_extra_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x999eec46 tracepoint_iter_reset +EXPORT_SYMBOL_GPL vmlinux 0x9a398f5c xfrm_ealg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x9b2f76ad ata_sff_check_status +EXPORT_SYMBOL_GPL vmlinux 0x9ba0501e unregister_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0x9bd8e150 ide_register_region +EXPORT_SYMBOL_GPL vmlinux 0x9be93aab scsi_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0x9bf888e2 inet_csk_listen_start +EXPORT_SYMBOL_GPL vmlinux 0x9c409467 pci_test_config_bits +EXPORT_SYMBOL_GPL vmlinux 0x9cb8037b xfrm_count_enc_supported +EXPORT_SYMBOL_GPL vmlinux 0x9d05ffbd crypto_alg_sem +EXPORT_SYMBOL_GPL vmlinux 0x9d710782 sysfs_notify_dirent +EXPORT_SYMBOL_GPL vmlinux 0x9dfac2d4 svc_reg_xprt_class +EXPORT_SYMBOL_GPL vmlinux 0x9e370c26 bus_get_kset +EXPORT_SYMBOL_GPL vmlinux 0x9e38e0af ide_issue_pc +EXPORT_SYMBOL_GPL vmlinux 0x9e45e448 ata_sff_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0x9e711ad2 pm_qos_requirement +EXPORT_SYMBOL_GPL vmlinux 0x9ee76812 rt_mutex_unlock +EXPORT_SYMBOL_GPL vmlinux 0x9f0b6eb6 rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0x9f396ecd rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x9fce80db fb_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xa0255440 net_ipv4_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0xa028f7f8 inet_hash +EXPORT_SYMBOL_GPL vmlinux 0xa04e3b2f rpc_malloc +EXPORT_SYMBOL_GPL vmlinux 0xa067ed66 ide_set_media_lock +EXPORT_SYMBOL_GPL vmlinux 0xa09c77f1 init_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0xa0a3d6a7 unregister_kprobe +EXPORT_SYMBOL_GPL vmlinux 0xa0cc2850 regulator_enable +EXPORT_SYMBOL_GPL vmlinux 0xa11520b7 ide_io_buffers +EXPORT_SYMBOL_GPL vmlinux 0xa155f542 generic_fh_to_dentry +EXPORT_SYMBOL_GPL vmlinux 0xa1c2e6ce input_ff_destroy +EXPORT_SYMBOL_GPL vmlinux 0xa1dc6a18 xfrm_output_resume +EXPORT_SYMBOL_GPL vmlinux 0xa221e9c9 inet_diag_unregister +EXPORT_SYMBOL_GPL vmlinux 0xa2256436 ide_error +EXPORT_SYMBOL_GPL vmlinux 0xa27fdda9 sysfs_get +EXPORT_SYMBOL_GPL vmlinux 0xa29a1214 usb_scuttle_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xa2bfe21c xfrm_output +EXPORT_SYMBOL_GPL vmlinux 0xa3137248 sata_link_hardreset +EXPORT_SYMBOL_GPL vmlinux 0xa3fc96f0 marker_probe_cb_noarg +EXPORT_SYMBOL_GPL vmlinux 0xa4303b73 hid_parse_report +EXPORT_SYMBOL_GPL vmlinux 0xa43266d1 regulator_set_current_limit +EXPORT_SYMBOL_GPL vmlinux 0xa43c0b6d async_tx_run_dependencies +EXPORT_SYMBOL_GPL vmlinux 0xa45febf6 dma_get_required_mask +EXPORT_SYMBOL_GPL vmlinux 0xa481fe33 __mmdrop +EXPORT_SYMBOL_GPL vmlinux 0xa49be4db single_release_net +EXPORT_SYMBOL_GPL vmlinux 0xa4f09479 arm_pm_restart +EXPORT_SYMBOL_GPL vmlinux 0xa5409810 inet6_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0xa57afc74 ktime_get +EXPORT_SYMBOL_GPL vmlinux 0xa5885f73 pci_intx +EXPORT_SYMBOL_GPL vmlinux 0xa5bf5c3e pm_qos_add_requirement +EXPORT_SYMBOL_GPL vmlinux 0xa5c36cec inotify_unmount_inodes +EXPORT_SYMBOL_GPL vmlinux 0xa5e1ad5b rpcauth_register +EXPORT_SYMBOL_GPL vmlinux 0xa65f9329 raw_seq_next +EXPORT_SYMBOL_GPL vmlinux 0xa6923523 unregister_kprobes +EXPORT_SYMBOL_GPL vmlinux 0xa751074a cfi_qry_mode_on +EXPORT_SYMBOL_GPL vmlinux 0xa778bae2 __inet_twsk_hashdance +EXPORT_SYMBOL_GPL vmlinux 0xa77c927c sock_prot_inuse_get +EXPORT_SYMBOL_GPL vmlinux 0xa7c35c6b getnstimeofday +EXPORT_SYMBOL_GPL vmlinux 0xa7ed6c2a netlink_has_listeners +EXPORT_SYMBOL_GPL vmlinux 0xa88a20c5 ide_host_alloc +EXPORT_SYMBOL_GPL vmlinux 0xa88f54f2 ata_cable_40wire +EXPORT_SYMBOL_GPL vmlinux 0xa8b88bff __pneigh_lookup +EXPORT_SYMBOL_GPL vmlinux 0xa8f59416 gpio_direction_output +EXPORT_SYMBOL_GPL vmlinux 0xa922b222 ata_port_freeze +EXPORT_SYMBOL_GPL vmlinux 0xa938a001 rpc_sleep_on +EXPORT_SYMBOL_GPL vmlinux 0xa94dd062 regulator_set_drvdata +EXPORT_SYMBOL_GPL vmlinux 0xa950b809 device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xa98087c5 svc_create_xprt +EXPORT_SYMBOL_GPL vmlinux 0xa9c530b8 unregister_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xaa2a72bf __iowrite64_copy +EXPORT_SYMBOL_GPL vmlinux 0xaa62eda2 ide_get_best_pio_mode +EXPORT_SYMBOL_GPL vmlinux 0xaa7991cd rpc_wake_up_next +EXPORT_SYMBOL_GPL vmlinux 0xaa8c4696 cpu_clock +EXPORT_SYMBOL_GPL vmlinux 0xab10e70b raw_hash_sk +EXPORT_SYMBOL_GPL vmlinux 0xab2251f9 rt_mutex_lock_interruptible +EXPORT_SYMBOL_GPL vmlinux 0xab291772 devres_release_group +EXPORT_SYMBOL_GPL vmlinux 0xab57e311 tracepoint_probe_register +EXPORT_SYMBOL_GPL vmlinux 0xabd46ac2 device_attach +EXPORT_SYMBOL_GPL vmlinux 0xabff29cc usb_init_urb +EXPORT_SYMBOL_GPL vmlinux 0xacb31862 device_reprobe +EXPORT_SYMBOL_GPL vmlinux 0xacb9c24f transport_setup_device +EXPORT_SYMBOL_GPL vmlinux 0xacc66eb2 sdev_evt_send +EXPORT_SYMBOL_GPL vmlinux 0xacd7dbb0 ata_scsi_simulate +EXPORT_SYMBOL_GPL vmlinux 0xace5c0fc usb_bus_list +EXPORT_SYMBOL_GPL vmlinux 0xad453f65 fat_scan +EXPORT_SYMBOL_GPL vmlinux 0xad775894 usb_free_urb +EXPORT_SYMBOL_GPL vmlinux 0xadbb2197 klist_add_after +EXPORT_SYMBOL_GPL vmlinux 0xade509d3 pci_block_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0xae0c87ee pm_qos_remove_notifier +EXPORT_SYMBOL_GPL vmlinux 0xae699240 svc_xprt_enqueue +EXPORT_SYMBOL_GPL vmlinux 0xaf153c56 firmware_kobj +EXPORT_SYMBOL_GPL vmlinux 0xaf3aa28e tracepoint_iter_start +EXPORT_SYMBOL_GPL vmlinux 0xaf5bf6ef nfs_debug +EXPORT_SYMBOL_GPL vmlinux 0xafafc2b8 ata_cable_ignore +EXPORT_SYMBOL_GPL vmlinux 0xb094d454 ata_host_register +EXPORT_SYMBOL_GPL vmlinux 0xb156d3a8 fat_remove_entries +EXPORT_SYMBOL_GPL vmlinux 0xb1acbcce rcu_barrier_sched +EXPORT_SYMBOL_GPL vmlinux 0xb2052ea2 rpc_max_payload +EXPORT_SYMBOL_GPL vmlinux 0xb23acf18 tcp_get_info +EXPORT_SYMBOL_GPL vmlinux 0xb2cd8dd9 sysfs_remove_file_from_group +EXPORT_SYMBOL_GPL vmlinux 0xb2dea76a usb_register_dev +EXPORT_SYMBOL_GPL vmlinux 0xb33a28bd fat_attach +EXPORT_SYMBOL_GPL vmlinux 0xb35b58aa ata_scsi_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0xb36fc2cc usb_alloc_urb +EXPORT_SYMBOL_GPL vmlinux 0xb38a8391 kobject_get_path +EXPORT_SYMBOL_GPL vmlinux 0xb3d51721 unregister_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0xb426b820 ata_bmdma_setup +EXPORT_SYMBOL_GPL vmlinux 0xb449ed11 mtd_table_mutex +EXPORT_SYMBOL_GPL vmlinux 0xb46b5118 usb_sg_wait +EXPORT_SYMBOL_GPL vmlinux 0xb4a4b9fb blocking_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0xb4b035fc mm_kobj +EXPORT_SYMBOL_GPL vmlinux 0xb541bac0 kset_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0xb55aa782 page_mkclean +EXPORT_SYMBOL_GPL vmlinux 0xb5b20f2a transport_configure_device +EXPORT_SYMBOL_GPL vmlinux 0xb5c719c5 sysdev_driver_register +EXPORT_SYMBOL_GPL vmlinux 0xb6031fc2 tty_mode_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xb60d886c pci_set_pcie_reset_state +EXPORT_SYMBOL_GPL vmlinux 0xb6399be3 fat_time_unix2fat +EXPORT_SYMBOL_GPL vmlinux 0xb6aa0a95 led_classdev_resume +EXPORT_SYMBOL_GPL vmlinux 0xb6aeb661 ata_id_c_string +EXPORT_SYMBOL_GPL vmlinux 0xb6bc5961 register_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0xb6f97405 class_dev_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0xb71223ff part_round_stats +EXPORT_SYMBOL_GPL vmlinux 0xb7398a55 rtc_update_irq +EXPORT_SYMBOL_GPL vmlinux 0xb74c5247 invalidate_inode_pages2_range +EXPORT_SYMBOL_GPL vmlinux 0xb7682e6b inet_twsk_put +EXPORT_SYMBOL_GPL vmlinux 0xb7d53571 usb_match_id +EXPORT_SYMBOL_GPL vmlinux 0xb7e92537 sysdev_store_int +EXPORT_SYMBOL_GPL vmlinux 0xb80610b9 platform_device_alloc +EXPORT_SYMBOL_GPL vmlinux 0xb8759c2c srcu_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0xb880d395 ata_sff_softreset +EXPORT_SYMBOL_GPL vmlinux 0xb896e634 regulator_register +EXPORT_SYMBOL_GPL vmlinux 0xb8b0dc77 platform_driver_register +EXPORT_SYMBOL_GPL vmlinux 0xb8d7fd71 ide_port_unregister_devices +EXPORT_SYMBOL_GPL vmlinux 0xb8f7fc58 register_mtd_user +EXPORT_SYMBOL_GPL vmlinux 0xb8fee532 blocking_notifier_chain_cond_register +EXPORT_SYMBOL_GPL vmlinux 0xb9046991 rtc_read_time +EXPORT_SYMBOL_GPL vmlinux 0xb99bd291 pci_create_slot +EXPORT_SYMBOL_GPL vmlinux 0xb9d5dfbd page_cache_sync_readahead +EXPORT_SYMBOL_GPL vmlinux 0xb9eb3aa9 add_uevent_var +EXPORT_SYMBOL_GPL vmlinux 0xba205d9c usb_hcd_pci_probe +EXPORT_SYMBOL_GPL vmlinux 0xbac26dcc tty_put_char +EXPORT_SYMBOL_GPL vmlinux 0xbac496fd svc_xprt_copy_addrs +EXPORT_SYMBOL_GPL vmlinux 0xbaf09ec0 klist_del +EXPORT_SYMBOL_GPL vmlinux 0xbb248c8a get_user_pages_fast +EXPORT_SYMBOL_GPL vmlinux 0xbb578578 hrtimer_cancel +EXPORT_SYMBOL_GPL vmlinux 0xbb9a2c75 ktime_add_ns +EXPORT_SYMBOL_GPL vmlinux 0xbbb8d3c0 rtc_set_mmss +EXPORT_SYMBOL_GPL vmlinux 0xbbc8ffda tcp_set_state +EXPORT_SYMBOL_GPL vmlinux 0xbbfd5af5 ide_set_dma_mode +EXPORT_SYMBOL_GPL vmlinux 0xbc0ce73d audit_log_vformat +EXPORT_SYMBOL_GPL vmlinux 0xbc163956 transport_remove_device +EXPORT_SYMBOL_GPL vmlinux 0xbc3a84f5 platform_device_add +EXPORT_SYMBOL_GPL vmlinux 0xbc4d7783 deregister_mtd_parser +EXPORT_SYMBOL_GPL vmlinux 0xbca22ac2 led_trigger_unregister_simple +EXPORT_SYMBOL_GPL vmlinux 0xbca3de14 sysfs_chmod_file +EXPORT_SYMBOL_GPL vmlinux 0xbcb74e58 __rpc_wait_for_completion_task +EXPORT_SYMBOL_GPL vmlinux 0xbcc45fdc regulator_bulk_disable +EXPORT_SYMBOL_GPL vmlinux 0xbcdb79c3 debugfs_create_x8 +EXPORT_SYMBOL_GPL vmlinux 0xbce967d7 nlmclnt_done +EXPORT_SYMBOL_GPL vmlinux 0xbcf9dbb3 regulator_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0xbdace338 bus_for_each_drv +EXPORT_SYMBOL_GPL vmlinux 0xbdb735a0 mtd_table +EXPORT_SYMBOL_GPL vmlinux 0xbdcfd09d xprt_unregister_transport +EXPORT_SYMBOL_GPL vmlinux 0xbdd295f0 trace_vprintk +EXPORT_SYMBOL_GPL vmlinux 0xbdd3ce48 usb_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0xbe082a49 sysdev_class_register +EXPORT_SYMBOL_GPL vmlinux 0xbe1887e4 ata_unpack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xbe5bab89 sysdev_register +EXPORT_SYMBOL_GPL vmlinux 0xbeea7a2b srcu_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0xbf55e66f crypto_alg_lookup +EXPORT_SYMBOL_GPL vmlinux 0xbf9d1b96 nfsd_debug +EXPORT_SYMBOL_GPL vmlinux 0xbfb463c3 __async_tx_find_channel +EXPORT_SYMBOL_GPL vmlinux 0xbfb66151 crypto_mod_get +EXPORT_SYMBOL_GPL vmlinux 0xbfc00ed3 ide_pktcmd_tf_load +EXPORT_SYMBOL_GPL vmlinux 0xbfc6ae2d __class_register +EXPORT_SYMBOL_GPL vmlinux 0xbfe7385b usb_kill_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xc08e6caf usb_kill_urb +EXPORT_SYMBOL_GPL vmlinux 0xc12435e3 rpc_calc_rto +EXPORT_SYMBOL_GPL vmlinux 0xc17515d7 usb_hcds_loaded +EXPORT_SYMBOL_GPL vmlinux 0xc1757a43 tcp_twsk_unique +EXPORT_SYMBOL_GPL vmlinux 0xc1cf14d3 debugfs_create_u32 +EXPORT_SYMBOL_GPL vmlinux 0xc21a2b6d usb_get_current_frame_number +EXPORT_SYMBOL_GPL vmlinux 0xc22a3091 vm_unmap_aliases +EXPORT_SYMBOL_GPL vmlinux 0xc2468d9c blk_execute_rq_nowait +EXPORT_SYMBOL_GPL vmlinux 0xc254324b svc_max_payload +EXPORT_SYMBOL_GPL vmlinux 0xc26184ac svc_close_xprt +EXPORT_SYMBOL_GPL vmlinux 0xc27d993c ata_sff_hsm_move +EXPORT_SYMBOL_GPL vmlinux 0xc2dc3b6d mnt_drop_write +EXPORT_SYMBOL_GPL vmlinux 0xc2e27f52 ata_sas_port_destroy +EXPORT_SYMBOL_GPL vmlinux 0xc2f94b72 device_add +EXPORT_SYMBOL_GPL vmlinux 0xc34efe27 snmp_fold_field +EXPORT_SYMBOL_GPL vmlinux 0xc351342e sysfs_put +EXPORT_SYMBOL_GPL vmlinux 0xc3a589be dev_attr_em_message_type +EXPORT_SYMBOL_GPL vmlinux 0xc3c69e27 usb_hcd_link_urb_to_ep +EXPORT_SYMBOL_GPL vmlinux 0xc3dac1cf __blkdev_driver_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xc3f59870 ide_set_irq +EXPORT_SYMBOL_GPL vmlinux 0xc3fe2dd0 unregister_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0xc427bc36 pci_renumber_slot +EXPORT_SYMBOL_GPL vmlinux 0xc428068d sata_deb_timing_long +EXPORT_SYMBOL_GPL vmlinux 0xc48b7ccf ata_mode_string +EXPORT_SYMBOL_GPL vmlinux 0xc4a30446 find_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0xc4b33aa6 tracepoint_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc516d01b devres_remove_group +EXPORT_SYMBOL_GPL vmlinux 0xc5424e3f usb_put_intf +EXPORT_SYMBOL_GPL vmlinux 0xc596d5d8 get_mtd_device_nm +EXPORT_SYMBOL_GPL vmlinux 0xc5aaf106 ata_cable_sata +EXPORT_SYMBOL_GPL vmlinux 0xc6613cf4 driver_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0xc673e23e ata_scsi_change_queue_depth +EXPORT_SYMBOL_GPL vmlinux 0xc744ac86 ide_pci_init_one +EXPORT_SYMBOL_GPL vmlinux 0xc7504484 tracepoint_get_iter_range +EXPORT_SYMBOL_GPL vmlinux 0xc7656416 regulator_set_optimum_mode +EXPORT_SYMBOL_GPL vmlinux 0xc7968cd6 blk_rq_bytes +EXPORT_SYMBOL_GPL vmlinux 0xc7a5decf unregister_mtd_user +EXPORT_SYMBOL_GPL vmlinux 0xc7d19186 tty_perform_flush +EXPORT_SYMBOL_GPL vmlinux 0xc7fc32ec usb_mon_register +EXPORT_SYMBOL_GPL vmlinux 0xc81fc664 ata_sff_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xc876e17d class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xc8d37866 __rt_mutex_init +EXPORT_SYMBOL_GPL vmlinux 0xc8eac19a regulator_disable +EXPORT_SYMBOL_GPL vmlinux 0xc9021068 sata_std_hardreset +EXPORT_SYMBOL_GPL vmlinux 0xc9155539 ata_sas_port_alloc +EXPORT_SYMBOL_GPL vmlinux 0xc927190b ide_output_data +EXPORT_SYMBOL_GPL vmlinux 0xc9428b5b put_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0xc9832c6d sysdev_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xca243389 ide_read_altstatus +EXPORT_SYMBOL_GPL vmlinux 0xca8d6757 pci_find_next_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0xcade53ff devm_kzalloc +EXPORT_SYMBOL_GPL vmlinux 0xcae30cc0 ide_setup_pci_noise +EXPORT_SYMBOL_GPL vmlinux 0xcb0c2ebf __srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xcb7b52fc fat_dir_empty +EXPORT_SYMBOL_GPL vmlinux 0xcbbf954f rpc_restart_call +EXPORT_SYMBOL_GPL vmlinux 0xcbf1782f __ata_port_next_link +EXPORT_SYMBOL_GPL vmlinux 0xcc0ed8d0 file_ra_state_init +EXPORT_SYMBOL_GPL vmlinux 0xcc1f1c3d inet_twdr_hangman +EXPORT_SYMBOL_GPL vmlinux 0xcc49f6d1 destroy_workqueue +EXPORT_SYMBOL_GPL vmlinux 0xcc6d999a sysfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0xcc9a7c1c elv_register +EXPORT_SYMBOL_GPL vmlinux 0xcc9db6d2 xprt_set_retrans_timeout_def +EXPORT_SYMBOL_GPL vmlinux 0xcca0c0c8 schedule_hrtimeout_range +EXPORT_SYMBOL_GPL vmlinux 0xccaedf35 usb_interrupt_msg +EXPORT_SYMBOL_GPL vmlinux 0xcccadf40 bus_find_device +EXPORT_SYMBOL_GPL vmlinux 0xcccfb2fa sata_deb_timing_hotplug +EXPORT_SYMBOL_GPL vmlinux 0xcce35b1b generic_drop_inode +EXPORT_SYMBOL_GPL vmlinux 0xcd12a8c0 usb_hcd_platform_shutdown +EXPORT_SYMBOL_GPL vmlinux 0xcd297462 vfs_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0xcd3f85d0 tty_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0xcd6c8525 pci_find_next_capability +EXPORT_SYMBOL_GPL vmlinux 0xcd76e810 sg_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xcda32a94 klist_remove +EXPORT_SYMBOL_GPL vmlinux 0xcdb3cff0 klist_iter_init_node +EXPORT_SYMBOL_GPL vmlinux 0xcdca3691 nr_irqs +EXPORT_SYMBOL_GPL vmlinux 0xce4259d2 class_dev_iter_init +EXPORT_SYMBOL_GPL vmlinux 0xce7a3921 __mnt_is_readonly +EXPORT_SYMBOL_GPL vmlinux 0xce7b1bcb async_tx_submit +EXPORT_SYMBOL_GPL vmlinux 0xcedc0124 rpc_print_iostats +EXPORT_SYMBOL_GPL vmlinux 0xcef257d5 driver_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xcf00a7cf sysdev_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xcf339ab0 debugfs_create_u8 +EXPORT_SYMBOL_GPL vmlinux 0xcf7bb156 hrtimer_init +EXPORT_SYMBOL_GPL vmlinux 0xcfcc83ad register_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0xcfd519e9 xdr_partial_copy_from_skb +EXPORT_SYMBOL_GPL vmlinux 0xd01b9664 vfs_getxattr +EXPORT_SYMBOL_GPL vmlinux 0xd027a07d marker_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xd02e4847 blk_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0xd03c7700 secure_ipv4_port_ephemeral +EXPORT_SYMBOL_GPL vmlinux 0xd0c05159 emergency_restart +EXPORT_SYMBOL_GPL vmlinux 0xd0e5e7d3 hid_set_field +EXPORT_SYMBOL_GPL vmlinux 0xd144828c simple_attr_open +EXPORT_SYMBOL_GPL vmlinux 0xd1d6cb06 crypto_alloc_base +EXPORT_SYMBOL_GPL vmlinux 0xd1da8004 fat_detach +EXPORT_SYMBOL_GPL vmlinux 0xd2303edf fat_add_entries +EXPORT_SYMBOL_GPL vmlinux 0xd2475c83 put_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0xd273b1b1 __round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xd2a79376 __scsi_get_command +EXPORT_SYMBOL_GPL vmlinux 0xd2a7b28d sata_scr_valid +EXPORT_SYMBOL_GPL vmlinux 0xd2f1343e svc_xprt_names +EXPORT_SYMBOL_GPL vmlinux 0xd3611c4b ata_pci_bmdma_clear_simplex +EXPORT_SYMBOL_GPL vmlinux 0xd3ac605d rpcauth_lookup_credcache +EXPORT_SYMBOL_GPL vmlinux 0xd3dd2cb3 xprt_reserve_xprt_cong +EXPORT_SYMBOL_GPL vmlinux 0xd4030d14 rtnl_put_cacheinfo +EXPORT_SYMBOL_GPL vmlinux 0xd440e729 blk_abort_queue +EXPORT_SYMBOL_GPL vmlinux 0xd516bc65 blk_end_request_callback +EXPORT_SYMBOL_GPL vmlinux 0xd52544d5 usb_hc_died +EXPORT_SYMBOL_GPL vmlinux 0xd564ecf2 usb_hcd_pci_remove +EXPORT_SYMBOL_GPL vmlinux 0xd5a28c0d device_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xd5a6221c ide_undecoded_slave +EXPORT_SYMBOL_GPL vmlinux 0xd5aee563 blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0xd6771d55 scsi_internal_device_block +EXPORT_SYMBOL_GPL vmlinux 0xd6e8db46 ata_sas_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0xd741cfcf blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xd828845f bus_unregister +EXPORT_SYMBOL_GPL vmlinux 0xd841ea15 net_assign_generic +EXPORT_SYMBOL_GPL vmlinux 0xd84cd7f4 ata_timing_find_mode +EXPORT_SYMBOL_GPL vmlinux 0xd8af770c __rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0xd909bd1c bus_find_device_by_name +EXPORT_SYMBOL_GPL vmlinux 0xd9dfbee3 get_driver +EXPORT_SYMBOL_GPL vmlinux 0xd9e878fa ide_set_pio +EXPORT_SYMBOL_GPL vmlinux 0xd9ea18b3 rpc_lookup_machine_cred +EXPORT_SYMBOL_GPL vmlinux 0xda1c436d inet6_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0xda1d5f92 ata_sff_freeze +EXPORT_SYMBOL_GPL vmlinux 0xda3fc60d ide_pad_transfer +EXPORT_SYMBOL_GPL vmlinux 0xda526418 ata_dummy_port_info +EXPORT_SYMBOL_GPL vmlinux 0xdbb29042 user_update +EXPORT_SYMBOL_GPL vmlinux 0xdc421e92 fsstack_copy_inode_size +EXPORT_SYMBOL_GPL vmlinux 0xdc5c7529 bus_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0xdcf63047 skb_morph +EXPORT_SYMBOL_GPL vmlinux 0xdcfff880 default_backing_dev_info +EXPORT_SYMBOL_GPL vmlinux 0xdd0d7369 queue_work +EXPORT_SYMBOL_GPL vmlinux 0xdd26a501 debugfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0xdd37a98e usb_deregister_dev +EXPORT_SYMBOL_GPL vmlinux 0xdde9332f ata_bmdma_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xdde99d1f exportfs_encode_fh +EXPORT_SYMBOL_GPL vmlinux 0xde3dba86 cfi_qry_present +EXPORT_SYMBOL_GPL vmlinux 0xde3f5dff xprt_release_xprt +EXPORT_SYMBOL_GPL vmlinux 0xdeb039ff platform_get_resource_byname +EXPORT_SYMBOL_GPL vmlinux 0xdf03e3b3 ata_sff_irq_clear +EXPORT_SYMBOL_GPL vmlinux 0xdf3022b2 ata_sff_interrupt +EXPORT_SYMBOL_GPL vmlinux 0xdf3d7955 get_task_mm +EXPORT_SYMBOL_GPL vmlinux 0xdf76b454 sysfs_add_file_to_group +EXPORT_SYMBOL_GPL vmlinux 0xdffaf4c1 ide_check_atapi_device +EXPORT_SYMBOL_GPL vmlinux 0xe0040bdb platform_get_resource +EXPORT_SYMBOL_GPL vmlinux 0xe0044526 usb_hcd_poll_rh_status +EXPORT_SYMBOL_GPL vmlinux 0xe0119487 security_inode_setattr +EXPORT_SYMBOL_GPL vmlinux 0xe0194303 inet_twsk_alloc +EXPORT_SYMBOL_GPL vmlinux 0xe09acf57 audit_log_d_path +EXPORT_SYMBOL_GPL vmlinux 0xe0fd46fe skb_partial_csum_set +EXPORT_SYMBOL_GPL vmlinux 0xe1192340 tcp_done +EXPORT_SYMBOL_GPL vmlinux 0xe1c1a642 ata_dummy_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xe1cff440 __sock_recv_timestamp +EXPORT_SYMBOL_GPL vmlinux 0xe1e4e818 crypto_free_tfm +EXPORT_SYMBOL_GPL vmlinux 0xe1e5f103 debugfs_rename +EXPORT_SYMBOL_GPL vmlinux 0xe2421b6f ata_qc_complete_multiple +EXPORT_SYMBOL_GPL vmlinux 0xe269b5ad usb_driver_set_configuration +EXPORT_SYMBOL_GPL vmlinux 0xe2c8e70e rpcb_getport_async +EXPORT_SYMBOL_GPL vmlinux 0xe2d1dc35 ide_init_pc +EXPORT_SYMBOL_GPL vmlinux 0xe2e118f0 cfi_cmdset_0001 +EXPORT_SYMBOL_GPL vmlinux 0xe334f63b led_trigger_remove +EXPORT_SYMBOL_GPL vmlinux 0xe39aaf89 regulator_force_disable +EXPORT_SYMBOL_GPL vmlinux 0xe4428e20 scsi_target_block +EXPORT_SYMBOL_GPL vmlinux 0xe4431ef2 devres_close_group +EXPORT_SYMBOL_GPL vmlinux 0xe459110e crypto_larval_kill +EXPORT_SYMBOL_GPL vmlinux 0xe49ff3b0 ata_wait_register +EXPORT_SYMBOL_GPL vmlinux 0xe4a56817 regulator_bulk_get +EXPORT_SYMBOL_GPL vmlinux 0xe4ba6379 device_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xe5001ca9 ata_sff_busy_sleep +EXPORT_SYMBOL_GPL vmlinux 0xe50b96ba ide_retry_pc +EXPORT_SYMBOL_GPL vmlinux 0xe50e330d led_classdev_unregister +EXPORT_SYMBOL_GPL vmlinux 0xe530071c pm_qos_remove_requirement +EXPORT_SYMBOL_GPL vmlinux 0xe54ad6e7 ata_eh_thaw_port +EXPORT_SYMBOL_GPL vmlinux 0xe55f0f8d inet_twsk_schedule +EXPORT_SYMBOL_GPL vmlinux 0xe5741c6c bus_get_device_klist +EXPORT_SYMBOL_GPL vmlinux 0xe59eebf5 inet_twsk_purge +EXPORT_SYMBOL_GPL vmlinux 0xe61a6d2f gpio_unexport +EXPORT_SYMBOL_GPL vmlinux 0xe6228681 mmput +EXPORT_SYMBOL_GPL vmlinux 0xe63448d4 ata_sff_dev_select +EXPORT_SYMBOL_GPL vmlinux 0xe68b16c9 ata_host_activate +EXPORT_SYMBOL_GPL vmlinux 0xe68ba9d0 ide_read_status +EXPORT_SYMBOL_GPL vmlinux 0xe8163e12 k_handler +EXPORT_SYMBOL_GPL vmlinux 0xe8e68708 ata_eh_freeze_port +EXPORT_SYMBOL_GPL vmlinux 0xe925e036 register_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0xe93e49c3 devres_free +EXPORT_SYMBOL_GPL vmlinux 0xe946a3cd ide_read_error +EXPORT_SYMBOL_GPL vmlinux 0xe9587909 usb_unregister_notify +EXPORT_SYMBOL_GPL vmlinux 0xe95b2b34 kobject_uevent +EXPORT_SYMBOL_GPL vmlinux 0xe95c2637 ata_timing_compute +EXPORT_SYMBOL_GPL vmlinux 0xe97bec68 uhci_check_and_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0xe9e0bf4e usb_deregister +EXPORT_SYMBOL_GPL vmlinux 0xe9e7a3f2 ata_std_bios_param +EXPORT_SYMBOL_GPL vmlinux 0xea418e0f atapi_cmd_type +EXPORT_SYMBOL_GPL vmlinux 0xea62c60c hrtimer_get_remaining +EXPORT_SYMBOL_GPL vmlinux 0xea7e528d debugfs_create_u64 +EXPORT_SYMBOL_GPL vmlinux 0xeb2aa95d rdev_get_dev +EXPORT_SYMBOL_GPL vmlinux 0xeb608325 kobject_init_and_add +EXPORT_SYMBOL_GPL vmlinux 0xeba24cb2 regulator_is_enabled +EXPORT_SYMBOL_GPL vmlinux 0xebaa0768 sysfs_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xec1b043e regulator_suspend_prepare +EXPORT_SYMBOL_GPL vmlinux 0xec575abe device_bind_driver +EXPORT_SYMBOL_GPL vmlinux 0xec731622 usb_match_one_id +EXPORT_SYMBOL_GPL vmlinux 0xed0fc5fa pci_find_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0xed186d94 vfs_listxattr +EXPORT_SYMBOL_GPL vmlinux 0xed1ee117 input_class +EXPORT_SYMBOL_GPL vmlinux 0xed262711 mnt_want_write +EXPORT_SYMBOL_GPL vmlinux 0xeddaf42b usb_control_msg +EXPORT_SYMBOL_GPL vmlinux 0xedf91b42 usb_ep0_reinit +EXPORT_SYMBOL_GPL vmlinux 0xeeacab69 rpc_update_rtt +EXPORT_SYMBOL_GPL vmlinux 0xef233ba3 rpc_destroy_wait_queue +EXPORT_SYMBOL_GPL vmlinux 0xef2693dd debugfs_remove +EXPORT_SYMBOL_GPL vmlinux 0xef4e963e __atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xef61dd04 sata_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xef6c3f70 round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xef759af9 usb_reset_device +EXPORT_SYMBOL_GPL vmlinux 0xef82fdba srcu_init_notifier_head +EXPORT_SYMBOL_GPL vmlinux 0xefe21106 snmp_mib_init +EXPORT_SYMBOL_GPL vmlinux 0xf0087f30 pciserial_resume_ports +EXPORT_SYMBOL_GPL vmlinux 0xf053f78a hid_output_report +EXPORT_SYMBOL_GPL vmlinux 0xf09034d4 inet6_sk_rebuild_header +EXPORT_SYMBOL_GPL vmlinux 0xf0c6f9c4 sysdev_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf0ce5881 parse_mtd_partitions +EXPORT_SYMBOL_GPL vmlinux 0xf105d00d ide_in_drive_list +EXPORT_SYMBOL_GPL vmlinux 0xf120b836 hid_connect +EXPORT_SYMBOL_GPL vmlinux 0xf1349926 bus_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0xf1463412 execute_in_process_context +EXPORT_SYMBOL_GPL vmlinux 0xf168f681 xprt_disconnect_done +EXPORT_SYMBOL_GPL vmlinux 0xf184d189 kernel_power_off +EXPORT_SYMBOL_GPL vmlinux 0xf18a2ca7 ata_ehi_clear_desc +EXPORT_SYMBOL_GPL vmlinux 0xf1afdb94 kill_pid_info_as_uid +EXPORT_SYMBOL_GPL vmlinux 0xf1bcbf2b device_rename +EXPORT_SYMBOL_GPL vmlinux 0xf1d4ea33 regulator_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0xf22411fd pci_bus_add_device +EXPORT_SYMBOL_GPL vmlinux 0xf266df9d rtc_irq_set_state +EXPORT_SYMBOL_GPL vmlinux 0xf28af424 sysfs_schedule_callback +EXPORT_SYMBOL_GPL vmlinux 0xf2c5c1b4 usb_unanchor_urb +EXPORT_SYMBOL_GPL vmlinux 0xf2fca922 uart_parse_options +EXPORT_SYMBOL_GPL vmlinux 0xf30a5457 mtd_erase_callback +EXPORT_SYMBOL_GPL vmlinux 0xf317788a dequeue_signal +EXPORT_SYMBOL_GPL vmlinux 0xf3cfcfb4 fat_sync_inode +EXPORT_SYMBOL_GPL vmlinux 0xf3d5cc13 ata_timing_merge +EXPORT_SYMBOL_GPL vmlinux 0xf3e96307 platform_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf46fd2bc sock_prot_inuse_add +EXPORT_SYMBOL_GPL vmlinux 0xf499fdb2 rcu_barrier_bh +EXPORT_SYMBOL_GPL vmlinux 0xf4bd9e27 ide_pci_setup_ports +EXPORT_SYMBOL_GPL vmlinux 0xf4d34ee1 regulator_get_mode +EXPORT_SYMBOL_GPL vmlinux 0xf4e7d037 ata_port_pbar_desc +EXPORT_SYMBOL_GPL vmlinux 0xf5070d56 flush_workqueue +EXPORT_SYMBOL_GPL vmlinux 0xf50cd762 sysdev_class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xf53cfe2b klist_node_attached +EXPORT_SYMBOL_GPL vmlinux 0xf5a691cd invalidate_bh_lrus +EXPORT_SYMBOL_GPL vmlinux 0xf5b46ba1 __rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf5bff8f9 deregister_mtd_blktrans +EXPORT_SYMBOL_GPL vmlinux 0xf6030f1b ata_common_sdev_attrs +EXPORT_SYMBOL_GPL vmlinux 0xf635d8a5 fnotify_change +EXPORT_SYMBOL_GPL vmlinux 0xf638b358 ata_dev_pair +EXPORT_SYMBOL_GPL vmlinux 0xf7f8ebb6 pci_unblock_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0xf82b2c98 usb_get_from_anchor +EXPORT_SYMBOL_GPL vmlinux 0xf863e82a flush_work +EXPORT_SYMBOL_GPL vmlinux 0xf8802492 print_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0xf8f3a0fb ata_ratelimit +EXPORT_SYMBOL_GPL vmlinux 0xf97e6de6 fat_alloc_new_dir +EXPORT_SYMBOL_GPL vmlinux 0xf99033c8 usb_remove_hcd +EXPORT_SYMBOL_GPL vmlinux 0xf99995e3 debugfs_remove_recursive +EXPORT_SYMBOL_GPL vmlinux 0xf9a054b5 __round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0xf9ad18ae bdi_writeout_inc +EXPORT_SYMBOL_GPL vmlinux 0xf9ca3160 ata_id_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xf9d1164c rpc_free +EXPORT_SYMBOL_GPL vmlinux 0xf9d7a49e ata_link_abort +EXPORT_SYMBOL_GPL vmlinux 0xfa410fc6 ata_base_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xfaddb0f7 sk_setup_caps +EXPORT_SYMBOL_GPL vmlinux 0xfb586e4c tty_get_pgrp +EXPORT_SYMBOL_GPL vmlinux 0xfb722d73 usb_set_interface +EXPORT_SYMBOL_GPL vmlinux 0xfb88d906 hidinput_connect +EXPORT_SYMBOL_GPL vmlinux 0xfb969556 sdev_evt_send_simple +EXPORT_SYMBOL_GPL vmlinux 0xfbf9be5d register_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xfc314def usb_ifnum_to_if +EXPORT_SYMBOL_GPL vmlinux 0xfcf29b93 rpcauth_init_cred +EXPORT_SYMBOL_GPL vmlinux 0xfd027438 sysctl_pathname +EXPORT_SYMBOL_GPL vmlinux 0xfd106104 ata_sff_dumb_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0xfd9f8f15 ide_read_bcount_and_ireason +EXPORT_SYMBOL_GPL vmlinux 0xfdbc01c3 usb_sg_cancel +EXPORT_SYMBOL_GPL vmlinux 0xfdcd46e0 blk_insert_cloned_request +EXPORT_SYMBOL_GPL vmlinux 0xfdd3a359 regulator_get_voltage +EXPORT_SYMBOL_GPL vmlinux 0xfdefa347 inet_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0xfe3a2ca0 led_classdev_register +EXPORT_SYMBOL_GPL vmlinux 0xfe974c2c nf_unregister_queue_handlers +EXPORT_SYMBOL_GPL vmlinux 0xfe987883 kobject_uevent_env +EXPORT_SYMBOL_GPL vmlinux 0xfe990052 gpio_free +EXPORT_SYMBOL_GPL vmlinux 0xfeb9fc14 ide_devset_execute +EXPORT_SYMBOL_GPL vmlinux 0xfebf3a0f ata_bmdma_stop +EXPORT_SYMBOL_GPL vmlinux 0xfecbff96 __mark_empty_function +EXPORT_SYMBOL_GPL vmlinux 0xfed11ed1 usb_mon_deregister +EXPORT_SYMBOL_GPL vmlinux 0xff5fb4fc ata_host_init +EXPORT_SYMBOL_GPL vmlinux 0xff772def scsi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xffaf7bbb __wake_up_sync --- linux-2.6.28.orig/debian/abi/2.6.28-11.41/armel/imx51.modules +++ linux-2.6.28/debian/abi/2.6.28-11.41/armel/imx51.modules @@ -0,0 +1,749 @@ +8021q +act200l-sir +act_gact +act_ipt +actisys-sir +act_mirred +act_nat +act_pedit +act_police +act_simple +act_skbedit +adutux +aes_generic +af9013 +af_key +af-rxrpc +ah4 +ah6 +aircable +ansi_cprng +anubis +aoe +appledisplay +appleir +appletouch +arc4 +ark3116 +arptable_filter +arp_tables +arpt_mangle +asix +async_memcpy +async_tx +async_xor +atkbd +aufs +authenc +auth_rpcgss +autofs4 +b2c2-flexcop +b2c2-flexcop-usb +bcm203x +bcm3510 +bcm5974 +belkin_sa +berry_charge +bfusb +binfmt_aout +binfmt_misc +blowfish +bluetooth +bnep +bonding +bpa10x +bridge +bsd_comp +btsdio +btusb +camellia +cast5 +cast6 +catc +cbc +ccm +cdc-acm +cdc_ether +cdc_subset +cdc-wdm +cdrom +cfg80211 +ch +ch341 +cifs +cls_basic +cls_flow +cls_fw +cls_route +cls_rsvp +cls_rsvp6 +cls_tcindex +cls_u32 +commandir +compat_ioctl32 +compcache +configfs +cp2101 +cpufreq_ondemand +cpufreq_powersave +cpufreq_userspace +crc32c +crc7 +crc-ccitt +crc-itu-t +cryptd +cryptoloop +crypto_null +cs53l32a +ctr +cts +cx22700 +cx22702 +cx2341x +cx24110 +cx24116 +cx24123 +cx25840 +cyberjack +cypress_cy7c63 +cypress_m8 +cytherm +dabusb +dccp +dccp_ccid2 +dccp_ccid3 +dccp_diag +dccp_ipv4 +dccp_ipv6 +dccp_tfrc_lib +deflate +dib0070 +dib3000mb +dib3000mc +dib7000m +dib7000p +dibx000_common +digi_acceleport +dlm +dm9601 +dm-bbr +dm-crypt +dm-delay +dm-log +dm-loop +dm-mem-cache +dm-message +dm-mirror +dm-mod +dm-multipath +dm-raid4-5 +dm-region_hash +dm-region-hash +dm-round-robin +dm-snapshot +dm-zero +dsbr100 +dummy +dvb-core +dvb-pll +dvb-ttusb-budget +dvb-usb +dvb-usb-a800 +dvb-usb-af9005 +dvb-usb-af9005-remote +dvb-usb-af9015 +dvb-usb-anysee +dvb-usb-au6610 +dvb-usb-cinergyT2 +dvb-usb-cxusb +dvb-usb-dib0700 +dvb-usb-dibusb-common +dvb-usb-dibusb-mb +dvb-usb-dibusb-mc +dvb-usb-digitv +dvb-usb-dtt200u +dvb-usb-dtv5100 +dvb-usb-dw2102 +dvb-usb-gl861 +dvb-usb-gp8psk +dvb-usb-m920x +dvb-usb-nova-t-usb2 +dvb-usb-opera +dvb-usb-ttusb2 +dvb-usb-umt-010 +dvb-usb-vp702x +dvb-usb-vp7045 +ecb +ecryptfs +eeprom_93cx6 +em28xx +em28xx-alsa +em28xx-dvb +em_cmp +emi26 +emi62 +em_meta +em_nbyte +empeg +em_text +em_u32 +eql +esi-sir +esp4 +esp6 +et61x251 +exportfs +ext4 +faulty +fcrypt +ftdi-elan +ftdi_sio +ftl +funsoft +fuse +gadgetfs +garmin_gps +garp +g_cdc +gcm +g_ether +gf128mul +g_file_storage +girbil-sir +gl620a +g_midi +g_printer +g_serial +gspca_main +hci_uart +hci_vhci +hfs +hfsplus +hid-a4tech +hid-apple +hid-belkin +hid-bright +hid-cherry +hid-chicony +hid-cypress +hid-dell +hid-ezkey +hid-gyration +hid-logitech +hid-microsoft +hid-monterey +hidp +hid-petalynx +hid-pl +hid-samsung +hid-sony +hid-sunplus +hmac +hp4x +hso +idmouse +ifb +inet_diag +inet_lro +inftl +input-polldev +io_edgeport +io_ti +iowarrior +ip6_queue +ip6table_filter +ip6table_mangle +ip6table_raw +ip6_tables +ip6table_security +ip6t_ah +ip6t_eui64 +ip6t_frag +ip6t_hbh +ip6t_hl +ip6t_HL +ip6t_ipv6header +ip6t_LOG +ip6t_mh +ip6t_REJECT +ip6t_rt +ip6_tunnel +ipaq +ipcomp +ipcomp6 +ip_gre +ipip +ipmi_devintf +ipmi_msghandler +ipmi_poweroff +ipmi_si +ipmi_watchdog +ip_queue +iptable_filter +iptable_mangle +iptable_nat +iptable_raw +ip_tables +iptable_security +ipt_addrtype +ipt_ah +ipt_CLUSTERIP +ipt_ecn +ipt_ECN +ipt_LOG +ipt_MASQUERADE +ipt_NETMAP +ipt_REDIRECT +ipt_REJECT +ipt_ttl +ipt_TTL +ipt_ULOG +ipu_prp_enc +ipu_prp_vf_sdc +ipu_prp_vf_sdc_bg +ipu_still +ipv6 +ip_vs +ip_vs_dh +ip_vs_ftp +ip_vs_lblc +ip_vs_lblcr +ip_vs_lc +ip_vs_nq +ip_vs_rr +ip_vs_sed +ip_vs_sh +ip_vs_wlc +ip_vs_wrr +ipw +ipx +ircomm +ir-common +ircomm-tty +irda +irda-usb +ir-kbd-i2c +irlan +irtty-sir +ir-usb +isight_firmware +isl6421 +isofs +isp116x-hcd +itd1000 +iuu_phoenix +jbd2 +jffs2 +jfs +kaweth +keyspan +keyspan_pda +khazad +kingsun-sir +kl5kusb105 +kobil_sct +ks959-sir +ksdazzle-sir +l2cap +ldusb +legousbtower +lgdt330x +libcrc32c +libertas +libertas_sdio +libertas_tf +libertas_tf_usb +libphy +libps2 +linear +lirc_atiusb +lirc_bt829 +lirc_cmdir +lirc_dev +lirc_i2c +lirc_igorplugusb +lirc_imon +lirc_it87 +lirc_mceusb +lirc_mceusb2 +lirc_sasem +lirc_serial +lirc_serial_igor +lirc_sir +lirc_streamzap +lirc_ttusbir +litelink-sir +llc +lnbp21 +lockd +lrw +lzo +lzo_compress +lzo_decompress +ma600-sir +mac80211 +macvlan +mcp2120-sir +mcs7780 +mcs7830 +mct_u232 +md4 +mdc800 +md-mod +michael_mic +microtek +mip6 +mos7720 +mos7840 +moto_modem +mousedev +msp3400 +mt312 +mt352 +mtdoops +multipath +mxc_v4l2_capture +mxc_v4l2_output +mxc_w1 +navman +nbd +net1080 +netconsole +nf_conntrack +nf_conntrack_amanda +nf_conntrack_ftp +nf_conntrack_h323 +nf_conntrack_ipv4 +nf_conntrack_ipv6 +nf_conntrack_irc +nf_conntrack_netbios_ns +nf_conntrack_netlink +nf_conntrack_pptp +nf_conntrack_proto_dccp +nf_conntrack_proto_gre +nf_conntrack_proto_sctp +nf_conntrack_proto_udplite +nf_conntrack_sane +nf_conntrack_sip +nf_conntrack_tftp +nf_defrag_ipv4 +nf_nat +nf_nat_amanda +nf_nat_ftp +nf_nat_h323 +nf_nat_irc +nf_nat_pptp +nf_nat_proto_dccp +nf_nat_proto_gre +nf_nat_proto_sctp +nf_nat_proto_udplite +nf_nat_sip +nf_nat_snmp_basic +nf_nat_tftp +nfnetlink +nfnetlink_log +nfnetlink_queue +nfs +nfs_acl +nfsd +nftl +nls_ascii +nls_cp1250 +nls_cp1251 +nls_cp1255 +nls_cp737 +nls_cp775 +nls_cp850 +nls_cp852 +nls_cp855 +nls_cp857 +nls_cp860 +nls_cp861 +nls_cp862 +nls_cp863 +nls_cp864 +nls_cp865 +nls_cp866 +nls_cp869 +nls_cp874 +nls_cp932 +nls_cp936 +nls_cp949 +nls_cp950 +nls_euc-jp +nls_iso8859-13 +nls_iso8859-14 +nls_iso8859-15 +nls_iso8859-2 +nls_iso8859-3 +nls_iso8859-4 +nls_iso8859-5 +nls_iso8859-6 +nls_iso8859-7 +nls_iso8859-9 +nls_koi8-r +nls_koi8-ru +nls_koi8-u +ntfs +nxt200x +nxt6000 +old_belkin-sir +omninet +onenand +oprofile +option +oti6858 +ov3640_camera +p8022 +p8023 +pata_platform +pcbc +pegasus +phidget +phidgetkit +phidgetmotorcontrol +phidgetservo +pktcdvd +pl2303 +plusb +ppp_async +ppp_deflate +ppp_generic +ppp_mppe +pppoe +pppol2tp +pppox +ppp_synctty +psnap +pvrusb2 +quickcam +r8a66597-hcd +radio-mr800 +radio-si470x +raid0 +raid1 +raid10 +raid456 +raid_class +reiserfs +rfcomm +rfd_ftl +rfkill +rfkill-input +rio500 +rmd128 +rmd160 +rmd256 +rmd320 +rndis_host +rpcsec_gss_krb5 +rpcsec_gss_spkm3 +rt2500usb +rt2x00lib +rt2x00usb +rt73usb +rtl8150 +rtl8187 +rxkad +s2255drv +s5h1409 +s5h1411 +s5h1420 +saa7115 +safe_serial +salsa20_generic +sch_cbq +sch_dsmark +sch_gred +sch_hfsc +sch_htb +sch_multiq +sch_netem +sch_prio +sch_red +sch_sfq +sch_tbf +sch_teql +sco +scsi_tgt +scsi_wait_scan +sctp +seed +seqiv +serio +serpent +serport +sg +sha1_generic +sha256_generic +sha512_generic +si21xx +sierra +sir-dev +sisusbvga +sit +sl811-hcd +slhc +slip +sms1xxx +smsc95xx +sn9c102 +snd-dummy +snd-mixer-oss +snd-mpu401 +snd-mpu401-uart +snd-mtpav +snd-pcm-oss +snd-rawmidi +snd-seq +snd-seq-device +snd-seq-midi +snd-seq-midi-event +snd-seq-virmidi +snd-serial-u16550 +snd-spdif +snd-virmidi +spcp8x5 +squashfs +sr_mod +ssfdc +st +stb6000 +stir4200 +stkwebcam +stp +stv0288 +stv0297 +stv0299 +sunrpc +tcp_bic +tcp_diag +tcp_htcp +tcp_westwood +tda10023 +tda10048 +tda1004x +tda10086 +tda18271 +tda8083 +tda826x +tda827x +tda8290 +tea +tekram-sir +tgr192 +tipc +ti_usb_3410_5052 +tlsf +toim3232-sir +trancevibrator +ts_bm +ts_fsm +ts_kmp +ttusb_dec +ttusbdecfe +tun +tuner +tunnel4 +tunnel6 +tveeprom +tvp5150 +twofish +twofish_common +u132-hcd +ub +ubi +ubifs +udf +unifi_fs +unionfs +usb8xxx +usb_debug +usblcd +usbled +usblp +usbnet +usbserial +usbsevseg +usbtest +usbtmc +usbvision +uvcvideo +v4l1-compat +v4l2-common +v4l2-int-device +ves1820 +veth +videobuf-core +videobuf-dvb +videobuf-vmalloc +videodev +visor +vstusb +whiteheat +wire +wm8775 +wp512 +xcbc +xfrm4_mode_beet +xfrm4_mode_transport +xfrm4_mode_tunnel +xfrm4_tunnel +xfrm6_mode_beet +xfrm6_mode_ro +xfrm6_mode_transport +xfrm6_mode_tunnel +xfrm6_tunnel +xfrm_ipcomp +xfrm_user +xfs +xor +x_tables +xt_CLASSIFY +xt_comment +xt_connbytes +xt_connlimit +xt_connmark +xt_CONNMARK +xt_CONNSECMARK +xt_conntrack +xt_dccp +xt_dscp +xt_esp +xt_hashlimit +xt_helper +xt_iprange +xt_length +xt_limit +xt_mac +xt_mark +xt_MARK +xt_multiport +xt_NFLOG +xt_NFQUEUE +xt_owner +xt_pkttype +xt_policy +xt_quota +xt_rateest +xt_RATEEST +xt_realm +xt_recent +xts +xt_sctp +xt_SECMARK +xt_state +xt_statistic +xt_string +xt_tcpmss +xt_TCPMSS +xt_tcpudp +xt_time +xt_u32 +zaurus +zc0301 +zd1201 +zd1211rw +zl10353 +zlib_deflate +zr364xx --- linux-2.6.28.orig/debian/abi/2.6.28-11.41/armel/ixp4xx +++ linux-2.6.28/debian/abi/2.6.28-11.41/armel/ixp4xx @@ -0,0 +1,4740 @@ +EXPORT_SYMBOL crypto/gf128mul 0x0c2f123f gf128mul_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x1068004b gf128mul_bbe +EXPORT_SYMBOL crypto/gf128mul 0x2f2889a0 gf128mul_init_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0x3755f990 gf128mul_init_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x384ef9ce gf128mul_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x56af0dbd gf128mul_x_ble +EXPORT_SYMBOL crypto/gf128mul 0x83581089 gf128mul_init_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0x9b2560b9 gf128mul_init_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x9e13f6f6 gf128mul_lle +EXPORT_SYMBOL crypto/gf128mul 0xbd17a0df gf128mul_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0xc0890413 gf128mul_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0xd60736ec gf128mul_free_64k +EXPORT_SYMBOL crypto/xor 0x5b6c00e6 xor_blocks +EXPORT_SYMBOL drivers/block/loop 0x3bfe523a loop_register_transfer +EXPORT_SYMBOL drivers/block/loop 0xbfee3ad5 loop_unregister_transfer +EXPORT_SYMBOL drivers/hwmon/hwmon-vid 0x0903c239 vid_from_reg +EXPORT_SYMBOL drivers/hwmon/hwmon-vid 0xef1c781c vid_which_vrm +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0x50462a18 i2c_bit_add_numbered_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0x538e0b9d i2c_bit_add_bus +EXPORT_SYMBOL drivers/i2c/i2c-core 0x02ad50ba i2c_master_send +EXPORT_SYMBOL drivers/i2c/i2c-core 0x03bbdeee i2c_smbus_write_byte_data +EXPORT_SYMBOL drivers/i2c/i2c-core 0x0962ac12 i2c_register_driver +EXPORT_SYMBOL drivers/i2c/i2c-core 0x19391695 i2c_smbus_read_byte_data +EXPORT_SYMBOL drivers/i2c/i2c-core 0x1bb06ad3 i2c_clients_command +EXPORT_SYMBOL drivers/i2c/i2c-core 0x1bb9e521 i2c_del_driver +EXPORT_SYMBOL drivers/i2c/i2c-core 0x21d990e2 i2c_use_client +EXPORT_SYMBOL drivers/i2c/i2c-core 0x353c71dd i2c_smbus_read_byte +EXPORT_SYMBOL drivers/i2c/i2c-core 0x37b7fbbd i2c_smbus_write_block_data +EXPORT_SYMBOL drivers/i2c/i2c-core 0x41b6f8d3 i2c_verify_client +EXPORT_SYMBOL drivers/i2c/i2c-core 0x496bdc9b i2c_smbus_read_word_data +EXPORT_SYMBOL drivers/i2c/i2c-core 0x4aea0889 i2c_put_adapter +EXPORT_SYMBOL drivers/i2c/i2c-core 0x4ce03f17 i2c_del_adapter +EXPORT_SYMBOL drivers/i2c/i2c-core 0x4da5ac5f i2c_master_recv +EXPORT_SYMBOL drivers/i2c/i2c-core 0x52fabe67 i2c_add_adapter +EXPORT_SYMBOL drivers/i2c/i2c-core 0x5b1fe028 i2c_detach_client +EXPORT_SYMBOL drivers/i2c/i2c-core 0x5f9573b4 i2c_smbus_xfer +EXPORT_SYMBOL drivers/i2c/i2c-core 0x67e967f7 i2c_probe +EXPORT_SYMBOL drivers/i2c/i2c-core 0x6f97f756 i2c_smbus_read_i2c_block_data +EXPORT_SYMBOL drivers/i2c/i2c-core 0x798085dc i2c_transfer +EXPORT_SYMBOL drivers/i2c/i2c-core 0x82ea6f16 i2c_smbus_read_block_data +EXPORT_SYMBOL drivers/i2c/i2c-core 0x9cbb2983 i2c_smbus_write_word_data +EXPORT_SYMBOL drivers/i2c/i2c-core 0xa125e0c2 i2c_smbus_write_i2c_block_data +EXPORT_SYMBOL drivers/i2c/i2c-core 0xcdb4ee24 i2c_release_client +EXPORT_SYMBOL drivers/i2c/i2c-core 0xe1c34467 i2c_get_adapter +EXPORT_SYMBOL drivers/i2c/i2c-core 0xee27cc41 i2c_smbus_write_byte +EXPORT_SYMBOL drivers/i2c/i2c-core 0xf40dc661 i2c_attach_client +EXPORT_SYMBOL drivers/i2c/i2c-core 0xf6636ec4 i2c_smbus_process_call +EXPORT_SYMBOL drivers/input/serio/libps2 0x2e4c4d27 ps2_handle_ack +EXPORT_SYMBOL drivers/input/serio/libps2 0x4cc97a0a ps2_init +EXPORT_SYMBOL drivers/input/serio/libps2 0x94821960 ps2_sendbyte +EXPORT_SYMBOL drivers/input/serio/libps2 0x9994c0ca ps2_is_keyboard_id +EXPORT_SYMBOL drivers/input/serio/libps2 0x9a5fdec0 ps2_cmd_aborted +EXPORT_SYMBOL drivers/input/serio/libps2 0xdeaf7e21 ps2_handle_response +EXPORT_SYMBOL drivers/input/serio/libps2 0xe3c6d82b ps2_command +EXPORT_SYMBOL drivers/input/serio/libps2 0xfd52e3b9 ps2_drain +EXPORT_SYMBOL drivers/input/serio/serio 0x0bf6433d serio_interrupt +EXPORT_SYMBOL drivers/input/serio/serio 0x418b28a1 serio_unregister_child_port +EXPORT_SYMBOL drivers/input/serio/serio 0x43c012c3 __serio_register_driver +EXPORT_SYMBOL drivers/input/serio/serio 0x53322278 serio_open +EXPORT_SYMBOL drivers/input/serio/serio 0x5d178525 __serio_register_port +EXPORT_SYMBOL drivers/input/serio/serio 0x6d448d03 serio_unregister_driver +EXPORT_SYMBOL drivers/input/serio/serio 0x6f3d2a42 serio_rescan +EXPORT_SYMBOL drivers/input/serio/serio 0x8983b5b1 serio_close +EXPORT_SYMBOL drivers/input/serio/serio 0xb576bbb7 serio_reconnect +EXPORT_SYMBOL drivers/input/serio/serio 0xe654a42f serio_unregister_port +EXPORT_SYMBOL drivers/md/dm-log 0x078bc77a dm_dirty_log_type_unregister +EXPORT_SYMBOL drivers/md/dm-log 0x38beb8cd dm_dirty_log_destroy +EXPORT_SYMBOL drivers/md/dm-log 0x4175e9e5 dm_dirty_log_type_register +EXPORT_SYMBOL drivers/md/dm-log 0x95cd3f07 dm_dirty_log_create +EXPORT_SYMBOL drivers/md/dm-mod 0x0ad60133 dm_kcopyd_copy +EXPORT_SYMBOL drivers/md/dm-mod 0x1e6dc6bf dm_table_get_mode +EXPORT_SYMBOL drivers/md/dm-mod 0x3c51719e dm_kcopyd_client_destroy +EXPORT_SYMBOL drivers/md/dm-mod 0x408a8fde dm_table_event +EXPORT_SYMBOL drivers/md/dm-mod 0x53958d61 dm_io_client_destroy +EXPORT_SYMBOL drivers/md/dm-mod 0x5bcf6823 dm_table_get_size +EXPORT_SYMBOL drivers/md/dm-mod 0x76ca9817 dm_io_client_resize +EXPORT_SYMBOL drivers/md/dm-mod 0x8346a1ac dm_io_client_create +EXPORT_SYMBOL drivers/md/dm-mod 0x8a5248b3 dm_kcopyd_client_create +EXPORT_SYMBOL drivers/md/dm-mod 0x9705f513 dm_put_device +EXPORT_SYMBOL drivers/md/dm-mod 0x9bf30629 dm_table_put +EXPORT_SYMBOL drivers/md/dm-mod 0x9dd6aebf dm_get_device +EXPORT_SYMBOL drivers/md/dm-mod 0xab668c4b dm_io +EXPORT_SYMBOL drivers/md/dm-mod 0xb7cc9edf dm_table_get +EXPORT_SYMBOL drivers/md/dm-mod 0xc79bcd36 dm_vcalloc +EXPORT_SYMBOL drivers/md/dm-mod 0xd25edde3 dm_table_unplug_all +EXPORT_SYMBOL drivers/md/dm-mod 0xd30003af dm_table_get_md +EXPORT_SYMBOL drivers/md/dm-mod 0xd4e2d0a0 dm_unregister_target +EXPORT_SYMBOL drivers/md/dm-mod 0xddf0bdc0 dm_register_target +EXPORT_SYMBOL drivers/md/dm-mod 0xed2593ef dm_get_mapinfo +EXPORT_SYMBOL drivers/md/md-mod 0x0f12841a register_md_personality +EXPORT_SYMBOL drivers/md/md-mod 0x165705d0 md_wakeup_thread +EXPORT_SYMBOL drivers/md/md-mod 0x218cd0e6 bitmap_endwrite +EXPORT_SYMBOL drivers/md/md-mod 0x2b832056 bitmap_unplug +EXPORT_SYMBOL drivers/md/md-mod 0x3703d8f4 md_done_sync +EXPORT_SYMBOL drivers/md/md-mod 0x3c1298ab md_wait_for_blocked_rdev +EXPORT_SYMBOL drivers/md/md-mod 0x41d19aa5 bitmap_start_sync +EXPORT_SYMBOL drivers/md/md-mod 0x5b80b820 bitmap_end_sync +EXPORT_SYMBOL drivers/md/md-mod 0x6228a2d4 md_write_end +EXPORT_SYMBOL drivers/md/md-mod 0x664db0db bitmap_startwrite +EXPORT_SYMBOL drivers/md/md-mod 0x7a75feda md_unregister_thread +EXPORT_SYMBOL drivers/md/md-mod 0x87f7c8f5 md_register_thread +EXPORT_SYMBOL drivers/md/md-mod 0x9483a389 unregister_md_personality +EXPORT_SYMBOL drivers/md/md-mod 0x9eb422dc md_check_recovery +EXPORT_SYMBOL drivers/md/md-mod 0xabe5862c md_error +EXPORT_SYMBOL drivers/md/md-mod 0xc3d3be32 bitmap_close_sync +EXPORT_SYMBOL drivers/md/md-mod 0xdca08919 md_write_start +EXPORT_SYMBOL drivers/md/md-mod 0xe9c9127d bitmap_cond_end_sync +EXPORT_SYMBOL drivers/misc/tifm_core 0x17d421ca tifm_queue_work +EXPORT_SYMBOL drivers/misc/tifm_core 0x22a59850 tifm_map_sg +EXPORT_SYMBOL drivers/misc/tifm_core 0x2da4ff2e tifm_has_ms_pif +EXPORT_SYMBOL drivers/misc/tifm_core 0x306c9158 tifm_free_device +EXPORT_SYMBOL drivers/misc/tifm_core 0x3f1e6557 tifm_register_driver +EXPORT_SYMBOL drivers/misc/tifm_core 0x4a06503e tifm_eject +EXPORT_SYMBOL drivers/misc/tifm_core 0x56a7e070 tifm_add_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0x7ba36442 tifm_remove_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0x92db0b8c tifm_alloc_device +EXPORT_SYMBOL drivers/misc/tifm_core 0xa49e37ca tifm_unregister_driver +EXPORT_SYMBOL drivers/misc/tifm_core 0xb027932a tifm_free_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0xb270335e tifm_alloc_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0xb3f6c41c tifm_unmap_sg +EXPORT_SYMBOL drivers/mmc/card/mmc_block 0x4238e95d mmc_cleanup_queue +EXPORT_SYMBOL drivers/mmc/core/mmc_core 0x11d12a36 mmc_align_data_size +EXPORT_SYMBOL drivers/mmc/core/mmc_core 0x62edab79 mmc_remove_host +EXPORT_SYMBOL drivers/mmc/core/mmc_core 0x72506820 mmc_add_host +EXPORT_SYMBOL drivers/mmc/core/mmc_core 0x7cc49d87 mmc_register_driver +EXPORT_SYMBOL drivers/mmc/core/mmc_core 0x7e8a8525 mmc_alloc_host +EXPORT_SYMBOL drivers/mmc/core/mmc_core 0x8da196a0 mmc_request_done +EXPORT_SYMBOL drivers/mmc/core/mmc_core 0x90721439 mmc_wait_for_req +EXPORT_SYMBOL drivers/mmc/core/mmc_core 0xa4348d0e mmc_wait_for_app_cmd +EXPORT_SYMBOL drivers/mmc/core/mmc_core 0xa5ce2a2e mmc_set_data_timeout +EXPORT_SYMBOL drivers/mmc/core/mmc_core 0xa8d32548 mmc_free_host +EXPORT_SYMBOL drivers/mmc/core/mmc_core 0xafd4791e mmc_wait_for_cmd +EXPORT_SYMBOL drivers/mmc/core/mmc_core 0xc225f6af mmc_release_host +EXPORT_SYMBOL drivers/mmc/core/mmc_core 0xce85efd9 mmc_unregister_driver +EXPORT_SYMBOL drivers/mmc/core/mmc_core 0xe8fa2fc2 mmc_detect_change +EXPORT_SYMBOL drivers/mmc/core/mmc_core 0xebdc15d3 __mmc_claim_host +EXPORT_SYMBOL drivers/mtd/nand/nand 0x2f5536fa nand_scan_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand 0x3650630c nand_default_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0x0526ae99 nand_calculate_ecc +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0x75ecd920 nand_correct_data +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0x836bdb72 nand_flash_ids +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0xa336feb7 nand_manuf_ids +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x2f6d0b6a sirdev_raw_read +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x3f6ef74f sirdev_put_instance +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x49e620d2 sirdev_raw_write +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x61e6b3ba irda_unregister_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x6cf8756a irda_register_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x99df6663 sirdev_receive +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xa672a912 sirdev_set_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xf2d3b0eb sirdev_write_complete +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xf692d112 sirdev_set_dtr_rts +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xfb100fa2 sirdev_get_instance +EXPORT_SYMBOL drivers/net/phy/libphy 0x002f4ca9 get_phy_id +EXPORT_SYMBOL drivers/net/phy/libphy 0x085b9282 phy_register_fixup_for_id +EXPORT_SYMBOL drivers/net/phy/libphy 0x089fb5c3 mdiobus_scan +EXPORT_SYMBOL drivers/net/phy/libphy 0x0c8cd52d phy_ethtool_sset +EXPORT_SYMBOL drivers/net/phy/libphy 0x0eb270ac phy_mii_ioctl +EXPORT_SYMBOL drivers/net/phy/libphy 0x1368242d phy_device_create +EXPORT_SYMBOL drivers/net/phy/libphy 0x2702921c phy_register_fixup +EXPORT_SYMBOL drivers/net/phy/libphy 0x37cbac39 genphy_config_aneg +EXPORT_SYMBOL drivers/net/phy/libphy 0x3fc89c2f phy_start_aneg +EXPORT_SYMBOL drivers/net/phy/libphy 0x41d9c51b mdiobus_write +EXPORT_SYMBOL drivers/net/phy/libphy 0x4687102e mdio_bus_type +EXPORT_SYMBOL drivers/net/phy/libphy 0x4d24194a mdiobus_alloc +EXPORT_SYMBOL drivers/net/phy/libphy 0x51fae34a phy_ethtool_gset +EXPORT_SYMBOL drivers/net/phy/libphy 0x55a5949d mdiobus_free +EXPORT_SYMBOL drivers/net/phy/libphy 0x5932f7cd phy_attach +EXPORT_SYMBOL drivers/net/phy/libphy 0x5b1f0576 phy_connect +EXPORT_SYMBOL drivers/net/phy/libphy 0x63e69f4e phy_driver_unregister +EXPORT_SYMBOL drivers/net/phy/libphy 0x7e114bf1 phy_start_interrupts +EXPORT_SYMBOL drivers/net/phy/libphy 0x870766cb phy_stop_interrupts +EXPORT_SYMBOL drivers/net/phy/libphy 0x8d067a13 mdiobus_register +EXPORT_SYMBOL drivers/net/phy/libphy 0x9c101a5d phy_disable_interrupts +EXPORT_SYMBOL drivers/net/phy/libphy 0xa2be8112 mdiobus_read +EXPORT_SYMBOL drivers/net/phy/libphy 0xa3cfa562 genphy_config_advert +EXPORT_SYMBOL drivers/net/phy/libphy 0xab512406 mdiobus_unregister +EXPORT_SYMBOL drivers/net/phy/libphy 0xb483669b phy_sanitize_settings +EXPORT_SYMBOL drivers/net/phy/libphy 0xbb95d644 phy_disconnect +EXPORT_SYMBOL drivers/net/phy/libphy 0xbba18198 phy_start +EXPORT_SYMBOL drivers/net/phy/libphy 0xbd31ccb5 genphy_update_link +EXPORT_SYMBOL drivers/net/phy/libphy 0xc797ec97 phy_driver_register +EXPORT_SYMBOL drivers/net/phy/libphy 0xca744020 phy_scan_fixups +EXPORT_SYMBOL drivers/net/phy/libphy 0xcf4be3d9 phy_stop +EXPORT_SYMBOL drivers/net/phy/libphy 0xd8424376 phy_register_fixup_for_uid +EXPORT_SYMBOL drivers/net/phy/libphy 0xd8aa2eaa genphy_read_status +EXPORT_SYMBOL drivers/net/phy/libphy 0xdc7db336 phy_print_status +EXPORT_SYMBOL drivers/net/phy/libphy 0xecaa1d7c phy_enable_interrupts +EXPORT_SYMBOL drivers/net/phy/libphy 0xee980918 phy_detach +EXPORT_SYMBOL drivers/net/phy/libphy 0xf495b52a genphy_restart_aneg +EXPORT_SYMBOL drivers/net/phy/mdio-bitbang 0xb68cd94d free_mdio_bitbang +EXPORT_SYMBOL drivers/net/phy/mdio-bitbang 0xe3bd33ec alloc_mdio_bitbang +EXPORT_SYMBOL drivers/net/ppp_generic 0x008802c0 ppp_register_compressor +EXPORT_SYMBOL drivers/net/ppp_generic 0x21512ecc ppp_output_wakeup +EXPORT_SYMBOL drivers/net/ppp_generic 0x4687f631 ppp_input +EXPORT_SYMBOL drivers/net/ppp_generic 0x48c5ba7b ppp_unit_number +EXPORT_SYMBOL drivers/net/ppp_generic 0x5e260ee3 ppp_register_channel +EXPORT_SYMBOL drivers/net/ppp_generic 0x8b702d1b ppp_unregister_compressor +EXPORT_SYMBOL drivers/net/ppp_generic 0x9346b3d0 ppp_input_error +EXPORT_SYMBOL drivers/net/ppp_generic 0xa91a5ce8 ppp_unregister_channel +EXPORT_SYMBOL drivers/net/ppp_generic 0xad1ef712 ppp_channel_index +EXPORT_SYMBOL drivers/net/pppox 0x2424e344 register_pppox_proto +EXPORT_SYMBOL drivers/net/pppox 0x3095b00a pppox_unbind_sock +EXPORT_SYMBOL drivers/net/pppox 0xa51aaeb1 pppox_ioctl +EXPORT_SYMBOL drivers/net/pppox 0xe0ff7a18 unregister_pppox_proto +EXPORT_SYMBOL drivers/net/slhc 0x0ff2b602 slhc_compress +EXPORT_SYMBOL drivers/net/slhc 0x23c8f257 slhc_uncompress +EXPORT_SYMBOL drivers/net/slhc 0xa63d85ab slhc_remember +EXPORT_SYMBOL drivers/net/slhc 0xb5ca1c46 slhc_free +EXPORT_SYMBOL drivers/net/slhc 0xdfc5169b slhc_init +EXPORT_SYMBOL drivers/net/slhc 0xe8794ce1 slhc_toss +EXPORT_SYMBOL drivers/scsi/raid_class 0x1e11beeb raid_class_attach +EXPORT_SYMBOL drivers/scsi/raid_class 0x337bc7cc raid_class_release +EXPORT_SYMBOL drivers/scsi/raid_class 0x350c9d0e raid_component_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x053c850c fc_vport_terminate +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x0db757fe fc_remote_port_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x1d3f205c fc_remote_port_rolechg +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x71388441 fc_host_post_vendor_event +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x7444f2d8 scsi_is_fc_rport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x790d6e01 fc_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x7954b1ea fc_get_event_number +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x7fc3f7b3 fc_host_post_event +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x84aa147b fc_vport_create +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x8d74629d fc_remove_host +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xec2f65af scsi_is_fc_vport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xedfe0bb7 fc_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xf49017e6 fc_remote_port_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x0336379b sas_port_delete_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x06ee6b15 sas_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x099df89a sas_port_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x0c6221f5 sas_remove_children +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x138e97b0 sas_port_mark_backlink +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x237c00e2 scsi_is_sas_port +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x2f017379 sas_phy_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x3c3c7f31 sas_rphy_remove +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x4d4a7b39 sas_remove_host +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x5fb7a8cf sas_port_alloc_num +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x69a5f33b sas_read_port_mode_page +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x6bead75f sas_phy_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x77ae0d92 sas_phy_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x88af150d sas_port_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x8a81f192 sas_phy_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xa03923c4 scsi_is_sas_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xa043bc84 sas_end_device_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xa65a999e scsi_is_sas_rphy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xb0595503 sas_port_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xb0b1da91 sas_expander_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xc3ad7db7 sas_port_add_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xd6ea0d89 sas_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xe525f9c7 sas_port_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xea6116cc sas_rphy_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xedc872db sas_rphy_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xf7ce03e4 sas_rphy_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x3686ea09 spi_print_msg +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x4b248e38 spi_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x7a0ccd92 spi_schedule_dv_device +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0xc1e4cae8 spi_dv_device +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0xc6178767 spi_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0xe6f5945b spi_display_xfer_agreement +EXPORT_SYMBOL drivers/usb/gadget/pxa25x_udc 0x35cbd33c usb_gadget_unregister_driver +EXPORT_SYMBOL drivers/usb/gadget/pxa25x_udc 0x43e631b6 usb_gadget_register_driver +EXPORT_SYMBOL drivers/usb/serial/usbserial 0x4d29ee27 usb_serial_suspend +EXPORT_SYMBOL drivers/usb/serial/usbserial 0x5c69238f usb_serial_resume +EXPORT_SYMBOL drivers/video/backlight/backlight 0x29f6e8f4 backlight_device_unregister +EXPORT_SYMBOL drivers/video/backlight/backlight 0x6d267599 backlight_device_register +EXPORT_SYMBOL drivers/video/backlight/lcd 0x29ea6cef lcd_device_register +EXPORT_SYMBOL drivers/video/backlight/lcd 0x8f2fdc4b lcd_device_unregister +EXPORT_SYMBOL drivers/video/console/font 0x09c8eb55 font_vga_8x16 +EXPORT_SYMBOL drivers/video/console/font 0xbb99125c get_default_font +EXPORT_SYMBOL drivers/video/console/font 0xf7584a9c find_font +EXPORT_SYMBOL drivers/w1/slaves/w1_bq27000 0x2c1c57f6 w1_bq27000_write +EXPORT_SYMBOL drivers/w1/slaves/w1_bq27000 0x85b92110 w1_bq27000_read +EXPORT_SYMBOL drivers/w1/slaves/w1_ds2760 0x393dc38f w1_ds2760_read +EXPORT_SYMBOL drivers/w1/slaves/w1_ds2760 0xafced5ab w1_ds2760_write +EXPORT_SYMBOL drivers/w1/wire 0x0914ebde w1_remove_master_device +EXPORT_SYMBOL drivers/w1/wire 0x33c5189a w1_add_master_device +EXPORT_SYMBOL drivers/w1/wire 0xb5d92be4 w1_unregister_family +EXPORT_SYMBOL drivers/w1/wire 0xd27cbcea w1_register_family +EXPORT_SYMBOL fs/configfs/configfs 0x14e7ae9b config_item_put +EXPORT_SYMBOL fs/configfs/configfs 0x47f044ef config_item_get +EXPORT_SYMBOL fs/configfs/configfs 0x4c5c2418 config_group_init +EXPORT_SYMBOL fs/configfs/configfs 0x4e1bd884 configfs_depend_item +EXPORT_SYMBOL fs/configfs/configfs 0x511f236a config_group_find_item +EXPORT_SYMBOL fs/configfs/configfs 0x8da85700 configfs_register_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0x910ab07a configfs_undepend_item +EXPORT_SYMBOL fs/configfs/configfs 0x9280001c config_item_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0xb265bc45 config_item_init +EXPORT_SYMBOL fs/configfs/configfs 0xcb3bbec6 configfs_unregister_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0xcbc3d46f config_group_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0xff593592 config_item_set_name +EXPORT_SYMBOL fs/jbd2/jbd2 0x0258ab7c jbd2_log_wait_commit +EXPORT_SYMBOL fs/jbd2/jbd2 0x10515f19 jbd2_journal_stop +EXPORT_SYMBOL fs/jbd2/jbd2 0x1e6ef8f3 jbd2_journal_errno +EXPORT_SYMBOL fs/jbd2/jbd2 0x2368d159 jbd2_journal_blocks_per_page +EXPORT_SYMBOL fs/jbd2/jbd2 0x3a9d65d2 jbd2_journal_get_undo_access +EXPORT_SYMBOL fs/jbd2/jbd2 0x451ad4bc jbd2_journal_abort +EXPORT_SYMBOL fs/jbd2/jbd2 0x46bdffe5 jbd2_journal_init_dev +EXPORT_SYMBOL fs/jbd2/jbd2 0x5074917f jbd2_journal_lock_updates +EXPORT_SYMBOL fs/jbd2/jbd2 0x50dca468 jbd2_journal_check_used_features +EXPORT_SYMBOL fs/jbd2/jbd2 0x60a40dd0 jbd2_journal_file_inode +EXPORT_SYMBOL fs/jbd2/jbd2 0x66303740 jbd2_journal_begin_ordered_truncate +EXPORT_SYMBOL fs/jbd2/jbd2 0x74d2469d jbd2_journal_check_available_features +EXPORT_SYMBOL fs/jbd2/jbd2 0x7acfe840 jbd2_journal_flush +EXPORT_SYMBOL fs/jbd2/jbd2 0x7e9bb8ac jbd2_journal_revoke +EXPORT_SYMBOL fs/jbd2/jbd2 0x813f3eea jbd2_journal_init_jbd_inode +EXPORT_SYMBOL fs/jbd2/jbd2 0x82fcffde jbd2_journal_destroy +EXPORT_SYMBOL fs/jbd2/jbd2 0x88ec5e6e jbd2_journal_update_format +EXPORT_SYMBOL fs/jbd2/jbd2 0x892e2b1d jbd2_journal_load +EXPORT_SYMBOL fs/jbd2/jbd2 0x936714d7 jbd2_journal_extend +EXPORT_SYMBOL fs/jbd2/jbd2 0x974359e9 jbd2_journal_force_commit +EXPORT_SYMBOL fs/jbd2/jbd2 0x9a5b2179 jbd2_journal_clear_features +EXPORT_SYMBOL fs/jbd2/jbd2 0xa3a57a15 jbd2_journal_create +EXPORT_SYMBOL fs/jbd2/jbd2 0xb06b4053 jbd2_journal_try_to_free_buffers +EXPORT_SYMBOL fs/jbd2/jbd2 0xbcd4d131 jbd2_journal_get_write_access +EXPORT_SYMBOL fs/jbd2/jbd2 0xbda6f044 jbd2_journal_wipe +EXPORT_SYMBOL fs/jbd2/jbd2 0xbf50a226 jbd2_journal_restart +EXPORT_SYMBOL fs/jbd2/jbd2 0xc6c34561 jbd2_journal_unlock_updates +EXPORT_SYMBOL fs/jbd2/jbd2 0xce6f1e1a jbd2_journal_set_features +EXPORT_SYMBOL fs/jbd2/jbd2 0xd334b111 jbd2_journal_get_create_access +EXPORT_SYMBOL fs/jbd2/jbd2 0xd52e9395 jbd2_journal_start_commit +EXPORT_SYMBOL fs/jbd2/jbd2 0xd770c61d jbd2_journal_release_buffer +EXPORT_SYMBOL fs/jbd2/jbd2 0xdcd821bc jbd2_journal_ack_err +EXPORT_SYMBOL fs/jbd2/jbd2 0xde18bca0 jbd2_journal_dirty_metadata +EXPORT_SYMBOL fs/jbd2/jbd2 0xe0d7e930 jbd2_journal_release_jbd_inode +EXPORT_SYMBOL fs/jbd2/jbd2 0xe6fad598 jbd2_journal_start +EXPORT_SYMBOL fs/jbd2/jbd2 0xeb799064 jbd2_journal_force_commit_nested +EXPORT_SYMBOL fs/jbd2/jbd2 0xed6940c7 jbd2_journal_forget +EXPORT_SYMBOL fs/jbd2/jbd2 0xf9db7f39 jbd2_journal_init_inode +EXPORT_SYMBOL fs/jbd2/jbd2 0xfa6b1631 jbd2_journal_clear_err +EXPORT_SYMBOL fs/jbd2/jbd2 0xfb2bdb20 jbd2_journal_invalidatepage +EXPORT_SYMBOL fs/lockd/lockd 0x4252ec81 nlmsvc_ops +EXPORT_SYMBOL fs/lockd/lockd 0xa7b91a7b lockd_down +EXPORT_SYMBOL fs/lockd/lockd 0xf6933c48 lockd_up +EXPORT_SYMBOL fs/nls/nls_base 0x01b76d39 unregister_nls +EXPORT_SYMBOL fs/nls/nls_base 0x03dfa9a6 unload_nls +EXPORT_SYMBOL fs/nls/nls_base 0x4ddc4b9f utf8_mbtowc +EXPORT_SYMBOL fs/nls/nls_base 0x77a76ef1 load_nls +EXPORT_SYMBOL fs/nls/nls_base 0x7d850612 utf8_mbstowcs +EXPORT_SYMBOL fs/nls/nls_base 0x863cb91a utf8_wcstombs +EXPORT_SYMBOL fs/nls/nls_base 0xa2028155 register_nls +EXPORT_SYMBOL fs/nls/nls_base 0xc25232a3 load_nls_default +EXPORT_SYMBOL fs/nls/nls_base 0xf82f1109 utf8_wctomb +EXPORT_SYMBOL fs/xfs/xfs 0xcdc2a741 xfs_qmcore_xfs +EXPORT_SYMBOL lib/crc-ccitt 0x3771b461 crc_ccitt +EXPORT_SYMBOL lib/crc-ccitt 0x75811312 crc_ccitt_table +EXPORT_SYMBOL lib/crc-itu-t 0xd29b009f crc_itu_t_table +EXPORT_SYMBOL lib/crc-itu-t 0xf5b4a948 crc_itu_t +EXPORT_SYMBOL lib/crc-t10dif 0xb6896671 crc_t10dif +EXPORT_SYMBOL lib/crc16 0x02a6ce5a crc16_table +EXPORT_SYMBOL lib/crc16 0x8ffdb3b8 crc16 +EXPORT_SYMBOL lib/libcrc32c 0x2329b292 crc32c_be +EXPORT_SYMBOL lib/libcrc32c 0x37d0b921 crc32c_le +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0x315c65fd zlib_deflateInit2 +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0x48034724 zlib_deflateReset +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xaf64ad0d zlib_deflate +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xf0caf44b zlib_deflate_workspacesize +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xf741c793 zlib_deflateEnd +EXPORT_SYMBOL lib/zlib_inflate/zlib_inflate 0x3ed63055 zlib_inflateReset +EXPORT_SYMBOL lib/zlib_inflate/zlib_inflate 0x4211c3c1 zlib_inflateInit2 +EXPORT_SYMBOL lib/zlib_inflate/zlib_inflate 0x65408378 zlib_inflate_blob +EXPORT_SYMBOL lib/zlib_inflate/zlib_inflate 0x668da8d5 zlib_inflateIncomp +EXPORT_SYMBOL lib/zlib_inflate/zlib_inflate 0x77ecac9f zlib_inflateEnd +EXPORT_SYMBOL lib/zlib_inflate/zlib_inflate 0x881039d0 zlib_inflate +EXPORT_SYMBOL lib/zlib_inflate/zlib_inflate 0xce5ac24f zlib_inflate_workspacesize +EXPORT_SYMBOL net/802/p8022 0x919cde48 register_8022_client +EXPORT_SYMBOL net/802/p8022 0xae6aa5eb unregister_8022_client +EXPORT_SYMBOL net/802/p8023 0x79790423 destroy_8023_client +EXPORT_SYMBOL net/802/p8023 0xc3a4c626 make_8023_client +EXPORT_SYMBOL net/802/psnap 0x658b79e4 unregister_snap_client +EXPORT_SYMBOL net/802/psnap 0xb7f26aae register_snap_client +EXPORT_SYMBOL net/9p/9pnet 0x00713a6e p9_client_read +EXPORT_SYMBOL net/9p/9pnet 0x00b06f3f p9_client_disconnect +EXPORT_SYMBOL net/9p/9pnet 0x01fee5a4 p9_client_create +EXPORT_SYMBOL net/9p/9pnet 0x06d8bdff p9_client_auth +EXPORT_SYMBOL net/9p/9pnet 0x0b11ff5a p9_idpool_put +EXPORT_SYMBOL net/9p/9pnet 0x3d73a797 p9_errstr2errno +EXPORT_SYMBOL net/9p/9pnet 0x41cdf927 v9fs_get_default_trans +EXPORT_SYMBOL net/9p/9pnet 0x47dd541d p9_client_stat +EXPORT_SYMBOL net/9p/9pnet 0x4a398d11 p9_client_write +EXPORT_SYMBOL net/9p/9pnet 0x521b3ff8 p9_client_fcreate +EXPORT_SYMBOL net/9p/9pnet 0x58c924a9 p9_client_cb +EXPORT_SYMBOL net/9p/9pnet 0x6744438c p9_client_destroy +EXPORT_SYMBOL net/9p/9pnet 0x6b754e6f p9_parse_header +EXPORT_SYMBOL net/9p/9pnet 0x7310a66f p9_idpool_create +EXPORT_SYMBOL net/9p/9pnet 0x76b79bf1 p9stat_read +EXPORT_SYMBOL net/9p/9pnet 0x7dec9c09 p9_client_version +EXPORT_SYMBOL net/9p/9pnet 0x801f1ec9 p9_tag_lookup +EXPORT_SYMBOL net/9p/9pnet 0x8c9391c0 v9fs_get_trans_by_name +EXPORT_SYMBOL net/9p/9pnet 0x8f34fe15 p9_idpool_check +EXPORT_SYMBOL net/9p/9pnet 0x976cdb7c p9_client_remove +EXPORT_SYMBOL net/9p/9pnet 0x99a7f30f p9_idpool_destroy +EXPORT_SYMBOL net/9p/9pnet 0x99aa7841 p9_idpool_get +EXPORT_SYMBOL net/9p/9pnet 0x9c964743 p9stat_free +EXPORT_SYMBOL net/9p/9pnet 0xadcff063 p9_client_walk +EXPORT_SYMBOL net/9p/9pnet 0xc1e0c942 p9_client_attach +EXPORT_SYMBOL net/9p/9pnet 0xd331fc1d p9pdu_dump +EXPORT_SYMBOL net/9p/9pnet 0xe185faeb p9_client_wstat +EXPORT_SYMBOL net/9p/9pnet 0xe2674869 p9_client_clunk +EXPORT_SYMBOL net/9p/9pnet 0xe58a3360 p9_error_init +EXPORT_SYMBOL net/9p/9pnet 0xf00321e0 p9_client_open +EXPORT_SYMBOL net/9p/9pnet 0xf0abb203 v9fs_register_trans +EXPORT_SYMBOL net/9p/9pnet 0xf45abee5 v9fs_unregister_trans +EXPORT_SYMBOL net/appletalk/appletalk 0x1b9b29cd atalk_find_dev_addr +EXPORT_SYMBOL net/appletalk/appletalk 0x37ce1715 alloc_ltalkdev +EXPORT_SYMBOL net/appletalk/appletalk 0x4f021d92 atrtr_get_dev +EXPORT_SYMBOL net/appletalk/appletalk 0xaed555d1 aarp_send_ddp +EXPORT_SYMBOL net/bluetooth/bluetooth 0x002c2171 bt_accept_unlink +EXPORT_SYMBOL net/bluetooth/bluetooth 0x15b65735 hci_register_cb +EXPORT_SYMBOL net/bluetooth/bluetooth 0x1795bfdd hci_resume_dev +EXPORT_SYMBOL net/bluetooth/bluetooth 0x1c586a03 hci_conn_auth +EXPORT_SYMBOL net/bluetooth/bluetooth 0x22d41d7f hci_unregister_cb +EXPORT_SYMBOL net/bluetooth/bluetooth 0x2c9d7d8b hci_unregister_dev +EXPORT_SYMBOL net/bluetooth/bluetooth 0x43cfdd62 hci_connect +EXPORT_SYMBOL net/bluetooth/bluetooth 0x4c1be78f bt_sock_register +EXPORT_SYMBOL net/bluetooth/bluetooth 0x58ba1fc0 hci_suspend_dev +EXPORT_SYMBOL net/bluetooth/bluetooth 0x5a422693 hci_send_sco +EXPORT_SYMBOL net/bluetooth/bluetooth 0x644be1b2 bt_sock_link +EXPORT_SYMBOL net/bluetooth/bluetooth 0x64bc6634 hci_alloc_dev +EXPORT_SYMBOL net/bluetooth/bluetooth 0x657dd06e bt_accept_dequeue +EXPORT_SYMBOL net/bluetooth/bluetooth 0x7094f8ae bt_err +EXPORT_SYMBOL net/bluetooth/bluetooth 0x726c6f59 hci_conn_check_link_mode +EXPORT_SYMBOL net/bluetooth/bluetooth 0x755cf738 hci_unregister_proto +EXPORT_SYMBOL net/bluetooth/bluetooth 0x8c41747d bt_accept_enqueue +EXPORT_SYMBOL net/bluetooth/bluetooth 0x8c99dffc hci_conn_switch_role +EXPORT_SYMBOL net/bluetooth/bluetooth 0x8d2f8bb6 hci_send_acl +EXPORT_SYMBOL net/bluetooth/bluetooth 0xa90965ae hci_conn_encrypt +EXPORT_SYMBOL net/bluetooth/bluetooth 0xad4cd2f1 bt_sock_recvmsg +EXPORT_SYMBOL net/bluetooth/bluetooth 0xaf24bbac hci_conn_change_link_key +EXPORT_SYMBOL net/bluetooth/bluetooth 0xb1870965 hci_register_dev +EXPORT_SYMBOL net/bluetooth/bluetooth 0xb1f627ba bt_sock_ioctl +EXPORT_SYMBOL net/bluetooth/bluetooth 0xb61893e7 bt_sock_unlink +EXPORT_SYMBOL net/bluetooth/bluetooth 0xbaa4a79d bt_sock_wait_state +EXPORT_SYMBOL net/bluetooth/bluetooth 0xbd01e611 hci_get_route +EXPORT_SYMBOL net/bluetooth/bluetooth 0xc2066af0 batostr +EXPORT_SYMBOL net/bluetooth/bluetooth 0xcc1fb551 baswap +EXPORT_SYMBOL net/bluetooth/bluetooth 0xd9a618cc hci_free_dev +EXPORT_SYMBOL net/bluetooth/bluetooth 0xdba227ba hci_recv_fragment +EXPORT_SYMBOL net/bluetooth/bluetooth 0xf19294db bt_sock_unregister +EXPORT_SYMBOL net/bluetooth/bluetooth 0xf4e7be1c hci_register_proto +EXPORT_SYMBOL net/bluetooth/bluetooth 0xfa214800 bt_sock_poll +EXPORT_SYMBOL net/bluetooth/l2cap 0xfc31fe88 l2cap_load +EXPORT_SYMBOL net/bridge/bridge 0x68f39c2c br_should_route_hook +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0x1eac46bd ebt_do_table +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0x87ec4788 ebt_register_table +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0xfb04340f ebt_unregister_table +EXPORT_SYMBOL net/ipv4/inet_lro 0x12cac1dd lro_flush_pkt +EXPORT_SYMBOL net/ipv4/inet_lro 0x2ed3892d lro_vlan_hwaccel_receive_skb +EXPORT_SYMBOL net/ipv4/inet_lro 0x355bbd6d lro_flush_all +EXPORT_SYMBOL net/ipv4/inet_lro 0xa585d1c0 lro_receive_skb +EXPORT_SYMBOL net/ipv4/inet_lro 0xe97fabb9 lro_vlan_hwaccel_receive_frags +EXPORT_SYMBOL net/ipv4/inet_lro 0xfc750d4e lro_receive_frags +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x6749e672 arpt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x7bc4f435 arpt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x8bb6fae4 arpt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0x11107419 ipt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0x73530e56 ipt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0xe273e63b ipt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x2a649f59 nf_nat_protocol_unregister +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x6a2beda6 nf_nat_used_tuple +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x6ff58a08 nf_nat_mangle_udp_packet +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x80601faf nf_nat_setup_info +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x9c73f8cc nf_nat_mangle_tcp_packet +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0xa4027abb nf_nat_protocol_register +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0xa60bba71 nf_nat_follow_master +EXPORT_SYMBOL net/ipv4/tunnel4 0xc5ee9785 xfrm4_tunnel_register +EXPORT_SYMBOL net/ipv4/tunnel4 0xf79fc1f1 xfrm4_tunnel_deregister +EXPORT_SYMBOL net/ipv6/ipv6 0x09b1d43b ip6_xmit +EXPORT_SYMBOL net/ipv6/ipv6 0x0aa63e36 inet6_bind +EXPORT_SYMBOL net/ipv6/ipv6 0x0aced4f9 xfrm6_prepare_output +EXPORT_SYMBOL net/ipv6/ipv6 0x0f2ba2b2 ndisc_mc_map +EXPORT_SYMBOL net/ipv6/ipv6 0x147deb67 ip6_frag_init +EXPORT_SYMBOL net/ipv6/ipv6 0x2034693f xfrm6_rcv +EXPORT_SYMBOL net/ipv6/ipv6 0x22248501 ipv6_getsockopt +EXPORT_SYMBOL net/ipv6/ipv6 0x25a6256b inet6_unregister_protosw +EXPORT_SYMBOL net/ipv6/ipv6 0x27e52196 ip6_route_output +EXPORT_SYMBOL net/ipv6/ipv6 0x2df01c48 ipv6_push_nfrag_opts +EXPORT_SYMBOL net/ipv6/ipv6 0x30123eb5 icmpv6_statistics +EXPORT_SYMBOL net/ipv6/ipv6 0x382b4e37 in6_dev_finish_destroy +EXPORT_SYMBOL net/ipv6/ipv6 0x38b7c741 xfrm6_find_1stfragopt +EXPORT_SYMBOL net/ipv6/ipv6 0x538383c0 unregister_inet6addr_notifier +EXPORT_SYMBOL net/ipv6/ipv6 0x60860634 inet6_del_protocol +EXPORT_SYMBOL net/ipv6/ipv6 0x61b15498 ipv6_chk_prefix +EXPORT_SYMBOL net/ipv6/ipv6 0x68750d8a ipv6_setsockopt +EXPORT_SYMBOL net/ipv6/ipv6 0x7475039c icmpv6_send +EXPORT_SYMBOL net/ipv6/ipv6 0x74d68c7a xfrm6_rcv_spi +EXPORT_SYMBOL net/ipv6/ipv6 0x7867fb0e inet6_add_protocol +EXPORT_SYMBOL net/ipv6/ipv6 0x81ae79bc inet6_release +EXPORT_SYMBOL net/ipv6/ipv6 0x8c935fd0 inet6_ioctl +EXPORT_SYMBOL net/ipv6/ipv6 0x96df79c4 ip6_route_me_harder +EXPORT_SYMBOL net/ipv6/ipv6 0x98fda437 ip6_frag_match +EXPORT_SYMBOL net/ipv6/ipv6 0xb1b5f553 nf_ip6_checksum +EXPORT_SYMBOL net/ipv6/ipv6 0xb905ad82 icmpv6_err_convert +EXPORT_SYMBOL net/ipv6/ipv6 0xce19bac5 register_inet6addr_notifier +EXPORT_SYMBOL net/ipv6/ipv6 0xd9586c61 inet6_getname +EXPORT_SYMBOL net/ipv6/ipv6 0xda890b91 rt6_lookup +EXPORT_SYMBOL net/ipv6/ipv6 0xe1a81c3a icmpv6msg_statistics +EXPORT_SYMBOL net/ipv6/ipv6 0xe690b8fd __ipv6_isatap_ifid +EXPORT_SYMBOL net/ipv6/ipv6 0xe9c2855d ipv6_chk_addr +EXPORT_SYMBOL net/ipv6/ipv6 0xec8f1dee ipv6_dev_get_saddr +EXPORT_SYMBOL net/ipv6/ipv6 0xfaaa617a inet6_register_protosw +EXPORT_SYMBOL net/ipv6/ipv6 0xfb6625be xfrm6_input_addr +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x5a84a207 ip6t_register_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xb8bddf33 ip6t_ext_hdr +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xc73b71ac ip6t_unregister_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xf4e5cbd5 ipv6_find_hdr +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xfce5b05b ip6t_do_table +EXPORT_SYMBOL net/ipv6/tunnel6 0x853b8af3 xfrm6_tunnel_deregister +EXPORT_SYMBOL net/ipv6/tunnel6 0xf9bc7417 xfrm6_tunnel_register +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0x9cd013f2 xfrm6_tunnel_alloc_spi +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0xab14e193 xfrm6_tunnel_free_spi +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0xdb1b42d1 xfrm6_tunnel_spi_lookup +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x175f86fa ircomm_control_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x24dff6fc ircomm_disconnect_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x519f4205 ircomm_connect_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x740c672e ircomm_open +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x741ef57b ircomm_flow_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0xc9cb799a ircomm_data_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0xd927bbf5 ircomm_connect_response +EXPORT_SYMBOL net/irda/ircomm/ircomm 0xe3924b13 ircomm_close +EXPORT_SYMBOL net/irda/irda 0x02391797 irttp_udata_request +EXPORT_SYMBOL net/irda/irda 0x05d7cfe5 irias_add_octseq_attrib +EXPORT_SYMBOL net/irda/irda 0x06a3ee58 irias_new_integer_value +EXPORT_SYMBOL net/irda/irda 0x06a5934a irlmp_open_lsap +EXPORT_SYMBOL net/irda/irda 0x07d3647c irlmp_register_service +EXPORT_SYMBOL net/irda/irda 0x19d79c82 hashbin_lock_find +EXPORT_SYMBOL net/irda/irda 0x1c51e992 hashbin_delete +EXPORT_SYMBOL net/irda/irda 0x1dcb68cc irttp_connect_request +EXPORT_SYMBOL net/irda/irda 0x2036ad06 irda_param_insert +EXPORT_SYMBOL net/irda/irda 0x213269b1 irlmp_connect_request +EXPORT_SYMBOL net/irda/irda 0x22b0f52d hashbin_insert +EXPORT_SYMBOL net/irda/irda 0x26c4a4ff irttp_connect_response +EXPORT_SYMBOL net/irda/irda 0x2e0744a1 proc_irda +EXPORT_SYMBOL net/irda/irda 0x30827e1c irias_insert_object +EXPORT_SYMBOL net/irda/irda 0x3299448e irda_device_set_media_busy +EXPORT_SYMBOL net/irda/irda 0x3b2e9df9 hashbin_remove +EXPORT_SYMBOL net/irda/irda 0x42c7c5ce irias_find_object +EXPORT_SYMBOL net/irda/irda 0x448b8aaa irda_qos_bits_to_value +EXPORT_SYMBOL net/irda/irda 0x44f04bc8 iriap_getvaluebyclass_request +EXPORT_SYMBOL net/irda/irda 0x46c1c4a2 irlmp_unregister_service +EXPORT_SYMBOL net/irda/irda 0x49f6b0b6 irlmp_close_lsap +EXPORT_SYMBOL net/irda/irda 0x519118cc irias_add_integer_attrib +EXPORT_SYMBOL net/irda/irda 0x538fe1e0 hashbin_get_first +EXPORT_SYMBOL net/irda/irda 0x5504cf7c hashbin_new +EXPORT_SYMBOL net/irda/irda 0x57fb1ed2 hashbin_remove_this +EXPORT_SYMBOL net/irda/irda 0x5aad87aa irias_delete_object +EXPORT_SYMBOL net/irda/irda 0x5d609063 irias_new_object +EXPORT_SYMBOL net/irda/irda 0x6057cd4f async_unwrap_char +EXPORT_SYMBOL net/irda/irda 0x6621aa8a hashbin_find +EXPORT_SYMBOL net/irda/irda 0x6b043eba irda_init_max_qos_capabilies +EXPORT_SYMBOL net/irda/irda 0x701e028e irias_add_string_attrib +EXPORT_SYMBOL net/irda/irda 0x7042bc54 irlmp_register_client +EXPORT_SYMBOL net/irda/irda 0x763e54a4 irlmp_unregister_client +EXPORT_SYMBOL net/irda/irda 0x7957f728 irlmp_update_client +EXPORT_SYMBOL net/irda/irda 0x8b8d7f22 async_wrap_skb +EXPORT_SYMBOL net/irda/irda 0x91815586 irda_param_pack +EXPORT_SYMBOL net/irda/irda 0x951b6aa2 alloc_irdadev +EXPORT_SYMBOL net/irda/irda 0x993ad14b irda_param_extract_all +EXPORT_SYMBOL net/irda/irda 0x99f66a99 irttp_disconnect_request +EXPORT_SYMBOL net/irda/irda 0xb9394173 irias_delete_value +EXPORT_SYMBOL net/irda/irda 0xba4f3ef2 irttp_dup +EXPORT_SYMBOL net/irda/irda 0xbcd3ef13 irias_object_change_attribute +EXPORT_SYMBOL net/irda/irda 0xbe40ace9 irlmp_discovery_request +EXPORT_SYMBOL net/irda/irda 0xc097d08e iriap_close +EXPORT_SYMBOL net/irda/irda 0xc962c3a1 irlap_open +EXPORT_SYMBOL net/irda/irda 0xd6460c33 iriap_open +EXPORT_SYMBOL net/irda/irda 0xd76cd189 irttp_data_request +EXPORT_SYMBOL net/irda/irda 0xde4c6b3c irlmp_service_to_hint +EXPORT_SYMBOL net/irda/irda 0xe11e9aff irlmp_connect_response +EXPORT_SYMBOL net/irda/irda 0xe1cb8b20 irttp_open_tsap +EXPORT_SYMBOL net/irda/irda 0xe2f84c82 hashbin_get_next +EXPORT_SYMBOL net/irda/irda 0xe538b224 irttp_close_tsap +EXPORT_SYMBOL net/irda/irda 0xe9e55ffb irda_notify_init +EXPORT_SYMBOL net/irda/irda 0xedd521c2 irlmp_get_discoveries +EXPORT_SYMBOL net/irda/irda 0xf4cef169 irlmp_disconnect_request +EXPORT_SYMBOL net/irda/irda 0xf58f31b8 irlmp_data_request +EXPORT_SYMBOL net/irda/irda 0xfa9101c9 irttp_flow_request +EXPORT_SYMBOL net/irda/irda 0xfc5b56be irlap_close +EXPORT_SYMBOL net/lapb/lapb 0x077495d7 lapb_disconnect_request +EXPORT_SYMBOL net/lapb/lapb 0x246b4015 lapb_unregister +EXPORT_SYMBOL net/lapb/lapb 0x32efdc96 lapb_data_request +EXPORT_SYMBOL net/lapb/lapb 0x9ee90a6e lapb_getparms +EXPORT_SYMBOL net/lapb/lapb 0xa8e6b97b lapb_connect_request +EXPORT_SYMBOL net/lapb/lapb 0xbdee9e50 lapb_setparms +EXPORT_SYMBOL net/lapb/lapb 0xc7cfb156 lapb_register +EXPORT_SYMBOL net/lapb/lapb 0xe429033e lapb_data_received +EXPORT_SYMBOL net/llc/llc 0x38b92846 llc_remove_pack +EXPORT_SYMBOL net/llc/llc 0x3b2e3e2a llc_sap_open +EXPORT_SYMBOL net/llc/llc 0x52d7b2fd llc_sap_list +EXPORT_SYMBOL net/llc/llc 0x556643e3 llc_sap_list_lock +EXPORT_SYMBOL net/llc/llc 0x79b4ab25 llc_set_station_handler +EXPORT_SYMBOL net/llc/llc 0x831e8920 llc_add_pack +EXPORT_SYMBOL net/llc/llc 0x89a06453 llc_sap_close +EXPORT_SYMBOL net/llc/llc 0xd2436c34 llc_sap_find +EXPORT_SYMBOL net/llc/llc 0xe4a651ac llc_mac_hdr_init +EXPORT_SYMBOL net/llc/llc 0xfaeff303 llc_build_and_send_ui_pkt +EXPORT_SYMBOL net/mac80211/mac80211 0x1ac742b9 ieee80211_get_hdrlen_from_skb +EXPORT_SYMBOL net/mac80211/mac80211 0x242920ae ieee80211_scan_completed +EXPORT_SYMBOL net/mac80211/mac80211 0x2af85d7c ieee80211_rate_control_unregister +EXPORT_SYMBOL net/mac80211/mac80211 0x313ce32f ieee80211_wake_queue +EXPORT_SYMBOL net/mac80211/mac80211 0x382b5138 ieee80211_stop_tx_ba_cb_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x3bec613b ieee80211_generic_frame_duration +EXPORT_SYMBOL net/mac80211/mac80211 0x47bd054c ieee80211_start_tx_ba_cb +EXPORT_SYMBOL net/mac80211/mac80211 0x4b01e47d ieee80211_free_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x4ee1d37c ieee80211_start_tx_ba_cb_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x4f4f6de7 ieee80211_get_tkip_key +EXPORT_SYMBOL net/mac80211/mac80211 0x4f72966d __ieee80211_rx +EXPORT_SYMBOL net/mac80211/mac80211 0x5315a932 ieee80211_queue_stopped +EXPORT_SYMBOL net/mac80211/mac80211 0x5812c019 ieee80211_unregister_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x69dc08c4 __ieee80211_get_rx_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x76dc9df9 ieee80211_rts_get +EXPORT_SYMBOL net/mac80211/mac80211 0x7fbf6608 ieee80211_ctstoself_duration +EXPORT_SYMBOL net/mac80211/mac80211 0x8036d2d4 ieee80211_wake_queues +EXPORT_SYMBOL net/mac80211/mac80211 0x8b8ef22f ieee80211_tx_status_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x8c35d732 ieee80211_hdrlen +EXPORT_SYMBOL net/mac80211/mac80211 0x8fcfee71 ieee80211_beacon_get +EXPORT_SYMBOL net/mac80211/mac80211 0x95ddb0ce ieee80211_find_sta +EXPORT_SYMBOL net/mac80211/mac80211 0x970a342e ieee80211_stop_queues +EXPORT_SYMBOL net/mac80211/mac80211 0xb00640df __ieee80211_get_radio_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0xb314fef6 __ieee80211_get_assoc_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0xb879b8ef ieee80211_rts_duration +EXPORT_SYMBOL net/mac80211/mac80211 0xbd8ae787 ieee80211_stop_tx_ba_session +EXPORT_SYMBOL net/mac80211/mac80211 0xbf95a6f4 ieee80211_tx_status +EXPORT_SYMBOL net/mac80211/mac80211 0xd2f7d70b __ieee80211_get_tx_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0xdc2be1de ieee80211_rx_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0xdef7aa26 ieee80211_alloc_hw +EXPORT_SYMBOL net/mac80211/mac80211 0xe85e2d55 ieee80211_stop_queue +EXPORT_SYMBOL net/mac80211/mac80211 0xe971358b wiphy_to_hw +EXPORT_SYMBOL net/mac80211/mac80211 0xec1d4b7b ieee80211_start_tx_ba_session +EXPORT_SYMBOL net/mac80211/mac80211 0xef1bb9dc ieee80211_ctstoself_get +EXPORT_SYMBOL net/mac80211/mac80211 0xef3d824e ieee80211_rate_control_register +EXPORT_SYMBOL net/mac80211/mac80211 0xf4950ad8 ieee80211_get_buffered_bc +EXPORT_SYMBOL net/mac80211/mac80211 0xfb81bffa ieee80211_register_hw +EXPORT_SYMBOL net/mac80211/mac80211 0xfc1665c0 ieee80211_stop_tx_ba_cb +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x3e1e90e4 ip_vs_conn_put +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x46a088fe register_ip_vs_scheduler +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x4cc0056e ip_vs_conn_new +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x510c2d1b unregister_ip_vs_app +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x7b37d81f ip_vs_tcp_conn_listen +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x90130404 unregister_ip_vs_scheduler +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xa1dbc2d8 ip_vs_proto_name +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xba39cacd register_ip_vs_app_inc +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xbe25e5ed ip_vs_skb_replace +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xd45318f4 ip_vs_conn_out_get +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xed656ea6 register_ip_vs_app +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xf239daf2 ip_vs_conn_in_get +EXPORT_SYMBOL net/netfilter/nf_conntrack 0xcd0e9b2e __nf_ct_ext_add +EXPORT_SYMBOL net/netfilter/nf_conntrack 0xdce60f12 __nf_ct_ext_destroy +EXPORT_SYMBOL net/netfilter/nf_conntrack_proto_gre 0xb9a7b465 nf_ct_gre_keymap_flush +EXPORT_SYMBOL net/netfilter/x_tables 0x1a801862 xt_find_match +EXPORT_SYMBOL net/netfilter/x_tables 0x358fc4e8 xt_unregister_target +EXPORT_SYMBOL net/netfilter/x_tables 0x3dcd58c5 xt_alloc_table_info +EXPORT_SYMBOL net/netfilter/x_tables 0x41f2a32f xt_unregister_targets +EXPORT_SYMBOL net/netfilter/x_tables 0x57e35170 xt_register_target +EXPORT_SYMBOL net/netfilter/x_tables 0x79de4f64 xt_register_targets +EXPORT_SYMBOL net/netfilter/x_tables 0xb7f0cb71 xt_unregister_matches +EXPORT_SYMBOL net/netfilter/x_tables 0xd39f08cf xt_register_matches +EXPORT_SYMBOL net/netfilter/x_tables 0xdf184bdc xt_unregister_match +EXPORT_SYMBOL net/netfilter/x_tables 0xeb2af803 xt_register_match +EXPORT_SYMBOL net/netfilter/x_tables 0xf7037dc6 xt_free_table_info +EXPORT_SYMBOL net/netfilter/x_tables 0xfa2c9ddf xt_find_target +EXPORT_SYMBOL net/phonet/phonet 0x0d51d0dc phonet_proto_unregister +EXPORT_SYMBOL net/phonet/phonet 0x45e680a7 phonet_proto_register +EXPORT_SYMBOL net/phonet/phonet 0x686318ab pn_sock_unhash +EXPORT_SYMBOL net/phonet/phonet 0x9b9c1f97 pn_sock_get_port +EXPORT_SYMBOL net/phonet/phonet 0x9d7c31ba pn_skb_send +EXPORT_SYMBOL net/phonet/phonet 0xa58bda4a pn_sock_hash +EXPORT_SYMBOL net/phonet/phonet 0xd413ed57 phonet_header_ops +EXPORT_SYMBOL net/phonet/phonet 0xfa238b85 phonet_stream_ops +EXPORT_SYMBOL net/rfkill/rfkill 0x250f509e rfkill_register +EXPORT_SYMBOL net/rfkill/rfkill 0x46dfa31f rfkill_force_state +EXPORT_SYMBOL net/rfkill/rfkill 0x6c60a0e0 rfkill_free +EXPORT_SYMBOL net/rfkill/rfkill 0x7772220d rfkill_switch_all +EXPORT_SYMBOL net/rfkill/rfkill 0x7957fea4 rfkill_unregister +EXPORT_SYMBOL net/rfkill/rfkill 0xa8da8ea0 rfkill_allocate +EXPORT_SYMBOL net/sunrpc/sunrpc 0x05e807a9 xdr_encode_string +EXPORT_SYMBOL net/sunrpc/sunrpc 0x065994f1 xdr_encode_opaque_fixed +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0f668ba9 svc_auth_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0fe39615 svc_reserve +EXPORT_SYMBOL net/sunrpc/sunrpc 0x102ee8b5 svc_set_client +EXPORT_SYMBOL net/sunrpc/sunrpc 0x12e280e3 svc_proc_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x18f1ba92 svc_process +EXPORT_SYMBOL net/sunrpc/sunrpc 0x19c1abf5 rpc_queue_upcall +EXPORT_SYMBOL net/sunrpc/sunrpc 0x1b14da15 svc_set_num_threads +EXPORT_SYMBOL net/sunrpc/sunrpc 0x22a1d5df rpc_mkpipe +EXPORT_SYMBOL net/sunrpc/sunrpc 0x24f0043b xdr_inline_decode +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2919b156 xdr_decode_string_inplace +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2e6eaa3e cache_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2eec63c9 xdr_encode_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0x326845c7 xdr_buf_from_iov +EXPORT_SYMBOL net/sunrpc/sunrpc 0x396bf190 auth_domain_find +EXPORT_SYMBOL net/sunrpc/sunrpc 0x39efeba4 auth_unix_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0x3f52cc1c cache_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x40f3e8d6 auth_unix_add_addr +EXPORT_SYMBOL net/sunrpc/sunrpc 0x43a94b87 svc_exit_thread +EXPORT_SYMBOL net/sunrpc/sunrpc 0x4af2f8f7 svc_sock_names +EXPORT_SYMBOL net/sunrpc/sunrpc 0x4e6c4964 xdr_read_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0x5912df9a xdr_buf_read_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0x5fd5047a svc_wake_up +EXPORT_SYMBOL net/sunrpc/sunrpc 0x607dcb8b svc_destroy +EXPORT_SYMBOL net/sunrpc/sunrpc 0x63a3bb8c svc_sock_update_bufs +EXPORT_SYMBOL net/sunrpc/sunrpc 0x6950743c svc_drop +EXPORT_SYMBOL net/sunrpc/sunrpc 0x6ae3fdcc xdr_decode_array2 +EXPORT_SYMBOL net/sunrpc/sunrpc 0x6ea0b55a svcauth_unix_set_client +EXPORT_SYMBOL net/sunrpc/sunrpc 0x6eea229d svcauth_unix_purge +EXPORT_SYMBOL net/sunrpc/sunrpc 0x71fa908a cache_flush +EXPORT_SYMBOL net/sunrpc/sunrpc 0x7f3a21a1 svc_create_pooled +EXPORT_SYMBOL net/sunrpc/sunrpc 0x81d6b01d xdr_inline_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0x82e94b1a svc_seq_show +EXPORT_SYMBOL net/sunrpc/sunrpc 0x874a6056 rpc_unlink +EXPORT_SYMBOL net/sunrpc/sunrpc 0x88b6f0fd xdr_shift_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0x88ed0a37 xdr_init_decode +EXPORT_SYMBOL net/sunrpc/sunrpc 0x8920f11a svc_recv +EXPORT_SYMBOL net/sunrpc/sunrpc 0x8ed4f227 svc_proc_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0x8f584615 svc_prepare_thread +EXPORT_SYMBOL net/sunrpc/sunrpc 0x9237a3ae xdr_encode_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0x9749c191 xdr_buf_subsegment +EXPORT_SYMBOL net/sunrpc/sunrpc 0x9c4a55ca cache_check +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa4bca271 svc_authenticate +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa5edfd01 xdr_enter_page +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa99413a8 auth_domain_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0xac26d002 auth_domain_put +EXPORT_SYMBOL net/sunrpc/sunrpc 0xb11917e3 xdr_init_encode +EXPORT_SYMBOL net/sunrpc/sunrpc 0xb3de7644 cache_purge +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc3880471 xdr_decode_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc393931e xdr_reserve_space +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc4b9ef78 sunrpc_cache_update +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc8e96dea qword_addhex +EXPORT_SYMBOL net/sunrpc/sunrpc 0xca2e4939 xdr_decode_word +EXPORT_SYMBOL net/sunrpc/sunrpc 0xd1e39609 xdr_encode_word +EXPORT_SYMBOL net/sunrpc/sunrpc 0xd620bcd9 unix_domain_find +EXPORT_SYMBOL net/sunrpc/sunrpc 0xd7cee6bb svc_auth_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0xd86c94f9 xdr_encode_array2 +EXPORT_SYMBOL net/sunrpc/sunrpc 0xdabe9653 sunrpc_cache_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe2c6c1a0 xdr_process_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe5919cb1 xdr_encode_opaque +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe6914e53 read_bytes_from_xdr_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe7eb87f2 svc_create +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe97f4ce5 qword_get +EXPORT_SYMBOL net/sunrpc/sunrpc 0xedcf6be4 qword_add +EXPORT_SYMBOL net/sunrpc/sunrpc 0xef030b59 xdr_write_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0xfbad7605 auth_unix_forget_old +EXPORT_SYMBOL net/wanrouter/wanrouter 0x0ebe03d1 unregister_wan_device +EXPORT_SYMBOL net/wanrouter/wanrouter 0x44ffaa88 register_wan_device +EXPORT_SYMBOL net/wireless/cfg80211 0x02862c64 wiphy_unregister +EXPORT_SYMBOL net/wireless/cfg80211 0x07e7ac5a ieee80211_radiotap_iterator_init +EXPORT_SYMBOL net/wireless/cfg80211 0x09c64fbd ieee80211_frequency_to_channel +EXPORT_SYMBOL net/wireless/cfg80211 0x4dad847b __ieee80211_get_channel +EXPORT_SYMBOL net/wireless/cfg80211 0x792e77d2 wiphy_free +EXPORT_SYMBOL net/wireless/cfg80211 0xaa4ddef7 wiphy_new +EXPORT_SYMBOL net/wireless/cfg80211 0xc4e85ec5 ieee80211_radiotap_iterator_next +EXPORT_SYMBOL net/wireless/cfg80211 0xccc291b3 ieee80211_channel_to_frequency +EXPORT_SYMBOL net/wireless/cfg80211 0xe77b9376 wiphy_register +EXPORT_SYMBOL net/wireless/cfg80211 0xf0479915 regulatory_hint +EXPORT_SYMBOL sound/core/oss/snd-mixer-oss 0x2b156eb9 snd_mixer_oss_ioctl_card +EXPORT_SYMBOL sound/core/seq/snd-seq 0x07b9c863 snd_seq_kernel_client_enqueue_blocking +EXPORT_SYMBOL sound/core/seq/snd-seq 0x1a724fcc snd_seq_kernel_client_ctl +EXPORT_SYMBOL sound/core/seq/snd-seq 0x3600bef3 snd_seq_kernel_client_write_poll +EXPORT_SYMBOL sound/core/seq/snd-seq 0x3ef3a376 snd_seq_create_kernel_client +EXPORT_SYMBOL sound/core/seq/snd-seq 0x3fb4d161 snd_seq_kernel_client_dispatch +EXPORT_SYMBOL sound/core/seq/snd-seq 0x6bb71038 snd_seq_delete_kernel_client +EXPORT_SYMBOL sound/core/seq/snd-seq 0x7ac2f329 snd_seq_expand_var_event +EXPORT_SYMBOL sound/core/seq/snd-seq 0x7b8699eb snd_seq_event_port_detach +EXPORT_SYMBOL sound/core/seq/snd-seq 0x90a7af96 snd_seq_event_port_attach +EXPORT_SYMBOL sound/core/seq/snd-seq 0xb8e448a0 snd_seq_set_queue_tempo +EXPORT_SYMBOL sound/core/seq/snd-seq 0xcac0a3be snd_seq_kernel_client_enqueue +EXPORT_SYMBOL sound/core/seq/snd-seq 0xe934da1d snd_seq_dump_var_event +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x3a57f235 snd_seq_autoload_unlock +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x5a69dadd snd_seq_device_register_driver +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x6339b6d0 snd_seq_device_load_drivers +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xb90668b2 snd_seq_autoload_lock +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xc622fb29 snd_seq_device_unregister_driver +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xdc085a34 snd_seq_device_new +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x3b55d387 snd_midi_event_encode_byte +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x68b9bd07 snd_midi_event_free +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x7adfa053 snd_midi_event_encode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x998f2126 snd_midi_event_new +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x9b1825a9 snd_midi_event_no_status +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xb6327286 snd_midi_event_decode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xbc51650a snd_midi_event_reset_decode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xe58d6519 snd_midi_event_reset_encode +EXPORT_SYMBOL sound/core/seq/snd-seq-virmidi 0xc1d0c4a7 snd_virmidi_new +EXPORT_SYMBOL sound/core/snd 0x0898f08e snd_register_device_for_dev +EXPORT_SYMBOL sound/core/snd 0x105cc8ef snd_register_oss_device +EXPORT_SYMBOL sound/core/snd 0x13463fc9 snd_add_device_sysfs_file +EXPORT_SYMBOL sound/core/snd 0x19552140 snd_info_create_card_entry +EXPORT_SYMBOL sound/core/snd 0x198788b4 snd_lookup_oss_minor_data +EXPORT_SYMBOL sound/core/snd 0x1ba5e1e0 snd_unregister_oss_device +EXPORT_SYMBOL sound/core/snd 0x23e7a3ad snd_info_register +EXPORT_SYMBOL sound/core/snd 0x24a94b26 snd_info_get_line +EXPORT_SYMBOL sound/core/snd 0x300ef546 snd_info_create_module_entry +EXPORT_SYMBOL sound/core/snd 0x3397d3e0 snd_card_register +EXPORT_SYMBOL sound/core/snd 0x3971b4df snd_ecards_limit +EXPORT_SYMBOL sound/core/snd 0x4023ceda snd_ctl_find_numid +EXPORT_SYMBOL sound/core/snd 0x40900528 snd_card_free +EXPORT_SYMBOL sound/core/snd 0x42cc17d6 snd_ctl_new1 +EXPORT_SYMBOL sound/core/snd 0x492a7ea0 snd_seq_root +EXPORT_SYMBOL sound/core/snd 0x4a3ea5c0 snd_request_card +EXPORT_SYMBOL sound/core/snd 0x5dfff781 snd_pci_quirk_lookup +EXPORT_SYMBOL sound/core/snd 0x602c96f0 copy_to_user_fromio +EXPORT_SYMBOL sound/core/snd 0x62e2349b snd_ctl_rename_id +EXPORT_SYMBOL sound/core/snd 0x6cf391d4 snd_card_disconnect +EXPORT_SYMBOL sound/core/snd 0x6d96397b snd_card_file_remove +EXPORT_SYMBOL sound/core/snd 0x6f2aa427 snd_card_proc_new +EXPORT_SYMBOL sound/core/snd 0x749fcef0 snd_ctl_notify +EXPORT_SYMBOL sound/core/snd 0x762b8d05 snd_unregister_device +EXPORT_SYMBOL sound/core/snd 0x86784844 snd_ctl_remove_id +EXPORT_SYMBOL sound/core/snd 0x8df3789f snd_oss_info_register +EXPORT_SYMBOL sound/core/snd 0x8e0c3c23 snd_card_file_add +EXPORT_SYMBOL sound/core/snd 0x8f595b11 snd_major +EXPORT_SYMBOL sound/core/snd 0x9b1c6390 snd_device_free +EXPORT_SYMBOL sound/core/snd 0xa6417fc8 snd_ctl_add +EXPORT_SYMBOL sound/core/snd 0xa77644a7 snd_info_free_entry +EXPORT_SYMBOL sound/core/snd 0xad83a1dd snd_ctl_boolean_stereo_info +EXPORT_SYMBOL sound/core/snd 0xb213fe8b snd_info_get_str +EXPORT_SYMBOL sound/core/snd 0xb2e5ae4a snd_lookup_minor_data +EXPORT_SYMBOL sound/core/snd 0xb55786b9 snd_ctl_boolean_mono_info +EXPORT_SYMBOL sound/core/snd 0xb5787b6e snd_mixer_oss_notify_callback +EXPORT_SYMBOL sound/core/snd 0xc05dd845 snd_ctl_register_ioctl +EXPORT_SYMBOL sound/core/snd 0xc5cf1777 snd_device_register +EXPORT_SYMBOL sound/core/snd 0xcd73dc07 snd_ctl_remove +EXPORT_SYMBOL sound/core/snd 0xce3ca308 copy_from_user_toio +EXPORT_SYMBOL sound/core/snd 0xd1157735 release_and_free_resource +EXPORT_SYMBOL sound/core/snd 0xd16fe1f3 snd_card_new +EXPORT_SYMBOL sound/core/snd 0xd2b6b63c snd_ctl_unregister_ioctl +EXPORT_SYMBOL sound/core/snd 0xd333121e snd_component_add +EXPORT_SYMBOL sound/core/snd 0xd7b8b734 snd_ctl_find_id +EXPORT_SYMBOL sound/core/snd 0xda4e8841 snd_ctl_free_one +EXPORT_SYMBOL sound/core/snd 0xe4854cea snd_iprintf +EXPORT_SYMBOL sound/core/snd 0xeffe522c snd_device_new +EXPORT_SYMBOL sound/core/snd 0xf379970d snd_cards +EXPORT_SYMBOL sound/core/snd 0xfcb94ec8 snd_card_free_when_closed +EXPORT_SYMBOL sound/core/snd-hwdep 0xed4f2d1a snd_hwdep_new +EXPORT_SYMBOL sound/core/snd-page-alloc 0x1f7e3ddc snd_dma_free_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0x2f59d78d snd_dma_reserve_buf +EXPORT_SYMBOL sound/core/snd-page-alloc 0x3225ef0c snd_dma_get_reserved_buf +EXPORT_SYMBOL sound/core/snd-page-alloc 0x3b91f3af snd_free_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0x4104a65d snd_dma_alloc_pages_fallback +EXPORT_SYMBOL sound/core/snd-page-alloc 0x87379374 snd_dma_alloc_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0xade88e76 snd_malloc_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x0181ba31 snd_pcm_lib_free_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x04cda566 snd_interval_refine +EXPORT_SYMBOL sound/core/snd-pcm 0x11498ac0 snd_pcm_hw_constraint_ratnums +EXPORT_SYMBOL sound/core/snd-pcm 0x115524a4 snd_pcm_set_sync +EXPORT_SYMBOL sound/core/snd-pcm 0x192b19ab snd_pcm_hw_constraint_minmax +EXPORT_SYMBOL sound/core/snd-pcm 0x1d027e4b snd_pcm_format_signed +EXPORT_SYMBOL sound/core/snd-pcm 0x1dc7c2d5 snd_pcm_lib_preallocate_free_for_all +EXPORT_SYMBOL sound/core/snd-pcm 0x1ea6009a snd_pcm_period_elapsed +EXPORT_SYMBOL sound/core/snd-pcm 0x2a151986 snd_pcm_lib_ioctl +EXPORT_SYMBOL sound/core/snd-pcm 0x2edb4bd8 snd_pcm_sgbuf_ops_page +EXPORT_SYMBOL sound/core/snd-pcm 0x33b2ea63 snd_pcm_lib_read +EXPORT_SYMBOL sound/core/snd-pcm 0x33cdf7d8 snd_pcm_sgbuf_get_chunk_size +EXPORT_SYMBOL sound/core/snd-pcm 0x3796bdcc snd_pcm_format_little_endian +EXPORT_SYMBOL sound/core/snd-pcm 0x38620404 snd_pcm_lib_writev +EXPORT_SYMBOL sound/core/snd-pcm 0x395e287f snd_pcm_link_rwlock +EXPORT_SYMBOL sound/core/snd-pcm 0x3a331710 snd_pcm_hw_constraint_integer +EXPORT_SYMBOL sound/core/snd-pcm 0x3c35e140 snd_pcm_mmap_data +EXPORT_SYMBOL sound/core/snd-pcm 0x456bd2fc snd_pcm_limit_hw_rates +EXPORT_SYMBOL sound/core/snd-pcm 0x4c6a7be7 snd_pcm_hw_rule_add +EXPORT_SYMBOL sound/core/snd-pcm 0x4d9b6d35 snd_pcm_format_size +EXPORT_SYMBOL sound/core/snd-pcm 0x4f816e9b snd_pcm_format_big_endian +EXPORT_SYMBOL sound/core/snd-pcm 0x52cb28f6 snd_pcm_lib_write +EXPORT_SYMBOL sound/core/snd-pcm 0x573020c6 snd_pcm_hw_refine +EXPORT_SYMBOL sound/core/snd-pcm 0x57db7486 snd_pcm_kernel_ioctl +EXPORT_SYMBOL sound/core/snd-pcm 0x5b80a5c8 snd_pcm_release_substream +EXPORT_SYMBOL sound/core/snd-pcm 0x5e7f4920 snd_pcm_format_set_silence +EXPORT_SYMBOL sound/core/snd-pcm 0x63f51c49 snd_pcm_hw_param_value +EXPORT_SYMBOL sound/core/snd-pcm 0x650f8603 snd_pcm_format_silence_64 +EXPORT_SYMBOL sound/core/snd-pcm 0x66054dc0 snd_pcm_stop +EXPORT_SYMBOL sound/core/snd-pcm 0x68a24153 snd_pcm_format_physical_width +EXPORT_SYMBOL sound/core/snd-pcm 0x699ecf82 snd_pcm_notify +EXPORT_SYMBOL sound/core/snd-pcm 0x6bba4f40 snd_pcm_hw_param_last +EXPORT_SYMBOL sound/core/snd-pcm 0x6ef8fcd8 snd_pcm_format_linear +EXPORT_SYMBOL sound/core/snd-pcm 0x77b9ccac _snd_pcm_hw_param_setempty +EXPORT_SYMBOL sound/core/snd-pcm 0x7880daaa snd_pcm_hw_constraint_step +EXPORT_SYMBOL sound/core/snd-pcm 0x79b3e29a snd_pcm_new_stream +EXPORT_SYMBOL sound/core/snd-pcm 0x8b64a6e3 snd_pcm_open_substream +EXPORT_SYMBOL sound/core/snd-pcm 0x952d5f21 _snd_pcm_hw_params_any +EXPORT_SYMBOL sound/core/snd-pcm 0x970c948b snd_pcm_lib_preallocate_pages_for_all +EXPORT_SYMBOL sound/core/snd-pcm 0x99a46126 snd_pcm_hw_constraint_list +EXPORT_SYMBOL sound/core/snd-pcm 0x99afda52 snd_pcm_lib_preallocate_pages +EXPORT_SYMBOL sound/core/snd-pcm 0xa61aa028 snd_pcm_format_unsigned +EXPORT_SYMBOL sound/core/snd-pcm 0xa65528aa snd_pcm_hw_constraint_msbits +EXPORT_SYMBOL sound/core/snd-pcm 0xa8de49a6 snd_pcm_lib_readv +EXPORT_SYMBOL sound/core/snd-pcm 0xb1ca44c9 snd_pcm_hw_constraint_ratdens +EXPORT_SYMBOL sound/core/snd-pcm 0xb9638db4 snd_pcm_rate_to_rate_bit +EXPORT_SYMBOL sound/core/snd-pcm 0xc86cd4ad snd_pcm_hw_constraint_pow2 +EXPORT_SYMBOL sound/core/snd-pcm 0xcc0b4bc1 snd_pcm_lib_malloc_pages +EXPORT_SYMBOL sound/core/snd-pcm 0xd0b9b8b8 snd_interval_list +EXPORT_SYMBOL sound/core/snd-pcm 0xd59441bf snd_pcm_hw_param_first +EXPORT_SYMBOL sound/core/snd-pcm 0xda5e389d snd_pcm_new +EXPORT_SYMBOL sound/core/snd-pcm 0xde1a996b snd_pcm_set_ops +EXPORT_SYMBOL sound/core/snd-pcm 0xe56a9336 snd_pcm_format_width +EXPORT_SYMBOL sound/core/snd-pcm 0xf3797152 snd_interval_ratnum +EXPORT_SYMBOL sound/core/snd-rawmidi 0x0468d895 snd_rawmidi_kernel_write +EXPORT_SYMBOL sound/core/snd-rawmidi 0x10865d54 snd_rawmidi_drain_input +EXPORT_SYMBOL sound/core/snd-rawmidi 0x291200be snd_rawmidi_drop_output +EXPORT_SYMBOL sound/core/snd-rawmidi 0x3db95450 snd_rawmidi_transmit_empty +EXPORT_SYMBOL sound/core/snd-rawmidi 0x5ef3ac6e snd_rawmidi_kernel_read +EXPORT_SYMBOL sound/core/snd-rawmidi 0x774d29ba snd_rawmidi_kernel_open +EXPORT_SYMBOL sound/core/snd-rawmidi 0x83a91089 snd_rawmidi_transmit +EXPORT_SYMBOL sound/core/snd-rawmidi 0xa576ed6b snd_rawmidi_drain_output +EXPORT_SYMBOL sound/core/snd-rawmidi 0xbe0f28ae snd_rawmidi_set_ops +EXPORT_SYMBOL sound/core/snd-rawmidi 0xc195bda1 snd_rawmidi_new +EXPORT_SYMBOL sound/core/snd-rawmidi 0xceb935c5 snd_rawmidi_info_select +EXPORT_SYMBOL sound/core/snd-rawmidi 0xe2ae0c1b snd_rawmidi_input_params +EXPORT_SYMBOL sound/core/snd-rawmidi 0xeee6645c snd_rawmidi_kernel_release +EXPORT_SYMBOL sound/core/snd-rawmidi 0xf1096f75 snd_rawmidi_transmit_ack +EXPORT_SYMBOL sound/core/snd-rawmidi 0xf3042eed snd_rawmidi_receive +EXPORT_SYMBOL sound/core/snd-rawmidi 0xf88adc10 snd_rawmidi_transmit_peek +EXPORT_SYMBOL sound/core/snd-rawmidi 0xfc877d13 snd_rawmidi_output_params +EXPORT_SYMBOL sound/core/snd-timer 0x10515b60 snd_timer_pause +EXPORT_SYMBOL sound/core/snd-timer 0x45f7e8ff snd_timer_continue +EXPORT_SYMBOL sound/core/snd-timer 0x484a33b3 snd_timer_interrupt +EXPORT_SYMBOL sound/core/snd-timer 0x51255de1 snd_timer_notify +EXPORT_SYMBOL sound/core/snd-timer 0x582eef55 snd_timer_open +EXPORT_SYMBOL sound/core/snd-timer 0x7ecc3921 snd_timer_new +EXPORT_SYMBOL sound/core/snd-timer 0x909d69ae snd_timer_close +EXPORT_SYMBOL sound/core/snd-timer 0x97a1fbf9 snd_timer_global_free +EXPORT_SYMBOL sound/core/snd-timer 0xdbb26c58 snd_timer_start +EXPORT_SYMBOL sound/core/snd-timer 0xdcdb3b8b snd_timer_resolution +EXPORT_SYMBOL sound/core/snd-timer 0xe9b0b50a snd_timer_global_register +EXPORT_SYMBOL sound/core/snd-timer 0xec254a4d snd_timer_global_new +EXPORT_SYMBOL sound/core/snd-timer 0xf1172248 snd_timer_stop +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0x73c4c993 snd_mpu401_uart_interrupt_tx +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0xfb98d832 snd_mpu401_uart_new +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0xfe618b58 snd_mpu401_uart_interrupt +EXPORT_SYMBOL sound/soundcore 0x1586ffa1 register_sound_special_device +EXPORT_SYMBOL sound/soundcore 0x1c891b55 sound_class +EXPORT_SYMBOL sound/soundcore 0x30c97e96 register_sound_mixer +EXPORT_SYMBOL sound/soundcore 0x63371691 register_sound_midi +EXPORT_SYMBOL sound/soundcore 0x7afc9d8a unregister_sound_mixer +EXPORT_SYMBOL sound/soundcore 0x96c6b059 register_sound_special +EXPORT_SYMBOL sound/soundcore 0x99c95fa5 unregister_sound_special +EXPORT_SYMBOL sound/soundcore 0xcd083b10 unregister_sound_dsp +EXPORT_SYMBOL sound/soundcore 0xea542470 register_sound_dsp +EXPORT_SYMBOL sound/soundcore 0xfdab6de3 unregister_sound_midi +EXPORT_SYMBOL sound/usb/snd-usb-lib 0x16756dc0 snd_usbmidi_input_start +EXPORT_SYMBOL sound/usb/snd-usb-lib 0x35207fcf snd_usb_create_midi_interface +EXPORT_SYMBOL sound/usb/snd-usb-lib 0x63343b1d snd_usbmidi_input_stop +EXPORT_SYMBOL sound/usb/snd-usb-lib 0xd9d2bb03 snd_usbmidi_disconnect +EXPORT_SYMBOL vmlinux 0x00000000 fp_printk +EXPORT_SYMBOL vmlinux 0x00000000 fp_send_sig +EXPORT_SYMBOL vmlinux 0x00000000 kern_fp_enter +EXPORT_SYMBOL vmlinux 0x00000000 per_cpu__softirq_work_list +EXPORT_SYMBOL vmlinux 0x002e39dc sock_create +EXPORT_SYMBOL vmlinux 0x002f9a26 proc_doulongvec_minmax +EXPORT_SYMBOL vmlinux 0x003d6cca inet_stream_connect +EXPORT_SYMBOL vmlinux 0x007eb211 qdisc_tree_decrease_qlen +EXPORT_SYMBOL vmlinux 0x00801678 flush_scheduled_work +EXPORT_SYMBOL vmlinux 0x00c44b7b __xfrm_route_forward +EXPORT_SYMBOL vmlinux 0x00e8097b csum_partial_copy_fromiovecend +EXPORT_SYMBOL vmlinux 0x01000e51 schedule +EXPORT_SYMBOL vmlinux 0x01139ffc max_mapnr +EXPORT_SYMBOL vmlinux 0x014b33a5 dst_destroy +EXPORT_SYMBOL vmlinux 0x01902adf netpoll_trap +EXPORT_SYMBOL vmlinux 0x01a4aab6 set_irq_chip_data +EXPORT_SYMBOL vmlinux 0x01d49005 scsi_register_interface +EXPORT_SYMBOL vmlinux 0x01f57287 tcp_tso_segment +EXPORT_SYMBOL vmlinux 0x020904e1 search_binary_handler +EXPORT_SYMBOL vmlinux 0x02124474 ip_send_check +EXPORT_SYMBOL vmlinux 0x02196324 __aeabi_idiv +EXPORT_SYMBOL vmlinux 0x024b64f5 ethtool_op_get_sg +EXPORT_SYMBOL vmlinux 0x02c4a5f4 xfrm_bundle_ok +EXPORT_SYMBOL vmlinux 0x02c95cbf blk_queue_start_tag +EXPORT_SYMBOL vmlinux 0x02ee26c1 free_pages_exact +EXPORT_SYMBOL vmlinux 0x0334da4e scsi_command_size_tbl +EXPORT_SYMBOL vmlinux 0x0344e86e blk_rq_map_sg +EXPORT_SYMBOL vmlinux 0x0349157e pci_find_bus +EXPORT_SYMBOL vmlinux 0x0350e2f4 up_read +EXPORT_SYMBOL vmlinux 0x037a0cba kfree +EXPORT_SYMBOL vmlinux 0x0381e33a generic_file_aio_read +EXPORT_SYMBOL vmlinux 0x0398db89 block_invalidatepage +EXPORT_SYMBOL vmlinux 0x03a99c3b rb_prev +EXPORT_SYMBOL vmlinux 0x03ad24d2 unlock_page +EXPORT_SYMBOL vmlinux 0x03c06156 bitmap_fold +EXPORT_SYMBOL vmlinux 0x03d6608c unregister_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0x03e89ffd put_tty_driver +EXPORT_SYMBOL vmlinux 0x03f4afcd qmgr_disable_irq +EXPORT_SYMBOL vmlinux 0x03fd2571 vm_unmap_ram +EXPORT_SYMBOL vmlinux 0x041e4ec1 uart_remove_one_port +EXPORT_SYMBOL vmlinux 0x041f561a igrab +EXPORT_SYMBOL vmlinux 0x0422fe4a inet_csk_timer_bug_msg +EXPORT_SYMBOL vmlinux 0x043b8483 __kfifo_get +EXPORT_SYMBOL vmlinux 0x0444ec06 filp_open +EXPORT_SYMBOL vmlinux 0x044fbf49 mempool_kzalloc +EXPORT_SYMBOL vmlinux 0x0491e8e1 dma_mark_declared_memory_occupied +EXPORT_SYMBOL vmlinux 0x04c2175e filemap_fdatawait +EXPORT_SYMBOL vmlinux 0x04c9d34a pci_pme_capable +EXPORT_SYMBOL vmlinux 0x04e2042a dma_unmap_sg +EXPORT_SYMBOL vmlinux 0x04f2bf2e tcf_hash_new_index +EXPORT_SYMBOL vmlinux 0x052b2967 kblockd_flush_work +EXPORT_SYMBOL vmlinux 0x0560cdeb xfrm_state_flush +EXPORT_SYMBOL vmlinux 0x056318d8 xfrm_init_state +EXPORT_SYMBOL vmlinux 0x056558aa simple_unlink +EXPORT_SYMBOL vmlinux 0x056d4d05 dma_alloc_coherent +EXPORT_SYMBOL vmlinux 0x057ce975 hex_dump_to_buffer +EXPORT_SYMBOL vmlinux 0x057f247c set_page_dirty +EXPORT_SYMBOL vmlinux 0x0589fe77 __xfrm_lookup +EXPORT_SYMBOL vmlinux 0x05f18d9c inode_needs_sync +EXPORT_SYMBOL vmlinux 0x0600304c open_bdev_exclusive +EXPORT_SYMBOL vmlinux 0x06018b1a dev_get_by_index +EXPORT_SYMBOL vmlinux 0x06090de7 __sg_free_table +EXPORT_SYMBOL vmlinux 0x061651be strcat +EXPORT_SYMBOL vmlinux 0x0618e633 dump_fpu +EXPORT_SYMBOL vmlinux 0x062aba95 mempool_free +EXPORT_SYMBOL vmlinux 0x06411920 tcp_proc_register +EXPORT_SYMBOL vmlinux 0x066b11b0 kset_register +EXPORT_SYMBOL vmlinux 0x0672331e km_new_mapping +EXPORT_SYMBOL vmlinux 0x06b48031 netpoll_cleanup +EXPORT_SYMBOL vmlinux 0x06c05f3a page_symlink +EXPORT_SYMBOL vmlinux 0x06cb34e5 init_waitqueue_head +EXPORT_SYMBOL vmlinux 0x06d4fe35 filemap_fdatawrite +EXPORT_SYMBOL vmlinux 0x06d8bae1 idr_get_new +EXPORT_SYMBOL vmlinux 0x06f7f1f2 kmem_cache_create +EXPORT_SYMBOL vmlinux 0x06fe3b14 default_grn +EXPORT_SYMBOL vmlinux 0x0715b090 tty_free_termios +EXPORT_SYMBOL vmlinux 0x0724ff35 eth_type_trans +EXPORT_SYMBOL vmlinux 0x0731adef audit_log_start +EXPORT_SYMBOL vmlinux 0x073a9a98 d_validate +EXPORT_SYMBOL vmlinux 0x075a1796 tty_chars_in_buffer +EXPORT_SYMBOL vmlinux 0x07910dd0 unregister_netdev +EXPORT_SYMBOL vmlinux 0x0799aca4 local_bh_enable +EXPORT_SYMBOL vmlinux 0x079cd7f1 ns_to_timeval +EXPORT_SYMBOL vmlinux 0x07bb3a03 generic_delete_inode +EXPORT_SYMBOL vmlinux 0x07cc4a5d printk_timed_ratelimit +EXPORT_SYMBOL vmlinux 0x07d1bcac gpio_to_irq +EXPORT_SYMBOL vmlinux 0x07d83ec9 arp_tbl +EXPORT_SYMBOL vmlinux 0x07d9b783 scsi_nl_send_vendor_msg +EXPORT_SYMBOL vmlinux 0x08047ba6 tcp_parse_options +EXPORT_SYMBOL vmlinux 0x082c3213 pci_root_buses +EXPORT_SYMBOL vmlinux 0x083e7362 kthread_bind +EXPORT_SYMBOL vmlinux 0x0850c387 nla_append +EXPORT_SYMBOL vmlinux 0x085efb5f scsi_allocate_command +EXPORT_SYMBOL vmlinux 0x089a1a1d vm_insert_page +EXPORT_SYMBOL vmlinux 0x092b007a sleep_on_timeout +EXPORT_SYMBOL vmlinux 0x092f6488 tcp_sendmsg +EXPORT_SYMBOL vmlinux 0x0948cde9 num_physpages +EXPORT_SYMBOL vmlinux 0x094bd17e xfrm_register_km +EXPORT_SYMBOL vmlinux 0x09870c51 netlink_change_ngroups +EXPORT_SYMBOL vmlinux 0x098baca5 page_follow_link_light +EXPORT_SYMBOL vmlinux 0x098f8861 blk_get_backing_dev_info +EXPORT_SYMBOL vmlinux 0x0994e1c1 file_update_time +EXPORT_SYMBOL vmlinux 0x099ee22f scsi_host_put +EXPORT_SYMBOL vmlinux 0x09a53ea6 dmam_free_coherent +EXPORT_SYMBOL vmlinux 0x09c55cec schedule_timeout_interruptible +EXPORT_SYMBOL vmlinux 0x09c58398 __nla_put +EXPORT_SYMBOL vmlinux 0x09d45c21 down_timeout +EXPORT_SYMBOL vmlinux 0x0a1bebc5 kernel_execve +EXPORT_SYMBOL vmlinux 0x0a21fe68 blk_queue_find_tag +EXPORT_SYMBOL vmlinux 0x0a2487e0 unblock_all_signals +EXPORT_SYMBOL vmlinux 0x0a3131f6 strnchr +EXPORT_SYMBOL vmlinux 0x0a373bf9 tcp_initialize_rcv_mss +EXPORT_SYMBOL vmlinux 0x0a3e367c ip_mc_inc_group +EXPORT_SYMBOL vmlinux 0x0a44e332 blk_queue_max_sectors +EXPORT_SYMBOL vmlinux 0x0a4747ff allocate_resource +EXPORT_SYMBOL vmlinux 0x0a5c0ae0 audit_log_format +EXPORT_SYMBOL vmlinux 0x0a7ae0d7 neigh_table_init_no_netlink +EXPORT_SYMBOL vmlinux 0x0aa13d05 __raw_readsw +EXPORT_SYMBOL vmlinux 0x0aa59277 bio_clone +EXPORT_SYMBOL vmlinux 0x0aa6a8d4 xfrm_input_resume +EXPORT_SYMBOL vmlinux 0x0acb1a3c __bitmap_shift_right +EXPORT_SYMBOL vmlinux 0x0ae5de9c dma_map_sg +EXPORT_SYMBOL vmlinux 0x0b10c176 dmam_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0x0b1beb31 vmalloc_32_user +EXPORT_SYMBOL vmlinux 0x0b295d65 generic_file_aio_write +EXPORT_SYMBOL vmlinux 0x0b54c004 dmabounce_sync_for_cpu +EXPORT_SYMBOL vmlinux 0x0b5f2d2c sg_next +EXPORT_SYMBOL vmlinux 0x0b673e5d scsi_add_host +EXPORT_SYMBOL vmlinux 0x0b6cec03 rtnetlink_put_metrics +EXPORT_SYMBOL vmlinux 0x0b742fd7 simple_strtol +EXPORT_SYMBOL vmlinux 0x0b7aad84 inet_frag_kill +EXPORT_SYMBOL vmlinux 0x0b9961ca pci_dev_driver +EXPORT_SYMBOL vmlinux 0x0bf51d30 sk_stream_wait_close +EXPORT_SYMBOL vmlinux 0x0bf61e9b kill_pgrp +EXPORT_SYMBOL vmlinux 0x0bfdef4f secpath_dup +EXPORT_SYMBOL vmlinux 0x0c248dfa __splice_from_pipe +EXPORT_SYMBOL vmlinux 0x0c65e73c scsi_normalize_sense +EXPORT_SYMBOL vmlinux 0x0c8c9e99 scsi_show_extd_sense +EXPORT_SYMBOL vmlinux 0x0c951eb0 nf_unregister_hooks +EXPORT_SYMBOL vmlinux 0x0ca4115f posix_lock_file_wait +EXPORT_SYMBOL vmlinux 0x0ce437cc ilookup5 +EXPORT_SYMBOL vmlinux 0x0ce98977 generic_setlease +EXPORT_SYMBOL vmlinux 0x0d3def21 idr_pre_get +EXPORT_SYMBOL vmlinux 0x0d3f57a2 _find_next_bit_le +EXPORT_SYMBOL vmlinux 0x0d431dee blk_queue_prep_rq +EXPORT_SYMBOL vmlinux 0x0d542439 __ipv6_addr_type +EXPORT_SYMBOL vmlinux 0x0d874d99 follow_down +EXPORT_SYMBOL vmlinux 0x0d8819a9 get_unmapped_area +EXPORT_SYMBOL vmlinux 0x0d8ab500 param_set_copystring +EXPORT_SYMBOL vmlinux 0x0d976f60 km_policy_notify +EXPORT_SYMBOL vmlinux 0x0dbce072 kmem_cache_free +EXPORT_SYMBOL vmlinux 0x0dc492c1 dma_free_coherent +EXPORT_SYMBOL vmlinux 0x0dd76158 kmem_ptr_validate +EXPORT_SYMBOL vmlinux 0x0de81826 inet_twsk_deschedule +EXPORT_SYMBOL vmlinux 0x0dff6e53 follow_up +EXPORT_SYMBOL vmlinux 0x0e524692 thaw_bdev +EXPORT_SYMBOL vmlinux 0x0e52592a panic +EXPORT_SYMBOL vmlinux 0x0e762d6e request_module +EXPORT_SYMBOL vmlinux 0x0e85b8a4 skb_store_bits +EXPORT_SYMBOL vmlinux 0x0f1ef871 posix_acl_alloc +EXPORT_SYMBOL vmlinux 0x0f951d0c fifo_create_dflt +EXPORT_SYMBOL vmlinux 0x0fa28816 blk_init_tags +EXPORT_SYMBOL vmlinux 0x0fa2a45e __memzero +EXPORT_SYMBOL vmlinux 0x0fc586ba down_trylock +EXPORT_SYMBOL vmlinux 0x0fcebab9 dma_pool_create +EXPORT_SYMBOL vmlinux 0x0fef57d1 remove_inode_hash +EXPORT_SYMBOL vmlinux 0x0ff0a224 sock_no_listen +EXPORT_SYMBOL vmlinux 0x0ff178f6 __aeabi_idivmod +EXPORT_SYMBOL vmlinux 0x10158803 sock_no_ioctl +EXPORT_SYMBOL vmlinux 0x103ba986 register_con_driver +EXPORT_SYMBOL vmlinux 0x10579454 sg_copy_from_buffer +EXPORT_SYMBOL vmlinux 0x106bf50d pci_enable_wake +EXPORT_SYMBOL vmlinux 0x1072a394 csum_partial_copy_from_user +EXPORT_SYMBOL vmlinux 0x10bbf072 gnet_stats_start_copy_compat +EXPORT_SYMBOL vmlinux 0x10ee20bb default_blu +EXPORT_SYMBOL vmlinux 0x111bcb2c groups_free +EXPORT_SYMBOL vmlinux 0x11267875 scsi_extd_sense_format +EXPORT_SYMBOL vmlinux 0x1163f0a7 blk_max_low_pfn +EXPORT_SYMBOL vmlinux 0x117093be qdisc_class_hash_init +EXPORT_SYMBOL vmlinux 0x119b50e7 elf_check_arch +EXPORT_SYMBOL vmlinux 0x11eb0b4a __scm_destroy +EXPORT_SYMBOL vmlinux 0x120c8896 blk_rq_map_user +EXPORT_SYMBOL vmlinux 0x126970ed param_set_uint +EXPORT_SYMBOL vmlinux 0x127c8255 inet_del_protocol +EXPORT_SYMBOL vmlinux 0x12da5bb2 __kmalloc +EXPORT_SYMBOL vmlinux 0x12dd0e91 generic_file_splice_write +EXPORT_SYMBOL vmlinux 0x12ee5607 pci_save_state +EXPORT_SYMBOL vmlinux 0x1308eb53 pcix_get_mmrbc +EXPORT_SYMBOL vmlinux 0x13266092 put_io_context +EXPORT_SYMBOL vmlinux 0x132f45f2 cookie_check_timestamp +EXPORT_SYMBOL vmlinux 0x133a60ec scsi_rescan_device +EXPORT_SYMBOL vmlinux 0x13837d11 clear_bdi_congested +EXPORT_SYMBOL vmlinux 0x13c1485e __bread +EXPORT_SYMBOL vmlinux 0x13ce2070 file_fsync +EXPORT_SYMBOL vmlinux 0x13f482c3 sock_no_setsockopt +EXPORT_SYMBOL vmlinux 0x13fef804 xfrm_state_check_expire +EXPORT_SYMBOL vmlinux 0x140b43b5 generic_read_dir +EXPORT_SYMBOL vmlinux 0x1415d4d9 call_usermodehelper_setkeys +EXPORT_SYMBOL vmlinux 0x14448d4a page_put_link +EXPORT_SYMBOL vmlinux 0x144ed3a1 dev_base_lock +EXPORT_SYMBOL vmlinux 0x14d78fa5 __xfrm_state_destroy +EXPORT_SYMBOL vmlinux 0x1502d40d xscale_flush_user_cache_range +EXPORT_SYMBOL vmlinux 0x151a4de6 __vlan_hwaccel_rx +EXPORT_SYMBOL vmlinux 0x1544aad4 genl_register_mc_group +EXPORT_SYMBOL vmlinux 0x1551dc51 bitmap_find_free_region +EXPORT_SYMBOL vmlinux 0x1569113f kernel_listen +EXPORT_SYMBOL vmlinux 0x156d7523 xfrm_unregister_mode +EXPORT_SYMBOL vmlinux 0x15d7aa3a tty_insert_flip_string_flags +EXPORT_SYMBOL vmlinux 0x15f50595 sock_kfree_s +EXPORT_SYMBOL vmlinux 0x163f906a block_prepare_write +EXPORT_SYMBOL vmlinux 0x16466a3c tcp_close +EXPORT_SYMBOL vmlinux 0x16479e8f panic_notifier_list +EXPORT_SYMBOL vmlinux 0x167be642 ip_mc_join_group +EXPORT_SYMBOL vmlinux 0x1684bf43 destroy_EII_client +EXPORT_SYMBOL vmlinux 0x168d215d km_policy_expired +EXPORT_SYMBOL vmlinux 0x16e80399 eth_header_cache_update +EXPORT_SYMBOL vmlinux 0x1716759d poll_freewait +EXPORT_SYMBOL vmlinux 0x179d4881 cap_netlink_recv +EXPORT_SYMBOL vmlinux 0x17a76e71 rb_first +EXPORT_SYMBOL vmlinux 0x17c0e626 bio_map_kern +EXPORT_SYMBOL vmlinux 0x17df17bc sysctl_tcp_ecn +EXPORT_SYMBOL vmlinux 0x18118eca __pskb_pull_tail +EXPORT_SYMBOL vmlinux 0x1817f51a generic_file_buffered_write +EXPORT_SYMBOL vmlinux 0x1823cefe journal_force_commit +EXPORT_SYMBOL vmlinux 0x183fa88b mempool_alloc_slab +EXPORT_SYMBOL vmlinux 0x1888b287 sk_common_release +EXPORT_SYMBOL vmlinux 0x18b07eb3 end_buffer_write_sync +EXPORT_SYMBOL vmlinux 0x18bdf7c3 npe_send_message +EXPORT_SYMBOL vmlinux 0x18cd2b27 sock_get_timestampns +EXPORT_SYMBOL vmlinux 0x18f3146c inet_frags_fini +EXPORT_SYMBOL vmlinux 0x19020699 journal_wipe +EXPORT_SYMBOL vmlinux 0x193d78a6 simple_write_end +EXPORT_SYMBOL vmlinux 0x194cf6ce vc_cons +EXPORT_SYMBOL vmlinux 0x199d63eb nf_register_hook +EXPORT_SYMBOL vmlinux 0x199ed0cd net_disable_timestamp +EXPORT_SYMBOL vmlinux 0x19a13bff register_netdev +EXPORT_SYMBOL vmlinux 0x1a18d01c ethtool_op_set_tx_hw_csum +EXPORT_SYMBOL vmlinux 0x1a36ff12 neigh_for_each +EXPORT_SYMBOL vmlinux 0x1a65f4ad __arm_ioremap_pfn +EXPORT_SYMBOL vmlinux 0x1a758117 simple_transaction_read +EXPORT_SYMBOL vmlinux 0x1a787f86 input_unregister_device +EXPORT_SYMBOL vmlinux 0x1a7e0940 console_start +EXPORT_SYMBOL vmlinux 0x1ac0e83d tcp_v4_send_check +EXPORT_SYMBOL vmlinux 0x1ace138d bitmap_allocate_region +EXPORT_SYMBOL vmlinux 0x1ad1f2e7 _memcpy_fromio +EXPORT_SYMBOL vmlinux 0x1ad4fc84 scsi_is_target_device +EXPORT_SYMBOL vmlinux 0x1adf990a call_usermodehelper_stdinpipe +EXPORT_SYMBOL vmlinux 0x1ae8d7dc param_set_invbool +EXPORT_SYMBOL vmlinux 0x1af6ae4f init_mm +EXPORT_SYMBOL vmlinux 0x1b015d25 bitmap_parselist +EXPORT_SYMBOL vmlinux 0x1b6314fd in_aton +EXPORT_SYMBOL vmlinux 0x1b9981cc set_irq_wake +EXPORT_SYMBOL vmlinux 0x1b9e0ff1 scsilun_to_int +EXPORT_SYMBOL vmlinux 0x1bbf5fc4 pci_bus_assign_resources +EXPORT_SYMBOL vmlinux 0x1be8157e kernel_getsockopt +EXPORT_SYMBOL vmlinux 0x1c0910e4 sysctl_data +EXPORT_SYMBOL vmlinux 0x1c324357 idr_replace +EXPORT_SYMBOL vmlinux 0x1c34c232 elv_next_request +EXPORT_SYMBOL vmlinux 0x1c3da6e6 nf_afinfo +EXPORT_SYMBOL vmlinux 0x1c3f2ecb journal_get_create_access +EXPORT_SYMBOL vmlinux 0x1c5daede input_inject_event +EXPORT_SYMBOL vmlinux 0x1c713908 zero_fill_bio +EXPORT_SYMBOL vmlinux 0x1cbd5d70 sock_no_sendmsg +EXPORT_SYMBOL vmlinux 0x1cc10e34 __scsi_put_command +EXPORT_SYMBOL vmlinux 0x1cc6719a register_reboot_notifier +EXPORT_SYMBOL vmlinux 0x1cda75d8 __sk_mem_schedule +EXPORT_SYMBOL vmlinux 0x1d0aaf41 scsi_kmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x1d394d01 pci_set_consistent_dma_mask +EXPORT_SYMBOL vmlinux 0x1d42e39f sync_page_range_nolock +EXPORT_SYMBOL vmlinux 0x1d52c5d0 npe_running +EXPORT_SYMBOL vmlinux 0x1d79c854 rtnl_unicast +EXPORT_SYMBOL vmlinux 0x1d7cddd5 set_device_ro +EXPORT_SYMBOL vmlinux 0x1d902c95 dev_set_mac_address +EXPORT_SYMBOL vmlinux 0x1dfc3201 udp_ioctl +EXPORT_SYMBOL vmlinux 0x1e49daa8 sg_init_one +EXPORT_SYMBOL vmlinux 0x1e6d26a8 strstr +EXPORT_SYMBOL vmlinux 0x1ea36c85 input_unregister_handle +EXPORT_SYMBOL vmlinux 0x1ec45a71 uart_update_timeout +EXPORT_SYMBOL vmlinux 0x1ecb9943 posix_acl_to_xattr +EXPORT_SYMBOL vmlinux 0x1edc9598 _atomic_dec_and_lock +EXPORT_SYMBOL vmlinux 0x1efe283f __cap_full_set +EXPORT_SYMBOL vmlinux 0x1f13fcdf tcf_hash_create +EXPORT_SYMBOL vmlinux 0x1f19f0ec sysctl_ms_jiffies +EXPORT_SYMBOL vmlinux 0x1f368a16 journal_destroy +EXPORT_SYMBOL vmlinux 0x1f64e7d7 netif_carrier_off +EXPORT_SYMBOL vmlinux 0x1f70d32d dma_cache_maint +EXPORT_SYMBOL vmlinux 0x1f73ad3f netpoll_print_options +EXPORT_SYMBOL vmlinux 0x1f7cc628 mempool_create +EXPORT_SYMBOL vmlinux 0x1f871a7d find_task_by_pid_ns +EXPORT_SYMBOL vmlinux 0x1fae7a0b wait_for_completion_timeout +EXPORT_SYMBOL vmlinux 0x1fc144c6 tty_flip_buffer_push +EXPORT_SYMBOL vmlinux 0x1fc91fb2 request_irq +EXPORT_SYMBOL vmlinux 0x20000329 simple_strtoul +EXPORT_SYMBOL vmlinux 0x209631b4 blk_verify_command +EXPORT_SYMBOL vmlinux 0x20ec6d13 __inet6_lookup_established +EXPORT_SYMBOL vmlinux 0x20f63e5e request_firmware +EXPORT_SYMBOL vmlinux 0x20f84a6a lock_may_write +EXPORT_SYMBOL vmlinux 0x211331fa __divsi3 +EXPORT_SYMBOL vmlinux 0x211d3391 block_sync_page +EXPORT_SYMBOL vmlinux 0x21220423 tty_devnum +EXPORT_SYMBOL vmlinux 0x215ebd78 bitrev16 +EXPORT_SYMBOL vmlinux 0x2190c4cf truncate_inode_pages_range +EXPORT_SYMBOL vmlinux 0x21d495ae inode_get_bytes +EXPORT_SYMBOL vmlinux 0x21e1268d scsi_device_put +EXPORT_SYMBOL vmlinux 0x222e7ce2 sysfs_streq +EXPORT_SYMBOL vmlinux 0x226672f1 elv_queue_empty +EXPORT_SYMBOL vmlinux 0x226e86a9 audit_log +EXPORT_SYMBOL vmlinux 0x22842092 pskb_expand_head +EXPORT_SYMBOL vmlinux 0x2288378f system_state +EXPORT_SYMBOL vmlinux 0x229cfd5b gen_new_estimator +EXPORT_SYMBOL vmlinux 0x22b325d5 kd_mksound +EXPORT_SYMBOL vmlinux 0x22b6533b xfrm_sad_getinfo +EXPORT_SYMBOL vmlinux 0x22f11670 sock_sendmsg +EXPORT_SYMBOL vmlinux 0x22f79d89 kernel_bind +EXPORT_SYMBOL vmlinux 0x2317726e scsi_host_alloc +EXPORT_SYMBOL vmlinux 0x231cf494 up_write +EXPORT_SYMBOL vmlinux 0x23269a13 strict_strtoul +EXPORT_SYMBOL vmlinux 0x23311017 __dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0x23838107 __down_write +EXPORT_SYMBOL vmlinux 0x239de09c kblockd_schedule_work +EXPORT_SYMBOL vmlinux 0x23df853c sock_common_getsockopt +EXPORT_SYMBOL vmlinux 0x23e22a0d stop_tty +EXPORT_SYMBOL vmlinux 0x23f5fc07 __xfrm_policy_check +EXPORT_SYMBOL vmlinux 0x23fa14ef inet_getname +EXPORT_SYMBOL vmlinux 0x23fd3028 vmalloc_node +EXPORT_SYMBOL vmlinux 0x244929eb bio_alloc_bioset +EXPORT_SYMBOL vmlinux 0x2455c156 __clear_user +EXPORT_SYMBOL vmlinux 0x2459bbcc console_set_on_cmdline +EXPORT_SYMBOL vmlinux 0x248874cc kernel_sendpage +EXPORT_SYMBOL vmlinux 0x248e7ab5 __set_page_dirty_nobuffers +EXPORT_SYMBOL vmlinux 0x24b0a661 nf_unregister_queue_handler +EXPORT_SYMBOL vmlinux 0x24bff699 cont_write_begin +EXPORT_SYMBOL vmlinux 0x24ce454f tty_unthrottle +EXPORT_SYMBOL vmlinux 0x24fdac79 wake_bit_function +EXPORT_SYMBOL vmlinux 0x250113b4 memory_read_from_buffer +EXPORT_SYMBOL vmlinux 0x2537bacb tcf_hash_destroy +EXPORT_SYMBOL vmlinux 0x254454e0 nonseekable_open +EXPORT_SYMBOL vmlinux 0x2557b624 ip_fragment +EXPORT_SYMBOL vmlinux 0x256887e1 warn_slowpath +EXPORT_SYMBOL vmlinux 0x25820c64 fs_overflowuid +EXPORT_SYMBOL vmlinux 0x25928c63 gen_replace_estimator +EXPORT_SYMBOL vmlinux 0x25a3a763 skb_dma_unmap +EXPORT_SYMBOL vmlinux 0x25ba121c mempool_resize +EXPORT_SYMBOL vmlinux 0x25e22891 kill_fasync +EXPORT_SYMBOL vmlinux 0x25fa6f17 wait_for_completion +EXPORT_SYMBOL vmlinux 0x2606b70a cfi_read_pri +EXPORT_SYMBOL vmlinux 0x261c1766 __backtrace +EXPORT_SYMBOL vmlinux 0x2623f750 dev_add_pack +EXPORT_SYMBOL vmlinux 0x26477c07 __vmalloc +EXPORT_SYMBOL vmlinux 0x267fc65b __tasklet_hi_schedule +EXPORT_SYMBOL vmlinux 0x2692c940 proc_create_data +EXPORT_SYMBOL vmlinux 0x26d7f03b textsearch_prepare +EXPORT_SYMBOL vmlinux 0x26e76fb8 sysctl_udp_wmem_min +EXPORT_SYMBOL vmlinux 0x271ec847 kmem_cache_size +EXPORT_SYMBOL vmlinux 0x272657db scsi_release_buffers +EXPORT_SYMBOL vmlinux 0x272c509a pci_get_subsys +EXPORT_SYMBOL vmlinux 0x272e7488 cond_resched_softirq +EXPORT_SYMBOL vmlinux 0x2755ed35 netlink_kernel_create +EXPORT_SYMBOL vmlinux 0x2765b034 neigh_seq_stop +EXPORT_SYMBOL vmlinux 0x27864d57 memparse +EXPORT_SYMBOL vmlinux 0x27a9a7eb ns_to_timespec +EXPORT_SYMBOL vmlinux 0x27bbf221 disable_irq_nosync +EXPORT_SYMBOL vmlinux 0x27c61ece qdisc_put_stab +EXPORT_SYMBOL vmlinux 0x27ece5c1 qmgr_regs +EXPORT_SYMBOL vmlinux 0x27ee096c blk_queue_update_dma_pad +EXPORT_SYMBOL vmlinux 0x28118cb6 __get_user_1 +EXPORT_SYMBOL vmlinux 0x281cbc32 ethtool_op_set_tx_ipv6_csum +EXPORT_SYMBOL vmlinux 0x2833c284 __brelse +EXPORT_SYMBOL vmlinux 0x28489a5b ethtool_op_set_tso +EXPORT_SYMBOL vmlinux 0x285ac517 strict_strtoll +EXPORT_SYMBOL vmlinux 0x28758681 bh_uptodate_or_lock +EXPORT_SYMBOL vmlinux 0x2881fe3f scsi_command_normalize_sense +EXPORT_SYMBOL vmlinux 0x28a2ed02 scsi_build_sense_buffer +EXPORT_SYMBOL vmlinux 0x28a3166e kobject_get +EXPORT_SYMBOL vmlinux 0x28da14eb nobh_truncate_page +EXPORT_SYMBOL vmlinux 0x28dcf25c udplite_hash +EXPORT_SYMBOL vmlinux 0x29148969 schedule_delayed_work +EXPORT_SYMBOL vmlinux 0x2916b831 pcibios_resource_to_bus +EXPORT_SYMBOL vmlinux 0x293b59ed qmgr_request_queue +EXPORT_SYMBOL vmlinux 0x29537c9e alloc_chrdev_region +EXPORT_SYMBOL vmlinux 0x29634306 ip_queue_xmit +EXPORT_SYMBOL vmlinux 0x29b962ef kmalloc_caches +EXPORT_SYMBOL vmlinux 0x29bd4c46 __cap_init_eff_set +EXPORT_SYMBOL vmlinux 0x29c95c14 path_get +EXPORT_SYMBOL vmlinux 0x29f91fe0 xfrm_state_register_afinfo +EXPORT_SYMBOL vmlinux 0x29fc177c skb_pad +EXPORT_SYMBOL vmlinux 0x2a138740 sync_blockdev +EXPORT_SYMBOL vmlinux 0x2a1aff9e bio_alloc +EXPORT_SYMBOL vmlinux 0x2a2cf8c8 nf_unregister_sockopt +EXPORT_SYMBOL vmlinux 0x2a460682 inetdev_by_index +EXPORT_SYMBOL vmlinux 0x2a520acc xfrm_policy_bysel_ctx +EXPORT_SYMBOL vmlinux 0x2a5e9d9a dev_load +EXPORT_SYMBOL vmlinux 0x2a63bbcc do_splice_to +EXPORT_SYMBOL vmlinux 0x2a957466 simple_statfs +EXPORT_SYMBOL vmlinux 0x2aa0e4fc strncasecmp +EXPORT_SYMBOL vmlinux 0x2aad338c journal_update_format +EXPORT_SYMBOL vmlinux 0x2acb4a38 shrink_dcache_sb +EXPORT_SYMBOL vmlinux 0x2af4d708 sock_wake_async +EXPORT_SYMBOL vmlinux 0x2b09725e input_free_device +EXPORT_SYMBOL vmlinux 0x2b0ba2b0 scsi_sense_desc_find +EXPORT_SYMBOL vmlinux 0x2b11bf13 scsi_init_io +EXPORT_SYMBOL vmlinux 0x2b40baff __down_write_nested +EXPORT_SYMBOL vmlinux 0x2b570dc0 ida_pre_get +EXPORT_SYMBOL vmlinux 0x2ba707a8 sysctl_tcp_low_latency +EXPORT_SYMBOL vmlinux 0x2c0cca2c d_instantiate +EXPORT_SYMBOL vmlinux 0x2c154736 sg_miter_start +EXPORT_SYMBOL vmlinux 0x2c484855 vlan_ioctl_set +EXPORT_SYMBOL vmlinux 0x2c4dd031 bio_phys_segments +EXPORT_SYMBOL vmlinux 0x2c920b76 sock_common_recvmsg +EXPORT_SYMBOL vmlinux 0x2c9b0505 dcache_dir_open +EXPORT_SYMBOL vmlinux 0x2ccbb016 journal_abort +EXPORT_SYMBOL vmlinux 0x2cd9e459 param_set_short +EXPORT_SYMBOL vmlinux 0x2d0f0443 ethtool_op_set_tx_csum +EXPORT_SYMBOL vmlinux 0x2d22eb66 sock_wfree +EXPORT_SYMBOL vmlinux 0x2d33316e textsearch_find_continuous +EXPORT_SYMBOL vmlinux 0x2d50ee34 __devm_request_region +EXPORT_SYMBOL vmlinux 0x2d6507b5 _find_next_zero_bit_le +EXPORT_SYMBOL vmlinux 0x2d89342a scsi_show_sense_hdr +EXPORT_SYMBOL vmlinux 0x2da30dc4 kmem_cache_alloc +EXPORT_SYMBOL vmlinux 0x2de9f66f param_get_long +EXPORT_SYMBOL vmlinux 0x2df0046c iget_failed +EXPORT_SYMBOL vmlinux 0x2e1cbbf7 read_cache_pages +EXPORT_SYMBOL vmlinux 0x2e2ce9e0 sysctl_tcp_syncookies +EXPORT_SYMBOL vmlinux 0x2e4a39f8 sysctl_udp_mem +EXPORT_SYMBOL vmlinux 0x2e6c92ef tcp_create_openreq_child +EXPORT_SYMBOL vmlinux 0x2e8856ce proc_dointvec_ms_jiffies +EXPORT_SYMBOL vmlinux 0x2e9beacd inet_sendmsg +EXPORT_SYMBOL vmlinux 0x2ea9f88e blk_register_region +EXPORT_SYMBOL vmlinux 0x2ec8d942 mark_page_accessed +EXPORT_SYMBOL vmlinux 0x2ecab3fe udplite_prot +EXPORT_SYMBOL vmlinux 0x2edb9ef3 pci_wake_from_d3 +EXPORT_SYMBOL vmlinux 0x2ef953f8 dev_alloc_name +EXPORT_SYMBOL vmlinux 0x2f6c2964 pci_enable_device_io +EXPORT_SYMBOL vmlinux 0x2f933cd3 sysctl_jiffies +EXPORT_SYMBOL vmlinux 0x2fa7a4ae start_tty +EXPORT_SYMBOL vmlinux 0x3020edf0 __skb_warn_lro_forwarding +EXPORT_SYMBOL vmlinux 0x304b0df9 netlink_dump_start +EXPORT_SYMBOL vmlinux 0x3072ca38 tcf_exts_change +EXPORT_SYMBOL vmlinux 0x30752b8f blk_get_request +EXPORT_SYMBOL vmlinux 0x30844739 inet_select_addr +EXPORT_SYMBOL vmlinux 0x30a290b7 dst_alloc +EXPORT_SYMBOL vmlinux 0x30a3961f __invalidate_device +EXPORT_SYMBOL vmlinux 0x30e4d614 xfrm_state_alloc +EXPORT_SYMBOL vmlinux 0x30e74134 tty_termios_copy_hw +EXPORT_SYMBOL vmlinux 0x3105407b cdev_alloc +EXPORT_SYMBOL vmlinux 0x310917fe sort +EXPORT_SYMBOL vmlinux 0x31142ac9 bh_submit_read +EXPORT_SYMBOL vmlinux 0x311c11ef dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0x313341a3 _set_bit_le +EXPORT_SYMBOL vmlinux 0x3145216f pci_dev_present +EXPORT_SYMBOL vmlinux 0x3147857d default_red +EXPORT_SYMBOL vmlinux 0x3166f5ca blk_sync_queue +EXPORT_SYMBOL vmlinux 0x3181466f path_permission +EXPORT_SYMBOL vmlinux 0x31889471 do_sync_read +EXPORT_SYMBOL vmlinux 0x318c997b npe_release +EXPORT_SYMBOL vmlinux 0x3192b3c9 dev_set_mtu +EXPORT_SYMBOL vmlinux 0x31a68463 may_umount_tree +EXPORT_SYMBOL vmlinux 0x31b31f5c csum_partial_copy_nocheck +EXPORT_SYMBOL vmlinux 0x32109579 tcf_action_exec +EXPORT_SYMBOL vmlinux 0x321f64c5 copy_strings_kernel +EXPORT_SYMBOL vmlinux 0x323222ba mutex_unlock +EXPORT_SYMBOL vmlinux 0x326cf83e ip_generic_getfrag +EXPORT_SYMBOL vmlinux 0x328a05f1 strncpy +EXPORT_SYMBOL vmlinux 0x32931aaa kobject_put +EXPORT_SYMBOL vmlinux 0x32ce623a sg_last +EXPORT_SYMBOL vmlinux 0x33291b5a xfrm_state_delete +EXPORT_SYMBOL vmlinux 0x3343bec0 scsi_execute +EXPORT_SYMBOL vmlinux 0x33599080 skb_copy_and_csum_dev +EXPORT_SYMBOL vmlinux 0x3359b28d skb_insert +EXPORT_SYMBOL vmlinux 0x3360a963 param_set_ulong +EXPORT_SYMBOL vmlinux 0x33aea288 __breadahead +EXPORT_SYMBOL vmlinux 0x33c5a1ff simple_link +EXPORT_SYMBOL vmlinux 0x33ce6583 seq_read +EXPORT_SYMBOL vmlinux 0x33f3fa35 skb_checksum +EXPORT_SYMBOL vmlinux 0x34472028 tty_port_tty_set +EXPORT_SYMBOL vmlinux 0x34533bef tty_check_change +EXPORT_SYMBOL vmlinux 0x34908c14 print_hex_dump_bytes +EXPORT_SYMBOL vmlinux 0x349b4ed3 dmabounce_register_dev +EXPORT_SYMBOL vmlinux 0x349cba85 strchr +EXPORT_SYMBOL vmlinux 0x34c4dd95 uart_suspend_port +EXPORT_SYMBOL vmlinux 0x353e3fa5 __get_user_4 +EXPORT_SYMBOL vmlinux 0x35481b84 inet_put_port +EXPORT_SYMBOL vmlinux 0x359103fe bioset_create +EXPORT_SYMBOL vmlinux 0x35a27515 pci_unregister_driver +EXPORT_SYMBOL vmlinux 0x35e4d7ed set_disk_ro +EXPORT_SYMBOL vmlinux 0x3603f1a1 blk_queue_stack_limits +EXPORT_SYMBOL vmlinux 0x360b1afe probe_irq_mask +EXPORT_SYMBOL vmlinux 0x361b579b generic_block_fiemap +EXPORT_SYMBOL vmlinux 0x363ad247 cap_set_effective +EXPORT_SYMBOL vmlinux 0x366bdeaa init_timer +EXPORT_SYMBOL vmlinux 0x369de5c2 scsi_prep_return +EXPORT_SYMBOL vmlinux 0x36b6cb8d kill_anon_super +EXPORT_SYMBOL vmlinux 0x36bea522 single_open +EXPORT_SYMBOL vmlinux 0x36d9f441 inode_permission +EXPORT_SYMBOL vmlinux 0x36dcfa44 netlink_clear_multicast_users +EXPORT_SYMBOL vmlinux 0x36e47222 remove_wait_queue +EXPORT_SYMBOL vmlinux 0x372251a4 vfs_create +EXPORT_SYMBOL vmlinux 0x37288b52 ethtool_op_set_sg +EXPORT_SYMBOL vmlinux 0x372906c4 xfrm_state_walk +EXPORT_SYMBOL vmlinux 0x3744cf36 vmalloc_to_pfn +EXPORT_SYMBOL vmlinux 0x374ed073 scnprintf +EXPORT_SYMBOL vmlinux 0x376437f1 uart_unregister_driver +EXPORT_SYMBOL vmlinux 0x37773e0c unregister_con_driver +EXPORT_SYMBOL vmlinux 0x3778e40c inode_add_bytes +EXPORT_SYMBOL vmlinux 0x378cbcf3 scsi_cmd_print_sense_hdr +EXPORT_SYMBOL vmlinux 0x37af6a0a abort_exclusive_wait +EXPORT_SYMBOL vmlinux 0x37befc70 jiffies_to_msecs +EXPORT_SYMBOL vmlinux 0x37dc8ee3 find_get_pages_tag +EXPORT_SYMBOL vmlinux 0x37e74642 get_jiffies_64 +EXPORT_SYMBOL vmlinux 0x37f0f8c5 gnet_stats_copy_queue +EXPORT_SYMBOL vmlinux 0x37f0fbba seq_release_private +EXPORT_SYMBOL vmlinux 0x37feffb9 udp_disconnect +EXPORT_SYMBOL vmlinux 0x38321f87 neigh_event_ns +EXPORT_SYMBOL vmlinux 0x383c9a0e scsi_host_get +EXPORT_SYMBOL vmlinux 0x3845a7a2 dmam_free_noncoherent +EXPORT_SYMBOL vmlinux 0x386cbb3b input_open_device +EXPORT_SYMBOL vmlinux 0x387c0967 vfs_lstat +EXPORT_SYMBOL vmlinux 0x388f9128 xfrm_state_walk_done +EXPORT_SYMBOL vmlinux 0x38d25848 elv_dispatch_sort +EXPORT_SYMBOL vmlinux 0x38dcc3ce sysctl_intvec +EXPORT_SYMBOL vmlinux 0x38e19864 dma_mmap_writecombine +EXPORT_SYMBOL vmlinux 0x38e8378d pgprot_kernel +EXPORT_SYMBOL vmlinux 0x38fea837 sock_no_sendpage +EXPORT_SYMBOL vmlinux 0x39059633 ip_mc_dec_group +EXPORT_SYMBOL vmlinux 0x3980aac1 unregister_reboot_notifier +EXPORT_SYMBOL vmlinux 0x39f78d31 is_bad_inode +EXPORT_SYMBOL vmlinux 0x39fbea9b __neigh_for_each_release +EXPORT_SYMBOL vmlinux 0x3a04ee8e __scsi_add_device +EXPORT_SYMBOL vmlinux 0x3a209f61 __napi_schedule +EXPORT_SYMBOL vmlinux 0x3a2e30c2 copy_io_context +EXPORT_SYMBOL vmlinux 0x3a515ac6 blk_queue_merge_bvec +EXPORT_SYMBOL vmlinux 0x3a9b6fb9 blk_unregister_region +EXPORT_SYMBOL vmlinux 0x3aa200e1 xfrm_policy_destroy +EXPORT_SYMBOL vmlinux 0x3ab2d174 down_killable +EXPORT_SYMBOL vmlinux 0x3abd8a5d blk_remove_plug +EXPORT_SYMBOL vmlinux 0x3adc15b9 posix_acl_from_mode +EXPORT_SYMBOL vmlinux 0x3ae240fa tcf_unregister_action +EXPORT_SYMBOL vmlinux 0x3ae831b6 kref_init +EXPORT_SYMBOL vmlinux 0x3aedd637 pci_request_region +EXPORT_SYMBOL vmlinux 0x3b59f7c1 journal_load +EXPORT_SYMBOL vmlinux 0x3b5dc870 __lock_page +EXPORT_SYMBOL vmlinux 0x3b79162a give_up_console +EXPORT_SYMBOL vmlinux 0x3b81d213 xfrm_policy_register_afinfo +EXPORT_SYMBOL vmlinux 0x3b9cfd2a dma_map_single +EXPORT_SYMBOL vmlinux 0x3bd1b1f6 msecs_to_jiffies +EXPORT_SYMBOL vmlinux 0x3bdd030e input_register_handle +EXPORT_SYMBOL vmlinux 0x3bfc785d blk_requeue_request +EXPORT_SYMBOL vmlinux 0x3c025f57 proc_dointvec_minmax +EXPORT_SYMBOL vmlinux 0x3c0345ec sock_no_shutdown +EXPORT_SYMBOL vmlinux 0x3c2c5af5 sprintf +EXPORT_SYMBOL vmlinux 0x3c4e42f1 do_map_probe +EXPORT_SYMBOL vmlinux 0x3c540687 inode_change_ok +EXPORT_SYMBOL vmlinux 0x3c7e59ba elv_abort_queue +EXPORT_SYMBOL vmlinux 0x3c9d1211 string_get_size +EXPORT_SYMBOL vmlinux 0x3ca71a20 netdev_rx_csum_fault +EXPORT_SYMBOL vmlinux 0x3cac81ae scsi_test_unit_ready +EXPORT_SYMBOL vmlinux 0x3cb8a495 param_get_string +EXPORT_SYMBOL vmlinux 0x3cbfa7c7 wait_on_page_bit +EXPORT_SYMBOL vmlinux 0x3cc0a3bb xfrm_spd_getinfo +EXPORT_SYMBOL vmlinux 0x3ce3a9a7 blk_init_queue_node +EXPORT_SYMBOL vmlinux 0x3ce4ca6f disable_irq +EXPORT_SYMBOL vmlinux 0x3cf999df inet_csk_init_xmit_timers +EXPORT_SYMBOL vmlinux 0x3d1d12d6 clocksource_register +EXPORT_SYMBOL vmlinux 0x3d3c540f elf_hwcap +EXPORT_SYMBOL vmlinux 0x3d4e3221 pci_bus_find_capability +EXPORT_SYMBOL vmlinux 0x3d517a2b dev_queue_xmit +EXPORT_SYMBOL vmlinux 0x3d519116 elv_rb_find +EXPORT_SYMBOL vmlinux 0x3d68bd4b flow_cache_genid +EXPORT_SYMBOL vmlinux 0x3d68d7da mb_cache_entry_find_first +EXPORT_SYMBOL vmlinux 0x3d70b886 vc_resize +EXPORT_SYMBOL vmlinux 0x3d805ced sock_alloc_send_skb +EXPORT_SYMBOL vmlinux 0x3d809f57 __mark_inode_dirty +EXPORT_SYMBOL vmlinux 0x3e108abc ip_ct_attach +EXPORT_SYMBOL vmlinux 0x3e383385 nf_hooks +EXPORT_SYMBOL vmlinux 0x3e45e9ff register_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x3e6caebd add_wait_queue_exclusive +EXPORT_SYMBOL vmlinux 0x3e6d1564 netpoll_parse_options +EXPORT_SYMBOL vmlinux 0x3e777683 sock_map_fd +EXPORT_SYMBOL vmlinux 0x3e95b220 force_sig +EXPORT_SYMBOL vmlinux 0x3ebb18f3 inet_sk_rebuild_header +EXPORT_SYMBOL vmlinux 0x3ecfe3ac input_flush_device +EXPORT_SYMBOL vmlinux 0x3ede9f51 path_put +EXPORT_SYMBOL vmlinux 0x3ef2ba4a test_set_page_writeback +EXPORT_SYMBOL vmlinux 0x3f3e694a iw_handler_set_thrspy +EXPORT_SYMBOL vmlinux 0x3f4547a7 put_unused_fd +EXPORT_SYMBOL vmlinux 0x3f71fa09 scsi_print_sense +EXPORT_SYMBOL vmlinux 0x3f7c6a4a simple_write_begin +EXPORT_SYMBOL vmlinux 0x3f902370 sk_stop_timer +EXPORT_SYMBOL vmlinux 0x3fbdc140 npe_names +EXPORT_SYMBOL vmlinux 0x3fef015e unlock_super +EXPORT_SYMBOL vmlinux 0x3ff386d8 ip_getsockopt +EXPORT_SYMBOL vmlinux 0x3ff62317 local_bh_disable +EXPORT_SYMBOL vmlinux 0x4010d4cf set_anon_super +EXPORT_SYMBOL vmlinux 0x40123aeb idr_for_each +EXPORT_SYMBOL vmlinux 0x404e4a22 check_disk_size_change +EXPORT_SYMBOL vmlinux 0x4059792f print_hex_dump +EXPORT_SYMBOL vmlinux 0x405c1144 get_seconds +EXPORT_SYMBOL vmlinux 0x407136b1 __put_user_8 +EXPORT_SYMBOL vmlinux 0x407d7795 __inode_dir_notify +EXPORT_SYMBOL vmlinux 0x409873e3 tty_termios_baud_rate +EXPORT_SYMBOL vmlinux 0x40a6f522 __arm_ioremap +EXPORT_SYMBOL vmlinux 0x40f07981 __ashldi3 +EXPORT_SYMBOL vmlinux 0x41166725 inet_frags_init_net +EXPORT_SYMBOL vmlinux 0x412c3f0b update_region +EXPORT_SYMBOL vmlinux 0x412ddc0c dcache_lock +EXPORT_SYMBOL vmlinux 0x4137f03c sock_no_socketpair +EXPORT_SYMBOL vmlinux 0x41482d8b strndup_user +EXPORT_SYMBOL vmlinux 0x4155c76b skb_kill_datagram +EXPORT_SYMBOL vmlinux 0x416983d9 netdev_fix_features +EXPORT_SYMBOL vmlinux 0x4185cf4b radix_tree_lookup_slot +EXPORT_SYMBOL vmlinux 0x4188d439 neigh_rand_reach_time +EXPORT_SYMBOL vmlinux 0x4190dfca __xfrm_state_delete +EXPORT_SYMBOL vmlinux 0x41b42f93 remap_pfn_range +EXPORT_SYMBOL vmlinux 0x41e7935e bio_put +EXPORT_SYMBOL vmlinux 0x421cc65b xfrm_policy_delete +EXPORT_SYMBOL vmlinux 0x42224298 sscanf +EXPORT_SYMBOL vmlinux 0x42805c51 bio_uncopy_user +EXPORT_SYMBOL vmlinux 0x429d218a kobject_add +EXPORT_SYMBOL vmlinux 0x42a5f396 unmap_mapping_range +EXPORT_SYMBOL vmlinux 0x42b9b40f pci_set_dma_max_seg_size +EXPORT_SYMBOL vmlinux 0x42fa64a1 mark_buffer_async_write +EXPORT_SYMBOL vmlinux 0x430205aa __sg_alloc_table +EXPORT_SYMBOL vmlinux 0x4302d0eb free_pages +EXPORT_SYMBOL vmlinux 0x4304fa85 __scsi_iterate_devices +EXPORT_SYMBOL vmlinux 0x431b2438 journal_ack_err +EXPORT_SYMBOL vmlinux 0x4346483f dev_mc_sync +EXPORT_SYMBOL vmlinux 0x43492a46 eth_rebuild_header +EXPORT_SYMBOL vmlinux 0x434fa55c release_console_sem +EXPORT_SYMBOL vmlinux 0x436cca53 blk_rq_map_kern +EXPORT_SYMBOL vmlinux 0x43c49da6 register_mtd_chip_driver +EXPORT_SYMBOL vmlinux 0x44161c19 unregister_shrinker +EXPORT_SYMBOL vmlinux 0x44314efb radix_tree_gang_lookup_tag_slot +EXPORT_SYMBOL vmlinux 0x443788bc con_set_default_unimap +EXPORT_SYMBOL vmlinux 0x444779c4 nla_find +EXPORT_SYMBOL vmlinux 0x4449f614 generic_file_splice_write_nolock +EXPORT_SYMBOL vmlinux 0x44575e53 skb_queue_head +EXPORT_SYMBOL vmlinux 0x44643b93 __aeabi_lmul +EXPORT_SYMBOL vmlinux 0x44b911c3 rb_replace_node +EXPORT_SYMBOL vmlinux 0x44c214d1 __wake_up_bit +EXPORT_SYMBOL vmlinux 0x44c7f7f1 sk_wait_data +EXPORT_SYMBOL vmlinux 0x44d722c3 tcp_v4_conn_request +EXPORT_SYMBOL vmlinux 0x44da5d0f __csum_ipv6_magic +EXPORT_SYMBOL vmlinux 0x44e9a829 match_token +EXPORT_SYMBOL vmlinux 0x45255f3b notify_change +EXPORT_SYMBOL vmlinux 0x45339de1 blk_start_queue +EXPORT_SYMBOL vmlinux 0x4574c4f9 ethtool_op_get_flags +EXPORT_SYMBOL vmlinux 0x45a55ec8 __iounmap +EXPORT_SYMBOL vmlinux 0x45a7af55 unlock_rename +EXPORT_SYMBOL vmlinux 0x45a7af5d elv_rb_former_request +EXPORT_SYMBOL vmlinux 0x45bda0d5 system_serial_low +EXPORT_SYMBOL vmlinux 0x45cdc6e4 elv_dispatch_add_tail +EXPORT_SYMBOL vmlinux 0x45d47da4 tcf_exts_dump +EXPORT_SYMBOL vmlinux 0x45e60a49 pneigh_enqueue +EXPORT_SYMBOL vmlinux 0x45fac74f invalidate_mapping_pages +EXPORT_SYMBOL vmlinux 0x462a2e75 match_strlcpy +EXPORT_SYMBOL vmlinux 0x4650d837 arp_find +EXPORT_SYMBOL vmlinux 0x46c35984 pci_back_from_sleep +EXPORT_SYMBOL vmlinux 0x46c4ca0e mark_buffer_dirty_inode +EXPORT_SYMBOL vmlinux 0x46c566e3 task_session_nr_ns +EXPORT_SYMBOL vmlinux 0x46d3b28c __div0 +EXPORT_SYMBOL vmlinux 0x4719ba4e kfifo_free +EXPORT_SYMBOL vmlinux 0x472d2a9a radix_tree_lookup +EXPORT_SYMBOL vmlinux 0x475100c2 inet_get_local_port_range +EXPORT_SYMBOL vmlinux 0x4757bce2 journal_stop +EXPORT_SYMBOL vmlinux 0x476e52f9 pcim_iomap_regions_request_all +EXPORT_SYMBOL vmlinux 0x47c62d70 xfrm_policy_flush +EXPORT_SYMBOL vmlinux 0x47cac3f6 unmap_underlying_metadata +EXPORT_SYMBOL vmlinux 0x47d9ed97 __alloc_pages_internal +EXPORT_SYMBOL vmlinux 0x47f757de elf_platform +EXPORT_SYMBOL vmlinux 0x4859b8bb rtc_year_days +EXPORT_SYMBOL vmlinux 0x48688629 kthread_stop +EXPORT_SYMBOL vmlinux 0x486b6407 hweight64 +EXPORT_SYMBOL vmlinux 0x4878fa56 tty_set_operations +EXPORT_SYMBOL vmlinux 0x48a2e15e arp_send +EXPORT_SYMBOL vmlinux 0x48a5b067 __machine_arch_type +EXPORT_SYMBOL vmlinux 0x48f9f12d complete_all +EXPORT_SYMBOL vmlinux 0x492197a6 pci_bus_read_config_dword +EXPORT_SYMBOL vmlinux 0x493e25e1 udp_hash +EXPORT_SYMBOL vmlinux 0x49446929 block_write_begin +EXPORT_SYMBOL vmlinux 0x495cc075 blk_recount_segments +EXPORT_SYMBOL vmlinux 0x495fb083 create_empty_buffers +EXPORT_SYMBOL vmlinux 0x497118f5 filp_close +EXPORT_SYMBOL vmlinux 0x4979eb57 uart_get_baud_rate +EXPORT_SYMBOL vmlinux 0x49a70ef8 locks_remove_posix +EXPORT_SYMBOL vmlinux 0x49a7f2f0 pci_try_set_mwi +EXPORT_SYMBOL vmlinux 0x49b8600c nf_unregister_hook +EXPORT_SYMBOL vmlinux 0x49d661d8 nf_reinject +EXPORT_SYMBOL vmlinux 0x4a0f64e7 scsi_get_command +EXPORT_SYMBOL vmlinux 0x4a1a8843 udp_sendmsg +EXPORT_SYMBOL vmlinux 0x4a2425ef udp_prot +EXPORT_SYMBOL vmlinux 0x4a358252 __bitmap_subset +EXPORT_SYMBOL vmlinux 0x4a6be018 seq_open +EXPORT_SYMBOL vmlinux 0x4a971ec7 radix_tree_delete +EXPORT_SYMBOL vmlinux 0x4acd0c2c __break_lease +EXPORT_SYMBOL vmlinux 0x4acfd8ad down_interruptible +EXPORT_SYMBOL vmlinux 0x4ad9a6fe xscale_mc_copy_user_page +EXPORT_SYMBOL vmlinux 0x4ae76638 neigh_resolve_output +EXPORT_SYMBOL vmlinux 0x4aea4791 __strncpy_from_user +EXPORT_SYMBOL vmlinux 0x4af4a833 tty_port_free_xmit_buf +EXPORT_SYMBOL vmlinux 0x4afe9a77 scsi_partsize +EXPORT_SYMBOL vmlinux 0x4b06902f pci_get_device +EXPORT_SYMBOL vmlinux 0x4b0d176f inet_shutdown +EXPORT_SYMBOL vmlinux 0x4b1ed313 d_delete +EXPORT_SYMBOL vmlinux 0x4b2f14b4 jiffies_to_timespec +EXPORT_SYMBOL vmlinux 0x4b34fbf5 block_all_signals +EXPORT_SYMBOL vmlinux 0x4b409d78 netpoll_send_udp +EXPORT_SYMBOL vmlinux 0x4b8edde9 complete_and_exit +EXPORT_SYMBOL vmlinux 0x4b9f3684 kfifo_init +EXPORT_SYMBOL vmlinux 0x4ba097f5 ixp4xx_pci_write +EXPORT_SYMBOL vmlinux 0x4bae2067 cpu_sysdev_class +EXPORT_SYMBOL vmlinux 0x4bb81a72 vfs_permission +EXPORT_SYMBOL vmlinux 0x4bdad456 block_write_full_page +EXPORT_SYMBOL vmlinux 0x4bf5168e skb_copy +EXPORT_SYMBOL vmlinux 0x4bf9707d pcibios_fixup_bus +EXPORT_SYMBOL vmlinux 0x4c1182cb bitmap_scnprintf +EXPORT_SYMBOL vmlinux 0x4c3894c4 __wait_on_buffer +EXPORT_SYMBOL vmlinux 0x4c5275b0 dma_alloc_writecombine +EXPORT_SYMBOL vmlinux 0x4cbbd171 __bitmap_weight +EXPORT_SYMBOL vmlinux 0x4cc0e074 block_write_end +EXPORT_SYMBOL vmlinux 0x4ce3907c lock_rename +EXPORT_SYMBOL vmlinux 0x4d0d163d copy_page +EXPORT_SYMBOL vmlinux 0x4d12333f iunique +EXPORT_SYMBOL vmlinux 0x4d18a642 generic_splice_sendpage +EXPORT_SYMBOL vmlinux 0x4d221fd3 blk_plug_device +EXPORT_SYMBOL vmlinux 0x4d3c153f sigprocmask +EXPORT_SYMBOL vmlinux 0x4d538f3f pci_request_regions +EXPORT_SYMBOL vmlinux 0x4d54813b qdisc_class_hash_grow +EXPORT_SYMBOL vmlinux 0x4d6214d7 boot_tvec_bases +EXPORT_SYMBOL vmlinux 0x4dc22cba pci_restore_state +EXPORT_SYMBOL vmlinux 0x4de8539b scsi_host_set_state +EXPORT_SYMBOL vmlinux 0x4dec6038 memscan +EXPORT_SYMBOL vmlinux 0x4df119fa __bitmap_parse +EXPORT_SYMBOL vmlinux 0x4e0009da idr_get_new_above +EXPORT_SYMBOL vmlinux 0x4e31576b pagevec_lookup_tag +EXPORT_SYMBOL vmlinux 0x4e3567f7 match_int +EXPORT_SYMBOL vmlinux 0x4e533a29 ethtool_op_get_tso +EXPORT_SYMBOL vmlinux 0x4e6e8ea7 fg_console +EXPORT_SYMBOL vmlinux 0x4e7aeb5f blk_queue_hardsect_size +EXPORT_SYMBOL vmlinux 0x4e830a3e strnicmp +EXPORT_SYMBOL vmlinux 0x4e96f67a simple_lookup +EXPORT_SYMBOL vmlinux 0x4e9c5972 scsi_nonblockable_ioctl +EXPORT_SYMBOL vmlinux 0x4ecb2230 kernel_accept +EXPORT_SYMBOL vmlinux 0x4ee54a1c dev_get_by_name +EXPORT_SYMBOL vmlinux 0x4efeea78 sk_stream_wait_memory +EXPORT_SYMBOL vmlinux 0x4f0ea0c0 up +EXPORT_SYMBOL vmlinux 0x4f459717 kset_unregister +EXPORT_SYMBOL vmlinux 0x4f5651c3 tcp_sockets_allocated +EXPORT_SYMBOL vmlinux 0x4f93725e kern_path +EXPORT_SYMBOL vmlinux 0x4fee3f7b tty_driver_kref_put +EXPORT_SYMBOL vmlinux 0x5011ba3d pci_enable_device_mem +EXPORT_SYMBOL vmlinux 0x50157320 fget +EXPORT_SYMBOL vmlinux 0x50183b12 alloc_disk +EXPORT_SYMBOL vmlinux 0x50695c85 pci_bus_add_devices +EXPORT_SYMBOL vmlinux 0x506a8f79 wireless_spy_update +EXPORT_SYMBOL vmlinux 0x507620d3 inet_dgram_connect +EXPORT_SYMBOL vmlinux 0x508763fb kernel_setsockopt +EXPORT_SYMBOL vmlinux 0x5093fa82 _clear_bit_le +EXPORT_SYMBOL vmlinux 0x50e7bdfa pci_match_id +EXPORT_SYMBOL vmlinux 0x50e7d4f8 d_alloc +EXPORT_SYMBOL vmlinux 0x50f763f1 scsi_put_command +EXPORT_SYMBOL vmlinux 0x5104defd dev_unicast_sync +EXPORT_SYMBOL vmlinux 0x5118c382 secure_dccp_sequence_number +EXPORT_SYMBOL vmlinux 0x51493d94 finish_wait +EXPORT_SYMBOL vmlinux 0x517e8753 ip4_datagram_connect +EXPORT_SYMBOL vmlinux 0x517f5b90 tc_classify +EXPORT_SYMBOL vmlinux 0x518ad0ea inet_frag_find +EXPORT_SYMBOL vmlinux 0x51908eb8 __raw_writesl +EXPORT_SYMBOL vmlinux 0x519d570f dcache_dir_close +EXPORT_SYMBOL vmlinux 0x51cd47e2 groups_alloc +EXPORT_SYMBOL vmlinux 0x51dce73b xfrm_state_walk_init +EXPORT_SYMBOL vmlinux 0x51ef33b8 kstrndup +EXPORT_SYMBOL vmlinux 0x522ab33e neigh_update +EXPORT_SYMBOL vmlinux 0x52354a0b mutex_trylock +EXPORT_SYMBOL vmlinux 0x5247322e inet_dev_addr_type +EXPORT_SYMBOL vmlinux 0x526df6e7 dmabounce_sync_for_device +EXPORT_SYMBOL vmlinux 0x5289baf4 lease_modify +EXPORT_SYMBOL vmlinux 0x528c709d simple_read_from_buffer +EXPORT_SYMBOL vmlinux 0x52a4920d input_set_keycode +EXPORT_SYMBOL vmlinux 0x52a58c24 ifla_policy +EXPORT_SYMBOL vmlinux 0x52ad52e4 generic_readlink +EXPORT_SYMBOL vmlinux 0x52c2e830 scsi_report_bus_reset +EXPORT_SYMBOL vmlinux 0x532f2924 param_get_byte +EXPORT_SYMBOL vmlinux 0x53326531 mempool_alloc_pages +EXPORT_SYMBOL vmlinux 0x53487fce simple_set_mnt +EXPORT_SYMBOL vmlinux 0x53c0767c sk_chk_filter +EXPORT_SYMBOL vmlinux 0x5401a027 __starget_for_each_device +EXPORT_SYMBOL vmlinux 0x5425a0e9 netdev_state_change +EXPORT_SYMBOL vmlinux 0x54290dc9 nla_validate +EXPORT_SYMBOL vmlinux 0x5456b592 vfs_write +EXPORT_SYMBOL vmlinux 0x5492151b elv_rb_add +EXPORT_SYMBOL vmlinux 0x54d42936 seq_printf +EXPORT_SYMBOL vmlinux 0x54e6fcdd net_enable_timestamp +EXPORT_SYMBOL vmlinux 0x5532f5d9 journal_start +EXPORT_SYMBOL vmlinux 0x555c85bb open_exec +EXPORT_SYMBOL vmlinux 0x5594be03 bitmap_remap +EXPORT_SYMBOL vmlinux 0x55a960a3 get_empty_filp +EXPORT_SYMBOL vmlinux 0x5614b010 xfrm_policy_walk_done +EXPORT_SYMBOL vmlinux 0x561523bd nla_put +EXPORT_SYMBOL vmlinux 0x56303b97 pcim_pin_device +EXPORT_SYMBOL vmlinux 0x5635a60a vmalloc_user +EXPORT_SYMBOL vmlinux 0x5640151f put_filp +EXPORT_SYMBOL vmlinux 0x568689f2 netpoll_setup +EXPORT_SYMBOL vmlinux 0x56a06b0d task_tgid_nr_ns +EXPORT_SYMBOL vmlinux 0x56ad18b3 devm_ioremap_nocache +EXPORT_SYMBOL vmlinux 0x56b89ecb scsi_add_device +EXPORT_SYMBOL vmlinux 0x56c8799d scsi_kunmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x570ae955 locks_copy_lock +EXPORT_SYMBOL vmlinux 0x571f03c6 cpu_xscale_set_pte_ext +EXPORT_SYMBOL vmlinux 0x57259713 blk_queue_dma_alignment +EXPORT_SYMBOL vmlinux 0x572e85d4 blk_lookup_devt +EXPORT_SYMBOL vmlinux 0x574a520b tty_schedule_flip +EXPORT_SYMBOL vmlinux 0x57806f2f per_cpu____irq_regs +EXPORT_SYMBOL vmlinux 0x579a47d9 in_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0x57a5c0d0 proc_symlink +EXPORT_SYMBOL vmlinux 0x57a6504e vsnprintf +EXPORT_SYMBOL vmlinux 0x57c887ab xfrm_policy_insert +EXPORT_SYMBOL vmlinux 0x57d151b1 pci_choose_state +EXPORT_SYMBOL vmlinux 0x57f94807 __alloc_skb +EXPORT_SYMBOL vmlinux 0x58324bed __scsi_alloc_queue +EXPORT_SYMBOL vmlinux 0x5838f6c9 rtc_valid_tm +EXPORT_SYMBOL vmlinux 0x584d8c1f genl_unregister_ops +EXPORT_SYMBOL vmlinux 0x5850930d ether_setup +EXPORT_SYMBOL vmlinux 0x58a4a13b xfrm_state_unregister_afinfo +EXPORT_SYMBOL vmlinux 0x58a5c585 page_symlink_inode_operations +EXPORT_SYMBOL vmlinux 0x58d9fb67 sb_has_dirty_inodes +EXPORT_SYMBOL vmlinux 0x5934392b fb_register_client +EXPORT_SYMBOL vmlinux 0x594e1317 __modsi3 +EXPORT_SYMBOL vmlinux 0x59706f79 nf_log_unregister_pf +EXPORT_SYMBOL vmlinux 0x5976c9ea generic_permission +EXPORT_SYMBOL vmlinux 0x598639a9 unregister_console +EXPORT_SYMBOL vmlinux 0x598f7621 qmgr_enable_irq +EXPORT_SYMBOL vmlinux 0x59c711da npe_recv_message +EXPORT_SYMBOL vmlinux 0x59d696b6 register_module_notifier +EXPORT_SYMBOL vmlinux 0x59d8223a ioport_resource +EXPORT_SYMBOL vmlinux 0x59da971d dmabounce_unregister_dev +EXPORT_SYMBOL vmlinux 0x59e5070d __do_div64 +EXPORT_SYMBOL vmlinux 0x59eb04d0 submit_bh +EXPORT_SYMBOL vmlinux 0x59ec2a03 __sk_dst_check +EXPORT_SYMBOL vmlinux 0x59f3a307 pci_bus_read_config_word +EXPORT_SYMBOL vmlinux 0x5a0875ec iget5_locked +EXPORT_SYMBOL vmlinux 0x5a3cf61a km_state_expired +EXPORT_SYMBOL vmlinux 0x5a744b86 netlink_set_nonroot +EXPORT_SYMBOL vmlinux 0x5a7a6f0f scm_fp_dup +EXPORT_SYMBOL vmlinux 0x5ab2f0f7 do_splice_from +EXPORT_SYMBOL vmlinux 0x5ab5cfbc inet_csk_delete_keepalive_timer +EXPORT_SYMBOL vmlinux 0x5ad177a7 tcp_v4_syn_recv_sock +EXPORT_SYMBOL vmlinux 0x5adffaf8 simple_pin_fs +EXPORT_SYMBOL vmlinux 0x5ae26392 eth_header_cache +EXPORT_SYMBOL vmlinux 0x5b19634d div_s64_rem +EXPORT_SYMBOL vmlinux 0x5ba220fc invalidate_inodes +EXPORT_SYMBOL vmlinux 0x5bab2105 block_commit_write +EXPORT_SYMBOL vmlinux 0x5bb35d8f tcp_init_xmit_timers +EXPORT_SYMBOL vmlinux 0x5bbd9e1a pci_unmap_rom +EXPORT_SYMBOL vmlinux 0x5c4d37bb alloc_buffer_head +EXPORT_SYMBOL vmlinux 0x5c673bc8 tty_mutex +EXPORT_SYMBOL vmlinux 0x5c85dcc4 tcp_simple_retransmit +EXPORT_SYMBOL vmlinux 0x5c9284a0 processor_id +EXPORT_SYMBOL vmlinux 0x5cbc5661 unlock_buffer +EXPORT_SYMBOL vmlinux 0x5ce03b9d arp_xmit +EXPORT_SYMBOL vmlinux 0x5d373131 vfs_rename +EXPORT_SYMBOL vmlinux 0x5d3b0878 iov_iter_copy_from_user +EXPORT_SYMBOL vmlinux 0x5d3efe04 skb_copy_and_csum_datagram_iovec +EXPORT_SYMBOL vmlinux 0x5d51d57f nf_register_queue_handler +EXPORT_SYMBOL vmlinux 0x5ddc4b8f inet_csk_reset_keepalive_timer +EXPORT_SYMBOL vmlinux 0x5df6a32f tty_port_alloc_xmit_buf +EXPORT_SYMBOL vmlinux 0x5e7cde0e vfs_readv +EXPORT_SYMBOL vmlinux 0x5ea520c5 tcp_select_initial_window +EXPORT_SYMBOL vmlinux 0x5ebb56fb down_read +EXPORT_SYMBOL vmlinux 0x5edd0762 bin2bcd +EXPORT_SYMBOL vmlinux 0x5f2121dd kernel_sendmsg +EXPORT_SYMBOL vmlinux 0x5f2c0650 blk_rq_unmap_user +EXPORT_SYMBOL vmlinux 0x5f37ffc0 nla_reserve +EXPORT_SYMBOL vmlinux 0x5f754e5a memset +EXPORT_SYMBOL vmlinux 0x5f77f0f0 fib_default_rule_add +EXPORT_SYMBOL vmlinux 0x5faccd11 xfrm_stateonly_find +EXPORT_SYMBOL vmlinux 0x5fb02413 proto_register +EXPORT_SYMBOL vmlinux 0x5fb97d0f bdev_read_only +EXPORT_SYMBOL vmlinux 0x5fcaaea8 sock_i_uid +EXPORT_SYMBOL vmlinux 0x5fdfd22c generic_removexattr +EXPORT_SYMBOL vmlinux 0x5fe97c2a redraw_screen +EXPORT_SYMBOL vmlinux 0x5fe9a7bd sock_get_timestamp +EXPORT_SYMBOL vmlinux 0x600683d3 do_unblank_screen +EXPORT_SYMBOL vmlinux 0x60203f13 dev_change_flags +EXPORT_SYMBOL vmlinux 0x602d47c0 cancel_delayed_work_sync +EXPORT_SYMBOL vmlinux 0x60774129 freeze_bdev +EXPORT_SYMBOL vmlinux 0x608c2831 warn_on_slowpath +EXPORT_SYMBOL vmlinux 0x609f1c7e synchronize_net +EXPORT_SYMBOL vmlinux 0x60a32ea9 pm_power_off +EXPORT_SYMBOL vmlinux 0x60a4efe2 ida_get_new +EXPORT_SYMBOL vmlinux 0x60ac7b74 eth_header_parse +EXPORT_SYMBOL vmlinux 0x60f8dfc5 generic_file_aio_write_nolock +EXPORT_SYMBOL vmlinux 0x61105e47 flock_lock_file_wait +EXPORT_SYMBOL vmlinux 0x612390ad netpoll_set_trap +EXPORT_SYMBOL vmlinux 0x61593b72 __mod_timer +EXPORT_SYMBOL vmlinux 0x618d8299 set_notify_swap_entry_free +EXPORT_SYMBOL vmlinux 0x61988523 contig_page_data +EXPORT_SYMBOL vmlinux 0x61aec1e8 seq_bitmap +EXPORT_SYMBOL vmlinux 0x61b7b126 simple_strtoull +EXPORT_SYMBOL vmlinux 0x6200fd58 journal_lock_updates +EXPORT_SYMBOL vmlinux 0x620e9491 mb_cache_create +EXPORT_SYMBOL vmlinux 0x622fadb8 xfrm_user_policy +EXPORT_SYMBOL vmlinux 0x62737e1d sock_unregister +EXPORT_SYMBOL vmlinux 0x628064b0 add_mtd_partitions +EXPORT_SYMBOL vmlinux 0x62843894 iw_handler_get_thrspy +EXPORT_SYMBOL vmlinux 0x62a0b92f bdi_destroy +EXPORT_SYMBOL vmlinux 0x62d8cc58 unlock_new_inode +EXPORT_SYMBOL vmlinux 0x62ecccbb alloc_file +EXPORT_SYMBOL vmlinux 0x6312fdb4 vfs_link +EXPORT_SYMBOL vmlinux 0x631926fa kernel_read +EXPORT_SYMBOL vmlinux 0x634cce39 bdi_unregister +EXPORT_SYMBOL vmlinux 0x63d7520b register_sysctl_paths +EXPORT_SYMBOL vmlinux 0x63ecad53 register_netdevice_notifier +EXPORT_SYMBOL vmlinux 0x6403e338 tcp_memory_pressure +EXPORT_SYMBOL vmlinux 0x640a7078 posix_acl_create_masq +EXPORT_SYMBOL vmlinux 0x645107e9 get_write_access +EXPORT_SYMBOL vmlinux 0x649135dd iw_handler_set_spy +EXPORT_SYMBOL vmlinux 0x64999478 congestion_wait +EXPORT_SYMBOL vmlinux 0x650128e7 br_fdb_get_hook +EXPORT_SYMBOL vmlinux 0x651334bb dmam_pool_create +EXPORT_SYMBOL vmlinux 0x6516e17f bdput +EXPORT_SYMBOL vmlinux 0x651a4139 test_taint +EXPORT_SYMBOL vmlinux 0x652dc6a9 scsi_device_get +EXPORT_SYMBOL vmlinux 0x65414e67 dev_valid_name +EXPORT_SYMBOL vmlinux 0x6548a81e deny_write_access +EXPORT_SYMBOL vmlinux 0x6552c054 rtnl_set_sk_err +EXPORT_SYMBOL vmlinux 0x6572fdfb set_irq_chip +EXPORT_SYMBOL vmlinux 0x65a5c3a2 cpu_present_map +EXPORT_SYMBOL vmlinux 0x65cd8b8e inet_bind +EXPORT_SYMBOL vmlinux 0x661e6ec8 bioset_free +EXPORT_SYMBOL vmlinux 0x66948a2f invalidate_partition +EXPORT_SYMBOL vmlinux 0x6697f962 dentry_open +EXPORT_SYMBOL vmlinux 0x66c74596 request_firmware_nowait +EXPORT_SYMBOL vmlinux 0x66c75eff xfrm_state_delete_tunnel +EXPORT_SYMBOL vmlinux 0x66e42647 __bforget +EXPORT_SYMBOL vmlinux 0x6705062e touch_atime +EXPORT_SYMBOL vmlinux 0x675d7f69 skb_gso_segment +EXPORT_SYMBOL vmlinux 0x6793d7b5 free_task +EXPORT_SYMBOL vmlinux 0x6799db9b scsi_eh_restore_cmnd +EXPORT_SYMBOL vmlinux 0x67b27ec1 tty_std_termios +EXPORT_SYMBOL vmlinux 0x67c2fa54 __copy_to_user +EXPORT_SYMBOL vmlinux 0x67d1258e sk_release_kernel +EXPORT_SYMBOL vmlinux 0x67df120f log_wait_commit +EXPORT_SYMBOL vmlinux 0x68185575 skb_append_datato_frags +EXPORT_SYMBOL vmlinux 0x683360f6 ip_setsockopt +EXPORT_SYMBOL vmlinux 0x6898a756 sg_init_table +EXPORT_SYMBOL vmlinux 0x68ec652b input_register_device +EXPORT_SYMBOL vmlinux 0x68ed89a5 tcp_sendpage +EXPORT_SYMBOL vmlinux 0x6900f755 blk_queue_make_request +EXPORT_SYMBOL vmlinux 0x691b9980 tcp_prot +EXPORT_SYMBOL vmlinux 0x692c2d9c __request_region +EXPORT_SYMBOL vmlinux 0x693ec9f0 posix_test_lock +EXPORT_SYMBOL vmlinux 0x6940ea35 sock_no_bind +EXPORT_SYMBOL vmlinux 0x69496641 mod_timer +EXPORT_SYMBOL vmlinux 0x6971447a rtc_month_days +EXPORT_SYMBOL vmlinux 0x698932d9 blk_rq_append_bio +EXPORT_SYMBOL vmlinux 0x69927dff try_acquire_console_sem +EXPORT_SYMBOL vmlinux 0x69a2b429 vfs_rmdir +EXPORT_SYMBOL vmlinux 0x69af2327 idr_init +EXPORT_SYMBOL vmlinux 0x69bbf946 journal_init_inode +EXPORT_SYMBOL vmlinux 0x69c300fd generic_ro_fops +EXPORT_SYMBOL vmlinux 0x69d38ed9 __scsi_print_sense +EXPORT_SYMBOL vmlinux 0x69de4c8e register_sysctl_table +EXPORT_SYMBOL vmlinux 0x69e27c7a bitmap_copy_le +EXPORT_SYMBOL vmlinux 0x69fdb553 close_bdev_exclusive +EXPORT_SYMBOL vmlinux 0x6a037cf1 mempool_kfree +EXPORT_SYMBOL vmlinux 0x6a171b0c filemap_write_and_wait +EXPORT_SYMBOL vmlinux 0x6a177f72 journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0x6a22d005 qdisc_list_del +EXPORT_SYMBOL vmlinux 0x6a47571d __set_personality +EXPORT_SYMBOL vmlinux 0x6a6ef2a8 kthread_create +EXPORT_SYMBOL vmlinux 0x6a7ca961 d_path +EXPORT_SYMBOL vmlinux 0x6a962884 generic_mii_ioctl +EXPORT_SYMBOL vmlinux 0x6ab062d4 vfs_writev +EXPORT_SYMBOL vmlinux 0x6ab4e6d1 skb_realloc_headroom +EXPORT_SYMBOL vmlinux 0x6ac45c28 __up_write +EXPORT_SYMBOL vmlinux 0x6ae5c8f9 scsi_track_queue_full +EXPORT_SYMBOL vmlinux 0x6af69bae proc_mkdir +EXPORT_SYMBOL vmlinux 0x6b1b67d3 __bdevname +EXPORT_SYMBOL vmlinux 0x6b2dc060 dump_stack +EXPORT_SYMBOL vmlinux 0x6b2f345c pcim_iomap_table +EXPORT_SYMBOL vmlinux 0x6b35093c call_usermodehelper_exec +EXPORT_SYMBOL vmlinux 0x6b44111c xfrm_input +EXPORT_SYMBOL vmlinux 0x6b511220 nf_register_sockopt +EXPORT_SYMBOL vmlinux 0x6b7166f5 iov_iter_copy_from_user_atomic +EXPORT_SYMBOL vmlinux 0x6b752ddf __getblk +EXPORT_SYMBOL vmlinux 0x6b96fd52 arp_broken_ops +EXPORT_SYMBOL vmlinux 0x6bdcfd99 qdisc_class_hash_remove +EXPORT_SYMBOL vmlinux 0x6c0456f3 xscale_mc_clear_user_page +EXPORT_SYMBOL vmlinux 0x6c1ce5ce strcspn +EXPORT_SYMBOL vmlinux 0x6c1cf9d5 sget +EXPORT_SYMBOL vmlinux 0x6c36a5c1 __mutex_init +EXPORT_SYMBOL vmlinux 0x6c5b12af pci_dev_put +EXPORT_SYMBOL vmlinux 0x6c702af7 sysctl_udp_rmem_min +EXPORT_SYMBOL vmlinux 0x6ca6925b task_pid_nr_ns +EXPORT_SYMBOL vmlinux 0x6ca84947 skb_put +EXPORT_SYMBOL vmlinux 0x6cdc5c6b nla_strlcpy +EXPORT_SYMBOL vmlinux 0x6cef247f __strnlen_user +EXPORT_SYMBOL vmlinux 0x6d0da34c param_get_short +EXPORT_SYMBOL vmlinux 0x6d243db0 tcf_exts_validate +EXPORT_SYMBOL vmlinux 0x6d27ef64 __bitmap_empty +EXPORT_SYMBOL vmlinux 0x6d288375 radix_tree_next_hole +EXPORT_SYMBOL vmlinux 0x6d294e43 clock_t_to_jiffies +EXPORT_SYMBOL vmlinux 0x6d340f64 tty_termios_input_baud_rate +EXPORT_SYMBOL vmlinux 0x6d34e5a5 mb_cache_entry_find_next +EXPORT_SYMBOL vmlinux 0x6d397397 gnet_stats_copy_basic +EXPORT_SYMBOL vmlinux 0x6d662533 _find_first_bit_le +EXPORT_SYMBOL vmlinux 0x6dd856e2 lookup_bdev +EXPORT_SYMBOL vmlinux 0x6de1a8a2 bd_set_size +EXPORT_SYMBOL vmlinux 0x6def2db2 half_md4_transform +EXPORT_SYMBOL vmlinux 0x6df5c2dc fd_install +EXPORT_SYMBOL vmlinux 0x6e31b98e bio_pair_release +EXPORT_SYMBOL vmlinux 0x6e34f226 blk_queue_max_segment_size +EXPORT_SYMBOL vmlinux 0x6e429e97 irq_to_gpio +EXPORT_SYMBOL vmlinux 0x6e440b58 memcpy_fromiovecend +EXPORT_SYMBOL vmlinux 0x6e55b0b0 redirty_page_for_writepage +EXPORT_SYMBOL vmlinux 0x6e71ee90 skb_under_panic +EXPORT_SYMBOL vmlinux 0x6e720ff2 rtnl_unlock +EXPORT_SYMBOL vmlinux 0x6e84a85c save_time_delta +EXPORT_SYMBOL vmlinux 0x6e9dd606 __symbol_put +EXPORT_SYMBOL vmlinux 0x6ebff1ac generic_fillattr +EXPORT_SYMBOL vmlinux 0x6ec28573 sock_init_data +EXPORT_SYMBOL vmlinux 0x6f2619c8 journal_extend +EXPORT_SYMBOL vmlinux 0x6f2a309d shrink_dcache_parent +EXPORT_SYMBOL vmlinux 0x6f7104c2 remove_arg_zero +EXPORT_SYMBOL vmlinux 0x6f9568c3 skb_prepare_seq_read +EXPORT_SYMBOL vmlinux 0x6f96977b dma_sync_sg_for_device +EXPORT_SYMBOL vmlinux 0x6f970a18 find_get_pages_contig +EXPORT_SYMBOL vmlinux 0x6fa0c9af devm_iounmap +EXPORT_SYMBOL vmlinux 0x6fba5a66 ip_xfrm_me_harder +EXPORT_SYMBOL vmlinux 0x7008a9b7 timespec_to_jiffies +EXPORT_SYMBOL vmlinux 0x700c26ab input_allocate_device +EXPORT_SYMBOL vmlinux 0x700d3a53 tty_register_ldisc +EXPORT_SYMBOL vmlinux 0x701d0ebd snprintf +EXPORT_SYMBOL vmlinux 0x703d4a7d check_disk_change +EXPORT_SYMBOL vmlinux 0x70cc069c vm_insert_pfn +EXPORT_SYMBOL vmlinux 0x70ed631a ilookup5_nowait +EXPORT_SYMBOL vmlinux 0x710eda52 pci_bus_read_config_byte +EXPORT_SYMBOL vmlinux 0x7129e5f8 hex_asc +EXPORT_SYMBOL vmlinux 0x71318e49 __netdev_alloc_page +EXPORT_SYMBOL vmlinux 0x7171121c overflowgid +EXPORT_SYMBOL vmlinux 0x7179d425 __scsi_device_lookup +EXPORT_SYMBOL vmlinux 0x71a50dbc register_blkdev +EXPORT_SYMBOL vmlinux 0x71a517ee tcp_splice_read +EXPORT_SYMBOL vmlinux 0x71c90087 memcmp +EXPORT_SYMBOL vmlinux 0x71efad36 journal_clear_err +EXPORT_SYMBOL vmlinux 0x72270e35 do_gettimeofday +EXPORT_SYMBOL vmlinux 0x723da779 pci_scan_bus_parented +EXPORT_SYMBOL vmlinux 0x72d5af61 try_wait_for_completion +EXPORT_SYMBOL vmlinux 0x72ea7b2d scsi_device_type +EXPORT_SYMBOL vmlinux 0x72fbae28 set_current_groups +EXPORT_SYMBOL vmlinux 0x73069aac cpu_possible_map +EXPORT_SYMBOL vmlinux 0x7308096f scsi_is_sdev_device +EXPORT_SYMBOL vmlinux 0x730dcfe1 netif_carrier_on +EXPORT_SYMBOL vmlinux 0x731db972 unregister_mtd_chip_driver +EXPORT_SYMBOL vmlinux 0x732de7d4 pci_request_selected_regions +EXPORT_SYMBOL vmlinux 0x733468f7 generic_make_request +EXPORT_SYMBOL vmlinux 0x7344883a sync_dirty_buffer +EXPORT_SYMBOL vmlinux 0x738be4a2 should_remove_suid +EXPORT_SYMBOL vmlinux 0x73a83874 file_permission +EXPORT_SYMBOL vmlinux 0x73b808e2 input_set_capability +EXPORT_SYMBOL vmlinux 0x73d06eaa pci_remove_behind_bridge +EXPORT_SYMBOL vmlinux 0x73e20c1c strlcpy +EXPORT_SYMBOL vmlinux 0x744206f0 read_cache_page_async +EXPORT_SYMBOL vmlinux 0x74586104 block_truncate_page +EXPORT_SYMBOL vmlinux 0x745f1c72 scsi_device_lookup +EXPORT_SYMBOL vmlinux 0x7485e15e unregister_chrdev_region +EXPORT_SYMBOL vmlinux 0x74cc238d current_kernel_time +EXPORT_SYMBOL vmlinux 0x74d066fb xfrm_find_acq_byseq +EXPORT_SYMBOL vmlinux 0x74d8d362 simple_empty +EXPORT_SYMBOL vmlinux 0x74f252e1 tty_shutdown +EXPORT_SYMBOL vmlinux 0x74feda85 dev_close +EXPORT_SYMBOL vmlinux 0x7510030d d_add_ci +EXPORT_SYMBOL vmlinux 0x751b8fb6 sock_i_ino +EXPORT_SYMBOL vmlinux 0x751fe760 ip_defrag +EXPORT_SYMBOL vmlinux 0x7557e4fd register_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0x75583fc5 find_task_by_pid_type_ns +EXPORT_SYMBOL vmlinux 0x75c020bd skb_dma_map +EXPORT_SYMBOL vmlinux 0x75fee7fd __raw_writesb +EXPORT_SYMBOL vmlinux 0x760a0f4f yield +EXPORT_SYMBOL vmlinux 0x760b437a unregister_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x760ceb36 sync_inode +EXPORT_SYMBOL vmlinux 0x76213cea scsi_unregister +EXPORT_SYMBOL vmlinux 0x765f75fb pgprot_user +EXPORT_SYMBOL vmlinux 0x766f134d pci_pme_active +EXPORT_SYMBOL vmlinux 0x76a14a29 pci_setup_cardbus +EXPORT_SYMBOL vmlinux 0x76ad6008 tty_register_device +EXPORT_SYMBOL vmlinux 0x76bf656d __bitmap_shift_left +EXPORT_SYMBOL vmlinux 0x76cf47f6 __aeabi_llsl +EXPORT_SYMBOL vmlinux 0x76d3cd60 laptop_mode +EXPORT_SYMBOL vmlinux 0x76f03268 register_qdisc +EXPORT_SYMBOL vmlinux 0x77381e23 pneigh_lookup +EXPORT_SYMBOL vmlinux 0x776d89e9 mii_check_link +EXPORT_SYMBOL vmlinux 0x77762d95 module_put +EXPORT_SYMBOL vmlinux 0x778de3c1 skb_checksum_help +EXPORT_SYMBOL vmlinux 0x77ab8ca8 scsi_set_medium_removal +EXPORT_SYMBOL vmlinux 0x77be43cd xfrm_nl +EXPORT_SYMBOL vmlinux 0x77bf8939 netdev_class_remove_file +EXPORT_SYMBOL vmlinux 0x77f47c3b generic_osync_inode +EXPORT_SYMBOL vmlinux 0x77fb3566 kmem_cache_shrink +EXPORT_SYMBOL vmlinux 0x7822772a blk_queue_bounce +EXPORT_SYMBOL vmlinux 0x7832443f block_read_full_page +EXPORT_SYMBOL vmlinux 0x78367bc7 user_path_at +EXPORT_SYMBOL vmlinux 0x7864abf6 lookup_one_len +EXPORT_SYMBOL vmlinux 0x788fe103 iomem_resource +EXPORT_SYMBOL vmlinux 0x78de4303 genl_register_ops +EXPORT_SYMBOL vmlinux 0x78df6bd7 no_pci_devices +EXPORT_SYMBOL vmlinux 0x790bd319 default_unplug_io_fn +EXPORT_SYMBOL vmlinux 0x794487ee disable_hlt +EXPORT_SYMBOL vmlinux 0x79600d4a wait_for_completion_killable +EXPORT_SYMBOL vmlinux 0x796fc5ce scsi_get_sense_info_fld +EXPORT_SYMBOL vmlinux 0x7985ab1c bio_split +EXPORT_SYMBOL vmlinux 0x79aa04a2 get_random_bytes +EXPORT_SYMBOL vmlinux 0x79ad224b tasklet_kill +EXPORT_SYMBOL vmlinux 0x79b8442f qdisc_destroy +EXPORT_SYMBOL vmlinux 0x79c40e64 dentry_unhash +EXPORT_SYMBOL vmlinux 0x79d90f71 input_grab_device +EXPORT_SYMBOL vmlinux 0x79db1950 pci_dev_get +EXPORT_SYMBOL vmlinux 0x79fb2501 elv_rb_del +EXPORT_SYMBOL vmlinux 0x7a05fde4 pci_bus_write_config_byte +EXPORT_SYMBOL vmlinux 0x7a2a837d strict_strtol +EXPORT_SYMBOL vmlinux 0x7a53772d __skb_checksum_complete_head +EXPORT_SYMBOL vmlinux 0x7ade0094 scsi_dma_map +EXPORT_SYMBOL vmlinux 0x7af30430 neigh_parms_release +EXPORT_SYMBOL vmlinux 0x7af900c5 fput +EXPORT_SYMBOL vmlinux 0x7b00ed27 simple_map_init +EXPORT_SYMBOL vmlinux 0x7b0abe84 rtnl_create_link +EXPORT_SYMBOL vmlinux 0x7b19a020 scsi_eh_prep_cmnd +EXPORT_SYMBOL vmlinux 0x7b19a951 proc_dointvec +EXPORT_SYMBOL vmlinux 0x7b201d53 mnt_pin +EXPORT_SYMBOL vmlinux 0x7b3feb9d kobject_set_name +EXPORT_SYMBOL vmlinux 0x7b5ac17e generic_setxattr +EXPORT_SYMBOL vmlinux 0x7b8a3816 generic_file_readonly_mmap +EXPORT_SYMBOL vmlinux 0x7baf3c2c dmam_alloc_coherent +EXPORT_SYMBOL vmlinux 0x7be4544f netlink_ack +EXPORT_SYMBOL vmlinux 0x7c0882fa skb_queue_tail +EXPORT_SYMBOL vmlinux 0x7c0b1a81 rtnl_notify +EXPORT_SYMBOL vmlinux 0x7c43bc1f sock_wmalloc +EXPORT_SYMBOL vmlinux 0x7c4b9f70 may_umount +EXPORT_SYMBOL vmlinux 0x7c58ecfa kill_pid +EXPORT_SYMBOL vmlinux 0x7c60d66e getname +EXPORT_SYMBOL vmlinux 0x7c63d959 get_sb_single +EXPORT_SYMBOL vmlinux 0x7c904ded unregister_module_notifier +EXPORT_SYMBOL vmlinux 0x7caf1008 locks_mandatory_area +EXPORT_SYMBOL vmlinux 0x7cc035a7 __ucmpdi2 +EXPORT_SYMBOL vmlinux 0x7d014deb blkdev_issue_discard +EXPORT_SYMBOL vmlinux 0x7d04c74e inet_unregister_protosw +EXPORT_SYMBOL vmlinux 0x7d11c268 jiffies +EXPORT_SYMBOL vmlinux 0x7d688bc1 init_task +EXPORT_SYMBOL vmlinux 0x7d9e5c39 ip_nat_decode_session +EXPORT_SYMBOL vmlinux 0x7da94897 udp_poll +EXPORT_SYMBOL vmlinux 0x7db0c206 inode_setattr +EXPORT_SYMBOL vmlinux 0x7dc05445 xfrm4_prepare_output +EXPORT_SYMBOL vmlinux 0x7dc2e07f deactivate_super +EXPORT_SYMBOL vmlinux 0x7dceceac capable +EXPORT_SYMBOL vmlinux 0x7dd81fe5 mnt_unpin +EXPORT_SYMBOL vmlinux 0x7e058bfb xscale_coherent_kern_range +EXPORT_SYMBOL vmlinux 0x7e0a1251 kernel_recvmsg +EXPORT_SYMBOL vmlinux 0x7e37f31c __lookup_hash +EXPORT_SYMBOL vmlinux 0x7e531cde del_timer +EXPORT_SYMBOL vmlinux 0x7e673ac7 mb_cache_entry_alloc +EXPORT_SYMBOL vmlinux 0x7e6efa02 pagecache_write_begin +EXPORT_SYMBOL vmlinux 0x7e8e0464 unregister_netdevice +EXPORT_SYMBOL vmlinux 0x7e9ebb05 kernel_thread +EXPORT_SYMBOL vmlinux 0x7ebf1fd1 blk_cleanup_queue +EXPORT_SYMBOL vmlinux 0x7f05999c elv_rb_latter_request +EXPORT_SYMBOL vmlinux 0x7f24de73 jiffies_to_usecs +EXPORT_SYMBOL vmlinux 0x7f41903a sk_receive_skb +EXPORT_SYMBOL vmlinux 0x7f63b31e _memcpy_toio +EXPORT_SYMBOL vmlinux 0x7f6a004b dput +EXPORT_SYMBOL vmlinux 0x7f8723bd pcie_mch_quirk +EXPORT_SYMBOL vmlinux 0x7f8877aa try_to_release_page +EXPORT_SYMBOL vmlinux 0x7f8eecdc netlink_broadcast +EXPORT_SYMBOL vmlinux 0x7f900b9d pci_find_capability +EXPORT_SYMBOL vmlinux 0x7fa57680 kernel_sock_shutdown +EXPORT_SYMBOL vmlinux 0x7fcc9735 register_sysrq_key +EXPORT_SYMBOL vmlinux 0x7fd9f1fa dev_getbyhwaddr +EXPORT_SYMBOL vmlinux 0x7ff14434 tcp_shutdown +EXPORT_SYMBOL vmlinux 0x800e4ffa __muldi3 +EXPORT_SYMBOL vmlinux 0x801c1648 ____pagevec_lru_add +EXPORT_SYMBOL vmlinux 0x80330989 tcp_read_sock +EXPORT_SYMBOL vmlinux 0x805c8e7a uart_get_divisor +EXPORT_SYMBOL vmlinux 0x8063f83d radix_tree_gang_lookup +EXPORT_SYMBOL vmlinux 0x80780088 have_submounts +EXPORT_SYMBOL vmlinux 0x8085c7b1 prepare_to_wait +EXPORT_SYMBOL vmlinux 0x80a8af2a scsi_mode_sense +EXPORT_SYMBOL vmlinux 0x80b13717 __scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0x80b3f995 tc_classify_compat +EXPORT_SYMBOL vmlinux 0x80d0f3fa simple_dir_inode_operations +EXPORT_SYMBOL vmlinux 0x80dce242 xfrm_lookup +EXPORT_SYMBOL vmlinux 0x80f0cbbe blk_alloc_queue +EXPORT_SYMBOL vmlinux 0x811b24f3 xfrm_state_lookup +EXPORT_SYMBOL vmlinux 0x811cd181 __free_pages +EXPORT_SYMBOL vmlinux 0x81204a38 tcp_hashinfo +EXPORT_SYMBOL vmlinux 0x81359edf find_vma +EXPORT_SYMBOL vmlinux 0x815b5dd4 match_octal +EXPORT_SYMBOL vmlinux 0x81799cee vscnprintf +EXPORT_SYMBOL vmlinux 0x819923a1 alloc_disk_node +EXPORT_SYMBOL vmlinux 0x819bda77 sk_stream_error +EXPORT_SYMBOL vmlinux 0x81b29e7e tcp_disconnect +EXPORT_SYMBOL vmlinux 0x81c8b508 npe_request +EXPORT_SYMBOL vmlinux 0x81c90983 tcf_destroy_chain +EXPORT_SYMBOL vmlinux 0x81ec9df2 nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0x81f14803 generic_write_checks +EXPORT_SYMBOL vmlinux 0x81f2c205 xfrm_register_type +EXPORT_SYMBOL vmlinux 0x820d225f print_mac +EXPORT_SYMBOL vmlinux 0x822476fb xfrm_unregister_km +EXPORT_SYMBOL vmlinux 0x8240380a elevator_init +EXPORT_SYMBOL vmlinux 0x8249be57 pci_reenable_device +EXPORT_SYMBOL vmlinux 0x8251bcc3 bitmap_release_region +EXPORT_SYMBOL vmlinux 0x82692209 kref_set +EXPORT_SYMBOL vmlinux 0x8271e178 pci_release_regions +EXPORT_SYMBOL vmlinux 0x82e489e7 dcache_readdir +EXPORT_SYMBOL vmlinux 0x82e5a238 vm_get_page_prot +EXPORT_SYMBOL vmlinux 0x8320bea8 __umodsi3 +EXPORT_SYMBOL vmlinux 0x834a5cba blkdev_dequeue_request +EXPORT_SYMBOL vmlinux 0x838542de __find_get_block +EXPORT_SYMBOL vmlinux 0x83a476ce bitmap_scnlistprintf +EXPORT_SYMBOL vmlinux 0x83bf638e npe_send_recv_message +EXPORT_SYMBOL vmlinux 0x84000988 fsync_bdev +EXPORT_SYMBOL vmlinux 0x84348e40 xfrm_prepare_input +EXPORT_SYMBOL vmlinux 0x84a2da8e blk_queue_end_tag +EXPORT_SYMBOL vmlinux 0x84b183ae strncmp +EXPORT_SYMBOL vmlinux 0x84d82a4b sb_min_blocksize +EXPORT_SYMBOL vmlinux 0x85034625 neigh_lookup_nodev +EXPORT_SYMBOL vmlinux 0x8508eee8 blk_insert_request +EXPORT_SYMBOL vmlinux 0x85287bd7 skb_pull +EXPORT_SYMBOL vmlinux 0x8557f729 generic_block_bmap +EXPORT_SYMBOL vmlinux 0x85583096 end_request +EXPORT_SYMBOL vmlinux 0x85670f1d rtnl_is_locked +EXPORT_SYMBOL vmlinux 0x858e2225 invalidate_inode_buffers +EXPORT_SYMBOL vmlinux 0x859f907b per_cpu__softnet_data +EXPORT_SYMBOL vmlinux 0x85ac7f10 posix_acl_from_xattr +EXPORT_SYMBOL vmlinux 0x85df9b6c strsep +EXPORT_SYMBOL vmlinux 0x85e7deb2 iov_iter_fault_in_readable +EXPORT_SYMBOL vmlinux 0x862368ea neigh_changeaddr +EXPORT_SYMBOL vmlinux 0x86575457 pci_set_dma_seg_boundary +EXPORT_SYMBOL vmlinux 0x868acba5 get_options +EXPORT_SYMBOL vmlinux 0x86dcface alloc_tty_driver +EXPORT_SYMBOL vmlinux 0x86fb9b05 bitmap_parse_user +EXPORT_SYMBOL vmlinux 0x8706fd72 tcp_v4_connect +EXPORT_SYMBOL vmlinux 0x871c0a7e fiemap_check_flags +EXPORT_SYMBOL vmlinux 0x874c48d2 bio_copy_kern +EXPORT_SYMBOL vmlinux 0x8785725d param_set_charp +EXPORT_SYMBOL vmlinux 0x878ab3ce sysctl_tcp_adv_win_scale +EXPORT_SYMBOL vmlinux 0x87a73c54 dma_alloc_from_coherent +EXPORT_SYMBOL vmlinux 0x8847a60e pci_bus_write_config_dword +EXPORT_SYMBOL vmlinux 0x887f7dc4 netif_receive_skb +EXPORT_SYMBOL vmlinux 0x88909a92 journal_create +EXPORT_SYMBOL vmlinux 0x88aef256 __xfrm_decode_session +EXPORT_SYMBOL vmlinux 0x88afa5d7 tcp_sync_mss +EXPORT_SYMBOL vmlinux 0x88b099fb d_alloc_name +EXPORT_SYMBOL vmlinux 0x88cc4109 generic_file_llseek_unlocked +EXPORT_SYMBOL vmlinux 0x88cc43a1 ioctl_by_bdev +EXPORT_SYMBOL vmlinux 0x8914511d nobh_write_end +EXPORT_SYMBOL vmlinux 0x891e32b8 wait_for_completion_interruptible +EXPORT_SYMBOL vmlinux 0x8928675f get_super +EXPORT_SYMBOL vmlinux 0x896b96df tcf_hash_lookup +EXPORT_SYMBOL vmlinux 0x897473df mktime +EXPORT_SYMBOL vmlinux 0x89ae62b3 dev_mc_add +EXPORT_SYMBOL vmlinux 0x89bb04b0 tty_write_room +EXPORT_SYMBOL vmlinux 0x89d66811 build_ehash_secret +EXPORT_SYMBOL vmlinux 0x8a0b4a09 pci_bus_write_config_word +EXPORT_SYMBOL vmlinux 0x8a1203a9 kref_get +EXPORT_SYMBOL vmlinux 0x8a4fa83b __aeabi_llsr +EXPORT_SYMBOL vmlinux 0x8a6584a8 scsi_finish_command +EXPORT_SYMBOL vmlinux 0x8a7d1c31 high_memory +EXPORT_SYMBOL vmlinux 0x8a99a016 mempool_free_slab +EXPORT_SYMBOL vmlinux 0x8abd9b9e proc_net_netfilter +EXPORT_SYMBOL vmlinux 0x8ac54895 ip_route_input +EXPORT_SYMBOL vmlinux 0x8ace6be1 sk_send_sigurg +EXPORT_SYMBOL vmlinux 0x8ad38d09 dev_unicast_unsync +EXPORT_SYMBOL vmlinux 0x8ae64879 pfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0x8b618d08 overflowuid +EXPORT_SYMBOL vmlinux 0x8b7206cb qdisc_watchdog_init +EXPORT_SYMBOL vmlinux 0x8b982dec invalidate_bdev +EXPORT_SYMBOL vmlinux 0x8b9a4149 ida_destroy +EXPORT_SYMBOL vmlinux 0x8b9e4440 journal_restart +EXPORT_SYMBOL vmlinux 0x8bbfa2b9 flow_cache_lookup +EXPORT_SYMBOL vmlinux 0x8bcfe206 dev_driver_string +EXPORT_SYMBOL vmlinux 0x8bd0194c dev_alloc_skb +EXPORT_SYMBOL vmlinux 0x8be68f73 map_destroy +EXPORT_SYMBOL vmlinux 0x8be8ba39 netlink_kernel_release +EXPORT_SYMBOL vmlinux 0x8c256828 seq_path +EXPORT_SYMBOL vmlinux 0x8c2e9e4c generic_write_end +EXPORT_SYMBOL vmlinux 0x8c39e9ff tcp_recvmsg +EXPORT_SYMBOL vmlinux 0x8c4dcb23 block_page_mkwrite +EXPORT_SYMBOL vmlinux 0x8c7bc348 ida_remove +EXPORT_SYMBOL vmlinux 0x8c84069c restore_time_delta +EXPORT_SYMBOL vmlinux 0x8c88a244 nf_getsockopt +EXPORT_SYMBOL vmlinux 0x8ca5c84d sock_no_connect +EXPORT_SYMBOL vmlinux 0x8cb68c3b skb_clone +EXPORT_SYMBOL vmlinux 0x8d3894f2 _ctype +EXPORT_SYMBOL vmlinux 0x8d551bef sysctl_tcp_rmem +EXPORT_SYMBOL vmlinux 0x8d5642fc wait_for_completion_interruptible_timeout +EXPORT_SYMBOL vmlinux 0x8d628de9 pci_release_region +EXPORT_SYMBOL vmlinux 0x8d64a5ae tcp_ioctl +EXPORT_SYMBOL vmlinux 0x8d6f81b4 __div64_32 +EXPORT_SYMBOL vmlinux 0x8dba9446 simple_getattr +EXPORT_SYMBOL vmlinux 0x8dcb5c27 idr_remove +EXPORT_SYMBOL vmlinux 0x8dfb1669 journal_set_features +EXPORT_SYMBOL vmlinux 0x8e015031 xrlim_allow +EXPORT_SYMBOL vmlinux 0x8e0b7743 ipv6_ext_hdr +EXPORT_SYMBOL vmlinux 0x8e1129c7 tty_vhangup +EXPORT_SYMBOL vmlinux 0x8e3c9cc3 vprintk +EXPORT_SYMBOL vmlinux 0x8e69b79a __scm_send +EXPORT_SYMBOL vmlinux 0x8e763ae1 send_remote_softirq +EXPORT_SYMBOL vmlinux 0x8e9ab01f scsi_free_command +EXPORT_SYMBOL vmlinux 0x8ec6a9c9 pci_set_power_state +EXPORT_SYMBOL vmlinux 0x8eda5384 mii_ethtool_sset +EXPORT_SYMBOL vmlinux 0x8ee23ec5 do_sync_write +EXPORT_SYMBOL vmlinux 0x8efd924c simple_readpage +EXPORT_SYMBOL vmlinux 0x8f07d8ca __wait_on_bit +EXPORT_SYMBOL vmlinux 0x8f596c33 iw_handler_get_spy +EXPORT_SYMBOL vmlinux 0x8f6b7950 set_irq_data +EXPORT_SYMBOL vmlinux 0x8f7b11a4 linkwatch_fire_event +EXPORT_SYMBOL vmlinux 0x8f9b86b2 kfifo_alloc +EXPORT_SYMBOL vmlinux 0x8fdd59eb clear_inode +EXPORT_SYMBOL vmlinux 0x8ff5e5c1 generic_shutdown_super +EXPORT_SYMBOL vmlinux 0x90035333 secure_tcpv6_sequence_number +EXPORT_SYMBOL vmlinux 0x90084047 init_special_inode +EXPORT_SYMBOL vmlinux 0x904a0086 vfs_statfs +EXPORT_SYMBOL vmlinux 0x90875afe bdget_disk +EXPORT_SYMBOL vmlinux 0x90b8029d pci_target_state +EXPORT_SYMBOL vmlinux 0x91159a62 inet_listen +EXPORT_SYMBOL vmlinux 0x9126abe2 dev_open +EXPORT_SYMBOL vmlinux 0x912afafb pci_map_rom +EXPORT_SYMBOL vmlinux 0x9132cdc0 dev_get_flags +EXPORT_SYMBOL vmlinux 0x91481982 __ratelimit +EXPORT_SYMBOL vmlinux 0x914b2d89 __skb_recv_datagram +EXPORT_SYMBOL vmlinux 0x91824fed pci_bus_size_bridges +EXPORT_SYMBOL vmlinux 0x919029aa __readwrite_bug +EXPORT_SYMBOL vmlinux 0x9199afbc generic_listxattr +EXPORT_SYMBOL vmlinux 0x91b149cd __tcf_em_tree_match +EXPORT_SYMBOL vmlinux 0x91c1c8ee journal_get_write_access +EXPORT_SYMBOL vmlinux 0x91d5b22e tcf_em_tree_dump +EXPORT_SYMBOL vmlinux 0x9226574b end_buffer_read_sync +EXPORT_SYMBOL vmlinux 0x926401f2 sg_copy_to_buffer +EXPORT_SYMBOL vmlinux 0x92d21eff no_llseek +EXPORT_SYMBOL vmlinux 0x9313848e journal_unlock_updates +EXPORT_SYMBOL vmlinux 0x932f60ab devm_ioremap +EXPORT_SYMBOL vmlinux 0x93618e35 dev_kfree_skb_any +EXPORT_SYMBOL vmlinux 0x93a6e0b2 io_schedule +EXPORT_SYMBOL vmlinux 0x93c69acf param_set_byte +EXPORT_SYMBOL vmlinux 0x93d3b4ba fifo_set_limit +EXPORT_SYMBOL vmlinux 0x93e22307 mpage_writepages +EXPORT_SYMBOL vmlinux 0x93ea1d67 udp_lib_getsockopt +EXPORT_SYMBOL vmlinux 0x93fca811 __get_free_pages +EXPORT_SYMBOL vmlinux 0x940047a1 eth_header +EXPORT_SYMBOL vmlinux 0x945d2a89 tcp_mtup_init +EXPORT_SYMBOL vmlinux 0x94761cc1 skb_make_writable +EXPORT_SYMBOL vmlinux 0x94847b23 nf_ct_destroy +EXPORT_SYMBOL vmlinux 0x94961283 vunmap +EXPORT_SYMBOL vmlinux 0x94972992 journal_flush +EXPORT_SYMBOL vmlinux 0x94a577c0 sb_set_blocksize +EXPORT_SYMBOL vmlinux 0x94a5ce17 journal_check_available_features +EXPORT_SYMBOL vmlinux 0x94a9c8e0 pci_get_bus_and_slot +EXPORT_SYMBOL vmlinux 0x94bfe015 pci_select_bars +EXPORT_SYMBOL vmlinux 0x94c01ed4 skb_copy_datagram_from_iovec +EXPORT_SYMBOL vmlinux 0x94e9ce6d directly_mappable_cdev_bdi +EXPORT_SYMBOL vmlinux 0x94f04834 sock_no_mmap +EXPORT_SYMBOL vmlinux 0x9501d078 __wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0x954488a4 syncookie_secret +EXPORT_SYMBOL vmlinux 0x954cbb26 vsprintf +EXPORT_SYMBOL vmlinux 0x95896cf6 d_lookup +EXPORT_SYMBOL vmlinux 0x95a7ef50 make_EII_client +EXPORT_SYMBOL vmlinux 0x95dbe078 __get_user_2 +EXPORT_SYMBOL vmlinux 0x95dfd5ab netpoll_poll +EXPORT_SYMBOL vmlinux 0x95e82df0 blk_queue_bounce_limit +EXPORT_SYMBOL vmlinux 0x963d533f journal_invalidatepage +EXPORT_SYMBOL vmlinux 0x96898769 sysfs_format_mac +EXPORT_SYMBOL vmlinux 0x968a1027 journal_dirty_data +EXPORT_SYMBOL vmlinux 0x969e6bb6 find_inode_number +EXPORT_SYMBOL vmlinux 0x96b31cd9 mb_cache_entry_get +EXPORT_SYMBOL vmlinux 0x96b6a764 tcp_v4_remember_stamp +EXPORT_SYMBOL vmlinux 0x96cd2b04 scsi_sense_key_string +EXPORT_SYMBOL vmlinux 0x96df5482 walk_stackframe +EXPORT_SYMBOL vmlinux 0x96e175eb __netif_schedule +EXPORT_SYMBOL vmlinux 0x96e78e85 dev_set_allmulti +EXPORT_SYMBOL vmlinux 0x96f6d304 ipv4_specific +EXPORT_SYMBOL vmlinux 0x970ba5ce scsi_scan_target +EXPORT_SYMBOL vmlinux 0x97255bdf strlen +EXPORT_SYMBOL vmlinux 0x97379db5 blk_queue_init_tags +EXPORT_SYMBOL vmlinux 0x9754ec10 radix_tree_preload +EXPORT_SYMBOL vmlinux 0x978f3742 scsi_target_quiesce +EXPORT_SYMBOL vmlinux 0x97b7911a __nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0x97c37fc5 xfrm_state_lookup_byaddr +EXPORT_SYMBOL vmlinux 0x97e65ce5 cdev_init +EXPORT_SYMBOL vmlinux 0x98040497 pci_scan_slot +EXPORT_SYMBOL vmlinux 0x981026f6 km_report +EXPORT_SYMBOL vmlinux 0x98497cfd remap_vmalloc_range +EXPORT_SYMBOL vmlinux 0x985a6950 bio_add_page +EXPORT_SYMBOL vmlinux 0x98a0c643 init_buffer +EXPORT_SYMBOL vmlinux 0x99395f13 pci_enable_device +EXPORT_SYMBOL vmlinux 0x993d47f4 con_is_bound +EXPORT_SYMBOL vmlinux 0x993eedd1 tcp_check_req +EXPORT_SYMBOL vmlinux 0x9946c145 mii_check_media +EXPORT_SYMBOL vmlinux 0x994bd13f devm_request_irq +EXPORT_SYMBOL vmlinux 0x99999a55 br_handle_frame_hook +EXPORT_SYMBOL vmlinux 0x999c3148 __raw_readsb +EXPORT_SYMBOL vmlinux 0x999e8297 vfree +EXPORT_SYMBOL vmlinux 0x99a2287d f_setown +EXPORT_SYMBOL vmlinux 0x99aadb21 param_get_ulong +EXPORT_SYMBOL vmlinux 0x99af37ba neigh_destroy +EXPORT_SYMBOL vmlinux 0x99b3ef49 blk_queue_resize_tags +EXPORT_SYMBOL vmlinux 0x99bb8806 memmove +EXPORT_SYMBOL vmlinux 0x99bfbe39 get_unused_fd +EXPORT_SYMBOL vmlinux 0x99c3c0b0 vfs_fstat +EXPORT_SYMBOL vmlinux 0x99cdc86b sysctl_tcp_reordering +EXPORT_SYMBOL vmlinux 0x99d11cb4 tty_hung_up_p +EXPORT_SYMBOL vmlinux 0x99d1f260 netlink_rcv_skb +EXPORT_SYMBOL vmlinux 0x99d4f3c1 scsi_scan_host +EXPORT_SYMBOL vmlinux 0x99ea12ce panic_blink +EXPORT_SYMBOL vmlinux 0x99fd11d1 xfrm_register_mode +EXPORT_SYMBOL vmlinux 0x9a108cd3 tcf_hash_release +EXPORT_SYMBOL vmlinux 0x9a1a1a54 iget_locked +EXPORT_SYMBOL vmlinux 0x9a1dfd65 strpbrk +EXPORT_SYMBOL vmlinux 0x9a763a2b tty_register_driver +EXPORT_SYMBOL vmlinux 0x9a965fd7 blk_queue_invalidate_tags +EXPORT_SYMBOL vmlinux 0x9aa90024 pcie_set_readrq +EXPORT_SYMBOL vmlinux 0x9ac524f8 scsi_is_host_device +EXPORT_SYMBOL vmlinux 0x9adc13ca tty_unregister_device +EXPORT_SYMBOL vmlinux 0x9afa1c15 put_disk +EXPORT_SYMBOL vmlinux 0x9b388444 get_zeroed_page +EXPORT_SYMBOL vmlinux 0x9b3f8e04 sk_stream_write_space +EXPORT_SYMBOL vmlinux 0x9b4b7ff6 tcp_poll +EXPORT_SYMBOL vmlinux 0x9b550346 input_event +EXPORT_SYMBOL vmlinux 0x9b76a978 d_alloc_root +EXPORT_SYMBOL vmlinux 0x9b776049 journal_revoke +EXPORT_SYMBOL vmlinux 0x9b8ef9fe splice_direct_to_actor +EXPORT_SYMBOL vmlinux 0x9ba7089d argv_split +EXPORT_SYMBOL vmlinux 0x9bce1364 __dst_free +EXPORT_SYMBOL vmlinux 0x9bce482f __release_region +EXPORT_SYMBOL vmlinux 0x9c02a657 inet_frags_init +EXPORT_SYMBOL vmlinux 0x9c19c548 neigh_connected_output +EXPORT_SYMBOL vmlinux 0x9c2571f4 __down_read +EXPORT_SYMBOL vmlinux 0x9c343960 __pci_register_driver +EXPORT_SYMBOL vmlinux 0x9c7077bd enable_hlt +EXPORT_SYMBOL vmlinux 0x9cb96e92 qdisc_put_rtab +EXPORT_SYMBOL vmlinux 0x9ceb163c memcpy_toiovec +EXPORT_SYMBOL vmlinux 0x9cf9d891 __kfree_skb +EXPORT_SYMBOL vmlinux 0x9cfd56c5 scsi_print_status +EXPORT_SYMBOL vmlinux 0x9d1e44b0 elv_add_request +EXPORT_SYMBOL vmlinux 0x9d669763 memcpy +EXPORT_SYMBOL vmlinux 0x9d76daf5 write_one_page +EXPORT_SYMBOL vmlinux 0x9dbfeea0 mb_cache_shrink +EXPORT_SYMBOL vmlinux 0x9e01d078 bdi_init +EXPORT_SYMBOL vmlinux 0x9e120414 ida_get_new_above +EXPORT_SYMBOL vmlinux 0x9e7d6bd0 __udelay +EXPORT_SYMBOL vmlinux 0x9e81a4a0 textsearch_register +EXPORT_SYMBOL vmlinux 0x9e97e409 set_binfmt +EXPORT_SYMBOL vmlinux 0x9eab73a0 d_instantiate_unique +EXPORT_SYMBOL vmlinux 0x9ec1b57f filemap_fdatawrite_range +EXPORT_SYMBOL vmlinux 0x9ec4cc1f mark_buffer_dirty +EXPORT_SYMBOL vmlinux 0x9ecc3cb0 ipv6_skip_exthdr +EXPORT_SYMBOL vmlinux 0x9ed685ee iov_iter_advance +EXPORT_SYMBOL vmlinux 0x9eecde16 do_brk +EXPORT_SYMBOL vmlinux 0x9ef749e2 unregister_chrdev +EXPORT_SYMBOL vmlinux 0x9f100139 jiffies_to_clock_t +EXPORT_SYMBOL vmlinux 0x9f231030 ethtool_op_get_link +EXPORT_SYMBOL vmlinux 0x9f2bdaac __bitmap_or +EXPORT_SYMBOL vmlinux 0x9f51c94a elv_rq_merge_ok +EXPORT_SYMBOL vmlinux 0x9f758271 tty_kref_put +EXPORT_SYMBOL vmlinux 0x9f984513 strrchr +EXPORT_SYMBOL vmlinux 0x9f9e08b7 set_bdi_congested +EXPORT_SYMBOL vmlinux 0x9fb3dd30 memcpy_fromiovec +EXPORT_SYMBOL vmlinux 0x9fbcfe13 bio_map_user +EXPORT_SYMBOL vmlinux 0x9fc85a5f get_user_pages +EXPORT_SYMBOL vmlinux 0x9fd5fc68 neigh_table_clear +EXPORT_SYMBOL vmlinux 0xa00c8310 dma_pool_destroy +EXPORT_SYMBOL vmlinux 0xa00db138 skb_free_datagram +EXPORT_SYMBOL vmlinux 0xa01c416e ll_rw_block +EXPORT_SYMBOL vmlinux 0xa04a01bd qdisc_class_hash_insert +EXPORT_SYMBOL vmlinux 0xa0563b08 dmam_alloc_noncoherent +EXPORT_SYMBOL vmlinux 0xa05c03df mempool_kmalloc +EXPORT_SYMBOL vmlinux 0xa079b779 pci_assign_resource +EXPORT_SYMBOL vmlinux 0xa07a8d22 sleep_on +EXPORT_SYMBOL vmlinux 0xa07ac24b irq_stat +EXPORT_SYMBOL vmlinux 0xa0b04675 vmalloc_32 +EXPORT_SYMBOL vmlinux 0xa0ceef51 out_of_line_wait_on_bit +EXPORT_SYMBOL vmlinux 0xa0fbac79 wake_up_bit +EXPORT_SYMBOL vmlinux 0xa108eb4d sysctl_optmem_max +EXPORT_SYMBOL vmlinux 0xa10dcc13 getrawmonotonic +EXPORT_SYMBOL vmlinux 0xa120d33c tty_unregister_ldisc +EXPORT_SYMBOL vmlinux 0xa13798f8 printk_ratelimit +EXPORT_SYMBOL vmlinux 0xa1596e63 bd_claim +EXPORT_SYMBOL vmlinux 0xa15a3de1 names_cachep +EXPORT_SYMBOL vmlinux 0xa15db998 blkdev_get +EXPORT_SYMBOL vmlinux 0xa1b2e57c inet_register_protosw +EXPORT_SYMBOL vmlinux 0xa1c76e0a _cond_resched +EXPORT_SYMBOL vmlinux 0xa1d494ca __dev_remove_pack +EXPORT_SYMBOL vmlinux 0xa20bd215 sock_register +EXPORT_SYMBOL vmlinux 0xa20c8ec8 pci_bus_alloc_resource +EXPORT_SYMBOL vmlinux 0xa20ce1b8 net_msg_warn +EXPORT_SYMBOL vmlinux 0xa20d93e5 try_to_free_buffers +EXPORT_SYMBOL vmlinux 0xa218bf61 complete +EXPORT_SYMBOL vmlinux 0xa227d5fd module_refcount +EXPORT_SYMBOL vmlinux 0xa26c826d dmam_release_declared_memory +EXPORT_SYMBOL vmlinux 0xa2760d20 __skb_checksum_complete +EXPORT_SYMBOL vmlinux 0xa29b1708 tcp_memory_allocated +EXPORT_SYMBOL vmlinux 0xa2a5fd77 inet_ehash_secret +EXPORT_SYMBOL vmlinux 0xa2cc6e6d inode_double_lock +EXPORT_SYMBOL vmlinux 0xa2d6cc77 d_move +EXPORT_SYMBOL vmlinux 0xa2de0f5a set_page_dirty_lock +EXPORT_SYMBOL vmlinux 0xa329f07e register_shrinker +EXPORT_SYMBOL vmlinux 0xa33e160a setup_arg_pages +EXPORT_SYMBOL vmlinux 0xa34f1ef5 crc32_le +EXPORT_SYMBOL vmlinux 0xa35de80f ipv4_config +EXPORT_SYMBOL vmlinux 0xa35ec9c4 scsi_calculate_bounce_limit +EXPORT_SYMBOL vmlinux 0xa3645827 grab_cache_page_write_begin +EXPORT_SYMBOL vmlinux 0xa37b9d84 pskb_copy +EXPORT_SYMBOL vmlinux 0xa3a4ed03 cond_resched_lock +EXPORT_SYMBOL vmlinux 0xa3ae8073 __page_symlink +EXPORT_SYMBOL vmlinux 0xa3bb9749 scsi_report_device_reset +EXPORT_SYMBOL vmlinux 0xa3d8c33a default_llseek +EXPORT_SYMBOL vmlinux 0xa3ea9a8b unregister_filesystem +EXPORT_SYMBOL vmlinux 0xa43f8021 xfrm4_rcv_encap +EXPORT_SYMBOL vmlinux 0xa4614667 sk_reset_timer +EXPORT_SYMBOL vmlinux 0xa464ed4e scsi_device_resume +EXPORT_SYMBOL vmlinux 0xa48a02ce compute_creds +EXPORT_SYMBOL vmlinux 0xa4fb83ec gnet_stats_start_copy +EXPORT_SYMBOL vmlinux 0xa5109b36 blk_alloc_queue_node +EXPORT_SYMBOL vmlinux 0xa53dc143 ethtool_op_set_ufo +EXPORT_SYMBOL vmlinux 0xa5423cc4 param_get_int +EXPORT_SYMBOL vmlinux 0xa54b780a dcache_dir_lseek +EXPORT_SYMBOL vmlinux 0xa5808bbf tasklet_init +EXPORT_SYMBOL vmlinux 0xa5866487 tty_insert_flip_string +EXPORT_SYMBOL vmlinux 0xa58b6804 nla_parse +EXPORT_SYMBOL vmlinux 0xa5a0b837 con_copy_unimap +EXPORT_SYMBOL vmlinux 0xa5ad165e find_get_page +EXPORT_SYMBOL vmlinux 0xa5b07b34 inet_addr_type +EXPORT_SYMBOL vmlinux 0xa5cef8ad release_resource +EXPORT_SYMBOL vmlinux 0xa6052842 vfs_readlink +EXPORT_SYMBOL vmlinux 0xa62432af netif_device_detach +EXPORT_SYMBOL vmlinux 0xa62693ad unregister_exec_domain +EXPORT_SYMBOL vmlinux 0xa6673095 __elv_add_request +EXPORT_SYMBOL vmlinux 0xa68124fa hweight8 +EXPORT_SYMBOL vmlinux 0xa681fe88 generate_random_uuid +EXPORT_SYMBOL vmlinux 0xa69df7de __insert_inode_hash +EXPORT_SYMBOL vmlinux 0xa69f7350 get_sb_bdev +EXPORT_SYMBOL vmlinux 0xa6dcc773 rb_insert_color +EXPORT_SYMBOL vmlinux 0xa6fa16e2 vfs_readdir +EXPORT_SYMBOL vmlinux 0xa7493093 mpage_writepage +EXPORT_SYMBOL vmlinux 0xa74b89ba simple_sync_file +EXPORT_SYMBOL vmlinux 0xa7502f48 jiffies_to_timeval +EXPORT_SYMBOL vmlinux 0xa75470dc blk_dump_rq_flags +EXPORT_SYMBOL vmlinux 0xa7668700 d_genocide +EXPORT_SYMBOL vmlinux 0xa786ac0d inode_double_unlock +EXPORT_SYMBOL vmlinux 0xa7aa94fc mii_nway_restart +EXPORT_SYMBOL vmlinux 0xa7c35c6b getnstimeofday +EXPORT_SYMBOL vmlinux 0xa7c5f3ad inet_frag_destroy +EXPORT_SYMBOL vmlinux 0xa7c994aa single_release +EXPORT_SYMBOL vmlinux 0xa7cfb238 journal_release_buffer +EXPORT_SYMBOL vmlinux 0xa85c4e66 pcix_get_max_mmrbc +EXPORT_SYMBOL vmlinux 0xa86c7b81 nf_log_unregister +EXPORT_SYMBOL vmlinux 0xa89e9b2a vmtruncate +EXPORT_SYMBOL vmlinux 0xa905d8e6 devm_ioport_map +EXPORT_SYMBOL vmlinux 0xa925899a param_set_bool +EXPORT_SYMBOL vmlinux 0xa94eb2da page_zero_new_buffers +EXPORT_SYMBOL vmlinux 0xa959a8ef inet_sock_destruct +EXPORT_SYMBOL vmlinux 0xa9f1ed23 bit_waitqueue +EXPORT_SYMBOL vmlinux 0xaa0e7924 netdev_features_change +EXPORT_SYMBOL vmlinux 0xaa16e567 dma_release_declared_memory +EXPORT_SYMBOL vmlinux 0xaa527612 __kfifo_put +EXPORT_SYMBOL vmlinux 0xaa644e6c generic_writepages +EXPORT_SYMBOL vmlinux 0xaaebe232 __bug +EXPORT_SYMBOL vmlinux 0xaaf14216 mpage_readpages +EXPORT_SYMBOL vmlinux 0xaafdc258 strcasecmp +EXPORT_SYMBOL vmlinux 0xab371c5d skb_add_rx_frag +EXPORT_SYMBOL vmlinux 0xab451afa sock_common_setsockopt +EXPORT_SYMBOL vmlinux 0xab471003 param_array_set +EXPORT_SYMBOL vmlinux 0xab53b0a8 mempool_alloc +EXPORT_SYMBOL vmlinux 0xab600421 probe_irq_off +EXPORT_SYMBOL vmlinux 0xab64527d mutex_lock_interruptible +EXPORT_SYMBOL vmlinux 0xab680c96 __down_read_trylock +EXPORT_SYMBOL vmlinux 0xabad83d7 udp_hash_lock +EXPORT_SYMBOL vmlinux 0xabd0c91c rtc_time_to_tm +EXPORT_SYMBOL vmlinux 0xabd0d5ba dget_locked +EXPORT_SYMBOL vmlinux 0xabf86ed2 get_disk +EXPORT_SYMBOL vmlinux 0xabff4f20 ip_route_me_harder +EXPORT_SYMBOL vmlinux 0xac06cfc6 input_unregister_handler +EXPORT_SYMBOL vmlinux 0xac2d1644 __f_setown +EXPORT_SYMBOL vmlinux 0xac2ec73d dma_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0xac369721 sk_alloc +EXPORT_SYMBOL vmlinux 0xac3b3cee __bitmap_and +EXPORT_SYMBOL vmlinux 0xac402b0b tty_port_init +EXPORT_SYMBOL vmlinux 0xac54fc9f mempool_destroy +EXPORT_SYMBOL vmlinux 0xac5f113d cpu_all_bits +EXPORT_SYMBOL vmlinux 0xac63704a blk_run_queue +EXPORT_SYMBOL vmlinux 0xac94992b file_remove_suid +EXPORT_SYMBOL vmlinux 0xaccabc6a in4_pton +EXPORT_SYMBOL vmlinux 0xacf4d843 match_strdup +EXPORT_SYMBOL vmlinux 0xad0413d4 match_hex +EXPORT_SYMBOL vmlinux 0xad55c4f6 __blockdev_direct_IO +EXPORT_SYMBOL vmlinux 0xadb792c2 prepare_to_wait_exclusive +EXPORT_SYMBOL vmlinux 0xadec9034 neigh_seq_start +EXPORT_SYMBOL vmlinux 0xae20b45b __mpage_writepage +EXPORT_SYMBOL vmlinux 0xae3bcea1 task_pgrp_nr_ns +EXPORT_SYMBOL vmlinux 0xae5b064b ethtool_op_set_flags +EXPORT_SYMBOL vmlinux 0xae783676 blk_queue_max_phys_segments +EXPORT_SYMBOL vmlinux 0xaebe73a3 vfs_mknod +EXPORT_SYMBOL vmlinux 0xaec655c7 alloc_pages_exact +EXPORT_SYMBOL vmlinux 0xaed013b9 posix_acl_valid +EXPORT_SYMBOL vmlinux 0xaee89596 mii_link_ok +EXPORT_SYMBOL vmlinux 0xaef5dc13 uart_add_one_port +EXPORT_SYMBOL vmlinux 0xaf035130 simple_transaction_get +EXPORT_SYMBOL vmlinux 0xaf3c5d47 sock_setsockopt +EXPORT_SYMBOL vmlinux 0xaf50e76d elf_set_personality +EXPORT_SYMBOL vmlinux 0xaf8aa518 system_rev +EXPORT_SYMBOL vmlinux 0xaf9b7112 mii_ethtool_gset +EXPORT_SYMBOL vmlinux 0xafb00f36 block_is_partially_uptodate +EXPORT_SYMBOL vmlinux 0xafb35e5c sock_no_getname +EXPORT_SYMBOL vmlinux 0xafc8893d generic_file_open +EXPORT_SYMBOL vmlinux 0xb0114773 mpage_bio_submit +EXPORT_SYMBOL vmlinux 0xb0b1caa0 pci_lost_interrupt +EXPORT_SYMBOL vmlinux 0xb0b847ac __bitmap_full +EXPORT_SYMBOL vmlinux 0xb0e10781 get_option +EXPORT_SYMBOL vmlinux 0xb0f42c0c bdevname +EXPORT_SYMBOL vmlinux 0xb10c39c6 skb_over_panic +EXPORT_SYMBOL vmlinux 0xb121390a probe_irq_on +EXPORT_SYMBOL vmlinux 0xb13e9c62 send_sig_info +EXPORT_SYMBOL vmlinux 0xb142eefa unregister_sysrq_key +EXPORT_SYMBOL vmlinux 0xb171a272 vfs_symlink +EXPORT_SYMBOL vmlinux 0xb17ef71f nlmsg_notify +EXPORT_SYMBOL vmlinux 0xb19760c3 bitmap_onto +EXPORT_SYMBOL vmlinux 0xb1c3a01a oops_in_progress +EXPORT_SYMBOL vmlinux 0xb1f8a727 call_usermodehelper_setcleanup +EXPORT_SYMBOL vmlinux 0xb2175df3 find_lock_page +EXPORT_SYMBOL vmlinux 0xb22fe6a3 netdev_increment_features +EXPORT_SYMBOL vmlinux 0xb2668bcd seq_puts +EXPORT_SYMBOL vmlinux 0xb2746cc7 vm_insert_mixed +EXPORT_SYMBOL vmlinux 0xb2897524 scsi_host_lookup +EXPORT_SYMBOL vmlinux 0xb2b3f316 balance_dirty_pages_ratelimited_nr +EXPORT_SYMBOL vmlinux 0xb2bf1312 __up_read +EXPORT_SYMBOL vmlinux 0xb2ea277d pci_bus_type +EXPORT_SYMBOL vmlinux 0xb3001f8f sock_create_kern +EXPORT_SYMBOL vmlinux 0xb304eb85 ilookup +EXPORT_SYMBOL vmlinux 0xb31f3ef3 __nla_put_nohdr +EXPORT_SYMBOL vmlinux 0xb35d628b tcp_enter_memory_pressure +EXPORT_SYMBOL vmlinux 0xb36c5e80 tcf_em_tree_validate +EXPORT_SYMBOL vmlinux 0xb376d79d radix_tree_tagged +EXPORT_SYMBOL vmlinux 0xb379f9e9 task_nice +EXPORT_SYMBOL vmlinux 0xb37ad437 per_cpu__kstat +EXPORT_SYMBOL vmlinux 0xb392abca grab_cache_page_nowait +EXPORT_SYMBOL vmlinux 0xb3a307c6 si_meminfo +EXPORT_SYMBOL vmlinux 0xb3c68ecf tcp_rcv_state_process +EXPORT_SYMBOL vmlinux 0xb3d10c03 simple_dir_operations +EXPORT_SYMBOL vmlinux 0xb3d21d06 blk_init_queue +EXPORT_SYMBOL vmlinux 0xb3e9cba5 free_buffer_head +EXPORT_SYMBOL vmlinux 0xb3efa805 do_mmap_pgoff +EXPORT_SYMBOL vmlinux 0xb3fe02b1 down_write +EXPORT_SYMBOL vmlinux 0xb423dba1 console_blanked +EXPORT_SYMBOL vmlinux 0xb478b7f7 journal_errno +EXPORT_SYMBOL vmlinux 0xb494e82a br_fdb_put_hook +EXPORT_SYMBOL vmlinux 0xb4a0e989 init_timer_deferrable +EXPORT_SYMBOL vmlinux 0xb4dca972 textsearch_destroy +EXPORT_SYMBOL vmlinux 0xb4f78507 d_namespace_path +EXPORT_SYMBOL vmlinux 0xb4fff42f open_by_devnum +EXPORT_SYMBOL vmlinux 0xb5044271 vsscanf +EXPORT_SYMBOL vmlinux 0xb51af9b3 ip_route_output_key +EXPORT_SYMBOL vmlinux 0xb5208e13 lease_get_mtime +EXPORT_SYMBOL vmlinux 0xb5285ba6 nf_log_register +EXPORT_SYMBOL vmlinux 0xb534763c sg_free_table +EXPORT_SYMBOL vmlinux 0xb54533f7 usecs_to_jiffies +EXPORT_SYMBOL vmlinux 0xb54edec6 nf_hook_slow +EXPORT_SYMBOL vmlinux 0xb58b72c4 save_mount_options +EXPORT_SYMBOL vmlinux 0xb590e4f1 pci_get_class +EXPORT_SYMBOL vmlinux 0xb5a459dc unregister_blkdev +EXPORT_SYMBOL vmlinux 0xb5b1ffff kill_block_super +EXPORT_SYMBOL vmlinux 0xb60b4975 blk_stop_queue +EXPORT_SYMBOL vmlinux 0xb60e34a8 nla_memcpy +EXPORT_SYMBOL vmlinux 0xb63cb93f sysctl_string +EXPORT_SYMBOL vmlinux 0xb678366f int_sqrt +EXPORT_SYMBOL vmlinux 0xb67dfa7f skb_push +EXPORT_SYMBOL vmlinux 0xb687443d ethtool_op_get_tx_csum +EXPORT_SYMBOL vmlinux 0xb6911588 write_cache_pages +EXPORT_SYMBOL vmlinux 0xb69e19ca posix_lock_file +EXPORT_SYMBOL vmlinux 0xb6a5fa22 dev_get_by_flags +EXPORT_SYMBOL vmlinux 0xb6a61a86 qdisc_get_rtab +EXPORT_SYMBOL vmlinux 0xb6c5a973 scsi_show_result +EXPORT_SYMBOL vmlinux 0xb6c70a7d __wake_up +EXPORT_SYMBOL vmlinux 0xb703911e release_firmware +EXPORT_SYMBOL vmlinux 0xb714a981 console_print +EXPORT_SYMBOL vmlinux 0xb75044e9 current_fs_time +EXPORT_SYMBOL vmlinux 0xb7555f12 timeval_to_jiffies +EXPORT_SYMBOL vmlinux 0xb76770ea seq_bitmap_list +EXPORT_SYMBOL vmlinux 0xb76c563d vm_map_ram +EXPORT_SYMBOL vmlinux 0xb77d23df sk_filter +EXPORT_SYMBOL vmlinux 0xb794b050 __bio_clone +EXPORT_SYMBOL vmlinux 0xb7aa1ee1 get_io_context +EXPORT_SYMBOL vmlinux 0xb7ad3321 ida_init +EXPORT_SYMBOL vmlinux 0xb7b61546 crc32_be +EXPORT_SYMBOL vmlinux 0xb7c3f52e inet_ioctl +EXPORT_SYMBOL vmlinux 0xb7dda6bb get_sb_nodev +EXPORT_SYMBOL vmlinux 0xb859f38b krealloc +EXPORT_SYMBOL vmlinux 0xb863585e n_tty_ioctl_helper +EXPORT_SYMBOL vmlinux 0xb86e4ab9 random32 +EXPORT_SYMBOL vmlinux 0xb89af9bf srandom32 +EXPORT_SYMBOL vmlinux 0xb8aa2342 __check_region +EXPORT_SYMBOL vmlinux 0xb8d404be kmem_cache_destroy +EXPORT_SYMBOL vmlinux 0xb9148418 blkdev_issue_flush +EXPORT_SYMBOL vmlinux 0xb93ed40b fasync_helper +EXPORT_SYMBOL vmlinux 0xb9486bf0 scsi_setup_fs_cmnd +EXPORT_SYMBOL vmlinux 0xb94e207d dma_map_page +EXPORT_SYMBOL vmlinux 0xb95adc0e vmap +EXPORT_SYMBOL vmlinux 0xb95f98d6 _memset_io +EXPORT_SYMBOL vmlinux 0xb97d4c9c mutex_lock +EXPORT_SYMBOL vmlinux 0xb98a0185 rtc_tm_to_time +EXPORT_SYMBOL vmlinux 0xb98ef804 vm_stat +EXPORT_SYMBOL vmlinux 0xb9acd3d9 __put_user_2 +EXPORT_SYMBOL vmlinux 0xb9c74bf1 gen_kill_estimator +EXPORT_SYMBOL vmlinux 0xba3bda2a __downgrade_write +EXPORT_SYMBOL vmlinux 0xba497f13 loops_per_jiffy +EXPORT_SYMBOL vmlinux 0xba5078fd xscale_flush_kern_cache_all +EXPORT_SYMBOL vmlinux 0xba8f8b68 completion_done +EXPORT_SYMBOL vmlinux 0xbac327c8 page_readlink +EXPORT_SYMBOL vmlinux 0xbb173b51 mb_cache_entry_release +EXPORT_SYMBOL vmlinux 0xbb189cad disallow_signal +EXPORT_SYMBOL vmlinux 0xbb289aad add_disk +EXPORT_SYMBOL vmlinux 0xbb47968b flush_dcache_page +EXPORT_SYMBOL vmlinux 0xbb5aaca9 filemap_fault +EXPORT_SYMBOL vmlinux 0xbb5d343d xfrm_get_acqseq +EXPORT_SYMBOL vmlinux 0xbb72d4fe __put_user_1 +EXPORT_SYMBOL vmlinux 0xbb77563f alloc_pci_dev +EXPORT_SYMBOL vmlinux 0xbba61c16 ixp4xx_pci_read +EXPORT_SYMBOL vmlinux 0xbbb0dbae cancel_dirty_page +EXPORT_SYMBOL vmlinux 0xbbbbe042 simple_rmdir +EXPORT_SYMBOL vmlinux 0xbbc8e804 param_set_ushort +EXPORT_SYMBOL vmlinux 0xbbd148c9 generic_unplug_device +EXPORT_SYMBOL vmlinux 0xbc10dd97 __put_user_4 +EXPORT_SYMBOL vmlinux 0xbc87c127 vfs_follow_link +EXPORT_SYMBOL vmlinux 0xbcd2ea92 find_or_create_page +EXPORT_SYMBOL vmlinux 0xbcda0784 udp_proc_register +EXPORT_SYMBOL vmlinux 0xbd788e78 pid_task +EXPORT_SYMBOL vmlinux 0xbda0c40b uart_write_wakeup +EXPORT_SYMBOL vmlinux 0xbde0feec bdi_set_max_ratio +EXPORT_SYMBOL vmlinux 0xbdf2580d __raw_readsl +EXPORT_SYMBOL vmlinux 0xbe0adc3b blk_complete_request +EXPORT_SYMBOL vmlinux 0xbe0e5118 nla_memcmp +EXPORT_SYMBOL vmlinux 0xbe3e409a ip_mc_rejoin_group +EXPORT_SYMBOL vmlinux 0xbe63ee40 request_resource +EXPORT_SYMBOL vmlinux 0xbe82135b cad_pid +EXPORT_SYMBOL vmlinux 0xbeac39e0 clear_page_dirty_for_io +EXPORT_SYMBOL vmlinux 0xbecb5d00 qdisc_watchdog_schedule +EXPORT_SYMBOL vmlinux 0xbed21e46 seq_open_private +EXPORT_SYMBOL vmlinux 0xbed451b2 seq_release +EXPORT_SYMBOL vmlinux 0xbef43296 console_conditional_schedule +EXPORT_SYMBOL vmlinux 0xbf7fd2f5 schedule_timeout_killable +EXPORT_SYMBOL vmlinux 0xbf9079df datagram_poll +EXPORT_SYMBOL vmlinux 0xbf9334fb blk_queue_set_discard +EXPORT_SYMBOL vmlinux 0xbf9bcc8d __cap_empty_set +EXPORT_SYMBOL vmlinux 0xbfd58661 pcim_iounmap_regions +EXPORT_SYMBOL vmlinux 0xbffe4725 dev_unicast_add +EXPORT_SYMBOL vmlinux 0xc000228c xfrm_alloc_spi +EXPORT_SYMBOL vmlinux 0xc015858a udp_lib_get_port +EXPORT_SYMBOL vmlinux 0xc045ad4e timespec_trunc +EXPORT_SYMBOL vmlinux 0xc057deda read_dev_sector +EXPORT_SYMBOL vmlinux 0xc0580937 rb_erase +EXPORT_SYMBOL vmlinux 0xc08a6562 pci_find_parent_resource +EXPORT_SYMBOL vmlinux 0xc0add046 d_splice_alias +EXPORT_SYMBOL vmlinux 0xc0b9ce5f hub_port_logical_disconnect +EXPORT_SYMBOL vmlinux 0xc0d89cb2 qmgr_set_irq +EXPORT_SYMBOL vmlinux 0xc11d8093 iov_shorten +EXPORT_SYMBOL vmlinux 0xc1306dce dma_sync_sg_for_cpu +EXPORT_SYMBOL vmlinux 0xc1595348 proto_unregister +EXPORT_SYMBOL vmlinux 0xc1601a4f _change_bit_le +EXPORT_SYMBOL vmlinux 0xc1bebdd5 ethtool_op_get_ufo +EXPORT_SYMBOL vmlinux 0xc1e2ab5f kobject_del +EXPORT_SYMBOL vmlinux 0xc1fc4511 _test_and_change_bit_le +EXPORT_SYMBOL vmlinux 0xc20be1b9 dev_mc_delete +EXPORT_SYMBOL vmlinux 0xc22616f1 __init_rwsem +EXPORT_SYMBOL vmlinux 0xc256e762 __bitmap_equal +EXPORT_SYMBOL vmlinux 0xc274fbb7 __ip_select_ident +EXPORT_SYMBOL vmlinux 0xc275f43d pci_set_master +EXPORT_SYMBOL vmlinux 0xc27c2dea inet_proto_csum_replace4 +EXPORT_SYMBOL vmlinux 0xc2a412af scsi_cmd_ioctl +EXPORT_SYMBOL vmlinux 0xc2e587d1 reset_devices +EXPORT_SYMBOL vmlinux 0xc2f3f019 gnet_stats_finish_copy +EXPORT_SYMBOL vmlinux 0xc312daa0 __nla_reserve +EXPORT_SYMBOL vmlinux 0xc3226a6c pcix_set_mmrbc +EXPORT_SYMBOL vmlinux 0xc359fb65 abort +EXPORT_SYMBOL vmlinux 0xc37aacab dma_pool_free +EXPORT_SYMBOL vmlinux 0xc39efd8d sg_miter_stop +EXPORT_SYMBOL vmlinux 0xc3c19d02 seq_putc +EXPORT_SYMBOL vmlinux 0xc3ca410f sg_miter_next +EXPORT_SYMBOL vmlinux 0xc3cf1128 in_group_p +EXPORT_SYMBOL vmlinux 0xc440c451 sg_alloc_table +EXPORT_SYMBOL vmlinux 0xc461a176 scsi_remove_host +EXPORT_SYMBOL vmlinux 0xc46d2a6f noop_qdisc +EXPORT_SYMBOL vmlinux 0xc46d68cf get_sb_pseudo +EXPORT_SYMBOL vmlinux 0xc46dd019 journal_forget +EXPORT_SYMBOL vmlinux 0xc48a9de1 call_usermodehelper_setup +EXPORT_SYMBOL vmlinux 0xc499ae1e kstrdup +EXPORT_SYMBOL vmlinux 0xc4cc68ff scsi_print_command +EXPORT_SYMBOL vmlinux 0xc5169671 bio_init +EXPORT_SYMBOL vmlinux 0xc541a4a9 flush_old_exec +EXPORT_SYMBOL vmlinux 0xc5670ca2 nf_ct_attach +EXPORT_SYMBOL vmlinux 0xc5c4a7d7 init_file +EXPORT_SYMBOL vmlinux 0xc5e0cd0b nf_register_hooks +EXPORT_SYMBOL vmlinux 0xc5e50b4f elevator_exit +EXPORT_SYMBOL vmlinux 0xc5e58762 xfrm_unregister_type +EXPORT_SYMBOL vmlinux 0xc6009ba4 release_sock +EXPORT_SYMBOL vmlinux 0xc60ab1ec pcie_get_readrq +EXPORT_SYMBOL vmlinux 0xc625d2b9 ixp4xx_exp_bus_size +EXPORT_SYMBOL vmlinux 0xc62cf616 kernel_getpeername +EXPORT_SYMBOL vmlinux 0xc633495b schedule_work +EXPORT_SYMBOL vmlinux 0xc634ee28 bio_copy_user +EXPORT_SYMBOL vmlinux 0xc6618e57 journal_start_commit +EXPORT_SYMBOL vmlinux 0xc6a680cd tcp_connect +EXPORT_SYMBOL vmlinux 0xc6b71b3c skb_copy_bits +EXPORT_SYMBOL vmlinux 0xc6be9a32 generic_cont_expand_simple +EXPORT_SYMBOL vmlinux 0xc6c33e9a dma_unmap_single +EXPORT_SYMBOL vmlinux 0xc6c55c27 scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0xc6ca5327 nf_setsockopt +EXPORT_SYMBOL vmlinux 0xc7153b1e genl_sock +EXPORT_SYMBOL vmlinux 0xc7208c3a serial8250_resume_port +EXPORT_SYMBOL vmlinux 0xc722227e posix_acl_clone +EXPORT_SYMBOL vmlinux 0xc73ddc9e pci_get_slot +EXPORT_SYMBOL vmlinux 0xc76f0498 qdisc_reset +EXPORT_SYMBOL vmlinux 0xc775da42 bio_get_nr_vecs +EXPORT_SYMBOL vmlinux 0xc7a4fbed rtnl_lock +EXPORT_SYMBOL vmlinux 0xc7cb8717 tcf_hash_check +EXPORT_SYMBOL vmlinux 0xc7e6b34b submit_bio +EXPORT_SYMBOL vmlinux 0xc7ec6c27 strspn +EXPORT_SYMBOL vmlinux 0xc7f8874b seq_escape +EXPORT_SYMBOL vmlinux 0xc8000629 tcf_em_tree_destroy +EXPORT_SYMBOL vmlinux 0xc805c958 d_invalidate +EXPORT_SYMBOL vmlinux 0xc80a47a7 npe_load_firmware +EXPORT_SYMBOL vmlinux 0xc80de694 down_write_trylock +EXPORT_SYMBOL vmlinux 0xc834e7ac tty_unregister_driver +EXPORT_SYMBOL vmlinux 0xc83c17b8 unregister_binfmt +EXPORT_SYMBOL vmlinux 0xc85aeddd take_over_console +EXPORT_SYMBOL vmlinux 0xc883bc87 pci_set_mwi +EXPORT_SYMBOL vmlinux 0xc8b1d16e drop_super +EXPORT_SYMBOL vmlinux 0xc8b57c27 autoremove_wake_function +EXPORT_SYMBOL vmlinux 0xc8c0b49d sk_stream_wait_connect +EXPORT_SYMBOL vmlinux 0xc8c1e49e journal_init_dev +EXPORT_SYMBOL vmlinux 0xc937f49d uart_register_driver +EXPORT_SYMBOL vmlinux 0xc998d641 icmp_err_convert +EXPORT_SYMBOL vmlinux 0xc9a6de51 inet_frags_exit_net +EXPORT_SYMBOL vmlinux 0xc9b35e50 scsi_prep_state_check +EXPORT_SYMBOL vmlinux 0xc9bc5b96 km_state_notify +EXPORT_SYMBOL vmlinux 0xc9cf439f __kill_fasync +EXPORT_SYMBOL vmlinux 0xca2d08bf lock_super +EXPORT_SYMBOL vmlinux 0xca4e285c blk_queue_dma_pad +EXPORT_SYMBOL vmlinux 0xca4f06dc nf_log_packet +EXPORT_SYMBOL vmlinux 0xca50b84f vfs_getattr +EXPORT_SYMBOL vmlinux 0xca5dbc50 scsi_print_sense_hdr +EXPORT_SYMBOL vmlinux 0xca750aef gnet_stats_copy_rate_est +EXPORT_SYMBOL vmlinux 0xca91986f sync_mapping_buffers +EXPORT_SYMBOL vmlinux 0xcaa448d3 blk_queue_softirq_done +EXPORT_SYMBOL vmlinux 0xcb32da10 param_set_int +EXPORT_SYMBOL vmlinux 0xcb37a42f __devm_release_region +EXPORT_SYMBOL vmlinux 0xcb4e793d bio_kmalloc +EXPORT_SYMBOL vmlinux 0xcb6beb40 hweight32 +EXPORT_SYMBOL vmlinux 0xcb8140c0 xfrm_policy_walk +EXPORT_SYMBOL vmlinux 0xcb9bea8d pcim_enable_device +EXPORT_SYMBOL vmlinux 0xcbce1325 scsi_device_set_state +EXPORT_SYMBOL vmlinux 0xcbce216c misc_deregister +EXPORT_SYMBOL vmlinux 0xcc10b623 register_filesystem +EXPORT_SYMBOL vmlinux 0xcc248d26 serial8250_suspend_port +EXPORT_SYMBOL vmlinux 0xcc36f32e fb_unregister_client +EXPORT_SYMBOL vmlinux 0xcc5005fe msleep_interruptible +EXPORT_SYMBOL vmlinux 0xcc72acce netdev_class_create_file +EXPORT_SYMBOL vmlinux 0xcc7ee4fa tcp_timewait_state_process +EXPORT_SYMBOL vmlinux 0xcc7fa952 local_bh_enable_ip +EXPORT_SYMBOL vmlinux 0xcca002fd cdev_add +EXPORT_SYMBOL vmlinux 0xccaff73d call_usermodehelper_pipe +EXPORT_SYMBOL vmlinux 0xccb93808 pagevec_lookup +EXPORT_SYMBOL vmlinux 0xcccca482 _test_and_clear_bit_le +EXPORT_SYMBOL vmlinux 0xcce15f27 simple_release_fs +EXPORT_SYMBOL vmlinux 0xcd088b07 inet_stream_ops +EXPORT_SYMBOL vmlinux 0xcd63c845 __aeabi_lasr +EXPORT_SYMBOL vmlinux 0xcdb2c148 vfs_path_lookup +EXPORT_SYMBOL vmlinux 0xcdec3890 __set_page_dirty_buffers +EXPORT_SYMBOL vmlinux 0xce303da0 del_mtd_partitions +EXPORT_SYMBOL vmlinux 0xce36ded6 sysctl_tcp_mem +EXPORT_SYMBOL vmlinux 0xce4699b5 inode_sub_bytes +EXPORT_SYMBOL vmlinux 0xce910b31 xfrm_state_add +EXPORT_SYMBOL vmlinux 0xcedf44dc blk_rq_map_user_iov +EXPORT_SYMBOL vmlinux 0xcefcd99a serial8250_unregister_port +EXPORT_SYMBOL vmlinux 0xcf0c0372 kfree_skb +EXPORT_SYMBOL vmlinux 0xcf5449e3 __fatal_signal_pending +EXPORT_SYMBOL vmlinux 0xcf57e5bf d_find_alias +EXPORT_SYMBOL vmlinux 0xcf65629f tcf_em_register +EXPORT_SYMBOL vmlinux 0xcf6d484d netif_rx_ni +EXPORT_SYMBOL vmlinux 0xcf8e60ae scsi_dma_unmap +EXPORT_SYMBOL vmlinux 0xcfbc9211 blk_queue_max_hw_segments +EXPORT_SYMBOL vmlinux 0xcfbe6d36 vfs_mkdir +EXPORT_SYMBOL vmlinux 0xcfd3018e set_normalized_timespec +EXPORT_SYMBOL vmlinux 0xcfdac9e0 lock_sock_nested +EXPORT_SYMBOL vmlinux 0xcfefb25a pci_scan_single_device +EXPORT_SYMBOL vmlinux 0xcff53400 kref_put +EXPORT_SYMBOL vmlinux 0xd0181f4f __bitmap_xor +EXPORT_SYMBOL vmlinux 0xd02cc869 __bitmap_andnot +EXPORT_SYMBOL vmlinux 0xd03268f3 scsi_block_requests +EXPORT_SYMBOL vmlinux 0xd07704f7 register_binfmt +EXPORT_SYMBOL vmlinux 0xd07b9d49 __locks_copy_lock +EXPORT_SYMBOL vmlinux 0xd0b5bfed wireless_send_event +EXPORT_SYMBOL vmlinux 0xd0eb51fc neigh_ifdown +EXPORT_SYMBOL vmlinux 0xd0ee38b8 schedule_timeout_uninterruptible +EXPORT_SYMBOL vmlinux 0xd0f20191 dma_mmap_coherent +EXPORT_SYMBOL vmlinux 0xd0f40219 xfrm_policy_unregister_afinfo +EXPORT_SYMBOL vmlinux 0xd0f65684 mem_map +EXPORT_SYMBOL vmlinux 0xd0f7173c journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0xd110a1d0 prepare_binprm +EXPORT_SYMBOL vmlinux 0xd115686e proc_doulongvec_ms_jiffies_minmax +EXPORT_SYMBOL vmlinux 0xd1208a98 kill_litter_super +EXPORT_SYMBOL vmlinux 0xd13927bf qdisc_calculate_pkt_len +EXPORT_SYMBOL vmlinux 0xd168d8b9 cpu_xscale_dcache_clean_area +EXPORT_SYMBOL vmlinux 0xd1770c83 pci_iounmap +EXPORT_SYMBOL vmlinux 0xd1a1f768 pci_remove_bus_device +EXPORT_SYMBOL vmlinux 0xd1a3b97a kernel_getsockname +EXPORT_SYMBOL vmlinux 0xd20afeb7 scsi_print_result +EXPORT_SYMBOL vmlinux 0xd20e7f95 pci_find_next_bus +EXPORT_SYMBOL vmlinux 0xd223734e kernel_sock_ioctl +EXPORT_SYMBOL vmlinux 0xd232b066 blk_start_queueing +EXPORT_SYMBOL vmlinux 0xd2555f19 jiffies_64_to_clock_t +EXPORT_SYMBOL vmlinux 0xd25d4f74 console_blank_hook +EXPORT_SYMBOL vmlinux 0xd278aadf journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0xd2965f6f kthread_should_stop +EXPORT_SYMBOL vmlinux 0xd2d45b10 qmgr_release_queue +EXPORT_SYMBOL vmlinux 0xd301dd51 mapping_tagged +EXPORT_SYMBOL vmlinux 0xd32e52c7 posix_acl_chmod_masq +EXPORT_SYMBOL vmlinux 0xd340ad56 inet_csk_destroy_sock +EXPORT_SYMBOL vmlinux 0xd3427f73 mempool_create_node +EXPORT_SYMBOL vmlinux 0xd375fcfc udp_proc_unregister +EXPORT_SYMBOL vmlinux 0xd38fab41 sock_no_getsockopt +EXPORT_SYMBOL vmlinux 0xd395ea70 proc_dointvec_userhz_jiffies +EXPORT_SYMBOL vmlinux 0xd3a35efc __seq_open_private +EXPORT_SYMBOL vmlinux 0xd3c05dd7 posix_acl_permission +EXPORT_SYMBOL vmlinux 0xd3c6b322 pci_fixup_device +EXPORT_SYMBOL vmlinux 0xd3dbfbc4 _find_first_zero_bit_le +EXPORT_SYMBOL vmlinux 0xd3e09288 get_fs_type +EXPORT_SYMBOL vmlinux 0xd40bb229 create_proc_entry +EXPORT_SYMBOL vmlinux 0xd418e1c0 adjust_resource +EXPORT_SYMBOL vmlinux 0xd429158e tcf_exts_destroy +EXPORT_SYMBOL vmlinux 0xd442dbbe tcp_rcv_established +EXPORT_SYMBOL vmlinux 0xd44815ff blk_free_tags +EXPORT_SYMBOL vmlinux 0xd44fd061 call_usermodehelper_freeinfo +EXPORT_SYMBOL vmlinux 0xd463f3b6 km_query +EXPORT_SYMBOL vmlinux 0xd4d5e63a __netdev_alloc_skb +EXPORT_SYMBOL vmlinux 0xd4dfd48d journal_get_undo_access +EXPORT_SYMBOL vmlinux 0xd51c3d17 mntput_no_expire +EXPORT_SYMBOL vmlinux 0xd5259bec pci_disable_device +EXPORT_SYMBOL vmlinux 0xd5263820 mb_cache_destroy +EXPORT_SYMBOL vmlinux 0xd555ba1b scsi_register_driver +EXPORT_SYMBOL vmlinux 0xd55b1213 __secpath_destroy +EXPORT_SYMBOL vmlinux 0xd5688a7a radix_tree_insert +EXPORT_SYMBOL vmlinux 0xd583aa82 __neigh_event_send +EXPORT_SYMBOL vmlinux 0xd5bbeacb __sk_mem_reclaim +EXPORT_SYMBOL vmlinux 0xd5f6d7c9 generic_show_options +EXPORT_SYMBOL vmlinux 0xd6035d05 do_settimeofday +EXPORT_SYMBOL vmlinux 0xd627480b strncat +EXPORT_SYMBOL vmlinux 0xd62c833f schedule_timeout +EXPORT_SYMBOL vmlinux 0xd65300d0 __lock_buffer +EXPORT_SYMBOL vmlinux 0xd665205c alloc_netdev_mq +EXPORT_SYMBOL vmlinux 0xd66c6228 down_read_trylock +EXPORT_SYMBOL vmlinux 0xd6960492 netif_device_attach +EXPORT_SYMBOL vmlinux 0xd6a585c1 neigh_lookup +EXPORT_SYMBOL vmlinux 0xd6cfcb43 input_close_device +EXPORT_SYMBOL vmlinux 0xd6d8023b textsearch_unregister +EXPORT_SYMBOL vmlinux 0xd6ee688f vmalloc +EXPORT_SYMBOL vmlinux 0xd6ef7be8 unregister_qdisc +EXPORT_SYMBOL vmlinux 0xd6ff3e9a simple_rename +EXPORT_SYMBOL vmlinux 0xd70ef2de alloc_etherdev_mq +EXPORT_SYMBOL vmlinux 0xd731c66c dev_mc_unsync +EXPORT_SYMBOL vmlinux 0xd7584004 skb_dequeue_tail +EXPORT_SYMBOL vmlinux 0xd76aa858 skb_recv_datagram +EXPORT_SYMBOL vmlinux 0xd78ccf8b neigh_seq_next +EXPORT_SYMBOL vmlinux 0xd79b5a02 allow_signal +EXPORT_SYMBOL vmlinux 0xd7b69fae idr_find +EXPORT_SYMBOL vmlinux 0xd7f5c508 mii_check_gmii_support +EXPORT_SYMBOL vmlinux 0xd8091bc7 bdget +EXPORT_SYMBOL vmlinux 0xd8282ff0 posix_acl_equiv_mode +EXPORT_SYMBOL vmlinux 0xd83791bc nf_conntrack_destroy +EXPORT_SYMBOL vmlinux 0xd8818e88 dma_pool_alloc +EXPORT_SYMBOL vmlinux 0xd896781a skb_split +EXPORT_SYMBOL vmlinux 0xd8a2ab95 in_egroup_p +EXPORT_SYMBOL vmlinux 0xd8e484f0 register_chrdev_region +EXPORT_SYMBOL vmlinux 0xd913f08d scsi_adjust_queue_depth +EXPORT_SYMBOL vmlinux 0xd935239b tty_driver_flush_buffer +EXPORT_SYMBOL vmlinux 0xd938e671 pci_add_new_bus +EXPORT_SYMBOL vmlinux 0xd97959df bd_release +EXPORT_SYMBOL vmlinux 0xd985dc99 mempool_free_pages +EXPORT_SYMBOL vmlinux 0xd99c594d input_get_keycode +EXPORT_SYMBOL vmlinux 0xd9ce2093 cfi_varsize_frob +EXPORT_SYMBOL vmlinux 0xd9ce8f0c strnlen +EXPORT_SYMBOL vmlinux 0xd9d952ce scsi_bios_ptable +EXPORT_SYMBOL vmlinux 0xd9ef3f3b mb_cache_entry_free +EXPORT_SYMBOL vmlinux 0xd9f1a5b4 skb_abort_seq_read +EXPORT_SYMBOL vmlinux 0xd9f434fd scm_detach_fds +EXPORT_SYMBOL vmlinux 0xda1a7335 kasprintf +EXPORT_SYMBOL vmlinux 0xda33a13e sync_page_range +EXPORT_SYMBOL vmlinux 0xda5ea696 _test_and_set_bit_le +EXPORT_SYMBOL vmlinux 0xda8b5096 xfrm_cfg_mutex +EXPORT_SYMBOL vmlinux 0xda940b20 sock_no_poll +EXPORT_SYMBOL vmlinux 0xdabb47f1 skb_dequeue +EXPORT_SYMBOL vmlinux 0xdaff094e blk_queue_update_dma_alignment +EXPORT_SYMBOL vmlinux 0xdb073fa3 sock_kmalloc +EXPORT_SYMBOL vmlinux 0xdb36a227 tty_hangup +EXPORT_SYMBOL vmlinux 0xdb864d65 iov_iter_single_seg_count +EXPORT_SYMBOL vmlinux 0xdb9a421a is_container_init +EXPORT_SYMBOL vmlinux 0xdbbe54de kernel_connect +EXPORT_SYMBOL vmlinux 0xdbcd416e sysctl_ip_nonlocal_bind +EXPORT_SYMBOL vmlinux 0xdbea2607 tcp_make_synack +EXPORT_SYMBOL vmlinux 0xdc053205 udp_memory_allocated +EXPORT_SYMBOL vmlinux 0xdc05b93d poll_initwait +EXPORT_SYMBOL vmlinux 0xdc14eda7 pci_pci_problems +EXPORT_SYMBOL vmlinux 0xdc2adb35 add_taint +EXPORT_SYMBOL vmlinux 0xdc43a9c8 daemonize +EXPORT_SYMBOL vmlinux 0xdcb0349b sys_close +EXPORT_SYMBOL vmlinux 0xdcb63f45 tty_get_baud_rate +EXPORT_SYMBOL vmlinux 0xdcb9c226 xfrm_dst_ifdown +EXPORT_SYMBOL vmlinux 0xdd0366ac starget_for_each_device +EXPORT_SYMBOL vmlinux 0xdd0a2ba2 strlcat +EXPORT_SYMBOL vmlinux 0xdd27fa87 memchr +EXPORT_SYMBOL vmlinux 0xdd41b90a inet_csk_accept +EXPORT_SYMBOL vmlinux 0xdd5addc2 generic_getxattr +EXPORT_SYMBOL vmlinux 0xdd5e4823 scsicam_bios_param +EXPORT_SYMBOL vmlinux 0xdd6bfccd radix_tree_tag_set +EXPORT_SYMBOL vmlinux 0xddacbb0b mtd_do_chip_probe +EXPORT_SYMBOL vmlinux 0xddb56b9a ip_dev_find +EXPORT_SYMBOL vmlinux 0xdde86015 tcf_action_dump_1 +EXPORT_SYMBOL vmlinux 0xddeef053 vfs_stat +EXPORT_SYMBOL vmlinux 0xddef28e8 scsi_eh_finish_cmd +EXPORT_SYMBOL vmlinux 0xddf2816b bio_unmap_user +EXPORT_SYMBOL vmlinux 0xde210b79 sockfd_lookup +EXPORT_SYMBOL vmlinux 0xde264264 misc_register +EXPORT_SYMBOL vmlinux 0xde291325 udp_flush_pending_frames +EXPORT_SYMBOL vmlinux 0xde75b689 set_irq_type +EXPORT_SYMBOL vmlinux 0xde9360ba totalram_pages +EXPORT_SYMBOL vmlinux 0xdf2717c2 __dev_get_by_index +EXPORT_SYMBOL vmlinux 0xdf28c5ce __blk_run_queue +EXPORT_SYMBOL vmlinux 0xdf4b5e84 neigh_create +EXPORT_SYMBOL vmlinux 0xdf55c41c tcf_exts_dump_stats +EXPORT_SYMBOL vmlinux 0xdf6b44ed sk_dst_check +EXPORT_SYMBOL vmlinux 0xdf76353b generic_file_splice_read +EXPORT_SYMBOL vmlinux 0xdf822399 serial8250_register_port +EXPORT_SYMBOL vmlinux 0xdf8aa6d4 skb_copy_expand +EXPORT_SYMBOL vmlinux 0xdf904c6b neigh_sysctl_unregister +EXPORT_SYMBOL vmlinux 0xdf929370 fs_overflowgid +EXPORT_SYMBOL vmlinux 0xdfb5d473 tty_throttle +EXPORT_SYMBOL vmlinux 0xdfd053e4 pci_clear_mwi +EXPORT_SYMBOL vmlinux 0xe01806fb sock_create_lite +EXPORT_SYMBOL vmlinux 0xe01e8f51 neigh_table_init +EXPORT_SYMBOL vmlinux 0xe041095a blk_unplug +EXPORT_SYMBOL vmlinux 0xe041e3f0 filemap_flush +EXPORT_SYMBOL vmlinux 0xe075d6eb iter_div_u64_rem +EXPORT_SYMBOL vmlinux 0xe07fa2b0 sock_recvmsg +EXPORT_SYMBOL vmlinux 0xe0878bfe __krealloc +EXPORT_SYMBOL vmlinux 0xe08e3af2 pci_set_dma_mask +EXPORT_SYMBOL vmlinux 0xe0a0a133 simple_fill_super +EXPORT_SYMBOL vmlinux 0xe0b13336 argv_free +EXPORT_SYMBOL vmlinux 0xe113bbbc csum_partial +EXPORT_SYMBOL vmlinux 0xe14c59a6 __rta_fill +EXPORT_SYMBOL vmlinux 0xe15a2fbf scsi_free_host_dev +EXPORT_SYMBOL vmlinux 0xe163a20e udp_lib_setsockopt +EXPORT_SYMBOL vmlinux 0xe18254bc inet_add_protocol +EXPORT_SYMBOL vmlinux 0xe1a7bf6f scsi_block_when_processing_errors +EXPORT_SYMBOL vmlinux 0xe1af6511 tcp_v4_destroy_sock +EXPORT_SYMBOL vmlinux 0xe227ad75 xfrm_state_insert +EXPORT_SYMBOL vmlinux 0xe234e872 ___pskb_trim +EXPORT_SYMBOL vmlinux 0xe2354050 locks_init_lock +EXPORT_SYMBOL vmlinux 0xe24d3a97 jiffies_64 +EXPORT_SYMBOL vmlinux 0xe24d9385 write_inode_now +EXPORT_SYMBOL vmlinux 0xe25aa47e register_netdevice +EXPORT_SYMBOL vmlinux 0xe28a5ac6 register_gifconf +EXPORT_SYMBOL vmlinux 0xe29995ad tty_port_tty_get +EXPORT_SYMBOL vmlinux 0xe2d5255a strcmp +EXPORT_SYMBOL vmlinux 0xe2fae716 kmemdup +EXPORT_SYMBOL vmlinux 0xe30565d9 send_sig +EXPORT_SYMBOL vmlinux 0xe34301e0 pci_iomap +EXPORT_SYMBOL vmlinux 0xe34694e7 struct_module +EXPORT_SYMBOL vmlinux 0xe351633f genl_register_family +EXPORT_SYMBOL vmlinux 0xe38ee105 put_page +EXPORT_SYMBOL vmlinux 0xe396f610 unregister_sysctl_table +EXPORT_SYMBOL vmlinux 0xe3b32d4f kobject_init +EXPORT_SYMBOL vmlinux 0xe3fdfaf4 bio_add_pc_page +EXPORT_SYMBOL vmlinux 0xe42f89b4 lock_may_read +EXPORT_SYMBOL vmlinux 0xe445a727 journal_check_used_features +EXPORT_SYMBOL vmlinux 0xe4874a37 scsi_remove_device +EXPORT_SYMBOL vmlinux 0xe4a97c71 __down_write_trylock +EXPORT_SYMBOL vmlinux 0xe4c80097 cacheid +EXPORT_SYMBOL vmlinux 0xe5360754 bio_endio +EXPORT_SYMBOL vmlinux 0xe54ef860 audit_log_end +EXPORT_SYMBOL vmlinux 0xe5504790 blk_queue_free_tags +EXPORT_SYMBOL vmlinux 0xe5697146 skb_unlink +EXPORT_SYMBOL vmlinux 0xe56c6fd7 dev_remove_pack +EXPORT_SYMBOL vmlinux 0xe574358d netdev_bonding_change +EXPORT_SYMBOL vmlinux 0xe57878a1 in6_pton +EXPORT_SYMBOL vmlinux 0xe5867808 dlci_ioctl_set +EXPORT_SYMBOL vmlinux 0xe5c2683e xfrm_find_acq +EXPORT_SYMBOL vmlinux 0xe5c78a99 do_blank_screen +EXPORT_SYMBOL vmlinux 0xe5ed5467 xfrm_policy_walk_init +EXPORT_SYMBOL vmlinux 0xe6068682 uart_resume_port +EXPORT_SYMBOL vmlinux 0xe63295d8 wake_up_process +EXPORT_SYMBOL vmlinux 0xe63fb778 netdev_set_master +EXPORT_SYMBOL vmlinux 0xe646387e pci_scan_bridge +EXPORT_SYMBOL vmlinux 0xe665c0fe __dev_get_by_name +EXPORT_SYMBOL vmlinux 0xe685d4b5 tcp_v4_do_rcv +EXPORT_SYMBOL vmlinux 0xe699a144 do_munmap +EXPORT_SYMBOL vmlinux 0xe6aa4039 inet_dgram_ops +EXPORT_SYMBOL vmlinux 0xe6c3ebb0 __raw_writesw +EXPORT_SYMBOL vmlinux 0xe6c850cb empty_zero_page +EXPORT_SYMBOL vmlinux 0xe6d99b28 scsi_setup_blk_pc_cmnd +EXPORT_SYMBOL vmlinux 0xe6edae5e journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0xe6fbe430 can_do_mlock +EXPORT_SYMBOL vmlinux 0xe6ff48c5 sk_stream_kill_queues +EXPORT_SYMBOL vmlinux 0xe707d823 __aeabi_uidiv +EXPORT_SYMBOL vmlinux 0xe74bf056 register_console +EXPORT_SYMBOL vmlinux 0xe757ac37 tty_name +EXPORT_SYMBOL vmlinux 0xe78c3298 input_release_device +EXPORT_SYMBOL vmlinux 0xe7c4eb8f dmam_pool_destroy +EXPORT_SYMBOL vmlinux 0xe7d4daac seq_list_next +EXPORT_SYMBOL vmlinux 0xe7e3c158 read_cache_page +EXPORT_SYMBOL vmlinux 0xe7ed96db neigh_sysctl_register +EXPORT_SYMBOL vmlinux 0xe7f415db scsi_register +EXPORT_SYMBOL vmlinux 0xe7f7b79a register_exec_domain +EXPORT_SYMBOL vmlinux 0xe80a1e69 pci_enable_bridges +EXPORT_SYMBOL vmlinux 0xe811541d vfs_read +EXPORT_SYMBOL vmlinux 0xe81f3af6 schedule_delayed_work_on +EXPORT_SYMBOL vmlinux 0xe8463306 pcim_iomap_regions +EXPORT_SYMBOL vmlinux 0xe84740c6 skb_trim +EXPORT_SYMBOL vmlinux 0xe872a10f sock_release +EXPORT_SYMBOL vmlinux 0xe8b39109 make_bad_inode +EXPORT_SYMBOL vmlinux 0xe8bad325 skb_find_text +EXPORT_SYMBOL vmlinux 0xe8c29f62 dev_disable_lro +EXPORT_SYMBOL vmlinux 0xe8cd902e hweight16 +EXPORT_SYMBOL vmlinux 0xe8dc920c vfs_unlink +EXPORT_SYMBOL vmlinux 0xe8e250e1 sock_rfree +EXPORT_SYMBOL vmlinux 0xe9062f9a I_BDEV +EXPORT_SYMBOL vmlinux 0xe914e41e strcpy +EXPORT_SYMBOL vmlinux 0xe9456a5a sysctl_xfrm_aevent_rseqth +EXPORT_SYMBOL vmlinux 0xe9921628 blk_put_request +EXPORT_SYMBOL vmlinux 0xe9e4dddf scsi_reset_provider +EXPORT_SYMBOL vmlinux 0xea00dd2c brioctl_set +EXPORT_SYMBOL vmlinux 0xea04d1b6 tcp_getsockopt +EXPORT_SYMBOL vmlinux 0xea0c5e9c scsi_execute_req +EXPORT_SYMBOL vmlinux 0xea10212a int_to_scsilun +EXPORT_SYMBOL vmlinux 0xea10655a __bitmap_intersects +EXPORT_SYMBOL vmlinux 0xea147363 printk +EXPORT_SYMBOL vmlinux 0xea2437d9 inet_accept +EXPORT_SYMBOL vmlinux 0xea2a97af scsi_unblock_requests +EXPORT_SYMBOL vmlinux 0xea2d33a2 radix_tree_gang_lookup_slot +EXPORT_SYMBOL vmlinux 0xea4260f0 bdi_register +EXPORT_SYMBOL vmlinux 0xea4d8cf8 nobh_writepage +EXPORT_SYMBOL vmlinux 0xea60a41a uart_match_port +EXPORT_SYMBOL vmlinux 0xea6fcdaa genl_unregister_family +EXPORT_SYMBOL vmlinux 0xea858cb5 radix_tree_gang_lookup_tag +EXPORT_SYMBOL vmlinux 0xea8dd4cd skb_recycle_check +EXPORT_SYMBOL vmlinux 0xeaaf498c new_inode +EXPORT_SYMBOL vmlinux 0xeab484e1 dst_release +EXPORT_SYMBOL vmlinux 0xeac49ab5 proc_dostring +EXPORT_SYMBOL vmlinux 0xeac5883b set_bh_page +EXPORT_SYMBOL vmlinux 0xead892b9 tty_wait_until_sent +EXPORT_SYMBOL vmlinux 0xead92f86 mpage_readpage +EXPORT_SYMBOL vmlinux 0xeae3dfd6 __const_udelay +EXPORT_SYMBOL vmlinux 0xeaec657c tcp_child_process +EXPORT_SYMBOL vmlinux 0xeb096789 skb_append +EXPORT_SYMBOL vmlinux 0xeb18c1f5 sk_run_filter +EXPORT_SYMBOL vmlinux 0xeb1f96e4 scsi_remove_target +EXPORT_SYMBOL vmlinux 0xeb395084 param_get_invbool +EXPORT_SYMBOL vmlinux 0xeb44eedd remove_proc_entry +EXPORT_SYMBOL vmlinux 0xeb615384 bfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0xeb726925 inode_set_bytes +EXPORT_SYMBOL vmlinux 0xeb8f54b3 strstrip +EXPORT_SYMBOL vmlinux 0xeba044c1 neigh_parms_alloc +EXPORT_SYMBOL vmlinux 0xebb01acd nobh_write_begin +EXPORT_SYMBOL vmlinux 0xebbba20c generic_file_llseek +EXPORT_SYMBOL vmlinux 0xebd273a6 strict_strtoull +EXPORT_SYMBOL vmlinux 0xebfdcbdf system_serial_high +EXPORT_SYMBOL vmlinux 0xec071c09 tcf_register_action +EXPORT_SYMBOL vmlinux 0xec0f900e bio_sector_offset +EXPORT_SYMBOL vmlinux 0xec33a61d devm_ioport_unmap +EXPORT_SYMBOL vmlinux 0xec5fc728 xfrm_policy_byid +EXPORT_SYMBOL vmlinux 0xec794ba0 __send_remote_softirq +EXPORT_SYMBOL vmlinux 0xec7b254c scsi_ioctl +EXPORT_SYMBOL vmlinux 0xec95f4b1 cdev_del +EXPORT_SYMBOL vmlinux 0xecb1abe1 flush_signals +EXPORT_SYMBOL vmlinux 0xeccf9ed6 nla_put_nohdr +EXPORT_SYMBOL vmlinux 0xed5a677d iput +EXPORT_SYMBOL vmlinux 0xed96a535 generic_file_direct_write +EXPORT_SYMBOL vmlinux 0xed98385c del_gendisk +EXPORT_SYMBOL vmlinux 0xeda00144 register_chrdev +EXPORT_SYMBOL vmlinux 0xedbaee5e nla_strcmp +EXPORT_SYMBOL vmlinux 0xedd14538 param_get_uint +EXPORT_SYMBOL vmlinux 0xedd9106d __ashrdi3 +EXPORT_SYMBOL vmlinux 0xedf7ebb5 blkdev_put +EXPORT_SYMBOL vmlinux 0xee2d0fc7 _local_bh_enable +EXPORT_SYMBOL vmlinux 0xee5f406d neigh_compat_output +EXPORT_SYMBOL vmlinux 0xee6fdf0b cpu_online_map +EXPORT_SYMBOL vmlinux 0xeea9dbaf bitmap_bitremap +EXPORT_SYMBOL vmlinux 0xeeb1717c param_array_get +EXPORT_SYMBOL vmlinux 0xeed6d8ed scsi_target_resume +EXPORT_SYMBOL vmlinux 0xef1a1668 km_waitq +EXPORT_SYMBOL vmlinux 0xef24b927 inet_release +EXPORT_SYMBOL vmlinux 0xef431cda qdisc_create_dflt +EXPORT_SYMBOL vmlinux 0xefaada36 handle_sysrq +EXPORT_SYMBOL vmlinux 0xf0009fee put_pages_list +EXPORT_SYMBOL vmlinux 0xf012639e qdisc_watchdog_cancel +EXPORT_SYMBOL vmlinux 0xf01d79b1 tcf_hash_insert +EXPORT_SYMBOL vmlinux 0xf033c6b5 pagecache_write_end +EXPORT_SYMBOL vmlinux 0xf03a0544 d_prune_aliases +EXPORT_SYMBOL vmlinux 0xf0b57c68 param_set_long +EXPORT_SYMBOL vmlinux 0xf0cc31aa dev_kfree_skb_irq +EXPORT_SYMBOL vmlinux 0xf0de38a3 tcp_proc_unregister +EXPORT_SYMBOL vmlinux 0xf0f1246c kvasprintf +EXPORT_SYMBOL vmlinux 0xf161993c set_blocksize +EXPORT_SYMBOL vmlinux 0xf162fe2d sysctl_xfrm_aevent_etime +EXPORT_SYMBOL vmlinux 0xf174ed48 acquire_console_sem +EXPORT_SYMBOL vmlinux 0xf1db4e2f xfrm4_rcv +EXPORT_SYMBOL vmlinux 0xf1deabf2 div64_u64 +EXPORT_SYMBOL vmlinux 0xf1e35324 xfrm_policy_alloc +EXPORT_SYMBOL vmlinux 0xf1e98c74 avenrun +EXPORT_SYMBOL vmlinux 0xf203f1f6 netlink_unicast +EXPORT_SYMBOL vmlinux 0xf20dabd8 free_irq +EXPORT_SYMBOL vmlinux 0xf2997713 tty_termios_hw_change +EXPORT_SYMBOL vmlinux 0xf2a6d2bf xfrm_policy_count +EXPORT_SYMBOL vmlinux 0xf2afa595 param_get_charp +EXPORT_SYMBOL vmlinux 0xf2e56bb4 truncate_inode_pages +EXPORT_SYMBOL vmlinux 0xf313da4e sha_transform +EXPORT_SYMBOL vmlinux 0xf338c0a0 inode_init_once +EXPORT_SYMBOL vmlinux 0xf338d4c3 netlink_unregister_notifier +EXPORT_SYMBOL vmlinux 0xf346231f seq_list_start_head +EXPORT_SYMBOL vmlinux 0xf35c3fd8 __inet6_hash +EXPORT_SYMBOL vmlinux 0xf375a48e pcim_iounmap +EXPORT_SYMBOL vmlinux 0xf395b9e4 dev_unicast_delete +EXPORT_SYMBOL vmlinux 0xf397b9aa __tasklet_schedule +EXPORT_SYMBOL vmlinux 0xf39bf4d9 put_cmsg +EXPORT_SYMBOL vmlinux 0xf3bf0bce __bitmap_complement +EXPORT_SYMBOL vmlinux 0xf4192c91 skb_queue_purge +EXPORT_SYMBOL vmlinux 0xf44c3874 tcp_setsockopt +EXPORT_SYMBOL vmlinux 0xf4522fcb bdi_register_dev +EXPORT_SYMBOL vmlinux 0xf45a151f blk_rq_init +EXPORT_SYMBOL vmlinux 0xf4655305 icmp_send +EXPORT_SYMBOL vmlinux 0xf4b4c3dd pci_prepare_to_sleep +EXPORT_SYMBOL vmlinux 0xf4bff960 revalidate_disk +EXPORT_SYMBOL vmlinux 0xf4def2e8 bmap +EXPORT_SYMBOL vmlinux 0xf4f14de6 rtnl_trylock +EXPORT_SYMBOL vmlinux 0xf51c639f interruptible_sleep_on_timeout +EXPORT_SYMBOL vmlinux 0xf5373dfe d_rehash +EXPORT_SYMBOL vmlinux 0xf53a59c4 ip_cmsg_recv +EXPORT_SYMBOL vmlinux 0xf53d4c26 qdisc_class_hash_destroy +EXPORT_SYMBOL vmlinux 0xf54940bb sk_free +EXPORT_SYMBOL vmlinux 0xf564412a __aeabi_ulcmp +EXPORT_SYMBOL vmlinux 0xf591e427 proc_dointvec_jiffies +EXPORT_SYMBOL vmlinux 0xf5b62f6a seq_lseek +EXPORT_SYMBOL vmlinux 0xf5c05914 generic_segment_checks +EXPORT_SYMBOL vmlinux 0xf5ec2c3d xfrm_state_update +EXPORT_SYMBOL vmlinux 0xf60c7781 blk_plug_device_unlocked +EXPORT_SYMBOL vmlinux 0xf69168ab generic_file_mmap +EXPORT_SYMBOL vmlinux 0xf6bb4729 color_table +EXPORT_SYMBOL vmlinux 0xf6ebc03b net_ratelimit +EXPORT_SYMBOL vmlinux 0xf7384f52 downgrade_write +EXPORT_SYMBOL vmlinux 0xf7623914 radix_tree_tag_clear +EXPORT_SYMBOL vmlinux 0xf77fbb46 idr_remove_all +EXPORT_SYMBOL vmlinux 0xf7802486 __aeabi_uidivmod +EXPORT_SYMBOL vmlinux 0xf78d04ab netlink_register_notifier +EXPORT_SYMBOL vmlinux 0xf7ed5098 cfi_fixup +EXPORT_SYMBOL vmlinux 0xf80c94fc scsi_device_quiesce +EXPORT_SYMBOL vmlinux 0xf811e69d scsi_eh_flush_done_q +EXPORT_SYMBOL vmlinux 0xf82abc1d isa_dma_bridge_buggy +EXPORT_SYMBOL vmlinux 0xf873f4c1 dst_discard +EXPORT_SYMBOL vmlinux 0xf87d22ff inet_csk_clear_xmit_timers +EXPORT_SYMBOL vmlinux 0xf8814f73 rb_last +EXPORT_SYMBOL vmlinux 0xf890fe7f pm_idle +EXPORT_SYMBOL vmlinux 0xf8f9409a scsi_get_host_dev +EXPORT_SYMBOL vmlinux 0xf8fbb4f0 __bad_xchg +EXPORT_SYMBOL vmlinux 0xf91f516e skb_copy_and_csum_bits +EXPORT_SYMBOL vmlinux 0xf94430fb skb_seq_read +EXPORT_SYMBOL vmlinux 0xf949cd68 simple_transaction_release +EXPORT_SYMBOL vmlinux 0xf95478ca sock_no_recvmsg +EXPORT_SYMBOL vmlinux 0xf9a482f9 msleep +EXPORT_SYMBOL vmlinux 0xf9b28bac interruptible_sleep_on +EXPORT_SYMBOL vmlinux 0xf9b93666 blk_execute_rq +EXPORT_SYMBOL vmlinux 0xf9c3c3f5 vmalloc_to_page +EXPORT_SYMBOL vmlinux 0xfa7b4562 do_SAK +EXPORT_SYMBOL vmlinux 0xfa8c711d add_to_page_cache_locked +EXPORT_SYMBOL vmlinux 0xfa984fd8 blk_queue_ordered +EXPORT_SYMBOL vmlinux 0xfa9ab5ee init_net +EXPORT_SYMBOL vmlinux 0xfaa9ffe8 bio_free +EXPORT_SYMBOL vmlinux 0xfac68eba arm_elf_read_implies_exec +EXPORT_SYMBOL vmlinux 0xfaf98462 bitrev32 +EXPORT_SYMBOL vmlinux 0xfb1ac053 devm_free_irq +EXPORT_SYMBOL vmlinux 0xfb2b6f58 blk_queue_segment_boundary +EXPORT_SYMBOL vmlinux 0xfb31ea4c inet_frag_evictor +EXPORT_SYMBOL vmlinux 0xfb326a5d down +EXPORT_SYMBOL vmlinux 0xfb36269b gnet_stats_copy_app +EXPORT_SYMBOL vmlinux 0xfb533258 pcibios_bus_to_resource +EXPORT_SYMBOL vmlinux 0xfb6af58d recalc_sigpending +EXPORT_SYMBOL vmlinux 0xfb72f638 xscale_flush_user_cache_all +EXPORT_SYMBOL vmlinux 0xfb7d9c45 __udivsi3 +EXPORT_SYMBOL vmlinux 0xfb89fa64 netdev_boot_setup_check +EXPORT_SYMBOL vmlinux 0xfbc74f64 __copy_from_user +EXPORT_SYMBOL vmlinux 0xfbf92453 param_get_bool +EXPORT_SYMBOL vmlinux 0xfc02b7ad sysctl_tcp_wmem +EXPORT_SYMBOL vmlinux 0xfc062842 input_register_handler +EXPORT_SYMBOL vmlinux 0xfc3d8d02 skb_copy_datagram_iovec +EXPORT_SYMBOL vmlinux 0xfc533f85 schedule_work_on +EXPORT_SYMBOL vmlinux 0xfc67ff1e __pagevec_release +EXPORT_SYMBOL vmlinux 0xfc861f2f tcf_em_unregister +EXPORT_SYMBOL vmlinux 0xfc984e0e path_lookup +EXPORT_SYMBOL vmlinux 0xfcaa04a0 out_of_line_wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0xfccaa633 dma_release_from_coherent +EXPORT_SYMBOL vmlinux 0xfcda63a3 node_states +EXPORT_SYMBOL vmlinux 0xfcdd8cf6 param_get_ushort +EXPORT_SYMBOL vmlinux 0xfcec0987 enable_irq +EXPORT_SYMBOL vmlinux 0xfcfc92fc find_task_by_vpid +EXPORT_SYMBOL vmlinux 0xfd1de3ac vfs_llseek +EXPORT_SYMBOL vmlinux 0xfd332776 pcim_iomap +EXPORT_SYMBOL vmlinux 0xfd44421f mb_cache_entry_insert +EXPORT_SYMBOL vmlinux 0xfd8dba4c add_wait_queue +EXPORT_SYMBOL vmlinux 0xfd98879a rb_next +EXPORT_SYMBOL vmlinux 0xfdc7460a set_user_nice +EXPORT_SYMBOL vmlinux 0xfdd48210 dev_set_promiscuity +EXPORT_SYMBOL vmlinux 0xfdde8d7a __module_put_and_exit +EXPORT_SYMBOL vmlinux 0xfdfc0b3b fiemap_fill_next_extent +EXPORT_SYMBOL vmlinux 0xfe0b58e2 pci_release_selected_regions +EXPORT_SYMBOL vmlinux 0xfe16775f idr_destroy +EXPORT_SYMBOL vmlinux 0xfe271510 mutex_lock_killable +EXPORT_SYMBOL vmlinux 0xfe5d4bb2 sys_tz +EXPORT_SYMBOL vmlinux 0xfe6681a0 sock_no_accept +EXPORT_SYMBOL vmlinux 0xfe686ae6 netif_rx +EXPORT_SYMBOL vmlinux 0xfe769456 unregister_netdevice_notifier +EXPORT_SYMBOL vmlinux 0xfead7929 pci_remove_bus +EXPORT_SYMBOL vmlinux 0xfec3c2f2 bcd2bin +EXPORT_SYMBOL vmlinux 0xfedae379 free_netdev +EXPORT_SYMBOL vmlinux 0xfedd35fc console_suspend_enabled +EXPORT_SYMBOL vmlinux 0xfee01f2c nf_ip_checksum +EXPORT_SYMBOL vmlinux 0xfef7b21c sock_queue_rcv_skb +EXPORT_SYMBOL vmlinux 0xfef96e23 __scsi_print_command +EXPORT_SYMBOL vmlinux 0xff1e9dd8 seq_list_start +EXPORT_SYMBOL vmlinux 0xff4c3f93 tcf_hash_search +EXPORT_SYMBOL vmlinux 0xff57e232 arp_create +EXPORT_SYMBOL vmlinux 0xff67b37f __lshrdi3 +EXPORT_SYMBOL vmlinux 0xff6b0259 posix_unblock_lock +EXPORT_SYMBOL vmlinux 0xff715436 console_stop +EXPORT_SYMBOL vmlinux 0xff80cf80 end_page_writeback +EXPORT_SYMBOL vmlinux 0xff870590 tcf_generic_walker +EXPORT_SYMBOL vmlinux 0xffae6b13 kmem_cache_name +EXPORT_SYMBOL vmlinux 0xffd5a395 default_wake_function +EXPORT_SYMBOL_GPL crypto/aead 0x05115420 crypto_grab_aead +EXPORT_SYMBOL_GPL crypto/aead 0x133bcfe1 crypto_aead_setauthsize +EXPORT_SYMBOL_GPL crypto/aead 0x388bcf2a crypto_alloc_aead +EXPORT_SYMBOL_GPL crypto/aead 0x75668be5 crypto_aead_type +EXPORT_SYMBOL_GPL crypto/aead 0x8b469485 aead_geniv_exit +EXPORT_SYMBOL_GPL crypto/aead 0x8c77daf7 crypto_nivaead_type +EXPORT_SYMBOL_GPL crypto/aead 0xb47d3fe0 aead_geniv_init +EXPORT_SYMBOL_GPL crypto/aead 0xbd49d7ab aead_geniv_alloc +EXPORT_SYMBOL_GPL crypto/aead 0xfeec9e45 aead_geniv_free +EXPORT_SYMBOL_GPL crypto/aes_generic 0x1381bf2d crypto_ft_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x22894d94 crypto_il_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x4c03fdfb crypto_aes_set_key +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5f943003 crypto_it_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5fe743de crypto_aes_expand_key +EXPORT_SYMBOL_GPL crypto/aes_generic 0x6e9cc2ba crypto_fl_tab +EXPORT_SYMBOL_GPL crypto/async_tx/async_memcpy 0xfa95982e async_memcpy +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x6c883d9a async_tx_submit +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0xa8517549 async_tx_quiesce +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0xf63efe46 async_trigger_callback +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0x2ed919af async_xor_zero_sum +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0x4aaf1ddb async_xor +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x055411de crypto_attr_alg +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x0b3921b3 crypto_dequeue_request +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x124f2056 crypto_get_attr_type +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x1f0b3b00 crypto_lookup_template +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x2296c00d crypto_attr_u32 +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x35706e85 crypto_init_spawn +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x45bf1ff3 crypto_inc +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x499043d3 crypto_init_queue +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x58157640 scatterwalk_map +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x5f1cced5 scatterwalk_start +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x66351fbe crypto_tfm_in_queue +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x69ec2bde crypto_register_template +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x75e8f3c3 crypto_register_notifier +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x7dc5d0b6 crypto_unregister_notifier +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x808ec1a3 crypto_alg_tested +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x83553786 scatterwalk_copychunks +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x8810ad5e crypto_xor +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x8ed6ef37 crypto_register_alg +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x9a11a0fc crypto_attr_alg_name +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x9b683b45 scatterwalk_done +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xacd83003 crypto_alloc_instance +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xb8c8333a crypto_drop_spawn +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xc03f2d14 crypto_enqueue_request +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xc116b095 crypto_unregister_alg +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xc51b86ae crypto_unregister_template +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xc8f98f36 crypto_spawn_tfm +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xd16712f3 crypto_check_attr_type +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xf807fd65 scatterwalk_map_and_copy +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xfde0b92c crypto_larval_error +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xff188ddf crypto_register_instance +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x0a9411bf crypto_blkcipher_type +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x0ed89bd0 blkcipher_walk_done +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x1473d07c crypto_ablkcipher_type +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x226ee51d skcipher_geniv_alloc +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x26fb5028 skcipher_geniv_exit +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x3fd90b5d crypto_alloc_ablkcipher +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x4e9b07fd crypto_givcipher_type +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x53d21021 skcipher_geniv_init +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x6ad70930 blkcipher_walk_phys +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x73946f88 skcipher_geniv_free +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x7b12f75c blkcipher_walk_virt +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0xd1f6415d blkcipher_walk_virt_block +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0xd4fcc46c crypto_grab_skcipher +EXPORT_SYMBOL_GPL crypto/crypto_hash 0x444d0c19 crypto_hash_type +EXPORT_SYMBOL_GPL crypto/crypto_hash 0x713beda5 crypto_hash_walk_done +EXPORT_SYMBOL_GPL crypto/crypto_hash 0x770e97a4 crypto_ahash_type +EXPORT_SYMBOL_GPL crypto/crypto_hash 0x8221028d crypto_hash_walk_first +EXPORT_SYMBOL_GPL crypto/cryptomgr 0x5086ac3a alg_test +EXPORT_SYMBOL_GPL crypto/des_generic 0xcfd9a2c0 des_ekey +EXPORT_SYMBOL_GPL crypto/rng 0x3f5ebaa5 crypto_default_rng +EXPORT_SYMBOL_GPL crypto/rng 0x668402aa crypto_put_default_rng +EXPORT_SYMBOL_GPL crypto/rng 0x6ff607b6 crypto_get_default_rng +EXPORT_SYMBOL_GPL crypto/rng 0x9be46309 crypto_rng_type +EXPORT_SYMBOL_GPL crypto/twofish_common 0x0ff947bc twofish_setkey +EXPORT_SYMBOL_GPL drivers/char/hw_random/rng-core 0x86b1667d hwrng_unregister +EXPORT_SYMBOL_GPL drivers/char/hw_random/rng-core 0xf6bcbd73 hwrng_register +EXPORT_SYMBOL_GPL drivers/connector/cn 0xb10d55bc cn_netlink_send +EXPORT_SYMBOL_GPL drivers/connector/cn 0xdf3c19ec cn_add_callback +EXPORT_SYMBOL_GPL drivers/connector/cn 0xff5a8cfe cn_del_callback +EXPORT_SYMBOL_GPL drivers/hid/hid 0x3082627c __hid_register_driver +EXPORT_SYMBOL_GPL drivers/hid/hid 0x41473e1c hid_destroy_device +EXPORT_SYMBOL_GPL drivers/hid/hid 0x469705bb hid_input_report +EXPORT_SYMBOL_GPL drivers/hid/hid 0x4e340ed1 hidinput_connect +EXPORT_SYMBOL_GPL drivers/hid/hid 0x59264adb hid_add_device +EXPORT_SYMBOL_GPL drivers/hid/hid 0x63dd7108 hidinput_report_event +EXPORT_SYMBOL_GPL drivers/hid/hid 0x74412c56 hid_report_raw_event +EXPORT_SYMBOL_GPL drivers/hid/hid 0x8869153b hid_parse_report +EXPORT_SYMBOL_GPL drivers/hid/hid 0x8fc19a1f hidinput_find_field +EXPORT_SYMBOL_GPL drivers/hid/hid 0x97901d79 hid_unregister_driver +EXPORT_SYMBOL_GPL drivers/hid/hid 0xba51a325 hid_connect +EXPORT_SYMBOL_GPL drivers/hid/hid 0xbe739e0c hidinput_disconnect +EXPORT_SYMBOL_GPL drivers/hid/hid 0xca296b1d hid_allocate_device +EXPORT_SYMBOL_GPL drivers/hid/hid 0xce19d5ba hid_set_field +EXPORT_SYMBOL_GPL drivers/hid/hid 0xece11960 hid_output_report +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x01fd453e usbhid_lookup_quirk +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0xa913f790 usbhid_set_leds +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0xb38aab92 usbhid_submit_report +EXPORT_SYMBOL_GPL drivers/hwmon/hwmon 0x41ea608a hwmon_device_unregister +EXPORT_SYMBOL_GPL drivers/hwmon/hwmon 0xbacd4571 hwmon_device_register +EXPORT_SYMBOL_GPL drivers/i2c/i2c-core 0x27f45f1e i2c_new_probed_device +EXPORT_SYMBOL_GPL drivers/i2c/i2c-core 0x2bd892a3 i2c_bus_type +EXPORT_SYMBOL_GPL drivers/i2c/i2c-core 0x65bbe182 i2c_unregister_device +EXPORT_SYMBOL_GPL drivers/i2c/i2c-core 0x826c83b3 i2c_new_device +EXPORT_SYMBOL_GPL drivers/i2c/i2c-core 0xb9d3c9ba i2c_new_dummy +EXPORT_SYMBOL_GPL drivers/i2c/i2c-core 0xdc87dba1 i2c_add_numbered_adapter +EXPORT_SYMBOL_GPL drivers/input/ff-memless 0x26a686e9 input_ff_create_memless +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x09c9a139 led_classdev_suspend +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x4ea6d6e6 led_classdev_register +EXPORT_SYMBOL_GPL drivers/leds/led-class 0xb5f6c1e3 led_classdev_unregister +EXPORT_SYMBOL_GPL drivers/leds/led-class 0xb741b93f led_classdev_resume +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0x14f59b24 dm_path_uevent +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0x1af3ebb1 dm_disk +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0x1ca35a19 dm_set_device_limits +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0x2edd7126 dm_put +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0x802029a7 dm_device_name +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0xb79536f0 dm_noflush_suspending +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0xeb36a977 dm_send_uevents +EXPORT_SYMBOL_GPL drivers/md/dm-multipath 0xa0e34ed6 dm_register_path_selector +EXPORT_SYMBOL_GPL drivers/md/dm-multipath 0xc394a565 dm_unregister_path_selector +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x00b850bc dm_region_hash_destroy +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x04b3c62f dm_rh_recovery_end +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x05382728 dm_rh_recovery_prepare +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x0db094b7 dm_rh_get_state +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x2c8812a1 dm_rh_region_context +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x2e6de49e dm_rh_dec +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x2f3b6565 dm_rh_stop_recovery +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x50e268e2 dm_rh_mark_nosync +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x5deb056c dm_rh_dirty_log +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x62ca9e50 dm_rh_start_recovery +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x63edc8a9 dm_rh_flush +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x9bb51172 dm_rh_get_region_size +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x9c049f31 dm_rh_get_region_key +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xa9ee1406 dm_rh_bio_to_region +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xad95c49f dm_rh_inc_pending +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xce7e191b dm_rh_recovery_in_flight +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xde52742c dm_rh_region_to_sector +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xe0fa9dbc dm_rh_recovery_start +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xfe26c81e dm_rh_delay +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xfe6c65c3 dm_region_hash_create +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xffa35617 dm_rh_update_states +EXPORT_SYMBOL_GPL drivers/md/md-mod 0x2c0c3130 md_allow_write +EXPORT_SYMBOL_GPL drivers/md/md-mod 0x2c6223a8 md_new_event +EXPORT_SYMBOL_GPL drivers/md/md-mod 0x52665dac md_do_sync +EXPORT_SYMBOL_GPL drivers/md/md-mod 0xad2f87c7 sync_page_io +EXPORT_SYMBOL_GPL drivers/mmc/core/mmc_core 0x00120cd6 sdio_f0_writeb +EXPORT_SYMBOL_GPL drivers/mmc/core/mmc_core 0x16073f0b sdio_align_size +EXPORT_SYMBOL_GPL drivers/mmc/core/mmc_core 0x17e59713 sdio_writel +EXPORT_SYMBOL_GPL drivers/mmc/core/mmc_core 0x1d68c9b1 sdio_memcpy_fromio +EXPORT_SYMBOL_GPL drivers/mmc/core/mmc_core 0x45e03b31 sdio_writeb +EXPORT_SYMBOL_GPL drivers/mmc/core/mmc_core 0x4700f609 sdio_readl +EXPORT_SYMBOL_GPL drivers/mmc/core/mmc_core 0x481bcd1d sdio_readw +EXPORT_SYMBOL_GPL drivers/mmc/core/mmc_core 0x4b83d802 sdio_writew +EXPORT_SYMBOL_GPL drivers/mmc/core/mmc_core 0x576d7fd1 sdio_unregister_driver +EXPORT_SYMBOL_GPL drivers/mmc/core/mmc_core 0x5ce12763 sdio_claim_irq +EXPORT_SYMBOL_GPL drivers/mmc/core/mmc_core 0x684a413c sdio_enable_func +EXPORT_SYMBOL_GPL drivers/mmc/core/mmc_core 0x70c4847e sdio_readb +EXPORT_SYMBOL_GPL drivers/mmc/core/mmc_core 0x7d7a7b93 sdio_set_block_size +EXPORT_SYMBOL_GPL drivers/mmc/core/mmc_core 0x8b7e27df sdio_register_driver +EXPORT_SYMBOL_GPL drivers/mmc/core/mmc_core 0x976fec42 sdio_readsb +EXPORT_SYMBOL_GPL drivers/mmc/core/mmc_core 0x9c607dfc sdio_release_irq +EXPORT_SYMBOL_GPL drivers/mmc/core/mmc_core 0xa4fa3be5 sdio_release_host +EXPORT_SYMBOL_GPL drivers/mmc/core/mmc_core 0xad0f5e27 sdio_memcpy_toio +EXPORT_SYMBOL_GPL drivers/mmc/core/mmc_core 0xbbafba19 sdio_disable_func +EXPORT_SYMBOL_GPL drivers/mmc/core/mmc_core 0xc3ab9d03 sdio_writesb +EXPORT_SYMBOL_GPL drivers/mmc/core/mmc_core 0xed1d5b40 sdio_f0_readb +EXPORT_SYMBOL_GPL drivers/mmc/core/mmc_core 0xfb7bec6b sdio_claim_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x116703a8 sdhci_remove_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0xb99b9f89 sdhci_alloc_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0xbba72d4d sdhci_add_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0xbecc3bf3 sdhci_free_host +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x4aeaeafb nand_release +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x6b4c6ad2 nand_scan +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x6fbb4dd6 nand_wait_ready +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x8a3dc11c nand_scan_tail +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xefd3646a nand_scan_ident +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x04be3da9 ubi_leb_erase +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x0b69dc19 ubi_leb_write +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x17389d55 ubi_is_mapped +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x27c9eb7a ubi_leb_change +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x42801d20 ubi_sync +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x76f9cfac ubi_get_volume_info +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x7fdd56df ubi_leb_read +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x8df9ffc3 ubi_leb_unmap +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x9d1c3dc7 ubi_open_volume_nm +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xbc505df4 ubi_get_device_info +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xbc7f7d5b ubi_leb_map +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xd9d4f58f ubi_open_volume +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xeb1d82c5 ubi_close_volume +EXPORT_SYMBOL_GPL drivers/net/usb/cdc_ether 0x605c5c79 usbnet_generic_cdc_bind +EXPORT_SYMBOL_GPL drivers/net/usb/cdc_ether 0xd2367b71 usbnet_cdc_unbind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x1e641531 generic_rndis_bind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x20ebc890 rndis_status +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x5c981632 rndis_tx_fixup +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x78faea1b rndis_command +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xde2f3160 rndis_rx_fixup +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xf0274bfa rndis_unbind +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x12766e75 usbnet_get_settings +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x1be44914 usbnet_nway_reset +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x29f06f99 usbnet_probe +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x3614084a usbnet_set_settings +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x3b597479 usbnet_get_drvinfo +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x431cd767 usbnet_skb_return +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x6ce88e69 usbnet_disconnect +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x730dddea usbnet_set_msglevel +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x94e6a748 usbnet_get_msglevel +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xb2fcdf9f usbnet_defer_kevent +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xcd3d733e usbnet_get_link +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xd4e68930 usbnet_suspend +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xd867d09c usbnet_resume +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xf1ce7c1e usbnet_get_endpoints +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xfec733d9 usbnet_unlink_rx_urbs +EXPORT_SYMBOL_GPL drivers/rtc/rtc-core 0x01523993 rtc_irq_set_freq +EXPORT_SYMBOL_GPL drivers/rtc/rtc-core 0x0faf2f06 rtc_read_time +EXPORT_SYMBOL_GPL drivers/rtc/rtc-core 0x133e0984 rtc_irq_register +EXPORT_SYMBOL_GPL drivers/rtc/rtc-core 0x1f41ea65 rtc_set_time +EXPORT_SYMBOL_GPL drivers/rtc/rtc-core 0x33039093 rtc_device_register +EXPORT_SYMBOL_GPL drivers/rtc/rtc-core 0x41e2bc18 rtc_class_open +EXPORT_SYMBOL_GPL drivers/rtc/rtc-core 0x4fa2849c rtc_device_unregister +EXPORT_SYMBOL_GPL drivers/rtc/rtc-core 0x6612d179 rtc_irq_set_state +EXPORT_SYMBOL_GPL drivers/rtc/rtc-core 0x671db4b9 rtc_read_alarm +EXPORT_SYMBOL_GPL drivers/rtc/rtc-core 0xac7b5b16 rtc_set_mmss +EXPORT_SYMBOL_GPL drivers/rtc/rtc-core 0xcb04873a rtc_irq_unregister +EXPORT_SYMBOL_GPL drivers/rtc/rtc-core 0xd318523e rtc_update_irq +EXPORT_SYMBOL_GPL drivers/rtc/rtc-core 0xdcb32da4 rtc_set_alarm +EXPORT_SYMBOL_GPL drivers/rtc/rtc-core 0xfdff08c6 rtc_class_close +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x0b978efc sas_slave_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x25a77fe5 sas_find_local_phy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x25ade44e sas_request_addr +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x2c0a910c __sas_task_abort +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x2c1a9078 sas_ioctl +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x2ce94055 sas_register_ha +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x3095383e sas_queuecommand +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x3ffcc8af sas_unregister_ha +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x58025bfc sas_target_destroy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x5a4d2efa sas_domain_attach_transport +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x65a2487d sas_phy_reset +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x7525cc47 sas_bios_param +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x7536a27b sas_change_queue_type +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x769dceb7 sas_target_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x86d98e09 sas_eh_bus_reset_handler +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x987d5819 sas_task_abort +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x99f60286 sas_slave_configure +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x9ae342a6 sas_domain_release_transport +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xbfc1c22b sas_phy_enable +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xd5a5fa4a sas_slave_destroy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xdbd6f789 sas_ssp_task_response +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xdd14a5e4 sas_change_queue_depth +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xe052f37e sas_eh_device_reset_handler +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x0ff8e619 scsi_tgt_alloc_queue +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x2da22b23 scsi_tgt_it_nexus_destroy +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x4c723525 scsi_tgt_cmd_to_host +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x5f6f6415 scsi_tgt_queue_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x65e7ede1 scsi_tgt_free_queue +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x77e7c6d8 scsi_tgt_tsk_mgmt_request +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x9ac19466 scsi_host_put_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xb25ba147 scsi_host_get_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xca9a97a7 scsi_tgt_it_nexus_create +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x05c6c352 iscsi_destroy_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x05d63460 iscsi_alloc_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x07fca354 iscsi_conn_error_event +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x100d7f47 iscsi_host_for_each_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x14358e0e iscsi_register_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x25436d6c iscsi_recv_pdu +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x2afc779e iscsi_free_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x2f21da3c iscsi_session_chkready +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x36d17878 iscsi_unblock_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x395155e6 iscsi_destroy_conn +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x437d2c56 iscsi_block_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x44bd8ac4 iscsi_scan_finished +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x453cdf24 iscsi_create_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x57d66c28 iscsi_add_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x9244dab4 iscsi_create_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x93c23e7b iscsi_remove_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xa0321894 iscsi_session_event +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xc5242e6a iscsi_lookup_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xd03a7979 iscsi_destroy_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xe2d2138f iscsi_unregister_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xff8db94f iscsi_create_conn +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0x0ef06974 spi_populate_ppr_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0xa0c71dac spi_populate_sync_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0xcffa2aff spi_populate_width_msg +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x082a2c2b usb_ftdi_elan_edset_flush +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x17db77a8 ftdi_elan_gone_away +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x4a797094 usb_ftdi_elan_edset_empty +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x77b40729 usb_ftdi_elan_edset_single +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x838650f3 usb_ftdi_elan_edset_input +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x8a89348f usb_ftdi_elan_edset_output +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x8d01464d usb_ftdi_elan_write_pcimem +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x9d8e9942 usb_ftdi_elan_edset_setup +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xaa1e5171 usb_ftdi_elan_read_pcimem +EXPORT_SYMBOL_GPL drivers/usb/misc/phidget 0x5dec671b phidget_class +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0x0e8c85ce ezusb_writememory +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0x2468fd25 usb_serial_generic_open +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0x30c9595b usb_serial_disconnect +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0x57a75a88 usb_serial_generic_read_bulk_callback +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0x7deba668 usb_serial_deregister +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0x7ee6f3c4 usb_serial_register +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0x8feef903 ezusb_set_reset +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0xa2ce5480 usb_serial_port_softint +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0xc40ac1ee usb_serial_probe +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0xcedb708c usb_serial_generic_write_bulk_callback +EXPORT_SYMBOL_GPL drivers/w1/wire 0x07438821 w1_read_block +EXPORT_SYMBOL_GPL drivers/w1/wire 0x15c6ee54 w1_reset_select_slave +EXPORT_SYMBOL_GPL drivers/w1/wire 0x1ee890eb w1_read_8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0x7c2f2afb w1_calc_crc8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0x8c58dd3d w1_reset_bus +EXPORT_SYMBOL_GPL drivers/w1/wire 0xa6a1c09a w1_next_pullup +EXPORT_SYMBOL_GPL drivers/w1/wire 0xc314975f w1_write_block +EXPORT_SYMBOL_GPL drivers/w1/wire 0xf817fa8d w1_write_8 +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x252535ce dlm_posix_unlock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x62b4e511 dlm_posix_get +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x9321df95 dlm_lock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xcf9f3328 dlm_release_lockspace +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xdc583c08 dlm_unlock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xdeaf8419 dlm_posix_lock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xdf3c14de dlm_new_lockspace +EXPORT_SYMBOL_GPL fs/exportfs/exportfs 0xb75b7b40 exportfs_encode_fh +EXPORT_SYMBOL_GPL fs/exportfs/exportfs 0xdbd48fea exportfs_decode_fh +EXPORT_SYMBOL_GPL fs/fat/fat 0x069a3257 fat_detach +EXPORT_SYMBOL_GPL fs/fat/fat 0x19b1457a fat_scan +EXPORT_SYMBOL_GPL fs/fat/fat 0x2de81896 fat_get_dotdot_entry +EXPORT_SYMBOL_GPL fs/fat/fat 0x33e8494d fat_attach +EXPORT_SYMBOL_GPL fs/fat/fat 0x43ee875b fat_search_long +EXPORT_SYMBOL_GPL fs/fat/fat 0x54816470 fat_build_inode +EXPORT_SYMBOL_GPL fs/fat/fat 0x54f87149 fat_alloc_new_dir +EXPORT_SYMBOL_GPL fs/fat/fat 0x5d9b592f fat_flush_inodes +EXPORT_SYMBOL_GPL fs/fat/fat 0x62fada9f fat_add_entries +EXPORT_SYMBOL_GPL fs/fat/fat 0x666bfc8b fat_free_clusters +EXPORT_SYMBOL_GPL fs/fat/fat 0x88ae75a4 fat_sync_inode +EXPORT_SYMBOL_GPL fs/fat/fat 0xbbae617d fat_setattr +EXPORT_SYMBOL_GPL fs/fat/fat 0xc3e46aff fat_fill_super +EXPORT_SYMBOL_GPL fs/fat/fat 0xdc15d5d9 fat_dir_empty +EXPORT_SYMBOL_GPL fs/fat/fat 0xe84b54b4 fat_time_unix2fat +EXPORT_SYMBOL_GPL fs/fat/fat 0xeb0d32de fat_remove_entries +EXPORT_SYMBOL_GPL fs/fat/fat 0xeedc5511 fat_fs_panic +EXPORT_SYMBOL_GPL fs/fat/fat 0xf63c6a86 fat_getattr +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x17ce645d locks_end_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x1a618932 nlmsvc_unlock_all_by_ip +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x418af29a nlmclnt_done +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x4818413f nlmclnt_proc +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x646273dd nlmclnt_init +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x6f959b35 locks_in_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x96877ac4 locks_start_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0xcc8aebe4 nlmsvc_unlock_all_by_sb +EXPORT_SYMBOL_GPL lib/lzo/lzo_compress 0x56b63670 lzo1x_1_compress +EXPORT_SYMBOL_GPL lib/lzo/lzo_decompress 0xf30fda27 lzo1x_decompress_safe +EXPORT_SYMBOL_GPL net/802/stp 0x03f0d0a0 stp_proto_register +EXPORT_SYMBOL_GPL net/802/stp 0x62d323aa stp_proto_unregister +EXPORT_SYMBOL_GPL net/bluetooth/bluetooth 0x98c06a04 bt_class +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x0627e3ae tfrc_tx_hist_add +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x0a487ea5 tfrc_calc_x +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x15138826 tfrc_rx_hist_sample_rtt +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x1f58bdae tfrc_tx_hist_rtt +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x4a2e5ec7 tfrc_lh_update_i_mean +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x6c252d29 tfrc_calc_x_reverse_lookup +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x8807aa35 tfrc_rx_hist_alloc +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x8dd3af8f tfrc_rx_hist_purge +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x902206f0 tfrc_lh_cleanup +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x97a4033e tfrc_rx_handle_loss +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x9c986e74 tfrc_rx_hist_add_packet +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xa8126bae tfrc_rx_hist_duplicate +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xb90cf12c tfrc_tx_hist_purge +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xbe888d86 tfrc_lh_interval_add +EXPORT_SYMBOL_GPL net/dccp/dccp 0x006621fe ccid_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0x05db032b dccp_disconnect +EXPORT_SYMBOL_GPL net/dccp/dccp 0x094eb5fa dccp_setsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x1d99d49a dccp_timestamp +EXPORT_SYMBOL_GPL net/dccp/dccp 0x2034b7e3 dccp_reqsk_send_ack +EXPORT_SYMBOL_GPL net/dccp/dccp 0x36d56e02 dccp_make_response +EXPORT_SYMBOL_GPL net/dccp/dccp 0x3b3c0b1b dccp_feat_clean +EXPORT_SYMBOL_GPL net/dccp/dccp 0x3da9de35 dccp_feat_change_recv +EXPORT_SYMBOL_GPL net/dccp/dccp 0x44857602 dccp_sync_mss +EXPORT_SYMBOL_GPL net/dccp/dccp 0x45e2eff4 dccp_create_openreq_child +EXPORT_SYMBOL_GPL net/dccp/dccp 0x50a39324 dccp_connect +EXPORT_SYMBOL_GPL net/dccp/dccp 0x56ea266a dccp_state_name +EXPORT_SYMBOL_GPL net/dccp/dccp 0x595010c0 dccp_destroy_sock +EXPORT_SYMBOL_GPL net/dccp/dccp 0x5964710e dccp_shutdown +EXPORT_SYMBOL_GPL net/dccp/dccp 0x5afb20fb dccp_set_state +EXPORT_SYMBOL_GPL net/dccp/dccp 0x5bc72150 dccp_send_sync +EXPORT_SYMBOL_GPL net/dccp/dccp 0x5dfacb41 ccid_hc_tx_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0x6883743d dccp_sendmsg +EXPORT_SYMBOL_GPL net/dccp/dccp 0x6c4203c9 ccid_register +EXPORT_SYMBOL_GPL net/dccp/dccp 0x6c558e4f inet_dccp_listen +EXPORT_SYMBOL_GPL net/dccp/dccp 0x708cb187 dccp_hashinfo +EXPORT_SYMBOL_GPL net/dccp/dccp 0x71541ff9 dccp_done +EXPORT_SYMBOL_GPL net/dccp/dccp 0x7387ef76 dccp_insert_option_timestamp +EXPORT_SYMBOL_GPL net/dccp/dccp 0x7b6f578e dccp_death_row +EXPORT_SYMBOL_GPL net/dccp/dccp 0x7fa9e884 dccp_close +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8373b3a1 dccp_parse_options +EXPORT_SYMBOL_GPL net/dccp/dccp 0x86be7924 dccp_packet_name +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8a90c549 dccp_feat_clone +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8b7d8caf dccp_statistics +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8cb3498f dccp_orphan_count +EXPORT_SYMBOL_GPL net/dccp/dccp 0x95f69ca9 dccp_feat_confirm_recv +EXPORT_SYMBOL_GPL net/dccp/dccp 0xa2e02654 ccid_unregister +EXPORT_SYMBOL_GPL net/dccp/dccp 0xa6efafbf dccp_reqsk_init +EXPORT_SYMBOL_GPL net/dccp/dccp 0xa82dff0b dccp_ctl_make_reset +EXPORT_SYMBOL_GPL net/dccp/dccp 0xae2fda8f dccp_check_req +EXPORT_SYMBOL_GPL net/dccp/dccp 0xb0b87fa6 dccp_child_process +EXPORT_SYMBOL_GPL net/dccp/dccp 0xb207f0e3 dccp_insert_option_elapsed_time +EXPORT_SYMBOL_GPL net/dccp/dccp 0xb773bd98 dccp_init_sock +EXPORT_SYMBOL_GPL net/dccp/dccp 0xb932a5bc dccp_rcv_established +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbba0e213 dccp_ioctl +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbe4cf010 dccp_feat_init +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbf6b58ba dccp_feat_change +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbf992b49 dccp_poll +EXPORT_SYMBOL_GPL net/dccp/dccp 0xc49aa3b9 dccp_insert_option +EXPORT_SYMBOL_GPL net/dccp/dccp 0xc4e63b71 dccp_rcv_state_process +EXPORT_SYMBOL_GPL net/dccp/dccp 0xc8a1a672 dccp_getsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0xc8c825a9 ccid_hc_rx_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0xd0a2ac86 dccp_recvmsg +EXPORT_SYMBOL_GPL net/dccp/dccp 0xf2a1af3a ccid_hc_tx_delete +EXPORT_SYMBOL_GPL net/dccp/dccp 0xf57d8530 dccp_send_ack +EXPORT_SYMBOL_GPL net/dccp/dccp 0xf76c4969 ccid_hc_rx_delete +EXPORT_SYMBOL_GPL net/dccp/dccp 0xf7e44768 dccp_sample_rtt +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x1309d73e dccp_v4_send_check +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x1f428663 dccp_v4_do_rcv +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x93ecdfba dccp_v4_conn_request +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x9c4a3407 dccp_v4_request_recv_sock +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0xbaf76657 dccp_v4_connect +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0xd9db4a46 dccp_invalid_packet +EXPORT_SYMBOL_GPL net/ipv4/inet_diag 0x94b4c812 inet_diag_unregister +EXPORT_SYMBOL_GPL net/ipv4/inet_diag 0xf16b070f inet_diag_register +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_conntrack_ipv4 0x15838e97 nf_nat_seq_adjust_hook +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_conntrack_ipv4 0x6d40a921 need_ipv4_conntrack +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_defrag_ipv4 0x6b6c3d10 nf_defrag_ipv4_enable +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x07ae60b6 nf_nat_proto_in_range +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x17ff2b67 nf_nat_proto_unique_tuple +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x20f6272e nf_nat_proto_range_to_nlattr +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x382bb1e4 nf_nat_icmp_reply_translation +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x41578cc6 nf_nat_proto_put +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x56dad219 nf_nat_packet +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x94a08134 nf_nat_proto_nlattr_to_range +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0xb7d69e50 nf_nat_proto_find_get +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat_proto_gre 0x636b12c8 nf_nat_need_gre +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x03fe3fdd inet6_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x08a3e5d1 net_ipv6_ctl_path +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x3640af1f inet6_destroy_sock +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x7471dc5d inet6_csk_search_req +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x811f2372 inet6_csk_xmit +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x848e625a inet6_csk_addr2sockaddr +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x85478a0b inet6_hash_frag +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x92c6fb37 inet6_sk_rebuild_header +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0xaa743d23 ipv6_opt_accepted +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0xacdc6979 ip6_dst_blackhole +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0xafc1a98a ip6_local_out +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0xb606cd81 ip6_sk_dst_lookup +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0xcd2196b9 ipv6_dup_options +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0xe60c7501 ip6_dst_lookup +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0xe6f283fc inet6_csk_bind_conflict +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0xe72925b7 fl6_sock_lookup +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0xf9ae2591 ipv6_find_tlv +EXPORT_SYMBOL_GPL net/mac80211/mac80211 0x5164f06c ieee80211_iterate_active_interfaces +EXPORT_SYMBOL_GPL net/mac80211/mac80211 0x5d0de493 ieee80211_iterate_active_interfaces_atomic +EXPORT_SYMBOL_GPL net/netfilter/ipvs/ip_vs 0xe6476b4a net_vs_ctl_path +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x02130f26 __nf_ct_refresh_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x045072cd nf_ct_port_nla_policy +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x0a610be2 nf_conntrack_tuple_taken +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x0d054d86 __nf_conntrack_helper_find_byname +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x1283d711 nf_ct_expect_unregister_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x15c10b0b nf_conntrack_unregister_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x1d1f10c9 nf_ct_get_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x1e45cc6f nf_ct_iterate_cleanup +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x2f26528f nf_ct_unexpect_related +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x33522ec2 nf_ct_expect_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3607ed1b nf_ct_helper_ext_add +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x36acaf7e nf_conntrack_free +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3b22f815 nf_conntrack_hash_insert +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3bc6cdf8 nf_ct_l3proto_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3ef0d26d nf_ct_l4proto_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3f5b1415 nf_ct_port_nlattr_to_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x4323a400 nf_conntrack_chain +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x4465dc38 nf_ct_expect_init +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x4d6bc480 nf_ct_extend_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x4d8857f2 __nf_conntrack_confirm +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x54b2ab26 nf_conntrack_alloc +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x5b9cf9c8 nf_ct_deliver_cached_events +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x60612faa nf_conntrack_l3proto_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x61bfc48c nf_ct_expect_related +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x6a9fc377 nf_ct_get_tuplepr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x6b9be2ec nf_conntrack_l3proto_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x6e224a7a need_conntrack +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x78f9b710 nf_ct_l3proto_try_module_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x7aff967c nf_conntrack_in +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x7e80fa54 nf_conntrack_tcp_update +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x81c103a4 __nf_ct_expect_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x828bb808 nf_ct_extend_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x82ae51aa __nf_ct_helper_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x88a2ec3a nf_conntrack_flush +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x8a16e181 nf_conntrack_l4proto_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x8e5c3192 __nf_ct_event_cache_init +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x8ffe7e89 nf_conntrack_htable_size +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x90ff6c9f nf_ct_invert_tuplepr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x96699928 nf_ct_expect_alloc +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x968a9052 nf_ct_remove_expectations +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x9b08be95 nf_conntrack_l4proto_tcp6 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa409775d seq_print_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa6f62ec0 nf_conntrack_set_hashsize +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa83bcc14 nf_conntrack_helper_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa8573524 nf_conntrack_alter_reply +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa93edc17 nf_conntrack_l4proto_tcp4 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb1a5b650 nf_ct_expect_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb2e3a7bf nf_ct_unlink_expect +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb602c57e nf_ct_l3proto_module_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbb1e1f1c nf_conntrack_helper_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbc887e16 nf_ct_expect_register_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc044befe nf_ct_free_hashtable +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc18ac88d nf_ct_expect_hsize +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc2c5fd9f nfnetlink_parse_nat_setup_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc3685676 __nf_ct_l4proto_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc4b6433a nf_conntrack_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xcbf7fd2a nf_conntrack_register_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xce6cc703 nf_conntrack_l3proto_generic +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xcf0592de print_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd1a75799 nf_ct_l3proto_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd1e0b3d6 nf_ct_invert_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd2ac89ce nf_conntrack_l4proto_udp4 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd50a96a2 nf_ct_alloc_hashtable +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xdbef8b57 nf_conntrack_lock +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xdf790802 nf_ct_l4proto_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xe09aeb4c nf_conntrack_l4proto_udp6 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xe2d53ea0 nf_ct_l3protos +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xe6c069f9 __nf_conntrack_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf299113f nf_conntrack_untracked +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf39b1eb2 __nf_ct_kill_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf4f09850 nf_ct_port_tuple_to_nlattr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf9ae81a1 nf_conntrack_max +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf9b3f06d nf_ct_expect_chain +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfbfaca1d nf_conntrack_l4proto_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_amanda 0xbc7ee928 nf_nat_amanda_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_ftp 0x3e16e646 nf_nat_ftp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x29e540e8 set_h225_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x3c75b6dd nat_q931_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x533e92da nat_callforwarding_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x6ff752d4 nat_h245_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x700788e7 set_ras_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xa5de50fc set_sig_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xb10b7230 set_h245_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xe47b0b1b get_h225_addr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xe744fa00 nat_t120_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xf4a548f4 nat_rtp_rtcp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_irc 0xde7d6aa1 nf_nat_irc_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x29cc20a3 nf_nat_pptp_hook_inbound +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0xce7c43f7 nf_nat_pptp_hook_outbound +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0xed2a3d2a nf_nat_pptp_hook_exp_gre +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0xf347a68f nf_nat_pptp_hook_expectfn +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_proto_gre 0x2f7822d0 nf_ct_gre_keymap_destroy +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_proto_gre 0xf79a31c5 nf_ct_gre_keymap_add +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x2295f11f ct_sip_parse_numerical_param +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x237f9ae6 nf_nat_sip_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x2b8b455a nf_nat_sdp_media_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x2f4e48df nf_nat_sdp_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x31dbfd6d nf_nat_sdp_port_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x47e81950 nf_nat_sip_expect_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x8d498cdf ct_sip_parse_header_uri +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xb5140461 ct_sip_get_sdp_header +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xb6d620f2 ct_sip_get_header +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xc307bc85 ct_sip_parse_address_param +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xcd40b81a nf_nat_sdp_session_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xea91fbfc ct_sip_parse_request +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_tftp 0xec9d765b nf_nat_tftp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_tproxy_core 0x43ad48ee nf_tproxy_get_sock_v4 +EXPORT_SYMBOL_GPL net/netfilter/nf_tproxy_core 0xf5362a20 nf_tproxy_assign_sock +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x1f58e71b nfnl_lock +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x3895cd7a nfnl_unlock +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x3f01684e nfnetlink_subsys_unregister +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x6636f73f nfnetlink_subsys_register +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x833fce30 nfnetlink_send +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xeca95329 nfnetlink_has_listeners +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xf129350a nfnetlink_unicast +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x12961299 xt_request_find_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x1f3296ef xt_register_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x40728a63 xt_find_revision +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x49bb0db0 xt_proto_fini +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x5fc45c09 xt_unregister_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x6ed1a62e xt_check_match +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x7f26db45 xt_proto_init +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x9107855d xt_replace_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xc6daf41a xt_find_table_lock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xf5275572 xt_check_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xf9e99c2f xt_table_unlock +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0x01ca27cf xt_rateest_lookup +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0xe62aee08 xt_rateest_put +EXPORT_SYMBOL_GPL net/rfkill/rfkill 0x83b2e956 register_rfkill_notifier +EXPORT_SYMBOL_GPL net/rfkill/rfkill 0x86c722f8 rfkill_epo +EXPORT_SYMBOL_GPL net/rfkill/rfkill 0xa6f4320d unregister_rfkill_notifier +EXPORT_SYMBOL_GPL net/rfkill/rfkill 0xf972e196 rfkill_restore_states +EXPORT_SYMBOL_GPL net/rfkill/rfkill 0xfcce694c rfkill_set_default +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x01cb2347 svc_xprt_put +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x0279424b rpc_proc_register +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x05c2b89d xprt_disconnect_done +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x0fb2df96 rpc_delay +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x10c1a9ad rpc_malloc +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x10ea2079 rpc_create +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x11890c6d rpcauth_init_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x11a9dec2 xprt_update_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x126db22c xprt_release_rqst_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x128b7c81 rpc_bind_new_program +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1553d429 svc_max_payload +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x18380e02 rpc_shutdown_client +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1cf6a959 xprt_wait_for_buffer_space +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x21565afa svc_xprt_copy_addrs +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x258f7fcb rpcauth_lookup_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x26f8ac61 rpc_killall_tasks +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x280937f8 __rpc_wait_for_completion_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2aa17774 rpc_free_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2b01f27b svc_addsock +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2bc5ef35 svc_unreg_xprt_class +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2d29045b rpcauth_unregister +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2e926ad7 rpc_clone_client +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2fcbfb11 rpcauth_create +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x31a89d59 rpc_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3239dfa4 rpc_wake_up_status +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x32afdf3e csum_partial_copy_to_xdr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x354efd75 rpc_restart_call +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x35cf63ff rpc_init_wait_queue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x39cdc9ba rpc_call_null +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3a58e328 rpc_call_start +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3b6c75f9 xdr_partial_copy_from_skb +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3bd97623 rpc_call_async +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x401e1443 svc_find_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x449c09f3 rpc_put_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x4550678a rpc_lookup_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x45657b78 rpc_wake_up +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x47064043 svc_create_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x4a019f07 rpc_run_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x53445f68 nlm_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x595e796d xprt_release_xprt_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5bd26000 rpc_proc_unregister +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5be43364 rpc_print_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5c89ef45 xprt_write_space +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x60461883 xprt_reserve_xprt_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x61ed4f27 svc_xprt_names +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x67b64c18 xprt_lookup_rqst +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6c5304c5 rpcb_getport_sync +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6cffd5e3 put_rpccred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7196df58 rpcauth_register +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x73fdc5b5 svc_reg_xprt_class +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x74048436 rpc_force_rebind +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x75491d13 rpc_peeraddr2str +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x756fdcc2 svc_xprt_received +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7a6a59c4 xdr_skb_read_bits +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7de53067 rpc_init_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x82af8a94 rpc_wake_up_next +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x886cfa5a xprt_unregister_transport +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x899690bb xprt_set_retrans_timeout_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x92b52c2c rpc_sleep_on +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x92f15e4b xprt_complete_rqst +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x97dde559 xprt_set_retrans_timeout_def +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x9a79a760 rpcauth_init_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xa98d0416 rpc_wake_up_queued_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xaf5bf6ef nfs_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb09f8e86 rpc_alloc_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbce75a40 rpc_exit_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbd2408c9 svc_xprt_init +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbf9d1b96 nfsd_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc12435e3 rpc_calc_rto +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc50a5163 rpcauth_generic_bind_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc7b4cfff xprt_release_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xcb34e663 xprt_reserve_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xce3f876d rpcb_getport_async +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xcf884b48 rpc_peeraddr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd336a368 rpc_lookup_machine_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd3452148 xprt_adjust_cwnd +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe39bfc0d rpc_max_payload +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe508bb12 xprt_register_transport +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe54f1724 svc_close_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe64e8ea0 rpcauth_destroy_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xec9020b1 rpc_call_sync +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xeeacab69 rpc_update_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xef233ba3 rpc_destroy_wait_queue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xefabe390 rpc_setbufsize +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xf9aa6a36 xprt_wake_pending_tasks +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xf9d1164c rpc_free +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xfe5a38b8 svc_xprt_enqueue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xff07b0e2 svc_print_addr +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0x6c85974b ipcomp_destroy +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0x779470f2 ipcomp_output +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0xdbeac1fa ipcomp_init_state +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0xed83bf38 ipcomp_input +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x1584fdb9 tlsf_destroy_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x42a50f11 tlsf_malloc +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x66da3d8f tlsf_create_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xe6acc368 tlsf_free +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xee6c65c9 tlsf_get_used_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xeec8caeb tlsf_get_total_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xf9805f1b tlsf_calloc +EXPORT_SYMBOL_GPL vmlinux 0x002b860e add_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0x00566d8f inotify_get_cookie +EXPORT_SYMBOL_GPL vmlinux 0x010404fb queue_work_on +EXPORT_SYMBOL_GPL vmlinux 0x01a4ea6d unregister_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x01caf71a xfrm_output +EXPORT_SYMBOL_GPL vmlinux 0x03299912 kobject_rename +EXPORT_SYMBOL_GPL vmlinux 0x0343bdf1 __i2c_board_list +EXPORT_SYMBOL_GPL vmlinux 0x03ccf6f8 vlan_dev_real_dev +EXPORT_SYMBOL_GPL vmlinux 0x03e9dc12 usb_buffer_alloc +EXPORT_SYMBOL_GPL vmlinux 0x0407295f scsi_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0x04486e88 rcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x054e550b kernel_halt +EXPORT_SYMBOL_GPL vmlinux 0x056d4570 __crypto_alloc_tfm +EXPORT_SYMBOL_GPL vmlinux 0x057279af tty_perform_flush +EXPORT_SYMBOL_GPL vmlinux 0x05b66ae0 do_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0x062513e2 blk_end_request_callback +EXPORT_SYMBOL_GPL vmlinux 0x064db9a5 mark_mounts_for_expiry +EXPORT_SYMBOL_GPL vmlinux 0x06b3a6f6 sg_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x06d5a83d device_move +EXPORT_SYMBOL_GPL vmlinux 0x06dd9b62 bus_find_device +EXPORT_SYMBOL_GPL vmlinux 0x072c6992 unregister_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0x0769d5db scsi_target_unblock +EXPORT_SYMBOL_GPL vmlinux 0x076de72f sysfs_put +EXPORT_SYMBOL_GPL vmlinux 0x077ef82b k_handler +EXPORT_SYMBOL_GPL vmlinux 0x07b52e38 rtnl_unregister +EXPORT_SYMBOL_GPL vmlinux 0x085bad80 transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x086ab268 klist_init +EXPORT_SYMBOL_GPL vmlinux 0x091eb9b4 round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0x098eb026 __mnt_is_readonly +EXPORT_SYMBOL_GPL vmlinux 0x09ec0f77 page_mkclean +EXPORT_SYMBOL_GPL vmlinux 0x09f79c6d exit_fs +EXPORT_SYMBOL_GPL vmlinux 0x0af69aa8 sysdev_show_ulong +EXPORT_SYMBOL_GPL vmlinux 0x0b02dd94 usb_clear_halt +EXPORT_SYMBOL_GPL vmlinux 0x0b567544 kobject_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0x0bd31d4f __i2c_board_lock +EXPORT_SYMBOL_GPL vmlinux 0x0c17e274 xfrm_aalg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x0c2a2de0 get_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0x0c9912d9 usb_bulk_msg +EXPORT_SYMBOL_GPL vmlinux 0x0cec587c blk_queue_dma_drain +EXPORT_SYMBOL_GPL vmlinux 0x0dd0b393 sysfs_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x0e340666 tty_ldisc_deref +EXPORT_SYMBOL_GPL vmlinux 0x0edb7791 inotify_rm_watch +EXPORT_SYMBOL_GPL vmlinux 0x0f1938db class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x0f834461 anon_transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x0fdeb3a4 usb_unanchor_urb +EXPORT_SYMBOL_GPL vmlinux 0x0ff60659 rt_mutex_timed_lock +EXPORT_SYMBOL_GPL vmlinux 0x10bbe2b4 led_trigger_remove +EXPORT_SYMBOL_GPL vmlinux 0x1111631c vfs_test_lock +EXPORT_SYMBOL_GPL vmlinux 0x11468068 elv_unregister +EXPORT_SYMBOL_GPL vmlinux 0x1156a495 put_pid +EXPORT_SYMBOL_GPL vmlinux 0x11bb3511 usb_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x124b9ce0 usb_driver_claim_interface +EXPORT_SYMBOL_GPL vmlinux 0x1251d30f call_rcu +EXPORT_SYMBOL_GPL vmlinux 0x12685b41 usb_hc_died +EXPORT_SYMBOL_GPL vmlinux 0x12e48f46 devm_kfree +EXPORT_SYMBOL_GPL vmlinux 0x13b2a946 register_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x1455437a sysfs_remove_group +EXPORT_SYMBOL_GPL vmlinux 0x148fa8a5 init_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0x1598dc9d unregister_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x16abaaba blk_rq_check_limits +EXPORT_SYMBOL_GPL vmlinux 0x16f76869 probe_kernel_read +EXPORT_SYMBOL_GPL vmlinux 0x16fecfca usb_submit_urb +EXPORT_SYMBOL_GPL vmlinux 0x178af926 bus_for_each_dev +EXPORT_SYMBOL_GPL vmlinux 0x1835ceb0 usb_set_interface +EXPORT_SYMBOL_GPL vmlinux 0x18363eab alloc_page_buffers +EXPORT_SYMBOL_GPL vmlinux 0x18a446db platform_get_resource_byname +EXPORT_SYMBOL_GPL vmlinux 0x18d2b717 usb_driver_release_interface +EXPORT_SYMBOL_GPL vmlinux 0x191fb096 srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x19a304ba usb_disabled +EXPORT_SYMBOL_GPL vmlinux 0x1ba6fd54 scsi_eh_ready_devs +EXPORT_SYMBOL_GPL vmlinux 0x1c4c2bf7 fs_kobj +EXPORT_SYMBOL_GPL vmlinux 0x1c61033b generic_drop_inode +EXPORT_SYMBOL_GPL vmlinux 0x1c87a811 __round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x1c972c43 proc_net_fops_create +EXPORT_SYMBOL_GPL vmlinux 0x1ca17f3e led_trigger_event +EXPORT_SYMBOL_GPL vmlinux 0x1cb377f1 fib_rules_cleanup_ops +EXPORT_SYMBOL_GPL vmlinux 0x1e7bbcb3 kernel_restart +EXPORT_SYMBOL_GPL vmlinux 0x1eb9516e round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x1eca52c2 devres_open_group +EXPORT_SYMBOL_GPL vmlinux 0x1f007434 hrtimer_forward +EXPORT_SYMBOL_GPL vmlinux 0x1f9ba457 usb_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0x1fcece42 inet_twdr_twcal_tick +EXPORT_SYMBOL_GPL vmlinux 0x2031c0d4 led_trigger_set_default +EXPORT_SYMBOL_GPL vmlinux 0x204db783 usb_find_interface +EXPORT_SYMBOL_GPL vmlinux 0x20577ea2 xfrm_ealg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x20596565 usb_wait_anchor_empty_timeout +EXPORT_SYMBOL_GPL vmlinux 0x207e9895 nf_register_afinfo +EXPORT_SYMBOL_GPL vmlinux 0x20bc3470 orderly_poweroff +EXPORT_SYMBOL_GPL vmlinux 0x211de1c7 generic_sync_sb_inodes +EXPORT_SYMBOL_GPL vmlinux 0x21476211 disk_part_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x2151aa8a usb_sg_cancel +EXPORT_SYMBOL_GPL vmlinux 0x22472bf4 xfrm_calg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x22526d1d hrtimer_try_to_cancel +EXPORT_SYMBOL_GPL vmlinux 0x22a20b24 devres_release_group +EXPORT_SYMBOL_GPL vmlinux 0x22e2c20b atomic_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x231023df vfs_setlease +EXPORT_SYMBOL_GPL vmlinux 0x2332fc46 rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0x23679939 __iowrite32_copy +EXPORT_SYMBOL_GPL vmlinux 0x23869dc7 cancel_work_sync +EXPORT_SYMBOL_GPL vmlinux 0x23966589 usb_free_urb +EXPORT_SYMBOL_GPL vmlinux 0x24eb7e32 leds_list +EXPORT_SYMBOL_GPL vmlinux 0x25a7da42 kobject_uevent +EXPORT_SYMBOL_GPL vmlinux 0x25b97bb7 crypto_free_tfm +EXPORT_SYMBOL_GPL vmlinux 0x26bb7259 skb_morph +EXPORT_SYMBOL_GPL vmlinux 0x26c90ea4 scsi_eh_get_sense +EXPORT_SYMBOL_GPL vmlinux 0x26dc1bc8 bus_get_kset +EXPORT_SYMBOL_GPL vmlinux 0x2835d722 transport_configure_device +EXPORT_SYMBOL_GPL vmlinux 0x28b2cc80 atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x28d664ff __raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x28e23139 xfrm_probe_algs +EXPORT_SYMBOL_GPL vmlinux 0x28feaf4a device_release_driver +EXPORT_SYMBOL_GPL vmlinux 0x29d61e10 bus_find_device_by_name +EXPORT_SYMBOL_GPL vmlinux 0x2a2d93b7 klist_add_before +EXPORT_SYMBOL_GPL vmlinux 0x2abd0a87 vfs_listxattr +EXPORT_SYMBOL_GPL vmlinux 0x2b9f8e23 nf_net_ipv4_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x2c11289f do_add_mount +EXPORT_SYMBOL_GPL vmlinux 0x2c16ed76 xfrm_calg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x2c24eb30 screen_glyph +EXPORT_SYMBOL_GPL vmlinux 0x2c3ab7b3 sysdev_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x2c5d0efb class_interface_register +EXPORT_SYMBOL_GPL vmlinux 0x2cdca1a0 tcp_reno_min_cwnd +EXPORT_SYMBOL_GPL vmlinux 0x2e13e816 crypto_alg_lookup +EXPORT_SYMBOL_GPL vmlinux 0x2e3d08b9 crypto_chain +EXPORT_SYMBOL_GPL vmlinux 0x2e4ab1c7 sysdev_unregister +EXPORT_SYMBOL_GPL vmlinux 0x2f9c3919 vfs_lock_file +EXPORT_SYMBOL_GPL vmlinux 0x2fc579ce tcp_slow_start +EXPORT_SYMBOL_GPL vmlinux 0x313783f4 device_add +EXPORT_SYMBOL_GPL vmlinux 0x313df28e sysdev_store_ulong +EXPORT_SYMBOL_GPL vmlinux 0x31496b7d usb_deregister_dev +EXPORT_SYMBOL_GPL vmlinux 0x31d10d3c pci_enable_rom +EXPORT_SYMBOL_GPL vmlinux 0x33007787 tcp_get_info +EXPORT_SYMBOL_GPL vmlinux 0x33e8ae52 del_mtd_blktrans_dev +EXPORT_SYMBOL_GPL vmlinux 0x340f8043 debugfs_create_u16 +EXPORT_SYMBOL_GPL vmlinux 0x35853e86 blk_rq_bytes +EXPORT_SYMBOL_GPL vmlinux 0x35918d81 page_cache_async_readahead +EXPORT_SYMBOL_GPL vmlinux 0x35b2bcec fib_rules_unregister +EXPORT_SYMBOL_GPL vmlinux 0x35b76088 register_posix_clock +EXPORT_SYMBOL_GPL vmlinux 0x35d8c94a sdev_evt_alloc +EXPORT_SYMBOL_GPL vmlinux 0x35ec7fcb klist_next +EXPORT_SYMBOL_GPL vmlinux 0x3601e205 usb_hcd_poll_rh_status +EXPORT_SYMBOL_GPL vmlinux 0x362e23ec call_rcu_bh +EXPORT_SYMBOL_GPL vmlinux 0x36347e1b crypto_larval_alloc +EXPORT_SYMBOL_GPL vmlinux 0x36788bc3 pskb_put +EXPORT_SYMBOL_GPL vmlinux 0x36c1d4f8 get_task_mm +EXPORT_SYMBOL_GPL vmlinux 0x375155a7 sysdev_store_int +EXPORT_SYMBOL_GPL vmlinux 0x376ac385 __blk_put_request +EXPORT_SYMBOL_GPL vmlinux 0x377cc8f2 blk_abort_request +EXPORT_SYMBOL_GPL vmlinux 0x37ce9bf8 sysfs_notify_dirent +EXPORT_SYMBOL_GPL vmlinux 0x388e5d90 sysfs_remove_link +EXPORT_SYMBOL_GPL vmlinux 0x38c995b1 fsstack_copy_attr_all +EXPORT_SYMBOL_GPL vmlinux 0x393e38ee map_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x395f826b register_mtd_parser +EXPORT_SYMBOL_GPL vmlinux 0x3969eeb5 transport_setup_device +EXPORT_SYMBOL_GPL vmlinux 0x39778c16 bus_register +EXPORT_SYMBOL_GPL vmlinux 0x397d3e13 find_get_pid +EXPORT_SYMBOL_GPL vmlinux 0x39819646 atomic_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x39bf3b3a class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x3a07a837 sysfs_add_file_to_group +EXPORT_SYMBOL_GPL vmlinux 0x3a3ef75c device_destroy +EXPORT_SYMBOL_GPL vmlinux 0x3a7f8b86 __local_bh_enable +EXPORT_SYMBOL_GPL vmlinux 0x3ae42d55 transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x3b212ace platform_device_register_simple +EXPORT_SYMBOL_GPL vmlinux 0x3bc33f65 cleanup_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x3be7af02 get_max_files +EXPORT_SYMBOL_GPL vmlinux 0x3be89d3c usb_register_notify +EXPORT_SYMBOL_GPL vmlinux 0x3cbda6bb input_ff_create +EXPORT_SYMBOL_GPL vmlinux 0x3cc2fbf7 fsstack_copy_inode_size +EXPORT_SYMBOL_GPL vmlinux 0x3cd06035 add_input_randomness +EXPORT_SYMBOL_GPL vmlinux 0x3cee402b __inet_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0x3cfcec15 cfi_qry_present +EXPORT_SYMBOL_GPL vmlinux 0x3d0d70b8 usb_get_from_anchor +EXPORT_SYMBOL_GPL vmlinux 0x3dbbeba8 device_create_vargs +EXPORT_SYMBOL_GPL vmlinux 0x3dc3d3ab crypto_larval_kill +EXPORT_SYMBOL_GPL vmlinux 0x3e678b06 unregister_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0x3f01570a probe_kernel_write +EXPORT_SYMBOL_GPL vmlinux 0x3f6828b3 vfs_setxattr +EXPORT_SYMBOL_GPL vmlinux 0x3fe15ea8 skb_partial_csum_set +EXPORT_SYMBOL_GPL vmlinux 0x3fe70524 device_for_each_child +EXPORT_SYMBOL_GPL vmlinux 0x4012f84c scsi_execute_async +EXPORT_SYMBOL_GPL vmlinux 0x409458a6 audit_log_untrustedstring +EXPORT_SYMBOL_GPL vmlinux 0x40cbc8a9 usb_deregister_device_driver +EXPORT_SYMBOL_GPL vmlinux 0x413563b1 pci_find_next_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0x415aed86 cfi_qry_mode_off +EXPORT_SYMBOL_GPL vmlinux 0x41f3cc90 xfrm_aalg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x42801b01 disk_get_part +EXPORT_SYMBOL_GPL vmlinux 0x433cc0ab ip_local_out +EXPORT_SYMBOL_GPL vmlinux 0x43565750 usb_ifnum_to_if +EXPORT_SYMBOL_GPL vmlinux 0x43ab466b unregister_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0x43e6854a cfi_cmdset_0001 +EXPORT_SYMBOL_GPL vmlinux 0x4433d5c4 kset_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0x4491be8e devres_add +EXPORT_SYMBOL_GPL vmlinux 0x457594fa crypto_alg_list +EXPORT_SYMBOL_GPL vmlinux 0x457de656 crypto_alg_mod_lookup +EXPORT_SYMBOL_GPL vmlinux 0x460168d4 xfrm_output_resume +EXPORT_SYMBOL_GPL vmlinux 0x46401f41 usb_hcd_giveback_urb +EXPORT_SYMBOL_GPL vmlinux 0x46c72860 usb_bus_list_lock +EXPORT_SYMBOL_GPL vmlinux 0x47201e85 kobject_get_path +EXPORT_SYMBOL_GPL vmlinux 0x4773484e d_materialise_unique +EXPORT_SYMBOL_GPL vmlinux 0x47acfb77 pci_bus_max_busnr +EXPORT_SYMBOL_GPL vmlinux 0x48915607 device_schedule_callback_owner +EXPORT_SYMBOL_GPL vmlinux 0x48a99661 invalidate_inode_pages2 +EXPORT_SYMBOL_GPL vmlinux 0x48b320c6 class_dev_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x48d33791 inotify_dentry_parent_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x4992cb88 __inet_hash_nolisten +EXPORT_SYMBOL_GPL vmlinux 0x499b1cc5 input_ff_upload +EXPORT_SYMBOL_GPL vmlinux 0x49cbf3ea init_user_ns +EXPORT_SYMBOL_GPL vmlinux 0x49cd4d76 uart_console_write +EXPORT_SYMBOL_GPL vmlinux 0x49dfdbe9 transport_remove_device +EXPORT_SYMBOL_GPL vmlinux 0x4a283160 usb_poison_urb +EXPORT_SYMBOL_GPL vmlinux 0x4a78aa27 usb_register_dev +EXPORT_SYMBOL_GPL vmlinux 0x4a90a57b lookup_instantiate_filp +EXPORT_SYMBOL_GPL vmlinux 0x4b22d985 platform_get_irq_byname +EXPORT_SYMBOL_GPL vmlinux 0x4bd62f9e platform_driver_probe +EXPORT_SYMBOL_GPL vmlinux 0x4be32d43 inotify_find_watch +EXPORT_SYMBOL_GPL vmlinux 0x4c73d8ce generic_fh_to_parent +EXPORT_SYMBOL_GPL vmlinux 0x4c759827 byte_rev_table +EXPORT_SYMBOL_GPL vmlinux 0x4c85e60a usb_hcd_link_urb_to_ep +EXPORT_SYMBOL_GPL vmlinux 0x4d570b74 rtnl_kill_links +EXPORT_SYMBOL_GPL vmlinux 0x4d74b383 driver_find +EXPORT_SYMBOL_GPL vmlinux 0x4d97b83b register_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0x4de70bf7 udp4_lib_lookup +EXPORT_SYMBOL_GPL vmlinux 0x4de9af90 platform_device_alloc +EXPORT_SYMBOL_GPL vmlinux 0x4e54ddbb uhci_check_and_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0x4f5a12d1 tty_get_pgrp +EXPORT_SYMBOL_GPL vmlinux 0x4f9bcd5c debugfs_rename +EXPORT_SYMBOL_GPL vmlinux 0x509c0248 disk_part_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x50b67174 xfrm_ealg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x50e7193a __i2c_first_dynamic_bus_num +EXPORT_SYMBOL_GPL vmlinux 0x50fad434 round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x512155da debugfs_create_u64 +EXPORT_SYMBOL_GPL vmlinux 0x5141aaf6 driver_create_file +EXPORT_SYMBOL_GPL vmlinux 0x5182a214 sysdev_create_file +EXPORT_SYMBOL_GPL vmlinux 0x51cb0e29 find_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0x51dd6488 xfrm_aalg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x51eb9dea platform_add_devices +EXPORT_SYMBOL_GPL vmlinux 0x521f0283 vlan_dev_vlan_id +EXPORT_SYMBOL_GPL vmlinux 0x52c80adb platform_get_irq +EXPORT_SYMBOL_GPL vmlinux 0x52d111ea pm_qos_update_requirement +EXPORT_SYMBOL_GPL vmlinux 0x52ec35c9 __rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x53614269 get_cpu_idle_time_us +EXPORT_SYMBOL_GPL vmlinux 0x53716b5e usb_add_hcd +EXPORT_SYMBOL_GPL vmlinux 0x53986488 register_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x53ece934 anon_transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x546ef175 blk_execute_rq_nowait +EXPORT_SYMBOL_GPL vmlinux 0x5486ccc9 crypto_larval_lookup +EXPORT_SYMBOL_GPL vmlinux 0x549863bf tty_prepare_flip_string +EXPORT_SYMBOL_GPL vmlinux 0x54cd0bb3 add_mtd_blktrans_dev +EXPORT_SYMBOL_GPL vmlinux 0x5542b913 cpu_bit_bitmap +EXPORT_SYMBOL_GPL vmlinux 0x556a7285 device_register +EXPORT_SYMBOL_GPL vmlinux 0x55a61e68 kern_mount_data +EXPORT_SYMBOL_GPL vmlinux 0x55b1e7e1 synchronize_srcu +EXPORT_SYMBOL_GPL vmlinux 0x55d52dde inet_csk_listen_stop +EXPORT_SYMBOL_GPL vmlinux 0x5641485b tty_termios_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x56d42418 thread_notify_head +EXPORT_SYMBOL_GPL vmlinux 0x579e0bf5 rtnl_unregister_all +EXPORT_SYMBOL_GPL vmlinux 0x57a97695 tcp_done +EXPORT_SYMBOL_GPL vmlinux 0x57ad77f5 blk_abort_queue +EXPORT_SYMBOL_GPL vmlinux 0x5847daec usb_get_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x585d67f5 part_round_stats +EXPORT_SYMBOL_GPL vmlinux 0x587ceb9b get_cpu_sysdev +EXPORT_SYMBOL_GPL vmlinux 0x58f9e0be usb_reset_device +EXPORT_SYMBOL_GPL vmlinux 0x596789b4 pci_reset_function +EXPORT_SYMBOL_GPL vmlinux 0x596ea90d blk_set_cmd_filter_defaults +EXPORT_SYMBOL_GPL vmlinux 0x59aa8e23 dma_get_required_mask +EXPORT_SYMBOL_GPL vmlinux 0x59ca3224 inet_twdr_twkill_work +EXPORT_SYMBOL_GPL vmlinux 0x59e40d4a sysfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x59fdaa1a tty_wakeup +EXPORT_SYMBOL_GPL vmlinux 0x5a5e130b fib_rules_lookup +EXPORT_SYMBOL_GPL vmlinux 0x5a5f52d4 usb_get_hcd +EXPORT_SYMBOL_GPL vmlinux 0x5a7bfe41 crypto_probing_notify +EXPORT_SYMBOL_GPL vmlinux 0x5aac1199 hrtimer_start_range_ns +EXPORT_SYMBOL_GPL vmlinux 0x5abe016e usb_put_hcd +EXPORT_SYMBOL_GPL vmlinux 0x5ae67cd1 kill_mtd_super +EXPORT_SYMBOL_GPL vmlinux 0x5b7dae12 ehci_cf_port_reset_rwsem +EXPORT_SYMBOL_GPL vmlinux 0x5b8a5183 driver_add_kobj +EXPORT_SYMBOL_GPL vmlinux 0x5bae2dc0 parse_mtd_partitions +EXPORT_SYMBOL_GPL vmlinux 0x5bfc03c3 unregister_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5c58ffec klist_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x5ca1c55e nf_unregister_afinfo +EXPORT_SYMBOL_GPL vmlinux 0x5cc44f7e klist_add_head +EXPORT_SYMBOL_GPL vmlinux 0x5d0f6f57 kbd_table +EXPORT_SYMBOL_GPL vmlinux 0x5d4a4572 ktime_sub_ns +EXPORT_SYMBOL_GPL vmlinux 0x5d730e7b raw_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5d7e2f70 klist_add_tail +EXPORT_SYMBOL_GPL vmlinux 0x5dd67618 register_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5f1238b7 inet_csk_clone +EXPORT_SYMBOL_GPL vmlinux 0x5fb85ca6 inotify_rm_wd +EXPORT_SYMBOL_GPL vmlinux 0x5fd86a15 inet_twsk_purge +EXPORT_SYMBOL_GPL vmlinux 0x60470569 usb_hcd_pci_shutdown +EXPORT_SYMBOL_GPL vmlinux 0x6091797f synchronize_rcu +EXPORT_SYMBOL_GPL vmlinux 0x60a13e90 rcu_barrier +EXPORT_SYMBOL_GPL vmlinux 0x6107fa03 ip_route_output_flow +EXPORT_SYMBOL_GPL vmlinux 0x616c0401 scsi_target_block +EXPORT_SYMBOL_GPL vmlinux 0x61bdddf3 xfrm_inner_extract_output +EXPORT_SYMBOL_GPL vmlinux 0x61c8ea20 raw_seq_start +EXPORT_SYMBOL_GPL vmlinux 0x61d891ce pci_renumber_slot +EXPORT_SYMBOL_GPL vmlinux 0x6225c1b6 devres_alloc +EXPORT_SYMBOL_GPL vmlinux 0x622b3e2c srcu_read_lock +EXPORT_SYMBOL_GPL vmlinux 0x625ddecd pci_bus_add_device +EXPORT_SYMBOL_GPL vmlinux 0x629f8fc6 usb_sg_wait +EXPORT_SYMBOL_GPL vmlinux 0x633e91b9 attribute_container_register +EXPORT_SYMBOL_GPL vmlinux 0x63595a10 led_trigger_show +EXPORT_SYMBOL_GPL vmlinux 0x63c54991 nf_unregister_queue_handlers +EXPORT_SYMBOL_GPL vmlinux 0x6466f540 get_mtd_device_nm +EXPORT_SYMBOL_GPL vmlinux 0x646b10a9 audit_log_d_path +EXPORT_SYMBOL_GPL vmlinux 0x6533c99c driver_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x6586e792 sysfs_update_group +EXPORT_SYMBOL_GPL vmlinux 0x65cc7c92 bus_for_each_drv +EXPORT_SYMBOL_GPL vmlinux 0x65ccb6f0 call_netevent_notifiers +EXPORT_SYMBOL_GPL vmlinux 0x65df980f dnotify_parent +EXPORT_SYMBOL_GPL vmlinux 0x65e104a9 debugfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x667fbf65 rt_mutex_destroy +EXPORT_SYMBOL_GPL vmlinux 0x66a8a22a inet_twsk_schedule +EXPORT_SYMBOL_GPL vmlinux 0x66b2a859 nr_free_buffer_pages +EXPORT_SYMBOL_GPL vmlinux 0x66d87d38 symbol_put_addr +EXPORT_SYMBOL_GPL vmlinux 0x66dd57c1 simple_attr_open +EXPORT_SYMBOL_GPL vmlinux 0x686c703f xfrm_count_auth_supported +EXPORT_SYMBOL_GPL vmlinux 0x6883d169 inotify_init_watch +EXPORT_SYMBOL_GPL vmlinux 0x689f6c6d tty_put_char +EXPORT_SYMBOL_GPL vmlinux 0x691c2916 debugfs_remove_recursive +EXPORT_SYMBOL_GPL vmlinux 0x69234864 zap_vma_ptes +EXPORT_SYMBOL_GPL vmlinux 0x69f6fbcf skb_segment +EXPORT_SYMBOL_GPL vmlinux 0x6af63b0e skb_cow_data +EXPORT_SYMBOL_GPL vmlinux 0x6b8c10e6 del_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0x6bd659bc led_trigger_unregister_simple +EXPORT_SYMBOL_GPL vmlinux 0x6c49c4f2 clockevents_notify +EXPORT_SYMBOL_GPL vmlinux 0x6c765e24 inet6_lookup +EXPORT_SYMBOL_GPL vmlinux 0x6d2fc5a6 net_namespace_list +EXPORT_SYMBOL_GPL vmlinux 0x6d3f6418 pci_create_slot +EXPORT_SYMBOL_GPL vmlinux 0x6d62594b usb_deregister +EXPORT_SYMBOL_GPL vmlinux 0x6d70779a sysdev_class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x6dd3b275 tty_prepare_flip_string_flags +EXPORT_SYMBOL_GPL vmlinux 0x6dec76ae platform_device_put +EXPORT_SYMBOL_GPL vmlinux 0x6e2ff071 inotify_inode_is_dead +EXPORT_SYMBOL_GPL vmlinux 0x6e401a07 klist_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x6e6f81e2 register_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0x6e823b44 driver_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x6e9a6915 sysfs_chmod_file +EXPORT_SYMBOL_GPL vmlinux 0x6ed146bc scsi_mode_select +EXPORT_SYMBOL_GPL vmlinux 0x6f1a9edc sdev_evt_send_simple +EXPORT_SYMBOL_GPL vmlinux 0x7069d3ea fib_rules_register +EXPORT_SYMBOL_GPL vmlinux 0x70b02ec4 usb_hcd_unlink_urb_from_ep +EXPORT_SYMBOL_GPL vmlinux 0x70bd23c7 mtd_erase_callback +EXPORT_SYMBOL_GPL vmlinux 0x710c61e3 tcp_init_congestion_ops +EXPORT_SYMBOL_GPL vmlinux 0x71196147 tcp_orphan_count +EXPORT_SYMBOL_GPL vmlinux 0x713119a9 rt_mutex_trylock +EXPORT_SYMBOL_GPL vmlinux 0x71f9246a leds_list_lock +EXPORT_SYMBOL_GPL vmlinux 0x726cb37d inverse_translate +EXPORT_SYMBOL_GPL vmlinux 0x72979891 uhci_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0x72f34fd1 rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0x7364a2c1 get_sb_mtd +EXPORT_SYMBOL_GPL vmlinux 0x73b1f76d do_posix_clock_nosettime +EXPORT_SYMBOL_GPL vmlinux 0x73b3c4af pciserial_resume_ports +EXPORT_SYMBOL_GPL vmlinux 0x73eaba33 debugfs_create_symlink +EXPORT_SYMBOL_GPL vmlinux 0x7408c04e rtnl_put_cacheinfo +EXPORT_SYMBOL_GPL vmlinux 0x74234235 scsi_nl_add_transport +EXPORT_SYMBOL_GPL vmlinux 0x7450ab53 inet_twsk_alloc +EXPORT_SYMBOL_GPL vmlinux 0x7486289a init_uts_ns +EXPORT_SYMBOL_GPL vmlinux 0x74dc5aaf register_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0x75662941 inotify_find_update_watch +EXPORT_SYMBOL_GPL vmlinux 0x76bf73d0 bdi_writeout_inc +EXPORT_SYMBOL_GPL vmlinux 0x7729cd35 bus_unregister +EXPORT_SYMBOL_GPL vmlinux 0x78af7c8f init_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x793bddd1 usb_control_msg +EXPORT_SYMBOL_GPL vmlinux 0x7948d109 srcu_read_unlock +EXPORT_SYMBOL_GPL vmlinux 0x79601497 pciserial_suspend_ports +EXPORT_SYMBOL_GPL vmlinux 0x79d2f3c2 usb_get_urb +EXPORT_SYMBOL_GPL vmlinux 0x79d2f8a1 usb_anchor_empty +EXPORT_SYMBOL_GPL vmlinux 0x7a1b1127 device_rename +EXPORT_SYMBOL_GPL vmlinux 0x7a792fd8 audit_log_vformat +EXPORT_SYMBOL_GPL vmlinux 0x7a901384 debugfs_create_u32 +EXPORT_SYMBOL_GPL vmlinux 0x7aa5a09a rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x7b27370e usb_sg_init +EXPORT_SYMBOL_GPL vmlinux 0x7b3d39f9 raw_seq_stop +EXPORT_SYMBOL_GPL vmlinux 0x7b4285bf unregister_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0x7b5cfe02 kernel_kobj +EXPORT_SYMBOL_GPL vmlinux 0x7b6022a8 inet6_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0x7b8ad86f bd_claim_by_disk +EXPORT_SYMBOL_GPL vmlinux 0x7c666959 device_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x7c6784ef ktime_get_real +EXPORT_SYMBOL_GPL vmlinux 0x7c8894d5 __rt_mutex_init +EXPORT_SYMBOL_GPL vmlinux 0x7d62dde8 platform_driver_register +EXPORT_SYMBOL_GPL vmlinux 0x7d748e1c do_sync_mapping_range +EXPORT_SYMBOL_GPL vmlinux 0x7dbe7466 usb_get_intf +EXPORT_SYMBOL_GPL vmlinux 0x7e275ea8 scsi_complete_async_scans +EXPORT_SYMBOL_GPL vmlinux 0x7e64181d usb_calc_bus_time +EXPORT_SYMBOL_GPL vmlinux 0x7ea7bc61 get_driver +EXPORT_SYMBOL_GPL vmlinux 0x7efadd4b usb_hcd_platform_shutdown +EXPORT_SYMBOL_GPL vmlinux 0x7f628320 default_backing_dev_info +EXPORT_SYMBOL_GPL vmlinux 0x7fd402b4 bus_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x7ff10ccf raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x7ffe5d5e class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x8023232d device_attach +EXPORT_SYMBOL_GPL vmlinux 0x809c6da2 proc_net_remove +EXPORT_SYMBOL_GPL vmlinux 0x81048242 netlink_has_listeners +EXPORT_SYMBOL_GPL vmlinux 0x8189e246 inotify_inode_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x81d8cbdb device_bind_driver +EXPORT_SYMBOL_GPL vmlinux 0x81eb2c1e fnotify_change +EXPORT_SYMBOL_GPL vmlinux 0x8208f07b attribute_container_find_class_device +EXPORT_SYMBOL_GPL vmlinux 0x821118c1 inet_csk_get_port +EXPORT_SYMBOL_GPL vmlinux 0x826360fd do_posix_clock_nonanosleep +EXPORT_SYMBOL_GPL vmlinux 0x82d5ec71 usb_match_id +EXPORT_SYMBOL_GPL vmlinux 0x82d79b51 sysctl_vfs_cache_pressure +EXPORT_SYMBOL_GPL vmlinux 0x836d2cc9 __blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x8376afb8 disk_map_sector_rcu +EXPORT_SYMBOL_GPL vmlinux 0x8412e3c5 srcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x8449318b schedule_hrtimeout +EXPORT_SYMBOL_GPL vmlinux 0x84b11562 skb_pull_rcsum +EXPORT_SYMBOL_GPL vmlinux 0x8561cbe9 usb_poison_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x85b5658a led_trigger_unregister +EXPORT_SYMBOL_GPL vmlinux 0x85c10896 rcu_batches_completed_bh +EXPORT_SYMBOL_GPL vmlinux 0x85e0d4e6 platform_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x85e5a3db ktime_get_ts +EXPORT_SYMBOL_GPL vmlinux 0x868784cb __symbol_get +EXPORT_SYMBOL_GPL vmlinux 0x87177ecb crypto_mod_put +EXPORT_SYMBOL_GPL vmlinux 0x87754115 raw_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x87a2ab34 debugfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0x87ee762d inet_csk_reqsk_queue_prune +EXPORT_SYMBOL_GPL vmlinux 0x87f38901 blk_update_request +EXPORT_SYMBOL_GPL vmlinux 0x8812bfa6 pid_vnr +EXPORT_SYMBOL_GPL vmlinux 0x8832e79b blk_queue_rq_timeout +EXPORT_SYMBOL_GPL vmlinux 0x885142a6 nf_net_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x88791f34 crypto_alloc_base +EXPORT_SYMBOL_GPL vmlinux 0x89183ed9 seq_release_net +EXPORT_SYMBOL_GPL vmlinux 0x89c5231f input_ff_erase +EXPORT_SYMBOL_GPL vmlinux 0x8a3a6a80 bus_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x8a75a54b inet_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0x8a88d0e1 usb_hcd_pci_remove +EXPORT_SYMBOL_GPL vmlinux 0x8aaa6472 inet_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0x8abed13d xfrm_aead_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x8aeeed1b tcp_twsk_unique +EXPORT_SYMBOL_GPL vmlinux 0x8b400091 usb_hcd_check_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0x8c2a16b1 register_net_sysctl_rotable +EXPORT_SYMBOL_GPL vmlinux 0x8c4a8e6f disk_part_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x8c5f92ef raw_hash_sk +EXPORT_SYMBOL_GPL vmlinux 0x8d0019aa dev_set_name +EXPORT_SYMBOL_GPL vmlinux 0x8d2831ad usb_unlink_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x8d942e19 driver_find_device +EXPORT_SYMBOL_GPL vmlinux 0x8e454dcd __sock_recv_timestamp +EXPORT_SYMBOL_GPL vmlinux 0x8eb22834 tty_ldisc_flush +EXPORT_SYMBOL_GPL vmlinux 0x8f316dd8 platform_device_add +EXPORT_SYMBOL_GPL vmlinux 0x8f6cee77 __round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x90a1004a crypto_has_alg +EXPORT_SYMBOL_GPL vmlinux 0x912b95ba console_drivers +EXPORT_SYMBOL_GPL vmlinux 0x915f8c44 tty_ldisc_ref_wait +EXPORT_SYMBOL_GPL vmlinux 0x91d8daa3 tcp_register_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0x91fe00e4 tcp_reno_ssthresh +EXPORT_SYMBOL_GPL vmlinux 0x92445aee hrtimer_get_res +EXPORT_SYMBOL_GPL vmlinux 0x93281185 class_find_device +EXPORT_SYMBOL_GPL vmlinux 0x936a3392 pciserial_remove_ports +EXPORT_SYMBOL_GPL vmlinux 0x9382bd39 devres_remove +EXPORT_SYMBOL_GPL vmlinux 0x93d2422d snmp_mib_free +EXPORT_SYMBOL_GPL vmlinux 0x945ac6de xattr_getsecurity +EXPORT_SYMBOL_GPL vmlinux 0x94fa885e device_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x951f8d8c scsi_internal_device_block +EXPORT_SYMBOL_GPL vmlinux 0x952664c5 do_exit +EXPORT_SYMBOL_GPL vmlinux 0x9551f5a1 driver_attach +EXPORT_SYMBOL_GPL vmlinux 0x958bce65 driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0x963aa34d debugfs_create_x8 +EXPORT_SYMBOL_GPL vmlinux 0x96ac8713 inet_csk_route_req +EXPORT_SYMBOL_GPL vmlinux 0x96c60636 posix_timer_event +EXPORT_SYMBOL_GPL vmlinux 0x96cbcf31 pm_qos_add_notifier +EXPORT_SYMBOL_GPL vmlinux 0x97303a93 destroy_workqueue +EXPORT_SYMBOL_GPL vmlinux 0x98196f5b blocking_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x9834ac8f register_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0x991b8d07 put_driver +EXPORT_SYMBOL_GPL vmlinux 0x9924c496 __usb_get_extra_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x99442d54 usb_match_one_id +EXPORT_SYMBOL_GPL vmlinux 0x99a2e9b3 simple_attr_write +EXPORT_SYMBOL_GPL vmlinux 0x99d47909 inet_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0x99f99245 usb_string +EXPORT_SYMBOL_GPL vmlinux 0x9a0c62a3 sched_setscheduler +EXPORT_SYMBOL_GPL vmlinux 0x9a398f5c xfrm_ealg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x9ac4017a input_ff_event +EXPORT_SYMBOL_GPL vmlinux 0x9b949409 hrtimer_init +EXPORT_SYMBOL_GPL vmlinux 0x9ba0501e unregister_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0x9cb8037b xfrm_count_enc_supported +EXPORT_SYMBOL_GPL vmlinux 0x9cf3ac14 pci_find_ext_capability +EXPORT_SYMBOL_GPL vmlinux 0x9d05ffbd crypto_alg_sem +EXPORT_SYMBOL_GPL vmlinux 0x9db64888 register_mtd_blktrans +EXPORT_SYMBOL_GPL vmlinux 0x9e247ed5 blk_queue_rq_timed_out +EXPORT_SYMBOL_GPL vmlinux 0x9e27a774 raw_seq_open +EXPORT_SYMBOL_GPL vmlinux 0x9e711ad2 pm_qos_requirement +EXPORT_SYMBOL_GPL vmlinux 0x9e7c6b7c __inet_twsk_hashdance +EXPORT_SYMBOL_GPL vmlinux 0x9e920d18 tcp_set_state +EXPORT_SYMBOL_GPL vmlinux 0x9ecd18c2 anon_inode_getfd +EXPORT_SYMBOL_GPL vmlinux 0x9f28ea62 platform_bus +EXPORT_SYMBOL_GPL vmlinux 0x9fcc5d39 free_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x9fce80db fb_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x9fdfb997 debugfs_create_bool +EXPORT_SYMBOL_GPL vmlinux 0x9fe089ff put_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0xa0255440 net_ipv4_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0xa02b2427 class_dev_iter_init +EXPORT_SYMBOL_GPL vmlinux 0xa02de8f3 usb_get_dev +EXPORT_SYMBOL_GPL vmlinux 0xa084c7ce sysfs_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xa19109ec kobject_uevent_env +EXPORT_SYMBOL_GPL vmlinux 0xa1a8fd60 proc_net_mkdir +EXPORT_SYMBOL_GPL vmlinux 0xa28f980f class_destroy +EXPORT_SYMBOL_GPL vmlinux 0xa29a1214 usb_scuttle_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xa300ef94 inet_unhash +EXPORT_SYMBOL_GPL vmlinux 0xa324a553 pci_destroy_slot +EXPORT_SYMBOL_GPL vmlinux 0xa386024a class_dev_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0xa3933f95 transport_add_device +EXPORT_SYMBOL_GPL vmlinux 0xa4361b10 inet_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0xa47f08c5 inotify_init +EXPORT_SYMBOL_GPL vmlinux 0xa4f09479 arm_pm_restart +EXPORT_SYMBOL_GPL vmlinux 0xa503c531 inet_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0xa52ea4c6 debugfs_remove +EXPORT_SYMBOL_GPL vmlinux 0xa57afc74 ktime_get +EXPORT_SYMBOL_GPL vmlinux 0xa5b48d16 attribute_container_unregister +EXPORT_SYMBOL_GPL vmlinux 0xa5bf5c3e pm_qos_add_requirement +EXPORT_SYMBOL_GPL vmlinux 0xa5c36cec inotify_unmount_inodes +EXPORT_SYMBOL_GPL vmlinux 0xa5cf2bd2 sysfs_get_dirent +EXPORT_SYMBOL_GPL vmlinux 0xa65f9329 raw_seq_next +EXPORT_SYMBOL_GPL vmlinux 0xa69c789e pci_scan_child_bus +EXPORT_SYMBOL_GPL vmlinux 0xa6f38122 usb_put_dev +EXPORT_SYMBOL_GPL vmlinux 0xa73bf280 bd_release_from_disk +EXPORT_SYMBOL_GPL vmlinux 0xa7b8a645 devres_close_group +EXPORT_SYMBOL_GPL vmlinux 0xa801ca59 sock_prot_inuse_get +EXPORT_SYMBOL_GPL vmlinux 0xa8282e34 rt_mutex_lock +EXPORT_SYMBOL_GPL vmlinux 0xa8a929ac flush_workqueue +EXPORT_SYMBOL_GPL vmlinux 0xa8f7cb78 hrtimer_cancel +EXPORT_SYMBOL_GPL vmlinux 0xa9c530b8 unregister_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xa9de0c3d rt_mutex_unlock +EXPORT_SYMBOL_GPL vmlinux 0xaa2a72bf __iowrite64_copy +EXPORT_SYMBOL_GPL vmlinux 0xaa8c4696 cpu_clock +EXPORT_SYMBOL_GPL vmlinux 0xab669aa4 sysctl_pathname +EXPORT_SYMBOL_GPL vmlinux 0xab690667 register_mtd_user +EXPORT_SYMBOL_GPL vmlinux 0xabf6ba05 alloc_vm_area +EXPORT_SYMBOL_GPL vmlinux 0xac27d54a sysfs_notify +EXPORT_SYMBOL_GPL vmlinux 0xaca678e2 __inet_lookup_established +EXPORT_SYMBOL_GPL vmlinux 0xace5c0fc usb_bus_list +EXPORT_SYMBOL_GPL vmlinux 0xad217edf firmware_kobj +EXPORT_SYMBOL_GPL vmlinux 0xad4247af bus_rescan_devices +EXPORT_SYMBOL_GPL vmlinux 0xad775c70 default_mtd_writev +EXPORT_SYMBOL_GPL vmlinux 0xada7ca99 pci_find_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0xadbb2197 klist_add_after +EXPORT_SYMBOL_GPL vmlinux 0xadd3978a inet_twsk_put +EXPORT_SYMBOL_GPL vmlinux 0xadf4ebf3 devres_get +EXPORT_SYMBOL_GPL vmlinux 0xae0c87ee pm_qos_remove_notifier +EXPORT_SYMBOL_GPL vmlinux 0xae6995e1 attribute_container_classdev_to_container +EXPORT_SYMBOL_GPL vmlinux 0xaed4dced skb_to_sgvec +EXPORT_SYMBOL_GPL vmlinux 0xb0169ec0 rt_mutex_lock_interruptible +EXPORT_SYMBOL_GPL vmlinux 0xb0ee07e3 vfs_getxattr +EXPORT_SYMBOL_GPL vmlinux 0xb0f4d357 __mmdrop +EXPORT_SYMBOL_GPL vmlinux 0xb1ab3e17 cfi_cmdset_0200 +EXPORT_SYMBOL_GPL vmlinux 0xb1acbcce rcu_barrier_sched +EXPORT_SYMBOL_GPL vmlinux 0xb1f56187 usb_put_intf +EXPORT_SYMBOL_GPL vmlinux 0xb3664270 debugfs_create_x16 +EXPORT_SYMBOL_GPL vmlinux 0xb3b1e6c8 devres_destroy +EXPORT_SYMBOL_GPL vmlinux 0xb448f831 usb_reset_configuration +EXPORT_SYMBOL_GPL vmlinux 0xb449ed11 mtd_table_mutex +EXPORT_SYMBOL_GPL vmlinux 0xb47cc661 simple_attr_read +EXPORT_SYMBOL_GPL vmlinux 0xb4a4b9fb blocking_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0xb4c409a2 usb_altnum_to_altsetting +EXPORT_SYMBOL_GPL vmlinux 0xb4f6c856 sdev_evt_send +EXPORT_SYMBOL_GPL vmlinux 0xb5038ec2 bus_sort_breadthfirst +EXPORT_SYMBOL_GPL vmlinux 0xb59fe4c3 crypto_shoot_alg +EXPORT_SYMBOL_GPL vmlinux 0xb5f839c6 debugfs_create_blob +EXPORT_SYMBOL_GPL vmlinux 0xb77399d8 inotify_remove_watch_locked +EXPORT_SYMBOL_GPL vmlinux 0xb7a92757 d_obtain_alias +EXPORT_SYMBOL_GPL vmlinux 0xb8115516 __blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0xb8325e18 kobject_init_and_add +EXPORT_SYMBOL_GPL vmlinux 0xb85091fe led_trigger_set +EXPORT_SYMBOL_GPL vmlinux 0xb8759c2c srcu_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0xb87bb627 queue_work +EXPORT_SYMBOL_GPL vmlinux 0xb8a55b0c invalidate_inode_pages2_range +EXPORT_SYMBOL_GPL vmlinux 0xb8e1a05e platform_get_resource +EXPORT_SYMBOL_GPL vmlinux 0xb8fee532 blocking_notifier_chain_cond_register +EXPORT_SYMBOL_GPL vmlinux 0xb925451a tcp_death_row +EXPORT_SYMBOL_GPL vmlinux 0xb9ab3f4b device_initialize +EXPORT_SYMBOL_GPL vmlinux 0xb9ced93c mnt_drop_write +EXPORT_SYMBOL_GPL vmlinux 0xb9eb3aa9 add_uevent_var +EXPORT_SYMBOL_GPL vmlinux 0xb9fc86b5 sysfs_schedule_callback +EXPORT_SYMBOL_GPL vmlinux 0xb9fc8f08 sysdev_class_register +EXPORT_SYMBOL_GPL vmlinux 0xba03f3a0 platform_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xbabda668 pciserial_init_ports +EXPORT_SYMBOL_GPL vmlinux 0xbae34c27 scsi_nl_remove_transport +EXPORT_SYMBOL_GPL vmlinux 0xbaf09ec0 klist_del +EXPORT_SYMBOL_GPL vmlinux 0xbaf69c3d usb_buffer_free +EXPORT_SYMBOL_GPL vmlinux 0xbb248c8a get_user_pages_fast +EXPORT_SYMBOL_GPL vmlinux 0xbb3316e8 sysfs_get +EXPORT_SYMBOL_GPL vmlinux 0xbb9a2c75 ktime_add_ns +EXPORT_SYMBOL_GPL vmlinux 0xbbd91e3d crypto_mod_get +EXPORT_SYMBOL_GPL vmlinux 0xbbfbb8a7 class_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0xbc824413 sysdev_register +EXPORT_SYMBOL_GPL vmlinux 0xbd24e514 sysdev_driver_register +EXPORT_SYMBOL_GPL vmlinux 0xbd5e225d unregister_mtd_user +EXPORT_SYMBOL_GPL vmlinux 0xbeea7a2b srcu_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0xbf4aec98 blk_insert_cloned_request +EXPORT_SYMBOL_GPL vmlinux 0xbfcd6333 inotify_add_watch +EXPORT_SYMBOL_GPL vmlinux 0xbfe7385b usb_kill_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xc04c3853 get_current_tty +EXPORT_SYMBOL_GPL vmlinux 0xc12ade40 shmem_file_setup +EXPORT_SYMBOL_GPL vmlinux 0xc12cb7bb mmput +EXPORT_SYMBOL_GPL vmlinux 0xc12fea56 blkdev_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xc17515d7 usb_hcds_loaded +EXPORT_SYMBOL_GPL vmlinux 0xc22a3091 vm_unmap_aliases +EXPORT_SYMBOL_GPL vmlinux 0xc25cf64f seq_open_net +EXPORT_SYMBOL_GPL vmlinux 0xc30ff9c6 driver_register +EXPORT_SYMBOL_GPL vmlinux 0xc319bccf __get_vm_area +EXPORT_SYMBOL_GPL vmlinux 0xc32dc9b0 __create_workqueue_key +EXPORT_SYMBOL_GPL vmlinux 0xc34efe27 snmp_fold_field +EXPORT_SYMBOL_GPL vmlinux 0xc37ee2ca scsi_nl_sock +EXPORT_SYMBOL_GPL vmlinux 0xc399468f scsi_nl_remove_driver +EXPORT_SYMBOL_GPL vmlinux 0xc3afa4ee bus_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xc4546e6b devres_remove_group +EXPORT_SYMBOL_GPL vmlinux 0xc4ce68c6 sysdev_class_create_file +EXPORT_SYMBOL_GPL vmlinux 0xc59d4109 usb_remove_hcd +EXPORT_SYMBOL_GPL vmlinux 0xc5a6114b cfi_qry_mode_on +EXPORT_SYMBOL_GPL vmlinux 0xc6c2c74a usb_buffer_map_sg +EXPORT_SYMBOL_GPL vmlinux 0xc763bfad get_device +EXPORT_SYMBOL_GPL vmlinux 0xc7d5a955 __class_create +EXPORT_SYMBOL_GPL vmlinux 0xc80e4476 unregister_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0xc8d6a46b pci_execute_reset_function +EXPORT_SYMBOL_GPL vmlinux 0xc9a3dcdc platform_device_add_resources +EXPORT_SYMBOL_GPL vmlinux 0xc9f22ae3 platform_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xca9e6283 put_device +EXPORT_SYMBOL_GPL vmlinux 0xcacf7f7d find_vpid +EXPORT_SYMBOL_GPL vmlinux 0xcb0c2ebf __srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xcbda1f42 __pneigh_lookup +EXPORT_SYMBOL_GPL vmlinux 0xcc1f1c3d inet_twdr_hangman +EXPORT_SYMBOL_GPL vmlinux 0xcc3cd014 blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0xcc6bd83d macvlan_handle_frame_hook +EXPORT_SYMBOL_GPL vmlinux 0xcc9c70d7 single_open_net +EXPORT_SYMBOL_GPL vmlinux 0xcca0c0c8 schedule_hrtimeout_range +EXPORT_SYMBOL_GPL vmlinux 0xccb06e48 usb_create_hcd +EXPORT_SYMBOL_GPL vmlinux 0xcda32a94 klist_remove +EXPORT_SYMBOL_GPL vmlinux 0xcdb3cff0 klist_iter_init_node +EXPORT_SYMBOL_GPL vmlinux 0xcdca3691 nr_irqs +EXPORT_SYMBOL_GPL vmlinux 0xce979f3e mm_kobj +EXPORT_SYMBOL_GPL vmlinux 0xced16cff __rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0xcedb0a2c hrtimer_get_remaining +EXPORT_SYMBOL_GPL vmlinux 0xcf37a4a7 blk_rq_cur_bytes +EXPORT_SYMBOL_GPL vmlinux 0xcfa019eb __rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0xcfc0d883 device_create_file +EXPORT_SYMBOL_GPL vmlinux 0xcfcc83ad register_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0xcfe500f4 elv_register +EXPORT_SYMBOL_GPL vmlinux 0xd015feb1 __blkdev_driver_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xd03c6827 usb_hub_tt_clear_buffer +EXPORT_SYMBOL_GPL vmlinux 0xd03c7700 secure_ipv4_port_ephemeral +EXPORT_SYMBOL_GPL vmlinux 0xd0c05159 emergency_restart +EXPORT_SYMBOL_GPL vmlinux 0xd0d2532e device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xd10a5dc0 device_reprobe +EXPORT_SYMBOL_GPL vmlinux 0xd1454cd6 lookup_create +EXPORT_SYMBOL_GPL vmlinux 0xd17c00fb drop_file_write_access +EXPORT_SYMBOL_GPL vmlinux 0xd1925829 usb_buffer_unmap_sg +EXPORT_SYMBOL_GPL vmlinux 0xd204dcff tcp_twsk_destructor +EXPORT_SYMBOL_GPL vmlinux 0xd273b1b1 __round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xd33a0f21 device_find_child +EXPORT_SYMBOL_GPL vmlinux 0xd3541127 page_cache_sync_readahead +EXPORT_SYMBOL_GPL vmlinux 0xd3cc12d8 class_interface_unregister +EXPORT_SYMBOL_GPL vmlinux 0xd3d6f385 usb_get_current_frame_number +EXPORT_SYMBOL_GPL vmlinux 0xd3f3aff3 copy_fs_struct +EXPORT_SYMBOL_GPL vmlinux 0xd41d13e6 vfs_removexattr +EXPORT_SYMBOL_GPL vmlinux 0xd44b9fdf __class_register +EXPORT_SYMBOL_GPL vmlinux 0xd4734e1a bus_get_device_klist +EXPORT_SYMBOL_GPL vmlinux 0xd5e694e8 pci_stop_bus_device +EXPORT_SYMBOL_GPL vmlinux 0xd6fed6ee sysdev_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xd741cfcf blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xd74841fc device_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xd892a149 sock_prot_inuse_add +EXPORT_SYMBOL_GPL vmlinux 0xd95f65a3 pci_slots_kset +EXPORT_SYMBOL_GPL vmlinux 0xd990a21e tty_buffer_request_room +EXPORT_SYMBOL_GPL vmlinux 0xd9a9dc66 scsi_nl_add_driver +EXPORT_SYMBOL_GPL vmlinux 0xd9d28ade usb_interrupt_msg +EXPORT_SYMBOL_GPL vmlinux 0xda194561 led_trigger_register_simple +EXPORT_SYMBOL_GPL vmlinux 0xdaa2fcc6 cfi_cmdset_0003 +EXPORT_SYMBOL_GPL vmlinux 0xdae7989d usb_get_status +EXPORT_SYMBOL_GPL vmlinux 0xdb1373e6 file_ra_state_init +EXPORT_SYMBOL_GPL vmlinux 0xdb339008 led_trigger_store +EXPORT_SYMBOL_GPL vmlinux 0xdb36bcc8 tcp_is_cwnd_limited +EXPORT_SYMBOL_GPL vmlinux 0xdb4db72c register_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0xdb7495bf inotify_destroy +EXPORT_SYMBOL_GPL vmlinux 0xdb81b17c blk_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0xdc34de02 device_del +EXPORT_SYMBOL_GPL vmlinux 0xdc3f5d59 pci_block_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0xdc62c742 sysdev_show_int +EXPORT_SYMBOL_GPL vmlinux 0xdda1d62d tcp_unregister_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0xde040eef single_release_net +EXPORT_SYMBOL_GPL vmlinux 0xde94c681 sysdev_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xdf1131fb tty_ldisc_ref +EXPORT_SYMBOL_GPL vmlinux 0xdf1b528c scsi_queue_work +EXPORT_SYMBOL_GPL vmlinux 0xdf8701e3 pci_find_next_capability +EXPORT_SYMBOL_GPL vmlinux 0xe04cc42f usb_anchor_urb +EXPORT_SYMBOL_GPL vmlinux 0xe06a8c08 tty_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0xe089922f blk_queue_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0xe09c2306 platform_device_del +EXPORT_SYMBOL_GPL vmlinux 0xe0b4b2c2 sk_setup_caps +EXPORT_SYMBOL_GPL vmlinux 0xe0c9aa46 mtd_table +EXPORT_SYMBOL_GPL vmlinux 0xe11499ac led_trigger_register +EXPORT_SYMBOL_GPL vmlinux 0xe159a0c2 deregister_mtd_parser +EXPORT_SYMBOL_GPL vmlinux 0xe1b0baf3 hrtimer_start +EXPORT_SYMBOL_GPL vmlinux 0xe305b72b usb_register_device_driver +EXPORT_SYMBOL_GPL vmlinux 0xe3b19d6b platform_device_add_data +EXPORT_SYMBOL_GPL vmlinux 0xe4275a9e kill_pid_info_as_uid +EXPORT_SYMBOL_GPL vmlinux 0xe46278da usb_hcd_pci_probe +EXPORT_SYMBOL_GPL vmlinux 0xe4cc79c3 scsi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xe4d80ab2 queue_delayed_work_on +EXPORT_SYMBOL_GPL vmlinux 0xe530071c pm_qos_remove_requirement +EXPORT_SYMBOL_GPL vmlinux 0xe5940540 sk_clone +EXPORT_SYMBOL_GPL vmlinux 0xe5d2403e debugfs_create_u8 +EXPORT_SYMBOL_GPL vmlinux 0xe5f12c16 dequeue_signal +EXPORT_SYMBOL_GPL vmlinux 0xe690dbd0 vfs_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0xe7096692 __ip_route_output_key +EXPORT_SYMBOL_GPL vmlinux 0xe811ea07 scsi_flush_work +EXPORT_SYMBOL_GPL vmlinux 0xe81d98e0 input_class +EXPORT_SYMBOL_GPL vmlinux 0xe84e078d get_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0xe8c004bf uart_set_options +EXPORT_SYMBOL_GPL vmlinux 0xe93e49c3 devres_free +EXPORT_SYMBOL_GPL vmlinux 0xe9587909 usb_unregister_notify +EXPORT_SYMBOL_GPL vmlinux 0xea509a94 bus_create_file +EXPORT_SYMBOL_GPL vmlinux 0xea8fdfbb simple_attr_release +EXPORT_SYMBOL_GPL vmlinux 0xeae74760 scsi_nl_send_transport_msg +EXPORT_SYMBOL_GPL vmlinux 0xeb3c96f0 blk_end_bidi_request +EXPORT_SYMBOL_GPL vmlinux 0xec15a0f7 generic_fh_to_dentry +EXPORT_SYMBOL_GPL vmlinux 0xec9fd929 devres_find +EXPORT_SYMBOL_GPL vmlinux 0xee1ad2cf skb_icv_walk +EXPORT_SYMBOL_GPL vmlinux 0xee3cbef2 queue_delayed_work +EXPORT_SYMBOL_GPL vmlinux 0xee63a30a usb_kill_urb +EXPORT_SYMBOL_GPL vmlinux 0xeec6cd79 vfs_cancel_lock +EXPORT_SYMBOL_GPL vmlinux 0xef0e1880 __inet_inherit_port +EXPORT_SYMBOL_GPL vmlinux 0xef4e963e __atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xef6c3f70 round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xef82fdba srcu_init_notifier_head +EXPORT_SYMBOL_GPL vmlinux 0xef8efb24 ip_build_and_send_pkt +EXPORT_SYMBOL_GPL vmlinux 0xefe21106 snmp_mib_init +EXPORT_SYMBOL_GPL vmlinux 0xf00794fc usb_lock_device_for_reset +EXPORT_SYMBOL_GPL vmlinux 0xf0f9a196 inet_ctl_sock_create +EXPORT_SYMBOL_GPL vmlinux 0xf12a116c usb_init_urb +EXPORT_SYMBOL_GPL vmlinux 0xf1463412 execute_in_process_context +EXPORT_SYMBOL_GPL vmlinux 0xf184d189 kernel_power_off +EXPORT_SYMBOL_GPL vmlinux 0xf2762268 pci_disable_rom +EXPORT_SYMBOL_GPL vmlinux 0xf2fca922 uart_parse_options +EXPORT_SYMBOL_GPL vmlinux 0xf499fdb2 rcu_barrier_bh +EXPORT_SYMBOL_GPL vmlinux 0xf4d0aa2a usb_driver_set_configuration +EXPORT_SYMBOL_GPL vmlinux 0xf53cfe2b klist_node_attached +EXPORT_SYMBOL_GPL vmlinux 0xf5643b35 usb_store_new_id +EXPORT_SYMBOL_GPL vmlinux 0xf568a7a2 raw_unhash_sk +EXPORT_SYMBOL_GPL vmlinux 0xf5a691cd invalidate_bh_lrus +EXPORT_SYMBOL_GPL vmlinux 0xf5fa7468 transport_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0xf6df5a08 device_create +EXPORT_SYMBOL_GPL vmlinux 0xf7763d3f __scsi_get_command +EXPORT_SYMBOL_GPL vmlinux 0xf7bece86 inet6_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0xf7e1ef34 scsi_internal_device_unblock +EXPORT_SYMBOL_GPL vmlinux 0xf80e1489 sysfs_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xf84e5142 devm_kzalloc +EXPORT_SYMBOL_GPL vmlinux 0xf863e82a flush_work +EXPORT_SYMBOL_GPL vmlinux 0xf88ef481 sysfs_create_group +EXPORT_SYMBOL_GPL vmlinux 0xf8df5f51 usb_ep0_reinit +EXPORT_SYMBOL_GPL vmlinux 0xf92b2105 inet_hash +EXPORT_SYMBOL_GPL vmlinux 0xf99c2580 tcp_reno_cong_avoid +EXPORT_SYMBOL_GPL vmlinux 0xf9a054b5 __round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0xf9e12484 pci_unblock_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0xfa522d80 usb_alloc_urb +EXPORT_SYMBOL_GPL vmlinux 0xfa6dd51a platform_device_register +EXPORT_SYMBOL_GPL vmlinux 0xfaa75b02 sysfs_remove_file_from_group +EXPORT_SYMBOL_GPL vmlinux 0xfadff492 input_ff_destroy +EXPORT_SYMBOL_GPL vmlinux 0xfb44bb46 mnt_want_write +EXPORT_SYMBOL_GPL vmlinux 0xfb50d1ef apply_to_page_range +EXPORT_SYMBOL_GPL vmlinux 0xfbb87044 deregister_mtd_blktrans +EXPORT_SYMBOL_GPL vmlinux 0xfbf9be5d register_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xfc579296 sysfs_create_link +EXPORT_SYMBOL_GPL vmlinux 0xfccc2def inet_csk_listen_start +EXPORT_SYMBOL_GPL vmlinux 0xfdefc046 usb_unpoison_urb +EXPORT_SYMBOL_GPL vmlinux 0xfdf9d1b7 debugfs_create_x32 +EXPORT_SYMBOL_GPL vmlinux 0xfe41c9ff tty_mode_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xfeabc459 pci_set_pcie_reset_state +EXPORT_SYMBOL_GPL vmlinux 0xfeabebde put_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0xfed70beb pci_intx +EXPORT_SYMBOL_GPL vmlinux 0xff031a45 net_assign_generic +EXPORT_SYMBOL_GPL vmlinux 0xffaf7bbb __wake_up_sync --- linux-2.6.28.orig/debian/abi/2.6.28-11.41/armel/ixp4xx.modules +++ linux-2.6.28/debian/abi/2.6.28-11.41/armel/ixp4xx.modules @@ -0,0 +1,755 @@ +8021q +9pnet +act200l-sir +act_gact +act_ipt +actisys-sir +act_mirred +act_nat +act_pedit +act_police +act_simple +act_skbedit +ad7414 +ad7418 +adm1021 +adm1025 +adm1026 +adm1029 +adm1031 +adm9240 +ads7828 +adt7462 +adt7470 +adt7473 +adutux +aead +aes_generic +af_key +ah4 +ah6 +aircable +anubis +appledisplay +appletalk +arc4 +ark3116 +arptable_filter +arp_tables +arpt_mangle +as-iosched +asix +async_memcpy +async_tx +async_xor +atkbd +atxp1 +authenc +backlight +bcm203x +belkin_sa +berry_charge +bfusb +binfmt_aout +binfmt_misc +blowfish +bluetooth +bnep +bonding +bpa10x +bridge +broadcom +bsd_comp +btusb +camellia +cast5 +cast6 +catc +cbc +ccm +cdc-acm +cdc_ether +cdc_subset +cdc-wdm +cfg80211 +ch341 +chainiv +cicada +cifs +cls_basic +cls_flow +cls_fw +cls_route +cls_rsvp +cls_rsvp6 +cls_tcindex +cls_u32 +cn +compcache +configfs +cp2101 +cramfs +crc16 +crc32c +crc-ccitt +crc-itu-t +crc-t10dif +crypto_algapi +crypto_blkcipher +crypto_hash +cryptoloop +cryptomgr +crypto_null +ctr +cts +cyberjack +cypress_cy7c63 +cypress_m8 +cytherm +davicom +dccp +dccp_ccid2 +dccp_ccid3 +dccp_diag +dccp_ipv4 +dccp_ipv6 +dccp_tfrc_lib +deadline-iosched +decnet +deflate +des_generic +digi_acceleport +dlm +dm9601 +dm-crypt +dm-delay +dme1737 +dm-log +dm-mirror +dm-mod +dm-multipath +dm-region-hash +dm-round-robin +dm-snapshot +dm-zero +ds1621 +ds2482 +ds2490 +dummy +ebt_802_3 +ebtable_broute +ebtable_filter +ebtable_nat +ebtables +ebt_among +ebt_arp +ebt_arpreply +ebt_dnat +ebt_ip +ebt_ip6 +ebt_limit +ebt_log +ebt_mark +ebt_mark_m +ebt_nflog +ebt_pkttype +ebt_redirect +ebt_snat +ebt_stp +ebt_ulog +ebt_vlan +ecb +econet +eeprom +em_cmp +emi26 +emi62 +em_meta +em_nbyte +empeg +em_text +em_u32 +eql +eseqiv +esi-sir +esp4 +esp6 +evdev +exportfs +ext4 +f71805f +f71882fg +f75375s +fat +fcrypt +ff-memless +font +ftdi-elan +ftdi_sio +funsoft +gadgetfs +garmin_gps +g_cdc +gcm +g_ether +gf128mul +g_file_storage +girbil-sir +gl518sm +gl520sm +gl620a +g_midi +gpio +g_printer +g_serial +g_zero +hci_uart +hci_vhci +hid +hid-a4tech +hid-apple +hid-belkin +hid-bright +hid-cherry +hid-chicony +hid-cypress +hid-dell +hid-ezkey +hid-gyration +hid-logitech +hid-microsoft +hid-monterey +hidp +hid-petalynx +hid-pl +hid-samsung +hid-sony +hid-sunplus +hid-tmff +hid-zpff +hmac +hp4x +hso +hwmon +hwmon-vid +i2c-algo-bit +i2c-core +i2c-dev +i2c-gpio +i2c-iop3xx +i5k_amb +icplus +idmouse +ifb +inet_diag +inet_lro +io_edgeport +io_ti +iowarrior +ip6table_filter +ip6table_mangle +ip6table_raw +ip6_tables +ip6t_ah +ip6t_eui64 +ip6t_frag +ip6t_hbh +ip6t_hl +ip6t_HL +ip6t_ipv6header +ip6t_LOG +ip6t_mh +ip6t_REJECT +ip6t_rt +ipaq +ipcomp +ipcomp6 +ipddp +ip_gre +ipip +iptable_filter +iptable_mangle +iptable_nat +iptable_raw +ip_tables +ipt_addrtype +ipt_ah +ipt_CLUSTERIP +ipt_ecn +ipt_ECN +ipt_LOG +ipt_MASQUERADE +ipt_NETMAP +ipt_REDIRECT +ipt_REJECT +ipt_ttl +ipt_TTL +ipt_ULOG +ipv6 +ip_vs +ip_vs_dh +ip_vs_ftp +ip_vs_lblc +ip_vs_lblcr +ip_vs_lc +ip_vs_nq +ip_vs_rr +ip_vs_sed +ip_vs_sh +ip_vs_wlc +ip_vs_wrr +ipw +ipx +ircomm +ircomm-tty +irda +irda-usb +irlan +irnet +irtty-sir +ir-usb +isight_firmware +isofs +it87 +iuu_phoenix +ixp4xx_crypto +ixp4xx-rng +jbd2 +jffs2 +jfs +kaweth +keyspan +keyspan_pda +khazad +kingsun-sir +kl5kusb105 +kobil_sct +krng +ks959-sir +ksdazzle-sir +l2cap +lapb +lcd +ldusb +led-class +leds-fsg +leds-gpio +legousbtower +libcrc32c +libphy +libps2 +libsas +linear +litelink-sir +llc +llc2 +lm63 +lm75 +lm77 +lm78 +lm80 +lm83 +lm85 +lm87 +lm90 +lm92 +lm93 +lockd +loop +lrw +lxt +lzo +lzo_compress +lzo_decompress +ma600-sir +mac80211 +macvlan +map_ram +marvell +matrox_w1 +max1619 +max6650 +max6875 +mcp2120-sir +mcs7780 +mcs7830 +mct_u232 +md4 +md5 +mdc800 +mdio-bitbang +md-mod +michael_mic +microtek +mmc_block +mmc_core +mos7720 +mos7840 +moto_modem +msdos +mtdoops +multipath +nand +nand_ecc +nand_ids +navman +nbd +net1080 +netconsole +nf_conntrack +nf_conntrack_amanda +nf_conntrack_ftp +nf_conntrack_h323 +nf_conntrack_ipv4 +nf_conntrack_ipv6 +nf_conntrack_irc +nf_conntrack_netbios_ns +nf_conntrack_netlink +nf_conntrack_pptp +nf_conntrack_proto_dccp +nf_conntrack_proto_gre +nf_conntrack_proto_sctp +nf_conntrack_proto_udplite +nf_conntrack_sane +nf_conntrack_sip +nf_conntrack_tftp +nf_defrag_ipv4 +nf_nat +nf_nat_amanda +nf_nat_ftp +nf_nat_h323 +nf_nat_irc +nf_nat_pptp +nf_nat_proto_dccp +nf_nat_proto_gre +nf_nat_proto_sctp +nf_nat_proto_udplite +nf_nat_sip +nf_nat_snmp_basic +nf_nat_tftp +nfnetlink +nfnetlink_log +nfnetlink_queue +nfs +nfsd +nf_tproxy_core +nls_ascii +nls_base +nls_cp1250 +nls_cp1251 +nls_cp1255 +nls_cp437 +nls_cp737 +nls_cp775 +nls_cp850 +nls_cp852 +nls_cp855 +nls_cp857 +nls_cp860 +nls_cp861 +nls_cp862 +nls_cp863 +nls_cp864 +nls_cp865 +nls_cp866 +nls_cp869 +nls_cp874 +nls_cp932 +nls_cp936 +nls_cp949 +nls_cp950 +nls_euc-jp +nls_iso8859-1 +nls_iso8859-13 +nls_iso8859-14 +nls_iso8859-15 +nls_iso8859-2 +nls_iso8859-3 +nls_iso8859-4 +nls_iso8859-5 +nls_iso8859-6 +nls_iso8859-7 +nls_iso8859-9 +nls_koi8-r +nls_koi8-ru +nls_koi8-u +nls_utf8 +nozomi +ntfs +old_belkin-sir +omninet +option +oti6858 +p8022 +p8023 +pc87360 +pc87427 +pca9539 +pcbc +pcf8574 +pcf8591 +pegasus +phidget +phidgetkit +phidgetmotorcontrol +phidgetservo +phonet +pktgen +pl2303 +platform_lcd +plusb +pn_pep +ppp_async +ppp_deflate +ppp_generic +ppp_mppe +pppoe +pppol2tp +pppox +ppp_synctty +psnap +pxa25x_udc +qsemi +raid0 +raid1 +raid10 +raid456 +raid_class +realtek +reiserfs +rfcomm +rfkill +rfkill-input +rio500 +rmd128 +rmd160 +rmd256 +rmd320 +rndis_host +rng +rng-core +rtc-bq4802 +rtc-core +rtc-ds1286 +rtc-ds1307 +rtc-ds1374 +rtc-ds1511 +rtc-ds1553 +rtc-ds1672 +rtc-ds1742 +rtc-fm3130 +rtc-isl1208 +rtc-m41t80 +rtc-m48t35 +rtc-m48t59 +rtc-m48t86 +rtc-max6900 +rtc-pcf8563 +rtc-pcf8583 +rtc-rs5c372 +rtc-rx8581 +rtc-s35390a +rtc-stk17ta8 +rtc-v3020 +rtc-x1205 +rtl8150 +safe_serial +salsa20_generic +sch_cbq +sch_dsmark +sch_gred +sch_hfsc +sch_htb +sch_ingress +sch_multiq +sch_netem +sch_prio +sch_red +sch_sfq +sch_tbf +sch_teql +sco +scsi_tgt +scsi_transport_fc +scsi_transport_iscsi +scsi_transport_sas +scsi_transport_spi +scsi_wait_scan +sctp +sdhci +sdio_uart +seed +seqiv +serio +serpent +serport +sha1_generic +sha256_generic +sha512_generic +sierra +sir-dev +sis5595 +sisusbvga +sit +slhc +slip +smsc +smsc47b397 +smsc47m1 +smsc47m192 +smsc95xx +snd +snd-dummy +snd-hwdep +snd-mixer-oss +snd-mpu401 +snd-mpu401-uart +snd-mtpav +snd-page-alloc +snd-pcm +snd-pcm-oss +snd-rawmidi +snd-seq +snd-seq-device +snd-seq-dummy +snd-seq-midi +snd-seq-midi-event +snd-seq-oss +snd-seq-virmidi +snd-serial-u16550 +snd-timer +snd-usb-audio +snd-usb-caiaq +snd-usb-lib +snd-virmidi +soundcore +spcp8x5 +stir4200 +stp +sunrpc +tcp_diag +tea +tekram-sir +tgr192 +thmc50 +tifm_core +tifm_sd +ti_usb_3410_5052 +tlsf +toim3232-sir +trancevibrator +ts_bm +ts_fsm +ts_kmp +tsl2550 +tun +tunnel4 +tunnel6 +twofish +twofish_common +ubi +ubifs +udf +uhci-hcd +uinput +usb_debug +usbhid +usblcd +usbled +usblp +usbnet +usbserial +usbsevseg +usbtest +usbtmc +veth +vfat +via686a +visor +vitesse +vlsi_ir +vstusb +vt1211 +vt8231 +w1_bq27000 +w1_ds2433 +w1_ds2760 +w1-gpio +w1_smem +w1_therm +w83627ehf +w83627hf +w83781d +w83791d +w83792d +w83793 +w83l785ts +w83l786ng +wanrouter +whiteheat +wire +wp512 +x25 +xcbc +xfrm4_mode_beet +xfrm4_mode_transport +xfrm4_mode_tunnel +xfrm4_tunnel +xfrm6_mode_beet +xfrm6_mode_transport +xfrm6_mode_tunnel +xfrm6_tunnel +xfrm_ipcomp +xfrm_user +xfs +xor +x_tables +xt_CLASSIFY +xt_comment +xt_connbytes +xt_connlimit +xt_connmark +xt_CONNMARK +xt_conntrack +xt_dccp +xt_dscp +xt_DSCP +xt_esp +xt_hashlimit +xt_helper +xt_iprange +xt_length +xt_limit +xt_mac +xt_mark +xt_MARK +xt_multiport +xt_NFLOG +xt_NFQUEUE +xt_NOTRACK +xt_owner +xt_physdev +xt_pkttype +xt_policy +xt_quota +xt_rateest +xt_RATEEST +xt_realm +xt_recent +xts +xt_sctp +xt_socket +xt_state +xt_statistic +xt_string +xt_tcpmss +xt_TCPMSS +xt_TCPOPTSTRIP +xt_tcpudp +xt_time +xt_TPROXY +xt_TRACE +xt_u32 +zaurus +zlib_deflate +zlib_inflate --- linux-2.6.28.orig/debian/abi/2.6.28-11.41/lpia/lpia.modules +++ linux-2.6.28/debian/abi/2.6.28-11.41/lpia/lpia.modules @@ -0,0 +1,1999 @@ +3c359 +3c501 +3c503 +3c505 +3c507 +3c509 +3c515 +3c523 +3c527 +3c574_cs +3c589_cs +3c59x +3w-9xxx +3w-xxxx +53c700 +8021q +8139cp +8139too +8250_accent +8250_boca +8250_exar_st16c554 +8250_fourport +8250_hub6 +8250_mca +82596 +8390 +8390p +a100u2w +a3d +aacraid +abituguru +abituguru3 +abyss +ac +ac3200 +ac97_bus +acecad +acenic +acerhk +acpiphp +acpiphp_ibm +acquirewdt +act200l-sir +act_gact +act_ipt +actisys-sir +act_mirred +act_nat +act_pedit +act_police +act_simple +acx +ad7414 +ad7418 +adcxx +adfs +adi +adm1021 +adm1025 +adm1026 +adm1029 +adm1031 +adm8211 +adm9240 +ads7828 +ads7846 +adt7470 +adt7473 +adutux +adv7170 +adv7175 +advansys +advantechwdt +aes_generic +aes-i586 +affs +af_key +af-rxrpc +agpgart +ah4 +ah6 +aha152x +aha152x_cs +aha1542 +aha1740 +ahci +aic79xx +aic7xxx +aic94xx +aiptek +aircable +airo +airo_cs +alauda +ali-agp +ali-ircc +alim1535_wdt +alim7101_wdt +amd64-agp +amd76x_edac +amd76xrom +amd8111e +amd-k7-agp +amd-rng +analog +anubis +aoe +appledisplay +appleir +applesmc +appletouch +applicom +ar7part +arc4 +arcfb +arcmsr +arcnet +arc-rawmode +arc-rimi +ark3116 +arkfb +arlan +arptable_filter +arp_tables +arpt_mangle +asb100 +asix +asus-laptop +async_memcpy +async_tx +async_xor +at1700 +at24 +at25 +aten +ath9k +ati-agp +ati_remote +ati_remote2 +atl1 +atl1e +atl2 +atlas_btns +atmel +atmel_cs +atmel_pci +atp +atp870u +atxp1 +aty128fb +atyfb +au0828 +au8522 +aufs +authenc +auth_rpcgss +autofs +autofs4 +av5100 +axnet_cs +b2c2-flexcop +b2c2-flexcop-pci +b2c2-flexcop-usb +b43 +b43legacy +b44 +battery +bcm203x +bcm3510 +bcm5974 +befs +belkin_sa +berry_charge +bfs +bfusb +binfmt_aout +binfmt_misc +bitblit +block2mtd +blowfish +bluecard_cs +bluetooth +bnep +bnx2 +bnx2x +bonding +bpa10x +bpck +bpck6 +bridge +broadcom +bsd_comp +bt3c_cs +bt819 +bt856 +bt878 +btcx-risc +btsdio +bttv +btuart_cs +btusb +budget +budget-av +budget-ci +budget-core +budget-patch +BusLogic +button +bw-qcam +c67x00 +cafe_ccic +cafe_nand +camellia +capmode +carminefb +cassini +cast5 +cast6 +catc +cbc +cciss +ccm +cdc-acm +cdc_ether +cdc_subset +cdc-wdm +cfag12864b +cfag12864bfb +cfg80211 +cfi_cmdset_0001 +cfi_cmdset_0002 +cfi_cmdset_0020 +cfi_probe +cfi_util +ch +ch341 +chipreg +cicada +cifs +cirrusfb +ck804xrom +cls_basic +cls_fw +cls_route +cls_rsvp +cls_rsvp6 +cls_tcindex +cls_u32 +cm4000_cs +cm4040_cs +cn +cobra +coda +com20020 +com20020_cs +com20020-isa +com20020-pci +com90io +com90xx +comm +commandir +compal-laptop +compat_ioctl32 +compcache +configfs +coretemp +corgi_bl +cp2101 +cpcihp_generic +cpcihp_zt5550 +cpia +cpia2 +cpia_pp +cpia_usb +cpqarray +cpqphp +cpu5wdt +cpufreq_conservative +cpufreq_powersave +cpufreq_stats +cpufreq_userspace +cpuid +c-qcam +cr_bllcd +crc32c +crc7 +crc-ccitt +crc-itu-t +crc-t10dif +crvml +cryptd +cryptoloop +crypto_null +cs5345 +cs53l32a +cs5535_gpio +cs553x_nand +cs89x0 +ct82c710 +ctr +cts +cx18 +cx22700 +cx22702 +cx2341x +cx23885 +cx24110 +cx24116 +cx24123 +cx25840 +cx8800 +cx8802 +cx88-alsa +cx88-blackbird +cx88-dvb +cx88-vp3054-i2c +cx88xx +cxgb +cxgb3 +cyber2000fb +cyberjack +cyblafb +cyclades +cypress_cy7c63 +cypress_m8 +cytherm +DAC960 +davicom +db9 +dc395x +dca +dccp +dccp_ccid2 +dccp_ccid3 +dccp_diag +dccp_ipv4 +dccp_ipv6 +dccp_probe +dccp_tfrc_lib +dcdbas +de2104x +de4x5 +de600 +de620 +deflate +dell_rbu +depca +des_generic +dib0070 +dib3000mb +dib3000mc +dib7000m +dib7000p +dibx000_common +digi_acceleport +dilnetpc +diskonchip +display +dlm +dm9601 +dm-bbr +dm-crypt +dme1737 +dmfe +dm-log +dm-loop +dm-mem-cache +dm-message +dm-mirror +dm-mod +dm-multipath +dm-raid4-5 +dm-region_hash +dm-region-hash +dm-round-robin +dm-snapshot +dmx3191d +dm-zero +doc2000 +doc2001 +doc2001plus +docecc +docprobe +donauboe +dpt_i2o +drbd +drm +drx397xD +ds1621 +ds1682 +ds2482 +ds2490 +ds2760_battery +dsbr100 +dst +dst_ca +dstr +dtc +dtl1_cs +dtlk +dummy +dummy_hcd +dv1394 +dvb-bt8xx +dvb-core +dvb-pll +dvb-ttpci +dvb-ttusb-budget +dvb-usb +dvb-usb-a800 +dvb-usb-af9005 +dvb-usb-af9005-remote +dvb-usb-anysee +dvb-usb-au6610 +dvb-usb-cxusb +dvb-usb-dib0700 +dvb-usb-dibusb-common +dvb-usb-dibusb-mb +dvb-usb-dibusb-mc +dvb-usb-digitv +dvb-usb-dtt200u +dvb-usb-dw2102 +dvb-usb-gl861 +dvb-usb-gp8psk +dvb-usb-m920x +dvb-usb-nova-t-usb2 +dvb-usb-opera +dvb-usb-ttusb2 +dvb-usb-umt-010 +dvb-usb-vp702x +dvb-usb-vp7045 +e100 +e1000 +e1000e +e2100 +e752x_edac +e7xxx_edac +eata +ebt_802_3 +ebtable_broute +ebtable_filter +ebtable_nat +ebtables +ebt_among +ebt_arp +ebt_arpreply +ebt_dnat +ebt_ip +ebt_ip6 +ebt_limit +ebt_log +ebt_mark +ebt_mark_m +ebt_nflog +ebt_pkttype +ebt_redirect +ebt_snat +ebt_stp +ebt_ulog +ebt_vlan +ecb +ecryptfs +edac_core +eeepc-laptop +eepro +eepro100 +eeprom +eeprom_93cx6 +eexpress +efficeon-agp +efs +ehci-hcd +elo +em28xx +em28xx-alsa +em28xx-dvb +em_cmp +emi26 +emi62 +em_meta +em_nbyte +empeg +em_text +emu10k1-gp +em_u32 +enclosure +epat +epca +epia +epic100 +eql +es3210 +esb2rom +esi-sir +esp +esp4 +esp6 +et131x +et61x251 +eth1394 +eth16i +eurotechwdt +evbug +evdev +ewrk3 +exportfs +f71805f +f71882fg +f75375s +fakephp +fan +fat +faulty +fbcon +fb_ddc +fb_sys_fops +fcrypt +fd_mcs +fdomain +fdomain_cs +fealnx +ff-memless +fit2 +fit3 +floppy +fm801-gp +fmvj18x_cs +font +forcedeth +freevxfs +friq +frpw +fsam7400 +fscher +fschmd +fscpos +ftdi-elan +ftdi_sio +ftl +fujitsu-laptop +fujitsu_ts +funsoft +g450_pll +gadgetfs +gamecon +gameport +garmin_gps +g_cdc +gcm +gdth +generic_serial +gen_probe +geode-aes +geode-rng +g_ether +gf128mul +gf2k +g_file_storage +gfs2 +girbil-sir +gl518sm +gl520sm +gl620a +g_NCR5380 +g_NCR5380_mmio +grip +grip_mp +g_serial +gspca_main +gtco +guillemot +gunze +gx1fb +gxfb +g_zero +hamachi +hangcheck-timer +hci_uart +hci_vhci +hdaps +hdlc +hdlc_cisco +hdlc_fr +hdlc_ppp +hdlc_raw +hdlc_raw_eth +heci +hecubafb +hermes +hermes_dld +hexium_gemini +hexium_orion +hfs +hfsplus +hgafb +hid +hid-a4tech +hid-apple +hid-belkin +hid-bright +hid-cherry +hid-chicony +hid-cypress +hid-dell +hid-dummy +hid-ezkey +hid-gyration +hid-logitech +hid-microsoft +hid-monterey +hidp +hid-petalynx +hid-pl +hid-samsung +hid-sony +hid-sunplus +hifn_795x +hostap +hostap_cs +hostap_pci +hostap_plx +hp +hp100 +hp4x +hpfs +hpilo +hp-plus +hptiop +hso +htc-pasic3 +htcpen +hwmon-vid +i2c-algo-bit +i2c-algo-pca +i2c-ali1535 +i2c-ali1563 +i2c-ali15x3 +i2c-amd756 +i2c-amd756-s4882 +i2c-amd8111 +i2c-core +i2c-dev +i2c-i801 +i2c-isch +i2c-matroxfb +i2c-nforce2 +i2c-nforce2-s4985 +i2c-ocores +i2c-parport +i2c-parport-light +i2c-pca-isa +i2c-pca-platform +i2c-piix4 +i2c-simtec +i2c-sis5595 +i2c-sis630 +i2c-sis96x +i2c-stub +i2c-taos-evm +i2c-tiny-usb +i2c-via +i2c-viapro +i2c-voodoo3 +i2o_block +i2o_bus +i2o_config +i2o_core +i2o_proc +i2o_scsi +i3000_edac +i5000_edac +i5100_edac +i5k_amb +i6300esb +i810 +i810fb +i82092 +i82365 +i82860_edac +i82875p_edac +i82975x_edac +i830 +i8k +i915 +ib700wdt +ib_addr +ib_cm +ib_core +ib_ipoib +ib_iser +ib_mad +ibmaem +ibmasm +ibmasr +ibmcam +ibmlana +ibmmca +ibmpex +ibmphp +ib_mthca +ibmtr +ibmtr_cs +ib_sa +ib_srp +ib_ucm +ib_umad +ib_uverbs +ichxrom +icplus +idmouse +ieee1394 +ieee80211 +ieee80211_crypt +ieee80211_crypt_ccmp +ieee80211_crypt_tkip +ieee80211_crypt_wep +ifb +iforce +igb +ili9320 +imm +in2000 +inet_lro +inexio +inftl +initio +inport +input-polldev +intel-agp +intelfb +intel_menlow +intel-rng +intel_vr_nor +interact +ioatdma +ioc4 +io_edgeport +io_ti +iowarrior +ip2 +ip6_queue +ip6table_filter +ip6table_mangle +ip6table_raw +ip6_tables +ip6table_security +ip6t_ah +ip6t_eui64 +ip6t_frag +ip6t_hbh +ip6t_hl +ip6t_HL +ip6t_ipv6header +ip6t_LOG +ip6t_mh +ip6t_REJECT +ip6t_rt +ip6_tunnel +ipaq +ipcomp +ipcomp6 +ipg +ip_gre +ipip +ipmi_devintf +ipmi_msghandler +ipmi_poweroff +ipmi_si +ipmi_watchdog +ip_queue +ipr +ips +iptable_filter +iptable_mangle +iptable_nat +iptable_raw +ip_tables +iptable_security +ipt_addrtype +ipt_ah +ipt_CLUSTERIP +ipt_ecn +ipt_ECN +ipt_LOG +ipt_MASQUERADE +ipt_NETMAP +ipt_REDIRECT +ipt_REJECT +ipt_ttl +ipt_TTL +ipt_ULOG +ipv6 +ip_vs +ip_vs_dh +ip_vs_ftp +ip_vs_lblc +ip_vs_lblcr +ip_vs_lc +ip_vs_nq +ip_vs_rr +ip_vs_sed +ip_vs_sh +ip_vs_wlc +ip_vs_wrr +ipw +ipw2100 +ipw2200 +ircomm +ir-common +ircomm-tty +irda +irda-usb +ir-kbd-i2c +irlan +irnet +irtty-sir +iscsi_tcp +iscsi_trgt +isight_firmware +isl6405 +isl6421 +isofs +isp116x-hcd +isp1760 +it87 +it8712f_wdt +iTCO_vendor_support +iTCO_wdt +itd1000 +ivtv +ivtvfb +iw_c2 +iw_cm +iw_cxgb3 +iwl3945 +iwlagn +iwlcore +ixgb +ixgbe +ixj +ixj_pcmcia +jedec_probe +jffs2 +jfs +joydev +joydump +jsm +k8temp +kafs +kaweth +kbic +kbtab +keyspan +keyspan_pda +keyspan_remote +khazad +kingsun-sir +kl5kusb105 +kobil_sct +konicawc +ks0108 +ks0127 +ks959-sir +ksdazzle-sir +ktti +kvm +kvm-amd +kvm-intel +kyrofb +l2cap +l440gx +l64781 +lance +lanstreamer +lcd +ldusb +led-class +leds-net48xx +leds-pca9532 +leds-pca955x +leds-wrap +ledtrig-default-on +ledtrig-heartbeat +ledtrig-timer +legousbtower +lgdt330x +libcrc32c +libertas +libertas_cs +libertas_sdio +libiscsi +libphy +libsas +libsrp +libusual +lightning +linear +lirc_atiusb +lirc_bt829 +lirc_cmdir +lirc_dev +lirc_i2c +lirc_igorplugusb +lirc_imon +lirc_it87 +lirc_mceusb +lirc_mceusb2 +lirc_pvr150 +lirc_sasem +lirc_serial +lirc_serial_igor +lirc_sir +lirc_streamzap +lirc_ttusbir +litelink-sir +lkkbd +llc2 +lm63 +lm70 +lm75 +lm77 +lm78 +lm80 +lm83 +lm85 +lm87 +lm90 +lm92 +lm93 +lmpcm_usb +lnbp21 +lne390 +lockd +lock_dlm +logibm +loop +lp +lp486e +lpfc +lrw +ltv350qv +lxfb +lxt +lzo +lzo_compress +lzo_decompress +m25p80 +m52790 +ma600-sir +mac80211 +machzwd +macmodes +macvlan +madgemc +magellan +map_absent +map_funcs +map_ram +map_rom +marvell +matroxfb_accel +matroxfb_base +matroxfb_crtc2 +matroxfb_DAC1064 +matroxfb_g450 +matroxfb_maven +matroxfb_misc +matroxfb_Ti3026 +matrox_w1 +max1619 +max6650 +max6875 +mcp2120-sir +mcs7780 +mcs7830 +mct_u232 +md4 +mdacon +mdc800 +mdio-bitbang +md-mod +megaraid +megaraid_mbox +megaraid_mm +megaraid_sas +meye +mga +michael_mic +microcode +microtek +mii +minix +mixcomwd +mk712 +mlx4_core +mlx4_ib +mmc_block +mos7720 +mos7840 +moto_modem +moxa +mptbase +mptctl +mptfc +mptlan +mptsas +mptscsih +mptspi +msdos +msi-laptop +msp3400 +msr +mt2060 +mt20xx +mt2131 +mt2266 +mt312 +mt352 +mt9m001 +mt9v022 +mtd +mtd_blkdevs +mtdblock +mtdblock_ro +mtdchar +mtdconcat +mtd_dataflash +mtdoops +mtdram +mtouch +multipath +mwave +mxb +mxl5005s +mxl5007t +mxser +myri10ge +nand +nand_ecc +nand_ids +nandsim +natsemi +navman +nbd +ncpfs +NCR53c406a +NCR_D700 +NCR_Q720_mod +ndiswrapper +ne +ne2 +ne2k-pci +ne3210 +neofb +net1080 +netconsole +netsc520 +nettel +netwave_cs +netxen_nic +newtonkbd +nf_conntrack +nf_conntrack_amanda +nf_conntrack_ftp +nf_conntrack_h323 +nf_conntrack_ipv4 +nf_conntrack_ipv6 +nf_conntrack_irc +nf_conntrack_netbios_ns +nf_conntrack_netlink +nf_conntrack_pptp +nf_conntrack_proto_gre +nf_conntrack_proto_sctp +nf_conntrack_proto_udplite +nf_conntrack_sip +nf_conntrack_tftp +nf_defrag_ipv4 +nf_nat +nf_nat_amanda +nf_nat_ftp +nf_nat_h323 +nf_nat_irc +nf_nat_pptp +nf_nat_proto_gre +nf_nat_proto_sctp +nf_nat_proto_udplite +nf_nat_sip +nf_nat_snmp_basic +nf_nat_tftp +nfnetlink +nfnetlink_log +nfnetlink_queue +nfs +nfs_acl +nfsd +nftl +nf_tproxy_core +n_hdlc +ni52 +ni65 +niu +nls_ascii +nls_cp1250 +nls_cp1251 +nls_cp1255 +nls_cp437 +nls_cp737 +nls_cp775 +nls_cp850 +nls_cp852 +nls_cp855 +nls_cp857 +nls_cp860 +nls_cp861 +nls_cp862 +nls_cp863 +nls_cp864 +nls_cp865 +nls_cp866 +nls_cp869 +nls_cp874 +nls_cp932 +nls_cp936 +nls_cp949 +nls_cp950 +nls_euc-jp +nls_iso8859-1 +nls_iso8859-13 +nls_iso8859-14 +nls_iso8859-15 +nls_iso8859-2 +nls_iso8859-3 +nls_iso8859-4 +nls_iso8859-5 +nls_iso8859-6 +nls_iso8859-7 +nls_iso8859-9 +nls_koi8-r +nls_koi8-ru +nls_koi8-u +nls_utf8 +nmclan_cs +nozomi +n_r3964 +ns558 +ns83820 +nsc_gpio +nsc-ircc +nsp32 +nsp_cs +ntfs +nvidia-agp +nvidiafb +nvram +nxt200x +nxt6000 +ocfs2 +ocfs2_dlm +ocfs2_dlmfs +ocfs2_nodemanager +ocfs2_stackglue +ocfs2_stack_o2cb +ocfs2_stack_user +ohci1394 +ohci-hcd +old_belkin-sir +olpc_battery +olympic +omfs +omninet +on20 +on26 +onenand +onenand_sim +oprofile +option +or51132 +or51211 +orinoco +orinoco_cs +orinoco_nortel +orinoco_pci +orinoco_plx +orinoco_tmd +osst +oti6858 +output +ov511 +ov511_decomp +ov518_decomp +ov7670 +ovcamchip +p4-clockmod +p54common +p54pci +p54usb +p80211 +padlock-aes +padlock-sha +paride +parkbd +parport +parport_ax88796 +parport_cs +parport_pc +parport_serial +pas16 +pata_cmd640 +pata_cs5535 +pata_cypress +pata_hpt37x +pata_it8213 +pata_legacy +pata_ninja32 +pata_oldpiix +pata_pcmcia +pata_platform +pata_radisys +pbe5 +pc110pad +pc87360 +pc8736x_gpio +pc87413_wdt +pc87427 +pca9539 +pcbc +pcd +pcf8574 +pcf8575 +pcf8591 +pci +pciehp +pci_hotplug +pcilynx +pcips2 +pci_slot +pcmcia +pcmcia_core +pcnet32 +pcnet_cs +pcwd +pcwd_pci +pcwd_usb +pd +pd6729 +pda_power +pegasus +penmount +pf +pg +phantom +phidget +phidgetkit +phidgetmotorcontrol +phidgetservo +phonedev +phram +physmap +pktcdvd +pktgen +pl2303 +platform_lcd +plat_nand +plat-ram +plip +plusb +pluto2 +pm2fb +pm3fb +pmc551 +pms +powermate +ppa +ppdev +ppp_async +ppp_deflate +ppp_generic +ppp_mppe +pppoe +pppol2tp +pppox +ppp_synctty +prism2_usb +prism54 +progear_bl +proteon +psmouse +pt +pvrusb2 +pwc +qla1280 +qla2xxx +qla3xxx +qla4xxx +qlogic_cs +qlogicfas +qlogicfas408 +qnx4 +qsemi +qt1010 +quickcam +quickcam_messenger +quota_v1 +quota_v2 +r128 +r8169 +r82600_edac +r8a66597-hcd +radeon +radeonfb +radio-aimslab +radio-aztech +radio-cadet +radio-gemtek +radio-gemtek-pci +radio-maestro +radio-maxiradio +radio-rtrack2 +radio-sf16fmi +radio-sf16fmr2 +radio-si470x +radio-terratec +radio-trust +radio-typhoon +radio-zoltrix +raid0 +raid1 +raid10 +raid456 +raid_class +raw +raw1394 +ray_cs +rdma_cm +rdma_ucm +redboot +reed_solomon +reiserfs +rfc1051 +rfc1201 +rfcomm +rfd_ftl +rfkill +rfkill-input +ricoh_mmc +rio +rio500 +riscom8 +rivafb +rmd128 +rmd160 +rmd256 +rmd320 +rndis_host +rndis_wlan +rocket +romfs +rpcsec_gss_krb5 +rpcsec_gss_spkm3 +rsrc_nonstatic +rt2400pci +rt2500pci +rt2500usb +rt2x00lib +rt2x00pci +rt2x00usb +rt61pci +rt73usb +rtc-ds1305 +rtc-ds1307 +rtc-ds1374 +rtc-ds1553 +rtc-ds1672 +rtc-ds1742 +rtc-fm3130 +rtc-isl1208 +rtc-m41t80 +rtc-m41t94 +rtc-m48t59 +rtc-m48t86 +rtc-max6900 +rtc-max6902 +rtc-pcf8563 +rtc-pcf8583 +rtc-rs5c348 +rtc-rs5c372 +rtc-stk17ta8 +rtc-test +rtc-v3020 +rtc-x1205 +rtl8150 +rtl8180 +rtl8187 +rxkad +s1d13xxxfb +s2255drv +s2io +s3fb +s5h1409 +s5h1411 +s5h1420 +saa5246a +saa5249 +saa6588 +saa6752hs +saa7110 +saa7111 +saa7114 +saa7115 +saa7127 +saa7134 +saa7134-alsa +saa7134-dvb +saa7134-empress +saa7146 +saa7146_vv +saa717x +saa7185 +safe_serial +salsa20_generic +salsa20-i586 +sata_mv +sata_sil24 +sata_sx4 +savage +savagefb +sb1000 +sbc60xxwdt +sbc7240_wdt +sbc8360 +sbc_epx_c3 +sbc_gxx +sbp2 +sbs +sbshc +sc1200wdt +sc520cdp +sc520_wdt +sc92031 +scb2_flash +sch_cbq +sch_dsmark +sch_gred +sch_hfsc +sch_htb +sch_ingress +sch_netem +sch_prio +sch_red +sch_sfq +sch_tbf +sch_teql +sco +scsi_debug +scsi_tgt +scsi_transport_fc +scsi_transport_iscsi +scsi_transport_sas +scsi_transport_spi +scsi_transport_srp +scsi_wait_scan +sctp +scx200 +scx200_acb +scx200_docflash +scx200_gpio +scx200_hrt +scx200_i2c +scx200_wdt +sdhci +sdhci-pci +sdio_uart +sdricoh_cs +se401 +seed +seeq8005 +seqiv +serial_cs +serio_raw +sermouse +serpent +serport +ses +sfc +sg +sha1_generic +sha256_generic +sha512_generic +shpchp +si21xx +sidewinder +sierra +sim710 +sir-dev +sis +sis190 +sis5595 +sis900 +sis-agp +sisfb +sisusbvga +sit +skge +skisa +sky2 +sl811_cs +sl811-hcd +slhc +slip +slram +sm501 +sm501fb +smbfs +smc9194 +smc91c92_cs +smc-mca +smctr +smc-ultra +smc-ultra32 +sms1xxx +smsc +smsc37b787_wdt +smsc47b397 +smsc47m1 +smsc47m192 +smsc-ircc2 +sn9c102 +snd +snd-ac97-codec +snd-ad1889 +snd-ak4114 +snd-ak4xxx-adda +snd-ali5451 +snd-als300 +snd-als4000 +snd-atiixp +snd-atiixp-modem +snd-au8810 +snd-au8820 +snd-au8830 +snd-aw2 +snd-azt3328 +snd-bt87x +snd-ca0106 +snd-cmipci +snd-cs4281 +snd-cs46xx +snd-cs5530 +snd-cs5535audio +snd-cs8427 +snd-darla20 +snd-darla24 +snd-dummy +snd-echo3g +snd-emu10k1 +snd-emu10k1-synth +snd-emu10k1x +snd-emux-synth +snd-ens1370 +snd-ens1371 +snd-es1938 +snd-es1968 +snd-fm801 +snd-gina20 +snd-gina24 +snd-hda-intel +snd-hdsp +snd-hdspm +snd-hifier +snd-hwdep +snd-i2c +snd-ice1712 +snd-ice1724 +snd-ice17xx-ak4xxx +snd-indigo +snd-indigodj +snd-indigoio +snd-intel8x0 +snd-intel8x0m +snd-korg1212 +snd-layla20 +snd-layla24 +snd-maestro3 +snd-mia +snd-mixart +snd-mixer-oss +snd-mona +snd-mpu401 +snd-mpu401-uart +snd-mtpav +snd-mts64 +snd-nm256 +snd-opl3-lib +snd-opl3-synth +snd-oxygen +snd-oxygen-lib +snd-page-alloc +snd-pcm +snd-pcm-oss +snd-pcsp +snd-pcxhr +snd-portman2x4 +snd-pt2258 +snd-rawmidi +snd-riptide +snd-rme32 +snd-rme96 +snd-rme9652 +snd-sb16-dsp +snd-sb-common +snd-seq +snd-seq-device +snd-seq-dummy +snd-seq-midi +snd-seq-midi-emul +snd-seq-midi-event +snd-seq-oss +snd-seq-virmidi +snd-serial-u16550 +snd-sis7019 +snd-soc-core +snd-sonicvibes +snd-tea575x-tuner +snd-timer +snd-trident +snd-usb-audio +snd-usb-caiaq +snd-usb-lib +snd-usb-usx2y +snd-util-mem +snd-via82xx +snd-via82xx-modem +snd-virmidi +snd-virtuoso +snd-vx222 +snd-vx-lib +snd-ymfpci +soc_camera +soc_camera_platform +softcursor +softdog +sony-laptop +sonypi +soundcore +sp8870 +sp887x +spaceball +spaceorb +spcp8x5 +specialix +spectrum_cs +spi_bitbang +spi_butterfly +spidev +spi_lm70llp +squashfs +ssb +ssfdc +sstfb +st +starfire +stb6000 +stex +stinger +stir4200 +stkwebcam +stowaway +stp +stradis +strip +stv0288 +stv0297 +stv0299 +stv680 +sundance +sungem +sungem_phy +sunhme +sunkbd +sunrpc +svcrdma +svgalib +sworks-agp +sx +sx8 +sym53c416 +sym53c500_cs +sym53c8xx +synclink +synclink_cs +synclink_gt +synclinkmp +syncppp +syscopyarea +sysfillrect +sysimgblt +sysv +t128 +tcic +tcp_bic +tcp_highspeed +tcp_htcp +tcp_hybla +tcp_illinois +tcp_lp +tcp_probe +tcp_scalable +tcp_vegas +tcp_veno +tcp_westwood +tcp_yeah +tcrypt +tda10021 +tda10023 +tda10048 +tda1004x +tda10086 +tda18271 +tda7432 +tda8083 +tda826x +tda827x +tda8290 +tda9840 +tda9875 +tda9887 +tdfx +tdfxfb +tea +tea5761 +tea5767 +tea6415c +tea6420 +tehuti +tekram-sir +tg3 +tgr192 +thermal +thinkpad_acpi +thinkpad_ec +thmc50 +tifm_7xx1 +tifm_core +tifm_sd +tileblit +tipc +ti_usb_3410_5052 +tlan +tlclk +tle62x0 +tlsf +tlsup +tmdc +tms380tr +tmscsim +tmspci +toshiba +toshiba_acpi +touchit213 +touchright +touchwin +tpm +tpm_atmel +tpm_bios +tpm_infineon +tpm_nsc +tpm_tis +tp_smapi +trancevibrator +tridentfb +ts5500_flash +ts_bm +ts_fsm +ts_kmp +tsl2550 +ttpci-eeprom +ttusb_dec +ttusbdecfe +tua6100 +tulip +tun +tuner +tuner-simple +tuner-types +tuner-xc2028 +tunnel4 +tunnel6 +turbografx +tvaudio +tveeprom +tvp5150 +twidjoy +twofish +twofish_common +twofish-i586 +typhoon +u132-hcd +u14-34f +ub +ubi +ubifs +udf +ufs +uhci-hcd +uinput +uio +uio_cif +uio_smx +uli526x +ultracam +ultrastor +umem +unionfs +upd64031a +upd64083 +usb8xxx +usbcore +usb_debug +usbhid +usbkbd +usblcd +usbled +usblp +usbmon +usbmouse +usbnet +usbserial +usb-storage +usbtouchscreen +usbvideo +usbvision +uss720 +uvcvideo +uvesafb +v4l1-compat +v4l2-common +v4l2-int-device +ves1820 +ves1x93 +vesafb +veth +vfat +vga16fb +vgastate +vgg2432a4 +via +via686a +via-agp +via-ircc +via-rhine +via-rng +via-velocity +vicam +video +video1394 +videobuf-core +videobuf-dma-sg +videobuf-dvb +videobuf-vmalloc +videocodec +videodev +virtio_balloon +virtio_blk +virtio_net +virtio_pci +virtio-rng +visor +vitesse +vivi +vlsi_ir +vmlfb +vp27smpx +vpx3220 +vsxxxaa +vt1211 +vt8231 +vt8623fb +w1_ds2433 +w1_ds2760 +w1_smem +w1_therm +w83627ehf +w83627hf +w83627hf_wdt +w83697hf_wdt +w83781d +w83791d +w83792d +w83793 +w83877f_wdt +w83977af_ir +w83977f_wdt +w83l785ts +w83l786ng +w9966 +w9968cf +wacom +wafer5823wdt +warrior +wavelan +wavelan_cs +wbsd +wd +wd7000 +wdt +wdt_pci +whiteheat +winbond-840 +wire +wistron_btns +wl3501_cs +wm8739 +wm8775 +wm97xx-ts +wp512 +xc5000 +xcbc +xfrm4_mode_beet +xfrm4_mode_transport +xfrm4_mode_tunnel +xfrm4_tunnel +xfrm6_mode_beet +xfrm6_mode_ro +xfrm6_mode_transport +xfrm6_mode_tunnel +xfrm6_tunnel +xfrm_ipcomp +xfrm_user +xfs +xirc2ps_cs +xircom_cb +xor +xpad +xprtrdma +x_tables +xt_CLASSIFY +xt_comment +xt_connbytes +xt_connlimit +xt_connmark +xt_CONNMARK +xt_CONNSECMARK +xt_conntrack +xt_dccp +xt_dscp +xt_DSCP +xt_esp +xt_hashlimit +xt_helper +xt_iprange +xtkbd +xt_length +xt_limit +xt_mac +xt_mark +xt_MARK +xt_multiport +xt_NFLOG +xt_NFQUEUE +xt_NOTRACK +xt_owner +xt_physdev +xt_pkttype +xt_policy +xt_quota +xt_rateest +xt_RATEEST +xt_realm +xt_recent +xts +xt_sctp +xt_SECMARK +xt_socket +xt_state +xt_statistic +xt_string +xt_tcpmss +xt_TCPMSS +xt_tcpudp +xt_time +xt_TPROXY +xt_TRACE +xt_u32 +yealink +yellowfin +yenta_socket +zaurus +zc0301 +zd1201 +zd1211rw +zhenhua +zl10353 +zlib_deflate +znet +zr36016 +zr36050 +zr36060 +zr36067 +zr364xx --- linux-2.6.28.orig/debian/abi/2.6.28-11.41/lpia/lpia +++ linux-2.6.28/debian/abi/2.6.28-11.41/lpia/lpia @@ -0,0 +1,7867 @@ +EXPORT_SYMBOL arch/x86/kernel/scx200 0x254e5667 scx200_gpio_base +EXPORT_SYMBOL arch/x86/kernel/scx200 0x35a3c008 scx200_gpio_configure +EXPORT_SYMBOL arch/x86/kernel/scx200 0x8cfa375c scx200_gpio_shadow +EXPORT_SYMBOL arch/x86/kernel/scx200 0x907665bd scx200_cb_base +EXPORT_SYMBOL arch/x86/kvm/kvm 0x38486085 kvm_read_guest_atomic +EXPORT_SYMBOL arch/x86/kvm/kvm 0x7f4ded1c kvm_cpu_has_pending_timer +EXPORT_SYMBOL crypto/gf128mul 0x0c2f123f gf128mul_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x1068004b gf128mul_bbe +EXPORT_SYMBOL crypto/gf128mul 0x2f2889a0 gf128mul_init_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0x3755f990 gf128mul_init_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x384ef9ce gf128mul_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x56af0dbd gf128mul_x_ble +EXPORT_SYMBOL crypto/gf128mul 0x83581089 gf128mul_init_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0x9b2560b9 gf128mul_init_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x9e13f6f6 gf128mul_lle +EXPORT_SYMBOL crypto/gf128mul 0xbd17a0df gf128mul_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0xc0890413 gf128mul_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0xd60736ec gf128mul_free_64k +EXPORT_SYMBOL crypto/xor 0x5b6c00e6 xor_blocks +EXPORT_SYMBOL drivers/block/loop 0x28b5eda3 loop_register_transfer +EXPORT_SYMBOL drivers/block/loop 0xbfee3ad5 loop_unregister_transfer +EXPORT_SYMBOL drivers/block/paride/paride 0x0721d0b3 pi_schedule_claimed +EXPORT_SYMBOL drivers/block/paride/paride 0x0e48e100 pi_release +EXPORT_SYMBOL drivers/block/paride/paride 0x29a980c8 pi_read_regr +EXPORT_SYMBOL drivers/block/paride/paride 0x4233ae72 pi_write_regr +EXPORT_SYMBOL drivers/block/paride/paride 0x492894e4 paride_unregister +EXPORT_SYMBOL drivers/block/paride/paride 0x61485f53 paride_register +EXPORT_SYMBOL drivers/block/paride/paride 0x6bb9c162 pi_read_block +EXPORT_SYMBOL drivers/block/paride/paride 0x6cb9e3b9 pi_connect +EXPORT_SYMBOL drivers/block/paride/paride 0x99fc3a14 pi_init +EXPORT_SYMBOL drivers/block/paride/paride 0xa46469e2 pi_disconnect +EXPORT_SYMBOL drivers/block/paride/paride 0xe29bafaf pi_do_claimed +EXPORT_SYMBOL drivers/block/paride/paride 0xebf12cdd pi_write_block +EXPORT_SYMBOL drivers/char/agp/agpgart 0x0acbc6f0 agp_generic_create_gatt_table +EXPORT_SYMBOL drivers/char/agp/agpgart 0x0d5ff29a agp_generic_alloc_user +EXPORT_SYMBOL drivers/char/agp/agpgart 0x1da51e19 agp_generic_destroy_pages +EXPORT_SYMBOL drivers/char/agp/agpgart 0x1e2f5175 agp_generic_destroy_page +EXPORT_SYMBOL drivers/char/agp/agpgart 0x1fe78eee agp_create_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0x22a00102 agp_free_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0x2abcfcfb agp_free_page_array +EXPORT_SYMBOL drivers/char/agp/agpgart 0x2b329cae agp_backend_acquire +EXPORT_SYMBOL drivers/char/agp/agpgart 0x2c0fbe45 agp_collect_device_status +EXPORT_SYMBOL drivers/char/agp/agpgart 0x2f633365 agp_generic_free_gatt_table +EXPORT_SYMBOL drivers/char/agp/agpgart 0x30226ddf agp_device_command +EXPORT_SYMBOL drivers/char/agp/agpgart 0x35f44222 agp_flush_chipset +EXPORT_SYMBOL drivers/char/agp/agpgart 0x3fad642b agp_generic_alloc_page +EXPORT_SYMBOL drivers/char/agp/agpgart 0x4b085dbf agp3_generic_configure +EXPORT_SYMBOL drivers/char/agp/agpgart 0x5480196a agp_generic_remove_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0x6400e1e2 agp_generic_mask_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0x64f1c10e agp_generic_alloc_pages +EXPORT_SYMBOL drivers/char/agp/agpgart 0x673f815e agp_bridges +EXPORT_SYMBOL drivers/char/agp/agpgart 0x6f1aaca8 agp_generic_free_by_type +EXPORT_SYMBOL drivers/char/agp/agpgart 0x710cab9e agp_alloc_bridge +EXPORT_SYMBOL drivers/char/agp/agpgart 0x7538b132 agp_off +EXPORT_SYMBOL drivers/char/agp/agpgart 0x78a59dc4 agp_bind_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0x8b423004 agp_backend_release +EXPORT_SYMBOL drivers/char/agp/agpgart 0x8e6cec40 agp_generic_type_to_mask_type +EXPORT_SYMBOL drivers/char/agp/agpgart 0x9759fa4b agp_alloc_page_array +EXPORT_SYMBOL drivers/char/agp/agpgart 0x98c9c0d6 agp_find_bridge +EXPORT_SYMBOL drivers/char/agp/agpgart 0xa1316c4b agp3_generic_tlbflush +EXPORT_SYMBOL drivers/char/agp/agpgart 0xa4d4f0e6 global_cache_flush +EXPORT_SYMBOL drivers/char/agp/agpgart 0xaa741c93 agp_enable +EXPORT_SYMBOL drivers/char/agp/agpgart 0xb04ea8f0 agp_rebind_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xb35b1c00 agp_copy_info +EXPORT_SYMBOL drivers/char/agp/agpgart 0xc2424641 agp3_generic_cleanup +EXPORT_SYMBOL drivers/char/agp/agpgart 0xc37b4b29 get_agp_version +EXPORT_SYMBOL drivers/char/agp/agpgart 0xc50baf47 agp_generic_insert_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xc5d9c46c agp_try_unsupported_boot +EXPORT_SYMBOL drivers/char/agp/agpgart 0xc65abeb7 agp3_generic_sizes +EXPORT_SYMBOL drivers/char/agp/agpgart 0xca439d00 agp_generic_alloc_by_type +EXPORT_SYMBOL drivers/char/agp/agpgart 0xd0fef3b2 agp_free_key +EXPORT_SYMBOL drivers/char/agp/agpgart 0xdb4b211e agp_bridge +EXPORT_SYMBOL drivers/char/agp/agpgart 0xde9b17ed agp3_generic_fetch_size +EXPORT_SYMBOL drivers/char/agp/agpgart 0xe3253bc3 agp_allocate_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xebafd88f agp_unbind_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xfb7ea8e3 agp_put_bridge +EXPORT_SYMBOL drivers/char/agp/agpgart 0xfc3e0bd5 agp_generic_enable +EXPORT_SYMBOL drivers/char/generic_serial 0x212ac5bf gs_hangup +EXPORT_SYMBOL drivers/char/generic_serial 0x371c9d3b gs_close +EXPORT_SYMBOL drivers/char/generic_serial 0x5bba79e4 gs_chars_in_buffer +EXPORT_SYMBOL drivers/char/generic_serial 0x64b25ffc gs_write +EXPORT_SYMBOL drivers/char/generic_serial 0x8fd069e3 gs_flush_buffer +EXPORT_SYMBOL drivers/char/generic_serial 0x8fd0ecb6 gs_write_room +EXPORT_SYMBOL drivers/char/generic_serial 0xa477ff19 gs_getserial +EXPORT_SYMBOL drivers/char/generic_serial 0xb35e5209 gs_got_break +EXPORT_SYMBOL drivers/char/generic_serial 0xb8b918b3 gs_put_char +EXPORT_SYMBOL drivers/char/generic_serial 0xc79989bd gs_block_til_ready +EXPORT_SYMBOL drivers/char/generic_serial 0xc884b5a6 gs_init_port +EXPORT_SYMBOL drivers/char/generic_serial 0xcf04808b gs_stop +EXPORT_SYMBOL drivers/char/generic_serial 0xdaf69d22 gs_flush_chars +EXPORT_SYMBOL drivers/char/generic_serial 0xdf2f537e gs_set_termios +EXPORT_SYMBOL drivers/char/generic_serial 0xe614c7a1 gs_start +EXPORT_SYMBOL drivers/char/generic_serial 0xf35c87c2 gs_setserial +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x06e6365f ipmi_set_my_LUN +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x0da58be6 ipmi_unregister_for_cmd +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x0dddcd81 ipmi_get_my_address +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x1d1ee62e ipmi_get_version +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x217f0989 ipmi_register_for_cmd +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x263f8907 ipmi_set_gets_events +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x3c1572c4 ipmi_smi_watcher_unregister +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x40f2b10c ipmi_alloc_smi_msg +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x4cadb0a4 ipmi_create_user +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x5736a7d6 ipmi_set_maintenance_mode +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x5b573e26 ipmi_get_maintenance_mode +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x5db01ea9 ipmi_free_recv_msg +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x6f4ced79 ipmi_smi_msg_received +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x7211ca14 ipmi_request_settime +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x76c31488 ipmi_smi_add_proc_entry +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x804f922a ipmi_addr_length +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xa05abc16 ipmi_destroy_user +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xb806f998 ipmi_smi_watchdog_pretimeout +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xcdc1b9c4 ipmi_set_my_address +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xd23fba8d ipmi_get_my_LUN +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xe4f4665b ipmi_validate_addr +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xeb961397 ipmi_poll_interface +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xec1d9480 ipmi_register_smi +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xed34a15d ipmi_unregister_smi +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xfbc37bf6 ipmi_smi_watcher_register +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xfd0775ab ipmi_request_supply_msgs +EXPORT_SYMBOL drivers/char/nsc_gpio 0x0e7fc66b nsc_gpio_read +EXPORT_SYMBOL drivers/char/nsc_gpio 0x31ae58ac nsc_gpio_write +EXPORT_SYMBOL drivers/char/nsc_gpio 0x369891a1 nsc_gpio_dump +EXPORT_SYMBOL drivers/char/nvram 0x0f28cb91 nvram_read_byte +EXPORT_SYMBOL drivers/char/nvram 0x17ff2c1d __nvram_read_byte +EXPORT_SYMBOL drivers/char/nvram 0x2adec1e0 __nvram_check_checksum +EXPORT_SYMBOL drivers/char/nvram 0x7da28f12 nvram_check_checksum +EXPORT_SYMBOL drivers/char/nvram 0x9ce3f83f nvram_write_byte +EXPORT_SYMBOL drivers/char/nvram 0xa8813189 __nvram_write_byte +EXPORT_SYMBOL drivers/char/toshiba 0x9421a6a6 tosh_smm +EXPORT_SYMBOL drivers/edac/edac_core 0x20aba54f edac_mc_handle_fbd_ce +EXPORT_SYMBOL drivers/edac/edac_core 0xab1ad8e8 edac_mc_handle_fbd_ue +EXPORT_SYMBOL drivers/edac/edac_core 0xeab1b301 edac_mc_find +EXPORT_SYMBOL drivers/gpu/drm/drm 0x03f493df drm_agp_info +EXPORT_SYMBOL drivers/gpu/drm/drm 0x0480f8ce drm_ioctl +EXPORT_SYMBOL drivers/gpu/drm/drm 0x049c8750 drm_addmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0x054021dc drm_clflush_pages +EXPORT_SYMBOL drivers/gpu/drm/drm 0x0836695c drm_sman_takedown +EXPORT_SYMBOL drivers/gpu/drm/drm 0x096d8e4a drm_unbind_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0x0ab44a14 drm_idlelock_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0x148e1e3a drm_mm_search_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x1884df49 drm_idlelock_take +EXPORT_SYMBOL drivers/gpu/drm/drm 0x1e5c6fcb drm_i_have_hw_lock +EXPORT_SYMBOL drivers/gpu/drm/drm 0x20645642 drm_debug +EXPORT_SYMBOL drivers/gpu/drm/drm 0x21451ac4 drm_sman_owner_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x27755d61 drm_pci_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2916bf63 drm_sman_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2c03925e drm_core_ioremapfree +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2c7a7f9b drm_agp_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2d7dd769 drm_agp_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2eb2f903 drm_sman_free_key +EXPORT_SYMBOL drivers/gpu/drm/drm 0x3074f033 drm_order +EXPORT_SYMBOL drivers/gpu/drm/drm 0x32055935 drm_agp_enable +EXPORT_SYMBOL drivers/gpu/drm/drm 0x322bb19e drm_ati_pcigart_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x32ea7776 drm_lock_take +EXPORT_SYMBOL drivers/gpu/drm/drm 0x33b9cc71 drm_vblank_get +EXPORT_SYMBOL drivers/gpu/drm/drm 0x37d2ef3e drm_handle_vblank +EXPORT_SYMBOL drivers/gpu/drm/drm 0x3870fb26 drm_fasync +EXPORT_SYMBOL drivers/gpu/drm/drm 0x3de8f0be drm_agp_bind_pages +EXPORT_SYMBOL drivers/gpu/drm/drm 0x42591511 drm_core_get_reg_ofs +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4b8082b9 drm_mm_put_block +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4ea1f5a2 drm_gem_object_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x501dc4fe drm_exit +EXPORT_SYMBOL drivers/gpu/drm/drm 0x53bc2d50 drm_agp_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0x556aebfc drm_irq_install +EXPORT_SYMBOL drivers/gpu/drm/drm 0x55f060ee drm_sman_set_range +EXPORT_SYMBOL drivers/gpu/drm/drm 0x57c45329 drm_gem_object_lookup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x5e36335a drm_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x5f35b45a drm_core_ioremap_wc +EXPORT_SYMBOL drivers/gpu/drm/drm 0x6370b050 drm_mm_get_block +EXPORT_SYMBOL drivers/gpu/drm/drm 0x67a7c7ab drm_agp_chipset_flush +EXPORT_SYMBOL drivers/gpu/drm/drm 0x7230229b drm_vblank_put +EXPORT_SYMBOL drivers/gpu/drm/drm 0x83b0862d drm_agp_unbind +EXPORT_SYMBOL drivers/gpu/drm/drm 0x8873dc30 drm_mm_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x8ddda02d drm_sg_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0x8f29a728 drm_open +EXPORT_SYMBOL drivers/gpu/drm/drm 0x92e6117e drm_poll +EXPORT_SYMBOL drivers/gpu/drm/drm 0x946394aa drm_agp_bind +EXPORT_SYMBOL drivers/gpu/drm/drm 0x94ac786c drm_get_resource_len +EXPORT_SYMBOL drivers/gpu/drm/drm 0x9c25b192 drm_core_get_map_ofs +EXPORT_SYMBOL drivers/gpu/drm/drm 0x9c54bfa7 drm_core_ioremap +EXPORT_SYMBOL drivers/gpu/drm/drm 0xa853bedb drm_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0xab994f40 drm_rmmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0xac3b3deb drm_get_drawable_info +EXPORT_SYMBOL drivers/gpu/drm/drm 0xaf29788e drm_sman_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0xb69b74ae drm_vblank_count +EXPORT_SYMBOL drivers/gpu/drm/drm 0xb71245c9 drm_lock_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0xc080eb9b drm_gem_object_handle_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0xc6dea839 drm_agp_acquire +EXPORT_SYMBOL drivers/gpu/drm/drm 0xcfa27b28 drm_addbufs_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd1779f74 drm_gem_object_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd3028e75 drm_sman_set_manager +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd62bc955 drm_free_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd793fb74 drm_mmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0xdf5d33c1 drm_vblank_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe2aa88a4 drm_core_reclaim_buffers +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe320c385 drm_ati_pcigart_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe36d0bc5 drm_gem_handle_create +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe5e7f7a9 drm_pci_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe699f570 drm_get_resource_start +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe7486ee7 drm_getsarea +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe919dd5c drm_sman_owner_clean +EXPORT_SYMBOL drivers/gpu/drm/drm 0xea53cd2c drm_addbufs_pci +EXPORT_SYMBOL drivers/gpu/drm/drm 0xf0d0038d drm_irq_uninstall +EXPORT_SYMBOL drivers/gpu/drm/drm 0xfdfbad19 drm_sman_alloc +EXPORT_SYMBOL drivers/hid/hid-a4tech 0x051a3b74 hid_compat_a4tech +EXPORT_SYMBOL drivers/hid/hid-apple 0xdb9d8fc4 hid_compat_apple +EXPORT_SYMBOL drivers/hid/hid-belkin 0xb63fbc94 hid_compat_belkin +EXPORT_SYMBOL drivers/hid/hid-bright 0xa0b92b77 hid_compat_bright +EXPORT_SYMBOL drivers/hid/hid-cherry 0x83da94c1 hid_compat_cherry +EXPORT_SYMBOL drivers/hid/hid-chicony 0x1e301bcf hid_compat_chicony +EXPORT_SYMBOL drivers/hid/hid-cypress 0xd595334a hid_compat_cypress +EXPORT_SYMBOL drivers/hid/hid-dell 0xdb6048ee hid_compat_dell +EXPORT_SYMBOL drivers/hid/hid-ezkey 0xe95d45d8 hid_compat_ezkey +EXPORT_SYMBOL drivers/hid/hid-gyration 0x73c2d369 hid_compat_gyration +EXPORT_SYMBOL drivers/hid/hid-logitech 0x1a829f44 hid_compat_logitech +EXPORT_SYMBOL drivers/hid/hid-microsoft 0x1c0be5fa hid_compat_microsoft +EXPORT_SYMBOL drivers/hid/hid-monterey 0x224b094b hid_compat_monterey +EXPORT_SYMBOL drivers/hid/hid-petalynx 0x519ddbba hid_compat_petalynx +EXPORT_SYMBOL drivers/hid/hid-pl 0x6a396e12 hid_compat_pantherlord +EXPORT_SYMBOL drivers/hid/hid-samsung 0x4a0cfa52 hid_compat_samsung +EXPORT_SYMBOL drivers/hid/hid-sony 0xd1da4e72 hid_compat_sony +EXPORT_SYMBOL drivers/hid/hid-sunplus 0x45319560 hid_compat_sunplus +EXPORT_SYMBOL drivers/hwmon/hwmon-vid 0x0903c239 vid_from_reg +EXPORT_SYMBOL drivers/hwmon/hwmon-vid 0xef1c781c vid_which_vrm +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0x66d04dc0 i2c_bit_add_numbered_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0x723ac448 i2c_bit_add_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pca 0x6fe4ced8 i2c_pca_add_numbered_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pca 0xda10f08a i2c_pca_add_bus +EXPORT_SYMBOL drivers/i2c/busses/i2c-amd756 0x75567e62 amd756_smbus +EXPORT_SYMBOL drivers/i2c/i2c-core 0x060e2fa2 i2c_smbus_read_byte_data +EXPORT_SYMBOL drivers/i2c/i2c-core 0x09a7ec8a i2c_smbus_read_byte +EXPORT_SYMBOL drivers/i2c/i2c-core 0x0bbf6ea3 i2c_get_adapter +EXPORT_SYMBOL drivers/i2c/i2c-core 0x14a9033e i2c_use_client +EXPORT_SYMBOL drivers/i2c/i2c-core 0x21009539 i2c_master_recv +EXPORT_SYMBOL drivers/i2c/i2c-core 0x34b4b450 i2c_smbus_process_call +EXPORT_SYMBOL drivers/i2c/i2c-core 0x38b5e060 i2c_smbus_write_byte +EXPORT_SYMBOL drivers/i2c/i2c-core 0x42c61421 i2c_smbus_read_word_data +EXPORT_SYMBOL drivers/i2c/i2c-core 0x49f29dcc i2c_register_driver +EXPORT_SYMBOL drivers/i2c/i2c-core 0x4dbf2c52 i2c_smbus_read_block_data +EXPORT_SYMBOL drivers/i2c/i2c-core 0x5252890e i2c_attach_client +EXPORT_SYMBOL drivers/i2c/i2c-core 0x53c758b5 i2c_smbus_write_block_data +EXPORT_SYMBOL drivers/i2c/i2c-core 0x848ddefb i2c_verify_client +EXPORT_SYMBOL drivers/i2c/i2c-core 0x87ebef0e i2c_smbus_read_i2c_block_data +EXPORT_SYMBOL drivers/i2c/i2c-core 0x8877ed6b i2c_transfer +EXPORT_SYMBOL drivers/i2c/i2c-core 0x8d4294af i2c_probe +EXPORT_SYMBOL drivers/i2c/i2c-core 0x8fc8a387 i2c_smbus_write_word_data +EXPORT_SYMBOL drivers/i2c/i2c-core 0xa7d03071 i2c_smbus_write_i2c_block_data +EXPORT_SYMBOL drivers/i2c/i2c-core 0xad36fc63 i2c_del_driver +EXPORT_SYMBOL drivers/i2c/i2c-core 0xb52f6364 i2c_smbus_write_byte_data +EXPORT_SYMBOL drivers/i2c/i2c-core 0xb954fb79 i2c_smbus_xfer +EXPORT_SYMBOL drivers/i2c/i2c-core 0xc6c1d9e2 i2c_clients_command +EXPORT_SYMBOL drivers/i2c/i2c-core 0xd6e1880b i2c_add_adapter +EXPORT_SYMBOL drivers/i2c/i2c-core 0xd6ef5412 i2c_master_send +EXPORT_SYMBOL drivers/i2c/i2c-core 0xe25adc06 i2c_put_adapter +EXPORT_SYMBOL drivers/i2c/i2c-core 0xec50a889 i2c_release_client +EXPORT_SYMBOL drivers/i2c/i2c-core 0xeec3e949 i2c_del_adapter +EXPORT_SYMBOL drivers/i2c/i2c-core 0xf8cd7645 i2c_detach_client +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x004fdfef hpsb_iso_packet_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0956a1bc hpsb_destroy_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0c191842 hpsb_set_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0c6da941 csr1212_release_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0e402f35 hpsb_register_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0e5a659c csr1212_new_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0ea702d0 hpsb_make_readpacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x13b4a268 csr1212_attach_keyval_to_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x15b28ea6 hpsb_iso_stop +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x161690da hpsb_get_hostinfo_bykey +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x1a133117 hpsb_make_phypacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x1c595c6a hpsb_make_lockpacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x1cfbbae5 hpsb_iso_wake +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x1fc78435 hpsb_free_tlabel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x219cbabe dma_region_offset_to_bus +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x260ea63e hpsb_set_packet_complete_task +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2752b9a8 csr1212_get_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2ff8112a hpsb_read +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x31019c97 hpsb_make_streampacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x3366dfc9 hpsb_alloc_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x375c0bc9 hpsb_selfid_complete +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x37a736c9 csr1212_read +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x3b1d1a4c hpsb_reset_bus +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x3c9f3a81 hpsb_send_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x40efeb66 hpsb_iso_recv_start +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x4962970e hpsb_unregister_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x4e8ccbf1 hpsb_iso_xmit_sync +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x52ad9c0c hpsb_iso_recv_listen_channel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x53440e85 hpsb_iso_xmit_queue_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x5e314ff4 hpsb_unregister_highlevel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x61c4fce0 hpsb_iso_recv_set_channel_mask +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x672ad148 dma_region_sync_for_device +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6b52993c hpsb_make_lock64packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6c3e9d6c hpsb_iso_recv_flush +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x7046e886 csr1212_parse_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x73c3842a hpsb_packet_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x7447b2e0 hpsb_read_cycle_timer +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x76abe3f3 hpsb_write +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x76bc1a5c dma_region_free +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x771b5257 hpsb_selfid_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x813fa71a hpsb_iso_n_ready +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8580ba4c dma_region_mmap +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x884ee157 hpsb_register_highlevel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8879f8f0 dma_region_sync_for_cpu +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x899444cb hpsb_free_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8a38d2da hpsb_iso_recv_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8c1c7dc5 hpsb_resume_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8ec2b312 dma_region_alloc +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8fb949cb hpsb_protocol_class +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x9565f787 hpsb_unregister_protocol +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x979b3052 dma_prog_region_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x9b2b7d1a hpsb_node_fill_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xa0347010 hpsb_iso_recv_unlisten_channel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xa3996ade hpsb_iso_xmit_start +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xa60fdf1d hpsb_update_config_rom +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xa721503f hpsb_add_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xa924dac6 dma_prog_region_alloc +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb3ff30ff hpsb_get_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb52a837f hpsb_allocate_and_register_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb5df7ee9 hpsb_make_writepacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xba1f9ff2 hpsb_bus_reset +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xbaf2b6a6 hpsb_node_write +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xbba70620 dma_prog_region_free +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xbbe87fb5 hpsb_iso_packet_sent +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc4d037a1 hpsb_update_config_rom_image +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc669a4d3 csr1212_detach_keyval_from_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc678cdd0 __hpsb_register_protocol +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xcc8a750d hpsb_alloc_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xda67eacb hpsb_iso_shutdown +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xda82099e hpsb_set_hostinfo_key +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xdc549aeb hpsb_create_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xe3111ddc hpsb_iso_recv_release_packets +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xe44a02bd hpsb_get_tlabel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xe63be5a3 hpsb_packet_sent +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xea4152ff dma_region_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xf9d1d24a hpsb_packet_success +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfafb7d7b hpsb_remove_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfba57f51 hpsb_speedto_str +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfdecfdc8 hpsb_iso_xmit_init +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0x46ad4e55 ohci1394_unregister_iso_tasklet +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0xb37ab086 ohci1394_init_iso_tasklet +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0xd44f0d3e ohci1394_stop_context +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0xf865a068 ohci1394_register_iso_tasklet +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x38396fd2 rdma_resolve_ip +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x6b2e588e rdma_copy_addr +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x71de06c2 rdma_addr_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0xb0cf346e rdma_addr_cancel +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0xbe81bb46 rdma_addr_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0xe5f651ef rdma_translate_ip +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x18b7c68f ib_create_cm_id +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x1e69b45b ib_send_cm_mra +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x297a5ce2 ib_send_cm_sidr_rep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x2c9fc602 ib_send_cm_apr +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x42a67674 ib_send_cm_sidr_req +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x54180093 ib_send_cm_lap +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x54b82355 ib_cm_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x642dc69e ib_send_cm_rtu +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x8f5c0154 ib_send_cm_rej +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x972f217e ib_send_cm_rep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x9c615a52 ib_send_cm_dreq +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xa291fb36 ib_send_cm_req +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xa395322e ib_cm_notify +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xbba40de3 cm_class +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xdf554b70 ib_destroy_cm_id +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xe7387d7e ib_send_cm_drep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xeaf05ae2 ib_cm_listen +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x04d3850d ib_fmr_pool_unmap +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x0c544157 ib_find_cached_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x0f59aeda ib_get_client_data +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x12f8c87f ib_modify_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x14fa1d02 ib_get_cached_lmc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x1de8bf41 ib_unregister_event_handler +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x1e491a04 ib_unmap_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x2272188b ib_get_cached_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x2c75fb29 ib_query_port +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x2ef1e77c ib_destroy_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x36669fd6 ib_alloc_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3785047e ib_alloc_fast_reg_page_list +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3c3ec071 ib_unregister_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3f7567fd ib_rate_to_mult +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3fbff5d8 ib_destroy_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x49d6cb1d ib_alloc_fast_reg_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x520b2638 ib_pack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x53333a1a ib_create_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x53ec909c ib_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x59880c2f ib_destroy_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x5a533349 ib_get_cached_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x62c31b30 ib_fmr_pool_map_phys +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x6745e59c ib_register_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x69d7afd1 ib_modify_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x6cfa90b3 ib_alloc_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x70752a50 ib_destroy_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x726a6591 ib_modify_port +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x75392e3b ib_init_ah_from_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x7c44a25b ib_alloc_pd +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x7d89e963 ib_modify_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x7f3642b1 ib_query_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x82b42bb7 ib_find_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x83541be0 ib_dispatch_event +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8640eaeb ib_modify_qp_is_ok +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x87b614d8 ib_ud_header_pack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8882738d ib_rereg_phys_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8947d964 ib_flush_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x898b10f9 ib_find_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8eedb5a0 ib_create_ah_from_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8f9ddc81 ib_dealloc_pd +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x96ce6c46 rdma_node_get_transport +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x99e456d0 ib_query_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9d804fa1 mult_to_ib_rate +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9f052c49 ib_create_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa25a813a ib_query_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa25b3289 ib_alloc_mw +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa25ce326 ib_dereg_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa3f05d7e ib_register_event_handler +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xab76e42f ib_umem_page_count +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb1a312e1 ib_unpack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb32928e8 ib_dealloc_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb433f5eb ib_query_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb62c1aaa ib_detach_mcast +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb9cb2602 ib_modify_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xbb9b1b66 ib_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xc0c5d202 ib_free_fast_reg_page_list +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xc592a5d4 ib_create_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xc7ebe6ff ib_modify_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xc7fb6ae3 ib_umem_get +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd02d1926 ib_attach_mcast +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd17ba9d1 ib_ud_header_init +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd2f617f3 ib_reg_phys_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd35ef598 ib_query_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd869506e ib_create_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xda7f0767 ib_destroy_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xdd4b2d54 ib_dealloc_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xe29b1b1f ib_umem_release +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xe62b442c ib_query_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xebf5d44d ib_find_cached_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf36498b9 ib_ud_header_unpack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf3b29738 ib_resize_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf40086ab ib_dealloc_mw +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf9c8ccc6 ib_set_client_data +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xfcfa9568 ib_get_dma_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xfe378400 ib_create_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xfea3e990 ib_query_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x05791fb7 ib_unregister_mad_agent +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x230bb7ec ib_cancel_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x4b3913a5 ib_register_mad_agent +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x524b1a55 ib_free_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6ea658b0 ib_redirect_mad_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6ef787ed ib_response_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6f077fcf ib_get_mad_data_offset +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x7b5d4b7a ib_is_mad_class_rmpp +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x87d78109 ib_free_recv_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xa40d861f ib_get_rmpp_segment +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xbf494545 ib_register_mad_snoop +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xc562f328 ib_modify_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xcc36afdf ib_create_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xd072dc6c ib_process_mad_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xfb13d213 ib_post_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x138c8fb3 ib_sa_service_rec_query +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x16199856 ib_sa_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x35f976fe ib_init_ah_from_mcmember +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x3e7d0d87 ib_sa_join_multicast +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x512ba124 ib_sa_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x576fdbac ib_sa_free_multicast +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x5f3f0bff ib_sa_path_rec_get +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x7430a81c ib_sa_cancel_query +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x86e07893 ib_sa_get_mcmember_rec +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xced7d0d9 ib_init_ah_from_path +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x02f847bc ib_copy_path_rec_from_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x07cf5a51 ib_copy_ah_attr_to_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x18382f6a ib_copy_path_rec_to_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x184f3575 ib_copy_qp_attr_to_user +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x26efb4b7 iw_cm_reject +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x53154816 iw_cm_listen +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xa3919d09 iw_destroy_cm_id +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xa4fcefdc iw_create_cm_id +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xda43207c iw_cm_accept +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xf39e6c34 iw_cm_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xf6a33155 iw_cm_connect +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xf811d28e iw_cm_disconnect +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x2651049f rdma_connect +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x33059300 rdma_destroy_qp +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x3403612e rdma_accept +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x3f0a07dd rdma_create_qp +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x4982d9e0 rdma_resolve_route +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x6717d18d rdma_reject +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x75a58180 rdma_bind_addr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x7680cce8 rdma_create_id +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x85fe87c0 rdma_set_ib_paths +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x94e20cb1 rdma_leave_multicast +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xab8d28e9 rdma_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xb036aae7 rdma_join_multicast +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xb8717ec3 rdma_destroy_id +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xc04fb373 rdma_set_service_type +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xd7c23696 rdma_notify +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xdd2dcf30 rdma_listen +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xe380ecad rdma_resolve_addr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xf443ec68 rdma_disconnect +EXPORT_SYMBOL drivers/input/gameport/gameport 0x0fb03106 __gameport_register_port +EXPORT_SYMBOL drivers/input/gameport/gameport 0x11212683 gameport_close +EXPORT_SYMBOL drivers/input/gameport/gameport 0x171609f8 gameport_stop_polling +EXPORT_SYMBOL drivers/input/gameport/gameport 0x3123ae5a __gameport_register_driver +EXPORT_SYMBOL drivers/input/gameport/gameport 0x47f0b742 gameport_unregister_port +EXPORT_SYMBOL drivers/input/gameport/gameport 0x6ad4d467 gameport_open +EXPORT_SYMBOL drivers/input/gameport/gameport 0x8ceb9811 gameport_unregister_driver +EXPORT_SYMBOL drivers/input/gameport/gameport 0xcbc6ade1 gameport_set_phys +EXPORT_SYMBOL drivers/input/gameport/gameport 0xe2621bb2 gameport_start_polling +EXPORT_SYMBOL drivers/input/input-polldev 0x616f5fec input_unregister_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0x62d2f18b input_allocate_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0x8e0e4ecc input_free_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0xf80f6d92 input_register_polled_device +EXPORT_SYMBOL drivers/md/dm-log 0x9970224f dm_dirty_log_type_register +EXPORT_SYMBOL drivers/md/dm-log 0xc093c1c0 dm_dirty_log_destroy +EXPORT_SYMBOL drivers/md/dm-log 0xd7842bcd dm_dirty_log_type_unregister +EXPORT_SYMBOL drivers/md/dm-log 0xde57fed9 dm_dirty_log_create +EXPORT_SYMBOL drivers/md/dm-mod 0x08923477 dm_table_get +EXPORT_SYMBOL drivers/md/dm-mod 0x08eeaa3b dm_kcopyd_client_destroy +EXPORT_SYMBOL drivers/md/dm-mod 0x26fbd6d4 dm_table_get_size +EXPORT_SYMBOL drivers/md/dm-mod 0x2bce80d4 dm_table_get_mode +EXPORT_SYMBOL drivers/md/dm-mod 0x3385e148 dm_table_event +EXPORT_SYMBOL drivers/md/dm-mod 0x3ac5dbf3 dm_get_mapinfo +EXPORT_SYMBOL drivers/md/dm-mod 0x3b3d0448 dm_io_client_create +EXPORT_SYMBOL drivers/md/dm-mod 0x64a897ac dm_unregister_target +EXPORT_SYMBOL drivers/md/dm-mod 0x769d065a dm_register_target +EXPORT_SYMBOL drivers/md/dm-mod 0x81628d49 dm_kcopyd_copy +EXPORT_SYMBOL drivers/md/dm-mod 0x8f899913 dm_io_client_destroy +EXPORT_SYMBOL drivers/md/dm-mod 0x91d8fbaa dm_table_unplug_all +EXPORT_SYMBOL drivers/md/dm-mod 0x98521090 dm_table_put +EXPORT_SYMBOL drivers/md/dm-mod 0x993c473b dm_io_client_resize +EXPORT_SYMBOL drivers/md/dm-mod 0x99e029a6 dm_kcopyd_client_create +EXPORT_SYMBOL drivers/md/dm-mod 0xb4dcd779 dm_get_device +EXPORT_SYMBOL drivers/md/dm-mod 0xb93d2e7f dm_table_get_md +EXPORT_SYMBOL drivers/md/dm-mod 0xc79bcd36 dm_vcalloc +EXPORT_SYMBOL drivers/md/dm-mod 0xd80bae8b dm_put_device +EXPORT_SYMBOL drivers/md/dm-mod 0xe198c560 dm_io +EXPORT_SYMBOL drivers/md/md-mod 0x0052a58d bitmap_cond_end_sync +EXPORT_SYMBOL drivers/md/md-mod 0x24653248 unregister_md_personality +EXPORT_SYMBOL drivers/md/md-mod 0x260ee7e2 md_unregister_thread +EXPORT_SYMBOL drivers/md/md-mod 0x3cab97f7 md_register_thread +EXPORT_SYMBOL drivers/md/md-mod 0x3d812455 md_write_end +EXPORT_SYMBOL drivers/md/md-mod 0x672b9054 register_md_personality +EXPORT_SYMBOL drivers/md/md-mod 0x6c9084ec bitmap_close_sync +EXPORT_SYMBOL drivers/md/md-mod 0x768dc053 md_done_sync +EXPORT_SYMBOL drivers/md/md-mod 0xac3d6fa4 bitmap_start_sync +EXPORT_SYMBOL drivers/md/md-mod 0xb0653d63 bitmap_unplug +EXPORT_SYMBOL drivers/md/md-mod 0xb19347f3 bitmap_end_sync +EXPORT_SYMBOL drivers/md/md-mod 0xb96cdfbf md_wait_for_blocked_rdev +EXPORT_SYMBOL drivers/md/md-mod 0xcefbea16 md_wakeup_thread +EXPORT_SYMBOL drivers/md/md-mod 0xd73d46cd md_write_start +EXPORT_SYMBOL drivers/md/md-mod 0xdc917506 md_check_recovery +EXPORT_SYMBOL drivers/md/md-mod 0xdcfa768f md_error +EXPORT_SYMBOL drivers/md/md-mod 0xe1a4335b bitmap_startwrite +EXPORT_SYMBOL drivers/md/md-mod 0xe61cefd9 bitmap_endwrite +EXPORT_SYMBOL drivers/media/common/tuners/mt2060 0x55108699 mt2060_attach +EXPORT_SYMBOL drivers/media/common/tuners/mt2131 0x03196761 mt2131_attach +EXPORT_SYMBOL drivers/media/common/tuners/mt2266 0xcb9e3d34 mt2266_attach +EXPORT_SYMBOL drivers/media/common/tuners/mxl5005s 0x2eaf29fc mxl5005s_attach +EXPORT_SYMBOL drivers/media/common/tuners/qt1010 0x7e6dae54 qt1010_attach +EXPORT_SYMBOL drivers/media/common/tuners/tuner-types 0x0cb4b189 tuners +EXPORT_SYMBOL drivers/media/common/tuners/tuner-types 0xc2821775 tuner_count +EXPORT_SYMBOL drivers/media/common/tuners/tuner-xc2028 0xd2b169e8 xc2028_attach +EXPORT_SYMBOL drivers/media/common/tuners/xc5000 0xd63707f5 xc5000_attach +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x01083071 flexcop_sram_set_dest +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x025eb47f flexcop_dma_config +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x1c24e48b flexcop_pass_dmx_data +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x31c4cb92 flexcop_dma_xfer_control +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x47580fe5 flexcop_device_initialize +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x535ec7f9 flexcop_pass_dmx_packets +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x54e057ea flexcop_dma_free +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x6b6ac0a5 flexcop_wan_set_speed +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x744d4d65 flexcop_dma_allocate +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x830fab18 flexcop_device_kfree +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x86c9aaa4 flexcop_device_exit +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x8d3e7957 flexcop_sram_ctrl +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x9c451489 flexcop_device_kmalloc +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xa62af550 flexcop_i2c_request +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xc0bf7861 flexcop_eeprom_check_mac_addr +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xc940a126 flexcop_dma_control_timer_irq +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xd2fde8fc flexcop_dump_reg +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xd3b95429 flexcop_dma_config_timer +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xd64a178f flexcop_dma_control_size_irq +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0x2ad2458a bt878_stop +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0x70348225 bt878_start +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0x73a1cff9 bt878_device_control +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0x86ebac12 bt878 +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0xd5d0bdef bt878_num +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x3f7376f4 dst_error_bailout +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x45ee9015 dst_wait_dst_ready +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x50b93e22 dst_attach +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x5fa19ff8 dst_comm_init +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xae29c306 rdc_reset_state +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xaf1c3f09 read_dst +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xd540285d dst_error_recovery +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xdef0a82e write_dst +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xe94b8c9c dst_check_sum +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xf6b58987 dst_pio_disable +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst_ca 0xbe4a58d9 dst_ca_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x02882a2a dvb_ca_en50221_camchange_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x03e0d598 dvb_dmxdev_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x14eb630c dvb_ringbuffer_free +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x1e4e3ce5 dvb_frontend_detach +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x2ce3225b dvb_ca_en50221_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x36c8ea1f dvb_frontend_sleep_until +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x391c317f dvb_generic_open +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x4428f2fd dvb_unregister_frontend +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x607e9832 dvb_generic_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x635eb40e dvb_dmx_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x6842d561 dvb_net_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x69c3e2da dvb_generic_ioctl +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x6f7f7d73 dvb_ringbuffer_empty +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x6f9c72e3 dvb_ringbuffer_read +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x74a5a698 dvb_filter_pes2ts_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x80e3832d dvb_filter_get_ac3info +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x8b49a23f timeval_usec_diff +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x8d604ce8 dvb_ca_en50221_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x8ed5a565 dvb_dmxdev_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x8f805f96 dvb_ca_en50221_frda_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x923aa88e dvb_ringbuffer_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x9cbff999 dvb_dmx_swfilter_204 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xac4ca1b0 intlog2 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb2db2592 dvb_ringbuffer_write +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb56f0404 dvb_dmx_swfilter_packets +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb5b95805 dvb_ringbuffer_read_user +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xbea1798d dvb_net_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xbed559e1 dvb_dmx_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xc6ebdd64 dvb_ca_en50221_camready_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xc7e3f4c9 dvb_register_device +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xc938e566 dvb_dmx_swfilter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xcf3807a4 dvb_frontend_reinitialise +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xe5ae8707 intlog10 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xe7949e59 dvb_ringbuffer_flush_spinlock_wakeup +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xeb7daf80 dvb_ringbuffer_avail +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf27d0738 dvb_unregister_device +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf5ce1305 dvb_register_frontend +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf7159bf1 dvb_unregister_adapter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf826deb0 dvb_filter_pes2ts +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xffddcbc3 dvb_register_adapter +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x27ff6c3e dvb_usb_device_exit +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x5c190bf3 dvb_usb_generic_write +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x62ad06d1 dvb_usb_get_hexline +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x764b37ab dvb_usb_generic_rw +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x813ab178 usb_cypress_load_firmware +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x8a19d2be dvb_usb_nec_rc_key_to_event +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xc26d491f dvb_usb_device_init +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0x2edc4728 af9005_rc_keys +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0xd26cedbe af9005_rc_decode +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0xd3383957 af9005_rc_keys_size +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x21d750ef dibusb_i2c_algo +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x3d046229 dibusb_dib3000mc_tuner_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xa29a9137 dibusb_streaming_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xa89c8232 dibusb2_0_streaming_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xaea027eb dibusb2_0_power_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xb25709aa dibusb_dib3000mc_frontend_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xcc6c4e26 dibusb_pid_filter +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xd4d3dddc dibusb_rc_keys +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xd870ac9a dibusb_power_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xdc824f15 dibusb_rc_query +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xdd34ea32 dibusb_read_eeprom_byte +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xf193a749 dibusb_pid_filter_ctrl +EXPORT_SYMBOL drivers/media/dvb/frontends/au8522 0x7ec1bf6a au8522_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/bcm3510 0x32242411 bcm3510_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx22700 0xa91f18d6 cx22700_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx22702 0x3444dfd6 cx22702_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24110 0xf8bf7ce9 cx24110_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24116 0xfdef7eb3 cx24116_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24123 0xb44a9c86 cx24123_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24123 0xdddd3dff cx24123_get_tuner_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/dib0070 0x6966965f dib0070_wbd_offset +EXPORT_SYMBOL drivers/media/dvb/frontends/dib0070 0xdfb5aef4 dib0070_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mb 0xf672c177 dib3000mb_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x13cb431e dib3000mc_get_tuner_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x1e6ee590 dib3000mc_pid_control +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x234ec532 dib3000mc_pid_parse +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0xc122ddd1 dib3000mc_set_config +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0xdee5898a dib3000mc_i2c_enumeration +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0xe688988a dib3000mc_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000m 0x058d31d4 dib7000m_get_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000m 0xdfbc60e2 dib7000m_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x5fb00472 dib7000p_i2c_enumeration +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x63963979 dib7000p_set_wbd_ref +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x8282bcb7 dib7000p_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x8634d07b dib7000p_set_gpio +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x8bd0dc02 dib7000p_get_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xad59d530 dib7000pc_detection +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0x3adce2be dibx000_exit_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0xb9930799 dibx000_init_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0xc0b76349 dibx000_get_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/drx397xD 0x86dfdd92 drx397xD_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dvb-pll 0xf368843b dvb_pll_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/isl6405 0xcd8d8f7e isl6405_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/isl6421 0xa860c847 isl6421_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/itd1000 0xe06caa5b itd1000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/l64781 0x5cb8409d l64781_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lgdt330x 0xbbada75d lgdt330x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lnbp21 0xcb6b9e8b lnbp21_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/mt312 0xb86ce95a mt312_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/mt352 0x22f33b93 mt352_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/nxt200x 0x84cf89d8 nxt200x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/nxt6000 0x3c47f725 nxt6000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/or51132 0x800b4be9 or51132_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/or51211 0xa3df26ff or51211_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1409 0xc48590c4 s5h1409_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1411 0xcde3ac0f s5h1411_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1420 0x3b7f9a51 s5h1420_get_tuner_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1420 0xb38fdb82 s5h1420_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/si21xx 0xc8a9474b si21xx_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/sp8870 0x8b55be00 sp8870_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/sp887x 0x34e7d096 sp887x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stb6000 0x5c34b712 stb6000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0288 0xdca156cc stv0288_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0297 0xe74714ac stv0297_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0299 0x09bac35d stv0299_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10021 0x1519090b tda10021_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10023 0x77bdccd2 tda10023_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10048 0xe959e2f8 tda10048_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda1004x 0xdddc367f tda10045_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda1004x 0xfa9d8f8f tda10046_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10086 0xa0d3a2a5 tda10086_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda8083 0x962f9038 tda8083_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda826x 0x20113ae4 tda826x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tua6100 0x47476c2f tua6100_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/ves1820 0xab760826 ves1820_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/ves1x93 0x4eaf2b9d ves1x93_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/zl10353 0x909a108e zl10353_attach +EXPORT_SYMBOL drivers/media/dvb/ttpci/ttpci-eeprom 0x2eb43923 ttpci_eeprom_parse_mac +EXPORT_SYMBOL drivers/media/dvb/ttusb-dec/ttusbdecfe 0x092ac86f ttusbdecfe_dvbs_attach +EXPORT_SYMBOL drivers/media/dvb/ttusb-dec/ttusbdecfe 0x22edc9a5 ttusbdecfe_dvbt_attach +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x065a60c1 bttv_sub_register +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x11dc4b6d bttv_gpio_enable +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x7b435b77 bttv_sub_unregister +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x8ecf4acc bttv_write_gpio +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0xafd4cb3c bttv_get_pcidev +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0xbcf2d2fb bttv_read_gpio +EXPORT_SYMBOL drivers/media/video/btcx-risc 0x3b303cc4 btcx_riscmem_alloc +EXPORT_SYMBOL drivers/media/video/btcx-risc 0x495e4b0c btcx_calc_skips +EXPORT_SYMBOL drivers/media/video/btcx-risc 0x6c0d64ed btcx_riscmem_free +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xad2fe38b btcx_sort_clips +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xc368f8e6 btcx_align +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xcda0ded2 btcx_screen_clips +EXPORT_SYMBOL drivers/media/video/cpia 0x996ced56 cpia_unregister_camera +EXPORT_SYMBOL drivers/media/video/cpia 0xa09d1942 cpia_register_camera +EXPORT_SYMBOL drivers/media/video/cx18/cx18 0x2cdea06d cx18_reset_ir_gpio +EXPORT_SYMBOL drivers/media/video/cx2341x 0x226b4360 cx2341x_ctrl_get_menu +EXPORT_SYMBOL drivers/media/video/cx2341x 0x484d9064 cx2341x_ctrl_query +EXPORT_SYMBOL drivers/media/video/cx2341x 0x61b38569 cx2341x_ext_ctrls +EXPORT_SYMBOL drivers/media/video/cx2341x 0x62f2c86b cx2341x_log_status +EXPORT_SYMBOL drivers/media/video/cx2341x 0x7f09da7c cx2341x_fill_defaults +EXPORT_SYMBOL drivers/media/video/cx2341x 0xcf8b77a4 cx2341x_mpeg_ctrls +EXPORT_SYMBOL drivers/media/video/cx2341x 0xe58ec2e3 cx2341x_update +EXPORT_SYMBOL drivers/media/video/cx88/cx88-vp3054-i2c 0x2933628d vp3054_i2c_remove +EXPORT_SYMBOL drivers/media/video/cx88/cx88-vp3054-i2c 0xd607a4cb vp3054_i2c_probe +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x0a2fb21f cx88_video_mux +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x22e62642 cx88_set_control +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x4a416351 cx88_enum_input +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x66597f79 cx88_get_control +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xac4e53b9 cx88_user_ctrls +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xdad1a1c4 cx8800_ctrl_query +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xfd77bf34 cx88_set_freq +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x3db8a2ee cx8802_unregister_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x445e26de cx8802_buf_prepare +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x97e50805 cx8802_register_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x98c131ae cx8802_get_device +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0xc2685cae cx8802_cancel_buffers +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0xdc68830b cx8802_buf_queue +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0xe2628d6c cx8802_get_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x197b19d2 cx88_risc_buffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x243f4300 cx88_free_buffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x30be7270 cx88_core_get +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x370b9006 cx88_sram_channel_dump +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x3f047c90 cx88_get_stereo +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x4a494848 cx88_set_stereo +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x4ed09172 cx88_wakeup +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x52977273 cx88_risc_stopper +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x5d347c92 cx88_newstation +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x6141c8c5 cx88_tuner_callback +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x719e1fa2 cx88_ir_start +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x8cbdcd6e cx88_core_irq +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x904b8696 cx88_audio_thread +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x90a12d46 cx88_risc_databuffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x9b140fff cx88_sram_channels +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xac78e861 cx88_vdev_init +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xb47f6cda cx88_print_irqbits +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xb62b769f cx88_ir_stop +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xc039f2d1 cx88_reset +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xc49092ea cx88_set_tvnorm +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xd45d069c cx88_shutdown +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xd702c672 cx88_core_put +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xdbcde59a cx88_call_i2c_clients +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xf1cd4c64 cx88_set_tvaudio +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xfa1abb8d cx88_sram_channel_setup +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xfea4d296 cx88_set_scale +EXPORT_SYMBOL drivers/media/video/em28xx/em28xx 0x3736688d em28xx_register_extension +EXPORT_SYMBOL drivers/media/video/em28xx/em28xx 0xbbdfeeda em28xx_unregister_extension +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x4b8de4a0 gspca_suspend +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x5200c980 gspca_auto_gain_n_exposure +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x5b127f69 gspca_frame_add +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x934d07ac gspca_disconnect +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x9670af2c gspca_debug +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xa1a7454b gspca_dev_probe +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xc43ba4f4 gspca_resume +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xc54c136b gspca_get_i_frame +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x0104578e ivtv_clear_irq_mask +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x044cdc53 ivtv_udma_prepare +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x0538e449 ivtv_cards_lock +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x0f9dc6c8 ivtv_vapi +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x14f67530 ivtv_debug +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x31597c15 ivtv_cards +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x4117650a ivtv_vapi_result +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x48ee023b ivtv_udma_alloc +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x4aa26d07 ivtv_udma_unmap +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x5302797d ivtv_set_irq_mask +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x70196ffb ivtv_cards_active +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x970d453f ivtv_api +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xa19736cb ivtv_init_on_first_open +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xbf7ae515 ivtv_saa7127 +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xcfed1532 ivtv_reset_ir_gpio +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xfda25d43 ivtv_udma_setup +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x04e83446 saa7134_tuner_callback +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x1211df5d saa7134_devlist +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x2f21d24b saa7134_tvaudio_setmute +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x3f576cf1 saa7134_ts_unregister +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x5c3cc58e saa_dsp_writel +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x695d888a saa7134_ts_register +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x98af79c1 saa7134_boards +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xa397bdd4 saa7134_i2c_call_clients +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xacb2e49b saa7134_set_dmabits +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xb743a1d4 saa7134_pgtable_build +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xb9bb3e1f saa7134_dmasound_init +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xc3ffeb00 saa7134_pgtable_alloc +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xccad041f saa7134_pgtable_free +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xd1bb1cdb saa7134_set_gpio +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xfb4a0155 saa7134_dmasound_exit +EXPORT_SYMBOL drivers/media/video/soc_camera 0x16eeaf3e soc_camera_video_stop +EXPORT_SYMBOL drivers/media/video/soc_camera 0x1ea4cfba soc_camera_host_unregister +EXPORT_SYMBOL drivers/media/video/soc_camera 0x665f0c9b soc_camera_host_register +EXPORT_SYMBOL drivers/media/video/soc_camera 0x88ff23bd soc_camera_device_register +EXPORT_SYMBOL drivers/media/video/soc_camera 0xe2ae103a soc_camera_device_unregister +EXPORT_SYMBOL drivers/media/video/soc_camera 0xfb552020 soc_camera_video_start +EXPORT_SYMBOL drivers/media/video/tveeprom 0x689bd206 tveeprom_read +EXPORT_SYMBOL drivers/media/video/tveeprom 0xa820dea7 tveeprom_hauppauge_analog +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x07fdffef usbvideo_DeinterlaceFrame +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x1095f29e usbvideo_RegisterVideoDevice +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x16a2915c RingQueue_Dequeue +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x1fc1a904 usbvideo_register +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x407a321c RingQueue_WakeUpInterruptible +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x4776d4fb usbvideo_TestPattern +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xcdfde937 usbvideo_AllocateDevice +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xdc888b75 usbvideo_Deregister +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xddecac6d RingQueue_Enqueue +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xf5011f67 RingQueue_Flush +EXPORT_SYMBOL drivers/media/video/v4l1-compat 0xbbac9e9f v4l_compat_translate_ioctl +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x03165a85 v4l2_ctrl_get_menu +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x0dfb5e57 v4l2_prio_max +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x1c427ecb v4l2_ctrl_query_fill +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x2de2b633 v4l2_prio_check +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x2e9a955d v4l2_prio_close +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x3af9a0f9 v4l2_chip_ident_i2c_client +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x42c8e001 v4l2_ctrl_next +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x495426ee v4l2_ctrl_get_name +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x50766d69 v4l2_ctrl_query_menu_valid_items +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x57abfbd8 v4l2_chip_match_host +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x5fef1b4a v4l2_ctrl_query_fill_std +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x942892ab v4l2_prio_open +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x9ca35085 v4l2_chip_match_i2c_client +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xb2d1e17e v4l2_prio_change +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xc369097d v4l2_ctrl_check +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xd464e760 v4l2_ctrl_query_menu +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xd4b8ba07 v4l2_i2c_attach +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xe330bce9 v4l2_prio_init +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x24bd0ae6 videobuf_dvb_dealloc_frontends +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x2fb7e9f4 videobuf_dvb_get_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x3053e95e videobuf_dvb_unregister_bus +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x577b8e95 videobuf_dvb_find_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0xb8d66a74 videobuf_dvb_alloc_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0xca0374af videobuf_dvb_register_bus +EXPORT_SYMBOL drivers/media/video/videodev 0x123959a1 v4l2_type_names +EXPORT_SYMBOL drivers/media/video/videodev 0x1f5a3220 video_register_device_index +EXPORT_SYMBOL drivers/media/video/videodev 0x23e61e17 __video_ioctl2 +EXPORT_SYMBOL drivers/media/video/videodev 0x2a0967e4 video_unregister_device +EXPORT_SYMBOL drivers/media/video/videodev 0x2aaa0474 video_device_release +EXPORT_SYMBOL drivers/media/video/videodev 0x3adbd595 v4l2_field_names +EXPORT_SYMBOL drivers/media/video/videodev 0x5ebefe4b v4l_printk_ioctl +EXPORT_SYMBOL drivers/media/video/videodev 0x945a8cc8 video_usercopy +EXPORT_SYMBOL drivers/media/video/videodev 0xa61318e9 video_device_alloc +EXPORT_SYMBOL drivers/media/video/videodev 0xe2b92059 v4l2_video_std_construct +EXPORT_SYMBOL drivers/media/video/videodev 0xf3251e7b v4l2_norm_to_name +EXPORT_SYMBOL drivers/media/video/videodev 0xf6155e13 video_devdata +EXPORT_SYMBOL drivers/media/video/videodev 0xfc06bd6b video_device_release_empty +EXPORT_SYMBOL drivers/media/video/videodev 0xfca2f028 video_register_device +EXPORT_SYMBOL drivers/media/video/videodev 0xfe2db661 video_ioctl2 +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0x00c31160 videocodec_unregister +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0x0b3ae454 videocodec_register +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0xbbd9bc86 videocodec_detach +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0xcada305a videocodec_attach +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x1d332975 mpt_resume +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x285a20e4 mpt_get_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x375d8126 mpt_add_sge +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x3b851e94 mpt_detach +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x3c93146c mpt_alloc_fw_memory +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x3c9c2c43 mpt_config +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x4526289b mpt_event_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x490a597b mpt_HardResetHandler +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x58bf0ea6 mpt_findImVolumes +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x5f65281f mpt_raid_phys_disk_pg0 +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x6272b945 mpt_suspend +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x7b261b5d mpt_reset_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x7fa1ca42 mpt_GetIocState +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x84b739d6 mpt_put_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x9a14d4fb mpt_verify_adapter +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x9f56d7de mpt_put_msg_frame_hi_pri +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xa004aaa2 mptbase_sas_persist_operation +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xb6acb2e0 mpt_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc0e69f82 mpt_device_driver_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc47c22e8 mpt_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xcd4d4627 mpt_free_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xce492ab9 mpt_attach +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xd8f442f0 mpt_print_ioc_summary +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xd964d467 mpt_device_driver_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xd9a92a75 mpt_reset_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xdad57198 mpt_send_handshake_request +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xdd805159 ioc_list +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xe76e1280 mpt_event_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xfed0f099 mpt_free_fw_memory +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x10282ccc mptscsih_TMHandler +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x1de7dab2 mptscsih_ioc_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x1dffd075 mptscsih_taskmgmt_complete +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x22ccee91 mptscsih_suspend +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x290aa4f4 mptscsih_slave_destroy +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x2c9c771c mptscsih_bios_param +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x442416e6 mptscsih_slave_configure +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x556fdf42 mptscsih_host_attrs +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x5e7146ec mptscsih_qcmd +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x61cbf5c9 mptscsih_shutdown +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x665f8ec3 mptscsih_abort +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x760f8e98 mptscsih_event_process +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x764ddf1a mptscsih_timer_expired +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x8f3b68cc mptscsih_raid_id_to_num +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xae4759bc mptscsih_resume +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xc373f145 mptscsih_info +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xc725a85d mptscsih_io_done +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xca910d61 mptscsih_bus_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xcdbeb9fd mptscsih_host_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xd38ff3cf mptscsih_is_phys_disk +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xe343f3fe mptscsih_remove +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xeccb4ddc mptscsih_scandv_complete +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xece5cafb mptscsih_change_queue_depth +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xf01b8f99 mptscsih_dev_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xfca673cd mptscsih_proc_info +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x043b4399 i2o_driver_notify_device_remove_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x09c018a7 i2o_parm_table_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x2a843bef i2o_dump_message +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x4fa42ecc i2o_exec_lct_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x535b789c i2o_parm_issue +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x5e4e16e3 i2o_driver_unregister +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x74e5fba7 i2o_find_iop +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x7cbe2ac6 i2o_status_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x93293ea5 i2o_msg_get_wait +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x968a3b6b i2o_parm_field_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x9733aea2 i2o_device_claim +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x99781612 i2o_driver_register +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x9a68cef3 i2o_iop_find_device +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x9c7cbf2c i2o_device_claim_release +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xa385bf6e i2o_driver_notify_device_add_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xb29edccb i2o_event_register +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xb4c00dcf i2o_controllers +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xbfedf5af i2o_msg_post_wait_mem +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xc99fccd8 i2o_driver_notify_controller_remove_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xcbcbb6a4 i2o_driver_notify_controller_add_all +EXPORT_SYMBOL drivers/mfd/htc-pasic3 0x4a553ab4 pasic3_write_register +EXPORT_SYMBOL drivers/mfd/htc-pasic3 0xd323a7d0 pasic3_read_register +EXPORT_SYMBOL drivers/misc/ioc4 0x0974b3f4 ioc4_register_submodule +EXPORT_SYMBOL drivers/misc/ioc4 0x14d03322 ioc4_unregister_submodule +EXPORT_SYMBOL drivers/misc/sony-laptop 0x5bb1e117 sony_pic_camera_command +EXPORT_SYMBOL drivers/misc/tifm_core 0x012f7671 tifm_has_ms_pif +EXPORT_SYMBOL drivers/misc/tifm_core 0x02fd19d2 tifm_remove_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0x1b86ab31 tifm_free_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0x39f86aa1 tifm_queue_work +EXPORT_SYMBOL drivers/misc/tifm_core 0x582b3b02 tifm_add_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0x5d41eba3 tifm_alloc_device +EXPORT_SYMBOL drivers/misc/tifm_core 0x8075db19 tifm_alloc_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0x952d927c tifm_eject +EXPORT_SYMBOL drivers/misc/tifm_core 0x9ad3aac7 tifm_map_sg +EXPORT_SYMBOL drivers/misc/tifm_core 0x9cfe6b7a tifm_free_device +EXPORT_SYMBOL drivers/misc/tifm_core 0xeb00fe4f tifm_unregister_driver +EXPORT_SYMBOL drivers/misc/tifm_core 0xfa3dc2b1 tifm_unmap_sg +EXPORT_SYMBOL drivers/misc/tifm_core 0xfb487e66 tifm_register_driver +EXPORT_SYMBOL drivers/mmc/card/mmc_block 0x73cb731e mmc_cleanup_queue +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0x04e30fec cfi_fixup +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0x5c3303f6 cfi_varsize_frob +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0xe47c899d cfi_read_pri +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x3b23f8d7 unregister_mtd_chip_driver +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x4b0d4f62 do_map_probe +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x62c0c9f8 register_mtd_chip_driver +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x8321c4e6 map_destroy +EXPORT_SYMBOL drivers/mtd/chips/gen_probe 0xa9db8f32 mtd_do_chip_probe +EXPORT_SYMBOL drivers/mtd/maps/map_funcs 0xc2700e9b simple_map_init +EXPORT_SYMBOL drivers/mtd/mtd 0x73e54bc1 add_mtd_partitions +EXPORT_SYMBOL drivers/mtd/mtd 0xe174e071 del_mtd_partitions +EXPORT_SYMBOL drivers/mtd/mtdconcat 0x38cc4dd8 mtd_concat_destroy +EXPORT_SYMBOL drivers/mtd/mtdconcat 0xf5ccec9d mtd_concat_create +EXPORT_SYMBOL drivers/mtd/nand/nand 0x44ebbbae nand_default_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand 0xaf1a8a74 nand_scan_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0xad48dffd nand_calculate_ecc +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0xeb0025d4 nand_correct_data +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0x836bdb72 nand_flash_ids +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0xa336feb7 nand_manuf_ids +EXPORT_SYMBOL drivers/mtd/onenand/onenand 0x789a8fa0 onenand_default_bbt +EXPORT_SYMBOL drivers/mtd/onenand/onenand 0x9902ed4f onenand_scan_bbt +EXPORT_SYMBOL drivers/net/8390 0x25603678 __alloc_ei_netdev +EXPORT_SYMBOL drivers/net/8390 0x3ca85bba ei_poll +EXPORT_SYMBOL drivers/net/8390 0x7d7e0dbc ei_interrupt +EXPORT_SYMBOL drivers/net/8390 0xb9d6466d ei_open +EXPORT_SYMBOL drivers/net/8390 0xe1080993 ei_close +EXPORT_SYMBOL drivers/net/8390 0xeaf76a07 NS8390_init +EXPORT_SYMBOL drivers/net/8390p 0x497cbf45 NS8390p_init +EXPORT_SYMBOL drivers/net/8390p 0x4b3844e7 eip_open +EXPORT_SYMBOL drivers/net/8390p 0x55398eff eip_poll +EXPORT_SYMBOL drivers/net/8390p 0x841bc69f eip_interrupt +EXPORT_SYMBOL drivers/net/8390p 0x9db4681b __alloc_eip_netdev +EXPORT_SYMBOL drivers/net/8390p 0xec978daf eip_close +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x11cfd7ec arc_bcast_proto +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x4641bd7d arcnet_interrupt +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x55e8dfcd arc_proto_map +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x6534792a arcnet_debug +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x9b02c14a alloc_arcdev +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0xa117c368 arc_raw_proto +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0xb9324875 arc_proto_default +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0xc299ce94 arcnet_unregister_proto +EXPORT_SYMBOL drivers/net/arcnet/com20020 0x150f1552 com20020_found +EXPORT_SYMBOL drivers/net/arcnet/com20020 0xfabd58b9 com20020_check +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x1e19e8d6 t3_l2t_get +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x1f571a72 t3_l2t_send_event +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x38fc2f2a cxgb3_free_stid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x52eea5a5 t3_l2e_free +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x62ee8d29 cxgb3_free_atid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x6413a6d9 cxgb3_alloc_atid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x70c7e622 cxgb3_ofld_send +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x7485e2ec t3_l2t_send_slow +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x84df9c87 cxgb3_alloc_stid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x8d436931 t3_register_cpl_handler +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x9f206ec5 cxgb3_remove_tid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xbcbb2df7 cxgb3_unregister_client +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xc87031fb cxgb3_queue_tid_release +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xd66eb02c dev2t3cdev +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xe53b95f3 cxgb3_register_client +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xede6eb59 cxgb3_insert_tid +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x0d81464c irda_unregister_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x42e2e938 sirdev_set_dtr_rts +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x78363846 irda_register_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x973ec80c sirdev_put_instance +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xcae08c57 sirdev_raw_write +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xd0c7a349 sirdev_get_instance +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xd485d5a3 sirdev_write_complete +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xdefe5a8d sirdev_receive +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xdf4a5a09 sirdev_set_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xfe5f7e4e sirdev_raw_read +EXPORT_SYMBOL drivers/net/mii 0x0a1703b4 mii_check_media +EXPORT_SYMBOL drivers/net/mii 0x212651e7 mii_check_gmii_support +EXPORT_SYMBOL drivers/net/mii 0x736eaf61 mii_nway_restart +EXPORT_SYMBOL drivers/net/mii 0x9d1cf48c mii_link_ok +EXPORT_SYMBOL drivers/net/mii 0xa44cb49d generic_mii_ioctl +EXPORT_SYMBOL drivers/net/mii 0xace9b902 mii_ethtool_sset +EXPORT_SYMBOL drivers/net/mii 0xe4057198 mii_check_link +EXPORT_SYMBOL drivers/net/mii 0xef22b4c5 mii_ethtool_gset +EXPORT_SYMBOL drivers/net/phy/libphy 0x04261dde phy_driver_unregister +EXPORT_SYMBOL drivers/net/phy/libphy 0x05a87fa8 phy_mii_ioctl +EXPORT_SYMBOL drivers/net/phy/libphy 0x14fc0bf0 phy_ethtool_sset +EXPORT_SYMBOL drivers/net/phy/libphy 0x17b85814 phy_register_fixup_for_id +EXPORT_SYMBOL drivers/net/phy/libphy 0x194069c4 mdiobus_unregister +EXPORT_SYMBOL drivers/net/phy/libphy 0x1b73a54f phy_start_aneg +EXPORT_SYMBOL drivers/net/phy/libphy 0x1dcc33ff mdiobus_write +EXPORT_SYMBOL drivers/net/phy/libphy 0x218112e6 genphy_read_status +EXPORT_SYMBOL drivers/net/phy/libphy 0x296ea520 mdiobus_register +EXPORT_SYMBOL drivers/net/phy/libphy 0x2a536635 phy_disable_interrupts +EXPORT_SYMBOL drivers/net/phy/libphy 0x2bc0dc21 mdiobus_free +EXPORT_SYMBOL drivers/net/phy/libphy 0x2e260719 phy_disconnect +EXPORT_SYMBOL drivers/net/phy/libphy 0x335a8267 phy_driver_register +EXPORT_SYMBOL drivers/net/phy/libphy 0x3619de75 mdiobus_alloc +EXPORT_SYMBOL drivers/net/phy/libphy 0x47415453 phy_attach +EXPORT_SYMBOL drivers/net/phy/libphy 0x4af18fae phy_start +EXPORT_SYMBOL drivers/net/phy/libphy 0x58da9443 mdio_bus_type +EXPORT_SYMBOL drivers/net/phy/libphy 0x63509c3a phy_stop_interrupts +EXPORT_SYMBOL drivers/net/phy/libphy 0x64a58cc0 genphy_restart_aneg +EXPORT_SYMBOL drivers/net/phy/libphy 0x64fe35e5 phy_stop +EXPORT_SYMBOL drivers/net/phy/libphy 0x6db953dd genphy_config_advert +EXPORT_SYMBOL drivers/net/phy/libphy 0x75a995e8 phy_device_create +EXPORT_SYMBOL drivers/net/phy/libphy 0x75b7ec89 phy_register_fixup +EXPORT_SYMBOL drivers/net/phy/libphy 0x7ecfe730 get_phy_id +EXPORT_SYMBOL drivers/net/phy/libphy 0x86deab06 mdiobus_scan +EXPORT_SYMBOL drivers/net/phy/libphy 0x9b0e046b phy_sanitize_settings +EXPORT_SYMBOL drivers/net/phy/libphy 0xa4910c27 mdiobus_read +EXPORT_SYMBOL drivers/net/phy/libphy 0xa8866e30 genphy_update_link +EXPORT_SYMBOL drivers/net/phy/libphy 0xa9edf0b1 phy_scan_fixups +EXPORT_SYMBOL drivers/net/phy/libphy 0xaff6ab15 phy_register_fixup_for_uid +EXPORT_SYMBOL drivers/net/phy/libphy 0xb0182a08 phy_connect +EXPORT_SYMBOL drivers/net/phy/libphy 0xb9df9c30 phy_detach +EXPORT_SYMBOL drivers/net/phy/libphy 0xc1dae11d genphy_config_aneg +EXPORT_SYMBOL drivers/net/phy/libphy 0xc436542c phy_ethtool_gset +EXPORT_SYMBOL drivers/net/phy/libphy 0xd6fed416 phy_enable_interrupts +EXPORT_SYMBOL drivers/net/phy/libphy 0xd8f8edaf phy_start_interrupts +EXPORT_SYMBOL drivers/net/phy/libphy 0xefcb4e62 phy_print_status +EXPORT_SYMBOL drivers/net/phy/mdio-bitbang 0xcd4e53f6 alloc_mdio_bitbang +EXPORT_SYMBOL drivers/net/phy/mdio-bitbang 0xcef69b5c free_mdio_bitbang +EXPORT_SYMBOL drivers/net/ppp_generic 0x4404613d ppp_output_wakeup +EXPORT_SYMBOL drivers/net/ppp_generic 0x4b608886 ppp_register_channel +EXPORT_SYMBOL drivers/net/ppp_generic 0x662e590e ppp_channel_index +EXPORT_SYMBOL drivers/net/ppp_generic 0xa91ad1f0 ppp_unregister_compressor +EXPORT_SYMBOL drivers/net/ppp_generic 0xbddb788c ppp_unregister_channel +EXPORT_SYMBOL drivers/net/ppp_generic 0xbe43a420 ppp_unit_number +EXPORT_SYMBOL drivers/net/ppp_generic 0xc43ea6a9 ppp_input_error +EXPORT_SYMBOL drivers/net/ppp_generic 0xeb7bce39 ppp_register_compressor +EXPORT_SYMBOL drivers/net/ppp_generic 0xf8560f89 ppp_input +EXPORT_SYMBOL drivers/net/pppox 0x1defb961 register_pppox_proto +EXPORT_SYMBOL drivers/net/pppox 0x27fdc6a3 pppox_unbind_sock +EXPORT_SYMBOL drivers/net/pppox 0x6f639ba4 pppox_ioctl +EXPORT_SYMBOL drivers/net/pppox 0xe0ff7a18 unregister_pppox_proto +EXPORT_SYMBOL drivers/net/slhc 0x0ff2b602 slhc_compress +EXPORT_SYMBOL drivers/net/slhc 0x23c8f257 slhc_uncompress +EXPORT_SYMBOL drivers/net/slhc 0xa63d85ab slhc_remember +EXPORT_SYMBOL drivers/net/slhc 0xb5ca1c46 slhc_free +EXPORT_SYMBOL drivers/net/slhc 0xdfc5169b slhc_init +EXPORT_SYMBOL drivers/net/slhc 0xe8794ce1 slhc_toss +EXPORT_SYMBOL drivers/net/sungem_phy 0xb26f64e0 mii_phy_probe +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x518fcbfb tms380tr_interrupt +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0xa1dca23c tmsdev_term +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0xa4a42c20 tms380tr_open +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0xd2328794 tms380tr_wait +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0xdd6c8bed tmsdev_init +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0xe97846d4 tms380tr_close +EXPORT_SYMBOL drivers/net/wan/hdlc 0x078d4013 attach_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0x27dcc3da unregister_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0x4d2f57a9 alloc_hdlcdev +EXPORT_SYMBOL drivers/net/wan/hdlc 0x7b49128c unregister_hdlc_device +EXPORT_SYMBOL drivers/net/wan/hdlc 0x87f002c6 hdlc_ioctl +EXPORT_SYMBOL drivers/net/wan/hdlc 0x8d17e1cf detach_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0xbaed8530 hdlc_open +EXPORT_SYMBOL drivers/net/wan/hdlc 0xd80278cc hdlc_close +EXPORT_SYMBOL drivers/net/wan/hdlc 0xea622da1 register_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/syncppp 0x07f5c7f1 sppp_close +EXPORT_SYMBOL drivers/net/wan/syncppp 0x17003a09 sppp_do_ioctl +EXPORT_SYMBOL drivers/net/wan/syncppp 0x27442522 sppp_open +EXPORT_SYMBOL drivers/net/wan/syncppp 0x5e384b6d sppp_detach +EXPORT_SYMBOL drivers/net/wan/syncppp 0xa6cf7ef0 sppp_attach +EXPORT_SYMBOL drivers/net/wan/syncppp 0xbedfac82 sppp_reopen +EXPORT_SYMBOL drivers/net/wireless/airo 0x515a067d stop_airo_card +EXPORT_SYMBOL drivers/net/wireless/airo 0x6a3c4262 reset_airo_card +EXPORT_SYMBOL drivers/net/wireless/airo 0xf3d58d62 init_airo_card +EXPORT_SYMBOL drivers/net/wireless/atmel 0x19588d79 stop_atmel_card +EXPORT_SYMBOL drivers/net/wireless/atmel 0x89ee7e3d init_atmel_card +EXPORT_SYMBOL drivers/net/wireless/atmel 0xce9a5326 atmel_open +EXPORT_SYMBOL drivers/net/wireless/hermes 0x4196c38b hermes_write_ltv +EXPORT_SYMBOL drivers/net/wireless/hermes 0xa031d8e4 hermes_doicmd_wait +EXPORT_SYMBOL drivers/net/wireless/hermes 0xc60b5e9e hermes_bap_pwrite +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd38d8ae2 hermes_read_ltv +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd3f714e5 hermes_bap_pread +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd5168829 hermes_allocate +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd5336e5d hermes_init +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd54e219d hermes_docmd_wait +EXPORT_SYMBOL drivers/net/wireless/hermes 0xed47b224 hermes_struct_init +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x161a199c hermes_program +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x2e340491 hermesi_program_end +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x3e7d91b2 hermesi_program_init +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x79a2030e hermes_read_pda +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xc4026a52 hermes_apply_pda +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xcbd49cae hermes_apply_pda_with_defaults +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xeeef9f73 hermes_blocks_length +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x0023eb77 hostap_set_hostapd +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x08132477 hostap_init_data +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x0ad69602 hostap_set_multicast_list_queue +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x0bc35e64 hostap_set_roaming +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x0dd2cb7a prism2_update_comms_qual +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x1a009dc7 hostap_info_init +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x1c1ff3c7 hostap_remove_proc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x25a079e1 hostap_80211_rx +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x26b13a79 hostap_80211_ops +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x32245842 hostap_info_process +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x3292b444 hostap_set_string +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x38020341 hostap_init_ap_proc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x4a7cef33 hostap_handle_sta_tx_exc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x56ab7e13 hostap_remove_interface +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x64e81f2f hostap_get_stats +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x6903f16c hostap_80211_get_hdrlen +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x69c9998d hostap_set_hostapd_sta +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x69e5e846 hostap_set_encryption +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x72b83819 hostap_get_porttype +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x8627e4bc hostap_setup_dev +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x9061edc3 hostap_set_antsel +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x92b48a13 hostap_check_sta_fw_version +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x9d81c181 hostap_add_interface +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xa12ad27f hostap_dump_tx_header +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xabbff9a2 hostap_free_data +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xb2a945e0 hostap_dump_rx_header +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xbd22f5dc hostap_set_word +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xcb194126 hostap_set_auth_algs +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xccf7579c hostap_master_start_xmit +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xf67c5595 hostap_init_proc +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x01ff8b24 iwl_get_sta_id +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x03405fc7 iwl_rfkill_unregister +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x039b8e87 iwl_radio_kill_sw_enable_radio +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x07748405 iwl_sta_modify_enable_tid_tx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x0831596f iwl_send_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x097c966e iwl_init_drv +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x0aebaa37 iwl_rx_agg_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x0c3aba84 iwl_rx_queue_reset +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x0e096cf5 iwl_power_update_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x10a4d711 iwl_rx_reply_compressed_ba +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x12f3a68f iwl_clear_stations_table +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x132020ff iwl_scan_cancel +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x1454bfac iwl_setup_power_deferred_work +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x16023deb iwl_set_tx_power +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x179869b8 iwl_get_ra_sta_id +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x19510aaa iwl_txq_update_write_ptr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x1ae280f9 iwl_is_fat_tx_allowed +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x1ba77493 iwl_rfkill_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x1bf8cced iwlcore_eeprom_acquire_semaphore +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x1d77b399 iwl_bcast_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x251781c7 iwl_rx_reply_rx_phy +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x29dbb4cb iwl_hwrate_to_tx_control +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x314250da iwl_eeprom_get_mac +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x3342015e iwl_set_rxon_channel +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x34c2b4e3 iwl_send_cmd_pdu_async +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x369d0936 iwl_rx_missed_beacon_notif +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x3e207d0c iwl_get_channel_info +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x40ebba80 iwl_set_rxon_ht +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x40f2c301 iwl_send_add_sta +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x41f2593e iwl_hw_detect +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x44c2a475 iwl_tx_agg_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x4635d568 iwl_scan_initiate +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x4e08dbb5 iwl_tx_agg_start +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5281de63 iwl_hw_nic_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5607e963 iwl_tx_skb +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5a819dce iwl_remove_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5aaaff5d iwl_setup_rx_scan_handlers +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5be97e58 iwl_send_lq_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5cf0b188 iwl_send_statistics_request +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5d353692 iwl_rx_reply_rx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5d9c8aff iwl_rxon_add_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5fd65fa3 iwl_rx_queue_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x609fc23d iwl_init_channel_map +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x6233504f iwl_rf_kill_ct_config +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x62727d56 iwl_calib_set +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x66e51856 iwl_set_dynamic_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x68dd8865 iwl_rx_agg_start +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x6eef764a iwl_rx_queue_update_write_ptr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7088f115 iwl_rx_statistics +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x76e2de83 iwl_rfkill_set_hw_state +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x77859e87 iwlcore_eeprom_verify_signature +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7d3878d1 iwl_eeprom_query16 +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7dac8c6a iwl_tx_cmd_complete +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x826ff0de iwl_verify_ucode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8670273d iwl_hwrate_to_plcp_idx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x88816339 iwl_dump_nic_error_log +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8bde2f27 iwl_power_temperature_change +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x93bde8ac iwl_uninit_drv +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9bc8b52e iwl_scan_cancel_timeout +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9cde1f24 iwl_queue_space +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9e473835 iwl_send_cmd_pdu +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa0f61e10 iwl_alloc_all +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa13048f5 iwl_setup_scan_deferred_work +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa20414a1 iwl_setup_mac +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa310d877 iwl_send_calib_results +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa8bd3db5 iwl_reset_qos +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa9718b07 iwl_chain_noise_calibration +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa9800371 iwl_eeprom_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xaec7d084 iwl_txq_check_empty +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xaf6fdcc1 iwl_init_sensitivity +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb06bd91e iwl_power_enable_management +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb19efa30 iwl_remove_default_wep_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb38c9e83 iwl_radio_kill_sw_disable_radio +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb4931f07 iwl_power_disable_management +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xbc17b064 iwl_tx_queue_reclaim +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xbcb11095 iwl_eeprom_check_version +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xbfe2e29d iwl_set_default_wep_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc1c21a9a iwl_eeprom_query_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc263cea8 iwl_send_cmd_sync +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc616997d iwl_reset_run_time_calib +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc94f9136 iwl_find_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xca1c100b iwl_set_rxon_chain +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcbaf4931 get_cmd_string +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xce8cbb1b iwl_remove_dynamic_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcfec9609 iwl_power_initialize +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd021dfb3 iwl_send_static_wepkey_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd2e63d2c iwl_add_station_flags +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd62b1116 iwl_rxq_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd767a3cb iwl_rx_queue_space +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd7a45b06 iwl_eeprom_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xdd2a601a iwl_txq_ctx_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xdda97467 iwl_rx_queue_restock +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe06a749e iwl_power_set_system_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe520be82 iwl_rx_queue_alloc +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe764d0f4 iwl_rx_replenish +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe7ce5d70 iwl_rates +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe7d9e679 iwl_hw_txq_ctx_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe8101341 iwlcore_eeprom_release_semaphore +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xecb05094 iwl_power_cancel_timeout +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xed4c7680 iwl_set_hw_params +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xeda0320e iwl_power_set_user_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xf1bea212 iwlcore_eeprom_query_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xf6c4fbc2 iwl_dump_nic_event_log +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xfc94ea8d iwl_sensitivity_calibration +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x1a9d334a orinoco_interrupt +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x58e6d60f __orinoco_up +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x99d44773 free_orinocodev +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x9dc28a65 alloc_orinocodev +EXPORT_SYMBOL drivers/net/wireless/orinoco 0xccde73e3 orinoco_reinit_firmware +EXPORT_SYMBOL drivers/net/wireless/orinoco 0xeff08906 __orinoco_down +EXPORT_SYMBOL drivers/parport/parport 0x05bec396 parport_register_port +EXPORT_SYMBOL drivers/parport/parport 0x0e3a0efe parport_set_timeout +EXPORT_SYMBOL drivers/parport/parport 0x15328faf parport_unregister_device +EXPORT_SYMBOL drivers/parport/parport 0x1dbe8d84 parport_irq_handler +EXPORT_SYMBOL drivers/parport/parport 0x2c16259a parport_ieee1284_ecp_write_data +EXPORT_SYMBOL drivers/parport/parport 0x2f475a21 parport_read +EXPORT_SYMBOL drivers/parport/parport 0x329d195d parport_wait_event +EXPORT_SYMBOL drivers/parport/parport 0x37d3c4f5 parport_find_number +EXPORT_SYMBOL drivers/parport/parport 0x48dcc8d1 parport_find_base +EXPORT_SYMBOL drivers/parport/parport 0x4d2a941b parport_ieee1284_interrupt +EXPORT_SYMBOL drivers/parport/parport 0x5af6000f parport_ieee1284_epp_write_addr +EXPORT_SYMBOL drivers/parport/parport 0x6ef85c4c parport_ieee1284_ecp_read_data +EXPORT_SYMBOL drivers/parport/parport 0x7771bd2d parport_register_driver +EXPORT_SYMBOL drivers/parport/parport 0x850cb1e0 parport_ieee1284_epp_read_data +EXPORT_SYMBOL drivers/parport/parport 0x8e60ab1e parport_claim_or_block +EXPORT_SYMBOL drivers/parport/parport 0x96ca0f4c parport_unregister_driver +EXPORT_SYMBOL drivers/parport/parport 0x98dd7326 parport_release +EXPORT_SYMBOL drivers/parport/parport 0x9966b0a2 parport_ieee1284_read_nibble +EXPORT_SYMBOL drivers/parport/parport 0x9eb612dc parport_ieee1284_write_compat +EXPORT_SYMBOL drivers/parport/parport 0xa7450b80 parport_negotiate +EXPORT_SYMBOL drivers/parport/parport 0xb4de4ec5 parport_get_port +EXPORT_SYMBOL drivers/parport/parport 0xba0da478 parport_ieee1284_epp_write_data +EXPORT_SYMBOL drivers/parport/parport 0xc0e470f7 parport_announce_port +EXPORT_SYMBOL drivers/parport/parport 0xc165515b parport_write +EXPORT_SYMBOL drivers/parport/parport 0xc48ca1d3 parport_wait_peripheral +EXPORT_SYMBOL drivers/parport/parport 0xc8e83a66 parport_put_port +EXPORT_SYMBOL drivers/parport/parport 0xc976c3c5 parport_ieee1284_read_byte +EXPORT_SYMBOL drivers/parport/parport 0xcced81ed parport_ieee1284_ecp_write_addr +EXPORT_SYMBOL drivers/parport/parport 0xe008048f parport_ieee1284_epp_read_addr +EXPORT_SYMBOL drivers/parport/parport 0xea28fab0 parport_register_device +EXPORT_SYMBOL drivers/parport/parport 0xebfdbe8a parport_remove_port +EXPORT_SYMBOL drivers/parport/parport 0xeedb4158 parport_claim +EXPORT_SYMBOL drivers/parport/parport_pc 0x9dd59f87 parport_pc_probe_port +EXPORT_SYMBOL drivers/parport/parport_pc 0xe7b1073c parport_pc_unregister_port +EXPORT_SYMBOL drivers/pci/hotplug/pci_hotplug 0x677875f2 acpi_get_hp_hw_control_from_firmware +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x1e02883a pcmcia_release_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x2287c646 pcmcia_request_irq +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x2f610981 pcmcia_modify_configuration +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x2ff0b902 pcmcia_get_mem_page +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x4fd033a0 pcmcia_error_func +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x62490d73 pcmcia_request_io +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x63aa4c47 pcmcia_map_mem_page +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x8eddc0cc pcmcia_dev_present +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xa3e2e208 pcmcia_access_configuration_register +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xb8030c2b pcmcia_request_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xc320737f pcmcia_get_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xc8a5118f pcmcia_loop_config +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xd2a52862 pcmcia_disable_device +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xdccbc24d pcmcia_unregister_driver +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xe1cee80c pcmcia_request_configuration +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xe1eba904 pcmcia_register_driver +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xf0a25e12 pcmcia_error_ret +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x01ae6dcb release_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x0395474d pcmcia_put_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x09aa31c3 pcmcia_validate_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x1ad54972 pccard_read_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x1d19ce63 pccard_static_ops +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x212db8d2 pcmcia_socket_list +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x245447b8 pccard_get_next_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x24955d5d pcmcia_adjust_io_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x2d2603a2 pcmcia_socket_class +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x34434c9f pcmcia_write_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x4cace1b1 pcmcia_reset_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x4f5ef2c8 pcmcia_unregister_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x60638001 pcmcia_resume_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x63fd0ab1 pccard_register_pcmcia +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x727e9981 pcmcia_register_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x7482cb0e pcmcia_get_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x74aba95d pcmcia_parse_events +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x7b2b0aec pcmcia_eject_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x83e2600a pcmcia_get_socket_by_nr +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x9dcdd034 pcmcia_find_mem_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xb48d86a4 pcmcia_suspend_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xbb1c0292 destroy_cis_cache +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xc02ef2c8 pcmcia_parse_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xc368f687 pcmcia_socket_list_rwsem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xc4825bf4 pcmcia_replace_cis +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xcdc33359 pcmcia_insert_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xcf8a3ca1 pccard_get_first_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xcf97f3bd dead_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xd0e90cd5 pcmcia_find_io_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xd44e5bf4 pcmcia_socket_dev_resume +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xe26c0d12 pcmcia_read_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xe4d277cb pcmcia_socket_dev_suspend +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xfc459bd4 pccard_validate_cis +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xfd568bdc pccard_get_tuple_data +EXPORT_SYMBOL drivers/pcmcia/rsrc_nonstatic 0x4f08d0d8 pccard_nonstatic_ops +EXPORT_SYMBOL drivers/scsi/53c700 0x12e64aea NCR_700_release +EXPORT_SYMBOL drivers/scsi/53c700 0x5175c0f0 NCR_700_intr +EXPORT_SYMBOL drivers/scsi/53c700 0xd928709e NCR_700_detect +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0x2250c66e mraid_mm_adapter_app_handle +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0x512c956d mraid_mm_unregister_adp +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0x593c22a1 mraid_mm_register_adp +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x26973e30 qlogicfas408_queuecommand +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x3fd8cd71 qlogicfas408_detect +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x5acbde90 qlogicfas408_abort +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x5c914a2d qlogicfas408_disable_ints +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x5cd179e6 qlogicfas408_ihandl +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xd338d268 qlogicfas408_info +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xdc0f56b1 qlogicfas408_bus_reset +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xe76b3b20 qlogicfas408_get_chip_type +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xf2b95199 qlogicfas408_setup +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xfbadd266 qlogicfas408_biosparam +EXPORT_SYMBOL drivers/scsi/raid_class 0x06f609e4 raid_class_release +EXPORT_SYMBOL drivers/scsi/raid_class 0x4447f7db raid_class_attach +EXPORT_SYMBOL drivers/scsi/raid_class 0xe2dce018 raid_component_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x0b8dc688 scsi_is_fc_rport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x2e650a22 fc_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x60262bfe fc_remote_port_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x7954b1ea fc_get_event_number +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x7fd22d33 fc_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x8cf57589 fc_host_post_vendor_event +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x9fd171e5 fc_remove_host +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xac7965b0 fc_remote_port_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xbe430888 scsi_is_fc_vport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xcf19d18e fc_host_post_event +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xdcbf94f3 fc_remote_port_rolechg +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xf5941537 fc_vport_terminate +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xf627e37d fc_vport_create +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x02986dba sas_phy_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x03398f25 sas_phy_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x07f54dd1 scsi_is_sas_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x1624a9f2 sas_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x2542d8a2 sas_port_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x32bb4d2a scsi_is_sas_port +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x35c26ede sas_port_alloc_num +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x3d588649 sas_rphy_remove +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x4014af76 sas_expander_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x4beac0cd scsi_is_sas_rphy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x522721dd sas_remove_children +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x64d22d46 sas_phy_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x6c458739 sas_port_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x70bf4116 sas_rphy_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x7cb587aa sas_port_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x7ed3a391 sas_end_device_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x900ddde3 sas_remove_host +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x9e17ed95 sas_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xa86f7ade sas_rphy_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xa9713bed sas_port_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xc710cb11 sas_port_delete_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xd5bb79f0 sas_phy_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xd701af4d sas_port_mark_backlink +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xe72a264b sas_port_add_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xe87a31eb sas_rphy_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xf3d5352a sas_read_port_mode_page +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x3686ea09 spi_print_msg +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x3d0e734a spi_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x444c5172 spi_schedule_dv_device +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x7b8890d1 spi_dv_device +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0xb71c30bd spi_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0xdbdb94c6 spi_display_xfer_agreement +EXPORT_SYMBOL drivers/ssb/ssb 0x0e965111 ssb_pcicore_dev_irqvecs_enable +EXPORT_SYMBOL drivers/ssb/ssb 0x0f440d70 ssb_driver_unregister +EXPORT_SYMBOL drivers/ssb/ssb 0x1814c911 __ssb_driver_register +EXPORT_SYMBOL drivers/ssb/ssb 0x1a197295 ssb_bus_may_powerdown +EXPORT_SYMBOL drivers/ssb/ssb 0x26d58abb ssb_set_devtypedata +EXPORT_SYMBOL drivers/ssb/ssb 0x3127e481 ssb_dma_alloc_consistent +EXPORT_SYMBOL drivers/ssb/ssb 0x40c0dc29 ssb_pcihost_register +EXPORT_SYMBOL drivers/ssb/ssb 0x55582992 ssb_device_disable +EXPORT_SYMBOL drivers/ssb/ssb 0x56b0c32b ssb_bus_unregister +EXPORT_SYMBOL drivers/ssb/ssb 0xa3c5cda2 ssb_bus_resume +EXPORT_SYMBOL drivers/ssb/ssb 0xa5a40827 ssb_bus_suspend +EXPORT_SYMBOL drivers/ssb/ssb 0xaa17a445 ssb_dma_set_mask +EXPORT_SYMBOL drivers/ssb/ssb 0xab5668d7 ssb_device_enable +EXPORT_SYMBOL drivers/ssb/ssb 0xb62606da ssb_bus_powerup +EXPORT_SYMBOL drivers/ssb/ssb 0xc0512e0f ssb_admatch_base +EXPORT_SYMBOL drivers/ssb/ssb 0xc72bcd91 ssb_device_is_enabled +EXPORT_SYMBOL drivers/ssb/ssb 0xcec41677 ssb_clockspeed +EXPORT_SYMBOL drivers/ssb/ssb 0xd481192b ssb_admatch_size +EXPORT_SYMBOL drivers/ssb/ssb 0xdf44db25 ssb_bus_pcibus_register +EXPORT_SYMBOL drivers/ssb/ssb 0xf854e692 ssb_dma_free_consistent +EXPORT_SYMBOL drivers/ssb/ssb 0xfba8fcc6 ssb_dma_translation +EXPORT_SYMBOL drivers/telephony/ixj 0x1e291987 ixj_pcmcia_probe +EXPORT_SYMBOL drivers/telephony/phonedev 0x30193471 phone_unregister_device +EXPORT_SYMBOL drivers/telephony/phonedev 0xf75595c1 phone_register_device +EXPORT_SYMBOL drivers/usb/core/usbcore 0x78d4fba0 hub_port_logical_disconnect +EXPORT_SYMBOL drivers/usb/gadget/dummy_hcd 0x76a237f7 net2280_set_fifo_mode +EXPORT_SYMBOL drivers/usb/gadget/dummy_hcd 0x8737d89a usb_gadget_unregister_driver +EXPORT_SYMBOL drivers/usb/gadget/dummy_hcd 0xd6ea518d usb_gadget_register_driver +EXPORT_SYMBOL drivers/usb/host/sl811-hcd 0xe947b594 sl811h_driver +EXPORT_SYMBOL drivers/usb/serial/usbserial 0x85fe556e usb_serial_resume +EXPORT_SYMBOL drivers/usb/serial/usbserial 0xf18f9e0c usb_serial_suspend +EXPORT_SYMBOL drivers/video/backlight/corgi_bl 0xc86baa7c corgibl_limit_intensity +EXPORT_SYMBOL drivers/video/backlight/lcd 0x3f49d67b lcd_device_unregister +EXPORT_SYMBOL drivers/video/backlight/lcd 0xd16d857c lcd_device_register +EXPORT_SYMBOL drivers/video/console/bitblit 0xc88c4fd8 fbcon_set_bitops +EXPORT_SYMBOL drivers/video/console/font 0x09c8eb55 font_vga_8x16 +EXPORT_SYMBOL drivers/video/console/font 0xbb99125c get_default_font +EXPORT_SYMBOL drivers/video/console/font 0xf7584a9c find_font +EXPORT_SYMBOL drivers/video/console/softcursor 0xf36d9b29 soft_cursor +EXPORT_SYMBOL drivers/video/console/tileblit 0x12a50118 fbcon_set_tileops +EXPORT_SYMBOL drivers/video/cyber2000fb 0x0cc3ede5 cyber2000fb_detach +EXPORT_SYMBOL drivers/video/cyber2000fb 0x21de16a5 cyber2000fb_disable_extregs +EXPORT_SYMBOL drivers/video/cyber2000fb 0x9f2f3a39 cyber2000fb_attach +EXPORT_SYMBOL drivers/video/cyber2000fb 0xb1f0e80b cyber2000fb_get_fb_var +EXPORT_SYMBOL drivers/video/cyber2000fb 0xc86a43a9 cyber2000fb_enable_extregs +EXPORT_SYMBOL drivers/video/display/display 0x91f2ecf4 display_device_unregister +EXPORT_SYMBOL drivers/video/display/display 0xd159bfbc display_device_register +EXPORT_SYMBOL drivers/video/macmodes 0x08ed0b62 mac_vmode_to_var +EXPORT_SYMBOL drivers/video/macmodes 0x7633e7c2 mac_find_mode +EXPORT_SYMBOL drivers/video/macmodes 0xe2304303 mac_map_monitor_sense +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0x207b2aef matroxfb_g450_setclk +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0x487254be g450_mnp2f +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0xc4d82a59 matroxfb_g450_setpll_cond +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0x0e6c360f matrox_mystique +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0x6def3d27 DAC1064_global_restore +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0xad0414d6 matrox_G100 +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0xae672fbd DAC1064_global_init +EXPORT_SYMBOL drivers/video/matrox/matroxfb_Ti3026 0x1bfea97b matrox_millennium +EXPORT_SYMBOL drivers/video/matrox/matroxfb_accel 0xb5e9c8b4 matrox_cfbX_init +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0x8bd217a4 matroxfb_register_driver +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0xa4bbd467 matroxfb_enable_irq +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0xaa3e32c3 matroxfb_unregister_driver +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0xb17e38cb matroxfb_wait_for_sync +EXPORT_SYMBOL drivers/video/matrox/matroxfb_g450 0x300501af matroxfb_g450_connect +EXPORT_SYMBOL drivers/video/matrox/matroxfb_g450 0x6223bfa4 matroxfb_g450_shutdown +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x25cf8049 matroxfb_PLL_calcclock +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x450d94f1 matroxfb_vgaHWinit +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x68debadf matroxfb_DAC_out +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x6b28cfad matroxfb_vgaHWrestore +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0xabd8e427 matroxfb_var2my +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0xb7b59216 matroxfb_read_pins +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0xdb01e536 matroxfb_DAC_in +EXPORT_SYMBOL drivers/video/output 0x649b2681 video_output_register +EXPORT_SYMBOL drivers/video/output 0x8248d75d video_output_unregister +EXPORT_SYMBOL drivers/video/sis/sisfb 0x3037658e sis_malloc +EXPORT_SYMBOL drivers/video/sis/sisfb 0x454a3cf0 sis_free +EXPORT_SYMBOL drivers/video/svgalib 0x00d1fce9 svga_set_default_seq_regs +EXPORT_SYMBOL drivers/video/svgalib 0x07b3da30 svga_wseq_multi +EXPORT_SYMBOL drivers/video/svgalib 0x1b95c56a svga_check_timings +EXPORT_SYMBOL drivers/video/svgalib 0x3b6743d9 svga_settile +EXPORT_SYMBOL drivers/video/svgalib 0x4796f0c6 svga_tileblit +EXPORT_SYMBOL drivers/video/svgalib 0x63e898d1 svga_set_default_crt_regs +EXPORT_SYMBOL drivers/video/svgalib 0x7a3ae959 svga_wcrt_multi +EXPORT_SYMBOL drivers/video/svgalib 0x80408443 svga_set_timings +EXPORT_SYMBOL drivers/video/svgalib 0x8af51443 svga_tilefill +EXPORT_SYMBOL drivers/video/svgalib 0x8fa8438b svga_set_textmode_vga_regs +EXPORT_SYMBOL drivers/video/svgalib 0xab3b22ad svga_set_default_gfx_regs +EXPORT_SYMBOL drivers/video/svgalib 0xabfdd9f8 svga_get_tilemax +EXPORT_SYMBOL drivers/video/svgalib 0xac215ca2 svga_tilecursor +EXPORT_SYMBOL drivers/video/svgalib 0xdad682b1 svga_set_default_atc_regs +EXPORT_SYMBOL drivers/video/svgalib 0xdcce2ddd svga_get_caps +EXPORT_SYMBOL drivers/video/svgalib 0xe39aa3a8 svga_tilecopy +EXPORT_SYMBOL drivers/video/svgalib 0xec83c473 svga_match_format +EXPORT_SYMBOL drivers/video/svgalib 0xef774f5d svga_compute_pll +EXPORT_SYMBOL drivers/video/syscopyarea 0xad8e488a sys_copyarea +EXPORT_SYMBOL drivers/video/sysfillrect 0xb006c97c sys_fillrect +EXPORT_SYMBOL drivers/video/sysimgblt 0xf9da6c79 sys_imageblit +EXPORT_SYMBOL drivers/video/vgastate 0x686de290 restore_vga +EXPORT_SYMBOL drivers/video/vgastate 0xe7a2620e save_vga +EXPORT_SYMBOL drivers/w1/slaves/w1_ds2760 0xa55111d5 w1_ds2760_read +EXPORT_SYMBOL drivers/w1/slaves/w1_ds2760 0xbdebc692 w1_ds2760_write +EXPORT_SYMBOL drivers/w1/wire 0x1c6f7ce9 w1_remove_master_device +EXPORT_SYMBOL drivers/w1/wire 0x4b32e0b5 w1_unregister_family +EXPORT_SYMBOL drivers/w1/wire 0x68704a82 w1_register_family +EXPORT_SYMBOL drivers/w1/wire 0x8feffeb8 w1_add_master_device +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0x04e133fc iTCO_vendor_check_noreboot_on +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0x672c9d44 iTCO_vendor_pre_keepalive +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xa78bd894 iTCO_vendor_pre_set_heartbeat +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xa8d6daac iTCO_vendor_pre_start +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xd0efe320 iTCO_vendor_pre_stop +EXPORT_SYMBOL fs/configfs/configfs 0x87fd4d95 config_item_set_name +EXPORT_SYMBOL fs/configfs/configfs 0x9da482b0 config_group_find_item +EXPORT_SYMBOL fs/configfs/configfs 0x9dbb429b config_item_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0xbd787fe1 config_group_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0xbddce8d2 config_group_init +EXPORT_SYMBOL fs/configfs/configfs 0xc548a235 configfs_register_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0xcb57ca47 configfs_undepend_item +EXPORT_SYMBOL fs/configfs/configfs 0xd6dca484 config_item_init +EXPORT_SYMBOL fs/configfs/configfs 0xdbf31e45 configfs_depend_item +EXPORT_SYMBOL fs/configfs/configfs 0xdef0adbd config_item_put +EXPORT_SYMBOL fs/configfs/configfs 0xe48d438b configfs_unregister_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0xf147dcff config_item_get +EXPORT_SYMBOL fs/lockd/lockd 0x4495c915 nlmsvc_ops +EXPORT_SYMBOL fs/lockd/lockd 0xa7b91a7b lockd_down +EXPORT_SYMBOL fs/lockd/lockd 0xf6933c48 lockd_up +EXPORT_SYMBOL fs/nfs_common/nfs_acl 0x23f702db nfsacl_encode +EXPORT_SYMBOL fs/nfs_common/nfs_acl 0xb9a6d5fe nfsacl_decode +EXPORT_SYMBOL fs/nfsd/nfsd 0x0f3e6e01 nfs4_acl_nfsv4_to_posix +EXPORT_SYMBOL fs/nfsd/nfsd 0x2095976a nfs4_acl_new +EXPORT_SYMBOL fs/nfsd/nfsd 0x35e33c1e nfs4_acl_write_who +EXPORT_SYMBOL fs/nfsd/nfsd 0x5a157ae4 nfs4_acl_get_whotype +EXPORT_SYMBOL fs/nfsd/nfsd 0x7ee78c79 nfs4_acl_posix_to_nfsv4 +EXPORT_SYMBOL fs/xfs/xfs 0xdaf7608c xfs_qmcore_xfs +EXPORT_SYMBOL lib/crc-ccitt 0x3771b461 crc_ccitt +EXPORT_SYMBOL lib/crc-ccitt 0x75811312 crc_ccitt_table +EXPORT_SYMBOL lib/crc-itu-t 0xd29b009f crc_itu_t_table +EXPORT_SYMBOL lib/crc-itu-t 0xf5b4a948 crc_itu_t +EXPORT_SYMBOL lib/crc-t10dif 0xb6896671 crc_t10dif +EXPORT_SYMBOL lib/crc7 0xa7587646 crc7 +EXPORT_SYMBOL lib/crc7 0xd80c3603 crc7_syndrome_table +EXPORT_SYMBOL lib/libcrc32c 0x2329b292 crc32c_be +EXPORT_SYMBOL lib/libcrc32c 0x37d0b921 crc32c_le +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0x315c65fd zlib_deflateInit2 +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0x48034724 zlib_deflateReset +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xaf64ad0d zlib_deflate +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xf0caf44b zlib_deflate_workspacesize +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xf741c793 zlib_deflateEnd +EXPORT_SYMBOL net/bluetooth/bluetooth 0x0485220d hci_recv_fragment +EXPORT_SYMBOL net/bluetooth/bluetooth 0x0f42c248 hci_conn_change_link_key +EXPORT_SYMBOL net/bluetooth/bluetooth 0x106af865 bt_sock_poll +EXPORT_SYMBOL net/bluetooth/bluetooth 0x2f559e1a bt_sock_recvmsg +EXPORT_SYMBOL net/bluetooth/bluetooth 0x33f584fa hci_unregister_cb +EXPORT_SYMBOL net/bluetooth/bluetooth 0x36233144 bt_sock_ioctl +EXPORT_SYMBOL net/bluetooth/bluetooth 0x3ab19456 hci_unregister_dev +EXPORT_SYMBOL net/bluetooth/bluetooth 0x42b87293 hci_unregister_proto +EXPORT_SYMBOL net/bluetooth/bluetooth 0x4309cb6d bt_sock_link +EXPORT_SYMBOL net/bluetooth/bluetooth 0x473a3dab hci_conn_encrypt +EXPORT_SYMBOL net/bluetooth/bluetooth 0x4c08085a bt_accept_unlink +EXPORT_SYMBOL net/bluetooth/bluetooth 0x5f3021f1 hci_free_dev +EXPORT_SYMBOL net/bluetooth/bluetooth 0x638550db bt_sock_register +EXPORT_SYMBOL net/bluetooth/bluetooth 0x692d59b2 bt_sock_wait_state +EXPORT_SYMBOL net/bluetooth/bluetooth 0x7094f8ae bt_err +EXPORT_SYMBOL net/bluetooth/bluetooth 0x79b6a42a hci_suspend_dev +EXPORT_SYMBOL net/bluetooth/bluetooth 0x8b13fa2a hci_connect +EXPORT_SYMBOL net/bluetooth/bluetooth 0x8c05f636 hci_send_acl +EXPORT_SYMBOL net/bluetooth/bluetooth 0x8e1cf101 hci_send_sco +EXPORT_SYMBOL net/bluetooth/bluetooth 0x976ceaa0 bt_accept_enqueue +EXPORT_SYMBOL net/bluetooth/bluetooth 0x99c76090 hci_register_cb +EXPORT_SYMBOL net/bluetooth/bluetooth 0xb60e09f2 hci_register_dev +EXPORT_SYMBOL net/bluetooth/bluetooth 0xb75a2961 hci_conn_switch_role +EXPORT_SYMBOL net/bluetooth/bluetooth 0xbfe001b0 hci_conn_auth +EXPORT_SYMBOL net/bluetooth/bluetooth 0xc0878e56 hci_alloc_dev +EXPORT_SYMBOL net/bluetooth/bluetooth 0xc2066af0 batostr +EXPORT_SYMBOL net/bluetooth/bluetooth 0xcc1fb551 baswap +EXPORT_SYMBOL net/bluetooth/bluetooth 0xcf4abb96 bt_accept_dequeue +EXPORT_SYMBOL net/bluetooth/bluetooth 0xd71c5e2b bt_sock_unlink +EXPORT_SYMBOL net/bluetooth/bluetooth 0xe466dcda hci_register_proto +EXPORT_SYMBOL net/bluetooth/bluetooth 0xe9056b48 hci_conn_check_link_mode +EXPORT_SYMBOL net/bluetooth/bluetooth 0xef439f92 hci_get_route +EXPORT_SYMBOL net/bluetooth/bluetooth 0xf19294db bt_sock_unregister +EXPORT_SYMBOL net/bluetooth/bluetooth 0xf951e154 hci_resume_dev +EXPORT_SYMBOL net/bluetooth/l2cap 0xfc31fe88 l2cap_load +EXPORT_SYMBOL net/bridge/bridge 0x564df78e br_should_route_hook +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0x0dd54f81 ebt_do_table +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0x4c75e8ac ebt_unregister_table +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0xd8da374b ebt_register_table +EXPORT_SYMBOL net/ieee80211/ieee80211 0x1197449b free_ieee80211 +EXPORT_SYMBOL net/ieee80211/ieee80211 0x223132bf ieee80211_set_geo +EXPORT_SYMBOL net/ieee80211/ieee80211 0x2a7084f9 ieee80211_rx_mgt +EXPORT_SYMBOL net/ieee80211/ieee80211 0x3700b417 ieee80211_wx_set_encodeext +EXPORT_SYMBOL net/ieee80211/ieee80211 0x4ca94e46 ieee80211_wx_set_encode +EXPORT_SYMBOL net/ieee80211/ieee80211 0x52ed96ea ieee80211_get_geo +EXPORT_SYMBOL net/ieee80211/ieee80211 0x5a086399 ieee80211_get_channel +EXPORT_SYMBOL net/ieee80211/ieee80211 0x69d7a876 alloc_ieee80211 +EXPORT_SYMBOL net/ieee80211/ieee80211 0x6fa66513 ieee80211_wx_get_scan +EXPORT_SYMBOL net/ieee80211/ieee80211 0x84684ddb ieee80211_get_channel_flags +EXPORT_SYMBOL net/ieee80211/ieee80211 0xa8ee8775 ieee80211_txb_free +EXPORT_SYMBOL net/ieee80211/ieee80211 0xa9fb135f escape_essid +EXPORT_SYMBOL net/ieee80211/ieee80211 0xc04daf50 ieee80211_wx_get_encodeext +EXPORT_SYMBOL net/ieee80211/ieee80211 0xd7747f8a ieee80211_channel_to_index +EXPORT_SYMBOL net/ieee80211/ieee80211 0xd8d2d24e ieee80211_networks_age +EXPORT_SYMBOL net/ieee80211/ieee80211 0xe2e5e515 ieee80211_channel_to_freq +EXPORT_SYMBOL net/ieee80211/ieee80211 0xe7a0d97a ieee80211_is_valid_channel +EXPORT_SYMBOL net/ieee80211/ieee80211 0xecb94091 ieee80211_rx +EXPORT_SYMBOL net/ieee80211/ieee80211 0xf08976ba ieee80211_freq_to_channel +EXPORT_SYMBOL net/ieee80211/ieee80211 0xf3ddcdb1 ieee80211_wx_get_encode +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x279e265f ieee80211_crypt_deinit_handler +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x56d933c2 ieee80211_crypt_deinit_entries +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x731baa5e ieee80211_get_crypto_ops +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x8342ea1b ieee80211_crypt_delayed_deinit +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x8a2c3b16 ieee80211_crypt_quiescing +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0xbc4df3c5 ieee80211_register_crypto_ops +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0xea81d0d8 ieee80211_unregister_crypto_ops +EXPORT_SYMBOL net/ipv4/inet_lro 0x4a01245f lro_receive_skb +EXPORT_SYMBOL net/ipv4/inet_lro 0x78c799a0 lro_vlan_hwaccel_receive_skb +EXPORT_SYMBOL net/ipv4/inet_lro 0x94a457de lro_flush_all +EXPORT_SYMBOL net/ipv4/inet_lro 0xc30ad086 lro_vlan_hwaccel_receive_frags +EXPORT_SYMBOL net/ipv4/inet_lro 0xf0a7d032 lro_flush_pkt +EXPORT_SYMBOL net/ipv4/inet_lro 0xf2a996d3 lro_receive_frags +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x69b3a82f arpt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0xa450b15c arpt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0xb6a25256 arpt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0x125d72de ipt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0x8b834e9d ipt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0xf9ce5800 ipt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x093387d2 nf_nat_setup_info +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x14303df1 nf_nat_mangle_udp_packet +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x5562eb75 nf_nat_protocol_unregister +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0xa9bc9c61 nf_nat_follow_master +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0xb23252de nf_nat_protocol_register +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0xb6584f25 nf_nat_mangle_tcp_packet +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0xcf5f7ac6 nf_nat_used_tuple +EXPORT_SYMBOL net/ipv4/tunnel4 0x187e7f5b xfrm4_tunnel_register +EXPORT_SYMBOL net/ipv4/tunnel4 0xb5cf42f6 xfrm4_tunnel_deregister +EXPORT_SYMBOL net/ipv6/ipv6 0x00c095fc xfrm6_input_addr +EXPORT_SYMBOL net/ipv6/ipv6 0x09721691 ipv6_chk_addr +EXPORT_SYMBOL net/ipv6/ipv6 0x1472885a inet6_bind +EXPORT_SYMBOL net/ipv6/ipv6 0x1a3d0308 inet6_ioctl +EXPORT_SYMBOL net/ipv6/ipv6 0x1c069688 ipv6_push_nfrag_opts +EXPORT_SYMBOL net/ipv6/ipv6 0x1fc4abeb icmpv6_send +EXPORT_SYMBOL net/ipv6/ipv6 0x2ea06747 ipv6_dev_get_saddr +EXPORT_SYMBOL net/ipv6/ipv6 0x30123eb5 icmpv6_statistics +EXPORT_SYMBOL net/ipv6/ipv6 0x367f6db5 inet6_register_protosw +EXPORT_SYMBOL net/ipv6/ipv6 0x3b99a693 inet6_del_protocol +EXPORT_SYMBOL net/ipv6/ipv6 0x4bd68346 ndisc_mc_map +EXPORT_SYMBOL net/ipv6/ipv6 0x4d86441a ip6_route_output +EXPORT_SYMBOL net/ipv6/ipv6 0x538383c0 unregister_inet6addr_notifier +EXPORT_SYMBOL net/ipv6/ipv6 0x5f968e2e in6_dev_finish_destroy +EXPORT_SYMBOL net/ipv6/ipv6 0x635f555b inet6_getname +EXPORT_SYMBOL net/ipv6/ipv6 0x65d708b4 ip6_frag_init +EXPORT_SYMBOL net/ipv6/ipv6 0x680a9d31 xfrm6_find_1stfragopt +EXPORT_SYMBOL net/ipv6/ipv6 0x68c0ad52 ipv6_chk_prefix +EXPORT_SYMBOL net/ipv6/ipv6 0x69b14790 ip6_frag_match +EXPORT_SYMBOL net/ipv6/ipv6 0x7e6d3237 xfrm6_prepare_output +EXPORT_SYMBOL net/ipv6/ipv6 0x937c0bc9 nf_ip6_checksum +EXPORT_SYMBOL net/ipv6/ipv6 0x93d4de61 ipv6_getsockopt +EXPORT_SYMBOL net/ipv6/ipv6 0xad87eb36 xfrm6_rcv +EXPORT_SYMBOL net/ipv6/ipv6 0xb38eb1ff inet6_add_protocol +EXPORT_SYMBOL net/ipv6/ipv6 0xb905ad82 icmpv6_err_convert +EXPORT_SYMBOL net/ipv6/ipv6 0xc1884fa2 ip6_route_me_harder +EXPORT_SYMBOL net/ipv6/ipv6 0xc65b3c29 ipv6_setsockopt +EXPORT_SYMBOL net/ipv6/ipv6 0xc7d18db2 inet6_unregister_protosw +EXPORT_SYMBOL net/ipv6/ipv6 0xce19bac5 register_inet6addr_notifier +EXPORT_SYMBOL net/ipv6/ipv6 0xd7f66359 rt6_lookup +EXPORT_SYMBOL net/ipv6/ipv6 0xe1a81c3a icmpv6msg_statistics +EXPORT_SYMBOL net/ipv6/ipv6 0xe690b8fd __ipv6_isatap_ifid +EXPORT_SYMBOL net/ipv6/ipv6 0xecad2c5c ip6_xmit +EXPORT_SYMBOL net/ipv6/ipv6 0xf421a340 xfrm6_rcv_spi +EXPORT_SYMBOL net/ipv6/ipv6 0xfc5593f2 inet6_release +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x10120791 ip6t_register_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xa2445be9 ip6t_unregister_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xb8bddf33 ip6t_ext_hdr +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xe50b2f99 ip6t_do_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xff136e12 ipv6_find_hdr +EXPORT_SYMBOL net/ipv6/tunnel6 0x65bb1cfb xfrm6_tunnel_register +EXPORT_SYMBOL net/ipv6/tunnel6 0xd4ce2d5b xfrm6_tunnel_deregister +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0x9cd013f2 xfrm6_tunnel_alloc_spi +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0xab14e193 xfrm6_tunnel_free_spi +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0xdb1b42d1 xfrm6_tunnel_spi_lookup +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x0f6df011 ircomm_connect_response +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x39ec8cc0 ircomm_open +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x6ad2af19 ircomm_flow_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x86d509df ircomm_connect_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x9b1aeef3 ircomm_close +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x9e261753 ircomm_control_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0xa4c7db9d ircomm_disconnect_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0xe2585a33 ircomm_data_request +EXPORT_SYMBOL net/irda/irda 0x01d1fcdb hashbin_delete +EXPORT_SYMBOL net/irda/irda 0x03a262dd irttp_open_tsap +EXPORT_SYMBOL net/irda/irda 0x06a3ee58 irias_new_integer_value +EXPORT_SYMBOL net/irda/irda 0x072e026f irias_add_octseq_attrib +EXPORT_SYMBOL net/irda/irda 0x07d3647c irlmp_register_service +EXPORT_SYMBOL net/irda/irda 0x0be36684 iriap_close +EXPORT_SYMBOL net/irda/irda 0x0bf2f742 irda_device_set_media_busy +EXPORT_SYMBOL net/irda/irda 0x10961455 irlmp_data_request +EXPORT_SYMBOL net/irda/irda 0x118c1e91 irttp_connect_request +EXPORT_SYMBOL net/irda/irda 0x1749e452 irlmp_disconnect_request +EXPORT_SYMBOL net/irda/irda 0x2036ad06 irda_param_insert +EXPORT_SYMBOL net/irda/irda 0x213a3658 irlap_close +EXPORT_SYMBOL net/irda/irda 0x3462950f hashbin_remove +EXPORT_SYMBOL net/irda/irda 0x369b987c irttp_flow_request +EXPORT_SYMBOL net/irda/irda 0x38a20e5b irda_debug +EXPORT_SYMBOL net/irda/irda 0x448b8aaa irda_qos_bits_to_value +EXPORT_SYMBOL net/irda/irda 0x46c1c4a2 irlmp_unregister_service +EXPORT_SYMBOL net/irda/irda 0x48bf6a5d iriap_open +EXPORT_SYMBOL net/irda/irda 0x5086f50f async_wrap_skb +EXPORT_SYMBOL net/irda/irda 0x5adc099f alloc_irdadev +EXPORT_SYMBOL net/irda/irda 0x6758f8ac irias_new_object +EXPORT_SYMBOL net/irda/irda 0x68b7447c hashbin_find +EXPORT_SYMBOL net/irda/irda 0x6b043eba irda_init_max_qos_capabilies +EXPORT_SYMBOL net/irda/irda 0x6d86d939 irlmp_open_lsap +EXPORT_SYMBOL net/irda/irda 0x704221bc irttp_close_tsap +EXPORT_SYMBOL net/irda/irda 0x7042bc54 irlmp_register_client +EXPORT_SYMBOL net/irda/irda 0x738006c2 irda_notify_init +EXPORT_SYMBOL net/irda/irda 0x747d6779 irias_delete_object +EXPORT_SYMBOL net/irda/irda 0x7621e908 hashbin_insert +EXPORT_SYMBOL net/irda/irda 0x76243bc9 irias_insert_object +EXPORT_SYMBOL net/irda/irda 0x763e54a4 irlmp_unregister_client +EXPORT_SYMBOL net/irda/irda 0x7660257c irlmp_connect_request +EXPORT_SYMBOL net/irda/irda 0x7760795a irlap_open +EXPORT_SYMBOL net/irda/irda 0x781e2db5 irias_find_object +EXPORT_SYMBOL net/irda/irda 0x7957f728 irlmp_update_client +EXPORT_SYMBOL net/irda/irda 0x7a57b6f3 hashbin_remove_this +EXPORT_SYMBOL net/irda/irda 0x7bf8ceb9 proc_irda +EXPORT_SYMBOL net/irda/irda 0x91815586 irda_param_pack +EXPORT_SYMBOL net/irda/irda 0x993ad14b irda_param_extract_all +EXPORT_SYMBOL net/irda/irda 0xa6420ecb irttp_udata_request +EXPORT_SYMBOL net/irda/irda 0xb9394173 irias_delete_value +EXPORT_SYMBOL net/irda/irda 0xbcacad8a irttp_disconnect_request +EXPORT_SYMBOL net/irda/irda 0xbcd3ef13 irias_object_change_attribute +EXPORT_SYMBOL net/irda/irda 0xbe40ace9 irlmp_discovery_request +EXPORT_SYMBOL net/irda/irda 0xc14e9b6a hashbin_get_next +EXPORT_SYMBOL net/irda/irda 0xcd41236c hashbin_new +EXPORT_SYMBOL net/irda/irda 0xcec7604d irlmp_close_lsap +EXPORT_SYMBOL net/irda/irda 0xd7172ff4 hashbin_get_first +EXPORT_SYMBOL net/irda/irda 0xd8bfb6d4 hashbin_lock_find +EXPORT_SYMBOL net/irda/irda 0xdbe9ec30 irlmp_connect_response +EXPORT_SYMBOL net/irda/irda 0xdc04c4fe irttp_connect_response +EXPORT_SYMBOL net/irda/irda 0xde4c6b3c irlmp_service_to_hint +EXPORT_SYMBOL net/irda/irda 0xe36c5af0 async_unwrap_char +EXPORT_SYMBOL net/irda/irda 0xe5260e0e irias_add_integer_attrib +EXPORT_SYMBOL net/irda/irda 0xe909f5ac irttp_dup +EXPORT_SYMBOL net/irda/irda 0xec41fe7f irias_add_string_attrib +EXPORT_SYMBOL net/irda/irda 0xedd521c2 irlmp_get_discoveries +EXPORT_SYMBOL net/irda/irda 0xf39b7fe0 irda_setup_dma +EXPORT_SYMBOL net/irda/irda 0xf4dfb27d irttp_data_request +EXPORT_SYMBOL net/irda/irda 0xf69fded3 iriap_getvaluebyclass_request +EXPORT_SYMBOL net/mac80211/mac80211 0x010cda85 __ieee80211_get_tx_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x033197ba ieee80211_scan_completed +EXPORT_SYMBOL net/mac80211/mac80211 0x103d4a50 ieee80211_generic_frame_duration +EXPORT_SYMBOL net/mac80211/mac80211 0x14d3e48d ieee80211_tx_status_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x1b0b2249 ieee80211_tx_status +EXPORT_SYMBOL net/mac80211/mac80211 0x285f10f3 ieee80211_ctstoself_duration +EXPORT_SYMBOL net/mac80211/mac80211 0x2bba4f4e ieee80211_alloc_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x2bbf0c88 ieee80211_rts_get +EXPORT_SYMBOL net/mac80211/mac80211 0x2c476a07 ieee80211_get_tkip_key +EXPORT_SYMBOL net/mac80211/mac80211 0x33fe250b __ieee80211_get_rx_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x37ec7f4d ieee80211_rate_control_register +EXPORT_SYMBOL net/mac80211/mac80211 0x41e77e61 ieee80211_find_sta +EXPORT_SYMBOL net/mac80211/mac80211 0x453f204d ieee80211_free_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x469c346f ieee80211_start_tx_ba_cb_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x52a64a8e ieee80211_stop_queues +EXPORT_SYMBOL net/mac80211/mac80211 0x584b7bdc wiphy_to_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x5f6eb4b5 ieee80211_queue_stopped +EXPORT_SYMBOL net/mac80211/mac80211 0x60fe789a ieee80211_stop_tx_ba_session +EXPORT_SYMBOL net/mac80211/mac80211 0x6c0933a9 ieee80211_stop_queue +EXPORT_SYMBOL net/mac80211/mac80211 0x722b4774 ieee80211_get_hdrlen_from_skb +EXPORT_SYMBOL net/mac80211/mac80211 0x822d68ef ieee80211_wake_queues +EXPORT_SYMBOL net/mac80211/mac80211 0x8c35d732 ieee80211_hdrlen +EXPORT_SYMBOL net/mac80211/mac80211 0x8dbfeb16 ieee80211_beacon_get +EXPORT_SYMBOL net/mac80211/mac80211 0x8e9e5b65 ieee80211_get_buffered_bc +EXPORT_SYMBOL net/mac80211/mac80211 0xa38f2bf5 ieee80211_stop_tx_ba_cb_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0xa8bce244 __ieee80211_rx +EXPORT_SYMBOL net/mac80211/mac80211 0xae383b9f ieee80211_wake_queue +EXPORT_SYMBOL net/mac80211/mac80211 0xaf05584d ieee80211_rate_control_unregister +EXPORT_SYMBOL net/mac80211/mac80211 0xb07aac0e ieee80211_start_tx_ba_session +EXPORT_SYMBOL net/mac80211/mac80211 0xb51fee71 ieee80211_start_tx_ba_cb +EXPORT_SYMBOL net/mac80211/mac80211 0xb6c1416f ieee80211_ctstoself_get +EXPORT_SYMBOL net/mac80211/mac80211 0xba723313 ieee80211_unregister_hw +EXPORT_SYMBOL net/mac80211/mac80211 0xc5144712 ieee80211_register_hw +EXPORT_SYMBOL net/mac80211/mac80211 0xca731156 __ieee80211_get_assoc_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0xd8ca7e70 ieee80211_stop_tx_ba_cb +EXPORT_SYMBOL net/mac80211/mac80211 0xe0b44127 ieee80211_rts_duration +EXPORT_SYMBOL net/mac80211/mac80211 0xe11b8ddd ieee80211_rx_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0xf111ab6a __ieee80211_get_radio_led_name +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x13eb0059 ip_vs_conn_new +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x47607a1d unregister_ip_vs_app +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x4be349ce unregister_ip_vs_scheduler +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x5942ea39 ip_vs_conn_put +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x6769dbfc ip_vs_conn_out_get +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x6dc63521 register_ip_vs_app +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xa1dbc2d8 ip_vs_proto_name +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xae80fc0a ip_vs_conn_in_get +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xcefb902d ip_vs_tcp_conn_listen +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xe2d35cfa register_ip_vs_scheduler +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xe9c00f26 register_ip_vs_app_inc +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xeb1f832b ip_vs_skb_replace +EXPORT_SYMBOL net/netfilter/nf_conntrack 0x8fb4ee7a __nf_ct_ext_destroy +EXPORT_SYMBOL net/netfilter/nf_conntrack 0xe372c1b6 __nf_ct_ext_add +EXPORT_SYMBOL net/netfilter/nf_conntrack_proto_gre 0xf6399dd4 nf_ct_gre_keymap_flush +EXPORT_SYMBOL net/netfilter/x_tables 0x0272ac39 xt_register_target +EXPORT_SYMBOL net/netfilter/x_tables 0x246f4bf6 xt_unregister_matches +EXPORT_SYMBOL net/netfilter/x_tables 0x37cec7b5 xt_unregister_match +EXPORT_SYMBOL net/netfilter/x_tables 0x3b73c6a3 xt_unregister_target +EXPORT_SYMBOL net/netfilter/x_tables 0x3dcd58c5 xt_alloc_table_info +EXPORT_SYMBOL net/netfilter/x_tables 0x557b4733 xt_find_match +EXPORT_SYMBOL net/netfilter/x_tables 0xa6066606 xt_register_targets +EXPORT_SYMBOL net/netfilter/x_tables 0xa886f5e6 xt_find_target +EXPORT_SYMBOL net/netfilter/x_tables 0xacba6166 xt_register_match +EXPORT_SYMBOL net/netfilter/x_tables 0xb9e48fd2 xt_register_matches +EXPORT_SYMBOL net/netfilter/x_tables 0xd0bd3104 xt_unregister_targets +EXPORT_SYMBOL net/netfilter/x_tables 0xf7037dc6 xt_free_table_info +EXPORT_SYMBOL net/rfkill/rfkill 0x1998b0ad rfkill_allocate +EXPORT_SYMBOL net/rfkill/rfkill 0x7772220d rfkill_switch_all +EXPORT_SYMBOL net/rfkill/rfkill 0xb16f7e3a rfkill_force_state +EXPORT_SYMBOL net/rfkill/rfkill 0xcffff444 rfkill_register +EXPORT_SYMBOL net/rfkill/rfkill 0xd97d0ca2 rfkill_free +EXPORT_SYMBOL net/rfkill/rfkill 0xf1cc84d7 rfkill_unregister +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x0a9269f3 rxrpc_kernel_is_data_last +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x1021f0ae key_type_rxrpc +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x34501c74 rxrpc_get_server_data_key +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x538eaade rxrpc_kernel_end_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x5fbbbe60 rxrpc_kernel_accept_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x65612d0b rxrpc_kernel_begin_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x88660f25 rxrpc_kernel_reject_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xa7e714ad rxrpc_kernel_get_error_number +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xa990fe05 rxrpc_kernel_get_abort_code +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xd5207b15 rxrpc_kernel_intercept_rx_messages +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xd535c354 rxrpc_kernel_data_delivered +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xe74380ee rxrpc_kernel_abort_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xea8cc671 rxrpc_kernel_send_data +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xf38d8b79 rxrpc_get_null_key +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xf3e63c83 rxrpc_kernel_free_skb +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x00c52ef5 g_make_token_header +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x2ca93931 gss_service_to_auth_domain_name +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x3c416e1d gss_mech_unregister +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x6d9e0ada gss_mech_register +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x7f1f9bfc svcauth_gss_flavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x8c064d78 gss_mech_get_by_name +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x8d1a827e svcauth_gss_register_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x968f70cc gss_pseudoflavor_to_service +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xb5dea7ef g_token_size +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xc0d30471 gss_mech_put +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xc956e213 gss_mech_get +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xce78ce47 gss_svc_to_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xf47852fa gss_mech_get_by_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xf8b2ff6e g_verify_token_header +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0235c214 svc_destroy +EXPORT_SYMBOL net/sunrpc/sunrpc 0x03ca79d2 svc_sock_update_bufs +EXPORT_SYMBOL net/sunrpc/sunrpc 0x045249c2 svc_set_client +EXPORT_SYMBOL net/sunrpc/sunrpc 0x05d34b60 xdr_buf_subsegment +EXPORT_SYMBOL net/sunrpc/sunrpc 0x05e807a9 xdr_encode_string +EXPORT_SYMBOL net/sunrpc/sunrpc 0x065994f1 xdr_encode_opaque_fixed +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0be36d8a xdr_inline_decode +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0d1df3a2 auth_domain_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0ec86af9 xdr_read_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0f668ba9 svc_auth_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x12e280e3 svc_proc_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x130c249b sunrpc_cache_update +EXPORT_SYMBOL net/sunrpc/sunrpc 0x13f04e6d xdr_decode_array2 +EXPORT_SYMBOL net/sunrpc/sunrpc 0x13f4208b svc_create +EXPORT_SYMBOL net/sunrpc/sunrpc 0x1daf0be5 read_bytes_from_xdr_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0x1f7a1a8c rpc_mkpipe +EXPORT_SYMBOL net/sunrpc/sunrpc 0x20c6cd09 xdr_inline_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2106f039 xdr_buf_from_iov +EXPORT_SYMBOL net/sunrpc/sunrpc 0x275c89d9 rpc_queue_upcall +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2919b156 xdr_decode_string_inplace +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2eec63c9 xdr_encode_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0x31120e7f xdr_reserve_space +EXPORT_SYMBOL net/sunrpc/sunrpc 0x352cbac8 svc_auth_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0x36638ef3 cache_purge +EXPORT_SYMBOL net/sunrpc/sunrpc 0x3c14b900 auth_unix_add_addr +EXPORT_SYMBOL net/sunrpc/sunrpc 0x42629086 svc_proc_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0x54017fdb auth_domain_put +EXPORT_SYMBOL net/sunrpc/sunrpc 0x560434e9 cache_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x5b09ea1c svc_drop +EXPORT_SYMBOL net/sunrpc/sunrpc 0x6039a6f3 xdr_process_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0x62b8cfa1 rpc_unlink +EXPORT_SYMBOL net/sunrpc/sunrpc 0x663aac66 cache_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0x6eea229d svcauth_unix_purge +EXPORT_SYMBOL net/sunrpc/sunrpc 0x71f0e6a4 xdr_shift_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0x71fa908a cache_flush +EXPORT_SYMBOL net/sunrpc/sunrpc 0x7822e342 auth_unix_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0x7979d756 svc_seq_show +EXPORT_SYMBOL net/sunrpc/sunrpc 0x87142f0b svc_wake_up +EXPORT_SYMBOL net/sunrpc/sunrpc 0x871491d9 svc_authenticate +EXPORT_SYMBOL net/sunrpc/sunrpc 0x8828f38d svc_reserve +EXPORT_SYMBOL net/sunrpc/sunrpc 0x8ad6d324 svc_process +EXPORT_SYMBOL net/sunrpc/sunrpc 0x8b18e8fe xdr_encode_word +EXPORT_SYMBOL net/sunrpc/sunrpc 0x90e07615 svcauth_unix_set_client +EXPORT_SYMBOL net/sunrpc/sunrpc 0x9472eae1 xdr_encode_array2 +EXPORT_SYMBOL net/sunrpc/sunrpc 0x99086309 svc_recv +EXPORT_SYMBOL net/sunrpc/sunrpc 0x9e7f1788 xdr_buf_read_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa29d7fe5 auth_domain_find +EXPORT_SYMBOL net/sunrpc/sunrpc 0xb0b39835 xdr_init_encode +EXPORT_SYMBOL net/sunrpc/sunrpc 0xb7a01afd svc_create_pooled +EXPORT_SYMBOL net/sunrpc/sunrpc 0xbc2ba5cd svc_sock_names +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc2ec27b2 svc_set_num_threads +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc3880471 xdr_decode_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc3a4c7aa xdr_write_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc8e96dea qword_addhex +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc998b2b2 svc_prepare_thread +EXPORT_SYMBOL net/sunrpc/sunrpc 0xd2555a5f auth_unix_forget_old +EXPORT_SYMBOL net/sunrpc/sunrpc 0xd508faa3 xdr_decode_word +EXPORT_SYMBOL net/sunrpc/sunrpc 0xd6f38039 xdr_encode_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe5919cb1 xdr_encode_opaque +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe97f4ce5 qword_get +EXPORT_SYMBOL net/sunrpc/sunrpc 0xea3e7f16 sunrpc_cache_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0xedcf6be4 qword_add +EXPORT_SYMBOL net/sunrpc/sunrpc 0xf4255edc xdr_init_decode +EXPORT_SYMBOL net/sunrpc/sunrpc 0xf495c5a8 cache_check +EXPORT_SYMBOL net/sunrpc/sunrpc 0xf4fa4168 unix_domain_find +EXPORT_SYMBOL net/sunrpc/sunrpc 0xfc8f3bc9 xdr_enter_page +EXPORT_SYMBOL net/sunrpc/sunrpc 0xfd73606b svc_exit_thread +EXPORT_SYMBOL net/tipc/tipc 0x08acf310 tipc_available_nodes +EXPORT_SYMBOL net/tipc/tipc 0x10d40fcd tipc_isconnected +EXPORT_SYMBOL net/tipc/tipc 0x1472b270 tipc_disconnect +EXPORT_SYMBOL net/tipc/tipc 0x1479cb03 tipc_deleteport +EXPORT_SYMBOL net/tipc/tipc 0x15b5ecde tipc_set_portunreliable +EXPORT_SYMBOL net/tipc/tipc 0x16f27683 tipc_block_bearer +EXPORT_SYMBOL net/tipc/tipc 0x21c69462 tipc_reject_msg +EXPORT_SYMBOL net/tipc/tipc 0x259b74f9 tipc_acknowledge +EXPORT_SYMBOL net/tipc/tipc 0x27d8bb58 tipc_send2port +EXPORT_SYMBOL net/tipc/tipc 0x310d1bc9 tipc_detach +EXPORT_SYMBOL net/tipc/tipc 0x3712e340 tipc_portunreliable +EXPORT_SYMBOL net/tipc/tipc 0x3976041f tipc_set_portimportance +EXPORT_SYMBOL net/tipc/tipc 0x4b2243c6 tipc_portimportance +EXPORT_SYMBOL net/tipc/tipc 0x4ba3cfc8 tipc_send2name +EXPORT_SYMBOL net/tipc/tipc 0x538b228a tipc_withdraw +EXPORT_SYMBOL net/tipc/tipc 0x5637ed44 tipc_get_mode +EXPORT_SYMBOL net/tipc/tipc 0x56e52bc1 tipc_continue +EXPORT_SYMBOL net/tipc/tipc 0x5c0d4b5c tipc_ref_valid +EXPORT_SYMBOL net/tipc/tipc 0x62a681a3 tipc_portunreturnable +EXPORT_SYMBOL net/tipc/tipc 0x62f6d70b tipc_send_buf2port +EXPORT_SYMBOL net/tipc/tipc 0x64357d3c tipc_multicast +EXPORT_SYMBOL net/tipc/tipc 0x8001e3d7 tipc_forward2port +EXPORT_SYMBOL net/tipc/tipc 0x8549d40d tipc_forward_buf2port +EXPORT_SYMBOL net/tipc/tipc 0x88b73627 tipc_get_addr +EXPORT_SYMBOL net/tipc/tipc 0x8b2d95d5 tipc_forward_buf2name +EXPORT_SYMBOL net/tipc/tipc 0x8d1fc13e tipc_send_buf2name +EXPORT_SYMBOL net/tipc/tipc 0x9c044d7e tipc_createport +EXPORT_SYMBOL net/tipc/tipc 0x9c45558e tipc_enable_bearer +EXPORT_SYMBOL net/tipc/tipc 0x9fcedd5b tipc_recv_msg +EXPORT_SYMBOL net/tipc/tipc 0xa936a24b tipc_get_port +EXPORT_SYMBOL net/tipc/tipc 0xaa73fe8e tipc_createport_raw +EXPORT_SYMBOL net/tipc/tipc 0xadd203d0 tipc_connect2port +EXPORT_SYMBOL net/tipc/tipc 0xae0103c3 tipc_shutdown +EXPORT_SYMBOL net/tipc/tipc 0xb01ffc2c tipc_forward2name +EXPORT_SYMBOL net/tipc/tipc 0xb35b672c tipc_publish +EXPORT_SYMBOL net/tipc/tipc 0xbb2b2504 tipc_send +EXPORT_SYMBOL net/tipc/tipc 0xcec8514a tipc_set_portunreturnable +EXPORT_SYMBOL net/tipc/tipc 0xd44731e5 tipc_ownidentity +EXPORT_SYMBOL net/tipc/tipc 0xda7f9d3f tipc_attach +EXPORT_SYMBOL net/tipc/tipc 0xdf5008fc tipc_peer +EXPORT_SYMBOL net/tipc/tipc 0xe2c78859 tipc_send_buf_fast +EXPORT_SYMBOL net/tipc/tipc 0xe7aece47 tipc_ispublished +EXPORT_SYMBOL net/tipc/tipc 0xeefd49b3 tipc_get_handle +EXPORT_SYMBOL net/tipc/tipc 0xef50a1ef tipc_disable_bearer +EXPORT_SYMBOL net/tipc/tipc 0xfaa9b8ae tipc_send_buf +EXPORT_SYMBOL net/tipc/tipc 0xfb1d769e tipc_register_media +EXPORT_SYMBOL net/wireless/cfg80211 0x039939b6 __ieee80211_get_channel +EXPORT_SYMBOL net/wireless/cfg80211 0x07e7ac5a ieee80211_radiotap_iterator_init +EXPORT_SYMBOL net/wireless/cfg80211 0x09c64fbd ieee80211_frequency_to_channel +EXPORT_SYMBOL net/wireless/cfg80211 0x5e04bc34 wiphy_new +EXPORT_SYMBOL net/wireless/cfg80211 0x78b7e8dd wiphy_free +EXPORT_SYMBOL net/wireless/cfg80211 0x8b5cf649 regulatory_hint +EXPORT_SYMBOL net/wireless/cfg80211 0xa104c3c1 wiphy_register +EXPORT_SYMBOL net/wireless/cfg80211 0xc4e85ec5 ieee80211_radiotap_iterator_next +EXPORT_SYMBOL net/wireless/cfg80211 0xccc291b3 ieee80211_channel_to_frequency +EXPORT_SYMBOL net/wireless/cfg80211 0xf59ca15b wiphy_unregister +EXPORT_SYMBOL sound/ac97_bus 0x3d4b5446 ac97_bus_type +EXPORT_SYMBOL sound/core/oss/snd-mixer-oss 0xbb15a8ef snd_mixer_oss_ioctl_card +EXPORT_SYMBOL sound/core/seq/snd-seq 0x0cc54f89 snd_seq_event_port_attach +EXPORT_SYMBOL sound/core/seq/snd-seq 0x1a724fcc snd_seq_kernel_client_ctl +EXPORT_SYMBOL sound/core/seq/snd-seq 0x3061c52d snd_use_lock_sync_helper +EXPORT_SYMBOL sound/core/seq/snd-seq 0x3659c84d snd_seq_kernel_client_write_poll +EXPORT_SYMBOL sound/core/seq/snd-seq 0x3fb4d161 snd_seq_kernel_client_dispatch +EXPORT_SYMBOL sound/core/seq/snd-seq 0x6bb71038 snd_seq_delete_kernel_client +EXPORT_SYMBOL sound/core/seq/snd-seq 0x7ac2f329 snd_seq_expand_var_event +EXPORT_SYMBOL sound/core/seq/snd-seq 0x7b8699eb snd_seq_event_port_detach +EXPORT_SYMBOL sound/core/seq/snd-seq 0x966b7197 snd_seq_create_kernel_client +EXPORT_SYMBOL sound/core/seq/snd-seq 0xb8e448a0 snd_seq_set_queue_tempo +EXPORT_SYMBOL sound/core/seq/snd-seq 0xcac0a3be snd_seq_kernel_client_enqueue +EXPORT_SYMBOL sound/core/seq/snd-seq 0xd243935a snd_seq_kernel_client_enqueue_blocking +EXPORT_SYMBOL sound/core/seq/snd-seq 0xe934da1d snd_seq_dump_var_event +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x01b3b672 snd_seq_device_new +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x3a57f235 snd_seq_autoload_unlock +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x5d26141d snd_seq_device_register_driver +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x6339b6d0 snd_seq_device_load_drivers +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xb90668b2 snd_seq_autoload_lock +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xc622fb29 snd_seq_device_unregister_driver +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0x6ea09972 snd_midi_channel_alloc_set +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0x833a3e07 snd_midi_channel_set_clear +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0xb9948d2c snd_midi_channel_free_set +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0xf0a1fdb3 snd_midi_process_event +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x17c15809 snd_midi_event_decode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x4ad3f518 snd_midi_event_reset_decode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x62384d3a snd_midi_event_encode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x8a348811 snd_midi_event_reset_encode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x9df7af8b snd_midi_event_free +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xc482499d snd_midi_event_new +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xd9072e1a snd_midi_event_no_status +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xe6df29c7 snd_midi_event_encode_byte +EXPORT_SYMBOL sound/core/seq/snd-seq-virmidi 0x32117aef snd_virmidi_new +EXPORT_SYMBOL sound/core/snd 0x0704538a snd_ctl_rename_id +EXPORT_SYMBOL sound/core/snd 0x0fc1fb57 snd_ctl_unregister_ioctl +EXPORT_SYMBOL sound/core/snd 0x1290089b snd_card_file_remove +EXPORT_SYMBOL sound/core/snd 0x12ae760d snd_ctl_add +EXPORT_SYMBOL sound/core/snd 0x18e1683f snd_dma_program +EXPORT_SYMBOL sound/core/snd 0x191e88cf snd_dma_pointer +EXPORT_SYMBOL sound/core/snd 0x1977cf56 snd_card_file_add +EXPORT_SYMBOL sound/core/snd 0x198788b4 snd_lookup_oss_minor_data +EXPORT_SYMBOL sound/core/snd 0x24a94b26 snd_info_get_line +EXPORT_SYMBOL sound/core/snd 0x259ff942 snd_card_proc_new +EXPORT_SYMBOL sound/core/snd 0x2802390f snd_device_register +EXPORT_SYMBOL sound/core/snd 0x2812d3f4 snd_register_oss_device +EXPORT_SYMBOL sound/core/snd 0x293d895e snd_power_wait +EXPORT_SYMBOL sound/core/snd 0x2a5680a8 snd_info_free_entry +EXPORT_SYMBOL sound/core/snd 0x2caf3949 snd_ctl_add_slave +EXPORT_SYMBOL sound/core/snd 0x2e235a8a snd_ctl_register_ioctl +EXPORT_SYMBOL sound/core/snd 0x31d38820 snd_ctl_make_virtual_master +EXPORT_SYMBOL sound/core/snd 0x32597317 snd_card_free_when_closed +EXPORT_SYMBOL sound/core/snd 0x3486c589 snd_info_register +EXPORT_SYMBOL sound/core/snd 0x3971b4df snd_ecards_limit +EXPORT_SYMBOL sound/core/snd 0x3c5514ef snd_unregister_oss_device +EXPORT_SYMBOL sound/core/snd 0x47f30be7 snd_ctl_find_numid +EXPORT_SYMBOL sound/core/snd 0x485a9969 snd_info_create_module_entry +EXPORT_SYMBOL sound/core/snd 0x4a3ea5c0 snd_request_card +EXPORT_SYMBOL sound/core/snd 0x4a7f71a0 snd_card_free +EXPORT_SYMBOL sound/core/snd 0x4c8ba1da snd_card_new +EXPORT_SYMBOL sound/core/snd 0x502e26ed snd_add_device_sysfs_file +EXPORT_SYMBOL sound/core/snd 0x52a8cf4f snd_seq_root +EXPORT_SYMBOL sound/core/snd 0x5968827b snd_unregister_device +EXPORT_SYMBOL sound/core/snd 0x5ece07c7 snd_ctl_boolean_mono_info +EXPORT_SYMBOL sound/core/snd 0x602c96f0 copy_to_user_fromio +EXPORT_SYMBOL sound/core/snd 0x61014d6f snd_info_create_card_entry +EXPORT_SYMBOL sound/core/snd 0x70c15ac1 snd_dma_disable +EXPORT_SYMBOL sound/core/snd 0x80f7c7f4 snd_cards +EXPORT_SYMBOL sound/core/snd 0x8c46ea1f snd_ctl_find_id +EXPORT_SYMBOL sound/core/snd 0x8cd359bb snd_device_free +EXPORT_SYMBOL sound/core/snd 0x8cdd8abe snd_ctl_notify +EXPORT_SYMBOL sound/core/snd 0x8df3789f snd_oss_info_register +EXPORT_SYMBOL sound/core/snd 0x8f595b11 snd_major +EXPORT_SYMBOL sound/core/snd 0xa695ae12 snd_ctl_free_one +EXPORT_SYMBOL sound/core/snd 0xb213fe8b snd_info_get_str +EXPORT_SYMBOL sound/core/snd 0xb2e5ae4a snd_lookup_minor_data +EXPORT_SYMBOL sound/core/snd 0xc9a33e29 snd_component_add +EXPORT_SYMBOL sound/core/snd 0xce3ca308 copy_from_user_toio +EXPORT_SYMBOL sound/core/snd 0xd1157735 release_and_free_resource +EXPORT_SYMBOL sound/core/snd 0xd9117d9d snd_ctl_new1 +EXPORT_SYMBOL sound/core/snd 0xd997cec7 snd_card_register +EXPORT_SYMBOL sound/core/snd 0xe030ab96 snd_device_new +EXPORT_SYMBOL sound/core/snd 0xe103fde8 snd_ctl_remove_id +EXPORT_SYMBOL sound/core/snd 0xe19888ae snd_ctl_remove +EXPORT_SYMBOL sound/core/snd 0xe4854cea snd_iprintf +EXPORT_SYMBOL sound/core/snd 0xe4c3266e snd_mixer_oss_notify_callback +EXPORT_SYMBOL sound/core/snd 0xea80fb46 snd_register_device_for_dev +EXPORT_SYMBOL sound/core/snd 0xef080655 snd_ctl_boolean_stereo_info +EXPORT_SYMBOL sound/core/snd 0xf148b599 snd_card_disconnect +EXPORT_SYMBOL sound/core/snd 0xf7963f93 snd_pci_quirk_lookup +EXPORT_SYMBOL sound/core/snd-hwdep 0x7f5917f5 snd_hwdep_new +EXPORT_SYMBOL sound/core/snd-page-alloc 0x287e7cf1 snd_dma_free_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0x3b91f3af snd_free_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0x3bbd4e13 snd_dma_alloc_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0x51e38301 snd_dma_alloc_pages_fallback +EXPORT_SYMBOL sound/core/snd-page-alloc 0x68a25773 snd_dma_reserve_buf +EXPORT_SYMBOL sound/core/snd-page-alloc 0x8b99e0e9 snd_dma_get_reserved_buf +EXPORT_SYMBOL sound/core/snd-page-alloc 0xade88e76 snd_malloc_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x00f590a1 snd_pcm_lib_malloc_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x03fc7488 snd_pcm_lib_free_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x04cda566 snd_interval_refine +EXPORT_SYMBOL sound/core/snd-pcm 0x0d843136 snd_pcm_release_substream +EXPORT_SYMBOL sound/core/snd-pcm 0x12deb5ed snd_pcm_set_ops +EXPORT_SYMBOL sound/core/snd-pcm 0x1d027e4b snd_pcm_format_signed +EXPORT_SYMBOL sound/core/snd-pcm 0x1face6d9 snd_pcm_mmap_data +EXPORT_SYMBOL sound/core/snd-pcm 0x23dc4db0 snd_pcm_lib_writev +EXPORT_SYMBOL sound/core/snd-pcm 0x28a5a235 snd_pcm_stop +EXPORT_SYMBOL sound/core/snd-pcm 0x3260f427 snd_pcm_limit_hw_rates +EXPORT_SYMBOL sound/core/snd-pcm 0x3796bdcc snd_pcm_format_little_endian +EXPORT_SYMBOL sound/core/snd-pcm 0x40210a92 snd_pcm_lib_ioctl +EXPORT_SYMBOL sound/core/snd-pcm 0x42ef15b0 snd_pcm_lib_read +EXPORT_SYMBOL sound/core/snd-pcm 0x43e47fff snd_pcm_notify +EXPORT_SYMBOL sound/core/snd-pcm 0x4c162148 snd_pcm_hw_constraint_integer +EXPORT_SYMBOL sound/core/snd-pcm 0x4d701e7a snd_pcm_sgbuf_ops_page +EXPORT_SYMBOL sound/core/snd-pcm 0x4d9b6d35 snd_pcm_format_size +EXPORT_SYMBOL sound/core/snd-pcm 0x4f816e9b snd_pcm_format_big_endian +EXPORT_SYMBOL sound/core/snd-pcm 0x54972171 snd_pcm_lib_write +EXPORT_SYMBOL sound/core/snd-pcm 0x57348ca4 snd_pcm_sgbuf_get_chunk_size +EXPORT_SYMBOL sound/core/snd-pcm 0x59ac0379 snd_pcm_suspend_all +EXPORT_SYMBOL sound/core/snd-pcm 0x5abeadca snd_pcm_hw_rule_add +EXPORT_SYMBOL sound/core/snd-pcm 0x5d9bc399 snd_pcm_hw_constraint_ratdens +EXPORT_SYMBOL sound/core/snd-pcm 0x5decf384 snd_pcm_hw_constraint_msbits +EXPORT_SYMBOL sound/core/snd-pcm 0x5e7f4920 snd_pcm_format_set_silence +EXPORT_SYMBOL sound/core/snd-pcm 0x63ef21a2 snd_pcm_lib_readv +EXPORT_SYMBOL sound/core/snd-pcm 0x63f51c49 snd_pcm_hw_param_value +EXPORT_SYMBOL sound/core/snd-pcm 0x6405ff7a snd_pcm_lib_preallocate_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x650f8603 snd_pcm_format_silence_64 +EXPORT_SYMBOL sound/core/snd-pcm 0x67f4dacc snd_pcm_hw_param_first +EXPORT_SYMBOL sound/core/snd-pcm 0x68a24153 snd_pcm_format_physical_width +EXPORT_SYMBOL sound/core/snd-pcm 0x6ef8fcd8 snd_pcm_format_linear +EXPORT_SYMBOL sound/core/snd-pcm 0x72997c0e snd_pcm_hw_constraint_pow2 +EXPORT_SYMBOL sound/core/snd-pcm 0x77b9ccac _snd_pcm_hw_param_setempty +EXPORT_SYMBOL sound/core/snd-pcm 0x78c7ddcd snd_pcm_hw_param_last +EXPORT_SYMBOL sound/core/snd-pcm 0x79519b39 snd_pcm_new +EXPORT_SYMBOL sound/core/snd-pcm 0x8322fa1c snd_pcm_suspend +EXPORT_SYMBOL sound/core/snd-pcm 0x851dd597 snd_pcm_lib_preallocate_pages_for_all +EXPORT_SYMBOL sound/core/snd-pcm 0x88cc66cc snd_pcm_link_rwlock +EXPORT_SYMBOL sound/core/snd-pcm 0x9330fc10 snd_pcm_open_substream +EXPORT_SYMBOL sound/core/snd-pcm 0x952d5f21 _snd_pcm_hw_params_any +EXPORT_SYMBOL sound/core/snd-pcm 0x9b17a284 snd_pcm_lib_mmap_iomem +EXPORT_SYMBOL sound/core/snd-pcm 0xa140d091 snd_pcm_kernel_ioctl +EXPORT_SYMBOL sound/core/snd-pcm 0xa61aa028 snd_pcm_format_unsigned +EXPORT_SYMBOL sound/core/snd-pcm 0xaf3d0574 snd_pcm_hw_refine +EXPORT_SYMBOL sound/core/snd-pcm 0xb5d62baa snd_pcm_hw_constraint_step +EXPORT_SYMBOL sound/core/snd-pcm 0xb9638db4 snd_pcm_rate_to_rate_bit +EXPORT_SYMBOL sound/core/snd-pcm 0xba1f6c94 snd_pcm_period_elapsed +EXPORT_SYMBOL sound/core/snd-pcm 0xcee9476c snd_pcm_new_stream +EXPORT_SYMBOL sound/core/snd-pcm 0xd0b9b8b8 snd_interval_list +EXPORT_SYMBOL sound/core/snd-pcm 0xd6e807de snd_pcm_hw_constraint_ratnums +EXPORT_SYMBOL sound/core/snd-pcm 0xe4e4ac75 snd_pcm_set_sync +EXPORT_SYMBOL sound/core/snd-pcm 0xe56a9336 snd_pcm_format_width +EXPORT_SYMBOL sound/core/snd-pcm 0xeaea0ac2 snd_pcm_hw_constraint_minmax +EXPORT_SYMBOL sound/core/snd-pcm 0xf10aea4e snd_pcm_lib_preallocate_free_for_all +EXPORT_SYMBOL sound/core/snd-pcm 0xf3797152 snd_interval_ratnum +EXPORT_SYMBOL sound/core/snd-pcm 0xfa0bfeb9 snd_pcm_hw_constraint_list +EXPORT_SYMBOL sound/core/snd-rawmidi 0x03592b64 snd_rawmidi_input_params +EXPORT_SYMBOL sound/core/snd-rawmidi 0x0a270437 snd_rawmidi_transmit_ack +EXPORT_SYMBOL sound/core/snd-rawmidi 0x0c6849d0 snd_rawmidi_drop_output +EXPORT_SYMBOL sound/core/snd-rawmidi 0x17fcf788 snd_rawmidi_set_ops +EXPORT_SYMBOL sound/core/snd-rawmidi 0x1895d3e9 snd_rawmidi_receive +EXPORT_SYMBOL sound/core/snd-rawmidi 0x2f12c88b snd_rawmidi_drain_output +EXPORT_SYMBOL sound/core/snd-rawmidi 0x44790d3e snd_rawmidi_transmit +EXPORT_SYMBOL sound/core/snd-rawmidi 0x521a6cad snd_rawmidi_kernel_write +EXPORT_SYMBOL sound/core/snd-rawmidi 0x6a336e3d snd_rawmidi_kernel_read +EXPORT_SYMBOL sound/core/snd-rawmidi 0x7071e49a snd_rawmidi_kernel_open +EXPORT_SYMBOL sound/core/snd-rawmidi 0x80d44cd7 snd_rawmidi_kernel_release +EXPORT_SYMBOL sound/core/snd-rawmidi 0x8250fa60 snd_rawmidi_new +EXPORT_SYMBOL sound/core/snd-rawmidi 0x8e9e71e6 snd_rawmidi_transmit_peek +EXPORT_SYMBOL sound/core/snd-rawmidi 0xa27e165f snd_rawmidi_drain_input +EXPORT_SYMBOL sound/core/snd-rawmidi 0xb91b5070 snd_rawmidi_transmit_empty +EXPORT_SYMBOL sound/core/snd-rawmidi 0xd491f43f snd_rawmidi_info_select +EXPORT_SYMBOL sound/core/snd-rawmidi 0xe713f7bd snd_rawmidi_output_params +EXPORT_SYMBOL sound/core/snd-timer 0x01f09826 snd_timer_start +EXPORT_SYMBOL sound/core/snd-timer 0x125c2bd6 snd_timer_continue +EXPORT_SYMBOL sound/core/snd-timer 0x18958f5d snd_timer_new +EXPORT_SYMBOL sound/core/snd-timer 0x46dac2aa snd_timer_pause +EXPORT_SYMBOL sound/core/snd-timer 0x52096398 snd_timer_stop +EXPORT_SYMBOL sound/core/snd-timer 0x9754f905 snd_timer_global_free +EXPORT_SYMBOL sound/core/snd-timer 0xaa28fe68 snd_timer_notify +EXPORT_SYMBOL sound/core/snd-timer 0xad07e02d snd_timer_resolution +EXPORT_SYMBOL sound/core/snd-timer 0xbc1b308e snd_timer_interrupt +EXPORT_SYMBOL sound/core/snd-timer 0xd8e52381 snd_timer_global_new +EXPORT_SYMBOL sound/core/snd-timer 0xdb09f612 snd_timer_open +EXPORT_SYMBOL sound/core/snd-timer 0xe6523da7 snd_timer_global_register +EXPORT_SYMBOL sound/core/snd-timer 0xffa27663 snd_timer_close +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0x0abda3a6 snd_mpu401_uart_new +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0x73c4c993 snd_mpu401_uart_interrupt_tx +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0xfe618b58 snd_mpu401_uart_interrupt +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x02f7b431 snd_opl3_new +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x05060a19 snd_opl3_regmap +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x0da7fd87 snd_opl3_interrupt +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x128e9c1f snd_opl3_reset +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x308b680f snd_opl3_find_patch +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x31b11b47 snd_opl3_timer_new +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0xa87e9dea snd_opl3_init +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0xad4cb456 snd_opl3_hwdep_new +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0xd11f6cb5 snd_opl3_create +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0xdccabfca snd_opl3_load_patch +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x00930050 snd_vx_dsp_boot +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x1cadb14b snd_vx_irq_handler +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x409defbc snd_vx_resume +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x46976678 snd_vx_setup_firmware +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x5dd137b0 snd_vx_suspend +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x68b17557 snd_vx_check_reg_bit +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x873a06b1 snd_vx_free_firmware +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xacf281d6 snd_vx_dsp_load +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xd7911163 snd_vx_create +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xd8606a54 snd_vx_load_boot_image +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x0f0b8df3 snd_ak4114_reinit +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x160bb4a6 snd_ak4114_build +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x4a14723d snd_ak4114_reg_write +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x7dd87252 snd_ak4114_create +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x85fe2bb5 snd_ak4114_check_rate_and_errors +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0xbc7868c0 snd_ak4114_external_rate +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0x14464f1c snd_akm4xxx_write +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0x5742730c snd_akm4xxx_init +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0xb1e9ae04 snd_akm4xxx_reset +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0xed4d2ff3 snd_akm4xxx_build_controls +EXPORT_SYMBOL sound/i2c/other/snd-pt2258 0x31e1d4fc snd_pt2258_reset +EXPORT_SYMBOL sound/i2c/other/snd-pt2258 0x40ad5bbc snd_pt2258_build_controls +EXPORT_SYMBOL sound/i2c/other/snd-tea575x-tuner 0x248bf54c snd_tea575x_init +EXPORT_SYMBOL sound/i2c/other/snd-tea575x-tuner 0x3abd10b2 snd_tea575x_exit +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x07d6f3de snd_cs8427_iec958_build +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x20d14c71 snd_cs8427_create +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x2d367194 snd_cs8427_iec958_pcm +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x4da0bdd1 snd_cs8427_iec958_active +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x75ecb73c snd_cs8427_reg_write +EXPORT_SYMBOL sound/i2c/snd-i2c 0x2fd7b1e2 snd_i2c_readbytes +EXPORT_SYMBOL sound/i2c/snd-i2c 0x4cbf7027 snd_i2c_device_free +EXPORT_SYMBOL sound/i2c/snd-i2c 0x5eb6c927 snd_i2c_probeaddr +EXPORT_SYMBOL sound/i2c/snd-i2c 0x639d7c84 snd_i2c_sendbytes +EXPORT_SYMBOL sound/i2c/snd-i2c 0x708dfbd0 snd_i2c_bus_create +EXPORT_SYMBOL sound/i2c/snd-i2c 0xdf02fb32 snd_i2c_device_create +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x05c155f8 snd_sbmixer_suspend +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x0a453152 snd_sbdsp_create +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x241a8e86 snd_sbmixer_add_ctl +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x775090ff snd_sbdsp_get_byte +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x80efcc55 snd_sbdsp_command +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x855f0597 snd_sbmixer_read +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x8a34c850 snd_sbmixer_write +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x9a089b35 snd_sbmixer_resume +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xab65faf7 snd_sbdsp_reset +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xeb3affa4 snd_sbmixer_new +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0x0ba4ef1d snd_sb16dsp_interrupt +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0x235e90b7 snd_sb16dsp_pcm +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0x39830559 snd_sb16dsp_configure +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0x60f7b447 snd_sb16dsp_get_pcm_ops +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x0181ffb5 snd_ac97_write_cache +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x177cabf3 snd_ac97_pcm_assign +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x30858ef0 snd_ac97_get_short_name +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x3aee543b snd_ac97_pcm_double_rate_rules +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x46e6a84f snd_ac97_set_rate +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x59369ff9 snd_ac97_bus +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x5dac563a snd_ac97_resume +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x6f91bc4c snd_ac97_mixer +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x77200daa snd_ac97_pcm_open +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x7ccf949e snd_ac97_read +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x8d0286ea snd_ac97_tune_hardware +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xc8d3c028 snd_ac97_update_power +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xcde6bf5b snd_ac97_update +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xd3fd0710 snd_ac97_update_bits +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xeb09b494 snd_ac97_suspend +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xf41e25c2 snd_ac97_write +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xfd1ffd1a snd_ac97_pcm_close +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x27cb15a6 snd_emu10k1_ptr_read +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x33d26b4b snd_emu10k1_synth_copy_from_user +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x3b2fb154 snd_emu10k1_synth_bzero +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x4e22dd3f snd_emu10k1_memblk_map +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x86b2ec2c snd_emu10k1_voice_alloc +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x8977cd7e snd_emu10k1_ptr_write +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x99d143c9 snd_emu10k1_voice_free +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xd5d1ce95 snd_emu10k1_synth_alloc +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xe48c7e4c snd_emu10k1_synth_free +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0xa3c3dfc6 snd_ice1712_akm4xxx_build_controls +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0xd4ae2b77 snd_ice1712_akm4xxx_init +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0xe9873479 snd_ice1712_akm4xxx_free +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x03fa39a5 oxygen_write32 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x04b347d2 oxygen_write32_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x1d6f34cd oxygen_write8 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x24da459c oxygen_write_uart +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x29145fae oxygen_pci_suspend +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x5b9c013d oxygen_read16 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x63d8762b oxygen_write_ac97_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x671e9c7d oxygen_write_spi +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x6f59ba13 oxygen_reset_uart +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x73ccae2b oxygen_read8 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x7a65c56b oxygen_write_i2c +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x8c6835ee oxygen_pci_resume +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xaf1f5d7b oxygen_read_ac97 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xb19333c7 oxygen_write16 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xc22fbd5f oxygen_pci_remove +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xd97f3ade oxygen_pci_probe +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xde3a9eec oxygen_write8_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xde94845c oxygen_write_ac97 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xeb914c1b oxygen_read32 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xf348a2df oxygen_write16_masked +EXPORT_SYMBOL sound/pci/trident/snd-trident 0x2aa2bff1 snd_trident_stop_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0x4b5fe76f snd_trident_write_voice_regs +EXPORT_SYMBOL sound/pci/trident/snd-trident 0x4f7a30ae snd_trident_free_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0x76ae6fea snd_trident_alloc_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0xf2e7730d snd_trident_start_voice +EXPORT_SYMBOL sound/soundcore 0x01679e50 register_sound_special +EXPORT_SYMBOL sound/soundcore 0x086e82f7 register_sound_midi +EXPORT_SYMBOL sound/soundcore 0x14e64988 register_sound_special_device +EXPORT_SYMBOL sound/soundcore 0x28afed7b register_sound_mixer +EXPORT_SYMBOL sound/soundcore 0x7afc9d8a unregister_sound_mixer +EXPORT_SYMBOL sound/soundcore 0x99c95fa5 unregister_sound_special +EXPORT_SYMBOL sound/soundcore 0xb74ed08f sound_class +EXPORT_SYMBOL sound/soundcore 0xcd083b10 unregister_sound_dsp +EXPORT_SYMBOL sound/soundcore 0xd1fb2c2f register_sound_dsp +EXPORT_SYMBOL sound/soundcore 0xfdab6de3 unregister_sound_midi +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x09bd0a91 snd_emux_terminate_all +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x09d365e9 snd_emux_new +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x107a88d6 snd_emux_lock_voice +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x655cb202 snd_sf_linear_to_log +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x8c013477 snd_emux_unlock_voice +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0xa7ff48b0 snd_emux_free +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0xc9b866c0 snd_emux_register +EXPORT_SYMBOL sound/synth/snd-util-mem 0x20d65978 snd_util_memhdr_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0x24886293 __snd_util_mem_alloc +EXPORT_SYMBOL sound/synth/snd-util-mem 0x569d614e snd_util_mem_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0x7a007343 snd_util_memhdr_new +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd197c5db __snd_util_memblk_new +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd34b56e4 __snd_util_mem_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd8b55e81 snd_util_mem_alloc +EXPORT_SYMBOL sound/synth/snd-util-mem 0xf158252c snd_util_mem_avail +EXPORT_SYMBOL sound/usb/snd-usb-lib 0x16756dc0 snd_usbmidi_input_start +EXPORT_SYMBOL sound/usb/snd-usb-lib 0x63343b1d snd_usbmidi_input_stop +EXPORT_SYMBOL sound/usb/snd-usb-lib 0xbd63c9ca snd_usb_create_midi_interface +EXPORT_SYMBOL sound/usb/snd-usb-lib 0xd9d2bb03 snd_usbmidi_disconnect +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x1ac3c419 dm_mem_cache_alloc +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x57541335 dm_mem_cache_client_destroy +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x664a7372 dm_mem_cache_free +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xafa56eee dm_mem_cache_shrink +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xc729c08f dm_mem_cache_client_create +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xf607e2c8 dm_mem_cache_grow +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-message 0x920a7a41 dm_message_parse +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x0329d132 rh_sector_to_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x108f2649 rh_dec +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x1c878cfe rh_bio_to_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x22f11f50 rh_delay +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x275fdd04 rh_recovery_start +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x344f225b rh_init +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x5c2a0632 rh_recovery_end +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x62842029 rh_flush +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x787877fb rh_inc_pending +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x8252ef05 rh_state +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x8821f9a7 rh_region_to_sector +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xa4a7321f rh_get_region_key +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xa923d788 rh_start_recovery +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xac274ed3 rh_stop_recovery +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xb513be98 rh_update_states +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xbb748327 rh_reg_set_context +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc4fdf256 rh_recovery_prepare +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc4ff7745 rh_reg_get_context +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc57bafec rh_exit +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc6a4b5b3 rh_delay_by_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xd99f0978 rh_inc +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xda581f7b rh_get_region_size +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x29c887a9 set_tx_channels +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x60b2e316 cmdir_read +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x7789312a cmdir_write +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0xd953a786 lirc_register_plugin +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0xe278ed43 lirc_get_pdata +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0xe96379eb lirc_unregister_plugin +EXPORT_SYMBOL ubuntu/misc/media/ov511/ov511 0x7db9be3c ov511_deregister_decomp_module +EXPORT_SYMBOL ubuntu/misc/media/ov511/ov511 0xb08da7fc ov511_register_decomp_module +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x1d44bbba p80211_resume +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x283215d6 p80211netdev_rx +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x32c05101 p80211_suspend +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x418a88da p80211netdev_hwremoved +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x7af19ac7 p80211skb_rxmeta_attach +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x8512b5df register_wlandev +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x945d8dc0 p80211wext_event_associated +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x971e9d92 p80211skb_free +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xb0af0799 wlan_wext_write +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xb8a7a18e p80211_allow_ioctls +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xbdad3640 wlan_unsetup +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xc5e779cc wlan_setup +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xccfc8534 unregister_wlandev +EXPORT_SYMBOL vmlinux 0x00000000 per_cpu__softirq_work_list +EXPORT_SYMBOL vmlinux 0x000cae37 neigh_connected_output +EXPORT_SYMBOL vmlinux 0x00112f51 groups_alloc +EXPORT_SYMBOL vmlinux 0x005ea755 tcp_setsockopt +EXPORT_SYMBOL vmlinux 0x00701c0f put_io_context +EXPORT_SYMBOL vmlinux 0x007a6685 rtnl_notify +EXPORT_SYMBOL vmlinux 0x007b6818 nf_register_queue_handler +EXPORT_SYMBOL vmlinux 0x00801678 flush_scheduled_work +EXPORT_SYMBOL vmlinux 0x0080fcd6 tcf_hash_release +EXPORT_SYMBOL vmlinux 0x009d258f _write_lock +EXPORT_SYMBOL vmlinux 0x00c3b220 register_con_driver +EXPORT_SYMBOL vmlinux 0x00e0dc7a jbd2_journal_get_write_access +EXPORT_SYMBOL vmlinux 0x00e8097b csum_partial_copy_fromiovecend +EXPORT_SYMBOL vmlinux 0x00f293d9 pnp_activate_dev +EXPORT_SYMBOL vmlinux 0x01139ffc max_mapnr +EXPORT_SYMBOL vmlinux 0x013255ce do_sync_write +EXPORT_SYMBOL vmlinux 0x0168a71f blk_queue_invalidate_tags +EXPORT_SYMBOL vmlinux 0x0186d073 percpu_counter_set +EXPORT_SYMBOL vmlinux 0x01902adf netpoll_trap +EXPORT_SYMBOL vmlinux 0x01987844 dma_alloc_from_coherent +EXPORT_SYMBOL vmlinux 0x01a4aab6 set_irq_chip_data +EXPORT_SYMBOL vmlinux 0x01b1107d skb_split +EXPORT_SYMBOL vmlinux 0x01c2a014 unregister_netdevice +EXPORT_SYMBOL vmlinux 0x01d19038 acpi_enable_subsystem +EXPORT_SYMBOL vmlinux 0x020ce349 pci_iounmap +EXPORT_SYMBOL vmlinux 0x02124474 ip_send_check +EXPORT_SYMBOL vmlinux 0x0225f982 block_page_mkwrite +EXPORT_SYMBOL vmlinux 0x0237b57a arch_unregister_cpu +EXPORT_SYMBOL vmlinux 0x02419cfa __inet6_hash +EXPORT_SYMBOL vmlinux 0x025277f6 profile_pc +EXPORT_SYMBOL vmlinux 0x0256389f bit_waitqueue +EXPORT_SYMBOL vmlinux 0x02649054 security_sock_rcv_skb +EXPORT_SYMBOL vmlinux 0x02731a67 dquot_free_space +EXPORT_SYMBOL vmlinux 0x0276c8e1 free_buffer_head +EXPORT_SYMBOL vmlinux 0x029444f0 native_read_tsc +EXPORT_SYMBOL vmlinux 0x02a18c74 nf_conntrack_destroy +EXPORT_SYMBOL vmlinux 0x02a6ce5a crc16_table +EXPORT_SYMBOL vmlinux 0x02aff2f4 acpi_install_gpe_handler +EXPORT_SYMBOL vmlinux 0x02d81845 audit_log_task_context +EXPORT_SYMBOL vmlinux 0x02e0d380 pci_disable_msix +EXPORT_SYMBOL vmlinux 0x02e1ea6d journal_create +EXPORT_SYMBOL vmlinux 0x02ee26c1 free_pages_exact +EXPORT_SYMBOL vmlinux 0x02f40f24 fb_set_suspend +EXPORT_SYMBOL vmlinux 0x02f5063c __serio_register_port +EXPORT_SYMBOL vmlinux 0x0334da4e scsi_command_size_tbl +EXPORT_SYMBOL vmlinux 0x037a0cba kfree +EXPORT_SYMBOL vmlinux 0x03a99c3b rb_prev +EXPORT_SYMBOL vmlinux 0x03b49251 brioctl_set +EXPORT_SYMBOL vmlinux 0x03c06156 bitmap_fold +EXPORT_SYMBOL vmlinux 0x03fd2571 vm_unmap_ram +EXPORT_SYMBOL vmlinux 0x0422fe4a inet_csk_timer_bug_msg +EXPORT_SYMBOL vmlinux 0x042ede82 fb_validate_mode +EXPORT_SYMBOL vmlinux 0x044fbf49 mempool_kzalloc +EXPORT_SYMBOL vmlinux 0x0476c12d tty_get_baud_rate +EXPORT_SYMBOL vmlinux 0x0487f831 fb_find_best_display +EXPORT_SYMBOL vmlinux 0x04aab44d vm_map_ram +EXPORT_SYMBOL vmlinux 0x04afc394 proc_symlink +EXPORT_SYMBOL vmlinux 0x04b975c2 generic_file_splice_write_nolock +EXPORT_SYMBOL vmlinux 0x04cf86c5 set_pages_nx +EXPORT_SYMBOL vmlinux 0x04d8c750 release_perfctr_nmi +EXPORT_SYMBOL vmlinux 0x04f6b1dd elevator_init +EXPORT_SYMBOL vmlinux 0x0523d549 mca_device_set_name +EXPORT_SYMBOL vmlinux 0x053ea817 mmc_remove_host +EXPORT_SYMBOL vmlinux 0x0560cdeb xfrm_state_flush +EXPORT_SYMBOL vmlinux 0x0562c107 generic_file_splice_write +EXPORT_SYMBOL vmlinux 0x057ce975 hex_dump_to_buffer +EXPORT_SYMBOL vmlinux 0x05820699 blk_get_backing_dev_info +EXPORT_SYMBOL vmlinux 0x0586aeea take_over_console +EXPORT_SYMBOL vmlinux 0x058c75d9 acpi_get_pci_id +EXPORT_SYMBOL vmlinux 0x05b0320d nf_hook_slow +EXPORT_SYMBOL vmlinux 0x05c329e4 pnp_find_card +EXPORT_SYMBOL vmlinux 0x05d0e369 __inc_zone_page_state +EXPORT_SYMBOL vmlinux 0x05e28d43 __first_cpu +EXPORT_SYMBOL vmlinux 0x05e7c570 xfrm_find_acq_byseq +EXPORT_SYMBOL vmlinux 0x060f9776 kmap_atomic +EXPORT_SYMBOL vmlinux 0x061651be strcat +EXPORT_SYMBOL vmlinux 0x065ec44f kill_anon_super +EXPORT_SYMBOL vmlinux 0x067d8d35 security_release_secctx +EXPORT_SYMBOL vmlinux 0x06a52448 generic_show_options +EXPORT_SYMBOL vmlinux 0x06d728b1 tcp_parse_md5sig_option +EXPORT_SYMBOL vmlinux 0x06fe3b14 default_grn +EXPORT_SYMBOL vmlinux 0x0702d6b4 sg_miter_next +EXPORT_SYMBOL vmlinux 0x0727c4f3 iowrite8 +EXPORT_SYMBOL vmlinux 0x0730faa5 pci_set_dma_max_seg_size +EXPORT_SYMBOL vmlinux 0x07368a54 starget_for_each_device +EXPORT_SYMBOL vmlinux 0x07388fb5 sock_wake_async +EXPORT_SYMBOL vmlinux 0x073bb594 eisa_driver_register +EXPORT_SYMBOL vmlinux 0x07491db3 jbd2_journal_errno +EXPORT_SYMBOL vmlinux 0x07608604 acpi_get_vendor_resource +EXPORT_SYMBOL vmlinux 0x077de7e2 search_binary_handler +EXPORT_SYMBOL vmlinux 0x0799aca4 local_bh_enable +EXPORT_SYMBOL vmlinux 0x079cd7f1 ns_to_timeval +EXPORT_SYMBOL vmlinux 0x07a890c8 fb_alloc_cmap +EXPORT_SYMBOL vmlinux 0x07aae6c6 alloc_fcdev +EXPORT_SYMBOL vmlinux 0x07cc4a5d printk_timed_ratelimit +EXPORT_SYMBOL vmlinux 0x07d50a24 csum_partial +EXPORT_SYMBOL vmlinux 0x07d9b783 scsi_nl_send_vendor_msg +EXPORT_SYMBOL vmlinux 0x07e5ac58 skb_pad +EXPORT_SYMBOL vmlinux 0x07f0ecf2 blk_start_queueing +EXPORT_SYMBOL vmlinux 0x0810eeee generic_getxattr +EXPORT_SYMBOL vmlinux 0x08271385 dev_mc_sync +EXPORT_SYMBOL vmlinux 0x082c3213 pci_root_buses +EXPORT_SYMBOL vmlinux 0x08790e6a per_cpu__cpu_info +EXPORT_SYMBOL vmlinux 0x0897c8f5 neigh_sysctl_unregister +EXPORT_SYMBOL vmlinux 0x08a89775 netif_carrier_on +EXPORT_SYMBOL vmlinux 0x09157101 f_setown +EXPORT_SYMBOL vmlinux 0x0933aae1 efi_enabled +EXPORT_SYMBOL vmlinux 0x093e947e posix_acl_create_masq +EXPORT_SYMBOL vmlinux 0x09455525 mmc_wait_for_app_cmd +EXPORT_SYMBOL vmlinux 0x0948cde9 num_physpages +EXPORT_SYMBOL vmlinux 0x096c8d51 fsync_bdev +EXPORT_SYMBOL vmlinux 0x09775cdc kref_get +EXPORT_SYMBOL vmlinux 0x097f2109 blk_rq_map_user_iov +EXPORT_SYMBOL vmlinux 0x098b71c6 fb_dealloc_cmap +EXPORT_SYMBOL vmlinux 0x09c55cec schedule_timeout_interruptible +EXPORT_SYMBOL vmlinux 0x09d44df9 in_lock_functions +EXPORT_SYMBOL vmlinux 0x0a00fd94 vfs_read +EXPORT_SYMBOL vmlinux 0x0a2487e0 unblock_all_signals +EXPORT_SYMBOL vmlinux 0x0a3131f6 strnchr +EXPORT_SYMBOL vmlinux 0x0a4747ff allocate_resource +EXPORT_SYMBOL vmlinux 0x0a666fca skb_kill_datagram +EXPORT_SYMBOL vmlinux 0x0a970979 inet_csk_init_xmit_timers +EXPORT_SYMBOL vmlinux 0x0a9b5969 generic_permission +EXPORT_SYMBOL vmlinux 0x0aac8d09 sk_release_kernel +EXPORT_SYMBOL vmlinux 0x0acb1a3c __bitmap_shift_right +EXPORT_SYMBOL vmlinux 0x0af302fa mmc_wait_for_req +EXPORT_SYMBOL vmlinux 0x0b033f78 tcf_action_exec +EXPORT_SYMBOL vmlinux 0x0b1beb31 vmalloc_32_user +EXPORT_SYMBOL vmlinux 0x0b21f1c8 pcim_iomap_regions +EXPORT_SYMBOL vmlinux 0x0b252952 dma_async_memcpy_pg_to_pg +EXPORT_SYMBOL vmlinux 0x0b32b2a8 neigh_event_ns +EXPORT_SYMBOL vmlinux 0x0b742fd7 simple_strtol +EXPORT_SYMBOL vmlinux 0x0bb1f3ea __skb_checksum_complete_head +EXPORT_SYMBOL vmlinux 0x0c0de91f netdev_class_remove_file +EXPORT_SYMBOL vmlinux 0x0c2c48c1 inetdev_by_index +EXPORT_SYMBOL vmlinux 0x0c34c2c6 generic_removexattr +EXPORT_SYMBOL vmlinux 0x0c428dad xfrm_lookup +EXPORT_SYMBOL vmlinux 0x0c5ef91b per_cpu__vm_event_states +EXPORT_SYMBOL vmlinux 0x0c65e73c scsi_normalize_sense +EXPORT_SYMBOL vmlinux 0x0c8c9e99 scsi_show_extd_sense +EXPORT_SYMBOL vmlinux 0x0ca21f81 call_usermodehelper_setkeys +EXPORT_SYMBOL vmlinux 0x0ca3481c proc_dointvec_minmax +EXPORT_SYMBOL vmlinux 0x0cc076a6 call_usermodehelper_stdinpipe +EXPORT_SYMBOL vmlinux 0x0ccde6f0 skb_seq_read +EXPORT_SYMBOL vmlinux 0x0ce094cb kthread_bind +EXPORT_SYMBOL vmlinux 0x0d26a76d _write_lock_irq +EXPORT_SYMBOL vmlinux 0x0d3dda14 acpi_get_type +EXPORT_SYMBOL vmlinux 0x0d4b77b7 gen_pool_add +EXPORT_SYMBOL vmlinux 0x0d4d468d bio_free +EXPORT_SYMBOL vmlinux 0x0d542439 __ipv6_addr_type +EXPORT_SYMBOL vmlinux 0x0d6c963c copy_from_user +EXPORT_SYMBOL vmlinux 0x0d80fb48 key_alloc +EXPORT_SYMBOL vmlinux 0x0d844151 bioset_free +EXPORT_SYMBOL vmlinux 0x0d8ab500 param_set_copystring +EXPORT_SYMBOL vmlinux 0x0d959889 skb_append_datato_frags +EXPORT_SYMBOL vmlinux 0x0da10ec3 security_sock_graft +EXPORT_SYMBOL vmlinux 0x0dccc816 register_qdisc +EXPORT_SYMBOL vmlinux 0x0ddec3fb pci_restore_state +EXPORT_SYMBOL vmlinux 0x0dea5135 scsi_device_put +EXPORT_SYMBOL vmlinux 0x0dee840c journal_release_buffer +EXPORT_SYMBOL vmlinux 0x0e232965 scsi_mode_sense +EXPORT_SYMBOL vmlinux 0x0e2983cf blk_execute_rq +EXPORT_SYMBOL vmlinux 0x0e480edb tty_check_change +EXPORT_SYMBOL vmlinux 0x0e5078fd inet_csk_destroy_sock +EXPORT_SYMBOL vmlinux 0x0e52592a panic +EXPORT_SYMBOL vmlinux 0x0e762d6e request_module +EXPORT_SYMBOL vmlinux 0x0e99e19c vfs_quota_on_mount +EXPORT_SYMBOL vmlinux 0x0e9a1a41 kill_pgrp +EXPORT_SYMBOL vmlinux 0x0eaa17c2 remap_vmalloc_range +EXPORT_SYMBOL vmlinux 0x0ecfa646 blk_rq_map_sg +EXPORT_SYMBOL vmlinux 0x0eda7244 set_page_dirty +EXPORT_SYMBOL vmlinux 0x0f1ac28f km_state_notify +EXPORT_SYMBOL vmlinux 0x0f26cbd8 locks_init_lock +EXPORT_SYMBOL vmlinux 0x0f3aa412 scsi_command_normalize_sense +EXPORT_SYMBOL vmlinux 0x0f60fc3d flush_signals +EXPORT_SYMBOL vmlinux 0x0f6d35da mb_cache_entry_free +EXPORT_SYMBOL vmlinux 0x0f7dc6a9 skb_put +EXPORT_SYMBOL vmlinux 0x0f9c0fe4 pci_find_parent_resource +EXPORT_SYMBOL vmlinux 0x0faef0ed __tasklet_schedule +EXPORT_SYMBOL vmlinux 0x0fb16018 tcp_close +EXPORT_SYMBOL vmlinux 0x0fd00a68 acpi_clear_event +EXPORT_SYMBOL vmlinux 0x0fe3f180 nonseekable_open +EXPORT_SYMBOL vmlinux 0x100fb90c scsi_host_alloc +EXPORT_SYMBOL vmlinux 0x103d001a tcf_em_unregister +EXPORT_SYMBOL vmlinux 0x10490b1b copy_strings_kernel +EXPORT_SYMBOL vmlinux 0x104fe8d5 pcim_iounmap_regions +EXPORT_SYMBOL vmlinux 0x1073708c bd_set_size +EXPORT_SYMBOL vmlinux 0x1073c3fd pci_release_region +EXPORT_SYMBOL vmlinux 0x107cd266 xfrm_state_delete +EXPORT_SYMBOL vmlinux 0x10919e34 vfs_rmdir +EXPORT_SYMBOL vmlinux 0x10ea7cbb sock_alloc_send_skb +EXPORT_SYMBOL vmlinux 0x10ee20bb default_blu +EXPORT_SYMBOL vmlinux 0x10eecaed journal_clear_err +EXPORT_SYMBOL vmlinux 0x111d6e97 inet_dev_addr_type +EXPORT_SYMBOL vmlinux 0x11267875 scsi_extd_sense_format +EXPORT_SYMBOL vmlinux 0x1129d9c3 simple_rename +EXPORT_SYMBOL vmlinux 0x114535a6 serio_interrupt +EXPORT_SYMBOL vmlinux 0x114de561 find_or_create_page +EXPORT_SYMBOL vmlinux 0x1163f0a7 blk_max_low_pfn +EXPORT_SYMBOL vmlinux 0x11658aff journal_lock_updates +EXPORT_SYMBOL vmlinux 0x117093be qdisc_class_hash_init +EXPORT_SYMBOL vmlinux 0x118f01ea putname +EXPORT_SYMBOL vmlinux 0x11a18b14 __wake_up_bit +EXPORT_SYMBOL vmlinux 0x11bb3770 nf_register_sockopt +EXPORT_SYMBOL vmlinux 0x11bf19b4 serio_unregister_driver +EXPORT_SYMBOL vmlinux 0x11c38f16 tcp_md5_hash_key +EXPORT_SYMBOL vmlinux 0x11ce4562 d_rehash +EXPORT_SYMBOL vmlinux 0x120507ac idr_get_new +EXPORT_SYMBOL vmlinux 0x123cc562 skb_gso_segment +EXPORT_SYMBOL vmlinux 0x125fbca7 cad_pid +EXPORT_SYMBOL vmlinux 0x126970ed param_set_uint +EXPORT_SYMBOL vmlinux 0x1288e272 pci_request_region +EXPORT_SYMBOL vmlinux 0x129140fe mb_cache_entry_find_next +EXPORT_SYMBOL vmlinux 0x129430f4 __nla_reserve +EXPORT_SYMBOL vmlinux 0x12c4f8db __nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0x12cfce58 acpi_notifier_call_chain +EXPORT_SYMBOL vmlinux 0x12da5bb2 __kmalloc +EXPORT_SYMBOL vmlinux 0x12f99022 inet_frags_init_net +EXPORT_SYMBOL vmlinux 0x130ae437 d_validate +EXPORT_SYMBOL vmlinux 0x1316014a unregister_framebuffer +EXPORT_SYMBOL vmlinux 0x132f45f2 cookie_check_timestamp +EXPORT_SYMBOL vmlinux 0x133f729b kmem_cache_size +EXPORT_SYMBOL vmlinux 0x13651fae tty_vhangup +EXPORT_SYMBOL vmlinux 0x1378e714 acpi_video_display_switch_support +EXPORT_SYMBOL vmlinux 0x1392023e clear_bdi_congested +EXPORT_SYMBOL vmlinux 0x13a533a6 __break_lease +EXPORT_SYMBOL vmlinux 0x13f71731 tcf_hash_lookup +EXPORT_SYMBOL vmlinux 0x14267c0b inet_release +EXPORT_SYMBOL vmlinux 0x1430e6e0 unregister_acpi_notifier +EXPORT_SYMBOL vmlinux 0x1434e4ae aio_put_req +EXPORT_SYMBOL vmlinux 0x14545b2d seq_open +EXPORT_SYMBOL vmlinux 0x1457b719 jbd2_journal_restart +EXPORT_SYMBOL vmlinux 0x1477c728 flow_cache_lookup +EXPORT_SYMBOL vmlinux 0x14ab02d5 input_unregister_device +EXPORT_SYMBOL vmlinux 0x14af0cf7 gen_pool_destroy +EXPORT_SYMBOL vmlinux 0x14c9a85a dma_pool_destroy +EXPORT_SYMBOL vmlinux 0x14f332ea up_read +EXPORT_SYMBOL vmlinux 0x15297db5 tcf_generic_walker +EXPORT_SYMBOL vmlinux 0x152f168b __scsi_alloc_queue +EXPORT_SYMBOL vmlinux 0x153869bc scsi_free_command +EXPORT_SYMBOL vmlinux 0x1544aad4 genl_register_mc_group +EXPORT_SYMBOL vmlinux 0x1551dc51 bitmap_find_free_region +EXPORT_SYMBOL vmlinux 0x15ef2dd9 kfifo_free +EXPORT_SYMBOL vmlinux 0x15ef938a ps2_sendbyte +EXPORT_SYMBOL vmlinux 0x161d074d inode_permission +EXPORT_SYMBOL vmlinux 0x16384a73 cdrom_media_changed +EXPORT_SYMBOL vmlinux 0x164546c3 kmalloc_caches +EXPORT_SYMBOL vmlinux 0x165a603b thermal_zone_device_register +EXPORT_SYMBOL vmlinux 0x165db287 __netdev_alloc_page +EXPORT_SYMBOL vmlinux 0x167e7f9d __get_user_1 +EXPORT_SYMBOL vmlinux 0x169ec561 pci_add_new_bus +EXPORT_SYMBOL vmlinux 0x16a35878 _read_unlock +EXPORT_SYMBOL vmlinux 0x16c337a3 fb_show_logo +EXPORT_SYMBOL vmlinux 0x16fb25d7 journal_check_used_features +EXPORT_SYMBOL vmlinux 0x170c25ee acpi_get_next_object +EXPORT_SYMBOL vmlinux 0x170c5068 jbd2_journal_check_used_features +EXPORT_SYMBOL vmlinux 0x1723f2c3 kobject_del +EXPORT_SYMBOL vmlinux 0x172ed4d7 __vmalloc +EXPORT_SYMBOL vmlinux 0x175a298d acpi_set_firmware_waking_vector +EXPORT_SYMBOL vmlinux 0x175f1a5b arch_acpi_processor_init_pdc +EXPORT_SYMBOL vmlinux 0x17839298 dev_mc_delete +EXPORT_SYMBOL vmlinux 0x17a76e71 rb_first +EXPORT_SYMBOL vmlinux 0x17c2cceb input_set_capability +EXPORT_SYMBOL vmlinux 0x17df17bc sysctl_tcp_ecn +EXPORT_SYMBOL vmlinux 0x17eea011 neigh_parms_release +EXPORT_SYMBOL vmlinux 0x180b3d8e set_disk_ro +EXPORT_SYMBOL vmlinux 0x181b6ff2 mempool_resize +EXPORT_SYMBOL vmlinux 0x182a9400 uart_write_wakeup +EXPORT_SYMBOL vmlinux 0x183fa88b mempool_alloc_slab +EXPORT_SYMBOL vmlinux 0x184000c8 xfrm_unregister_km +EXPORT_SYMBOL vmlinux 0x1845e7c5 acpi_evaluate_integer +EXPORT_SYMBOL vmlinux 0x184e4975 pci_clear_mwi +EXPORT_SYMBOL vmlinux 0x187fea42 acpi_check_resource_conflict +EXPORT_SYMBOL vmlinux 0x1892c631 mmc_set_data_timeout +EXPORT_SYMBOL vmlinux 0x18a31551 sock_wfree +EXPORT_SYMBOL vmlinux 0x18b0e6e4 bioset_create +EXPORT_SYMBOL vmlinux 0x18bbeb55 register_8022_client +EXPORT_SYMBOL vmlinux 0x18e00caa scsi_prep_state_check +EXPORT_SYMBOL vmlinux 0x18e4342d iw_handler_get_thrspy +EXPORT_SYMBOL vmlinux 0x18faa7b6 give_up_console +EXPORT_SYMBOL vmlinux 0x19085e2f register_nls +EXPORT_SYMBOL vmlinux 0x190f7eef pci_disable_msi +EXPORT_SYMBOL vmlinux 0x194676b8 jbd2_journal_clear_err +EXPORT_SYMBOL vmlinux 0x194ce29e journal_load +EXPORT_SYMBOL vmlinux 0x1959569b bio_alloc_bioset +EXPORT_SYMBOL vmlinux 0x1979e17d pci_unmap_rom +EXPORT_SYMBOL vmlinux 0x1985ed3c prepare_to_wait_exclusive +EXPORT_SYMBOL vmlinux 0x199ec57b lease_get_mtime +EXPORT_SYMBOL vmlinux 0x199ed0cd net_disable_timestamp +EXPORT_SYMBOL vmlinux 0x19d41fa8 blk_queue_max_segment_size +EXPORT_SYMBOL vmlinux 0x19d5d20a acpi_walk_namespace +EXPORT_SYMBOL vmlinux 0x19e2c460 llc_sap_find +EXPORT_SYMBOL vmlinux 0x19edf9ae vfs_get_dqblk +EXPORT_SYMBOL vmlinux 0x1a0c1709 sg_miter_stop +EXPORT_SYMBOL vmlinux 0x1a19aaa1 unmap_mapping_range +EXPORT_SYMBOL vmlinux 0x1a1ab15d tty_mutex +EXPORT_SYMBOL vmlinux 0x1a45cb6c acpi_disabled +EXPORT_SYMBOL vmlinux 0x1a5559dd pcie_set_readrq +EXPORT_SYMBOL vmlinux 0x1a5f2e27 __napi_schedule +EXPORT_SYMBOL vmlinux 0x1a75caa3 _read_lock +EXPORT_SYMBOL vmlinux 0x1a777f91 pci_enable_msix +EXPORT_SYMBOL vmlinux 0x1a854228 get_io_context +EXPORT_SYMBOL vmlinux 0x1a8a845e idle_nomwait +EXPORT_SYMBOL vmlinux 0x1aa3d746 tcp_connect +EXPORT_SYMBOL vmlinux 0x1abe150b netif_receive_skb +EXPORT_SYMBOL vmlinux 0x1ace138d bitmap_allocate_region +EXPORT_SYMBOL vmlinux 0x1ae8d7dc param_set_invbool +EXPORT_SYMBOL vmlinux 0x1af707ce skb_push +EXPORT_SYMBOL vmlinux 0x1b015d25 bitmap_parselist +EXPORT_SYMBOL vmlinux 0x1b0f30ab send_sig_info +EXPORT_SYMBOL vmlinux 0x1b107d00 find_task_by_vpid +EXPORT_SYMBOL vmlinux 0x1b3c678a gen_new_estimator +EXPORT_SYMBOL vmlinux 0x1b5fa99c blk_start_queue +EXPORT_SYMBOL vmlinux 0x1b6314fd in_aton +EXPORT_SYMBOL vmlinux 0x1b89419f add_wait_queue_exclusive +EXPORT_SYMBOL vmlinux 0x1b897bf0 __sk_mem_schedule +EXPORT_SYMBOL vmlinux 0x1b90245f pci_request_selected_regions +EXPORT_SYMBOL vmlinux 0x1b9981cc set_irq_wake +EXPORT_SYMBOL vmlinux 0x1b9e0ff1 scsilun_to_int +EXPORT_SYMBOL vmlinux 0x1bab2521 scsi_device_set_state +EXPORT_SYMBOL vmlinux 0x1baf9a60 __netdev_alloc_skb +EXPORT_SYMBOL vmlinux 0x1bb0f796 skb_recycle_check +EXPORT_SYMBOL vmlinux 0x1bca402a console_start +EXPORT_SYMBOL vmlinux 0x1bd59eca journal_flush +EXPORT_SYMBOL vmlinux 0x1bd841f4 blk_rq_append_bio +EXPORT_SYMBOL vmlinux 0x1c08f29c simple_write_begin +EXPORT_SYMBOL vmlinux 0x1c3aa0da find_inode_number +EXPORT_SYMBOL vmlinux 0x1c3f8ed5 scsi_device_resume +EXPORT_SYMBOL vmlinux 0x1c4f1230 pci_scan_slot +EXPORT_SYMBOL vmlinux 0x1c53260c sk_stream_wait_connect +EXPORT_SYMBOL vmlinux 0x1c5d24cf pci_remove_bus_device +EXPORT_SYMBOL vmlinux 0x1cc6719a register_reboot_notifier +EXPORT_SYMBOL vmlinux 0x1cefe352 wait_for_completion +EXPORT_SYMBOL vmlinux 0x1d0c8255 dma_ops +EXPORT_SYMBOL vmlinux 0x1d17ced7 pci_prepare_to_sleep +EXPORT_SYMBOL vmlinux 0x1d30b70c rwsem_wake +EXPORT_SYMBOL vmlinux 0x1d3a695f cdev_alloc +EXPORT_SYMBOL vmlinux 0x1d4eed14 sock_map_fd +EXPORT_SYMBOL vmlinux 0x1d8baa28 tcf_em_tree_destroy +EXPORT_SYMBOL vmlinux 0x1dc36131 fb_destroy_modedb +EXPORT_SYMBOL vmlinux 0x1dd571e6 fb_copy_cmap +EXPORT_SYMBOL vmlinux 0x1dfe17d1 inet_bind +EXPORT_SYMBOL vmlinux 0x1e0b48ba pcim_pin_device +EXPORT_SYMBOL vmlinux 0x1e142b74 kset_register +EXPORT_SYMBOL vmlinux 0x1e17e921 xfrm_find_acq +EXPORT_SYMBOL vmlinux 0x1e2d4bb6 register_snap_client +EXPORT_SYMBOL vmlinux 0x1e2e427f cpumask_next_and +EXPORT_SYMBOL vmlinux 0x1e3541b9 blk_alloc_queue_node +EXPORT_SYMBOL vmlinux 0x1e35f433 dst_destroy +EXPORT_SYMBOL vmlinux 0x1e385edc secpath_dup +EXPORT_SYMBOL vmlinux 0x1e60c2e9 block_write_begin +EXPORT_SYMBOL vmlinux 0x1e6d26a8 strstr +EXPORT_SYMBOL vmlinux 0x1eb6b52c __xfrm_route_forward +EXPORT_SYMBOL vmlinux 0x1eb7c4d5 cdrom_mode_sense +EXPORT_SYMBOL vmlinux 0x1eb922a3 IO_APIC_get_PCI_irq_vector +EXPORT_SYMBOL vmlinux 0x1ec94405 dquot_initialize +EXPORT_SYMBOL vmlinux 0x1ee95c6b elv_rb_del +EXPORT_SYMBOL vmlinux 0x1efe283f __cap_full_set +EXPORT_SYMBOL vmlinux 0x1f27d6d7 _write_unlock +EXPORT_SYMBOL vmlinux 0x1f4ac055 acpi_processor_preregister_performance +EXPORT_SYMBOL vmlinux 0x1fa470c7 jbd2_journal_get_create_access +EXPORT_SYMBOL vmlinux 0x1fd050fb pnp_get_resource +EXPORT_SYMBOL vmlinux 0x1fd36846 bio_endio +EXPORT_SYMBOL vmlinux 0x1fe5ede6 per_cpu__irq_stat +EXPORT_SYMBOL vmlinux 0x1ff37b11 dmam_pool_destroy +EXPORT_SYMBOL vmlinux 0x20000329 simple_strtoul +EXPORT_SYMBOL vmlinux 0x2005e68a acpi_remove_fixed_event_handler +EXPORT_SYMBOL vmlinux 0x20265d93 xfrm4_prepare_output +EXPORT_SYMBOL vmlinux 0x208739f6 acpi_load_table +EXPORT_SYMBOL vmlinux 0x20a4ecd1 simple_statfs +EXPORT_SYMBOL vmlinux 0x20c8fc33 pci_osc_control_set +EXPORT_SYMBOL vmlinux 0x20c98fe5 inet_frag_find +EXPORT_SYMBOL vmlinux 0x20e6aefb tcp_rcv_state_process +EXPORT_SYMBOL vmlinux 0x20ebe4de tcf_hash_create +EXPORT_SYMBOL vmlinux 0x21034449 neigh_parms_alloc +EXPORT_SYMBOL vmlinux 0x2106908b pci_setup_cardbus +EXPORT_SYMBOL vmlinux 0x2123f372 is_bad_inode +EXPORT_SYMBOL vmlinux 0x2141af57 ps2_command +EXPORT_SYMBOL vmlinux 0x215ebd78 bitrev16 +EXPORT_SYMBOL vmlinux 0x21677a81 scsi_host_set_state +EXPORT_SYMBOL vmlinux 0x21df272c scsi_eh_prep_cmnd +EXPORT_SYMBOL vmlinux 0x21e0ea22 acpi_get_id +EXPORT_SYMBOL vmlinux 0x21e227cf udp_ioctl +EXPORT_SYMBOL vmlinux 0x222e7ce2 sysfs_streq +EXPORT_SYMBOL vmlinux 0x22654998 pci_bus_write_config_word +EXPORT_SYMBOL vmlinux 0x226e86a9 audit_log +EXPORT_SYMBOL vmlinux 0x2288378f system_state +EXPORT_SYMBOL vmlinux 0x22a73912 __tcp_put_md5sig_pool +EXPORT_SYMBOL vmlinux 0x22b0ebab ip_setsockopt +EXPORT_SYMBOL vmlinux 0x22b1d57e journal_force_commit +EXPORT_SYMBOL vmlinux 0x22b325d5 kd_mksound +EXPORT_SYMBOL vmlinux 0x22b6533b xfrm_sad_getinfo +EXPORT_SYMBOL vmlinux 0x22b9d809 struct_module +EXPORT_SYMBOL vmlinux 0x22dbdf80 generic_readlink +EXPORT_SYMBOL vmlinux 0x231f3a66 __kfifo_put +EXPORT_SYMBOL vmlinux 0x23269a13 strict_strtoul +EXPORT_SYMBOL vmlinux 0x2340b36d netdev_class_create_file +EXPORT_SYMBOL vmlinux 0x23440c14 blk_requeue_request +EXPORT_SYMBOL vmlinux 0x2347e430 revalidate_disk +EXPORT_SYMBOL vmlinux 0x23581334 find_task_by_pid_ns +EXPORT_SYMBOL vmlinux 0x2368be6d posix_acl_to_xattr +EXPORT_SYMBOL vmlinux 0x23ad070a set_current_groups +EXPORT_SYMBOL vmlinux 0x23fd3028 vmalloc_node +EXPORT_SYMBOL vmlinux 0x24183939 llc_set_station_handler +EXPORT_SYMBOL vmlinux 0x243de6ea vfs_readdir +EXPORT_SYMBOL vmlinux 0x243ffddc idr_destroy +EXPORT_SYMBOL vmlinux 0x24428be5 strncpy_from_user +EXPORT_SYMBOL vmlinux 0x2459bbcc console_set_on_cmdline +EXPORT_SYMBOL vmlinux 0x24622382 udp_poll +EXPORT_SYMBOL vmlinux 0x24909ca9 scm_fp_dup +EXPORT_SYMBOL vmlinux 0x24fdac79 wake_bit_function +EXPORT_SYMBOL vmlinux 0x250113b4 memory_read_from_buffer +EXPORT_SYMBOL vmlinux 0x25030266 tcp_disconnect +EXPORT_SYMBOL vmlinux 0x25270431 tcp_shutdown +EXPORT_SYMBOL vmlinux 0x2531348e con_set_default_unimap +EXPORT_SYMBOL vmlinux 0x253600a9 netpoll_parse_options +EXPORT_SYMBOL vmlinux 0x25542624 pci_bus_assign_resources +EXPORT_SYMBOL vmlinux 0x256887e1 warn_slowpath +EXPORT_SYMBOL vmlinux 0x25820c64 fs_overflowuid +EXPORT_SYMBOL vmlinux 0x258355b4 fb_find_best_mode +EXPORT_SYMBOL vmlinux 0x2590316c skb_checksum +EXPORT_SYMBOL vmlinux 0x25d81960 posix_acl_equiv_mode +EXPORT_SYMBOL vmlinux 0x25dbf36c inode_add_bytes +EXPORT_SYMBOL vmlinux 0x26082779 mmc_wait_for_cmd +EXPORT_SYMBOL vmlinux 0x260a58e8 netlink_dump_start +EXPORT_SYMBOL vmlinux 0x2658a956 seq_printf +EXPORT_SYMBOL vmlinux 0x265bdf41 journal_forget +EXPORT_SYMBOL vmlinux 0x26667afb skb_under_panic +EXPORT_SYMBOL vmlinux 0x26766f27 get_write_access +EXPORT_SYMBOL vmlinux 0x268a238d pnp_device_attach +EXPORT_SYMBOL vmlinux 0x268cc6a2 sys_close +EXPORT_SYMBOL vmlinux 0x26961116 netif_device_detach +EXPORT_SYMBOL vmlinux 0x269a101d seq_putc +EXPORT_SYMBOL vmlinux 0x26bae88d bio_uncopy_user +EXPORT_SYMBOL vmlinux 0x26d395e3 simple_getattr +EXPORT_SYMBOL vmlinux 0x26e76fb8 sysctl_udp_wmem_min +EXPORT_SYMBOL vmlinux 0x272d394e mtrr_del +EXPORT_SYMBOL vmlinux 0x272e7488 cond_resched_softirq +EXPORT_SYMBOL vmlinux 0x273f066e _write_unlock_irq +EXPORT_SYMBOL vmlinux 0x276d5419 __vlan_hwaccel_rx +EXPORT_SYMBOL vmlinux 0x27864158 kmap +EXPORT_SYMBOL vmlinux 0x27864d57 memparse +EXPORT_SYMBOL vmlinux 0x27a9a7eb ns_to_timespec +EXPORT_SYMBOL vmlinux 0x27bbf221 disable_irq_nosync +EXPORT_SYMBOL vmlinux 0x27c61ece qdisc_put_stab +EXPORT_SYMBOL vmlinux 0x27dedd8f call_usermodehelper_freeinfo +EXPORT_SYMBOL vmlinux 0x2850ca7b deny_write_access +EXPORT_SYMBOL vmlinux 0x285ac517 strict_strtoll +EXPORT_SYMBOL vmlinux 0x28a2ed02 scsi_build_sense_buffer +EXPORT_SYMBOL vmlinux 0x28b715a6 isapnp_cfg_end +EXPORT_SYMBOL vmlinux 0x28d5fdfa pci_release_regions +EXPORT_SYMBOL vmlinux 0x28dbfd14 tty_insert_flip_string +EXPORT_SYMBOL vmlinux 0x28dcf25c udplite_hash +EXPORT_SYMBOL vmlinux 0x291d6b1d sk_wait_data +EXPORT_SYMBOL vmlinux 0x2942f314 kobject_init +EXPORT_SYMBOL vmlinux 0x29471212 posix_acl_permission +EXPORT_SYMBOL vmlinux 0x29537c9e alloc_chrdev_region +EXPORT_SYMBOL vmlinux 0x295d22e9 dmam_free_coherent +EXPORT_SYMBOL vmlinux 0x29b104f6 thermal_cooling_device_register +EXPORT_SYMBOL vmlinux 0x29b1c366 __sg_alloc_table +EXPORT_SYMBOL vmlinux 0x29bd4c46 __cap_init_eff_set +EXPORT_SYMBOL vmlinux 0x29d3d9b6 netdev_bonding_change +EXPORT_SYMBOL vmlinux 0x29ec9953 journal_restart +EXPORT_SYMBOL vmlinux 0x29f1100d lock_may_write +EXPORT_SYMBOL vmlinux 0x2a303d4d check_signature +EXPORT_SYMBOL vmlinux 0x2a42e381 put_tty_driver +EXPORT_SYMBOL vmlinux 0x2a55da0f proc_dointvec_ms_jiffies +EXPORT_SYMBOL vmlinux 0x2a6a4eef pneigh_lookup +EXPORT_SYMBOL vmlinux 0x2aa0e4fc strncasecmp +EXPORT_SYMBOL vmlinux 0x2aeb2800 mempool_create_node +EXPORT_SYMBOL vmlinux 0x2aeb5643 should_remove_suid +EXPORT_SYMBOL vmlinux 0x2af95246 vm_insert_pfn +EXPORT_SYMBOL vmlinux 0x2b0ba2b0 scsi_sense_desc_find +EXPORT_SYMBOL vmlinux 0x2b51f5ae blk_queue_set_discard +EXPORT_SYMBOL vmlinux 0x2b6aac8c tcp_sockets_allocated +EXPORT_SYMBOL vmlinux 0x2b984411 scsi_host_get +EXPORT_SYMBOL vmlinux 0x2ba707a8 sysctl_tcp_low_latency +EXPORT_SYMBOL vmlinux 0x2bb55d6e acpi_remove_notify_handler +EXPORT_SYMBOL vmlinux 0x2bc5f79d inet_register_protosw +EXPORT_SYMBOL vmlinux 0x2bc95bd4 memset +EXPORT_SYMBOL vmlinux 0x2be09893 _atomic_dec_and_lock +EXPORT_SYMBOL vmlinux 0x2bf74136 inet_stream_ops +EXPORT_SYMBOL vmlinux 0x2bfeb410 acpi_get_handle +EXPORT_SYMBOL vmlinux 0x2c47640d generic_shutdown_super +EXPORT_SYMBOL vmlinux 0x2c4af0b2 cpu_sysdev_class +EXPORT_SYMBOL vmlinux 0x2c55907f gnet_stats_copy_queue +EXPORT_SYMBOL vmlinux 0x2c5749e6 acpi_clear_gpe +EXPORT_SYMBOL vmlinux 0x2c87687f skb_make_writable +EXPORT_SYMBOL vmlinux 0x2c89bc37 request_key +EXPORT_SYMBOL vmlinux 0x2c8f5989 acpi_remove_address_space_handler +EXPORT_SYMBOL vmlinux 0x2c9874fe ida_remove +EXPORT_SYMBOL vmlinux 0x2cb1f735 blkdev_put +EXPORT_SYMBOL vmlinux 0x2cccfa03 jbd2_journal_load +EXPORT_SYMBOL vmlinux 0x2cd9e459 param_set_short +EXPORT_SYMBOL vmlinux 0x2cdde43a __pci_register_driver +EXPORT_SYMBOL vmlinux 0x2cecebfb get_fs_type +EXPORT_SYMBOL vmlinux 0x2cf190e3 request_irq +EXPORT_SYMBOL vmlinux 0x2cf1f536 scsi_device_lookup +EXPORT_SYMBOL vmlinux 0x2d05f263 sock_no_sendpage +EXPORT_SYMBOL vmlinux 0x2d19c1ab netpoll_send_udp +EXPORT_SYMBOL vmlinux 0x2d2f2ddf serio_close +EXPORT_SYMBOL vmlinux 0x2d546a09 xfrm_state_lookup +EXPORT_SYMBOL vmlinux 0x2d77a734 sock_kmalloc +EXPORT_SYMBOL vmlinux 0x2d84b978 proc_dointvec_jiffies +EXPORT_SYMBOL vmlinux 0x2d89342a scsi_show_sense_hdr +EXPORT_SYMBOL vmlinux 0x2dd16564 arch_register_cpu +EXPORT_SYMBOL vmlinux 0x2de9f66f param_get_long +EXPORT_SYMBOL vmlinux 0x2dedc4c2 acpi_format_exception +EXPORT_SYMBOL vmlinux 0x2def7f76 rtc_cmos_write +EXPORT_SYMBOL vmlinux 0x2e12ed45 jbd2_journal_begin_ordered_truncate +EXPORT_SYMBOL vmlinux 0x2e24856d unregister_filesystem +EXPORT_SYMBOL vmlinux 0x2e2ce9e0 sysctl_tcp_syncookies +EXPORT_SYMBOL vmlinux 0x2e35b84a bdi_init +EXPORT_SYMBOL vmlinux 0x2e3b531f blk_run_queue +EXPORT_SYMBOL vmlinux 0x2e3de966 blk_free_tags +EXPORT_SYMBOL vmlinux 0x2e4a39f8 sysctl_udp_mem +EXPORT_SYMBOL vmlinux 0x2e60bace memcpy +EXPORT_SYMBOL vmlinux 0x2e8e6c06 sync_inode +EXPORT_SYMBOL vmlinux 0x2e97859f rwsem_downgrade_wake +EXPORT_SYMBOL vmlinux 0x2eb9a0e8 _read_lock_irq +EXPORT_SYMBOL vmlinux 0x2eda6823 seq_open_private +EXPORT_SYMBOL vmlinux 0x2eff2c04 sysctl_string +EXPORT_SYMBOL vmlinux 0x2f287f0d copy_to_user +EXPORT_SYMBOL vmlinux 0x2f44b85d fb_is_primary_device +EXPORT_SYMBOL vmlinux 0x2f744eb2 udp_disconnect +EXPORT_SYMBOL vmlinux 0x2f96ba9a dev_set_allmulti +EXPORT_SYMBOL vmlinux 0x2facddae uart_register_driver +EXPORT_SYMBOL vmlinux 0x2ff7efaa tcf_hash_new_index +EXPORT_SYMBOL vmlinux 0x2ffcdd07 tty_kref_put +EXPORT_SYMBOL vmlinux 0x3017f8e4 scsi_block_when_processing_errors +EXPORT_SYMBOL vmlinux 0x302868c0 vfs_mknod +EXPORT_SYMBOL vmlinux 0x302a741d keyring_clear +EXPORT_SYMBOL vmlinux 0x302d4ba8 tcp_v4_md5_do_add +EXPORT_SYMBOL vmlinux 0x304124e6 d_move +EXPORT_SYMBOL vmlinux 0x305ad73a tcp_init_xmit_timers +EXPORT_SYMBOL vmlinux 0x30a82b07 bio_map_kern +EXPORT_SYMBOL vmlinux 0x30be9867 pcim_enable_device +EXPORT_SYMBOL vmlinux 0x30d6038e scsi_register +EXPORT_SYMBOL vmlinux 0x30e4de72 cap_netlink_recv +EXPORT_SYMBOL vmlinux 0x30e74134 tty_termios_copy_hw +EXPORT_SYMBOL vmlinux 0x30f6dc26 tcp_prot +EXPORT_SYMBOL vmlinux 0x310917fe sort +EXPORT_SYMBOL vmlinux 0x31115e11 tty_unregister_device +EXPORT_SYMBOL vmlinux 0x3118dc19 tty_register_driver +EXPORT_SYMBOL vmlinux 0x3145216f pci_dev_present +EXPORT_SYMBOL vmlinux 0x3147857d default_red +EXPORT_SYMBOL vmlinux 0x315cc21b add_to_page_cache_locked +EXPORT_SYMBOL vmlinux 0x3191f109 __krealloc +EXPORT_SYMBOL vmlinux 0x31e76b57 recalibrate_cpu_khz +EXPORT_SYMBOL vmlinux 0x31f8f5dd register_binfmt +EXPORT_SYMBOL vmlinux 0x3255ee77 vm_insert_page +EXPORT_SYMBOL vmlinux 0x326f2687 vfs_create +EXPORT_SYMBOL vmlinux 0x32718a6a scsi_target_resume +EXPORT_SYMBOL vmlinux 0x329592f1 udp_prot +EXPORT_SYMBOL vmlinux 0x32ad74a0 neigh_for_each +EXPORT_SYMBOL vmlinux 0x32baf865 tcp_v4_destroy_sock +EXPORT_SYMBOL vmlinux 0x32d01fec acpi_attach_data +EXPORT_SYMBOL vmlinux 0x3304eef0 tty_driver_flush_buffer +EXPORT_SYMBOL vmlinux 0x334d4de7 nla_put +EXPORT_SYMBOL vmlinux 0x335a831e vfs_get_dqinfo +EXPORT_SYMBOL vmlinux 0x3360a963 param_set_ulong +EXPORT_SYMBOL vmlinux 0x3385c8cb per_cpu__this_cpu_off +EXPORT_SYMBOL vmlinux 0x339fe002 journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0x33d92f9a prepare_to_wait +EXPORT_SYMBOL vmlinux 0x33dc1608 blk_stop_queue +EXPORT_SYMBOL vmlinux 0x3423794d filemap_fdatawrite +EXPORT_SYMBOL vmlinux 0x342d8668 __xfrm_state_destroy +EXPORT_SYMBOL vmlinux 0x342f60fe apm_info +EXPORT_SYMBOL vmlinux 0x344a8654 dev_close +EXPORT_SYMBOL vmlinux 0x345ca611 blkdev_get +EXPORT_SYMBOL vmlinux 0x34908c14 print_hex_dump_bytes +EXPORT_SYMBOL vmlinux 0x34971d09 unlock_new_inode +EXPORT_SYMBOL vmlinux 0x349cba85 strchr +EXPORT_SYMBOL vmlinux 0x34ae5dba ethtool_op_get_link +EXPORT_SYMBOL vmlinux 0x34cf0c0a blk_insert_request +EXPORT_SYMBOL vmlinux 0x34d6f331 tcp_parse_options +EXPORT_SYMBOL vmlinux 0x34e991c3 pid_task +EXPORT_SYMBOL vmlinux 0x34f2cdc7 scsi_eh_finish_cmd +EXPORT_SYMBOL vmlinux 0x350ba022 neigh_lookup_nodev +EXPORT_SYMBOL vmlinux 0x35224a53 pci_assign_resource +EXPORT_SYMBOL vmlinux 0x355d323d acpi_bus_get_device +EXPORT_SYMBOL vmlinux 0x356be8de scsi_is_target_device +EXPORT_SYMBOL vmlinux 0x35c2ba9e refrigerator +EXPORT_SYMBOL vmlinux 0x35c5979a simple_lookup +EXPORT_SYMBOL vmlinux 0x35d427bf journal_unlock_updates +EXPORT_SYMBOL vmlinux 0x35f0faa2 acpi_evaluate_object +EXPORT_SYMBOL vmlinux 0x360b1afe probe_irq_mask +EXPORT_SYMBOL vmlinux 0x361525c8 find_task_by_pid_type_ns +EXPORT_SYMBOL vmlinux 0x36184e27 alloc_disk +EXPORT_SYMBOL vmlinux 0x36333635 pci_set_power_state +EXPORT_SYMBOL vmlinux 0x363ad247 cap_set_effective +EXPORT_SYMBOL vmlinux 0x3656bf5a lock_kernel +EXPORT_SYMBOL vmlinux 0x36ae9df5 pnp_possible_config +EXPORT_SYMBOL vmlinux 0x36e36d24 clear_inode +EXPORT_SYMBOL vmlinux 0x37117417 balance_dirty_pages_ratelimited_nr +EXPORT_SYMBOL vmlinux 0x3714d697 __blockdev_direct_IO +EXPORT_SYMBOL vmlinux 0x371bc686 pnp_find_dev +EXPORT_SYMBOL vmlinux 0x3725ffc5 inet_frag_kill +EXPORT_SYMBOL vmlinux 0x3744cf36 vmalloc_to_pfn +EXPORT_SYMBOL vmlinux 0x374ed073 scnprintf +EXPORT_SYMBOL vmlinux 0x37525223 pci_set_dma_seg_boundary +EXPORT_SYMBOL vmlinux 0x378fffb0 journal_stop +EXPORT_SYMBOL vmlinux 0x379d65f5 gen_pool_alloc +EXPORT_SYMBOL vmlinux 0x379f4dbd nf_unregister_hooks +EXPORT_SYMBOL vmlinux 0x37befc70 jiffies_to_msecs +EXPORT_SYMBOL vmlinux 0x37c32b1e netdev_features_change +EXPORT_SYMBOL vmlinux 0x37e18ebe kernel_bind +EXPORT_SYMBOL vmlinux 0x37e74642 get_jiffies_64 +EXPORT_SYMBOL vmlinux 0x37ed9491 d_alloc_name +EXPORT_SYMBOL vmlinux 0x3816319e generic_file_readonly_mmap +EXPORT_SYMBOL vmlinux 0x38203ca1 __init_rwsem +EXPORT_SYMBOL vmlinux 0x3858d075 invalidate_partition +EXPORT_SYMBOL vmlinux 0x3861f2e8 xfrm_policy_delete +EXPORT_SYMBOL vmlinux 0x387c0967 vfs_lstat +EXPORT_SYMBOL vmlinux 0x388f9128 xfrm_state_walk_done +EXPORT_SYMBOL vmlinux 0x389fbb28 bdget_disk +EXPORT_SYMBOL vmlinux 0x38a6c00f generic_read_dir +EXPORT_SYMBOL vmlinux 0x38ab9e63 skb_dequeue_tail +EXPORT_SYMBOL vmlinux 0x38b92846 llc_remove_pack +EXPORT_SYMBOL vmlinux 0x38d676c5 xfrm4_rcv_encap +EXPORT_SYMBOL vmlinux 0x38e09305 vfs_unlink +EXPORT_SYMBOL vmlinux 0x38e848a1 read_cache_page +EXPORT_SYMBOL vmlinux 0x38f712c7 xfrm_policy_bysel_ctx +EXPORT_SYMBOL vmlinux 0x390c84f0 kobject_put +EXPORT_SYMBOL vmlinux 0x3932478b dev_open +EXPORT_SYMBOL vmlinux 0x396dc949 alloc_buffer_head +EXPORT_SYMBOL vmlinux 0x396ec1d8 ip4_datagram_connect +EXPORT_SYMBOL vmlinux 0x3976cd43 generic_file_direct_write +EXPORT_SYMBOL vmlinux 0x3980aac1 unregister_reboot_notifier +EXPORT_SYMBOL vmlinux 0x39962137 pci_get_device +EXPORT_SYMBOL vmlinux 0x39a4c3bd elv_abort_queue +EXPORT_SYMBOL vmlinux 0x39c645a2 schedule_delayed_work_on +EXPORT_SYMBOL vmlinux 0x39cce957 file_remove_suid +EXPORT_SYMBOL vmlinux 0x39ee40bf __bio_clone +EXPORT_SYMBOL vmlinux 0x3a06a890 bio_add_pc_page +EXPORT_SYMBOL vmlinux 0x3a0b3793 may_umount +EXPORT_SYMBOL vmlinux 0x3a10bd39 lock_sock_nested +EXPORT_SYMBOL vmlinux 0x3a15a44e iov_iter_copy_from_user_atomic +EXPORT_SYMBOL vmlinux 0x3a15f76d pcie_port_service_register +EXPORT_SYMBOL vmlinux 0x3a2204c6 security_netlink_recv +EXPORT_SYMBOL vmlinux 0x3a48bdaa posix_lock_file_wait +EXPORT_SYMBOL vmlinux 0x3a5d11c2 journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0x3a60e463 set_user_nice +EXPORT_SYMBOL vmlinux 0x3a8f72f1 __rta_fill +EXPORT_SYMBOL vmlinux 0x3a9aef61 vm_insert_mixed +EXPORT_SYMBOL vmlinux 0x3a9b6fb9 blk_unregister_region +EXPORT_SYMBOL vmlinux 0x3aa10e94 pci_set_master +EXPORT_SYMBOL vmlinux 0x3aa1dbcf _spin_unlock_bh +EXPORT_SYMBOL vmlinux 0x3aaa34f9 __devm_request_region +EXPORT_SYMBOL vmlinux 0x3af98f9e ioremap_nocache +EXPORT_SYMBOL vmlinux 0x3b238cc1 input_close_device +EXPORT_SYMBOL vmlinux 0x3b3016d3 cpufreq_unregister_notifier +EXPORT_SYMBOL vmlinux 0x3b31a650 in_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0x3b47bec3 scsi_remove_device +EXPORT_SYMBOL vmlinux 0x3bb012ca journal_set_features +EXPORT_SYMBOL vmlinux 0x3bd1b1f6 msecs_to_jiffies +EXPORT_SYMBOL vmlinux 0x3bf7b79c kfree_skb +EXPORT_SYMBOL vmlinux 0x3c2c5af5 sprintf +EXPORT_SYMBOL vmlinux 0x3c4a0272 mem_map +EXPORT_SYMBOL vmlinux 0x3c7227bf complete_all +EXPORT_SYMBOL vmlinux 0x3c80dc6c pci_get_bus_and_slot +EXPORT_SYMBOL vmlinux 0x3c81f32a ethtool_op_set_sg +EXPORT_SYMBOL vmlinux 0x3c978f33 pci_bus_size_bridges +EXPORT_SYMBOL vmlinux 0x3c97cac3 acpi_lock_battery_dir +EXPORT_SYMBOL vmlinux 0x3c9c0170 generic_setlease +EXPORT_SYMBOL vmlinux 0x3c9d1211 string_get_size +EXPORT_SYMBOL vmlinux 0x3cb8a495 param_get_string +EXPORT_SYMBOL vmlinux 0x3cba5c56 __scsi_device_lookup +EXPORT_SYMBOL vmlinux 0x3cc0a3bb xfrm_spd_getinfo +EXPORT_SYMBOL vmlinux 0x3ce4ca6f disable_irq +EXPORT_SYMBOL vmlinux 0x3ced9d98 nf_getsockopt +EXPORT_SYMBOL vmlinux 0x3cf2ba73 posix_test_lock +EXPORT_SYMBOL vmlinux 0x3d138f28 pci_find_bus +EXPORT_SYMBOL vmlinux 0x3d1bcea2 blk_queue_find_tag +EXPORT_SYMBOL vmlinux 0x3d4419ac tcp_v4_md5_lookup +EXPORT_SYMBOL vmlinux 0x3d538c94 block_truncate_page +EXPORT_SYMBOL vmlinux 0x3d9c9c55 block_prepare_write +EXPORT_SYMBOL vmlinux 0x3da171f9 pci_mem_start +EXPORT_SYMBOL vmlinux 0x3da5eb6d kfifo_alloc +EXPORT_SYMBOL vmlinux 0x3dc24207 dma_pool_create +EXPORT_SYMBOL vmlinux 0x3e0dd149 tcp_check_req +EXPORT_SYMBOL vmlinux 0x3e1f073d wait_for_completion_timeout +EXPORT_SYMBOL vmlinux 0x3e219de6 try_wait_for_completion +EXPORT_SYMBOL vmlinux 0x3e2ae3a8 acpi_release_global_lock +EXPORT_SYMBOL vmlinux 0x3e383385 nf_hooks +EXPORT_SYMBOL vmlinux 0x3e45e9ff register_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x3e5d49e2 bdev_read_only +EXPORT_SYMBOL vmlinux 0x3e6e9351 page_symlink_inode_operations +EXPORT_SYMBOL vmlinux 0x3e73d38c skb_copy_datagram_from_iovec +EXPORT_SYMBOL vmlinux 0x3ed63055 zlib_inflateReset +EXPORT_SYMBOL vmlinux 0x3ef65c95 fput +EXPORT_SYMBOL vmlinux 0x3f0546a8 ioread32_rep +EXPORT_SYMBOL vmlinux 0x3f0799dd inet_twsk_deschedule +EXPORT_SYMBOL vmlinux 0x3f1899f1 up +EXPORT_SYMBOL vmlinux 0x3f39b162 up_write +EXPORT_SYMBOL vmlinux 0x3f4547a7 put_unused_fd +EXPORT_SYMBOL vmlinux 0x3f9febb6 pci_bus_read_config_byte +EXPORT_SYMBOL vmlinux 0x3fa26b8b simple_fill_super +EXPORT_SYMBOL vmlinux 0x3fc4b92f unlock_super +EXPORT_SYMBOL vmlinux 0x3fdfbe77 ip_dev_find +EXPORT_SYMBOL vmlinux 0x3ff62317 local_bh_disable +EXPORT_SYMBOL vmlinux 0x3ffbf812 simple_dir_inode_operations +EXPORT_SYMBOL vmlinux 0x403412bc dma_async_client_unregister +EXPORT_SYMBOL vmlinux 0x4059792f print_hex_dump +EXPORT_SYMBOL vmlinux 0x405c1144 get_seconds +EXPORT_SYMBOL vmlinux 0x407e1013 jbd2_journal_extend +EXPORT_SYMBOL vmlinux 0x409873e3 tty_termios_baud_rate +EXPORT_SYMBOL vmlinux 0x40ac8d0b kernel_listen +EXPORT_SYMBOL vmlinux 0x40ad3989 thermal_zone_device_unregister +EXPORT_SYMBOL vmlinux 0x40c89d46 acpi_get_table_by_index +EXPORT_SYMBOL vmlinux 0x4105f2b8 input_register_device +EXPORT_SYMBOL vmlinux 0x4108e69a fb_match_mode +EXPORT_SYMBOL vmlinux 0x4109fde6 ip_mc_join_group +EXPORT_SYMBOL vmlinux 0x41323fec eisa_driver_unregister +EXPORT_SYMBOL vmlinux 0x4146da0a security_sb_set_mnt_opts +EXPORT_SYMBOL vmlinux 0x41482d8b strndup_user +EXPORT_SYMBOL vmlinux 0x41607856 register_sysctl_table +EXPORT_SYMBOL vmlinux 0x416983d9 netdev_fix_features +EXPORT_SYMBOL vmlinux 0x4185cf4b radix_tree_lookup_slot +EXPORT_SYMBOL vmlinux 0x4188d439 neigh_rand_reach_time +EXPORT_SYMBOL vmlinux 0x419fc3c1 neigh_create +EXPORT_SYMBOL vmlinux 0x41a9c68d _spin_trylock_bh +EXPORT_SYMBOL vmlinux 0x420b1a10 seq_release +EXPORT_SYMBOL vmlinux 0x4211c3c1 zlib_inflateInit2 +EXPORT_SYMBOL vmlinux 0x42224298 sscanf +EXPORT_SYMBOL vmlinux 0x422c05d0 acpi_get_data +EXPORT_SYMBOL vmlinux 0x42475c5a uart_get_divisor +EXPORT_SYMBOL vmlinux 0x4275f32d cdev_init +EXPORT_SYMBOL vmlinux 0x4292364c schedule +EXPORT_SYMBOL vmlinux 0x42938b21 xfrm_unregister_mode +EXPORT_SYMBOL vmlinux 0x4299484e inet_proto_csum_replace4 +EXPORT_SYMBOL vmlinux 0x42a09809 __alloc_skb +EXPORT_SYMBOL vmlinux 0x42ae5700 xfrm_policy_insert +EXPORT_SYMBOL vmlinux 0x42b5da02 generic_fillattr +EXPORT_SYMBOL vmlinux 0x42dd731b start_tty +EXPORT_SYMBOL vmlinux 0x4302d0eb free_pages +EXPORT_SYMBOL vmlinux 0x43302203 journal_abort +EXPORT_SYMBOL vmlinux 0x4337d7df ethtool_op_get_tx_csum +EXPORT_SYMBOL vmlinux 0x43385ad9 acpi_pci_unregister_driver +EXPORT_SYMBOL vmlinux 0x43496cbb dev_set_promiscuity +EXPORT_SYMBOL vmlinux 0x434fa55c release_console_sem +EXPORT_SYMBOL vmlinux 0x435b566d _spin_unlock +EXPORT_SYMBOL vmlinux 0x436c2179 iowrite32 +EXPORT_SYMBOL vmlinux 0x4379f527 cancel_dirty_page +EXPORT_SYMBOL vmlinux 0x437bc6e4 kunmap_high +EXPORT_SYMBOL vmlinux 0x43b40de7 kunmap_atomic +EXPORT_SYMBOL vmlinux 0x43c188d7 textsearch_unregister +EXPORT_SYMBOL vmlinux 0x43edbaf7 pci_enable_device +EXPORT_SYMBOL vmlinux 0x43f14e24 have_submounts +EXPORT_SYMBOL vmlinux 0x43f8147d tcp_v4_send_check +EXPORT_SYMBOL vmlinux 0x440984a3 vfs_mkdir +EXPORT_SYMBOL vmlinux 0x44161c19 unregister_shrinker +EXPORT_SYMBOL vmlinux 0x44204d93 dmam_free_noncoherent +EXPORT_SYMBOL vmlinux 0x4430cfa5 lock_rename +EXPORT_SYMBOL vmlinux 0x44314efb radix_tree_gang_lookup_tag_slot +EXPORT_SYMBOL vmlinux 0x443bf52d scsi_free_host_dev +EXPORT_SYMBOL vmlinux 0x444779c4 nla_find +EXPORT_SYMBOL vmlinux 0x444a009b udp_lib_setsockopt +EXPORT_SYMBOL vmlinux 0x4464c609 security_sb_clone_mnt_opts +EXPORT_SYMBOL vmlinux 0x44aaf30f tsc_khz +EXPORT_SYMBOL vmlinux 0x44af365f unregister_netdev +EXPORT_SYMBOL vmlinux 0x44b911c3 rb_replace_node +EXPORT_SYMBOL vmlinux 0x44cee110 follow_down +EXPORT_SYMBOL vmlinux 0x44db3350 pci_bus_write_config_byte +EXPORT_SYMBOL vmlinux 0x44e9a829 match_token +EXPORT_SYMBOL vmlinux 0x44e9ea61 uart_suspend_port +EXPORT_SYMBOL vmlinux 0x44f21bea idr_for_each +EXPORT_SYMBOL vmlinux 0x4527b771 ilookup5 +EXPORT_SYMBOL vmlinux 0x455078be mpage_readpages +EXPORT_SYMBOL vmlinux 0x4550ba8a register_cpu_notifier +EXPORT_SYMBOL vmlinux 0x45534a98 arp_xmit +EXPORT_SYMBOL vmlinux 0x455fd57d acpi_set_register +EXPORT_SYMBOL vmlinux 0x456b4559 ethtool_op_get_ufo +EXPORT_SYMBOL vmlinux 0x45762d17 d_splice_alias +EXPORT_SYMBOL vmlinux 0x4576afa5 tcp_v4_md5_hash_skb +EXPORT_SYMBOL vmlinux 0x45b3d2cb update_region +EXPORT_SYMBOL vmlinux 0x45bb123e try_to_del_timer_sync +EXPORT_SYMBOL vmlinux 0x45c220ae blk_rq_init +EXPORT_SYMBOL vmlinux 0x45c723f8 d_delete +EXPORT_SYMBOL vmlinux 0x45d11c43 down_interruptible +EXPORT_SYMBOL vmlinux 0x46051d22 put_disk +EXPORT_SYMBOL vmlinux 0x46139e82 inode_setattr +EXPORT_SYMBOL vmlinux 0x46295839 serio_open +EXPORT_SYMBOL vmlinux 0x462a2e75 match_strlcpy +EXPORT_SYMBOL vmlinux 0x466c14a7 __delay +EXPORT_SYMBOL vmlinux 0x46c5761d kern_path +EXPORT_SYMBOL vmlinux 0x46daa648 aio_complete +EXPORT_SYMBOL vmlinux 0x470718ca invalidate_mapping_pages +EXPORT_SYMBOL vmlinux 0x47126d67 follow_up +EXPORT_SYMBOL vmlinux 0x472d2a9a radix_tree_lookup +EXPORT_SYMBOL vmlinux 0x475100c2 inet_get_local_port_range +EXPORT_SYMBOL vmlinux 0x475bd5ad pci_request_regions +EXPORT_SYMBOL vmlinux 0x475ed471 tcp_poll +EXPORT_SYMBOL vmlinux 0x475f010b acpi_purge_cached_objects +EXPORT_SYMBOL vmlinux 0x4775ce48 inet_csk_clear_xmit_timers +EXPORT_SYMBOL vmlinux 0x47761094 con_copy_unimap +EXPORT_SYMBOL vmlinux 0x478d10b2 ht_destroy_irq +EXPORT_SYMBOL vmlinux 0x47939e0d __tasklet_hi_schedule +EXPORT_SYMBOL vmlinux 0x479c3c86 find_next_zero_bit +EXPORT_SYMBOL vmlinux 0x47c62d70 xfrm_policy_flush +EXPORT_SYMBOL vmlinux 0x47c8c654 simple_link +EXPORT_SYMBOL vmlinux 0x47da5232 remap_pfn_range +EXPORT_SYMBOL vmlinux 0x481cb9ab acpi_enter_sleep_state_prep +EXPORT_SYMBOL vmlinux 0x482073a0 __dev_get_by_name +EXPORT_SYMBOL vmlinux 0x4859b8bb rtc_year_days +EXPORT_SYMBOL vmlinux 0x486b6407 hweight64 +EXPORT_SYMBOL vmlinux 0x48711884 neigh_lookup +EXPORT_SYMBOL vmlinux 0x4879278b iov_iter_copy_from_user +EXPORT_SYMBOL vmlinux 0x48bdee41 journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x48ca8975 pskb_copy +EXPORT_SYMBOL vmlinux 0x48d22c77 block_read_full_page +EXPORT_SYMBOL vmlinux 0x49285a3a filemap_fault +EXPORT_SYMBOL vmlinux 0x493e25e1 udp_hash +EXPORT_SYMBOL vmlinux 0x49603fb8 security_sb_copy_data +EXPORT_SYMBOL vmlinux 0x4974c62c blk_cleanup_queue +EXPORT_SYMBOL vmlinux 0x49da9a9a _read_unlock_bh +EXPORT_SYMBOL vmlinux 0x49f8a6c8 dmam_pool_create +EXPORT_SYMBOL vmlinux 0x49fc4552 nobh_write_end +EXPORT_SYMBOL vmlinux 0x4a050829 __skb_warn_lro_forwarding +EXPORT_SYMBOL vmlinux 0x4a32c0f9 netdev_set_master +EXPORT_SYMBOL vmlinux 0x4a358252 __bitmap_subset +EXPORT_SYMBOL vmlinux 0x4a677e17 elv_rb_add +EXPORT_SYMBOL vmlinux 0x4a750928 neigh_resolve_output +EXPORT_SYMBOL vmlinux 0x4a7e5923 tty_hangup +EXPORT_SYMBOL vmlinux 0x4a971ec7 radix_tree_delete +EXPORT_SYMBOL vmlinux 0x4ad4cc95 jbd2_journal_release_buffer +EXPORT_SYMBOL vmlinux 0x4ae3e6b4 ip_route_output_key +EXPORT_SYMBOL vmlinux 0x4afe9a77 scsi_partsize +EXPORT_SYMBOL vmlinux 0x4b07e779 _spin_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x4b172e9e do_SAK +EXPORT_SYMBOL vmlinux 0x4b2f14b4 jiffies_to_timespec +EXPORT_SYMBOL vmlinux 0x4b34fbf5 block_all_signals +EXPORT_SYMBOL vmlinux 0x4b37e873 __module_put_and_exit +EXPORT_SYMBOL vmlinux 0x4b77c0d1 tcf_hash_insert +EXPORT_SYMBOL vmlinux 0x4b8b453a scsi_cmd_ioctl +EXPORT_SYMBOL vmlinux 0x4bbc3e5f pm_flags +EXPORT_SYMBOL vmlinux 0x4bc91333 netif_device_attach +EXPORT_SYMBOL vmlinux 0x4c1182cb bitmap_scnprintf +EXPORT_SYMBOL vmlinux 0x4c2adde4 generic_file_aio_read +EXPORT_SYMBOL vmlinux 0x4c43a1a2 udp_lib_getsockopt +EXPORT_SYMBOL vmlinux 0x4cb10970 eth_header +EXPORT_SYMBOL vmlinux 0x4cbbd171 __bitmap_weight +EXPORT_SYMBOL vmlinux 0x4cbf7ff9 seq_puts +EXPORT_SYMBOL vmlinux 0x4cdcfb5d write_inode_now +EXPORT_SYMBOL vmlinux 0x4d2dc830 acpi_get_object_info +EXPORT_SYMBOL vmlinux 0x4d3c153f sigprocmask +EXPORT_SYMBOL vmlinux 0x4d783eae tc_classify_compat +EXPORT_SYMBOL vmlinux 0x4d85793f nla_put_nohdr +EXPORT_SYMBOL vmlinux 0x4d9f41bb __dev_get_by_index +EXPORT_SYMBOL vmlinux 0x4dc1f697 __free_pages +EXPORT_SYMBOL vmlinux 0x4dd68b96 neigh_compat_output +EXPORT_SYMBOL vmlinux 0x4ddc4b9f utf8_mbtowc +EXPORT_SYMBOL vmlinux 0x4df119fa __bitmap_parse +EXPORT_SYMBOL vmlinux 0x4df388fd cfb_copyarea +EXPORT_SYMBOL vmlinux 0x4e100f60 _spin_unlock_irq +EXPORT_SYMBOL vmlinux 0x4e3567f7 match_int +EXPORT_SYMBOL vmlinux 0x4e6e8ea7 fg_console +EXPORT_SYMBOL vmlinux 0x4e830a3e strnicmp +EXPORT_SYMBOL vmlinux 0x4ea7cecc blk_remove_plug +EXPORT_SYMBOL vmlinux 0x4ed42e4c textsearch_find_continuous +EXPORT_SYMBOL vmlinux 0x4f476e96 init_cdrom_command +EXPORT_SYMBOL vmlinux 0x4f5438c1 idle_halt +EXPORT_SYMBOL vmlinux 0x4f91d5f7 acpi_is_video_device +EXPORT_SYMBOL vmlinux 0x4fdee897 i8042_command +EXPORT_SYMBOL vmlinux 0x50211ee3 tcp_free_md5sig_pool +EXPORT_SYMBOL vmlinux 0x5067036d __neigh_for_each_release +EXPORT_SYMBOL vmlinux 0x50709310 register_framebuffer +EXPORT_SYMBOL vmlinux 0x507b090b cfb_fillrect +EXPORT_SYMBOL vmlinux 0x50b1532d nf_unregister_sockopt +EXPORT_SYMBOL vmlinux 0x50bb4195 pcim_iomap_table +EXPORT_SYMBOL vmlinux 0x50cbcf53 default_llseek +EXPORT_SYMBOL vmlinux 0x50ecceef tty_schedule_flip +EXPORT_SYMBOL vmlinux 0x510e29fd save_mount_options +EXPORT_SYMBOL vmlinux 0x5118c382 secure_dccp_sequence_number +EXPORT_SYMBOL vmlinux 0x511c55ac bd_release +EXPORT_SYMBOL vmlinux 0x514758f5 pci_release_selected_regions +EXPORT_SYMBOL vmlinux 0x5152e605 memcmp +EXPORT_SYMBOL vmlinux 0x518eb764 per_cpu__cpu_number +EXPORT_SYMBOL vmlinux 0x51995ee0 call_usermodehelper_pipe +EXPORT_SYMBOL vmlinux 0x51bc4c88 journal_extend +EXPORT_SYMBOL vmlinux 0x51be3ff1 bdi_unregister +EXPORT_SYMBOL vmlinux 0x51cd13e4 grab_cache_page_nowait +EXPORT_SYMBOL vmlinux 0x51cd71be ps2_drain +EXPORT_SYMBOL vmlinux 0x51d12d4e acpi_pci_disabled +EXPORT_SYMBOL vmlinux 0x51d7a776 acpi_detach_data +EXPORT_SYMBOL vmlinux 0x51dce73b xfrm_state_walk_init +EXPORT_SYMBOL vmlinux 0x51ef33b8 kstrndup +EXPORT_SYMBOL vmlinux 0x51fff8ba unregister_cdrom +EXPORT_SYMBOL vmlinux 0x52026cdf security_sb_parse_opts_str +EXPORT_SYMBOL vmlinux 0x523b4efd pagevec_lookup +EXPORT_SYMBOL vmlinux 0x523bd173 pci_find_slot +EXPORT_SYMBOL vmlinux 0x5265764c blk_queue_stack_limits +EXPORT_SYMBOL vmlinux 0x5268a3e5 blk_unplug +EXPORT_SYMBOL vmlinux 0x527603be ip_xfrm_me_harder +EXPORT_SYMBOL vmlinux 0x528c709d simple_read_from_buffer +EXPORT_SYMBOL vmlinux 0x52a58c24 ifla_policy +EXPORT_SYMBOL vmlinux 0x52aadeab get_super +EXPORT_SYMBOL vmlinux 0x52d7b2fd llc_sap_list +EXPORT_SYMBOL vmlinux 0x52d7d26c tty_register_ldisc +EXPORT_SYMBOL vmlinux 0x52e24296 key_validate +EXPORT_SYMBOL vmlinux 0x52e30c27 sock_register +EXPORT_SYMBOL vmlinux 0x52e97a25 unmap_underlying_metadata +EXPORT_SYMBOL vmlinux 0x52ee88ef blk_queue_max_sectors +EXPORT_SYMBOL vmlinux 0x530b1e98 pm_suspend +EXPORT_SYMBOL vmlinux 0x531b604e __virt_addr_valid +EXPORT_SYMBOL vmlinux 0x532f2924 param_get_byte +EXPORT_SYMBOL vmlinux 0x53326531 mempool_alloc_pages +EXPORT_SYMBOL vmlinux 0x53a3c899 __scm_send +EXPORT_SYMBOL vmlinux 0x53c0767c sk_chk_filter +EXPORT_SYMBOL vmlinux 0x53d9fd68 tty_wait_until_sent +EXPORT_SYMBOL vmlinux 0x53ddd58d nobh_write_begin +EXPORT_SYMBOL vmlinux 0x5417b071 page_symlink +EXPORT_SYMBOL vmlinux 0x54290dc9 nla_validate +EXPORT_SYMBOL vmlinux 0x542e9e71 find_vma +EXPORT_SYMBOL vmlinux 0x543affb5 per_cpu__kstat +EXPORT_SYMBOL vmlinux 0x544781a5 sync_blockdev +EXPORT_SYMBOL vmlinux 0x546757e3 blk_queue_ordered +EXPORT_SYMBOL vmlinux 0x54935666 acpi_os_read_port +EXPORT_SYMBOL vmlinux 0x54b81541 init_timer_deferrable +EXPORT_SYMBOL vmlinux 0x54ba9d95 filemap_fdatawrite_range +EXPORT_SYMBOL vmlinux 0x54bcea63 ethtool_op_set_tx_hw_csum +EXPORT_SYMBOL vmlinux 0x54c4c9ef blk_put_request +EXPORT_SYMBOL vmlinux 0x54e6fcdd net_enable_timestamp +EXPORT_SYMBOL vmlinux 0x54e7f58d eisa_bus_type +EXPORT_SYMBOL vmlinux 0x550bacae submit_bio +EXPORT_SYMBOL vmlinux 0x552364a3 scsi_init_io +EXPORT_SYMBOL vmlinux 0x553f9dd3 down_read_trylock +EXPORT_SYMBOL vmlinux 0x55750ad6 dmam_alloc_noncoherent +EXPORT_SYMBOL vmlinux 0x5594be03 bitmap_remap +EXPORT_SYMBOL vmlinux 0x55b24f94 __alloc_pages_internal +EXPORT_SYMBOL vmlinux 0x55b9c767 call_usermodehelper_setcleanup +EXPORT_SYMBOL vmlinux 0x55f79a92 registered_fb +EXPORT_SYMBOL vmlinux 0x55fc9fc7 pci_get_class +EXPORT_SYMBOL vmlinux 0x5600904f fb_get_color_depth +EXPORT_SYMBOL vmlinux 0x5614b010 xfrm_policy_walk_done +EXPORT_SYMBOL vmlinux 0x5634992b sock_get_timestamp +EXPORT_SYMBOL vmlinux 0x5635a60a vmalloc_user +EXPORT_SYMBOL vmlinux 0x5643fb3e simple_pin_fs +EXPORT_SYMBOL vmlinux 0x56524853 posix_unblock_lock +EXPORT_SYMBOL vmlinux 0x5663b2ff tty_port_tty_set +EXPORT_SYMBOL vmlinux 0x569eaa35 get_disk +EXPORT_SYMBOL vmlinux 0x56c8799d scsi_kunmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x56f494e0 smp_call_function +EXPORT_SYMBOL vmlinux 0x57209c02 write_one_page +EXPORT_SYMBOL vmlinux 0x57273b1b vmalloc_to_page +EXPORT_SYMBOL vmlinux 0x572e85d4 blk_lookup_devt +EXPORT_SYMBOL vmlinux 0x5749eb16 textsearch_register +EXPORT_SYMBOL vmlinux 0x57565976 bio_map_user +EXPORT_SYMBOL vmlinux 0x577cb66b skb_realloc_headroom +EXPORT_SYMBOL vmlinux 0x577cc638 mutex_unlock +EXPORT_SYMBOL vmlinux 0x5780a5e5 eth_header_parse +EXPORT_SYMBOL vmlinux 0x578cd63b nla_append +EXPORT_SYMBOL vmlinux 0x578f2944 generic_file_mmap +EXPORT_SYMBOL vmlinux 0x5791d8a8 set_binfmt +EXPORT_SYMBOL vmlinux 0x57a6504e vsnprintf +EXPORT_SYMBOL vmlinux 0x580a9d61 tty_port_tty_get +EXPORT_SYMBOL vmlinux 0x581de2e6 bio_put +EXPORT_SYMBOL vmlinux 0x58282da1 dquot_drop +EXPORT_SYMBOL vmlinux 0x58337af4 register_cdrom +EXPORT_SYMBOL vmlinux 0x5838f6c9 rtc_valid_tm +EXPORT_SYMBOL vmlinux 0x583df77d sk_send_sigurg +EXPORT_SYMBOL vmlinux 0x584738f9 rdmsr_safe_on_cpu +EXPORT_SYMBOL vmlinux 0x5852a347 tcf_em_tree_validate +EXPORT_SYMBOL vmlinux 0x5857b225 ioread16_rep +EXPORT_SYMBOL vmlinux 0x585ffa44 sk_receive_skb +EXPORT_SYMBOL vmlinux 0x586fb7b6 read_cache_pages +EXPORT_SYMBOL vmlinux 0x58a8df52 mca_register_driver_integrated +EXPORT_SYMBOL vmlinux 0x58cb118f skb_copy_bits +EXPORT_SYMBOL vmlinux 0x58dbac1e blk_plug_device_unlocked +EXPORT_SYMBOL vmlinux 0x58fef6f8 ist_info +EXPORT_SYMBOL vmlinux 0x5909dc6e scsi_execute +EXPORT_SYMBOL vmlinux 0x591c2b86 inet_csk_delete_keepalive_timer +EXPORT_SYMBOL vmlinux 0x5934392b fb_register_client +EXPORT_SYMBOL vmlinux 0x594bf15b ioport_map +EXPORT_SYMBOL vmlinux 0x59706f79 nf_log_unregister_pf +EXPORT_SYMBOL vmlinux 0x5984e4fd acpi_processor_register_performance +EXPORT_SYMBOL vmlinux 0x59a633e0 file_update_time +EXPORT_SYMBOL vmlinux 0x59b782b8 pci_remove_bus +EXPORT_SYMBOL vmlinux 0x59d696b6 register_module_notifier +EXPORT_SYMBOL vmlinux 0x59d8223a ioport_resource +EXPORT_SYMBOL vmlinux 0x5a4896a8 __put_user_2 +EXPORT_SYMBOL vmlinux 0x5a5aa208 tcp_enter_memory_pressure +EXPORT_SYMBOL vmlinux 0x5a60119e init_task +EXPORT_SYMBOL vmlinux 0x5a744b86 netlink_set_nonroot +EXPORT_SYMBOL vmlinux 0x5a9ac3b3 scsi_remove_target +EXPORT_SYMBOL vmlinux 0x5ac376a5 acpi_install_fixed_event_handler +EXPORT_SYMBOL vmlinux 0x5acb5bdc cdrom_open +EXPORT_SYMBOL vmlinux 0x5ad854a3 sock_no_recvmsg +EXPORT_SYMBOL vmlinux 0x5ad872f2 skb_dma_unmap +EXPORT_SYMBOL vmlinux 0x5af2a30e inode_double_unlock +EXPORT_SYMBOL vmlinux 0x5afc871f mpage_writepages +EXPORT_SYMBOL vmlinux 0x5b1232cc journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0x5b19634d div_s64_rem +EXPORT_SYMBOL vmlinux 0x5b2499ba nf_ip_checksum +EXPORT_SYMBOL vmlinux 0x5b2607ec neigh_table_clear +EXPORT_SYMBOL vmlinux 0x5b51c6a7 acpi_walk_resources +EXPORT_SYMBOL vmlinux 0x5bad07ec tty_driver_kref_put +EXPORT_SYMBOL vmlinux 0x5c265cba sg_init_one +EXPORT_SYMBOL vmlinux 0x5c2a8565 proc_create_data +EXPORT_SYMBOL vmlinux 0x5c2e8ca1 kernel_sock_ioctl +EXPORT_SYMBOL vmlinux 0x5c537722 sock_create_kern +EXPORT_SYMBOL vmlinux 0x5c68705b mca_read_pos +EXPORT_SYMBOL vmlinux 0x5cd9f9ee inode_get_bytes +EXPORT_SYMBOL vmlinux 0x5d06e135 dcache_dir_lseek +EXPORT_SYMBOL vmlinux 0x5d2a989d wait_on_sync_kiocb +EXPORT_SYMBOL vmlinux 0x5d353bef elv_rb_find +EXPORT_SYMBOL vmlinux 0x5d6942e7 pnp_unregister_driver +EXPORT_SYMBOL vmlinux 0x5d73b5f8 km_waitq +EXPORT_SYMBOL vmlinux 0x5d85ad6e qdisc_watchdog_cancel +EXPORT_SYMBOL vmlinux 0x5d868d6a skb_queue_tail +EXPORT_SYMBOL vmlinux 0x5db6e6d3 bio_sector_offset +EXPORT_SYMBOL vmlinux 0x5dbcfa4f boot_cpu_physical_apicid +EXPORT_SYMBOL vmlinux 0x5dcf6068 tty_name +EXPORT_SYMBOL vmlinux 0x5dde15a5 fb_get_mode +EXPORT_SYMBOL vmlinux 0x5e0c76ef blkdev_dequeue_request +EXPORT_SYMBOL vmlinux 0x5e25159a dput +EXPORT_SYMBOL vmlinux 0x5e251cf1 xfrm_user_policy +EXPORT_SYMBOL vmlinux 0x5e365665 flush_tlb_page +EXPORT_SYMBOL vmlinux 0x5e79ebec gen_replace_estimator +EXPORT_SYMBOL vmlinux 0x5ea520c5 tcp_select_initial_window +EXPORT_SYMBOL vmlinux 0x5eb980b6 set_pages_x +EXPORT_SYMBOL vmlinux 0x5ec3dde2 acpi_bus_unregister_driver +EXPORT_SYMBOL vmlinux 0x5ed040b0 pm_set_vt_switch +EXPORT_SYMBOL vmlinux 0x5edd0762 bin2bcd +EXPORT_SYMBOL vmlinux 0x5ef4caae remove_proc_entry +EXPORT_SYMBOL vmlinux 0x5f1bd579 mca_find_adapter +EXPORT_SYMBOL vmlinux 0x5f48f1e7 path_get +EXPORT_SYMBOL vmlinux 0x5f75c735 fb_class +EXPORT_SYMBOL vmlinux 0x5f812a93 find_lock_page +EXPORT_SYMBOL vmlinux 0x5fa278a5 netif_rx_ni +EXPORT_SYMBOL vmlinux 0x5fa753c1 uart_get_baud_rate +EXPORT_SYMBOL vmlinux 0x5fd10213 thaw_bdev +EXPORT_SYMBOL vmlinux 0x5fd33bda mark_buffer_dirty +EXPORT_SYMBOL vmlinux 0x5ff2aa87 elv_rb_latter_request +EXPORT_SYMBOL vmlinux 0x5ff42b08 acpi_video_get_capabilities +EXPORT_SYMBOL vmlinux 0x6005137c inet_frags_fini +EXPORT_SYMBOL vmlinux 0x600683d3 do_unblank_screen +EXPORT_SYMBOL vmlinux 0x602e6ebc module_refcount +EXPORT_SYMBOL vmlinux 0x603daa7f pci_enable_device_io +EXPORT_SYMBOL vmlinux 0x608c2831 warn_on_slowpath +EXPORT_SYMBOL vmlinux 0x60902600 inode_double_lock +EXPORT_SYMBOL vmlinux 0x609f1c7e synchronize_net +EXPORT_SYMBOL vmlinux 0x60a32ea9 pm_power_off +EXPORT_SYMBOL vmlinux 0x60afc44e drop_super +EXPORT_SYMBOL vmlinux 0x60b2a1e6 __neigh_event_send +EXPORT_SYMBOL vmlinux 0x60dd7452 __sk_mem_reclaim +EXPORT_SYMBOL vmlinux 0x60eefc02 wireless_spy_update +EXPORT_SYMBOL vmlinux 0x60fe896c redirty_page_for_writepage +EXPORT_SYMBOL vmlinux 0x6111e1bc init_timer +EXPORT_SYMBOL vmlinux 0x612390ad netpoll_set_trap +EXPORT_SYMBOL vmlinux 0x6125af7d sock_wmalloc +EXPORT_SYMBOL vmlinux 0x613d69d8 free_netdev +EXPORT_SYMBOL vmlinux 0x6145af1a generic_block_bmap +EXPORT_SYMBOL vmlinux 0x614b7b15 __brelse +EXPORT_SYMBOL vmlinux 0x614efe09 pagecache_write_end +EXPORT_SYMBOL vmlinux 0x617b315e nf_reinject +EXPORT_SYMBOL vmlinux 0x617e4f9a dquot_commit_info +EXPORT_SYMBOL vmlinux 0x618d8299 set_notify_swap_entry_free +EXPORT_SYMBOL vmlinux 0x61b7b126 simple_strtoull +EXPORT_SYMBOL vmlinux 0x62049256 acpi_disable +EXPORT_SYMBOL vmlinux 0x6237f6b5 acpi_enable_event +EXPORT_SYMBOL vmlinux 0x6241a2ab __copy_from_user_ll_nocache +EXPORT_SYMBOL vmlinux 0x6241fd2c acpi_install_address_space_handler +EXPORT_SYMBOL vmlinux 0x626552c9 __mod_zone_page_state +EXPORT_SYMBOL vmlinux 0x62737e1d sock_unregister +EXPORT_SYMBOL vmlinux 0x627a4fbc vfs_link +EXPORT_SYMBOL vmlinux 0x627ac10a jbd2_journal_abort +EXPORT_SYMBOL vmlinux 0x62827bec security_secctx_to_secid +EXPORT_SYMBOL vmlinux 0x62923cfb proc_doulongvec_minmax +EXPORT_SYMBOL vmlinux 0x62c7e7e7 pnp_stop_dev +EXPORT_SYMBOL vmlinux 0x62d9932e tcf_register_action +EXPORT_SYMBOL vmlinux 0x632cfeed ethtool_op_get_flags +EXPORT_SYMBOL vmlinux 0x6330c450 serio_rescan +EXPORT_SYMBOL vmlinux 0x635631d8 blkdev_issue_flush +EXPORT_SYMBOL vmlinux 0x63569367 pskb_expand_head +EXPORT_SYMBOL vmlinux 0x63632a2b tcf_exts_dump_stats +EXPORT_SYMBOL vmlinux 0x6364723d open_exec +EXPORT_SYMBOL vmlinux 0x636a5691 acpi_register_ioapic +EXPORT_SYMBOL vmlinux 0x6378814f page_readlink +EXPORT_SYMBOL vmlinux 0x637fe602 dev_mc_unsync +EXPORT_SYMBOL vmlinux 0x63cc6cf2 tcp_create_openreq_child +EXPORT_SYMBOL vmlinux 0x63d8710b jbd2_journal_stop +EXPORT_SYMBOL vmlinux 0x63ecad53 register_netdevice_notifier +EXPORT_SYMBOL vmlinux 0x6403e338 tcp_memory_pressure +EXPORT_SYMBOL vmlinux 0x64283ba5 poll_freewait +EXPORT_SYMBOL vmlinux 0x642e54ac __wake_up +EXPORT_SYMBOL vmlinux 0x6451294b posix_acl_valid +EXPORT_SYMBOL vmlinux 0x6466a1e6 mempool_alloc +EXPORT_SYMBOL vmlinux 0x6478134c ec_burst_enable +EXPORT_SYMBOL vmlinux 0x64999478 congestion_wait +EXPORT_SYMBOL vmlinux 0x64a6a7c8 posix_lock_file +EXPORT_SYMBOL vmlinux 0x64cd5d16 init_waitqueue_head +EXPORT_SYMBOL vmlinux 0x64d99179 inet_sendmsg +EXPORT_SYMBOL vmlinux 0x64eae7ad set_memory_array_wb +EXPORT_SYMBOL vmlinux 0x650128e7 br_fdb_get_hook +EXPORT_SYMBOL vmlinux 0x650fb346 add_wait_queue +EXPORT_SYMBOL vmlinux 0x651a4139 test_taint +EXPORT_SYMBOL vmlinux 0x65286e16 pneigh_enqueue +EXPORT_SYMBOL vmlinux 0x65408378 zlib_inflate_blob +EXPORT_SYMBOL vmlinux 0x65414e67 dev_valid_name +EXPORT_SYMBOL vmlinux 0x65509c46 elv_rb_former_request +EXPORT_SYMBOL vmlinux 0x6567ae60 key_link +EXPORT_SYMBOL vmlinux 0x656a299f n_tty_ioctl_helper +EXPORT_SYMBOL vmlinux 0x65998934 skb_dequeue +EXPORT_SYMBOL vmlinux 0x65a252f7 tcf_em_tree_dump +EXPORT_SYMBOL vmlinux 0x65b7efd1 mmc_release_host +EXPORT_SYMBOL vmlinux 0x65eedb80 register_sysctl_paths +EXPORT_SYMBOL vmlinux 0x66157288 jbd2_journal_get_undo_access +EXPORT_SYMBOL vmlinux 0x662a7d75 grab_cache_page_write_begin +EXPORT_SYMBOL vmlinux 0x66526e9e check_disk_size_change +EXPORT_SYMBOL vmlinux 0x665986ea fget +EXPORT_SYMBOL vmlinux 0x66672b63 jbd2_journal_force_commit +EXPORT_SYMBOL vmlinux 0x666dcaa6 netif_rx +EXPORT_SYMBOL vmlinux 0x6672d0e5 bdput +EXPORT_SYMBOL vmlinux 0x668da8d5 zlib_inflateIncomp +EXPORT_SYMBOL vmlinux 0x66f3ac82 eth_type_trans +EXPORT_SYMBOL vmlinux 0x66ff33d5 qdisc_reset +EXPORT_SYMBOL vmlinux 0x6704e286 scsi_scan_host +EXPORT_SYMBOL vmlinux 0x670798ca skb_clone +EXPORT_SYMBOL vmlinux 0x6729d3df __get_user_4 +EXPORT_SYMBOL vmlinux 0x6756dc1e ilookup5_nowait +EXPORT_SYMBOL vmlinux 0x67859aa9 inet_sk_rebuild_header +EXPORT_SYMBOL vmlinux 0x67a98cdb unregister_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0x67b27ec1 tty_std_termios +EXPORT_SYMBOL vmlinux 0x67b610b3 backlight_device_register +EXPORT_SYMBOL vmlinux 0x67c55f98 sock_common_setsockopt +EXPORT_SYMBOL vmlinux 0x67e71b77 __mutex_init +EXPORT_SYMBOL vmlinux 0x67f63d9a __splice_from_pipe +EXPORT_SYMBOL vmlinux 0x67f94e04 blk_queue_end_tag +EXPORT_SYMBOL vmlinux 0x6802d62b pci_scan_bridge +EXPORT_SYMBOL vmlinux 0x682a8c8f bdevname +EXPORT_SYMBOL vmlinux 0x682b2473 d_path +EXPORT_SYMBOL vmlinux 0x686c08b3 task_pgrp_nr_ns +EXPORT_SYMBOL vmlinux 0x686e8bac arp_broken_ops +EXPORT_SYMBOL vmlinux 0x687837c3 blk_queue_prep_rq +EXPORT_SYMBOL vmlinux 0x689a19fd arp_tbl +EXPORT_SYMBOL vmlinux 0x68ebc6e5 bdget +EXPORT_SYMBOL vmlinux 0x6926ed26 truncate_inode_pages +EXPORT_SYMBOL vmlinux 0x692c2d9c __request_region +EXPORT_SYMBOL vmlinux 0x6971447a rtc_month_days +EXPORT_SYMBOL vmlinux 0x6986d5f5 filp_close +EXPORT_SYMBOL vmlinux 0x69927dff try_acquire_console_sem +EXPORT_SYMBOL vmlinux 0x69a0ca7d iowrite16be +EXPORT_SYMBOL vmlinux 0x69b89667 dst_alloc +EXPORT_SYMBOL vmlinux 0x69bd7bdf dev_disable_lro +EXPORT_SYMBOL vmlinux 0x69c8c1d5 security_req_classify_flow +EXPORT_SYMBOL vmlinux 0x69d2575f efi +EXPORT_SYMBOL vmlinux 0x69d38ed9 __scsi_print_sense +EXPORT_SYMBOL vmlinux 0x69e27c7a bitmap_copy_le +EXPORT_SYMBOL vmlinux 0x69ea098b sk_stream_wait_memory +EXPORT_SYMBOL vmlinux 0x69edea2c blk_queue_update_dma_pad +EXPORT_SYMBOL vmlinux 0x6a037cf1 mempool_kfree +EXPORT_SYMBOL vmlinux 0x6a10e078 uart_unregister_driver +EXPORT_SYMBOL vmlinux 0x6a1edda6 no_llseek +EXPORT_SYMBOL vmlinux 0x6a27bfce csum_partial_copy_generic +EXPORT_SYMBOL vmlinux 0x6a282381 xfrm_input_resume +EXPORT_SYMBOL vmlinux 0x6a47571d __set_personality +EXPORT_SYMBOL vmlinux 0x6a6cc4bb key_payload_reserve +EXPORT_SYMBOL vmlinux 0x6a7057a1 scsi_report_bus_reset +EXPORT_SYMBOL vmlinux 0x6ac37174 tty_unregister_driver +EXPORT_SYMBOL vmlinux 0x6acb973d iowrite32be +EXPORT_SYMBOL vmlinux 0x6ace338e pci_scan_single_device +EXPORT_SYMBOL vmlinux 0x6ad85887 acpi_enable_gpe +EXPORT_SYMBOL vmlinux 0x6ada9b61 nf_setsockopt +EXPORT_SYMBOL vmlinux 0x6add5c9a dmi_find_device +EXPORT_SYMBOL vmlinux 0x6af3217b pci_unregister_driver +EXPORT_SYMBOL vmlinux 0x6b1b67d3 __bdevname +EXPORT_SYMBOL vmlinux 0x6b2dc060 dump_stack +EXPORT_SYMBOL vmlinux 0x6b558ddd page_address +EXPORT_SYMBOL vmlinux 0x6b6034d6 __set_page_dirty_buffers +EXPORT_SYMBOL vmlinux 0x6b651511 acpi_bus_generate_proc_event +EXPORT_SYMBOL vmlinux 0x6b8f8e2d blk_rq_map_user +EXPORT_SYMBOL vmlinux 0x6b937ffb mca_mark_as_used +EXPORT_SYMBOL vmlinux 0x6b9755a0 add_disk +EXPORT_SYMBOL vmlinux 0x6b9b88f3 sleep_on +EXPORT_SYMBOL vmlinux 0x6b9bd5f4 set_bdi_congested +EXPORT_SYMBOL vmlinux 0x6b9df764 netlink_rcv_skb +EXPORT_SYMBOL vmlinux 0x6bafbced mod_timer +EXPORT_SYMBOL vmlinux 0x6bc28220 input_grab_device +EXPORT_SYMBOL vmlinux 0x6bdcfd99 qdisc_class_hash_remove +EXPORT_SYMBOL vmlinux 0x6c1ce5ce strcspn +EXPORT_SYMBOL vmlinux 0x6c25cf70 inode_init_once +EXPORT_SYMBOL vmlinux 0x6c27d11d mca_device_read_pos +EXPORT_SYMBOL vmlinux 0x6c2de1d8 netpoll_cleanup +EXPORT_SYMBOL vmlinux 0x6c2e3320 strncmp +EXPORT_SYMBOL vmlinux 0x6c3562e9 seq_release_private +EXPORT_SYMBOL vmlinux 0x6c389761 acpi_bus_get_private_data +EXPORT_SYMBOL vmlinux 0x6c61ce70 num_registered_fb +EXPORT_SYMBOL vmlinux 0x6c6b26b0 skb_insert +EXPORT_SYMBOL vmlinux 0x6c702af7 sysctl_udp_rmem_min +EXPORT_SYMBOL vmlinux 0x6ca2158e kernel_getpeername +EXPORT_SYMBOL vmlinux 0x6ca5c480 unregister_console +EXPORT_SYMBOL vmlinux 0x6cb73e1a vfs_quota_on +EXPORT_SYMBOL vmlinux 0x6cbf6c87 tcf_exts_destroy +EXPORT_SYMBOL vmlinux 0x6cdc5c6b nla_strlcpy +EXPORT_SYMBOL vmlinux 0x6cebcaff dma_async_client_register +EXPORT_SYMBOL vmlinux 0x6cf08a7e bio_clone +EXPORT_SYMBOL vmlinux 0x6d0da34c param_get_short +EXPORT_SYMBOL vmlinux 0x6d10832b key_put +EXPORT_SYMBOL vmlinux 0x6d231129 inet_accept +EXPORT_SYMBOL vmlinux 0x6d27ef64 __bitmap_empty +EXPORT_SYMBOL vmlinux 0x6d288375 radix_tree_next_hole +EXPORT_SYMBOL vmlinux 0x6d294e43 clock_t_to_jiffies +EXPORT_SYMBOL vmlinux 0x6d340f64 tty_termios_input_baud_rate +EXPORT_SYMBOL vmlinux 0x6d3dd7cc jbd2_journal_invalidatepage +EXPORT_SYMBOL vmlinux 0x6d464175 __sg_free_table +EXPORT_SYMBOL vmlinux 0x6d4c2b13 tcp_proc_register +EXPORT_SYMBOL vmlinux 0x6d56994a cmpxchg_486_u64 +EXPORT_SYMBOL vmlinux 0x6d5be4a3 dev_unicast_unsync +EXPORT_SYMBOL vmlinux 0x6d74b4b4 mb_cache_entry_insert +EXPORT_SYMBOL vmlinux 0x6d85d909 __mmc_claim_host +EXPORT_SYMBOL vmlinux 0x6d929a40 alloc_tty_driver +EXPORT_SYMBOL vmlinux 0x6d9bc6db create_proc_entry +EXPORT_SYMBOL vmlinux 0x6db10c2a do_splice_from +EXPORT_SYMBOL vmlinux 0x6dc0c24b complete_and_exit +EXPORT_SYMBOL vmlinux 0x6dcc0f01 new_inode +EXPORT_SYMBOL vmlinux 0x6dcfd380 boot_cpu_data +EXPORT_SYMBOL vmlinux 0x6dddb6cb vfs_follow_link +EXPORT_SYMBOL vmlinux 0x6dee7be5 dump_fpu +EXPORT_SYMBOL vmlinux 0x6def2db2 half_md4_transform +EXPORT_SYMBOL vmlinux 0x6e07a54e acpi_get_gpe_status +EXPORT_SYMBOL vmlinux 0x6e1a4bbb udp_hash_lock +EXPORT_SYMBOL vmlinux 0x6e38e4da udp_proc_register +EXPORT_SYMBOL vmlinux 0x6e440b58 memcpy_fromiovecend +EXPORT_SYMBOL vmlinux 0x6e720ff2 rtnl_unlock +EXPORT_SYMBOL vmlinux 0x6e9dd606 __symbol_put +EXPORT_SYMBOL vmlinux 0x6e9ffffd register_netdevice +EXPORT_SYMBOL vmlinux 0x6ead242b cond_resched_lock +EXPORT_SYMBOL vmlinux 0x6ec3b50b dev_get_by_index +EXPORT_SYMBOL vmlinux 0x6ed4c329 locks_mandatory_area +EXPORT_SYMBOL vmlinux 0x6ed8a758 tcf_action_dump_1 +EXPORT_SYMBOL vmlinux 0x6ef0de40 invalidate_inodes +EXPORT_SYMBOL vmlinux 0x6ef41ccf fb_pan_display +EXPORT_SYMBOL vmlinux 0x6f2fb5ab scsi_remove_host +EXPORT_SYMBOL vmlinux 0x6f3ba95b kmem_cache_destroy +EXPORT_SYMBOL vmlinux 0x6f47d60c blk_queue_merge_bvec +EXPORT_SYMBOL vmlinux 0x6f49d31d scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0x6f8df5ca jbd2_journal_forget +EXPORT_SYMBOL vmlinux 0x6fa5c0ca bio_phys_segments +EXPORT_SYMBOL vmlinux 0x6fb4f177 generic_file_llseek_unlocked +EXPORT_SYMBOL vmlinux 0x6fcb87a1 touch_softlockup_watchdog +EXPORT_SYMBOL vmlinux 0x6fe7c674 pci_set_mwi +EXPORT_SYMBOL vmlinux 0x6ffe59cb __dec_zone_page_state +EXPORT_SYMBOL vmlinux 0x7008a9b7 timespec_to_jiffies +EXPORT_SYMBOL vmlinux 0x701d0ebd snprintf +EXPORT_SYMBOL vmlinux 0x70442750 register_netdev +EXPORT_SYMBOL vmlinux 0x70461a22 key_revoke +EXPORT_SYMBOL vmlinux 0x7054a3e4 request_dma +EXPORT_SYMBOL vmlinux 0x7056b8f5 remove_inode_hash +EXPORT_SYMBOL vmlinux 0x706356f8 block_is_partially_uptodate +EXPORT_SYMBOL vmlinux 0x70890a5a jbd2_log_wait_commit +EXPORT_SYMBOL vmlinux 0x70ad2b6b kblockd_schedule_work +EXPORT_SYMBOL vmlinux 0x70d1f8f3 strncat +EXPORT_SYMBOL vmlinux 0x70d8ab82 acpi_acquire_global_lock +EXPORT_SYMBOL vmlinux 0x70d968e1 blk_get_request +EXPORT_SYMBOL vmlinux 0x70e0d61f cpu_all_bits +EXPORT_SYMBOL vmlinux 0x70ef12e4 pci_lost_interrupt +EXPORT_SYMBOL vmlinux 0x7129e5f8 hex_asc +EXPORT_SYMBOL vmlinux 0x712aa29b _spin_lock_irqsave +EXPORT_SYMBOL vmlinux 0x71356fba remove_wait_queue +EXPORT_SYMBOL vmlinux 0x714c7a81 acpi_check_mem_region +EXPORT_SYMBOL vmlinux 0x7171121c overflowgid +EXPORT_SYMBOL vmlinux 0x71907357 keyring_search +EXPORT_SYMBOL vmlinux 0x71a50dbc register_blkdev +EXPORT_SYMBOL vmlinux 0x71c5ad47 dev_unicast_sync +EXPORT_SYMBOL vmlinux 0x71ce3caf tcp_rcv_established +EXPORT_SYMBOL vmlinux 0x71fe70ca sync_dirty_buffer +EXPORT_SYMBOL vmlinux 0x7214a2a0 generic_file_splice_read +EXPORT_SYMBOL vmlinux 0x72270e35 do_gettimeofday +EXPORT_SYMBOL vmlinux 0x725dc6df clocksource_register +EXPORT_SYMBOL vmlinux 0x7276b7b5 mod_zone_page_state +EXPORT_SYMBOL vmlinux 0x7285a980 scsi_scan_target +EXPORT_SYMBOL vmlinux 0x72924d76 vfs_llseek +EXPORT_SYMBOL vmlinux 0x72a99220 pci_dev_put +EXPORT_SYMBOL vmlinux 0x72b243d4 free_dma +EXPORT_SYMBOL vmlinux 0x72bb04d7 audit_log_format +EXPORT_SYMBOL vmlinux 0x72bf2140 mtrr_add +EXPORT_SYMBOL vmlinux 0x72d02a49 journal_errno +EXPORT_SYMBOL vmlinux 0x72e06055 vfs_dq_drop +EXPORT_SYMBOL vmlinux 0x72ea7b2d scsi_device_type +EXPORT_SYMBOL vmlinux 0x72f89253 xfrm_state_update +EXPORT_SYMBOL vmlinux 0x73513897 ip_queue_xmit +EXPORT_SYMBOL vmlinux 0x735a0bd5 native_io_delay +EXPORT_SYMBOL vmlinux 0x7376a1fd inet_dgram_connect +EXPORT_SYMBOL vmlinux 0x738803e6 strnlen +EXPORT_SYMBOL vmlinux 0x7389c9a8 acpi_bus_get_power +EXPORT_SYMBOL vmlinux 0x73bc1484 scsi_put_command +EXPORT_SYMBOL vmlinux 0x73e20c1c strlcpy +EXPORT_SYMBOL vmlinux 0x73fd5453 dev_get_flags +EXPORT_SYMBOL vmlinux 0x740a1b95 reserve_evntsel_nmi +EXPORT_SYMBOL vmlinux 0x7413793a EISA_bus +EXPORT_SYMBOL vmlinux 0x742b3977 scsi_eh_restore_cmnd +EXPORT_SYMBOL vmlinux 0x74321dbd blk_queue_hardsect_size +EXPORT_SYMBOL vmlinux 0x743250f8 read_dev_sector +EXPORT_SYMBOL vmlinux 0x7434b654 sock_no_socketpair +EXPORT_SYMBOL vmlinux 0x7436ff42 blk_queue_bounce_limit +EXPORT_SYMBOL vmlinux 0x743e2a41 blk_init_tags +EXPORT_SYMBOL vmlinux 0x74420304 generic_file_buffered_write +EXPORT_SYMBOL vmlinux 0x7448c8bf scsi_is_host_device +EXPORT_SYMBOL vmlinux 0x7485e15e unregister_chrdev_region +EXPORT_SYMBOL vmlinux 0x748caf40 down +EXPORT_SYMBOL vmlinux 0x74b4fbe7 scsi_prep_return +EXPORT_SYMBOL vmlinux 0x74bfd5c8 blk_init_queue +EXPORT_SYMBOL vmlinux 0x74cc1cbe unregister_cpu_notifier +EXPORT_SYMBOL vmlinux 0x74cc238d current_kernel_time +EXPORT_SYMBOL vmlinux 0x74cd6bd0 __xfrm_lookup +EXPORT_SYMBOL vmlinux 0x74dcb070 input_free_device +EXPORT_SYMBOL vmlinux 0x74e63407 acpi_unlock_battery_dir +EXPORT_SYMBOL vmlinux 0x750857b4 dentry_unhash +EXPORT_SYMBOL vmlinux 0x75271716 save_processor_state +EXPORT_SYMBOL vmlinux 0x7530238c tcp_simple_retransmit +EXPORT_SYMBOL vmlinux 0x75566739 complete_request_key +EXPORT_SYMBOL vmlinux 0x755f7821 tty_register_device +EXPORT_SYMBOL vmlinux 0x758a15ba register_key_type +EXPORT_SYMBOL vmlinux 0x758d8f27 mpage_bio_submit +EXPORT_SYMBOL vmlinux 0x759bad63 blk_queue_make_request +EXPORT_SYMBOL vmlinux 0x75ae3dd4 uart_remove_one_port +EXPORT_SYMBOL vmlinux 0x75e1f0e3 __ht_create_irq +EXPORT_SYMBOL vmlinux 0x760a0f4f yield +EXPORT_SYMBOL vmlinux 0x760b437a unregister_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x763579b2 tcp_proc_unregister +EXPORT_SYMBOL vmlinux 0x763a0ad5 __xfrm_decode_session +EXPORT_SYMBOL vmlinux 0x767ddb02 set_memory_wc +EXPORT_SYMBOL vmlinux 0x768cdce2 dst_discard +EXPORT_SYMBOL vmlinux 0x76b0f8f8 bad_dma_address +EXPORT_SYMBOL vmlinux 0x76b626f3 xfrm_register_type +EXPORT_SYMBOL vmlinux 0x76bf656d __bitmap_shift_left +EXPORT_SYMBOL vmlinux 0x76cf5fdf neigh_update +EXPORT_SYMBOL vmlinux 0x76d3cd60 laptop_mode +EXPORT_SYMBOL vmlinux 0x76eb08fe llc_mac_hdr_init +EXPORT_SYMBOL vmlinux 0x76f3f8a5 num_k8_northbridges +EXPORT_SYMBOL vmlinux 0x770a0036 isapnp_cfg_begin +EXPORT_SYMBOL vmlinux 0x7756c95d scsi_dma_unmap +EXPORT_SYMBOL vmlinux 0x77658ae7 blk_queue_max_hw_segments +EXPORT_SYMBOL vmlinux 0x77a108df _write_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x77a68024 input_register_handler +EXPORT_SYMBOL vmlinux 0x77a90139 mb_cache_entry_get +EXPORT_SYMBOL vmlinux 0x77ecac9f zlib_inflateEnd +EXPORT_SYMBOL vmlinux 0x7811ee84 per_cpu__softnet_data +EXPORT_SYMBOL vmlinux 0x782d8dd8 mmc_detect_change +EXPORT_SYMBOL vmlinux 0x783d0db0 security_inode_init_security +EXPORT_SYMBOL vmlinux 0x78797c51 nf_register_hook +EXPORT_SYMBOL vmlinux 0x788fe103 iomem_resource +EXPORT_SYMBOL vmlinux 0x78a484c9 _read_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x78bc8428 llc_build_and_send_ui_pkt +EXPORT_SYMBOL vmlinux 0x78c95b09 netpoll_poll +EXPORT_SYMBOL vmlinux 0x78cb2783 down_write_trylock +EXPORT_SYMBOL vmlinux 0x78df6bd7 no_pci_devices +EXPORT_SYMBOL vmlinux 0x7908fd52 mca_device_transform_memory +EXPORT_SYMBOL vmlinux 0x79178a3a ip_defrag +EXPORT_SYMBOL vmlinux 0x791bc859 blk_init_queue_node +EXPORT_SYMBOL vmlinux 0x7925cba8 kernel_recvmsg +EXPORT_SYMBOL vmlinux 0x7928d84a pci_save_state +EXPORT_SYMBOL vmlinux 0x79391a7b vfs_quota_on_path +EXPORT_SYMBOL vmlinux 0x793f5ec1 blkdev_issue_discard +EXPORT_SYMBOL vmlinux 0x794487ee disable_hlt +EXPORT_SYMBOL vmlinux 0x796fc5ce scsi_get_sense_info_fld +EXPORT_SYMBOL vmlinux 0x797ea0ff scsi_unblock_requests +EXPORT_SYMBOL vmlinux 0x79a1e15c vfs_write +EXPORT_SYMBOL vmlinux 0x79aa04a2 get_random_bytes +EXPORT_SYMBOL vmlinux 0x79b9f050 put_filp +EXPORT_SYMBOL vmlinux 0x79bd96af shrink_dcache_sb +EXPORT_SYMBOL vmlinux 0x7a29415f acpi_lock_ac_dir +EXPORT_SYMBOL vmlinux 0x7a2a837d strict_strtol +EXPORT_SYMBOL vmlinux 0x7a3c7076 inet_dgram_ops +EXPORT_SYMBOL vmlinux 0x7a80f3b2 isapnp_protocol +EXPORT_SYMBOL vmlinux 0x7a848702 _read_lock_irqsave +EXPORT_SYMBOL vmlinux 0x7ab5daef dquot_free_inode +EXPORT_SYMBOL vmlinux 0x7ac0b22b alloc_netdev_mq +EXPORT_SYMBOL vmlinux 0x7ac56581 serio_unregister_child_port +EXPORT_SYMBOL vmlinux 0x7acf3c3c scsi_host_lookup +EXPORT_SYMBOL vmlinux 0x7ae49896 acpi_root_dir +EXPORT_SYMBOL vmlinux 0x7aec9089 clear_user +EXPORT_SYMBOL vmlinux 0x7afca02e dmam_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0x7b0c84c4 acpi_remove_table_handler +EXPORT_SYMBOL vmlinux 0x7b134ddf acpi_get_name +EXPORT_SYMBOL vmlinux 0x7b4e8bfe free_task +EXPORT_SYMBOL vmlinux 0x7b52a859 wrmsr_safe_on_cpu +EXPORT_SYMBOL vmlinux 0x7b69467e posix_acl_from_xattr +EXPORT_SYMBOL vmlinux 0x7b6efd52 dma_mark_declared_memory_occupied +EXPORT_SYMBOL vmlinux 0x7b7c8ee9 get_sb_pseudo +EXPORT_SYMBOL vmlinux 0x7b9ba7cd blk_rq_map_kern +EXPORT_SYMBOL vmlinux 0x7bc5ca03 acpi_processor_unregister_performance +EXPORT_SYMBOL vmlinux 0x7bd76097 ethtool_op_set_tx_csum +EXPORT_SYMBOL vmlinux 0x7c0689ee mpage_writepage +EXPORT_SYMBOL vmlinux 0x7c0edd7d acpi_check_region +EXPORT_SYMBOL vmlinux 0x7c17b61d sg_miter_start +EXPORT_SYMBOL vmlinux 0x7c341c54 pnp_device_detach +EXPORT_SYMBOL vmlinux 0x7c42a608 qdisc_watchdog_schedule +EXPORT_SYMBOL vmlinux 0x7c46233a cpufreq_quick_get +EXPORT_SYMBOL vmlinux 0x7c5068cb elv_next_request +EXPORT_SYMBOL vmlinux 0x7c5de9e8 mca_device_claimed +EXPORT_SYMBOL vmlinux 0x7c60d66e getname +EXPORT_SYMBOL vmlinux 0x7c904ded unregister_module_notifier +EXPORT_SYMBOL vmlinux 0x7c934a24 inet_addr_type +EXPORT_SYMBOL vmlinux 0x7ca39b01 xfrm_state_register_afinfo +EXPORT_SYMBOL vmlinux 0x7cb1ae69 cpu_down +EXPORT_SYMBOL vmlinux 0x7cef2f87 set_bh_page +EXPORT_SYMBOL vmlinux 0x7d047e7e acpi_ut_exception +EXPORT_SYMBOL vmlinux 0x7d11c268 jiffies +EXPORT_SYMBOL vmlinux 0x7d1fa099 blk_sync_queue +EXPORT_SYMBOL vmlinux 0x7d52126f nobh_writepage +EXPORT_SYMBOL vmlinux 0x7d53e56a xfrm_alloc_spi +EXPORT_SYMBOL vmlinux 0x7d79a978 request_key_with_auxdata +EXPORT_SYMBOL vmlinux 0x7d850612 utf8_mbstowcs +EXPORT_SYMBOL vmlinux 0x7db862a8 seq_path +EXPORT_SYMBOL vmlinux 0x7db9af68 alloc_pci_dev +EXPORT_SYMBOL vmlinux 0x7dceceac capable +EXPORT_SYMBOL vmlinux 0x7dd24b4a filp_open +EXPORT_SYMBOL vmlinux 0x7df37514 pnpbios_protocol +EXPORT_SYMBOL vmlinux 0x7e3f198f sk_free +EXPORT_SYMBOL vmlinux 0x7e84e289 lease_modify +EXPORT_SYMBOL vmlinux 0x7e9ebb05 kernel_thread +EXPORT_SYMBOL vmlinux 0x7ea731d3 scsi_target_quiesce +EXPORT_SYMBOL vmlinux 0x7eaff494 pci_get_slot +EXPORT_SYMBOL vmlinux 0x7ec25d8b kobject_get +EXPORT_SYMBOL vmlinux 0x7ee5ae03 cdrom_number_of_slots +EXPORT_SYMBOL vmlinux 0x7ee91c1d _spin_trylock +EXPORT_SYMBOL vmlinux 0x7f24de73 jiffies_to_usecs +EXPORT_SYMBOL vmlinux 0x7f61fc5a pci_pme_active +EXPORT_SYMBOL vmlinux 0x7f8723bd pcie_mch_quirk +EXPORT_SYMBOL vmlinux 0x7f9155f6 tty_port_free_xmit_buf +EXPORT_SYMBOL vmlinux 0x7f93931e llc_sap_close +EXPORT_SYMBOL vmlinux 0x7fa3642f tcp_make_synack +EXPORT_SYMBOL vmlinux 0x7fb37e55 blk_complete_request +EXPORT_SYMBOL vmlinux 0x80312e74 skb_over_panic +EXPORT_SYMBOL vmlinux 0x8031fcf6 skb_pull +EXPORT_SYMBOL vmlinux 0x8047200a fb_set_cmap +EXPORT_SYMBOL vmlinux 0x80539ecc kernel_sendmsg +EXPORT_SYMBOL vmlinux 0x8063f83d radix_tree_gang_lookup +EXPORT_SYMBOL vmlinux 0x8069e584 rtnl_unicast +EXPORT_SYMBOL vmlinux 0x807ff4a2 request_firmware +EXPORT_SYMBOL vmlinux 0x80c2e894 cdrom_get_media_event +EXPORT_SYMBOL vmlinux 0x80f085b7 release_sock +EXPORT_SYMBOL vmlinux 0x80f0b8c5 qdisc_tree_decrease_qlen +EXPORT_SYMBOL vmlinux 0x812e08ef tcp_initialize_rcv_mss +EXPORT_SYMBOL vmlinux 0x8132e305 path_permission +EXPORT_SYMBOL vmlinux 0x81472677 acpi_get_table +EXPORT_SYMBOL vmlinux 0x814e7730 nf_ct_destroy +EXPORT_SYMBOL vmlinux 0x815b5dd4 match_octal +EXPORT_SYMBOL vmlinux 0x815f2897 empty_zero_page +EXPORT_SYMBOL vmlinux 0x81799cee vscnprintf +EXPORT_SYMBOL vmlinux 0x81b0540c elv_rq_merge_ok +EXPORT_SYMBOL vmlinux 0x81bb8fba __xfrm_state_delete +EXPORT_SYMBOL vmlinux 0x81d944fe scsi_get_command +EXPORT_SYMBOL vmlinux 0x81e6b37f dmi_get_system_info +EXPORT_SYMBOL vmlinux 0x82057cb8 pci_set_dma_mask +EXPORT_SYMBOL vmlinux 0x82072614 tasklet_kill +EXPORT_SYMBOL vmlinux 0x820873a3 __tcf_em_tree_match +EXPORT_SYMBOL vmlinux 0x820d225f print_mac +EXPORT_SYMBOL vmlinux 0x820f8021 __scsi_iterate_devices +EXPORT_SYMBOL vmlinux 0x8235805b memmove +EXPORT_SYMBOL vmlinux 0x8250ceb9 init_special_inode +EXPORT_SYMBOL vmlinux 0x8251bcc3 bitmap_release_region +EXPORT_SYMBOL vmlinux 0x825d1767 pci_remove_behind_bridge +EXPORT_SYMBOL vmlinux 0x82621542 make_bad_inode +EXPORT_SYMBOL vmlinux 0x82673561 schedule_delayed_work +EXPORT_SYMBOL vmlinux 0x828f6b2b request_key_async +EXPORT_SYMBOL vmlinux 0x82a9d71f netpoll_setup +EXPORT_SYMBOL vmlinux 0x82acfccf unregister_con_driver +EXPORT_SYMBOL vmlinux 0x8309bafa jbd2_journal_start +EXPORT_SYMBOL vmlinux 0x8317e20a completion_done +EXPORT_SYMBOL vmlinux 0x8343938d tcp_getsockopt +EXPORT_SYMBOL vmlinux 0x83800bfa kref_init +EXPORT_SYMBOL vmlinux 0x83a476ce bitmap_scnlistprintf +EXPORT_SYMBOL vmlinux 0x83bd8e51 sget +EXPORT_SYMBOL vmlinux 0x843cfb87 mmc_align_data_size +EXPORT_SYMBOL vmlinux 0x8448fc04 input_unregister_handler +EXPORT_SYMBOL vmlinux 0x846d6e6a submit_bh +EXPORT_SYMBOL vmlinux 0x84785c15 block_write_end +EXPORT_SYMBOL vmlinux 0x849995be bh_submit_read +EXPORT_SYMBOL vmlinux 0x84dfc57d seq_bitmap +EXPORT_SYMBOL vmlinux 0x84e1d84f blk_alloc_queue +EXPORT_SYMBOL vmlinux 0x84fc6129 neigh_table_init_no_netlink +EXPORT_SYMBOL vmlinux 0x85670f1d rtnl_is_locked +EXPORT_SYMBOL vmlinux 0x856c235e jbd2_journal_set_features +EXPORT_SYMBOL vmlinux 0x85ca504e udp_flush_pending_frames +EXPORT_SYMBOL vmlinux 0x85df9b6c strsep +EXPORT_SYMBOL vmlinux 0x85e7deb2 iov_iter_fault_in_readable +EXPORT_SYMBOL vmlinux 0x863cb91a utf8_wcstombs +EXPORT_SYMBOL vmlinux 0x8664f62e cpufreq_update_policy +EXPORT_SYMBOL vmlinux 0x868acba5 get_options +EXPORT_SYMBOL vmlinux 0x868da5b5 journal_check_available_features +EXPORT_SYMBOL vmlinux 0x86c09764 km_policy_notify +EXPORT_SYMBOL vmlinux 0x86c784d5 unregister_qdisc +EXPORT_SYMBOL vmlinux 0x86e8cef8 dev_remove_pack +EXPORT_SYMBOL vmlinux 0x86fb9b05 bitmap_parse_user +EXPORT_SYMBOL vmlinux 0x87079ba6 tcp_md5_hash_skb_data +EXPORT_SYMBOL vmlinux 0x871b1166 bio_split +EXPORT_SYMBOL vmlinux 0x871c0a7e fiemap_check_flags +EXPORT_SYMBOL vmlinux 0x872e35ca scsi_dma_map +EXPORT_SYMBOL vmlinux 0x8733e9a3 sleep_on_timeout +EXPORT_SYMBOL vmlinux 0x876dafc3 ec_write +EXPORT_SYMBOL vmlinux 0x877e1e5e xfrm_nl +EXPORT_SYMBOL vmlinux 0x8785725d param_set_charp +EXPORT_SYMBOL vmlinux 0x878ab3ce sysctl_tcp_adv_win_scale +EXPORT_SYMBOL vmlinux 0x878ff594 jbd2_journal_revoke +EXPORT_SYMBOL vmlinux 0x87c76bb5 tcf_hash_search +EXPORT_SYMBOL vmlinux 0x87d7d6f4 __nla_put_nohdr +EXPORT_SYMBOL vmlinux 0x87f59fea inet_del_protocol +EXPORT_SYMBOL vmlinux 0x880f574b sk_reset_timer +EXPORT_SYMBOL vmlinux 0x881039d0 zlib_inflate +EXPORT_SYMBOL vmlinux 0x88352a87 jbd2_journal_release_jbd_inode +EXPORT_SYMBOL vmlinux 0x885819ba nf_register_hooks +EXPORT_SYMBOL vmlinux 0x8868aba7 write_cache_pages +EXPORT_SYMBOL vmlinux 0x8893d83f generic_write_end +EXPORT_SYMBOL vmlinux 0x88e88136 ioremap_prot +EXPORT_SYMBOL vmlinux 0x89070d49 tty_throttle +EXPORT_SYMBOL vmlinux 0x890832cb iget_failed +EXPORT_SYMBOL vmlinux 0x890bd06e tty_write_room +EXPORT_SYMBOL vmlinux 0x891279b8 skb_add_rx_frag +EXPORT_SYMBOL vmlinux 0x89156a01 inet_select_addr +EXPORT_SYMBOL vmlinux 0x892b26a0 set_memory_nx +EXPORT_SYMBOL vmlinux 0x8949858b schedule_work +EXPORT_SYMBOL vmlinux 0x8953bb27 del_timer +EXPORT_SYMBOL vmlinux 0x8969b997 ida_get_new +EXPORT_SYMBOL vmlinux 0x896eb16e serio_reconnect +EXPORT_SYMBOL vmlinux 0x89707538 xfrm_bundle_ok +EXPORT_SYMBOL vmlinux 0x897473df mktime +EXPORT_SYMBOL vmlinux 0x898b1fec mutex_trylock +EXPORT_SYMBOL vmlinux 0x89949018 down_timeout +EXPORT_SYMBOL vmlinux 0x89a991a8 genl_register_ops +EXPORT_SYMBOL vmlinux 0x89c3ea8c kill_fasync +EXPORT_SYMBOL vmlinux 0x89cf7971 inet_csk_accept +EXPORT_SYMBOL vmlinux 0x89d5538d fb_pad_aligned_buffer +EXPORT_SYMBOL vmlinux 0x89d66811 build_ehash_secret +EXPORT_SYMBOL vmlinux 0x8a3eabf0 __wait_on_bit +EXPORT_SYMBOL vmlinux 0x8a608f4d sock_common_recvmsg +EXPORT_SYMBOL vmlinux 0x8a7d1c31 high_memory +EXPORT_SYMBOL vmlinux 0x8a99a016 mempool_free_slab +EXPORT_SYMBOL vmlinux 0x8aaf8654 mutex_lock +EXPORT_SYMBOL vmlinux 0x8b18496f __copy_to_user_ll +EXPORT_SYMBOL vmlinux 0x8b50bd1c udp_memory_allocated +EXPORT_SYMBOL vmlinux 0x8b57e096 gnet_stats_copy_app +EXPORT_SYMBOL vmlinux 0x8b5956de find_get_page +EXPORT_SYMBOL vmlinux 0x8b618d08 overflowuid +EXPORT_SYMBOL vmlinux 0x8b76cef6 ps2_init +EXPORT_SYMBOL vmlinux 0x8b989cf9 acpi_bus_can_wakeup +EXPORT_SYMBOL vmlinux 0x8ba8bb08 d_invalidate +EXPORT_SYMBOL vmlinux 0x8bf14095 ip_route_me_harder +EXPORT_SYMBOL vmlinux 0x8c03a3ac sock_no_setsockopt +EXPORT_SYMBOL vmlinux 0x8c07825d skb_recv_datagram +EXPORT_SYMBOL vmlinux 0x8c183cbe iowrite16 +EXPORT_SYMBOL vmlinux 0x8c54fbce unregister_nls +EXPORT_SYMBOL vmlinux 0x8c6dc169 genl_unregister_ops +EXPORT_SYMBOL vmlinux 0x8c777105 mark_buffer_async_write +EXPORT_SYMBOL vmlinux 0x8c7de6df jbd2_journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0x8cac4fb6 __mpage_writepage +EXPORT_SYMBOL vmlinux 0x8cc79cab iowrite16_rep +EXPORT_SYMBOL vmlinux 0x8ccfb86e scsi_register_driver +EXPORT_SYMBOL vmlinux 0x8cd60209 names_cachep +EXPORT_SYMBOL vmlinux 0x8d0a14ce key_type_keyring +EXPORT_SYMBOL vmlinux 0x8d346213 netlink_unicast +EXPORT_SYMBOL vmlinux 0x8d3894f2 _ctype +EXPORT_SYMBOL vmlinux 0x8d3e33aa jbd2_journal_start_commit +EXPORT_SYMBOL vmlinux 0x8d40c358 scsi_device_quiesce +EXPORT_SYMBOL vmlinux 0x8d460d01 lookup_bdev +EXPORT_SYMBOL vmlinux 0x8d4db994 simple_set_mnt +EXPORT_SYMBOL vmlinux 0x8d551bef sysctl_tcp_rmem +EXPORT_SYMBOL vmlinux 0x8d57bd93 xfrm_prepare_input +EXPORT_SYMBOL vmlinux 0x8d6f81b4 __div64_32 +EXPORT_SYMBOL vmlinux 0x8d750d2f current_fs_time +EXPORT_SYMBOL vmlinux 0x8d8d96c6 acpi_get_sleep_type_data +EXPORT_SYMBOL vmlinux 0x8dbc2d53 set_pages_uc +EXPORT_SYMBOL vmlinux 0x8dbc6c97 jbd2_journal_create +EXPORT_SYMBOL vmlinux 0x8dc6e564 restore_processor_state +EXPORT_SYMBOL vmlinux 0x8dca832f __percpu_counter_sum +EXPORT_SYMBOL vmlinux 0x8df3cc7c tcp_recvmsg +EXPORT_SYMBOL vmlinux 0x8e002cda acpi_remove_gpe_block +EXPORT_SYMBOL vmlinux 0x8e0637ba i8253_lock +EXPORT_SYMBOL vmlinux 0x8e08ab00 pcim_iounmap +EXPORT_SYMBOL vmlinux 0x8e0b7743 ipv6_ext_hdr +EXPORT_SYMBOL vmlinux 0x8e360406 unload_nls +EXPORT_SYMBOL vmlinux 0x8e763ae1 send_remote_softirq +EXPORT_SYMBOL vmlinux 0x8eb4287c scsi_block_requests +EXPORT_SYMBOL vmlinux 0x8ece7089 nlmsg_notify +EXPORT_SYMBOL vmlinux 0x8ed047e7 dmam_release_declared_memory +EXPORT_SYMBOL vmlinux 0x8ed175e9 sock_queue_rcv_skb +EXPORT_SYMBOL vmlinux 0x8ee405bc textsearch_destroy +EXPORT_SYMBOL vmlinux 0x8f2170f4 xfrm_state_walk +EXPORT_SYMBOL vmlinux 0x8f447732 tty_chars_in_buffer +EXPORT_SYMBOL vmlinux 0x8f4a8619 unregister_quota_format +EXPORT_SYMBOL vmlinux 0x8f5fdcdc ht_create_irq +EXPORT_SYMBOL vmlinux 0x8f6b7950 set_irq_data +EXPORT_SYMBOL vmlinux 0x8f865ca0 nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0x8f8cb8cf __insert_inode_hash +EXPORT_SYMBOL vmlinux 0x8f9c199c __get_user_2 +EXPORT_SYMBOL vmlinux 0x8fba1ba1 xfrm_state_lookup_byaddr +EXPORT_SYMBOL vmlinux 0x8feb553b sk_dst_check +EXPORT_SYMBOL vmlinux 0x8ffdb3b8 crc16 +EXPORT_SYMBOL vmlinux 0x90035333 secure_tcpv6_sequence_number +EXPORT_SYMBOL vmlinux 0x900e3d36 proc_dostring +EXPORT_SYMBOL vmlinux 0x9054e78f __lookup_hash +EXPORT_SYMBOL vmlinux 0x9055e030 scsi_add_device +EXPORT_SYMBOL vmlinux 0x90582f65 udp_proc_unregister +EXPORT_SYMBOL vmlinux 0x9079fd72 genl_sock +EXPORT_SYMBOL vmlinux 0x90a01598 journal_revoke +EXPORT_SYMBOL vmlinux 0x90a1601f dmi_check_system +EXPORT_SYMBOL vmlinux 0x90a943ba nmi_active +EXPORT_SYMBOL vmlinux 0x90c7945e tcp_read_sock +EXPORT_SYMBOL vmlinux 0x9144a8e2 ec_burst_disable +EXPORT_SYMBOL vmlinux 0x91481982 __ratelimit +EXPORT_SYMBOL vmlinux 0x915124d2 pci_find_device +EXPORT_SYMBOL vmlinux 0x915ffa78 may_umount_tree +EXPORT_SYMBOL vmlinux 0x91607d95 set_memory_wb +EXPORT_SYMBOL vmlinux 0x916b6fad dcache_dir_open +EXPORT_SYMBOL vmlinux 0x91825657 generic_listxattr +EXPORT_SYMBOL vmlinux 0x91ca8959 acpi_get_register +EXPORT_SYMBOL vmlinux 0x91ec9604 dev_mc_add +EXPORT_SYMBOL vmlinux 0x91f005bc journal_wipe +EXPORT_SYMBOL vmlinux 0x921e454b dquot_transfer +EXPORT_SYMBOL vmlinux 0x92229929 per_cpu__current_task +EXPORT_SYMBOL vmlinux 0x9223f79c sock_no_bind +EXPORT_SYMBOL vmlinux 0x923111f0 neigh_changeaddr +EXPORT_SYMBOL vmlinux 0x9280bb2f nf_afinfo +EXPORT_SYMBOL vmlinux 0x92a90241 seq_bitmap_list +EXPORT_SYMBOL vmlinux 0x9305f8e6 cpufreq_get +EXPORT_SYMBOL vmlinux 0x9308511c serio_unregister_port +EXPORT_SYMBOL vmlinux 0x9313d506 ps2_cmd_aborted +EXPORT_SYMBOL vmlinux 0x9330cb9f sg_alloc_table +EXPORT_SYMBOL vmlinux 0x933bb363 scsi_setup_fs_cmnd +EXPORT_SYMBOL vmlinux 0x93771707 ethtool_op_get_sg +EXPORT_SYMBOL vmlinux 0x93a3b961 jbd2_journal_update_format +EXPORT_SYMBOL vmlinux 0x93a6e0b2 io_schedule +EXPORT_SYMBOL vmlinux 0x93ad6b2a bio_alloc +EXPORT_SYMBOL vmlinux 0x93ae3a7d mnt_pin +EXPORT_SYMBOL vmlinux 0x93afa72e vm_get_page_prot +EXPORT_SYMBOL vmlinux 0x93b8ef56 mutex_lock_interruptible +EXPORT_SYMBOL vmlinux 0x93c69acf param_set_byte +EXPORT_SYMBOL vmlinux 0x93cbd1ec _spin_lock_bh +EXPORT_SYMBOL vmlinux 0x93e6dc7a mmc_request_done +EXPORT_SYMBOL vmlinux 0x93fca811 __get_free_pages +EXPORT_SYMBOL vmlinux 0x94153122 alloc_etherdev_mq +EXPORT_SYMBOL vmlinux 0x941927db dma_supported +EXPORT_SYMBOL vmlinux 0x943944a0 unregister_exec_domain +EXPORT_SYMBOL vmlinux 0x94540284 dev_get_by_flags +EXPORT_SYMBOL vmlinux 0x9459266a vfs_set_dqinfo +EXPORT_SYMBOL vmlinux 0x9464a86e xfrm_policy_destroy +EXPORT_SYMBOL vmlinux 0x9472f57f mb_cache_entry_alloc +EXPORT_SYMBOL vmlinux 0x94961283 vunmap +EXPORT_SYMBOL vmlinux 0x94b2bbfb skb_trim +EXPORT_SYMBOL vmlinux 0x94b5bf68 skb_find_text +EXPORT_SYMBOL vmlinux 0x95231516 sock_no_sendmsg +EXPORT_SYMBOL vmlinux 0x954488a4 syncookie_secret +EXPORT_SYMBOL vmlinux 0x9545af6d tasklet_init +EXPORT_SYMBOL vmlinux 0x954cbb26 vsprintf +EXPORT_SYMBOL vmlinux 0x954dc4e7 pcie_get_readrq +EXPORT_SYMBOL vmlinux 0x956aa3f1 inet_unregister_protosw +EXPORT_SYMBOL vmlinux 0x95871d5d gnet_stats_start_copy_compat +EXPORT_SYMBOL vmlinux 0x95bd48fb seq_lseek +EXPORT_SYMBOL vmlinux 0x95df6cbd do_mmap_pgoff +EXPORT_SYMBOL vmlinux 0x95f2d351 __seq_open_private +EXPORT_SYMBOL vmlinux 0x95f638d5 posix_acl_chmod_masq +EXPORT_SYMBOL vmlinux 0x9605e820 generic_writepages +EXPORT_SYMBOL vmlinux 0x962a152c scsi_ioctl +EXPORT_SYMBOL vmlinux 0x96481cc7 per_cpu__x86_cpu_to_apicid +EXPORT_SYMBOL vmlinux 0x964e8483 freeze_bdev +EXPORT_SYMBOL vmlinux 0x967e968a d_alloc +EXPORT_SYMBOL vmlinux 0x96898769 sysfs_format_mac +EXPORT_SYMBOL vmlinux 0x96926be7 dma_sync_wait +EXPORT_SYMBOL vmlinux 0x96afd5f9 tcf_exts_dump +EXPORT_SYMBOL vmlinux 0x96cd2b04 scsi_sense_key_string +EXPORT_SYMBOL vmlinux 0x96ee14f1 dev_set_mac_address +EXPORT_SYMBOL vmlinux 0x96fffc65 netdev_rx_csum_fault +EXPORT_SYMBOL vmlinux 0x97201903 tcf_exts_validate +EXPORT_SYMBOL vmlinux 0x97210b01 eth_header_cache +EXPORT_SYMBOL vmlinux 0x973703e7 neigh_table_init +EXPORT_SYMBOL vmlinux 0x973873ab _spin_lock +EXPORT_SYMBOL vmlinux 0x9754ec10 radix_tree_preload +EXPORT_SYMBOL vmlinux 0x97600d31 cpufreq_get_policy +EXPORT_SYMBOL vmlinux 0x97608fd7 __devm_release_region +EXPORT_SYMBOL vmlinux 0x97667f3f dump_trace +EXPORT_SYMBOL vmlinux 0x9790a10c mb_cache_create +EXPORT_SYMBOL vmlinux 0x97a75869 acpi_bus_register_driver +EXPORT_SYMBOL vmlinux 0x97b3790d single_release +EXPORT_SYMBOL vmlinux 0x97de0ddd acpi_install_gpe_block +EXPORT_SYMBOL vmlinux 0x97e432a9 register_quota_format +EXPORT_SYMBOL vmlinux 0x980f6e8b sock_get_timestampns +EXPORT_SYMBOL vmlinux 0x981026f6 km_report +EXPORT_SYMBOL vmlinux 0x9835f79b kunmap +EXPORT_SYMBOL vmlinux 0x984dfaf7 arp_find +EXPORT_SYMBOL vmlinux 0x986e6135 fb_pad_unaligned_buffer +EXPORT_SYMBOL vmlinux 0x98782089 generic_ro_fops +EXPORT_SYMBOL vmlinux 0x988ed85d set_memory_x +EXPORT_SYMBOL vmlinux 0x98969ef6 locks_remove_posix +EXPORT_SYMBOL vmlinux 0x9896f742 sync_page_range_nolock +EXPORT_SYMBOL vmlinux 0x9898cc58 rtnl_create_link +EXPORT_SYMBOL vmlinux 0x98a177b1 dev_kfree_skb_irq +EXPORT_SYMBOL vmlinux 0x98a331f4 cdev_del +EXPORT_SYMBOL vmlinux 0x98cc11ab skb_copy +EXPORT_SYMBOL vmlinux 0x98f2a082 page_zero_new_buffers +EXPORT_SYMBOL vmlinux 0x98f3a577 end_buffer_read_sync +EXPORT_SYMBOL vmlinux 0x9902abca __scsi_put_command +EXPORT_SYMBOL vmlinux 0x99052a84 acpi_os_write_port +EXPORT_SYMBOL vmlinux 0x9942b6db dmam_alloc_coherent +EXPORT_SYMBOL vmlinux 0x9994c0ca ps2_is_keyboard_id +EXPORT_SYMBOL vmlinux 0x999e8297 vfree +EXPORT_SYMBOL vmlinux 0x99aadb21 param_get_ulong +EXPORT_SYMBOL vmlinux 0x99bfbe39 get_unused_fd +EXPORT_SYMBOL vmlinux 0x99c3c0b0 vfs_fstat +EXPORT_SYMBOL vmlinux 0x99cdc86b sysctl_tcp_reordering +EXPORT_SYMBOL vmlinux 0x99e41d8d tcf_hash_check +EXPORT_SYMBOL vmlinux 0x99ea12ce panic_blink +EXPORT_SYMBOL vmlinux 0x99ff07e3 inode_set_bytes +EXPORT_SYMBOL vmlinux 0x9a1dfd65 strpbrk +EXPORT_SYMBOL vmlinux 0x9a4d9a18 tcp_tso_segment +EXPORT_SYMBOL vmlinux 0x9a598bd1 get_sb_nodev +EXPORT_SYMBOL vmlinux 0x9a6a83f9 cmos_lock +EXPORT_SYMBOL vmlinux 0x9a6eb5ba per_cpu__cpu_core_map +EXPORT_SYMBOL vmlinux 0x9a979d79 acpi_get_physical_device +EXPORT_SYMBOL vmlinux 0x9a9985be percpu_counter_destroy +EXPORT_SYMBOL vmlinux 0x9ad7b330 netlink_kernel_create +EXPORT_SYMBOL vmlinux 0x9b388444 get_zeroed_page +EXPORT_SYMBOL vmlinux 0x9b4de8eb idr_replace +EXPORT_SYMBOL vmlinux 0x9b74b9f1 d_alloc_root +EXPORT_SYMBOL vmlinux 0x9b7725b0 journal_ack_err +EXPORT_SYMBOL vmlinux 0x9b8e81d0 jbd2_journal_destroy +EXPORT_SYMBOL vmlinux 0x9ba7089d argv_split +EXPORT_SYMBOL vmlinux 0x9bce482f __release_region +EXPORT_SYMBOL vmlinux 0x9bda55c1 vfs_readv +EXPORT_SYMBOL vmlinux 0x9bf3a4ae ilookup +EXPORT_SYMBOL vmlinux 0x9c012508 fb_parse_edid +EXPORT_SYMBOL vmlinux 0x9c2282d7 skb_queue_head +EXPORT_SYMBOL vmlinux 0x9c22a4b8 inet_frag_evictor +EXPORT_SYMBOL vmlinux 0x9c2c944a __copy_from_user_ll_nocache_nozero +EXPORT_SYMBOL vmlinux 0x9c6137c3 pfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0x9c7077bd enable_hlt +EXPORT_SYMBOL vmlinux 0x9c7b1a6e kill_block_super +EXPORT_SYMBOL vmlinux 0x9cb96e92 qdisc_put_rtab +EXPORT_SYMBOL vmlinux 0x9ccb2622 finish_wait +EXPORT_SYMBOL vmlinux 0x9ceb163c memcpy_toiovec +EXPORT_SYMBOL vmlinux 0x9ced38aa down_trylock +EXPORT_SYMBOL vmlinux 0x9cfd56c5 scsi_print_status +EXPORT_SYMBOL vmlinux 0x9d10d16f xrlim_allow +EXPORT_SYMBOL vmlinux 0x9d1d613c kmem_cache_name +EXPORT_SYMBOL vmlinux 0x9d203635 cdrom_mode_select +EXPORT_SYMBOL vmlinux 0x9d33ef5e acpi_enable +EXPORT_SYMBOL vmlinux 0x9d4dfce0 proc_dointvec +EXPORT_SYMBOL vmlinux 0x9d54524f arp_send +EXPORT_SYMBOL vmlinux 0x9d5a4ae1 check_disk_change +EXPORT_SYMBOL vmlinux 0x9d6a682f unregister_sysrq_key +EXPORT_SYMBOL vmlinux 0x9d711f1f percpu_counter_init +EXPORT_SYMBOL vmlinux 0x9d784063 dquot_acquire +EXPORT_SYMBOL vmlinux 0x9d87d949 nf_log_unregister +EXPORT_SYMBOL vmlinux 0x9d9f0d41 rwsem_down_write_failed +EXPORT_SYMBOL vmlinux 0x9da482e5 scsi_register_interface +EXPORT_SYMBOL vmlinux 0x9e001662 sysctl_jiffies +EXPORT_SYMBOL vmlinux 0x9e0967d3 journal_destroy +EXPORT_SYMBOL vmlinux 0x9e20a68e acpi_bus_add +EXPORT_SYMBOL vmlinux 0x9e20e973 mnt_unpin +EXPORT_SYMBOL vmlinux 0x9e226551 kthread_stop +EXPORT_SYMBOL vmlinux 0x9e363b6b acpi_disable_gpe +EXPORT_SYMBOL vmlinux 0x9e64fbfe rtc_cmos_read +EXPORT_SYMBOL vmlinux 0x9e672ff6 scsi_kmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x9e7d6bd0 __udelay +EXPORT_SYMBOL vmlinux 0x9e8bcc28 jbd2_journal_wipe +EXPORT_SYMBOL vmlinux 0x9ed685ee iov_iter_advance +EXPORT_SYMBOL vmlinux 0x9ed6f856 tcf_unregister_action +EXPORT_SYMBOL vmlinux 0x9eecde16 do_brk +EXPORT_SYMBOL vmlinux 0x9ef749e2 unregister_chrdev +EXPORT_SYMBOL vmlinux 0x9f025e21 force_sig +EXPORT_SYMBOL vmlinux 0x9f0eb0a2 mmc_free_host +EXPORT_SYMBOL vmlinux 0x9f100139 jiffies_to_clock_t +EXPORT_SYMBOL vmlinux 0x9f12e4bc acpi_match_device_ids +EXPORT_SYMBOL vmlinux 0x9f2bdaac __bitmap_or +EXPORT_SYMBOL vmlinux 0x9f343c61 udp_sendmsg +EXPORT_SYMBOL vmlinux 0x9f3e3ff8 tty_port_alloc_xmit_buf +EXPORT_SYMBOL vmlinux 0x9f740170 skb_free_datagram +EXPORT_SYMBOL vmlinux 0x9f9125ee open_by_devnum +EXPORT_SYMBOL vmlinux 0x9f984513 strrchr +EXPORT_SYMBOL vmlinux 0x9fa274b4 dq_data_lock +EXPORT_SYMBOL vmlinux 0x9fae89dc __bforget +EXPORT_SYMBOL vmlinux 0x9fb3dd30 memcpy_fromiovec +EXPORT_SYMBOL vmlinux 0x9fcc4cd4 jbd2_journal_check_available_features +EXPORT_SYMBOL vmlinux 0x9fdf56e5 scsi_test_unit_ready +EXPORT_SYMBOL vmlinux 0x9ffcd746 __mark_inode_dirty +EXPORT_SYMBOL vmlinux 0xa01f56f5 sysctl_intvec +EXPORT_SYMBOL vmlinux 0xa03523d5 security_unix_stream_connect +EXPORT_SYMBOL vmlinux 0xa04a01bd qdisc_class_hash_insert +EXPORT_SYMBOL vmlinux 0xa05c03df mempool_kmalloc +EXPORT_SYMBOL vmlinux 0xa05eed65 tcp_sendmsg +EXPORT_SYMBOL vmlinux 0xa07f7098 skb_copy_and_csum_bits +EXPORT_SYMBOL vmlinux 0xa0aef162 pcix_get_mmrbc +EXPORT_SYMBOL vmlinux 0xa0b04675 vmalloc_32 +EXPORT_SYMBOL vmlinux 0xa0ceef51 out_of_line_wait_on_bit +EXPORT_SYMBOL vmlinux 0xa0e314d9 jbd2_journal_flush +EXPORT_SYMBOL vmlinux 0xa0edb07b pv_mmu_ops +EXPORT_SYMBOL vmlinux 0xa0fbac79 wake_up_bit +EXPORT_SYMBOL vmlinux 0xa108eb4d sysctl_optmem_max +EXPORT_SYMBOL vmlinux 0xa10dcc13 getrawmonotonic +EXPORT_SYMBOL vmlinux 0xa10e3e49 dev_add_pack +EXPORT_SYMBOL vmlinux 0xa117cded tty_devnum +EXPORT_SYMBOL vmlinux 0xa11b0b86 invalidate_bdev +EXPORT_SYMBOL vmlinux 0xa120d33c tty_unregister_ldisc +EXPORT_SYMBOL vmlinux 0xa13798f8 printk_ratelimit +EXPORT_SYMBOL vmlinux 0xa14c750c __kfree_skb +EXPORT_SYMBOL vmlinux 0xa16aac5b dev_unicast_delete +EXPORT_SYMBOL vmlinux 0xa1863162 sk_common_release +EXPORT_SYMBOL vmlinux 0xa1911db2 input_set_keycode +EXPORT_SYMBOL vmlinux 0xa1b1fe7d inet_ioctl +EXPORT_SYMBOL vmlinux 0xa1b759ce fb_add_videomode +EXPORT_SYMBOL vmlinux 0xa1c76e0a _cond_resched +EXPORT_SYMBOL vmlinux 0xa1cffbb1 pci_dev_get +EXPORT_SYMBOL vmlinux 0xa20ce1b8 net_msg_warn +EXPORT_SYMBOL vmlinux 0xa2139bc1 netif_carrier_off +EXPORT_SYMBOL vmlinux 0xa254d827 tcp_hashinfo +EXPORT_SYMBOL vmlinux 0xa25fefd5 k8_northbridges +EXPORT_SYMBOL vmlinux 0xa267b66d ps2_handle_response +EXPORT_SYMBOL vmlinux 0xa272cd32 __starget_for_each_device +EXPORT_SYMBOL vmlinux 0xa279036d __skb_checksum_complete +EXPORT_SYMBOL vmlinux 0xa2843e64 cdrom_get_last_written +EXPORT_SYMBOL vmlinux 0xa2a1e5c9 _write_lock_bh +EXPORT_SYMBOL vmlinux 0xa2a5fd77 inet_ehash_secret +EXPORT_SYMBOL vmlinux 0xa2cd6223 mmc_unregister_driver +EXPORT_SYMBOL vmlinux 0xa2f84dcb scsi_execute_req +EXPORT_SYMBOL vmlinux 0xa329f07e register_shrinker +EXPORT_SYMBOL vmlinux 0xa33f0d8c mca_device_transform_ioport +EXPORT_SYMBOL vmlinux 0xa34f1ef5 crc32_le +EXPORT_SYMBOL vmlinux 0xa350a8f8 set_memory_array_uc +EXPORT_SYMBOL vmlinux 0xa35c1f05 acpi_extract_package +EXPORT_SYMBOL vmlinux 0xa35de80f ipv4_config +EXPORT_SYMBOL vmlinux 0xa376dc41 rtnetlink_put_metrics +EXPORT_SYMBOL vmlinux 0xa3b1056c do_splice_to +EXPORT_SYMBOL vmlinux 0xa3bbcd80 acpi_set_gpe_type +EXPORT_SYMBOL vmlinux 0xa3cae58c pci_enable_device_mem +EXPORT_SYMBOL vmlinux 0xa3cd3ca1 iw_handler_set_thrspy +EXPORT_SYMBOL vmlinux 0xa3e2c115 xfrm4_rcv +EXPORT_SYMBOL vmlinux 0xa3ec85d4 sock_no_accept +EXPORT_SYMBOL vmlinux 0xa4165b73 qdisc_destroy +EXPORT_SYMBOL vmlinux 0xa44072fc posix_acl_alloc +EXPORT_SYMBOL vmlinux 0xa449c682 dquot_release +EXPORT_SYMBOL vmlinux 0xa44ad274 wait_for_completion_interruptible_timeout +EXPORT_SYMBOL vmlinux 0xa455f2d2 pnp_request_card_device +EXPORT_SYMBOL vmlinux 0xa4794c0e xfrm_stateonly_find +EXPORT_SYMBOL vmlinux 0xa498eb02 seq_escape +EXPORT_SYMBOL vmlinux 0xa4b94fea iowrite8_rep +EXPORT_SYMBOL vmlinux 0xa4c49b7b tty_free_termios +EXPORT_SYMBOL vmlinux 0xa4d9bf24 sock_no_getsockopt +EXPORT_SYMBOL vmlinux 0xa4df1151 kref_set +EXPORT_SYMBOL vmlinux 0xa4ea5bf3 pci_wake_from_d3 +EXPORT_SYMBOL vmlinux 0xa51cdfe8 __FIXADDR_TOP +EXPORT_SYMBOL vmlinux 0xa5423cc4 param_get_int +EXPORT_SYMBOL vmlinux 0xa5693df7 posix_acl_clone +EXPORT_SYMBOL vmlinux 0xa56f1315 mempool_free +EXPORT_SYMBOL vmlinux 0xa57ef5b4 ip_generic_getfrag +EXPORT_SYMBOL vmlinux 0xa58b3070 mark_buffer_dirty_inode +EXPORT_SYMBOL vmlinux 0xa58b6804 nla_parse +EXPORT_SYMBOL vmlinux 0xa5922bb1 kfifo_init +EXPORT_SYMBOL vmlinux 0xa598e29c vesa_modes +EXPORT_SYMBOL vmlinux 0xa5a633b9 sg_last +EXPORT_SYMBOL vmlinux 0xa5cef8ad release_resource +EXPORT_SYMBOL vmlinux 0xa5d41bcf mca_register_driver +EXPORT_SYMBOL vmlinux 0xa5d9ab67 task_session_nr_ns +EXPORT_SYMBOL vmlinux 0xa5da0abd acpi_enter_sleep_state_s4bios +EXPORT_SYMBOL vmlinux 0xa5dcffc8 sk_run_filter +EXPORT_SYMBOL vmlinux 0xa61c83b1 __pagevec_release +EXPORT_SYMBOL vmlinux 0xa62312c8 console_stop +EXPORT_SYMBOL vmlinux 0xa6265113 neigh_seq_stop +EXPORT_SYMBOL vmlinux 0xa6274526 __elv_add_request +EXPORT_SYMBOL vmlinux 0xa6484eae smp_call_function_mask +EXPORT_SYMBOL vmlinux 0xa66637a5 I_BDEV +EXPORT_SYMBOL vmlinux 0xa68124fa hweight8 +EXPORT_SYMBOL vmlinux 0xa6814433 groups_free +EXPORT_SYMBOL vmlinux 0xa681fe88 generate_random_uuid +EXPORT_SYMBOL vmlinux 0xa6a81c50 eth_rebuild_header +EXPORT_SYMBOL vmlinux 0xa6dcc773 rb_insert_color +EXPORT_SYMBOL vmlinux 0xa7046549 vprintk +EXPORT_SYMBOL vmlinux 0xa70fabbe release_evntsel_nmi +EXPORT_SYMBOL vmlinux 0xa73e0396 igrab +EXPORT_SYMBOL vmlinux 0xa7502f48 jiffies_to_timeval +EXPORT_SYMBOL vmlinux 0xa75aa257 mb_cache_entry_release +EXPORT_SYMBOL vmlinux 0xa770b803 kblockd_flush_work +EXPORT_SYMBOL vmlinux 0xa77d2359 tty_insert_flip_string_flags +EXPORT_SYMBOL vmlinux 0xa789d5d2 nf_log_register +EXPORT_SYMBOL vmlinux 0xa79c2952 sb_has_dirty_inodes +EXPORT_SYMBOL vmlinux 0xa7c35c6b getnstimeofday +EXPORT_SYMBOL vmlinux 0xa7f4350e fb_firmware_edid +EXPORT_SYMBOL vmlinux 0xa815901a dev_getbyhwaddr +EXPORT_SYMBOL vmlinux 0xa841079b flock_lock_file_wait +EXPORT_SYMBOL vmlinux 0xa8850e3f sysctl_data +EXPORT_SYMBOL vmlinux 0xa889cad9 fb_set_var +EXPORT_SYMBOL vmlinux 0xa89acbb3 acpi_evaluate_reference +EXPORT_SYMBOL vmlinux 0xa8b3e802 pagevec_lookup_tag +EXPORT_SYMBOL vmlinux 0xa8b50d46 __xfrm_policy_check +EXPORT_SYMBOL vmlinux 0xa8f9f009 input_inject_event +EXPORT_SYMBOL vmlinux 0xa8fc5615 kmem_cache_alloc +EXPORT_SYMBOL vmlinux 0xa8fef7bb security_unix_may_send +EXPORT_SYMBOL vmlinux 0xa91b5561 acpi_video_backlight_support +EXPORT_SYMBOL vmlinux 0xa925899a param_set_bool +EXPORT_SYMBOL vmlinux 0xa96b6fb8 get_empty_filp +EXPORT_SYMBOL vmlinux 0xa971d960 skb_append +EXPORT_SYMBOL vmlinux 0xa9a14377 unregister_key_type +EXPORT_SYMBOL vmlinux 0xa9bb6377 km_state_expired +EXPORT_SYMBOL vmlinux 0xa9e56605 set_irq_chip +EXPORT_SYMBOL vmlinux 0xa9fcf31d wait_for_completion_interruptible +EXPORT_SYMBOL vmlinux 0xaa29a678 vlan_ioctl_set +EXPORT_SYMBOL vmlinux 0xaa32e6b1 sock_create_lite +EXPORT_SYMBOL vmlinux 0xaa36c678 blk_queue_start_tag +EXPORT_SYMBOL vmlinux 0xaa760a69 sock_sendmsg +EXPORT_SYMBOL vmlinux 0xaa84a8ae acpi_processor_power_init_bm_check +EXPORT_SYMBOL vmlinux 0xaa8ab19e cpu_online_map +EXPORT_SYMBOL vmlinux 0xaaa0541f mb_cache_entry_find_first +EXPORT_SYMBOL vmlinux 0xaab06af8 _write_lock_irqsave +EXPORT_SYMBOL vmlinux 0xaab156b3 vfs_statfs +EXPORT_SYMBOL vmlinux 0xaae8ab0e acpi_bus_power_manageable +EXPORT_SYMBOL vmlinux 0xaaebe34f mca_write_pos +EXPORT_SYMBOL vmlinux 0xaafdc258 strcasecmp +EXPORT_SYMBOL vmlinux 0xaaffb9a5 acpi_bus_private_data_handler +EXPORT_SYMBOL vmlinux 0xab31ff2c x86_dma_fallback_dev +EXPORT_SYMBOL vmlinux 0xab471003 param_array_set +EXPORT_SYMBOL vmlinux 0xab600421 probe_irq_off +EXPORT_SYMBOL vmlinux 0xab65ed80 set_memory_uc +EXPORT_SYMBOL vmlinux 0xabc03d4d task_pid_nr_ns +EXPORT_SYMBOL vmlinux 0xabc8cd4c register_chrdev +EXPORT_SYMBOL vmlinux 0xabd0c91c rtc_time_to_tm +EXPORT_SYMBOL vmlinux 0xabd2c533 dget_locked +EXPORT_SYMBOL vmlinux 0xabf81922 sock_common_getsockopt +EXPORT_SYMBOL vmlinux 0xabfd69ce read_cache_page_async +EXPORT_SYMBOL vmlinux 0xabfea473 pci_map_rom +EXPORT_SYMBOL vmlinux 0xac0035ef tcp_sendpage +EXPORT_SYMBOL vmlinux 0xac3b3cee __bitmap_and +EXPORT_SYMBOL vmlinux 0xac549974 __serio_register_driver +EXPORT_SYMBOL vmlinux 0xac58ea5e acpi_unload_table_id +EXPORT_SYMBOL vmlinux 0xac790b39 poll_initwait +EXPORT_SYMBOL vmlinux 0xaccabc6a in4_pton +EXPORT_SYMBOL vmlinux 0xace2db19 single_open +EXPORT_SYMBOL vmlinux 0xace8bdf7 pagecache_write_begin +EXPORT_SYMBOL vmlinux 0xacf4d843 match_strdup +EXPORT_SYMBOL vmlinux 0xad0413d4 match_hex +EXPORT_SYMBOL vmlinux 0xad0f13c0 scsi_host_put +EXPORT_SYMBOL vmlinux 0xad131372 clear_page_dirty_for_io +EXPORT_SYMBOL vmlinux 0xad13c689 acpi_os_execute +EXPORT_SYMBOL vmlinux 0xad2df2f4 find_get_pages_contig +EXPORT_SYMBOL vmlinux 0xad2f23dc xfrm_register_km +EXPORT_SYMBOL vmlinux 0xad5b67c0 pci_iomap +EXPORT_SYMBOL vmlinux 0xad75145b xfrm_input +EXPORT_SYMBOL vmlinux 0xad86bf25 acpi_get_physical_pci_device +EXPORT_SYMBOL vmlinux 0xad9b4813 ____pagevec_lru_add +EXPORT_SYMBOL vmlinux 0xadaa2657 cpufreq_register_notifier +EXPORT_SYMBOL vmlinux 0xadc7dce5 kmem_cache_create +EXPORT_SYMBOL vmlinux 0xadc9397d misc_deregister +EXPORT_SYMBOL vmlinux 0xade280c4 xfrm_register_mode +EXPORT_SYMBOL vmlinux 0xae1c07ce thaw_process +EXPORT_SYMBOL vmlinux 0xae43bdaf jbd2_journal_ack_err +EXPORT_SYMBOL vmlinux 0xae4595c5 neigh_seq_next +EXPORT_SYMBOL vmlinux 0xae4b6230 blk_recount_segments +EXPORT_SYMBOL vmlinux 0xae75f004 ida_destroy +EXPORT_SYMBOL vmlinux 0xae89395d acpi_processor_notify_smm +EXPORT_SYMBOL vmlinux 0xae9c4223 sock_i_uid +EXPORT_SYMBOL vmlinux 0xae9de1c3 sock_i_ino +EXPORT_SYMBOL vmlinux 0xaea836c2 kset_unregister +EXPORT_SYMBOL vmlinux 0xaec655c7 alloc_pages_exact +EXPORT_SYMBOL vmlinux 0xaed16f5a dec_zone_page_state +EXPORT_SYMBOL vmlinux 0xaef97737 pnp_disable_dev +EXPORT_SYMBOL vmlinux 0xaf3dd7dc scsi_logging_level +EXPORT_SYMBOL vmlinux 0xaf4b1540 acpi_get_irq_routing_table +EXPORT_SYMBOL vmlinux 0xaf52c2d3 iommu_bio_merge +EXPORT_SYMBOL vmlinux 0xaf5abb01 sock_no_connect +EXPORT_SYMBOL vmlinux 0xaf6fb45c devm_ioremap +EXPORT_SYMBOL vmlinux 0xafaa937e __scm_destroy +EXPORT_SYMBOL vmlinux 0xafb36a67 uart_resume_port +EXPORT_SYMBOL vmlinux 0xafe01377 down_read +EXPORT_SYMBOL vmlinux 0xafe8f572 ip_mc_inc_group +EXPORT_SYMBOL vmlinux 0xaff7343d vfs_path_lookup +EXPORT_SYMBOL vmlinux 0xb03d8f3d sb_min_blocksize +EXPORT_SYMBOL vmlinux 0xb077ef32 acpi_enter_sleep_state +EXPORT_SYMBOL vmlinux 0xb07dfb3d acpi_remove_gpe_handler +EXPORT_SYMBOL vmlinux 0xb08f76ad gen_pool_free +EXPORT_SYMBOL vmlinux 0xb0a13cf5 inet_add_protocol +EXPORT_SYMBOL vmlinux 0xb0b847ac __bitmap_full +EXPORT_SYMBOL vmlinux 0xb0e10781 get_option +EXPORT_SYMBOL vmlinux 0xb0f10b8c locks_copy_lock +EXPORT_SYMBOL vmlinux 0xb121390a probe_irq_on +EXPORT_SYMBOL vmlinux 0xb13c4dba down_write +EXPORT_SYMBOL vmlinux 0xb1723edc tty_flip_buffer_push +EXPORT_SYMBOL vmlinux 0xb19760c3 bitmap_onto +EXPORT_SYMBOL vmlinux 0xb1c3a01a oops_in_progress +EXPORT_SYMBOL vmlinux 0xb1cfad22 rdmsr_on_cpu +EXPORT_SYMBOL vmlinux 0xb1d8b8a8 qdisc_class_hash_grow +EXPORT_SYMBOL vmlinux 0xb1f975aa unlock_kernel +EXPORT_SYMBOL vmlinux 0xb2017c1d per_cpu__x86_bios_cpu_apicid +EXPORT_SYMBOL vmlinux 0xb22d63f5 bmap +EXPORT_SYMBOL vmlinux 0xb22fe6a3 netdev_increment_features +EXPORT_SYMBOL vmlinux 0xb2304011 journal_invalidatepage +EXPORT_SYMBOL vmlinux 0xb279da12 pv_lock_ops +EXPORT_SYMBOL vmlinux 0xb29bc8bd idr_remove +EXPORT_SYMBOL vmlinux 0xb2a82ff7 serial8250_register_port +EXPORT_SYMBOL vmlinux 0xb2b568f7 path_put +EXPORT_SYMBOL vmlinux 0xb2be638a dma_chan_cleanup +EXPORT_SYMBOL vmlinux 0xb2c5a21a blk_queue_update_dma_alignment +EXPORT_SYMBOL vmlinux 0xb2efb6be mca_read_stored_pos +EXPORT_SYMBOL vmlinux 0xb2fd5ceb __put_user_4 +EXPORT_SYMBOL vmlinux 0xb30abf8d idr_get_new_above +EXPORT_SYMBOL vmlinux 0xb312f05a gnet_stats_finish_copy +EXPORT_SYMBOL vmlinux 0xb31526ee sg_copy_from_buffer +EXPORT_SYMBOL vmlinux 0xb3205415 wait_for_completion_killable +EXPORT_SYMBOL vmlinux 0xb3284531 acpi_dbg_layer +EXPORT_SYMBOL vmlinux 0xb349886a vfs_quota_sync +EXPORT_SYMBOL vmlinux 0xb34d4c2e acpi_terminate +EXPORT_SYMBOL vmlinux 0xb352177e find_first_bit +EXPORT_SYMBOL vmlinux 0xb3692eb4 ioremap_wc +EXPORT_SYMBOL vmlinux 0xb376d79d radix_tree_tagged +EXPORT_SYMBOL vmlinux 0xb377bc96 tcp_timewait_state_process +EXPORT_SYMBOL vmlinux 0xb398f790 __tcp_get_md5sig_pool +EXPORT_SYMBOL vmlinux 0xb3a307c6 si_meminfo +EXPORT_SYMBOL vmlinux 0xb3e0590d acpi_set_current_resources +EXPORT_SYMBOL vmlinux 0xb40c336b kick_iocb +EXPORT_SYMBOL vmlinux 0xb41b2c0e netpoll_print_options +EXPORT_SYMBOL vmlinux 0xb423dba1 console_blanked +EXPORT_SYMBOL vmlinux 0xb429410a posix_acl_from_mode +EXPORT_SYMBOL vmlinux 0xb45578b8 memscan +EXPORT_SYMBOL vmlinux 0xb4559c8b backlight_device_unregister +EXPORT_SYMBOL vmlinux 0xb45b24f6 k8_nb_ids +EXPORT_SYMBOL vmlinux 0xb494e82a br_fdb_put_hook +EXPORT_SYMBOL vmlinux 0xb4ca9447 __kfifo_get +EXPORT_SYMBOL vmlinux 0xb4d77360 mca_unregister_driver +EXPORT_SYMBOL vmlinux 0xb4e2ad70 netlink_kernel_release +EXPORT_SYMBOL vmlinux 0xb5044271 vsscanf +EXPORT_SYMBOL vmlinux 0xb54533f7 usecs_to_jiffies +EXPORT_SYMBOL vmlinux 0xb5a459dc unregister_blkdev +EXPORT_SYMBOL vmlinux 0xb5b2b856 scsi_nonblockable_ioctl +EXPORT_SYMBOL vmlinux 0xb5d2763e netlink_clear_multicast_users +EXPORT_SYMBOL vmlinux 0xb5d52c27 ec_transaction +EXPORT_SYMBOL vmlinux 0xb5e6e590 xfrm_state_delete_tunnel +EXPORT_SYMBOL vmlinux 0xb5f28b5f __any_online_cpu +EXPORT_SYMBOL vmlinux 0xb60e34a8 nla_memcpy +EXPORT_SYMBOL vmlinux 0xb678366f int_sqrt +EXPORT_SYMBOL vmlinux 0xb693265a kmem_cache_shrink +EXPORT_SYMBOL vmlinux 0xb6a61a86 qdisc_get_rtab +EXPORT_SYMBOL vmlinux 0xb6bf50a9 unlock_buffer +EXPORT_SYMBOL vmlinux 0xb6c5a973 scsi_show_result +EXPORT_SYMBOL vmlinux 0xb6cd208d scsi_is_sdev_device +EXPORT_SYMBOL vmlinux 0xb6e227aa rtc_lock +EXPORT_SYMBOL vmlinux 0xb6ed1e53 strncpy +EXPORT_SYMBOL vmlinux 0xb703911e release_firmware +EXPORT_SYMBOL vmlinux 0xb714a981 console_print +EXPORT_SYMBOL vmlinux 0xb72397d5 printk +EXPORT_SYMBOL vmlinux 0xb7555f12 timeval_to_jiffies +EXPORT_SYMBOL vmlinux 0xb758b225 acpi_disable_event +EXPORT_SYMBOL vmlinux 0xb76c33d4 cfb_imageblit +EXPORT_SYMBOL vmlinux 0xb79b38e1 audit_log_start +EXPORT_SYMBOL vmlinux 0xb7b61546 crc32_be +EXPORT_SYMBOL vmlinux 0xb7b7011d file_fsync +EXPORT_SYMBOL vmlinux 0xb828c786 per_cpu__cpu_sibling_map +EXPORT_SYMBOL vmlinux 0xb85b2bac vm_stat +EXPORT_SYMBOL vmlinux 0xb8609dcd arp_create +EXPORT_SYMBOL vmlinux 0xb86e4ab9 random32 +EXPORT_SYMBOL vmlinux 0xb886e519 journal_get_undo_access +EXPORT_SYMBOL vmlinux 0xb894926d schedule_work_on +EXPORT_SYMBOL vmlinux 0xb89af9bf srandom32 +EXPORT_SYMBOL vmlinux 0xb8aa2342 __check_region +EXPORT_SYMBOL vmlinux 0xb8b15be8 mca_device_read_stored_pos +EXPORT_SYMBOL vmlinux 0xb8c6b8b7 pcim_iomap_regions_request_all +EXPORT_SYMBOL vmlinux 0xb8d69e08 security_d_instantiate +EXPORT_SYMBOL vmlinux 0xb8e7ce2c __put_user_8 +EXPORT_SYMBOL vmlinux 0xb8f4236f proc_mkdir +EXPORT_SYMBOL vmlinux 0xb8f70f57 kernel_getsockopt +EXPORT_SYMBOL vmlinux 0xb90eae23 tcf_em_register +EXPORT_SYMBOL vmlinux 0xb952846d vfs_dq_transfer +EXPORT_SYMBOL vmlinux 0xb95b5130 input_get_keycode +EXPORT_SYMBOL vmlinux 0xb95bcb8c bdi_register_dev +EXPORT_SYMBOL vmlinux 0xb97f0410 create_empty_buffers +EXPORT_SYMBOL vmlinux 0xb98813e2 tcp_v4_md5_do_del +EXPORT_SYMBOL vmlinux 0xb98a0185 rtc_tm_to_time +EXPORT_SYMBOL vmlinux 0xb9b865e6 inet_frags_init +EXPORT_SYMBOL vmlinux 0xb9c74bf1 gen_kill_estimator +EXPORT_SYMBOL vmlinux 0xb9f6d558 journal_dirty_data +EXPORT_SYMBOL vmlinux 0xb9fd2205 add_efi_memmap +EXPORT_SYMBOL vmlinux 0xba180b34 prepare_binprm +EXPORT_SYMBOL vmlinux 0xba196c98 dma_pool_free +EXPORT_SYMBOL vmlinux 0xba2d8594 ec_read +EXPORT_SYMBOL vmlinux 0xba497f13 loops_per_jiffy +EXPORT_SYMBOL vmlinux 0xba6c299b invalidate_inode_buffers +EXPORT_SYMBOL vmlinux 0xba6c62f5 tcp_v4_remember_stamp +EXPORT_SYMBOL vmlinux 0xba8d645b tcp_v4_do_rcv +EXPORT_SYMBOL vmlinux 0xbad05000 scsi_print_sense +EXPORT_SYMBOL vmlinux 0xbae5095c pcim_iomap +EXPORT_SYMBOL vmlinux 0xbae71059 blk_dump_rq_flags +EXPORT_SYMBOL vmlinux 0xbaefbe9c simple_transaction_read +EXPORT_SYMBOL vmlinux 0xbb10b024 input_unregister_handle +EXPORT_SYMBOL vmlinux 0xbb167766 fb_var_to_videomode +EXPORT_SYMBOL vmlinux 0xbb189cad disallow_signal +EXPORT_SYMBOL vmlinux 0xbb1ddf09 scsi_reset_provider +EXPORT_SYMBOL vmlinux 0xbb5d343d xfrm_get_acqseq +EXPORT_SYMBOL vmlinux 0xbb83bd29 xfrm_cfg_mutex +EXPORT_SYMBOL vmlinux 0xbb89de17 ida_init +EXPORT_SYMBOL vmlinux 0xbbc8e804 param_set_ushort +EXPORT_SYMBOL vmlinux 0xbc0947a6 xfrm_policy_unregister_afinfo +EXPORT_SYMBOL vmlinux 0xbc25b207 unregister_8022_client +EXPORT_SYMBOL vmlinux 0xbc41b7f9 unlock_rename +EXPORT_SYMBOL vmlinux 0xbc5ce66f thermal_cooling_device_unregister +EXPORT_SYMBOL vmlinux 0xbc85fc6b bio_kmalloc +EXPORT_SYMBOL vmlinux 0xbca03f87 tty_set_operations +EXPORT_SYMBOL vmlinux 0xbcc308bb strnlen_user +EXPORT_SYMBOL vmlinux 0xbcd630a1 mmc_suspend_host +EXPORT_SYMBOL vmlinux 0xbcf239e8 block_commit_write +EXPORT_SYMBOL vmlinux 0xbd0e234f task_tgid_nr_ns +EXPORT_SYMBOL vmlinux 0xbd10c3d8 dcache_readdir +EXPORT_SYMBOL vmlinux 0xbd1be4b8 km_new_mapping +EXPORT_SYMBOL vmlinux 0xbd69017f dev_set_mtu +EXPORT_SYMBOL vmlinux 0xbda84d36 vfs_dq_quota_on_remount +EXPORT_SYMBOL vmlinux 0xbdb7e415 is_container_init +EXPORT_SYMBOL vmlinux 0xbde2a2d8 sk_filter +EXPORT_SYMBOL vmlinux 0xbe0e5118 nla_memcmp +EXPORT_SYMBOL vmlinux 0xbe0f1399 pnp_start_dev +EXPORT_SYMBOL vmlinux 0xbe236fe2 bio_pair_release +EXPORT_SYMBOL vmlinux 0xbe63ee40 request_resource +EXPORT_SYMBOL vmlinux 0xbee618cd call_usermodehelper_setup +EXPORT_SYMBOL vmlinux 0xbef43296 console_conditional_schedule +EXPORT_SYMBOL vmlinux 0xbef6b541 fib_default_rule_add +EXPORT_SYMBOL vmlinux 0xbf13b163 rwsem_down_read_failed +EXPORT_SYMBOL vmlinux 0xbf183953 dquot_mark_dquot_dirty +EXPORT_SYMBOL vmlinux 0xbf772a1c fifo_create_dflt +EXPORT_SYMBOL vmlinux 0xbf7fd2f5 schedule_timeout_killable +EXPORT_SYMBOL vmlinux 0xbf8b39e9 isapnp_present +EXPORT_SYMBOL vmlinux 0xbf9bcc8d __cap_empty_set +EXPORT_SYMBOL vmlinux 0xbfa17560 pci_scan_bus_parented +EXPORT_SYMBOL vmlinux 0xbfa5831b __skb_recv_datagram +EXPORT_SYMBOL vmlinux 0xbfc177bc iowrite32_rep +EXPORT_SYMBOL vmlinux 0xbfe16bcc generic_osync_inode +EXPORT_SYMBOL vmlinux 0xbff4bc96 kobject_add +EXPORT_SYMBOL vmlinux 0xbff5c703 ip_cmsg_recv +EXPORT_SYMBOL vmlinux 0xc003c637 __strncpy_from_user +EXPORT_SYMBOL vmlinux 0xc01e4e5b tc_classify +EXPORT_SYMBOL vmlinux 0xc01eed33 __copy_from_user_ll_nozero +EXPORT_SYMBOL vmlinux 0xc023064b __scsi_add_device +EXPORT_SYMBOL vmlinux 0xc045ad4e timespec_trunc +EXPORT_SYMBOL vmlinux 0xc04c1d25 bdi_set_max_ratio +EXPORT_SYMBOL vmlinux 0xc0580937 rb_erase +EXPORT_SYMBOL vmlinux 0xc06ccc9a find_get_pages_tag +EXPORT_SYMBOL vmlinux 0xc0a3d105 find_next_bit +EXPORT_SYMBOL vmlinux 0xc0e01240 qdisc_list_del +EXPORT_SYMBOL vmlinux 0xc0e12bfa xfrm_policy_byid +EXPORT_SYMBOL vmlinux 0xc0fb801a inet_sock_destruct +EXPORT_SYMBOL vmlinux 0xc11d8093 iov_shorten +EXPORT_SYMBOL vmlinux 0xc1463b6c pci_choose_state +EXPORT_SYMBOL vmlinux 0xc1ce2d53 gnet_stats_copy_basic +EXPORT_SYMBOL vmlinux 0xc1eef1e7 scsi_set_medium_removal +EXPORT_SYMBOL vmlinux 0xc1ff7d23 task_nice +EXPORT_SYMBOL vmlinux 0xc2152dea pci_bus_alloc_resource +EXPORT_SYMBOL vmlinux 0xc2162af9 tty_shutdown +EXPORT_SYMBOL vmlinux 0xc21a6853 sk_stream_write_space +EXPORT_SYMBOL vmlinux 0xc239aa4f block_invalidatepage +EXPORT_SYMBOL vmlinux 0xc2480d3a inet_listen +EXPORT_SYMBOL vmlinux 0xc254af48 dcache_lock +EXPORT_SYMBOL vmlinux 0xc256e762 __bitmap_equal +EXPORT_SYMBOL vmlinux 0xc266a14a noop_qdisc +EXPORT_SYMBOL vmlinux 0xc27ef5a0 vfs_rename +EXPORT_SYMBOL vmlinux 0xc280a525 __copy_from_user_ll +EXPORT_SYMBOL vmlinux 0xc2cd2114 fb_find_mode +EXPORT_SYMBOL vmlinux 0xc2d711e1 krealloc +EXPORT_SYMBOL vmlinux 0xc2e00b24 do_sync_read +EXPORT_SYMBOL vmlinux 0xc2e587d1 reset_devices +EXPORT_SYMBOL vmlinux 0xc3084280 get_sb_single +EXPORT_SYMBOL vmlinux 0xc31bc137 flush_old_exec +EXPORT_SYMBOL vmlinux 0xc31e448b blk_queue_init_tags +EXPORT_SYMBOL vmlinux 0xc33f6f4c on_each_cpu +EXPORT_SYMBOL vmlinux 0xc3806ff5 bio_init +EXPORT_SYMBOL vmlinux 0xc382e926 skb_copy_expand +EXPORT_SYMBOL vmlinux 0xc3aaf0a9 __put_user_1 +EXPORT_SYMBOL vmlinux 0xc3b8dec8 proc_dointvec_userhz_jiffies +EXPORT_SYMBOL vmlinux 0xc3bb9e14 pci_set_consistent_dma_mask +EXPORT_SYMBOL vmlinux 0xc3cf1128 in_group_p +EXPORT_SYMBOL vmlinux 0xc3e5c802 touch_atime +EXPORT_SYMBOL vmlinux 0xc3fa6a59 memchr +EXPORT_SYMBOL vmlinux 0xc4023eb3 jbd2_journal_init_dev +EXPORT_SYMBOL vmlinux 0xc402cc99 register_acpi_notifier +EXPORT_SYMBOL vmlinux 0xc427692b tty_port_init +EXPORT_SYMBOL vmlinux 0xc499ae1e kstrdup +EXPORT_SYMBOL vmlinux 0xc4a3e228 dentry_open +EXPORT_SYMBOL vmlinux 0xc4a550ce scsi_cmd_print_sense_hdr +EXPORT_SYMBOL vmlinux 0xc4b00ab0 test_set_page_writeback +EXPORT_SYMBOL vmlinux 0xc4ebfc80 framebuffer_alloc +EXPORT_SYMBOL vmlinux 0xc4ffd5f8 inc_zone_page_state +EXPORT_SYMBOL vmlinux 0xc5029841 sock_release +EXPORT_SYMBOL vmlinux 0xc50395ee truncate_inode_pages_range +EXPORT_SYMBOL vmlinux 0xc52665a9 d_add_ci +EXPORT_SYMBOL vmlinux 0xc52f5714 fb_videomode_to_var +EXPORT_SYMBOL vmlinux 0xc53446c4 xfrm_state_alloc +EXPORT_SYMBOL vmlinux 0xc5534d64 ioread16 +EXPORT_SYMBOL vmlinux 0xc55f7dc7 _write_trylock +EXPORT_SYMBOL vmlinux 0xc5718627 sg_copy_to_buffer +EXPORT_SYMBOL vmlinux 0xc5844fb8 __per_cpu_offset +EXPORT_SYMBOL vmlinux 0xc5abe5a0 scsicam_bios_param +EXPORT_SYMBOL vmlinux 0xc5ba2c3c proto_unregister +EXPORT_SYMBOL vmlinux 0xc5d84c03 dev_alloc_name +EXPORT_SYMBOL vmlinux 0xc615928c xfrm_state_add +EXPORT_SYMBOL vmlinux 0xc62c4dda directly_mappable_cdev_bdi +EXPORT_SYMBOL vmlinux 0xc632425f journal_init_dev +EXPORT_SYMBOL vmlinux 0xc633dd19 pci_target_state +EXPORT_SYMBOL vmlinux 0xc63fbc88 bd_claim +EXPORT_SYMBOL vmlinux 0xc640bb4d vfs_permission +EXPORT_SYMBOL vmlinux 0xc64b61f1 mca_bus_type +EXPORT_SYMBOL vmlinux 0xc698f6e0 proto_register +EXPORT_SYMBOL vmlinux 0xc6a3ee16 sockfd_lookup +EXPORT_SYMBOL vmlinux 0xc6ba509a mca_device_transform_irq +EXPORT_SYMBOL vmlinux 0xc6c2334d bio_add_page +EXPORT_SYMBOL vmlinux 0xc70f77c1 pnp_is_active +EXPORT_SYMBOL vmlinux 0xc7131591 pcibios_align_resource +EXPORT_SYMBOL vmlinux 0xc7208c3a serial8250_resume_port +EXPORT_SYMBOL vmlinux 0xc73c86d2 generic_file_aio_write_nolock +EXPORT_SYMBOL vmlinux 0xc78dd838 sock_no_listen +EXPORT_SYMBOL vmlinux 0xc79deaca __inode_dir_notify +EXPORT_SYMBOL vmlinux 0xc7a4fbed rtnl_lock +EXPORT_SYMBOL vmlinux 0xc7d56940 vmtruncate +EXPORT_SYMBOL vmlinux 0xc7da9ad5 fifo_set_limit +EXPORT_SYMBOL vmlinux 0xc7ec6c27 strspn +EXPORT_SYMBOL vmlinux 0xc8240c28 generic_delete_inode +EXPORT_SYMBOL vmlinux 0xc8a78a14 ip_nat_decode_session +EXPORT_SYMBOL vmlinux 0xc8b57c27 autoremove_wake_function +EXPORT_SYMBOL vmlinux 0xc8ca3e25 acpi_get_child +EXPORT_SYMBOL vmlinux 0xc9247c61 jbd2_journal_file_inode +EXPORT_SYMBOL vmlinux 0xc95b3124 skb_copy_datagram_iovec +EXPORT_SYMBOL vmlinux 0xc97fa3c9 cont_write_begin +EXPORT_SYMBOL vmlinux 0xc9951ad5 __set_page_dirty_nobuffers +EXPORT_SYMBOL vmlinux 0xc998d641 icmp_err_convert +EXPORT_SYMBOL vmlinux 0xc99fef51 neigh_destroy +EXPORT_SYMBOL vmlinux 0xc9ab2eef acpi_os_wait_events_complete +EXPORT_SYMBOL vmlinux 0xc9d8bce0 fasync_helper +EXPORT_SYMBOL vmlinux 0xc9f4f23c pci_bus_type +EXPORT_SYMBOL vmlinux 0xca0c0675 blk_queue_softirq_done +EXPORT_SYMBOL vmlinux 0xca232769 register_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0xca2904ed blk_queue_bounce +EXPORT_SYMBOL vmlinux 0xca58f4a2 __secpath_destroy +EXPORT_SYMBOL vmlinux 0xca5a3ddf devm_ioremap_nocache +EXPORT_SYMBOL vmlinux 0xca5dbc50 scsi_print_sense_hdr +EXPORT_SYMBOL vmlinux 0xca6320d5 mmc_add_host +EXPORT_SYMBOL vmlinux 0xca8914d5 neigh_seq_start +EXPORT_SYMBOL vmlinux 0xca8acc78 acpi_dbg_level +EXPORT_SYMBOL vmlinux 0xca8d13eb mark_page_accessed +EXPORT_SYMBOL vmlinux 0xca93a948 pci_find_next_bus +EXPORT_SYMBOL vmlinux 0xca961885 nobh_truncate_page +EXPORT_SYMBOL vmlinux 0xcaa56fcc mark_info_dirty +EXPORT_SYMBOL vmlinux 0xcab1a131 linkwatch_fire_event +EXPORT_SYMBOL vmlinux 0xcabdccb0 kmem_cache_free +EXPORT_SYMBOL vmlinux 0xcae7b115 set_blocksize +EXPORT_SYMBOL vmlinux 0xcafa24c7 mmc_register_driver +EXPORT_SYMBOL vmlinux 0xcafadbe4 sock_no_shutdown +EXPORT_SYMBOL vmlinux 0xcb040c07 nf_ct_attach +EXPORT_SYMBOL vmlinux 0xcb1612fc simple_transaction_get +EXPORT_SYMBOL vmlinux 0xcb32da10 param_set_int +EXPORT_SYMBOL vmlinux 0xcb6beb40 hweight32 +EXPORT_SYMBOL vmlinux 0xcb7131fb fb_get_options +EXPORT_SYMBOL vmlinux 0xcb733bf2 acpi_bus_set_power +EXPORT_SYMBOL vmlinux 0xcb9cfc05 qdisc_calculate_pkt_len +EXPORT_SYMBOL vmlinux 0xcbcaa494 dev_unicast_add +EXPORT_SYMBOL vmlinux 0xcbd5f0f8 kernel_read +EXPORT_SYMBOL vmlinux 0xcbdaf538 scsi_print_result +EXPORT_SYMBOL vmlinux 0xcc248d26 serial8250_suspend_port +EXPORT_SYMBOL vmlinux 0xcc26ac01 tcp_v4_syn_recv_sock +EXPORT_SYMBOL vmlinux 0xcc363096 journal_update_format +EXPORT_SYMBOL vmlinux 0xcc36f32e fb_unregister_client +EXPORT_SYMBOL vmlinux 0xcc4240bf dquot_alloc_space +EXPORT_SYMBOL vmlinux 0xcc5005fe msleep_interruptible +EXPORT_SYMBOL vmlinux 0xcc51ee50 dma_spin_lock +EXPORT_SYMBOL vmlinux 0xcc7fa952 local_bh_enable_ip +EXPORT_SYMBOL vmlinux 0xcca35c8b xfrm_policy_walk +EXPORT_SYMBOL vmlinux 0xccd82c71 ethtool_op_set_tso +EXPORT_SYMBOL vmlinux 0xccf70675 kill_pid +EXPORT_SYMBOL vmlinux 0xccfe3efa user_revoke +EXPORT_SYMBOL vmlinux 0xcd03c327 put_page +EXPORT_SYMBOL vmlinux 0xcd1d76c0 seq_read +EXPORT_SYMBOL vmlinux 0xcd250ad6 journal_init_inode +EXPORT_SYMBOL vmlinux 0xcd5f0fb8 pcie_port_service_unregister +EXPORT_SYMBOL vmlinux 0xcd835be1 xfrm_init_state +EXPORT_SYMBOL vmlinux 0xcd8ca27f generic_unplug_device +EXPORT_SYMBOL vmlinux 0xcd8fb736 scsi_finish_command +EXPORT_SYMBOL vmlinux 0xcde4f9c4 lookup_one_len +EXPORT_SYMBOL vmlinux 0xcdfd8faa load_nls +EXPORT_SYMBOL vmlinux 0xce1e4e37 inet_put_port +EXPORT_SYMBOL vmlinux 0xce36ded6 sysctl_tcp_mem +EXPORT_SYMBOL vmlinux 0xce37bb87 security_task_getsecid +EXPORT_SYMBOL vmlinux 0xce4904a4 acpi_leave_sleep_state +EXPORT_SYMBOL vmlinux 0xce5ac24f zlib_inflate_workspacesize +EXPORT_SYMBOL vmlinux 0xce66757f input_allocate_device +EXPORT_SYMBOL vmlinux 0xce9ca1c7 __getblk +EXPORT_SYMBOL vmlinux 0xcefcd99a serial8250_unregister_port +EXPORT_SYMBOL vmlinux 0xcf1602c4 audit_log_end +EXPORT_SYMBOL vmlinux 0xcf25e70b unregister_binfmt +EXPORT_SYMBOL vmlinux 0xcf2b2ac9 pci_disable_device +EXPORT_SYMBOL vmlinux 0xcf55f536 d_find_alias +EXPORT_SYMBOL vmlinux 0xcf6d7aa0 ip_route_input +EXPORT_SYMBOL vmlinux 0xcf843fbf path_lookup +EXPORT_SYMBOL vmlinux 0xcf860fac setup_arg_pages +EXPORT_SYMBOL vmlinux 0xcf879319 __ip_select_ident +EXPORT_SYMBOL vmlinux 0xcfa7bafa thermal_zone_bind_cooling_device +EXPORT_SYMBOL vmlinux 0xcfadd723 __percpu_counter_add +EXPORT_SYMBOL vmlinux 0xcfbe3ded inet_stream_connect +EXPORT_SYMBOL vmlinux 0xcfd3018e set_normalized_timespec +EXPORT_SYMBOL vmlinux 0xcfd3819a tcf_destroy_chain +EXPORT_SYMBOL vmlinux 0xcffbe42c jbd2_journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0xd0181f4f __bitmap_xor +EXPORT_SYMBOL vmlinux 0xd02cc869 __bitmap_andnot +EXPORT_SYMBOL vmlinux 0xd0520303 pci_enable_msi +EXPORT_SYMBOL vmlinux 0xd053925a init_buffer +EXPORT_SYMBOL vmlinux 0xd063f8e4 devm_ioport_map +EXPORT_SYMBOL vmlinux 0xd0751a0d do_munmap +EXPORT_SYMBOL vmlinux 0xd08197fa acpi_load_tables +EXPORT_SYMBOL vmlinux 0xd09cdccd uart_update_timeout +EXPORT_SYMBOL vmlinux 0xd0a768f5 pci_match_id +EXPORT_SYMBOL vmlinux 0xd0d213de vfs_readlink +EXPORT_SYMBOL vmlinux 0xd0d8621b strlen +EXPORT_SYMBOL vmlinux 0xd0ee38b8 schedule_timeout_uninterruptible +EXPORT_SYMBOL vmlinux 0xd1472061 acpi_pci_register_driver +EXPORT_SYMBOL vmlinux 0xd15172f9 input_event +EXPORT_SYMBOL vmlinux 0xd18b6eb2 acpi_unmap_lsapic +EXPORT_SYMBOL vmlinux 0xd1d5d6da register_console +EXPORT_SYMBOL vmlinux 0xd1f6c5f3 smp_num_siblings +EXPORT_SYMBOL vmlinux 0xd1f91bcd dev_base_lock +EXPORT_SYMBOL vmlinux 0xd21e1737 __f_setown +EXPORT_SYMBOL vmlinux 0xd251d7b0 security_socket_getpeersec_dgram +EXPORT_SYMBOL vmlinux 0xd2555f19 jiffies_64_to_clock_t +EXPORT_SYMBOL vmlinux 0xd25b5856 inet_frags_exit_net +EXPORT_SYMBOL vmlinux 0xd25d4f74 console_blank_hook +EXPORT_SYMBOL vmlinux 0xd267d42c down_killable +EXPORT_SYMBOL vmlinux 0xd2965f6f kthread_should_stop +EXPORT_SYMBOL vmlinux 0xd2981b51 request_key_async_with_auxdata +EXPORT_SYMBOL vmlinux 0xd2a17692 sock_kfree_s +EXPORT_SYMBOL vmlinux 0xd2a31068 inet_csk_reset_keepalive_timer +EXPORT_SYMBOL vmlinux 0xd2a941d4 sg_init_table +EXPORT_SYMBOL vmlinux 0xd2ad8350 scsi_track_queue_full +EXPORT_SYMBOL vmlinux 0xd2ca7419 kernel_setsockopt +EXPORT_SYMBOL vmlinux 0xd2d79897 ether_setup +EXPORT_SYMBOL vmlinux 0xd3309c5c user_path_at +EXPORT_SYMBOL vmlinux 0xd34f0c62 gen_pool_create +EXPORT_SYMBOL vmlinux 0xd3545464 simple_write_end +EXPORT_SYMBOL vmlinux 0xd35ac51b iput +EXPORT_SYMBOL vmlinux 0xd35f163f simple_unlink +EXPORT_SYMBOL vmlinux 0xd366f319 dma_pool_alloc +EXPORT_SYMBOL vmlinux 0xd38dc630 __locks_copy_lock +EXPORT_SYMBOL vmlinux 0xd3951da4 acpi_resource_to_address64 +EXPORT_SYMBOL vmlinux 0xd3c03509 sk_stop_timer +EXPORT_SYMBOL vmlinux 0xd3e129ee uhci_clear_usb_int +EXPORT_SYMBOL vmlinux 0xd3e2b0c9 __lock_buffer +EXPORT_SYMBOL vmlinux 0xd3f74cf1 interruptible_sleep_on_timeout +EXPORT_SYMBOL vmlinux 0xd3fe25ea scm_detach_fds +EXPORT_SYMBOL vmlinux 0xd408e68c iw_handler_get_spy +EXPORT_SYMBOL vmlinux 0xd411a9b9 generic_file_aio_write +EXPORT_SYMBOL vmlinux 0xd418e1c0 adjust_resource +EXPORT_SYMBOL vmlinux 0xd42b7232 _write_unlock_bh +EXPORT_SYMBOL vmlinux 0xd46130d6 dma_async_device_unregister +EXPORT_SYMBOL vmlinux 0xd4a7fe74 inet_frag_destroy +EXPORT_SYMBOL vmlinux 0xd4aaade9 unbind_con_driver +EXPORT_SYMBOL vmlinux 0xd4bb579c km_policy_expired +EXPORT_SYMBOL vmlinux 0xd4f2e2ca close_bdev_exclusive +EXPORT_SYMBOL vmlinux 0xd4f33ebe uart_match_port +EXPORT_SYMBOL vmlinux 0xd5055e39 datagram_poll +EXPORT_SYMBOL vmlinux 0xd50638c4 splice_direct_to_actor +EXPORT_SYMBOL vmlinux 0xd5263820 mb_cache_destroy +EXPORT_SYMBOL vmlinux 0xd53aec49 cpu_possible_map +EXPORT_SYMBOL vmlinux 0xd54ecf43 wait_on_page_bit +EXPORT_SYMBOL vmlinux 0xd560e321 kmap_high +EXPORT_SYMBOL vmlinux 0xd56228dc tcp_md5_hash_header +EXPORT_SYMBOL vmlinux 0xd5688a7a radix_tree_insert +EXPORT_SYMBOL vmlinux 0xd5b037e1 kref_put +EXPORT_SYMBOL vmlinux 0xd5bb3c87 pcix_get_max_mmrbc +EXPORT_SYMBOL vmlinux 0xd5beff9a register_gifconf +EXPORT_SYMBOL vmlinux 0xd5c57f6a __pskb_pull_tail +EXPORT_SYMBOL vmlinux 0xd5d92d05 set_device_ro +EXPORT_SYMBOL vmlinux 0xd5eaa7e1 set_page_dirty_lock +EXPORT_SYMBOL vmlinux 0xd5fee499 d_prune_aliases +EXPORT_SYMBOL vmlinux 0xd6035d05 do_settimeofday +EXPORT_SYMBOL vmlinux 0xd62c833f schedule_timeout +EXPORT_SYMBOL vmlinux 0xd642fefb pci_find_capability +EXPORT_SYMBOL vmlinux 0xd660c450 ip_fragment +EXPORT_SYMBOL vmlinux 0xd66f1ec3 scsi_report_device_reset +EXPORT_SYMBOL vmlinux 0xd675b8db pci_bus_write_config_dword +EXPORT_SYMBOL vmlinux 0xd6a614e1 bh_uptodate_or_lock +EXPORT_SYMBOL vmlinux 0xd6a78d08 smp_call_function_single +EXPORT_SYMBOL vmlinux 0xd6a84bb2 simple_dir_operations +EXPORT_SYMBOL vmlinux 0xd6b33026 cpu_khz +EXPORT_SYMBOL vmlinux 0xd6b42908 remove_arg_zero +EXPORT_SYMBOL vmlinux 0xd6db5ebd ___pskb_trim +EXPORT_SYMBOL vmlinux 0xd6ee688f vmalloc +EXPORT_SYMBOL vmlinux 0xd6f0589b dma_async_device_register +EXPORT_SYMBOL vmlinux 0xd6f1beb8 dma_async_client_chan_request +EXPORT_SYMBOL vmlinux 0xd73f9a52 arch_debugfs_dir +EXPORT_SYMBOL vmlinux 0xd747cf1d cdev_add +EXPORT_SYMBOL vmlinux 0xd757dc9b bio_copy_kern +EXPORT_SYMBOL vmlinux 0xd79b5a02 allow_signal +EXPORT_SYMBOL vmlinux 0xd79f8c59 key_unlink +EXPORT_SYMBOL vmlinux 0xd7a6fafa panic_notifier_list +EXPORT_SYMBOL vmlinux 0xd7b44f50 textsearch_prepare +EXPORT_SYMBOL vmlinux 0xd7c60429 kernel_sock_shutdown +EXPORT_SYMBOL vmlinux 0xd7d36d1a idr_find +EXPORT_SYMBOL vmlinux 0xd7dd777b reserve_perfctr_nmi +EXPORT_SYMBOL vmlinux 0xd7f7dd8a xfrm_state_insert +EXPORT_SYMBOL vmlinux 0xd7fc9e87 nf_unregister_queue_handler +EXPORT_SYMBOL vmlinux 0xd81fde53 __scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0xd841ece8 ethtool_op_set_flags +EXPORT_SYMBOL vmlinux 0xd852891d __dst_free +EXPORT_SYMBOL vmlinux 0xd855b8a7 tcp_mtup_init +EXPORT_SYMBOL vmlinux 0xd855fdda sock_no_ioctl +EXPORT_SYMBOL vmlinux 0xd8568c93 blk_queue_dma_alignment +EXPORT_SYMBOL vmlinux 0xd86fff31 vfs_getattr +EXPORT_SYMBOL vmlinux 0xd88d7363 register_sysrq_key +EXPORT_SYMBOL vmlinux 0xd88f695a __mod_timer +EXPORT_SYMBOL vmlinux 0xd89da37f movable_zone +EXPORT_SYMBOL vmlinux 0xd8a2ab95 in_egroup_p +EXPORT_SYMBOL vmlinux 0xd8aa02cc skb_queue_purge +EXPORT_SYMBOL vmlinux 0xd8b19b67 mntput_no_expire +EXPORT_SYMBOL vmlinux 0xd8e484f0 register_chrdev_region +EXPORT_SYMBOL vmlinux 0xd8e5e48f tcf_exts_change +EXPORT_SYMBOL vmlinux 0xd8f7dadb misc_register +EXPORT_SYMBOL vmlinux 0xd9091363 acpi_install_notify_handler +EXPORT_SYMBOL vmlinux 0xd958b889 redraw_screen +EXPORT_SYMBOL vmlinux 0xd95bc76d xfrm_policy_alloc +EXPORT_SYMBOL vmlinux 0xd96190aa log_wait_commit +EXPORT_SYMBOL vmlinux 0xd985dc99 mempool_free_pages +EXPORT_SYMBOL vmlinux 0xd98962cb llc_sap_open +EXPORT_SYMBOL vmlinux 0xd9915573 scsi_get_host_dev +EXPORT_SYMBOL vmlinux 0xd996d859 idr_pre_get +EXPORT_SYMBOL vmlinux 0xd9b26c32 acpi_bus_start +EXPORT_SYMBOL vmlinux 0xd9b4bddb __page_symlink +EXPORT_SYMBOL vmlinux 0xd9c272aa mca_mark_as_unused +EXPORT_SYMBOL vmlinux 0xd9d2f3ab scsi_setup_blk_pc_cmnd +EXPORT_SYMBOL vmlinux 0xd9d3d293 pci_pme_capable +EXPORT_SYMBOL vmlinux 0xd9f50e85 ll_rw_block +EXPORT_SYMBOL vmlinux 0xda08c0d7 pcibios_get_irq_routing_table +EXPORT_SYMBOL vmlinux 0xda0a6b0e acpi_map_lsapic +EXPORT_SYMBOL vmlinux 0xda1a7335 kasprintf +EXPORT_SYMBOL vmlinux 0xda3fa787 tty_unthrottle +EXPORT_SYMBOL vmlinux 0xda48312c module_put +EXPORT_SYMBOL vmlinux 0xda7084c0 try_to_free_buffers +EXPORT_SYMBOL vmlinux 0xda74e2b1 dma_release_declared_memory +EXPORT_SYMBOL vmlinux 0xda7ca6cb fb_mode_is_equal +EXPORT_SYMBOL vmlinux 0xda7d5f47 inet_getname +EXPORT_SYMBOL vmlinux 0xda8af7ad fb_find_nearest_mode +EXPORT_SYMBOL vmlinux 0xda8fd495 isapnp_write_byte +EXPORT_SYMBOL vmlinux 0xda928914 nmi_watchdog +EXPORT_SYMBOL vmlinux 0xdaa57ec3 totalhigh_pages +EXPORT_SYMBOL vmlinux 0xdaced6f0 sock_no_getname +EXPORT_SYMBOL vmlinux 0xdad363a2 bdi_destroy +EXPORT_SYMBOL vmlinux 0xdaf2028a kill_litter_super +EXPORT_SYMBOL vmlinux 0xdb14ff8f __fatal_signal_pending +EXPORT_SYMBOL vmlinux 0xdb40542d open_bdev_exclusive +EXPORT_SYMBOL vmlinux 0xdb6ce750 copy_io_context +EXPORT_SYMBOL vmlinux 0xdb864d65 iov_iter_single_seg_count +EXPORT_SYMBOL vmlinux 0xdb98bdde sk_stream_wait_close +EXPORT_SYMBOL vmlinux 0xdb9a48f3 tcp_splice_read +EXPORT_SYMBOL vmlinux 0xdbb10be4 sock_setsockopt +EXPORT_SYMBOL vmlinux 0xdbba191c pci_bus_find_capability +EXPORT_SYMBOL vmlinux 0xdbcd416e sysctl_ip_nonlocal_bind +EXPORT_SYMBOL vmlinux 0xdc14eda7 pci_pci_problems +EXPORT_SYMBOL vmlinux 0xdc2adb35 add_taint +EXPORT_SYMBOL vmlinux 0xdc2e4e84 elv_queue_empty +EXPORT_SYMBOL vmlinux 0xdc43a9c8 daemonize +EXPORT_SYMBOL vmlinux 0xdc4b4d6c dma_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0xdc86db2d bio_unmap_user +EXPORT_SYMBOL vmlinux 0xdc873a70 screen_info +EXPORT_SYMBOL vmlinux 0xdc8aaf52 dma_async_tx_descriptor_init +EXPORT_SYMBOL vmlinux 0xdcb13ef3 request_firmware_nowait +EXPORT_SYMBOL vmlinux 0xdcb2f6c4 key_task_permission +EXPORT_SYMBOL vmlinux 0xdcba2718 ipv6_skip_exthdr +EXPORT_SYMBOL vmlinux 0xdcc5baf2 pci_select_bars +EXPORT_SYMBOL vmlinux 0xdd06d7b4 jbd2_journal_clear_features +EXPORT_SYMBOL vmlinux 0xdd0a2ba2 strlcat +EXPORT_SYMBOL vmlinux 0xdd2e62cd generic_splice_sendpage +EXPORT_SYMBOL vmlinux 0xdd301e4e sock_no_poll +EXPORT_SYMBOL vmlinux 0xdd45d4ca vc_resize +EXPORT_SYMBOL vmlinux 0xdd6bfccd radix_tree_tag_set +EXPORT_SYMBOL vmlinux 0xdd762e3a tcp_sync_mss +EXPORT_SYMBOL vmlinux 0xdd8071a2 pnp_release_card_device +EXPORT_SYMBOL vmlinux 0xdd85ec0e xfrm_policy_register_afinfo +EXPORT_SYMBOL vmlinux 0xddc8eb07 generic_cont_expand_simple +EXPORT_SYMBOL vmlinux 0xddd6b0f8 load_nls_default +EXPORT_SYMBOL vmlinux 0xdde86aac sysctl_ms_jiffies +EXPORT_SYMBOL vmlinux 0xdde95460 block_sync_page +EXPORT_SYMBOL vmlinux 0xddeef053 vfs_stat +EXPORT_SYMBOL vmlinux 0xde40231f alloc_disk_node +EXPORT_SYMBOL vmlinux 0xde59b1f5 sk_stream_error +EXPORT_SYMBOL vmlinux 0xde75b689 set_irq_type +EXPORT_SYMBOL vmlinux 0xde9360ba totalram_pages +EXPORT_SYMBOL vmlinux 0xdea8ad18 send_sig +EXPORT_SYMBOL vmlinux 0xdecd8750 input_register_handle +EXPORT_SYMBOL vmlinux 0xded6cf2e iget5_locked +EXPORT_SYMBOL vmlinux 0xdf00f12f pcix_set_mmrbc +EXPORT_SYMBOL vmlinux 0xdf0da3cc acpi_get_devices +EXPORT_SYMBOL vmlinux 0xdf2ae72c skb_abort_seq_read +EXPORT_SYMBOL vmlinux 0xdf60cc27 __print_symbol +EXPORT_SYMBOL vmlinux 0xdf8c1f82 scsi_bios_ptable +EXPORT_SYMBOL vmlinux 0xdf8c695a __ndelay +EXPORT_SYMBOL vmlinux 0xdf929370 fs_overflowgid +EXPORT_SYMBOL vmlinux 0xdf9a0562 __inet6_lookup_established +EXPORT_SYMBOL vmlinux 0xdf9f2910 skb_unlink +EXPORT_SYMBOL vmlinux 0xdfa80abf devm_free_irq +EXPORT_SYMBOL vmlinux 0xdfdfcd96 unregister_snap_client +EXPORT_SYMBOL vmlinux 0xe037bc4a __kill_fasync +EXPORT_SYMBOL vmlinux 0xe043bf76 ip_getsockopt +EXPORT_SYMBOL vmlinux 0xe05395e7 register_exec_domain +EXPORT_SYMBOL vmlinux 0xe06b4431 wait_for_key_construction +EXPORT_SYMBOL vmlinux 0xe06d382f __invalidate_device +EXPORT_SYMBOL vmlinux 0xe075d6eb iter_div_u64_rem +EXPORT_SYMBOL vmlinux 0xe094ef39 sg_next +EXPORT_SYMBOL vmlinux 0xe0a501e3 idr_remove_all +EXPORT_SYMBOL vmlinux 0xe0ac8bd2 acpi_bus_generate_netlink_event +EXPORT_SYMBOL vmlinux 0xe0b13336 argv_free +EXPORT_SYMBOL vmlinux 0xe11188d1 __lock_page +EXPORT_SYMBOL vmlinux 0xe13cd8a7 dmi_name_in_vendors +EXPORT_SYMBOL vmlinux 0xe1449cd6 fb_get_buffer_offset +EXPORT_SYMBOL vmlinux 0xe14dd181 d_genocide +EXPORT_SYMBOL vmlinux 0xe15aeee2 downgrade_write +EXPORT_SYMBOL vmlinux 0xe16f8a79 per_cpu__irq_regs +EXPORT_SYMBOL vmlinux 0xe1761617 security_inet_conn_request +EXPORT_SYMBOL vmlinux 0xe1f464f4 ip_mc_dec_group +EXPORT_SYMBOL vmlinux 0xe206be2a thermal_zone_unbind_cooling_device +EXPORT_SYMBOL vmlinux 0xe22a1b8b skb_store_bits +EXPORT_SYMBOL vmlinux 0xe24d3a97 jiffies_64 +EXPORT_SYMBOL vmlinux 0xe252918e mca_device_write_pos +EXPORT_SYMBOL vmlinux 0xe25ea0af ip_mc_rejoin_group +EXPORT_SYMBOL vmlinux 0xe2677658 sock_recvmsg +EXPORT_SYMBOL vmlinux 0xe282a745 skb_prepare_seq_read +EXPORT_SYMBOL vmlinux 0xe2c90de7 jbd2_journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0xe2d5255a strcmp +EXPORT_SYMBOL vmlinux 0xe2fa236b generic_setxattr +EXPORT_SYMBOL vmlinux 0xe2fae716 kmemdup +EXPORT_SYMBOL vmlinux 0xe305bb6d tcp_alloc_md5sig_pool +EXPORT_SYMBOL vmlinux 0xe343cc1f vc_cons +EXPORT_SYMBOL vmlinux 0xe351633f genl_register_family +EXPORT_SYMBOL vmlinux 0xe35fe139 elv_dispatch_sort +EXPORT_SYMBOL vmlinux 0xe390cd4e blk_plug_device +EXPORT_SYMBOL vmlinux 0xe3a1c288 con_is_bound +EXPORT_SYMBOL vmlinux 0xe3a808ab scsi_device_get +EXPORT_SYMBOL vmlinux 0xe3c775a3 icmp_send +EXPORT_SYMBOL vmlinux 0xe3cb458c sock_init_data +EXPORT_SYMBOL vmlinux 0xe3eb7a4f filemap_fdatawait +EXPORT_SYMBOL vmlinux 0xe3fbe148 acpi_install_table_handler +EXPORT_SYMBOL vmlinux 0xe41d06ae mca_device_status +EXPORT_SYMBOL vmlinux 0xe422e755 __breadahead +EXPORT_SYMBOL vmlinux 0xe43617f7 acpi_gbl_FADT +EXPORT_SYMBOL vmlinux 0xe437f612 dma_async_memcpy_buf_to_pg +EXPORT_SYMBOL vmlinux 0xe43e38e8 __sk_dst_check +EXPORT_SYMBOL vmlinux 0xe456bd3a complete +EXPORT_SYMBOL vmlinux 0xe47ab11b pci_try_set_mwi +EXPORT_SYMBOL vmlinux 0xe484e35f ioread32 +EXPORT_SYMBOL vmlinux 0xe4870354 _read_trylock +EXPORT_SYMBOL vmlinux 0xe48f3039 ida_get_new_above +EXPORT_SYMBOL vmlinux 0xe49a9db8 gnet_stats_start_copy +EXPORT_SYMBOL vmlinux 0xe4b24b8c __next_cpu +EXPORT_SYMBOL vmlinux 0xe4b9c8b8 netlink_ack +EXPORT_SYMBOL vmlinux 0xe4babf28 mmc_resume_host +EXPORT_SYMBOL vmlinux 0xe4c1df3e _read_lock_bh +EXPORT_SYMBOL vmlinux 0xe4e46962 cdrom_release +EXPORT_SYMBOL vmlinux 0xe4fdf498 get_sb_bdev +EXPORT_SYMBOL vmlinux 0xe50795e8 pci_reenable_device +EXPORT_SYMBOL vmlinux 0xe508019b blk_queue_dma_pad +EXPORT_SYMBOL vmlinux 0xe5122890 flow_cache_genid +EXPORT_SYMBOL vmlinux 0xe519106f mca_device_set_claim +EXPORT_SYMBOL vmlinux 0xe523ad75 synchronize_irq +EXPORT_SYMBOL vmlinux 0xe524bc17 pci_bus_add_devices +EXPORT_SYMBOL vmlinux 0xe52937e7 simple_readpage +EXPORT_SYMBOL vmlinux 0xe53cdee1 udplite_prot +EXPORT_SYMBOL vmlinux 0xe5405ade bio_copy_user +EXPORT_SYMBOL vmlinux 0xe55de3ad bdi_register +EXPORT_SYMBOL vmlinux 0xe57878a1 in6_pton +EXPORT_SYMBOL vmlinux 0xe5844107 cpu_present_map +EXPORT_SYMBOL vmlinux 0xe5867808 dlci_ioctl_set +EXPORT_SYMBOL vmlinux 0xe5b49b99 dev_kfree_skb_any +EXPORT_SYMBOL vmlinux 0xe5b56900 netdev_boot_setup_check +EXPORT_SYMBOL vmlinux 0xe5c78a99 do_blank_screen +EXPORT_SYMBOL vmlinux 0xe5d1b80c end_page_writeback +EXPORT_SYMBOL vmlinux 0xe5e988c5 dev_change_flags +EXPORT_SYMBOL vmlinux 0xe5ed5467 xfrm_policy_walk_init +EXPORT_SYMBOL vmlinux 0xe6021734 d_lookup +EXPORT_SYMBOL vmlinux 0xe6420566 generic_write_checks +EXPORT_SYMBOL vmlinux 0xe64a9c85 journal_get_write_access +EXPORT_SYMBOL vmlinux 0xe65b1784 skb_copy_and_csum_datagram_iovec +EXPORT_SYMBOL vmlinux 0xe6785027 __blk_run_queue +EXPORT_SYMBOL vmlinux 0xe68f0283 simple_transaction_release +EXPORT_SYMBOL vmlinux 0xe6b791db elevator_exit +EXPORT_SYMBOL vmlinux 0xe6c550b3 kernel_getsockname +EXPORT_SYMBOL vmlinux 0xe6d86268 compute_creds +EXPORT_SYMBOL vmlinux 0xe6ebc016 key_create_or_update +EXPORT_SYMBOL vmlinux 0xe6fbe430 can_do_mlock +EXPORT_SYMBOL vmlinux 0xe716baed acpi_unregister_ioapic +EXPORT_SYMBOL vmlinux 0xe73172ab ethtool_op_set_ufo +EXPORT_SYMBOL vmlinux 0xe760d06d llc_add_pack +EXPORT_SYMBOL vmlinux 0xe77e15bf qdisc_create_dflt +EXPORT_SYMBOL vmlinux 0xe78a6228 sync_page_range +EXPORT_SYMBOL vmlinux 0xe78ebafe wake_up_process +EXPORT_SYMBOL vmlinux 0xe7a200c0 key_negate_and_link +EXPORT_SYMBOL vmlinux 0xe7a389d4 journal_start +EXPORT_SYMBOL vmlinux 0xe7aa12a7 scsi_release_buffers +EXPORT_SYMBOL vmlinux 0xe7cf64f7 acpi_bus_get_status +EXPORT_SYMBOL vmlinux 0xe7d2aca1 security_sk_classify_flow +EXPORT_SYMBOL vmlinux 0xe7d4daac seq_list_next +EXPORT_SYMBOL vmlinux 0xe7db93fb dma_async_memcpy_buf_to_buf +EXPORT_SYMBOL vmlinux 0xe7dd1c37 generic_make_request +EXPORT_SYMBOL vmlinux 0xe7e64644 register_filesystem +EXPORT_SYMBOL vmlinux 0xe7e9f573 elv_add_request +EXPORT_SYMBOL vmlinux 0xe7fbbe71 del_gendisk +EXPORT_SYMBOL vmlinux 0xe80ce219 sysctl_tcp_dma_copybreak +EXPORT_SYMBOL vmlinux 0xe810ffa2 dst_release +EXPORT_SYMBOL vmlinux 0xe811d2b4 tcp_v4_conn_request +EXPORT_SYMBOL vmlinux 0xe83c9296 nf_unregister_hook +EXPORT_SYMBOL vmlinux 0xe858e15a scsi_rescan_device +EXPORT_SYMBOL vmlinux 0xe86022cc blk_queue_resize_tags +EXPORT_SYMBOL vmlinux 0xe8694a50 neigh_sysctl_register +EXPORT_SYMBOL vmlinux 0xe87a830b bio_get_nr_vecs +EXPORT_SYMBOL vmlinux 0xe880faa5 filemap_write_and_wait +EXPORT_SYMBOL vmlinux 0xe894d7a8 deactivate_super +EXPORT_SYMBOL vmlinux 0xe8a3605f acpi_processor_set_thermal_limit +EXPORT_SYMBOL vmlinux 0xe8a70f24 scsi_allocate_command +EXPORT_SYMBOL vmlinux 0xe8b0111d vfs_symlink +EXPORT_SYMBOL vmlinux 0xe8cd902e hweight16 +EXPORT_SYMBOL vmlinux 0xe8cfd327 skb_dma_map +EXPORT_SYMBOL vmlinux 0xe8e20709 pci_back_from_sleep +EXPORT_SYMBOL vmlinux 0xe9078613 nf_log_packet +EXPORT_SYMBOL vmlinux 0xe910b532 del_timer_sync +EXPORT_SYMBOL vmlinux 0xe914e41e strcpy +EXPORT_SYMBOL vmlinux 0xe915e90e dcache_dir_close +EXPORT_SYMBOL vmlinux 0xe935dbb9 zero_fill_bio +EXPORT_SYMBOL vmlinux 0xe942b27c netdev_state_change +EXPORT_SYMBOL vmlinux 0xe9456a5a sysctl_xfrm_aevent_rseqth +EXPORT_SYMBOL vmlinux 0xe947d8f9 xfrm_dst_ifdown +EXPORT_SYMBOL vmlinux 0xe968fea9 pnp_unregister_card_driver +EXPORT_SYMBOL vmlinux 0xe96ab06c km_query +EXPORT_SYMBOL vmlinux 0xe97bada9 kthread_create +EXPORT_SYMBOL vmlinux 0xe997667b wrmsr_on_cpu +EXPORT_SYMBOL vmlinux 0xe9b51f0b iunique +EXPORT_SYMBOL vmlinux 0xe9cbd7c3 devm_ioport_unmap +EXPORT_SYMBOL vmlinux 0xe9e10196 netlink_change_ngroups +EXPORT_SYMBOL vmlinux 0xe9e76158 alloc_trdev +EXPORT_SYMBOL vmlinux 0xe9f494c7 unlock_page +EXPORT_SYMBOL vmlinux 0xea10212a int_to_scsilun +EXPORT_SYMBOL vmlinux 0xea10655a __bitmap_intersects +EXPORT_SYMBOL vmlinux 0xea2ab153 blk_verify_command +EXPORT_SYMBOL vmlinux 0xea2d33a2 radix_tree_gang_lookup_slot +EXPORT_SYMBOL vmlinux 0xea3045bd eth_header_cache_update +EXPORT_SYMBOL vmlinux 0xea5491eb framebuffer_release +EXPORT_SYMBOL vmlinux 0xea6fcdaa genl_unregister_family +EXPORT_SYMBOL vmlinux 0xea7987f1 key_update +EXPORT_SYMBOL vmlinux 0xea858cb5 radix_tree_gang_lookup_tag +EXPORT_SYMBOL vmlinux 0xea995885 udp_lib_get_port +EXPORT_SYMBOL vmlinux 0xead13794 pcibios_set_irq_routing +EXPORT_SYMBOL vmlinux 0xeae1b26a __find_get_block +EXPORT_SYMBOL vmlinux 0xeae3dfd6 __const_udelay +EXPORT_SYMBOL vmlinux 0xeae7e726 elv_dispatch_add_tail +EXPORT_SYMBOL vmlinux 0xeb012f6a pv_cpu_ops +EXPORT_SYMBOL vmlinux 0xeb03e861 tr_type_trans +EXPORT_SYMBOL vmlinux 0xeb1fabf6 interruptible_sleep_on +EXPORT_SYMBOL vmlinux 0xeb395084 param_get_invbool +EXPORT_SYMBOL vmlinux 0xeb505650 sk_alloc +EXPORT_SYMBOL vmlinux 0xeb58bdf6 file_permission +EXPORT_SYMBOL vmlinux 0xeb7a11cf blk_register_region +EXPORT_SYMBOL vmlinux 0xeb8bfcdc init_net +EXPORT_SYMBOL vmlinux 0xeb8f54b3 strstrip +EXPORT_SYMBOL vmlinux 0xebd273a6 strict_strtoull +EXPORT_SYMBOL vmlinux 0xebea4b1f jbd2_journal_lock_updates +EXPORT_SYMBOL vmlinux 0xec32284a dev_queue_xmit +EXPORT_SYMBOL vmlinux 0xec3dacbe pci_enable_wake +EXPORT_SYMBOL vmlinux 0xec794ba0 __send_remote_softirq +EXPORT_SYMBOL vmlinux 0xec7a34cc __dev_remove_pack +EXPORT_SYMBOL vmlinux 0xec7f3d30 sock_no_mmap +EXPORT_SYMBOL vmlinux 0xec9ee784 page_put_link +EXPORT_SYMBOL vmlinux 0xecad24bc rtnl_set_sk_err +EXPORT_SYMBOL vmlinux 0xecde1418 _spin_lock_irq +EXPORT_SYMBOL vmlinux 0xecde8227 pci_dev_driver +EXPORT_SYMBOL vmlinux 0xece90b92 dev_alloc_skb +EXPORT_SYMBOL vmlinux 0xecfa16f2 jbd2_journal_init_jbd_inode +EXPORT_SYMBOL vmlinux 0xed5c20c1 sync_mapping_buffers +EXPORT_SYMBOL vmlinux 0xed633abc pv_irq_ops +EXPORT_SYMBOL vmlinux 0xed7c7865 pci_get_subsys +EXPORT_SYMBOL vmlinux 0xed8541ce __netif_schedule +EXPORT_SYMBOL vmlinux 0xedad6284 inode_change_ok +EXPORT_SYMBOL vmlinux 0xedbaee5e nla_strcmp +EXPORT_SYMBOL vmlinux 0xedc03953 iounmap +EXPORT_SYMBOL vmlinux 0xedd14538 param_get_uint +EXPORT_SYMBOL vmlinux 0xedda7993 gnet_stats_copy_rate_est +EXPORT_SYMBOL vmlinux 0xede9ddc6 tcp_v4_connect +EXPORT_SYMBOL vmlinux 0xee1f7c9b kernel_sendpage +EXPORT_SYMBOL vmlinux 0xee21f0a2 ethtool_op_get_tso +EXPORT_SYMBOL vmlinux 0xee2d0fc7 _local_bh_enable +EXPORT_SYMBOL vmlinux 0xee535f9e init_file +EXPORT_SYMBOL vmlinux 0xee53d6e7 dquot_alloc_inode +EXPORT_SYMBOL vmlinux 0xee5b046a __wait_on_buffer +EXPORT_SYMBOL vmlinux 0xee7eb9e1 pnp_platform_devices +EXPORT_SYMBOL vmlinux 0xeea9dbaf bitmap_bitremap +EXPORT_SYMBOL vmlinux 0xeeb1717c param_array_get +EXPORT_SYMBOL vmlinux 0xeedfbeed tcp_ioctl +EXPORT_SYMBOL vmlinux 0xeee21e2e generic_file_open +EXPORT_SYMBOL vmlinux 0xef1f6f16 mapping_tagged +EXPORT_SYMBOL vmlinux 0xef36f5e4 lock_super +EXPORT_SYMBOL vmlinux 0xef3bd862 mca_find_unused_adapter +EXPORT_SYMBOL vmlinux 0xef8a1312 pci_enable_bridges +EXPORT_SYMBOL vmlinux 0xef9aedfc boot_option_idle_override +EXPORT_SYMBOL vmlinux 0xefabc5ec inode_needs_sync +EXPORT_SYMBOL vmlinux 0xefd41a3d wireless_send_event +EXPORT_SYMBOL vmlinux 0xefdd70ce security_secid_to_secctx +EXPORT_SYMBOL vmlinux 0xefe099c3 acpi_get_event_status +EXPORT_SYMBOL vmlinux 0xeff14be9 ioremap_cache +EXPORT_SYMBOL vmlinux 0xf0009fee put_pages_list +EXPORT_SYMBOL vmlinux 0xf02e8ddd page_follow_link_light +EXPORT_SYMBOL vmlinux 0xf0301279 inode_sub_bytes +EXPORT_SYMBOL vmlinux 0xf0528a38 generic_block_fiemap +EXPORT_SYMBOL vmlinux 0xf065f629 ioread16be +EXPORT_SYMBOL vmlinux 0xf090e3fa sock_rfree +EXPORT_SYMBOL vmlinux 0xf0b57c68 param_set_long +EXPORT_SYMBOL vmlinux 0xf0f1246c kvasprintf +EXPORT_SYMBOL vmlinux 0xf0f83b79 __bread +EXPORT_SYMBOL vmlinux 0xf10de535 ioread8 +EXPORT_SYMBOL vmlinux 0xf11543ff find_first_zero_bit +EXPORT_SYMBOL vmlinux 0xf1225a29 __dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0xf1244dd3 uart_add_one_port +EXPORT_SYMBOL vmlinux 0xf162fe2d sysctl_xfrm_aevent_etime +EXPORT_SYMBOL vmlinux 0xf16615ac skb_copy_and_csum_dev +EXPORT_SYMBOL vmlinux 0xf174ed48 acquire_console_sem +EXPORT_SYMBOL vmlinux 0xf195c682 fb_invert_cmaps +EXPORT_SYMBOL vmlinux 0xf1d97bf1 generic_file_llseek +EXPORT_SYMBOL vmlinux 0xf1deabf2 div64_u64 +EXPORT_SYMBOL vmlinux 0xf1e807a3 scsi_adjust_queue_depth +EXPORT_SYMBOL vmlinux 0xf1e950f5 kobject_set_name +EXPORT_SYMBOL vmlinux 0xf1e98c74 avenrun +EXPORT_SYMBOL vmlinux 0xf20dabd8 free_irq +EXPORT_SYMBOL vmlinux 0xf218110d dma_set_mask +EXPORT_SYMBOL vmlinux 0xf22104d7 vmap +EXPORT_SYMBOL vmlinux 0xf22b9f51 ip_ct_attach +EXPORT_SYMBOL vmlinux 0xf246de13 tcf_hash_destroy +EXPORT_SYMBOL vmlinux 0xf24be385 input_open_device +EXPORT_SYMBOL vmlinux 0xf2876b35 blk_queue_free_tags +EXPORT_SYMBOL vmlinux 0xf2884663 xfrm_state_check_expire +EXPORT_SYMBOL vmlinux 0xf2997713 tty_termios_hw_change +EXPORT_SYMBOL vmlinux 0xf2a6d2bf xfrm_policy_count +EXPORT_SYMBOL vmlinux 0xf2afa595 param_get_charp +EXPORT_SYMBOL vmlinux 0xf2e74040 mca_set_adapter_name +EXPORT_SYMBOL vmlinux 0xf313da4e sha_transform +EXPORT_SYMBOL vmlinux 0xf3341268 __clear_user +EXPORT_SYMBOL vmlinux 0xf338d4c3 netlink_unregister_notifier +EXPORT_SYMBOL vmlinux 0xf346231f seq_list_start_head +EXPORT_SYMBOL vmlinux 0xf3562a53 pci_bus_read_config_dword +EXPORT_SYMBOL vmlinux 0xf39bf4d9 put_cmsg +EXPORT_SYMBOL vmlinux 0xf3b1c73f jbd2_journal_unlock_updates +EXPORT_SYMBOL vmlinux 0xf3bdeaa6 sock_create +EXPORT_SYMBOL vmlinux 0xf3bf0bce __bitmap_complement +EXPORT_SYMBOL vmlinux 0xf3c0c2ba qdisc_watchdog_init +EXPORT_SYMBOL vmlinux 0xf3ca2695 dev_get_by_name +EXPORT_SYMBOL vmlinux 0xf3d14795 notify_change +EXPORT_SYMBOL vmlinux 0xf3f5f8bd pci_do_scan_bus +EXPORT_SYMBOL vmlinux 0xf40a37b5 shrink_dcache_parent +EXPORT_SYMBOL vmlinux 0xf40e54ba journal_get_create_access +EXPORT_SYMBOL vmlinux 0xf40fdd8a pci_fixup_device +EXPORT_SYMBOL vmlinux 0xf42ba21b cdrom_ioctl +EXPORT_SYMBOL vmlinux 0xf441ac43 ioread8_rep +EXPORT_SYMBOL vmlinux 0xf488eced ps2_handle_ack +EXPORT_SYMBOL vmlinux 0xf48a2c4c MCA_bus +EXPORT_SYMBOL vmlinux 0xf4a10d38 get_unmapped_area +EXPORT_SYMBOL vmlinux 0xf4a5c213 avail_to_resrv_perfctr_nmi_bit +EXPORT_SYMBOL vmlinux 0xf4ae9d51 ida_pre_get +EXPORT_SYMBOL vmlinux 0xf4c1763e blk_queue_max_phys_segments +EXPORT_SYMBOL vmlinux 0xf4c9fc4c end_buffer_write_sync +EXPORT_SYMBOL vmlinux 0xf4d407c6 dev_driver_string +EXPORT_SYMBOL vmlinux 0xf4e85f71 d_namespace_path +EXPORT_SYMBOL vmlinux 0xf4f14de6 rtnl_trylock +EXPORT_SYMBOL vmlinux 0xf4f481a1 scsi_print_command +EXPORT_SYMBOL vmlinux 0xf4f52f93 dqstats +EXPORT_SYMBOL vmlinux 0xf4f7fefa tty_hung_up_p +EXPORT_SYMBOL vmlinux 0xf502d273 acpi_get_current_resources +EXPORT_SYMBOL vmlinux 0xf5061101 neigh_ifdown +EXPORT_SYMBOL vmlinux 0xf50c2777 proc_doulongvec_ms_jiffies_minmax +EXPORT_SYMBOL vmlinux 0xf51921ed dma_release_from_coherent +EXPORT_SYMBOL vmlinux 0xf51ae235 touch_nmi_watchdog +EXPORT_SYMBOL vmlinux 0xf53d4c26 qdisc_class_hash_destroy +EXPORT_SYMBOL vmlinux 0xf553d7c5 call_usermodehelper_exec +EXPORT_SYMBOL vmlinux 0xf58db95b simple_release_fs +EXPORT_SYMBOL vmlinux 0xf5a807cf ioctl_by_bdev +EXPORT_SYMBOL vmlinux 0xf5c05914 generic_segment_checks +EXPORT_SYMBOL vmlinux 0xf5ce9811 tcp_memory_allocated +EXPORT_SYMBOL vmlinux 0xf5d2600f key_instantiate_and_link +EXPORT_SYMBOL vmlinux 0xf61271e1 xfrm_state_unregister_afinfo +EXPORT_SYMBOL vmlinux 0xf63e49e0 kernel_connect +EXPORT_SYMBOL vmlinux 0xf64ef54e fb_blank +EXPORT_SYMBOL vmlinux 0xf68b0e1a dev_load +EXPORT_SYMBOL vmlinux 0xf68f4764 blk_rq_unmap_user +EXPORT_SYMBOL vmlinux 0xf6ad523e dquot_commit +EXPORT_SYMBOL vmlinux 0xf6bb4729 color_table +EXPORT_SYMBOL vmlinux 0xf6ebc03b net_ratelimit +EXPORT_SYMBOL vmlinux 0xf7137f5e vfs_quota_off +EXPORT_SYMBOL vmlinux 0xf737a85d xfrm_unregister_type +EXPORT_SYMBOL vmlinux 0xf737cb2d scsi_unregister +EXPORT_SYMBOL vmlinux 0xf7623914 radix_tree_tag_clear +EXPORT_SYMBOL vmlinux 0xf786ef5e idr_init +EXPORT_SYMBOL vmlinux 0xf7879e5c mpage_readpage +EXPORT_SYMBOL vmlinux 0xf78d04ab netlink_register_notifier +EXPORT_SYMBOL vmlinux 0xf7910386 proc_net_netfilter +EXPORT_SYMBOL vmlinux 0xf7b70f2d alloc_file +EXPORT_SYMBOL vmlinux 0xf811e69d scsi_eh_flush_done_q +EXPORT_SYMBOL vmlinux 0xf82abc1d isa_dma_bridge_buggy +EXPORT_SYMBOL vmlinux 0xf82e3d47 acpi_initialize_objects +EXPORT_SYMBOL vmlinux 0xf82f1109 utf8_wctomb +EXPORT_SYMBOL vmlinux 0xf8515f94 tcp_child_process +EXPORT_SYMBOL vmlinux 0xf8814f73 rb_last +EXPORT_SYMBOL vmlinux 0xf88e0ee2 acpi_get_table_header +EXPORT_SYMBOL vmlinux 0xf890fe7f pm_idle +EXPORT_SYMBOL vmlinux 0xf89edaa8 sb_set_blocksize +EXPORT_SYMBOL vmlinux 0xf8a72716 iget_locked +EXPORT_SYMBOL vmlinux 0xf8aa47ae mutex_lock_killable +EXPORT_SYMBOL vmlinux 0xf8b30e93 mempool_create +EXPORT_SYMBOL vmlinux 0xf8b939ff lock_may_read +EXPORT_SYMBOL vmlinux 0xf8c4c473 jbd2_journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0xf8cf9ee5 abort_exclusive_wait +EXPORT_SYMBOL vmlinux 0xf91fe22c __nla_put +EXPORT_SYMBOL vmlinux 0xf9213929 block_write_full_page +EXPORT_SYMBOL vmlinux 0xf9256a3d devm_request_irq +EXPORT_SYMBOL vmlinux 0xf929a848 br_handle_frame_hook +EXPORT_SYMBOL vmlinux 0xf9a482f9 msleep +EXPORT_SYMBOL vmlinux 0xf9b575d0 simple_sync_file +EXPORT_SYMBOL vmlinux 0xf9bd9116 journal_start_commit +EXPORT_SYMBOL vmlinux 0xf9cc0539 pci_bus_read_config_word +EXPORT_SYMBOL vmlinux 0xf9dedb80 handle_sysrq +EXPORT_SYMBOL vmlinux 0xf9fb9c6d acpi_unlock_ac_dir +EXPORT_SYMBOL vmlinux 0xfa0564fc __wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0xfa214fcd get_user_pages +EXPORT_SYMBOL vmlinux 0xfa4946e2 netlink_broadcast +EXPORT_SYMBOL vmlinux 0xfa6e79ed sk_stream_kill_queues +EXPORT_SYMBOL vmlinux 0xfa7efd48 ipv4_specific +EXPORT_SYMBOL vmlinux 0xfabfe05a input_flush_device +EXPORT_SYMBOL vmlinux 0xfaf98462 bitrev32 +EXPORT_SYMBOL vmlinux 0xfb038d63 cpu_mask_all +EXPORT_SYMBOL vmlinux 0xfb0443fb acpi_get_parent +EXPORT_SYMBOL vmlinux 0xfb05c41a d_instantiate +EXPORT_SYMBOL vmlinux 0xfb0cf2e9 touch_all_softlockup_watchdogs +EXPORT_SYMBOL vmlinux 0xfb0d64c8 blk_queue_segment_boundary +EXPORT_SYMBOL vmlinux 0xfb3423c0 kernel_accept +EXPORT_SYMBOL vmlinux 0xfb6af58d recalc_sigpending +EXPORT_SYMBOL vmlinux 0xfb79ab76 unregister_sysctl_table +EXPORT_SYMBOL vmlinux 0xfba0c2e0 llc_sap_list_lock +EXPORT_SYMBOL vmlinux 0xfba4c8e0 set_pages_wb +EXPORT_SYMBOL vmlinux 0xfbf92453 param_get_bool +EXPORT_SYMBOL vmlinux 0xfc02b7ad sysctl_tcp_wmem +EXPORT_SYMBOL vmlinux 0xfc2a4b7a scsi_add_host +EXPORT_SYMBOL vmlinux 0xfc309c3e cancel_delayed_work_sync +EXPORT_SYMBOL vmlinux 0xfc39e32f ioport_unmap +EXPORT_SYMBOL vmlinux 0xfcaa04a0 out_of_line_wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0xfcad226c default_unplug_io_fn +EXPORT_SYMBOL vmlinux 0xfcda63a3 node_states +EXPORT_SYMBOL vmlinux 0xfcdd8cf6 param_get_ushort +EXPORT_SYMBOL vmlinux 0xfcec0987 enable_irq +EXPORT_SYMBOL vmlinux 0xfcfa03ff fb_videomode_to_modelist +EXPORT_SYMBOL vmlinux 0xfd2e07a6 filemap_flush +EXPORT_SYMBOL vmlinux 0xfd518be7 end_request +EXPORT_SYMBOL vmlinux 0xfd608e4d devm_iounmap +EXPORT_SYMBOL vmlinux 0xfd767879 kmem_ptr_validate +EXPORT_SYMBOL vmlinux 0xfd98879a rb_next +EXPORT_SYMBOL vmlinux 0xfdb9b629 ioread32be +EXPORT_SYMBOL vmlinux 0xfde2145a boot_tvec_bases +EXPORT_SYMBOL vmlinux 0xfde62c3e bfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0xfde77075 stop_tty +EXPORT_SYMBOL vmlinux 0xfde8c3e3 contig_page_data +EXPORT_SYMBOL vmlinux 0xfdfc0b3b fiemap_fill_next_extent +EXPORT_SYMBOL vmlinux 0xfe336351 try_to_release_page +EXPORT_SYMBOL vmlinux 0xfe451dea ethtool_op_set_tx_ipv6_csum +EXPORT_SYMBOL vmlinux 0xfe5102fa skb_checksum_help +EXPORT_SYMBOL vmlinux 0xfe5d4bb2 sys_tz +EXPORT_SYMBOL vmlinux 0xfe769456 unregister_netdevice_notifier +EXPORT_SYMBOL vmlinux 0xfe793c0f pnp_register_driver +EXPORT_SYMBOL vmlinux 0xfe7c4287 nr_cpu_ids +EXPORT_SYMBOL vmlinux 0xfe907c7f input_release_device +EXPORT_SYMBOL vmlinux 0xfe910601 mmc_alloc_host +EXPORT_SYMBOL vmlinux 0xfec17daf inet_shutdown +EXPORT_SYMBOL vmlinux 0xfec3c2f2 bcd2bin +EXPORT_SYMBOL vmlinux 0xfedd35fc console_suspend_enabled +EXPORT_SYMBOL vmlinux 0xfeee8aad simple_rmdir +EXPORT_SYMBOL vmlinux 0xfef96e23 __scsi_print_command +EXPORT_SYMBOL vmlinux 0xff1b4294 vfs_set_dqblk +EXPORT_SYMBOL vmlinux 0xff1e9dd8 seq_list_start +EXPORT_SYMBOL vmlinux 0xff2cbd61 vfs_writev +EXPORT_SYMBOL vmlinux 0xff2d5f7d dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0xff472595 set_anon_super +EXPORT_SYMBOL vmlinux 0xff5cdf26 fd_install +EXPORT_SYMBOL vmlinux 0xff6508ec iw_handler_set_spy +EXPORT_SYMBOL vmlinux 0xff6878cf fb_default_cmap +EXPORT_SYMBOL vmlinux 0xff708fd3 mempool_destroy +EXPORT_SYMBOL vmlinux 0xff76dbed d_instantiate_unique +EXPORT_SYMBOL vmlinux 0xff9b7377 jbd2_journal_init_inode +EXPORT_SYMBOL vmlinux 0xff9ca065 fb_edid_to_monspecs +EXPORT_SYMBOL vmlinux 0xffa83cf3 mb_cache_shrink +EXPORT_SYMBOL vmlinux 0xffaa25b7 nla_reserve +EXPORT_SYMBOL vmlinux 0xffafdc5c _read_unlock_irq +EXPORT_SYMBOL vmlinux 0xffb83c2d scsi_calculate_bounce_limit +EXPORT_SYMBOL vmlinux 0xffc453b3 pnp_register_card_driver +EXPORT_SYMBOL vmlinux 0xffd202f2 simple_empty +EXPORT_SYMBOL vmlinux 0xffd5a395 default_wake_function +EXPORT_SYMBOL vmlinux 0xffdb82bc sg_free_table +EXPORT_SYMBOL_GPL arch/x86/kernel/microcode 0xdf66ca81 ucode_cpu_info +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x00aaf935 kvm_disable_tdp +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x03b3209e kvm_mmu_page_fault +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x03cd0cba kvm_mmu_invlpg +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x063c6a9d kvm_cpu_has_interrupt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x07255c62 kvm_get_msr_common +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x094ac8f4 kvm_get_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0a08c19b kvm_vcpu_uninit +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0b970382 kvm_put_guest_fpu +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0df4e14f __kvm_set_memory_region +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0e3aace0 kvm_set_cr0 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1209b842 kvm_clear_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x12d1b23b kvm_release_pfn_clean +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x165516fd emulator_read_std +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x19752223 kvm_is_visible_gfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1e1de760 kvm_lapic_get_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1e330d1c kvm_lmsw +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1e4580bb kvm_release_pfn_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x21d83b94 kvm_emulate_halt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x2322e039 kvm_set_pfn_accessed +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x24bb0a8c kvm_set_apic_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x27046576 kvm_exit +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x29511341 emulate_instruction +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x2a9d04ae kvm_emulate_cpuid +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x2b5cb8db kvm_queue_exception_e +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x2c26b21d kvm_lapic_get_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x317f9e6b kvm_enable_efer_bits +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x32ee6d74 kvm_queue_exception +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x331ed402 kvm_emulate_pio_string +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x33d9fd3c kvm_write_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x39808721 kvm_mmu_unprotect_page_virt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x3b768e4f kvm_set_memory_region +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x3e5c9824 kvm_set_page_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x3f133caa kvm_lapic_reset +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x41900f78 kvm_inject_pending_timer_irqs +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x41eb35e9 kvm_load_guest_fpu +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x4390f330 kvm_get_apic_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x492dc965 kvm_get_cs_db_l_bits +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x4a7cbe69 is_error_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x537d0fcf kvm_set_cr3 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x541632d4 is_error_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x578032ef kvm_read_guest +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x599086dd kvm_handle_fault_on_reboot +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x5f32bde4 kvm_put_kvm +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x5f34814e kvm_emulate_pio +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x626af93e fx_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x65561589 kvm_emulate_hypercall +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x682ed30c kvm_get_kvm +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x6e8e1f28 kvm_lapic_set_tpr +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x7347e5cc kvm_vcpu_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x735f5d89 kvm_set_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x79d2e226 emulator_write_emulated +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x874e9cd1 kvm_mmu_load +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x88a29df3 kvm_x86_ops +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8a5528c9 kvm_create_lapic +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8c8b8065 gfn_to_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8ce4f3ab kvm_enable_tdp +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8e7f9b47 segment_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x90fc512e kvm_task_switch +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x973be6fa kvm_resched +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x9c725b91 kvm_timer_intr_post +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa2e9ebac gfn_to_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa361bc65 kvm_set_pfn_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa53d7a5d gfn_to_hva +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xaa5d887e kvm_get_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb30d4bb4 kvm_set_msr_common +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb3a210df kvm_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb454f69a kvm_lapic_enabled +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb5db6766 kvm_cpu_get_interrupt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb66e33f0 kvm_inject_nmi +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbd377dc9 kvm_mmu_set_nonpresent_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbd94103b kvm_mmu_set_base_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbef642be kvm_report_emulation_failure +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xc9c9458a kvm_lapic_find_highest_irr +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd0b2727a kvm_mmu_set_mask_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd182a784 load_pdptrs +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd296def9 kvm_is_error_hva +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xdd30d774 kvm_set_cr4 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xe610d239 kvm_read_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xe8b8c584 kvm_vcpu_cache +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf6566baa kvm_release_page_clean +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf72f4c80 kvm_clear_guest +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xfac43d31 kvm_mmu_reset_context +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xfe6d3c6c kvm_release_page_dirty +EXPORT_SYMBOL_GPL crypto/aes_generic 0x1381bf2d crypto_ft_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x22894d94 crypto_il_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5f943003 crypto_it_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5fe743de crypto_aes_expand_key +EXPORT_SYMBOL_GPL crypto/aes_generic 0x6e9cc2ba crypto_fl_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x8a2b5ccc crypto_aes_set_key +EXPORT_SYMBOL_GPL crypto/async_tx/async_memcpy 0x0df4e0d5 async_memcpy +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x26fae8ee async_trigger_callback +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x297b5343 __async_tx_find_channel +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x491cdbfd async_tx_run_dependencies +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x6b4a6db2 async_tx_issue_pending_all +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x97eaff75 dma_wait_for_async_tx +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0xbda59e88 async_tx_submit +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0xec13bae7 async_tx_quiesce +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0x9ea6faa3 async_xor +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0xff9ebc4f async_xor_zero_sum +EXPORT_SYMBOL_GPL crypto/des_generic 0xcfd9a2c0 des_ekey +EXPORT_SYMBOL_GPL crypto/twofish_common 0x192200bc twofish_setkey +EXPORT_SYMBOL_GPL drivers/acpi/sbshc 0x0ad5c33f acpi_smbus_register_callback +EXPORT_SYMBOL_GPL drivers/acpi/sbshc 0x158c2ad0 acpi_smbus_unregister_callback +EXPORT_SYMBOL_GPL drivers/acpi/sbshc 0x526b867a acpi_smbus_read +EXPORT_SYMBOL_GPL drivers/acpi/sbshc 0xb3d5e527 acpi_smbus_write +EXPORT_SYMBOL_GPL drivers/ata/pata_platform 0x79a46947 __pata_platform_remove +EXPORT_SYMBOL_GPL drivers/ata/pata_platform 0x829b8567 __pata_platform_probe +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x02ff9464 cfag12864b_isinited +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x0ecb2e5d cfag12864b_disable +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x305dc3c6 cfag12864b_isenabled +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x3389f926 cfag12864b_enable +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x9522a342 cfag12864b_getrate +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0xc48e9d95 cfag12864b_buffer +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x14102f23 ks0108_displaystate +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x48a70518 ks0108_writedata +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x4f506333 ks0108_startline +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x6edae968 ks0108_isinited +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xbf4774db ks0108_writecontrol +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xedde6df2 ks0108_page +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xfee8ef7b ks0108_address +EXPORT_SYMBOL_GPL drivers/char/agp/agpgart 0x4480ac4d agp_remove_bridge +EXPORT_SYMBOL_GPL drivers/char/agp/agpgart 0x6b25e290 agp_add_bridge +EXPORT_SYMBOL_GPL drivers/char/agp/agpgart 0xd6feefa5 agp_num_entries +EXPORT_SYMBOL_GPL drivers/char/agp/agpgart 0xe089cfcc agp_memory_reserved +EXPORT_SYMBOL_GPL drivers/char/scx200_gpio 0x783acecc scx200_gpio_ops +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x168b4942 tpm_show_enabled +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x22463f67 tpm_read +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x241f43f8 tpm_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x3aa62734 tpm_show_pcrs +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x3c37d1c4 tpm_show_caps_1_2 +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x3f2b2001 tpm_get_timeouts +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x4434b8c1 tpm_write +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x651b035a tpm_register_hardware +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x7274cdd0 tpm_show_caps +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x7d7600fb tpm_remove_hardware +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x852d090e tpm_show_pubek +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x86095995 tpm_store_cancel +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x8a8ce59d tpm_pm_resume +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x90ec1341 tpm_show_owned +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x96cc88ab tpm_dev_vendor_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x9c580361 tpm_continue_selftest +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xa68f2bc7 tpm_show_active +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xabaadc42 tpm_gen_interrupt +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xc45536ae tpm_calc_ordinal_duration +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xcd5e1c70 tpm_dev_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xddae67ae tpm_show_temp_deactivated +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xe921540c tpm_open +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xf3cd8307 tpm_pm_suspend +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm_bios 0x7e84ef13 tpm_bios_log_teardown +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm_bios 0xe59865a3 tpm_bios_log_setup +EXPORT_SYMBOL_GPL drivers/connector/cn 0xb10d55bc cn_netlink_send +EXPORT_SYMBOL_GPL drivers/connector/cn 0xdf3c19ec cn_add_callback +EXPORT_SYMBOL_GPL drivers/connector/cn 0xff5a8cfe cn_del_callback +EXPORT_SYMBOL_GPL drivers/dca/dca 0x1576a45f register_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0x1812ca83 dca3_get_tag +EXPORT_SYMBOL_GPL drivers/dca/dca 0x22a08a8a dca_add_requester +EXPORT_SYMBOL_GPL drivers/dca/dca 0x2e471f01 dca_register_notify +EXPORT_SYMBOL_GPL drivers/dca/dca 0x31a2c8df dca_get_tag +EXPORT_SYMBOL_GPL drivers/dca/dca 0x7602c097 alloc_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0x7aec055a unregister_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0x8006c614 dca_unregister_notify +EXPORT_SYMBOL_GPL drivers/dca/dca 0x874aa944 free_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0xc5b74d04 dca_remove_requester +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x017e3073 edac_pci_create_generic_ctl +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x0606850a edac_device_del_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x0bec36cd edac_pci_add_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x17932390 edac_mc_handle_ce_no_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x287b7df4 edac_pci_handle_pe +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x2e463004 edac_pci_reset_delay_period +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x4dedc0ac edac_mc_del_mc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x4e250f7a edac_mc_free +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x548ea787 edac_pci_del_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x54f7f408 edac_pci_free_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x598e3e5d edac_device_alloc_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x629108e9 edac_mc_handle_ue_no_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x73f03cc6 edac_pci_handle_npe +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xa71a9bdd edac_mc_handle_ce +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xadb26746 edac_pci_alloc_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xb7e777d9 edac_pci_release_generic_ctl +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xc590ed0a edac_mc_alloc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xc715cde8 edac_mc_handle_ue +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xcf2229a0 edac_mc_add_mc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xd3a0e6d3 edac_device_handle_ce +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xe6459e9b edac_mc_find_csrow_by_page +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xf92e310a edac_device_handle_ue +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xfff1d739 edac_device_free_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xfffed20c edac_device_add_device +EXPORT_SYMBOL_GPL drivers/hid/hid 0x0c02e052 hidraw_report_event +EXPORT_SYMBOL_GPL drivers/hid/hid 0x0c902c66 hid_add_device +EXPORT_SYMBOL_GPL drivers/hid/hid 0x1145819b __hid_register_driver +EXPORT_SYMBOL_GPL drivers/hid/hid 0x1e6dcbb8 hidinput_report_event +EXPORT_SYMBOL_GPL drivers/hid/hid 0x3196ea65 hid_unregister_driver +EXPORT_SYMBOL_GPL drivers/hid/hid 0x3c541352 hidraw_disconnect +EXPORT_SYMBOL_GPL drivers/hid/hid 0x6e43dba5 hid_allocate_device +EXPORT_SYMBOL_GPL drivers/hid/hid 0x7c5cacbe hid_input_report +EXPORT_SYMBOL_GPL drivers/hid/hid 0x8fc56278 hidinput_disconnect +EXPORT_SYMBOL_GPL drivers/hid/hid 0x93f60169 hid_output_report +EXPORT_SYMBOL_GPL drivers/hid/hid 0xa59575bf hid_destroy_device +EXPORT_SYMBOL_GPL drivers/hid/hid 0xb2d04fd7 hid_connect +EXPORT_SYMBOL_GPL drivers/hid/hid 0xdd64dde8 hid_set_field +EXPORT_SYMBOL_GPL drivers/hid/hid 0xe0676b62 hidinput_find_field +EXPORT_SYMBOL_GPL drivers/hid/hid 0xe35d8155 hidraw_connect +EXPORT_SYMBOL_GPL drivers/hid/hid 0xe94ab390 hid_parse_report +EXPORT_SYMBOL_GPL drivers/hid/hid 0xf3de905f hidinput_connect +EXPORT_SYMBOL_GPL drivers/hid/hid 0xf5f0712e hid_report_raw_event +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x01fd453e usbhid_lookup_quirk +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x380233bb usbhid_submit_report +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x5734633c usbhid_set_leds +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0xfa2335bb hiddev_hid_event +EXPORT_SYMBOL_GPL drivers/i2c/busses/i2c-nforce2 0xce75d872 nforce2_smbus +EXPORT_SYMBOL_GPL drivers/i2c/i2c-core 0x0316cfc9 i2c_new_dummy +EXPORT_SYMBOL_GPL drivers/i2c/i2c-core 0x61c24ad6 i2c_new_probed_device +EXPORT_SYMBOL_GPL drivers/i2c/i2c-core 0xb2e708ea i2c_add_numbered_adapter +EXPORT_SYMBOL_GPL drivers/i2c/i2c-core 0xc11bd108 i2c_new_device +EXPORT_SYMBOL_GPL drivers/i2c/i2c-core 0xd367f3f8 i2c_unregister_device +EXPORT_SYMBOL_GPL drivers/i2c/i2c-core 0xf500b40a i2c_bus_type +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0x750a7972 hpsb_config_rom_ip1394_add +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0xb4a489a0 hpsb_config_rom_ip1394_remove +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0xec8d18cf hpsb_disable_irm +EXPORT_SYMBOL_GPL drivers/input/ff-memless 0x0e4e1894 input_ff_create_memless +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x1d01ce10 wm97xx_set_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x1f48d8e7 wm97xx_reg_write +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x20c62192 wm97xx_get_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x63bfc12c wm97xx_read_aux_adc +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x72e0f2f1 wm97xx_set_suspend_mode +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x7c4f41de wm97xx_reg_read +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x9e16e7a8 wm97xx_config_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xb53174ae wm97xx_unregister_mach_ops +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xda9919d1 wm97xx_register_mach_ops +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x3236dba0 led_classdev_register +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x47365dab led_classdev_unregister +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x7225b49f led_classdev_suspend +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x7deffa49 led_classdev_resume +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0x194f0a09 dm_set_device_limits +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0x5183525a dm_device_name +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0x698af4a6 dm_put +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0x9d0c3688 dm_send_uevents +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0xa8da9346 dm_noflush_suspending +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0xab538925 dm_disk +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0xb40ec24e dm_path_uevent +EXPORT_SYMBOL_GPL drivers/md/dm-multipath 0x374c8a96 dm_register_path_selector +EXPORT_SYMBOL_GPL drivers/md/dm-multipath 0xe0622e62 dm_unregister_path_selector +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x005d2af8 dm_rh_stop_recovery +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x0921eeaf dm_rh_recovery_in_flight +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x2178d897 dm_rh_get_region_size +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x24ae4e49 dm_rh_flush +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x34d69df6 dm_rh_get_region_key +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x496819f0 dm_rh_recovery_prepare +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x49a261e6 dm_region_hash_destroy +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x51697b43 dm_rh_bio_to_region +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x604f5f22 dm_rh_dirty_log +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x62d11348 dm_rh_inc_pending +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x65b88c0b dm_rh_get_state +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0x8ff31bfd dm_rh_update_states +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xad31a5ea dm_rh_region_context +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xb333698c dm_rh_recovery_end +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xbcfe5b5d dm_rh_delay +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xd0997448 dm_rh_region_to_sector +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xd4815174 dm_region_hash_create +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xd9d9a37b dm_rh_start_recovery +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xe25812fa dm_rh_recovery_start +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xe9b0c293 dm_rh_mark_nosync +EXPORT_SYMBOL_GPL drivers/md/dm-region-hash 0xfde3608a dm_rh_dec +EXPORT_SYMBOL_GPL drivers/md/md-mod 0x15f2f116 sync_page_io +EXPORT_SYMBOL_GPL drivers/md/md-mod 0x2e7f77ae md_new_event +EXPORT_SYMBOL_GPL drivers/md/md-mod 0x64288af4 md_allow_write +EXPORT_SYMBOL_GPL drivers/md/md-mod 0xeef445f2 md_do_sync +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x04662e0f ir_codes_fusionhdtv_mce +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x07e92917 ir_codes_avermedia_a16d +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x083661f9 ir_codes_avertv_303 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x088631b9 ir_codes_behold +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x1cb148f5 ir_extract_bits +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2456e513 ir_decode_pulsedistance +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2a4852cc ir_codes_dntv_live_dvb_t +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2af1a608 ir_codes_proteus_2309 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x3811daea ir_codes_manli +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x43c89ef4 ir_decode_biphase +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x45b08f68 ir_codes_pinnacle_grey +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4740e7a3 ir_codes_empty +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4beb7618 ir_codes_encore_enltv_fm53 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4ea698a2 ir_codes_purpletv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x55338dda ir_codes_pixelview_new +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x589cad50 ir_codes_apac_viewcomp +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x5db13554 ir_codes_encore_enltv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6606596a ir_rc5_timer_keyup +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6adc476d ir_codes_powercolor_real_angel +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6aefdbea ir_codes_npgtech +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6b87c69d ir_codes_iodata_bctv7e +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6d6511e7 ir_dump_samples +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6e2a1870 ir_codes_adstech_dvb_t_pci +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x7277973d ir_codes_pctv_sedna +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x75e89cc3 ir_codes_flydvb +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x76db72ee ir_input_init +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x772a30a2 ir_codes_nebula +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x7b38143b ir_codes_encore_enltv2 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x85d37490 ir_codes_dntv_live_dvbt_pro +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x89cc1189 ir_codes_winfast +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x902a3cd2 ir_codes_hauppauge_new +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x933d0bb3 ir_codes_msi_tvanywhere +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x9451e232 ir_codes_behold_columbus +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x96470cab ir_codes_cinergy +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb1f4eb35 ir_codes_avermedia_dvbt +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb50812de ir_codes_real_audio_220_32_keys +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb6cd4666 ir_codes_eztv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb9a46136 ir_input_nokey +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xbb08d146 ir_codes_msi_tvanywhere_plus +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xbdce6594 ir_codes_tt_1500 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc1fea0c1 ir_codes_pv951 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc42bd037 ir_codes_budget_ci_old +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc51b639f ir_input_keydown +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc6c5a7a1 ir_codes_em_terratec +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xcdf2859f ir_codes_avermedia_m135a +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd1e0258a ir_codes_flyvideo +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd55e6891 ir_codes_gotview7135 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd9c7f010 ir_codes_rc5_tv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xdaa041ad ir_codes_cinergy_1400 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xdfcf23df ir_codes_norwood +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xee2f5e0e ir_codes_pinnacle_pctv_hd +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf07533a1 ir_codes_videomate_tv_pvr +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf0fc9374 ir_codes_avermedia +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf2b421aa ir_codes_genius_tvgo_a11mce +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf4f7a4d6 ir_rc5_timer_end +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfa177653 ir_codes_pixelview +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfb981300 ir_codes_pinnacle_color +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfc54a5cd ir_codes_asus_pc39 +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x16c271de saa7146_unregister_extension +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x347f9a44 saa7146_pgtable_alloc +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x3adc40ca saa7146_vmalloc_build_pgtable +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x5c851743 saa7146_pgtable_build_single +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x78874abd saa7146_i2c_adapter_prepare +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x9d099f98 saa7146_pgtable_free +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x9d3aefd9 saa7146_wait_for_debi_done +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xa4db3a03 saa7146_vfree_destroy_pgtable +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xc98faf20 saa7146_devices_lock +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xcf683cf2 saa7146_devices +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xd1c28d4e saa7146_register_extension +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xe3cd9b5c saa7146_debug +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xfffce673 saa7146_setgpio +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x15570454 saa7146_stop_preview +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x22ea9117 saa7146_vv_init +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x573c89da saa7146_register_device +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x5ac5767f saa7146_unregister_device +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xaa002b79 saa7146_start_preview +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xef8d5b88 saa7146_set_hps_source_and_sync +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xf3ec9874 saa7146_vv_release +EXPORT_SYMBOL_GPL drivers/media/common/tuners/mt20xx 0xac42ab4b microtune_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/mxl5007t 0x6a7cfbbb mxl5007t_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda18271 0x3e04cdd8 tda18271_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda827x 0x7bfe7b7b tda827x_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda8290 0xa136e9c4 tda829x_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda8290 0xa9897fa9 tda829x_probe +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda9887 0x635a97a3 tda9887_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5761 0x775b5c4c tea5761_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5761 0xd1b351a6 tea5761_autodetection +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5767 0x0c8af467 tea5767_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5767 0x9ad0ebda tea5767_autodetection +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tuner-simple 0xc58ba305 simple_tuner_attach +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x418eda8e ttpci_budget_init_hooks +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x49fdd9df ttpci_budget_set_video_port +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x72f8094f ttpci_budget_debiread +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x7948c222 budget_debug +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x92a1e362 ttpci_budget_irq10_handler +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xe2b7ff74 ttpci_budget_init +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xe9dcc982 ttpci_budget_debiwrite +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xf0ef2e07 ttpci_budget_deinit +EXPORT_SYMBOL_GPL drivers/media/video/compat_ioctl32 0x62df4bb1 v4l_compat_ioctl32 +EXPORT_SYMBOL_GPL drivers/media/video/cx88/cx88xx 0xae5025c9 cx88_setup_xc3028 +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x318cc71d em28xx_uninit_isoc +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x631c6b13 em28xx_init_isoc +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x7fc8652c em28xx_tuner_callback +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x7fd3bc1b em28xx_set_mode +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0xcbdcd3c6 em28xx_audio_analog_set +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x02b9d93b saa7134_ts_qops +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x1c6e74a8 saa7134_s_ctrl_internal +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x2334d6b1 saa7134_g_ctrl_internal +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x3ccebd4d saa7134_s_std_internal +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0xb199cbc8 saa7134_i2c_call_saa6752 +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0xf9086f56 saa7134_queryctrl +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0x1dd95031 v4l2_int_device_register +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0x48f19a77 v4l2_int_ioctl_1 +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xa5228b24 v4l2_int_device_try_attach_all +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xb8c3d956 v4l2_int_ioctl_0 +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xe9a7f737 v4l2_int_device_unregister +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x043b7b44 videobuf_read_stream +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x05e22905 videobuf_mmap_setup +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x10986258 videobuf_iolock +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x2b7f2978 videobuf_querybuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x5d6ddf1c videobuf_qbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x60910fbc videobuf_queue_cancel +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x68f36bca videobuf_queue_to_vmalloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x761ee1e9 videobuf_read_start +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x7ae4a7e7 videobuf_alloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x7b5b82d5 videobuf_cgmbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x841cf42d videobuf_streamon +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x9004a50b videobuf_queue_is_busy +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x960495bf videobuf_reqbufs +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xa6f1ed33 videobuf_stop +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xa8fe554d videobuf_waiton +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xa99caf71 videobuf_read_stop +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xb548aad3 videobuf_next_field +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xb8150985 videobuf_dqbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xcb2d3af1 videobuf_streamoff +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xd1e020a2 videobuf_mmap_mapper +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xf04602fc videobuf_mmap_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xf39bf398 videobuf_queue_core_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xf41b3fc8 videobuf_poll_stream +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xf6f0b80f videobuf_read_one +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xfb0398b2 __videobuf_mmap_setup +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x090e3684 videobuf_dma_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x34f6fcae videobuf_sg_dma_unmap +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x3eecb840 videobuf_dma_map +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x52598e9c videobuf_sg_dma_map +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x5ce28b60 videobuf_dma_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x6199838d videobuf_to_dma +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x7a7f0c78 videobuf_dma_unmap +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x853e8c1e videobuf_queue_sg_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x937793fd videobuf_dma_init_user +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xa825c75b videobuf_sg_alloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xc62d9f0d videobuf_dma_init_kernel +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xcc2a7e0f videobuf_dma_init_overlay +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xe59ea68f videobuf_dma_sync +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xe8a24336 videobuf_vmalloc_to_sg +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0x2bcf0e77 videobuf_to_vmalloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0x305563d0 videobuf_queue_vmalloc_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0xde9199e5 videobuf_vmalloc_free +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x2a4af485 i2o_dma_map_single +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x2e98310f i2o_dma_map_sg +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x53976b70 i2o_pool_alloc +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x61e82369 i2o_dma_alloc +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xa17bf059 i2o_dma_realloc +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xb1b3db18 i2o_dma_free +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xd876324e i2o_sg_tablesize +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xf22b9004 i2o_pool_free +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x2126cd65 sm501_find_clock +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x4dfa7ac8 sm501_set_clock +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x6cd87b4f sm501_modify_reg +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0xbf1fe594 sm501_misc_control +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0xcba94253 sm501_unit_power +EXPORT_SYMBOL_GPL drivers/misc/eeprom_93cx6 0x2df115d4 eeprom_93cx6_multiread +EXPORT_SYMBOL_GPL drivers/misc/eeprom_93cx6 0x63d14d2f eeprom_93cx6_read +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x3190be63 enclosure_unregister +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x4793c93a enclosure_register +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x48f9e155 enclosure_remove_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x77711c41 enclosure_find +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x99197e7d enclosure_for_each_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0xbc0f59ee enclosure_component_register +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0xdeb8c4ac enclosure_add_device +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x493cb103 sdhci_add_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x5c2b8fa5 sdhci_resume_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x8536e313 sdhci_suspend_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x85f2963e sdhci_remove_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x866c6dcf sdhci_alloc_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0xe69832bb sdhci_free_host +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0x1fdc6676 cfi_cmdset_0200 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0x74d5a4a7 cfi_cmdset_0003 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0xed91dd2b cfi_cmdset_0001 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0002 0x38779861 cfi_cmdset_0002 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0020 0x45a46a9f cfi_cmdset_0020 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0xd90a98cf cfi_qry_present +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0xdff756ac cfi_qry_mode_off +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0xe465a348 cfi_qry_mode_on +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2000 0x340f5e8f DoC2k_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2001 0x31355c13 DoCMil_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2001plus 0x8e59158d DoCMilPlus_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/docecc 0x45937659 doc_decode_ecc +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x0abcdc26 get_mtd_device_nm +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x12807b8f add_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x16058139 deregister_mtd_parser +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x3304b8ef register_mtd_parser +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x36dd85f3 register_mtd_user +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x3a800734 kill_mtd_super +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x8fc3c8e9 put_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x901708d7 unregister_mtd_user +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x9beb3345 mtd_table +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x9f9f9aca parse_mtd_partitions +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xa820e562 del_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xac91edac mtd_erase_callback +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xd3bf06da default_mtd_writev +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xd52c0ef6 get_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xdf558302 get_sb_mtd +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xeff64be1 mtd_table_mutex +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0x3a926815 deregister_mtd_blktrans +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0x43648c54 add_mtd_blktrans_dev +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0xe3e59738 del_mtd_blktrans_dev +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0xff618a31 register_mtd_blktrans +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x11f86398 nand_wait_ready +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x73964a13 nand_scan_tail +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x9211d319 nand_release +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xa3d7a704 nand_scan_ident +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xaa5d6a1d nand_scan +EXPORT_SYMBOL_GPL drivers/mtd/onenand/onenand 0x3a81b672 onenand_release +EXPORT_SYMBOL_GPL drivers/mtd/onenand/onenand 0x8728df19 onenand_scan +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x1d387aa9 ubi_leb_map +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x2a8dc106 ubi_close_volume +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x42801d20 ubi_sync +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x75514b29 ubi_open_volume_nm +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x7ed090b5 ubi_leb_erase +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x8c6f4698 ubi_get_volume_info +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x8ff9e0cd ubi_is_mapped +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x921c9d9e ubi_leb_unmap +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xa6e1fbf6 ubi_leb_write +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xa7a75004 ubi_leb_change +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xab16e017 ubi_leb_read +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xbc505df4 ubi_get_device_info +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xe71ad2e9 ubi_open_volume +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0115f3b5 mlx4_multicast_attach +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x06b463d8 mlx4_db_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0a650e88 mlx4_qp_reserve_range +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0e494b22 mlx4_fmr_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0fdd7a25 mlx4_INIT_PORT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x1885e528 mlx4_cq_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x204cdee4 mlx4_mtt_init +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x232785ba mlx4_pd_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x2886ed85 mlx4_mr_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x317c3468 mlx4_srq_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x3c43cdda mlx4_free_hwq_res +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x3db2df79 mlx4_cq_resize +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x43e139dd mlx4_fmr_unmap +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x466375e7 mlx4_SYNC_TPT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x4a94edc9 mlx4_multicast_detach +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x4e7daa1f mlx4_buf_write_mtt +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x4f038a74 mlx4_alloc_hwq_res +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x51680b82 mlx4_CLOSE_PORT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x54a0a76e mlx4_unregister_interface +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x55ec98e9 mlx4_write_mtt +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x687962a4 mlx4_fmr_enable +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x6d0de4de mlx4_register_interface +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x6fbd3016 mlx4_mtt_cleanup +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x730585ff mlx4_unregister_vlan +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x7aec0ae6 mlx4_srq_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x7bec23d8 mlx4_cq_modify +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x7d5913b5 mlx4_buf_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x7e82a781 mlx4_qp_remove +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x888bcc44 mlx4_qp_query +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x8abda00b mlx4_uar_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x8cc045a0 mlx4_srq_arm +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x904d21b7 mlx4_qp_modify +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x92410158 mlx4_map_phys_fmr +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x99a532f0 mlx4_mtt_addr +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x9f4eb783 mlx4_unregister_mac +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xa1484a0d mlx4_qp_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xa79c194d __mlx4_cmd +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xa7e28943 mlx4_mr_enable +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xad8a8a2d mlx4_register_vlan +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xaf04daef mlx4_mr_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xafc447b4 mlx4_free_cmd_mailbox +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xb1cf08e6 mlx4_buf_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xb305c435 mlx4_pd_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xb87e7ca1 mlx4_qp_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xc1c219c5 mlx4_cq_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xd0331d71 mlx4_db_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xd7deb3da mlx4_fmr_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xe07728a2 mlx4_alloc_cmd_mailbox +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xe8e1fe3a mlx4_srq_query +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xebe9dd8b mlx4_register_mac +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf50300b3 mlx4_qp_to_ready +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf77f70a6 mlx4_qp_release_range +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf920695c mlx4_uar_free +EXPORT_SYMBOL_GPL drivers/net/usb/cdc_ether 0x92e700e6 usbnet_generic_cdc_bind +EXPORT_SYMBOL_GPL drivers/net/usb/cdc_ether 0xdccf264d usbnet_cdc_unbind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x17fac72b generic_rndis_bind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x198b053a rndis_unbind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x23171c0e rndis_status +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x4287ef4c rndis_tx_fixup +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x71da37b6 rndis_rx_fixup +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xcc876831 rndis_command +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x00af2dd0 usbnet_set_settings +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x125a2676 usbnet_skb_return +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x20456981 usbnet_disconnect +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x2358fc00 usbnet_get_link +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x3cf74bd2 usbnet_get_drvinfo +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x43bc66e4 usbnet_unlink_rx_urbs +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x52a10e68 usbnet_probe +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x5773af2a usbnet_set_msglevel +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x6f690aef usbnet_get_endpoints +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x861eafb8 usbnet_suspend +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x98899e7d usbnet_resume +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xa130f95a usbnet_get_msglevel +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xe897f1c9 usbnet_get_settings +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xf23d7886 usbnet_nway_reset +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xf98a17c1 usbnet_defer_kevent +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x0b1d3c2c __lbs_cmd +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x157c3322 lbs_host_sleep_cfg +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x1d3c74f5 lbs_queue_event +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x3db1f539 lbs_cmd_copyback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x447beb9e lbs_add_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x4c99a623 lbs_stop_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x5e2e5f23 lbs_notify_command_response +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x5f2362c4 lbs_cmd_802_11_rate_adapt_rateset +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x85518574 lbs_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x89ef7f3e lbs_send_tx_feedback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xa2501bd4 lbs_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xaa595378 lbs_host_to_card_done +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xcd23e21f lbs_process_rxed_packet +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xe665795e lbs_start_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xf2cc9601 lbs_remove_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xf64277de lbs_debug +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x02f3484b p54_parse_firmware +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x61f4a5ab p54_init_common +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x82be40a8 p54_free_common +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0xc53623b9 p54_read_eeprom +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0xf183b5d6 p54_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x1b00fdc7 rt2x00mac_get_tx_stats +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x2eab342e rt2x00lib_remove_dev +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x428b472c rt2x00lib_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x47adeb5c rt2x00lib_beacondone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x5e394396 rt2x00lib_txdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x613b7615 rt2x00mac_remove_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x644e6bb6 rt2x00queue_map_txskb +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x77d5c8ff rt2x00mac_get_stats +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x7a7f9d88 rt2x00queue_get_entry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x7d2ef2d4 rt2x00mac_stop +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x840a2b38 rt2x00mac_config +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xa732af90 rt2x00mac_start +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xabe74df9 rt2x00mac_add_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xb1a3e81f rt2x00mac_tx +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xb1d424f3 rt2x00mac_conf_tx +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xb68f7ada rt2x00mac_bss_info_changed +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xbae7121f rt2x00mac_configure_filter +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xc9b32011 rt2x00mac_set_key +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xd19753b8 rt2x00lib_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xd8e83037 rt2x00mac_config_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xf3ef4215 rt2x00lib_rxdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xf8f04e60 rt2x00lib_probe_dev +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xfd1ca96e rt2x00queue_get_queue +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x24160fea rt2x00pci_remove +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x286147a2 rt2x00pci_initialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x7522313e rt2x00pci_uninitialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x757a602b rt2x00pci_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x84087ed7 rt2x00pci_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0xcaa6d3a9 rt2x00pci_probe +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0xd99b00e2 rt2x00pci_write_tx_data +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0xf31d4536 rt2x00pci_rxdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x04872ba8 rt2x00usb_init_rxentry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x15cb3314 rt2x00usb_vendor_request +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x1a3937c1 rt2x00usb_vendor_request_buff +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x1da8b5c3 rt2x00usb_disable_radio +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x6245e3fa rt2x00usb_probe +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x6bace4ad rt2x00usb_vendor_req_buff_lock +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x731c6e92 rt2x00usb_init_txentry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x8bb383b4 rt2x00usb_vendor_request_large_buff +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xa53bc4e0 rt2x00usb_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xad26b6fb rt2x00usb_initialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xc279fc82 rt2x00usb_kick_tx_queue +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xd4e190ee rt2x00usb_uninitialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xe344f9f2 rt2x00usb_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xf972f740 rt2x00usb_write_tx_data +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xfbd4721d rt2x00usb_disconnect +EXPORT_SYMBOL_GPL drivers/pci/hotplug/acpiphp 0x61ec5ba4 acpiphp_register_attention +EXPORT_SYMBOL_GPL drivers/pci/hotplug/acpiphp 0xe860a12d acpiphp_unregister_attention +EXPORT_SYMBOL_GPL drivers/pci/hotplug/pci_hotplug 0x04246173 cpci_hp_register_controller +EXPORT_SYMBOL_GPL drivers/pci/hotplug/pci_hotplug 0x0fa84b65 cpci_hp_register_bus +EXPORT_SYMBOL_GPL drivers/pci/hotplug/pci_hotplug 0x12c72979 pci_hp_deregister +EXPORT_SYMBOL_GPL drivers/pci/hotplug/pci_hotplug 0x1ad3b491 acpi_root_bridge +EXPORT_SYMBOL_GPL drivers/pci/hotplug/pci_hotplug 0x1d52d70c cpci_hp_unregister_controller +EXPORT_SYMBOL_GPL drivers/pci/hotplug/pci_hotplug 0x3c527b6f cpci_hp_unregister_bus +EXPORT_SYMBOL_GPL drivers/pci/hotplug/pci_hotplug 0x4c55deaf acpi_get_hp_params_from_firmware +EXPORT_SYMBOL_GPL drivers/pci/hotplug/pci_hotplug 0x6a8441be cpci_hp_start +EXPORT_SYMBOL_GPL drivers/pci/hotplug/pci_hotplug 0x94ef4d05 cpci_hp_stop +EXPORT_SYMBOL_GPL drivers/pci/hotplug/pci_hotplug 0xdf59241c pci_hp_register +EXPORT_SYMBOL_GPL drivers/pci/hotplug/pci_hotplug 0xf6f68108 pci_hp_change_slot_info +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x0233f349 iscsi_pool_init +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x028daf42 iscsi_suspend_tx +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x0e46e258 iscsi_itt_to_ctask +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x1621d1cc __iscsi_get_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x1f2e8be0 __iscsi_complete_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x29712283 iscsi_host_set_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x2b24e4ee iscsi_put_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x2ce953b2 iscsi_conn_failure +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x2dac90f5 iscsi_eh_abort +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x3073eb7d iscsi_eh_device_reset +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x361e7860 iscsi_conn_start +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x3d05100b iscsi_update_cmdsn +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x400d8698 iscsi_conn_teardown +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x41ba1d14 iscsi_pool_free +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x4b34a3e1 iscsi_conn_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x55ad74f3 iscsi_host_add +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x5f1ffd79 iscsi_host_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x638c1f0c iscsi_conn_send_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x69f0978f iscsi_session_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x7bf47440 iscsi_eh_target_reset +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x7d01437b iscsi_session_teardown +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x8401eee7 iscsi_change_queue_depth +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x93df6fbb iscsi_verify_itt +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x94a16671 iscsi_prep_unsolicit_data_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x9b0c42bf iscsi_host_remove +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xa7c8daf1 iscsi_conn_bind +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xa82a027c iscsi_queuecommand +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xa9ec46ea iscsi_session_failure +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xb7a52003 iscsi_conn_setup +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xc6750772 iscsi_set_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xcf90b87b iscsi_session_recovery_timedout +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xcfe97087 iscsi_host_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xdffb4eab iscsi_session_setup +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xe9c64790 iscsi_conn_stop +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xf46aaff0 iscsi_requeue_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xfbc06ba7 iscsi_complete_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xfbc67806 iscsi_host_free +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x13feac5b sas_target_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x156ec700 sas_target_destroy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x172b2035 sas_domain_attach_transport +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x22614288 sas_eh_bus_reset_handler +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x3cbc30ee sas_ssp_task_response +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x45b11d77 sas_slave_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x4658053a sas_phy_enable +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x50806f00 sas_register_ha +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x56140d47 sas_slave_configure +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x5e763dbe sas_domain_release_transport +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x6bad79ee sas_phy_reset +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x75dcfb65 sas_bios_param +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x7e2c3b2c sas_find_local_phy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x877a10a9 sas_unregister_ha +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x8c0f371b sas_queuecommand +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x8d0a67ac sas_slave_destroy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x93d8b4d4 sas_request_addr +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x95e71bdd __sas_task_abort +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x9c4f922c sas_change_queue_type +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xc01ffc61 sas_task_abort +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xc7301eaf sas_ioctl +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xcfeabb69 sas_eh_device_reset_handler +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xddd1227a sas_change_queue_depth +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x049f1b53 srp_target_free +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x0d58c132 srp_iu_get +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x12619d57 srp_iu_put +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x2037a470 srp_cmd_queue +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x59aeafca srp_target_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0xde341c0d srp_transfer_data +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x1a3c39b1 scsi_tgt_it_nexus_create +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x3176434b scsi_host_get_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x32db657a scsi_tgt_cmd_to_host +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x620a2daa scsi_tgt_it_nexus_destroy +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xb43b47f2 scsi_tgt_queue_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xcaaa2702 scsi_host_put_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xd379f56c scsi_tgt_free_queue +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xe40833fb scsi_tgt_alloc_queue +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xfaec2c96 scsi_tgt_tsk_mgmt_request +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x215ba455 iscsi_lookup_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x218a5671 iscsi_destroy_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x2aa20ef7 iscsi_unregister_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x3020b3e6 iscsi_remove_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x3197f85c iscsi_conn_error_event +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x33c59b55 iscsi_create_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x33cf6d8d iscsi_host_for_each_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x8940ac23 iscsi_recv_pdu +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x8afacb91 iscsi_create_conn +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x9eb6071b iscsi_block_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xa0392fd7 iscsi_session_chkready +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xa143551b iscsi_create_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xa18ed357 iscsi_unblock_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xa43405a8 iscsi_add_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xa9b198cd iscsi_alloc_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xad9a5ce2 iscsi_register_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xba25e3d2 iscsi_destroy_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xbbf2a01b iscsi_free_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xd17dbee1 iscsi_scan_finished +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xe582c50c iscsi_session_event +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xf03b1f3e iscsi_destroy_conn +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0x0ef06974 spi_populate_ppr_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0xa0c71dac spi_populate_sync_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0xcffa2aff spi_populate_width_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x39f2e1e8 srp_rport_add +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x6216bfd2 srp_attach_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0xa382ab23 srp_rport_del +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0xe21cd9a4 srp_release_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0xe5abf3e6 srp_remove_host +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x270daea6 spi_bitbang_stop +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x4916056e spi_bitbang_transfer +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x61efa99d spi_bitbang_start +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x6e09ee2a spi_bitbang_setup_transfer +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0xd25b6af9 spi_bitbang_setup +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0xe8b7696f spi_bitbang_cleanup +EXPORT_SYMBOL_GPL drivers/uio/uio 0x2adab7c6 uio_event_notify +EXPORT_SYMBOL_GPL drivers/uio/uio 0x8beeaf1a uio_unregister_device +EXPORT_SYMBOL_GPL drivers/uio/uio 0xa47037f7 __uio_register_device +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x004da1df usb_deregister +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x03c44566 usb_deregister_dev +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x0f772efb usb_unlink_urb +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x100c13c6 usb_kill_anchored_urbs +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x103400d4 usb_sg_init +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x14c3f669 usb_altnum_to_altsetting +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x16f4fb96 usb_find_interface +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x19a304ba usb_disabled +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x1bb9d895 usb_hcd_pci_probe +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x1f5bc7a4 usb_remove_hcd +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x1f8ed906 usb_get_from_anchor +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x228945b0 usb_get_status +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x22c85017 usb_set_interface +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x262f6b83 usb_get_intf +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x27648bc2 usb_ifnum_to_if +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x291e9be9 usb_get_dev +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x2960d55d usb_autopm_set_interface +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x2b1d775a usb_mon_register +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x315c2685 usb_hcd_unlink_urb_from_ep +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x31f65782 usb_autopm_get_interface +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x321e6946 usb_register_dev +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x33afd13f usb_create_hcd +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x37e19d1c usb_buffer_unmap_sg +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x390aab4f usb_driver_release_interface +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x3be42f98 usb_put_dev +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x3be89d3c usb_register_notify +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x3dd1dbc7 usb_register_driver +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x3e0b05d4 usb_hcd_pci_resume +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x41ce0be7 usb_bulk_msg +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x428735c6 usb_match_id +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x42c1bf5c usb_ep0_reinit +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x4da8060a usb_reset_configuration +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x4f5b9d8b usb_kill_urb +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x50876557 usb_match_one_id +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x52050390 usb_interrupt_msg +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x577b382b usb_anchor_urb +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x599076ec usb_hcd_platform_shutdown +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x641ff64f usb_hcd_pci_remove +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x666ccffd usb_hcd_giveback_urb +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x67ad1c21 usb_poison_urb +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x6dce94bf usb_bus_list_lock +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x720215ad usb_string +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x722c4f65 usb_scuttle_anchored_urbs +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x737a269c usb_free_urb +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x75610a4d usb_driver_set_configuration +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x78b87c2f usb_hub_tt_clear_buffer +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x7e64181d usb_calc_bus_time +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x8319f178 usb_get_current_frame_number +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x85059359 usb_driver_claim_interface +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x86b10394 ehci_cf_port_reset_rwsem +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x884d9a9e usb_register_device_driver +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x8c3a36e5 usb_control_msg +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x8d1ce9c9 usb_get_hcd +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x8da7b6d1 usb_unpoison_urb +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x91482eef usb_anchor_empty +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x9195f363 usb_clear_halt +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x922722cc usb_hcd_pci_shutdown +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x94a39544 usb_get_descriptor +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x9924c496 __usb_get_extra_descriptor +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0x9c419d36 usb_buffer_alloc +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xa1270650 usb_hcd_check_unlink_urb +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xa28d8527 usb_poison_anchored_urbs +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xa320a283 usb_sg_cancel +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xa6f5f899 usb_hcd_link_urb_to_ep +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xa98f84f3 usb_lock_device_for_reset +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xaab9ede9 usb_init_urb +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xab637846 usb_submit_urb +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xace5c0fc usb_bus_list +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xad7523cd usb_put_intf +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xadcac991 usb_hcd_resume_root_hub +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xaf23c80a usb_sg_wait +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xafc7c996 usb_unlink_anchored_urbs +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xb0eedea9 usb_wait_anchor_empty_timeout +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xb2d02438 usb_hc_died +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xb313d7c6 usb_buffer_free +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xb6a4d684 usb_root_hub_lost_power +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xbc0914eb usb_unanchor_urb +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xbe31d61e usb_hcd_pci_suspend +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xbf18bb5b usb_alloc_urb +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xbf4a3b68 usb_autopm_put_interface +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xc17515d7 usb_hcds_loaded +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xda6f9697 usb_deregister_device_driver +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xe1ad7ce9 usb_buffer_map_sg +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xe29f115a usb_store_new_id +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xe5b29503 usb_add_hcd +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xe7252a58 usb_put_hcd +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xe9587909 usb_unregister_notify +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xec185def usb_get_urb +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xf522abaf usb_reset_device +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xf9331f5a usb_hcd_poll_rh_status +EXPORT_SYMBOL_GPL drivers/usb/core/usbcore 0xfed11ed1 usb_mon_deregister +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x27738e15 usb_ftdi_elan_edset_flush +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x464e7b79 usb_ftdi_elan_edset_output +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x511cdf95 ftdi_elan_gone_away +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xa283c2df usb_ftdi_elan_edset_empty +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xa857aa60 usb_ftdi_elan_edset_input +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xc5a8a4c6 usb_ftdi_elan_read_pcimem +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xc781bd0e usb_ftdi_elan_edset_setup +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xd10b12e4 usb_ftdi_elan_write_pcimem +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xdfa18ebd usb_ftdi_elan_edset_single +EXPORT_SYMBOL_GPL drivers/usb/misc/phidget 0x2a8dfa71 phidget_class +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0x010f3317 usb_serial_generic_open +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0x4e0da1f9 usb_serial_register +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0x512145c2 usb_serial_probe +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0x53338d22 ezusb_writememory +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0x5670b69d ezusb_set_reset +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0x691328ca usb_serial_disconnect +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0x8d8bfcd1 usb_serial_generic_write_bulk_callback +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0xce2653ba usb_serial_generic_read_bulk_callback +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0xddfa863b usb_serial_port_softint +EXPORT_SYMBOL_GPL drivers/usb/serial/usbserial 0xf10c214d usb_serial_deregister +EXPORT_SYMBOL_GPL drivers/usb/storage/libusual 0x3edad223 usb_usual_clear_present +EXPORT_SYMBOL_GPL drivers/usb/storage/libusual 0x89d4dbaf usb_usual_check_type +EXPORT_SYMBOL_GPL drivers/usb/storage/libusual 0xcd9991a9 usb_usual_set_present +EXPORT_SYMBOL_GPL drivers/usb/storage/libusual 0xde134c69 storage_usb_ids +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x23615577 ili9320_resume +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x275656da ili9320_remove +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x2bfaa5d2 ili9320_suspend +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x38e0b64b ili9320_write_regs +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x4ad3d3f9 ili9320_shutdown +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0xab18b2c2 ili9320_probe_spi +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0xf00ae1e2 ili9320_write +EXPORT_SYMBOL_GPL drivers/video/fb_ddc 0x15cf5743 fb_ddc_read +EXPORT_SYMBOL_GPL drivers/video/fb_sys_fops 0x2e0a30a5 fb_sys_read +EXPORT_SYMBOL_GPL drivers/video/fb_sys_fops 0xee579ef9 fb_sys_write +EXPORT_SYMBOL_GPL drivers/video/sis/sisfb 0x077050f6 sis_free_new +EXPORT_SYMBOL_GPL drivers/video/sis/sisfb 0x20df54f8 sis_malloc_new +EXPORT_SYMBOL_GPL drivers/video/vermilion/vmlfb 0x016e6c20 vmlfb_unregister_subsys +EXPORT_SYMBOL_GPL drivers/video/vermilion/vmlfb 0x90c018c6 vmlfb_register_subsys +EXPORT_SYMBOL_GPL drivers/w1/wire 0x17158a6f w1_reset_select_slave +EXPORT_SYMBOL_GPL drivers/w1/wire 0x36466bc9 w1_read_block +EXPORT_SYMBOL_GPL drivers/w1/wire 0x3728b0ad w1_reset_bus +EXPORT_SYMBOL_GPL drivers/w1/wire 0x45274ccb w1_next_pullup +EXPORT_SYMBOL_GPL drivers/w1/wire 0x646d091d w1_read_8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0x7c2f2afb w1_calc_crc8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0x7e315b16 w1_write_8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0xe564dd3e w1_write_block +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x274f453c dlm_posix_get +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x9321df95 dlm_lock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x96fd78e5 dlm_posix_lock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xcf9f3328 dlm_release_lockspace +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xdc583c08 dlm_unlock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xdf3c14de dlm_new_lockspace +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xfe58907e dlm_posix_unlock +EXPORT_SYMBOL_GPL fs/exportfs/exportfs 0x762385b6 exportfs_decode_fh +EXPORT_SYMBOL_GPL fs/exportfs/exportfs 0x7f2acb68 exportfs_encode_fh +EXPORT_SYMBOL_GPL fs/fat/fat 0x1047b643 fat_getattr +EXPORT_SYMBOL_GPL fs/fat/fat 0x1542194b fat_build_inode +EXPORT_SYMBOL_GPL fs/fat/fat 0x5f87006f fat_fs_panic +EXPORT_SYMBOL_GPL fs/fat/fat 0x63364128 fat_search_long +EXPORT_SYMBOL_GPL fs/fat/fat 0x6b7fcc24 fat_get_dotdot_entry +EXPORT_SYMBOL_GPL fs/fat/fat 0x73050b2f fat_attach +EXPORT_SYMBOL_GPL fs/fat/fat 0x88a584de fat_remove_entries +EXPORT_SYMBOL_GPL fs/fat/fat 0x88c330a4 fat_dir_empty +EXPORT_SYMBOL_GPL fs/fat/fat 0x958bdfd3 fat_scan +EXPORT_SYMBOL_GPL fs/fat/fat 0xb7c60117 fat_detach +EXPORT_SYMBOL_GPL fs/fat/fat 0xbb0aa194 fat_fill_super +EXPORT_SYMBOL_GPL fs/fat/fat 0xc2cb8e1a fat_time_unix2fat +EXPORT_SYMBOL_GPL fs/fat/fat 0xc941d010 fat_flush_inodes +EXPORT_SYMBOL_GPL fs/fat/fat 0xd7caaf7a fat_add_entries +EXPORT_SYMBOL_GPL fs/fat/fat 0xe09c5666 fat_setattr +EXPORT_SYMBOL_GPL fs/fat/fat 0xe37d1edc fat_free_clusters +EXPORT_SYMBOL_GPL fs/fat/fat 0xfcf29bd1 fat_alloc_new_dir +EXPORT_SYMBOL_GPL fs/fat/fat 0xfcf4ecb9 fat_sync_inode +EXPORT_SYMBOL_GPL fs/gfs2/gfs2 0x03c87f65 gfs2_unregister_lockproto +EXPORT_SYMBOL_GPL fs/gfs2/gfs2 0x5963fbe3 gfs2_register_lockproto +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x0f4ba866 nlmclnt_init +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x17ce645d locks_end_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x1a618932 nlmsvc_unlock_all_by_ip +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x67d1ec7e nlmclnt_proc +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x6f959b35 locks_in_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x803ddfa8 nlmsvc_unlock_all_by_sb +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x96877ac4 locks_start_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0xb49391b6 nlmclnt_done +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x0fafbc6f o2hb_unregister_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x16e21507 o2nm_node_get +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x1b89c6ee o2hb_fill_node_map +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x1cb231d0 mlog_not_bits +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x1d747ce3 o2hb_check_node_heartbeating +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x2ef048b6 o2nm_node_put +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x36418553 o2net_send_message +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x4900035b o2hb_stop_all_regions +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x625dc02b o2hb_register_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x665a2c14 o2hb_setup_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x687f6251 mlog_and_bits +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xa3c93fa0 o2nm_get_node_by_ip +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xa82a8645 o2nm_this_node +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xa87bc9e7 o2nm_configured_node_map +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xa9f5379a o2net_send_message_vec +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xae808bac o2net_register_handler +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xbaeb4700 o2hb_check_node_heartbeating_from_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xce9cd163 o2nm_get_node_by_num +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xd60f2c6c o2hb_check_local_node_heartbeating +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xf1a5611d o2net_unregister_handler_list +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x779a5f5a dlm_register_domain +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x7a1211f8 dlm_setup_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xa22ff1db dlmunlock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xcbc0b1f5 dlm_print_one_lock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xcdfe1ca4 dlmlock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xd7ba575e dlm_errmsg +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xd8fa57a6 dlm_unregister_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xdaf9b3a1 dlm_unregister_domain +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xfb86b96f dlm_errname +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xfd736c32 dlm_register_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x0562c415 ocfs2_cluster_this_node +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x0e27f909 ocfs2_dlm_lock +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x1c2301b1 ocfs2_stack_glue_unregister +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x21db5b88 ocfs2_cluster_disconnect +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x3015aea4 ocfs2_plock +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x4a1f6fe9 ocfs2_cluster_connect +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x4d3af7fa ocfs2_cluster_hangup +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x81c85a68 ocfs2_dlm_lock_status +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x91fab465 ocfs2_dlm_lvb +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x963932a3 ocfs2_stack_glue_set_locking_protocol +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xa7d5c1c0 ocfs2_dlm_unlock +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xaacf45ff ocfs2_stack_glue_register +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xbbc4ef97 ocfs2_stack_supports_plocks +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xd066711e ocfs2_dlm_dump_lksb +EXPORT_SYMBOL_GPL lib/lzo/lzo_compress 0x56b63670 lzo1x_1_compress +EXPORT_SYMBOL_GPL lib/lzo/lzo_decompress 0xf30fda27 lzo1x_decompress_safe +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0x300d7e57 free_rs +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0x6fbb3bd9 init_rs_non_canonical +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0xabda1e2e decode_rs16 +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0xb050f329 init_rs +EXPORT_SYMBOL_GPL net/802/stp 0xa8796802 stp_proto_unregister +EXPORT_SYMBOL_GPL net/802/stp 0xb2fc3040 stp_proto_register +EXPORT_SYMBOL_GPL net/bluetooth/bluetooth 0xbc07d81e bt_class +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x02309432 tfrc_rx_hist_duplicate +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x09c5ed3c tfrc_tx_hist_purge +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x0a487ea5 tfrc_calc_x +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x106fe6d3 tfrc_tx_hist_rtt +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x14dcf2f6 tfrc_lh_interval_add +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x1f5975bf tfrc_lh_update_i_mean +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x2262397e tfrc_rx_handle_loss +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x69ec5731 tfrc_tx_hist_add +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x6c252d29 tfrc_calc_x_reverse_lookup +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x8860de41 tfrc_rx_hist_add_packet +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x902206f0 tfrc_lh_cleanup +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x92285650 tfrc_rx_hist_alloc +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x9969bfa9 tfrc_rx_hist_sample_rtt +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xc612a5b6 tfrc_rx_hist_purge +EXPORT_SYMBOL_GPL net/dccp/dccp 0x031f7f6d dccp_recvmsg +EXPORT_SYMBOL_GPL net/dccp/dccp 0x04415b54 dccp_done +EXPORT_SYMBOL_GPL net/dccp/dccp 0x05a4f988 dccp_feat_clone +EXPORT_SYMBOL_GPL net/dccp/dccp 0x0e3b97ca dccp_send_sync +EXPORT_SYMBOL_GPL net/dccp/dccp 0x1421cf49 dccp_send_ack +EXPORT_SYMBOL_GPL net/dccp/dccp 0x1d99d49a dccp_timestamp +EXPORT_SYMBOL_GPL net/dccp/dccp 0x1da9d5a6 dccp_disconnect +EXPORT_SYMBOL_GPL net/dccp/dccp 0x23936ea8 dccp_poll +EXPORT_SYMBOL_GPL net/dccp/dccp 0x2b27cc14 ccid_hc_tx_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0x30073ff6 ccid_hc_tx_delete +EXPORT_SYMBOL_GPL net/dccp/dccp 0x322d897c dccp_ctl_make_reset +EXPORT_SYMBOL_GPL net/dccp/dccp 0x34ac8555 dccp_set_state +EXPORT_SYMBOL_GPL net/dccp/dccp 0x3b3c0b1b dccp_feat_clean +EXPORT_SYMBOL_GPL net/dccp/dccp 0x3d81f98b inet_dccp_listen +EXPORT_SYMBOL_GPL net/dccp/dccp 0x43d6f796 dccp_destroy_sock +EXPORT_SYMBOL_GPL net/dccp/dccp 0x4e5f8aa4 dccp_ioctl +EXPORT_SYMBOL_GPL net/dccp/dccp 0x505cf2c5 dccp_check_req +EXPORT_SYMBOL_GPL net/dccp/dccp 0x51bd702f dccp_feat_confirm_recv +EXPORT_SYMBOL_GPL net/dccp/dccp 0x56178dd8 dccp_insert_option_timestamp +EXPORT_SYMBOL_GPL net/dccp/dccp 0x56ea266a dccp_state_name +EXPORT_SYMBOL_GPL net/dccp/dccp 0x5eadacf4 dccp_init_sock +EXPORT_SYMBOL_GPL net/dccp/dccp 0x67904267 dccp_sample_rtt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x69ce6e14 dccp_insert_option_elapsed_time +EXPORT_SYMBOL_GPL net/dccp/dccp 0x6d462b7b dccp_setsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x71f7a202 dccp_connect +EXPORT_SYMBOL_GPL net/dccp/dccp 0x76bb26ab ccid_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0x7facd81d dccp_shutdown +EXPORT_SYMBOL_GPL net/dccp/dccp 0x814c2202 dccp_create_openreq_child +EXPORT_SYMBOL_GPL net/dccp/dccp 0x86be7924 dccp_packet_name +EXPORT_SYMBOL_GPL net/dccp/dccp 0x89c0c350 dccp_rcv_state_process +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8b7d8caf dccp_statistics +EXPORT_SYMBOL_GPL net/dccp/dccp 0x988acf6d dccp_getsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x9c99d2ad dccp_reqsk_init +EXPORT_SYMBOL_GPL net/dccp/dccp 0x9d6a3846 dccp_orphan_count +EXPORT_SYMBOL_GPL net/dccp/dccp 0xa520c356 dccp_insert_option +EXPORT_SYMBOL_GPL net/dccp/dccp 0xb69318b6 dccp_reqsk_send_ack +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbe1522fc ccid_hc_rx_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbe4cf010 dccp_feat_init +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbf6b58ba dccp_feat_change +EXPORT_SYMBOL_GPL net/dccp/dccp 0xc2b37492 dccp_sync_mss +EXPORT_SYMBOL_GPL net/dccp/dccp 0xc9379a69 dccp_sendmsg +EXPORT_SYMBOL_GPL net/dccp/dccp 0xcdc4ad4d dccp_make_response +EXPORT_SYMBOL_GPL net/dccp/dccp 0xdf762ab7 ccid_unregister +EXPORT_SYMBOL_GPL net/dccp/dccp 0xe9a76976 dccp_child_process +EXPORT_SYMBOL_GPL net/dccp/dccp 0xf64a85fd dccp_rcv_established +EXPORT_SYMBOL_GPL net/dccp/dccp 0xf6c4b82b ccid_register +EXPORT_SYMBOL_GPL net/dccp/dccp 0xfa4367ee dccp_feat_change_recv +EXPORT_SYMBOL_GPL net/dccp/dccp 0xfd683280 ccid_hc_rx_delete +EXPORT_SYMBOL_GPL net/dccp/dccp 0xfda7c8e0 dccp_hashinfo +EXPORT_SYMBOL_GPL net/dccp/dccp 0xff6a8f48 dccp_close +EXPORT_SYMBOL_GPL net/dccp/dccp 0xff80f932 dccp_parse_options +EXPORT_SYMBOL_GPL net/dccp/dccp 0xff90f026 dccp_death_row +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x05e82860 dccp_v4_request_recv_sock +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x2daad732 dccp_v4_send_check +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x65140f6e dccp_v4_connect +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x6f9b5de3 dccp_v4_conn_request +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0xa5f08b5c dccp_invalid_packet +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0xd709f078 dccp_v4_do_rcv +EXPORT_SYMBOL_GPL net/ieee80211/ieee80211 0x4c8ee7b2 ieee80211_rx_any +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_conntrack_ipv4 0x6d40a921 need_ipv4_conntrack +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_conntrack_ipv4 0x79df9e3e nf_nat_seq_adjust_hook +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_defrag_ipv4 0x6b6c3d10 nf_defrag_ipv4_enable +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x07ae60b6 nf_nat_proto_in_range +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x4443bad8 nf_nat_packet +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x59c3072f nf_nat_proto_unique_tuple +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x94a08134 nf_nat_proto_nlattr_to_range +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0xb05db2ef nf_nat_proto_find_get +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0xb7a56b76 nf_nat_icmp_reply_translation +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0xbc80437f nf_nat_proto_put +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0xc3d6d4d9 nf_nat_proto_range_to_nlattr +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat_proto_gre 0x636b12c8 nf_nat_need_gre +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x2a3527a8 tcp_vegas_get_info +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x37ce0019 tcp_vegas_init +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x52c94a34 tcp_vegas_pkts_acked +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0xdca0e102 tcp_vegas_state +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0xe5deb59c tcp_vegas_cwnd_event +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x08a3e5d1 net_ipv6_ctl_path +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x1c25501c inet6_destroy_sock +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x25c70a0b inet6_csk_search_req +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x2beb1583 inet6_sk_rebuild_header +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x764f3378 inet6_csk_bind_conflict +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x7ad85f7c ipv6_opt_accepted +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x85478a0b inet6_hash_frag +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x8dc33c30 ip6_local_out +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0x8f5139c7 ipv6_find_tlv +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0xb10a67d4 fl6_sock_lookup +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0xb71b7e7c ip6_sk_dst_lookup +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0xcf8857ce ip6_dst_lookup +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0xd02b694b ip6_dst_blackhole +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0xd4ad0c0a inet6_csk_xmit +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0xda31c1a5 ipv6_dup_options +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0xeb04af99 inet6_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL net/ipv6/ipv6 0xf7dc3ad9 inet6_csk_addr2sockaddr +EXPORT_SYMBOL_GPL net/mac80211/mac80211 0x06efb31a ieee80211_iterate_active_interfaces_atomic +EXPORT_SYMBOL_GPL net/mac80211/mac80211 0x303807bd ieee80211_iterate_active_interfaces +EXPORT_SYMBOL_GPL net/netfilter/ipvs/ip_vs 0xe6476b4a net_vs_ctl_path +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x041013fd nf_conntrack_lock +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x045072cd nf_ct_port_nla_policy +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x065f1e3e nf_ct_l4proto_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x08703976 nf_ct_expect_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x0bfa734c nf_ct_port_tuple_to_nlattr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x1239329e nf_conntrack_l3proto_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x1283d711 nf_ct_expect_unregister_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x15c10b0b nf_conntrack_unregister_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x17ebe947 nf_ct_l3proto_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x1feffbe2 nf_ct_get_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x25bbbeac __nf_conntrack_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x38630158 nf_conntrack_tuple_taken +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x38c9440b nf_ct_extend_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x39ddda8c nf_conntrack_l3proto_generic +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3aabddce nf_conntrack_alloc +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3f5b1415 nf_ct_port_nlattr_to_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x40387ccf __nf_ct_event_cache_init +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x52985a13 __nf_ct_helper_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x52aa3d83 nf_conntrack_helper_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x53555328 nf_ct_expect_init +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x5404bd2f nf_ct_get_tuplepr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x648bef5c nf_conntrack_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x6c759545 nf_ct_unexpect_related +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x6e224a7a need_conntrack +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x72836f4a nf_conntrack_free +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x73bab158 nf_ct_helper_ext_add +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x77aadb54 nf_conntrack_alter_reply +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x7819297c nf_conntrack_l3proto_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x78f9b710 nf_ct_l3proto_try_module_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x79ca2e53 nf_ct_expect_chain +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x79e0eff2 nf_ct_unlink_expect +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x7b71f563 nf_ct_l3proto_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x801bfbe6 __nf_ct_l4proto_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x817c5544 seq_print_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x8393c15c nf_conntrack_l4proto_udp4 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x839de9a2 __nf_conntrack_confirm +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x88eed37c __nf_ct_kill_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x8d15960e nf_conntrack_l4proto_tcp4 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x8ffe7e89 nf_conntrack_htable_size +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x90069eea __nf_conntrack_helper_find_byname +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x90cc95b7 __nf_ct_refresh_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x90ff6c9f nf_ct_invert_tuplepr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x98981ea0 nf_conntrack_flush +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x9a8cde23 nf_conntrack_l4proto_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x9c856ce6 nf_conntrack_in +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa5f08b5c print_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa6f62ec0 nf_conntrack_set_hashsize +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xaa79c401 nf_ct_expect_related +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xac25c7c2 nf_conntrack_tcp_update +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xaf57e66f nf_ct_extend_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb1a5a3de nf_conntrack_l4proto_udp6 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb5b2922c nf_ct_expect_alloc +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb602c57e nf_ct_l3proto_module_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbc887e16 nf_ct_expect_register_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbecb6b09 nf_conntrack_l4proto_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbf23f48c nf_conntrack_l4proto_tcp6 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc044befe nf_ct_free_hashtable +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc18ac88d nf_ct_expect_hsize +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc35a7a3e nf_conntrack_chain +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc7b18858 nf_ct_invert_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc7b64d79 nf_conntrack_hash_insert +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc7bfe55d nf_ct_expect_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc8008b77 nf_ct_l4proto_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xcbf7fd2a nf_conntrack_register_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd50a96a2 nf_ct_alloc_hashtable +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd675dee6 nf_ct_iterate_cleanup +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd8b9e335 nf_ct_l3protos +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd9efb053 nf_ct_deliver_cached_events +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf0fe205c nf_conntrack_helper_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf84e61f2 __nf_ct_expect_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf9ae81a1 nf_conntrack_max +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfa169dac nf_conntrack_untracked +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfb839673 nf_ct_remove_expectations +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xff9e9fc3 nfnetlink_parse_nat_setup_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_amanda 0x7af04b6d nf_nat_amanda_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_ftp 0x4c168a80 nf_nat_ftp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x1137430f set_h225_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x264c0cf3 get_h225_addr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x56a7616d nat_callforwarding_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x58566fec nat_rtp_rtcp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x6684ac39 set_sig_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x69e8e298 nat_h245_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xc6c23c92 set_ras_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xe1a8a21c nat_q931_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xe527ca2b nat_t120_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xf171ccd3 set_h245_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_irc 0x2969503c nf_nat_irc_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x4535a527 nf_nat_pptp_hook_inbound +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x8b8b2d3e nf_nat_pptp_hook_exp_gre +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x9ac968f3 nf_nat_pptp_hook_expectfn +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0xa6480fa6 nf_nat_pptp_hook_outbound +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_proto_gre 0x05f8e58c nf_ct_gre_keymap_destroy +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_proto_gre 0x6f59d77c nf_ct_gre_keymap_add +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x0b94985a nf_nat_sdp_media_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x13169b79 ct_sip_parse_request +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x3c2058a6 ct_sip_parse_numerical_param +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x5333cb69 ct_sip_parse_header_uri +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x5343611e ct_sip_get_sdp_header +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x56ad8f6e ct_sip_parse_address_param +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x86d67add nf_nat_sip_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x8b9ff6d7 nf_nat_sdp_port_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x9c80724c nf_nat_sdp_session_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xd8362945 nf_nat_sdp_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xf670db83 nf_nat_sip_expect_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xf8b610ea ct_sip_get_header +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_tftp 0x5943f1e1 nf_nat_tftp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_tproxy_core 0x326b5375 nf_tproxy_get_sock_v4 +EXPORT_SYMBOL_GPL net/netfilter/nf_tproxy_core 0xfcdd46f6 nf_tproxy_assign_sock +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x1f58e71b nfnl_lock +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x3895cd7a nfnl_unlock +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x566adcaf nfnetlink_send +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x9555690a nfnetlink_subsys_unregister +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x964b27ba nfnetlink_unicast +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xc2b8b214 nfnetlink_subsys_register +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xeca95329 nfnetlink_has_listeners +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x0f2f6d3c xt_check_match +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x1abeaa52 xt_proto_init +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x40728a63 xt_find_revision +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x4afd7e1f xt_register_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x5fd5258d xt_unregister_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x66a7243e xt_proto_fini +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x85b54e95 xt_check_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xca19f66e xt_request_find_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xd54dde5a xt_find_table_lock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xeabba574 xt_replace_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xf88dfcf0 xt_table_unlock +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0xc177bee0 xt_rateest_put +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0xdb8418cc xt_rateest_lookup +EXPORT_SYMBOL_GPL net/rfkill/rfkill 0x83b2e956 register_rfkill_notifier +EXPORT_SYMBOL_GPL net/rfkill/rfkill 0x86c722f8 rfkill_epo +EXPORT_SYMBOL_GPL net/rfkill/rfkill 0xa6f4320d unregister_rfkill_notifier +EXPORT_SYMBOL_GPL net/rfkill/rfkill 0xf972e196 rfkill_restore_states +EXPORT_SYMBOL_GPL net/rfkill/rfkill 0xfcce694c rfkill_set_default +EXPORT_SYMBOL_GPL net/rxrpc/af-rxrpc 0x27f9d9d2 rxrpc_register_security +EXPORT_SYMBOL_GPL net/rxrpc/af-rxrpc 0xcb953c0d rxrpc_unregister_security +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x00c540f2 rpcauth_create +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x041371a5 xprt_set_retrans_timeout_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x05f547e6 xprt_update_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x0672455b svc_unreg_xprt_class +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x082114db rpc_create +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x08c30edf rpc_exit_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1650face xprt_wake_pending_tasks +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x194f5b19 rpc_proc_register +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1f6f7f0a svc_xprt_init +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x228bdfa2 __rpc_wait_for_completion_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x23af86ba xprt_reserve_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x25db8a90 xprt_register_transport +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2aa17774 rpc_free_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2c1ed620 svc_max_payload +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x31a89d59 rpc_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3288cc13 rpcauth_generic_bind_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x330f8a4a rpcauth_init_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x344804c6 svc_reg_xprt_class +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3453ff9f rpc_delay +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x35140d29 xprt_disconnect_done +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x367d1a8b xprt_set_retrans_timeout_def +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x390c5bcc rpc_malloc +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3b986972 xprt_write_space +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x4383d02d put_rpccred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x45b99d4e svc_xprt_put +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x48df42d9 rpc_bind_new_program +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x53445f68 nlm_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x54717ff6 rpc_killall_tasks +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x550547a3 rpc_destroy_wait_queue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x59a30a92 rpc_sleep_on +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5b20566a rpc_wake_up_queued_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5bd26000 rpc_proc_unregister +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5dfa1818 rpc_force_rebind +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5ff2e80b xprt_unregister_transport +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6094c7b9 rpc_call_start +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6351e124 rpc_lookup_machine_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6563f841 xdr_partial_copy_from_skb +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x661b2d0d rpc_shutdown_client +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x66277f4e svc_xprt_names +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6b07a148 rpc_max_payload +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6c5304c5 rpcb_getport_sync +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6efe736b xprt_release_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x71955cf4 rpc_call_null +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x74f98674 svc_xprt_enqueue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x785f37a0 rpc_alloc_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7af4044d xprt_release_xprt_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7cc48532 svc_close_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7d672766 rpcauth_lookup_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7de53067 rpc_init_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7e075b22 rpc_put_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x843ae264 rpc_setbufsize +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x877879d9 rpcauth_init_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8aeb87d7 rpcauth_unregister +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8c20d35f rpc_restart_call +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8c4579ad rpc_wake_up_next +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8eaeff55 svc_xprt_copy_addrs +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x925d4f69 rpc_call_async +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x9734dbca rpcauth_destroy_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xa37d8bb0 rpc_call_sync +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xa846e94c rpcb_getport_async +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xaabf4887 xprt_lookup_rqst +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xac854c35 rpc_print_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xaebe1fb1 xdr_skb_read_bits +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xaf5bf6ef nfs_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb046166f xprt_wait_for_buffer_space +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb26a0bca rpc_peeraddr2str +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb387b246 rpc_wake_up_status +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb6aae65c xprt_release_rqst_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbf9d1b96 nfsd_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc12435e3 rpc_calc_rto +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc1cd04db xprt_reserve_xprt_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc9dfe06d svc_create_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd089317c rpc_run_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd6cb144e rpc_peeraddr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd82c728e rpc_init_wait_queue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe3d33418 rpc_clone_client +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe5ef86e8 xprt_complete_rqst +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe6f6d363 rpc_lookup_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe96d499b svc_print_addr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe985607b svc_xprt_received +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xea342344 csum_partial_copy_to_xdr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xedafc8d9 svc_addsock +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xedd1ba52 rpc_wake_up +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xeeacab69 rpc_update_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xf4e80685 xprt_adjust_cwnd +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xf4f4e702 rpcauth_register +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xf9d1164c rpc_free +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xfe4c0563 svc_find_xprt +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0x42230c05 ipcomp_input +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0x51edeb1e ipcomp_destroy +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0xaeddab33 ipcomp_init_state +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0xfbeee13c ipcomp_output +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x049bba76 snd_soc_dapm_add_routes +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x058d2749 snd_soc_dapm_get_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x08e6493e snd_soc_dapm_get_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x0b888fb3 snd_soc_dapm_new_control +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x14995765 snd_soc_info_volsw_ext +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x25a1207f snd_soc_info_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x39048657 snd_soc_dai_set_clkdiv +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x39728543 snd_soc_put_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x3cc55e4e snd_soc_dapm_put_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x3db49421 snd_soc_dapm_stream_event +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x3e0cbe80 snd_soc_dai_set_tdm_slot +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x3e5831a4 snd_soc_cnew +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x41fef793 snd_soc_info_enum_ext +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x463dc741 snd_soc_dapm_connect_input +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x4d19e568 snd_soc_dai_set_sysclk +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x4d8a2c86 snd_soc_dapm_put_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x53bbec55 snd_soc_new_ac97_codec +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x586354e6 snd_soc_put_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x586aac07 snd_soc_dapm_free +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x5a483675 snd_soc_info_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x648f8554 snd_soc_update_bits +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x685ee7a7 snd_soc_free_pcms +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x6c404396 snd_soc_get_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x7756109b snd_soc_set_runtime_hwparams +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x7c7742a4 snd_soc_put_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x849834d2 snd_soc_dapm_disable_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x8f62df24 snd_soc_get_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x91f5aa05 snd_soc_dai_set_pll +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x9dac894e snd_soc_get_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xa87dd4d6 snd_soc_info_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xaffe6530 snd_soc_dai_set_fmt +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xb24ce717 snd_soc_dapm_new_controls +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xb54e1c3b snd_soc_dapm_nc_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xc18b6ee2 snd_soc_dapm_sync +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xc6410121 dapm_reg_event +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xca45486e snd_soc_dapm_get_pin_status +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xca6718c3 snd_soc_get_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xcbb4d035 snd_soc_new_pcms +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xd25061bf snd_soc_dai_set_tristate +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xd5ab8281 snd_soc_put_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xd8a93cd5 snd_soc_dapm_enable_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xd98b3a4b snd_soc_free_ac97_codec +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xde8090f5 snd_soc_dapm_new_widgets +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xead9e46d snd_soc_dai_digital_mute +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xf16d602f snd_soc_test_bits +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xf326fc31 snd_soc_register_card +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xff3ab252 snd_soc_info_volsw_2r +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x1584fdb9 tlsf_destroy_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x42a50f11 tlsf_malloc +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x66da3d8f tlsf_create_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xe6acc368 tlsf_free +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xee6c65c9 tlsf_get_used_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xeec8caeb tlsf_get_total_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xf9805f1b tlsf_calloc +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x02500586 thinkpad_ec_unlock +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x0dc7484e thinkpad_ec_try_read_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x2552d213 thinkpad_ec_lock +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x3dbfef12 thinkpad_ec_read_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x8dbbd831 thinkpad_ec_invalidate +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0xa3042743 thinkpad_ec_prefetch_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0xfb5aa917 thinkpad_ec_try_lock +EXPORT_SYMBOL_GPL vmlinux 0x000cff9e transport_remove_device +EXPORT_SYMBOL_GPL vmlinux 0x00566d8f inotify_get_cookie +EXPORT_SYMBOL_GPL vmlinux 0x0067df75 ata_tf_from_fis +EXPORT_SYMBOL_GPL vmlinux 0x006d7cad srcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x00ebcb5d ata_id_string +EXPORT_SYMBOL_GPL vmlinux 0x0110b3d1 register_hotplug_dock_device +EXPORT_SYMBOL_GPL vmlinux 0x01848a8e local_apic_timer_c2_ok +EXPORT_SYMBOL_GPL vmlinux 0x01a4ea6d unregister_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x01e1a8de kgdb_breakpoint +EXPORT_SYMBOL_GPL vmlinux 0x023f9548 cpufreq_frequency_table_target +EXPORT_SYMBOL_GPL vmlinux 0x02ccea56 lock_policy_rwsem_write +EXPORT_SYMBOL_GPL vmlinux 0x031fbfaa __ata_port_next_link +EXPORT_SYMBOL_GPL vmlinux 0x0343bdf1 __i2c_board_list +EXPORT_SYMBOL_GPL vmlinux 0x03be741b tty_buffer_request_room +EXPORT_SYMBOL_GPL vmlinux 0x03c4687d vring_interrupt +EXPORT_SYMBOL_GPL vmlinux 0x03e3686c ata_timing_cycle2mode +EXPORT_SYMBOL_GPL vmlinux 0x04003ec2 device_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x040282f3 pci_find_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0x04136bca klist_init +EXPORT_SYMBOL_GPL vmlinux 0x04486e88 rcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x04566c7f init_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x04e2258c skb_cow_data +EXPORT_SYMBOL_GPL vmlinux 0x0531dcb8 ata_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0x054e550b kernel_halt +EXPORT_SYMBOL_GPL vmlinux 0x05934191 inotify_destroy +EXPORT_SYMBOL_GPL vmlinux 0x05943168 generic_drop_inode +EXPORT_SYMBOL_GPL vmlinux 0x05a007b3 blk_abort_request +EXPORT_SYMBOL_GPL vmlinux 0x060d1064 set_memory_ro +EXPORT_SYMBOL_GPL vmlinux 0x0612adba aead_geniv_init +EXPORT_SYMBOL_GPL vmlinux 0x061f101f blk_trace_setup +EXPORT_SYMBOL_GPL vmlinux 0x063ccc69 ata_sas_port_destroy +EXPORT_SYMBOL_GPL vmlinux 0x064db9a5 mark_mounts_for_expiry +EXPORT_SYMBOL_GPL vmlinux 0x06c10551 fib_rules_cleanup_ops +EXPORT_SYMBOL_GPL vmlinux 0x06cccfa9 power_supply_register +EXPORT_SYMBOL_GPL vmlinux 0x06d222f8 device_resume +EXPORT_SYMBOL_GPL vmlinux 0x075a57b7 register_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0x07935caf crypto_grab_skcipher +EXPORT_SYMBOL_GPL vmlinux 0x07aeff4a skcipher_geniv_free +EXPORT_SYMBOL_GPL vmlinux 0x07b52e38 rtnl_unregister +EXPORT_SYMBOL_GPL vmlinux 0x08bd5384 vfs_getxattr +EXPORT_SYMBOL_GPL vmlinux 0x0911375b ata_sas_port_init +EXPORT_SYMBOL_GPL vmlinux 0x091eb9b4 round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0x0945dde8 sysctl_pathname +EXPORT_SYMBOL_GPL vmlinux 0x09769db9 ata_cable_80wire +EXPORT_SYMBOL_GPL vmlinux 0x09bd30e5 hrtimer_init +EXPORT_SYMBOL_GPL vmlinux 0x0ab985cc put_device +EXPORT_SYMBOL_GPL vmlinux 0x0aee6104 debugfs_create_u16 +EXPORT_SYMBOL_GPL vmlinux 0x0b21f8f1 hvc_alloc +EXPORT_SYMBOL_GPL vmlinux 0x0b8c2c78 kset_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0x0b8f9002 __blkdev_driver_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x0c17e274 xfrm_aalg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x0c459abb ata_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0x0c4717f7 srcu_init_notifier_head +EXPORT_SYMBOL_GPL vmlinux 0x0c90dcb8 sata_scr_write +EXPORT_SYMBOL_GPL vmlinux 0x0cd67faa sata_link_resume +EXPORT_SYMBOL_GPL vmlinux 0x0d3fdece blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0x0d64a8ff debugfs_create_symlink +EXPORT_SYMBOL_GPL vmlinux 0x0d814646 klist_add_head +EXPORT_SYMBOL_GPL vmlinux 0x0dbf1523 pci_create_slot +EXPORT_SYMBOL_GPL vmlinux 0x0dd1a660 tracepoint_iter_start +EXPORT_SYMBOL_GPL vmlinux 0x0de93520 inotify_inode_is_dead +EXPORT_SYMBOL_GPL vmlinux 0x0df0e358 __mnt_is_readonly +EXPORT_SYMBOL_GPL vmlinux 0x0ebdffc2 fb_deferred_io_init +EXPORT_SYMBOL_GPL vmlinux 0x0f52544c get_current_tty +EXPORT_SYMBOL_GPL vmlinux 0x0fbb3d0d crypto_blkcipher_type +EXPORT_SYMBOL_GPL vmlinux 0x0ff93fae inet_twsk_put +EXPORT_SYMBOL_GPL vmlinux 0x100aae3f sysfs_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x100c48a2 unregister_dock_notifier +EXPORT_SYMBOL_GPL vmlinux 0x1115cd84 inet_diag_register +EXPORT_SYMBOL_GPL vmlinux 0x117d6c8b klist_add_after +EXPORT_SYMBOL_GPL vmlinux 0x11980d17 input_ff_destroy +EXPORT_SYMBOL_GPL vmlinux 0x124f2056 crypto_get_attr_type +EXPORT_SYMBOL_GPL vmlinux 0x1251d30f call_rcu +EXPORT_SYMBOL_GPL vmlinux 0x12d75d07 __get_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x12feca50 fb_deferred_io_open +EXPORT_SYMBOL_GPL vmlinux 0x13354608 scatterwalk_map_and_copy +EXPORT_SYMBOL_GPL vmlinux 0x1375b761 tty_ldisc_ref_wait +EXPORT_SYMBOL_GPL vmlinux 0x13b2a946 register_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x145eebd0 device_power_up +EXPORT_SYMBOL_GPL vmlinux 0x1467b686 ata_sff_irq_on +EXPORT_SYMBOL_GPL vmlinux 0x149db923 selinux_string_to_sid +EXPORT_SYMBOL_GPL vmlinux 0x14cb71ea security_inode_setattr +EXPORT_SYMBOL_GPL vmlinux 0x153d74ed ata_slave_link_init +EXPORT_SYMBOL_GPL vmlinux 0x15560eb8 netlink_has_listeners +EXPORT_SYMBOL_GPL vmlinux 0x1598dc9d unregister_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x15b0606e e820_any_mapped +EXPORT_SYMBOL_GPL vmlinux 0x15c11515 platform_device_register +EXPORT_SYMBOL_GPL vmlinux 0x16836e04 speedstep_detect_processor +EXPORT_SYMBOL_GPL vmlinux 0x16a62964 vring_new_virtqueue +EXPORT_SYMBOL_GPL vmlinux 0x16a87e11 sata_link_debounce +EXPORT_SYMBOL_GPL vmlinux 0x16d21dd9 anon_transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x16f58561 tcp_register_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0x16f76869 probe_kernel_read +EXPORT_SYMBOL_GPL vmlinux 0x171e225d tracepoint_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x172e72d4 vdso_enabled +EXPORT_SYMBOL_GPL vmlinux 0x1731b57e sysfs_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x174af677 ata_eh_analyze_ncq_error +EXPORT_SYMBOL_GPL vmlinux 0x1878f62b edac_err_assert +EXPORT_SYMBOL_GPL vmlinux 0x1881e867 cpufreq_cpu_put +EXPORT_SYMBOL_GPL vmlinux 0x18d53420 kgdb_register_io_module +EXPORT_SYMBOL_GPL vmlinux 0x1977fe58 pci_restore_msi_state +EXPORT_SYMBOL_GPL vmlinux 0x19f5e330 ata_port_desc +EXPORT_SYMBOL_GPL vmlinux 0x1a2f967c devres_remove +EXPORT_SYMBOL_GPL vmlinux 0x1a43c332 unregister_jprobe +EXPORT_SYMBOL_GPL vmlinux 0x1a938737 atomic_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x1aca44a7 attribute_container_unregister +EXPORT_SYMBOL_GPL vmlinux 0x1acda5b2 atomic_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x1af05e03 proc_net_remove +EXPORT_SYMBOL_GPL vmlinux 0x1b15a0e2 blk_queue_dma_drain +EXPORT_SYMBOL_GPL vmlinux 0x1b2137da crypto_larval_alloc +EXPORT_SYMBOL_GPL vmlinux 0x1b4e15fc sata_scr_read +EXPORT_SYMBOL_GPL vmlinux 0x1b9aca3f jprobe_return +EXPORT_SYMBOL_GPL vmlinux 0x1bbaca53 inotify_rm_wd +EXPORT_SYMBOL_GPL vmlinux 0x1bedc3f8 kill_pid_info_as_uid +EXPORT_SYMBOL_GPL vmlinux 0x1c87a811 __round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x1d023170 schedule_hrtimeout +EXPORT_SYMBOL_GPL vmlinux 0x1dd70100 dmi_walk +EXPORT_SYMBOL_GPL vmlinux 0x1e4957a6 inotify_rm_watch +EXPORT_SYMBOL_GPL vmlinux 0x1e7bbcb3 kernel_restart +EXPORT_SYMBOL_GPL vmlinux 0x1e88e089 blk_abort_queue +EXPORT_SYMBOL_GPL vmlinux 0x1eb9516e round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x1eca30a8 sata_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x1f014b7b ata_host_start +EXPORT_SYMBOL_GPL vmlinux 0x1f232cd1 kmap_atomic_pfn +EXPORT_SYMBOL_GPL vmlinux 0x1f8ec1b3 acpi_get_pci_rootbridge_handle +EXPORT_SYMBOL_GPL vmlinux 0x1f9a0fbf hpet_unregister_irq_handler +EXPORT_SYMBOL_GPL vmlinux 0x1fcece42 inet_twdr_twcal_tick +EXPORT_SYMBOL_GPL vmlinux 0x1fe444c1 ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0x201fd737 kernel_kobj +EXPORT_SYMBOL_GPL vmlinux 0x20577ea2 xfrm_ealg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x209301fd crypto_larval_lookup +EXPORT_SYMBOL_GPL vmlinux 0x20b82470 hpet_register_irq_handler +EXPORT_SYMBOL_GPL vmlinux 0x20bc3470 orderly_poweroff +EXPORT_SYMBOL_GPL vmlinux 0x20cd788f __ftrace_printk +EXPORT_SYMBOL_GPL vmlinux 0x20fffe9a platform_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x2134140f fib_rules_lookup +EXPORT_SYMBOL_GPL vmlinux 0x213c1513 klist_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x2145dea7 ata_eh_thaw_port +EXPORT_SYMBOL_GPL vmlinux 0x214d5b5f class_dev_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x218f52d7 inet_ctl_sock_create +EXPORT_SYMBOL_GPL vmlinux 0x21b03a91 unregister_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0x21e0a478 spi_sync +EXPORT_SYMBOL_GPL vmlinux 0x221f76a1 ata_sff_post_internal_cmd +EXPORT_SYMBOL_GPL vmlinux 0x22472bf4 xfrm_calg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x227ecb73 spi_add_device +EXPORT_SYMBOL_GPL vmlinux 0x2296c00d crypto_attr_u32 +EXPORT_SYMBOL_GPL vmlinux 0x22d1f635 __class_create +EXPORT_SYMBOL_GPL vmlinux 0x22d54add hvc_instantiate +EXPORT_SYMBOL_GPL vmlinux 0x22f4251d shmem_file_setup +EXPORT_SYMBOL_GPL vmlinux 0x230c09ee ata_sff_busy_sleep +EXPORT_SYMBOL_GPL vmlinux 0x23414e45 crypto_rng_type +EXPORT_SYMBOL_GPL vmlinux 0x23679939 __iowrite32_copy +EXPORT_SYMBOL_GPL vmlinux 0x236b46ff uart_set_options +EXPORT_SYMBOL_GPL vmlinux 0x23864ce7 cpuset_mem_spread_node +EXPORT_SYMBOL_GPL vmlinux 0x23e5974f debugfs_create_x8 +EXPORT_SYMBOL_GPL vmlinux 0x24196ba2 init_uts_ns +EXPORT_SYMBOL_GPL vmlinux 0x242dc5cb device_for_each_child +EXPORT_SYMBOL_GPL vmlinux 0x2447533c ktime_get_real +EXPORT_SYMBOL_GPL vmlinux 0x24eb7e32 leds_list +EXPORT_SYMBOL_GPL vmlinux 0x2504c7ef ata_sff_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0x25191161 crypto_alg_lookup +EXPORT_SYMBOL_GPL vmlinux 0x2562afee invalidate_inode_pages2_range +EXPORT_SYMBOL_GPL vmlinux 0x25a4f38b dev_attr_em_message +EXPORT_SYMBOL_GPL vmlinux 0x2685cccc inet_hash +EXPORT_SYMBOL_GPL vmlinux 0x26aee003 d_materialise_unique +EXPORT_SYMBOL_GPL vmlinux 0x26c90ea4 scsi_eh_get_sense +EXPORT_SYMBOL_GPL vmlinux 0x2769d64b vfs_removexattr +EXPORT_SYMBOL_GPL vmlinux 0x27d57acd sysdev_register +EXPORT_SYMBOL_GPL vmlinux 0x28088f0f pv_time_ops +EXPORT_SYMBOL_GPL vmlinux 0x2859a606 led_trigger_set_default +EXPORT_SYMBOL_GPL vmlinux 0x2866d8fc skb_pull_rcsum +EXPORT_SYMBOL_GPL vmlinux 0x28961016 init_user_ns +EXPORT_SYMBOL_GPL vmlinux 0x28a24255 ata_host_register +EXPORT_SYMBOL_GPL vmlinux 0x28a45d5d rtc_class_close +EXPORT_SYMBOL_GPL vmlinux 0x28bdacde hrtimer_start_range_ns +EXPORT_SYMBOL_GPL vmlinux 0x28d664ff __raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x28e23139 xfrm_probe_algs +EXPORT_SYMBOL_GPL vmlinux 0x292ea151 rtc_set_alarm +EXPORT_SYMBOL_GPL vmlinux 0x29307236 sysdev_store_ulong +EXPORT_SYMBOL_GPL vmlinux 0x29ef064b debugfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x29fbd591 debugfs_create_u8 +EXPORT_SYMBOL_GPL vmlinux 0x2a0ce8bc device_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x2a5e02b2 skcipher_geniv_exit +EXPORT_SYMBOL_GPL vmlinux 0x2a5e585d map_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x2a678a13 __suspend_report_result +EXPORT_SYMBOL_GPL vmlinux 0x2a916359 sdio_f0_readb +EXPORT_SYMBOL_GPL vmlinux 0x2b602581 cpufreq_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x2b7baf8d sdev_evt_send_simple +EXPORT_SYMBOL_GPL vmlinux 0x2b9f8e23 nf_net_ipv4_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x2bf8658a rtc_set_mmss +EXPORT_SYMBOL_GPL vmlinux 0x2bfc9e52 blkcipher_walk_phys +EXPORT_SYMBOL_GPL vmlinux 0x2c16ed76 xfrm_calg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x2c208607 power_supply_is_system_supplied +EXPORT_SYMBOL_GPL vmlinux 0x2c27ab1d bus_for_each_dev +EXPORT_SYMBOL_GPL vmlinux 0x2c6e5220 ata_sff_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x2c89ab13 unregister_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0x2cd5c63e driver_find +EXPORT_SYMBOL_GPL vmlinux 0x2d45bcda crypto_alg_sem +EXPORT_SYMBOL_GPL vmlinux 0x2d59c954 edac_handlers +EXPORT_SYMBOL_GPL vmlinux 0x2d9f2ce3 sched_clock_idle_wakeup_event +EXPORT_SYMBOL_GPL vmlinux 0x2dcf126a device_bind_driver +EXPORT_SYMBOL_GPL vmlinux 0x2e367af7 device_create_vargs +EXPORT_SYMBOL_GPL vmlinux 0x2e9b28ea pci_find_next_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0x2eb91dfe scatterwalk_map +EXPORT_SYMBOL_GPL vmlinux 0x2f47d8c7 cpufreq_frequency_get_table +EXPORT_SYMBOL_GPL vmlinux 0x2f6a54de ata_sas_port_stop +EXPORT_SYMBOL_GPL vmlinux 0x2f7e0679 tcp_reno_cong_avoid +EXPORT_SYMBOL_GPL vmlinux 0x2f7ee8b9 generic_fh_to_parent +EXPORT_SYMBOL_GPL vmlinux 0x3050148b sysfs_get_dirent +EXPORT_SYMBOL_GPL vmlinux 0x30a0ec13 get_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0x30c35925 destroy_workqueue +EXPORT_SYMBOL_GPL vmlinux 0x31192df0 crypto_ablkcipher_type +EXPORT_SYMBOL_GPL vmlinux 0x317d2b52 crypto_alloc_instance +EXPORT_SYMBOL_GPL vmlinux 0x317fe065 ata_timing_compute +EXPORT_SYMBOL_GPL vmlinux 0x318920b1 register_dock_notifier +EXPORT_SYMBOL_GPL vmlinux 0x31a5004e spi_new_device +EXPORT_SYMBOL_GPL vmlinux 0x31d140ef device_schedule_callback_owner +EXPORT_SYMBOL_GPL vmlinux 0x3213f8a0 acpi_bus_trim +EXPORT_SYMBOL_GPL vmlinux 0x3223d213 ata_host_alloc_pinfo +EXPORT_SYMBOL_GPL vmlinux 0x32292c6f alloc_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x32e98b5b attribute_container_find_class_device +EXPORT_SYMBOL_GPL vmlinux 0x334c0cea __ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0x336b05be pci_disable_pcie_error_reporting +EXPORT_SYMBOL_GPL vmlinux 0x33a47a0a disk_part_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x33b0316d inet_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0x33b6e752 acpi_ec_remove_query_handler +EXPORT_SYMBOL_GPL vmlinux 0x344fa6d1 devres_release_group +EXPORT_SYMBOL_GPL vmlinux 0x3459f2ca __inet_hash_nolisten +EXPORT_SYMBOL_GPL vmlinux 0x34ca3b54 sysfs_remove_link +EXPORT_SYMBOL_GPL vmlinux 0x34f43fc4 fib_rules_unregister +EXPORT_SYMBOL_GPL vmlinux 0x34f738bb sysfs_notify +EXPORT_SYMBOL_GPL vmlinux 0x35305ef2 vfs_test_lock +EXPORT_SYMBOL_GPL vmlinux 0x35412bfb dev_attr_em_message_type +EXPORT_SYMBOL_GPL vmlinux 0x35697743 inet6_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0x35d8c94a sdev_evt_alloc +EXPORT_SYMBOL_GPL vmlinux 0x361e2bcc save_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0x362e23ec call_rcu_bh +EXPORT_SYMBOL_GPL vmlinux 0x366a1956 __create_workqueue_key +EXPORT_SYMBOL_GPL vmlinux 0x3674509e part_round_stats +EXPORT_SYMBOL_GPL vmlinux 0x36880578 led_trigger_store +EXPORT_SYMBOL_GPL vmlinux 0x36de3c84 sock_prot_inuse_get +EXPORT_SYMBOL_GPL vmlinux 0x379c5e38 aead_geniv_alloc +EXPORT_SYMBOL_GPL vmlinux 0x3819ffa5 sdio_writel +EXPORT_SYMBOL_GPL vmlinux 0x383c6374 skcipher_geniv_init +EXPORT_SYMBOL_GPL vmlinux 0x383e100a ata_bmdma_stop +EXPORT_SYMBOL_GPL vmlinux 0x38418146 cpufreq_cpu_get +EXPORT_SYMBOL_GPL vmlinux 0x3895233b srcu_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x38a80f8b uhci_check_and_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0x38f35757 fsstack_copy_inode_size +EXPORT_SYMBOL_GPL vmlinux 0x39238b57 klist_del +EXPORT_SYMBOL_GPL vmlinux 0x39fdddb6 xfrm_audit_state_notfound +EXPORT_SYMBOL_GPL vmlinux 0x3a12df8b blkcipher_walk_virt_block +EXPORT_SYMBOL_GPL vmlinux 0x3a2a907d ata_sff_freeze +EXPORT_SYMBOL_GPL vmlinux 0x3a78ecf0 apply_to_page_range +EXPORT_SYMBOL_GPL vmlinux 0x3a7f8b86 __local_bh_enable +EXPORT_SYMBOL_GPL vmlinux 0x3a853842 inotify_init_watch +EXPORT_SYMBOL_GPL vmlinux 0x3ad3dc82 driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0x3aea4538 get_device +EXPORT_SYMBOL_GPL vmlinux 0x3b25c77f platform_get_resource_byname +EXPORT_SYMBOL_GPL vmlinux 0x3b711bda __inet_inherit_port +EXPORT_SYMBOL_GPL vmlinux 0x3ba794a8 ata_pci_device_suspend +EXPORT_SYMBOL_GPL vmlinux 0x3bd26673 class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x3be7af02 get_max_files +EXPORT_SYMBOL_GPL vmlinux 0x3c0233d6 tty_ldisc_deref +EXPORT_SYMBOL_GPL vmlinux 0x3c942368 profile_event_unregister +EXPORT_SYMBOL_GPL vmlinux 0x3ca01d26 __scsi_get_command +EXPORT_SYMBOL_GPL vmlinux 0x3cd06035 add_input_randomness +EXPORT_SYMBOL_GPL vmlinux 0x3cf4fe46 driver_attach +EXPORT_SYMBOL_GPL vmlinux 0x3cfedb3f register_pm_notifier +EXPORT_SYMBOL_GPL vmlinux 0x3d023d54 tcp_twsk_unique +EXPORT_SYMBOL_GPL vmlinux 0x3d05f228 __blk_put_request +EXPORT_SYMBOL_GPL vmlinux 0x3d40ac85 unregister_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0x3d899c5a crypto_mod_put +EXPORT_SYMBOL_GPL vmlinux 0x3dde7b0f ata_do_eh +EXPORT_SYMBOL_GPL vmlinux 0x3df4f63c vlan_dev_vlan_id +EXPORT_SYMBOL_GPL vmlinux 0x3e00a3c9 led_trigger_unregister_simple +EXPORT_SYMBOL_GPL vmlinux 0x3efb35c9 get_online_cpus +EXPORT_SYMBOL_GPL vmlinux 0x3f01570a probe_kernel_write +EXPORT_SYMBOL_GPL vmlinux 0x3f238101 dcookie_register +EXPORT_SYMBOL_GPL vmlinux 0x3f6c1356 dev_attr_sw_activity +EXPORT_SYMBOL_GPL vmlinux 0x3f6f7a07 ata_cable_40wire +EXPORT_SYMBOL_GPL vmlinux 0x3fe5716b fb_bl_default_curve +EXPORT_SYMBOL_GPL vmlinux 0x40380ad6 hrtimer_cancel +EXPORT_SYMBOL_GPL vmlinux 0x405f1433 d_obtain_alias +EXPORT_SYMBOL_GPL vmlinux 0x40af0dec ata_xfer_mode2mask +EXPORT_SYMBOL_GPL vmlinux 0x40cfecbf blk_queue_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0x41e08e02 bus_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x41f3cc90 xfrm_aalg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x421c4bc1 tracepoint_iter_stop +EXPORT_SYMBOL_GPL vmlinux 0x42b364ef scatterwalk_done +EXPORT_SYMBOL_GPL vmlinux 0x42b9b876 vlan_dev_real_dev +EXPORT_SYMBOL_GPL vmlinux 0x432e653f crypto_drop_spawn +EXPORT_SYMBOL_GPL vmlinux 0x43b1bae5 debugfs_create_blob +EXPORT_SYMBOL_GPL vmlinux 0x43b392b4 power_supply_changed +EXPORT_SYMBOL_GPL vmlinux 0x43bcd311 fib_rules_register +EXPORT_SYMBOL_GPL vmlinux 0x43f56e82 ata_xfer_mode2shift +EXPORT_SYMBOL_GPL vmlinux 0x445ce03a raw_seq_next +EXPORT_SYMBOL_GPL vmlinux 0x4471f2c3 debugfs_create_u32 +EXPORT_SYMBOL_GPL vmlinux 0x44a65d5c lock_policy_rwsem_read +EXPORT_SYMBOL_GPL vmlinux 0x44e2b7cb register_virtio_driver +EXPORT_SYMBOL_GPL vmlinux 0x457594fa crypto_alg_list +EXPORT_SYMBOL_GPL vmlinux 0x458db457 ata_host_activate +EXPORT_SYMBOL_GPL vmlinux 0x459a0cbd transport_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0x45a08cd6 seq_release_net +EXPORT_SYMBOL_GPL vmlinux 0x45bf1ff3 crypto_inc +EXPORT_SYMBOL_GPL vmlinux 0x4638042c sata_pmp_qc_defer_cmd_switch +EXPORT_SYMBOL_GPL vmlinux 0x46402cdb bus_get_kset +EXPORT_SYMBOL_GPL vmlinux 0x4658276b platform_add_devices +EXPORT_SYMBOL_GPL vmlinux 0x4689bc88 klist_node_attached +EXPORT_SYMBOL_GPL vmlinux 0x4881e846 sdio_memcpy_fromio +EXPORT_SYMBOL_GPL vmlinux 0x48ed4ac9 scsi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x48f1ddae copy_fs_struct +EXPORT_SYMBOL_GPL vmlinux 0x49576a88 debugfs_remove +EXPORT_SYMBOL_GPL vmlinux 0x499043d3 crypto_init_queue +EXPORT_SYMBOL_GPL vmlinux 0x49c0fb6c blk_rq_cur_bytes +EXPORT_SYMBOL_GPL vmlinux 0x49ef15d2 spi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x4a4e108c sysfs_add_file_to_group +EXPORT_SYMBOL_GPL vmlinux 0x4a7e30d9 marker_probe_unregister_private_data +EXPORT_SYMBOL_GPL vmlinux 0x4ae2986f user_describe +EXPORT_SYMBOL_GPL vmlinux 0x4afa2cca ata_pci_sff_activate_host +EXPORT_SYMBOL_GPL vmlinux 0x4b3b34f0 crypto_larval_kill +EXPORT_SYMBOL_GPL vmlinux 0x4b682b4b drop_file_write_access +EXPORT_SYMBOL_GPL vmlinux 0x4baab221 register_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0x4bb42b4f crypto_givcipher_type +EXPORT_SYMBOL_GPL vmlinux 0x4bd03660 macvlan_handle_frame_hook +EXPORT_SYMBOL_GPL vmlinux 0x4c01f313 rt_mutex_trylock +EXPORT_SYMBOL_GPL vmlinux 0x4c59591c rtc_irq_unregister +EXPORT_SYMBOL_GPL vmlinux 0x4c5ec47a tcp_unregister_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0x4c759827 byte_rev_table +EXPORT_SYMBOL_GPL vmlinux 0x4c9dbfdd disk_get_part +EXPORT_SYMBOL_GPL vmlinux 0x4cd8d832 fnotify_change +EXPORT_SYMBOL_GPL vmlinux 0x4cdb4bd0 speedstep_get_processor_frequency +EXPORT_SYMBOL_GPL vmlinux 0x4cdf43d2 __mmdrop +EXPORT_SYMBOL_GPL vmlinux 0x4ceaeaa7 get_user_pages_fast +EXPORT_SYMBOL_GPL vmlinux 0x4dab8b0d queue_work +EXPORT_SYMBOL_GPL vmlinux 0x4e0f45df kobject_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0x4e6814b4 device_attach +EXPORT_SYMBOL_GPL vmlinux 0x4f066318 simple_attr_read +EXPORT_SYMBOL_GPL vmlinux 0x4f83067e proc_net_fops_create +EXPORT_SYMBOL_GPL vmlinux 0x4fbc29d8 __cpufreq_driver_target +EXPORT_SYMBOL_GPL vmlinux 0x4fcc4a56 ata_bus_reset +EXPORT_SYMBOL_GPL vmlinux 0x4fd1723d fsstack_copy_attr_all +EXPORT_SYMBOL_GPL vmlinux 0x4fdc945d sata_deb_timing_normal +EXPORT_SYMBOL_GPL vmlinux 0x5014017e ata_bmdma_status +EXPORT_SYMBOL_GPL vmlinux 0x50686ffe xfrm_output +EXPORT_SYMBOL_GPL vmlinux 0x5086ac3a alg_test +EXPORT_SYMBOL_GPL vmlinux 0x50b67174 xfrm_ealg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x50e7193a __i2c_first_dynamic_bus_num +EXPORT_SYMBOL_GPL vmlinux 0x50fad434 round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x5108b3fc acpi_os_map_memory +EXPORT_SYMBOL_GPL vmlinux 0x511f3e1f apic_ops +EXPORT_SYMBOL_GPL vmlinux 0x517d2c14 register_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0x518c2fc6 hpet_rtc_dropped_irq +EXPORT_SYMBOL_GPL vmlinux 0x51af5cdf raw_unhash_sk +EXPORT_SYMBOL_GPL vmlinux 0x51dd6488 xfrm_aalg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x51e25191 spi_unregister_master +EXPORT_SYMBOL_GPL vmlinux 0x520d64ff sg_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x526ea172 user_destroy +EXPORT_SYMBOL_GPL vmlinux 0x52d111ea pm_qos_update_requirement +EXPORT_SYMBOL_GPL vmlinux 0x53196461 elv_register +EXPORT_SYMBOL_GPL vmlinux 0x53358276 sis_info133_for_sata +EXPORT_SYMBOL_GPL vmlinux 0x53614269 get_cpu_idle_time_us +EXPORT_SYMBOL_GPL vmlinux 0x5372dede unregister_acpi_bus_notifier +EXPORT_SYMBOL_GPL vmlinux 0x53986488 register_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x53d0af47 rt_mutex_lock_interruptible +EXPORT_SYMBOL_GPL vmlinux 0x545a7923 anon_transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5498c8f6 sdio_readb +EXPORT_SYMBOL_GPL vmlinux 0x54be3de0 fb_deferred_io_fsync +EXPORT_SYMBOL_GPL vmlinux 0x553c44d8 ata_sff_exec_command +EXPORT_SYMBOL_GPL vmlinux 0x554a1766 skb_partial_csum_set +EXPORT_SYMBOL_GPL vmlinux 0x55dcad96 crypto_spawn_tfm +EXPORT_SYMBOL_GPL vmlinux 0x5601ceb5 raw_seq_open +EXPORT_SYMBOL_GPL vmlinux 0x56292f36 pci_reset_function +EXPORT_SYMBOL_GPL vmlinux 0x56398615 mark_tsc_unstable +EXPORT_SYMBOL_GPL vmlinux 0x5641485b tty_termios_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x56d9a59f platform_driver_register +EXPORT_SYMBOL_GPL vmlinux 0x573ba554 disk_part_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x577e40e7 ata_pci_bmdma_init +EXPORT_SYMBOL_GPL vmlinux 0x579e0bf5 rtnl_unregister_all +EXPORT_SYMBOL_GPL vmlinux 0x57b0afb7 pci_bus_max_busnr +EXPORT_SYMBOL_GPL vmlinux 0x57fe37a5 platform_device_add_resources +EXPORT_SYMBOL_GPL vmlinux 0x582ce91a transport_setup_device +EXPORT_SYMBOL_GPL vmlinux 0x58447740 sysdev_show_ulong +EXPORT_SYMBOL_GPL vmlinux 0x587e4bff led_trigger_unregister +EXPORT_SYMBOL_GPL vmlinux 0x589123e1 devm_kzalloc +EXPORT_SYMBOL_GPL vmlinux 0x58c0ff21 user_instantiate +EXPORT_SYMBOL_GPL vmlinux 0x58e83570 pci_test_config_bits +EXPORT_SYMBOL_GPL vmlinux 0x592ad7d0 ata_scsi_simulate +EXPORT_SYMBOL_GPL vmlinux 0x597f3bc3 marker_get_private_data +EXPORT_SYMBOL_GPL vmlinux 0x59903dbc device_register +EXPORT_SYMBOL_GPL vmlinux 0x59fbcb6e inet_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0x5a4407aa bdi_writeout_inc +EXPORT_SYMBOL_GPL vmlinux 0x5a7bfe41 crypto_probing_notify +EXPORT_SYMBOL_GPL vmlinux 0x5a97eadc ata_acpi_stm +EXPORT_SYMBOL_GPL vmlinux 0x5ac8c6b7 unregister_kprobes +EXPORT_SYMBOL_GPL vmlinux 0x5b4188c8 xfrm_audit_policy_delete +EXPORT_SYMBOL_GPL vmlinux 0x5bfc03c3 unregister_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5bfdc369 ata_host_detach +EXPORT_SYMBOL_GPL vmlinux 0x5c1a9929 device_initialize +EXPORT_SYMBOL_GPL vmlinux 0x5ca73444 devres_close_group +EXPORT_SYMBOL_GPL vmlinux 0x5ca80ebb sdio_set_block_size +EXPORT_SYMBOL_GPL vmlinux 0x5cfcf0f1 percpu_free +EXPORT_SYMBOL_GPL vmlinux 0x5d0f6f57 kbd_table +EXPORT_SYMBOL_GPL vmlinux 0x5d276e8f nf_unregister_queue_handlers +EXPORT_SYMBOL_GPL vmlinux 0x5d424267 raw_hash_sk +EXPORT_SYMBOL_GPL vmlinux 0x5d51bcf7 scatterwalk_start +EXPORT_SYMBOL_GPL vmlinux 0x5d730e7b raw_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5d87c067 register_acpi_bus_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5d937446 platform_device_put +EXPORT_SYMBOL_GPL vmlinux 0x5dd67618 register_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5e379e58 xfrm_inner_extract_output +EXPORT_SYMBOL_GPL vmlinux 0x5ed71e34 raw_seq_stop +EXPORT_SYMBOL_GPL vmlinux 0x5f28d05e ata_bmdma_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x5f2da8c4 check_tsc_unstable +EXPORT_SYMBOL_GPL vmlinux 0x5f39c09b blk_queue_rq_timeout +EXPORT_SYMBOL_GPL vmlinux 0x5f5966d0 bd_claim_by_disk +EXPORT_SYMBOL_GPL vmlinux 0x605ff123 klist_add_tail +EXPORT_SYMBOL_GPL vmlinux 0x6068a609 ata_pci_device_do_resume +EXPORT_SYMBOL_GPL vmlinux 0x6087d5b2 rt_mutex_unlock +EXPORT_SYMBOL_GPL vmlinux 0x6091797f synchronize_rcu +EXPORT_SYMBOL_GPL vmlinux 0x60a13e90 rcu_barrier +EXPORT_SYMBOL_GPL vmlinux 0x60e65389 pciserial_remove_ports +EXPORT_SYMBOL_GPL vmlinux 0x611cb0d7 bus_for_each_drv +EXPORT_SYMBOL_GPL vmlinux 0x612f8183 inet_csk_clone +EXPORT_SYMBOL_GPL vmlinux 0x6131a5af inet6_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0x613f7a77 page_cache_sync_readahead +EXPORT_SYMBOL_GPL vmlinux 0x61414388 security_inode_permission +EXPORT_SYMBOL_GPL vmlinux 0x615784ef firmware_kobj +EXPORT_SYMBOL_GPL vmlinux 0x616d3eb2 devres_alloc +EXPORT_SYMBOL_GPL vmlinux 0x61f1cdbd device_del +EXPORT_SYMBOL_GPL vmlinux 0x6240dabf crypto_alloc_ablkcipher +EXPORT_SYMBOL_GPL vmlinux 0x624aeea8 pci_set_pcie_reset_state +EXPORT_SYMBOL_GPL vmlinux 0x633fb2e9 unregister_virtio_driver +EXPORT_SYMBOL_GPL vmlinux 0x63abdb65 sock_prot_inuse_add +EXPORT_SYMBOL_GPL vmlinux 0x63ae27d6 add_nops +EXPORT_SYMBOL_GPL vmlinux 0x63e3009d ata_acpi_gtm +EXPORT_SYMBOL_GPL vmlinux 0x6436e2c1 sdio_release_irq +EXPORT_SYMBOL_GPL vmlinux 0x645ce0fc platform_get_resource +EXPORT_SYMBOL_GPL vmlinux 0x6463219e sdio_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x646e9467 sysdev_unregister +EXPORT_SYMBOL_GPL vmlinux 0x64bd072e crypto_alg_mod_lookup +EXPORT_SYMBOL_GPL vmlinux 0x657033f5 unregister_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0x65a8ef2c input_ff_erase +EXPORT_SYMBOL_GPL vmlinux 0x65ccb6f0 call_netevent_notifiers +EXPORT_SYMBOL_GPL vmlinux 0x65f50ba1 zap_vma_ptes +EXPORT_SYMBOL_GPL vmlinux 0x6600c1ce bus_rescan_devices +EXPORT_SYMBOL_GPL vmlinux 0x6610ad99 synchronize_srcu +EXPORT_SYMBOL_GPL vmlinux 0x661601de sprint_symbol +EXPORT_SYMBOL_GPL vmlinux 0x66501588 platform_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0x668402aa crypto_put_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x66b2a859 nr_free_buffer_pages +EXPORT_SYMBOL_GPL vmlinux 0x66d87d38 symbol_put_addr +EXPORT_SYMBOL_GPL vmlinux 0x67955ce6 profile_hits +EXPORT_SYMBOL_GPL vmlinux 0x686456c9 sata_std_hardreset +EXPORT_SYMBOL_GPL vmlinux 0x686c703f xfrm_count_auth_supported +EXPORT_SYMBOL_GPL vmlinux 0x6875d38c klist_next +EXPORT_SYMBOL_GPL vmlinux 0x6892088c unregister_pm_notifier +EXPORT_SYMBOL_GPL vmlinux 0x69349c63 schedule_hrtimeout_range +EXPORT_SYMBOL_GPL vmlinux 0x698134bd class_destroy +EXPORT_SYMBOL_GPL vmlinux 0x69821f0e isa_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x69b456ae blk_trace_remove +EXPORT_SYMBOL_GPL vmlinux 0x69e9a2cb ata_scsi_slave_config +EXPORT_SYMBOL_GPL vmlinux 0x6a2d9281 pci_block_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0x6b00adc7 __inet_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0x6b3195c8 net_assign_generic +EXPORT_SYMBOL_GPL vmlinux 0x6b62d934 class_dev_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x6bb3bb80 pciserial_resume_ports +EXPORT_SYMBOL_GPL vmlinux 0x6bd4e5c0 inet_twsk_purge +EXPORT_SYMBOL_GPL vmlinux 0x6bd65d93 tcp_reno_min_cwnd +EXPORT_SYMBOL_GPL vmlinux 0x6c11059b __srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x6c21da4e xfrm_audit_state_replay_overflow +EXPORT_SYMBOL_GPL vmlinux 0x6c49c4f2 clockevents_notify +EXPORT_SYMBOL_GPL vmlinux 0x6c4d0726 dequeue_signal +EXPORT_SYMBOL_GPL vmlinux 0x6c8ee66f blk_insert_cloned_request +EXPORT_SYMBOL_GPL vmlinux 0x6cc52be9 aead_geniv_exit +EXPORT_SYMBOL_GPL vmlinux 0x6d2fc5a6 net_namespace_list +EXPORT_SYMBOL_GPL vmlinux 0x6d35b120 anon_inode_getfd +EXPORT_SYMBOL_GPL vmlinux 0x6d3a2770 crypto_attr_alg +EXPORT_SYMBOL_GPL vmlinux 0x6e491cc3 debugfs_remove_recursive +EXPORT_SYMBOL_GPL vmlinux 0x6e85c87b disk_map_sector_rcu +EXPORT_SYMBOL_GPL vmlinux 0x6eb7a90f sdio_release_host +EXPORT_SYMBOL_GPL vmlinux 0x6f1cbd9a vfs_cancel_lock +EXPORT_SYMBOL_GPL vmlinux 0x6f296401 ata_link_abort +EXPORT_SYMBOL_GPL vmlinux 0x6f2aea35 sdio_claim_host +EXPORT_SYMBOL_GPL vmlinux 0x6f9c2efe marker_probe_cb +EXPORT_SYMBOL_GPL vmlinux 0x6fbe78b7 dma_get_required_mask +EXPORT_SYMBOL_GPL vmlinux 0x6fc0b49d debugfs_create_u64 +EXPORT_SYMBOL_GPL vmlinux 0x6ff607b6 crypto_get_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x702a12cc klist_iter_init_node +EXPORT_SYMBOL_GPL vmlinux 0x7037d79d k8_flush_garts +EXPORT_SYMBOL_GPL vmlinux 0x706b3a33 cpufreq_frequency_table_get_attr +EXPORT_SYMBOL_GPL vmlinux 0x707e374d inotify_remove_watch_locked +EXPORT_SYMBOL_GPL vmlinux 0x707ff1bb ata_xfer_mask2mode +EXPORT_SYMBOL_GPL vmlinux 0x7125ddeb device_rename +EXPORT_SYMBOL_GPL vmlinux 0x712e5387 ata_bmdma_setup +EXPORT_SYMBOL_GPL vmlinux 0x713dcb96 pci_unblock_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0x7154578d ip_route_output_flow +EXPORT_SYMBOL_GPL vmlinux 0x71568e0e sdio_writesb +EXPORT_SYMBOL_GPL vmlinux 0x71afd509 tracepoint_iter_reset +EXPORT_SYMBOL_GPL vmlinux 0x71c8bc95 kgdb_unregister_io_module +EXPORT_SYMBOL_GPL vmlinux 0x71cbbc31 __blk_add_trace +EXPORT_SYMBOL_GPL vmlinux 0x7233dcbf dev_attr_unload_heads +EXPORT_SYMBOL_GPL vmlinux 0x723af766 crypto_init_spawn +EXPORT_SYMBOL_GPL vmlinux 0x7278d328 all_vm_events +EXPORT_SYMBOL_GPL vmlinux 0x729c7d07 pci_bus_add_device +EXPORT_SYMBOL_GPL vmlinux 0x72a91ea5 rtc_irq_set_freq +EXPORT_SYMBOL_GPL vmlinux 0x72bb390d queue_delayed_work_on +EXPORT_SYMBOL_GPL vmlinux 0x72e467bb inet_twsk_alloc +EXPORT_SYMBOL_GPL vmlinux 0x7306cbb4 kobject_rename +EXPORT_SYMBOL_GPL vmlinux 0x73a48b4a ata_sff_std_ports +EXPORT_SYMBOL_GPL vmlinux 0x73b1f76d do_posix_clock_nosettime +EXPORT_SYMBOL_GPL vmlinux 0x73d75546 cpufreq_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x73e6a8ec ata_sg_init +EXPORT_SYMBOL_GPL vmlinux 0x7431a177 find_get_pid +EXPORT_SYMBOL_GPL vmlinux 0x743a165e ata_pack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0x74abdafa task_handoff_register +EXPORT_SYMBOL_GPL vmlinux 0x74d61a4d get_dcookie +EXPORT_SYMBOL_GPL vmlinux 0x74deb10c used_vectors +EXPORT_SYMBOL_GPL vmlinux 0x7521afb6 leave_mm +EXPORT_SYMBOL_GPL vmlinux 0x7568b92e register_jprobes +EXPORT_SYMBOL_GPL vmlinux 0x75c8a11c inet_twdr_twkill_work +EXPORT_SYMBOL_GPL vmlinux 0x75d039dc sdio_align_size +EXPORT_SYMBOL_GPL vmlinux 0x75e532aa single_open_net +EXPORT_SYMBOL_GPL vmlinux 0x75e8f3c3 crypto_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x76416d19 sdio_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x7712581f cpuidle_enable_device +EXPORT_SYMBOL_GPL vmlinux 0x7751aae0 user_update +EXPORT_SYMBOL_GPL vmlinux 0x77598c45 debugfs_create_bool +EXPORT_SYMBOL_GPL vmlinux 0x77a3436f sysdev_show_int +EXPORT_SYMBOL_GPL vmlinux 0x7804f40d klist_remove +EXPORT_SYMBOL_GPL vmlinux 0x788a2978 sysfs_schedule_callback +EXPORT_SYMBOL_GPL vmlinux 0x7894227d preempt_notifier_unregister +EXPORT_SYMBOL_GPL vmlinux 0x78b2bb86 tcp_set_state +EXPORT_SYMBOL_GPL vmlinux 0x79045c2d bus_create_file +EXPORT_SYMBOL_GPL vmlinux 0x7923cfdb ata_ehi_clear_desc +EXPORT_SYMBOL_GPL vmlinux 0x792972c7 blk_queue_rq_timed_out +EXPORT_SYMBOL_GPL vmlinux 0x797423ac klist_add_before +EXPORT_SYMBOL_GPL vmlinux 0x79ca56a6 ata_sas_port_start +EXPORT_SYMBOL_GPL vmlinux 0x7a3070dd cpufreq_frequency_table_verify +EXPORT_SYMBOL_GPL vmlinux 0x7a4c1438 pv_info +EXPORT_SYMBOL_GPL vmlinux 0x7a8cb59e tcp_get_info +EXPORT_SYMBOL_GPL vmlinux 0x7ad708ff debugfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0x7ae1ae8e cpufreq_frequency_table_put_attr +EXPORT_SYMBOL_GPL vmlinux 0x7b0aec27 platform_driver_probe +EXPORT_SYMBOL_GPL vmlinux 0x7b1d544d edac_handler_set +EXPORT_SYMBOL_GPL vmlinux 0x7b2c1c7d class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x7b6ac07c ata_port_start +EXPORT_SYMBOL_GPL vmlinux 0x7b7a7535 pci_cleanup_aer_uncorrect_error_status +EXPORT_SYMBOL_GPL vmlinux 0x7b7e282a kern_mount_data +EXPORT_SYMBOL_GPL vmlinux 0x7b858e5c ata_acpi_cbl_80wire +EXPORT_SYMBOL_GPL vmlinux 0x7b8a702d sdio_readsb +EXPORT_SYMBOL_GPL vmlinux 0x7be15cfc ata_acpi_gtm_xfermask +EXPORT_SYMBOL_GPL vmlinux 0x7bedecd5 blk_trace_startstop +EXPORT_SYMBOL_GPL vmlinux 0x7c5a5b8f ata_sff_check_status +EXPORT_SYMBOL_GPL vmlinux 0x7c62982d attribute_container_classdev_to_container +EXPORT_SYMBOL_GPL vmlinux 0x7ca17842 bus_get_device_klist +EXPORT_SYMBOL_GPL vmlinux 0x7d803de8 sdio_claim_irq +EXPORT_SYMBOL_GPL vmlinux 0x7d85cd4c bus_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x7da6573d sdev_evt_send +EXPORT_SYMBOL_GPL vmlinux 0x7da8d037 marker_probe_register +EXPORT_SYMBOL_GPL vmlinux 0x7dc5d0b6 crypto_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x7e23cc10 alloc_page_buffers +EXPORT_SYMBOL_GPL vmlinux 0x7e275ea8 scsi_complete_async_scans +EXPORT_SYMBOL_GPL vmlinux 0x7e4dfca1 rtc_irq_register +EXPORT_SYMBOL_GPL vmlinux 0x7e698a51 unregister_jprobes +EXPORT_SYMBOL_GPL vmlinux 0x7e9f1a7d skcipher_geniv_alloc +EXPORT_SYMBOL_GPL vmlinux 0x7ea8a934 cpuidle_unregister_device +EXPORT_SYMBOL_GPL vmlinux 0x7ef2bec8 ip_local_out +EXPORT_SYMBOL_GPL vmlinux 0x7f09eff6 bus_register +EXPORT_SYMBOL_GPL vmlinux 0x7f19c836 unlock_policy_rwsem_write +EXPORT_SYMBOL_GPL vmlinux 0x7fa47e11 put_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0x7fdc9965 spi_alloc_master +EXPORT_SYMBOL_GPL vmlinux 0x7ff10ccf raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x8029888f ata_pci_device_resume +EXPORT_SYMBOL_GPL vmlinux 0x8039d043 selinux_secmark_relabel_packet_permission +EXPORT_SYMBOL_GPL vmlinux 0x8045bc6f register_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0x8058f02c devres_open_group +EXPORT_SYMBOL_GPL vmlinux 0x805a3cfc ata_sas_slave_configure +EXPORT_SYMBOL_GPL vmlinux 0x808ec1a3 crypto_alg_tested +EXPORT_SYMBOL_GPL vmlinux 0x80a580da class_find_device +EXPORT_SYMBOL_GPL vmlinux 0x80b5ad63 inet_twsk_schedule +EXPORT_SYMBOL_GPL vmlinux 0x80ee55c3 selinux_secmark_refcount_inc +EXPORT_SYMBOL_GPL vmlinux 0x812894c5 ata_port_pbar_desc +EXPORT_SYMBOL_GPL vmlinux 0x812c7fac hrtimer_try_to_cancel +EXPORT_SYMBOL_GPL vmlinux 0x816b352c preempt_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x8182bbb3 pci_find_ext_capability +EXPORT_SYMBOL_GPL vmlinux 0x81d63043 relay_reset +EXPORT_SYMBOL_GPL vmlinux 0x8247ef3e skb_segment +EXPORT_SYMBOL_GPL vmlinux 0x8259b1ca inotify_inode_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x826360fd do_posix_clock_nonanosleep +EXPORT_SYMBOL_GPL vmlinux 0x8268ead4 iounmap_atomic +EXPORT_SYMBOL_GPL vmlinux 0x8278a3c8 invalidate_inode_pages2 +EXPORT_SYMBOL_GPL vmlinux 0x82cfe8ee sdio_writew +EXPORT_SYMBOL_GPL vmlinux 0x82d79b51 sysctl_vfs_cache_pressure +EXPORT_SYMBOL_GPL vmlinux 0x82f27386 find_vpid +EXPORT_SYMBOL_GPL vmlinux 0x82f5273b register_timer_hook +EXPORT_SYMBOL_GPL vmlinux 0x83465554 sysdev_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x843786ad blkcipher_walk_done +EXPORT_SYMBOL_GPL vmlinux 0x84834145 hrtimer_get_remaining +EXPORT_SYMBOL_GPL vmlinux 0x850e9f0f sysdev_class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x852fd873 led_trigger_register_simple +EXPORT_SYMBOL_GPL vmlinux 0x853827e6 page_mkclean +EXPORT_SYMBOL_GPL vmlinux 0x857d3281 cpufreq_unregister_governor +EXPORT_SYMBOL_GPL vmlinux 0x85a31931 mm_kobj +EXPORT_SYMBOL_GPL vmlinux 0x85a6311b inet_csk_route_req +EXPORT_SYMBOL_GPL vmlinux 0x85c10896 rcu_batches_completed_bh +EXPORT_SYMBOL_GPL vmlinux 0x85d7edfd hpet_set_periodic_freq +EXPORT_SYMBOL_GPL vmlinux 0x85e5a3db ktime_get_ts +EXPORT_SYMBOL_GPL vmlinux 0x8632a5d3 queue_work_on +EXPORT_SYMBOL_GPL vmlinux 0x86430e6b input_class +EXPORT_SYMBOL_GPL vmlinux 0x8661384b unregister_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0x867c684a setup_APIC_eilvt_ibs +EXPORT_SYMBOL_GPL vmlinux 0x8681eeb5 skb_to_sgvec +EXPORT_SYMBOL_GPL vmlinux 0x868784cb __symbol_get +EXPORT_SYMBOL_GPL vmlinux 0x8690f1f4 xfrm_audit_state_delete +EXPORT_SYMBOL_GPL vmlinux 0x86b1667d hwrng_unregister +EXPORT_SYMBOL_GPL vmlinux 0x870404b8 crypto_chain +EXPORT_SYMBOL_GPL vmlinux 0x873fbaea edac_atomic_assert_error +EXPORT_SYMBOL_GPL vmlinux 0x87754115 raw_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x878057cd crypto_hash_walk_first +EXPORT_SYMBOL_GPL vmlinux 0x880b189a __atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x8810ad5e crypto_xor +EXPORT_SYMBOL_GPL vmlinux 0x88251a24 blk_update_request +EXPORT_SYMBOL_GPL vmlinux 0x882c7a09 hwmon_device_register +EXPORT_SYMBOL_GPL vmlinux 0x883ef9b3 mnt_drop_write +EXPORT_SYMBOL_GPL vmlinux 0x885142a6 nf_net_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x886736fc olpc_platform_info +EXPORT_SYMBOL_GPL vmlinux 0x889595b3 ata_sff_port_start +EXPORT_SYMBOL_GPL vmlinux 0x893d9076 queue_delayed_work +EXPORT_SYMBOL_GPL vmlinux 0x895b090e ata_sas_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0x8992a3c3 sata_link_hardreset +EXPORT_SYMBOL_GPL vmlinux 0x89a40cbf scsi_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0x89cb5811 sk_setup_caps +EXPORT_SYMBOL_GPL vmlinux 0x8a00fb14 disk_part_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x8abed13d xfrm_aead_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x8aede83a elv_unregister +EXPORT_SYMBOL_GPL vmlinux 0x8afb3228 platform_get_irq_byname +EXPORT_SYMBOL_GPL vmlinux 0x8b028e32 class_interface_register +EXPORT_SYMBOL_GPL vmlinux 0x8b752ac1 ata_tf_to_fis +EXPORT_SYMBOL_GPL vmlinux 0x8bb17ba7 register_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0x8be6c094 tcp_is_cwnd_limited +EXPORT_SYMBOL_GPL vmlinux 0x8bfb6808 device_move +EXPORT_SYMBOL_GPL vmlinux 0x8c8801b7 rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x8c938899 __blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0x8cd1ed5c kobject_init_and_add +EXPORT_SYMBOL_GPL vmlinux 0x8d348e05 screen_glyph +EXPORT_SYMBOL_GPL vmlinux 0x8d87a337 debugfs_create_x16 +EXPORT_SYMBOL_GPL vmlinux 0x8da17b42 scatterwalk_copychunks +EXPORT_SYMBOL_GPL vmlinux 0x8dd78d25 blocking_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x8dfafcd5 ata_eh_freeze_port +EXPORT_SYMBOL_GPL vmlinux 0x8e65b9d0 ata_eh_qc_retry +EXPORT_SYMBOL_GPL vmlinux 0x8e940877 ata_host_init +EXPORT_SYMBOL_GPL vmlinux 0x8eb58c6e __wake_up_sync +EXPORT_SYMBOL_GPL vmlinux 0x8f0bb4d3 driver_add_kobj +EXPORT_SYMBOL_GPL vmlinux 0x8f189080 generic_fh_to_dentry +EXPORT_SYMBOL_GPL vmlinux 0x8f685b1c nf_unregister_afinfo +EXPORT_SYMBOL_GPL vmlinux 0x8f6cee77 __round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x8f777e2c do_add_mount +EXPORT_SYMBOL_GPL vmlinux 0x8f8a0f37 blk_set_cmd_filter_defaults +EXPORT_SYMBOL_GPL vmlinux 0x8f951728 ata_pci_sff_init_host +EXPORT_SYMBOL_GPL vmlinux 0x8fab745e tty_get_pgrp +EXPORT_SYMBOL_GPL vmlinux 0x8ff8dbcd blocking_notifier_chain_cond_register +EXPORT_SYMBOL_GPL vmlinux 0x9009602a acpi_bus_get_ejd +EXPORT_SYMBOL_GPL vmlinux 0x90439332 cpufreq_driver_target +EXPORT_SYMBOL_GPL vmlinux 0x906b805e srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x90a1004a crypto_has_alg +EXPORT_SYMBOL_GPL vmlinux 0x90f526ec crypto_alloc_base +EXPORT_SYMBOL_GPL vmlinux 0x90fc8ab3 vfs_setxattr +EXPORT_SYMBOL_GPL vmlinux 0x911d6916 ata_sff_tf_load +EXPORT_SYMBOL_GPL vmlinux 0x91266918 crypto_free_tfm +EXPORT_SYMBOL_GPL vmlinux 0x914749a9 ata_sff_dev_select +EXPORT_SYMBOL_GPL vmlinux 0x9159b9d6 profile_event_register +EXPORT_SYMBOL_GPL vmlinux 0x916ebf9d ata_sff_host_intr +EXPORT_SYMBOL_GPL vmlinux 0x91b28e29 device_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x91b2d653 platform_device_add +EXPORT_SYMBOL_GPL vmlinux 0x91cb41a7 ata_link_offline +EXPORT_SYMBOL_GPL vmlinux 0x91dacaa2 acpi_processor_ffh_cstate_probe +EXPORT_SYMBOL_GPL vmlinux 0x9241c3ee device_power_down +EXPORT_SYMBOL_GPL vmlinux 0x92445aee hrtimer_get_res +EXPORT_SYMBOL_GPL vmlinux 0x92c84293 bd_release_from_disk +EXPORT_SYMBOL_GPL vmlinux 0x92fb217b dcookie_unregister +EXPORT_SYMBOL_GPL vmlinux 0x931eb258 rtnl_kill_links +EXPORT_SYMBOL_GPL vmlinux 0x933740ca cancel_work_sync +EXPORT_SYMBOL_GPL vmlinux 0x93537618 led_trigger_register +EXPORT_SYMBOL_GPL vmlinux 0x93bcc9ba inet_csk_listen_stop +EXPORT_SYMBOL_GPL vmlinux 0x93c6be31 inet_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0x93d2422d snmp_mib_free +EXPORT_SYMBOL_GPL vmlinux 0x93f41648 audit_log_untrustedstring +EXPORT_SYMBOL_GPL vmlinux 0x93f7abe0 rt_mutex_lock +EXPORT_SYMBOL_GPL vmlinux 0x941edb2f sysdev_class_register +EXPORT_SYMBOL_GPL vmlinux 0x942c1704 cleanup_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x9495825e ata_sas_port_alloc +EXPORT_SYMBOL_GPL vmlinux 0x94a68723 ata_scsi_slave_destroy +EXPORT_SYMBOL_GPL vmlinux 0x94dc62d2 ata_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x952664c5 do_exit +EXPORT_SYMBOL_GPL vmlinux 0x954591ed cpuidle_disable_device +EXPORT_SYMBOL_GPL vmlinux 0x9577271c hpet_rtc_interrupt +EXPORT_SYMBOL_GPL vmlinux 0x95b91102 ata_bmdma_start +EXPORT_SYMBOL_GPL vmlinux 0x95d8f0cf ata_std_qc_defer +EXPORT_SYMBOL_GPL vmlinux 0x961a8cd3 unlock_policy_rwsem_read +EXPORT_SYMBOL_GPL vmlinux 0x966aec76 sata_pmp_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x9683ab18 led_trigger_remove +EXPORT_SYMBOL_GPL vmlinux 0x96c7aa0c devres_remove_group +EXPORT_SYMBOL_GPL vmlinux 0x96cbcf31 pm_qos_add_notifier +EXPORT_SYMBOL_GPL vmlinux 0x971897c1 sata_scr_valid +EXPORT_SYMBOL_GPL vmlinux 0x97e88c54 rtc_class_open +EXPORT_SYMBOL_GPL vmlinux 0x97ea3d8e ata_pci_device_do_suspend +EXPORT_SYMBOL_GPL vmlinux 0x980fc159 __ip_route_output_key +EXPORT_SYMBOL_GPL vmlinux 0x9833bc0c hvc_kick +EXPORT_SYMBOL_GPL vmlinux 0x989a9de5 spi_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x98adb824 hrtimer_forward +EXPORT_SYMBOL_GPL vmlinux 0x98e5386b bus_unregister +EXPORT_SYMBOL_GPL vmlinux 0x98ec71b5 nf_register_afinfo +EXPORT_SYMBOL_GPL vmlinux 0x9908070d spi_busnum_to_master +EXPORT_SYMBOL_GPL vmlinux 0x99157065 sdio_readl +EXPORT_SYMBOL_GPL vmlinux 0x995d1071 prof_on +EXPORT_SYMBOL_GPL vmlinux 0x9994d6d6 __rt_mutex_init +EXPORT_SYMBOL_GPL vmlinux 0x999d277b sata_set_spd +EXPORT_SYMBOL_GPL vmlinux 0x99ba287b xfrm_audit_state_add +EXPORT_SYMBOL_GPL vmlinux 0x9a11a0fc crypto_attr_alg_name +EXPORT_SYMBOL_GPL vmlinux 0x9a2d993e __inet_twsk_hashdance +EXPORT_SYMBOL_GPL vmlinux 0x9a398f5c xfrm_ealg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x9a5333eb devres_add +EXPORT_SYMBOL_GPL vmlinux 0x9a70f421 ata_do_set_mode +EXPORT_SYMBOL_GPL vmlinux 0x9a9ba59d sysfs_create_link +EXPORT_SYMBOL_GPL vmlinux 0x9adaa3b3 ata_port_abort +EXPORT_SYMBOL_GPL vmlinux 0x9ae40d5f transport_add_device +EXPORT_SYMBOL_GPL vmlinux 0x9b210325 register_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0x9b2f3242 led_trigger_show +EXPORT_SYMBOL_GPL vmlinux 0x9b4ec1af tty_mode_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x9ba0501e unregister_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0x9c303374 simple_attr_write +EXPORT_SYMBOL_GPL vmlinux 0x9c3a1e1b device_reprobe +EXPORT_SYMBOL_GPL vmlinux 0x9c88444f inotify_find_update_watch +EXPORT_SYMBOL_GPL vmlinux 0x9cb8037b xfrm_count_enc_supported +EXPORT_SYMBOL_GPL vmlinux 0x9d2a3bac register_virtio_device +EXPORT_SYMBOL_GPL vmlinux 0x9d482dd6 pci_renumber_slot +EXPORT_SYMBOL_GPL vmlinux 0x9e4313e1 audit_log_vformat +EXPORT_SYMBOL_GPL vmlinux 0x9e5f28d2 rtc_irq_set_state +EXPORT_SYMBOL_GPL vmlinux 0x9e6d0df0 set_cpus_allowed_ptr +EXPORT_SYMBOL_GPL vmlinux 0x9e711ad2 pm_qos_requirement +EXPORT_SYMBOL_GPL vmlinux 0x9e7b7952 hrtimer_start +EXPORT_SYMBOL_GPL vmlinux 0x9ef3b0c7 relay_subbufs_consumed +EXPORT_SYMBOL_GPL vmlinux 0x9f0f6902 sysdev_store_int +EXPORT_SYMBOL_GPL vmlinux 0x9fce80db fb_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xa0255440 net_ipv4_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0xa067c6a0 scsi_flush_work +EXPORT_SYMBOL_GPL vmlinux 0xa0987582 ata_sff_dumb_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0xa0b954ea register_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0xa0c3b5fe register_posix_clock +EXPORT_SYMBOL_GPL vmlinux 0xa0f70cce sysdev_create_file +EXPORT_SYMBOL_GPL vmlinux 0xa10c29a6 cpuidle_register_device +EXPORT_SYMBOL_GPL vmlinux 0xa1320001 platform_device_add_data +EXPORT_SYMBOL_GPL vmlinux 0xa1388777 simple_attr_open +EXPORT_SYMBOL_GPL vmlinux 0xa1596d98 acpi_processor_ffh_cstate_enter +EXPORT_SYMBOL_GPL vmlinux 0xa25c2e8b sdio_writeb +EXPORT_SYMBOL_GPL vmlinux 0xa28e61c6 xattr_getsecurity +EXPORT_SYMBOL_GPL vmlinux 0xa2974e9f single_release_net +EXPORT_SYMBOL_GPL vmlinux 0xa2e67f08 acpi_bus_generate_proc_event4 +EXPORT_SYMBOL_GPL vmlinux 0xa32b3a7b inotify_init +EXPORT_SYMBOL_GPL vmlinux 0xa3d56833 pci_enable_rom +EXPORT_SYMBOL_GPL vmlinux 0xa3f7f01d sysfs_remove_file_from_group +EXPORT_SYMBOL_GPL vmlinux 0xa3fc96f0 marker_probe_cb_noarg +EXPORT_SYMBOL_GPL vmlinux 0xa43ca8d4 inet_csk_listen_start +EXPORT_SYMBOL_GPL vmlinux 0xa452c297 hpet_mask_rtc_irq_bit +EXPORT_SYMBOL_GPL vmlinux 0xa48bf9db sdio_f0_writeb +EXPORT_SYMBOL_GPL vmlinux 0xa504dfe2 device_find_child +EXPORT_SYMBOL_GPL vmlinux 0xa51cb83e sched_setscheduler +EXPORT_SYMBOL_GPL vmlinux 0xa528ba23 get_driver +EXPORT_SYMBOL_GPL vmlinux 0xa5386e7c audit_log_d_path +EXPORT_SYMBOL_GPL vmlinux 0xa5bf5c3e pm_qos_add_requirement +EXPORT_SYMBOL_GPL vmlinux 0xa5c36cec inotify_unmount_inodes +EXPORT_SYMBOL_GPL vmlinux 0xa5c86fb7 transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0xa6447e82 inet_diag_unregister +EXPORT_SYMBOL_GPL vmlinux 0xa64ccd3d pv_apic_ops +EXPORT_SYMBOL_GPL vmlinux 0xa657e826 tty_wakeup +EXPORT_SYMBOL_GPL vmlinux 0xa6b2b8de blk_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0xa6fc4f32 __mmu_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0xa714eef9 lookup_instantiate_filp +EXPORT_SYMBOL_GPL vmlinux 0xa7b79346 rtc_read_time +EXPORT_SYMBOL_GPL vmlinux 0xa8457cd3 pci_disable_rom +EXPORT_SYMBOL_GPL vmlinux 0xa8c439a9 power_supply_class +EXPORT_SYMBOL_GPL vmlinux 0xa9126bff hpet_set_rtc_irq_bit +EXPORT_SYMBOL_GPL vmlinux 0xa956a362 register_jprobe +EXPORT_SYMBOL_GPL vmlinux 0xa963f49c tcp_orphan_count +EXPORT_SYMBOL_GPL vmlinux 0xa9ad8b76 device_create_file +EXPORT_SYMBOL_GPL vmlinux 0xa9c530b8 unregister_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xaa2a72bf __iowrite64_copy +EXPORT_SYMBOL_GPL vmlinux 0xaa8c4696 cpu_clock +EXPORT_SYMBOL_GPL vmlinux 0xaad5d0f6 blkdev_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xaae680db spi_write_then_read +EXPORT_SYMBOL_GPL vmlinux 0xab11a89d bus_sort_breadthfirst +EXPORT_SYMBOL_GPL vmlinux 0xab57e311 tracepoint_probe_register +EXPORT_SYMBOL_GPL vmlinux 0xab7a372c ata_cable_sata +EXPORT_SYMBOL_GPL vmlinux 0xab948e71 ata_sff_postreset +EXPORT_SYMBOL_GPL vmlinux 0xac0292be blocking_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0xac13582a xfrm_audit_policy_add +EXPORT_SYMBOL_GPL vmlinux 0xacaf87e6 fs_kobj +EXPORT_SYMBOL_GPL vmlinux 0xaccfc678 cpu_bit_bitmap +EXPORT_SYMBOL_GPL vmlinux 0xace64572 inet6_lookup +EXPORT_SYMBOL_GPL vmlinux 0xad2096a7 hvc_poll +EXPORT_SYMBOL_GPL vmlinux 0xad54b96f tty_prepare_flip_string_flags +EXPORT_SYMBOL_GPL vmlinux 0xae0c87ee pm_qos_remove_notifier +EXPORT_SYMBOL_GPL vmlinux 0xaea385da pci_intx +EXPORT_SYMBOL_GPL vmlinux 0xaea71b2f devres_get +EXPORT_SYMBOL_GPL vmlinux 0xaeb7f977 __blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xaf1145f3 ata_noop_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0xaf12b0aa uhci_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0xaf1618b0 attribute_container_register +EXPORT_SYMBOL_GPL vmlinux 0xaf5e7a99 cpufreq_freq_attr_scaling_available_freqs +EXPORT_SYMBOL_GPL vmlinux 0xafcad923 device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xafd6efd6 driver_find_device +EXPORT_SYMBOL_GPL vmlinux 0xb0757a0b devres_destroy +EXPORT_SYMBOL_GPL vmlinux 0xb0851104 rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0xb08c0a8f lookup_create +EXPORT_SYMBOL_GPL vmlinux 0xb08df9a6 ata_sff_dma_pause +EXPORT_SYMBOL_GPL vmlinux 0xb09a9ee8 iomap_atomic_prot_pfn +EXPORT_SYMBOL_GPL vmlinux 0xb0a248dc ata_port_freeze +EXPORT_SYMBOL_GPL vmlinux 0xb0ab9f8c flush_work +EXPORT_SYMBOL_GPL vmlinux 0xb10633a5 sdio_memcpy_toio +EXPORT_SYMBOL_GPL vmlinux 0xb12fc05f crypto_shoot_alg +EXPORT_SYMBOL_GPL vmlinux 0xb133941d cpufreq_frequency_table_cpuinfo +EXPORT_SYMBOL_GPL vmlinux 0xb1670ff6 device_release_driver +EXPORT_SYMBOL_GPL vmlinux 0xb1a71bf3 ata_pio_need_iordy +EXPORT_SYMBOL_GPL vmlinux 0xb1acbcce rcu_barrier_sched +EXPORT_SYMBOL_GPL vmlinux 0xb27005f5 device_suspend +EXPORT_SYMBOL_GPL vmlinux 0xb2da0648 crypto_nivaead_type +EXPORT_SYMBOL_GPL vmlinux 0xb2f7a839 tty_ldisc_flush +EXPORT_SYMBOL_GPL vmlinux 0xb313a59e unregister_kprobe +EXPORT_SYMBOL_GPL vmlinux 0xb3253ed9 hpet_rtc_timer_init +EXPORT_SYMBOL_GPL vmlinux 0xb3bbe1d1 k_handler +EXPORT_SYMBOL_GPL vmlinux 0xb3ffe4ad proc_net_mkdir +EXPORT_SYMBOL_GPL vmlinux 0xb47ad282 ata_pci_sff_init_one +EXPORT_SYMBOL_GPL vmlinux 0xb4adb236 ata_port_probe +EXPORT_SYMBOL_GPL vmlinux 0xb4ba63ec inotify_dentry_parent_queue_event +EXPORT_SYMBOL_GPL vmlinux 0xb4ea7cf7 kgdb_connected +EXPORT_SYMBOL_GPL vmlinux 0xb4f06150 vfs_setlease +EXPORT_SYMBOL_GPL vmlinux 0xb50357b6 sk_clone +EXPORT_SYMBOL_GPL vmlinux 0xb51fbd64 edac_op_state +EXPORT_SYMBOL_GPL vmlinux 0xb53ae573 cpu_idle_wait +EXPORT_SYMBOL_GPL vmlinux 0xb5784414 get_cpu_sysdev +EXPORT_SYMBOL_GPL vmlinux 0xb5969f94 driver_create_file +EXPORT_SYMBOL_GPL vmlinux 0xb601025b relay_switch_subbuf +EXPORT_SYMBOL_GPL vmlinux 0xb63550f5 __i2c_board_lock +EXPORT_SYMBOL_GPL vmlinux 0xb65091b3 selinux_secmark_refcount_dec +EXPORT_SYMBOL_GPL vmlinux 0xb68327a2 __trace_note_message +EXPORT_SYMBOL_GPL vmlinux 0xb69ab611 securityfs_remove +EXPORT_SYMBOL_GPL vmlinux 0xb6aeb661 ata_id_c_string +EXPORT_SYMBOL_GPL vmlinux 0xb74b1c52 crypto_mod_get +EXPORT_SYMBOL_GPL vmlinux 0xb76011ca ata_sff_data_xfer +EXPORT_SYMBOL_GPL vmlinux 0xb7d7c12e hpet_set_alarm_time +EXPORT_SYMBOL_GPL vmlinux 0xb874763d do_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0xb8e9423c pci_slots_kset +EXPORT_SYMBOL_GPL vmlinux 0xb90e18b7 rtc_set_time +EXPORT_SYMBOL_GPL vmlinux 0xb91aac83 tcp_init_congestion_ops +EXPORT_SYMBOL_GPL vmlinux 0xb9354432 vring_del_virtqueue +EXPORT_SYMBOL_GPL vmlinux 0xb97a5c61 kobject_get_path +EXPORT_SYMBOL_GPL vmlinux 0xb9eb3aa9 add_uevent_var +EXPORT_SYMBOL_GPL vmlinux 0xb9fdda42 mnt_want_write +EXPORT_SYMBOL_GPL vmlinux 0xba25295c do_sync_mapping_range +EXPORT_SYMBOL_GPL vmlinux 0xba698916 __percpu_alloc_mask +EXPORT_SYMBOL_GPL vmlinux 0xba808357 ata_pci_remove_one +EXPORT_SYMBOL_GPL vmlinux 0xbae34c27 scsi_nl_remove_transport +EXPORT_SYMBOL_GPL vmlinux 0xbb04b8cc ata_common_sdev_attrs +EXPORT_SYMBOL_GPL vmlinux 0xbb15cead bus_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0xbb301687 ata_eh_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0xbb3fc4b9 ata_port_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0xbb63d8b0 save_stack_trace_tsk +EXPORT_SYMBOL_GPL vmlinux 0xbb73968e ata_sff_qc_fill_rtf +EXPORT_SYMBOL_GPL vmlinux 0xbb90e4fd blk_end_request_callback +EXPORT_SYMBOL_GPL vmlinux 0xbbb98859 edid_info +EXPORT_SYMBOL_GPL vmlinux 0xbc45800e ata_host_resume +EXPORT_SYMBOL_GPL vmlinux 0xbc63401f ata_std_error_handler +EXPORT_SYMBOL_GPL vmlinux 0xbc9962c7 sysfs_notify_dirent +EXPORT_SYMBOL_GPL vmlinux 0xbcf07adf get_task_mm +EXPORT_SYMBOL_GPL vmlinux 0xbd506a46 unregister_hotplug_dock_device +EXPORT_SYMBOL_GPL vmlinux 0xbdadca2d ata_dev_disable +EXPORT_SYMBOL_GPL vmlinux 0xbdcce1b1 register_kprobe +EXPORT_SYMBOL_GPL vmlinux 0xbdd295f0 trace_vprintk +EXPORT_SYMBOL_GPL vmlinux 0xbe1887e4 ata_unpack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xbeb0ceaf inet_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0xbecde787 blkcipher_walk_virt +EXPORT_SYMBOL_GPL vmlinux 0xbf66d06e simple_attr_release +EXPORT_SYMBOL_GPL vmlinux 0xbfbc6446 unregister_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0xc01fd0b9 blk_end_bidi_request +EXPORT_SYMBOL_GPL vmlinux 0xc04047f2 relay_close +EXPORT_SYMBOL_GPL vmlinux 0xc0882507 skb_icv_walk +EXPORT_SYMBOL_GPL vmlinux 0xc0a06119 sdio_readw +EXPORT_SYMBOL_GPL vmlinux 0xc0dfddeb default_backing_dev_info +EXPORT_SYMBOL_GPL vmlinux 0xc116068e skb_morph +EXPORT_SYMBOL_GPL vmlinux 0xc1276db8 tcp_slow_start +EXPORT_SYMBOL_GPL vmlinux 0xc1b9670d leds_list_lock +EXPORT_SYMBOL_GPL vmlinux 0xc1c16b62 sysfs_remove_group +EXPORT_SYMBOL_GPL vmlinux 0xc1c5b612 ata_dummy_port_info +EXPORT_SYMBOL_GPL vmlinux 0xc1d3759b crypto_enqueue_request +EXPORT_SYMBOL_GPL vmlinux 0xc1dc6311 ata_dummy_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xc22a3091 vm_unmap_aliases +EXPORT_SYMBOL_GPL vmlinux 0xc24132e5 platform_device_register_simple +EXPORT_SYMBOL_GPL vmlinux 0xc31830f0 debugfs_create_x32 +EXPORT_SYMBOL_GPL vmlinux 0xc34efe27 snmp_fold_field +EXPORT_SYMBOL_GPL vmlinux 0xc399468f scsi_nl_remove_driver +EXPORT_SYMBOL_GPL vmlinux 0xc3bfee35 relay_buf_full +EXPORT_SYMBOL_GPL vmlinux 0xc428068d sata_deb_timing_long +EXPORT_SYMBOL_GPL vmlinux 0xc48b7ccf ata_mode_string +EXPORT_SYMBOL_GPL vmlinux 0xc4b33aa6 tracepoint_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc4c552d7 stop_machine +EXPORT_SYMBOL_GPL vmlinux 0xc4f3c96e __audit_inode_child +EXPORT_SYMBOL_GPL vmlinux 0xc512626a __supported_pte_mask +EXPORT_SYMBOL_GPL vmlinux 0xc52db791 generic_sync_sb_inodes +EXPORT_SYMBOL_GPL vmlinux 0xc58354e8 crypto_alloc_aead +EXPORT_SYMBOL_GPL vmlinux 0xc58cdb60 lookup_address +EXPORT_SYMBOL_GPL vmlinux 0xc59cd4fb driver_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0xc5b91f59 inet_unhash +EXPORT_SYMBOL_GPL vmlinux 0xc646dc6b sata_sff_hardreset +EXPORT_SYMBOL_GPL vmlinux 0xc648350d ata_cable_unknown +EXPORT_SYMBOL_GPL vmlinux 0xc6730fc2 klist_iter_init +EXPORT_SYMBOL_GPL vmlinux 0xc673e23e ata_scsi_change_queue_depth +EXPORT_SYMBOL_GPL vmlinux 0xc6ef9ca1 spi_alloc_device +EXPORT_SYMBOL_GPL vmlinux 0xc709914c class_dev_iter_init +EXPORT_SYMBOL_GPL vmlinux 0xc74b5b18 sysfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0xc7504484 tracepoint_get_iter_range +EXPORT_SYMBOL_GPL vmlinux 0xc7e3fa14 scsi_nl_sock +EXPORT_SYMBOL_GPL vmlinux 0xc7ec11f6 atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xc87c1f84 ktime_get +EXPORT_SYMBOL_GPL vmlinux 0xc87e487a sched_clock_idle_sleep_event +EXPORT_SYMBOL_GPL vmlinux 0xc88734b6 xfrm_audit_state_icvfail +EXPORT_SYMBOL_GPL vmlinux 0xc8b1e1cb ata_do_dev_read_id +EXPORT_SYMBOL_GPL vmlinux 0xc8cf22ba unregister_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0xc9561772 fb_destroy_modelist +EXPORT_SYMBOL_GPL vmlinux 0xc9817589 sysfs_get +EXPORT_SYMBOL_GPL vmlinux 0xc98e12e0 crypto_register_alg +EXPORT_SYMBOL_GPL vmlinux 0xc9a4998d rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc9c71000 ata_sff_thaw +EXPORT_SYMBOL_GPL vmlinux 0xca1cdc89 isa_register_driver +EXPORT_SYMBOL_GPL vmlinux 0xca874e7f raw_seq_start +EXPORT_SYMBOL_GPL vmlinux 0xcabe04de cpuidle_resume_and_unlock +EXPORT_SYMBOL_GPL vmlinux 0xcaf2fdce crypto_default_rng +EXPORT_SYMBOL_GPL vmlinux 0xcaf4425a ata_sff_softreset +EXPORT_SYMBOL_GPL vmlinux 0xcb0a933e tcp_reno_ssthresh +EXPORT_SYMBOL_GPL vmlinux 0xcc1cf1b7 ata_sff_error_handler +EXPORT_SYMBOL_GPL vmlinux 0xcc1f1c3d inet_twdr_hangman +EXPORT_SYMBOL_GPL vmlinux 0xcc1faa1c inverse_translate +EXPORT_SYMBOL_GPL vmlinux 0xcc458e1e kobject_uevent_env +EXPORT_SYMBOL_GPL vmlinux 0xcc6ab305 is_dock_device +EXPORT_SYMBOL_GPL vmlinux 0xcc99102f input_ff_event +EXPORT_SYMBOL_GPL vmlinux 0xcccfb2fa sata_deb_timing_hotplug +EXPORT_SYMBOL_GPL vmlinux 0xcd080361 __class_register +EXPORT_SYMBOL_GPL vmlinux 0xcd27c086 console_drivers +EXPORT_SYMBOL_GPL vmlinux 0xcd2e7bed device_destroy +EXPORT_SYMBOL_GPL vmlinux 0xcd792238 ata_pci_sff_prepare_host +EXPORT_SYMBOL_GPL vmlinux 0xcd7f3257 inotify_add_watch +EXPORT_SYMBOL_GPL vmlinux 0xcdc9da3a page_cache_async_readahead +EXPORT_SYMBOL_GPL vmlinux 0xcdca3691 nr_irqs +EXPORT_SYMBOL_GPL vmlinux 0xcdd6550e register_kprobes +EXPORT_SYMBOL_GPL vmlinux 0xcdef82e5 xfrm_audit_state_notfound_simple +EXPORT_SYMBOL_GPL vmlinux 0xce195c16 xfrm_output_resume +EXPORT_SYMBOL_GPL vmlinux 0xce317245 sysfs_chmod_file +EXPORT_SYMBOL_GPL vmlinux 0xce402fe2 bus_find_device_by_name +EXPORT_SYMBOL_GPL vmlinux 0xce80aa96 led_trigger_set +EXPORT_SYMBOL_GPL vmlinux 0xcf0bfd12 start_thread +EXPORT_SYMBOL_GPL vmlinux 0xcfc83669 vring_transport_features +EXPORT_SYMBOL_GPL vmlinux 0xcfcc83ad register_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0xcfd4e47b tty_prepare_flip_string +EXPORT_SYMBOL_GPL vmlinux 0xcfdfc488 crypto_register_instance +EXPORT_SYMBOL_GPL vmlinux 0xcfff1609 devm_kfree +EXPORT_SYMBOL_GPL vmlinux 0xd027a07d marker_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xd03c7700 secure_ipv4_port_ephemeral +EXPORT_SYMBOL_GPL vmlinux 0xd0c05159 emergency_restart +EXPORT_SYMBOL_GPL vmlinux 0xd0d342a1 smp_ops +EXPORT_SYMBOL_GPL vmlinux 0xd12ac59b olpc_ec_cmd +EXPORT_SYMBOL_GPL vmlinux 0xd16712f3 crypto_check_attr_type +EXPORT_SYMBOL_GPL vmlinux 0xd1a2c742 ata_sff_wait_ready +EXPORT_SYMBOL_GPL vmlinux 0xd1bed98c securityfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0xd23c6961 ata_std_postreset +EXPORT_SYMBOL_GPL vmlinux 0xd273b1b1 __round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xd2a8caf0 work_on_cpu +EXPORT_SYMBOL_GPL vmlinux 0xd3801384 transport_configure_device +EXPORT_SYMBOL_GPL vmlinux 0xd38f1617 ata_sff_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xd38f9ad6 power_supply_am_i_supplied +EXPORT_SYMBOL_GPL vmlinux 0xd3c4c812 device_add +EXPORT_SYMBOL_GPL vmlinux 0xd40cc07b ata_dev_pair +EXPORT_SYMBOL_GPL vmlinux 0xd462d86a udp4_lib_lookup +EXPORT_SYMBOL_GPL vmlinux 0xd48cc0b8 __crypto_alloc_tfm +EXPORT_SYMBOL_GPL vmlinux 0xd494ee54 speedstep_get_freqs +EXPORT_SYMBOL_GPL vmlinux 0xd4a7e6d9 sata_scr_write_flush +EXPORT_SYMBOL_GPL vmlinux 0xd50536ac inet_csk_get_port +EXPORT_SYMBOL_GPL vmlinux 0xd5a1bb5a crypto_tfm_in_queue +EXPORT_SYMBOL_GPL vmlinux 0xd5e208aa ata_host_suspend +EXPORT_SYMBOL_GPL vmlinux 0xd632a43e mmput +EXPORT_SYMBOL_GPL vmlinux 0xd6a6e94b rt_mutex_destroy +EXPORT_SYMBOL_GPL vmlinux 0xd71494ef blk_execute_rq_nowait +EXPORT_SYMBOL_GPL vmlinux 0xd7282df0 inet_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0xd7303a39 __rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0xd76a8d01 devres_find +EXPORT_SYMBOL_GPL vmlinux 0xd777d601 scsi_internal_device_block +EXPORT_SYMBOL_GPL vmlinux 0xd7a71bfe crypto_register_template +EXPORT_SYMBOL_GPL vmlinux 0xd7d40267 tcp_done +EXPORT_SYMBOL_GPL vmlinux 0xd7d79132 put_online_cpus +EXPORT_SYMBOL_GPL vmlinux 0xd7d98e13 pci_destroy_slot +EXPORT_SYMBOL_GPL vmlinux 0xd84cd7f4 ata_timing_find_mode +EXPORT_SYMBOL_GPL vmlinux 0xd85da16e uart_console_write +EXPORT_SYMBOL_GPL vmlinux 0xd8821d83 spi_register_master +EXPORT_SYMBOL_GPL vmlinux 0xd90bba62 scsi_queue_work +EXPORT_SYMBOL_GPL vmlinux 0xd932be24 ata_port_disable +EXPORT_SYMBOL_GPL vmlinux 0xd95fadac ata_sff_tf_read +EXPORT_SYMBOL_GPL vmlinux 0xd9d348f4 sysdev_class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xd9dd326d tcp_twsk_destructor +EXPORT_SYMBOL_GPL vmlinux 0xd9f1fd1b kobject_uevent +EXPORT_SYMBOL_GPL vmlinux 0xda1314bc rtc_update_irq +EXPORT_SYMBOL_GPL vmlinux 0xdaf4dfb3 fb_mode_option +EXPORT_SYMBOL_GPL vmlinux 0xdb8f4d20 ata_base_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xdbb3bd98 tty_put_char +EXPORT_SYMBOL_GPL vmlinux 0xdbe2a69d sysfs_update_group +EXPORT_SYMBOL_GPL vmlinux 0xdc396d88 dev_set_name +EXPORT_SYMBOL_GPL vmlinux 0xdc401558 cpuidle_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0xdcb60b68 blk_rq_bytes +EXPORT_SYMBOL_GPL vmlinux 0xdcfbe4da sysfs_put +EXPORT_SYMBOL_GPL vmlinux 0xdd2670cc input_ff_upload +EXPORT_SYMBOL_GPL vmlinux 0xdd43173e class_create_file +EXPORT_SYMBOL_GPL vmlinux 0xdd5c4942 srcu_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0xde7252e1 class_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0xde93412d put_driver +EXPORT_SYMBOL_GPL vmlinux 0xdea772c7 class_interface_unregister +EXPORT_SYMBOL_GPL vmlinux 0xdeee8be2 crypto_dequeue_request +EXPORT_SYMBOL_GPL vmlinux 0xdf3022b2 ata_sff_interrupt +EXPORT_SYMBOL_GPL vmlinux 0xdf471f91 ata_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0xdf7ceb78 inotify_find_watch +EXPORT_SYMBOL_GPL vmlinux 0xdf7e8eaa sdio_disable_func +EXPORT_SYMBOL_GPL vmlinux 0xdf9904c5 crypto_hash_type +EXPORT_SYMBOL_GPL vmlinux 0xdfbca8f0 ata_sff_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0xe019c067 __pneigh_lookup +EXPORT_SYMBOL_GPL vmlinux 0xe0406b5a blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xe0f54ae1 vfs_listxattr +EXPORT_SYMBOL_GPL vmlinux 0xe14191d4 platform_bus +EXPORT_SYMBOL_GPL vmlinux 0xe2340631 pci_enable_pcie_error_reporting +EXPORT_SYMBOL_GPL vmlinux 0xe295c0ff is_hpet_enabled +EXPORT_SYMBOL_GPL vmlinux 0xe3220907 ata_std_bios_param +EXPORT_SYMBOL_GPL vmlinux 0xe32d9e93 scsi_target_unblock +EXPORT_SYMBOL_GPL vmlinux 0xe34ccf90 crypto_lookup_template +EXPORT_SYMBOL_GPL vmlinux 0xe384cd0a __rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0xe4719b74 sata_pmp_error_handler +EXPORT_SYMBOL_GPL vmlinux 0xe48d5eac acpi_ec_add_query_handler +EXPORT_SYMBOL_GPL vmlinux 0xe49bc622 blk_rq_check_limits +EXPORT_SYMBOL_GPL vmlinux 0xe49ff3b0 ata_wait_register +EXPORT_SYMBOL_GPL vmlinux 0xe4c331b6 acpi_os_unmap_memory +EXPORT_SYMBOL_GPL vmlinux 0xe5101b4b tty_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0xe513afc0 cache_k8_northbridges +EXPORT_SYMBOL_GPL vmlinux 0xe530071c pm_qos_remove_requirement +EXPORT_SYMBOL_GPL vmlinux 0xe54ef0ac __cpufreq_driver_getavg +EXPORT_SYMBOL_GPL vmlinux 0xe5d45626 pskb_put +EXPORT_SYMBOL_GPL vmlinux 0xe5f218ca debugfs_rename +EXPORT_SYMBOL_GPL vmlinux 0xe62823ef scsi_execute_async +EXPORT_SYMBOL_GPL vmlinux 0xe6488b47 cpufreq_notify_transition +EXPORT_SYMBOL_GPL vmlinux 0xe674a5cb srcu_read_lock +EXPORT_SYMBOL_GPL vmlinux 0xe689d81c ata_sff_prereset +EXPORT_SYMBOL_GPL vmlinux 0xe6b8da65 securityfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0xe716160e __rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0xe7d22da9 platform_device_alloc +EXPORT_SYMBOL_GPL vmlinux 0xe7e6e0b3 posix_timer_event +EXPORT_SYMBOL_GPL vmlinux 0xe7e94764 driver_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xe7fa47ad srcu_read_unlock +EXPORT_SYMBOL_GPL vmlinux 0xe86ec989 pci_execute_reset_function +EXPORT_SYMBOL_GPL vmlinux 0xe895bc76 platform_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xe93e49c3 devres_free +EXPORT_SYMBOL_GPL vmlinux 0xe9909bbb vfs_lock_file +EXPORT_SYMBOL_GPL vmlinux 0xe9b5d51a power_supply_unregister +EXPORT_SYMBOL_GPL vmlinux 0xe9b6e6bb ata_sff_hsm_move +EXPORT_SYMBOL_GPL vmlinux 0xe9e7b245 pciserial_init_ports +EXPORT_SYMBOL_GPL vmlinux 0xea065e01 task_handoff_unregister +EXPORT_SYMBOL_GPL vmlinux 0xea418e0f atapi_cmd_type +EXPORT_SYMBOL_GPL vmlinux 0xeaab8713 virtio_check_driver_offered_feature +EXPORT_SYMBOL_GPL vmlinux 0xeae74760 scsi_nl_send_transport_msg +EXPORT_SYMBOL_GPL vmlinux 0xeb1e2ded platform_device_del +EXPORT_SYMBOL_GPL vmlinux 0xeb801539 hwmon_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xebc0f243 scsi_nl_add_transport +EXPORT_SYMBOL_GPL vmlinux 0xec6457a7 input_ff_create +EXPORT_SYMBOL_GPL vmlinux 0xec6f4dd6 dev_attr_link_power_management_policy +EXPORT_SYMBOL_GPL vmlinux 0xec83cb40 crypto_hash_walk_done +EXPORT_SYMBOL_GPL vmlinux 0xecc25519 transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0xecc8f8d0 crypto_aead_setauthsize +EXPORT_SYMBOL_GPL vmlinux 0xece306b1 relay_file_operations +EXPORT_SYMBOL_GPL vmlinux 0xed44255b rtnl_put_cacheinfo +EXPORT_SYMBOL_GPL vmlinux 0xed5d7ceb sysfs_create_group +EXPORT_SYMBOL_GPL vmlinux 0xedfe1b00 ata_sff_pause +EXPORT_SYMBOL_GPL vmlinux 0xee001c94 sysdev_driver_register +EXPORT_SYMBOL_GPL vmlinux 0xee18ede2 dnotify_parent +EXPORT_SYMBOL_GPL vmlinux 0xee1c4cd1 sysdev_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xee54b110 sysdev_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xeebe4fc4 __sock_recv_timestamp +EXPORT_SYMBOL_GPL vmlinux 0xef1e2bf3 user_read +EXPORT_SYMBOL_GPL vmlinux 0xef62b3f3 sata_async_notification +EXPORT_SYMBOL_GPL vmlinux 0xef65e0cc scsi_target_block +EXPORT_SYMBOL_GPL vmlinux 0xef6c3f70 round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xef91db65 flush_workqueue +EXPORT_SYMBOL_GPL vmlinux 0xefbdae78 find_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0xefd534bc pci_stop_bus_device +EXPORT_SYMBOL_GPL vmlinux 0xefe21106 snmp_mib_init +EXPORT_SYMBOL_GPL vmlinux 0xf022e7b2 mmu_notifier_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf0b20e3e user_match +EXPORT_SYMBOL_GPL vmlinux 0xf0e0152b ata_pci_bmdma_clear_simplex +EXPORT_SYMBOL_GPL vmlinux 0xf13f76b9 ata_qc_complete_multiple +EXPORT_SYMBOL_GPL vmlinux 0xf16d6453 pci_scan_child_bus +EXPORT_SYMBOL_GPL vmlinux 0xf184d189 kernel_power_off +EXPORT_SYMBOL_GPL vmlinux 0xf18997a4 aead_geniv_free +EXPORT_SYMBOL_GPL vmlinux 0xf1bac0b7 rt_mutex_timed_lock +EXPORT_SYMBOL_GPL vmlinux 0xf2003934 ip_build_and_send_pkt +EXPORT_SYMBOL_GPL vmlinux 0xf21e2e36 ata_sff_data_xfer_noirq +EXPORT_SYMBOL_GPL vmlinux 0xf2234af2 init_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0xf2617e90 scsi_mode_select +EXPORT_SYMBOL_GPL vmlinux 0xf2908d2e register_net_sysctl_rotable +EXPORT_SYMBOL_GPL vmlinux 0xf2fca922 uart_parse_options +EXPORT_SYMBOL_GPL vmlinux 0xf32fe5de vfs_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0xf3638316 file_ra_state_init +EXPORT_SYMBOL_GPL vmlinux 0xf38739a2 scsi_nl_add_driver +EXPORT_SYMBOL_GPL vmlinux 0xf3d5cc13 ata_timing_merge +EXPORT_SYMBOL_GPL vmlinux 0xf423dbd3 seq_open_net +EXPORT_SYMBOL_GPL vmlinux 0xf44ae1cf __inet_lookup_established +EXPORT_SYMBOL_GPL vmlinux 0xf499fdb2 rcu_barrier_bh +EXPORT_SYMBOL_GPL vmlinux 0xf4c4f7d2 device_create +EXPORT_SYMBOL_GPL vmlinux 0xf5097bae sysfs_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xf553318d cpuidle_pause_and_lock +EXPORT_SYMBOL_GPL vmlinux 0xf55f1e25 ata_scsi_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0xf5a691cd invalidate_bh_lrus +EXPORT_SYMBOL_GPL vmlinux 0xf5a86513 key_type_user +EXPORT_SYMBOL_GPL vmlinux 0xf5e7b209 tty_perform_flush +EXPORT_SYMBOL_GPL vmlinux 0xf67ea74a pciserial_suspend_ports +EXPORT_SYMBOL_GPL vmlinux 0xf6861eed cpufreq_register_governor +EXPORT_SYMBOL_GPL vmlinux 0xf69420d3 platform_get_irq +EXPORT_SYMBOL_GPL vmlinux 0xf6bcbd73 hwrng_register +EXPORT_SYMBOL_GPL vmlinux 0xf6d8e1fe mmu_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0xf710b2f7 crypto_grab_aead +EXPORT_SYMBOL_GPL vmlinux 0xf7b16edf ata_host_alloc +EXPORT_SYMBOL_GPL vmlinux 0xf7b91aa6 crypto_unregister_alg +EXPORT_SYMBOL_GPL vmlinux 0xf7c87c39 ata_sff_irq_clear +EXPORT_SYMBOL_GPL vmlinux 0xf7c97cef pcie_port_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xf7cee2e3 inet_csk_reqsk_queue_prune +EXPORT_SYMBOL_GPL vmlinux 0xf7d8e4b3 tty_find_polling_driver +EXPORT_SYMBOL_GPL vmlinux 0xf7e2f200 rtc_read_alarm +EXPORT_SYMBOL_GPL vmlinux 0xf8061701 crypto_aead_type +EXPORT_SYMBOL_GPL vmlinux 0xf82f16b3 execute_in_process_context +EXPORT_SYMBOL_GPL vmlinux 0xf8802492 print_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0xf8c33309 tcp_death_row +EXPORT_SYMBOL_GPL vmlinux 0xf8deecd4 exit_fs +EXPORT_SYMBOL_GPL vmlinux 0xf8ef0153 relay_flush +EXPORT_SYMBOL_GPL vmlinux 0xf8f3a0fb ata_ratelimit +EXPORT_SYMBOL_GPL vmlinux 0xf9512d04 task_current_syscall +EXPORT_SYMBOL_GPL vmlinux 0xf97666a0 set_memory_rw +EXPORT_SYMBOL_GPL vmlinux 0xf9a054b5 __round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0xf9ca3160 ata_id_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xfa2b2ecd relay_open +EXPORT_SYMBOL_GPL vmlinux 0xfa518617 scsi_eh_ready_devs +EXPORT_SYMBOL_GPL vmlinux 0xfaba9eab ata_sff_qc_issue +EXPORT_SYMBOL_GPL vmlinux 0xfac89440 pci_find_next_capability +EXPORT_SYMBOL_GPL vmlinux 0xfad830b5 scsi_internal_device_unblock +EXPORT_SYMBOL_GPL vmlinux 0xfb2a3293 math_state_restore +EXPORT_SYMBOL_GPL vmlinux 0xfb5bfadc ata_bmdma_mode_filter +EXPORT_SYMBOL_GPL vmlinux 0xfb65f55a unregister_virtio_device +EXPORT_SYMBOL_GPL vmlinux 0xfb96572b tty_ldisc_ref +EXPORT_SYMBOL_GPL vmlinux 0xfbd9a746 ata_std_prereset +EXPORT_SYMBOL_GPL vmlinux 0xfbf9be5d register_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xfbff3ea7 crypto_unregister_template +EXPORT_SYMBOL_GPL vmlinux 0xfc040179 rtc_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xfc32d171 put_pid +EXPORT_SYMBOL_GPL vmlinux 0xfc3d1f6a ata_cable_ignore +EXPORT_SYMBOL_GPL vmlinux 0xfc41cf7a fb_deferred_io_cleanup +EXPORT_SYMBOL_GPL vmlinux 0xfceb112c pid_vnr +EXPORT_SYMBOL_GPL vmlinux 0xfd1a5a96 bus_find_device +EXPORT_SYMBOL_GPL vmlinux 0xfd3930d7 unregister_timer_hook +EXPORT_SYMBOL_GPL vmlinux 0xfde0b92c crypto_larval_error +EXPORT_SYMBOL_GPL vmlinux 0xfdf1c041 per_cpu__gdt_page +EXPORT_SYMBOL_GPL vmlinux 0xfe51d5f6 crypto_ahash_type +EXPORT_SYMBOL_GPL vmlinux 0xfec920e9 led_trigger_event +EXPORT_SYMBOL_GPL vmlinux 0xfecbff96 __mark_empty_function +EXPORT_SYMBOL_GPL vmlinux 0xfed45c6c driver_register +EXPORT_SYMBOL_GPL vmlinux 0xfef1c70d sdio_enable_func +EXPORT_SYMBOL_GPL vmlinux 0xff1f0287 rtc_device_register +EXPORT_SYMBOL_GPL vmlinux 0xff4234b6 free_vm_area +EXPORT_SYMBOL_GPL vmlinux 0xff8982f6 ata_link_online +EXPORT_SYMBOL_GPL vmlinux 0xffaa8061 cpuidle_register_driver +EXPORT_UNUSED_SYMBOL vmlinux 0x00000000 init_mm +EXPORT_UNUSED_SYMBOL vmlinux 0x00000000 simple_prepare_write --- linux-2.6.28.orig/debian/abi/2.6.28-11.41/amd64/generic +++ linux-2.6.28/debian/abi/2.6.28-11.41/amd64/generic @@ -0,0 +1,8601 @@ +EXPORT_SYMBOL arch/x86/kvm/kvm 0x90720858 kvm_cpu_has_pending_timer +EXPORT_SYMBOL arch/x86/kvm/kvm 0xb33feb4e kvm_read_guest_atomic +EXPORT_SYMBOL crypto/gf128mul 0x0c2f123f gf128mul_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x1068004b gf128mul_bbe +EXPORT_SYMBOL crypto/gf128mul 0x2f2889a0 gf128mul_init_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0x3755f990 gf128mul_init_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x384ef9ce gf128mul_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x56af0dbd gf128mul_x_ble +EXPORT_SYMBOL crypto/gf128mul 0x83581089 gf128mul_init_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0x9b2560b9 gf128mul_init_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x9e13f6f6 gf128mul_lle +EXPORT_SYMBOL crypto/gf128mul 0xbd17a0df gf128mul_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0xc0890413 gf128mul_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0xd60736ec gf128mul_free_64k +EXPORT_SYMBOL crypto/xor 0x5b6c00e6 xor_blocks +EXPORT_SYMBOL drivers/atm/suni 0x18efa936 suni_init +EXPORT_SYMBOL drivers/atm/uPD98402 0x82c7ac20 uPD98402_init +EXPORT_SYMBOL drivers/block/paride/paride 0x07687c98 pi_write_block +EXPORT_SYMBOL drivers/block/paride/paride 0x1042a2fe pi_do_claimed +EXPORT_SYMBOL drivers/block/paride/paride 0x1843deb9 pi_schedule_claimed +EXPORT_SYMBOL drivers/block/paride/paride 0x1988eb9f pi_write_regr +EXPORT_SYMBOL drivers/block/paride/paride 0x35219630 pi_read_block +EXPORT_SYMBOL drivers/block/paride/paride 0x7b08bf80 pi_init +EXPORT_SYMBOL drivers/block/paride/paride 0x8cf8cdf3 pi_connect +EXPORT_SYMBOL drivers/block/paride/paride 0x98c9e523 pi_disconnect +EXPORT_SYMBOL drivers/block/paride/paride 0xa3484fb8 paride_register +EXPORT_SYMBOL drivers/block/paride/paride 0xe4ec774f pi_release +EXPORT_SYMBOL drivers/block/paride/paride 0xef27aec2 paride_unregister +EXPORT_SYMBOL drivers/block/paride/paride 0xf78f1fc7 pi_read_regr +EXPORT_SYMBOL drivers/char/generic_serial 0x03e1be18 gs_chars_in_buffer +EXPORT_SYMBOL drivers/char/generic_serial 0x0cc217e7 gs_stop +EXPORT_SYMBOL drivers/char/generic_serial 0x310ddf5c gs_hangup +EXPORT_SYMBOL drivers/char/generic_serial 0x39d20150 gs_block_til_ready +EXPORT_SYMBOL drivers/char/generic_serial 0x4980713e gs_got_break +EXPORT_SYMBOL drivers/char/generic_serial 0x5720b672 gs_write_room +EXPORT_SYMBOL drivers/char/generic_serial 0x661f5c05 gs_close +EXPORT_SYMBOL drivers/char/generic_serial 0x6983cac3 gs_start +EXPORT_SYMBOL drivers/char/generic_serial 0x69fb7c1a gs_setserial +EXPORT_SYMBOL drivers/char/generic_serial 0x74d5ff94 gs_getserial +EXPORT_SYMBOL drivers/char/generic_serial 0x7f4392ba gs_set_termios +EXPORT_SYMBOL drivers/char/generic_serial 0x82b82e17 gs_init_port +EXPORT_SYMBOL drivers/char/generic_serial 0xa1f9adb9 gs_write +EXPORT_SYMBOL drivers/char/generic_serial 0xbe2c5129 gs_flush_buffer +EXPORT_SYMBOL drivers/char/generic_serial 0xf1121e1e gs_flush_chars +EXPORT_SYMBOL drivers/char/generic_serial 0xf35f44d0 gs_put_char +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x00e3d608 ipmi_smi_watcher_register +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x05644e9b ipmi_request_supply_msgs +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x160ba3ad ipmi_get_my_address +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x183689ff ipmi_smi_add_proc_entry +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x1a11a4e9 ipmi_unregister_smi +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x1e815137 ipmi_set_gets_events +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x2f8cb466 ipmi_poll_interface +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x40f2b10c ipmi_alloc_smi_msg +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x451c65d6 ipmi_free_recv_msg +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x61c17a25 ipmi_smi_watchdog_pretimeout +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x68bc907a ipmi_smi_msg_received +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x6cc7d91a ipmi_register_for_cmd +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x804f922a ipmi_addr_length +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x90dfe8fe ipmi_destroy_user +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xa19db7bd ipmi_set_maintenance_mode +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xa780cdda ipmi_smi_watcher_unregister +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xa9eb893d ipmi_request_settime +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xaac23f42 ipmi_set_my_address +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xaf38e552 ipmi_get_maintenance_mode +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xb4ca1b06 ipmi_unregister_for_cmd +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xbb540354 ipmi_get_my_LUN +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xc96ce9fd ipmi_register_smi +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xd45ac495 ipmi_get_version +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xe4f4665b ipmi_validate_addr +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xf2b79bae ipmi_create_user +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xf7010caa ipmi_set_my_LUN +EXPORT_SYMBOL drivers/char/nsc_gpio 0xa693b704 nsc_gpio_read +EXPORT_SYMBOL drivers/char/nsc_gpio 0xb1b1f859 nsc_gpio_dump +EXPORT_SYMBOL drivers/char/nsc_gpio 0xcabf9062 nsc_gpio_write +EXPORT_SYMBOL drivers/char/nvram 0x0f28cb91 nvram_read_byte +EXPORT_SYMBOL drivers/char/nvram 0x17ff2c1d __nvram_read_byte +EXPORT_SYMBOL drivers/char/nvram 0x2adec1e0 __nvram_check_checksum +EXPORT_SYMBOL drivers/char/nvram 0x7da28f12 nvram_check_checksum +EXPORT_SYMBOL drivers/char/nvram 0x9ce3f83f nvram_write_byte +EXPORT_SYMBOL drivers/char/nvram 0xa8813189 __nvram_write_byte +EXPORT_SYMBOL drivers/edac/edac_core 0x359a0024 edac_mc_handle_fbd_ce +EXPORT_SYMBOL drivers/edac/edac_core 0xaae260de edac_mc_handle_fbd_ue +EXPORT_SYMBOL drivers/edac/edac_core 0xf62038d0 edac_mc_find +EXPORT_SYMBOL drivers/firewire/firewire-core 0x117749d0 fw_fill_response +EXPORT_SYMBOL drivers/firewire/firewire-core 0x143eff32 fw_core_add_address_handler +EXPORT_SYMBOL drivers/firewire/firewire-core 0x1c0bbf77 fw_core_handle_bus_reset +EXPORT_SYMBOL drivers/firewire/firewire-core 0x1fa6db83 fw_send_request +EXPORT_SYMBOL drivers/firewire/firewire-core 0x39c3b606 fw_device_enable_phys_dma +EXPORT_SYMBOL drivers/firewire/firewire-core 0x410178d7 fw_core_handle_request +EXPORT_SYMBOL drivers/firewire/firewire-core 0x75fe59af fw_cancel_transaction +EXPORT_SYMBOL drivers/firewire/firewire-core 0x7c76bfe4 fw_card_initialize +EXPORT_SYMBOL drivers/firewire/firewire-core 0x7c9c0f74 fw_run_transaction +EXPORT_SYMBOL drivers/firewire/firewire-core 0x842dbe57 fw_card_add +EXPORT_SYMBOL drivers/firewire/firewire-core 0x90863005 fw_high_memory_region +EXPORT_SYMBOL drivers/firewire/firewire-core 0x9afe8043 fw_core_initiate_bus_reset +EXPORT_SYMBOL drivers/firewire/firewire-core 0xa2fda37b fw_core_handle_response +EXPORT_SYMBOL drivers/firewire/firewire-core 0xafc1c793 fw_csr_iterator_next +EXPORT_SYMBOL drivers/firewire/firewire-core 0xb047a2c6 fw_csr_iterator_init +EXPORT_SYMBOL drivers/firewire/firewire-core 0xb61de976 fw_core_remove_card +EXPORT_SYMBOL drivers/firewire/firewire-core 0xca9550db fw_bus_type +EXPORT_SYMBOL drivers/firewire/firewire-core 0xcd704cb0 fw_send_response +EXPORT_SYMBOL drivers/firewire/firewire-core 0xfc33f0cf fw_core_remove_address_handler +EXPORT_SYMBOL drivers/gpu/drm/drm 0x024ba16b drm_agp_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0x031a52a0 drm_gem_handle_create +EXPORT_SYMBOL drivers/gpu/drm/drm 0x082b0ed8 drm_vblank_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x0836695c drm_sman_takedown +EXPORT_SYMBOL drivers/gpu/drm/drm 0x0abd128b drm_agp_bind_pages +EXPORT_SYMBOL drivers/gpu/drm/drm 0x12cfe7e5 drm_get_resource_len +EXPORT_SYMBOL drivers/gpu/drm/drm 0x13dccda7 drm_pci_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x148e1e3a drm_mm_search_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x15881121 drm_agp_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x1bba7733 drm_core_ioremapfree +EXPORT_SYMBOL drivers/gpu/drm/drm 0x20645642 drm_debug +EXPORT_SYMBOL drivers/gpu/drm/drm 0x21451ac4 drm_sman_owner_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x25e9275c drm_clflush_pages +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2916bf63 drm_sman_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2ddc140e drm_exit +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2eb2f903 drm_sman_free_key +EXPORT_SYMBOL drivers/gpu/drm/drm 0x3074f033 drm_order +EXPORT_SYMBOL drivers/gpu/drm/drm 0x34ebade3 drm_idlelock_take +EXPORT_SYMBOL drivers/gpu/drm/drm 0x3b663c29 drm_agp_acquire +EXPORT_SYMBOL drivers/gpu/drm/drm 0x3c389847 drm_ati_pcigart_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x40ce71c5 drm_ioctl +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4759ad01 drm_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4a26d8c0 drm_fasync +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4b8082b9 drm_mm_put_block +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4d2d93e7 drm_core_get_reg_ofs +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4ea1f5a2 drm_gem_object_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4fc2bb7f drm_handle_vblank +EXPORT_SYMBOL drivers/gpu/drm/drm 0x523f0ea4 drm_free_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0x5571b9c8 drm_core_ioremap +EXPORT_SYMBOL drivers/gpu/drm/drm 0x558c5358 drm_compat_ioctl +EXPORT_SYMBOL drivers/gpu/drm/drm 0x55f060ee drm_sman_set_range +EXPORT_SYMBOL drivers/gpu/drm/drm 0x5976a266 drm_addbufs_pci +EXPORT_SYMBOL drivers/gpu/drm/drm 0x5b7fc24a drm_agp_info +EXPORT_SYMBOL drivers/gpu/drm/drm 0x5c471c35 drm_poll +EXPORT_SYMBOL drivers/gpu/drm/drm 0x60398ee6 drm_getsarea +EXPORT_SYMBOL drivers/gpu/drm/drm 0x6315554c drm_addmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0x6370b050 drm_mm_get_block +EXPORT_SYMBOL drivers/gpu/drm/drm 0x64fd01bc drm_agp_unbind +EXPORT_SYMBOL drivers/gpu/drm/drm 0x6c18f9af drm_gem_object_lookup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x7b0038f2 drm_addbufs_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0x7b5bbf08 drm_i_have_hw_lock +EXPORT_SYMBOL drivers/gpu/drm/drm 0x80898037 drm_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x8873dc30 drm_mm_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x8c7f6ebc drm_vblank_put +EXPORT_SYMBOL drivers/gpu/drm/drm 0x9731da87 drm_irq_install +EXPORT_SYMBOL drivers/gpu/drm/drm 0x983ebc1d drm_core_ioremap_wc +EXPORT_SYMBOL drivers/gpu/drm/drm 0x9c25b192 drm_core_get_map_ofs +EXPORT_SYMBOL drivers/gpu/drm/drm 0xa2542dd5 drm_unbind_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0xa2f4f02a drm_core_reclaim_buffers +EXPORT_SYMBOL drivers/gpu/drm/drm 0xa504bbb3 drm_agp_enable +EXPORT_SYMBOL drivers/gpu/drm/drm 0xa949cadc drm_agp_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0xaaa3a0b3 drm_vblank_get +EXPORT_SYMBOL drivers/gpu/drm/drm 0xaf29788e drm_sman_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0xb88ed451 drm_gem_object_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0xb9e015eb drm_lock_take +EXPORT_SYMBOL drivers/gpu/drm/drm 0xbc29bde9 drm_mmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0xbd68627a drm_pci_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0xc080eb9b drm_gem_object_handle_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0xcc332edb drm_open +EXPORT_SYMBOL drivers/gpu/drm/drm 0xcdde8349 drm_get_resource_start +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd3028e75 drm_sman_set_manager +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd5390b28 drm_ati_pcigart_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0xda43786d drm_rmmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0xdee80769 drm_lock_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe6d38ebd drm_sg_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe76bce2f drm_agp_bind +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe80a5254 drm_irq_uninstall +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe919dd5c drm_sman_owner_clean +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe9204a10 drm_agp_chipset_flush +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe974d945 drm_vblank_count +EXPORT_SYMBOL drivers/gpu/drm/drm 0xeae40686 drm_get_drawable_info +EXPORT_SYMBOL drivers/gpu/drm/drm 0xf3e2e73d drm_idlelock_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0xfdfbad19 drm_sman_alloc +EXPORT_SYMBOL drivers/hwmon/hwmon-vid 0x0903c239 vid_from_reg +EXPORT_SYMBOL drivers/hwmon/hwmon-vid 0xef1c781c vid_which_vrm +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0x11a5b304 i2c_bit_add_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0x44845cc7 i2c_bit_add_numbered_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pca 0x507de99f i2c_pca_add_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pca 0x948afbc1 i2c_pca_add_numbered_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pcf 0x12a90cbf i2c_pcf_add_bus +EXPORT_SYMBOL drivers/i2c/busses/i2c-amd756 0x401f64df amd756_smbus +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x02d4ad0f tps65013_set_low_pwr +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x28485130 tps65010_config_vregs1 +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x33739de7 tps65010_set_vib +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x9fd44c69 tps65010_set_led +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0xb14080cc tps65010_set_low_pwr +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0xd5bb106d tps65010_set_vbus_draw +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0xe99b3f36 tps65010_set_gpio_out_value +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0064463e hpsb_read +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x01ba41d4 hpsb_get_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x02e2a0a0 hpsb_iso_recv_set_channel_mask +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x03a5b3fe hpsb_make_phypacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x05a70ba0 hpsb_packet_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0ab3a14d hpsb_iso_xmit_sync +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0b234c4e dma_prog_region_alloc +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0bd42c31 hpsb_iso_recv_start +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0c6da941 csr1212_release_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0e5a659c csr1212_new_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x13b4a268 csr1212_attach_keyval_to_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x158ac548 dma_region_offset_to_bus +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x19f1f97b csr1212_parse_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x204f5bf1 hpsb_iso_stop +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x20f8a34a hpsb_iso_xmit_queue_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x289a8231 hpsb_free_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2cb1b63f hpsb_iso_recv_listen_channel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2dd29f75 csr1212_read +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2e22e7ae hpsb_iso_n_ready +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2e7a5592 hpsb_packet_success +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2ebf6e5a dma_prog_region_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x3414a7fd hpsb_set_hostinfo_key +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x3450c68c hpsb_get_hostinfo_bykey +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x3ca6ed90 dma_region_mmap +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x4f81f0e9 hpsb_resume_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x52e6baf9 hpsb_make_writepacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x5898d2c8 hpsb_iso_recv_unlisten_channel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x5cbbbfe9 hpsb_reset_bus +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6269a311 hpsb_send_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6507e273 hpsb_alloc_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x66d9b139 hpsb_iso_shutdown +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x672ad148 dma_region_sync_for_device +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x68d91355 hpsb_iso_recv_release_packets +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x68e97456 hpsb_allocate_and_register_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6bb19117 __hpsb_register_protocol +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6f3aaf0c hpsb_unregister_protocol +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x713446e4 hpsb_node_fill_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x74087985 hpsb_set_packet_complete_task +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x76bc1a5c dma_region_free +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x76e8837f hpsb_bus_reset +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x79530b08 csr1212_get_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x80364b20 hpsb_make_readpacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8255db23 hpsb_create_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x85900442 hpsb_set_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8826fc79 hpsb_read_cycle_timer +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8879f8f0 dma_region_sync_for_cpu +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x88e140f7 hpsb_update_config_rom +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8ec2b312 dma_region_alloc +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x963a5e25 hpsb_make_lock64packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x9cc83242 hpsb_make_streampacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x9db79966 hpsb_update_config_rom_image +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xa616000b hpsb_alloc_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xa63b98ed hpsb_free_tlabel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xadbeb3b9 hpsb_get_tlabel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb61ad687 hpsb_unregister_highlevel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb837e769 hpsb_iso_recv_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xbaf04652 hpsb_iso_recv_flush +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xbbb693e2 hpsb_register_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc669a4d3 csr1212_detach_keyval_from_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc7e15c34 hpsb_packet_sent +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xcb67fdb3 hpsb_protocol_class +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xcd9e772b dma_prog_region_free +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xcfe3c87b hpsb_iso_xmit_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xd5d09d8f hpsb_register_highlevel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xd62c34d1 hpsb_write +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xda9537a9 hpsb_selfid_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xddc06a09 hpsb_selfid_complete +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xdf6b49ba hpsb_iso_wake +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xdfb00ad3 hpsb_add_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xe1319b73 hpsb_make_lockpacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xea4152ff dma_region_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xeaae7724 hpsb_iso_packet_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xeb85a4b8 hpsb_iso_xmit_start +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xeeb2c108 hpsb_remove_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xf173d60b hpsb_iso_packet_sent +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xf3a77346 hpsb_destroy_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xf4b071bd hpsb_unregister_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfba57f51 hpsb_speedto_str +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfc7562c9 hpsb_node_write +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0x12ba900a ohci1394_register_iso_tasklet +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0xb37ab086 ohci1394_init_iso_tasklet +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0xcd2e9d92 ohci1394_unregister_iso_tasklet +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0xea3d9493 ohci1394_stop_context +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x00f858b0 rdma_addr_cancel +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x71de06c2 rdma_addr_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x9067537c rdma_resolve_ip +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0xbe81bb46 rdma_addr_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0xdfc742a2 rdma_translate_ip +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0xfd3269b2 rdma_copy_addr +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x031df8c1 cm_class +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x1444b68f ib_create_cm_id +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x2fbb509f ib_send_cm_lap +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x3165e06b ib_send_cm_mra +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x3f44b773 ib_destroy_cm_id +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x42384d07 ib_cm_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x464fc19b ib_send_cm_rej +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x4d14d7f9 ib_send_cm_apr +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x6274fe02 ib_send_cm_drep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x8127f928 ib_send_cm_rtu +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x86386492 ib_send_cm_sidr_rep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xae046706 ib_send_cm_dreq +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xae171789 ib_send_cm_req +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xb690accc ib_cm_listen +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xe7bf60ed ib_cm_notify +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xf034a002 ib_send_cm_rep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xfe9257b2 ib_send_cm_sidr_req +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x000ad6aa ib_query_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x06830b9a ib_pack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x073373bf ib_create_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x0ae1742e ib_get_cached_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x0fc7f5cf ib_find_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x14fb18a7 ib_query_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x17f563c9 ib_alloc_pd +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x185953ef ib_create_ah_from_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x19de8c51 ib_get_dma_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x1ade0b3c ib_detach_mcast +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x1e491a04 ib_unmap_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x2ae082f0 ib_query_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x2d284e61 ib_unregister_event_handler +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x2f0db218 ib_query_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x304535a0 ib_free_fast_reg_page_list +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x350f6ca4 ib_destroy_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3e7bd1ad ib_dereg_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3f7567fd ib_rate_to_mult +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x440a5411 ib_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x48b59153 ib_dealloc_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x521e828b ib_query_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x522c10ed ib_fmr_pool_unmap +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x523def05 ib_find_cached_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x60d28f08 ib_fmr_pool_map_phys +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x62000940 ib_modify_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x6518539b ib_set_client_data +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x71199f76 ib_alloc_fast_reg_page_list +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x7235cc54 ib_query_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x77f52ce7 ib_dispatch_event +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x78025171 ib_unregister_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x816eeafb ib_rereg_phys_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x85144001 ib_alloc_fast_reg_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8640eaeb ib_modify_qp_is_ok +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x87b614d8 ib_ud_header_pack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x883f5bc5 ib_umem_get +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8a5c35ff ib_get_client_data +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8c8489de ib_flush_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8d97ce82 ib_find_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x90aa1213 ib_resize_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x968d4200 ib_alloc_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x96ce6c46 rdma_node_get_transport +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x980b1149 ib_modify_port +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x99cb120c ib_dealloc_mw +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9a23c171 ib_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9d5a599b ib_destroy_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9d69bca7 ib_create_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9d804fa1 mult_to_ib_rate +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9def2f32 ib_modify_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa33390c8 ib_create_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa4c3cf05 ib_umem_release +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa83c316f ib_find_cached_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xaf2e3edb ib_modify_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb1216612 ib_alloc_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb617feab ib_dealloc_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb66fd438 ib_attach_mcast +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xbd9cd88a ib_get_cached_lmc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xbe5782b4 ib_query_port +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xbf77693f ib_create_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xc0ae909e ib_destroy_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xc3cff0d9 ib_modify_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xc723dd4e ib_destroy_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xcf7b8dec ib_alloc_mw +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd17ba9d1 ib_ud_header_init +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd639288d ib_umem_page_count +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd78660f9 ib_init_ah_from_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xdc598cc9 ib_reg_phys_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xde01606d ib_destroy_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xeccda842 ib_register_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xed26e1df ib_modify_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xefa569cf ib_dealloc_pd +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf04608a5 ib_query_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf0ee3787 ib_get_cached_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf260cef4 ib_register_event_handler +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf36498b9 ib_ud_header_unpack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf45c0c5c ib_create_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf96fc9de ib_unpack +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x1169e3c7 ib_cancel_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x4a40d5b9 ib_process_mad_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x587b39b7 ib_redirect_mad_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6246f687 ib_post_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x63882290 ib_get_rmpp_segment +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6cdd8d85 ib_register_mad_snoop +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6ef787ed ib_response_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6f077fcf ib_get_mad_data_offset +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x7b5d4b7a ib_is_mad_class_rmpp +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x838c907e ib_create_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xa93cbb1d ib_modify_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xb03a52cd ib_free_recv_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xcf13b864 ib_free_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xe9284e33 ib_register_mad_agent +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xeabdbb12 ib_unregister_mad_agent +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x0bc535c5 ib_sa_service_rec_query +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x0f9b7f47 ib_init_ah_from_mcmember +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x16199856 ib_sa_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x512ba124 ib_sa_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x576fdbac ib_sa_free_multicast +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x9a0f35d3 ib_sa_cancel_query +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xe3358228 ib_sa_get_mcmember_rec +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xe7a48ed8 ib_init_ah_from_path +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xf13c75bf ib_sa_join_multicast +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xfe7ea33e ib_sa_path_rec_get +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x02f847bc ib_copy_path_rec_from_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x07cf5a51 ib_copy_ah_attr_to_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x18382f6a ib_copy_path_rec_to_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x184f3575 ib_copy_qp_attr_to_user +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x0495aadc iw_cm_accept +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x2595c1d1 iw_cm_listen +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x2febc857 iw_create_cm_id +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x3ed51dae iw_destroy_cm_id +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x44f55151 iw_cm_disconnect +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xabf3371a iw_cm_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xce0002e0 iw_cm_reject +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xdb4af68f iw_cm_connect +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x15e1f915 rdma_resolve_addr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x4af8b7b9 rdma_create_id +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x529dbb8a rdma_connect +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x5e701ef4 rdma_destroy_id +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x6179eca1 rdma_disconnect +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x8904d358 rdma_join_multicast +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x8d39ec55 rdma_accept +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x8e2a22e5 rdma_resolve_route +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x90dda189 rdma_notify +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x96b37df5 rdma_reject +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x972bb993 rdma_listen +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x9fa4599c rdma_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xae046c89 rdma_set_service_type +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xca9e5aad rdma_set_ib_paths +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xd7427b17 rdma_bind_addr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xd7f9f3a5 rdma_create_qp +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xd86d264e rdma_destroy_qp +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xf81e66fd rdma_leave_multicast +EXPORT_SYMBOL drivers/input/gameport/gameport 0x276e1ec4 gameport_start_polling +EXPORT_SYMBOL drivers/input/gameport/gameport 0x43f704b3 __gameport_register_driver +EXPORT_SYMBOL drivers/input/gameport/gameport 0x78e8546b gameport_close +EXPORT_SYMBOL drivers/input/gameport/gameport 0x7a6ca563 gameport_unregister_driver +EXPORT_SYMBOL drivers/input/gameport/gameport 0xa2f195eb __gameport_register_port +EXPORT_SYMBOL drivers/input/gameport/gameport 0xa5a5bfdd gameport_unregister_port +EXPORT_SYMBOL drivers/input/gameport/gameport 0xc9cfda3d gameport_open +EXPORT_SYMBOL drivers/input/gameport/gameport 0xf173fbea gameport_set_phys +EXPORT_SYMBOL drivers/input/gameport/gameport 0xfa5885cb gameport_stop_polling +EXPORT_SYMBOL drivers/input/input-polldev 0x4955fcda input_allocate_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0x5e6012b9 input_register_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0x82aaa2dc input_unregister_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0xdda5e358 input_free_polled_device +EXPORT_SYMBOL drivers/isdn/capi/capifs 0x2c54c957 capifs_free_ncci +EXPORT_SYMBOL drivers/isdn/capi/capifs 0xd0bc06ce capifs_new_ncci +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x04403fcf unregister_capi_driver +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x0f72c34b capi_ctr_reseted +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x14f2aa5a capi20_get_version +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x2b8eab1f capilib_free_ncci +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x2baa6586 capilib_new_ncci +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x31c24aa4 capi20_isinstalled +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x47d3fc51 capi_info2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x47dbfa0a capi_message2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x50b33ca4 capi_cmsg2message +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x56d99518 capi20_set_callback +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x6057c6f3 capi_message2cmsg +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x62e32d43 capilib_data_b3_conf +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x69ab56cd capi_ctr_suspend_output +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x6dc6af0f capi_ctr_resume_output +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x71e8d5ba capilib_data_b3_req +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x77d8de5d capi_ctr_handle_message +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x788d398c capi_cmsg2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x7a33596c capi20_get_serial +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x7e6f1307 capi20_get_manufacturer +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x85e2a499 detach_capi_ctr +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x8f699913 capilib_release +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x8f71ada9 capi20_release +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x9f823278 register_capi_driver +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xaa165d27 capilib_release_appl +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xac47e751 attach_capi_ctr +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xada5fb07 capi20_put_message +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xb19fda8d capi_cmd2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xb60e5e5f capi_cmsg_header +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xc5327ee3 capi20_register +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xd63026bc capi_ctr_ready +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xe19a11ac capi20_get_profile +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xe9f62f29 cdebbuf_free +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xed061606 capi20_manufacturer +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x0d2961f0 b1_release_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x2af765b8 b1_register_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x36fa8c3d b1_parse_version +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x4c005457 b1_send_message +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x4f045313 b1_alloc_card +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x708ff839 b1_reset_ctr +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x722b6224 avmcard_dma_alloc +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x7c956a55 b1_getrevision +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x7d75d9b1 b1_load_firmware +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x85f09690 b1_irq_table +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x96f9d2f4 b1_interrupt +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xbaf35b3f b1_load_t4file +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xc59849fd avmcard_dma_free +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xcbe049fe b1_free_card +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xd41b0f28 b1ctl_read_proc +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xdaa1ecee b1_load_config +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xdfd28376 b1_detect +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xeff549da b1_loaded +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x0fd2150e b1dma_send_message +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x2a386384 b1dma_interrupt +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x67fd146d b1dmactl_read_proc +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x845015ca b1dma_register_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x8d1a7c2e b1dma_release_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x96c8b53f b1dma_reset_ctr +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x9d8ebe28 b1dma_reset +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0xce86502c b1pciv4_detect +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0xdcf1483f t1pci_detect +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0xfc767683 b1dma_load_firmware +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0x29562993 b1pcmcia_delcard +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0xaec3240e b1pcmcia_addcard_m1 +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0xea620116 b1pcmcia_addcard_m2 +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0xf14bf8b1 b1pcmcia_addcard_b1 +EXPORT_SYMBOL drivers/isdn/hardware/eicon/divadidd 0x2974ead1 DIVA_DIDD_Read +EXPORT_SYMBOL drivers/isdn/hardware/eicon/divadidd 0x334e8477 proc_net_eicon +EXPORT_SYMBOL drivers/isdn/hardware/mISDN/hfcmulti 0x5293ed86 plx_lock +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x07f4f2ce hisax_unregister +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x148f0c99 FsmFree +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x2844a899 FsmInitTimer +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x93a64734 FsmChangeState +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x9df0cd27 FsmEvent +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xc0c558f9 FsmRestartTimer +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xd94696e8 FsmDelTimer +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xe6a7d50c hisax_init_pcmcia +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xee93522c hisax_register +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xf0a16657 FsmNew +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xfc27303b HiSax_closecard +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x2401c03b isacsx_irq +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x3f3b323a isac_d_l2l1 +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x596dfd02 isacsx_setup +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x945c494f isac_setup +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0xf26b0a14 isac_init +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0xf5833474 isac_irq +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0x1ee629e2 isdnhdlc_rcv_init +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0x95aed401 isdnhdlc_decode +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0x9ffc8215 isdnhdlc_out_init +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0xf5c8131d isdnhdlc_encode +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0x7fcca8fc isdn_ppp_unregister_compressor +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0xc6ad2630 register_isdn +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0xf207e374 isdn_ppp_register_compressor +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0xfa06820f isdn_register_divert +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x012c7f57 recv_Bchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x0549f9fb mISDN_freebchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x0ca7de0f create_l1 +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x176a312b mISDN_unregister_Bprotocol +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x2348cc3c mISDN_FsmFree +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x33428888 mISDN_register_device +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x3ea336fd mISDN_FsmAddTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x429129f2 mISDN_FsmRestartTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x50c2230c mISDN_FsmChangeState +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x694e0240 mISDN_register_Bprotocol +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x6f09c0de mISDN_freedchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x7072571b get_next_dframe +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x74bfb4ff mISDN_initdchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x81ca1c26 l1_event +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xa6d4e660 dchannel_senddata +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xa7c7825a recv_Dchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xa93ab7e7 mISDN_initbchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xace35cae mISDN_FsmDelTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xae34e4d9 recv_Bchannel_skb +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xb9654d66 bchannel_senddata +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xd5145151 mISDN_FsmEvent +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xd9a7fbfd mISDN_FsmInitTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xdc3696e1 confirm_Bsend +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xec18f46d mISDN_unregister_device +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xf0a343d4 recv_Dchannel_skb +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xf50c5d18 get_next_bframe +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xf9e7832f mISDN_FsmNew +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xfebda0a1 queue_ch_frame +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0x4c2ec443 mISDN_dsp_element_register +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0x60721da7 dsp_audio_law_to_s32 +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0xa215f1b2 dsp_audio_s16_to_law +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0xd3a023b8 mISDN_dsp_element_unregister +EXPORT_SYMBOL drivers/media/common/tuners/mt2060 0x6420f8c9 mt2060_attach +EXPORT_SYMBOL drivers/media/common/tuners/mt2131 0x32291931 mt2131_attach +EXPORT_SYMBOL drivers/media/common/tuners/mt2266 0x3f39d332 mt2266_attach +EXPORT_SYMBOL drivers/media/common/tuners/mxl5005s 0x095c4fe7 mxl5005s_attach +EXPORT_SYMBOL drivers/media/common/tuners/qt1010 0x8aca4052 qt1010_attach +EXPORT_SYMBOL drivers/media/common/tuners/tuner-types 0x0cb4b189 tuners +EXPORT_SYMBOL drivers/media/common/tuners/tuner-types 0xc2821775 tuner_count +EXPORT_SYMBOL drivers/media/common/tuners/tuner-xc2028 0xc16031ac xc2028_attach +EXPORT_SYMBOL drivers/media/common/tuners/xc5000 0x16978bf6 xc5000_attach +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x0e083609 flexcop_sram_set_dest +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x1b6f5e41 flexcop_sram_ctrl +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x1f932042 flexcop_eeprom_check_mac_addr +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x3097914c flexcop_dma_config +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x3801272a flexcop_pass_dmx_packets +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x557bda50 flexcop_dma_control_timer_irq +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x5b4d85f9 flexcop_dma_control_size_irq +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x68e1a779 flexcop_i2c_request +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x736112a6 flexcop_device_initialize +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x782b58d0 flexcop_dma_free +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x8ce9fa2a flexcop_device_kmalloc +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x9fd04a27 flexcop_dma_allocate +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xa05c4d18 flexcop_dump_reg +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xb71d34b0 flexcop_device_kfree +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xb77ad719 flexcop_dma_config_timer +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xbb61fb7c flexcop_wan_set_speed +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xbea25c00 flexcop_device_exit +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xdfa36240 flexcop_pass_dmx_data +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xf0d873ba flexcop_dma_xfer_control +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0x34c1d297 bt878_stop +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0x7221d2c8 bt878 +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0x99fd4c74 bt878_start +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0xa064eb8c bt878_device_control +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0xd5d0bdef bt878_num +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x1463d73a write_dst +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x14bf627f dst_wait_dst_ready +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x68991be2 dst_error_bailout +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x6cae0cd5 dst_comm_init +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xa980b9f7 read_dst +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xb44952b7 rdc_reset_state +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xb8e2bb66 dst_error_recovery +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xc7a3b1b2 dst_pio_disable +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xe94b8c9c dst_check_sum +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xfc1b5b49 dst_attach +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst_ca 0x0b8dc6ee dst_ca_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x03504e20 dvb_ca_en50221_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x0b8a0067 dvb_unregister_device +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x0c457c5c dvb_ringbuffer_flush_spinlock_wakeup +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x1b1c06dd dvb_net_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x2ae6c78e dvb_dmxdev_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x2af2a213 dvb_ca_en50221_camchange_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x36c8ea1f dvb_frontend_sleep_until +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x3aad6ce4 dvb_generic_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x3bbdff45 dvb_unregister_frontend +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x4db3899f dvb_dmx_swfilter_packets +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x51f3767c dvb_ringbuffer_read +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x54fab26a dvb_ca_en50221_camready_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x5ce2d08f dvb_frontend_reinitialise +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x6988f784 dvb_ringbuffer_read_user +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x698b0fb2 dvb_generic_open +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x735d0c02 dvb_register_adapter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x74a5a698 dvb_filter_pes2ts_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x7773ac71 dvb_register_frontend +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x80e3832d dvb_filter_get_ac3info +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x8b49a23f timeval_usec_diff +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x8bf881e9 dvb_generic_ioctl +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xac4ca1b0 intlog2 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb29fe59b dvb_dmxdev_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xbbb1d1a4 dvb_frontend_detach +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xbc5b257b dvb_net_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xbd3054c7 dvb_register_device +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xc324b69b dvb_dmx_swfilter_204 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xc80754c1 dvb_dmx_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xcb89fc7d dvb_ringbuffer_free +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xcca08cb5 dvb_ringbuffer_avail +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xcce0eeed dvb_ringbuffer_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xd639b9bc dvb_ringbuffer_write +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xd7765e69 dvb_ringbuffer_empty +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xe5ae8707 intlog10 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xee54ac68 dvb_ca_en50221_frda_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xee73de0a dvb_dmx_swfilter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf7573a18 dvb_unregister_adapter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf826deb0 dvb_filter_pes2ts +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf86f20c5 dvb_dmx_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xfbd75b8d dvb_ca_en50221_init +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x5ee180fd dvb_usb_device_init +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x78ebcc81 dvb_usb_generic_rw +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x8a412dc2 dvb_usb_get_hexline +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xb1b6a93e usb_cypress_load_firmware +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xb2a26caf dvb_usb_device_exit +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xe89537bd dvb_usb_nec_rc_key_to_event +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xfccd9ed6 dvb_usb_generic_write +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0x1cda9de5 af9005_rc_decode +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0x2edc4728 af9005_rc_keys +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0xd3383957 af9005_rc_keys_size +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x092a6969 dibusb2_0_streaming_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x0a7276dd dibusb_i2c_algo +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x0b450070 dibusb_rc_query +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x0cb7fcb9 dibusb_pid_filter_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x65ad6b25 dibusb_dib3000mc_tuner_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x6fefc18d dibusb_pid_filter +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x76281ce1 dibusb_power_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x765df0ec dibusb_read_eeprom_byte +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xa1087823 dibusb2_0_power_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xd2ee5062 dibusb_dib3000mc_frontend_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xd4d3dddc dibusb_rc_keys +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xd88fa7be dibusb_streaming_ctrl +EXPORT_SYMBOL drivers/media/dvb/frontends/af9013 0x6d4268ca af9013_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/au8522 0x4fc62d15 au8522_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/bcm3510 0xdef3768a bcm3510_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx22700 0x5e87381d cx22700_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx22702 0xb8864bb9 cx22702_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24110 0x0f275c22 cx24110_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24116 0xadceb0d9 cx24116_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24123 0x14835b9a cx24123_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24123 0x94caca18 cx24123_get_tuner_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/dib0070 0x64ef8c46 dib0070_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib0070 0xaa361af1 dib0070_wbd_offset +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mb 0xd2c47019 dib3000mb_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x2fe2ecf1 dib3000mc_i2c_enumeration +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x30c5cba9 dib3000mc_pid_parse +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0xb98ec6d0 dib3000mc_pid_control +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0xc0a67ecc dib3000mc_set_config +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0xcc624b43 dib3000mc_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0xe987ae03 dib3000mc_get_tuner_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000m 0x17ded495 dib7000m_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000m 0xc95cfc1c dib7000m_get_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x03180c94 dib7000p_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x07fd563e dib7000p_set_gpio +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x1fac3b29 dib7000p_set_wbd_ref +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x470111ca dib7000p_get_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xb475e9bb dib7000pc_detection +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xd9dd7aa9 dib7000p_i2c_enumeration +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0x3a0a4e3e dibx000_init_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0x8aac55d4 dibx000_get_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0xcfee3935 dibx000_exit_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/drx397xD 0x1ecbc359 drx397xD_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dvb-pll 0x8d6e9362 dvb_pll_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/isl6405 0x95416412 isl6405_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/isl6421 0xf0ac232b isl6421_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/itd1000 0xf1843605 itd1000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/l64781 0x2413b783 l64781_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lgdt330x 0x10c33664 lgdt330x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lgs8gl5 0x3f7a4c76 lgs8gl5_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lnbp21 0x0a564913 lnbp21_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/mt312 0x4ac11027 mt312_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/mt352 0x07ff6d61 mt352_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/nxt200x 0xe392663d nxt200x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/nxt6000 0x063df531 nxt6000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/or51132 0xe756a40c or51132_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/or51211 0x87699791 or51211_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1409 0x676a87a1 s5h1409_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1411 0x4fddc712 s5h1411_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1420 0x6c54bcae s5h1420_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1420 0x72686db6 s5h1420_get_tuner_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/si21xx 0x446bd324 si21xx_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/sp8870 0x205648fc sp8870_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/sp887x 0x9fe4266a sp887x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stb6000 0xd9b6a81b stb6000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0288 0x47f8ef06 stv0288_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0297 0x67e23d37 stv0297_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0299 0x384ebb11 stv0299_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10021 0x001ea5fc tda10021_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10023 0x0c97bec5 tda10023_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10048 0x01d4ccee tda10048_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda1004x 0xcf104776 tda10045_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda1004x 0xe851fe86 tda10046_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10086 0x3d2d2928 tda10086_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda8083 0x61b7b0f3 tda8083_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda826x 0x4500cca4 tda826x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tua6100 0xc2c57326 tua6100_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/ves1820 0x6ae07d76 ves1820_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/ves1x93 0x0d09e1ab ves1x93_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/zl10353 0x409d5b96 zl10353_attach +EXPORT_SYMBOL drivers/media/dvb/ttpci/ttpci-eeprom 0x0adcb58f ttpci_eeprom_parse_mac +EXPORT_SYMBOL drivers/media/dvb/ttusb-dec/ttusbdecfe 0xd4c1205d ttusbdecfe_dvbt_attach +EXPORT_SYMBOL drivers/media/dvb/ttusb-dec/ttusbdecfe 0xff062197 ttusbdecfe_dvbs_attach +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x11dc4b6d bttv_gpio_enable +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x30b21926 bttv_sub_register +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x8ecf4acc bttv_write_gpio +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x91dba186 bttv_get_pcidev +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0xbb0ddd8c bttv_sub_unregister +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0xbcf2d2fb bttv_read_gpio +EXPORT_SYMBOL drivers/media/video/btcx-risc 0x204418bb btcx_riscmem_alloc +EXPORT_SYMBOL drivers/media/video/btcx-risc 0x495e4b0c btcx_calc_skips +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xad2fe38b btcx_sort_clips +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xc368f8e6 btcx_align +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xcda0ded2 btcx_screen_clips +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xf5320745 btcx_riscmem_free +EXPORT_SYMBOL drivers/media/video/cpia 0x30228a04 cpia_unregister_camera +EXPORT_SYMBOL drivers/media/video/cpia 0xbfa7615f cpia_register_camera +EXPORT_SYMBOL drivers/media/video/cx18/cx18 0x2cdea06d cx18_reset_ir_gpio +EXPORT_SYMBOL drivers/media/video/cx2341x 0x226b4360 cx2341x_ctrl_get_menu +EXPORT_SYMBOL drivers/media/video/cx2341x 0x484d9064 cx2341x_ctrl_query +EXPORT_SYMBOL drivers/media/video/cx2341x 0x61b38569 cx2341x_ext_ctrls +EXPORT_SYMBOL drivers/media/video/cx2341x 0x62f2c86b cx2341x_log_status +EXPORT_SYMBOL drivers/media/video/cx2341x 0x7f09da7c cx2341x_fill_defaults +EXPORT_SYMBOL drivers/media/video/cx2341x 0xcf8b77a4 cx2341x_mpeg_ctrls +EXPORT_SYMBOL drivers/media/video/cx2341x 0xe58ec2e3 cx2341x_update +EXPORT_SYMBOL drivers/media/video/cx88/cx88-vp3054-i2c 0xbc8e326e vp3054_i2c_remove +EXPORT_SYMBOL drivers/media/video/cx88/cx88-vp3054-i2c 0xcedddb94 vp3054_i2c_probe +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x053eb641 cx88_enum_input +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x5d7dc16e cx8800_ctrl_query +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x85b05c97 cx88_video_mux +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xa5aa3c49 cx88_set_freq +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xac4e53b9 cx88_user_ctrls +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xd46e4fcd cx88_get_control +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xd981839d cx88_set_control +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x1b33605a cx8802_register_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x4e260536 cx8802_get_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x7081ed5e cx8802_get_device +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x7a0378a4 cx8802_buf_queue +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0xa043807a cx8802_buf_prepare +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0xa61d3c6b cx8802_unregister_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0xea972e54 cx8802_cancel_buffers +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x11defc94 cx88_free_buffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x1c8d1334 cx88_core_get +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x31e0656e cx88_shutdown +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x3d2f8a03 cx88_risc_buffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x4245f1ca cx88_risc_stopper +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x4f822e89 cx88_core_put +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x5ac8afa5 cx88_call_i2c_clients +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x5cca4f67 cx88_vdev_init +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x6141c8c5 cx88_tuner_callback +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x61842754 cx88_sram_channel_setup +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x6303a677 cx88_sram_channel_dump +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x904b8696 cx88_audio_thread +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x9b140fff cx88_sram_channels +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xa23333f5 cx88_set_tvaudio +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xa8add6b3 cx88_core_irq +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xaf87f71d cx88_set_scale +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xb47f6cda cx88_print_irqbits +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xc175d744 cx88_set_tvnorm +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xcfcb4d1c cx88_wakeup +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xd032068d cx88_ir_start +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xd284a4fb cx88_ir_stop +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xd4fb0e22 cx88_get_stereo +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xdffb5b16 cx88_newstation +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xe5abb543 cx88_risc_databuffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xeebcc7d6 cx88_reset +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xf73645f0 cx88_set_stereo +EXPORT_SYMBOL drivers/media/video/em28xx/em28xx 0x3d8ab3a4 em28xx_register_extension +EXPORT_SYMBOL drivers/media/video/em28xx/em28xx 0x8e784a36 em28xx_unregister_extension +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x1d8e7789 gspca_disconnect +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x7e05faf8 gspca_get_i_frame +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x92ade976 gspca_resume +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x9670af2c gspca_debug +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x9a9f47f3 gspca_suspend +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xa939d14d gspca_frame_add +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xd0272a51 gspca_auto_gain_n_exposure +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xe724ca51 gspca_dev_probe +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x02855897 ivtv_udma_setup +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x0538e449 ivtv_cards_lock +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x14f67530 ivtv_debug +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x21af8062 ivtv_vapi +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x2b616968 ivtv_set_irq_mask +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x2c43cbed ivtv_saa7127 +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x37314be6 ivtv_cards +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x6b83c8fa ivtv_udma_unmap +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x6eb503aa ivtv_udma_prepare +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x70196ffb ivtv_cards_active +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x846636a9 ivtv_reset_ir_gpio +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x8cb1fde9 ivtv_vapi_result +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xcf7bd683 ivtv_clear_irq_mask +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xd4989890 ivtv_init_on_first_open +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xdc1e2d71 ivtv_api +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xe31266a7 ivtv_udma_alloc +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x03cf0281 saa7134_ts_register +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x04e83446 saa7134_tuner_callback +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x0c521a9f saa_dsp_writel +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x1211df5d saa7134_devlist +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x26ac10c4 saa7134_set_dmabits +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x40beef25 saa7134_dmasound_init +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x58c5c6c1 saa7134_tvaudio_setmute +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x81a5cf3b saa7134_pgtable_free +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x826ca7c8 saa7134_pgtable_build +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x90f0e5e2 saa7134_pgtable_alloc +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x98af79c1 saa7134_boards +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x9c3e69ad saa7134_ts_unregister +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xa87edaea saa7134_set_gpio +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xd7206e4d saa7134_dmasound_exit +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xeaa66df9 saa7134_i2c_call_clients +EXPORT_SYMBOL drivers/media/video/soc_camera 0x0cf70239 soc_camera_video_start +EXPORT_SYMBOL drivers/media/video/soc_camera 0x106404a0 soc_camera_device_unregister +EXPORT_SYMBOL drivers/media/video/soc_camera 0x2771b5fe soc_camera_host_unregister +EXPORT_SYMBOL drivers/media/video/soc_camera 0x6264d512 soc_camera_video_stop +EXPORT_SYMBOL drivers/media/video/soc_camera 0x8001a204 soc_camera_device_register +EXPORT_SYMBOL drivers/media/video/soc_camera 0xe19634a9 soc_camera_host_register +EXPORT_SYMBOL drivers/media/video/tveeprom 0x527f9934 tveeprom_read +EXPORT_SYMBOL drivers/media/video/tveeprom 0x970fc1f8 tveeprom_hauppauge_analog +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x16a2915c RingQueue_Dequeue +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x3ddd85ea usbvideo_Deregister +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x407a321c RingQueue_WakeUpInterruptible +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x73858cb6 usbvideo_TestPattern +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xa0eb548e usbvideo_AllocateDevice +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xdbd0edaa usbvideo_DeinterlaceFrame +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xddecac6d RingQueue_Enqueue +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xf22d5969 usbvideo_register +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xf5011f67 RingQueue_Flush +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xffb1af38 usbvideo_RegisterVideoDevice +EXPORT_SYMBOL drivers/media/video/v4l1-compat 0x52e4360d v4l_compat_translate_ioctl +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x03165a85 v4l2_ctrl_get_menu +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x0dfb5e57 v4l2_prio_max +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x1c427ecb v4l2_ctrl_query_fill +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x1c743f66 v4l2_chip_ident_i2c_client +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x2de2b633 v4l2_prio_check +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x2e9a955d v4l2_prio_close +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x42c8e001 v4l2_ctrl_next +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x458af61e v4l2_chip_match_i2c_client +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x495426ee v4l2_ctrl_get_name +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x50766d69 v4l2_ctrl_query_menu_valid_items +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x57abfbd8 v4l2_chip_match_host +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x5fef1b4a v4l2_ctrl_query_fill_std +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x942892ab v4l2_prio_open +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xafa05d8f v4l2_i2c_attach +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xb2d1e17e v4l2_prio_change +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xc369097d v4l2_ctrl_check +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xd464e760 v4l2_ctrl_query_menu +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xe330bce9 v4l2_prio_init +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x17c4dba2 videobuf_dvb_find_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x3b278798 videobuf_dvb_register_bus +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x6dce5841 videobuf_dvb_get_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x8873645c videobuf_dvb_dealloc_frontends +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x9d02f1ea videobuf_dvb_alloc_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0xda492b14 videobuf_dvb_unregister_bus +EXPORT_SYMBOL drivers/media/video/videodev 0x123959a1 v4l2_type_names +EXPORT_SYMBOL drivers/media/video/videodev 0x207688d4 video_devdata +EXPORT_SYMBOL drivers/media/video/videodev 0x3adbd595 v4l2_field_names +EXPORT_SYMBOL drivers/media/video/videodev 0x3edeac69 video_device_release_empty +EXPORT_SYMBOL drivers/media/video/videodev 0x454e5c1b video_unregister_device +EXPORT_SYMBOL drivers/media/video/videodev 0x5581dcff video_usercopy +EXPORT_SYMBOL drivers/media/video/videodev 0x5782066d video_device_alloc +EXPORT_SYMBOL drivers/media/video/videodev 0x5ebefe4b v4l_printk_ioctl +EXPORT_SYMBOL drivers/media/video/videodev 0x81c485c0 __video_ioctl2 +EXPORT_SYMBOL drivers/media/video/videodev 0x9c544691 video_register_device +EXPORT_SYMBOL drivers/media/video/videodev 0xbafd9a90 video_register_device_index +EXPORT_SYMBOL drivers/media/video/videodev 0xd3d61d8c video_ioctl2 +EXPORT_SYMBOL drivers/media/video/videodev 0xe2b92059 v4l2_video_std_construct +EXPORT_SYMBOL drivers/media/video/videodev 0xe80c140d video_device_release +EXPORT_SYMBOL drivers/media/video/videodev 0xf3251e7b v4l2_norm_to_name +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0x3762dd30 videocodec_register +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0x5aa1a02c videocodec_attach +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0x7d26cdd9 videocodec_unregister +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0xb15312b4 videocodec_detach +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x0260e217 mpt_resume +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x105d4f47 mpt_add_sge +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x1866638d mpt_HardResetHandler +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x1c14127f mpt_verify_adapter +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x1c24d0e3 mpt_put_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x1e18d227 mpt_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x26435392 mpt_put_msg_frame_hi_pri +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x3820b007 mptbase_sas_persist_operation +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x38ae5eb6 mpt_get_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x43344d4a mpt_suspend +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x4526289b mpt_event_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x48079e7c mpt_GetIocState +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x6c93ea2e mpt_device_driver_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x716ce290 mpt_findImVolumes +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x8e7ba68a mpt_alloc_fw_memory +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xb8fca91a mpt_send_handshake_request +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xbb493324 mpt_raid_phys_disk_pg0 +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc0e69f82 mpt_device_driver_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc3f79fae mpt_event_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc47c22e8 mpt_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc7242b04 mpt_detach +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xca290bde mpt_print_ioc_summary +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xd01d3691 mpt_reset_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xd9a92a75 mpt_reset_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xdb725bd1 mpt_free_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xdd805159 ioc_list +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xee63fd47 mpt_free_fw_memory +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xefa46b65 mpt_attach +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xfdd2e669 mpt_config +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x043c1bf6 mptscsih_is_phys_disk +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x0ab54b82 mptscsih_qcmd +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x178b0afb mptscsih_abort +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x1848b9ce mptscsih_TMHandler +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x1abebe98 mptscsih_raid_id_to_num +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x1d51b2b8 mptscsih_event_process +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x28cf9dae mptscsih_host_attrs +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x3361c968 mptscsih_taskmgmt_complete +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x39a5cbb1 mptscsih_remove +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x49761fae mptscsih_resume +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x53ad14a5 mptscsih_slave_destroy +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x764ddf1a mptscsih_timer_expired +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x7f1185ba mptscsih_proc_info +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x80b1fb36 mptscsih_info +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x81ac9bfa mptscsih_dev_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x82265975 mptscsih_shutdown +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xc351e941 mptscsih_change_queue_depth +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xd5144969 mptscsih_bios_param +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xd9770762 mptscsih_host_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xdbf34090 mptscsih_bus_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xe1da2395 mptscsih_slave_configure +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xe2d92c66 mptscsih_ioc_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xe2fe4323 mptscsih_io_done +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xe402ff81 mptscsih_scandv_complete +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xfeddd00c mptscsih_suspend +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x02e531d2 i2o_parm_field_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x047f60f0 i2o_cntxt_list_remove +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x0a66fe49 i2o_cntxt_list_add +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x12481d66 i2o_msg_get_wait +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x1f028baa i2o_status_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x2a843bef i2o_dump_message +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x2b6e2695 i2o_device_claim +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x319d9801 i2o_find_iop +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x32b35498 i2o_driver_notify_device_remove_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x5957cc68 i2o_driver_notify_controller_remove_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x720b95b0 i2o_device_claim_release +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x80cae138 i2o_driver_register +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x85134dab i2o_cntxt_list_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x8768ebb3 i2o_msg_post_wait_mem +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x97d1531b i2o_parm_table_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xa8746ae2 i2o_iop_find_device +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xab766960 i2o_driver_notify_device_add_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xac2c3c2c i2o_driver_unregister +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xb4c00dcf i2o_controllers +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xb8e021c0 i2o_exec_lct_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xd9f06a17 i2o_driver_notify_controller_add_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xe45ff8e7 i2o_event_register +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xe4993e2c i2o_cntxt_list_get_ptr +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xfa8b63be i2o_parm_issue +EXPORT_SYMBOL drivers/mfd/htc-pasic3 0x16c0b530 pasic3_write_register +EXPORT_SYMBOL drivers/mfd/htc-pasic3 0x5b0e75c9 pasic3_read_register +EXPORT_SYMBOL drivers/misc/c2port/core 0x625cfe08 c2port_device_register +EXPORT_SYMBOL drivers/misc/c2port/core 0x763f552f c2port_device_unregister +EXPORT_SYMBOL drivers/misc/ioc4 0x1c5e179e ioc4_register_submodule +EXPORT_SYMBOL drivers/misc/ioc4 0xb101e35d ioc4_unregister_submodule +EXPORT_SYMBOL drivers/misc/sony-laptop 0x5bb1e117 sony_pic_camera_command +EXPORT_SYMBOL drivers/misc/tifm_core 0x307b183f tifm_free_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0x339d3143 tifm_free_device +EXPORT_SYMBOL drivers/misc/tifm_core 0x603905d0 tifm_unmap_sg +EXPORT_SYMBOL drivers/misc/tifm_core 0x710d8462 tifm_remove_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0x7abb4df7 tifm_map_sg +EXPORT_SYMBOL drivers/misc/tifm_core 0x86f5ba03 tifm_has_ms_pif +EXPORT_SYMBOL drivers/misc/tifm_core 0x95dc7e2b tifm_alloc_device +EXPORT_SYMBOL drivers/misc/tifm_core 0x9ddfe759 tifm_add_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0xa8c2ec46 tifm_queue_work +EXPORT_SYMBOL drivers/misc/tifm_core 0xb1dc9315 tifm_unregister_driver +EXPORT_SYMBOL drivers/misc/tifm_core 0xb4c82359 tifm_alloc_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0xdfba73c3 tifm_eject +EXPORT_SYMBOL drivers/misc/tifm_core 0xf72e11fa tifm_register_driver +EXPORT_SYMBOL drivers/mmc/card/mmc_block 0xa67735c0 mmc_cleanup_queue +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0x1cea879b cfi_varsize_frob +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0x23fc6929 cfi_read_pri +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0xb3654456 cfi_fixup +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x14087773 unregister_mtd_chip_driver +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x25bbe5aa register_mtd_chip_driver +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0xadcf4d3a map_destroy +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0xd2cda739 do_map_probe +EXPORT_SYMBOL drivers/mtd/chips/gen_probe 0xd644ae97 mtd_do_chip_probe +EXPORT_SYMBOL drivers/mtd/maps/map_funcs 0x2bb097e1 simple_map_init +EXPORT_SYMBOL drivers/mtd/mtd 0x7756c0a5 add_mtd_partitions +EXPORT_SYMBOL drivers/mtd/mtd 0xbaf734c8 del_mtd_partitions +EXPORT_SYMBOL drivers/mtd/mtdconcat 0x491cc641 mtd_concat_destroy +EXPORT_SYMBOL drivers/mtd/mtdconcat 0x4b950d6c mtd_concat_create +EXPORT_SYMBOL drivers/mtd/nand/nand 0x048072b9 nand_scan_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand 0xc09627f4 nand_default_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0x4aa2274e nand_calculate_ecc +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0xb779cfd9 nand_correct_data +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0x836bdb72 nand_flash_ids +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0xa336feb7 nand_manuf_ids +EXPORT_SYMBOL drivers/mtd/onenand/onenand 0x4b7c4d6d onenand_default_bbt +EXPORT_SYMBOL drivers/mtd/onenand/onenand 0xd2ee8327 onenand_scan_bbt +EXPORT_SYMBOL drivers/net/8390 0x5f0275ef ei_open +EXPORT_SYMBOL drivers/net/8390 0x7d7e0dbc ei_interrupt +EXPORT_SYMBOL drivers/net/8390 0x8247a6fd ei_close +EXPORT_SYMBOL drivers/net/8390 0xe7c82df6 NS8390_init +EXPORT_SYMBOL drivers/net/8390 0xead390c8 ei_poll +EXPORT_SYMBOL drivers/net/8390 0xef01a348 __alloc_ei_netdev +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x4641bd7d arcnet_interrupt +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x565f323d arc_proto_default +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x6534792a arcnet_debug +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x6f90ce81 arcnet_unregister_proto +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x850ca899 arc_raw_proto +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0xb2c8a89a arc_proto_map +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0xc6089bdb arc_bcast_proto +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0xf895c418 alloc_arcdev +EXPORT_SYMBOL drivers/net/arcnet/com20020 0xc4d7ac09 com20020_found +EXPORT_SYMBOL drivers/net/arcnet/com20020 0xf8c5dbf3 com20020_check +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x00ff575e cxgb3_register_client +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x112cf145 t3_l2t_get +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x2aeed5c9 cxgb3_free_stid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x36688bae cxgb3_alloc_atid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x3f994026 cxgb3_free_atid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x454cbfe0 cxgb3_remove_tid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x4ff27ed3 t3_register_cpl_handler +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x54bf55f7 t3_l2t_send_event +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x572f013a cxgb3_unregister_client +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x6464dc30 cxgb3_alloc_stid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x67d6dd25 t3_l2t_send_slow +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x690cbe4e dev2t3cdev +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x6d5b0a0a cxgb3_insert_tid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x7f48f310 t3_l2e_free +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xcc8655f5 cxgb3_ofld_send +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xfd0e28bb cxgb3_queue_tid_release +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0x17b94117 hdlcdrv_arbitrate +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0x2e8bec28 hdlcdrv_transmitter +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0xba8e7e78 hdlcdrv_register +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0xef78bfaa hdlcdrv_unregister +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0xfd300aa0 hdlcdrv_receiver +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x07ff2fde sirdev_raw_write +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x2f5251a5 sirdev_set_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x3d4a80e2 irda_register_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x648cebb4 sirdev_get_instance +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x7092ec3a sirdev_raw_read +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x75bfa86b sirdev_write_complete +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x915c6825 irda_unregister_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x97627d2b sirdev_set_dtr_rts +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xe5f4e048 sirdev_put_instance +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xeb6dfbf1 sirdev_receive +EXPORT_SYMBOL drivers/net/mii 0x0258d875 mii_link_ok +EXPORT_SYMBOL drivers/net/mii 0x0526d3a6 generic_mii_ioctl +EXPORT_SYMBOL drivers/net/mii 0x2aeaaeee mii_ethtool_gset +EXPORT_SYMBOL drivers/net/mii 0x9e9709e6 mii_check_gmii_support +EXPORT_SYMBOL drivers/net/mii 0xa16fae4e mii_check_link +EXPORT_SYMBOL drivers/net/mii 0xabe6ce07 mii_check_media +EXPORT_SYMBOL drivers/net/mii 0xea01ce46 mii_ethtool_sset +EXPORT_SYMBOL drivers/net/mii 0xf2de11c5 mii_nway_restart +EXPORT_SYMBOL drivers/net/phy/mdio-bitbang 0x70dc209c free_mdio_bitbang +EXPORT_SYMBOL drivers/net/phy/mdio-bitbang 0xff804612 alloc_mdio_bitbang +EXPORT_SYMBOL drivers/net/pppox 0x205ed453 register_pppox_proto +EXPORT_SYMBOL drivers/net/pppox 0xc718edc7 pppox_ioctl +EXPORT_SYMBOL drivers/net/pppox 0xe0ff7a18 unregister_pppox_proto +EXPORT_SYMBOL drivers/net/pppox 0xfb44cb49 pppox_unbind_sock +EXPORT_SYMBOL drivers/net/sungem_phy 0x83f0aa55 mii_phy_probe +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x518fcbfb tms380tr_interrupt +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x8c97fd64 tmsdev_term +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x9f201ccf tms380tr_open +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0xa7309f65 tmsdev_init +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0xb9e9a45c tms380tr_close +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0xd2328794 tms380tr_wait +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x38da4725 cycx_intr +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x62be23ea cycx_setup +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x66a4c4e6 cycx_down +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x968458a6 cycx_peek +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0xb6f383de cycx_poke +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0xfe7cd576 cycx_exec +EXPORT_SYMBOL drivers/net/wan/hdlc 0x035522c0 detach_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0x3395649e unregister_hdlc_device +EXPORT_SYMBOL drivers/net/wan/hdlc 0x35c92bf4 register_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0x4f2af92a unregister_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0x5f2155f3 hdlc_ioctl +EXPORT_SYMBOL drivers/net/wan/hdlc 0xc87b529f hdlc_close +EXPORT_SYMBOL drivers/net/wan/hdlc 0xccea8354 attach_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0xe2eccbb2 hdlc_open +EXPORT_SYMBOL drivers/net/wan/hdlc 0xffba517d alloc_hdlcdev +EXPORT_SYMBOL drivers/net/wan/syncppp 0x342bbb18 sppp_reopen +EXPORT_SYMBOL drivers/net/wan/syncppp 0x43e9a654 sppp_detach +EXPORT_SYMBOL drivers/net/wan/syncppp 0x6aafd92d sppp_do_ioctl +EXPORT_SYMBOL drivers/net/wan/syncppp 0x6e0df095 sppp_attach +EXPORT_SYMBOL drivers/net/wan/syncppp 0x8660d85d sppp_close +EXPORT_SYMBOL drivers/net/wan/syncppp 0xa35ac069 sppp_open +EXPORT_SYMBOL drivers/net/wireless/airo 0x1ef22162 init_airo_card +EXPORT_SYMBOL drivers/net/wireless/airo 0x6368e1f6 reset_airo_card +EXPORT_SYMBOL drivers/net/wireless/airo 0xe9e4eca9 stop_airo_card +EXPORT_SYMBOL drivers/net/wireless/atmel 0x05cfe783 atmel_open +EXPORT_SYMBOL drivers/net/wireless/atmel 0x0bca67ee stop_atmel_card +EXPORT_SYMBOL drivers/net/wireless/atmel 0x4081136c init_atmel_card +EXPORT_SYMBOL drivers/net/wireless/hermes 0x4196c38b hermes_write_ltv +EXPORT_SYMBOL drivers/net/wireless/hermes 0xa031d8e4 hermes_doicmd_wait +EXPORT_SYMBOL drivers/net/wireless/hermes 0xc60b5e9e hermes_bap_pwrite +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd38d8ae2 hermes_read_ltv +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd3f714e5 hermes_bap_pread +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd5168829 hermes_allocate +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd5336e5d hermes_init +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd54e219d hermes_docmd_wait +EXPORT_SYMBOL drivers/net/wireless/hermes 0xed47b224 hermes_struct_init +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x161a199c hermes_program +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x2e340491 hermesi_program_end +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x3e7d91b2 hermesi_program_init +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x79a2030e hermes_read_pda +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xc4026a52 hermes_apply_pda +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xcbd49cae hermes_apply_pda_with_defaults +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xeb824e25 hermes_blocks_length +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x0f43164e hostap_set_encryption +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x11736c42 hostap_get_stats +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x1723ac32 hostap_set_multicast_list_queue +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x1fc82c2c hostap_remove_interface +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x2e3241fa hostap_get_porttype +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x3337ce74 hostap_init_ap_proc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x3abb3c1f hostap_master_start_xmit +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x3c01e695 hostap_info_init +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x4f766616 hostap_info_process +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x6792e340 hostap_80211_rx +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x6903f16c hostap_80211_get_hdrlen +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x6a95b594 hostap_set_word +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x7b9b7c5d hostap_handle_sta_tx_exc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x822f739d hostap_init_data +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x96c48d9a hostap_setup_dev +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xa12ad27f hostap_dump_tx_header +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xa61e0671 hostap_add_interface +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xb2a945e0 hostap_dump_rx_header +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xb48400d4 prism2_update_comms_qual +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xb70f95ec hostap_set_string +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xbd2d5236 hostap_free_data +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xd683a55e hostap_80211_ops +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xdf87216f hostap_check_sta_fw_version +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xe27fe246 hostap_init_proc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xe35539fe hostap_set_hostapd_sta +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xe5f8bf73 hostap_remove_proc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xe6cab397 hostap_set_antsel +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xee2c51a1 hostap_set_auth_algs +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xf210eb54 hostap_set_roaming +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xf9ae44df hostap_set_hostapd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x0f9a4bb3 iwl_leds_background +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x14bf6aa8 iwl_send_cmd_sync +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x1d77b399 iwl_bcast_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x204b1326 iwl_remove_dynamic_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x22c00ca5 iwl_set_rxon_ht +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x286ee917 iwl_set_dynamic_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x29c257b0 iwl_txq_check_empty +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x29d250e7 iwl_hwrate_to_tx_control +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2d74c198 iwl_rfkill_unregister +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2e6b0c36 iwl_tx_skb +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2ec11143 iwl_rx_queue_reset +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2f04eeab iwl_power_temperature_change +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x3102d33f iwl_init_sensitivity +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x31e452b5 iwl_dump_nic_error_log +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x391fd5c6 iwl_rx_reply_rx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x40b59bf7 iwl_set_rxon_channel +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x413b4052 iwl_hw_txq_ctx_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x44c0772b iwl_uninit_drv +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x48ab9866 iwl_get_sta_id +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x495b13bb iwl_tx_cmd_complete +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x49b37f85 iwl_dump_nic_event_log +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x4b80ab72 iwl_eeprom_get_mac +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x4d55e8dd iwl_sta_modify_enable_tid_tx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x4eda3d94 iwl_init_channel_map +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x50494cda iwl_sensitivity_calibration +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x542de193 iwl_eeprom_query16 +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x56a8f7dc iwl_eeprom_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x57499238 iwl_rx_missed_beacon_notif +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x57d37671 iwl_setup_rx_scan_handlers +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x592fdb78 iwlcore_eeprom_verify_signature +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5a049174 iwl_tx_agg_start +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5af2341e iwl_rx_agg_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5c7f252c iwl_hw_nic_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5cf8d1c9 iwl_rx_queue_space +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x60774702 iwl_queue_space +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x64bd8355 iwl_leds_register +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x671ed26b iwl_rx_queue_restock +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x6d75a072 iwl_set_tx_power +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x6f6dc043 iwl_rx_queue_alloc +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x71f29758 iwl_rx_reply_rx_phy +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x74f81149 iwl_tx_agg_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7a030c53 iwl_send_lq_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7b0aaa49 iwlcore_eeprom_acquire_semaphore +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7b403137 iwlcore_eeprom_release_semaphore +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7c39bae8 iwl_send_static_wepkey_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7c8cde50 iwl_hw_detect +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8123ba43 iwl_send_cmd_pdu_async +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x83504727 iwl_eeprom_check_version +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x843685fc iwl_rf_kill_ct_config +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x84dc0e1e iwl_rx_replenish +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x84fa9d10 iwl_add_station_flags +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8670273d iwl_hwrate_to_plcp_idx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x868bd88f iwl_rxon_add_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8911b832 iwl_scan_cancel +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x89f0b4f0 iwlcore_eeprom_query_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8bf26d84 iwl_power_initialize +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8bf2ff2c iwl_setup_mac +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8f8df527 iwl_send_add_sta +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x912410ce iwl_get_ra_sta_id +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x95e7add7 iwl_power_cancel_timeout +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x97361f69 iwl_power_update_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9b3fbf83 iwl_setup_power_deferred_work +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9ca243e1 iwl_send_cmd_pdu +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9d30a4f3 iwl_is_fat_tx_allowed +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9faced57 iwl_calib_set +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa1c3cb8b iwl_remove_default_wep_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa228b5e7 iwl_rx_statistics +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa384cd03 iwl_find_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa3d2ed9d iwl_verify_ucode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa94857e8 iwl_rx_reply_compressed_ba +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xab890b30 iwl_eeprom_query_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xabf5d7f7 iwl_get_channel_info +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xacf84f2a iwl_power_set_user_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xaf53aff1 iwl_radio_kill_sw_enable_radio +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb02d206c iwl_send_calib_results +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb083703e iwl_clear_stations_table +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb590ffe6 iwl_send_statistics_request +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb6af4ea1 iwl_reset_qos +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb95e83e9 iwl_power_disable_management +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb9ee04bf iwl_alloc_all +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xbdc69c2e iwl_radio_kill_sw_disable_radio +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xbfd039bd iwl_rfkill_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc0e7dbd6 iwl_remove_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc1743c24 iwl_txq_ctx_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc3dac20b iwl_send_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc545b89d iwl_leds_unregister +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc69e75ed iwl_rx_queue_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc7196f0e iwl_init_drv +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcbaf4931 get_cmd_string +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcf28136a iwl_eeprom_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcf9fc5a6 iwl_rx_queue_update_write_ptr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcfc088cb iwl_txq_update_write_ptr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd22b044e iwl_set_hw_params +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd28a6fa6 iwl_tx_queue_reclaim +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd2ba42ba iwl_rfkill_set_hw_state +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd3fa5c20 iwl_power_enable_management +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd9a85d2a iwl_scan_cancel_timeout +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xdad05f86 iwl_power_set_system_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xdfb69344 iwl_set_rxon_chain +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe1cb6a69 iwl_scan_initiate +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe7ce5d70 iwl_rates +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe904d7c6 iwl_set_default_wep_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xeb2a2e05 iwl_chain_noise_calibration +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xf12be572 iwl_reset_run_time_calib +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xf6ca975a iwl_rxq_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xf6f34ea4 iwl_rx_agg_start +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xfa2e794f iwl_setup_scan_deferred_work +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x100af4e6 orinoco_reinit_firmware +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x1a9d334a orinoco_interrupt +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x82861a78 free_orinocodev +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x8a54e940 __orinoco_up +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x95ca3e64 __orinoco_down +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x9643ce33 alloc_orinocodev +EXPORT_SYMBOL drivers/parport/parport 0x106360db parport_ieee1284_epp_write_data +EXPORT_SYMBOL drivers/parport/parport 0x1476608c parport_claim +EXPORT_SYMBOL drivers/parport/parport 0x14fde6c7 parport_ieee1284_epp_write_addr +EXPORT_SYMBOL drivers/parport/parport 0x158c8e8b parport_claim_or_block +EXPORT_SYMBOL drivers/parport/parport 0x1b48a1b7 parport_put_port +EXPORT_SYMBOL drivers/parport/parport 0x1dbe8d84 parport_irq_handler +EXPORT_SYMBOL drivers/parport/parport 0x21766871 parport_ieee1284_read_nibble +EXPORT_SYMBOL drivers/parport/parport 0x4d2a941b parport_ieee1284_interrupt +EXPORT_SYMBOL drivers/parport/parport 0x4e17dcb4 parport_find_number +EXPORT_SYMBOL drivers/parport/parport 0x55a21e07 parport_get_port +EXPORT_SYMBOL drivers/parport/parport 0x656f345b parport_read +EXPORT_SYMBOL drivers/parport/parport 0x704e8709 parport_register_device +EXPORT_SYMBOL drivers/parport/parport 0x7c208fa1 parport_unregister_driver +EXPORT_SYMBOL drivers/parport/parport 0x81c788fc parport_ieee1284_ecp_write_data +EXPORT_SYMBOL drivers/parport/parport 0x85590ee0 parport_ieee1284_ecp_write_addr +EXPORT_SYMBOL drivers/parport/parport 0x87610617 parport_find_base +EXPORT_SYMBOL drivers/parport/parport 0x87879095 parport_announce_port +EXPORT_SYMBOL drivers/parport/parport 0x8ec0ae02 parport_wait_peripheral +EXPORT_SYMBOL drivers/parport/parport 0x993f77ea parport_remove_port +EXPORT_SYMBOL drivers/parport/parport 0xa3c968e5 parport_unregister_device +EXPORT_SYMBOL drivers/parport/parport 0xa46a9382 parport_negotiate +EXPORT_SYMBOL drivers/parport/parport 0xa9506615 parport_set_timeout +EXPORT_SYMBOL drivers/parport/parport 0xb4a79359 parport_register_port +EXPORT_SYMBOL drivers/parport/parport 0xb4db819b parport_wait_event +EXPORT_SYMBOL drivers/parport/parport 0xb50c7bd5 parport_ieee1284_read_byte +EXPORT_SYMBOL drivers/parport/parport 0xc4879a8b parport_register_driver +EXPORT_SYMBOL drivers/parport/parport 0xc6b85495 parport_ieee1284_epp_read_addr +EXPORT_SYMBOL drivers/parport/parport 0xe281341d parport_ieee1284_write_compat +EXPORT_SYMBOL drivers/parport/parport 0xe7336577 parport_ieee1284_ecp_read_data +EXPORT_SYMBOL drivers/parport/parport 0xe74ccd23 parport_write +EXPORT_SYMBOL drivers/parport/parport 0xe762f51c parport_ieee1284_epp_read_data +EXPORT_SYMBOL drivers/parport/parport 0xfee25d87 parport_release +EXPORT_SYMBOL drivers/parport/parport_pc 0x2e6e5e9c parport_pc_unregister_port +EXPORT_SYMBOL drivers/parport/parport_pc 0xe8d9c6f5 parport_pc_probe_port +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x00882b95 pcmcia_modify_configuration +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x1451bf03 pcmcia_request_irq +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x19d5708a pcmcia_request_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x1aadfa92 pcmcia_disable_device +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x2be616ec pcmcia_map_mem_page +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x4d74879f pcmcia_request_io +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x4fd033a0 pcmcia_error_func +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x5f8bd925 pcmcia_request_configuration +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x7a666475 pcmcia_get_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x984f60d5 pcmcia_unregister_driver +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xa96b806e pcmcia_dev_present +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xab4b297d pcmcia_register_driver +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xc053c5b9 pcmcia_loop_config +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xc41e2e14 pcmcia_access_configuration_register +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xdd017b98 pcmcia_get_mem_page +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xf000e2ac pcmcia_release_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xf0a25e12 pcmcia_error_ret +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x09e54cbe pcmcia_suspend_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x0af4df0a pcmcia_parse_events +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x1a185344 pcmcia_get_socket_by_nr +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x1dd67e11 pcmcia_write_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x212db8d2 pcmcia_socket_list +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x30b936b0 pccard_get_first_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x32ab9fc7 pccard_get_tuple_data +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x3a582895 pcmcia_socket_dev_suspend +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x3f9a7e4d pccard_static_ops +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x42d7d874 pccard_register_pcmcia +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x4688a421 pcmcia_resume_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x4ee49d1e pcmcia_get_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x59643bf5 release_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x6891c6ca pcmcia_find_io_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x86278490 pcmcia_unregister_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x8cd7f463 pccard_get_next_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x8f484df7 pcmcia_socket_dev_resume +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x9a120356 pcmcia_put_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xa8df65b6 pcmcia_socket_list_rwsem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xaffef93a pcmcia_find_mem_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xb427f969 pcmcia_reset_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xb523cd38 pcmcia_register_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xbb2638bb destroy_cis_cache +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xbb8c467e pcmcia_validate_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xbe29b84f pcmcia_socket_class +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xc02ef2c8 pcmcia_parse_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xccbbe894 pcmcia_adjust_io_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xcf97f3bd dead_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xdb49f4ad pcmcia_replace_cis +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xdded96b8 pcmcia_insert_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xeaee8dc0 pcmcia_read_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xf7b27ccd pccard_read_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xfcc0842b pccard_validate_cis +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xfea1a025 pcmcia_eject_card +EXPORT_SYMBOL drivers/pcmcia/rsrc_nonstatic 0xedafc732 pccard_nonstatic_ops +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0x2250c66e mraid_mm_adapter_app_handle +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0x512c956d mraid_mm_unregister_adp +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0xdb61961e mraid_mm_register_adp +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x12c7dab5 qlogicfas408_biosparam +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x22de13a2 qlogicfas408_info +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x3fd8cd71 qlogicfas408_detect +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x4e7fc283 qlogicfas408_queuecommand +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x5cd179e6 qlogicfas408_ihandl +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x5eadb027 qlogicfas408_abort +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x6b98b9ff qlogicfas408_bus_reset +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xe76b3b20 qlogicfas408_get_chip_type +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xf21ae8fb qlogicfas408_disable_ints +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xf2b95199 qlogicfas408_setup +EXPORT_SYMBOL drivers/scsi/raid_class 0x397e9127 raid_component_add +EXPORT_SYMBOL drivers/scsi/raid_class 0xdeb9eb67 raid_class_attach +EXPORT_SYMBOL drivers/scsi/raid_class 0xfc34af92 raid_class_release +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x190b1dd3 fc_remote_port_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x5df4a4b4 fc_remote_port_rolechg +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x651d7edb scsi_is_fc_vport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x70f32dd6 scsi_is_fc_rport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x7954b1ea fc_get_event_number +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x8e7dde3b fc_remote_port_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xa2e65a3b fc_vport_terminate +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xad8984d0 fc_host_post_vendor_event +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xd31fa5f6 fc_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xd5f3c323 fc_remove_host +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xde4f3b2a fc_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xe2afb381 fc_host_post_event +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xe7dff79a fc_vport_create +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x0bbbaeb0 sas_port_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x14a46f71 sas_read_port_mode_page +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x1ec4982c sas_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x2086ec36 sas_phy_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x4c7f599f sas_rphy_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x4fd3cdd8 sas_remove_host +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x55898cf3 scsi_is_sas_port +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x58cdc38f sas_rphy_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x63579305 scsi_is_sas_rphy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x63c44a4b sas_port_delete_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x710b79bc sas_rphy_remove +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x7515d383 sas_end_device_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x760e1155 sas_phy_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x7effe674 sas_port_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x88818e30 sas_port_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x97e4abda sas_expander_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xa5e1059f sas_port_add_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xaf7cd5aa scsi_is_sas_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xb0a14f08 sas_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xc600edf6 sas_phy_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xc65b0531 sas_remove_children +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xd3e376ef sas_port_mark_backlink +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xe7006b77 sas_rphy_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xe93048c9 sas_port_alloc_num +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xea0c529f sas_phy_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xf33e38cc sas_port_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x3686ea09 spi_print_msg +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x51e22e6c spi_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0xbf024dd5 spi_display_xfer_agreement +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0xe3d2f6f3 spi_schedule_dv_device +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0xedda47f7 spi_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0xfbcf6bbc spi_dv_device +EXPORT_SYMBOL drivers/ssb/ssb 0x04806729 ssb_driver_unregister +EXPORT_SYMBOL drivers/ssb/ssb 0x1bc66f60 ssb_pcihost_register +EXPORT_SYMBOL drivers/ssb/ssb 0x450cbf47 ssb_bus_suspend +EXPORT_SYMBOL drivers/ssb/ssb 0x482cfd26 ssb_dma_free_consistent +EXPORT_SYMBOL drivers/ssb/ssb 0x654ba824 ssb_device_enable +EXPORT_SYMBOL drivers/ssb/ssb 0x6b7bb1d8 ssb_bus_powerup +EXPORT_SYMBOL drivers/ssb/ssb 0x7269e1bd ssb_bus_pcibus_register +EXPORT_SYMBOL drivers/ssb/ssb 0x8b2a202f ssb_clockspeed +EXPORT_SYMBOL drivers/ssb/ssb 0x8e3f3d86 ssb_dma_set_mask +EXPORT_SYMBOL drivers/ssb/ssb 0xad50bc86 ssb_device_is_enabled +EXPORT_SYMBOL drivers/ssb/ssb 0xb902d676 ssb_device_disable +EXPORT_SYMBOL drivers/ssb/ssb 0xc0512e0f ssb_admatch_base +EXPORT_SYMBOL drivers/ssb/ssb 0xd029e4ef ssb_bus_unregister +EXPORT_SYMBOL drivers/ssb/ssb 0xd481192b ssb_admatch_size +EXPORT_SYMBOL drivers/ssb/ssb 0xe05fa98f ssb_dma_alloc_consistent +EXPORT_SYMBOL drivers/ssb/ssb 0xe351c81d ssb_pcicore_dev_irqvecs_enable +EXPORT_SYMBOL drivers/ssb/ssb 0xebcc3296 __ssb_driver_register +EXPORT_SYMBOL drivers/ssb/ssb 0xefacae02 ssb_bus_may_powerdown +EXPORT_SYMBOL drivers/ssb/ssb 0xefec92fb ssb_dma_translation +EXPORT_SYMBOL drivers/ssb/ssb 0xf1e067c0 ssb_bus_resume +EXPORT_SYMBOL drivers/ssb/ssb 0xf4b0445c ssb_set_devtypedata +EXPORT_SYMBOL drivers/telephony/ixj 0xd92498c2 ixj_pcmcia_probe +EXPORT_SYMBOL drivers/telephony/phonedev 0x0c3f562a phone_unregister_device +EXPORT_SYMBOL drivers/telephony/phonedev 0x2189adca phone_register_device +EXPORT_SYMBOL drivers/usb/gadget/dummy_hcd 0x3d35254c usb_gadget_register_driver +EXPORT_SYMBOL drivers/usb/gadget/dummy_hcd 0x91ba969e usb_gadget_unregister_driver +EXPORT_SYMBOL drivers/usb/gadget/dummy_hcd 0xbbc64535 net2280_set_fifo_mode +EXPORT_SYMBOL drivers/usb/host/sl811-hcd 0x725ecddd sl811h_driver +EXPORT_SYMBOL drivers/video/backlight/corgi_bl 0xc86baa7c corgibl_limit_intensity +EXPORT_SYMBOL drivers/video/backlight/lcd 0x07e62c04 lcd_device_register +EXPORT_SYMBOL drivers/video/backlight/lcd 0xa9c67fbc lcd_device_unregister +EXPORT_SYMBOL drivers/video/console/bitblit 0x8cc12c22 fbcon_set_bitops +EXPORT_SYMBOL drivers/video/console/font 0x09c8eb55 font_vga_8x16 +EXPORT_SYMBOL drivers/video/console/font 0xbb99125c get_default_font +EXPORT_SYMBOL drivers/video/console/font 0xf7584a9c find_font +EXPORT_SYMBOL drivers/video/console/softcursor 0xcde5eab0 soft_cursor +EXPORT_SYMBOL drivers/video/console/tileblit 0xc9ec2bb5 fbcon_set_tileops +EXPORT_SYMBOL drivers/video/cyber2000fb 0x050324de cyber2000fb_disable_extregs +EXPORT_SYMBOL drivers/video/cyber2000fb 0x0cc3ede5 cyber2000fb_detach +EXPORT_SYMBOL drivers/video/cyber2000fb 0x85893ae7 cyber2000fb_attach +EXPORT_SYMBOL drivers/video/cyber2000fb 0xbe9c5f59 cyber2000fb_get_fb_var +EXPORT_SYMBOL drivers/video/cyber2000fb 0xd4196aae cyber2000fb_enable_extregs +EXPORT_SYMBOL drivers/video/display/display 0x2137b5f4 display_device_unregister +EXPORT_SYMBOL drivers/video/display/display 0xac53975d display_device_register +EXPORT_SYMBOL drivers/video/macmodes 0x08ed0b62 mac_vmode_to_var +EXPORT_SYMBOL drivers/video/macmodes 0x0d9ecf34 mac_find_mode +EXPORT_SYMBOL drivers/video/macmodes 0xe2304303 mac_map_monitor_sense +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0x2cea0278 g450_mnp2f +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0x31c65143 matroxfb_g450_setpll_cond +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0x6d10e413 matroxfb_g450_setclk +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0x2e85e373 matrox_G100 +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0x31aaf133 DAC1064_global_restore +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0x927bc1fd matrox_mystique +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0xffad0d38 DAC1064_global_init +EXPORT_SYMBOL drivers/video/matrox/matroxfb_Ti3026 0x1eadd1ec matrox_millennium +EXPORT_SYMBOL drivers/video/matrox/matroxfb_accel 0x2f9a9f28 matrox_cfbX_init +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0x741d861e matroxfb_unregister_driver +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0x9a87d2f5 matroxfb_enable_irq +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0xd5bb65eb matroxfb_register_driver +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0xf4b72b4b matroxfb_wait_for_sync +EXPORT_SYMBOL drivers/video/matrox/matroxfb_g450 0x6eb16351 matroxfb_g450_shutdown +EXPORT_SYMBOL drivers/video/matrox/matroxfb_g450 0xb77c756d matroxfb_g450_connect +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x1311e13e matroxfb_vgaHWrestore +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x25cf8049 matroxfb_PLL_calcclock +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x5e96016e matroxfb_vgaHWinit +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0xa0df6df2 matroxfb_DAC_in +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0xabd8e427 matroxfb_var2my +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0xdff73773 matroxfb_DAC_out +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0xf6f6c16c matroxfb_read_pins +EXPORT_SYMBOL drivers/video/output 0x8a205396 video_output_register +EXPORT_SYMBOL drivers/video/output 0xfbbaabdc video_output_unregister +EXPORT_SYMBOL drivers/video/sis/sisfb 0x3037658e sis_malloc +EXPORT_SYMBOL drivers/video/sis/sisfb 0x454a3cf0 sis_free +EXPORT_SYMBOL drivers/video/svgalib 0x00d1fce9 svga_set_default_seq_regs +EXPORT_SYMBOL drivers/video/svgalib 0x07b3da30 svga_wseq_multi +EXPORT_SYMBOL drivers/video/svgalib 0x1b95c56a svga_check_timings +EXPORT_SYMBOL drivers/video/svgalib 0x2f50c40b svga_tilecursor +EXPORT_SYMBOL drivers/video/svgalib 0x513e9f65 svga_tileblit +EXPORT_SYMBOL drivers/video/svgalib 0x55bcf9a8 svga_settile +EXPORT_SYMBOL drivers/video/svgalib 0x55c6ad32 svga_tilefill +EXPORT_SYMBOL drivers/video/svgalib 0x63e898d1 svga_set_default_crt_regs +EXPORT_SYMBOL drivers/video/svgalib 0x6486adda svga_get_caps +EXPORT_SYMBOL drivers/video/svgalib 0x7a3ae959 svga_wcrt_multi +EXPORT_SYMBOL drivers/video/svgalib 0x80408443 svga_set_timings +EXPORT_SYMBOL drivers/video/svgalib 0x8fa8438b svga_set_textmode_vga_regs +EXPORT_SYMBOL drivers/video/svgalib 0xab3b22ad svga_set_default_gfx_regs +EXPORT_SYMBOL drivers/video/svgalib 0xd959a181 svga_tilecopy +EXPORT_SYMBOL drivers/video/svgalib 0xdad682b1 svga_set_default_atc_regs +EXPORT_SYMBOL drivers/video/svgalib 0xe1d7cee7 svga_get_tilemax +EXPORT_SYMBOL drivers/video/svgalib 0xec83c473 svga_match_format +EXPORT_SYMBOL drivers/video/svgalib 0xef774f5d svga_compute_pll +EXPORT_SYMBOL drivers/video/syscopyarea 0x96027e88 sys_copyarea +EXPORT_SYMBOL drivers/video/sysfillrect 0x9c7b18dd sys_fillrect +EXPORT_SYMBOL drivers/video/sysimgblt 0xb9e95906 sys_imageblit +EXPORT_SYMBOL drivers/video/vgastate 0x686de290 restore_vga +EXPORT_SYMBOL drivers/video/vgastate 0xe7a2620e save_vga +EXPORT_SYMBOL drivers/w1/slaves/w1_bq27000 0x12a2face w1_bq27000_write +EXPORT_SYMBOL drivers/w1/slaves/w1_bq27000 0xed142032 w1_bq27000_read +EXPORT_SYMBOL drivers/w1/slaves/w1_ds2760 0x1597cae7 w1_ds2760_read +EXPORT_SYMBOL drivers/w1/slaves/w1_ds2760 0xaaa7c65c w1_ds2760_write +EXPORT_SYMBOL drivers/w1/wire 0x02bed5c8 w1_unregister_family +EXPORT_SYMBOL drivers/w1/wire 0x18c202ea w1_add_master_device +EXPORT_SYMBOL drivers/w1/wire 0x28e7b5ec w1_remove_master_device +EXPORT_SYMBOL drivers/w1/wire 0xe440b712 w1_register_family +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0x04e133fc iTCO_vendor_check_noreboot_on +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0x672c9d44 iTCO_vendor_pre_keepalive +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xa78bd894 iTCO_vendor_pre_set_heartbeat +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xa8d6daac iTCO_vendor_pre_start +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xd0efe320 iTCO_vendor_pre_stop +EXPORT_SYMBOL fs/configfs/configfs 0x10fe2451 configfs_undepend_item +EXPORT_SYMBOL fs/configfs/configfs 0x19ebf19b config_item_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0x5399c7f3 config_item_init +EXPORT_SYMBOL fs/configfs/configfs 0x555ab1d8 configfs_depend_item +EXPORT_SYMBOL fs/configfs/configfs 0x6d34e075 configfs_register_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0x92601909 configfs_unregister_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0xa0f6c135 config_item_put +EXPORT_SYMBOL fs/configfs/configfs 0xa1cf56cf config_group_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0xa750e5d9 config_group_find_item +EXPORT_SYMBOL fs/configfs/configfs 0xd45a6ca6 config_item_set_name +EXPORT_SYMBOL fs/configfs/configfs 0xf166c617 config_item_get +EXPORT_SYMBOL fs/configfs/configfs 0xf8da3fd7 config_group_init +EXPORT_SYMBOL fs/lockd/lockd 0x38a3c7da nlmsvc_ops +EXPORT_SYMBOL fs/lockd/lockd 0xa7b91a7b lockd_down +EXPORT_SYMBOL fs/lockd/lockd 0xf6933c48 lockd_up +EXPORT_SYMBOL fs/nfs_common/nfs_acl 0x9f22b68f nfsacl_decode +EXPORT_SYMBOL fs/nfs_common/nfs_acl 0xea4dec89 nfsacl_encode +EXPORT_SYMBOL fs/nfsd/nfsd 0x23f0a2c8 nfs4_acl_nfsv4_to_posix +EXPORT_SYMBOL fs/nfsd/nfsd 0x35e33c1e nfs4_acl_write_who +EXPORT_SYMBOL fs/nfsd/nfsd 0x46ffdc39 nfs4_acl_posix_to_nfsv4 +EXPORT_SYMBOL fs/nfsd/nfsd 0x5a157ae4 nfs4_acl_get_whotype +EXPORT_SYMBOL fs/nfsd/nfsd 0x96ce9bb4 nfs4_acl_new +EXPORT_SYMBOL fs/xfs/xfs 0x06ebf741 xfs_qmcore_xfs +EXPORT_SYMBOL lib/crc-ccitt 0x651c2313 crc_ccitt +EXPORT_SYMBOL lib/crc-ccitt 0x75811312 crc_ccitt_table +EXPORT_SYMBOL lib/crc-itu-t 0x276c7e62 crc_itu_t +EXPORT_SYMBOL lib/crc-itu-t 0xd29b009f crc_itu_t_table +EXPORT_SYMBOL lib/crc7 0xc086bfba crc7 +EXPORT_SYMBOL lib/crc7 0xd80c3603 crc7_syndrome_table +EXPORT_SYMBOL lib/libcrc32c 0x13c0c38e crc32c_le +EXPORT_SYMBOL lib/libcrc32c 0x41bcd8b3 crc32c_be +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0x315c65fd zlib_deflateInit2 +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0x48034724 zlib_deflateReset +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xaf64ad0d zlib_deflate +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xf0caf44b zlib_deflate_workspacesize +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xf741c793 zlib_deflateEnd +EXPORT_SYMBOL net/802/p8023 0x74323c9b make_8023_client +EXPORT_SYMBOL net/802/p8023 0xe0ea8821 destroy_8023_client +EXPORT_SYMBOL net/9p/9pnet 0x029a693d p9_client_walk +EXPORT_SYMBOL net/9p/9pnet 0x08ee3bfc p9_client_wstat +EXPORT_SYMBOL net/9p/9pnet 0x0b3ac49a p9pdu_dump +EXPORT_SYMBOL net/9p/9pnet 0x0ce66b90 p9_client_remove +EXPORT_SYMBOL net/9p/9pnet 0x11a8e7c8 p9_client_clunk +EXPORT_SYMBOL net/9p/9pnet 0x160dd0c2 v9fs_unregister_trans +EXPORT_SYMBOL net/9p/9pnet 0x244c6d40 p9_idpool_get +EXPORT_SYMBOL net/9p/9pnet 0x2d4949e9 p9_client_write +EXPORT_SYMBOL net/9p/9pnet 0x3d73a797 p9_errstr2errno +EXPORT_SYMBOL net/9p/9pnet 0x41e6bc51 p9_parse_header +EXPORT_SYMBOL net/9p/9pnet 0x47141098 p9_client_open +EXPORT_SYMBOL net/9p/9pnet 0x5734bdb3 p9_client_cb +EXPORT_SYMBOL net/9p/9pnet 0x5e0ef374 p9_idpool_check +EXPORT_SYMBOL net/9p/9pnet 0x5e6d5179 p9_client_auth +EXPORT_SYMBOL net/9p/9pnet 0x61852dea p9_idpool_put +EXPORT_SYMBOL net/9p/9pnet 0x67e0b648 p9_client_stat +EXPORT_SYMBOL net/9p/9pnet 0x6c5e479c p9_idpool_create +EXPORT_SYMBOL net/9p/9pnet 0x76b79bf1 p9stat_read +EXPORT_SYMBOL net/9p/9pnet 0x79472263 v9fs_get_default_trans +EXPORT_SYMBOL net/9p/9pnet 0x7fcbcded v9fs_register_trans +EXPORT_SYMBOL net/9p/9pnet 0x8b21990d p9_client_create +EXPORT_SYMBOL net/9p/9pnet 0x9c964743 p9stat_free +EXPORT_SYMBOL net/9p/9pnet 0xa78787fd p9_client_disconnect +EXPORT_SYMBOL net/9p/9pnet 0xaa1596e9 p9_client_attach +EXPORT_SYMBOL net/9p/9pnet 0xb31e80bc p9_client_fcreate +EXPORT_SYMBOL net/9p/9pnet 0xbaa17b44 p9_idpool_destroy +EXPORT_SYMBOL net/9p/9pnet 0xc83ea934 p9_client_destroy +EXPORT_SYMBOL net/9p/9pnet 0xca8b4a1a p9_client_version +EXPORT_SYMBOL net/9p/9pnet 0xccdf7c0f v9fs_get_trans_by_name +EXPORT_SYMBOL net/9p/9pnet 0xd1e17491 p9_tag_lookup +EXPORT_SYMBOL net/9p/9pnet 0xe3bebafe p9_client_read +EXPORT_SYMBOL net/9p/9pnet 0xe58a3360 p9_error_init +EXPORT_SYMBOL net/appletalk/appletalk 0x107877ed atrtr_get_dev +EXPORT_SYMBOL net/appletalk/appletalk 0x683ddbba alloc_ltalkdev +EXPORT_SYMBOL net/appletalk/appletalk 0x9e19cddc aarp_send_ddp +EXPORT_SYMBOL net/appletalk/appletalk 0xb9e251a5 atalk_find_dev_addr +EXPORT_SYMBOL net/ax25/ax25 0x0479d44f ax25_findbyuid +EXPORT_SYMBOL net/ax25/ax25 0x1955e1c2 ax25_rebuild_header +EXPORT_SYMBOL net/ax25/ax25 0x1ab238f5 ax25_hard_header +EXPORT_SYMBOL net/ax25/ax25 0x2023afd2 ax25_find_cb +EXPORT_SYMBOL net/ax25/ax25 0x242852b9 ax25_uid_policy +EXPORT_SYMBOL net/ax25/ax25 0x3d2d82ec ax25_display_timer +EXPORT_SYMBOL net/ax25/ax25 0x4502c65a asc2ax +EXPORT_SYMBOL net/ax25/ax25 0x4a1bfbeb ax25_send_frame +EXPORT_SYMBOL net/ax25/ax25 0x53dea1ff ax2asc +EXPORT_SYMBOL net/ax25/ax25 0x6b4a5b83 ax25_header_ops +EXPORT_SYMBOL net/ax25/ax25 0x712f4cdf ax25_linkfail_register +EXPORT_SYMBOL net/ax25/ax25 0x83235b9a ax25_listen_register +EXPORT_SYMBOL net/ax25/ax25 0x8ede9e26 ax25_protocol_release +EXPORT_SYMBOL net/ax25/ax25 0xc1444946 ax25cmp +EXPORT_SYMBOL net/ax25/ax25 0xcd9bf19c ax25_listen_release +EXPORT_SYMBOL net/ax25/ax25 0xd43ecbf1 null_ax25_address +EXPORT_SYMBOL net/ax25/ax25 0xe59fa4f0 ax25_linkfail_release +EXPORT_SYMBOL net/bridge/bridge 0x5ca39b32 br_should_route_hook +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0x10779d17 ebt_unregister_table +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0x4ad1a9e5 ebt_register_table +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0xb9b50b0b ebt_do_table +EXPORT_SYMBOL net/ieee80211/ieee80211 0x060fb12f ieee80211_get_channel_flags +EXPORT_SYMBOL net/ieee80211/ieee80211 0x147d33c6 ieee80211_freq_to_channel +EXPORT_SYMBOL net/ieee80211/ieee80211 0x21d15068 ieee80211_wx_get_encodeext +EXPORT_SYMBOL net/ieee80211/ieee80211 0x360c8f86 ieee80211_rx_mgt +EXPORT_SYMBOL net/ieee80211/ieee80211 0x372440cf ieee80211_channel_to_freq +EXPORT_SYMBOL net/ieee80211/ieee80211 0x493eb11c ieee80211_wx_get_encode +EXPORT_SYMBOL net/ieee80211/ieee80211 0x510e1f20 ieee80211_is_valid_channel +EXPORT_SYMBOL net/ieee80211/ieee80211 0x5ef67fc9 ieee80211_get_geo +EXPORT_SYMBOL net/ieee80211/ieee80211 0x853785c1 ieee80211_txb_free +EXPORT_SYMBOL net/ieee80211/ieee80211 0x8dfd0507 ieee80211_wx_set_encode +EXPORT_SYMBOL net/ieee80211/ieee80211 0xa0bf3775 ieee80211_channel_to_index +EXPORT_SYMBOL net/ieee80211/ieee80211 0xa9fb135f escape_essid +EXPORT_SYMBOL net/ieee80211/ieee80211 0xb366e48b ieee80211_wx_set_encodeext +EXPORT_SYMBOL net/ieee80211/ieee80211 0xb5418393 ieee80211_set_geo +EXPORT_SYMBOL net/ieee80211/ieee80211 0xba56042e alloc_ieee80211 +EXPORT_SYMBOL net/ieee80211/ieee80211 0xc761852c ieee80211_rx +EXPORT_SYMBOL net/ieee80211/ieee80211 0xda4bcfee free_ieee80211 +EXPORT_SYMBOL net/ieee80211/ieee80211 0xebe81936 ieee80211_networks_age +EXPORT_SYMBOL net/ieee80211/ieee80211 0xec2968f0 ieee80211_get_channel +EXPORT_SYMBOL net/ieee80211/ieee80211 0xf8dd08eb ieee80211_wx_get_scan +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x15a3f5d7 ieee80211_crypt_delayed_deinit +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x279e265f ieee80211_crypt_deinit_handler +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x35d418dc ieee80211_register_crypto_ops +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x85df8d13 ieee80211_crypt_quiescing +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x8d5d6b35 ieee80211_get_crypto_ops +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x94001580 ieee80211_crypt_deinit_entries +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0xca44d2f2 ieee80211_unregister_crypto_ops +EXPORT_SYMBOL net/ipv4/inet_lro 0x1c3571ce lro_receive_skb +EXPORT_SYMBOL net/ipv4/inet_lro 0x67a81f52 lro_flush_all +EXPORT_SYMBOL net/ipv4/inet_lro 0x7491fb4e lro_vlan_hwaccel_receive_skb +EXPORT_SYMBOL net/ipv4/inet_lro 0xa62178e4 lro_flush_pkt +EXPORT_SYMBOL net/ipv4/inet_lro 0xee561c7e lro_vlan_hwaccel_receive_frags +EXPORT_SYMBOL net/ipv4/inet_lro 0xfd05a75d lro_receive_frags +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x0a0b62a0 arpt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x9553cc88 arpt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0xa89bd2a5 arpt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0x24b7f399 ipt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0xb24166ce ipt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0xcd8e353b ipt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x093387d2 nf_nat_setup_info +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x397f130b nf_nat_protocol_register +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x561b9a30 nf_nat_protocol_unregister +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x614c9d7f nf_nat_follow_master +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x61ef1530 nf_nat_mangle_udp_packet +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0xbb2b6e52 nf_nat_mangle_tcp_packet +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0xcf5f7ac6 nf_nat_used_tuple +EXPORT_SYMBOL net/ipv4/tunnel4 0x5aa99d76 xfrm4_tunnel_deregister +EXPORT_SYMBOL net/ipv4/tunnel4 0xab0af138 xfrm4_tunnel_register +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x0167de9d ip6t_register_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x01cd2e95 ipv6_find_hdr +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x5245476d ip6t_do_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x5fe18cec ip6t_unregister_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xb8bddf33 ip6t_ext_hdr +EXPORT_SYMBOL net/ipv6/tunnel6 0x344bfab7 xfrm6_tunnel_deregister +EXPORT_SYMBOL net/ipv6/tunnel6 0x5a15e353 xfrm6_tunnel_register +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0x9cd013f2 xfrm6_tunnel_alloc_spi +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0xab14e193 xfrm6_tunnel_free_spi +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0xdb1b42d1 xfrm6_tunnel_spi_lookup +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x36afa602 ircomm_control_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x587a95c6 ircomm_connect_response +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x6aedd015 ircomm_close +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x73787663 ircomm_flow_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x9b6079da ircomm_open +EXPORT_SYMBOL net/irda/ircomm/ircomm 0xb62da6ae ircomm_connect_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0xd0f4cf66 ircomm_disconnect_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0xd505f341 ircomm_data_request +EXPORT_SYMBOL net/irda/irda 0x01d1fcdb hashbin_delete +EXPORT_SYMBOL net/irda/irda 0x06a3ee58 irias_new_integer_value +EXPORT_SYMBOL net/irda/irda 0x072e026f irias_add_octseq_attrib +EXPORT_SYMBOL net/irda/irda 0x07d3647c irlmp_register_service +EXPORT_SYMBOL net/irda/irda 0x1068c113 irttp_connect_request +EXPORT_SYMBOL net/irda/irda 0x1726003f iriap_getvaluebyclass_request +EXPORT_SYMBOL net/irda/irda 0x1cbe465f irda_device_set_media_busy +EXPORT_SYMBOL net/irda/irda 0x1e6c4f64 proc_irda +EXPORT_SYMBOL net/irda/irda 0x2036ad06 irda_param_insert +EXPORT_SYMBOL net/irda/irda 0x32f19039 irttp_flow_request +EXPORT_SYMBOL net/irda/irda 0x3462950f hashbin_remove +EXPORT_SYMBOL net/irda/irda 0x3631112a async_unwrap_char +EXPORT_SYMBOL net/irda/irda 0x38a20e5b irda_debug +EXPORT_SYMBOL net/irda/irda 0x448b8aaa irda_qos_bits_to_value +EXPORT_SYMBOL net/irda/irda 0x46c1c4a2 irlmp_unregister_service +EXPORT_SYMBOL net/irda/irda 0x4cb5523c alloc_irdadev +EXPORT_SYMBOL net/irda/irda 0x4e7db259 irlmp_connect_request +EXPORT_SYMBOL net/irda/irda 0x5c2d0cda async_wrap_skb +EXPORT_SYMBOL net/irda/irda 0x5ca96dc4 irttp_disconnect_request +EXPORT_SYMBOL net/irda/irda 0x654c7e81 irttp_udata_request +EXPORT_SYMBOL net/irda/irda 0x6758f8ac irias_new_object +EXPORT_SYMBOL net/irda/irda 0x68b7447c hashbin_find +EXPORT_SYMBOL net/irda/irda 0x6b043eba irda_init_max_qos_capabilies +EXPORT_SYMBOL net/irda/irda 0x6f91f9e7 irlap_open +EXPORT_SYMBOL net/irda/irda 0x7042bc54 irlmp_register_client +EXPORT_SYMBOL net/irda/irda 0x747d6779 irias_delete_object +EXPORT_SYMBOL net/irda/irda 0x7621e908 hashbin_insert +EXPORT_SYMBOL net/irda/irda 0x76243bc9 irias_insert_object +EXPORT_SYMBOL net/irda/irda 0x763e54a4 irlmp_unregister_client +EXPORT_SYMBOL net/irda/irda 0x7745f266 irlap_close +EXPORT_SYMBOL net/irda/irda 0x781e2db5 irias_find_object +EXPORT_SYMBOL net/irda/irda 0x7957f728 irlmp_update_client +EXPORT_SYMBOL net/irda/irda 0x7a57b6f3 hashbin_remove_this +EXPORT_SYMBOL net/irda/irda 0x91815586 irda_param_pack +EXPORT_SYMBOL net/irda/irda 0x993ad14b irda_param_extract_all +EXPORT_SYMBOL net/irda/irda 0x9f1c93c8 irlmp_data_request +EXPORT_SYMBOL net/irda/irda 0xa3accaf4 irttp_data_request +EXPORT_SYMBOL net/irda/irda 0xaafef94d irttp_open_tsap +EXPORT_SYMBOL net/irda/irda 0xb07156bf iriap_open +EXPORT_SYMBOL net/irda/irda 0xb9394173 irias_delete_value +EXPORT_SYMBOL net/irda/irda 0xbcd3ef13 irias_object_change_attribute +EXPORT_SYMBOL net/irda/irda 0xbe40ace9 irlmp_discovery_request +EXPORT_SYMBOL net/irda/irda 0xbee2ae01 irlmp_connect_response +EXPORT_SYMBOL net/irda/irda 0xc14e9b6a hashbin_get_next +EXPORT_SYMBOL net/irda/irda 0xc6d36e31 irttp_connect_response +EXPORT_SYMBOL net/irda/irda 0xcd41236c hashbin_new +EXPORT_SYMBOL net/irda/irda 0xd6b266d5 irlmp_disconnect_request +EXPORT_SYMBOL net/irda/irda 0xd6deeaae irda_setup_dma +EXPORT_SYMBOL net/irda/irda 0xd7172ff4 hashbin_get_first +EXPORT_SYMBOL net/irda/irda 0xd8bfb6d4 hashbin_lock_find +EXPORT_SYMBOL net/irda/irda 0xd9b024fa irttp_close_tsap +EXPORT_SYMBOL net/irda/irda 0xdb64f8dc irlmp_close_lsap +EXPORT_SYMBOL net/irda/irda 0xde4c6b3c irlmp_service_to_hint +EXPORT_SYMBOL net/irda/irda 0xe5260e0e irias_add_integer_attrib +EXPORT_SYMBOL net/irda/irda 0xec41fe7f irias_add_string_attrib +EXPORT_SYMBOL net/irda/irda 0xedd521c2 irlmp_get_discoveries +EXPORT_SYMBOL net/irda/irda 0xf0ea5b96 irda_notify_init +EXPORT_SYMBOL net/irda/irda 0xf8e5180e iriap_close +EXPORT_SYMBOL net/irda/irda 0xfd778f75 irttp_dup +EXPORT_SYMBOL net/irda/irda 0xfe1cd3e3 irlmp_open_lsap +EXPORT_SYMBOL net/lapb/lapb 0x09a88385 lapb_getparms +EXPORT_SYMBOL net/lapb/lapb 0x1ab8aaa7 lapb_disconnect_request +EXPORT_SYMBOL net/lapb/lapb 0x2ec10340 lapb_connect_request +EXPORT_SYMBOL net/lapb/lapb 0x4cdc5541 lapb_data_received +EXPORT_SYMBOL net/lapb/lapb 0x70577819 lapb_setparms +EXPORT_SYMBOL net/lapb/lapb 0xa0231801 lapb_unregister +EXPORT_SYMBOL net/lapb/lapb 0xb43b7095 lapb_data_request +EXPORT_SYMBOL net/lapb/lapb 0xce32ee4d lapb_register +EXPORT_SYMBOL net/mac80211/mac80211 0x08228b21 ieee80211_tx_status +EXPORT_SYMBOL net/mac80211/mac80211 0x085269e5 ieee80211_stop_tx_ba_session +EXPORT_SYMBOL net/mac80211/mac80211 0x189b3560 ieee80211_wake_queue +EXPORT_SYMBOL net/mac80211/mac80211 0x18e4be16 ieee80211_scan_completed +EXPORT_SYMBOL net/mac80211/mac80211 0x1fae2c72 ieee80211_start_tx_ba_cb +EXPORT_SYMBOL net/mac80211/mac80211 0x25cbbda9 ieee80211_register_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x2771de65 ieee80211_rate_control_register +EXPORT_SYMBOL net/mac80211/mac80211 0x2ca13350 ieee80211_get_buffered_bc +EXPORT_SYMBOL net/mac80211/mac80211 0x30e0ce5b ieee80211_tx_status_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x331df38d ieee80211_stop_tx_ba_cb +EXPORT_SYMBOL net/mac80211/mac80211 0x39ed1882 ieee80211_stop_queue +EXPORT_SYMBOL net/mac80211/mac80211 0x3b159617 ieee80211_wake_queues +EXPORT_SYMBOL net/mac80211/mac80211 0x41f3d137 __ieee80211_get_radio_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x446a6953 ieee80211_ctstoself_duration +EXPORT_SYMBOL net/mac80211/mac80211 0x5f2c8e51 ieee80211_free_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x625c72d0 __ieee80211_get_assoc_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x67385434 ieee80211_get_hdrlen_from_skb +EXPORT_SYMBOL net/mac80211/mac80211 0x6cd3d91c __ieee80211_rx +EXPORT_SYMBOL net/mac80211/mac80211 0x7436a56c ieee80211_stop_queues +EXPORT_SYMBOL net/mac80211/mac80211 0x76758222 ieee80211_alloc_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x7b3bccad __ieee80211_get_rx_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x7f305ba2 ieee80211_find_sta +EXPORT_SYMBOL net/mac80211/mac80211 0x8a6331a7 ieee80211_rts_get +EXPORT_SYMBOL net/mac80211/mac80211 0x8a6adfdd ieee80211_rts_duration +EXPORT_SYMBOL net/mac80211/mac80211 0x8c35d732 ieee80211_hdrlen +EXPORT_SYMBOL net/mac80211/mac80211 0x8cf32f16 ieee80211_start_tx_ba_cb_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x97e21c41 wiphy_to_hw +EXPORT_SYMBOL net/mac80211/mac80211 0xa2f392f3 ieee80211_unregister_hw +EXPORT_SYMBOL net/mac80211/mac80211 0xa5780c96 ieee80211_generic_frame_duration +EXPORT_SYMBOL net/mac80211/mac80211 0xb006e36b ieee80211_queue_stopped +EXPORT_SYMBOL net/mac80211/mac80211 0xb4355840 __ieee80211_get_tx_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0xbceb637a ieee80211_get_tkip_key +EXPORT_SYMBOL net/mac80211/mac80211 0xc7f51a89 ieee80211_rx_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0xcef43733 ieee80211_rate_control_unregister +EXPORT_SYMBOL net/mac80211/mac80211 0xd2b4d38d ieee80211_beacon_get +EXPORT_SYMBOL net/mac80211/mac80211 0xee2a13fc ieee80211_ctstoself_get +EXPORT_SYMBOL net/mac80211/mac80211 0xf96b979d ieee80211_stop_tx_ba_cb_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0xfd0950db ieee80211_start_tx_ba_session +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x17a65385 unregister_ip_vs_scheduler +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x215c0602 ip_vs_conn_new +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x4ab630fc ip_vs_tcp_conn_listen +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x4f3e3168 ip_vs_conn_put +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x763462e5 unregister_ip_vs_app +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x7c533504 ip_vs_conn_in_get +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x80032532 ip_vs_conn_out_get +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x8386e332 register_ip_vs_app_inc +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xa1dbc2d8 ip_vs_proto_name +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xb8e8f458 register_ip_vs_scheduler +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xd838d9fc register_ip_vs_app +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xe30ca082 ip_vs_skb_replace +EXPORT_SYMBOL net/netfilter/nf_conntrack 0x8fb4ee7a __nf_ct_ext_destroy +EXPORT_SYMBOL net/netfilter/nf_conntrack 0xe372c1b6 __nf_ct_ext_add +EXPORT_SYMBOL net/netfilter/nf_conntrack_proto_gre 0x7937209a nf_ct_gre_keymap_flush +EXPORT_SYMBOL net/netfilter/x_tables 0x09f928ea xt_find_match +EXPORT_SYMBOL net/netfilter/x_tables 0x3dcd58c5 xt_alloc_table_info +EXPORT_SYMBOL net/netfilter/x_tables 0x5851432b xt_register_targets +EXPORT_SYMBOL net/netfilter/x_tables 0x5bfad9f3 xt_unregister_targets +EXPORT_SYMBOL net/netfilter/x_tables 0x765f8557 xt_unregister_target +EXPORT_SYMBOL net/netfilter/x_tables 0xabd46db5 xt_register_target +EXPORT_SYMBOL net/netfilter/x_tables 0xc6f16bc8 xt_unregister_matches +EXPORT_SYMBOL net/netfilter/x_tables 0xcd60aed9 xt_find_target +EXPORT_SYMBOL net/netfilter/x_tables 0xdc462e0e xt_register_matches +EXPORT_SYMBOL net/netfilter/x_tables 0xe0c3c0f9 xt_register_match +EXPORT_SYMBOL net/netfilter/x_tables 0xf7037dc6 xt_free_table_info +EXPORT_SYMBOL net/netfilter/x_tables 0xfd5e72e9 xt_unregister_match +EXPORT_SYMBOL net/phonet/phonet 0x02b16a0c pn_skb_send +EXPORT_SYMBOL net/phonet/phonet 0x08febbf3 phonet_header_ops +EXPORT_SYMBOL net/phonet/phonet 0x1106a4be phonet_proto_register +EXPORT_SYMBOL net/phonet/phonet 0x13fa16a5 pn_sock_hash +EXPORT_SYMBOL net/phonet/phonet 0x26b54660 pn_sock_get_port +EXPORT_SYMBOL net/phonet/phonet 0x43b82849 pn_sock_unhash +EXPORT_SYMBOL net/phonet/phonet 0x89d47352 phonet_proto_unregister +EXPORT_SYMBOL net/phonet/phonet 0x9d66fe33 phonet_stream_ops +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x18be3534 rxrpc_kernel_accept_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x21c7e940 rxrpc_kernel_is_data_last +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x344e577b rxrpc_kernel_reject_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x474ce1ff rxrpc_kernel_abort_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x499668fe rxrpc_kernel_send_data +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x580e7e00 rxrpc_kernel_end_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x6795a6d3 key_type_rxrpc +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x70c56c75 rxrpc_kernel_begin_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x7f136cb1 rxrpc_get_server_data_key +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x84438924 rxrpc_kernel_get_error_number +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x95f91085 rxrpc_kernel_get_abort_code +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xb0b0eb1b rxrpc_kernel_free_skb +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xd3b48148 rxrpc_kernel_data_delivered +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xdc342317 rxrpc_get_null_key +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xf55a4051 rxrpc_kernel_intercept_rx_messages +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x00c52ef5 g_make_token_header +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x1b74ab7a gss_mech_put +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x4d203cef gss_mech_get_by_name +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x4f328f81 gss_mech_register +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x8d1a827e svcauth_gss_register_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x90a44498 gss_svc_to_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xa7623331 gss_pseudoflavor_to_service +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xa7fcc285 gss_mech_get +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xb3146ec4 gss_mech_get_by_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xb5dea7ef g_token_size +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xcaa4524c svcauth_gss_flavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xdde79bfb gss_service_to_auth_domain_name +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xe2dbcb33 gss_mech_unregister +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xf8b2ff6e g_verify_token_header +EXPORT_SYMBOL net/sunrpc/sunrpc 0x02c424af svc_seq_show +EXPORT_SYMBOL net/sunrpc/sunrpc 0x05e807a9 xdr_encode_string +EXPORT_SYMBOL net/sunrpc/sunrpc 0x065994f1 xdr_encode_opaque_fixed +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0ae96559 unix_domain_find +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0b3d2b49 xdr_enter_page +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0c21eca7 sunrpc_cache_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0f668ba9 svc_auth_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x12e280e3 svc_proc_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x1d57a21d xdr_inline_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0x251e14ad svc_prepare_thread +EXPORT_SYMBOL net/sunrpc/sunrpc 0x25dbd661 svc_set_num_threads +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2919b156 xdr_decode_string_inplace +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2ba53ef7 cache_check +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2e401365 xdr_buf_subsegment +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2eec63c9 xdr_encode_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0x50e39896 cache_purge +EXPORT_SYMBOL net/sunrpc/sunrpc 0x5146aed4 read_bytes_from_xdr_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0x528a3158 xdr_write_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0x56ee9ab2 svc_auth_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0x6eea229d svcauth_unix_purge +EXPORT_SYMBOL net/sunrpc/sunrpc 0x71d765b7 xdr_decode_word +EXPORT_SYMBOL net/sunrpc/sunrpc 0x71fa908a cache_flush +EXPORT_SYMBOL net/sunrpc/sunrpc 0x752598e6 xdr_decode_array2 +EXPORT_SYMBOL net/sunrpc/sunrpc 0x7829f18d sunrpc_cache_update +EXPORT_SYMBOL net/sunrpc/sunrpc 0x785bdadd cache_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0x7e9d84a1 rpc_unlink +EXPORT_SYMBOL net/sunrpc/sunrpc 0x82121833 xdr_buf_from_iov +EXPORT_SYMBOL net/sunrpc/sunrpc 0x84e66963 auth_domain_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0x886dee72 rpc_mkpipe +EXPORT_SYMBOL net/sunrpc/sunrpc 0x8a52e726 svc_authenticate +EXPORT_SYMBOL net/sunrpc/sunrpc 0x8e0039cb xdr_buf_read_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0x92929a9f svc_reserve +EXPORT_SYMBOL net/sunrpc/sunrpc 0x976cf9b2 svc_sock_update_bufs +EXPORT_SYMBOL net/sunrpc/sunrpc 0x9f7f5755 svcauth_unix_set_client +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa281cf78 svc_sock_names +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa4b9f1bb svc_destroy +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa63bf43f svc_process +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa8dcacf8 auth_unix_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0xaa66bfc7 auth_domain_find +EXPORT_SYMBOL net/sunrpc/sunrpc 0xaaf34f46 auth_domain_put +EXPORT_SYMBOL net/sunrpc/sunrpc 0xb3ae1e4f auth_unix_forget_old +EXPORT_SYMBOL net/sunrpc/sunrpc 0xb65ccd2f xdr_reserve_space +EXPORT_SYMBOL net/sunrpc/sunrpc 0xb7790a42 svc_recv +EXPORT_SYMBOL net/sunrpc/sunrpc 0xb8574a97 cache_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc3880471 xdr_decode_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc48ea26f svc_proc_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc51d9167 svc_wake_up +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc77c89e4 xdr_shift_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc8e96dea qword_addhex +EXPORT_SYMBOL net/sunrpc/sunrpc 0xced899bb svc_drop +EXPORT_SYMBOL net/sunrpc/sunrpc 0xcf4aef05 xdr_encode_array2 +EXPORT_SYMBOL net/sunrpc/sunrpc 0xcf83ad74 xdr_read_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0xd60c71f7 svc_create +EXPORT_SYMBOL net/sunrpc/sunrpc 0xda84ea51 xdr_encode_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0xdac125b2 svc_exit_thread +EXPORT_SYMBOL net/sunrpc/sunrpc 0xdee34d88 auth_unix_add_addr +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe28ba4fd xdr_process_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe5919cb1 xdr_encode_opaque +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe8a1df54 svc_create_pooled +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe97f4ce5 qword_get +EXPORT_SYMBOL net/sunrpc/sunrpc 0xedac8f2c xdr_encode_word +EXPORT_SYMBOL net/sunrpc/sunrpc 0xedcf6be4 qword_add +EXPORT_SYMBOL net/sunrpc/sunrpc 0xf06beabc xdr_init_encode +EXPORT_SYMBOL net/sunrpc/sunrpc 0xf0799ac1 rpc_queue_upcall +EXPORT_SYMBOL net/sunrpc/sunrpc 0xf4197150 xdr_init_decode +EXPORT_SYMBOL net/sunrpc/sunrpc 0xf8d32f5f xdr_inline_decode +EXPORT_SYMBOL net/sunrpc/sunrpc 0xfcceb775 svc_set_client +EXPORT_SYMBOL net/tipc/tipc 0x086f02a2 tipc_send_buf +EXPORT_SYMBOL net/tipc/tipc 0x08acf310 tipc_available_nodes +EXPORT_SYMBOL net/tipc/tipc 0x0b074a7b tipc_multicast +EXPORT_SYMBOL net/tipc/tipc 0x10d40fcd tipc_isconnected +EXPORT_SYMBOL net/tipc/tipc 0x1472b270 tipc_disconnect +EXPORT_SYMBOL net/tipc/tipc 0x1479cb03 tipc_deleteport +EXPORT_SYMBOL net/tipc/tipc 0x15b5ecde tipc_set_portunreliable +EXPORT_SYMBOL net/tipc/tipc 0x16f27683 tipc_block_bearer +EXPORT_SYMBOL net/tipc/tipc 0x23daecbd tipc_send +EXPORT_SYMBOL net/tipc/tipc 0x259b74f9 tipc_acknowledge +EXPORT_SYMBOL net/tipc/tipc 0x28d26670 tipc_register_media +EXPORT_SYMBOL net/tipc/tipc 0x2c8d2f2b tipc_createport +EXPORT_SYMBOL net/tipc/tipc 0x310d1bc9 tipc_detach +EXPORT_SYMBOL net/tipc/tipc 0x3712e340 tipc_portunreliable +EXPORT_SYMBOL net/tipc/tipc 0x3976041f tipc_set_portimportance +EXPORT_SYMBOL net/tipc/tipc 0x401be2a2 tipc_send_buf_fast +EXPORT_SYMBOL net/tipc/tipc 0x419b02fc tipc_send2port +EXPORT_SYMBOL net/tipc/tipc 0x4b2243c6 tipc_portimportance +EXPORT_SYMBOL net/tipc/tipc 0x538b228a tipc_withdraw +EXPORT_SYMBOL net/tipc/tipc 0x54d9a95d tipc_send_buf2port +EXPORT_SYMBOL net/tipc/tipc 0x5637ed44 tipc_get_mode +EXPORT_SYMBOL net/tipc/tipc 0x56e52bc1 tipc_continue +EXPORT_SYMBOL net/tipc/tipc 0x5c0d4b5c tipc_ref_valid +EXPORT_SYMBOL net/tipc/tipc 0x62a681a3 tipc_portunreturnable +EXPORT_SYMBOL net/tipc/tipc 0x88b73627 tipc_get_addr +EXPORT_SYMBOL net/tipc/tipc 0x94b2b5b2 tipc_forward_buf2name +EXPORT_SYMBOL net/tipc/tipc 0x9c45558e tipc_enable_bearer +EXPORT_SYMBOL net/tipc/tipc 0xa1b42d32 tipc_forward2port +EXPORT_SYMBOL net/tipc/tipc 0xa75c5aeb tipc_recv_msg +EXPORT_SYMBOL net/tipc/tipc 0xa936a24b tipc_get_port +EXPORT_SYMBOL net/tipc/tipc 0xadd203d0 tipc_connect2port +EXPORT_SYMBOL net/tipc/tipc 0xae0103c3 tipc_shutdown +EXPORT_SYMBOL net/tipc/tipc 0xb1f8eacc tipc_send2name +EXPORT_SYMBOL net/tipc/tipc 0xb35b672c tipc_publish +EXPORT_SYMBOL net/tipc/tipc 0xb7f7cf09 tipc_forward_buf2port +EXPORT_SYMBOL net/tipc/tipc 0xcec8514a tipc_set_portunreturnable +EXPORT_SYMBOL net/tipc/tipc 0xcee290be tipc_forward2name +EXPORT_SYMBOL net/tipc/tipc 0xd44731e5 tipc_ownidentity +EXPORT_SYMBOL net/tipc/tipc 0xda7f9d3f tipc_attach +EXPORT_SYMBOL net/tipc/tipc 0xdf5008fc tipc_peer +EXPORT_SYMBOL net/tipc/tipc 0xe4f744f2 tipc_send_buf2name +EXPORT_SYMBOL net/tipc/tipc 0xe7aece47 tipc_ispublished +EXPORT_SYMBOL net/tipc/tipc 0xeefd49b3 tipc_get_handle +EXPORT_SYMBOL net/tipc/tipc 0xef50a1ef tipc_disable_bearer +EXPORT_SYMBOL net/tipc/tipc 0xf6e5e581 tipc_createport_raw +EXPORT_SYMBOL net/tipc/tipc 0xfc1627e5 tipc_reject_msg +EXPORT_SYMBOL net/wanrouter/wanrouter 0x0b4ccab1 register_wan_device +EXPORT_SYMBOL net/wanrouter/wanrouter 0x0ebe03d1 unregister_wan_device +EXPORT_SYMBOL net/wireless/cfg80211 0x07e7ac5a ieee80211_radiotap_iterator_init +EXPORT_SYMBOL net/wireless/cfg80211 0x09c64fbd ieee80211_frequency_to_channel +EXPORT_SYMBOL net/wireless/cfg80211 0x3645fc28 __ieee80211_get_channel +EXPORT_SYMBOL net/wireless/cfg80211 0x48deb77b wiphy_free +EXPORT_SYMBOL net/wireless/cfg80211 0x4cd156de wiphy_register +EXPORT_SYMBOL net/wireless/cfg80211 0x8c4ea500 wiphy_unregister +EXPORT_SYMBOL net/wireless/cfg80211 0x9d0489ca regulatory_hint +EXPORT_SYMBOL net/wireless/cfg80211 0xc4e85ec5 ieee80211_radiotap_iterator_next +EXPORT_SYMBOL net/wireless/cfg80211 0xccc291b3 ieee80211_channel_to_frequency +EXPORT_SYMBOL net/wireless/cfg80211 0xe09d8877 wiphy_new +EXPORT_SYMBOL sound/ac97_bus 0x07918f29 ac97_bus_type +EXPORT_SYMBOL sound/core/oss/snd-mixer-oss 0x200ad6d2 snd_mixer_oss_ioctl_card +EXPORT_SYMBOL sound/core/seq/snd-seq 0x1a724fcc snd_seq_kernel_client_ctl +EXPORT_SYMBOL sound/core/seq/snd-seq 0x2b9824d3 snd_seq_create_kernel_client +EXPORT_SYMBOL sound/core/seq/snd-seq 0x3061c52d snd_use_lock_sync_helper +EXPORT_SYMBOL sound/core/seq/snd-seq 0x3fb4d161 snd_seq_kernel_client_dispatch +EXPORT_SYMBOL sound/core/seq/snd-seq 0x6bb71038 snd_seq_delete_kernel_client +EXPORT_SYMBOL sound/core/seq/snd-seq 0x7ac2f329 snd_seq_expand_var_event +EXPORT_SYMBOL sound/core/seq/snd-seq 0x7b8699eb snd_seq_event_port_detach +EXPORT_SYMBOL sound/core/seq/snd-seq 0x8d486972 snd_seq_kernel_client_enqueue_blocking +EXPORT_SYMBOL sound/core/seq/snd-seq 0xb8e448a0 snd_seq_set_queue_tempo +EXPORT_SYMBOL sound/core/seq/snd-seq 0xc5e18e51 snd_seq_kernel_client_write_poll +EXPORT_SYMBOL sound/core/seq/snd-seq 0xcac0a3be snd_seq_kernel_client_enqueue +EXPORT_SYMBOL sound/core/seq/snd-seq 0xd5dcc83e snd_seq_event_port_attach +EXPORT_SYMBOL sound/core/seq/snd-seq 0xe934da1d snd_seq_dump_var_event +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x3a57f235 snd_seq_autoload_unlock +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x6339b6d0 snd_seq_device_load_drivers +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xb90668b2 snd_seq_autoload_lock +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xc622fb29 snd_seq_device_unregister_driver +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xd51bfe6f snd_seq_device_register_driver +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xe0cc79a0 snd_seq_device_new +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0x6ea09972 snd_midi_channel_alloc_set +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0x833a3e07 snd_midi_channel_set_clear +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0xb9948d2c snd_midi_channel_free_set +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0xf0a1fdb3 snd_midi_process_event +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x17c15809 snd_midi_event_decode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x4ad3f518 snd_midi_event_reset_decode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x62384d3a snd_midi_event_encode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x8a348811 snd_midi_event_reset_encode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x9df7af8b snd_midi_event_free +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xc482499d snd_midi_event_new +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xd9072e1a snd_midi_event_no_status +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xe6df29c7 snd_midi_event_encode_byte +EXPORT_SYMBOL sound/core/seq/snd-seq-virmidi 0xbc625809 snd_virmidi_new +EXPORT_SYMBOL sound/core/snd 0x15c65dcb snd_info_free_entry +EXPORT_SYMBOL sound/core/snd 0x18e1683f snd_dma_program +EXPORT_SYMBOL sound/core/snd 0x191e88cf snd_dma_pointer +EXPORT_SYMBOL sound/core/snd 0x198788b4 snd_lookup_oss_minor_data +EXPORT_SYMBOL sound/core/snd 0x1cf1b253 snd_device_new +EXPORT_SYMBOL sound/core/snd 0x24a94b26 snd_info_get_line +EXPORT_SYMBOL sound/core/snd 0x2a98c635 snd_power_wait +EXPORT_SYMBOL sound/core/snd 0x2ae3deaa release_and_free_resource +EXPORT_SYMBOL sound/core/snd 0x2b21f96f snd_register_oss_device +EXPORT_SYMBOL sound/core/snd 0x2bc174d0 snd_card_free +EXPORT_SYMBOL sound/core/snd 0x3971b4df snd_ecards_limit +EXPORT_SYMBOL sound/core/snd 0x39c671b9 snd_ctl_unregister_ioctl_compat +EXPORT_SYMBOL sound/core/snd 0x3cd618ca snd_ctl_notify +EXPORT_SYMBOL sound/core/snd 0x3f6c6bca snd_pci_quirk_lookup +EXPORT_SYMBOL sound/core/snd 0x41f573ca snd_info_register +EXPORT_SYMBOL sound/core/snd 0x428c00a4 snd_ctl_register_ioctl +EXPORT_SYMBOL sound/core/snd 0x45c3247d snd_ctl_boolean_mono_info +EXPORT_SYMBOL sound/core/snd 0x4a3ea5c0 snd_request_card +EXPORT_SYMBOL sound/core/snd 0x4cd1c6ec snd_ctl_remove +EXPORT_SYMBOL sound/core/snd 0x4e109350 snd_ctl_unregister_ioctl +EXPORT_SYMBOL sound/core/snd 0x4eae5ad0 snd_ctl_free_one +EXPORT_SYMBOL sound/core/snd 0x518bb7f8 copy_from_user_toio +EXPORT_SYMBOL sound/core/snd 0x5547650d snd_mixer_oss_notify_callback +EXPORT_SYMBOL sound/core/snd 0x57851758 snd_ctl_add +EXPORT_SYMBOL sound/core/snd 0x581aeb26 snd_card_proc_new +EXPORT_SYMBOL sound/core/snd 0x5e2b2c72 snd_device_free +EXPORT_SYMBOL sound/core/snd 0x63d7c993 snd_card_file_remove +EXPORT_SYMBOL sound/core/snd 0x6b94f55f snd_ctl_find_id +EXPORT_SYMBOL sound/core/snd 0x6c257e37 snd_ctl_register_ioctl_compat +EXPORT_SYMBOL sound/core/snd 0x70c15ac1 snd_dma_disable +EXPORT_SYMBOL sound/core/snd 0x71b229f9 snd_card_register +EXPORT_SYMBOL sound/core/snd 0x72f91e03 snd_device_register +EXPORT_SYMBOL sound/core/snd 0x75d963c7 snd_card_disconnect +EXPORT_SYMBOL sound/core/snd 0x7ec0440a snd_ctl_new1 +EXPORT_SYMBOL sound/core/snd 0x8a65ce0f snd_info_create_module_entry +EXPORT_SYMBOL sound/core/snd 0x8df3789f snd_oss_info_register +EXPORT_SYMBOL sound/core/snd 0x8f595b11 snd_major +EXPORT_SYMBOL sound/core/snd 0x9270a6b6 snd_unregister_oss_device +EXPORT_SYMBOL sound/core/snd 0x956ead8f snd_register_device_for_dev +EXPORT_SYMBOL sound/core/snd 0x9a9b1b18 snd_card_new +EXPORT_SYMBOL sound/core/snd 0x9b4e0101 snd_card_file_add +EXPORT_SYMBOL sound/core/snd 0x9cae4a65 snd_component_add +EXPORT_SYMBOL sound/core/snd 0xa316afe1 snd_ctl_add_slave +EXPORT_SYMBOL sound/core/snd 0xa33e1a09 snd_info_create_card_entry +EXPORT_SYMBOL sound/core/snd 0xaf765cd1 snd_card_free_when_closed +EXPORT_SYMBOL sound/core/snd 0xb213fe8b snd_info_get_str +EXPORT_SYMBOL sound/core/snd 0xb2e5ae4a snd_lookup_minor_data +EXPORT_SYMBOL sound/core/snd 0xda3ace2d snd_ctl_find_numid +EXPORT_SYMBOL sound/core/snd 0xde2b7038 snd_add_device_sysfs_file +EXPORT_SYMBOL sound/core/snd 0xdeaa266d snd_seq_root +EXPORT_SYMBOL sound/core/snd 0xe243dde3 copy_to_user_fromio +EXPORT_SYMBOL sound/core/snd 0xe4854cea snd_iprintf +EXPORT_SYMBOL sound/core/snd 0xe8a1bed7 snd_ctl_boolean_stereo_info +EXPORT_SYMBOL sound/core/snd 0xebc8c476 snd_cards +EXPORT_SYMBOL sound/core/snd 0xebcabc1e snd_ctl_rename_id +EXPORT_SYMBOL sound/core/snd 0xec040a1c snd_ctl_make_virtual_master +EXPORT_SYMBOL sound/core/snd 0xeeb13d65 snd_ctl_remove_id +EXPORT_SYMBOL sound/core/snd 0xef57da30 snd_unregister_device +EXPORT_SYMBOL sound/core/snd-hwdep 0x17db0fed snd_hwdep_new +EXPORT_SYMBOL sound/core/snd-page-alloc 0x19cc2ce3 snd_free_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0x2ca6c797 snd_dma_alloc_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0x399fe6f1 snd_dma_alloc_pages_fallback +EXPORT_SYMBOL sound/core/snd-page-alloc 0x5a1328a3 snd_dma_get_reserved_buf +EXPORT_SYMBOL sound/core/snd-page-alloc 0x5d2a3a58 snd_dma_reserve_buf +EXPORT_SYMBOL sound/core/snd-page-alloc 0xc6829020 snd_malloc_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0xf2d3e8c4 snd_dma_free_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x01b57d20 snd_pcm_lib_read +EXPORT_SYMBOL sound/core/snd-pcm 0x04cda566 snd_interval_refine +EXPORT_SYMBOL sound/core/snd-pcm 0x0712bfcd snd_pcm_new_stream +EXPORT_SYMBOL sound/core/snd-pcm 0x088723a7 snd_pcm_suspend_all +EXPORT_SYMBOL sound/core/snd-pcm 0x0d86e9b4 snd_pcm_lib_write +EXPORT_SYMBOL sound/core/snd-pcm 0x15279172 snd_pcm_hw_constraint_msbits +EXPORT_SYMBOL sound/core/snd-pcm 0x1d027e4b snd_pcm_format_signed +EXPORT_SYMBOL sound/core/snd-pcm 0x1e5588f9 snd_pcm_open_substream +EXPORT_SYMBOL sound/core/snd-pcm 0x1e98f682 snd_pcm_hw_param_last +EXPORT_SYMBOL sound/core/snd-pcm 0x22a7492b snd_pcm_hw_constraint_list +EXPORT_SYMBOL sound/core/snd-pcm 0x29eaf5e7 snd_pcm_lib_mmap_iomem +EXPORT_SYMBOL sound/core/snd-pcm 0x2d566e72 snd_pcm_lib_preallocate_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x31587bf6 snd_pcm_lib_malloc_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x35234838 snd_pcm_period_elapsed +EXPORT_SYMBOL sound/core/snd-pcm 0x353c86eb snd_pcm_lib_readv +EXPORT_SYMBOL sound/core/snd-pcm 0x367951bb snd_pcm_lib_ioctl +EXPORT_SYMBOL sound/core/snd-pcm 0x3796bdcc snd_pcm_format_little_endian +EXPORT_SYMBOL sound/core/snd-pcm 0x431a8ea8 snd_pcm_hw_constraint_step +EXPORT_SYMBOL sound/core/snd-pcm 0x43598bc4 snd_pcm_hw_constraint_ratnums +EXPORT_SYMBOL sound/core/snd-pcm 0x4e798027 snd_pcm_hw_constraint_integer +EXPORT_SYMBOL sound/core/snd-pcm 0x4f816e9b snd_pcm_format_big_endian +EXPORT_SYMBOL sound/core/snd-pcm 0x5293071c snd_pcm_hw_constraint_ratdens +EXPORT_SYMBOL sound/core/snd-pcm 0x5c473b94 snd_pcm_limit_hw_rates +EXPORT_SYMBOL sound/core/snd-pcm 0x5e7f4920 snd_pcm_format_set_silence +EXPORT_SYMBOL sound/core/snd-pcm 0x6067bfe0 snd_pcm_sgbuf_get_chunk_size +EXPORT_SYMBOL sound/core/snd-pcm 0x63f51c49 snd_pcm_hw_param_value +EXPORT_SYMBOL sound/core/snd-pcm 0x650f8603 snd_pcm_format_silence_64 +EXPORT_SYMBOL sound/core/snd-pcm 0x6622ab15 snd_pcm_hw_constraint_minmax +EXPORT_SYMBOL sound/core/snd-pcm 0x68a24153 snd_pcm_format_physical_width +EXPORT_SYMBOL sound/core/snd-pcm 0x6ef8fcd8 snd_pcm_format_linear +EXPORT_SYMBOL sound/core/snd-pcm 0x706d8bb6 snd_pcm_lib_preallocate_free_for_all +EXPORT_SYMBOL sound/core/snd-pcm 0x710f8896 snd_pcm_suspend +EXPORT_SYMBOL sound/core/snd-pcm 0x77b9ccac _snd_pcm_hw_param_setempty +EXPORT_SYMBOL sound/core/snd-pcm 0x785b3117 snd_pcm_sgbuf_ops_page +EXPORT_SYMBOL sound/core/snd-pcm 0x7a662d08 snd_pcm_stop +EXPORT_SYMBOL sound/core/snd-pcm 0x88cc66cc snd_pcm_link_rwlock +EXPORT_SYMBOL sound/core/snd-pcm 0x9051b1c6 snd_pcm_lib_preallocate_pages_for_all +EXPORT_SYMBOL sound/core/snd-pcm 0x952d5f21 _snd_pcm_hw_params_any +EXPORT_SYMBOL sound/core/snd-pcm 0x984b7f59 snd_pcm_hw_param_first +EXPORT_SYMBOL sound/core/snd-pcm 0x997b0323 snd_pcm_hw_rule_add +EXPORT_SYMBOL sound/core/snd-pcm 0xa3c4f675 snd_pcm_kernel_ioctl +EXPORT_SYMBOL sound/core/snd-pcm 0xa61aa028 snd_pcm_format_unsigned +EXPORT_SYMBOL sound/core/snd-pcm 0xadc422fc snd_pcm_notify +EXPORT_SYMBOL sound/core/snd-pcm 0xb1e1480f snd_pcm_lib_free_pages +EXPORT_SYMBOL sound/core/snd-pcm 0xb9638db4 snd_pcm_rate_to_rate_bit +EXPORT_SYMBOL sound/core/snd-pcm 0xc5057852 snd_pcm_hw_constraint_pow2 +EXPORT_SYMBOL sound/core/snd-pcm 0xc7d36e59 snd_pcm_set_ops +EXPORT_SYMBOL sound/core/snd-pcm 0xcd698603 snd_pcm_new +EXPORT_SYMBOL sound/core/snd-pcm 0xd0b9b8b8 snd_interval_list +EXPORT_SYMBOL sound/core/snd-pcm 0xd2e00486 snd_pcm_set_sync +EXPORT_SYMBOL sound/core/snd-pcm 0xdf06b3c3 snd_pcm_lib_writev +EXPORT_SYMBOL sound/core/snd-pcm 0xdfd4f3c5 snd_pcm_mmap_data +EXPORT_SYMBOL sound/core/snd-pcm 0xe51a1c64 snd_pcm_format_size +EXPORT_SYMBOL sound/core/snd-pcm 0xe56a9336 snd_pcm_format_width +EXPORT_SYMBOL sound/core/snd-pcm 0xe81fcd84 snd_pcm_release_substream +EXPORT_SYMBOL sound/core/snd-pcm 0xf3797152 snd_interval_ratnum +EXPORT_SYMBOL sound/core/snd-pcm 0xf797883b snd_pcm_hw_refine +EXPORT_SYMBOL sound/core/snd-rawmidi 0x004826ad snd_rawmidi_drain_output +EXPORT_SYMBOL sound/core/snd-rawmidi 0x02cf7bf5 snd_rawmidi_transmit_empty +EXPORT_SYMBOL sound/core/snd-rawmidi 0x0eeee389 snd_rawmidi_output_params +EXPORT_SYMBOL sound/core/snd-rawmidi 0x1d0eb425 snd_rawmidi_kernel_release +EXPORT_SYMBOL sound/core/snd-rawmidi 0x265f8cd8 snd_rawmidi_transmit_peek +EXPORT_SYMBOL sound/core/snd-rawmidi 0x31293dff snd_rawmidi_info_select +EXPORT_SYMBOL sound/core/snd-rawmidi 0x3c2f71eb snd_rawmidi_receive +EXPORT_SYMBOL sound/core/snd-rawmidi 0x521b6b23 snd_rawmidi_transmit +EXPORT_SYMBOL sound/core/snd-rawmidi 0x52e219f7 snd_rawmidi_input_params +EXPORT_SYMBOL sound/core/snd-rawmidi 0x567607a3 snd_rawmidi_drain_input +EXPORT_SYMBOL sound/core/snd-rawmidi 0x74d68721 snd_rawmidi_kernel_write +EXPORT_SYMBOL sound/core/snd-rawmidi 0x83b8df3f snd_rawmidi_set_ops +EXPORT_SYMBOL sound/core/snd-rawmidi 0x96c012b5 snd_rawmidi_new +EXPORT_SYMBOL sound/core/snd-rawmidi 0xbf6a9b6f snd_rawmidi_transmit_ack +EXPORT_SYMBOL sound/core/snd-rawmidi 0xf12c7ad8 snd_rawmidi_kernel_read +EXPORT_SYMBOL sound/core/snd-rawmidi 0xf89adb00 snd_rawmidi_drop_output +EXPORT_SYMBOL sound/core/snd-rawmidi 0xff1befbf snd_rawmidi_kernel_open +EXPORT_SYMBOL sound/core/snd-timer 0x09bbc2af snd_timer_global_new +EXPORT_SYMBOL sound/core/snd-timer 0x0a70b545 snd_timer_global_free +EXPORT_SYMBOL sound/core/snd-timer 0x0ebcb4f5 snd_timer_pause +EXPORT_SYMBOL sound/core/snd-timer 0x261eca76 snd_timer_start +EXPORT_SYMBOL sound/core/snd-timer 0x35272dac snd_timer_interrupt +EXPORT_SYMBOL sound/core/snd-timer 0x49fae34e snd_timer_open +EXPORT_SYMBOL sound/core/snd-timer 0x4f1ddb9b snd_timer_resolution +EXPORT_SYMBOL sound/core/snd-timer 0x5161a387 snd_timer_notify +EXPORT_SYMBOL sound/core/snd-timer 0xa0d9d174 snd_timer_stop +EXPORT_SYMBOL sound/core/snd-timer 0xc7c708e7 snd_timer_continue +EXPORT_SYMBOL sound/core/snd-timer 0xec064ad9 snd_timer_new +EXPORT_SYMBOL sound/core/snd-timer 0xfc4b07ac snd_timer_global_register +EXPORT_SYMBOL sound/core/snd-timer 0xfe72f880 snd_timer_close +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0x73c4c993 snd_mpu401_uart_interrupt_tx +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0xb186eb15 snd_mpu401_uart_new +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0xfe618b58 snd_mpu401_uart_interrupt +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x05060a19 snd_opl3_regmap +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x0a7eaced snd_opl3_init +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x1f8a5c4c snd_opl3_interrupt +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x21b8d810 snd_opl3_new +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x277d042c snd_opl3_find_patch +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x3bd2438c snd_opl3_reset +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x42fd2d0a snd_opl3_hwdep_new +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x59f003c3 snd_opl3_create +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x5dc7185e snd_opl3_timer_new +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x8de17dfc snd_opl3_load_patch +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x0f21d7d3 snd_vx_load_boot_image +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x1c5b887a snd_vx_create +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x1cadb14b snd_vx_irq_handler +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x3b36ad0a snd_vx_suspend +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x3ec64b29 snd_vx_dsp_boot +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x8af000bd snd_vx_check_reg_bit +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x9ec80b3f snd_vx_resume +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xa4e96ffc snd_vx_setup_firmware +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xcadb5afc snd_vx_free_firmware +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xd6348532 snd_vx_dsp_load +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x1d94ac49 snd_ak4114_reg_write +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x669f4291 snd_ak4114_reinit +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x752b5709 snd_ak4114_check_rate_and_errors +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x88b56b57 snd_ak4114_create +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0xb262e136 snd_ak4114_build +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0xec784061 snd_ak4114_external_rate +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0x3d5de68b snd_ak4117_reinit +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0x64b5c0aa snd_ak4117_build +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xbe50e729 snd_ak4117_create +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xdde3594d snd_ak4117_external_rate +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xe5cb3599 snd_ak4117_check_rate_and_errors +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xe8eaad88 snd_ak4117_reg_write +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0x373fcfc5 snd_akm4xxx_reset +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0xb24fb3f2 snd_akm4xxx_write +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0xd7828f05 snd_akm4xxx_init +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0xdd331f63 snd_akm4xxx_build_controls +EXPORT_SYMBOL sound/i2c/other/snd-pt2258 0x2c9eae69 snd_pt2258_build_controls +EXPORT_SYMBOL sound/i2c/other/snd-pt2258 0x54f28d51 snd_pt2258_reset +EXPORT_SYMBOL sound/i2c/other/snd-tea575x-tuner 0x67d9fa70 snd_tea575x_exit +EXPORT_SYMBOL sound/i2c/other/snd-tea575x-tuner 0xb010377a snd_tea575x_init +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x19ea1779 snd_cs8427_iec958_pcm +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x1ad0b328 snd_cs8427_iec958_active +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x82b01c5d snd_cs8427_iec958_build +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x99d3a875 snd_cs8427_reg_write +EXPORT_SYMBOL sound/i2c/snd-cs8427 0xb87bfc24 snd_cs8427_create +EXPORT_SYMBOL sound/i2c/snd-i2c 0x38b0cac8 snd_i2c_probeaddr +EXPORT_SYMBOL sound/i2c/snd-i2c 0x4edc52e1 snd_i2c_bus_create +EXPORT_SYMBOL sound/i2c/snd-i2c 0x5317d2e8 snd_i2c_device_create +EXPORT_SYMBOL sound/i2c/snd-i2c 0xbdbb4e68 snd_i2c_device_free +EXPORT_SYMBOL sound/i2c/snd-i2c 0xd49a2077 snd_i2c_readbytes +EXPORT_SYMBOL sound/i2c/snd-i2c 0xf482214b snd_i2c_sendbytes +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x0d165f28 snd_sbmixer_suspend +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x1068d71e snd_sbdsp_command +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x1bf76394 snd_sbmixer_resume +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x1c2d8730 snd_sbdsp_get_byte +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x32c80631 snd_sbmixer_add_ctl +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x382115b8 snd_sbdsp_create +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x38d7bc88 snd_sbmixer_write +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xa3d6b261 snd_sbdsp_reset +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xa40e2b8f snd_sbmixer_new +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xf1529acb snd_sbmixer_read +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0x0ba4ef1d snd_sb16dsp_interrupt +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0x281f4b44 snd_sb16dsp_get_pcm_ops +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0xd0145a0c snd_sb16dsp_pcm +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0xd2792e84 snd_sb16dsp_configure +EXPORT_SYMBOL sound/oss/ad1848 0x26c427ee ad1848_detect +EXPORT_SYMBOL sound/oss/ad1848 0x55262c70 probe_ms_sound +EXPORT_SYMBOL sound/oss/ad1848 0x9bf1cc62 ad1848_unload +EXPORT_SYMBOL sound/oss/ad1848 0xa4977c81 ad1848_init +EXPORT_SYMBOL sound/oss/ad1848 0xb29a9148 unload_ms_sound +EXPORT_SYMBOL sound/oss/ad1848 0xc04f6f67 ad1848_control +EXPORT_SYMBOL sound/oss/ad1848 0xeb556fe9 attach_ms_sound +EXPORT_SYMBOL sound/oss/mpu401 0x5febf284 unload_mpu401 +EXPORT_SYMBOL sound/oss/mpu401 0x81290ae9 attach_mpu401 +EXPORT_SYMBOL sound/oss/mpu401 0xd9ec5db4 probe_mpu401 +EXPORT_SYMBOL sound/oss/sb_lib 0x20cdf0b5 probe_sbmpu +EXPORT_SYMBOL sound/oss/sb_lib 0x42424109 sb_be_quiet +EXPORT_SYMBOL sound/oss/sb_lib 0x450f9aea smw_free +EXPORT_SYMBOL sound/oss/sb_lib 0x74afd69c unload_sbmpu +EXPORT_SYMBOL sound/oss/sb_lib 0xc4884969 sb_dsp_unload +EXPORT_SYMBOL sound/oss/sb_lib 0xd8a2731c sb_dsp_detect +EXPORT_SYMBOL sound/oss/sb_lib 0xfd5b1d1f sb_dsp_init +EXPORT_SYMBOL sound/oss/sound 0x04c87ec8 compute_finetune +EXPORT_SYMBOL sound/oss/sound 0x06339815 sound_unload_synthdev +EXPORT_SYMBOL sound/oss/sound 0x0f280035 conf_printf +EXPORT_SYMBOL sound/oss/sound 0x17ba231d seq_input_event +EXPORT_SYMBOL sound/oss/sound 0x1b3df3cf sound_alloc_mixerdev +EXPORT_SYMBOL sound/oss/sound 0x1f395686 MIDIbuf_avail +EXPORT_SYMBOL sound/oss/sound 0x2161d5e8 sound_timer_init +EXPORT_SYMBOL sound/oss/sound 0x2aa31695 midi_synth_kill_note +EXPORT_SYMBOL sound/oss/sound 0x3902725b midi_devs +EXPORT_SYMBOL sound/oss/sound 0x394cb088 sound_free_dma +EXPORT_SYMBOL sound/oss/sound 0x418f5fbe sound_close_dma +EXPORT_SYMBOL sound/oss/sound 0x4cd01bdd num_audiodevs +EXPORT_SYMBOL sound/oss/sound 0x4ff47e9d midi_synth_setup_voice +EXPORT_SYMBOL sound/oss/sound 0x51e354b2 sound_alloc_timerdev +EXPORT_SYMBOL sound/oss/sound 0x56504ca2 midi_synth_reset +EXPORT_SYMBOL sound/oss/sound 0x5d986fc9 note_to_freq +EXPORT_SYMBOL sound/oss/sound 0x6991e57f sound_timer_devs +EXPORT_SYMBOL sound/oss/sound 0x6b359fcb mixer_devs +EXPORT_SYMBOL sound/oss/sound 0x7679ee76 seq_copy_to_input +EXPORT_SYMBOL sound/oss/sound 0x7bdf0907 conf_printf2 +EXPORT_SYMBOL sound/oss/sound 0x87e480df synth_devs +EXPORT_SYMBOL sound/oss/sound 0x892093e0 midi_synth_controller +EXPORT_SYMBOL sound/oss/sound 0x90bd9714 sequencer_timer +EXPORT_SYMBOL sound/oss/sound 0x987bcf12 DMAbuf_outputintr +EXPORT_SYMBOL sound/oss/sound 0x9a95733f sound_alloc_dma +EXPORT_SYMBOL sound/oss/sound 0x9bdaf24d midi_synth_start_note +EXPORT_SYMBOL sound/oss/sound 0x9d845b18 num_mixers +EXPORT_SYMBOL sound/oss/sound 0xa1d5f04f load_mixer_volumes +EXPORT_SYMBOL sound/oss/sound 0xa1eae7cf num_midis +EXPORT_SYMBOL sound/oss/sound 0xa41ead5f sound_unload_timerdev +EXPORT_SYMBOL sound/oss/sound 0xa51c913b sound_unload_mixerdev +EXPORT_SYMBOL sound/oss/sound 0xa6bb414c sound_unload_mididev +EXPORT_SYMBOL sound/oss/sound 0xa948751e sound_unload_audiodev +EXPORT_SYMBOL sound/oss/sound 0xad45df73 midi_synth_close +EXPORT_SYMBOL sound/oss/sound 0xaef743b2 midi_synth_ioctl +EXPORT_SYMBOL sound/oss/sound 0xb14b22cd midi_synth_hw_control +EXPORT_SYMBOL sound/oss/sound 0xb350ab10 sound_install_mixer +EXPORT_SYMBOL sound/oss/sound 0xb3bf73a8 sound_install_audiodrv +EXPORT_SYMBOL sound/oss/sound 0xb51587f6 do_midi_msg +EXPORT_SYMBOL sound/oss/sound 0xba413f87 sound_alloc_mididev +EXPORT_SYMBOL sound/oss/sound 0xba7dd041 midi_synth_bender +EXPORT_SYMBOL sound/oss/sound 0xc748d109 sound_alloc_synthdev +EXPORT_SYMBOL sound/oss/sound 0xcc4b8797 sound_open_dma +EXPORT_SYMBOL sound/oss/sound 0xd85be938 midi_synth_set_instr +EXPORT_SYMBOL sound/oss/sound 0xdb400afa midi_synth_panning +EXPORT_SYMBOL sound/oss/sound 0xe056b71c DMAbuf_start_dma +EXPORT_SYMBOL sound/oss/sound 0xe2675a79 sound_timer_interrupt +EXPORT_SYMBOL sound/oss/sound 0xeb315d99 DMAbuf_inputintr +EXPORT_SYMBOL sound/oss/sound 0xf1ea8a20 midi_synth_aftertouch +EXPORT_SYMBOL sound/oss/sound 0xf6b3a2fb midi_synth_open +EXPORT_SYMBOL sound/oss/sound 0xf7426da3 midi_synth_load_patch +EXPORT_SYMBOL sound/oss/sound 0xf78f6363 sequencer_init +EXPORT_SYMBOL sound/oss/sound 0xfa6871be sound_timer_syncinterval +EXPORT_SYMBOL sound/oss/sound 0xfddcbfb3 midi_synth_send_sysex +EXPORT_SYMBOL sound/oss/sound 0xff84a03a audio_devs +EXPORT_SYMBOL sound/oss/uart401 0x46248c57 uart401intr +EXPORT_SYMBOL sound/oss/uart401 0x84351315 probe_uart401 +EXPORT_SYMBOL sound/oss/uart401 0xecfdd9c9 unload_uart401 +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x0cfc2203 snd_ac97_get_short_name +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x14f0545e snd_ac97_update +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x1802e59b snd_ac97_write +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x3f0dabce snd_ac97_update_power +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x4ce4d9c0 snd_ac97_pcm_assign +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x50e9b581 snd_ac97_read +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x61694b83 snd_ac97_update_bits +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x62271297 snd_ac97_write_cache +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x64d35c4a snd_ac97_resume +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x66465e8f snd_ac97_suspend +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x6c369ae8 snd_ac97_pcm_open +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x7edd8507 snd_ac97_pcm_double_rate_rules +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x962f3b5b snd_ac97_bus +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xb5cc654b snd_ac97_tune_hardware +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xc1ccef50 snd_ac97_pcm_close +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xdbb93515 snd_ac97_mixer +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xe658a44e snd_ac97_set_rate +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x0c67e6bc snd_emu10k1_ptr_write +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x78fbdcbe snd_emu10k1_voice_alloc +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x8e43570c snd_emu10k1_memblk_map +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x9bbeb287 snd_emu10k1_ptr_read +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xb295a8c6 snd_emu10k1_synth_alloc +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xcdbce9da snd_emu10k1_synth_free +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xd9a6a282 snd_emu10k1_voice_free +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xf2b985ce snd_emu10k1_synth_bzero +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xfe3f983e snd_emu10k1_synth_copy_from_user +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0x36dde1d2 snd_ice1712_akm4xxx_init +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0x4d17e64d snd_ice1712_akm4xxx_build_controls +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0xd023d69f snd_ice1712_akm4xxx_free +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x098ba0a8 oxygen_read_ac97 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x0bf82873 oxygen_write8 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x244e4762 oxygen_pci_suspend +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x2599918f oxygen_write_ac97 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x38316cd0 oxygen_write8_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x49a2900c oxygen_read16 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x4c85f65a oxygen_write16 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x54f3923b oxygen_write_ac97_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x5a06249f oxygen_read8 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x5cd5a745 oxygen_write_i2c +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x6fe1c556 oxygen_pci_probe +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x78386fe5 oxygen_write16_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x7db735b4 oxygen_write_uart +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x82b4502b oxygen_write32 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x8faf906b oxygen_write_spi +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xb0d04e50 oxygen_pci_remove +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xb638b09e oxygen_read32 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xd5fae012 oxygen_write32_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xe9763d5e oxygen_reset_uart +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xec7b16a7 oxygen_pci_resume +EXPORT_SYMBOL sound/pci/trident/snd-trident 0x7fc41554 snd_trident_alloc_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0xb547befc snd_trident_write_voice_regs +EXPORT_SYMBOL sound/pci/trident/snd-trident 0xcc6387ff snd_trident_stop_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0xd3041cee snd_trident_start_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0xe9aa6d20 snd_trident_free_voice +EXPORT_SYMBOL sound/sound_firmware 0x39e3dd23 mod_firmware_load +EXPORT_SYMBOL sound/soundcore 0x1e383422 register_sound_special_device +EXPORT_SYMBOL sound/soundcore 0x3ad7916b sound_class +EXPORT_SYMBOL sound/soundcore 0x6b6ca6fe register_sound_dsp +EXPORT_SYMBOL sound/soundcore 0x7afc9d8a unregister_sound_mixer +EXPORT_SYMBOL sound/soundcore 0x98959ab3 register_sound_mixer +EXPORT_SYMBOL sound/soundcore 0x99c95fa5 unregister_sound_special +EXPORT_SYMBOL sound/soundcore 0xcd083b10 unregister_sound_dsp +EXPORT_SYMBOL sound/soundcore 0xd53020b3 register_sound_special +EXPORT_SYMBOL sound/soundcore 0xe28f94bf register_sound_midi +EXPORT_SYMBOL sound/soundcore 0xfdab6de3 unregister_sound_midi +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x08a2fc07 snd_emux_register +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x3ec477a6 snd_emux_free +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x5d5a4711 snd_emux_lock_voice +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x655cb202 snd_sf_linear_to_log +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0xa24f2e56 snd_emux_terminate_all +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0xbeba3ee5 snd_emux_unlock_voice +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0xe16578d8 snd_emux_new +EXPORT_SYMBOL sound/synth/snd-util-mem 0x20d65978 snd_util_memhdr_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0x24886293 __snd_util_mem_alloc +EXPORT_SYMBOL sound/synth/snd-util-mem 0x569d614e snd_util_mem_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0x7a007343 snd_util_memhdr_new +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd197c5db __snd_util_memblk_new +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd34b56e4 __snd_util_mem_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd8b55e81 snd_util_mem_alloc +EXPORT_SYMBOL sound/synth/snd-util-mem 0xf158252c snd_util_mem_avail +EXPORT_SYMBOL sound/usb/snd-usb-lib 0x16756dc0 snd_usbmidi_input_start +EXPORT_SYMBOL sound/usb/snd-usb-lib 0x63343b1d snd_usbmidi_input_stop +EXPORT_SYMBOL sound/usb/snd-usb-lib 0xc63f8e43 snd_usb_create_midi_interface +EXPORT_SYMBOL sound/usb/snd-usb-lib 0xd9d2bb03 snd_usbmidi_disconnect +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x1538a700 dm_mem_cache_alloc +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x8397fa9b dm_mem_cache_client_create +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xaa3934fa dm_mem_cache_free +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xe10a68f0 dm_mem_cache_client_destroy +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xe58d61c9 dm_mem_cache_grow +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xec6ad524 dm_mem_cache_shrink +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-message 0x920a7a41 dm_message_parse +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x0050f52c rh_get_region_key +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x1a5edde8 rh_bio_to_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x275fdd04 rh_recovery_start +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x29e53a6b rh_dec +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x4b49baf9 rh_delay_by_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x5c2a0632 rh_recovery_end +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x62842029 rh_flush +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x83baca27 rh_state +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x87d45b9d rh_get_region_size +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x8c817c1b rh_inc_pending +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xa923d788 rh_start_recovery +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xac274ed3 rh_stop_recovery +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xb513be98 rh_update_states +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xbb748327 rh_reg_set_context +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xbd3452f9 rh_sector_to_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xbec97c36 rh_init +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc4fdf256 rh_recovery_prepare +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc4ff7745 rh_reg_get_context +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc57bafec rh_exit +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xe9f7f71a rh_region_to_sector +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xead50daa rh_delay +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xf3e0a2b0 rh_inc +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x29c887a9 set_tx_channels +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x7789312a cmdir_write +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0xf4c689aa cmdir_read +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0x61ea4c33 lirc_register_plugin +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0x78f8f267 lirc_get_pdata +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0xe96379eb lirc_unregister_plugin +EXPORT_SYMBOL ubuntu/misc/media/ov511/ov511 0x1b191f09 ov511_register_decomp_module +EXPORT_SYMBOL ubuntu/misc/media/ov511/ov511 0x7db9be3c ov511_deregister_decomp_module +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x0bdc41a4 wlan_unsetup +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x16cf8480 unregister_wlandev +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x2116f492 p80211wext_event_associated +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x298f31b5 p80211netdev_rx +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x311df397 p80211netdev_hwremoved +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x3f2ba908 wlan_setup +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x452a3ad6 p80211_suspend +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x481ce6b2 p80211_allow_ioctls +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x4bbf5a1c p80211skb_free +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x703f432c p80211_resume +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x755833c9 register_wlandev +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xb0af0799 wlan_wext_write +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xdf3b1fa0 p80211skb_rxmeta_attach +EXPORT_SYMBOL vmlinux 0x00000000 per_cpu__softirq_work_list +EXPORT_SYMBOL vmlinux 0x004c9840 sock_register +EXPORT_SYMBOL vmlinux 0x00502c91 dm_unregister_target +EXPORT_SYMBOL vmlinux 0x007ee135 blk_queue_resize_tags +EXPORT_SYMBOL vmlinux 0x00801678 flush_scheduled_work +EXPORT_SYMBOL vmlinux 0x0080fcd6 tcf_hash_release +EXPORT_SYMBOL vmlinux 0x009d258f _write_lock +EXPORT_SYMBOL vmlinux 0x00b3575c xfrm4_prepare_output +EXPORT_SYMBOL vmlinux 0x00c9f88d aio_complete +EXPORT_SYMBOL vmlinux 0x01000e51 schedule +EXPORT_SYMBOL vmlinux 0x0110da24 block_write_full_page +EXPORT_SYMBOL vmlinux 0x01139ffc max_mapnr +EXPORT_SYMBOL vmlinux 0x013930bf xfrm_bundle_ok +EXPORT_SYMBOL vmlinux 0x0186d073 percpu_counter_set +EXPORT_SYMBOL vmlinux 0x01902adf netpoll_trap +EXPORT_SYMBOL vmlinux 0x01a4aab6 set_irq_chip_data +EXPORT_SYMBOL vmlinux 0x01aea714 sk_stream_wait_memory +EXPORT_SYMBOL vmlinux 0x01b22d0d genl_sock +EXPORT_SYMBOL vmlinux 0x01bbcca7 sock_no_mmap +EXPORT_SYMBOL vmlinux 0x01cbfa48 flush_old_exec +EXPORT_SYMBOL vmlinux 0x01d19038 acpi_enable_subsystem +EXPORT_SYMBOL vmlinux 0x020dc66a netif_device_detach +EXPORT_SYMBOL vmlinux 0x02124474 ip_send_check +EXPORT_SYMBOL vmlinux 0x02138f9d bioset_integrity_create +EXPORT_SYMBOL vmlinux 0x02307437 pagecache_write_end +EXPORT_SYMBOL vmlinux 0x0237b57a arch_unregister_cpu +EXPORT_SYMBOL vmlinux 0x0256389f bit_waitqueue +EXPORT_SYMBOL vmlinux 0x02649054 security_sock_rcv_skb +EXPORT_SYMBOL vmlinux 0x02681888 load_nls_default +EXPORT_SYMBOL vmlinux 0x0270f66b proc_doulongvec_ms_jiffies_minmax +EXPORT_SYMBOL vmlinux 0x029444f0 native_read_tsc +EXPORT_SYMBOL vmlinux 0x02a18c74 nf_conntrack_destroy +EXPORT_SYMBOL vmlinux 0x02a6ce5a crc16_table +EXPORT_SYMBOL vmlinux 0x02aff2f4 acpi_install_gpe_handler +EXPORT_SYMBOL vmlinux 0x02c2f41d locks_init_lock +EXPORT_SYMBOL vmlinux 0x02d81845 audit_log_task_context +EXPORT_SYMBOL vmlinux 0x02db771b kernel_recvmsg +EXPORT_SYMBOL vmlinux 0x02eaee64 xfrm6_find_1stfragopt +EXPORT_SYMBOL vmlinux 0x02ec1563 generic_file_llseek_unlocked +EXPORT_SYMBOL vmlinux 0x030ad9c5 pci_remove_behind_bridge +EXPORT_SYMBOL vmlinux 0x0334da4e scsi_command_size_tbl +EXPORT_SYMBOL vmlinux 0x034ce6d7 put_filp +EXPORT_SYMBOL vmlinux 0x03585c8f tc_classify_compat +EXPORT_SYMBOL vmlinux 0x0360055e agp_alloc_bridge +EXPORT_SYMBOL vmlinux 0x036f3a7f ipv4_specific +EXPORT_SYMBOL vmlinux 0x037a0cba kfree +EXPORT_SYMBOL vmlinux 0x0388e7a1 kill_pid +EXPORT_SYMBOL vmlinux 0x039699d1 send_sig_info +EXPORT_SYMBOL vmlinux 0x03a99c3b rb_prev +EXPORT_SYMBOL vmlinux 0x03c06156 bitmap_fold +EXPORT_SYMBOL vmlinux 0x03fd2571 vm_unmap_ram +EXPORT_SYMBOL vmlinux 0x0411bcb9 netdev_features_change +EXPORT_SYMBOL vmlinux 0x0422fe4a inet_csk_timer_bug_msg +EXPORT_SYMBOL vmlinux 0x04358912 inet6_del_protocol +EXPORT_SYMBOL vmlinux 0x043b2d2b datagram_poll +EXPORT_SYMBOL vmlinux 0x043cd354 tty_port_tty_get +EXPORT_SYMBOL vmlinux 0x044fbf49 mempool_kzalloc +EXPORT_SYMBOL vmlinux 0x045c4781 bio_kmalloc +EXPORT_SYMBOL vmlinux 0x0487f831 fb_find_best_display +EXPORT_SYMBOL vmlinux 0x0489a8f9 simple_getattr +EXPORT_SYMBOL vmlinux 0x048f0b5e pci_release_region +EXPORT_SYMBOL vmlinux 0x04902d07 kmalloc_caches +EXPORT_SYMBOL vmlinux 0x04a22717 dev_mc_unsync +EXPORT_SYMBOL vmlinux 0x04d8c750 release_perfctr_nmi +EXPORT_SYMBOL vmlinux 0x04e03bd3 key_unlink +EXPORT_SYMBOL vmlinux 0x050aff81 dev_unicast_sync +EXPORT_SYMBOL vmlinux 0x051dafb6 ip6_route_output +EXPORT_SYMBOL vmlinux 0x05859091 skb_under_panic +EXPORT_SYMBOL vmlinux 0x058c75d9 acpi_get_pci_id +EXPORT_SYMBOL vmlinux 0x0598ff70 mark_page_accessed +EXPORT_SYMBOL vmlinux 0x05e28d43 __first_cpu +EXPORT_SYMBOL vmlinux 0x05eb1af0 tcp_timewait_state_process +EXPORT_SYMBOL vmlinux 0x061651be strcat +EXPORT_SYMBOL vmlinux 0x06673d5e serio_open +EXPORT_SYMBOL vmlinux 0x06706a56 proto_register +EXPORT_SYMBOL vmlinux 0x067d8d35 security_release_secctx +EXPORT_SYMBOL vmlinux 0x068040eb ip_route_me_harder +EXPORT_SYMBOL vmlinux 0x068c7263 ioremap_cache +EXPORT_SYMBOL vmlinux 0x06a485f2 __krealloc +EXPORT_SYMBOL vmlinux 0x06a53eb0 genphy_config_advert +EXPORT_SYMBOL vmlinux 0x06d2e999 task_tgid_nr_ns +EXPORT_SYMBOL vmlinux 0x06d728b1 tcp_parse_md5sig_option +EXPORT_SYMBOL vmlinux 0x06df0ac3 skb_clone +EXPORT_SYMBOL vmlinux 0x06fe3b14 default_grn +EXPORT_SYMBOL vmlinux 0x070b22d4 pci_iounmap +EXPORT_SYMBOL vmlinux 0x071f40f8 agp_generic_free_by_type +EXPORT_SYMBOL vmlinux 0x072628fd tty_register_driver +EXPORT_SYMBOL vmlinux 0x0727c4f3 iowrite8 +EXPORT_SYMBOL vmlinux 0x073dfa12 generate_resume_trace +EXPORT_SYMBOL vmlinux 0x0751f011 dquot_commit +EXPORT_SYMBOL vmlinux 0x0763cd92 write_cache_pages +EXPORT_SYMBOL vmlinux 0x076d59b8 pagevec_lookup +EXPORT_SYMBOL vmlinux 0x0770e7c4 scsi_free_command +EXPORT_SYMBOL vmlinux 0x0791f849 dm_table_unplug_all +EXPORT_SYMBOL vmlinux 0x0799aca4 local_bh_enable +EXPORT_SYMBOL vmlinux 0x079cd7f1 ns_to_timeval +EXPORT_SYMBOL vmlinux 0x07a00652 cpu_sysdev_class +EXPORT_SYMBOL vmlinux 0x07a423ba bio_pair_release +EXPORT_SYMBOL vmlinux 0x07a890c8 fb_alloc_cmap +EXPORT_SYMBOL vmlinux 0x07cc4a5d printk_timed_ratelimit +EXPORT_SYMBOL vmlinux 0x07d6581c atm_proc_root +EXPORT_SYMBOL vmlinux 0x07d9b783 scsi_nl_send_vendor_msg +EXPORT_SYMBOL vmlinux 0x0803458e xfrm_user_policy +EXPORT_SYMBOL vmlinux 0x082c3213 pci_root_buses +EXPORT_SYMBOL vmlinux 0x0845e96d textsearch_prepare +EXPORT_SYMBOL vmlinux 0x0853a3ef scsi_device_put +EXPORT_SYMBOL vmlinux 0x089208eb sock_create_lite +EXPORT_SYMBOL vmlinux 0x08c8c3e4 dmam_pool_destroy +EXPORT_SYMBOL vmlinux 0x08fef4f6 netif_carrier_off +EXPORT_SYMBOL vmlinux 0x092d9dd2 __xfrm_state_delete +EXPORT_SYMBOL vmlinux 0x0933aae1 efi_enabled +EXPORT_SYMBOL vmlinux 0x0948cde9 num_physpages +EXPORT_SYMBOL vmlinux 0x095dd691 alloc_file +EXPORT_SYMBOL vmlinux 0x0976c4d0 fb_validate_mode +EXPORT_SYMBOL vmlinux 0x09775cdc kref_get +EXPORT_SYMBOL vmlinux 0x098431ba acpi_get_current_resources +EXPORT_SYMBOL vmlinux 0x098b71c6 fb_dealloc_cmap +EXPORT_SYMBOL vmlinux 0x09947956 follow_down +EXPORT_SYMBOL vmlinux 0x09c55cec schedule_timeout_interruptible +EXPORT_SYMBOL vmlinux 0x09d44df9 in_lock_functions +EXPORT_SYMBOL vmlinux 0x09d62219 sock_wmalloc +EXPORT_SYMBOL vmlinux 0x09e3272a swiotlb_sync_single_for_device +EXPORT_SYMBOL vmlinux 0x09e9e866 tcf_exts_change +EXPORT_SYMBOL vmlinux 0x0a025c50 bh_uptodate_or_lock +EXPORT_SYMBOL vmlinux 0x0a2487e0 unblock_all_signals +EXPORT_SYMBOL vmlinux 0x0a586bd9 compat_mc_getsockopt +EXPORT_SYMBOL vmlinux 0x0a8dc420 try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x0ac93e9d ll_rw_block +EXPORT_SYMBOL vmlinux 0x0acb1a3c __bitmap_shift_right +EXPORT_SYMBOL vmlinux 0x0afd5ac6 bt_sock_link +EXPORT_SYMBOL vmlinux 0x0b0f23fe kmem_cache_size +EXPORT_SYMBOL vmlinux 0x0b1beb31 vmalloc_32_user +EXPORT_SYMBOL vmlinux 0x0b33d577 dma_async_memcpy_pg_to_pg +EXPORT_SYMBOL vmlinux 0x0b47ae83 generic_setlease +EXPORT_SYMBOL vmlinux 0x0b58408f tty_register_ldisc +EXPORT_SYMBOL vmlinux 0x0b742fd7 simple_strtol +EXPORT_SYMBOL vmlinux 0x0ba1c35c mmc_alloc_host +EXPORT_SYMBOL vmlinux 0x0bac70e2 tcp_v4_remember_stamp +EXPORT_SYMBOL vmlinux 0x0bb3e997 pci_dev_driver +EXPORT_SYMBOL vmlinux 0x0bc6950e blkdev_dequeue_request +EXPORT_SYMBOL vmlinux 0x0c5ef91b per_cpu__vm_event_states +EXPORT_SYMBOL vmlinux 0x0c65e73c scsi_normalize_sense +EXPORT_SYMBOL vmlinux 0x0c8c9e99 scsi_show_extd_sense +EXPORT_SYMBOL vmlinux 0x0ca7b7a8 acpi_check_region +EXPORT_SYMBOL vmlinux 0x0cb66005 __pskb_pull_tail +EXPORT_SYMBOL vmlinux 0x0cb96a0c proc_mkdir +EXPORT_SYMBOL vmlinux 0x0cbd71b6 ethtool_op_set_tx_ipv6_csum +EXPORT_SYMBOL vmlinux 0x0ce1eda9 inode_add_bytes +EXPORT_SYMBOL vmlinux 0x0cee6ad2 arp_create +EXPORT_SYMBOL vmlinux 0x0cf38c13 input_unregister_handle +EXPORT_SYMBOL vmlinux 0x0d26a76d _write_lock_irq +EXPORT_SYMBOL vmlinux 0x0d3be396 jbd2_journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x0d3dda14 acpi_get_type +EXPORT_SYMBOL vmlinux 0x0d513770 sock_no_sendpage +EXPORT_SYMBOL vmlinux 0x0d542439 __ipv6_addr_type +EXPORT_SYMBOL vmlinux 0x0d689a5f blk_rq_init +EXPORT_SYMBOL vmlinux 0x0d8ab500 param_set_copystring +EXPORT_SYMBOL vmlinux 0x0da10ec3 security_sock_graft +EXPORT_SYMBOL vmlinux 0x0db60990 input_get_keycode +EXPORT_SYMBOL vmlinux 0x0e0252ec downgrade_write +EXPORT_SYMBOL vmlinux 0x0e0b5818 generic_make_request +EXPORT_SYMBOL vmlinux 0x0e4b9195 sock_common_setsockopt +EXPORT_SYMBOL vmlinux 0x0e52592a panic +EXPORT_SYMBOL vmlinux 0x0e54afb4 generic_file_direct_write +EXPORT_SYMBOL vmlinux 0x0e610b16 hci_conn_change_link_key +EXPORT_SYMBOL vmlinux 0x0e762d6e request_module +EXPORT_SYMBOL vmlinux 0x0e81bd98 proc_dointvec_ms_jiffies +EXPORT_SYMBOL vmlinux 0x0ed488bd is_container_init +EXPORT_SYMBOL vmlinux 0x0f0a1f51 xfrm_unregister_km +EXPORT_SYMBOL vmlinux 0x0f144e0e __pagevec_release +EXPORT_SYMBOL vmlinux 0x0f1612f0 rtnl_unicast +EXPORT_SYMBOL vmlinux 0x0f20f19f agp_unbind_memory +EXPORT_SYMBOL vmlinux 0x0f695a88 xfrm_policy_walk +EXPORT_SYMBOL vmlinux 0x0f74dbe9 kblockd_schedule_work +EXPORT_SYMBOL vmlinux 0x0f8ef5ab tty_write_room +EXPORT_SYMBOL vmlinux 0x0f90bb98 lease_modify +EXPORT_SYMBOL vmlinux 0x0faef0ed __tasklet_schedule +EXPORT_SYMBOL vmlinux 0x0fc5e8eb radix_tree_gang_lookup_slot +EXPORT_SYMBOL vmlinux 0x0fcc5d45 inet_release +EXPORT_SYMBOL vmlinux 0x0fd00a68 acpi_clear_event +EXPORT_SYMBOL vmlinux 0x0ff2b602 slhc_compress +EXPORT_SYMBOL vmlinux 0x1029f56e neigh_table_init +EXPORT_SYMBOL vmlinux 0x106a2397 generic_file_aio_write +EXPORT_SYMBOL vmlinux 0x106aad55 sock_no_listen +EXPORT_SYMBOL vmlinux 0x1072a394 csum_partial_copy_from_user +EXPORT_SYMBOL vmlinux 0x107803e4 bio_map_kern +EXPORT_SYMBOL vmlinux 0x107f49a8 pci_set_power_state +EXPORT_SYMBOL vmlinux 0x108ca07e pci_prepare_to_sleep +EXPORT_SYMBOL vmlinux 0x109f5dce inet_frag_find +EXPORT_SYMBOL vmlinux 0x10a20a24 __seq_open_private +EXPORT_SYMBOL vmlinux 0x10d6faff ip_mc_dec_group +EXPORT_SYMBOL vmlinux 0x10ee20bb default_blu +EXPORT_SYMBOL vmlinux 0x11128496 ps2_cmd_aborted +EXPORT_SYMBOL vmlinux 0x11267875 scsi_extd_sense_format +EXPORT_SYMBOL vmlinux 0x113a23d4 submit_bio +EXPORT_SYMBOL vmlinux 0x11476bd1 find_or_create_page +EXPORT_SYMBOL vmlinux 0x11505636 dm_table_get_size +EXPORT_SYMBOL vmlinux 0x116240db key_instantiate_and_link +EXPORT_SYMBOL vmlinux 0x1163f0a7 blk_max_low_pfn +EXPORT_SYMBOL vmlinux 0x117093be qdisc_class_hash_init +EXPORT_SYMBOL vmlinux 0x117e9c36 get_disk +EXPORT_SYMBOL vmlinux 0x118f01ea putname +EXPORT_SYMBOL vmlinux 0x11a18b14 __wake_up_bit +EXPORT_SYMBOL vmlinux 0x11dab346 __down_read +EXPORT_SYMBOL vmlinux 0x1203262a pci_unmap_rom +EXPORT_SYMBOL vmlinux 0x120729ae make_bad_inode +EXPORT_SYMBOL vmlinux 0x120ceca2 ip_nat_decode_session +EXPORT_SYMBOL vmlinux 0x122cc2ea elv_dispatch_sort +EXPORT_SYMBOL vmlinux 0x12596cd6 jbd2_journal_load +EXPORT_SYMBOL vmlinux 0x125fbca7 cad_pid +EXPORT_SYMBOL vmlinux 0x126970ed param_set_uint +EXPORT_SYMBOL vmlinux 0x1282ae67 d_splice_alias +EXPORT_SYMBOL vmlinux 0x12854dc7 pci_save_state +EXPORT_SYMBOL vmlinux 0x12a3c827 cfb_imageblit +EXPORT_SYMBOL vmlinux 0x12c39f27 backlight_device_register +EXPORT_SYMBOL vmlinux 0x12f99022 inet_frags_init_net +EXPORT_SYMBOL vmlinux 0x131eeb12 blk_get_backing_dev_info +EXPORT_SYMBOL vmlinux 0x132f45f2 cookie_check_timestamp +EXPORT_SYMBOL vmlinux 0x13304daa tcp_setsockopt +EXPORT_SYMBOL vmlinux 0x1359bb1c d_invalidate +EXPORT_SYMBOL vmlinux 0x1374a41b generic_fillattr +EXPORT_SYMBOL vmlinux 0x1378e714 acpi_video_display_switch_support +EXPORT_SYMBOL vmlinux 0x137ac5a8 tty_register_device +EXPORT_SYMBOL vmlinux 0x1381b8de sock_kfree_s +EXPORT_SYMBOL vmlinux 0x1387e1e6 tcp_rcv_state_process +EXPORT_SYMBOL vmlinux 0x138b2518 sock_get_timestampns +EXPORT_SYMBOL vmlinux 0x138de5f2 dentry_open +EXPORT_SYMBOL vmlinux 0x13d75458 grab_cache_page_nowait +EXPORT_SYMBOL vmlinux 0x13dd2865 __skb_warn_lro_forwarding +EXPORT_SYMBOL vmlinux 0x13e41db9 filp_open +EXPORT_SYMBOL vmlinux 0x13e8fe2e nobh_write_end +EXPORT_SYMBOL vmlinux 0x13f6e920 simple_readpage +EXPORT_SYMBOL vmlinux 0x13f71731 tcf_hash_lookup +EXPORT_SYMBOL vmlinux 0x140e0279 jbd2_journal_force_commit +EXPORT_SYMBOL vmlinux 0x1430e6e0 unregister_acpi_notifier +EXPORT_SYMBOL vmlinux 0x143856e1 remap_vmalloc_range +EXPORT_SYMBOL vmlinux 0x145b7453 tty_hung_up_p +EXPORT_SYMBOL vmlinux 0x146118b1 thermal_cooling_device_unregister +EXPORT_SYMBOL vmlinux 0x1477548e acpi_root_dir +EXPORT_SYMBOL vmlinux 0x1477c728 flow_cache_lookup +EXPORT_SYMBOL vmlinux 0x1480fa25 mmc_suspend_host +EXPORT_SYMBOL vmlinux 0x14879f85 __bforget +EXPORT_SYMBOL vmlinux 0x14a4a0b9 blk_free_tags +EXPORT_SYMBOL vmlinux 0x14af0cf7 gen_pool_destroy +EXPORT_SYMBOL vmlinux 0x14b1f4d1 __kill_fasync +EXPORT_SYMBOL vmlinux 0x14dbd16d unregister_cdrom +EXPORT_SYMBOL vmlinux 0x1500a1b0 jbd2_journal_get_create_access +EXPORT_SYMBOL vmlinux 0x15076519 i2c_detach_client +EXPORT_SYMBOL vmlinux 0x150c296d misc_register +EXPORT_SYMBOL vmlinux 0x1523a019 blk_queue_end_tag +EXPORT_SYMBOL vmlinux 0x1544aad4 genl_register_mc_group +EXPORT_SYMBOL vmlinux 0x1551dc51 bitmap_find_free_region +EXPORT_SYMBOL vmlinux 0x1589b8d8 dquot_drop +EXPORT_SYMBOL vmlinux 0x15c8fad7 dquot_acquire +EXPORT_SYMBOL vmlinux 0x15ef2dd9 kfifo_free +EXPORT_SYMBOL vmlinux 0x15f4837e nf_log_packet +EXPORT_SYMBOL vmlinux 0x160211bc tcf_em_unregister +EXPORT_SYMBOL vmlinux 0x163472f7 hci_send_acl +EXPORT_SYMBOL vmlinux 0x1675606f bad_dma_address +EXPORT_SYMBOL vmlinux 0x167e7f9d __get_user_1 +EXPORT_SYMBOL vmlinux 0x16a35878 _read_unlock +EXPORT_SYMBOL vmlinux 0x16e6bcb3 dm_put_device +EXPORT_SYMBOL vmlinux 0x170c25ee acpi_get_next_object +EXPORT_SYMBOL vmlinux 0x172ed4d7 __vmalloc +EXPORT_SYMBOL vmlinux 0x1739832a security_sb_set_mnt_opts +EXPORT_SYMBOL vmlinux 0x173b74f2 agp_generic_alloc_page +EXPORT_SYMBOL vmlinux 0x17472522 journal_destroy +EXPORT_SYMBOL vmlinux 0x174eb704 uart_resume_port +EXPORT_SYMBOL vmlinux 0x1791caca pci_enable_msix +EXPORT_SYMBOL vmlinux 0x17931cd4 __dec_zone_page_state +EXPORT_SYMBOL vmlinux 0x17a76e71 rb_first +EXPORT_SYMBOL vmlinux 0x17ade817 agp_generic_mask_memory +EXPORT_SYMBOL vmlinux 0x17c09eaf set_pages_nx +EXPORT_SYMBOL vmlinux 0x17c85a66 radix_tree_tagged +EXPORT_SYMBOL vmlinux 0x17c95a8e compat_sock_get_timestamp +EXPORT_SYMBOL vmlinux 0x17d6c4bf tcp_rcv_established +EXPORT_SYMBOL vmlinux 0x17de15b6 do_splice_to +EXPORT_SYMBOL vmlinux 0x17df17bc sysctl_tcp_ecn +EXPORT_SYMBOL vmlinux 0x17eafeac set_pages_x +EXPORT_SYMBOL vmlinux 0x180d2d1d bdi_register_dev +EXPORT_SYMBOL vmlinux 0x18153faf bt_sock_poll +EXPORT_SYMBOL vmlinux 0x1815d57f generic_permission +EXPORT_SYMBOL vmlinux 0x181b6ff2 mempool_resize +EXPORT_SYMBOL vmlinux 0x183fa88b mempool_alloc_slab +EXPORT_SYMBOL vmlinux 0x18471524 pnp_device_detach +EXPORT_SYMBOL vmlinux 0x184dec25 fb_get_buffer_offset +EXPORT_SYMBOL vmlinux 0x18899507 agp_find_bridge +EXPORT_SYMBOL vmlinux 0x189b6bac memory_read_from_buffer +EXPORT_SYMBOL vmlinux 0x18a336a0 ipv6_chk_prefix +EXPORT_SYMBOL vmlinux 0x18b381bc mdiobus_register +EXPORT_SYMBOL vmlinux 0x18f5188a key_put +EXPORT_SYMBOL vmlinux 0x19006762 kobject_add +EXPORT_SYMBOL vmlinux 0x19079192 read_cache_page +EXPORT_SYMBOL vmlinux 0x190dc72d unregister_qdisc +EXPORT_SYMBOL vmlinux 0x19176123 neigh_for_each +EXPORT_SYMBOL vmlinux 0x192fd0a2 block_write_begin +EXPORT_SYMBOL vmlinux 0x1933b36b journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x19391763 iov_iter_fault_in_readable +EXPORT_SYMBOL vmlinux 0x1940c620 __xfrm_route_forward +EXPORT_SYMBOL vmlinux 0x1985ed3c prepare_to_wait_exclusive +EXPORT_SYMBOL vmlinux 0x199ed0cd net_disable_timestamp +EXPORT_SYMBOL vmlinux 0x19ac7490 ppp_register_channel +EXPORT_SYMBOL vmlinux 0x19cb2aa3 pci_clear_mwi +EXPORT_SYMBOL vmlinux 0x19d5d20a acpi_walk_namespace +EXPORT_SYMBOL vmlinux 0x19f36e4c dm_dirty_log_type_register +EXPORT_SYMBOL vmlinux 0x1a0cb885 i2c_put_adapter +EXPORT_SYMBOL vmlinux 0x1a0f7a9e ip_dev_find +EXPORT_SYMBOL vmlinux 0x1a18de0d jbd2_journal_update_format +EXPORT_SYMBOL vmlinux 0x1a1ab15d tty_mutex +EXPORT_SYMBOL vmlinux 0x1a1cbf6c pneigh_lookup +EXPORT_SYMBOL vmlinux 0x1a1d7bed dm_io_client_create +EXPORT_SYMBOL vmlinux 0x1a45cb6c acpi_disabled +EXPORT_SYMBOL vmlinux 0x1a5075fc path_permission +EXPORT_SYMBOL vmlinux 0x1a657c5c read_cache_page_async +EXPORT_SYMBOL vmlinux 0x1a7505be jbd2_journal_check_available_features +EXPORT_SYMBOL vmlinux 0x1a75caa3 _read_lock +EXPORT_SYMBOL vmlinux 0x1a8a845e idle_nomwait +EXPORT_SYMBOL vmlinux 0x1aa41e74 vfs_write +EXPORT_SYMBOL vmlinux 0x1aa9724f blk_put_request +EXPORT_SYMBOL vmlinux 0x1ac0950d unregister_sysrq_key +EXPORT_SYMBOL vmlinux 0x1ace138d bitmap_allocate_region +EXPORT_SYMBOL vmlinux 0x1ad2b9b8 inode_change_ok +EXPORT_SYMBOL vmlinux 0x1ae8d7dc param_set_invbool +EXPORT_SYMBOL vmlinux 0x1b015d25 bitmap_parselist +EXPORT_SYMBOL vmlinux 0x1b1bdd8c dquot_initialize +EXPORT_SYMBOL vmlinux 0x1b3b77bb file_permission +EXPORT_SYMBOL vmlinux 0x1b3c678a gen_new_estimator +EXPORT_SYMBOL vmlinux 0x1b4a5ae3 generic_file_open +EXPORT_SYMBOL vmlinux 0x1b4c94ef sock_init_data +EXPORT_SYMBOL vmlinux 0x1b4df3d7 unregister_filesystem +EXPORT_SYMBOL vmlinux 0x1b524da8 proc_dointvec_userhz_jiffies +EXPORT_SYMBOL vmlinux 0x1b6314fd in_aton +EXPORT_SYMBOL vmlinux 0x1b89419f add_wait_queue_exclusive +EXPORT_SYMBOL vmlinux 0x1b92facd tcp_parse_options +EXPORT_SYMBOL vmlinux 0x1b9981cc set_irq_wake +EXPORT_SYMBOL vmlinux 0x1b9e0ff1 scsilun_to_int +EXPORT_SYMBOL vmlinux 0x1ba40d85 do_SAK +EXPORT_SYMBOL vmlinux 0x1bcbc825 d_find_alias +EXPORT_SYMBOL vmlinux 0x1be8744f udp_disconnect +EXPORT_SYMBOL vmlinux 0x1c0e7f66 sb_has_dirty_inodes +EXPORT_SYMBOL vmlinux 0x1c2da9cf get_empty_filp +EXPORT_SYMBOL vmlinux 0x1c36ed22 sk_free +EXPORT_SYMBOL vmlinux 0x1c372d20 sk_release_kernel +EXPORT_SYMBOL vmlinux 0x1c56d004 brioctl_set +EXPORT_SYMBOL vmlinux 0x1c674a16 single_release +EXPORT_SYMBOL vmlinux 0x1c6d9ce1 scsi_host_get +EXPORT_SYMBOL vmlinux 0x1c7f59e4 journal_stop +EXPORT_SYMBOL vmlinux 0x1c87cc2d ip6_xmit +EXPORT_SYMBOL vmlinux 0x1cad252a uart_write_wakeup +EXPORT_SYMBOL vmlinux 0x1cc6719a register_reboot_notifier +EXPORT_SYMBOL vmlinux 0x1ceec59f sk_stream_wait_connect +EXPORT_SYMBOL vmlinux 0x1cefe352 wait_for_completion +EXPORT_SYMBOL vmlinux 0x1cf7cdde revalidate_disk +EXPORT_SYMBOL vmlinux 0x1d0883fc registered_fb +EXPORT_SYMBOL vmlinux 0x1d172f94 km_new_mapping +EXPORT_SYMBOL vmlinux 0x1d314be3 inet6_ioctl +EXPORT_SYMBOL vmlinux 0x1d3cfb6c d_rehash +EXPORT_SYMBOL vmlinux 0x1db3741e phy_driver_register +EXPORT_SYMBOL vmlinux 0x1db4fb1d d_prune_aliases +EXPORT_SYMBOL vmlinux 0x1db7706b __copy_user_nocache +EXPORT_SYMBOL vmlinux 0x1dc36131 fb_destroy_modedb +EXPORT_SYMBOL vmlinux 0x1dc9743d dev_mc_sync +EXPORT_SYMBOL vmlinux 0x1dd571e6 fb_copy_cmap +EXPORT_SYMBOL vmlinux 0x1df5cc80 swiotlb_map_single_attrs +EXPORT_SYMBOL vmlinux 0x1df868cf simple_rmdir +EXPORT_SYMBOL vmlinux 0x1e095613 skb_over_panic +EXPORT_SYMBOL vmlinux 0x1e0ab99b ip6_frag_init +EXPORT_SYMBOL vmlinux 0x1e0c94c1 netpoll_parse_options +EXPORT_SYMBOL vmlinux 0x1e103f06 xfrm_policy_insert +EXPORT_SYMBOL vmlinux 0x1e190fe1 dput +EXPORT_SYMBOL vmlinux 0x1e1ef162 inet_add_protocol +EXPORT_SYMBOL vmlinux 0x1e28cbfd task_session_nr_ns +EXPORT_SYMBOL vmlinux 0x1e2e427f cpumask_next_and +EXPORT_SYMBOL vmlinux 0x1e2f5175 agp_generic_destroy_page +EXPORT_SYMBOL vmlinux 0x1e3e3284 skb_copy_expand +EXPORT_SYMBOL vmlinux 0x1e52b1ba clear_inode +EXPORT_SYMBOL vmlinux 0x1e60f0af tcf_em_register +EXPORT_SYMBOL vmlinux 0x1e6d26a8 strstr +EXPORT_SYMBOL vmlinux 0x1e8d9d2a __set_page_dirty_buffers +EXPORT_SYMBOL vmlinux 0x1ea42fa6 unregister_nls +EXPORT_SYMBOL vmlinux 0x1eb922a3 IO_APIC_get_PCI_irq_vector +EXPORT_SYMBOL vmlinux 0x1ecbbd92 mmc_wait_for_cmd +EXPORT_SYMBOL vmlinux 0x1ee986a5 ip_mc_join_group +EXPORT_SYMBOL vmlinux 0x1efe283f __cap_full_set +EXPORT_SYMBOL vmlinux 0x1f04966f complete_request_key +EXPORT_SYMBOL vmlinux 0x1f1f59a3 mem_map +EXPORT_SYMBOL vmlinux 0x1f2067af textsearch_destroy +EXPORT_SYMBOL vmlinux 0x1f22da5c simple_sync_file +EXPORT_SYMBOL vmlinux 0x1f27d6d7 _write_unlock +EXPORT_SYMBOL vmlinux 0x1f48692e ppp_input +EXPORT_SYMBOL vmlinux 0x1f4ac055 acpi_processor_preregister_performance +EXPORT_SYMBOL vmlinux 0x1f58d936 pcix_get_max_mmrbc +EXPORT_SYMBOL vmlinux 0x1fb7df6b inet6_unregister_protosw +EXPORT_SYMBOL vmlinux 0x1fd623c6 force_sig +EXPORT_SYMBOL vmlinux 0x1ff36d03 sock_common_recvmsg +EXPORT_SYMBOL vmlinux 0x20000329 simple_strtoul +EXPORT_SYMBOL vmlinux 0x2005e68a acpi_remove_fixed_event_handler +EXPORT_SYMBOL vmlinux 0x20092385 acpi_enter_sleep_state_s4bios +EXPORT_SYMBOL vmlinux 0x201b3a0f jbd2_journal_start +EXPORT_SYMBOL vmlinux 0x201dbc8e unmap_underlying_metadata +EXPORT_SYMBOL vmlinux 0x2037f50a thermal_zone_bind_cooling_device +EXPORT_SYMBOL vmlinux 0x203c53a2 skb_queue_purge +EXPORT_SYMBOL vmlinux 0x2071bf25 i2c_del_adapter +EXPORT_SYMBOL vmlinux 0x207cff98 nf_ip_checksum +EXPORT_SYMBOL vmlinux 0x208739f6 acpi_load_table +EXPORT_SYMBOL vmlinux 0x208cfdaa bio_integrity_enabled +EXPORT_SYMBOL vmlinux 0x20a265d8 km_state_notify +EXPORT_SYMBOL vmlinux 0x20b52f1b blkdev_issue_discard +EXPORT_SYMBOL vmlinux 0x20c8fc33 pci_osc_control_set +EXPORT_SYMBOL vmlinux 0x20d4dbeb md_register_thread +EXPORT_SYMBOL vmlinux 0x20d8f9ca set_user_nice +EXPORT_SYMBOL vmlinux 0x20d965f0 dev_alloc_skb +EXPORT_SYMBOL vmlinux 0x20e73086 sock_create_kern +EXPORT_SYMBOL vmlinux 0x20eadeb6 ip_compute_csum +EXPORT_SYMBOL vmlinux 0x20f9322a idr_pre_get +EXPORT_SYMBOL vmlinux 0x20fa8ced path_get +EXPORT_SYMBOL vmlinux 0x211df440 tty_insert_flip_string_flags +EXPORT_SYMBOL vmlinux 0x21265937 mnt_pin +EXPORT_SYMBOL vmlinux 0x213fc970 jbd2_journal_wipe +EXPORT_SYMBOL vmlinux 0x2150bedb llc_mac_hdr_init +EXPORT_SYMBOL vmlinux 0x215ebd78 bitrev16 +EXPORT_SYMBOL vmlinux 0x2180374a tcp_poll +EXPORT_SYMBOL vmlinux 0x2189eb79 bio_integrity_alloc_bioset +EXPORT_SYMBOL vmlinux 0x219f7d4f pci_scan_slot +EXPORT_SYMBOL vmlinux 0x21b33bda tcp_v4_md5_lookup +EXPORT_SYMBOL vmlinux 0x21c3c002 page_symlink +EXPORT_SYMBOL vmlinux 0x21ce61e2 per_cpu__softnet_data +EXPORT_SYMBOL vmlinux 0x21e0ea22 acpi_get_id +EXPORT_SYMBOL vmlinux 0x21e5679c copy_user_generic +EXPORT_SYMBOL vmlinux 0x21e8df8e pci_request_regions +EXPORT_SYMBOL vmlinux 0x21ffc9e8 pci_get_subsys +EXPORT_SYMBOL vmlinux 0x222e7ce2 sysfs_streq +EXPORT_SYMBOL vmlinux 0x2253c959 kblockd_flush_work +EXPORT_SYMBOL vmlinux 0x2258a0bb acpi_bus_register_driver +EXPORT_SYMBOL vmlinux 0x225e3790 serio_unregister_child_port +EXPORT_SYMBOL vmlinux 0x226e86a9 audit_log +EXPORT_SYMBOL vmlinux 0x22805613 I_BDEV +EXPORT_SYMBOL vmlinux 0x2288378f system_state +EXPORT_SYMBOL vmlinux 0x228a8644 iget5_locked +EXPORT_SYMBOL vmlinux 0x2293912c pci_set_mwi +EXPORT_SYMBOL vmlinux 0x22a73912 __tcp_put_md5sig_pool +EXPORT_SYMBOL vmlinux 0x22aecc5d simple_write_begin +EXPORT_SYMBOL vmlinux 0x22b325d5 kd_mksound +EXPORT_SYMBOL vmlinux 0x22b62d9a bio_free +EXPORT_SYMBOL vmlinux 0x22b6533b xfrm_sad_getinfo +EXPORT_SYMBOL vmlinux 0x22d3d1dd simple_write_end +EXPORT_SYMBOL vmlinux 0x22e74c2d bio_integrity_advance +EXPORT_SYMBOL vmlinux 0x22e9842b __netdev_alloc_page +EXPORT_SYMBOL vmlinux 0x230466a9 __dev_get_by_name +EXPORT_SYMBOL vmlinux 0x231f3a66 __kfifo_put +EXPORT_SYMBOL vmlinux 0x23269a13 strict_strtoul +EXPORT_SYMBOL vmlinux 0x234509f3 strncat +EXPORT_SYMBOL vmlinux 0x234518cf sock_no_socketpair +EXPORT_SYMBOL vmlinux 0x234ac9df init_task +EXPORT_SYMBOL vmlinux 0x236c8c64 memcpy +EXPORT_SYMBOL vmlinux 0x238b10a6 inode_permission +EXPORT_SYMBOL vmlinux 0x239e3719 vfs_follow_link +EXPORT_SYMBOL vmlinux 0x23c8f257 slhc_uncompress +EXPORT_SYMBOL vmlinux 0x23e2715f bd_release +EXPORT_SYMBOL vmlinux 0x23fd3028 vmalloc_node +EXPORT_SYMBOL vmlinux 0x24428be5 strncpy_from_user +EXPORT_SYMBOL vmlinux 0x2459bbcc console_set_on_cmdline +EXPORT_SYMBOL vmlinux 0x247c1bd1 blk_queue_bounce +EXPORT_SYMBOL vmlinux 0x24837cd2 sk_dst_check +EXPORT_SYMBOL vmlinux 0x24cad263 keyring_search +EXPORT_SYMBOL vmlinux 0x24fdac79 wake_bit_function +EXPORT_SYMBOL vmlinux 0x252ece4a scsi_nonblockable_ioctl +EXPORT_SYMBOL vmlinux 0x25419de2 tcp_initialize_rcv_mss +EXPORT_SYMBOL vmlinux 0x256887e1 warn_slowpath +EXPORT_SYMBOL vmlinux 0x25820c64 fs_overflowuid +EXPORT_SYMBOL vmlinux 0x258355b4 fb_find_best_mode +EXPORT_SYMBOL vmlinux 0x25ec1b28 strlen +EXPORT_SYMBOL vmlinux 0x26205011 i2c_smbus_read_byte_data +EXPORT_SYMBOL vmlinux 0x263782b5 cancel_delayed_work_sync +EXPORT_SYMBOL vmlinux 0x263a597f dma_async_memcpy_buf_to_buf +EXPORT_SYMBOL vmlinux 0x26688b89 seq_open +EXPORT_SYMBOL vmlinux 0x266c4efa xfrm_state_walk +EXPORT_SYMBOL vmlinux 0x26815153 iget_failed +EXPORT_SYMBOL vmlinux 0x2685c3d7 __sg_alloc_table +EXPORT_SYMBOL vmlinux 0x268eae0d hci_get_route +EXPORT_SYMBOL vmlinux 0x26a37de6 netdev_set_master +EXPORT_SYMBOL vmlinux 0x26a6b57f blk_rq_append_bio +EXPORT_SYMBOL vmlinux 0x26ccbc11 inet_sk_rebuild_header +EXPORT_SYMBOL vmlinux 0x26d9ce4f blk_dump_rq_flags +EXPORT_SYMBOL vmlinux 0x26e76fb8 sysctl_udp_wmem_min +EXPORT_SYMBOL vmlinux 0x26e8d711 netlink_rcv_skb +EXPORT_SYMBOL vmlinux 0x26e97973 kmem_ptr_validate +EXPORT_SYMBOL vmlinux 0x26f27f88 i2c_get_adapter +EXPORT_SYMBOL vmlinux 0x270ecd29 tcf_destroy_chain +EXPORT_SYMBOL vmlinux 0x2719d8ec genl_unregister_ops +EXPORT_SYMBOL vmlinux 0x2727372d bio_copy_kern +EXPORT_SYMBOL vmlinux 0x272d394e mtrr_del +EXPORT_SYMBOL vmlinux 0x272e7488 cond_resched_softirq +EXPORT_SYMBOL vmlinux 0x273f066e _write_unlock_irq +EXPORT_SYMBOL vmlinux 0x27864d57 memparse +EXPORT_SYMBOL vmlinux 0x27879dac flush_signals +EXPORT_SYMBOL vmlinux 0x278ef1dd rtnetlink_put_metrics +EXPORT_SYMBOL vmlinux 0x27917d65 alloc_pci_dev +EXPORT_SYMBOL vmlinux 0x27a9a7eb ns_to_timespec +EXPORT_SYMBOL vmlinux 0x27b95d86 inet_register_protosw +EXPORT_SYMBOL vmlinux 0x27bbf221 disable_irq_nosync +EXPORT_SYMBOL vmlinux 0x27c0e46a d_move +EXPORT_SYMBOL vmlinux 0x27c33efe csum_ipv6_magic +EXPORT_SYMBOL vmlinux 0x27c61ece qdisc_put_stab +EXPORT_SYMBOL vmlinux 0x281a5dc4 __secpath_destroy +EXPORT_SYMBOL vmlinux 0x282a977d unregister_console +EXPORT_SYMBOL vmlinux 0x285135e6 acpi_evaluate_integer +EXPORT_SYMBOL vmlinux 0x285ac517 strict_strtoll +EXPORT_SYMBOL vmlinux 0x2876a6d3 memcpy_toiovec +EXPORT_SYMBOL vmlinux 0x28a2ed02 scsi_build_sense_buffer +EXPORT_SYMBOL vmlinux 0x28b56ac1 __skb_recv_datagram +EXPORT_SYMBOL vmlinux 0x28bf2c37 pcim_iomap_regions +EXPORT_SYMBOL vmlinux 0x28cd8f05 dev_set_promiscuity +EXPORT_SYMBOL vmlinux 0x28d2dc6f dmam_free_coherent +EXPORT_SYMBOL vmlinux 0x28dcf25c udplite_hash +EXPORT_SYMBOL vmlinux 0x28f343db pv_mmu_ops +EXPORT_SYMBOL vmlinux 0x29121b7c pskb_copy +EXPORT_SYMBOL vmlinux 0x29304349 __sk_dst_check +EXPORT_SYMBOL vmlinux 0x293d8a7f pci_enable_bridges +EXPORT_SYMBOL vmlinux 0x29537c9e alloc_chrdev_region +EXPORT_SYMBOL vmlinux 0x29554926 arp_tbl +EXPORT_SYMBOL vmlinux 0x299b83fc sb_set_blocksize +EXPORT_SYMBOL vmlinux 0x29ab5917 journal_extend +EXPORT_SYMBOL vmlinux 0x29b1176d xfrm_nl +EXPORT_SYMBOL vmlinux 0x29bd4c46 __cap_init_eff_set +EXPORT_SYMBOL vmlinux 0x29cf7b7f __blk_run_queue +EXPORT_SYMBOL vmlinux 0x2a281af6 generic_writepages +EXPORT_SYMBOL vmlinux 0x2a2a998a neigh_resolve_output +EXPORT_SYMBOL vmlinux 0x2a303d4d check_signature +EXPORT_SYMBOL vmlinux 0x2a457d85 tcp_read_sock +EXPORT_SYMBOL vmlinux 0x2a6fd6f3 acpi_get_physical_pci_device +EXPORT_SYMBOL vmlinux 0x2a7df9b7 rtnl_notify +EXPORT_SYMBOL vmlinux 0x2aa353cd nf_unregister_sockopt +EXPORT_SYMBOL vmlinux 0x2ac73cf8 phy_disconnect +EXPORT_SYMBOL vmlinux 0x2ad34755 neigh_ifdown +EXPORT_SYMBOL vmlinux 0x2aeb2800 mempool_create_node +EXPORT_SYMBOL vmlinux 0x2aee5a16 mpage_readpages +EXPORT_SYMBOL vmlinux 0x2afaacc8 input_set_keycode +EXPORT_SYMBOL vmlinux 0x2b0ba2b0 scsi_sense_desc_find +EXPORT_SYMBOL vmlinux 0x2b37632e __lookup_hash +EXPORT_SYMBOL vmlinux 0x2b5010a9 tcf_exts_destroy +EXPORT_SYMBOL vmlinux 0x2b6aac8c tcp_sockets_allocated +EXPORT_SYMBOL vmlinux 0x2b801f7d vfs_get_dqblk +EXPORT_SYMBOL vmlinux 0x2ba707a8 sysctl_tcp_low_latency +EXPORT_SYMBOL vmlinux 0x2bae8a88 mmc_unregister_driver +EXPORT_SYMBOL vmlinux 0x2bb55d6e acpi_remove_notify_handler +EXPORT_SYMBOL vmlinux 0x2be09893 _atomic_dec_and_lock +EXPORT_SYMBOL vmlinux 0x2be74a86 neigh_seq_next +EXPORT_SYMBOL vmlinux 0x2bfc63f1 tcp_connect +EXPORT_SYMBOL vmlinux 0x2bfeb410 acpi_get_handle +EXPORT_SYMBOL vmlinux 0x2c08b3ad hci_free_dev +EXPORT_SYMBOL vmlinux 0x2c094594 bio_integrity_get_tag +EXPORT_SYMBOL vmlinux 0x2c14bf80 register_qdisc +EXPORT_SYMBOL vmlinux 0x2c3568dc iov_iter_copy_from_user +EXPORT_SYMBOL vmlinux 0x2c384cb3 dma_async_client_register +EXPORT_SYMBOL vmlinux 0x2c3caeb6 skb_copy_and_csum_dev +EXPORT_SYMBOL vmlinux 0x2c5749e6 acpi_clear_gpe +EXPORT_SYMBOL vmlinux 0x2c741ff6 scsi_unregister +EXPORT_SYMBOL vmlinux 0x2cb69dc1 fifo_set_limit +EXPORT_SYMBOL vmlinux 0x2cb7c6f1 dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0x2cc2d52d vcc_hash +EXPORT_SYMBOL vmlinux 0x2cd9e459 param_set_short +EXPORT_SYMBOL vmlinux 0x2cf190e3 request_irq +EXPORT_SYMBOL vmlinux 0x2d06ea56 dquot_free_space +EXPORT_SYMBOL vmlinux 0x2d5528c9 sg_copy_to_buffer +EXPORT_SYMBOL vmlinux 0x2d891384 swiotlb_unmap_sg_attrs +EXPORT_SYMBOL vmlinux 0x2d89342a scsi_show_sense_hdr +EXPORT_SYMBOL vmlinux 0x2d8bb4c1 single_open +EXPORT_SYMBOL vmlinux 0x2da23671 skb_append +EXPORT_SYMBOL vmlinux 0x2dbafbe3 pcibios_align_resource +EXPORT_SYMBOL vmlinux 0x2dbd324f sock_rfree +EXPORT_SYMBOL vmlinux 0x2dbd488e __skb_checksum_complete +EXPORT_SYMBOL vmlinux 0x2dc846ae dma_sync_wait +EXPORT_SYMBOL vmlinux 0x2dd16564 arch_register_cpu +EXPORT_SYMBOL vmlinux 0x2ddf758d nf_ip6_checksum +EXPORT_SYMBOL vmlinux 0x2de8d987 journal_lock_updates +EXPORT_SYMBOL vmlinux 0x2de9f66f param_get_long +EXPORT_SYMBOL vmlinux 0x2dedc4c2 acpi_format_exception +EXPORT_SYMBOL vmlinux 0x2def7f76 rtc_cmos_write +EXPORT_SYMBOL vmlinux 0x2e2ce9e0 sysctl_tcp_syncookies +EXPORT_SYMBOL vmlinux 0x2e41f365 sock_no_setsockopt +EXPORT_SYMBOL vmlinux 0x2e4a39f8 sysctl_udp_mem +EXPORT_SYMBOL vmlinux 0x2e4fb343 scsi_scan_host +EXPORT_SYMBOL vmlinux 0x2e50b523 usb_serial_suspend +EXPORT_SYMBOL vmlinux 0x2e51fbed blk_rq_map_integrity_sg +EXPORT_SYMBOL vmlinux 0x2e59bf67 pnp_activate_dev +EXPORT_SYMBOL vmlinux 0x2e97a729 idr_remove +EXPORT_SYMBOL vmlinux 0x2e9a22e9 __dev_remove_pack +EXPORT_SYMBOL vmlinux 0x2eb2cd8c vfs_readdir +EXPORT_SYMBOL vmlinux 0x2eb7a5d7 set_device_ro +EXPORT_SYMBOL vmlinux 0x2eb9a0e8 _read_lock_irq +EXPORT_SYMBOL vmlinux 0x2ee829e3 udplite_prot +EXPORT_SYMBOL vmlinux 0x2eed9583 uart_add_one_port +EXPORT_SYMBOL vmlinux 0x2ef1cade tcp_proc_register +EXPORT_SYMBOL vmlinux 0x2ef3d52f thermal_cooling_device_register +EXPORT_SYMBOL vmlinux 0x2f109287 truncate_inode_pages_range +EXPORT_SYMBOL vmlinux 0x2f13a9db invalidate_partition +EXPORT_SYMBOL vmlinux 0x2f57a663 pcim_enable_device +EXPORT_SYMBOL vmlinux 0x2f670530 acpi_unlock_ac_dir +EXPORT_SYMBOL vmlinux 0x2f84a7e8 uart_suspend_port +EXPORT_SYMBOL vmlinux 0x2fa5a500 memcmp +EXPORT_SYMBOL vmlinux 0x2fb19ede fb_show_logo +EXPORT_SYMBOL vmlinux 0x2fe3b854 scsi_execute_req +EXPORT_SYMBOL vmlinux 0x2feb0c5b sysctl_jiffies +EXPORT_SYMBOL vmlinux 0x2ff063b5 acpi_get_name +EXPORT_SYMBOL vmlinux 0x2ff1610d tcp_v4_connect +EXPORT_SYMBOL vmlinux 0x2ff7efaa tcf_hash_new_index +EXPORT_SYMBOL vmlinux 0x30123eb5 icmpv6_statistics +EXPORT_SYMBOL vmlinux 0x30226ddf agp_device_command +EXPORT_SYMBOL vmlinux 0x306bd3c3 vfs_fstat +EXPORT_SYMBOL vmlinux 0x307f0827 scsi_finish_command +EXPORT_SYMBOL vmlinux 0x30aade9b sync_page_range +EXPORT_SYMBOL vmlinux 0x30b22bab swiotlb_sync_single_for_cpu +EXPORT_SYMBOL vmlinux 0x30c5dc03 tcp_simple_retransmit +EXPORT_SYMBOL vmlinux 0x30de8b2e copy_io_context +EXPORT_SYMBOL vmlinux 0x30e74134 tty_termios_copy_hw +EXPORT_SYMBOL vmlinux 0x31092a45 blk_rq_map_kern +EXPORT_SYMBOL vmlinux 0x31406e82 dquot_mark_dquot_dirty +EXPORT_SYMBOL vmlinux 0x3145216f pci_dev_present +EXPORT_SYMBOL vmlinux 0x314693bd md_error +EXPORT_SYMBOL vmlinux 0x3147857d default_red +EXPORT_SYMBOL vmlinux 0x3157a7b1 __mmc_claim_host +EXPORT_SYMBOL vmlinux 0x3182ebc8 tcp_md5_hash_key +EXPORT_SYMBOL vmlinux 0x31b31f5c csum_partial_copy_nocheck +EXPORT_SYMBOL vmlinux 0x31ebadcd in_group_p +EXPORT_SYMBOL vmlinux 0x320d0972 bdput +EXPORT_SYMBOL vmlinux 0x3261cffc tty_devnum +EXPORT_SYMBOL vmlinux 0x326ba0c4 km_report +EXPORT_SYMBOL vmlinux 0x326e9b64 blk_remove_plug +EXPORT_SYMBOL vmlinux 0x32ce9342 tcf_hash_search +EXPORT_SYMBOL vmlinux 0x32d01fec acpi_attach_data +EXPORT_SYMBOL vmlinux 0x32f87920 inet_frag_kill +EXPORT_SYMBOL vmlinux 0x330d556f gnet_stats_copy_app +EXPORT_SYMBOL vmlinux 0x3360a963 param_set_ulong +EXPORT_SYMBOL vmlinux 0x33651ad5 atm_charge +EXPORT_SYMBOL vmlinux 0x3369cd0b alloc_etherdev_mq +EXPORT_SYMBOL vmlinux 0x336ba577 elv_rq_merge_ok +EXPORT_SYMBOL vmlinux 0x33b84f74 copy_page +EXPORT_SYMBOL vmlinux 0x33ba1447 ppp_register_compressor +EXPORT_SYMBOL vmlinux 0x33bae2c7 udp_flush_pending_frames +EXPORT_SYMBOL vmlinux 0x33cda660 posix_acl_from_mode +EXPORT_SYMBOL vmlinux 0x33d92f9a prepare_to_wait +EXPORT_SYMBOL vmlinux 0x340e6101 nf_unregister_hook +EXPORT_SYMBOL vmlinux 0x3471a40d blk_rq_map_user +EXPORT_SYMBOL vmlinux 0x349cba85 strchr +EXPORT_SYMBOL vmlinux 0x349d4d02 vm_map_ram +EXPORT_SYMBOL vmlinux 0x34ea47ff genphy_config_aneg +EXPORT_SYMBOL vmlinux 0x34f90edf udp_sendmsg +EXPORT_SYMBOL vmlinux 0x34fce488 pci_remove_bus +EXPORT_SYMBOL vmlinux 0x351a3cb1 get_super +EXPORT_SYMBOL vmlinux 0x352f7444 __brelse +EXPORT_SYMBOL vmlinux 0x35327d6f sk_stream_error +EXPORT_SYMBOL vmlinux 0x356c4cdc pci_request_selected_regions +EXPORT_SYMBOL vmlinux 0x358ae134 xfrm_unregister_mode +EXPORT_SYMBOL vmlinux 0x358e92f7 inet_csk_destroy_sock +EXPORT_SYMBOL vmlinux 0x359ee5c9 add_disk +EXPORT_SYMBOL vmlinux 0x35a07e32 vfs_stat +EXPORT_SYMBOL vmlinux 0x35ab1162 i2c_smbus_write_i2c_block_data +EXPORT_SYMBOL vmlinux 0x35b0650f vsnprintf +EXPORT_SYMBOL vmlinux 0x35c2ba9e refrigerator +EXPORT_SYMBOL vmlinux 0x36051349 acpi_bus_get_device +EXPORT_SYMBOL vmlinux 0x360b1afe probe_irq_mask +EXPORT_SYMBOL vmlinux 0x36139a51 memcpy_fromiovec +EXPORT_SYMBOL vmlinux 0x3616c547 blkdev_put +EXPORT_SYMBOL vmlinux 0x3639e95f blk_sync_queue +EXPORT_SYMBOL vmlinux 0x363ad247 cap_set_effective +EXPORT_SYMBOL vmlinux 0x3656bf5a lock_kernel +EXPORT_SYMBOL vmlinux 0x365a3202 seq_path +EXPORT_SYMBOL vmlinux 0x365c06dd clip_tbl_hook +EXPORT_SYMBOL vmlinux 0x3672224d kernel_bind +EXPORT_SYMBOL vmlinux 0x3673a38b inet_getname +EXPORT_SYMBOL vmlinux 0x3685fbac serio_interrupt +EXPORT_SYMBOL vmlinux 0x3699509d pci_get_device +EXPORT_SYMBOL vmlinux 0x369df217 journal_init_inode +EXPORT_SYMBOL vmlinux 0x36b6f5ad phy_disable_interrupts +EXPORT_SYMBOL vmlinux 0x36db2bb5 netpoll_send_udp +EXPORT_SYMBOL vmlinux 0x36e32136 pci_pme_capable +EXPORT_SYMBOL vmlinux 0x36e3b8da inet6_release +EXPORT_SYMBOL vmlinux 0x3701a196 csum_partial_copy_to_user +EXPORT_SYMBOL vmlinux 0x3715f105 d_genocide +EXPORT_SYMBOL vmlinux 0x3744cf36 vmalloc_to_pfn +EXPORT_SYMBOL vmlinux 0x375465a7 radix_tree_gang_lookup_tag_slot +EXPORT_SYMBOL vmlinux 0x377b7856 generic_file_mmap +EXPORT_SYMBOL vmlinux 0x378305f3 shrink_dcache_parent +EXPORT_SYMBOL vmlinux 0x37befc70 jiffies_to_msecs +EXPORT_SYMBOL vmlinux 0x37ce9e7a mb_cache_entry_alloc +EXPORT_SYMBOL vmlinux 0x38103e34 dm_table_get_md +EXPORT_SYMBOL vmlinux 0x38119468 sock_no_accept +EXPORT_SYMBOL vmlinux 0x38224889 simple_lookup +EXPORT_SYMBOL vmlinux 0x3849804c kernel_sendmsg +EXPORT_SYMBOL vmlinux 0x3852c9da __mod_zone_page_state +EXPORT_SYMBOL vmlinux 0x388d0556 xfrm_alloc_spi +EXPORT_SYMBOL vmlinux 0x388e3850 dma_pool_alloc +EXPORT_SYMBOL vmlinux 0x388f9128 xfrm_state_walk_done +EXPORT_SYMBOL vmlinux 0x38a4965d bio_get_nr_vecs +EXPORT_SYMBOL vmlinux 0x38b92846 llc_remove_pack +EXPORT_SYMBOL vmlinux 0x38f33bed dump_fpu +EXPORT_SYMBOL vmlinux 0x3932d0ee proc_dointvec_jiffies +EXPORT_SYMBOL vmlinux 0x3980aac1 unregister_reboot_notifier +EXPORT_SYMBOL vmlinux 0x3991db43 llc_add_pack +EXPORT_SYMBOL vmlinux 0x39c16f1e release_firmware +EXPORT_SYMBOL vmlinux 0x39cd891a __down_write_trylock +EXPORT_SYMBOL vmlinux 0x39f7e053 pneigh_enqueue +EXPORT_SYMBOL vmlinux 0x3a2003a3 iommu_nr_pages +EXPORT_SYMBOL vmlinux 0x3a2204c6 security_netlink_recv +EXPORT_SYMBOL vmlinux 0x3a2959a5 dev_kfree_skb_any +EXPORT_SYMBOL vmlinux 0x3a2acae3 sock_map_fd +EXPORT_SYMBOL vmlinux 0x3a698d29 set_page_dirty_lock +EXPORT_SYMBOL vmlinux 0x3a9b6fb9 blk_unregister_region +EXPORT_SYMBOL vmlinux 0x3aa1dbcf _spin_unlock_bh +EXPORT_SYMBOL vmlinux 0x3ab4ffd1 compat_tcp_setsockopt +EXPORT_SYMBOL vmlinux 0x3adbddd1 generic_block_bmap +EXPORT_SYMBOL vmlinux 0x3b298f72 sock_no_ioctl +EXPORT_SYMBOL vmlinux 0x3b3016d3 cpufreq_unregister_notifier +EXPORT_SYMBOL vmlinux 0x3b67cbbf __init_rwsem +EXPORT_SYMBOL vmlinux 0x3b6d96a5 netpoll_print_options +EXPORT_SYMBOL vmlinux 0x3b706deb nobh_write_begin +EXPORT_SYMBOL vmlinux 0x3b9d1e63 acpi_get_physical_device +EXPORT_SYMBOL vmlinux 0x3bcba798 gnet_stats_copy_queue +EXPORT_SYMBOL vmlinux 0x3bd1b1f6 msecs_to_jiffies +EXPORT_SYMBOL vmlinux 0x3beed89a kthread_bind +EXPORT_SYMBOL vmlinux 0x3c199319 vfs_statfs +EXPORT_SYMBOL vmlinux 0x3c26fa17 udp_ioctl +EXPORT_SYMBOL vmlinux 0x3c2c5af5 sprintf +EXPORT_SYMBOL vmlinux 0x3c348dce __serio_register_driver +EXPORT_SYMBOL vmlinux 0x3c3be62a sock_alloc_send_skb +EXPORT_SYMBOL vmlinux 0x3c4887e1 vfs_dq_transfer +EXPORT_SYMBOL vmlinux 0x3c7227bf complete_all +EXPORT_SYMBOL vmlinux 0x3c77f440 alloc_disk_node +EXPORT_SYMBOL vmlinux 0x3c898c9d dcache_dir_open +EXPORT_SYMBOL vmlinux 0x3c8e3114 dma_async_device_register +EXPORT_SYMBOL vmlinux 0x3c9cee7e journal_update_format +EXPORT_SYMBOL vmlinux 0x3c9d1211 string_get_size +EXPORT_SYMBOL vmlinux 0x3cb8a495 param_get_string +EXPORT_SYMBOL vmlinux 0x3cc0a3bb xfrm_spd_getinfo +EXPORT_SYMBOL vmlinux 0x3ce4ca6f disable_irq +EXPORT_SYMBOL vmlinux 0x3cf09da1 skb_pad +EXPORT_SYMBOL vmlinux 0x3d231728 write_one_page +EXPORT_SYMBOL vmlinux 0x3d421196 xfrm_state_check_expire +EXPORT_SYMBOL vmlinux 0x3d59592d tcf_generic_walker +EXPORT_SYMBOL vmlinux 0x3d9001f7 skb_split +EXPORT_SYMBOL vmlinux 0x3d9ee9f0 clear_page +EXPORT_SYMBOL vmlinux 0x3da171f9 pci_mem_start +EXPORT_SYMBOL vmlinux 0x3da5eb6d kfifo_alloc +EXPORT_SYMBOL vmlinux 0x3dafe793 pci_enable_device +EXPORT_SYMBOL vmlinux 0x3db2e258 radix_tree_gang_lookup +EXPORT_SYMBOL vmlinux 0x3e199f1d bdi_unregister +EXPORT_SYMBOL vmlinux 0x3e1e1adf fb_find_mode +EXPORT_SYMBOL vmlinux 0x3e1f073d wait_for_completion_timeout +EXPORT_SYMBOL vmlinux 0x3e219de6 try_wait_for_completion +EXPORT_SYMBOL vmlinux 0x3e285ec6 __getblk +EXPORT_SYMBOL vmlinux 0x3e2ae3a8 acpi_release_global_lock +EXPORT_SYMBOL vmlinux 0x3e383385 nf_hooks +EXPORT_SYMBOL vmlinux 0x3e3c36ed xfrm_policy_delete +EXPORT_SYMBOL vmlinux 0x3e45e9ff register_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x3e472776 bitmap_close_sync +EXPORT_SYMBOL vmlinux 0x3e72271d call_usermodehelper_setcleanup +EXPORT_SYMBOL vmlinux 0x3e7ae090 unregister_exec_domain +EXPORT_SYMBOL vmlinux 0x3ebed522 devm_ioremap_nocache +EXPORT_SYMBOL vmlinux 0x3ecb576a close_bdev_exclusive +EXPORT_SYMBOL vmlinux 0x3ed63055 zlib_inflateReset +EXPORT_SYMBOL vmlinux 0x3ef8409e blk_verify_command +EXPORT_SYMBOL vmlinux 0x3efcadda register_nls +EXPORT_SYMBOL vmlinux 0x3efed9c1 pnp_request_card_device +EXPORT_SYMBOL vmlinux 0x3f0546a8 ioread32_rep +EXPORT_SYMBOL vmlinux 0x3f1899f1 up +EXPORT_SYMBOL vmlinux 0x3f2324fb ip6_route_me_harder +EXPORT_SYMBOL vmlinux 0x3f2b34c9 cdrom_get_media_event +EXPORT_SYMBOL vmlinux 0x3f4547a7 put_unused_fd +EXPORT_SYMBOL vmlinux 0x3f659d90 i2c_del_driver +EXPORT_SYMBOL vmlinux 0x3f96e2f2 dcache_dir_lseek +EXPORT_SYMBOL vmlinux 0x3fa913da strspn +EXPORT_SYMBOL vmlinux 0x3fc56f74 bitmap_cond_end_sync +EXPORT_SYMBOL vmlinux 0x3fec048f sg_next +EXPORT_SYMBOL vmlinux 0x3fee578c find_inode_number +EXPORT_SYMBOL vmlinux 0x3ff62317 local_bh_disable +EXPORT_SYMBOL vmlinux 0x3ff7abbc journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0x40228261 pci_scan_single_device +EXPORT_SYMBOL vmlinux 0x405c1144 get_seconds +EXPORT_SYMBOL vmlinux 0x4065c9f6 inet_dgram_connect +EXPORT_SYMBOL vmlinux 0x409873e3 tty_termios_baud_rate +EXPORT_SYMBOL vmlinux 0x4099e614 compute_creds +EXPORT_SYMBOL vmlinux 0x409d3e27 get_fs_type +EXPORT_SYMBOL vmlinux 0x40c4cb94 nf_register_hook +EXPORT_SYMBOL vmlinux 0x40c89d46 acpi_get_table_by_index +EXPORT_SYMBOL vmlinux 0x40e29b20 sock_sendmsg +EXPORT_SYMBOL vmlinux 0x40e8140f scsi_calculate_bounce_limit +EXPORT_SYMBOL vmlinux 0x40eb1795 genphy_restart_aneg +EXPORT_SYMBOL vmlinux 0x40ec4bce sysctl_intvec +EXPORT_SYMBOL vmlinux 0x4100f2f6 elv_dispatch_add_tail +EXPORT_SYMBOL vmlinux 0x4108e69a fb_match_mode +EXPORT_SYMBOL vmlinux 0x41482d8b strndup_user +EXPORT_SYMBOL vmlinux 0x416983d9 netdev_fix_features +EXPORT_SYMBOL vmlinux 0x418269c6 tcp_tso_segment +EXPORT_SYMBOL vmlinux 0x4188d439 neigh_rand_reach_time +EXPORT_SYMBOL vmlinux 0x41a7c227 schedule_delayed_work +EXPORT_SYMBOL vmlinux 0x41a9c68d _spin_trylock_bh +EXPORT_SYMBOL vmlinux 0x41c60dc7 sk_stream_kill_queues +EXPORT_SYMBOL vmlinux 0x4211c3c1 zlib_inflateInit2 +EXPORT_SYMBOL vmlinux 0x42205caf get_unmapped_area +EXPORT_SYMBOL vmlinux 0x42224298 sscanf +EXPORT_SYMBOL vmlinux 0x422c05d0 acpi_get_data +EXPORT_SYMBOL vmlinux 0x42380ed1 neigh_sysctl_unregister +EXPORT_SYMBOL vmlinux 0x423fdb41 generic_delete_inode +EXPORT_SYMBOL vmlinux 0x4264c52a generic_file_splice_read +EXPORT_SYMBOL vmlinux 0x4292f948 find_task_by_pid_ns +EXPORT_SYMBOL vmlinux 0x429fce76 blk_execute_rq +EXPORT_SYMBOL vmlinux 0x42a4bdf2 in_egroup_p +EXPORT_SYMBOL vmlinux 0x42c49d24 pci_enable_device_io +EXPORT_SYMBOL vmlinux 0x42c8de35 ioremap_nocache +EXPORT_SYMBOL vmlinux 0x42e78535 blk_queue_invalidate_tags +EXPORT_SYMBOL vmlinux 0x42fdba67 da903x_query_status +EXPORT_SYMBOL vmlinux 0x42ff9b19 unregister_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0x4302d0eb free_pages +EXPORT_SYMBOL vmlinux 0x4316e256 dm_kcopyd_client_create +EXPORT_SYMBOL vmlinux 0x4327f0d5 memset_io +EXPORT_SYMBOL vmlinux 0x43385ad9 acpi_pci_unregister_driver +EXPORT_SYMBOL vmlinux 0x433b9f95 free_task +EXPORT_SYMBOL vmlinux 0x434fa55c release_console_sem +EXPORT_SYMBOL vmlinux 0x435b36d9 call_usermodehelper_pipe +EXPORT_SYMBOL vmlinux 0x435b566d _spin_unlock +EXPORT_SYMBOL vmlinux 0x435dcca7 blk_init_queue +EXPORT_SYMBOL vmlinux 0x436c2179 iowrite32 +EXPORT_SYMBOL vmlinux 0x4370c734 alloc_netdev_mq +EXPORT_SYMBOL vmlinux 0x4391075c scsi_remove_device +EXPORT_SYMBOL vmlinux 0x43bb2b77 tcp_v4_md5_hash_skb +EXPORT_SYMBOL vmlinux 0x43ec913a put_cmsg +EXPORT_SYMBOL vmlinux 0x43ed2774 kill_pgrp +EXPORT_SYMBOL vmlinux 0x44161c19 unregister_shrinker +EXPORT_SYMBOL vmlinux 0x444779c4 nla_find +EXPORT_SYMBOL vmlinux 0x4465bd0b tcp_v4_conn_request +EXPORT_SYMBOL vmlinux 0x4468daca __module_put_and_exit +EXPORT_SYMBOL vmlinux 0x4470fb17 vfs_unlink +EXPORT_SYMBOL vmlinux 0x447ffc39 i2c_smbus_write_byte_data +EXPORT_SYMBOL vmlinux 0x449436df tcp_check_req +EXPORT_SYMBOL vmlinux 0x449b428f get_phy_id +EXPORT_SYMBOL vmlinux 0x44aaf30f tsc_khz +EXPORT_SYMBOL vmlinux 0x44b4f979 ethtool_op_get_sg +EXPORT_SYMBOL vmlinux 0x44b911c3 rb_replace_node +EXPORT_SYMBOL vmlinux 0x44c55333 tty_driver_flush_buffer +EXPORT_SYMBOL vmlinux 0x44c999da phy_mii_ioctl +EXPORT_SYMBOL vmlinux 0x44d560e3 init_level4_pgt +EXPORT_SYMBOL vmlinux 0x44e9a829 match_token +EXPORT_SYMBOL vmlinux 0x44f5d39d blk_queue_init_tags +EXPORT_SYMBOL vmlinux 0x44ffc02e dm_dirty_log_destroy +EXPORT_SYMBOL vmlinux 0x45133753 pci_release_regions +EXPORT_SYMBOL vmlinux 0x4526b2f4 d_namespace_path +EXPORT_SYMBOL vmlinux 0x453438eb fb_pan_display +EXPORT_SYMBOL vmlinux 0x454b6b8b pnp_get_resource +EXPORT_SYMBOL vmlinux 0x4550ba8a register_cpu_notifier +EXPORT_SYMBOL vmlinux 0x455fd57d acpi_set_register +EXPORT_SYMBOL vmlinux 0x45704798 print_hex_dump_bytes +EXPORT_SYMBOL vmlinux 0x4572534c key_payload_reserve +EXPORT_SYMBOL vmlinux 0x4574007a register_sysctl_table +EXPORT_SYMBOL vmlinux 0x45a20318 poll_freewait +EXPORT_SYMBOL vmlinux 0x45bb123e try_to_del_timer_sync +EXPORT_SYMBOL vmlinux 0x45d11c43 down_interruptible +EXPORT_SYMBOL vmlinux 0x45f8404e elv_next_request +EXPORT_SYMBOL vmlinux 0x4611eb6e find_task_by_vpid +EXPORT_SYMBOL vmlinux 0x46206f0f cdev_init +EXPORT_SYMBOL vmlinux 0x46341a6e __dev_get_by_index +EXPORT_SYMBOL vmlinux 0x4635aa9d iw_handler_set_spy +EXPORT_SYMBOL vmlinux 0x4653b7e1 thaw_process +EXPORT_SYMBOL vmlinux 0x466c14a7 __delay +EXPORT_SYMBOL vmlinux 0x4673f74b netlink_clear_multicast_users +EXPORT_SYMBOL vmlinux 0x4679020d pnp_register_card_driver +EXPORT_SYMBOL vmlinux 0x469266e1 dev_unicast_unsync +EXPORT_SYMBOL vmlinux 0x46a1fc92 kill_block_super +EXPORT_SYMBOL vmlinux 0x46af11aa aio_put_req +EXPORT_SYMBOL vmlinux 0x46bc276b skb_add_rx_frag +EXPORT_SYMBOL vmlinux 0x46e619eb bt_sock_register +EXPORT_SYMBOL vmlinux 0x470a0b1e scsi_remove_host +EXPORT_SYMBOL vmlinux 0x475100c2 inet_get_local_port_range +EXPORT_SYMBOL vmlinux 0x475f010b acpi_purge_cached_objects +EXPORT_SYMBOL vmlinux 0x475f05af acpi_set_firmware_waking_vector +EXPORT_SYMBOL vmlinux 0x4776ea98 clear_page_dirty_for_io +EXPORT_SYMBOL vmlinux 0x477d1434 km_policy_notify +EXPORT_SYMBOL vmlinux 0x478b04c7 pci_enable_wake +EXPORT_SYMBOL vmlinux 0x478d10b2 ht_destroy_irq +EXPORT_SYMBOL vmlinux 0x47908454 tcp_mtup_init +EXPORT_SYMBOL vmlinux 0x47939e0d __tasklet_hi_schedule +EXPORT_SYMBOL vmlinux 0x479c3c86 find_next_zero_bit +EXPORT_SYMBOL vmlinux 0x47c3ea2a unlock_page +EXPORT_SYMBOL vmlinux 0x47e0048d pci_bus_read_config_dword +EXPORT_SYMBOL vmlinux 0x47f5b0e7 read_dev_sector +EXPORT_SYMBOL vmlinux 0x4810aed0 xfrm_find_acq +EXPORT_SYMBOL vmlinux 0x48139088 __tcp_get_md5sig_pool +EXPORT_SYMBOL vmlinux 0x4814f1ad tcp_v4_destroy_sock +EXPORT_SYMBOL vmlinux 0x481cb9ab acpi_enter_sleep_state_prep +EXPORT_SYMBOL vmlinux 0x4825376a inet_listen +EXPORT_SYMBOL vmlinux 0x4829bea6 ps2_sendbyte +EXPORT_SYMBOL vmlinux 0x4859b8bb rtc_year_days +EXPORT_SYMBOL vmlinux 0x486b6407 hweight64 +EXPORT_SYMBOL vmlinux 0x48a18bde take_over_console +EXPORT_SYMBOL vmlinux 0x48a63abc pci_bus_read_config_word +EXPORT_SYMBOL vmlinux 0x48baca5a __scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0x48cd6404 dquot_alloc_space +EXPORT_SYMBOL vmlinux 0x48eef067 netlink_dump_start +EXPORT_SYMBOL vmlinux 0x48f1b504 write_inode_now +EXPORT_SYMBOL vmlinux 0x4904b042 mntput_no_expire +EXPORT_SYMBOL vmlinux 0x49088768 journal_ack_err +EXPORT_SYMBOL vmlinux 0x4916e964 simple_fill_super +EXPORT_SYMBOL vmlinux 0x49319f9d loop_register_transfer +EXPORT_SYMBOL vmlinux 0x493e25e1 udp_hash +EXPORT_SYMBOL vmlinux 0x49603fb8 security_sb_copy_data +EXPORT_SYMBOL vmlinux 0x4969b543 vfs_set_dqinfo +EXPORT_SYMBOL vmlinux 0x4969b5c1 __napi_schedule +EXPORT_SYMBOL vmlinux 0x496e1c67 xfrm_state_unregister_afinfo +EXPORT_SYMBOL vmlinux 0x49b547a2 sk_send_sigurg +EXPORT_SYMBOL vmlinux 0x49c5c8de scsi_device_set_state +EXPORT_SYMBOL vmlinux 0x49c8e72c neigh_parms_alloc +EXPORT_SYMBOL vmlinux 0x49d3fc10 mb_cache_entry_find_next +EXPORT_SYMBOL vmlinux 0x49da9a9a _read_unlock_bh +EXPORT_SYMBOL vmlinux 0x49f06839 lock_super +EXPORT_SYMBOL vmlinux 0x4a161231 open_bdev_exclusive +EXPORT_SYMBOL vmlinux 0x4a326cd7 sock_wake_async +EXPORT_SYMBOL vmlinux 0x4a358252 __bitmap_subset +EXPORT_SYMBOL vmlinux 0x4a422356 unbind_con_driver +EXPORT_SYMBOL vmlinux 0x4a4fa755 input_allocate_device +EXPORT_SYMBOL vmlinux 0x4a94553e get_sb_single +EXPORT_SYMBOL vmlinux 0x4a9c4273 blk_queue_softirq_done +EXPORT_SYMBOL vmlinux 0x4aaa4b1d atm_dev_deregister +EXPORT_SYMBOL vmlinux 0x4acd93d3 release_resource +EXPORT_SYMBOL vmlinux 0x4ad5986d tcp_make_synack +EXPORT_SYMBOL vmlinux 0x4ae37fb7 thermal_zone_device_unregister +EXPORT_SYMBOL vmlinux 0x4aec9d60 rfkill_force_state +EXPORT_SYMBOL vmlinux 0x4afe9a77 scsi_partsize +EXPORT_SYMBOL vmlinux 0x4b07e779 _spin_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x4b085dbf agp3_generic_configure +EXPORT_SYMBOL vmlinux 0x4b1daa0b uart_register_driver +EXPORT_SYMBOL vmlinux 0x4b2f14b4 jiffies_to_timespec +EXPORT_SYMBOL vmlinux 0x4b3b0496 touch_atime +EXPORT_SYMBOL vmlinux 0x4b3e20cc kill_anon_super +EXPORT_SYMBOL vmlinux 0x4b697a82 kick_iocb +EXPORT_SYMBOL vmlinux 0x4b6acb52 pci_target_state +EXPORT_SYMBOL vmlinux 0x4b72e20d scsi_is_host_device +EXPORT_SYMBOL vmlinux 0x4b77c0d1 tcf_hash_insert +EXPORT_SYMBOL vmlinux 0x4b861460 blk_queue_dma_pad +EXPORT_SYMBOL vmlinux 0x4b91f272 sync_dirty_buffer +EXPORT_SYMBOL vmlinux 0x4b946f0a sk_reset_timer +EXPORT_SYMBOL vmlinux 0x4b947ee9 __bread +EXPORT_SYMBOL vmlinux 0x4b9dfa8e netif_device_attach +EXPORT_SYMBOL vmlinux 0x4ba5baa0 load_gs_index +EXPORT_SYMBOL vmlinux 0x4ba6d5ef vfs_quota_sync +EXPORT_SYMBOL vmlinux 0x4baf99fb __serio_register_port +EXPORT_SYMBOL vmlinux 0x4bbc3e5f pm_flags +EXPORT_SYMBOL vmlinux 0x4bbcb530 thermal_zone_device_register +EXPORT_SYMBOL vmlinux 0x4bdf028e idr_find +EXPORT_SYMBOL vmlinux 0x4bdf5fa0 dev_alloc_name +EXPORT_SYMBOL vmlinux 0x4c08c497 sockfd_lookup +EXPORT_SYMBOL vmlinux 0x4c1182cb bitmap_scnprintf +EXPORT_SYMBOL vmlinux 0x4c149667 dm_get_mapinfo +EXPORT_SYMBOL vmlinux 0x4c4c956e nla_memcmp +EXPORT_SYMBOL vmlinux 0x4c5bfaa2 inet_select_addr +EXPORT_SYMBOL vmlinux 0x4cbbd171 __bitmap_weight +EXPORT_SYMBOL vmlinux 0x4cede630 inet_stream_connect +EXPORT_SYMBOL vmlinux 0x4d0b5e7f kern_path +EXPORT_SYMBOL vmlinux 0x4d53dd31 mdiobus_unregister +EXPORT_SYMBOL vmlinux 0x4d561118 dm_table_event +EXPORT_SYMBOL vmlinux 0x4db1e1d4 posix_acl_equiv_mode +EXPORT_SYMBOL vmlinux 0x4dc53c79 proc_dointvec +EXPORT_SYMBOL vmlinux 0x4dda726b match_strlcpy +EXPORT_SYMBOL vmlinux 0x4ddc4b9f utf8_mbtowc +EXPORT_SYMBOL vmlinux 0x4df119fa __bitmap_parse +EXPORT_SYMBOL vmlinux 0x4df47e9f xfrm_state_flush +EXPORT_SYMBOL vmlinux 0x4e100f60 _spin_unlock_irq +EXPORT_SYMBOL vmlinux 0x4e18acf8 journal_create +EXPORT_SYMBOL vmlinux 0x4e273b39 scsi_is_sdev_device +EXPORT_SYMBOL vmlinux 0x4e3567f7 match_int +EXPORT_SYMBOL vmlinux 0x4e3d21a9 may_umount_tree +EXPORT_SYMBOL vmlinux 0x4e6e8ea7 fg_console +EXPORT_SYMBOL vmlinux 0x4e70455f starget_for_each_device +EXPORT_SYMBOL vmlinux 0x4e9fd62d mdio_bus_type +EXPORT_SYMBOL vmlinux 0x4eb8e005 neigh_sysctl_register +EXPORT_SYMBOL vmlinux 0x4ed71508 generic_file_aio_write_nolock +EXPORT_SYMBOL vmlinux 0x4edd72f7 block_all_signals +EXPORT_SYMBOL vmlinux 0x4ef970c6 vfs_path_lookup +EXPORT_SYMBOL vmlinux 0x4f096eb7 fd_install +EXPORT_SYMBOL vmlinux 0x4f212c7a jbd2_journal_start_commit +EXPORT_SYMBOL vmlinux 0x4f2933c5 sk_wait_data +EXPORT_SYMBOL vmlinux 0x4f3739e7 blk_queue_max_phys_segments +EXPORT_SYMBOL vmlinux 0x4f3874ce ip_setsockopt +EXPORT_SYMBOL vmlinux 0x4f476e96 init_cdrom_command +EXPORT_SYMBOL vmlinux 0x4f5438c1 idle_halt +EXPORT_SYMBOL vmlinux 0x4fa75270 inet_frags_fini +EXPORT_SYMBOL vmlinux 0x4fa9b1f2 pci_select_bars +EXPORT_SYMBOL vmlinux 0x4faebd58 mpage_writepages +EXPORT_SYMBOL vmlinux 0x4fafc99a blk_queue_hardsect_size +EXPORT_SYMBOL vmlinux 0x4fbc92da hci_register_proto +EXPORT_SYMBOL vmlinux 0x4fcee107 __up_read +EXPORT_SYMBOL vmlinux 0x4fdee897 i8042_command +EXPORT_SYMBOL vmlinux 0x4fea84e2 d_alloc_root +EXPORT_SYMBOL vmlinux 0x5008cfd0 blk_stop_queue +EXPORT_SYMBOL vmlinux 0x500fe15e mmc_remove_host +EXPORT_SYMBOL vmlinux 0x501b94c0 scsi_release_buffers +EXPORT_SYMBOL vmlinux 0x50211ee3 tcp_free_md5sig_pool +EXPORT_SYMBOL vmlinux 0x5072b6b8 create_proc_entry +EXPORT_SYMBOL vmlinux 0x50893d88 filemap_fdatawrite_range +EXPORT_SYMBOL vmlinux 0x50913357 xfrm_unregister_type +EXPORT_SYMBOL vmlinux 0x50918b64 __inode_dir_notify +EXPORT_SYMBOL vmlinux 0x50adf917 cdrom_mode_sense +EXPORT_SYMBOL vmlinux 0x50b5cb2d idr_get_new_above +EXPORT_SYMBOL vmlinux 0x50bfc890 xfrm_input +EXPORT_SYMBOL vmlinux 0x50cbc815 names_cachep +EXPORT_SYMBOL vmlinux 0x50eb1994 ioctl_by_bdev +EXPORT_SYMBOL vmlinux 0x51019583 dev_add_pack +EXPORT_SYMBOL vmlinux 0x5118c382 secure_dccp_sequence_number +EXPORT_SYMBOL vmlinux 0x51458dfb pnp_release_card_device +EXPORT_SYMBOL vmlinux 0x514ee97b inc_zone_page_state +EXPORT_SYMBOL vmlinux 0x51a2925e bd_set_size +EXPORT_SYMBOL vmlinux 0x51b25835 skb_unlink +EXPORT_SYMBOL vmlinux 0x51ceb99f prepare_binprm +EXPORT_SYMBOL vmlinux 0x51d12d4e acpi_pci_disabled +EXPORT_SYMBOL vmlinux 0x51d7a776 acpi_detach_data +EXPORT_SYMBOL vmlinux 0x51dce73b xfrm_state_walk_init +EXPORT_SYMBOL vmlinux 0x51fcc0aa i2c_master_recv +EXPORT_SYMBOL vmlinux 0x5200ceba scsi_host_set_state +EXPORT_SYMBOL vmlinux 0x52026cdf security_sb_parse_opts_str +EXPORT_SYMBOL vmlinux 0x521d63ec wait_for_key_construction +EXPORT_SYMBOL vmlinux 0x52293a12 input_unregister_device +EXPORT_SYMBOL vmlinux 0x522f5573 pv_irq_ops +EXPORT_SYMBOL vmlinux 0x523d9dea scsi_device_resume +EXPORT_SYMBOL vmlinux 0x5252f304 __memcpy_toio +EXPORT_SYMBOL vmlinux 0x525becd3 do_munmap +EXPORT_SYMBOL vmlinux 0x52645447 vcc_insert_socket +EXPORT_SYMBOL vmlinux 0x528562dc phy_ethtool_gset +EXPORT_SYMBOL vmlinux 0x5285fdff nla_append +EXPORT_SYMBOL vmlinux 0x529dabda devm_ioport_unmap +EXPORT_SYMBOL vmlinux 0x52a58c24 ifla_policy +EXPORT_SYMBOL vmlinux 0x52d7b2fd llc_sap_list +EXPORT_SYMBOL vmlinux 0x52e2627a i2c_smbus_read_block_data +EXPORT_SYMBOL vmlinux 0x52ff1e8c journal_restart +EXPORT_SYMBOL vmlinux 0x530b1e98 pm_suspend +EXPORT_SYMBOL vmlinux 0x531b604e __virt_addr_valid +EXPORT_SYMBOL vmlinux 0x532ea2b5 mdiobus_read +EXPORT_SYMBOL vmlinux 0x532f2924 param_get_byte +EXPORT_SYMBOL vmlinux 0x53326531 mempool_alloc_pages +EXPORT_SYMBOL vmlinux 0x538383c0 unregister_inet6addr_notifier +EXPORT_SYMBOL vmlinux 0x539d263f ps2_command +EXPORT_SYMBOL vmlinux 0x53bc3a8d __neigh_event_send +EXPORT_SYMBOL vmlinux 0x53c0767c sk_chk_filter +EXPORT_SYMBOL vmlinux 0x53cea7ca acpi_bus_unregister_driver +EXPORT_SYMBOL vmlinux 0x54113934 fb_firmware_edid +EXPORT_SYMBOL vmlinux 0x54128174 compat_ip_getsockopt +EXPORT_SYMBOL vmlinux 0x54290dc9 nla_validate +EXPORT_SYMBOL vmlinux 0x543affb5 per_cpu__kstat +EXPORT_SYMBOL vmlinux 0x5443b0da grab_cache_page_write_begin +EXPORT_SYMBOL vmlinux 0x547913a9 netif_rx_ni +EXPORT_SYMBOL vmlinux 0x548d56c3 rfkill_register +EXPORT_SYMBOL vmlinux 0x54913832 agp_generic_destroy_pages +EXPORT_SYMBOL vmlinux 0x5497842e mdiobus_alloc +EXPORT_SYMBOL vmlinux 0x54b81541 init_timer_deferrable +EXPORT_SYMBOL vmlinux 0x54e5e0ba tcp_sync_mss +EXPORT_SYMBOL vmlinux 0x54e6fcdd net_enable_timestamp +EXPORT_SYMBOL vmlinux 0x550f8ade groups_alloc +EXPORT_SYMBOL vmlinux 0x5513442d llc_set_station_handler +EXPORT_SYMBOL vmlinux 0x55205a27 inode_needs_sync +EXPORT_SYMBOL vmlinux 0x5534938c pcie_set_readrq +EXPORT_SYMBOL vmlinux 0x5594be03 bitmap_remap +EXPORT_SYMBOL vmlinux 0x559919da i2c_smbus_write_block_data +EXPORT_SYMBOL vmlinux 0x55b38a04 inet_csk_init_xmit_timers +EXPORT_SYMBOL vmlinux 0x55bd79ef xfrm4_rcv_encap +EXPORT_SYMBOL vmlinux 0x55f151fe cap_netlink_recv +EXPORT_SYMBOL vmlinux 0x5600904f fb_get_color_depth +EXPORT_SYMBOL vmlinux 0x56076f40 serial8250_register_port +EXPORT_SYMBOL vmlinux 0x5614b010 xfrm_policy_walk_done +EXPORT_SYMBOL vmlinux 0x5632bd12 xfrm_state_lookup +EXPORT_SYMBOL vmlinux 0x5635a60a vmalloc_user +EXPORT_SYMBOL vmlinux 0x56514f10 __wait_on_buffer +EXPORT_SYMBOL vmlinux 0x56828b6e dst_alloc +EXPORT_SYMBOL vmlinux 0x569100c0 read_cache_pages +EXPORT_SYMBOL vmlinux 0x5691c766 unregister_quota_format +EXPORT_SYMBOL vmlinux 0x56977d85 br_handle_frame_hook +EXPORT_SYMBOL vmlinux 0x56b4b5e1 llc_sap_open +EXPORT_SYMBOL vmlinux 0x56c8799d scsi_kunmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x56d92d3c tc_classify +EXPORT_SYMBOL vmlinux 0x56f2a90c thermal_zone_unbind_cooling_device +EXPORT_SYMBOL vmlinux 0x56f494e0 smp_call_function +EXPORT_SYMBOL vmlinux 0x56faf946 ppp_unregister_compressor +EXPORT_SYMBOL vmlinux 0x57072242 bt_accept_dequeue +EXPORT_SYMBOL vmlinux 0x5707a417 tcp_getsockopt +EXPORT_SYMBOL vmlinux 0x5717e9eb __inet6_lookup_established +EXPORT_SYMBOL vmlinux 0x572c3cd7 scsi_host_lookup +EXPORT_SYMBOL vmlinux 0x572e85d4 blk_lookup_devt +EXPORT_SYMBOL vmlinux 0x57383fcf no_llseek +EXPORT_SYMBOL vmlinux 0x574554cb clear_bdi_congested +EXPORT_SYMBOL vmlinux 0x576d55a8 i2c_clients_command +EXPORT_SYMBOL vmlinux 0x577cc638 mutex_unlock +EXPORT_SYMBOL vmlinux 0x57d5a8ea phy_stop +EXPORT_SYMBOL vmlinux 0x57dbf49a compat_sock_common_setsockopt +EXPORT_SYMBOL vmlinux 0x57f0a6a7 tcp_v4_do_rcv +EXPORT_SYMBOL vmlinux 0x5810f6f2 put_io_context +EXPORT_SYMBOL vmlinux 0x5838f6c9 rtc_valid_tm +EXPORT_SYMBOL vmlinux 0x583c43c0 sk_stream_write_space +EXPORT_SYMBOL vmlinux 0x584738f9 rdmsr_safe_on_cpu +EXPORT_SYMBOL vmlinux 0x5857b225 ioread16_rep +EXPORT_SYMBOL vmlinux 0x588ab303 pcie_port_service_unregister +EXPORT_SYMBOL vmlinux 0x589ddb05 submit_bh +EXPORT_SYMBOL vmlinux 0x58cf6528 alloc_fddidev +EXPORT_SYMBOL vmlinux 0x58f17ca9 framebuffer_alloc +EXPORT_SYMBOL vmlinux 0x58f4bed8 qdisc_reset +EXPORT_SYMBOL vmlinux 0x58f895d8 sock_no_poll +EXPORT_SYMBOL vmlinux 0x590ce35a blk_queue_max_hw_segments +EXPORT_SYMBOL vmlinux 0x5934392b fb_register_client +EXPORT_SYMBOL vmlinux 0x5938f506 misc_deregister +EXPORT_SYMBOL vmlinux 0x594bf15b ioport_map +EXPORT_SYMBOL vmlinux 0x59706f79 nf_log_unregister_pf +EXPORT_SYMBOL vmlinux 0x5984e4fd acpi_processor_register_performance +EXPORT_SYMBOL vmlinux 0x59a245c1 tcp_close +EXPORT_SYMBOL vmlinux 0x59a7fdf5 elv_rb_del +EXPORT_SYMBOL vmlinux 0x59d696b6 register_module_notifier +EXPORT_SYMBOL vmlinux 0x59d71c73 vlan_ioctl_set +EXPORT_SYMBOL vmlinux 0x5a1e9d72 ppp_input_error +EXPORT_SYMBOL vmlinux 0x5a34a45c __kmalloc +EXPORT_SYMBOL vmlinux 0x5a4896a8 __put_user_2 +EXPORT_SYMBOL vmlinux 0x5a5e7ea3 simple_read_from_buffer +EXPORT_SYMBOL vmlinux 0x5a5fc2b0 ilookup5 +EXPORT_SYMBOL vmlinux 0x5a69219f __up_write +EXPORT_SYMBOL vmlinux 0x5a744b86 netlink_set_nonroot +EXPORT_SYMBOL vmlinux 0x5a7d7045 pci_enable_msi +EXPORT_SYMBOL vmlinux 0x5ab5a456 inet_dev_addr_type +EXPORT_SYMBOL vmlinux 0x5ac376a5 acpi_install_fixed_event_handler +EXPORT_SYMBOL vmlinux 0x5aca96a8 agp_free_page_array +EXPORT_SYMBOL vmlinux 0x5b00783d unlock_buffer +EXPORT_SYMBOL vmlinux 0x5b087862 posix_unblock_lock +EXPORT_SYMBOL vmlinux 0x5b51c6a7 acpi_walk_resources +EXPORT_SYMBOL vmlinux 0x5bae2eac acpi_extract_package +EXPORT_SYMBOL vmlinux 0x5bec44cb __down_write +EXPORT_SYMBOL vmlinux 0x5c2775ab dm_kcopyd_copy +EXPORT_SYMBOL vmlinux 0x5c4631d5 hci_register_cb +EXPORT_SYMBOL vmlinux 0x5c46b6fa posix_acl_chmod_masq +EXPORT_SYMBOL vmlinux 0x5c709821 pcim_pin_device +EXPORT_SYMBOL vmlinux 0x5ca0000d schedule_delayed_work_on +EXPORT_SYMBOL vmlinux 0x5cae8e03 page_follow_link_light +EXPORT_SYMBOL vmlinux 0x5cc8e015 iov_iter_single_seg_count +EXPORT_SYMBOL vmlinux 0x5cce9095 inet_ioctl +EXPORT_SYMBOL vmlinux 0x5cfb632f dma_async_client_unregister +EXPORT_SYMBOL vmlinux 0x5d096bf1 __mpage_writepage +EXPORT_SYMBOL vmlinux 0x5d113035 vm_stat +EXPORT_SYMBOL vmlinux 0x5d73b5f8 km_waitq +EXPORT_SYMBOL vmlinux 0x5d959196 register_atm_ioctl +EXPORT_SYMBOL vmlinux 0x5d982b15 inet6_register_protosw +EXPORT_SYMBOL vmlinux 0x5db8a9df pagecache_write_begin +EXPORT_SYMBOL vmlinux 0x5dbcfa4f boot_cpu_physical_apicid +EXPORT_SYMBOL vmlinux 0x5dfff93f open_by_devnum +EXPORT_SYMBOL vmlinux 0x5e177a0d filemap_fdatawrite +EXPORT_SYMBOL vmlinux 0x5e2fa18a bio_init +EXPORT_SYMBOL vmlinux 0x5e35dbc7 pci_disable_msi +EXPORT_SYMBOL vmlinux 0x5e3a178c vmalloc_to_page +EXPORT_SYMBOL vmlinux 0x5e3f29bc con_copy_unimap +EXPORT_SYMBOL vmlinux 0x5e4e27aa eth_header_cache +EXPORT_SYMBOL vmlinux 0x5e79ebec gen_replace_estimator +EXPORT_SYMBOL vmlinux 0x5e9f09df get_io_context +EXPORT_SYMBOL vmlinux 0x5e9f4d20 cont_write_begin +EXPORT_SYMBOL vmlinux 0x5ea520c5 tcp_select_initial_window +EXPORT_SYMBOL vmlinux 0x5ed040b0 pm_set_vt_switch +EXPORT_SYMBOL vmlinux 0x5edd0762 bin2bcd +EXPORT_SYMBOL vmlinux 0x5f125ff1 get_user_pages +EXPORT_SYMBOL vmlinux 0x5f2ab215 sget +EXPORT_SYMBOL vmlinux 0x5f5d3857 blk_rq_count_integrity_sg +EXPORT_SYMBOL vmlinux 0x5f80c434 lock_may_read +EXPORT_SYMBOL vmlinux 0x5fa70ddf nf_ct_attach +EXPORT_SYMBOL vmlinux 0x5faeca90 unmap_mapping_range +EXPORT_SYMBOL vmlinux 0x5fb55341 __free_pages +EXPORT_SYMBOL vmlinux 0x5fe99421 elv_add_request +EXPORT_SYMBOL vmlinux 0x5ff42b08 acpi_video_get_capabilities +EXPORT_SYMBOL vmlinux 0x5ffdef84 __breadahead +EXPORT_SYMBOL vmlinux 0x600683d3 do_unblank_screen +EXPORT_SYMBOL vmlinux 0x600743be journal_get_undo_access +EXPORT_SYMBOL vmlinux 0x6049ea1f shrink_dcache_sb +EXPORT_SYMBOL vmlinux 0x605c8954 sock_i_ino +EXPORT_SYMBOL vmlinux 0x605c8bde radix_tree_delete +EXPORT_SYMBOL vmlinux 0x605cdc41 journal_errno +EXPORT_SYMBOL vmlinux 0x6061957d in6_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0x607d9ec1 register_exec_domain +EXPORT_SYMBOL vmlinux 0x608ac795 ppp_unit_number +EXPORT_SYMBOL vmlinux 0x608c2831 warn_on_slowpath +EXPORT_SYMBOL vmlinux 0x609f1c7e synchronize_net +EXPORT_SYMBOL vmlinux 0x60a32ea9 pm_power_off +EXPORT_SYMBOL vmlinux 0x60b242d6 xfrm6_prepare_output +EXPORT_SYMBOL vmlinux 0x60ccc549 inet_dgram_ops +EXPORT_SYMBOL vmlinux 0x60eacf77 scsi_execute +EXPORT_SYMBOL vmlinux 0x60ec7101 dev_queue_xmit +EXPORT_SYMBOL vmlinux 0x6111e1bc init_timer +EXPORT_SYMBOL vmlinux 0x612390ad netpoll_set_trap +EXPORT_SYMBOL vmlinux 0x6148f0c0 __netdev_alloc_skb +EXPORT_SYMBOL vmlinux 0x6157c9e3 scsi_add_device +EXPORT_SYMBOL vmlinux 0x6159c44d request_key_async +EXPORT_SYMBOL vmlinux 0x618d8299 set_notify_swap_entry_free +EXPORT_SYMBOL vmlinux 0x61b7b126 simple_strtoull +EXPORT_SYMBOL vmlinux 0x61c1c365 unregister_key_type +EXPORT_SYMBOL vmlinux 0x61e948f1 audit_log_start +EXPORT_SYMBOL vmlinux 0x62019176 acpi_match_device_ids +EXPORT_SYMBOL vmlinux 0x62049256 acpi_disable +EXPORT_SYMBOL vmlinux 0x6218142a elv_queue_empty +EXPORT_SYMBOL vmlinux 0x6237f6b5 acpi_enable_event +EXPORT_SYMBOL vmlinux 0x62602f5a tty_port_alloc_xmit_buf +EXPORT_SYMBOL vmlinux 0x62737e1d sock_unregister +EXPORT_SYMBOL vmlinux 0x62748e70 acpi_set_current_resources +EXPORT_SYMBOL vmlinux 0x62827bec security_secctx_to_secid +EXPORT_SYMBOL vmlinux 0x629540f8 hci_conn_encrypt +EXPORT_SYMBOL vmlinux 0x62c53f85 bio_copy_user +EXPORT_SYMBOL vmlinux 0x62ce7313 blk_alloc_queue_node +EXPORT_SYMBOL vmlinux 0x62e5a5ab d_instantiate_unique +EXPORT_SYMBOL vmlinux 0x635426fd bio_integrity_add_page +EXPORT_SYMBOL vmlinux 0x636a5691 acpi_register_ioapic +EXPORT_SYMBOL vmlinux 0x636d2945 nf_log_unregister +EXPORT_SYMBOL vmlinux 0x6371f7b5 inet_put_port +EXPORT_SYMBOL vmlinux 0x63a31199 blk_queue_max_sectors +EXPORT_SYMBOL vmlinux 0x63b60516 dm_io +EXPORT_SYMBOL vmlinux 0x63db67fc kobject_set_name +EXPORT_SYMBOL vmlinux 0x63ecad53 register_netdevice_notifier +EXPORT_SYMBOL vmlinux 0x63f1d58f request_key_async_with_auxdata +EXPORT_SYMBOL vmlinux 0x63fc232f strlen_user +EXPORT_SYMBOL vmlinux 0x6403e338 tcp_memory_pressure +EXPORT_SYMBOL vmlinux 0x641b1bd3 scsi_dma_map +EXPORT_SYMBOL vmlinux 0x642e54ac __wake_up +EXPORT_SYMBOL vmlinux 0x6451294b posix_acl_valid +EXPORT_SYMBOL vmlinux 0x6466a1e6 mempool_alloc +EXPORT_SYMBOL vmlinux 0x6478134c ec_burst_enable +EXPORT_SYMBOL vmlinux 0x6485ca36 pci_set_dma_mask +EXPORT_SYMBOL vmlinux 0x6488aab0 unregister_md_personality +EXPORT_SYMBOL vmlinux 0x64999478 congestion_wait +EXPORT_SYMBOL vmlinux 0x649d136a elv_rb_find +EXPORT_SYMBOL vmlinux 0x64cd5d16 init_waitqueue_head +EXPORT_SYMBOL vmlinux 0x64d6ec86 vfs_quota_on_path +EXPORT_SYMBOL vmlinux 0x64eae7ad set_memory_array_wb +EXPORT_SYMBOL vmlinux 0x65002a14 scsicam_bios_param +EXPORT_SYMBOL vmlinux 0x650128e7 br_fdb_get_hook +EXPORT_SYMBOL vmlinux 0x650fb346 add_wait_queue +EXPORT_SYMBOL vmlinux 0x651a4139 test_taint +EXPORT_SYMBOL vmlinux 0x65408378 zlib_inflate_blob +EXPORT_SYMBOL vmlinux 0x65414e67 dev_valid_name +EXPORT_SYMBOL vmlinux 0x659611d7 rtnl_set_sk_err +EXPORT_SYMBOL vmlinux 0x65b862ba sk_filter +EXPORT_SYMBOL vmlinux 0x65de574f ethtool_op_set_flags +EXPORT_SYMBOL vmlinux 0x65f205dd jbd2_journal_create +EXPORT_SYMBOL vmlinux 0x65f873a3 scsi_print_result +EXPORT_SYMBOL vmlinux 0x66373df5 uart_get_baud_rate +EXPORT_SYMBOL vmlinux 0x666c233a iw_handler_set_thrspy +EXPORT_SYMBOL vmlinux 0x668da8d5 zlib_inflateIncomp +EXPORT_SYMBOL vmlinux 0x66b7b5a0 fget +EXPORT_SYMBOL vmlinux 0x672144bd strlcpy +EXPORT_SYMBOL vmlinux 0x6725f99e bt_accept_enqueue +EXPORT_SYMBOL vmlinux 0x6729d3df __get_user_4 +EXPORT_SYMBOL vmlinux 0x673f815e agp_bridges +EXPORT_SYMBOL vmlinux 0x6774180c jbd2_journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0x678ed706 tcf_exts_validate +EXPORT_SYMBOL vmlinux 0x67b27ec1 tty_std_termios +EXPORT_SYMBOL vmlinux 0x67be8276 xfrm_state_delete +EXPORT_SYMBOL vmlinux 0x67c69713 agp_generic_free_gatt_table +EXPORT_SYMBOL vmlinux 0x67dfe977 block_sync_page +EXPORT_SYMBOL vmlinux 0x67e71b77 __mutex_init +EXPORT_SYMBOL vmlinux 0x67f4bc17 __xfrm_decode_session +EXPORT_SYMBOL vmlinux 0x680bed94 netlink_unicast +EXPORT_SYMBOL vmlinux 0x68257c4c swiotlb_map_sg_attrs +EXPORT_SYMBOL vmlinux 0x6862a8c0 pci_reenable_device +EXPORT_SYMBOL vmlinux 0x687346ec __xfrm_state_destroy +EXPORT_SYMBOL vmlinux 0x688f0af4 _cpu_pda +EXPORT_SYMBOL vmlinux 0x68a1d5b9 scsi_dma_unmap +EXPORT_SYMBOL vmlinux 0x68c2b39c dma_async_memcpy_buf_to_pg +EXPORT_SYMBOL vmlinux 0x68c52436 dev_get_by_name +EXPORT_SYMBOL vmlinux 0x6907d4e9 idr_for_each +EXPORT_SYMBOL vmlinux 0x690f11f8 ether_setup +EXPORT_SYMBOL vmlinux 0x691445ec skb_recycle_check +EXPORT_SYMBOL vmlinux 0x69271cb8 tty_port_tty_set +EXPORT_SYMBOL vmlinux 0x692cfb18 dev_getbyhwaddr +EXPORT_SYMBOL vmlinux 0x693570a3 km_query +EXPORT_SYMBOL vmlinux 0x693971ad tcp_v4_send_check +EXPORT_SYMBOL vmlinux 0x693dc7c8 boot_cpu_data +EXPORT_SYMBOL vmlinux 0x6957defb find_vma +EXPORT_SYMBOL vmlinux 0x695df447 hci_conn_check_link_mode +EXPORT_SYMBOL vmlinux 0x6971447a rtc_month_days +EXPORT_SYMBOL vmlinux 0x69757b10 simple_transaction_release +EXPORT_SYMBOL vmlinux 0x69927dff try_acquire_console_sem +EXPORT_SYMBOL vmlinux 0x699859f7 input_unregister_handler +EXPORT_SYMBOL vmlinux 0x69a0ca7d iowrite16be +EXPORT_SYMBOL vmlinux 0x69a358a6 iomem_resource +EXPORT_SYMBOL vmlinux 0x69b91767 do_sync_read +EXPORT_SYMBOL vmlinux 0x69bfc5e3 lock_may_write +EXPORT_SYMBOL vmlinux 0x69c8c1d5 security_req_classify_flow +EXPORT_SYMBOL vmlinux 0x69d2575f efi +EXPORT_SYMBOL vmlinux 0x69d38ed9 __scsi_print_sense +EXPORT_SYMBOL vmlinux 0x69d52d57 agp_generic_remove_memory +EXPORT_SYMBOL vmlinux 0x69e27c7a bitmap_copy_le +EXPORT_SYMBOL vmlinux 0x69f39cde blk_queue_prep_rq +EXPORT_SYMBOL vmlinux 0x6a037cf1 mempool_kfree +EXPORT_SYMBOL vmlinux 0x6a47571d __set_personality +EXPORT_SYMBOL vmlinux 0x6a5f98a0 ida_get_new_above +EXPORT_SYMBOL vmlinux 0x6a5fa363 sigprocmask +EXPORT_SYMBOL vmlinux 0x6a87ea76 pci_bus_add_devices +EXPORT_SYMBOL vmlinux 0x6acb973d iowrite32be +EXPORT_SYMBOL vmlinux 0x6ad85887 acpi_enable_gpe +EXPORT_SYMBOL vmlinux 0x6add5c9a dmi_find_device +EXPORT_SYMBOL vmlinux 0x6addb1fe pci_bus_type +EXPORT_SYMBOL vmlinux 0x6af9b725 hci_recv_fragment +EXPORT_SYMBOL vmlinux 0x6b1b67d3 __bdevname +EXPORT_SYMBOL vmlinux 0x6b2dc060 dump_stack +EXPORT_SYMBOL vmlinux 0x6b304413 bio_integrity_prep +EXPORT_SYMBOL vmlinux 0x6b4e5a52 radix_tree_lookup_slot +EXPORT_SYMBOL vmlinux 0x6b9b88f3 sleep_on +EXPORT_SYMBOL vmlinux 0x6ba2a6d8 nlmsg_notify +EXPORT_SYMBOL vmlinux 0x6bafbced mod_timer +EXPORT_SYMBOL vmlinux 0x6bc56c67 radix_tree_next_hole +EXPORT_SYMBOL vmlinux 0x6bd83313 generic_getxattr +EXPORT_SYMBOL vmlinux 0x6bdcfd99 qdisc_class_hash_remove +EXPORT_SYMBOL vmlinux 0x6bf997f7 pci_enable_device_mem +EXPORT_SYMBOL vmlinux 0x6c2c0141 dquot_free_inode +EXPORT_SYMBOL vmlinux 0x6c389761 acpi_bus_get_private_data +EXPORT_SYMBOL vmlinux 0x6c3af89b hci_suspend_dev +EXPORT_SYMBOL vmlinux 0x6c5e0743 alloc_trdev +EXPORT_SYMBOL vmlinux 0x6c61ce70 num_registered_fb +EXPORT_SYMBOL vmlinux 0x6c702af7 sysctl_udp_rmem_min +EXPORT_SYMBOL vmlinux 0x6ca24339 find_lock_page +EXPORT_SYMBOL vmlinux 0x6cbe7632 posix_acl_to_xattr +EXPORT_SYMBOL vmlinux 0x6d07560f vc_cons +EXPORT_SYMBOL vmlinux 0x6d0da34c param_get_short +EXPORT_SYMBOL vmlinux 0x6d185df4 simple_set_mnt +EXPORT_SYMBOL vmlinux 0x6d1ced27 vcc_sklist_lock +EXPORT_SYMBOL vmlinux 0x6d205e2e bdget +EXPORT_SYMBOL vmlinux 0x6d27ef64 __bitmap_empty +EXPORT_SYMBOL vmlinux 0x6d294e43 clock_t_to_jiffies +EXPORT_SYMBOL vmlinux 0x6d334118 __get_user_8 +EXPORT_SYMBOL vmlinux 0x6d340f64 tty_termios_input_baud_rate +EXPORT_SYMBOL vmlinux 0x6d375299 netdev_class_create_file +EXPORT_SYMBOL vmlinux 0x6d429195 inet6_getname +EXPORT_SYMBOL vmlinux 0x6d44931d jbd2_journal_set_features +EXPORT_SYMBOL vmlinux 0x6d47d90d groups_free +EXPORT_SYMBOL vmlinux 0x6d80c3d5 kernel_sock_ioctl +EXPORT_SYMBOL vmlinux 0x6d9192f6 locks_mandatory_area +EXPORT_SYMBOL vmlinux 0x6d992637 skb_append_datato_frags +EXPORT_SYMBOL vmlinux 0x6dc0c24b complete_and_exit +EXPORT_SYMBOL vmlinux 0x6de6bf83 radix_tree_lookup +EXPORT_SYMBOL vmlinux 0x6def26b4 tty_port_free_xmit_buf +EXPORT_SYMBOL vmlinux 0x6def2db2 half_md4_transform +EXPORT_SYMBOL vmlinux 0x6df789b9 iput +EXPORT_SYMBOL vmlinux 0x6e07a54e acpi_get_gpe_status +EXPORT_SYMBOL vmlinux 0x6e1a4bbb udp_hash_lock +EXPORT_SYMBOL vmlinux 0x6e37e6e9 filemap_fault +EXPORT_SYMBOL vmlinux 0x6e720ff2 rtnl_unlock +EXPORT_SYMBOL vmlinux 0x6e8bf9e2 i2c_smbus_process_call +EXPORT_SYMBOL vmlinux 0x6e90beeb tcp_create_openreq_child +EXPORT_SYMBOL vmlinux 0x6e9c1d39 simple_statfs +EXPORT_SYMBOL vmlinux 0x6e9dd606 __symbol_put +EXPORT_SYMBOL vmlinux 0x6ead242b cond_resched_lock +EXPORT_SYMBOL vmlinux 0x6ef44eba audit_log_end +EXPORT_SYMBOL vmlinux 0x6f1c5c0f register_netdevice +EXPORT_SYMBOL vmlinux 0x6f24d2f1 generic_cont_expand_simple +EXPORT_SYMBOL vmlinux 0x6f277045 phy_register_fixup_for_uid +EXPORT_SYMBOL vmlinux 0x6f41e66b pci_find_bus +EXPORT_SYMBOL vmlinux 0x6f63083f inetdev_by_index +EXPORT_SYMBOL vmlinux 0x6f7145f1 start_tty +EXPORT_SYMBOL vmlinux 0x6fa61eb8 blk_queue_set_discard +EXPORT_SYMBOL vmlinux 0x6fafa502 blk_rq_unmap_user +EXPORT_SYMBOL vmlinux 0x6fb8a0a9 simple_release_fs +EXPORT_SYMBOL vmlinux 0x6fca8d78 page_symlink_inode_operations +EXPORT_SYMBOL vmlinux 0x6fcb87a1 touch_softlockup_watchdog +EXPORT_SYMBOL vmlinux 0x6fd0000d qdisc_watchdog_init +EXPORT_SYMBOL vmlinux 0x6fd0e144 neigh_connected_output +EXPORT_SYMBOL vmlinux 0x7008a9b7 timespec_to_jiffies +EXPORT_SYMBOL vmlinux 0x7009c81a block_page_mkwrite +EXPORT_SYMBOL vmlinux 0x7016a046 kernel_getsockopt +EXPORT_SYMBOL vmlinux 0x70296335 tcp_child_process +EXPORT_SYMBOL vmlinux 0x702ff8e7 pnp_register_driver +EXPORT_SYMBOL vmlinux 0x7041e67a compat_sock_common_getsockopt +EXPORT_SYMBOL vmlinux 0x70538c79 textsearch_find_continuous +EXPORT_SYMBOL vmlinux 0x7054a3e4 request_dma +EXPORT_SYMBOL vmlinux 0x7094f8ae bt_err +EXPORT_SYMBOL vmlinux 0x70a253e1 bdevname +EXPORT_SYMBOL vmlinux 0x70a3bba0 vfs_mkdir +EXPORT_SYMBOL vmlinux 0x70bcb65e generic_readlink +EXPORT_SYMBOL vmlinux 0x70d8ab82 acpi_acquire_global_lock +EXPORT_SYMBOL vmlinux 0x70e0d61f cpu_all_bits +EXPORT_SYMBOL vmlinux 0x70f99f75 sock_no_bind +EXPORT_SYMBOL vmlinux 0x7101267c pci_set_dma_max_seg_size +EXPORT_SYMBOL vmlinux 0x711da2e9 bio_integrity_set_tag +EXPORT_SYMBOL vmlinux 0x71225de1 kmem_cache_create +EXPORT_SYMBOL vmlinux 0x7128abae get_agp_version +EXPORT_SYMBOL vmlinux 0x7129e5f8 hex_asc +EXPORT_SYMBOL vmlinux 0x712aa29b _spin_lock_irqsave +EXPORT_SYMBOL vmlinux 0x71356fba remove_wait_queue +EXPORT_SYMBOL vmlinux 0x716079a3 phy_start_aneg +EXPORT_SYMBOL vmlinux 0x7171121c overflowgid +EXPORT_SYMBOL vmlinux 0x7181cec5 tcp_sendmsg +EXPORT_SYMBOL vmlinux 0x7191a0d9 path_put +EXPORT_SYMBOL vmlinux 0x7195e42b pci_release_selected_regions +EXPORT_SYMBOL vmlinux 0x7196ae7e netlink_kernel_release +EXPORT_SYMBOL vmlinux 0x719faee7 free_netdev +EXPORT_SYMBOL vmlinux 0x71a50dbc register_blkdev +EXPORT_SYMBOL vmlinux 0x71a77529 sysctl_ms_jiffies +EXPORT_SYMBOL vmlinux 0x71c45fa8 seq_lseek +EXPORT_SYMBOL vmlinux 0x71c6cd8b init_net +EXPORT_SYMBOL vmlinux 0x71e74e33 d_delete +EXPORT_SYMBOL vmlinux 0x71f6eb38 sg_copy_from_buffer +EXPORT_SYMBOL vmlinux 0x71f7c5ef swiotlb_alloc_coherent +EXPORT_SYMBOL vmlinux 0x7223a6d7 get_write_access +EXPORT_SYMBOL vmlinux 0x7226644b scm_detach_fds +EXPORT_SYMBOL vmlinux 0x72270e35 do_gettimeofday +EXPORT_SYMBOL vmlinux 0x7242e96d strnchr +EXPORT_SYMBOL vmlinux 0x725068d8 truncate_inode_pages +EXPORT_SYMBOL vmlinux 0x725dc6df clocksource_register +EXPORT_SYMBOL vmlinux 0x7270d32d journal_forget +EXPORT_SYMBOL vmlinux 0x7277c6f7 netdev_class_remove_file +EXPORT_SYMBOL vmlinux 0x729fd68f tcf_unregister_action +EXPORT_SYMBOL vmlinux 0x72a97404 directly_mappable_cdev_bdi +EXPORT_SYMBOL vmlinux 0x72abd4d0 pci_do_scan_bus +EXPORT_SYMBOL vmlinux 0x72b243d4 free_dma +EXPORT_SYMBOL vmlinux 0x72bf2140 mtrr_add +EXPORT_SYMBOL vmlinux 0x72ea7b2d scsi_device_type +EXPORT_SYMBOL vmlinux 0x730de4af bdi_init +EXPORT_SYMBOL vmlinux 0x735a0bd5 native_io_delay +EXPORT_SYMBOL vmlinux 0x736bde60 cpufreq_get_policy +EXPORT_SYMBOL vmlinux 0x7389c9a8 acpi_bus_get_power +EXPORT_SYMBOL vmlinux 0x739ee22d gen_pool_add +EXPORT_SYMBOL vmlinux 0x73c174aa bio_uncopy_user +EXPORT_SYMBOL vmlinux 0x73c8390f acpi_unlock_battery_dir +EXPORT_SYMBOL vmlinux 0x7408e1d5 __elv_add_request +EXPORT_SYMBOL vmlinux 0x740a1b95 reserve_evntsel_nmi +EXPORT_SYMBOL vmlinux 0x7415fdc1 uart_remove_one_port +EXPORT_SYMBOL vmlinux 0x74162316 filemap_fdatawait +EXPORT_SYMBOL vmlinux 0x742c4215 register_con_driver +EXPORT_SYMBOL vmlinux 0x74399384 sock_wfree +EXPORT_SYMBOL vmlinux 0x744a7003 hippi_type_trans +EXPORT_SYMBOL vmlinux 0x746a1463 pci_try_set_mwi +EXPORT_SYMBOL vmlinux 0x747ad76c try_to_release_page +EXPORT_SYMBOL vmlinux 0x748162fb pci_setup_cardbus +EXPORT_SYMBOL vmlinux 0x74855e39 scsi_test_unit_ready +EXPORT_SYMBOL vmlinux 0x7485e15e unregister_chrdev_region +EXPORT_SYMBOL vmlinux 0x748caf40 down +EXPORT_SYMBOL vmlinux 0x74946de1 pci_set_consistent_dma_mask +EXPORT_SYMBOL vmlinux 0x74af0c65 unregister_snap_client +EXPORT_SYMBOL vmlinux 0x74bfdb28 phy_sanitize_settings +EXPORT_SYMBOL vmlinux 0x74cc1cbe unregister_cpu_notifier +EXPORT_SYMBOL vmlinux 0x74cc238d current_kernel_time +EXPORT_SYMBOL vmlinux 0x7523ba84 blk_queue_free_tags +EXPORT_SYMBOL vmlinux 0x752a5d25 blk_queue_make_request +EXPORT_SYMBOL vmlinux 0x7538b132 agp_off +EXPORT_SYMBOL vmlinux 0x7567e205 pv_cpu_ops +EXPORT_SYMBOL vmlinux 0x756e6992 strnicmp +EXPORT_SYMBOL vmlinux 0x7578cf96 rfkill_unregister +EXPORT_SYMBOL vmlinux 0x757df1f4 genphy_update_link +EXPORT_SYMBOL vmlinux 0x75a8bba1 ethtool_op_set_tso +EXPORT_SYMBOL vmlinux 0x75bdea12 iommu_area_alloc +EXPORT_SYMBOL vmlinux 0x75d6cb2b mmc_free_host +EXPORT_SYMBOL vmlinux 0x75dc9096 fb_set_cmap +EXPORT_SYMBOL vmlinux 0x75e4716f bio_split +EXPORT_SYMBOL vmlinux 0x75ea9531 key_negate_and_link +EXPORT_SYMBOL vmlinux 0x7600c416 generic_ro_fops +EXPORT_SYMBOL vmlinux 0x760a0f4f yield +EXPORT_SYMBOL vmlinux 0x760b437a unregister_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x760be277 ppp_unregister_channel +EXPORT_SYMBOL vmlinux 0x761668a8 i2c_smbus_xfer +EXPORT_SYMBOL vmlinux 0x7620d6b0 dquot_release +EXPORT_SYMBOL vmlinux 0x762affe9 blk_queue_update_dma_alignment +EXPORT_SYMBOL vmlinux 0x76350f6d blk_plug_device_unlocked +EXPORT_SYMBOL vmlinux 0x763ca220 pci_unregister_driver +EXPORT_SYMBOL vmlinux 0x764b38b2 compat_sock_get_timestampns +EXPORT_SYMBOL vmlinux 0x764bd77c request_resource +EXPORT_SYMBOL vmlinux 0x767293ab unlock_new_inode +EXPORT_SYMBOL vmlinux 0x767dd8fd acpi_get_irq_routing_table +EXPORT_SYMBOL vmlinux 0x767ddb02 set_memory_wc +EXPORT_SYMBOL vmlinux 0x76a09b21 inet_csk_accept +EXPORT_SYMBOL vmlinux 0x76bf656d __bitmap_shift_left +EXPORT_SYMBOL vmlinux 0x76d3cd60 laptop_mode +EXPORT_SYMBOL vmlinux 0x76d8a747 mpage_writepage +EXPORT_SYMBOL vmlinux 0x76eb1342 nobh_truncate_page +EXPORT_SYMBOL vmlinux 0x76f3f8a5 num_k8_northbridges +EXPORT_SYMBOL vmlinux 0x76faa91c agp_backend_acquire +EXPORT_SYMBOL vmlinux 0x771543e8 vfs_permission +EXPORT_SYMBOL vmlinux 0x77161035 init_buffer +EXPORT_SYMBOL vmlinux 0x77324e4b pnp_possible_config +EXPORT_SYMBOL vmlinux 0x7746aad1 sock_queue_rcv_skb +EXPORT_SYMBOL vmlinux 0x77489bd3 register_key_type +EXPORT_SYMBOL vmlinux 0x7751fff2 tcp_v4_md5_do_del +EXPORT_SYMBOL vmlinux 0x775481f1 scsi_free_host_dev +EXPORT_SYMBOL vmlinux 0x77557899 mmc_resume_host +EXPORT_SYMBOL vmlinux 0x7760dd18 nf_hook_slow +EXPORT_SYMBOL vmlinux 0x77624973 scsi_is_target_device +EXPORT_SYMBOL vmlinux 0x77664aee dma_async_tx_descriptor_init +EXPORT_SYMBOL vmlinux 0x776afed0 secpath_dup +EXPORT_SYMBOL vmlinux 0x7772220d rfkill_switch_all +EXPORT_SYMBOL vmlinux 0x778d3a1b vm_insert_pfn +EXPORT_SYMBOL vmlinux 0x77990a15 __nla_reserve +EXPORT_SYMBOL vmlinux 0x77a108df _write_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x77b6de43 blk_queue_dma_alignment +EXPORT_SYMBOL vmlinux 0x77b848b1 agp_free_memory +EXPORT_SYMBOL vmlinux 0x77bb88d2 nf_reinject +EXPORT_SYMBOL vmlinux 0x77d27770 bitmap_unplug +EXPORT_SYMBOL vmlinux 0x77ecac9f zlib_inflateEnd +EXPORT_SYMBOL vmlinux 0x77f53abc acpi_get_vendor_resource +EXPORT_SYMBOL vmlinux 0x782acba5 crc_t10dif +EXPORT_SYMBOL vmlinux 0x784041d7 inet_proto_csum_replace4 +EXPORT_SYMBOL vmlinux 0x784ed2fc handle_sysrq +EXPORT_SYMBOL vmlinux 0x785148a3 idr_destroy +EXPORT_SYMBOL vmlinux 0x788b5de9 blk_queue_ordered +EXPORT_SYMBOL vmlinux 0x78a484c9 _read_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x78df6bd7 no_pci_devices +EXPORT_SYMBOL vmlinux 0x78ea0b21 mmc_release_host +EXPORT_SYMBOL vmlinux 0x791a928c lookup_bdev +EXPORT_SYMBOL vmlinux 0x79230c86 generic_osync_inode +EXPORT_SYMBOL vmlinux 0x793b367f __sk_mem_schedule +EXPORT_SYMBOL vmlinux 0x794a6aef fb_blank +EXPORT_SYMBOL vmlinux 0x795392ba ethtool_op_set_tx_hw_csum +EXPORT_SYMBOL vmlinux 0x796fc5ce scsi_get_sense_info_fld +EXPORT_SYMBOL vmlinux 0x79aa04a2 get_random_bytes +EXPORT_SYMBOL vmlinux 0x79d8fbaa pnp_unregister_driver +EXPORT_SYMBOL vmlinux 0x7a01c274 devm_request_irq +EXPORT_SYMBOL vmlinux 0x7a2a837d strict_strtol +EXPORT_SYMBOL vmlinux 0x7a2e6a10 remove_inode_hash +EXPORT_SYMBOL vmlinux 0x7a40f215 scsi_ioctl +EXPORT_SYMBOL vmlinux 0x7a5ba15d vc_resize +EXPORT_SYMBOL vmlinux 0x7a6d1ba9 serio_reconnect +EXPORT_SYMBOL vmlinux 0x7a79107e pci_remove_bus_device +EXPORT_SYMBOL vmlinux 0x7a81bfc5 scsi_rescan_device +EXPORT_SYMBOL vmlinux 0x7a848702 _read_lock_irqsave +EXPORT_SYMBOL vmlinux 0x7a9877e5 register_sysrq_key +EXPORT_SYMBOL vmlinux 0x7ac959be pci_bus_alloc_resource +EXPORT_SYMBOL vmlinux 0x7ae73de1 alloc_pages_exact +EXPORT_SYMBOL vmlinux 0x7aec9089 clear_user +EXPORT_SYMBOL vmlinux 0x7b0c84c4 acpi_remove_table_handler +EXPORT_SYMBOL vmlinux 0x7b164761 xfrm_state_delete_tunnel +EXPORT_SYMBOL vmlinux 0x7b21ef9c hci_unregister_proto +EXPORT_SYMBOL vmlinux 0x7b453860 acpi_lock_battery_dir +EXPORT_SYMBOL vmlinux 0x7b4bdaac dcache_readdir +EXPORT_SYMBOL vmlinux 0x7b52a859 wrmsr_safe_on_cpu +EXPORT_SYMBOL vmlinux 0x7b5a6591 invalidate_inodes +EXPORT_SYMBOL vmlinux 0x7b8f4c40 key_create_or_update +EXPORT_SYMBOL vmlinux 0x7bc5ca03 acpi_processor_unregister_performance +EXPORT_SYMBOL vmlinux 0x7bff3be7 iov_iter_advance +EXPORT_SYMBOL vmlinux 0x7c46233a cpufreq_quick_get +EXPORT_SYMBOL vmlinux 0x7c469032 blk_run_queue +EXPORT_SYMBOL vmlinux 0x7c475db7 per_cpu__cpu_info +EXPORT_SYMBOL vmlinux 0x7c60d66e getname +EXPORT_SYMBOL vmlinux 0x7c61340c __release_region +EXPORT_SYMBOL vmlinux 0x7c7f1654 simple_transaction_get +EXPORT_SYMBOL vmlinux 0x7c904ded unregister_module_notifier +EXPORT_SYMBOL vmlinux 0x7c9a4dc8 key_alloc +EXPORT_SYMBOL vmlinux 0x7caf41cc block_read_full_page +EXPORT_SYMBOL vmlinux 0x7cb1ae69 cpu_down +EXPORT_SYMBOL vmlinux 0x7cb6b303 iw_handler_get_spy +EXPORT_SYMBOL vmlinux 0x7cbcfc30 netpoll_cleanup +EXPORT_SYMBOL vmlinux 0x7cdcee68 __rta_fill +EXPORT_SYMBOL vmlinux 0x7d01f731 sock_no_getsockopt +EXPORT_SYMBOL vmlinux 0x7d047e7e acpi_ut_exception +EXPORT_SYMBOL vmlinux 0x7d05b15c dev_close +EXPORT_SYMBOL vmlinux 0x7d08bc11 mdiobus_scan +EXPORT_SYMBOL vmlinux 0x7d11c268 jiffies +EXPORT_SYMBOL vmlinux 0x7d12f9fa __find_get_block +EXPORT_SYMBOL vmlinux 0x7d3d33d9 pci_bus_write_config_word +EXPORT_SYMBOL vmlinux 0x7d850612 utf8_mbstowcs +EXPORT_SYMBOL vmlinux 0x7d8b87df kthread_stop +EXPORT_SYMBOL vmlinux 0x7d8cce21 fib_default_rule_add +EXPORT_SYMBOL vmlinux 0x7d94f746 acpi_os_write_port +EXPORT_SYMBOL vmlinux 0x7d9dc765 invalidate_mapping_pages +EXPORT_SYMBOL vmlinux 0x7dceceac capable +EXPORT_SYMBOL vmlinux 0x7de9649b skb_copy +EXPORT_SYMBOL vmlinux 0x7dee8e84 mb_cache_entry_find_first +EXPORT_SYMBOL vmlinux 0x7e27c5b3 dev_unicast_add +EXPORT_SYMBOL vmlinux 0x7e2ced73 mmc_align_data_size +EXPORT_SYMBOL vmlinux 0x7e406779 simple_dir_inode_operations +EXPORT_SYMBOL vmlinux 0x7e434200 __scsi_add_device +EXPORT_SYMBOL vmlinux 0x7e436d5d inet_csk_clear_xmit_timers +EXPORT_SYMBOL vmlinux 0x7e50cd78 iw_handler_get_thrspy +EXPORT_SYMBOL vmlinux 0x7e663bba neigh_lookup_nodev +EXPORT_SYMBOL vmlinux 0x7e667392 redraw_screen +EXPORT_SYMBOL vmlinux 0x7e716da5 skb_insert +EXPORT_SYMBOL vmlinux 0x7e7e3408 scsi_prep_return +EXPORT_SYMBOL vmlinux 0x7e9ebb05 kernel_thread +EXPORT_SYMBOL vmlinux 0x7ec9bfbc strncpy +EXPORT_SYMBOL vmlinux 0x7ed697f2 scsi_cmd_ioctl +EXPORT_SYMBOL vmlinux 0x7ee91c1d _spin_trylock +EXPORT_SYMBOL vmlinux 0x7ef572c5 bitmap_end_sync +EXPORT_SYMBOL vmlinux 0x7f2390e4 scsi_mode_sense +EXPORT_SYMBOL vmlinux 0x7f24de73 jiffies_to_usecs +EXPORT_SYMBOL vmlinux 0x7f321afd i2c_smbus_read_word_data +EXPORT_SYMBOL vmlinux 0x7f4cf820 dget_locked +EXPORT_SYMBOL vmlinux 0x7f601852 dma_async_device_unregister +EXPORT_SYMBOL vmlinux 0x7f8723bd pcie_mch_quirk +EXPORT_SYMBOL vmlinux 0x7fc73e1d bdget_disk +EXPORT_SYMBOL vmlinux 0x7fe032e6 netlink_change_ngroups +EXPORT_SYMBOL vmlinux 0x8007530f __tcf_em_tree_match +EXPORT_SYMBOL vmlinux 0x8011de15 ip4_datagram_connect +EXPORT_SYMBOL vmlinux 0x804638f2 kfree_skb +EXPORT_SYMBOL vmlinux 0x805b1a98 scsi_print_sense +EXPORT_SYMBOL vmlinux 0x8068bc63 scsi_command_normalize_sense +EXPORT_SYMBOL vmlinux 0x806aa648 contig_page_data +EXPORT_SYMBOL vmlinux 0x80748186 blk_unplug +EXPORT_SYMBOL vmlinux 0x809b0a92 xfrm_policy_bysel_ctx +EXPORT_SYMBOL vmlinux 0x80b8fcc1 ip_mc_inc_group +EXPORT_SYMBOL vmlinux 0x80c3f50e dev_get_by_index +EXPORT_SYMBOL vmlinux 0x80c9a786 journal_check_used_features +EXPORT_SYMBOL vmlinux 0x80f43163 xfrm_state_update +EXPORT_SYMBOL vmlinux 0x810fc83f tcp_prot +EXPORT_SYMBOL vmlinux 0x812cddd6 end_request +EXPORT_SYMBOL vmlinux 0x81410400 tcp_shutdown +EXPORT_SYMBOL vmlinux 0x81472677 acpi_get_table +EXPORT_SYMBOL vmlinux 0x814b2d57 deactivate_super +EXPORT_SYMBOL vmlinux 0x814e7730 nf_ct_destroy +EXPORT_SYMBOL vmlinux 0x815b5dd4 match_octal +EXPORT_SYMBOL vmlinux 0x815f2897 empty_zero_page +EXPORT_SYMBOL vmlinux 0x8185aca6 netif_carrier_on +EXPORT_SYMBOL vmlinux 0x819fba62 dma_pool_destroy +EXPORT_SYMBOL vmlinux 0x81af529a xfrm_state_lookup_byaddr +EXPORT_SYMBOL vmlinux 0x81dbc061 do_sync_write +EXPORT_SYMBOL vmlinux 0x81e6b37f dmi_get_system_info +EXPORT_SYMBOL vmlinux 0x82042e78 zero_fill_bio +EXPORT_SYMBOL vmlinux 0x82072614 tasklet_kill +EXPORT_SYMBOL vmlinux 0x820d225f print_mac +EXPORT_SYMBOL vmlinux 0x821380dd alloc_fcdev +EXPORT_SYMBOL vmlinux 0x822723c8 cdev_alloc +EXPORT_SYMBOL vmlinux 0x823a27ed blk_integrity_compare +EXPORT_SYMBOL vmlinux 0x8251bcc3 bitmap_release_region +EXPORT_SYMBOL vmlinux 0x827b4492 tcf_action_exec +EXPORT_SYMBOL vmlinux 0x8286e248 d_alloc_name +EXPORT_SYMBOL vmlinux 0x829ead58 md_write_end +EXPORT_SYMBOL vmlinux 0x82e9c083 csum_partial_copy_fromiovecend +EXPORT_SYMBOL vmlinux 0x82f65633 dm_io_client_resize +EXPORT_SYMBOL vmlinux 0x82f7d015 keyring_clear +EXPORT_SYMBOL vmlinux 0x82ffeda5 tty_name +EXPORT_SYMBOL vmlinux 0x830e547b ioremap_prot +EXPORT_SYMBOL vmlinux 0x8317e20a completion_done +EXPORT_SYMBOL vmlinux 0x836482a3 genl_register_ops +EXPORT_SYMBOL vmlinux 0x83659ae7 qdisc_destroy +EXPORT_SYMBOL vmlinux 0x83800bfa kref_init +EXPORT_SYMBOL vmlinux 0x838ae1cb bio_endio +EXPORT_SYMBOL vmlinux 0x83a31fdb skb_push +EXPORT_SYMBOL vmlinux 0x83a476ce bitmap_scnlistprintf +EXPORT_SYMBOL vmlinux 0x83ce0d01 kobject_del +EXPORT_SYMBOL vmlinux 0x83d33c39 tcf_hash_check +EXPORT_SYMBOL vmlinux 0x83d8379b bio_unmap_user +EXPORT_SYMBOL vmlinux 0x83ea64dd tcf_em_tree_validate +EXPORT_SYMBOL vmlinux 0x841178a5 dev_load +EXPORT_SYMBOL vmlinux 0x84158773 agp_alloc_page_array +EXPORT_SYMBOL vmlinux 0x8417d647 tty_unthrottle +EXPORT_SYMBOL vmlinux 0x843f8362 pci_pme_active +EXPORT_SYMBOL vmlinux 0x8486ceac register_console +EXPORT_SYMBOL vmlinux 0x84a48d8b mb_cache_shrink +EXPORT_SYMBOL vmlinux 0x84b1ae82 atm_dev_lookup +EXPORT_SYMBOL vmlinux 0x84cbac36 blk_plug_device +EXPORT_SYMBOL vmlinux 0x84d7f055 gnet_stats_start_copy_compat +EXPORT_SYMBOL vmlinux 0x84db1396 neigh_table_clear +EXPORT_SYMBOL vmlinux 0x84ee6c04 i2c_add_adapter +EXPORT_SYMBOL vmlinux 0x8501cb29 bio_phys_segments +EXPORT_SYMBOL vmlinux 0x8525c138 tcp_recvmsg +EXPORT_SYMBOL vmlinux 0x853cbf6b pci_get_class +EXPORT_SYMBOL vmlinux 0x85539bc3 arp_xmit +EXPORT_SYMBOL vmlinux 0x85670f1d rtnl_is_locked +EXPORT_SYMBOL vmlinux 0x8590a80f sysctl_data +EXPORT_SYMBOL vmlinux 0x85a21e75 kernel_listen +EXPORT_SYMBOL vmlinux 0x85abc85f strncmp +EXPORT_SYMBOL vmlinux 0x85df9b6c strsep +EXPORT_SYMBOL vmlinux 0x85e772e4 tty_wait_until_sent +EXPORT_SYMBOL vmlinux 0x85eacd60 md_wait_for_blocked_rdev +EXPORT_SYMBOL vmlinux 0x85f37c53 kernel_getpeername +EXPORT_SYMBOL vmlinux 0x862bff88 i2c_register_driver +EXPORT_SYMBOL vmlinux 0x8631f188 radix_tree_tag_set +EXPORT_SYMBOL vmlinux 0x863cb91a utf8_wcstombs +EXPORT_SYMBOL vmlinux 0x864941a1 arp_broken_ops +EXPORT_SYMBOL vmlinux 0x8664f62e cpufreq_update_policy +EXPORT_SYMBOL vmlinux 0x8686dc2f scsi_prep_state_check +EXPORT_SYMBOL vmlinux 0x868acba5 get_options +EXPORT_SYMBOL vmlinux 0x86a9543c set_bdi_congested +EXPORT_SYMBOL vmlinux 0x86e6c29c simple_rename +EXPORT_SYMBOL vmlinux 0x86fb9b05 bitmap_parse_user +EXPORT_SYMBOL vmlinux 0x871c0a7e fiemap_check_flags +EXPORT_SYMBOL vmlinux 0x871d6f6c seq_puts +EXPORT_SYMBOL vmlinux 0x872e611f nf_log_register +EXPORT_SYMBOL vmlinux 0x8733e9a3 sleep_on_timeout +EXPORT_SYMBOL vmlinux 0x875729b3 jbd2_journal_extend +EXPORT_SYMBOL vmlinux 0x876dafc3 ec_write +EXPORT_SYMBOL vmlinux 0x8785725d param_set_charp +EXPORT_SYMBOL vmlinux 0x87861e60 neigh_compat_output +EXPORT_SYMBOL vmlinux 0x878ab3ce sysctl_tcp_adv_win_scale +EXPORT_SYMBOL vmlinux 0x87945010 give_up_console +EXPORT_SYMBOL vmlinux 0x87c5cffe unlock_rename +EXPORT_SYMBOL vmlinux 0x8804e025 agp3_generic_tlbflush +EXPORT_SYMBOL vmlinux 0x880a44f0 set_anon_super +EXPORT_SYMBOL vmlinux 0x881039d0 zlib_inflate +EXPORT_SYMBOL vmlinux 0x882c26db scsi_register +EXPORT_SYMBOL vmlinux 0x885bc707 acpi_bus_generate_proc_event +EXPORT_SYMBOL vmlinux 0x8872d11c pnp_unregister_card_driver +EXPORT_SYMBOL vmlinux 0x88b56bd1 ps2_drain +EXPORT_SYMBOL vmlinux 0x88c81e1c ppp_channel_index +EXPORT_SYMBOL vmlinux 0x892b26a0 set_memory_nx +EXPORT_SYMBOL vmlinux 0x8933c99e tcf_exts_dump_stats +EXPORT_SYMBOL vmlinux 0x89361e08 __nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0x8953bb27 del_timer +EXPORT_SYMBOL vmlinux 0x8957d569 dev_disable_lro +EXPORT_SYMBOL vmlinux 0x897473df mktime +EXPORT_SYMBOL vmlinux 0x898b1fec mutex_trylock +EXPORT_SYMBOL vmlinux 0x89949018 down_timeout +EXPORT_SYMBOL vmlinux 0x89d5538d fb_pad_aligned_buffer +EXPORT_SYMBOL vmlinux 0x89d66811 build_ehash_secret +EXPORT_SYMBOL vmlinux 0x8a32803d scsi_unblock_requests +EXPORT_SYMBOL vmlinux 0x8a3eabf0 __wait_on_bit +EXPORT_SYMBOL vmlinux 0x8a709909 bitmap_startwrite +EXPORT_SYMBOL vmlinux 0x8a7d1c31 high_memory +EXPORT_SYMBOL vmlinux 0x8a99a016 mempool_free_slab +EXPORT_SYMBOL vmlinux 0x8aa27945 netlink_ack +EXPORT_SYMBOL vmlinux 0x8aaf8654 mutex_lock +EXPORT_SYMBOL vmlinux 0x8ac40297 iommu_area_free +EXPORT_SYMBOL vmlinux 0x8b093e8f blk_queue_stack_limits +EXPORT_SYMBOL vmlinux 0x8b35e873 sg_last +EXPORT_SYMBOL vmlinux 0x8b3a226b udp_prot +EXPORT_SYMBOL vmlinux 0x8b439ba6 bio_integrity_alloc +EXPORT_SYMBOL vmlinux 0x8b50bd1c udp_memory_allocated +EXPORT_SYMBOL vmlinux 0x8b52d791 __scm_destroy +EXPORT_SYMBOL vmlinux 0x8b618d08 overflowuid +EXPORT_SYMBOL vmlinux 0x8b7fe311 kmemdup +EXPORT_SYMBOL vmlinux 0x8b922c0f __strnlen_user +EXPORT_SYMBOL vmlinux 0x8b966b63 sn_rtc_cycles_per_second +EXPORT_SYMBOL vmlinux 0x8b989cf9 acpi_bus_can_wakeup +EXPORT_SYMBOL vmlinux 0x8bca3aba vfs_llseek +EXPORT_SYMBOL vmlinux 0x8bda29e3 neigh_destroy +EXPORT_SYMBOL vmlinux 0x8c08b567 swiotlb_unmap_single +EXPORT_SYMBOL vmlinux 0x8c0f7f87 mmc_add_host +EXPORT_SYMBOL vmlinux 0x8c183cbe iowrite16 +EXPORT_SYMBOL vmlinux 0x8c59df14 tty_unregister_driver +EXPORT_SYMBOL vmlinux 0x8c67363c scsi_register_driver +EXPORT_SYMBOL vmlinux 0x8c7a10f6 pci_add_new_bus +EXPORT_SYMBOL vmlinux 0x8cc79cab iowrite16_rep +EXPORT_SYMBOL vmlinux 0x8cebbcd8 rtnl_create_link +EXPORT_SYMBOL vmlinux 0x8cfb9422 wireless_spy_update +EXPORT_SYMBOL vmlinux 0x8cfd0c17 __starget_for_each_device +EXPORT_SYMBOL vmlinux 0x8d3894f2 _ctype +EXPORT_SYMBOL vmlinux 0x8d551bef sysctl_tcp_rmem +EXPORT_SYMBOL vmlinux 0x8d57f908 module_refcount +EXPORT_SYMBOL vmlinux 0x8d6a6ed8 mb_cache_entry_get +EXPORT_SYMBOL vmlinux 0x8d741950 udp_lib_getsockopt +EXPORT_SYMBOL vmlinux 0x8d8d96c6 acpi_get_sleep_type_data +EXPORT_SYMBOL vmlinux 0x8da379a1 dquot_transfer +EXPORT_SYMBOL vmlinux 0x8da5cf90 nobh_writepage +EXPORT_SYMBOL vmlinux 0x8dbf55c9 udp_proc_register +EXPORT_SYMBOL vmlinux 0x8dca832f __percpu_counter_sum +EXPORT_SYMBOL vmlinux 0x8ddae97f serio_rescan +EXPORT_SYMBOL vmlinux 0x8df0192a journal_start +EXPORT_SYMBOL vmlinux 0x8e002cda acpi_remove_gpe_block +EXPORT_SYMBOL vmlinux 0x8e0637ba i8253_lock +EXPORT_SYMBOL vmlinux 0x8e0b7743 ipv6_ext_hdr +EXPORT_SYMBOL vmlinux 0x8e33c268 jbd2_journal_forget +EXPORT_SYMBOL vmlinux 0x8e3c9cc3 vprintk +EXPORT_SYMBOL vmlinux 0x8e4d403b noop_qdisc +EXPORT_SYMBOL vmlinux 0x8e4ff64b seq_printf +EXPORT_SYMBOL vmlinux 0x8e763ae1 send_remote_softirq +EXPORT_SYMBOL vmlinux 0x8f0e3a2c dev_kfree_skb_irq +EXPORT_SYMBOL vmlinux 0x8f17ff7b xfrm_input_resume +EXPORT_SYMBOL vmlinux 0x8f1ae4c9 pcim_iounmap +EXPORT_SYMBOL vmlinux 0x8f3745de journal_flush +EXPORT_SYMBOL vmlinux 0x8f45b14c fb_set_var +EXPORT_SYMBOL vmlinux 0x8f6096d2 unregister_sysctl_table +EXPORT_SYMBOL vmlinux 0x8f6b7950 set_irq_data +EXPORT_SYMBOL vmlinux 0x8f859662 generic_file_llseek +EXPORT_SYMBOL vmlinux 0x8f9c199c __get_user_2 +EXPORT_SYMBOL vmlinux 0x8fb29b6c mod_zone_page_state +EXPORT_SYMBOL vmlinux 0x8ff891de scsi_print_command +EXPORT_SYMBOL vmlinux 0x90022b44 xfrm_policy_flush +EXPORT_SYMBOL vmlinux 0x90035333 secure_tcpv6_sequence_number +EXPORT_SYMBOL vmlinux 0x9012c649 scsi_setup_fs_cmnd +EXPORT_SYMBOL vmlinux 0x907812d0 wait_on_page_bit +EXPORT_SYMBOL vmlinux 0x90a15841 jbd2_journal_init_dev +EXPORT_SYMBOL vmlinux 0x90a1601f dmi_check_system +EXPORT_SYMBOL vmlinux 0x90a943ba nmi_active +EXPORT_SYMBOL vmlinux 0x90ae6c3f unregister_framebuffer +EXPORT_SYMBOL vmlinux 0x910097b6 acpi_get_hp_hw_control_from_firmware +EXPORT_SYMBOL vmlinux 0x911d3001 __splice_from_pipe +EXPORT_SYMBOL vmlinux 0x9137355d pci_bus_read_config_byte +EXPORT_SYMBOL vmlinux 0x9137ab13 bio_integrity_endio +EXPORT_SYMBOL vmlinux 0x9144a8e2 ec_burst_disable +EXPORT_SYMBOL vmlinux 0x9144e262 thaw_bdev +EXPORT_SYMBOL vmlinux 0x91481982 __ratelimit +EXPORT_SYMBOL vmlinux 0x91539557 acpi_notifier_call_chain +EXPORT_SYMBOL vmlinux 0x91607d95 set_memory_wb +EXPORT_SYMBOL vmlinux 0x91724aae inet_sock_destruct +EXPORT_SYMBOL vmlinux 0x91865d16 dma_pool_free +EXPORT_SYMBOL vmlinux 0x91b6b487 tcp_v4_md5_do_add +EXPORT_SYMBOL vmlinux 0x91ca8959 acpi_get_register +EXPORT_SYMBOL vmlinux 0x920f8ea4 get_sb_pseudo +EXPORT_SYMBOL vmlinux 0x922af490 pci_bus_write_config_byte +EXPORT_SYMBOL vmlinux 0x92392cd9 iov_shorten +EXPORT_SYMBOL vmlinux 0x926de07b jbd2_journal_begin_ordered_truncate +EXPORT_SYMBOL vmlinux 0x927e989f gen_pool_alloc +EXPORT_SYMBOL vmlinux 0x92b202dd __lock_page +EXPORT_SYMBOL vmlinux 0x92ea4ae4 crc32_le +EXPORT_SYMBOL vmlinux 0x93017a66 i2c_attach_client +EXPORT_SYMBOL vmlinux 0x9305f8e6 cpufreq_get +EXPORT_SYMBOL vmlinux 0x931528d0 sock_no_connect +EXPORT_SYMBOL vmlinux 0x931b19ef phy_attach +EXPORT_SYMBOL vmlinux 0x931c8578 dev_open +EXPORT_SYMBOL vmlinux 0x9337a815 sg_miter_next +EXPORT_SYMBOL vmlinux 0x93439151 skb_make_writable +EXPORT_SYMBOL vmlinux 0x934f87f6 nf_register_queue_handler +EXPORT_SYMBOL vmlinux 0x9382c27d stop_tty +EXPORT_SYMBOL vmlinux 0x93a6e0b2 io_schedule +EXPORT_SYMBOL vmlinux 0x93abcfb7 set_disk_ro +EXPORT_SYMBOL vmlinux 0x93afa72e vm_get_page_prot +EXPORT_SYMBOL vmlinux 0x93b8ef56 mutex_lock_interruptible +EXPORT_SYMBOL vmlinux 0x93c0eca7 ip_route_output_key +EXPORT_SYMBOL vmlinux 0x93c69acf param_set_byte +EXPORT_SYMBOL vmlinux 0x93ca03de netif_rx +EXPORT_SYMBOL vmlinux 0x93cbd1ec _spin_lock_bh +EXPORT_SYMBOL vmlinux 0x93dd9edd fb_set_suspend +EXPORT_SYMBOL vmlinux 0x93ed6a1b mem_section +EXPORT_SYMBOL vmlinux 0x93fca811 __get_free_pages +EXPORT_SYMBOL vmlinux 0x943cf844 sock_create +EXPORT_SYMBOL vmlinux 0x943e868f ida_get_new +EXPORT_SYMBOL vmlinux 0x94556016 i2c_verify_client +EXPORT_SYMBOL vmlinux 0x945bc6a7 copy_from_user +EXPORT_SYMBOL vmlinux 0x946feb8c skb_queue_head +EXPORT_SYMBOL vmlinux 0x94883ab2 gnet_stats_copy_rate_est +EXPORT_SYMBOL vmlinux 0x94961283 vunmap +EXPORT_SYMBOL vmlinux 0x94bd77de dm_get_device +EXPORT_SYMBOL vmlinux 0x94c8e2ec key_type_keyring +EXPORT_SYMBOL vmlinux 0x94d57240 skb_copy_datagram_iovec +EXPORT_SYMBOL vmlinux 0x94ec74a8 i2c_release_client +EXPORT_SYMBOL vmlinux 0x94f62693 tty_free_termios +EXPORT_SYMBOL vmlinux 0x94fcf08e bioset_create +EXPORT_SYMBOL vmlinux 0x9515c0e7 block_prepare_write +EXPORT_SYMBOL vmlinux 0x95352ea9 acpi_check_mem_region +EXPORT_SYMBOL vmlinux 0x954488a4 syncookie_secret +EXPORT_SYMBOL vmlinux 0x9545af6d tasklet_init +EXPORT_SYMBOL vmlinux 0x954c8af3 dm_io_client_destroy +EXPORT_SYMBOL vmlinux 0x954cbb26 vsprintf +EXPORT_SYMBOL vmlinux 0x954e2599 iget_locked +EXPORT_SYMBOL vmlinux 0x957ebc01 sync_mapping_buffers +EXPORT_SYMBOL vmlinux 0x95b7a3cf call_usermodehelper_setup +EXPORT_SYMBOL vmlinux 0x95b9239e tcp_disconnect +EXPORT_SYMBOL vmlinux 0x95ceb864 key_update +EXPORT_SYMBOL vmlinux 0x95dd999a gnet_stats_finish_copy +EXPORT_SYMBOL vmlinux 0x96066cc6 swiotlb_dma_mapping_error +EXPORT_SYMBOL vmlinux 0x962bee22 pci_dev_put +EXPORT_SYMBOL vmlinux 0x96481cc7 per_cpu__x86_cpu_to_apicid +EXPORT_SYMBOL vmlinux 0x965d39c7 skb_free_datagram +EXPORT_SYMBOL vmlinux 0x96668bc1 vfs_read +EXPORT_SYMBOL vmlinux 0x967379be put_tty_driver +EXPORT_SYMBOL vmlinux 0x968f3f5f scsi_target_quiesce +EXPORT_SYMBOL vmlinux 0x96abc764 dst_release +EXPORT_SYMBOL vmlinux 0x96b18f4d simple_transaction_read +EXPORT_SYMBOL vmlinux 0x96b937dd qdisc_create_dflt +EXPORT_SYMBOL vmlinux 0x96cd2b04 scsi_sense_key_string +EXPORT_SYMBOL vmlinux 0x96d65908 dev_set_mac_address +EXPORT_SYMBOL vmlinux 0x96f33400 up_read +EXPORT_SYMBOL vmlinux 0x970b3894 ilookup5_nowait +EXPORT_SYMBOL vmlinux 0x970dc9dc uart_get_divisor +EXPORT_SYMBOL vmlinux 0x97234958 __scsi_alloc_queue +EXPORT_SYMBOL vmlinux 0x972750c5 mark_buffer_dirty +EXPORT_SYMBOL vmlinux 0x973873ab _spin_lock +EXPORT_SYMBOL vmlinux 0x9739b607 inode_set_bytes +EXPORT_SYMBOL vmlinux 0x9754ec10 radix_tree_preload +EXPORT_SYMBOL vmlinux 0x978eb519 poll_initwait +EXPORT_SYMBOL vmlinux 0x97a808f6 security_inode_init_security +EXPORT_SYMBOL vmlinux 0x97be1693 ht_create_irq +EXPORT_SYMBOL vmlinux 0x97d86283 __nla_put +EXPORT_SYMBOL vmlinux 0x97de0ddd acpi_install_gpe_block +EXPORT_SYMBOL vmlinux 0x97e9eb82 inode_double_unlock +EXPORT_SYMBOL vmlinux 0x97ec05a6 cfb_fillrect +EXPORT_SYMBOL vmlinux 0x980a6e3d pskb_expand_head +EXPORT_SYMBOL vmlinux 0x980a9b4f file_update_time +EXPORT_SYMBOL vmlinux 0x981caa83 bdi_destroy +EXPORT_SYMBOL vmlinux 0x98208eba key_link +EXPORT_SYMBOL vmlinux 0x9839449c load_nls +EXPORT_SYMBOL vmlinux 0x9863500a udp_lib_setsockopt +EXPORT_SYMBOL vmlinux 0x986e6135 fb_pad_unaligned_buffer +EXPORT_SYMBOL vmlinux 0x988cb93b remove_proc_entry +EXPORT_SYMBOL vmlinux 0x988ed85d set_memory_x +EXPORT_SYMBOL vmlinux 0x9892437d udp_poll +EXPORT_SYMBOL vmlinux 0x98b86016 __xfrm_lookup +EXPORT_SYMBOL vmlinux 0x98beef35 unlock_super +EXPORT_SYMBOL vmlinux 0x98c6b09d scsi_put_command +EXPORT_SYMBOL vmlinux 0x98de1daf sock_no_recvmsg +EXPORT_SYMBOL vmlinux 0x98e5f680 __devm_release_region +EXPORT_SYMBOL vmlinux 0x993c8662 kernel_accept +EXPORT_SYMBOL vmlinux 0x9957309a find_task_by_pid_type_ns +EXPORT_SYMBOL vmlinux 0x9970c3fa igrab +EXPORT_SYMBOL vmlinux 0x99792b4c jbd2_journal_lock_updates +EXPORT_SYMBOL vmlinux 0x99860a48 jbd2_journal_errno +EXPORT_SYMBOL vmlinux 0x998a90bf mark_buffer_dirty_inode +EXPORT_SYMBOL vmlinux 0x9994c0ca ps2_is_keyboard_id +EXPORT_SYMBOL vmlinux 0x999e8297 vfree +EXPORT_SYMBOL vmlinux 0x99aadb21 param_get_ulong +EXPORT_SYMBOL vmlinux 0x99bc6958 arch_acpi_processor_init_pdc +EXPORT_SYMBOL vmlinux 0x99bfbe39 get_unused_fd +EXPORT_SYMBOL vmlinux 0x99cdc86b sysctl_tcp_reordering +EXPORT_SYMBOL vmlinux 0x99ea12ce panic_blink +EXPORT_SYMBOL vmlinux 0x99feb0ad phy_start +EXPORT_SYMBOL vmlinux 0x9a1dfd65 strpbrk +EXPORT_SYMBOL vmlinux 0x9a225951 sync_blockdev +EXPORT_SYMBOL vmlinux 0x9a356159 llc_sap_close +EXPORT_SYMBOL vmlinux 0x9a5eef7f llc_build_and_send_ui_pkt +EXPORT_SYMBOL vmlinux 0x9a68e47b inode_init_once +EXPORT_SYMBOL vmlinux 0x9a6eb5ba per_cpu__cpu_core_map +EXPORT_SYMBOL vmlinux 0x9a70437b eth_header +EXPORT_SYMBOL vmlinux 0x9a738dcb blk_rq_map_user_iov +EXPORT_SYMBOL vmlinux 0x9a9985be percpu_counter_destroy +EXPORT_SYMBOL vmlinux 0x9aabc564 crc16 +EXPORT_SYMBOL vmlinux 0x9acd888a blk_queue_merge_bvec +EXPORT_SYMBOL vmlinux 0x9af0f806 register_gifconf +EXPORT_SYMBOL vmlinux 0x9b06c07f i2c_transfer +EXPORT_SYMBOL vmlinux 0x9b07312c unregister_netdevice +EXPORT_SYMBOL vmlinux 0x9b175304 mmc_detect_change +EXPORT_SYMBOL vmlinux 0x9b2db58a ipv6_chk_addr +EXPORT_SYMBOL vmlinux 0x9b388444 get_zeroed_page +EXPORT_SYMBOL vmlinux 0x9b3cd06c pci_bus_write_config_dword +EXPORT_SYMBOL vmlinux 0x9b3e0aa5 __vlan_hwaccel_rx +EXPORT_SYMBOL vmlinux 0x9b6408d6 gnet_stats_start_copy +EXPORT_SYMBOL vmlinux 0x9ba03769 security_task_getsecid +EXPORT_SYMBOL vmlinux 0x9ba7089d argv_split +EXPORT_SYMBOL vmlinux 0x9ba88a9d seq_read +EXPORT_SYMBOL vmlinux 0x9bba3e5d tcp_sendpage +EXPORT_SYMBOL vmlinux 0x9bc1530f seq_bitmap +EXPORT_SYMBOL vmlinux 0x9bc565c5 memcpy_fromiovecend +EXPORT_SYMBOL vmlinux 0x9bccf12d nla_put_nohdr +EXPORT_SYMBOL vmlinux 0x9bfbc3d5 jbd2_journal_stop +EXPORT_SYMBOL vmlinux 0x9c012508 fb_parse_edid +EXPORT_SYMBOL vmlinux 0x9c035a4a block_invalidatepage +EXPORT_SYMBOL vmlinux 0x9c0ea3cd memscan +EXPORT_SYMBOL vmlinux 0x9c491f60 sg_alloc_table +EXPORT_SYMBOL vmlinux 0x9c93b123 console_stop +EXPORT_SYMBOL vmlinux 0x9ca95a0e sort +EXPORT_SYMBOL vmlinux 0x9cb96e92 qdisc_put_rtab +EXPORT_SYMBOL vmlinux 0x9cc77ca0 scsi_host_alloc +EXPORT_SYMBOL vmlinux 0x9ccb2622 finish_wait +EXPORT_SYMBOL vmlinux 0x9ce88b95 eth_type_trans +EXPORT_SYMBOL vmlinux 0x9ced38aa down_trylock +EXPORT_SYMBOL vmlinux 0x9cfd56c5 scsi_print_status +EXPORT_SYMBOL vmlinux 0x9d0a94bf register_md_personality +EXPORT_SYMBOL vmlinux 0x9d11f223 generic_write_checks +EXPORT_SYMBOL vmlinux 0x9d33ef5e acpi_enable +EXPORT_SYMBOL vmlinux 0x9d4c3461 jbd2_journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0x9d711f1f percpu_counter_init +EXPORT_SYMBOL vmlinux 0x9d7bdca5 blk_requeue_request +EXPORT_SYMBOL vmlinux 0x9d821191 xfrm6_input_addr +EXPORT_SYMBOL vmlinux 0x9d8b9cbe inet_stream_ops +EXPORT_SYMBOL vmlinux 0x9d9563f3 cfb_copyarea +EXPORT_SYMBOL vmlinux 0x9db21624 hex_dump_to_buffer +EXPORT_SYMBOL vmlinux 0x9dde8322 ipv6_setsockopt +EXPORT_SYMBOL vmlinux 0x9df53af6 agp_generic_insert_memory +EXPORT_SYMBOL vmlinux 0x9e1723ce usb_serial_resume +EXPORT_SYMBOL vmlinux 0x9e251a06 xfrm_state_alloc +EXPORT_SYMBOL vmlinux 0x9e2ba23e posix_test_lock +EXPORT_SYMBOL vmlinux 0x9e363b6b acpi_disable_gpe +EXPORT_SYMBOL vmlinux 0x9e38fc89 vcc_release_async +EXPORT_SYMBOL vmlinux 0x9e5142de genphy_read_status +EXPORT_SYMBOL vmlinux 0x9e5be29f scsi_reset_provider +EXPORT_SYMBOL vmlinux 0x9e64fbfe rtc_cmos_read +EXPORT_SYMBOL vmlinux 0x9e6a9388 end_buffer_read_sync +EXPORT_SYMBOL vmlinux 0x9e7d6bd0 __udelay +EXPORT_SYMBOL vmlinux 0x9e9cbb94 proto_unregister +EXPORT_SYMBOL vmlinux 0x9ea0ad49 __sg_free_table +EXPORT_SYMBOL vmlinux 0x9ea28ec7 acpi_evaluate_object +EXPORT_SYMBOL vmlinux 0x9ea8616d dev_change_flags +EXPORT_SYMBOL vmlinux 0x9eacbc13 d_instantiate +EXPORT_SYMBOL vmlinux 0x9ebd4c04 adjust_resource +EXPORT_SYMBOL vmlinux 0x9edbecae snprintf +EXPORT_SYMBOL vmlinux 0x9eecde16 do_brk +EXPORT_SYMBOL vmlinux 0x9eef8a19 mdiobus_write +EXPORT_SYMBOL vmlinux 0x9ef44061 cdrom_open +EXPORT_SYMBOL vmlinux 0x9ef63672 xfrm_find_acq_byseq +EXPORT_SYMBOL vmlinux 0x9ef749e2 unregister_chrdev +EXPORT_SYMBOL vmlinux 0x9f100139 jiffies_to_clock_t +EXPORT_SYMBOL vmlinux 0x9f10e62f kernel_connect +EXPORT_SYMBOL vmlinux 0x9f11d4c6 input_release_device +EXPORT_SYMBOL vmlinux 0x9f288ec1 vfs_link +EXPORT_SYMBOL vmlinux 0x9f2bdaac __bitmap_or +EXPORT_SYMBOL vmlinux 0x9f50ad81 ethtool_op_set_sg +EXPORT_SYMBOL vmlinux 0x9f5bad27 inet_del_protocol +EXPORT_SYMBOL vmlinux 0x9f5bb256 acpi_bus_get_status +EXPORT_SYMBOL vmlinux 0x9f6b6587 inet_frags_exit_net +EXPORT_SYMBOL vmlinux 0x9f8ae080 ethtool_op_get_tso +EXPORT_SYMBOL vmlinux 0x9f984513 strrchr +EXPORT_SYMBOL vmlinux 0x9fa274b4 dq_data_lock +EXPORT_SYMBOL vmlinux 0x9fe94a67 is_bad_inode +EXPORT_SYMBOL vmlinux 0x9feaf287 sonet_subtract_stats +EXPORT_SYMBOL vmlinux 0x9ff08d4d vfs_rename +EXPORT_SYMBOL vmlinux 0xa0240e9d generic_file_readonly_mmap +EXPORT_SYMBOL vmlinux 0xa0293d68 call_usermodehelper_stdinpipe +EXPORT_SYMBOL vmlinux 0xa03523d5 security_unix_stream_connect +EXPORT_SYMBOL vmlinux 0xa041068d dma_set_mask +EXPORT_SYMBOL vmlinux 0xa04a01bd qdisc_class_hash_insert +EXPORT_SYMBOL vmlinux 0xa05c03df mempool_kmalloc +EXPORT_SYMBOL vmlinux 0xa06d7419 remove_arg_zero +EXPORT_SYMBOL vmlinux 0xa0ad23d5 nf_register_sockopt +EXPORT_SYMBOL vmlinux 0xa0b04675 vmalloc_32 +EXPORT_SYMBOL vmlinux 0xa0ceef51 out_of_line_wait_on_bit +EXPORT_SYMBOL vmlinux 0xa0d26732 blk_queue_bounce_limit +EXPORT_SYMBOL vmlinux 0xa0fbac79 wake_up_bit +EXPORT_SYMBOL vmlinux 0xa108eb4d sysctl_optmem_max +EXPORT_SYMBOL vmlinux 0xa10dcc13 getrawmonotonic +EXPORT_SYMBOL vmlinux 0xa120d33c tty_unregister_ldisc +EXPORT_SYMBOL vmlinux 0xa123dbe2 scsi_cmd_print_sense_hdr +EXPORT_SYMBOL vmlinux 0xa1321b1e blk_queue_segment_boundary +EXPORT_SYMBOL vmlinux 0xa13798f8 printk_ratelimit +EXPORT_SYMBOL vmlinux 0xa161f34c inet_unregister_protosw +EXPORT_SYMBOL vmlinux 0xa1a3de46 generic_listxattr +EXPORT_SYMBOL vmlinux 0xa1b0163f __scsi_put_command +EXPORT_SYMBOL vmlinux 0xa1b759ce fb_add_videomode +EXPORT_SYMBOL vmlinux 0xa1c76e0a _cond_resched +EXPORT_SYMBOL vmlinux 0xa1ccf5a0 generic_removexattr +EXPORT_SYMBOL vmlinux 0xa1d3b72e inet_shutdown +EXPORT_SYMBOL vmlinux 0xa1e14039 balance_dirty_pages_ratelimited_nr +EXPORT_SYMBOL vmlinux 0xa1e6ee96 tcp_alloc_md5sig_pool +EXPORT_SYMBOL vmlinux 0xa1f4cd89 devm_iounmap +EXPORT_SYMBOL vmlinux 0xa20ce1b8 net_msg_warn +EXPORT_SYMBOL vmlinux 0xa222de6b nf_register_hooks +EXPORT_SYMBOL vmlinux 0xa27fdf75 generic_shutdown_super +EXPORT_SYMBOL vmlinux 0xa285db3e swiotlb_map_sg +EXPORT_SYMBOL vmlinux 0xa290736c setup_arg_pages +EXPORT_SYMBOL vmlinux 0xa2a1e5c9 _write_lock_bh +EXPORT_SYMBOL vmlinux 0xa2a5fd77 inet_ehash_secret +EXPORT_SYMBOL vmlinux 0xa2aa2a4e jbd2_journal_revoke +EXPORT_SYMBOL vmlinux 0xa2babe7f scsi_block_requests +EXPORT_SYMBOL vmlinux 0xa2eff383 __alloc_skb +EXPORT_SYMBOL vmlinux 0xa302bdca sock_no_getname +EXPORT_SYMBOL vmlinux 0xa319895a posix_lock_file_wait +EXPORT_SYMBOL vmlinux 0xa31f172d __copy_from_user_inatomic +EXPORT_SYMBOL vmlinux 0xa329f07e register_shrinker +EXPORT_SYMBOL vmlinux 0xa33f7c7c nla_strlcpy +EXPORT_SYMBOL vmlinux 0xa350a8f8 set_memory_array_uc +EXPORT_SYMBOL vmlinux 0xa35de80f ipv4_config +EXPORT_SYMBOL vmlinux 0xa361f73c input_set_capability +EXPORT_SYMBOL vmlinux 0xa38ab0ba i2c_probe +EXPORT_SYMBOL vmlinux 0xa38d3042 __kfree_skb +EXPORT_SYMBOL vmlinux 0xa395ef1c bt_sock_wait_state +EXPORT_SYMBOL vmlinux 0xa3a5be95 memmove +EXPORT_SYMBOL vmlinux 0xa3ba3b4c jbd2_journal_file_inode +EXPORT_SYMBOL vmlinux 0xa3bbcd80 acpi_set_gpe_type +EXPORT_SYMBOL vmlinux 0xa3c982e0 jbd2_journal_release_jbd_inode +EXPORT_SYMBOL vmlinux 0xa3ebcf22 console_start +EXPORT_SYMBOL vmlinux 0xa42596c5 page_zero_new_buffers +EXPORT_SYMBOL vmlinux 0xa4295360 textsearch_unregister +EXPORT_SYMBOL vmlinux 0xa44072fc posix_acl_alloc +EXPORT_SYMBOL vmlinux 0xa44ad274 wait_for_completion_interruptible_timeout +EXPORT_SYMBOL vmlinux 0xa45dcda5 log_wait_commit +EXPORT_SYMBOL vmlinux 0xa46bea97 cancel_dirty_page +EXPORT_SYMBOL vmlinux 0xa471e75b cdrom_get_last_written +EXPORT_SYMBOL vmlinux 0xa476fc6e qdisc_list_del +EXPORT_SYMBOL vmlinux 0xa4936133 kmem_cache_name +EXPORT_SYMBOL vmlinux 0xa4b94fea iowrite8_rep +EXPORT_SYMBOL vmlinux 0xa4d4f0e6 global_cache_flush +EXPORT_SYMBOL vmlinux 0xa4d8fe5f vfs_dq_drop +EXPORT_SYMBOL vmlinux 0xa4df1151 kref_set +EXPORT_SYMBOL vmlinux 0xa4e76ca3 dquot_alloc_inode +EXPORT_SYMBOL vmlinux 0xa506d10a kobject_init +EXPORT_SYMBOL vmlinux 0xa5114b0b pcie_port_service_register +EXPORT_SYMBOL vmlinux 0xa52bbc64 register_chrdev +EXPORT_SYMBOL vmlinux 0xa5423cc4 param_get_int +EXPORT_SYMBOL vmlinux 0xa5452482 tcp_md5_hash_skb_data +EXPORT_SYMBOL vmlinux 0xa5693df7 posix_acl_clone +EXPORT_SYMBOL vmlinux 0xa56f1315 mempool_free +EXPORT_SYMBOL vmlinux 0xa58b6804 nla_parse +EXPORT_SYMBOL vmlinux 0xa5922bb1 kfifo_init +EXPORT_SYMBOL vmlinux 0xa598e29c vesa_modes +EXPORT_SYMBOL vmlinux 0xa5ad131a linkwatch_fire_event +EXPORT_SYMBOL vmlinux 0xa5adbe8c ida_destroy +EXPORT_SYMBOL vmlinux 0xa6021043 ip6_frag_match +EXPORT_SYMBOL vmlinux 0xa6186361 dma_pool_create +EXPORT_SYMBOL vmlinux 0xa61d7316 cdrom_release +EXPORT_SYMBOL vmlinux 0xa63d85ab slhc_remember +EXPORT_SYMBOL vmlinux 0xa6484eae smp_call_function_mask +EXPORT_SYMBOL vmlinux 0xa6582bac vmap +EXPORT_SYMBOL vmlinux 0xa68124fa hweight8 +EXPORT_SYMBOL vmlinux 0xa681fe88 generate_random_uuid +EXPORT_SYMBOL vmlinux 0xa6857424 alloc_buffer_head +EXPORT_SYMBOL vmlinux 0xa69087d6 register_framebuffer +EXPORT_SYMBOL vmlinux 0xa6b83a2a set_pages_wb +EXPORT_SYMBOL vmlinux 0xa6d3799f bio_map_user +EXPORT_SYMBOL vmlinux 0xa6dcc773 rb_insert_color +EXPORT_SYMBOL vmlinux 0xa6e0fa68 k8_northbridges +EXPORT_SYMBOL vmlinux 0xa70d5c6a ethtool_op_get_tx_csum +EXPORT_SYMBOL vmlinux 0xa70fabbe release_evntsel_nmi +EXPORT_SYMBOL vmlinux 0xa73cba7b netdev_rx_csum_fault +EXPORT_SYMBOL vmlinux 0xa7502f48 jiffies_to_timeval +EXPORT_SYMBOL vmlinux 0xa75d6155 pci_find_device +EXPORT_SYMBOL vmlinux 0xa76dc0c8 locks_remove_posix +EXPORT_SYMBOL vmlinux 0xa76f5b40 neigh_update +EXPORT_SYMBOL vmlinux 0xa7760ad9 __scm_send +EXPORT_SYMBOL vmlinux 0xa7778241 get_sb_nodev +EXPORT_SYMBOL vmlinux 0xa780f383 ___pskb_trim +EXPORT_SYMBOL vmlinux 0xa78f6a23 skb_gso_segment +EXPORT_SYMBOL vmlinux 0xa7c2293e netdev_state_change +EXPORT_SYMBOL vmlinux 0xa7c35c6b getnstimeofday +EXPORT_SYMBOL vmlinux 0xa7d78add kthread_create +EXPORT_SYMBOL vmlinux 0xa816c525 schedule_work_on +EXPORT_SYMBOL vmlinux 0xa81b826c bd_claim +EXPORT_SYMBOL vmlinux 0xa822dae7 down_read +EXPORT_SYMBOL vmlinux 0xa82f436d agp_flush_chipset +EXPORT_SYMBOL vmlinux 0xa871d950 cdrom_number_of_slots +EXPORT_SYMBOL vmlinux 0xa87c8b14 atm_dev_register +EXPORT_SYMBOL vmlinux 0xa886a958 krealloc +EXPORT_SYMBOL vmlinux 0xa88f9255 seq_release_private +EXPORT_SYMBOL vmlinux 0xa890f6aa ip_queue_xmit +EXPORT_SYMBOL vmlinux 0xa8a6f639 __check_region +EXPORT_SYMBOL vmlinux 0xa8c8db5c blkdev_get +EXPORT_SYMBOL vmlinux 0xa8fa06da vfs_mknod +EXPORT_SYMBOL vmlinux 0xa8fbf582 idr_replace +EXPORT_SYMBOL vmlinux 0xa8fef7bb security_unix_may_send +EXPORT_SYMBOL vmlinux 0xa9001a2f blk_integrity_register +EXPORT_SYMBOL vmlinux 0xa90131ec file_remove_suid +EXPORT_SYMBOL vmlinux 0xa91b5561 acpi_video_backlight_support +EXPORT_SYMBOL vmlinux 0xa91ddef7 ethtool_op_set_tx_csum +EXPORT_SYMBOL vmlinux 0xa925899a param_set_bool +EXPORT_SYMBOL vmlinux 0xa92c32c3 jbd2_journal_ack_err +EXPORT_SYMBOL vmlinux 0xa92d4b4e d_alloc +EXPORT_SYMBOL vmlinux 0xa94a3e45 km_policy_expired +EXPORT_SYMBOL vmlinux 0xa95cb7be nf_unregister_hooks +EXPORT_SYMBOL vmlinux 0xa95d817f __ip_select_ident +EXPORT_SYMBOL vmlinux 0xa96d1b79 blk_get_request +EXPORT_SYMBOL vmlinux 0xa96e4bc3 pci_wake_from_d3 +EXPORT_SYMBOL vmlinux 0xa9871889 tty_port_init +EXPORT_SYMBOL vmlinux 0xa98b73b0 wake_up_process +EXPORT_SYMBOL vmlinux 0xa9a9e0b9 agp_generic_alloc_user +EXPORT_SYMBOL vmlinux 0xa9de438d simple_empty +EXPORT_SYMBOL vmlinux 0xa9e316be xfrm_policy_alloc +EXPORT_SYMBOL vmlinux 0xa9e56605 set_irq_chip +EXPORT_SYMBOL vmlinux 0xa9ec36e7 bdev_read_only +EXPORT_SYMBOL vmlinux 0xa9fcf31d wait_for_completion_interruptible +EXPORT_SYMBOL vmlinux 0xaa024146 sonet_copy_stats +EXPORT_SYMBOL vmlinux 0xaa0fdf9f deregister_atm_ioctl +EXPORT_SYMBOL vmlinux 0xaa36d9d0 elv_abort_queue +EXPORT_SYMBOL vmlinux 0xaa54ca9e hci_send_sco +EXPORT_SYMBOL vmlinux 0xaa84a8ae acpi_processor_power_init_bm_check +EXPORT_SYMBOL vmlinux 0xaa8ab19e cpu_online_map +EXPORT_SYMBOL vmlinux 0xaa8c439b create_empty_buffers +EXPORT_SYMBOL vmlinux 0xaa9295bd block_is_partially_uptodate +EXPORT_SYMBOL vmlinux 0xaab06af8 _write_lock_irqsave +EXPORT_SYMBOL vmlinux 0xaadf7733 inet_sendmsg +EXPORT_SYMBOL vmlinux 0xaae8ab0e acpi_bus_power_manageable +EXPORT_SYMBOL vmlinux 0xaaee4400 inet6_add_protocol +EXPORT_SYMBOL vmlinux 0xaafdc258 strcasecmp +EXPORT_SYMBOL vmlinux 0xaaffb9a5 acpi_bus_private_data_handler +EXPORT_SYMBOL vmlinux 0xab2d19b3 find_get_page +EXPORT_SYMBOL vmlinux 0xab471003 param_array_set +EXPORT_SYMBOL vmlinux 0xab600421 probe_irq_off +EXPORT_SYMBOL vmlinux 0xab65ed80 set_memory_uc +EXPORT_SYMBOL vmlinux 0xab6c8a25 ip_ct_attach +EXPORT_SYMBOL vmlinux 0xab87714f get_sb_bdev +EXPORT_SYMBOL vmlinux 0xab970259 __skb_checksum_complete_head +EXPORT_SYMBOL vmlinux 0xaba9ff34 allocate_resource +EXPORT_SYMBOL vmlinux 0xabbb29fe scsi_get_host_dev +EXPORT_SYMBOL vmlinux 0xabd0c91c rtc_time_to_tm +EXPORT_SYMBOL vmlinux 0xabe084bc tty_schedule_flip +EXPORT_SYMBOL vmlinux 0xabe85a21 idr_init +EXPORT_SYMBOL vmlinux 0xac0bbfa8 _proxy_pda +EXPORT_SYMBOL vmlinux 0xac11a968 serio_close +EXPORT_SYMBOL vmlinux 0xac383451 radix_tree_tag_clear +EXPORT_SYMBOL vmlinux 0xac3b3cee __bitmap_and +EXPORT_SYMBOL vmlinux 0xac58ea5e acpi_unload_table_id +EXPORT_SYMBOL vmlinux 0xac7eb238 bdi_register +EXPORT_SYMBOL vmlinux 0xaccabc6a in4_pton +EXPORT_SYMBOL vmlinux 0xacd30a5b phy_stop_interrupts +EXPORT_SYMBOL vmlinux 0xacf4d843 match_strdup +EXPORT_SYMBOL vmlinux 0xad0413d4 match_hex +EXPORT_SYMBOL vmlinux 0xad0541b1 jbd2_journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0xad055bab simple_pin_fs +EXPORT_SYMBOL vmlinux 0xad13c689 acpi_os_execute +EXPORT_SYMBOL vmlinux 0xad25fb12 __memcpy +EXPORT_SYMBOL vmlinux 0xad5c03e2 xfrm_dst_ifdown +EXPORT_SYMBOL vmlinux 0xad7bb63e vm_insert_mixed +EXPORT_SYMBOL vmlinux 0xad8de1b3 acpi_remove_address_space_handler +EXPORT_SYMBOL vmlinux 0xada74d83 blk_cleanup_queue +EXPORT_SYMBOL vmlinux 0xadaa2657 cpufreq_register_notifier +EXPORT_SYMBOL vmlinux 0xadfdff51 scsi_add_host +EXPORT_SYMBOL vmlinux 0xae37c90a sk_receive_skb +EXPORT_SYMBOL vmlinux 0xae51e575 tcf_register_action +EXPORT_SYMBOL vmlinux 0xae699019 mpage_readpage +EXPORT_SYMBOL vmlinux 0xae944cc6 tty_vhangup +EXPORT_SYMBOL vmlinux 0xaeef6127 ipv6_push_nfrag_opts +EXPORT_SYMBOL vmlinux 0xaef14b23 scsi_eh_finish_cmd +EXPORT_SYMBOL vmlinux 0xaf21f3d5 tty_chars_in_buffer +EXPORT_SYMBOL vmlinux 0xaf300f21 __mark_inode_dirty +EXPORT_SYMBOL vmlinux 0xaf33e2ee alloc_hippi_dev +EXPORT_SYMBOL vmlinux 0xaf3dd7dc scsi_logging_level +EXPORT_SYMBOL vmlinux 0xaf52c2d3 iommu_bio_merge +EXPORT_SYMBOL vmlinux 0xaf5814cc jbd2_journal_release_buffer +EXPORT_SYMBOL vmlinux 0xaf5c7784 __inc_zone_page_state +EXPORT_SYMBOL vmlinux 0xaf74f3ef follow_up +EXPORT_SYMBOL vmlinux 0xafa6ce93 security_sb_clone_mnt_opts +EXPORT_SYMBOL vmlinux 0xafe82e10 strcspn +EXPORT_SYMBOL vmlinux 0xb0001805 __fatal_signal_pending +EXPORT_SYMBOL vmlinux 0xb04ea8f0 agp_rebind_memory +EXPORT_SYMBOL vmlinux 0xb051909f ida_init +EXPORT_SYMBOL vmlinux 0xb05b24a5 unregister_con_driver +EXPORT_SYMBOL vmlinux 0xb05ec98c proc_net_netfilter +EXPORT_SYMBOL vmlinux 0xb06c7521 save_mount_options +EXPORT_SYMBOL vmlinux 0xb075a606 bfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0xb0785e3e fddi_type_trans +EXPORT_SYMBOL vmlinux 0xb0791c14 inode_sub_bytes +EXPORT_SYMBOL vmlinux 0xb07dfb3d acpi_remove_gpe_handler +EXPORT_SYMBOL vmlinux 0xb0a2c5e5 scsi_scan_target +EXPORT_SYMBOL vmlinux 0xb0ae0184 skb_trim +EXPORT_SYMBOL vmlinux 0xb0ae91e7 vfs_quota_off +EXPORT_SYMBOL vmlinux 0xb0b847ac __bitmap_full +EXPORT_SYMBOL vmlinux 0xb0e10781 get_option +EXPORT_SYMBOL vmlinux 0xb0fb30ce set_trace_device +EXPORT_SYMBOL vmlinux 0xb116807f vfs_lstat +EXPORT_SYMBOL vmlinux 0xb11740f6 fasync_helper +EXPORT_SYMBOL vmlinux 0xb11fa1ce strlcat +EXPORT_SYMBOL vmlinux 0xb121390a probe_irq_on +EXPORT_SYMBOL vmlinux 0xb1304af4 netlink_broadcast +EXPORT_SYMBOL vmlinux 0xb1375dae hci_alloc_dev +EXPORT_SYMBOL vmlinux 0xb150f6d4 tty_throttle +EXPORT_SYMBOL vmlinux 0xb1645a2e sg_free_table +EXPORT_SYMBOL vmlinux 0xb1795d55 tty_check_change +EXPORT_SYMBOL vmlinux 0xb18e02c3 radix_tree_gang_lookup_tag +EXPORT_SYMBOL vmlinux 0xb18f0114 pci_bus_assign_resources +EXPORT_SYMBOL vmlinux 0xb19760c3 bitmap_onto +EXPORT_SYMBOL vmlinux 0xb1bdd82c journal_abort +EXPORT_SYMBOL vmlinux 0xb1c3a01a oops_in_progress +EXPORT_SYMBOL vmlinux 0xb1cfad22 rdmsr_on_cpu +EXPORT_SYMBOL vmlinux 0xb1f975aa unlock_kernel +EXPORT_SYMBOL vmlinux 0xb2017c1d per_cpu__x86_bios_cpu_apicid +EXPORT_SYMBOL vmlinux 0xb2042a1c input_register_handle +EXPORT_SYMBOL vmlinux 0xb2218099 md_unregister_thread +EXPORT_SYMBOL vmlinux 0xb22fe6a3 netdev_increment_features +EXPORT_SYMBOL vmlinux 0xb2386228 ethtool_op_set_ufo +EXPORT_SYMBOL vmlinux 0xb2434461 dev_unicast_delete +EXPORT_SYMBOL vmlinux 0xb24d2ba8 udp_lib_get_port +EXPORT_SYMBOL vmlinux 0xb257462c arp_send +EXPORT_SYMBOL vmlinux 0xb25a953c vfs_readlink +EXPORT_SYMBOL vmlinux 0xb26e28aa update_region +EXPORT_SYMBOL vmlinux 0xb279da12 pv_lock_ops +EXPORT_SYMBOL vmlinux 0xb280bd34 splice_direct_to_actor +EXPORT_SYMBOL vmlinux 0xb289b39d skb_kill_datagram +EXPORT_SYMBOL vmlinux 0xb2ab43ab kobject_put +EXPORT_SYMBOL vmlinux 0xb2be638a dma_chan_cleanup +EXPORT_SYMBOL vmlinux 0xb2fd5ceb __put_user_4 +EXPORT_SYMBOL vmlinux 0xb308bdb2 register_quota_format +EXPORT_SYMBOL vmlinux 0xb309f141 sk_stream_wait_close +EXPORT_SYMBOL vmlinux 0xb3205415 wait_for_completion_killable +EXPORT_SYMBOL vmlinux 0xb3284531 acpi_dbg_layer +EXPORT_SYMBOL vmlinux 0xb3318ded __down_read_trylock +EXPORT_SYMBOL vmlinux 0xb34ca107 xfrm4_rcv +EXPORT_SYMBOL vmlinux 0xb34d4c2e acpi_terminate +EXPORT_SYMBOL vmlinux 0xb352177e find_first_bit +EXPORT_SYMBOL vmlinux 0xb3650126 sk_stop_timer +EXPORT_SYMBOL vmlinux 0xb3692eb4 ioremap_wc +EXPORT_SYMBOL vmlinux 0xb37f2355 xfrm_policy_byid +EXPORT_SYMBOL vmlinux 0xb3a307c6 si_meminfo +EXPORT_SYMBOL vmlinux 0xb3bdd9d5 skb_put +EXPORT_SYMBOL vmlinux 0xb3d8772c rfkill_free +EXPORT_SYMBOL vmlinux 0xb3dda100 neigh_event_ns +EXPORT_SYMBOL vmlinux 0xb3e78a43 ndisc_mc_map +EXPORT_SYMBOL vmlinux 0xb3ee5fe0 file_fsync +EXPORT_SYMBOL vmlinux 0xb3fcf014 blk_queue_max_segment_size +EXPORT_SYMBOL vmlinux 0xb3ff1f69 free_pages_exact +EXPORT_SYMBOL vmlinux 0xb40940bd ipv6_getsockopt +EXPORT_SYMBOL vmlinux 0xb423dba1 console_blanked +EXPORT_SYMBOL vmlinux 0xb436fe32 phy_start_interrupts +EXPORT_SYMBOL vmlinux 0xb45b24f6 k8_nb_ids +EXPORT_SYMBOL vmlinux 0xb47c38bc bt_sock_recvmsg +EXPORT_SYMBOL vmlinux 0xb494e82a br_fdb_put_hook +EXPORT_SYMBOL vmlinux 0xb4a452fc __bio_clone +EXPORT_SYMBOL vmlinux 0xb4b8594f seq_bitmap_list +EXPORT_SYMBOL vmlinux 0xb4ca9447 __kfifo_get +EXPORT_SYMBOL vmlinux 0xb4dea094 tty_kref_put +EXPORT_SYMBOL vmlinux 0xb5044271 vsscanf +EXPORT_SYMBOL vmlinux 0xb528a386 xfrm_policy_destroy +EXPORT_SYMBOL vmlinux 0xb54533f7 usecs_to_jiffies +EXPORT_SYMBOL vmlinux 0xb54a7690 input_grab_device +EXPORT_SYMBOL vmlinux 0xb55df41b search_binary_handler +EXPORT_SYMBOL vmlinux 0xb5a459dc unregister_blkdev +EXPORT_SYMBOL vmlinux 0xb5aaa798 __pci_register_driver +EXPORT_SYMBOL vmlinux 0xb5c0dd82 vfs_get_dqinfo +EXPORT_SYMBOL vmlinux 0xb5ca1c46 slhc_free +EXPORT_SYMBOL vmlinux 0xb5d52c27 ec_transaction +EXPORT_SYMBOL vmlinux 0xb5f28b5f __any_online_cpu +EXPORT_SYMBOL vmlinux 0xb5f96f10 kill_litter_super +EXPORT_SYMBOL vmlinux 0xb6067cfa register_sysctl_paths +EXPORT_SYMBOL vmlinux 0xb60e34a8 nla_memcpy +EXPORT_SYMBOL vmlinux 0xb6110715 f_setown +EXPORT_SYMBOL vmlinux 0xb6244511 sg_init_one +EXPORT_SYMBOL vmlinux 0xb65be0f9 kmem_cache_alloc +EXPORT_SYMBOL vmlinux 0xb678366f int_sqrt +EXPORT_SYMBOL vmlinux 0xb6a61a86 qdisc_get_rtab +EXPORT_SYMBOL vmlinux 0xb6bfc512 journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0xb6c25f65 elv_rb_add +EXPORT_SYMBOL vmlinux 0xb6c5a973 scsi_show_result +EXPORT_SYMBOL vmlinux 0xb6e227aa rtc_lock +EXPORT_SYMBOL vmlinux 0xb6ec9e2c ethtool_op_get_ufo +EXPORT_SYMBOL vmlinux 0xb6ee6e69 neigh_lookup +EXPORT_SYMBOL vmlinux 0xb70154af dm_table_put +EXPORT_SYMBOL vmlinux 0xb714a981 console_print +EXPORT_SYMBOL vmlinux 0xb7555f12 timeval_to_jiffies +EXPORT_SYMBOL vmlinux 0xb758b225 acpi_disable_event +EXPORT_SYMBOL vmlinux 0xb77093c7 tcf_exts_dump +EXPORT_SYMBOL vmlinux 0xb784680e __neigh_for_each_release +EXPORT_SYMBOL vmlinux 0xb796cb09 struct_module +EXPORT_SYMBOL vmlinux 0xb79e590d nla_reserve +EXPORT_SYMBOL vmlinux 0xb7bd9886 __nla_put_nohdr +EXPORT_SYMBOL vmlinux 0xb7ee3f25 inet_frag_destroy +EXPORT_SYMBOL vmlinux 0xb7f53e88 pci_back_from_sleep +EXPORT_SYMBOL vmlinux 0xb81be4b7 phy_scan_fixups +EXPORT_SYMBOL vmlinux 0xb828c786 per_cpu__cpu_sibling_map +EXPORT_SYMBOL vmlinux 0xb86e4ab9 random32 +EXPORT_SYMBOL vmlinux 0xb88200fe skb_queue_tail +EXPORT_SYMBOL vmlinux 0xb8837d21 may_umount +EXPORT_SYMBOL vmlinux 0xb89af9bf srandom32 +EXPORT_SYMBOL vmlinux 0xb8b2d731 sg_miter_stop +EXPORT_SYMBOL vmlinux 0xb8d21fab d_lookup +EXPORT_SYMBOL vmlinux 0xb8e7ce2c __put_user_8 +EXPORT_SYMBOL vmlinux 0xb8f9cb1f pci_fixup_device +EXPORT_SYMBOL vmlinux 0xb905ad82 icmpv6_err_convert +EXPORT_SYMBOL vmlinux 0xb93e59e4 con_is_bound +EXPORT_SYMBOL vmlinux 0xb93fc0fe llc_sap_find +EXPORT_SYMBOL vmlinux 0xb95455c8 mapping_tagged +EXPORT_SYMBOL vmlinux 0xb9767d21 pnp_device_attach +EXPORT_SYMBOL vmlinux 0xb976e30a call_usermodehelper_setkeys +EXPORT_SYMBOL vmlinux 0xb9805b0c down_read_trylock +EXPORT_SYMBOL vmlinux 0xb98a0185 rtc_tm_to_time +EXPORT_SYMBOL vmlinux 0xb9b2be81 dst_destroy +EXPORT_SYMBOL vmlinux 0xb9bbe97d pci_scan_bridge +EXPORT_SYMBOL vmlinux 0xb9c74bf1 gen_kill_estimator +EXPORT_SYMBOL vmlinux 0xb9df6c28 phy_print_status +EXPORT_SYMBOL vmlinux 0xb9e6d1de pci_disable_device +EXPORT_SYMBOL vmlinux 0xb9ea1ec5 __sk_mem_reclaim +EXPORT_SYMBOL vmlinux 0xb9fd2205 add_efi_memmap +EXPORT_SYMBOL vmlinux 0xba1b6524 netdev_bonding_change +EXPORT_SYMBOL vmlinux 0xba2d8594 ec_read +EXPORT_SYMBOL vmlinux 0xba33d601 kmem_cache_destroy +EXPORT_SYMBOL vmlinux 0xba36d7e8 bio_integrity_free +EXPORT_SYMBOL vmlinux 0xba497f13 loops_per_jiffy +EXPORT_SYMBOL vmlinux 0xba56154c iov_iter_copy_from_user_atomic +EXPORT_SYMBOL vmlinux 0xba62bbc4 user_revoke +EXPORT_SYMBOL vmlinux 0xba86d0b4 mmc_register_driver +EXPORT_SYMBOL vmlinux 0xba8c9abd __f_setown +EXPORT_SYMBOL vmlinux 0xbaa2782a kstrndup +EXPORT_SYMBOL vmlinux 0xbaa688af sock_i_uid +EXPORT_SYMBOL vmlinux 0xbaa79c56 devm_ioport_map +EXPORT_SYMBOL vmlinux 0xbb077485 netlink_kernel_create +EXPORT_SYMBOL vmlinux 0xbb167766 fb_var_to_videomode +EXPORT_SYMBOL vmlinux 0xbb189cad disallow_signal +EXPORT_SYMBOL vmlinux 0xbb1acde6 i2c_smbus_write_byte +EXPORT_SYMBOL vmlinux 0xbb2419ad check_disk_size_change +EXPORT_SYMBOL vmlinux 0xbb32da64 mb_cache_create +EXPORT_SYMBOL vmlinux 0xbb486510 invalidate_inode_buffers +EXPORT_SYMBOL vmlinux 0xbb5ad1c4 unregister_binfmt +EXPORT_SYMBOL vmlinux 0xbb5d343d xfrm_get_acqseq +EXPORT_SYMBOL vmlinux 0xbb654e6b blk_insert_request +EXPORT_SYMBOL vmlinux 0xbb83bd29 xfrm_cfg_mutex +EXPORT_SYMBOL vmlinux 0xbba4a94d i2c_smbus_read_i2c_block_data +EXPORT_SYMBOL vmlinux 0xbba90b28 nla_put +EXPORT_SYMBOL vmlinux 0xbbc8e804 param_set_ushort +EXPORT_SYMBOL vmlinux 0xbbed86c4 journal_wipe +EXPORT_SYMBOL vmlinux 0xbc05a109 scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0xbc158c67 skb_copy_and_csum_datagram_iovec +EXPORT_SYMBOL vmlinux 0xbc54e13f scsi_device_lookup +EXPORT_SYMBOL vmlinux 0xbc554353 neigh_parms_release +EXPORT_SYMBOL vmlinux 0xbc9bd27a end_buffer_write_sync +EXPORT_SYMBOL vmlinux 0xbcc308bb strnlen_user +EXPORT_SYMBOL vmlinux 0xbcc935d2 dmam_free_noncoherent +EXPORT_SYMBOL vmlinux 0xbccbb49c idr_remove_all +EXPORT_SYMBOL vmlinux 0xbce63187 bio_integrity_clone +EXPORT_SYMBOL vmlinux 0xbcf148cf inet_frag_evictor +EXPORT_SYMBOL vmlinux 0xbcfe2fab journal_start_commit +EXPORT_SYMBOL vmlinux 0xbd11ff69 compat_ipv6_setsockopt +EXPORT_SYMBOL vmlinux 0xbd28924c scsi_eh_restore_cmnd +EXPORT_SYMBOL vmlinux 0xbd2b113b flock_lock_file_wait +EXPORT_SYMBOL vmlinux 0xbd711923 jbd2_journal_abort +EXPORT_SYMBOL vmlinux 0xbdaf5b07 acpi_os_read_port +EXPORT_SYMBOL vmlinux 0xbdc5bbc7 mnt_unpin +EXPORT_SYMBOL vmlinux 0xbdede79e blk_complete_request +EXPORT_SYMBOL vmlinux 0xbe01692e make_EII_client +EXPORT_SYMBOL vmlinux 0xbe108647 input_flush_device +EXPORT_SYMBOL vmlinux 0xbe3f9941 xfrm_register_type +EXPORT_SYMBOL vmlinux 0xbe499d81 copy_to_user +EXPORT_SYMBOL vmlinux 0xbea3ff0e compat_tcp_getsockopt +EXPORT_SYMBOL vmlinux 0xbeac8776 freeze_bdev +EXPORT_SYMBOL vmlinux 0xbecdce74 ida_pre_get +EXPORT_SYMBOL vmlinux 0xbeeb4d65 bt_accept_unlink +EXPORT_SYMBOL vmlinux 0xbef43296 console_conditional_schedule +EXPORT_SYMBOL vmlinux 0xbefe75b8 __inet6_hash +EXPORT_SYMBOL vmlinux 0xbefee397 acpi_get_object_info +EXPORT_SYMBOL vmlinux 0xbf00b52c neigh_create +EXPORT_SYMBOL vmlinux 0xbf34369c fsync_bdev +EXPORT_SYMBOL vmlinux 0xbf5b12b9 inode_get_bytes +EXPORT_SYMBOL vmlinux 0xbf7bca92 pci_choose_state +EXPORT_SYMBOL vmlinux 0xbf7fd2f5 schedule_timeout_killable +EXPORT_SYMBOL vmlinux 0xbf9bcc8d __cap_empty_set +EXPORT_SYMBOL vmlinux 0xbfb4df47 task_pgrp_nr_ns +EXPORT_SYMBOL vmlinux 0xbfc177bc iowrite32_rep +EXPORT_SYMBOL vmlinux 0xbfcc3a51 wait_on_sync_kiocb +EXPORT_SYMBOL vmlinux 0xbfe258d9 cdrom_ioctl +EXPORT_SYMBOL vmlinux 0xbfee3ad5 loop_unregister_transfer +EXPORT_SYMBOL vmlinux 0xc000d51e journal_release_buffer +EXPORT_SYMBOL vmlinux 0xc003c637 __strncpy_from_user +EXPORT_SYMBOL vmlinux 0xc01400fd icmpv6_send +EXPORT_SYMBOL vmlinux 0xc018d2de user_path_at +EXPORT_SYMBOL vmlinux 0xc03c64d6 module_put +EXPORT_SYMBOL vmlinux 0xc03d95cb journal_set_features +EXPORT_SYMBOL vmlinux 0xc045ad4e timespec_trunc +EXPORT_SYMBOL vmlinux 0xc0487f56 phy_driver_unregister +EXPORT_SYMBOL vmlinux 0xc0580937 rb_erase +EXPORT_SYMBOL vmlinux 0xc0608429 seq_escape +EXPORT_SYMBOL vmlinux 0xc06a4103 inet_csk_reset_keepalive_timer +EXPORT_SYMBOL vmlinux 0xc07a3759 scsi_host_put +EXPORT_SYMBOL vmlinux 0xc07ba03a agp_generic_alloc_pages +EXPORT_SYMBOL vmlinux 0xc07d43ae acpi_evaluate_reference +EXPORT_SYMBOL vmlinux 0xc09651d9 crc32_be +EXPORT_SYMBOL vmlinux 0xc0a3d105 find_next_bit +EXPORT_SYMBOL vmlinux 0xc0bc1c94 unregister_8022_client +EXPORT_SYMBOL vmlinux 0xc0d7fa39 pci_iomap +EXPORT_SYMBOL vmlinux 0xc0f10839 kill_fasync +EXPORT_SYMBOL vmlinux 0xc0f48608 xfrm_policy_unregister_afinfo +EXPORT_SYMBOL vmlinux 0xc13d6cec ethtool_op_get_flags +EXPORT_SYMBOL vmlinux 0xc13d7e4c __downgrade_write +EXPORT_SYMBOL vmlinux 0xc16a9eaf skb_dma_map +EXPORT_SYMBOL vmlinux 0xc17fc9f1 vfs_quota_on +EXPORT_SYMBOL vmlinux 0xc1870b62 scm_fp_dup +EXPORT_SYMBOL vmlinux 0xc1a3bd46 inet_twsk_deschedule +EXPORT_SYMBOL vmlinux 0xc1cda2fa sk_alloc +EXPORT_SYMBOL vmlinux 0xc1e5799b unload_nls +EXPORT_SYMBOL vmlinux 0xc2066af0 batostr +EXPORT_SYMBOL vmlinux 0xc21cc374 pcim_iomap +EXPORT_SYMBOL vmlinux 0xc22fba54 vfs_quota_on_mount +EXPORT_SYMBOL vmlinux 0xc23ff1c2 task_nice +EXPORT_SYMBOL vmlinux 0xc2424641 agp3_generic_cleanup +EXPORT_SYMBOL vmlinux 0xc254af48 dcache_lock +EXPORT_SYMBOL vmlinux 0xc256e762 __bitmap_equal +EXPORT_SYMBOL vmlinux 0xc281d33e tty_unregister_device +EXPORT_SYMBOL vmlinux 0xc287c44a tcf_em_tree_dump +EXPORT_SYMBOL vmlinux 0xc2aaa3e4 pcim_iomap_regions_request_all +EXPORT_SYMBOL vmlinux 0xc2c1f483 agp_enable +EXPORT_SYMBOL vmlinux 0xc2c8d899 register_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0xc2c95270 pnp_start_dev +EXPORT_SYMBOL vmlinux 0xc2d027f1 generic_show_options +EXPORT_SYMBOL vmlinux 0xc2d12b59 blk_alloc_queue +EXPORT_SYMBOL vmlinux 0xc2d1f126 proc_dointvec_minmax +EXPORT_SYMBOL vmlinux 0xc2da3f7d in_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0xc2e587d1 reset_devices +EXPORT_SYMBOL vmlinux 0xc31b077a dquot_commit_info +EXPORT_SYMBOL vmlinux 0xc33f6f4c on_each_cpu +EXPORT_SYMBOL vmlinux 0xc340960a swiotlb_sync_sg_for_cpu +EXPORT_SYMBOL vmlinux 0xc3aaf0a9 __put_user_1 +EXPORT_SYMBOL vmlinux 0xc3d96c18 netpoll_poll +EXPORT_SYMBOL vmlinux 0xc3df7a86 posix_acl_permission +EXPORT_SYMBOL vmlinux 0xc402cc99 register_acpi_notifier +EXPORT_SYMBOL vmlinux 0xc41d175f kset_register +EXPORT_SYMBOL vmlinux 0xc438bf18 cdrom_media_changed +EXPORT_SYMBOL vmlinux 0xc47c2497 do_splice_from +EXPORT_SYMBOL vmlinux 0xc4925812 pci_map_rom +EXPORT_SYMBOL vmlinux 0xc4945d6c inode_setattr +EXPORT_SYMBOL vmlinux 0xc499ae1e kstrdup +EXPORT_SYMBOL vmlinux 0xc4a182bc skb_copy_datagram_from_iovec +EXPORT_SYMBOL vmlinux 0xc4b1b4be skb_copy_and_csum_bits +EXPORT_SYMBOL vmlinux 0xc4d489e9 up_write +EXPORT_SYMBOL vmlinux 0xc4e96d83 jbd2_journal_restart +EXPORT_SYMBOL vmlinux 0xc4ec3bad end_page_writeback +EXPORT_SYMBOL vmlinux 0xc52f5714 fb_videomode_to_var +EXPORT_SYMBOL vmlinux 0xc535491a generic_setxattr +EXPORT_SYMBOL vmlinux 0xc5382659 journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0xc53c882d idr_get_new +EXPORT_SYMBOL vmlinux 0xc53f90a2 devm_free_irq +EXPORT_SYMBOL vmlinux 0xc5534d64 ioread16 +EXPORT_SYMBOL vmlinux 0xc558530d profile_pc +EXPORT_SYMBOL vmlinux 0xc55f7dc7 _write_trylock +EXPORT_SYMBOL vmlinux 0xc561998e con_set_default_unimap +EXPORT_SYMBOL vmlinux 0xc5681b61 mb_cache_entry_free +EXPORT_SYMBOL vmlinux 0xc5708a48 vfs_writev +EXPORT_SYMBOL vmlinux 0xc58d8b08 d_path +EXPORT_SYMBOL vmlinux 0xc593b275 neigh_seq_stop +EXPORT_SYMBOL vmlinux 0xc59de455 put_disk +EXPORT_SYMBOL vmlinux 0xc5a06657 textsearch_register +EXPORT_SYMBOL vmlinux 0xc5cc8c81 proc_create_data +EXPORT_SYMBOL vmlinux 0xc5d9c46c agp_try_unsupported_boot +EXPORT_SYMBOL vmlinux 0xc5de555b input_register_device +EXPORT_SYMBOL vmlinux 0xc65abeb7 agp3_generic_sizes +EXPORT_SYMBOL vmlinux 0xc65ce1b2 swiotlb_unmap_single_attrs +EXPORT_SYMBOL vmlinux 0xc68944ce swiotlb_dma_supported +EXPORT_SYMBOL vmlinux 0xc6dfe13a skb_find_text +EXPORT_SYMBOL vmlinux 0xc6e40edb journal_dirty_data +EXPORT_SYMBOL vmlinux 0xc6fe73e3 pci_bus_size_bridges +EXPORT_SYMBOL vmlinux 0xc7190107 inet_addr_type +EXPORT_SYMBOL vmlinux 0xc71f58c0 scsi_device_get +EXPORT_SYMBOL vmlinux 0xc7200d2b set_binfmt +EXPORT_SYMBOL vmlinux 0xc7208c3a serial8250_resume_port +EXPORT_SYMBOL vmlinux 0xc740c64a memchr +EXPORT_SYMBOL vmlinux 0xc78cf944 generic_block_fiemap +EXPORT_SYMBOL vmlinux 0xc7911d30 bitmap_start_sync +EXPORT_SYMBOL vmlinux 0xc79bcd36 dm_vcalloc +EXPORT_SYMBOL vmlinux 0xc7a24d76 sysfs_format_mac +EXPORT_SYMBOL vmlinux 0xc7a4fbed rtnl_lock +EXPORT_SYMBOL vmlinux 0xc7bad7d4 sk_common_release +EXPORT_SYMBOL vmlinux 0xc83456f9 scsi_report_device_reset +EXPORT_SYMBOL vmlinux 0xc860a3ae skb_dequeue_tail +EXPORT_SYMBOL vmlinux 0xc86249a0 dmam_alloc_noncoherent +EXPORT_SYMBOL vmlinux 0xc897c382 sg_init_table +EXPORT_SYMBOL vmlinux 0xc8a28e28 init_file +EXPORT_SYMBOL vmlinux 0xc8b165fe agp_allocate_memory +EXPORT_SYMBOL vmlinux 0xc8b57c27 autoremove_wake_function +EXPORT_SYMBOL vmlinux 0xc8c82bf2 vfs_symlink +EXPORT_SYMBOL vmlinux 0xc8ca3e25 acpi_get_child +EXPORT_SYMBOL vmlinux 0xc8dc6fb8 __blockdev_direct_IO +EXPORT_SYMBOL vmlinux 0xc8e94ef8 key_validate +EXPORT_SYMBOL vmlinux 0xc90e71f6 tcp_md5_hash_header +EXPORT_SYMBOL vmlinux 0xc93eae38 icmp_send +EXPORT_SYMBOL vmlinux 0xc9437ede __down_write_nested +EXPORT_SYMBOL vmlinux 0xc998d641 icmp_err_convert +EXPORT_SYMBOL vmlinux 0xc9997173 kmem_cache_shrink +EXPORT_SYMBOL vmlinux 0xc9ab2eef acpi_os_wait_events_complete +EXPORT_SYMBOL vmlinux 0xc9c0cd17 gnet_stats_copy_basic +EXPORT_SYMBOL vmlinux 0xca0136f2 sock_common_getsockopt +EXPORT_SYMBOL vmlinux 0xca024545 i2c_use_client +EXPORT_SYMBOL vmlinux 0xca351be8 jbd2_log_wait_commit +EXPORT_SYMBOL vmlinux 0xca4c9885 xfrm_policy_register_afinfo +EXPORT_SYMBOL vmlinux 0xca5c105a agp_create_memory +EXPORT_SYMBOL vmlinux 0xca5dbc50 scsi_print_sense_hdr +EXPORT_SYMBOL vmlinux 0xca61cf69 serio_unregister_port +EXPORT_SYMBOL vmlinux 0xca763f21 __invalidate_device +EXPORT_SYMBOL vmlinux 0xca8abced request_key_with_auxdata +EXPORT_SYMBOL vmlinux 0xca8acc78 acpi_dbg_level +EXPORT_SYMBOL vmlinux 0xcac9f3a8 journal_invalidatepage +EXPORT_SYMBOL vmlinux 0xcad4badd arch_debugfs_dir +EXPORT_SYMBOL vmlinux 0xcae54476 scsi_adjust_queue_depth +EXPORT_SYMBOL vmlinux 0xcaec4800 skb_realloc_headroom +EXPORT_SYMBOL vmlinux 0xcb090571 swiotlb_map_single +EXPORT_SYMBOL vmlinux 0xcb293d3c journal_clear_err +EXPORT_SYMBOL vmlinux 0xcb32da10 param_set_int +EXPORT_SYMBOL vmlinux 0xcb6beb40 hweight32 +EXPORT_SYMBOL vmlinux 0xcb7131fb fb_get_options +EXPORT_SYMBOL vmlinux 0xcb733bf2 acpi_bus_set_power +EXPORT_SYMBOL vmlinux 0xcbdd460c input_inject_event +EXPORT_SYMBOL vmlinux 0xcbe1eb2a eth_rebuild_header +EXPORT_SYMBOL vmlinux 0xcc07af75 strnlen +EXPORT_SYMBOL vmlinux 0xcc1fb551 baswap +EXPORT_SYMBOL vmlinux 0xcc248d26 serial8250_suspend_port +EXPORT_SYMBOL vmlinux 0xcc305a32 acpi_lock_ac_dir +EXPORT_SYMBOL vmlinux 0xcc36f32e fb_unregister_client +EXPORT_SYMBOL vmlinux 0xcc5005fe msleep_interruptible +EXPORT_SYMBOL vmlinux 0xcc51ee50 dma_spin_lock +EXPORT_SYMBOL vmlinux 0xcc6a9014 qdisc_watchdog_cancel +EXPORT_SYMBOL vmlinux 0xcc7e5f66 ____pagevec_lru_add +EXPORT_SYMBOL vmlinux 0xcc7fa952 local_bh_enable_ip +EXPORT_SYMBOL vmlinux 0xcc8e0825 journal_unlock_updates +EXPORT_SYMBOL vmlinux 0xcc923dab scsi_block_when_processing_errors +EXPORT_SYMBOL vmlinux 0xcccd73a7 generic_write_end +EXPORT_SYMBOL vmlinux 0xcce54e83 ip_defrag +EXPORT_SYMBOL vmlinux 0xcd100fa9 hci_unregister_dev +EXPORT_SYMBOL vmlinux 0xcd11c1ac generic_file_splice_write_nolock +EXPORT_SYMBOL vmlinux 0xcd3fab1e dev_mc_delete +EXPORT_SYMBOL vmlinux 0xcd478485 phy_register_fixup +EXPORT_SYMBOL vmlinux 0xce038024 tcf_hash_create +EXPORT_SYMBOL vmlinux 0xce0c313f sysctl_string +EXPORT_SYMBOL vmlinux 0xce19bac5 register_inet6addr_notifier +EXPORT_SYMBOL vmlinux 0xce1b5310 dst_discard +EXPORT_SYMBOL vmlinux 0xce36ded6 sysctl_tcp_mem +EXPORT_SYMBOL vmlinux 0xce4904a4 acpi_leave_sleep_state +EXPORT_SYMBOL vmlinux 0xce5ac24f zlib_inflate_workspacesize +EXPORT_SYMBOL vmlinux 0xce6847e3 seq_release +EXPORT_SYMBOL vmlinux 0xce72e2cc nf_unregister_queue_handler +EXPORT_SYMBOL vmlinux 0xce72e50f ip_getsockopt +EXPORT_SYMBOL vmlinux 0xced15af8 nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0xcee49ef1 dcache_dir_close +EXPORT_SYMBOL vmlinux 0xcefcd99a serial8250_unregister_port +EXPORT_SYMBOL vmlinux 0xcf0ffdcb block_truncate_page +EXPORT_SYMBOL vmlinux 0xcf35e0b8 ip_route_input +EXPORT_SYMBOL vmlinux 0xcf3d1948 tcp_hashinfo +EXPORT_SYMBOL vmlinux 0xcf447f0b scsi_report_bus_reset +EXPORT_SYMBOL vmlinux 0xcfa6a587 __netif_schedule +EXPORT_SYMBOL vmlinux 0xcfadd723 __percpu_counter_add +EXPORT_SYMBOL vmlinux 0xcfc8145d nonseekable_open +EXPORT_SYMBOL vmlinux 0xcfd3018e set_normalized_timespec +EXPORT_SYMBOL vmlinux 0xcfd3cc05 netif_receive_skb +EXPORT_SYMBOL vmlinux 0xd0037460 serio_unregister_driver +EXPORT_SYMBOL vmlinux 0xd0049e7c put_page +EXPORT_SYMBOL vmlinux 0xd0181f4f __bitmap_xor +EXPORT_SYMBOL vmlinux 0xd0291a06 proc_symlink +EXPORT_SYMBOL vmlinux 0xd02cc869 __bitmap_andnot +EXPORT_SYMBOL vmlinux 0xd05a22b6 dev_set_mtu +EXPORT_SYMBOL vmlinux 0xd06535a9 pci_assign_resource +EXPORT_SYMBOL vmlinux 0xd06cbb7f dev_get_by_flags +EXPORT_SYMBOL vmlinux 0xd073f3f9 deny_write_access +EXPORT_SYMBOL vmlinux 0xd075a790 register_8022_client +EXPORT_SYMBOL vmlinux 0xd078b53d ethtool_op_get_link +EXPORT_SYMBOL vmlinux 0xd08197fa acpi_load_tables +EXPORT_SYMBOL vmlinux 0xd08994c4 neigh_seq_start +EXPORT_SYMBOL vmlinux 0xd092912f kernel_sendpage +EXPORT_SYMBOL vmlinux 0xd0bae86f acpi_processor_notify_smm +EXPORT_SYMBOL vmlinux 0xd0cff314 scsi_allocate_command +EXPORT_SYMBOL vmlinux 0xd0ee38b8 schedule_timeout_uninterruptible +EXPORT_SYMBOL vmlinux 0xd0f67674 tty_set_operations +EXPORT_SYMBOL vmlinux 0xd0fef3b2 agp_free_key +EXPORT_SYMBOL vmlinux 0xd11504ce xfrm_prepare_input +EXPORT_SYMBOL vmlinux 0xd1460462 pci_set_dma_seg_boundary +EXPORT_SYMBOL vmlinux 0xd1472061 acpi_pci_register_driver +EXPORT_SYMBOL vmlinux 0xd15cbea6 should_remove_suid +EXPORT_SYMBOL vmlinux 0xd1626a57 register_netdev +EXPORT_SYMBOL vmlinux 0xd17b9fe6 md_done_sync +EXPORT_SYMBOL vmlinux 0xd18b6eb2 acpi_unmap_lsapic +EXPORT_SYMBOL vmlinux 0xd19bb294 acpi_install_address_space_handler +EXPORT_SYMBOL vmlinux 0xd1b5fd12 input_register_handler +EXPORT_SYMBOL vmlinux 0xd1eddd17 dev_get_flags +EXPORT_SYMBOL vmlinux 0xd1f2bdfb pfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0xd1f6c5f3 smp_num_siblings +EXPORT_SYMBOL vmlinux 0xd1f91bcd dev_base_lock +EXPORT_SYMBOL vmlinux 0xd20795bc send_sig +EXPORT_SYMBOL vmlinux 0xd24e6218 call_usermodehelper_exec +EXPORT_SYMBOL vmlinux 0xd251d7b0 security_socket_getpeersec_dgram +EXPORT_SYMBOL vmlinux 0xd2555f19 jiffies_64_to_clock_t +EXPORT_SYMBOL vmlinux 0xd25d4f74 console_blank_hook +EXPORT_SYMBOL vmlinux 0xd267d42c down_killable +EXPORT_SYMBOL vmlinux 0xd27195b6 netdev_boot_setup_check +EXPORT_SYMBOL vmlinux 0xd2965f6f kthread_should_stop +EXPORT_SYMBOL vmlinux 0xd2bb5c3c pci_lost_interrupt +EXPORT_SYMBOL vmlinux 0xd2ce4ad7 i2c_smbus_read_byte +EXPORT_SYMBOL vmlinux 0xd2f697ad input_open_device +EXPORT_SYMBOL vmlinux 0xd30d90c1 km_state_expired +EXPORT_SYMBOL vmlinux 0xd323b38a open_exec +EXPORT_SYMBOL vmlinux 0xd328f23f lookup_one_len +EXPORT_SYMBOL vmlinux 0xd334919e __page_symlink +EXPORT_SYMBOL vmlinux 0xd34f0c62 gen_pool_create +EXPORT_SYMBOL vmlinux 0xd35ee027 ipv6_skip_exthdr +EXPORT_SYMBOL vmlinux 0xd35fc5c4 dma_supported +EXPORT_SYMBOL vmlinux 0xd37a2ed6 scsi_remove_target +EXPORT_SYMBOL vmlinux 0xd3951da4 acpi_resource_to_address64 +EXPORT_SYMBOL vmlinux 0xd3b8a866 xfrm_register_km +EXPORT_SYMBOL vmlinux 0xd3c92584 block_commit_write +EXPORT_SYMBOL vmlinux 0xd3f74cf1 interruptible_sleep_on_timeout +EXPORT_SYMBOL vmlinux 0xd40525c2 pci_match_id +EXPORT_SYMBOL vmlinux 0xd41764c6 scsi_setup_blk_pc_cmnd +EXPORT_SYMBOL vmlinux 0xd42b7232 _write_unlock_bh +EXPORT_SYMBOL vmlinux 0xd42be8f2 check_disk_change +EXPORT_SYMBOL vmlinux 0xd46ca808 blk_register_region +EXPORT_SYMBOL vmlinux 0xd473160d sk_run_filter +EXPORT_SYMBOL vmlinux 0xd484f755 request_firmware_nowait +EXPORT_SYMBOL vmlinux 0xd4b95eb9 test_set_page_writeback +EXPORT_SYMBOL vmlinux 0xd4cb32db vfs_set_dqblk +EXPORT_SYMBOL vmlinux 0xd4ea959b pci_find_parent_resource +EXPORT_SYMBOL vmlinux 0xd4f240d1 key_task_permission +EXPORT_SYMBOL vmlinux 0xd5007292 tcp_enter_memory_pressure +EXPORT_SYMBOL vmlinux 0xd507cf7c journal_revoke +EXPORT_SYMBOL vmlinux 0xd5263820 mb_cache_destroy +EXPORT_SYMBOL vmlinux 0xd53694b3 dm_dirty_log_type_unregister +EXPORT_SYMBOL vmlinux 0xd53aec49 cpu_possible_map +EXPORT_SYMBOL vmlinux 0xd5538cdf tcp_v4_syn_recv_sock +EXPORT_SYMBOL vmlinux 0xd55ba1e7 dentry_unhash +EXPORT_SYMBOL vmlinux 0xd56ce68b bio_integrity_split +EXPORT_SYMBOL vmlinux 0xd57f8789 iommu_num_pages +EXPORT_SYMBOL vmlinux 0xd5835f11 blk_recount_segments +EXPORT_SYMBOL vmlinux 0xd58d0c54 agp_put_bridge +EXPORT_SYMBOL vmlinux 0xd5ae76e4 generic_splice_sendpage +EXPORT_SYMBOL vmlinux 0xd5b037e1 kref_put +EXPORT_SYMBOL vmlinux 0xd5c54f65 journal_force_commit +EXPORT_SYMBOL vmlinux 0xd6035d05 do_settimeofday +EXPORT_SYMBOL vmlinux 0xd60d7af4 ida_remove +EXPORT_SYMBOL vmlinux 0xd61b8b2a agp_copy_info +EXPORT_SYMBOL vmlinux 0xd62c833f schedule_timeout +EXPORT_SYMBOL vmlinux 0xd6486a5a md_wakeup_thread +EXPORT_SYMBOL vmlinux 0xd64a0cf9 simple_dir_operations +EXPORT_SYMBOL vmlinux 0xd659923a ip_mc_rejoin_group +EXPORT_SYMBOL vmlinux 0xd692b34f mdiobus_free +EXPORT_SYMBOL vmlinux 0xd696c85a bio_integrity_trim +EXPORT_SYMBOL vmlinux 0xd6a78d08 smp_call_function_single +EXPORT_SYMBOL vmlinux 0xd6b33026 cpu_khz +EXPORT_SYMBOL vmlinux 0xd6d11ecc tcp_init_xmit_timers +EXPORT_SYMBOL vmlinux 0xd6ee688f vmalloc +EXPORT_SYMBOL vmlinux 0xd6f453ea skb_dequeue +EXPORT_SYMBOL vmlinux 0xd72f8cac filemap_flush +EXPORT_SYMBOL vmlinux 0xd78ee65a tcp_splice_read +EXPORT_SYMBOL vmlinux 0xd791c500 skb_recv_datagram +EXPORT_SYMBOL vmlinux 0xd79b5a02 allow_signal +EXPORT_SYMBOL vmlinux 0xd7a69233 __alloc_pages_internal +EXPORT_SYMBOL vmlinux 0xd7a6fafa panic_notifier_list +EXPORT_SYMBOL vmlinux 0xd7caadc8 register_snap_client +EXPORT_SYMBOL vmlinux 0xd7dd777b reserve_perfctr_nmi +EXPORT_SYMBOL vmlinux 0xd7e48b73 kset_unregister +EXPORT_SYMBOL vmlinux 0xd7ee54a9 dm_kcopyd_client_destroy +EXPORT_SYMBOL vmlinux 0xd7f979cd __scsi_iterate_devices +EXPORT_SYMBOL vmlinux 0xd8007933 pci_disable_msix +EXPORT_SYMBOL vmlinux 0xd80c2bbf inet6_bind +EXPORT_SYMBOL vmlinux 0xd810ede5 jbd2_journal_init_inode +EXPORT_SYMBOL vmlinux 0xd833bcdf task_pid_nr_ns +EXPORT_SYMBOL vmlinux 0xd88f695a __mod_timer +EXPORT_SYMBOL vmlinux 0xd89da37f movable_zone +EXPORT_SYMBOL vmlinux 0xd8a56ae0 ip_xfrm_me_harder +EXPORT_SYMBOL vmlinux 0xd8b661ec cdev_del +EXPORT_SYMBOL vmlinux 0xd8bd192b tcp_proc_unregister +EXPORT_SYMBOL vmlinux 0xd8e484f0 register_chrdev_region +EXPORT_SYMBOL vmlinux 0xd901c5c8 sync_page_range_nolock +EXPORT_SYMBOL vmlinux 0xd9091363 acpi_install_notify_handler +EXPORT_SYMBOL vmlinux 0xd9222286 generic_file_buffered_write +EXPORT_SYMBOL vmlinux 0xd9370b06 skb_dma_unmap +EXPORT_SYMBOL vmlinux 0xd985dc99 mempool_free_pages +EXPORT_SYMBOL vmlinux 0xd9a8fa31 journal_init_dev +EXPORT_SYMBOL vmlinux 0xd9c22b28 xfrm_state_add +EXPORT_SYMBOL vmlinux 0xd9c2b8c8 bio_alloc_bioset +EXPORT_SYMBOL vmlinux 0xd9e1b194 fb_get_mode +EXPORT_SYMBOL vmlinux 0xd9e8f55e __break_lease +EXPORT_SYMBOL vmlinux 0xda0a6b0e acpi_map_lsapic +EXPORT_SYMBOL vmlinux 0xda1a7335 kasprintf +EXPORT_SYMBOL vmlinux 0xda1ec81d vfs_readv +EXPORT_SYMBOL vmlinux 0xda2817d2 cdrom_mode_select +EXPORT_SYMBOL vmlinux 0xda4629e4 radix_tree_insert +EXPORT_SYMBOL vmlinux 0xda597d34 __ht_create_irq +EXPORT_SYMBOL vmlinux 0xda7ca6cb fb_mode_is_equal +EXPORT_SYMBOL vmlinux 0xda7e5443 call_usermodehelper_freeinfo +EXPORT_SYMBOL vmlinux 0xda8af7ad fb_find_nearest_mode +EXPORT_SYMBOL vmlinux 0xda928914 nmi_watchdog +EXPORT_SYMBOL vmlinux 0xda987cb8 jbd2_journal_invalidatepage +EXPORT_SYMBOL vmlinux 0xda9be667 new_inode +EXPORT_SYMBOL vmlinux 0xdaa3953a elv_rb_former_request +EXPORT_SYMBOL vmlinux 0xdacad00d uart_update_timeout +EXPORT_SYMBOL vmlinux 0xdb09b950 blk_init_tags +EXPORT_SYMBOL vmlinux 0xdb16aed4 vfs_getattr +EXPORT_SYMBOL vmlinux 0xdb22a60c i2c_master_send +EXPORT_SYMBOL vmlinux 0xdb64a569 proc_doulongvec_minmax +EXPORT_SYMBOL vmlinux 0xdb8a364a atm_init_aal5 +EXPORT_SYMBOL vmlinux 0xdbcd416e sysctl_ip_nonlocal_bind +EXPORT_SYMBOL vmlinux 0xdbef92a1 ps2_init +EXPORT_SYMBOL vmlinux 0xdc138430 skb_seq_read +EXPORT_SYMBOL vmlinux 0xdc14eda7 pci_pci_problems +EXPORT_SYMBOL vmlinux 0xdc262d6d vfs_create +EXPORT_SYMBOL vmlinux 0xdc2adb35 add_taint +EXPORT_SYMBOL vmlinux 0xdc43a9c8 daemonize +EXPORT_SYMBOL vmlinux 0xdc6242e7 agp_generic_alloc_by_type +EXPORT_SYMBOL vmlinux 0xdc696d35 dm_dirty_log_create +EXPORT_SYMBOL vmlinux 0xdc873a70 screen_info +EXPORT_SYMBOL vmlinux 0xdc93f908 acpi_bus_add +EXPORT_SYMBOL vmlinux 0xdcb0349b sys_close +EXPORT_SYMBOL vmlinux 0xdcec9299 sock_release +EXPORT_SYMBOL vmlinux 0xdd275c36 cdev_add +EXPORT_SYMBOL vmlinux 0xdd2a40ab md_write_start +EXPORT_SYMBOL vmlinux 0xdd87b8f8 ip_cmsg_recv +EXPORT_SYMBOL vmlinux 0xddc1ac11 bioset_integrity_free +EXPORT_SYMBOL vmlinux 0xddcbc04f __set_page_dirty_nobuffers +EXPORT_SYMBOL vmlinux 0xddd107d2 framebuffer_release +EXPORT_SYMBOL vmlinux 0xdde2a4da agp_bridge +EXPORT_SYMBOL vmlinux 0xddeba0e5 sg_miter_start +EXPORT_SYMBOL vmlinux 0xde0bdcff memset +EXPORT_SYMBOL vmlinux 0xde75b689 set_irq_type +EXPORT_SYMBOL vmlinux 0xde9360ba totalram_pages +EXPORT_SYMBOL vmlinux 0xde99af71 pci_get_slot +EXPORT_SYMBOL vmlinux 0xde9b17ed agp3_generic_fetch_size +EXPORT_SYMBOL vmlinux 0xdef36088 notify_change +EXPORT_SYMBOL vmlinux 0xdf0da3cc acpi_get_devices +EXPORT_SYMBOL vmlinux 0xdf3f2657 phy_enable_interrupts +EXPORT_SYMBOL vmlinux 0xdf60cc27 __print_symbol +EXPORT_SYMBOL vmlinux 0xdf8c695a __ndelay +EXPORT_SYMBOL vmlinux 0xdf929370 fs_overflowgid +EXPORT_SYMBOL vmlinux 0xdfb7bada acpi_check_resource_conflict +EXPORT_SYMBOL vmlinux 0xdfc5169b slhc_init +EXPORT_SYMBOL vmlinux 0xe001a3fb elv_rb_latter_request +EXPORT_SYMBOL vmlinux 0xe004b54e pci_find_capability +EXPORT_SYMBOL vmlinux 0xe02c04cf agp_collect_device_status +EXPORT_SYMBOL vmlinux 0xe075d6eb iter_div_u64_rem +EXPORT_SYMBOL vmlinux 0xe0939d0a iunique +EXPORT_SYMBOL vmlinux 0xe0ac8bd2 acpi_bus_generate_netlink_event +EXPORT_SYMBOL vmlinux 0xe0b13336 argv_free +EXPORT_SYMBOL vmlinux 0xe0edcf77 vmtruncate +EXPORT_SYMBOL vmlinux 0xe105ff54 eth_header_parse +EXPORT_SYMBOL vmlinux 0xe1088976 sb_min_blocksize +EXPORT_SYMBOL vmlinux 0xe1127940 tcp_ioctl +EXPORT_SYMBOL vmlinux 0xe113bbbc csum_partial +EXPORT_SYMBOL vmlinux 0xe12d6f3d pci_find_next_bus +EXPORT_SYMBOL vmlinux 0xe13cd8a7 dmi_name_in_vendors +EXPORT_SYMBOL vmlinux 0xe15148ca register_binfmt +EXPORT_SYMBOL vmlinux 0xe1605aba generic_file_splice_write +EXPORT_SYMBOL vmlinux 0xe162204a scsi_register_interface +EXPORT_SYMBOL vmlinux 0xe1761617 security_inet_conn_request +EXPORT_SYMBOL vmlinux 0xe1a81c3a icmpv6msg_statistics +EXPORT_SYMBOL vmlinux 0xe1e3c318 tcf_action_dump_1 +EXPORT_SYMBOL vmlinux 0xe1e64e24 xfrm6_rcv_spi +EXPORT_SYMBOL vmlinux 0xe1ef59aa compat_nf_getsockopt +EXPORT_SYMBOL vmlinux 0xe2029eaa pci_get_bus_and_slot +EXPORT_SYMBOL vmlinux 0xe2113040 mmc_wait_for_req +EXPORT_SYMBOL vmlinux 0xe24050c7 scnprintf +EXPORT_SYMBOL vmlinux 0xe24d3a97 jiffies_64 +EXPORT_SYMBOL vmlinux 0xe279d525 kernel_getsockname +EXPORT_SYMBOL vmlinux 0xe28ba8b0 xfrm_state_insert +EXPORT_SYMBOL vmlinux 0xe2d5255a strcmp +EXPORT_SYMBOL vmlinux 0xe2e7e025 qdisc_class_hash_grow +EXPORT_SYMBOL vmlinux 0xe351633f genl_register_family +EXPORT_SYMBOL vmlinux 0xe35ae20c generic_unplug_device +EXPORT_SYMBOL vmlinux 0xe35d843b security_d_instantiate +EXPORT_SYMBOL vmlinux 0xe36eea7b md_check_recovery +EXPORT_SYMBOL vmlinux 0xe3b0192b vscnprintf +EXPORT_SYMBOL vmlinux 0xe3b93a66 swiotlb_sync_sg_for_device +EXPORT_SYMBOL vmlinux 0xe3d0a362 del_gendisk +EXPORT_SYMBOL vmlinux 0xe3fbe148 acpi_install_table_handler +EXPORT_SYMBOL vmlinux 0xe41cac3f sock_recvmsg +EXPORT_SYMBOL vmlinux 0xe4306cc8 ip_generic_getfrag +EXPORT_SYMBOL vmlinux 0xe43617f7 acpi_gbl_FADT +EXPORT_SYMBOL vmlinux 0xe4401184 generic_file_aio_read +EXPORT_SYMBOL vmlinux 0xe44e6c70 tty_get_baud_rate +EXPORT_SYMBOL vmlinux 0xe455af6b xfrm_state_register_afinfo +EXPORT_SYMBOL vmlinux 0xe456bd3a complete +EXPORT_SYMBOL vmlinux 0xe4747346 blk_integrity_unregister +EXPORT_SYMBOL vmlinux 0xe484e35f ioread32 +EXPORT_SYMBOL vmlinux 0xe4870354 _read_trylock +EXPORT_SYMBOL vmlinux 0xe49b43e3 hci_resume_dev +EXPORT_SYMBOL vmlinux 0xe49e4b80 skb_store_bits +EXPORT_SYMBOL vmlinux 0xe49e9dbc lease_get_mtime +EXPORT_SYMBOL vmlinux 0xe4b24b8c __next_cpu +EXPORT_SYMBOL vmlinux 0xe4c1df3e _read_lock_bh +EXPORT_SYMBOL vmlinux 0xe4c9f6c2 bitmap_endwrite +EXPORT_SYMBOL vmlinux 0xe4fc93a9 bio_add_pc_page +EXPORT_SYMBOL vmlinux 0xe5122890 flow_cache_genid +EXPORT_SYMBOL vmlinux 0xe523ad75 synchronize_irq +EXPORT_SYMBOL vmlinux 0xe52947e7 __phys_addr +EXPORT_SYMBOL vmlinux 0xe537e069 x86_dma_fallback_dev +EXPORT_SYMBOL vmlinux 0xe542862a pnp_disable_dev +EXPORT_SYMBOL vmlinux 0xe54b8071 neigh_table_init_no_netlink +EXPORT_SYMBOL vmlinux 0xe56400dc sock_no_shutdown +EXPORT_SYMBOL vmlinux 0xe56d551d sync_inode +EXPORT_SYMBOL vmlinux 0xe57878a1 in6_pton +EXPORT_SYMBOL vmlinux 0xe5844107 cpu_present_map +EXPORT_SYMBOL vmlinux 0xe5867808 dlci_ioctl_set +EXPORT_SYMBOL vmlinux 0xe5982bf3 seq_putc +EXPORT_SYMBOL vmlinux 0xe599adb0 xfrm_lookup +EXPORT_SYMBOL vmlinux 0xe5c78a99 do_blank_screen +EXPORT_SYMBOL vmlinux 0xe5d16d63 d_validate +EXPORT_SYMBOL vmlinux 0xe5e44848 ps2_handle_ack +EXPORT_SYMBOL vmlinux 0xe5ed5467 xfrm_policy_walk_init +EXPORT_SYMBOL vmlinux 0xe60921f6 wireless_send_event +EXPORT_SYMBOL vmlinux 0xe6422f6f mmc_request_done +EXPORT_SYMBOL vmlinux 0xe64b0341 set_blocksize +EXPORT_SYMBOL vmlinux 0xe6537c33 udp_proc_unregister +EXPORT_SYMBOL vmlinux 0xe690b8fd __ipv6_isatap_ifid +EXPORT_SYMBOL vmlinux 0xe694cc8a set_current_groups +EXPORT_SYMBOL vmlinux 0xe6b8ef5a do_mmap_pgoff +EXPORT_SYMBOL vmlinux 0xe6bd9acf __lock_buffer +EXPORT_SYMBOL vmlinux 0xe6c545d8 elevator_exit +EXPORT_SYMBOL vmlinux 0xe6cb2f0b acpi_bus_start +EXPORT_SYMBOL vmlinux 0xe6d04f9f uart_match_port +EXPORT_SYMBOL vmlinux 0xe6d46a01 vm_insert_page +EXPORT_SYMBOL vmlinux 0xe6dadc21 kernel_setsockopt +EXPORT_SYMBOL vmlinux 0xe6e09c33 bio_alloc +EXPORT_SYMBOL vmlinux 0xe6f75785 eth_header_cache_update +EXPORT_SYMBOL vmlinux 0xe6fbe430 can_do_mlock +EXPORT_SYMBOL vmlinux 0xe70eebcc bio_clone +EXPORT_SYMBOL vmlinux 0xe716baed acpi_unregister_ioapic +EXPORT_SYMBOL vmlinux 0xe717feeb bio_put +EXPORT_SYMBOL vmlinux 0xe71cf65f sock_no_sendmsg +EXPORT_SYMBOL vmlinux 0xe720682f mb_cache_entry_insert +EXPORT_SYMBOL vmlinux 0xe725d067 pci_bus_find_capability +EXPORT_SYMBOL vmlinux 0xe74d9e50 simple_unlink +EXPORT_SYMBOL vmlinux 0xe751ba22 rfkill_allocate +EXPORT_SYMBOL vmlinux 0xe7546fa3 dmam_alloc_coherent +EXPORT_SYMBOL vmlinux 0xe76248f0 input_close_device +EXPORT_SYMBOL vmlinux 0xe76db524 ppp_output_wakeup +EXPORT_SYMBOL vmlinux 0xe78459c7 fifo_create_dflt +EXPORT_SYMBOL vmlinux 0xe79a5fe1 dma_async_client_chan_request +EXPORT_SYMBOL vmlinux 0xe7a5c0f0 register_filesystem +EXPORT_SYMBOL vmlinux 0xe7ac09c1 path_lookup +EXPORT_SYMBOL vmlinux 0xe7b486a7 free_buffer_head +EXPORT_SYMBOL vmlinux 0xe7d2aca1 security_sk_classify_flow +EXPORT_SYMBOL vmlinux 0xe7d4daac seq_list_next +EXPORT_SYMBOL vmlinux 0xe80ce219 sysctl_tcp_dma_copybreak +EXPORT_SYMBOL vmlinux 0xe81a0d7f register_cdrom +EXPORT_SYMBOL vmlinux 0xe8288225 ip_fragment +EXPORT_SYMBOL vmlinux 0xe83e789e add_to_page_cache_locked +EXPORT_SYMBOL vmlinux 0xe8413996 xfrm_register_mode +EXPORT_SYMBOL vmlinux 0xe8583614 posix_acl_from_xattr +EXPORT_SYMBOL vmlinux 0xe860edf0 remap_pfn_range +EXPORT_SYMBOL vmlinux 0xe8794ce1 slhc_toss +EXPORT_SYMBOL vmlinux 0xe8920035 jbd2_journal_init_jbd_inode +EXPORT_SYMBOL vmlinux 0xe8a3605f acpi_processor_set_thermal_limit +EXPORT_SYMBOL vmlinux 0xe8a4caa0 dump_trace +EXPORT_SYMBOL vmlinux 0xe8cd902e hweight16 +EXPORT_SYMBOL vmlinux 0xe9041e08 hci_conn_auth +EXPORT_SYMBOL vmlinux 0xe910b532 del_timer_sync +EXPORT_SYMBOL vmlinux 0xe914e41e strcpy +EXPORT_SYMBOL vmlinux 0xe9456a5a sysctl_xfrm_aevent_rseqth +EXPORT_SYMBOL vmlinux 0xe9811c0a filp_close +EXPORT_SYMBOL vmlinux 0xe981822b dec_zone_page_state +EXPORT_SYMBOL vmlinux 0xe98a4363 skb_checksum_help +EXPORT_SYMBOL vmlinux 0xe997667b wrmsr_on_cpu +EXPORT_SYMBOL vmlinux 0xe9ace35a swiotlb_unmap_sg +EXPORT_SYMBOL vmlinux 0xe9c4f355 tr_type_trans +EXPORT_SYMBOL vmlinux 0xe9c53214 set_page_dirty +EXPORT_SYMBOL vmlinux 0xea008e90 drop_super +EXPORT_SYMBOL vmlinux 0xea0a85ab blk_start_queue +EXPORT_SYMBOL vmlinux 0xea10212a int_to_scsilun +EXPORT_SYMBOL vmlinux 0xea10655a __bitmap_intersects +EXPORT_SYMBOL vmlinux 0xea147363 printk +EXPORT_SYMBOL vmlinux 0xea2085fc fput +EXPORT_SYMBOL vmlinux 0xea4f065b blk_queue_update_dma_pad +EXPORT_SYMBOL vmlinux 0xea68a449 journal_get_write_access +EXPORT_SYMBOL vmlinux 0xea6fcdaa genl_unregister_family +EXPORT_SYMBOL vmlinux 0xea757d9e inet_frags_init +EXPORT_SYMBOL vmlinux 0xea7ee743 copy_strings_kernel +EXPORT_SYMBOL vmlinux 0xea9b99ef seq_open_private +EXPORT_SYMBOL vmlinux 0xeac5f6f2 tty_insert_flip_string +EXPORT_SYMBOL vmlinux 0xeac95a1b generic_read_dir +EXPORT_SYMBOL vmlinux 0xead58fb9 print_hex_dump +EXPORT_SYMBOL vmlinux 0xead5f5ac jbd2_journal_clear_features +EXPORT_SYMBOL vmlinux 0xeae2bad8 compat_mc_setsockopt +EXPORT_SYMBOL vmlinux 0xeae3dfd6 __const_udelay +EXPORT_SYMBOL vmlinux 0xeb02b9a5 scsi_track_queue_full +EXPORT_SYMBOL vmlinux 0xeb14c77e skb_abort_seq_read +EXPORT_SYMBOL vmlinux 0xeb1fabf6 interruptible_sleep_on +EXPORT_SYMBOL vmlinux 0xeb228272 posix_acl_create_masq +EXPORT_SYMBOL vmlinux 0xeb395084 param_get_invbool +EXPORT_SYMBOL vmlinux 0xeb6137a4 swiotlb_free_coherent +EXPORT_SYMBOL vmlinux 0xeb6d94cb qdisc_calculate_pkt_len +EXPORT_SYMBOL vmlinux 0xeb7228bf qdisc_watchdog_schedule +EXPORT_SYMBOL vmlinux 0xeb72e81a default_unplug_io_fn +EXPORT_SYMBOL vmlinux 0xeb78d6c0 hci_unregister_cb +EXPORT_SYMBOL vmlinux 0xeb8f54b3 strstrip +EXPORT_SYMBOL vmlinux 0xeba1386d agp_generic_create_gatt_table +EXPORT_SYMBOL vmlinux 0xebbf1dba strncasecmp +EXPORT_SYMBOL vmlinux 0xebd273a6 strict_strtoull +EXPORT_SYMBOL vmlinux 0xebed96ac mb_cache_entry_release +EXPORT_SYMBOL vmlinux 0xebedc550 neigh_changeaddr +EXPORT_SYMBOL vmlinux 0xebf0830b unregister_netdev +EXPORT_SYMBOL vmlinux 0xebff49f0 inet_accept +EXPORT_SYMBOL vmlinux 0xec0da1f9 tty_driver_kref_put +EXPORT_SYMBOL vmlinux 0xec2c6c63 kmem_cache_free +EXPORT_SYMBOL vmlinux 0xec3bf4e9 request_firmware +EXPORT_SYMBOL vmlinux 0xec45a0cc fb_class +EXPORT_SYMBOL vmlinux 0xec48b368 current_fs_time +EXPORT_SYMBOL vmlinux 0xec794ba0 __send_remote_softirq +EXPORT_SYMBOL vmlinux 0xec860422 bioset_free +EXPORT_SYMBOL vmlinux 0xeccebb50 have_submounts +EXPORT_SYMBOL vmlinux 0xecd41a34 sock_get_timestamp +EXPORT_SYMBOL vmlinux 0xecde1418 _spin_lock_irq +EXPORT_SYMBOL vmlinux 0xecfb4e86 simple_link +EXPORT_SYMBOL vmlinux 0xed14f346 release_sock +EXPORT_SYMBOL vmlinux 0xed4cba62 journal_load +EXPORT_SYMBOL vmlinux 0xed6ba5fa phy_register_fixup_for_id +EXPORT_SYMBOL vmlinux 0xed6cc474 __devm_request_region +EXPORT_SYMBOL vmlinux 0xed6f8714 xrlim_allow +EXPORT_SYMBOL vmlinux 0xed7c45f6 scsi_bios_ptable +EXPORT_SYMBOL vmlinux 0xedb2b884 dmam_pool_create +EXPORT_SYMBOL vmlinux 0xedbaee5e nla_strcmp +EXPORT_SYMBOL vmlinux 0xedc03953 iounmap +EXPORT_SYMBOL vmlinux 0xedcb5eb7 proc_dostring +EXPORT_SYMBOL vmlinux 0xedd14538 param_get_uint +EXPORT_SYMBOL vmlinux 0xedd6f5f3 journal_get_create_access +EXPORT_SYMBOL vmlinux 0xedefc2e5 agp_bind_memory +EXPORT_SYMBOL vmlinux 0xee1ee7ed atm_alloc_charge +EXPORT_SYMBOL vmlinux 0xee2d0fc7 _local_bh_enable +EXPORT_SYMBOL vmlinux 0xee5281cd pnp_is_active +EXPORT_SYMBOL vmlinux 0xee787a1a nf_setsockopt +EXPORT_SYMBOL vmlinux 0xee7eb9e1 pnp_platform_devices +EXPORT_SYMBOL vmlinux 0xeea9dbaf bitmap_bitremap +EXPORT_SYMBOL vmlinux 0xeeb1717c param_array_get +EXPORT_SYMBOL vmlinux 0xeeb3edd5 blkdev_issue_flush +EXPORT_SYMBOL vmlinux 0xeecaea22 down_write_trylock +EXPORT_SYMBOL vmlinux 0xeee86a27 nf_afinfo +EXPORT_SYMBOL vmlinux 0xeef19211 blk_queue_start_tag +EXPORT_SYMBOL vmlinux 0xef0c219b skb_pull +EXPORT_SYMBOL vmlinux 0xef13b91d find_get_pages_tag +EXPORT_SYMBOL vmlinux 0xef15facf ipv6_dev_get_saddr +EXPORT_SYMBOL vmlinux 0xef1db2e5 jbd2_journal_clear_err +EXPORT_SYMBOL vmlinux 0xef2e7bd4 block_write_end +EXPORT_SYMBOL vmlinux 0xef3e91fe sock_kmalloc +EXPORT_SYMBOL vmlinux 0xef8ab8df dev_remove_pack +EXPORT_SYMBOL vmlinux 0xef9aedfc boot_option_idle_override +EXPORT_SYMBOL vmlinux 0xefa62ba5 sock_setsockopt +EXPORT_SYMBOL vmlinux 0xefa8cb36 pid_task +EXPORT_SYMBOL vmlinux 0xefae2cdb bdi_set_max_ratio +EXPORT_SYMBOL vmlinux 0xefc77514 __dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0xefdd70ce security_secid_to_secctx +EXPORT_SYMBOL vmlinux 0xefe099c3 acpi_get_event_status +EXPORT_SYMBOL vmlinux 0xefe26913 dev_set_allmulti +EXPORT_SYMBOL vmlinux 0xf0009fee put_pages_list +EXPORT_SYMBOL vmlinux 0xf006ccc6 __xfrm_policy_check +EXPORT_SYMBOL vmlinux 0xf0191c34 agp_generic_enable +EXPORT_SYMBOL vmlinux 0xf034828d lock_sock_nested +EXPORT_SYMBOL vmlinux 0xf04454c0 backlight_device_unregister +EXPORT_SYMBOL vmlinux 0xf060b282 scsi_get_command +EXPORT_SYMBOL vmlinux 0xf065f629 ioread16be +EXPORT_SYMBOL vmlinux 0xf068bdef mpage_bio_submit +EXPORT_SYMBOL vmlinux 0xf07fa58d scsi_set_medium_removal +EXPORT_SYMBOL vmlinux 0xf097d3e1 pcim_iomap_table +EXPORT_SYMBOL vmlinux 0xf0b57c68 param_set_long +EXPORT_SYMBOL vmlinux 0xf0e5e77f bt_sock_ioctl +EXPORT_SYMBOL vmlinux 0xf0f1246c kvasprintf +EXPORT_SYMBOL vmlinux 0xf0fb65ce dm_register_target +EXPORT_SYMBOL vmlinux 0xf0fee2e8 pcim_iounmap_regions +EXPORT_SYMBOL vmlinux 0xf10de535 ioread8 +EXPORT_SYMBOL vmlinux 0xf11543ff find_first_zero_bit +EXPORT_SYMBOL vmlinux 0xf116d4b5 copy_in_user +EXPORT_SYMBOL vmlinux 0xf13f8f46 alloc_tty_driver +EXPORT_SYMBOL vmlinux 0xf1420618 input_free_device +EXPORT_SYMBOL vmlinux 0xf162fe2d sysctl_xfrm_aevent_etime +EXPORT_SYMBOL vmlinux 0xf16cd806 filemap_write_and_wait +EXPORT_SYMBOL vmlinux 0xf17191c9 __insert_inode_hash +EXPORT_SYMBOL vmlinux 0xf174ed48 acquire_console_sem +EXPORT_SYMBOL vmlinux 0xf1752afe __request_region +EXPORT_SYMBOL vmlinux 0xf18be979 alloc_disk +EXPORT_SYMBOL vmlinux 0xf19294db bt_sock_unregister +EXPORT_SYMBOL vmlinux 0xf195c682 fb_invert_cmaps +EXPORT_SYMBOL vmlinux 0xf19e2fc0 lock_rename +EXPORT_SYMBOL vmlinux 0xf1e0f3e0 pcix_set_mmrbc +EXPORT_SYMBOL vmlinux 0xf1e41132 d_add_ci +EXPORT_SYMBOL vmlinux 0xf1e82f78 mark_info_dirty +EXPORT_SYMBOL vmlinux 0xf1e98c74 avenrun +EXPORT_SYMBOL vmlinux 0xf1f42356 pci_set_master +EXPORT_SYMBOL vmlinux 0xf20aee9e phy_device_create +EXPORT_SYMBOL vmlinux 0xf20dabd8 free_irq +EXPORT_SYMBOL vmlinux 0xf21d8179 scsi_device_quiesce +EXPORT_SYMBOL vmlinux 0xf220c28c phy_detach +EXPORT_SYMBOL vmlinux 0xf246de13 tcf_hash_destroy +EXPORT_SYMBOL vmlinux 0xf2660f94 qdisc_tree_decrease_qlen +EXPORT_SYMBOL vmlinux 0xf27e0bff xfrm_stateonly_find +EXPORT_SYMBOL vmlinux 0xf2997713 tty_termios_hw_change +EXPORT_SYMBOL vmlinux 0xf29ca034 default_llseek +EXPORT_SYMBOL vmlinux 0xf2a02f99 vfs_dq_quota_on_remount +EXPORT_SYMBOL vmlinux 0xf2a6d2bf xfrm_policy_count +EXPORT_SYMBOL vmlinux 0xf2ab098a __dst_free +EXPORT_SYMBOL vmlinux 0xf2afa595 param_get_charp +EXPORT_SYMBOL vmlinux 0xf2e579e6 hub_port_logical_disconnect +EXPORT_SYMBOL vmlinux 0xf2eeff90 mmc_set_data_timeout +EXPORT_SYMBOL vmlinux 0xf313da4e sha_transform +EXPORT_SYMBOL vmlinux 0xf3341268 __clear_user +EXPORT_SYMBOL vmlinux 0xf338d4c3 netlink_unregister_notifier +EXPORT_SYMBOL vmlinux 0xf33a7ede nf_getsockopt +EXPORT_SYMBOL vmlinux 0xf346231f seq_list_start_head +EXPORT_SYMBOL vmlinux 0xf34e1f39 n_tty_ioctl_helper +EXPORT_SYMBOL vmlinux 0xf35d2b40 dm_table_get +EXPORT_SYMBOL vmlinux 0xf373a5f7 input_event +EXPORT_SYMBOL vmlinux 0xf373ccfc page_put_link +EXPORT_SYMBOL vmlinux 0xf39f759e inode_double_lock +EXPORT_SYMBOL vmlinux 0xf3bf0bce __bitmap_complement +EXPORT_SYMBOL vmlinux 0xf3f63de7 skb_prepare_seq_read +EXPORT_SYMBOL vmlinux 0xf4129e00 audit_log_format +EXPORT_SYMBOL vmlinux 0xf42f30cc set_pages_uc +EXPORT_SYMBOL vmlinux 0xf441ac43 ioread8_rep +EXPORT_SYMBOL vmlinux 0xf441e032 bio_sector_offset +EXPORT_SYMBOL vmlinux 0xf4528073 scsi_kmap_atomic_sg +EXPORT_SYMBOL vmlinux 0xf452f436 bio_integrity_tag_size +EXPORT_SYMBOL vmlinux 0xf464ef69 pnp_stop_dev +EXPORT_SYMBOL vmlinux 0xf47a933c page_readlink +EXPORT_SYMBOL vmlinux 0xf49bc67a atm_pcr_goal +EXPORT_SYMBOL vmlinux 0xf4a2491f tty_shutdown +EXPORT_SYMBOL vmlinux 0xf4a496f4 jbd2_journal_check_used_features +EXPORT_SYMBOL vmlinux 0xf4a5c213 avail_to_resrv_perfctr_nmi_bit +EXPORT_SYMBOL vmlinux 0xf4f14de6 rtnl_trylock +EXPORT_SYMBOL vmlinux 0xf4f52f93 dqstats +EXPORT_SYMBOL vmlinux 0xf4fd7eed redirty_page_for_writepage +EXPORT_SYMBOL vmlinux 0xf51ae235 touch_nmi_watchdog +EXPORT_SYMBOL vmlinux 0xf53d4c26 qdisc_class_hash_destroy +EXPORT_SYMBOL vmlinux 0xf55c5c2f blk_queue_find_tag +EXPORT_SYMBOL vmlinux 0xf5bb5dcc inet_csk_delete_keepalive_timer +EXPORT_SYMBOL vmlinux 0xf5ce9811 tcp_memory_allocated +EXPORT_SYMBOL vmlinux 0xf5d91be0 jbd2_journal_get_undo_access +EXPORT_SYMBOL vmlinux 0xf5dda112 inet_bind +EXPORT_SYMBOL vmlinux 0xf606ec39 dm_table_get_mode +EXPORT_SYMBOL vmlinux 0xf6417c43 pagevec_lookup_tag +EXPORT_SYMBOL vmlinux 0xf64c09d6 devm_ioremap +EXPORT_SYMBOL vmlinux 0xf64ed723 xfrm6_rcv +EXPORT_SYMBOL vmlinux 0xf6598cd0 skb_copy_bits +EXPORT_SYMBOL vmlinux 0xf666cbb3 __memcpy_fromio +EXPORT_SYMBOL vmlinux 0xf66d7727 phy_ethtool_sset +EXPORT_SYMBOL vmlinux 0xf6815397 posix_lock_file +EXPORT_SYMBOL vmlinux 0xf6a61256 jbd2_journal_get_write_access +EXPORT_SYMBOL vmlinux 0xf6a900b7 dev_mc_add +EXPORT_SYMBOL vmlinux 0xf6bb4729 color_table +EXPORT_SYMBOL vmlinux 0xf6c53202 pci_dev_get +EXPORT_SYMBOL vmlinux 0xf6c67d02 bh_submit_read +EXPORT_SYMBOL vmlinux 0xf6cdb69b key_revoke +EXPORT_SYMBOL vmlinux 0xf6dcc427 __locks_copy_lock +EXPORT_SYMBOL vmlinux 0xf6ebc03b net_ratelimit +EXPORT_SYMBOL vmlinux 0xf705ff13 phy_connect +EXPORT_SYMBOL vmlinux 0xf743d5be scsi_target_resume +EXPORT_SYMBOL vmlinux 0xf749534a gen_pool_free +EXPORT_SYMBOL vmlinux 0xf75b36c9 jbd2_journal_destroy +EXPORT_SYMBOL vmlinux 0xf78d04ab netlink_register_notifier +EXPORT_SYMBOL vmlinux 0xf7a2a3c7 __scsi_device_lookup +EXPORT_SYMBOL vmlinux 0xf7b89124 set_bh_page +EXPORT_SYMBOL vmlinux 0xf7ddb696 agp_generic_type_to_mask_type +EXPORT_SYMBOL vmlinux 0xf7efcdc5 arp_find +EXPORT_SYMBOL vmlinux 0xf811e69d scsi_eh_flush_done_q +EXPORT_SYMBOL vmlinux 0xf8146b51 bt_sock_unlink +EXPORT_SYMBOL vmlinux 0xf81a3662 compat_ip_setsockopt +EXPORT_SYMBOL vmlinux 0xf82abc1d isa_dma_bridge_buggy +EXPORT_SYMBOL vmlinux 0xf82e3d47 acpi_initialize_objects +EXPORT_SYMBOL vmlinux 0xf82f1109 utf8_wctomb +EXPORT_SYMBOL vmlinux 0xf847b471 ps2_handle_response +EXPORT_SYMBOL vmlinux 0xf863d3d3 hci_connect +EXPORT_SYMBOL vmlinux 0xf876683c dev_driver_string +EXPORT_SYMBOL vmlinux 0xf8814f73 rb_last +EXPORT_SYMBOL vmlinux 0xf88e0ee2 acpi_get_table_header +EXPORT_SYMBOL vmlinux 0xf890fe7f pm_idle +EXPORT_SYMBOL vmlinux 0xf89843f9 schedule_work +EXPORT_SYMBOL vmlinux 0xf8aa47ae mutex_lock_killable +EXPORT_SYMBOL vmlinux 0xf8b30e93 mempool_create +EXPORT_SYMBOL vmlinux 0xf8b34d13 ilookup +EXPORT_SYMBOL vmlinux 0xf8c682b1 bio_add_page +EXPORT_SYMBOL vmlinux 0xf8c8e3a3 agp_backend_release +EXPORT_SYMBOL vmlinux 0xf8cf9ee5 abort_exclusive_wait +EXPORT_SYMBOL vmlinux 0xf8d95381 tcf_em_tree_destroy +EXPORT_SYMBOL vmlinux 0xf8fdf6bf dma_ops +EXPORT_SYMBOL vmlinux 0xf90f83d4 kernel_sock_shutdown +EXPORT_SYMBOL vmlinux 0xf92847b6 pcie_get_readrq +EXPORT_SYMBOL vmlinux 0xf93a2e8a blk_rq_map_sg +EXPORT_SYMBOL vmlinux 0xf98e59f0 tty_flip_buffer_push +EXPORT_SYMBOL vmlinux 0xf9a482f9 msleep +EXPORT_SYMBOL vmlinux 0xf9be5c69 vfs_rmdir +EXPORT_SYMBOL vmlinux 0xfa0564fc __wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0xfa44f38c blk_init_queue_node +EXPORT_SYMBOL vmlinux 0xfa6d625a scsi_eh_prep_cmnd +EXPORT_SYMBOL vmlinux 0xfa842fdc down_write +EXPORT_SYMBOL vmlinux 0xfaae9c9d kobject_get +EXPORT_SYMBOL vmlinux 0xfae4c37f i2c_smbus_write_word_data +EXPORT_SYMBOL vmlinux 0xfaeb31c4 rt6_lookup +EXPORT_SYMBOL vmlinux 0xfaf98462 bitrev32 +EXPORT_SYMBOL vmlinux 0xfb0443fb acpi_get_parent +EXPORT_SYMBOL vmlinux 0xfb0cf2e9 touch_all_softlockup_watchdogs +EXPORT_SYMBOL vmlinux 0xfb3cf087 pci_find_slot +EXPORT_SYMBOL vmlinux 0xfb403f69 pci_restore_state +EXPORT_SYMBOL vmlinux 0xfb493c1c pci_scan_bus_parented +EXPORT_SYMBOL vmlinux 0xfb6af58d recalc_sigpending +EXPORT_SYMBOL vmlinux 0xfb72bc41 elevator_init +EXPORT_SYMBOL vmlinux 0xfba0c2e0 llc_sap_list_lock +EXPORT_SYMBOL vmlinux 0xfbb9052a journal_check_available_features +EXPORT_SYMBOL vmlinux 0xfbc2302d locks_copy_lock +EXPORT_SYMBOL vmlinux 0xfbc617a8 kernel_read +EXPORT_SYMBOL vmlinux 0xfbf92453 param_get_bool +EXPORT_SYMBOL vmlinux 0xfc02b7ad sysctl_tcp_wmem +EXPORT_SYMBOL vmlinux 0xfc069b40 skb_checksum +EXPORT_SYMBOL vmlinux 0xfc2e76ae pcix_get_mmrbc +EXPORT_SYMBOL vmlinux 0xfc31fe88 l2cap_load +EXPORT_SYMBOL vmlinux 0xfc39e32f ioport_unmap +EXPORT_SYMBOL vmlinux 0xfcaa04a0 out_of_line_wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0xfcd056cf blk_start_queueing +EXPORT_SYMBOL vmlinux 0xfcda63a3 node_states +EXPORT_SYMBOL vmlinux 0xfcdd8cf6 param_get_ushort +EXPORT_SYMBOL vmlinux 0xfcec0987 enable_irq +EXPORT_SYMBOL vmlinux 0xfcfa03ff fb_videomode_to_modelist +EXPORT_SYMBOL vmlinux 0xfd04efbb destroy_EII_client +EXPORT_SYMBOL vmlinux 0xfd0ecdd5 acpi_is_video_device +EXPORT_SYMBOL vmlinux 0xfd1c92a8 per_cpu____irq_regs +EXPORT_SYMBOL vmlinux 0xfd41fc46 compat_nf_setsockopt +EXPORT_SYMBOL vmlinux 0xfd98879a rb_next +EXPORT_SYMBOL vmlinux 0xfdb9b629 ioread32be +EXPORT_SYMBOL vmlinux 0xfdbc4ad0 tty_hangup +EXPORT_SYMBOL vmlinux 0xfdcfc302 mmc_wait_for_app_cmd +EXPORT_SYMBOL vmlinux 0xfde2145a boot_tvec_bases +EXPORT_SYMBOL vmlinux 0xfdfc0b3b fiemap_fill_next_extent +EXPORT_SYMBOL vmlinux 0xfe01439f pci_request_region +EXPORT_SYMBOL vmlinux 0xfe047ce6 acpi_enter_sleep_state +EXPORT_SYMBOL vmlinux 0xfe0dc56f hci_register_dev +EXPORT_SYMBOL vmlinux 0xfe0f5e62 request_key +EXPORT_SYMBOL vmlinux 0xfe133f2e xfrm_init_state +EXPORT_SYMBOL vmlinux 0xfe37cbab compat_ipv6_getsockopt +EXPORT_SYMBOL vmlinux 0xfe392bcd generic_segment_checks +EXPORT_SYMBOL vmlinux 0xfe3ac12e find_get_pages_contig +EXPORT_SYMBOL vmlinux 0xfe5d4bb2 sys_tz +EXPORT_SYMBOL vmlinux 0xfe769456 unregister_netdevice_notifier +EXPORT_SYMBOL vmlinux 0xfe7c4287 nr_cpu_ids +EXPORT_SYMBOL vmlinux 0xfebfa15d hci_conn_switch_role +EXPORT_SYMBOL vmlinux 0xfec3c2f2 bcd2bin +EXPORT_SYMBOL vmlinux 0xfed70555 jbd2_journal_flush +EXPORT_SYMBOL vmlinux 0xfedd35fc console_suspend_enabled +EXPORT_SYMBOL vmlinux 0xfee27768 init_special_inode +EXPORT_SYMBOL vmlinux 0xfef96e23 __scsi_print_command +EXPORT_SYMBOL vmlinux 0xff1e9dd8 seq_list_start +EXPORT_SYMBOL vmlinux 0xff550566 bmap +EXPORT_SYMBOL vmlinux 0xff6878cf fb_default_cmap +EXPORT_SYMBOL vmlinux 0xff708fd3 mempool_destroy +EXPORT_SYMBOL vmlinux 0xff73377b netpoll_setup +EXPORT_SYMBOL vmlinux 0xff7559e4 ioport_resource +EXPORT_SYMBOL vmlinux 0xff9ca065 fb_edid_to_monspecs +EXPORT_SYMBOL vmlinux 0xffa9bd29 mark_buffer_async_write +EXPORT_SYMBOL vmlinux 0xffafdc5c _read_unlock_irq +EXPORT_SYMBOL vmlinux 0xffc31720 invalidate_bdev +EXPORT_SYMBOL vmlinux 0xffd5a395 default_wake_function +EXPORT_SYMBOL vmlinux 0xffd7d6c5 uart_unregister_driver +EXPORT_SYMBOL vmlinux 0xffebb694 scsi_init_io +EXPORT_SYMBOL vmlinux 0xffed9d4d jbd2_journal_unlock_updates +EXPORT_SYMBOL_GPL arch/x86/kernel/cpu/cpufreq/speedstep-lib 0x16836e04 speedstep_detect_processor +EXPORT_SYMBOL_GPL arch/x86/kernel/cpu/cpufreq/speedstep-lib 0x4cdb4bd0 speedstep_get_processor_frequency +EXPORT_SYMBOL_GPL arch/x86/kernel/cpu/cpufreq/speedstep-lib 0xd494ee54 speedstep_get_freqs +EXPORT_SYMBOL_GPL arch/x86/kernel/microcode 0xdf66ca81 ucode_cpu_info +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x00aaf935 kvm_disable_tdp +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x00c41b68 kvm_set_msr_common +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0209e520 kvm_cpu_get_interrupt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x02b176ae kvm_get_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x04162c68 is_error_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x06ccca4a kvm_report_emulation_failure +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x094ac8f4 kvm_get_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x096f0fe1 __kvm_set_memory_region +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x09fe8abd kvm_set_cr4 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0b8f1b8a kvm_load_guest_fpu +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0eccc801 kvm_set_memory_region +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0fea85f8 kvm_clear_guest +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x117ea67b kvm_put_kvm +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x12d1b23b kvm_release_pfn_clean +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x12ee9fbf kvm_inject_pending_timer_irqs +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1553ccce kvm_lapic_set_tpr +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1563796f gfn_to_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1c79a65c kvm_get_apic_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1e4580bb kvm_release_pfn_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x2235873d kvm_mmu_page_fault +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x2322e039 kvm_set_pfn_accessed +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x26761056 kvm_create_lapic +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x27046576 kvm_exit +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x2e2dbb7f kvm_emulate_halt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x317f9e6b kvm_enable_efer_bits +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x3795dd14 kvm_lapic_get_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x3c3a6bc5 kvm_set_apic_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x3fe68371 kvm_cpu_has_interrupt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x4809f83d kvm_lmsw +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x4a7cbe69 is_error_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x4f9cef18 kvm_emulate_hypercall +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x51ba4894 fx_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x54ba0e0e kvm_set_cr3 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x557860a2 kvm_write_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x5a005f20 kvm_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x6365e092 kvm_queue_exception_e +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x64b49051 kvm_emulate_cpuid +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x69f72a11 kvm_set_page_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x6beae4d6 kvm_vcpu_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x6df1a9c7 kvm_get_kvm +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x75953a49 kvm_set_cr0 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x7805180f emulate_instruction +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x78d7b87e kvm_is_visible_gfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8c61771c kvm_put_guest_fpu +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8ce4f3ab kvm_enable_tdp +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8d425ba1 kvm_set_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8d6f3d13 kvm_x86_ops +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8e7f9b47 segment_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x903778ca emulator_write_emulated +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x988df7e9 kvm_lapic_enabled +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x9aa9451d load_pdptrs +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x9ce545f9 kvm_get_cs_db_l_bits +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa201ff11 kvm_mmu_invlpg +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa361bc65 kvm_set_pfn_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa438186a kvm_vcpu_uninit +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa505a215 kvm_lapic_get_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xaa39b963 kvm_release_page_clean +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xaac3ddc6 kvm_read_guest +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb158a7ca kvm_release_page_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb4456b21 gfn_to_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb5f42786 kvm_mmu_load +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb759d5fb kvm_mmu_unprotect_page_virt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbc2735c3 kvm_get_msr_common +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbd377dc9 kvm_mmu_set_nonpresent_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbd86163a kvm_handle_fault_on_reboot +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbd94103b kvm_mmu_set_base_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xc8e71670 kvm_emulate_pio +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xcb382b58 kvm_lapic_reset +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xcedc9f8b kvm_emulate_pio_string +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xcef7aeb2 kvm_mmu_reset_context +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd0b2727a kvm_mmu_set_mask_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd296def9 kvm_is_error_hva +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd665ba76 emulator_read_std +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xe34b1994 gfn_to_hva +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xe3878e22 kvm_queue_exception +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xe5310334 kvm_lapic_find_highest_irr +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xeb704bfa kvm_clear_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf1e0103d kvm_timer_intr_post +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf2f707c4 kvm_task_switch +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf35502ca kvm_inject_nmi +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf3c0f643 kvm_resched +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf947e82d kvm_read_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xff4ce98f kvm_vcpu_cache +EXPORT_SYMBOL_GPL crypto/aes_generic 0x1381bf2d crypto_ft_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x22894d94 crypto_il_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5f943003 crypto_it_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5fe743de crypto_aes_expand_key +EXPORT_SYMBOL_GPL crypto/aes_generic 0x6e9cc2ba crypto_fl_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0xe30299c5 crypto_aes_set_key +EXPORT_SYMBOL_GPL crypto/async_tx/async_memcpy 0x2197ea37 async_memcpy +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x011ee2b8 async_tx_quiesce +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x393a1354 async_tx_run_dependencies +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x3ac9e557 async_tx_submit +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x55879432 async_trigger_callback +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x6b4a6db2 async_tx_issue_pending_all +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0xa7b0f830 dma_wait_for_async_tx +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0xd98571ba __async_tx_find_channel +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0x3d79e99c async_xor_zero_sum +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0xeae5a9fd async_xor +EXPORT_SYMBOL_GPL crypto/des_generic 0xcfd9a2c0 des_ekey +EXPORT_SYMBOL_GPL crypto/twofish_common 0xb296502d twofish_setkey +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x02ff9464 cfag12864b_isinited +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x0ecb2e5d cfag12864b_disable +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x305dc3c6 cfag12864b_isenabled +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x3389f926 cfag12864b_enable +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x9522a342 cfag12864b_getrate +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0xc48e9d95 cfag12864b_buffer +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x14102f23 ks0108_displaystate +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x48a70518 ks0108_writedata +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x4f506333 ks0108_startline +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x6edae968 ks0108_isinited +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xbf4774db ks0108_writecontrol +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xedde6df2 ks0108_page +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xfee8ef7b ks0108_address +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x053ab5a1 tpm_pm_resume +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x09c52d81 tpm_show_owned +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x1b0ecd46 tpm_remove_hardware +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x238a497e tpm_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x250fe8b3 tpm_show_temp_deactivated +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x25bacaf3 tpm_continue_selftest +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x357a7304 tpm_show_caps +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x447da381 tpm_pm_suspend +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x536c7301 tpm_store_cancel +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x62f888b7 tpm_gen_interrupt +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x85f32426 tpm_dev_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x86d21c03 tpm_show_pcrs +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x945c9cb3 tpm_get_timeouts +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x973ee529 tpm_dev_vendor_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xa931f4ba tpm_calc_ordinal_duration +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xb843694a tpm_write +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xbbc3c07a tpm_register_hardware +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xbbc80003 tpm_show_caps_1_2 +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xc73b65c4 tpm_show_pubek +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xcc1693ab tpm_show_active +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xce18d2c8 tpm_open +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xebebbe8d tpm_show_enabled +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xfa37ef15 tpm_read +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm_bios 0x67d3b9aa tpm_bios_log_setup +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm_bios 0xca3301dc tpm_bios_log_teardown +EXPORT_SYMBOL_GPL drivers/dca/dca 0x28f12408 dca3_get_tag +EXPORT_SYMBOL_GPL drivers/dca/dca 0x2e471f01 dca_register_notify +EXPORT_SYMBOL_GPL drivers/dca/dca 0x31a2c8df dca_get_tag +EXPORT_SYMBOL_GPL drivers/dca/dca 0x8006c614 dca_unregister_notify +EXPORT_SYMBOL_GPL drivers/dca/dca 0x9c555a61 unregister_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0xb575212e dca_remove_requester +EXPORT_SYMBOL_GPL drivers/dca/dca 0xc6989265 free_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0xd8d79dbe register_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0xe1528c60 alloc_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0xf5f54a23 dca_add_requester +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x01d49ad2 edac_pci_del_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x2b29bb58 edac_mc_find_csrow_by_page +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x320b4464 edac_pci_release_generic_ctl +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x383ff3f9 edac_mc_handle_ue +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x4f344e84 edac_mc_alloc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x4f8d943a edac_pci_free_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x52ecdee7 edac_mc_handle_ce +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x583be4e2 edac_device_handle_ue +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x5aac3e00 edac_mc_handle_ce_no_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x5ef02549 edac_device_handle_ce +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x60af076e edac_mc_del_mc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x70782bac edac_mc_handle_ue_no_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x70a17a23 edac_device_alloc_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x85e849ca edac_pci_add_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x93596fea edac_device_add_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xa705c411 edac_pci_handle_npe +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xabbda82a edac_mc_free +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xb38bd890 edac_device_del_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xca2ff835 edac_pci_reset_delay_period +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xcdcc6130 edac_pci_create_generic_ctl +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xce82348d edac_pci_alloc_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xcfc49b6c edac_mc_add_mc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xe37b6552 edac_device_free_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xf25d7e97 edac_pci_handle_pe +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x01fd453e usbhid_lookup_quirk +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x246ce8ed hiddev_hid_event +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x48db528b usbhid_submit_report +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0xf715dedd usbhid_set_leds +EXPORT_SYMBOL_GPL drivers/i2c/busses/i2c-nforce2 0xbcdeb6eb nforce2_smbus +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0x58ed75d7 hpsb_config_rom_ip1394_add +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0xec8d18cf hpsb_disable_irm +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0xefc79df8 hpsb_config_rom_ip1394_remove +EXPORT_SYMBOL_GPL drivers/infiniband/hw/ipath/ib_ipath 0x1514b2b2 ipath_debug +EXPORT_SYMBOL_GPL drivers/input/ff-memless 0x32282501 input_ff_create_memless +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x05e7f13e wm97xx_get_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x15b95809 wm97xx_set_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x2c658e0c wm9705_codec +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x31db9356 wm9712_codec +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x401f356c wm97xx_set_suspend_mode +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x405129ab wm97xx_unregister_mach_ops +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x60edba96 wm97xx_config_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x66ec2a6e wm97xx_read_aux_adc +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xb515506c wm97xx_reg_read +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xda37554f wm97xx_register_mach_ops +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xddc028b7 wm97xx_reg_write +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xfd7193c8 wm9713_codec +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x0b1a95cd gigaset_m10x_input +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x0c05baa9 gigaset_stop +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x1170f695 gigaset_start +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x1ae60259 gigaset_freecs +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x2b89a1be gigaset_add_event +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x2c0979ce gigaset_dbg_buffer +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x454aa44f gigaset_debuglevel +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x6ca0d57f gigaset_initcs +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x89d7f5bb gigaset_if_receive +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x8c25b292 gigaset_handle_modem_response +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x953a2725 gigaset_freedriver +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x9b012d02 gigaset_shutdown +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xa3c2a512 gigaset_initdriver +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xb91f2588 gigaset_skb_sent +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xcf14b452 gigaset_fill_inbuf +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xf5308471 gigaset_m10x_send_skb +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xfde2d249 gigaset_blockdriver +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x0f5a72c9 led_classdev_suspend +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x73413396 led_classdev_resume +EXPORT_SYMBOL_GPL drivers/leds/led-class 0xbac80395 led_classdev_unregister +EXPORT_SYMBOL_GPL drivers/leds/led-class 0xbdb0d224 led_classdev_register +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x04662e0f ir_codes_fusionhdtv_mce +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x07e92917 ir_codes_avermedia_a16d +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x083661f9 ir_codes_avertv_303 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x088631b9 ir_codes_behold +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x1cb148f5 ir_extract_bits +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2456e513 ir_decode_pulsedistance +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2a4852cc ir_codes_dntv_live_dvb_t +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2af1a608 ir_codes_proteus_2309 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x3811daea ir_codes_manli +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x43c89ef4 ir_decode_biphase +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x45b08f68 ir_codes_pinnacle_grey +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4740e7a3 ir_codes_empty +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4beb7618 ir_codes_encore_enltv_fm53 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4ea698a2 ir_codes_purpletv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x55338dda ir_codes_pixelview_new +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x589cad50 ir_codes_apac_viewcomp +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x5db13554 ir_codes_encore_enltv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6606596a ir_rc5_timer_keyup +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6adc476d ir_codes_powercolor_real_angel +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6aefdbea ir_codes_npgtech +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6b87c69d ir_codes_iodata_bctv7e +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6d6511e7 ir_dump_samples +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6e2a1870 ir_codes_adstech_dvb_t_pci +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x7277973d ir_codes_pctv_sedna +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x75e89cc3 ir_codes_flydvb +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x772a30a2 ir_codes_nebula +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x7953bd28 ir_input_init +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x7a9a39b9 ir_input_nokey +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x7b38143b ir_codes_encore_enltv2 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x85d37490 ir_codes_dntv_live_dvbt_pro +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x89cc1189 ir_codes_winfast +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x902a3cd2 ir_codes_hauppauge_new +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x933d0bb3 ir_codes_msi_tvanywhere +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x9451e232 ir_codes_behold_columbus +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x96470cab ir_codes_cinergy +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb1f4eb35 ir_codes_avermedia_dvbt +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb50812de ir_codes_real_audio_220_32_keys +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb6cd4666 ir_codes_eztv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xbb08d146 ir_codes_msi_tvanywhere_plus +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xbdce6594 ir_codes_tt_1500 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc1fea0c1 ir_codes_pv951 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc42bd037 ir_codes_budget_ci_old +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc6c5a7a1 ir_codes_em_terratec +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xcdf2859f ir_codes_avermedia_m135a +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd1e0258a ir_codes_flyvideo +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd55e6891 ir_codes_gotview7135 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd9c7f010 ir_codes_rc5_tv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xdaa041ad ir_codes_cinergy_1400 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xdfcf23df ir_codes_norwood +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xee2f5e0e ir_codes_pinnacle_pctv_hd +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf07533a1 ir_codes_videomate_tv_pvr +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf0fc9374 ir_codes_avermedia +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf2b421aa ir_codes_genius_tvgo_a11mce +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf4f7a4d6 ir_rc5_timer_end +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfa177653 ir_codes_pixelview +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfb981300 ir_codes_pinnacle_color +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfc54a5cd ir_codes_asus_pc39 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfce8436a ir_input_keydown +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x156cbd11 saa7146_pgtable_free +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x4be77651 saa7146_i2c_adapter_prepare +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x4e1b4c87 saa7146_vmalloc_build_pgtable +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x534e46dd saa7146_unregister_extension +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xad7028fa saa7146_pgtable_alloc +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xc98faf20 saa7146_devices_lock +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xcef0dd61 saa7146_setgpio +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xcf0bd119 saa7146_pgtable_build_single +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xcf683cf2 saa7146_devices +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xd3a59773 saa7146_register_extension +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xded24131 saa7146_vfree_destroy_pgtable +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xe3cd9b5c saa7146_debug +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xe41ea880 saa7146_wait_for_debi_done +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x03625be4 saa7146_start_preview +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x2113c3b1 saa7146_set_hps_source_and_sync +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x4d56ee74 saa7146_unregister_device +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x67e593bd saa7146_vv_release +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xa13a5df7 saa7146_stop_preview +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xd5d0be76 saa7146_vv_init +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xe6d43634 saa7146_register_device +EXPORT_SYMBOL_GPL drivers/media/common/tuners/mt20xx 0xd51b91f0 microtune_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/mxl5007t 0x15a2a824 mxl5007t_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda18271 0x0b8cc61e tda18271_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda827x 0xfa87259d tda827x_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda8290 0xa7caa5e9 tda829x_probe +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda8290 0xc66b0621 tda829x_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda9887 0x97ac800f tda9887_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5761 0x90748d1e tea5761_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5761 0xd44c4b97 tea5761_autodetection +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5767 0x41fc50f6 tea5767_autodetection +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5767 0xeba52535 tea5767_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tuner-simple 0xfa83d290 simple_tuner_attach +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x49ce277e ttpci_budget_init +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x71b696c9 ttpci_budget_set_video_port +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x7948c222 budget_debug +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x910c1b3d ttpci_budget_debiwrite +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xc27d81eb ttpci_budget_irq10_handler +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xc8a5ba63 ttpci_budget_debiread +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xd06abfc6 ttpci_budget_deinit +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xf1f2ab29 ttpci_budget_init_hooks +EXPORT_SYMBOL_GPL drivers/media/video/compat_ioctl32 0x7dd192b2 v4l_compat_ioctl32 +EXPORT_SYMBOL_GPL drivers/media/video/cx88/cx88xx 0xe3349e98 cx88_setup_xc3028 +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x30f66c73 em28xx_audio_analog_set +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x7fc8652c em28xx_tuner_callback +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x912d396e em28xx_set_mode +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0xa5c12520 em28xx_uninit_isoc +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0xf14e9917 em28xx_init_isoc +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x4da88413 saa7134_g_ctrl_internal +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x683ea5e9 saa7134_s_ctrl_internal +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x7d6b2546 saa7134_ts_qops +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0xd2c00a07 saa7134_s_std_internal +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0xd8fc95f7 saa7134_i2c_call_saa6752 +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0xf1d5a073 saa7134_queryctrl +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xa5228b24 v4l2_int_device_try_attach_all +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xd21fd8c8 v4l2_int_ioctl_1 +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xe81d11f2 v4l2_int_device_register +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xf0ab7a91 v4l2_int_device_unregister +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xfb0d9985 v4l2_int_ioctl_0 +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x0ce36380 videobuf_alloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x1cc8b3b8 videobuf_poll_stream +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x2c7af86d videobuf_stop +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x3195733e videobuf_read_one +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x3fdc0069 videobuf_querybuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x4487b016 videobuf_mmap_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x47006727 videobuf_queue_cancel +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x4907add5 videobuf_qbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x5d8bd94a videobuf_dqbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x71af6a86 videobuf_queue_to_vmalloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x750dc2fb __videobuf_mmap_setup +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x912f06ec videobuf_waiton +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xa68e2009 videobuf_queue_is_busy +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xa6c601b7 videobuf_cgmbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xa97a6992 videobuf_mmap_mapper +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xc11c3bd4 videobuf_read_start +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xc35b5085 videobuf_reqbufs +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xc8e76031 videobuf_mmap_setup +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xda744963 videobuf_next_field +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xdb7a97ed videobuf_iolock +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xdc754901 videobuf_read_stop +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xe276c7ad videobuf_streamon +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xf4c2d29c videobuf_read_stream +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xf74be1b7 videobuf_queue_core_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xfb756611 videobuf_streamoff +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-contig 0x90447803 videobuf_to_dma_contig +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-contig 0xd0294f52 videobuf_dma_contig_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-contig 0xe192d782 videobuf_queue_dma_contig_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x15798be9 videobuf_queue_sg_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x3956de84 videobuf_dma_unmap +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x5df0fcf4 videobuf_dma_init_user +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x74462913 videobuf_sg_dma_map +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x7fd5e7e2 videobuf_sg_dma_unmap +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x933dfb43 videobuf_vmalloc_to_sg +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x95be35cc videobuf_to_dma +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xa38faed2 videobuf_sg_alloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xaf2168f1 videobuf_dma_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xb051e879 videobuf_dma_init_overlay +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xb7fdbd03 videobuf_dma_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xbe1b616b videobuf_dma_sync +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xcd41b440 videobuf_dma_map +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xd8922c8f videobuf_dma_init_kernel +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0x1b3530c3 videobuf_queue_vmalloc_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0x76731887 videobuf_to_vmalloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0xf3b77cf4 videobuf_vmalloc_free +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x1fc93f38 i2o_dma_map_single +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x427f9239 i2o_dma_free +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x7449fa91 i2o_pool_free +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x8bfd28aa i2o_sg_tablesize +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x8fd3ef7d i2o_pool_alloc +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xa408630a i2o_dma_map_sg +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xdecd4ca1 i2o_dma_realloc +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xf60f392d i2o_dma_alloc +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x06f05eb4 sm501_modify_reg +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x8e5fac2d sm501_find_clock +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x9910feb0 sm501_misc_control +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0xce530659 sm501_unit_power +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0xdd5a466e sm501_set_clock +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x04946744 wm8350_free_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x11913bbe wm8350_unmask_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x15ae2a89 wm8350_gpio_config +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x286fbf63 wm8350_block_write +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x37cefab6 wm8350_reg_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x43638f6d wm8350_clear_bits +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x4eeb1f0e wm8350_mask_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x5cdc306c wm8350_reg_unlock +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x5d5bca21 wm8350_device_init +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x8c8478d8 wm8350_set_bits +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xab760b4c wm8350_block_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xc3683c7d wm8350_reg_write +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xd1a31cbf wm8350_register_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xd2978a19 wm8350_reg_lock +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xf0bc714f wm8350_device_exit +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x0babf20d wm8400_reset_codec_reg_cache +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x87526730 wm8400_block_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x8fe53b39 wm8400_set_bits +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0xc04a2ca1 wm8400_reg_read +EXPORT_SYMBOL_GPL drivers/misc/eeprom_93cx6 0x2df115d4 eeprom_93cx6_multiread +EXPORT_SYMBOL_GPL drivers/misc/eeprom_93cx6 0x63d14d2f eeprom_93cx6_read +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x0777a7bb enclosure_remove_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x38a18ea8 enclosure_for_each_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x8978690d enclosure_find +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x90f9a7df enclosure_component_register +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x98210099 enclosure_unregister +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0xd369abf2 enclosure_add_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0xdd30a8a6 enclosure_register +EXPORT_SYMBOL_GPL drivers/misc/sgi-gru/gru 0x2293c8e0 gru_get_next_message +EXPORT_SYMBOL_GPL drivers/misc/sgi-gru/gru 0x5927a880 gru_send_message_gpa +EXPORT_SYMBOL_GPL drivers/misc/sgi-gru/gru 0x7e83f3fc gru_free_message +EXPORT_SYMBOL_GPL drivers/misc/sgi-gru/gru 0x81b3b8e3 gru_create_message_queue +EXPORT_SYMBOL_GPL drivers/misc/sgi-gru/gru 0x9c7283a1 gru_copy_gpa +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x345c9217 xpc_disconnect +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x39046c7a xpc_clear_interface +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x43a01eea xpc_registrations +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x6285dfe8 xp_cpu_to_nasid +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x64ba5017 xp_pa +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x76e36d39 xp_region_size +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x9823adb0 xpc_set_interface +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x9acd8cf8 xpc_interface +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0xba3694f3 xp_remote_memcpy +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0xead4f7fe xp_max_npartitions +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0xf3b47f67 xp_partition_id +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0xfe709b6c xpc_connect +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x00c30503 sdhci_resume_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x1f75831f sdhci_free_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x21b53e2c sdhci_alloc_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x39cb80ea sdhci_add_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x82033960 sdhci_remove_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0xa19cf51e sdhci_suspend_host +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0x3af54703 cfi_cmdset_0200 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0x51fc85d2 cfi_cmdset_0003 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0xc8b8fc5e cfi_cmdset_0001 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0002 0x1d5eb914 cfi_cmdset_0002 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0020 0x608d4bea cfi_cmdset_0020 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0x554e8f9a cfi_qry_present +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0x773f7934 cfi_qry_mode_off +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0xe82b3be3 cfi_qry_mode_on +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2000 0x21566cea DoC2k_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2001 0x704103a1 DoCMil_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2001plus 0x7209b2a0 DoCMilPlus_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/docecc 0x45937659 doc_decode_ecc +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x05ef575e unregister_mtd_user +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x3c22bd4a get_mtd_device_nm +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x3d556e8e mtd_erase_callback +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x406d1f31 register_mtd_parser +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x436392b8 deregister_mtd_parser +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x76a4c646 get_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x7d4b0486 parse_mtd_partitions +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x982b23a9 get_sb_mtd +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xa11d9c0d del_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xac749edb add_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xb1a673a6 mtd_table +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xb9cb5109 register_mtd_user +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xc368afcf default_mtd_writev +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xe1890494 put_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xeff64be1 mtd_table_mutex +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xf53fbcaa kill_mtd_super +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0x09677e1d deregister_mtd_blktrans +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0x54fb56db register_mtd_blktrans +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0xb59d4bfb add_mtd_blktrans_dev +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0xcc81a2fb del_mtd_blktrans_dev +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x55eac26a nand_wait_ready +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x5d89e703 nand_release +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x7517ccec nand_scan_tail +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x805dac7c nand_scan +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x9f43afc2 nand_scan_ident +EXPORT_SYMBOL_GPL drivers/mtd/onenand/onenand 0x937825c9 onenand_release +EXPORT_SYMBOL_GPL drivers/mtd/onenand/onenand 0xb7e79a65 onenand_scan +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x0f2f471c ubi_leb_erase +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x16ca1f43 ubi_get_volume_info +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x2c92dd5f ubi_is_mapped +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x2e755c49 ubi_leb_change +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x42801d20 ubi_sync +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x61981acd ubi_open_volume +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x82b3c662 ubi_open_volume_nm +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xa58c68f8 ubi_leb_map +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xad1e1647 ubi_leb_unmap +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xb2820bd0 ubi_close_volume +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xbc505df4 ubi_get_device_info +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xcf89f6b3 ubi_leb_write +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xdbda372b ubi_leb_read +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0c34e52e mlx4_free_hwq_res +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0d1ffc23 mlx4_unregister_interface +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0d61c3a2 mlx4_buf_write_mtt +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0d84b31d mlx4_db_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x147bc971 mlx4_free_cmd_mailbox +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x2376c32b mlx4_register_mac +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x265975b8 mlx4_srq_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x2b1ef35d mlx4_cq_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x2c3f4f18 mlx4_srq_query +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x32f97ac5 mlx4_srq_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x33e15ee5 mlx4_qp_reserve_range +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x39b08a0d mlx4_CLOSE_PORT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x3e01c338 mlx4_INIT_PORT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x3e9f0f69 mlx4_buf_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x41ae37a7 mlx4_fmr_enable +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x4acf159c mlx4_alloc_cmd_mailbox +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5179ceb1 mlx4_fmr_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x530598b6 mlx4_qp_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x547a5a0d mlx4_write_mtt +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5492704c mlx4_multicast_detach +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x59198627 mlx4_qp_to_ready +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5b40ac08 mlx4_map_phys_fmr +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x65e2573f mlx4_fmr_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x6b3a6d90 mlx4_qp_modify +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x6c288f36 mlx4_mtt_init +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x6dfc6f95 mlx4_qp_remove +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x7176a3d3 mlx4_buf_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x76e49be9 mlx4_multicast_attach +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x781305fe mlx4_qp_release_range +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x78b636f1 mlx4_uar_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x853bc27f mlx4_SYNC_TPT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x95424208 mlx4_unregister_mac +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x9833505d mlx4_mr_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x9848e9fd mlx4_cq_modify +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x9cd1ec57 mlx4_mr_enable +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xa56f3812 mlx4_mtt_cleanup +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xa9bfc610 mlx4_qp_query +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xabd9402b mlx4_pd_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xbd11a45f mlx4_db_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xbf374bc0 mlx4_cq_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xbf96a560 mlx4_srq_arm +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xcb42adf5 mlx4_qp_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xe0b2dd4f __mlx4_cmd +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xe3cf82d0 mlx4_register_interface +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xea210cd4 mlx4_pd_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xea2224e0 mlx4_mr_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xece2073c mlx4_alloc_hwq_res +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf33437a8 mlx4_uar_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf5392392 mlx4_cq_resize +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf5487691 mlx4_mtt_addr +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf8a90d04 mlx4_unregister_vlan +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf9b4e7ca mlx4_fmr_unmap +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xff3487ea mlx4_register_vlan +EXPORT_SYMBOL_GPL drivers/net/usb/cdc_ether 0x0f627478 usbnet_cdc_unbind +EXPORT_SYMBOL_GPL drivers/net/usb/cdc_ether 0xf64d7018 usbnet_generic_cdc_bind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x450af3a5 generic_rndis_bind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x716b91e6 rndis_tx_fixup +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x8cd63312 rndis_rx_fixup +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xd3d901f8 rndis_status +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xf4216732 rndis_unbind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xff80166d rndis_command +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x05e7c13f usbnet_resume +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x066de199 usbnet_set_settings +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x10dbf2e4 usbnet_get_msglevel +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x356792b4 usbnet_unlink_rx_urbs +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x3c2e2ce6 usbnet_set_msglevel +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x4b8daa96 usbnet_disconnect +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x6dfb02a6 usbnet_get_settings +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x6f990d04 usbnet_skb_return +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x9c03e41d usbnet_get_link +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xa57c9f9b usbnet_get_endpoints +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xab153645 usbnet_nway_reset +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xadd952b0 usbnet_defer_kevent +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xd3c57937 usbnet_probe +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xe3a52d6f usbnet_suspend +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xe7136e99 usbnet_get_drvinfo +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x0869889a lbs_stop_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x25b2019b lbs_send_tx_feedback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x2a27bc90 lbs_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x568bad1b lbs_queue_event +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x5cd4b362 lbs_host_sleep_cfg +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x5ec0c8ba lbs_cmd_copyback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x61713e89 lbs_host_to_card_done +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x6425c3d7 __lbs_cmd +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x85f9cd48 lbs_remove_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xd62c1fde lbs_process_rxed_packet +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xdf839a1a lbs_start_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xe0aec75c lbs_notify_command_response +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xe740f199 lbs_cmd_802_11_rate_adapt_rateset +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xf64277de lbs_debug +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xfa5bdf97 lbs_add_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xfd6bd1c0 lbs_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x1830dd6e lbtf_send_tx_feedback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x7196c8bc lbtf_cmd_response_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x7756d322 lbtf_remove_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x830d5575 lbtf_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x8e77ea35 __lbtf_cmd +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xc5851f81 lbtf_cmd_copyback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xce96edb3 lbtf_bcn_sent +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xd3e10e87 lbtf_add_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf_usb 0x951ac8e2 if_usb_reset_device +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf_usb 0xc7bdceac if_usb_prog_firmware +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x0608ce5b p54_parse_firmware +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x1b80d4de p54_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x856a1020 p54_read_eeprom +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0xd2baa4f5 p54_free_common +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0xf6e1cb76 p54_init_common +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x245fbbc9 rt2x00mac_get_tx_stats +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x269d7eba rt2x00mac_add_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x2e456f45 rt2x00mac_set_key +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x3da12eac rt2x00mac_start +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x43426a85 rt2x00lib_txdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x4f3c4783 rt2x00mac_bss_info_changed +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x69e4a2c6 rt2x00lib_remove_dev +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x83cac156 rt2x00lib_probe_dev +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x8cd8f86b rt2x00lib_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x91a71026 rt2x00lib_rxdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x92f1eeb2 rt2x00mac_config_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x93afdb7f rt2x00lib_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x9829af98 rt2x00mac_remove_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x9a173688 rt2x00mac_tx +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x9bbdefd2 rt2x00queue_get_entry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xae873b28 rt2x00mac_conf_tx +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xbd2ccd5a rt2x00mac_stop +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xd4423900 rt2x00lib_beacondone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xd4e7e4f3 rt2x00mac_configure_filter +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xd546885b rt2x00mac_get_stats +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xe48789fd rt2x00queue_get_queue +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xe58c01fa rt2x00mac_config +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xfd81ddbc rt2x00queue_map_txskb +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x09f0e24a rt2x00pci_uninitialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x0f690294 rt2x00pci_initialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x2e43ec92 rt2x00pci_probe +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x42db1868 rt2x00pci_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x496be573 rt2x00pci_remove +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0xc412962e rt2x00pci_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0xd045f3b3 rt2x00pci_rxdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0xe7dd4163 rt2x00pci_write_tx_data +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x1e12c487 rt2x00usb_disconnect +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x2f53a3bd rt2x00usb_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x34d83380 rt2x00usb_probe +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x4b89b147 rt2x00usb_write_tx_data +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x55bddad1 rt2x00usb_disable_radio +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x60faca66 rt2x00usb_vendor_request +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x61508676 rt2x00usb_vendor_req_buff_lock +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x9562c0df rt2x00usb_vendor_request_buff +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x9740512a rt2x00usb_init_txentry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xa1135a5d rt2x00usb_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xae0e7487 rt2x00usb_kick_tx_queue +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xb840fa0d rt2x00usb_uninitialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xc267b938 rt2x00usb_init_rxentry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xf54d3a21 rt2x00usb_initialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xfd723143 rt2x00usb_vendor_request_large_buff +EXPORT_SYMBOL_GPL drivers/pci/hotplug/acpiphp 0x262d2fee acpiphp_unregister_attention +EXPORT_SYMBOL_GPL drivers/pci/hotplug/acpiphp 0x9337f4a2 acpiphp_register_attention +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0x9b07ce90 wm8350_ldo_set_slot +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0xb00b1e3b wm8350_isink_set_flash +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0xbc05f8d1 wm8350_dcdc25_set_mode +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0xcdd96120 wm8350_register_regulator +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0xf2922bba wm8350_dcdc_set_slot +EXPORT_SYMBOL_GPL drivers/regulator/wm8400-regulator 0xe326dfe8 wm8400_register_regulator +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x01dc6456 iscsi_host_remove +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x0233f349 iscsi_pool_init +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x0260d772 iscsi_requeue_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x05403470 iscsi_eh_abort +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x08c1608f iscsi_set_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x0c0b0ee2 __iscsi_get_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x0dc0c54f iscsi_change_queue_depth +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x16da38f6 iscsi_itt_to_ctask +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x341b7667 iscsi_host_set_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x3e3e217b iscsi_host_free +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x41ba1d14 iscsi_pool_free +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x58e333e2 iscsi_host_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x5e55c69c iscsi_session_setup +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x6a868a5a __iscsi_complete_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x6e61bb51 iscsi_session_failure +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x6f08acb1 iscsi_conn_setup +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x71cb60d2 iscsi_conn_start +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x77042bb7 iscsi_put_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x7bc40054 iscsi_conn_send_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x7cdd6b48 iscsi_eh_target_reset +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x876ed3e7 iscsi_session_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x8c6fe2fc iscsi_host_add +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x8e37c3b2 iscsi_prep_unsolicit_data_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xa29cd46c iscsi_host_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xa3e0521c iscsi_conn_bind +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xa43ea67a iscsi_conn_teardown +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xa50f9edb iscsi_queuecommand +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xa7c32a58 iscsi_session_recovery_timedout +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xb47fe326 iscsi_conn_stop +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xb75c17e6 iscsi_update_cmdsn +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xcca7edb9 iscsi_conn_failure +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xcce86fa9 iscsi_conn_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xcf95fc89 iscsi_verify_itt +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xd4930c0c iscsi_session_teardown +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xd59fe937 iscsi_complete_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xde9317e9 iscsi_eh_device_reset +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xe35b3921 iscsi_suspend_tx +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x006848e4 sas_register_ha +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x1e9c44b4 sas_bios_param +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x295ae607 sas_ioctl +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x2bef2cfb sas_request_addr +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x3cea6700 sas_target_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x44ee3cb4 sas_ssp_task_response +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x533bb75b sas_domain_attach_transport +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x5e39cfe5 sas_task_abort +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x80e70c69 sas_change_queue_depth +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x819b0bbb sas_unregister_ha +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x861ef2ff sas_slave_destroy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x8fdf5c88 sas_phy_reset +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x993548a5 sas_eh_device_reset_handler +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x9dac9ccb sas_eh_bus_reset_handler +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xbe576603 sas_phy_enable +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xc38ced64 sas_target_destroy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xd16fca1e sas_change_queue_type +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xd5264683 __sas_task_abort +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xdb8da37e sas_slave_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xe818edfa sas_queuecommand +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xee03c6fb sas_domain_release_transport +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xf3741952 sas_slave_configure +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xf9183816 sas_find_local_phy +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x38c0280d srp_cmd_queue +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x6eaf618c srp_target_free +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x8241014f srp_transfer_data +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x849fe831 srp_iu_get +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0xf0de1473 srp_target_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0xffab22e1 srp_iu_put +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x03b81ab4 scsi_tgt_tsk_mgmt_request +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x090af767 scsi_tgt_it_nexus_destroy +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x28d47b8a scsi_tgt_it_nexus_create +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x343945ca scsi_tgt_queue_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x45e0ded4 scsi_tgt_cmd_to_host +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x4902b246 scsi_host_put_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x49c377b8 scsi_tgt_free_queue +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x9380483d scsi_tgt_alloc_queue +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xa3d871e3 scsi_host_get_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x0556abbe iscsi_conn_error_event +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x0fe8953c iscsi_destroy_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x266d2ed6 iscsi_scan_finished +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x27be0dc0 iscsi_create_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x421dea6a iscsi_host_for_each_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x42a0ad84 iscsi_block_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x514e85ec iscsi_unblock_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x59b89ce7 iscsi_create_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x5ef9259d iscsi_session_chkready +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x626b6398 iscsi_destroy_conn +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x7431087a iscsi_register_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x78377ca4 iscsi_create_conn +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x799d6646 iscsi_recv_pdu +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x8353cc8b iscsi_free_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x98a6f9e5 iscsi_unregister_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xa44ea02c iscsi_destroy_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xa7a6fc8e iscsi_lookup_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xd42ba398 iscsi_alloc_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xd857a9b0 iscsi_remove_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xfb7da240 iscsi_session_event +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xfc9efde0 iscsi_add_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0x0ef06974 spi_populate_ppr_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0xa0c71dac spi_populate_sync_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0xcffa2aff spi_populate_width_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x55244fdf srp_remove_host +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x8385f679 srp_rport_del +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0xa2b8a117 srp_attach_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0xb275de97 srp_release_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0xc81a00a5 srp_rport_add +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x0e18d348 spi_bitbang_start +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x1343f41f spi_bitbang_setup +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x327aefee spi_bitbang_cleanup +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x8367cf31 spi_bitbang_setup_transfer +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x9fdd8396 spi_bitbang_stop +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0xcc058868 spi_bitbang_transfer +EXPORT_SYMBOL_GPL drivers/uio/uio 0x689ca9a7 uio_event_notify +EXPORT_SYMBOL_GPL drivers/uio/uio 0xc2d06c4d uio_unregister_device +EXPORT_SYMBOL_GPL drivers/uio/uio 0xeeef4f86 __uio_register_device +EXPORT_SYMBOL_GPL drivers/usb/atm/usbatm 0x46c935f0 usbatm_usb_probe +EXPORT_SYMBOL_GPL drivers/usb/atm/usbatm 0x8a30fb7b usbatm_usb_disconnect +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x0fbdd77b usb_ftdi_elan_read_pcimem +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x393870b5 usb_ftdi_elan_edset_empty +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x6a5b7f9e usb_ftdi_elan_write_pcimem +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x71539aae ftdi_elan_gone_away +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x73e1201e usb_ftdi_elan_edset_output +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x894a57ef usb_ftdi_elan_edset_input +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xa2e703e5 usb_ftdi_elan_edset_flush +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xfebbbd69 usb_ftdi_elan_edset_single +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xff9645fe usb_ftdi_elan_edset_setup +EXPORT_SYMBOL_GPL drivers/usb/misc/phidget 0x11443006 phidget_class +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x0a09810e wa_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x122f15ac wa_urb_enqueue_run +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x668f3c90 wa_urb_enqueue +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x7bb38a51 rpipe_ep_disable +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xb7481e77 __wa_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xcb55ad58 rpipe_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xccc901c6 wa_urb_dequeue +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x0bb6bf5e wusb_cluster_id_get +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x14301ad1 wusbhc_rh_start_port_reset +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x18791193 wusbhc_giveback_urb +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x1c3b8c66 wusbhc_handle_dn +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x3e6007bc wusbhc_rh_resume +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x48535cf7 __wusb_dev_get_by_usb_dev +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x57d38b84 wusbhc_chid_set +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x5f2a4188 wusbhc_mmcie_rm +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x5f7f208a wusbhc_mmcie_set +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x5fec1e8e wusbhc_stop +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x607c2f60 wusbhc_rh_status_data +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x764dae51 wusbhc_reset_all +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x7f0b7631 wusb_dev_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xb725d128 wusb_cluster_id_put +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xbed6ff81 wusbhc_b_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xc7e2f835 wusbhc_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xcefc1a47 wusbhc_rh_control +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xf1c2d078 wusbhc_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xf770a6b4 wusbd +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xf7a3def5 wusbhc_b_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xfd145b0b wusbhc_rh_suspend +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xfe2e17d7 wusb_et_name +EXPORT_SYMBOL_GPL drivers/uwb/i1480/dfu/i1480-dfu-usb 0x89353975 i1480_fw_upload +EXPORT_SYMBOL_GPL drivers/uwb/i1480/dfu/i1480-dfu-usb 0xb5d3791c i1480_rceb_check +EXPORT_SYMBOL_GPL drivers/uwb/i1480/dfu/i1480-dfu-usb 0xbe1e6d10 i1480_cmd +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x184ae104 uwb_ack_policy_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x4fea41b0 uwb_phy_rate_show +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x629af4ac uwb_ack_policy_show +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x6b78ce6b uwb_rts_cts_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x7e37e9d8 uwb_phy_rate_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0xa6074e56 uwb_pca_base_priority_show +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0xde1a063c uwb_pca_base_priority_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0xfdf789d7 uwb_rts_cts_show +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x44501c9e umc_device_register +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x55212a1f umc_device_unregister +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x9c38507d umc_match_pci_id +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x9cce3f63 umc_driver_unregister +EXPORT_SYMBOL_GPL drivers/uwb/umc 0xaeadc5b7 umc_bus_type +EXPORT_SYMBOL_GPL drivers/uwb/umc 0xbae3dba9 umc_controller_reset +EXPORT_SYMBOL_GPL drivers/uwb/umc 0xf1ac24d2 __umc_driver_register +EXPORT_SYMBOL_GPL drivers/uwb/umc 0xfe831d27 umc_device_create +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x0ccb5b3a uwb_rc_vcmd +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x1d5cc8d3 uwb_bg_joined +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x1fe101ba uwb_rc_mac_addr_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x22a6d823 uwb_rc_cmd_async +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x262dbf90 uwb_est_find_size +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x2ca10493 uwb_rsv_create +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4288ed9d uwb_rc_rm +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x45f41cb0 uwb_rc_ie_rm +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x487aa8e0 uwb_rc_neh_error +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4a65b2ee uwb_pal_init +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4c1c4dea uwb_rc_reset_all +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4d57ae3c uwb_rsv_type_str +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4d7ef33c uwb_rc_add +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x5a1a5f78 uwb_rsv_terminate +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x5b4c9452 uwb_rc_get_by_dev +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x6625c91d dump_bytes +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x6b9377c5 uwb_ie_next +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x6c520475 uwb_rsv_accept +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7367dfcc uwb_rsv_modify +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7613c0e2 uwb_rsv_state_str +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x80e5fccc uwb_rc_ie_add +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x85b780e3 uwb_pal_unregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x85de05ea uwb_ie_for_each +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x8cb42db6 __uwb_addr_print +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x8e2d74dc uwb_notifs_deregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x8fde6d5a uwb_rsv_establish +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x9024117b uwb_notifs_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x9058988e uwb_dev_try_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa1a00900 uwb_rc_init +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa4f8bc8c uwb_ie_dump_hex +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xaaf6cdc5 uwb_rsv_destroy +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xb4a066c1 uwb_rc_alloc +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xb7c8c825 uwb_rc_cmd +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xbf6a1b3d uwb_rc_get_ie +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xc348d995 uwb_pal_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xd3fcb9ba uwb_rc_put +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xdc71b8e0 uwb_rc_dev_addr_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xdf769559 uwb_rc_get_by_grandpa +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe6077cba uwb_rc_neh_grok +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xeb4cab9a uwb_est_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xefddc9f6 uwb_dev_for_each +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xf7ca313a uwb_est_unregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xfd6df965 __uwb_rc_try_get +EXPORT_SYMBOL_GPL drivers/uwb/whci 0xf52983e0 whci_wait_for +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x1e2d0c54 wlp_wss_activate_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x21084b65 wlp_dev_manufacturer_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x2b831457 wlp_setup +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x31e5d7aa wlp_dev_serial_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x3391dfe3 wlp_wss_setup +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x37b0f845 wlp_wss_activate_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x3c6694bb wlp_dev_name_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x456ddf13 wlp_dev_model_nr_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x4622e57e wlp_uuid_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x463db906 wlp_reset_all +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x4e37d99d wlp_uuid_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x4eba6030 wlp_eda_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x51c027fd wlp_dev_model_nr_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x51e568ed wlp_dev_prim_OUI_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x54d51db2 wlp_dev_name_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x646086cc wlp_dev_serial_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x682408ec wlp_wss_remove +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x6d162f73 wlp_prepare_tx_frame +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x72eaf9e2 wlp_dev_prim_category_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x74fe4fd8 wlp_dev_prim_OUI_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x766a54c7 wlp_dev_prim_subcat_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x7ea9242b wlp_neighborhood_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x83cbe4f3 wlp_dev_prim_subcat_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x8b11c01f wlp_dev_prim_OUI_sub_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x9a019108 wlp_dev_prim_OUI_sub_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xa19777ed wlp_receive_frame +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xa90e2058 wlp_remove +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xc471e812 wlp_eda_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xcd713803 wlp_dev_model_name_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xcde35b91 wlp_dev_model_name_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xd040056b wlp_dev_prim_category_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xfd0e1141 wlp_dev_manufacturer_show +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x0ecda790 ili9320_suspend +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x189f512a ili9320_shutdown +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x1cdcedaa ili9320_resume +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x3a8cfebc ili9320_write_regs +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x3c65e516 ili9320_write +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0xe00410c5 ili9320_probe_spi +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0xe1132254 ili9320_remove +EXPORT_SYMBOL_GPL drivers/video/fb_ddc 0x3f5d05fe fb_ddc_read +EXPORT_SYMBOL_GPL drivers/video/fb_sys_fops 0x30eaeb84 fb_sys_write +EXPORT_SYMBOL_GPL drivers/video/fb_sys_fops 0x39bb34e9 fb_sys_read +EXPORT_SYMBOL_GPL drivers/video/sis/sisfb 0x5bdf8447 sis_free_new +EXPORT_SYMBOL_GPL drivers/video/sis/sisfb 0x6ce9fa59 sis_malloc_new +EXPORT_SYMBOL_GPL drivers/video/vermilion/vmlfb 0x016e6c20 vmlfb_unregister_subsys +EXPORT_SYMBOL_GPL drivers/video/vermilion/vmlfb 0x90c018c6 vmlfb_register_subsys +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x1bf1bae0 virtio_check_driver_offered_feature +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x36c04a91 register_virtio_device +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x7176ad10 unregister_virtio_driver +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x74c0608e register_virtio_driver +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0xfcdd6498 unregister_virtio_device +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x03c4687d vring_interrupt +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x4f924c62 vring_del_virtqueue +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x67d130a2 vring_transport_features +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x7274b59b vring_new_virtqueue +EXPORT_SYMBOL_GPL drivers/w1/wire 0x0472e1dc w1_reset_bus +EXPORT_SYMBOL_GPL drivers/w1/wire 0x3c93f792 w1_write_block +EXPORT_SYMBOL_GPL drivers/w1/wire 0x5e2d88f7 w1_write_8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0x7c2f2afb w1_calc_crc8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0x90a52159 w1_read_block +EXPORT_SYMBOL_GPL drivers/w1/wire 0x9f1117d5 w1_read_8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0xdba68dd7 w1_reset_select_slave +EXPORT_SYMBOL_GPL drivers/w1/wire 0xddb5bcb3 w1_next_pullup +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x9321df95 dlm_lock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xac959fb6 dlm_posix_lock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xcf9f3328 dlm_release_lockspace +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xdc583c08 dlm_unlock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xdf3c14de dlm_new_lockspace +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xe8bb8f15 dlm_posix_unlock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xeb3985a3 dlm_posix_get +EXPORT_SYMBOL_GPL fs/exportfs/exportfs 0x0266d6d3 exportfs_encode_fh +EXPORT_SYMBOL_GPL fs/exportfs/exportfs 0xf12a8826 exportfs_decode_fh +EXPORT_SYMBOL_GPL fs/fat/fat 0x0136ffef fat_search_long +EXPORT_SYMBOL_GPL fs/fat/fat 0x02724089 fat_getattr +EXPORT_SYMBOL_GPL fs/fat/fat 0x0e018f20 fat_flush_inodes +EXPORT_SYMBOL_GPL fs/fat/fat 0x20779f0f fat_get_dotdot_entry +EXPORT_SYMBOL_GPL fs/fat/fat 0x2ad961cb fat_free_clusters +EXPORT_SYMBOL_GPL fs/fat/fat 0x5882a717 fat_scan +EXPORT_SYMBOL_GPL fs/fat/fat 0x6d832825 fat_time_unix2fat +EXPORT_SYMBOL_GPL fs/fat/fat 0x815779cb fat_detach +EXPORT_SYMBOL_GPL fs/fat/fat 0x888bf742 fat_alloc_new_dir +EXPORT_SYMBOL_GPL fs/fat/fat 0x8a16e2e6 fat_fill_super +EXPORT_SYMBOL_GPL fs/fat/fat 0x92c12179 fat_remove_entries +EXPORT_SYMBOL_GPL fs/fat/fat 0x9307fc43 fat_fs_panic +EXPORT_SYMBOL_GPL fs/fat/fat 0x933e5c5a fat_attach +EXPORT_SYMBOL_GPL fs/fat/fat 0xbe3feb62 fat_add_entries +EXPORT_SYMBOL_GPL fs/fat/fat 0xc26b821d fat_dir_empty +EXPORT_SYMBOL_GPL fs/fat/fat 0xed37a4f9 fat_build_inode +EXPORT_SYMBOL_GPL fs/fat/fat 0xfaff4cd9 fat_sync_inode +EXPORT_SYMBOL_GPL fs/fat/fat 0xfb89844d fat_setattr +EXPORT_SYMBOL_GPL fs/gfs2/gfs2 0x3f3c16bf gfs2_unregister_lockproto +EXPORT_SYMBOL_GPL fs/gfs2/gfs2 0x4a8c63a9 gfs2_register_lockproto +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x17ce645d locks_end_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x1a618932 nlmsvc_unlock_all_by_ip +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x2371b1df nlmclnt_proc +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x254e410a nlmclnt_done +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x6f959b35 locks_in_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x9080d4b5 nlmclnt_init +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x96877ac4 locks_start_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0xa5c4eea0 nlmsvc_unlock_all_by_sb +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x15d2bc28 o2nm_get_node_by_num +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x1b89c6ee o2hb_fill_node_map +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x1d747ce3 o2hb_check_node_heartbeating +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x36418553 o2net_send_message +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x3afe3972 o2hb_register_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x3b2a9a0a o2hb_setup_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x4900035b o2hb_stop_all_regions +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x521e0726 o2net_send_message_vec +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x6854fed3 o2hb_unregister_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x80e8842a o2nm_node_put +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x81a17396 mlog_and_bits +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x8f0355cf o2nm_node_get +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x9e312427 o2nm_get_node_by_ip +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xa82a8645 o2nm_this_node +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xa87bc9e7 o2nm_configured_node_map +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xae808bac o2net_register_handler +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xbaeb4700 o2hb_check_node_heartbeating_from_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xd60f2c6c o2hb_check_local_node_heartbeating +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xf1a5611d o2net_unregister_handler_list +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xf56c2017 mlog_not_bits +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x026be456 dlm_register_domain +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x7a1211f8 dlm_setup_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x92ba250c dlmunlock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x97676965 dlm_register_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xcbc0b1f5 dlm_print_one_lock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xcd561950 dlmlock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xd7ba575e dlm_errmsg +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xd8fa57a6 dlm_unregister_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xec4a224b dlm_unregister_domain +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xfb86b96f dlm_errname +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x0562c415 ocfs2_cluster_this_node +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x0e27f909 ocfs2_dlm_lock +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x21db5b88 ocfs2_cluster_disconnect +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x390ef9ae ocfs2_stack_glue_register +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x4a1f6fe9 ocfs2_cluster_connect +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x4d3af7fa ocfs2_cluster_hangup +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x81c85a68 ocfs2_dlm_lock_status +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x91fab465 ocfs2_dlm_lvb +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x963932a3 ocfs2_stack_glue_set_locking_protocol +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xa7d5c1c0 ocfs2_dlm_unlock +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xad9bfc8d ocfs2_plock +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xbbc4ef97 ocfs2_stack_supports_plocks +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xd066711e ocfs2_dlm_dump_lksb +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xf7ad83ed ocfs2_stack_glue_unregister +EXPORT_SYMBOL_GPL lib/lzo/lzo_compress 0x2e1d43cf lzo1x_1_compress +EXPORT_SYMBOL_GPL lib/lzo/lzo_decompress 0x2a1538ca lzo1x_decompress_safe +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0x300d7e57 free_rs +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0x6fbb3bd9 init_rs_non_canonical +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0xabda1e2e decode_rs16 +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0xb050f329 init_rs +EXPORT_SYMBOL_GPL net/802/garp 0x1907f7f3 garp_request_leave +EXPORT_SYMBOL_GPL net/802/garp 0x39a7cae9 garp_uninit_applicant +EXPORT_SYMBOL_GPL net/802/garp 0x419c4b47 garp_request_join +EXPORT_SYMBOL_GPL net/802/garp 0x482d6edf garp_register_application +EXPORT_SYMBOL_GPL net/802/garp 0xb6d9aeac garp_unregister_application +EXPORT_SYMBOL_GPL net/802/garp 0xdbbdc05b garp_init_applicant +EXPORT_SYMBOL_GPL net/802/stp 0x1afd488c stp_proto_register +EXPORT_SYMBOL_GPL net/802/stp 0x541174cd stp_proto_unregister +EXPORT_SYMBOL_GPL net/ax25/ax25 0xa05d6568 ax25_register_pid +EXPORT_SYMBOL_GPL net/ax25/ax25 0xac93ae05 ax25_bcast +EXPORT_SYMBOL_GPL net/ax25/ax25 0xaeb7451e ax25_defaddr +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x09c5ed3c tfrc_tx_hist_purge +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x0a487ea5 tfrc_calc_x +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x106fe6d3 tfrc_tx_hist_rtt +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x15ea8043 tfrc_lh_update_i_mean +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x31b68851 tfrc_rx_hist_duplicate +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x356e87b1 tfrc_rx_hist_add_packet +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x69ec5731 tfrc_tx_hist_add +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x6c252d29 tfrc_calc_x_reverse_lookup +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x71afb660 tfrc_rx_handle_loss +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x72b3baaa tfrc_lh_interval_add +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x87d92541 tfrc_rx_hist_sample_rtt +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x902206f0 tfrc_lh_cleanup +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x92285650 tfrc_rx_hist_alloc +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xc612a5b6 tfrc_rx_hist_purge +EXPORT_SYMBOL_GPL net/dccp/dccp 0x10974018 dccp_insert_option_timestamp +EXPORT_SYMBOL_GPL net/dccp/dccp 0x14043931 ccid_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0x1637cb01 dccp_parse_options +EXPORT_SYMBOL_GPL net/dccp/dccp 0x16566c00 dccp_send_sync +EXPORT_SYMBOL_GPL net/dccp/dccp 0x1d99d49a dccp_timestamp +EXPORT_SYMBOL_GPL net/dccp/dccp 0x20c7dde8 dccp_hashinfo +EXPORT_SYMBOL_GPL net/dccp/dccp 0x28402e98 dccp_connect +EXPORT_SYMBOL_GPL net/dccp/dccp 0x2fec6c12 compat_dccp_setsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x37a4fa7c dccp_destroy_sock +EXPORT_SYMBOL_GPL net/dccp/dccp 0x3b3c0b1b dccp_feat_clean +EXPORT_SYMBOL_GPL net/dccp/dccp 0x43156bbd dccp_disconnect +EXPORT_SYMBOL_GPL net/dccp/dccp 0x494a5d53 dccp_check_req +EXPORT_SYMBOL_GPL net/dccp/dccp 0x495c66bb dccp_sendmsg +EXPORT_SYMBOL_GPL net/dccp/dccp 0x4998d38e ccid_hc_tx_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0x4cd7aacc dccp_poll +EXPORT_SYMBOL_GPL net/dccp/dccp 0x5693fbe8 dccp_close +EXPORT_SYMBOL_GPL net/dccp/dccp 0x56ea266a dccp_state_name +EXPORT_SYMBOL_GPL net/dccp/dccp 0x5bcb7dee dccp_sample_rtt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x5ccd4c15 dccp_feat_clone +EXPORT_SYMBOL_GPL net/dccp/dccp 0x6600112b dccp_setsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x688da138 dccp_child_process +EXPORT_SYMBOL_GPL net/dccp/dccp 0x6d33b26f ccid_hc_tx_delete +EXPORT_SYMBOL_GPL net/dccp/dccp 0x7028c505 dccp_feat_change_recv +EXPORT_SYMBOL_GPL net/dccp/dccp 0x7a4619d9 ccid_unregister +EXPORT_SYMBOL_GPL net/dccp/dccp 0x7b461540 dccp_feat_confirm_recv +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8503e110 dccp_create_openreq_child +EXPORT_SYMBOL_GPL net/dccp/dccp 0x86be7924 dccp_packet_name +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8a091a2d dccp_sync_mss +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8b7d8caf dccp_statistics +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8cc71d51 inet_dccp_listen +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8f3ecb0c dccp_getsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x90debbee dccp_set_state +EXPORT_SYMBOL_GPL net/dccp/dccp 0x9d6a3846 dccp_orphan_count +EXPORT_SYMBOL_GPL net/dccp/dccp 0xad61e86b dccp_insert_option +EXPORT_SYMBOL_GPL net/dccp/dccp 0xaf0e02db compat_dccp_getsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0xb091c29d dccp_death_row +EXPORT_SYMBOL_GPL net/dccp/dccp 0xb35ac20d dccp_ctl_make_reset +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbe4cf010 dccp_feat_init +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbf6b58ba dccp_feat_change +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbfb58e6e dccp_make_response +EXPORT_SYMBOL_GPL net/dccp/dccp 0xc27d1bb5 dccp_done +EXPORT_SYMBOL_GPL net/dccp/dccp 0xc3819a5d dccp_init_sock +EXPORT_SYMBOL_GPL net/dccp/dccp 0xd6ad6750 dccp_ioctl +EXPORT_SYMBOL_GPL net/dccp/dccp 0xd77f200e dccp_reqsk_init +EXPORT_SYMBOL_GPL net/dccp/dccp 0xdcaa3d66 ccid_hc_rx_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0xe23c4af4 dccp_shutdown +EXPORT_SYMBOL_GPL net/dccp/dccp 0xe86782c0 dccp_insert_option_elapsed_time +EXPORT_SYMBOL_GPL net/dccp/dccp 0xe97659fb dccp_send_ack +EXPORT_SYMBOL_GPL net/dccp/dccp 0xefed8c40 dccp_recvmsg +EXPORT_SYMBOL_GPL net/dccp/dccp 0xf382535a dccp_rcv_established +EXPORT_SYMBOL_GPL net/dccp/dccp 0xf40ae2b9 dccp_rcv_state_process +EXPORT_SYMBOL_GPL net/dccp/dccp 0xfa5b159a dccp_reqsk_send_ack +EXPORT_SYMBOL_GPL net/dccp/dccp 0xfd976ae1 ccid_hc_rx_delete +EXPORT_SYMBOL_GPL net/dccp/dccp 0xffc1aa07 ccid_register +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x5a2545c5 dccp_v4_request_recv_sock +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x72eba005 dccp_invalid_packet +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x7b5e5f62 dccp_v4_do_rcv +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0xac656af5 dccp_v4_send_check +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0xcb76e5cf dccp_v4_connect +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0xdc87d192 dccp_v4_conn_request +EXPORT_SYMBOL_GPL net/ieee80211/ieee80211 0x5fcca57a ieee80211_rx_any +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_conntrack_ipv4 0x6d40a921 need_ipv4_conntrack +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_conntrack_ipv4 0x9e345380 nf_nat_seq_adjust_hook +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_defrag_ipv4 0x6b6c3d10 nf_defrag_ipv4_enable +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x07ae60b6 nf_nat_proto_in_range +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x2ff913ca nf_nat_proto_put +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x36f80f48 nf_nat_icmp_reply_translation +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x59c3072f nf_nat_proto_unique_tuple +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x768ad038 nf_nat_packet +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x8fc7d688 nf_nat_proto_find_get +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x94a08134 nf_nat_proto_nlattr_to_range +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0xe8b2ed48 nf_nat_proto_range_to_nlattr +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat_proto_gre 0x636b12c8 nf_nat_need_gre +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x00c70b0c tcp_vegas_get_info +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x1507817f tcp_vegas_init +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x515ac83c tcp_vegas_cwnd_event +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x8a3d5a53 tcp_vegas_pkts_acked +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0xd1c0f3f3 tcp_vegas_state +EXPORT_SYMBOL_GPL net/mac80211/mac80211 0x1f4da46d ieee80211_iterate_active_interfaces_atomic +EXPORT_SYMBOL_GPL net/mac80211/mac80211 0x327fae20 ieee80211_iterate_active_interfaces +EXPORT_SYMBOL_GPL net/netfilter/ipvs/ip_vs 0xe6476b4a net_vs_ctl_path +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x03e6f688 nf_ct_l4proto_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x041013fd nf_conntrack_lock +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x045072cd nf_ct_port_nla_policy +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x1283d711 nf_ct_expect_unregister_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x15c10b0b nf_conntrack_unregister_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x16f36638 __nf_conntrack_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x21756e3d __nf_ct_kill_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x23b10ece nf_conntrack_alloc +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x24fde9a4 nf_ct_helper_ext_add +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x251f8acf nf_conntrack_tcp_update +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x28f7c555 nf_ct_get_tuplepr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x2bcc7114 seq_print_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3560f027 __nf_ct_expect_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x38630158 nf_conntrack_tuple_taken +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x38c9440b nf_ct_extend_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x39ea4343 nf_ct_unexpect_related +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3b5fde34 nf_ct_get_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3e41b53c nf_conntrack_l3proto_generic +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3f5b1415 nf_ct_port_nlattr_to_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x40387ccf __nf_ct_event_cache_init +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x4a94e585 nf_conntrack_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x4b5d5821 nf_ct_invert_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x4c9316c1 print_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x596a3590 __nf_ct_l4proto_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x60105d3e nf_conntrack_helper_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x68f1f18f nf_ct_expect_related +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x69669e24 nf_ct_unlink_expect +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x6e224a7a need_conntrack +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x70db8eb4 nf_ct_expect_init +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x71c92394 nf_conntrack_l3proto_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x72836f4a nf_conntrack_free +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x77aadb54 nf_conntrack_alter_reply +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x78bbf824 nf_ct_iterate_cleanup +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x78f9b710 nf_ct_l3proto_try_module_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x79ca2e53 nf_ct_expect_chain +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x80a3ee17 __nf_conntrack_helper_find_byname +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x81dd6ad8 nf_conntrack_l4proto_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x8341414f nf_ct_expect_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x8ffe7e89 nf_conntrack_htable_size +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x90ff6c9f nf_ct_invert_tuplepr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x92e72b76 nf_ct_l3proto_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x985888b9 nf_conntrack_l4proto_udp6 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa6f62ec0 nf_conntrack_set_hashsize +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa9083557 nf_conntrack_flush +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa99022d8 nf_ct_expect_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xaa6eea3b nf_conntrack_l4proto_udp4 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xaa74a0d1 nf_conntrack_l3proto_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xaf57e66f nf_ct_extend_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb320d303 nf_conntrack_in +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb4cd4bb2 __nf_ct_helper_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb602c57e nf_ct_l3proto_module_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xba619e5a nf_ct_l3proto_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbc887e16 nf_ct_expect_register_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbfad5f95 nf_conntrack_l4proto_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc044befe nf_ct_free_hashtable +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc18ac88d nf_ct_expect_hsize +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc1d36191 nf_conntrack_l4proto_tcp6 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc35a7a3e nf_conntrack_chain +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc7b64d79 nf_conntrack_hash_insert +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xcbf7fd2a nf_conntrack_register_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xcc81e5df nf_ct_l3protos +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd2a9ba10 nf_ct_port_tuple_to_nlattr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd50a96a2 nf_ct_alloc_hashtable +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd850f41b __nf_conntrack_confirm +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd9efb053 nf_ct_deliver_cached_events +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xdbbb77f3 nf_ct_expect_alloc +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xe6acae30 nf_conntrack_helper_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xed10d319 nf_ct_l4proto_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf3e50313 nf_conntrack_l4proto_tcp4 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf4d36579 __nf_ct_refresh_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf9ae81a1 nf_conntrack_max +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfa169dac nf_conntrack_untracked +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfb839673 nf_ct_remove_expectations +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xff9e9fc3 nfnetlink_parse_nat_setup_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_amanda 0x50c0c5e7 nf_nat_amanda_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_ftp 0x73278174 nf_nat_ftp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x25d58ef2 set_h225_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x264c0cf3 get_h225_addr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x384e1de8 nat_h245_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x4f2319d4 nat_rtp_rtcp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x96b1910d set_sig_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x98a7874e nat_callforwarding_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xb24a46ff set_h245_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xcafb4002 nat_q931_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xef8a1092 nat_t120_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xf3e163c1 set_ras_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_irc 0x436fd424 nf_nat_irc_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x0e1d2562 nf_nat_pptp_hook_exp_gre +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x65277d44 nf_nat_pptp_hook_expectfn +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0xce4daed2 nf_nat_pptp_hook_outbound +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0xfdb657f9 nf_nat_pptp_hook_inbound +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_proto_gre 0x05f8e58c nf_ct_gre_keymap_destroy +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_proto_gre 0x6f59d77c nf_ct_gre_keymap_add +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x13169b79 ct_sip_parse_request +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x23c04245 nf_nat_sip_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x2be122f2 nf_nat_sip_expect_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x3c2058a6 ct_sip_parse_numerical_param +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x5301a261 nf_nat_sdp_media_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x5333cb69 ct_sip_parse_header_uri +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x5343611e ct_sip_get_sdp_header +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x56ad8f6e ct_sip_parse_address_param +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x640dc776 nf_nat_sdp_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x99030709 nf_nat_sdp_session_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xc965cb05 nf_nat_sdp_port_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xf8b610ea ct_sip_get_header +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_tftp 0xb9dcc58a nf_nat_tftp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_tproxy_core 0xf19a8cf1 nf_tproxy_assign_sock +EXPORT_SYMBOL_GPL net/netfilter/nf_tproxy_core 0xf47d9002 nf_tproxy_get_sock_v4 +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x1f58e71b nfnl_lock +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x3895cd7a nfnl_unlock +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x48e4dbc5 nfnetlink_subsys_unregister +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x7ce8bf80 nfnetlink_subsys_register +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xa849b6f4 nfnetlink_send +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xeca95329 nfnetlink_has_listeners +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xefce3605 nfnetlink_unicast +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x161d1417 xt_compat_unlock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x19706b65 xt_proto_init +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x19eeb63e xt_compat_target_from_user +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x26e90a50 xt_request_find_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x40728a63 xt_find_revision +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x419232be xt_check_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x54b2c95b xt_check_match +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x57c6befb xt_table_unlock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x5d677a07 xt_compat_target_to_user +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x5f82f1f7 xt_compat_flush_offsets +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x684694c5 xt_compat_add_offset +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x6ab3db46 xt_register_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x6f66f520 xt_compat_match_offset +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x6f901533 xt_compat_match_to_user +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x6f9aa2fb xt_compat_calc_jump +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x70004e75 xt_proto_fini +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x72997956 xt_find_table_lock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x74bc21f9 xt_compat_match_from_user +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x9c0a97c8 xt_unregister_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xb32f3d92 xt_replace_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xdc90d2f4 xt_compat_target_offset +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xe0b4971b xt_compat_lock +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0xc177bee0 xt_rateest_put +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0xdb8418cc xt_rateest_lookup +EXPORT_SYMBOL_GPL net/rxrpc/af-rxrpc 0x621683e2 rxrpc_register_security +EXPORT_SYMBOL_GPL net/rxrpc/af-rxrpc 0xf1baf687 rxrpc_unregister_security +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x002ac26c xprt_update_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x01d98f83 xprt_register_transport +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x0a4db2dd xprt_release_xprt_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x113e21ea rpc_wake_up_next +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x14048ac2 xprt_wait_for_buffer_space +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x163c46fc xdr_skb_read_bits +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1670dc9b rpc_print_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x19a1d725 rpc_exit_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1c7437de xprt_release_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2069c8c1 svc_print_addr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2156d2ac rpc_shutdown_client +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x23f414a5 rpcb_getport_async +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x241244fd rpcauth_lookup_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x25901e9e svc_reg_xprt_class +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x28f7c105 svc_xprt_names +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2aa17774 rpc_free_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2e10bbe3 rpcauth_create +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x31a89d59 rpc_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x35a51449 svc_xprt_enqueue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x36644df1 rpc_peeraddr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3d1840c7 csum_partial_copy_to_xdr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3d9a2e05 svc_xprt_init +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3e517319 rpc_create +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3f66a753 rpcauth_unregister +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x402a5c3c xprt_disconnect_done +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x432fd9cd xprt_reserve_xprt_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x48a22506 rpc_force_rebind +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x49626223 svc_addsock +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x52c38aca xprt_release_rqst_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x52dfc220 rpcauth_register +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x53445f68 nlm_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x547b35e5 __rpc_wait_for_completion_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x54c5a5ed rpc_setbufsize +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x54f9fcb9 xprt_unregister_transport +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x550547a3 rpc_destroy_wait_queue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5bd26000 rpc_proc_unregister +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5c3bee35 rpc_killall_tasks +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5fceded6 xprt_wake_pending_tasks +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x68a230d8 xprt_complete_rqst +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6abc3aac rpc_lookup_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6bcab895 rpc_malloc +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6c5304c5 rpcb_getport_sync +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6cb98b9e rpc_call_start +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6e8e67f2 put_rpccred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7140304d xprt_write_space +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x77a52650 svc_max_payload +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x78c2d5a6 rpc_restart_call +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7c4378cf svc_xprt_copy_addrs +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7de53067 rpc_init_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7fec05c9 rpc_sleep_on +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8231b07b rpc_call_null +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x82601ccc rpc_call_sync +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x82ecc76d rpc_bind_new_program +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x847ca0f8 rpc_wake_up_queued_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x887f3ebf xprt_lookup_rqst +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8a5d3c5c rpcauth_init_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8ac504cb svc_xprt_received +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8c2f79c4 rpc_delay +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8c3a23e2 rpc_lookup_machine_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8d40819c xprt_reserve_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8f059ce2 xprt_set_retrans_timeout_def +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x91963df9 rpc_put_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x931a8c3a rpc_clone_client +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x9958edad xprt_adjust_cwnd +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xaa2e822d xdr_partial_copy_from_skb +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xac49b2cd svc_create_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xaf5bf6ef nfs_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb2af9ba6 svc_find_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb387b246 rpc_wake_up_status +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb4b21aaa rpcauth_destroy_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb59a9f44 rpcauth_generic_bind_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb6c99ad2 rpc_alloc_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb9cc8e73 svc_xprt_put +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbbfd23a7 rpc_max_payload +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbc6522e3 svc_close_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbf9d1b96 nfsd_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc12435e3 rpc_calc_rto +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xcb23e955 rpc_proc_register +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xcc34c30c rpc_run_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd82c728e rpc_init_wait_queue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe0791c55 xprt_set_retrans_timeout_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe264e665 rpc_call_async +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xedd1ba52 rpc_wake_up +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xeeacab69 rpc_update_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xf47cf370 svc_unreg_xprt_class +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xf97dcd0c rpcauth_init_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xf9d1164c rpc_free +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xfe7bd420 rpc_peeraddr2str +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0x66e88335 ipcomp_input +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0xa9d45aa6 ipcomp_destroy +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0xd0805fa8 ipcomp_output +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0xfb02881b ipcomp_init_state +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ad73311 0x1cb5c83b ad73311_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ad73311 0x845b2dc1 soc_codec_dev_ad73311 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ak4535 0x77471d3a soc_codec_dev_ak4535 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ak4535 0x838102d5 ak4535_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-cs4270 0x0d21b27a soc_codec_device_cs4270 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-cs4270 0x41d3c6b1 cs4270_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ssm2602 0x95f87230 soc_codec_dev_ssm2602 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ssm2602 0xaa151fac ssm2602_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic23 0x995b6318 tlv320aic23_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic23 0xc1734253 soc_codec_dev_tlv320aic23 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic26 0x8c28beee aic26_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic26 0xc53b26d1 aic26_soc_codec_dev +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0x13c1634a aic3x_headset_detected +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0x1980b6eb soc_codec_dev_aic3x +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0x1f0dde46 aic3x_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0xcf6335ac aic3x_set_gpio +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0xd66a4989 aic3x_get_gpio +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-uda1380 0x7adf09ad uda1380_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-uda1380 0xca77a054 soc_codec_dev_uda1380 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8510 0x1e139af9 soc_codec_dev_wm8510 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8510 0xe9ba0f94 wm8510_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8580 0x11c2a176 soc_codec_dev_wm8580 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8580 0xb4b1012b wm8580_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8731 0xae85b75d soc_codec_dev_wm8731 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8731 0xf75cca65 wm8731_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8750 0x5fd02cfa wm8750_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8750 0xb313faae soc_codec_dev_wm8750 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8753 0x983ea96d soc_codec_dev_wm8753 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8753 0xc64cf916 wm8753_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8900 0x1862116f wm8900_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8900 0x55074f76 soc_codec_dev_wm8900 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8903 0x7e2a1cb5 soc_codec_dev_wm8903 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8903 0x9ef663c1 wm8903_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8971 0x1699fc44 wm8971_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8971 0x495368b2 soc_codec_dev_wm8971 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8990 0x5ad674f9 soc_codec_dev_wm8990 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8990 0x8dfa54bc wm8990_dai +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x0d90fd92 snd_soc_info_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x174819d7 snd_soc_dai_set_sysclk +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x17a8e76e snd_soc_dapm_stream_event +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x1ae4e512 snd_soc_set_runtime_hwparams +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x1b695f20 snd_soc_info_enum_ext +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x1dfbeec0 snd_soc_get_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x255863f0 snd_soc_free_ac97_codec +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x34dbdc5a snd_soc_get_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x360be706 snd_soc_dapm_enable_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x39847c93 snd_soc_dapm_get_pin_status +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x3af51347 snd_soc_dai_set_tdm_slot +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x3c58273d snd_soc_new_ac97_codec +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x413b9922 snd_soc_put_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x414c6e01 snd_soc_dapm_nc_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x43b72d05 snd_soc_dapm_add_routes +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x50e5e9a2 snd_soc_dai_set_pll +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x54bc73da snd_soc_dapm_new_control +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x6300a7fc snd_soc_dapm_get_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x68f545e9 snd_soc_cnew +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x6a0ba3cb snd_soc_get_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x6a1d8e65 snd_soc_put_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x6c4d562d snd_soc_update_bits +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x6c7e1b37 snd_soc_info_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x6f9afb35 snd_soc_dapm_new_controls +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x76179d9f snd_soc_new_pcms +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x766999e5 snd_soc_info_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x78b36b96 snd_soc_dapm_free +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x7f2d6ef3 snd_soc_register_card +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x848f3528 snd_soc_info_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x8d15478b snd_soc_dapm_sync +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x901b121b snd_soc_get_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x902714ea snd_soc_dapm_put_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x992c10dd snd_soc_put_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xa24e5105 snd_soc_free_pcms +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xa3d11ce8 dapm_reg_event +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xa9dbbebc snd_soc_dai_digital_mute +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xb328fa1b snd_soc_dapm_put_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xb332d7b5 snd_soc_dai_set_fmt +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xb92c2e11 snd_soc_info_volsw_ext +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xc6c8bf63 snd_soc_dapm_get_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xd85d2ea1 snd_soc_dapm_connect_input +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xda7875c0 snd_soc_dapm_new_widgets +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xdcc7f200 snd_soc_dai_set_tristate +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xe6844609 snd_soc_dapm_disable_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xe7fd72be snd_soc_put_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xebbfacc3 snd_soc_dai_set_clkdiv +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xf171c0f1 snd_soc_test_bits +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x0d93d0e1 tlsf_create_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x1584fdb9 tlsf_destroy_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x2c383ca4 tlsf_calloc +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x54064cb9 tlsf_get_used_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x60d233a6 tlsf_malloc +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xbe77d1fe tlsf_get_total_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xe6acc368 tlsf_free +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x02500586 thinkpad_ec_unlock +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x0dc7484e thinkpad_ec_try_read_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x2552d213 thinkpad_ec_lock +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x3dbfef12 thinkpad_ec_read_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x8dbbd831 thinkpad_ec_invalidate +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0xa3042743 thinkpad_ec_prefetch_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0xfb5aa917 thinkpad_ec_try_lock +EXPORT_SYMBOL_GPL vmlinux 0x00566d8f inotify_get_cookie +EXPORT_SYMBOL_GPL vmlinux 0x0067df75 ata_tf_from_fis +EXPORT_SYMBOL_GPL vmlinux 0x006d7cad srcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x00b8ecf8 __iowrite32_copy +EXPORT_SYMBOL_GPL vmlinux 0x00c6cc8f kobject_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0x00ebcb5d ata_id_string +EXPORT_SYMBOL_GPL vmlinux 0x0110b3d1 register_hotplug_dock_device +EXPORT_SYMBOL_GPL vmlinux 0x0146ef74 elv_register +EXPORT_SYMBOL_GPL vmlinux 0x01848a8e local_apic_timer_c2_ok +EXPORT_SYMBOL_GPL vmlinux 0x01a4ea6d unregister_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x01e06afe device_reprobe +EXPORT_SYMBOL_GPL vmlinux 0x01e1a8de kgdb_breakpoint +EXPORT_SYMBOL_GPL vmlinux 0x020a0f8a devres_remove +EXPORT_SYMBOL_GPL vmlinux 0x02121d51 sdio_readsb +EXPORT_SYMBOL_GPL vmlinux 0x0275003e pci_bus_add_device +EXPORT_SYMBOL_GPL vmlinux 0x028e6f97 __blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x02a0738f xattr_getsecurity +EXPORT_SYMBOL_GPL vmlinux 0x02ccea56 lock_policy_rwsem_write +EXPORT_SYMBOL_GPL vmlinux 0x030a1563 device_destroy +EXPORT_SYMBOL_GPL vmlinux 0x031bcb4a single_release_net +EXPORT_SYMBOL_GPL vmlinux 0x0343bdf1 __i2c_board_list +EXPORT_SYMBOL_GPL vmlinux 0x0349e695 register_posix_clock +EXPORT_SYMBOL_GPL vmlinux 0x03505c33 rtc_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x03608e3c skb_icv_walk +EXPORT_SYMBOL_GPL vmlinux 0x036a5b83 page_cache_async_readahead +EXPORT_SYMBOL_GPL vmlinux 0x03caa330 user_update +EXPORT_SYMBOL_GPL vmlinux 0x03e3686c ata_timing_cycle2mode +EXPORT_SYMBOL_GPL vmlinux 0x03e7c75d devres_find +EXPORT_SYMBOL_GPL vmlinux 0x03fe2cca flush_work +EXPORT_SYMBOL_GPL vmlinux 0x04011ed8 tty_ldisc_deref +EXPORT_SYMBOL_GPL vmlinux 0x04136bca klist_init +EXPORT_SYMBOL_GPL vmlinux 0x0417078b pci_execute_reset_function +EXPORT_SYMBOL_GPL vmlinux 0x042194b9 scsi_execute_async +EXPORT_SYMBOL_GPL vmlinux 0x044210b0 gpiochip_is_requested +EXPORT_SYMBOL_GPL vmlinux 0x04486e88 rcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x044fc8ec usb_get_hcd +EXPORT_SYMBOL_GPL vmlinux 0x04566c7f init_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x04711ee6 ata_host_register +EXPORT_SYMBOL_GPL vmlinux 0x049fcd7d inet6_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0x04b60a2b ata_qc_complete_multiple +EXPORT_SYMBOL_GPL vmlinux 0x04c2d05a __rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0x04c3f2c1 gnttab_empty_grant_references +EXPORT_SYMBOL_GPL vmlinux 0x04e628cd leds_list_lock +EXPORT_SYMBOL_GPL vmlinux 0x04ea8706 __iowrite64_copy +EXPORT_SYMBOL_GPL vmlinux 0x04f7df9a uv_teardown_irq +EXPORT_SYMBOL_GPL vmlinux 0x0514e03e user_destroy +EXPORT_SYMBOL_GPL vmlinux 0x0531dcb8 ata_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0x054e550b kernel_halt +EXPORT_SYMBOL_GPL vmlinux 0x05d19195 sysfs_notify +EXPORT_SYMBOL_GPL vmlinux 0x05d9d8e2 __ata_port_next_link +EXPORT_SYMBOL_GPL vmlinux 0x060d1064 set_memory_ro +EXPORT_SYMBOL_GPL vmlinux 0x060fbc7e raw_seq_next +EXPORT_SYMBOL_GPL vmlinux 0x064db9a5 mark_mounts_for_expiry +EXPORT_SYMBOL_GPL vmlinux 0x06d222f8 device_resume +EXPORT_SYMBOL_GPL vmlinux 0x06f8aa16 anon_transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x073b14bb usb_serial_generic_write_bulk_callback +EXPORT_SYMBOL_GPL vmlinux 0x073ed337 hvc_alloc +EXPORT_SYMBOL_GPL vmlinux 0x078f04ce xenbus_watch_path +EXPORT_SYMBOL_GPL vmlinux 0x079b170c hid_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0x07a3dddf xenbus_watch_pathfmt +EXPORT_SYMBOL_GPL vmlinux 0x07a92a87 put_device +EXPORT_SYMBOL_GPL vmlinux 0x07b52e38 rtnl_unregister +EXPORT_SYMBOL_GPL vmlinux 0x07d43a2a fixed_phy_set_link_update +EXPORT_SYMBOL_GPL vmlinux 0x07ff4aea xenbus_scanf +EXPORT_SYMBOL_GPL vmlinux 0x0838fe91 regulator_set_current_limit +EXPORT_SYMBOL_GPL vmlinux 0x085b4d3c get_current_tty +EXPORT_SYMBOL_GPL vmlinux 0x08a3e5d1 net_ipv6_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0x08bc0f1e sysfs_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x08d9d137 inotify_rm_wd +EXPORT_SYMBOL_GPL vmlinux 0x0906ea9f usb_sg_init +EXPORT_SYMBOL_GPL vmlinux 0x090c418c ata_sff_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x091eb9b4 round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0x09493a9a xfrm_audit_state_add +EXPORT_SYMBOL_GPL vmlinux 0x09bd30e5 hrtimer_init +EXPORT_SYMBOL_GPL vmlinux 0x09d60bea skb_to_sgvec +EXPORT_SYMBOL_GPL vmlinux 0x09e49c5e usb_ifnum_to_if +EXPORT_SYMBOL_GPL vmlinux 0x09f7810e inet_diag_register +EXPORT_SYMBOL_GPL vmlinux 0x0a28ac54 securityfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x0a2ca061 xfrm_audit_state_replay_overflow +EXPORT_SYMBOL_GPL vmlinux 0x0a88a700 crypto_larval_kill +EXPORT_SYMBOL_GPL vmlinux 0x0ad5c33f acpi_smbus_register_callback +EXPORT_SYMBOL_GPL vmlinux 0x0b0f8665 spi_new_device +EXPORT_SYMBOL_GPL vmlinux 0x0b17239a unregister_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0x0b19b744 ata_sas_port_stop +EXPORT_SYMBOL_GPL vmlinux 0x0b266d8b pci_hp_deregister +EXPORT_SYMBOL_GPL vmlinux 0x0b6e9149 tcp_twsk_unique +EXPORT_SYMBOL_GPL vmlinux 0x0c17e274 xfrm_aalg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x0c4717f7 srcu_init_notifier_head +EXPORT_SYMBOL_GPL vmlinux 0x0c577dba aead_geniv_free +EXPORT_SYMBOL_GPL vmlinux 0x0c5eaae8 regulator_bulk_enable +EXPORT_SYMBOL_GPL vmlinux 0x0ca02e41 ipv6_dup_options +EXPORT_SYMBOL_GPL vmlinux 0x0ca3c4fc driver_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x0d814646 klist_add_head +EXPORT_SYMBOL_GPL vmlinux 0x0d8f20da ata_sff_data_xfer_noirq +EXPORT_SYMBOL_GPL vmlinux 0x0daced87 transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x0dbf8659 devres_get +EXPORT_SYMBOL_GPL vmlinux 0x0de46caf udp4_lib_lookup +EXPORT_SYMBOL_GPL vmlinux 0x0e29bf3c driver_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x0e39b31d hidraw_report_event +EXPORT_SYMBOL_GPL vmlinux 0x0e5c6fd7 i2c_add_numbered_adapter +EXPORT_SYMBOL_GPL vmlinux 0x0e6e2682 crypto_alloc_ablkcipher +EXPORT_SYMBOL_GPL vmlinux 0x0e726910 usb_hcd_pci_suspend +EXPORT_SYMBOL_GPL vmlinux 0x0e7bf714 generic_fh_to_parent +EXPORT_SYMBOL_GPL vmlinux 0x0e8ae8d0 fb_deferred_io_open +EXPORT_SYMBOL_GPL vmlinux 0x0ebf0827 transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x0ec210b8 xen_start_info +EXPORT_SYMBOL_GPL vmlinux 0x0ed56c02 usb_submit_urb +EXPORT_SYMBOL_GPL vmlinux 0x0f20214f crypto_alloc_aead +EXPORT_SYMBOL_GPL vmlinux 0x0f2af6e2 dm_rh_get_state +EXPORT_SYMBOL_GPL vmlinux 0x0f38034f ata_acpi_stm +EXPORT_SYMBOL_GPL vmlinux 0x0f4cdef1 ata_pci_device_resume +EXPORT_SYMBOL_GPL vmlinux 0x0f4efaac sdio_enable_func +EXPORT_SYMBOL_GPL vmlinux 0x0f71d52d ata_pci_device_suspend +EXPORT_SYMBOL_GPL vmlinux 0x0f91bc8c get_cpu_sysdev +EXPORT_SYMBOL_GPL vmlinux 0x0f999ea0 sdio_set_block_size +EXPORT_SYMBOL_GPL vmlinux 0x0f9e7618 do_add_mount +EXPORT_SYMBOL_GPL vmlinux 0x0fe2d570 xenbus_directory +EXPORT_SYMBOL_GPL vmlinux 0x100c13c6 usb_kill_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x100c48a2 unregister_dock_notifier +EXPORT_SYMBOL_GPL vmlinux 0x105185f9 crypto_nivaead_type +EXPORT_SYMBOL_GPL vmlinux 0x10c4d3db disk_get_part +EXPORT_SYMBOL_GPL vmlinux 0x1131631b sata_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x1151aa97 ata_host_alloc_pinfo +EXPORT_SYMBOL_GPL vmlinux 0x117d6c8b klist_add_after +EXPORT_SYMBOL_GPL vmlinux 0x11f447ce __gpio_to_irq +EXPORT_SYMBOL_GPL vmlinux 0x11fabec5 usb_clear_halt +EXPORT_SYMBOL_GPL vmlinux 0x12350a68 __class_register +EXPORT_SYMBOL_GPL vmlinux 0x124f2056 crypto_get_attr_type +EXPORT_SYMBOL_GPL vmlinux 0x1251d30f call_rcu +EXPORT_SYMBOL_GPL vmlinux 0x1294d8a0 tcp_register_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0x129c0f56 sata_scr_write +EXPORT_SYMBOL_GPL vmlinux 0x12b4295b sata_link_resume +EXPORT_SYMBOL_GPL vmlinux 0x12d896f3 input_ff_upload +EXPORT_SYMBOL_GPL vmlinux 0x12e285ec is_uv_system +EXPORT_SYMBOL_GPL vmlinux 0x139620e4 audit_log_vformat +EXPORT_SYMBOL_GPL vmlinux 0x13a8e007 sched_setscheduler +EXPORT_SYMBOL_GPL vmlinux 0x13b2a946 register_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x13d2c65a crypto_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x13ed1e95 crypto_hash_walk_first +EXPORT_SYMBOL_GPL vmlinux 0x13f9a11b crypto_dequeue_request +EXPORT_SYMBOL_GPL vmlinux 0x1434c4ce ata_host_suspend +EXPORT_SYMBOL_GPL vmlinux 0x14566a8c pci_intx +EXPORT_SYMBOL_GPL vmlinux 0x145eebd0 device_power_up +EXPORT_SYMBOL_GPL vmlinux 0x149db923 selinux_string_to_sid +EXPORT_SYMBOL_GPL vmlinux 0x14a2018f vfs_removexattr +EXPORT_SYMBOL_GPL vmlinux 0x14a88277 pid_vnr +EXPORT_SYMBOL_GPL vmlinux 0x14dda409 power_supply_register +EXPORT_SYMBOL_GPL vmlinux 0x15690075 ata_link_abort +EXPORT_SYMBOL_GPL vmlinux 0x158c2ad0 acpi_smbus_unregister_callback +EXPORT_SYMBOL_GPL vmlinux 0x1598dc9d unregister_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x15b0606e e820_any_mapped +EXPORT_SYMBOL_GPL vmlinux 0x15c7e63b regulator_set_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x15d25537 xenbus_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x15d2b854 usb_anchor_urb +EXPORT_SYMBOL_GPL vmlinux 0x15e5f816 spi_add_device +EXPORT_SYMBOL_GPL vmlinux 0x160d5763 inotify_rm_watch +EXPORT_SYMBOL_GPL vmlinux 0x175fbb16 posix_timer_event +EXPORT_SYMBOL_GPL vmlinux 0x176ba7fe input_ff_event +EXPORT_SYMBOL_GPL vmlinux 0x178b5646 mmput +EXPORT_SYMBOL_GPL vmlinux 0x17c33f07 tty_find_polling_driver +EXPORT_SYMBOL_GPL vmlinux 0x17ff5913 ata_sff_irq_on +EXPORT_SYMBOL_GPL vmlinux 0x18076f5f mmu_notifier_unregister +EXPORT_SYMBOL_GPL vmlinux 0x18110ff3 debugfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0x183a4077 spi_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x1878f62b edac_err_assert +EXPORT_SYMBOL_GPL vmlinux 0x18d53420 kgdb_register_io_module +EXPORT_SYMBOL_GPL vmlinux 0x18f83fab gnttab_grant_foreign_access_ref +EXPORT_SYMBOL_GPL vmlinux 0x191d8f45 ata_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0x192faf01 crypto_mod_put +EXPORT_SYMBOL_GPL vmlinux 0x19a304ba usb_disabled +EXPORT_SYMBOL_GPL vmlinux 0x19a4df4c unregister_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0x19b48e2c usb_buffer_free +EXPORT_SYMBOL_GPL vmlinux 0x19b7a4c8 ata_host_alloc +EXPORT_SYMBOL_GPL vmlinux 0x19d01a22 cpuidle_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x19f6884f dm_noflush_suspending +EXPORT_SYMBOL_GPL vmlinux 0x1a10607f unregister_jprobes +EXPORT_SYMBOL_GPL vmlinux 0x1a779255 fib_rules_lookup +EXPORT_SYMBOL_GPL vmlinux 0x1a938737 atomic_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x1ab20959 scsi_target_unblock +EXPORT_SYMBOL_GPL vmlinux 0x1acda5b2 atomic_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x1ad12d5f devres_destroy +EXPORT_SYMBOL_GPL vmlinux 0x1ad3b491 acpi_root_bridge +EXPORT_SYMBOL_GPL vmlinux 0x1af87a65 hvc_instantiate +EXPORT_SYMBOL_GPL vmlinux 0x1b8be8fb dev_attr_link_power_management_policy +EXPORT_SYMBOL_GPL vmlinux 0x1b8dfa03 ata_sff_data_xfer +EXPORT_SYMBOL_GPL vmlinux 0x1b9aca3f jprobe_return +EXPORT_SYMBOL_GPL vmlinux 0x1bde3f3e audit_log_untrustedstring +EXPORT_SYMBOL_GPL vmlinux 0x1be86560 sdio_writew +EXPORT_SYMBOL_GPL vmlinux 0x1c4654a5 da903x_write +EXPORT_SYMBOL_GPL vmlinux 0x1c643609 xfrm_audit_state_icvfail +EXPORT_SYMBOL_GPL vmlinux 0x1c87a811 __round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x1c9b34c7 blkdev_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x1ce06916 sysdev_create_file +EXPORT_SYMBOL_GPL vmlinux 0x1ce957a7 blk_abort_queue +EXPORT_SYMBOL_GPL vmlinux 0x1ce9f482 led_trigger_store +EXPORT_SYMBOL_GPL vmlinux 0x1d023170 schedule_hrtimeout +EXPORT_SYMBOL_GPL vmlinux 0x1d735315 kobject_rename +EXPORT_SYMBOL_GPL vmlinux 0x1dbea856 usb_autopm_put_interface +EXPORT_SYMBOL_GPL vmlinux 0x1dd70100 dmi_walk +EXPORT_SYMBOL_GPL vmlinux 0x1e5a5f22 sn_partition_id +EXPORT_SYMBOL_GPL vmlinux 0x1e725999 __mnt_is_readonly +EXPORT_SYMBOL_GPL vmlinux 0x1e7bbcb3 kernel_restart +EXPORT_SYMBOL_GPL vmlinux 0x1e999fe1 inet_diag_unregister +EXPORT_SYMBOL_GPL vmlinux 0x1eb9516e round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x1ed52eed rdev_get_dev +EXPORT_SYMBOL_GPL vmlinux 0x1ed70c6e usb_serial_register +EXPORT_SYMBOL_GPL vmlinux 0x1f57e18e pci_disable_rom +EXPORT_SYMBOL_GPL vmlinux 0x1f87fc15 da903x_read +EXPORT_SYMBOL_GPL vmlinux 0x1f8ec1b3 acpi_get_pci_rootbridge_handle +EXPORT_SYMBOL_GPL vmlinux 0x1f94682b ata_dummy_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x1f9519c4 rt_mutex_lock_interruptible +EXPORT_SYMBOL_GPL vmlinux 0x1f9a0fbf hpet_unregister_irq_handler +EXPORT_SYMBOL_GPL vmlinux 0x1fac607a usb_hcd_unlink_urb_from_ep +EXPORT_SYMBOL_GPL vmlinux 0x1fcece42 inet_twdr_twcal_tick +EXPORT_SYMBOL_GPL vmlinux 0x1fd64d91 usb_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x20577ea2 xfrm_ealg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x20788098 dm_rh_dirty_log +EXPORT_SYMBOL_GPL vmlinux 0x2089d9a1 usb_control_msg +EXPORT_SYMBOL_GPL vmlinux 0x20b82470 hpet_register_irq_handler +EXPORT_SYMBOL_GPL vmlinux 0x20bc3470 orderly_poweroff +EXPORT_SYMBOL_GPL vmlinux 0x20cd788f __ftrace_printk +EXPORT_SYMBOL_GPL vmlinux 0x213c1513 klist_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x2171b7a5 devres_alloc +EXPORT_SYMBOL_GPL vmlinux 0x219b3ca9 exit_fs +EXPORT_SYMBOL_GPL vmlinux 0x21bd1bdd uart_console_write +EXPORT_SYMBOL_GPL vmlinux 0x21e811d7 debugfs_create_u16 +EXPORT_SYMBOL_GPL vmlinux 0x2240d211 unregister_jprobe +EXPORT_SYMBOL_GPL vmlinux 0x22472bf4 xfrm_calg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x226f8820 skb_partial_csum_set +EXPORT_SYMBOL_GPL vmlinux 0x2296c00d crypto_attr_u32 +EXPORT_SYMBOL_GPL vmlinux 0x22b3070f tty_prepare_flip_string +EXPORT_SYMBOL_GPL vmlinux 0x23309227 security_inode_setattr +EXPORT_SYMBOL_GPL vmlinux 0x236cddcf inet_csk_clone +EXPORT_SYMBOL_GPL vmlinux 0x23864ce7 cpuset_mem_spread_node +EXPORT_SYMBOL_GPL vmlinux 0x23866e87 ata_bmdma_status +EXPORT_SYMBOL_GPL vmlinux 0x238e9331 tcp_get_info +EXPORT_SYMBOL_GPL vmlinux 0x239a55e2 fsstack_copy_attr_all +EXPORT_SYMBOL_GPL vmlinux 0x239fb7bd kobject_get_path +EXPORT_SYMBOL_GPL vmlinux 0x23bbf3f2 crypto_rng_type +EXPORT_SYMBOL_GPL vmlinux 0x23c613c0 hid_allocate_device +EXPORT_SYMBOL_GPL vmlinux 0x23c661bf dm_rh_recovery_prepare +EXPORT_SYMBOL_GPL vmlinux 0x24196ba2 init_uts_ns +EXPORT_SYMBOL_GPL vmlinux 0x2429e0c6 preempt_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x2447533c ktime_get_real +EXPORT_SYMBOL_GPL vmlinux 0x2469ca66 platform_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x2486928f usb_create_hcd +EXPORT_SYMBOL_GPL vmlinux 0x24c7698a xenbus_write +EXPORT_SYMBOL_GPL vmlinux 0x24eb7e32 leds_list +EXPORT_SYMBOL_GPL vmlinux 0x24fb231f tty_wakeup +EXPORT_SYMBOL_GPL vmlinux 0x2531c51d sysdev_class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x253d2c12 crypto_tfm_in_queue +EXPORT_SYMBOL_GPL vmlinux 0x253e0711 ata_do_set_mode +EXPORT_SYMBOL_GPL vmlinux 0x2545c170 unregister_xenbus_watch +EXPORT_SYMBOL_GPL vmlinux 0x25845190 tcp_reno_min_cwnd +EXPORT_SYMBOL_GPL vmlinux 0x25e98d63 kobject_uevent_env +EXPORT_SYMBOL_GPL vmlinux 0x2603daaa tcp_death_row +EXPORT_SYMBOL_GPL vmlinux 0x262a43af dm_rh_update_states +EXPORT_SYMBOL_GPL vmlinux 0x2665b4b3 spi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x269d69b8 ata_sff_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0x26bfc6f0 ata_sff_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x26c90ea4 scsi_eh_get_sense +EXPORT_SYMBOL_GPL vmlinux 0x26da2c43 pci_stop_bus_device +EXPORT_SYMBOL_GPL vmlinux 0x26eff321 aead_geniv_alloc +EXPORT_SYMBOL_GPL vmlinux 0x27951461 __hid_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x2798ce5c pci_restore_msi_state +EXPORT_SYMBOL_GPL vmlinux 0x28088f0f pv_time_ops +EXPORT_SYMBOL_GPL vmlinux 0x28471e55 driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0x28503e2e platform_device_add_resources +EXPORT_SYMBOL_GPL vmlinux 0x28bdacde hrtimer_start_range_ns +EXPORT_SYMBOL_GPL vmlinux 0x28d664ff __raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x28e23139 xfrm_probe_algs +EXPORT_SYMBOL_GPL vmlinux 0x28e45708 kobject_uevent +EXPORT_SYMBOL_GPL vmlinux 0x28f923d4 dm_device_name +EXPORT_SYMBOL_GPL vmlinux 0x28f99734 sata_link_hardreset +EXPORT_SYMBOL_GPL vmlinux 0x291ed881 inet_twsk_purge +EXPORT_SYMBOL_GPL vmlinux 0x292cbc95 bt_class +EXPORT_SYMBOL_GPL vmlinux 0x292fd278 class_destroy +EXPORT_SYMBOL_GPL vmlinux 0x29c68900 page_mkclean +EXPORT_SYMBOL_GPL vmlinux 0x29d034df netlink_has_listeners +EXPORT_SYMBOL_GPL vmlinux 0x2a02e169 ata_scsi_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0x2a42547c debugfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x2a678a13 __suspend_report_result +EXPORT_SYMBOL_GPL vmlinux 0x2a81396a xenbus_bind_evtchn +EXPORT_SYMBOL_GPL vmlinux 0x2b24e4a0 uv_blade_info +EXPORT_SYMBOL_GPL vmlinux 0x2b486747 vfs_lock_file +EXPORT_SYMBOL_GPL vmlinux 0x2b81a680 macvlan_handle_frame_hook +EXPORT_SYMBOL_GPL vmlinux 0x2b9f8e23 nf_net_ipv4_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x2bcf3d87 rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0x2c16ed76 xfrm_calg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x2c208607 power_supply_is_system_supplied +EXPORT_SYMBOL_GPL vmlinux 0x2c5524b3 xenbus_switch_state +EXPORT_SYMBOL_GPL vmlinux 0x2ca95082 cpufreq_cpu_put +EXPORT_SYMBOL_GPL vmlinux 0x2cbc3b61 __audit_inode_child +EXPORT_SYMBOL_GPL vmlinux 0x2d29ff22 ata_port_pbar_desc +EXPORT_SYMBOL_GPL vmlinux 0x2d48f4f9 __inet_twsk_hashdance +EXPORT_SYMBOL_GPL vmlinux 0x2d54d537 anon_inode_getfd +EXPORT_SYMBOL_GPL vmlinux 0x2d59c954 edac_handlers +EXPORT_SYMBOL_GPL vmlinux 0x2d9f2ce3 sched_clock_idle_wakeup_event +EXPORT_SYMBOL_GPL vmlinux 0x2daeff65 rdev_get_id +EXPORT_SYMBOL_GPL vmlinux 0x2db68b9a sysfs_get +EXPORT_SYMBOL_GPL vmlinux 0x2dc783a5 crypto_init_spawn +EXPORT_SYMBOL_GPL vmlinux 0x2dd4aab4 rtc_set_time +EXPORT_SYMBOL_GPL vmlinux 0x2de9f755 anon_transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x2dfd4290 cpuidle_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x2e180ffc queue_delayed_work_on +EXPORT_SYMBOL_GPL vmlinux 0x2e2995cc led_trigger_unregister_simple +EXPORT_SYMBOL_GPL vmlinux 0x2e9973ad inet6_destroy_sock +EXPORT_SYMBOL_GPL vmlinux 0x2eb573b6 user_read +EXPORT_SYMBOL_GPL vmlinux 0x2ec3b51d hwmon_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x2ec92012 scatterwalk_copychunks +EXPORT_SYMBOL_GPL vmlinux 0x2ede9716 usb_sg_cancel +EXPORT_SYMBOL_GPL vmlinux 0x2ee85928 sdev_evt_send_simple +EXPORT_SYMBOL_GPL vmlinux 0x2ee96b90 usb_hcd_giveback_urb +EXPORT_SYMBOL_GPL vmlinux 0x2f0e87cb ata_eh_thaw_port +EXPORT_SYMBOL_GPL vmlinux 0x2f27bf97 ata_pci_bmdma_init +EXPORT_SYMBOL_GPL vmlinux 0x2f47d8c7 cpufreq_frequency_get_table +EXPORT_SYMBOL_GPL vmlinux 0x2f621dcc __cpufreq_driver_getavg +EXPORT_SYMBOL_GPL vmlinux 0x2f70706a regulator_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x2fc66786 blk_insert_cloned_request +EXPORT_SYMBOL_GPL vmlinux 0x3011e931 devm_kzalloc +EXPORT_SYMBOL_GPL vmlinux 0x30140599 inotify_init +EXPORT_SYMBOL_GPL vmlinux 0x305112d9 blk_trace_remove +EXPORT_SYMBOL_GPL vmlinux 0x307003f3 sis_info133_for_sata +EXPORT_SYMBOL_GPL vmlinux 0x30b268ec unregister_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0x3160efaf device_schedule_callback_owner +EXPORT_SYMBOL_GPL vmlinux 0x31797610 tracepoint_iter_reset +EXPORT_SYMBOL_GPL vmlinux 0x318920b1 register_dock_notifier +EXPORT_SYMBOL_GPL vmlinux 0x322284f3 tty_buffer_request_room +EXPORT_SYMBOL_GPL vmlinux 0x3227d4cb class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x3227fde7 net_assign_generic +EXPORT_SYMBOL_GPL vmlinux 0x325e677c gnttab_grant_foreign_transfer_ref +EXPORT_SYMBOL_GPL vmlinux 0x328b2a12 transport_configure_device +EXPORT_SYMBOL_GPL vmlinux 0x32ebf6f1 crypto_attr_alg +EXPORT_SYMBOL_GPL vmlinux 0x330e075d led_trigger_set +EXPORT_SYMBOL_GPL vmlinux 0x336096d4 simple_attr_write +EXPORT_SYMBOL_GPL vmlinux 0x33b6e752 acpi_ec_remove_query_handler +EXPORT_SYMBOL_GPL vmlinux 0x34105c01 bus_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x3441c3d6 gpio_set_value_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x344e210e ata_acpi_cbl_80wire +EXPORT_SYMBOL_GPL vmlinux 0x34dd71ab ata_sff_irq_clear +EXPORT_SYMBOL_GPL vmlinux 0x34e8d5a8 kern_mount_data +EXPORT_SYMBOL_GPL vmlinux 0x3523a891 dm_rh_stop_recovery +EXPORT_SYMBOL_GPL vmlinux 0x356b1376 usb_driver_set_configuration +EXPORT_SYMBOL_GPL vmlinux 0x35897293 crypto_hash_walk_done +EXPORT_SYMBOL_GPL vmlinux 0x35d8c94a sdev_evt_alloc +EXPORT_SYMBOL_GPL vmlinux 0x361e2bcc save_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0x362e23ec call_rcu_bh +EXPORT_SYMBOL_GPL vmlinux 0x365c2c94 spi_busnum_to_master +EXPORT_SYMBOL_GPL vmlinux 0x36969fdb devres_close_group +EXPORT_SYMBOL_GPL vmlinux 0x3707c683 input_class +EXPORT_SYMBOL_GPL vmlinux 0x374319b0 skcipher_geniv_alloc +EXPORT_SYMBOL_GPL vmlinux 0x377dbe49 ata_sff_check_status +EXPORT_SYMBOL_GPL vmlinux 0x378e3321 crypto_alg_mod_lookup +EXPORT_SYMBOL_GPL vmlinux 0x37af0835 cpufreq_cpu_get +EXPORT_SYMBOL_GPL vmlinux 0x37bf012a devres_release_group +EXPORT_SYMBOL_GPL vmlinux 0x37ca9f53 input_ff_create +EXPORT_SYMBOL_GPL vmlinux 0x3895233b srcu_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x389fd081 md_new_event +EXPORT_SYMBOL_GPL vmlinux 0x38aa8e9b blk_set_cmd_filter_defaults +EXPORT_SYMBOL_GPL vmlinux 0x38d36cdd dnotify_parent +EXPORT_SYMBOL_GPL vmlinux 0x390d337e sysfs_remove_link +EXPORT_SYMBOL_GPL vmlinux 0x39238b57 klist_del +EXPORT_SYMBOL_GPL vmlinux 0x395cd90d ata_pci_remove_one +EXPORT_SYMBOL_GPL vmlinux 0x39939e12 queue_work_on +EXPORT_SYMBOL_GPL vmlinux 0x39942348 bus_for_each_drv +EXPORT_SYMBOL_GPL vmlinux 0x39a438e8 put_driver +EXPORT_SYMBOL_GPL vmlinux 0x39f68db3 __trace_note_message +EXPORT_SYMBOL_GPL vmlinux 0x3a25eb7e blk_trace_setup +EXPORT_SYMBOL_GPL vmlinux 0x3a311560 unregister_kprobes +EXPORT_SYMBOL_GPL vmlinux 0x3a7f8b86 __local_bh_enable +EXPORT_SYMBOL_GPL vmlinux 0x3b17aec1 device_initialize +EXPORT_SYMBOL_GPL vmlinux 0x3b1d5794 usb_hcd_poll_rh_status +EXPORT_SYMBOL_GPL vmlinux 0x3b58c91e inet_twsk_put +EXPORT_SYMBOL_GPL vmlinux 0x3b954dde pci_destroy_slot +EXPORT_SYMBOL_GPL vmlinux 0x3bc8d088 blk_queue_rq_timeout +EXPORT_SYMBOL_GPL vmlinux 0x3be7af02 get_max_files +EXPORT_SYMBOL_GPL vmlinux 0x3be89d3c usb_register_notify +EXPORT_SYMBOL_GPL vmlinux 0x3c026ec5 inotify_find_update_watch +EXPORT_SYMBOL_GPL vmlinux 0x3c942368 profile_event_unregister +EXPORT_SYMBOL_GPL vmlinux 0x3ca5ac98 ata_sff_tf_load +EXPORT_SYMBOL_GPL vmlinux 0x3cd06035 add_input_randomness +EXPORT_SYMBOL_GPL vmlinux 0x3cf9bf4f platform_driver_probe +EXPORT_SYMBOL_GPL vmlinux 0x3cfedb3f register_pm_notifier +EXPORT_SYMBOL_GPL vmlinux 0x3d00851b sdio_readb +EXPORT_SYMBOL_GPL vmlinux 0x3d29867d per_cpu__gdt_page +EXPORT_SYMBOL_GPL vmlinux 0x3d33f2a4 __rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0x3d342883 save_stack_trace_tsk +EXPORT_SYMBOL_GPL vmlinux 0x3d5f392d acpi_os_unmap_memory +EXPORT_SYMBOL_GPL vmlinux 0x3d67f752 usb_deregister_dev +EXPORT_SYMBOL_GPL vmlinux 0x3d7ea99a gnttab_grant_foreign_transfer +EXPORT_SYMBOL_GPL vmlinux 0x3db1e6d2 usb_altnum_to_altsetting +EXPORT_SYMBOL_GPL vmlinux 0x3e1c3c88 usb_serial_deregister +EXPORT_SYMBOL_GPL vmlinux 0x3e39a652 usb_serial_port_softint +EXPORT_SYMBOL_GPL vmlinux 0x3e500979 rtc_irq_unregister +EXPORT_SYMBOL_GPL vmlinux 0x3e9a96f5 usb_reset_configuration +EXPORT_SYMBOL_GPL vmlinux 0x3eb551c6 sata_sff_hardreset +EXPORT_SYMBOL_GPL vmlinux 0x3ebffc33 sdio_memcpy_toio +EXPORT_SYMBOL_GPL vmlinux 0x3ecf6cfc wmi_install_notify_handler +EXPORT_SYMBOL_GPL vmlinux 0x3edad223 usb_usual_clear_present +EXPORT_SYMBOL_GPL vmlinux 0x3efb35c9 get_online_cpus +EXPORT_SYMBOL_GPL vmlinux 0x3f102d74 i2c_new_device +EXPORT_SYMBOL_GPL vmlinux 0x3f238101 dcookie_register +EXPORT_SYMBOL_GPL vmlinux 0x3f567507 inet_csk_compat_setsockopt +EXPORT_SYMBOL_GPL vmlinux 0x3f6b3a76 usb_get_from_anchor +EXPORT_SYMBOL_GPL vmlinux 0x3f84d4c9 gnttab_release_grant_reference +EXPORT_SYMBOL_GPL vmlinux 0x3f9a2a10 hidinput_find_field +EXPORT_SYMBOL_GPL vmlinux 0x3fc24436 dm_rh_recovery_end +EXPORT_SYMBOL_GPL vmlinux 0x3fc35f5a fib_rules_register +EXPORT_SYMBOL_GPL vmlinux 0x3fdb68b4 hidinput_disconnect +EXPORT_SYMBOL_GPL vmlinux 0x40380ad6 hrtimer_cancel +EXPORT_SYMBOL_GPL vmlinux 0x40af0dec ata_xfer_mode2mask +EXPORT_SYMBOL_GPL vmlinux 0x40c4f3a2 hid_parse_report +EXPORT_SYMBOL_GPL vmlinux 0x41781289 ata_bmdma_stop +EXPORT_SYMBOL_GPL vmlinux 0x41c0a559 crypto_ahash_type +EXPORT_SYMBOL_GPL vmlinux 0x41f3cc90 xfrm_aalg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x42308f55 bus_for_each_dev +EXPORT_SYMBOL_GPL vmlinux 0x424acc6d scatterwalk_done +EXPORT_SYMBOL_GPL vmlinux 0x425074a8 ata_cable_sata +EXPORT_SYMBOL_GPL vmlinux 0x4264debc tty_ldisc_ref_wait +EXPORT_SYMBOL_GPL vmlinux 0x42845667 inet6_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0x42b50f75 nf_register_afinfo +EXPORT_SYMBOL_GPL vmlinux 0x42cc609c usb_bulk_msg +EXPORT_SYMBOL_GPL vmlinux 0x432fd7f6 __gpio_set_value +EXPORT_SYMBOL_GPL vmlinux 0x43321fe8 usb_autopm_set_interface +EXPORT_SYMBOL_GPL vmlinux 0x436336ad rtc_class_open +EXPORT_SYMBOL_GPL vmlinux 0x43dc6200 platform_device_del +EXPORT_SYMBOL_GPL vmlinux 0x43f56e82 ata_xfer_mode2shift +EXPORT_SYMBOL_GPL vmlinux 0x4446f8cb rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0x444a66a1 led_trigger_show +EXPORT_SYMBOL_GPL vmlinux 0x448a059b sysfs_add_file_to_group +EXPORT_SYMBOL_GPL vmlinux 0x44a65d5c lock_policy_rwsem_read +EXPORT_SYMBOL_GPL vmlinux 0x44b5ba8b platform_device_add +EXPORT_SYMBOL_GPL vmlinux 0x44c6c44e debugfs_create_u64 +EXPORT_SYMBOL_GPL vmlinux 0x4516d33d devres_open_group +EXPORT_SYMBOL_GPL vmlinux 0x451a0bd2 device_release_driver +EXPORT_SYMBOL_GPL vmlinux 0x457594fa crypto_alg_list +EXPORT_SYMBOL_GPL vmlinux 0x45b8b6d4 ata_cable_unknown +EXPORT_SYMBOL_GPL vmlinux 0x45bf1ff3 crypto_inc +EXPORT_SYMBOL_GPL vmlinux 0x45d14bdf hypercall_page +EXPORT_SYMBOL_GPL vmlinux 0x460f31aa rodata_test_data +EXPORT_SYMBOL_GPL vmlinux 0x4689bc88 klist_node_attached +EXPORT_SYMBOL_GPL vmlinux 0x46ac4d22 dm_rh_region_context +EXPORT_SYMBOL_GPL vmlinux 0x47229b5c gpio_request +EXPORT_SYMBOL_GPL vmlinux 0x4732157e inet_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0x473465b5 pciserial_init_ports +EXPORT_SYMBOL_GPL vmlinux 0x474ab29b user_match +EXPORT_SYMBOL_GPL vmlinux 0x47583845 platform_get_resource +EXPORT_SYMBOL_GPL vmlinux 0x476437f0 single_open_net +EXPORT_SYMBOL_GPL vmlinux 0x47744df3 ata_slave_link_init +EXPORT_SYMBOL_GPL vmlinux 0x47931cbb regulator_register +EXPORT_SYMBOL_GPL vmlinux 0x47d148b9 simple_attr_open +EXPORT_SYMBOL_GPL vmlinux 0x4817ac2e bus_find_device +EXPORT_SYMBOL_GPL vmlinux 0x4826eb62 __inet_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0x486b6ff6 attribute_container_find_class_device +EXPORT_SYMBOL_GPL vmlinux 0x489f945e mnt_drop_write +EXPORT_SYMBOL_GPL vmlinux 0x48dae124 ata_pci_device_do_suspend +EXPORT_SYMBOL_GPL vmlinux 0x4903219c usb_get_dev +EXPORT_SYMBOL_GPL vmlinux 0x493e3cf2 map_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x496a7702 usb_add_hcd +EXPORT_SYMBOL_GPL vmlinux 0x499043d3 crypto_init_queue +EXPORT_SYMBOL_GPL vmlinux 0x49fd5e6d disk_part_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x4a11a4fb bind_virq_to_irqhandler +EXPORT_SYMBOL_GPL vmlinux 0x4a3ae268 alloc_page_buffers +EXPORT_SYMBOL_GPL vmlinux 0x4a5aa1f7 crypto_grab_aead +EXPORT_SYMBOL_GPL vmlinux 0x4a7e30d9 marker_probe_unregister_private_data +EXPORT_SYMBOL_GPL vmlinux 0x4aa91899 relay_switch_subbuf +EXPORT_SYMBOL_GPL vmlinux 0x4ace7eb7 platform_add_devices +EXPORT_SYMBOL_GPL vmlinux 0x4af2264c pci_set_pcie_reset_state +EXPORT_SYMBOL_GPL vmlinux 0x4b3f6efd fs_kobj +EXPORT_SYMBOL_GPL vmlinux 0x4b762828 start_thread +EXPORT_SYMBOL_GPL vmlinux 0x4c759827 byte_rev_table +EXPORT_SYMBOL_GPL vmlinux 0x4c95ad6e uhci_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0x4d19eb5a __scsi_get_command +EXPORT_SYMBOL_GPL vmlinux 0x4d44c06d platform_get_irq +EXPORT_SYMBOL_GPL vmlinux 0x4d6efa5a xfrm_audit_policy_add +EXPORT_SYMBOL_GPL vmlinux 0x4d7e5436 proc_net_remove +EXPORT_SYMBOL_GPL vmlinux 0x4ddd5265 inotify_inode_is_dead +EXPORT_SYMBOL_GPL vmlinux 0x4e695d74 regulator_get_mode +EXPORT_SYMBOL_GPL vmlinux 0x4ea27434 sysfs_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x4eca01cb inet_twsk_schedule +EXPORT_SYMBOL_GPL vmlinux 0x4f2dcea9 sata_async_notification +EXPORT_SYMBOL_GPL vmlinux 0x4f4d143e lookup_create +EXPORT_SYMBOL_GPL vmlinux 0x4f84d4f3 bdi_writeout_inc +EXPORT_SYMBOL_GPL vmlinux 0x4fdc945d sata_deb_timing_normal +EXPORT_SYMBOL_GPL vmlinux 0x4fdf5251 device_bind_driver +EXPORT_SYMBOL_GPL vmlinux 0x5086ac3a alg_test +EXPORT_SYMBOL_GPL vmlinux 0x50b319ce cpu_bit_bitmap +EXPORT_SYMBOL_GPL vmlinux 0x50b67174 xfrm_ealg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x50e7193a __i2c_first_dynamic_bus_num +EXPORT_SYMBOL_GPL vmlinux 0x50fad434 round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x511f3e1f apic_ops +EXPORT_SYMBOL_GPL vmlinux 0x511f8529 ata_dev_disable +EXPORT_SYMBOL_GPL vmlinux 0x5121c2f0 sysfs_update_group +EXPORT_SYMBOL_GPL vmlinux 0x514525b7 usb_hub_tt_clear_buffer +EXPORT_SYMBOL_GPL vmlinux 0x51596651 led_trigger_unregister +EXPORT_SYMBOL_GPL vmlinux 0x518be000 usb_kill_urb +EXPORT_SYMBOL_GPL vmlinux 0x518c2fc6 hpet_rtc_dropped_irq +EXPORT_SYMBOL_GPL vmlinux 0x51a4c094 unregister_kprobe +EXPORT_SYMBOL_GPL vmlinux 0x51acca77 ata_sas_port_destroy +EXPORT_SYMBOL_GPL vmlinux 0x51dd6488 xfrm_aalg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x51f9fe26 ata_cable_80wire +EXPORT_SYMBOL_GPL vmlinux 0x51fc8b26 pci_renumber_slot +EXPORT_SYMBOL_GPL vmlinux 0x526b867a acpi_smbus_read +EXPORT_SYMBOL_GPL vmlinux 0x52a34488 tty_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x52b0e33e xenbus_alloc_evtchn +EXPORT_SYMBOL_GPL vmlinux 0x52d0ae76 regulator_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x52d111ea pm_qos_update_requirement +EXPORT_SYMBOL_GPL vmlinux 0x52d54db1 kill_pid_info_as_uid +EXPORT_SYMBOL_GPL vmlinux 0x53614269 get_cpu_idle_time_us +EXPORT_SYMBOL_GPL vmlinux 0x5372dede unregister_acpi_bus_notifier +EXPORT_SYMBOL_GPL vmlinux 0x53986488 register_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x539c4f37 crypto_larval_alloc +EXPORT_SYMBOL_GPL vmlinux 0x53c2a1ae get_user_pages_fast +EXPORT_SYMBOL_GPL vmlinux 0x542652cf bus_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5440ae2b class_dev_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x5490bd91 securityfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0x552891c8 regulator_disable +EXPORT_SYMBOL_GPL vmlinux 0x552a80eb sdio_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x552bea82 device_for_each_child +EXPORT_SYMBOL_GPL vmlinux 0x55526907 xen_features +EXPORT_SYMBOL_GPL vmlinux 0x55c5a0b7 pci_hp_register +EXPORT_SYMBOL_GPL vmlinux 0x55ef8bc5 blk_end_bidi_request +EXPORT_SYMBOL_GPL vmlinux 0x561c634a wmi_evaluate_method +EXPORT_SYMBOL_GPL vmlinux 0x56398615 mark_tsc_unstable +EXPORT_SYMBOL_GPL vmlinux 0x5641485b tty_termios_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x5669e4a5 driver_attach +EXPORT_SYMBOL_GPL vmlinux 0x56a940e7 sdio_readw +EXPORT_SYMBOL_GPL vmlinux 0x56ed913f generic_sync_sb_inodes +EXPORT_SYMBOL_GPL vmlinux 0x5740252c vfs_setxattr +EXPORT_SYMBOL_GPL vmlinux 0x575c5f94 execute_in_process_context +EXPORT_SYMBOL_GPL vmlinux 0x5779d445 xenbus_exists +EXPORT_SYMBOL_GPL vmlinux 0x579e0bf5 rtnl_unregister_all +EXPORT_SYMBOL_GPL vmlinux 0x57b75f80 inet_csk_route_req +EXPORT_SYMBOL_GPL vmlinux 0x57cc0ffd usb_serial_generic_open +EXPORT_SYMBOL_GPL vmlinux 0x57fd5249 ata_sff_qc_fill_rtf +EXPORT_SYMBOL_GPL vmlinux 0x580a49e3 power_supply_class +EXPORT_SYMBOL_GPL vmlinux 0x58547767 scsi_dh_activate +EXPORT_SYMBOL_GPL vmlinux 0x58666eb6 sdio_disable_func +EXPORT_SYMBOL_GPL vmlinux 0x586d5849 ata_ehi_clear_desc +EXPORT_SYMBOL_GPL vmlinux 0x59163259 proc_net_fops_create +EXPORT_SYMBOL_GPL vmlinux 0x591e216f dev_set_name +EXPORT_SYMBOL_GPL vmlinux 0x593a36c2 scsi_dh_handler_exist +EXPORT_SYMBOL_GPL vmlinux 0x597f3bc3 marker_get_private_data +EXPORT_SYMBOL_GPL vmlinux 0x59cf8cec device_move +EXPORT_SYMBOL_GPL vmlinux 0x5a2b1b67 gnttab_free_grant_reference +EXPORT_SYMBOL_GPL vmlinux 0x5a6fe27b dm_rh_dec +EXPORT_SYMBOL_GPL vmlinux 0x5a7bfe41 crypto_probing_notify +EXPORT_SYMBOL_GPL vmlinux 0x5a80af43 sysfs_schedule_callback +EXPORT_SYMBOL_GPL vmlinux 0x5a8fe62b ata_link_offline +EXPORT_SYMBOL_GPL vmlinux 0x5af03a28 gnttab_claim_grant_reference +EXPORT_SYMBOL_GPL vmlinux 0x5b1b2997 sysdev_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5b1b54f9 dm_rh_get_region_key +EXPORT_SYMBOL_GPL vmlinux 0x5ba155f7 hid_add_device +EXPORT_SYMBOL_GPL vmlinux 0x5beccf80 ata_host_activate +EXPORT_SYMBOL_GPL vmlinux 0x5bfc03c3 unregister_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5c783951 class_dev_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x5c93cace usb_serial_generic_read_bulk_callback +EXPORT_SYMBOL_GPL vmlinux 0x5ca4f09f usb_hcd_pci_probe +EXPORT_SYMBOL_GPL vmlinux 0x5cc852e3 uv_coherency_id +EXPORT_SYMBOL_GPL vmlinux 0x5cd9b24c acpi_bus_trim +EXPORT_SYMBOL_GPL vmlinux 0x5cfcf0f1 percpu_free +EXPORT_SYMBOL_GPL vmlinux 0x5d0f6f57 kbd_table +EXPORT_SYMBOL_GPL vmlinux 0x5d366dec gnttab_cancel_free_callback +EXPORT_SYMBOL_GPL vmlinux 0x5d546d0b hid_report_raw_event +EXPORT_SYMBOL_GPL vmlinux 0x5d730e7b raw_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5d87c067 register_acpi_bus_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5d884417 ata_sff_port_start +EXPORT_SYMBOL_GPL vmlinux 0x5d95e10c inotify_remove_watch_locked +EXPORT_SYMBOL_GPL vmlinux 0x5d9c0967 class_find_device +EXPORT_SYMBOL_GPL vmlinux 0x5dd67618 register_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5e22ccd3 ata_bmdma_mode_filter +EXPORT_SYMBOL_GPL vmlinux 0x5e51be23 led_trigger_event +EXPORT_SYMBOL_GPL vmlinux 0x5ee84e19 lookup_instantiate_filp +EXPORT_SYMBOL_GPL vmlinux 0x5eeb2077 usb_get_intf +EXPORT_SYMBOL_GPL vmlinux 0x5efb957f inet6_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0x5f2da8c4 check_tsc_unstable +EXPORT_SYMBOL_GPL vmlinux 0x5f2f792b sdio_readl +EXPORT_SYMBOL_GPL vmlinux 0x60355ac6 seq_release_net +EXPORT_SYMBOL_GPL vmlinux 0x605ff123 klist_add_tail +EXPORT_SYMBOL_GPL vmlinux 0x6061f651 raw_seq_stop +EXPORT_SYMBOL_GPL vmlinux 0x6091797f synchronize_rcu +EXPORT_SYMBOL_GPL vmlinux 0x60a13e90 rcu_barrier +EXPORT_SYMBOL_GPL vmlinux 0x60a469af usb_get_urb +EXPORT_SYMBOL_GPL vmlinux 0x60f20463 sysdev_store_int +EXPORT_SYMBOL_GPL vmlinux 0x611f95c2 disk_part_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x612a5385 __ip_route_output_key +EXPORT_SYMBOL_GPL vmlinux 0x612f7277 ipv6_opt_accepted +EXPORT_SYMBOL_GPL vmlinux 0x6155188f __blk_put_request +EXPORT_SYMBOL_GPL vmlinux 0x6160b057 __inet_lookup_established +EXPORT_SYMBOL_GPL vmlinux 0x616c9d5f crypto_alloc_base +EXPORT_SYMBOL_GPL vmlinux 0x61aeac91 devm_kfree +EXPORT_SYMBOL_GPL vmlinux 0x61b13635 kobject_init_and_add +EXPORT_SYMBOL_GPL vmlinux 0x62170d1e hid_input_report +EXPORT_SYMBOL_GPL vmlinux 0x62370f44 ata_port_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0x629f4926 __blk_add_trace +EXPORT_SYMBOL_GPL vmlinux 0x62d48fd2 ipv6_find_tlv +EXPORT_SYMBOL_GPL vmlinux 0x62e5757d usb_hcd_pci_remove +EXPORT_SYMBOL_GPL vmlinux 0x63735f62 aead_geniv_exit +EXPORT_SYMBOL_GPL vmlinux 0x63ae27d6 add_nops +EXPORT_SYMBOL_GPL vmlinux 0x63b17000 ata_sff_qc_issue +EXPORT_SYMBOL_GPL vmlinux 0x63b91799 ata_sff_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0x6458da3d screen_glyph +EXPORT_SYMBOL_GPL vmlinux 0x64ecdabd sata_set_spd +EXPORT_SYMBOL_GPL vmlinux 0x6545ec8a regulator_force_disable +EXPORT_SYMBOL_GPL vmlinux 0x655500e0 ata_link_online +EXPORT_SYMBOL_GPL vmlinux 0x65ccb6f0 call_netevent_notifiers +EXPORT_SYMBOL_GPL vmlinux 0x65d6d0f0 gpio_direction_input +EXPORT_SYMBOL_GPL vmlinux 0x6610ad99 synchronize_srcu +EXPORT_SYMBOL_GPL vmlinux 0x661601de sprint_symbol +EXPORT_SYMBOL_GPL vmlinux 0x66298204 flush_workqueue +EXPORT_SYMBOL_GPL vmlinux 0x66615c98 scsi_flush_work +EXPORT_SYMBOL_GPL vmlinux 0x6682999f ata_host_detach +EXPORT_SYMBOL_GPL vmlinux 0x668402aa crypto_put_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x66b2a859 nr_free_buffer_pages +EXPORT_SYMBOL_GPL vmlinux 0x66d87d38 symbol_put_addr +EXPORT_SYMBOL_GPL vmlinux 0x67498885 ata_sas_port_alloc +EXPORT_SYMBOL_GPL vmlinux 0x67906f96 cpci_hp_register_bus +EXPORT_SYMBOL_GPL vmlinux 0x67955ce6 profile_hits +EXPORT_SYMBOL_GPL vmlinux 0x679aaeb7 ata_port_probe +EXPORT_SYMBOL_GPL vmlinux 0x67b55728 input_ff_destroy +EXPORT_SYMBOL_GPL vmlinux 0x67d6e188 vlan_dev_vlan_id +EXPORT_SYMBOL_GPL vmlinux 0x6830ae4a dm_rh_flush +EXPORT_SYMBOL_GPL vmlinux 0x685b8e90 put_pid +EXPORT_SYMBOL_GPL vmlinux 0x686c703f xfrm_count_auth_supported +EXPORT_SYMBOL_GPL vmlinux 0x6875d38c klist_next +EXPORT_SYMBOL_GPL vmlinux 0x68818bc6 firmware_kobj +EXPORT_SYMBOL_GPL vmlinux 0x688910fe crypto_hash_type +EXPORT_SYMBOL_GPL vmlinux 0x6892088c unregister_pm_notifier +EXPORT_SYMBOL_GPL vmlinux 0x68a8095b debugfs_create_bool +EXPORT_SYMBOL_GPL vmlinux 0x69349c63 schedule_hrtimeout_range +EXPORT_SYMBOL_GPL vmlinux 0x698d2ce7 sysdev_driver_register +EXPORT_SYMBOL_GPL vmlinux 0x69b2cb1d file_ra_state_init +EXPORT_SYMBOL_GPL vmlinux 0x69e9a2cb ata_scsi_slave_config +EXPORT_SYMBOL_GPL vmlinux 0x6a0c408d platform_device_register +EXPORT_SYMBOL_GPL vmlinux 0x6a323371 sysdev_class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x6a64e896 security_inode_permission +EXPORT_SYMBOL_GPL vmlinux 0x6a72f0c4 tracepoint_iter_stop +EXPORT_SYMBOL_GPL vmlinux 0x6a8441be cpci_hp_start +EXPORT_SYMBOL_GPL vmlinux 0x6ab4b51d find_get_pid +EXPORT_SYMBOL_GPL vmlinux 0x6af19b0e bus_get_kset +EXPORT_SYMBOL_GPL vmlinux 0x6afedc6d usb_lock_device_for_reset +EXPORT_SYMBOL_GPL vmlinux 0x6b899a51 cpci_hp_unregister_bus +EXPORT_SYMBOL_GPL vmlinux 0x6b8becf1 usb_reset_device +EXPORT_SYMBOL_GPL vmlinux 0x6b9178b3 xenbus_strstate +EXPORT_SYMBOL_GPL vmlinux 0x6b93bf60 inet_twdr_twkill_work +EXPORT_SYMBOL_GPL vmlinux 0x6ba6b5b6 sysdev_register +EXPORT_SYMBOL_GPL vmlinux 0x6bdd6118 hidinput_connect +EXPORT_SYMBOL_GPL vmlinux 0x6be62dfd probe_kernel_read +EXPORT_SYMBOL_GPL vmlinux 0x6c11059b __srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x6c3ee176 regulator_get +EXPORT_SYMBOL_GPL vmlinux 0x6c49c4f2 clockevents_notify +EXPORT_SYMBOL_GPL vmlinux 0x6c8d5ae8 __gpio_get_value +EXPORT_SYMBOL_GPL vmlinux 0x6d2fc5a6 net_namespace_list +EXPORT_SYMBOL_GPL vmlinux 0x6d431cd3 user_describe +EXPORT_SYMBOL_GPL vmlinux 0x6d622eab pci_cleanup_aer_uncorrect_error_status +EXPORT_SYMBOL_GPL vmlinux 0x6d9084cf dm_rh_recovery_in_flight +EXPORT_SYMBOL_GPL vmlinux 0x6d9f8efc transport_add_device +EXPORT_SYMBOL_GPL vmlinux 0x6dce94bf usb_bus_list_lock +EXPORT_SYMBOL_GPL vmlinux 0x6dda76cd usb_match_one_id +EXPORT_SYMBOL_GPL vmlinux 0x6df4aa40 fnotify_change +EXPORT_SYMBOL_GPL vmlinux 0x6e3f44d6 attribute_container_register +EXPORT_SYMBOL_GPL vmlinux 0x6e496159 inotify_destroy +EXPORT_SYMBOL_GPL vmlinux 0x6e58ddf0 gnttab_end_foreign_transfer_ref +EXPORT_SYMBOL_GPL vmlinux 0x6ea72a40 uv_bios_freq_base +EXPORT_SYMBOL_GPL vmlinux 0x6f10d668 crypto_mod_get +EXPORT_SYMBOL_GPL vmlinux 0x6f3823fa ata_eh_freeze_port +EXPORT_SYMBOL_GPL vmlinux 0x6f778210 debugfs_create_u32 +EXPORT_SYMBOL_GPL vmlinux 0x6f9c2efe marker_probe_cb +EXPORT_SYMBOL_GPL vmlinux 0x6faeaf2f dm_unregister_path_selector +EXPORT_SYMBOL_GPL vmlinux 0x6fbf8658 driver_find +EXPORT_SYMBOL_GPL vmlinux 0x6ff607b6 crypto_get_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x700d7d44 dev_attr_em_message_type +EXPORT_SYMBOL_GPL vmlinux 0x700f6109 preempt_notifier_unregister +EXPORT_SYMBOL_GPL vmlinux 0x701822d9 regulator_is_enabled +EXPORT_SYMBOL_GPL vmlinux 0x7024b387 ata_pci_sff_prepare_host +EXPORT_SYMBOL_GPL vmlinux 0x702a12cc klist_iter_init_node +EXPORT_SYMBOL_GPL vmlinux 0x7037d79d k8_flush_garts +EXPORT_SYMBOL_GPL vmlinux 0x706b3a33 cpufreq_frequency_table_get_attr +EXPORT_SYMBOL_GPL vmlinux 0x70724246 device_attach +EXPORT_SYMBOL_GPL vmlinux 0x707ff1bb ata_xfer_mask2mode +EXPORT_SYMBOL_GPL vmlinux 0x70a626fe ata_sff_host_intr +EXPORT_SYMBOL_GPL vmlinux 0x70b1479d ata_port_start +EXPORT_SYMBOL_GPL vmlinux 0x70c94321 usb_remove_hcd +EXPORT_SYMBOL_GPL vmlinux 0x71c8bc95 kgdb_unregister_io_module +EXPORT_SYMBOL_GPL vmlinux 0x720e2700 crypto_unregister_template +EXPORT_SYMBOL_GPL vmlinux 0x722c4f65 usb_scuttle_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x72598bb0 init_user_ns +EXPORT_SYMBOL_GPL vmlinux 0x7274f455 fib_rules_unregister +EXPORT_SYMBOL_GPL vmlinux 0x7278d328 all_vm_events +EXPORT_SYMBOL_GPL vmlinux 0x731433ee unregister_timer_hook +EXPORT_SYMBOL_GPL vmlinux 0x731b88ac ata_sff_exec_command +EXPORT_SYMBOL_GPL vmlinux 0x731dba7a xen_domain_type +EXPORT_SYMBOL_GPL vmlinux 0x7330b07b sata_link_debounce +EXPORT_SYMBOL_GPL vmlinux 0x73a48b4a ata_sff_std_ports +EXPORT_SYMBOL_GPL vmlinux 0x73a64601 platform_driver_register +EXPORT_SYMBOL_GPL vmlinux 0x73b1f76d do_posix_clock_nosettime +EXPORT_SYMBOL_GPL vmlinux 0x73ed13b0 usb_get_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x7420bff3 ata_sff_prereset +EXPORT_SYMBOL_GPL vmlinux 0x743a165e ata_pack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0x746a0649 spi_alloc_master +EXPORT_SYMBOL_GPL vmlinux 0x74abdafa task_handoff_register +EXPORT_SYMBOL_GPL vmlinux 0x74acd52f regulator_get_current_limit +EXPORT_SYMBOL_GPL vmlinux 0x74d61a4d get_dcookie +EXPORT_SYMBOL_GPL vmlinux 0x74f6ab8c tty_put_char +EXPORT_SYMBOL_GPL vmlinux 0x74fb4335 rtc_read_alarm +EXPORT_SYMBOL_GPL vmlinux 0x75010237 fb_deferred_io_cleanup +EXPORT_SYMBOL_GPL vmlinux 0x75030931 ata_port_abort +EXPORT_SYMBOL_GPL vmlinux 0x75141b4d class_interface_unregister +EXPORT_SYMBOL_GPL vmlinux 0x7521afb6 leave_mm +EXPORT_SYMBOL_GPL vmlinux 0x7534b389 regulator_unregister +EXPORT_SYMBOL_GPL vmlinux 0x7553f80d power_supply_changed +EXPORT_SYMBOL_GPL vmlinux 0x75e8f3c3 crypto_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x760247b9 ata_cable_40wire +EXPORT_SYMBOL_GPL vmlinux 0x762579ad cpufreq_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x7645e02b usb_driver_claim_interface +EXPORT_SYMBOL_GPL vmlinux 0x766c82cd inet6_csk_xmit +EXPORT_SYMBOL_GPL vmlinux 0x76deb589 ata_pci_sff_init_host +EXPORT_SYMBOL_GPL vmlinux 0x76e9f70a ata_sff_thaw +EXPORT_SYMBOL_GPL vmlinux 0x7712771a unbind_from_irqhandler +EXPORT_SYMBOL_GPL vmlinux 0x77457124 ip6_local_out +EXPORT_SYMBOL_GPL vmlinux 0x774fc39c __percpu_alloc_mask +EXPORT_SYMBOL_GPL vmlinux 0x776ee4c2 usb_buffer_unmap_sg +EXPORT_SYMBOL_GPL vmlinux 0x776f00ff ata_std_prereset +EXPORT_SYMBOL_GPL vmlinux 0x77b29e1b xenbus_unmap_ring +EXPORT_SYMBOL_GPL vmlinux 0x7804f40d klist_remove +EXPORT_SYMBOL_GPL vmlinux 0x7847ce38 platform_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x787bc159 regulator_bulk_get +EXPORT_SYMBOL_GPL vmlinux 0x788b847f pci_scan_child_bus +EXPORT_SYMBOL_GPL vmlinux 0x7890ca14 ata_timing_compute +EXPORT_SYMBOL_GPL vmlinux 0x78cfa717 dequeue_signal +EXPORT_SYMBOL_GPL vmlinux 0x792cefcb xfrm_audit_state_delete +EXPORT_SYMBOL_GPL vmlinux 0x797423ac klist_add_before +EXPORT_SYMBOL_GPL vmlinux 0x79d8cd2e d_obtain_alias +EXPORT_SYMBOL_GPL vmlinux 0x7a4c1438 pv_info +EXPORT_SYMBOL_GPL vmlinux 0x7a6cb59f class_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x7ac10ebc uv_node_to_blade +EXPORT_SYMBOL_GPL vmlinux 0x7ae1ae8e cpufreq_frequency_table_put_attr +EXPORT_SYMBOL_GPL vmlinux 0x7aed932a rt_mutex_timed_lock +EXPORT_SYMBOL_GPL vmlinux 0x7b0d1dc5 inet_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0x7b1d544d edac_handler_set +EXPORT_SYMBOL_GPL vmlinux 0x7b351ef0 usb_match_id +EXPORT_SYMBOL_GPL vmlinux 0x7b52d61c rtc_class_close +EXPORT_SYMBOL_GPL vmlinux 0x7b71cdc4 inet_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0x7c028a0e da903x_set_bits +EXPORT_SYMBOL_GPL vmlinux 0x7c605420 __sock_recv_timestamp +EXPORT_SYMBOL_GPL vmlinux 0x7c6d7605 blocking_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x7c9ca444 usb_serial_probe +EXPORT_SYMBOL_GPL vmlinux 0x7da8d037 marker_probe_register +EXPORT_SYMBOL_GPL vmlinux 0x7dc5d0b6 crypto_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x7dd10e55 vfs_setlease +EXPORT_SYMBOL_GPL vmlinux 0x7e275ea8 scsi_complete_async_scans +EXPORT_SYMBOL_GPL vmlinux 0x7e64181d usb_calc_bus_time +EXPORT_SYMBOL_GPL vmlinux 0x7f19c836 unlock_policy_rwsem_write +EXPORT_SYMBOL_GPL vmlinux 0x7f7092d4 blk_abort_request +EXPORT_SYMBOL_GPL vmlinux 0x7fa0854c relay_buf_full +EXPORT_SYMBOL_GPL vmlinux 0x7fcae6b9 regulator_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x7ff10ccf raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x8039d043 selinux_secmark_relabel_packet_permission +EXPORT_SYMBOL_GPL vmlinux 0x80450993 register_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0x806bcf08 usb_serial_disconnect +EXPORT_SYMBOL_GPL vmlinux 0x808ec1a3 crypto_alg_tested +EXPORT_SYMBOL_GPL vmlinux 0x80ee55c3 selinux_secmark_refcount_inc +EXPORT_SYMBOL_GPL vmlinux 0x81006c0f rdev_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x812c7fac hrtimer_try_to_cancel +EXPORT_SYMBOL_GPL vmlinux 0x8161605a blk_queue_dma_drain +EXPORT_SYMBOL_GPL vmlinux 0x81ecefef spi_register_master +EXPORT_SYMBOL_GPL vmlinux 0x821093a9 crypto_grab_skcipher +EXPORT_SYMBOL_GPL vmlinux 0x8226642f __gpio_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x826360fd do_posix_clock_nonanosleep +EXPORT_SYMBOL_GPL vmlinux 0x82a84117 __blkdev_driver_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x82cd19f3 register_xenstore_notifier +EXPORT_SYMBOL_GPL vmlinux 0x82d79b51 sysctl_vfs_cache_pressure +EXPORT_SYMBOL_GPL vmlinux 0x82f776b7 gpio_export +EXPORT_SYMBOL_GPL vmlinux 0x831e6780 device_rename +EXPORT_SYMBOL_GPL vmlinux 0x8361342c do_sync_mapping_range +EXPORT_SYMBOL_GPL vmlinux 0x83666f91 proc_net_mkdir +EXPORT_SYMBOL_GPL vmlinux 0x83b2e956 register_rfkill_notifier +EXPORT_SYMBOL_GPL vmlinux 0x83d94db0 inet_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0x83fab8d3 power_supply_unregister +EXPORT_SYMBOL_GPL vmlinux 0x8452dd8e bus_register +EXPORT_SYMBOL_GPL vmlinux 0x84834145 hrtimer_get_remaining +EXPORT_SYMBOL_GPL vmlinux 0x84bda7ab sdio_release_host +EXPORT_SYMBOL_GPL vmlinux 0x851f1bf0 usb_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0x85478a0b inet6_hash_frag +EXPORT_SYMBOL_GPL vmlinux 0x85781f58 ezusb_set_reset +EXPORT_SYMBOL_GPL vmlinux 0x85c10896 rcu_batches_completed_bh +EXPORT_SYMBOL_GPL vmlinux 0x85d7edfd hpet_set_periodic_freq +EXPORT_SYMBOL_GPL vmlinux 0x85e5a3db ktime_get_ts +EXPORT_SYMBOL_GPL vmlinux 0x85fdcf96 ata_dev_pair +EXPORT_SYMBOL_GPL vmlinux 0x8648f109 ezusb_writememory +EXPORT_SYMBOL_GPL vmlinux 0x864b4fe6 sata_scr_read +EXPORT_SYMBOL_GPL vmlinux 0x865ee09f tcp_is_cwnd_limited +EXPORT_SYMBOL_GPL vmlinux 0x86623fd7 notify_remote_via_irq +EXPORT_SYMBOL_GPL vmlinux 0x86765505 pci_test_config_bits +EXPORT_SYMBOL_GPL vmlinux 0x86772245 vfs_listxattr +EXPORT_SYMBOL_GPL vmlinux 0x86782f94 crypto_shoot_alg +EXPORT_SYMBOL_GPL vmlinux 0x867c684a setup_APIC_eilvt_ibs +EXPORT_SYMBOL_GPL vmlinux 0x868784cb __symbol_get +EXPORT_SYMBOL_GPL vmlinux 0x869d59be rtc_irq_register +EXPORT_SYMBOL_GPL vmlinux 0x86a51007 gnttab_end_foreign_transfer +EXPORT_SYMBOL_GPL vmlinux 0x86b1667d hwrng_unregister +EXPORT_SYMBOL_GPL vmlinux 0x86b552bd crypto_alg_lookup +EXPORT_SYMBOL_GPL vmlinux 0x86c722f8 rfkill_epo +EXPORT_SYMBOL_GPL vmlinux 0x871a9910 register_kprobes +EXPORT_SYMBOL_GPL vmlinux 0x8727384e rtnl_kill_links +EXPORT_SYMBOL_GPL vmlinux 0x873fbaea edac_atomic_assert_error +EXPORT_SYMBOL_GPL vmlinux 0x8766a2f6 k_handler +EXPORT_SYMBOL_GPL vmlinux 0x876d29f1 wmi_get_event_data +EXPORT_SYMBOL_GPL vmlinux 0x87754115 raw_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x87a0198b default_backing_dev_info +EXPORT_SYMBOL_GPL vmlinux 0x87bb040d aead_geniv_init +EXPORT_SYMBOL_GPL vmlinux 0x87cf96fb rtc_read_time +EXPORT_SYMBOL_GPL vmlinux 0x87f2cf3a blocking_notifier_chain_cond_register +EXPORT_SYMBOL_GPL vmlinux 0x880b189a __atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x8810ad5e crypto_xor +EXPORT_SYMBOL_GPL vmlinux 0x88115cfb rt_mutex_unlock +EXPORT_SYMBOL_GPL vmlinux 0x885142a6 nf_net_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x88806d6c ata_std_qc_defer +EXPORT_SYMBOL_GPL vmlinux 0x88f0db24 cancel_work_sync +EXPORT_SYMBOL_GPL vmlinux 0x891c3a42 crypto_enqueue_request +EXPORT_SYMBOL_GPL vmlinux 0x898b9854 ata_bus_reset +EXPORT_SYMBOL_GPL vmlinux 0x8999ab35 __rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x89ba353e blk_rq_cur_bytes +EXPORT_SYMBOL_GPL vmlinux 0x89d4dbaf usb_usual_check_type +EXPORT_SYMBOL_GPL vmlinux 0x8abed13d xfrm_aead_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x8add8105 ip_local_out +EXPORT_SYMBOL_GPL vmlinux 0x8af9b1ab tcp_reno_cong_avoid +EXPORT_SYMBOL_GPL vmlinux 0x8b1aab6a spi_sync +EXPORT_SYMBOL_GPL vmlinux 0x8b3fdfe1 crypto_spawn_tfm +EXPORT_SYMBOL_GPL vmlinux 0x8b752ac1 ata_tf_to_fis +EXPORT_SYMBOL_GPL vmlinux 0x8b9200fd lookup_address +EXPORT_SYMBOL_GPL vmlinux 0x8c06a108 xenbus_transaction_start +EXPORT_SYMBOL_GPL vmlinux 0x8c38074a unregister_xenstore_notifier +EXPORT_SYMBOL_GPL vmlinux 0x8c7eabaa generic_drop_inode +EXPORT_SYMBOL_GPL vmlinux 0x8cd24340 ata_port_disable +EXPORT_SYMBOL_GPL vmlinux 0x8cda2d21 ata_sff_tf_read +EXPORT_SYMBOL_GPL vmlinux 0x8ce0aeea tty_perform_flush +EXPORT_SYMBOL_GPL vmlinux 0x8d0f74f2 attribute_container_unregister +EXPORT_SYMBOL_GPL vmlinux 0x8d4c50a9 xenbus_map_ring +EXPORT_SYMBOL_GPL vmlinux 0x8d5ebc47 ata_bmdma_setup +EXPORT_SYMBOL_GPL vmlinux 0x8d7b62a2 ip_route_output_flow +EXPORT_SYMBOL_GPL vmlinux 0x8df31d69 input_ff_erase +EXPORT_SYMBOL_GPL vmlinux 0x8e4f7c7b dm_rh_recovery_start +EXPORT_SYMBOL_GPL vmlinux 0x8e7cbaf0 sysdev_class_register +EXPORT_SYMBOL_GPL vmlinux 0x8e8d86e8 bus_rescan_devices +EXPORT_SYMBOL_GPL vmlinux 0x8e95df0f cpuidle_disable_device +EXPORT_SYMBOL_GPL vmlinux 0x8eb58c6e __wake_up_sync +EXPORT_SYMBOL_GPL vmlinux 0x8ec3345b tty_get_pgrp +EXPORT_SYMBOL_GPL vmlinux 0x8f09ef7e ata_port_freeze +EXPORT_SYMBOL_GPL vmlinux 0x8f5fc2a0 fsstack_copy_inode_size +EXPORT_SYMBOL_GPL vmlinux 0x8f6cee77 __round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x8f819698 inverse_translate +EXPORT_SYMBOL_GPL vmlinux 0x8fbc0c9b regulator_set_voltage +EXPORT_SYMBOL_GPL vmlinux 0x8ffaa7a7 da903x_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x9009602a acpi_bus_get_ejd +EXPORT_SYMBOL_GPL vmlinux 0x90097289 usb_free_urb +EXPORT_SYMBOL_GPL vmlinux 0x900f4bbf dm_register_path_selector +EXPORT_SYMBOL_GPL vmlinux 0x9049c9c0 debugfs_remove +EXPORT_SYMBOL_GPL vmlinux 0x905f73ad xfrm_output_resume +EXPORT_SYMBOL_GPL vmlinux 0x906b805e srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x90a1004a crypto_has_alg +EXPORT_SYMBOL_GPL vmlinux 0x91482eef usb_anchor_empty +EXPORT_SYMBOL_GPL vmlinux 0x9159b9d6 profile_event_register +EXPORT_SYMBOL_GPL vmlinux 0x9193f762 disk_map_sector_rcu +EXPORT_SYMBOL_GPL vmlinux 0x91dacaa2 acpi_processor_ffh_cstate_probe +EXPORT_SYMBOL_GPL vmlinux 0x9215cb3d regulator_get_init_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x92183295 crypto_chain +EXPORT_SYMBOL_GPL vmlinux 0x9220ee73 rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x9241c3ee device_power_down +EXPORT_SYMBOL_GPL vmlinux 0x92445aee hrtimer_get_res +EXPORT_SYMBOL_GPL vmlinux 0x92542724 inotify_find_watch +EXPORT_SYMBOL_GPL vmlinux 0x928d1290 usb_autopm_get_interface +EXPORT_SYMBOL_GPL vmlinux 0x92946a1a vfs_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0x92bfb9dd sock_prot_inuse_get +EXPORT_SYMBOL_GPL vmlinux 0x92d20b43 raw_seq_open +EXPORT_SYMBOL_GPL vmlinux 0x92d31cfb fixed_phy_add +EXPORT_SYMBOL_GPL vmlinux 0x92e90d18 __mmu_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x92fb217b dcookie_unregister +EXPORT_SYMBOL_GPL vmlinux 0x935b3776 dm_rh_inc_pending +EXPORT_SYMBOL_GPL vmlinux 0x93755b89 regulator_get_voltage +EXPORT_SYMBOL_GPL vmlinux 0x937d164a rtc_update_irq +EXPORT_SYMBOL_GPL vmlinux 0x93843a06 pci_find_next_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0x93c0850e rt_mutex_destroy +EXPORT_SYMBOL_GPL vmlinux 0x93d2422d snmp_mib_free +EXPORT_SYMBOL_GPL vmlinux 0x93d4d74a __class_create +EXPORT_SYMBOL_GPL vmlinux 0x93f1254b cpufreq_freq_attr_scaling_available_freqs +EXPORT_SYMBOL_GPL vmlinux 0x93f83633 crypto_register_template +EXPORT_SYMBOL_GPL vmlinux 0x942c1704 cleanup_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x945ef9e8 cpufreq_unregister_governor +EXPORT_SYMBOL_GPL vmlinux 0x9481713a get_device +EXPORT_SYMBOL_GPL vmlinux 0x948b1b82 xfrm_audit_state_notfound_simple +EXPORT_SYMBOL_GPL vmlinux 0x948ecaf5 inet_unhash +EXPORT_SYMBOL_GPL vmlinux 0x94a68723 ata_scsi_slave_destroy +EXPORT_SYMBOL_GPL vmlinux 0x94dc62d2 ata_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x94ef4d05 cpci_hp_stop +EXPORT_SYMBOL_GPL vmlinux 0x951c26ae led_trigger_register_simple +EXPORT_SYMBOL_GPL vmlinux 0x952664c5 do_exit +EXPORT_SYMBOL_GPL vmlinux 0x95431980 inotify_inode_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x956a91ba gpio_get_value_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x9577271c hpet_rtc_interrupt +EXPORT_SYMBOL_GPL vmlinux 0x961a8cd3 unlock_policy_rwsem_read +EXPORT_SYMBOL_GPL vmlinux 0x964d5c39 acpi_os_map_memory +EXPORT_SYMBOL_GPL vmlinux 0x96cbcf31 pm_qos_add_notifier +EXPORT_SYMBOL_GPL vmlinux 0x97309c43 ata_acpi_gtm +EXPORT_SYMBOL_GPL vmlinux 0x9753573a vfs_getxattr +EXPORT_SYMBOL_GPL vmlinux 0x977f09c2 scsi_nl_add_transport +EXPORT_SYMBOL_GPL vmlinux 0x97d44d4d tty_ldisc_flush +EXPORT_SYMBOL_GPL vmlinux 0x9833bc0c hvc_kick +EXPORT_SYMBOL_GPL vmlinux 0x983646be rt_mutex_lock +EXPORT_SYMBOL_GPL vmlinux 0x98a62878 bus_create_file +EXPORT_SYMBOL_GPL vmlinux 0x98adb824 hrtimer_forward +EXPORT_SYMBOL_GPL vmlinux 0x991f3cb0 vfs_test_lock +EXPORT_SYMBOL_GPL vmlinux 0x9924c496 __usb_get_extra_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x992c011b __rt_mutex_init +EXPORT_SYMBOL_GPL vmlinux 0x995d1071 prof_on +EXPORT_SYMBOL_GPL vmlinux 0x99750e11 hidraw_connect +EXPORT_SYMBOL_GPL vmlinux 0x99856cbc debugfs_rename +EXPORT_SYMBOL_GPL vmlinux 0x999afee1 sysctl_pathname +EXPORT_SYMBOL_GPL vmlinux 0x9a11a0fc crypto_attr_alg_name +EXPORT_SYMBOL_GPL vmlinux 0x9a278ba2 __cpufreq_driver_target +EXPORT_SYMBOL_GPL vmlinux 0x9a398f5c xfrm_ealg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x9a4d1034 idle_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x9a711941 blk_execute_rq_nowait +EXPORT_SYMBOL_GPL vmlinux 0x9aa8d532 bd_release_from_disk +EXPORT_SYMBOL_GPL vmlinux 0x9abfe361 skcipher_geniv_exit +EXPORT_SYMBOL_GPL vmlinux 0x9ac12409 ata_do_dev_read_id +EXPORT_SYMBOL_GPL vmlinux 0x9ac8ef4a dm_rh_mark_nosync +EXPORT_SYMBOL_GPL vmlinux 0x9aec7588 inet_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0x9b63de24 scsi_queue_work +EXPORT_SYMBOL_GPL vmlinux 0x9b8a1454 tracepoint_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x9ba0501e unregister_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0x9bc9fcb2 ata_sff_dev_select +EXPORT_SYMBOL_GPL vmlinux 0x9bd37575 sdio_writel +EXPORT_SYMBOL_GPL vmlinux 0x9cb76733 ata_sff_hsm_move +EXPORT_SYMBOL_GPL vmlinux 0x9cb8037b xfrm_count_enc_supported +EXPORT_SYMBOL_GPL vmlinux 0x9cbe58b3 dm_set_device_limits +EXPORT_SYMBOL_GPL vmlinux 0x9d06688b register_xenbus_watch +EXPORT_SYMBOL_GPL vmlinux 0x9d118a8b xenbus_frontend_closed +EXPORT_SYMBOL_GPL vmlinux 0x9d2770bc __xenbus_register_frontend +EXPORT_SYMBOL_GPL vmlinux 0x9d3850e1 gnttab_alloc_grant_references +EXPORT_SYMBOL_GPL vmlinux 0x9d86a06d sync_page_io +EXPORT_SYMBOL_GPL vmlinux 0x9dcaa462 scsi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x9de5e149 devres_add +EXPORT_SYMBOL_GPL vmlinux 0x9dff3258 ata_sas_port_start +EXPORT_SYMBOL_GPL vmlinux 0x9e5f1d47 sdio_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x9e711ad2 pm_qos_requirement +EXPORT_SYMBOL_GPL vmlinux 0x9e7b7952 hrtimer_start +EXPORT_SYMBOL_GPL vmlinux 0x9e7d3442 xenbus_resume +EXPORT_SYMBOL_GPL vmlinux 0x9e7f3792 get_driver +EXPORT_SYMBOL_GPL vmlinux 0x9e9eab7c bd_claim_by_disk +EXPORT_SYMBOL_GPL vmlinux 0x9eb26852 regulator_put +EXPORT_SYMBOL_GPL vmlinux 0x9eb669ae debugfs_remove_recursive +EXPORT_SYMBOL_GPL vmlinux 0x9f628956 device_add +EXPORT_SYMBOL_GPL vmlinux 0x9fb5d63b sysdev_show_int +EXPORT_SYMBOL_GPL vmlinux 0x9fce80db fb_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x9ff7295f dev_attr_em_message +EXPORT_SYMBOL_GPL vmlinux 0xa00e7e6b crypto_register_instance +EXPORT_SYMBOL_GPL vmlinux 0xa0255440 net_ipv4_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0xa0343e0f crypto_larval_lookup +EXPORT_SYMBOL_GPL vmlinux 0xa038dd1c ata_sff_postreset +EXPORT_SYMBOL_GPL vmlinux 0xa03e4418 pskb_put +EXPORT_SYMBOL_GPL vmlinux 0xa0f8c4b3 ata_sas_port_init +EXPORT_SYMBOL_GPL vmlinux 0xa0ff5aac nf_unregister_queue_handlers +EXPORT_SYMBOL_GPL vmlinux 0xa1438b24 ata_sff_dma_pause +EXPORT_SYMBOL_GPL vmlinux 0xa1484057 ata_cable_ignore +EXPORT_SYMBOL_GPL vmlinux 0xa1569e89 sysfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0xa1596d98 acpi_processor_ffh_cstate_enter +EXPORT_SYMBOL_GPL vmlinux 0xa19d0bce xfrm_audit_state_notfound +EXPORT_SYMBOL_GPL vmlinux 0xa1e0d58a find_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0xa2245576 platform_device_alloc +EXPORT_SYMBOL_GPL vmlinux 0xa2422139 blk_update_request +EXPORT_SYMBOL_GPL vmlinux 0xa27c3443 ata_eh_analyze_ncq_error +EXPORT_SYMBOL_GPL vmlinux 0xa28d8527 usb_poison_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xa2c03841 bind_evtchn_to_irqhandler +EXPORT_SYMBOL_GPL vmlinux 0xa2e67f08 acpi_bus_generate_proc_event4 +EXPORT_SYMBOL_GPL vmlinux 0xa303d2b8 skb_pull_rcsum +EXPORT_SYMBOL_GPL vmlinux 0xa3421352 sysdev_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0xa353fffc xenbus_rm +EXPORT_SYMBOL_GPL vmlinux 0xa395ed45 sysfs_create_link +EXPORT_SYMBOL_GPL vmlinux 0xa3fc96f0 marker_probe_cb_noarg +EXPORT_SYMBOL_GPL vmlinux 0xa43a7887 inet6_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0xa452c297 hpet_mask_rtc_irq_bit +EXPORT_SYMBOL_GPL vmlinux 0xa480e2ed led_trigger_remove +EXPORT_SYMBOL_GPL vmlinux 0xa4d58669 math_state_restore +EXPORT_SYMBOL_GPL vmlinux 0xa50c7406 __ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0xa57112ec sdio_claim_host +EXPORT_SYMBOL_GPL vmlinux 0xa58c825c queue_delayed_work +EXPORT_SYMBOL_GPL vmlinux 0xa5905968 skcipher_geniv_init +EXPORT_SYMBOL_GPL vmlinux 0xa596f330 tracepoint_iter_start +EXPORT_SYMBOL_GPL vmlinux 0xa5bf5c3e pm_qos_add_requirement +EXPORT_SYMBOL_GPL vmlinux 0xa5c36cec inotify_unmount_inodes +EXPORT_SYMBOL_GPL vmlinux 0xa641de63 sysfs_chmod_file +EXPORT_SYMBOL_GPL vmlinux 0xa64ccd3d pv_apic_ops +EXPORT_SYMBOL_GPL vmlinux 0xa6777ff8 nf_unregister_afinfo +EXPORT_SYMBOL_GPL vmlinux 0xa681d3e4 debugfs_create_x16 +EXPORT_SYMBOL_GPL vmlinux 0xa6874c4d __get_vm_area +EXPORT_SYMBOL_GPL vmlinux 0xa68e8802 blk_trace_startstop +EXPORT_SYMBOL_GPL vmlinux 0xa6c31e2a get_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0xa6f4320d unregister_rfkill_notifier +EXPORT_SYMBOL_GPL vmlinux 0xa778271c inet6_lookup +EXPORT_SYMBOL_GPL vmlinux 0xa7c86791 crypto_blkcipher_type +EXPORT_SYMBOL_GPL vmlinux 0xa83d191c i2c_new_dummy +EXPORT_SYMBOL_GPL vmlinux 0xa854dce3 sdio_release_irq +EXPORT_SYMBOL_GPL vmlinux 0xa880c5e0 cpuidle_enable_device +EXPORT_SYMBOL_GPL vmlinux 0xa8bcb0c3 pci_unblock_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0xa8f1ab7d sata_pmp_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xa8f59416 gpio_direction_output +EXPORT_SYMBOL_GPL vmlinux 0xa9126bff hpet_set_rtc_irq_bit +EXPORT_SYMBOL_GPL vmlinux 0xa928204a ata_eh_qc_retry +EXPORT_SYMBOL_GPL vmlinux 0xa92c6424 pci_enable_rom +EXPORT_SYMBOL_GPL vmlinux 0xa93df210 pci_slots_kset +EXPORT_SYMBOL_GPL vmlinux 0xa963f49c tcp_orphan_count +EXPORT_SYMBOL_GPL vmlinux 0xa965d9d3 blk_rq_check_limits +EXPORT_SYMBOL_GPL vmlinux 0xa96e4b6e usb_buffer_map_sg +EXPORT_SYMBOL_GPL vmlinux 0xa988cdd5 dm_rh_delay +EXPORT_SYMBOL_GPL vmlinux 0xa9c2de28 inet_twsk_alloc +EXPORT_SYMBOL_GPL vmlinux 0xa9c530b8 unregister_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xa9c862e5 invalidate_inode_pages2 +EXPORT_SYMBOL_GPL vmlinux 0xa9cfcb95 ata_pci_sff_init_one +EXPORT_SYMBOL_GPL vmlinux 0xa9f271bb find_vpid +EXPORT_SYMBOL_GPL vmlinux 0xaa266d1c ata_std_bios_param +EXPORT_SYMBOL_GPL vmlinux 0xaa797cb0 pci_reset_function +EXPORT_SYMBOL_GPL vmlinux 0xaa86cfb5 uv_possible_blades +EXPORT_SYMBOL_GPL vmlinux 0xaa8c4696 cpu_clock +EXPORT_SYMBOL_GPL vmlinux 0xaa939143 rtnl_put_cacheinfo +EXPORT_SYMBOL_GPL vmlinux 0xaa9b096b register_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0xaa9c12ce ata_sff_freeze +EXPORT_SYMBOL_GPL vmlinux 0xaabe8903 mm_kobj +EXPORT_SYMBOL_GPL vmlinux 0xaadfa84a usb_unanchor_urb +EXPORT_SYMBOL_GPL vmlinux 0xab01acbe gnttab_request_free_callback +EXPORT_SYMBOL_GPL vmlinux 0xab4c3488 usb_sg_wait +EXPORT_SYMBOL_GPL vmlinux 0xab57e311 tracepoint_probe_register +EXPORT_SYMBOL_GPL vmlinux 0xabb566fc device_create +EXPORT_SYMBOL_GPL vmlinux 0xabf840a8 elv_unregister +EXPORT_SYMBOL_GPL vmlinux 0xac34813d pci_find_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0xac470458 cpci_hp_unregister_controller +EXPORT_SYMBOL_GPL vmlinux 0xac9d742d class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xacc19485 ibft_addr +EXPORT_SYMBOL_GPL vmlinux 0xace5c0fc usb_bus_list +EXPORT_SYMBOL_GPL vmlinux 0xad096363 xenbus_printf +EXPORT_SYMBOL_GPL vmlinux 0xad372144 part_round_stats +EXPORT_SYMBOL_GPL vmlinux 0xad46b724 rtc_set_mmss +EXPORT_SYMBOL_GPL vmlinux 0xad5bdeca pci_find_next_capability +EXPORT_SYMBOL_GPL vmlinux 0xad63a24e per_cpu____uv_hub_info +EXPORT_SYMBOL_GPL vmlinux 0xad6f414f crypto_aead_type +EXPORT_SYMBOL_GPL vmlinux 0xade5f8e0 sysdev_show_ulong +EXPORT_SYMBOL_GPL vmlinux 0xadf38d45 inotify_add_watch +EXPORT_SYMBOL_GPL vmlinux 0xae0c87ee pm_qos_remove_notifier +EXPORT_SYMBOL_GPL vmlinux 0xae1d8f2d generic_fh_to_dentry +EXPORT_SYMBOL_GPL vmlinux 0xae6e97c2 fl6_sock_lookup +EXPORT_SYMBOL_GPL vmlinux 0xae7dfbdc usb_set_interface +EXPORT_SYMBOL_GPL vmlinux 0xaeac662a cpufreq_register_driver +EXPORT_SYMBOL_GPL vmlinux 0xaee89436 skb_cow_data +EXPORT_SYMBOL_GPL vmlinux 0xaf7112f6 device_register +EXPORT_SYMBOL_GPL vmlinux 0xafc7c996 usb_unlink_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xb03bd622 usb_deregister +EXPORT_SYMBOL_GPL vmlinux 0xb07bc423 ata_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0xb0aa812e fips_enabled +EXPORT_SYMBOL_GPL vmlinux 0xb0de7d62 ata_std_postreset +EXPORT_SYMBOL_GPL vmlinux 0xb0eedea9 usb_wait_anchor_empty_timeout +EXPORT_SYMBOL_GPL vmlinux 0xb10d55bc cn_netlink_send +EXPORT_SYMBOL_GPL vmlinux 0xb1982c21 crypto_free_tfm +EXPORT_SYMBOL_GPL vmlinux 0xb1acbcce rcu_barrier_sched +EXPORT_SYMBOL_GPL vmlinux 0xb1d1d4de usb_put_hcd +EXPORT_SYMBOL_GPL vmlinux 0xb27005f5 device_suspend +EXPORT_SYMBOL_GPL vmlinux 0xb2ad79c5 crypto_lookup_template +EXPORT_SYMBOL_GPL vmlinux 0xb2b9bc64 alloc_vm_area +EXPORT_SYMBOL_GPL vmlinux 0xb3253ed9 hpet_rtc_timer_init +EXPORT_SYMBOL_GPL vmlinux 0xb390832b dm_rh_region_to_sector +EXPORT_SYMBOL_GPL vmlinux 0xb3c7da52 usb_poison_urb +EXPORT_SYMBOL_GPL vmlinux 0xb3d5e527 acpi_smbus_write +EXPORT_SYMBOL_GPL vmlinux 0xb44f07a1 usb_hcd_link_urb_to_ep +EXPORT_SYMBOL_GPL vmlinux 0xb4af05f6 debugfs_create_x8 +EXPORT_SYMBOL_GPL vmlinux 0xb4da3a51 dma_get_required_mask +EXPORT_SYMBOL_GPL vmlinux 0xb4e14553 gnttab_query_foreign_access +EXPORT_SYMBOL_GPL vmlinux 0xb4ea7cf7 kgdb_connected +EXPORT_SYMBOL_GPL vmlinux 0xb4fe6005 bus_find_device_by_name +EXPORT_SYMBOL_GPL vmlinux 0xb51fbd64 edac_op_state +EXPORT_SYMBOL_GPL vmlinux 0xb53ae573 cpu_idle_wait +EXPORT_SYMBOL_GPL vmlinux 0xb5a6ebe2 wmi_remove_notify_handler +EXPORT_SYMBOL_GPL vmlinux 0xb5eb38c2 device_create_file +EXPORT_SYMBOL_GPL vmlinux 0xb612444d snmp_mib_init +EXPORT_SYMBOL_GPL vmlinux 0xb61ad05f register_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0xb6230f1f gnttab_grant_foreign_access +EXPORT_SYMBOL_GPL vmlinux 0xb6296082 usb_get_status +EXPORT_SYMBOL_GPL vmlinux 0xb631e26a cpufreq_driver_target +EXPORT_SYMBOL_GPL vmlinux 0xb63550f5 __i2c_board_lock +EXPORT_SYMBOL_GPL vmlinux 0xb65091b3 selinux_secmark_refcount_dec +EXPORT_SYMBOL_GPL vmlinux 0xb6aeb661 ata_id_c_string +EXPORT_SYMBOL_GPL vmlinux 0xb7b9ba01 scsi_dh_attach +EXPORT_SYMBOL_GPL vmlinux 0xb7d7c12e hpet_set_alarm_time +EXPORT_SYMBOL_GPL vmlinux 0xb827c653 ata_std_error_handler +EXPORT_SYMBOL_GPL vmlinux 0xb836264b inet_hash +EXPORT_SYMBOL_GPL vmlinux 0xb842724c cpuidle_register_device +EXPORT_SYMBOL_GPL vmlinux 0xb8452387 do_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0xb89ac110 scsi_internal_device_block +EXPORT_SYMBOL_GPL vmlinux 0xb89bd016 ata_sff_busy_sleep +EXPORT_SYMBOL_GPL vmlinux 0xb903674c scatterwalk_map_and_copy +EXPORT_SYMBOL_GPL vmlinux 0xb92b16ba dm_region_hash_create +EXPORT_SYMBOL_GPL vmlinux 0xb93f8d40 ip6_dst_lookup +EXPORT_SYMBOL_GPL vmlinux 0xb96fe7f8 usb_init_urb +EXPORT_SYMBOL_GPL vmlinux 0xb99d5837 xenbus_read +EXPORT_SYMBOL_GPL vmlinux 0xb9c3a6a9 platform_device_add_data +EXPORT_SYMBOL_GPL vmlinux 0xb9eb3aa9 add_uevent_var +EXPORT_SYMBOL_GPL vmlinux 0xba786f29 md_do_sync +EXPORT_SYMBOL_GPL vmlinux 0xbae34c27 scsi_nl_remove_transport +EXPORT_SYMBOL_GPL vmlinux 0xbafc3fc2 da903x_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0xbb29d2c6 inet_csk_get_port +EXPORT_SYMBOL_GPL vmlinux 0xbb3318c9 usb_hcd_pci_shutdown +EXPORT_SYMBOL_GPL vmlinux 0xbb3d9e45 d_materialise_unique +EXPORT_SYMBOL_GPL vmlinux 0xbbae5e95 usb_driver_release_interface +EXPORT_SYMBOL_GPL vmlinux 0xbbb98859 edid_info +EXPORT_SYMBOL_GPL vmlinux 0xbbd4d910 hidraw_disconnect +EXPORT_SYMBOL_GPL vmlinux 0xbc0362a4 i2c_new_probed_device +EXPORT_SYMBOL_GPL vmlinux 0xbc8d4732 sock_prot_inuse_add +EXPORT_SYMBOL_GPL vmlinux 0xbcfb76b5 regulator_bulk_free +EXPORT_SYMBOL_GPL vmlinux 0xbd236675 dm_rh_get_region_size +EXPORT_SYMBOL_GPL vmlinux 0xbd25a9e8 device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xbd506a46 unregister_hotplug_dock_device +EXPORT_SYMBOL_GPL vmlinux 0xbd7387a6 driver_create_file +EXPORT_SYMBOL_GPL vmlinux 0xbd7bda4c register_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0xbd952066 register_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0xbdd295f0 trace_vprintk +EXPORT_SYMBOL_GPL vmlinux 0xbde5e56e transport_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0xbdeff290 inet_ctl_sock_create +EXPORT_SYMBOL_GPL vmlinux 0xbe1887e4 ata_unpack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xbe214d59 platform_device_register_simple +EXPORT_SYMBOL_GPL vmlinux 0xbe4668ed ata_sff_pause +EXPORT_SYMBOL_GPL vmlinux 0xbe4c0a45 dm_path_uevent +EXPORT_SYMBOL_GPL vmlinux 0xbe685641 dev_attr_sw_activity +EXPORT_SYMBOL_GPL vmlinux 0xbe7e9e95 usb_buffer_alloc +EXPORT_SYMBOL_GPL vmlinux 0xbeb14728 debugfs_create_u8 +EXPORT_SYMBOL_GPL vmlinux 0xbeb161fa usb_interrupt_msg +EXPORT_SYMBOL_GPL vmlinux 0xbeb3dfae transport_setup_device +EXPORT_SYMBOL_GPL vmlinux 0xbf74eb20 probe_kernel_write +EXPORT_SYMBOL_GPL vmlinux 0xbfbc456a disk_part_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0xbfbeb44a i2c_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xc00c8f8d swiotlb_sync_single_range_for_device +EXPORT_SYMBOL_GPL vmlinux 0xc03c74f5 xfrm_inner_extract_output +EXPORT_SYMBOL_GPL vmlinux 0xc041ab3a vfs_cancel_lock +EXPORT_SYMBOL_GPL vmlinux 0xc0ca9071 shmem_file_setup +EXPORT_SYMBOL_GPL vmlinux 0xc17515d7 usb_hcds_loaded +EXPORT_SYMBOL_GPL vmlinux 0xc196a571 ip6_dst_blackhole +EXPORT_SYMBOL_GPL vmlinux 0xc1a86893 cpufreq_frequency_table_target +EXPORT_SYMBOL_GPL vmlinux 0xc2083518 class_interface_register +EXPORT_SYMBOL_GPL vmlinux 0xc22a3091 vm_unmap_aliases +EXPORT_SYMBOL_GPL vmlinux 0xc2485e93 rtc_device_register +EXPORT_SYMBOL_GPL vmlinux 0xc26351f8 bind_evtchn_to_irq +EXPORT_SYMBOL_GPL vmlinux 0xc28d73a2 ata_bmdma_start +EXPORT_SYMBOL_GPL vmlinux 0xc295e93e i2c_unregister_device +EXPORT_SYMBOL_GPL vmlinux 0xc2beeb74 scsi_unregister_device_handler +EXPORT_SYMBOL_GPL vmlinux 0xc2fb2b59 hwmon_device_register +EXPORT_SYMBOL_GPL vmlinux 0xc310fd2d blk_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0xc34efe27 snmp_fold_field +EXPORT_SYMBOL_GPL vmlinux 0xc3887ccf sdio_memcpy_fromio +EXPORT_SYMBOL_GPL vmlinux 0xc399468f scsi_nl_remove_driver +EXPORT_SYMBOL_GPL vmlinux 0xc408b2d1 scsi_eh_ready_devs +EXPORT_SYMBOL_GPL vmlinux 0xc41b487b kset_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0xc428068d sata_deb_timing_long +EXPORT_SYMBOL_GPL vmlinux 0xc42f2f94 xenbus_read_driver_state +EXPORT_SYMBOL_GPL vmlinux 0xc42f91e0 sysdev_store_ulong +EXPORT_SYMBOL_GPL vmlinux 0xc44aa88f __inet_inherit_port +EXPORT_SYMBOL_GPL vmlinux 0xc4568cce dm_rh_bio_to_region +EXPORT_SYMBOL_GPL vmlinux 0xc462dc12 user_instantiate +EXPORT_SYMBOL_GPL vmlinux 0xc48b7ccf ata_mode_string +EXPORT_SYMBOL_GPL vmlinux 0xc49facc7 ata_pci_bmdma_clear_simplex +EXPORT_SYMBOL_GPL vmlinux 0xc4a85741 cpuidle_unregister_device +EXPORT_SYMBOL_GPL vmlinux 0xc4b33aa6 tracepoint_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc4c552d7 stop_machine +EXPORT_SYMBOL_GPL vmlinux 0xc4ce6189 idle_notifier_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc512626a __supported_pte_mask +EXPORT_SYMBOL_GPL vmlinux 0xc5397da6 xenbus_mkdir +EXPORT_SYMBOL_GPL vmlinux 0xc54bd4d7 power_supply_am_i_supplied +EXPORT_SYMBOL_GPL vmlinux 0xc54ffd6d sysfs_get_dirent +EXPORT_SYMBOL_GPL vmlinux 0xc56e129b regulator_set_optimum_mode +EXPORT_SYMBOL_GPL vmlinux 0xc5834e90 drop_file_write_access +EXPORT_SYMBOL_GPL vmlinux 0xc5a4fbd0 ata_pio_need_iordy +EXPORT_SYMBOL_GPL vmlinux 0xc6041916 dm_put +EXPORT_SYMBOL_GPL vmlinux 0xc62c8e0f copy_fs_struct +EXPORT_SYMBOL_GPL vmlinux 0xc64006aa __mmdrop +EXPORT_SYMBOL_GPL vmlinux 0xc6730fc2 klist_iter_init +EXPORT_SYMBOL_GPL vmlinux 0xc673e23e ata_scsi_change_queue_depth +EXPORT_SYMBOL_GPL vmlinux 0xc6a6bf0e sata_pmp_qc_defer_cmd_switch +EXPORT_SYMBOL_GPL vmlinux 0xc719de28 usb_register_dev +EXPORT_SYMBOL_GPL vmlinux 0xc71a1b01 sk_setup_caps +EXPORT_SYMBOL_GPL vmlinux 0xc7395d43 crypto_unregister_alg +EXPORT_SYMBOL_GPL vmlinux 0xc74ffc80 hid_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0xc7504484 tracepoint_get_iter_range +EXPORT_SYMBOL_GPL vmlinux 0xc77bbc73 cpufreq_frequency_table_verify +EXPORT_SYMBOL_GPL vmlinux 0xc7aaec22 spi_write_then_read +EXPORT_SYMBOL_GPL vmlinux 0xc7ec11f6 atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xc80881c5 crypto_ablkcipher_type +EXPORT_SYMBOL_GPL vmlinux 0xc87c1f84 ktime_get +EXPORT_SYMBOL_GPL vmlinux 0xc87e487a sched_clock_idle_sleep_event +EXPORT_SYMBOL_GPL vmlinux 0xc89cb625 inet_csk_reqsk_queue_prune +EXPORT_SYMBOL_GPL vmlinux 0xc8c49291 ata_bmdma_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xc8ea1705 sysfs_remove_group +EXPORT_SYMBOL_GPL vmlinux 0xc94846ff usb_alloc_urb +EXPORT_SYMBOL_GPL vmlinux 0xc94d8c75 pcie_port_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xc955780f pci_bus_max_busnr +EXPORT_SYMBOL_GPL vmlinux 0xc9561772 fb_destroy_modelist +EXPORT_SYMBOL_GPL vmlinux 0xc9d2b99d driver_find_device +EXPORT_SYMBOL_GPL vmlinux 0xc9d4d6d1 wmi_has_guid +EXPORT_SYMBOL_GPL vmlinux 0xca81ea9a xenbus_transaction_end +EXPORT_SYMBOL_GPL vmlinux 0xcabe04de cpuidle_resume_and_unlock +EXPORT_SYMBOL_GPL vmlinux 0xcacd0328 usb_store_new_id +EXPORT_SYMBOL_GPL vmlinux 0xcb016909 unregister_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0xcb0f85f3 __blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0xcb80ff98 ata_sg_init +EXPORT_SYMBOL_GPL vmlinux 0xcbb08ab4 __inet_hash_nolisten +EXPORT_SYMBOL_GPL vmlinux 0xcc018d9c register_kprobe +EXPORT_SYMBOL_GPL vmlinux 0xcc131ad2 usb_hcd_check_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0xcc1f1c3d inet_twdr_hangman +EXPORT_SYMBOL_GPL vmlinux 0xcc3d7311 ata_sff_dumb_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0xcc6ab305 is_dock_device +EXPORT_SYMBOL_GPL vmlinux 0xcc9b23db skb_morph +EXPORT_SYMBOL_GPL vmlinux 0xccb1569d raw_unhash_sk +EXPORT_SYMBOL_GPL vmlinux 0xcccfb2fa sata_deb_timing_hotplug +EXPORT_SYMBOL_GPL vmlinux 0xcccfe12d mnt_want_write +EXPORT_SYMBOL_GPL vmlinux 0xcd0d72f7 register_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0xcd7fd1c8 key_type_user +EXPORT_SYMBOL_GPL vmlinux 0xcd9991a9 usb_usual_set_present +EXPORT_SYMBOL_GPL vmlinux 0xcda06d2e spi_alloc_device +EXPORT_SYMBOL_GPL vmlinux 0xcdc65197 tcp_reno_ssthresh +EXPORT_SYMBOL_GPL vmlinux 0xcdca3691 nr_irqs +EXPORT_SYMBOL_GPL vmlinux 0xce1f9baf usb_hc_died +EXPORT_SYMBOL_GPL vmlinux 0xcfcc83ad register_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0xcfd86dff usb_register_device_driver +EXPORT_SYMBOL_GPL vmlinux 0xd027a07d marker_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xd03c7700 secure_ipv4_port_ephemeral +EXPORT_SYMBOL_GPL vmlinux 0xd074f1e6 class_dev_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0xd0755a62 inet6_sk_rebuild_header +EXPORT_SYMBOL_GPL vmlinux 0xd0c05159 emergency_restart +EXPORT_SYMBOL_GPL vmlinux 0xd0d342a1 smp_ops +EXPORT_SYMBOL_GPL vmlinux 0xd0fe474f register_net_sysctl_rotable +EXPORT_SYMBOL_GPL vmlinux 0xd10a8a02 crypto_aead_setauthsize +EXPORT_SYMBOL_GPL vmlinux 0xd11df9db device_find_child +EXPORT_SYMBOL_GPL vmlinux 0xd129e5da ata_sas_slave_configure +EXPORT_SYMBOL_GPL vmlinux 0xd15ae16a ata_do_eh +EXPORT_SYMBOL_GPL vmlinux 0xd16712f3 crypto_check_attr_type +EXPORT_SYMBOL_GPL vmlinux 0xd1ce26aa device_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xd1fb4606 put_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0xd273b1b1 __round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xd2a8caf0 work_on_cpu +EXPORT_SYMBOL_GPL vmlinux 0xd2d121cd simple_attr_release +EXPORT_SYMBOL_GPL vmlinux 0xd2d9ba67 ata_sff_post_internal_cmd +EXPORT_SYMBOL_GPL vmlinux 0xd2f7f54c blk_queue_rq_timed_out +EXPORT_SYMBOL_GPL vmlinux 0xd3363284 hidinput_report_event +EXPORT_SYMBOL_GPL vmlinux 0xd371d730 ip6_sk_dst_lookup +EXPORT_SYMBOL_GPL vmlinux 0xd39d813f led_trigger_register +EXPORT_SYMBOL_GPL vmlinux 0xd3b78da3 xenbus_suspend_cancel +EXPORT_SYMBOL_GPL vmlinux 0xd3caf79d devres_remove_group +EXPORT_SYMBOL_GPL vmlinux 0xd4889861 ata_eh_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0xd48d0359 sysfs_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xd4ce5807 usb_mon_register +EXPORT_SYMBOL_GPL vmlinux 0xd5048499 relay_close +EXPORT_SYMBOL_GPL vmlinux 0xd58b776f sk_clone +EXPORT_SYMBOL_GPL vmlinux 0xd5d9d5f4 regulator_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0xd60c6ecf sdio_writesb +EXPORT_SYMBOL_GPL vmlinux 0xd6869ca1 inet_csk_listen_stop +EXPORT_SYMBOL_GPL vmlinux 0xd6c026d6 xenbus_dev_error +EXPORT_SYMBOL_GPL vmlinux 0xd6feefa5 agp_num_entries +EXPORT_SYMBOL_GPL vmlinux 0xd7207011 uhci_check_and_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0xd76c42a5 pci_find_ext_capability +EXPORT_SYMBOL_GPL vmlinux 0xd789ac1f blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0xd7b5a61e scsi_dh_detach +EXPORT_SYMBOL_GPL vmlinux 0xd7d79132 put_online_cpus +EXPORT_SYMBOL_GPL vmlinux 0xd81192d1 da903x_update +EXPORT_SYMBOL_GPL vmlinux 0xd82e0f23 pciserial_remove_ports +EXPORT_SYMBOL_GPL vmlinux 0xd830b79f sysfs_create_group +EXPORT_SYMBOL_GPL vmlinux 0xd839375e tcp_init_congestion_ops +EXPORT_SYMBOL_GPL vmlinux 0xd84cd7f4 ata_timing_find_mode +EXPORT_SYMBOL_GPL vmlinux 0xd8d30719 xenbus_grant_ring +EXPORT_SYMBOL_GPL vmlinux 0xd8f554ad pci_disable_pcie_error_reporting +EXPORT_SYMBOL_GPL vmlinux 0xd9042fa8 scatterwalk_map +EXPORT_SYMBOL_GPL vmlinux 0xd95f1389 inet6_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0xd9e77cd4 ata_noop_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0xd9f3ff29 agp_add_bridge +EXPORT_SYMBOL_GPL vmlinux 0xda0b72bd regulator_bulk_disable +EXPORT_SYMBOL_GPL vmlinux 0xda29f8b0 wmi_set_block +EXPORT_SYMBOL_GPL vmlinux 0xda3f53a8 pciserial_resume_ports +EXPORT_SYMBOL_GPL vmlinux 0xda476b19 fb_deferred_io_fsync +EXPORT_SYMBOL_GPL vmlinux 0xda9495d9 ata_port_desc +EXPORT_SYMBOL_GPL vmlinux 0xdab1c10e init_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0xdad5c012 usb_ep0_reinit +EXPORT_SYMBOL_GPL vmlinux 0xdaf4dfb3 fb_mode_option +EXPORT_SYMBOL_GPL vmlinux 0xdb232c36 register_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0xdc1f8f2e register_timer_hook +EXPORT_SYMBOL_GPL vmlinux 0xdc5dfdc4 relay_file_operations +EXPORT_SYMBOL_GPL vmlinux 0xdc94bd29 xenbus_unmap_ring_vfree +EXPORT_SYMBOL_GPL vmlinux 0xdd19eb31 usb_put_dev +EXPORT_SYMBOL_GPL vmlinux 0xdd2f37c8 unregister_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0xdd45195a ata_base_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xdd5c4942 srcu_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0xdd8a6d24 acpi_get_hp_params_from_firmware +EXPORT_SYMBOL_GPL vmlinux 0xddae4360 usb_unpoison_urb +EXPORT_SYMBOL_GPL vmlinux 0xdde785f1 ata_pci_device_do_resume +EXPORT_SYMBOL_GPL vmlinux 0xde134c69 storage_usb_ids +EXPORT_SYMBOL_GPL vmlinux 0xde63aa9f scsi_mode_select +EXPORT_SYMBOL_GPL vmlinux 0xdec38cd4 transport_remove_device +EXPORT_SYMBOL_GPL vmlinux 0xdeca70c3 usb_hcd_resume_root_hub +EXPORT_SYMBOL_GPL vmlinux 0xdede6812 destroy_workqueue +EXPORT_SYMBOL_GPL vmlinux 0xdf2fa99d md_allow_write +EXPORT_SYMBOL_GPL vmlinux 0xdf3022b2 ata_sff_interrupt +EXPORT_SYMBOL_GPL vmlinux 0xdf3c19ec cn_add_callback +EXPORT_SYMBOL_GPL vmlinux 0xe04b2c82 inet_csk_listen_start +EXPORT_SYMBOL_GPL vmlinux 0xe089cfcc agp_memory_reserved +EXPORT_SYMBOL_GPL vmlinux 0xe0ab448b unregister_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0xe0ef923b led_trigger_set_default +EXPORT_SYMBOL_GPL vmlinux 0xe0fd3846 pci_create_slot +EXPORT_SYMBOL_GPL vmlinux 0xe1451295 dm_region_hash_destroy +EXPORT_SYMBOL_GPL vmlinux 0xe15e0574 scsi_nl_sock +EXPORT_SYMBOL_GPL vmlinux 0xe15e245b scsi_target_block +EXPORT_SYMBOL_GPL vmlinux 0xe193f9a5 xfrm_audit_policy_delete +EXPORT_SYMBOL_GPL vmlinux 0xe1a3f63d get_task_mm +EXPORT_SYMBOL_GPL vmlinux 0xe1ba34c0 __crypto_alloc_tfm +EXPORT_SYMBOL_GPL vmlinux 0xe1ea1e1e sata_std_hardreset +EXPORT_SYMBOL_GPL vmlinux 0xe2185511 ata_pci_sff_activate_host +EXPORT_SYMBOL_GPL vmlinux 0xe2437c3c tcp_unregister_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0xe24ff917 blocking_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0xe276e657 gpiochip_add +EXPORT_SYMBOL_GPL vmlinux 0xe295c0ff is_hpet_enabled +EXPORT_SYMBOL_GPL vmlinux 0xe2cc626b device_del +EXPORT_SYMBOL_GPL vmlinux 0xe2cd352e bus_sort_breadthfirst +EXPORT_SYMBOL_GPL vmlinux 0xe2deb514 ata_host_resume +EXPORT_SYMBOL_GPL vmlinux 0xe2ed12bf sata_scr_valid +EXPORT_SYMBOL_GPL vmlinux 0xe30c1c14 inotify_dentry_parent_queue_event +EXPORT_SYMBOL_GPL vmlinux 0xe31a1333 dm_rh_start_recovery +EXPORT_SYMBOL_GPL vmlinux 0xe325df3a scsi_internal_device_unblock +EXPORT_SYMBOL_GPL vmlinux 0xe339bc6c inotify_init_watch +EXPORT_SYMBOL_GPL vmlinux 0xe34358a0 spi_unregister_master +EXPORT_SYMBOL_GPL vmlinux 0xe39f7d37 skb_segment +EXPORT_SYMBOL_GPL vmlinux 0xe3b5f581 device_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xe3c771d3 crypto_givcipher_type +EXPORT_SYMBOL_GPL vmlinux 0xe3e69990 attribute_container_classdev_to_container +EXPORT_SYMBOL_GPL vmlinux 0xe3edf30b tty_prepare_flip_string_flags +EXPORT_SYMBOL_GPL vmlinux 0xe3feb972 pci_block_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0xe40c1aa9 free_vm_area +EXPORT_SYMBOL_GPL vmlinux 0xe42a11fe ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0xe45d412c regulator_set_mode +EXPORT_SYMBOL_GPL vmlinux 0xe46c5f15 relay_flush +EXPORT_SYMBOL_GPL vmlinux 0xe48d5eac acpi_ec_add_query_handler +EXPORT_SYMBOL_GPL vmlinux 0xe492360a da903x_clr_bits +EXPORT_SYMBOL_GPL vmlinux 0xe498ca38 scsi_register_device_handler +EXPORT_SYMBOL_GPL vmlinux 0xe49ff3b0 ata_wait_register +EXPORT_SYMBOL_GPL vmlinux 0xe4c65520 tcp_set_state +EXPORT_SYMBOL_GPL vmlinux 0xe513afc0 cache_k8_northbridges +EXPORT_SYMBOL_GPL vmlinux 0xe52c0d40 bus_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xe530071c pm_qos_remove_requirement +EXPORT_SYMBOL_GPL vmlinux 0xe56b2181 tcp_twsk_destructor +EXPORT_SYMBOL_GPL vmlinux 0xe57affff unregister_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0xe6024e4b set_cpus_allowed_ptr +EXPORT_SYMBOL_GPL vmlinux 0xe61a6d2f gpio_unexport +EXPORT_SYMBOL_GPL vmlinux 0xe640f211 hid_connect +EXPORT_SYMBOL_GPL vmlinux 0xe6488b47 cpufreq_notify_transition +EXPORT_SYMBOL_GPL vmlinux 0xe674a5cb srcu_read_lock +EXPORT_SYMBOL_GPL vmlinux 0xe67f6ede usb_find_interface +EXPORT_SYMBOL_GPL vmlinux 0xe68df6cd ata_common_sdev_attrs +EXPORT_SYMBOL_GPL vmlinux 0xe7169caf blkcipher_walk_virt_block +EXPORT_SYMBOL_GPL vmlinux 0xe75382b6 bus_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0xe75e4dad pciserial_suspend_ports +EXPORT_SYMBOL_GPL vmlinux 0xe7a7865a sdio_f0_readb +EXPORT_SYMBOL_GPL vmlinux 0xe7fa47ad srcu_read_unlock +EXPORT_SYMBOL_GPL vmlinux 0xe81af31a crypto_alg_sem +EXPORT_SYMBOL_GPL vmlinux 0xe81e4023 debugfs_create_x32 +EXPORT_SYMBOL_GPL vmlinux 0xe839a91e ata_acpi_gtm_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xe8448267 platform_get_resource_byname +EXPORT_SYMBOL_GPL vmlinux 0xe881eacc dm_send_uevents +EXPORT_SYMBOL_GPL vmlinux 0xe8b259b6 securityfs_remove +EXPORT_SYMBOL_GPL vmlinux 0xe8d004ce uart_set_options +EXPORT_SYMBOL_GPL vmlinux 0xe8e62adf seq_open_net +EXPORT_SYMBOL_GPL vmlinux 0xe8f9dfaf uv_cpu_to_blade +EXPORT_SYMBOL_GPL vmlinux 0xe91b66aa ata_sff_wait_ready +EXPORT_SYMBOL_GPL vmlinux 0xe93e49c3 devres_free +EXPORT_SYMBOL_GPL vmlinux 0xe957bd4e sdio_f0_writeb +EXPORT_SYMBOL_GPL vmlinux 0xe9587909 usb_unregister_notify +EXPORT_SYMBOL_GPL vmlinux 0xe9baec81 blk_end_request_callback +EXPORT_SYMBOL_GPL vmlinux 0xe9ce504f cpufreq_frequency_table_cpuinfo +EXPORT_SYMBOL_GPL vmlinux 0xe9d84865 sysfs_notify_dirent +EXPORT_SYMBOL_GPL vmlinux 0xe9de9970 usb_string +EXPORT_SYMBOL_GPL vmlinux 0xe9e3a809 ata_host_init +EXPORT_SYMBOL_GPL vmlinux 0xea065e01 task_handoff_unregister +EXPORT_SYMBOL_GPL vmlinux 0xea418e0f atapi_cmd_type +EXPORT_SYMBOL_GPL vmlinux 0xea7e21b9 sysdev_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xeae74760 scsi_nl_send_transport_msg +EXPORT_SYMBOL_GPL vmlinux 0xeb1c3908 page_cache_sync_readahead +EXPORT_SYMBOL_GPL vmlinux 0xeb55ca25 platform_device_put +EXPORT_SYMBOL_GPL vmlinux 0xec1b043e regulator_suspend_prepare +EXPORT_SYMBOL_GPL vmlinux 0xec207697 tcp_done +EXPORT_SYMBOL_GPL vmlinux 0xec46fd91 ata_dummy_port_info +EXPORT_SYMBOL_GPL vmlinux 0xecddb118 __create_workqueue_key +EXPORT_SYMBOL_GPL vmlinux 0xecde29bb pci_hp_change_slot_info +EXPORT_SYMBOL_GPL vmlinux 0xecdf6149 simple_attr_read +EXPORT_SYMBOL_GPL vmlinux 0xed0690a5 ehci_cf_port_reset_rwsem +EXPORT_SYMBOL_GPL vmlinux 0xed411831 dm_disk +EXPORT_SYMBOL_GPL vmlinux 0xed54d3c0 platform_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xeda9c35f apply_to_page_range +EXPORT_SYMBOL_GPL vmlinux 0xedbc6f67 gnttab_end_foreign_access +EXPORT_SYMBOL_GPL vmlinux 0xeddfea5d fb_deferred_io_init +EXPORT_SYMBOL_GPL vmlinux 0xedf15345 ata_host_start +EXPORT_SYMBOL_GPL vmlinux 0xee97d6b9 platform_bus +EXPORT_SYMBOL_GPL vmlinux 0xeea3f3f1 zap_vma_ptes +EXPORT_SYMBOL_GPL vmlinux 0xeec5e3fe __pneigh_lookup +EXPORT_SYMBOL_GPL vmlinux 0xef0dea14 vlan_dev_real_dev +EXPORT_SYMBOL_GPL vmlinux 0xef1e9ecc task_current_syscall +EXPORT_SYMBOL_GPL vmlinux 0xef6c3f70 round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xef819708 regulator_enable +EXPORT_SYMBOL_GPL vmlinux 0xef82ec92 rt_mutex_trylock +EXPORT_SYMBOL_GPL vmlinux 0xef9beca8 uv_region_size +EXPORT_SYMBOL_GPL vmlinux 0xefb538bb usb_deregister_device_driver +EXPORT_SYMBOL_GPL vmlinux 0xefbcb7f4 scsi_nl_add_driver +EXPORT_SYMBOL_GPL vmlinux 0xefff3857 usb_hcd_pci_resume +EXPORT_SYMBOL_GPL vmlinux 0xf03f7eb5 sata_scr_write_flush +EXPORT_SYMBOL_GPL vmlinux 0xf05f0cab xenbus_map_ring_valloc +EXPORT_SYMBOL_GPL vmlinux 0xf07828ca blk_rq_bytes +EXPORT_SYMBOL_GPL vmlinux 0xf1346c19 usb_get_current_frame_number +EXPORT_SYMBOL_GPL vmlinux 0xf135ec8f xfrm_output +EXPORT_SYMBOL_GPL vmlinux 0xf1615d3d dev_attr_unload_heads +EXPORT_SYMBOL_GPL vmlinux 0xf184d189 kernel_power_off +EXPORT_SYMBOL_GPL vmlinux 0xf18e0d8f sata_pmp_error_handler +EXPORT_SYMBOL_GPL vmlinux 0xf1a07f83 sdio_writeb +EXPORT_SYMBOL_GPL vmlinux 0xf1db8489 sdio_claim_irq +EXPORT_SYMBOL_GPL vmlinux 0xf1ec8137 crypto_register_alg +EXPORT_SYMBOL_GPL vmlinux 0xf2035627 inet6_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0xf20b9d09 relay_reset +EXPORT_SYMBOL_GPL vmlinux 0xf2855040 platform_get_irq_byname +EXPORT_SYMBOL_GPL vmlinux 0xf293c618 rtc_irq_set_state +EXPORT_SYMBOL_GPL vmlinux 0xf29c030c debugfs_create_symlink +EXPORT_SYMBOL_GPL vmlinux 0xf2db08c0 ata_sff_softreset +EXPORT_SYMBOL_GPL vmlinux 0xf2ed5ff6 queue_work +EXPORT_SYMBOL_GPL vmlinux 0xf2fca922 uart_parse_options +EXPORT_SYMBOL_GPL vmlinux 0xf30ff34a device_create_vargs +EXPORT_SYMBOL_GPL vmlinux 0xf383cbac class_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf3a6af55 register_jprobes +EXPORT_SYMBOL_GPL vmlinux 0xf3d5cc13 ata_timing_merge +EXPORT_SYMBOL_GPL vmlinux 0xf3e5db04 fib_rules_cleanup_ops +EXPORT_SYMBOL_GPL vmlinux 0xf4027ad9 pci_enable_pcie_error_reporting +EXPORT_SYMBOL_GPL vmlinux 0xf4466b0c tcp_slow_start +EXPORT_SYMBOL_GPL vmlinux 0xf4627be0 console_drivers +EXPORT_SYMBOL_GPL vmlinux 0xf47f81bd kernel_kobj +EXPORT_SYMBOL_GPL vmlinux 0xf48cc16b ata_sff_error_handler +EXPORT_SYMBOL_GPL vmlinux 0xf499fdb2 rcu_barrier_bh +EXPORT_SYMBOL_GPL vmlinux 0xf4aebdc3 xenbus_suspend +EXPORT_SYMBOL_GPL vmlinux 0xf4c787af sysfs_put +EXPORT_SYMBOL_GPL vmlinux 0xf50b106c rtc_irq_set_freq +EXPORT_SYMBOL_GPL vmlinux 0xf553318d cpuidle_pause_and_lock +EXPORT_SYMBOL_GPL vmlinux 0xf5945bac gnttab_free_grant_references +EXPORT_SYMBOL_GPL vmlinux 0xf5a691cd invalidate_bh_lrus +EXPORT_SYMBOL_GPL vmlinux 0xf5c3b0ef agp_remove_bridge +EXPORT_SYMBOL_GPL vmlinux 0xf610cd65 raw_hash_sk +EXPORT_SYMBOL_GPL vmlinux 0xf659b41c sdio_align_size +EXPORT_SYMBOL_GPL vmlinux 0xf6ab3971 rtc_set_alarm +EXPORT_SYMBOL_GPL vmlinux 0xf6bcbd73 hwrng_register +EXPORT_SYMBOL_GPL vmlinux 0xf7016530 xenbus_gather +EXPORT_SYMBOL_GPL vmlinux 0xf7199eff ip_build_and_send_pkt +EXPORT_SYMBOL_GPL vmlinux 0xf73e8612 swiotlb_sync_single_range_for_cpu +EXPORT_SYMBOL_GPL vmlinux 0xf7427c4c register_jprobe +EXPORT_SYMBOL_GPL vmlinux 0xf7632ec8 xenbus_dev_fatal +EXPORT_SYMBOL_GPL vmlinux 0xf776f5a9 sysfs_remove_file_from_group +EXPORT_SYMBOL_GPL vmlinux 0xf7b1535a hvc_poll +EXPORT_SYMBOL_GPL vmlinux 0xf7b1d85b hid_output_report +EXPORT_SYMBOL_GPL vmlinux 0xf7cd966e sysdev_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf7d34928 bus_get_device_klist +EXPORT_SYMBOL_GPL vmlinux 0xf835e1ab invalidate_inode_pages2_range +EXPORT_SYMBOL_GPL vmlinux 0xf8802492 print_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0xf8cd4b63 sg_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xf8f3a0fb ata_ratelimit +EXPORT_SYMBOL_GPL vmlinux 0xf94fd2a8 blkcipher_walk_virt +EXPORT_SYMBOL_GPL vmlinux 0xf972e196 rfkill_restore_states +EXPORT_SYMBOL_GPL vmlinux 0xf97666a0 set_memory_rw +EXPORT_SYMBOL_GPL vmlinux 0xf97c8283 mmu_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0xf9a054b5 __round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0xf9ca3160 ata_id_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xf9df7149 skcipher_geniv_free +EXPORT_SYMBOL_GPL vmlinux 0xfa1f4662 scatterwalk_start +EXPORT_SYMBOL_GPL vmlinux 0xfa45d31c driver_add_kobj +EXPORT_SYMBOL_GPL vmlinux 0xfa731410 cpufreq_register_governor +EXPORT_SYMBOL_GPL vmlinux 0xfa91c434 tty_ldisc_ref +EXPORT_SYMBOL_GPL vmlinux 0xfac267a6 xenbus_free_evtchn +EXPORT_SYMBOL_GPL vmlinux 0xfb0aabb1 ata_sas_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0xfb77a706 blkcipher_walk_phys +EXPORT_SYMBOL_GPL vmlinux 0xfb882fb7 wmi_query_block +EXPORT_SYMBOL_GPL vmlinux 0xfb8bab74 ata_scsi_simulate +EXPORT_SYMBOL_GPL vmlinux 0xfba2097b cpci_hp_register_controller +EXPORT_SYMBOL_GPL vmlinux 0xfbc016de blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xfbf9be5d register_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xfc0509d8 scsi_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0xfc16ffdc hid_set_field +EXPORT_SYMBOL_GPL vmlinux 0xfc2ff860 uv_setup_irq +EXPORT_SYMBOL_GPL vmlinux 0xfc73253e crypto_drop_spawn +EXPORT_SYMBOL_GPL vmlinux 0xfcaf4b91 device_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xfcce694c rfkill_set_default +EXPORT_SYMBOL_GPL vmlinux 0xfcd05cb5 inet_csk_compat_getsockopt +EXPORT_SYMBOL_GPL vmlinux 0xfd250c2c relay_open +EXPORT_SYMBOL_GPL vmlinux 0xfd51b281 gnttab_end_foreign_access_ref +EXPORT_SYMBOL_GPL vmlinux 0xfd59ace8 gpiochip_remove +EXPORT_SYMBOL_GPL vmlinux 0xfd6ed1de usb_hcd_platform_shutdown +EXPORT_SYMBOL_GPL vmlinux 0xfd798df4 usb_put_intf +EXPORT_SYMBOL_GPL vmlinux 0xfd90fb09 sdev_evt_send +EXPORT_SYMBOL_GPL vmlinux 0xfd9da487 relay_subbufs_consumed +EXPORT_SYMBOL_GPL vmlinux 0xfde0b92c crypto_larval_error +EXPORT_SYMBOL_GPL vmlinux 0xfe0c6852 raw_seq_start +EXPORT_SYMBOL_GPL vmlinux 0xfe3c161d tty_mode_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xfe727411 get_phys_to_machine +EXPORT_SYMBOL_GPL vmlinux 0xfe7aa5e3 crypto_alloc_instance +EXPORT_SYMBOL_GPL vmlinux 0xfe922be7 audit_log_d_path +EXPORT_SYMBOL_GPL vmlinux 0xfe9407fa debugfs_create_blob +EXPORT_SYMBOL_GPL vmlinux 0xfe990052 gpio_free +EXPORT_SYMBOL_GPL vmlinux 0xfecbff96 __mark_empty_function +EXPORT_SYMBOL_GPL vmlinux 0xfed11ed1 usb_mon_deregister +EXPORT_SYMBOL_GPL vmlinux 0xfefee878 driver_register +EXPORT_SYMBOL_GPL vmlinux 0xff103202 blk_queue_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0xff5a8cfe cn_del_callback +EXPORT_SYMBOL_GPL vmlinux 0xffc14f34 blkcipher_walk_done +EXPORT_SYMBOL_GPL vmlinux 0xffce06b2 fb_bl_default_curve +EXPORT_SYMBOL_GPL vmlinux 0xffcf35e1 usb_root_hub_lost_power +EXPORT_UNUSED_SYMBOL vmlinux 0x00000000 init_mm +EXPORT_UNUSED_SYMBOL vmlinux 0x00000000 simple_prepare_write --- linux-2.6.28.orig/debian/abi/2.6.28-11.41/amd64/server +++ linux-2.6.28/debian/abi/2.6.28-11.41/amd64/server @@ -0,0 +1,8601 @@ +EXPORT_SYMBOL arch/x86/kvm/kvm 0x90720858 kvm_cpu_has_pending_timer +EXPORT_SYMBOL arch/x86/kvm/kvm 0xb33feb4e kvm_read_guest_atomic +EXPORT_SYMBOL crypto/gf128mul 0x0c2f123f gf128mul_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x1068004b gf128mul_bbe +EXPORT_SYMBOL crypto/gf128mul 0x2f2889a0 gf128mul_init_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0x3755f990 gf128mul_init_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x384ef9ce gf128mul_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x56af0dbd gf128mul_x_ble +EXPORT_SYMBOL crypto/gf128mul 0x83581089 gf128mul_init_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0x9b2560b9 gf128mul_init_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x9e13f6f6 gf128mul_lle +EXPORT_SYMBOL crypto/gf128mul 0xbd17a0df gf128mul_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0xc0890413 gf128mul_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0xd60736ec gf128mul_free_64k +EXPORT_SYMBOL crypto/xor 0x5b6c00e6 xor_blocks +EXPORT_SYMBOL drivers/atm/suni 0x18efa936 suni_init +EXPORT_SYMBOL drivers/atm/uPD98402 0x82c7ac20 uPD98402_init +EXPORT_SYMBOL drivers/block/paride/paride 0x07687c98 pi_write_block +EXPORT_SYMBOL drivers/block/paride/paride 0x1042a2fe pi_do_claimed +EXPORT_SYMBOL drivers/block/paride/paride 0x1843deb9 pi_schedule_claimed +EXPORT_SYMBOL drivers/block/paride/paride 0x1988eb9f pi_write_regr +EXPORT_SYMBOL drivers/block/paride/paride 0x35219630 pi_read_block +EXPORT_SYMBOL drivers/block/paride/paride 0x7b08bf80 pi_init +EXPORT_SYMBOL drivers/block/paride/paride 0x8cf8cdf3 pi_connect +EXPORT_SYMBOL drivers/block/paride/paride 0x98c9e523 pi_disconnect +EXPORT_SYMBOL drivers/block/paride/paride 0xa3484fb8 paride_register +EXPORT_SYMBOL drivers/block/paride/paride 0xe4ec774f pi_release +EXPORT_SYMBOL drivers/block/paride/paride 0xef27aec2 paride_unregister +EXPORT_SYMBOL drivers/block/paride/paride 0xf78f1fc7 pi_read_regr +EXPORT_SYMBOL drivers/char/generic_serial 0x03e1be18 gs_chars_in_buffer +EXPORT_SYMBOL drivers/char/generic_serial 0x0cc217e7 gs_stop +EXPORT_SYMBOL drivers/char/generic_serial 0x310ddf5c gs_hangup +EXPORT_SYMBOL drivers/char/generic_serial 0x39d20150 gs_block_til_ready +EXPORT_SYMBOL drivers/char/generic_serial 0x4980713e gs_got_break +EXPORT_SYMBOL drivers/char/generic_serial 0x5720b672 gs_write_room +EXPORT_SYMBOL drivers/char/generic_serial 0x661f5c05 gs_close +EXPORT_SYMBOL drivers/char/generic_serial 0x6983cac3 gs_start +EXPORT_SYMBOL drivers/char/generic_serial 0x69fb7c1a gs_setserial +EXPORT_SYMBOL drivers/char/generic_serial 0x74d5ff94 gs_getserial +EXPORT_SYMBOL drivers/char/generic_serial 0x7f4392ba gs_set_termios +EXPORT_SYMBOL drivers/char/generic_serial 0x82b82e17 gs_init_port +EXPORT_SYMBOL drivers/char/generic_serial 0xa1f9adb9 gs_write +EXPORT_SYMBOL drivers/char/generic_serial 0xbe2c5129 gs_flush_buffer +EXPORT_SYMBOL drivers/char/generic_serial 0xf1121e1e gs_flush_chars +EXPORT_SYMBOL drivers/char/generic_serial 0xf35f44d0 gs_put_char +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x00e3d608 ipmi_smi_watcher_register +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x05644e9b ipmi_request_supply_msgs +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x160ba3ad ipmi_get_my_address +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x183689ff ipmi_smi_add_proc_entry +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x1a11a4e9 ipmi_unregister_smi +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x1e815137 ipmi_set_gets_events +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x2f8cb466 ipmi_poll_interface +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x40f2b10c ipmi_alloc_smi_msg +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x451c65d6 ipmi_free_recv_msg +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x61c17a25 ipmi_smi_watchdog_pretimeout +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x68bc907a ipmi_smi_msg_received +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x6cc7d91a ipmi_register_for_cmd +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x804f922a ipmi_addr_length +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x90dfe8fe ipmi_destroy_user +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xa19db7bd ipmi_set_maintenance_mode +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xa780cdda ipmi_smi_watcher_unregister +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xa9eb893d ipmi_request_settime +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xaac23f42 ipmi_set_my_address +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xaf38e552 ipmi_get_maintenance_mode +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xb4ca1b06 ipmi_unregister_for_cmd +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xbb540354 ipmi_get_my_LUN +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xc96ce9fd ipmi_register_smi +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xd45ac495 ipmi_get_version +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xe4f4665b ipmi_validate_addr +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xf2b79bae ipmi_create_user +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xf7010caa ipmi_set_my_LUN +EXPORT_SYMBOL drivers/char/nsc_gpio 0xa693b704 nsc_gpio_read +EXPORT_SYMBOL drivers/char/nsc_gpio 0xb1b1f859 nsc_gpio_dump +EXPORT_SYMBOL drivers/char/nsc_gpio 0xcabf9062 nsc_gpio_write +EXPORT_SYMBOL drivers/char/nvram 0x0f28cb91 nvram_read_byte +EXPORT_SYMBOL drivers/char/nvram 0x17ff2c1d __nvram_read_byte +EXPORT_SYMBOL drivers/char/nvram 0x2adec1e0 __nvram_check_checksum +EXPORT_SYMBOL drivers/char/nvram 0x7da28f12 nvram_check_checksum +EXPORT_SYMBOL drivers/char/nvram 0x9ce3f83f nvram_write_byte +EXPORT_SYMBOL drivers/char/nvram 0xa8813189 __nvram_write_byte +EXPORT_SYMBOL drivers/edac/edac_core 0x359a0024 edac_mc_handle_fbd_ce +EXPORT_SYMBOL drivers/edac/edac_core 0xaae260de edac_mc_handle_fbd_ue +EXPORT_SYMBOL drivers/edac/edac_core 0xf62038d0 edac_mc_find +EXPORT_SYMBOL drivers/firewire/firewire-core 0x117749d0 fw_fill_response +EXPORT_SYMBOL drivers/firewire/firewire-core 0x143eff32 fw_core_add_address_handler +EXPORT_SYMBOL drivers/firewire/firewire-core 0x1c0bbf77 fw_core_handle_bus_reset +EXPORT_SYMBOL drivers/firewire/firewire-core 0x1fa6db83 fw_send_request +EXPORT_SYMBOL drivers/firewire/firewire-core 0x39c3b606 fw_device_enable_phys_dma +EXPORT_SYMBOL drivers/firewire/firewire-core 0x410178d7 fw_core_handle_request +EXPORT_SYMBOL drivers/firewire/firewire-core 0x75fe59af fw_cancel_transaction +EXPORT_SYMBOL drivers/firewire/firewire-core 0x7c76bfe4 fw_card_initialize +EXPORT_SYMBOL drivers/firewire/firewire-core 0x7c9c0f74 fw_run_transaction +EXPORT_SYMBOL drivers/firewire/firewire-core 0x842dbe57 fw_card_add +EXPORT_SYMBOL drivers/firewire/firewire-core 0x90863005 fw_high_memory_region +EXPORT_SYMBOL drivers/firewire/firewire-core 0x9afe8043 fw_core_initiate_bus_reset +EXPORT_SYMBOL drivers/firewire/firewire-core 0xa2fda37b fw_core_handle_response +EXPORT_SYMBOL drivers/firewire/firewire-core 0xafc1c793 fw_csr_iterator_next +EXPORT_SYMBOL drivers/firewire/firewire-core 0xb047a2c6 fw_csr_iterator_init +EXPORT_SYMBOL drivers/firewire/firewire-core 0xb61de976 fw_core_remove_card +EXPORT_SYMBOL drivers/firewire/firewire-core 0xca9550db fw_bus_type +EXPORT_SYMBOL drivers/firewire/firewire-core 0xcd704cb0 fw_send_response +EXPORT_SYMBOL drivers/firewire/firewire-core 0xfc33f0cf fw_core_remove_address_handler +EXPORT_SYMBOL drivers/gpu/drm/drm 0x024ba16b drm_agp_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0x031a52a0 drm_gem_handle_create +EXPORT_SYMBOL drivers/gpu/drm/drm 0x082b0ed8 drm_vblank_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x0836695c drm_sman_takedown +EXPORT_SYMBOL drivers/gpu/drm/drm 0x0abd128b drm_agp_bind_pages +EXPORT_SYMBOL drivers/gpu/drm/drm 0x12cfe7e5 drm_get_resource_len +EXPORT_SYMBOL drivers/gpu/drm/drm 0x13dccda7 drm_pci_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x148e1e3a drm_mm_search_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x15881121 drm_agp_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x1bba7733 drm_core_ioremapfree +EXPORT_SYMBOL drivers/gpu/drm/drm 0x20645642 drm_debug +EXPORT_SYMBOL drivers/gpu/drm/drm 0x21451ac4 drm_sman_owner_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x25e9275c drm_clflush_pages +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2916bf63 drm_sman_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2ddc140e drm_exit +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2eb2f903 drm_sman_free_key +EXPORT_SYMBOL drivers/gpu/drm/drm 0x3074f033 drm_order +EXPORT_SYMBOL drivers/gpu/drm/drm 0x34ebade3 drm_idlelock_take +EXPORT_SYMBOL drivers/gpu/drm/drm 0x3b663c29 drm_agp_acquire +EXPORT_SYMBOL drivers/gpu/drm/drm 0x3c389847 drm_ati_pcigart_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x40ce71c5 drm_ioctl +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4759ad01 drm_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4a26d8c0 drm_fasync +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4b8082b9 drm_mm_put_block +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4d2d93e7 drm_core_get_reg_ofs +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4ea1f5a2 drm_gem_object_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4fc2bb7f drm_handle_vblank +EXPORT_SYMBOL drivers/gpu/drm/drm 0x523f0ea4 drm_free_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0x5571b9c8 drm_core_ioremap +EXPORT_SYMBOL drivers/gpu/drm/drm 0x558c5358 drm_compat_ioctl +EXPORT_SYMBOL drivers/gpu/drm/drm 0x55f060ee drm_sman_set_range +EXPORT_SYMBOL drivers/gpu/drm/drm 0x5976a266 drm_addbufs_pci +EXPORT_SYMBOL drivers/gpu/drm/drm 0x5b7fc24a drm_agp_info +EXPORT_SYMBOL drivers/gpu/drm/drm 0x5c471c35 drm_poll +EXPORT_SYMBOL drivers/gpu/drm/drm 0x60398ee6 drm_getsarea +EXPORT_SYMBOL drivers/gpu/drm/drm 0x6315554c drm_addmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0x6370b050 drm_mm_get_block +EXPORT_SYMBOL drivers/gpu/drm/drm 0x64fd01bc drm_agp_unbind +EXPORT_SYMBOL drivers/gpu/drm/drm 0x6c18f9af drm_gem_object_lookup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x7b0038f2 drm_addbufs_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0x7b5bbf08 drm_i_have_hw_lock +EXPORT_SYMBOL drivers/gpu/drm/drm 0x80898037 drm_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x8873dc30 drm_mm_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x8c7f6ebc drm_vblank_put +EXPORT_SYMBOL drivers/gpu/drm/drm 0x9731da87 drm_irq_install +EXPORT_SYMBOL drivers/gpu/drm/drm 0x983ebc1d drm_core_ioremap_wc +EXPORT_SYMBOL drivers/gpu/drm/drm 0x9c25b192 drm_core_get_map_ofs +EXPORT_SYMBOL drivers/gpu/drm/drm 0xa2542dd5 drm_unbind_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0xa2f4f02a drm_core_reclaim_buffers +EXPORT_SYMBOL drivers/gpu/drm/drm 0xa504bbb3 drm_agp_enable +EXPORT_SYMBOL drivers/gpu/drm/drm 0xa949cadc drm_agp_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0xaaa3a0b3 drm_vblank_get +EXPORT_SYMBOL drivers/gpu/drm/drm 0xaf29788e drm_sman_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0xb88ed451 drm_gem_object_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0xb9e015eb drm_lock_take +EXPORT_SYMBOL drivers/gpu/drm/drm 0xbc29bde9 drm_mmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0xbd68627a drm_pci_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0xc080eb9b drm_gem_object_handle_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0xcc332edb drm_open +EXPORT_SYMBOL drivers/gpu/drm/drm 0xcdde8349 drm_get_resource_start +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd3028e75 drm_sman_set_manager +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd5390b28 drm_ati_pcigart_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0xda43786d drm_rmmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0xdee80769 drm_lock_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe6d38ebd drm_sg_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe76bce2f drm_agp_bind +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe80a5254 drm_irq_uninstall +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe919dd5c drm_sman_owner_clean +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe9204a10 drm_agp_chipset_flush +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe974d945 drm_vblank_count +EXPORT_SYMBOL drivers/gpu/drm/drm 0xeae40686 drm_get_drawable_info +EXPORT_SYMBOL drivers/gpu/drm/drm 0xf3e2e73d drm_idlelock_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0xfdfbad19 drm_sman_alloc +EXPORT_SYMBOL drivers/hwmon/hwmon-vid 0x0903c239 vid_from_reg +EXPORT_SYMBOL drivers/hwmon/hwmon-vid 0xef1c781c vid_which_vrm +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0x11a5b304 i2c_bit_add_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0x44845cc7 i2c_bit_add_numbered_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pca 0x507de99f i2c_pca_add_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pca 0x948afbc1 i2c_pca_add_numbered_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pcf 0x12a90cbf i2c_pcf_add_bus +EXPORT_SYMBOL drivers/i2c/busses/i2c-amd756 0x401f64df amd756_smbus +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x02d4ad0f tps65013_set_low_pwr +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x28485130 tps65010_config_vregs1 +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x33739de7 tps65010_set_vib +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x9fd44c69 tps65010_set_led +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0xb14080cc tps65010_set_low_pwr +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0xd5bb106d tps65010_set_vbus_draw +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0xe99b3f36 tps65010_set_gpio_out_value +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0064463e hpsb_read +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x01ba41d4 hpsb_get_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x02e2a0a0 hpsb_iso_recv_set_channel_mask +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x03a5b3fe hpsb_make_phypacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x05a70ba0 hpsb_packet_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0ab3a14d hpsb_iso_xmit_sync +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0b234c4e dma_prog_region_alloc +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0bd42c31 hpsb_iso_recv_start +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0c6da941 csr1212_release_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0e5a659c csr1212_new_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x13b4a268 csr1212_attach_keyval_to_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x158ac548 dma_region_offset_to_bus +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x19f1f97b csr1212_parse_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x204f5bf1 hpsb_iso_stop +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x20f8a34a hpsb_iso_xmit_queue_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x289a8231 hpsb_free_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2cb1b63f hpsb_iso_recv_listen_channel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2dd29f75 csr1212_read +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2e22e7ae hpsb_iso_n_ready +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2e7a5592 hpsb_packet_success +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2ebf6e5a dma_prog_region_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x3414a7fd hpsb_set_hostinfo_key +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x3450c68c hpsb_get_hostinfo_bykey +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x3ca6ed90 dma_region_mmap +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x4f81f0e9 hpsb_resume_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x52e6baf9 hpsb_make_writepacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x5898d2c8 hpsb_iso_recv_unlisten_channel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x5cbbbfe9 hpsb_reset_bus +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6269a311 hpsb_send_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6507e273 hpsb_alloc_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x66d9b139 hpsb_iso_shutdown +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x672ad148 dma_region_sync_for_device +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x68d91355 hpsb_iso_recv_release_packets +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x68e97456 hpsb_allocate_and_register_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6bb19117 __hpsb_register_protocol +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6f3aaf0c hpsb_unregister_protocol +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x713446e4 hpsb_node_fill_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x74087985 hpsb_set_packet_complete_task +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x76bc1a5c dma_region_free +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x76e8837f hpsb_bus_reset +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x79530b08 csr1212_get_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x80364b20 hpsb_make_readpacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8255db23 hpsb_create_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x85900442 hpsb_set_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8826fc79 hpsb_read_cycle_timer +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8879f8f0 dma_region_sync_for_cpu +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x88e140f7 hpsb_update_config_rom +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8ec2b312 dma_region_alloc +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x963a5e25 hpsb_make_lock64packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x9cc83242 hpsb_make_streampacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x9db79966 hpsb_update_config_rom_image +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xa616000b hpsb_alloc_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xa63b98ed hpsb_free_tlabel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xadbeb3b9 hpsb_get_tlabel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb61ad687 hpsb_unregister_highlevel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb837e769 hpsb_iso_recv_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xbaf04652 hpsb_iso_recv_flush +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xbbb693e2 hpsb_register_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc669a4d3 csr1212_detach_keyval_from_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc7e15c34 hpsb_packet_sent +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xcb67fdb3 hpsb_protocol_class +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xcd9e772b dma_prog_region_free +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xcfe3c87b hpsb_iso_xmit_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xd5d09d8f hpsb_register_highlevel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xd62c34d1 hpsb_write +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xda9537a9 hpsb_selfid_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xddc06a09 hpsb_selfid_complete +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xdf6b49ba hpsb_iso_wake +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xdfb00ad3 hpsb_add_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xe1319b73 hpsb_make_lockpacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xea4152ff dma_region_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xeaae7724 hpsb_iso_packet_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xeb85a4b8 hpsb_iso_xmit_start +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xeeb2c108 hpsb_remove_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xf173d60b hpsb_iso_packet_sent +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xf3a77346 hpsb_destroy_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xf4b071bd hpsb_unregister_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfba57f51 hpsb_speedto_str +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfc7562c9 hpsb_node_write +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0x12ba900a ohci1394_register_iso_tasklet +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0xb37ab086 ohci1394_init_iso_tasklet +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0xcd2e9d92 ohci1394_unregister_iso_tasklet +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0xea3d9493 ohci1394_stop_context +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x00f858b0 rdma_addr_cancel +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x71de06c2 rdma_addr_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x9067537c rdma_resolve_ip +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0xbe81bb46 rdma_addr_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0xdfc742a2 rdma_translate_ip +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0xfd3269b2 rdma_copy_addr +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x031df8c1 cm_class +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x1444b68f ib_create_cm_id +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x2fbb509f ib_send_cm_lap +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x3165e06b ib_send_cm_mra +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x3f44b773 ib_destroy_cm_id +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x42384d07 ib_cm_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x464fc19b ib_send_cm_rej +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x4d14d7f9 ib_send_cm_apr +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x6274fe02 ib_send_cm_drep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x8127f928 ib_send_cm_rtu +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x86386492 ib_send_cm_sidr_rep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xae046706 ib_send_cm_dreq +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xae171789 ib_send_cm_req +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xb690accc ib_cm_listen +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xe7bf60ed ib_cm_notify +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xf034a002 ib_send_cm_rep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xfe9257b2 ib_send_cm_sidr_req +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x000ad6aa ib_query_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x06830b9a ib_pack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x073373bf ib_create_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x0ae1742e ib_get_cached_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x0fc7f5cf ib_find_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x14fb18a7 ib_query_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x17f563c9 ib_alloc_pd +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x185953ef ib_create_ah_from_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x19de8c51 ib_get_dma_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x1ade0b3c ib_detach_mcast +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x1e491a04 ib_unmap_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x2ae082f0 ib_query_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x2d284e61 ib_unregister_event_handler +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x2f0db218 ib_query_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x304535a0 ib_free_fast_reg_page_list +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x350f6ca4 ib_destroy_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3e7bd1ad ib_dereg_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3f7567fd ib_rate_to_mult +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x440a5411 ib_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x48b59153 ib_dealloc_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x521e828b ib_query_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x522c10ed ib_fmr_pool_unmap +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x523def05 ib_find_cached_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x60d28f08 ib_fmr_pool_map_phys +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x62000940 ib_modify_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x6518539b ib_set_client_data +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x71199f76 ib_alloc_fast_reg_page_list +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x7235cc54 ib_query_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x77f52ce7 ib_dispatch_event +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x78025171 ib_unregister_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x816eeafb ib_rereg_phys_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x85144001 ib_alloc_fast_reg_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8640eaeb ib_modify_qp_is_ok +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x87b614d8 ib_ud_header_pack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x883f5bc5 ib_umem_get +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8a5c35ff ib_get_client_data +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8c8489de ib_flush_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8d97ce82 ib_find_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x90aa1213 ib_resize_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x968d4200 ib_alloc_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x96ce6c46 rdma_node_get_transport +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x980b1149 ib_modify_port +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x99cb120c ib_dealloc_mw +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9a23c171 ib_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9d5a599b ib_destroy_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9d69bca7 ib_create_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9d804fa1 mult_to_ib_rate +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9def2f32 ib_modify_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa33390c8 ib_create_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa4c3cf05 ib_umem_release +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa83c316f ib_find_cached_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xaf2e3edb ib_modify_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb1216612 ib_alloc_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb617feab ib_dealloc_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb66fd438 ib_attach_mcast +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xbd9cd88a ib_get_cached_lmc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xbe5782b4 ib_query_port +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xbf77693f ib_create_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xc0ae909e ib_destroy_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xc3cff0d9 ib_modify_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xc723dd4e ib_destroy_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xcf7b8dec ib_alloc_mw +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd17ba9d1 ib_ud_header_init +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd639288d ib_umem_page_count +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd78660f9 ib_init_ah_from_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xdc598cc9 ib_reg_phys_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xde01606d ib_destroy_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xeccda842 ib_register_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xed26e1df ib_modify_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xefa569cf ib_dealloc_pd +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf04608a5 ib_query_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf0ee3787 ib_get_cached_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf260cef4 ib_register_event_handler +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf36498b9 ib_ud_header_unpack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf45c0c5c ib_create_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf96fc9de ib_unpack +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x1169e3c7 ib_cancel_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x4a40d5b9 ib_process_mad_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x587b39b7 ib_redirect_mad_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6246f687 ib_post_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x63882290 ib_get_rmpp_segment +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6cdd8d85 ib_register_mad_snoop +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6ef787ed ib_response_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6f077fcf ib_get_mad_data_offset +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x7b5d4b7a ib_is_mad_class_rmpp +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x838c907e ib_create_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xa93cbb1d ib_modify_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xb03a52cd ib_free_recv_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xcf13b864 ib_free_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xe9284e33 ib_register_mad_agent +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xeabdbb12 ib_unregister_mad_agent +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x0bc535c5 ib_sa_service_rec_query +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x0f9b7f47 ib_init_ah_from_mcmember +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x16199856 ib_sa_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x512ba124 ib_sa_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x576fdbac ib_sa_free_multicast +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x9a0f35d3 ib_sa_cancel_query +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xe3358228 ib_sa_get_mcmember_rec +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xe7a48ed8 ib_init_ah_from_path +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xf13c75bf ib_sa_join_multicast +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xfe7ea33e ib_sa_path_rec_get +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x02f847bc ib_copy_path_rec_from_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x07cf5a51 ib_copy_ah_attr_to_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x18382f6a ib_copy_path_rec_to_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x184f3575 ib_copy_qp_attr_to_user +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x0495aadc iw_cm_accept +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x2595c1d1 iw_cm_listen +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x2febc857 iw_create_cm_id +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x3ed51dae iw_destroy_cm_id +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x44f55151 iw_cm_disconnect +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xabf3371a iw_cm_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xce0002e0 iw_cm_reject +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xdb4af68f iw_cm_connect +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x15e1f915 rdma_resolve_addr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x4af8b7b9 rdma_create_id +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x529dbb8a rdma_connect +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x5e701ef4 rdma_destroy_id +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x6179eca1 rdma_disconnect +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x8904d358 rdma_join_multicast +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x8d39ec55 rdma_accept +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x8e2a22e5 rdma_resolve_route +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x90dda189 rdma_notify +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x96b37df5 rdma_reject +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x972bb993 rdma_listen +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x9fa4599c rdma_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xae046c89 rdma_set_service_type +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xca9e5aad rdma_set_ib_paths +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xd7427b17 rdma_bind_addr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xd7f9f3a5 rdma_create_qp +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xd86d264e rdma_destroy_qp +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xf81e66fd rdma_leave_multicast +EXPORT_SYMBOL drivers/input/gameport/gameport 0x276e1ec4 gameport_start_polling +EXPORT_SYMBOL drivers/input/gameport/gameport 0x43f704b3 __gameport_register_driver +EXPORT_SYMBOL drivers/input/gameport/gameport 0x78e8546b gameport_close +EXPORT_SYMBOL drivers/input/gameport/gameport 0x7a6ca563 gameport_unregister_driver +EXPORT_SYMBOL drivers/input/gameport/gameport 0xa2f195eb __gameport_register_port +EXPORT_SYMBOL drivers/input/gameport/gameport 0xa5a5bfdd gameport_unregister_port +EXPORT_SYMBOL drivers/input/gameport/gameport 0xc9cfda3d gameport_open +EXPORT_SYMBOL drivers/input/gameport/gameport 0xf173fbea gameport_set_phys +EXPORT_SYMBOL drivers/input/gameport/gameport 0xfa5885cb gameport_stop_polling +EXPORT_SYMBOL drivers/input/input-polldev 0x4955fcda input_allocate_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0x5e6012b9 input_register_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0x82aaa2dc input_unregister_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0xdda5e358 input_free_polled_device +EXPORT_SYMBOL drivers/isdn/capi/capifs 0x2c54c957 capifs_free_ncci +EXPORT_SYMBOL drivers/isdn/capi/capifs 0xd0bc06ce capifs_new_ncci +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x04403fcf unregister_capi_driver +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x0f72c34b capi_ctr_reseted +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x14f2aa5a capi20_get_version +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x2b8eab1f capilib_free_ncci +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x2baa6586 capilib_new_ncci +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x31c24aa4 capi20_isinstalled +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x47d3fc51 capi_info2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x47dbfa0a capi_message2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x50b33ca4 capi_cmsg2message +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x56d99518 capi20_set_callback +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x6057c6f3 capi_message2cmsg +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x62e32d43 capilib_data_b3_conf +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x69ab56cd capi_ctr_suspend_output +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x6dc6af0f capi_ctr_resume_output +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x71e8d5ba capilib_data_b3_req +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x77d8de5d capi_ctr_handle_message +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x788d398c capi_cmsg2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x7a33596c capi20_get_serial +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x7e6f1307 capi20_get_manufacturer +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x85e2a499 detach_capi_ctr +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x8f699913 capilib_release +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x8f71ada9 capi20_release +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x9f823278 register_capi_driver +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xaa165d27 capilib_release_appl +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xac47e751 attach_capi_ctr +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xada5fb07 capi20_put_message +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xb19fda8d capi_cmd2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xb60e5e5f capi_cmsg_header +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xc5327ee3 capi20_register +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xd63026bc capi_ctr_ready +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xe19a11ac capi20_get_profile +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xe9f62f29 cdebbuf_free +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xed061606 capi20_manufacturer +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x0d2961f0 b1_release_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x2af765b8 b1_register_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x36fa8c3d b1_parse_version +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x4c005457 b1_send_message +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x4f045313 b1_alloc_card +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x708ff839 b1_reset_ctr +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x722b6224 avmcard_dma_alloc +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x7c956a55 b1_getrevision +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x7d75d9b1 b1_load_firmware +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x85f09690 b1_irq_table +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x96f9d2f4 b1_interrupt +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xbaf35b3f b1_load_t4file +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xc59849fd avmcard_dma_free +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xcbe049fe b1_free_card +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xd41b0f28 b1ctl_read_proc +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xdaa1ecee b1_load_config +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xdfd28376 b1_detect +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xeff549da b1_loaded +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x0fd2150e b1dma_send_message +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x2a386384 b1dma_interrupt +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x67fd146d b1dmactl_read_proc +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x845015ca b1dma_register_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x8d1a7c2e b1dma_release_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x96c8b53f b1dma_reset_ctr +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x9d8ebe28 b1dma_reset +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0xce86502c b1pciv4_detect +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0xdcf1483f t1pci_detect +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0xfc767683 b1dma_load_firmware +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0x29562993 b1pcmcia_delcard +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0xaec3240e b1pcmcia_addcard_m1 +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0xea620116 b1pcmcia_addcard_m2 +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0xf14bf8b1 b1pcmcia_addcard_b1 +EXPORT_SYMBOL drivers/isdn/hardware/eicon/divadidd 0x2974ead1 DIVA_DIDD_Read +EXPORT_SYMBOL drivers/isdn/hardware/eicon/divadidd 0x334e8477 proc_net_eicon +EXPORT_SYMBOL drivers/isdn/hardware/mISDN/hfcmulti 0x5293ed86 plx_lock +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x07f4f2ce hisax_unregister +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x148f0c99 FsmFree +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x2844a899 FsmInitTimer +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x93a64734 FsmChangeState +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x9df0cd27 FsmEvent +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xc0c558f9 FsmRestartTimer +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xd94696e8 FsmDelTimer +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xe6a7d50c hisax_init_pcmcia +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xee93522c hisax_register +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xf0a16657 FsmNew +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xfc27303b HiSax_closecard +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x2401c03b isacsx_irq +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x3f3b323a isac_d_l2l1 +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x596dfd02 isacsx_setup +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x945c494f isac_setup +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0xf26b0a14 isac_init +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0xf5833474 isac_irq +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0x1ee629e2 isdnhdlc_rcv_init +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0x95aed401 isdnhdlc_decode +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0x9ffc8215 isdnhdlc_out_init +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0xf5c8131d isdnhdlc_encode +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0x7fcca8fc isdn_ppp_unregister_compressor +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0xc6ad2630 register_isdn +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0xf207e374 isdn_ppp_register_compressor +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0xfa06820f isdn_register_divert +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x012c7f57 recv_Bchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x0549f9fb mISDN_freebchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x0ca7de0f create_l1 +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x176a312b mISDN_unregister_Bprotocol +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x2348cc3c mISDN_FsmFree +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x33428888 mISDN_register_device +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x3ea336fd mISDN_FsmAddTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x429129f2 mISDN_FsmRestartTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x50c2230c mISDN_FsmChangeState +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x694e0240 mISDN_register_Bprotocol +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x6f09c0de mISDN_freedchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x7072571b get_next_dframe +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x74bfb4ff mISDN_initdchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x81ca1c26 l1_event +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xa6d4e660 dchannel_senddata +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xa7c7825a recv_Dchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xa93ab7e7 mISDN_initbchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xace35cae mISDN_FsmDelTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xae34e4d9 recv_Bchannel_skb +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xb9654d66 bchannel_senddata +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xd5145151 mISDN_FsmEvent +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xd9a7fbfd mISDN_FsmInitTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xdc3696e1 confirm_Bsend +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xec18f46d mISDN_unregister_device +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xf0a343d4 recv_Dchannel_skb +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xf50c5d18 get_next_bframe +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xf9e7832f mISDN_FsmNew +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xfebda0a1 queue_ch_frame +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0x4c2ec443 mISDN_dsp_element_register +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0x60721da7 dsp_audio_law_to_s32 +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0xa215f1b2 dsp_audio_s16_to_law +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0xd3a023b8 mISDN_dsp_element_unregister +EXPORT_SYMBOL drivers/media/common/tuners/mt2060 0x6420f8c9 mt2060_attach +EXPORT_SYMBOL drivers/media/common/tuners/mt2131 0x32291931 mt2131_attach +EXPORT_SYMBOL drivers/media/common/tuners/mt2266 0x3f39d332 mt2266_attach +EXPORT_SYMBOL drivers/media/common/tuners/mxl5005s 0x095c4fe7 mxl5005s_attach +EXPORT_SYMBOL drivers/media/common/tuners/qt1010 0x8aca4052 qt1010_attach +EXPORT_SYMBOL drivers/media/common/tuners/tuner-types 0x0cb4b189 tuners +EXPORT_SYMBOL drivers/media/common/tuners/tuner-types 0xc2821775 tuner_count +EXPORT_SYMBOL drivers/media/common/tuners/tuner-xc2028 0xc16031ac xc2028_attach +EXPORT_SYMBOL drivers/media/common/tuners/xc5000 0x16978bf6 xc5000_attach +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x0e083609 flexcop_sram_set_dest +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x1b6f5e41 flexcop_sram_ctrl +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x1f932042 flexcop_eeprom_check_mac_addr +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x3097914c flexcop_dma_config +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x3801272a flexcop_pass_dmx_packets +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x557bda50 flexcop_dma_control_timer_irq +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x5b4d85f9 flexcop_dma_control_size_irq +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x68e1a779 flexcop_i2c_request +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x736112a6 flexcop_device_initialize +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x782b58d0 flexcop_dma_free +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x8ce9fa2a flexcop_device_kmalloc +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x9fd04a27 flexcop_dma_allocate +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xa05c4d18 flexcop_dump_reg +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xb71d34b0 flexcop_device_kfree +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xb77ad719 flexcop_dma_config_timer +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xbb61fb7c flexcop_wan_set_speed +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xbea25c00 flexcop_device_exit +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xdfa36240 flexcop_pass_dmx_data +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xf0d873ba flexcop_dma_xfer_control +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0x34c1d297 bt878_stop +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0x7221d2c8 bt878 +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0x99fd4c74 bt878_start +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0xa064eb8c bt878_device_control +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0xd5d0bdef bt878_num +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x1463d73a write_dst +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x14bf627f dst_wait_dst_ready +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x68991be2 dst_error_bailout +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x6cae0cd5 dst_comm_init +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xa980b9f7 read_dst +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xb44952b7 rdc_reset_state +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xb8e2bb66 dst_error_recovery +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xc7a3b1b2 dst_pio_disable +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xe94b8c9c dst_check_sum +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xfc1b5b49 dst_attach +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst_ca 0x0b8dc6ee dst_ca_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x03504e20 dvb_ca_en50221_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x0b8a0067 dvb_unregister_device +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x0c457c5c dvb_ringbuffer_flush_spinlock_wakeup +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x1b1c06dd dvb_net_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x2ae6c78e dvb_dmxdev_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x2af2a213 dvb_ca_en50221_camchange_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x36c8ea1f dvb_frontend_sleep_until +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x3aad6ce4 dvb_generic_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x3bbdff45 dvb_unregister_frontend +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x4db3899f dvb_dmx_swfilter_packets +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x51f3767c dvb_ringbuffer_read +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x54fab26a dvb_ca_en50221_camready_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x5ce2d08f dvb_frontend_reinitialise +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x6988f784 dvb_ringbuffer_read_user +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x698b0fb2 dvb_generic_open +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x735d0c02 dvb_register_adapter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x74a5a698 dvb_filter_pes2ts_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x7773ac71 dvb_register_frontend +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x80e3832d dvb_filter_get_ac3info +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x8b49a23f timeval_usec_diff +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x8bf881e9 dvb_generic_ioctl +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xac4ca1b0 intlog2 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb29fe59b dvb_dmxdev_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xbbb1d1a4 dvb_frontend_detach +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xbc5b257b dvb_net_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xbd3054c7 dvb_register_device +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xc324b69b dvb_dmx_swfilter_204 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xc80754c1 dvb_dmx_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xcb89fc7d dvb_ringbuffer_free +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xcca08cb5 dvb_ringbuffer_avail +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xcce0eeed dvb_ringbuffer_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xd639b9bc dvb_ringbuffer_write +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xd7765e69 dvb_ringbuffer_empty +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xe5ae8707 intlog10 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xee54ac68 dvb_ca_en50221_frda_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xee73de0a dvb_dmx_swfilter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf7573a18 dvb_unregister_adapter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf826deb0 dvb_filter_pes2ts +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf86f20c5 dvb_dmx_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xfbd75b8d dvb_ca_en50221_init +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x5ee180fd dvb_usb_device_init +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x78ebcc81 dvb_usb_generic_rw +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x8a412dc2 dvb_usb_get_hexline +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xb1b6a93e usb_cypress_load_firmware +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xb2a26caf dvb_usb_device_exit +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xe89537bd dvb_usb_nec_rc_key_to_event +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xfccd9ed6 dvb_usb_generic_write +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0x1cda9de5 af9005_rc_decode +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0x2edc4728 af9005_rc_keys +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0xd3383957 af9005_rc_keys_size +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x092a6969 dibusb2_0_streaming_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x0a7276dd dibusb_i2c_algo +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x0b450070 dibusb_rc_query +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x0cb7fcb9 dibusb_pid_filter_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x65ad6b25 dibusb_dib3000mc_tuner_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x6fefc18d dibusb_pid_filter +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x76281ce1 dibusb_power_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x765df0ec dibusb_read_eeprom_byte +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xa1087823 dibusb2_0_power_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xd2ee5062 dibusb_dib3000mc_frontend_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xd4d3dddc dibusb_rc_keys +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xd88fa7be dibusb_streaming_ctrl +EXPORT_SYMBOL drivers/media/dvb/frontends/af9013 0x6d4268ca af9013_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/au8522 0x4fc62d15 au8522_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/bcm3510 0xdef3768a bcm3510_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx22700 0x5e87381d cx22700_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx22702 0xb8864bb9 cx22702_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24110 0x0f275c22 cx24110_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24116 0xadceb0d9 cx24116_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24123 0x14835b9a cx24123_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24123 0x94caca18 cx24123_get_tuner_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/dib0070 0x64ef8c46 dib0070_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib0070 0xaa361af1 dib0070_wbd_offset +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mb 0xd2c47019 dib3000mb_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x2fe2ecf1 dib3000mc_i2c_enumeration +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x30c5cba9 dib3000mc_pid_parse +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0xb98ec6d0 dib3000mc_pid_control +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0xc0a67ecc dib3000mc_set_config +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0xcc624b43 dib3000mc_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0xe987ae03 dib3000mc_get_tuner_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000m 0x17ded495 dib7000m_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000m 0xc95cfc1c dib7000m_get_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x03180c94 dib7000p_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x07fd563e dib7000p_set_gpio +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x1fac3b29 dib7000p_set_wbd_ref +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x470111ca dib7000p_get_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xb475e9bb dib7000pc_detection +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xd9dd7aa9 dib7000p_i2c_enumeration +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0x3a0a4e3e dibx000_init_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0x8aac55d4 dibx000_get_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0xcfee3935 dibx000_exit_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/drx397xD 0x1ecbc359 drx397xD_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dvb-pll 0x8d6e9362 dvb_pll_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/isl6405 0x95416412 isl6405_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/isl6421 0xf0ac232b isl6421_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/itd1000 0xf1843605 itd1000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/l64781 0x2413b783 l64781_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lgdt330x 0x10c33664 lgdt330x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lgs8gl5 0x3f7a4c76 lgs8gl5_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lnbp21 0x0a564913 lnbp21_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/mt312 0x4ac11027 mt312_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/mt352 0x07ff6d61 mt352_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/nxt200x 0xe392663d nxt200x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/nxt6000 0x063df531 nxt6000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/or51132 0xe756a40c or51132_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/or51211 0x87699791 or51211_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1409 0x676a87a1 s5h1409_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1411 0x4fddc712 s5h1411_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1420 0x6c54bcae s5h1420_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1420 0x72686db6 s5h1420_get_tuner_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/si21xx 0x446bd324 si21xx_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/sp8870 0x205648fc sp8870_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/sp887x 0x9fe4266a sp887x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stb6000 0xd9b6a81b stb6000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0288 0x47f8ef06 stv0288_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0297 0x67e23d37 stv0297_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0299 0x384ebb11 stv0299_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10021 0x001ea5fc tda10021_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10023 0x0c97bec5 tda10023_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10048 0x01d4ccee tda10048_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda1004x 0xcf104776 tda10045_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda1004x 0xe851fe86 tda10046_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10086 0x3d2d2928 tda10086_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda8083 0x61b7b0f3 tda8083_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda826x 0x4500cca4 tda826x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tua6100 0xc2c57326 tua6100_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/ves1820 0x6ae07d76 ves1820_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/ves1x93 0x0d09e1ab ves1x93_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/zl10353 0x409d5b96 zl10353_attach +EXPORT_SYMBOL drivers/media/dvb/ttpci/ttpci-eeprom 0x0adcb58f ttpci_eeprom_parse_mac +EXPORT_SYMBOL drivers/media/dvb/ttusb-dec/ttusbdecfe 0xd4c1205d ttusbdecfe_dvbt_attach +EXPORT_SYMBOL drivers/media/dvb/ttusb-dec/ttusbdecfe 0xff062197 ttusbdecfe_dvbs_attach +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x11dc4b6d bttv_gpio_enable +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x30b21926 bttv_sub_register +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x8ecf4acc bttv_write_gpio +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x91dba186 bttv_get_pcidev +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0xbb0ddd8c bttv_sub_unregister +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0xbcf2d2fb bttv_read_gpio +EXPORT_SYMBOL drivers/media/video/btcx-risc 0x204418bb btcx_riscmem_alloc +EXPORT_SYMBOL drivers/media/video/btcx-risc 0x495e4b0c btcx_calc_skips +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xad2fe38b btcx_sort_clips +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xc368f8e6 btcx_align +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xcda0ded2 btcx_screen_clips +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xf5320745 btcx_riscmem_free +EXPORT_SYMBOL drivers/media/video/cpia 0x30228a04 cpia_unregister_camera +EXPORT_SYMBOL drivers/media/video/cpia 0xbfa7615f cpia_register_camera +EXPORT_SYMBOL drivers/media/video/cx18/cx18 0x2cdea06d cx18_reset_ir_gpio +EXPORT_SYMBOL drivers/media/video/cx2341x 0x226b4360 cx2341x_ctrl_get_menu +EXPORT_SYMBOL drivers/media/video/cx2341x 0x484d9064 cx2341x_ctrl_query +EXPORT_SYMBOL drivers/media/video/cx2341x 0x61b38569 cx2341x_ext_ctrls +EXPORT_SYMBOL drivers/media/video/cx2341x 0x62f2c86b cx2341x_log_status +EXPORT_SYMBOL drivers/media/video/cx2341x 0x7f09da7c cx2341x_fill_defaults +EXPORT_SYMBOL drivers/media/video/cx2341x 0xcf8b77a4 cx2341x_mpeg_ctrls +EXPORT_SYMBOL drivers/media/video/cx2341x 0xe58ec2e3 cx2341x_update +EXPORT_SYMBOL drivers/media/video/cx88/cx88-vp3054-i2c 0xbc8e326e vp3054_i2c_remove +EXPORT_SYMBOL drivers/media/video/cx88/cx88-vp3054-i2c 0xcedddb94 vp3054_i2c_probe +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x053eb641 cx88_enum_input +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x5d7dc16e cx8800_ctrl_query +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x85b05c97 cx88_video_mux +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xa5aa3c49 cx88_set_freq +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xac4e53b9 cx88_user_ctrls +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xd46e4fcd cx88_get_control +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xd981839d cx88_set_control +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x1b33605a cx8802_register_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x4e260536 cx8802_get_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x7081ed5e cx8802_get_device +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x7a0378a4 cx8802_buf_queue +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0xa043807a cx8802_buf_prepare +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0xa61d3c6b cx8802_unregister_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0xea972e54 cx8802_cancel_buffers +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x11defc94 cx88_free_buffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x1c8d1334 cx88_core_get +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x31e0656e cx88_shutdown +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x3d2f8a03 cx88_risc_buffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x4245f1ca cx88_risc_stopper +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x4f822e89 cx88_core_put +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x5ac8afa5 cx88_call_i2c_clients +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x5cca4f67 cx88_vdev_init +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x6141c8c5 cx88_tuner_callback +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x61842754 cx88_sram_channel_setup +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x6303a677 cx88_sram_channel_dump +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x904b8696 cx88_audio_thread +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x9b140fff cx88_sram_channels +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xa23333f5 cx88_set_tvaudio +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xa8add6b3 cx88_core_irq +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xaf87f71d cx88_set_scale +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xb47f6cda cx88_print_irqbits +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xc175d744 cx88_set_tvnorm +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xcfcb4d1c cx88_wakeup +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xd032068d cx88_ir_start +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xd284a4fb cx88_ir_stop +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xd4fb0e22 cx88_get_stereo +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xdffb5b16 cx88_newstation +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xe5abb543 cx88_risc_databuffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xeebcc7d6 cx88_reset +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xf73645f0 cx88_set_stereo +EXPORT_SYMBOL drivers/media/video/em28xx/em28xx 0x3d8ab3a4 em28xx_register_extension +EXPORT_SYMBOL drivers/media/video/em28xx/em28xx 0x8e784a36 em28xx_unregister_extension +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x1d8e7789 gspca_disconnect +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x7e05faf8 gspca_get_i_frame +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x92ade976 gspca_resume +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x9670af2c gspca_debug +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x9a9f47f3 gspca_suspend +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xa939d14d gspca_frame_add +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xd0272a51 gspca_auto_gain_n_exposure +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xe724ca51 gspca_dev_probe +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x02855897 ivtv_udma_setup +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x0538e449 ivtv_cards_lock +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x14f67530 ivtv_debug +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x21af8062 ivtv_vapi +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x2b616968 ivtv_set_irq_mask +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x2c43cbed ivtv_saa7127 +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x37314be6 ivtv_cards +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x6b83c8fa ivtv_udma_unmap +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x6eb503aa ivtv_udma_prepare +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x70196ffb ivtv_cards_active +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x846636a9 ivtv_reset_ir_gpio +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x8cb1fde9 ivtv_vapi_result +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xcf7bd683 ivtv_clear_irq_mask +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xd4989890 ivtv_init_on_first_open +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xdc1e2d71 ivtv_api +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xe31266a7 ivtv_udma_alloc +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x03cf0281 saa7134_ts_register +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x04e83446 saa7134_tuner_callback +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x0c521a9f saa_dsp_writel +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x1211df5d saa7134_devlist +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x26ac10c4 saa7134_set_dmabits +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x40beef25 saa7134_dmasound_init +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x58c5c6c1 saa7134_tvaudio_setmute +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x81a5cf3b saa7134_pgtable_free +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x826ca7c8 saa7134_pgtable_build +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x90f0e5e2 saa7134_pgtable_alloc +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x98af79c1 saa7134_boards +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x9c3e69ad saa7134_ts_unregister +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xa87edaea saa7134_set_gpio +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xd7206e4d saa7134_dmasound_exit +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xeaa66df9 saa7134_i2c_call_clients +EXPORT_SYMBOL drivers/media/video/soc_camera 0x0cf70239 soc_camera_video_start +EXPORT_SYMBOL drivers/media/video/soc_camera 0x106404a0 soc_camera_device_unregister +EXPORT_SYMBOL drivers/media/video/soc_camera 0x2771b5fe soc_camera_host_unregister +EXPORT_SYMBOL drivers/media/video/soc_camera 0x6264d512 soc_camera_video_stop +EXPORT_SYMBOL drivers/media/video/soc_camera 0x8001a204 soc_camera_device_register +EXPORT_SYMBOL drivers/media/video/soc_camera 0xe19634a9 soc_camera_host_register +EXPORT_SYMBOL drivers/media/video/tveeprom 0x527f9934 tveeprom_read +EXPORT_SYMBOL drivers/media/video/tveeprom 0x970fc1f8 tveeprom_hauppauge_analog +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x16a2915c RingQueue_Dequeue +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x3ddd85ea usbvideo_Deregister +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x407a321c RingQueue_WakeUpInterruptible +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x73858cb6 usbvideo_TestPattern +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xa0eb548e usbvideo_AllocateDevice +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xdbd0edaa usbvideo_DeinterlaceFrame +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xddecac6d RingQueue_Enqueue +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xf22d5969 usbvideo_register +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xf5011f67 RingQueue_Flush +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xffb1af38 usbvideo_RegisterVideoDevice +EXPORT_SYMBOL drivers/media/video/v4l1-compat 0x52e4360d v4l_compat_translate_ioctl +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x03165a85 v4l2_ctrl_get_menu +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x0dfb5e57 v4l2_prio_max +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x1c427ecb v4l2_ctrl_query_fill +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x1c743f66 v4l2_chip_ident_i2c_client +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x2de2b633 v4l2_prio_check +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x2e9a955d v4l2_prio_close +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x42c8e001 v4l2_ctrl_next +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x458af61e v4l2_chip_match_i2c_client +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x495426ee v4l2_ctrl_get_name +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x50766d69 v4l2_ctrl_query_menu_valid_items +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x57abfbd8 v4l2_chip_match_host +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x5fef1b4a v4l2_ctrl_query_fill_std +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x942892ab v4l2_prio_open +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xafa05d8f v4l2_i2c_attach +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xb2d1e17e v4l2_prio_change +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xc369097d v4l2_ctrl_check +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xd464e760 v4l2_ctrl_query_menu +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xe330bce9 v4l2_prio_init +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x17c4dba2 videobuf_dvb_find_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x3b278798 videobuf_dvb_register_bus +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x6dce5841 videobuf_dvb_get_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x8873645c videobuf_dvb_dealloc_frontends +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x9d02f1ea videobuf_dvb_alloc_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0xda492b14 videobuf_dvb_unregister_bus +EXPORT_SYMBOL drivers/media/video/videodev 0x123959a1 v4l2_type_names +EXPORT_SYMBOL drivers/media/video/videodev 0x207688d4 video_devdata +EXPORT_SYMBOL drivers/media/video/videodev 0x3adbd595 v4l2_field_names +EXPORT_SYMBOL drivers/media/video/videodev 0x3edeac69 video_device_release_empty +EXPORT_SYMBOL drivers/media/video/videodev 0x454e5c1b video_unregister_device +EXPORT_SYMBOL drivers/media/video/videodev 0x5581dcff video_usercopy +EXPORT_SYMBOL drivers/media/video/videodev 0x5782066d video_device_alloc +EXPORT_SYMBOL drivers/media/video/videodev 0x5ebefe4b v4l_printk_ioctl +EXPORT_SYMBOL drivers/media/video/videodev 0x81c485c0 __video_ioctl2 +EXPORT_SYMBOL drivers/media/video/videodev 0x9c544691 video_register_device +EXPORT_SYMBOL drivers/media/video/videodev 0xbafd9a90 video_register_device_index +EXPORT_SYMBOL drivers/media/video/videodev 0xd3d61d8c video_ioctl2 +EXPORT_SYMBOL drivers/media/video/videodev 0xe2b92059 v4l2_video_std_construct +EXPORT_SYMBOL drivers/media/video/videodev 0xe80c140d video_device_release +EXPORT_SYMBOL drivers/media/video/videodev 0xf3251e7b v4l2_norm_to_name +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0x3762dd30 videocodec_register +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0x5aa1a02c videocodec_attach +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0x7d26cdd9 videocodec_unregister +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0xb15312b4 videocodec_detach +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x0260e217 mpt_resume +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x105d4f47 mpt_add_sge +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x1866638d mpt_HardResetHandler +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x1c14127f mpt_verify_adapter +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x1c24d0e3 mpt_put_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x1e18d227 mpt_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x26435392 mpt_put_msg_frame_hi_pri +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x3820b007 mptbase_sas_persist_operation +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x38ae5eb6 mpt_get_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x43344d4a mpt_suspend +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x4526289b mpt_event_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x48079e7c mpt_GetIocState +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x6c93ea2e mpt_device_driver_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x716ce290 mpt_findImVolumes +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x8e7ba68a mpt_alloc_fw_memory +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xb8fca91a mpt_send_handshake_request +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xbb493324 mpt_raid_phys_disk_pg0 +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc0e69f82 mpt_device_driver_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc3f79fae mpt_event_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc47c22e8 mpt_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc7242b04 mpt_detach +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xca290bde mpt_print_ioc_summary +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xd01d3691 mpt_reset_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xd9a92a75 mpt_reset_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xdb725bd1 mpt_free_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xdd805159 ioc_list +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xee63fd47 mpt_free_fw_memory +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xefa46b65 mpt_attach +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xfdd2e669 mpt_config +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x043c1bf6 mptscsih_is_phys_disk +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x0ab54b82 mptscsih_qcmd +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x178b0afb mptscsih_abort +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x1848b9ce mptscsih_TMHandler +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x1abebe98 mptscsih_raid_id_to_num +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x1d51b2b8 mptscsih_event_process +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x28cf9dae mptscsih_host_attrs +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x3361c968 mptscsih_taskmgmt_complete +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x39a5cbb1 mptscsih_remove +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x49761fae mptscsih_resume +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x53ad14a5 mptscsih_slave_destroy +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x764ddf1a mptscsih_timer_expired +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x7f1185ba mptscsih_proc_info +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x80b1fb36 mptscsih_info +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x81ac9bfa mptscsih_dev_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x82265975 mptscsih_shutdown +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xc351e941 mptscsih_change_queue_depth +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xd5144969 mptscsih_bios_param +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xd9770762 mptscsih_host_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xdbf34090 mptscsih_bus_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xe1da2395 mptscsih_slave_configure +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xe2d92c66 mptscsih_ioc_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xe2fe4323 mptscsih_io_done +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xe402ff81 mptscsih_scandv_complete +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xfeddd00c mptscsih_suspend +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x02e531d2 i2o_parm_field_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x047f60f0 i2o_cntxt_list_remove +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x0a66fe49 i2o_cntxt_list_add +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x12481d66 i2o_msg_get_wait +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x1f028baa i2o_status_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x2a843bef i2o_dump_message +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x2b6e2695 i2o_device_claim +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x319d9801 i2o_find_iop +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x32b35498 i2o_driver_notify_device_remove_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x5957cc68 i2o_driver_notify_controller_remove_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x720b95b0 i2o_device_claim_release +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x80cae138 i2o_driver_register +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x85134dab i2o_cntxt_list_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x8768ebb3 i2o_msg_post_wait_mem +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x97d1531b i2o_parm_table_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xa8746ae2 i2o_iop_find_device +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xab766960 i2o_driver_notify_device_add_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xac2c3c2c i2o_driver_unregister +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xb4c00dcf i2o_controllers +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xb8e021c0 i2o_exec_lct_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xd9f06a17 i2o_driver_notify_controller_add_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xe45ff8e7 i2o_event_register +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xe4993e2c i2o_cntxt_list_get_ptr +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xfa8b63be i2o_parm_issue +EXPORT_SYMBOL drivers/mfd/htc-pasic3 0x16c0b530 pasic3_write_register +EXPORT_SYMBOL drivers/mfd/htc-pasic3 0x5b0e75c9 pasic3_read_register +EXPORT_SYMBOL drivers/misc/c2port/core 0x625cfe08 c2port_device_register +EXPORT_SYMBOL drivers/misc/c2port/core 0x763f552f c2port_device_unregister +EXPORT_SYMBOL drivers/misc/ioc4 0x1c5e179e ioc4_register_submodule +EXPORT_SYMBOL drivers/misc/ioc4 0xb101e35d ioc4_unregister_submodule +EXPORT_SYMBOL drivers/misc/sony-laptop 0x5bb1e117 sony_pic_camera_command +EXPORT_SYMBOL drivers/misc/tifm_core 0x307b183f tifm_free_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0x339d3143 tifm_free_device +EXPORT_SYMBOL drivers/misc/tifm_core 0x603905d0 tifm_unmap_sg +EXPORT_SYMBOL drivers/misc/tifm_core 0x710d8462 tifm_remove_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0x7abb4df7 tifm_map_sg +EXPORT_SYMBOL drivers/misc/tifm_core 0x86f5ba03 tifm_has_ms_pif +EXPORT_SYMBOL drivers/misc/tifm_core 0x95dc7e2b tifm_alloc_device +EXPORT_SYMBOL drivers/misc/tifm_core 0x9ddfe759 tifm_add_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0xa8c2ec46 tifm_queue_work +EXPORT_SYMBOL drivers/misc/tifm_core 0xb1dc9315 tifm_unregister_driver +EXPORT_SYMBOL drivers/misc/tifm_core 0xb4c82359 tifm_alloc_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0xdfba73c3 tifm_eject +EXPORT_SYMBOL drivers/misc/tifm_core 0xf72e11fa tifm_register_driver +EXPORT_SYMBOL drivers/mmc/card/mmc_block 0xa67735c0 mmc_cleanup_queue +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0x1cea879b cfi_varsize_frob +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0x23fc6929 cfi_read_pri +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0xb3654456 cfi_fixup +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x14087773 unregister_mtd_chip_driver +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x25bbe5aa register_mtd_chip_driver +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0xadcf4d3a map_destroy +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0xd2cda739 do_map_probe +EXPORT_SYMBOL drivers/mtd/chips/gen_probe 0xd644ae97 mtd_do_chip_probe +EXPORT_SYMBOL drivers/mtd/maps/map_funcs 0x2bb097e1 simple_map_init +EXPORT_SYMBOL drivers/mtd/mtd 0x7756c0a5 add_mtd_partitions +EXPORT_SYMBOL drivers/mtd/mtd 0xbaf734c8 del_mtd_partitions +EXPORT_SYMBOL drivers/mtd/mtdconcat 0x491cc641 mtd_concat_destroy +EXPORT_SYMBOL drivers/mtd/mtdconcat 0x4b950d6c mtd_concat_create +EXPORT_SYMBOL drivers/mtd/nand/nand 0x048072b9 nand_scan_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand 0xc09627f4 nand_default_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0x4aa2274e nand_calculate_ecc +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0xb779cfd9 nand_correct_data +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0x836bdb72 nand_flash_ids +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0xa336feb7 nand_manuf_ids +EXPORT_SYMBOL drivers/mtd/onenand/onenand 0x4b7c4d6d onenand_default_bbt +EXPORT_SYMBOL drivers/mtd/onenand/onenand 0xd2ee8327 onenand_scan_bbt +EXPORT_SYMBOL drivers/net/8390 0x5f0275ef ei_open +EXPORT_SYMBOL drivers/net/8390 0x7d7e0dbc ei_interrupt +EXPORT_SYMBOL drivers/net/8390 0x8247a6fd ei_close +EXPORT_SYMBOL drivers/net/8390 0xe7c82df6 NS8390_init +EXPORT_SYMBOL drivers/net/8390 0xead390c8 ei_poll +EXPORT_SYMBOL drivers/net/8390 0xef01a348 __alloc_ei_netdev +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x4641bd7d arcnet_interrupt +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x565f323d arc_proto_default +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x6534792a arcnet_debug +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x6f90ce81 arcnet_unregister_proto +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x850ca899 arc_raw_proto +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0xb2c8a89a arc_proto_map +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0xc6089bdb arc_bcast_proto +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0xf895c418 alloc_arcdev +EXPORT_SYMBOL drivers/net/arcnet/com20020 0xc4d7ac09 com20020_found +EXPORT_SYMBOL drivers/net/arcnet/com20020 0xf8c5dbf3 com20020_check +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x00ff575e cxgb3_register_client +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x112cf145 t3_l2t_get +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x2aeed5c9 cxgb3_free_stid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x36688bae cxgb3_alloc_atid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x3f994026 cxgb3_free_atid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x454cbfe0 cxgb3_remove_tid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x4ff27ed3 t3_register_cpl_handler +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x54bf55f7 t3_l2t_send_event +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x572f013a cxgb3_unregister_client +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x6464dc30 cxgb3_alloc_stid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x67d6dd25 t3_l2t_send_slow +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x690cbe4e dev2t3cdev +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x6d5b0a0a cxgb3_insert_tid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x7f48f310 t3_l2e_free +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xcc8655f5 cxgb3_ofld_send +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xfd0e28bb cxgb3_queue_tid_release +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0x17b94117 hdlcdrv_arbitrate +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0x2e8bec28 hdlcdrv_transmitter +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0xba8e7e78 hdlcdrv_register +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0xef78bfaa hdlcdrv_unregister +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0xfd300aa0 hdlcdrv_receiver +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x07ff2fde sirdev_raw_write +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x2f5251a5 sirdev_set_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x3d4a80e2 irda_register_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x648cebb4 sirdev_get_instance +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x7092ec3a sirdev_raw_read +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x75bfa86b sirdev_write_complete +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x915c6825 irda_unregister_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x97627d2b sirdev_set_dtr_rts +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xe5f4e048 sirdev_put_instance +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xeb6dfbf1 sirdev_receive +EXPORT_SYMBOL drivers/net/mii 0x0258d875 mii_link_ok +EXPORT_SYMBOL drivers/net/mii 0x0526d3a6 generic_mii_ioctl +EXPORT_SYMBOL drivers/net/mii 0x2aeaaeee mii_ethtool_gset +EXPORT_SYMBOL drivers/net/mii 0x9e9709e6 mii_check_gmii_support +EXPORT_SYMBOL drivers/net/mii 0xa16fae4e mii_check_link +EXPORT_SYMBOL drivers/net/mii 0xabe6ce07 mii_check_media +EXPORT_SYMBOL drivers/net/mii 0xea01ce46 mii_ethtool_sset +EXPORT_SYMBOL drivers/net/mii 0xf2de11c5 mii_nway_restart +EXPORT_SYMBOL drivers/net/phy/mdio-bitbang 0x70dc209c free_mdio_bitbang +EXPORT_SYMBOL drivers/net/phy/mdio-bitbang 0xff804612 alloc_mdio_bitbang +EXPORT_SYMBOL drivers/net/pppox 0x205ed453 register_pppox_proto +EXPORT_SYMBOL drivers/net/pppox 0xc718edc7 pppox_ioctl +EXPORT_SYMBOL drivers/net/pppox 0xe0ff7a18 unregister_pppox_proto +EXPORT_SYMBOL drivers/net/pppox 0xfb44cb49 pppox_unbind_sock +EXPORT_SYMBOL drivers/net/sungem_phy 0x83f0aa55 mii_phy_probe +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x518fcbfb tms380tr_interrupt +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x8c97fd64 tmsdev_term +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x9f201ccf tms380tr_open +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0xa7309f65 tmsdev_init +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0xb9e9a45c tms380tr_close +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0xd2328794 tms380tr_wait +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x38da4725 cycx_intr +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x62be23ea cycx_setup +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x66a4c4e6 cycx_down +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x968458a6 cycx_peek +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0xb6f383de cycx_poke +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0xfe7cd576 cycx_exec +EXPORT_SYMBOL drivers/net/wan/hdlc 0x035522c0 detach_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0x3395649e unregister_hdlc_device +EXPORT_SYMBOL drivers/net/wan/hdlc 0x35c92bf4 register_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0x4f2af92a unregister_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0x5f2155f3 hdlc_ioctl +EXPORT_SYMBOL drivers/net/wan/hdlc 0xc87b529f hdlc_close +EXPORT_SYMBOL drivers/net/wan/hdlc 0xccea8354 attach_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0xe2eccbb2 hdlc_open +EXPORT_SYMBOL drivers/net/wan/hdlc 0xffba517d alloc_hdlcdev +EXPORT_SYMBOL drivers/net/wan/syncppp 0x342bbb18 sppp_reopen +EXPORT_SYMBOL drivers/net/wan/syncppp 0x43e9a654 sppp_detach +EXPORT_SYMBOL drivers/net/wan/syncppp 0x6aafd92d sppp_do_ioctl +EXPORT_SYMBOL drivers/net/wan/syncppp 0x6e0df095 sppp_attach +EXPORT_SYMBOL drivers/net/wan/syncppp 0x8660d85d sppp_close +EXPORT_SYMBOL drivers/net/wan/syncppp 0xa35ac069 sppp_open +EXPORT_SYMBOL drivers/net/wireless/airo 0x1ef22162 init_airo_card +EXPORT_SYMBOL drivers/net/wireless/airo 0x6368e1f6 reset_airo_card +EXPORT_SYMBOL drivers/net/wireless/airo 0xe9e4eca9 stop_airo_card +EXPORT_SYMBOL drivers/net/wireless/atmel 0x05cfe783 atmel_open +EXPORT_SYMBOL drivers/net/wireless/atmel 0x0bca67ee stop_atmel_card +EXPORT_SYMBOL drivers/net/wireless/atmel 0x4081136c init_atmel_card +EXPORT_SYMBOL drivers/net/wireless/hermes 0x4196c38b hermes_write_ltv +EXPORT_SYMBOL drivers/net/wireless/hermes 0xa031d8e4 hermes_doicmd_wait +EXPORT_SYMBOL drivers/net/wireless/hermes 0xc60b5e9e hermes_bap_pwrite +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd38d8ae2 hermes_read_ltv +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd3f714e5 hermes_bap_pread +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd5168829 hermes_allocate +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd5336e5d hermes_init +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd54e219d hermes_docmd_wait +EXPORT_SYMBOL drivers/net/wireless/hermes 0xed47b224 hermes_struct_init +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x161a199c hermes_program +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x2e340491 hermesi_program_end +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x3e7d91b2 hermesi_program_init +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x79a2030e hermes_read_pda +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xc4026a52 hermes_apply_pda +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xcbd49cae hermes_apply_pda_with_defaults +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xeb824e25 hermes_blocks_length +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x0f43164e hostap_set_encryption +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x11736c42 hostap_get_stats +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x1723ac32 hostap_set_multicast_list_queue +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x1fc82c2c hostap_remove_interface +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x2e3241fa hostap_get_porttype +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x3337ce74 hostap_init_ap_proc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x3abb3c1f hostap_master_start_xmit +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x3c01e695 hostap_info_init +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x4f766616 hostap_info_process +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x6792e340 hostap_80211_rx +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x6903f16c hostap_80211_get_hdrlen +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x6a95b594 hostap_set_word +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x7b9b7c5d hostap_handle_sta_tx_exc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x822f739d hostap_init_data +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x96c48d9a hostap_setup_dev +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xa12ad27f hostap_dump_tx_header +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xa61e0671 hostap_add_interface +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xb2a945e0 hostap_dump_rx_header +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xb48400d4 prism2_update_comms_qual +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xb70f95ec hostap_set_string +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xbd2d5236 hostap_free_data +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xd683a55e hostap_80211_ops +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xdf87216f hostap_check_sta_fw_version +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xe27fe246 hostap_init_proc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xe35539fe hostap_set_hostapd_sta +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xe5f8bf73 hostap_remove_proc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xe6cab397 hostap_set_antsel +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xee2c51a1 hostap_set_auth_algs +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xf210eb54 hostap_set_roaming +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xf9ae44df hostap_set_hostapd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x0f9a4bb3 iwl_leds_background +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x14bf6aa8 iwl_send_cmd_sync +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x1d77b399 iwl_bcast_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x204b1326 iwl_remove_dynamic_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x22c00ca5 iwl_set_rxon_ht +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x286ee917 iwl_set_dynamic_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x29c257b0 iwl_txq_check_empty +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x29d250e7 iwl_hwrate_to_tx_control +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2d74c198 iwl_rfkill_unregister +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2e6b0c36 iwl_tx_skb +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2ec11143 iwl_rx_queue_reset +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2f04eeab iwl_power_temperature_change +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x3102d33f iwl_init_sensitivity +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x31e452b5 iwl_dump_nic_error_log +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x391fd5c6 iwl_rx_reply_rx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x40b59bf7 iwl_set_rxon_channel +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x413b4052 iwl_hw_txq_ctx_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x44c0772b iwl_uninit_drv +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x48ab9866 iwl_get_sta_id +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x495b13bb iwl_tx_cmd_complete +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x49b37f85 iwl_dump_nic_event_log +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x4b80ab72 iwl_eeprom_get_mac +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x4d55e8dd iwl_sta_modify_enable_tid_tx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x4eda3d94 iwl_init_channel_map +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x50494cda iwl_sensitivity_calibration +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x542de193 iwl_eeprom_query16 +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x56a8f7dc iwl_eeprom_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x57499238 iwl_rx_missed_beacon_notif +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x57d37671 iwl_setup_rx_scan_handlers +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x592fdb78 iwlcore_eeprom_verify_signature +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5a049174 iwl_tx_agg_start +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5af2341e iwl_rx_agg_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5c7f252c iwl_hw_nic_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5cf8d1c9 iwl_rx_queue_space +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x60774702 iwl_queue_space +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x64bd8355 iwl_leds_register +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x671ed26b iwl_rx_queue_restock +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x6d75a072 iwl_set_tx_power +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x6f6dc043 iwl_rx_queue_alloc +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x71f29758 iwl_rx_reply_rx_phy +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x74f81149 iwl_tx_agg_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7a030c53 iwl_send_lq_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7b0aaa49 iwlcore_eeprom_acquire_semaphore +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7b403137 iwlcore_eeprom_release_semaphore +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7c39bae8 iwl_send_static_wepkey_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7c8cde50 iwl_hw_detect +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8123ba43 iwl_send_cmd_pdu_async +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x83504727 iwl_eeprom_check_version +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x843685fc iwl_rf_kill_ct_config +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x84dc0e1e iwl_rx_replenish +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x84fa9d10 iwl_add_station_flags +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8670273d iwl_hwrate_to_plcp_idx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x868bd88f iwl_rxon_add_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8911b832 iwl_scan_cancel +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x89f0b4f0 iwlcore_eeprom_query_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8bf26d84 iwl_power_initialize +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8bf2ff2c iwl_setup_mac +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8f8df527 iwl_send_add_sta +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x912410ce iwl_get_ra_sta_id +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x95e7add7 iwl_power_cancel_timeout +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x97361f69 iwl_power_update_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9b3fbf83 iwl_setup_power_deferred_work +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9ca243e1 iwl_send_cmd_pdu +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9d30a4f3 iwl_is_fat_tx_allowed +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9faced57 iwl_calib_set +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa1c3cb8b iwl_remove_default_wep_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa228b5e7 iwl_rx_statistics +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa384cd03 iwl_find_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa3d2ed9d iwl_verify_ucode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa94857e8 iwl_rx_reply_compressed_ba +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xab890b30 iwl_eeprom_query_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xabf5d7f7 iwl_get_channel_info +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xacf84f2a iwl_power_set_user_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xaf53aff1 iwl_radio_kill_sw_enable_radio +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb02d206c iwl_send_calib_results +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb083703e iwl_clear_stations_table +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb590ffe6 iwl_send_statistics_request +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb6af4ea1 iwl_reset_qos +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb95e83e9 iwl_power_disable_management +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb9ee04bf iwl_alloc_all +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xbdc69c2e iwl_radio_kill_sw_disable_radio +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xbfd039bd iwl_rfkill_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc0e7dbd6 iwl_remove_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc1743c24 iwl_txq_ctx_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc3dac20b iwl_send_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc545b89d iwl_leds_unregister +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc69e75ed iwl_rx_queue_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc7196f0e iwl_init_drv +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcbaf4931 get_cmd_string +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcf28136a iwl_eeprom_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcf9fc5a6 iwl_rx_queue_update_write_ptr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcfc088cb iwl_txq_update_write_ptr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd22b044e iwl_set_hw_params +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd28a6fa6 iwl_tx_queue_reclaim +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd2ba42ba iwl_rfkill_set_hw_state +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd3fa5c20 iwl_power_enable_management +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd9a85d2a iwl_scan_cancel_timeout +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xdad05f86 iwl_power_set_system_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xdfb69344 iwl_set_rxon_chain +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe1cb6a69 iwl_scan_initiate +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe7ce5d70 iwl_rates +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe904d7c6 iwl_set_default_wep_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xeb2a2e05 iwl_chain_noise_calibration +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xf12be572 iwl_reset_run_time_calib +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xf6ca975a iwl_rxq_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xf6f34ea4 iwl_rx_agg_start +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xfa2e794f iwl_setup_scan_deferred_work +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x100af4e6 orinoco_reinit_firmware +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x1a9d334a orinoco_interrupt +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x82861a78 free_orinocodev +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x8a54e940 __orinoco_up +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x95ca3e64 __orinoco_down +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x9643ce33 alloc_orinocodev +EXPORT_SYMBOL drivers/parport/parport 0x106360db parport_ieee1284_epp_write_data +EXPORT_SYMBOL drivers/parport/parport 0x1476608c parport_claim +EXPORT_SYMBOL drivers/parport/parport 0x14fde6c7 parport_ieee1284_epp_write_addr +EXPORT_SYMBOL drivers/parport/parport 0x158c8e8b parport_claim_or_block +EXPORT_SYMBOL drivers/parport/parport 0x1b48a1b7 parport_put_port +EXPORT_SYMBOL drivers/parport/parport 0x1dbe8d84 parport_irq_handler +EXPORT_SYMBOL drivers/parport/parport 0x21766871 parport_ieee1284_read_nibble +EXPORT_SYMBOL drivers/parport/parport 0x4d2a941b parport_ieee1284_interrupt +EXPORT_SYMBOL drivers/parport/parport 0x4e17dcb4 parport_find_number +EXPORT_SYMBOL drivers/parport/parport 0x55a21e07 parport_get_port +EXPORT_SYMBOL drivers/parport/parport 0x656f345b parport_read +EXPORT_SYMBOL drivers/parport/parport 0x704e8709 parport_register_device +EXPORT_SYMBOL drivers/parport/parport 0x7c208fa1 parport_unregister_driver +EXPORT_SYMBOL drivers/parport/parport 0x81c788fc parport_ieee1284_ecp_write_data +EXPORT_SYMBOL drivers/parport/parport 0x85590ee0 parport_ieee1284_ecp_write_addr +EXPORT_SYMBOL drivers/parport/parport 0x87610617 parport_find_base +EXPORT_SYMBOL drivers/parport/parport 0x87879095 parport_announce_port +EXPORT_SYMBOL drivers/parport/parport 0x8ec0ae02 parport_wait_peripheral +EXPORT_SYMBOL drivers/parport/parport 0x993f77ea parport_remove_port +EXPORT_SYMBOL drivers/parport/parport 0xa3c968e5 parport_unregister_device +EXPORT_SYMBOL drivers/parport/parport 0xa46a9382 parport_negotiate +EXPORT_SYMBOL drivers/parport/parport 0xa9506615 parport_set_timeout +EXPORT_SYMBOL drivers/parport/parport 0xb4a79359 parport_register_port +EXPORT_SYMBOL drivers/parport/parport 0xb4db819b parport_wait_event +EXPORT_SYMBOL drivers/parport/parport 0xb50c7bd5 parport_ieee1284_read_byte +EXPORT_SYMBOL drivers/parport/parport 0xc4879a8b parport_register_driver +EXPORT_SYMBOL drivers/parport/parport 0xc6b85495 parport_ieee1284_epp_read_addr +EXPORT_SYMBOL drivers/parport/parport 0xe281341d parport_ieee1284_write_compat +EXPORT_SYMBOL drivers/parport/parport 0xe7336577 parport_ieee1284_ecp_read_data +EXPORT_SYMBOL drivers/parport/parport 0xe74ccd23 parport_write +EXPORT_SYMBOL drivers/parport/parport 0xe762f51c parport_ieee1284_epp_read_data +EXPORT_SYMBOL drivers/parport/parport 0xfee25d87 parport_release +EXPORT_SYMBOL drivers/parport/parport_pc 0x2e6e5e9c parport_pc_unregister_port +EXPORT_SYMBOL drivers/parport/parport_pc 0xe8d9c6f5 parport_pc_probe_port +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x00882b95 pcmcia_modify_configuration +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x1451bf03 pcmcia_request_irq +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x19d5708a pcmcia_request_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x1aadfa92 pcmcia_disable_device +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x2be616ec pcmcia_map_mem_page +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x4d74879f pcmcia_request_io +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x4fd033a0 pcmcia_error_func +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x5f8bd925 pcmcia_request_configuration +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x7a666475 pcmcia_get_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x984f60d5 pcmcia_unregister_driver +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xa96b806e pcmcia_dev_present +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xab4b297d pcmcia_register_driver +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xc053c5b9 pcmcia_loop_config +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xc41e2e14 pcmcia_access_configuration_register +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xdd017b98 pcmcia_get_mem_page +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xf000e2ac pcmcia_release_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xf0a25e12 pcmcia_error_ret +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x09e54cbe pcmcia_suspend_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x0af4df0a pcmcia_parse_events +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x1a185344 pcmcia_get_socket_by_nr +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x1dd67e11 pcmcia_write_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x212db8d2 pcmcia_socket_list +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x30b936b0 pccard_get_first_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x32ab9fc7 pccard_get_tuple_data +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x3a582895 pcmcia_socket_dev_suspend +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x3f9a7e4d pccard_static_ops +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x42d7d874 pccard_register_pcmcia +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x4688a421 pcmcia_resume_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x4ee49d1e pcmcia_get_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x59643bf5 release_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x6891c6ca pcmcia_find_io_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x86278490 pcmcia_unregister_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x8cd7f463 pccard_get_next_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x8f484df7 pcmcia_socket_dev_resume +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x9a120356 pcmcia_put_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xa8df65b6 pcmcia_socket_list_rwsem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xaffef93a pcmcia_find_mem_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xb427f969 pcmcia_reset_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xb523cd38 pcmcia_register_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xbb2638bb destroy_cis_cache +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xbb8c467e pcmcia_validate_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xbe29b84f pcmcia_socket_class +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xc02ef2c8 pcmcia_parse_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xccbbe894 pcmcia_adjust_io_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xcf97f3bd dead_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xdb49f4ad pcmcia_replace_cis +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xdded96b8 pcmcia_insert_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xeaee8dc0 pcmcia_read_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xf7b27ccd pccard_read_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xfcc0842b pccard_validate_cis +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xfea1a025 pcmcia_eject_card +EXPORT_SYMBOL drivers/pcmcia/rsrc_nonstatic 0xedafc732 pccard_nonstatic_ops +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0x2250c66e mraid_mm_adapter_app_handle +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0x512c956d mraid_mm_unregister_adp +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0xdb61961e mraid_mm_register_adp +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x12c7dab5 qlogicfas408_biosparam +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x22de13a2 qlogicfas408_info +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x3fd8cd71 qlogicfas408_detect +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x4e7fc283 qlogicfas408_queuecommand +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x5cd179e6 qlogicfas408_ihandl +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x5eadb027 qlogicfas408_abort +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x6b98b9ff qlogicfas408_bus_reset +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xe76b3b20 qlogicfas408_get_chip_type +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xf21ae8fb qlogicfas408_disable_ints +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xf2b95199 qlogicfas408_setup +EXPORT_SYMBOL drivers/scsi/raid_class 0x397e9127 raid_component_add +EXPORT_SYMBOL drivers/scsi/raid_class 0xdeb9eb67 raid_class_attach +EXPORT_SYMBOL drivers/scsi/raid_class 0xfc34af92 raid_class_release +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x190b1dd3 fc_remote_port_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x5df4a4b4 fc_remote_port_rolechg +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x651d7edb scsi_is_fc_vport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x70f32dd6 scsi_is_fc_rport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x7954b1ea fc_get_event_number +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x8e7dde3b fc_remote_port_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xa2e65a3b fc_vport_terminate +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xad8984d0 fc_host_post_vendor_event +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xd31fa5f6 fc_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xd5f3c323 fc_remove_host +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xde4f3b2a fc_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xe2afb381 fc_host_post_event +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xe7dff79a fc_vport_create +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x0bbbaeb0 sas_port_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x14a46f71 sas_read_port_mode_page +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x1ec4982c sas_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x2086ec36 sas_phy_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x4c7f599f sas_rphy_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x4fd3cdd8 sas_remove_host +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x55898cf3 scsi_is_sas_port +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x58cdc38f sas_rphy_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x63579305 scsi_is_sas_rphy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x63c44a4b sas_port_delete_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x710b79bc sas_rphy_remove +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x7515d383 sas_end_device_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x760e1155 sas_phy_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x7effe674 sas_port_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x88818e30 sas_port_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x97e4abda sas_expander_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xa5e1059f sas_port_add_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xaf7cd5aa scsi_is_sas_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xb0a14f08 sas_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xc600edf6 sas_phy_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xc65b0531 sas_remove_children +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xd3e376ef sas_port_mark_backlink +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xe7006b77 sas_rphy_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xe93048c9 sas_port_alloc_num +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xea0c529f sas_phy_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xf33e38cc sas_port_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x3686ea09 spi_print_msg +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x51e22e6c spi_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0xbf024dd5 spi_display_xfer_agreement +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0xe3d2f6f3 spi_schedule_dv_device +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0xedda47f7 spi_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0xfbcf6bbc spi_dv_device +EXPORT_SYMBOL drivers/ssb/ssb 0x04806729 ssb_driver_unregister +EXPORT_SYMBOL drivers/ssb/ssb 0x1bc66f60 ssb_pcihost_register +EXPORT_SYMBOL drivers/ssb/ssb 0x450cbf47 ssb_bus_suspend +EXPORT_SYMBOL drivers/ssb/ssb 0x482cfd26 ssb_dma_free_consistent +EXPORT_SYMBOL drivers/ssb/ssb 0x654ba824 ssb_device_enable +EXPORT_SYMBOL drivers/ssb/ssb 0x6b7bb1d8 ssb_bus_powerup +EXPORT_SYMBOL drivers/ssb/ssb 0x7269e1bd ssb_bus_pcibus_register +EXPORT_SYMBOL drivers/ssb/ssb 0x8b2a202f ssb_clockspeed +EXPORT_SYMBOL drivers/ssb/ssb 0x8e3f3d86 ssb_dma_set_mask +EXPORT_SYMBOL drivers/ssb/ssb 0xad50bc86 ssb_device_is_enabled +EXPORT_SYMBOL drivers/ssb/ssb 0xb902d676 ssb_device_disable +EXPORT_SYMBOL drivers/ssb/ssb 0xc0512e0f ssb_admatch_base +EXPORT_SYMBOL drivers/ssb/ssb 0xd029e4ef ssb_bus_unregister +EXPORT_SYMBOL drivers/ssb/ssb 0xd481192b ssb_admatch_size +EXPORT_SYMBOL drivers/ssb/ssb 0xe05fa98f ssb_dma_alloc_consistent +EXPORT_SYMBOL drivers/ssb/ssb 0xe351c81d ssb_pcicore_dev_irqvecs_enable +EXPORT_SYMBOL drivers/ssb/ssb 0xebcc3296 __ssb_driver_register +EXPORT_SYMBOL drivers/ssb/ssb 0xefacae02 ssb_bus_may_powerdown +EXPORT_SYMBOL drivers/ssb/ssb 0xefec92fb ssb_dma_translation +EXPORT_SYMBOL drivers/ssb/ssb 0xf1e067c0 ssb_bus_resume +EXPORT_SYMBOL drivers/ssb/ssb 0xf4b0445c ssb_set_devtypedata +EXPORT_SYMBOL drivers/telephony/ixj 0xd92498c2 ixj_pcmcia_probe +EXPORT_SYMBOL drivers/telephony/phonedev 0x0c3f562a phone_unregister_device +EXPORT_SYMBOL drivers/telephony/phonedev 0x2189adca phone_register_device +EXPORT_SYMBOL drivers/usb/gadget/dummy_hcd 0x3d35254c usb_gadget_register_driver +EXPORT_SYMBOL drivers/usb/gadget/dummy_hcd 0x91ba969e usb_gadget_unregister_driver +EXPORT_SYMBOL drivers/usb/gadget/dummy_hcd 0xbbc64535 net2280_set_fifo_mode +EXPORT_SYMBOL drivers/usb/host/sl811-hcd 0x725ecddd sl811h_driver +EXPORT_SYMBOL drivers/video/backlight/corgi_bl 0xc86baa7c corgibl_limit_intensity +EXPORT_SYMBOL drivers/video/backlight/lcd 0x07e62c04 lcd_device_register +EXPORT_SYMBOL drivers/video/backlight/lcd 0xa9c67fbc lcd_device_unregister +EXPORT_SYMBOL drivers/video/console/bitblit 0x8cc12c22 fbcon_set_bitops +EXPORT_SYMBOL drivers/video/console/font 0x09c8eb55 font_vga_8x16 +EXPORT_SYMBOL drivers/video/console/font 0xbb99125c get_default_font +EXPORT_SYMBOL drivers/video/console/font 0xf7584a9c find_font +EXPORT_SYMBOL drivers/video/console/softcursor 0xcde5eab0 soft_cursor +EXPORT_SYMBOL drivers/video/console/tileblit 0xc9ec2bb5 fbcon_set_tileops +EXPORT_SYMBOL drivers/video/cyber2000fb 0x050324de cyber2000fb_disable_extregs +EXPORT_SYMBOL drivers/video/cyber2000fb 0x0cc3ede5 cyber2000fb_detach +EXPORT_SYMBOL drivers/video/cyber2000fb 0x85893ae7 cyber2000fb_attach +EXPORT_SYMBOL drivers/video/cyber2000fb 0xbe9c5f59 cyber2000fb_get_fb_var +EXPORT_SYMBOL drivers/video/cyber2000fb 0xd4196aae cyber2000fb_enable_extregs +EXPORT_SYMBOL drivers/video/display/display 0x2137b5f4 display_device_unregister +EXPORT_SYMBOL drivers/video/display/display 0xac53975d display_device_register +EXPORT_SYMBOL drivers/video/macmodes 0x08ed0b62 mac_vmode_to_var +EXPORT_SYMBOL drivers/video/macmodes 0x0d9ecf34 mac_find_mode +EXPORT_SYMBOL drivers/video/macmodes 0xe2304303 mac_map_monitor_sense +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0x2cea0278 g450_mnp2f +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0x31c65143 matroxfb_g450_setpll_cond +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0x6d10e413 matroxfb_g450_setclk +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0x2e85e373 matrox_G100 +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0x31aaf133 DAC1064_global_restore +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0x927bc1fd matrox_mystique +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0xffad0d38 DAC1064_global_init +EXPORT_SYMBOL drivers/video/matrox/matroxfb_Ti3026 0x1eadd1ec matrox_millennium +EXPORT_SYMBOL drivers/video/matrox/matroxfb_accel 0x2f9a9f28 matrox_cfbX_init +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0x741d861e matroxfb_unregister_driver +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0x9a87d2f5 matroxfb_enable_irq +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0xd5bb65eb matroxfb_register_driver +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0xf4b72b4b matroxfb_wait_for_sync +EXPORT_SYMBOL drivers/video/matrox/matroxfb_g450 0x6eb16351 matroxfb_g450_shutdown +EXPORT_SYMBOL drivers/video/matrox/matroxfb_g450 0xb77c756d matroxfb_g450_connect +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x1311e13e matroxfb_vgaHWrestore +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x25cf8049 matroxfb_PLL_calcclock +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x5e96016e matroxfb_vgaHWinit +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0xa0df6df2 matroxfb_DAC_in +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0xabd8e427 matroxfb_var2my +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0xdff73773 matroxfb_DAC_out +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0xf6f6c16c matroxfb_read_pins +EXPORT_SYMBOL drivers/video/output 0x8a205396 video_output_register +EXPORT_SYMBOL drivers/video/output 0xfbbaabdc video_output_unregister +EXPORT_SYMBOL drivers/video/sis/sisfb 0x3037658e sis_malloc +EXPORT_SYMBOL drivers/video/sis/sisfb 0x454a3cf0 sis_free +EXPORT_SYMBOL drivers/video/svgalib 0x00d1fce9 svga_set_default_seq_regs +EXPORT_SYMBOL drivers/video/svgalib 0x07b3da30 svga_wseq_multi +EXPORT_SYMBOL drivers/video/svgalib 0x1b95c56a svga_check_timings +EXPORT_SYMBOL drivers/video/svgalib 0x2f50c40b svga_tilecursor +EXPORT_SYMBOL drivers/video/svgalib 0x513e9f65 svga_tileblit +EXPORT_SYMBOL drivers/video/svgalib 0x55bcf9a8 svga_settile +EXPORT_SYMBOL drivers/video/svgalib 0x55c6ad32 svga_tilefill +EXPORT_SYMBOL drivers/video/svgalib 0x63e898d1 svga_set_default_crt_regs +EXPORT_SYMBOL drivers/video/svgalib 0x6486adda svga_get_caps +EXPORT_SYMBOL drivers/video/svgalib 0x7a3ae959 svga_wcrt_multi +EXPORT_SYMBOL drivers/video/svgalib 0x80408443 svga_set_timings +EXPORT_SYMBOL drivers/video/svgalib 0x8fa8438b svga_set_textmode_vga_regs +EXPORT_SYMBOL drivers/video/svgalib 0xab3b22ad svga_set_default_gfx_regs +EXPORT_SYMBOL drivers/video/svgalib 0xd959a181 svga_tilecopy +EXPORT_SYMBOL drivers/video/svgalib 0xdad682b1 svga_set_default_atc_regs +EXPORT_SYMBOL drivers/video/svgalib 0xe1d7cee7 svga_get_tilemax +EXPORT_SYMBOL drivers/video/svgalib 0xec83c473 svga_match_format +EXPORT_SYMBOL drivers/video/svgalib 0xef774f5d svga_compute_pll +EXPORT_SYMBOL drivers/video/syscopyarea 0x96027e88 sys_copyarea +EXPORT_SYMBOL drivers/video/sysfillrect 0x9c7b18dd sys_fillrect +EXPORT_SYMBOL drivers/video/sysimgblt 0xb9e95906 sys_imageblit +EXPORT_SYMBOL drivers/video/vgastate 0x686de290 restore_vga +EXPORT_SYMBOL drivers/video/vgastate 0xe7a2620e save_vga +EXPORT_SYMBOL drivers/w1/slaves/w1_bq27000 0x12a2face w1_bq27000_write +EXPORT_SYMBOL drivers/w1/slaves/w1_bq27000 0xed142032 w1_bq27000_read +EXPORT_SYMBOL drivers/w1/slaves/w1_ds2760 0x1597cae7 w1_ds2760_read +EXPORT_SYMBOL drivers/w1/slaves/w1_ds2760 0xaaa7c65c w1_ds2760_write +EXPORT_SYMBOL drivers/w1/wire 0x02bed5c8 w1_unregister_family +EXPORT_SYMBOL drivers/w1/wire 0x18c202ea w1_add_master_device +EXPORT_SYMBOL drivers/w1/wire 0x28e7b5ec w1_remove_master_device +EXPORT_SYMBOL drivers/w1/wire 0xe440b712 w1_register_family +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0x04e133fc iTCO_vendor_check_noreboot_on +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0x672c9d44 iTCO_vendor_pre_keepalive +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xa78bd894 iTCO_vendor_pre_set_heartbeat +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xa8d6daac iTCO_vendor_pre_start +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xd0efe320 iTCO_vendor_pre_stop +EXPORT_SYMBOL fs/configfs/configfs 0x10fe2451 configfs_undepend_item +EXPORT_SYMBOL fs/configfs/configfs 0x19ebf19b config_item_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0x5399c7f3 config_item_init +EXPORT_SYMBOL fs/configfs/configfs 0x555ab1d8 configfs_depend_item +EXPORT_SYMBOL fs/configfs/configfs 0x6d34e075 configfs_register_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0x92601909 configfs_unregister_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0xa0f6c135 config_item_put +EXPORT_SYMBOL fs/configfs/configfs 0xa1cf56cf config_group_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0xa750e5d9 config_group_find_item +EXPORT_SYMBOL fs/configfs/configfs 0xd45a6ca6 config_item_set_name +EXPORT_SYMBOL fs/configfs/configfs 0xf166c617 config_item_get +EXPORT_SYMBOL fs/configfs/configfs 0xf8da3fd7 config_group_init +EXPORT_SYMBOL fs/lockd/lockd 0x38a3c7da nlmsvc_ops +EXPORT_SYMBOL fs/lockd/lockd 0xa7b91a7b lockd_down +EXPORT_SYMBOL fs/lockd/lockd 0xf6933c48 lockd_up +EXPORT_SYMBOL fs/nfs_common/nfs_acl 0x9f22b68f nfsacl_decode +EXPORT_SYMBOL fs/nfs_common/nfs_acl 0xea4dec89 nfsacl_encode +EXPORT_SYMBOL fs/nfsd/nfsd 0x23f0a2c8 nfs4_acl_nfsv4_to_posix +EXPORT_SYMBOL fs/nfsd/nfsd 0x35e33c1e nfs4_acl_write_who +EXPORT_SYMBOL fs/nfsd/nfsd 0x46ffdc39 nfs4_acl_posix_to_nfsv4 +EXPORT_SYMBOL fs/nfsd/nfsd 0x5a157ae4 nfs4_acl_get_whotype +EXPORT_SYMBOL fs/nfsd/nfsd 0x96ce9bb4 nfs4_acl_new +EXPORT_SYMBOL fs/xfs/xfs 0x06ebf741 xfs_qmcore_xfs +EXPORT_SYMBOL lib/crc-ccitt 0x651c2313 crc_ccitt +EXPORT_SYMBOL lib/crc-ccitt 0x75811312 crc_ccitt_table +EXPORT_SYMBOL lib/crc-itu-t 0x276c7e62 crc_itu_t +EXPORT_SYMBOL lib/crc-itu-t 0xd29b009f crc_itu_t_table +EXPORT_SYMBOL lib/crc7 0xc086bfba crc7 +EXPORT_SYMBOL lib/crc7 0xd80c3603 crc7_syndrome_table +EXPORT_SYMBOL lib/libcrc32c 0x13c0c38e crc32c_le +EXPORT_SYMBOL lib/libcrc32c 0x41bcd8b3 crc32c_be +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0x315c65fd zlib_deflateInit2 +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0x48034724 zlib_deflateReset +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xaf64ad0d zlib_deflate +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xf0caf44b zlib_deflate_workspacesize +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xf741c793 zlib_deflateEnd +EXPORT_SYMBOL net/802/p8023 0x74323c9b make_8023_client +EXPORT_SYMBOL net/802/p8023 0xe0ea8821 destroy_8023_client +EXPORT_SYMBOL net/9p/9pnet 0x029a693d p9_client_walk +EXPORT_SYMBOL net/9p/9pnet 0x08ee3bfc p9_client_wstat +EXPORT_SYMBOL net/9p/9pnet 0x0b3ac49a p9pdu_dump +EXPORT_SYMBOL net/9p/9pnet 0x0ce66b90 p9_client_remove +EXPORT_SYMBOL net/9p/9pnet 0x11a8e7c8 p9_client_clunk +EXPORT_SYMBOL net/9p/9pnet 0x160dd0c2 v9fs_unregister_trans +EXPORT_SYMBOL net/9p/9pnet 0x244c6d40 p9_idpool_get +EXPORT_SYMBOL net/9p/9pnet 0x2d4949e9 p9_client_write +EXPORT_SYMBOL net/9p/9pnet 0x3d73a797 p9_errstr2errno +EXPORT_SYMBOL net/9p/9pnet 0x41e6bc51 p9_parse_header +EXPORT_SYMBOL net/9p/9pnet 0x47141098 p9_client_open +EXPORT_SYMBOL net/9p/9pnet 0x5734bdb3 p9_client_cb +EXPORT_SYMBOL net/9p/9pnet 0x5e0ef374 p9_idpool_check +EXPORT_SYMBOL net/9p/9pnet 0x5e6d5179 p9_client_auth +EXPORT_SYMBOL net/9p/9pnet 0x61852dea p9_idpool_put +EXPORT_SYMBOL net/9p/9pnet 0x67e0b648 p9_client_stat +EXPORT_SYMBOL net/9p/9pnet 0x6c5e479c p9_idpool_create +EXPORT_SYMBOL net/9p/9pnet 0x76b79bf1 p9stat_read +EXPORT_SYMBOL net/9p/9pnet 0x79472263 v9fs_get_default_trans +EXPORT_SYMBOL net/9p/9pnet 0x7fcbcded v9fs_register_trans +EXPORT_SYMBOL net/9p/9pnet 0x8b21990d p9_client_create +EXPORT_SYMBOL net/9p/9pnet 0x9c964743 p9stat_free +EXPORT_SYMBOL net/9p/9pnet 0xa78787fd p9_client_disconnect +EXPORT_SYMBOL net/9p/9pnet 0xaa1596e9 p9_client_attach +EXPORT_SYMBOL net/9p/9pnet 0xb31e80bc p9_client_fcreate +EXPORT_SYMBOL net/9p/9pnet 0xbaa17b44 p9_idpool_destroy +EXPORT_SYMBOL net/9p/9pnet 0xc83ea934 p9_client_destroy +EXPORT_SYMBOL net/9p/9pnet 0xca8b4a1a p9_client_version +EXPORT_SYMBOL net/9p/9pnet 0xccdf7c0f v9fs_get_trans_by_name +EXPORT_SYMBOL net/9p/9pnet 0xd1e17491 p9_tag_lookup +EXPORT_SYMBOL net/9p/9pnet 0xe3bebafe p9_client_read +EXPORT_SYMBOL net/9p/9pnet 0xe58a3360 p9_error_init +EXPORT_SYMBOL net/appletalk/appletalk 0x107877ed atrtr_get_dev +EXPORT_SYMBOL net/appletalk/appletalk 0x683ddbba alloc_ltalkdev +EXPORT_SYMBOL net/appletalk/appletalk 0x9e19cddc aarp_send_ddp +EXPORT_SYMBOL net/appletalk/appletalk 0xb9e251a5 atalk_find_dev_addr +EXPORT_SYMBOL net/ax25/ax25 0x0479d44f ax25_findbyuid +EXPORT_SYMBOL net/ax25/ax25 0x1955e1c2 ax25_rebuild_header +EXPORT_SYMBOL net/ax25/ax25 0x1ab238f5 ax25_hard_header +EXPORT_SYMBOL net/ax25/ax25 0x2023afd2 ax25_find_cb +EXPORT_SYMBOL net/ax25/ax25 0x242852b9 ax25_uid_policy +EXPORT_SYMBOL net/ax25/ax25 0x3d2d82ec ax25_display_timer +EXPORT_SYMBOL net/ax25/ax25 0x4502c65a asc2ax +EXPORT_SYMBOL net/ax25/ax25 0x4a1bfbeb ax25_send_frame +EXPORT_SYMBOL net/ax25/ax25 0x53dea1ff ax2asc +EXPORT_SYMBOL net/ax25/ax25 0x6b4a5b83 ax25_header_ops +EXPORT_SYMBOL net/ax25/ax25 0x712f4cdf ax25_linkfail_register +EXPORT_SYMBOL net/ax25/ax25 0x83235b9a ax25_listen_register +EXPORT_SYMBOL net/ax25/ax25 0x8ede9e26 ax25_protocol_release +EXPORT_SYMBOL net/ax25/ax25 0xc1444946 ax25cmp +EXPORT_SYMBOL net/ax25/ax25 0xcd9bf19c ax25_listen_release +EXPORT_SYMBOL net/ax25/ax25 0xd43ecbf1 null_ax25_address +EXPORT_SYMBOL net/ax25/ax25 0xe59fa4f0 ax25_linkfail_release +EXPORT_SYMBOL net/bridge/bridge 0x5ca39b32 br_should_route_hook +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0x10779d17 ebt_unregister_table +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0x4ad1a9e5 ebt_register_table +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0xb9b50b0b ebt_do_table +EXPORT_SYMBOL net/ieee80211/ieee80211 0x060fb12f ieee80211_get_channel_flags +EXPORT_SYMBOL net/ieee80211/ieee80211 0x147d33c6 ieee80211_freq_to_channel +EXPORT_SYMBOL net/ieee80211/ieee80211 0x21d15068 ieee80211_wx_get_encodeext +EXPORT_SYMBOL net/ieee80211/ieee80211 0x360c8f86 ieee80211_rx_mgt +EXPORT_SYMBOL net/ieee80211/ieee80211 0x372440cf ieee80211_channel_to_freq +EXPORT_SYMBOL net/ieee80211/ieee80211 0x493eb11c ieee80211_wx_get_encode +EXPORT_SYMBOL net/ieee80211/ieee80211 0x510e1f20 ieee80211_is_valid_channel +EXPORT_SYMBOL net/ieee80211/ieee80211 0x5ef67fc9 ieee80211_get_geo +EXPORT_SYMBOL net/ieee80211/ieee80211 0x853785c1 ieee80211_txb_free +EXPORT_SYMBOL net/ieee80211/ieee80211 0x8dfd0507 ieee80211_wx_set_encode +EXPORT_SYMBOL net/ieee80211/ieee80211 0xa0bf3775 ieee80211_channel_to_index +EXPORT_SYMBOL net/ieee80211/ieee80211 0xa9fb135f escape_essid +EXPORT_SYMBOL net/ieee80211/ieee80211 0xb366e48b ieee80211_wx_set_encodeext +EXPORT_SYMBOL net/ieee80211/ieee80211 0xb5418393 ieee80211_set_geo +EXPORT_SYMBOL net/ieee80211/ieee80211 0xba56042e alloc_ieee80211 +EXPORT_SYMBOL net/ieee80211/ieee80211 0xc761852c ieee80211_rx +EXPORT_SYMBOL net/ieee80211/ieee80211 0xda4bcfee free_ieee80211 +EXPORT_SYMBOL net/ieee80211/ieee80211 0xebe81936 ieee80211_networks_age +EXPORT_SYMBOL net/ieee80211/ieee80211 0xec2968f0 ieee80211_get_channel +EXPORT_SYMBOL net/ieee80211/ieee80211 0xf8dd08eb ieee80211_wx_get_scan +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x15a3f5d7 ieee80211_crypt_delayed_deinit +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x279e265f ieee80211_crypt_deinit_handler +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x35d418dc ieee80211_register_crypto_ops +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x85df8d13 ieee80211_crypt_quiescing +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x8d5d6b35 ieee80211_get_crypto_ops +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x94001580 ieee80211_crypt_deinit_entries +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0xca44d2f2 ieee80211_unregister_crypto_ops +EXPORT_SYMBOL net/ipv4/inet_lro 0x1c3571ce lro_receive_skb +EXPORT_SYMBOL net/ipv4/inet_lro 0x67a81f52 lro_flush_all +EXPORT_SYMBOL net/ipv4/inet_lro 0x7491fb4e lro_vlan_hwaccel_receive_skb +EXPORT_SYMBOL net/ipv4/inet_lro 0xa62178e4 lro_flush_pkt +EXPORT_SYMBOL net/ipv4/inet_lro 0xee561c7e lro_vlan_hwaccel_receive_frags +EXPORT_SYMBOL net/ipv4/inet_lro 0xfd05a75d lro_receive_frags +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x0a0b62a0 arpt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x9553cc88 arpt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0xa89bd2a5 arpt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0x24b7f399 ipt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0xb24166ce ipt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0xcd8e353b ipt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x093387d2 nf_nat_setup_info +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x397f130b nf_nat_protocol_register +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x561b9a30 nf_nat_protocol_unregister +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x614c9d7f nf_nat_follow_master +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x61ef1530 nf_nat_mangle_udp_packet +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0xbb2b6e52 nf_nat_mangle_tcp_packet +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0xcf5f7ac6 nf_nat_used_tuple +EXPORT_SYMBOL net/ipv4/tunnel4 0x5aa99d76 xfrm4_tunnel_deregister +EXPORT_SYMBOL net/ipv4/tunnel4 0xab0af138 xfrm4_tunnel_register +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x0167de9d ip6t_register_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x01cd2e95 ipv6_find_hdr +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x5245476d ip6t_do_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x5fe18cec ip6t_unregister_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xb8bddf33 ip6t_ext_hdr +EXPORT_SYMBOL net/ipv6/tunnel6 0x344bfab7 xfrm6_tunnel_deregister +EXPORT_SYMBOL net/ipv6/tunnel6 0x5a15e353 xfrm6_tunnel_register +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0x9cd013f2 xfrm6_tunnel_alloc_spi +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0xab14e193 xfrm6_tunnel_free_spi +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0xdb1b42d1 xfrm6_tunnel_spi_lookup +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x36afa602 ircomm_control_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x587a95c6 ircomm_connect_response +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x6aedd015 ircomm_close +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x73787663 ircomm_flow_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x9b6079da ircomm_open +EXPORT_SYMBOL net/irda/ircomm/ircomm 0xb62da6ae ircomm_connect_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0xd0f4cf66 ircomm_disconnect_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0xd505f341 ircomm_data_request +EXPORT_SYMBOL net/irda/irda 0x01d1fcdb hashbin_delete +EXPORT_SYMBOL net/irda/irda 0x06a3ee58 irias_new_integer_value +EXPORT_SYMBOL net/irda/irda 0x072e026f irias_add_octseq_attrib +EXPORT_SYMBOL net/irda/irda 0x07d3647c irlmp_register_service +EXPORT_SYMBOL net/irda/irda 0x1068c113 irttp_connect_request +EXPORT_SYMBOL net/irda/irda 0x1726003f iriap_getvaluebyclass_request +EXPORT_SYMBOL net/irda/irda 0x1cbe465f irda_device_set_media_busy +EXPORT_SYMBOL net/irda/irda 0x1e6c4f64 proc_irda +EXPORT_SYMBOL net/irda/irda 0x2036ad06 irda_param_insert +EXPORT_SYMBOL net/irda/irda 0x32f19039 irttp_flow_request +EXPORT_SYMBOL net/irda/irda 0x3462950f hashbin_remove +EXPORT_SYMBOL net/irda/irda 0x3631112a async_unwrap_char +EXPORT_SYMBOL net/irda/irda 0x38a20e5b irda_debug +EXPORT_SYMBOL net/irda/irda 0x448b8aaa irda_qos_bits_to_value +EXPORT_SYMBOL net/irda/irda 0x46c1c4a2 irlmp_unregister_service +EXPORT_SYMBOL net/irda/irda 0x4cb5523c alloc_irdadev +EXPORT_SYMBOL net/irda/irda 0x4e7db259 irlmp_connect_request +EXPORT_SYMBOL net/irda/irda 0x5c2d0cda async_wrap_skb +EXPORT_SYMBOL net/irda/irda 0x5ca96dc4 irttp_disconnect_request +EXPORT_SYMBOL net/irda/irda 0x654c7e81 irttp_udata_request +EXPORT_SYMBOL net/irda/irda 0x6758f8ac irias_new_object +EXPORT_SYMBOL net/irda/irda 0x68b7447c hashbin_find +EXPORT_SYMBOL net/irda/irda 0x6b043eba irda_init_max_qos_capabilies +EXPORT_SYMBOL net/irda/irda 0x6f91f9e7 irlap_open +EXPORT_SYMBOL net/irda/irda 0x7042bc54 irlmp_register_client +EXPORT_SYMBOL net/irda/irda 0x747d6779 irias_delete_object +EXPORT_SYMBOL net/irda/irda 0x7621e908 hashbin_insert +EXPORT_SYMBOL net/irda/irda 0x76243bc9 irias_insert_object +EXPORT_SYMBOL net/irda/irda 0x763e54a4 irlmp_unregister_client +EXPORT_SYMBOL net/irda/irda 0x7745f266 irlap_close +EXPORT_SYMBOL net/irda/irda 0x781e2db5 irias_find_object +EXPORT_SYMBOL net/irda/irda 0x7957f728 irlmp_update_client +EXPORT_SYMBOL net/irda/irda 0x7a57b6f3 hashbin_remove_this +EXPORT_SYMBOL net/irda/irda 0x91815586 irda_param_pack +EXPORT_SYMBOL net/irda/irda 0x993ad14b irda_param_extract_all +EXPORT_SYMBOL net/irda/irda 0x9f1c93c8 irlmp_data_request +EXPORT_SYMBOL net/irda/irda 0xa3accaf4 irttp_data_request +EXPORT_SYMBOL net/irda/irda 0xaafef94d irttp_open_tsap +EXPORT_SYMBOL net/irda/irda 0xb07156bf iriap_open +EXPORT_SYMBOL net/irda/irda 0xb9394173 irias_delete_value +EXPORT_SYMBOL net/irda/irda 0xbcd3ef13 irias_object_change_attribute +EXPORT_SYMBOL net/irda/irda 0xbe40ace9 irlmp_discovery_request +EXPORT_SYMBOL net/irda/irda 0xbee2ae01 irlmp_connect_response +EXPORT_SYMBOL net/irda/irda 0xc14e9b6a hashbin_get_next +EXPORT_SYMBOL net/irda/irda 0xc6d36e31 irttp_connect_response +EXPORT_SYMBOL net/irda/irda 0xcd41236c hashbin_new +EXPORT_SYMBOL net/irda/irda 0xd6b266d5 irlmp_disconnect_request +EXPORT_SYMBOL net/irda/irda 0xd6deeaae irda_setup_dma +EXPORT_SYMBOL net/irda/irda 0xd7172ff4 hashbin_get_first +EXPORT_SYMBOL net/irda/irda 0xd8bfb6d4 hashbin_lock_find +EXPORT_SYMBOL net/irda/irda 0xd9b024fa irttp_close_tsap +EXPORT_SYMBOL net/irda/irda 0xdb64f8dc irlmp_close_lsap +EXPORT_SYMBOL net/irda/irda 0xde4c6b3c irlmp_service_to_hint +EXPORT_SYMBOL net/irda/irda 0xe5260e0e irias_add_integer_attrib +EXPORT_SYMBOL net/irda/irda 0xec41fe7f irias_add_string_attrib +EXPORT_SYMBOL net/irda/irda 0xedd521c2 irlmp_get_discoveries +EXPORT_SYMBOL net/irda/irda 0xf0ea5b96 irda_notify_init +EXPORT_SYMBOL net/irda/irda 0xf8e5180e iriap_close +EXPORT_SYMBOL net/irda/irda 0xfd778f75 irttp_dup +EXPORT_SYMBOL net/irda/irda 0xfe1cd3e3 irlmp_open_lsap +EXPORT_SYMBOL net/lapb/lapb 0x09a88385 lapb_getparms +EXPORT_SYMBOL net/lapb/lapb 0x1ab8aaa7 lapb_disconnect_request +EXPORT_SYMBOL net/lapb/lapb 0x2ec10340 lapb_connect_request +EXPORT_SYMBOL net/lapb/lapb 0x4cdc5541 lapb_data_received +EXPORT_SYMBOL net/lapb/lapb 0x70577819 lapb_setparms +EXPORT_SYMBOL net/lapb/lapb 0xa0231801 lapb_unregister +EXPORT_SYMBOL net/lapb/lapb 0xb43b7095 lapb_data_request +EXPORT_SYMBOL net/lapb/lapb 0xce32ee4d lapb_register +EXPORT_SYMBOL net/mac80211/mac80211 0x08228b21 ieee80211_tx_status +EXPORT_SYMBOL net/mac80211/mac80211 0x085269e5 ieee80211_stop_tx_ba_session +EXPORT_SYMBOL net/mac80211/mac80211 0x189b3560 ieee80211_wake_queue +EXPORT_SYMBOL net/mac80211/mac80211 0x18e4be16 ieee80211_scan_completed +EXPORT_SYMBOL net/mac80211/mac80211 0x1fae2c72 ieee80211_start_tx_ba_cb +EXPORT_SYMBOL net/mac80211/mac80211 0x25cbbda9 ieee80211_register_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x2771de65 ieee80211_rate_control_register +EXPORT_SYMBOL net/mac80211/mac80211 0x2ca13350 ieee80211_get_buffered_bc +EXPORT_SYMBOL net/mac80211/mac80211 0x30e0ce5b ieee80211_tx_status_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x331df38d ieee80211_stop_tx_ba_cb +EXPORT_SYMBOL net/mac80211/mac80211 0x39ed1882 ieee80211_stop_queue +EXPORT_SYMBOL net/mac80211/mac80211 0x3b159617 ieee80211_wake_queues +EXPORT_SYMBOL net/mac80211/mac80211 0x41f3d137 __ieee80211_get_radio_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x446a6953 ieee80211_ctstoself_duration +EXPORT_SYMBOL net/mac80211/mac80211 0x5f2c8e51 ieee80211_free_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x625c72d0 __ieee80211_get_assoc_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x67385434 ieee80211_get_hdrlen_from_skb +EXPORT_SYMBOL net/mac80211/mac80211 0x6cd3d91c __ieee80211_rx +EXPORT_SYMBOL net/mac80211/mac80211 0x7436a56c ieee80211_stop_queues +EXPORT_SYMBOL net/mac80211/mac80211 0x76758222 ieee80211_alloc_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x7b3bccad __ieee80211_get_rx_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x7f305ba2 ieee80211_find_sta +EXPORT_SYMBOL net/mac80211/mac80211 0x8a6331a7 ieee80211_rts_get +EXPORT_SYMBOL net/mac80211/mac80211 0x8a6adfdd ieee80211_rts_duration +EXPORT_SYMBOL net/mac80211/mac80211 0x8c35d732 ieee80211_hdrlen +EXPORT_SYMBOL net/mac80211/mac80211 0x8cf32f16 ieee80211_start_tx_ba_cb_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x97e21c41 wiphy_to_hw +EXPORT_SYMBOL net/mac80211/mac80211 0xa2f392f3 ieee80211_unregister_hw +EXPORT_SYMBOL net/mac80211/mac80211 0xa5780c96 ieee80211_generic_frame_duration +EXPORT_SYMBOL net/mac80211/mac80211 0xb006e36b ieee80211_queue_stopped +EXPORT_SYMBOL net/mac80211/mac80211 0xb4355840 __ieee80211_get_tx_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0xbceb637a ieee80211_get_tkip_key +EXPORT_SYMBOL net/mac80211/mac80211 0xc7f51a89 ieee80211_rx_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0xcef43733 ieee80211_rate_control_unregister +EXPORT_SYMBOL net/mac80211/mac80211 0xd2b4d38d ieee80211_beacon_get +EXPORT_SYMBOL net/mac80211/mac80211 0xee2a13fc ieee80211_ctstoself_get +EXPORT_SYMBOL net/mac80211/mac80211 0xf96b979d ieee80211_stop_tx_ba_cb_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0xfd0950db ieee80211_start_tx_ba_session +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x17a65385 unregister_ip_vs_scheduler +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x215c0602 ip_vs_conn_new +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x4ab630fc ip_vs_tcp_conn_listen +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x4f3e3168 ip_vs_conn_put +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x763462e5 unregister_ip_vs_app +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x7c533504 ip_vs_conn_in_get +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x80032532 ip_vs_conn_out_get +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x8386e332 register_ip_vs_app_inc +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xa1dbc2d8 ip_vs_proto_name +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xb8e8f458 register_ip_vs_scheduler +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xd838d9fc register_ip_vs_app +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xe30ca082 ip_vs_skb_replace +EXPORT_SYMBOL net/netfilter/nf_conntrack 0x8fb4ee7a __nf_ct_ext_destroy +EXPORT_SYMBOL net/netfilter/nf_conntrack 0xe372c1b6 __nf_ct_ext_add +EXPORT_SYMBOL net/netfilter/nf_conntrack_proto_gre 0x7937209a nf_ct_gre_keymap_flush +EXPORT_SYMBOL net/netfilter/x_tables 0x09f928ea xt_find_match +EXPORT_SYMBOL net/netfilter/x_tables 0x3dcd58c5 xt_alloc_table_info +EXPORT_SYMBOL net/netfilter/x_tables 0x5851432b xt_register_targets +EXPORT_SYMBOL net/netfilter/x_tables 0x5bfad9f3 xt_unregister_targets +EXPORT_SYMBOL net/netfilter/x_tables 0x765f8557 xt_unregister_target +EXPORT_SYMBOL net/netfilter/x_tables 0xabd46db5 xt_register_target +EXPORT_SYMBOL net/netfilter/x_tables 0xc6f16bc8 xt_unregister_matches +EXPORT_SYMBOL net/netfilter/x_tables 0xcd60aed9 xt_find_target +EXPORT_SYMBOL net/netfilter/x_tables 0xdc462e0e xt_register_matches +EXPORT_SYMBOL net/netfilter/x_tables 0xe0c3c0f9 xt_register_match +EXPORT_SYMBOL net/netfilter/x_tables 0xf7037dc6 xt_free_table_info +EXPORT_SYMBOL net/netfilter/x_tables 0xfd5e72e9 xt_unregister_match +EXPORT_SYMBOL net/phonet/phonet 0x02b16a0c pn_skb_send +EXPORT_SYMBOL net/phonet/phonet 0x08febbf3 phonet_header_ops +EXPORT_SYMBOL net/phonet/phonet 0x1106a4be phonet_proto_register +EXPORT_SYMBOL net/phonet/phonet 0x13fa16a5 pn_sock_hash +EXPORT_SYMBOL net/phonet/phonet 0x26b54660 pn_sock_get_port +EXPORT_SYMBOL net/phonet/phonet 0x43b82849 pn_sock_unhash +EXPORT_SYMBOL net/phonet/phonet 0x89d47352 phonet_proto_unregister +EXPORT_SYMBOL net/phonet/phonet 0x9d66fe33 phonet_stream_ops +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x18be3534 rxrpc_kernel_accept_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x21c7e940 rxrpc_kernel_is_data_last +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x344e577b rxrpc_kernel_reject_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x474ce1ff rxrpc_kernel_abort_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x499668fe rxrpc_kernel_send_data +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x580e7e00 rxrpc_kernel_end_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x6795a6d3 key_type_rxrpc +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x70c56c75 rxrpc_kernel_begin_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x7f136cb1 rxrpc_get_server_data_key +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x84438924 rxrpc_kernel_get_error_number +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x95f91085 rxrpc_kernel_get_abort_code +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xb0b0eb1b rxrpc_kernel_free_skb +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xd3b48148 rxrpc_kernel_data_delivered +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xdc342317 rxrpc_get_null_key +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xf55a4051 rxrpc_kernel_intercept_rx_messages +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x00c52ef5 g_make_token_header +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x1b74ab7a gss_mech_put +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x4d203cef gss_mech_get_by_name +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x4f328f81 gss_mech_register +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x8d1a827e svcauth_gss_register_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x90a44498 gss_svc_to_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xa7623331 gss_pseudoflavor_to_service +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xa7fcc285 gss_mech_get +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xb3146ec4 gss_mech_get_by_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xb5dea7ef g_token_size +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xcaa4524c svcauth_gss_flavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xdde79bfb gss_service_to_auth_domain_name +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xe2dbcb33 gss_mech_unregister +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xf8b2ff6e g_verify_token_header +EXPORT_SYMBOL net/sunrpc/sunrpc 0x02c424af svc_seq_show +EXPORT_SYMBOL net/sunrpc/sunrpc 0x05e807a9 xdr_encode_string +EXPORT_SYMBOL net/sunrpc/sunrpc 0x065994f1 xdr_encode_opaque_fixed +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0ae96559 unix_domain_find +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0b3d2b49 xdr_enter_page +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0c21eca7 sunrpc_cache_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0f668ba9 svc_auth_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x12e280e3 svc_proc_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x1d57a21d xdr_inline_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0x251e14ad svc_prepare_thread +EXPORT_SYMBOL net/sunrpc/sunrpc 0x25dbd661 svc_set_num_threads +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2919b156 xdr_decode_string_inplace +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2ba53ef7 cache_check +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2e401365 xdr_buf_subsegment +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2eec63c9 xdr_encode_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0x50e39896 cache_purge +EXPORT_SYMBOL net/sunrpc/sunrpc 0x5146aed4 read_bytes_from_xdr_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0x528a3158 xdr_write_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0x56ee9ab2 svc_auth_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0x6eea229d svcauth_unix_purge +EXPORT_SYMBOL net/sunrpc/sunrpc 0x71d765b7 xdr_decode_word +EXPORT_SYMBOL net/sunrpc/sunrpc 0x71fa908a cache_flush +EXPORT_SYMBOL net/sunrpc/sunrpc 0x752598e6 xdr_decode_array2 +EXPORT_SYMBOL net/sunrpc/sunrpc 0x7829f18d sunrpc_cache_update +EXPORT_SYMBOL net/sunrpc/sunrpc 0x785bdadd cache_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0x7e9d84a1 rpc_unlink +EXPORT_SYMBOL net/sunrpc/sunrpc 0x82121833 xdr_buf_from_iov +EXPORT_SYMBOL net/sunrpc/sunrpc 0x84e66963 auth_domain_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0x886dee72 rpc_mkpipe +EXPORT_SYMBOL net/sunrpc/sunrpc 0x8a52e726 svc_authenticate +EXPORT_SYMBOL net/sunrpc/sunrpc 0x8e0039cb xdr_buf_read_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0x92929a9f svc_reserve +EXPORT_SYMBOL net/sunrpc/sunrpc 0x976cf9b2 svc_sock_update_bufs +EXPORT_SYMBOL net/sunrpc/sunrpc 0x9f7f5755 svcauth_unix_set_client +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa281cf78 svc_sock_names +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa4b9f1bb svc_destroy +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa63bf43f svc_process +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa8dcacf8 auth_unix_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0xaa66bfc7 auth_domain_find +EXPORT_SYMBOL net/sunrpc/sunrpc 0xaaf34f46 auth_domain_put +EXPORT_SYMBOL net/sunrpc/sunrpc 0xb3ae1e4f auth_unix_forget_old +EXPORT_SYMBOL net/sunrpc/sunrpc 0xb65ccd2f xdr_reserve_space +EXPORT_SYMBOL net/sunrpc/sunrpc 0xb7790a42 svc_recv +EXPORT_SYMBOL net/sunrpc/sunrpc 0xb8574a97 cache_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc3880471 xdr_decode_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc48ea26f svc_proc_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc51d9167 svc_wake_up +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc77c89e4 xdr_shift_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc8e96dea qword_addhex +EXPORT_SYMBOL net/sunrpc/sunrpc 0xced899bb svc_drop +EXPORT_SYMBOL net/sunrpc/sunrpc 0xcf4aef05 xdr_encode_array2 +EXPORT_SYMBOL net/sunrpc/sunrpc 0xcf83ad74 xdr_read_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0xd60c71f7 svc_create +EXPORT_SYMBOL net/sunrpc/sunrpc 0xda84ea51 xdr_encode_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0xdac125b2 svc_exit_thread +EXPORT_SYMBOL net/sunrpc/sunrpc 0xdee34d88 auth_unix_add_addr +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe28ba4fd xdr_process_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe5919cb1 xdr_encode_opaque +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe8a1df54 svc_create_pooled +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe97f4ce5 qword_get +EXPORT_SYMBOL net/sunrpc/sunrpc 0xedac8f2c xdr_encode_word +EXPORT_SYMBOL net/sunrpc/sunrpc 0xedcf6be4 qword_add +EXPORT_SYMBOL net/sunrpc/sunrpc 0xf06beabc xdr_init_encode +EXPORT_SYMBOL net/sunrpc/sunrpc 0xf0799ac1 rpc_queue_upcall +EXPORT_SYMBOL net/sunrpc/sunrpc 0xf4197150 xdr_init_decode +EXPORT_SYMBOL net/sunrpc/sunrpc 0xf8d32f5f xdr_inline_decode +EXPORT_SYMBOL net/sunrpc/sunrpc 0xfcceb775 svc_set_client +EXPORT_SYMBOL net/tipc/tipc 0x086f02a2 tipc_send_buf +EXPORT_SYMBOL net/tipc/tipc 0x08acf310 tipc_available_nodes +EXPORT_SYMBOL net/tipc/tipc 0x0b074a7b tipc_multicast +EXPORT_SYMBOL net/tipc/tipc 0x10d40fcd tipc_isconnected +EXPORT_SYMBOL net/tipc/tipc 0x1472b270 tipc_disconnect +EXPORT_SYMBOL net/tipc/tipc 0x1479cb03 tipc_deleteport +EXPORT_SYMBOL net/tipc/tipc 0x15b5ecde tipc_set_portunreliable +EXPORT_SYMBOL net/tipc/tipc 0x16f27683 tipc_block_bearer +EXPORT_SYMBOL net/tipc/tipc 0x23daecbd tipc_send +EXPORT_SYMBOL net/tipc/tipc 0x259b74f9 tipc_acknowledge +EXPORT_SYMBOL net/tipc/tipc 0x28d26670 tipc_register_media +EXPORT_SYMBOL net/tipc/tipc 0x2c8d2f2b tipc_createport +EXPORT_SYMBOL net/tipc/tipc 0x310d1bc9 tipc_detach +EXPORT_SYMBOL net/tipc/tipc 0x3712e340 tipc_portunreliable +EXPORT_SYMBOL net/tipc/tipc 0x3976041f tipc_set_portimportance +EXPORT_SYMBOL net/tipc/tipc 0x401be2a2 tipc_send_buf_fast +EXPORT_SYMBOL net/tipc/tipc 0x419b02fc tipc_send2port +EXPORT_SYMBOL net/tipc/tipc 0x4b2243c6 tipc_portimportance +EXPORT_SYMBOL net/tipc/tipc 0x538b228a tipc_withdraw +EXPORT_SYMBOL net/tipc/tipc 0x54d9a95d tipc_send_buf2port +EXPORT_SYMBOL net/tipc/tipc 0x5637ed44 tipc_get_mode +EXPORT_SYMBOL net/tipc/tipc 0x56e52bc1 tipc_continue +EXPORT_SYMBOL net/tipc/tipc 0x5c0d4b5c tipc_ref_valid +EXPORT_SYMBOL net/tipc/tipc 0x62a681a3 tipc_portunreturnable +EXPORT_SYMBOL net/tipc/tipc 0x88b73627 tipc_get_addr +EXPORT_SYMBOL net/tipc/tipc 0x94b2b5b2 tipc_forward_buf2name +EXPORT_SYMBOL net/tipc/tipc 0x9c45558e tipc_enable_bearer +EXPORT_SYMBOL net/tipc/tipc 0xa1b42d32 tipc_forward2port +EXPORT_SYMBOL net/tipc/tipc 0xa75c5aeb tipc_recv_msg +EXPORT_SYMBOL net/tipc/tipc 0xa936a24b tipc_get_port +EXPORT_SYMBOL net/tipc/tipc 0xadd203d0 tipc_connect2port +EXPORT_SYMBOL net/tipc/tipc 0xae0103c3 tipc_shutdown +EXPORT_SYMBOL net/tipc/tipc 0xb1f8eacc tipc_send2name +EXPORT_SYMBOL net/tipc/tipc 0xb35b672c tipc_publish +EXPORT_SYMBOL net/tipc/tipc 0xb7f7cf09 tipc_forward_buf2port +EXPORT_SYMBOL net/tipc/tipc 0xcec8514a tipc_set_portunreturnable +EXPORT_SYMBOL net/tipc/tipc 0xcee290be tipc_forward2name +EXPORT_SYMBOL net/tipc/tipc 0xd44731e5 tipc_ownidentity +EXPORT_SYMBOL net/tipc/tipc 0xda7f9d3f tipc_attach +EXPORT_SYMBOL net/tipc/tipc 0xdf5008fc tipc_peer +EXPORT_SYMBOL net/tipc/tipc 0xe4f744f2 tipc_send_buf2name +EXPORT_SYMBOL net/tipc/tipc 0xe7aece47 tipc_ispublished +EXPORT_SYMBOL net/tipc/tipc 0xeefd49b3 tipc_get_handle +EXPORT_SYMBOL net/tipc/tipc 0xef50a1ef tipc_disable_bearer +EXPORT_SYMBOL net/tipc/tipc 0xf6e5e581 tipc_createport_raw +EXPORT_SYMBOL net/tipc/tipc 0xfc1627e5 tipc_reject_msg +EXPORT_SYMBOL net/wanrouter/wanrouter 0x0b4ccab1 register_wan_device +EXPORT_SYMBOL net/wanrouter/wanrouter 0x0ebe03d1 unregister_wan_device +EXPORT_SYMBOL net/wireless/cfg80211 0x07e7ac5a ieee80211_radiotap_iterator_init +EXPORT_SYMBOL net/wireless/cfg80211 0x09c64fbd ieee80211_frequency_to_channel +EXPORT_SYMBOL net/wireless/cfg80211 0x3645fc28 __ieee80211_get_channel +EXPORT_SYMBOL net/wireless/cfg80211 0x48deb77b wiphy_free +EXPORT_SYMBOL net/wireless/cfg80211 0x4cd156de wiphy_register +EXPORT_SYMBOL net/wireless/cfg80211 0x8c4ea500 wiphy_unregister +EXPORT_SYMBOL net/wireless/cfg80211 0x9d0489ca regulatory_hint +EXPORT_SYMBOL net/wireless/cfg80211 0xc4e85ec5 ieee80211_radiotap_iterator_next +EXPORT_SYMBOL net/wireless/cfg80211 0xccc291b3 ieee80211_channel_to_frequency +EXPORT_SYMBOL net/wireless/cfg80211 0xe09d8877 wiphy_new +EXPORT_SYMBOL sound/ac97_bus 0x07918f29 ac97_bus_type +EXPORT_SYMBOL sound/core/oss/snd-mixer-oss 0x200ad6d2 snd_mixer_oss_ioctl_card +EXPORT_SYMBOL sound/core/seq/snd-seq 0x1a724fcc snd_seq_kernel_client_ctl +EXPORT_SYMBOL sound/core/seq/snd-seq 0x2b9824d3 snd_seq_create_kernel_client +EXPORT_SYMBOL sound/core/seq/snd-seq 0x3061c52d snd_use_lock_sync_helper +EXPORT_SYMBOL sound/core/seq/snd-seq 0x3fb4d161 snd_seq_kernel_client_dispatch +EXPORT_SYMBOL sound/core/seq/snd-seq 0x6bb71038 snd_seq_delete_kernel_client +EXPORT_SYMBOL sound/core/seq/snd-seq 0x7ac2f329 snd_seq_expand_var_event +EXPORT_SYMBOL sound/core/seq/snd-seq 0x7b8699eb snd_seq_event_port_detach +EXPORT_SYMBOL sound/core/seq/snd-seq 0x8d486972 snd_seq_kernel_client_enqueue_blocking +EXPORT_SYMBOL sound/core/seq/snd-seq 0xb8e448a0 snd_seq_set_queue_tempo +EXPORT_SYMBOL sound/core/seq/snd-seq 0xc5e18e51 snd_seq_kernel_client_write_poll +EXPORT_SYMBOL sound/core/seq/snd-seq 0xcac0a3be snd_seq_kernel_client_enqueue +EXPORT_SYMBOL sound/core/seq/snd-seq 0xd5dcc83e snd_seq_event_port_attach +EXPORT_SYMBOL sound/core/seq/snd-seq 0xe934da1d snd_seq_dump_var_event +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x3a57f235 snd_seq_autoload_unlock +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x6339b6d0 snd_seq_device_load_drivers +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xb90668b2 snd_seq_autoload_lock +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xc622fb29 snd_seq_device_unregister_driver +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xd51bfe6f snd_seq_device_register_driver +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xe0cc79a0 snd_seq_device_new +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0x6ea09972 snd_midi_channel_alloc_set +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0x833a3e07 snd_midi_channel_set_clear +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0xb9948d2c snd_midi_channel_free_set +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0xf0a1fdb3 snd_midi_process_event +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x17c15809 snd_midi_event_decode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x4ad3f518 snd_midi_event_reset_decode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x62384d3a snd_midi_event_encode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x8a348811 snd_midi_event_reset_encode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x9df7af8b snd_midi_event_free +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xc482499d snd_midi_event_new +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xd9072e1a snd_midi_event_no_status +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xe6df29c7 snd_midi_event_encode_byte +EXPORT_SYMBOL sound/core/seq/snd-seq-virmidi 0xbc625809 snd_virmidi_new +EXPORT_SYMBOL sound/core/snd 0x15c65dcb snd_info_free_entry +EXPORT_SYMBOL sound/core/snd 0x18e1683f snd_dma_program +EXPORT_SYMBOL sound/core/snd 0x191e88cf snd_dma_pointer +EXPORT_SYMBOL sound/core/snd 0x198788b4 snd_lookup_oss_minor_data +EXPORT_SYMBOL sound/core/snd 0x1cf1b253 snd_device_new +EXPORT_SYMBOL sound/core/snd 0x24a94b26 snd_info_get_line +EXPORT_SYMBOL sound/core/snd 0x2a98c635 snd_power_wait +EXPORT_SYMBOL sound/core/snd 0x2ae3deaa release_and_free_resource +EXPORT_SYMBOL sound/core/snd 0x2b21f96f snd_register_oss_device +EXPORT_SYMBOL sound/core/snd 0x2bc174d0 snd_card_free +EXPORT_SYMBOL sound/core/snd 0x3971b4df snd_ecards_limit +EXPORT_SYMBOL sound/core/snd 0x39c671b9 snd_ctl_unregister_ioctl_compat +EXPORT_SYMBOL sound/core/snd 0x3cd618ca snd_ctl_notify +EXPORT_SYMBOL sound/core/snd 0x3f6c6bca snd_pci_quirk_lookup +EXPORT_SYMBOL sound/core/snd 0x41f573ca snd_info_register +EXPORT_SYMBOL sound/core/snd 0x428c00a4 snd_ctl_register_ioctl +EXPORT_SYMBOL sound/core/snd 0x45c3247d snd_ctl_boolean_mono_info +EXPORT_SYMBOL sound/core/snd 0x4a3ea5c0 snd_request_card +EXPORT_SYMBOL sound/core/snd 0x4cd1c6ec snd_ctl_remove +EXPORT_SYMBOL sound/core/snd 0x4e109350 snd_ctl_unregister_ioctl +EXPORT_SYMBOL sound/core/snd 0x4eae5ad0 snd_ctl_free_one +EXPORT_SYMBOL sound/core/snd 0x518bb7f8 copy_from_user_toio +EXPORT_SYMBOL sound/core/snd 0x5547650d snd_mixer_oss_notify_callback +EXPORT_SYMBOL sound/core/snd 0x57851758 snd_ctl_add +EXPORT_SYMBOL sound/core/snd 0x581aeb26 snd_card_proc_new +EXPORT_SYMBOL sound/core/snd 0x5e2b2c72 snd_device_free +EXPORT_SYMBOL sound/core/snd 0x63d7c993 snd_card_file_remove +EXPORT_SYMBOL sound/core/snd 0x6b94f55f snd_ctl_find_id +EXPORT_SYMBOL sound/core/snd 0x6c257e37 snd_ctl_register_ioctl_compat +EXPORT_SYMBOL sound/core/snd 0x70c15ac1 snd_dma_disable +EXPORT_SYMBOL sound/core/snd 0x71b229f9 snd_card_register +EXPORT_SYMBOL sound/core/snd 0x72f91e03 snd_device_register +EXPORT_SYMBOL sound/core/snd 0x75d963c7 snd_card_disconnect +EXPORT_SYMBOL sound/core/snd 0x7ec0440a snd_ctl_new1 +EXPORT_SYMBOL sound/core/snd 0x8a65ce0f snd_info_create_module_entry +EXPORT_SYMBOL sound/core/snd 0x8df3789f snd_oss_info_register +EXPORT_SYMBOL sound/core/snd 0x8f595b11 snd_major +EXPORT_SYMBOL sound/core/snd 0x9270a6b6 snd_unregister_oss_device +EXPORT_SYMBOL sound/core/snd 0x956ead8f snd_register_device_for_dev +EXPORT_SYMBOL sound/core/snd 0x9a9b1b18 snd_card_new +EXPORT_SYMBOL sound/core/snd 0x9b4e0101 snd_card_file_add +EXPORT_SYMBOL sound/core/snd 0x9cae4a65 snd_component_add +EXPORT_SYMBOL sound/core/snd 0xa316afe1 snd_ctl_add_slave +EXPORT_SYMBOL sound/core/snd 0xa33e1a09 snd_info_create_card_entry +EXPORT_SYMBOL sound/core/snd 0xaf765cd1 snd_card_free_when_closed +EXPORT_SYMBOL sound/core/snd 0xb213fe8b snd_info_get_str +EXPORT_SYMBOL sound/core/snd 0xb2e5ae4a snd_lookup_minor_data +EXPORT_SYMBOL sound/core/snd 0xda3ace2d snd_ctl_find_numid +EXPORT_SYMBOL sound/core/snd 0xde2b7038 snd_add_device_sysfs_file +EXPORT_SYMBOL sound/core/snd 0xdeaa266d snd_seq_root +EXPORT_SYMBOL sound/core/snd 0xe243dde3 copy_to_user_fromio +EXPORT_SYMBOL sound/core/snd 0xe4854cea snd_iprintf +EXPORT_SYMBOL sound/core/snd 0xe8a1bed7 snd_ctl_boolean_stereo_info +EXPORT_SYMBOL sound/core/snd 0xebc8c476 snd_cards +EXPORT_SYMBOL sound/core/snd 0xebcabc1e snd_ctl_rename_id +EXPORT_SYMBOL sound/core/snd 0xec040a1c snd_ctl_make_virtual_master +EXPORT_SYMBOL sound/core/snd 0xeeb13d65 snd_ctl_remove_id +EXPORT_SYMBOL sound/core/snd 0xef57da30 snd_unregister_device +EXPORT_SYMBOL sound/core/snd-hwdep 0x17db0fed snd_hwdep_new +EXPORT_SYMBOL sound/core/snd-page-alloc 0x19cc2ce3 snd_free_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0x2ca6c797 snd_dma_alloc_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0x399fe6f1 snd_dma_alloc_pages_fallback +EXPORT_SYMBOL sound/core/snd-page-alloc 0x5a1328a3 snd_dma_get_reserved_buf +EXPORT_SYMBOL sound/core/snd-page-alloc 0x5d2a3a58 snd_dma_reserve_buf +EXPORT_SYMBOL sound/core/snd-page-alloc 0xc6829020 snd_malloc_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0xf2d3e8c4 snd_dma_free_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x01b57d20 snd_pcm_lib_read +EXPORT_SYMBOL sound/core/snd-pcm 0x04cda566 snd_interval_refine +EXPORT_SYMBOL sound/core/snd-pcm 0x0712bfcd snd_pcm_new_stream +EXPORT_SYMBOL sound/core/snd-pcm 0x088723a7 snd_pcm_suspend_all +EXPORT_SYMBOL sound/core/snd-pcm 0x0d86e9b4 snd_pcm_lib_write +EXPORT_SYMBOL sound/core/snd-pcm 0x15279172 snd_pcm_hw_constraint_msbits +EXPORT_SYMBOL sound/core/snd-pcm 0x1d027e4b snd_pcm_format_signed +EXPORT_SYMBOL sound/core/snd-pcm 0x1e5588f9 snd_pcm_open_substream +EXPORT_SYMBOL sound/core/snd-pcm 0x1e98f682 snd_pcm_hw_param_last +EXPORT_SYMBOL sound/core/snd-pcm 0x22a7492b snd_pcm_hw_constraint_list +EXPORT_SYMBOL sound/core/snd-pcm 0x29eaf5e7 snd_pcm_lib_mmap_iomem +EXPORT_SYMBOL sound/core/snd-pcm 0x2d566e72 snd_pcm_lib_preallocate_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x31587bf6 snd_pcm_lib_malloc_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x35234838 snd_pcm_period_elapsed +EXPORT_SYMBOL sound/core/snd-pcm 0x353c86eb snd_pcm_lib_readv +EXPORT_SYMBOL sound/core/snd-pcm 0x367951bb snd_pcm_lib_ioctl +EXPORT_SYMBOL sound/core/snd-pcm 0x3796bdcc snd_pcm_format_little_endian +EXPORT_SYMBOL sound/core/snd-pcm 0x431a8ea8 snd_pcm_hw_constraint_step +EXPORT_SYMBOL sound/core/snd-pcm 0x43598bc4 snd_pcm_hw_constraint_ratnums +EXPORT_SYMBOL sound/core/snd-pcm 0x4e798027 snd_pcm_hw_constraint_integer +EXPORT_SYMBOL sound/core/snd-pcm 0x4f816e9b snd_pcm_format_big_endian +EXPORT_SYMBOL sound/core/snd-pcm 0x5293071c snd_pcm_hw_constraint_ratdens +EXPORT_SYMBOL sound/core/snd-pcm 0x5c473b94 snd_pcm_limit_hw_rates +EXPORT_SYMBOL sound/core/snd-pcm 0x5e7f4920 snd_pcm_format_set_silence +EXPORT_SYMBOL sound/core/snd-pcm 0x6067bfe0 snd_pcm_sgbuf_get_chunk_size +EXPORT_SYMBOL sound/core/snd-pcm 0x63f51c49 snd_pcm_hw_param_value +EXPORT_SYMBOL sound/core/snd-pcm 0x650f8603 snd_pcm_format_silence_64 +EXPORT_SYMBOL sound/core/snd-pcm 0x6622ab15 snd_pcm_hw_constraint_minmax +EXPORT_SYMBOL sound/core/snd-pcm 0x68a24153 snd_pcm_format_physical_width +EXPORT_SYMBOL sound/core/snd-pcm 0x6ef8fcd8 snd_pcm_format_linear +EXPORT_SYMBOL sound/core/snd-pcm 0x706d8bb6 snd_pcm_lib_preallocate_free_for_all +EXPORT_SYMBOL sound/core/snd-pcm 0x710f8896 snd_pcm_suspend +EXPORT_SYMBOL sound/core/snd-pcm 0x77b9ccac _snd_pcm_hw_param_setempty +EXPORT_SYMBOL sound/core/snd-pcm 0x785b3117 snd_pcm_sgbuf_ops_page +EXPORT_SYMBOL sound/core/snd-pcm 0x7a662d08 snd_pcm_stop +EXPORT_SYMBOL sound/core/snd-pcm 0x88cc66cc snd_pcm_link_rwlock +EXPORT_SYMBOL sound/core/snd-pcm 0x9051b1c6 snd_pcm_lib_preallocate_pages_for_all +EXPORT_SYMBOL sound/core/snd-pcm 0x952d5f21 _snd_pcm_hw_params_any +EXPORT_SYMBOL sound/core/snd-pcm 0x984b7f59 snd_pcm_hw_param_first +EXPORT_SYMBOL sound/core/snd-pcm 0x997b0323 snd_pcm_hw_rule_add +EXPORT_SYMBOL sound/core/snd-pcm 0xa3c4f675 snd_pcm_kernel_ioctl +EXPORT_SYMBOL sound/core/snd-pcm 0xa61aa028 snd_pcm_format_unsigned +EXPORT_SYMBOL sound/core/snd-pcm 0xadc422fc snd_pcm_notify +EXPORT_SYMBOL sound/core/snd-pcm 0xb1e1480f snd_pcm_lib_free_pages +EXPORT_SYMBOL sound/core/snd-pcm 0xb9638db4 snd_pcm_rate_to_rate_bit +EXPORT_SYMBOL sound/core/snd-pcm 0xc5057852 snd_pcm_hw_constraint_pow2 +EXPORT_SYMBOL sound/core/snd-pcm 0xc7d36e59 snd_pcm_set_ops +EXPORT_SYMBOL sound/core/snd-pcm 0xcd698603 snd_pcm_new +EXPORT_SYMBOL sound/core/snd-pcm 0xd0b9b8b8 snd_interval_list +EXPORT_SYMBOL sound/core/snd-pcm 0xd2e00486 snd_pcm_set_sync +EXPORT_SYMBOL sound/core/snd-pcm 0xdf06b3c3 snd_pcm_lib_writev +EXPORT_SYMBOL sound/core/snd-pcm 0xdfd4f3c5 snd_pcm_mmap_data +EXPORT_SYMBOL sound/core/snd-pcm 0xe51a1c64 snd_pcm_format_size +EXPORT_SYMBOL sound/core/snd-pcm 0xe56a9336 snd_pcm_format_width +EXPORT_SYMBOL sound/core/snd-pcm 0xe81fcd84 snd_pcm_release_substream +EXPORT_SYMBOL sound/core/snd-pcm 0xf3797152 snd_interval_ratnum +EXPORT_SYMBOL sound/core/snd-pcm 0xf797883b snd_pcm_hw_refine +EXPORT_SYMBOL sound/core/snd-rawmidi 0x004826ad snd_rawmidi_drain_output +EXPORT_SYMBOL sound/core/snd-rawmidi 0x02cf7bf5 snd_rawmidi_transmit_empty +EXPORT_SYMBOL sound/core/snd-rawmidi 0x0eeee389 snd_rawmidi_output_params +EXPORT_SYMBOL sound/core/snd-rawmidi 0x1d0eb425 snd_rawmidi_kernel_release +EXPORT_SYMBOL sound/core/snd-rawmidi 0x265f8cd8 snd_rawmidi_transmit_peek +EXPORT_SYMBOL sound/core/snd-rawmidi 0x31293dff snd_rawmidi_info_select +EXPORT_SYMBOL sound/core/snd-rawmidi 0x3c2f71eb snd_rawmidi_receive +EXPORT_SYMBOL sound/core/snd-rawmidi 0x521b6b23 snd_rawmidi_transmit +EXPORT_SYMBOL sound/core/snd-rawmidi 0x52e219f7 snd_rawmidi_input_params +EXPORT_SYMBOL sound/core/snd-rawmidi 0x567607a3 snd_rawmidi_drain_input +EXPORT_SYMBOL sound/core/snd-rawmidi 0x74d68721 snd_rawmidi_kernel_write +EXPORT_SYMBOL sound/core/snd-rawmidi 0x83b8df3f snd_rawmidi_set_ops +EXPORT_SYMBOL sound/core/snd-rawmidi 0x96c012b5 snd_rawmidi_new +EXPORT_SYMBOL sound/core/snd-rawmidi 0xbf6a9b6f snd_rawmidi_transmit_ack +EXPORT_SYMBOL sound/core/snd-rawmidi 0xf12c7ad8 snd_rawmidi_kernel_read +EXPORT_SYMBOL sound/core/snd-rawmidi 0xf89adb00 snd_rawmidi_drop_output +EXPORT_SYMBOL sound/core/snd-rawmidi 0xff1befbf snd_rawmidi_kernel_open +EXPORT_SYMBOL sound/core/snd-timer 0x09bbc2af snd_timer_global_new +EXPORT_SYMBOL sound/core/snd-timer 0x0a70b545 snd_timer_global_free +EXPORT_SYMBOL sound/core/snd-timer 0x0ebcb4f5 snd_timer_pause +EXPORT_SYMBOL sound/core/snd-timer 0x261eca76 snd_timer_start +EXPORT_SYMBOL sound/core/snd-timer 0x35272dac snd_timer_interrupt +EXPORT_SYMBOL sound/core/snd-timer 0x49fae34e snd_timer_open +EXPORT_SYMBOL sound/core/snd-timer 0x4f1ddb9b snd_timer_resolution +EXPORT_SYMBOL sound/core/snd-timer 0x5161a387 snd_timer_notify +EXPORT_SYMBOL sound/core/snd-timer 0xa0d9d174 snd_timer_stop +EXPORT_SYMBOL sound/core/snd-timer 0xc7c708e7 snd_timer_continue +EXPORT_SYMBOL sound/core/snd-timer 0xec064ad9 snd_timer_new +EXPORT_SYMBOL sound/core/snd-timer 0xfc4b07ac snd_timer_global_register +EXPORT_SYMBOL sound/core/snd-timer 0xfe72f880 snd_timer_close +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0x73c4c993 snd_mpu401_uart_interrupt_tx +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0xb186eb15 snd_mpu401_uart_new +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0xfe618b58 snd_mpu401_uart_interrupt +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x05060a19 snd_opl3_regmap +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x0a7eaced snd_opl3_init +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x1f8a5c4c snd_opl3_interrupt +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x21b8d810 snd_opl3_new +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x277d042c snd_opl3_find_patch +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x3bd2438c snd_opl3_reset +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x42fd2d0a snd_opl3_hwdep_new +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x59f003c3 snd_opl3_create +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x5dc7185e snd_opl3_timer_new +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x8de17dfc snd_opl3_load_patch +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x0f21d7d3 snd_vx_load_boot_image +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x1c5b887a snd_vx_create +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x1cadb14b snd_vx_irq_handler +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x3b36ad0a snd_vx_suspend +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x3ec64b29 snd_vx_dsp_boot +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x8af000bd snd_vx_check_reg_bit +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x9ec80b3f snd_vx_resume +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xa4e96ffc snd_vx_setup_firmware +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xcadb5afc snd_vx_free_firmware +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xd6348532 snd_vx_dsp_load +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x1d94ac49 snd_ak4114_reg_write +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x669f4291 snd_ak4114_reinit +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x752b5709 snd_ak4114_check_rate_and_errors +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x88b56b57 snd_ak4114_create +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0xb262e136 snd_ak4114_build +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0xec784061 snd_ak4114_external_rate +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0x3d5de68b snd_ak4117_reinit +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0x64b5c0aa snd_ak4117_build +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xbe50e729 snd_ak4117_create +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xdde3594d snd_ak4117_external_rate +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xe5cb3599 snd_ak4117_check_rate_and_errors +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xe8eaad88 snd_ak4117_reg_write +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0x373fcfc5 snd_akm4xxx_reset +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0xb24fb3f2 snd_akm4xxx_write +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0xd7828f05 snd_akm4xxx_init +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0xdd331f63 snd_akm4xxx_build_controls +EXPORT_SYMBOL sound/i2c/other/snd-pt2258 0x2c9eae69 snd_pt2258_build_controls +EXPORT_SYMBOL sound/i2c/other/snd-pt2258 0x54f28d51 snd_pt2258_reset +EXPORT_SYMBOL sound/i2c/other/snd-tea575x-tuner 0x67d9fa70 snd_tea575x_exit +EXPORT_SYMBOL sound/i2c/other/snd-tea575x-tuner 0xb010377a snd_tea575x_init +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x19ea1779 snd_cs8427_iec958_pcm +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x1ad0b328 snd_cs8427_iec958_active +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x82b01c5d snd_cs8427_iec958_build +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x99d3a875 snd_cs8427_reg_write +EXPORT_SYMBOL sound/i2c/snd-cs8427 0xb87bfc24 snd_cs8427_create +EXPORT_SYMBOL sound/i2c/snd-i2c 0x38b0cac8 snd_i2c_probeaddr +EXPORT_SYMBOL sound/i2c/snd-i2c 0x4edc52e1 snd_i2c_bus_create +EXPORT_SYMBOL sound/i2c/snd-i2c 0x5317d2e8 snd_i2c_device_create +EXPORT_SYMBOL sound/i2c/snd-i2c 0xbdbb4e68 snd_i2c_device_free +EXPORT_SYMBOL sound/i2c/snd-i2c 0xd49a2077 snd_i2c_readbytes +EXPORT_SYMBOL sound/i2c/snd-i2c 0xf482214b snd_i2c_sendbytes +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x0d165f28 snd_sbmixer_suspend +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x1068d71e snd_sbdsp_command +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x1bf76394 snd_sbmixer_resume +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x1c2d8730 snd_sbdsp_get_byte +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x32c80631 snd_sbmixer_add_ctl +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x382115b8 snd_sbdsp_create +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x38d7bc88 snd_sbmixer_write +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xa3d6b261 snd_sbdsp_reset +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xa40e2b8f snd_sbmixer_new +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xf1529acb snd_sbmixer_read +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0x0ba4ef1d snd_sb16dsp_interrupt +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0x281f4b44 snd_sb16dsp_get_pcm_ops +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0xd0145a0c snd_sb16dsp_pcm +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0xd2792e84 snd_sb16dsp_configure +EXPORT_SYMBOL sound/oss/ad1848 0x26c427ee ad1848_detect +EXPORT_SYMBOL sound/oss/ad1848 0x55262c70 probe_ms_sound +EXPORT_SYMBOL sound/oss/ad1848 0x9bf1cc62 ad1848_unload +EXPORT_SYMBOL sound/oss/ad1848 0xa4977c81 ad1848_init +EXPORT_SYMBOL sound/oss/ad1848 0xb29a9148 unload_ms_sound +EXPORT_SYMBOL sound/oss/ad1848 0xc04f6f67 ad1848_control +EXPORT_SYMBOL sound/oss/ad1848 0xeb556fe9 attach_ms_sound +EXPORT_SYMBOL sound/oss/mpu401 0x5febf284 unload_mpu401 +EXPORT_SYMBOL sound/oss/mpu401 0x81290ae9 attach_mpu401 +EXPORT_SYMBOL sound/oss/mpu401 0xd9ec5db4 probe_mpu401 +EXPORT_SYMBOL sound/oss/sb_lib 0x20cdf0b5 probe_sbmpu +EXPORT_SYMBOL sound/oss/sb_lib 0x42424109 sb_be_quiet +EXPORT_SYMBOL sound/oss/sb_lib 0x450f9aea smw_free +EXPORT_SYMBOL sound/oss/sb_lib 0x74afd69c unload_sbmpu +EXPORT_SYMBOL sound/oss/sb_lib 0xc4884969 sb_dsp_unload +EXPORT_SYMBOL sound/oss/sb_lib 0xd8a2731c sb_dsp_detect +EXPORT_SYMBOL sound/oss/sb_lib 0xfd5b1d1f sb_dsp_init +EXPORT_SYMBOL sound/oss/sound 0x04c87ec8 compute_finetune +EXPORT_SYMBOL sound/oss/sound 0x06339815 sound_unload_synthdev +EXPORT_SYMBOL sound/oss/sound 0x0f280035 conf_printf +EXPORT_SYMBOL sound/oss/sound 0x17ba231d seq_input_event +EXPORT_SYMBOL sound/oss/sound 0x1b3df3cf sound_alloc_mixerdev +EXPORT_SYMBOL sound/oss/sound 0x1f395686 MIDIbuf_avail +EXPORT_SYMBOL sound/oss/sound 0x2161d5e8 sound_timer_init +EXPORT_SYMBOL sound/oss/sound 0x2aa31695 midi_synth_kill_note +EXPORT_SYMBOL sound/oss/sound 0x3902725b midi_devs +EXPORT_SYMBOL sound/oss/sound 0x394cb088 sound_free_dma +EXPORT_SYMBOL sound/oss/sound 0x418f5fbe sound_close_dma +EXPORT_SYMBOL sound/oss/sound 0x4cd01bdd num_audiodevs +EXPORT_SYMBOL sound/oss/sound 0x4ff47e9d midi_synth_setup_voice +EXPORT_SYMBOL sound/oss/sound 0x51e354b2 sound_alloc_timerdev +EXPORT_SYMBOL sound/oss/sound 0x56504ca2 midi_synth_reset +EXPORT_SYMBOL sound/oss/sound 0x5d986fc9 note_to_freq +EXPORT_SYMBOL sound/oss/sound 0x6991e57f sound_timer_devs +EXPORT_SYMBOL sound/oss/sound 0x6b359fcb mixer_devs +EXPORT_SYMBOL sound/oss/sound 0x7679ee76 seq_copy_to_input +EXPORT_SYMBOL sound/oss/sound 0x7bdf0907 conf_printf2 +EXPORT_SYMBOL sound/oss/sound 0x87e480df synth_devs +EXPORT_SYMBOL sound/oss/sound 0x892093e0 midi_synth_controller +EXPORT_SYMBOL sound/oss/sound 0x90bd9714 sequencer_timer +EXPORT_SYMBOL sound/oss/sound 0x987bcf12 DMAbuf_outputintr +EXPORT_SYMBOL sound/oss/sound 0x9a95733f sound_alloc_dma +EXPORT_SYMBOL sound/oss/sound 0x9bdaf24d midi_synth_start_note +EXPORT_SYMBOL sound/oss/sound 0x9d845b18 num_mixers +EXPORT_SYMBOL sound/oss/sound 0xa1d5f04f load_mixer_volumes +EXPORT_SYMBOL sound/oss/sound 0xa1eae7cf num_midis +EXPORT_SYMBOL sound/oss/sound 0xa41ead5f sound_unload_timerdev +EXPORT_SYMBOL sound/oss/sound 0xa51c913b sound_unload_mixerdev +EXPORT_SYMBOL sound/oss/sound 0xa6bb414c sound_unload_mididev +EXPORT_SYMBOL sound/oss/sound 0xa948751e sound_unload_audiodev +EXPORT_SYMBOL sound/oss/sound 0xad45df73 midi_synth_close +EXPORT_SYMBOL sound/oss/sound 0xaef743b2 midi_synth_ioctl +EXPORT_SYMBOL sound/oss/sound 0xb14b22cd midi_synth_hw_control +EXPORT_SYMBOL sound/oss/sound 0xb350ab10 sound_install_mixer +EXPORT_SYMBOL sound/oss/sound 0xb3bf73a8 sound_install_audiodrv +EXPORT_SYMBOL sound/oss/sound 0xb51587f6 do_midi_msg +EXPORT_SYMBOL sound/oss/sound 0xba413f87 sound_alloc_mididev +EXPORT_SYMBOL sound/oss/sound 0xba7dd041 midi_synth_bender +EXPORT_SYMBOL sound/oss/sound 0xc748d109 sound_alloc_synthdev +EXPORT_SYMBOL sound/oss/sound 0xcc4b8797 sound_open_dma +EXPORT_SYMBOL sound/oss/sound 0xd85be938 midi_synth_set_instr +EXPORT_SYMBOL sound/oss/sound 0xdb400afa midi_synth_panning +EXPORT_SYMBOL sound/oss/sound 0xe056b71c DMAbuf_start_dma +EXPORT_SYMBOL sound/oss/sound 0xe2675a79 sound_timer_interrupt +EXPORT_SYMBOL sound/oss/sound 0xeb315d99 DMAbuf_inputintr +EXPORT_SYMBOL sound/oss/sound 0xf1ea8a20 midi_synth_aftertouch +EXPORT_SYMBOL sound/oss/sound 0xf6b3a2fb midi_synth_open +EXPORT_SYMBOL sound/oss/sound 0xf7426da3 midi_synth_load_patch +EXPORT_SYMBOL sound/oss/sound 0xf78f6363 sequencer_init +EXPORT_SYMBOL sound/oss/sound 0xfa6871be sound_timer_syncinterval +EXPORT_SYMBOL sound/oss/sound 0xfddcbfb3 midi_synth_send_sysex +EXPORT_SYMBOL sound/oss/sound 0xff84a03a audio_devs +EXPORT_SYMBOL sound/oss/uart401 0x46248c57 uart401intr +EXPORT_SYMBOL sound/oss/uart401 0x84351315 probe_uart401 +EXPORT_SYMBOL sound/oss/uart401 0xecfdd9c9 unload_uart401 +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x0cfc2203 snd_ac97_get_short_name +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x14f0545e snd_ac97_update +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x1802e59b snd_ac97_write +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x3f0dabce snd_ac97_update_power +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x4ce4d9c0 snd_ac97_pcm_assign +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x50e9b581 snd_ac97_read +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x61694b83 snd_ac97_update_bits +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x62271297 snd_ac97_write_cache +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x64d35c4a snd_ac97_resume +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x66465e8f snd_ac97_suspend +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x6c369ae8 snd_ac97_pcm_open +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x7edd8507 snd_ac97_pcm_double_rate_rules +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x962f3b5b snd_ac97_bus +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xb5cc654b snd_ac97_tune_hardware +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xc1ccef50 snd_ac97_pcm_close +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xdbb93515 snd_ac97_mixer +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xe658a44e snd_ac97_set_rate +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x0c67e6bc snd_emu10k1_ptr_write +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x78fbdcbe snd_emu10k1_voice_alloc +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x8e43570c snd_emu10k1_memblk_map +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x9bbeb287 snd_emu10k1_ptr_read +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xb295a8c6 snd_emu10k1_synth_alloc +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xcdbce9da snd_emu10k1_synth_free +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xd9a6a282 snd_emu10k1_voice_free +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xf2b985ce snd_emu10k1_synth_bzero +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xfe3f983e snd_emu10k1_synth_copy_from_user +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0x36dde1d2 snd_ice1712_akm4xxx_init +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0x4d17e64d snd_ice1712_akm4xxx_build_controls +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0xd023d69f snd_ice1712_akm4xxx_free +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x098ba0a8 oxygen_read_ac97 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x0bf82873 oxygen_write8 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x244e4762 oxygen_pci_suspend +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x2599918f oxygen_write_ac97 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x38316cd0 oxygen_write8_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x49a2900c oxygen_read16 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x4c85f65a oxygen_write16 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x54f3923b oxygen_write_ac97_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x5a06249f oxygen_read8 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x5cd5a745 oxygen_write_i2c +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x6fe1c556 oxygen_pci_probe +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x78386fe5 oxygen_write16_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x7db735b4 oxygen_write_uart +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x82b4502b oxygen_write32 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x8faf906b oxygen_write_spi +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xb0d04e50 oxygen_pci_remove +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xb638b09e oxygen_read32 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xd5fae012 oxygen_write32_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xe9763d5e oxygen_reset_uart +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xec7b16a7 oxygen_pci_resume +EXPORT_SYMBOL sound/pci/trident/snd-trident 0x7fc41554 snd_trident_alloc_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0xb547befc snd_trident_write_voice_regs +EXPORT_SYMBOL sound/pci/trident/snd-trident 0xcc6387ff snd_trident_stop_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0xd3041cee snd_trident_start_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0xe9aa6d20 snd_trident_free_voice +EXPORT_SYMBOL sound/sound_firmware 0x39e3dd23 mod_firmware_load +EXPORT_SYMBOL sound/soundcore 0x1e383422 register_sound_special_device +EXPORT_SYMBOL sound/soundcore 0x3ad7916b sound_class +EXPORT_SYMBOL sound/soundcore 0x6b6ca6fe register_sound_dsp +EXPORT_SYMBOL sound/soundcore 0x7afc9d8a unregister_sound_mixer +EXPORT_SYMBOL sound/soundcore 0x98959ab3 register_sound_mixer +EXPORT_SYMBOL sound/soundcore 0x99c95fa5 unregister_sound_special +EXPORT_SYMBOL sound/soundcore 0xcd083b10 unregister_sound_dsp +EXPORT_SYMBOL sound/soundcore 0xd53020b3 register_sound_special +EXPORT_SYMBOL sound/soundcore 0xe28f94bf register_sound_midi +EXPORT_SYMBOL sound/soundcore 0xfdab6de3 unregister_sound_midi +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x08a2fc07 snd_emux_register +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x3ec477a6 snd_emux_free +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x5d5a4711 snd_emux_lock_voice +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x655cb202 snd_sf_linear_to_log +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0xa24f2e56 snd_emux_terminate_all +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0xbeba3ee5 snd_emux_unlock_voice +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0xe16578d8 snd_emux_new +EXPORT_SYMBOL sound/synth/snd-util-mem 0x20d65978 snd_util_memhdr_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0x24886293 __snd_util_mem_alloc +EXPORT_SYMBOL sound/synth/snd-util-mem 0x569d614e snd_util_mem_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0x7a007343 snd_util_memhdr_new +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd197c5db __snd_util_memblk_new +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd34b56e4 __snd_util_mem_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd8b55e81 snd_util_mem_alloc +EXPORT_SYMBOL sound/synth/snd-util-mem 0xf158252c snd_util_mem_avail +EXPORT_SYMBOL sound/usb/snd-usb-lib 0x16756dc0 snd_usbmidi_input_start +EXPORT_SYMBOL sound/usb/snd-usb-lib 0x63343b1d snd_usbmidi_input_stop +EXPORT_SYMBOL sound/usb/snd-usb-lib 0xc63f8e43 snd_usb_create_midi_interface +EXPORT_SYMBOL sound/usb/snd-usb-lib 0xd9d2bb03 snd_usbmidi_disconnect +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x1538a700 dm_mem_cache_alloc +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x8397fa9b dm_mem_cache_client_create +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xaa3934fa dm_mem_cache_free +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xe10a68f0 dm_mem_cache_client_destroy +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xe58d61c9 dm_mem_cache_grow +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xec6ad524 dm_mem_cache_shrink +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-message 0x920a7a41 dm_message_parse +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x0050f52c rh_get_region_key +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x1a5edde8 rh_bio_to_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x275fdd04 rh_recovery_start +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x29e53a6b rh_dec +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x4b49baf9 rh_delay_by_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x5c2a0632 rh_recovery_end +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x62842029 rh_flush +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x83baca27 rh_state +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x87d45b9d rh_get_region_size +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x8c817c1b rh_inc_pending +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xa923d788 rh_start_recovery +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xac274ed3 rh_stop_recovery +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xb513be98 rh_update_states +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xbb748327 rh_reg_set_context +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xbd3452f9 rh_sector_to_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xbec97c36 rh_init +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc4fdf256 rh_recovery_prepare +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc4ff7745 rh_reg_get_context +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc57bafec rh_exit +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xe9f7f71a rh_region_to_sector +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xead50daa rh_delay +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xf3e0a2b0 rh_inc +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x29c887a9 set_tx_channels +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x7789312a cmdir_write +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0xf4c689aa cmdir_read +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0x61ea4c33 lirc_register_plugin +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0x78f8f267 lirc_get_pdata +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0xe96379eb lirc_unregister_plugin +EXPORT_SYMBOL ubuntu/misc/media/ov511/ov511 0x1b191f09 ov511_register_decomp_module +EXPORT_SYMBOL ubuntu/misc/media/ov511/ov511 0x7db9be3c ov511_deregister_decomp_module +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x0bdc41a4 wlan_unsetup +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x16cf8480 unregister_wlandev +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x2116f492 p80211wext_event_associated +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x298f31b5 p80211netdev_rx +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x311df397 p80211netdev_hwremoved +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x3f2ba908 wlan_setup +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x452a3ad6 p80211_suspend +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x481ce6b2 p80211_allow_ioctls +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x4bbf5a1c p80211skb_free +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x703f432c p80211_resume +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x755833c9 register_wlandev +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xb0af0799 wlan_wext_write +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xdf3b1fa0 p80211skb_rxmeta_attach +EXPORT_SYMBOL vmlinux 0x00000000 per_cpu__softirq_work_list +EXPORT_SYMBOL vmlinux 0x004c9840 sock_register +EXPORT_SYMBOL vmlinux 0x00502c91 dm_unregister_target +EXPORT_SYMBOL vmlinux 0x007ee135 blk_queue_resize_tags +EXPORT_SYMBOL vmlinux 0x00801678 flush_scheduled_work +EXPORT_SYMBOL vmlinux 0x0080fcd6 tcf_hash_release +EXPORT_SYMBOL vmlinux 0x009d258f _write_lock +EXPORT_SYMBOL vmlinux 0x00b3575c xfrm4_prepare_output +EXPORT_SYMBOL vmlinux 0x00c9f88d aio_complete +EXPORT_SYMBOL vmlinux 0x01000e51 schedule +EXPORT_SYMBOL vmlinux 0x0110da24 block_write_full_page +EXPORT_SYMBOL vmlinux 0x01139ffc max_mapnr +EXPORT_SYMBOL vmlinux 0x013930bf xfrm_bundle_ok +EXPORT_SYMBOL vmlinux 0x0186d073 percpu_counter_set +EXPORT_SYMBOL vmlinux 0x01902adf netpoll_trap +EXPORT_SYMBOL vmlinux 0x01a4aab6 set_irq_chip_data +EXPORT_SYMBOL vmlinux 0x01aea714 sk_stream_wait_memory +EXPORT_SYMBOL vmlinux 0x01b22d0d genl_sock +EXPORT_SYMBOL vmlinux 0x01bbcca7 sock_no_mmap +EXPORT_SYMBOL vmlinux 0x01cbfa48 flush_old_exec +EXPORT_SYMBOL vmlinux 0x01d19038 acpi_enable_subsystem +EXPORT_SYMBOL vmlinux 0x020dc66a netif_device_detach +EXPORT_SYMBOL vmlinux 0x02124474 ip_send_check +EXPORT_SYMBOL vmlinux 0x02138f9d bioset_integrity_create +EXPORT_SYMBOL vmlinux 0x02307437 pagecache_write_end +EXPORT_SYMBOL vmlinux 0x0237b57a arch_unregister_cpu +EXPORT_SYMBOL vmlinux 0x0256389f bit_waitqueue +EXPORT_SYMBOL vmlinux 0x02649054 security_sock_rcv_skb +EXPORT_SYMBOL vmlinux 0x02681888 load_nls_default +EXPORT_SYMBOL vmlinux 0x0270f66b proc_doulongvec_ms_jiffies_minmax +EXPORT_SYMBOL vmlinux 0x029444f0 native_read_tsc +EXPORT_SYMBOL vmlinux 0x02a18c74 nf_conntrack_destroy +EXPORT_SYMBOL vmlinux 0x02a6ce5a crc16_table +EXPORT_SYMBOL vmlinux 0x02aff2f4 acpi_install_gpe_handler +EXPORT_SYMBOL vmlinux 0x02c2f41d locks_init_lock +EXPORT_SYMBOL vmlinux 0x02d81845 audit_log_task_context +EXPORT_SYMBOL vmlinux 0x02db771b kernel_recvmsg +EXPORT_SYMBOL vmlinux 0x02eaee64 xfrm6_find_1stfragopt +EXPORT_SYMBOL vmlinux 0x02ec1563 generic_file_llseek_unlocked +EXPORT_SYMBOL vmlinux 0x030ad9c5 pci_remove_behind_bridge +EXPORT_SYMBOL vmlinux 0x0334da4e scsi_command_size_tbl +EXPORT_SYMBOL vmlinux 0x034ce6d7 put_filp +EXPORT_SYMBOL vmlinux 0x03585c8f tc_classify_compat +EXPORT_SYMBOL vmlinux 0x0360055e agp_alloc_bridge +EXPORT_SYMBOL vmlinux 0x036f3a7f ipv4_specific +EXPORT_SYMBOL vmlinux 0x037a0cba kfree +EXPORT_SYMBOL vmlinux 0x0388e7a1 kill_pid +EXPORT_SYMBOL vmlinux 0x039699d1 send_sig_info +EXPORT_SYMBOL vmlinux 0x03a99c3b rb_prev +EXPORT_SYMBOL vmlinux 0x03c06156 bitmap_fold +EXPORT_SYMBOL vmlinux 0x03fd2571 vm_unmap_ram +EXPORT_SYMBOL vmlinux 0x0411bcb9 netdev_features_change +EXPORT_SYMBOL vmlinux 0x0422fe4a inet_csk_timer_bug_msg +EXPORT_SYMBOL vmlinux 0x04358912 inet6_del_protocol +EXPORT_SYMBOL vmlinux 0x043b2d2b datagram_poll +EXPORT_SYMBOL vmlinux 0x043cd354 tty_port_tty_get +EXPORT_SYMBOL vmlinux 0x044fbf49 mempool_kzalloc +EXPORT_SYMBOL vmlinux 0x045c4781 bio_kmalloc +EXPORT_SYMBOL vmlinux 0x0487f831 fb_find_best_display +EXPORT_SYMBOL vmlinux 0x0489a8f9 simple_getattr +EXPORT_SYMBOL vmlinux 0x048f0b5e pci_release_region +EXPORT_SYMBOL vmlinux 0x04902d07 kmalloc_caches +EXPORT_SYMBOL vmlinux 0x04a22717 dev_mc_unsync +EXPORT_SYMBOL vmlinux 0x04d8c750 release_perfctr_nmi +EXPORT_SYMBOL vmlinux 0x04e03bd3 key_unlink +EXPORT_SYMBOL vmlinux 0x050aff81 dev_unicast_sync +EXPORT_SYMBOL vmlinux 0x051dafb6 ip6_route_output +EXPORT_SYMBOL vmlinux 0x05859091 skb_under_panic +EXPORT_SYMBOL vmlinux 0x058c75d9 acpi_get_pci_id +EXPORT_SYMBOL vmlinux 0x0598ff70 mark_page_accessed +EXPORT_SYMBOL vmlinux 0x05e28d43 __first_cpu +EXPORT_SYMBOL vmlinux 0x05eb1af0 tcp_timewait_state_process +EXPORT_SYMBOL vmlinux 0x061651be strcat +EXPORT_SYMBOL vmlinux 0x06673d5e serio_open +EXPORT_SYMBOL vmlinux 0x06706a56 proto_register +EXPORT_SYMBOL vmlinux 0x067d8d35 security_release_secctx +EXPORT_SYMBOL vmlinux 0x068040eb ip_route_me_harder +EXPORT_SYMBOL vmlinux 0x068c7263 ioremap_cache +EXPORT_SYMBOL vmlinux 0x06a485f2 __krealloc +EXPORT_SYMBOL vmlinux 0x06a53eb0 genphy_config_advert +EXPORT_SYMBOL vmlinux 0x06d2e999 task_tgid_nr_ns +EXPORT_SYMBOL vmlinux 0x06d728b1 tcp_parse_md5sig_option +EXPORT_SYMBOL vmlinux 0x06df0ac3 skb_clone +EXPORT_SYMBOL vmlinux 0x06fe3b14 default_grn +EXPORT_SYMBOL vmlinux 0x070b22d4 pci_iounmap +EXPORT_SYMBOL vmlinux 0x071f40f8 agp_generic_free_by_type +EXPORT_SYMBOL vmlinux 0x072628fd tty_register_driver +EXPORT_SYMBOL vmlinux 0x0727c4f3 iowrite8 +EXPORT_SYMBOL vmlinux 0x073dfa12 generate_resume_trace +EXPORT_SYMBOL vmlinux 0x0751f011 dquot_commit +EXPORT_SYMBOL vmlinux 0x0763cd92 write_cache_pages +EXPORT_SYMBOL vmlinux 0x076d59b8 pagevec_lookup +EXPORT_SYMBOL vmlinux 0x0770e7c4 scsi_free_command +EXPORT_SYMBOL vmlinux 0x0791f849 dm_table_unplug_all +EXPORT_SYMBOL vmlinux 0x0799aca4 local_bh_enable +EXPORT_SYMBOL vmlinux 0x079cd7f1 ns_to_timeval +EXPORT_SYMBOL vmlinux 0x07a00652 cpu_sysdev_class +EXPORT_SYMBOL vmlinux 0x07a423ba bio_pair_release +EXPORT_SYMBOL vmlinux 0x07a890c8 fb_alloc_cmap +EXPORT_SYMBOL vmlinux 0x07cc4a5d printk_timed_ratelimit +EXPORT_SYMBOL vmlinux 0x07d6581c atm_proc_root +EXPORT_SYMBOL vmlinux 0x07d9b783 scsi_nl_send_vendor_msg +EXPORT_SYMBOL vmlinux 0x0803458e xfrm_user_policy +EXPORT_SYMBOL vmlinux 0x082c3213 pci_root_buses +EXPORT_SYMBOL vmlinux 0x0845e96d textsearch_prepare +EXPORT_SYMBOL vmlinux 0x0853a3ef scsi_device_put +EXPORT_SYMBOL vmlinux 0x089208eb sock_create_lite +EXPORT_SYMBOL vmlinux 0x08c8c3e4 dmam_pool_destroy +EXPORT_SYMBOL vmlinux 0x08fef4f6 netif_carrier_off +EXPORT_SYMBOL vmlinux 0x092d9dd2 __xfrm_state_delete +EXPORT_SYMBOL vmlinux 0x0933aae1 efi_enabled +EXPORT_SYMBOL vmlinux 0x0948cde9 num_physpages +EXPORT_SYMBOL vmlinux 0x095dd691 alloc_file +EXPORT_SYMBOL vmlinux 0x0976c4d0 fb_validate_mode +EXPORT_SYMBOL vmlinux 0x09775cdc kref_get +EXPORT_SYMBOL vmlinux 0x098431ba acpi_get_current_resources +EXPORT_SYMBOL vmlinux 0x098b71c6 fb_dealloc_cmap +EXPORT_SYMBOL vmlinux 0x09947956 follow_down +EXPORT_SYMBOL vmlinux 0x09c55cec schedule_timeout_interruptible +EXPORT_SYMBOL vmlinux 0x09d44df9 in_lock_functions +EXPORT_SYMBOL vmlinux 0x09d62219 sock_wmalloc +EXPORT_SYMBOL vmlinux 0x09e3272a swiotlb_sync_single_for_device +EXPORT_SYMBOL vmlinux 0x09e9e866 tcf_exts_change +EXPORT_SYMBOL vmlinux 0x0a025c50 bh_uptodate_or_lock +EXPORT_SYMBOL vmlinux 0x0a2487e0 unblock_all_signals +EXPORT_SYMBOL vmlinux 0x0a586bd9 compat_mc_getsockopt +EXPORT_SYMBOL vmlinux 0x0a8dc420 try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x0ac93e9d ll_rw_block +EXPORT_SYMBOL vmlinux 0x0acb1a3c __bitmap_shift_right +EXPORT_SYMBOL vmlinux 0x0afd5ac6 bt_sock_link +EXPORT_SYMBOL vmlinux 0x0b0f23fe kmem_cache_size +EXPORT_SYMBOL vmlinux 0x0b1beb31 vmalloc_32_user +EXPORT_SYMBOL vmlinux 0x0b33d577 dma_async_memcpy_pg_to_pg +EXPORT_SYMBOL vmlinux 0x0b47ae83 generic_setlease +EXPORT_SYMBOL vmlinux 0x0b58408f tty_register_ldisc +EXPORT_SYMBOL vmlinux 0x0b742fd7 simple_strtol +EXPORT_SYMBOL vmlinux 0x0ba1c35c mmc_alloc_host +EXPORT_SYMBOL vmlinux 0x0bac70e2 tcp_v4_remember_stamp +EXPORT_SYMBOL vmlinux 0x0bb3e997 pci_dev_driver +EXPORT_SYMBOL vmlinux 0x0bc6950e blkdev_dequeue_request +EXPORT_SYMBOL vmlinux 0x0c5ef91b per_cpu__vm_event_states +EXPORT_SYMBOL vmlinux 0x0c65e73c scsi_normalize_sense +EXPORT_SYMBOL vmlinux 0x0c8c9e99 scsi_show_extd_sense +EXPORT_SYMBOL vmlinux 0x0ca7b7a8 acpi_check_region +EXPORT_SYMBOL vmlinux 0x0cb66005 __pskb_pull_tail +EXPORT_SYMBOL vmlinux 0x0cb96a0c proc_mkdir +EXPORT_SYMBOL vmlinux 0x0cbd71b6 ethtool_op_set_tx_ipv6_csum +EXPORT_SYMBOL vmlinux 0x0ce1eda9 inode_add_bytes +EXPORT_SYMBOL vmlinux 0x0cee6ad2 arp_create +EXPORT_SYMBOL vmlinux 0x0cf38c13 input_unregister_handle +EXPORT_SYMBOL vmlinux 0x0d26a76d _write_lock_irq +EXPORT_SYMBOL vmlinux 0x0d3be396 jbd2_journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x0d3dda14 acpi_get_type +EXPORT_SYMBOL vmlinux 0x0d513770 sock_no_sendpage +EXPORT_SYMBOL vmlinux 0x0d542439 __ipv6_addr_type +EXPORT_SYMBOL vmlinux 0x0d689a5f blk_rq_init +EXPORT_SYMBOL vmlinux 0x0d8ab500 param_set_copystring +EXPORT_SYMBOL vmlinux 0x0da10ec3 security_sock_graft +EXPORT_SYMBOL vmlinux 0x0db60990 input_get_keycode +EXPORT_SYMBOL vmlinux 0x0e0252ec downgrade_write +EXPORT_SYMBOL vmlinux 0x0e0b5818 generic_make_request +EXPORT_SYMBOL vmlinux 0x0e4b9195 sock_common_setsockopt +EXPORT_SYMBOL vmlinux 0x0e52592a panic +EXPORT_SYMBOL vmlinux 0x0e54afb4 generic_file_direct_write +EXPORT_SYMBOL vmlinux 0x0e610b16 hci_conn_change_link_key +EXPORT_SYMBOL vmlinux 0x0e762d6e request_module +EXPORT_SYMBOL vmlinux 0x0e81bd98 proc_dointvec_ms_jiffies +EXPORT_SYMBOL vmlinux 0x0ed488bd is_container_init +EXPORT_SYMBOL vmlinux 0x0f0a1f51 xfrm_unregister_km +EXPORT_SYMBOL vmlinux 0x0f144e0e __pagevec_release +EXPORT_SYMBOL vmlinux 0x0f1612f0 rtnl_unicast +EXPORT_SYMBOL vmlinux 0x0f20f19f agp_unbind_memory +EXPORT_SYMBOL vmlinux 0x0f695a88 xfrm_policy_walk +EXPORT_SYMBOL vmlinux 0x0f74dbe9 kblockd_schedule_work +EXPORT_SYMBOL vmlinux 0x0f8ef5ab tty_write_room +EXPORT_SYMBOL vmlinux 0x0f90bb98 lease_modify +EXPORT_SYMBOL vmlinux 0x0faef0ed __tasklet_schedule +EXPORT_SYMBOL vmlinux 0x0fc5e8eb radix_tree_gang_lookup_slot +EXPORT_SYMBOL vmlinux 0x0fcc5d45 inet_release +EXPORT_SYMBOL vmlinux 0x0fd00a68 acpi_clear_event +EXPORT_SYMBOL vmlinux 0x0ff2b602 slhc_compress +EXPORT_SYMBOL vmlinux 0x1029f56e neigh_table_init +EXPORT_SYMBOL vmlinux 0x106a2397 generic_file_aio_write +EXPORT_SYMBOL vmlinux 0x106aad55 sock_no_listen +EXPORT_SYMBOL vmlinux 0x1072a394 csum_partial_copy_from_user +EXPORT_SYMBOL vmlinux 0x107803e4 bio_map_kern +EXPORT_SYMBOL vmlinux 0x107f49a8 pci_set_power_state +EXPORT_SYMBOL vmlinux 0x108ca07e pci_prepare_to_sleep +EXPORT_SYMBOL vmlinux 0x109f5dce inet_frag_find +EXPORT_SYMBOL vmlinux 0x10a20a24 __seq_open_private +EXPORT_SYMBOL vmlinux 0x10d6faff ip_mc_dec_group +EXPORT_SYMBOL vmlinux 0x10ee20bb default_blu +EXPORT_SYMBOL vmlinux 0x11128496 ps2_cmd_aborted +EXPORT_SYMBOL vmlinux 0x11267875 scsi_extd_sense_format +EXPORT_SYMBOL vmlinux 0x113a23d4 submit_bio +EXPORT_SYMBOL vmlinux 0x11476bd1 find_or_create_page +EXPORT_SYMBOL vmlinux 0x11505636 dm_table_get_size +EXPORT_SYMBOL vmlinux 0x116240db key_instantiate_and_link +EXPORT_SYMBOL vmlinux 0x1163f0a7 blk_max_low_pfn +EXPORT_SYMBOL vmlinux 0x117093be qdisc_class_hash_init +EXPORT_SYMBOL vmlinux 0x117e9c36 get_disk +EXPORT_SYMBOL vmlinux 0x118f01ea putname +EXPORT_SYMBOL vmlinux 0x11a18b14 __wake_up_bit +EXPORT_SYMBOL vmlinux 0x11dab346 __down_read +EXPORT_SYMBOL vmlinux 0x1203262a pci_unmap_rom +EXPORT_SYMBOL vmlinux 0x120729ae make_bad_inode +EXPORT_SYMBOL vmlinux 0x120ceca2 ip_nat_decode_session +EXPORT_SYMBOL vmlinux 0x122cc2ea elv_dispatch_sort +EXPORT_SYMBOL vmlinux 0x12596cd6 jbd2_journal_load +EXPORT_SYMBOL vmlinux 0x125fbca7 cad_pid +EXPORT_SYMBOL vmlinux 0x126970ed param_set_uint +EXPORT_SYMBOL vmlinux 0x1282ae67 d_splice_alias +EXPORT_SYMBOL vmlinux 0x12854dc7 pci_save_state +EXPORT_SYMBOL vmlinux 0x12a3c827 cfb_imageblit +EXPORT_SYMBOL vmlinux 0x12c39f27 backlight_device_register +EXPORT_SYMBOL vmlinux 0x12f99022 inet_frags_init_net +EXPORT_SYMBOL vmlinux 0x131eeb12 blk_get_backing_dev_info +EXPORT_SYMBOL vmlinux 0x132f45f2 cookie_check_timestamp +EXPORT_SYMBOL vmlinux 0x13304daa tcp_setsockopt +EXPORT_SYMBOL vmlinux 0x1359bb1c d_invalidate +EXPORT_SYMBOL vmlinux 0x1374a41b generic_fillattr +EXPORT_SYMBOL vmlinux 0x1378e714 acpi_video_display_switch_support +EXPORT_SYMBOL vmlinux 0x137ac5a8 tty_register_device +EXPORT_SYMBOL vmlinux 0x1381b8de sock_kfree_s +EXPORT_SYMBOL vmlinux 0x1387e1e6 tcp_rcv_state_process +EXPORT_SYMBOL vmlinux 0x138b2518 sock_get_timestampns +EXPORT_SYMBOL vmlinux 0x138de5f2 dentry_open +EXPORT_SYMBOL vmlinux 0x13d75458 grab_cache_page_nowait +EXPORT_SYMBOL vmlinux 0x13dd2865 __skb_warn_lro_forwarding +EXPORT_SYMBOL vmlinux 0x13e41db9 filp_open +EXPORT_SYMBOL vmlinux 0x13e8fe2e nobh_write_end +EXPORT_SYMBOL vmlinux 0x13f6e920 simple_readpage +EXPORT_SYMBOL vmlinux 0x13f71731 tcf_hash_lookup +EXPORT_SYMBOL vmlinux 0x140e0279 jbd2_journal_force_commit +EXPORT_SYMBOL vmlinux 0x1430e6e0 unregister_acpi_notifier +EXPORT_SYMBOL vmlinux 0x143856e1 remap_vmalloc_range +EXPORT_SYMBOL vmlinux 0x145b7453 tty_hung_up_p +EXPORT_SYMBOL vmlinux 0x146118b1 thermal_cooling_device_unregister +EXPORT_SYMBOL vmlinux 0x1477548e acpi_root_dir +EXPORT_SYMBOL vmlinux 0x1477c728 flow_cache_lookup +EXPORT_SYMBOL vmlinux 0x1480fa25 mmc_suspend_host +EXPORT_SYMBOL vmlinux 0x14879f85 __bforget +EXPORT_SYMBOL vmlinux 0x14a4a0b9 blk_free_tags +EXPORT_SYMBOL vmlinux 0x14af0cf7 gen_pool_destroy +EXPORT_SYMBOL vmlinux 0x14b1f4d1 __kill_fasync +EXPORT_SYMBOL vmlinux 0x14dbd16d unregister_cdrom +EXPORT_SYMBOL vmlinux 0x1500a1b0 jbd2_journal_get_create_access +EXPORT_SYMBOL vmlinux 0x15076519 i2c_detach_client +EXPORT_SYMBOL vmlinux 0x150c296d misc_register +EXPORT_SYMBOL vmlinux 0x1523a019 blk_queue_end_tag +EXPORT_SYMBOL vmlinux 0x1544aad4 genl_register_mc_group +EXPORT_SYMBOL vmlinux 0x1551dc51 bitmap_find_free_region +EXPORT_SYMBOL vmlinux 0x1589b8d8 dquot_drop +EXPORT_SYMBOL vmlinux 0x15c8fad7 dquot_acquire +EXPORT_SYMBOL vmlinux 0x15ef2dd9 kfifo_free +EXPORT_SYMBOL vmlinux 0x15f4837e nf_log_packet +EXPORT_SYMBOL vmlinux 0x160211bc tcf_em_unregister +EXPORT_SYMBOL vmlinux 0x163472f7 hci_send_acl +EXPORT_SYMBOL vmlinux 0x1675606f bad_dma_address +EXPORT_SYMBOL vmlinux 0x167e7f9d __get_user_1 +EXPORT_SYMBOL vmlinux 0x16a35878 _read_unlock +EXPORT_SYMBOL vmlinux 0x16e6bcb3 dm_put_device +EXPORT_SYMBOL vmlinux 0x170c25ee acpi_get_next_object +EXPORT_SYMBOL vmlinux 0x172ed4d7 __vmalloc +EXPORT_SYMBOL vmlinux 0x1739832a security_sb_set_mnt_opts +EXPORT_SYMBOL vmlinux 0x173b74f2 agp_generic_alloc_page +EXPORT_SYMBOL vmlinux 0x17472522 journal_destroy +EXPORT_SYMBOL vmlinux 0x174eb704 uart_resume_port +EXPORT_SYMBOL vmlinux 0x1791caca pci_enable_msix +EXPORT_SYMBOL vmlinux 0x17931cd4 __dec_zone_page_state +EXPORT_SYMBOL vmlinux 0x17a76e71 rb_first +EXPORT_SYMBOL vmlinux 0x17ade817 agp_generic_mask_memory +EXPORT_SYMBOL vmlinux 0x17c09eaf set_pages_nx +EXPORT_SYMBOL vmlinux 0x17c85a66 radix_tree_tagged +EXPORT_SYMBOL vmlinux 0x17c95a8e compat_sock_get_timestamp +EXPORT_SYMBOL vmlinux 0x17d6c4bf tcp_rcv_established +EXPORT_SYMBOL vmlinux 0x17de15b6 do_splice_to +EXPORT_SYMBOL vmlinux 0x17df17bc sysctl_tcp_ecn +EXPORT_SYMBOL vmlinux 0x17eafeac set_pages_x +EXPORT_SYMBOL vmlinux 0x180d2d1d bdi_register_dev +EXPORT_SYMBOL vmlinux 0x18153faf bt_sock_poll +EXPORT_SYMBOL vmlinux 0x1815d57f generic_permission +EXPORT_SYMBOL vmlinux 0x181b6ff2 mempool_resize +EXPORT_SYMBOL vmlinux 0x183fa88b mempool_alloc_slab +EXPORT_SYMBOL vmlinux 0x18471524 pnp_device_detach +EXPORT_SYMBOL vmlinux 0x184dec25 fb_get_buffer_offset +EXPORT_SYMBOL vmlinux 0x18899507 agp_find_bridge +EXPORT_SYMBOL vmlinux 0x189b6bac memory_read_from_buffer +EXPORT_SYMBOL vmlinux 0x18a336a0 ipv6_chk_prefix +EXPORT_SYMBOL vmlinux 0x18b381bc mdiobus_register +EXPORT_SYMBOL vmlinux 0x18f5188a key_put +EXPORT_SYMBOL vmlinux 0x19006762 kobject_add +EXPORT_SYMBOL vmlinux 0x19079192 read_cache_page +EXPORT_SYMBOL vmlinux 0x190dc72d unregister_qdisc +EXPORT_SYMBOL vmlinux 0x19176123 neigh_for_each +EXPORT_SYMBOL vmlinux 0x192fd0a2 block_write_begin +EXPORT_SYMBOL vmlinux 0x1933b36b journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x19391763 iov_iter_fault_in_readable +EXPORT_SYMBOL vmlinux 0x1940c620 __xfrm_route_forward +EXPORT_SYMBOL vmlinux 0x1985ed3c prepare_to_wait_exclusive +EXPORT_SYMBOL vmlinux 0x199ed0cd net_disable_timestamp +EXPORT_SYMBOL vmlinux 0x19ac7490 ppp_register_channel +EXPORT_SYMBOL vmlinux 0x19cb2aa3 pci_clear_mwi +EXPORT_SYMBOL vmlinux 0x19d5d20a acpi_walk_namespace +EXPORT_SYMBOL vmlinux 0x19f36e4c dm_dirty_log_type_register +EXPORT_SYMBOL vmlinux 0x1a0cb885 i2c_put_adapter +EXPORT_SYMBOL vmlinux 0x1a0f7a9e ip_dev_find +EXPORT_SYMBOL vmlinux 0x1a18de0d jbd2_journal_update_format +EXPORT_SYMBOL vmlinux 0x1a1ab15d tty_mutex +EXPORT_SYMBOL vmlinux 0x1a1cbf6c pneigh_lookup +EXPORT_SYMBOL vmlinux 0x1a1d7bed dm_io_client_create +EXPORT_SYMBOL vmlinux 0x1a45cb6c acpi_disabled +EXPORT_SYMBOL vmlinux 0x1a5075fc path_permission +EXPORT_SYMBOL vmlinux 0x1a657c5c read_cache_page_async +EXPORT_SYMBOL vmlinux 0x1a7505be jbd2_journal_check_available_features +EXPORT_SYMBOL vmlinux 0x1a75caa3 _read_lock +EXPORT_SYMBOL vmlinux 0x1a8a845e idle_nomwait +EXPORT_SYMBOL vmlinux 0x1aa41e74 vfs_write +EXPORT_SYMBOL vmlinux 0x1aa9724f blk_put_request +EXPORT_SYMBOL vmlinux 0x1ac0950d unregister_sysrq_key +EXPORT_SYMBOL vmlinux 0x1ace138d bitmap_allocate_region +EXPORT_SYMBOL vmlinux 0x1ad2b9b8 inode_change_ok +EXPORT_SYMBOL vmlinux 0x1ae8d7dc param_set_invbool +EXPORT_SYMBOL vmlinux 0x1b015d25 bitmap_parselist +EXPORT_SYMBOL vmlinux 0x1b1bdd8c dquot_initialize +EXPORT_SYMBOL vmlinux 0x1b3b77bb file_permission +EXPORT_SYMBOL vmlinux 0x1b3c678a gen_new_estimator +EXPORT_SYMBOL vmlinux 0x1b4a5ae3 generic_file_open +EXPORT_SYMBOL vmlinux 0x1b4c94ef sock_init_data +EXPORT_SYMBOL vmlinux 0x1b4df3d7 unregister_filesystem +EXPORT_SYMBOL vmlinux 0x1b524da8 proc_dointvec_userhz_jiffies +EXPORT_SYMBOL vmlinux 0x1b6314fd in_aton +EXPORT_SYMBOL vmlinux 0x1b89419f add_wait_queue_exclusive +EXPORT_SYMBOL vmlinux 0x1b92facd tcp_parse_options +EXPORT_SYMBOL vmlinux 0x1b9981cc set_irq_wake +EXPORT_SYMBOL vmlinux 0x1b9e0ff1 scsilun_to_int +EXPORT_SYMBOL vmlinux 0x1ba40d85 do_SAK +EXPORT_SYMBOL vmlinux 0x1bcbc825 d_find_alias +EXPORT_SYMBOL vmlinux 0x1be8744f udp_disconnect +EXPORT_SYMBOL vmlinux 0x1c0e7f66 sb_has_dirty_inodes +EXPORT_SYMBOL vmlinux 0x1c2da9cf get_empty_filp +EXPORT_SYMBOL vmlinux 0x1c36ed22 sk_free +EXPORT_SYMBOL vmlinux 0x1c372d20 sk_release_kernel +EXPORT_SYMBOL vmlinux 0x1c56d004 brioctl_set +EXPORT_SYMBOL vmlinux 0x1c674a16 single_release +EXPORT_SYMBOL vmlinux 0x1c6d9ce1 scsi_host_get +EXPORT_SYMBOL vmlinux 0x1c7f59e4 journal_stop +EXPORT_SYMBOL vmlinux 0x1c87cc2d ip6_xmit +EXPORT_SYMBOL vmlinux 0x1cad252a uart_write_wakeup +EXPORT_SYMBOL vmlinux 0x1cc6719a register_reboot_notifier +EXPORT_SYMBOL vmlinux 0x1ceec59f sk_stream_wait_connect +EXPORT_SYMBOL vmlinux 0x1cefe352 wait_for_completion +EXPORT_SYMBOL vmlinux 0x1cf7cdde revalidate_disk +EXPORT_SYMBOL vmlinux 0x1d0883fc registered_fb +EXPORT_SYMBOL vmlinux 0x1d172f94 km_new_mapping +EXPORT_SYMBOL vmlinux 0x1d314be3 inet6_ioctl +EXPORT_SYMBOL vmlinux 0x1d3cfb6c d_rehash +EXPORT_SYMBOL vmlinux 0x1db3741e phy_driver_register +EXPORT_SYMBOL vmlinux 0x1db4fb1d d_prune_aliases +EXPORT_SYMBOL vmlinux 0x1db7706b __copy_user_nocache +EXPORT_SYMBOL vmlinux 0x1dc36131 fb_destroy_modedb +EXPORT_SYMBOL vmlinux 0x1dc9743d dev_mc_sync +EXPORT_SYMBOL vmlinux 0x1dd571e6 fb_copy_cmap +EXPORT_SYMBOL vmlinux 0x1df5cc80 swiotlb_map_single_attrs +EXPORT_SYMBOL vmlinux 0x1df868cf simple_rmdir +EXPORT_SYMBOL vmlinux 0x1e095613 skb_over_panic +EXPORT_SYMBOL vmlinux 0x1e0ab99b ip6_frag_init +EXPORT_SYMBOL vmlinux 0x1e0c94c1 netpoll_parse_options +EXPORT_SYMBOL vmlinux 0x1e103f06 xfrm_policy_insert +EXPORT_SYMBOL vmlinux 0x1e190fe1 dput +EXPORT_SYMBOL vmlinux 0x1e1ef162 inet_add_protocol +EXPORT_SYMBOL vmlinux 0x1e28cbfd task_session_nr_ns +EXPORT_SYMBOL vmlinux 0x1e2e427f cpumask_next_and +EXPORT_SYMBOL vmlinux 0x1e2f5175 agp_generic_destroy_page +EXPORT_SYMBOL vmlinux 0x1e3e3284 skb_copy_expand +EXPORT_SYMBOL vmlinux 0x1e52b1ba clear_inode +EXPORT_SYMBOL vmlinux 0x1e60f0af tcf_em_register +EXPORT_SYMBOL vmlinux 0x1e6d26a8 strstr +EXPORT_SYMBOL vmlinux 0x1e8d9d2a __set_page_dirty_buffers +EXPORT_SYMBOL vmlinux 0x1ea42fa6 unregister_nls +EXPORT_SYMBOL vmlinux 0x1eb922a3 IO_APIC_get_PCI_irq_vector +EXPORT_SYMBOL vmlinux 0x1ecbbd92 mmc_wait_for_cmd +EXPORT_SYMBOL vmlinux 0x1ee986a5 ip_mc_join_group +EXPORT_SYMBOL vmlinux 0x1efe283f __cap_full_set +EXPORT_SYMBOL vmlinux 0x1f04966f complete_request_key +EXPORT_SYMBOL vmlinux 0x1f1f59a3 mem_map +EXPORT_SYMBOL vmlinux 0x1f2067af textsearch_destroy +EXPORT_SYMBOL vmlinux 0x1f22da5c simple_sync_file +EXPORT_SYMBOL vmlinux 0x1f27d6d7 _write_unlock +EXPORT_SYMBOL vmlinux 0x1f48692e ppp_input +EXPORT_SYMBOL vmlinux 0x1f4ac055 acpi_processor_preregister_performance +EXPORT_SYMBOL vmlinux 0x1f58d936 pcix_get_max_mmrbc +EXPORT_SYMBOL vmlinux 0x1fb7df6b inet6_unregister_protosw +EXPORT_SYMBOL vmlinux 0x1fd623c6 force_sig +EXPORT_SYMBOL vmlinux 0x1ff36d03 sock_common_recvmsg +EXPORT_SYMBOL vmlinux 0x20000329 simple_strtoul +EXPORT_SYMBOL vmlinux 0x2005e68a acpi_remove_fixed_event_handler +EXPORT_SYMBOL vmlinux 0x20092385 acpi_enter_sleep_state_s4bios +EXPORT_SYMBOL vmlinux 0x201b3a0f jbd2_journal_start +EXPORT_SYMBOL vmlinux 0x201dbc8e unmap_underlying_metadata +EXPORT_SYMBOL vmlinux 0x2037f50a thermal_zone_bind_cooling_device +EXPORT_SYMBOL vmlinux 0x203c53a2 skb_queue_purge +EXPORT_SYMBOL vmlinux 0x2071bf25 i2c_del_adapter +EXPORT_SYMBOL vmlinux 0x207cff98 nf_ip_checksum +EXPORT_SYMBOL vmlinux 0x208739f6 acpi_load_table +EXPORT_SYMBOL vmlinux 0x208cfdaa bio_integrity_enabled +EXPORT_SYMBOL vmlinux 0x20a265d8 km_state_notify +EXPORT_SYMBOL vmlinux 0x20b52f1b blkdev_issue_discard +EXPORT_SYMBOL vmlinux 0x20c8fc33 pci_osc_control_set +EXPORT_SYMBOL vmlinux 0x20d4dbeb md_register_thread +EXPORT_SYMBOL vmlinux 0x20d8f9ca set_user_nice +EXPORT_SYMBOL vmlinux 0x20d965f0 dev_alloc_skb +EXPORT_SYMBOL vmlinux 0x20e73086 sock_create_kern +EXPORT_SYMBOL vmlinux 0x20eadeb6 ip_compute_csum +EXPORT_SYMBOL vmlinux 0x20f9322a idr_pre_get +EXPORT_SYMBOL vmlinux 0x20fa8ced path_get +EXPORT_SYMBOL vmlinux 0x211df440 tty_insert_flip_string_flags +EXPORT_SYMBOL vmlinux 0x21265937 mnt_pin +EXPORT_SYMBOL vmlinux 0x213fc970 jbd2_journal_wipe +EXPORT_SYMBOL vmlinux 0x2150bedb llc_mac_hdr_init +EXPORT_SYMBOL vmlinux 0x215ebd78 bitrev16 +EXPORT_SYMBOL vmlinux 0x2180374a tcp_poll +EXPORT_SYMBOL vmlinux 0x2189eb79 bio_integrity_alloc_bioset +EXPORT_SYMBOL vmlinux 0x219f7d4f pci_scan_slot +EXPORT_SYMBOL vmlinux 0x21b33bda tcp_v4_md5_lookup +EXPORT_SYMBOL vmlinux 0x21c3c002 page_symlink +EXPORT_SYMBOL vmlinux 0x21ce61e2 per_cpu__softnet_data +EXPORT_SYMBOL vmlinux 0x21e0ea22 acpi_get_id +EXPORT_SYMBOL vmlinux 0x21e5679c copy_user_generic +EXPORT_SYMBOL vmlinux 0x21e8df8e pci_request_regions +EXPORT_SYMBOL vmlinux 0x21ffc9e8 pci_get_subsys +EXPORT_SYMBOL vmlinux 0x222e7ce2 sysfs_streq +EXPORT_SYMBOL vmlinux 0x2253c959 kblockd_flush_work +EXPORT_SYMBOL vmlinux 0x2258a0bb acpi_bus_register_driver +EXPORT_SYMBOL vmlinux 0x225e3790 serio_unregister_child_port +EXPORT_SYMBOL vmlinux 0x226e86a9 audit_log +EXPORT_SYMBOL vmlinux 0x22805613 I_BDEV +EXPORT_SYMBOL vmlinux 0x2288378f system_state +EXPORT_SYMBOL vmlinux 0x228a8644 iget5_locked +EXPORT_SYMBOL vmlinux 0x2293912c pci_set_mwi +EXPORT_SYMBOL vmlinux 0x22a73912 __tcp_put_md5sig_pool +EXPORT_SYMBOL vmlinux 0x22aecc5d simple_write_begin +EXPORT_SYMBOL vmlinux 0x22b325d5 kd_mksound +EXPORT_SYMBOL vmlinux 0x22b62d9a bio_free +EXPORT_SYMBOL vmlinux 0x22b6533b xfrm_sad_getinfo +EXPORT_SYMBOL vmlinux 0x22d3d1dd simple_write_end +EXPORT_SYMBOL vmlinux 0x22e74c2d bio_integrity_advance +EXPORT_SYMBOL vmlinux 0x22e9842b __netdev_alloc_page +EXPORT_SYMBOL vmlinux 0x230466a9 __dev_get_by_name +EXPORT_SYMBOL vmlinux 0x231f3a66 __kfifo_put +EXPORT_SYMBOL vmlinux 0x23269a13 strict_strtoul +EXPORT_SYMBOL vmlinux 0x234509f3 strncat +EXPORT_SYMBOL vmlinux 0x234518cf sock_no_socketpair +EXPORT_SYMBOL vmlinux 0x234ac9df init_task +EXPORT_SYMBOL vmlinux 0x236c8c64 memcpy +EXPORT_SYMBOL vmlinux 0x238b10a6 inode_permission +EXPORT_SYMBOL vmlinux 0x239e3719 vfs_follow_link +EXPORT_SYMBOL vmlinux 0x23c8f257 slhc_uncompress +EXPORT_SYMBOL vmlinux 0x23e2715f bd_release +EXPORT_SYMBOL vmlinux 0x23fd3028 vmalloc_node +EXPORT_SYMBOL vmlinux 0x24428be5 strncpy_from_user +EXPORT_SYMBOL vmlinux 0x2459bbcc console_set_on_cmdline +EXPORT_SYMBOL vmlinux 0x247c1bd1 blk_queue_bounce +EXPORT_SYMBOL vmlinux 0x24837cd2 sk_dst_check +EXPORT_SYMBOL vmlinux 0x24cad263 keyring_search +EXPORT_SYMBOL vmlinux 0x24fdac79 wake_bit_function +EXPORT_SYMBOL vmlinux 0x252ece4a scsi_nonblockable_ioctl +EXPORT_SYMBOL vmlinux 0x25419de2 tcp_initialize_rcv_mss +EXPORT_SYMBOL vmlinux 0x256887e1 warn_slowpath +EXPORT_SYMBOL vmlinux 0x25820c64 fs_overflowuid +EXPORT_SYMBOL vmlinux 0x258355b4 fb_find_best_mode +EXPORT_SYMBOL vmlinux 0x25ec1b28 strlen +EXPORT_SYMBOL vmlinux 0x26205011 i2c_smbus_read_byte_data +EXPORT_SYMBOL vmlinux 0x263782b5 cancel_delayed_work_sync +EXPORT_SYMBOL vmlinux 0x263a597f dma_async_memcpy_buf_to_buf +EXPORT_SYMBOL vmlinux 0x26688b89 seq_open +EXPORT_SYMBOL vmlinux 0x266c4efa xfrm_state_walk +EXPORT_SYMBOL vmlinux 0x26815153 iget_failed +EXPORT_SYMBOL vmlinux 0x2685c3d7 __sg_alloc_table +EXPORT_SYMBOL vmlinux 0x268eae0d hci_get_route +EXPORT_SYMBOL vmlinux 0x26a37de6 netdev_set_master +EXPORT_SYMBOL vmlinux 0x26a6b57f blk_rq_append_bio +EXPORT_SYMBOL vmlinux 0x26ccbc11 inet_sk_rebuild_header +EXPORT_SYMBOL vmlinux 0x26d9ce4f blk_dump_rq_flags +EXPORT_SYMBOL vmlinux 0x26e76fb8 sysctl_udp_wmem_min +EXPORT_SYMBOL vmlinux 0x26e8d711 netlink_rcv_skb +EXPORT_SYMBOL vmlinux 0x26e97973 kmem_ptr_validate +EXPORT_SYMBOL vmlinux 0x26f27f88 i2c_get_adapter +EXPORT_SYMBOL vmlinux 0x270ecd29 tcf_destroy_chain +EXPORT_SYMBOL vmlinux 0x2719d8ec genl_unregister_ops +EXPORT_SYMBOL vmlinux 0x2727372d bio_copy_kern +EXPORT_SYMBOL vmlinux 0x272d394e mtrr_del +EXPORT_SYMBOL vmlinux 0x272e7488 cond_resched_softirq +EXPORT_SYMBOL vmlinux 0x273f066e _write_unlock_irq +EXPORT_SYMBOL vmlinux 0x27864d57 memparse +EXPORT_SYMBOL vmlinux 0x27879dac flush_signals +EXPORT_SYMBOL vmlinux 0x278ef1dd rtnetlink_put_metrics +EXPORT_SYMBOL vmlinux 0x27917d65 alloc_pci_dev +EXPORT_SYMBOL vmlinux 0x27a9a7eb ns_to_timespec +EXPORT_SYMBOL vmlinux 0x27b95d86 inet_register_protosw +EXPORT_SYMBOL vmlinux 0x27bbf221 disable_irq_nosync +EXPORT_SYMBOL vmlinux 0x27c0e46a d_move +EXPORT_SYMBOL vmlinux 0x27c33efe csum_ipv6_magic +EXPORT_SYMBOL vmlinux 0x27c61ece qdisc_put_stab +EXPORT_SYMBOL vmlinux 0x281a5dc4 __secpath_destroy +EXPORT_SYMBOL vmlinux 0x282a977d unregister_console +EXPORT_SYMBOL vmlinux 0x285135e6 acpi_evaluate_integer +EXPORT_SYMBOL vmlinux 0x285ac517 strict_strtoll +EXPORT_SYMBOL vmlinux 0x2876a6d3 memcpy_toiovec +EXPORT_SYMBOL vmlinux 0x28a2ed02 scsi_build_sense_buffer +EXPORT_SYMBOL vmlinux 0x28b56ac1 __skb_recv_datagram +EXPORT_SYMBOL vmlinux 0x28bf2c37 pcim_iomap_regions +EXPORT_SYMBOL vmlinux 0x28cd8f05 dev_set_promiscuity +EXPORT_SYMBOL vmlinux 0x28d2dc6f dmam_free_coherent +EXPORT_SYMBOL vmlinux 0x28dcf25c udplite_hash +EXPORT_SYMBOL vmlinux 0x28f343db pv_mmu_ops +EXPORT_SYMBOL vmlinux 0x29121b7c pskb_copy +EXPORT_SYMBOL vmlinux 0x29304349 __sk_dst_check +EXPORT_SYMBOL vmlinux 0x293d8a7f pci_enable_bridges +EXPORT_SYMBOL vmlinux 0x29537c9e alloc_chrdev_region +EXPORT_SYMBOL vmlinux 0x29554926 arp_tbl +EXPORT_SYMBOL vmlinux 0x299b83fc sb_set_blocksize +EXPORT_SYMBOL vmlinux 0x29ab5917 journal_extend +EXPORT_SYMBOL vmlinux 0x29b1176d xfrm_nl +EXPORT_SYMBOL vmlinux 0x29bd4c46 __cap_init_eff_set +EXPORT_SYMBOL vmlinux 0x29cf7b7f __blk_run_queue +EXPORT_SYMBOL vmlinux 0x2a281af6 generic_writepages +EXPORT_SYMBOL vmlinux 0x2a2a998a neigh_resolve_output +EXPORT_SYMBOL vmlinux 0x2a303d4d check_signature +EXPORT_SYMBOL vmlinux 0x2a457d85 tcp_read_sock +EXPORT_SYMBOL vmlinux 0x2a6fd6f3 acpi_get_physical_pci_device +EXPORT_SYMBOL vmlinux 0x2a7df9b7 rtnl_notify +EXPORT_SYMBOL vmlinux 0x2aa353cd nf_unregister_sockopt +EXPORT_SYMBOL vmlinux 0x2ac73cf8 phy_disconnect +EXPORT_SYMBOL vmlinux 0x2ad34755 neigh_ifdown +EXPORT_SYMBOL vmlinux 0x2aeb2800 mempool_create_node +EXPORT_SYMBOL vmlinux 0x2aee5a16 mpage_readpages +EXPORT_SYMBOL vmlinux 0x2afaacc8 input_set_keycode +EXPORT_SYMBOL vmlinux 0x2b0ba2b0 scsi_sense_desc_find +EXPORT_SYMBOL vmlinux 0x2b37632e __lookup_hash +EXPORT_SYMBOL vmlinux 0x2b5010a9 tcf_exts_destroy +EXPORT_SYMBOL vmlinux 0x2b6aac8c tcp_sockets_allocated +EXPORT_SYMBOL vmlinux 0x2b801f7d vfs_get_dqblk +EXPORT_SYMBOL vmlinux 0x2ba707a8 sysctl_tcp_low_latency +EXPORT_SYMBOL vmlinux 0x2bae8a88 mmc_unregister_driver +EXPORT_SYMBOL vmlinux 0x2bb55d6e acpi_remove_notify_handler +EXPORT_SYMBOL vmlinux 0x2be09893 _atomic_dec_and_lock +EXPORT_SYMBOL vmlinux 0x2be74a86 neigh_seq_next +EXPORT_SYMBOL vmlinux 0x2bfc63f1 tcp_connect +EXPORT_SYMBOL vmlinux 0x2bfeb410 acpi_get_handle +EXPORT_SYMBOL vmlinux 0x2c08b3ad hci_free_dev +EXPORT_SYMBOL vmlinux 0x2c094594 bio_integrity_get_tag +EXPORT_SYMBOL vmlinux 0x2c14bf80 register_qdisc +EXPORT_SYMBOL vmlinux 0x2c3568dc iov_iter_copy_from_user +EXPORT_SYMBOL vmlinux 0x2c384cb3 dma_async_client_register +EXPORT_SYMBOL vmlinux 0x2c3caeb6 skb_copy_and_csum_dev +EXPORT_SYMBOL vmlinux 0x2c5749e6 acpi_clear_gpe +EXPORT_SYMBOL vmlinux 0x2c741ff6 scsi_unregister +EXPORT_SYMBOL vmlinux 0x2cb69dc1 fifo_set_limit +EXPORT_SYMBOL vmlinux 0x2cb7c6f1 dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0x2cc2d52d vcc_hash +EXPORT_SYMBOL vmlinux 0x2cd9e459 param_set_short +EXPORT_SYMBOL vmlinux 0x2cf190e3 request_irq +EXPORT_SYMBOL vmlinux 0x2d06ea56 dquot_free_space +EXPORT_SYMBOL vmlinux 0x2d5528c9 sg_copy_to_buffer +EXPORT_SYMBOL vmlinux 0x2d891384 swiotlb_unmap_sg_attrs +EXPORT_SYMBOL vmlinux 0x2d89342a scsi_show_sense_hdr +EXPORT_SYMBOL vmlinux 0x2d8bb4c1 single_open +EXPORT_SYMBOL vmlinux 0x2da23671 skb_append +EXPORT_SYMBOL vmlinux 0x2dbafbe3 pcibios_align_resource +EXPORT_SYMBOL vmlinux 0x2dbd324f sock_rfree +EXPORT_SYMBOL vmlinux 0x2dbd488e __skb_checksum_complete +EXPORT_SYMBOL vmlinux 0x2dc846ae dma_sync_wait +EXPORT_SYMBOL vmlinux 0x2dd16564 arch_register_cpu +EXPORT_SYMBOL vmlinux 0x2ddf758d nf_ip6_checksum +EXPORT_SYMBOL vmlinux 0x2de8d987 journal_lock_updates +EXPORT_SYMBOL vmlinux 0x2de9f66f param_get_long +EXPORT_SYMBOL vmlinux 0x2dedc4c2 acpi_format_exception +EXPORT_SYMBOL vmlinux 0x2def7f76 rtc_cmos_write +EXPORT_SYMBOL vmlinux 0x2e2ce9e0 sysctl_tcp_syncookies +EXPORT_SYMBOL vmlinux 0x2e41f365 sock_no_setsockopt +EXPORT_SYMBOL vmlinux 0x2e4a39f8 sysctl_udp_mem +EXPORT_SYMBOL vmlinux 0x2e4fb343 scsi_scan_host +EXPORT_SYMBOL vmlinux 0x2e50b523 usb_serial_suspend +EXPORT_SYMBOL vmlinux 0x2e51fbed blk_rq_map_integrity_sg +EXPORT_SYMBOL vmlinux 0x2e59bf67 pnp_activate_dev +EXPORT_SYMBOL vmlinux 0x2e97a729 idr_remove +EXPORT_SYMBOL vmlinux 0x2e9a22e9 __dev_remove_pack +EXPORT_SYMBOL vmlinux 0x2eb2cd8c vfs_readdir +EXPORT_SYMBOL vmlinux 0x2eb7a5d7 set_device_ro +EXPORT_SYMBOL vmlinux 0x2eb9a0e8 _read_lock_irq +EXPORT_SYMBOL vmlinux 0x2ee829e3 udplite_prot +EXPORT_SYMBOL vmlinux 0x2eed9583 uart_add_one_port +EXPORT_SYMBOL vmlinux 0x2ef1cade tcp_proc_register +EXPORT_SYMBOL vmlinux 0x2ef3d52f thermal_cooling_device_register +EXPORT_SYMBOL vmlinux 0x2f109287 truncate_inode_pages_range +EXPORT_SYMBOL vmlinux 0x2f13a9db invalidate_partition +EXPORT_SYMBOL vmlinux 0x2f57a663 pcim_enable_device +EXPORT_SYMBOL vmlinux 0x2f670530 acpi_unlock_ac_dir +EXPORT_SYMBOL vmlinux 0x2f84a7e8 uart_suspend_port +EXPORT_SYMBOL vmlinux 0x2fa5a500 memcmp +EXPORT_SYMBOL vmlinux 0x2fb19ede fb_show_logo +EXPORT_SYMBOL vmlinux 0x2fe3b854 scsi_execute_req +EXPORT_SYMBOL vmlinux 0x2feb0c5b sysctl_jiffies +EXPORT_SYMBOL vmlinux 0x2ff063b5 acpi_get_name +EXPORT_SYMBOL vmlinux 0x2ff1610d tcp_v4_connect +EXPORT_SYMBOL vmlinux 0x2ff7efaa tcf_hash_new_index +EXPORT_SYMBOL vmlinux 0x30123eb5 icmpv6_statistics +EXPORT_SYMBOL vmlinux 0x30226ddf agp_device_command +EXPORT_SYMBOL vmlinux 0x306bd3c3 vfs_fstat +EXPORT_SYMBOL vmlinux 0x307f0827 scsi_finish_command +EXPORT_SYMBOL vmlinux 0x30aade9b sync_page_range +EXPORT_SYMBOL vmlinux 0x30b22bab swiotlb_sync_single_for_cpu +EXPORT_SYMBOL vmlinux 0x30c5dc03 tcp_simple_retransmit +EXPORT_SYMBOL vmlinux 0x30de8b2e copy_io_context +EXPORT_SYMBOL vmlinux 0x30e74134 tty_termios_copy_hw +EXPORT_SYMBOL vmlinux 0x31092a45 blk_rq_map_kern +EXPORT_SYMBOL vmlinux 0x31406e82 dquot_mark_dquot_dirty +EXPORT_SYMBOL vmlinux 0x3145216f pci_dev_present +EXPORT_SYMBOL vmlinux 0x314693bd md_error +EXPORT_SYMBOL vmlinux 0x3147857d default_red +EXPORT_SYMBOL vmlinux 0x3157a7b1 __mmc_claim_host +EXPORT_SYMBOL vmlinux 0x3182ebc8 tcp_md5_hash_key +EXPORT_SYMBOL vmlinux 0x31b31f5c csum_partial_copy_nocheck +EXPORT_SYMBOL vmlinux 0x31ebadcd in_group_p +EXPORT_SYMBOL vmlinux 0x320d0972 bdput +EXPORT_SYMBOL vmlinux 0x3261cffc tty_devnum +EXPORT_SYMBOL vmlinux 0x326ba0c4 km_report +EXPORT_SYMBOL vmlinux 0x326e9b64 blk_remove_plug +EXPORT_SYMBOL vmlinux 0x32ce9342 tcf_hash_search +EXPORT_SYMBOL vmlinux 0x32d01fec acpi_attach_data +EXPORT_SYMBOL vmlinux 0x32f87920 inet_frag_kill +EXPORT_SYMBOL vmlinux 0x330d556f gnet_stats_copy_app +EXPORT_SYMBOL vmlinux 0x3360a963 param_set_ulong +EXPORT_SYMBOL vmlinux 0x33651ad5 atm_charge +EXPORT_SYMBOL vmlinux 0x3369cd0b alloc_etherdev_mq +EXPORT_SYMBOL vmlinux 0x336ba577 elv_rq_merge_ok +EXPORT_SYMBOL vmlinux 0x33b84f74 copy_page +EXPORT_SYMBOL vmlinux 0x33ba1447 ppp_register_compressor +EXPORT_SYMBOL vmlinux 0x33bae2c7 udp_flush_pending_frames +EXPORT_SYMBOL vmlinux 0x33cda660 posix_acl_from_mode +EXPORT_SYMBOL vmlinux 0x33d92f9a prepare_to_wait +EXPORT_SYMBOL vmlinux 0x340e6101 nf_unregister_hook +EXPORT_SYMBOL vmlinux 0x3471a40d blk_rq_map_user +EXPORT_SYMBOL vmlinux 0x349cba85 strchr +EXPORT_SYMBOL vmlinux 0x349d4d02 vm_map_ram +EXPORT_SYMBOL vmlinux 0x34ea47ff genphy_config_aneg +EXPORT_SYMBOL vmlinux 0x34f90edf udp_sendmsg +EXPORT_SYMBOL vmlinux 0x34fce488 pci_remove_bus +EXPORT_SYMBOL vmlinux 0x351a3cb1 get_super +EXPORT_SYMBOL vmlinux 0x352f7444 __brelse +EXPORT_SYMBOL vmlinux 0x35327d6f sk_stream_error +EXPORT_SYMBOL vmlinux 0x356c4cdc pci_request_selected_regions +EXPORT_SYMBOL vmlinux 0x358ae134 xfrm_unregister_mode +EXPORT_SYMBOL vmlinux 0x358e92f7 inet_csk_destroy_sock +EXPORT_SYMBOL vmlinux 0x359ee5c9 add_disk +EXPORT_SYMBOL vmlinux 0x35a07e32 vfs_stat +EXPORT_SYMBOL vmlinux 0x35ab1162 i2c_smbus_write_i2c_block_data +EXPORT_SYMBOL vmlinux 0x35b0650f vsnprintf +EXPORT_SYMBOL vmlinux 0x35c2ba9e refrigerator +EXPORT_SYMBOL vmlinux 0x36051349 acpi_bus_get_device +EXPORT_SYMBOL vmlinux 0x360b1afe probe_irq_mask +EXPORT_SYMBOL vmlinux 0x36139a51 memcpy_fromiovec +EXPORT_SYMBOL vmlinux 0x3616c547 blkdev_put +EXPORT_SYMBOL vmlinux 0x3639e95f blk_sync_queue +EXPORT_SYMBOL vmlinux 0x363ad247 cap_set_effective +EXPORT_SYMBOL vmlinux 0x3656bf5a lock_kernel +EXPORT_SYMBOL vmlinux 0x365a3202 seq_path +EXPORT_SYMBOL vmlinux 0x365c06dd clip_tbl_hook +EXPORT_SYMBOL vmlinux 0x3672224d kernel_bind +EXPORT_SYMBOL vmlinux 0x3673a38b inet_getname +EXPORT_SYMBOL vmlinux 0x3685fbac serio_interrupt +EXPORT_SYMBOL vmlinux 0x3699509d pci_get_device +EXPORT_SYMBOL vmlinux 0x369df217 journal_init_inode +EXPORT_SYMBOL vmlinux 0x36b6f5ad phy_disable_interrupts +EXPORT_SYMBOL vmlinux 0x36db2bb5 netpoll_send_udp +EXPORT_SYMBOL vmlinux 0x36e32136 pci_pme_capable +EXPORT_SYMBOL vmlinux 0x36e3b8da inet6_release +EXPORT_SYMBOL vmlinux 0x3701a196 csum_partial_copy_to_user +EXPORT_SYMBOL vmlinux 0x3715f105 d_genocide +EXPORT_SYMBOL vmlinux 0x3744cf36 vmalloc_to_pfn +EXPORT_SYMBOL vmlinux 0x375465a7 radix_tree_gang_lookup_tag_slot +EXPORT_SYMBOL vmlinux 0x377b7856 generic_file_mmap +EXPORT_SYMBOL vmlinux 0x378305f3 shrink_dcache_parent +EXPORT_SYMBOL vmlinux 0x37befc70 jiffies_to_msecs +EXPORT_SYMBOL vmlinux 0x37ce9e7a mb_cache_entry_alloc +EXPORT_SYMBOL vmlinux 0x38103e34 dm_table_get_md +EXPORT_SYMBOL vmlinux 0x38119468 sock_no_accept +EXPORT_SYMBOL vmlinux 0x38224889 simple_lookup +EXPORT_SYMBOL vmlinux 0x3849804c kernel_sendmsg +EXPORT_SYMBOL vmlinux 0x3852c9da __mod_zone_page_state +EXPORT_SYMBOL vmlinux 0x388d0556 xfrm_alloc_spi +EXPORT_SYMBOL vmlinux 0x388e3850 dma_pool_alloc +EXPORT_SYMBOL vmlinux 0x388f9128 xfrm_state_walk_done +EXPORT_SYMBOL vmlinux 0x38a4965d bio_get_nr_vecs +EXPORT_SYMBOL vmlinux 0x38b92846 llc_remove_pack +EXPORT_SYMBOL vmlinux 0x38f33bed dump_fpu +EXPORT_SYMBOL vmlinux 0x3932d0ee proc_dointvec_jiffies +EXPORT_SYMBOL vmlinux 0x3980aac1 unregister_reboot_notifier +EXPORT_SYMBOL vmlinux 0x3991db43 llc_add_pack +EXPORT_SYMBOL vmlinux 0x39c16f1e release_firmware +EXPORT_SYMBOL vmlinux 0x39cd891a __down_write_trylock +EXPORT_SYMBOL vmlinux 0x39f7e053 pneigh_enqueue +EXPORT_SYMBOL vmlinux 0x3a2003a3 iommu_nr_pages +EXPORT_SYMBOL vmlinux 0x3a2204c6 security_netlink_recv +EXPORT_SYMBOL vmlinux 0x3a2959a5 dev_kfree_skb_any +EXPORT_SYMBOL vmlinux 0x3a2acae3 sock_map_fd +EXPORT_SYMBOL vmlinux 0x3a698d29 set_page_dirty_lock +EXPORT_SYMBOL vmlinux 0x3a9b6fb9 blk_unregister_region +EXPORT_SYMBOL vmlinux 0x3aa1dbcf _spin_unlock_bh +EXPORT_SYMBOL vmlinux 0x3ab4ffd1 compat_tcp_setsockopt +EXPORT_SYMBOL vmlinux 0x3adbddd1 generic_block_bmap +EXPORT_SYMBOL vmlinux 0x3b298f72 sock_no_ioctl +EXPORT_SYMBOL vmlinux 0x3b3016d3 cpufreq_unregister_notifier +EXPORT_SYMBOL vmlinux 0x3b67cbbf __init_rwsem +EXPORT_SYMBOL vmlinux 0x3b6d96a5 netpoll_print_options +EXPORT_SYMBOL vmlinux 0x3b706deb nobh_write_begin +EXPORT_SYMBOL vmlinux 0x3b9d1e63 acpi_get_physical_device +EXPORT_SYMBOL vmlinux 0x3bcba798 gnet_stats_copy_queue +EXPORT_SYMBOL vmlinux 0x3bd1b1f6 msecs_to_jiffies +EXPORT_SYMBOL vmlinux 0x3beed89a kthread_bind +EXPORT_SYMBOL vmlinux 0x3c199319 vfs_statfs +EXPORT_SYMBOL vmlinux 0x3c26fa17 udp_ioctl +EXPORT_SYMBOL vmlinux 0x3c2c5af5 sprintf +EXPORT_SYMBOL vmlinux 0x3c348dce __serio_register_driver +EXPORT_SYMBOL vmlinux 0x3c3be62a sock_alloc_send_skb +EXPORT_SYMBOL vmlinux 0x3c4887e1 vfs_dq_transfer +EXPORT_SYMBOL vmlinux 0x3c7227bf complete_all +EXPORT_SYMBOL vmlinux 0x3c77f440 alloc_disk_node +EXPORT_SYMBOL vmlinux 0x3c898c9d dcache_dir_open +EXPORT_SYMBOL vmlinux 0x3c8e3114 dma_async_device_register +EXPORT_SYMBOL vmlinux 0x3c9cee7e journal_update_format +EXPORT_SYMBOL vmlinux 0x3c9d1211 string_get_size +EXPORT_SYMBOL vmlinux 0x3cb8a495 param_get_string +EXPORT_SYMBOL vmlinux 0x3cc0a3bb xfrm_spd_getinfo +EXPORT_SYMBOL vmlinux 0x3ce4ca6f disable_irq +EXPORT_SYMBOL vmlinux 0x3cf09da1 skb_pad +EXPORT_SYMBOL vmlinux 0x3d231728 write_one_page +EXPORT_SYMBOL vmlinux 0x3d421196 xfrm_state_check_expire +EXPORT_SYMBOL vmlinux 0x3d59592d tcf_generic_walker +EXPORT_SYMBOL vmlinux 0x3d9001f7 skb_split +EXPORT_SYMBOL vmlinux 0x3d9ee9f0 clear_page +EXPORT_SYMBOL vmlinux 0x3da171f9 pci_mem_start +EXPORT_SYMBOL vmlinux 0x3da5eb6d kfifo_alloc +EXPORT_SYMBOL vmlinux 0x3dafe793 pci_enable_device +EXPORT_SYMBOL vmlinux 0x3db2e258 radix_tree_gang_lookup +EXPORT_SYMBOL vmlinux 0x3e199f1d bdi_unregister +EXPORT_SYMBOL vmlinux 0x3e1e1adf fb_find_mode +EXPORT_SYMBOL vmlinux 0x3e1f073d wait_for_completion_timeout +EXPORT_SYMBOL vmlinux 0x3e219de6 try_wait_for_completion +EXPORT_SYMBOL vmlinux 0x3e285ec6 __getblk +EXPORT_SYMBOL vmlinux 0x3e2ae3a8 acpi_release_global_lock +EXPORT_SYMBOL vmlinux 0x3e383385 nf_hooks +EXPORT_SYMBOL vmlinux 0x3e3c36ed xfrm_policy_delete +EXPORT_SYMBOL vmlinux 0x3e45e9ff register_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x3e472776 bitmap_close_sync +EXPORT_SYMBOL vmlinux 0x3e72271d call_usermodehelper_setcleanup +EXPORT_SYMBOL vmlinux 0x3e7ae090 unregister_exec_domain +EXPORT_SYMBOL vmlinux 0x3ebed522 devm_ioremap_nocache +EXPORT_SYMBOL vmlinux 0x3ecb576a close_bdev_exclusive +EXPORT_SYMBOL vmlinux 0x3ed63055 zlib_inflateReset +EXPORT_SYMBOL vmlinux 0x3ef8409e blk_verify_command +EXPORT_SYMBOL vmlinux 0x3efcadda register_nls +EXPORT_SYMBOL vmlinux 0x3efed9c1 pnp_request_card_device +EXPORT_SYMBOL vmlinux 0x3f0546a8 ioread32_rep +EXPORT_SYMBOL vmlinux 0x3f1899f1 up +EXPORT_SYMBOL vmlinux 0x3f2324fb ip6_route_me_harder +EXPORT_SYMBOL vmlinux 0x3f2b34c9 cdrom_get_media_event +EXPORT_SYMBOL vmlinux 0x3f4547a7 put_unused_fd +EXPORT_SYMBOL vmlinux 0x3f659d90 i2c_del_driver +EXPORT_SYMBOL vmlinux 0x3f96e2f2 dcache_dir_lseek +EXPORT_SYMBOL vmlinux 0x3fa913da strspn +EXPORT_SYMBOL vmlinux 0x3fc56f74 bitmap_cond_end_sync +EXPORT_SYMBOL vmlinux 0x3fec048f sg_next +EXPORT_SYMBOL vmlinux 0x3fee578c find_inode_number +EXPORT_SYMBOL vmlinux 0x3ff62317 local_bh_disable +EXPORT_SYMBOL vmlinux 0x3ff7abbc journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0x40228261 pci_scan_single_device +EXPORT_SYMBOL vmlinux 0x405c1144 get_seconds +EXPORT_SYMBOL vmlinux 0x4065c9f6 inet_dgram_connect +EXPORT_SYMBOL vmlinux 0x409873e3 tty_termios_baud_rate +EXPORT_SYMBOL vmlinux 0x4099e614 compute_creds +EXPORT_SYMBOL vmlinux 0x409d3e27 get_fs_type +EXPORT_SYMBOL vmlinux 0x40c4cb94 nf_register_hook +EXPORT_SYMBOL vmlinux 0x40c89d46 acpi_get_table_by_index +EXPORT_SYMBOL vmlinux 0x40e29b20 sock_sendmsg +EXPORT_SYMBOL vmlinux 0x40e8140f scsi_calculate_bounce_limit +EXPORT_SYMBOL vmlinux 0x40eb1795 genphy_restart_aneg +EXPORT_SYMBOL vmlinux 0x40ec4bce sysctl_intvec +EXPORT_SYMBOL vmlinux 0x4100f2f6 elv_dispatch_add_tail +EXPORT_SYMBOL vmlinux 0x4108e69a fb_match_mode +EXPORT_SYMBOL vmlinux 0x41482d8b strndup_user +EXPORT_SYMBOL vmlinux 0x416983d9 netdev_fix_features +EXPORT_SYMBOL vmlinux 0x418269c6 tcp_tso_segment +EXPORT_SYMBOL vmlinux 0x4188d439 neigh_rand_reach_time +EXPORT_SYMBOL vmlinux 0x41a7c227 schedule_delayed_work +EXPORT_SYMBOL vmlinux 0x41a9c68d _spin_trylock_bh +EXPORT_SYMBOL vmlinux 0x41c60dc7 sk_stream_kill_queues +EXPORT_SYMBOL vmlinux 0x4211c3c1 zlib_inflateInit2 +EXPORT_SYMBOL vmlinux 0x42205caf get_unmapped_area +EXPORT_SYMBOL vmlinux 0x42224298 sscanf +EXPORT_SYMBOL vmlinux 0x422c05d0 acpi_get_data +EXPORT_SYMBOL vmlinux 0x42380ed1 neigh_sysctl_unregister +EXPORT_SYMBOL vmlinux 0x423fdb41 generic_delete_inode +EXPORT_SYMBOL vmlinux 0x4264c52a generic_file_splice_read +EXPORT_SYMBOL vmlinux 0x4292f948 find_task_by_pid_ns +EXPORT_SYMBOL vmlinux 0x429fce76 blk_execute_rq +EXPORT_SYMBOL vmlinux 0x42a4bdf2 in_egroup_p +EXPORT_SYMBOL vmlinux 0x42c49d24 pci_enable_device_io +EXPORT_SYMBOL vmlinux 0x42c8de35 ioremap_nocache +EXPORT_SYMBOL vmlinux 0x42e78535 blk_queue_invalidate_tags +EXPORT_SYMBOL vmlinux 0x42fdba67 da903x_query_status +EXPORT_SYMBOL vmlinux 0x42ff9b19 unregister_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0x4302d0eb free_pages +EXPORT_SYMBOL vmlinux 0x4316e256 dm_kcopyd_client_create +EXPORT_SYMBOL vmlinux 0x4327f0d5 memset_io +EXPORT_SYMBOL vmlinux 0x43385ad9 acpi_pci_unregister_driver +EXPORT_SYMBOL vmlinux 0x433b9f95 free_task +EXPORT_SYMBOL vmlinux 0x434fa55c release_console_sem +EXPORT_SYMBOL vmlinux 0x435b36d9 call_usermodehelper_pipe +EXPORT_SYMBOL vmlinux 0x435b566d _spin_unlock +EXPORT_SYMBOL vmlinux 0x435dcca7 blk_init_queue +EXPORT_SYMBOL vmlinux 0x436c2179 iowrite32 +EXPORT_SYMBOL vmlinux 0x4370c734 alloc_netdev_mq +EXPORT_SYMBOL vmlinux 0x4391075c scsi_remove_device +EXPORT_SYMBOL vmlinux 0x43bb2b77 tcp_v4_md5_hash_skb +EXPORT_SYMBOL vmlinux 0x43ec913a put_cmsg +EXPORT_SYMBOL vmlinux 0x43ed2774 kill_pgrp +EXPORT_SYMBOL vmlinux 0x44161c19 unregister_shrinker +EXPORT_SYMBOL vmlinux 0x444779c4 nla_find +EXPORT_SYMBOL vmlinux 0x4465bd0b tcp_v4_conn_request +EXPORT_SYMBOL vmlinux 0x4468daca __module_put_and_exit +EXPORT_SYMBOL vmlinux 0x4470fb17 vfs_unlink +EXPORT_SYMBOL vmlinux 0x447ffc39 i2c_smbus_write_byte_data +EXPORT_SYMBOL vmlinux 0x449436df tcp_check_req +EXPORT_SYMBOL vmlinux 0x449b428f get_phy_id +EXPORT_SYMBOL vmlinux 0x44aaf30f tsc_khz +EXPORT_SYMBOL vmlinux 0x44b4f979 ethtool_op_get_sg +EXPORT_SYMBOL vmlinux 0x44b911c3 rb_replace_node +EXPORT_SYMBOL vmlinux 0x44c55333 tty_driver_flush_buffer +EXPORT_SYMBOL vmlinux 0x44c999da phy_mii_ioctl +EXPORT_SYMBOL vmlinux 0x44d560e3 init_level4_pgt +EXPORT_SYMBOL vmlinux 0x44e9a829 match_token +EXPORT_SYMBOL vmlinux 0x44f5d39d blk_queue_init_tags +EXPORT_SYMBOL vmlinux 0x44ffc02e dm_dirty_log_destroy +EXPORT_SYMBOL vmlinux 0x45133753 pci_release_regions +EXPORT_SYMBOL vmlinux 0x4526b2f4 d_namespace_path +EXPORT_SYMBOL vmlinux 0x453438eb fb_pan_display +EXPORT_SYMBOL vmlinux 0x454b6b8b pnp_get_resource +EXPORT_SYMBOL vmlinux 0x4550ba8a register_cpu_notifier +EXPORT_SYMBOL vmlinux 0x455fd57d acpi_set_register +EXPORT_SYMBOL vmlinux 0x45704798 print_hex_dump_bytes +EXPORT_SYMBOL vmlinux 0x4572534c key_payload_reserve +EXPORT_SYMBOL vmlinux 0x4574007a register_sysctl_table +EXPORT_SYMBOL vmlinux 0x45a20318 poll_freewait +EXPORT_SYMBOL vmlinux 0x45bb123e try_to_del_timer_sync +EXPORT_SYMBOL vmlinux 0x45d11c43 down_interruptible +EXPORT_SYMBOL vmlinux 0x45f8404e elv_next_request +EXPORT_SYMBOL vmlinux 0x4611eb6e find_task_by_vpid +EXPORT_SYMBOL vmlinux 0x46206f0f cdev_init +EXPORT_SYMBOL vmlinux 0x46341a6e __dev_get_by_index +EXPORT_SYMBOL vmlinux 0x4635aa9d iw_handler_set_spy +EXPORT_SYMBOL vmlinux 0x4653b7e1 thaw_process +EXPORT_SYMBOL vmlinux 0x466c14a7 __delay +EXPORT_SYMBOL vmlinux 0x4673f74b netlink_clear_multicast_users +EXPORT_SYMBOL vmlinux 0x4679020d pnp_register_card_driver +EXPORT_SYMBOL vmlinux 0x469266e1 dev_unicast_unsync +EXPORT_SYMBOL vmlinux 0x46a1fc92 kill_block_super +EXPORT_SYMBOL vmlinux 0x46af11aa aio_put_req +EXPORT_SYMBOL vmlinux 0x46bc276b skb_add_rx_frag +EXPORT_SYMBOL vmlinux 0x46e619eb bt_sock_register +EXPORT_SYMBOL vmlinux 0x470a0b1e scsi_remove_host +EXPORT_SYMBOL vmlinux 0x475100c2 inet_get_local_port_range +EXPORT_SYMBOL vmlinux 0x475f010b acpi_purge_cached_objects +EXPORT_SYMBOL vmlinux 0x475f05af acpi_set_firmware_waking_vector +EXPORT_SYMBOL vmlinux 0x4776ea98 clear_page_dirty_for_io +EXPORT_SYMBOL vmlinux 0x477d1434 km_policy_notify +EXPORT_SYMBOL vmlinux 0x478b04c7 pci_enable_wake +EXPORT_SYMBOL vmlinux 0x478d10b2 ht_destroy_irq +EXPORT_SYMBOL vmlinux 0x47908454 tcp_mtup_init +EXPORT_SYMBOL vmlinux 0x47939e0d __tasklet_hi_schedule +EXPORT_SYMBOL vmlinux 0x479c3c86 find_next_zero_bit +EXPORT_SYMBOL vmlinux 0x47c3ea2a unlock_page +EXPORT_SYMBOL vmlinux 0x47e0048d pci_bus_read_config_dword +EXPORT_SYMBOL vmlinux 0x47f5b0e7 read_dev_sector +EXPORT_SYMBOL vmlinux 0x4810aed0 xfrm_find_acq +EXPORT_SYMBOL vmlinux 0x48139088 __tcp_get_md5sig_pool +EXPORT_SYMBOL vmlinux 0x4814f1ad tcp_v4_destroy_sock +EXPORT_SYMBOL vmlinux 0x481cb9ab acpi_enter_sleep_state_prep +EXPORT_SYMBOL vmlinux 0x4825376a inet_listen +EXPORT_SYMBOL vmlinux 0x4829bea6 ps2_sendbyte +EXPORT_SYMBOL vmlinux 0x4859b8bb rtc_year_days +EXPORT_SYMBOL vmlinux 0x486b6407 hweight64 +EXPORT_SYMBOL vmlinux 0x48a18bde take_over_console +EXPORT_SYMBOL vmlinux 0x48a63abc pci_bus_read_config_word +EXPORT_SYMBOL vmlinux 0x48baca5a __scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0x48cd6404 dquot_alloc_space +EXPORT_SYMBOL vmlinux 0x48eef067 netlink_dump_start +EXPORT_SYMBOL vmlinux 0x48f1b504 write_inode_now +EXPORT_SYMBOL vmlinux 0x4904b042 mntput_no_expire +EXPORT_SYMBOL vmlinux 0x49088768 journal_ack_err +EXPORT_SYMBOL vmlinux 0x4916e964 simple_fill_super +EXPORT_SYMBOL vmlinux 0x49319f9d loop_register_transfer +EXPORT_SYMBOL vmlinux 0x493e25e1 udp_hash +EXPORT_SYMBOL vmlinux 0x49603fb8 security_sb_copy_data +EXPORT_SYMBOL vmlinux 0x4969b543 vfs_set_dqinfo +EXPORT_SYMBOL vmlinux 0x4969b5c1 __napi_schedule +EXPORT_SYMBOL vmlinux 0x496e1c67 xfrm_state_unregister_afinfo +EXPORT_SYMBOL vmlinux 0x49b547a2 sk_send_sigurg +EXPORT_SYMBOL vmlinux 0x49c5c8de scsi_device_set_state +EXPORT_SYMBOL vmlinux 0x49c8e72c neigh_parms_alloc +EXPORT_SYMBOL vmlinux 0x49d3fc10 mb_cache_entry_find_next +EXPORT_SYMBOL vmlinux 0x49da9a9a _read_unlock_bh +EXPORT_SYMBOL vmlinux 0x49f06839 lock_super +EXPORT_SYMBOL vmlinux 0x4a161231 open_bdev_exclusive +EXPORT_SYMBOL vmlinux 0x4a326cd7 sock_wake_async +EXPORT_SYMBOL vmlinux 0x4a358252 __bitmap_subset +EXPORT_SYMBOL vmlinux 0x4a422356 unbind_con_driver +EXPORT_SYMBOL vmlinux 0x4a4fa755 input_allocate_device +EXPORT_SYMBOL vmlinux 0x4a94553e get_sb_single +EXPORT_SYMBOL vmlinux 0x4a9c4273 blk_queue_softirq_done +EXPORT_SYMBOL vmlinux 0x4aaa4b1d atm_dev_deregister +EXPORT_SYMBOL vmlinux 0x4acd93d3 release_resource +EXPORT_SYMBOL vmlinux 0x4ad5986d tcp_make_synack +EXPORT_SYMBOL vmlinux 0x4ae37fb7 thermal_zone_device_unregister +EXPORT_SYMBOL vmlinux 0x4aec9d60 rfkill_force_state +EXPORT_SYMBOL vmlinux 0x4afe9a77 scsi_partsize +EXPORT_SYMBOL vmlinux 0x4b07e779 _spin_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x4b085dbf agp3_generic_configure +EXPORT_SYMBOL vmlinux 0x4b1daa0b uart_register_driver +EXPORT_SYMBOL vmlinux 0x4b2f14b4 jiffies_to_timespec +EXPORT_SYMBOL vmlinux 0x4b3b0496 touch_atime +EXPORT_SYMBOL vmlinux 0x4b3e20cc kill_anon_super +EXPORT_SYMBOL vmlinux 0x4b697a82 kick_iocb +EXPORT_SYMBOL vmlinux 0x4b6acb52 pci_target_state +EXPORT_SYMBOL vmlinux 0x4b72e20d scsi_is_host_device +EXPORT_SYMBOL vmlinux 0x4b77c0d1 tcf_hash_insert +EXPORT_SYMBOL vmlinux 0x4b861460 blk_queue_dma_pad +EXPORT_SYMBOL vmlinux 0x4b91f272 sync_dirty_buffer +EXPORT_SYMBOL vmlinux 0x4b946f0a sk_reset_timer +EXPORT_SYMBOL vmlinux 0x4b947ee9 __bread +EXPORT_SYMBOL vmlinux 0x4b9dfa8e netif_device_attach +EXPORT_SYMBOL vmlinux 0x4ba5baa0 load_gs_index +EXPORT_SYMBOL vmlinux 0x4ba6d5ef vfs_quota_sync +EXPORT_SYMBOL vmlinux 0x4baf99fb __serio_register_port +EXPORT_SYMBOL vmlinux 0x4bbc3e5f pm_flags +EXPORT_SYMBOL vmlinux 0x4bbcb530 thermal_zone_device_register +EXPORT_SYMBOL vmlinux 0x4bdf028e idr_find +EXPORT_SYMBOL vmlinux 0x4bdf5fa0 dev_alloc_name +EXPORT_SYMBOL vmlinux 0x4c08c497 sockfd_lookup +EXPORT_SYMBOL vmlinux 0x4c1182cb bitmap_scnprintf +EXPORT_SYMBOL vmlinux 0x4c149667 dm_get_mapinfo +EXPORT_SYMBOL vmlinux 0x4c4c956e nla_memcmp +EXPORT_SYMBOL vmlinux 0x4c5bfaa2 inet_select_addr +EXPORT_SYMBOL vmlinux 0x4cbbd171 __bitmap_weight +EXPORT_SYMBOL vmlinux 0x4cede630 inet_stream_connect +EXPORT_SYMBOL vmlinux 0x4d0b5e7f kern_path +EXPORT_SYMBOL vmlinux 0x4d53dd31 mdiobus_unregister +EXPORT_SYMBOL vmlinux 0x4d561118 dm_table_event +EXPORT_SYMBOL vmlinux 0x4db1e1d4 posix_acl_equiv_mode +EXPORT_SYMBOL vmlinux 0x4dc53c79 proc_dointvec +EXPORT_SYMBOL vmlinux 0x4dda726b match_strlcpy +EXPORT_SYMBOL vmlinux 0x4ddc4b9f utf8_mbtowc +EXPORT_SYMBOL vmlinux 0x4df119fa __bitmap_parse +EXPORT_SYMBOL vmlinux 0x4df47e9f xfrm_state_flush +EXPORT_SYMBOL vmlinux 0x4e100f60 _spin_unlock_irq +EXPORT_SYMBOL vmlinux 0x4e18acf8 journal_create +EXPORT_SYMBOL vmlinux 0x4e273b39 scsi_is_sdev_device +EXPORT_SYMBOL vmlinux 0x4e3567f7 match_int +EXPORT_SYMBOL vmlinux 0x4e3d21a9 may_umount_tree +EXPORT_SYMBOL vmlinux 0x4e6e8ea7 fg_console +EXPORT_SYMBOL vmlinux 0x4e70455f starget_for_each_device +EXPORT_SYMBOL vmlinux 0x4e9fd62d mdio_bus_type +EXPORT_SYMBOL vmlinux 0x4eb8e005 neigh_sysctl_register +EXPORT_SYMBOL vmlinux 0x4ed71508 generic_file_aio_write_nolock +EXPORT_SYMBOL vmlinux 0x4edd72f7 block_all_signals +EXPORT_SYMBOL vmlinux 0x4ef970c6 vfs_path_lookup +EXPORT_SYMBOL vmlinux 0x4f096eb7 fd_install +EXPORT_SYMBOL vmlinux 0x4f212c7a jbd2_journal_start_commit +EXPORT_SYMBOL vmlinux 0x4f2933c5 sk_wait_data +EXPORT_SYMBOL vmlinux 0x4f3739e7 blk_queue_max_phys_segments +EXPORT_SYMBOL vmlinux 0x4f3874ce ip_setsockopt +EXPORT_SYMBOL vmlinux 0x4f476e96 init_cdrom_command +EXPORT_SYMBOL vmlinux 0x4f5438c1 idle_halt +EXPORT_SYMBOL vmlinux 0x4fa75270 inet_frags_fini +EXPORT_SYMBOL vmlinux 0x4fa9b1f2 pci_select_bars +EXPORT_SYMBOL vmlinux 0x4faebd58 mpage_writepages +EXPORT_SYMBOL vmlinux 0x4fafc99a blk_queue_hardsect_size +EXPORT_SYMBOL vmlinux 0x4fbc92da hci_register_proto +EXPORT_SYMBOL vmlinux 0x4fcee107 __up_read +EXPORT_SYMBOL vmlinux 0x4fdee897 i8042_command +EXPORT_SYMBOL vmlinux 0x4fea84e2 d_alloc_root +EXPORT_SYMBOL vmlinux 0x5008cfd0 blk_stop_queue +EXPORT_SYMBOL vmlinux 0x500fe15e mmc_remove_host +EXPORT_SYMBOL vmlinux 0x501b94c0 scsi_release_buffers +EXPORT_SYMBOL vmlinux 0x50211ee3 tcp_free_md5sig_pool +EXPORT_SYMBOL vmlinux 0x5072b6b8 create_proc_entry +EXPORT_SYMBOL vmlinux 0x50893d88 filemap_fdatawrite_range +EXPORT_SYMBOL vmlinux 0x50913357 xfrm_unregister_type +EXPORT_SYMBOL vmlinux 0x50918b64 __inode_dir_notify +EXPORT_SYMBOL vmlinux 0x50adf917 cdrom_mode_sense +EXPORT_SYMBOL vmlinux 0x50b5cb2d idr_get_new_above +EXPORT_SYMBOL vmlinux 0x50bfc890 xfrm_input +EXPORT_SYMBOL vmlinux 0x50cbc815 names_cachep +EXPORT_SYMBOL vmlinux 0x50eb1994 ioctl_by_bdev +EXPORT_SYMBOL vmlinux 0x51019583 dev_add_pack +EXPORT_SYMBOL vmlinux 0x5118c382 secure_dccp_sequence_number +EXPORT_SYMBOL vmlinux 0x51458dfb pnp_release_card_device +EXPORT_SYMBOL vmlinux 0x514ee97b inc_zone_page_state +EXPORT_SYMBOL vmlinux 0x51a2925e bd_set_size +EXPORT_SYMBOL vmlinux 0x51b25835 skb_unlink +EXPORT_SYMBOL vmlinux 0x51ceb99f prepare_binprm +EXPORT_SYMBOL vmlinux 0x51d12d4e acpi_pci_disabled +EXPORT_SYMBOL vmlinux 0x51d7a776 acpi_detach_data +EXPORT_SYMBOL vmlinux 0x51dce73b xfrm_state_walk_init +EXPORT_SYMBOL vmlinux 0x51fcc0aa i2c_master_recv +EXPORT_SYMBOL vmlinux 0x5200ceba scsi_host_set_state +EXPORT_SYMBOL vmlinux 0x52026cdf security_sb_parse_opts_str +EXPORT_SYMBOL vmlinux 0x521d63ec wait_for_key_construction +EXPORT_SYMBOL vmlinux 0x52293a12 input_unregister_device +EXPORT_SYMBOL vmlinux 0x522f5573 pv_irq_ops +EXPORT_SYMBOL vmlinux 0x523d9dea scsi_device_resume +EXPORT_SYMBOL vmlinux 0x5252f304 __memcpy_toio +EXPORT_SYMBOL vmlinux 0x525becd3 do_munmap +EXPORT_SYMBOL vmlinux 0x52645447 vcc_insert_socket +EXPORT_SYMBOL vmlinux 0x528562dc phy_ethtool_gset +EXPORT_SYMBOL vmlinux 0x5285fdff nla_append +EXPORT_SYMBOL vmlinux 0x529dabda devm_ioport_unmap +EXPORT_SYMBOL vmlinux 0x52a58c24 ifla_policy +EXPORT_SYMBOL vmlinux 0x52d7b2fd llc_sap_list +EXPORT_SYMBOL vmlinux 0x52e2627a i2c_smbus_read_block_data +EXPORT_SYMBOL vmlinux 0x52ff1e8c journal_restart +EXPORT_SYMBOL vmlinux 0x530b1e98 pm_suspend +EXPORT_SYMBOL vmlinux 0x531b604e __virt_addr_valid +EXPORT_SYMBOL vmlinux 0x532ea2b5 mdiobus_read +EXPORT_SYMBOL vmlinux 0x532f2924 param_get_byte +EXPORT_SYMBOL vmlinux 0x53326531 mempool_alloc_pages +EXPORT_SYMBOL vmlinux 0x538383c0 unregister_inet6addr_notifier +EXPORT_SYMBOL vmlinux 0x539d263f ps2_command +EXPORT_SYMBOL vmlinux 0x53bc3a8d __neigh_event_send +EXPORT_SYMBOL vmlinux 0x53c0767c sk_chk_filter +EXPORT_SYMBOL vmlinux 0x53cea7ca acpi_bus_unregister_driver +EXPORT_SYMBOL vmlinux 0x54113934 fb_firmware_edid +EXPORT_SYMBOL vmlinux 0x54128174 compat_ip_getsockopt +EXPORT_SYMBOL vmlinux 0x54290dc9 nla_validate +EXPORT_SYMBOL vmlinux 0x543affb5 per_cpu__kstat +EXPORT_SYMBOL vmlinux 0x5443b0da grab_cache_page_write_begin +EXPORT_SYMBOL vmlinux 0x547913a9 netif_rx_ni +EXPORT_SYMBOL vmlinux 0x548d56c3 rfkill_register +EXPORT_SYMBOL vmlinux 0x54913832 agp_generic_destroy_pages +EXPORT_SYMBOL vmlinux 0x5497842e mdiobus_alloc +EXPORT_SYMBOL vmlinux 0x54b81541 init_timer_deferrable +EXPORT_SYMBOL vmlinux 0x54e5e0ba tcp_sync_mss +EXPORT_SYMBOL vmlinux 0x54e6fcdd net_enable_timestamp +EXPORT_SYMBOL vmlinux 0x550f8ade groups_alloc +EXPORT_SYMBOL vmlinux 0x5513442d llc_set_station_handler +EXPORT_SYMBOL vmlinux 0x55205a27 inode_needs_sync +EXPORT_SYMBOL vmlinux 0x5534938c pcie_set_readrq +EXPORT_SYMBOL vmlinux 0x5594be03 bitmap_remap +EXPORT_SYMBOL vmlinux 0x559919da i2c_smbus_write_block_data +EXPORT_SYMBOL vmlinux 0x55b38a04 inet_csk_init_xmit_timers +EXPORT_SYMBOL vmlinux 0x55bd79ef xfrm4_rcv_encap +EXPORT_SYMBOL vmlinux 0x55f151fe cap_netlink_recv +EXPORT_SYMBOL vmlinux 0x5600904f fb_get_color_depth +EXPORT_SYMBOL vmlinux 0x56076f40 serial8250_register_port +EXPORT_SYMBOL vmlinux 0x5614b010 xfrm_policy_walk_done +EXPORT_SYMBOL vmlinux 0x5632bd12 xfrm_state_lookup +EXPORT_SYMBOL vmlinux 0x5635a60a vmalloc_user +EXPORT_SYMBOL vmlinux 0x56514f10 __wait_on_buffer +EXPORT_SYMBOL vmlinux 0x56828b6e dst_alloc +EXPORT_SYMBOL vmlinux 0x569100c0 read_cache_pages +EXPORT_SYMBOL vmlinux 0x5691c766 unregister_quota_format +EXPORT_SYMBOL vmlinux 0x56977d85 br_handle_frame_hook +EXPORT_SYMBOL vmlinux 0x56b4b5e1 llc_sap_open +EXPORT_SYMBOL vmlinux 0x56c8799d scsi_kunmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x56d92d3c tc_classify +EXPORT_SYMBOL vmlinux 0x56f2a90c thermal_zone_unbind_cooling_device +EXPORT_SYMBOL vmlinux 0x56f494e0 smp_call_function +EXPORT_SYMBOL vmlinux 0x56faf946 ppp_unregister_compressor +EXPORT_SYMBOL vmlinux 0x57072242 bt_accept_dequeue +EXPORT_SYMBOL vmlinux 0x5707a417 tcp_getsockopt +EXPORT_SYMBOL vmlinux 0x5717e9eb __inet6_lookup_established +EXPORT_SYMBOL vmlinux 0x572c3cd7 scsi_host_lookup +EXPORT_SYMBOL vmlinux 0x572e85d4 blk_lookup_devt +EXPORT_SYMBOL vmlinux 0x57383fcf no_llseek +EXPORT_SYMBOL vmlinux 0x574554cb clear_bdi_congested +EXPORT_SYMBOL vmlinux 0x576d55a8 i2c_clients_command +EXPORT_SYMBOL vmlinux 0x577cc638 mutex_unlock +EXPORT_SYMBOL vmlinux 0x57d5a8ea phy_stop +EXPORT_SYMBOL vmlinux 0x57dbf49a compat_sock_common_setsockopt +EXPORT_SYMBOL vmlinux 0x57f0a6a7 tcp_v4_do_rcv +EXPORT_SYMBOL vmlinux 0x5810f6f2 put_io_context +EXPORT_SYMBOL vmlinux 0x5838f6c9 rtc_valid_tm +EXPORT_SYMBOL vmlinux 0x583c43c0 sk_stream_write_space +EXPORT_SYMBOL vmlinux 0x584738f9 rdmsr_safe_on_cpu +EXPORT_SYMBOL vmlinux 0x5857b225 ioread16_rep +EXPORT_SYMBOL vmlinux 0x588ab303 pcie_port_service_unregister +EXPORT_SYMBOL vmlinux 0x589ddb05 submit_bh +EXPORT_SYMBOL vmlinux 0x58cf6528 alloc_fddidev +EXPORT_SYMBOL vmlinux 0x58f17ca9 framebuffer_alloc +EXPORT_SYMBOL vmlinux 0x58f4bed8 qdisc_reset +EXPORT_SYMBOL vmlinux 0x58f895d8 sock_no_poll +EXPORT_SYMBOL vmlinux 0x590ce35a blk_queue_max_hw_segments +EXPORT_SYMBOL vmlinux 0x5934392b fb_register_client +EXPORT_SYMBOL vmlinux 0x5938f506 misc_deregister +EXPORT_SYMBOL vmlinux 0x594bf15b ioport_map +EXPORT_SYMBOL vmlinux 0x59706f79 nf_log_unregister_pf +EXPORT_SYMBOL vmlinux 0x5984e4fd acpi_processor_register_performance +EXPORT_SYMBOL vmlinux 0x59a245c1 tcp_close +EXPORT_SYMBOL vmlinux 0x59a7fdf5 elv_rb_del +EXPORT_SYMBOL vmlinux 0x59d696b6 register_module_notifier +EXPORT_SYMBOL vmlinux 0x59d71c73 vlan_ioctl_set +EXPORT_SYMBOL vmlinux 0x5a1e9d72 ppp_input_error +EXPORT_SYMBOL vmlinux 0x5a34a45c __kmalloc +EXPORT_SYMBOL vmlinux 0x5a4896a8 __put_user_2 +EXPORT_SYMBOL vmlinux 0x5a5e7ea3 simple_read_from_buffer +EXPORT_SYMBOL vmlinux 0x5a5fc2b0 ilookup5 +EXPORT_SYMBOL vmlinux 0x5a69219f __up_write +EXPORT_SYMBOL vmlinux 0x5a744b86 netlink_set_nonroot +EXPORT_SYMBOL vmlinux 0x5a7d7045 pci_enable_msi +EXPORT_SYMBOL vmlinux 0x5ab5a456 inet_dev_addr_type +EXPORT_SYMBOL vmlinux 0x5ac376a5 acpi_install_fixed_event_handler +EXPORT_SYMBOL vmlinux 0x5aca96a8 agp_free_page_array +EXPORT_SYMBOL vmlinux 0x5b00783d unlock_buffer +EXPORT_SYMBOL vmlinux 0x5b087862 posix_unblock_lock +EXPORT_SYMBOL vmlinux 0x5b51c6a7 acpi_walk_resources +EXPORT_SYMBOL vmlinux 0x5bae2eac acpi_extract_package +EXPORT_SYMBOL vmlinux 0x5bec44cb __down_write +EXPORT_SYMBOL vmlinux 0x5c2775ab dm_kcopyd_copy +EXPORT_SYMBOL vmlinux 0x5c4631d5 hci_register_cb +EXPORT_SYMBOL vmlinux 0x5c46b6fa posix_acl_chmod_masq +EXPORT_SYMBOL vmlinux 0x5c709821 pcim_pin_device +EXPORT_SYMBOL vmlinux 0x5ca0000d schedule_delayed_work_on +EXPORT_SYMBOL vmlinux 0x5cae8e03 page_follow_link_light +EXPORT_SYMBOL vmlinux 0x5cc8e015 iov_iter_single_seg_count +EXPORT_SYMBOL vmlinux 0x5cce9095 inet_ioctl +EXPORT_SYMBOL vmlinux 0x5cfb632f dma_async_client_unregister +EXPORT_SYMBOL vmlinux 0x5d096bf1 __mpage_writepage +EXPORT_SYMBOL vmlinux 0x5d113035 vm_stat +EXPORT_SYMBOL vmlinux 0x5d73b5f8 km_waitq +EXPORT_SYMBOL vmlinux 0x5d959196 register_atm_ioctl +EXPORT_SYMBOL vmlinux 0x5d982b15 inet6_register_protosw +EXPORT_SYMBOL vmlinux 0x5db8a9df pagecache_write_begin +EXPORT_SYMBOL vmlinux 0x5dbcfa4f boot_cpu_physical_apicid +EXPORT_SYMBOL vmlinux 0x5dfff93f open_by_devnum +EXPORT_SYMBOL vmlinux 0x5e177a0d filemap_fdatawrite +EXPORT_SYMBOL vmlinux 0x5e2fa18a bio_init +EXPORT_SYMBOL vmlinux 0x5e35dbc7 pci_disable_msi +EXPORT_SYMBOL vmlinux 0x5e3a178c vmalloc_to_page +EXPORT_SYMBOL vmlinux 0x5e3f29bc con_copy_unimap +EXPORT_SYMBOL vmlinux 0x5e4e27aa eth_header_cache +EXPORT_SYMBOL vmlinux 0x5e79ebec gen_replace_estimator +EXPORT_SYMBOL vmlinux 0x5e9f09df get_io_context +EXPORT_SYMBOL vmlinux 0x5e9f4d20 cont_write_begin +EXPORT_SYMBOL vmlinux 0x5ea520c5 tcp_select_initial_window +EXPORT_SYMBOL vmlinux 0x5ed040b0 pm_set_vt_switch +EXPORT_SYMBOL vmlinux 0x5edd0762 bin2bcd +EXPORT_SYMBOL vmlinux 0x5f125ff1 get_user_pages +EXPORT_SYMBOL vmlinux 0x5f2ab215 sget +EXPORT_SYMBOL vmlinux 0x5f5d3857 blk_rq_count_integrity_sg +EXPORT_SYMBOL vmlinux 0x5f80c434 lock_may_read +EXPORT_SYMBOL vmlinux 0x5fa70ddf nf_ct_attach +EXPORT_SYMBOL vmlinux 0x5faeca90 unmap_mapping_range +EXPORT_SYMBOL vmlinux 0x5fb55341 __free_pages +EXPORT_SYMBOL vmlinux 0x5fe99421 elv_add_request +EXPORT_SYMBOL vmlinux 0x5ff42b08 acpi_video_get_capabilities +EXPORT_SYMBOL vmlinux 0x5ffdef84 __breadahead +EXPORT_SYMBOL vmlinux 0x600683d3 do_unblank_screen +EXPORT_SYMBOL vmlinux 0x600743be journal_get_undo_access +EXPORT_SYMBOL vmlinux 0x6049ea1f shrink_dcache_sb +EXPORT_SYMBOL vmlinux 0x605c8954 sock_i_ino +EXPORT_SYMBOL vmlinux 0x605c8bde radix_tree_delete +EXPORT_SYMBOL vmlinux 0x605cdc41 journal_errno +EXPORT_SYMBOL vmlinux 0x6061957d in6_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0x607d9ec1 register_exec_domain +EXPORT_SYMBOL vmlinux 0x608ac795 ppp_unit_number +EXPORT_SYMBOL vmlinux 0x608c2831 warn_on_slowpath +EXPORT_SYMBOL vmlinux 0x609f1c7e synchronize_net +EXPORT_SYMBOL vmlinux 0x60a32ea9 pm_power_off +EXPORT_SYMBOL vmlinux 0x60b242d6 xfrm6_prepare_output +EXPORT_SYMBOL vmlinux 0x60ccc549 inet_dgram_ops +EXPORT_SYMBOL vmlinux 0x60eacf77 scsi_execute +EXPORT_SYMBOL vmlinux 0x60ec7101 dev_queue_xmit +EXPORT_SYMBOL vmlinux 0x6111e1bc init_timer +EXPORT_SYMBOL vmlinux 0x612390ad netpoll_set_trap +EXPORT_SYMBOL vmlinux 0x6148f0c0 __netdev_alloc_skb +EXPORT_SYMBOL vmlinux 0x6157c9e3 scsi_add_device +EXPORT_SYMBOL vmlinux 0x6159c44d request_key_async +EXPORT_SYMBOL vmlinux 0x618d8299 set_notify_swap_entry_free +EXPORT_SYMBOL vmlinux 0x61b7b126 simple_strtoull +EXPORT_SYMBOL vmlinux 0x61c1c365 unregister_key_type +EXPORT_SYMBOL vmlinux 0x61e948f1 audit_log_start +EXPORT_SYMBOL vmlinux 0x62019176 acpi_match_device_ids +EXPORT_SYMBOL vmlinux 0x62049256 acpi_disable +EXPORT_SYMBOL vmlinux 0x6218142a elv_queue_empty +EXPORT_SYMBOL vmlinux 0x6237f6b5 acpi_enable_event +EXPORT_SYMBOL vmlinux 0x62602f5a tty_port_alloc_xmit_buf +EXPORT_SYMBOL vmlinux 0x62737e1d sock_unregister +EXPORT_SYMBOL vmlinux 0x62748e70 acpi_set_current_resources +EXPORT_SYMBOL vmlinux 0x62827bec security_secctx_to_secid +EXPORT_SYMBOL vmlinux 0x629540f8 hci_conn_encrypt +EXPORT_SYMBOL vmlinux 0x62c53f85 bio_copy_user +EXPORT_SYMBOL vmlinux 0x62ce7313 blk_alloc_queue_node +EXPORT_SYMBOL vmlinux 0x62e5a5ab d_instantiate_unique +EXPORT_SYMBOL vmlinux 0x635426fd bio_integrity_add_page +EXPORT_SYMBOL vmlinux 0x636a5691 acpi_register_ioapic +EXPORT_SYMBOL vmlinux 0x636d2945 nf_log_unregister +EXPORT_SYMBOL vmlinux 0x6371f7b5 inet_put_port +EXPORT_SYMBOL vmlinux 0x63a31199 blk_queue_max_sectors +EXPORT_SYMBOL vmlinux 0x63b60516 dm_io +EXPORT_SYMBOL vmlinux 0x63db67fc kobject_set_name +EXPORT_SYMBOL vmlinux 0x63ecad53 register_netdevice_notifier +EXPORT_SYMBOL vmlinux 0x63f1d58f request_key_async_with_auxdata +EXPORT_SYMBOL vmlinux 0x63fc232f strlen_user +EXPORT_SYMBOL vmlinux 0x6403e338 tcp_memory_pressure +EXPORT_SYMBOL vmlinux 0x641b1bd3 scsi_dma_map +EXPORT_SYMBOL vmlinux 0x642e54ac __wake_up +EXPORT_SYMBOL vmlinux 0x6451294b posix_acl_valid +EXPORT_SYMBOL vmlinux 0x6466a1e6 mempool_alloc +EXPORT_SYMBOL vmlinux 0x6478134c ec_burst_enable +EXPORT_SYMBOL vmlinux 0x6485ca36 pci_set_dma_mask +EXPORT_SYMBOL vmlinux 0x6488aab0 unregister_md_personality +EXPORT_SYMBOL vmlinux 0x64999478 congestion_wait +EXPORT_SYMBOL vmlinux 0x649d136a elv_rb_find +EXPORT_SYMBOL vmlinux 0x64cd5d16 init_waitqueue_head +EXPORT_SYMBOL vmlinux 0x64d6ec86 vfs_quota_on_path +EXPORT_SYMBOL vmlinux 0x64eae7ad set_memory_array_wb +EXPORT_SYMBOL vmlinux 0x65002a14 scsicam_bios_param +EXPORT_SYMBOL vmlinux 0x650128e7 br_fdb_get_hook +EXPORT_SYMBOL vmlinux 0x650fb346 add_wait_queue +EXPORT_SYMBOL vmlinux 0x651a4139 test_taint +EXPORT_SYMBOL vmlinux 0x65408378 zlib_inflate_blob +EXPORT_SYMBOL vmlinux 0x65414e67 dev_valid_name +EXPORT_SYMBOL vmlinux 0x659611d7 rtnl_set_sk_err +EXPORT_SYMBOL vmlinux 0x65b862ba sk_filter +EXPORT_SYMBOL vmlinux 0x65de574f ethtool_op_set_flags +EXPORT_SYMBOL vmlinux 0x65f205dd jbd2_journal_create +EXPORT_SYMBOL vmlinux 0x65f873a3 scsi_print_result +EXPORT_SYMBOL vmlinux 0x66373df5 uart_get_baud_rate +EXPORT_SYMBOL vmlinux 0x666c233a iw_handler_set_thrspy +EXPORT_SYMBOL vmlinux 0x668da8d5 zlib_inflateIncomp +EXPORT_SYMBOL vmlinux 0x66b7b5a0 fget +EXPORT_SYMBOL vmlinux 0x672144bd strlcpy +EXPORT_SYMBOL vmlinux 0x6725f99e bt_accept_enqueue +EXPORT_SYMBOL vmlinux 0x6729d3df __get_user_4 +EXPORT_SYMBOL vmlinux 0x673f815e agp_bridges +EXPORT_SYMBOL vmlinux 0x6774180c jbd2_journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0x678ed706 tcf_exts_validate +EXPORT_SYMBOL vmlinux 0x67b27ec1 tty_std_termios +EXPORT_SYMBOL vmlinux 0x67be8276 xfrm_state_delete +EXPORT_SYMBOL vmlinux 0x67c69713 agp_generic_free_gatt_table +EXPORT_SYMBOL vmlinux 0x67dfe977 block_sync_page +EXPORT_SYMBOL vmlinux 0x67e71b77 __mutex_init +EXPORT_SYMBOL vmlinux 0x67f4bc17 __xfrm_decode_session +EXPORT_SYMBOL vmlinux 0x680bed94 netlink_unicast +EXPORT_SYMBOL vmlinux 0x68257c4c swiotlb_map_sg_attrs +EXPORT_SYMBOL vmlinux 0x6862a8c0 pci_reenable_device +EXPORT_SYMBOL vmlinux 0x687346ec __xfrm_state_destroy +EXPORT_SYMBOL vmlinux 0x688f0af4 _cpu_pda +EXPORT_SYMBOL vmlinux 0x68a1d5b9 scsi_dma_unmap +EXPORT_SYMBOL vmlinux 0x68c2b39c dma_async_memcpy_buf_to_pg +EXPORT_SYMBOL vmlinux 0x68c52436 dev_get_by_name +EXPORT_SYMBOL vmlinux 0x6907d4e9 idr_for_each +EXPORT_SYMBOL vmlinux 0x690f11f8 ether_setup +EXPORT_SYMBOL vmlinux 0x691445ec skb_recycle_check +EXPORT_SYMBOL vmlinux 0x69271cb8 tty_port_tty_set +EXPORT_SYMBOL vmlinux 0x692cfb18 dev_getbyhwaddr +EXPORT_SYMBOL vmlinux 0x693570a3 km_query +EXPORT_SYMBOL vmlinux 0x693971ad tcp_v4_send_check +EXPORT_SYMBOL vmlinux 0x693dc7c8 boot_cpu_data +EXPORT_SYMBOL vmlinux 0x6957defb find_vma +EXPORT_SYMBOL vmlinux 0x695df447 hci_conn_check_link_mode +EXPORT_SYMBOL vmlinux 0x6971447a rtc_month_days +EXPORT_SYMBOL vmlinux 0x69757b10 simple_transaction_release +EXPORT_SYMBOL vmlinux 0x69927dff try_acquire_console_sem +EXPORT_SYMBOL vmlinux 0x699859f7 input_unregister_handler +EXPORT_SYMBOL vmlinux 0x69a0ca7d iowrite16be +EXPORT_SYMBOL vmlinux 0x69a358a6 iomem_resource +EXPORT_SYMBOL vmlinux 0x69b91767 do_sync_read +EXPORT_SYMBOL vmlinux 0x69bfc5e3 lock_may_write +EXPORT_SYMBOL vmlinux 0x69c8c1d5 security_req_classify_flow +EXPORT_SYMBOL vmlinux 0x69d2575f efi +EXPORT_SYMBOL vmlinux 0x69d38ed9 __scsi_print_sense +EXPORT_SYMBOL vmlinux 0x69d52d57 agp_generic_remove_memory +EXPORT_SYMBOL vmlinux 0x69e27c7a bitmap_copy_le +EXPORT_SYMBOL vmlinux 0x69f39cde blk_queue_prep_rq +EXPORT_SYMBOL vmlinux 0x6a037cf1 mempool_kfree +EXPORT_SYMBOL vmlinux 0x6a47571d __set_personality +EXPORT_SYMBOL vmlinux 0x6a5f98a0 ida_get_new_above +EXPORT_SYMBOL vmlinux 0x6a5fa363 sigprocmask +EXPORT_SYMBOL vmlinux 0x6a87ea76 pci_bus_add_devices +EXPORT_SYMBOL vmlinux 0x6acb973d iowrite32be +EXPORT_SYMBOL vmlinux 0x6ad85887 acpi_enable_gpe +EXPORT_SYMBOL vmlinux 0x6add5c9a dmi_find_device +EXPORT_SYMBOL vmlinux 0x6addb1fe pci_bus_type +EXPORT_SYMBOL vmlinux 0x6af9b725 hci_recv_fragment +EXPORT_SYMBOL vmlinux 0x6b1b67d3 __bdevname +EXPORT_SYMBOL vmlinux 0x6b2dc060 dump_stack +EXPORT_SYMBOL vmlinux 0x6b304413 bio_integrity_prep +EXPORT_SYMBOL vmlinux 0x6b4e5a52 radix_tree_lookup_slot +EXPORT_SYMBOL vmlinux 0x6b9b88f3 sleep_on +EXPORT_SYMBOL vmlinux 0x6ba2a6d8 nlmsg_notify +EXPORT_SYMBOL vmlinux 0x6bafbced mod_timer +EXPORT_SYMBOL vmlinux 0x6bc56c67 radix_tree_next_hole +EXPORT_SYMBOL vmlinux 0x6bd83313 generic_getxattr +EXPORT_SYMBOL vmlinux 0x6bdcfd99 qdisc_class_hash_remove +EXPORT_SYMBOL vmlinux 0x6bf997f7 pci_enable_device_mem +EXPORT_SYMBOL vmlinux 0x6c2c0141 dquot_free_inode +EXPORT_SYMBOL vmlinux 0x6c389761 acpi_bus_get_private_data +EXPORT_SYMBOL vmlinux 0x6c3af89b hci_suspend_dev +EXPORT_SYMBOL vmlinux 0x6c5e0743 alloc_trdev +EXPORT_SYMBOL vmlinux 0x6c61ce70 num_registered_fb +EXPORT_SYMBOL vmlinux 0x6c702af7 sysctl_udp_rmem_min +EXPORT_SYMBOL vmlinux 0x6ca24339 find_lock_page +EXPORT_SYMBOL vmlinux 0x6cbe7632 posix_acl_to_xattr +EXPORT_SYMBOL vmlinux 0x6d07560f vc_cons +EXPORT_SYMBOL vmlinux 0x6d0da34c param_get_short +EXPORT_SYMBOL vmlinux 0x6d185df4 simple_set_mnt +EXPORT_SYMBOL vmlinux 0x6d1ced27 vcc_sklist_lock +EXPORT_SYMBOL vmlinux 0x6d205e2e bdget +EXPORT_SYMBOL vmlinux 0x6d27ef64 __bitmap_empty +EXPORT_SYMBOL vmlinux 0x6d294e43 clock_t_to_jiffies +EXPORT_SYMBOL vmlinux 0x6d334118 __get_user_8 +EXPORT_SYMBOL vmlinux 0x6d340f64 tty_termios_input_baud_rate +EXPORT_SYMBOL vmlinux 0x6d375299 netdev_class_create_file +EXPORT_SYMBOL vmlinux 0x6d429195 inet6_getname +EXPORT_SYMBOL vmlinux 0x6d44931d jbd2_journal_set_features +EXPORT_SYMBOL vmlinux 0x6d47d90d groups_free +EXPORT_SYMBOL vmlinux 0x6d80c3d5 kernel_sock_ioctl +EXPORT_SYMBOL vmlinux 0x6d9192f6 locks_mandatory_area +EXPORT_SYMBOL vmlinux 0x6d992637 skb_append_datato_frags +EXPORT_SYMBOL vmlinux 0x6dc0c24b complete_and_exit +EXPORT_SYMBOL vmlinux 0x6de6bf83 radix_tree_lookup +EXPORT_SYMBOL vmlinux 0x6def26b4 tty_port_free_xmit_buf +EXPORT_SYMBOL vmlinux 0x6def2db2 half_md4_transform +EXPORT_SYMBOL vmlinux 0x6df789b9 iput +EXPORT_SYMBOL vmlinux 0x6e07a54e acpi_get_gpe_status +EXPORT_SYMBOL vmlinux 0x6e1a4bbb udp_hash_lock +EXPORT_SYMBOL vmlinux 0x6e37e6e9 filemap_fault +EXPORT_SYMBOL vmlinux 0x6e720ff2 rtnl_unlock +EXPORT_SYMBOL vmlinux 0x6e8bf9e2 i2c_smbus_process_call +EXPORT_SYMBOL vmlinux 0x6e90beeb tcp_create_openreq_child +EXPORT_SYMBOL vmlinux 0x6e9c1d39 simple_statfs +EXPORT_SYMBOL vmlinux 0x6e9dd606 __symbol_put +EXPORT_SYMBOL vmlinux 0x6ead242b cond_resched_lock +EXPORT_SYMBOL vmlinux 0x6ef44eba audit_log_end +EXPORT_SYMBOL vmlinux 0x6f1c5c0f register_netdevice +EXPORT_SYMBOL vmlinux 0x6f24d2f1 generic_cont_expand_simple +EXPORT_SYMBOL vmlinux 0x6f277045 phy_register_fixup_for_uid +EXPORT_SYMBOL vmlinux 0x6f41e66b pci_find_bus +EXPORT_SYMBOL vmlinux 0x6f63083f inetdev_by_index +EXPORT_SYMBOL vmlinux 0x6f7145f1 start_tty +EXPORT_SYMBOL vmlinux 0x6fa61eb8 blk_queue_set_discard +EXPORT_SYMBOL vmlinux 0x6fafa502 blk_rq_unmap_user +EXPORT_SYMBOL vmlinux 0x6fb8a0a9 simple_release_fs +EXPORT_SYMBOL vmlinux 0x6fca8d78 page_symlink_inode_operations +EXPORT_SYMBOL vmlinux 0x6fcb87a1 touch_softlockup_watchdog +EXPORT_SYMBOL vmlinux 0x6fd0000d qdisc_watchdog_init +EXPORT_SYMBOL vmlinux 0x6fd0e144 neigh_connected_output +EXPORT_SYMBOL vmlinux 0x7008a9b7 timespec_to_jiffies +EXPORT_SYMBOL vmlinux 0x7009c81a block_page_mkwrite +EXPORT_SYMBOL vmlinux 0x7016a046 kernel_getsockopt +EXPORT_SYMBOL vmlinux 0x70296335 tcp_child_process +EXPORT_SYMBOL vmlinux 0x702ff8e7 pnp_register_driver +EXPORT_SYMBOL vmlinux 0x7041e67a compat_sock_common_getsockopt +EXPORT_SYMBOL vmlinux 0x70538c79 textsearch_find_continuous +EXPORT_SYMBOL vmlinux 0x7054a3e4 request_dma +EXPORT_SYMBOL vmlinux 0x7094f8ae bt_err +EXPORT_SYMBOL vmlinux 0x70a253e1 bdevname +EXPORT_SYMBOL vmlinux 0x70a3bba0 vfs_mkdir +EXPORT_SYMBOL vmlinux 0x70bcb65e generic_readlink +EXPORT_SYMBOL vmlinux 0x70d8ab82 acpi_acquire_global_lock +EXPORT_SYMBOL vmlinux 0x70e0d61f cpu_all_bits +EXPORT_SYMBOL vmlinux 0x70f99f75 sock_no_bind +EXPORT_SYMBOL vmlinux 0x7101267c pci_set_dma_max_seg_size +EXPORT_SYMBOL vmlinux 0x711da2e9 bio_integrity_set_tag +EXPORT_SYMBOL vmlinux 0x71225de1 kmem_cache_create +EXPORT_SYMBOL vmlinux 0x7128abae get_agp_version +EXPORT_SYMBOL vmlinux 0x7129e5f8 hex_asc +EXPORT_SYMBOL vmlinux 0x712aa29b _spin_lock_irqsave +EXPORT_SYMBOL vmlinux 0x71356fba remove_wait_queue +EXPORT_SYMBOL vmlinux 0x716079a3 phy_start_aneg +EXPORT_SYMBOL vmlinux 0x7171121c overflowgid +EXPORT_SYMBOL vmlinux 0x7181cec5 tcp_sendmsg +EXPORT_SYMBOL vmlinux 0x7191a0d9 path_put +EXPORT_SYMBOL vmlinux 0x7195e42b pci_release_selected_regions +EXPORT_SYMBOL vmlinux 0x7196ae7e netlink_kernel_release +EXPORT_SYMBOL vmlinux 0x719faee7 free_netdev +EXPORT_SYMBOL vmlinux 0x71a50dbc register_blkdev +EXPORT_SYMBOL vmlinux 0x71a77529 sysctl_ms_jiffies +EXPORT_SYMBOL vmlinux 0x71c45fa8 seq_lseek +EXPORT_SYMBOL vmlinux 0x71c6cd8b init_net +EXPORT_SYMBOL vmlinux 0x71e74e33 d_delete +EXPORT_SYMBOL vmlinux 0x71f6eb38 sg_copy_from_buffer +EXPORT_SYMBOL vmlinux 0x71f7c5ef swiotlb_alloc_coherent +EXPORT_SYMBOL vmlinux 0x7223a6d7 get_write_access +EXPORT_SYMBOL vmlinux 0x7226644b scm_detach_fds +EXPORT_SYMBOL vmlinux 0x72270e35 do_gettimeofday +EXPORT_SYMBOL vmlinux 0x7242e96d strnchr +EXPORT_SYMBOL vmlinux 0x725068d8 truncate_inode_pages +EXPORT_SYMBOL vmlinux 0x725dc6df clocksource_register +EXPORT_SYMBOL vmlinux 0x7270d32d journal_forget +EXPORT_SYMBOL vmlinux 0x7277c6f7 netdev_class_remove_file +EXPORT_SYMBOL vmlinux 0x729fd68f tcf_unregister_action +EXPORT_SYMBOL vmlinux 0x72a97404 directly_mappable_cdev_bdi +EXPORT_SYMBOL vmlinux 0x72abd4d0 pci_do_scan_bus +EXPORT_SYMBOL vmlinux 0x72b243d4 free_dma +EXPORT_SYMBOL vmlinux 0x72bf2140 mtrr_add +EXPORT_SYMBOL vmlinux 0x72ea7b2d scsi_device_type +EXPORT_SYMBOL vmlinux 0x730de4af bdi_init +EXPORT_SYMBOL vmlinux 0x735a0bd5 native_io_delay +EXPORT_SYMBOL vmlinux 0x736bde60 cpufreq_get_policy +EXPORT_SYMBOL vmlinux 0x7389c9a8 acpi_bus_get_power +EXPORT_SYMBOL vmlinux 0x739ee22d gen_pool_add +EXPORT_SYMBOL vmlinux 0x73c174aa bio_uncopy_user +EXPORT_SYMBOL vmlinux 0x73c8390f acpi_unlock_battery_dir +EXPORT_SYMBOL vmlinux 0x7408e1d5 __elv_add_request +EXPORT_SYMBOL vmlinux 0x740a1b95 reserve_evntsel_nmi +EXPORT_SYMBOL vmlinux 0x7415fdc1 uart_remove_one_port +EXPORT_SYMBOL vmlinux 0x74162316 filemap_fdatawait +EXPORT_SYMBOL vmlinux 0x742c4215 register_con_driver +EXPORT_SYMBOL vmlinux 0x74399384 sock_wfree +EXPORT_SYMBOL vmlinux 0x744a7003 hippi_type_trans +EXPORT_SYMBOL vmlinux 0x746a1463 pci_try_set_mwi +EXPORT_SYMBOL vmlinux 0x747ad76c try_to_release_page +EXPORT_SYMBOL vmlinux 0x748162fb pci_setup_cardbus +EXPORT_SYMBOL vmlinux 0x74855e39 scsi_test_unit_ready +EXPORT_SYMBOL vmlinux 0x7485e15e unregister_chrdev_region +EXPORT_SYMBOL vmlinux 0x748caf40 down +EXPORT_SYMBOL vmlinux 0x74946de1 pci_set_consistent_dma_mask +EXPORT_SYMBOL vmlinux 0x74af0c65 unregister_snap_client +EXPORT_SYMBOL vmlinux 0x74bfdb28 phy_sanitize_settings +EXPORT_SYMBOL vmlinux 0x74cc1cbe unregister_cpu_notifier +EXPORT_SYMBOL vmlinux 0x74cc238d current_kernel_time +EXPORT_SYMBOL vmlinux 0x7523ba84 blk_queue_free_tags +EXPORT_SYMBOL vmlinux 0x752a5d25 blk_queue_make_request +EXPORT_SYMBOL vmlinux 0x7538b132 agp_off +EXPORT_SYMBOL vmlinux 0x7567e205 pv_cpu_ops +EXPORT_SYMBOL vmlinux 0x756e6992 strnicmp +EXPORT_SYMBOL vmlinux 0x7578cf96 rfkill_unregister +EXPORT_SYMBOL vmlinux 0x757df1f4 genphy_update_link +EXPORT_SYMBOL vmlinux 0x75a8bba1 ethtool_op_set_tso +EXPORT_SYMBOL vmlinux 0x75bdea12 iommu_area_alloc +EXPORT_SYMBOL vmlinux 0x75d6cb2b mmc_free_host +EXPORT_SYMBOL vmlinux 0x75dc9096 fb_set_cmap +EXPORT_SYMBOL vmlinux 0x75e4716f bio_split +EXPORT_SYMBOL vmlinux 0x75ea9531 key_negate_and_link +EXPORT_SYMBOL vmlinux 0x7600c416 generic_ro_fops +EXPORT_SYMBOL vmlinux 0x760a0f4f yield +EXPORT_SYMBOL vmlinux 0x760b437a unregister_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x760be277 ppp_unregister_channel +EXPORT_SYMBOL vmlinux 0x761668a8 i2c_smbus_xfer +EXPORT_SYMBOL vmlinux 0x7620d6b0 dquot_release +EXPORT_SYMBOL vmlinux 0x762affe9 blk_queue_update_dma_alignment +EXPORT_SYMBOL vmlinux 0x76350f6d blk_plug_device_unlocked +EXPORT_SYMBOL vmlinux 0x763ca220 pci_unregister_driver +EXPORT_SYMBOL vmlinux 0x764b38b2 compat_sock_get_timestampns +EXPORT_SYMBOL vmlinux 0x764bd77c request_resource +EXPORT_SYMBOL vmlinux 0x767293ab unlock_new_inode +EXPORT_SYMBOL vmlinux 0x767dd8fd acpi_get_irq_routing_table +EXPORT_SYMBOL vmlinux 0x767ddb02 set_memory_wc +EXPORT_SYMBOL vmlinux 0x76a09b21 inet_csk_accept +EXPORT_SYMBOL vmlinux 0x76bf656d __bitmap_shift_left +EXPORT_SYMBOL vmlinux 0x76d3cd60 laptop_mode +EXPORT_SYMBOL vmlinux 0x76d8a747 mpage_writepage +EXPORT_SYMBOL vmlinux 0x76eb1342 nobh_truncate_page +EXPORT_SYMBOL vmlinux 0x76f3f8a5 num_k8_northbridges +EXPORT_SYMBOL vmlinux 0x76faa91c agp_backend_acquire +EXPORT_SYMBOL vmlinux 0x771543e8 vfs_permission +EXPORT_SYMBOL vmlinux 0x77161035 init_buffer +EXPORT_SYMBOL vmlinux 0x77324e4b pnp_possible_config +EXPORT_SYMBOL vmlinux 0x7746aad1 sock_queue_rcv_skb +EXPORT_SYMBOL vmlinux 0x77489bd3 register_key_type +EXPORT_SYMBOL vmlinux 0x7751fff2 tcp_v4_md5_do_del +EXPORT_SYMBOL vmlinux 0x775481f1 scsi_free_host_dev +EXPORT_SYMBOL vmlinux 0x77557899 mmc_resume_host +EXPORT_SYMBOL vmlinux 0x7760dd18 nf_hook_slow +EXPORT_SYMBOL vmlinux 0x77624973 scsi_is_target_device +EXPORT_SYMBOL vmlinux 0x77664aee dma_async_tx_descriptor_init +EXPORT_SYMBOL vmlinux 0x776afed0 secpath_dup +EXPORT_SYMBOL vmlinux 0x7772220d rfkill_switch_all +EXPORT_SYMBOL vmlinux 0x778d3a1b vm_insert_pfn +EXPORT_SYMBOL vmlinux 0x77990a15 __nla_reserve +EXPORT_SYMBOL vmlinux 0x77a108df _write_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x77b6de43 blk_queue_dma_alignment +EXPORT_SYMBOL vmlinux 0x77b848b1 agp_free_memory +EXPORT_SYMBOL vmlinux 0x77bb88d2 nf_reinject +EXPORT_SYMBOL vmlinux 0x77d27770 bitmap_unplug +EXPORT_SYMBOL vmlinux 0x77ecac9f zlib_inflateEnd +EXPORT_SYMBOL vmlinux 0x77f53abc acpi_get_vendor_resource +EXPORT_SYMBOL vmlinux 0x782acba5 crc_t10dif +EXPORT_SYMBOL vmlinux 0x784041d7 inet_proto_csum_replace4 +EXPORT_SYMBOL vmlinux 0x784ed2fc handle_sysrq +EXPORT_SYMBOL vmlinux 0x785148a3 idr_destroy +EXPORT_SYMBOL vmlinux 0x788b5de9 blk_queue_ordered +EXPORT_SYMBOL vmlinux 0x78a484c9 _read_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x78df6bd7 no_pci_devices +EXPORT_SYMBOL vmlinux 0x78ea0b21 mmc_release_host +EXPORT_SYMBOL vmlinux 0x791a928c lookup_bdev +EXPORT_SYMBOL vmlinux 0x79230c86 generic_osync_inode +EXPORT_SYMBOL vmlinux 0x793b367f __sk_mem_schedule +EXPORT_SYMBOL vmlinux 0x794a6aef fb_blank +EXPORT_SYMBOL vmlinux 0x795392ba ethtool_op_set_tx_hw_csum +EXPORT_SYMBOL vmlinux 0x796fc5ce scsi_get_sense_info_fld +EXPORT_SYMBOL vmlinux 0x79aa04a2 get_random_bytes +EXPORT_SYMBOL vmlinux 0x79d8fbaa pnp_unregister_driver +EXPORT_SYMBOL vmlinux 0x7a01c274 devm_request_irq +EXPORT_SYMBOL vmlinux 0x7a2a837d strict_strtol +EXPORT_SYMBOL vmlinux 0x7a2e6a10 remove_inode_hash +EXPORT_SYMBOL vmlinux 0x7a40f215 scsi_ioctl +EXPORT_SYMBOL vmlinux 0x7a5ba15d vc_resize +EXPORT_SYMBOL vmlinux 0x7a6d1ba9 serio_reconnect +EXPORT_SYMBOL vmlinux 0x7a79107e pci_remove_bus_device +EXPORT_SYMBOL vmlinux 0x7a81bfc5 scsi_rescan_device +EXPORT_SYMBOL vmlinux 0x7a848702 _read_lock_irqsave +EXPORT_SYMBOL vmlinux 0x7a9877e5 register_sysrq_key +EXPORT_SYMBOL vmlinux 0x7ac959be pci_bus_alloc_resource +EXPORT_SYMBOL vmlinux 0x7ae73de1 alloc_pages_exact +EXPORT_SYMBOL vmlinux 0x7aec9089 clear_user +EXPORT_SYMBOL vmlinux 0x7b0c84c4 acpi_remove_table_handler +EXPORT_SYMBOL vmlinux 0x7b164761 xfrm_state_delete_tunnel +EXPORT_SYMBOL vmlinux 0x7b21ef9c hci_unregister_proto +EXPORT_SYMBOL vmlinux 0x7b453860 acpi_lock_battery_dir +EXPORT_SYMBOL vmlinux 0x7b4bdaac dcache_readdir +EXPORT_SYMBOL vmlinux 0x7b52a859 wrmsr_safe_on_cpu +EXPORT_SYMBOL vmlinux 0x7b5a6591 invalidate_inodes +EXPORT_SYMBOL vmlinux 0x7b8f4c40 key_create_or_update +EXPORT_SYMBOL vmlinux 0x7bc5ca03 acpi_processor_unregister_performance +EXPORT_SYMBOL vmlinux 0x7bff3be7 iov_iter_advance +EXPORT_SYMBOL vmlinux 0x7c46233a cpufreq_quick_get +EXPORT_SYMBOL vmlinux 0x7c469032 blk_run_queue +EXPORT_SYMBOL vmlinux 0x7c475db7 per_cpu__cpu_info +EXPORT_SYMBOL vmlinux 0x7c60d66e getname +EXPORT_SYMBOL vmlinux 0x7c61340c __release_region +EXPORT_SYMBOL vmlinux 0x7c7f1654 simple_transaction_get +EXPORT_SYMBOL vmlinux 0x7c904ded unregister_module_notifier +EXPORT_SYMBOL vmlinux 0x7c9a4dc8 key_alloc +EXPORT_SYMBOL vmlinux 0x7caf41cc block_read_full_page +EXPORT_SYMBOL vmlinux 0x7cb1ae69 cpu_down +EXPORT_SYMBOL vmlinux 0x7cb6b303 iw_handler_get_spy +EXPORT_SYMBOL vmlinux 0x7cbcfc30 netpoll_cleanup +EXPORT_SYMBOL vmlinux 0x7cdcee68 __rta_fill +EXPORT_SYMBOL vmlinux 0x7d01f731 sock_no_getsockopt +EXPORT_SYMBOL vmlinux 0x7d047e7e acpi_ut_exception +EXPORT_SYMBOL vmlinux 0x7d05b15c dev_close +EXPORT_SYMBOL vmlinux 0x7d08bc11 mdiobus_scan +EXPORT_SYMBOL vmlinux 0x7d11c268 jiffies +EXPORT_SYMBOL vmlinux 0x7d12f9fa __find_get_block +EXPORT_SYMBOL vmlinux 0x7d3d33d9 pci_bus_write_config_word +EXPORT_SYMBOL vmlinux 0x7d850612 utf8_mbstowcs +EXPORT_SYMBOL vmlinux 0x7d8b87df kthread_stop +EXPORT_SYMBOL vmlinux 0x7d8cce21 fib_default_rule_add +EXPORT_SYMBOL vmlinux 0x7d94f746 acpi_os_write_port +EXPORT_SYMBOL vmlinux 0x7d9dc765 invalidate_mapping_pages +EXPORT_SYMBOL vmlinux 0x7dceceac capable +EXPORT_SYMBOL vmlinux 0x7de9649b skb_copy +EXPORT_SYMBOL vmlinux 0x7dee8e84 mb_cache_entry_find_first +EXPORT_SYMBOL vmlinux 0x7e27c5b3 dev_unicast_add +EXPORT_SYMBOL vmlinux 0x7e2ced73 mmc_align_data_size +EXPORT_SYMBOL vmlinux 0x7e406779 simple_dir_inode_operations +EXPORT_SYMBOL vmlinux 0x7e434200 __scsi_add_device +EXPORT_SYMBOL vmlinux 0x7e436d5d inet_csk_clear_xmit_timers +EXPORT_SYMBOL vmlinux 0x7e50cd78 iw_handler_get_thrspy +EXPORT_SYMBOL vmlinux 0x7e663bba neigh_lookup_nodev +EXPORT_SYMBOL vmlinux 0x7e667392 redraw_screen +EXPORT_SYMBOL vmlinux 0x7e716da5 skb_insert +EXPORT_SYMBOL vmlinux 0x7e7e3408 scsi_prep_return +EXPORT_SYMBOL vmlinux 0x7e9ebb05 kernel_thread +EXPORT_SYMBOL vmlinux 0x7ec9bfbc strncpy +EXPORT_SYMBOL vmlinux 0x7ed697f2 scsi_cmd_ioctl +EXPORT_SYMBOL vmlinux 0x7ee91c1d _spin_trylock +EXPORT_SYMBOL vmlinux 0x7ef572c5 bitmap_end_sync +EXPORT_SYMBOL vmlinux 0x7f2390e4 scsi_mode_sense +EXPORT_SYMBOL vmlinux 0x7f24de73 jiffies_to_usecs +EXPORT_SYMBOL vmlinux 0x7f321afd i2c_smbus_read_word_data +EXPORT_SYMBOL vmlinux 0x7f4cf820 dget_locked +EXPORT_SYMBOL vmlinux 0x7f601852 dma_async_device_unregister +EXPORT_SYMBOL vmlinux 0x7f8723bd pcie_mch_quirk +EXPORT_SYMBOL vmlinux 0x7fc73e1d bdget_disk +EXPORT_SYMBOL vmlinux 0x7fe032e6 netlink_change_ngroups +EXPORT_SYMBOL vmlinux 0x8007530f __tcf_em_tree_match +EXPORT_SYMBOL vmlinux 0x8011de15 ip4_datagram_connect +EXPORT_SYMBOL vmlinux 0x804638f2 kfree_skb +EXPORT_SYMBOL vmlinux 0x805b1a98 scsi_print_sense +EXPORT_SYMBOL vmlinux 0x8068bc63 scsi_command_normalize_sense +EXPORT_SYMBOL vmlinux 0x806aa648 contig_page_data +EXPORT_SYMBOL vmlinux 0x80748186 blk_unplug +EXPORT_SYMBOL vmlinux 0x809b0a92 xfrm_policy_bysel_ctx +EXPORT_SYMBOL vmlinux 0x80b8fcc1 ip_mc_inc_group +EXPORT_SYMBOL vmlinux 0x80c3f50e dev_get_by_index +EXPORT_SYMBOL vmlinux 0x80c9a786 journal_check_used_features +EXPORT_SYMBOL vmlinux 0x80f43163 xfrm_state_update +EXPORT_SYMBOL vmlinux 0x810fc83f tcp_prot +EXPORT_SYMBOL vmlinux 0x812cddd6 end_request +EXPORT_SYMBOL vmlinux 0x81410400 tcp_shutdown +EXPORT_SYMBOL vmlinux 0x81472677 acpi_get_table +EXPORT_SYMBOL vmlinux 0x814b2d57 deactivate_super +EXPORT_SYMBOL vmlinux 0x814e7730 nf_ct_destroy +EXPORT_SYMBOL vmlinux 0x815b5dd4 match_octal +EXPORT_SYMBOL vmlinux 0x815f2897 empty_zero_page +EXPORT_SYMBOL vmlinux 0x8185aca6 netif_carrier_on +EXPORT_SYMBOL vmlinux 0x819fba62 dma_pool_destroy +EXPORT_SYMBOL vmlinux 0x81af529a xfrm_state_lookup_byaddr +EXPORT_SYMBOL vmlinux 0x81dbc061 do_sync_write +EXPORT_SYMBOL vmlinux 0x81e6b37f dmi_get_system_info +EXPORT_SYMBOL vmlinux 0x82042e78 zero_fill_bio +EXPORT_SYMBOL vmlinux 0x82072614 tasklet_kill +EXPORT_SYMBOL vmlinux 0x820d225f print_mac +EXPORT_SYMBOL vmlinux 0x821380dd alloc_fcdev +EXPORT_SYMBOL vmlinux 0x822723c8 cdev_alloc +EXPORT_SYMBOL vmlinux 0x823a27ed blk_integrity_compare +EXPORT_SYMBOL vmlinux 0x8251bcc3 bitmap_release_region +EXPORT_SYMBOL vmlinux 0x827b4492 tcf_action_exec +EXPORT_SYMBOL vmlinux 0x8286e248 d_alloc_name +EXPORT_SYMBOL vmlinux 0x829ead58 md_write_end +EXPORT_SYMBOL vmlinux 0x82e9c083 csum_partial_copy_fromiovecend +EXPORT_SYMBOL vmlinux 0x82f65633 dm_io_client_resize +EXPORT_SYMBOL vmlinux 0x82f7d015 keyring_clear +EXPORT_SYMBOL vmlinux 0x82ffeda5 tty_name +EXPORT_SYMBOL vmlinux 0x830e547b ioremap_prot +EXPORT_SYMBOL vmlinux 0x8317e20a completion_done +EXPORT_SYMBOL vmlinux 0x836482a3 genl_register_ops +EXPORT_SYMBOL vmlinux 0x83659ae7 qdisc_destroy +EXPORT_SYMBOL vmlinux 0x83800bfa kref_init +EXPORT_SYMBOL vmlinux 0x838ae1cb bio_endio +EXPORT_SYMBOL vmlinux 0x83a31fdb skb_push +EXPORT_SYMBOL vmlinux 0x83a476ce bitmap_scnlistprintf +EXPORT_SYMBOL vmlinux 0x83ce0d01 kobject_del +EXPORT_SYMBOL vmlinux 0x83d33c39 tcf_hash_check +EXPORT_SYMBOL vmlinux 0x83d8379b bio_unmap_user +EXPORT_SYMBOL vmlinux 0x83ea64dd tcf_em_tree_validate +EXPORT_SYMBOL vmlinux 0x841178a5 dev_load +EXPORT_SYMBOL vmlinux 0x84158773 agp_alloc_page_array +EXPORT_SYMBOL vmlinux 0x8417d647 tty_unthrottle +EXPORT_SYMBOL vmlinux 0x843f8362 pci_pme_active +EXPORT_SYMBOL vmlinux 0x8486ceac register_console +EXPORT_SYMBOL vmlinux 0x84a48d8b mb_cache_shrink +EXPORT_SYMBOL vmlinux 0x84b1ae82 atm_dev_lookup +EXPORT_SYMBOL vmlinux 0x84cbac36 blk_plug_device +EXPORT_SYMBOL vmlinux 0x84d7f055 gnet_stats_start_copy_compat +EXPORT_SYMBOL vmlinux 0x84db1396 neigh_table_clear +EXPORT_SYMBOL vmlinux 0x84ee6c04 i2c_add_adapter +EXPORT_SYMBOL vmlinux 0x8501cb29 bio_phys_segments +EXPORT_SYMBOL vmlinux 0x8525c138 tcp_recvmsg +EXPORT_SYMBOL vmlinux 0x853cbf6b pci_get_class +EXPORT_SYMBOL vmlinux 0x85539bc3 arp_xmit +EXPORT_SYMBOL vmlinux 0x85670f1d rtnl_is_locked +EXPORT_SYMBOL vmlinux 0x8590a80f sysctl_data +EXPORT_SYMBOL vmlinux 0x85a21e75 kernel_listen +EXPORT_SYMBOL vmlinux 0x85abc85f strncmp +EXPORT_SYMBOL vmlinux 0x85df9b6c strsep +EXPORT_SYMBOL vmlinux 0x85e772e4 tty_wait_until_sent +EXPORT_SYMBOL vmlinux 0x85eacd60 md_wait_for_blocked_rdev +EXPORT_SYMBOL vmlinux 0x85f37c53 kernel_getpeername +EXPORT_SYMBOL vmlinux 0x862bff88 i2c_register_driver +EXPORT_SYMBOL vmlinux 0x8631f188 radix_tree_tag_set +EXPORT_SYMBOL vmlinux 0x863cb91a utf8_wcstombs +EXPORT_SYMBOL vmlinux 0x864941a1 arp_broken_ops +EXPORT_SYMBOL vmlinux 0x8664f62e cpufreq_update_policy +EXPORT_SYMBOL vmlinux 0x8686dc2f scsi_prep_state_check +EXPORT_SYMBOL vmlinux 0x868acba5 get_options +EXPORT_SYMBOL vmlinux 0x86a9543c set_bdi_congested +EXPORT_SYMBOL vmlinux 0x86e6c29c simple_rename +EXPORT_SYMBOL vmlinux 0x86fb9b05 bitmap_parse_user +EXPORT_SYMBOL vmlinux 0x871c0a7e fiemap_check_flags +EXPORT_SYMBOL vmlinux 0x871d6f6c seq_puts +EXPORT_SYMBOL vmlinux 0x872e611f nf_log_register +EXPORT_SYMBOL vmlinux 0x8733e9a3 sleep_on_timeout +EXPORT_SYMBOL vmlinux 0x875729b3 jbd2_journal_extend +EXPORT_SYMBOL vmlinux 0x876dafc3 ec_write +EXPORT_SYMBOL vmlinux 0x8785725d param_set_charp +EXPORT_SYMBOL vmlinux 0x87861e60 neigh_compat_output +EXPORT_SYMBOL vmlinux 0x878ab3ce sysctl_tcp_adv_win_scale +EXPORT_SYMBOL vmlinux 0x87945010 give_up_console +EXPORT_SYMBOL vmlinux 0x87c5cffe unlock_rename +EXPORT_SYMBOL vmlinux 0x8804e025 agp3_generic_tlbflush +EXPORT_SYMBOL vmlinux 0x880a44f0 set_anon_super +EXPORT_SYMBOL vmlinux 0x881039d0 zlib_inflate +EXPORT_SYMBOL vmlinux 0x882c26db scsi_register +EXPORT_SYMBOL vmlinux 0x885bc707 acpi_bus_generate_proc_event +EXPORT_SYMBOL vmlinux 0x8872d11c pnp_unregister_card_driver +EXPORT_SYMBOL vmlinux 0x88b56bd1 ps2_drain +EXPORT_SYMBOL vmlinux 0x88c81e1c ppp_channel_index +EXPORT_SYMBOL vmlinux 0x892b26a0 set_memory_nx +EXPORT_SYMBOL vmlinux 0x8933c99e tcf_exts_dump_stats +EXPORT_SYMBOL vmlinux 0x89361e08 __nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0x8953bb27 del_timer +EXPORT_SYMBOL vmlinux 0x8957d569 dev_disable_lro +EXPORT_SYMBOL vmlinux 0x897473df mktime +EXPORT_SYMBOL vmlinux 0x898b1fec mutex_trylock +EXPORT_SYMBOL vmlinux 0x89949018 down_timeout +EXPORT_SYMBOL vmlinux 0x89d5538d fb_pad_aligned_buffer +EXPORT_SYMBOL vmlinux 0x89d66811 build_ehash_secret +EXPORT_SYMBOL vmlinux 0x8a32803d scsi_unblock_requests +EXPORT_SYMBOL vmlinux 0x8a3eabf0 __wait_on_bit +EXPORT_SYMBOL vmlinux 0x8a709909 bitmap_startwrite +EXPORT_SYMBOL vmlinux 0x8a7d1c31 high_memory +EXPORT_SYMBOL vmlinux 0x8a99a016 mempool_free_slab +EXPORT_SYMBOL vmlinux 0x8aa27945 netlink_ack +EXPORT_SYMBOL vmlinux 0x8aaf8654 mutex_lock +EXPORT_SYMBOL vmlinux 0x8ac40297 iommu_area_free +EXPORT_SYMBOL vmlinux 0x8b093e8f blk_queue_stack_limits +EXPORT_SYMBOL vmlinux 0x8b35e873 sg_last +EXPORT_SYMBOL vmlinux 0x8b3a226b udp_prot +EXPORT_SYMBOL vmlinux 0x8b439ba6 bio_integrity_alloc +EXPORT_SYMBOL vmlinux 0x8b50bd1c udp_memory_allocated +EXPORT_SYMBOL vmlinux 0x8b52d791 __scm_destroy +EXPORT_SYMBOL vmlinux 0x8b618d08 overflowuid +EXPORT_SYMBOL vmlinux 0x8b7fe311 kmemdup +EXPORT_SYMBOL vmlinux 0x8b922c0f __strnlen_user +EXPORT_SYMBOL vmlinux 0x8b966b63 sn_rtc_cycles_per_second +EXPORT_SYMBOL vmlinux 0x8b989cf9 acpi_bus_can_wakeup +EXPORT_SYMBOL vmlinux 0x8bca3aba vfs_llseek +EXPORT_SYMBOL vmlinux 0x8bda29e3 neigh_destroy +EXPORT_SYMBOL vmlinux 0x8c08b567 swiotlb_unmap_single +EXPORT_SYMBOL vmlinux 0x8c0f7f87 mmc_add_host +EXPORT_SYMBOL vmlinux 0x8c183cbe iowrite16 +EXPORT_SYMBOL vmlinux 0x8c59df14 tty_unregister_driver +EXPORT_SYMBOL vmlinux 0x8c67363c scsi_register_driver +EXPORT_SYMBOL vmlinux 0x8c7a10f6 pci_add_new_bus +EXPORT_SYMBOL vmlinux 0x8cc79cab iowrite16_rep +EXPORT_SYMBOL vmlinux 0x8cebbcd8 rtnl_create_link +EXPORT_SYMBOL vmlinux 0x8cfb9422 wireless_spy_update +EXPORT_SYMBOL vmlinux 0x8cfd0c17 __starget_for_each_device +EXPORT_SYMBOL vmlinux 0x8d3894f2 _ctype +EXPORT_SYMBOL vmlinux 0x8d551bef sysctl_tcp_rmem +EXPORT_SYMBOL vmlinux 0x8d57f908 module_refcount +EXPORT_SYMBOL vmlinux 0x8d6a6ed8 mb_cache_entry_get +EXPORT_SYMBOL vmlinux 0x8d741950 udp_lib_getsockopt +EXPORT_SYMBOL vmlinux 0x8d8d96c6 acpi_get_sleep_type_data +EXPORT_SYMBOL vmlinux 0x8da379a1 dquot_transfer +EXPORT_SYMBOL vmlinux 0x8da5cf90 nobh_writepage +EXPORT_SYMBOL vmlinux 0x8dbf55c9 udp_proc_register +EXPORT_SYMBOL vmlinux 0x8dca832f __percpu_counter_sum +EXPORT_SYMBOL vmlinux 0x8ddae97f serio_rescan +EXPORT_SYMBOL vmlinux 0x8df0192a journal_start +EXPORT_SYMBOL vmlinux 0x8e002cda acpi_remove_gpe_block +EXPORT_SYMBOL vmlinux 0x8e0637ba i8253_lock +EXPORT_SYMBOL vmlinux 0x8e0b7743 ipv6_ext_hdr +EXPORT_SYMBOL vmlinux 0x8e33c268 jbd2_journal_forget +EXPORT_SYMBOL vmlinux 0x8e3c9cc3 vprintk +EXPORT_SYMBOL vmlinux 0x8e4d403b noop_qdisc +EXPORT_SYMBOL vmlinux 0x8e4ff64b seq_printf +EXPORT_SYMBOL vmlinux 0x8e763ae1 send_remote_softirq +EXPORT_SYMBOL vmlinux 0x8f0e3a2c dev_kfree_skb_irq +EXPORT_SYMBOL vmlinux 0x8f17ff7b xfrm_input_resume +EXPORT_SYMBOL vmlinux 0x8f1ae4c9 pcim_iounmap +EXPORT_SYMBOL vmlinux 0x8f3745de journal_flush +EXPORT_SYMBOL vmlinux 0x8f45b14c fb_set_var +EXPORT_SYMBOL vmlinux 0x8f6096d2 unregister_sysctl_table +EXPORT_SYMBOL vmlinux 0x8f6b7950 set_irq_data +EXPORT_SYMBOL vmlinux 0x8f859662 generic_file_llseek +EXPORT_SYMBOL vmlinux 0x8f9c199c __get_user_2 +EXPORT_SYMBOL vmlinux 0x8fb29b6c mod_zone_page_state +EXPORT_SYMBOL vmlinux 0x8ff891de scsi_print_command +EXPORT_SYMBOL vmlinux 0x90022b44 xfrm_policy_flush +EXPORT_SYMBOL vmlinux 0x90035333 secure_tcpv6_sequence_number +EXPORT_SYMBOL vmlinux 0x9012c649 scsi_setup_fs_cmnd +EXPORT_SYMBOL vmlinux 0x907812d0 wait_on_page_bit +EXPORT_SYMBOL vmlinux 0x90a15841 jbd2_journal_init_dev +EXPORT_SYMBOL vmlinux 0x90a1601f dmi_check_system +EXPORT_SYMBOL vmlinux 0x90a943ba nmi_active +EXPORT_SYMBOL vmlinux 0x90ae6c3f unregister_framebuffer +EXPORT_SYMBOL vmlinux 0x910097b6 acpi_get_hp_hw_control_from_firmware +EXPORT_SYMBOL vmlinux 0x911d3001 __splice_from_pipe +EXPORT_SYMBOL vmlinux 0x9137355d pci_bus_read_config_byte +EXPORT_SYMBOL vmlinux 0x9137ab13 bio_integrity_endio +EXPORT_SYMBOL vmlinux 0x9144a8e2 ec_burst_disable +EXPORT_SYMBOL vmlinux 0x9144e262 thaw_bdev +EXPORT_SYMBOL vmlinux 0x91481982 __ratelimit +EXPORT_SYMBOL vmlinux 0x91539557 acpi_notifier_call_chain +EXPORT_SYMBOL vmlinux 0x91607d95 set_memory_wb +EXPORT_SYMBOL vmlinux 0x91724aae inet_sock_destruct +EXPORT_SYMBOL vmlinux 0x91865d16 dma_pool_free +EXPORT_SYMBOL vmlinux 0x91b6b487 tcp_v4_md5_do_add +EXPORT_SYMBOL vmlinux 0x91ca8959 acpi_get_register +EXPORT_SYMBOL vmlinux 0x920f8ea4 get_sb_pseudo +EXPORT_SYMBOL vmlinux 0x922af490 pci_bus_write_config_byte +EXPORT_SYMBOL vmlinux 0x92392cd9 iov_shorten +EXPORT_SYMBOL vmlinux 0x926de07b jbd2_journal_begin_ordered_truncate +EXPORT_SYMBOL vmlinux 0x927e989f gen_pool_alloc +EXPORT_SYMBOL vmlinux 0x92b202dd __lock_page +EXPORT_SYMBOL vmlinux 0x92ea4ae4 crc32_le +EXPORT_SYMBOL vmlinux 0x93017a66 i2c_attach_client +EXPORT_SYMBOL vmlinux 0x9305f8e6 cpufreq_get +EXPORT_SYMBOL vmlinux 0x931528d0 sock_no_connect +EXPORT_SYMBOL vmlinux 0x931b19ef phy_attach +EXPORT_SYMBOL vmlinux 0x931c8578 dev_open +EXPORT_SYMBOL vmlinux 0x9337a815 sg_miter_next +EXPORT_SYMBOL vmlinux 0x93439151 skb_make_writable +EXPORT_SYMBOL vmlinux 0x934f87f6 nf_register_queue_handler +EXPORT_SYMBOL vmlinux 0x9382c27d stop_tty +EXPORT_SYMBOL vmlinux 0x93a6e0b2 io_schedule +EXPORT_SYMBOL vmlinux 0x93abcfb7 set_disk_ro +EXPORT_SYMBOL vmlinux 0x93afa72e vm_get_page_prot +EXPORT_SYMBOL vmlinux 0x93b8ef56 mutex_lock_interruptible +EXPORT_SYMBOL vmlinux 0x93c0eca7 ip_route_output_key +EXPORT_SYMBOL vmlinux 0x93c69acf param_set_byte +EXPORT_SYMBOL vmlinux 0x93ca03de netif_rx +EXPORT_SYMBOL vmlinux 0x93cbd1ec _spin_lock_bh +EXPORT_SYMBOL vmlinux 0x93dd9edd fb_set_suspend +EXPORT_SYMBOL vmlinux 0x93ed6a1b mem_section +EXPORT_SYMBOL vmlinux 0x93fca811 __get_free_pages +EXPORT_SYMBOL vmlinux 0x943cf844 sock_create +EXPORT_SYMBOL vmlinux 0x943e868f ida_get_new +EXPORT_SYMBOL vmlinux 0x94556016 i2c_verify_client +EXPORT_SYMBOL vmlinux 0x945bc6a7 copy_from_user +EXPORT_SYMBOL vmlinux 0x946feb8c skb_queue_head +EXPORT_SYMBOL vmlinux 0x94883ab2 gnet_stats_copy_rate_est +EXPORT_SYMBOL vmlinux 0x94961283 vunmap +EXPORT_SYMBOL vmlinux 0x94bd77de dm_get_device +EXPORT_SYMBOL vmlinux 0x94c8e2ec key_type_keyring +EXPORT_SYMBOL vmlinux 0x94d57240 skb_copy_datagram_iovec +EXPORT_SYMBOL vmlinux 0x94ec74a8 i2c_release_client +EXPORT_SYMBOL vmlinux 0x94f62693 tty_free_termios +EXPORT_SYMBOL vmlinux 0x94fcf08e bioset_create +EXPORT_SYMBOL vmlinux 0x9515c0e7 block_prepare_write +EXPORT_SYMBOL vmlinux 0x95352ea9 acpi_check_mem_region +EXPORT_SYMBOL vmlinux 0x954488a4 syncookie_secret +EXPORT_SYMBOL vmlinux 0x9545af6d tasklet_init +EXPORT_SYMBOL vmlinux 0x954c8af3 dm_io_client_destroy +EXPORT_SYMBOL vmlinux 0x954cbb26 vsprintf +EXPORT_SYMBOL vmlinux 0x954e2599 iget_locked +EXPORT_SYMBOL vmlinux 0x957ebc01 sync_mapping_buffers +EXPORT_SYMBOL vmlinux 0x95b7a3cf call_usermodehelper_setup +EXPORT_SYMBOL vmlinux 0x95b9239e tcp_disconnect +EXPORT_SYMBOL vmlinux 0x95ceb864 key_update +EXPORT_SYMBOL vmlinux 0x95dd999a gnet_stats_finish_copy +EXPORT_SYMBOL vmlinux 0x96066cc6 swiotlb_dma_mapping_error +EXPORT_SYMBOL vmlinux 0x962bee22 pci_dev_put +EXPORT_SYMBOL vmlinux 0x96481cc7 per_cpu__x86_cpu_to_apicid +EXPORT_SYMBOL vmlinux 0x965d39c7 skb_free_datagram +EXPORT_SYMBOL vmlinux 0x96668bc1 vfs_read +EXPORT_SYMBOL vmlinux 0x967379be put_tty_driver +EXPORT_SYMBOL vmlinux 0x968f3f5f scsi_target_quiesce +EXPORT_SYMBOL vmlinux 0x96abc764 dst_release +EXPORT_SYMBOL vmlinux 0x96b18f4d simple_transaction_read +EXPORT_SYMBOL vmlinux 0x96b937dd qdisc_create_dflt +EXPORT_SYMBOL vmlinux 0x96cd2b04 scsi_sense_key_string +EXPORT_SYMBOL vmlinux 0x96d65908 dev_set_mac_address +EXPORT_SYMBOL vmlinux 0x96f33400 up_read +EXPORT_SYMBOL vmlinux 0x970b3894 ilookup5_nowait +EXPORT_SYMBOL vmlinux 0x970dc9dc uart_get_divisor +EXPORT_SYMBOL vmlinux 0x97234958 __scsi_alloc_queue +EXPORT_SYMBOL vmlinux 0x972750c5 mark_buffer_dirty +EXPORT_SYMBOL vmlinux 0x973873ab _spin_lock +EXPORT_SYMBOL vmlinux 0x9739b607 inode_set_bytes +EXPORT_SYMBOL vmlinux 0x9754ec10 radix_tree_preload +EXPORT_SYMBOL vmlinux 0x978eb519 poll_initwait +EXPORT_SYMBOL vmlinux 0x97a808f6 security_inode_init_security +EXPORT_SYMBOL vmlinux 0x97be1693 ht_create_irq +EXPORT_SYMBOL vmlinux 0x97d86283 __nla_put +EXPORT_SYMBOL vmlinux 0x97de0ddd acpi_install_gpe_block +EXPORT_SYMBOL vmlinux 0x97e9eb82 inode_double_unlock +EXPORT_SYMBOL vmlinux 0x97ec05a6 cfb_fillrect +EXPORT_SYMBOL vmlinux 0x980a6e3d pskb_expand_head +EXPORT_SYMBOL vmlinux 0x980a9b4f file_update_time +EXPORT_SYMBOL vmlinux 0x981caa83 bdi_destroy +EXPORT_SYMBOL vmlinux 0x98208eba key_link +EXPORT_SYMBOL vmlinux 0x9839449c load_nls +EXPORT_SYMBOL vmlinux 0x9863500a udp_lib_setsockopt +EXPORT_SYMBOL vmlinux 0x986e6135 fb_pad_unaligned_buffer +EXPORT_SYMBOL vmlinux 0x988cb93b remove_proc_entry +EXPORT_SYMBOL vmlinux 0x988ed85d set_memory_x +EXPORT_SYMBOL vmlinux 0x9892437d udp_poll +EXPORT_SYMBOL vmlinux 0x98b86016 __xfrm_lookup +EXPORT_SYMBOL vmlinux 0x98beef35 unlock_super +EXPORT_SYMBOL vmlinux 0x98c6b09d scsi_put_command +EXPORT_SYMBOL vmlinux 0x98de1daf sock_no_recvmsg +EXPORT_SYMBOL vmlinux 0x98e5f680 __devm_release_region +EXPORT_SYMBOL vmlinux 0x993c8662 kernel_accept +EXPORT_SYMBOL vmlinux 0x9957309a find_task_by_pid_type_ns +EXPORT_SYMBOL vmlinux 0x9970c3fa igrab +EXPORT_SYMBOL vmlinux 0x99792b4c jbd2_journal_lock_updates +EXPORT_SYMBOL vmlinux 0x99860a48 jbd2_journal_errno +EXPORT_SYMBOL vmlinux 0x998a90bf mark_buffer_dirty_inode +EXPORT_SYMBOL vmlinux 0x9994c0ca ps2_is_keyboard_id +EXPORT_SYMBOL vmlinux 0x999e8297 vfree +EXPORT_SYMBOL vmlinux 0x99aadb21 param_get_ulong +EXPORT_SYMBOL vmlinux 0x99bc6958 arch_acpi_processor_init_pdc +EXPORT_SYMBOL vmlinux 0x99bfbe39 get_unused_fd +EXPORT_SYMBOL vmlinux 0x99cdc86b sysctl_tcp_reordering +EXPORT_SYMBOL vmlinux 0x99ea12ce panic_blink +EXPORT_SYMBOL vmlinux 0x99feb0ad phy_start +EXPORT_SYMBOL vmlinux 0x9a1dfd65 strpbrk +EXPORT_SYMBOL vmlinux 0x9a225951 sync_blockdev +EXPORT_SYMBOL vmlinux 0x9a356159 llc_sap_close +EXPORT_SYMBOL vmlinux 0x9a5eef7f llc_build_and_send_ui_pkt +EXPORT_SYMBOL vmlinux 0x9a68e47b inode_init_once +EXPORT_SYMBOL vmlinux 0x9a6eb5ba per_cpu__cpu_core_map +EXPORT_SYMBOL vmlinux 0x9a70437b eth_header +EXPORT_SYMBOL vmlinux 0x9a738dcb blk_rq_map_user_iov +EXPORT_SYMBOL vmlinux 0x9a9985be percpu_counter_destroy +EXPORT_SYMBOL vmlinux 0x9aabc564 crc16 +EXPORT_SYMBOL vmlinux 0x9acd888a blk_queue_merge_bvec +EXPORT_SYMBOL vmlinux 0x9af0f806 register_gifconf +EXPORT_SYMBOL vmlinux 0x9b06c07f i2c_transfer +EXPORT_SYMBOL vmlinux 0x9b07312c unregister_netdevice +EXPORT_SYMBOL vmlinux 0x9b175304 mmc_detect_change +EXPORT_SYMBOL vmlinux 0x9b2db58a ipv6_chk_addr +EXPORT_SYMBOL vmlinux 0x9b388444 get_zeroed_page +EXPORT_SYMBOL vmlinux 0x9b3cd06c pci_bus_write_config_dword +EXPORT_SYMBOL vmlinux 0x9b3e0aa5 __vlan_hwaccel_rx +EXPORT_SYMBOL vmlinux 0x9b6408d6 gnet_stats_start_copy +EXPORT_SYMBOL vmlinux 0x9ba03769 security_task_getsecid +EXPORT_SYMBOL vmlinux 0x9ba7089d argv_split +EXPORT_SYMBOL vmlinux 0x9ba88a9d seq_read +EXPORT_SYMBOL vmlinux 0x9bba3e5d tcp_sendpage +EXPORT_SYMBOL vmlinux 0x9bc1530f seq_bitmap +EXPORT_SYMBOL vmlinux 0x9bc565c5 memcpy_fromiovecend +EXPORT_SYMBOL vmlinux 0x9bccf12d nla_put_nohdr +EXPORT_SYMBOL vmlinux 0x9bfbc3d5 jbd2_journal_stop +EXPORT_SYMBOL vmlinux 0x9c012508 fb_parse_edid +EXPORT_SYMBOL vmlinux 0x9c035a4a block_invalidatepage +EXPORT_SYMBOL vmlinux 0x9c0ea3cd memscan +EXPORT_SYMBOL vmlinux 0x9c491f60 sg_alloc_table +EXPORT_SYMBOL vmlinux 0x9c93b123 console_stop +EXPORT_SYMBOL vmlinux 0x9ca95a0e sort +EXPORT_SYMBOL vmlinux 0x9cb96e92 qdisc_put_rtab +EXPORT_SYMBOL vmlinux 0x9cc77ca0 scsi_host_alloc +EXPORT_SYMBOL vmlinux 0x9ccb2622 finish_wait +EXPORT_SYMBOL vmlinux 0x9ce88b95 eth_type_trans +EXPORT_SYMBOL vmlinux 0x9ced38aa down_trylock +EXPORT_SYMBOL vmlinux 0x9cfd56c5 scsi_print_status +EXPORT_SYMBOL vmlinux 0x9d0a94bf register_md_personality +EXPORT_SYMBOL vmlinux 0x9d11f223 generic_write_checks +EXPORT_SYMBOL vmlinux 0x9d33ef5e acpi_enable +EXPORT_SYMBOL vmlinux 0x9d4c3461 jbd2_journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0x9d711f1f percpu_counter_init +EXPORT_SYMBOL vmlinux 0x9d7bdca5 blk_requeue_request +EXPORT_SYMBOL vmlinux 0x9d821191 xfrm6_input_addr +EXPORT_SYMBOL vmlinux 0x9d8b9cbe inet_stream_ops +EXPORT_SYMBOL vmlinux 0x9d9563f3 cfb_copyarea +EXPORT_SYMBOL vmlinux 0x9db21624 hex_dump_to_buffer +EXPORT_SYMBOL vmlinux 0x9dde8322 ipv6_setsockopt +EXPORT_SYMBOL vmlinux 0x9df53af6 agp_generic_insert_memory +EXPORT_SYMBOL vmlinux 0x9e1723ce usb_serial_resume +EXPORT_SYMBOL vmlinux 0x9e251a06 xfrm_state_alloc +EXPORT_SYMBOL vmlinux 0x9e2ba23e posix_test_lock +EXPORT_SYMBOL vmlinux 0x9e363b6b acpi_disable_gpe +EXPORT_SYMBOL vmlinux 0x9e38fc89 vcc_release_async +EXPORT_SYMBOL vmlinux 0x9e5142de genphy_read_status +EXPORT_SYMBOL vmlinux 0x9e5be29f scsi_reset_provider +EXPORT_SYMBOL vmlinux 0x9e64fbfe rtc_cmos_read +EXPORT_SYMBOL vmlinux 0x9e6a9388 end_buffer_read_sync +EXPORT_SYMBOL vmlinux 0x9e7d6bd0 __udelay +EXPORT_SYMBOL vmlinux 0x9e9cbb94 proto_unregister +EXPORT_SYMBOL vmlinux 0x9ea0ad49 __sg_free_table +EXPORT_SYMBOL vmlinux 0x9ea28ec7 acpi_evaluate_object +EXPORT_SYMBOL vmlinux 0x9ea8616d dev_change_flags +EXPORT_SYMBOL vmlinux 0x9eacbc13 d_instantiate +EXPORT_SYMBOL vmlinux 0x9ebd4c04 adjust_resource +EXPORT_SYMBOL vmlinux 0x9edbecae snprintf +EXPORT_SYMBOL vmlinux 0x9eecde16 do_brk +EXPORT_SYMBOL vmlinux 0x9eef8a19 mdiobus_write +EXPORT_SYMBOL vmlinux 0x9ef44061 cdrom_open +EXPORT_SYMBOL vmlinux 0x9ef63672 xfrm_find_acq_byseq +EXPORT_SYMBOL vmlinux 0x9ef749e2 unregister_chrdev +EXPORT_SYMBOL vmlinux 0x9f100139 jiffies_to_clock_t +EXPORT_SYMBOL vmlinux 0x9f10e62f kernel_connect +EXPORT_SYMBOL vmlinux 0x9f11d4c6 input_release_device +EXPORT_SYMBOL vmlinux 0x9f288ec1 vfs_link +EXPORT_SYMBOL vmlinux 0x9f2bdaac __bitmap_or +EXPORT_SYMBOL vmlinux 0x9f50ad81 ethtool_op_set_sg +EXPORT_SYMBOL vmlinux 0x9f5bad27 inet_del_protocol +EXPORT_SYMBOL vmlinux 0x9f5bb256 acpi_bus_get_status +EXPORT_SYMBOL vmlinux 0x9f6b6587 inet_frags_exit_net +EXPORT_SYMBOL vmlinux 0x9f8ae080 ethtool_op_get_tso +EXPORT_SYMBOL vmlinux 0x9f984513 strrchr +EXPORT_SYMBOL vmlinux 0x9fa274b4 dq_data_lock +EXPORT_SYMBOL vmlinux 0x9fe94a67 is_bad_inode +EXPORT_SYMBOL vmlinux 0x9feaf287 sonet_subtract_stats +EXPORT_SYMBOL vmlinux 0x9ff08d4d vfs_rename +EXPORT_SYMBOL vmlinux 0xa0240e9d generic_file_readonly_mmap +EXPORT_SYMBOL vmlinux 0xa0293d68 call_usermodehelper_stdinpipe +EXPORT_SYMBOL vmlinux 0xa03523d5 security_unix_stream_connect +EXPORT_SYMBOL vmlinux 0xa041068d dma_set_mask +EXPORT_SYMBOL vmlinux 0xa04a01bd qdisc_class_hash_insert +EXPORT_SYMBOL vmlinux 0xa05c03df mempool_kmalloc +EXPORT_SYMBOL vmlinux 0xa06d7419 remove_arg_zero +EXPORT_SYMBOL vmlinux 0xa0ad23d5 nf_register_sockopt +EXPORT_SYMBOL vmlinux 0xa0b04675 vmalloc_32 +EXPORT_SYMBOL vmlinux 0xa0ceef51 out_of_line_wait_on_bit +EXPORT_SYMBOL vmlinux 0xa0d26732 blk_queue_bounce_limit +EXPORT_SYMBOL vmlinux 0xa0fbac79 wake_up_bit +EXPORT_SYMBOL vmlinux 0xa108eb4d sysctl_optmem_max +EXPORT_SYMBOL vmlinux 0xa10dcc13 getrawmonotonic +EXPORT_SYMBOL vmlinux 0xa120d33c tty_unregister_ldisc +EXPORT_SYMBOL vmlinux 0xa123dbe2 scsi_cmd_print_sense_hdr +EXPORT_SYMBOL vmlinux 0xa1321b1e blk_queue_segment_boundary +EXPORT_SYMBOL vmlinux 0xa13798f8 printk_ratelimit +EXPORT_SYMBOL vmlinux 0xa161f34c inet_unregister_protosw +EXPORT_SYMBOL vmlinux 0xa1a3de46 generic_listxattr +EXPORT_SYMBOL vmlinux 0xa1b0163f __scsi_put_command +EXPORT_SYMBOL vmlinux 0xa1b759ce fb_add_videomode +EXPORT_SYMBOL vmlinux 0xa1c76e0a _cond_resched +EXPORT_SYMBOL vmlinux 0xa1ccf5a0 generic_removexattr +EXPORT_SYMBOL vmlinux 0xa1d3b72e inet_shutdown +EXPORT_SYMBOL vmlinux 0xa1e14039 balance_dirty_pages_ratelimited_nr +EXPORT_SYMBOL vmlinux 0xa1e6ee96 tcp_alloc_md5sig_pool +EXPORT_SYMBOL vmlinux 0xa1f4cd89 devm_iounmap +EXPORT_SYMBOL vmlinux 0xa20ce1b8 net_msg_warn +EXPORT_SYMBOL vmlinux 0xa222de6b nf_register_hooks +EXPORT_SYMBOL vmlinux 0xa27fdf75 generic_shutdown_super +EXPORT_SYMBOL vmlinux 0xa285db3e swiotlb_map_sg +EXPORT_SYMBOL vmlinux 0xa290736c setup_arg_pages +EXPORT_SYMBOL vmlinux 0xa2a1e5c9 _write_lock_bh +EXPORT_SYMBOL vmlinux 0xa2a5fd77 inet_ehash_secret +EXPORT_SYMBOL vmlinux 0xa2aa2a4e jbd2_journal_revoke +EXPORT_SYMBOL vmlinux 0xa2babe7f scsi_block_requests +EXPORT_SYMBOL vmlinux 0xa2eff383 __alloc_skb +EXPORT_SYMBOL vmlinux 0xa302bdca sock_no_getname +EXPORT_SYMBOL vmlinux 0xa319895a posix_lock_file_wait +EXPORT_SYMBOL vmlinux 0xa31f172d __copy_from_user_inatomic +EXPORT_SYMBOL vmlinux 0xa329f07e register_shrinker +EXPORT_SYMBOL vmlinux 0xa33f7c7c nla_strlcpy +EXPORT_SYMBOL vmlinux 0xa350a8f8 set_memory_array_uc +EXPORT_SYMBOL vmlinux 0xa35de80f ipv4_config +EXPORT_SYMBOL vmlinux 0xa361f73c input_set_capability +EXPORT_SYMBOL vmlinux 0xa38ab0ba i2c_probe +EXPORT_SYMBOL vmlinux 0xa38d3042 __kfree_skb +EXPORT_SYMBOL vmlinux 0xa395ef1c bt_sock_wait_state +EXPORT_SYMBOL vmlinux 0xa3a5be95 memmove +EXPORT_SYMBOL vmlinux 0xa3ba3b4c jbd2_journal_file_inode +EXPORT_SYMBOL vmlinux 0xa3bbcd80 acpi_set_gpe_type +EXPORT_SYMBOL vmlinux 0xa3c982e0 jbd2_journal_release_jbd_inode +EXPORT_SYMBOL vmlinux 0xa3ebcf22 console_start +EXPORT_SYMBOL vmlinux 0xa42596c5 page_zero_new_buffers +EXPORT_SYMBOL vmlinux 0xa4295360 textsearch_unregister +EXPORT_SYMBOL vmlinux 0xa44072fc posix_acl_alloc +EXPORT_SYMBOL vmlinux 0xa44ad274 wait_for_completion_interruptible_timeout +EXPORT_SYMBOL vmlinux 0xa45dcda5 log_wait_commit +EXPORT_SYMBOL vmlinux 0xa46bea97 cancel_dirty_page +EXPORT_SYMBOL vmlinux 0xa471e75b cdrom_get_last_written +EXPORT_SYMBOL vmlinux 0xa476fc6e qdisc_list_del +EXPORT_SYMBOL vmlinux 0xa4936133 kmem_cache_name +EXPORT_SYMBOL vmlinux 0xa4b94fea iowrite8_rep +EXPORT_SYMBOL vmlinux 0xa4d4f0e6 global_cache_flush +EXPORT_SYMBOL vmlinux 0xa4d8fe5f vfs_dq_drop +EXPORT_SYMBOL vmlinux 0xa4df1151 kref_set +EXPORT_SYMBOL vmlinux 0xa4e76ca3 dquot_alloc_inode +EXPORT_SYMBOL vmlinux 0xa506d10a kobject_init +EXPORT_SYMBOL vmlinux 0xa5114b0b pcie_port_service_register +EXPORT_SYMBOL vmlinux 0xa52bbc64 register_chrdev +EXPORT_SYMBOL vmlinux 0xa5423cc4 param_get_int +EXPORT_SYMBOL vmlinux 0xa5452482 tcp_md5_hash_skb_data +EXPORT_SYMBOL vmlinux 0xa5693df7 posix_acl_clone +EXPORT_SYMBOL vmlinux 0xa56f1315 mempool_free +EXPORT_SYMBOL vmlinux 0xa58b6804 nla_parse +EXPORT_SYMBOL vmlinux 0xa5922bb1 kfifo_init +EXPORT_SYMBOL vmlinux 0xa598e29c vesa_modes +EXPORT_SYMBOL vmlinux 0xa5ad131a linkwatch_fire_event +EXPORT_SYMBOL vmlinux 0xa5adbe8c ida_destroy +EXPORT_SYMBOL vmlinux 0xa6021043 ip6_frag_match +EXPORT_SYMBOL vmlinux 0xa6186361 dma_pool_create +EXPORT_SYMBOL vmlinux 0xa61d7316 cdrom_release +EXPORT_SYMBOL vmlinux 0xa63d85ab slhc_remember +EXPORT_SYMBOL vmlinux 0xa6484eae smp_call_function_mask +EXPORT_SYMBOL vmlinux 0xa6582bac vmap +EXPORT_SYMBOL vmlinux 0xa68124fa hweight8 +EXPORT_SYMBOL vmlinux 0xa681fe88 generate_random_uuid +EXPORT_SYMBOL vmlinux 0xa6857424 alloc_buffer_head +EXPORT_SYMBOL vmlinux 0xa69087d6 register_framebuffer +EXPORT_SYMBOL vmlinux 0xa6b83a2a set_pages_wb +EXPORT_SYMBOL vmlinux 0xa6d3799f bio_map_user +EXPORT_SYMBOL vmlinux 0xa6dcc773 rb_insert_color +EXPORT_SYMBOL vmlinux 0xa6e0fa68 k8_northbridges +EXPORT_SYMBOL vmlinux 0xa70d5c6a ethtool_op_get_tx_csum +EXPORT_SYMBOL vmlinux 0xa70fabbe release_evntsel_nmi +EXPORT_SYMBOL vmlinux 0xa73cba7b netdev_rx_csum_fault +EXPORT_SYMBOL vmlinux 0xa7502f48 jiffies_to_timeval +EXPORT_SYMBOL vmlinux 0xa75d6155 pci_find_device +EXPORT_SYMBOL vmlinux 0xa76dc0c8 locks_remove_posix +EXPORT_SYMBOL vmlinux 0xa76f5b40 neigh_update +EXPORT_SYMBOL vmlinux 0xa7760ad9 __scm_send +EXPORT_SYMBOL vmlinux 0xa7778241 get_sb_nodev +EXPORT_SYMBOL vmlinux 0xa780f383 ___pskb_trim +EXPORT_SYMBOL vmlinux 0xa78f6a23 skb_gso_segment +EXPORT_SYMBOL vmlinux 0xa7c2293e netdev_state_change +EXPORT_SYMBOL vmlinux 0xa7c35c6b getnstimeofday +EXPORT_SYMBOL vmlinux 0xa7d78add kthread_create +EXPORT_SYMBOL vmlinux 0xa816c525 schedule_work_on +EXPORT_SYMBOL vmlinux 0xa81b826c bd_claim +EXPORT_SYMBOL vmlinux 0xa822dae7 down_read +EXPORT_SYMBOL vmlinux 0xa82f436d agp_flush_chipset +EXPORT_SYMBOL vmlinux 0xa871d950 cdrom_number_of_slots +EXPORT_SYMBOL vmlinux 0xa87c8b14 atm_dev_register +EXPORT_SYMBOL vmlinux 0xa886a958 krealloc +EXPORT_SYMBOL vmlinux 0xa88f9255 seq_release_private +EXPORT_SYMBOL vmlinux 0xa890f6aa ip_queue_xmit +EXPORT_SYMBOL vmlinux 0xa8a6f639 __check_region +EXPORT_SYMBOL vmlinux 0xa8c8db5c blkdev_get +EXPORT_SYMBOL vmlinux 0xa8fa06da vfs_mknod +EXPORT_SYMBOL vmlinux 0xa8fbf582 idr_replace +EXPORT_SYMBOL vmlinux 0xa8fef7bb security_unix_may_send +EXPORT_SYMBOL vmlinux 0xa9001a2f blk_integrity_register +EXPORT_SYMBOL vmlinux 0xa90131ec file_remove_suid +EXPORT_SYMBOL vmlinux 0xa91b5561 acpi_video_backlight_support +EXPORT_SYMBOL vmlinux 0xa91ddef7 ethtool_op_set_tx_csum +EXPORT_SYMBOL vmlinux 0xa925899a param_set_bool +EXPORT_SYMBOL vmlinux 0xa92c32c3 jbd2_journal_ack_err +EXPORT_SYMBOL vmlinux 0xa92d4b4e d_alloc +EXPORT_SYMBOL vmlinux 0xa94a3e45 km_policy_expired +EXPORT_SYMBOL vmlinux 0xa95cb7be nf_unregister_hooks +EXPORT_SYMBOL vmlinux 0xa95d817f __ip_select_ident +EXPORT_SYMBOL vmlinux 0xa96d1b79 blk_get_request +EXPORT_SYMBOL vmlinux 0xa96e4bc3 pci_wake_from_d3 +EXPORT_SYMBOL vmlinux 0xa9871889 tty_port_init +EXPORT_SYMBOL vmlinux 0xa98b73b0 wake_up_process +EXPORT_SYMBOL vmlinux 0xa9a9e0b9 agp_generic_alloc_user +EXPORT_SYMBOL vmlinux 0xa9de438d simple_empty +EXPORT_SYMBOL vmlinux 0xa9e316be xfrm_policy_alloc +EXPORT_SYMBOL vmlinux 0xa9e56605 set_irq_chip +EXPORT_SYMBOL vmlinux 0xa9ec36e7 bdev_read_only +EXPORT_SYMBOL vmlinux 0xa9fcf31d wait_for_completion_interruptible +EXPORT_SYMBOL vmlinux 0xaa024146 sonet_copy_stats +EXPORT_SYMBOL vmlinux 0xaa0fdf9f deregister_atm_ioctl +EXPORT_SYMBOL vmlinux 0xaa36d9d0 elv_abort_queue +EXPORT_SYMBOL vmlinux 0xaa54ca9e hci_send_sco +EXPORT_SYMBOL vmlinux 0xaa84a8ae acpi_processor_power_init_bm_check +EXPORT_SYMBOL vmlinux 0xaa8ab19e cpu_online_map +EXPORT_SYMBOL vmlinux 0xaa8c439b create_empty_buffers +EXPORT_SYMBOL vmlinux 0xaa9295bd block_is_partially_uptodate +EXPORT_SYMBOL vmlinux 0xaab06af8 _write_lock_irqsave +EXPORT_SYMBOL vmlinux 0xaadf7733 inet_sendmsg +EXPORT_SYMBOL vmlinux 0xaae8ab0e acpi_bus_power_manageable +EXPORT_SYMBOL vmlinux 0xaaee4400 inet6_add_protocol +EXPORT_SYMBOL vmlinux 0xaafdc258 strcasecmp +EXPORT_SYMBOL vmlinux 0xaaffb9a5 acpi_bus_private_data_handler +EXPORT_SYMBOL vmlinux 0xab2d19b3 find_get_page +EXPORT_SYMBOL vmlinux 0xab471003 param_array_set +EXPORT_SYMBOL vmlinux 0xab600421 probe_irq_off +EXPORT_SYMBOL vmlinux 0xab65ed80 set_memory_uc +EXPORT_SYMBOL vmlinux 0xab6c8a25 ip_ct_attach +EXPORT_SYMBOL vmlinux 0xab87714f get_sb_bdev +EXPORT_SYMBOL vmlinux 0xab970259 __skb_checksum_complete_head +EXPORT_SYMBOL vmlinux 0xaba9ff34 allocate_resource +EXPORT_SYMBOL vmlinux 0xabbb29fe scsi_get_host_dev +EXPORT_SYMBOL vmlinux 0xabd0c91c rtc_time_to_tm +EXPORT_SYMBOL vmlinux 0xabe084bc tty_schedule_flip +EXPORT_SYMBOL vmlinux 0xabe85a21 idr_init +EXPORT_SYMBOL vmlinux 0xac0bbfa8 _proxy_pda +EXPORT_SYMBOL vmlinux 0xac11a968 serio_close +EXPORT_SYMBOL vmlinux 0xac383451 radix_tree_tag_clear +EXPORT_SYMBOL vmlinux 0xac3b3cee __bitmap_and +EXPORT_SYMBOL vmlinux 0xac58ea5e acpi_unload_table_id +EXPORT_SYMBOL vmlinux 0xac7eb238 bdi_register +EXPORT_SYMBOL vmlinux 0xaccabc6a in4_pton +EXPORT_SYMBOL vmlinux 0xacd30a5b phy_stop_interrupts +EXPORT_SYMBOL vmlinux 0xacf4d843 match_strdup +EXPORT_SYMBOL vmlinux 0xad0413d4 match_hex +EXPORT_SYMBOL vmlinux 0xad0541b1 jbd2_journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0xad055bab simple_pin_fs +EXPORT_SYMBOL vmlinux 0xad13c689 acpi_os_execute +EXPORT_SYMBOL vmlinux 0xad25fb12 __memcpy +EXPORT_SYMBOL vmlinux 0xad5c03e2 xfrm_dst_ifdown +EXPORT_SYMBOL vmlinux 0xad7bb63e vm_insert_mixed +EXPORT_SYMBOL vmlinux 0xad8de1b3 acpi_remove_address_space_handler +EXPORT_SYMBOL vmlinux 0xada74d83 blk_cleanup_queue +EXPORT_SYMBOL vmlinux 0xadaa2657 cpufreq_register_notifier +EXPORT_SYMBOL vmlinux 0xadfdff51 scsi_add_host +EXPORT_SYMBOL vmlinux 0xae37c90a sk_receive_skb +EXPORT_SYMBOL vmlinux 0xae51e575 tcf_register_action +EXPORT_SYMBOL vmlinux 0xae699019 mpage_readpage +EXPORT_SYMBOL vmlinux 0xae944cc6 tty_vhangup +EXPORT_SYMBOL vmlinux 0xaeef6127 ipv6_push_nfrag_opts +EXPORT_SYMBOL vmlinux 0xaef14b23 scsi_eh_finish_cmd +EXPORT_SYMBOL vmlinux 0xaf21f3d5 tty_chars_in_buffer +EXPORT_SYMBOL vmlinux 0xaf300f21 __mark_inode_dirty +EXPORT_SYMBOL vmlinux 0xaf33e2ee alloc_hippi_dev +EXPORT_SYMBOL vmlinux 0xaf3dd7dc scsi_logging_level +EXPORT_SYMBOL vmlinux 0xaf52c2d3 iommu_bio_merge +EXPORT_SYMBOL vmlinux 0xaf5814cc jbd2_journal_release_buffer +EXPORT_SYMBOL vmlinux 0xaf5c7784 __inc_zone_page_state +EXPORT_SYMBOL vmlinux 0xaf74f3ef follow_up +EXPORT_SYMBOL vmlinux 0xafa6ce93 security_sb_clone_mnt_opts +EXPORT_SYMBOL vmlinux 0xafe82e10 strcspn +EXPORT_SYMBOL vmlinux 0xb0001805 __fatal_signal_pending +EXPORT_SYMBOL vmlinux 0xb04ea8f0 agp_rebind_memory +EXPORT_SYMBOL vmlinux 0xb051909f ida_init +EXPORT_SYMBOL vmlinux 0xb05b24a5 unregister_con_driver +EXPORT_SYMBOL vmlinux 0xb05ec98c proc_net_netfilter +EXPORT_SYMBOL vmlinux 0xb06c7521 save_mount_options +EXPORT_SYMBOL vmlinux 0xb075a606 bfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0xb0785e3e fddi_type_trans +EXPORT_SYMBOL vmlinux 0xb0791c14 inode_sub_bytes +EXPORT_SYMBOL vmlinux 0xb07dfb3d acpi_remove_gpe_handler +EXPORT_SYMBOL vmlinux 0xb0a2c5e5 scsi_scan_target +EXPORT_SYMBOL vmlinux 0xb0ae0184 skb_trim +EXPORT_SYMBOL vmlinux 0xb0ae91e7 vfs_quota_off +EXPORT_SYMBOL vmlinux 0xb0b847ac __bitmap_full +EXPORT_SYMBOL vmlinux 0xb0e10781 get_option +EXPORT_SYMBOL vmlinux 0xb0fb30ce set_trace_device +EXPORT_SYMBOL vmlinux 0xb116807f vfs_lstat +EXPORT_SYMBOL vmlinux 0xb11740f6 fasync_helper +EXPORT_SYMBOL vmlinux 0xb11fa1ce strlcat +EXPORT_SYMBOL vmlinux 0xb121390a probe_irq_on +EXPORT_SYMBOL vmlinux 0xb1304af4 netlink_broadcast +EXPORT_SYMBOL vmlinux 0xb1375dae hci_alloc_dev +EXPORT_SYMBOL vmlinux 0xb150f6d4 tty_throttle +EXPORT_SYMBOL vmlinux 0xb1645a2e sg_free_table +EXPORT_SYMBOL vmlinux 0xb1795d55 tty_check_change +EXPORT_SYMBOL vmlinux 0xb18e02c3 radix_tree_gang_lookup_tag +EXPORT_SYMBOL vmlinux 0xb18f0114 pci_bus_assign_resources +EXPORT_SYMBOL vmlinux 0xb19760c3 bitmap_onto +EXPORT_SYMBOL vmlinux 0xb1bdd82c journal_abort +EXPORT_SYMBOL vmlinux 0xb1c3a01a oops_in_progress +EXPORT_SYMBOL vmlinux 0xb1cfad22 rdmsr_on_cpu +EXPORT_SYMBOL vmlinux 0xb1f975aa unlock_kernel +EXPORT_SYMBOL vmlinux 0xb2017c1d per_cpu__x86_bios_cpu_apicid +EXPORT_SYMBOL vmlinux 0xb2042a1c input_register_handle +EXPORT_SYMBOL vmlinux 0xb2218099 md_unregister_thread +EXPORT_SYMBOL vmlinux 0xb22fe6a3 netdev_increment_features +EXPORT_SYMBOL vmlinux 0xb2386228 ethtool_op_set_ufo +EXPORT_SYMBOL vmlinux 0xb2434461 dev_unicast_delete +EXPORT_SYMBOL vmlinux 0xb24d2ba8 udp_lib_get_port +EXPORT_SYMBOL vmlinux 0xb257462c arp_send +EXPORT_SYMBOL vmlinux 0xb25a953c vfs_readlink +EXPORT_SYMBOL vmlinux 0xb26e28aa update_region +EXPORT_SYMBOL vmlinux 0xb279da12 pv_lock_ops +EXPORT_SYMBOL vmlinux 0xb280bd34 splice_direct_to_actor +EXPORT_SYMBOL vmlinux 0xb289b39d skb_kill_datagram +EXPORT_SYMBOL vmlinux 0xb2ab43ab kobject_put +EXPORT_SYMBOL vmlinux 0xb2be638a dma_chan_cleanup +EXPORT_SYMBOL vmlinux 0xb2fd5ceb __put_user_4 +EXPORT_SYMBOL vmlinux 0xb308bdb2 register_quota_format +EXPORT_SYMBOL vmlinux 0xb309f141 sk_stream_wait_close +EXPORT_SYMBOL vmlinux 0xb3205415 wait_for_completion_killable +EXPORT_SYMBOL vmlinux 0xb3284531 acpi_dbg_layer +EXPORT_SYMBOL vmlinux 0xb3318ded __down_read_trylock +EXPORT_SYMBOL vmlinux 0xb34ca107 xfrm4_rcv +EXPORT_SYMBOL vmlinux 0xb34d4c2e acpi_terminate +EXPORT_SYMBOL vmlinux 0xb352177e find_first_bit +EXPORT_SYMBOL vmlinux 0xb3650126 sk_stop_timer +EXPORT_SYMBOL vmlinux 0xb3692eb4 ioremap_wc +EXPORT_SYMBOL vmlinux 0xb37f2355 xfrm_policy_byid +EXPORT_SYMBOL vmlinux 0xb3a307c6 si_meminfo +EXPORT_SYMBOL vmlinux 0xb3bdd9d5 skb_put +EXPORT_SYMBOL vmlinux 0xb3d8772c rfkill_free +EXPORT_SYMBOL vmlinux 0xb3dda100 neigh_event_ns +EXPORT_SYMBOL vmlinux 0xb3e78a43 ndisc_mc_map +EXPORT_SYMBOL vmlinux 0xb3ee5fe0 file_fsync +EXPORT_SYMBOL vmlinux 0xb3fcf014 blk_queue_max_segment_size +EXPORT_SYMBOL vmlinux 0xb3ff1f69 free_pages_exact +EXPORT_SYMBOL vmlinux 0xb40940bd ipv6_getsockopt +EXPORT_SYMBOL vmlinux 0xb423dba1 console_blanked +EXPORT_SYMBOL vmlinux 0xb436fe32 phy_start_interrupts +EXPORT_SYMBOL vmlinux 0xb45b24f6 k8_nb_ids +EXPORT_SYMBOL vmlinux 0xb47c38bc bt_sock_recvmsg +EXPORT_SYMBOL vmlinux 0xb494e82a br_fdb_put_hook +EXPORT_SYMBOL vmlinux 0xb4a452fc __bio_clone +EXPORT_SYMBOL vmlinux 0xb4b8594f seq_bitmap_list +EXPORT_SYMBOL vmlinux 0xb4ca9447 __kfifo_get +EXPORT_SYMBOL vmlinux 0xb4dea094 tty_kref_put +EXPORT_SYMBOL vmlinux 0xb5044271 vsscanf +EXPORT_SYMBOL vmlinux 0xb528a386 xfrm_policy_destroy +EXPORT_SYMBOL vmlinux 0xb54533f7 usecs_to_jiffies +EXPORT_SYMBOL vmlinux 0xb54a7690 input_grab_device +EXPORT_SYMBOL vmlinux 0xb55df41b search_binary_handler +EXPORT_SYMBOL vmlinux 0xb5a459dc unregister_blkdev +EXPORT_SYMBOL vmlinux 0xb5aaa798 __pci_register_driver +EXPORT_SYMBOL vmlinux 0xb5c0dd82 vfs_get_dqinfo +EXPORT_SYMBOL vmlinux 0xb5ca1c46 slhc_free +EXPORT_SYMBOL vmlinux 0xb5d52c27 ec_transaction +EXPORT_SYMBOL vmlinux 0xb5f28b5f __any_online_cpu +EXPORT_SYMBOL vmlinux 0xb5f96f10 kill_litter_super +EXPORT_SYMBOL vmlinux 0xb6067cfa register_sysctl_paths +EXPORT_SYMBOL vmlinux 0xb60e34a8 nla_memcpy +EXPORT_SYMBOL vmlinux 0xb6110715 f_setown +EXPORT_SYMBOL vmlinux 0xb6244511 sg_init_one +EXPORT_SYMBOL vmlinux 0xb65be0f9 kmem_cache_alloc +EXPORT_SYMBOL vmlinux 0xb678366f int_sqrt +EXPORT_SYMBOL vmlinux 0xb6a61a86 qdisc_get_rtab +EXPORT_SYMBOL vmlinux 0xb6bfc512 journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0xb6c25f65 elv_rb_add +EXPORT_SYMBOL vmlinux 0xb6c5a973 scsi_show_result +EXPORT_SYMBOL vmlinux 0xb6e227aa rtc_lock +EXPORT_SYMBOL vmlinux 0xb6ec9e2c ethtool_op_get_ufo +EXPORT_SYMBOL vmlinux 0xb6ee6e69 neigh_lookup +EXPORT_SYMBOL vmlinux 0xb70154af dm_table_put +EXPORT_SYMBOL vmlinux 0xb714a981 console_print +EXPORT_SYMBOL vmlinux 0xb7555f12 timeval_to_jiffies +EXPORT_SYMBOL vmlinux 0xb758b225 acpi_disable_event +EXPORT_SYMBOL vmlinux 0xb77093c7 tcf_exts_dump +EXPORT_SYMBOL vmlinux 0xb784680e __neigh_for_each_release +EXPORT_SYMBOL vmlinux 0xb796cb09 struct_module +EXPORT_SYMBOL vmlinux 0xb79e590d nla_reserve +EXPORT_SYMBOL vmlinux 0xb7bd9886 __nla_put_nohdr +EXPORT_SYMBOL vmlinux 0xb7ee3f25 inet_frag_destroy +EXPORT_SYMBOL vmlinux 0xb7f53e88 pci_back_from_sleep +EXPORT_SYMBOL vmlinux 0xb81be4b7 phy_scan_fixups +EXPORT_SYMBOL vmlinux 0xb828c786 per_cpu__cpu_sibling_map +EXPORT_SYMBOL vmlinux 0xb86e4ab9 random32 +EXPORT_SYMBOL vmlinux 0xb88200fe skb_queue_tail +EXPORT_SYMBOL vmlinux 0xb8837d21 may_umount +EXPORT_SYMBOL vmlinux 0xb89af9bf srandom32 +EXPORT_SYMBOL vmlinux 0xb8b2d731 sg_miter_stop +EXPORT_SYMBOL vmlinux 0xb8d21fab d_lookup +EXPORT_SYMBOL vmlinux 0xb8e7ce2c __put_user_8 +EXPORT_SYMBOL vmlinux 0xb8f9cb1f pci_fixup_device +EXPORT_SYMBOL vmlinux 0xb905ad82 icmpv6_err_convert +EXPORT_SYMBOL vmlinux 0xb93e59e4 con_is_bound +EXPORT_SYMBOL vmlinux 0xb93fc0fe llc_sap_find +EXPORT_SYMBOL vmlinux 0xb95455c8 mapping_tagged +EXPORT_SYMBOL vmlinux 0xb9767d21 pnp_device_attach +EXPORT_SYMBOL vmlinux 0xb976e30a call_usermodehelper_setkeys +EXPORT_SYMBOL vmlinux 0xb9805b0c down_read_trylock +EXPORT_SYMBOL vmlinux 0xb98a0185 rtc_tm_to_time +EXPORT_SYMBOL vmlinux 0xb9b2be81 dst_destroy +EXPORT_SYMBOL vmlinux 0xb9bbe97d pci_scan_bridge +EXPORT_SYMBOL vmlinux 0xb9c74bf1 gen_kill_estimator +EXPORT_SYMBOL vmlinux 0xb9df6c28 phy_print_status +EXPORT_SYMBOL vmlinux 0xb9e6d1de pci_disable_device +EXPORT_SYMBOL vmlinux 0xb9ea1ec5 __sk_mem_reclaim +EXPORT_SYMBOL vmlinux 0xb9fd2205 add_efi_memmap +EXPORT_SYMBOL vmlinux 0xba1b6524 netdev_bonding_change +EXPORT_SYMBOL vmlinux 0xba2d8594 ec_read +EXPORT_SYMBOL vmlinux 0xba33d601 kmem_cache_destroy +EXPORT_SYMBOL vmlinux 0xba36d7e8 bio_integrity_free +EXPORT_SYMBOL vmlinux 0xba497f13 loops_per_jiffy +EXPORT_SYMBOL vmlinux 0xba56154c iov_iter_copy_from_user_atomic +EXPORT_SYMBOL vmlinux 0xba62bbc4 user_revoke +EXPORT_SYMBOL vmlinux 0xba86d0b4 mmc_register_driver +EXPORT_SYMBOL vmlinux 0xba8c9abd __f_setown +EXPORT_SYMBOL vmlinux 0xbaa2782a kstrndup +EXPORT_SYMBOL vmlinux 0xbaa688af sock_i_uid +EXPORT_SYMBOL vmlinux 0xbaa79c56 devm_ioport_map +EXPORT_SYMBOL vmlinux 0xbb077485 netlink_kernel_create +EXPORT_SYMBOL vmlinux 0xbb167766 fb_var_to_videomode +EXPORT_SYMBOL vmlinux 0xbb189cad disallow_signal +EXPORT_SYMBOL vmlinux 0xbb1acde6 i2c_smbus_write_byte +EXPORT_SYMBOL vmlinux 0xbb2419ad check_disk_size_change +EXPORT_SYMBOL vmlinux 0xbb32da64 mb_cache_create +EXPORT_SYMBOL vmlinux 0xbb486510 invalidate_inode_buffers +EXPORT_SYMBOL vmlinux 0xbb5ad1c4 unregister_binfmt +EXPORT_SYMBOL vmlinux 0xbb5d343d xfrm_get_acqseq +EXPORT_SYMBOL vmlinux 0xbb654e6b blk_insert_request +EXPORT_SYMBOL vmlinux 0xbb83bd29 xfrm_cfg_mutex +EXPORT_SYMBOL vmlinux 0xbba4a94d i2c_smbus_read_i2c_block_data +EXPORT_SYMBOL vmlinux 0xbba90b28 nla_put +EXPORT_SYMBOL vmlinux 0xbbc8e804 param_set_ushort +EXPORT_SYMBOL vmlinux 0xbbed86c4 journal_wipe +EXPORT_SYMBOL vmlinux 0xbc05a109 scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0xbc158c67 skb_copy_and_csum_datagram_iovec +EXPORT_SYMBOL vmlinux 0xbc54e13f scsi_device_lookup +EXPORT_SYMBOL vmlinux 0xbc554353 neigh_parms_release +EXPORT_SYMBOL vmlinux 0xbc9bd27a end_buffer_write_sync +EXPORT_SYMBOL vmlinux 0xbcc308bb strnlen_user +EXPORT_SYMBOL vmlinux 0xbcc935d2 dmam_free_noncoherent +EXPORT_SYMBOL vmlinux 0xbccbb49c idr_remove_all +EXPORT_SYMBOL vmlinux 0xbce63187 bio_integrity_clone +EXPORT_SYMBOL vmlinux 0xbcf148cf inet_frag_evictor +EXPORT_SYMBOL vmlinux 0xbcfe2fab journal_start_commit +EXPORT_SYMBOL vmlinux 0xbd11ff69 compat_ipv6_setsockopt +EXPORT_SYMBOL vmlinux 0xbd28924c scsi_eh_restore_cmnd +EXPORT_SYMBOL vmlinux 0xbd2b113b flock_lock_file_wait +EXPORT_SYMBOL vmlinux 0xbd711923 jbd2_journal_abort +EXPORT_SYMBOL vmlinux 0xbdaf5b07 acpi_os_read_port +EXPORT_SYMBOL vmlinux 0xbdc5bbc7 mnt_unpin +EXPORT_SYMBOL vmlinux 0xbdede79e blk_complete_request +EXPORT_SYMBOL vmlinux 0xbe01692e make_EII_client +EXPORT_SYMBOL vmlinux 0xbe108647 input_flush_device +EXPORT_SYMBOL vmlinux 0xbe3f9941 xfrm_register_type +EXPORT_SYMBOL vmlinux 0xbe499d81 copy_to_user +EXPORT_SYMBOL vmlinux 0xbea3ff0e compat_tcp_getsockopt +EXPORT_SYMBOL vmlinux 0xbeac8776 freeze_bdev +EXPORT_SYMBOL vmlinux 0xbecdce74 ida_pre_get +EXPORT_SYMBOL vmlinux 0xbeeb4d65 bt_accept_unlink +EXPORT_SYMBOL vmlinux 0xbef43296 console_conditional_schedule +EXPORT_SYMBOL vmlinux 0xbefe75b8 __inet6_hash +EXPORT_SYMBOL vmlinux 0xbefee397 acpi_get_object_info +EXPORT_SYMBOL vmlinux 0xbf00b52c neigh_create +EXPORT_SYMBOL vmlinux 0xbf34369c fsync_bdev +EXPORT_SYMBOL vmlinux 0xbf5b12b9 inode_get_bytes +EXPORT_SYMBOL vmlinux 0xbf7bca92 pci_choose_state +EXPORT_SYMBOL vmlinux 0xbf7fd2f5 schedule_timeout_killable +EXPORT_SYMBOL vmlinux 0xbf9bcc8d __cap_empty_set +EXPORT_SYMBOL vmlinux 0xbfb4df47 task_pgrp_nr_ns +EXPORT_SYMBOL vmlinux 0xbfc177bc iowrite32_rep +EXPORT_SYMBOL vmlinux 0xbfcc3a51 wait_on_sync_kiocb +EXPORT_SYMBOL vmlinux 0xbfe258d9 cdrom_ioctl +EXPORT_SYMBOL vmlinux 0xbfee3ad5 loop_unregister_transfer +EXPORT_SYMBOL vmlinux 0xc000d51e journal_release_buffer +EXPORT_SYMBOL vmlinux 0xc003c637 __strncpy_from_user +EXPORT_SYMBOL vmlinux 0xc01400fd icmpv6_send +EXPORT_SYMBOL vmlinux 0xc018d2de user_path_at +EXPORT_SYMBOL vmlinux 0xc03c64d6 module_put +EXPORT_SYMBOL vmlinux 0xc03d95cb journal_set_features +EXPORT_SYMBOL vmlinux 0xc045ad4e timespec_trunc +EXPORT_SYMBOL vmlinux 0xc0487f56 phy_driver_unregister +EXPORT_SYMBOL vmlinux 0xc0580937 rb_erase +EXPORT_SYMBOL vmlinux 0xc0608429 seq_escape +EXPORT_SYMBOL vmlinux 0xc06a4103 inet_csk_reset_keepalive_timer +EXPORT_SYMBOL vmlinux 0xc07a3759 scsi_host_put +EXPORT_SYMBOL vmlinux 0xc07ba03a agp_generic_alloc_pages +EXPORT_SYMBOL vmlinux 0xc07d43ae acpi_evaluate_reference +EXPORT_SYMBOL vmlinux 0xc09651d9 crc32_be +EXPORT_SYMBOL vmlinux 0xc0a3d105 find_next_bit +EXPORT_SYMBOL vmlinux 0xc0bc1c94 unregister_8022_client +EXPORT_SYMBOL vmlinux 0xc0d7fa39 pci_iomap +EXPORT_SYMBOL vmlinux 0xc0f10839 kill_fasync +EXPORT_SYMBOL vmlinux 0xc0f48608 xfrm_policy_unregister_afinfo +EXPORT_SYMBOL vmlinux 0xc13d6cec ethtool_op_get_flags +EXPORT_SYMBOL vmlinux 0xc13d7e4c __downgrade_write +EXPORT_SYMBOL vmlinux 0xc16a9eaf skb_dma_map +EXPORT_SYMBOL vmlinux 0xc17fc9f1 vfs_quota_on +EXPORT_SYMBOL vmlinux 0xc1870b62 scm_fp_dup +EXPORT_SYMBOL vmlinux 0xc1a3bd46 inet_twsk_deschedule +EXPORT_SYMBOL vmlinux 0xc1cda2fa sk_alloc +EXPORT_SYMBOL vmlinux 0xc1e5799b unload_nls +EXPORT_SYMBOL vmlinux 0xc2066af0 batostr +EXPORT_SYMBOL vmlinux 0xc21cc374 pcim_iomap +EXPORT_SYMBOL vmlinux 0xc22fba54 vfs_quota_on_mount +EXPORT_SYMBOL vmlinux 0xc23ff1c2 task_nice +EXPORT_SYMBOL vmlinux 0xc2424641 agp3_generic_cleanup +EXPORT_SYMBOL vmlinux 0xc254af48 dcache_lock +EXPORT_SYMBOL vmlinux 0xc256e762 __bitmap_equal +EXPORT_SYMBOL vmlinux 0xc281d33e tty_unregister_device +EXPORT_SYMBOL vmlinux 0xc287c44a tcf_em_tree_dump +EXPORT_SYMBOL vmlinux 0xc2aaa3e4 pcim_iomap_regions_request_all +EXPORT_SYMBOL vmlinux 0xc2c1f483 agp_enable +EXPORT_SYMBOL vmlinux 0xc2c8d899 register_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0xc2c95270 pnp_start_dev +EXPORT_SYMBOL vmlinux 0xc2d027f1 generic_show_options +EXPORT_SYMBOL vmlinux 0xc2d12b59 blk_alloc_queue +EXPORT_SYMBOL vmlinux 0xc2d1f126 proc_dointvec_minmax +EXPORT_SYMBOL vmlinux 0xc2da3f7d in_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0xc2e587d1 reset_devices +EXPORT_SYMBOL vmlinux 0xc31b077a dquot_commit_info +EXPORT_SYMBOL vmlinux 0xc33f6f4c on_each_cpu +EXPORT_SYMBOL vmlinux 0xc340960a swiotlb_sync_sg_for_cpu +EXPORT_SYMBOL vmlinux 0xc3aaf0a9 __put_user_1 +EXPORT_SYMBOL vmlinux 0xc3d96c18 netpoll_poll +EXPORT_SYMBOL vmlinux 0xc3df7a86 posix_acl_permission +EXPORT_SYMBOL vmlinux 0xc402cc99 register_acpi_notifier +EXPORT_SYMBOL vmlinux 0xc41d175f kset_register +EXPORT_SYMBOL vmlinux 0xc438bf18 cdrom_media_changed +EXPORT_SYMBOL vmlinux 0xc47c2497 do_splice_from +EXPORT_SYMBOL vmlinux 0xc4925812 pci_map_rom +EXPORT_SYMBOL vmlinux 0xc4945d6c inode_setattr +EXPORT_SYMBOL vmlinux 0xc499ae1e kstrdup +EXPORT_SYMBOL vmlinux 0xc4a182bc skb_copy_datagram_from_iovec +EXPORT_SYMBOL vmlinux 0xc4b1b4be skb_copy_and_csum_bits +EXPORT_SYMBOL vmlinux 0xc4d489e9 up_write +EXPORT_SYMBOL vmlinux 0xc4e96d83 jbd2_journal_restart +EXPORT_SYMBOL vmlinux 0xc4ec3bad end_page_writeback +EXPORT_SYMBOL vmlinux 0xc52f5714 fb_videomode_to_var +EXPORT_SYMBOL vmlinux 0xc535491a generic_setxattr +EXPORT_SYMBOL vmlinux 0xc5382659 journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0xc53c882d idr_get_new +EXPORT_SYMBOL vmlinux 0xc53f90a2 devm_free_irq +EXPORT_SYMBOL vmlinux 0xc5534d64 ioread16 +EXPORT_SYMBOL vmlinux 0xc558530d profile_pc +EXPORT_SYMBOL vmlinux 0xc55f7dc7 _write_trylock +EXPORT_SYMBOL vmlinux 0xc561998e con_set_default_unimap +EXPORT_SYMBOL vmlinux 0xc5681b61 mb_cache_entry_free +EXPORT_SYMBOL vmlinux 0xc5708a48 vfs_writev +EXPORT_SYMBOL vmlinux 0xc58d8b08 d_path +EXPORT_SYMBOL vmlinux 0xc593b275 neigh_seq_stop +EXPORT_SYMBOL vmlinux 0xc59de455 put_disk +EXPORT_SYMBOL vmlinux 0xc5a06657 textsearch_register +EXPORT_SYMBOL vmlinux 0xc5cc8c81 proc_create_data +EXPORT_SYMBOL vmlinux 0xc5d9c46c agp_try_unsupported_boot +EXPORT_SYMBOL vmlinux 0xc5de555b input_register_device +EXPORT_SYMBOL vmlinux 0xc65abeb7 agp3_generic_sizes +EXPORT_SYMBOL vmlinux 0xc65ce1b2 swiotlb_unmap_single_attrs +EXPORT_SYMBOL vmlinux 0xc68944ce swiotlb_dma_supported +EXPORT_SYMBOL vmlinux 0xc6dfe13a skb_find_text +EXPORT_SYMBOL vmlinux 0xc6e40edb journal_dirty_data +EXPORT_SYMBOL vmlinux 0xc6fe73e3 pci_bus_size_bridges +EXPORT_SYMBOL vmlinux 0xc7190107 inet_addr_type +EXPORT_SYMBOL vmlinux 0xc71f58c0 scsi_device_get +EXPORT_SYMBOL vmlinux 0xc7200d2b set_binfmt +EXPORT_SYMBOL vmlinux 0xc7208c3a serial8250_resume_port +EXPORT_SYMBOL vmlinux 0xc740c64a memchr +EXPORT_SYMBOL vmlinux 0xc78cf944 generic_block_fiemap +EXPORT_SYMBOL vmlinux 0xc7911d30 bitmap_start_sync +EXPORT_SYMBOL vmlinux 0xc79bcd36 dm_vcalloc +EXPORT_SYMBOL vmlinux 0xc7a24d76 sysfs_format_mac +EXPORT_SYMBOL vmlinux 0xc7a4fbed rtnl_lock +EXPORT_SYMBOL vmlinux 0xc7bad7d4 sk_common_release +EXPORT_SYMBOL vmlinux 0xc83456f9 scsi_report_device_reset +EXPORT_SYMBOL vmlinux 0xc860a3ae skb_dequeue_tail +EXPORT_SYMBOL vmlinux 0xc86249a0 dmam_alloc_noncoherent +EXPORT_SYMBOL vmlinux 0xc897c382 sg_init_table +EXPORT_SYMBOL vmlinux 0xc8a28e28 init_file +EXPORT_SYMBOL vmlinux 0xc8b165fe agp_allocate_memory +EXPORT_SYMBOL vmlinux 0xc8b57c27 autoremove_wake_function +EXPORT_SYMBOL vmlinux 0xc8c82bf2 vfs_symlink +EXPORT_SYMBOL vmlinux 0xc8ca3e25 acpi_get_child +EXPORT_SYMBOL vmlinux 0xc8dc6fb8 __blockdev_direct_IO +EXPORT_SYMBOL vmlinux 0xc8e94ef8 key_validate +EXPORT_SYMBOL vmlinux 0xc90e71f6 tcp_md5_hash_header +EXPORT_SYMBOL vmlinux 0xc93eae38 icmp_send +EXPORT_SYMBOL vmlinux 0xc9437ede __down_write_nested +EXPORT_SYMBOL vmlinux 0xc998d641 icmp_err_convert +EXPORT_SYMBOL vmlinux 0xc9997173 kmem_cache_shrink +EXPORT_SYMBOL vmlinux 0xc9ab2eef acpi_os_wait_events_complete +EXPORT_SYMBOL vmlinux 0xc9c0cd17 gnet_stats_copy_basic +EXPORT_SYMBOL vmlinux 0xca0136f2 sock_common_getsockopt +EXPORT_SYMBOL vmlinux 0xca024545 i2c_use_client +EXPORT_SYMBOL vmlinux 0xca351be8 jbd2_log_wait_commit +EXPORT_SYMBOL vmlinux 0xca4c9885 xfrm_policy_register_afinfo +EXPORT_SYMBOL vmlinux 0xca5c105a agp_create_memory +EXPORT_SYMBOL vmlinux 0xca5dbc50 scsi_print_sense_hdr +EXPORT_SYMBOL vmlinux 0xca61cf69 serio_unregister_port +EXPORT_SYMBOL vmlinux 0xca763f21 __invalidate_device +EXPORT_SYMBOL vmlinux 0xca8abced request_key_with_auxdata +EXPORT_SYMBOL vmlinux 0xca8acc78 acpi_dbg_level +EXPORT_SYMBOL vmlinux 0xcac9f3a8 journal_invalidatepage +EXPORT_SYMBOL vmlinux 0xcad4badd arch_debugfs_dir +EXPORT_SYMBOL vmlinux 0xcae54476 scsi_adjust_queue_depth +EXPORT_SYMBOL vmlinux 0xcaec4800 skb_realloc_headroom +EXPORT_SYMBOL vmlinux 0xcb090571 swiotlb_map_single +EXPORT_SYMBOL vmlinux 0xcb293d3c journal_clear_err +EXPORT_SYMBOL vmlinux 0xcb32da10 param_set_int +EXPORT_SYMBOL vmlinux 0xcb6beb40 hweight32 +EXPORT_SYMBOL vmlinux 0xcb7131fb fb_get_options +EXPORT_SYMBOL vmlinux 0xcb733bf2 acpi_bus_set_power +EXPORT_SYMBOL vmlinux 0xcbdd460c input_inject_event +EXPORT_SYMBOL vmlinux 0xcbe1eb2a eth_rebuild_header +EXPORT_SYMBOL vmlinux 0xcc07af75 strnlen +EXPORT_SYMBOL vmlinux 0xcc1fb551 baswap +EXPORT_SYMBOL vmlinux 0xcc248d26 serial8250_suspend_port +EXPORT_SYMBOL vmlinux 0xcc305a32 acpi_lock_ac_dir +EXPORT_SYMBOL vmlinux 0xcc36f32e fb_unregister_client +EXPORT_SYMBOL vmlinux 0xcc5005fe msleep_interruptible +EXPORT_SYMBOL vmlinux 0xcc51ee50 dma_spin_lock +EXPORT_SYMBOL vmlinux 0xcc6a9014 qdisc_watchdog_cancel +EXPORT_SYMBOL vmlinux 0xcc7e5f66 ____pagevec_lru_add +EXPORT_SYMBOL vmlinux 0xcc7fa952 local_bh_enable_ip +EXPORT_SYMBOL vmlinux 0xcc8e0825 journal_unlock_updates +EXPORT_SYMBOL vmlinux 0xcc923dab scsi_block_when_processing_errors +EXPORT_SYMBOL vmlinux 0xcccd73a7 generic_write_end +EXPORT_SYMBOL vmlinux 0xcce54e83 ip_defrag +EXPORT_SYMBOL vmlinux 0xcd100fa9 hci_unregister_dev +EXPORT_SYMBOL vmlinux 0xcd11c1ac generic_file_splice_write_nolock +EXPORT_SYMBOL vmlinux 0xcd3fab1e dev_mc_delete +EXPORT_SYMBOL vmlinux 0xcd478485 phy_register_fixup +EXPORT_SYMBOL vmlinux 0xce038024 tcf_hash_create +EXPORT_SYMBOL vmlinux 0xce0c313f sysctl_string +EXPORT_SYMBOL vmlinux 0xce19bac5 register_inet6addr_notifier +EXPORT_SYMBOL vmlinux 0xce1b5310 dst_discard +EXPORT_SYMBOL vmlinux 0xce36ded6 sysctl_tcp_mem +EXPORT_SYMBOL vmlinux 0xce4904a4 acpi_leave_sleep_state +EXPORT_SYMBOL vmlinux 0xce5ac24f zlib_inflate_workspacesize +EXPORT_SYMBOL vmlinux 0xce6847e3 seq_release +EXPORT_SYMBOL vmlinux 0xce72e2cc nf_unregister_queue_handler +EXPORT_SYMBOL vmlinux 0xce72e50f ip_getsockopt +EXPORT_SYMBOL vmlinux 0xced15af8 nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0xcee49ef1 dcache_dir_close +EXPORT_SYMBOL vmlinux 0xcefcd99a serial8250_unregister_port +EXPORT_SYMBOL vmlinux 0xcf0ffdcb block_truncate_page +EXPORT_SYMBOL vmlinux 0xcf35e0b8 ip_route_input +EXPORT_SYMBOL vmlinux 0xcf3d1948 tcp_hashinfo +EXPORT_SYMBOL vmlinux 0xcf447f0b scsi_report_bus_reset +EXPORT_SYMBOL vmlinux 0xcfa6a587 __netif_schedule +EXPORT_SYMBOL vmlinux 0xcfadd723 __percpu_counter_add +EXPORT_SYMBOL vmlinux 0xcfc8145d nonseekable_open +EXPORT_SYMBOL vmlinux 0xcfd3018e set_normalized_timespec +EXPORT_SYMBOL vmlinux 0xcfd3cc05 netif_receive_skb +EXPORT_SYMBOL vmlinux 0xd0037460 serio_unregister_driver +EXPORT_SYMBOL vmlinux 0xd0049e7c put_page +EXPORT_SYMBOL vmlinux 0xd0181f4f __bitmap_xor +EXPORT_SYMBOL vmlinux 0xd0291a06 proc_symlink +EXPORT_SYMBOL vmlinux 0xd02cc869 __bitmap_andnot +EXPORT_SYMBOL vmlinux 0xd05a22b6 dev_set_mtu +EXPORT_SYMBOL vmlinux 0xd06535a9 pci_assign_resource +EXPORT_SYMBOL vmlinux 0xd06cbb7f dev_get_by_flags +EXPORT_SYMBOL vmlinux 0xd073f3f9 deny_write_access +EXPORT_SYMBOL vmlinux 0xd075a790 register_8022_client +EXPORT_SYMBOL vmlinux 0xd078b53d ethtool_op_get_link +EXPORT_SYMBOL vmlinux 0xd08197fa acpi_load_tables +EXPORT_SYMBOL vmlinux 0xd08994c4 neigh_seq_start +EXPORT_SYMBOL vmlinux 0xd092912f kernel_sendpage +EXPORT_SYMBOL vmlinux 0xd0bae86f acpi_processor_notify_smm +EXPORT_SYMBOL vmlinux 0xd0cff314 scsi_allocate_command +EXPORT_SYMBOL vmlinux 0xd0ee38b8 schedule_timeout_uninterruptible +EXPORT_SYMBOL vmlinux 0xd0f67674 tty_set_operations +EXPORT_SYMBOL vmlinux 0xd0fef3b2 agp_free_key +EXPORT_SYMBOL vmlinux 0xd11504ce xfrm_prepare_input +EXPORT_SYMBOL vmlinux 0xd1460462 pci_set_dma_seg_boundary +EXPORT_SYMBOL vmlinux 0xd1472061 acpi_pci_register_driver +EXPORT_SYMBOL vmlinux 0xd15cbea6 should_remove_suid +EXPORT_SYMBOL vmlinux 0xd1626a57 register_netdev +EXPORT_SYMBOL vmlinux 0xd17b9fe6 md_done_sync +EXPORT_SYMBOL vmlinux 0xd18b6eb2 acpi_unmap_lsapic +EXPORT_SYMBOL vmlinux 0xd19bb294 acpi_install_address_space_handler +EXPORT_SYMBOL vmlinux 0xd1b5fd12 input_register_handler +EXPORT_SYMBOL vmlinux 0xd1eddd17 dev_get_flags +EXPORT_SYMBOL vmlinux 0xd1f2bdfb pfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0xd1f6c5f3 smp_num_siblings +EXPORT_SYMBOL vmlinux 0xd1f91bcd dev_base_lock +EXPORT_SYMBOL vmlinux 0xd20795bc send_sig +EXPORT_SYMBOL vmlinux 0xd24e6218 call_usermodehelper_exec +EXPORT_SYMBOL vmlinux 0xd251d7b0 security_socket_getpeersec_dgram +EXPORT_SYMBOL vmlinux 0xd2555f19 jiffies_64_to_clock_t +EXPORT_SYMBOL vmlinux 0xd25d4f74 console_blank_hook +EXPORT_SYMBOL vmlinux 0xd267d42c down_killable +EXPORT_SYMBOL vmlinux 0xd27195b6 netdev_boot_setup_check +EXPORT_SYMBOL vmlinux 0xd2965f6f kthread_should_stop +EXPORT_SYMBOL vmlinux 0xd2bb5c3c pci_lost_interrupt +EXPORT_SYMBOL vmlinux 0xd2ce4ad7 i2c_smbus_read_byte +EXPORT_SYMBOL vmlinux 0xd2f697ad input_open_device +EXPORT_SYMBOL vmlinux 0xd30d90c1 km_state_expired +EXPORT_SYMBOL vmlinux 0xd323b38a open_exec +EXPORT_SYMBOL vmlinux 0xd328f23f lookup_one_len +EXPORT_SYMBOL vmlinux 0xd334919e __page_symlink +EXPORT_SYMBOL vmlinux 0xd34f0c62 gen_pool_create +EXPORT_SYMBOL vmlinux 0xd35ee027 ipv6_skip_exthdr +EXPORT_SYMBOL vmlinux 0xd35fc5c4 dma_supported +EXPORT_SYMBOL vmlinux 0xd37a2ed6 scsi_remove_target +EXPORT_SYMBOL vmlinux 0xd3951da4 acpi_resource_to_address64 +EXPORT_SYMBOL vmlinux 0xd3b8a866 xfrm_register_km +EXPORT_SYMBOL vmlinux 0xd3c92584 block_commit_write +EXPORT_SYMBOL vmlinux 0xd3f74cf1 interruptible_sleep_on_timeout +EXPORT_SYMBOL vmlinux 0xd40525c2 pci_match_id +EXPORT_SYMBOL vmlinux 0xd41764c6 scsi_setup_blk_pc_cmnd +EXPORT_SYMBOL vmlinux 0xd42b7232 _write_unlock_bh +EXPORT_SYMBOL vmlinux 0xd42be8f2 check_disk_change +EXPORT_SYMBOL vmlinux 0xd46ca808 blk_register_region +EXPORT_SYMBOL vmlinux 0xd473160d sk_run_filter +EXPORT_SYMBOL vmlinux 0xd484f755 request_firmware_nowait +EXPORT_SYMBOL vmlinux 0xd4b95eb9 test_set_page_writeback +EXPORT_SYMBOL vmlinux 0xd4cb32db vfs_set_dqblk +EXPORT_SYMBOL vmlinux 0xd4ea959b pci_find_parent_resource +EXPORT_SYMBOL vmlinux 0xd4f240d1 key_task_permission +EXPORT_SYMBOL vmlinux 0xd5007292 tcp_enter_memory_pressure +EXPORT_SYMBOL vmlinux 0xd507cf7c journal_revoke +EXPORT_SYMBOL vmlinux 0xd5263820 mb_cache_destroy +EXPORT_SYMBOL vmlinux 0xd53694b3 dm_dirty_log_type_unregister +EXPORT_SYMBOL vmlinux 0xd53aec49 cpu_possible_map +EXPORT_SYMBOL vmlinux 0xd5538cdf tcp_v4_syn_recv_sock +EXPORT_SYMBOL vmlinux 0xd55ba1e7 dentry_unhash +EXPORT_SYMBOL vmlinux 0xd56ce68b bio_integrity_split +EXPORT_SYMBOL vmlinux 0xd57f8789 iommu_num_pages +EXPORT_SYMBOL vmlinux 0xd5835f11 blk_recount_segments +EXPORT_SYMBOL vmlinux 0xd58d0c54 agp_put_bridge +EXPORT_SYMBOL vmlinux 0xd5ae76e4 generic_splice_sendpage +EXPORT_SYMBOL vmlinux 0xd5b037e1 kref_put +EXPORT_SYMBOL vmlinux 0xd5c54f65 journal_force_commit +EXPORT_SYMBOL vmlinux 0xd6035d05 do_settimeofday +EXPORT_SYMBOL vmlinux 0xd60d7af4 ida_remove +EXPORT_SYMBOL vmlinux 0xd61b8b2a agp_copy_info +EXPORT_SYMBOL vmlinux 0xd62c833f schedule_timeout +EXPORT_SYMBOL vmlinux 0xd6486a5a md_wakeup_thread +EXPORT_SYMBOL vmlinux 0xd64a0cf9 simple_dir_operations +EXPORT_SYMBOL vmlinux 0xd659923a ip_mc_rejoin_group +EXPORT_SYMBOL vmlinux 0xd692b34f mdiobus_free +EXPORT_SYMBOL vmlinux 0xd696c85a bio_integrity_trim +EXPORT_SYMBOL vmlinux 0xd6a78d08 smp_call_function_single +EXPORT_SYMBOL vmlinux 0xd6b33026 cpu_khz +EXPORT_SYMBOL vmlinux 0xd6d11ecc tcp_init_xmit_timers +EXPORT_SYMBOL vmlinux 0xd6ee688f vmalloc +EXPORT_SYMBOL vmlinux 0xd6f453ea skb_dequeue +EXPORT_SYMBOL vmlinux 0xd72f8cac filemap_flush +EXPORT_SYMBOL vmlinux 0xd78ee65a tcp_splice_read +EXPORT_SYMBOL vmlinux 0xd791c500 skb_recv_datagram +EXPORT_SYMBOL vmlinux 0xd79b5a02 allow_signal +EXPORT_SYMBOL vmlinux 0xd7a69233 __alloc_pages_internal +EXPORT_SYMBOL vmlinux 0xd7a6fafa panic_notifier_list +EXPORT_SYMBOL vmlinux 0xd7caadc8 register_snap_client +EXPORT_SYMBOL vmlinux 0xd7dd777b reserve_perfctr_nmi +EXPORT_SYMBOL vmlinux 0xd7e48b73 kset_unregister +EXPORT_SYMBOL vmlinux 0xd7ee54a9 dm_kcopyd_client_destroy +EXPORT_SYMBOL vmlinux 0xd7f979cd __scsi_iterate_devices +EXPORT_SYMBOL vmlinux 0xd8007933 pci_disable_msix +EXPORT_SYMBOL vmlinux 0xd80c2bbf inet6_bind +EXPORT_SYMBOL vmlinux 0xd810ede5 jbd2_journal_init_inode +EXPORT_SYMBOL vmlinux 0xd833bcdf task_pid_nr_ns +EXPORT_SYMBOL vmlinux 0xd88f695a __mod_timer +EXPORT_SYMBOL vmlinux 0xd89da37f movable_zone +EXPORT_SYMBOL vmlinux 0xd8a56ae0 ip_xfrm_me_harder +EXPORT_SYMBOL vmlinux 0xd8b661ec cdev_del +EXPORT_SYMBOL vmlinux 0xd8bd192b tcp_proc_unregister +EXPORT_SYMBOL vmlinux 0xd8e484f0 register_chrdev_region +EXPORT_SYMBOL vmlinux 0xd901c5c8 sync_page_range_nolock +EXPORT_SYMBOL vmlinux 0xd9091363 acpi_install_notify_handler +EXPORT_SYMBOL vmlinux 0xd9222286 generic_file_buffered_write +EXPORT_SYMBOL vmlinux 0xd9370b06 skb_dma_unmap +EXPORT_SYMBOL vmlinux 0xd985dc99 mempool_free_pages +EXPORT_SYMBOL vmlinux 0xd9a8fa31 journal_init_dev +EXPORT_SYMBOL vmlinux 0xd9c22b28 xfrm_state_add +EXPORT_SYMBOL vmlinux 0xd9c2b8c8 bio_alloc_bioset +EXPORT_SYMBOL vmlinux 0xd9e1b194 fb_get_mode +EXPORT_SYMBOL vmlinux 0xd9e8f55e __break_lease +EXPORT_SYMBOL vmlinux 0xda0a6b0e acpi_map_lsapic +EXPORT_SYMBOL vmlinux 0xda1a7335 kasprintf +EXPORT_SYMBOL vmlinux 0xda1ec81d vfs_readv +EXPORT_SYMBOL vmlinux 0xda2817d2 cdrom_mode_select +EXPORT_SYMBOL vmlinux 0xda4629e4 radix_tree_insert +EXPORT_SYMBOL vmlinux 0xda597d34 __ht_create_irq +EXPORT_SYMBOL vmlinux 0xda7ca6cb fb_mode_is_equal +EXPORT_SYMBOL vmlinux 0xda7e5443 call_usermodehelper_freeinfo +EXPORT_SYMBOL vmlinux 0xda8af7ad fb_find_nearest_mode +EXPORT_SYMBOL vmlinux 0xda928914 nmi_watchdog +EXPORT_SYMBOL vmlinux 0xda987cb8 jbd2_journal_invalidatepage +EXPORT_SYMBOL vmlinux 0xda9be667 new_inode +EXPORT_SYMBOL vmlinux 0xdaa3953a elv_rb_former_request +EXPORT_SYMBOL vmlinux 0xdacad00d uart_update_timeout +EXPORT_SYMBOL vmlinux 0xdb09b950 blk_init_tags +EXPORT_SYMBOL vmlinux 0xdb16aed4 vfs_getattr +EXPORT_SYMBOL vmlinux 0xdb22a60c i2c_master_send +EXPORT_SYMBOL vmlinux 0xdb64a569 proc_doulongvec_minmax +EXPORT_SYMBOL vmlinux 0xdb8a364a atm_init_aal5 +EXPORT_SYMBOL vmlinux 0xdbcd416e sysctl_ip_nonlocal_bind +EXPORT_SYMBOL vmlinux 0xdbef92a1 ps2_init +EXPORT_SYMBOL vmlinux 0xdc138430 skb_seq_read +EXPORT_SYMBOL vmlinux 0xdc14eda7 pci_pci_problems +EXPORT_SYMBOL vmlinux 0xdc262d6d vfs_create +EXPORT_SYMBOL vmlinux 0xdc2adb35 add_taint +EXPORT_SYMBOL vmlinux 0xdc43a9c8 daemonize +EXPORT_SYMBOL vmlinux 0xdc6242e7 agp_generic_alloc_by_type +EXPORT_SYMBOL vmlinux 0xdc696d35 dm_dirty_log_create +EXPORT_SYMBOL vmlinux 0xdc873a70 screen_info +EXPORT_SYMBOL vmlinux 0xdc93f908 acpi_bus_add +EXPORT_SYMBOL vmlinux 0xdcb0349b sys_close +EXPORT_SYMBOL vmlinux 0xdcec9299 sock_release +EXPORT_SYMBOL vmlinux 0xdd275c36 cdev_add +EXPORT_SYMBOL vmlinux 0xdd2a40ab md_write_start +EXPORT_SYMBOL vmlinux 0xdd87b8f8 ip_cmsg_recv +EXPORT_SYMBOL vmlinux 0xddc1ac11 bioset_integrity_free +EXPORT_SYMBOL vmlinux 0xddcbc04f __set_page_dirty_nobuffers +EXPORT_SYMBOL vmlinux 0xddd107d2 framebuffer_release +EXPORT_SYMBOL vmlinux 0xdde2a4da agp_bridge +EXPORT_SYMBOL vmlinux 0xddeba0e5 sg_miter_start +EXPORT_SYMBOL vmlinux 0xde0bdcff memset +EXPORT_SYMBOL vmlinux 0xde75b689 set_irq_type +EXPORT_SYMBOL vmlinux 0xde9360ba totalram_pages +EXPORT_SYMBOL vmlinux 0xde99af71 pci_get_slot +EXPORT_SYMBOL vmlinux 0xde9b17ed agp3_generic_fetch_size +EXPORT_SYMBOL vmlinux 0xdef36088 notify_change +EXPORT_SYMBOL vmlinux 0xdf0da3cc acpi_get_devices +EXPORT_SYMBOL vmlinux 0xdf3f2657 phy_enable_interrupts +EXPORT_SYMBOL vmlinux 0xdf60cc27 __print_symbol +EXPORT_SYMBOL vmlinux 0xdf8c695a __ndelay +EXPORT_SYMBOL vmlinux 0xdf929370 fs_overflowgid +EXPORT_SYMBOL vmlinux 0xdfb7bada acpi_check_resource_conflict +EXPORT_SYMBOL vmlinux 0xdfc5169b slhc_init +EXPORT_SYMBOL vmlinux 0xe001a3fb elv_rb_latter_request +EXPORT_SYMBOL vmlinux 0xe004b54e pci_find_capability +EXPORT_SYMBOL vmlinux 0xe02c04cf agp_collect_device_status +EXPORT_SYMBOL vmlinux 0xe075d6eb iter_div_u64_rem +EXPORT_SYMBOL vmlinux 0xe0939d0a iunique +EXPORT_SYMBOL vmlinux 0xe0ac8bd2 acpi_bus_generate_netlink_event +EXPORT_SYMBOL vmlinux 0xe0b13336 argv_free +EXPORT_SYMBOL vmlinux 0xe0edcf77 vmtruncate +EXPORT_SYMBOL vmlinux 0xe105ff54 eth_header_parse +EXPORT_SYMBOL vmlinux 0xe1088976 sb_min_blocksize +EXPORT_SYMBOL vmlinux 0xe1127940 tcp_ioctl +EXPORT_SYMBOL vmlinux 0xe113bbbc csum_partial +EXPORT_SYMBOL vmlinux 0xe12d6f3d pci_find_next_bus +EXPORT_SYMBOL vmlinux 0xe13cd8a7 dmi_name_in_vendors +EXPORT_SYMBOL vmlinux 0xe15148ca register_binfmt +EXPORT_SYMBOL vmlinux 0xe1605aba generic_file_splice_write +EXPORT_SYMBOL vmlinux 0xe162204a scsi_register_interface +EXPORT_SYMBOL vmlinux 0xe1761617 security_inet_conn_request +EXPORT_SYMBOL vmlinux 0xe1a81c3a icmpv6msg_statistics +EXPORT_SYMBOL vmlinux 0xe1e3c318 tcf_action_dump_1 +EXPORT_SYMBOL vmlinux 0xe1e64e24 xfrm6_rcv_spi +EXPORT_SYMBOL vmlinux 0xe1ef59aa compat_nf_getsockopt +EXPORT_SYMBOL vmlinux 0xe2029eaa pci_get_bus_and_slot +EXPORT_SYMBOL vmlinux 0xe2113040 mmc_wait_for_req +EXPORT_SYMBOL vmlinux 0xe24050c7 scnprintf +EXPORT_SYMBOL vmlinux 0xe24d3a97 jiffies_64 +EXPORT_SYMBOL vmlinux 0xe279d525 kernel_getsockname +EXPORT_SYMBOL vmlinux 0xe28ba8b0 xfrm_state_insert +EXPORT_SYMBOL vmlinux 0xe2d5255a strcmp +EXPORT_SYMBOL vmlinux 0xe2e7e025 qdisc_class_hash_grow +EXPORT_SYMBOL vmlinux 0xe351633f genl_register_family +EXPORT_SYMBOL vmlinux 0xe35ae20c generic_unplug_device +EXPORT_SYMBOL vmlinux 0xe35d843b security_d_instantiate +EXPORT_SYMBOL vmlinux 0xe36eea7b md_check_recovery +EXPORT_SYMBOL vmlinux 0xe3b0192b vscnprintf +EXPORT_SYMBOL vmlinux 0xe3b93a66 swiotlb_sync_sg_for_device +EXPORT_SYMBOL vmlinux 0xe3d0a362 del_gendisk +EXPORT_SYMBOL vmlinux 0xe3fbe148 acpi_install_table_handler +EXPORT_SYMBOL vmlinux 0xe41cac3f sock_recvmsg +EXPORT_SYMBOL vmlinux 0xe4306cc8 ip_generic_getfrag +EXPORT_SYMBOL vmlinux 0xe43617f7 acpi_gbl_FADT +EXPORT_SYMBOL vmlinux 0xe4401184 generic_file_aio_read +EXPORT_SYMBOL vmlinux 0xe44e6c70 tty_get_baud_rate +EXPORT_SYMBOL vmlinux 0xe455af6b xfrm_state_register_afinfo +EXPORT_SYMBOL vmlinux 0xe456bd3a complete +EXPORT_SYMBOL vmlinux 0xe4747346 blk_integrity_unregister +EXPORT_SYMBOL vmlinux 0xe484e35f ioread32 +EXPORT_SYMBOL vmlinux 0xe4870354 _read_trylock +EXPORT_SYMBOL vmlinux 0xe49b43e3 hci_resume_dev +EXPORT_SYMBOL vmlinux 0xe49e4b80 skb_store_bits +EXPORT_SYMBOL vmlinux 0xe49e9dbc lease_get_mtime +EXPORT_SYMBOL vmlinux 0xe4b24b8c __next_cpu +EXPORT_SYMBOL vmlinux 0xe4c1df3e _read_lock_bh +EXPORT_SYMBOL vmlinux 0xe4c9f6c2 bitmap_endwrite +EXPORT_SYMBOL vmlinux 0xe4fc93a9 bio_add_pc_page +EXPORT_SYMBOL vmlinux 0xe5122890 flow_cache_genid +EXPORT_SYMBOL vmlinux 0xe523ad75 synchronize_irq +EXPORT_SYMBOL vmlinux 0xe52947e7 __phys_addr +EXPORT_SYMBOL vmlinux 0xe537e069 x86_dma_fallback_dev +EXPORT_SYMBOL vmlinux 0xe542862a pnp_disable_dev +EXPORT_SYMBOL vmlinux 0xe54b8071 neigh_table_init_no_netlink +EXPORT_SYMBOL vmlinux 0xe56400dc sock_no_shutdown +EXPORT_SYMBOL vmlinux 0xe56d551d sync_inode +EXPORT_SYMBOL vmlinux 0xe57878a1 in6_pton +EXPORT_SYMBOL vmlinux 0xe5844107 cpu_present_map +EXPORT_SYMBOL vmlinux 0xe5867808 dlci_ioctl_set +EXPORT_SYMBOL vmlinux 0xe5982bf3 seq_putc +EXPORT_SYMBOL vmlinux 0xe599adb0 xfrm_lookup +EXPORT_SYMBOL vmlinux 0xe5c78a99 do_blank_screen +EXPORT_SYMBOL vmlinux 0xe5d16d63 d_validate +EXPORT_SYMBOL vmlinux 0xe5e44848 ps2_handle_ack +EXPORT_SYMBOL vmlinux 0xe5ed5467 xfrm_policy_walk_init +EXPORT_SYMBOL vmlinux 0xe60921f6 wireless_send_event +EXPORT_SYMBOL vmlinux 0xe6422f6f mmc_request_done +EXPORT_SYMBOL vmlinux 0xe64b0341 set_blocksize +EXPORT_SYMBOL vmlinux 0xe6537c33 udp_proc_unregister +EXPORT_SYMBOL vmlinux 0xe690b8fd __ipv6_isatap_ifid +EXPORT_SYMBOL vmlinux 0xe694cc8a set_current_groups +EXPORT_SYMBOL vmlinux 0xe6b8ef5a do_mmap_pgoff +EXPORT_SYMBOL vmlinux 0xe6bd9acf __lock_buffer +EXPORT_SYMBOL vmlinux 0xe6c545d8 elevator_exit +EXPORT_SYMBOL vmlinux 0xe6cb2f0b acpi_bus_start +EXPORT_SYMBOL vmlinux 0xe6d04f9f uart_match_port +EXPORT_SYMBOL vmlinux 0xe6d46a01 vm_insert_page +EXPORT_SYMBOL vmlinux 0xe6dadc21 kernel_setsockopt +EXPORT_SYMBOL vmlinux 0xe6e09c33 bio_alloc +EXPORT_SYMBOL vmlinux 0xe6f75785 eth_header_cache_update +EXPORT_SYMBOL vmlinux 0xe6fbe430 can_do_mlock +EXPORT_SYMBOL vmlinux 0xe70eebcc bio_clone +EXPORT_SYMBOL vmlinux 0xe716baed acpi_unregister_ioapic +EXPORT_SYMBOL vmlinux 0xe717feeb bio_put +EXPORT_SYMBOL vmlinux 0xe71cf65f sock_no_sendmsg +EXPORT_SYMBOL vmlinux 0xe720682f mb_cache_entry_insert +EXPORT_SYMBOL vmlinux 0xe725d067 pci_bus_find_capability +EXPORT_SYMBOL vmlinux 0xe74d9e50 simple_unlink +EXPORT_SYMBOL vmlinux 0xe751ba22 rfkill_allocate +EXPORT_SYMBOL vmlinux 0xe7546fa3 dmam_alloc_coherent +EXPORT_SYMBOL vmlinux 0xe76248f0 input_close_device +EXPORT_SYMBOL vmlinux 0xe76db524 ppp_output_wakeup +EXPORT_SYMBOL vmlinux 0xe78459c7 fifo_create_dflt +EXPORT_SYMBOL vmlinux 0xe79a5fe1 dma_async_client_chan_request +EXPORT_SYMBOL vmlinux 0xe7a5c0f0 register_filesystem +EXPORT_SYMBOL vmlinux 0xe7ac09c1 path_lookup +EXPORT_SYMBOL vmlinux 0xe7b486a7 free_buffer_head +EXPORT_SYMBOL vmlinux 0xe7d2aca1 security_sk_classify_flow +EXPORT_SYMBOL vmlinux 0xe7d4daac seq_list_next +EXPORT_SYMBOL vmlinux 0xe80ce219 sysctl_tcp_dma_copybreak +EXPORT_SYMBOL vmlinux 0xe81a0d7f register_cdrom +EXPORT_SYMBOL vmlinux 0xe8288225 ip_fragment +EXPORT_SYMBOL vmlinux 0xe83e789e add_to_page_cache_locked +EXPORT_SYMBOL vmlinux 0xe8413996 xfrm_register_mode +EXPORT_SYMBOL vmlinux 0xe8583614 posix_acl_from_xattr +EXPORT_SYMBOL vmlinux 0xe860edf0 remap_pfn_range +EXPORT_SYMBOL vmlinux 0xe8794ce1 slhc_toss +EXPORT_SYMBOL vmlinux 0xe8920035 jbd2_journal_init_jbd_inode +EXPORT_SYMBOL vmlinux 0xe8a3605f acpi_processor_set_thermal_limit +EXPORT_SYMBOL vmlinux 0xe8a4caa0 dump_trace +EXPORT_SYMBOL vmlinux 0xe8cd902e hweight16 +EXPORT_SYMBOL vmlinux 0xe9041e08 hci_conn_auth +EXPORT_SYMBOL vmlinux 0xe910b532 del_timer_sync +EXPORT_SYMBOL vmlinux 0xe914e41e strcpy +EXPORT_SYMBOL vmlinux 0xe9456a5a sysctl_xfrm_aevent_rseqth +EXPORT_SYMBOL vmlinux 0xe9811c0a filp_close +EXPORT_SYMBOL vmlinux 0xe981822b dec_zone_page_state +EXPORT_SYMBOL vmlinux 0xe98a4363 skb_checksum_help +EXPORT_SYMBOL vmlinux 0xe997667b wrmsr_on_cpu +EXPORT_SYMBOL vmlinux 0xe9ace35a swiotlb_unmap_sg +EXPORT_SYMBOL vmlinux 0xe9c4f355 tr_type_trans +EXPORT_SYMBOL vmlinux 0xe9c53214 set_page_dirty +EXPORT_SYMBOL vmlinux 0xea008e90 drop_super +EXPORT_SYMBOL vmlinux 0xea0a85ab blk_start_queue +EXPORT_SYMBOL vmlinux 0xea10212a int_to_scsilun +EXPORT_SYMBOL vmlinux 0xea10655a __bitmap_intersects +EXPORT_SYMBOL vmlinux 0xea147363 printk +EXPORT_SYMBOL vmlinux 0xea2085fc fput +EXPORT_SYMBOL vmlinux 0xea4f065b blk_queue_update_dma_pad +EXPORT_SYMBOL vmlinux 0xea68a449 journal_get_write_access +EXPORT_SYMBOL vmlinux 0xea6fcdaa genl_unregister_family +EXPORT_SYMBOL vmlinux 0xea757d9e inet_frags_init +EXPORT_SYMBOL vmlinux 0xea7ee743 copy_strings_kernel +EXPORT_SYMBOL vmlinux 0xea9b99ef seq_open_private +EXPORT_SYMBOL vmlinux 0xeac5f6f2 tty_insert_flip_string +EXPORT_SYMBOL vmlinux 0xeac95a1b generic_read_dir +EXPORT_SYMBOL vmlinux 0xead58fb9 print_hex_dump +EXPORT_SYMBOL vmlinux 0xead5f5ac jbd2_journal_clear_features +EXPORT_SYMBOL vmlinux 0xeae2bad8 compat_mc_setsockopt +EXPORT_SYMBOL vmlinux 0xeae3dfd6 __const_udelay +EXPORT_SYMBOL vmlinux 0xeb02b9a5 scsi_track_queue_full +EXPORT_SYMBOL vmlinux 0xeb14c77e skb_abort_seq_read +EXPORT_SYMBOL vmlinux 0xeb1fabf6 interruptible_sleep_on +EXPORT_SYMBOL vmlinux 0xeb228272 posix_acl_create_masq +EXPORT_SYMBOL vmlinux 0xeb395084 param_get_invbool +EXPORT_SYMBOL vmlinux 0xeb6137a4 swiotlb_free_coherent +EXPORT_SYMBOL vmlinux 0xeb6d94cb qdisc_calculate_pkt_len +EXPORT_SYMBOL vmlinux 0xeb7228bf qdisc_watchdog_schedule +EXPORT_SYMBOL vmlinux 0xeb72e81a default_unplug_io_fn +EXPORT_SYMBOL vmlinux 0xeb78d6c0 hci_unregister_cb +EXPORT_SYMBOL vmlinux 0xeb8f54b3 strstrip +EXPORT_SYMBOL vmlinux 0xeba1386d agp_generic_create_gatt_table +EXPORT_SYMBOL vmlinux 0xebbf1dba strncasecmp +EXPORT_SYMBOL vmlinux 0xebd273a6 strict_strtoull +EXPORT_SYMBOL vmlinux 0xebed96ac mb_cache_entry_release +EXPORT_SYMBOL vmlinux 0xebedc550 neigh_changeaddr +EXPORT_SYMBOL vmlinux 0xebf0830b unregister_netdev +EXPORT_SYMBOL vmlinux 0xebff49f0 inet_accept +EXPORT_SYMBOL vmlinux 0xec0da1f9 tty_driver_kref_put +EXPORT_SYMBOL vmlinux 0xec2c6c63 kmem_cache_free +EXPORT_SYMBOL vmlinux 0xec3bf4e9 request_firmware +EXPORT_SYMBOL vmlinux 0xec45a0cc fb_class +EXPORT_SYMBOL vmlinux 0xec48b368 current_fs_time +EXPORT_SYMBOL vmlinux 0xec794ba0 __send_remote_softirq +EXPORT_SYMBOL vmlinux 0xec860422 bioset_free +EXPORT_SYMBOL vmlinux 0xeccebb50 have_submounts +EXPORT_SYMBOL vmlinux 0xecd41a34 sock_get_timestamp +EXPORT_SYMBOL vmlinux 0xecde1418 _spin_lock_irq +EXPORT_SYMBOL vmlinux 0xecfb4e86 simple_link +EXPORT_SYMBOL vmlinux 0xed14f346 release_sock +EXPORT_SYMBOL vmlinux 0xed4cba62 journal_load +EXPORT_SYMBOL vmlinux 0xed6ba5fa phy_register_fixup_for_id +EXPORT_SYMBOL vmlinux 0xed6cc474 __devm_request_region +EXPORT_SYMBOL vmlinux 0xed6f8714 xrlim_allow +EXPORT_SYMBOL vmlinux 0xed7c45f6 scsi_bios_ptable +EXPORT_SYMBOL vmlinux 0xedb2b884 dmam_pool_create +EXPORT_SYMBOL vmlinux 0xedbaee5e nla_strcmp +EXPORT_SYMBOL vmlinux 0xedc03953 iounmap +EXPORT_SYMBOL vmlinux 0xedcb5eb7 proc_dostring +EXPORT_SYMBOL vmlinux 0xedd14538 param_get_uint +EXPORT_SYMBOL vmlinux 0xedd6f5f3 journal_get_create_access +EXPORT_SYMBOL vmlinux 0xedefc2e5 agp_bind_memory +EXPORT_SYMBOL vmlinux 0xee1ee7ed atm_alloc_charge +EXPORT_SYMBOL vmlinux 0xee2d0fc7 _local_bh_enable +EXPORT_SYMBOL vmlinux 0xee5281cd pnp_is_active +EXPORT_SYMBOL vmlinux 0xee787a1a nf_setsockopt +EXPORT_SYMBOL vmlinux 0xee7eb9e1 pnp_platform_devices +EXPORT_SYMBOL vmlinux 0xeea9dbaf bitmap_bitremap +EXPORT_SYMBOL vmlinux 0xeeb1717c param_array_get +EXPORT_SYMBOL vmlinux 0xeeb3edd5 blkdev_issue_flush +EXPORT_SYMBOL vmlinux 0xeecaea22 down_write_trylock +EXPORT_SYMBOL vmlinux 0xeee86a27 nf_afinfo +EXPORT_SYMBOL vmlinux 0xeef19211 blk_queue_start_tag +EXPORT_SYMBOL vmlinux 0xef0c219b skb_pull +EXPORT_SYMBOL vmlinux 0xef13b91d find_get_pages_tag +EXPORT_SYMBOL vmlinux 0xef15facf ipv6_dev_get_saddr +EXPORT_SYMBOL vmlinux 0xef1db2e5 jbd2_journal_clear_err +EXPORT_SYMBOL vmlinux 0xef2e7bd4 block_write_end +EXPORT_SYMBOL vmlinux 0xef3e91fe sock_kmalloc +EXPORT_SYMBOL vmlinux 0xef8ab8df dev_remove_pack +EXPORT_SYMBOL vmlinux 0xef9aedfc boot_option_idle_override +EXPORT_SYMBOL vmlinux 0xefa62ba5 sock_setsockopt +EXPORT_SYMBOL vmlinux 0xefa8cb36 pid_task +EXPORT_SYMBOL vmlinux 0xefae2cdb bdi_set_max_ratio +EXPORT_SYMBOL vmlinux 0xefc77514 __dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0xefdd70ce security_secid_to_secctx +EXPORT_SYMBOL vmlinux 0xefe099c3 acpi_get_event_status +EXPORT_SYMBOL vmlinux 0xefe26913 dev_set_allmulti +EXPORT_SYMBOL vmlinux 0xf0009fee put_pages_list +EXPORT_SYMBOL vmlinux 0xf006ccc6 __xfrm_policy_check +EXPORT_SYMBOL vmlinux 0xf0191c34 agp_generic_enable +EXPORT_SYMBOL vmlinux 0xf034828d lock_sock_nested +EXPORT_SYMBOL vmlinux 0xf04454c0 backlight_device_unregister +EXPORT_SYMBOL vmlinux 0xf060b282 scsi_get_command +EXPORT_SYMBOL vmlinux 0xf065f629 ioread16be +EXPORT_SYMBOL vmlinux 0xf068bdef mpage_bio_submit +EXPORT_SYMBOL vmlinux 0xf07fa58d scsi_set_medium_removal +EXPORT_SYMBOL vmlinux 0xf097d3e1 pcim_iomap_table +EXPORT_SYMBOL vmlinux 0xf0b57c68 param_set_long +EXPORT_SYMBOL vmlinux 0xf0e5e77f bt_sock_ioctl +EXPORT_SYMBOL vmlinux 0xf0f1246c kvasprintf +EXPORT_SYMBOL vmlinux 0xf0fb65ce dm_register_target +EXPORT_SYMBOL vmlinux 0xf0fee2e8 pcim_iounmap_regions +EXPORT_SYMBOL vmlinux 0xf10de535 ioread8 +EXPORT_SYMBOL vmlinux 0xf11543ff find_first_zero_bit +EXPORT_SYMBOL vmlinux 0xf116d4b5 copy_in_user +EXPORT_SYMBOL vmlinux 0xf13f8f46 alloc_tty_driver +EXPORT_SYMBOL vmlinux 0xf1420618 input_free_device +EXPORT_SYMBOL vmlinux 0xf162fe2d sysctl_xfrm_aevent_etime +EXPORT_SYMBOL vmlinux 0xf16cd806 filemap_write_and_wait +EXPORT_SYMBOL vmlinux 0xf17191c9 __insert_inode_hash +EXPORT_SYMBOL vmlinux 0xf174ed48 acquire_console_sem +EXPORT_SYMBOL vmlinux 0xf1752afe __request_region +EXPORT_SYMBOL vmlinux 0xf18be979 alloc_disk +EXPORT_SYMBOL vmlinux 0xf19294db bt_sock_unregister +EXPORT_SYMBOL vmlinux 0xf195c682 fb_invert_cmaps +EXPORT_SYMBOL vmlinux 0xf19e2fc0 lock_rename +EXPORT_SYMBOL vmlinux 0xf1e0f3e0 pcix_set_mmrbc +EXPORT_SYMBOL vmlinux 0xf1e41132 d_add_ci +EXPORT_SYMBOL vmlinux 0xf1e82f78 mark_info_dirty +EXPORT_SYMBOL vmlinux 0xf1e98c74 avenrun +EXPORT_SYMBOL vmlinux 0xf1f42356 pci_set_master +EXPORT_SYMBOL vmlinux 0xf20aee9e phy_device_create +EXPORT_SYMBOL vmlinux 0xf20dabd8 free_irq +EXPORT_SYMBOL vmlinux 0xf21d8179 scsi_device_quiesce +EXPORT_SYMBOL vmlinux 0xf220c28c phy_detach +EXPORT_SYMBOL vmlinux 0xf246de13 tcf_hash_destroy +EXPORT_SYMBOL vmlinux 0xf2660f94 qdisc_tree_decrease_qlen +EXPORT_SYMBOL vmlinux 0xf27e0bff xfrm_stateonly_find +EXPORT_SYMBOL vmlinux 0xf2997713 tty_termios_hw_change +EXPORT_SYMBOL vmlinux 0xf29ca034 default_llseek +EXPORT_SYMBOL vmlinux 0xf2a02f99 vfs_dq_quota_on_remount +EXPORT_SYMBOL vmlinux 0xf2a6d2bf xfrm_policy_count +EXPORT_SYMBOL vmlinux 0xf2ab098a __dst_free +EXPORT_SYMBOL vmlinux 0xf2afa595 param_get_charp +EXPORT_SYMBOL vmlinux 0xf2e579e6 hub_port_logical_disconnect +EXPORT_SYMBOL vmlinux 0xf2eeff90 mmc_set_data_timeout +EXPORT_SYMBOL vmlinux 0xf313da4e sha_transform +EXPORT_SYMBOL vmlinux 0xf3341268 __clear_user +EXPORT_SYMBOL vmlinux 0xf338d4c3 netlink_unregister_notifier +EXPORT_SYMBOL vmlinux 0xf33a7ede nf_getsockopt +EXPORT_SYMBOL vmlinux 0xf346231f seq_list_start_head +EXPORT_SYMBOL vmlinux 0xf34e1f39 n_tty_ioctl_helper +EXPORT_SYMBOL vmlinux 0xf35d2b40 dm_table_get +EXPORT_SYMBOL vmlinux 0xf373a5f7 input_event +EXPORT_SYMBOL vmlinux 0xf373ccfc page_put_link +EXPORT_SYMBOL vmlinux 0xf39f759e inode_double_lock +EXPORT_SYMBOL vmlinux 0xf3bf0bce __bitmap_complement +EXPORT_SYMBOL vmlinux 0xf3f63de7 skb_prepare_seq_read +EXPORT_SYMBOL vmlinux 0xf4129e00 audit_log_format +EXPORT_SYMBOL vmlinux 0xf42f30cc set_pages_uc +EXPORT_SYMBOL vmlinux 0xf441ac43 ioread8_rep +EXPORT_SYMBOL vmlinux 0xf441e032 bio_sector_offset +EXPORT_SYMBOL vmlinux 0xf4528073 scsi_kmap_atomic_sg +EXPORT_SYMBOL vmlinux 0xf452f436 bio_integrity_tag_size +EXPORT_SYMBOL vmlinux 0xf464ef69 pnp_stop_dev +EXPORT_SYMBOL vmlinux 0xf47a933c page_readlink +EXPORT_SYMBOL vmlinux 0xf49bc67a atm_pcr_goal +EXPORT_SYMBOL vmlinux 0xf4a2491f tty_shutdown +EXPORT_SYMBOL vmlinux 0xf4a496f4 jbd2_journal_check_used_features +EXPORT_SYMBOL vmlinux 0xf4a5c213 avail_to_resrv_perfctr_nmi_bit +EXPORT_SYMBOL vmlinux 0xf4f14de6 rtnl_trylock +EXPORT_SYMBOL vmlinux 0xf4f52f93 dqstats +EXPORT_SYMBOL vmlinux 0xf4fd7eed redirty_page_for_writepage +EXPORT_SYMBOL vmlinux 0xf51ae235 touch_nmi_watchdog +EXPORT_SYMBOL vmlinux 0xf53d4c26 qdisc_class_hash_destroy +EXPORT_SYMBOL vmlinux 0xf55c5c2f blk_queue_find_tag +EXPORT_SYMBOL vmlinux 0xf5bb5dcc inet_csk_delete_keepalive_timer +EXPORT_SYMBOL vmlinux 0xf5ce9811 tcp_memory_allocated +EXPORT_SYMBOL vmlinux 0xf5d91be0 jbd2_journal_get_undo_access +EXPORT_SYMBOL vmlinux 0xf5dda112 inet_bind +EXPORT_SYMBOL vmlinux 0xf606ec39 dm_table_get_mode +EXPORT_SYMBOL vmlinux 0xf6417c43 pagevec_lookup_tag +EXPORT_SYMBOL vmlinux 0xf64c09d6 devm_ioremap +EXPORT_SYMBOL vmlinux 0xf64ed723 xfrm6_rcv +EXPORT_SYMBOL vmlinux 0xf6598cd0 skb_copy_bits +EXPORT_SYMBOL vmlinux 0xf666cbb3 __memcpy_fromio +EXPORT_SYMBOL vmlinux 0xf66d7727 phy_ethtool_sset +EXPORT_SYMBOL vmlinux 0xf6815397 posix_lock_file +EXPORT_SYMBOL vmlinux 0xf6a61256 jbd2_journal_get_write_access +EXPORT_SYMBOL vmlinux 0xf6a900b7 dev_mc_add +EXPORT_SYMBOL vmlinux 0xf6bb4729 color_table +EXPORT_SYMBOL vmlinux 0xf6c53202 pci_dev_get +EXPORT_SYMBOL vmlinux 0xf6c67d02 bh_submit_read +EXPORT_SYMBOL vmlinux 0xf6cdb69b key_revoke +EXPORT_SYMBOL vmlinux 0xf6dcc427 __locks_copy_lock +EXPORT_SYMBOL vmlinux 0xf6ebc03b net_ratelimit +EXPORT_SYMBOL vmlinux 0xf705ff13 phy_connect +EXPORT_SYMBOL vmlinux 0xf743d5be scsi_target_resume +EXPORT_SYMBOL vmlinux 0xf749534a gen_pool_free +EXPORT_SYMBOL vmlinux 0xf75b36c9 jbd2_journal_destroy +EXPORT_SYMBOL vmlinux 0xf78d04ab netlink_register_notifier +EXPORT_SYMBOL vmlinux 0xf7a2a3c7 __scsi_device_lookup +EXPORT_SYMBOL vmlinux 0xf7b89124 set_bh_page +EXPORT_SYMBOL vmlinux 0xf7ddb696 agp_generic_type_to_mask_type +EXPORT_SYMBOL vmlinux 0xf7efcdc5 arp_find +EXPORT_SYMBOL vmlinux 0xf811e69d scsi_eh_flush_done_q +EXPORT_SYMBOL vmlinux 0xf8146b51 bt_sock_unlink +EXPORT_SYMBOL vmlinux 0xf81a3662 compat_ip_setsockopt +EXPORT_SYMBOL vmlinux 0xf82abc1d isa_dma_bridge_buggy +EXPORT_SYMBOL vmlinux 0xf82e3d47 acpi_initialize_objects +EXPORT_SYMBOL vmlinux 0xf82f1109 utf8_wctomb +EXPORT_SYMBOL vmlinux 0xf847b471 ps2_handle_response +EXPORT_SYMBOL vmlinux 0xf863d3d3 hci_connect +EXPORT_SYMBOL vmlinux 0xf876683c dev_driver_string +EXPORT_SYMBOL vmlinux 0xf8814f73 rb_last +EXPORT_SYMBOL vmlinux 0xf88e0ee2 acpi_get_table_header +EXPORT_SYMBOL vmlinux 0xf890fe7f pm_idle +EXPORT_SYMBOL vmlinux 0xf89843f9 schedule_work +EXPORT_SYMBOL vmlinux 0xf8aa47ae mutex_lock_killable +EXPORT_SYMBOL vmlinux 0xf8b30e93 mempool_create +EXPORT_SYMBOL vmlinux 0xf8b34d13 ilookup +EXPORT_SYMBOL vmlinux 0xf8c682b1 bio_add_page +EXPORT_SYMBOL vmlinux 0xf8c8e3a3 agp_backend_release +EXPORT_SYMBOL vmlinux 0xf8cf9ee5 abort_exclusive_wait +EXPORT_SYMBOL vmlinux 0xf8d95381 tcf_em_tree_destroy +EXPORT_SYMBOL vmlinux 0xf8fdf6bf dma_ops +EXPORT_SYMBOL vmlinux 0xf90f83d4 kernel_sock_shutdown +EXPORT_SYMBOL vmlinux 0xf92847b6 pcie_get_readrq +EXPORT_SYMBOL vmlinux 0xf93a2e8a blk_rq_map_sg +EXPORT_SYMBOL vmlinux 0xf98e59f0 tty_flip_buffer_push +EXPORT_SYMBOL vmlinux 0xf9a482f9 msleep +EXPORT_SYMBOL vmlinux 0xf9be5c69 vfs_rmdir +EXPORT_SYMBOL vmlinux 0xfa0564fc __wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0xfa44f38c blk_init_queue_node +EXPORT_SYMBOL vmlinux 0xfa6d625a scsi_eh_prep_cmnd +EXPORT_SYMBOL vmlinux 0xfa842fdc down_write +EXPORT_SYMBOL vmlinux 0xfaae9c9d kobject_get +EXPORT_SYMBOL vmlinux 0xfae4c37f i2c_smbus_write_word_data +EXPORT_SYMBOL vmlinux 0xfaeb31c4 rt6_lookup +EXPORT_SYMBOL vmlinux 0xfaf98462 bitrev32 +EXPORT_SYMBOL vmlinux 0xfb0443fb acpi_get_parent +EXPORT_SYMBOL vmlinux 0xfb0cf2e9 touch_all_softlockup_watchdogs +EXPORT_SYMBOL vmlinux 0xfb3cf087 pci_find_slot +EXPORT_SYMBOL vmlinux 0xfb403f69 pci_restore_state +EXPORT_SYMBOL vmlinux 0xfb493c1c pci_scan_bus_parented +EXPORT_SYMBOL vmlinux 0xfb6af58d recalc_sigpending +EXPORT_SYMBOL vmlinux 0xfb72bc41 elevator_init +EXPORT_SYMBOL vmlinux 0xfba0c2e0 llc_sap_list_lock +EXPORT_SYMBOL vmlinux 0xfbb9052a journal_check_available_features +EXPORT_SYMBOL vmlinux 0xfbc2302d locks_copy_lock +EXPORT_SYMBOL vmlinux 0xfbc617a8 kernel_read +EXPORT_SYMBOL vmlinux 0xfbf92453 param_get_bool +EXPORT_SYMBOL vmlinux 0xfc02b7ad sysctl_tcp_wmem +EXPORT_SYMBOL vmlinux 0xfc069b40 skb_checksum +EXPORT_SYMBOL vmlinux 0xfc2e76ae pcix_get_mmrbc +EXPORT_SYMBOL vmlinux 0xfc31fe88 l2cap_load +EXPORT_SYMBOL vmlinux 0xfc39e32f ioport_unmap +EXPORT_SYMBOL vmlinux 0xfcaa04a0 out_of_line_wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0xfcd056cf blk_start_queueing +EXPORT_SYMBOL vmlinux 0xfcda63a3 node_states +EXPORT_SYMBOL vmlinux 0xfcdd8cf6 param_get_ushort +EXPORT_SYMBOL vmlinux 0xfcec0987 enable_irq +EXPORT_SYMBOL vmlinux 0xfcfa03ff fb_videomode_to_modelist +EXPORT_SYMBOL vmlinux 0xfd04efbb destroy_EII_client +EXPORT_SYMBOL vmlinux 0xfd0ecdd5 acpi_is_video_device +EXPORT_SYMBOL vmlinux 0xfd1c92a8 per_cpu____irq_regs +EXPORT_SYMBOL vmlinux 0xfd41fc46 compat_nf_setsockopt +EXPORT_SYMBOL vmlinux 0xfd98879a rb_next +EXPORT_SYMBOL vmlinux 0xfdb9b629 ioread32be +EXPORT_SYMBOL vmlinux 0xfdbc4ad0 tty_hangup +EXPORT_SYMBOL vmlinux 0xfdcfc302 mmc_wait_for_app_cmd +EXPORT_SYMBOL vmlinux 0xfde2145a boot_tvec_bases +EXPORT_SYMBOL vmlinux 0xfdfc0b3b fiemap_fill_next_extent +EXPORT_SYMBOL vmlinux 0xfe01439f pci_request_region +EXPORT_SYMBOL vmlinux 0xfe047ce6 acpi_enter_sleep_state +EXPORT_SYMBOL vmlinux 0xfe0dc56f hci_register_dev +EXPORT_SYMBOL vmlinux 0xfe0f5e62 request_key +EXPORT_SYMBOL vmlinux 0xfe133f2e xfrm_init_state +EXPORT_SYMBOL vmlinux 0xfe37cbab compat_ipv6_getsockopt +EXPORT_SYMBOL vmlinux 0xfe392bcd generic_segment_checks +EXPORT_SYMBOL vmlinux 0xfe3ac12e find_get_pages_contig +EXPORT_SYMBOL vmlinux 0xfe5d4bb2 sys_tz +EXPORT_SYMBOL vmlinux 0xfe769456 unregister_netdevice_notifier +EXPORT_SYMBOL vmlinux 0xfe7c4287 nr_cpu_ids +EXPORT_SYMBOL vmlinux 0xfebfa15d hci_conn_switch_role +EXPORT_SYMBOL vmlinux 0xfec3c2f2 bcd2bin +EXPORT_SYMBOL vmlinux 0xfed70555 jbd2_journal_flush +EXPORT_SYMBOL vmlinux 0xfedd35fc console_suspend_enabled +EXPORT_SYMBOL vmlinux 0xfee27768 init_special_inode +EXPORT_SYMBOL vmlinux 0xfef96e23 __scsi_print_command +EXPORT_SYMBOL vmlinux 0xff1e9dd8 seq_list_start +EXPORT_SYMBOL vmlinux 0xff550566 bmap +EXPORT_SYMBOL vmlinux 0xff6878cf fb_default_cmap +EXPORT_SYMBOL vmlinux 0xff708fd3 mempool_destroy +EXPORT_SYMBOL vmlinux 0xff73377b netpoll_setup +EXPORT_SYMBOL vmlinux 0xff7559e4 ioport_resource +EXPORT_SYMBOL vmlinux 0xff9ca065 fb_edid_to_monspecs +EXPORT_SYMBOL vmlinux 0xffa9bd29 mark_buffer_async_write +EXPORT_SYMBOL vmlinux 0xffafdc5c _read_unlock_irq +EXPORT_SYMBOL vmlinux 0xffc31720 invalidate_bdev +EXPORT_SYMBOL vmlinux 0xffd5a395 default_wake_function +EXPORT_SYMBOL vmlinux 0xffd7d6c5 uart_unregister_driver +EXPORT_SYMBOL vmlinux 0xffebb694 scsi_init_io +EXPORT_SYMBOL vmlinux 0xffed9d4d jbd2_journal_unlock_updates +EXPORT_SYMBOL_GPL arch/x86/kernel/cpu/cpufreq/speedstep-lib 0x16836e04 speedstep_detect_processor +EXPORT_SYMBOL_GPL arch/x86/kernel/cpu/cpufreq/speedstep-lib 0x4cdb4bd0 speedstep_get_processor_frequency +EXPORT_SYMBOL_GPL arch/x86/kernel/cpu/cpufreq/speedstep-lib 0xd494ee54 speedstep_get_freqs +EXPORT_SYMBOL_GPL arch/x86/kernel/microcode 0xdf66ca81 ucode_cpu_info +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x00aaf935 kvm_disable_tdp +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x00c41b68 kvm_set_msr_common +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0209e520 kvm_cpu_get_interrupt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x02b176ae kvm_get_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x04162c68 is_error_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x06ccca4a kvm_report_emulation_failure +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x094ac8f4 kvm_get_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x096f0fe1 __kvm_set_memory_region +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x09fe8abd kvm_set_cr4 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0b8f1b8a kvm_load_guest_fpu +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0eccc801 kvm_set_memory_region +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0fea85f8 kvm_clear_guest +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x117ea67b kvm_put_kvm +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x12d1b23b kvm_release_pfn_clean +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x12ee9fbf kvm_inject_pending_timer_irqs +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1553ccce kvm_lapic_set_tpr +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1563796f gfn_to_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1c79a65c kvm_get_apic_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1e4580bb kvm_release_pfn_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x2235873d kvm_mmu_page_fault +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x2322e039 kvm_set_pfn_accessed +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x26761056 kvm_create_lapic +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x27046576 kvm_exit +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x2e2dbb7f kvm_emulate_halt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x317f9e6b kvm_enable_efer_bits +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x3795dd14 kvm_lapic_get_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x3c3a6bc5 kvm_set_apic_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x3fe68371 kvm_cpu_has_interrupt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x4809f83d kvm_lmsw +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x4a7cbe69 is_error_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x4f9cef18 kvm_emulate_hypercall +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x51ba4894 fx_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x54ba0e0e kvm_set_cr3 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x557860a2 kvm_write_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x5a005f20 kvm_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x6365e092 kvm_queue_exception_e +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x64b49051 kvm_emulate_cpuid +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x69f72a11 kvm_set_page_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x6beae4d6 kvm_vcpu_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x6df1a9c7 kvm_get_kvm +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x75953a49 kvm_set_cr0 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x7805180f emulate_instruction +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x78d7b87e kvm_is_visible_gfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8c61771c kvm_put_guest_fpu +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8ce4f3ab kvm_enable_tdp +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8d425ba1 kvm_set_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8d6f3d13 kvm_x86_ops +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8e7f9b47 segment_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x903778ca emulator_write_emulated +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x988df7e9 kvm_lapic_enabled +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x9aa9451d load_pdptrs +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x9ce545f9 kvm_get_cs_db_l_bits +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa201ff11 kvm_mmu_invlpg +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa361bc65 kvm_set_pfn_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa438186a kvm_vcpu_uninit +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa505a215 kvm_lapic_get_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xaa39b963 kvm_release_page_clean +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xaac3ddc6 kvm_read_guest +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb158a7ca kvm_release_page_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb4456b21 gfn_to_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb5f42786 kvm_mmu_load +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb759d5fb kvm_mmu_unprotect_page_virt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbc2735c3 kvm_get_msr_common +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbd377dc9 kvm_mmu_set_nonpresent_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbd86163a kvm_handle_fault_on_reboot +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbd94103b kvm_mmu_set_base_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xc8e71670 kvm_emulate_pio +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xcb382b58 kvm_lapic_reset +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xcedc9f8b kvm_emulate_pio_string +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xcef7aeb2 kvm_mmu_reset_context +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd0b2727a kvm_mmu_set_mask_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd296def9 kvm_is_error_hva +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd665ba76 emulator_read_std +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xe34b1994 gfn_to_hva +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xe3878e22 kvm_queue_exception +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xe5310334 kvm_lapic_find_highest_irr +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xeb704bfa kvm_clear_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf1e0103d kvm_timer_intr_post +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf2f707c4 kvm_task_switch +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf35502ca kvm_inject_nmi +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf3c0f643 kvm_resched +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf947e82d kvm_read_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xff4ce98f kvm_vcpu_cache +EXPORT_SYMBOL_GPL crypto/aes_generic 0x1381bf2d crypto_ft_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x22894d94 crypto_il_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5f943003 crypto_it_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5fe743de crypto_aes_expand_key +EXPORT_SYMBOL_GPL crypto/aes_generic 0x6e9cc2ba crypto_fl_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0xe30299c5 crypto_aes_set_key +EXPORT_SYMBOL_GPL crypto/async_tx/async_memcpy 0x2197ea37 async_memcpy +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x011ee2b8 async_tx_quiesce +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x393a1354 async_tx_run_dependencies +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x3ac9e557 async_tx_submit +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x55879432 async_trigger_callback +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x6b4a6db2 async_tx_issue_pending_all +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0xa7b0f830 dma_wait_for_async_tx +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0xd98571ba __async_tx_find_channel +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0x3d79e99c async_xor_zero_sum +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0xeae5a9fd async_xor +EXPORT_SYMBOL_GPL crypto/des_generic 0xcfd9a2c0 des_ekey +EXPORT_SYMBOL_GPL crypto/twofish_common 0xb296502d twofish_setkey +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x02ff9464 cfag12864b_isinited +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x0ecb2e5d cfag12864b_disable +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x305dc3c6 cfag12864b_isenabled +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x3389f926 cfag12864b_enable +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x9522a342 cfag12864b_getrate +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0xc48e9d95 cfag12864b_buffer +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x14102f23 ks0108_displaystate +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x48a70518 ks0108_writedata +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x4f506333 ks0108_startline +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x6edae968 ks0108_isinited +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xbf4774db ks0108_writecontrol +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xedde6df2 ks0108_page +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xfee8ef7b ks0108_address +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x053ab5a1 tpm_pm_resume +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x09c52d81 tpm_show_owned +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x1b0ecd46 tpm_remove_hardware +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x238a497e tpm_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x250fe8b3 tpm_show_temp_deactivated +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x25bacaf3 tpm_continue_selftest +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x357a7304 tpm_show_caps +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x447da381 tpm_pm_suspend +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x536c7301 tpm_store_cancel +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x62f888b7 tpm_gen_interrupt +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x85f32426 tpm_dev_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x86d21c03 tpm_show_pcrs +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x945c9cb3 tpm_get_timeouts +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x973ee529 tpm_dev_vendor_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xa931f4ba tpm_calc_ordinal_duration +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xb843694a tpm_write +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xbbc3c07a tpm_register_hardware +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xbbc80003 tpm_show_caps_1_2 +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xc73b65c4 tpm_show_pubek +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xcc1693ab tpm_show_active +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xce18d2c8 tpm_open +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xebebbe8d tpm_show_enabled +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xfa37ef15 tpm_read +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm_bios 0x67d3b9aa tpm_bios_log_setup +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm_bios 0xca3301dc tpm_bios_log_teardown +EXPORT_SYMBOL_GPL drivers/dca/dca 0x28f12408 dca3_get_tag +EXPORT_SYMBOL_GPL drivers/dca/dca 0x2e471f01 dca_register_notify +EXPORT_SYMBOL_GPL drivers/dca/dca 0x31a2c8df dca_get_tag +EXPORT_SYMBOL_GPL drivers/dca/dca 0x8006c614 dca_unregister_notify +EXPORT_SYMBOL_GPL drivers/dca/dca 0x9c555a61 unregister_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0xb575212e dca_remove_requester +EXPORT_SYMBOL_GPL drivers/dca/dca 0xc6989265 free_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0xd8d79dbe register_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0xe1528c60 alloc_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0xf5f54a23 dca_add_requester +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x01d49ad2 edac_pci_del_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x2b29bb58 edac_mc_find_csrow_by_page +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x320b4464 edac_pci_release_generic_ctl +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x383ff3f9 edac_mc_handle_ue +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x4f344e84 edac_mc_alloc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x4f8d943a edac_pci_free_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x52ecdee7 edac_mc_handle_ce +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x583be4e2 edac_device_handle_ue +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x5aac3e00 edac_mc_handle_ce_no_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x5ef02549 edac_device_handle_ce +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x60af076e edac_mc_del_mc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x70782bac edac_mc_handle_ue_no_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x70a17a23 edac_device_alloc_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x85e849ca edac_pci_add_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x93596fea edac_device_add_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xa705c411 edac_pci_handle_npe +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xabbda82a edac_mc_free +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xb38bd890 edac_device_del_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xca2ff835 edac_pci_reset_delay_period +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xcdcc6130 edac_pci_create_generic_ctl +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xce82348d edac_pci_alloc_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xcfc49b6c edac_mc_add_mc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xe37b6552 edac_device_free_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xf25d7e97 edac_pci_handle_pe +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x01fd453e usbhid_lookup_quirk +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x246ce8ed hiddev_hid_event +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x48db528b usbhid_submit_report +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0xf715dedd usbhid_set_leds +EXPORT_SYMBOL_GPL drivers/i2c/busses/i2c-nforce2 0xbcdeb6eb nforce2_smbus +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0x58ed75d7 hpsb_config_rom_ip1394_add +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0xec8d18cf hpsb_disable_irm +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0xefc79df8 hpsb_config_rom_ip1394_remove +EXPORT_SYMBOL_GPL drivers/infiniband/hw/ipath/ib_ipath 0x1514b2b2 ipath_debug +EXPORT_SYMBOL_GPL drivers/input/ff-memless 0x32282501 input_ff_create_memless +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x05e7f13e wm97xx_get_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x15b95809 wm97xx_set_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x2c658e0c wm9705_codec +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x31db9356 wm9712_codec +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x401f356c wm97xx_set_suspend_mode +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x405129ab wm97xx_unregister_mach_ops +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x60edba96 wm97xx_config_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x66ec2a6e wm97xx_read_aux_adc +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xb515506c wm97xx_reg_read +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xda37554f wm97xx_register_mach_ops +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xddc028b7 wm97xx_reg_write +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xfd7193c8 wm9713_codec +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x0b1a95cd gigaset_m10x_input +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x0c05baa9 gigaset_stop +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x1170f695 gigaset_start +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x1ae60259 gigaset_freecs +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x2b89a1be gigaset_add_event +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x2c0979ce gigaset_dbg_buffer +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x454aa44f gigaset_debuglevel +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x6ca0d57f gigaset_initcs +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x89d7f5bb gigaset_if_receive +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x8c25b292 gigaset_handle_modem_response +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x953a2725 gigaset_freedriver +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x9b012d02 gigaset_shutdown +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xa3c2a512 gigaset_initdriver +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xb91f2588 gigaset_skb_sent +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xcf14b452 gigaset_fill_inbuf +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xf5308471 gigaset_m10x_send_skb +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xfde2d249 gigaset_blockdriver +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x0f5a72c9 led_classdev_suspend +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x73413396 led_classdev_resume +EXPORT_SYMBOL_GPL drivers/leds/led-class 0xbac80395 led_classdev_unregister +EXPORT_SYMBOL_GPL drivers/leds/led-class 0xbdb0d224 led_classdev_register +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x04662e0f ir_codes_fusionhdtv_mce +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x07e92917 ir_codes_avermedia_a16d +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x083661f9 ir_codes_avertv_303 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x088631b9 ir_codes_behold +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x1cb148f5 ir_extract_bits +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2456e513 ir_decode_pulsedistance +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2a4852cc ir_codes_dntv_live_dvb_t +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2af1a608 ir_codes_proteus_2309 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x3811daea ir_codes_manli +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x43c89ef4 ir_decode_biphase +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x45b08f68 ir_codes_pinnacle_grey +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4740e7a3 ir_codes_empty +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4beb7618 ir_codes_encore_enltv_fm53 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4ea698a2 ir_codes_purpletv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x55338dda ir_codes_pixelview_new +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x589cad50 ir_codes_apac_viewcomp +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x5db13554 ir_codes_encore_enltv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6606596a ir_rc5_timer_keyup +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6adc476d ir_codes_powercolor_real_angel +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6aefdbea ir_codes_npgtech +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6b87c69d ir_codes_iodata_bctv7e +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6d6511e7 ir_dump_samples +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6e2a1870 ir_codes_adstech_dvb_t_pci +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x7277973d ir_codes_pctv_sedna +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x75e89cc3 ir_codes_flydvb +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x772a30a2 ir_codes_nebula +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x7953bd28 ir_input_init +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x7a9a39b9 ir_input_nokey +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x7b38143b ir_codes_encore_enltv2 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x85d37490 ir_codes_dntv_live_dvbt_pro +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x89cc1189 ir_codes_winfast +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x902a3cd2 ir_codes_hauppauge_new +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x933d0bb3 ir_codes_msi_tvanywhere +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x9451e232 ir_codes_behold_columbus +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x96470cab ir_codes_cinergy +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb1f4eb35 ir_codes_avermedia_dvbt +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb50812de ir_codes_real_audio_220_32_keys +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb6cd4666 ir_codes_eztv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xbb08d146 ir_codes_msi_tvanywhere_plus +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xbdce6594 ir_codes_tt_1500 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc1fea0c1 ir_codes_pv951 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc42bd037 ir_codes_budget_ci_old +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc6c5a7a1 ir_codes_em_terratec +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xcdf2859f ir_codes_avermedia_m135a +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd1e0258a ir_codes_flyvideo +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd55e6891 ir_codes_gotview7135 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd9c7f010 ir_codes_rc5_tv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xdaa041ad ir_codes_cinergy_1400 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xdfcf23df ir_codes_norwood +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xee2f5e0e ir_codes_pinnacle_pctv_hd +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf07533a1 ir_codes_videomate_tv_pvr +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf0fc9374 ir_codes_avermedia +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf2b421aa ir_codes_genius_tvgo_a11mce +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf4f7a4d6 ir_rc5_timer_end +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfa177653 ir_codes_pixelview +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfb981300 ir_codes_pinnacle_color +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfc54a5cd ir_codes_asus_pc39 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfce8436a ir_input_keydown +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x156cbd11 saa7146_pgtable_free +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x4be77651 saa7146_i2c_adapter_prepare +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x4e1b4c87 saa7146_vmalloc_build_pgtable +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x534e46dd saa7146_unregister_extension +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xad7028fa saa7146_pgtable_alloc +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xc98faf20 saa7146_devices_lock +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xcef0dd61 saa7146_setgpio +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xcf0bd119 saa7146_pgtable_build_single +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xcf683cf2 saa7146_devices +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xd3a59773 saa7146_register_extension +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xded24131 saa7146_vfree_destroy_pgtable +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xe3cd9b5c saa7146_debug +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xe41ea880 saa7146_wait_for_debi_done +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x03625be4 saa7146_start_preview +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x2113c3b1 saa7146_set_hps_source_and_sync +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x4d56ee74 saa7146_unregister_device +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x67e593bd saa7146_vv_release +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xa13a5df7 saa7146_stop_preview +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xd5d0be76 saa7146_vv_init +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xe6d43634 saa7146_register_device +EXPORT_SYMBOL_GPL drivers/media/common/tuners/mt20xx 0xd51b91f0 microtune_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/mxl5007t 0x15a2a824 mxl5007t_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda18271 0x0b8cc61e tda18271_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda827x 0xfa87259d tda827x_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda8290 0xa7caa5e9 tda829x_probe +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda8290 0xc66b0621 tda829x_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda9887 0x97ac800f tda9887_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5761 0x90748d1e tea5761_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5761 0xd44c4b97 tea5761_autodetection +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5767 0x41fc50f6 tea5767_autodetection +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5767 0xeba52535 tea5767_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tuner-simple 0xfa83d290 simple_tuner_attach +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x49ce277e ttpci_budget_init +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x71b696c9 ttpci_budget_set_video_port +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x7948c222 budget_debug +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x910c1b3d ttpci_budget_debiwrite +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xc27d81eb ttpci_budget_irq10_handler +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xc8a5ba63 ttpci_budget_debiread +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xd06abfc6 ttpci_budget_deinit +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xf1f2ab29 ttpci_budget_init_hooks +EXPORT_SYMBOL_GPL drivers/media/video/compat_ioctl32 0x7dd192b2 v4l_compat_ioctl32 +EXPORT_SYMBOL_GPL drivers/media/video/cx88/cx88xx 0xe3349e98 cx88_setup_xc3028 +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x30f66c73 em28xx_audio_analog_set +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x7fc8652c em28xx_tuner_callback +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x912d396e em28xx_set_mode +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0xa5c12520 em28xx_uninit_isoc +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0xf14e9917 em28xx_init_isoc +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x4da88413 saa7134_g_ctrl_internal +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x683ea5e9 saa7134_s_ctrl_internal +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x7d6b2546 saa7134_ts_qops +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0xd2c00a07 saa7134_s_std_internal +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0xd8fc95f7 saa7134_i2c_call_saa6752 +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0xf1d5a073 saa7134_queryctrl +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xa5228b24 v4l2_int_device_try_attach_all +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xd21fd8c8 v4l2_int_ioctl_1 +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xe81d11f2 v4l2_int_device_register +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xf0ab7a91 v4l2_int_device_unregister +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xfb0d9985 v4l2_int_ioctl_0 +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x0ce36380 videobuf_alloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x1cc8b3b8 videobuf_poll_stream +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x2c7af86d videobuf_stop +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x3195733e videobuf_read_one +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x3fdc0069 videobuf_querybuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x4487b016 videobuf_mmap_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x47006727 videobuf_queue_cancel +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x4907add5 videobuf_qbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x5d8bd94a videobuf_dqbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x71af6a86 videobuf_queue_to_vmalloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x750dc2fb __videobuf_mmap_setup +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x912f06ec videobuf_waiton +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xa68e2009 videobuf_queue_is_busy +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xa6c601b7 videobuf_cgmbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xa97a6992 videobuf_mmap_mapper +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xc11c3bd4 videobuf_read_start +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xc35b5085 videobuf_reqbufs +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xc8e76031 videobuf_mmap_setup +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xda744963 videobuf_next_field +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xdb7a97ed videobuf_iolock +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xdc754901 videobuf_read_stop +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xe276c7ad videobuf_streamon +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xf4c2d29c videobuf_read_stream +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xf74be1b7 videobuf_queue_core_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xfb756611 videobuf_streamoff +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-contig 0x90447803 videobuf_to_dma_contig +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-contig 0xd0294f52 videobuf_dma_contig_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-contig 0xe192d782 videobuf_queue_dma_contig_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x15798be9 videobuf_queue_sg_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x3956de84 videobuf_dma_unmap +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x5df0fcf4 videobuf_dma_init_user +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x74462913 videobuf_sg_dma_map +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x7fd5e7e2 videobuf_sg_dma_unmap +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x933dfb43 videobuf_vmalloc_to_sg +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x95be35cc videobuf_to_dma +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xa38faed2 videobuf_sg_alloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xaf2168f1 videobuf_dma_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xb051e879 videobuf_dma_init_overlay +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xb7fdbd03 videobuf_dma_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xbe1b616b videobuf_dma_sync +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xcd41b440 videobuf_dma_map +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xd8922c8f videobuf_dma_init_kernel +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0x1b3530c3 videobuf_queue_vmalloc_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0x76731887 videobuf_to_vmalloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0xf3b77cf4 videobuf_vmalloc_free +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x1fc93f38 i2o_dma_map_single +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x427f9239 i2o_dma_free +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x7449fa91 i2o_pool_free +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x8bfd28aa i2o_sg_tablesize +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x8fd3ef7d i2o_pool_alloc +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xa408630a i2o_dma_map_sg +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xdecd4ca1 i2o_dma_realloc +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xf60f392d i2o_dma_alloc +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x06f05eb4 sm501_modify_reg +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x8e5fac2d sm501_find_clock +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x9910feb0 sm501_misc_control +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0xce530659 sm501_unit_power +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0xdd5a466e sm501_set_clock +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x04946744 wm8350_free_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x11913bbe wm8350_unmask_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x15ae2a89 wm8350_gpio_config +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x286fbf63 wm8350_block_write +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x37cefab6 wm8350_reg_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x43638f6d wm8350_clear_bits +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x4eeb1f0e wm8350_mask_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x5cdc306c wm8350_reg_unlock +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x5d5bca21 wm8350_device_init +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x8c8478d8 wm8350_set_bits +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xab760b4c wm8350_block_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xc3683c7d wm8350_reg_write +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xd1a31cbf wm8350_register_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xd2978a19 wm8350_reg_lock +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xf0bc714f wm8350_device_exit +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x0babf20d wm8400_reset_codec_reg_cache +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x87526730 wm8400_block_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x8fe53b39 wm8400_set_bits +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0xc04a2ca1 wm8400_reg_read +EXPORT_SYMBOL_GPL drivers/misc/eeprom_93cx6 0x2df115d4 eeprom_93cx6_multiread +EXPORT_SYMBOL_GPL drivers/misc/eeprom_93cx6 0x63d14d2f eeprom_93cx6_read +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x0777a7bb enclosure_remove_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x38a18ea8 enclosure_for_each_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x8978690d enclosure_find +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x90f9a7df enclosure_component_register +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x98210099 enclosure_unregister +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0xd369abf2 enclosure_add_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0xdd30a8a6 enclosure_register +EXPORT_SYMBOL_GPL drivers/misc/sgi-gru/gru 0x2293c8e0 gru_get_next_message +EXPORT_SYMBOL_GPL drivers/misc/sgi-gru/gru 0x5927a880 gru_send_message_gpa +EXPORT_SYMBOL_GPL drivers/misc/sgi-gru/gru 0x7e83f3fc gru_free_message +EXPORT_SYMBOL_GPL drivers/misc/sgi-gru/gru 0x81b3b8e3 gru_create_message_queue +EXPORT_SYMBOL_GPL drivers/misc/sgi-gru/gru 0x9c7283a1 gru_copy_gpa +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x345c9217 xpc_disconnect +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x39046c7a xpc_clear_interface +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x43a01eea xpc_registrations +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x6285dfe8 xp_cpu_to_nasid +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x64ba5017 xp_pa +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x76e36d39 xp_region_size +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x9823adb0 xpc_set_interface +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x9acd8cf8 xpc_interface +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0xba3694f3 xp_remote_memcpy +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0xead4f7fe xp_max_npartitions +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0xf3b47f67 xp_partition_id +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0xfe709b6c xpc_connect +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x00c30503 sdhci_resume_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x1f75831f sdhci_free_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x21b53e2c sdhci_alloc_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x39cb80ea sdhci_add_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x82033960 sdhci_remove_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0xa19cf51e sdhci_suspend_host +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0x3af54703 cfi_cmdset_0200 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0x51fc85d2 cfi_cmdset_0003 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0xc8b8fc5e cfi_cmdset_0001 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0002 0x1d5eb914 cfi_cmdset_0002 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0020 0x608d4bea cfi_cmdset_0020 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0x554e8f9a cfi_qry_present +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0x773f7934 cfi_qry_mode_off +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0xe82b3be3 cfi_qry_mode_on +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2000 0x21566cea DoC2k_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2001 0x704103a1 DoCMil_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2001plus 0x7209b2a0 DoCMilPlus_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/docecc 0x45937659 doc_decode_ecc +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x05ef575e unregister_mtd_user +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x3c22bd4a get_mtd_device_nm +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x3d556e8e mtd_erase_callback +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x406d1f31 register_mtd_parser +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x436392b8 deregister_mtd_parser +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x76a4c646 get_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x7d4b0486 parse_mtd_partitions +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x982b23a9 get_sb_mtd +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xa11d9c0d del_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xac749edb add_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xb1a673a6 mtd_table +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xb9cb5109 register_mtd_user +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xc368afcf default_mtd_writev +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xe1890494 put_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xeff64be1 mtd_table_mutex +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xf53fbcaa kill_mtd_super +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0x09677e1d deregister_mtd_blktrans +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0x54fb56db register_mtd_blktrans +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0xb59d4bfb add_mtd_blktrans_dev +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0xcc81a2fb del_mtd_blktrans_dev +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x55eac26a nand_wait_ready +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x5d89e703 nand_release +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x7517ccec nand_scan_tail +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x805dac7c nand_scan +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x9f43afc2 nand_scan_ident +EXPORT_SYMBOL_GPL drivers/mtd/onenand/onenand 0x937825c9 onenand_release +EXPORT_SYMBOL_GPL drivers/mtd/onenand/onenand 0xb7e79a65 onenand_scan +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x0f2f471c ubi_leb_erase +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x16ca1f43 ubi_get_volume_info +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x2c92dd5f ubi_is_mapped +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x2e755c49 ubi_leb_change +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x42801d20 ubi_sync +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x61981acd ubi_open_volume +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x82b3c662 ubi_open_volume_nm +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xa58c68f8 ubi_leb_map +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xad1e1647 ubi_leb_unmap +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xb2820bd0 ubi_close_volume +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xbc505df4 ubi_get_device_info +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xcf89f6b3 ubi_leb_write +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xdbda372b ubi_leb_read +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0c34e52e mlx4_free_hwq_res +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0d1ffc23 mlx4_unregister_interface +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0d61c3a2 mlx4_buf_write_mtt +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0d84b31d mlx4_db_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x147bc971 mlx4_free_cmd_mailbox +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x2376c32b mlx4_register_mac +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x265975b8 mlx4_srq_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x2b1ef35d mlx4_cq_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x2c3f4f18 mlx4_srq_query +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x32f97ac5 mlx4_srq_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x33e15ee5 mlx4_qp_reserve_range +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x39b08a0d mlx4_CLOSE_PORT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x3e01c338 mlx4_INIT_PORT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x3e9f0f69 mlx4_buf_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x41ae37a7 mlx4_fmr_enable +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x4acf159c mlx4_alloc_cmd_mailbox +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5179ceb1 mlx4_fmr_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x530598b6 mlx4_qp_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x547a5a0d mlx4_write_mtt +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5492704c mlx4_multicast_detach +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x59198627 mlx4_qp_to_ready +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5b40ac08 mlx4_map_phys_fmr +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x65e2573f mlx4_fmr_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x6b3a6d90 mlx4_qp_modify +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x6c288f36 mlx4_mtt_init +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x6dfc6f95 mlx4_qp_remove +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x7176a3d3 mlx4_buf_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x76e49be9 mlx4_multicast_attach +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x781305fe mlx4_qp_release_range +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x78b636f1 mlx4_uar_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x853bc27f mlx4_SYNC_TPT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x95424208 mlx4_unregister_mac +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x9833505d mlx4_mr_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x9848e9fd mlx4_cq_modify +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x9cd1ec57 mlx4_mr_enable +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xa56f3812 mlx4_mtt_cleanup +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xa9bfc610 mlx4_qp_query +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xabd9402b mlx4_pd_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xbd11a45f mlx4_db_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xbf374bc0 mlx4_cq_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xbf96a560 mlx4_srq_arm +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xcb42adf5 mlx4_qp_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xe0b2dd4f __mlx4_cmd +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xe3cf82d0 mlx4_register_interface +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xea210cd4 mlx4_pd_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xea2224e0 mlx4_mr_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xece2073c mlx4_alloc_hwq_res +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf33437a8 mlx4_uar_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf5392392 mlx4_cq_resize +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf5487691 mlx4_mtt_addr +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf8a90d04 mlx4_unregister_vlan +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf9b4e7ca mlx4_fmr_unmap +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xff3487ea mlx4_register_vlan +EXPORT_SYMBOL_GPL drivers/net/usb/cdc_ether 0x0f627478 usbnet_cdc_unbind +EXPORT_SYMBOL_GPL drivers/net/usb/cdc_ether 0xf64d7018 usbnet_generic_cdc_bind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x450af3a5 generic_rndis_bind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x716b91e6 rndis_tx_fixup +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x8cd63312 rndis_rx_fixup +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xd3d901f8 rndis_status +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xf4216732 rndis_unbind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xff80166d rndis_command +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x05e7c13f usbnet_resume +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x066de199 usbnet_set_settings +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x10dbf2e4 usbnet_get_msglevel +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x356792b4 usbnet_unlink_rx_urbs +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x3c2e2ce6 usbnet_set_msglevel +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x4b8daa96 usbnet_disconnect +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x6dfb02a6 usbnet_get_settings +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x6f990d04 usbnet_skb_return +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x9c03e41d usbnet_get_link +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xa57c9f9b usbnet_get_endpoints +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xab153645 usbnet_nway_reset +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xadd952b0 usbnet_defer_kevent +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xd3c57937 usbnet_probe +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xe3a52d6f usbnet_suspend +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xe7136e99 usbnet_get_drvinfo +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x0869889a lbs_stop_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x25b2019b lbs_send_tx_feedback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x2a27bc90 lbs_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x568bad1b lbs_queue_event +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x5cd4b362 lbs_host_sleep_cfg +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x5ec0c8ba lbs_cmd_copyback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x61713e89 lbs_host_to_card_done +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x6425c3d7 __lbs_cmd +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x85f9cd48 lbs_remove_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xd62c1fde lbs_process_rxed_packet +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xdf839a1a lbs_start_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xe0aec75c lbs_notify_command_response +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xe740f199 lbs_cmd_802_11_rate_adapt_rateset +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xf64277de lbs_debug +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xfa5bdf97 lbs_add_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xfd6bd1c0 lbs_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x1830dd6e lbtf_send_tx_feedback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x7196c8bc lbtf_cmd_response_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x7756d322 lbtf_remove_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x830d5575 lbtf_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x8e77ea35 __lbtf_cmd +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xc5851f81 lbtf_cmd_copyback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xce96edb3 lbtf_bcn_sent +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xd3e10e87 lbtf_add_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf_usb 0x951ac8e2 if_usb_reset_device +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf_usb 0xc7bdceac if_usb_prog_firmware +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x0608ce5b p54_parse_firmware +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x1b80d4de p54_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x856a1020 p54_read_eeprom +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0xd2baa4f5 p54_free_common +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0xf6e1cb76 p54_init_common +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x245fbbc9 rt2x00mac_get_tx_stats +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x269d7eba rt2x00mac_add_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x2e456f45 rt2x00mac_set_key +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x3da12eac rt2x00mac_start +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x43426a85 rt2x00lib_txdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x4f3c4783 rt2x00mac_bss_info_changed +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x69e4a2c6 rt2x00lib_remove_dev +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x83cac156 rt2x00lib_probe_dev +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x8cd8f86b rt2x00lib_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x91a71026 rt2x00lib_rxdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x92f1eeb2 rt2x00mac_config_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x93afdb7f rt2x00lib_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x9829af98 rt2x00mac_remove_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x9a173688 rt2x00mac_tx +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x9bbdefd2 rt2x00queue_get_entry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xae873b28 rt2x00mac_conf_tx +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xbd2ccd5a rt2x00mac_stop +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xd4423900 rt2x00lib_beacondone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xd4e7e4f3 rt2x00mac_configure_filter +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xd546885b rt2x00mac_get_stats +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xe48789fd rt2x00queue_get_queue +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xe58c01fa rt2x00mac_config +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xfd81ddbc rt2x00queue_map_txskb +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x09f0e24a rt2x00pci_uninitialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x0f690294 rt2x00pci_initialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x2e43ec92 rt2x00pci_probe +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x42db1868 rt2x00pci_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x496be573 rt2x00pci_remove +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0xc412962e rt2x00pci_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0xd045f3b3 rt2x00pci_rxdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0xe7dd4163 rt2x00pci_write_tx_data +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x1e12c487 rt2x00usb_disconnect +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x2f53a3bd rt2x00usb_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x34d83380 rt2x00usb_probe +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x4b89b147 rt2x00usb_write_tx_data +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x55bddad1 rt2x00usb_disable_radio +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x60faca66 rt2x00usb_vendor_request +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x61508676 rt2x00usb_vendor_req_buff_lock +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x9562c0df rt2x00usb_vendor_request_buff +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x9740512a rt2x00usb_init_txentry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xa1135a5d rt2x00usb_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xae0e7487 rt2x00usb_kick_tx_queue +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xb840fa0d rt2x00usb_uninitialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xc267b938 rt2x00usb_init_rxentry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xf54d3a21 rt2x00usb_initialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xfd723143 rt2x00usb_vendor_request_large_buff +EXPORT_SYMBOL_GPL drivers/pci/hotplug/acpiphp 0x262d2fee acpiphp_unregister_attention +EXPORT_SYMBOL_GPL drivers/pci/hotplug/acpiphp 0x9337f4a2 acpiphp_register_attention +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0x9b07ce90 wm8350_ldo_set_slot +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0xb00b1e3b wm8350_isink_set_flash +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0xbc05f8d1 wm8350_dcdc25_set_mode +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0xcdd96120 wm8350_register_regulator +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0xf2922bba wm8350_dcdc_set_slot +EXPORT_SYMBOL_GPL drivers/regulator/wm8400-regulator 0xe326dfe8 wm8400_register_regulator +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x01dc6456 iscsi_host_remove +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x0233f349 iscsi_pool_init +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x0260d772 iscsi_requeue_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x05403470 iscsi_eh_abort +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x08c1608f iscsi_set_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x0c0b0ee2 __iscsi_get_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x0dc0c54f iscsi_change_queue_depth +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x16da38f6 iscsi_itt_to_ctask +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x341b7667 iscsi_host_set_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x3e3e217b iscsi_host_free +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x41ba1d14 iscsi_pool_free +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x58e333e2 iscsi_host_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x5e55c69c iscsi_session_setup +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x6a868a5a __iscsi_complete_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x6e61bb51 iscsi_session_failure +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x6f08acb1 iscsi_conn_setup +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x71cb60d2 iscsi_conn_start +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x77042bb7 iscsi_put_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x7bc40054 iscsi_conn_send_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x7cdd6b48 iscsi_eh_target_reset +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x876ed3e7 iscsi_session_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x8c6fe2fc iscsi_host_add +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x8e37c3b2 iscsi_prep_unsolicit_data_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xa29cd46c iscsi_host_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xa3e0521c iscsi_conn_bind +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xa43ea67a iscsi_conn_teardown +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xa50f9edb iscsi_queuecommand +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xa7c32a58 iscsi_session_recovery_timedout +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xb47fe326 iscsi_conn_stop +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xb75c17e6 iscsi_update_cmdsn +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xcca7edb9 iscsi_conn_failure +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xcce86fa9 iscsi_conn_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xcf95fc89 iscsi_verify_itt +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xd4930c0c iscsi_session_teardown +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xd59fe937 iscsi_complete_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xde9317e9 iscsi_eh_device_reset +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xe35b3921 iscsi_suspend_tx +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x006848e4 sas_register_ha +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x1e9c44b4 sas_bios_param +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x295ae607 sas_ioctl +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x2bef2cfb sas_request_addr +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x3cea6700 sas_target_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x44ee3cb4 sas_ssp_task_response +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x533bb75b sas_domain_attach_transport +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x5e39cfe5 sas_task_abort +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x80e70c69 sas_change_queue_depth +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x819b0bbb sas_unregister_ha +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x861ef2ff sas_slave_destroy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x8fdf5c88 sas_phy_reset +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x993548a5 sas_eh_device_reset_handler +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x9dac9ccb sas_eh_bus_reset_handler +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xbe576603 sas_phy_enable +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xc38ced64 sas_target_destroy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xd16fca1e sas_change_queue_type +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xd5264683 __sas_task_abort +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xdb8da37e sas_slave_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xe818edfa sas_queuecommand +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xee03c6fb sas_domain_release_transport +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xf3741952 sas_slave_configure +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xf9183816 sas_find_local_phy +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x38c0280d srp_cmd_queue +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x6eaf618c srp_target_free +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x8241014f srp_transfer_data +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x849fe831 srp_iu_get +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0xf0de1473 srp_target_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0xffab22e1 srp_iu_put +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x03b81ab4 scsi_tgt_tsk_mgmt_request +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x090af767 scsi_tgt_it_nexus_destroy +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x28d47b8a scsi_tgt_it_nexus_create +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x343945ca scsi_tgt_queue_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x45e0ded4 scsi_tgt_cmd_to_host +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x4902b246 scsi_host_put_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x49c377b8 scsi_tgt_free_queue +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x9380483d scsi_tgt_alloc_queue +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xa3d871e3 scsi_host_get_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x0556abbe iscsi_conn_error_event +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x0fe8953c iscsi_destroy_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x266d2ed6 iscsi_scan_finished +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x27be0dc0 iscsi_create_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x421dea6a iscsi_host_for_each_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x42a0ad84 iscsi_block_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x514e85ec iscsi_unblock_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x59b89ce7 iscsi_create_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x5ef9259d iscsi_session_chkready +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x626b6398 iscsi_destroy_conn +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x7431087a iscsi_register_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x78377ca4 iscsi_create_conn +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x799d6646 iscsi_recv_pdu +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x8353cc8b iscsi_free_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x98a6f9e5 iscsi_unregister_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xa44ea02c iscsi_destroy_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xa7a6fc8e iscsi_lookup_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xd42ba398 iscsi_alloc_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xd857a9b0 iscsi_remove_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xfb7da240 iscsi_session_event +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xfc9efde0 iscsi_add_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0x0ef06974 spi_populate_ppr_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0xa0c71dac spi_populate_sync_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0xcffa2aff spi_populate_width_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x55244fdf srp_remove_host +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x8385f679 srp_rport_del +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0xa2b8a117 srp_attach_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0xb275de97 srp_release_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0xc81a00a5 srp_rport_add +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x0e18d348 spi_bitbang_start +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x1343f41f spi_bitbang_setup +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x327aefee spi_bitbang_cleanup +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x8367cf31 spi_bitbang_setup_transfer +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x9fdd8396 spi_bitbang_stop +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0xcc058868 spi_bitbang_transfer +EXPORT_SYMBOL_GPL drivers/uio/uio 0x689ca9a7 uio_event_notify +EXPORT_SYMBOL_GPL drivers/uio/uio 0xc2d06c4d uio_unregister_device +EXPORT_SYMBOL_GPL drivers/uio/uio 0xeeef4f86 __uio_register_device +EXPORT_SYMBOL_GPL drivers/usb/atm/usbatm 0x46c935f0 usbatm_usb_probe +EXPORT_SYMBOL_GPL drivers/usb/atm/usbatm 0x8a30fb7b usbatm_usb_disconnect +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x0fbdd77b usb_ftdi_elan_read_pcimem +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x393870b5 usb_ftdi_elan_edset_empty +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x6a5b7f9e usb_ftdi_elan_write_pcimem +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x71539aae ftdi_elan_gone_away +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x73e1201e usb_ftdi_elan_edset_output +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x894a57ef usb_ftdi_elan_edset_input +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xa2e703e5 usb_ftdi_elan_edset_flush +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xfebbbd69 usb_ftdi_elan_edset_single +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xff9645fe usb_ftdi_elan_edset_setup +EXPORT_SYMBOL_GPL drivers/usb/misc/phidget 0x11443006 phidget_class +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x0a09810e wa_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x122f15ac wa_urb_enqueue_run +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x668f3c90 wa_urb_enqueue +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x7bb38a51 rpipe_ep_disable +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xb7481e77 __wa_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xcb55ad58 rpipe_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xccc901c6 wa_urb_dequeue +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x0bb6bf5e wusb_cluster_id_get +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x14301ad1 wusbhc_rh_start_port_reset +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x18791193 wusbhc_giveback_urb +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x1c3b8c66 wusbhc_handle_dn +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x3e6007bc wusbhc_rh_resume +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x48535cf7 __wusb_dev_get_by_usb_dev +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x57d38b84 wusbhc_chid_set +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x5f2a4188 wusbhc_mmcie_rm +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x5f7f208a wusbhc_mmcie_set +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x5fec1e8e wusbhc_stop +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x607c2f60 wusbhc_rh_status_data +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x764dae51 wusbhc_reset_all +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x7f0b7631 wusb_dev_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xb725d128 wusb_cluster_id_put +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xbed6ff81 wusbhc_b_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xc7e2f835 wusbhc_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xcefc1a47 wusbhc_rh_control +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xf1c2d078 wusbhc_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xf770a6b4 wusbd +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xf7a3def5 wusbhc_b_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xfd145b0b wusbhc_rh_suspend +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xfe2e17d7 wusb_et_name +EXPORT_SYMBOL_GPL drivers/uwb/i1480/dfu/i1480-dfu-usb 0x89353975 i1480_fw_upload +EXPORT_SYMBOL_GPL drivers/uwb/i1480/dfu/i1480-dfu-usb 0xb5d3791c i1480_rceb_check +EXPORT_SYMBOL_GPL drivers/uwb/i1480/dfu/i1480-dfu-usb 0xbe1e6d10 i1480_cmd +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x184ae104 uwb_ack_policy_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x4fea41b0 uwb_phy_rate_show +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x629af4ac uwb_ack_policy_show +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x6b78ce6b uwb_rts_cts_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x7e37e9d8 uwb_phy_rate_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0xa6074e56 uwb_pca_base_priority_show +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0xde1a063c uwb_pca_base_priority_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0xfdf789d7 uwb_rts_cts_show +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x44501c9e umc_device_register +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x55212a1f umc_device_unregister +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x9c38507d umc_match_pci_id +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x9cce3f63 umc_driver_unregister +EXPORT_SYMBOL_GPL drivers/uwb/umc 0xaeadc5b7 umc_bus_type +EXPORT_SYMBOL_GPL drivers/uwb/umc 0xbae3dba9 umc_controller_reset +EXPORT_SYMBOL_GPL drivers/uwb/umc 0xf1ac24d2 __umc_driver_register +EXPORT_SYMBOL_GPL drivers/uwb/umc 0xfe831d27 umc_device_create +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x0ccb5b3a uwb_rc_vcmd +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x1d5cc8d3 uwb_bg_joined +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x1fe101ba uwb_rc_mac_addr_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x22a6d823 uwb_rc_cmd_async +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x262dbf90 uwb_est_find_size +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x2ca10493 uwb_rsv_create +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4288ed9d uwb_rc_rm +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x45f41cb0 uwb_rc_ie_rm +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x487aa8e0 uwb_rc_neh_error +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4a65b2ee uwb_pal_init +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4c1c4dea uwb_rc_reset_all +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4d57ae3c uwb_rsv_type_str +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4d7ef33c uwb_rc_add +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x5a1a5f78 uwb_rsv_terminate +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x5b4c9452 uwb_rc_get_by_dev +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x6625c91d dump_bytes +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x6b9377c5 uwb_ie_next +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x6c520475 uwb_rsv_accept +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7367dfcc uwb_rsv_modify +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7613c0e2 uwb_rsv_state_str +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x80e5fccc uwb_rc_ie_add +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x85b780e3 uwb_pal_unregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x85de05ea uwb_ie_for_each +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x8cb42db6 __uwb_addr_print +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x8e2d74dc uwb_notifs_deregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x8fde6d5a uwb_rsv_establish +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x9024117b uwb_notifs_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x9058988e uwb_dev_try_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa1a00900 uwb_rc_init +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa4f8bc8c uwb_ie_dump_hex +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xaaf6cdc5 uwb_rsv_destroy +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xb4a066c1 uwb_rc_alloc +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xb7c8c825 uwb_rc_cmd +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xbf6a1b3d uwb_rc_get_ie +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xc348d995 uwb_pal_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xd3fcb9ba uwb_rc_put +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xdc71b8e0 uwb_rc_dev_addr_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xdf769559 uwb_rc_get_by_grandpa +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe6077cba uwb_rc_neh_grok +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xeb4cab9a uwb_est_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xefddc9f6 uwb_dev_for_each +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xf7ca313a uwb_est_unregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xfd6df965 __uwb_rc_try_get +EXPORT_SYMBOL_GPL drivers/uwb/whci 0xf52983e0 whci_wait_for +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x1e2d0c54 wlp_wss_activate_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x21084b65 wlp_dev_manufacturer_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x2b831457 wlp_setup +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x31e5d7aa wlp_dev_serial_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x3391dfe3 wlp_wss_setup +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x37b0f845 wlp_wss_activate_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x3c6694bb wlp_dev_name_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x456ddf13 wlp_dev_model_nr_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x4622e57e wlp_uuid_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x463db906 wlp_reset_all +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x4e37d99d wlp_uuid_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x4eba6030 wlp_eda_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x51c027fd wlp_dev_model_nr_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x51e568ed wlp_dev_prim_OUI_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x54d51db2 wlp_dev_name_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x646086cc wlp_dev_serial_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x682408ec wlp_wss_remove +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x6d162f73 wlp_prepare_tx_frame +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x72eaf9e2 wlp_dev_prim_category_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x74fe4fd8 wlp_dev_prim_OUI_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x766a54c7 wlp_dev_prim_subcat_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x7ea9242b wlp_neighborhood_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x83cbe4f3 wlp_dev_prim_subcat_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x8b11c01f wlp_dev_prim_OUI_sub_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x9a019108 wlp_dev_prim_OUI_sub_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xa19777ed wlp_receive_frame +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xa90e2058 wlp_remove +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xc471e812 wlp_eda_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xcd713803 wlp_dev_model_name_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xcde35b91 wlp_dev_model_name_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xd040056b wlp_dev_prim_category_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xfd0e1141 wlp_dev_manufacturer_show +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x0ecda790 ili9320_suspend +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x189f512a ili9320_shutdown +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x1cdcedaa ili9320_resume +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x3a8cfebc ili9320_write_regs +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x3c65e516 ili9320_write +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0xe00410c5 ili9320_probe_spi +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0xe1132254 ili9320_remove +EXPORT_SYMBOL_GPL drivers/video/fb_ddc 0x3f5d05fe fb_ddc_read +EXPORT_SYMBOL_GPL drivers/video/fb_sys_fops 0x30eaeb84 fb_sys_write +EXPORT_SYMBOL_GPL drivers/video/fb_sys_fops 0x39bb34e9 fb_sys_read +EXPORT_SYMBOL_GPL drivers/video/sis/sisfb 0x5bdf8447 sis_free_new +EXPORT_SYMBOL_GPL drivers/video/sis/sisfb 0x6ce9fa59 sis_malloc_new +EXPORT_SYMBOL_GPL drivers/video/vermilion/vmlfb 0x016e6c20 vmlfb_unregister_subsys +EXPORT_SYMBOL_GPL drivers/video/vermilion/vmlfb 0x90c018c6 vmlfb_register_subsys +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x1bf1bae0 virtio_check_driver_offered_feature +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x36c04a91 register_virtio_device +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x7176ad10 unregister_virtio_driver +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x74c0608e register_virtio_driver +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0xfcdd6498 unregister_virtio_device +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x03c4687d vring_interrupt +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x4f924c62 vring_del_virtqueue +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x67d130a2 vring_transport_features +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x7274b59b vring_new_virtqueue +EXPORT_SYMBOL_GPL drivers/w1/wire 0x0472e1dc w1_reset_bus +EXPORT_SYMBOL_GPL drivers/w1/wire 0x3c93f792 w1_write_block +EXPORT_SYMBOL_GPL drivers/w1/wire 0x5e2d88f7 w1_write_8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0x7c2f2afb w1_calc_crc8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0x90a52159 w1_read_block +EXPORT_SYMBOL_GPL drivers/w1/wire 0x9f1117d5 w1_read_8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0xdba68dd7 w1_reset_select_slave +EXPORT_SYMBOL_GPL drivers/w1/wire 0xddb5bcb3 w1_next_pullup +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x9321df95 dlm_lock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xac959fb6 dlm_posix_lock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xcf9f3328 dlm_release_lockspace +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xdc583c08 dlm_unlock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xdf3c14de dlm_new_lockspace +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xe8bb8f15 dlm_posix_unlock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xeb3985a3 dlm_posix_get +EXPORT_SYMBOL_GPL fs/exportfs/exportfs 0x0266d6d3 exportfs_encode_fh +EXPORT_SYMBOL_GPL fs/exportfs/exportfs 0xf12a8826 exportfs_decode_fh +EXPORT_SYMBOL_GPL fs/fat/fat 0x0136ffef fat_search_long +EXPORT_SYMBOL_GPL fs/fat/fat 0x02724089 fat_getattr +EXPORT_SYMBOL_GPL fs/fat/fat 0x0e018f20 fat_flush_inodes +EXPORT_SYMBOL_GPL fs/fat/fat 0x20779f0f fat_get_dotdot_entry +EXPORT_SYMBOL_GPL fs/fat/fat 0x2ad961cb fat_free_clusters +EXPORT_SYMBOL_GPL fs/fat/fat 0x5882a717 fat_scan +EXPORT_SYMBOL_GPL fs/fat/fat 0x6d832825 fat_time_unix2fat +EXPORT_SYMBOL_GPL fs/fat/fat 0x815779cb fat_detach +EXPORT_SYMBOL_GPL fs/fat/fat 0x888bf742 fat_alloc_new_dir +EXPORT_SYMBOL_GPL fs/fat/fat 0x8a16e2e6 fat_fill_super +EXPORT_SYMBOL_GPL fs/fat/fat 0x92c12179 fat_remove_entries +EXPORT_SYMBOL_GPL fs/fat/fat 0x9307fc43 fat_fs_panic +EXPORT_SYMBOL_GPL fs/fat/fat 0x933e5c5a fat_attach +EXPORT_SYMBOL_GPL fs/fat/fat 0xbe3feb62 fat_add_entries +EXPORT_SYMBOL_GPL fs/fat/fat 0xc26b821d fat_dir_empty +EXPORT_SYMBOL_GPL fs/fat/fat 0xed37a4f9 fat_build_inode +EXPORT_SYMBOL_GPL fs/fat/fat 0xfaff4cd9 fat_sync_inode +EXPORT_SYMBOL_GPL fs/fat/fat 0xfb89844d fat_setattr +EXPORT_SYMBOL_GPL fs/gfs2/gfs2 0x3f3c16bf gfs2_unregister_lockproto +EXPORT_SYMBOL_GPL fs/gfs2/gfs2 0x4a8c63a9 gfs2_register_lockproto +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x17ce645d locks_end_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x1a618932 nlmsvc_unlock_all_by_ip +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x2371b1df nlmclnt_proc +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x254e410a nlmclnt_done +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x6f959b35 locks_in_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x9080d4b5 nlmclnt_init +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x96877ac4 locks_start_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0xa5c4eea0 nlmsvc_unlock_all_by_sb +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x15d2bc28 o2nm_get_node_by_num +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x1b89c6ee o2hb_fill_node_map +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x1d747ce3 o2hb_check_node_heartbeating +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x36418553 o2net_send_message +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x3afe3972 o2hb_register_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x3b2a9a0a o2hb_setup_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x4900035b o2hb_stop_all_regions +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x521e0726 o2net_send_message_vec +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x6854fed3 o2hb_unregister_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x80e8842a o2nm_node_put +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x81a17396 mlog_and_bits +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x8f0355cf o2nm_node_get +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x9e312427 o2nm_get_node_by_ip +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xa82a8645 o2nm_this_node +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xa87bc9e7 o2nm_configured_node_map +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xae808bac o2net_register_handler +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xbaeb4700 o2hb_check_node_heartbeating_from_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xd60f2c6c o2hb_check_local_node_heartbeating +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xf1a5611d o2net_unregister_handler_list +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xf56c2017 mlog_not_bits +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x026be456 dlm_register_domain +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x7a1211f8 dlm_setup_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x92ba250c dlmunlock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x97676965 dlm_register_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xcbc0b1f5 dlm_print_one_lock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xcd561950 dlmlock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xd7ba575e dlm_errmsg +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xd8fa57a6 dlm_unregister_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xec4a224b dlm_unregister_domain +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xfb86b96f dlm_errname +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x0562c415 ocfs2_cluster_this_node +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x0e27f909 ocfs2_dlm_lock +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x21db5b88 ocfs2_cluster_disconnect +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x390ef9ae ocfs2_stack_glue_register +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x4a1f6fe9 ocfs2_cluster_connect +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x4d3af7fa ocfs2_cluster_hangup +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x81c85a68 ocfs2_dlm_lock_status +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x91fab465 ocfs2_dlm_lvb +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x963932a3 ocfs2_stack_glue_set_locking_protocol +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xa7d5c1c0 ocfs2_dlm_unlock +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xad9bfc8d ocfs2_plock +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xbbc4ef97 ocfs2_stack_supports_plocks +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xd066711e ocfs2_dlm_dump_lksb +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xf7ad83ed ocfs2_stack_glue_unregister +EXPORT_SYMBOL_GPL lib/lzo/lzo_compress 0x2e1d43cf lzo1x_1_compress +EXPORT_SYMBOL_GPL lib/lzo/lzo_decompress 0x2a1538ca lzo1x_decompress_safe +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0x300d7e57 free_rs +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0x6fbb3bd9 init_rs_non_canonical +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0xabda1e2e decode_rs16 +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0xb050f329 init_rs +EXPORT_SYMBOL_GPL net/802/garp 0x1907f7f3 garp_request_leave +EXPORT_SYMBOL_GPL net/802/garp 0x39a7cae9 garp_uninit_applicant +EXPORT_SYMBOL_GPL net/802/garp 0x419c4b47 garp_request_join +EXPORT_SYMBOL_GPL net/802/garp 0x482d6edf garp_register_application +EXPORT_SYMBOL_GPL net/802/garp 0xb6d9aeac garp_unregister_application +EXPORT_SYMBOL_GPL net/802/garp 0xdbbdc05b garp_init_applicant +EXPORT_SYMBOL_GPL net/802/stp 0x1afd488c stp_proto_register +EXPORT_SYMBOL_GPL net/802/stp 0x541174cd stp_proto_unregister +EXPORT_SYMBOL_GPL net/ax25/ax25 0xa05d6568 ax25_register_pid +EXPORT_SYMBOL_GPL net/ax25/ax25 0xac93ae05 ax25_bcast +EXPORT_SYMBOL_GPL net/ax25/ax25 0xaeb7451e ax25_defaddr +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x09c5ed3c tfrc_tx_hist_purge +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x0a487ea5 tfrc_calc_x +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x106fe6d3 tfrc_tx_hist_rtt +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x15ea8043 tfrc_lh_update_i_mean +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x31b68851 tfrc_rx_hist_duplicate +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x356e87b1 tfrc_rx_hist_add_packet +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x69ec5731 tfrc_tx_hist_add +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x6c252d29 tfrc_calc_x_reverse_lookup +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x71afb660 tfrc_rx_handle_loss +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x72b3baaa tfrc_lh_interval_add +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x87d92541 tfrc_rx_hist_sample_rtt +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x902206f0 tfrc_lh_cleanup +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x92285650 tfrc_rx_hist_alloc +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xc612a5b6 tfrc_rx_hist_purge +EXPORT_SYMBOL_GPL net/dccp/dccp 0x10974018 dccp_insert_option_timestamp +EXPORT_SYMBOL_GPL net/dccp/dccp 0x14043931 ccid_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0x1637cb01 dccp_parse_options +EXPORT_SYMBOL_GPL net/dccp/dccp 0x16566c00 dccp_send_sync +EXPORT_SYMBOL_GPL net/dccp/dccp 0x1d99d49a dccp_timestamp +EXPORT_SYMBOL_GPL net/dccp/dccp 0x20c7dde8 dccp_hashinfo +EXPORT_SYMBOL_GPL net/dccp/dccp 0x28402e98 dccp_connect +EXPORT_SYMBOL_GPL net/dccp/dccp 0x2fec6c12 compat_dccp_setsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x37a4fa7c dccp_destroy_sock +EXPORT_SYMBOL_GPL net/dccp/dccp 0x3b3c0b1b dccp_feat_clean +EXPORT_SYMBOL_GPL net/dccp/dccp 0x43156bbd dccp_disconnect +EXPORT_SYMBOL_GPL net/dccp/dccp 0x494a5d53 dccp_check_req +EXPORT_SYMBOL_GPL net/dccp/dccp 0x495c66bb dccp_sendmsg +EXPORT_SYMBOL_GPL net/dccp/dccp 0x4998d38e ccid_hc_tx_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0x4cd7aacc dccp_poll +EXPORT_SYMBOL_GPL net/dccp/dccp 0x5693fbe8 dccp_close +EXPORT_SYMBOL_GPL net/dccp/dccp 0x56ea266a dccp_state_name +EXPORT_SYMBOL_GPL net/dccp/dccp 0x5bcb7dee dccp_sample_rtt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x5ccd4c15 dccp_feat_clone +EXPORT_SYMBOL_GPL net/dccp/dccp 0x6600112b dccp_setsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x688da138 dccp_child_process +EXPORT_SYMBOL_GPL net/dccp/dccp 0x6d33b26f ccid_hc_tx_delete +EXPORT_SYMBOL_GPL net/dccp/dccp 0x7028c505 dccp_feat_change_recv +EXPORT_SYMBOL_GPL net/dccp/dccp 0x7a4619d9 ccid_unregister +EXPORT_SYMBOL_GPL net/dccp/dccp 0x7b461540 dccp_feat_confirm_recv +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8503e110 dccp_create_openreq_child +EXPORT_SYMBOL_GPL net/dccp/dccp 0x86be7924 dccp_packet_name +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8a091a2d dccp_sync_mss +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8b7d8caf dccp_statistics +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8cc71d51 inet_dccp_listen +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8f3ecb0c dccp_getsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x90debbee dccp_set_state +EXPORT_SYMBOL_GPL net/dccp/dccp 0x9d6a3846 dccp_orphan_count +EXPORT_SYMBOL_GPL net/dccp/dccp 0xad61e86b dccp_insert_option +EXPORT_SYMBOL_GPL net/dccp/dccp 0xaf0e02db compat_dccp_getsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0xb091c29d dccp_death_row +EXPORT_SYMBOL_GPL net/dccp/dccp 0xb35ac20d dccp_ctl_make_reset +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbe4cf010 dccp_feat_init +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbf6b58ba dccp_feat_change +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbfb58e6e dccp_make_response +EXPORT_SYMBOL_GPL net/dccp/dccp 0xc27d1bb5 dccp_done +EXPORT_SYMBOL_GPL net/dccp/dccp 0xc3819a5d dccp_init_sock +EXPORT_SYMBOL_GPL net/dccp/dccp 0xd6ad6750 dccp_ioctl +EXPORT_SYMBOL_GPL net/dccp/dccp 0xd77f200e dccp_reqsk_init +EXPORT_SYMBOL_GPL net/dccp/dccp 0xdcaa3d66 ccid_hc_rx_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0xe23c4af4 dccp_shutdown +EXPORT_SYMBOL_GPL net/dccp/dccp 0xe86782c0 dccp_insert_option_elapsed_time +EXPORT_SYMBOL_GPL net/dccp/dccp 0xe97659fb dccp_send_ack +EXPORT_SYMBOL_GPL net/dccp/dccp 0xefed8c40 dccp_recvmsg +EXPORT_SYMBOL_GPL net/dccp/dccp 0xf382535a dccp_rcv_established +EXPORT_SYMBOL_GPL net/dccp/dccp 0xf40ae2b9 dccp_rcv_state_process +EXPORT_SYMBOL_GPL net/dccp/dccp 0xfa5b159a dccp_reqsk_send_ack +EXPORT_SYMBOL_GPL net/dccp/dccp 0xfd976ae1 ccid_hc_rx_delete +EXPORT_SYMBOL_GPL net/dccp/dccp 0xffc1aa07 ccid_register +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x5a2545c5 dccp_v4_request_recv_sock +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x72eba005 dccp_invalid_packet +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x7b5e5f62 dccp_v4_do_rcv +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0xac656af5 dccp_v4_send_check +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0xcb76e5cf dccp_v4_connect +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0xdc87d192 dccp_v4_conn_request +EXPORT_SYMBOL_GPL net/ieee80211/ieee80211 0x5fcca57a ieee80211_rx_any +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_conntrack_ipv4 0x6d40a921 need_ipv4_conntrack +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_conntrack_ipv4 0x9e345380 nf_nat_seq_adjust_hook +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_defrag_ipv4 0x6b6c3d10 nf_defrag_ipv4_enable +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x07ae60b6 nf_nat_proto_in_range +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x2ff913ca nf_nat_proto_put +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x36f80f48 nf_nat_icmp_reply_translation +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x59c3072f nf_nat_proto_unique_tuple +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x768ad038 nf_nat_packet +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x8fc7d688 nf_nat_proto_find_get +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x94a08134 nf_nat_proto_nlattr_to_range +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0xe8b2ed48 nf_nat_proto_range_to_nlattr +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat_proto_gre 0x636b12c8 nf_nat_need_gre +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x00c70b0c tcp_vegas_get_info +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x1507817f tcp_vegas_init +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x515ac83c tcp_vegas_cwnd_event +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x8a3d5a53 tcp_vegas_pkts_acked +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0xd1c0f3f3 tcp_vegas_state +EXPORT_SYMBOL_GPL net/mac80211/mac80211 0x1f4da46d ieee80211_iterate_active_interfaces_atomic +EXPORT_SYMBOL_GPL net/mac80211/mac80211 0x327fae20 ieee80211_iterate_active_interfaces +EXPORT_SYMBOL_GPL net/netfilter/ipvs/ip_vs 0xe6476b4a net_vs_ctl_path +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x03e6f688 nf_ct_l4proto_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x041013fd nf_conntrack_lock +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x045072cd nf_ct_port_nla_policy +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x1283d711 nf_ct_expect_unregister_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x15c10b0b nf_conntrack_unregister_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x16f36638 __nf_conntrack_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x21756e3d __nf_ct_kill_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x23b10ece nf_conntrack_alloc +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x24fde9a4 nf_ct_helper_ext_add +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x251f8acf nf_conntrack_tcp_update +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x28f7c555 nf_ct_get_tuplepr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x2bcc7114 seq_print_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3560f027 __nf_ct_expect_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x38630158 nf_conntrack_tuple_taken +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x38c9440b nf_ct_extend_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x39ea4343 nf_ct_unexpect_related +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3b5fde34 nf_ct_get_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3e41b53c nf_conntrack_l3proto_generic +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3f5b1415 nf_ct_port_nlattr_to_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x40387ccf __nf_ct_event_cache_init +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x4a94e585 nf_conntrack_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x4b5d5821 nf_ct_invert_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x4c9316c1 print_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x596a3590 __nf_ct_l4proto_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x60105d3e nf_conntrack_helper_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x68f1f18f nf_ct_expect_related +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x69669e24 nf_ct_unlink_expect +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x6e224a7a need_conntrack +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x70db8eb4 nf_ct_expect_init +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x71c92394 nf_conntrack_l3proto_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x72836f4a nf_conntrack_free +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x77aadb54 nf_conntrack_alter_reply +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x78bbf824 nf_ct_iterate_cleanup +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x78f9b710 nf_ct_l3proto_try_module_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x79ca2e53 nf_ct_expect_chain +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x80a3ee17 __nf_conntrack_helper_find_byname +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x81dd6ad8 nf_conntrack_l4proto_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x8341414f nf_ct_expect_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x8ffe7e89 nf_conntrack_htable_size +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x90ff6c9f nf_ct_invert_tuplepr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x92e72b76 nf_ct_l3proto_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x985888b9 nf_conntrack_l4proto_udp6 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa6f62ec0 nf_conntrack_set_hashsize +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa9083557 nf_conntrack_flush +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa99022d8 nf_ct_expect_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xaa6eea3b nf_conntrack_l4proto_udp4 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xaa74a0d1 nf_conntrack_l3proto_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xaf57e66f nf_ct_extend_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb320d303 nf_conntrack_in +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb4cd4bb2 __nf_ct_helper_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb602c57e nf_ct_l3proto_module_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xba619e5a nf_ct_l3proto_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbc887e16 nf_ct_expect_register_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbfad5f95 nf_conntrack_l4proto_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc044befe nf_ct_free_hashtable +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc18ac88d nf_ct_expect_hsize +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc1d36191 nf_conntrack_l4proto_tcp6 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc35a7a3e nf_conntrack_chain +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc7b64d79 nf_conntrack_hash_insert +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xcbf7fd2a nf_conntrack_register_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xcc81e5df nf_ct_l3protos +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd2a9ba10 nf_ct_port_tuple_to_nlattr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd50a96a2 nf_ct_alloc_hashtable +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd850f41b __nf_conntrack_confirm +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd9efb053 nf_ct_deliver_cached_events +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xdbbb77f3 nf_ct_expect_alloc +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xe6acae30 nf_conntrack_helper_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xed10d319 nf_ct_l4proto_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf3e50313 nf_conntrack_l4proto_tcp4 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf4d36579 __nf_ct_refresh_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf9ae81a1 nf_conntrack_max +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfa169dac nf_conntrack_untracked +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfb839673 nf_ct_remove_expectations +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xff9e9fc3 nfnetlink_parse_nat_setup_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_amanda 0x50c0c5e7 nf_nat_amanda_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_ftp 0x73278174 nf_nat_ftp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x25d58ef2 set_h225_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x264c0cf3 get_h225_addr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x384e1de8 nat_h245_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x4f2319d4 nat_rtp_rtcp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x96b1910d set_sig_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x98a7874e nat_callforwarding_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xb24a46ff set_h245_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xcafb4002 nat_q931_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xef8a1092 nat_t120_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xf3e163c1 set_ras_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_irc 0x436fd424 nf_nat_irc_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x0e1d2562 nf_nat_pptp_hook_exp_gre +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x65277d44 nf_nat_pptp_hook_expectfn +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0xce4daed2 nf_nat_pptp_hook_outbound +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0xfdb657f9 nf_nat_pptp_hook_inbound +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_proto_gre 0x05f8e58c nf_ct_gre_keymap_destroy +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_proto_gre 0x6f59d77c nf_ct_gre_keymap_add +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x13169b79 ct_sip_parse_request +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x23c04245 nf_nat_sip_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x2be122f2 nf_nat_sip_expect_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x3c2058a6 ct_sip_parse_numerical_param +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x5301a261 nf_nat_sdp_media_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x5333cb69 ct_sip_parse_header_uri +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x5343611e ct_sip_get_sdp_header +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x56ad8f6e ct_sip_parse_address_param +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x640dc776 nf_nat_sdp_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x99030709 nf_nat_sdp_session_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xc965cb05 nf_nat_sdp_port_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xf8b610ea ct_sip_get_header +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_tftp 0xb9dcc58a nf_nat_tftp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_tproxy_core 0xf19a8cf1 nf_tproxy_assign_sock +EXPORT_SYMBOL_GPL net/netfilter/nf_tproxy_core 0xf47d9002 nf_tproxy_get_sock_v4 +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x1f58e71b nfnl_lock +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x3895cd7a nfnl_unlock +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x48e4dbc5 nfnetlink_subsys_unregister +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x7ce8bf80 nfnetlink_subsys_register +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xa849b6f4 nfnetlink_send +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xeca95329 nfnetlink_has_listeners +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xefce3605 nfnetlink_unicast +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x161d1417 xt_compat_unlock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x19706b65 xt_proto_init +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x19eeb63e xt_compat_target_from_user +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x26e90a50 xt_request_find_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x40728a63 xt_find_revision +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x419232be xt_check_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x54b2c95b xt_check_match +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x57c6befb xt_table_unlock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x5d677a07 xt_compat_target_to_user +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x5f82f1f7 xt_compat_flush_offsets +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x684694c5 xt_compat_add_offset +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x6ab3db46 xt_register_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x6f66f520 xt_compat_match_offset +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x6f901533 xt_compat_match_to_user +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x6f9aa2fb xt_compat_calc_jump +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x70004e75 xt_proto_fini +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x72997956 xt_find_table_lock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x74bc21f9 xt_compat_match_from_user +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x9c0a97c8 xt_unregister_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xb32f3d92 xt_replace_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xdc90d2f4 xt_compat_target_offset +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xe0b4971b xt_compat_lock +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0xc177bee0 xt_rateest_put +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0xdb8418cc xt_rateest_lookup +EXPORT_SYMBOL_GPL net/rxrpc/af-rxrpc 0x621683e2 rxrpc_register_security +EXPORT_SYMBOL_GPL net/rxrpc/af-rxrpc 0xf1baf687 rxrpc_unregister_security +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x002ac26c xprt_update_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x01d98f83 xprt_register_transport +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x0a4db2dd xprt_release_xprt_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x113e21ea rpc_wake_up_next +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x14048ac2 xprt_wait_for_buffer_space +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x163c46fc xdr_skb_read_bits +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1670dc9b rpc_print_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x19a1d725 rpc_exit_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1c7437de xprt_release_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2069c8c1 svc_print_addr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2156d2ac rpc_shutdown_client +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x23f414a5 rpcb_getport_async +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x241244fd rpcauth_lookup_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x25901e9e svc_reg_xprt_class +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x28f7c105 svc_xprt_names +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2aa17774 rpc_free_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2e10bbe3 rpcauth_create +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x31a89d59 rpc_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x35a51449 svc_xprt_enqueue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x36644df1 rpc_peeraddr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3d1840c7 csum_partial_copy_to_xdr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3d9a2e05 svc_xprt_init +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3e517319 rpc_create +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3f66a753 rpcauth_unregister +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x402a5c3c xprt_disconnect_done +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x432fd9cd xprt_reserve_xprt_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x48a22506 rpc_force_rebind +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x49626223 svc_addsock +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x52c38aca xprt_release_rqst_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x52dfc220 rpcauth_register +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x53445f68 nlm_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x547b35e5 __rpc_wait_for_completion_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x54c5a5ed rpc_setbufsize +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x54f9fcb9 xprt_unregister_transport +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x550547a3 rpc_destroy_wait_queue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5bd26000 rpc_proc_unregister +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5c3bee35 rpc_killall_tasks +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5fceded6 xprt_wake_pending_tasks +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x68a230d8 xprt_complete_rqst +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6abc3aac rpc_lookup_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6bcab895 rpc_malloc +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6c5304c5 rpcb_getport_sync +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6cb98b9e rpc_call_start +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6e8e67f2 put_rpccred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7140304d xprt_write_space +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x77a52650 svc_max_payload +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x78c2d5a6 rpc_restart_call +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7c4378cf svc_xprt_copy_addrs +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7de53067 rpc_init_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7fec05c9 rpc_sleep_on +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8231b07b rpc_call_null +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x82601ccc rpc_call_sync +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x82ecc76d rpc_bind_new_program +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x847ca0f8 rpc_wake_up_queued_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x887f3ebf xprt_lookup_rqst +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8a5d3c5c rpcauth_init_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8ac504cb svc_xprt_received +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8c2f79c4 rpc_delay +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8c3a23e2 rpc_lookup_machine_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8d40819c xprt_reserve_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8f059ce2 xprt_set_retrans_timeout_def +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x91963df9 rpc_put_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x931a8c3a rpc_clone_client +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x9958edad xprt_adjust_cwnd +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xaa2e822d xdr_partial_copy_from_skb +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xac49b2cd svc_create_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xaf5bf6ef nfs_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb2af9ba6 svc_find_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb387b246 rpc_wake_up_status +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb4b21aaa rpcauth_destroy_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb59a9f44 rpcauth_generic_bind_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb6c99ad2 rpc_alloc_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb9cc8e73 svc_xprt_put +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbbfd23a7 rpc_max_payload +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbc6522e3 svc_close_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbf9d1b96 nfsd_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc12435e3 rpc_calc_rto +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xcb23e955 rpc_proc_register +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xcc34c30c rpc_run_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd82c728e rpc_init_wait_queue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe0791c55 xprt_set_retrans_timeout_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe264e665 rpc_call_async +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xedd1ba52 rpc_wake_up +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xeeacab69 rpc_update_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xf47cf370 svc_unreg_xprt_class +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xf97dcd0c rpcauth_init_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xf9d1164c rpc_free +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xfe7bd420 rpc_peeraddr2str +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0x66e88335 ipcomp_input +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0xa9d45aa6 ipcomp_destroy +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0xd0805fa8 ipcomp_output +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0xfb02881b ipcomp_init_state +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ad73311 0x1cb5c83b ad73311_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ad73311 0x845b2dc1 soc_codec_dev_ad73311 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ak4535 0x77471d3a soc_codec_dev_ak4535 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ak4535 0x838102d5 ak4535_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-cs4270 0x0d21b27a soc_codec_device_cs4270 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-cs4270 0x41d3c6b1 cs4270_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ssm2602 0x95f87230 soc_codec_dev_ssm2602 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ssm2602 0xaa151fac ssm2602_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic23 0x995b6318 tlv320aic23_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic23 0xc1734253 soc_codec_dev_tlv320aic23 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic26 0x8c28beee aic26_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic26 0xc53b26d1 aic26_soc_codec_dev +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0x13c1634a aic3x_headset_detected +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0x1980b6eb soc_codec_dev_aic3x +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0x1f0dde46 aic3x_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0xcf6335ac aic3x_set_gpio +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0xd66a4989 aic3x_get_gpio +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-uda1380 0x7adf09ad uda1380_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-uda1380 0xca77a054 soc_codec_dev_uda1380 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8510 0x1e139af9 soc_codec_dev_wm8510 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8510 0xe9ba0f94 wm8510_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8580 0x11c2a176 soc_codec_dev_wm8580 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8580 0xb4b1012b wm8580_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8731 0xae85b75d soc_codec_dev_wm8731 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8731 0xf75cca65 wm8731_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8750 0x5fd02cfa wm8750_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8750 0xb313faae soc_codec_dev_wm8750 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8753 0x983ea96d soc_codec_dev_wm8753 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8753 0xc64cf916 wm8753_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8900 0x1862116f wm8900_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8900 0x55074f76 soc_codec_dev_wm8900 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8903 0x7e2a1cb5 soc_codec_dev_wm8903 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8903 0x9ef663c1 wm8903_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8971 0x1699fc44 wm8971_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8971 0x495368b2 soc_codec_dev_wm8971 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8990 0x5ad674f9 soc_codec_dev_wm8990 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8990 0x8dfa54bc wm8990_dai +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x0d90fd92 snd_soc_info_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x174819d7 snd_soc_dai_set_sysclk +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x17a8e76e snd_soc_dapm_stream_event +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x1ae4e512 snd_soc_set_runtime_hwparams +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x1b695f20 snd_soc_info_enum_ext +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x1dfbeec0 snd_soc_get_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x255863f0 snd_soc_free_ac97_codec +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x34dbdc5a snd_soc_get_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x360be706 snd_soc_dapm_enable_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x39847c93 snd_soc_dapm_get_pin_status +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x3af51347 snd_soc_dai_set_tdm_slot +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x3c58273d snd_soc_new_ac97_codec +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x413b9922 snd_soc_put_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x414c6e01 snd_soc_dapm_nc_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x43b72d05 snd_soc_dapm_add_routes +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x50e5e9a2 snd_soc_dai_set_pll +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x54bc73da snd_soc_dapm_new_control +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x6300a7fc snd_soc_dapm_get_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x68f545e9 snd_soc_cnew +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x6a0ba3cb snd_soc_get_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x6a1d8e65 snd_soc_put_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x6c4d562d snd_soc_update_bits +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x6c7e1b37 snd_soc_info_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x6f9afb35 snd_soc_dapm_new_controls +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x76179d9f snd_soc_new_pcms +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x766999e5 snd_soc_info_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x78b36b96 snd_soc_dapm_free +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x7f2d6ef3 snd_soc_register_card +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x848f3528 snd_soc_info_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x8d15478b snd_soc_dapm_sync +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x901b121b snd_soc_get_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x902714ea snd_soc_dapm_put_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x992c10dd snd_soc_put_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xa24e5105 snd_soc_free_pcms +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xa3d11ce8 dapm_reg_event +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xa9dbbebc snd_soc_dai_digital_mute +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xb328fa1b snd_soc_dapm_put_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xb332d7b5 snd_soc_dai_set_fmt +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xb92c2e11 snd_soc_info_volsw_ext +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xc6c8bf63 snd_soc_dapm_get_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xd85d2ea1 snd_soc_dapm_connect_input +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xda7875c0 snd_soc_dapm_new_widgets +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xdcc7f200 snd_soc_dai_set_tristate +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xe6844609 snd_soc_dapm_disable_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xe7fd72be snd_soc_put_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xebbfacc3 snd_soc_dai_set_clkdiv +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xf171c0f1 snd_soc_test_bits +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x0d93d0e1 tlsf_create_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x1584fdb9 tlsf_destroy_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x2c383ca4 tlsf_calloc +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x54064cb9 tlsf_get_used_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x60d233a6 tlsf_malloc +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xbe77d1fe tlsf_get_total_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xe6acc368 tlsf_free +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x02500586 thinkpad_ec_unlock +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x0dc7484e thinkpad_ec_try_read_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x2552d213 thinkpad_ec_lock +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x3dbfef12 thinkpad_ec_read_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x8dbbd831 thinkpad_ec_invalidate +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0xa3042743 thinkpad_ec_prefetch_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0xfb5aa917 thinkpad_ec_try_lock +EXPORT_SYMBOL_GPL vmlinux 0x00566d8f inotify_get_cookie +EXPORT_SYMBOL_GPL vmlinux 0x0067df75 ata_tf_from_fis +EXPORT_SYMBOL_GPL vmlinux 0x006d7cad srcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x00b8ecf8 __iowrite32_copy +EXPORT_SYMBOL_GPL vmlinux 0x00c6cc8f kobject_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0x00ebcb5d ata_id_string +EXPORT_SYMBOL_GPL vmlinux 0x0110b3d1 register_hotplug_dock_device +EXPORT_SYMBOL_GPL vmlinux 0x0146ef74 elv_register +EXPORT_SYMBOL_GPL vmlinux 0x01848a8e local_apic_timer_c2_ok +EXPORT_SYMBOL_GPL vmlinux 0x01a4ea6d unregister_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x01e06afe device_reprobe +EXPORT_SYMBOL_GPL vmlinux 0x01e1a8de kgdb_breakpoint +EXPORT_SYMBOL_GPL vmlinux 0x020a0f8a devres_remove +EXPORT_SYMBOL_GPL vmlinux 0x02121d51 sdio_readsb +EXPORT_SYMBOL_GPL vmlinux 0x0275003e pci_bus_add_device +EXPORT_SYMBOL_GPL vmlinux 0x028e6f97 __blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x02a0738f xattr_getsecurity +EXPORT_SYMBOL_GPL vmlinux 0x02ccea56 lock_policy_rwsem_write +EXPORT_SYMBOL_GPL vmlinux 0x030a1563 device_destroy +EXPORT_SYMBOL_GPL vmlinux 0x031bcb4a single_release_net +EXPORT_SYMBOL_GPL vmlinux 0x0343bdf1 __i2c_board_list +EXPORT_SYMBOL_GPL vmlinux 0x0349e695 register_posix_clock +EXPORT_SYMBOL_GPL vmlinux 0x03505c33 rtc_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x03608e3c skb_icv_walk +EXPORT_SYMBOL_GPL vmlinux 0x036a5b83 page_cache_async_readahead +EXPORT_SYMBOL_GPL vmlinux 0x03caa330 user_update +EXPORT_SYMBOL_GPL vmlinux 0x03e3686c ata_timing_cycle2mode +EXPORT_SYMBOL_GPL vmlinux 0x03e7c75d devres_find +EXPORT_SYMBOL_GPL vmlinux 0x03fe2cca flush_work +EXPORT_SYMBOL_GPL vmlinux 0x04011ed8 tty_ldisc_deref +EXPORT_SYMBOL_GPL vmlinux 0x04136bca klist_init +EXPORT_SYMBOL_GPL vmlinux 0x0417078b pci_execute_reset_function +EXPORT_SYMBOL_GPL vmlinux 0x042194b9 scsi_execute_async +EXPORT_SYMBOL_GPL vmlinux 0x044210b0 gpiochip_is_requested +EXPORT_SYMBOL_GPL vmlinux 0x04486e88 rcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x044fc8ec usb_get_hcd +EXPORT_SYMBOL_GPL vmlinux 0x04566c7f init_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x04711ee6 ata_host_register +EXPORT_SYMBOL_GPL vmlinux 0x049fcd7d inet6_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0x04b60a2b ata_qc_complete_multiple +EXPORT_SYMBOL_GPL vmlinux 0x04c2d05a __rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0x04c3f2c1 gnttab_empty_grant_references +EXPORT_SYMBOL_GPL vmlinux 0x04e628cd leds_list_lock +EXPORT_SYMBOL_GPL vmlinux 0x04ea8706 __iowrite64_copy +EXPORT_SYMBOL_GPL vmlinux 0x04f7df9a uv_teardown_irq +EXPORT_SYMBOL_GPL vmlinux 0x0514e03e user_destroy +EXPORT_SYMBOL_GPL vmlinux 0x0531dcb8 ata_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0x054e550b kernel_halt +EXPORT_SYMBOL_GPL vmlinux 0x05d19195 sysfs_notify +EXPORT_SYMBOL_GPL vmlinux 0x05d9d8e2 __ata_port_next_link +EXPORT_SYMBOL_GPL vmlinux 0x060d1064 set_memory_ro +EXPORT_SYMBOL_GPL vmlinux 0x060fbc7e raw_seq_next +EXPORT_SYMBOL_GPL vmlinux 0x064db9a5 mark_mounts_for_expiry +EXPORT_SYMBOL_GPL vmlinux 0x06d222f8 device_resume +EXPORT_SYMBOL_GPL vmlinux 0x06f8aa16 anon_transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x073b14bb usb_serial_generic_write_bulk_callback +EXPORT_SYMBOL_GPL vmlinux 0x073ed337 hvc_alloc +EXPORT_SYMBOL_GPL vmlinux 0x078f04ce xenbus_watch_path +EXPORT_SYMBOL_GPL vmlinux 0x079b170c hid_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0x07a3dddf xenbus_watch_pathfmt +EXPORT_SYMBOL_GPL vmlinux 0x07a92a87 put_device +EXPORT_SYMBOL_GPL vmlinux 0x07b52e38 rtnl_unregister +EXPORT_SYMBOL_GPL vmlinux 0x07d43a2a fixed_phy_set_link_update +EXPORT_SYMBOL_GPL vmlinux 0x07ff4aea xenbus_scanf +EXPORT_SYMBOL_GPL vmlinux 0x0838fe91 regulator_set_current_limit +EXPORT_SYMBOL_GPL vmlinux 0x085b4d3c get_current_tty +EXPORT_SYMBOL_GPL vmlinux 0x08a3e5d1 net_ipv6_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0x08bc0f1e sysfs_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x08d9d137 inotify_rm_wd +EXPORT_SYMBOL_GPL vmlinux 0x0906ea9f usb_sg_init +EXPORT_SYMBOL_GPL vmlinux 0x090c418c ata_sff_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x091eb9b4 round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0x09493a9a xfrm_audit_state_add +EXPORT_SYMBOL_GPL vmlinux 0x09bd30e5 hrtimer_init +EXPORT_SYMBOL_GPL vmlinux 0x09d60bea skb_to_sgvec +EXPORT_SYMBOL_GPL vmlinux 0x09e49c5e usb_ifnum_to_if +EXPORT_SYMBOL_GPL vmlinux 0x09f7810e inet_diag_register +EXPORT_SYMBOL_GPL vmlinux 0x0a28ac54 securityfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x0a2ca061 xfrm_audit_state_replay_overflow +EXPORT_SYMBOL_GPL vmlinux 0x0a88a700 crypto_larval_kill +EXPORT_SYMBOL_GPL vmlinux 0x0ad5c33f acpi_smbus_register_callback +EXPORT_SYMBOL_GPL vmlinux 0x0b0f8665 spi_new_device +EXPORT_SYMBOL_GPL vmlinux 0x0b17239a unregister_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0x0b19b744 ata_sas_port_stop +EXPORT_SYMBOL_GPL vmlinux 0x0b266d8b pci_hp_deregister +EXPORT_SYMBOL_GPL vmlinux 0x0b6e9149 tcp_twsk_unique +EXPORT_SYMBOL_GPL vmlinux 0x0c17e274 xfrm_aalg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x0c4717f7 srcu_init_notifier_head +EXPORT_SYMBOL_GPL vmlinux 0x0c577dba aead_geniv_free +EXPORT_SYMBOL_GPL vmlinux 0x0c5eaae8 regulator_bulk_enable +EXPORT_SYMBOL_GPL vmlinux 0x0ca02e41 ipv6_dup_options +EXPORT_SYMBOL_GPL vmlinux 0x0ca3c4fc driver_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x0d814646 klist_add_head +EXPORT_SYMBOL_GPL vmlinux 0x0d8f20da ata_sff_data_xfer_noirq +EXPORT_SYMBOL_GPL vmlinux 0x0daced87 transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x0dbf8659 devres_get +EXPORT_SYMBOL_GPL vmlinux 0x0de46caf udp4_lib_lookup +EXPORT_SYMBOL_GPL vmlinux 0x0e29bf3c driver_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x0e39b31d hidraw_report_event +EXPORT_SYMBOL_GPL vmlinux 0x0e5c6fd7 i2c_add_numbered_adapter +EXPORT_SYMBOL_GPL vmlinux 0x0e6e2682 crypto_alloc_ablkcipher +EXPORT_SYMBOL_GPL vmlinux 0x0e726910 usb_hcd_pci_suspend +EXPORT_SYMBOL_GPL vmlinux 0x0e7bf714 generic_fh_to_parent +EXPORT_SYMBOL_GPL vmlinux 0x0e8ae8d0 fb_deferred_io_open +EXPORT_SYMBOL_GPL vmlinux 0x0ebf0827 transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x0ec210b8 xen_start_info +EXPORT_SYMBOL_GPL vmlinux 0x0ed56c02 usb_submit_urb +EXPORT_SYMBOL_GPL vmlinux 0x0f20214f crypto_alloc_aead +EXPORT_SYMBOL_GPL vmlinux 0x0f2af6e2 dm_rh_get_state +EXPORT_SYMBOL_GPL vmlinux 0x0f38034f ata_acpi_stm +EXPORT_SYMBOL_GPL vmlinux 0x0f4cdef1 ata_pci_device_resume +EXPORT_SYMBOL_GPL vmlinux 0x0f4efaac sdio_enable_func +EXPORT_SYMBOL_GPL vmlinux 0x0f71d52d ata_pci_device_suspend +EXPORT_SYMBOL_GPL vmlinux 0x0f91bc8c get_cpu_sysdev +EXPORT_SYMBOL_GPL vmlinux 0x0f999ea0 sdio_set_block_size +EXPORT_SYMBOL_GPL vmlinux 0x0f9e7618 do_add_mount +EXPORT_SYMBOL_GPL vmlinux 0x0fe2d570 xenbus_directory +EXPORT_SYMBOL_GPL vmlinux 0x100c13c6 usb_kill_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x100c48a2 unregister_dock_notifier +EXPORT_SYMBOL_GPL vmlinux 0x105185f9 crypto_nivaead_type +EXPORT_SYMBOL_GPL vmlinux 0x10c4d3db disk_get_part +EXPORT_SYMBOL_GPL vmlinux 0x1131631b sata_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x1151aa97 ata_host_alloc_pinfo +EXPORT_SYMBOL_GPL vmlinux 0x117d6c8b klist_add_after +EXPORT_SYMBOL_GPL vmlinux 0x11f447ce __gpio_to_irq +EXPORT_SYMBOL_GPL vmlinux 0x11fabec5 usb_clear_halt +EXPORT_SYMBOL_GPL vmlinux 0x12350a68 __class_register +EXPORT_SYMBOL_GPL vmlinux 0x124f2056 crypto_get_attr_type +EXPORT_SYMBOL_GPL vmlinux 0x1251d30f call_rcu +EXPORT_SYMBOL_GPL vmlinux 0x1294d8a0 tcp_register_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0x129c0f56 sata_scr_write +EXPORT_SYMBOL_GPL vmlinux 0x12b4295b sata_link_resume +EXPORT_SYMBOL_GPL vmlinux 0x12d896f3 input_ff_upload +EXPORT_SYMBOL_GPL vmlinux 0x12e285ec is_uv_system +EXPORT_SYMBOL_GPL vmlinux 0x139620e4 audit_log_vformat +EXPORT_SYMBOL_GPL vmlinux 0x13a8e007 sched_setscheduler +EXPORT_SYMBOL_GPL vmlinux 0x13b2a946 register_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x13d2c65a crypto_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x13ed1e95 crypto_hash_walk_first +EXPORT_SYMBOL_GPL vmlinux 0x13f9a11b crypto_dequeue_request +EXPORT_SYMBOL_GPL vmlinux 0x1434c4ce ata_host_suspend +EXPORT_SYMBOL_GPL vmlinux 0x14566a8c pci_intx +EXPORT_SYMBOL_GPL vmlinux 0x145eebd0 device_power_up +EXPORT_SYMBOL_GPL vmlinux 0x149db923 selinux_string_to_sid +EXPORT_SYMBOL_GPL vmlinux 0x14a2018f vfs_removexattr +EXPORT_SYMBOL_GPL vmlinux 0x14a88277 pid_vnr +EXPORT_SYMBOL_GPL vmlinux 0x14dda409 power_supply_register +EXPORT_SYMBOL_GPL vmlinux 0x15690075 ata_link_abort +EXPORT_SYMBOL_GPL vmlinux 0x158c2ad0 acpi_smbus_unregister_callback +EXPORT_SYMBOL_GPL vmlinux 0x1598dc9d unregister_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x15b0606e e820_any_mapped +EXPORT_SYMBOL_GPL vmlinux 0x15c7e63b regulator_set_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x15d25537 xenbus_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x15d2b854 usb_anchor_urb +EXPORT_SYMBOL_GPL vmlinux 0x15e5f816 spi_add_device +EXPORT_SYMBOL_GPL vmlinux 0x160d5763 inotify_rm_watch +EXPORT_SYMBOL_GPL vmlinux 0x175fbb16 posix_timer_event +EXPORT_SYMBOL_GPL vmlinux 0x176ba7fe input_ff_event +EXPORT_SYMBOL_GPL vmlinux 0x178b5646 mmput +EXPORT_SYMBOL_GPL vmlinux 0x17c33f07 tty_find_polling_driver +EXPORT_SYMBOL_GPL vmlinux 0x17ff5913 ata_sff_irq_on +EXPORT_SYMBOL_GPL vmlinux 0x18076f5f mmu_notifier_unregister +EXPORT_SYMBOL_GPL vmlinux 0x18110ff3 debugfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0x183a4077 spi_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x1878f62b edac_err_assert +EXPORT_SYMBOL_GPL vmlinux 0x18d53420 kgdb_register_io_module +EXPORT_SYMBOL_GPL vmlinux 0x18f83fab gnttab_grant_foreign_access_ref +EXPORT_SYMBOL_GPL vmlinux 0x191d8f45 ata_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0x192faf01 crypto_mod_put +EXPORT_SYMBOL_GPL vmlinux 0x19a304ba usb_disabled +EXPORT_SYMBOL_GPL vmlinux 0x19a4df4c unregister_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0x19b48e2c usb_buffer_free +EXPORT_SYMBOL_GPL vmlinux 0x19b7a4c8 ata_host_alloc +EXPORT_SYMBOL_GPL vmlinux 0x19d01a22 cpuidle_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x19f6884f dm_noflush_suspending +EXPORT_SYMBOL_GPL vmlinux 0x1a10607f unregister_jprobes +EXPORT_SYMBOL_GPL vmlinux 0x1a779255 fib_rules_lookup +EXPORT_SYMBOL_GPL vmlinux 0x1a938737 atomic_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x1ab20959 scsi_target_unblock +EXPORT_SYMBOL_GPL vmlinux 0x1acda5b2 atomic_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x1ad12d5f devres_destroy +EXPORT_SYMBOL_GPL vmlinux 0x1ad3b491 acpi_root_bridge +EXPORT_SYMBOL_GPL vmlinux 0x1af87a65 hvc_instantiate +EXPORT_SYMBOL_GPL vmlinux 0x1b8be8fb dev_attr_link_power_management_policy +EXPORT_SYMBOL_GPL vmlinux 0x1b8dfa03 ata_sff_data_xfer +EXPORT_SYMBOL_GPL vmlinux 0x1b9aca3f jprobe_return +EXPORT_SYMBOL_GPL vmlinux 0x1bde3f3e audit_log_untrustedstring +EXPORT_SYMBOL_GPL vmlinux 0x1be86560 sdio_writew +EXPORT_SYMBOL_GPL vmlinux 0x1c4654a5 da903x_write +EXPORT_SYMBOL_GPL vmlinux 0x1c643609 xfrm_audit_state_icvfail +EXPORT_SYMBOL_GPL vmlinux 0x1c87a811 __round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x1c9b34c7 blkdev_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x1ce06916 sysdev_create_file +EXPORT_SYMBOL_GPL vmlinux 0x1ce957a7 blk_abort_queue +EXPORT_SYMBOL_GPL vmlinux 0x1ce9f482 led_trigger_store +EXPORT_SYMBOL_GPL vmlinux 0x1d023170 schedule_hrtimeout +EXPORT_SYMBOL_GPL vmlinux 0x1d735315 kobject_rename +EXPORT_SYMBOL_GPL vmlinux 0x1dbea856 usb_autopm_put_interface +EXPORT_SYMBOL_GPL vmlinux 0x1dd70100 dmi_walk +EXPORT_SYMBOL_GPL vmlinux 0x1e5a5f22 sn_partition_id +EXPORT_SYMBOL_GPL vmlinux 0x1e725999 __mnt_is_readonly +EXPORT_SYMBOL_GPL vmlinux 0x1e7bbcb3 kernel_restart +EXPORT_SYMBOL_GPL vmlinux 0x1e999fe1 inet_diag_unregister +EXPORT_SYMBOL_GPL vmlinux 0x1eb9516e round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x1ed52eed rdev_get_dev +EXPORT_SYMBOL_GPL vmlinux 0x1ed70c6e usb_serial_register +EXPORT_SYMBOL_GPL vmlinux 0x1f57e18e pci_disable_rom +EXPORT_SYMBOL_GPL vmlinux 0x1f87fc15 da903x_read +EXPORT_SYMBOL_GPL vmlinux 0x1f8ec1b3 acpi_get_pci_rootbridge_handle +EXPORT_SYMBOL_GPL vmlinux 0x1f94682b ata_dummy_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x1f9519c4 rt_mutex_lock_interruptible +EXPORT_SYMBOL_GPL vmlinux 0x1f9a0fbf hpet_unregister_irq_handler +EXPORT_SYMBOL_GPL vmlinux 0x1fac607a usb_hcd_unlink_urb_from_ep +EXPORT_SYMBOL_GPL vmlinux 0x1fcece42 inet_twdr_twcal_tick +EXPORT_SYMBOL_GPL vmlinux 0x1fd64d91 usb_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x20577ea2 xfrm_ealg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x20788098 dm_rh_dirty_log +EXPORT_SYMBOL_GPL vmlinux 0x2089d9a1 usb_control_msg +EXPORT_SYMBOL_GPL vmlinux 0x20b82470 hpet_register_irq_handler +EXPORT_SYMBOL_GPL vmlinux 0x20bc3470 orderly_poweroff +EXPORT_SYMBOL_GPL vmlinux 0x20cd788f __ftrace_printk +EXPORT_SYMBOL_GPL vmlinux 0x213c1513 klist_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x2171b7a5 devres_alloc +EXPORT_SYMBOL_GPL vmlinux 0x219b3ca9 exit_fs +EXPORT_SYMBOL_GPL vmlinux 0x21bd1bdd uart_console_write +EXPORT_SYMBOL_GPL vmlinux 0x21e811d7 debugfs_create_u16 +EXPORT_SYMBOL_GPL vmlinux 0x2240d211 unregister_jprobe +EXPORT_SYMBOL_GPL vmlinux 0x22472bf4 xfrm_calg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x226f8820 skb_partial_csum_set +EXPORT_SYMBOL_GPL vmlinux 0x2296c00d crypto_attr_u32 +EXPORT_SYMBOL_GPL vmlinux 0x22b3070f tty_prepare_flip_string +EXPORT_SYMBOL_GPL vmlinux 0x23309227 security_inode_setattr +EXPORT_SYMBOL_GPL vmlinux 0x236cddcf inet_csk_clone +EXPORT_SYMBOL_GPL vmlinux 0x23864ce7 cpuset_mem_spread_node +EXPORT_SYMBOL_GPL vmlinux 0x23866e87 ata_bmdma_status +EXPORT_SYMBOL_GPL vmlinux 0x238e9331 tcp_get_info +EXPORT_SYMBOL_GPL vmlinux 0x239a55e2 fsstack_copy_attr_all +EXPORT_SYMBOL_GPL vmlinux 0x239fb7bd kobject_get_path +EXPORT_SYMBOL_GPL vmlinux 0x23bbf3f2 crypto_rng_type +EXPORT_SYMBOL_GPL vmlinux 0x23c613c0 hid_allocate_device +EXPORT_SYMBOL_GPL vmlinux 0x23c661bf dm_rh_recovery_prepare +EXPORT_SYMBOL_GPL vmlinux 0x24196ba2 init_uts_ns +EXPORT_SYMBOL_GPL vmlinux 0x2429e0c6 preempt_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x2447533c ktime_get_real +EXPORT_SYMBOL_GPL vmlinux 0x2469ca66 platform_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x2486928f usb_create_hcd +EXPORT_SYMBOL_GPL vmlinux 0x24c7698a xenbus_write +EXPORT_SYMBOL_GPL vmlinux 0x24eb7e32 leds_list +EXPORT_SYMBOL_GPL vmlinux 0x24fb231f tty_wakeup +EXPORT_SYMBOL_GPL vmlinux 0x2531c51d sysdev_class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x253d2c12 crypto_tfm_in_queue +EXPORT_SYMBOL_GPL vmlinux 0x253e0711 ata_do_set_mode +EXPORT_SYMBOL_GPL vmlinux 0x2545c170 unregister_xenbus_watch +EXPORT_SYMBOL_GPL vmlinux 0x25845190 tcp_reno_min_cwnd +EXPORT_SYMBOL_GPL vmlinux 0x25e98d63 kobject_uevent_env +EXPORT_SYMBOL_GPL vmlinux 0x2603daaa tcp_death_row +EXPORT_SYMBOL_GPL vmlinux 0x262a43af dm_rh_update_states +EXPORT_SYMBOL_GPL vmlinux 0x2665b4b3 spi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x269d69b8 ata_sff_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0x26bfc6f0 ata_sff_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x26c90ea4 scsi_eh_get_sense +EXPORT_SYMBOL_GPL vmlinux 0x26da2c43 pci_stop_bus_device +EXPORT_SYMBOL_GPL vmlinux 0x26eff321 aead_geniv_alloc +EXPORT_SYMBOL_GPL vmlinux 0x27951461 __hid_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x2798ce5c pci_restore_msi_state +EXPORT_SYMBOL_GPL vmlinux 0x28088f0f pv_time_ops +EXPORT_SYMBOL_GPL vmlinux 0x28471e55 driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0x28503e2e platform_device_add_resources +EXPORT_SYMBOL_GPL vmlinux 0x28bdacde hrtimer_start_range_ns +EXPORT_SYMBOL_GPL vmlinux 0x28d664ff __raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x28e23139 xfrm_probe_algs +EXPORT_SYMBOL_GPL vmlinux 0x28e45708 kobject_uevent +EXPORT_SYMBOL_GPL vmlinux 0x28f923d4 dm_device_name +EXPORT_SYMBOL_GPL vmlinux 0x28f99734 sata_link_hardreset +EXPORT_SYMBOL_GPL vmlinux 0x291ed881 inet_twsk_purge +EXPORT_SYMBOL_GPL vmlinux 0x292cbc95 bt_class +EXPORT_SYMBOL_GPL vmlinux 0x292fd278 class_destroy +EXPORT_SYMBOL_GPL vmlinux 0x29c68900 page_mkclean +EXPORT_SYMBOL_GPL vmlinux 0x29d034df netlink_has_listeners +EXPORT_SYMBOL_GPL vmlinux 0x2a02e169 ata_scsi_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0x2a42547c debugfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x2a678a13 __suspend_report_result +EXPORT_SYMBOL_GPL vmlinux 0x2a81396a xenbus_bind_evtchn +EXPORT_SYMBOL_GPL vmlinux 0x2b24e4a0 uv_blade_info +EXPORT_SYMBOL_GPL vmlinux 0x2b486747 vfs_lock_file +EXPORT_SYMBOL_GPL vmlinux 0x2b81a680 macvlan_handle_frame_hook +EXPORT_SYMBOL_GPL vmlinux 0x2b9f8e23 nf_net_ipv4_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x2bcf3d87 rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0x2c16ed76 xfrm_calg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x2c208607 power_supply_is_system_supplied +EXPORT_SYMBOL_GPL vmlinux 0x2c5524b3 xenbus_switch_state +EXPORT_SYMBOL_GPL vmlinux 0x2ca95082 cpufreq_cpu_put +EXPORT_SYMBOL_GPL vmlinux 0x2cbc3b61 __audit_inode_child +EXPORT_SYMBOL_GPL vmlinux 0x2d29ff22 ata_port_pbar_desc +EXPORT_SYMBOL_GPL vmlinux 0x2d48f4f9 __inet_twsk_hashdance +EXPORT_SYMBOL_GPL vmlinux 0x2d54d537 anon_inode_getfd +EXPORT_SYMBOL_GPL vmlinux 0x2d59c954 edac_handlers +EXPORT_SYMBOL_GPL vmlinux 0x2d9f2ce3 sched_clock_idle_wakeup_event +EXPORT_SYMBOL_GPL vmlinux 0x2daeff65 rdev_get_id +EXPORT_SYMBOL_GPL vmlinux 0x2db68b9a sysfs_get +EXPORT_SYMBOL_GPL vmlinux 0x2dc783a5 crypto_init_spawn +EXPORT_SYMBOL_GPL vmlinux 0x2dd4aab4 rtc_set_time +EXPORT_SYMBOL_GPL vmlinux 0x2de9f755 anon_transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x2dfd4290 cpuidle_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x2e180ffc queue_delayed_work_on +EXPORT_SYMBOL_GPL vmlinux 0x2e2995cc led_trigger_unregister_simple +EXPORT_SYMBOL_GPL vmlinux 0x2e9973ad inet6_destroy_sock +EXPORT_SYMBOL_GPL vmlinux 0x2eb573b6 user_read +EXPORT_SYMBOL_GPL vmlinux 0x2ec3b51d hwmon_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x2ec92012 scatterwalk_copychunks +EXPORT_SYMBOL_GPL vmlinux 0x2ede9716 usb_sg_cancel +EXPORT_SYMBOL_GPL vmlinux 0x2ee85928 sdev_evt_send_simple +EXPORT_SYMBOL_GPL vmlinux 0x2ee96b90 usb_hcd_giveback_urb +EXPORT_SYMBOL_GPL vmlinux 0x2f0e87cb ata_eh_thaw_port +EXPORT_SYMBOL_GPL vmlinux 0x2f27bf97 ata_pci_bmdma_init +EXPORT_SYMBOL_GPL vmlinux 0x2f47d8c7 cpufreq_frequency_get_table +EXPORT_SYMBOL_GPL vmlinux 0x2f621dcc __cpufreq_driver_getavg +EXPORT_SYMBOL_GPL vmlinux 0x2f70706a regulator_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x2fc66786 blk_insert_cloned_request +EXPORT_SYMBOL_GPL vmlinux 0x3011e931 devm_kzalloc +EXPORT_SYMBOL_GPL vmlinux 0x30140599 inotify_init +EXPORT_SYMBOL_GPL vmlinux 0x305112d9 blk_trace_remove +EXPORT_SYMBOL_GPL vmlinux 0x307003f3 sis_info133_for_sata +EXPORT_SYMBOL_GPL vmlinux 0x30b268ec unregister_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0x3160efaf device_schedule_callback_owner +EXPORT_SYMBOL_GPL vmlinux 0x31797610 tracepoint_iter_reset +EXPORT_SYMBOL_GPL vmlinux 0x318920b1 register_dock_notifier +EXPORT_SYMBOL_GPL vmlinux 0x322284f3 tty_buffer_request_room +EXPORT_SYMBOL_GPL vmlinux 0x3227d4cb class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x3227fde7 net_assign_generic +EXPORT_SYMBOL_GPL vmlinux 0x325e677c gnttab_grant_foreign_transfer_ref +EXPORT_SYMBOL_GPL vmlinux 0x328b2a12 transport_configure_device +EXPORT_SYMBOL_GPL vmlinux 0x32ebf6f1 crypto_attr_alg +EXPORT_SYMBOL_GPL vmlinux 0x330e075d led_trigger_set +EXPORT_SYMBOL_GPL vmlinux 0x336096d4 simple_attr_write +EXPORT_SYMBOL_GPL vmlinux 0x33b6e752 acpi_ec_remove_query_handler +EXPORT_SYMBOL_GPL vmlinux 0x34105c01 bus_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x3441c3d6 gpio_set_value_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x344e210e ata_acpi_cbl_80wire +EXPORT_SYMBOL_GPL vmlinux 0x34dd71ab ata_sff_irq_clear +EXPORT_SYMBOL_GPL vmlinux 0x34e8d5a8 kern_mount_data +EXPORT_SYMBOL_GPL vmlinux 0x3523a891 dm_rh_stop_recovery +EXPORT_SYMBOL_GPL vmlinux 0x356b1376 usb_driver_set_configuration +EXPORT_SYMBOL_GPL vmlinux 0x35897293 crypto_hash_walk_done +EXPORT_SYMBOL_GPL vmlinux 0x35d8c94a sdev_evt_alloc +EXPORT_SYMBOL_GPL vmlinux 0x361e2bcc save_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0x362e23ec call_rcu_bh +EXPORT_SYMBOL_GPL vmlinux 0x365c2c94 spi_busnum_to_master +EXPORT_SYMBOL_GPL vmlinux 0x36969fdb devres_close_group +EXPORT_SYMBOL_GPL vmlinux 0x3707c683 input_class +EXPORT_SYMBOL_GPL vmlinux 0x374319b0 skcipher_geniv_alloc +EXPORT_SYMBOL_GPL vmlinux 0x377dbe49 ata_sff_check_status +EXPORT_SYMBOL_GPL vmlinux 0x378e3321 crypto_alg_mod_lookup +EXPORT_SYMBOL_GPL vmlinux 0x37af0835 cpufreq_cpu_get +EXPORT_SYMBOL_GPL vmlinux 0x37bf012a devres_release_group +EXPORT_SYMBOL_GPL vmlinux 0x37ca9f53 input_ff_create +EXPORT_SYMBOL_GPL vmlinux 0x3895233b srcu_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x389fd081 md_new_event +EXPORT_SYMBOL_GPL vmlinux 0x38aa8e9b blk_set_cmd_filter_defaults +EXPORT_SYMBOL_GPL vmlinux 0x38d36cdd dnotify_parent +EXPORT_SYMBOL_GPL vmlinux 0x390d337e sysfs_remove_link +EXPORT_SYMBOL_GPL vmlinux 0x39238b57 klist_del +EXPORT_SYMBOL_GPL vmlinux 0x395cd90d ata_pci_remove_one +EXPORT_SYMBOL_GPL vmlinux 0x39939e12 queue_work_on +EXPORT_SYMBOL_GPL vmlinux 0x39942348 bus_for_each_drv +EXPORT_SYMBOL_GPL vmlinux 0x39a438e8 put_driver +EXPORT_SYMBOL_GPL vmlinux 0x39f68db3 __trace_note_message +EXPORT_SYMBOL_GPL vmlinux 0x3a25eb7e blk_trace_setup +EXPORT_SYMBOL_GPL vmlinux 0x3a311560 unregister_kprobes +EXPORT_SYMBOL_GPL vmlinux 0x3a7f8b86 __local_bh_enable +EXPORT_SYMBOL_GPL vmlinux 0x3b17aec1 device_initialize +EXPORT_SYMBOL_GPL vmlinux 0x3b1d5794 usb_hcd_poll_rh_status +EXPORT_SYMBOL_GPL vmlinux 0x3b58c91e inet_twsk_put +EXPORT_SYMBOL_GPL vmlinux 0x3b954dde pci_destroy_slot +EXPORT_SYMBOL_GPL vmlinux 0x3bc8d088 blk_queue_rq_timeout +EXPORT_SYMBOL_GPL vmlinux 0x3be7af02 get_max_files +EXPORT_SYMBOL_GPL vmlinux 0x3be89d3c usb_register_notify +EXPORT_SYMBOL_GPL vmlinux 0x3c026ec5 inotify_find_update_watch +EXPORT_SYMBOL_GPL vmlinux 0x3c942368 profile_event_unregister +EXPORT_SYMBOL_GPL vmlinux 0x3ca5ac98 ata_sff_tf_load +EXPORT_SYMBOL_GPL vmlinux 0x3cd06035 add_input_randomness +EXPORT_SYMBOL_GPL vmlinux 0x3cf9bf4f platform_driver_probe +EXPORT_SYMBOL_GPL vmlinux 0x3cfedb3f register_pm_notifier +EXPORT_SYMBOL_GPL vmlinux 0x3d00851b sdio_readb +EXPORT_SYMBOL_GPL vmlinux 0x3d29867d per_cpu__gdt_page +EXPORT_SYMBOL_GPL vmlinux 0x3d33f2a4 __rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0x3d342883 save_stack_trace_tsk +EXPORT_SYMBOL_GPL vmlinux 0x3d5f392d acpi_os_unmap_memory +EXPORT_SYMBOL_GPL vmlinux 0x3d67f752 usb_deregister_dev +EXPORT_SYMBOL_GPL vmlinux 0x3d7ea99a gnttab_grant_foreign_transfer +EXPORT_SYMBOL_GPL vmlinux 0x3db1e6d2 usb_altnum_to_altsetting +EXPORT_SYMBOL_GPL vmlinux 0x3e1c3c88 usb_serial_deregister +EXPORT_SYMBOL_GPL vmlinux 0x3e39a652 usb_serial_port_softint +EXPORT_SYMBOL_GPL vmlinux 0x3e500979 rtc_irq_unregister +EXPORT_SYMBOL_GPL vmlinux 0x3e9a96f5 usb_reset_configuration +EXPORT_SYMBOL_GPL vmlinux 0x3eb551c6 sata_sff_hardreset +EXPORT_SYMBOL_GPL vmlinux 0x3ebffc33 sdio_memcpy_toio +EXPORT_SYMBOL_GPL vmlinux 0x3ecf6cfc wmi_install_notify_handler +EXPORT_SYMBOL_GPL vmlinux 0x3edad223 usb_usual_clear_present +EXPORT_SYMBOL_GPL vmlinux 0x3efb35c9 get_online_cpus +EXPORT_SYMBOL_GPL vmlinux 0x3f102d74 i2c_new_device +EXPORT_SYMBOL_GPL vmlinux 0x3f238101 dcookie_register +EXPORT_SYMBOL_GPL vmlinux 0x3f567507 inet_csk_compat_setsockopt +EXPORT_SYMBOL_GPL vmlinux 0x3f6b3a76 usb_get_from_anchor +EXPORT_SYMBOL_GPL vmlinux 0x3f84d4c9 gnttab_release_grant_reference +EXPORT_SYMBOL_GPL vmlinux 0x3f9a2a10 hidinput_find_field +EXPORT_SYMBOL_GPL vmlinux 0x3fc24436 dm_rh_recovery_end +EXPORT_SYMBOL_GPL vmlinux 0x3fc35f5a fib_rules_register +EXPORT_SYMBOL_GPL vmlinux 0x3fdb68b4 hidinput_disconnect +EXPORT_SYMBOL_GPL vmlinux 0x40380ad6 hrtimer_cancel +EXPORT_SYMBOL_GPL vmlinux 0x40af0dec ata_xfer_mode2mask +EXPORT_SYMBOL_GPL vmlinux 0x40c4f3a2 hid_parse_report +EXPORT_SYMBOL_GPL vmlinux 0x41781289 ata_bmdma_stop +EXPORT_SYMBOL_GPL vmlinux 0x41c0a559 crypto_ahash_type +EXPORT_SYMBOL_GPL vmlinux 0x41f3cc90 xfrm_aalg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x42308f55 bus_for_each_dev +EXPORT_SYMBOL_GPL vmlinux 0x424acc6d scatterwalk_done +EXPORT_SYMBOL_GPL vmlinux 0x425074a8 ata_cable_sata +EXPORT_SYMBOL_GPL vmlinux 0x4264debc tty_ldisc_ref_wait +EXPORT_SYMBOL_GPL vmlinux 0x42845667 inet6_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0x42b50f75 nf_register_afinfo +EXPORT_SYMBOL_GPL vmlinux 0x42cc609c usb_bulk_msg +EXPORT_SYMBOL_GPL vmlinux 0x432fd7f6 __gpio_set_value +EXPORT_SYMBOL_GPL vmlinux 0x43321fe8 usb_autopm_set_interface +EXPORT_SYMBOL_GPL vmlinux 0x436336ad rtc_class_open +EXPORT_SYMBOL_GPL vmlinux 0x43dc6200 platform_device_del +EXPORT_SYMBOL_GPL vmlinux 0x43f56e82 ata_xfer_mode2shift +EXPORT_SYMBOL_GPL vmlinux 0x4446f8cb rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0x444a66a1 led_trigger_show +EXPORT_SYMBOL_GPL vmlinux 0x448a059b sysfs_add_file_to_group +EXPORT_SYMBOL_GPL vmlinux 0x44a65d5c lock_policy_rwsem_read +EXPORT_SYMBOL_GPL vmlinux 0x44b5ba8b platform_device_add +EXPORT_SYMBOL_GPL vmlinux 0x44c6c44e debugfs_create_u64 +EXPORT_SYMBOL_GPL vmlinux 0x4516d33d devres_open_group +EXPORT_SYMBOL_GPL vmlinux 0x451a0bd2 device_release_driver +EXPORT_SYMBOL_GPL vmlinux 0x457594fa crypto_alg_list +EXPORT_SYMBOL_GPL vmlinux 0x45b8b6d4 ata_cable_unknown +EXPORT_SYMBOL_GPL vmlinux 0x45bf1ff3 crypto_inc +EXPORT_SYMBOL_GPL vmlinux 0x45d14bdf hypercall_page +EXPORT_SYMBOL_GPL vmlinux 0x460f31aa rodata_test_data +EXPORT_SYMBOL_GPL vmlinux 0x4689bc88 klist_node_attached +EXPORT_SYMBOL_GPL vmlinux 0x46ac4d22 dm_rh_region_context +EXPORT_SYMBOL_GPL vmlinux 0x47229b5c gpio_request +EXPORT_SYMBOL_GPL vmlinux 0x4732157e inet_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0x473465b5 pciserial_init_ports +EXPORT_SYMBOL_GPL vmlinux 0x474ab29b user_match +EXPORT_SYMBOL_GPL vmlinux 0x47583845 platform_get_resource +EXPORT_SYMBOL_GPL vmlinux 0x476437f0 single_open_net +EXPORT_SYMBOL_GPL vmlinux 0x47744df3 ata_slave_link_init +EXPORT_SYMBOL_GPL vmlinux 0x47931cbb regulator_register +EXPORT_SYMBOL_GPL vmlinux 0x47d148b9 simple_attr_open +EXPORT_SYMBOL_GPL vmlinux 0x4817ac2e bus_find_device +EXPORT_SYMBOL_GPL vmlinux 0x4826eb62 __inet_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0x486b6ff6 attribute_container_find_class_device +EXPORT_SYMBOL_GPL vmlinux 0x489f945e mnt_drop_write +EXPORT_SYMBOL_GPL vmlinux 0x48dae124 ata_pci_device_do_suspend +EXPORT_SYMBOL_GPL vmlinux 0x4903219c usb_get_dev +EXPORT_SYMBOL_GPL vmlinux 0x493e3cf2 map_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x496a7702 usb_add_hcd +EXPORT_SYMBOL_GPL vmlinux 0x499043d3 crypto_init_queue +EXPORT_SYMBOL_GPL vmlinux 0x49fd5e6d disk_part_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x4a11a4fb bind_virq_to_irqhandler +EXPORT_SYMBOL_GPL vmlinux 0x4a3ae268 alloc_page_buffers +EXPORT_SYMBOL_GPL vmlinux 0x4a5aa1f7 crypto_grab_aead +EXPORT_SYMBOL_GPL vmlinux 0x4a7e30d9 marker_probe_unregister_private_data +EXPORT_SYMBOL_GPL vmlinux 0x4aa91899 relay_switch_subbuf +EXPORT_SYMBOL_GPL vmlinux 0x4ace7eb7 platform_add_devices +EXPORT_SYMBOL_GPL vmlinux 0x4af2264c pci_set_pcie_reset_state +EXPORT_SYMBOL_GPL vmlinux 0x4b3f6efd fs_kobj +EXPORT_SYMBOL_GPL vmlinux 0x4b762828 start_thread +EXPORT_SYMBOL_GPL vmlinux 0x4c759827 byte_rev_table +EXPORT_SYMBOL_GPL vmlinux 0x4c95ad6e uhci_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0x4d19eb5a __scsi_get_command +EXPORT_SYMBOL_GPL vmlinux 0x4d44c06d platform_get_irq +EXPORT_SYMBOL_GPL vmlinux 0x4d6efa5a xfrm_audit_policy_add +EXPORT_SYMBOL_GPL vmlinux 0x4d7e5436 proc_net_remove +EXPORT_SYMBOL_GPL vmlinux 0x4ddd5265 inotify_inode_is_dead +EXPORT_SYMBOL_GPL vmlinux 0x4e695d74 regulator_get_mode +EXPORT_SYMBOL_GPL vmlinux 0x4ea27434 sysfs_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x4eca01cb inet_twsk_schedule +EXPORT_SYMBOL_GPL vmlinux 0x4f2dcea9 sata_async_notification +EXPORT_SYMBOL_GPL vmlinux 0x4f4d143e lookup_create +EXPORT_SYMBOL_GPL vmlinux 0x4f84d4f3 bdi_writeout_inc +EXPORT_SYMBOL_GPL vmlinux 0x4fdc945d sata_deb_timing_normal +EXPORT_SYMBOL_GPL vmlinux 0x4fdf5251 device_bind_driver +EXPORT_SYMBOL_GPL vmlinux 0x5086ac3a alg_test +EXPORT_SYMBOL_GPL vmlinux 0x50b319ce cpu_bit_bitmap +EXPORT_SYMBOL_GPL vmlinux 0x50b67174 xfrm_ealg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x50e7193a __i2c_first_dynamic_bus_num +EXPORT_SYMBOL_GPL vmlinux 0x50fad434 round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x511f3e1f apic_ops +EXPORT_SYMBOL_GPL vmlinux 0x511f8529 ata_dev_disable +EXPORT_SYMBOL_GPL vmlinux 0x5121c2f0 sysfs_update_group +EXPORT_SYMBOL_GPL vmlinux 0x514525b7 usb_hub_tt_clear_buffer +EXPORT_SYMBOL_GPL vmlinux 0x51596651 led_trigger_unregister +EXPORT_SYMBOL_GPL vmlinux 0x518be000 usb_kill_urb +EXPORT_SYMBOL_GPL vmlinux 0x518c2fc6 hpet_rtc_dropped_irq +EXPORT_SYMBOL_GPL vmlinux 0x51a4c094 unregister_kprobe +EXPORT_SYMBOL_GPL vmlinux 0x51acca77 ata_sas_port_destroy +EXPORT_SYMBOL_GPL vmlinux 0x51dd6488 xfrm_aalg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x51f9fe26 ata_cable_80wire +EXPORT_SYMBOL_GPL vmlinux 0x51fc8b26 pci_renumber_slot +EXPORT_SYMBOL_GPL vmlinux 0x526b867a acpi_smbus_read +EXPORT_SYMBOL_GPL vmlinux 0x52a34488 tty_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x52b0e33e xenbus_alloc_evtchn +EXPORT_SYMBOL_GPL vmlinux 0x52d0ae76 regulator_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x52d111ea pm_qos_update_requirement +EXPORT_SYMBOL_GPL vmlinux 0x52d54db1 kill_pid_info_as_uid +EXPORT_SYMBOL_GPL vmlinux 0x53614269 get_cpu_idle_time_us +EXPORT_SYMBOL_GPL vmlinux 0x5372dede unregister_acpi_bus_notifier +EXPORT_SYMBOL_GPL vmlinux 0x53986488 register_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x539c4f37 crypto_larval_alloc +EXPORT_SYMBOL_GPL vmlinux 0x53c2a1ae get_user_pages_fast +EXPORT_SYMBOL_GPL vmlinux 0x542652cf bus_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5440ae2b class_dev_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x5490bd91 securityfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0x552891c8 regulator_disable +EXPORT_SYMBOL_GPL vmlinux 0x552a80eb sdio_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x552bea82 device_for_each_child +EXPORT_SYMBOL_GPL vmlinux 0x55526907 xen_features +EXPORT_SYMBOL_GPL vmlinux 0x55c5a0b7 pci_hp_register +EXPORT_SYMBOL_GPL vmlinux 0x55ef8bc5 blk_end_bidi_request +EXPORT_SYMBOL_GPL vmlinux 0x561c634a wmi_evaluate_method +EXPORT_SYMBOL_GPL vmlinux 0x56398615 mark_tsc_unstable +EXPORT_SYMBOL_GPL vmlinux 0x5641485b tty_termios_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x5669e4a5 driver_attach +EXPORT_SYMBOL_GPL vmlinux 0x56a940e7 sdio_readw +EXPORT_SYMBOL_GPL vmlinux 0x56ed913f generic_sync_sb_inodes +EXPORT_SYMBOL_GPL vmlinux 0x5740252c vfs_setxattr +EXPORT_SYMBOL_GPL vmlinux 0x575c5f94 execute_in_process_context +EXPORT_SYMBOL_GPL vmlinux 0x5779d445 xenbus_exists +EXPORT_SYMBOL_GPL vmlinux 0x579e0bf5 rtnl_unregister_all +EXPORT_SYMBOL_GPL vmlinux 0x57b75f80 inet_csk_route_req +EXPORT_SYMBOL_GPL vmlinux 0x57cc0ffd usb_serial_generic_open +EXPORT_SYMBOL_GPL vmlinux 0x57fd5249 ata_sff_qc_fill_rtf +EXPORT_SYMBOL_GPL vmlinux 0x580a49e3 power_supply_class +EXPORT_SYMBOL_GPL vmlinux 0x58547767 scsi_dh_activate +EXPORT_SYMBOL_GPL vmlinux 0x58666eb6 sdio_disable_func +EXPORT_SYMBOL_GPL vmlinux 0x586d5849 ata_ehi_clear_desc +EXPORT_SYMBOL_GPL vmlinux 0x59163259 proc_net_fops_create +EXPORT_SYMBOL_GPL vmlinux 0x591e216f dev_set_name +EXPORT_SYMBOL_GPL vmlinux 0x593a36c2 scsi_dh_handler_exist +EXPORT_SYMBOL_GPL vmlinux 0x597f3bc3 marker_get_private_data +EXPORT_SYMBOL_GPL vmlinux 0x59cf8cec device_move +EXPORT_SYMBOL_GPL vmlinux 0x5a2b1b67 gnttab_free_grant_reference +EXPORT_SYMBOL_GPL vmlinux 0x5a6fe27b dm_rh_dec +EXPORT_SYMBOL_GPL vmlinux 0x5a7bfe41 crypto_probing_notify +EXPORT_SYMBOL_GPL vmlinux 0x5a80af43 sysfs_schedule_callback +EXPORT_SYMBOL_GPL vmlinux 0x5a8fe62b ata_link_offline +EXPORT_SYMBOL_GPL vmlinux 0x5af03a28 gnttab_claim_grant_reference +EXPORT_SYMBOL_GPL vmlinux 0x5b1b2997 sysdev_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5b1b54f9 dm_rh_get_region_key +EXPORT_SYMBOL_GPL vmlinux 0x5ba155f7 hid_add_device +EXPORT_SYMBOL_GPL vmlinux 0x5beccf80 ata_host_activate +EXPORT_SYMBOL_GPL vmlinux 0x5bfc03c3 unregister_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5c783951 class_dev_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x5c93cace usb_serial_generic_read_bulk_callback +EXPORT_SYMBOL_GPL vmlinux 0x5ca4f09f usb_hcd_pci_probe +EXPORT_SYMBOL_GPL vmlinux 0x5cc852e3 uv_coherency_id +EXPORT_SYMBOL_GPL vmlinux 0x5cd9b24c acpi_bus_trim +EXPORT_SYMBOL_GPL vmlinux 0x5cfcf0f1 percpu_free +EXPORT_SYMBOL_GPL vmlinux 0x5d0f6f57 kbd_table +EXPORT_SYMBOL_GPL vmlinux 0x5d366dec gnttab_cancel_free_callback +EXPORT_SYMBOL_GPL vmlinux 0x5d546d0b hid_report_raw_event +EXPORT_SYMBOL_GPL vmlinux 0x5d730e7b raw_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5d87c067 register_acpi_bus_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5d884417 ata_sff_port_start +EXPORT_SYMBOL_GPL vmlinux 0x5d95e10c inotify_remove_watch_locked +EXPORT_SYMBOL_GPL vmlinux 0x5d9c0967 class_find_device +EXPORT_SYMBOL_GPL vmlinux 0x5dd67618 register_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5e22ccd3 ata_bmdma_mode_filter +EXPORT_SYMBOL_GPL vmlinux 0x5e51be23 led_trigger_event +EXPORT_SYMBOL_GPL vmlinux 0x5ee84e19 lookup_instantiate_filp +EXPORT_SYMBOL_GPL vmlinux 0x5eeb2077 usb_get_intf +EXPORT_SYMBOL_GPL vmlinux 0x5efb957f inet6_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0x5f2da8c4 check_tsc_unstable +EXPORT_SYMBOL_GPL vmlinux 0x5f2f792b sdio_readl +EXPORT_SYMBOL_GPL vmlinux 0x60355ac6 seq_release_net +EXPORT_SYMBOL_GPL vmlinux 0x605ff123 klist_add_tail +EXPORT_SYMBOL_GPL vmlinux 0x6061f651 raw_seq_stop +EXPORT_SYMBOL_GPL vmlinux 0x6091797f synchronize_rcu +EXPORT_SYMBOL_GPL vmlinux 0x60a13e90 rcu_barrier +EXPORT_SYMBOL_GPL vmlinux 0x60a469af usb_get_urb +EXPORT_SYMBOL_GPL vmlinux 0x60f20463 sysdev_store_int +EXPORT_SYMBOL_GPL vmlinux 0x611f95c2 disk_part_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x612a5385 __ip_route_output_key +EXPORT_SYMBOL_GPL vmlinux 0x612f7277 ipv6_opt_accepted +EXPORT_SYMBOL_GPL vmlinux 0x6155188f __blk_put_request +EXPORT_SYMBOL_GPL vmlinux 0x6160b057 __inet_lookup_established +EXPORT_SYMBOL_GPL vmlinux 0x616c9d5f crypto_alloc_base +EXPORT_SYMBOL_GPL vmlinux 0x61aeac91 devm_kfree +EXPORT_SYMBOL_GPL vmlinux 0x61b13635 kobject_init_and_add +EXPORT_SYMBOL_GPL vmlinux 0x62170d1e hid_input_report +EXPORT_SYMBOL_GPL vmlinux 0x62370f44 ata_port_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0x629f4926 __blk_add_trace +EXPORT_SYMBOL_GPL vmlinux 0x62d48fd2 ipv6_find_tlv +EXPORT_SYMBOL_GPL vmlinux 0x62e5757d usb_hcd_pci_remove +EXPORT_SYMBOL_GPL vmlinux 0x63735f62 aead_geniv_exit +EXPORT_SYMBOL_GPL vmlinux 0x63ae27d6 add_nops +EXPORT_SYMBOL_GPL vmlinux 0x63b17000 ata_sff_qc_issue +EXPORT_SYMBOL_GPL vmlinux 0x63b91799 ata_sff_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0x6458da3d screen_glyph +EXPORT_SYMBOL_GPL vmlinux 0x64ecdabd sata_set_spd +EXPORT_SYMBOL_GPL vmlinux 0x6545ec8a regulator_force_disable +EXPORT_SYMBOL_GPL vmlinux 0x655500e0 ata_link_online +EXPORT_SYMBOL_GPL vmlinux 0x65ccb6f0 call_netevent_notifiers +EXPORT_SYMBOL_GPL vmlinux 0x65d6d0f0 gpio_direction_input +EXPORT_SYMBOL_GPL vmlinux 0x6610ad99 synchronize_srcu +EXPORT_SYMBOL_GPL vmlinux 0x661601de sprint_symbol +EXPORT_SYMBOL_GPL vmlinux 0x66298204 flush_workqueue +EXPORT_SYMBOL_GPL vmlinux 0x66615c98 scsi_flush_work +EXPORT_SYMBOL_GPL vmlinux 0x6682999f ata_host_detach +EXPORT_SYMBOL_GPL vmlinux 0x668402aa crypto_put_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x66b2a859 nr_free_buffer_pages +EXPORT_SYMBOL_GPL vmlinux 0x66d87d38 symbol_put_addr +EXPORT_SYMBOL_GPL vmlinux 0x67498885 ata_sas_port_alloc +EXPORT_SYMBOL_GPL vmlinux 0x67906f96 cpci_hp_register_bus +EXPORT_SYMBOL_GPL vmlinux 0x67955ce6 profile_hits +EXPORT_SYMBOL_GPL vmlinux 0x679aaeb7 ata_port_probe +EXPORT_SYMBOL_GPL vmlinux 0x67b55728 input_ff_destroy +EXPORT_SYMBOL_GPL vmlinux 0x67d6e188 vlan_dev_vlan_id +EXPORT_SYMBOL_GPL vmlinux 0x6830ae4a dm_rh_flush +EXPORT_SYMBOL_GPL vmlinux 0x685b8e90 put_pid +EXPORT_SYMBOL_GPL vmlinux 0x686c703f xfrm_count_auth_supported +EXPORT_SYMBOL_GPL vmlinux 0x6875d38c klist_next +EXPORT_SYMBOL_GPL vmlinux 0x68818bc6 firmware_kobj +EXPORT_SYMBOL_GPL vmlinux 0x688910fe crypto_hash_type +EXPORT_SYMBOL_GPL vmlinux 0x6892088c unregister_pm_notifier +EXPORT_SYMBOL_GPL vmlinux 0x68a8095b debugfs_create_bool +EXPORT_SYMBOL_GPL vmlinux 0x69349c63 schedule_hrtimeout_range +EXPORT_SYMBOL_GPL vmlinux 0x698d2ce7 sysdev_driver_register +EXPORT_SYMBOL_GPL vmlinux 0x69b2cb1d file_ra_state_init +EXPORT_SYMBOL_GPL vmlinux 0x69e9a2cb ata_scsi_slave_config +EXPORT_SYMBOL_GPL vmlinux 0x6a0c408d platform_device_register +EXPORT_SYMBOL_GPL vmlinux 0x6a323371 sysdev_class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x6a64e896 security_inode_permission +EXPORT_SYMBOL_GPL vmlinux 0x6a72f0c4 tracepoint_iter_stop +EXPORT_SYMBOL_GPL vmlinux 0x6a8441be cpci_hp_start +EXPORT_SYMBOL_GPL vmlinux 0x6ab4b51d find_get_pid +EXPORT_SYMBOL_GPL vmlinux 0x6af19b0e bus_get_kset +EXPORT_SYMBOL_GPL vmlinux 0x6afedc6d usb_lock_device_for_reset +EXPORT_SYMBOL_GPL vmlinux 0x6b899a51 cpci_hp_unregister_bus +EXPORT_SYMBOL_GPL vmlinux 0x6b8becf1 usb_reset_device +EXPORT_SYMBOL_GPL vmlinux 0x6b9178b3 xenbus_strstate +EXPORT_SYMBOL_GPL vmlinux 0x6b93bf60 inet_twdr_twkill_work +EXPORT_SYMBOL_GPL vmlinux 0x6ba6b5b6 sysdev_register +EXPORT_SYMBOL_GPL vmlinux 0x6bdd6118 hidinput_connect +EXPORT_SYMBOL_GPL vmlinux 0x6be62dfd probe_kernel_read +EXPORT_SYMBOL_GPL vmlinux 0x6c11059b __srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x6c3ee176 regulator_get +EXPORT_SYMBOL_GPL vmlinux 0x6c49c4f2 clockevents_notify +EXPORT_SYMBOL_GPL vmlinux 0x6c8d5ae8 __gpio_get_value +EXPORT_SYMBOL_GPL vmlinux 0x6d2fc5a6 net_namespace_list +EXPORT_SYMBOL_GPL vmlinux 0x6d431cd3 user_describe +EXPORT_SYMBOL_GPL vmlinux 0x6d622eab pci_cleanup_aer_uncorrect_error_status +EXPORT_SYMBOL_GPL vmlinux 0x6d9084cf dm_rh_recovery_in_flight +EXPORT_SYMBOL_GPL vmlinux 0x6d9f8efc transport_add_device +EXPORT_SYMBOL_GPL vmlinux 0x6dce94bf usb_bus_list_lock +EXPORT_SYMBOL_GPL vmlinux 0x6dda76cd usb_match_one_id +EXPORT_SYMBOL_GPL vmlinux 0x6df4aa40 fnotify_change +EXPORT_SYMBOL_GPL vmlinux 0x6e3f44d6 attribute_container_register +EXPORT_SYMBOL_GPL vmlinux 0x6e496159 inotify_destroy +EXPORT_SYMBOL_GPL vmlinux 0x6e58ddf0 gnttab_end_foreign_transfer_ref +EXPORT_SYMBOL_GPL vmlinux 0x6ea72a40 uv_bios_freq_base +EXPORT_SYMBOL_GPL vmlinux 0x6f10d668 crypto_mod_get +EXPORT_SYMBOL_GPL vmlinux 0x6f3823fa ata_eh_freeze_port +EXPORT_SYMBOL_GPL vmlinux 0x6f778210 debugfs_create_u32 +EXPORT_SYMBOL_GPL vmlinux 0x6f9c2efe marker_probe_cb +EXPORT_SYMBOL_GPL vmlinux 0x6faeaf2f dm_unregister_path_selector +EXPORT_SYMBOL_GPL vmlinux 0x6fbf8658 driver_find +EXPORT_SYMBOL_GPL vmlinux 0x6ff607b6 crypto_get_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x700d7d44 dev_attr_em_message_type +EXPORT_SYMBOL_GPL vmlinux 0x700f6109 preempt_notifier_unregister +EXPORT_SYMBOL_GPL vmlinux 0x701822d9 regulator_is_enabled +EXPORT_SYMBOL_GPL vmlinux 0x7024b387 ata_pci_sff_prepare_host +EXPORT_SYMBOL_GPL vmlinux 0x702a12cc klist_iter_init_node +EXPORT_SYMBOL_GPL vmlinux 0x7037d79d k8_flush_garts +EXPORT_SYMBOL_GPL vmlinux 0x706b3a33 cpufreq_frequency_table_get_attr +EXPORT_SYMBOL_GPL vmlinux 0x70724246 device_attach +EXPORT_SYMBOL_GPL vmlinux 0x707ff1bb ata_xfer_mask2mode +EXPORT_SYMBOL_GPL vmlinux 0x70a626fe ata_sff_host_intr +EXPORT_SYMBOL_GPL vmlinux 0x70b1479d ata_port_start +EXPORT_SYMBOL_GPL vmlinux 0x70c94321 usb_remove_hcd +EXPORT_SYMBOL_GPL vmlinux 0x71c8bc95 kgdb_unregister_io_module +EXPORT_SYMBOL_GPL vmlinux 0x720e2700 crypto_unregister_template +EXPORT_SYMBOL_GPL vmlinux 0x722c4f65 usb_scuttle_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x72598bb0 init_user_ns +EXPORT_SYMBOL_GPL vmlinux 0x7274f455 fib_rules_unregister +EXPORT_SYMBOL_GPL vmlinux 0x7278d328 all_vm_events +EXPORT_SYMBOL_GPL vmlinux 0x731433ee unregister_timer_hook +EXPORT_SYMBOL_GPL vmlinux 0x731b88ac ata_sff_exec_command +EXPORT_SYMBOL_GPL vmlinux 0x731dba7a xen_domain_type +EXPORT_SYMBOL_GPL vmlinux 0x7330b07b sata_link_debounce +EXPORT_SYMBOL_GPL vmlinux 0x73a48b4a ata_sff_std_ports +EXPORT_SYMBOL_GPL vmlinux 0x73a64601 platform_driver_register +EXPORT_SYMBOL_GPL vmlinux 0x73b1f76d do_posix_clock_nosettime +EXPORT_SYMBOL_GPL vmlinux 0x73ed13b0 usb_get_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x7420bff3 ata_sff_prereset +EXPORT_SYMBOL_GPL vmlinux 0x743a165e ata_pack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0x746a0649 spi_alloc_master +EXPORT_SYMBOL_GPL vmlinux 0x74abdafa task_handoff_register +EXPORT_SYMBOL_GPL vmlinux 0x74acd52f regulator_get_current_limit +EXPORT_SYMBOL_GPL vmlinux 0x74d61a4d get_dcookie +EXPORT_SYMBOL_GPL vmlinux 0x74f6ab8c tty_put_char +EXPORT_SYMBOL_GPL vmlinux 0x74fb4335 rtc_read_alarm +EXPORT_SYMBOL_GPL vmlinux 0x75010237 fb_deferred_io_cleanup +EXPORT_SYMBOL_GPL vmlinux 0x75030931 ata_port_abort +EXPORT_SYMBOL_GPL vmlinux 0x75141b4d class_interface_unregister +EXPORT_SYMBOL_GPL vmlinux 0x7521afb6 leave_mm +EXPORT_SYMBOL_GPL vmlinux 0x7534b389 regulator_unregister +EXPORT_SYMBOL_GPL vmlinux 0x7553f80d power_supply_changed +EXPORT_SYMBOL_GPL vmlinux 0x75e8f3c3 crypto_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x760247b9 ata_cable_40wire +EXPORT_SYMBOL_GPL vmlinux 0x762579ad cpufreq_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x7645e02b usb_driver_claim_interface +EXPORT_SYMBOL_GPL vmlinux 0x766c82cd inet6_csk_xmit +EXPORT_SYMBOL_GPL vmlinux 0x76deb589 ata_pci_sff_init_host +EXPORT_SYMBOL_GPL vmlinux 0x76e9f70a ata_sff_thaw +EXPORT_SYMBOL_GPL vmlinux 0x7712771a unbind_from_irqhandler +EXPORT_SYMBOL_GPL vmlinux 0x77457124 ip6_local_out +EXPORT_SYMBOL_GPL vmlinux 0x774fc39c __percpu_alloc_mask +EXPORT_SYMBOL_GPL vmlinux 0x776ee4c2 usb_buffer_unmap_sg +EXPORT_SYMBOL_GPL vmlinux 0x776f00ff ata_std_prereset +EXPORT_SYMBOL_GPL vmlinux 0x77b29e1b xenbus_unmap_ring +EXPORT_SYMBOL_GPL vmlinux 0x7804f40d klist_remove +EXPORT_SYMBOL_GPL vmlinux 0x7847ce38 platform_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x787bc159 regulator_bulk_get +EXPORT_SYMBOL_GPL vmlinux 0x788b847f pci_scan_child_bus +EXPORT_SYMBOL_GPL vmlinux 0x7890ca14 ata_timing_compute +EXPORT_SYMBOL_GPL vmlinux 0x78cfa717 dequeue_signal +EXPORT_SYMBOL_GPL vmlinux 0x792cefcb xfrm_audit_state_delete +EXPORT_SYMBOL_GPL vmlinux 0x797423ac klist_add_before +EXPORT_SYMBOL_GPL vmlinux 0x79d8cd2e d_obtain_alias +EXPORT_SYMBOL_GPL vmlinux 0x7a4c1438 pv_info +EXPORT_SYMBOL_GPL vmlinux 0x7a6cb59f class_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x7ac10ebc uv_node_to_blade +EXPORT_SYMBOL_GPL vmlinux 0x7ae1ae8e cpufreq_frequency_table_put_attr +EXPORT_SYMBOL_GPL vmlinux 0x7aed932a rt_mutex_timed_lock +EXPORT_SYMBOL_GPL vmlinux 0x7b0d1dc5 inet_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0x7b1d544d edac_handler_set +EXPORT_SYMBOL_GPL vmlinux 0x7b351ef0 usb_match_id +EXPORT_SYMBOL_GPL vmlinux 0x7b52d61c rtc_class_close +EXPORT_SYMBOL_GPL vmlinux 0x7b71cdc4 inet_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0x7c028a0e da903x_set_bits +EXPORT_SYMBOL_GPL vmlinux 0x7c605420 __sock_recv_timestamp +EXPORT_SYMBOL_GPL vmlinux 0x7c6d7605 blocking_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x7c9ca444 usb_serial_probe +EXPORT_SYMBOL_GPL vmlinux 0x7da8d037 marker_probe_register +EXPORT_SYMBOL_GPL vmlinux 0x7dc5d0b6 crypto_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x7dd10e55 vfs_setlease +EXPORT_SYMBOL_GPL vmlinux 0x7e275ea8 scsi_complete_async_scans +EXPORT_SYMBOL_GPL vmlinux 0x7e64181d usb_calc_bus_time +EXPORT_SYMBOL_GPL vmlinux 0x7f19c836 unlock_policy_rwsem_write +EXPORT_SYMBOL_GPL vmlinux 0x7f7092d4 blk_abort_request +EXPORT_SYMBOL_GPL vmlinux 0x7fa0854c relay_buf_full +EXPORT_SYMBOL_GPL vmlinux 0x7fcae6b9 regulator_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x7ff10ccf raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x8039d043 selinux_secmark_relabel_packet_permission +EXPORT_SYMBOL_GPL vmlinux 0x80450993 register_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0x806bcf08 usb_serial_disconnect +EXPORT_SYMBOL_GPL vmlinux 0x808ec1a3 crypto_alg_tested +EXPORT_SYMBOL_GPL vmlinux 0x80ee55c3 selinux_secmark_refcount_inc +EXPORT_SYMBOL_GPL vmlinux 0x81006c0f rdev_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x812c7fac hrtimer_try_to_cancel +EXPORT_SYMBOL_GPL vmlinux 0x8161605a blk_queue_dma_drain +EXPORT_SYMBOL_GPL vmlinux 0x81ecefef spi_register_master +EXPORT_SYMBOL_GPL vmlinux 0x821093a9 crypto_grab_skcipher +EXPORT_SYMBOL_GPL vmlinux 0x8226642f __gpio_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x826360fd do_posix_clock_nonanosleep +EXPORT_SYMBOL_GPL vmlinux 0x82a84117 __blkdev_driver_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x82cd19f3 register_xenstore_notifier +EXPORT_SYMBOL_GPL vmlinux 0x82d79b51 sysctl_vfs_cache_pressure +EXPORT_SYMBOL_GPL vmlinux 0x82f776b7 gpio_export +EXPORT_SYMBOL_GPL vmlinux 0x831e6780 device_rename +EXPORT_SYMBOL_GPL vmlinux 0x8361342c do_sync_mapping_range +EXPORT_SYMBOL_GPL vmlinux 0x83666f91 proc_net_mkdir +EXPORT_SYMBOL_GPL vmlinux 0x83b2e956 register_rfkill_notifier +EXPORT_SYMBOL_GPL vmlinux 0x83d94db0 inet_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0x83fab8d3 power_supply_unregister +EXPORT_SYMBOL_GPL vmlinux 0x8452dd8e bus_register +EXPORT_SYMBOL_GPL vmlinux 0x84834145 hrtimer_get_remaining +EXPORT_SYMBOL_GPL vmlinux 0x84bda7ab sdio_release_host +EXPORT_SYMBOL_GPL vmlinux 0x851f1bf0 usb_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0x85478a0b inet6_hash_frag +EXPORT_SYMBOL_GPL vmlinux 0x85781f58 ezusb_set_reset +EXPORT_SYMBOL_GPL vmlinux 0x85c10896 rcu_batches_completed_bh +EXPORT_SYMBOL_GPL vmlinux 0x85d7edfd hpet_set_periodic_freq +EXPORT_SYMBOL_GPL vmlinux 0x85e5a3db ktime_get_ts +EXPORT_SYMBOL_GPL vmlinux 0x85fdcf96 ata_dev_pair +EXPORT_SYMBOL_GPL vmlinux 0x8648f109 ezusb_writememory +EXPORT_SYMBOL_GPL vmlinux 0x864b4fe6 sata_scr_read +EXPORT_SYMBOL_GPL vmlinux 0x865ee09f tcp_is_cwnd_limited +EXPORT_SYMBOL_GPL vmlinux 0x86623fd7 notify_remote_via_irq +EXPORT_SYMBOL_GPL vmlinux 0x86765505 pci_test_config_bits +EXPORT_SYMBOL_GPL vmlinux 0x86772245 vfs_listxattr +EXPORT_SYMBOL_GPL vmlinux 0x86782f94 crypto_shoot_alg +EXPORT_SYMBOL_GPL vmlinux 0x867c684a setup_APIC_eilvt_ibs +EXPORT_SYMBOL_GPL vmlinux 0x868784cb __symbol_get +EXPORT_SYMBOL_GPL vmlinux 0x869d59be rtc_irq_register +EXPORT_SYMBOL_GPL vmlinux 0x86a51007 gnttab_end_foreign_transfer +EXPORT_SYMBOL_GPL vmlinux 0x86b1667d hwrng_unregister +EXPORT_SYMBOL_GPL vmlinux 0x86b552bd crypto_alg_lookup +EXPORT_SYMBOL_GPL vmlinux 0x86c722f8 rfkill_epo +EXPORT_SYMBOL_GPL vmlinux 0x871a9910 register_kprobes +EXPORT_SYMBOL_GPL vmlinux 0x8727384e rtnl_kill_links +EXPORT_SYMBOL_GPL vmlinux 0x873fbaea edac_atomic_assert_error +EXPORT_SYMBOL_GPL vmlinux 0x8766a2f6 k_handler +EXPORT_SYMBOL_GPL vmlinux 0x876d29f1 wmi_get_event_data +EXPORT_SYMBOL_GPL vmlinux 0x87754115 raw_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x87a0198b default_backing_dev_info +EXPORT_SYMBOL_GPL vmlinux 0x87bb040d aead_geniv_init +EXPORT_SYMBOL_GPL vmlinux 0x87cf96fb rtc_read_time +EXPORT_SYMBOL_GPL vmlinux 0x87f2cf3a blocking_notifier_chain_cond_register +EXPORT_SYMBOL_GPL vmlinux 0x880b189a __atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x8810ad5e crypto_xor +EXPORT_SYMBOL_GPL vmlinux 0x88115cfb rt_mutex_unlock +EXPORT_SYMBOL_GPL vmlinux 0x885142a6 nf_net_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x88806d6c ata_std_qc_defer +EXPORT_SYMBOL_GPL vmlinux 0x88f0db24 cancel_work_sync +EXPORT_SYMBOL_GPL vmlinux 0x891c3a42 crypto_enqueue_request +EXPORT_SYMBOL_GPL vmlinux 0x898b9854 ata_bus_reset +EXPORT_SYMBOL_GPL vmlinux 0x8999ab35 __rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x89ba353e blk_rq_cur_bytes +EXPORT_SYMBOL_GPL vmlinux 0x89d4dbaf usb_usual_check_type +EXPORT_SYMBOL_GPL vmlinux 0x8abed13d xfrm_aead_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x8add8105 ip_local_out +EXPORT_SYMBOL_GPL vmlinux 0x8af9b1ab tcp_reno_cong_avoid +EXPORT_SYMBOL_GPL vmlinux 0x8b1aab6a spi_sync +EXPORT_SYMBOL_GPL vmlinux 0x8b3fdfe1 crypto_spawn_tfm +EXPORT_SYMBOL_GPL vmlinux 0x8b752ac1 ata_tf_to_fis +EXPORT_SYMBOL_GPL vmlinux 0x8b9200fd lookup_address +EXPORT_SYMBOL_GPL vmlinux 0x8c06a108 xenbus_transaction_start +EXPORT_SYMBOL_GPL vmlinux 0x8c38074a unregister_xenstore_notifier +EXPORT_SYMBOL_GPL vmlinux 0x8c7eabaa generic_drop_inode +EXPORT_SYMBOL_GPL vmlinux 0x8cd24340 ata_port_disable +EXPORT_SYMBOL_GPL vmlinux 0x8cda2d21 ata_sff_tf_read +EXPORT_SYMBOL_GPL vmlinux 0x8ce0aeea tty_perform_flush +EXPORT_SYMBOL_GPL vmlinux 0x8d0f74f2 attribute_container_unregister +EXPORT_SYMBOL_GPL vmlinux 0x8d4c50a9 xenbus_map_ring +EXPORT_SYMBOL_GPL vmlinux 0x8d5ebc47 ata_bmdma_setup +EXPORT_SYMBOL_GPL vmlinux 0x8d7b62a2 ip_route_output_flow +EXPORT_SYMBOL_GPL vmlinux 0x8df31d69 input_ff_erase +EXPORT_SYMBOL_GPL vmlinux 0x8e4f7c7b dm_rh_recovery_start +EXPORT_SYMBOL_GPL vmlinux 0x8e7cbaf0 sysdev_class_register +EXPORT_SYMBOL_GPL vmlinux 0x8e8d86e8 bus_rescan_devices +EXPORT_SYMBOL_GPL vmlinux 0x8e95df0f cpuidle_disable_device +EXPORT_SYMBOL_GPL vmlinux 0x8eb58c6e __wake_up_sync +EXPORT_SYMBOL_GPL vmlinux 0x8ec3345b tty_get_pgrp +EXPORT_SYMBOL_GPL vmlinux 0x8f09ef7e ata_port_freeze +EXPORT_SYMBOL_GPL vmlinux 0x8f5fc2a0 fsstack_copy_inode_size +EXPORT_SYMBOL_GPL vmlinux 0x8f6cee77 __round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x8f819698 inverse_translate +EXPORT_SYMBOL_GPL vmlinux 0x8fbc0c9b regulator_set_voltage +EXPORT_SYMBOL_GPL vmlinux 0x8ffaa7a7 da903x_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x9009602a acpi_bus_get_ejd +EXPORT_SYMBOL_GPL vmlinux 0x90097289 usb_free_urb +EXPORT_SYMBOL_GPL vmlinux 0x900f4bbf dm_register_path_selector +EXPORT_SYMBOL_GPL vmlinux 0x9049c9c0 debugfs_remove +EXPORT_SYMBOL_GPL vmlinux 0x905f73ad xfrm_output_resume +EXPORT_SYMBOL_GPL vmlinux 0x906b805e srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x90a1004a crypto_has_alg +EXPORT_SYMBOL_GPL vmlinux 0x91482eef usb_anchor_empty +EXPORT_SYMBOL_GPL vmlinux 0x9159b9d6 profile_event_register +EXPORT_SYMBOL_GPL vmlinux 0x9193f762 disk_map_sector_rcu +EXPORT_SYMBOL_GPL vmlinux 0x91dacaa2 acpi_processor_ffh_cstate_probe +EXPORT_SYMBOL_GPL vmlinux 0x9215cb3d regulator_get_init_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x92183295 crypto_chain +EXPORT_SYMBOL_GPL vmlinux 0x9220ee73 rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x9241c3ee device_power_down +EXPORT_SYMBOL_GPL vmlinux 0x92445aee hrtimer_get_res +EXPORT_SYMBOL_GPL vmlinux 0x92542724 inotify_find_watch +EXPORT_SYMBOL_GPL vmlinux 0x928d1290 usb_autopm_get_interface +EXPORT_SYMBOL_GPL vmlinux 0x92946a1a vfs_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0x92bfb9dd sock_prot_inuse_get +EXPORT_SYMBOL_GPL vmlinux 0x92d20b43 raw_seq_open +EXPORT_SYMBOL_GPL vmlinux 0x92d31cfb fixed_phy_add +EXPORT_SYMBOL_GPL vmlinux 0x92e90d18 __mmu_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x92fb217b dcookie_unregister +EXPORT_SYMBOL_GPL vmlinux 0x935b3776 dm_rh_inc_pending +EXPORT_SYMBOL_GPL vmlinux 0x93755b89 regulator_get_voltage +EXPORT_SYMBOL_GPL vmlinux 0x937d164a rtc_update_irq +EXPORT_SYMBOL_GPL vmlinux 0x93843a06 pci_find_next_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0x93c0850e rt_mutex_destroy +EXPORT_SYMBOL_GPL vmlinux 0x93d2422d snmp_mib_free +EXPORT_SYMBOL_GPL vmlinux 0x93d4d74a __class_create +EXPORT_SYMBOL_GPL vmlinux 0x93f1254b cpufreq_freq_attr_scaling_available_freqs +EXPORT_SYMBOL_GPL vmlinux 0x93f83633 crypto_register_template +EXPORT_SYMBOL_GPL vmlinux 0x942c1704 cleanup_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x945ef9e8 cpufreq_unregister_governor +EXPORT_SYMBOL_GPL vmlinux 0x9481713a get_device +EXPORT_SYMBOL_GPL vmlinux 0x948b1b82 xfrm_audit_state_notfound_simple +EXPORT_SYMBOL_GPL vmlinux 0x948ecaf5 inet_unhash +EXPORT_SYMBOL_GPL vmlinux 0x94a68723 ata_scsi_slave_destroy +EXPORT_SYMBOL_GPL vmlinux 0x94dc62d2 ata_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x94ef4d05 cpci_hp_stop +EXPORT_SYMBOL_GPL vmlinux 0x951c26ae led_trigger_register_simple +EXPORT_SYMBOL_GPL vmlinux 0x952664c5 do_exit +EXPORT_SYMBOL_GPL vmlinux 0x95431980 inotify_inode_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x956a91ba gpio_get_value_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x9577271c hpet_rtc_interrupt +EXPORT_SYMBOL_GPL vmlinux 0x961a8cd3 unlock_policy_rwsem_read +EXPORT_SYMBOL_GPL vmlinux 0x964d5c39 acpi_os_map_memory +EXPORT_SYMBOL_GPL vmlinux 0x96cbcf31 pm_qos_add_notifier +EXPORT_SYMBOL_GPL vmlinux 0x97309c43 ata_acpi_gtm +EXPORT_SYMBOL_GPL vmlinux 0x9753573a vfs_getxattr +EXPORT_SYMBOL_GPL vmlinux 0x977f09c2 scsi_nl_add_transport +EXPORT_SYMBOL_GPL vmlinux 0x97d44d4d tty_ldisc_flush +EXPORT_SYMBOL_GPL vmlinux 0x9833bc0c hvc_kick +EXPORT_SYMBOL_GPL vmlinux 0x983646be rt_mutex_lock +EXPORT_SYMBOL_GPL vmlinux 0x98a62878 bus_create_file +EXPORT_SYMBOL_GPL vmlinux 0x98adb824 hrtimer_forward +EXPORT_SYMBOL_GPL vmlinux 0x991f3cb0 vfs_test_lock +EXPORT_SYMBOL_GPL vmlinux 0x9924c496 __usb_get_extra_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x992c011b __rt_mutex_init +EXPORT_SYMBOL_GPL vmlinux 0x995d1071 prof_on +EXPORT_SYMBOL_GPL vmlinux 0x99750e11 hidraw_connect +EXPORT_SYMBOL_GPL vmlinux 0x99856cbc debugfs_rename +EXPORT_SYMBOL_GPL vmlinux 0x999afee1 sysctl_pathname +EXPORT_SYMBOL_GPL vmlinux 0x9a11a0fc crypto_attr_alg_name +EXPORT_SYMBOL_GPL vmlinux 0x9a278ba2 __cpufreq_driver_target +EXPORT_SYMBOL_GPL vmlinux 0x9a398f5c xfrm_ealg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x9a4d1034 idle_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x9a711941 blk_execute_rq_nowait +EXPORT_SYMBOL_GPL vmlinux 0x9aa8d532 bd_release_from_disk +EXPORT_SYMBOL_GPL vmlinux 0x9abfe361 skcipher_geniv_exit +EXPORT_SYMBOL_GPL vmlinux 0x9ac12409 ata_do_dev_read_id +EXPORT_SYMBOL_GPL vmlinux 0x9ac8ef4a dm_rh_mark_nosync +EXPORT_SYMBOL_GPL vmlinux 0x9aec7588 inet_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0x9b63de24 scsi_queue_work +EXPORT_SYMBOL_GPL vmlinux 0x9b8a1454 tracepoint_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x9ba0501e unregister_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0x9bc9fcb2 ata_sff_dev_select +EXPORT_SYMBOL_GPL vmlinux 0x9bd37575 sdio_writel +EXPORT_SYMBOL_GPL vmlinux 0x9cb76733 ata_sff_hsm_move +EXPORT_SYMBOL_GPL vmlinux 0x9cb8037b xfrm_count_enc_supported +EXPORT_SYMBOL_GPL vmlinux 0x9cbe58b3 dm_set_device_limits +EXPORT_SYMBOL_GPL vmlinux 0x9d06688b register_xenbus_watch +EXPORT_SYMBOL_GPL vmlinux 0x9d118a8b xenbus_frontend_closed +EXPORT_SYMBOL_GPL vmlinux 0x9d2770bc __xenbus_register_frontend +EXPORT_SYMBOL_GPL vmlinux 0x9d3850e1 gnttab_alloc_grant_references +EXPORT_SYMBOL_GPL vmlinux 0x9d86a06d sync_page_io +EXPORT_SYMBOL_GPL vmlinux 0x9dcaa462 scsi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x9de5e149 devres_add +EXPORT_SYMBOL_GPL vmlinux 0x9dff3258 ata_sas_port_start +EXPORT_SYMBOL_GPL vmlinux 0x9e5f1d47 sdio_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x9e711ad2 pm_qos_requirement +EXPORT_SYMBOL_GPL vmlinux 0x9e7b7952 hrtimer_start +EXPORT_SYMBOL_GPL vmlinux 0x9e7d3442 xenbus_resume +EXPORT_SYMBOL_GPL vmlinux 0x9e7f3792 get_driver +EXPORT_SYMBOL_GPL vmlinux 0x9e9eab7c bd_claim_by_disk +EXPORT_SYMBOL_GPL vmlinux 0x9eb26852 regulator_put +EXPORT_SYMBOL_GPL vmlinux 0x9eb669ae debugfs_remove_recursive +EXPORT_SYMBOL_GPL vmlinux 0x9f628956 device_add +EXPORT_SYMBOL_GPL vmlinux 0x9fb5d63b sysdev_show_int +EXPORT_SYMBOL_GPL vmlinux 0x9fce80db fb_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x9ff7295f dev_attr_em_message +EXPORT_SYMBOL_GPL vmlinux 0xa00e7e6b crypto_register_instance +EXPORT_SYMBOL_GPL vmlinux 0xa0255440 net_ipv4_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0xa0343e0f crypto_larval_lookup +EXPORT_SYMBOL_GPL vmlinux 0xa038dd1c ata_sff_postreset +EXPORT_SYMBOL_GPL vmlinux 0xa03e4418 pskb_put +EXPORT_SYMBOL_GPL vmlinux 0xa0f8c4b3 ata_sas_port_init +EXPORT_SYMBOL_GPL vmlinux 0xa0ff5aac nf_unregister_queue_handlers +EXPORT_SYMBOL_GPL vmlinux 0xa1438b24 ata_sff_dma_pause +EXPORT_SYMBOL_GPL vmlinux 0xa1484057 ata_cable_ignore +EXPORT_SYMBOL_GPL vmlinux 0xa1569e89 sysfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0xa1596d98 acpi_processor_ffh_cstate_enter +EXPORT_SYMBOL_GPL vmlinux 0xa19d0bce xfrm_audit_state_notfound +EXPORT_SYMBOL_GPL vmlinux 0xa1e0d58a find_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0xa2245576 platform_device_alloc +EXPORT_SYMBOL_GPL vmlinux 0xa2422139 blk_update_request +EXPORT_SYMBOL_GPL vmlinux 0xa27c3443 ata_eh_analyze_ncq_error +EXPORT_SYMBOL_GPL vmlinux 0xa28d8527 usb_poison_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xa2c03841 bind_evtchn_to_irqhandler +EXPORT_SYMBOL_GPL vmlinux 0xa2e67f08 acpi_bus_generate_proc_event4 +EXPORT_SYMBOL_GPL vmlinux 0xa303d2b8 skb_pull_rcsum +EXPORT_SYMBOL_GPL vmlinux 0xa3421352 sysdev_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0xa353fffc xenbus_rm +EXPORT_SYMBOL_GPL vmlinux 0xa395ed45 sysfs_create_link +EXPORT_SYMBOL_GPL vmlinux 0xa3fc96f0 marker_probe_cb_noarg +EXPORT_SYMBOL_GPL vmlinux 0xa43a7887 inet6_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0xa452c297 hpet_mask_rtc_irq_bit +EXPORT_SYMBOL_GPL vmlinux 0xa480e2ed led_trigger_remove +EXPORT_SYMBOL_GPL vmlinux 0xa4d58669 math_state_restore +EXPORT_SYMBOL_GPL vmlinux 0xa50c7406 __ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0xa57112ec sdio_claim_host +EXPORT_SYMBOL_GPL vmlinux 0xa58c825c queue_delayed_work +EXPORT_SYMBOL_GPL vmlinux 0xa5905968 skcipher_geniv_init +EXPORT_SYMBOL_GPL vmlinux 0xa596f330 tracepoint_iter_start +EXPORT_SYMBOL_GPL vmlinux 0xa5bf5c3e pm_qos_add_requirement +EXPORT_SYMBOL_GPL vmlinux 0xa5c36cec inotify_unmount_inodes +EXPORT_SYMBOL_GPL vmlinux 0xa641de63 sysfs_chmod_file +EXPORT_SYMBOL_GPL vmlinux 0xa64ccd3d pv_apic_ops +EXPORT_SYMBOL_GPL vmlinux 0xa6777ff8 nf_unregister_afinfo +EXPORT_SYMBOL_GPL vmlinux 0xa681d3e4 debugfs_create_x16 +EXPORT_SYMBOL_GPL vmlinux 0xa6874c4d __get_vm_area +EXPORT_SYMBOL_GPL vmlinux 0xa68e8802 blk_trace_startstop +EXPORT_SYMBOL_GPL vmlinux 0xa6c31e2a get_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0xa6f4320d unregister_rfkill_notifier +EXPORT_SYMBOL_GPL vmlinux 0xa778271c inet6_lookup +EXPORT_SYMBOL_GPL vmlinux 0xa7c86791 crypto_blkcipher_type +EXPORT_SYMBOL_GPL vmlinux 0xa83d191c i2c_new_dummy +EXPORT_SYMBOL_GPL vmlinux 0xa854dce3 sdio_release_irq +EXPORT_SYMBOL_GPL vmlinux 0xa880c5e0 cpuidle_enable_device +EXPORT_SYMBOL_GPL vmlinux 0xa8bcb0c3 pci_unblock_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0xa8f1ab7d sata_pmp_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xa8f59416 gpio_direction_output +EXPORT_SYMBOL_GPL vmlinux 0xa9126bff hpet_set_rtc_irq_bit +EXPORT_SYMBOL_GPL vmlinux 0xa928204a ata_eh_qc_retry +EXPORT_SYMBOL_GPL vmlinux 0xa92c6424 pci_enable_rom +EXPORT_SYMBOL_GPL vmlinux 0xa93df210 pci_slots_kset +EXPORT_SYMBOL_GPL vmlinux 0xa963f49c tcp_orphan_count +EXPORT_SYMBOL_GPL vmlinux 0xa965d9d3 blk_rq_check_limits +EXPORT_SYMBOL_GPL vmlinux 0xa96e4b6e usb_buffer_map_sg +EXPORT_SYMBOL_GPL vmlinux 0xa988cdd5 dm_rh_delay +EXPORT_SYMBOL_GPL vmlinux 0xa9c2de28 inet_twsk_alloc +EXPORT_SYMBOL_GPL vmlinux 0xa9c530b8 unregister_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xa9c862e5 invalidate_inode_pages2 +EXPORT_SYMBOL_GPL vmlinux 0xa9cfcb95 ata_pci_sff_init_one +EXPORT_SYMBOL_GPL vmlinux 0xa9f271bb find_vpid +EXPORT_SYMBOL_GPL vmlinux 0xaa266d1c ata_std_bios_param +EXPORT_SYMBOL_GPL vmlinux 0xaa797cb0 pci_reset_function +EXPORT_SYMBOL_GPL vmlinux 0xaa86cfb5 uv_possible_blades +EXPORT_SYMBOL_GPL vmlinux 0xaa8c4696 cpu_clock +EXPORT_SYMBOL_GPL vmlinux 0xaa939143 rtnl_put_cacheinfo +EXPORT_SYMBOL_GPL vmlinux 0xaa9b096b register_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0xaa9c12ce ata_sff_freeze +EXPORT_SYMBOL_GPL vmlinux 0xaabe8903 mm_kobj +EXPORT_SYMBOL_GPL vmlinux 0xaadfa84a usb_unanchor_urb +EXPORT_SYMBOL_GPL vmlinux 0xab01acbe gnttab_request_free_callback +EXPORT_SYMBOL_GPL vmlinux 0xab4c3488 usb_sg_wait +EXPORT_SYMBOL_GPL vmlinux 0xab57e311 tracepoint_probe_register +EXPORT_SYMBOL_GPL vmlinux 0xabb566fc device_create +EXPORT_SYMBOL_GPL vmlinux 0xabf840a8 elv_unregister +EXPORT_SYMBOL_GPL vmlinux 0xac34813d pci_find_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0xac470458 cpci_hp_unregister_controller +EXPORT_SYMBOL_GPL vmlinux 0xac9d742d class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xacc19485 ibft_addr +EXPORT_SYMBOL_GPL vmlinux 0xace5c0fc usb_bus_list +EXPORT_SYMBOL_GPL vmlinux 0xad096363 xenbus_printf +EXPORT_SYMBOL_GPL vmlinux 0xad372144 part_round_stats +EXPORT_SYMBOL_GPL vmlinux 0xad46b724 rtc_set_mmss +EXPORT_SYMBOL_GPL vmlinux 0xad5bdeca pci_find_next_capability +EXPORT_SYMBOL_GPL vmlinux 0xad63a24e per_cpu____uv_hub_info +EXPORT_SYMBOL_GPL vmlinux 0xad6f414f crypto_aead_type +EXPORT_SYMBOL_GPL vmlinux 0xade5f8e0 sysdev_show_ulong +EXPORT_SYMBOL_GPL vmlinux 0xadf38d45 inotify_add_watch +EXPORT_SYMBOL_GPL vmlinux 0xae0c87ee pm_qos_remove_notifier +EXPORT_SYMBOL_GPL vmlinux 0xae1d8f2d generic_fh_to_dentry +EXPORT_SYMBOL_GPL vmlinux 0xae6e97c2 fl6_sock_lookup +EXPORT_SYMBOL_GPL vmlinux 0xae7dfbdc usb_set_interface +EXPORT_SYMBOL_GPL vmlinux 0xaeac662a cpufreq_register_driver +EXPORT_SYMBOL_GPL vmlinux 0xaee89436 skb_cow_data +EXPORT_SYMBOL_GPL vmlinux 0xaf7112f6 device_register +EXPORT_SYMBOL_GPL vmlinux 0xafc7c996 usb_unlink_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xb03bd622 usb_deregister +EXPORT_SYMBOL_GPL vmlinux 0xb07bc423 ata_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0xb0aa812e fips_enabled +EXPORT_SYMBOL_GPL vmlinux 0xb0de7d62 ata_std_postreset +EXPORT_SYMBOL_GPL vmlinux 0xb0eedea9 usb_wait_anchor_empty_timeout +EXPORT_SYMBOL_GPL vmlinux 0xb10d55bc cn_netlink_send +EXPORT_SYMBOL_GPL vmlinux 0xb1982c21 crypto_free_tfm +EXPORT_SYMBOL_GPL vmlinux 0xb1acbcce rcu_barrier_sched +EXPORT_SYMBOL_GPL vmlinux 0xb1d1d4de usb_put_hcd +EXPORT_SYMBOL_GPL vmlinux 0xb27005f5 device_suspend +EXPORT_SYMBOL_GPL vmlinux 0xb2ad79c5 crypto_lookup_template +EXPORT_SYMBOL_GPL vmlinux 0xb2b9bc64 alloc_vm_area +EXPORT_SYMBOL_GPL vmlinux 0xb3253ed9 hpet_rtc_timer_init +EXPORT_SYMBOL_GPL vmlinux 0xb390832b dm_rh_region_to_sector +EXPORT_SYMBOL_GPL vmlinux 0xb3c7da52 usb_poison_urb +EXPORT_SYMBOL_GPL vmlinux 0xb3d5e527 acpi_smbus_write +EXPORT_SYMBOL_GPL vmlinux 0xb44f07a1 usb_hcd_link_urb_to_ep +EXPORT_SYMBOL_GPL vmlinux 0xb4af05f6 debugfs_create_x8 +EXPORT_SYMBOL_GPL vmlinux 0xb4da3a51 dma_get_required_mask +EXPORT_SYMBOL_GPL vmlinux 0xb4e14553 gnttab_query_foreign_access +EXPORT_SYMBOL_GPL vmlinux 0xb4ea7cf7 kgdb_connected +EXPORT_SYMBOL_GPL vmlinux 0xb4fe6005 bus_find_device_by_name +EXPORT_SYMBOL_GPL vmlinux 0xb51fbd64 edac_op_state +EXPORT_SYMBOL_GPL vmlinux 0xb53ae573 cpu_idle_wait +EXPORT_SYMBOL_GPL vmlinux 0xb5a6ebe2 wmi_remove_notify_handler +EXPORT_SYMBOL_GPL vmlinux 0xb5eb38c2 device_create_file +EXPORT_SYMBOL_GPL vmlinux 0xb612444d snmp_mib_init +EXPORT_SYMBOL_GPL vmlinux 0xb61ad05f register_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0xb6230f1f gnttab_grant_foreign_access +EXPORT_SYMBOL_GPL vmlinux 0xb6296082 usb_get_status +EXPORT_SYMBOL_GPL vmlinux 0xb631e26a cpufreq_driver_target +EXPORT_SYMBOL_GPL vmlinux 0xb63550f5 __i2c_board_lock +EXPORT_SYMBOL_GPL vmlinux 0xb65091b3 selinux_secmark_refcount_dec +EXPORT_SYMBOL_GPL vmlinux 0xb6aeb661 ata_id_c_string +EXPORT_SYMBOL_GPL vmlinux 0xb7b9ba01 scsi_dh_attach +EXPORT_SYMBOL_GPL vmlinux 0xb7d7c12e hpet_set_alarm_time +EXPORT_SYMBOL_GPL vmlinux 0xb827c653 ata_std_error_handler +EXPORT_SYMBOL_GPL vmlinux 0xb836264b inet_hash +EXPORT_SYMBOL_GPL vmlinux 0xb842724c cpuidle_register_device +EXPORT_SYMBOL_GPL vmlinux 0xb8452387 do_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0xb89ac110 scsi_internal_device_block +EXPORT_SYMBOL_GPL vmlinux 0xb89bd016 ata_sff_busy_sleep +EXPORT_SYMBOL_GPL vmlinux 0xb903674c scatterwalk_map_and_copy +EXPORT_SYMBOL_GPL vmlinux 0xb92b16ba dm_region_hash_create +EXPORT_SYMBOL_GPL vmlinux 0xb93f8d40 ip6_dst_lookup +EXPORT_SYMBOL_GPL vmlinux 0xb96fe7f8 usb_init_urb +EXPORT_SYMBOL_GPL vmlinux 0xb99d5837 xenbus_read +EXPORT_SYMBOL_GPL vmlinux 0xb9c3a6a9 platform_device_add_data +EXPORT_SYMBOL_GPL vmlinux 0xb9eb3aa9 add_uevent_var +EXPORT_SYMBOL_GPL vmlinux 0xba786f29 md_do_sync +EXPORT_SYMBOL_GPL vmlinux 0xbae34c27 scsi_nl_remove_transport +EXPORT_SYMBOL_GPL vmlinux 0xbafc3fc2 da903x_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0xbb29d2c6 inet_csk_get_port +EXPORT_SYMBOL_GPL vmlinux 0xbb3318c9 usb_hcd_pci_shutdown +EXPORT_SYMBOL_GPL vmlinux 0xbb3d9e45 d_materialise_unique +EXPORT_SYMBOL_GPL vmlinux 0xbbae5e95 usb_driver_release_interface +EXPORT_SYMBOL_GPL vmlinux 0xbbb98859 edid_info +EXPORT_SYMBOL_GPL vmlinux 0xbbd4d910 hidraw_disconnect +EXPORT_SYMBOL_GPL vmlinux 0xbc0362a4 i2c_new_probed_device +EXPORT_SYMBOL_GPL vmlinux 0xbc8d4732 sock_prot_inuse_add +EXPORT_SYMBOL_GPL vmlinux 0xbcfb76b5 regulator_bulk_free +EXPORT_SYMBOL_GPL vmlinux 0xbd236675 dm_rh_get_region_size +EXPORT_SYMBOL_GPL vmlinux 0xbd25a9e8 device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xbd506a46 unregister_hotplug_dock_device +EXPORT_SYMBOL_GPL vmlinux 0xbd7387a6 driver_create_file +EXPORT_SYMBOL_GPL vmlinux 0xbd7bda4c register_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0xbd952066 register_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0xbdd295f0 trace_vprintk +EXPORT_SYMBOL_GPL vmlinux 0xbde5e56e transport_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0xbdeff290 inet_ctl_sock_create +EXPORT_SYMBOL_GPL vmlinux 0xbe1887e4 ata_unpack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xbe214d59 platform_device_register_simple +EXPORT_SYMBOL_GPL vmlinux 0xbe4668ed ata_sff_pause +EXPORT_SYMBOL_GPL vmlinux 0xbe4c0a45 dm_path_uevent +EXPORT_SYMBOL_GPL vmlinux 0xbe685641 dev_attr_sw_activity +EXPORT_SYMBOL_GPL vmlinux 0xbe7e9e95 usb_buffer_alloc +EXPORT_SYMBOL_GPL vmlinux 0xbeb14728 debugfs_create_u8 +EXPORT_SYMBOL_GPL vmlinux 0xbeb161fa usb_interrupt_msg +EXPORT_SYMBOL_GPL vmlinux 0xbeb3dfae transport_setup_device +EXPORT_SYMBOL_GPL vmlinux 0xbf74eb20 probe_kernel_write +EXPORT_SYMBOL_GPL vmlinux 0xbfbc456a disk_part_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0xbfbeb44a i2c_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xc00c8f8d swiotlb_sync_single_range_for_device +EXPORT_SYMBOL_GPL vmlinux 0xc03c74f5 xfrm_inner_extract_output +EXPORT_SYMBOL_GPL vmlinux 0xc041ab3a vfs_cancel_lock +EXPORT_SYMBOL_GPL vmlinux 0xc0ca9071 shmem_file_setup +EXPORT_SYMBOL_GPL vmlinux 0xc17515d7 usb_hcds_loaded +EXPORT_SYMBOL_GPL vmlinux 0xc196a571 ip6_dst_blackhole +EXPORT_SYMBOL_GPL vmlinux 0xc1a86893 cpufreq_frequency_table_target +EXPORT_SYMBOL_GPL vmlinux 0xc2083518 class_interface_register +EXPORT_SYMBOL_GPL vmlinux 0xc22a3091 vm_unmap_aliases +EXPORT_SYMBOL_GPL vmlinux 0xc2485e93 rtc_device_register +EXPORT_SYMBOL_GPL vmlinux 0xc26351f8 bind_evtchn_to_irq +EXPORT_SYMBOL_GPL vmlinux 0xc28d73a2 ata_bmdma_start +EXPORT_SYMBOL_GPL vmlinux 0xc295e93e i2c_unregister_device +EXPORT_SYMBOL_GPL vmlinux 0xc2beeb74 scsi_unregister_device_handler +EXPORT_SYMBOL_GPL vmlinux 0xc2fb2b59 hwmon_device_register +EXPORT_SYMBOL_GPL vmlinux 0xc310fd2d blk_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0xc34efe27 snmp_fold_field +EXPORT_SYMBOL_GPL vmlinux 0xc3887ccf sdio_memcpy_fromio +EXPORT_SYMBOL_GPL vmlinux 0xc399468f scsi_nl_remove_driver +EXPORT_SYMBOL_GPL vmlinux 0xc408b2d1 scsi_eh_ready_devs +EXPORT_SYMBOL_GPL vmlinux 0xc41b487b kset_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0xc428068d sata_deb_timing_long +EXPORT_SYMBOL_GPL vmlinux 0xc42f2f94 xenbus_read_driver_state +EXPORT_SYMBOL_GPL vmlinux 0xc42f91e0 sysdev_store_ulong +EXPORT_SYMBOL_GPL vmlinux 0xc44aa88f __inet_inherit_port +EXPORT_SYMBOL_GPL vmlinux 0xc4568cce dm_rh_bio_to_region +EXPORT_SYMBOL_GPL vmlinux 0xc462dc12 user_instantiate +EXPORT_SYMBOL_GPL vmlinux 0xc48b7ccf ata_mode_string +EXPORT_SYMBOL_GPL vmlinux 0xc49facc7 ata_pci_bmdma_clear_simplex +EXPORT_SYMBOL_GPL vmlinux 0xc4a85741 cpuidle_unregister_device +EXPORT_SYMBOL_GPL vmlinux 0xc4b33aa6 tracepoint_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc4c552d7 stop_machine +EXPORT_SYMBOL_GPL vmlinux 0xc4ce6189 idle_notifier_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc512626a __supported_pte_mask +EXPORT_SYMBOL_GPL vmlinux 0xc5397da6 xenbus_mkdir +EXPORT_SYMBOL_GPL vmlinux 0xc54bd4d7 power_supply_am_i_supplied +EXPORT_SYMBOL_GPL vmlinux 0xc54ffd6d sysfs_get_dirent +EXPORT_SYMBOL_GPL vmlinux 0xc56e129b regulator_set_optimum_mode +EXPORT_SYMBOL_GPL vmlinux 0xc5834e90 drop_file_write_access +EXPORT_SYMBOL_GPL vmlinux 0xc5a4fbd0 ata_pio_need_iordy +EXPORT_SYMBOL_GPL vmlinux 0xc6041916 dm_put +EXPORT_SYMBOL_GPL vmlinux 0xc62c8e0f copy_fs_struct +EXPORT_SYMBOL_GPL vmlinux 0xc64006aa __mmdrop +EXPORT_SYMBOL_GPL vmlinux 0xc6730fc2 klist_iter_init +EXPORT_SYMBOL_GPL vmlinux 0xc673e23e ata_scsi_change_queue_depth +EXPORT_SYMBOL_GPL vmlinux 0xc6a6bf0e sata_pmp_qc_defer_cmd_switch +EXPORT_SYMBOL_GPL vmlinux 0xc719de28 usb_register_dev +EXPORT_SYMBOL_GPL vmlinux 0xc71a1b01 sk_setup_caps +EXPORT_SYMBOL_GPL vmlinux 0xc7395d43 crypto_unregister_alg +EXPORT_SYMBOL_GPL vmlinux 0xc74ffc80 hid_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0xc7504484 tracepoint_get_iter_range +EXPORT_SYMBOL_GPL vmlinux 0xc77bbc73 cpufreq_frequency_table_verify +EXPORT_SYMBOL_GPL vmlinux 0xc7aaec22 spi_write_then_read +EXPORT_SYMBOL_GPL vmlinux 0xc7ec11f6 atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xc80881c5 crypto_ablkcipher_type +EXPORT_SYMBOL_GPL vmlinux 0xc87c1f84 ktime_get +EXPORT_SYMBOL_GPL vmlinux 0xc87e487a sched_clock_idle_sleep_event +EXPORT_SYMBOL_GPL vmlinux 0xc89cb625 inet_csk_reqsk_queue_prune +EXPORT_SYMBOL_GPL vmlinux 0xc8c49291 ata_bmdma_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xc8ea1705 sysfs_remove_group +EXPORT_SYMBOL_GPL vmlinux 0xc94846ff usb_alloc_urb +EXPORT_SYMBOL_GPL vmlinux 0xc94d8c75 pcie_port_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xc955780f pci_bus_max_busnr +EXPORT_SYMBOL_GPL vmlinux 0xc9561772 fb_destroy_modelist +EXPORT_SYMBOL_GPL vmlinux 0xc9d2b99d driver_find_device +EXPORT_SYMBOL_GPL vmlinux 0xc9d4d6d1 wmi_has_guid +EXPORT_SYMBOL_GPL vmlinux 0xca81ea9a xenbus_transaction_end +EXPORT_SYMBOL_GPL vmlinux 0xcabe04de cpuidle_resume_and_unlock +EXPORT_SYMBOL_GPL vmlinux 0xcacd0328 usb_store_new_id +EXPORT_SYMBOL_GPL vmlinux 0xcb016909 unregister_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0xcb0f85f3 __blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0xcb80ff98 ata_sg_init +EXPORT_SYMBOL_GPL vmlinux 0xcbb08ab4 __inet_hash_nolisten +EXPORT_SYMBOL_GPL vmlinux 0xcc018d9c register_kprobe +EXPORT_SYMBOL_GPL vmlinux 0xcc131ad2 usb_hcd_check_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0xcc1f1c3d inet_twdr_hangman +EXPORT_SYMBOL_GPL vmlinux 0xcc3d7311 ata_sff_dumb_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0xcc6ab305 is_dock_device +EXPORT_SYMBOL_GPL vmlinux 0xcc9b23db skb_morph +EXPORT_SYMBOL_GPL vmlinux 0xccb1569d raw_unhash_sk +EXPORT_SYMBOL_GPL vmlinux 0xcccfb2fa sata_deb_timing_hotplug +EXPORT_SYMBOL_GPL vmlinux 0xcccfe12d mnt_want_write +EXPORT_SYMBOL_GPL vmlinux 0xcd0d72f7 register_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0xcd7fd1c8 key_type_user +EXPORT_SYMBOL_GPL vmlinux 0xcd9991a9 usb_usual_set_present +EXPORT_SYMBOL_GPL vmlinux 0xcda06d2e spi_alloc_device +EXPORT_SYMBOL_GPL vmlinux 0xcdc65197 tcp_reno_ssthresh +EXPORT_SYMBOL_GPL vmlinux 0xcdca3691 nr_irqs +EXPORT_SYMBOL_GPL vmlinux 0xce1f9baf usb_hc_died +EXPORT_SYMBOL_GPL vmlinux 0xcfcc83ad register_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0xcfd86dff usb_register_device_driver +EXPORT_SYMBOL_GPL vmlinux 0xd027a07d marker_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xd03c7700 secure_ipv4_port_ephemeral +EXPORT_SYMBOL_GPL vmlinux 0xd074f1e6 class_dev_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0xd0755a62 inet6_sk_rebuild_header +EXPORT_SYMBOL_GPL vmlinux 0xd0c05159 emergency_restart +EXPORT_SYMBOL_GPL vmlinux 0xd0d342a1 smp_ops +EXPORT_SYMBOL_GPL vmlinux 0xd0fe474f register_net_sysctl_rotable +EXPORT_SYMBOL_GPL vmlinux 0xd10a8a02 crypto_aead_setauthsize +EXPORT_SYMBOL_GPL vmlinux 0xd11df9db device_find_child +EXPORT_SYMBOL_GPL vmlinux 0xd129e5da ata_sas_slave_configure +EXPORT_SYMBOL_GPL vmlinux 0xd15ae16a ata_do_eh +EXPORT_SYMBOL_GPL vmlinux 0xd16712f3 crypto_check_attr_type +EXPORT_SYMBOL_GPL vmlinux 0xd1ce26aa device_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xd1fb4606 put_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0xd273b1b1 __round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xd2a8caf0 work_on_cpu +EXPORT_SYMBOL_GPL vmlinux 0xd2d121cd simple_attr_release +EXPORT_SYMBOL_GPL vmlinux 0xd2d9ba67 ata_sff_post_internal_cmd +EXPORT_SYMBOL_GPL vmlinux 0xd2f7f54c blk_queue_rq_timed_out +EXPORT_SYMBOL_GPL vmlinux 0xd3363284 hidinput_report_event +EXPORT_SYMBOL_GPL vmlinux 0xd371d730 ip6_sk_dst_lookup +EXPORT_SYMBOL_GPL vmlinux 0xd39d813f led_trigger_register +EXPORT_SYMBOL_GPL vmlinux 0xd3b78da3 xenbus_suspend_cancel +EXPORT_SYMBOL_GPL vmlinux 0xd3caf79d devres_remove_group +EXPORT_SYMBOL_GPL vmlinux 0xd4889861 ata_eh_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0xd48d0359 sysfs_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xd4ce5807 usb_mon_register +EXPORT_SYMBOL_GPL vmlinux 0xd5048499 relay_close +EXPORT_SYMBOL_GPL vmlinux 0xd58b776f sk_clone +EXPORT_SYMBOL_GPL vmlinux 0xd5d9d5f4 regulator_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0xd60c6ecf sdio_writesb +EXPORT_SYMBOL_GPL vmlinux 0xd6869ca1 inet_csk_listen_stop +EXPORT_SYMBOL_GPL vmlinux 0xd6c026d6 xenbus_dev_error +EXPORT_SYMBOL_GPL vmlinux 0xd6feefa5 agp_num_entries +EXPORT_SYMBOL_GPL vmlinux 0xd7207011 uhci_check_and_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0xd76c42a5 pci_find_ext_capability +EXPORT_SYMBOL_GPL vmlinux 0xd789ac1f blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0xd7b5a61e scsi_dh_detach +EXPORT_SYMBOL_GPL vmlinux 0xd7d79132 put_online_cpus +EXPORT_SYMBOL_GPL vmlinux 0xd81192d1 da903x_update +EXPORT_SYMBOL_GPL vmlinux 0xd82e0f23 pciserial_remove_ports +EXPORT_SYMBOL_GPL vmlinux 0xd830b79f sysfs_create_group +EXPORT_SYMBOL_GPL vmlinux 0xd839375e tcp_init_congestion_ops +EXPORT_SYMBOL_GPL vmlinux 0xd84cd7f4 ata_timing_find_mode +EXPORT_SYMBOL_GPL vmlinux 0xd8d30719 xenbus_grant_ring +EXPORT_SYMBOL_GPL vmlinux 0xd8f554ad pci_disable_pcie_error_reporting +EXPORT_SYMBOL_GPL vmlinux 0xd9042fa8 scatterwalk_map +EXPORT_SYMBOL_GPL vmlinux 0xd95f1389 inet6_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0xd9e77cd4 ata_noop_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0xd9f3ff29 agp_add_bridge +EXPORT_SYMBOL_GPL vmlinux 0xda0b72bd regulator_bulk_disable +EXPORT_SYMBOL_GPL vmlinux 0xda29f8b0 wmi_set_block +EXPORT_SYMBOL_GPL vmlinux 0xda3f53a8 pciserial_resume_ports +EXPORT_SYMBOL_GPL vmlinux 0xda476b19 fb_deferred_io_fsync +EXPORT_SYMBOL_GPL vmlinux 0xda9495d9 ata_port_desc +EXPORT_SYMBOL_GPL vmlinux 0xdab1c10e init_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0xdad5c012 usb_ep0_reinit +EXPORT_SYMBOL_GPL vmlinux 0xdaf4dfb3 fb_mode_option +EXPORT_SYMBOL_GPL vmlinux 0xdb232c36 register_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0xdc1f8f2e register_timer_hook +EXPORT_SYMBOL_GPL vmlinux 0xdc5dfdc4 relay_file_operations +EXPORT_SYMBOL_GPL vmlinux 0xdc94bd29 xenbus_unmap_ring_vfree +EXPORT_SYMBOL_GPL vmlinux 0xdd19eb31 usb_put_dev +EXPORT_SYMBOL_GPL vmlinux 0xdd2f37c8 unregister_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0xdd45195a ata_base_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xdd5c4942 srcu_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0xdd8a6d24 acpi_get_hp_params_from_firmware +EXPORT_SYMBOL_GPL vmlinux 0xddae4360 usb_unpoison_urb +EXPORT_SYMBOL_GPL vmlinux 0xdde785f1 ata_pci_device_do_resume +EXPORT_SYMBOL_GPL vmlinux 0xde134c69 storage_usb_ids +EXPORT_SYMBOL_GPL vmlinux 0xde63aa9f scsi_mode_select +EXPORT_SYMBOL_GPL vmlinux 0xdec38cd4 transport_remove_device +EXPORT_SYMBOL_GPL vmlinux 0xdeca70c3 usb_hcd_resume_root_hub +EXPORT_SYMBOL_GPL vmlinux 0xdede6812 destroy_workqueue +EXPORT_SYMBOL_GPL vmlinux 0xdf2fa99d md_allow_write +EXPORT_SYMBOL_GPL vmlinux 0xdf3022b2 ata_sff_interrupt +EXPORT_SYMBOL_GPL vmlinux 0xdf3c19ec cn_add_callback +EXPORT_SYMBOL_GPL vmlinux 0xe04b2c82 inet_csk_listen_start +EXPORT_SYMBOL_GPL vmlinux 0xe089cfcc agp_memory_reserved +EXPORT_SYMBOL_GPL vmlinux 0xe0ab448b unregister_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0xe0ef923b led_trigger_set_default +EXPORT_SYMBOL_GPL vmlinux 0xe0fd3846 pci_create_slot +EXPORT_SYMBOL_GPL vmlinux 0xe1451295 dm_region_hash_destroy +EXPORT_SYMBOL_GPL vmlinux 0xe15e0574 scsi_nl_sock +EXPORT_SYMBOL_GPL vmlinux 0xe15e245b scsi_target_block +EXPORT_SYMBOL_GPL vmlinux 0xe193f9a5 xfrm_audit_policy_delete +EXPORT_SYMBOL_GPL vmlinux 0xe1a3f63d get_task_mm +EXPORT_SYMBOL_GPL vmlinux 0xe1ba34c0 __crypto_alloc_tfm +EXPORT_SYMBOL_GPL vmlinux 0xe1ea1e1e sata_std_hardreset +EXPORT_SYMBOL_GPL vmlinux 0xe2185511 ata_pci_sff_activate_host +EXPORT_SYMBOL_GPL vmlinux 0xe2437c3c tcp_unregister_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0xe24ff917 blocking_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0xe276e657 gpiochip_add +EXPORT_SYMBOL_GPL vmlinux 0xe295c0ff is_hpet_enabled +EXPORT_SYMBOL_GPL vmlinux 0xe2cc626b device_del +EXPORT_SYMBOL_GPL vmlinux 0xe2cd352e bus_sort_breadthfirst +EXPORT_SYMBOL_GPL vmlinux 0xe2deb514 ata_host_resume +EXPORT_SYMBOL_GPL vmlinux 0xe2ed12bf sata_scr_valid +EXPORT_SYMBOL_GPL vmlinux 0xe30c1c14 inotify_dentry_parent_queue_event +EXPORT_SYMBOL_GPL vmlinux 0xe31a1333 dm_rh_start_recovery +EXPORT_SYMBOL_GPL vmlinux 0xe325df3a scsi_internal_device_unblock +EXPORT_SYMBOL_GPL vmlinux 0xe339bc6c inotify_init_watch +EXPORT_SYMBOL_GPL vmlinux 0xe34358a0 spi_unregister_master +EXPORT_SYMBOL_GPL vmlinux 0xe39f7d37 skb_segment +EXPORT_SYMBOL_GPL vmlinux 0xe3b5f581 device_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xe3c771d3 crypto_givcipher_type +EXPORT_SYMBOL_GPL vmlinux 0xe3e69990 attribute_container_classdev_to_container +EXPORT_SYMBOL_GPL vmlinux 0xe3edf30b tty_prepare_flip_string_flags +EXPORT_SYMBOL_GPL vmlinux 0xe3feb972 pci_block_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0xe40c1aa9 free_vm_area +EXPORT_SYMBOL_GPL vmlinux 0xe42a11fe ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0xe45d412c regulator_set_mode +EXPORT_SYMBOL_GPL vmlinux 0xe46c5f15 relay_flush +EXPORT_SYMBOL_GPL vmlinux 0xe48d5eac acpi_ec_add_query_handler +EXPORT_SYMBOL_GPL vmlinux 0xe492360a da903x_clr_bits +EXPORT_SYMBOL_GPL vmlinux 0xe498ca38 scsi_register_device_handler +EXPORT_SYMBOL_GPL vmlinux 0xe49ff3b0 ata_wait_register +EXPORT_SYMBOL_GPL vmlinux 0xe4c65520 tcp_set_state +EXPORT_SYMBOL_GPL vmlinux 0xe513afc0 cache_k8_northbridges +EXPORT_SYMBOL_GPL vmlinux 0xe52c0d40 bus_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xe530071c pm_qos_remove_requirement +EXPORT_SYMBOL_GPL vmlinux 0xe56b2181 tcp_twsk_destructor +EXPORT_SYMBOL_GPL vmlinux 0xe57affff unregister_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0xe6024e4b set_cpus_allowed_ptr +EXPORT_SYMBOL_GPL vmlinux 0xe61a6d2f gpio_unexport +EXPORT_SYMBOL_GPL vmlinux 0xe640f211 hid_connect +EXPORT_SYMBOL_GPL vmlinux 0xe6488b47 cpufreq_notify_transition +EXPORT_SYMBOL_GPL vmlinux 0xe674a5cb srcu_read_lock +EXPORT_SYMBOL_GPL vmlinux 0xe67f6ede usb_find_interface +EXPORT_SYMBOL_GPL vmlinux 0xe68df6cd ata_common_sdev_attrs +EXPORT_SYMBOL_GPL vmlinux 0xe7169caf blkcipher_walk_virt_block +EXPORT_SYMBOL_GPL vmlinux 0xe75382b6 bus_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0xe75e4dad pciserial_suspend_ports +EXPORT_SYMBOL_GPL vmlinux 0xe7a7865a sdio_f0_readb +EXPORT_SYMBOL_GPL vmlinux 0xe7fa47ad srcu_read_unlock +EXPORT_SYMBOL_GPL vmlinux 0xe81af31a crypto_alg_sem +EXPORT_SYMBOL_GPL vmlinux 0xe81e4023 debugfs_create_x32 +EXPORT_SYMBOL_GPL vmlinux 0xe839a91e ata_acpi_gtm_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xe8448267 platform_get_resource_byname +EXPORT_SYMBOL_GPL vmlinux 0xe881eacc dm_send_uevents +EXPORT_SYMBOL_GPL vmlinux 0xe8b259b6 securityfs_remove +EXPORT_SYMBOL_GPL vmlinux 0xe8d004ce uart_set_options +EXPORT_SYMBOL_GPL vmlinux 0xe8e62adf seq_open_net +EXPORT_SYMBOL_GPL vmlinux 0xe8f9dfaf uv_cpu_to_blade +EXPORT_SYMBOL_GPL vmlinux 0xe91b66aa ata_sff_wait_ready +EXPORT_SYMBOL_GPL vmlinux 0xe93e49c3 devres_free +EXPORT_SYMBOL_GPL vmlinux 0xe957bd4e sdio_f0_writeb +EXPORT_SYMBOL_GPL vmlinux 0xe9587909 usb_unregister_notify +EXPORT_SYMBOL_GPL vmlinux 0xe9baec81 blk_end_request_callback +EXPORT_SYMBOL_GPL vmlinux 0xe9ce504f cpufreq_frequency_table_cpuinfo +EXPORT_SYMBOL_GPL vmlinux 0xe9d84865 sysfs_notify_dirent +EXPORT_SYMBOL_GPL vmlinux 0xe9de9970 usb_string +EXPORT_SYMBOL_GPL vmlinux 0xe9e3a809 ata_host_init +EXPORT_SYMBOL_GPL vmlinux 0xea065e01 task_handoff_unregister +EXPORT_SYMBOL_GPL vmlinux 0xea418e0f atapi_cmd_type +EXPORT_SYMBOL_GPL vmlinux 0xea7e21b9 sysdev_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xeae74760 scsi_nl_send_transport_msg +EXPORT_SYMBOL_GPL vmlinux 0xeb1c3908 page_cache_sync_readahead +EXPORT_SYMBOL_GPL vmlinux 0xeb55ca25 platform_device_put +EXPORT_SYMBOL_GPL vmlinux 0xec1b043e regulator_suspend_prepare +EXPORT_SYMBOL_GPL vmlinux 0xec207697 tcp_done +EXPORT_SYMBOL_GPL vmlinux 0xec46fd91 ata_dummy_port_info +EXPORT_SYMBOL_GPL vmlinux 0xecddb118 __create_workqueue_key +EXPORT_SYMBOL_GPL vmlinux 0xecde29bb pci_hp_change_slot_info +EXPORT_SYMBOL_GPL vmlinux 0xecdf6149 simple_attr_read +EXPORT_SYMBOL_GPL vmlinux 0xed0690a5 ehci_cf_port_reset_rwsem +EXPORT_SYMBOL_GPL vmlinux 0xed411831 dm_disk +EXPORT_SYMBOL_GPL vmlinux 0xed54d3c0 platform_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xeda9c35f apply_to_page_range +EXPORT_SYMBOL_GPL vmlinux 0xedbc6f67 gnttab_end_foreign_access +EXPORT_SYMBOL_GPL vmlinux 0xeddfea5d fb_deferred_io_init +EXPORT_SYMBOL_GPL vmlinux 0xedf15345 ata_host_start +EXPORT_SYMBOL_GPL vmlinux 0xee97d6b9 platform_bus +EXPORT_SYMBOL_GPL vmlinux 0xeea3f3f1 zap_vma_ptes +EXPORT_SYMBOL_GPL vmlinux 0xeec5e3fe __pneigh_lookup +EXPORT_SYMBOL_GPL vmlinux 0xef0dea14 vlan_dev_real_dev +EXPORT_SYMBOL_GPL vmlinux 0xef1e9ecc task_current_syscall +EXPORT_SYMBOL_GPL vmlinux 0xef6c3f70 round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xef819708 regulator_enable +EXPORT_SYMBOL_GPL vmlinux 0xef82ec92 rt_mutex_trylock +EXPORT_SYMBOL_GPL vmlinux 0xef9beca8 uv_region_size +EXPORT_SYMBOL_GPL vmlinux 0xefb538bb usb_deregister_device_driver +EXPORT_SYMBOL_GPL vmlinux 0xefbcb7f4 scsi_nl_add_driver +EXPORT_SYMBOL_GPL vmlinux 0xefff3857 usb_hcd_pci_resume +EXPORT_SYMBOL_GPL vmlinux 0xf03f7eb5 sata_scr_write_flush +EXPORT_SYMBOL_GPL vmlinux 0xf05f0cab xenbus_map_ring_valloc +EXPORT_SYMBOL_GPL vmlinux 0xf07828ca blk_rq_bytes +EXPORT_SYMBOL_GPL vmlinux 0xf1346c19 usb_get_current_frame_number +EXPORT_SYMBOL_GPL vmlinux 0xf135ec8f xfrm_output +EXPORT_SYMBOL_GPL vmlinux 0xf1615d3d dev_attr_unload_heads +EXPORT_SYMBOL_GPL vmlinux 0xf184d189 kernel_power_off +EXPORT_SYMBOL_GPL vmlinux 0xf18e0d8f sata_pmp_error_handler +EXPORT_SYMBOL_GPL vmlinux 0xf1a07f83 sdio_writeb +EXPORT_SYMBOL_GPL vmlinux 0xf1db8489 sdio_claim_irq +EXPORT_SYMBOL_GPL vmlinux 0xf1ec8137 crypto_register_alg +EXPORT_SYMBOL_GPL vmlinux 0xf2035627 inet6_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0xf20b9d09 relay_reset +EXPORT_SYMBOL_GPL vmlinux 0xf2855040 platform_get_irq_byname +EXPORT_SYMBOL_GPL vmlinux 0xf293c618 rtc_irq_set_state +EXPORT_SYMBOL_GPL vmlinux 0xf29c030c debugfs_create_symlink +EXPORT_SYMBOL_GPL vmlinux 0xf2db08c0 ata_sff_softreset +EXPORT_SYMBOL_GPL vmlinux 0xf2ed5ff6 queue_work +EXPORT_SYMBOL_GPL vmlinux 0xf2fca922 uart_parse_options +EXPORT_SYMBOL_GPL vmlinux 0xf30ff34a device_create_vargs +EXPORT_SYMBOL_GPL vmlinux 0xf383cbac class_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf3a6af55 register_jprobes +EXPORT_SYMBOL_GPL vmlinux 0xf3d5cc13 ata_timing_merge +EXPORT_SYMBOL_GPL vmlinux 0xf3e5db04 fib_rules_cleanup_ops +EXPORT_SYMBOL_GPL vmlinux 0xf4027ad9 pci_enable_pcie_error_reporting +EXPORT_SYMBOL_GPL vmlinux 0xf4466b0c tcp_slow_start +EXPORT_SYMBOL_GPL vmlinux 0xf4627be0 console_drivers +EXPORT_SYMBOL_GPL vmlinux 0xf47f81bd kernel_kobj +EXPORT_SYMBOL_GPL vmlinux 0xf48cc16b ata_sff_error_handler +EXPORT_SYMBOL_GPL vmlinux 0xf499fdb2 rcu_barrier_bh +EXPORT_SYMBOL_GPL vmlinux 0xf4aebdc3 xenbus_suspend +EXPORT_SYMBOL_GPL vmlinux 0xf4c787af sysfs_put +EXPORT_SYMBOL_GPL vmlinux 0xf50b106c rtc_irq_set_freq +EXPORT_SYMBOL_GPL vmlinux 0xf553318d cpuidle_pause_and_lock +EXPORT_SYMBOL_GPL vmlinux 0xf5945bac gnttab_free_grant_references +EXPORT_SYMBOL_GPL vmlinux 0xf5a691cd invalidate_bh_lrus +EXPORT_SYMBOL_GPL vmlinux 0xf5c3b0ef agp_remove_bridge +EXPORT_SYMBOL_GPL vmlinux 0xf610cd65 raw_hash_sk +EXPORT_SYMBOL_GPL vmlinux 0xf659b41c sdio_align_size +EXPORT_SYMBOL_GPL vmlinux 0xf6ab3971 rtc_set_alarm +EXPORT_SYMBOL_GPL vmlinux 0xf6bcbd73 hwrng_register +EXPORT_SYMBOL_GPL vmlinux 0xf7016530 xenbus_gather +EXPORT_SYMBOL_GPL vmlinux 0xf7199eff ip_build_and_send_pkt +EXPORT_SYMBOL_GPL vmlinux 0xf73e8612 swiotlb_sync_single_range_for_cpu +EXPORT_SYMBOL_GPL vmlinux 0xf7427c4c register_jprobe +EXPORT_SYMBOL_GPL vmlinux 0xf7632ec8 xenbus_dev_fatal +EXPORT_SYMBOL_GPL vmlinux 0xf776f5a9 sysfs_remove_file_from_group +EXPORT_SYMBOL_GPL vmlinux 0xf7b1535a hvc_poll +EXPORT_SYMBOL_GPL vmlinux 0xf7b1d85b hid_output_report +EXPORT_SYMBOL_GPL vmlinux 0xf7cd966e sysdev_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf7d34928 bus_get_device_klist +EXPORT_SYMBOL_GPL vmlinux 0xf835e1ab invalidate_inode_pages2_range +EXPORT_SYMBOL_GPL vmlinux 0xf8802492 print_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0xf8cd4b63 sg_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xf8f3a0fb ata_ratelimit +EXPORT_SYMBOL_GPL vmlinux 0xf94fd2a8 blkcipher_walk_virt +EXPORT_SYMBOL_GPL vmlinux 0xf972e196 rfkill_restore_states +EXPORT_SYMBOL_GPL vmlinux 0xf97666a0 set_memory_rw +EXPORT_SYMBOL_GPL vmlinux 0xf97c8283 mmu_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0xf9a054b5 __round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0xf9ca3160 ata_id_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xf9df7149 skcipher_geniv_free +EXPORT_SYMBOL_GPL vmlinux 0xfa1f4662 scatterwalk_start +EXPORT_SYMBOL_GPL vmlinux 0xfa45d31c driver_add_kobj +EXPORT_SYMBOL_GPL vmlinux 0xfa731410 cpufreq_register_governor +EXPORT_SYMBOL_GPL vmlinux 0xfa91c434 tty_ldisc_ref +EXPORT_SYMBOL_GPL vmlinux 0xfac267a6 xenbus_free_evtchn +EXPORT_SYMBOL_GPL vmlinux 0xfb0aabb1 ata_sas_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0xfb77a706 blkcipher_walk_phys +EXPORT_SYMBOL_GPL vmlinux 0xfb882fb7 wmi_query_block +EXPORT_SYMBOL_GPL vmlinux 0xfb8bab74 ata_scsi_simulate +EXPORT_SYMBOL_GPL vmlinux 0xfba2097b cpci_hp_register_controller +EXPORT_SYMBOL_GPL vmlinux 0xfbc016de blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xfbf9be5d register_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xfc0509d8 scsi_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0xfc16ffdc hid_set_field +EXPORT_SYMBOL_GPL vmlinux 0xfc2ff860 uv_setup_irq +EXPORT_SYMBOL_GPL vmlinux 0xfc73253e crypto_drop_spawn +EXPORT_SYMBOL_GPL vmlinux 0xfcaf4b91 device_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xfcce694c rfkill_set_default +EXPORT_SYMBOL_GPL vmlinux 0xfcd05cb5 inet_csk_compat_getsockopt +EXPORT_SYMBOL_GPL vmlinux 0xfd250c2c relay_open +EXPORT_SYMBOL_GPL vmlinux 0xfd51b281 gnttab_end_foreign_access_ref +EXPORT_SYMBOL_GPL vmlinux 0xfd59ace8 gpiochip_remove +EXPORT_SYMBOL_GPL vmlinux 0xfd6ed1de usb_hcd_platform_shutdown +EXPORT_SYMBOL_GPL vmlinux 0xfd798df4 usb_put_intf +EXPORT_SYMBOL_GPL vmlinux 0xfd90fb09 sdev_evt_send +EXPORT_SYMBOL_GPL vmlinux 0xfd9da487 relay_subbufs_consumed +EXPORT_SYMBOL_GPL vmlinux 0xfde0b92c crypto_larval_error +EXPORT_SYMBOL_GPL vmlinux 0xfe0c6852 raw_seq_start +EXPORT_SYMBOL_GPL vmlinux 0xfe3c161d tty_mode_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xfe727411 get_phys_to_machine +EXPORT_SYMBOL_GPL vmlinux 0xfe7aa5e3 crypto_alloc_instance +EXPORT_SYMBOL_GPL vmlinux 0xfe922be7 audit_log_d_path +EXPORT_SYMBOL_GPL vmlinux 0xfe9407fa debugfs_create_blob +EXPORT_SYMBOL_GPL vmlinux 0xfe990052 gpio_free +EXPORT_SYMBOL_GPL vmlinux 0xfecbff96 __mark_empty_function +EXPORT_SYMBOL_GPL vmlinux 0xfed11ed1 usb_mon_deregister +EXPORT_SYMBOL_GPL vmlinux 0xfefee878 driver_register +EXPORT_SYMBOL_GPL vmlinux 0xff103202 blk_queue_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0xff5a8cfe cn_del_callback +EXPORT_SYMBOL_GPL vmlinux 0xffc14f34 blkcipher_walk_done +EXPORT_SYMBOL_GPL vmlinux 0xffce06b2 fb_bl_default_curve +EXPORT_SYMBOL_GPL vmlinux 0xffcf35e1 usb_root_hub_lost_power +EXPORT_UNUSED_SYMBOL vmlinux 0x00000000 init_mm +EXPORT_UNUSED_SYMBOL vmlinux 0x00000000 simple_prepare_write --- linux-2.6.28.orig/debian/abi/2.6.28-11.41/amd64/generic.modules +++ linux-2.6.28/debian/abi/2.6.28-11.41/amd64/generic.modules @@ -0,0 +1,2091 @@ +3c359 +3c574_cs +3c589_cs +3c59x +3w-9xxx +3w-xxxx +6pack +8021q +8139cp +8139too +8390 +9p +9pnet +9pnet_rdma +9pnet_virtio +a100u2w +a3d +aacraid +abituguru +abituguru3 +abyss +ac97_bus +acecad +acenic +acer-wmi +acpiphp +acpiphp_ibm +acquirewdt +act200l-sir +act_gact +act_ipt +actisys-sir +act_mirred +act_nat +act_pedit +act_police +act_simple +act_skbedit +acx +ad1848 +ad7414 +ad7418 +adcxx +adfs +adi +adm1021 +adm1025 +adm1026 +adm1029 +adm1031 +adm8211 +adm9240 +ads7828 +ads7846 +adt7462 +adt7470 +adt7473 +adutux +adv7170 +adv7175 +advansys +advantechwdt +aedsp16 +aes_generic +aes-x86_64 +af9013 +affs +af_key +af-rxrpc +ah4 +ah6 +aic79xx +aic7xxx +aic94xx +aiptek +aircable +airo +airo_cs +alauda +ali-ircc +alim1535_wdt +alim7101_wdt +ambassador +amd76xrom +amd8111e +amd-rng +analog +ansi_cprng +anubis +aoe +appledisplay +appleir +applesmc +appletalk +appletouch +applicom +ar7part +arc4 +arcfb +arcmsr +arcnet +arc-rawmode +arc-rimi +ark3116 +arkfb +arptable_filter +arp_tables +arpt_mangle +asb100 +asix +asus-laptop +async_memcpy +async_tx +async_xor +at24 +at25 +at76_usb +aten +ath5k +ath9k +ati_remote +ati_remote2 +atl1 +atl1e +atl2 +atlas_btns +atmel +atmel_cs +atmel_pci +atmtcp +atp +atp870u +atxp1 +aty128fb +atyfb +au0828 +au8522 +aufs +authenc +auth_rpcgss +autofs +autofs4 +av5100 +avma1_cs +avm_cs +ax25 +axnet_cs +b1 +b1dma +b1pci +b1pcmcia +b2c2-flexcop +b2c2-flexcop-pci +b2c2-flexcop-usb +b43 +b43legacy +b44 +bas_gigaset +baycom_par +baycom_ser_fdx +baycom_ser_hdx +bcm203x +bcm3510 +bcm5974 +befs +belkin_sa +berry_charge +bfs +bfusb +binfmt_misc +bitblit +block2mtd +blowfish +bluecard_cs +bnep +bnx2 +bnx2x +bonding +bpa10x +bpck +bpqether +bq24022 +bq27x00_battery +br2684 +bridge +broadcom +bsd_comp +bt3c_cs +bt819 +bt856 +bt878 +btcx-risc +btsdio +bttv +btuart_cs +btusb +budget +budget-av +budget-ci +budget-core +budget-patch +BusLogic +bw-qcam +c2port-duramar2150 +c4 +c67x00 +cafe_ccic +cafe_nand +camellia +capi +capidrv +capifs +capmode +carminefb +cassini +cast5 +cast6 +catc +cbc +cciss +ccm +cdc-acm +cdc_ether +cdc_subset +cdc-wdm +cfag12864b +cfag12864bfb +cfg80211 +cfi_cmdset_0001 +cfi_cmdset_0002 +cfi_cmdset_0020 +cfi_probe +cfi_util +ch +ch341 +chipreg +cicada +cifs +cirrusfb +ck804xrom +cls_basic +cls_fw +cls_route +cls_rsvp +cls_rsvp6 +cls_tcindex +cls_u32 +cm109 +cm4000_cs +cm4040_cs +cmtp +cobra +coda +com20020 +com20020_cs +com20020-pci +com90io +com90xx +comm +commandir +compal-laptop +compat_ioctl32 +compcache +configfs +core +coretemp +corgi_bl +cp2101 +cpcihp_generic +cpcihp_zt5550 +cpia +cpia2 +cpia_pp +cpia_usb +cpqarray +cpu5wdt +cpuid +c-qcam +cr_bllcd +crc32c +crc32c-intel +crc7 +crc-ccitt +crc-itu-t +crvml +cryptd +cryptoloop +crypto_null +cs5345 +cs53l32a +ct82c710 +ctr +cts +cx18 +cx22700 +cx22702 +cx2341x +cx23885 +cx24110 +cx24116 +cx24123 +cx25840 +cx8800 +cx8802 +cx88-alsa +cx88-blackbird +cx88-dvb +cx88-vp3054-i2c +cx88xx +cxacru +cxgb +cxgb3 +cyber2000fb +cyberjack +cyclades +cyclomx +cycx_drv +cypress_cy7c63 +cypress_m8 +cytherm +da903x +DAC960 +davicom +db9 +dc395x +dca +dccp +dccp_ccid2 +dccp_ccid3 +dccp_diag +dccp_ipv4 +dccp_ipv6 +dccp_probe +dccp_tfrc_lib +dcdbas +de2104x +de4x5 +de600 +de620 +decnet +deflate +defxx +dell_rbu +des_generic +dib0070 +dib3000mb +dib3000mc +dib7000m +dib7000p +dibx000_common +digi_acceleport +dilnetpc +diskonchip +display +divacapi +divadidd +diva_idi +diva_mnt +divas +dlci +dlm +dm1105 +dm9601 +dm-bbr +dm-crypt +dme1737 +dmfe +dm-loop +dm-mem-cache +dm-message +dm-raid4-5 +dm-region_hash +dmx3191d +dm-zero +dn_rtmsg +doc2000 +doc2001 +doc2001plus +docecc +docprobe +dpt_i2o +drbd +drm +drx397xD +ds1621 +ds1682 +ds2482 +ds2490 +ds2760_battery +dsbr100 +dscc4 +dss1_divert +dst +dst_ca +dstr +dtl1_cs +dummy +dummy_hcd +dv1394 +dvb-bt8xx +dvb-core +dvb-pll +dvb-ttpci +dvb-ttusb-budget +dvb-usb +dvb-usb-a800 +dvb-usb-af9005 +dvb-usb-af9005-remote +dvb-usb-af9015 +dvb-usb-anysee +dvb-usb-au6610 +dvb-usb-cinergyT2 +dvb-usb-cxusb +dvb-usb-dib0700 +dvb-usb-dibusb-common +dvb-usb-dibusb-mb +dvb-usb-dibusb-mc +dvb-usb-digitv +dvb-usb-dtt200u +dvb-usb-dtv5100 +dvb-usb-dw2102 +dvb-usb-gl861 +dvb-usb-gp8psk +dvb-usb-m920x +dvb-usb-nova-t-usb2 +dvb-usb-opera +dvb-usb-ttusb2 +dvb-usb-umt-010 +dvb-usb-vp702x +dvb-usb-vp7045 +e100 +e1000 +e1000e +e752x_edac +eata +ebt_802_3 +ebtable_broute +ebtable_filter +ebtable_nat +ebtables +ebt_among +ebt_arp +ebt_arpreply +ebt_dnat +ebt_ip +ebt_ip6 +ebt_limit +ebt_log +ebt_mark +ebt_mark_m +ebt_nflog +ebt_pkttype +ebt_redirect +ebt_snat +ebt_stp +ebt_ulog +ebt_vlan +ecb +econet +edac_core +eeepc-laptop +eepro100 +eeprom +eeprom_93cx6 +efs +elo +elsa_cs +em28xx +em28xx-alsa +em28xx-dvb +em_cmp +emi26 +emi62 +em_meta +em_nbyte +empeg +em_text +emu10k1-gp +em_u32 +enclosure +eni +enic +epat +epca +epia +epic100 +eql +esb2rom +esi-sir +esp4 +esp6 +et131x +et61x251 +eth1394 +eurotechwdt +evbug +exportfs +f71805f +f71882fg +f75375s +fakephp +farsync +fat +faulty +fbcon +fb_ddc +fb_sys_fops +fcrypt +fdomain +fdomain_cs +fealnx +ff-memless +firestream +firewire-core +firewire-ohci +firewire-sbp2 +fit2 +fit3 +floppy +fm801-gp +fmvj18x_cs +font +forcedeth +fore_200e +freevxfs +friq +frpw +fsam7400 +fscher +fschmd +fscpos +ftdi-elan +ftdi_sio +ftl +fujitsu-laptop +fujitsu_ts +funsoft +g450_pll +gadgetfs +gamecon +gameport +garmin_gps +garp +g_cdc +gcm +gdth +generic_serial +gen_probe +g_ether +gf128mul +gf2k +g_file_storage +gfs2 +gigaset +girbil-sir +gl518sm +gl520sm +gl620a +gpio_keys +gpio_mouse +grip +grip_mp +gru +g_serial +gspca_conex +gspca_etoms +gspca_finepix +gspca_m5602 +gspca_main +gspca_mars +gspca_ov519 +gspca_pac207 +gspca_pac7311 +gspca_sonixb +gspca_sonixj +gspca_spca500 +gspca_spca501 +gspca_spca505 +gspca_spca506 +gspca_spca508 +gspca_spca561 +gspca_stk014 +gspca_sunplus +gspca_t613 +gspca_tv8532 +gspca_vc032x +gspca_zc3xx +gtco +guillemot +gunze +gx1fb +gxfb +g_zero +hamachi +hangcheck-timer +hci_uart +hci_vhci +hdaps +hdlc +hdlc_cisco +hdlcdrv +hdlc_fr +hdlc_ppp +hdlc_raw +hdlc_raw_eth +hdlc_x25 +he +heci +hecubafb +hermes +hermes_dld +hexium_gemini +hexium_orion +hfc4s8s_l1 +hfcmulti +hfcpci +hfc_usb +hfs +hfsplus +hgafb +hid-a4tech +hid-apple +hid-belkin +hid-bright +hid-cherry +hid-chicony +hid-cypress +hid-dell +hid-ezkey +hid-gyration +hid-logitech +hid-microsoft +hid-monterey +hidp +hid-petalynx +hid-pl +hid-samsung +hid-sony +hid-sunplus +hid-tmff +hid-zpff +hifn_795x +hisax +hisax_fcpcipnp +hisax_isac +hisax_st5481 +horizon +hostap +hostap_cs +hostap_pci +hostap_plx +hp100 +hp4x +hpfs +hpilo +hptiop +hp-wmi +hso +htc-pasic3 +hwa-hc +hwa-rc +hwmon-vid +hysdn +i1480-dfu-usb +i1480-est +i1480u-wlp +i2c-algo-bit +i2c-algo-pca +i2c-algo-pcf +i2c-ali1535 +i2c-ali1563 +i2c-ali15x3 +i2c-amd756 +i2c-amd756-s4882 +i2c-amd8111 +i2c-dev +i2c-gpio +i2c-i801 +i2c-isch +i2c-matroxfb +i2c-nforce2 +i2c-nforce2-s4985 +i2c-ocores +i2c-parport +i2c-parport-light +i2c-pca-platform +i2c-piix4 +i2c-simtec +i2c-sis5595 +i2c-sis630 +i2c-sis96x +i2c-stub +i2c-taos-evm +i2c-tiny-usb +i2c-via +i2c-viapro +i2c-voodoo3 +i2o_block +i2o_bus +i2o_config +i2o_core +i2o_proc +i2o_scsi +i3000_edac +i5000_edac +i5100_edac +i5k_amb +i6300esb +i7300_idle +i810 +i82092 +i82975x_edac +i830 +i8k +i915 +ib700wdt +ib_addr +ib_cm +ib_core +ib_ipath +ib_ipoib +ib_iser +ib_mad +ibmaem +ibmasm +ibmasr +ibmcam +ibmpex +ib_mthca +ibmtr_cs +ib_sa +ib_srp +ib_ucm +ib_umad +ib_uverbs +ichxrom +icplus +ics932s401 +idmouse +idt77252 +ieee1394 +ieee80211 +ieee80211_crypt +ieee80211_crypt_ccmp +ieee80211_crypt_tkip +ieee80211_crypt_wep +ifb +iforce +igb +ili9320 +imm +inet_lro +inexio +inftl +initio +input-polldev +intel-agp +intelfb +intel_menlow +intel-rng +intel_vr_nor +interact +ioatdma +ioc4 +io_edgeport +io_ti +iowarrior +ip2 +ip6_queue +ip6table_filter +ip6table_mangle +ip6table_raw +ip6_tables +ip6table_security +ip6t_ah +ip6t_eui64 +ip6t_frag +ip6t_hbh +ip6t_hl +ip6t_HL +ip6t_ipv6header +ip6t_LOG +ip6t_mh +ip6t_REJECT +ip6t_rt +ip6_tunnel +ipaq +ipcomp +ipcomp6 +ipddp +ipg +ip_gre +iphase +ipip +ipmi_devintf +ipmi_msghandler +ipmi_poweroff +ipmi_si +ipmi_watchdog +ip_queue +ipr +ips +iptable_filter +iptable_mangle +iptable_nat +iptable_raw +ip_tables +iptable_security +ipt_addrtype +ipt_ah +ipt_CLUSTERIP +ipt_ecn +ipt_ECN +ipt_LOG +ipt_MASQUERADE +ipt_NETMAP +ipt_REDIRECT +ipt_REJECT +ipt_ttl +ipt_TTL +ipt_ULOG +ip_vs +ip_vs_dh +ip_vs_ftp +ip_vs_lblc +ip_vs_lblcr +ip_vs_lc +ip_vs_nq +ip_vs_rr +ip_vs_sed +ip_vs_sh +ip_vs_wlc +ip_vs_wrr +ipw +ipw2100 +ipw2200 +ipwireless +ipx +ircomm +ir-common +ircomm-tty +irda +irda-usb +ir-kbd-i2c +irlan +irnet +irtty-sir +iscsi_ibft +iscsi_tcp +iscsi_trgt +isdn +isdn_bsdcomp +isdnhdlc +isight_firmware +isl6405 +isl6421 +isofs +isp116x-hcd +isp1760 +istallion +it87 +it8712f_wdt +it87_wdt +iTCO_vendor_support +iTCO_wdt +itd1000 +ivtv +ivtvfb +iw_c2 +iw_cm +iw_cxgb3 +iwl3945 +iwlagn +iwlcore +ixgb +ixgbe +ixj +ixj_pcmcia +jedec_probe +jffs2 +jfs +jme +joydev +joydump +jsm +k8temp +kafs +kahlua +kaweth +kb3886_bl +kbic +kbtab +kernelcapi +keyspan +keyspan_pda +keyspan_remote +khazad +kingsun-sir +kl5kusb105 +kobil_sct +konicawc +ks0108 +ks0127 +ks959-sir +ksdazzle-sir +ktti +kvm +kvm-amd +kvm-intel +kyrofb +l1oip +l440gx +l64781 +lanai +lapb +lapbether +lcd +ldusb +lec +led-class +leds-da903x +leds-gpio +leds-hp-disk +leds-pca9532 +leds-pca955x +ledtrig-backlight +ledtrig-default-on +ledtrig-heartbeat +ledtrig-timer +legousbtower +lgdt330x +lgs8gl5 +libcrc32c +libertas +libertas_cs +libertas_sdio +libertas_tf +libertas_tf_usb +libiscsi +libsas +libsrp +lightning +linear +lirc_atiusb +lirc_bt829 +lirc_cmdir +lirc_dev +lirc_gpio +lirc_i2c +lirc_igorplugusb +lirc_imon +lirc_it87 +lirc_mceusb +lirc_mceusb2 +lirc_pvr150 +lirc_sasem +lirc_serial +lirc_serial_igor +lirc_sir +lirc_streamzap +lirc_ttusbir +lis3lv02d +litelink-sir +lkkbd +llc2 +lm63 +lm70 +lm75 +lm77 +lm78 +lm80 +lm83 +lm85 +lm87 +lm90 +lm92 +lm93 +lmc +lmpcm_usb +lnbp21 +lockd +lock_dlm +lp +lpfc +lrw +ltv350qv +lxfb +lxt +lzo +lzo_compress +lzo_decompress +m25p80 +m52790 +ma600-sir +mac80211 +machzwd +macmodes +macvlan +magellan +map_absent +map_funcs +map_ram +map_rom +marvell +matroxfb_accel +matroxfb_base +matroxfb_crtc2 +matroxfb_DAC1064 +matroxfb_g450 +matroxfb_maven +matroxfb_misc +matroxfb_Ti3026 +matrox_w1 +max1111 +max1619 +max6650 +max6875 +max7301 +max732x +mb862xxfb +mbp_nvidia_bl +mcp2120-sir +mcp23s08 +mcs7780 +mcs7830 +mct_u232 +md4 +mdc800 +mdio-bitbang +megaraid +megaraid_mbox +megaraid_mm +megaraid_sas +metronomefb +meye +mga +michael_mic +microcode +microtek +mii +minix +mISDN_core +mISDN_dsp +mk712 +mkiss +mlx4_core +mlx4_en +mlx4_ib +mmc_block +mmc_spi +mos7720 +mos7840 +moto_modem +moxa +mpoa +mptbase +mptctl +mptfc +mptlan +mptsas +mptscsih +mptspi +mpu401 +msdos +msi-laptop +msp3400 +msr +mt2060 +mt20xx +mt2131 +mt2266 +mt312 +mt352 +mt9m001 +mt9m111 +mt9v022 +mtd +mtd_blkdevs +mtdblock +mtdblock_ro +mtdchar +mtdconcat +mtd_dataflash +mtdoops +mtdram +mtouch +multipath +mwave +mxb +mxl5005s +mxl5007t +mxser +myri10ge +nand +nand_ecc +nand_ids +nandsim +natsemi +navman +nbd +ncpfs +ndiswrapper +ne2k-pci +neofb +net1080 +netconsole +netrom +netsc520 +nettel +netwave_cs +netxen_nic +newtonkbd +nf_conntrack +nf_conntrack_amanda +nf_conntrack_ftp +nf_conntrack_h323 +nf_conntrack_ipv4 +nf_conntrack_ipv6 +nf_conntrack_irc +nf_conntrack_netbios_ns +nf_conntrack_netlink +nf_conntrack_pptp +nf_conntrack_proto_gre +nf_conntrack_proto_sctp +nf_conntrack_proto_udplite +nf_conntrack_sip +nf_conntrack_tftp +nf_defrag_ipv4 +nf_nat +nf_nat_amanda +nf_nat_ftp +nf_nat_h323 +nf_nat_irc +nf_nat_pptp +nf_nat_proto_gre +nf_nat_proto_sctp +nf_nat_proto_udplite +nf_nat_sip +nf_nat_snmp_basic +nf_nat_tftp +nfnetlink +nfnetlink_log +nfnetlink_queue +nfs +nfs_acl +nfsd +nftl +nf_tproxy_core +n_hdlc +niu +nls_ascii +nls_cp1250 +nls_cp1251 +nls_cp1255 +nls_cp437 +nls_cp737 +nls_cp775 +nls_cp850 +nls_cp852 +nls_cp855 +nls_cp857 +nls_cp860 +nls_cp861 +nls_cp862 +nls_cp863 +nls_cp864 +nls_cp865 +nls_cp866 +nls_cp869 +nls_cp874 +nls_cp932 +nls_cp936 +nls_cp949 +nls_cp950 +nls_euc-jp +nls_iso8859-1 +nls_iso8859-13 +nls_iso8859-14 +nls_iso8859-15 +nls_iso8859-2 +nls_iso8859-3 +nls_iso8859-4 +nls_iso8859-5 +nls_iso8859-6 +nls_iso8859-7 +nls_iso8859-9 +nls_koi8-r +nls_koi8-ru +nls_koi8-u +nls_utf8 +nmclan_cs +nozomi +n_r3964 +ns558 +ns83820 +nsc_gpio +nsc-ircc +ntfs +nvidiafb +nvram +nxt200x +nxt6000 +ocfs2 +ocfs2_dlm +ocfs2_dlmfs +ocfs2_nodemanager +ocfs2_stackglue +ocfs2_stack_o2cb +ocfs2_stack_user +ohci1394 +old_belkin-sir +olympic +omfs +omninet +on20 +on26 +onenand +onenand_sim +opl3 +oprofile +option +or51132 +or51211 +orinoco +orinoco_cs +orinoco_nortel +orinoco_pci +orinoco_plx +orinoco_tmd +osst +oti6858 +output +ov511 +ov511_decomp +ov518_decomp +ov7670 +ovcamchip +p4-clockmod +p54common +p54pci +p54usb +p80211 +p8023 +panasonic-laptop +paride +parkbd +parport +parport_ax88796 +parport_cs +parport_pc +parport_serial +pas2 +pata_cmd640 +pata_cypress +pata_hpt3x2n +pata_it8213 +pata_ninja32 +pata_opti +pata_optidma +pata_pcmcia +pata_radisys +pbe5 +pc87360 +pc8736x_gpio +pc87413_wdt +pc87427 +pca953x +pcbc +pcd +pcf857x +pcf8591 +pci +pci200syn +pcilynx +pcips2 +pcmcia +pcmcia_core +pcnet32 +pcnet_cs +pcspkr +pcwd_pci +pcwd_usb +pd +pd6729 +pda_power +pegasus +penmount +pf +pg +phantom +phidget +phidgetkit +phidgetmotorcontrol +phidgetservo +phonedev +phonet +phram +physmap +pktgen +pl2303 +platform_lcd +plat_nand +plat-ram +plip +plusb +pluto2 +pm2fb +pm3fb +pmc551 +pn_pep +powermate +ppa +ppdev +ppp_async +ppp_deflate +ppp_mppe +pppoatm +pppoe +pppol2tp +pppox +ppp_synctty +prism2_usb +prism54 +progear_bl +psmouse +pss +pt +pvrusb2 +pwc +qla1280 +qla2xxx +qla3xxx +qla4xxx +qlge +qlogic_cs +qlogicfas408 +qnx4 +qsemi +qt1010 +quickcam +quickcam_messenger +quota_v1 +quota_v2 +r128 +r8169 +r8a66597-hcd +radeon +radeonfb +radio-gemtek-pci +radio-maestro +radio-maxiradio +radio-mr800 +radio-si470x +raid0 +raid1 +raid10 +raid456 +raid_class +raw +raw1394 +ray_cs +rdma_cm +rdma_ucm +redboot +reed_solomon +reiserfs +rfc1051 +rfc1201 +rfd_ftl +rfkill-input +ricoh_mmc +rio +rio500 +riscom8 +rivafb +rmd128 +rmd160 +rmd256 +rmd320 +rndis_host +rndis_wlan +rocket +romfs +rose +rpcsec_gss_krb5 +rpcsec_gss_spkm3 +rrunner +rsrc_nonstatic +rt2400pci +rt2500pci +rt2500usb +rt2860sta +rt2870sta +rt2x00lib +rt2x00pci +rt2x00usb +rt61pci +rt73usb +rtc-bq4802 +rtc-ds1286 +rtc-ds1305 +rtc-ds1307 +rtc-ds1374 +rtc-ds1390 +rtc-ds1553 +rtc-ds1672 +rtc-ds1742 +rtc-ds3234 +rtc-fm3130 +rtc-isl1208 +rtc-m41t80 +rtc-m41t94 +rtc-m48t35 +rtc-m48t59 +rtc-m48t86 +rtc-max6900 +rtc-max6902 +rtc-pcf8563 +rtc-pcf8583 +rtc-rs5c348 +rtc-rs5c372 +rtc-rx8581 +rtc-stk17ta8 +rtc-test +rtc-v3020 +rtc-wm8350 +rtc-x1205 +rtl8150 +rtl8180 +rtl8187 +rtl8187se +rxkad +s1d13xxxfb +s2255drv +s2io +s3fb +s5h1409 +s5h1411 +s5h1420 +saa5246a +saa5249 +saa6588 +saa6752hs +saa7110 +saa7111 +saa7114 +saa7115 +saa7127 +saa7134 +saa7134-alsa +saa7134-dvb +saa7134-empress +saa7146 +saa7146_vv +saa717x +saa7185 +safe_serial +salsa20_generic +salsa20-x86_64 +sata_mv +savage +savagefb +sb +sb1000 +sbc60xxwdt +sbc8360 +sbc_epx_c3 +sbc_gxx +sb_lib +sbni +sbp2 +sc1200wdt +sc520cdp +sc520_wdt +sc92031 +scb2_flash +sch_atm +sch_cbq +sch_dsmark +sch_gred +sch_hfsc +sch_htb +sch_ingress +sch_multiq +sch_netem +sch_prio +sch_red +sch_sfq +sch_tbf +sch_teql +scsi_debug +scsi_dh_alua +scsi_dh_emc +scsi_dh_hp_sw +scsi_dh_rdac +scsi_tgt +scsi_transport_fc +scsi_transport_iscsi +scsi_transport_sas +scsi_transport_spi +scsi_transport_srp +scsi_wait_scan +sctp +sdhci +sdhci-pci +sdio_uart +sdricoh_cs +se401 +sedlbauer_cs +seed +seqiv +ser_gigaset +serial_cs +serio_raw +sermouse +serpent +serport +ses +sfc +sha1_generic +sha256_generic +sha512_generic +sh_mobile_ceu_camera +shpchp +si21xx +sidewinder +sierra +sir-dev +sis +sis190 +sis5595 +sis900 +sis-agp +sisfb +sisusbvga +sit +skfp +skge +sky2 +sl811_cs +sl811-hcd +slip +slram +sm501 +sm501fb +smbfs +smc91c92_cs +sms1xxx +smsc +smsc37b787_wdt +smsc47b397 +smsc47m1 +smsc47m192 +smsc95xx +smsc-ircc2 +sn9c102 +snd +snd-ac97-codec +snd-ad1889 +snd-ak4114 +snd-ak4117 +snd-ak4xxx-adda +snd-ali5451 +snd-als300 +snd-als4000 +snd-atiixp +snd-atiixp-modem +snd-au8810 +snd-au8820 +snd-au8830 +snd-aw2 +snd-azt3328 +snd-bt87x +snd-ca0106 +snd-cmipci +snd-cs4281 +snd-cs46xx +snd-cs5530 +snd-cs8427 +snd-darla20 +snd-darla24 +snd-dummy +snd-echo3g +snd-emu10k1 +snd-emu10k1-synth +snd-emu10k1x +snd-emux-synth +snd-ens1370 +snd-ens1371 +snd-es1938 +snd-es1968 +snd-fm801 +snd-gina20 +snd-gina24 +snd-hda-intel +snd-hdsp +snd-hdspm +snd-hifier +snd-hwdep +snd-i2c +snd-ice1712 +snd-ice1724 +snd-ice17xx-ak4xxx +snd-indigo +snd-indigodj +snd-indigoio +snd-intel8x0 +snd-intel8x0m +snd-korg1212 +snd-layla20 +snd-layla24 +snd-maestro3 +snd-mia +snd-mixart +snd-mixer-oss +snd-mona +snd-mpu401 +snd-mpu401-uart +snd-mtpav +snd-mts64 +snd-nm256 +snd-opl3-lib +snd-opl3-synth +snd-oxygen +snd-oxygen-lib +snd-page-alloc +snd-pcm +snd-pcm-oss +snd-pcsp +snd-pcxhr +snd-pdaudiocf +snd-portman2x4 +snd-pt2258 +snd-rawmidi +snd-riptide +snd-rme32 +snd-rme96 +snd-rme9652 +snd-sb16-dsp +snd-sb-common +snd-seq +snd-seq-device +snd-seq-dummy +snd-seq-midi +snd-seq-midi-emul +snd-seq-midi-event +snd-seq-oss +snd-seq-virmidi +snd-serial-u16550 +snd-soc-ad73311 +snd-soc-ak4535 +snd-soc-core +snd-soc-cs4270 +snd-soc-ssm2602 +snd-soc-tlv320aic23 +snd-soc-tlv320aic26 +snd-soc-tlv320aic3x +snd-soc-uda1380 +snd-soc-wm8510 +snd-soc-wm8580 +snd-soc-wm8731 +snd-soc-wm8750 +snd-soc-wm8753 +snd-soc-wm8900 +snd-soc-wm8903 +snd-soc-wm8971 +snd-soc-wm8990 +snd-sonicvibes +snd-tea575x-tuner +snd-timer +snd-trident +snd-usb-audio +snd-usb-caiaq +snd-usb-lib +snd-usb-us122l +snd-usb-usx2y +snd-util-mem +snd-via82xx +snd-via82xx-modem +snd-virmidi +snd-virtuoso +snd-vx222 +snd-vx-lib +snd-vxpocket +snd-ymfpci +soc_camera +soc_camera_platform +softcursor +softdog +sony-laptop +sound +soundcore +sound_firmware +sp8870 +sp887x +spaceball +spaceorb +spcp8x5 +specialix +spectrum_cs +speedstep-lib +speedtch +spi_bitbang +spi_butterfly +spidev +spi_lm70llp +squashfs +ssb +sscape +ssfdc +sstfb +st +stallion +starfire +stb6000 +stex +stinger +stir4200 +stkwebcam +stowaway +stp +stradis +strip +stv0288 +stv0297 +stv0299 +stv680 +sundance +sungem +sungem_phy +sunhme +suni +sunkbd +sunrpc +svcrdma +svgalib +sx +sx8 +sym53c500_cs +sym53c8xx +synclink +synclink_cs +synclink_gt +synclinkmp +syncppp +syscopyarea +sysfillrect +sysimgblt +sysv +t1pci +tcp_bic +tcp_highspeed +tcp_htcp +tcp_hybla +tcp_illinois +tcp_lp +tcp_probe +tcp_scalable +tcp_vegas +tcp_veno +tcp_westwood +tcp_yeah +tcrypt +tda10021 +tda10023 +tda10048 +tda1004x +tda10086 +tda18271 +tda7432 +tda8083 +tda826x +tda827x +tda8290 +tda9840 +tda9875 +tda9887 +tdfx +tdfxfb +tdo24m +tea +tea5761 +tea5767 +tea6415c +tea6420 +tehuti +tekram-sir +teles_cs +tg3 +tgr192 +thinkpad_acpi +thinkpad_ec +thmc50 +tifm_7xx1 +tifm_core +tifm_sd +tileblit +tipc +ti_usb_3410_5052 +tlan +tlclk +tle62x0 +tlsf +tmdc +tms380tr +tmscsim +tmspci +toshiba_acpi +touchit213 +touchright +touchwin +tpm +tpm_atmel +tpm_bios +tpm_infineon +tpm_nsc +tpm_tis +tps65010 +tp_smapi +trancevibrator +tridentfb +trix +ts5500_flash +ts_bm +ts_fsm +ts_kmp +tsl2550 +ttpci-eeprom +ttusb_dec +ttusbdecfe +tua6100 +tulip +tun +tuner +tuner-simple +tuner-types +tuner-xc2028 +tunnel4 +tunnel6 +turbografx +tvaudio +tveeprom +tvp5150 +twidjoy +twofish +twofish_common +twofish-x86_64 +typhoon +u132-hcd +uart401 +uart6850 +ub +ubi +ubifs +ucb1400_core +ucb1400_ts +udf +ueagle-atm +ufs +uinput +uio +uio_cif +uio_pdrv +uio_pdrv_genirq +uio_sercos3 +uio_smx +uli526x +ultracam +umc +umem +unionfs +upd64031a +upd64083 +uPD98402 +usb8xxx +usbatm +usb_debug +usb_gigaset +usbhid +usbkbd +usblcd +usbled +usblp +usbmouse +usbnet +usbsevseg +usb-storage +usbtmc +usbtouchscreen +usbvideo +usbvision +uss720 +uvcvideo +uvesafb +uwb +v4l1-compat +v4l2-common +v4l2-int-device +ves1820 +ves1x93 +vesafb +veth +vfat +vga16fb +vgastate +vgg2432a4 +via +via686a +via-agp +viafb +via-ircc +via-rhine +via-velocity +vicam +video +video1394 +videobuf-core +videobuf-dma-contig +videobuf-dma-sg +videobuf-dvb +videobuf-vmalloc +videocodec +videodev +virtio +virtio_balloon +virtio_blk +virtio_console +virtio_net +virtio_pci +virtio_ring +virtio-rng +virtual +visor +vitesse +vivi +vlsi_ir +v_midi +vmlfb +vp27smpx +vpx3220 +vstusb +vsxxxaa +vt1211 +vt8231 +vt8623fb +w1_bq27000 +w1_ds2433 +w1_ds2760 +w1-gpio +w1_smem +w1_therm +w83627ehf +w83627hf +w83627hf_wdt +w83697hf_wdt +w83697ug_wdt +w83781d +w83791d +w83792d +w83793 +w83877f_wdt +w83977af_ir +w83977f_wdt +w83l785ts +w83l786ng +w9966 +w9968cf +wacom +wafer5823wdt +wanrouter +wanxl +warrior +wavelan_cs +wbsd +wdt_pci +whci +whci-hcd +whc-rc +whiteheat +winbond-840 +wire +wl3501_cs +wlp +wm8350 +wm8350-i2c +wm8350-regulator +wm8400-core +wm8400-regulator +wm8739 +wm8775 +wm97xx-ts +wp512 +wusb-cbaf +wusbcore +wusb-wa +x25 +x25_asy +x38_edac +xc5000 +xcbc +xen-blkfront +xen-fbfront +xen-kbdfront +xen-netfront +xfrm4_mode_beet +xfrm4_mode_transport +xfrm4_mode_tunnel +xfrm4_tunnel +xfrm6_mode_beet +xfrm6_mode_ro +xfrm6_mode_transport +xfrm6_mode_tunnel +xfrm6_tunnel +xfrm_ipcomp +xfrm_user +xfs +xirc2ps_cs +xircom_cb +xor +xp +xpad +xpc +xpnet +xprtrdma +x_tables +xt_CLASSIFY +xt_comment +xt_connbytes +xt_connlimit +xt_connmark +xt_CONNMARK +xt_CONNSECMARK +xt_conntrack +xt_dccp +xt_dscp +xt_DSCP +xt_esp +xt_hashlimit +xt_helper +xt_iprange +xtkbd +xt_length +xt_limit +xt_mac +xt_mark +xt_MARK +xt_multiport +xt_NFLOG +xt_NFQUEUE +xt_NOTRACK +xt_owner +xt_physdev +xt_pkttype +xt_policy +xt_quota +xt_rateest +xt_RATEEST +xt_realm +xt_recent +xts +xt_sctp +xt_SECMARK +xt_socket +xt_state +xt_statistic +xt_string +xt_tcpmss +xt_TCPMSS +xt_tcpudp +xt_time +xt_TPROXY +xt_TRACE +xt_u32 +xusbatm +yam +yealink +yellowfin +yenta_socket +zatm +zaurus +zc0301 +zd1201 +zd1211rw +zhenhua +zl10353 +zlib_deflate +zr36016 +zr36050 +zr36060 +zr36067 +zr364xx --- linux-2.6.28.orig/debian/abi/2.6.28-11.41/amd64/server.modules +++ linux-2.6.28/debian/abi/2.6.28-11.41/amd64/server.modules @@ -0,0 +1,2091 @@ +3c359 +3c574_cs +3c589_cs +3c59x +3w-9xxx +3w-xxxx +6pack +8021q +8139cp +8139too +8390 +9p +9pnet +9pnet_rdma +9pnet_virtio +a100u2w +a3d +aacraid +abituguru +abituguru3 +abyss +ac97_bus +acecad +acenic +acer-wmi +acpiphp +acpiphp_ibm +acquirewdt +act200l-sir +act_gact +act_ipt +actisys-sir +act_mirred +act_nat +act_pedit +act_police +act_simple +act_skbedit +acx +ad1848 +ad7414 +ad7418 +adcxx +adfs +adi +adm1021 +adm1025 +adm1026 +adm1029 +adm1031 +adm8211 +adm9240 +ads7828 +ads7846 +adt7462 +adt7470 +adt7473 +adutux +adv7170 +adv7175 +advansys +advantechwdt +aedsp16 +aes_generic +aes-x86_64 +af9013 +affs +af_key +af-rxrpc +ah4 +ah6 +aic79xx +aic7xxx +aic94xx +aiptek +aircable +airo +airo_cs +alauda +ali-ircc +alim1535_wdt +alim7101_wdt +ambassador +amd76xrom +amd8111e +amd-rng +analog +ansi_cprng +anubis +aoe +appledisplay +appleir +applesmc +appletalk +appletouch +applicom +ar7part +arc4 +arcfb +arcmsr +arcnet +arc-rawmode +arc-rimi +ark3116 +arkfb +arptable_filter +arp_tables +arpt_mangle +asb100 +asix +asus-laptop +async_memcpy +async_tx +async_xor +at24 +at25 +at76_usb +aten +ath5k +ath9k +ati_remote +ati_remote2 +atl1 +atl1e +atl2 +atlas_btns +atmel +atmel_cs +atmel_pci +atmtcp +atp +atp870u +atxp1 +aty128fb +atyfb +au0828 +au8522 +aufs +authenc +auth_rpcgss +autofs +autofs4 +av5100 +avma1_cs +avm_cs +ax25 +axnet_cs +b1 +b1dma +b1pci +b1pcmcia +b2c2-flexcop +b2c2-flexcop-pci +b2c2-flexcop-usb +b43 +b43legacy +b44 +bas_gigaset +baycom_par +baycom_ser_fdx +baycom_ser_hdx +bcm203x +bcm3510 +bcm5974 +befs +belkin_sa +berry_charge +bfs +bfusb +binfmt_misc +bitblit +block2mtd +blowfish +bluecard_cs +bnep +bnx2 +bnx2x +bonding +bpa10x +bpck +bpqether +bq24022 +bq27x00_battery +br2684 +bridge +broadcom +bsd_comp +bt3c_cs +bt819 +bt856 +bt878 +btcx-risc +btsdio +bttv +btuart_cs +btusb +budget +budget-av +budget-ci +budget-core +budget-patch +BusLogic +bw-qcam +c2port-duramar2150 +c4 +c67x00 +cafe_ccic +cafe_nand +camellia +capi +capidrv +capifs +capmode +carminefb +cassini +cast5 +cast6 +catc +cbc +cciss +ccm +cdc-acm +cdc_ether +cdc_subset +cdc-wdm +cfag12864b +cfag12864bfb +cfg80211 +cfi_cmdset_0001 +cfi_cmdset_0002 +cfi_cmdset_0020 +cfi_probe +cfi_util +ch +ch341 +chipreg +cicada +cifs +cirrusfb +ck804xrom +cls_basic +cls_fw +cls_route +cls_rsvp +cls_rsvp6 +cls_tcindex +cls_u32 +cm109 +cm4000_cs +cm4040_cs +cmtp +cobra +coda +com20020 +com20020_cs +com20020-pci +com90io +com90xx +comm +commandir +compal-laptop +compat_ioctl32 +compcache +configfs +core +coretemp +corgi_bl +cp2101 +cpcihp_generic +cpcihp_zt5550 +cpia +cpia2 +cpia_pp +cpia_usb +cpqarray +cpu5wdt +cpuid +c-qcam +cr_bllcd +crc32c +crc32c-intel +crc7 +crc-ccitt +crc-itu-t +crvml +cryptd +cryptoloop +crypto_null +cs5345 +cs53l32a +ct82c710 +ctr +cts +cx18 +cx22700 +cx22702 +cx2341x +cx23885 +cx24110 +cx24116 +cx24123 +cx25840 +cx8800 +cx8802 +cx88-alsa +cx88-blackbird +cx88-dvb +cx88-vp3054-i2c +cx88xx +cxacru +cxgb +cxgb3 +cyber2000fb +cyberjack +cyclades +cyclomx +cycx_drv +cypress_cy7c63 +cypress_m8 +cytherm +da903x +DAC960 +davicom +db9 +dc395x +dca +dccp +dccp_ccid2 +dccp_ccid3 +dccp_diag +dccp_ipv4 +dccp_ipv6 +dccp_probe +dccp_tfrc_lib +dcdbas +de2104x +de4x5 +de600 +de620 +decnet +deflate +defxx +dell_rbu +des_generic +dib0070 +dib3000mb +dib3000mc +dib7000m +dib7000p +dibx000_common +digi_acceleport +dilnetpc +diskonchip +display +divacapi +divadidd +diva_idi +diva_mnt +divas +dlci +dlm +dm1105 +dm9601 +dm-bbr +dm-crypt +dme1737 +dmfe +dm-loop +dm-mem-cache +dm-message +dm-raid4-5 +dm-region_hash +dmx3191d +dm-zero +dn_rtmsg +doc2000 +doc2001 +doc2001plus +docecc +docprobe +dpt_i2o +drbd +drm +drx397xD +ds1621 +ds1682 +ds2482 +ds2490 +ds2760_battery +dsbr100 +dscc4 +dss1_divert +dst +dst_ca +dstr +dtl1_cs +dummy +dummy_hcd +dv1394 +dvb-bt8xx +dvb-core +dvb-pll +dvb-ttpci +dvb-ttusb-budget +dvb-usb +dvb-usb-a800 +dvb-usb-af9005 +dvb-usb-af9005-remote +dvb-usb-af9015 +dvb-usb-anysee +dvb-usb-au6610 +dvb-usb-cinergyT2 +dvb-usb-cxusb +dvb-usb-dib0700 +dvb-usb-dibusb-common +dvb-usb-dibusb-mb +dvb-usb-dibusb-mc +dvb-usb-digitv +dvb-usb-dtt200u +dvb-usb-dtv5100 +dvb-usb-dw2102 +dvb-usb-gl861 +dvb-usb-gp8psk +dvb-usb-m920x +dvb-usb-nova-t-usb2 +dvb-usb-opera +dvb-usb-ttusb2 +dvb-usb-umt-010 +dvb-usb-vp702x +dvb-usb-vp7045 +e100 +e1000 +e1000e +e752x_edac +eata +ebt_802_3 +ebtable_broute +ebtable_filter +ebtable_nat +ebtables +ebt_among +ebt_arp +ebt_arpreply +ebt_dnat +ebt_ip +ebt_ip6 +ebt_limit +ebt_log +ebt_mark +ebt_mark_m +ebt_nflog +ebt_pkttype +ebt_redirect +ebt_snat +ebt_stp +ebt_ulog +ebt_vlan +ecb +econet +edac_core +eeepc-laptop +eepro100 +eeprom +eeprom_93cx6 +efs +elo +elsa_cs +em28xx +em28xx-alsa +em28xx-dvb +em_cmp +emi26 +emi62 +em_meta +em_nbyte +empeg +em_text +emu10k1-gp +em_u32 +enclosure +eni +enic +epat +epca +epia +epic100 +eql +esb2rom +esi-sir +esp4 +esp6 +et131x +et61x251 +eth1394 +eurotechwdt +evbug +exportfs +f71805f +f71882fg +f75375s +fakephp +farsync +fat +faulty +fbcon +fb_ddc +fb_sys_fops +fcrypt +fdomain +fdomain_cs +fealnx +ff-memless +firestream +firewire-core +firewire-ohci +firewire-sbp2 +fit2 +fit3 +floppy +fm801-gp +fmvj18x_cs +font +forcedeth +fore_200e +freevxfs +friq +frpw +fsam7400 +fscher +fschmd +fscpos +ftdi-elan +ftdi_sio +ftl +fujitsu-laptop +fujitsu_ts +funsoft +g450_pll +gadgetfs +gamecon +gameport +garmin_gps +garp +g_cdc +gcm +gdth +generic_serial +gen_probe +g_ether +gf128mul +gf2k +g_file_storage +gfs2 +gigaset +girbil-sir +gl518sm +gl520sm +gl620a +gpio_keys +gpio_mouse +grip +grip_mp +gru +g_serial +gspca_conex +gspca_etoms +gspca_finepix +gspca_m5602 +gspca_main +gspca_mars +gspca_ov519 +gspca_pac207 +gspca_pac7311 +gspca_sonixb +gspca_sonixj +gspca_spca500 +gspca_spca501 +gspca_spca505 +gspca_spca506 +gspca_spca508 +gspca_spca561 +gspca_stk014 +gspca_sunplus +gspca_t613 +gspca_tv8532 +gspca_vc032x +gspca_zc3xx +gtco +guillemot +gunze +gx1fb +gxfb +g_zero +hamachi +hangcheck-timer +hci_uart +hci_vhci +hdaps +hdlc +hdlc_cisco +hdlcdrv +hdlc_fr +hdlc_ppp +hdlc_raw +hdlc_raw_eth +hdlc_x25 +he +heci +hecubafb +hermes +hermes_dld +hexium_gemini +hexium_orion +hfc4s8s_l1 +hfcmulti +hfcpci +hfc_usb +hfs +hfsplus +hgafb +hid-a4tech +hid-apple +hid-belkin +hid-bright +hid-cherry +hid-chicony +hid-cypress +hid-dell +hid-ezkey +hid-gyration +hid-logitech +hid-microsoft +hid-monterey +hidp +hid-petalynx +hid-pl +hid-samsung +hid-sony +hid-sunplus +hid-tmff +hid-zpff +hifn_795x +hisax +hisax_fcpcipnp +hisax_isac +hisax_st5481 +horizon +hostap +hostap_cs +hostap_pci +hostap_plx +hp100 +hp4x +hpfs +hpilo +hptiop +hp-wmi +hso +htc-pasic3 +hwa-hc +hwa-rc +hwmon-vid +hysdn +i1480-dfu-usb +i1480-est +i1480u-wlp +i2c-algo-bit +i2c-algo-pca +i2c-algo-pcf +i2c-ali1535 +i2c-ali1563 +i2c-ali15x3 +i2c-amd756 +i2c-amd756-s4882 +i2c-amd8111 +i2c-dev +i2c-gpio +i2c-i801 +i2c-isch +i2c-matroxfb +i2c-nforce2 +i2c-nforce2-s4985 +i2c-ocores +i2c-parport +i2c-parport-light +i2c-pca-platform +i2c-piix4 +i2c-simtec +i2c-sis5595 +i2c-sis630 +i2c-sis96x +i2c-stub +i2c-taos-evm +i2c-tiny-usb +i2c-via +i2c-viapro +i2c-voodoo3 +i2o_block +i2o_bus +i2o_config +i2o_core +i2o_proc +i2o_scsi +i3000_edac +i5000_edac +i5100_edac +i5k_amb +i6300esb +i7300_idle +i810 +i82092 +i82975x_edac +i830 +i8k +i915 +ib700wdt +ib_addr +ib_cm +ib_core +ib_ipath +ib_ipoib +ib_iser +ib_mad +ibmaem +ibmasm +ibmasr +ibmcam +ibmpex +ib_mthca +ibmtr_cs +ib_sa +ib_srp +ib_ucm +ib_umad +ib_uverbs +ichxrom +icplus +ics932s401 +idmouse +idt77252 +ieee1394 +ieee80211 +ieee80211_crypt +ieee80211_crypt_ccmp +ieee80211_crypt_tkip +ieee80211_crypt_wep +ifb +iforce +igb +ili9320 +imm +inet_lro +inexio +inftl +initio +input-polldev +intel-agp +intelfb +intel_menlow +intel-rng +intel_vr_nor +interact +ioatdma +ioc4 +io_edgeport +io_ti +iowarrior +ip2 +ip6_queue +ip6table_filter +ip6table_mangle +ip6table_raw +ip6_tables +ip6table_security +ip6t_ah +ip6t_eui64 +ip6t_frag +ip6t_hbh +ip6t_hl +ip6t_HL +ip6t_ipv6header +ip6t_LOG +ip6t_mh +ip6t_REJECT +ip6t_rt +ip6_tunnel +ipaq +ipcomp +ipcomp6 +ipddp +ipg +ip_gre +iphase +ipip +ipmi_devintf +ipmi_msghandler +ipmi_poweroff +ipmi_si +ipmi_watchdog +ip_queue +ipr +ips +iptable_filter +iptable_mangle +iptable_nat +iptable_raw +ip_tables +iptable_security +ipt_addrtype +ipt_ah +ipt_CLUSTERIP +ipt_ecn +ipt_ECN +ipt_LOG +ipt_MASQUERADE +ipt_NETMAP +ipt_REDIRECT +ipt_REJECT +ipt_ttl +ipt_TTL +ipt_ULOG +ip_vs +ip_vs_dh +ip_vs_ftp +ip_vs_lblc +ip_vs_lblcr +ip_vs_lc +ip_vs_nq +ip_vs_rr +ip_vs_sed +ip_vs_sh +ip_vs_wlc +ip_vs_wrr +ipw +ipw2100 +ipw2200 +ipwireless +ipx +ircomm +ir-common +ircomm-tty +irda +irda-usb +ir-kbd-i2c +irlan +irnet +irtty-sir +iscsi_ibft +iscsi_tcp +iscsi_trgt +isdn +isdn_bsdcomp +isdnhdlc +isight_firmware +isl6405 +isl6421 +isofs +isp116x-hcd +isp1760 +istallion +it87 +it8712f_wdt +it87_wdt +iTCO_vendor_support +iTCO_wdt +itd1000 +ivtv +ivtvfb +iw_c2 +iw_cm +iw_cxgb3 +iwl3945 +iwlagn +iwlcore +ixgb +ixgbe +ixj +ixj_pcmcia +jedec_probe +jffs2 +jfs +jme +joydev +joydump +jsm +k8temp +kafs +kahlua +kaweth +kb3886_bl +kbic +kbtab +kernelcapi +keyspan +keyspan_pda +keyspan_remote +khazad +kingsun-sir +kl5kusb105 +kobil_sct +konicawc +ks0108 +ks0127 +ks959-sir +ksdazzle-sir +ktti +kvm +kvm-amd +kvm-intel +kyrofb +l1oip +l440gx +l64781 +lanai +lapb +lapbether +lcd +ldusb +lec +led-class +leds-da903x +leds-gpio +leds-hp-disk +leds-pca9532 +leds-pca955x +ledtrig-backlight +ledtrig-default-on +ledtrig-heartbeat +ledtrig-timer +legousbtower +lgdt330x +lgs8gl5 +libcrc32c +libertas +libertas_cs +libertas_sdio +libertas_tf +libertas_tf_usb +libiscsi +libsas +libsrp +lightning +linear +lirc_atiusb +lirc_bt829 +lirc_cmdir +lirc_dev +lirc_gpio +lirc_i2c +lirc_igorplugusb +lirc_imon +lirc_it87 +lirc_mceusb +lirc_mceusb2 +lirc_pvr150 +lirc_sasem +lirc_serial +lirc_serial_igor +lirc_sir +lirc_streamzap +lirc_ttusbir +lis3lv02d +litelink-sir +lkkbd +llc2 +lm63 +lm70 +lm75 +lm77 +lm78 +lm80 +lm83 +lm85 +lm87 +lm90 +lm92 +lm93 +lmc +lmpcm_usb +lnbp21 +lockd +lock_dlm +lp +lpfc +lrw +ltv350qv +lxfb +lxt +lzo +lzo_compress +lzo_decompress +m25p80 +m52790 +ma600-sir +mac80211 +machzwd +macmodes +macvlan +magellan +map_absent +map_funcs +map_ram +map_rom +marvell +matroxfb_accel +matroxfb_base +matroxfb_crtc2 +matroxfb_DAC1064 +matroxfb_g450 +matroxfb_maven +matroxfb_misc +matroxfb_Ti3026 +matrox_w1 +max1111 +max1619 +max6650 +max6875 +max7301 +max732x +mb862xxfb +mbp_nvidia_bl +mcp2120-sir +mcp23s08 +mcs7780 +mcs7830 +mct_u232 +md4 +mdc800 +mdio-bitbang +megaraid +megaraid_mbox +megaraid_mm +megaraid_sas +metronomefb +meye +mga +michael_mic +microcode +microtek +mii +minix +mISDN_core +mISDN_dsp +mk712 +mkiss +mlx4_core +mlx4_en +mlx4_ib +mmc_block +mmc_spi +mos7720 +mos7840 +moto_modem +moxa +mpoa +mptbase +mptctl +mptfc +mptlan +mptsas +mptscsih +mptspi +mpu401 +msdos +msi-laptop +msp3400 +msr +mt2060 +mt20xx +mt2131 +mt2266 +mt312 +mt352 +mt9m001 +mt9m111 +mt9v022 +mtd +mtd_blkdevs +mtdblock +mtdblock_ro +mtdchar +mtdconcat +mtd_dataflash +mtdoops +mtdram +mtouch +multipath +mwave +mxb +mxl5005s +mxl5007t +mxser +myri10ge +nand +nand_ecc +nand_ids +nandsim +natsemi +navman +nbd +ncpfs +ndiswrapper +ne2k-pci +neofb +net1080 +netconsole +netrom +netsc520 +nettel +netwave_cs +netxen_nic +newtonkbd +nf_conntrack +nf_conntrack_amanda +nf_conntrack_ftp +nf_conntrack_h323 +nf_conntrack_ipv4 +nf_conntrack_ipv6 +nf_conntrack_irc +nf_conntrack_netbios_ns +nf_conntrack_netlink +nf_conntrack_pptp +nf_conntrack_proto_gre +nf_conntrack_proto_sctp +nf_conntrack_proto_udplite +nf_conntrack_sip +nf_conntrack_tftp +nf_defrag_ipv4 +nf_nat +nf_nat_amanda +nf_nat_ftp +nf_nat_h323 +nf_nat_irc +nf_nat_pptp +nf_nat_proto_gre +nf_nat_proto_sctp +nf_nat_proto_udplite +nf_nat_sip +nf_nat_snmp_basic +nf_nat_tftp +nfnetlink +nfnetlink_log +nfnetlink_queue +nfs +nfs_acl +nfsd +nftl +nf_tproxy_core +n_hdlc +niu +nls_ascii +nls_cp1250 +nls_cp1251 +nls_cp1255 +nls_cp437 +nls_cp737 +nls_cp775 +nls_cp850 +nls_cp852 +nls_cp855 +nls_cp857 +nls_cp860 +nls_cp861 +nls_cp862 +nls_cp863 +nls_cp864 +nls_cp865 +nls_cp866 +nls_cp869 +nls_cp874 +nls_cp932 +nls_cp936 +nls_cp949 +nls_cp950 +nls_euc-jp +nls_iso8859-1 +nls_iso8859-13 +nls_iso8859-14 +nls_iso8859-15 +nls_iso8859-2 +nls_iso8859-3 +nls_iso8859-4 +nls_iso8859-5 +nls_iso8859-6 +nls_iso8859-7 +nls_iso8859-9 +nls_koi8-r +nls_koi8-ru +nls_koi8-u +nls_utf8 +nmclan_cs +nozomi +n_r3964 +ns558 +ns83820 +nsc_gpio +nsc-ircc +ntfs +nvidiafb +nvram +nxt200x +nxt6000 +ocfs2 +ocfs2_dlm +ocfs2_dlmfs +ocfs2_nodemanager +ocfs2_stackglue +ocfs2_stack_o2cb +ocfs2_stack_user +ohci1394 +old_belkin-sir +olympic +omfs +omninet +on20 +on26 +onenand +onenand_sim +opl3 +oprofile +option +or51132 +or51211 +orinoco +orinoco_cs +orinoco_nortel +orinoco_pci +orinoco_plx +orinoco_tmd +osst +oti6858 +output +ov511 +ov511_decomp +ov518_decomp +ov7670 +ovcamchip +p4-clockmod +p54common +p54pci +p54usb +p80211 +p8023 +panasonic-laptop +paride +parkbd +parport +parport_ax88796 +parport_cs +parport_pc +parport_serial +pas2 +pata_cmd640 +pata_cypress +pata_hpt3x2n +pata_it8213 +pata_ninja32 +pata_opti +pata_optidma +pata_pcmcia +pata_radisys +pbe5 +pc87360 +pc8736x_gpio +pc87413_wdt +pc87427 +pca953x +pcbc +pcd +pcf857x +pcf8591 +pci +pci200syn +pcilynx +pcips2 +pcmcia +pcmcia_core +pcnet32 +pcnet_cs +pcspkr +pcwd_pci +pcwd_usb +pd +pd6729 +pda_power +pegasus +penmount +pf +pg +phantom +phidget +phidgetkit +phidgetmotorcontrol +phidgetservo +phonedev +phonet +phram +physmap +pktgen +pl2303 +platform_lcd +plat_nand +plat-ram +plip +plusb +pluto2 +pm2fb +pm3fb +pmc551 +pn_pep +powermate +ppa +ppdev +ppp_async +ppp_deflate +ppp_mppe +pppoatm +pppoe +pppol2tp +pppox +ppp_synctty +prism2_usb +prism54 +progear_bl +psmouse +pss +pt +pvrusb2 +pwc +qla1280 +qla2xxx +qla3xxx +qla4xxx +qlge +qlogic_cs +qlogicfas408 +qnx4 +qsemi +qt1010 +quickcam +quickcam_messenger +quota_v1 +quota_v2 +r128 +r8169 +r8a66597-hcd +radeon +radeonfb +radio-gemtek-pci +radio-maestro +radio-maxiradio +radio-mr800 +radio-si470x +raid0 +raid1 +raid10 +raid456 +raid_class +raw +raw1394 +ray_cs +rdma_cm +rdma_ucm +redboot +reed_solomon +reiserfs +rfc1051 +rfc1201 +rfd_ftl +rfkill-input +ricoh_mmc +rio +rio500 +riscom8 +rivafb +rmd128 +rmd160 +rmd256 +rmd320 +rndis_host +rndis_wlan +rocket +romfs +rose +rpcsec_gss_krb5 +rpcsec_gss_spkm3 +rrunner +rsrc_nonstatic +rt2400pci +rt2500pci +rt2500usb +rt2860sta +rt2870sta +rt2x00lib +rt2x00pci +rt2x00usb +rt61pci +rt73usb +rtc-bq4802 +rtc-ds1286 +rtc-ds1305 +rtc-ds1307 +rtc-ds1374 +rtc-ds1390 +rtc-ds1553 +rtc-ds1672 +rtc-ds1742 +rtc-ds3234 +rtc-fm3130 +rtc-isl1208 +rtc-m41t80 +rtc-m41t94 +rtc-m48t35 +rtc-m48t59 +rtc-m48t86 +rtc-max6900 +rtc-max6902 +rtc-pcf8563 +rtc-pcf8583 +rtc-rs5c348 +rtc-rs5c372 +rtc-rx8581 +rtc-stk17ta8 +rtc-test +rtc-v3020 +rtc-wm8350 +rtc-x1205 +rtl8150 +rtl8180 +rtl8187 +rtl8187se +rxkad +s1d13xxxfb +s2255drv +s2io +s3fb +s5h1409 +s5h1411 +s5h1420 +saa5246a +saa5249 +saa6588 +saa6752hs +saa7110 +saa7111 +saa7114 +saa7115 +saa7127 +saa7134 +saa7134-alsa +saa7134-dvb +saa7134-empress +saa7146 +saa7146_vv +saa717x +saa7185 +safe_serial +salsa20_generic +salsa20-x86_64 +sata_mv +savage +savagefb +sb +sb1000 +sbc60xxwdt +sbc8360 +sbc_epx_c3 +sbc_gxx +sb_lib +sbni +sbp2 +sc1200wdt +sc520cdp +sc520_wdt +sc92031 +scb2_flash +sch_atm +sch_cbq +sch_dsmark +sch_gred +sch_hfsc +sch_htb +sch_ingress +sch_multiq +sch_netem +sch_prio +sch_red +sch_sfq +sch_tbf +sch_teql +scsi_debug +scsi_dh_alua +scsi_dh_emc +scsi_dh_hp_sw +scsi_dh_rdac +scsi_tgt +scsi_transport_fc +scsi_transport_iscsi +scsi_transport_sas +scsi_transport_spi +scsi_transport_srp +scsi_wait_scan +sctp +sdhci +sdhci-pci +sdio_uart +sdricoh_cs +se401 +sedlbauer_cs +seed +seqiv +ser_gigaset +serial_cs +serio_raw +sermouse +serpent +serport +ses +sfc +sha1_generic +sha256_generic +sha512_generic +sh_mobile_ceu_camera +shpchp +si21xx +sidewinder +sierra +sir-dev +sis +sis190 +sis5595 +sis900 +sis-agp +sisfb +sisusbvga +sit +skfp +skge +sky2 +sl811_cs +sl811-hcd +slip +slram +sm501 +sm501fb +smbfs +smc91c92_cs +sms1xxx +smsc +smsc37b787_wdt +smsc47b397 +smsc47m1 +smsc47m192 +smsc95xx +smsc-ircc2 +sn9c102 +snd +snd-ac97-codec +snd-ad1889 +snd-ak4114 +snd-ak4117 +snd-ak4xxx-adda +snd-ali5451 +snd-als300 +snd-als4000 +snd-atiixp +snd-atiixp-modem +snd-au8810 +snd-au8820 +snd-au8830 +snd-aw2 +snd-azt3328 +snd-bt87x +snd-ca0106 +snd-cmipci +snd-cs4281 +snd-cs46xx +snd-cs5530 +snd-cs8427 +snd-darla20 +snd-darla24 +snd-dummy +snd-echo3g +snd-emu10k1 +snd-emu10k1-synth +snd-emu10k1x +snd-emux-synth +snd-ens1370 +snd-ens1371 +snd-es1938 +snd-es1968 +snd-fm801 +snd-gina20 +snd-gina24 +snd-hda-intel +snd-hdsp +snd-hdspm +snd-hifier +snd-hwdep +snd-i2c +snd-ice1712 +snd-ice1724 +snd-ice17xx-ak4xxx +snd-indigo +snd-indigodj +snd-indigoio +snd-intel8x0 +snd-intel8x0m +snd-korg1212 +snd-layla20 +snd-layla24 +snd-maestro3 +snd-mia +snd-mixart +snd-mixer-oss +snd-mona +snd-mpu401 +snd-mpu401-uart +snd-mtpav +snd-mts64 +snd-nm256 +snd-opl3-lib +snd-opl3-synth +snd-oxygen +snd-oxygen-lib +snd-page-alloc +snd-pcm +snd-pcm-oss +snd-pcsp +snd-pcxhr +snd-pdaudiocf +snd-portman2x4 +snd-pt2258 +snd-rawmidi +snd-riptide +snd-rme32 +snd-rme96 +snd-rme9652 +snd-sb16-dsp +snd-sb-common +snd-seq +snd-seq-device +snd-seq-dummy +snd-seq-midi +snd-seq-midi-emul +snd-seq-midi-event +snd-seq-oss +snd-seq-virmidi +snd-serial-u16550 +snd-soc-ad73311 +snd-soc-ak4535 +snd-soc-core +snd-soc-cs4270 +snd-soc-ssm2602 +snd-soc-tlv320aic23 +snd-soc-tlv320aic26 +snd-soc-tlv320aic3x +snd-soc-uda1380 +snd-soc-wm8510 +snd-soc-wm8580 +snd-soc-wm8731 +snd-soc-wm8750 +snd-soc-wm8753 +snd-soc-wm8900 +snd-soc-wm8903 +snd-soc-wm8971 +snd-soc-wm8990 +snd-sonicvibes +snd-tea575x-tuner +snd-timer +snd-trident +snd-usb-audio +snd-usb-caiaq +snd-usb-lib +snd-usb-us122l +snd-usb-usx2y +snd-util-mem +snd-via82xx +snd-via82xx-modem +snd-virmidi +snd-virtuoso +snd-vx222 +snd-vx-lib +snd-vxpocket +snd-ymfpci +soc_camera +soc_camera_platform +softcursor +softdog +sony-laptop +sound +soundcore +sound_firmware +sp8870 +sp887x +spaceball +spaceorb +spcp8x5 +specialix +spectrum_cs +speedstep-lib +speedtch +spi_bitbang +spi_butterfly +spidev +spi_lm70llp +squashfs +ssb +sscape +ssfdc +sstfb +st +stallion +starfire +stb6000 +stex +stinger +stir4200 +stkwebcam +stowaway +stp +stradis +strip +stv0288 +stv0297 +stv0299 +stv680 +sundance +sungem +sungem_phy +sunhme +suni +sunkbd +sunrpc +svcrdma +svgalib +sx +sx8 +sym53c500_cs +sym53c8xx +synclink +synclink_cs +synclink_gt +synclinkmp +syncppp +syscopyarea +sysfillrect +sysimgblt +sysv +t1pci +tcp_bic +tcp_highspeed +tcp_htcp +tcp_hybla +tcp_illinois +tcp_lp +tcp_probe +tcp_scalable +tcp_vegas +tcp_veno +tcp_westwood +tcp_yeah +tcrypt +tda10021 +tda10023 +tda10048 +tda1004x +tda10086 +tda18271 +tda7432 +tda8083 +tda826x +tda827x +tda8290 +tda9840 +tda9875 +tda9887 +tdfx +tdfxfb +tdo24m +tea +tea5761 +tea5767 +tea6415c +tea6420 +tehuti +tekram-sir +teles_cs +tg3 +tgr192 +thinkpad_acpi +thinkpad_ec +thmc50 +tifm_7xx1 +tifm_core +tifm_sd +tileblit +tipc +ti_usb_3410_5052 +tlan +tlclk +tle62x0 +tlsf +tmdc +tms380tr +tmscsim +tmspci +toshiba_acpi +touchit213 +touchright +touchwin +tpm +tpm_atmel +tpm_bios +tpm_infineon +tpm_nsc +tpm_tis +tps65010 +tp_smapi +trancevibrator +tridentfb +trix +ts5500_flash +ts_bm +ts_fsm +ts_kmp +tsl2550 +ttpci-eeprom +ttusb_dec +ttusbdecfe +tua6100 +tulip +tun +tuner +tuner-simple +tuner-types +tuner-xc2028 +tunnel4 +tunnel6 +turbografx +tvaudio +tveeprom +tvp5150 +twidjoy +twofish +twofish_common +twofish-x86_64 +typhoon +u132-hcd +uart401 +uart6850 +ub +ubi +ubifs +ucb1400_core +ucb1400_ts +udf +ueagle-atm +ufs +uinput +uio +uio_cif +uio_pdrv +uio_pdrv_genirq +uio_sercos3 +uio_smx +uli526x +ultracam +umc +umem +unionfs +upd64031a +upd64083 +uPD98402 +usb8xxx +usbatm +usb_debug +usb_gigaset +usbhid +usbkbd +usblcd +usbled +usblp +usbmouse +usbnet +usbsevseg +usb-storage +usbtmc +usbtouchscreen +usbvideo +usbvision +uss720 +uvcvideo +uvesafb +uwb +v4l1-compat +v4l2-common +v4l2-int-device +ves1820 +ves1x93 +vesafb +veth +vfat +vga16fb +vgastate +vgg2432a4 +via +via686a +via-agp +viafb +via-ircc +via-rhine +via-velocity +vicam +video +video1394 +videobuf-core +videobuf-dma-contig +videobuf-dma-sg +videobuf-dvb +videobuf-vmalloc +videocodec +videodev +virtio +virtio_balloon +virtio_blk +virtio_console +virtio_net +virtio_pci +virtio_ring +virtio-rng +virtual +visor +vitesse +vivi +vlsi_ir +v_midi +vmlfb +vp27smpx +vpx3220 +vstusb +vsxxxaa +vt1211 +vt8231 +vt8623fb +w1_bq27000 +w1_ds2433 +w1_ds2760 +w1-gpio +w1_smem +w1_therm +w83627ehf +w83627hf +w83627hf_wdt +w83697hf_wdt +w83697ug_wdt +w83781d +w83791d +w83792d +w83793 +w83877f_wdt +w83977af_ir +w83977f_wdt +w83l785ts +w83l786ng +w9966 +w9968cf +wacom +wafer5823wdt +wanrouter +wanxl +warrior +wavelan_cs +wbsd +wdt_pci +whci +whci-hcd +whc-rc +whiteheat +winbond-840 +wire +wl3501_cs +wlp +wm8350 +wm8350-i2c +wm8350-regulator +wm8400-core +wm8400-regulator +wm8739 +wm8775 +wm97xx-ts +wp512 +wusb-cbaf +wusbcore +wusb-wa +x25 +x25_asy +x38_edac +xc5000 +xcbc +xen-blkfront +xen-fbfront +xen-kbdfront +xen-netfront +xfrm4_mode_beet +xfrm4_mode_transport +xfrm4_mode_tunnel +xfrm4_tunnel +xfrm6_mode_beet +xfrm6_mode_ro +xfrm6_mode_transport +xfrm6_mode_tunnel +xfrm6_tunnel +xfrm_ipcomp +xfrm_user +xfs +xirc2ps_cs +xircom_cb +xor +xp +xpad +xpc +xpnet +xprtrdma +x_tables +xt_CLASSIFY +xt_comment +xt_connbytes +xt_connlimit +xt_connmark +xt_CONNMARK +xt_CONNSECMARK +xt_conntrack +xt_dccp +xt_dscp +xt_DSCP +xt_esp +xt_hashlimit +xt_helper +xt_iprange +xtkbd +xt_length +xt_limit +xt_mac +xt_mark +xt_MARK +xt_multiport +xt_NFLOG +xt_NFQUEUE +xt_NOTRACK +xt_owner +xt_physdev +xt_pkttype +xt_policy +xt_quota +xt_rateest +xt_RATEEST +xt_realm +xt_recent +xts +xt_sctp +xt_SECMARK +xt_socket +xt_state +xt_statistic +xt_string +xt_tcpmss +xt_TCPMSS +xt_tcpudp +xt_time +xt_TPROXY +xt_TRACE +xt_u32 +xusbatm +yam +yealink +yellowfin +yenta_socket +zatm +zaurus +zc0301 +zd1201 +zd1211rw +zhenhua +zl10353 +zlib_deflate +zr36016 +zr36050 +zr36060 +zr36067 +zr364xx --- linux-2.6.28.orig/debian/tests/README +++ linux-2.6.28/debian/tests/README @@ -0,0 +1,21 @@ +Scripts placed in this directory get called one at a time by run-parts(8). +The scripts are expected to perform some sort of sanity checks on the +finished build. Scripts will be called once for each flavour. + +Some environment variables are exported to make life a little easier: + +DPKG_ARCH : The dpkg architecture (e.g. "amd64") +KERN_ARCH : The kernel architecture (e.g. "x86_64") +FLAVOUR : The specific flavour for this run (e.g. "generic") +VERSION : The full version of this build (e.g. 2.6.22-1) +REVISION : The exact revision of this build (e.g. 1.3) +PREV_REVISION : The revision prior to this one +ABI_NUM : The specific ABI number for this build (e.g. 2) +PREV_ABI_NUM : The previous ABI number. Can be the same as ABI_NUM. +BUILD_DIR : The directory where this build took place +INSTALL_DIR : The directory where the package is prepared +SOURCE_DIR : Where the main kernel source is + +Scripts are expected to have a zero exit status when no problems occur, +and non-zero when an error occurs that should stop the build. Scripts +should print whatever info they deem needed to deduce the problem. --- linux-2.6.28.orig/debian/tests/check-aliases +++ linux-2.6.28/debian/tests/check-aliases @@ -0,0 +1,24 @@ +#!/usr/bin/perl -w + +my %map; + +print "Checking for dupe aliases in $ENV{'FLAVOUR'}...\n"; + +$aliases = + "$ENV{'INSTALL_DIR'}/lib/modules/$ENV{'VERSION'}-$ENV{'FLAVOUR'}/modules.alias"; + +open(ALIASES, "< $aliases") or die "Could not open $aliases"; + +while () { + chomp; + my ($junk, $alias, $module) = split; + + if (defined($map{$alias})) { + printf("%s %20s / %-20s : %s \n", ("$map{$alias}" eq "$module") + ? "INT" : " ", $map{$alias}, $module, $alias); + } else { + $map{$alias} = $module; + } +} + +exit(0); --- linux-2.6.28.orig/debian/commit-templates/patch +++ linux-2.6.28/debian/commit-templates/patch @@ -0,0 +1,28 @@ +# Ubuntu commit template. +# +# NOTE: This gets reformatted for debian/changelog +# +# The initial UBUNTU is a flag that this is an Ubuntu commit. It will be +# referenced to the Author in the debian/changelog entry. +# +# The text following is the short message that will be placed in the +# changelog. Extra text on the following lines will be ignored, but left +# in the git commit. Lines with # will be ignored in the commit. +# +# OriginalAuthor allows for alternate attribution. +# +# OriginalLocation allows for a URL or description of where the patch came +# from. +# +# Bug is a reference to a Malone bug number. Be sure to include the '#' as +# part of the bug number, e.g., 'Bug: #1'. +# +# Ignore: yes will keep this commit from showing up in the changelog. +# +UBUNTU: + +# OriginalAuthor: +# OriginalLocation: +# Bug: # +# Ignore: yes +# Other text below here. --- linux-2.6.28.orig/debian/commit-templates/sauce-patch +++ linux-2.6.28/debian/commit-templates/sauce-patch @@ -0,0 +1,38 @@ +# Ubuntu commit template. +# +# NOTE: This gets reformatted for debian/changelog +# +# +# SAUCE refers to the fact that this patch might not go upstream, but we need to +# carry it to successive releases. In most cases you DONOT want to use this +# template. +# +# An example of a SAUCE patch is the ACPI DSDT-in-initramfs patch which has been +# refused upstream, but still provides useful functionality to users with broken +# BIOSes. +# +#------------------------------------------------------------------------- +# +# The initial UBUNTU is a flag that this is an Ubuntu commit. It will be +# referenced to the Author in the debian/changelog entry. +# +# The text following is the short message that will be placed in the +# changelog. Extra text on the following lines will be ignored, but left +# in the git commit. Lines with # will be ignored in the commit. +# +# OriginalAuthor allows for alternate attribution. +# +# OriginalLocation allows for a URL or description of where the patch came +# from. +# +# Bug is a reference to a Malone bug number. +# +# Ignore: yes will keep this commit from showing up in the changelog. +# +UBUNTU: SAUCE: + +# OriginalAuthor: +# OriginalLocation: +# Bug: # +# Ignore: yes +# Other text below here. --- linux-2.6.28.orig/debian/commit-templates/bumpabi +++ linux-2.6.28/debian/commit-templates/bumpabi @@ -0,0 +1,3 @@ +UBUNTU: Bump ABI + +Ignore: yes --- linux-2.6.28.orig/debian/commit-templates/missing-modules +++ linux-2.6.28/debian/commit-templates/missing-modules @@ -0,0 +1,3 @@ +UBUNTU: build/modules: Add modules that have intentionally gone missing + +Ignore: yes --- linux-2.6.28.orig/debian/commit-templates/external-driver +++ linux-2.6.28/debian/commit-templates/external-driver @@ -0,0 +1,20 @@ +# Ubuntu external driver commit. +# +# NOTE: This gets reformatted for README.Ubuntu-External-Drivers and +# debian/changelog. +# +# This is only needed when a driver is added, updated or removed. It is +# not needed when patches or fixes are applied to the driver. If the +# driver is being removed, add the line: +# +# Removing: yes +# +# to the commit, and you can remove all other tags (except UBUNTU:). +# +UBUNTU: + +ExternalDriver: +Description: +Url: +Mask: +Version: --- linux-2.6.28.orig/debian/commit-templates/newrelease +++ linux-2.6.28/debian/commit-templates/newrelease @@ -0,0 +1,3 @@ +UBUNTU: Start new release + +Ignore: yes --- linux-2.6.28.orig/debian/commit-templates/update-configs +++ linux-2.6.28/debian/commit-templates/update-configs @@ -0,0 +1,10 @@ +# +# This template is used for commit messages that don't need to +# show up in debian/changelog. Administrative stuff like config +# updates, ABI bumps, etc. Setting 'Ignore: yes' prevents +# 'debian/rules insertchanges' from inserting this commit meesage +# as a changelog entry. +# +UBUNTU: Updating configs + +Ignore: yes --- linux-2.6.28.orig/debian/control-scripts/prerm +++ linux-2.6.28/debian/control-scripts/prerm @@ -0,0 +1,307 @@ +#! /usr/bin/perl +# -*- Mode: Perl -*- +# image.prerm --- +# Author : root ( root@melkor.pilgrim.umass.edu ) +# Created On : Fri May 17 03:28:59 1996 +# Created On Node : melkor.pilgrim.umass.edu +# Last Modified By : Manoj Srivastava +# Last Modified On : Sat Aug 5 13:14:17 2006 +# Last Machine Used: glaurung.internal.golden-gryphon.com +# Update Count : 85 +# Status : Unknown, Use with caution! +# HISTORY : +# Description : +# +# +# $Id: image.prerm,v 1.22 2003/10/07 16:24:20 srivasta Exp $ +# +# +#use strict; + +$|=1; +# Predefined values: +my $version = "=V"; +my $link_in_boot = ""; # Should be empty, mostly +my $no_symlink = ""; # Should be empty, mostly +my $reverse_symlink = ""; # Should be empty, mostly +my $do_symlinks = "Yes"; # target machine defined +my $do_boot_enable = "Yes"; # target machine defined +my $do_bootfloppy = "Yes"; # target machine defined +my $do_bootloader = "Yes"; # target machine defined +my $move_image = ''; # target machine defined +my $kimage = "=K"; # Should be empty, mostly +my $loader = "=L"; # lilo, silo, quik, palo, vmelilo, or nettrom +my $image_dir = "/boot"; # where the image is located +my $clobber_modules = ''; # target machine defined +my $initrd = "YES"; # initrd kernel +my $use_hard_links = ''; # hardlinks do not wirk across fs boundaries +my $postinst_hook = ''; #Normally we do not +my $postrm_hook = ''; #Normally we do not +my $preinst_hook = ''; #Normally we do not +my $prerm_hook = ''; #Normally we do not +my $minimal_swap = ''; # Do not swap symlinks +my $ignore_depmod_err = ''; # normally we do not +my $relink_build_link = 'YES'; # There is no harm in checking the link +my $force_build_link = ''; # There is no harm in checking the link +my $kernel_arch = "=B"; +my $ramdisk = "/usr/sbin/update-initramfs"; +my $package_name = "linux-image-$version"; + +my $Loader = "NoLOADER"; # +$Loader = "LILO" if $loader =~ /^lilo/io; +$Loader = "SILO" if $loader =~ /^silo/io; +$Loader = "QUIK" if $loader =~ /^quik/io; +$Loader = "yaboot" if $loader =~ /^yaboot/io; +$Loader = "PALO" if $loader =~ /^palo/io; +$Loader = "NETTROM" if $loader =~ /^nettrom/io; +$Loader = "VMELILO" if $loader =~ /^vmelilo/io; +$Loader = "ZIPL" if $loader =~ /^zipl/io; +$Loader = "ELILO" if $loader =~ /^elilo/io; + + +# This should not point to /tmp, because of security risks. +my $temp_file_name = "/var/log/$loader" . "_log.$$"; + +#known variables +my $image_dest = "/"; +my $realimageloc = "/$image_dir/"; +my $have_conffile = ""; +my $CONF_LOC = '/etc/kernel-img.conf'; +my $relative_links = ''; +my $silent_loader = ''; +my $warn_reboot = 'Yes'; # Warn that we are installing a version of + # the kernel we are running + +# remove multiple leading slashes; make sure there is at least one. +$realimageloc =~ s|^/*|/|o; +$realimageloc =~ s|/+|/|o; + +my $DEBUG = 0; + +# Variables used +my $image=''; +my $ret=0; +my $seen=''; +my $answer=''; +my $running = ''; +my $WouldInvalidate = 0; + +if ($ARGV[0] && ($ARGV[0] =~ /remove/ || $ARGV[0] =~ /upgrade/)) { + if (-l "/usr/doc/linux-image-$version") { + unlink "/usr/doc/linux-image-$version"; + } +} + +# Ignore all invocations uxcept when called on to remove +exit 0 unless ($ARGV[0] && $ARGV[0] =~ /remove/) ; + +# Paranoid check to make sure that the correct value is put in there +if (! $kimage) { $kimage = "vmlinuz";} # Hmm. empty +elsif ($kimage =~ m/^b?zImage$/o) { $kimage = "vmlinuz";} # these produce vmlinuz +elsif ($kimage =~ m/^[iI]mage$/o) { my $nop = $kimage; } +elsif ($kimage =~ m/^vmlinux$/o) { my $nop = $kimage; } +else { $kimage = "vmlinuz";} # Default + +if (-r "$CONF_LOC" && -f "$CONF_LOC" ) { + if (open(CONF, "$CONF_LOC")) { + while () { + chomp; + s/\#.*$//g; + next if /^\s*$/; + + $do_symlink = "" if /^\s*do_symlinks\s*=\s*(no|false|0)\s*$/ig; + $no_symlink = "" if /^\s*no_symlinks\s*=\s*(no|false|0)\s*$/ig; + $reverse_symlink = "" if /^\s*reverse_symlinks\s*=\s*(no|false|0)\s*$/ig; + $link_in_boot = "" if /^\s*image_in_boot\s*=\s*(no|false|0)\s*$/ig; + $link_in_boot = "" if /^\s*link_in_boot\s*=\s*(no|false|0)\s*$/ig; + $move_image = "" if /^\s*move_image\s*=\s*(no|false|0)\s*$/ig; + $clobber_modules = '' if /^\s*clobber_modules\s*=\s*(no|false|0)\s*$/ig; + $do_boot_enable = '' if /^\s*do_boot_enable\s*=\s*(no|false|0)\s*$/ig; + $do_bootfloppy = '' if /^\s*do_bootfloppy\s*=\s*(no|false|0)\s*$/ig; + $relative_links = '' if /^\s*relative_links \s*=\s*(no|false|0)\s*$/ig; + $do_bootloader = '' if /^\s*do_bootloader\s*=\s*(no|false|0)\s*$/ig; + $do_initrd = '' if /^\s*do_initrd\s*=\s*(no|false|0)\s*$/ig; + $use_hard_links = '' if /^\s*use_hard_links\s*=\s*(no|false|0)\s*$/ig; + $silent_loader = '' if /^\s*silent_loader\s*=\s*(no|false|0)\s*$/ig; + $warn_reboot = '' if /^\s*warn_reboot\s*=\s*(no|false|0)\s*$/ig; + $minimal_swap = '' if /^\s*minimal_swap\s*=\s*(no|false|0)\s*$/ig; + $ignore_depmod_err = '' if /^\s*ignore_depmod_err\s*=\s*(no|false|0)\s*$/ig; + $relink_build_link = '' if /^\s*relink_build_link\s*=\s*(no|false|0)\s*$/ig; + $force_build_link = '' if /^\s*force_build_link\s*=\s*(no|false|0)\s*$/ig; + + + $do_symlink = "Yes" if /^\s*do_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $no_symlink = "Yes" if /^\s*no_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $reverse_symlink = "Yes" if /^\s*reverse_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $link_in_boot = "Yes" if /^\s*image_in_boot\s*=\s*(yes|true|1)\s*$/ig; + $link_in_boot = "Yes" if /^\s*link_in_boot\s*=\s*(yes|true|1)\s*$/ig; + $move_image = "Yes" if /^\s*move_image\s*=\s*(yes|true|1)\s*$/ig; + $clobber_modules = "Yes" if /^\s*clobber_modules\s*=\s*(yes|true|1)\s*$/ig; + $do_boot_enable = "Yes" if /^\s*do_boot_enable\s*=\s*(yes|true|1)\s*$/ig; + $do_bootfloppy = "Yes" if /^\s*do_bootfloppy\s*=\s*(yes|true|1)\s*$/ig; + $do_bootloader = "Yes" if /^\s*do_bootloader\s*=\s*(yes|true|1)\s*$/ig; + $relative_links = "Yes" if /^\s*relative_links\s*=\s*(yes|true|1)\s*$/ig; + $do_initrd = "Yes" if /^\s*do_initrd\s*=\s*(yes|true|1)\s*$/ig; + $use_hard_links = "Yes" if /^\s*use_hard_links\s*=\s*(yes|true|1)\s*$/ig; + $silent_loader = 'Yes' if /^\s*silent_loader\s*=\s*(yes|true|1)\s*$/ig; + $warn_reboot = 'Yes' if /^\s*warn_reboot\s*=\s*(yes|true|1)\s*$/ig; + $minimal_swap = 'Yes' if /^\s*minimal_swap\s*=\s*(yes|true|1)\s*$/ig; + $ignore_depmod_err = 'Yes' if /^\s*ignore_depmod_err\s*=\s*(yes|true|1)\s*$/ig; + $relink_build_link = 'Yes' if /^\s*relink_build_link\s*=\s*(yes|true|1)\s*$/ig; + $force_build_link = 'Yes' if /^\s*force_build_link\s*=\s*(yes|true|1)\s*$/ig; + + $image_dest = "$1" if /^\s*image_dest\s*=\s*(\S+)/ig; + $postinst_hook = "$1" if /^\s*postinst_hook\s*=\s*(\S+)/ig; + $postrm_hook = "$1" if /^\s*postrm_hook\s*=\s*(\S+)/ig; + $preinst_hook = "$1" if /^\s*preinst_hook\s*=\s*(\S+)/ig; + $prerm_hook = "$1" if /^\s*prerm_hook\s*=\s*(\S+)/ig; + $ramdisk = "$1" if /^\s*ramdisk\s*=\s*(.+)$/ig; + } + close CONF; + $have_conffile = "Yes"; + } +} + + +$ENV{KERNEL_ARCH}=$kernel_arch if $kernel_arch; + +#check to see if we are trying to remove a running kernel +# if so we abort right now. +chop($running=`uname -r`); +if ($running eq $version) { + print STDERR "WARN: Proceeding with removing running kernel image.\n"; +} + +#Now, they have an alternate kernel which they are currently running + +# This is just us being nice to lilo users. + +chdir("/") or die "could not chdir to /:$!\n"; + +if (-f "/etc/$loader.conf") { #I know, could be a link, but .. + open (LILO, "/etc/$loader.conf") || &success(); # this is not critical + while () { + chop; + s/\#.*//; # nix the comments + next unless /^\s*image\s*=\s(\S+)/o; + $image = $1; + if ($image && -e $image) { + while (defined($image) && -l $image) { + $image = readlink ($image); + } + if (defined($image) && -e $image) { + $WouldInvalidate |= $image =~ /$kimage-$version/; + } + else { + &success(); # invalid $loader.conf file + } + } + else { + &success(); # invalid $loader.conf file + } + } + close (LILO); + if ($WouldInvalidate) { + print STFERR "WARN: Proceeding with removing running kernel image.\n"; + &success(); + } +} + + +# set the env var stem +$ENV{'STEM'} = "linux"; + +sub exec_script { + my $type = shift; + my $script = shift; + print STDERR "Running $type hook script $script.\n"; + system ("$script $version $realimageloc$kimage-$version") && + print STDERR "User $type hook script [$script] "; + if ($?) { + if ($? == -1) { + print STDERR "failed to execute: $!\n"; + } + elsif ($? & 127) { + printf STDERR "died with signal %d, %s coredump\n", + ($? & 127), ($? & 128) ? 'with' : 'without'; + } + else { + printf STDERR "exited with value %d\n", $? >> 8; + } + exit $? >> 8; + } +} +sub run_hook { + my $type = shift; + my $script = shift; + if ($script =~ m,^/,) { + # Full path provided for the hook script + if (-x "$script") { + &exec_script($type,$script); + } + else { + die "The provided $type hook script [$script] could not be run.\n"; + } + } + else { + # Look for it in a safe path + for my $path ('/bin', '/sbin', '/usr/bin', '/usr/sbin') { + if (-x "$path/$script") { + &exec_script($type, "$path/$script"); + return 0; + } + } + # No luck + print STDERR "Could not find $type hook script [$script].\n"; + die "Looked in: '/bin', '/sbin', '/usr/bin', '/usr/sbin'\n"; + } +} + + +## Run user hook script here, if any +if (-x "$prerm_hook") { + &run_hook("prerm", $prerm_hook); +} +if (-d "/etc/kernel/prerm.d") { + print STDERR "Examining /etc/kernel/prerm.d.\n"; + system ("run-parts --verbose --exit-on-error --arg=$version " . + "--arg=$realimageloc$kimage-$version /etc/kernel/prerm.d") && + die "Failed to process /etc/kernel/prerm.d"; +} +if (-d "/etc/kernel/prerm.d/$version") { + print STDERR "Examining /etc/kernel/prerm.d/$version.\n"; + system ("run-parts --verbose --exit-on-error --arg=$version" . + " --arg=$realimageloc$kimage-$version " . + "/etc/kernel/prerm.d/$version") && + die "Failed to process /etc/kernel/prerm.d/$version"; +} + +sub success () { + my @files_to_remove = qw{ + modules.dep modules.isapnpmap modules.pcimap + modules.usbmap modules.parportmap + modules.generic_string modules.ieee1394map + modules.ieee1394map modules.pnpbiosmap + modules.alias modules.ccwmap modules.inputmap + modules.symbols modules.ofmap modules.seriomap + modules.alias.bin modules.dep.bin modules.symbols.bin + }; + + foreach my $extra_file (@files_to_remove) { + if (-f "/lib/modules/$version/$extra_file") { + unlink "/lib/modules/$version/$extra_file"; + } + } + exit 0; +} + + + +&success(); +exit 0; +__END__ + + + + + --- linux-2.6.28.orig/debian/control-scripts/postinst +++ linux-2.6.28/debian/control-scripts/postinst @@ -0,0 +1,1087 @@ +#! /usr/bin/perl +# OriginalAuthor : Manoj Srivastava ( srivasta@pilgrim.umass.edu ) +# +# Customized for Ubuntu by: Ben Collins + +#use strict; #for debugging +use Cwd 'abs_path'; + +$|=1; + +# Predefined values: +my $version = "=V"; +my $link_in_boot = ""; # Should be empty, mostly +my $no_symlink = ""; # Should be empty, mostly +my $reverse_symlink = ""; # Should be empty, mostly +my $do_symlink = "Yes"; # target machine defined +my $do_boot_enable = "Yes"; # target machine defined +my $do_bootfloppy = "Yes"; # target machine defined +my $do_bootloader = "Yes"; # target machine defined +my $move_image = ''; # target machine defined +my $kimage = "=K"; # Should be empty, mostly +my $loader = "=L"; # lilo, silo, quik, palo, vmelilo, nettrom, arcboot or delo +my $image_dir = "/boot"; # where the image is located +my $clobber_modules = ''; # target machine defined +my $relative_links = ""; # target machine defined +my $initrd = "YES"; # initrd kernel +my $do_initrd = ''; # Normally we do not +my $use_hard_links = ''; # hardlinks do not work across fs boundaries +my $postinst_hook = ''; #Normally we do not +my $postrm_hook = ''; #Normally we do not +my $preinst_hook = ''; #Normally we do not +my $prerm_hook = ''; #Normally we do not +my $minimal_swap = ''; # Do not swap symlinks +my $ignore_depmod_err = ''; # normally we do not +my $kernel_arch = "=B"; +my $ramdisk = "/usr/sbin/update-initramfs"; # List of tools to create initial ram fs. +my $notifier = "/usr/share/update-notifier/notify-reboot-required"; +my $package_name = "linux-image-$version"; +my $explicit_do_loader = 'Yes'; + +my $Loader = "NoLOADER"; # +$Loader = "LILO" if $loader =~ /^lilo/io; +$Loader = "SILO" if $loader =~ /^silo/io; +$Loader = "QUIK" if $loader =~ /^quik/io; +$Loader = "yaboot" if $loader =~ /^yaboot/io; +$Loader = "PALO" if $loader =~ /^palo/io; +$Loader = "NETTROM" if $loader =~ /^nettrom/io; +$Loader = "VMELILO" if $loader =~ /^vmelilo/io; +$Loader = "ZIPL" if $loader =~ /^zipl/io; +$Loader = "ELILO" if $loader =~ /^elilo/io; +$Loader = "ARCBOOT" if $loader =~ /^arcboot/io; +$Loader = "DELO" if $loader =~ /^delo/io; + +# This should not point to /tmp, because of security risks. +my $temp_file_name = "/var/log/$loader" . "_log.$$"; + +#known variables +my $image_dest = "/"; +my $realimageloc = "/$image_dir/"; +my $have_conffile = ""; +my $silent_modules = ''; +my $silent_loader = ''; +my $warn_reboot = 'Yes'; # Warn that we are installing a version of + # the kernel we are running + +my $modules_base = '/lib/modules'; +my $CONF_LOC = '/etc/kernel-img.conf'; + +# Ignore all invocations except when called on to configure. +exit 0 unless $ARGV[0] =~ /configure/; + +my $DEBUG = 0; + +# Do some preliminary sanity checks here to ensure we actually have an +# valid image dir +chdir('/') or die "could not chdir to /:$!\n"; +die "Internal Error: ($image_dir) is not a directory!\n" + unless -d $image_dir; + +# remove multiple leading slashes; make sure there is at least one. +$realimageloc =~ s|^/*|/|o; +$realimageloc =~ s|/+|/|o; +die "Internal Error: ($realimageloc) is not a directory!\n" + unless -d $realimageloc; + +if (-r "$CONF_LOC" && -f "$CONF_LOC" ) { + if (open(CONF, "$CONF_LOC")) { + while () { + chomp; + s/\#.*$//g; + next if /^\s*$/; + + $do_symlink = "" if /^\s*do_symlinks\s*=\s*(no|false|0)\s*$/ig; + $no_symlink = "" if /^\s*no_symlinks\s*=\s*(no|false|0)\s*$/ig; + $reverse_symlink = "" if /^\s*reverse_symlink\s*=\s*(no|false|0)\s*$/ig; + $link_in_boot = "" if /^\s*image_in_boot\s*=\s*(no|false|0)\s*$/ig; + $link_in_boot = "" if /^\s*link_in_boot\s*=\s*(no|false|0)\s*$/ig; + $move_image = "" if /^\s*move_image\s*=\s*(no|false|0)\s*$/ig; + $clobber_modules = '' if /^\s*clobber_modules\s*=\s*(no|false|0)\s*$/ig; + $do_boot_enable = '' if /^\s*do_boot_enable\s*=\s*(no|false|0)\s*$/ig; + $do_bootfloppy = '' if /^\s*do_bootfloppy\s*=\s*(no|false|0)\s*$/ig; + $relative_links = '' if /^\s*relative_links \s*=\s*(no|false|0)\s*$/ig; + $do_bootloader = '' if /^\s*do_bootloader\s*=\s*(no|false|0)\s*$/ig; + $explicit_do_loader = '' if /^\s*do_bootloader\s*=\s*(no|false|0)\s*$/ig; + $do_initrd = '' if /^\s*do_initrd\s*=\s*(no|false|0)\s*$/ig; + $use_hard_links = '' if /^\s*use_hard_links\s*=\s*(no|false|0)\s*$/ig; + $silent_modules = '' if /^\s*silent_modules\s*=\s*(no|false|0)\s*$/ig; + $silent_loader = '' if /^\s*silent_loader\s*=\s*(no|false|0)\s*$/ig; + $warn_reboot = '' if /^\s*warn_reboot\s*=\s*(no|false|0)\s*$/ig; + $minimal_swap = '' if /^\s*minimal_swap\s*=\s*(no|false|0)\s*$/ig; + $ignore_depmod_err = '' if /^\s*ignore_depmod_err\s*=\s*(no|false|0)\s*$/ig; + + $do_symlink = "Yes" if /^\s*do_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $no_symlink = "Yes" if /^\s*no_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $reverse_symlink = "Yes" if /^\s*reverse_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $link_in_boot = "Yes" if /^\s*image_in_boot\s*=\s*(yes|true|1)\s*$/ig; + $link_in_boot = "Yes" if /^\s*link_in_boot\s*=\s*(yes|true|1)\s*$/ig; + $move_image = "Yes" if /^\s*move_image\s*=\s*(yes|true|1)\s*$/ig; + $clobber_modules = "Yes" if /^\s*clobber_modules\s*=\s*(yes|true|1)\s*$/ig; + $do_boot_enable = "Yes" if /^\s*do_boot_enable\s*=\s*(yes|true|1)\s*$/ig; + $do_bootfloppy = "Yes" if /^\s*do_bootfloppy\s*=\s*(yes|true|1)\s*$/ig; + $do_bootloader = "Yes" if /^\s*do_bootloader\s*=\s*(yes|true|1)\s*$/ig; + $explicit_do_loader = "YES" if /^\s*do_bootloader\s*=\s*(yes|true|1)\s*$/ig; + $relative_links = "Yes" if /^\s*relative_links\s*=\s*(yes|true|1)\s*$/ig; + $do_initrd = "Yes" if /^\s*do_initrd\s*=\s*(yes|true|1)\s*$/ig; + $use_hard_links = "Yes" if /^\s*use_hard_links\s*=\s*(yes|true|1)\s*$/ig; + $silent_modules = 'Yes' if /^\s*silent_modules\s*=\s*(yes|true|1)\s*$/ig; + $silent_loader = 'Yes' if /^\s*silent_loader\s*=\s*(yes|true|1)\s*$/ig; + $warn_reboot = 'Yes' if /^\s*warn_reboot\s*=\s*(yes|true|1)\s*$/ig; + $minimal_swap = 'Yes' if /^\s*minimal_swap\s*=\s*(yes|true|1)\s*$/ig; + $ignore_depmod_err = 'Yes' if /^\s*ignore_depmod_err\s*=\s*(yes|true|1)\s*$/ig; + + $image_dest = "$1" if /^\s*image_dest\s*=\s*(\S+)/ig; + $postinst_hook = "$1" if /^\s*postinst_hook\s*=\s*(\S+)/ig; + $postrm_hook = "$1" if /^\s*postrm_hook\s*=\s*(\S+)/ig; + $preinst_hook = "$1" if /^\s*preinst_hook\s*=\s*(\S+)/ig; + $prerm_hook = "$1" if /^\s*prerm_hook\s*=\s*(\S+)/ig; + $ramdisk = "$1" if /^\s*ramdisk\s*=\s*(.+)$/ig; + } + close CONF; + $have_conffile = "Yes"; + } +} + + + +# For some versions of kernel-package, we had this warning in the +# postinst, but the rules did not really interpolate the value in. +# Here is a sanity check. +my $pattern = "=" . "I"; +$initrd=~ s/^$pattern$//; + +if ($link_in_boot) { + $image_dest = "/$image_dir/"; # same as realimageloc +} + +# Tack on at least one trainling / +$image_dest = "$image_dest/"; +$image_dest =~ s|^/*|/|o; +$image_dest =~ s|/+$|/|o; + +if (! -d "$image_dest") { + die "Expected Image Destination dir ($image_dest) to be a valid directory!\n"; +} + +# sanity +if (!($do_bootfloppy || $do_bootloader)) { + $do_boot_enable = ''; +} +if ($do_symlink && $no_symlink) { + warn "Both do_symlinks and no_symlinks options enabled; disabling no_symlinks\n"; + $no_symlink = 0; +} + +# most of our work is done in $image_dest (nominally /) +chdir("$image_dest") or die "could not chdir to $image_dest:$!\n"; + +# Paranoid check to make sure that the correct value is put in there +if (! $kimage) { $kimage = "vmlinuz"; } # Hmm. empty +elsif ($kimage =~ m/^b?zImage$/o) { $kimage = "vmlinuz"; } # these produce vmlinuz +elsif ($kimage =~ m/^[iI]mage$/o) { my $nop = $kimage; } +elsif ($kimage =~ m/^vmlinux$/o) { my $nop = $kimage; } +else { $kimage = "vmlinuz"; } # Default + +$ENV{KERNEL_ARCH}=$kernel_arch if $kernel_arch; + + +die "Internal Error: Could not find image (" . $realimageloc + . "$kimage-$version)\n" unless -e $realimageloc + . "$kimage-$version"; + +# search for the boot loader in the path +my $loader_exec; +($loader_exec = $loader) =~ s|.*/||; +my ($loaderloc) = grep -x, map "$_/$loader_exec", + map { length($_) ? $_ : "." } split /:/, $ENV{PATH}; + + +###################################################################### +###################################################################### +########### Test whether a relative symlinkwould be OK ####### +###################################################################### +###################################################################### +sub test_relative { + my %params = @_; + my $cwd; + + die "Internal Error: Missing Required paramater 'Old Dir' " + unless $params{'Old Dir'}; + die "Internal Error: Missing Required paramater New Dir' " + unless $params{'New Dir'}; + + + die "Internal Error: No such dir $params{'Old Dir'} " + unless -d $params{'Old Dir'}; + die "Internal Error: No such dir $params{'New Dir'} " + unless -d $params{'New Dir'}; + + warn "Test relative: testing $params{'Old Dir'} -> $params{'New Dir'}" + if $DEBUG; + chomp($cwd = `pwd`); + chdir ($params{'New Dir'}) or die "Could not chdir to $params{'New Dir'}:$!"; + my $ok = 0; + $params{'Old Dir'} =~ s|^/*||o; + if (-d $params{'Old Dir'} ) { + if (defined $params{'Test File'}) { + if (-e $params{'Old Dir'} . $params{'Test File'}) { + $ok = 1; + } + } else { + $ok = 1; # well, backward compatibility + } + } + chdir ($cwd) or die "Could not chdir to $params{'New Dir'}:$!"; + return $ok; +} + +###################################################################### +###################################################################### +############ +###################################################################### +###################################################################### +# sub CanonicalizePath { +# my $path = join '/', @_; +# my @work = split '/', $path; +# my @out; +# my $is_absolute; + +# if (@work && $work[0] eq "") { +# $is_absolute = 1; shift @work; +# } + +# while (@work) { +# my $seg = shift @work; +# if ($seg eq "." || $seg eq "") { +# } +# elsif ($seg eq "..") { +# if (@out && $out[-1] ne "..") { +# pop @out; +# } +# else { +# # Leading "..", or "../..", etc. +# push @out, $seg; +# } +# } +# else { +# push @out, $seg; +# } +# } + +# unshift @out, "" if $is_absolute; +# return join('/', @out); +# } +###################################################################### +###################################################################### +############ +###################################################################### +###################################################################### + +sub spath { + my %params = @_; + + die "Missing Required paramater 'Old'" unless $params{'Old'}; + die "Missing Required paramater 'New'" unless $params{'New'}; + + my @olddir = split '/', `readlink -q -m $params{'Old'}`; + my @newdir = split '/', `readlink -q -m $params{'New'}`; + my @outdir = @olddir; + + my $out = ''; + my $i; + for ($i = 0; $i <= $#olddir && $i <= $#newdir; $i++) { + $out++ if ($olddir[$i] ne $newdir[$i]); + shift @outdir unless $out; + unshift @outdir, ".." if $out; + } + if ($#newdir > $#olddir) { + for ($i=0; $i < $#newdir; $i++) { + unshift @outdir, ".."; + } + } + return join ('/', @outdir); +} +###################################################################### +###################################################################### +############ +###################################################################### +###################################################################### + + +# This routine actually moves the kernel image +# From: $realimageloc/$kimage-$version (/boot/vmlinuz-2.6.12) +# To: $image_dest/$kimage-$version (/vmlinuz-2.6.12) +# Note that the image is moved to a versioned destination, but ordinary +# symlinks we create otherwise are not normally versioned +sub really_move_image { + my $src_dir = $_[0]; + my $target = $_[1]; + my $dest_dir = $_[2]; + + warn "Really move image: src_dir=$src_dir, target=$target,\n destdir=$dest_dir" + if $DEBUG; + if (-e "$target") { + # we should be in dir $dest_dir == $image_dest /, normally + rename("$target", "$target.$$") || + die "failed to move " . $dest_dir . "$target:$!"; + warn "mv $target $target.$$" if $DEBUG; + } + warn "mv -f $src_dir$target $target" if $DEBUG; + my $ret = system("mv -f " . $src_dir . "$target " . + " $target"); + if ($ret) { + die("Failed to move " . $src_dir . "$target to " + . $dest_dir . "$target.\n"); + } + # Ok, now we may clobber the previous .old files + if (-e "$target.$$") { + rename("$target.$$", "$target.old") || + die "failed to move " . $dest_dir . "$target:$!"; + warn "mv $target.$$ $target " if $DEBUG; + } +} + +# Normally called after really_move_image; and only called if we asked for +# reversed link this routine reverses the symbolic link that is notmally +# created. Since the real kernel image has been moved over to +# $image_dest/$kimage-$version. So, this routine links +# From: $image_dest/$kimage-$version (/vmlinuz-2.6.12) +# To: $realimageloc/$kimage-$version (/boot/vmlinuz-2.6.12) +sub really_reverse_link { + my $src_dir = $_[0]; + my $link_name = $_[1]; + my $dest_dir = $_[2]; + warn "Really reverse link: src_dir=$src_dir, link name=$link_name\n" . + "\tdestdir=$dest_dir" if $DEBUG; + + my $Old = $dest_dir; + if (test_relative ('Old Dir' => $Old, 'New Dir' => $src_dir, + 'Test File' => "$link_name")) { + $Old =~ s|^/*||o; + } + # Special case is they are in the same dir + my $rel_path = spath('Old' => "$Old", 'New' => "$src_dir" ); + $Old ="" if $rel_path =~ m/^\s*$/o; + + if ($use_hard_links =~ m/YES/i) { + link($Old . "$link_name", $src_dir . "$link_name") || + die("Failed to symbolic-link " . $dest_dir . "$link_name to " . $src_dir + . "$link_name .\n"); + warn "ln " . $Old . "$link_name " . $src_dir . "$link_name" if $DEBUG; + } + else { + symlink($Old . "$link_name", $src_dir . "$link_name") || + die("Failed to link " . $dest_dir . "$link_name to " . $src_dir . + "$link_name .\n"); + warn "ln -s " . $Old . "$link_name " . $src_dir . "$link_name" if $DEBUG; + } +} + +# This routine is invoked if there is a symbolic link in place +# in $image_dest/$kimage -- so a symlink exists in the destination. +# What we are trying to determine is if we need to move the symbolic link over +# to the the .old location +sub move_p { + my $kimage = $_[0]; # Name of the symbolic link + my $image_dest = $_[1]; # The directory the links goes into + my $image_name = $_[2]; + my $src_dir = $_[3]; + my $force_move = 0; + warn "Move?: kimage=$kimage, image_dest=$image_dest, \n" . + "\timage_name=$image_name, src_dir=$src_dir" if $DEBUG; + + if ($no_symlink || $reverse_symlink) { + # we do not want links, yet we have a symbolic link here! + warn "found a symbolic link in " . $image_dest . "$kimage \n" . + "even though no_symlink is defined\n" if $no_symlink; + warn "found a symbolic link in " . $image_dest . "$kimage \n" . + "even though reverse_symlink is defined\n" if $reverse_symlink; + # make sure we change this state of affairs + $force_move = 1; + return $force_move; + } + + warn "DEBUG: OK. We found symlink, and we should have a symlink here.\n" + if $DEBUG; + my $vmlinuz_target = readlink "$kimage"; + my $real_target = ''; + my $target = `readlink -q -m "${realimageloc}${kimage-$version}"`; + $real_target = abs_path($vmlinuz_target) if defined($vmlinuz_target); + + if (!defined($vmlinuz_target) || ! -f "$real_target") { + # what, a dangling symlink? + warn "The link " . $image_dest . "$kimage is a dangling link" . + "to $real_target\n"; + $force_move = 1; + return $force_move; + } + + + warn "DEBUG: The link $kimage points to ($vmlinuz_target)\n" if $DEBUG; + warn "DEBUG: ($vmlinuz_target) is really ($real_target)\n" if $DEBUG; + my $cwd; + chomp ($cwd=`pwd`); + if ($vmlinuz_target !~ m|^/|o) { + $vmlinuz_target = $cwd . "/" . $vmlinuz_target; + $vmlinuz_target =~ s|/+|/|o; + } + $vmlinuz_target = `readlink -q -m $vmlinuz_target`; + + if ("$vmlinuz_target" ne "$target") { + warn "DEBUG: We need to handle this.\n" if $DEBUG; + if ($minimal_swap) { + warn "DEBUG: Minimal swap.\n" if $DEBUG; + if (-l "$kimage.old") { + warn "DEBUG: There is an old link at $kimage.old\n" if $DEBUG; + my $old_target = readlink "$kimage.old"; + my $real_old_target = ''; + $real_old_target=abs_path($old_target) if defined ($old_target); + + if ($real_old_target && -f "$real_old_target") { + if ($old_target !~ m|^/|o) { + $old_target = $cwd . "/" . $old_target; + $old_target =~ s|/+|/|o; + } + $old_target = `readlink -q -m $old_target`; + if ("$old_target" ne "$target") { + $force_move = 1; + warn "DEBUG: Old link ($old_target) does not point to us ($target)\n" + if $DEBUG; + } + else { # The .old points to the current + warn "$kimage.old --> $target -- doing nothing"; + $force_move = 0; + } + } + else { + warn "DEBUG: Well, the old link does not exist -- so we move\n" + if $DEBUG; + $force_move = 1; + } + } + else { + warn "DEBUG: No .old link -- OK to move\n" + if $DEBUG; + $force_move = 1; + } + } + else { + warn "DEBUG: ok, minimal swap is no-- so we move.\n" + if $DEBUG; + $force_move = 1; + } + } + else { # already have proper link + warn "$kimage($vmlinuz_target) points to $target ($real_target) -- doing nothing"; + $force_move = 0; + } + return $force_move; +} + + +# This routine moves the symbolic link around (/vmlinuz -> /vmlinuz.old) +# It pays attention to whether we should the fact whether we should be using +# hard links or not. +sub really_move_link { + my $kimage = $_[0]; # Name of the symbolic link + my $image_dest = $_[1]; # The directory the links goes into + my $image_name = $_[2]; + my $src_dir = $_[3]; + warn "really_move_link: kimage=$kimage, image_dest=$image_dest\n" . + "\t image_name=$image_name, src_dir=$src_dir" if $DEBUG; + + # don't clobber $kimage.old quite yet + rename("$kimage", "$kimage.$$") || + die "failed to move " . $image_dest . "$kimage:$!"; + warn "mv $kimage $kimage.$$" if $DEBUG; + my $Old = $src_dir; + my $cwd; + + chomp($cwd=`pwd`); + if (test_relative ('Old Dir' => $Old, 'New Dir' => $cwd, + 'Test File' => "$image_name")) { + $Old =~ s|^/*||o; + } + # Special case is they are in the same dir + my $rel_path = spath('Old' => "$Old", 'New' => "$cwd" ); + $Old ="" if $rel_path =~ m/^\s*$/o; + + if ($use_hard_links =~ m/YES/i) { + warn "ln ${Old}${image_name} $kimage" if $DEBUG; + if (! link("${Old}${image_name}", "$kimage")) { + rename("$kimage.$$", "$kimage"); + die("Failed to link ${Old}${image_name} to " . + "${image_dest}${kimage}.\n"); + } + } + else { + warn "ln -s ${Old}${image_name} $kimage" if $DEBUG; + if (! symlink("${Old}${image_name}", "$kimage")) { + rename("$kimage.$$", "$kimage"); + die("Failed to symbolic-link ${Old}${image_name} to " . + "${image_dest}${kimage}.\n"); + } + } + + # Ok, now we may clobber the previous .old file + if (-l "$kimage.old" || ! -e "$kimage.old" ) { + rename("$kimage.$$", "$kimage.old"); + warn "mv $kimage.$$ $kimage.old" if $DEBUG; + } + else { + warn "$kimage.old is not a symlink, not clobbering\n"; + warn "rm $kimage.$$"; + unlink "$kimage.$$" if $DEBUG; + } +} + +# This routine handles a request to do symlinks, but there is no +# symlink file already there. Either we are supposed to use copy, or we are +# installing on a pristine system, or the user does not want symbolic links at +# all. We use a configuration file to tell the last two cases apart, creating +# a config file if needed. +sub handle_missing_link { + my $kimage = $_[0]; # Name of the symbolic link + my $image_dest = $_[1]; # The directory the links goes into + my $image_name = $_[2]; + my $src_dir = $_[3]; + warn "handle_missing_link: kimage=$kimage, image_dest=$image_dest\n" . + "\t image_name=$image_name, src_dir=$src_dir" if $DEBUG; + + if ($no_symlink) { + warn "cp -a --backup=t $realimageloc$image_name $kimage" if $DEBUG; + my $ret = system("cp -a --backup=t " . $realimageloc . + "$image_name " . " $kimage"); + if ($ret) { + die("Failed to copy " . $realimageloc . "$image_name to " + . $image_dest . "$kimage .\n"); + } + } + elsif ($reverse_symlink) { + warn "mv -f $realimageloc$image_name $kimage" if $DEBUG; + my $ret = system("mv -f " . $realimageloc . "$image_name " + . "$kimage"); + if ($ret) { + die("Failed to move " . $realimageloc . "$image_name to " + . $image_dest . "$kimage .\n"); + } + } + else { + if (! $have_conffile) { + my $ret; + my $answer=''; + $do_symlink = "Yes"; + + if (open(CONF, ">$CONF_LOC")) { + print CONF "# Kernel Image management overrides\n"; + print CONF "# See kernel-img.conf(5) for details\n"; + if ($loader =~ /palo/i) { + print CONF "link_in_boot = Yes\n"; + print CONF "do_symlinks = Yes\n"; + print CONF "relative_links = Yes\n"; + print CONF "do_bootloader = No\n"; + } else { + print CONF "do_symlinks = $do_symlink\n"; + } + close CONF; + } + $have_conffile = "Yes"; + } + } + + if (! $no_symlink && $do_symlink =~ /Yes/i) { + my $Old = $realimageloc; + my $New = $image_dest; + my $Name = "$image_name"; + my $Link_Dest = "$kimage"; + + if ($reverse_symlink) { + $Old = $image_dest; + $New = $realimageloc; + $Name = "$kimage"; + $Link_Dest = $realimageloc . "$image_name"; + } + if (test_relative ('Old Dir' => $Old, + 'New Dir' => $New, + 'Test File' => $Name)) { + $Old =~ s|^/*||o; + } + # Special case is they are in the same dir + my $rel_path = spath('Old' => "$Old", 'New' => "$New" ); + $Old ="" if $rel_path =~ m/^\s*$/o; + + symlink($Old . "$Name", "$Link_Dest") || + die("Failed to symbolic-link ${Old}$Name to $Link_Dest.\n"); + warn "ln -s ${Old}$Name $Link_Dest" if $DEBUG; + + } +} + +# This routine handles the rest of the cases, where the user has requested +# non-traditional handling, like using cp, or reverse symlinks, or hard links. +sub handle_non_symlinks { + my $kimage = $_[0]; # Name of the symbolic link + my $image_dest = $_[1]; # The directory the links goes into + my $image_name = $_[2]; + my $src_dir = $_[3]; + warn "handle_non_link: kimage=$kimage, image_dest=$image_dest\n" . + "\t image_name=$image_name, src_dir=$src_dir" if $DEBUG; + + # Save the current image. We do this in all four cases + rename("$kimage", "$kimage.$$") || + die "failed to move " . $image_dest . "$kimage:$!"; + warn "mv $kimage $kimage.$$" if $DEBUG; + + ##,#### + # case One + #`#### + if ($no_symlink) { + # Maybe /$image_dest is on a dos system? + warn "cp -a --backup=t $realimageloc$image_name $kimage" if $DEBUG; + my $ret = system("cp -a --backup=t " . $realimageloc + . "$image_name " . "$kimage"); + if ($ret) { + if (-e "$kimage.$$") { + rename("$kimage.$$", "$kimage"); + warn "mv $kimage.$$ $kimage" if $DEBUG; + } + die("Failed to copy " . $realimageloc . "$image_name to " + . $image_dest . "$kimage .\n"); + } + } + ##,#### + # case Two + #`#### + elsif ($reverse_symlink) { # Maybe /$image_dest is on a dos system? + warn "mv -f $realimageloc$image_name $kimage" if $DEBUG; + my $ret = system("mv -f " . $realimageloc . "$image_name " + . $image_dest . "$kimage"); + if ($ret) { + if (-e "$kimage.$$") { + rename("$kimage.$$", "$kimage"); + warn "mv $kimage.$$ $kimage" if $DEBUG; + } + die("Failed to move " . $realimageloc . "$image_name to " + . $image_dest . "$kimage .\n"); + } + my $Old = $image_dest; + if (test_relative ('Old Dir' => $Old, 'New Dir' => $realimageloc, + 'Test File' => "$kimage")) { + $Old =~ s|^/*||o; + } + # Special case is they are in the same dir + my $rel_path = spath('Old' => "$Old", 'New' => "$realimageloc" ); + $Old ="" if $rel_path =~ m/^\s*$/o; + + if ($use_hard_links =~ m/YES/i) { + warn "ln " . $Old . "$kimage " . $realimageloc . "$image_name" if $DEBUG; + if (! link($Old . "$kimage", $realimageloc . "$image_name")) { + warn "Could not link " . $image_dest . + "$kimage to $image_name :$!"; + } + } + else { + warn "ln -s " . $Old . "$kimage " . $realimageloc . "$image_name" if $DEBUG; + if (! symlink($Old . "$kimage", $realimageloc . "$image_name")) { + warn "Could not symlink " . $image_dest . + "$kimage to $image_name :$!"; + } + } + } + ##,#### + # case Three + #`#### + elsif ($use_hard_links =~ m/YES/i ) { + # Ok then. this ought to be a hard link, and hence fair game + # don't clobber $kimage.old quite yet + my $Old = $realimageloc; + my $cwd; + chomp($cwd=`pwd`); + if (test_relative ('Old Dir' => $Old, 'New Dir' => $cwd, + 'Test File' => "$image_name")) { + $Old =~ s|^/*||o; + } + # Special case is they are in the same dir + my $rel_path = spath('Old' => "$Old", 'New' => "$cwd" ); + $Old ="" if $rel_path =~ m/^\s*$/o; + + warn "ln " . $Old . "$image_name " . "$kimage" if $DEBUG; + if (! link($Old . "$image_name", "$kimage")) { + warn "mv $kimage.$$ $kimage" if $DEBUG; + rename("$kimage.$$", "$kimage"); + die("Failed to link " . $realimageloc . "$image_name to " + . $image_dest . "$kimage .\n"); + } + } + ##,#### + # case Four + #`#### + else { + # We just use cp + warn "cp -a --backup=t $realimageloc$image_name $kimage" if $DEBUG; + my $ret = system("cp -a --backup=t " . $realimageloc + . "$image_name " . "$kimage"); + if ($ret) { + if (-e "$kimage.$$") { + warn "mv $kimage.$$ $kimage" if $DEBUG; + rename("$kimage.$$", "$kimage"); + } + die("Failed to copy " . $realimageloc . "$image_name to " + . $image_dest . "$kimage .\n"); + } + } + # Ok, now we may clobber the previous .old file + warn "mv $kimage.$$ $kimage.old if -e $kimage.$$" if $DEBUG; + rename("$kimage.$$", "$kimage.old") if -e "$kimage.$$"; +} + +# This routine is responsible for setting up the symbolic links +# So, the actual kernel image lives in +# $realimageloc/$image_name (/boot/vmlinuz-2.6.12). +# This routine creates symbolic links in $image_dest/$kimage (/vmlinuz) +sub image_magic { + my $kimage = $_[0]; # Name of the symbolic link + my $image_dest = $_[1]; # The directory the links goes into + my $image_name = "$kimage-$version"; + my $src_dir = $realimageloc; + warn "image_magic: kimage=$kimage, image_dest=$image_dest\n" . + "\t image_name=$image_name, src_dir=$src_dir" if $DEBUG; + + # Well, in any case, if the destination (the symlink we are trying + # to create) is a directory, we should do nothing, except throw a + # diagnostic. + if (-d "$kimage" ) { + die ("Hmm. $kimage is a directory, which I did not expect. I am\n" . + "trying to create a symbolic link with that name linked to \n" . + "$image_dest . Since a directory exists here, my assumptions \n" . + "are way off, and I am aborting.\n" ); + exit (3); + } + + if ($move_image) { # Maybe $image_dest is in on dos, or something? + # source dir, link name, dest dir + really_move_image( $realimageloc, $image_name, $image_dest); + really_reverse_link($realimageloc, $image_name, $image_dest) + if $reverse_symlink; + return; + } + + if (-l "$kimage") { # There is a symbolic link + warn "DEBUG: There is a symlink for $kimage\n" if $DEBUG; + my $force_move = move_p($kimage, $image_dest, $image_name, $src_dir); + + if ($force_move) { + really_move_link($kimage, $image_dest, $image_name, $src_dir); + } + } + elsif (! -e "$kimage") { + # Hmm. Pristine system? How can that be? Installing from scratch? + # Or maybe the user does not want a symbolic link here. + # Possibly they do not want a link here. (we should be in / + # here[$image_dest, really] + handle_missing_link($kimage, $image_dest, $image_name, $src_dir); + } + elsif (-e "$kimage" ) { + # OK, $kimage exists -- but is not a link + handle_non_symlinks($kimage, $image_dest, $image_name, $src_dir); + } +} + +###################################################################### +###################################################################### +###################################################################### +###################################################################### + +# We may not have any modules installed +if ( -d "$modules_base/$version" ) { + print STDERR "Running depmod.\n"; + my $ret = system("depmod -a $version"); + if ($ret) { + print STDERR "Failed to run depmod\n"; + exit(1); + } +} + + + +sub find_initrd_tool { + my $hostversion = shift; + my $version = shift; + print STDERR "Finding valid ramdisk creators.\n"; + my @ramdisks = + grep { + my $args = + "$_ " . + "--supported-host-version=$hostversion " . + "--supported-target-version=$version " . + "1>/dev/null 2>&1" + ; + system($args) == 0; + } + split (/[:,\s]+/, $ramdisk); +} + +# The initrd symlink should probably be in the same dir that the +# symlinks are in +if ($initrd) { + my $success = 0; + + # Update-initramfs is called slightly different than mkinitrd and + # mkinitramfs. XXX It should really be made compatible with this stuff + # some how. + my $upgrading = 1; + if (! defined $ARGV[1] || ! $ARGV[1] || $ARGV[1] =~ m//og) { + $upgrading = 0; + } + my $ret = system("$ramdisk " . ($upgrading ? "-u" : "-c") . " -k " . $version . " >&2"); + $success = 1 unless $ret; + die "Failed to create initrd image.\n" unless $success; + if (! defined $ARGV[1] || ! $ARGV[1] || $ARGV[1] =~ m//og) { + image_magic("initrd.img", $image_dest); + } + else { + if (! -e "initrd.img") { + handle_missing_link("initrd.img", $image_dest, "initrd.img-$version", + $realimageloc); + } + else { + print STDERR + "Not updating initrd symbolic links since we are being updated/reinstalled \n"; + print STDERR + "($ARGV[1] was configured last, according to dpkg)\n"; + } + } + + if ($initrd && -l "initrd" ) { + unlink "initrd"; + } + + if ($initrd && -l "$image_dir/initrd" && ! $link_in_boot) { + unlink "$image_dir/initrd"; + } +} +else { # Not making an initrd emage + if (-l "initrd.img") { + # Ooh, last image was an initrd image? in any case, we should move it. + my $target = readlink "initrd.img"; + my $real_target = ''; + $real_target = abs_path($target) if defined ($target); + + if (!defined($target) || ! -f "$real_target") { + # Eh. dangling link. can safely be removed. + unlink("initrd.img"); + } else { + if (-l "initrd.img.old" || ! -e "initrd.img.old" ) { + rename("initrd.img", "initrd.img.old"); + } else { + warn "initrd.img.old is not a symlink, not clobbering\n"; + unlink("initrd.img"); + } + } + } +} + +# Warn of a reboot +if (-x $notifier) { + system($notifier); +} + +# Let programs know not to hibernate if the kernel that would be used for +# resume-from-hibernate is likely to differ from the currently running kernel. +system("mountpoint -q /var/run"); +if ($? eq 0) { + system("touch /var/run/do-not-hibernate"); +} + +# Only change the symlinks if we are not being upgraded +if (! defined $ARGV[1] || ! $ARGV[1] || $ARGV[1] =~ m//og) { + image_magic($kimage, $image_dest); +} +else { + if (! -e "$kimage") { + handle_missing_link($kimage, $image_dest, "$kimage-$version", + $realimageloc); + } + else { + print STDERR + "Not updating image symbolic links since we are being updated/reinstalled \n"; + print STDERR + "($ARGV[1] was configured last, according to dpkg)\n"; + } +} + +# We used to have System.* files in / +if (-e "/System.map" || -e "/System.old") { + unlink '/System.map' if -e '/System.map'; + unlink '/System.old' if -e '/System.old'; +} + +# creating some info about kernel and initrd +if ($DEBUG) { + my $ksize=sprintf("%.0f",(stat($realimageloc . + "$kimage-$version"))[7]/1024)."kB"; + my $initrdsize=''; + if ($initrd) { + $initrdsize=sprintf("%.0f",(stat($realimageloc . + "initrd.img-$version"))[7]/1024)."kB"; + } + + print STDERR <<"EOMSG"; +A new kernel image has been installed at $realimageloc$kimage-$version + (Size: $ksize) + +Symbolic links, unless otherwise specified, can be found in $image_dest + +EOMSG + ; + + if ($initrd) { + print STDERR <<"EOMSGA"; + + Initial rootdisk image: ${realimageloc}initrd.img-$version (Size: $initrdsize) +EOMSGA + ; + } +} + +# set the env var stem +$ENV{'STEM'} = "linux"; +sub exec_script { + my $type = shift; + my $script = shift; + print STDERR "Running $type hook script $script.\n"; + system ("$script $version $realimageloc$kimage-$version") && + print STDERR "User $type hook script [$script] "; + if ($?) { + if ($? == -1) { + print STDERR "failed to execute: $!\n"; + } + elsif ($? & 127) { + printf STDERR "died with signal %d, %s coredump\n", + ($? & 127), ($? & 128) ? 'with' : 'without'; + } + else { + printf STDERR "exited with value %d\n", $? >> 8; + } + exit $? >> 8; + } +} +sub run_hook { + my $type = shift; + my $script = shift; + if ($script =~ m,^/,) { + # Full path provided for the hook script + if (-x "$script") { + &exec_script($type,$script); + } + else { + die "The provided $type hook script [$script] could not be run.\n"; + } + } + else { + # Look for it in a safe path + for my $path ('/bin', '/sbin', '/usr/bin', '/usr/sbin') { + if (-x "$path/$script") { + &exec_script($type, "$path/$script"); + return 0; + } + } + # No luck + print STDERR "Could not find $type hook script [$script].\n"; + die "Looked in: '/bin', '/sbin', '/usr/bin', '/usr/sbin'\n"; + } +} + +## Run user hook script here, if any +if ($postinst_hook) { + &run_hook("postinst", $postinst_hook); +} + +if (-d "/etc/kernel/postinst.d") { + print STDERR "Examining /etc/kernel/postinst.d.\n"; + system ("run-parts --verbose --exit-on-error --arg=$version " . + "--arg=$realimageloc$kimage-$version " . + "/etc/kernel/postinst.d") && + die "Failed to process /etc/kernel/postinst.d"; +} + +if (-d "/etc/kernel/postinst.d/$version") { + print STDERR "Examining /etc/kernel/postinst.d/$version.\n"; + system ("run-parts --verbose --exit-on-error --arg=$version " . + "--arg=$realimageloc$kimage-$version " . + "/etc/kernel/postinst.d/$version") && + die "Failed to process /etc/kernel/postinst.d/$version"; +} + +LOADER: { + last unless $do_boot_enable; # Exit if explicitly asked to + + last if $loader =~ /silo/i; # SILO does not have to be executed. + last if $loader =~ /yaboot/i; # yaboot does not have to be executed. + last if $loader =~ /milo/i; # MILO does not have to be executed. + last if $loader =~ /nettrom/i; # NETTROM does not have to be executed. + last if $loader =~ /arcboot/i; # ARCBOOT does not have to be executed. + last if $loader =~ /delo/i; # DELO does not have to be executed. + last if $loader =~ /quik/i; # maintainer asked quik invocation to be ignored + + last unless $loaderloc; + last unless -x $loaderloc; + last unless $do_bootloader; + + if (-T "/etc/$loader.conf") { + # Trust and use the existing lilo.conf. + print STDERR "You already have a $Loader configuration in /etc/$loader.conf\n"; + my $ret = &run_lilo(); + exit $ret if $ret; + } +} + + +sub run_lilo (){ + my $ret; + # Try and figure out if the user really wants lilo to be run -- + # since the default is to run the boot laoder, which is ! grub -- but + # the user may be using grub now, and not changed the default. + + # So, if the user has explicitly asked for the loader to be run, or + # if there is no postinst hook, or if there is no grub installed -- + # we are OK. Or else, we ask. + if ($explicit_do_loader || (! ($postinst_hook && -x '/usr/sbin/grub'))) { + print STDERR "Running boot loader as requested\n"; + } else { + print STDERR "Ok, not running $loader\n"; + } + if ($loader =~ /^lilo/io or $loader =~ /vmelilo/io) { + print STDERR "Testing $loader.conf ... \n"; + unlink $temp_file_name; # security + $ret = system("$loaderloc -t >$temp_file_name 2>&1"); + if ($ret) { + print STDERR "Boot loader test failed\n"; + return $ret; + } + unlink "$temp_file_name"; + print STDERR "Testing successful.\n"; + print STDERR "Installing the "; + print STDERR "partition " if $loader =~ /^lilo/io; + print STDERR "boot sector... \n"; + } + + print STDERR "Running $loaderloc ... \n"; + if ($loader =~ /^elilo/io) { + $ret = system("$loaderloc 2>&1 | tee $temp_file_name"); + } else { + $ret = system("$loaderloc >$temp_file_name 2>&1"); + } + if ($ret) { + print STDERR "Boot loader failed to run\n"; + return $ret; + } + unlink $temp_file_name; + print STDERR "Installation successful.\n"; + return 0; +} + +exit 0; + +__END__ + --- linux-2.6.28.orig/debian/control-scripts/preinst +++ linux-2.6.28/debian/control-scripts/preinst @@ -0,0 +1,299 @@ +#! /usr/bin/perl +# -*- Mode: Cperl -*- +# image.preinst --- +# Author : Manoj Srivastava ( srivasta@tiamat.datasync.com ) +# Created On : Sun Jun 14 03:38:02 1998 +# Created On Node : tiamat.datasync.com +# Last Modified By : Manoj Srivastava +# Last Modified On : Sun Sep 24 14:04:42 2006 +# Last Machine Used: glaurung.internal.golden-gryphon.com +# Update Count : 99 +# Status : Unknown, Use with caution! +# HISTORY : +# Description : +# +# + +# +#use strict; #for debugging + +use Debconf::Client::ConfModule qw(:all); +version('2.0'); +my $capb=capb("backup"); + +$|=1; + +# Predefined values: +my $version = "=V"; +my $link_in_boot = ""; # Should be empty, mostly +my $no_symlink = ""; # Should be empty, mostly +my $reverse_symlink = ""; # Should be empty, mostly +my $do_symlink = "Yes"; # target machine defined +my $do_boot_enable = "Yes"; # target machine defined +my $do_bootfloppy = "Yes"; # target machine defined +my $do_bootloader = "Yes"; # target machine defined +my $move_image = ''; # target machine defined +my $kimage = "=K"; # Should be empty, mostly +my $loader = "=L"; # lilo, silo, quik, palo, vmelilo, nettrom + # or elilo +my $image_dir = "/boot"; # where the image is located +my $initrd = "YES"; # initrd kernel +my $use_hard_links = ''; # hardlinks do not wirk across fs boundaries +my $postinst_hook = ''; #Normally we do not +my $postrm_hook = ''; #Normally we do not +my $preinst_hook = ''; #Normally we do not +my $prerm_hook = ''; #Normally we do not +my $minimal_swap = ''; # Do not swap symlinks +my $ignore_depmod_err = ''; # normally we do not +my $relink_src_link = 'YES'; # There is no harm in checking the link +my $relink_build_link = 'YES'; # There is no harm in checking the link +my $force_build_link = ''; # There is no harm in checking the link +my $kernel_arch = "=B"; +my $ramdisk = "/usr/sbin/update-initramfs"; # List of tools to create initial ram fs. +my $package_name = "linux-image-$version"; + +my $Loader = "NoLOADER"; # +$Loader = "LILO" if $loader =~ /^lilo/io; +$Loader = "SILO" if $loader =~ /^silo/io; +$Loader = "QUIK" if $loader =~ /^quik/io; +$Loader = "yaboot" if $loader =~ /^yaboot/io; +$Loader = "PALO" if $loader =~ /^palo/io; +$Loader = "NETTROM" if $loader =~ /^nettrom/io; +$Loader = "VMELILO" if $loader =~ /^vmelilo/io; +$Loader = "ZIPL" if $loader =~ /^zipl/io; +$Loader = "ELILO" if $loader =~ /^elilo/io; + + +#known variables +my @boilerplate = (); +my @silotemplate = (); +my @quiktemplate = (); +my @palotemplate = (); +my @vmelilotemplate = (); +my $bootdevice = ''; +my $rootdevice = ''; +my $rootdisk = ''; +my $rootpartition = ''; +my $image_dest = "/"; +my $realimageloc = "/$image_dir/"; +my $have_conffile = ""; +my $CONF_LOC = '/etc/kernel-img.conf'; +my $relative_links = ''; +my $silent_loader = ''; +my $warn_reboot = ''; # Warn that we are installing a version of + # the kernel we are running + +my $modules_base = '/lib/modules'; + +die "Pre inst Internal error. Aborting." unless $version; + +exit 0 if $ARGV[0] =~ /abort-upgrade/; +exit 1 unless $ARGV[0] =~ /(install|upgrade)/; + +# remove multiple leading slashes; make sure there is at least one. +$realimageloc =~ s|^/*|/|o; +$realimageloc =~ s|/+|/|o; + +if (-r "$CONF_LOC" && -f "$CONF_LOC" ) { + if (open(CONF, "$CONF_LOC")) { + while () { + chomp; + s/\#.*$//g; + next if /^\s*$/; + + $do_symlink = "" if /^\s*do_symlinks\s*=\s*(no|false|0)\s*$/ig; + $no_symlink = "" if /^\s*no_symlinks\s*=\s*(no|false|0)\s*$/ig; + $reverse_symlink = "" if /^\s*reverse_symlinks\s*=\s*(no|false|0)\s*$/ig; + $link_in_boot = "" if /^\s*image_in_boot\s*=\s*(no|false|0)\s*$/ig; + $link_in_boot = "" if /^\s*link_in_boot\s*=\s*(no|false|0)\s*$/ig; + $move_image = "" if /^\s*move_image\s*=\s*(no|false|0)\s*$/ig; + $do_boot_enable = '' if /^\s*do_boot_enable\s*=\s*(no|false|0)\s*$/ig; + $do_bootfloppy = '' if /^\s*do_bootfloppy\s*=\s*(no|false|0)\s*$/ig; + $do_bootloader = '' if /^\s*do_bootloader\s*=\s*(no|false|0)\s*$/ig; + $relative_links = '' if /^\s*relative_links \s*=\s*(no|false|0)\s*$/ig; + $use_hard_links = '' if /^\s*use_hard_links\s*=\s*(no|false|0)\s*$/ig; + $silent_loader = '' if /^\s*silent_loader\s*=\s*(no|false|0)\s*$/ig; + $warn_reboot = '' if /^\s*warn_reboot\s*=\s*(no|false|0)\s*$/ig; + $minimal_swap = '' if /^\s*minimal_swap\s*=\s*(no|false|0)\s*$/ig; + $ignore_depmod_err = '' if /^\s*ignore_depmod_err\s*=\s*(no|false|0)\s*$/ig; + $relink_src_link = '' if /^\s*relink_src_link\s*=\s*(no|false|0)\s*$/ig; + $relink_build_link = '' if /^\s*relink_build_link\s*=\s*(no|false|0)\s*$/ig; + $force_build_link = '' if /^\s*force_build_link\s*=\s*(no|false|0)\s*$/ig; + + $do_symlink = "Yes" if /^\s*do_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $no_symlink = "Yes" if /^\s*no_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $reverse_symlink = "Yes" if /^\s*reverse_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $link_in_boot = "Yes" if /^\s*image_in_boot\s*=\s*(yes|true|1)\s*$/ig; + $link_in_boot = "Yes" if /^\s*link_in_boot\s*=\s*(yes|true|1)\s*$/ig; + $move_image = "Yes" if /^\s*move_image\s*=\s*(yes|true|1)\s*$/ig; + $do_boot_enable = "Yes" if /^\s*do_boot_enable\s*=\s*(yes|true|1)\s*$/ig; + $do_bootfloppy = "Yes" if /^\s*do_bootfloppy\s*=\s*(yes|true|1)\s*$/ig; + $do_bootloader = "Yes" if /^\s*do_bootloader\s*=\s*(yes|true|1)\s*$/ig; + $relative_links = "Yes" if /^\s*relative_links\s*=\s*(yes|true|1)\s*$/ig; + $use_hard_links = "Yes" if /^\s*use_hard_links\s*=\s*(yes|true|1)\s*$/ig; + $silent_loader = 'Yes' if /^\s*silent_loader\s*=\s*(yes|true|1)\s*$/ig; + $warn_reboot = 'Yes' if /^\s*warn_reboot\s*=\s*(yes|true|1)\s*$/ig; + $minimal_swap = 'Yes' if /^\s*minimal_swap\s*=\s*(yes|true|1)\s*$/ig; + $ignore_depmod_err = 'Yes' if /^\s*ignore_depmod_err\s*=\s*(yes|true|1)\s*$/ig; + $relink_src_link = 'Yes' if /^\s*relink_src_link\s*=\s*(yes|true|1)\s*$/ig; + $relink_build_link = 'Yes' if /^\s*relink_build_link\s*=\s*(yes|true|1)\s*$/ig; + $force_build_link = 'Yes' if /^\s*force_build_link\s*=\s*(yes|true|1)\s*$/ig; + + $image_dest = "$1" if /^\s*image_dest\s*=\s*(\S+)/ig; + $postinst_hook = "$1" if /^\s*postinst_hook\s*=\s*(\S+)/ig; + $postrm_hook = "$1" if /^\s*postrm_hook\s*=\s*(\S+)/ig; + $preinst_hook = "$1" if /^\s*preinst_hook\s*=\s*(\S+)/ig; + $prerm_hook = "$1" if /^\s*prerm_hook\s*=\s*(\S+)/ig; + $ramdisk = "$1" if /^\s*ramdisk\s*=\s*(.+)$/ig; + } + close CONF; + $have_conffile = "Yes"; + $have_conffile = "Yes"; # stop perl complaining + } +} + +$ENV{KERNEL_ARCH}=$kernel_arch if $kernel_arch; + +# About to upgrade this package from version $2 TO THIS VERSION. +# "prerm upgrade" has already been called for the old version of +# this package. + +sub find_initrd_tool { + my $hostversion = shift; + my $version = shift; + my @ramdisks = + grep { + my $args = + "$_ " . + "--supported-host-version=$hostversion " . + "--supported-target-version=$version " . + "1>/dev/null 2>&1" + ; + system($args) == 0; + } + split (/[:,\s]+/, $ramdisk); +} + +sub check { + my $version = shift; + my $lib_modules="$modules_base/$version"; + my $message = ''; + + if (-d "$lib_modules") { + opendir(DIR, $lib_modules) || die "can’t opendir $lib_modules: $!"; + my @children = readdir(DIR); + if ($#children > 1) { + my @dirs = grep { -d "$lib_modules/$_" } @children; + if ($#dirs > 1) { # we have subdirs + my $dir_message=''; + for my $dir (@dirs) { + if ($dir =~/kernel$/) { + $dir_message="An older install was detected.\n"; + } + else { + $dir_message="Module sub-directories were detected.\n" + unless $dir_message; + } + } + $message += $dir_message if $dir_message; + } + + my @links = grep { -l "$lib_modules/$_" } @children; + if ($#links > -1) { + my $links_message = ''; + for my $link (@links) { + next if ($link =~ /^build$/); + next if ($link =~ /^source$/); + $links_message = "Symbolic links were detected in $modules_base/$version.\n"; + } + $message += $links_message if $links_message; + } + my @files = grep { -f "$lib_modules/$_" } @children; + $message += "Additional files also exist in $modules_base/$version.\n" + if ($#files > -1); + } + } + else { $message .= "$lib_modules does not exist. ";} + return $message; +} + +if (-d "$modules_base/$version") { + my $errors=check($version); + warn "Info:\n$errors\n" if $errors; +} + +# set the env var stem +$ENV{'STEM'} = "linux"; + +sub exec_script { + my $type = shift; + my $script = shift; + print STDERR "Running $type hook script $script.\n"; + system ("$script $version $realimageloc$kimage-$version") && + print STDERR "User $type hook script [$script] "; + if ($?) { + if ($? == -1) { + print STDERR "failed to execute: $!\n"; + } + elsif ($? & 127) { + printf STDERR "died with signal %d, %s coredump\n", + ($? & 127), ($? & 128) ? 'with' : 'without'; + } + else { + printf STDERR "exited with value %d\n", $? >> 8; + } + exit $? >> 8; + } +} +sub run_hook { + my $type = shift; + my $script = shift; + if ($script =~ m,^/,) { + # Full path provided for the hook script + if (-x "$script") { + &exec_script($type,$script); + } + else { + die "The provided $type hook script [$script] could not be run.\n"; + } + } + else { + # Look for it in a safe path + for my $path ('/bin', '/sbin', '/usr/bin', '/usr/sbin') { + if (-x "$path/$script") { + &exec_script($type, "$path/$script"); + return 0; + } + } + # No luck + print STDERR "Could not find $type hook script [$script].\n"; + die "Looked in: '/bin', '/sbin', '/usr/bin', '/usr/sbin'\n"; + } +} + + +## Run user hook script here, if any +if (-x "$preinst_hook") { + &run_hook("preinst", $preinst_hook); +} +if (-d "/etc/kernel/preinst.d") { + print STDERR "Examining /etc/kernel/preinst.d/\n"; + system ("run-parts --verbose --exit-on-error --arg=$version" . + " --arg=$realimageloc$kimage-$version" . + " /etc/kernel/preinst.d") && + die "Failed to process /etc/kernel/preinst.d"; +} +if (-d "/etc/kernel/preinst.d/$version") { + print STDERR "Examining /etc/kernel/preinst.d/$version.\n"; + system ("run-parts --verbose --exit-on-error --arg=$version" . + " --arg=$realimageloc$kimage-$version" . + " /etc/kernel/preinst.d/$version") && + die "Failed to process /etc/kernel/preinst.d/$version"; +} +print STDERR "Done.\n"; + +exit 0; + +__END__ + + --- linux-2.6.28.orig/debian/control-scripts/headers-postinst +++ linux-2.6.28/debian/control-scripts/headers-postinst @@ -0,0 +1,126 @@ +#!/usr/bin/perl +# -*- Mode: Cperl -*- +# debian.postinst --- +# Author : Manoj Srivastava ( srivasta@pilgrim.umass.edu ) +# Created On : Sat Apr 27 05:42:43 1996 +# Created On Node : melkor.pilgrim.umass.edu +# Last Modified By : Manoj Srivastava +# Last Modified On : Sat Aug 5 13:20:22 2006 +# Last Machine Used: glaurung.internal.golden-gryphon.com +# Update Count : 45 +# Status : Unknown, Use with caution! +# HISTORY : +# Description : +# +# +# +# arch-tag: 1c716174-2f0a-476d-a626-a1322e62503a +# + + +$|=1; + +# Predefined values: +my $version = "=V"; +my $kimage = "=K"; +my $package_name = "linux-image-$version"; + + +# Ignore all invocations uxcept when called on to configure. +exit 0 unless ($ARGV[0] && $ARGV[0] =~ /configure/); + +#known variables +my $image_dest = "/"; +my $realimageloc = "/boot/"; +my $silent_modules = ''; +my $modules_base = '/lib/modules'; +my $CONF_LOC = '/etc/kernel-img.conf'; +# remove multiple leading slashes; make sure there is at least one. +$realimageloc =~ s|^/*|/|o; +$realimageloc =~ s|/+|/|o; + +chdir '/usr/src' or die "Could not chdir to /usr/src:$!"; + +if (-r "$CONF_LOC" && -f "$CONF_LOC" ) { + if (open(CONF, "$CONF_LOC")) { + while () { + chomp; + s/\#.*$//g; + next if /^\s*$/; + + $header_postinst_hook = "$1" if /^\s*header_postinst_hook\s*=\s*(\S+)/ig; + } + close CONF; + } +} + +sub exec_script { + my $type = shift; + my $script = shift; + print STDERR "Running $type hook script $script.\n"; + system ("$script $version $realimageloc$kimage-$version") && + print STDERR "User $type hook script [$script] "; + if ($?) { + if ($? == -1) { + print STDERR "failed to execute: $!\n"; + } + elsif ($? & 127) { + printf STDERR "died with signal %d, %s coredump\n", + ($? & 127), ($? & 128) ? 'with' : 'without'; + } + else { + printf STDERR "exited with value %d\n", $? >> 8; + } + exit $? >> 8; + } +} +sub run_hook { + my $type = shift; + my $script = shift; + if ($script =~ m,^/,) { + # Full path provided for the hook script + if (-x "$script") { + &exec_script($type,$script); + } + else { + die "The provided $type hook script [$script] could not be run.\n"; + } + } + else { + # Look for it in a safe path + for my $path ('/bin', '/sbin', '/usr/bin', '/usr/sbin') { + if (-x "$path/$script") { + &exec_script($type, "$path/$script"); + return 0; + } + } + # No luck + print STDERR "Could not find $type hook script [$script].\n"; + die "Looked in: '/bin', '/sbin', '/usr/bin', '/usr/sbin'\n"; + } +} + +## Run user hook script here, if any +if (-x "$header_postinst_hook") { + &run_hook("postinst", $header_postinst_hook); +} + +if (-d "/etc/kernel/header_postinst.d") { + print STDERR "Examining /etc/kernel/header_postinst.d.\n"; + system ("run-parts --verbose --exit-on-error --arg=$version " . + "--arg=$realimageloc$kimage-$version " . + "/etc/kernel/header_postinst.d") && + die "Failed to process /etc/kernel/header_postinst.d"; +} + +if (-d "/etc/kernel/header_postinst.d/$version") { + print STDERR "Examining /etc/kernel/header_postinst.d/$version.\n"; + system ("run-parts --verbose --exit-on-error --arg=$version " . + "--arg=$realimageloc$kimage-$version " . + "/etc/kernel/header_postinst.d/$version") && + die "Failed to process /etc/kernel/header_postinst.d/$version"; +} + +exit 0; + +__END__ --- linux-2.6.28.orig/debian/control-scripts/postrm +++ linux-2.6.28/debian/control-scripts/postrm @@ -0,0 +1,353 @@ +#! /usr/bin/perl +# -*- Mode: Cperl -*- +# image.postrm --- +# Author : Manoj Srivastava ( srivasta@glaurung.green-gryphon.com ) +# Created On : Sat May 15 11:05:13 1999 +# Created On Node : glaurung.green-gryphon.com +# Last Modified By : Manoj Srivastava +# Last Modified On : Wed Sep 13 11:26:19 2006 +# Last Machine Used: glaurung.internal.golden-gryphon.com +# Update Count : 57 +# Status : Unknown, Use with caution! +# HISTORY : +# Description : +# +# $Id: image.postrm,v 1.31 2003/10/07 16:24:20 srivasta Exp $ +# + + +# +#use strict; #for debugging +use Cwd 'abs_path'; + +$|=1; + +# Predefined values: +my $version = "=V"; +my $link_in_boot = ""; # Should be empty, mostly +my $no_symlink = ""; # Should be empty, mostly +my $reverse_symlink = ""; # Should be empty, mostly +my $do_symlink = "Yes"; # target machine defined +my $do_boot_enable = "Yes"; # target machine defined +my $do_bootfloppy = "Yes"; # target machine defined +my $do_bootloader = "Yes"; # target machine defined +my $move_image = ''; # target machine defined +my $kimage = "=K"; # Should be empty, mostly +my $loader = "=L"; # lilo, silo, quik, palo, vmelilo, or nettrom +my $image_dir = "/boot"; # where the image is located +my $clobber_modules = ''; # target machine defined +my $initrd = "YES"; # initrd kernel +my $do_initrd = ''; # Normally, we don't +my $warn_initrd = 'YES'; # Normally we do +my $use_hard_links = ''; # hardlinks do not work across fs boundaries +my $postinst_hook = ''; #Normally we do not +my $postrm_hook = ''; #Normally we do not +my $preinst_hook = ''; #Normally we do not +my $prerm_hook = ''; #Normally we do not +my $minimal_swap = ''; # Do not swap symlinks +my $ignore_depmod_err = ''; # normally we do not +my $relink_build_link = 'YES'; # There is no harm in checking the link +my $force_build_link = ''; # we shall not create a dangling link +my $kernel_arch = "=B"; +my $ramdisk = "/usr/sbin/update-initramfs"; +my $package_name = "linux-image-$version"; + +my $Loader = "NoLOADER"; # +$Loader = "LILO" if $loader =~ /^lilo/io; +$Loader = "SILO" if $loader =~ /^silo/io; +$Loader = "QUIK" if $loader =~ /^quik/io; +$Loader = "yaboot" if $loader =~ /^yaboot/io; +$Loader = "PALO" if $loader =~ /^palo/io; +$Loader = "NETTROM" if $loader =~ /^nettrom/io; +$Loader = "VMELILO" if $loader =~ /^vmelilo/io; +$Loader = "ZIPL" if $loader =~ /^zipl/io; +$Loader = "ELILO" if $loader =~ /^elilo/io; + + +# This should not point to /tmp, because of security risks. +my $temp_file_name = "/var/log/$loader" . "_log.$$"; + +#known variables +my @boilerplate = (); +my @silotemplate = (); +my @quiktemplate = (); +my @palotemplate = (); +my @vmelilotemplate = (); +my $bootdevice = ''; +my $rootdevice = ''; +my $rootdisk = ''; +my $rootpartition = ''; +my $image_dest = "/"; +my $realimageloc = "/$image_dir/"; +my $have_conffile = ""; +my $CONF_LOC = '/etc/kernel-img.conf'; +my $relative_links = ''; +my $silent_modules = ''; +my $silent_loader = ''; +my $warn_reboot = 'Yes'; # Warn that we are installing a version of + # the kernel we are running + +chdir('/') or die "could not chdir to /:$!\n"; +# remove multiple leading slashes; make sure there is at least one. +$realimageloc =~ s|^/*|/|o; +$realimageloc =~ s|/+|/|o; + + +if (-r "$CONF_LOC" && -f "$CONF_LOC" ) { + if (open(CONF, "$CONF_LOC")) { + while () { + chomp; + s/\#.*$//g; + next if /^\s*$/; + + $do_symlink = "" if /^\s*do_symlinks\s*=\s*(no|false|0)\s*$/ig; + $no_symlink = "" if /^\s*no_symlinks\s*=\s*(no|false|0)\s*$/ig; + $reverse_symlink = "" if /^\s*reverse_symlinks\s*=\s*(no|false|0)\s*$/ig; + $link_in_boot = "" if /^\s*image_in_boot\s*=\s*(no|false|0)\s*$/ig; + $link_in_boot = "" if /^\s*link_in_boot\s*=\s*(no|false|0)\s*$/ig; + $move_image = "" if /^\s*move_image\s*=\s*(no|false|0)\s*$/ig; + $clobber_modules = '' if /^\s*clobber_modules\s*=\s*(no|false|0)\s*$/ig; + $do_boot_enable = '' if /^\s*do_boot_enable\s*=\s*(no|false|0)\s*$/ig; + $do_bootfloppy = '' if /^\s*do_bootfloppy\s*=\s*(no|false|0)\s*$/ig; + $relative_links = '' if /^\s*relative_links \s*=\s*(no|false|0)\s*$/ig; + $do_bootloader = '' if /^\s*do_bootloader\s*=\s*(no|false|0)\s*$/ig; + $do_initrd = '' if /^\s*do_initrd\s*=\s*(no|false|0)\s*$/ig; + $warn_initrd = '' if /^\s*warn_initrd\s*=\s*(no|false|0)\s*$/ig; + $use_hard_links = '' if /^\s*use_hard_links\s*=\s*(no|false|0)\s*$/ig; + $silent_modules = '' if /^\s*silent_modules\s*=\s*(no|false|0)\s*$/ig; + $silent_loader = '' if /^\s*silent_loader\s*=\s*(no|false|0)\s*$/ig; + $warn_reboot = '' if /^\s*warn_reboot\s*=\s*(no|false|0)\s*$/ig; + $minimal_swap = '' if /^\s*minimal_swap\s*=\s*(no|false|0)\s*$/ig; + $ignore_depmod_err = '' if /^\s*ignore_depmod_err\s*=\s*(no|false|0)\s*$/ig; + $relink_build_link = '' if /^\s*relink_build_link\s*=\s*(no|false|0)\s*$/ig; + $force_build_link = '' if /^\s*force_build_link\s*=\s*(no|false|0)\s*$/ig; + + $do_symlink = "Yes" if /^\s*do_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $no_symlink = "Yes" if /^\s*no_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $reverse_symlink = "Yes" if /^\s*reverse_symlinks\s*=\s*(yes|true|1)\s*$/ig; + $link_in_boot = "Yes" if /^\s*image_in_boot\s*=\s*(yes|true|1)\s*$/ig; + $link_in_boot = "Yes" if /^\s*link_in_boot\s*=\s*(yes|true|1)\s*$/ig; + $move_image = "Yes" if /^\s*move_image\s*=\s*(yes|true|1)\s*$/ig; + $clobber_modules = "Yes" if /^\s*clobber_modules\s*=\s*(yes|true|1)\s*$/ig; + $do_boot_enable = "Yes" if /^\s*do_boot_enable\s*=\s*(yes|true|1)\s*$/ig; + $do_bootfloppy = "Yes" if /^\s*do_bootfloppy\s*=\s*(yes|true|1)\s*$/ig; + $do_bootloader = "Yes" if /^\s*do_bootloader\s*=\s*(yes|true|1)\s*$/ig; + $relative_links = "Yes" if /^\s*relative_links\s*=\s*(yes|true|1)\s*$/ig; + $do_initrd = "Yes" if /^\s*do_initrd\s*=\s*(yes|true|1)\s*$/ig; + $warn_initrd = "Yes" if /^\s*warn_initrd\s*=\s*(yes|true|1)\s*$/ig; + $use_hard_links = "Yes" if /^\s*use_hard_links\s*=\s*(yes|true|1)\s*$/ig; + $silent_modules = 'Yes' if /^\s*silent_modules\s*=\s*(yes|true|1)\s*$/ig; + $silent_loader = 'Yes' if /^\s*silent_loader\s*=\s*(yes|true|1)\s*$/ig; + $warn_reboot = 'Yes' if /^\s*warn_reboot\s*=\s*(yes|true|1)\s*$/ig; + $minimal_swap = 'Yes' if /^\s*minimal_swap\s*=\s*(yes|true|1)\s*$/ig; + $ignore_depmod_err = 'Yes' if /^\s*ignore_depmod_err\s*=\s*(yes|true|1)\s*$/ig; + $relink_build_link = 'Yes' if /^\s*relink_build_link\s*=\s*(yes|true|1)\s*$/ig; + $force_build_link = 'Yes' if /^\s*force_build_link\s*=\s*(yes|true|1)\s*$/ig; + + $image_dest = "$1" if /^\s*image_dest\s*=\s*(\S+)/ig; + $postinst_hook = "$1" if /^\s*postinst_hook\s*=\s*(\S+)/ig; + $postrm_hook = "$1" if /^\s*postrm_hook\s*=\s*(\S+)/ig; + $preinst_hook = "$1" if /^\s*preinst_hook\s*=\s*(\S+)/ig; + $prerm_hook = "$1" if /^\s*prerm_hook\s*=\s*(\S+)/ig; + $ramdisk = "$1" if /^\s*ramdisk\s*=\s*(.+)$/ig; + } + close CONF; + $have_conffile = "Yes"; + } +} + +if ($link_in_boot) { + $image_dest = "/$image_dir/"; + $image_dest =~ s|^/*|/|o; +} + +$image_dest = "$image_dest/"; +$image_dest =~ s|/+$|/|o; + +# The destdir may be gone by now. +if (-d "$image_dest") { + chdir("$image_dest") or die "could not chdir to $image_dest:$!\n"; +} + +# Paranoid check to make sure that the correct value is put in there +if (! $kimage) {$kimage = "vmlinuz"} # Hmm. empty +elsif ($kimage =~ m/^b?zImage$/o) {$kimage = "vmlinuz"} # these produce vmlinuz +elsif ($kimage =~ m/^[iI]mage$/o) { my $nop = $kimage;} +elsif ($kimage =~ m/^vmlinux$/o) { my $nop = $kimage;} +else {$kimage = "vmlinuz"} # default + +$ENV{KERNEL_ARCH}=$kernel_arch if $kernel_arch; + + +###################################################################### +###################################################################### +############ +###################################################################### +###################################################################### +sub remove_sym_link { + my $bad_image = $_[0]; + + warn "Removing symbolic link $bad_image \n"; + if ($loader =~ /lilo/i) + { + warn "Unless you used the optional flag in lilo, \n"; + } + warn " you may need to re-run your boot loader" . ($loader ? "[$loader]":"") + . "\n"; + # Remove the dangling link + unlink "$bad_image"; +} + +###################################################################### +###################################################################### +############ +###################################################################### +###################################################################### +sub CanonicalizePath { + my $path = join '/', @_; + my @work = split '/', $path; + my @out; + my $is_absolute; + + if (@work && $work[0] eq "") { $is_absolute = 1; shift @work; } + + while (@work) { + my $seg = shift @work; + if ($seg eq "." || $seg eq "") { + } elsif ($seg eq "..") { + if (@out && $out[-1] ne "..") { + pop @out; + } else { + # Leading "..", or "../..", etc. + push @out, $seg; + } + } else { + push @out, $seg; + } + } + + unshift @out, "" if $is_absolute; + return join('/', @out); +} + +###################################################################### +###################################################################### +############ +###################################################################### +###################################################################### +# This removes dangling symlinks. What do we do about hard links? Surely a +# something with the nane $image_dest . "$kimage" ought not to be left behind? +sub image_magic { + my $kimage = $_[0]; + my $image_dest = $_[1]; + + if (-l "$kimage") { + # There is a symbolic link + my $force_move = 0; + my $vmlinuz_target = readlink "$kimage"; + my $real_target = ''; + $real_target = abs_path($vmlinuz_target) if defined ($vmlinuz_target); + if (!defined($vmlinuz_target) || ! -f "$real_target") { + # what, a dangling symlink? + warn "The link " . $image_dest . "$kimage is a damaged link\n"; + # Remove the dangling link + &remove_sym_link("$kimage"); + } + else { + my $canonical_target = CanonicalizePath("$vmlinuz_target"); + if (! -e $canonical_target) { + warn "The link " . $image_dest . "$kimage is a dangling link\n"; + &remove_sym_link("$kimage"); + } + } + } +} + +# set the env var stem +$ENV{'STEM'} = "linux"; + +sub exec_script { + my $type = shift; + my $script = shift; + print STDERR "Running $type hook script $script.\n"; + system ("$script $version $realimageloc$kimage-$version") && + print STDERR "User $type hook script [$script] "; + if ($?) { + if ($? == -1) { + print STDERR "failed to execute: $!\n"; + } + elsif ($? & 127) { + printf STDERR "died with signal %d, %s coredump\n", + ($? & 127), ($? & 128) ? 'with' : 'without'; + } + else { + printf STDERR "exited with value %d\n", $? >> 8; + } + } +} +sub run_hook { + my $type = shift; + my $script = shift; + if ($script =~ m,^/,) { + # Full path provided for the hook script + if (-x "$script") { + &exec_script($type,$script); + } + else { + warn "The provided $type hook script [$script] could not be run.\n"; + } + } + else { + # Look for it in a safe path + for my $path ('/bin', '/sbin', '/usr/bin', '/usr/sbin') { + if (-x "$path/$script") { + &exec_script($type, "$path/$script"); + return 0; + } + } + # No luck + print STDERR "Could not find $type hook script [$script].\n"; + warn "Looked in: '/bin', '/sbin', '/usr/bin', '/usr/sbin'\n"; + } +} + +## Run user hook script here, if any +if ($postrm_hook) { + &run_hook("postrm", $postrm_hook); +} +if (-d "/etc/kernel/postrm.d") { + warn "Examining /etc/kernel/postrm.d .\n"; + system ("run-parts --verbose --exit-on-error --arg=$version " . + "--arg=$realimageloc$kimage-$version " . + "/etc/kernel/postrm.d") && + die "Failed to process /etc/kernel/postrm.d"; +} +if (-d "/etc/kernel/postrm.d/$version") { + warn "Examining /etc/kernel/postrm.d/$version .\n"; + system ("run-parts --verbose --exit-on-error --arg=$version " . + "--arg=$realimageloc$kimage-$version " . + "/etc/kernel/postrm.d/$version") && + die "Failed to process /etc/kernel/postrm.d/$version"; +} + +# check and remove damaged and dangling symlinks +if ($ARGV[0] !~ /upgrade/) { + system("$ramdisk -d -k " . $version . " > /dev/null 2>&1"); + if (-f $realimageloc . "initrd.img-$version.bak") { + unlink $realimageloc . "initrd.img-$version.bak"; + } + image_magic($kimage, $image_dest); + image_magic($kimage . ".old", $image_dest); + image_magic("initrd.img", $image_dest) if $initrd; + image_magic("initrd.img.old", $image_dest) if $initrd; +} + +exit 0; + +__END__ + + + + + + --- linux-2.6.28.orig/debian/d-i/kernel-versions.in +++ linux-2.6.28/debian/d-i/kernel-versions.in @@ -0,0 +1,11 @@ +# arch version flavour installedname suffix bdep +amd64 PKGVER-ABINUM generic PKGVER-ABINUM-generic - + +armel PKGVER-ABINUM iop32x PKGVER-ABINUM-iop32x y +armel PKGVER-ABINUM ixp4xx PKGVER-ABINUM-ixp4xx y +armel PKGVER-ABINUM versatile PKGVER-ABINUM-versatile y +armel PKGVER-ABINUM imx51 PKGVER-ABINUM-imx51 y + +i386 PKGVER-ABINUM generic PKGVER-ABINUM-generic - + +lpia PKGVER-ABINUM lpia PKGVER-ABINUM-lpia --- linux-2.6.28.orig/debian/d-i/exclude-modules.armel-ixp4xx +++ linux-2.6.28/debian/d-i/exclude-modules.armel-ixp4xx @@ -0,0 +1,2 @@ +nic-pcmcia-modules +fs-secondary-modules --- linux-2.6.28.orig/debian/d-i/package-list +++ linux-2.6.28/debian/d-i/package-list @@ -0,0 +1,169 @@ +Package: kernel-image +Provides_armel: crypto-modules, ext2-modules, ext3-modules, socket-modules, fat-modules +Provides_armel_versatile: crypto-modules, ext2-modules, ext3-modules, socket-modules, fb-modules + +Package: fat-modules +Depends: kernel-image +Priority: standard +Description: FAT filesystem support + This includes Windows FAT and VFAT support. + +Package: fb-modules +Depends: kernel-image +Priority: standard +Description: Framebuffer modules + +Package: firewire-core-modules +Depends: kernel-image, storage-core-modules +Priority: standard +Description: Firewire (IEEE-1394) Support + +Package: floppy-modules +Depends: kernel-image +Priority: standard +Description: Floppy driver support + +Package: fs-core-modules +Depends: kernel-image +Priority: standard +Provides: jfs-modules, reiserfs-modules, xfs-modules +Provides_armel: jfs-modules, reiserfs-modules, xfs-modules +Description: Base filesystem modules + This includes jfs, reiserfs and xfs. + +Package: fs-secondary-modules +Depends: kernel-image, fat-modules +Priority: standard +Provides: ntfs-modules, hfs-modules +Description: Extra filesystem modules + This includes support for Windows NTFS and MacOS HFS/HFSPlus + +Package: input-modules +Depends: kernel-image, usb-modules +Priority: standard +Description: Support for various input methods + +Package: irda-modules +Depends: kernel-image, nic-shared-modules +Priority: standard +Description: Support for Infrared protocols + +Package: md-modules +Depends: kernel-image +Priority: standard +Description: Multi-device support (raid, device-mapper, lvm) + +Package: nic-modules +Depends: kernel-image, nic-shared-modules, virtio-modules +Priority: standard +Description: Network interface support + +Package: nic-pcmcia-modules +Depends: kernel-image, nic-shared-modules, nic-modules +Priority: standard +Description: PCMCIA network interface support + +Package: nic-usb-modules +Depends: kernel-image, nic-shared-modules, usb-modules +Priority: standard +Description: USB network interface support + +Package: parport-modules +Depends: kernel-image +Priority: standard +Description: Parallel port support + +Package: pata-modules +Depends: kernel-image, storage-core-modules +Priority: standard +Description: PATA support modules + +Package: pcmcia-modules +Depends: kernel-image +Priority: standard +Description: PCMCIA Modules + +Package: pcmcia-storage-modules +Depends: kernel-image, scsi-modules +Priority: standard +Description: PCMCIA storage support + +Package: plip-modules +Depends: kernel-image, nic-shared-modules, parport-modules +Priority: standard +Description: PLIP (parallel port) networking support + +Package: ppp-modules +Depends: kernel-image, nic-shared-modules, serial-modules +Priority: standard +Description: PPP (serial port) networking support + +Package: sata-modules +Depends: kernel-image, storage-core-modules +Priority: standard +Description: SATA storage support + +Package: scsi-modules +Depends: kernel-image, storage-core-modules +Priority: standard +Description: SCSI storage support + +Package: serial-modules +Depends: kernel-image +Priority: standard +Description: Serial port support + +Package: storage-core-modules +Depends: kernel-image +Priority: standard +Provides: loop-modules +Description: Core storage support + Includes core SCSI, LibATA, USB-Storage. Also includes related block + devices for CD, Disk and Tape medium (and IDE Floppy). + +Package: usb-modules +Depends: kernel-image, storage-core-modules +Priority: standard +Description: Core USB support + +Package: nfs-modules +Priority: standard +Depends: kernel-image +Description: NFS filesystem drivers + Includes the NFS client driver, and supporting modules. + +Package: block-modules +Priority: standard +Depends: kernel-image, storage-core-modules, parport-modules, virtio-modules +Description: Block storage devices + This package contains the block storage devices, including DAC960 and + paraide. + +Package: message-modules +Priority: standard +Depends: kernel-image, storage-core-modules, scsi-modules +Description: Fusion and i2o storage modules + This package containes the fusion and i2o storage modules. + +Package: crypto-modules +Priority: extra +Depends: kernel-image +Description: crypto modules + This package contains crypto modules. + +Package: virtio-modules +Priority: standard +Depends: kernel-image +Description: VirtIO Modules + Includes modules for VirtIO (virtual machine, generally kvm guests) + +Package: socket-modules +Depends: kernel-image +Priority: standard +Description: Unix socket support + +Package: mouse-modules +Depends: kernel-image, input-modules, usb-modules +Priority: extra +Description: Mouse support + This package contains mouse drivers for the Linux kernel. --- linux-2.6.28.orig/debian/d-i/exclude-modules.armel-iop32x +++ linux-2.6.28/debian/d-i/exclude-modules.armel-iop32x @@ -0,0 +1,7 @@ +crypto-modules +fat-modules +fs-secondary-modules +storage-core-modules +nic-pcmcia-modules +nic-usb-modules +nfs-modules --- linux-2.6.28.orig/debian/d-i/kernel-versions +++ linux-2.6.28/debian/d-i/kernel-versions @@ -0,0 +1,11 @@ +# arch version flavour installedname suffix bdep +amd64 2.6.28-11 generic 2.6.28-11-generic - + +armel 2.6.28-11 iop32x 2.6.28-11-iop32x y +armel 2.6.28-11 ixp4xx 2.6.28-11-ixp4xx y +armel 2.6.28-11 versatile 2.6.28-11-versatile y +armel 2.6.28-11 imx51 2.6.28-11-imx51 y + +i386 2.6.28-11 generic 2.6.28-11-generic - + +lpia 2.6.28-11 lpia 2.6.28-11-lpia --- linux-2.6.28.orig/debian/d-i/exclude-modules.armel-imx51 +++ linux-2.6.28/debian/d-i/exclude-modules.armel-imx51 @@ -0,0 +1,26 @@ +acpi-modules +block-modules +ext2-modules +ext3-modules +fat-modules +fb-modules +firewire-core-modules +floppy-modules +input-modules +irda-modules +message-modules +mouse-modules +nic-modules +nic-pcmcia-modules +nic-shared-modules +parport-modules +pata-modules +pcmcia-modules +pcmcia-storage-modules +plip-modules +sata-modules +scsi-modules +serial-modules +socket-modules +usb-modules +virtio-modules --- linux-2.6.28.orig/debian/d-i/exclude-modules.armel-versatile +++ linux-2.6.28/debian/d-i/exclude-modules.armel-versatile @@ -0,0 +1,10 @@ +crypto-modules +fb-modules +fs-core-modules +fs-secondary-modules +nic-modules +nic-pcmcia-modules +nic-usb-modules +scsi-modules +storage-core-modules +nfs-modules --- linux-2.6.28.orig/debian/d-i/exclude-modules.armel +++ linux-2.6.28/debian/d-i/exclude-modules.armel @@ -0,0 +1,26 @@ +acpi-modules +block-modules +ext2-modules +ext3-modules +fb-modules +firewire-core-modules +floppy-modules +fs-secondary-modules +input-modules +irda-modules +md-modules +message-modules +mouse-modules +nic-pcmcia-modules +nic-shared-modules +parport-modules +pata-modules +pcmcia-modules +pcmcia-storage-modules +plip-modules +ppp-modules +sata-modules +serial-modules +socket-modules +usb-modules +virtio-modules --- linux-2.6.28.orig/debian/d-i/modules-armel/fs-core-modules +++ linux-2.6.28/debian/d-i/modules-armel/fs-core-modules @@ -0,0 +1,5 @@ +# ext2 and ext3 are built-in. + +jfs ? +reiserfs ? +xfs ? --- linux-2.6.28.orig/debian/d-i/modules/pcmcia-storage-modules +++ linux-2.6.28/debian/d-i/modules/pcmcia-storage-modules @@ -0,0 +1,6 @@ +pata_pcmcia +qlogic_cs +fdomain_cs +aha152x_cs ? +nsp_cs ? +sym53c500_cs --- linux-2.6.28.orig/debian/d-i/modules/floppy-modules +++ linux-2.6.28/debian/d-i/modules/floppy-modules @@ -0,0 +1 @@ +floppy --- linux-2.6.28.orig/debian/d-i/modules/nic-shared-modules +++ linux-2.6.28/debian/d-i/modules/nic-shared-modules @@ -0,0 +1,21 @@ +# PHY +8390 +mii + +# CRC modules +crc-ccitt +crc-itu-t + +# mac80211 stuff +mac80211 +cfg80211 + +# rt2x00 lib (since rt2x00 is split across usb/pci/cb +rt2x00lib + +# Wireless 802.11 modules +ieee80211 +ieee80211_crypt +ieee80211_crypt_ccmp +ieee80211_crypt_tkip +ieee80211_crypt_wep --- linux-2.6.28.orig/debian/d-i/modules/fat-modules +++ linux-2.6.28/debian/d-i/modules/fat-modules @@ -0,0 +1,7 @@ +fat +vfat + +# Supporting modules ? +nls_cp437 ? +nls_iso8859-1 ? +nls_utf8 ? --- linux-2.6.28.orig/debian/d-i/modules/crypto-modules +++ linux-2.6.28/debian/d-i/modules/crypto-modules @@ -0,0 +1,8 @@ +aes_generic +blowfish +twofish +serpent +sha256_generic +cbc +ecb +crc32c --- linux-2.6.28.orig/debian/d-i/modules/usb-modules +++ linux-2.6.28/debian/d-i/modules/usb-modules @@ -0,0 +1,9 @@ +ehci-hcd ? +isp116x-hcd +isp1760 +ohci-hcd ? +r8a66597-hcd +sl811_cs +sl811-hcd +u132-hcd +uhci-hcd ? --- linux-2.6.28.orig/debian/d-i/modules/nic-pcmcia-modules +++ linux-2.6.28/debian/d-i/modules/nic-pcmcia-modules @@ -0,0 +1,19 @@ +3c574_cs ? +3c589_cs ? +airo_cs ? +atmel_cs ? +axnet_cs ? +com20020_cs ? +fmvj18x_cs ? +ibmtr_cs ? +netwave_cs ? +nmclan_cs ? +orinoco_cs ? +pcnet_cs ? +ray_cs ? +smc91c92_cs ? +wavelan_cs ? +wl3501_cs ? +xirc2ps_cs ? +xircom_cb ? +xircom_tulip_cb ? --- linux-2.6.28.orig/debian/d-i/modules/virtio-modules +++ linux-2.6.28/debian/d-i/modules/virtio-modules @@ -0,0 +1,4 @@ +virtio_balloon +virtio_pci +virtio_ring ? +virtio-rng --- linux-2.6.28.orig/debian/d-i/modules/serial-modules +++ linux-2.6.28/debian/d-i/modules/serial-modules @@ -0,0 +1,3 @@ +generic_serial +serial_cs +synclink_cs --- linux-2.6.28.orig/debian/d-i/modules/pcmcia-modules +++ linux-2.6.28/debian/d-i/modules/pcmcia-modules @@ -0,0 +1,8 @@ +i82092 +i82365 ? +pcmcia +pcmcia_core +pd6729 +rsrc_nonstatic +tcic ? +yenta_socket --- linux-2.6.28.orig/debian/d-i/modules/fs-core-modules +++ linux-2.6.28/debian/d-i/modules/fs-core-modules @@ -0,0 +1,3 @@ +jfs +reiserfs +xfs --- linux-2.6.28.orig/debian/d-i/modules/nic-modules +++ linux-2.6.28/debian/d-i/modules/nic-modules @@ -0,0 +1,150 @@ +3c359 ? +3c501 ? +3c503 ? +3c505 ? +3c507 ? +3c509 ? +3c515 ? +3c523 ? +3c527 ? +3c59x ? +8139cp ? +8139too ? +82596 ? +abyss ? +ac3200 ? +adm8211 ? +airo ? +airport ? +amd8111e ? +arc4 ? +arcnet ? +arc-rawmode ? +arc-rimi ? +arlan ? +at1700 ? +atl1 ? +atl1e ? +atl2 ? +atmel ? +atmel_pci ? +b44 ? +bcm43xx ? +bcm43xx-mac80211 ? +bmac ? +bnx2 ? +bonding ? +cassini ? +com20020 ? +com20020-pci ? +com90io ? +com90xx ? +cs89x0 ? +de2104x ? +de4x5 ? +de600 ? +de620 ? +defxx ? +depca ? +dl2k ? +dmfe ? +dummy ? +e100 ? +e1000 ? +e1000e ? +e2100 ? +eepro ? +eepro100 ? +eexpress ? +epic100 ? +eql ? +es3210 ? +eth16i ? +ewrk3 ? +fealnx ? +forcedeth ? +igb ? +ps3_gelic ? +hamachi ? +hermes ? +hp ? +hp100 ? +hp-plus ? +ibmtr ? +ipddp ? +ipw2100 ? +ipw2200 ? +ipw3945 ? +ixgb ? +lance ? +lanstreamer ? +lasi_82596 ? +lne390 ? +lp486e ? +mace ? +mv643xx_eth ? +myri_sbus ? +natsemi ? +ne ? +ne2 ? +ne2k-pci ? +ne3210 ? +netconsole ? +ni5010 ? +ni52 ? +ni65 ? +niu ? +ns83820 ? +olympic ? +orinoco ? +orinoco_pci ? +orinoco_plx ? +orinoco_tmd ? +pcnet32 ? +prism54 ? +r8169 ? +rate_control ? +rfc1051 ? +rfc1201 ? +rrunner ? +rt2400 ? +rt2500 ? +rt61pci ? +s2io ? +shaper ? +sis190 ? +sis900 ? +spidernet ? +skfp ? +skge ? +sk98lin ? +sky2 ? +smc9194 ? +smc-ultra ? +smc-ultra32 ? +starfire ? +strip ? +sunbmac ? +sundance ? +sungem ? +sungem_phy ? +sunhme ? +sunlance ? +sunqe ? +sunvnet ? +tg3 ? +tlan ? +tms380tr ? +tmspci ? +tulip ? +tun ? +typhoon ? +uli526x ? +via-rhine ? +via-velocity ? +virtio_net ? +wavelan ? +wd ? +winbond-840 ? +yellowfin ? +znet ? --- linux-2.6.28.orig/debian/d-i/modules/scsi-modules +++ linux-2.6.28/debian/d-i/modules/scsi-modules @@ -0,0 +1,113 @@ +# SCSI +raid_class ? +scsi_transport_spi ? +scsi_transport_fc ? +scsi_transport_iscsi ? +scsi_transport_sas ? +iscsi_tcp ? +libiscsi ? +amiga7xx ? +a3000 ? +a2091 ? +gvp11 ? +mvme147 ? +sgiwd93 ? +cyberstorm ? +cyberstormII ? +blz2060 ? +blz1230 ? +fastlane ? +oktagon_esp_mod ? +atari_scsi ? +mac_scsi ? +mac_esp ? +sun3_scsi ? +mvme16x ? +bvme6000 ? +sim710 ? +advansys ? +psi240i ? +BusLogic ? +dpt_i2o ? +u14-34f ? +ultrastor ? +aha152x ? +aha1542 ? +aha1740 ? +aic7xxx_old ? +ips ? +fd_mcs ? +fdomain ? +in2000 ? +g_NCR5380 ? +g_NCR5380_mmio ? +NCR53c406a ? +NCR_D700 ? +NCR_Q720_mod ? +sym53c416 ? +qlogicfas408 ? +qla1280 ? +pas16 ? +seagate ? +seagate ? +t128 ? +dmx3191d ? +dtc ? +zalon7xx ? +eata_pio ? +wd7000 ? +mca_53c9x ? +ibmmca ? +eata ? +dc395x ? +tmscsim ? +megaraid ? +atp870u ? +esp ? +gdth ? +initio ? +a100u2w ? +qlogicpti ? +ide-scsi ? +mesh ? +mac53c94 ? +pluto ? +dec_esp ? +3w-xxxx ? +3w-9xxx ? +ppa ? +imm ? +jazz_esp ? +sun3x_esp ? +fcal ? +lasi700 ? +nsp32 ? +ipr ? +hptiop ? +stex ? +osst ? +sg ? +ch ? +scsi_debug ? +aacraid ? +aic7xxx ? +aic79xx ? +aic94xx ? +arcmsr ? +acornscsi_mod ? +arxescsi ? +cumana_1 ? +cumana_2 ? +ecoscsi ? +oak ? +powertec ? +eesox ? +ibmvscsic ? +libsas ? +lpfc ? +megaraid_mm ? +megaraid_mbox ? +megaraid_sas ? +qla2xxx ? +sym53c8xx ? +qla4xxx ? --- linux-2.6.28.orig/debian/d-i/modules/storage-core-modules +++ linux-2.6.28/debian/d-i/modules/storage-core-modules @@ -0,0 +1,10 @@ +# Core stacks +usb-storage ? + +# Block level + +# Loop modules +cryptoloop + +# Needs to be here for better cdrom initrd layout +isofs --- linux-2.6.28.orig/debian/d-i/modules/firewire-core-modules +++ linux-2.6.28/debian/d-i/modules/firewire-core-modules @@ -0,0 +1,4 @@ +ieee1394 +ohci1394 +sbp2 +eth1394 --- linux-2.6.28.orig/debian/d-i/modules/plip-modules +++ linux-2.6.28/debian/d-i/modules/plip-modules @@ -0,0 +1 @@ +plip --- linux-2.6.28.orig/debian/d-i/modules/message-modules +++ linux-2.6.28/debian/d-i/modules/message-modules @@ -0,0 +1,13 @@ +mptbase +mptctl +mptfc +mptlan +mptsas +mptscsih +mptspi +i2o_block +i2o_bus +i2o_config +i2o_core +i2o_proc +i2o_scsi --- linux-2.6.28.orig/debian/d-i/modules/nic-usb-modules +++ linux-2.6.28/debian/d-i/modules/nic-usb-modules @@ -0,0 +1,11 @@ +catc ? +kaweth ? +pegasus ? +prism2_usb ? +rtl8150 ? +usbnet ? +zd1211rw ? +zd1201 ? +rt2500usb ? +rt73usb ? +rt2570 ? --- linux-2.6.28.orig/debian/d-i/modules/fb-modules +++ linux-2.6.28/debian/d-i/modules/fb-modules @@ -0,0 +1,3 @@ +fbcon +vesafb +vga16fb --- linux-2.6.28.orig/debian/d-i/modules/parport-modules +++ linux-2.6.28/debian/d-i/modules/parport-modules @@ -0,0 +1,2 @@ +parport +parport_pc --- linux-2.6.28.orig/debian/d-i/modules/md-modules +++ linux-2.6.28/debian/d-i/modules/md-modules @@ -0,0 +1,14 @@ +dm-crypt +dm-zero +faulty +linear +multipath +raid0 +raid1 +raid10 +raid456 + +# Extras +dm-raid4-5 ? +dm-loop +dm-bbr --- linux-2.6.28.orig/debian/d-i/modules/ppp-modules +++ linux-2.6.28/debian/d-i/modules/ppp-modules @@ -0,0 +1,7 @@ +ppp_async +ppp_deflate +ppp_mppe +pppoe +pppox +ppp_synctty +syncppp ? --- linux-2.6.28.orig/debian/d-i/modules/pata-modules +++ linux-2.6.28/debian/d-i/modules/pata-modules @@ -0,0 +1,2 @@ +pata_it8213 +pata_ninja32 --- linux-2.6.28.orig/debian/d-i/modules/block-modules +++ linux-2.6.28/debian/d-i/modules/block-modules @@ -0,0 +1,30 @@ +aoe +aten +bpck +bpck6 ? +cciss +comm +cpqarray +DAC960 +dstr +epat +epia +fit2 +fit3 +friq +frpw +kbic +ktti +nbd +on20 +on26 +paride +pcd +pd +pf +pg +pt +sx8 +ub +umem +virtio_blk ? --- linux-2.6.28.orig/debian/d-i/modules/input-modules +++ linux-2.6.28/debian/d-i/modules/input-modules @@ -0,0 +1,22 @@ +hid-a4tech ? +hid-apple ? +hid-belkin ? +hid-bright ? +hid-cherry ? +hid-chicony ? +hid-cypress ? +hid-dell ? +hid-ezkey ? +hid-gyration ? +hid-logitech ? +hid-microsoft ? +hid-monterey ? +hid-petalynx ? +hid-pl ? +hid-samsung ? +hid-sony ? +hid-sunplus ? +hid-tmff ? +hid-zpff ? +usbhid +usbkbd --- linux-2.6.28.orig/debian/d-i/modules/nfs-modules +++ linux-2.6.28/debian/d-i/modules/nfs-modules @@ -0,0 +1,4 @@ +nfs +nfs_acl ? +lockd +sunrpc --- linux-2.6.28.orig/debian/d-i/modules/fs-secondary-modules +++ linux-2.6.28/debian/d-i/modules/fs-secondary-modules @@ -0,0 +1,4 @@ +fuse ? +ntfs ? +hfs ? +hfsplus ? --- linux-2.6.28.orig/debian/d-i/modules/irda-modules +++ linux-2.6.28/debian/d-i/modules/irda-modules @@ -0,0 +1,30 @@ +act200l-sir +actisys-sir +ali-ircc +donauboe ? +esi-sir +girbil-sir +ircomm +ircomm-tty +irda +irda-usb +irlan +irnet +irport ? +irtty-sir +kingsun-sir +ks959-sir +ksdazzle-sir +litelink-sir +ma600-sir +mcp2120-sir +mcs7780 +nsc-ircc +old_belkin-sir +sir-dev +smsc-ircc2 +stir4200 +tekram-sir +via-ircc +vlsi_ir +w83977af_ir --- linux-2.6.28.orig/debian/d-i/modules/sata-modules +++ linux-2.6.28/debian/d-i/modules/sata-modules @@ -0,0 +1,2 @@ + +sata_mv --- linux-2.6.28.orig/debian/d-i/modules/mouse-modules +++ linux-2.6.28/debian/d-i/modules/mouse-modules @@ -0,0 +1,2 @@ +psmouse +usbmouse ? --- linux-2.6.28.orig/debian/rules.d/5-udebs.mk +++ linux-2.6.28/debian/rules.d/5-udebs.mk @@ -0,0 +1,33 @@ +# Do udebs if not disabled in the arch-specific makefile +binary-udebs: binary-debs debian/control +ifeq ($(disable_d_i),) + debian/rules do-binary-udebs; +endif + +do-binary-udebs: + dh_testdir + dh_testroot + + # unpack the kernels into a temporary directory + mkdir -p debian/d-i-${arch} + + imagelist=$$(cat kernel-versions | grep ^${arch} | awk '{print $$4}') && \ + for i in $$imagelist; do \ + dpkg -x $$(ls ../linux-image-$$i\_$(release)-$(revision)_${arch}.deb) \ + debian/d-i-${arch}; \ + /sbin/depmod -b debian/d-i-${arch} $$i; \ + done + + touch ignore-dups + export SOURCEDIR=debian/d-i-${arch} && \ + kernel-wedge install-files && \ + kernel-wedge check + + # Build just the udebs + dilist=$$(dh_listpackages -s | grep "\-di$$") && \ + [ -z "$dilist" ] || \ + for i in $$dilist; do \ + dh_fixperms -p$$i; \ + dh_gencontrol -p$$i; \ + dh_builddeb -p$$i; \ + done --- linux-2.6.28.orig/debian/rules.d/amd64.mk +++ linux-2.6.28/debian/rules.d/amd64.mk @@ -0,0 +1,12 @@ +build_arch = x86_64 +header_arch = $(build_arch) +asm_link = x86 +defconfig = defconfig +flavours = generic server +build_image = bzImage +kernel_file = arch/$(build_arch)/boot/bzImage +install_file = vmlinuz + +server_sub = virtual + +loader = grub --- linux-2.6.28.orig/debian/rules.d/armel.mk +++ linux-2.6.28/debian/rules.d/armel.mk @@ -0,0 +1,11 @@ +build_arch = arm +header_arch = arm +asm_link = arm +defconfig = defconfig +flavours = iop32x ixp4xx versatile imx51 +build_image = zImage +kernel_file = arch/$(build_arch)/boot/zImage +install_file = vmlinuz +no_dumpfile = true + +loader = grub --- linux-2.6.28.orig/debian/rules.d/3-binary-indep.mk +++ linux-2.6.28/debian/rules.d/3-binary-indep.mk @@ -0,0 +1,88 @@ +build-indep: + +docpkg = linux-doc-$(release) +docdir = $(CURDIR)/debian/$(docpkg)/usr/share/doc/$(docpkg) +install-doc: + dh_testdir + dh_testroot + dh_clean -k -p$(docpkg) + + install -d $(docdir) + + # First the html docs. We skip these for autobuilds + if [ -z "$(AUTOBUILD) nobuild" ]; then \ + install -d $(docdir)/linux-doc-tmp; \ + $(kmake) O=$(docdir)/linux-doc-tmp htmldocs; \ + mv $(docdir)/linux-doc-tmp/Documentation/DocBook \ + $(docdir)/html; \ + rm -rf $(docdir)/linux-doc-tmp; \ + fi + + # Copy the rest + cp -a Documentation/* $(docdir) + rm -rf $(docdir)/DocBook + +indep_hdrpkg = linux-headers-$(abi_release) +indep_hdrdir = $(CURDIR)/debian/$(indep_hdrpkg)/usr/src/$(indep_hdrpkg) +install-headers: + dh_testdir + dh_testroot + dh_clean -k -p$(indep_hdrpkg) + + install -d $(indep_hdrdir) + find . -path './debian/*' -prune -o -path './include/*' -prune \ + -o -path './scripts/*' -prune -o -type f \ + \( -name 'Makefile*' -o -name 'Kconfig*' -o -name 'Kbuild*' -o \ + -name '*.sh' -o -name '*.pl' -o -name '*.lds' \) \ + -print | cpio -pd --preserve-modification-time $(indep_hdrdir) + cp -a drivers/media/dvb/dvb-core/*.h $(indep_hdrdir)/drivers/media/dvb/dvb-core + cp -a drivers/media/video/*.h $(indep_hdrdir)/drivers/media/video + cp -a drivers/media/dvb/frontends/*.h $(indep_hdrdir)/drivers/media/dvb/frontends + cp -a scripts include $(indep_hdrdir) + (find arch -name include -type d -print | \ + xargs -n1 -i: find : -type f) | \ + cpio -pd --preserve-modification-time $(indep_hdrdir) + +srcpkg = linux-source-$(release) +srcdir = $(CURDIR)/debian/$(srcpkg)/usr/src/$(srcpkg) +install-source: + dh_testdir + dh_testroot + dh_clean -k -p$(srcpkg) + + install -d $(srcdir) + find . -path './debian/*' -prune -o \ + -path './.*' -prune -o -print | \ + cpio -pd --preserve-modification-time $(srcdir) + (cd $(srcdir)/..; tar cf - $(srcpkg)) | bzip2 -9c > \ + $(srcdir).tar.bz2 + rm -rf $(srcdir) + +install-indep: install-headers install-doc install-source + +# This is just to make it easy to call manually. Normally done in +# binary-indep target during builds. +binary-headers: install-headers + dh_testdir + dh_testroot + dh_installchangelogs -p$(indep_hdrpkg) + dh_installdocs -p$(indep_hdrpkg) + dh_compress -p$(indep_hdrpkg) + dh_fixperms -p$(indep_hdrpkg) + dh_installdeb -p$(indep_hdrpkg) + dh_gencontrol -p$(indep_hdrpkg) + dh_md5sums -p$(indep_hdrpkg) + dh_builddeb -p$(indep_hdrpkg) + +binary-indep: install-indep + dh_testdir + dh_testroot + + dh_installchangelogs -i + dh_installdocs -i + dh_compress -i + dh_fixperms -i + dh_installdeb -i + dh_gencontrol -i + dh_md5sums -i + dh_builddeb -i --- linux-2.6.28.orig/debian/rules.d/4-checks.mk +++ linux-2.6.28/debian/rules.d/4-checks.mk @@ -0,0 +1,26 @@ +# Check ABI for package against last release (if not same abinum) +abi-%: $(abidir)/% + @# Empty for make to be happy +$(abidir)/%: $(stampdir)/stamp-build-% + install -d $(abidir) + sed -e 's/^\(.\+\)[[:space:]]\+\(.\+\)[[:space:]]\(.\+\)$$/\3 \2 \1/' \ + $(builddir)/build-$*/Module.symvers | sort > $@ + +abi-check-%: $(abidir)/% + @perl -f debian/scripts/abi-check "$*" "$(prev_abinum)" "$(abinum)" \ + "$(prev_abidir)" "$(abidir)" "$(skipabi)" + +# Check the module list against the last release (always) +module-%: $(abidir)/%.modules + @# Empty for make to be happy +$(abidir)/%.modules: $(stampdir)/stamp-build-% + install -d $(abidir) + find $(builddir)/build-$*/ -name \*.ko | \ + sed -e 's/.*\/\([^\/]*\)\.ko/\1/' | sort > $@ + +module-check-%: $(abidir)/%.modules + @perl -f debian/scripts/module-check "$*" \ + "$(prev_abidir)" "$(abidir)" $(skipmodule) + +checks-%: abi-check-% module-check-% + @# Will be calling more stuff later --- linux-2.6.28.orig/debian/rules.d/lpia.mk +++ linux-2.6.28/debian/rules.d/lpia.mk @@ -0,0 +1,10 @@ +build_arch = i386 +header_arch = i386 +asm_link = x86 +defconfig = defconfig +flavours = lpia +build_image = bzImage +kernel_file = arch/$(build_arch)/boot/bzImage +install_file = vmlinuz +do_debug_image = true +loader = grub --- linux-2.6.28.orig/debian/rules.d/0-common-vars.mk +++ linux-2.6.28/debian/rules.d/0-common-vars.mk @@ -0,0 +1,104 @@ +# Get some version info +stub=linux + +release := $(shell sed -n '1s/^.*(\(.*\)-.*).*$$/\1/p' debian/changelog) +revisions := $(shell sed -n 's/^$(stub)\ .*($(release)-\(.*\)).*$$/\1/p' debian/changelog | tac) +revision ?= $(word $(words $(revisions)),$(revisions)) +prev_revisions := $(filter-out $(revision),0.0 $(revisions)) +prev_revision := $(word $(words $(prev_revisions)),$(prev_revisions)) + +# This is an internally used mechanism for the daily kernel builds. It +# creates packages who's ABI is suffixed with a minimal representation of +# the current git HEAD sha. If .git/HEAD is not present, then it uses the +# uuidgen program, +# +# AUTOBUILD can also be used by anyone wanting to build a custom kernel +# image, or rebuild the entire set of Ubuntu packages using custom patches +# or configs. +AUTOBUILD= + +# +# This is a way to support some external variables. A good example is +# a local setup for ccache and distcc See LOCAL_ENV_CC and +# LOCAL_ENV_DISTCC_HOSTS in the definition of kmake. +# For example: +# LOCAL_ENV_CC="ccache distcc" +# LOCAL_ENV_DISTCC_HOSTS="localhost 10.0.2.5 10.0.2.221" +# +-include $(CURDIR)/../.jaunty-env + +ifneq ($(AUTOBUILD),) +skipabi = true +skipmodule = true +skipdbg = true +gitver=$(shell if test -f .git/HEAD; then cat .git/HEAD; else uuidgen; fi) +gitverpre=$(shell echo $(gitver) | cut -b -3) +gitverpost=$(shell echo $(gitver) | cut -b 38-40) +abi_suffix = -$(gitverpre)$(gitverpost) +endif + +ifneq ($(NOKERNLOG),) +ubuntu_log_opts += --no-kern-log +endif +ifneq ($(PRINTSHAS),) +ubuntu_log_opts += --print-shas +endif + +ifeq ($(wildcard /CurrentlyBuilding),) +skipdbg=true +endif + +abinum := $(shell echo $(revision) | sed -e 's/\..*//')$(abi_suffix) +prev_abinum := $(shell echo $(prev_revision) | sed -e 's/\..*//')$(abi_suffix) + +abi_release := $(release)-$(abinum) + +uploadnum := $(shell echo $(revision) | sed -e 's/.*\.//') +ifneq ($(wildcard /CurrentlyBuilding),) + uploadnum := $(uploadnum)-Ubuntu +endif + +# We force the sublevel to be exactly what we want. The actual source may +# be an in development git tree. We want to force it here instead of +# committing changes to the top level Makefile +SUBLEVEL := $(shell echo $(release) | awk -F. '{print $$3}') + +arch := $(shell dpkg-architecture -qDEB_HOST_ARCH) +abidir := $(CURDIR)/debian/abi/$(release)-$(revision)/$(arch) +prev_abidir := $(CURDIR)/debian/abi/$(release)-$(prev_revision)/$(arch) +confdir := $(CURDIR)/debian/config/$(arch) +builddir := $(CURDIR)/debian/build +stampdir := $(CURDIR)/debian/stamps + +# Support parallel= in DEB_BUILD_OPTIONS (see #209008) +COMMA=, +DEB_BUILD_OPTIONS_PARA = $(subst parallel=,,$(filter parallel=%,$(subst $(COMMA), ,$(DEB_BUILD_OPTIONS)))) +ifneq (,$(DEB_BUILD_OPTIONS_PARA)) + CONCURRENCY_LEVEL := $(DEB_BUILD_OPTIONS_PARA) +endif + +ifeq ($(CONCURRENCY_LEVEL),) + # Check the environment + CONCURRENCY_LEVEL := $(shell echo $$CONCURRENCY_LEVEL) + # No? Check if this is on a buildd + ifeq ($(CONCURRENCY_LEVEL),) + ifeq ($(wildcard /CurrentlyBuilding),) + CONCURRENCY_LEVEL := $(shell expr `getconf _NPROCESSORS_ONLN` \* 1) + endif + endif + # Oh hell, give 'em one + ifeq ($(CONCURRENCY_LEVEL),) + CONCURRENCY_LEVEL := 1 + endif +endif + +conc_level = -j$(CONCURRENCY_LEVEL) + +# target_flavour is filled in for each step +kmake = make ARCH=$(build_arch) \ + EXTRAVERSION=-$(abinum)-$(target_flavour) \ + CONFIG_DEBUG_SECTION_MISMATCH=y SUBLEVEL=$(SUBLEVEL) \ + KBUILD_BUILD_VERSION="$(uploadnum)" +ifneq ($(LOCAL_ENV_CC),) +kmake += CC=$(LOCAL_ENV_CC) DISTCC_HOSTS=$(LOCAL_ENV_DISTCC_HOSTS) +endif --- linux-2.6.28.orig/debian/rules.d/2-binary-arch.mk +++ linux-2.6.28/debian/rules.d/2-binary-arch.mk @@ -0,0 +1,282 @@ +# We don't want make removing intermediary stamps +.SECONDARY : + +# Prepare the out-of-tree build directory + +prepare-%: $(stampdir)/stamp-prepare-% + @# Empty for make to be happy +$(stampdir)/stamp-prepare-%: target_flavour = $* +$(stampdir)/stamp-prepare-%: $(confdir)/config $(confdir)/config.% + @echo "Preparing $*..." + install -d $(builddir)/build-$* + touch $(builddir)/build-$*/ubuntu-build + cat $^ | sed -e 's/.*CONFIG_VERSION_SIGNATURE.*/CONFIG_VERSION_SIGNATURE="Ubuntu $(release)-$(revision)-$*"/' > $(builddir)/build-$*/.config + find $(builddir)/build-$* -name "*.ko" | xargs rm -f + $(kmake) O=$(builddir)/build-$* silentoldconfig prepare scripts + touch $@ + + +# Do the actual build, including image and modules +build-%: $(stampdir)/stamp-build-% + @# Empty for make to be happy +$(stampdir)/stamp-build-%: target_flavour = $* +$(stampdir)/stamp-build-%: $(stampdir)/stamp-prepare-% + @echo "Building $*..." + $(kmake) O=$(builddir)/build-$* $(conc_level) $(build_image) + $(kmake) O=$(builddir)/build-$* $(conc_level) modules + @touch $@ + +# Install the finished build +install-%: pkgdir = $(CURDIR)/debian/linux-image-$(abi_release)-$* +install-%: dbgpkgdir = $(CURDIR)/debian/linux-image-debug-$(abi_release)-$* +install-%: basepkg = linux-headers-$(abi_release) +install-%: hdrdir = $(CURDIR)/debian/$(basepkg)-$*/usr/src/$(basepkg)-$* +install-%: target_flavour = $* +install-%: $(stampdir)/stamp-build-% checks-% + dh_testdir + dh_testroot + dh_clean -k -plinux-image-$(abi_release)-$* + dh_clean -k -plinux-headers-$(abi_release)-$* + dh_clean -k -plinux-image-debug-$(abi_release)-$* + + # The main image + install -m644 -D $(builddir)/build-$*/$(kernel_file) \ + $(pkgdir)/boot/$(install_file)-$(abi_release)-$* + + install -m644 $(builddir)/build-$*/.config \ + $(pkgdir)/boot/config-$(abi_release)-$* + install -m644 $(abidir)/$* \ + $(pkgdir)/boot/abi-$(abi_release)-$* + install -m644 $(builddir)/build-$*/System.map \ + $(pkgdir)/boot/System.map-$(abi_release)-$* +ifeq ($(no_dumpfile),) + makedumpfile -g $(pkgdir)/boot/vmcoreinfo-$(abi_release)-$* \ + -x $(builddir)/build-$*/vmlinux +endif + + $(kmake) O=$(builddir)/build-$* modules_install \ + INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$(pkgdir)/ \ + INSTALL_FW_PATH=$(pkgdir)/lib/firmware/$(abi_release)-$* + +ifeq ($(no_dumpfile),) + makedumpfile -g $(pkgdir)/boot/vmcoreinfo-$(abi_release)-$* \ + -x $(builddir)/build-$*/vmlinux +endif + rm -f $(pkgdir)/lib/modules/$(abi_release)-$*/build + rm -f $(pkgdir)/lib/modules/$(abi_release)-$*/source + + # Some initramfs-tools specific modules + install -d $(pkgdir)/lib/modules/$(abi_release)-$*/initrd + if [ -f $(pkgdir)/lib/modules/$(abi_release)-$*/kernel/drivers/video/vesafb.ko ]; then\ + ln -f $(pkgdir)/lib/modules/$(abi_release)-$*/kernel/drivers/video/vesafb.ko \ + $(pkgdir)/lib/modules/$(abi_release)-$*/initrd/; \ + fi + + # Now the image scripts + install -d $(pkgdir)/DEBIAN + for script in postinst postrm preinst prerm; do \ + sed -e 's/=V/$(abi_release)-$*/g' -e 's/=K/$(install_file)/g' \ + -e 's/=L/$(loader)/g' -e 's@=B@$(build_arch)@g' \ + debian/control-scripts/$$script > $(pkgdir)/DEBIAN/$$script; \ + chmod 755 $(pkgdir)/DEBIAN/$$script; \ + done + +ifneq ($(skipsub),true) + @set -e; for sub in $($(*)_sub); do \ + TO=$$sub FROM=$* ABI_RELEASE=$(abi_release) $(SHELL) \ + debian/scripts/sub-flavour; \ + /sbin/depmod -b debian/linux-image-$(abi_release)-$$sub \ + -ea -F debian/linux-image-$(abi_release)-$$sub/boot/System.map-$(abi_release)-$* \ + $(abi_release)-$*; \ + install -d debian/linux-image-$(abi_release)-$$sub/DEBIAN; \ + for script in postinst postrm preinst prerm; do \ + sed -e 's/=V/$(abi_release)-$*/g' \ + -e 's/=K/$(install_file)/g' \ + -e 's/=L/$(loader)/g' \ + -e 's@=B@$(build_arch)@g' \ + debian/control-scripts/$$script > \ + debian/linux-image-$(abi_release)-$$sub/DEBIAN/$$script;\ + chmod 755 debian/linux-image-$(abi_release)-$$sub/DEBIAN/$$script;\ + done; \ + done +endif + +ifneq ($(skipdbg),true) + # Debug image is simple + install -m644 -D $(builddir)/build-$*/vmlinux \ + $(dbgpkgdir)/usr/lib/debug/boot/vmlinux-$(abi_release)-$* + $(kmake) O=$(builddir)/build-$* modules_install \ + INSTALL_MOD_PATH=$(dbgpkgdir)/usr/lib/debug + rm -f $(dbgpkgdir)/usr/lib/debug/lib/modules/$(abi_release)-$*/build + rm -f $(dbgpkgdir)/usr/lib/debug/lib/modules/$(abi_release)-$*/source + rm -f $(dbgpkgdir)/usr/lib/debug/lib/modules/$(abi_release)-$*/modules.* + rm -fr $(dbgpkgdir)/usr/lib/debug/lib/firmware +endif + + # The flavour specific headers image + # TODO: Would be nice if we didn't have to dupe the original builddir + install -d -m755 $(hdrdir) + cat $(builddir)/build-$*/.config | \ + sed -e 's/.*CONFIG_DEBUG_INFO=.*/# CONFIG_DEBUG_INFO is not set/g' > \ + $(hdrdir)/.config + chmod 644 $(hdrdir)/.config + $(kmake) O=$(hdrdir) silentoldconfig prepare scripts + # We'll symlink this stuff + rm -f $(hdrdir)/Makefile + rm -rf $(hdrdir)/include2 + # Script to symlink everything up + $(SHELL) debian/scripts/link-headers "$(hdrdir)" "$(basepkg)" "$*" + # Setup the proper asm symlink + rm -f $(hdrdir)/include/asm + ln -s asm-$(asm_link) $(hdrdir)/include/asm + # The build symlink + install -d debian/$(basepkg)-$*/lib/modules/$(abi_release)-$* + ln -s /usr/src/$(basepkg)-$* \ + debian/$(basepkg)-$*/lib/modules/$(abi_release)-$*/build + # And finally the symvers + install -m644 $(builddir)/build-$*/Module.symvers \ + $(hdrdir)/Module.symvers + + # Now the header scripts + install -d $(CURDIR)/debian/$(basepkg)-$*/DEBIAN + for script in postinst; do \ + sed -e 's/=V/$(abi_release)-$*/g' -e 's/=K/$(install_file)/g' \ + debian/control-scripts/headers-$$script > \ + $(CURDIR)/debian/$(basepkg)-$*/DEBIAN/$$script; \ + chmod 755 $(CURDIR)/debian/$(basepkg)-$*/DEBIAN/$$script; \ + done + + # At the end of the package prep, call the tests + DPKG_ARCH="$(arch)" KERN_ARCH="$(build_arch)" FLAVOUR="$*" \ + VERSION="$(abi_release)" REVISION="$(revision)" \ + PREV_REVISION="$(prev_revision)" ABI_NUM="$(abinum)" \ + PREV_ABI_NUM="$(prev_abinum)" BUILD_DIR="$(builddir)/build-$*" \ + INSTALL_DIR="$(pkgdir)" SOURCE_DIR="$(CURDIR)" \ + run-parts -v debian/tests + + # + # Remove files which are generated at installation by postinst, except for + # modules.order. + # + mv $(pkgdir)/lib/modules/$(abi_release)-$*/modules.order \ + $(pkgdir)/lib/modules/$(abi_release)-$*/_modules.order + rm -f $(pkgdir)/lib/modules/$(abi_release)-$*/modules.* + mv $(pkgdir)/lib/modules/$(abi_release)-$*/_modules.order \ + $(pkgdir)/lib/modules/$(abi_release)-$*/modules.order + +headers_tmp := $(CURDIR)/debian/tmp-headers +headers_dir := $(CURDIR)/debian/linux-libc-dev + +hmake := $(MAKE) -C $(CURDIR) O=$(headers_tmp) SUBLEVEL=$(SUBLEVEL) \ + EXTRAVERSION=-$(abinum) INSTALL_HDR_PATH=$(headers_tmp)/install \ + SHELL="$(SHELL)" ARCH=$(header_arch) + +install-arch-headers: + dh_testdir + dh_testroot + dh_clean -k -plinux-libc-dev + + rm -rf $(headers_tmp) + install -d $(headers_tmp) $(headers_dir)/usr/include/ + + $(hmake) $(defconfig) + mv $(headers_tmp)/.config $(headers_tmp)/.config.old + sed -e 's/^# \(CONFIG_MODVERSIONS\) is not set$$/\1=y/' \ + -e 's/.*CONFIG_LOCALVERSION_AUTO.*/# CONFIG_LOCALVERSION_AUTO is not set/' \ + $(headers_tmp)/.config.old > $(headers_tmp)/.config + $(hmake) silentoldconfig + $(hmake) headers_install + + ( cd $(headers_tmp)/install/include/ && \ + find . -name '.' -o -name '.*' -prune -o -print | \ + cpio -pvd --preserve-modification-time \ + $(headers_dir)/usr/include/ ) + + rm -rf $(headers_tmp) + +binary-arch-headers: install-arch-headers + dh_testdir + dh_testroot + + dh_installchangelogs -plinux-libc-dev + dh_installdocs -plinux-libc-dev + dh_compress -plinux-libc-dev + dh_fixperms -plinux-libc-dev + dh_installdeb -plinux-libc-dev + dh_gencontrol -plinux-libc-dev + dh_md5sums -plinux-libc-dev + dh_builddeb -plinux-libc-dev + +binary-%: pkgimg = linux-image-$(abi_release)-$* +binary-%: pkghdr = linux-headers-$(abi_release)-$* +binary-%: dbgpkg = linux-image-debug-$(abi_release)-$* +binary-%: install-% + dh_testdir + dh_testroot + + dh_installchangelogs -p$(pkgimg) + dh_installdocs -p$(pkgimg) + dh_compress -p$(pkgimg) + dh_fixperms -p$(pkgimg) + dh_installdeb -p$(pkgimg) + dh_gencontrol -p$(pkgimg) + dh_md5sums -p$(pkgimg) + dh_builddeb -p$(pkgimg) -- -Zbzip2 -z9 + + dh_installchangelogs -p$(pkghdr) + dh_installdocs -p$(pkghdr) + dh_compress -p$(pkghdr) + dh_fixperms -p$(pkghdr) + dh_shlibdeps -p$(pkghdr) + dh_installdeb -p$(pkghdr) + dh_gencontrol -p$(pkghdr) + dh_md5sums -p$(pkghdr) + dh_builddeb -p$(pkghdr) + +ifneq ($(skipsub),true) + @set -e; for sub in $($(*)_sub); do \ + pkg=linux-image-$(abi_release)-$$sub; \ + dh_installchangelogs -p$$pkg; \ + dh_installdocs -p$$pkg; \ + dh_compress -p$$pkg; \ + dh_fixperms -p$$pkg; \ + dh_shlibdeps -p$$pkg; \ + dh_installdeb -p$$pkg; \ + dh_gencontrol -p$$pkg; \ + dh_md5sums -p$$pkg; \ + dh_builddeb -p$$pkg; \ + done +endif + +ifneq ($(skipdbg),true) + dh_installchangelogs -p$(dbgpkg) + dh_installdocs -p$(dbgpkg) + dh_compress -p$(dbgpkg) + dh_fixperms -p$(dbgpkg) + dh_installdeb -p$(dbgpkg) + dh_gencontrol -p$(dbgpkg) + dh_md5sums -p$(dbgpkg) + dh_builddeb -p$(dbgpkg) + + # Hokay...here's where we do a little twiddling... + mv ../$(dbgpkg)_$(release)-$(revision)_$(arch).deb \ + ../$(dbgpkg)_$(release)-$(revision)_$(arch).ddeb + grep -v '^$(dbgpkg)_.*$$' debian/files > debian/files.new + mv debian/files.new debian/files + # Now, the package wont get into the archive, but it will get put + # into the debug system. +endif + +$(stampdir)/stamp-flavours: + @echo $(flavours) > $@ + +binary-debs: $(stampdir)/stamp-flavours $(addprefix binary-,$(flavours)) \ + binary-arch-headers + +build-arch: $(addprefix build-,$(flavours)) + +binary-arch-deps = binary-debs +ifeq ($(AUTOBUILD),) +binary-arch-deps += binary-udebs +endif +binary-arch: $(binary-arch-deps) --- linux-2.6.28.orig/debian/rules.d/i386.mk +++ linux-2.6.28/debian/rules.d/i386.mk @@ -0,0 +1,12 @@ +build_arch = i386 +header_arch = x86_64 +asm_link = x86 +defconfig = defconfig +flavours = generic server +build_image = bzImage +kernel_file = arch/$(build_arch)/boot/bzImage +install_file = vmlinuz + +server_sub = virtual + +loader = grub --- linux-2.6.28.orig/debian/rules.d/1-maintainer.mk +++ linux-2.6.28/debian/rules.d/1-maintainer.mk @@ -0,0 +1,95 @@ +# The following targets are for the maintainer only! do no run if you don't +# know what they do. + +.PHONY: printenv updateconfigs printchanges insertchanges startnewrelease diffupstream help + +help: + @echo "These are the targets in addition to the normal debian ones:" + @echo + @echo " printenv : Print some variables used in the build" + @echo + @echo " updateconfigs : Update debian/config/*" + @echo + @echo " editconfigs : Update debian/config/* interactively" + @echo + @echo " printchanges : Print the current changelog entries (from git)" + @echo + @echo " insertchanges : Insert current changelog entries (from git)" + @echo + @echo " startnewrelease : Start a new changelog set" + @echo + @echo " diffupstream : Diff stock kernel code against upstream (git)" + @echo + @echo " help : If you are kernel hacking, you need the professional" + @echo " version of this" + @echo + @echo "Environment variables:" + @echo + @echo " NOKERNLOG : Do not add upstream kernel commits to changelog" + @echo " CONCURRENCY_LEVEL=X" + @echo " : Use -jX for kernel compile" + @echo " PRINTSHAS : Include SHAs for commits in changelog" + +ARCH_CONFIGS=i386 amd64 armel lpia + +updateconfigs: + dh_testdir + @for arch in $(ARCH_CONFIGS); do \ + $(SHELL) debian/scripts/misc/oldconfig $$arch; \ + done + rm -rf build + +editconfigs: + dh_testdir + @for arch in $(ARCH_CONFIGS); do \ + $(SHELL) debian/scripts/misc/doconfig $$arch; \ + done + rm -rf build + +printenv: + dh_testdir + @echo "release = $(release)" + @echo "revisions = $(revisions)" + @echo "revision = $(revision)" + @echo "uploadnum = $(uploadnum)" + @echo "prev_revisions = $(prev_revisions)" + @echo "prev_revision = $(prev_revision)" + @echo "abinum = $(abinum)" + @echo "gitver = $(gitver)" + @echo "flavours = $(flavours)" + @echo "skipabi = $(skipabi)" + @echo "skipmodule = $(skipmodule)" + @echo "skipdbg = $(skipdbg)" + @echo "ubuntu_log_opts = $(ubuntu_log_opts)" +ifneq ($(SUBLEVEL),) + @echo "SUBLEVEL = $(SUBLEVEL)" +endif + @echo "CONCURRENCY_LEVEL = $(CONCURRENCY_LEVEL)" + +printchanges: + @git log Ubuntu-$(release)-$(prev_revision)..HEAD | \ + perl -w -f debian/scripts/misc/git-ubuntu-log $(ubuntu_log_opts) + +insertchanges: + @perl -w -f debian/scripts/misc/insert-changes.pl + +diffupstream: + @git diff-tree -p refs/remotes/linux-2.6/master..HEAD $(shell ls | grep -vE '^(ubuntu|debian|\.git.*)') + +startnewrelease: + dh_testdir + @nextminor=$(shell expr `echo $(revision) | awk -F. '{print $$2}'` + 1); \ + now="$(shell date -R)"; \ + echo "Creating new changelog set for $(abi_release).$$nextminor..."; \ + echo -e "$(stub) ($(abi_release).$$nextminor) UNRELEASED; urgency=low\n" > debian/changelog.new; \ + echo " CHANGELOG: Do not edit directly. Autogenerated at release." >> \ + debian/changelog.new; \ + echo " CHANGELOG: Use the printchanges target to see the curent changes." \ + >> debian/changelog.new; \ + echo " CHANGELOG: Use the insertchanges target to create the final log." \ + >> debian/changelog.new; \ + echo -e "\n -- $$DEBFULLNAME <$$DEBEMAIL> $$now\n" >> \ + debian/changelog.new ; \ + cat debian/changelog >> debian/changelog.new; \ + mv debian/changelog.new debian/changelog + --- linux-2.6.28.orig/debian/scripts/abi-check +++ linux-2.6.28/debian/scripts/abi-check @@ -0,0 +1,210 @@ +#!/usr/bin/perl -w + +my $flavour = shift; +my $prev_abinum = shift; +my $abinum = shift; +my $prev_abidir = shift; +my $abidir = shift; +my $skipabi = shift; + +my $fail_exit = 1; +my $EE = "EE:"; +my $errors = 0; +my $abiskip = 0; + +my $count; + +print "II: Checking ABI for $flavour...\n"; + +if (-f "$prev_abidir/ignore" + or -f "$prev_abidir/$flavour.ignore" or "$skipabi" eq "true") { + print "WW: Explicitly asked to ignore ABI, running in no-fail mode\n"; + $fail_exit = 0; + $abiskip = 1; + $EE = "WW:"; +} + +if ($prev_abinum != $abinum) { + print "II: Different ABI's, running in no-fail mode\n"; + $fail_exit = 0; + $EE = "WW:"; +} + +if (not -f "$abidir/$flavour" or not -f "$prev_abidir/$flavour") { + print "EE: Previous or current ABI file missing!\n"; + print " $abidir/$flavour\n" if not -f "$abidir/$flavour"; + print " $prev_abidir/$flavour\n" if not -f "$prev_abidir/$flavour"; + + # Exit if the ABI files are missing, but return status based on whether + # skip ABI was indicated. + if ("$abiskip" eq "1") { + exit(0); + } else { + exit(1); + } +} + +my %symbols; +my %symbols_ignore; +my %modules_ignore; +my %module_syms; + +# See if we have any ignores +my $ignore = 0; +print " Reading symbols/modules to ignore..."; + +for $file ("$prev_abidir/../blacklist", "$prev_abidir/../../perm-blacklist") { + if (-f $file) { + open(IGNORE, "< $file") or + die "Could not open $file"; + while () { + chomp; + if ($_ =~ m/M: (.*)/) { + $modules_ignore{$1} = 1; + } else { + $symbols_ignore{$_} = 1; + } + $ignore++; + } + close(IGNORE); + } +} +print "read $ignore symbols/modules.\n"; + +sub is_ignored($$) { + my ($mod, $sym) = @_; + + die "Missing module name in is_ignored()" if not defined($mod); + die "Missing symbol name in is_ignored()" if not defined($sym); + + if (defined($symbols_ignore{$sym}) or defined($modules_ignore{$mod})) { + return 1; + } + return 0; +} + +# Read new syms first +print " Reading new symbols ($abinum)..."; +$count = 0; +open(NEW, "< $abidir/$flavour") or + die "Could not open $abidir/$flavour"; +while () { + chomp; + m/^(EXPORT_.+)\s(.+)\s(0x[0-9a-f]+)\s(.+)$/; + $symbols{$4}{'type'} = $1; + $symbols{$4}{'loc'} = $2; + $symbols{$4}{'hash'} = $3; + $module_syms{$2} = 0; + $count++; +} +close(NEW); +print "read $count symbols.\n"; + +# Now the old symbols, checking for missing ones +print " Reading old symbols ($prev_abinum)..."; +$count = 0; +open(OLD, "< $prev_abidir/$flavour") or + die "Could not open $prev_abidir/$flavour"; +while () { + chomp; + m/^(EXPORT_.+)\s(.+)\s(0x[0-9a-f]+)\s(.+)$/; + $symbols{$4}{'old_type'} = $1; + $symbols{$4}{'old_loc'} = $2; + $symbols{$4}{'old_hash'} = $3; + $count++; +} +close(OLD); + +print "read $count symbols.\n"; + +print "II: Checking for missing symbols in new ABI..."; +$count = 0; +foreach $sym (keys(%symbols)) { + if (!defined($symbols{$sym}{'type'})) { + print "\n" if not $count; + printf(" MISS : %s%s\n", $sym, + is_ignored($symbols{$sym}{'old_loc'}, $sym) ? " (ignored)" : ""); + $count++ if !is_ignored($symbols{$sym}{'old_loc'}, $sym); + } +} +print " " if $count; +print "found $count missing symbols\n"; +if ($count) { + print "$EE Symbols gone missing (what did you do!?!)\n"; + $errors++; +} + + +print "II: Checking for new symbols in new ABI..."; +$count = 0; +foreach $sym (keys(%symbols)) { + if (!defined($symbols{$sym}{'old_type'})) { + print "\n" if not $count; + print " NEW : $sym\n"; + $count++; + } +} +print " " if $count; +print "found $count new symbols\n"; +if ($count and $prev_abinum == $abinum) { + print "WW: Found new symbols within same ABI. Not recommended\n"; +} + +print "II: Checking for changes to ABI...\n"; +$count = 0; +my $moved = 0; +my $changed_type = 0; +my $changed_hash = 0; +foreach $sym (keys(%symbols)) { + if (!defined($symbols{$sym}{'old_type'}) or + !defined($symbols{$sym}{'type'})) { + next; + } + + # Changes in location don't hurt us, but log it anyway + if ($symbols{$sym}{'loc'} ne $symbols{$sym}{'old_loc'}) { + printf(" MOVE : %-40s : %s => %s\n", $sym, $symbols{$sym}{'old_loc'}, + $symbols{$sym}{'loc'}); + $moved++; + } + + # Changes to export type are only bad if new type isn't + # EXPORT_SYMBOL. Changing things to GPL are bad. + if ($symbols{$sym}{'type'} ne $symbols{$sym}{'old_type'}) { + printf(" TYPE : %-40s : %s => %s%s\n", $sym, $symbols{$sym}{'old_type'}. + $symbols{$sym}{'type'}, is_ignored($symbols{$sym}{'loc'}, $sym) + ? " (ignored)" : ""); + $changed_type++ if $symbols{$sym}{'type'} ne "EXPORT_SYMBOL" + and !is_ignored($symbols{$sym}{'loc'}, $sym); + } + + # Changes to the hash are always bad + if ($symbols{$sym}{'hash'} ne $symbols{$sym}{'old_hash'}) { + printf(" HASH : %-40s : %s => %s%s\n", $sym, $symbols{$sym}{'old_hash'}, + $symbols{$sym}{'hash'}, is_ignored($symbols{$sym}{'loc'}, $sym) + ? " (ignored)" : ""); + $changed_hash++ if !is_ignored($symbols{$sym}{'loc'}, $sym); + $module_syms{$symbols{$sym}{'loc'}}++; + } +} + +print "WW: $moved symbols changed location\n" if $moved; +print "$EE $changed_type symbols changed export type and weren't ignored\n" if $changed_type; +print "$EE $changed_hash symbols changed hash and weren't ignored\n" if $changed_hash; + +$errors++ if $changed_hash or $changed_type; +if ($changed_hash) { + print "II: Module hash change summary...\n"; + foreach $mod (sort { $module_syms{$b} <=> $module_syms{$a} } keys %module_syms) { + next if ! $module_syms{$mod}; + printf(" %-40s: %d\n", $mod, $module_syms{$mod}); + } +} + +print "II: Done\n"; + +if ($errors) { + exit($fail_exit); +} else { + exit(0); +} --- linux-2.6.28.orig/debian/scripts/control-create +++ linux-2.6.28/debian/scripts/control-create @@ -0,0 +1,23 @@ +#!/bin/bash + +vars=$1 + +. $vars + +if [ "$is_sub" = "" ]; then + flavour=$(basename $vars | sed 's/.*\.//') + stub=debian/control.d/flavour-control.stub +else + flavour=$(basename $vars .vars) + stub=debian/sub-flavours/control.stub +fi + +cat $stub | grep -v '^#' | sed \ + -e "s#FLAVOUR#$flavour#g" \ + -e "s#DESC#$desc#g" \ + -e "s#ARCH#$arch#g" \ + -e "s#SUPPORTED#$supported#g" \ + -e "s#TARGET#$target#g" \ + -e "s#BOOTLOADER#$bootloader#g" \ + -e "s#=PROVIDES=#$provides#g" \ + -e "s#=CONFLICTS=#$conflicts#g" --- linux-2.6.28.orig/debian/scripts/module-check +++ linux-2.6.28/debian/scripts/module-check @@ -0,0 +1,120 @@ +#!/usr/bin/perl -w + +$flavour = shift; +$prev_abidir = shift; +$abidir = shift; +$skipmodule = shift; + +print "II: Checking modules for $flavour..."; + +if (-f "$prev_abidir/ignore.modules" + or -f "$prev_abidir/$flavour.ignore.modules") { + print "explicitly ignoring modules\n"; + exit(0); +} + +if (not -f "$abidir/$flavour.modules" or not -f + "$prev_abidir/$flavour.modules") { + print "previous or current modules file missing!\n"; + print " $abidir/$flavour.modules\n"; + print " $prev_abidir/$flavour.modules\n"; + if (defined($skipmodule)) { + exit(0); + } else { + exit(1); + } +} + +print "\n"; + +my %modules; +my %modules_ignore; +my $missing = 0; +my $new = 0; +my $errors = 0; + +# See if we have any ignores +if (-f "$prev_abidir/../modules.ignore") { + my $ignore = 0; + open(IGNORE, "< $prev_abidir/../modules.ignore") or + die "Could not open $prev_abidir/../modules.ignore"; + print " reading modules to ignore..."; + while () { + chomp; + next if /\s*#/; + $modules_ignore{$_} = 1; + $ignore++; + } + close(IGNORE); + print "read $ignore modules.\n"; +} + +# Read new modules first +print " reading new modules..."; +$new_count = 0; +open(NEW, "< $abidir/$flavour.modules") or + die "Could not open $abidir/$flavour.modules"; +while () { + chomp; + $modules{$_} = 1; + $new_count++; +} +close(NEW); +print "read $new_count modules.\n"; + +# Now the old modules, checking for missing ones +print " reading old modules..."; +$old_count = 0; +open(OLD, "< $prev_abidir/$flavour.modules") or + die "Could not open $prev_abidir/$flavour.modules"; +while () { + chomp; + if (not defined($modules{$_})) { + print "\n" if not $missing; + $missing++; + if (not defined($modules_ignore{$_})) { + print " MISS: $_\n"; + $errors++; + } else { + print " MISS: $_ (ignored)\n"; + } + } else { + $modules{$_}++; + } + $old_count++; +} +close(OLD); +# Check for new modules +foreach $mod (keys(%modules)) { + if ($modules{$mod} < 2) { + print "\n" if not $missing and not $new; + print " NEW : $mod\n"; + $new++; + } +} +if ($new or $missing) { + print " read $old_count modules : new($new) missing($missing)\n"; +} else { + print "read $old_count modules.\n"; +} + + +# Let's see where we stand... +if ($errors) { + if (defined($skipmodule)) { + print "WW: Explicitly asked to ignore failures (probably not good)\n"; + } else { + print "EE: Missing modules (start begging for mercy)\n"; + exit 1 + } +} + +if ($new) { + print "II: New modules (you've been busy, wipe the poop off your nose)\n"; +} else { + print "II: No new modules (hope you're happy, slacker)\n"; +} + +print "II: Done\n"; + +exit(0); --- linux-2.6.28.orig/debian/scripts/sub-flavour +++ linux-2.6.28/debian/scripts/sub-flavour @@ -0,0 +1,32 @@ +#!/bin/bash -e + + + +echo "SUB_PROCESS $FROM => $TO" + +export from_pkg="linux-image-$ABI_RELEASE-$FROM" +export to_pkg="linux-image-$ABI_RELEASE-$TO" + +from_moddir="debian/$from_pkg/lib/modules/$ABI_RELEASE-$FROM" +to_moddir="debian/$to_pkg/lib/modules/$ABI_RELEASE-$FROM" + +install -d "debian/$to_pkg/boot" +install -m644 debian/$from_pkg/boot/{vmlinuz,System.map,config}-$ABI_RELEASE-$FROM \ + debian/$to_pkg/boot/ + +cat debian/sub-flavours/$TO.list | while read line; do + (cd debian/$from_pkg/lib/modules/$ABI_RELEASE-$FROM/kernel; + eval find $line -name '*.ko'); +done | while read mod; do + echo "SUB_INST checking: $mod" + fromdir="/lib/modules/$ABI_RELEASE-$FROM/" + egrep "^($fromdir)?kernel/$mod:" \ + $from_moddir/modules.dep | sed -e "s|^$fromdir||" -e 's/://' -e 's/ /\n/g' | \ + while read m; do + m="${fromdir}$m" + test -f debian/$to_pkg/$m && continue + echo "SUB_INST installing: $mod" + install -D -m644 debian/$from_pkg/$m \ + debian/$to_pkg/$m + done +done --- linux-2.6.28.orig/debian/scripts/link-headers +++ linux-2.6.28/debian/scripts/link-headers @@ -0,0 +1,40 @@ +#!/bin/bash -e + +hdrdir="$1" +symdir="$2" +flavour="$3" + +echo "Symlinking and copying headers for $flavour..." + +excludes='( -path ./debian -prune -o -path ./.git ) -prune -o' + +( +find . $excludes -type f \ + \( -name 'Makefile*' -o -name 'Kconfig*' -o -name 'Kbuild*' -o \ + -name '*.sh' -o -name '*.pl' -o -name '*.lds' \) -print +find ./include ./scripts -name .gitignore -prune -o -type f -print +find ./include -mindepth 1 -maxdepth 1 $excludes -type d -print +) | ( +while read file; do + dir=$file + lastdir=$file + + if [ -e "$hdrdir/$file" -o -L "$hdrdir/$file" ]; then + continue + fi + + while [ ! -e "$hdrdir/$dir" -a ! -L "$hdrdir/$dir" ]; do + lastdir=$dir + dir=`dirname $dir` + done + # If the last item to exist is a symlink we assume all is good + if [ ! -L "$hdrdir/$dir" ]; then + # Turns things like "./foo" into "../" + deref="`echo -n $lastdir | sed -e 's/^\.//' -e's,/[^/]*,../,g'`" + item="`echo -n $lastdir | sed -e 's/^\.\///'`" + ln -s $deref$symdir/$item $hdrdir/$item + fi +done +) + +exit --- linux-2.6.28.orig/debian/scripts/misc/git-ubuntu-log +++ linux-2.6.28/debian/scripts/misc/git-ubuntu-log @@ -0,0 +1,220 @@ +#!/usr/bin/perl -w + +use strict; +use Text::Wrap; + +my $kernel_auth = "Upstream Kernel Changes"; + +my (%map, @reverts); +my $pstate = 1; +my $no_kern_log = 0; +my $print_shas = 0; +my $first_print = 1; + +while (@ARGV) { + my $opt = $ARGV[0]; + shift; + if ($opt eq "--no-kern-log") { + $no_kern_log = 1; + } elsif ($opt eq "--print-shas") { + $print_shas = 1; + } else { + print STDERR "Unknown options: $opt\n"; + exit(1); + } +} + +sub check_reverts($) { + my ($entry) = @_; + my ($check); + + foreach $check (reverse @reverts) { + my $desc = "Revert \"" . $entry->{'desc'} . "\""; + if ($check->{'desc'} eq $desc) { + @reverts = grep($_->{'desc'} ne $desc, @reverts); + return 1; + } + } + + return 0; +} + +sub add_entry($) { + my ($entry) = @_; + my $key = $entry->{'author'}; + + # store description in array, in email->{desc list} map + if (exists $map{$key}) { + # grab ref + my $obj = $map{$key}; + + # add desc to array + push(@$obj, $entry); + } else { + # create new array, containing 1 item + my @arr = ($entry); + + # store ref to array + $map{$key} = \@arr; + } +} + +sub shortlog_entry($$$$$) { + my ($name, $desc, $bug, $cve, $commit) = @_; + my $entry; + + $desc =~ s#/pub/scm/linux/kernel/git/#/.../#g; + $desc =~ s#\[PATCH\] ##g; + + $desc =~ s#^\s*##g; + $desc =~ s# *UBUNTU: ##g; + + $entry->{'desc'} = $desc; + $entry->{'bugno'} = $bug; + $entry->{'cve'} = $cve; + $entry->{'commit'} = $commit; + $entry->{'author'} = $name; + + if ($desc =~ /^Revert "/) { + push(@reverts, $entry); + return; + } + + return if check_reverts($entry); + + add_entry($entry); +} + +# sort comparison function +sub by_name($$) { + my ($a, $b) = @_; + + uc($a) cmp uc($b); +} + +sub shortlog_output { + my ($obj, $key, $entry); + + foreach $key (sort by_name keys %map) { + next if $key eq $kernel_auth and $no_kern_log; + + print "\n" unless $first_print; + $first_print = 0; + + # output author + printf " [ %s ]\n\n", $key; + + # output author's 1-line summaries + $obj = $map{$key}; + foreach $entry (reverse @$obj) { + print wrap(" * ", " ", $entry->{'desc'}) . "\n"; + # For non upstream changes, add other info. + if ($key ne $kernel_auth) { + if ($print_shas) { + print " - GIT-SHA " . $entry->{'commit'} . + "\n"; + } + } + if (defined($entry->{'bugno'})) { + print " - LP: #" . $entry->{'bugno'} . "\n"; + } + if (defined($entry->{'cve'})) { + print " - " . $entry->{'cve'} . "\n"; + } + } + } +} + +sub changelog_input { + my ($author, $desc, $commit, $entry, $cve); + + while () { + # get commit + if ($pstate == 1) { + next unless /^commit (.*)/; + + $commit = $1; + + $pstate++; + } + + # get author and email + elsif ($pstate == 2) { + my ($email); + + next unless /^[Aa]uthor:?\s*(.*?)\s*<(.*)>/; + + $author = $1; + $email = $2; + $desc = undef; + $cve = undef; + + # cset author fixups + if (!$author) { + $author = $email; + } + $pstate++; + } + + # skip to blank line + elsif ($pstate == 3) { + next unless /^\s*$/; + $pstate++; + } + + # skip to non-blank line + elsif ($pstate == 4) { + next unless /^\s*?(.*)/; + my $ignore = 0; + my $bug = undef; + + # skip lines that are obviously not + # a 1-line cset description + next if /^\s*From: /; + + chomp; + $desc = $1; + + if ($desc =~ /^ *(Revert "|)UBUNTU:/) { + while () { + $ignore = 1 if /^ *Ignore: yes/i; + $bug = $2 if /^ *Bug: *(#|)(.*)/; + $cve = $1 if /^ *(CVE-.*)/; + last if /^commit /; + } + } else { + $author = $kernel_auth; + $ignore = 1 if $desc =~ /Merge /; + while () { + $bug = $2 if /^ *Bug: *(#|)(.*)/; + $cve = $1 if /^ *(CVE-.*)/; + last if /^commit /; + } + } + + if (!$ignore) { + &shortlog_entry($author, $desc, $bug, + $cve, $commit, 0); + } + + $pstate = 1; + if ($_ && /^commit (.*)/) { + $commit = $1; + $pstate++; + } + } + + else { + die "invalid parse state $pstate"; + } + } + + foreach $entry (@reverts) { + add_entry($entry); + } +} + +&changelog_input; +&shortlog_output; + +exit(0); --- linux-2.6.28.orig/debian/scripts/misc/oldconfig +++ linux-2.6.28/debian/scripts/misc/oldconfig @@ -0,0 +1,65 @@ +#!/bin/bash + +# We have to be in the top level kernel source directory +if [ ! -f MAINTAINERS ] || [ ! -f Makefile ]; then + echo "This does not appear to be the kernel source directory." 1>&2 + exit 1 +fi + + +# One arg, and that's it. Just pass an architecture +if [ $# -ne 1 ]; then + echo "Usage: $0 " 1>&2 + exit 1 +fi + +arch="$1" + +case "$arch" in + amd64) kernarch="x86_64" ;; + armel) kernarch="arm" ;; + lpia) kernarch="i386" ;; + *) kernarch="$arch" ;; +esac + +confdir="`pwd`/debian/config/$arch" +bindir="`pwd`/debian/scripts/misc" + +# Make sure the architecture exists +if [ ! -d $confdir ]; then + echo "Could not find config directory for $arch" 1>&2 + exit 1 +fi + +echo "Processing $arch ($kernarch) ... " + +configs=$(cd $confdir && ls config.*) + +if [ -f $confdir/config ]; then + for config in $configs; do + case $config in + *) + cat $confdir/config >> $confdir/$config + ;; + esac + done + rm -f $confdir/config +fi + +test -d build || mkdir build +cd build +for config in $configs; do + echo "Running silentoldconfig for $config ... " + + cat $confdir/$config > .config + + make -C ../ O=`pwd` silentoldconfig ARCH=$kernarch + + cat .config > $confdir/$config +done +cd .. + +echo "Running splitconfig.pl ... " +echo + +(cd $confdir ; $bindir/splitconfig.pl) --- linux-2.6.28.orig/debian/scripts/misc/splitconfig.pl +++ linux-2.6.28/debian/scripts/misc/splitconfig.pl @@ -0,0 +1,110 @@ +#!/usr/bin/perl -w + +%configs = (); +%common = (); + +print "Reading config's ...\n"; + +opendir(DIR, "."); + +while (defined($config = readdir(DIR))) { + # Only config.* + next if $config !~ /^config\..*/; + # Nothing that is disabled, or remnant + next if $config =~ /.*\.(default|disabled|stub)$/; + # Server config's are standalone + #next if $config =~ /config.server-.*/; + + %{$configs{$config}} = (); + + print " processing $config ... "; + + open(CONFIG, "< $config"); + + while () { + /^#*\s*CONFIG_(\w+)[\s=](.*)$/ or next; + + ${$configs{$config}}{$1} = $2; + + $common{$1} = $2; + } + + close(CONFIG); + + print "done.\n"; +} + +closedir(DIR); + +print "\n"; + +print "Merging lists ... \n"; + +for $config (keys(%configs)) { + my %options = %{$configs{$config}}; + + print " processing $config ... "; + + for $key (keys(%common)) { + next if not defined $common{$key}; + + # If we don't have the common option, then it isn't + # common. If we do have that option, it must have the same + # value (this is where the old split.py was broken). It + # also did the common check while it was parsing files, so + # that there were cases where a non-common option was in + # common anyway (ordering). + if (not defined($options{$key})) { + undef $common{$key}; + } elsif ($common{$key} ne $options{$key}) { + undef $common{$key}; + } + } + + print "done.\n"; +} + +print "\n"; + +print "Creating common config ... "; + +open(COMMON, "> config"); +print COMMON "#\n# Common config options automatically generated by splitconfig.pl\n#\n"; + +for $key (sort(keys(%common))) { + next if not defined $common{$key}; + + if ($common{$key} eq "is not set") { + print COMMON "# CONFIG_$key is not set\n"; + } else { + print COMMON "CONFIG_$key=$common{$key}\n"; + } +} +close(COMMON); + +print "done.\n\n"; + +print "Creating stub configs ...\n"; + +for $config (keys(%configs)) { + my %options = %{$configs{$config}}; + + print " processing $config ... "; + + open(STUB, "> $config"); + print STUB "#\n# Config options for $config automatically generated by splitconfig.pl\n#\n"; + + for $key (sort(keys(%options))) { + next if defined $common{$key}; + + if ($options{$key} eq "is not set") { + print STUB "# CONFIG_$key is not set\n"; + } else { + print STUB "CONFIG_$key=$options{$key}\n"; + } + } + + close(STUB); + + print "done.\n"; +} --- linux-2.6.28.orig/debian/scripts/misc/doconfig +++ linux-2.6.28/debian/scripts/misc/doconfig @@ -0,0 +1,66 @@ +#!/bin/bash + +# We have to be in the top level kernel source directory +if [ ! -f MAINTAINERS ] || [ ! -f Makefile ]; then + echo "This does not appear to be the kernel source directory." 1>&2 + exit 1 +fi + + +# One arg, and that's it. Just pass an architecture +if [ $# -ne 1 ]; then + echo "Usage: $0 " 1>&2 + exit 1 +fi + +arch="$1" + +case "$arch" in + amd64) kernarch="x86_64" ;; + armel) kernarch="arm" ;; + lpia) kernarch="i386" ;; + *) kernarch="$arch" ;; +esac + +confdir="`pwd`/debian/config/$arch" +bindir="`pwd`/debian/scripts/misc" + +# Make sure the architecture exists +if [ ! -d $confdir ]; then + echo "Could not find config directory for $arch" 1>&2 + exit 1 +fi + +echo "Processing $arch ($kernarch) ... " + +configs=$(cd $confdir && ls config.*) + +if [ -f $confdir/config ]; then + for config in $configs; do + case $config in + *) + cat $confdir/config >> $confdir/$config + ;; + esac + done + rm -f $confdir/config +fi + +test -d build || mkdir build +cd build +for config in $configs; do + + cat $confdir/$config > .config + + echo About to configure $arch $config + read + make -C ../ O=`pwd` ARCH=$kernarch menuconfig + + cat .config > $confdir/$config +done +cd .. + +echo "Running splitconfig.pl ... " +echo + +(cd $confdir ; $bindir/splitconfig.pl) --- linux-2.6.28.orig/debian/scripts/misc/ppa-cron-job +++ linux-2.6.28/debian/scripts/misc/ppa-cron-job @@ -0,0 +1,47 @@ +#!/bin/sh + +# +# Use this script as a template for the daily kernel build cron job. +# You should copy it somewhere outside of the git tree 'cause the whole +# git tree gets removed and recreated. +# +KNAME=jaunty +DAILY_BUILD_DIR=${KBDIR:=${HOME}/${KNAME}} +KERNEL_GIT_REPO=${KREPO:=/srv/kernel.ubuntu.com/git/ubuntu/ubuntu-${KNAME}.git} + +# +# Nothing works unless there is a dput configuration. +# +if [ ! -f ${HOME}/.dput.cf ] +then + echo No dput configuration. + exit 1 +fi + +if [ ! -d ${DAILY_BUILD_DIR} ] +then + rm -rf ${DAILY_BUILD_DIR} + mkdir -p ${DAILY_BUILD_DIR} +fi + +# +# Start with a fresh repo. +# +cd ${DAILY_BUILD_DIR} +rm -rf ubuntu-${KNAME} +git clone ${KERNEL_GIT_REPO} + +# +# Remember that the success of prepare-ppa depends on +# this user account having an un-passworded GPG key. +# Otherwise it requires user intervention, e.g., a +# user must enter the GPG key password. +# +rm -f *.changes +(cd ubuntu-${KNAME}; debian/scripts/misc/prepare-ppa-source) + +find . -maxdepth 1 -type f -name "*.changes" | while read f +do + echo dput my-ppa $f +done + --- linux-2.6.28.orig/debian/scripts/misc/insert-changes.pl +++ linux-2.6.28/debian/scripts/misc/insert-changes.pl @@ -0,0 +1,30 @@ +#!/usr/bin/perl -w + +system("make -s -f debian/rules printchanges > debian/changes"); + +open(CHANGELOG, "< debian/changelog") or die "Cannot open changelog"; +open(CHANGES, "< debian/changes") or die "Cannot open new changes"; +open(NEW, "> debian/changelog.new") or die "Cannot open new changelog"; + +$printed = 0; + +while () { + if (/^ CHANGELOG: /) { + next if $printed; + + while () { + print NEW; + } + + $printed = 1; + } else { + print NEW; + } +} + +close(NEW); +close(CHANGES); +close(CHANGELOG); + +rename("debian/changelog.new", "debian/changelog"); +unlink("debian/changes"); --- linux-2.6.28.orig/debian/scripts/misc/getabis +++ linux-2.6.28/debian/scripts/misc/getabis @@ -0,0 +1,85 @@ +#!/bin/bash + +if [ "$#" != "2" ]; then + echo "Usage: $0 " 1>&2 + exit 1 +fi + +ver=$1 +revision=$2 +abi=$(echo $revision | awk -F. '{print $1}') + +verabi=$ver-$abi +verfull=$ver-$revision + +repo="http://archive.ubuntu.com/ubuntu/pool/main/l" +repo_ports="http://ports.ubuntu.com/ubuntu-ports/pool/main/l" +repo_uni="http://archive.ubuntu.com/ubuntu/pool/universe/l" +repo_ports_uni="http://ports.ubuntu.com/ubuntu-ports/pool/universe/l" + +WGET="wget --quiet -c" + +abidir="`pwd`/debian/abi/$verfull" +tmpdir="`pwd`/abi-tmp-$verfull" +origdir="`pwd`" + +test -d $tmpdir || mkdir $tmpdir + +getall() { + arch=$1 + shift + + mkdir -p $abidir/$arch + + for sub in $@; do + if [ -f $abidir/$arch/$sub ]; then + echo "Exists: $sub" + continue + fi + echo -n "Fetching $sub..." + filename=linux-image-${verabi}-${sub}_${verfull}_${arch}.deb + cd $tmpdir + if ! [ -f $filename ]; then + $WGET $repo/linux/$filename + fi + if ! [ -f $filename ]; then + $WGET $repo_ports/linux/$filename + fi + if ! [ -f $filename ]; then + $WGET $repo_uni/linux/$filename + fi + if [ "$?" = "0" ]; then + echo -n "extracting..." + dpkg-deb --extract $filename tmp + if [ -f tmp/boot/abi-* ]; then + mv tmp/boot/abi-* $abidir/$arch/$sub + else + echo -n "NO ABI FILE..." + fi + (cd tmp; find lib/modules/$verabi-$sub/kernel -name '*.ko') | \ + sed -e 's/.*\/\([^\/]*\)\.ko/\1/' | sort > \ + $abidir/$arch/$sub.modules + rm -rf tmp $filename + echo "done." + else + echo "FAILED." + fi + cd $origdir + done +} + +# MAIN + +# Setup abi directory +mkdir -p $abidir +echo $abi > $abidir/abiname + +# NOTE: The flavours are hardcoded, because they may have changed from the +# current build. + +getall lpia lpia +getall amd64 generic server +getall i386 generic server +getall armel iop32x ixp4xx versatile imx51 + +rmdir $tmpdir --- linux-2.6.28.orig/debian/scripts/misc/retag +++ linux-2.6.28/debian/scripts/misc/retag @@ -0,0 +1,34 @@ +#!/usr/bin/perl -w + +open(TAGS, "git tag -l |") or die "Could not get list of tags"; +@tags = ; +close(TAGS); + +open(LOGS, "git log --pretty=short |") or die "ERROR: Calling git log"; +my $commit = ""; + +while () { + my $origtag; + + if (m|^commit (.*)$|) { + $commit = $1; + next; + } + + m|\s*UBUNTU: (Ubuntu-2\.6\..*)| or next; + + $tag = $1; + + ($origtag) = grep(/^$tag.orig$/, @tags); + + if (!defined($origtag)) { + print "I: Adding original tag for $tag\n"; + system("git tag -m $tag $tag.orig $tag"); + } + + print "I: Tagging $tag => $commit\n"; + + system("git tag -f -m $tag $tag $commit"); +} + +close(LOGS); --- linux-2.6.28.orig/debian/config/i386/config.generic +++ linux-2.6.28/debian/config/i386/config.generic @@ -0,0 +1,32 @@ +# +# Config options for config.generic automatically generated by splitconfig.pl +# +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set +CONFIG_DCA=m +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_DMADEVICES=y +# CONFIG_DMATEST is not set +CONFIG_DMA_ENGINE=y +CONFIG_HIGHMEM4G=y +# CONFIG_HIGHMEM64G is not set +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +CONFIG_IGB_DCA=y +CONFIG_INTEL_IOATDMA=m +CONFIG_IXGBE_DCA=y +# CONFIG_LGUEST is not set +# CONFIG_LGUEST_GUEST is not set +CONFIG_M586=y +# CONFIG_M686 is not set +CONFIG_MYRI10GE_DCA=y +CONFIG_NET_DMA=y +# CONFIG_PHYS_ADDR_T_64BIT is not set +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_RESOURCES_64BIT is not set +CONFIG_X86_ALIGNMENT_16=y +CONFIG_X86_E_POWERSAVER=m +CONFIG_X86_F00F_BUG=y --- linux-2.6.28.orig/debian/config/i386/config.server +++ linux-2.6.28/debian/config/i386/config.server @@ -0,0 +1,39 @@ +# +# Config options for config.server automatically generated by splitconfig.pl +# +CONFIG_ARCH_PHYS_ADDR_T_64BIT=y +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_DEADLINE=y +CONFIG_DEFAULT_IOSCHED="deadline" +# CONFIG_HIGHMEM4G is not set +CONFIG_HIGHMEM64G=y +CONFIG_HVC_IRQ=y +CONFIG_HVC_XEN=y +CONFIG_HZ=100 +CONFIG_HZ_100=y +# CONFIG_HZ_250 is not set +CONFIG_I2O_EXT_ADAPTEC_DMA64=y +# CONFIG_M586 is not set +CONFIG_M686=y +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_RESOURCES_64BIT=y +CONFIG_X86_CMOV=y +CONFIG_X86_CMPXCHG64=y +CONFIG_X86_DEBUGCTLMSR=y +# CONFIG_X86_DS is not set +# CONFIG_X86_E_POWERSAVER is not set +CONFIG_X86_PAE=y +CONFIG_X86_TSC=y +CONFIG_X86_USE_PPRO_CHECKSUM=y +CONFIG_XEN=y +CONFIG_XEN_BALLOON=y +CONFIG_XEN_BLKDEV_FRONTEND=m +# CONFIG_XEN_DEBUG_FS is not set +CONFIG_XEN_FBDEV_FRONTEND=m +CONFIG_XEN_KBDDEV_FRONTEND=m +CONFIG_XEN_MAX_DOMAIN_MEMORY=8 +CONFIG_XEN_NETDEV_FRONTEND=m +CONFIG_XEN_SAVE_RESTORE=y +CONFIG_XEN_SCRUB_PAGES=y --- linux-2.6.28.orig/debian/config/i386/config +++ linux-2.6.28/debian/config/i386/config @@ -0,0 +1,3933 @@ +# +# Common config options automatically generated by splitconfig.pl +# +CONFIG_3C359=m +CONFIG_3C515=m +# CONFIG_4KSTACKS is not set +CONFIG_60XX_WDT=m +# CONFIG_64BIT is not set +CONFIG_6PACK=m +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_8129=y +CONFIG_8139TOO_PIO=y +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_9P_FS=m +CONFIG_ABYSS=m +CONFIG_AC3200=m +CONFIG_AC97_BUS=m +# CONFIG_ACCESSIBILITY is not set +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_ACER_WMI=m +CONFIG_ACORN_PARTITION=y +# CONFIG_ACORN_PARTITION_ADFS is not set +# CONFIG_ACORN_PARTITION_CUMANA is not set +# CONFIG_ACORN_PARTITION_EESOX is not set +CONFIG_ACORN_PARTITION_ICS=y +# CONFIG_ACORN_PARTITION_POWERTEC is not set +CONFIG_ACORN_PARTITION_RISCIX=y +CONFIG_ACPI=y +CONFIG_ACPI_AC=y +# CONFIG_ACPI_ASUS is not set +CONFIG_ACPI_BATTERY=y +CONFIG_ACPI_BLACKLIST_YEAR=2000 +CONFIG_ACPI_BUTTON=y +CONFIG_ACPI_CONTAINER=y +# CONFIG_ACPI_CUSTOM_DSDT is not set +CONFIG_ACPI_CUSTOM_DSDT_FILE="" +CONFIG_ACPI_CUSTOM_DSDT_INITRD=y +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_DOCK=y +CONFIG_ACPI_FAN=y +CONFIG_ACPI_HOTPLUG_CPU=y +CONFIG_ACPI_PCI_SLOT=y +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_PROCFS=y +CONFIG_ACPI_PROCFS_POWER=y +CONFIG_ACPI_PROC_EVENT=y +CONFIG_ACPI_SBS=y +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_SYSFS_POWER=y +CONFIG_ACPI_SYSTEM=y +CONFIG_ACPI_THERMAL=y +CONFIG_ACPI_TOSHIBA=m +CONFIG_ACPI_VIDEO=m +CONFIG_ACPI_WMI=y +CONFIG_ACQUIRE_WDT=m +CONFIG_ACT200L_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_ADAPTEC_STARFIRE=m +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_ADM8211=m +CONFIG_ADVANTECH_WDT=m +CONFIG_AFFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_AFS_FS=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_AGP=m +CONFIG_AGP_ALI=m +CONFIG_AGP_AMD=m +CONFIG_AGP_AMD64=m +CONFIG_AGP_ATI=m +CONFIG_AGP_EFFICEON=m +CONFIG_AGP_INTEL=m +CONFIG_AGP_NVIDIA=m +CONFIG_AGP_SIS=m +CONFIG_AGP_SWORKS=m +CONFIG_AGP_VIA=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +CONFIG_AIC79XX_DEBUG_ENABLE=y +CONFIG_AIC79XX_DEBUG_MASK=0 +CONFIG_AIC79XX_REG_PRETTY_PRINT=y +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 +CONFIG_AIC7XXX_DEBUG_ENABLE=y +CONFIG_AIC7XXX_DEBUG_MASK=0 +CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_AIO=y +CONFIG_AIRO=m +CONFIG_AIRO_CS=m +CONFIG_ALIM1535_WDT=m +CONFIG_ALIM7101_WDT=m +CONFIG_ALI_FIR=m +CONFIG_AMD8111_ETH=m +CONFIG_AMIGA_PARTITION=y +CONFIG_ANON_INODES=y +CONFIG_APM=m +# CONFIG_APM_ALLOW_INTS is not set +# CONFIG_APM_CPU_IDLE is not set +# CONFIG_APM_DISPLAY_BLANK is not set +# CONFIG_APM_DO_ENABLE is not set +# CONFIG_APM_IGNORE_USER_SUSPEND is not set +# CONFIG_APM_REAL_MODE_POWER_OFF is not set +CONFIG_APPLICOM=m +CONFIG_APRICOT=m +CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig" +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_ARCH_HAS_CPU_RELAX=y +CONFIG_ARCH_HAS_DEFAULT_IDLE=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUPPORTS_MSI=y +CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_ARCNET=m +CONFIG_ARCNET_1051=m +CONFIG_ARCNET_1201=m +CONFIG_ARCNET_CAP=m +CONFIG_ARCNET_COM20020=m +CONFIG_ARCNET_COM20020_CS=m +CONFIG_ARCNET_COM20020_ISA=m +CONFIG_ARCNET_COM20020_PCI=m +CONFIG_ARCNET_COM90xx=m +CONFIG_ARCNET_COM90xxIO=m +CONFIG_ARCNET_RAW=m +CONFIG_ARCNET_RIM_I=m +CONFIG_ARLAN=m +# CONFIG_ARPD is not set +CONFIG_ASK_IP_FIB_HASH=y +CONFIG_ASUS_LAPTOP=m +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_AT1700=m +CONFIG_AT24=m +CONFIG_ATA=y +CONFIG_ATALK=m +CONFIG_ATARI_PARTITION=y +CONFIG_ATA_ACPI=y +CONFIG_ATA_GENERIC=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_OVER_ETH=m +CONFIG_ATA_PIIX=y +CONFIG_ATA_SFF=y +CONFIG_ATH5K=m +# CONFIG_ATH5K_DEBUG is not set +CONFIG_ATH9K=m +CONFIG_ATL1=m +CONFIG_ATL1E=m +CONFIG_ATL2=m +CONFIG_ATM=y +CONFIG_ATMEL=m +CONFIG_ATM_AMBASSADOR=m +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_ATM_CLIP=y +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +CONFIG_ATM_ENI=m +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +CONFIG_ATM_FIRESTREAM=m +CONFIG_ATM_FORE200E=m +CONFIG_ATM_FORE200E_DEBUG=0 +CONFIG_ATM_FORE200E_TX_RETRY=16 +# CONFIG_ATM_FORE200E_USE_TASKLET is not set +CONFIG_ATM_HE=m +CONFIG_ATM_HE_USE_SUNI=y +CONFIG_ATM_HORIZON=m +# CONFIG_ATM_HORIZON_DEBUG is not set +CONFIG_ATM_IA=m +# CONFIG_ATM_IA_DEBUG is not set +CONFIG_ATM_IDT77252=m +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +CONFIG_ATM_IDT77252_USE_SUNI=y +CONFIG_ATM_LANAI=m +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_NICSTAR=m +# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set +# CONFIG_ATM_NICSTAR_USE_SUNI is not set +CONFIG_ATM_TCP=m +CONFIG_ATM_ZATM=m +# CONFIG_ATM_ZATM_DEBUG is not set +CONFIG_ATP=m +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y +# CONFIG_AUDIT_ARCH is not set +CONFIG_AUDIT_GENERIC=y +CONFIG_AUDIT_TREE=y +CONFIG_AUFS=m +# CONFIG_AUFS_BRANCH_MAX_1023 is not set +CONFIG_AUFS_BRANCH_MAX_127=y +# CONFIG_AUFS_BRANCH_MAX_32767 is not set +# CONFIG_AUFS_BRANCH_MAX_511 is not set +CONFIG_AUFS_BR_NFS=y +CONFIG_AUFS_BR_XFS=y +# CONFIG_AUFS_COMPAT is not set +# CONFIG_AUFS_DEBUG is not set +CONFIG_AUFS_DENY_WRITE_ACCESS_PATCH=y +# CONFIG_AUFS_DLGT is not set +CONFIG_AUFS_EXPORT=y +# CONFIG_AUFS_FSYNC_SUPER_PATCH is not set +CONFIG_AUFS_HINOTIFY=y +CONFIG_AUFS_HIN_OR_DLGT=y +CONFIG_AUFS_HIN_OR_FUSE=y +CONFIG_AUFS_LHASH_PATCH=y +CONFIG_AUFS_PUT_FILP_PATCH=y +# CONFIG_AUFS_ROBR is not set +CONFIG_AUFS_RR_SQUASHFS=y +CONFIG_AUFS_SEC_PERM_PATCH=y +CONFIG_AUFS_SHWH=y +CONFIG_AUFS_SPLICE_PATCH=y +CONFIG_AUFS_STAT=y +# CONFIG_AUFS_UNIONFS22_PATCH is not set +# CONFIG_AUFS_UNIONFS23_PATCH is not set +# CONFIG_AUFS_WORKAROUND_FUSE is not set +CONFIG_AUTOFS4_FS=m +CONFIG_AUTOFS_FS=m +CONFIG_AUXDISPLAY=y +CONFIG_AVERATEC_5100P=m +CONFIG_AX25=m +CONFIG_AX25_DAMA_SLAVE=y +CONFIG_B43=m +CONFIG_B43LEGACY=m +CONFIG_B43LEGACY_DEBUG=y +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +CONFIG_B43LEGACY_LEDS=y +CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y +CONFIG_B43LEGACY_PCI_AUTOSELECT=y +CONFIG_B43LEGACY_PIO=y +# CONFIG_B43LEGACY_PIO_MODE is not set +CONFIG_B43LEGACY_RFKILL=y +# CONFIG_B43_DEBUG is not set +CONFIG_B43_LEDS=y +CONFIG_B43_PCICORE_AUTOSELECT=y +CONFIG_B43_PCI_AUTOSELECT=y +# CONFIG_B43_PCMCIA is not set +CONFIG_B43_RFKILL=y +CONFIG_B44=m +CONFIG_B44_PCI=y +CONFIG_B44_PCICORE_AUTOSELECT=y +CONFIG_B44_PCI_AUTOSELECT=y +CONFIG_BACKLIGHT_CARILLO_RANCH=m +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_CORGI=m +CONFIG_BACKLIGHT_DA903X=m +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_MBP_NVIDIA=m +CONFIG_BACKLIGHT_PROGEAR=m +CONFIG_BACKLIGHT_SAHARA=m +# CONFIG_BACKTRACE_SELF_TEST is not set +CONFIG_BASE_FULL=y +CONFIG_BASE_SMALL=0 +CONFIG_BATTERY_BQ27x00=m +CONFIG_BATTERY_DS2760=m +CONFIG_BATTERY_OLPC=m +CONFIG_BAYCOM_EPP=m +CONFIG_BAYCOM_PAR=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +# CONFIG_BEFS_DEBUG is not set +CONFIG_BEFS_FS=m +CONFIG_BFS_FS=m +CONFIG_BINFMT_AOUT=m +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_BITREVERSE=y +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_DEV=y +CONFIG_BLK_DEV_3W_XXXX_RAID=m +# CONFIG_BLK_DEV_BSG is not set +CONFIG_BLK_DEV_COMPCACHE=m +# CONFIG_BLK_DEV_COMPCACHE_DEBUG is not set +# CONFIG_BLK_DEV_COMPCACHE_STATS is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_DM=y +CONFIG_BLK_DEV_DM_BBR=m +CONFIG_BLK_DEV_DRBD=m +CONFIG_BLK_DEV_FD=m +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_INTEGRITY=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_MD=y +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_BLK_DEV_SX8=m +CONFIG_BLK_DEV_UB=m +CONFIG_BLK_DEV_UMEM=m +# CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_DEV_XIP is not set +CONFIG_BLOCK=y +CONFIG_BNX2=m +CONFIG_BNX2X=m +CONFIG_BONDING=m +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BOUNCE=y +CONFIG_BPQETHER=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_NFLOG=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_NETFILTER=y +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BROADCOM_PHY=m +CONFIG_BSD_DISKLABEL=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_BT=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_CMTP=m +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBTSDIO=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HIDP=m +CONFIG_BT_L2CAP=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_SCO=y +CONFIG_BUG=y +CONFIG_C101=m +CONFIG_C2PORT=m +CONFIG_C2PORT_DURAMAR_2150=m +# CONFIG_CAN is not set +CONFIG_CAN_PM_TRACE=y +CONFIG_CAPI_AVM=y +CONFIG_CAPI_EICON=y +CONFIG_CAPI_TRACE=y +CONFIG_CARDBUS=y +CONFIG_CARDMAN_4000=m +CONFIG_CARDMAN_4040=m +# CONFIG_CARMINE_DRAM_CUSTOM is not set +CONFIG_CASSINI=m +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_CDROM_PKTCDVD=y +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_CFAG12864B=m +CONFIG_CFAG12864B_RATE=20 +CONFIG_CFG80211=m +CONFIG_CGROUPS=y +CONFIG_CGROUP_CPUACCT=y +# CONFIG_CGROUP_DEBUG is not set +# CONFIG_CGROUP_DEVICE is not set +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_MEM_RES_CTLR=y +CONFIG_CGROUP_NS=y +CONFIG_CGROUP_SCHED=y +CONFIG_CHECK_SIGNATURE=y +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T3=m +CONFIG_CHR_DEV_OSST=m +CONFIG_CHR_DEV_SCH=m +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_ST=m +CONFIG_CICADA_PHY=m +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG2 is not set +CONFIG_CIFS_DFS_UPCALL=y +CONFIG_CIFS_EXPERIMENTAL=y +CONFIG_CIFS_POSIX=y +# CONFIG_CIFS_STATS is not set +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_WEAK_PW_HASH=y +CONFIG_CIFS_XATTR=y +CONFIG_CISS_SCSI_TAPE=y +CONFIG_CLASSIC_RCU=y +CONFIG_CLOCKSOURCE_WATCHDOG=y +CONFIG_CLS_U32_MARK=y +# CONFIG_CLS_U32_PERF is not set +# CONFIG_CMDLINE_BOOL is not set +CONFIG_CODA_FS=m +CONFIG_COMPAL_LAPTOP=m +# CONFIG_COMPAT_BRK is not set +# CONFIG_COMPAT_VDSO is not set +CONFIG_COMPUTONE=m +CONFIG_CONFIGFS_FS=m +CONFIG_CONNECTOR=y +CONFIG_CONSOLE_POLL=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_CONTEXT_SWITCH_TRACER=y +# CONFIG_COPS is not set +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_COSA=m +# CONFIG_CPA_DEBUG is not set +CONFIG_CPU5_WDT=m +CONFIG_CPUSETS=y +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_DEBUG is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y +CONFIG_CPU_SUP_AMD=y +CONFIG_CPU_SUP_CENTAUR_32=y +CONFIG_CPU_SUP_CYRIX_32=y +CONFIG_CPU_SUP_INTEL=y +CONFIG_CPU_SUP_TRANSMETA_32=y +CONFIG_CPU_SUP_UMC_32=y +CONFIG_CRAMFS=y +CONFIG_CRASH_DUMP=y +CONFIG_CRC16=y +CONFIG_CRC32=y +CONFIG_CRC7=m +CONFIG_CRC_CCITT=m +CONFIG_CRC_ITU_T=m +CONFIG_CRC_T10DIF=y +CONFIG_CRYPTO=y +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_AES_586=m +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_CRC32C_INTEL=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_DEV_GEODE=m +CONFIG_CRYPTO_DEV_HIFN_795X=m +CONFIG_CRYPTO_DEV_HIFN_795X_RNG=y +CONFIG_CRYPTO_DEV_PADLOCK=y +CONFIG_CRYPTO_DEV_PADLOCK_AES=m +CONFIG_CRYPTO_DEV_PADLOCK_SHA=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_FIPS=y +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_LZO=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SALSA20_586=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SEQIV=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_586=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_XTS=m +CONFIG_CS5535_GPIO=m +CONFIG_CS89x0=m +CONFIG_CYCLADES=m +CONFIG_CYCLADES_SYNC=m +CONFIG_CYCLOMX_X25=y +# CONFIG_CYZ_INTR is not set +# CONFIG_DAB is not set +CONFIG_DAVICOM_PHY=m +CONFIG_DCDBAS=m +CONFIG_DE2104X=m +CONFIG_DE4X5=m +CONFIG_DE600=m +CONFIG_DE620=m +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_BOOT_PARAMS is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_DRIVER is not set +CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_GPIO is not set +# CONFIG_DEBUG_HIGHMEM is not set +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_NX_TEST is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +CONFIG_DEBUG_RODATA=y +# CONFIG_DEBUG_RODATA_TEST is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_VIRTUAL is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +CONFIG_DECNET=m +CONFIG_DECNET_NF_GRABULATOR=m +# CONFIG_DECNET_ROUTER is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_BIC is not set +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_HTCP is not set +CONFIG_DEFAULT_IO_DELAY_TYPE=1 +# CONFIG_DEFAULT_NOOP is not set +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_WESTWOOD is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_DEFXX=m +# CONFIG_DEFXX_MMIO is not set +CONFIG_DELL_RBU=m +CONFIG_DEPCA=m +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_DEVKMEM is not set +CONFIG_DEVPORT=y +CONFIG_DEV_APPLETALK=m +CONFIG_DE_AOC=y +CONFIG_DIGIEPCA=m +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_DISPLAY_SUPPORT=m +# CONFIG_DL2K is not set +CONFIG_DLCI=m +CONFIG_DLCI_MAX=8 +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +CONFIG_DM9102=m +CONFIG_DMI=y +CONFIG_DMIID=y +CONFIG_DM_CRYPT=m +# CONFIG_DM_DEBUG is not set +# CONFIG_DM_DELAY is not set +CONFIG_DM_LOOP=m +CONFIG_DM_MIRROR=y +CONFIG_DM_MULTIPATH=y +CONFIG_DM_RAID45=m +CONFIG_DM_SNAPSHOT=y +CONFIG_DM_UEVENT=y +CONFIG_DM_ZERO=m +CONFIG_DNOTIFY=y +CONFIG_DONGLE=y +CONFIG_DOUBLEFAULT=y +CONFIG_DRM=m +CONFIG_DRM_I810=m +CONFIG_DRM_I830=m +CONFIG_DRM_I915=m +CONFIG_DRM_MGA=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_SAVAGE=m +CONFIG_DRM_SIS=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_VIA=m +CONFIG_DS1682=m +CONFIG_DSCC4=m +CONFIG_DSCC4_PCISYNC=y +CONFIG_DSCC4_PCI_RST=y +CONFIG_DTLK=m +CONFIG_DUMMY=m +CONFIG_DUMMY_CONSOLE=y +CONFIG_DVB_AF9013=m +CONFIG_DVB_AU8522=m +CONFIG_DVB_AV7110=m +# CONFIG_DVB_AV7110_FIRMWARE is not set +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_B2C2_FLEXCOP=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_BT8XX=m +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_CORE=m +CONFIG_DVB_BUDGET_PATCH=m +CONFIG_DVB_CAPTURE_DRIVERS=y +CONFIG_DVB_CORE=m +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +CONFIG_DVB_DM1105=m +CONFIG_DVB_DRX397XD=m +# CONFIG_DVB_DUMMY_FE is not set +# CONFIG_DVB_FE_CUSTOMISE is not set +CONFIG_DVB_ISL6405=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_L64781=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LGS8GL5=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_MT312=m +CONFIG_DVB_MT352=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_PLL=m +CONFIG_DVB_PLUTO2=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_S5H1411=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_SI21XX=m +CONFIG_DVB_SIANO_SMS1XXX=m +CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS=y +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_STB6000=m +CONFIG_DVB_STV0288=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_TDA10048=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_USB=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_CINERGY_T2=m +CONFIG_DVB_USB_CXUSB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_DIBUSB_MB=m +# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_DW2102=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_VES1820=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_ZL10353=m +# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +CONFIG_E100=m +CONFIG_E1000=m +CONFIG_E1000E=m +CONFIG_E2100=m +CONFIG_EARLY_PRINTK=y +# CONFIG_EARLY_PRINTK_DBGP is not set +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +CONFIG_ECRYPT_FS=y +CONFIG_EDAC=y +CONFIG_EDAC_AMD76X=m +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_E752X=m +CONFIG_EDAC_E7XXX=m +CONFIG_EDAC_I3000=m +CONFIG_EDAC_I5000=m +CONFIG_EDAC_I5100=m +CONFIG_EDAC_I82860=m +CONFIG_EDAC_I82875P=m +CONFIG_EDAC_I82975X=m +CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC_R82600=m +CONFIG_EDAC_X38=m +CONFIG_EDD=y +CONFIG_EDD_OFF=y +CONFIG_EEEPC_LAPTOP=m +CONFIG_EEPRO100=m +CONFIG_EEPROM_93CX6=m +CONFIG_EEXPRESS=m +CONFIG_EEXPRESS_PRO=m +CONFIG_EFI=y +CONFIG_EFI_PARTITION=y +CONFIG_EFI_VARS=y +CONFIG_EFS_FS=m +CONFIG_EISA=y +CONFIG_EISA_NAMES=y +CONFIG_EISA_PCI_EISA=y +CONFIG_EISA_VIRTUAL_ROOT=y +CONFIG_EISA_VLB_PRIMING=y +CONFIG_EL1=m +CONFIG_EL16=m +CONFIG_EL2=m +CONFIG_EL3=m +CONFIG_ELF_CORE=y +CONFIG_ELMC=m +CONFIG_ELMC_II=m +CONFIG_ELPLUS=m +# CONFIG_EMBEDDED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENC28J60 is not set +CONFIG_ENCLOSURE_SERVICES=m +CONFIG_ENIC=m +CONFIG_EPIC100=m +CONFIG_EPOLL=y +CONFIG_EQUALIZER=m +CONFIG_ES3210=m +CONFIG_ESI_DONGLE=m +CONFIG_ESPSERIAL=m +CONFIG_ETH16I=m +CONFIG_EUROTECH_WDT=m +CONFIG_EVENTFD=y +CONFIG_EWRK3=m +CONFIG_EXPERIMENTAL=y +CONFIG_EXPORTFS=m +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT4DEV_COMPAT is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_EXT4_FS_XATTR=y +CONFIG_EXTRA_FIRMWARE="" +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FARSYNC=m +CONFIG_FAST_CMPXCHG_LOCAL=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_FAT_FS=m +# CONFIG_FAULT_INJECTION is not set +CONFIG_FB=y +CONFIG_FB_3DFX=m +# CONFIG_FB_3DFX_ACCEL is not set +CONFIG_FB_ARC=m +CONFIG_FB_ARK=m +CONFIG_FB_ASILIANT=y +CONFIG_FB_ATY=m +CONFIG_FB_ATY128=m +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY_BACKLIGHT=y +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_BOOT_VESA_SUPPORT=y +CONFIG_FB_CARILLO_RANCH=m +CONFIG_FB_CARMINE=m +CONFIG_FB_CARMINE_DRAM_EVAL=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +CONFIG_FB_CIRRUS=m +CONFIG_FB_CYBER2000=m +CONFIG_FB_CYBLA=m +CONFIG_FB_DDC=m +CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_EFI=y +# CONFIG_FB_FOREIGN_ENDIAN is not set +CONFIG_FB_GEODE=y +CONFIG_FB_GEODE_GX=m +CONFIG_FB_GEODE_GX1=m +CONFIG_FB_GEODE_LX=m +CONFIG_FB_HECUBA=m +CONFIG_FB_HGA=m +# CONFIG_FB_HGA_ACCEL is not set +CONFIG_FB_I810=m +# CONFIG_FB_I810_GTF is not set +CONFIG_FB_IMSTT=y +CONFIG_FB_INTEL=m +# CONFIG_FB_INTEL_DEBUG is not set +CONFIG_FB_INTEL_I2C=y +CONFIG_FB_KYRO=m +CONFIG_FB_LE80578=m +# CONFIG_FB_MACMODES is not set +CONFIG_FB_MATROX=m +CONFIG_FB_MATROX_G=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MULTIHEAD=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MB862XX=m +CONFIG_FB_MB862XX_PCI_GDC=y +CONFIG_FB_METRONOME=m +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_N411=m +CONFIG_FB_NEOMAGIC=m +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_BACKLIGHT=y +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_I2C=y +CONFIG_FB_PM2=m +CONFIG_FB_PM2_FIFO_DISCONNECT=y +CONFIG_FB_PM3=m +CONFIG_FB_RADEON=m +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RIVA=m +CONFIG_FB_RIVA_BACKLIGHT=y +# CONFIG_FB_RIVA_DEBUG is not set +CONFIG_FB_RIVA_I2C=y +CONFIG_FB_S1D13XXX=m +CONFIG_FB_S3=m +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_ACCEL=y +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SIS=m +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +CONFIG_FB_SM501=m +CONFIG_FB_SVGALIB=m +CONFIG_FB_SYS_COPYAREA=m +CONFIG_FB_SYS_FILLRECT=m +CONFIG_FB_SYS_FOPS=m +CONFIG_FB_SYS_IMAGEBLIT=m +CONFIG_FB_TILEBLITTING=y +CONFIG_FB_TRIDENT=m +# CONFIG_FB_TRIDENT_ACCEL is not set +CONFIG_FB_UVESA=m +CONFIG_FB_VESA=m +CONFIG_FB_VGA16=m +CONFIG_FB_VIA=m +# CONFIG_FB_VIRTUAL is not set +CONFIG_FB_VOODOO1=m +CONFIG_FB_VT8623=m +CONFIG_FDDI=y +CONFIG_FEALNX=m +CONFIG_FIB_RULES=y +CONFIG_FILE_LOCKING=y +CONFIG_FIREWIRE=m +CONFIG_FIREWIRE_OHCI=m +CONFIG_FIREWIRE_OHCI_DEBUG=y +# CONFIG_FIREWIRE_OHCI_REMOTE_DMA is not set +CONFIG_FIREWIRE_SBP2=m +CONFIG_FIRMWARE_EDID=y +# CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_FIRMWARE_MEMMAP=y +CONFIG_FIXED_PHY=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_FLATMEM=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x16=y +CONFIG_FONT_8x8=y +CONFIG_FORCEDETH=m +# CONFIG_FORCEDETH_NAPI is not set +CONFIG_FRAMEBUFFER_CONSOLE=m +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FRAME_POINTER=y +CONFIG_FRAME_WARN=1024 +CONFIG_FREEZER=y +CONFIG_FSAM7400=m +CONFIG_FS_MBCACHE=y +CONFIG_FS_POSIX_ACL=y +CONFIG_FS_UNIONFS=m +CONFIG_FTL=m +# CONFIG_FTRACE_STARTUP_TEST is not set +CONFIG_FUJITSU_LAPTOP=m +# CONFIG_FUJITSU_LAPTOP_DEBUG is not set +# CONFIG_FUNCTION_TRACER is not set +CONFIG_FUSE_FS=y +CONFIG_FUSION=y +CONFIG_FUSION_CTL=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_LAN=m +CONFIG_FUSION_LOGGING=y +CONFIG_FUSION_MAX_SGE=128 +CONFIG_FUSION_SAS=m +CONFIG_FUSION_SPI=m +CONFIG_FUTEX=y +CONFIG_FW_LOADER=y +CONFIG_GACT_PROB=y +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GARP=m +CONFIG_GENERIC_ACL=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_CMOS_UPDATE=y +# CONFIG_GENERIC_CPU is not set +CONFIG_GENERIC_FIND_FIRST_BIT=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_GENERIC_TIME=y +# CONFIG_GENERIC_TIME_VSYSCALL is not set +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=m +CONFIG_GFS_FS=m +CONFIG_GIGASET_BASE=m +# CONFIG_GIGASET_DEBUG is not set +CONFIG_GIGASET_M101=m +CONFIG_GIGASET_M105=m +# CONFIG_GIGASET_UNDOCREQ is not set +CONFIG_GIRBIL_DONGLE=m +CONFIG_GPIOLIB=y +CONFIG_GPIO_MAX7301=m +CONFIG_GPIO_MAX732X=m +CONFIG_GPIO_MCP23S08=m +CONFIG_GPIO_PCA953X=m +CONFIG_GPIO_PCF857X=m +CONFIG_GPIO_SYSFS=y +CONFIG_GROUP_SCHED=y +CONFIG_HAMACHI=m +CONFIG_HAMRADIO=y +CONFIG_HANGCHECK_TIMER=m +CONFIG_HAPPYMEAL=m +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAVE_AOUT=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_ATOMIC_IOMAP=y +# CONFIG_HAVE_CPUMASK_OF_CPU_MAP is not set +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_HAVE_IDE=y +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_KVM=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_HAVE_MTD_OTP=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_SETUP_PER_CPU_AREA=y +CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y +CONFIG_HDLC=m +CONFIG_HDLC_CISCO=m +CONFIG_HDLC_FR=m +CONFIG_HDLC_PPP=m +CONFIG_HDLC_RAW=m +CONFIG_HDLC_RAW_ETH=m +CONFIG_HDLC_X25=m +# CONFIG_HEADERS_CHECK is not set +CONFIG_HECI=m +CONFIG_HERMES=m +CONFIG_HFSPLUS_FS=m +CONFIG_HFS_FS=m +CONFIG_HIBERNATION=y +CONFIG_HID=y +CONFIG_HIDRAW=y +CONFIG_HID_A4TECH=m +CONFIG_HID_APPLE=m +CONFIG_HID_BELKIN=m +CONFIG_HID_BRIGHT=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +# CONFIG_HID_COMPAT is not set +CONFIG_HID_CYPRESS=m +# CONFIG_HID_DEBUG is not set +CONFIG_HID_DELL=m +CONFIG_HID_EZKEY=m +CONFIG_HID_GYRATION=m +CONFIG_HID_LOGITECH=m +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_PANTHERLORD=m +CONFIG_HID_PETALYNX=m +CONFIG_HID_PID=y +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_HID_SUNPLUS=m +CONFIG_HID_SUPPORT=y +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_HIPPI=y +CONFIG_HISAX_16_0=y +CONFIG_HISAX_16_3=y +CONFIG_HISAX_1TR6=y +CONFIG_HISAX_ASUSCOM=y +CONFIG_HISAX_AVM_A1=y +CONFIG_HISAX_AVM_A1_CS=m +CONFIG_HISAX_AVM_A1_PCMCIA=y +CONFIG_HISAX_BKM_A4T=y +# CONFIG_HISAX_DEBUG is not set +CONFIG_HISAX_DIEHLDIVA=y +CONFIG_HISAX_ELSA=y +CONFIG_HISAX_ELSA_CS=m +CONFIG_HISAX_ENTERNOW_PCI=y +CONFIG_HISAX_EURO=y +CONFIG_HISAX_FRITZPCI=y +CONFIG_HISAX_FRITZ_PCIPNP=m +CONFIG_HISAX_GAZEL=y +CONFIG_HISAX_HDLC=y +CONFIG_HISAX_HFC4S8S=m +CONFIG_HISAX_HFCS=y +CONFIG_HISAX_HFCUSB=m +CONFIG_HISAX_HFC_PCI=y +CONFIG_HISAX_HFC_SX=y +CONFIG_HISAX_HSTSAPHIR=y +CONFIG_HISAX_ISURF=y +CONFIG_HISAX_IX1MICROR2=y +CONFIG_HISAX_MAX_CARDS=8 +CONFIG_HISAX_MIC=y +CONFIG_HISAX_NETJET=y +CONFIG_HISAX_NETJET_U=y +CONFIG_HISAX_NI1=y +CONFIG_HISAX_NICCY=y +# CONFIG_HISAX_NO_KEYPAD is not set +# CONFIG_HISAX_NO_LLC is not set +# CONFIG_HISAX_NO_SENDCOMPLETE is not set +CONFIG_HISAX_S0BOX=y +CONFIG_HISAX_SCT_QUADRO=y +CONFIG_HISAX_SEDLBAUER=y +CONFIG_HISAX_SEDLBAUER_CS=m +CONFIG_HISAX_SPORTSTER=y +CONFIG_HISAX_ST5481=m +CONFIG_HISAX_TELEINT=y +CONFIG_HISAX_TELESPCI=y +CONFIG_HISAX_TELES_CS=m +CONFIG_HISAX_W6692=y +CONFIG_HOSTAP=m +CONFIG_HOSTAP_CS=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_PLX=m +CONFIG_HOSTESS_SV11=m +CONFIG_HOTPLUG=y +CONFIG_HOTPLUG_CPU=y +CONFIG_HOTPLUG_PCI=y +CONFIG_HOTPLUG_PCI_ACPI=m +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +CONFIG_HOTPLUG_PCI_COMPAQ=m +CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM=y +CONFIG_HOTPLUG_PCI_CPCI=y +CONFIG_HOTPLUG_PCI_CPCI_GENERIC=m +CONFIG_HOTPLUG_PCI_CPCI_ZT5550=m +CONFIG_HOTPLUG_PCI_FAKE=m +CONFIG_HOTPLUG_PCI_IBM=m +CONFIG_HOTPLUG_PCI_PCIE=y +CONFIG_HOTPLUG_PCI_SHPC=m +CONFIG_HP100=m +CONFIG_HPET=y +CONFIG_HPET_EMULATE_RTC=y +CONFIG_HPET_MMAP=y +CONFIG_HPET_TIMER=y +CONFIG_HPFS_FS=m +CONFIG_HPLAN=m +CONFIG_HPLAN_PLUS=m +CONFIG_HP_ILO=m +# CONFIG_HP_WATCHDOG is not set +CONFIG_HP_WMI=m +CONFIG_HTC_PASIC3=m +CONFIG_HT_IRQ=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_HVC_DRIVER=y +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_HWMON_VID=m +CONFIG_HW_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_AMD=m +CONFIG_HW_RANDOM_GEODE=m +CONFIG_HW_RANDOM_INTEL=m +CONFIG_HW_RANDOM_VIA=m +CONFIG_HW_RANDOM_VIRTIO=m +CONFIG_HYSDN=m +CONFIG_HYSDN_CAPI=y +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_300 is not set +CONFIG_I2C=y +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCA=m +CONFIG_I2C_ALGOPCF=m +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_I2C_DEBUG_CORE is not set +CONFIG_I2C_GPIO=m +# CONFIG_I2C_HELPER_AUTO is not set +CONFIG_I2C_I801=m +CONFIG_I2C_ISCH=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_NFORCE2_S4985=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_PCA_ISA=m +CONFIG_I2C_PCA_PLATFORM=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_STUB=m +CONFIG_I2C_TAOS_EVM=m +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_BUS=m +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_PROC=m +CONFIG_I2O_SCSI=m +CONFIG_I6300ESB_WDT=m +CONFIG_I82092=m +CONFIG_I82365=m +CONFIG_I8K=m +CONFIG_IB700_WDT=m +CONFIG_IBMASR=m +CONFIG_IBMLANA=m +CONFIG_IBMLS=m +# CONFIG_IBMMCA_SCSI_DEV_RESET is not set +CONFIG_IBMMCA_SCSI_ORDER_STANDARD=y +CONFIG_IBMOL=m +CONFIG_IBMTR=m +CONFIG_IBM_ASM=m +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +CONFIG_ICPLUS_PHY=m +CONFIG_ICS932S401=m +# CONFIG_IDE is not set +CONFIG_IEEE1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y +CONFIG_IEEE1394_OHCI1394=m +CONFIG_IEEE1394_PCILYNX=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE80211=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_CRYPT_WEP=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IFB=m +CONFIG_IGB=m +# CONFIG_IGB_LRO is not set +# CONFIG_IKCONFIG is not set +CONFIG_INET=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET_AH=m +CONFIG_INET_DCCP_DIAG=m +CONFIG_INET_DIAG=y +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_LRO=m +CONFIG_INET_TCP_DIAG=y +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_AMSO1100=m +CONFIG_INFINIBAND_AMSO1100_DEBUG=y +CONFIG_INFINIBAND_CXGB3=m +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_IPOIB_DEBUG=y +# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set +CONFIG_INFINIBAND_ISER=m +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_MTHCA_DEBUG=y +# CONFIG_INFINIBAND_NES is not set +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INFTL=m +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_INPUT=y +CONFIG_INPUT_ACERHK=m +# CONFIG_INPUT_APANEL is not set +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_ATLAS_BTNS=m +CONFIG_INPUT_CM109=m +CONFIG_INPUT_EVBUG=m +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_INPUT_KEYBOARD=y +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_MOUSE=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_PCSPKR=m +CONFIG_INPUT_POLLDEV=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_TABLET=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_WISTRON_BTNS=m +CONFIG_INPUT_YEALINK=m +CONFIG_INTEL_MENLOW=m +# CONFIG_IOMMU_HELPER is not set +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_CFQ=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_NOOP=y +# CONFIG_IO_DELAY_0X80 is not set +CONFIG_IO_DELAY_0XED=y +# CONFIG_IO_DELAY_NONE is not set +CONFIG_IO_DELAY_TYPE_0X80=0 +CONFIG_IO_DELAY_TYPE_0XED=1 +CONFIG_IO_DELAY_TYPE_NONE=3 +CONFIG_IO_DELAY_TYPE_UDELAY=2 +# CONFIG_IO_DELAY_UDELAY is not set +CONFIG_IP1000=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_SECURITY=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IPC_NS=y +CONFIG_IPDDP=m +CONFIG_IPDDP_DECAP=y +CONFIG_IPDDP_ENCAP=y +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_POWEROFF=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPPP_FILTER=y +CONFIG_IPV6=y +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_MROUTE is not set +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_IPV6_SIT=m +# CONFIG_IPV6_SUBTREES is not set +CONFIG_IPV6_TUNNEL=m +CONFIG_IPW2100=m +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2100_MONITOR=y +CONFIG_IPW2200=m +# CONFIG_IPW2200_DEBUG is not set +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IPWIRELESS=m +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_DCCP=m +CONFIG_IP_DCCP_ACKVEC=y +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_IP_DCCP_TFRC_LIB=m +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_MROUTE=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_SECURITY=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_IP_PNP is not set +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_SCTP=m +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_IPV6=y +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_AH_ESP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_TAB_BITS=12 +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_WRR=m +CONFIG_IRCOMM=m +CONFIG_IRDA=m +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_DEBUG=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_ULTRA=y +CONFIG_IRLAN=m +CONFIG_IRNET=m +# CONFIG_IRQSOFF_TRACER is not set +CONFIG_IRTTY_SIR=m +CONFIG_ISA=y +CONFIG_ISAPNP=y +CONFIG_ISA_DMA_API=y +CONFIG_ISCSI_IBFT=m +CONFIG_ISCSI_IBFT_FIND=y +CONFIG_ISCSI_TCP=m +CONFIG_ISDN=y +CONFIG_ISDN_AUDIO=y +CONFIG_ISDN_CAPI=m +CONFIG_ISDN_CAPI_CAPI20=m +CONFIG_ISDN_CAPI_CAPIDRV=m +CONFIG_ISDN_CAPI_CAPIFS=m +CONFIG_ISDN_CAPI_CAPIFS_BOOL=y +CONFIG_ISDN_CAPI_MIDDLEWARE=y +CONFIG_ISDN_DIVAS=m +CONFIG_ISDN_DIVAS_BRIPCI=y +CONFIG_ISDN_DIVAS_DIVACAPI=m +CONFIG_ISDN_DIVAS_MAINT=m +CONFIG_ISDN_DIVAS_PRIPCI=y +CONFIG_ISDN_DIVAS_USERIDI=m +CONFIG_ISDN_DIVERSION=m +CONFIG_ISDN_DRV_ACT2000=m +CONFIG_ISDN_DRV_AVMB1_AVM_CS=m +CONFIG_ISDN_DRV_AVMB1_B1ISA=m +CONFIG_ISDN_DRV_AVMB1_B1PCI=m +CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m +CONFIG_ISDN_DRV_AVMB1_C4=m +CONFIG_ISDN_DRV_AVMB1_T1ISA=m +CONFIG_ISDN_DRV_AVMB1_T1PCI=m +CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y +CONFIG_ISDN_DRV_GIGASET=m +CONFIG_ISDN_DRV_HISAX=m +CONFIG_ISDN_DRV_ICN=m +CONFIG_ISDN_DRV_PCBIT=m +CONFIG_ISDN_DRV_SC=m +CONFIG_ISDN_I4L=m +CONFIG_ISDN_MPP=y +CONFIG_ISDN_PPP=y +CONFIG_ISDN_PPP_BSDCOMP=m +CONFIG_ISDN_PPP_VJ=y +CONFIG_ISDN_TTY_FAX=y +CONFIG_ISDN_X25=y +# CONFIG_ISI is not set +CONFIG_ISO9660_FS=m +CONFIG_ISTALLION=m +CONFIG_IT8712F_WDT=m +CONFIG_IT87_WDT=m +CONFIG_ITCO_VENDOR_SUPPORT=y +CONFIG_ITCO_WDT=m +CONFIG_IWL3945=m +# CONFIG_IWL3945_DEBUG is not set +CONFIG_IWL3945_LEDS=y +CONFIG_IWL3945_RFKILL=y +CONFIG_IWL3945_SPECTRUM_MEASUREMENT=y +CONFIG_IWL4965=y +CONFIG_IWL5000=y +CONFIG_IWLAGN=m +CONFIG_IWLAGN_LEDS=y +CONFIG_IWLAGN_SPECTRUM_MEASUREMENT=y +CONFIG_IWLCORE=m +CONFIG_IWLWIFI=m +# CONFIG_IWLWIFI_DEBUG is not set +CONFIG_IWLWIFI_LEDS=y +CONFIG_IWLWIFI_RFKILL=y +CONFIG_IXGB=m +CONFIG_IXGBE=m +CONFIG_JBD=y +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +# CONFIG_JBD_DEBUG is not set +CONFIG_JFFS2_CMODE_FAVOURLZO=y +# CONFIG_JFFS2_CMODE_NONE is not set +# CONFIG_JFFS2_CMODE_PRIORITY is not set +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_LZO=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_SUMMARY is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFS_DEBUG is not set +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +CONFIG_JFS_STATISTICS=y +CONFIG_JME=m +CONFIG_JOLIET=y +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_232=y +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_JOYSTICK_ZHENHUA=m +CONFIG_K8_NB=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_KARMA_PARTITION=y +CONFIG_KEXEC=y +CONFIG_KEXEC_JUMP=y +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_GPIO=m +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_KGDB=y +CONFIG_KGDB_SERIAL_CONSOLE=y +# CONFIG_KGDB_TESTS is not set +CONFIG_KINGSUN_DONGLE=m +CONFIG_KMOD=y +CONFIG_KPROBES=y +# CONFIG_KPROBES_SANITY_TEST is not set +CONFIG_KRETPROBES=y +CONFIG_KS0108=m +CONFIG_KS0108_DELAY=2 +CONFIG_KS0108_PORT=0x378 +CONFIG_KS959_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +CONFIG_KTIME_SCALAR=y +CONFIG_KVM=m +CONFIG_KVM_AMD=m +CONFIG_KVM_CLOCK=y +CONFIG_KVM_GUEST=y +CONFIG_KVM_INTEL=m +# CONFIG_KVM_TRACE is not set +CONFIG_LANCE=m +CONFIG_LANMEDIA=m +CONFIG_LAPB=m +CONFIG_LAPBETHER=m +CONFIG_LATENCYTOP=y +CONFIG_LBD=y +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_ILI9320=m +CONFIG_LCD_LTV350QV=m +CONFIG_LCD_PLATFORM=m +CONFIG_LCD_TDO24M=m +CONFIG_LCD_VGG2432A4=m +# CONFIG_LDM_DEBUG is not set +CONFIG_LDM_PARTITION=y +CONFIG_LEDS_CLASS=m +# CONFIG_LEDS_CLEVO_MAIL is not set +CONFIG_LEDS_DA903X=m +CONFIG_LEDS_GPIO=m +CONFIG_LEDS_HP_DISK=m +CONFIG_LEDS_NET48XX=m +CONFIG_LEDS_PCA9532=m +CONFIG_LEDS_PCA955X=m +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=m +CONFIG_LEDS_TRIGGER_DEFAULT_ON=m +CONFIG_LEDS_TRIGGER_HEARTBEAT=m +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_WRAP=m +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=0 +CONFIG_LIBCRC32C=m +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_CS=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_SDIO=m +CONFIG_LIBERTAS_THINFIRM=m +CONFIG_LIBERTAS_THINFIRM_USB=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIRC_ATIUSB=m +CONFIG_LIRC_BT829=m +CONFIG_LIRC_CMDIR=m +CONFIG_LIRC_DEV=m +CONFIG_LIRC_GPIO=m +CONFIG_LIRC_I2C=m +CONFIG_LIRC_IGORPLUGUSB=m +CONFIG_LIRC_IMON=m +CONFIG_LIRC_IT87=m +CONFIG_LIRC_MCEUSB=m +CONFIG_LIRC_MCEUSB2=m +# CONFIG_LIRC_PARALLEL is not set +CONFIG_LIRC_PVR150=m +CONFIG_LIRC_SASEM=m +CONFIG_LIRC_SERIAL=m +CONFIG_LIRC_SERIAL_IGOR=m +CONFIG_LIRC_SIR=m +CONFIG_LIRC_STREAMZAP=m +CONFIG_LIRC_TTUSBIR=m +CONFIG_LITELINK_DONGLE=m +# CONFIG_LKDTM is not set +CONFIG_LLC=y +CONFIG_LLC2=m +CONFIG_LMPCM_USB=m +CONFIG_LNE390=m +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_LOCKD=m +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_LOCKD_V4=y +CONFIG_LOCK_KERNEL=y +# CONFIG_LOCK_STAT is not set +CONFIG_LOGIRUMBLEPAD2_FF=y +CONFIG_LOGITECH_FF=y +# CONFIG_LOGO is not set +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_LP486E=m +# CONFIG_LP_CONSOLE is not set +CONFIG_LSF=y +CONFIG_LTPC=m +CONFIG_LXT_PHY=m +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +CONFIG_M25PXX_USE_FAST_READ=y +# CONFIG_M386 is not set +# CONFIG_M486 is not set +# CONFIG_M586MMX is not set +# CONFIG_M586TSC is not set +CONFIG_MA600_DONGLE=m +CONFIG_MAC80211=m +CONFIG_MAC80211_DEBUGFS=y +# CONFIG_MAC80211_DEBUG_MENU is not set +# CONFIG_MAC80211_HWSIM is not set +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_MESH=y +CONFIG_MAC80211_RC_DEFAULT="pid" +# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set +CONFIG_MAC80211_RC_DEFAULT_PID=y +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_PID=y +CONFIG_MACHZ_WDT=m +CONFIG_MACINTOSH_DRIVERS=y +CONFIG_MACVLAN=m +CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_MAC_PARTITION=y +CONFIG_MADGEMC=m +CONFIG_MAGIC_SYSRQ=y +CONFIG_MARKERS=y +CONFIG_MARVELL_PHY=m +# CONFIG_MATH_EMULATION is not set +CONFIG_MAX_RAW_DEVS=256 +CONFIG_MCA=y +CONFIG_MCA_LEGACY=y +# CONFIG_MCA_PROC_FS is not set +# CONFIG_MCORE2 is not set +CONFIG_MCP2120_DONGLE=m +# CONFIG_MCRUSOE is not set +CONFIG_MCS_FIR=m +# CONFIG_MCYRIXIII is not set +CONFIG_MD=y +CONFIG_MDA_CONSOLE=m +CONFIG_MDIO_BITBANG=m +CONFIG_MD_AUTODETECT=y +CONFIG_MD_FAULTY=m +CONFIG_MD_LINEAR=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID5_RESHAPE=y +CONFIG_MEDIA_ATTACH=y +CONFIG_MEDIA_TUNER=m +# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2131=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +# CONFIG_MEFFICEON is not set +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_SAS=m +# CONFIG_MEMSTICK is not set +# CONFIG_MEMTEST is not set +# CONFIG_MFD_CORE is not set +CONFIG_MFD_SM501=m +# CONFIG_MFD_SM501_GPIO is not set +# CONFIG_MFD_TMIO is not set +CONFIG_MFD_WM8350=m +CONFIG_MFD_WM8350_I2C=m +CONFIG_MFD_WM8400=m +# CONFIG_MGEODEGX1 is not set +# CONFIG_MGEODE_LX is not set +CONFIG_MICROCODE=m +CONFIG_MICROCODE_AMD=y +CONFIG_MICROCODE_INTEL=y +CONFIG_MICROCODE_OLD_INTERFACE=y +CONFIG_MII=m +CONFIG_MINIX_FS=m +CONFIG_MINIX_SUBPARTITION=y +CONFIG_MISC_DEVICES=y +CONFIG_MISDN=m +CONFIG_MISDN_DSP=m +CONFIG_MISDN_HFCMULTI=m +CONFIG_MISDN_HFCPCI=m +CONFIG_MISDN_L1OIP=m +CONFIG_MIXCOMWD=m +# CONFIG_MK6 is not set +# CONFIG_MK7 is not set +# CONFIG_MK8 is not set +CONFIG_MKISS=m +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_MLX4_EN=m +CONFIG_MLX4_INFINIBAND=m +CONFIG_MMC=y +CONFIG_MMC_BLOCK=m +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_RICOH_MMC=m +CONFIG_MMC_SDHCI=m +CONFIG_MMC_SDHCI_PCI=m +CONFIG_MMC_SDRICOH_CS=m +# CONFIG_MMC_TEST is not set +CONFIG_MMC_TIFM_SD=m +# CONFIG_MMC_UNSAFE_RESUME is not set +CONFIG_MMC_WBSD=m +# CONFIG_MMIOTRACE is not set +CONFIG_MMU=y +CONFIG_MMU_NOTIFIER=y +CONFIG_MM_OWNER=y +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MOUSE_APPLETOUCH=m +# CONFIG_MOUSE_ATIXL is not set +CONFIG_MOUSE_BCM5974=m +CONFIG_MOUSE_GPIO=m +CONFIG_MOUSE_INPORT=m +CONFIG_MOUSE_LOGIBM=m +CONFIG_MOUSE_PC110PAD=m +CONFIG_MOUSE_PS2=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_ELANTECH=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_OLPC=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_PS2_TRACKPOINT=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_MOXA_INTELLIO=m +CONFIG_MOXA_SMARTIO=m +# CONFIG_MPENTIUM4 is not set +# CONFIG_MPENTIUMII is not set +# CONFIG_MPENTIUMIII is not set +# CONFIG_MPENTIUMM is not set +# CONFIG_MPSC is not set +CONFIG_MSDOS_FS=m +CONFIG_MSDOS_PARTITION=y +CONFIG_MSI_LAPTOP=m +CONFIG_MSNDCLAS_INIT_FILE="/etc/sound/msndinit.bin" +CONFIG_MSNDCLAS_PERM_FILE="/etc/sound/msndperm.bin" +CONFIG_MSNDPIN_INIT_FILE="/etc/sound/pndspini.bin" +CONFIG_MSNDPIN_PERM_FILE="/etc/sound/pndsperm.bin" +CONFIG_MT9M001_PCA9536_SWITCH=y +CONFIG_MT9V022_PCA9536_SWITCH=y +CONFIG_MTD=m +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTD_ABSENT=m +CONFIG_MTD_ALAUDA=m +CONFIG_MTD_AMD76XROM=m +CONFIG_MTD_AR7_PARTS=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK2MTD=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_MTD_CFI=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_AMDSTD=m +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=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_CHAR=m +CONFIG_MTD_CK804XROM=m +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_CONCAT=m +CONFIG_MTD_DATAFLASH=m +CONFIG_MTD_DATAFLASH_OTP=y +# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_DILNETPC=m +CONFIG_MTD_DILNETPC_BOOTSIZE=0x80000 +CONFIG_MTD_DOC2000=m +CONFIG_MTD_DOC2001=m +CONFIG_MTD_DOC2001PLUS=m +CONFIG_MTD_DOCECC=m +CONFIG_MTD_DOCPROBE=m +CONFIG_MTD_DOCPROBE_ADDRESS=0 +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_ESB2ROM=m +CONFIG_MTD_GEN_PROBE=m +CONFIG_MTD_ICHXROM=m +CONFIG_MTD_INTEL_VR_NOR=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_L440GX=m +CONFIG_MTD_M25P80=m +CONFIG_MTD_MAP_BANK_WIDTH_1=y +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +CONFIG_MTD_MTDRAM=m +CONFIG_MTD_NAND=m +CONFIG_MTD_NAND_CAFE=m +CONFIG_MTD_NAND_CS553X=m +CONFIG_MTD_NAND_DISKONCHIP=m +# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_NANDSIM=m +CONFIG_MTD_NAND_PLATFORM=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NETSC520=m +CONFIG_MTD_NETtel=m +CONFIG_MTD_ONENAND=m +CONFIG_MTD_ONENAND_2X_PROGRAM=y +# CONFIG_MTD_ONENAND_OTP is not set +CONFIG_MTD_ONENAND_SIM=m +CONFIG_MTD_ONENAND_VERIFY_WRITE=y +CONFIG_MTD_OOPS=m +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_PCI=m +CONFIG_MTD_PHRAM=m +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PHYSMAP_LEN=0x4000000 +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PLATRAM=m +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +CONFIG_MTD_RAM=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS=m +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +CONFIG_MTD_ROM=m +CONFIG_MTD_SBC_GXX=m +CONFIG_MTD_SC520CDP=m +CONFIG_MTD_SCB2_FLASH=m +CONFIG_MTD_SCx200_DOCFLASH=m +CONFIG_MTD_SLRAM=m +CONFIG_MTD_TS5500=m +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_DEBUG is not set +CONFIG_MTD_UBI_GLUEBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTRR=y +CONFIG_MTRR_SANITIZER=y +CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0 +CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1 +# CONFIG_MVIAC3_2 is not set +# CONFIG_MVIAC7 is not set +CONFIG_MWAVE=m +# CONFIG_MWINCHIP3D is not set +# CONFIG_MWINCHIPC6 is not set +CONFIG_MYRI10GE=m +CONFIG_N2=m +CONFIG_NAMESPACES=y +CONFIG_NATSEMI=m +CONFIG_NCPFS_EXTRAS=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_OS2_NS=y +CONFIG_NCPFS_PACKET_SIGNING=y +# CONFIG_NCPFS_SMALLDOS is not set +CONFIG_NCPFS_STRONG=y +CONFIG_NCP_FS=m +CONFIG_NDISWRAPPER=m +CONFIG_NE2000=m +CONFIG_NE2K_PCI=m +CONFIG_NE2_MCA=m +CONFIG_NE3210=m +CONFIG_NET=y +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETDEVICES=y +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y +CONFIG_NETFILTER=y +CONFIG_NETFILTER_ADVANCED=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_TPROXY=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=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_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=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_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=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_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETLABEL=y +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NETROM=m +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NETWORK_SECMARK=y +CONFIG_NETXEN_NIC=m +CONFIG_NET_9P=m +# CONFIG_NET_9P_DEBUG is not set +CONFIG_NET_9P_RDMA=m +CONFIG_NET_9P_VIRTIO=m +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_CLS=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_BASIC=m +# CONFIG_NET_CLS_FLOW is not set +CONFIG_NET_CLS_FW=m +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_DCCPPROBE=m +CONFIG_NET_DSA=y +CONFIG_NET_DSA_MV88E6060=y +CONFIG_NET_DSA_MV88E6123_61_65=y +CONFIG_NET_DSA_MV88E6131=y +CONFIG_NET_DSA_MV88E6XXX=y +CONFIG_NET_DSA_MV88E6XXX_NEED_PPU=y +CONFIG_NET_DSA_TAG_DSA=y +CONFIG_NET_DSA_TAG_EDSA=y +CONFIG_NET_DSA_TAG_TRAILER=y +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_ET131X=m +CONFIG_NET_ETHERNET=y +CONFIG_NET_FC=y +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_NET_IPIP=m +CONFIG_NET_ISA=y +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_NET_PCI=y +CONFIG_NET_PCMCIA=y +CONFIG_NET_PKTGEN=m +CONFIG_NET_POCKET=y +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_NET_SB1000=m +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_FIFO=y +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_TCPPROBE=m +CONFIG_NET_TULIP=y +CONFIG_NET_VENDOR_3COM=y +CONFIG_NET_VENDOR_RACAL=y +CONFIG_NET_VENDOR_SMC=y +CONFIG_NEW_LEDS=y +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_NF_CONNTRACK_SANE is not set +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CT_NETLINK=m +# CONFIG_NF_CT_PROTO_DCCP is not set +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_SCTP=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NI52=m +CONFIG_NI65=m +CONFIG_NIU=m +CONFIG_NL80211=y +CONFIG_NLS=y +CONFIG_NLS_ASCII=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +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_874=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=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_8=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +# CONFIG_NOHIGHMEM is not set +CONFIG_NOP_TRACER=y +CONFIG_NORTEL_HERMES=m +CONFIG_NOZOMI=m +CONFIG_NO_HZ=y +CONFIG_NR_CPUS=64 +CONFIG_NS83820=m +CONFIG_NSC_FIR=m +CONFIG_NSC_GPIO=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_FS=m +# CONFIG_NTFS_RW is not set +CONFIG_NVRAM=m +CONFIG_N_HDLC=m +# CONFIG_OCFS2_COMPAT_JBD is not set +# CONFIG_OCFS2_DEBUG_FS is not set +CONFIG_OCFS2_DEBUG_MASKLOG=y +CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_STATS=y +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_OLPC=y +CONFIG_OMFS_FS=m +CONFIG_OPEN_TRACER=y +CONFIG_OPROFILE=m +CONFIG_OPROFILE_IBS=y +CONFIG_OPTIMIZE_INLINING=y +CONFIG_OSF_PARTITION=y +CONFIG_P54_COMMON=m +CONFIG_P54_PCI=m +CONFIG_P54_USB=m +CONFIG_P80211=m +CONFIG_PACKARDBELL_E5=m +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PANASONIC_LAPTOP=m +CONFIG_PANTHERLORD_FF=y +CONFIG_PARAVIRT=y +CONFIG_PARAVIRT_CLOCK=y +# CONFIG_PARAVIRT_DEBUG is not set +CONFIG_PARAVIRT_GUEST=y +CONFIG_PARIDE=m +CONFIG_PARIDE_ATEN=m +CONFIG_PARIDE_BPCK=m +CONFIG_PARIDE_BPCK6=m +CONFIG_PARIDE_COMM=m +CONFIG_PARIDE_DSTR=m +CONFIG_PARIDE_EPAT=m +# CONFIG_PARIDE_EPATC8 is not set +CONFIG_PARIDE_EPIA=m +CONFIG_PARIDE_FIT2=m +CONFIG_PARIDE_FIT3=m +CONFIG_PARIDE_FRIQ=m +CONFIG_PARIDE_FRPW=m +CONFIG_PARIDE_KBIC=m +CONFIG_PARIDE_KTTI=m +CONFIG_PARIDE_ON20=m +CONFIG_PARIDE_ON26=m +CONFIG_PARIDE_PCD=m +CONFIG_PARIDE_PD=m +CONFIG_PARIDE_PF=m +CONFIG_PARIDE_PG=m +CONFIG_PARIDE_PT=m +CONFIG_PARPORT=m +CONFIG_PARPORT_1284=y +CONFIG_PARPORT_AX88796=m +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_NOT_PC=y +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_FIFO=y +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_SERIAL=m +CONFIG_PARTITION_ADVANCED=y +CONFIG_PATA_ACPI=y +CONFIG_PATA_ALI=y +CONFIG_PATA_AMD=y +CONFIG_PATA_ARTOP=y +CONFIG_PATA_ATIIXP=y +CONFIG_PATA_CMD640_PCI=y +CONFIG_PATA_CMD64X=y +CONFIG_PATA_CS5520=y +CONFIG_PATA_CS5530=y +CONFIG_PATA_CS5535=m +CONFIG_PATA_CS5536=y +CONFIG_PATA_CYPRESS=m +CONFIG_PATA_EFAR=y +CONFIG_PATA_HPT366=y +CONFIG_PATA_HPT37X=m +CONFIG_PATA_HPT3X2N=y +CONFIG_PATA_HPT3X3=y +# CONFIG_PATA_HPT3X3_DMA is not set +CONFIG_PATA_ISAPNP=m +CONFIG_PATA_IT8213=m +CONFIG_PATA_IT821X=y +CONFIG_PATA_JMICRON=y +CONFIG_PATA_LEGACY=m +CONFIG_PATA_MARVELL=y +CONFIG_PATA_MPIIX=y +CONFIG_PATA_NETCELL=y +CONFIG_PATA_NINJA32=m +CONFIG_PATA_NS87410=y +CONFIG_PATA_NS87415=y +CONFIG_PATA_OLDPIIX=m +CONFIG_PATA_OPTI=m +CONFIG_PATA_OPTIDMA=m +CONFIG_PATA_PCMCIA=m +CONFIG_PATA_PDC2027X=y +CONFIG_PATA_PDC_OLD=y +CONFIG_PATA_QDI=y +CONFIG_PATA_RADISYS=m +CONFIG_PATA_RZ1000=y +CONFIG_PATA_SC1200=y +CONFIG_PATA_SCH=y +CONFIG_PATA_SERVERWORKS=y +CONFIG_PATA_SIL680=y +CONFIG_PATA_SIS=y +CONFIG_PATA_TRIFLEX=y +CONFIG_PATA_VIA=y +CONFIG_PATA_WINBOND=y +CONFIG_PATA_WINBOND_VLB=m +# CONFIG_PC300TOO is not set +CONFIG_PC8736x_GPIO=m +CONFIG_PC87413_WDT=m +CONFIG_PCCARD=m +CONFIG_PCCARD_NONSTATIC=m +CONFIG_PCI=y +CONFIG_PCI200SYN=m +CONFIG_PCIEAER=y +# CONFIG_PCIEASPM is not set +CONFIG_PCIEPORTBUS=y +CONFIG_PCIPCWATCHDOG=m +CONFIG_PCI_ATMEL=m +CONFIG_PCI_BIOS=y +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_DIRECT=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_GOANY=y +# CONFIG_PCI_GOBIOS is not set +# CONFIG_PCI_GODIRECT is not set +# CONFIG_PCI_GOMMCONFIG is not set +# CONFIG_PCI_GOOLPC is not set +CONFIG_PCI_HERMES=m +CONFIG_PCI_LEGACY=y +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_MSI=y +CONFIG_PCI_OLPC=y +CONFIG_PCI_QUIRKS=y +CONFIG_PCMCIA=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_AHA152X=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_PCMCIA_AXNET=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_HERMES=m +CONFIG_PCMCIA_IBMTR=m +CONFIG_PCMCIA_IOCTL=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_NETWAVE=m +CONFIG_PCMCIA_NINJA_SCSI=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_PROBE=y +CONFIG_PCMCIA_QLOGIC=m +CONFIG_PCMCIA_RAYCS=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_SPECTRUM=m +CONFIG_PCMCIA_SYM53C500=m +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_WL3501=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_PCNET32=m +CONFIG_PCSPKR_PLATFORM=y +CONFIG_PCWATCHDOG=m +CONFIG_PD6729=m +CONFIG_PDA_POWER=m +CONFIG_PDC_ADMA=y +CONFIG_PHANTOM=m +CONFIG_PHONE=m +CONFIG_PHONET=m +CONFIG_PHONE_IXJ=m +CONFIG_PHONE_IXJ_PCMCIA=m +CONFIG_PHYLIB=y +CONFIG_PHYSICAL_ALIGN=0x100000 +CONFIG_PHYSICAL_START=0x100000 +CONFIG_PID_NS=y +CONFIG_PLIP=m +CONFIG_PLIST=y +CONFIG_PLX_HERMES=m +CONFIG_PM=y +CONFIG_PMIC_DA903X=y +CONFIG_PM_DEBUG=y +CONFIG_PM_DISABLE_CONSOLE=y +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +CONFIG_PM_STD_PARTITION="" +CONFIG_PM_TEST_SUSPEND=y +CONFIG_PM_TRACE=y +CONFIG_PM_TRACE_RTC=y +# CONFIG_PM_VERBOSE is not set +CONFIG_PNP=y +CONFIG_PNPACPI=y +CONFIG_PNPBIOS=y +CONFIG_PNPBIOS_PROC_FS=y +CONFIG_PNP_DEBUG_MESSAGES=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +CONFIG_PPDEV=m +CONFIG_PPP=y +CONFIG_PPPOATM=m +CONFIG_PPPOE=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_SYNC_TTY=m +# CONFIG_PREEMPT is not set +CONFIG_PREEMPT_NOTIFIERS=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_PRINTER=m +CONFIG_PRINTK=y +CONFIG_PRINTK_TIME=y +CONFIG_PRINT_QUOTA_WARNING=y +CONFIG_PRISM2_USB=m +CONFIG_PRISM54=m +CONFIG_PROC_EVENTS=y +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_VMCORE=y +CONFIG_PROFILING=y +CONFIG_PROTEON=m +# CONFIG_PROVE_LOCKING is not set +# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set +# CONFIG_PSS_HAVE_BOOT is not set +CONFIG_PSS_MIXER=y +CONFIG_QC_USB=m +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_QLA3XXX=m +CONFIG_QLGE=m +CONFIG_QNX4FS_FS=m +CONFIG_QSEMI_PHY=m +CONFIG_QUOTA=y +CONFIG_QUOTACTL=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +CONFIG_R3964=m +# CONFIG_R6040 is not set +CONFIG_R8169=m +CONFIG_R8169_VLAN=y +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_AZTECH=m +CONFIG_RADIO_CADET=m +CONFIG_RADIO_GEMTEK=m +CONFIG_RADIO_GEMTEK_PCI=m +CONFIG_RADIO_MAESTRO=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RADIO_RTRACK=m +CONFIG_RADIO_RTRACK2=m +CONFIG_RADIO_SF16FMI=m +CONFIG_RADIO_SF16FMR2=m +CONFIG_RADIO_TERRATEC=m +CONFIG_RADIO_TRUST=m +CONFIG_RADIO_TYPHOON=m +CONFIG_RADIO_TYPHOON_PROC_FS=y +CONFIG_RADIO_ZOLTRIX=m +CONFIG_RAID_ATTRS=m +CONFIG_RAW_DRIVER=m +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_REALTEK_PHY is not set +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_DEC16=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_BQ24022=m +CONFIG_REGULATOR_DA903X=m +CONFIG_REGULATOR_DEBUG=y +# CONFIG_REGULATOR_FIXED_VOLTAGE is not set +CONFIG_REGULATOR_VIRTUAL_CONSUMER=m +CONFIG_REGULATOR_WM8350=m +CONFIG_REGULATOR_WM8400=m +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_FS=m +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_REISERFS_FS_XATTR=y +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_RELAY=y +CONFIG_RELOCATABLE=y +CONFIG_RESOURCE_COUNTERS=y +CONFIG_RFD_FTL=m +CONFIG_RFKILL=y +CONFIG_RFKILL_INPUT=m +CONFIG_RFKILL_LEDS=y +CONFIG_RING_BUFFER=y +CONFIG_RIO=m +# CONFIG_RIO_OLDPCI is not set +CONFIG_RISCOM8=m +CONFIG_ROADRUNNER=m +# CONFIG_ROADRUNNER_LARGE_RINGS is not set +CONFIG_ROCKETPORT=m +CONFIG_ROMFS_FS=m +CONFIG_ROSE=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_RT2400PCI=m +CONFIG_RT2500PCI=m +CONFIG_RT2500USB=m +CONFIG_RT2860=m +CONFIG_RT2870=m +CONFIG_RT2X00=m +# CONFIG_RT2X00_DEBUG is not set +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_CRYPTO=y +# CONFIG_RT2X00_LIB_DEBUGFS is not set +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_LEDS=y +CONFIG_RT2X00_LIB_PCI=m +CONFIG_RT2X00_LIB_RFKILL=y +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT61PCI=m +CONFIG_RT73USB=m +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DEBUG is not set +CONFIG_RTC_DRV_BQ4802=m +CONFIG_RTC_DRV_CMOS=y +CONFIG_RTC_DRV_DS1286=m +CONFIG_RTC_DRV_DS1305=m +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1390=m +# CONFIG_RTC_DRV_DS1511 is not set +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_DS3234=m +CONFIG_RTC_DRV_FM3130=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_M41T80_WDT=y +CONFIG_RTC_DRV_M41T94=m +CONFIG_RTC_DRV_M48T35=m +CONFIG_RTC_DRV_M48T59=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +# CONFIG_RTC_DRV_R9701 is not set +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_RX8581=m +# CONFIG_RTC_DRV_S35390A is not set +CONFIG_RTC_DRV_STK17TA8=m +CONFIG_RTC_DRV_TEST=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_WM8350=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_LIB=y +CONFIG_RTL8180=m +CONFIG_RTL8187=m +CONFIG_RTL8187SE=m +CONFIG_RT_GROUP_SCHED=y +CONFIG_RT_MUTEXES=y +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_RXKAD=m +CONFIG_S2IO=m +# CONFIG_SAMPLES is not set +CONFIG_SATA_AHCI=y +CONFIG_SATA_INIC162X=y +CONFIG_SATA_MV=m +CONFIG_SATA_NV=y +CONFIG_SATA_PMP=y +CONFIG_SATA_PROMISE=y +CONFIG_SATA_QSTOR=y +CONFIG_SATA_SIL=y +CONFIG_SATA_SIL24=y +CONFIG_SATA_SIS=y +CONFIG_SATA_SVW=y +CONFIG_SATA_SX4=m +CONFIG_SATA_ULI=y +CONFIG_SATA_VIA=y +CONFIG_SATA_VITESSE=y +CONFIG_SBC7240_WDT=m +CONFIG_SBC8360_WDT=m +CONFIG_SBC_EPX_C3_WATCHDOG=m +CONFIG_SBNI=m +# CONFIG_SBNI_MULTILINE is not set +CONFIG_SC1200_WDT=m +CONFIG_SC520_WDT=m +CONFIG_SC6600=y +CONFIG_SC6600_CDROM=4 +CONFIG_SC6600_CDROMBASE=0 +CONFIG_SC6600_JOY=y +CONFIG_SC92031=m +CONFIG_SCC=m +# CONFIG_SCC_DELAY is not set +# CONFIG_SCC_TRXECHO is not set +CONFIG_SCHEDSTATS=y +CONFIG_SCHED_DEBUG=y +CONFIG_SCHED_HRTICK=y +CONFIG_SCHED_MC=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_SCHED_SMT=y +# CONFIG_SCHED_TRACER is not set +CONFIG_SCSI=y +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_7000FASST=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_ADVANSYS=m +CONFIG_SCSI_AHA152X=m +CONFIG_SCSI_AHA1542=m +CONFIG_SCSI_AHA1740=m +CONFIG_SCSI_AIC79XX=m +CONFIG_SCSI_AIC7XXX=m +# CONFIG_SCSI_AIC7XXX_OLD is not set +CONFIG_SCSI_AIC94XX=m +CONFIG_SCSI_ARCMSR=m +CONFIG_SCSI_ARCMSR_AER=y +CONFIG_SCSI_BUSLOGIC=m +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_DC390T=m +CONFIG_SCSI_DC395x=m +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_DH=y +CONFIG_SCSI_DH_ALUA=m +CONFIG_SCSI_DH_EMC=m +CONFIG_SCSI_DH_HP_SW=m +CONFIG_SCSI_DH_RDAC=m +CONFIG_SCSI_DMA=y +CONFIG_SCSI_DMX3191D=m +CONFIG_SCSI_DPT_I2O=m +CONFIG_SCSI_DTC3280=m +CONFIG_SCSI_EATA=m +CONFIG_SCSI_EATA_LINKED_COMMANDS=y +CONFIG_SCSI_EATA_MAX_TAGS=16 +CONFIG_SCSI_EATA_TAGGED_QUEUE=y +CONFIG_SCSI_ENCLOSURE=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_FC_TGT_ATTRS=y +CONFIG_SCSI_FD_MCS=m +# CONFIG_SCSI_FLASHPOINT is not set +CONFIG_SCSI_FUTURE_DOMAIN=m +CONFIG_SCSI_GDTH=m +CONFIG_SCSI_GENERIC_NCR5380=m +CONFIG_SCSI_GENERIC_NCR5380_MMIO=m +CONFIG_SCSI_GENERIC_NCR53C400=y +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_IBMMCA=m +CONFIG_SCSI_IMM=m +CONFIG_SCSI_IN2000=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_IPR=m +# CONFIG_SCSI_IPR_DUMP is not set +# CONFIG_SCSI_IPR_TRACE is not set +CONFIG_SCSI_IPS=m +CONFIG_SCSI_ISCSITARGET=m +CONFIG_SCSI_ISCSI_ATTRS=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_LOWLEVEL=y +CONFIG_SCSI_LOWLEVEL_PCMCIA=y +CONFIG_SCSI_LPFC=m +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_MVSAS is not set +CONFIG_SCSI_NCR53C406A=m +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=4 +CONFIG_SCSI_NCR53C8XX_SYNC=5 +CONFIG_SCSI_NCR_D700=m +CONFIG_SCSI_NCR_Q720=m +CONFIG_SCSI_NETLINK=y +CONFIG_SCSI_NSP32=m +CONFIG_SCSI_PAS16=m +CONFIG_SCSI_PPA=m +CONFIG_SCSI_PROC_FS=y +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_QLOGIC_FAS=m +CONFIG_SCSI_SAS_ATA=y +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_HOST_SMP=y +CONFIG_SCSI_SAS_LIBSAS=m +# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_SIM710=m +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_SRP=m +CONFIG_SCSI_SRP_ATTRS=m +CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C416=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_T128=m +CONFIG_SCSI_TGT=m +CONFIG_SCSI_U14_34F=m +CONFIG_SCSI_U14_34F_LINKED_COMMANDS=y +CONFIG_SCSI_U14_34F_MAX_TAGS=8 +CONFIG_SCSI_U14_34F_TAGGED_QUEUE=y +CONFIG_SCSI_ULTRASTOR=m +CONFIG_SCSI_WAIT_SCAN=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_HMAC_MD5=y +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCx200=m +CONFIG_SCx200HR_TIMER=m +CONFIG_SCx200_ACB=m +CONFIG_SCx200_GPIO=m +CONFIG_SCx200_I2C=m +CONFIG_SCx200_I2C_SCL=12 +CONFIG_SCx200_I2C_SDA=13 +CONFIG_SCx200_WDT=m +CONFIG_SDIO_UART=m +CONFIG_SDLA=m +CONFIG_SEALEVEL_4021=m +CONFIG_SECCOMP=y +CONFIG_SECURITY=y +CONFIG_SECURITYFS=y +CONFIG_SECURITY_APPARMOR=y +CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 +CONFIG_SECURITY_APPARMOR_DISABLE=y +CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=65536 +CONFIG_SECURITY_FILE_CAPABILITIES=y +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +# CONFIG_SECURITY_ROOTPLUG is not set +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_DISABLE=y +# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set +CONFIG_SECURITY_SMACK=y +CONFIG_SEEQ8005=m +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_ABITUGURU3=m +CONFIG_SENSORS_AD7414=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADCXX=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ADS7828=m +CONFIG_SENSORS_ADT7462=m +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_ADT7473=m +CONFIG_SENSORS_APPLESMC=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_CORETEMP=m +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_FSCHMD=m +CONFIG_SENSORS_FSCPOS=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_HDAPS=m +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_IBMAEM=m +CONFIG_SENSORS_IBMPEX=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_K8TEMP=m +CONFIG_SENSORS_LIS3LV02D=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_LM93=m +CONFIG_SENSORS_MAX1111=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_TSL2550=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SENSORS_W83L786NG=m +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_ACCENT=m +CONFIG_SERIAL_8250_BOCA=m +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_CS=m +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_EXAR_ST16C554=m +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_FOURPORT=m +CONFIG_SERIAL_8250_HUB6=m +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_MCA=m +CONFIG_SERIAL_8250_NR_UARTS=48 +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_PNP=y +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_JSM=m +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_SERIO=y +CONFIG_SERIO_CT82C710=m +CONFIG_SERIO_I8042=y +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_PARKBD=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SERIO_RAW=m +CONFIG_SERIO_SERPORT=m +CONFIG_SFC=m +CONFIG_SGI_IOC4=m +CONFIG_SGI_PARTITION=y +CONFIG_SHMEM=y +CONFIG_SIGMATEL_FIR=m +CONFIG_SIGNALFD=y +CONFIG_SIS190=m +CONFIG_SIS900=m +CONFIG_SKFP=m +CONFIG_SKGE=m +# CONFIG_SKGE_DEBUG is not set +CONFIG_SKISA=m +CONFIG_SKY2=m +# CONFIG_SKY2_DEBUG is not set +# CONFIG_SLAB is not set +CONFIG_SLABINFO=y +CONFIG_SLHC=y +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_MODE_SLIP6=y +CONFIG_SLIP_SMART=y +# CONFIG_SLOB is not set +CONFIG_SLUB=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_SMC9194=m +CONFIG_SMCTR=m +CONFIG_SMC_IRCC_FIR=m +CONFIG_SMP=y +CONFIG_SMSC37B787_WDT=m +# CONFIG_SMSC911X is not set +CONFIG_SMSC_PHY=m +CONFIG_SND=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_AC97_POWER_SAVE=y +CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0 +CONFIG_SND_AD1816A=m +CONFIG_SND_AD1848=m +CONFIG_SND_AD1889=m +CONFIG_SND_ADLIB=m +CONFIG_SND_ALI5451=m +CONFIG_SND_ALS100=m +CONFIG_SND_ALS300=m +CONFIG_SND_ALS4000=m +CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m +CONFIG_SND_AU8810=m +CONFIG_SND_AU8820=m +CONFIG_SND_AU8830=m +CONFIG_SND_AW2=m +CONFIG_SND_AZT2320=m +CONFIG_SND_AZT3328=m +CONFIG_SND_BT87X=m +# CONFIG_SND_BT87X_OVERCLOCK is not set +CONFIG_SND_BTSCO=m +CONFIG_SND_CA0106=m +CONFIG_SND_CMI8330=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_CS4231=m +CONFIG_SND_CS4232=m +CONFIG_SND_CS4236=m +CONFIG_SND_CS4281=m +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_CS5530=m +CONFIG_SND_CS5535AUDIO=m +CONFIG_SND_DARLA20=m +CONFIG_SND_DARLA24=m +# CONFIG_SND_DEBUG is not set +CONFIG_SND_DRIVERS=y +CONFIG_SND_DT019X=m +CONFIG_SND_DUMMY=m +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_ECHO3G=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_EMU10K1X=m +CONFIG_SND_ENS1370=m +CONFIG_SND_ENS1371=m +CONFIG_SND_ES1688=m +CONFIG_SND_ES18XX=m +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +CONFIG_SND_ES968=m +CONFIG_SND_FM801=m +CONFIG_SND_FM801_TEA575X=m +CONFIG_SND_FM801_TEA575X_BOOL=y +CONFIG_SND_GINA20=m +CONFIG_SND_GINA24=m +CONFIG_SND_GUSCLASSIC=m +CONFIG_SND_GUSEXTREME=m +CONFIG_SND_GUSMAX=m +CONFIG_SND_HDA_CODEC_ANALOG=y +CONFIG_SND_HDA_CODEC_ATIHDMI=y +CONFIG_SND_HDA_CODEC_CMEDIA=y +CONFIG_SND_HDA_CODEC_CONEXANT=y +CONFIG_SND_HDA_CODEC_INTELHDMI=y +CONFIG_SND_HDA_CODEC_NVHDMI=y +CONFIG_SND_HDA_CODEC_REALTEK=y +CONFIG_SND_HDA_CODEC_SI3054=y +CONFIG_SND_HDA_CODEC_SIGMATEL=y +CONFIG_SND_HDA_CODEC_VIA=y +CONFIG_SND_HDA_ELD=y +CONFIG_SND_HDA_GENERIC=y +# CONFIG_SND_HDA_HWDEP is not set +CONFIG_SND_HDA_INPUT_BEEP=y +CONFIG_SND_HDA_INTEL=m +CONFIG_SND_HDA_POWER_SAVE=y +CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 +CONFIG_SND_HDSP=m +CONFIG_SND_HDSPM=m +CONFIG_SND_HIFIER=m +CONFIG_SND_HWDEP=m +CONFIG_SND_ICE1712=m +CONFIG_SND_ICE1724=m +CONFIG_SND_INDIGO=m +CONFIG_SND_INDIGODJ=m +CONFIG_SND_INDIGOIO=m +CONFIG_SND_INTEL8X0=m +CONFIG_SND_INTEL8X0M=m +CONFIG_SND_INTERWAVE=m +CONFIG_SND_INTERWAVE_STB=m +CONFIG_SND_ISA=y +CONFIG_SND_KORG1212=m +CONFIG_SND_LAYLA20=m +CONFIG_SND_LAYLA24=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_MIA=m +CONFIG_SND_MIRO=m +CONFIG_SND_MIXART=m +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_MONA=m +CONFIG_SND_MPU401=m +CONFIG_SND_MPU401_UART=m +CONFIG_SND_MTPAV=m +CONFIG_SND_MTS64=m +CONFIG_SND_NM256=m +CONFIG_SND_OPL3SA2=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_OPL4_LIB=m +CONFIG_SND_OPTI92X_AD1848=m +CONFIG_SND_OPTI92X_CS4231=m +CONFIG_SND_OPTI93X=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_OXYGEN=m +CONFIG_SND_OXYGEN_LIB=m +CONFIG_SND_PCI=y +CONFIG_SND_PCM=m +CONFIG_SND_PCMCIA=y +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_PCSP=m +CONFIG_SND_PCXHR=m +CONFIG_SND_PDAUDIOCF=m +CONFIG_SND_PORTMAN2X4=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_RIPTIDE=m +CONFIG_SND_RME32=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m +CONFIG_SND_SB16=m +CONFIG_SND_SB16_CSP=y +CONFIG_SND_SB16_DSP=m +CONFIG_SND_SB8=m +CONFIG_SND_SB8_DSP=m +CONFIG_SND_SBAWE=m +CONFIG_SND_SB_COMMON=m +CONFIG_SND_SC6000=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_SGALAXY=m +CONFIG_SND_SIS7019=m +CONFIG_SND_SOC=m +CONFIG_SND_SOC_AD73311=m +CONFIG_SND_SOC_AK4535=m +CONFIG_SND_SOC_ALL_CODECS=m +CONFIG_SND_SOC_CS4270=m +CONFIG_SND_SOC_SSM2602=m +CONFIG_SND_SOC_TLV320AIC23=m +CONFIG_SND_SOC_TLV320AIC26=m +CONFIG_SND_SOC_TLV320AIC3X=m +CONFIG_SND_SOC_UDA1380=m +CONFIG_SND_SOC_WM8510=m +CONFIG_SND_SOC_WM8580=m +CONFIG_SND_SOC_WM8731=m +CONFIG_SND_SOC_WM8750=m +CONFIG_SND_SOC_WM8753=m +CONFIG_SND_SOC_WM8900=m +CONFIG_SND_SOC_WM8903=m +CONFIG_SND_SOC_WM8971=m +CONFIG_SND_SOC_WM8990=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_SPI=y +CONFIG_SND_SSCAPE=m +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_TIMER=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_USB_US122L=m +CONFIG_SND_USB_USX2Y=m +# CONFIG_SND_VERBOSE_PRINTK is not set +CONFIG_SND_VERBOSE_PROCFS=y +CONFIG_SND_VIA82XX=m +CONFIG_SND_VIA82XX_MODEM=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_VIRTUOSO=m +CONFIG_SND_VMASTER=y +CONFIG_SND_VX222=m +CONFIG_SND_VXPOCKET=m +CONFIG_SND_VX_LIB=m +CONFIG_SND_WAVEFRONT=m +CONFIG_SND_WAVEFRONT_FIRMWARE_IN_KERNEL=y +CONFIG_SND_WSS_LIB=m +CONFIG_SND_YMFPCI=m +CONFIG_SOC_CAMERA=m +CONFIG_SOC_CAMERA_MT9M001=m +CONFIG_SOC_CAMERA_MT9M111=m +CONFIG_SOC_CAMERA_MT9V022=m +CONFIG_SOC_CAMERA_PLATFORM=m +CONFIG_SOFT_WATCHDOG=m +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_SONYPI=m +CONFIG_SONYPI_COMPAT=y +CONFIG_SONY_LAPTOP=m +CONFIG_SOUND=m +CONFIG_SOUND_AEDSP16=m +CONFIG_SOUND_DMAP=y +CONFIG_SOUND_KAHLUA=m +CONFIG_SOUND_MPU401=m +CONFIG_SOUND_MSNDCLAS=m +CONFIG_SOUND_MSNDPIN=m +CONFIG_SOUND_MSS=m +CONFIG_SOUND_OSS=m +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_PAS=m +CONFIG_SOUND_PRIME=m +CONFIG_SOUND_PSS=m +CONFIG_SOUND_SB=m +CONFIG_SOUND_SSCAPE=m +# CONFIG_SOUND_TRACEINIT is not set +CONFIG_SOUND_TRIX=m +CONFIG_SOUND_UART6850=m +CONFIG_SOUND_VMIDI=m +CONFIG_SOUND_YM3812=m +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_SPARSEMEM_STATIC=y +CONFIG_SPECIALIX=m +CONFIG_SPI=y +CONFIG_SPI_AT25=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_LM70_LLP=m +CONFIG_SPI_MASTER=y +CONFIG_SPI_SPIDEV=m +CONFIG_SPI_TLE62X0=m +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_SQUASHFS=m +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +CONFIG_SSB=m +CONFIG_SSB_B43_PCI_BRIDGE=y +# CONFIG_SSB_DEBUG is not set +CONFIG_SSB_DRIVER_PCICORE=y +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +# CONFIG_SSB_PCMCIAHOST is not set +CONFIG_SSB_PCMCIAHOST_POSSIBLE=y +CONFIG_SSB_POSSIBLE=y +CONFIG_SSB_SPROM=y +CONFIG_SSFDC=m +CONFIG_STACKTRACE=y +CONFIG_STACKTRACE_SUPPORT=y +# CONFIG_STACK_TRACER is not set +CONFIG_STAGING=y +CONFIG_STAGING_EXCLUDE_BUILD=y +CONFIG_STALDRV=y +CONFIG_STALLION=m +# CONFIG_STANDALONE is not set +CONFIG_STOP_MACHINE=y +CONFIG_STP=m +CONFIG_STRICT_DEVMEM=y +CONFIG_STRIP=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_SUNGEM=m +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +# CONFIG_SUNRPC_REGISTER_V4 is not set +CONFIG_SUNRPC_XPRT_RDMA=m +CONFIG_SUN_PARTITION=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_SWAP=y +CONFIG_SX=m +CONFIG_SYNCLINK=m +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_CS=m +CONFIG_SYNCLINK_GT=m +CONFIG_SYN_COOKIES=y +CONFIG_SYSCTL=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_SYSFS=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_SYSPROF_TRACER is not set +CONFIG_SYSV68_PARTITION=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_SYSV_FS=m +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +CONFIG_TASKSTATS=y +# CONFIG_TASK_DELAY_ACCT is not set +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_TASK_XACCT=y +CONFIG_TC1100_WMI=m +CONFIG_TCG_ATMEL=m +CONFIG_TCG_INFINEON=m +CONFIG_TCG_NSC=m +CONFIG_TCG_TIS=m +CONFIG_TCG_TPM=m +CONFIG_TCIC=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_MD5SIG=y +CONFIG_TEHUTI=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TELCLOCK=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_TEXTSEARCH_KMP=m +CONFIG_THERMAL=y +CONFIG_THERMAL_HWMON=y +CONFIG_THINKPAD_ACPI=m +CONFIG_THINKPAD_ACPI_BAY=y +# CONFIG_THINKPAD_ACPI_DEBUG is not set +CONFIG_THINKPAD_ACPI_HOTKEY_POLL=y +CONFIG_THINKPAD_ACPI_VIDEO=y +CONFIG_THRUSTMASTER_FF=m +CONFIG_TICK_ONESHOT=y +CONFIG_TIFM_7XX1=m +CONFIG_TIFM_CORE=m +CONFIG_TIGON3=m +CONFIG_TIMERFD=y +CONFIG_TIMER_STATS=y +# CONFIG_TINY_SHMEM is not set +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set +CONFIG_TLAN=m +CONFIG_TLSF=m +# CONFIG_TLSF_DEBUG is not set +# CONFIG_TLSF_STATS is not set +# CONFIG_TLSUP is not set +CONFIG_TMD_HERMES=m +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMS380TR=m +CONFIG_TMSPCI=m +# CONFIG_TOIM3232_DONGLE is not set +# CONFIG_TOSHIBA is not set +CONFIG_TOSHIBA_FIR=m +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_HTCPEN=m +CONFIG_TOUCHSCREEN_INEXIO=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TOUCHIT213=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_UCB1400=m +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TOUCHSCREEN_WM9705=y +CONFIG_TOUCHSCREEN_WM9712=y +CONFIG_TOUCHSCREEN_WM9713=y +CONFIG_TOUCHSCREEN_WM97XX=m +CONFIG_TPS65010=m +CONFIG_TP_SMAPI=m +CONFIG_TP_SMAPI_EC=m +CONFIG_TR=y +CONFIG_TRACEPOINTS=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_TRACING=y +CONFIG_TTPCI_EEPROM=m +CONFIG_TULIP=m +# CONFIG_TULIP_MMIO is not set +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_NAPI is not set +CONFIG_TUN=m +CONFIG_TYPHOON=m +CONFIG_UBIFS_FS=m +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +# CONFIG_UBIFS_FS_DEBUG is not set +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_XATTR=y +CONFIG_UBIFS_FS_ZLIB=y +CONFIG_UCB1400_CORE=m +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +CONFIG_UEVENT_HELPER_PATH="" +# CONFIG_UFS_DEBUG is not set +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +CONFIG_UID16=y +CONFIG_UIO=m +CONFIG_UIO_CIF=m +CONFIG_UIO_PDRV=m +CONFIG_UIO_PDRV_GENIRQ=m +CONFIG_UIO_SERCOS3=m +CONFIG_UIO_SMX=m +CONFIG_ULI526X=m +CONFIG_ULTRA=m +CONFIG_ULTRA32=m +CONFIG_ULTRAMCA=m +CONFIG_ULTRIX_PARTITION=y +CONFIG_UNEVICTABLE_LRU=y +CONFIG_UNIX=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_USB=y +CONFIG_USBPCWATCHDOG=m +CONFIG_USB_ACM=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_APPLEIR=m +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_ATM=m +CONFIG_USB_ATMEL=m +CONFIG_USB_BELKIN=y +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_C67X00_HCD=m +CONFIG_USB_CATC=m +CONFIG_USB_CDC_COMPOSITE=m +CONFIG_USB_CXACRU=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +CONFIG_USB_DSBR=m +CONFIG_USB_DUMMY_HCD=m +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EMI26=m +CONFIG_USB_EMI62=m +CONFIG_USB_EPSON2888=y +CONFIG_USB_ET61X251=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_EZUSB=y +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_GADGET=m +CONFIG_USB_GADGETFS=m +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_ARC is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_DUALSPEED=y +CONFIG_USB_GADGET_DUMMY_HCD=y +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C2410 is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GSPCA=m +CONFIG_USB_GSPCA_CONEX=m +CONFIG_USB_GSPCA_ETOMS=m +CONFIG_USB_GSPCA_FINEPIX=m +CONFIG_USB_GSPCA_MARS=m +CONFIG_USB_GSPCA_OV519=m +CONFIG_USB_GSPCA_PAC207=m +CONFIG_USB_GSPCA_PAC7311=m +CONFIG_USB_GSPCA_SONIXB=m +CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_USB_GSPCA_SPCA500=m +CONFIG_USB_GSPCA_SPCA501=m +CONFIG_USB_GSPCA_SPCA505=m +CONFIG_USB_GSPCA_SPCA506=m +CONFIG_USB_GSPCA_SPCA508=m +CONFIG_USB_GSPCA_SPCA561=m +CONFIG_USB_GSPCA_STK014=m +CONFIG_USB_GSPCA_SUNPLUS=m +CONFIG_USB_GSPCA_T613=m +CONFIG_USB_GSPCA_TV8532=m +CONFIG_USB_GSPCA_VC032X=m +CONFIG_USB_GSPCA_ZC3XX=m +# CONFIG_USB_G_PRINTER is not set +CONFIG_USB_G_SERIAL=m +CONFIG_USB_HID=m +CONFIG_USB_HIDDEV=y +CONFIG_USB_HSO=m +CONFIG_USB_HWA_HCD=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_IRDA=m +CONFIG_USB_ISIGHTFW=m +CONFIG_USB_ISP116X_HCD=m +CONFIG_USB_ISP1760_HCD=m +CONFIG_USB_KAWETH=m +CONFIG_USB_KBD=m +CONFIG_USB_KC2190=y +CONFIG_USB_KONICAWC=m +CONFIG_USB_LCD=m +CONFIG_USB_LD=m +CONFIG_USB_LED=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LIBUSUAL=y +CONFIG_USB_M5602=m +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_USB_MON=y +CONFIG_USB_MOUSE=m +CONFIG_USB_MR800=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_RNDIS_WLAN=m +CONFIG_USB_NET_SMSC95XX=m +CONFIG_USB_NET_ZAURUS=m +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OV511 is not set +CONFIG_USB_OV511_NEW=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_PRINTER=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_R8A66597_HCD=m +CONFIG_USB_RIO500=m +CONFIG_USB_RTL8150=m +CONFIG_USB_S2255=m +CONFIG_USB_SE401=m +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_CONSOLE=y +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IPW=m +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_IUU is not set +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_MOTOROLA=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SEVSEG=m +CONFIG_USB_SI470X=m +CONFIG_USB_SISUSBVGA=m +# CONFIG_USB_SISUSBVGA_CON is not set +CONFIG_USB_SL811_CS=m +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SN9C102=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_STKWEBCAM=m +CONFIG_USB_STORAGE=m +CONFIG_USB_STORAGE_ALAUDA=y +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +CONFIG_USB_STORAGE_DATAFAB=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_KARMA=y +# CONFIG_USB_STORAGE_ONETOUCH is not set +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STV680=m +CONFIG_USB_SUPPORT=y +CONFIG_USB_SUSPEND=y +# CONFIG_USB_TEST is not set +CONFIG_USB_TMC=m +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_U132_HCD=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_UHCI_HCD=y +CONFIG_USB_USBNET=m +CONFIG_USB_USS720=m +CONFIG_USB_VICAM=m +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_VST=m +CONFIG_USB_W9968CF=m +CONFIG_USB_WDM=m +CONFIG_USB_WHCI_HCD=m +CONFIG_USB_WUSB=m +CONFIG_USB_WUSB_CBAF=m +# CONFIG_USB_WUSB_CBAF_DEBUG is not set +CONFIG_USB_XUSBATM=m +CONFIG_USB_ZC0301=m +CONFIG_USB_ZD1201=m +CONFIG_USB_ZERO=m +CONFIG_USB_ZR364XX=m +# CONFIG_USER_NS is not set +# CONFIG_USER_SCHED is not set +CONFIG_USE_GENERIC_SMP_HELPERS=y +CONFIG_UTS_NS=y +CONFIG_UWB=m +CONFIG_UWB_HWA=m +CONFIG_UWB_I1480U=m +CONFIG_UWB_I1480U_WLP=m +CONFIG_UWB_WHCI=m +CONFIG_UWB_WLP=m +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VERSION_SIGNATURE="" +CONFIG_VETH=m +CONFIG_VFAT_FS=m +# CONFIG_VGACON_SOFT_SCROLLBACK is not set +CONFIG_VGASTATE=m +CONFIG_VGA_CONSOLE=y +CONFIG_VIA_FIR=m +CONFIG_VIA_RHINE=m +CONFIG_VIA_RHINE_MMIO=y +CONFIG_VIA_VELOCITY=m +CONFIG_VIDEOBUF_DMA_CONTIG=m +CONFIG_VIDEOBUF_DMA_SG=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_ALLOW_V4L1=y +CONFIG_VIDEO_AU0828=m +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BTCX=m +CONFIG_VIDEO_BWQCAM=m +CONFIG_VIDEO_CAFE_CCIC=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_CPIA_PP=m +CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_CS5345=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_CX18=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_CX23885=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_ALSA=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_EM28XX_ALSA=m +CONFIG_VIDEO_EM28XX_DVB=m +CONFIG_VIDEO_FB_IVTV=m +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_IR_I2C=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_M52790=m +CONFIG_VIDEO_MEDIA=m +CONFIG_VIDEO_MEYE=m +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_MXB=m +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_VIDEO_PMS=m +CONFIG_VIDEO_PVRUSB2=m +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_PVRUSB2_DVB=y +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA7111=m +CONFIG_VIDEO_SAA7114=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_ALSA=m +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_SAA717X=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_SH_MOBILE_CEU=m +CONFIG_VIDEO_STRADIS=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TDA9875=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_V4L1=m +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=m +CONFIG_VIDEO_V4L2_COMMON=m +CONFIG_VIDEO_VIVI=m +CONFIG_VIDEO_VP27SMPX=m +CONFIG_VIDEO_VPX3220=m +CONFIG_VIDEO_W9966=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_ZR36060=m +CONFIG_VIRTIO=m +CONFIG_VIRTIO_BALLOON=m +CONFIG_VIRTIO_BLK=m +CONFIG_VIRTIO_CONSOLE=m +CONFIG_VIRTIO_NET=m +CONFIG_VIRTIO_PCI=m +CONFIG_VIRTIO_RING=m +CONFIG_VIRTUALIZATION=y +CONFIG_VIRT_TO_BUS=y +CONFIG_VITESSE_PHY=m +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_VLSI_FIR=m +CONFIG_VM86=y +CONFIG_VMI=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VORTEX=m +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_VXFS_FS=m +CONFIG_W1=m +CONFIG_W1_CON=y +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_GPIO=m +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_SLAVE_BQ27000=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +# CONFIG_W1_SLAVE_DS2438 is not set +CONFIG_W1_SLAVE_DS2760=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_THERM=m +CONFIG_W83627HF_WDT=m +CONFIG_W83697HF_WDT=m +CONFIG_W83697UG_WDT=m +CONFIG_W83877F_WDT=m +CONFIG_W83977F_WDT=m +CONFIG_WAFER_WDT=m +CONFIG_WAN=y +CONFIG_WANXL=m +CONFIG_WAN_ROUTER=m +CONFIG_WAN_ROUTER_DRIVERS=m +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +CONFIG_WAVELAN=m +CONFIG_WD80x3=m +CONFIG_WDT=m +CONFIG_WDTPCI=m +CONFIG_WDT_501=y +CONFIG_WDT_501_PCI=y +CONFIG_WINBOND_840=m +CONFIG_WINBOND_FIR=m +CONFIG_WIRELESS=y +CONFIG_WIRELESS_ACX=m +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +# CONFIG_WIRELESS_OLD_REGULATORY is not set +CONFIG_WLAN_80211=y +CONFIG_WLAN_PRE80211=y +CONFIG_X25=m +CONFIG_X25_ASY=m +CONFIG_X86=y +CONFIG_X86_32=y +CONFIG_X86_32_SMP=y +# CONFIG_X86_64 is not set +CONFIG_X86_ACPI_CPUFREQ=y +# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set +CONFIG_X86_APM_BOOT=y +CONFIG_X86_BIOS_REBOOT=y +CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y +CONFIG_X86_BSWAP=y +CONFIG_X86_CHECK_BIOS_CORRUPTION=y +CONFIG_X86_CMPXCHG=y +CONFIG_X86_CPU=y +CONFIG_X86_CPUFREQ_NFORCE2=y +CONFIG_X86_CPUID=m +# CONFIG_X86_ELAN is not set +CONFIG_X86_FIND_SMP_CONFIG=y +CONFIG_X86_GENERIC=y +# CONFIG_X86_GENERICARCH is not set +CONFIG_X86_GX_SUSPMOD=y +CONFIG_X86_HT=y +CONFIG_X86_INTEL_USERCOPY=y +CONFIG_X86_INVLPG=y +CONFIG_X86_IO_APIC=y +CONFIG_X86_L1_CACHE_SHIFT=7 +CONFIG_X86_LOCAL_APIC=y +CONFIG_X86_LONGHAUL=y +CONFIG_X86_LONGRUN=y +# CONFIG_X86_LPIA is not set +# CONFIG_X86_MCE is not set +CONFIG_X86_MINIMUM_CPU_FAMILY=4 +CONFIG_X86_MPPARSE=y +CONFIG_X86_MSR=m +CONFIG_X86_P4_CLOCKMOD=m +# CONFIG_X86_PAT is not set +CONFIG_X86_PC=y +CONFIG_X86_PM_TIMER=y +CONFIG_X86_POPAD_OK=y +CONFIG_X86_POWERNOW_K6=y +CONFIG_X86_POWERNOW_K7=y +CONFIG_X86_POWERNOW_K7_ACPI=y +CONFIG_X86_POWERNOW_K8=y +CONFIG_X86_POWERNOW_K8_ACPI=y +CONFIG_X86_PPRO_FENCE=y +# CONFIG_X86_PTDUMP is not set +# CONFIG_X86_RDC321X is not set +CONFIG_X86_REBOOTFIXUPS=y +CONFIG_X86_RESERVE_LOW_64K=y +CONFIG_X86_SMP=y +CONFIG_X86_SPEEDSTEP_CENTRINO=y +CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y +CONFIG_X86_SPEEDSTEP_ICH=y +CONFIG_X86_SPEEDSTEP_LIB=y +CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK=y +CONFIG_X86_SPEEDSTEP_SMI=y +CONFIG_X86_TRAMPOLINE=y +# CONFIG_X86_VERBOSE_BOOTUP is not set +# CONFIG_X86_VOYAGER is not set +# CONFIG_X86_VSMP is not set +CONFIG_X86_WP_WORKS_OK=y +CONFIG_X86_XADD=y +CONFIG_XFRM=y +CONFIG_XFRM_IPCOMP=m +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_XFRM_USER=m +# CONFIG_XFS_DEBUG is not set +CONFIG_XFS_FS=m +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_QUOTA=y +CONFIG_XFS_RT=y +CONFIG_XOR_BLOCKS=m +CONFIG_YAM=m +CONFIG_YELLOWFIN=m +CONFIG_YENTA=m +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_ZEROPLUS_FF=m +CONFIG_ZISOFS=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZNET=m +CONFIG_ZONE_DMA=y +# CONFIG_ZONE_DMA32 is not set +CONFIG_ZONE_DMA_FLAG=1 --- linux-2.6.28.orig/debian/config/armel/config.imx51 +++ linux-2.6.28/debian/config/armel/config.imx51 @@ -0,0 +1,1717 @@ +# +# Config options for config.imx51 automatically generated by splitconfig.pl +# +CONFIG_ACT200L_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_AIO=y +# CONFIG_APM_EMULATION is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IXP4XX is not set +CONFIG_ARCH_MTD_XIP=y +# CONFIG_ARCH_MX2 is not set +# CONFIG_ARCH_MX3 is not set +CONFIG_ARCH_MX51=y +CONFIG_ARCH_MXC=y +CONFIG_ARCH_MXC_CANONICAL=y +CONFIG_ARCH_MXC_HAS_NFC_V3=y +CONFIG_ARCH_MXC_HAS_NFC_V3_2=y +# CONFIG_ARCH_VERSATILE is not set +CONFIG_ARM_THUMB=y +# CONFIG_ARM_THUMBEE is not set +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_ATA=y +# CONFIG_ATALK is not set +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_OVER_ETH=m +CONFIG_ATA_SFF=y +CONFIG_AUFS=m +# CONFIG_AUFS_BRANCH_MAX_1023 is not set +CONFIG_AUFS_BRANCH_MAX_127=y +# CONFIG_AUFS_BRANCH_MAX_32767 is not set +# CONFIG_AUFS_BRANCH_MAX_511 is not set +# CONFIG_AUFS_BR_NFS is not set +CONFIG_AUFS_BR_XFS=y +# CONFIG_AUFS_COMPAT is not set +# CONFIG_AUFS_DEBUG is not set +CONFIG_AUFS_DENY_WRITE_ACCESS_PATCH=y +# CONFIG_AUFS_DLGT is not set +CONFIG_AUFS_EXPORT=y +# CONFIG_AUFS_FSYNC_SUPER_PATCH is not set +CONFIG_AUFS_HINOTIFY=y +CONFIG_AUFS_HIN_OR_DLGT=y +CONFIG_AUFS_HIN_OR_FUSE=y +CONFIG_AUFS_LHASH_PATCH=y +# CONFIG_AUFS_PUT_FILP_PATCH is not set +# CONFIG_AUFS_ROBR is not set +CONFIG_AUFS_RR_SQUASHFS=y +CONFIG_AUFS_SEC_PERM_PATCH=y +CONFIG_AUFS_SHWH=y +CONFIG_AUFS_SPLICE_PATCH=y +CONFIG_AUFS_STAT=y +# CONFIG_AUFS_UNIONFS22_PATCH is not set +# CONFIG_AUFS_UNIONFS23_PATCH is not set +# CONFIG_AUFS_WORKAROUND_FUSE is not set +CONFIG_AUTOFS4_FS=m +# CONFIG_B43 is not set +# CONFIG_B43LEGACY is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +# CONFIG_BACKLIGHT_CORGI is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_MXC=y +CONFIG_BACKLIGHT_MXC_MC13892=y +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_BATTERY_BQ27x00 is not set +# CONFIG_BATTERY_DS2760 is not set +CONFIG_BINFMT_AOUT=m +CONFIG_BINFMT_MISC=m +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DM=m +CONFIG_BLK_DEV_DM_BBR=m +CONFIG_BLK_DEV_INTEGRITY=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_MD=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM_SIZE=65535 +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_BLK_DEV_UB=m +CONFIG_BONDING=m +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BOUNCE=y +CONFIG_BRIDGE=m +CONFIG_BRIDGE_NETFILTER=y +# CONFIG_BRIDGE_NF_EBTABLES is not set +# CONFIG_BROADCOM_PHY is not set +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_BT=m +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBTSDIO=m +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HIDP=m +CONFIG_BT_L2CAP=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_SCO=m +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_CFG80211=m +CONFIG_CHR_DEV_SCH=m +CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_ST=m +# CONFIG_CICADA_PHY is not set +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +CONFIG_CIFS_POSIX=y +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_UPCALL is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +CONFIG_CIFS_XATTR=y +CONFIG_CLS_U32_MARK=y +CONFIG_CLS_U32_PERF=y +CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw rootfstype=jffs2 ip=off" +CONFIG_COMPAT_BRK=y +CONFIG_CONFIGFS_FS=m +CONFIG_CONNECTOR=y +# CONFIG_CONTEXT_SWITCH_TRACER is not set +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +# CONFIG_CPU_ARM926T is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_DEBUG is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_GOV_ONDEMAND=m +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_IMX=y +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_HAS_ASID=y +# CONFIG_CPU_ICACHE_DISABLE is not set +CONFIG_CPU_PABRT_IFAR=y +CONFIG_CPU_TLB_V7=y +# CONFIG_CPU_V6 is not set +CONFIG_CPU_V7=y +CONFIG_CRAMFS=y +CONFIG_CRC16=y +CONFIG_CRC7=m +CONFIG_CRC_CCITT=m +CONFIG_CRC_ITU_T=m +CONFIG_CRC_T10DIF=y +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_FIPS=y +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_HASH=m +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_HMAC=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_LZO=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SEQIV=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_XTS=m +CONFIG_DAB=y +# CONFIG_DAVICOM_PHY is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_ERRORS is not set +CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_LL is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SG is not set +CONFIG_DEBUG_SHIRQ=y +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_USER is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DECNET is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_BIC is not set +CONFIG_DEFAULT_CFQ=y +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_HTCP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_DEFAULT_RENO is not set +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_WESTWOOD is not set +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +# CONFIG_DMADEVICES is not set +CONFIG_DMA_ZONE_SIZE=64 +CONFIG_DM_CRYPT=m +CONFIG_DM_DELAY=m +CONFIG_DM_LOOP=m +CONFIG_DM_MIRROR=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_RAID45=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_UEVENT=y +CONFIG_DM_ZERO=m +CONFIG_DONGLE=y +CONFIG_DUMMY=m +CONFIG_DVB_AF9013=m +# CONFIG_DVB_AU8522 is not set +CONFIG_DVB_B2C2_FLEXCOP=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set +CONFIG_DVB_B2C2_FLEXCOP_USB=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_CAPTURE_DRIVERS=y +CONFIG_DVB_CORE=m +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +# CONFIG_DVB_DRX397XD is not set +# CONFIG_DVB_DUMMY_FE is not set +# CONFIG_DVB_FE_CUSTOMISE is not set +# CONFIG_DVB_ISL6405 is not set +CONFIG_DVB_ISL6421=m +# CONFIG_DVB_L64781 is not set +CONFIG_DVB_LGDT330X=m +# CONFIG_DVB_LGS8GL5 is not set +CONFIG_DVB_LNBP21=m +CONFIG_DVB_MT312=m +CONFIG_DVB_MT352=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_NXT6000=m +# CONFIG_DVB_OR51132 is not set +# CONFIG_DVB_OR51211 is not set +CONFIG_DVB_PLL=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_S5H1411=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_SI21XX=m +CONFIG_DVB_SIANO_SMS1XXX=m +CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS=y +# CONFIG_DVB_SP8870 is not set +# CONFIG_DVB_SP887X is not set +CONFIG_DVB_STB6000=m +CONFIG_DVB_STV0288=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_STV0299=m +# CONFIG_DVB_TDA10021 is not set +CONFIG_DVB_TDA10023=m +CONFIG_DVB_TDA10048=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +# CONFIG_DVB_TUA6100 is not set +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_USB=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_CINERGY_T2=m +CONFIG_DVB_USB_CXUSB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_DIBUSB_MB=m +CONFIG_DVB_USB_DIBUSB_MB_FAULTY=y +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_DW2102=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_VES1820=m +# CONFIG_DVB_VES1X93 is not set +CONFIG_DVB_ZL10353=m +# CONFIG_ECONET is not set +CONFIG_ECRYPT_FS=m +CONFIG_EEPROM_93CX6=m +CONFIG_EMBEDDED=y +# CONFIG_ENC28J60 is not set +CONFIG_EQUALIZER=m +CONFIG_ESI_DONGLE=m +CONFIG_EXPORTFS=m +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT3_FS_SECURITY=y +# CONFIG_EXT4DEV_COMPAT is not set +CONFIG_EXT4_FS=m +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_EXT4_FS_XATTR=y +CONFIG_FAT_FS=y +# CONFIG_FAULT_INJECTION is not set +CONFIG_FB=y +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MODE_HELPERS is not set +CONFIG_FB_MXC=y +CONFIG_FB_MXC_CH7026=y +CONFIG_FB_MXC_EPSON_VGA_SYNC_PANEL=y +CONFIG_FB_MXC_SYNC_PANEL=y +CONFIG_FB_MXC_TVOUT_TVE=y +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_UVESA is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_FEC=y +# CONFIG_FEC2 is not set +CONFIG_FIB_RULES=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_FONTS=y +# CONFIG_FONT_10x18 is not set +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +CONFIG_FONT_8x16=y +# CONFIG_FONT_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_SUN8x16 is not set +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FREEZER=y +CONFIG_FS_UNIONFS=m +CONFIG_FTL=m +# CONFIG_FUNCTION_TRACER is not set +CONFIG_FUSE_FS=m +CONFIG_GACT_PROB=y +CONFIG_GARP=m +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_GENERIC_GPIO is not set +CONFIG_GENERIC_TIME=y +# CONFIG_GFS2_FS is not set +CONFIG_GIRBIL_DONGLE=m +CONFIG_HAS_TLS_REG=y +CONFIG_HFSPLUS_FS=m +CONFIG_HFS_FS=m +CONFIG_HID=y +# CONFIG_HIDRAW is not set +CONFIG_HID_A4TECH=m +CONFIG_HID_APPLE=m +CONFIG_HID_BELKIN=m +CONFIG_HID_BRIGHT=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +# CONFIG_HID_COMPAT is not set +CONFIG_HID_CYPRESS=m +# CONFIG_HID_DEBUG is not set +CONFIG_HID_DELL=m +CONFIG_HID_EZKEY=m +CONFIG_HID_GYRATION=m +CONFIG_HID_LOGITECH=m +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_PANTHERLORD=m +CONFIG_HID_PETALYNX=m +# CONFIG_HID_PID is not set +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_HID_SUNPLUS=m +CONFIG_HID_SUPPORT=y +CONFIG_HIGH_RES_TIMERS=y +# CONFIG_HOSTAP is not set +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +# CONFIG_HWMON_VID is not set +CONFIG_HW_RANDOM=y +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_MXC=y +CONFIG_I2C_MXC_HS=y +CONFIG_I2C_MXC_SELECT1=y +CONFIG_I2C_MXC_SELECT2=y +# CONFIG_I2C_MXC_SELECT3 is not set +# CONFIG_I2C_TINY_USB is not set +# CONFIG_ICPLUS_PHY is not set +# CONFIG_IDE is not set +CONFIG_IFB=m +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET_AH=m +CONFIG_INET_DCCP_DIAG=m +CONFIG_INET_DIAG=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_LRO=m +CONFIG_INET_TCP_DIAG=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INFTL=m +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_FF_MEMLESS is not set +CONFIG_INPUT_KEYBOARD=y +# CONFIG_INPUT_MISC is not set +CONFIG_INPUT_MOUSE=y +CONFIG_INPUT_MOUSEDEV=m +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_POLLDEV=m +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_SECURITY=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_POWEROFF=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPV6=m +CONFIG_IPV6_MIP6=m +# CONFIG_IPV6_MROUTE is not set +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_IPV6_SIT=m +# CONFIG_IPV6_SUBTREES is not set +CONFIG_IPV6_TUNNEL=m +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_DCCP=m +CONFIG_IP_DCCP_ACKVEC=y +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_IP_DCCP_TFRC_LIB=m +CONFIG_IP_MROUTE=y +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_SECURITY=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_RARP is not set +CONFIG_IP_SCTP=m +CONFIG_IP_VS=m +CONFIG_IP_VS_DEBUG=y +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_IPV6=y +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_AH_ESP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_TAB_BITS=12 +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_WRR=m +CONFIG_IRCOMM=m +CONFIG_IRDA=m +CONFIG_IRDA_CACHE_LAST_LSAP=y +# CONFIG_IRDA_DEBUG is not set +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_ULTRA=y +CONFIG_IRLAN=m +# CONFIG_IRNET is not set +# CONFIG_IRQSOFF_TRACER is not set +CONFIG_IRTTY_SIR=m +# CONFIG_ISCSI_TCP is not set +CONFIG_ISO9660_FS=m +CONFIG_JBD2=m +# CONFIG_JBD2_DEBUG is not set +# CONFIG_JBD_DEBUG is not set +CONFIG_JFFS2_FS=m +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFS_DEBUG is not set +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +# CONFIG_JFS_STATISTICS is not set +CONFIG_JOLIET=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_KEXEC is not set +CONFIG_KEYBOARD_ATKBD=m +# CONFIG_KEYBOARD_LKKBD is not set +CONFIG_KEYBOARD_MXC=y +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +# CONFIG_KGDB is not set +CONFIG_KINGSUN_DONGLE=m +# CONFIG_KPROBES is not set +CONFIG_KS959_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +# CONFIG_LAPB is not set +CONFIG_LATENCYTOP=y +CONFIG_LBD=y +# CONFIG_LCD_CLASS_DEVICE is not set +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_MC13892=y +# CONFIG_LEDS_PCA9532 is not set +# CONFIG_LEDS_PCA955X is not set +CONFIG_LEDS_TRIGGERS=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set +# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set +# CONFIG_LEDS_TRIGGER_TIMER is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=16 +CONFIG_LIBCRC32C=m +CONFIG_LIBERTAS=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_SDIO=m +CONFIG_LIBERTAS_THINFIRM=m +CONFIG_LIBERTAS_THINFIRM_USB=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIRC_ATIUSB=m +CONFIG_LIRC_BT829=m +CONFIG_LIRC_CMDIR=m +CONFIG_LIRC_DEV=m +# CONFIG_LIRC_GPIO is not set +CONFIG_LIRC_I2C=m +CONFIG_LIRC_IGORPLUGUSB=m +CONFIG_LIRC_IMON=m +CONFIG_LIRC_IT87=m +CONFIG_LIRC_MCEUSB=m +CONFIG_LIRC_MCEUSB2=m +# CONFIG_LIRC_PARALLEL is not set +CONFIG_LIRC_SASEM=m +CONFIG_LIRC_SERIAL=m +CONFIG_LIRC_SERIAL_IGOR=m +CONFIG_LIRC_SIR=m +CONFIG_LIRC_STREAMZAP=m +CONFIG_LIRC_TTUSBIR=m +CONFIG_LITELINK_DONGLE=m +CONFIG_LLC=m +# CONFIG_LLC2 is not set +# CONFIG_LMPCM_USB is not set +CONFIG_LOCKD=m +# CONFIG_LOCK_STAT is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGO is not set +CONFIG_LSF=y +# CONFIG_LXT_PHY is not set +CONFIG_MA600_DONGLE=m +CONFIG_MAC80211=m +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +# CONFIG_MAC80211_HWSIM is not set +CONFIG_MAC80211_LEDS=y +# CONFIG_MAC80211_MESH is not set +CONFIG_MAC80211_RC_DEFAULT="pid" +# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set +CONFIG_MAC80211_RC_DEFAULT_PID=y +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_PID=y +CONFIG_MACH_MX51_3DS=y +CONFIG_MACH_MX51_BABBAGE=y +CONFIG_MACVLAN=m +# CONFIG_MARKERS is not set +# CONFIG_MARVELL_PHY is not set +CONFIG_MCP2120_DONGLE=m +CONFIG_MCS_FIR=m +# CONFIG_MDIO_BITBANG is not set +CONFIG_MD_FAULTY=m +CONFIG_MD_LINEAR=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID5_RESHAPE=y +CONFIG_MEDIA_ATTACH=y +CONFIG_MEDIA_TUNER=m +CONFIG_MEDIA_TUNER_CUSTOMIZE=y +# CONFIG_MEDIA_TUNER_MT2060 is not set +# CONFIG_MEDIA_TUNER_MT20XX is not set +# CONFIG_MEDIA_TUNER_MT2131 is not set +# CONFIG_MEDIA_TUNER_MT2266 is not set +# CONFIG_MEDIA_TUNER_MXL5005S is not set +# CONFIG_MEDIA_TUNER_MXL5007T is not set +# CONFIG_MEDIA_TUNER_QT1010 is not set +# CONFIG_MEDIA_TUNER_SIMPLE is not set +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA8290=m +# CONFIG_MEDIA_TUNER_TDA9887 is not set +# CONFIG_MEDIA_TUNER_TEA5761 is not set +# CONFIG_MEDIA_TUNER_TEA5767 is not set +# CONFIG_MEDIA_TUNER_XC2028 is not set +# CONFIG_MEDIA_TUNER_XC5000 is not set +# CONFIG_MINIX_FS is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_MMC=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_IMX_ESDHCI=y +# CONFIG_MMC_IMX_ESDHCI_PIO_MODE is not set +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_SPI is not set +# CONFIG_MMC_TEST is not set +# CONFIG_MMC_UNSAFE_RESUME is not set +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_BCM5974=m +# CONFIG_MOUSE_PS2 is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +CONFIG_MSDOS_FS=y +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_CFI is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_MXC_FORCE_CE is not set +# CONFIG_MTD_NAND_MXC_SWECC is not set +CONFIG_MTD_NAND_MXC_V3=y +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_ONENAND=m +# CONFIG_MTD_ONENAND_2X_PROGRAM is not set +# CONFIG_MTD_ONENAND_GENERIC is not set +# CONFIG_MTD_ONENAND_OTP is not set +# CONFIG_MTD_ONENAND_SIM is not set +# CONFIG_MTD_ONENAND_VERIFY_WRITE is not set +CONFIG_MTD_OOPS=m +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_DEBUG is not set +# CONFIG_MTD_UBI_GLUEBI is not set +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MX51_OPTIONS=y +CONFIG_MXC_BLUETOOTH=y +CONFIG_MXC_CAMERA_OV3640=m +CONFIG_MXC_IPU=y +CONFIG_MXC_IPU_PRP_ENC=m +CONFIG_MXC_IPU_PRP_VF_SDC=m +CONFIG_MXC_IPU_V3=y +# CONFIG_MXC_IRQ_PRIOR is not set +CONFIG_MXC_MC13892_ADC=y +CONFIG_MXC_MC13892_BATTERY=y +CONFIG_MXC_MC13892_CONNECTIVITY=y +CONFIG_MXC_MC13892_LIGHT=y +CONFIG_MXC_MC13892_POWER=y +CONFIG_MXC_MC13892_RTC=y +# CONFIG_MXC_NAND_LOW_LEVEL_ERASE is not set +CONFIG_MXC_PMIC=y +CONFIG_MXC_PMIC_I2C=y +CONFIG_MXC_PMIC_MC13892=y +CONFIG_MXC_PMIC_SPI=y +CONFIG_MXC_SAHARA=y +# CONFIG_MXC_SAHARA_POLL_MODE is not set +CONFIG_MXC_SAHARA_USER_MODE=y +CONFIG_MXC_SDMA_API=y +CONFIG_MXC_SECURITY_SCC2=y +CONFIG_MXC_TZIC=y +CONFIG_MXC_VPU=y +# CONFIG_MXC_VPU_DEBUG is not set +CONFIG_MXC_VPU_IRAM=y +CONFIG_MXC_WATCHDOG=y +# CONFIG_NAMESPACES is not set +# CONFIG_NEON is not set +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +# CONFIG_NETDEV_1000 is not set +CONFIG_NETFILTER=y +CONFIG_NETFILTER_ADVANCED=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +# CONFIG_NETFILTER_TPROXY is not set +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=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_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=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_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set +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_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set +# CONFIG_NETFILTER_XT_TARGET_TRACE is not set +CONFIG_NETLABEL=y +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NETWORK_SECMARK=y +# CONFIG_NET_9P is not set +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_CLS=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_FLOW=m +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_IND=y +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_NET_IPIP=m +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +# CONFIG_NET_PKTGEN is not set +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_FIFO=y +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_HTB=m +# CONFIG_NET_SCH_INGRESS is not set +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NEW_LEDS=y +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_FS=m +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFTL=m +# CONFIG_NFTL_RW is not set +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_PROTO_DCCP=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_PROTO_DCCP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_SCTP=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NL80211=y +CONFIG_NLS=y +CONFIG_NLS_ASCII=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_737=m +CONFIG_NLS_CODEPAGE_775=m +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_CODEPAGE_852=m +CONFIG_NLS_CODEPAGE_855=m +CONFIG_NLS_CODEPAGE_857=m +CONFIG_NLS_CODEPAGE_860=m +CONFIG_NLS_CODEPAGE_861=m +CONFIG_NLS_CODEPAGE_862=m +CONFIG_NLS_CODEPAGE_863=m +CONFIG_NLS_CODEPAGE_864=m +CONFIG_NLS_CODEPAGE_865=m +CONFIG_NLS_CODEPAGE_866=m +CONFIG_NLS_CODEPAGE_869=m +CONFIG_NLS_CODEPAGE_874=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=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_8=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=y +CONFIG_NO_HZ=y +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_FS=m +CONFIG_NTFS_RW=y +# CONFIG_OABI_COMPAT is not set +CONFIG_OLD_BELKIN_DONGLE=m +# CONFIG_OPEN_TRACER is not set +CONFIG_OPROFILE=m +CONFIG_OPROFILE_ARMV7=y +# CONFIG_P54_COMMON is not set +CONFIG_PACKET_MMAP=y +# CONFIG_PANTHERLORD_FF is not set +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_PATA_FSL=y +CONFIG_PATA_PLATFORM=m +# CONFIG_PCI_SYSCALL is not set +# CONFIG_PDA_POWER is not set +# CONFIG_PHONET is not set +CONFIG_PHYLIB=m +CONFIG_PM=y +# CONFIG_PMIC_DA903X is not set +# CONFIG_PM_DEBUG is not set +# CONFIG_PM_DISABLE_CONSOLE is not set +CONFIG_PM_SLEEP=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +CONFIG_PPP=m +CONFIG_PPPOE=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_SYNC_TTY=m +CONFIG_PRINTK_TIME=y +CONFIG_PROC_EVENTS=y +CONFIG_PROFILING=y +# CONFIG_PROVE_LOCKING is not set +CONFIG_QC_USB=m +# CONFIG_QSEMI_PHY is not set +CONFIG_QUOTACTL=y +CONFIG_RADIO_ADAPTERS=y +CONFIG_RAID_ATTRS=m +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_REALTEK_PHY is not set +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_BQ24022 is not set +# CONFIG_REGULATOR_DEBUG is not set +# CONFIG_REGULATOR_FIXED_VOLTAGE is not set +CONFIG_REGULATOR_MC13892=y +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_FS_XATTR is not set +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_RELAY=y +CONFIG_RFD_FTL=m +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +CONFIG_RFKILL_LEDS=y +# CONFIG_ROMFS_FS is not set +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_RT2500USB=m +CONFIG_RT2X00=m +# CONFIG_RT2X00_DEBUG is not set +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_CRYPTO=y +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_LEDS=y +CONFIG_RT2X00_LIB_RFKILL=y +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT73USB=m +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DEBUG is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_MXC_V2 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_V3020 is not set +# CONFIG_RTC_DRV_X1205 is not set +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_MC13892=y +CONFIG_RTL8187=m +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_RXKAD=m +# CONFIG_SATA_MV is not set +# CONFIG_SATA_PMP is not set +CONFIG_SCC_DEBUG=y +CONFIG_SCHEDSTATS=y +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHED_TRACER is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y +# CONFIG_SCSI_SAS_LIBSAS is not set +CONFIG_SCSI_SCAN_ASYNC=y +# CONFIG_SCSI_SPI_ATTRS is not set +CONFIG_SCSI_TGT=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_HMAC_MD5=y +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +# CONFIG_SDIO_UART is not set +CONFIG_SDIO_UNIFI_FS=m +CONFIG_SDMA_IRAM=y +CONFIG_SDMA_IRAM_SIZE=0x1000 +CONFIG_SECURITY=y +CONFIG_SECURITYFS=y +CONFIG_SECURITY_APPARMOR=y +CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 +CONFIG_SECURITY_APPARMOR_DISABLE=y +CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=32768 +CONFIG_SECURITY_FILE_CAPABILITIES=y +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +# CONFIG_SECURITY_ROOTPLUG is not set +# CONFIG_SECURITY_SELINUX is not set +# CONFIG_SECURITY_SMACK is not set +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADCXX is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7473 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_EEPROM 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_IBMAEM is not set +# CONFIG_SENSORS_IBMPEX is not set +CONFIG_SENSORS_ISL29003=y +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_MAX1111 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_SENSORS_W83627HF 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_SERIAL_8250 is not set +# CONFIG_SERIAL_IMX is not set +CONFIG_SERIAL_MXC=y +CONFIG_SERIAL_MXC_CONSOLE=y +CONFIG_SERIO=m +CONFIG_SERIO_LIBPS2=m +# CONFIG_SERIO_RAW is not set +CONFIG_SERIO_SERPORT=m +CONFIG_SIGMATEL_FIR=m +# CONFIG_SLAB is not set +CONFIG_SLABINFO=y +CONFIG_SLHC=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_MODE_SLIP6=y +CONFIG_SLIP_SMART=y +CONFIG_SLUB=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_SMC91X is not set +CONFIG_SMSC911X=y +# CONFIG_SMSC_PHY is not set +CONFIG_SND=y +CONFIG_SND_ARM=y +CONFIG_SND_BTSCO=m +# CONFIG_SND_DEBUG is not set +CONFIG_SND_DRIVERS=y +CONFIG_SND_DUMMY=m +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_MPU401=m +CONFIG_SND_MPU401_UART=m +CONFIG_SND_MTPAV=m +CONFIG_SND_MXC_SOC=y +CONFIG_SND_MXC_SOC_IRAM=y +CONFIG_SND_MXC_SOC_SSI=y +CONFIG_SND_MXC_SPDIF=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_PCM=y +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_RAWMIDI=m +CONFIG_SND_SEQUENCER=m +# CONFIG_SND_SEQUENCER_OSS is not set +# CONFIG_SND_SEQ_DUMMY is not set +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_SOC=y +# CONFIG_SND_SOC_ALL_CODECS is not set +CONFIG_SND_SOC_IMX_3STACK_SGTL5000=y +CONFIG_SND_SOC_SGTL5000=y +CONFIG_SND_SPI=y +# CONFIG_SND_SUPPORT_OLD_API is not set +CONFIG_SND_TIMER=y +CONFIG_SND_USB=y +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_CAIAQ is not set +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_VERBOSE_PROCFS is not set +CONFIG_SND_VIRMIDI=m +# CONFIG_SOC_CAMERA is not set +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_SOUND=y +CONFIG_SOUND_OSS_CORE=y +# CONFIG_SOUND_PRIME is not set +CONFIG_SPI=y +# CONFIG_SPI_AT25 is not set +CONFIG_SPI_BITBANG=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y +CONFIG_SPI_MXC=y +CONFIG_SPI_MXC_SELECT1=y +# CONFIG_SPI_MXC_SELECT2 is not set +# CONFIG_SPI_MXC_SELECT3 is not set +# CONFIG_SPI_MXC_TEST_LOOPBACK is not set +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_SQUASHFS=m +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +CONFIG_SSFDC=m +CONFIG_STACKTRACE=y +# CONFIG_STACK_TRACER is not set +# CONFIG_STANDALONE is not set +CONFIG_STP=m +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_SYN_COOKIES=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set +CONFIG_TASKSTATS=y +# CONFIG_TASK_DELAY_ACCT is not set +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_TASK_XACCT=y +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +# CONFIG_TCP_CONG_HSTCP is not set +CONFIG_TCP_CONG_HTCP=m +# CONFIG_TCP_CONG_HYBLA is not set +# CONFIG_TCP_CONG_ILLINOIS is not set +# CONFIG_TCP_CONG_LP is not set +# CONFIG_TCP_CONG_SCALABLE is not set +# CONFIG_TCP_CONG_VEGAS is not set +# CONFIG_TCP_CONG_VENO is not set +CONFIG_TCP_CONG_WESTWOOD=m +# CONFIG_TCP_CONG_YEAH is not set +CONFIG_TEKRAM_DONGLE=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_TEXTSEARCH_KMP=m +CONFIG_THERMAL_HWMON=y +# CONFIG_THRUSTMASTER_FF is not set +CONFIG_TICK_ONESHOT=y +# CONFIG_TIMER_STATS is not set +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set +CONFIG_TOIM3232_DONGLE=m +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +CONFIG_TOUCHSCREEN_MXC=y +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_TTPCI_EEPROM is not set +CONFIG_TUN=m +CONFIG_UBIFS_FS=m +CONFIG_UBIFS_FS_ADVANCED_COMPR=y +# CONFIG_UBIFS_FS_DEBUG is not set +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_XATTR=y +CONFIG_UBIFS_FS_ZLIB=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +CONFIG_USB=y +# CONFIG_USBPCWATCHDOG is not set +CONFIG_USB_ACM=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_APPLEIR=m +CONFIG_USB_ARC=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +CONFIG_USB_ARMLINUX=y +CONFIG_USB_ATMEL=m +CONFIG_USB_BELKIN=y +CONFIG_USB_BERRY_CHARGE=m +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_CATC=m +CONFIG_USB_CDC_COMPOSITE=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_DABUSB=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +CONFIG_USB_DSBR=m +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_EHCI_ARC=y +CONFIG_USB_EHCI_ARC_H1=y +CONFIG_USB_EHCI_ARC_H2=y +CONFIG_USB_EHCI_ARC_OTG=y +CONFIG_USB_EHCI_FSL_UTMI=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +CONFIG_USB_EMI26=m +CONFIG_USB_EMI62=m +CONFIG_USB_EPSON2888=y +CONFIG_USB_ET61X251=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_EZUSB=y +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_GADGET=y +CONFIG_USB_GADGETFS=m +# CONFIG_USB_GADGET_AMD5536UDC is not set +CONFIG_USB_GADGET_ARC=y +CONFIG_USB_GADGET_ARC_OTG=y +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +CONFIG_USB_GADGET_FSL_UTMI=y +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C2410 is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GSPCA=m +# CONFIG_USB_GSPCA_CONEX is not set +# CONFIG_USB_GSPCA_ETOMS is not set +# CONFIG_USB_GSPCA_FINEPIX is not set +# CONFIG_USB_GSPCA_MARS is not set +# CONFIG_USB_GSPCA_OV519 is not set +# CONFIG_USB_GSPCA_PAC207 is not set +# CONFIG_USB_GSPCA_PAC7311 is not set +# CONFIG_USB_GSPCA_SONIXB is not set +# CONFIG_USB_GSPCA_SONIXJ is not set +# CONFIG_USB_GSPCA_SPCA500 is not set +# CONFIG_USB_GSPCA_SPCA501 is not set +# CONFIG_USB_GSPCA_SPCA505 is not set +# CONFIG_USB_GSPCA_SPCA506 is not set +# CONFIG_USB_GSPCA_SPCA508 is not set +# CONFIG_USB_GSPCA_SPCA561 is not set +# CONFIG_USB_GSPCA_STK014 is not set +# CONFIG_USB_GSPCA_SUNPLUS is not set +# CONFIG_USB_GSPCA_T613 is not set +# CONFIG_USB_GSPCA_TV8532 is not set +# CONFIG_USB_GSPCA_VC032X is not set +# CONFIG_USB_GSPCA_ZC3XX is not set +CONFIG_USB_G_PRINTER=m +CONFIG_USB_G_SERIAL=m +CONFIG_USB_HID=y +# CONFIG_USB_HIDDEV is not set +CONFIG_USB_HSO=m +# CONFIG_USB_HWA_HCD is not set +CONFIG_USB_IDMOUSE=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_IRDA=m +CONFIG_USB_ISIGHTFW=m +CONFIG_USB_ISP116X_HCD=m +CONFIG_USB_KAWETH=m +CONFIG_USB_KC2190=y +CONFIG_USB_LCD=m +CONFIG_USB_LD=m +CONFIG_USB_LED=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LIBUSUAL=y +# CONFIG_USB_M5602 is not set +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USB_MIDI_GADGET=m +# CONFIG_USB_MON is not set +CONFIG_USB_MR800=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_RNDIS_HOST=m +# CONFIG_USB_NET_RNDIS_WLAN is not set +CONFIG_USB_NET_SMSC95XX=m +CONFIG_USB_NET_ZAURUS=m +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OV511_NEW is not set +CONFIG_USB_PEGASUS=m +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_PRINTER=m +CONFIG_USB_R8A66597_HCD=m +CONFIG_USB_RIO500=m +CONFIG_USB_RTL8150=m +CONFIG_USB_S2255=m +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IPW=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_IUU=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_MOTOROLA=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +CONFIG_USB_SERIAL_SAFE_PADDED=y +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SEVSEG=m +CONFIG_USB_SI470X=m +CONFIG_USB_SISUSBVGA=m +CONFIG_USB_SISUSBVGA_CON=y +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SN9C102=m +# CONFIG_USB_STATIC_IRAM is not set +CONFIG_USB_STKWEBCAM=m +CONFIG_USB_STORAGE=y +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_CYPRESS_ATACB=y +CONFIG_USB_STORAGE_DATAFAB=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_ONETOUCH=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_USBAT=y +# CONFIG_USB_SUSPEND is not set +CONFIG_USB_TEST=m +CONFIG_USB_TMC=m +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_U132_HCD=m +CONFIG_USB_USBNET=m +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_VST=m +CONFIG_USB_WDM=m +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set +CONFIG_USB_ZC0301=m +CONFIG_USB_ZD1201=m +# CONFIG_USB_ZERO is not set +CONFIG_USB_ZR364XX=m +CONFIG_UTMI_MXC=y +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VETH=m +CONFIG_VFAT_FS=y +CONFIG_VFP=y +CONFIG_VFPv3=y +# CONFIG_VGA_CONSOLE is not set +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_VMALLOC=m +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_ALLOW_V4L1 is not set +# CONFIG_VIDEO_AU0828 is not set +CONFIG_VIDEO_CAPTURE_DRIVERS=y +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_EM28XX_ALSA=m +CONFIG_VIDEO_EM28XX_DVB=m +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_IR_I2C=m +CONFIG_VIDEO_MEDIA=m +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_MXC_CAMERA=m +CONFIG_VIDEO_MXC_IPU_CAMERA=y +CONFIG_VIDEO_MXC_IPU_OUTPUT=y +CONFIG_VIDEO_MXC_OUTPUT=m +CONFIG_VIDEO_PVRUSB2=m +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_PVRUSB2_DVB=y +CONFIG_VIDEO_PVRUSB2_SYSFS=y +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=m +CONFIG_VIDEO_V4L2_COMMON=m +# CONFIG_VIDEO_VIVI is not set +CONFIG_VIDEO_WM8775=m +# CONFIG_VITESSE_PHY is not set +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_W1=m +CONFIG_W1_CON=y +# CONFIG_W1_MASTER_DS2482 is not set +# CONFIG_W1_MASTER_DS2490 is not set +CONFIG_W1_MASTER_MXC=m +# CONFIG_W1_SLAVE_BQ27000 is not set +# CONFIG_W1_SLAVE_DS2433 is not set +CONFIG_W1_SLAVE_DS2438=m +# CONFIG_W1_SLAVE_DS2760 is not set +# CONFIG_W1_SLAVE_SMEM is not set +# CONFIG_W1_SLAVE_THERM is not set +# CONFIG_WAN_ROUTER is not set +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +CONFIG_WIRELESS_OLD_REGULATORY=y +CONFIG_WLAN_80211=y +# CONFIG_X25 is not set +CONFIG_XFRM_IPCOMP=m +CONFIG_XFRM_USER=m +# CONFIG_XFS_DEBUG is not set +CONFIG_XFS_FS=m +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_QUOTA=y +CONFIG_XFS_RT=y +CONFIG_XOR_BLOCKS=m +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +# CONFIG_ZEROPLUS_FF is not set +# CONFIG_ZISOFS is not set +CONFIG_ZLIB_DEFLATE=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZONE_DMA=y +CONFIG_ZONE_DMA_FLAG=1 --- linux-2.6.28.orig/debian/config/armel/config.iop32x +++ linux-2.6.28/debian/config/armel/config.iop32x @@ -0,0 +1,1112 @@ +# +# Config options for config.iop32x automatically generated by splitconfig.pl +# +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_ACENIC is not set +# CONFIG_ACORN_PARTITION is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AF_RXRPC is not set +CONFIG_AIO=y +# CONFIG_AMD8111_ETH is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_APPLICOM is not set +CONFIG_ARCH_IOP32X=y +CONFIG_ARCH_IQ31244=y +CONFIG_ARCH_IQ80321=y +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_MXC is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCNET is not set +# CONFIG_ARM_THUMB is not set +CONFIG_ASK_IP_FIB_HASH=y +CONFIG_ASYNC_CORE=y +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_ATA=y +# CONFIG_ATALK is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_ATA_GENERIC is not set +# CONFIG_ATA_NONSTANDARD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_ATA_PIIX is not set +CONFIG_ATA_SFF=y +# CONFIG_ATL1 is not set +# CONFIG_ATL1E is not set +# CONFIG_ATL2 is not set +CONFIG_AUFS=m +# CONFIG_AUFS_BRANCH_MAX_1023 is not set +CONFIG_AUFS_BRANCH_MAX_127=y +# CONFIG_AUFS_BRANCH_MAX_32767 is not set +# CONFIG_AUFS_BRANCH_MAX_511 is not set +CONFIG_AUFS_BR_NFS=y +CONFIG_AUFS_BR_XFS=y +# CONFIG_AUFS_COMPAT is not set +# CONFIG_AUFS_DEBUG is not set +CONFIG_AUFS_DENY_WRITE_ACCESS_PATCH=y +# CONFIG_AUFS_DLGT is not set +CONFIG_AUFS_EXPORT=y +# CONFIG_AUFS_FSYNC_SUPER_PATCH is not set +CONFIG_AUFS_HINOTIFY=y +CONFIG_AUFS_HIN_OR_DLGT=y +CONFIG_AUFS_HIN_OR_FUSE=y +CONFIG_AUFS_LHASH_PATCH=y +CONFIG_AUFS_PUT_FILP_PATCH=y +# CONFIG_AUFS_ROBR is not set +CONFIG_AUFS_RR_SQUASHFS=y +# CONFIG_AUFS_SEC_PERM_PATCH is not set +CONFIG_AUFS_SHWH=y +CONFIG_AUFS_SPLICE_PATCH=y +CONFIG_AUFS_STAT=y +# CONFIG_AUFS_UNIONFS22_PATCH is not set +# CONFIG_AUFS_UNIONFS23_PATCH is not set +CONFIG_AUFS_WORKAROUND_FUSE=y +# CONFIG_AUTOFS4_FS is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_CMD64X is not set +CONFIG_BLK_DEV_CRYPTOLOOP=m +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_DM=m +# CONFIG_BLK_DEV_DM_BBR is not set +CONFIG_BLK_DEV_GENERIC=m +# CONFIG_BLK_DEV_HPT366 is not set +CONFIG_BLK_DEV_IDECD=m +# CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS is not set +# CONFIG_BLK_DEV_IDEDMA is not set +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_BLK_DEV_IDESCSI is not set +CONFIG_BLK_DEV_IDETAPE=m +# CONFIG_BLK_DEV_IDE_SATA is not set +# CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_BLK_DEV_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_JMICRON is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_MD=m +CONFIG_BLK_DEV_NBD=m +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_OPTI621 is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_PLATFORM is not set +CONFIG_BLK_DEV_RAM_SIZE=8192 +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SL82C105 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_TC86C001 is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_UB is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_BNX2 is not set +# CONFIG_BONDING is not set +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +# CONFIG_BOOT_PRINTK_DELAY is not set +CONFIG_BOOT_TRACER=y +# CONFIG_BRIDGE is not set +# CONFIG_BSD_DISKLABEL is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_BT is not set +# CONFIG_C2PORT is not set +# CONFIG_CASSINI is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_CFG80211 is not set +# CONFIG_CHR_DEV_SCH is not set +CONFIG_CHR_DEV_SG=m +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CIFS is not set +CONFIG_CLS_U32_MARK=y +CONFIG_CLS_U32_PERF=y +CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp cachepolicy=writealloc" +# CONFIG_COMPAT_BRK is not set +CONFIG_CONFIGFS_FS=m +# CONFIG_CONNECTOR is not set +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_PABRT_NOIFAR=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_XSCALE=y +CONFIG_CRAMFS=y +CONFIG_CRC16=m +# CONFIG_CRC7 is not set +# CONFIG_CRC_CCITT is not set +CONFIG_CRC_ITU_T=m +CONFIG_CRC_T10DIF=m +CONFIG_CRYPTO_AEAD2=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ALGAPI=m +CONFIG_CRYPTO_ALGAPI2=m +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +# CONFIG_CRYPTO_AUTHENC is not set +CONFIG_CRYPTO_BLKCIPHER2=m +CONFIG_CRYPTO_BLOWFISH=m +# CONFIG_CRYPTO_CAMELLIA is not set +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +# CONFIG_CRYPTO_CCM is not set +CONFIG_CRYPTO_CRC32C=m +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_DES=m +# CONFIG_CRYPTO_DEV_HIFN_795X is not set +CONFIG_CRYPTO_ECB=m +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_FIPS is not set +# CONFIG_CRYPTO_GCM is not set +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_HASH=m +CONFIG_CRYPTO_HASH2=m +CONFIG_CRYPTO_HMAC=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_LRW=m +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_MANAGER=m +CONFIG_CRYPTO_MANAGER2=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_RNG2=m +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SEQIV is not set +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +# CONFIG_CRYPTO_XTS is not set +# CONFIG_DAB is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_DRIVER is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_GPIO is not set +# CONFIG_DEBUG_ICEDCC is not set +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_LIST is not set +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DECNET is not set +# CONFIG_DEFAULT_AS is not set +CONFIG_DEFAULT_CFQ=y +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_DEVPORT=y +# CONFIG_DL2K is not set +# CONFIG_DLM is not set +CONFIG_DMADEVICES=y +# CONFIG_DMATEST is not set +CONFIG_DMA_ENGINE=y +# CONFIG_DM_CRYPT is not set +# CONFIG_DM_DELAY is not set +# CONFIG_DM_LOOP is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_RAID45 is not set +# CONFIG_DM_SNAPSHOT is not set +# CONFIG_DM_UEVENT is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DRM is not set +# CONFIG_DUMMY is not set +# CONFIG_DVB_CORE is not set +CONFIG_E100=y +CONFIG_E1000=y +# CONFIG_E1000E is not set +# CONFIG_ECONET is not set +CONFIG_ECRYPT_FS=y +# CONFIG_EEPRO100 is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_EFI_PARTITION is not set +CONFIG_EMBEDDED=y +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_EPIC100 is not set +# CONFIG_EQUALIZER is not set +CONFIG_EXPORTFS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4_FS is not set +CONFIG_FAT_FS=y +# CONFIG_FAULT_INJECTION is not set +# CONFIG_FB is not set +# CONFIG_FDDI is not set +# CONFIG_FEALNX is not set +# CONFIG_FIREWIRE is not set +# CONFIG_FIRMWARE_IN_KERNEL is not set +# CONFIG_FORCEDETH is not set +# CONFIG_FREEZER is not set +# CONFIG_FS_UNIONFS is not set +# CONFIG_FTL is not set +# CONFIG_FUNCTION_TRACER is not set +CONFIG_FUSE_FS=y +# CONFIG_FUSION is not set +# CONFIG_GACT_PROB is not set +# CONFIG_GENERIC_CLOCKEVENTS is not set +CONFIG_GENERIC_GPIO=y +# CONFIG_GENERIC_TIME is not set +CONFIG_GPIOLIB=y +# CONFIG_GPIO_BT8XX is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +CONFIG_GPIO_SYSFS=y +# CONFIG_HAMACHI is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_HFS_FS is not set +CONFIG_HID=y +# CONFIG_HIDRAW is not set +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_APPLE is not set +CONFIG_HID_BELKIN=m +CONFIG_HID_BRIGHT=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +# CONFIG_HID_COMPAT is not set +CONFIG_HID_CYPRESS=m +# CONFIG_HID_DEBUG is not set +CONFIG_HID_DELL=m +CONFIG_HID_EZKEY=m +CONFIG_HID_GYRATION=m +CONFIG_HID_LOGITECH=m +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_PANTHERLORD=m +CONFIG_HID_PETALYNX=m +# CONFIG_HID_PID is not set +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_HID_SUNPLUS=m +CONFIG_HID_SUPPORT=y +# CONFIG_HIPPI is not set +# CONFIG_HP100 is not set +# CONFIG_HP_ILO is not set +# CONFIG_HTC_EGPIO is not set +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +# CONFIG_HWMON_VID is not set +CONFIG_HW_RANDOM=m +CONFIG_I2C=y +CONFIG_I2C_ALGOBIT=m +# 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_CHARDEV=y +CONFIG_I2C_GPIO=m +CONFIG_I2C_HELPER_AUTO=y +# CONFIG_I2C_I801 is not set +CONFIG_I2C_IOP3XX=y +# CONFIG_I2C_ISCH is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X 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_I2O is not set +# CONFIG_ICS932S401 is not set +CONFIG_IDE=y +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +CONFIG_IDE_ATAPI=y +# CONFIG_IDE_GD is not set +# CONFIG_IDE_PROC_FS is not set +# CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IEEE1394 is not set +CONFIG_IFB=m +# CONFIG_IGB is not set +# CONFIG_IKCONFIG is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_INET6_TUNNEL is not set +CONFIG_INET6_XFRM_MODE_BEET=m +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET_AH is not set +CONFIG_INET_DIAG=y +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_LRO is not set +CONFIG_INET_TCP_DIAG=y +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INFTL is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MISC is not set +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INTEL_IOP_ADMA=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +# CONFIG_IP1000 is not set +# CONFIG_IP6_NF_IPTABLES is not set +# CONFIG_IP6_NF_QUEUE is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_IPV6=y +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_IPV6_SIT=m +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPX is not set +CONFIG_IP_ADVANCED_ROUTER=y +# CONFIG_IP_DCCP is not set +# CONFIG_IP_FIB_TRIE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_IP_MULTIPLE_TABLES is not set +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_TTL=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_RAW=m +# CONFIG_IP_NF_SECURITY is not set +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_PNP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +# CONFIG_IP_SCTP is not set +# CONFIG_IP_VS is not set +# CONFIG_IRDA is not set +CONFIG_ISO9660_FS=m +# CONFIG_IWMMXT is not set +# CONFIG_JBD_DEBUG is not set +CONFIG_JFFS2_FS=y +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFS_DEBUG is not set +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +CONFIG_JFS_STATISTICS=y +# CONFIG_JME is not set +CONFIG_JOLIET=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_KEXEC is not set +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +# CONFIG_KGDB is not set +CONFIG_KPROBES=y +# CONFIG_KPROBES_SANITY_TEST is not set +CONFIG_KRETPROBES=y +# CONFIG_LAPB is not set +CONFIG_LATENCYTOP=y +# CONFIG_LBD is not set +# CONFIG_LDM_PARTITION is not set +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +# CONFIG_LEDS_PCA9532 is not set +# CONFIG_LEDS_PCA955X is not set +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=0 +CONFIG_LIBCRC32C=m +# CONFIG_LIRC_DEV is not set +# CONFIG_LKDTM is not set +# CONFIG_LLC2 is not set +# CONFIG_LMPCM_USB is not set +CONFIG_LOCKD=y +# CONFIG_LOCK_STAT is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGITECH_FF is not set +# CONFIG_LSF is not set +# CONFIG_MAC80211 is not set +# CONFIG_MACH_EM7210 is not set +CONFIG_MACH_EP80219=y +CONFIG_MACH_GLANTANK=y +CONFIG_MACH_N2100=y +# CONFIG_MACVLAN is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MARKERS=y +# CONFIG_MD_FAULTY is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_MULTIPATH is not set +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +# CONFIG_MD_RAID5_RESHAPE is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_MINIX_FS is not set +# CONFIG_MINIX_SUBPARTITION is not set +CONFIG_MISC_DEVICES=y +# CONFIG_MMC is not set +CONFIG_MSDOS_FS=m +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_CFI=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +# CONFIG_MTD_CFI_AMDSTD is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_INTEL_VR_NOR is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +CONFIG_MTD_NAND=m +# CONFIG_MTD_NAND_CAFE is not set +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_NANDSIM is not set +CONFIG_MTD_NAND_PLATFORM=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_ONENAND is not set +# CONFIG_MTD_OOPS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_BANKWIDTH=1 +CONFIG_MTD_PHYSMAP_LEN=0x0 +CONFIG_MTD_PHYSMAP_START=0x0 +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_RAM is not set +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_PARTS_READONLY=y +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +# CONFIG_MTD_UBI is not set +# CONFIG_NAMESPACES is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NETCONSOLE is not set +CONFIG_NETDEV_1000=y +CONFIG_NETFILTER=y +CONFIG_NETFILTER_ADVANCED=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_NETFILTER_NETLINK_LOG is not set +# CONFIG_NETFILTER_NETLINK_QUEUE is not set +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_DSCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=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_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +# CONFIG_NETLABEL is not set +# CONFIG_NETPOLL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NET_9P is not set +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_CLS=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_FLOW=m +CONFIG_NET_CLS_FW=m +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_U32=m +# CONFIG_NET_DMA is not set +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_ET131X is not set +# CONFIG_NET_FC is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_KEY is not set +CONFIG_NET_PCI=y +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_POLL_CONTROLLER is not set +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_FIFO=y +CONFIG_NET_SCH_GRED=m +# CONFIG_NET_SCH_HFSC is not set +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_INGRESS=m +# CONFIG_NET_SCH_MULTIQ is not set +# CONFIG_NET_SCH_NETEM is not set +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_TEQL=m +# CONFIG_NET_TCPPROBE is not set +# CONFIG_NET_TULIP is not set +# CONFIG_NET_VENDOR_3COM is not set +CONFIG_NEW_LEDS=y +CONFIG_NFSD=y +# CONFIG_NFSD_V3_ACL is not set +# CONFIG_NFSD_V4 is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFTL is not set +# CONFIG_NF_CONNTRACK is not set +# CONFIG_NF_DEFRAG_IPV4 is not set +CONFIG_NLS=y +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +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_874 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +CONFIG_NLS_ISO8859_2=y +# 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_8 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set +CONFIG_NOP_TRACER=y +# CONFIG_NOZOMI is not set +# CONFIG_NS83820 is not set +# CONFIG_NTFS_FS is not set +# CONFIG_OABI_COMPAT is not set +# CONFIG_OPEN_TRACER is not set +# CONFIG_OSF_PARTITION is not set +CONFIG_PACKET_MMAP=y +# CONFIG_PANTHERLORD_FF is not set +CONFIG_PARTITION_ADVANCED=y +# 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_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_IT8213 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_MPIIX 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_OLDPIIX is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_PLATFORM is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SCH is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set +CONFIG_PCI=y +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_LEGACY=y +# CONFIG_PCI_QUIRKS is not set +CONFIG_PCI_SYSCALL=y +# CONFIG_PCNET32 is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_PHANTOM is not set +CONFIG_PHONET=m +# CONFIG_PHYLIB is not set +CONFIG_PLAT_IOP=y +# CONFIG_PM is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_PPP is not set +# CONFIG_PRINTK_TIME is not set +# CONFIG_PROFILING is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_QC_USB is not set +# CONFIG_QLA3XXX is not set +CONFIG_QUOTACTL=y +# CONFIG_R6040 is not set +CONFIG_R8169=y +# CONFIG_RAID_ATTRS is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_BQ24022 is not set +# CONFIG_REGULATOR_DEBUG is not set +# CONFIG_REGULATOR_FIXED_VOLTAGE is not set +CONFIG_REGULATOR_VIRTUAL_CONSUMER=m +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_FS=m +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_REISERFS_FS_XATTR=y +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_RELAY is not set +# CONFIG_RFD_FTL is not set +# CONFIG_RFKILL is not set +CONFIG_RING_BUFFER=y +# CONFIG_ROMFS_FS is not set +CONFIG_ROOT_NFS=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DEBUG is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +CONFIG_RTC_DRV_RS5C372=y +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_V3020 is not set +# CONFIG_RTC_DRV_X1205 is not set +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +CONFIG_RTL8187SE=m +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_SATA_AHCI is not set +# CONFIG_SATA_INIC162X is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_SATA_PMP is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_QSTOR is not set +CONFIG_SATA_SIL=y +# CONFIG_SATA_SIL24 is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_SVW is not set +# CONFIG_SATA_SX4 is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +CONFIG_SATA_VITESSE=y +# CONFIG_SC92031 is not set +CONFIG_SCHEDSTATS=y +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHED_TRACER is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_SCSI_PROC_FS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_TGT is not set +CONFIG_SECURITY=y +CONFIG_SECURITYFS=y +CONFIG_SECURITY_APPARMOR=y +CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 +CONFIG_SECURITY_APPARMOR_DISABLE=y +CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=32768 +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +# CONFIG_SECURITY_ROOTPLUG is not set +# CONFIG_SECURITY_SELINUX is not set +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7473 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_EEPROM 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_I5K_AMB is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_SENSORS_W83627HF 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_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_JSM is not set +# CONFIG_SERIO is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_SIS190 is not set +# CONFIG_SIS900 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_SLAB is not set +# CONFIG_SLIP is not set +CONFIG_SLUB=y +# CONFIG_SLUB_DEBUG is not set +# CONFIG_SMC91X is not set +# CONFIG_SMSC911X is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_SOUND is not set +# CONFIG_SPI is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +CONFIG_SQUASHFS=m +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_SSFDC is not set +CONFIG_STACKTRACE=y +# CONFIG_STACK_TRACER is not set +CONFIG_STANDALONE=y +# CONFIG_SUNDANCE is not set +# CONFIG_SUNGEM is not set +CONFIG_SUNRPC=y +# CONFIG_SUN_PARTITION is not set +# CONFIG_SYN_COOKIES is not set +CONFIG_SYSCTL_SYSCALL=y +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_SYSV68_PARTITION is not set +# CONFIG_TASKSTATS is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_TEXTSEARCH_KMP=m +# CONFIG_THERMAL_HWMON is not set +# CONFIG_THRUSTMASTER_FF is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_TIGON3 is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_TIPC is not set +# CONFIG_TLAN is not set +# CONFIG_TPS65010 is not set +# CONFIG_TR is not set +CONFIG_TRACEPOINTS=y +CONFIG_TRACING=y +# CONFIG_TUN is not set +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +CONFIG_USB=y +# CONFIG_USB_ACM is not set +# CONFIG_USB_ADUTUX is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_APPLEIR is not set +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_GADGET is not set +CONFIG_USB_HID=y +# CONFIG_USB_HIDDEV is not set +CONFIG_USB_HWA_HCD=m +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LIBUSUAL is not set +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +CONFIG_USB_MON=y +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_SL811_HCD is not set +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_TEST is not set +CONFIG_USB_TMC=m +# CONFIG_USB_TRANCEVIBRATOR is not set +CONFIG_USB_UHCI_HCD=y +# CONFIG_USB_USBNET is not set +# CONFIG_USB_VST is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_WHCI_HCD is not set +CONFIG_USB_WUSB=m +CONFIG_USB_WUSB_CBAF=m +# CONFIG_USB_WUSB_CBAF_DEBUG is not set +CONFIG_UWB=m +CONFIG_UWB_HWA=m +# CONFIG_UWB_I1480U is not set +# CONFIG_UWB_WHCI is not set +# CONFIG_UWB_WLP is not set +# CONFIG_VETH is not set +CONFIG_VFAT_FS=y +# CONFIG_VGA_CONSOLE is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_VIDEO_DEV is not set +# CONFIG_VIDEO_MEDIA is not set +# CONFIG_VLAN_8021Q is not set +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_W1 is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_WATCHDOG is not set +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +# CONFIG_WIRELESS_OLD_REGULATORY is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_X25 is not set +# CONFIG_XFRM_USER is not set +# CONFIG_XFS_DEBUG is not set +CONFIG_XFS_FS=m +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_QUOTA=y +CONFIG_XFS_RT=y +CONFIG_XOR_BLOCKS=m +CONFIG_XSCALE_PMU=y +# CONFIG_YELLOWFIN is not set +# CONFIG_ZEROPLUS_FF is not set +# CONFIG_ZISOFS is not set +CONFIG_ZLIB_DEFLATE=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZONE_DMA_FLAG=0 --- linux-2.6.28.orig/debian/config/armel/config.ixp4xx +++ linux-2.6.28/debian/config/armel/config.ixp4xx @@ -0,0 +1,1322 @@ +# +# Config options for config.ixp4xx automatically generated by splitconfig.pl +# +# CONFIG_9P_FS is not set +# CONFIG_ACORN_PARTITION is not set +CONFIG_ACT200L_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +# CONFIG_AF_RXRPC is not set +# CONFIG_AIO is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_APPLICOM is not set +# CONFIG_ARCH_ADI_COYOTE is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IXDP425 is not set +CONFIG_ARCH_IXP4XX=y +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_PRPMC1100 is not set +CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCNET is not set +CONFIG_ARM_THUMB=y +CONFIG_ASK_IP_FIB_HASH=y +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +# CONFIG_ATA is not set +CONFIG_ATAGS_PROC=y +CONFIG_ATALK=m +# CONFIG_ATARI_PARTITION is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_ATL2 is not set +# CONFIG_AUFS is not set +# CONFIG_AUTOFS4_FS is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=m +# CONFIG_BACKLIGHT_CORGI is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BINFMT_AOUT=m +CONFIG_BINFMT_MISC=m +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_CPQ_DA is not set +CONFIG_BLK_DEV_CRYPTOLOOP=m +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_DM=m +# CONFIG_BLK_DEV_DM_BBR is not set +# CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_MD=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM_SIZE=8192 +# CONFIG_BLK_DEV_SR is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BONDING=m +CONFIG_BOUNCE=y +CONFIG_BRIDGE=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_NFLOG=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_NETFILTER=y +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BROADCOM_PHY=m +# CONFIG_BSD_DISKLABEL is not set +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_BT=m +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIBPA10X=m +# CONFIG_BT_HCIBTSDIO is not set +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HIDP=m +CONFIG_BT_L2CAP=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_SCO=m +# CONFIG_CASSINI is not set +# CONFIG_CDROM_PKTCDVD is not set +CONFIG_CFG80211=m +# CONFIG_CHR_DEV_SCH is not set +CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_ST is not set +CONFIG_CICADA_PHY=m +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +CONFIG_CIFS_POSIX=y +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +CONFIG_CIFS_XATTR=y +CONFIG_CLS_U32_MARK=y +CONFIG_CLS_U32_PERF=y +CONFIG_CMDLINE="console=ttyS0,115200" +# CONFIG_COMPAT_BRK is not set +CONFIG_CONFIGFS_FS=m +CONFIG_CONNECTOR=m +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_PABRT_NOIFAR=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_XSCALE=y +CONFIG_CRAMFS=m +CONFIG_CRC16=m +# CONFIG_CRC7 is not set +CONFIG_CRC_CCITT=m +CONFIG_CRC_ITU_T=m +CONFIG_CRC_T10DIF=m +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_ALGAPI=m +CONFIG_CRYPTO_ALGAPI2=m +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_BLKCIPHER2=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_CRC32C=m +# CONFIG_CRYPTO_CRYPTD is not set +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_DES=m +# CONFIG_CRYPTO_DEV_HIFN_795X is not set +CONFIG_CRYPTO_DEV_IXP4XX=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_FCRYPT=m +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_HASH=m +CONFIG_CRYPTO_HASH2=m +CONFIG_CRYPTO_HMAC=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_LZO=m +CONFIG_CRYPTO_MANAGER=m +CONFIG_CRYPTO_MANAGER2=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=m +CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SEQIV=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_XTS=m +# CONFIG_DAB is not set +CONFIG_DAVICOM_PHY=m +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_KERNEL is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_USER is not set +CONFIG_DECNET=m +# CONFIG_DECNET_NF_GRABULATOR is not set +# CONFIG_DECNET_ROUTER is not set +# CONFIG_DEFAULT_AS is not set +CONFIG_DEFAULT_CFQ=y +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_DEVPORT=y +CONFIG_DEV_APPLETALK=m +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +CONFIG_DMABOUNCE=y +# CONFIG_DMADEVICES is not set +CONFIG_DM_CRYPT=m +CONFIG_DM_DELAY=m +# CONFIG_DM_LOOP is not set +CONFIG_DM_MIRROR=m +CONFIG_DM_MULTIPATH=m +# CONFIG_DM_RAID45 is not set +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_UEVENT=y +CONFIG_DM_ZERO=m +CONFIG_DONGLE=y +# CONFIG_DRM is not set +CONFIG_DUMMY=m +# CONFIG_DVB_CORE is not set +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +# CONFIG_EFI_PARTITION is not set +CONFIG_EMBEDDED=y +CONFIG_EQUALIZER=m +CONFIG_ESI_DONGLE=m +CONFIG_EXPORTFS=m +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_COMPAT is not set +CONFIG_EXT4_FS=m +# CONFIG_EXT4_FS_POSIX_ACL is not set +# CONFIG_EXT4_FS_SECURITY is not set +CONFIG_EXT4_FS_XATTR=y +CONFIG_FAT_FS=m +# CONFIG_FB is not set +# CONFIG_FDDI is not set +CONFIG_FIB_RULES=y +# CONFIG_FIREWIRE is not set +# CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_FONT_8x16=y +# CONFIG_FREEZER is not set +# CONFIG_FS_UNIONFS is not set +# CONFIG_FTL is not set +CONFIG_FUSE_FS=y +# CONFIG_FUSION is not set +CONFIG_GACT_PROB=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +CONFIG_GIRBIL_DONGLE=m +# CONFIG_HAPPYMEAL is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_HFS_FS is not set +CONFIG_HID=m +# CONFIG_HIDRAW is not set +CONFIG_HID_A4TECH=m +CONFIG_HID_APPLE=m +CONFIG_HID_BELKIN=m +CONFIG_HID_BRIGHT=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +# CONFIG_HID_COMPAT is not set +CONFIG_HID_CYPRESS=m +# CONFIG_HID_DEBUG is not set +CONFIG_HID_DELL=m +CONFIG_HID_EZKEY=m +CONFIG_HID_GYRATION=m +CONFIG_HID_LOGITECH=m +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_PANTHERLORD=m +CONFIG_HID_PETALYNX=m +# CONFIG_HID_PID is not set +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_HID_SUNPLUS=m +CONFIG_HID_SUPPORT=y +CONFIG_HIGH_RES_TIMERS=y +# CONFIG_HIPPI is not set +# CONFIG_HP100 is not set +CONFIG_HWMON=m +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_HWMON_VID=m +CONFIG_HW_RANDOM=m +CONFIG_HW_RANDOM_IXP4XX=m +CONFIG_I2C=m +CONFIG_I2C_ALGOBIT=m +# 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_CHARDEV=m +CONFIG_I2C_GPIO=m +CONFIG_I2C_HELPER_AUTO=y +# CONFIG_I2C_I801 is not set +CONFIG_I2C_IOP3XX=m +# CONFIG_I2C_ISCH is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X 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_I2O is not set +CONFIG_ICPLUS_PHY=m +# CONFIG_IDE is not set +# CONFIG_IEEE1394 is not set +CONFIG_IFB=m +# CONFIG_IKCONFIG is not set +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET_AH=m +CONFIG_INET_DCCP_DIAG=m +CONFIG_INET_DIAG=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_LRO=m +CONFIG_INET_TCP_DIAG=m +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_TUNNEL=m +# CONFIG_INFTL is not set +# CONFIG_INPUT_ATI_REMOTE is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_CM109 is not set +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_IXP4XX_BEEPER=y +CONFIG_INPUT_KEYBOARD=y +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_UINPUT=m +# CONFIG_INPUT_YEALINK is not set +CONFIG_IOSCHED_AS=m +CONFIG_IOSCHED_DEADLINE=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_RT=m +# CONFIG_IP6_NF_QUEUE is not set +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IPDDP=m +CONFIG_IPDDP_DECAP=y +CONFIG_IPDDP_ENCAP=y +# CONFIG_IPMI_HANDLER is not set +CONFIG_IPV6=m +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_IPV6_SIT=m +# CONFIG_IPV6_TUNNEL is not set +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_DCCP=m +CONFIG_IP_DCCP_ACKVEC=y +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +CONFIG_IP_DCCP_TFRC_LIB=m +# CONFIG_IP_FIB_TRIE is not set +# CONFIG_IP_MROUTE is not set +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_TTL=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_ULOG=m +# CONFIG_IP_PNP is not set +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_SCTP=m +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_FTP=m +# CONFIG_IP_VS_IPV6 is not set +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_AH_ESP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_TAB_BITS=12 +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_WRR=m +CONFIG_IRCOMM=m +CONFIG_IRDA=m +CONFIG_IRDA_CACHE_LAST_LSAP=y +# CONFIG_IRDA_DEBUG is not set +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_ULTRA=y +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRTTY_SIR=m +CONFIG_ISO9660_FS=m +# CONFIG_IWMMXT is not set +CONFIG_IXP4XX_ETH=y +# CONFIG_IXP4XX_INDIRECT_PCI is not set +CONFIG_IXP4XX_NPE=y +CONFIG_IXP4XX_QMGR=y +CONFIG_IXP4XX_WATCHDOG=y +CONFIG_JBD2=m +# CONFIG_JBD2_DEBUG is not set +# CONFIG_JBD_DEBUG is not set +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_POSIX_ACL=y +CONFIG_JFFS2_FS_SECURITY=y +CONFIG_JFFS2_FS_XATTR=y +CONFIG_JFFS2_SUMMARY=y +# CONFIG_JFS_DEBUG is not set +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +# CONFIG_JFS_STATISTICS is not set +CONFIG_JOLIET=y +# CONFIG_KALLSYMS is not set +# CONFIG_KARMA_PARTITION is not set +CONFIG_KEXEC=y +CONFIG_KEYBOARD_ATKBD=m +# CONFIG_KEYBOARD_GPIO is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYS is not set +CONFIG_KINGSUN_DONGLE=m +CONFIG_KS959_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +CONFIG_LAPB=m +# CONFIG_LATENCYTOP is not set +# CONFIG_LBD is not set +CONFIG_LCD_CLASS_DEVICE=m +# CONFIG_LCD_ILI9320 is not set +CONFIG_LCD_PLATFORM=m +# CONFIG_LDM_PARTITION is not set +CONFIG_LEDS_CLASS=m +CONFIG_LEDS_FSG=m +CONFIG_LEDS_GPIO=m +# CONFIG_LEDS_PCA9532 is not set +# CONFIG_LEDS_PCA955X is not set +CONFIG_LEDS_TRIGGERS=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set +# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set +CONFIG_LEDS_TRIGGER_TIMER=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_LIBCRC32C=m +# CONFIG_LIRC_DEV is not set +CONFIG_LITELINK_DONGLE=m +CONFIG_LLC=m +CONFIG_LLC2=m +# CONFIG_LMPCM_USB is not set +CONFIG_LOCKD=m +CONFIG_LOGIRUMBLEPAD2_FF=y +CONFIG_LOGITECH_FF=y +# CONFIG_LSF is not set +CONFIG_LXT_PHY=m +CONFIG_MA600_DONGLE=m +CONFIG_MAC80211=m +CONFIG_MAC80211_DEBUGFS=y +# CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_MESH=y +CONFIG_MAC80211_RC_DEFAULT="pid" +# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set +CONFIG_MAC80211_RC_DEFAULT_PID=y +# CONFIG_MAC80211_RC_MINSTREL is not set +CONFIG_MAC80211_RC_PID=y +# CONFIG_MACH_AVILA is not set +CONFIG_MACH_DSMG600=y +CONFIG_MACH_FSG=y +# CONFIG_MACH_GATEWAY7001 is not set +# CONFIG_MACH_GTWX5715 is not set +# CONFIG_MACH_IXDP465 is not set +# CONFIG_MACH_IXDPG425 is not set +# CONFIG_MACH_KIXRP435 is not set +CONFIG_MACH_NAS100D=y +CONFIG_MACH_NSLU2=y +# CONFIG_MACH_WG302V2 is not set +CONFIG_MACVLAN=m +# CONFIG_MAC_PARTITION is not set +# CONFIG_MARKERS is not set +CONFIG_MARVELL_PHY=m +CONFIG_MCP2120_DONGLE=m +CONFIG_MCS_FIR=m +CONFIG_MDIO_BITBANG=m +# CONFIG_MD_FAULTY is not set +CONFIG_MD_LINEAR=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID5_RESHAPE=y +# CONFIG_MINIX_FS is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_MMC=m +CONFIG_MMC_BLOCK=m +# CONFIG_MMC_BLOCK_BOUNCE is not set +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_SDHCI=m +# CONFIG_MMC_SDHCI_PCI is not set +# CONFIG_MMC_TEST is not set +CONFIG_MMC_TIFM_SD=m +# CONFIG_MMC_UNSAFE_RESUME is not set +CONFIG_MSDOS_FS=m +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +# CONFIG_MTD_CFI_AMDSTD is not set +CONFIG_MTD_CFI_BE_BYTE_SWAP=y +CONFIG_MTD_CFI_GEOMETRY=y +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_NOSWAP is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_CMDLINE_PARTS is not set +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_INTEL_VR_NOR is not set +CONFIG_MTD_IXP4XX=y +# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set +CONFIG_MTD_NAND=m +# CONFIG_MTD_NAND_CAFE is not set +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_GPIO=m +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_ONENAND is not set +CONFIG_MTD_OOPS=m +# CONFIG_MTD_OTP is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PMC551 is not set +CONFIG_MTD_RAM=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS=y +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_DEBUG is not set +# CONFIG_MTD_UBI_GLUEBI is not set +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +# CONFIG_NAMESPACES is not set +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +# CONFIG_NETDEV_1000 is not set +CONFIG_NETFILTER=y +CONFIG_NETFILTER_ADVANCED=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_TPROXY=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=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_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=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_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=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_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=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_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NET_9P=m +# CONFIG_NET_9P_DEBUG is not set +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_CLS=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_FLOW=m +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_IND=y +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_U32=m +# CONFIG_NET_ET131X is not set +# CONFIG_NET_FC is not set +CONFIG_NET_IPGRE=m +# CONFIG_NET_IPGRE_BROADCAST is not set +CONFIG_NET_IPIP=m +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +# CONFIG_NET_PCI is not set +CONFIG_NET_PKTGEN=m +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_FIFO=y +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_TEQL=m +# CONFIG_NET_TULIP is not set +# CONFIG_NET_VENDOR_3COM is not set +CONFIG_NEW_LEDS=y +CONFIG_NFSD=m +# CONFIG_NFSD_V3_ACL is not set +# CONFIG_NFSD_V4 is not set +CONFIG_NFS_FS=m +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFTL is not set +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +CONFIG_NF_CONNTRACK_SANE=m +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CT_NETLINK=m +CONFIG_NF_CT_PROTO_DCCP=m +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_PROTO_DCCP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_SCTP=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NL80211=y +CONFIG_NLS=m +CONFIG_NLS_ASCII=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +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_874=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_DEFAULT="UTF-8" +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=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_8=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +CONFIG_NOZOMI=m +CONFIG_NO_HZ=y +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_FS=m +CONFIG_NTFS_RW=y +# CONFIG_OABI_COMPAT is not set +CONFIG_OLD_BELKIN_DONGLE=m +# CONFIG_OSF_PARTITION is not set +# CONFIG_PACKET_MMAP is not set +CONFIG_PANTHERLORD_FF=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_PCI=y +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_PCI_LEGACY is not set +# CONFIG_PCI_QUIRKS is not set +CONFIG_PCI_SYSCALL=y +CONFIG_PHONET=m +CONFIG_PHYLIB=m +# CONFIG_PM is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_POWER_SUPPLY is not set +CONFIG_PPP=m +CONFIG_PPPOE=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_SYNC_TTY=m +# CONFIG_PRINTK_TIME is not set +# CONFIG_PROFILING is not set +# CONFIG_QC_USB is not set +CONFIG_QSEMI_PHY=m +CONFIG_QUOTACTL=y +CONFIG_RAID_ATTRS=m +CONFIG_REALTEK_PHY=m +# CONFIG_REGULATOR is not set +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_FS=m +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_REISERFS_FS_XATTR=y +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_RELAY is not set +# CONFIG_RFD_FTL is not set +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +CONFIG_RFKILL_LEDS=y +# CONFIG_ROMFS_FS is not set +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_RTC_CLASS=m +CONFIG_RTC_DRV_BQ4802=m +CONFIG_RTC_DRV_DS1286=m +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1511=m +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_FM3130=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_M41T80_WDT=y +CONFIG_RTC_DRV_M48T35=m +CONFIG_RTC_DRV_M48T59=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_RX8581=m +CONFIG_RTC_DRV_S35390A=m +CONFIG_RTC_DRV_STK17TA8=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_X1205=m +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +CONFIG_RTL8187SE=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_FC_TGT_ATTRS=y +CONFIG_SCSI_ISCSI_ATTRS=m +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_NETLINK=y +# CONFIG_SCSI_PROC_FS is not set +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_HOST_SMP=y +CONFIG_SCSI_SAS_LIBSAS=m +CONFIG_SCSI_SAS_LIBSAS_DEBUG=y +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_TGT=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_HMAC_MD5=y +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SDIO_UART=m +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_SENSORS_AD7414=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ADS7828=m +CONFIG_SENSORS_ADT7462=m +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_ADT7473=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_LM93=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_TSL2550=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SENSORS_W83L786NG=m +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set +CONFIG_SERIAL_8250_NR_UARTS=2 +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +# CONFIG_SERIAL_JSM is not set +CONFIG_SERIO=m +CONFIG_SERIO_LIBPS2=m +# CONFIG_SERIO_PCIPS2 is not set +# CONFIG_SERIO_RAW is not set +CONFIG_SERIO_SERPORT=m +# CONFIG_SGI_PARTITION is not set +CONFIG_SIGMATEL_FIR=m +# CONFIG_SLAB is not set +CONFIG_SLHC=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_MODE_SLIP6=y +CONFIG_SLIP_SMART=y +CONFIG_SLUB=y +# CONFIG_SLUB_DEBUG is not set +# CONFIG_SMC91X is not set +# CONFIG_SMSC911X is not set +CONFIG_SMSC_PHY=m +CONFIG_SND=m +# CONFIG_SND_ARM is not set +# CONFIG_SND_BTSCO is not set +# CONFIG_SND_DEBUG is not set +CONFIG_SND_DRIVERS=y +CONFIG_SND_DUMMY=m +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_HWDEP=m +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_MPU401=m +CONFIG_SND_MPU401_UART=m +CONFIG_SND_MTPAV=m +CONFIG_SND_OSSEMUL=y +# CONFIG_SND_PCI is not set +CONFIG_SND_PCM=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_RAWMIDI=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SERIAL_U16550=m +# CONFIG_SND_SOC is not set +# CONFIG_SND_SUPPORT_OLD_API is not set +CONFIG_SND_TIMER=m +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +# CONFIG_SND_VERBOSE_PRINTK is not set +CONFIG_SND_VERBOSE_PROCFS=y +CONFIG_SND_VIRMIDI=m +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +CONFIG_SOUND=m +CONFIG_SOUND_OSS_CORE=y +# CONFIG_SOUND_PRIME is not set +# CONFIG_SPI is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_SQUASHFS is not set +# CONFIG_SSFDC is not set +CONFIG_STANDALONE=y +CONFIG_STP=m +# CONFIG_SUNGEM is not set +CONFIG_SUNRPC=m +# CONFIG_SUN_PARTITION is not set +CONFIG_SYN_COOKIES=y +# CONFIG_SYSCTL_SYSCALL is not set +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_SYSV68_PARTITION is not set +# CONFIG_TASKSTATS is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TEKRAM_DONGLE=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_TEXTSEARCH_KMP=m +CONFIG_THRUSTMASTER_FF=m +CONFIG_TICK_ONESHOT=y +CONFIG_TIFM_CORE=m +# CONFIG_TIPC is not set +CONFIG_TOIM3232_DONGLE=m +# CONFIG_TOSHIBA_FIR is not set +# CONFIG_TR is not set +CONFIG_TUN=m +CONFIG_UBIFS_FS=m +CONFIG_UBIFS_FS_ADVANCED_COMPR=y +# CONFIG_UBIFS_FS_DEBUG is not set +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_XATTR=y +CONFIG_UBIFS_FS_ZLIB=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +CONFIG_USB=y +# CONFIG_USBPCWATCHDOG is not set +CONFIG_USB_ACM=m +CONFIG_USB_ADUTUX=m +# CONFIG_USB_ALI_M5632 is not set +# CONFIG_USB_AN2720 is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_APPLEDISPLAY=m +# CONFIG_USB_APPLEIR is not set +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_BELKIN=y +CONFIG_USB_BERRY_CHARGE=m +# CONFIG_USB_C67X00_HCD is not set +CONFIG_USB_CATC=m +CONFIG_USB_CDC_COMPOSITE=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_EHCI_BIG_ENDIAN_DESC=y +CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +CONFIG_USB_EMI26=m +CONFIG_USB_EMI62=m +# CONFIG_USB_EPSON2888 is not set +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_EZUSB=y +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_GADGET=m +CONFIG_USB_GADGETFS=m +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_ARC is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_DEBUG_FS=y +# CONFIG_USB_GADGET_DUALSPEED is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_OMAP is not set +CONFIG_USB_GADGET_PXA25X=y +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C2410 is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_G_PRINTER=m +CONFIG_USB_G_SERIAL=m +CONFIG_USB_HID=m +# CONFIG_USB_HIDDEV is not set +CONFIG_USB_HSO=m +# CONFIG_USB_HWA_HCD is not set +CONFIG_USB_IDMOUSE=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_IRDA=m +CONFIG_USB_ISIGHTFW=m +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +CONFIG_USB_KAWETH=m +# CONFIG_USB_KBD is not set +# CONFIG_USB_KC2190 is not set +CONFIG_USB_LCD=m +CONFIG_USB_LD=m +CONFIG_USB_LED=m +CONFIG_USB_LEGOTOWER=m +# CONFIG_USB_LIBUSUAL is not set +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +CONFIG_USB_MIDI_GADGET=m +# CONFIG_USB_MON is not set +# CONFIG_USB_MOUSE is not set +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_SMSC95XX=m +CONFIG_USB_NET_ZAURUS=m +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_OTG_WHITELIST is not set +CONFIG_USB_PEGASUS=m +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_PRINTER=m +CONFIG_USB_PXA25X=m +# CONFIG_USB_PXA25X_SMALL is not set +# CONFIG_USB_R8A66597_HCD is not set +CONFIG_USB_RIO500=m +CONFIG_USB_RTL8150=m +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IPW=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_IUU=m +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_MOTOROLA=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +CONFIG_USB_SERIAL_SAFE_PADDED=y +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SEVSEG=m +CONFIG_USB_SISUSBVGA=m +CONFIG_USB_SISUSBVGA_CON=y +# CONFIG_USB_SL811_HCD is not set +CONFIG_USB_STORAGE=y +CONFIG_USB_STORAGE_ALAUDA=y +CONFIG_USB_STORAGE_CYPRESS_ATACB=y +CONFIG_USB_STORAGE_DATAFAB=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_KARMA=y +CONFIG_USB_STORAGE_ONETOUCH=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_TEST=m +CONFIG_USB_TMC=m +CONFIG_USB_TRANCEVIBRATOR=m +# CONFIG_USB_U132_HCD is not set +CONFIG_USB_UHCI_HCD=m +CONFIG_USB_USBNET=m +CONFIG_USB_VST=m +CONFIG_USB_WDM=m +# CONFIG_USB_WHCI_HCD is not set +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set +CONFIG_USB_ZERO=m +# CONFIG_UWB is not set +CONFIG_VETH=m +CONFIG_VFAT_FS=m +# CONFIG_VGA_CONSOLE is not set +# CONFIG_VIDEO_DEV is not set +# CONFIG_VIDEO_MEDIA is not set +CONFIG_VITESSE_PHY=m +CONFIG_VLAN_8021Q=m +# CONFIG_VLAN_8021Q_GVRP is not set +CONFIG_VLSI_FIR=m +# CONFIG_VM_EVENT_COUNTERS is not set +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_W1=m +CONFIG_W1_CON=y +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_GPIO=m +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_SLAVE_BQ27000=m +CONFIG_W1_SLAVE_DS2433=m +CONFIG_W1_SLAVE_DS2433_CRC=y +# CONFIG_W1_SLAVE_DS2438 is not set +CONFIG_W1_SLAVE_DS2760=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_THERM=m +CONFIG_WAN_ROUTER=m +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +# CONFIG_WDTPCI is not set +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +# CONFIG_WIRELESS_OLD_REGULATORY is not set +# CONFIG_WLAN_80211 is not set +CONFIG_X25=m +CONFIG_XFRM_IPCOMP=m +CONFIG_XFRM_USER=m +# CONFIG_XFS_DEBUG is not set +CONFIG_XFS_FS=m +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_QUOTA=y +CONFIG_XFS_RT=y +CONFIG_XOR_BLOCKS=m +CONFIG_XSCALE_PMU=y +CONFIG_ZEROPLUS_FF=m +# CONFIG_ZISOFS is not set +CONFIG_ZLIB_DEFLATE=m +CONFIG_ZLIB_INFLATE=m +CONFIG_ZONE_DMA=y +CONFIG_ZONE_DMA_FLAG=1 --- linux-2.6.28.orig/debian/config/armel/config.versatile +++ linux-2.6.28/debian/config/armel/config.versatile @@ -0,0 +1,801 @@ +# +# Config options for config.versatile automatically generated by splitconfig.pl +# +CONFIG_AC97_BUS=m +# CONFIG_ACORN_PARTITION is not set +# CONFIG_AF_RXRPC is not set +CONFIG_AIO=y +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_APM_EMULATION is not set +# CONFIG_APPLICOM is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_MXC is not set +CONFIG_ARCH_VERSATILE=y +CONFIG_ARCH_VERSATILE_PB=y +# CONFIG_ARCNET is not set +CONFIG_ARM_AMBA=y +CONFIG_ARM_THUMB=y +CONFIG_ARM_VIC=y +CONFIG_ATA=y +# CONFIG_ATALK is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_ATA_NONSTANDARD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_ATA_SFF is not set +# CONFIG_ATL2 is not set +CONFIG_AUFS=m +# CONFIG_AUFS_BRANCH_MAX_1023 is not set +CONFIG_AUFS_BRANCH_MAX_127=y +# CONFIG_AUFS_BRANCH_MAX_32767 is not set +# CONFIG_AUFS_BRANCH_MAX_511 is not set +CONFIG_AUFS_BR_NFS=y +# CONFIG_AUFS_COMPAT is not set +# CONFIG_AUFS_DEBUG is not set +CONFIG_AUFS_DENY_WRITE_ACCESS_PATCH=y +# CONFIG_AUFS_DLGT is not set +CONFIG_AUFS_EXPORT=y +# CONFIG_AUFS_FSYNC_SUPER_PATCH is not set +CONFIG_AUFS_HINOTIFY=y +CONFIG_AUFS_HIN_OR_DLGT=y +CONFIG_AUFS_HIN_OR_FUSE=y +CONFIG_AUFS_LHASH_PATCH=y +CONFIG_AUFS_PUT_FILP_PATCH=y +# CONFIG_AUFS_ROBR is not set +CONFIG_AUFS_RR_SQUASHFS=y +# CONFIG_AUFS_SEC_PERM_PATCH is not set +CONFIG_AUFS_SHWH=y +CONFIG_AUFS_SPLICE_PATCH=y +CONFIG_AUFS_STAT=y +# CONFIG_AUFS_UNIONFS22_PATCH is not set +# CONFIG_AUFS_UNIONFS23_PATCH is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_DM=y +# CONFIG_BLK_DEV_DM_BBR is not set +# CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_MD=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BONDING is not set +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_BRIDGE is not set +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_BT is not set +# CONFIG_C2PORT is not set +# CONFIG_CASSINI is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_CFG80211 is not set +# CONFIG_CHR_DEV_SCH is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CIFS is not set +CONFIG_CMDLINE="root=1f03 mem=32M" +CONFIG_COMPAT_BRK=y +# CONFIG_CONFIGFS_FS is not set +# CONFIG_CONNECTOR is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_ARM926T=y +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +CONFIG_CPU_PABRT_NOIFAR=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CRAMFS=y +# CONFIG_CRC16 is not set +# CONFIG_CRC7 is not set +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC_T10DIF=y +CONFIG_CRYPTO_AEAD2=m +# CONFIG_CRYPTO_AES is not set +CONFIG_CRYPTO_ALGAPI=m +CONFIG_CRYPTO_ALGAPI2=m +# CONFIG_CRYPTO_ANSI_CPRNG is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_AUTHENC is not set +CONFIG_CRYPTO_BLKCIPHER2=m +# 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_CCM is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_FIPS is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_HASH2=m +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_MANAGER=m +CONFIG_CRYPTO_MANAGER2=m +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_RNG2=m +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SEQIV is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_DAB is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_DRIVER is not set +CONFIG_DEBUG_ERRORS=y +# CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_ICEDCC is not set +# CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_LIST is not set +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DECNET is not set +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_DEVPORT=y +# CONFIG_DLM is not set +# CONFIG_DMADEVICES is not set +CONFIG_DM_CRYPT=m +# CONFIG_DM_DELAY is not set +# CONFIG_DM_LOOP is not set +CONFIG_DM_MIRROR=m +CONFIG_DM_MULTIPATH=m +# CONFIG_DM_RAID45 is not set +CONFIG_DM_SNAPSHOT=m +# CONFIG_DM_UEVENT is not set +CONFIG_DM_ZERO=m +# CONFIG_DRM is not set +# CONFIG_DUMMY is not set +# CONFIG_DVB_CORE is not set +# CONFIG_ECONET is not set +# CONFIG_ECRYPT_FS is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_EMBEDDED is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_EQUALIZER is not set +CONFIG_EXPORTFS=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT3_FS_SECURITY=y +# CONFIG_EXT4_FS is not set +CONFIG_FAT_FS=m +# CONFIG_FAULT_INJECTION is not set +CONFIG_FB=y +# CONFIG_FB_3DFX is not set +# CONFIG_FB_ARK is not set +CONFIG_FB_ARMCLCD=y +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +# CONFIG_FB_CARMINE is not set +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_PM3 is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_S3 is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_VIA is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_VT8623 is not set +# CONFIG_FDDI is not set +# CONFIG_FIREWIRE is not set +# CONFIG_FIRMWARE_EDID is not set +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_FONTS=y +# CONFIG_FONT_10x18 is not set +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +CONFIG_FONT_8x16=y +# CONFIG_FONT_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_SUN8x16 is not set +# CONFIG_FPE_FASTFPE is not set +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FREEZER is not set +# CONFIG_FS_UNIONFS is not set +# CONFIG_FTL is not set +# CONFIG_FUNCTION_TRACER is not set +# CONFIG_FUSE_FS is not set +# CONFIG_FUSION is not set +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_GENERIC_GPIO is not set +CONFIG_GENERIC_TIME=y +# CONFIG_HAPPYMEAL is not set +CONFIG_HAVE_CLK=y +# CONFIG_HFSPLUS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HID_SUPPORT is not set +# CONFIG_HIGH_RES_TIMERS is not set +# CONFIG_HIPPI is not set +# CONFIG_HP100 is not set +# CONFIG_HP_ILO is not set +# CONFIG_HWMON is not set +CONFIG_HW_RANDOM=m +CONFIG_I2C=y +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCA is not set +# CONFIG_I2C_ALGOPCF is not set +# 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_CHARDEV=m +# CONFIG_I2C_HELPER_AUTO is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_ISCH is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_VERSATILE is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2O is not set +# CONFIG_ICS932S401 is not set +CONFIG_ICST307=y +# CONFIG_IDE is not set +# CONFIG_IEEE1394 is not set +# CONFIG_IKCONFIG is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_DIAG is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_LRO is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INFTL is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_FF_MEMLESS is not set +CONFIG_INPUT_KEYBOARD=y +# CONFIG_INPUT_MISC is not set +CONFIG_INPUT_MOUSE=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +# CONFIG_IPC_NS is not set +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPV6 is not set +# CONFIG_IPX is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_MROUTE is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_IRDA is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_ISCSI_TCP is not set +# CONFIG_ISO9660_FS is not set +CONFIG_JFFS2_FS=y +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFS_FS is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_KEXEC is not set +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +# CONFIG_KGDB is not set +# CONFIG_KPROBES is not set +# CONFIG_LAPB is not set +# CONFIG_LATENCYTOP is not set +# CONFIG_LBD is not set +# CONFIG_LDM_PARTITION is not set +CONFIG_LEDS=y +CONFIG_LEDS_CPU=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=16 +# CONFIG_LIBCRC32C is not set +# CONFIG_LIRC_DEV is not set +# CONFIG_LLC2 is not set +CONFIG_LOCKD=y +# CONFIG_LOCK_STAT is not set +# CONFIG_LOGO is not set +# CONFIG_LSF is not set +# CONFIG_MAC80211 is not set +CONFIG_MACH_VERSATILE_AB=y +# CONFIG_MACVLAN is not set +# CONFIG_MAC_PARTITION is not set +# CONFIG_MARKERS is not set +CONFIG_MD_AUTODETECT=y +CONFIG_MD_FAULTY=y +CONFIG_MD_LINEAR=y +CONFIG_MD_MULTIPATH=y +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID10 is not set +# CONFIG_MD_RAID456 is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +CONFIG_MINIX_FS=y +# CONFIG_MINIX_SUBPARTITION is not set +CONFIG_MISC_DEVICES=y +CONFIG_MMC=y +CONFIG_MMC_ARMMMCI=m +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_TEST is not set +# CONFIG_MMC_TIFM_SD is not set +# CONFIG_MMC_UNSAFE_RESUME is not set +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_BCM5974 is not set +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +# CONFIG_MOUSE_PS2_ELANTECH is not set +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_PS2_TRACKPOINT=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_MSDOS_FS is not set +CONFIG_MTD_ARM_INTEGRATOR=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_GEOMETRY is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_INTEL_VR_NOR is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set +# CONFIG_MTD_OOPS is not set +# CONFIG_MTD_OTP is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_UBI is not set +CONFIG_NAMESPACES=y +# CONFIG_NETCONSOLE is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETFILTER is not set +# CONFIG_NETLABEL is not set +# CONFIG_NETPOLL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NET_9P is not set +# CONFIG_NET_ET131X is not set +# CONFIG_NET_FC is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_KEY is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_NET_SCHED is not set +# CONFIG_NET_TULIP is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NEW_LEDS is not set +CONFIG_NFSD=y +# CONFIG_NFSD_V3_ACL is not set +# CONFIG_NFSD_V4 is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFTL is not set +CONFIG_NLS=m +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# 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=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_874 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 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_8 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set +# CONFIG_NOZOMI is not set +# CONFIG_NO_HZ is not set +# CONFIG_NTFS_FS is not set +CONFIG_OABI_COMPAT=y +# CONFIG_OPEN_TRACER is not set +# CONFIG_OSF_PARTITION is not set +CONFIG_PACKET_MMAP=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_PCI=y +# CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_LEGACY is not set +CONFIG_PCI_QUIRKS=y +CONFIG_PCI_SYSCALL=y +# CONFIG_PHANTOM is not set +# CONFIG_PHONET is not set +# CONFIG_PHYLIB is not set +# CONFIG_PID_NS is not set +CONFIG_PM=y +# CONFIG_PMIC_DA903X is not set +# CONFIG_PM_DEBUG is not set +# CONFIG_PM_DISABLE_CONSOLE is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_PPP is not set +# CONFIG_PRINTK_TIME is not set +# CONFIG_PROFILING is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_RAID_ATTRS is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_REGULATOR is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_RELAY is not set +# CONFIG_RFD_FTL is not set +# CONFIG_RFKILL is not set +CONFIG_ROMFS_FS=y +CONFIG_ROOT_NFS=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DEBUG is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_PL030 is not set +CONFIG_RTC_DRV_PL031=y +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_V3020 is not set +# CONFIG_RTC_DRV_X1205 is not set +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +CONFIG_RTL8187SE=m +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_SATA_AHCI is not set +# CONFIG_SATA_PMP is not set +# CONFIG_SATA_SIL24 is not set +# CONFIG_SCHEDSTATS is not set +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHED_TRACER is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_MVSAS is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_SCSI_NSP32 is not set +CONFIG_SCSI_PROC_FS=y +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_SPI_ATTRS=y +# CONFIG_SCSI_SRP is not set +# CONFIG_SCSI_STEX is not set +CONFIG_SCSI_SYM53C8XX_2=y +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SDIO_UART is not set +CONFIG_SECURITY=y +CONFIG_SECURITYFS=y +CONFIG_SECURITY_APPARMOR=y +CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 +CONFIG_SECURITY_APPARMOR_DISABLE=y +CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=32768 +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +# CONFIG_SECURITY_SELINUX is not set +CONFIG_SENSORS_EEPROM=m +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_TSL2550 is not set +CONFIG_SERIAL_8250=m +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_PCI=m +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_SERIO=y +CONFIG_SERIO_AMBAKMI=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_PCIPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_SGI_PARTITION is not set +CONFIG_SLAB=y +CONFIG_SLABINFO=y +# CONFIG_SLIP is not set +# CONFIG_SLUB is not set +CONFIG_SMC91X=y +# CONFIG_SMSC911X is not set +CONFIG_SND=m +CONFIG_SND_AC97_CODEC=m +# CONFIG_SND_AC97_POWER_SAVE is not set +CONFIG_SND_ARM=y +CONFIG_SND_ARMAACI=m +# CONFIG_SND_DEBUG is not set +CONFIG_SND_DRIVERS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_MIXER_OSS=m +# CONFIG_SND_MPU401 is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_MXC_SPDIF is not set +CONFIG_SND_OSSEMUL=y +# CONFIG_SND_PCI is not set +CONFIG_SND_PCM=m +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_SOC is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_TIMER=m +# CONFIG_SND_VERBOSE_PRINTK is not set +CONFIG_SND_VERBOSE_PROCFS=y +CONFIG_SND_VMASTER=y +# CONFIG_SOLARIS_X86_PARTITION is not set +CONFIG_SOUND=y +CONFIG_SOUND_OSS_CORE=y +# CONFIG_SOUND_PRIME is not set +# CONFIG_SPI is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +CONFIG_SQUASHFS=m +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_SSFDC is not set +# CONFIG_STACK_TRACER is not set +CONFIG_STANDALONE=y +# CONFIG_SUNGEM is not set +CONFIG_SUNRPC=y +# CONFIG_SUN_PARTITION is not set +# CONFIG_SUSPEND is not set +# CONFIG_SYN_COOKIES is not set +CONFIG_SYSCTL_SYSCALL=y +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSV68_PARTITION is not set +# CONFIG_TASKSTATS is not set +# CONFIG_TCP_CONG_ADVANCED is not set +# CONFIG_THERMAL_HWMON is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_TIPC is not set +# CONFIG_TR is not set +CONFIG_TUN=y +# CONFIG_UDF_FS is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_USB is not set +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_GADGET is not set +# CONFIG_USER_NS is not set +# CONFIG_UTS_NS is not set +# CONFIG_UWB is not set +# CONFIG_VETH is not set +CONFIG_VFAT_FS=m +CONFIG_VFP=y +# CONFIG_VIDEO_DEV is not set +# CONFIG_VIDEO_MEDIA is not set +# CONFIG_VLAN_8021Q is not set +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_W1 is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_WATCHDOG is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_WIRELESS_OLD_REGULATORY is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_X25 is not set +# CONFIG_XFRM_USER is not set +# CONFIG_XFS_FS is not set +CONFIG_ZLIB_DEFLATE=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZONE_DMA_FLAG=0 --- linux-2.6.28.orig/debian/config/armel/config +++ linux-2.6.28/debian/config/armel/config @@ -0,0 +1,392 @@ +# +# Common config options automatically generated by splitconfig.pl +# +# CONFIG_ACCESSIBILITY is not set +# CONFIG_ADFS_FS is not set +CONFIG_AEABI=y +# CONFIG_AFFS_FS is not set +# CONFIG_AFS_FS is not set +CONFIG_ALIGNMENT_TRAP=y +CONFIG_ANON_INODES=y +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +CONFIG_ARCH_FLATMEM_HAS_HOLES=y +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARM=y +# CONFIG_ARPD is not set +# CONFIG_AT24 is not set +# CONFIG_ATM is not set +CONFIG_AUDIT=y +CONFIG_AUDIT_GENERIC=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AVERATEC_5100P is not set +# CONFIG_AX88796 is not set +# CONFIG_B44 is not set +CONFIG_BASE_FULL=y +CONFIG_BASE_SMALL=0 +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +CONFIG_BINFMT_ELF=y +CONFIG_BITREVERSE=y +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_BSG is not set +CONFIG_BLK_DEV_COMPCACHE=m +# CONFIG_BLK_DEV_COMPCACHE_DEBUG is not set +# CONFIG_BLK_DEV_COMPCACHE_STATS is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_DRBD is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_SD=y +# CONFIG_BLK_DEV_XIP is not set +CONFIG_BLOCK=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_BUG=y +# CONFIG_CAN is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +# CONFIG_CGROUPS is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_CLASSIC_RCU=y +# CONFIG_CODA_FS is not set +CONFIG_CONSOLE_TRANSLATIONS=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_CPU_32=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_IDLE is not set +CONFIG_CRC32=y +CONFIG_CRYPTO=y +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_TEST is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +# CONFIG_DEVKMEM is not set +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_DM9000 is not set +# CONFIG_DM_DEBUG is not set +CONFIG_DNOTIFY=y +# CONFIG_DS1682 is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +# CONFIG_EFS_FS is not set +CONFIG_ELF_CORE=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_EPOLL=y +CONFIG_EVENTFD=y +CONFIG_EXPERIMENTAL=y +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_XATTR=y +CONFIG_EXTRA_FIRMWARE="" +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_FILE_LOCKING=y +CONFIG_FLATMEM=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_FRAME_POINTER=y +CONFIG_FRAME_WARN=1024 +# CONFIG_FSAM7400 is not set +CONFIG_FS_MBCACHE=y +CONFIG_FS_POSIX_ACL=y +CONFIG_FUTEX=y +CONFIG_FW_LOADER=y +# CONFIG_GAMEPORT is not set +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_IRQ_PROBE=y +# CONFIG_GFS_FS is not set +# CONFIG_GROUP_SCHED is not set +# CONFIG_HAMRADIO is not set +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAVE_AOUT=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_HAVE_IDE=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_HAVE_OPROFILE=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_HECI is not set +CONFIG_HOTPLUG=y +# CONFIG_HPFS_FS is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_HW_CONSOLE=y +CONFIG_HZ=100 +CONFIG_I2C_BOARDINFO=y +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IEEE80211 is not set +CONFIG_INET=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_INPUT=y +# CONFIG_INPUT_EVBUG is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_JOYSTICK is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_TABLET is not set +CONFIG_IOSCHED_CFQ=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IP_FIB_HASH=y +CONFIG_IP_MULTICAST=y +# CONFIG_ISDN is not set +# CONFIG_IWLWIFI_LEDS is not set +CONFIG_JBD=y +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_KMOD=y +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_LOCKD_V4=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +CONFIG_MAGIC_SYSRQ=y +CONFIG_MD=y +# CONFIG_MEMSTICK is not set +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8400 is not set +CONFIG_MII=y +CONFIG_MMU=y +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MSDOS_PARTITION=y +CONFIG_MTD=y +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_MTD_BLOCK2MTD 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_CHAR=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_JEDECPROBE is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MTDRAM is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_PLATRAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_NCP_FS is not set +# CONFIG_NDISWRAPPER is not set +CONFIG_NET=y +CONFIG_NETDEVICES=y +# CONFIG_NETDEV_10000 is not set +CONFIG_NETWORK_FILESYSTEMS=y +# CONFIG_NET_DSA is not set +CONFIG_NET_ETHERNET=y +CONFIG_NFSD_V3=y +CONFIG_NFS_COMMON=y +CONFIG_NFS_V3=y +# CONFIG_NO_IOPORT is not set +# CONFIG_NVRAM is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_OUTER_CACHE is not set +# CONFIG_P80211 is not set +# CONFIG_PACKARDBELL_E5 is not set +CONFIG_PACKET=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_PAGE_OFFSET=0xC0000000 +# CONFIG_PARPORT is not set +# CONFIG_PCCARD is not set +# CONFIG_PCF8575 is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_PLIST=y +# CONFIG_PREEMPT is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_PRINTK=y +# CONFIG_PRISM2_USB is not set +CONFIG_PROC_FS=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_PROC_SYSCTL=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_RESOURCES_64BIT is not set +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_TEST is not set +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_LIB=y +CONFIG_RT_MUTEXES=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_SAMPLES is not set +CONFIG_SCSI=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_DH is not set +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_ISCSITARGET is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_WAIT_SCAN=m +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_SHMEM=y +CONFIG_SIGNALFD=y +# CONFIG_SLOB is not set +# CONFIG_SMB_FS is not set +# CONFIG_SMC911X is not set +# CONFIG_SPARSEMEM_MANUAL is not set +# CONFIG_SSB is not set +CONFIG_SSB_POSSIBLE=y +CONFIG_STACKTRACE_SUPPORT=y +# CONFIG_SUNRPC_REGISTER_V4 is not set +CONFIG_SWAP=y +CONFIG_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_SYSV_FS is not set +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +# CONFIG_TCG_TPM is not set +CONFIG_TCP_CONG_CUBIC=y +# CONFIG_TCP_MD5SIG is not set +# CONFIG_THERMAL is not set +CONFIG_TIMERFD=y +# CONFIG_TINY_SHMEM is not set +CONFIG_TLSF=m +# CONFIG_TLSF_DEBUG is not set +# CONFIG_TLSF_STATS is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_TP_SMAPI is not set +# CONFIG_TP_SMAPI_EC is not set +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_UEVENT_HELPER_PATH="" +# CONFIG_UFS_FS is not set +CONFIG_UID16=y +# CONFIG_UIO is not set +CONFIG_UNEVICTABLE_LRU=y +CONFIG_UNIX=y +CONFIG_UNIX98_PTYS=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_SUPPORT=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_VERSION_SIGNATURE="" +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_VIRT_TO_BUS=y +# CONFIG_VMSPLIT_1G is not set +# CONFIG_VMSPLIT_2G is not set +CONFIG_VMSPLIT_3G=y +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +# CONFIG_VXFS_FS is not set +# CONFIG_WAN is not set +CONFIG_WIRELESS=y +# CONFIG_WLAN_PRE80211 is not set +CONFIG_XFRM=y +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XIP_KERNEL is not set +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_ZBOOT_ROM_TEXT=0x0 --- linux-2.6.28.orig/debian/config/lpia/config.lpia +++ linux-2.6.28/debian/config/lpia/config.lpia @@ -0,0 +1,3 @@ +# +# Config options for config.lpia automatically generated by splitconfig.pl +# --- linux-2.6.28.orig/debian/config/lpia/config +++ linux-2.6.28/debian/config/lpia/config @@ -0,0 +1,3623 @@ +# +# Common config options automatically generated by splitconfig.pl +# +CONFIG_3C359=m +CONFIG_3C515=m +# CONFIG_4KSTACKS is not set +CONFIG_60XX_WDT=m +# CONFIG_64BIT is not set +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_8129=y +CONFIG_8139TOO_PIO=y +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_ABYSS=m +CONFIG_AC3200=m +CONFIG_AC97_BUS=m +# CONFIG_ACCESSIBILITY is not set +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +# CONFIG_ACER_WMI is not set +CONFIG_ACORN_PARTITION=y +# CONFIG_ACORN_PARTITION_ADFS is not set +# CONFIG_ACORN_PARTITION_CUMANA is not set +# CONFIG_ACORN_PARTITION_EESOX is not set +CONFIG_ACORN_PARTITION_ICS=y +# CONFIG_ACORN_PARTITION_POWERTEC is not set +CONFIG_ACORN_PARTITION_RISCIX=y +CONFIG_ACPI=y +CONFIG_ACPI_AC=m +# CONFIG_ACPI_ASUS is not set +CONFIG_ACPI_BATTERY=m +CONFIG_ACPI_BLACKLIST_YEAR=2000 +CONFIG_ACPI_BUTTON=m +CONFIG_ACPI_CONTAINER=y +# CONFIG_ACPI_CUSTOM_DSDT is not set +CONFIG_ACPI_CUSTOM_DSDT_FILE="" +CONFIG_ACPI_CUSTOM_DSDT_INITRD=y +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_DOCK=y +CONFIG_ACPI_FAN=m +CONFIG_ACPI_HOTPLUG_CPU=y +CONFIG_ACPI_PCI_SLOT=m +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_PROCFS=y +CONFIG_ACPI_PROCFS_POWER=y +CONFIG_ACPI_PROC_EVENT=y +CONFIG_ACPI_SBS=m +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_SYSFS_POWER=y +CONFIG_ACPI_SYSTEM=y +CONFIG_ACPI_THERMAL=m +CONFIG_ACPI_TOSHIBA=m +CONFIG_ACPI_VIDEO=m +# CONFIG_ACPI_WMI is not set +CONFIG_ACQUIRE_WDT=m +CONFIG_ACT200L_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_ADAPTEC_STARFIRE=m +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_ADM8211=m +CONFIG_ADVANTECH_WDT=m +CONFIG_AFFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_AFS_FS=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_AGP=m +CONFIG_AGP_ALI=m +CONFIG_AGP_AMD=m +CONFIG_AGP_AMD64=m +CONFIG_AGP_ATI=m +CONFIG_AGP_EFFICEON=m +CONFIG_AGP_INTEL=m +CONFIG_AGP_NVIDIA=m +CONFIG_AGP_SIS=m +CONFIG_AGP_SWORKS=m +CONFIG_AGP_VIA=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +CONFIG_AIC79XX_DEBUG_ENABLE=y +CONFIG_AIC79XX_DEBUG_MASK=0 +CONFIG_AIC79XX_REG_PRETTY_PRINT=y +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 +CONFIG_AIC7XXX_DEBUG_ENABLE=y +CONFIG_AIC7XXX_DEBUG_MASK=0 +CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_AIO=y +CONFIG_AIRO=m +CONFIG_AIRO_CS=m +CONFIG_ALIM1535_WDT=m +CONFIG_ALIM7101_WDT=m +CONFIG_ALI_FIR=m +CONFIG_AMD8111_ETH=m +CONFIG_AMIGA_PARTITION=y +CONFIG_ANON_INODES=y +# CONFIG_APM is not set +CONFIG_APPLICOM=m +CONFIG_APRICOT=m +CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig" +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_ARCH_HAS_CPU_RELAX=y +CONFIG_ARCH_HAS_DEFAULT_IDLE=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUPPORTS_MSI=y +CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_ARCNET=m +CONFIG_ARCNET_1051=m +CONFIG_ARCNET_1201=m +CONFIG_ARCNET_CAP=m +CONFIG_ARCNET_COM20020=m +CONFIG_ARCNET_COM20020_CS=m +CONFIG_ARCNET_COM20020_ISA=m +CONFIG_ARCNET_COM20020_PCI=m +CONFIG_ARCNET_COM90xx=m +CONFIG_ARCNET_COM90xxIO=m +CONFIG_ARCNET_RAW=m +CONFIG_ARCNET_RIM_I=m +CONFIG_ARLAN=m +# CONFIG_ARPD is not set +CONFIG_ASK_IP_FIB_HASH=y +CONFIG_ASUS_LAPTOP=m +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_AT1700=m +CONFIG_AT24=m +CONFIG_ATA=y +# CONFIG_ATALK is not set +CONFIG_ATARI_PARTITION=y +CONFIG_ATA_ACPI=y +CONFIG_ATA_GENERIC=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_OVER_ETH=m +CONFIG_ATA_PIIX=y +CONFIG_ATA_SFF=y +# CONFIG_ATH5K is not set +CONFIG_ATH9K=m +CONFIG_ATL1=m +CONFIG_ATL1E=m +CONFIG_ATL2=m +# CONFIG_ATM is not set +CONFIG_ATMEL=m +CONFIG_ATP=m +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y +# CONFIG_AUDIT_ARCH is not set +CONFIG_AUDIT_GENERIC=y +CONFIG_AUDIT_TREE=y +CONFIG_AUFS=m +# CONFIG_AUFS_BRANCH_MAX_1023 is not set +CONFIG_AUFS_BRANCH_MAX_127=y +# CONFIG_AUFS_BRANCH_MAX_32767 is not set +# CONFIG_AUFS_BRANCH_MAX_511 is not set +CONFIG_AUFS_BR_NFS=y +CONFIG_AUFS_BR_XFS=y +# CONFIG_AUFS_COMPAT is not set +# CONFIG_AUFS_DEBUG is not set +CONFIG_AUFS_DENY_WRITE_ACCESS_PATCH=y +# CONFIG_AUFS_DLGT is not set +CONFIG_AUFS_EXPORT=y +# CONFIG_AUFS_FSYNC_SUPER_PATCH is not set +CONFIG_AUFS_HINOTIFY=y +CONFIG_AUFS_HIN_OR_DLGT=y +CONFIG_AUFS_HIN_OR_FUSE=y +CONFIG_AUFS_LHASH_PATCH=y +CONFIG_AUFS_PUT_FILP_PATCH=y +# CONFIG_AUFS_ROBR is not set +CONFIG_AUFS_RR_SQUASHFS=y +CONFIG_AUFS_SEC_PERM_PATCH=y +CONFIG_AUFS_SHWH=y +CONFIG_AUFS_SPLICE_PATCH=y +CONFIG_AUFS_STAT=y +# CONFIG_AUFS_UNIONFS22_PATCH is not set +# CONFIG_AUFS_UNIONFS23_PATCH is not set +# CONFIG_AUFS_WORKAROUND_FUSE is not set +CONFIG_AUTOFS4_FS=m +CONFIG_AUTOFS_FS=m +CONFIG_AUXDISPLAY=y +CONFIG_AVERATEC_5100P=m +CONFIG_B43=m +CONFIG_B43LEGACY=m +CONFIG_B43LEGACY_DEBUG=y +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +CONFIG_B43LEGACY_LEDS=y +CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y +CONFIG_B43LEGACY_PCI_AUTOSELECT=y +CONFIG_B43LEGACY_PIO=y +# CONFIG_B43LEGACY_PIO_MODE is not set +CONFIG_B43LEGACY_RFKILL=y +# CONFIG_B43_DEBUG is not set +CONFIG_B43_LEDS=y +CONFIG_B43_PCICORE_AUTOSELECT=y +CONFIG_B43_PCI_AUTOSELECT=y +# CONFIG_B43_PCMCIA is not set +CONFIG_B43_RFKILL=y +CONFIG_B44=m +CONFIG_B44_PCI=y +CONFIG_B44_PCICORE_AUTOSELECT=y +CONFIG_B44_PCI_AUTOSELECT=y +CONFIG_BACKLIGHT_CARILLO_RANCH=m +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_CORGI=m +CONFIG_BACKLIGHT_LCD_SUPPORT=y +# CONFIG_BACKLIGHT_MBP_NVIDIA is not set +CONFIG_BACKLIGHT_PROGEAR=m +# CONFIG_BACKLIGHT_SAHARA is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +CONFIG_BASE_FULL=y +CONFIG_BASE_SMALL=0 +# CONFIG_BATTERY_BQ27x00 is not set +CONFIG_BATTERY_DS2760=m +CONFIG_BATTERY_OLPC=m +# CONFIG_BEFS_DEBUG is not set +CONFIG_BEFS_FS=m +CONFIG_BFS_FS=m +CONFIG_BINFMT_AOUT=m +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_BITREVERSE=y +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_DEV=y +CONFIG_BLK_DEV_3W_XXXX_RAID=m +# CONFIG_BLK_DEV_BSG is not set +CONFIG_BLK_DEV_COMPCACHE=m +# CONFIG_BLK_DEV_COMPCACHE_DEBUG is not set +# CONFIG_BLK_DEV_COMPCACHE_STATS is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_DM=m +CONFIG_BLK_DEV_DM_BBR=m +CONFIG_BLK_DEV_DRBD=m +CONFIG_BLK_DEV_FD=m +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_DEV_INTEGRITY is not set +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_MD=m +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_BLK_DEV_SX8=m +CONFIG_BLK_DEV_UB=m +CONFIG_BLK_DEV_UMEM=m +# CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_DEV_XIP is not set +CONFIG_BLOCK=y +CONFIG_BNX2=m +CONFIG_BNX2X=m +CONFIG_BONDING=m +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BOUNCE=y +CONFIG_BRIDGE=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_NFLOG=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_NETFILTER=y +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BROADCOM_PHY=m +CONFIG_BSD_DISKLABEL=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_BT=m +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBTSDIO=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HIDP=m +CONFIG_BT_L2CAP=m +CONFIG_BT_RFCOMM=m +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_SCO=m +CONFIG_BUG=y +# CONFIG_C101 is not set +# CONFIG_C2PORT is not set +# CONFIG_CAN is not set +CONFIG_CAN_PM_TRACE=y +CONFIG_CARDBUS=y +CONFIG_CARDMAN_4000=m +CONFIG_CARDMAN_4040=m +# CONFIG_CARMINE_DRAM_CUSTOM is not set +CONFIG_CASSINI=m +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_CFAG12864B=m +CONFIG_CFAG12864B_RATE=20 +CONFIG_CFG80211=m +CONFIG_CGROUPS=y +CONFIG_CGROUP_CPUACCT=y +# CONFIG_CGROUP_DEBUG is not set +# CONFIG_CGROUP_DEVICE is not set +# CONFIG_CGROUP_FREEZER is not set +CONFIG_CGROUP_MEM_RES_CTLR=y +CONFIG_CGROUP_NS=y +CONFIG_CGROUP_SCHED=y +CONFIG_CHECK_SIGNATURE=y +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T3=m +CONFIG_CHR_DEV_OSST=m +CONFIG_CHR_DEV_SCH=m +CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_ST=m +CONFIG_CICADA_PHY=m +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG2 is not set +CONFIG_CIFS_DFS_UPCALL=y +CONFIG_CIFS_EXPERIMENTAL=y +# CONFIG_CIFS_STATS is not set +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_WEAK_PW_HASH=y +# CONFIG_CIFS_XATTR is not set +CONFIG_CISS_SCSI_TAPE=y +CONFIG_CLASSIC_RCU=y +CONFIG_CLOCKSOURCE_WATCHDOG=y +CONFIG_CLS_U32_MARK=y +# CONFIG_CLS_U32_PERF is not set +# CONFIG_CMDLINE_BOOL is not set +CONFIG_CODA_FS=m +CONFIG_COMPAL_LAPTOP=m +# CONFIG_COMPAT_BRK is not set +# CONFIG_COMPAT_VDSO is not set +CONFIG_COMPUTONE=m +CONFIG_CONFIGFS_FS=m +CONFIG_CONNECTOR=m +CONFIG_CONSOLE_POLL=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_CONTEXT_SWITCH_TRACER=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_COSA is not set +# CONFIG_CPA_DEBUG is not set +CONFIG_CPU5_WDT=m +CONFIG_CPUSETS=y +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_DEBUG is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=m +CONFIG_CPU_FREQ_STAT=m +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y +CONFIG_CPU_SUP_AMD=y +CONFIG_CPU_SUP_CENTAUR_32=y +CONFIG_CPU_SUP_CYRIX_32=y +CONFIG_CPU_SUP_INTEL=y +CONFIG_CPU_SUP_TRANSMETA_32=y +CONFIG_CPU_SUP_UMC_32=y +CONFIG_CRAMFS=y +# CONFIG_CRASH_DUMP is not set +CONFIG_CRC16=y +CONFIG_CRC32=y +CONFIG_CRC7=m +CONFIG_CRC_CCITT=m +CONFIG_CRC_ITU_T=m +CONFIG_CRC_T10DIF=m +CONFIG_CRYPTO=y +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_AES_586=m +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_CRC32C=m +# CONFIG_CRYPTO_CRC32C_INTEL is not set +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_DEV_GEODE=m +CONFIG_CRYPTO_DEV_HIFN_795X=m +CONFIG_CRYPTO_DEV_HIFN_795X_RNG=y +CONFIG_CRYPTO_DEV_PADLOCK=y +CONFIG_CRYPTO_DEV_PADLOCK_AES=m +CONFIG_CRYPTO_DEV_PADLOCK_SHA=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_FCRYPT=m +# CONFIG_CRYPTO_FIPS is not set +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_LZO=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SALSA20_586=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SEQIV=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_586=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_XTS=m +CONFIG_CS5535_GPIO=m +CONFIG_CS89x0=m +CONFIG_CYCLADES=m +# CONFIG_CYZ_INTR is not set +# CONFIG_DAB is not set +CONFIG_DAVICOM_PHY=m +CONFIG_DCA=m +CONFIG_DCDBAS=m +CONFIG_DE2104X=m +CONFIG_DE4X5=m +CONFIG_DE600=m +CONFIG_DE620=m +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_BOOT_PARAMS is not set +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_DRIVER is not set +CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_HIGHMEM is not set +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_NX_TEST is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +# CONFIG_DEBUG_RODATA is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_VIRTUAL is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DECNET is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_BIC is not set +CONFIG_DEFAULT_CFQ=y +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_HTCP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_DEFAULT_IO_DELAY_TYPE=1 +# CONFIG_DEFAULT_NOOP is not set +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_WESTWOOD is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_DELL_RBU=m +CONFIG_DEPCA=m +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_DEVKMEM is not set +CONFIG_DEVPORT=y +CONFIG_DIGIEPCA=m +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_DISPLAY_SUPPORT=m +# CONFIG_DL2K is not set +# CONFIG_DLCI is not set +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +CONFIG_DM9102=m +CONFIG_DMADEVICES=y +# CONFIG_DMATEST is not set +CONFIG_DMA_ENGINE=y +CONFIG_DMI=y +CONFIG_DMIID=y +CONFIG_DM_CRYPT=m +# CONFIG_DM_DEBUG is not set +# CONFIG_DM_DELAY is not set +CONFIG_DM_LOOP=m +CONFIG_DM_MIRROR=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_RAID45=m +CONFIG_DM_SNAPSHOT=m +CONFIG_DM_UEVENT=y +CONFIG_DM_ZERO=m +CONFIG_DNOTIFY=y +CONFIG_DONGLE=y +CONFIG_DOUBLEFAULT=y +CONFIG_DRM=m +CONFIG_DRM_I810=m +CONFIG_DRM_I830=m +CONFIG_DRM_I915=m +CONFIG_DRM_MGA=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_SAVAGE=m +CONFIG_DRM_SIS=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_VIA=m +CONFIG_DS1682=m +# CONFIG_DSCC4 is not set +CONFIG_DTLK=m +CONFIG_DUMMY=m +CONFIG_DUMMY_CONSOLE=y +# CONFIG_DVB_AF9013 is not set +CONFIG_DVB_AU8522=m +CONFIG_DVB_AV7110=m +# CONFIG_DVB_AV7110_FIRMWARE is not set +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_B2C2_FLEXCOP=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_BT8XX=m +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_CORE=m +CONFIG_DVB_BUDGET_PATCH=m +CONFIG_DVB_CAPTURE_DRIVERS=y +CONFIG_DVB_CORE=m +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +# CONFIG_DVB_DM1105 is not set +CONFIG_DVB_DRX397XD=m +# CONFIG_DVB_DUMMY_FE is not set +# CONFIG_DVB_FE_CUSTOMISE is not set +CONFIG_DVB_ISL6405=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_L64781=m +CONFIG_DVB_LGDT330X=m +# CONFIG_DVB_LGS8GL5 is not set +CONFIG_DVB_LNBP21=m +CONFIG_DVB_MT312=m +CONFIG_DVB_MT352=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_PLL=m +CONFIG_DVB_PLUTO2=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_S5H1411=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_SI21XX=m +CONFIG_DVB_SIANO_SMS1XXX=m +CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS=y +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_STB6000=m +CONFIG_DVB_STV0288=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_TDA10048=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_USB=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +# CONFIG_DVB_USB_AF9015 is not set +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_AU6610=m +# CONFIG_DVB_USB_CINERGY_T2 is not set +CONFIG_DVB_USB_CXUSB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_DIBUSB_MB=m +# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_DTT200U=m +# CONFIG_DVB_USB_DTV5100 is not set +CONFIG_DVB_USB_DW2102=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_VES1820=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_ZL10353=m +# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +CONFIG_E100=m +CONFIG_E1000=m +CONFIG_E1000E=m +CONFIG_E2100=m +CONFIG_EARLY_PRINTK=y +# CONFIG_EARLY_PRINTK_DBGP is not set +# CONFIG_ECONET is not set +CONFIG_ECRYPT_FS=m +CONFIG_EDAC=y +CONFIG_EDAC_AMD76X=m +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_E752X=m +CONFIG_EDAC_E7XXX=m +CONFIG_EDAC_I3000=m +CONFIG_EDAC_I5000=m +CONFIG_EDAC_I5100=m +CONFIG_EDAC_I82860=m +CONFIG_EDAC_I82875P=m +CONFIG_EDAC_I82975X=m +CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC_R82600=m +# CONFIG_EDAC_X38 is not set +CONFIG_EDD=y +CONFIG_EDD_OFF=y +CONFIG_EEEPC_LAPTOP=m +CONFIG_EEPRO100=m +CONFIG_EEPROM_93CX6=m +CONFIG_EEXPRESS=m +CONFIG_EEXPRESS_PRO=m +CONFIG_EFI=y +CONFIG_EFI_PARTITION=y +CONFIG_EFI_VARS=y +CONFIG_EFS_FS=m +CONFIG_EISA=y +CONFIG_EISA_NAMES=y +CONFIG_EISA_PCI_EISA=y +CONFIG_EISA_VIRTUAL_ROOT=y +CONFIG_EISA_VLB_PRIMING=y +CONFIG_EL1=m +CONFIG_EL16=m +CONFIG_EL2=m +CONFIG_EL3=m +CONFIG_ELF_CORE=y +CONFIG_ELMC=m +CONFIG_ELMC_II=m +CONFIG_ELPLUS=m +CONFIG_EMBEDDED=y +# CONFIG_ENABLE_MUST_CHECK is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENC28J60 is not set +CONFIG_ENCLOSURE_SERVICES=m +# CONFIG_ENIC is not set +CONFIG_EPIC100=m +CONFIG_EPOLL=y +CONFIG_EQUALIZER=m +CONFIG_ES3210=m +CONFIG_ESI_DONGLE=m +CONFIG_ESPSERIAL=m +CONFIG_ETH16I=m +CONFIG_EUROTECH_WDT=m +CONFIG_EVENTFD=y +CONFIG_EWRK3=m +CONFIG_EXPERIMENTAL=y +CONFIG_EXPORTFS=m +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT4DEV_COMPAT is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_EXT4_FS_XATTR=y +CONFIG_EXTRA_FIRMWARE="" +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_FARSYNC is not set +CONFIG_FAST_CMPXCHG_LOCAL=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_FAT_FS=m +# CONFIG_FAULT_INJECTION is not set +CONFIG_FB=y +CONFIG_FB_3DFX=m +# CONFIG_FB_3DFX_ACCEL is not set +CONFIG_FB_ARC=m +CONFIG_FB_ARK=m +CONFIG_FB_ASILIANT=y +CONFIG_FB_ATY=m +CONFIG_FB_ATY128=m +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY_BACKLIGHT=y +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_BOOT_VESA_SUPPORT=y +CONFIG_FB_CARILLO_RANCH=m +CONFIG_FB_CARMINE=m +CONFIG_FB_CARMINE_DRAM_EVAL=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +CONFIG_FB_CIRRUS=m +CONFIG_FB_CYBER2000=m +CONFIG_FB_CYBLA=m +CONFIG_FB_DDC=m +CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_EFI=y +# CONFIG_FB_FOREIGN_ENDIAN is not set +CONFIG_FB_GEODE=y +CONFIG_FB_GEODE_GX=m +CONFIG_FB_GEODE_GX1=m +CONFIG_FB_GEODE_LX=m +CONFIG_FB_HECUBA=m +CONFIG_FB_HGA=m +# CONFIG_FB_HGA_ACCEL is not set +CONFIG_FB_I810=m +# CONFIG_FB_I810_GTF is not set +CONFIG_FB_IMSTT=y +CONFIG_FB_INTEL=m +# CONFIG_FB_INTEL_DEBUG is not set +CONFIG_FB_INTEL_I2C=y +CONFIG_FB_KYRO=m +CONFIG_FB_LE80578=m +# CONFIG_FB_MACMODES is not set +CONFIG_FB_MATROX=m +CONFIG_FB_MATROX_G=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MULTIHEAD=y +CONFIG_FB_MATROX_MYSTIQUE=y +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_METRONOME is not set +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_N411=m +CONFIG_FB_NEOMAGIC=m +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_BACKLIGHT=y +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_I2C=y +CONFIG_FB_PM2=m +CONFIG_FB_PM2_FIFO_DISCONNECT=y +CONFIG_FB_PM3=m +CONFIG_FB_RADEON=m +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RIVA=m +CONFIG_FB_RIVA_BACKLIGHT=y +# CONFIG_FB_RIVA_DEBUG is not set +CONFIG_FB_RIVA_I2C=y +CONFIG_FB_S1D13XXX=m +CONFIG_FB_S3=m +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_ACCEL=y +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SIS=m +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +CONFIG_FB_SM501=m +CONFIG_FB_SVGALIB=m +CONFIG_FB_SYS_COPYAREA=m +CONFIG_FB_SYS_FILLRECT=m +CONFIG_FB_SYS_FOPS=m +CONFIG_FB_SYS_IMAGEBLIT=m +CONFIG_FB_TILEBLITTING=y +CONFIG_FB_TRIDENT=m +# CONFIG_FB_TRIDENT_ACCEL is not set +CONFIG_FB_UVESA=m +CONFIG_FB_VESA=m +CONFIG_FB_VGA16=m +# CONFIG_FB_VIA is not set +# CONFIG_FB_VIRTUAL is not set +CONFIG_FB_VOODOO1=m +CONFIG_FB_VT8623=m +# CONFIG_FDDI is not set +CONFIG_FEALNX=m +CONFIG_FIB_RULES=y +CONFIG_FILE_LOCKING=y +# CONFIG_FIREWIRE is not set +CONFIG_FIRMWARE_EDID=y +# CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_FIRMWARE_MEMMAP=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_FLATMEM=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_FONTS is not set +CONFIG_FONT_8x16=y +CONFIG_FONT_8x8=y +CONFIG_FORCEDETH=m +# CONFIG_FORCEDETH_NAPI is not set +CONFIG_FRAMEBUFFER_CONSOLE=m +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FRAME_POINTER=y +CONFIG_FRAME_WARN=1024 +CONFIG_FREEZER=y +CONFIG_FSAM7400=m +CONFIG_FS_MBCACHE=y +CONFIG_FS_POSIX_ACL=y +CONFIG_FS_UNIONFS=m +CONFIG_FTL=m +# CONFIG_FTRACE_STARTUP_TEST is not set +CONFIG_FUJITSU_LAPTOP=m +# CONFIG_FUJITSU_LAPTOP_DEBUG is not set +# CONFIG_FUNCTION_TRACER is not set +CONFIG_FUSE_FS=y +CONFIG_FUSION=y +CONFIG_FUSION_CTL=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_LAN=m +# CONFIG_FUSION_LOGGING is not set +CONFIG_FUSION_MAX_SGE=128 +CONFIG_FUSION_SAS=m +CONFIG_FUSION_SPI=m +CONFIG_FUTEX=y +CONFIG_FW_LOADER=y +CONFIG_GACT_PROB=y +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GENERIC_ACL=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_CMOS_UPDATE=y +# CONFIG_GENERIC_CPU is not set +CONFIG_GENERIC_FIND_FIRST_BIT=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_GENERIC_TIME=y +# CONFIG_GENERIC_TIME_VSYSCALL is not set +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=m +CONFIG_GFS_FS=m +CONFIG_GIRBIL_DONGLE=m +# CONFIG_GPIOLIB is not set +CONFIG_GROUP_SCHED=y +CONFIG_HAMACHI=m +# CONFIG_HAMRADIO is not set +CONFIG_HANGCHECK_TIMER=m +CONFIG_HAPPYMEAL=m +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAVE_AOUT=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_ATOMIC_IOMAP=y +# CONFIG_HAVE_CPUMASK_OF_CPU_MAP is not set +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_HAVE_IDE=y +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_KVM=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_SETUP_PER_CPU_AREA=y +CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y +CONFIG_HDLC=m +CONFIG_HDLC_CISCO=m +CONFIG_HDLC_FR=m +CONFIG_HDLC_PPP=m +CONFIG_HDLC_RAW=m +CONFIG_HDLC_RAW_ETH=m +# CONFIG_HEADERS_CHECK is not set +CONFIG_HECI=m +CONFIG_HERMES=m +CONFIG_HFSPLUS_FS=m +CONFIG_HFS_FS=m +CONFIG_HIBERNATION=y +CONFIG_HID=m +CONFIG_HIDRAW=y +CONFIG_HID_A4TECH=m +CONFIG_HID_APPLE=m +CONFIG_HID_BELKIN=m +CONFIG_HID_BRIGHT=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +CONFIG_HID_COMPAT=y +CONFIG_HID_CYPRESS=m +# CONFIG_HID_DEBUG is not set +CONFIG_HID_DELL=m +CONFIG_HID_EZKEY=m +CONFIG_HID_GYRATION=m +CONFIG_HID_LOGITECH=m +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_PANTHERLORD=m +CONFIG_HID_PETALYNX=m +# CONFIG_HID_PID is not set +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_HID_SUNPLUS=m +CONFIG_HID_SUPPORT=y +CONFIG_HIGHMEM=y +CONFIG_HIGHMEM4G=y +# CONFIG_HIGHMEM64G is not set +# CONFIG_HIGHPTE is not set +CONFIG_HIGH_RES_TIMERS=y +# CONFIG_HIPPI is not set +CONFIG_HOSTAP=m +CONFIG_HOSTAP_CS=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_PLX=m +# CONFIG_HOSTESS_SV11 is not set +CONFIG_HOTPLUG=y +CONFIG_HOTPLUG_CPU=y +CONFIG_HOTPLUG_PCI=m +CONFIG_HOTPLUG_PCI_ACPI=m +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +CONFIG_HOTPLUG_PCI_COMPAQ=m +CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM=y +CONFIG_HOTPLUG_PCI_CPCI=y +CONFIG_HOTPLUG_PCI_CPCI_GENERIC=m +CONFIG_HOTPLUG_PCI_CPCI_ZT5550=m +CONFIG_HOTPLUG_PCI_FAKE=m +CONFIG_HOTPLUG_PCI_IBM=m +CONFIG_HOTPLUG_PCI_PCIE=m +CONFIG_HOTPLUG_PCI_SHPC=m +CONFIG_HP100=m +CONFIG_HPET=y +CONFIG_HPET_EMULATE_RTC=y +CONFIG_HPET_MMAP=y +CONFIG_HPET_TIMER=y +CONFIG_HPFS_FS=m +CONFIG_HPLAN=m +CONFIG_HPLAN_PLUS=m +CONFIG_HP_ILO=m +# CONFIG_HP_WATCHDOG is not set +CONFIG_HTC_PASIC3=m +CONFIG_HT_IRQ=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_HVC_DRIVER=y +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_HWMON_VID=m +CONFIG_HW_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_AMD=m +CONFIG_HW_RANDOM_GEODE=m +CONFIG_HW_RANDOM_INTEL=m +CONFIG_HW_RANDOM_VIA=m +CONFIG_HW_RANDOM_VIRTIO=m +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +CONFIG_I2C=m +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCA=m +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_I2C_DEBUG_CORE is not set +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_I801=m +CONFIG_I2C_ISCH=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_NFORCE2_S4985=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_PCA_ISA=m +CONFIG_I2C_PCA_PLATFORM=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_STUB=m +CONFIG_I2C_TAOS_EVM=m +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_BUS=m +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_PROC=m +CONFIG_I2O_SCSI=m +CONFIG_I6300ESB_WDT=m +CONFIG_I82092=m +CONFIG_I82365=m +CONFIG_I8K=m +CONFIG_IB700_WDT=m +CONFIG_IBMASR=m +CONFIG_IBMLANA=m +CONFIG_IBMLS=m +# CONFIG_IBMMCA_SCSI_DEV_RESET is not set +CONFIG_IBMMCA_SCSI_ORDER_STANDARD=y +CONFIG_IBMOL=m +CONFIG_IBMTR=m +CONFIG_IBM_ASM=m +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +CONFIG_ICPLUS_PHY=m +# CONFIG_ICS932S401 is not set +# CONFIG_IDE is not set +CONFIG_IEEE1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y +CONFIG_IEEE1394_OHCI1394=m +CONFIG_IEEE1394_PCILYNX=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE80211=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_CRYPT_WEP=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IFB=m +CONFIG_IGB=m +CONFIG_IGB_DCA=y +# CONFIG_IGB_LRO is not set +# CONFIG_IKCONFIG is not set +CONFIG_INET=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET_AH=m +CONFIG_INET_DCCP_DIAG=m +CONFIG_INET_DIAG=y +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_LRO=m +CONFIG_INET_TCP_DIAG=y +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_AMSO1100=m +CONFIG_INFINIBAND_AMSO1100_DEBUG=y +CONFIG_INFINIBAND_CXGB3=m +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_IPOIB_DEBUG=y +# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set +CONFIG_INFINIBAND_ISER=m +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_MTHCA_DEBUG=y +# CONFIG_INFINIBAND_NES is not set +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INFTL=m +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_INPUT=y +CONFIG_INPUT_ACERHK=m +# CONFIG_INPUT_APANEL is not set +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_ATLAS_BTNS=m +# CONFIG_INPUT_CM109 is not set +CONFIG_INPUT_EVBUG=m +CONFIG_INPUT_EVDEV=m +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_INPUT_KEYBOARD=y +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_MOUSE=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_PCSPKR is not set +CONFIG_INPUT_POLLDEV=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_TABLET=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_WISTRON_BTNS=m +CONFIG_INPUT_YEALINK=m +CONFIG_INTEL_IOATDMA=m +CONFIG_INTEL_MENLOW=m +# CONFIG_IOMMU_HELPER is not set +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_CFQ=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_NOOP=y +# CONFIG_IO_DELAY_0X80 is not set +CONFIG_IO_DELAY_0XED=y +# CONFIG_IO_DELAY_NONE is not set +CONFIG_IO_DELAY_TYPE_0X80=0 +CONFIG_IO_DELAY_TYPE_0XED=1 +CONFIG_IO_DELAY_TYPE_NONE=3 +CONFIG_IO_DELAY_TYPE_UDELAY=2 +# CONFIG_IO_DELAY_UDELAY is not set +CONFIG_IP1000=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_SECURITY=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_POWEROFF=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPV6=m +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_MROUTE is not set +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_IPV6_SIT=m +# CONFIG_IPV6_SUBTREES is not set +CONFIG_IPV6_TUNNEL=m +CONFIG_IPW2100=m +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2100_MONITOR=y +CONFIG_IPW2200=m +# CONFIG_IPW2200_DEBUG is not set +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +CONFIG_IPW2200_RADIOTAP=y +# CONFIG_IPWIRELESS is not set +# CONFIG_IPX is not set +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_DCCP=m +CONFIG_IP_DCCP_ACKVEC=y +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_IP_DCCP_TFRC_LIB=m +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_MROUTE=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_SECURITY=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_IP_PNP is not set +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_SCTP=m +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_FTP=m +# CONFIG_IP_VS_IPV6 is not set +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_AH_ESP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_TAB_BITS=12 +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_WRR=m +CONFIG_IRCOMM=m +CONFIG_IRDA=m +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_DEBUG=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_ULTRA=y +CONFIG_IRLAN=m +CONFIG_IRNET=m +# CONFIG_IRQSOFF_TRACER is not set +CONFIG_IRTTY_SIR=m +CONFIG_ISA=y +CONFIG_ISAPNP=y +CONFIG_ISA_DMA_API=y +# CONFIG_ISCSI_IBFT_FIND is not set +CONFIG_ISCSI_TCP=m +# CONFIG_ISDN is not set +# CONFIG_ISI is not set +CONFIG_ISO9660_FS=m +# CONFIG_ISTALLION is not set +CONFIG_IT8712F_WDT=m +# CONFIG_IT87_WDT is not set +CONFIG_ITCO_VENDOR_SUPPORT=y +CONFIG_ITCO_WDT=m +CONFIG_IWL3945=m +# CONFIG_IWL3945_DEBUG is not set +CONFIG_IWL3945_LEDS=y +CONFIG_IWL3945_RFKILL=y +CONFIG_IWL3945_SPECTRUM_MEASUREMENT=y +CONFIG_IWL4965=y +CONFIG_IWL5000=y +CONFIG_IWLAGN=m +# CONFIG_IWLAGN_LEDS is not set +# CONFIG_IWLAGN_SPECTRUM_MEASUREMENT is not set +CONFIG_IWLCORE=m +CONFIG_IWLWIFI=m +# CONFIG_IWLWIFI_DEBUG is not set +# CONFIG_IWLWIFI_LEDS is not set +CONFIG_IWLWIFI_RFKILL=y +CONFIG_IXGB=m +CONFIG_IXGBE=m +CONFIG_IXGBE_DCA=y +CONFIG_JBD=y +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +# CONFIG_JBD_DEBUG is not set +CONFIG_JFFS2_CMODE_FAVOURLZO=y +# CONFIG_JFFS2_CMODE_NONE is not set +# CONFIG_JFFS2_CMODE_PRIORITY is not set +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_LZO=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_SUMMARY is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFS_DEBUG is not set +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +CONFIG_JFS_STATISTICS=y +# CONFIG_JME is not set +CONFIG_JOLIET=y +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_232=y +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_JOYSTICK_ZHENHUA=m +CONFIG_K8_NB=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_KARMA_PARTITION=y +CONFIG_KEXEC=y +# CONFIG_KEXEC_JUMP is not set +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_KGDB=y +CONFIG_KGDB_SERIAL_CONSOLE=y +# CONFIG_KGDB_TESTS is not set +CONFIG_KINGSUN_DONGLE=m +CONFIG_KMOD=y +CONFIG_KPROBES=y +# CONFIG_KPROBES_SANITY_TEST is not set +CONFIG_KRETPROBES=y +CONFIG_KS0108=m +CONFIG_KS0108_DELAY=2 +CONFIG_KS0108_PORT=0x378 +CONFIG_KS959_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +CONFIG_KTIME_SCALAR=y +CONFIG_KVM=m +CONFIG_KVM_AMD=m +# CONFIG_KVM_CLOCK is not set +# CONFIG_KVM_GUEST is not set +CONFIG_KVM_INTEL=m +# CONFIG_KVM_TRACE is not set +CONFIG_LANCE=m +# CONFIG_LANMEDIA is not set +# CONFIG_LAPB is not set +CONFIG_LATENCYTOP=y +CONFIG_LBD=y +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_ILI9320=m +CONFIG_LCD_LTV350QV=m +CONFIG_LCD_PLATFORM=m +# CONFIG_LCD_TDO24M is not set +CONFIG_LCD_VGG2432A4=m +# CONFIG_LDM_DEBUG is not set +CONFIG_LDM_PARTITION=y +CONFIG_LEDS_CLASS=m +# CONFIG_LEDS_CLEVO_MAIL is not set +# CONFIG_LEDS_HP_DISK is not set +CONFIG_LEDS_NET48XX=m +CONFIG_LEDS_PCA9532=m +CONFIG_LEDS_PCA955X=m +CONFIG_LEDS_TRIGGERS=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +CONFIG_LEDS_TRIGGER_DEFAULT_ON=m +CONFIG_LEDS_TRIGGER_HEARTBEAT=m +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_WRAP=m +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_LGUEST is not set +CONFIG_LGUEST_GUEST=y +CONFIG_LIBCRC32C=m +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_CS=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_SDIO=m +# CONFIG_LIBERTAS_THINFIRM is not set +CONFIG_LIBERTAS_USB=m +CONFIG_LIRC_ATIUSB=m +CONFIG_LIRC_BT829=m +CONFIG_LIRC_CMDIR=m +CONFIG_LIRC_DEV=m +# CONFIG_LIRC_GPIO is not set +CONFIG_LIRC_I2C=m +CONFIG_LIRC_IGORPLUGUSB=m +CONFIG_LIRC_IMON=m +CONFIG_LIRC_IT87=m +CONFIG_LIRC_MCEUSB=m +CONFIG_LIRC_MCEUSB2=m +# CONFIG_LIRC_PARALLEL is not set +CONFIG_LIRC_PVR150=m +CONFIG_LIRC_SASEM=m +CONFIG_LIRC_SERIAL=m +CONFIG_LIRC_SERIAL_IGOR=m +CONFIG_LIRC_SIR=m +CONFIG_LIRC_STREAMZAP=m +CONFIG_LIRC_TTUSBIR=m +CONFIG_LITELINK_DONGLE=m +# CONFIG_LKDTM is not set +CONFIG_LLC=y +CONFIG_LLC2=m +CONFIG_LMPCM_USB=m +CONFIG_LNE390=m +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_LOCKD=m +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_LOCKD_V4=y +CONFIG_LOCK_KERNEL=y +# CONFIG_LOCK_STAT is not set +# CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGITECH_FF is not set +# CONFIG_LOGO is not set +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_LP486E=m +# CONFIG_LP_CONSOLE is not set +CONFIG_LSF=y +CONFIG_LXT_PHY=m +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +CONFIG_M25PXX_USE_FAST_READ=y +# CONFIG_M386 is not set +# CONFIG_M486 is not set +CONFIG_M586=y +# CONFIG_M586MMX is not set +# CONFIG_M586TSC is not set +# CONFIG_M686 is not set +CONFIG_MA600_DONGLE=m +CONFIG_MAC80211=m +CONFIG_MAC80211_DEBUGFS=y +# CONFIG_MAC80211_DEBUG_MENU is not set +# CONFIG_MAC80211_HWSIM is not set +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_MESH=y +CONFIG_MAC80211_RC_DEFAULT="pid" +# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set +CONFIG_MAC80211_RC_DEFAULT_PID=y +# CONFIG_MAC80211_RC_MINSTREL is not set +CONFIG_MAC80211_RC_PID=y +CONFIG_MACHZ_WDT=m +# CONFIG_MACINTOSH_DRIVERS is not set +CONFIG_MACVLAN=m +CONFIG_MAC_PARTITION=y +CONFIG_MADGEMC=m +CONFIG_MAGIC_SYSRQ=y +CONFIG_MARKERS=y +CONFIG_MARVELL_PHY=m +# CONFIG_MATH_EMULATION is not set +CONFIG_MAX_RAW_DEVS=256 +CONFIG_MCA=y +CONFIG_MCA_LEGACY=y +# CONFIG_MCA_PROC_FS is not set +# CONFIG_MCORE2 is not set +CONFIG_MCP2120_DONGLE=m +# CONFIG_MCRUSOE is not set +CONFIG_MCS_FIR=m +# CONFIG_MCYRIXIII is not set +CONFIG_MD=y +CONFIG_MDA_CONSOLE=m +CONFIG_MDIO_BITBANG=m +CONFIG_MD_FAULTY=m +CONFIG_MD_LINEAR=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID5_RESHAPE=y +CONFIG_MEDIA_ATTACH=y +CONFIG_MEDIA_TUNER=m +# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2131=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +# CONFIG_MEFFICEON is not set +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_SAS=m +# CONFIG_MEMSTICK is not set +# CONFIG_MEMTEST is not set +# CONFIG_MFD_CORE is not set +CONFIG_MFD_SM501=m +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MGEODEGX1 is not set +# CONFIG_MGEODE_LX is not set +CONFIG_MICROCODE=m +# CONFIG_MICROCODE_AMD is not set +CONFIG_MICROCODE_INTEL=y +CONFIG_MICROCODE_OLD_INTERFACE=y +CONFIG_MII=m +CONFIG_MINIX_FS=m +CONFIG_MINIX_SUBPARTITION=y +CONFIG_MISC_DEVICES=y +CONFIG_MIXCOMWD=m +# CONFIG_MK6 is not set +# CONFIG_MK7 is not set +# CONFIG_MK8 is not set +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +# CONFIG_MLX4_EN is not set +CONFIG_MLX4_INFINIBAND=m +CONFIG_MMC=y +CONFIG_MMC_BLOCK=m +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_RICOH_MMC=m +CONFIG_MMC_SDHCI=m +CONFIG_MMC_SDHCI_PCI=m +CONFIG_MMC_SDRICOH_CS=m +# CONFIG_MMC_TEST is not set +CONFIG_MMC_TIFM_SD=m +# CONFIG_MMC_UNSAFE_RESUME is not set +CONFIG_MMC_WBSD=m +# CONFIG_MMIOTRACE is not set +CONFIG_MMU=y +CONFIG_MMU_NOTIFIER=y +CONFIG_MM_OWNER=y +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MOUSE_APPLETOUCH=m +# CONFIG_MOUSE_ATIXL is not set +CONFIG_MOUSE_BCM5974=m +CONFIG_MOUSE_INPORT=m +CONFIG_MOUSE_LOGIBM=m +CONFIG_MOUSE_PC110PAD=m +CONFIG_MOUSE_PS2=m +CONFIG_MOUSE_PS2_ALPS=y +# CONFIG_MOUSE_PS2_ELANTECH is not set +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +# CONFIG_MOUSE_PS2_OLPC is not set +CONFIG_MOUSE_PS2_SYNAPTICS=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_PS2_TRACKPOINT=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_MOXA_INTELLIO=m +CONFIG_MOXA_SMARTIO=m +# CONFIG_MPENTIUM4 is not set +# CONFIG_MPENTIUMII is not set +# CONFIG_MPENTIUMIII is not set +# CONFIG_MPENTIUMM is not set +# CONFIG_MPSC is not set +CONFIG_MSDOS_FS=m +CONFIG_MSDOS_PARTITION=y +CONFIG_MSI_LAPTOP=m +CONFIG_MTD=m +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTD_ABSENT=m +CONFIG_MTD_ALAUDA=m +CONFIG_MTD_AMD76XROM=m +CONFIG_MTD_AR7_PARTS=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK2MTD=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_MTD_CFI=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_AMDSTD=m +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=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_CHAR=m +CONFIG_MTD_CK804XROM=m +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_CONCAT=m +CONFIG_MTD_DATAFLASH=m +# CONFIG_MTD_DATAFLASH_OTP is not set +# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_DILNETPC=m +CONFIG_MTD_DILNETPC_BOOTSIZE=0x80000 +CONFIG_MTD_DOC2000=m +CONFIG_MTD_DOC2001=m +CONFIG_MTD_DOC2001PLUS=m +CONFIG_MTD_DOCECC=m +CONFIG_MTD_DOCPROBE=m +CONFIG_MTD_DOCPROBE_ADDRESS=0 +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_ESB2ROM=m +CONFIG_MTD_GEN_PROBE=m +CONFIG_MTD_ICHXROM=m +CONFIG_MTD_INTEL_VR_NOR=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_L440GX=m +CONFIG_MTD_M25P80=m +CONFIG_MTD_MAP_BANK_WIDTH_1=y +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +CONFIG_MTD_MTDRAM=m +CONFIG_MTD_NAND=m +CONFIG_MTD_NAND_CAFE=m +CONFIG_MTD_NAND_CS553X=m +CONFIG_MTD_NAND_DISKONCHIP=m +# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_NANDSIM=m +CONFIG_MTD_NAND_PLATFORM=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NETSC520=m +CONFIG_MTD_NETtel=m +CONFIG_MTD_ONENAND=m +CONFIG_MTD_ONENAND_2X_PROGRAM=y +# CONFIG_MTD_ONENAND_OTP is not set +CONFIG_MTD_ONENAND_SIM=m +CONFIG_MTD_ONENAND_VERIFY_WRITE=y +CONFIG_MTD_OOPS=m +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_PCI=m +CONFIG_MTD_PHRAM=m +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PHYSMAP_LEN=0x4000000 +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PLATRAM=m +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +CONFIG_MTD_RAM=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS=m +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +CONFIG_MTD_ROM=m +CONFIG_MTD_SBC_GXX=m +CONFIG_MTD_SC520CDP=m +CONFIG_MTD_SCB2_FLASH=m +CONFIG_MTD_SCx200_DOCFLASH=m +CONFIG_MTD_SLRAM=m +CONFIG_MTD_TS5500=m +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_DEBUG is not set +CONFIG_MTD_UBI_GLUEBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTRR=y +# CONFIG_MTRR_SANITIZER is not set +# CONFIG_MVIAC3_2 is not set +# CONFIG_MVIAC7 is not set +CONFIG_MWAVE=m +# CONFIG_MWINCHIP3D is not set +# CONFIG_MWINCHIPC6 is not set +CONFIG_MYRI10GE=m +CONFIG_MYRI10GE_DCA=y +# CONFIG_N2 is not set +# CONFIG_NAMESPACES is not set +CONFIG_NATSEMI=m +CONFIG_NCPFS_EXTRAS=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_OS2_NS=y +CONFIG_NCPFS_PACKET_SIGNING=y +# CONFIG_NCPFS_SMALLDOS is not set +CONFIG_NCPFS_STRONG=y +CONFIG_NCP_FS=m +CONFIG_NDISWRAPPER=m +CONFIG_NE2000=m +CONFIG_NE2K_PCI=m +CONFIG_NE2_MCA=m +CONFIG_NE3210=m +CONFIG_NET=y +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETDEVICES=y +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y +CONFIG_NETFILTER=y +CONFIG_NETFILTER_ADVANCED=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_TPROXY=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=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_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=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_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=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_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETLABEL=y +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NETWORK_SECMARK=y +CONFIG_NETXEN_NIC=m +# CONFIG_NET_9P is not set +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +# CONFIG_NET_ACT_SKBEDIT is not set +CONFIG_NET_CLS=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_BASIC=m +# CONFIG_NET_CLS_FLOW is not set +CONFIG_NET_CLS_FW=m +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_DCCPPROBE=m +CONFIG_NET_DMA=y +# CONFIG_NET_DSA is not set +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_ET131X=m +CONFIG_NET_ETHERNET=y +CONFIG_NET_FC=y +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_NET_IPIP=m +CONFIG_NET_ISA=y +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_NET_PCI=y +CONFIG_NET_PCMCIA=y +CONFIG_NET_PKTGEN=m +CONFIG_NET_POCKET=y +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_NET_SB1000=m +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_FIFO=y +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_INGRESS=m +# CONFIG_NET_SCH_MULTIQ is not set +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_TCPPROBE=m +CONFIG_NET_TULIP=y +CONFIG_NET_VENDOR_3COM=y +CONFIG_NET_VENDOR_RACAL=y +CONFIG_NET_VENDOR_SMC=y +CONFIG_NEW_LEDS=y +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_NF_CONNTRACK_SANE is not set +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CT_NETLINK=m +# CONFIG_NF_CT_PROTO_DCCP is not set +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_SCTP=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NI52=m +CONFIG_NI65=m +CONFIG_NIU=m +CONFIG_NL80211=y +CONFIG_NLS=y +CONFIG_NLS_ASCII=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +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_874=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=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_8=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +# CONFIG_NOHIGHMEM is not set +CONFIG_NOP_TRACER=y +CONFIG_NORTEL_HERMES=m +CONFIG_NOZOMI=m +CONFIG_NO_HZ=y +CONFIG_NR_CPUS=64 +CONFIG_NS83820=m +CONFIG_NSC_FIR=m +CONFIG_NSC_GPIO=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_FS=m +# CONFIG_NTFS_RW is not set +CONFIG_NVRAM=m +CONFIG_N_HDLC=m +# CONFIG_OCFS2_COMPAT_JBD is not set +# CONFIG_OCFS2_DEBUG_FS is not set +CONFIG_OCFS2_DEBUG_MASKLOG=y +CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_STATS=y +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_OLPC=y +CONFIG_OMFS_FS=m +# CONFIG_OPEN_TRACER is not set +CONFIG_OPROFILE=m +# CONFIG_OPROFILE_IBS is not set +# CONFIG_OPTIMIZE_INLINING is not set +CONFIG_OSF_PARTITION=y +CONFIG_P54_COMMON=m +CONFIG_P54_PCI=m +CONFIG_P54_USB=m +CONFIG_P80211=m +CONFIG_PACKARDBELL_E5=m +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_PAGE_OFFSET=0xC0000000 +# CONFIG_PANASONIC_LAPTOP is not set +# CONFIG_PANTHERLORD_FF is not set +CONFIG_PARAVIRT=y +# CONFIG_PARAVIRT_CLOCK is not set +# CONFIG_PARAVIRT_DEBUG is not set +CONFIG_PARAVIRT_GUEST=y +CONFIG_PARIDE=m +CONFIG_PARIDE_ATEN=m +CONFIG_PARIDE_BPCK=m +CONFIG_PARIDE_BPCK6=m +CONFIG_PARIDE_COMM=m +CONFIG_PARIDE_DSTR=m +CONFIG_PARIDE_EPAT=m +# CONFIG_PARIDE_EPATC8 is not set +CONFIG_PARIDE_EPIA=m +CONFIG_PARIDE_FIT2=m +CONFIG_PARIDE_FIT3=m +CONFIG_PARIDE_FRIQ=m +CONFIG_PARIDE_FRPW=m +CONFIG_PARIDE_KBIC=m +CONFIG_PARIDE_KTTI=m +CONFIG_PARIDE_ON20=m +CONFIG_PARIDE_ON26=m +CONFIG_PARIDE_PCD=m +CONFIG_PARIDE_PD=m +CONFIG_PARIDE_PF=m +CONFIG_PARIDE_PG=m +CONFIG_PARIDE_PT=m +CONFIG_PARPORT=m +CONFIG_PARPORT_1284=y +CONFIG_PARPORT_AX88796=m +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_NOT_PC=y +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_FIFO=y +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_SERIAL=m +CONFIG_PARTITION_ADVANCED=y +CONFIG_PATA_ACPI=y +CONFIG_PATA_ALI=y +CONFIG_PATA_AMD=y +CONFIG_PATA_ARTOP=y +CONFIG_PATA_ATIIXP=y +CONFIG_PATA_CMD640_PCI=m +CONFIG_PATA_CMD64X=y +CONFIG_PATA_CS5520=y +CONFIG_PATA_CS5530=y +CONFIG_PATA_CS5535=m +CONFIG_PATA_CS5536=y +CONFIG_PATA_CYPRESS=m +CONFIG_PATA_EFAR=y +CONFIG_PATA_HPT366=y +CONFIG_PATA_HPT37X=m +# CONFIG_PATA_HPT3X2N is not set +CONFIG_PATA_HPT3X3=y +# CONFIG_PATA_HPT3X3_DMA is not set +# CONFIG_PATA_ISAPNP is not set +CONFIG_PATA_IT8213=m +CONFIG_PATA_IT821X=y +CONFIG_PATA_JMICRON=y +CONFIG_PATA_LEGACY=m +CONFIG_PATA_MARVELL=y +CONFIG_PATA_MPIIX=y +CONFIG_PATA_NETCELL=y +CONFIG_PATA_NINJA32=m +CONFIG_PATA_NS87410=y +CONFIG_PATA_NS87415=y +CONFIG_PATA_OLDPIIX=m +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +CONFIG_PATA_PCMCIA=m +CONFIG_PATA_PDC2027X=y +CONFIG_PATA_PDC_OLD=y +CONFIG_PATA_PLATFORM=m +CONFIG_PATA_QDI=y +CONFIG_PATA_RADISYS=m +CONFIG_PATA_RZ1000=y +CONFIG_PATA_SC1200=y +CONFIG_PATA_SCH=y +CONFIG_PATA_SERVERWORKS=y +CONFIG_PATA_SIL680=y +CONFIG_PATA_SIS=y +CONFIG_PATA_TRIFLEX=y +CONFIG_PATA_VIA=y +CONFIG_PATA_WINBOND=y +CONFIG_PATA_WINBOND_VLB=y +# CONFIG_PC300TOO is not set +CONFIG_PC8736x_GPIO=m +CONFIG_PC87413_WDT=m +CONFIG_PCCARD=m +CONFIG_PCCARD_NONSTATIC=m +CONFIG_PCF8575=m +CONFIG_PCI=y +# CONFIG_PCI200SYN is not set +CONFIG_PCIEAER=y +# CONFIG_PCIEASPM is not set +CONFIG_PCIEPORTBUS=y +CONFIG_PCIPCWATCHDOG=m +CONFIG_PCI_ATMEL=m +CONFIG_PCI_BIOS=y +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_DIRECT=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_GOANY=y +# CONFIG_PCI_GOBIOS is not set +# CONFIG_PCI_GODIRECT is not set +# CONFIG_PCI_GOMMCONFIG is not set +# CONFIG_PCI_GOOLPC is not set +CONFIG_PCI_HERMES=m +CONFIG_PCI_LEGACY=y +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_MSI=y +CONFIG_PCI_OLPC=y +CONFIG_PCI_QUIRKS=y +CONFIG_PCMCIA=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_AHA152X=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_PCMCIA_AXNET=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_HERMES=m +CONFIG_PCMCIA_IBMTR=m +CONFIG_PCMCIA_IOCTL=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_NETWAVE=m +CONFIG_PCMCIA_NINJA_SCSI=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_PROBE=y +CONFIG_PCMCIA_QLOGIC=m +CONFIG_PCMCIA_RAYCS=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_SPECTRUM=m +CONFIG_PCMCIA_SYM53C500=m +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_WL3501=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_PCNET32=m +CONFIG_PCSPKR_PLATFORM=y +CONFIG_PCWATCHDOG=m +CONFIG_PD6729=m +CONFIG_PDA_POWER=m +CONFIG_PDC_ADMA=y +CONFIG_PHANTOM=m +CONFIG_PHONE=m +# CONFIG_PHONET is not set +CONFIG_PHONE_IXJ=m +CONFIG_PHONE_IXJ_PCMCIA=m +CONFIG_PHYLIB=m +CONFIG_PHYSICAL_ALIGN=0x100000 +CONFIG_PHYSICAL_START=0x100000 +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_PLIP=m +CONFIG_PLIST=y +CONFIG_PLX_HERMES=m +CONFIG_PM=y +CONFIG_PM_DEBUG=y +CONFIG_PM_DISABLE_CONSOLE=y +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +CONFIG_PM_STD_PARTITION="" +# CONFIG_PM_TEST_SUSPEND is not set +# CONFIG_PM_TRACE_RTC is not set +# CONFIG_PM_VERBOSE is not set +CONFIG_PNP=y +CONFIG_PNPACPI=y +CONFIG_PNPBIOS=y +CONFIG_PNPBIOS_PROC_FS=y +CONFIG_PNP_DEBUG_MESSAGES=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +CONFIG_PPDEV=m +CONFIG_PPP=m +CONFIG_PPPOE=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_SYNC_TTY=m +# CONFIG_PREEMPT is not set +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_NOTIFIERS=y +CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_PRINTER=m +CONFIG_PRINTK=y +CONFIG_PRINTK_TIME=y +CONFIG_PRINT_QUOTA_WARNING=y +CONFIG_PRISM2_USB=m +CONFIG_PRISM54=m +# CONFIG_PROCESSOR_SELECT is not set +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROFILING=y +CONFIG_PROTEON=m +# CONFIG_PROVE_LOCKING is not set +# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set +CONFIG_QC_USB=m +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_QLA3XXX=m +# CONFIG_QLGE is not set +CONFIG_QNX4FS_FS=m +CONFIG_QSEMI_PHY=m +CONFIG_QUOTA=y +CONFIG_QUOTACTL=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +CONFIG_R3964=m +# CONFIG_R6040 is not set +CONFIG_R8169=m +CONFIG_R8169_VLAN=y +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_AZTECH=m +CONFIG_RADIO_CADET=m +CONFIG_RADIO_GEMTEK=m +CONFIG_RADIO_GEMTEK_PCI=m +CONFIG_RADIO_MAESTRO=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RADIO_RTRACK=m +CONFIG_RADIO_RTRACK2=m +CONFIG_RADIO_SF16FMI=m +CONFIG_RADIO_SF16FMR2=m +CONFIG_RADIO_TERRATEC=m +CONFIG_RADIO_TRUST=m +CONFIG_RADIO_TYPHOON=m +CONFIG_RADIO_TYPHOON_PROC_FS=y +CONFIG_RADIO_ZOLTRIX=m +CONFIG_RAID_ATTRS=m +CONFIG_RAW_DRIVER=m +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_REALTEK_PHY is not set +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_DEC16=y +# CONFIG_REGULATOR is not set +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_FS=m +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_REISERFS_FS_XATTR=y +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_RELAY=y +CONFIG_RELOCATABLE=y +# CONFIG_RESOURCES_64BIT is not set +CONFIG_RESOURCE_COUNTERS=y +CONFIG_RFD_FTL=m +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +CONFIG_RFKILL_LEDS=y +CONFIG_RING_BUFFER=y +CONFIG_RIO=m +# CONFIG_RIO_OLDPCI is not set +CONFIG_RISCOM8=m +CONFIG_ROCKETPORT=m +CONFIG_ROMFS_FS=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_RT2400PCI=m +CONFIG_RT2500PCI=m +CONFIG_RT2500USB=m +CONFIG_RT2860=m +CONFIG_RT2870=m +CONFIG_RT2X00=m +# CONFIG_RT2X00_DEBUG is not set +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_CRYPTO=y +# CONFIG_RT2X00_LIB_DEBUGFS is not set +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_LEDS=y +CONFIG_RT2X00_LIB_PCI=m +CONFIG_RT2X00_LIB_RFKILL=y +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT61PCI=m +CONFIG_RT73USB=m +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DEBUG is not set +# CONFIG_RTC_DRV_BQ4802 is not set +CONFIG_RTC_DRV_CMOS=y +# CONFIG_RTC_DRV_DS1286 is not set +CONFIG_RTC_DRV_DS1305=m +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1374=m +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_DS1511 is not set +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_DS1742=m +# CONFIG_RTC_DRV_DS3234 is not set +CONFIG_RTC_DRV_FM3130=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_M41T80_WDT=y +CONFIG_RTC_DRV_M41T94=m +# CONFIG_RTC_DRV_M48T35 is not set +CONFIG_RTC_DRV_M48T59=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +# CONFIG_RTC_DRV_R9701 is not set +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_RS5C372=m +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_S35390A is not set +CONFIG_RTC_DRV_STK17TA8=m +CONFIG_RTC_DRV_TEST=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_LIB=y +CONFIG_RTL8180=m +CONFIG_RTL8187=m +CONFIG_RTL8187SE=m +CONFIG_RT_GROUP_SCHED=y +CONFIG_RT_MUTEXES=y +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_RXKAD=m +CONFIG_S2IO=m +# CONFIG_SAMPLES is not set +CONFIG_SATA_AHCI=m +CONFIG_SATA_INIC162X=y +CONFIG_SATA_MV=m +CONFIG_SATA_NV=y +CONFIG_SATA_PMP=y +CONFIG_SATA_PROMISE=y +CONFIG_SATA_QSTOR=y +CONFIG_SATA_SIL=y +CONFIG_SATA_SIL24=m +CONFIG_SATA_SIS=y +CONFIG_SATA_SVW=y +CONFIG_SATA_SX4=m +CONFIG_SATA_ULI=y +CONFIG_SATA_VIA=y +CONFIG_SATA_VITESSE=y +CONFIG_SBC7240_WDT=m +CONFIG_SBC8360_WDT=m +CONFIG_SBC_EPX_C3_WATCHDOG=m +# CONFIG_SBNI is not set +CONFIG_SC1200_WDT=m +CONFIG_SC520_WDT=m +CONFIG_SC92031=m +CONFIG_SCHEDSTATS=y +CONFIG_SCHED_DEBUG=y +CONFIG_SCHED_HRTICK=y +CONFIG_SCHED_MC=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_SCHED_SMT=y +CONFIG_SCHED_TRACER=y +CONFIG_SCSI=y +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_7000FASST=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_ADVANSYS=m +CONFIG_SCSI_AHA152X=m +CONFIG_SCSI_AHA1542=m +CONFIG_SCSI_AHA1740=m +CONFIG_SCSI_AIC79XX=m +CONFIG_SCSI_AIC7XXX=m +# CONFIG_SCSI_AIC7XXX_OLD is not set +CONFIG_SCSI_AIC94XX=m +CONFIG_SCSI_ARCMSR=m +CONFIG_SCSI_ARCMSR_AER=y +CONFIG_SCSI_BUSLOGIC=m +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_DC390T=m +CONFIG_SCSI_DC395x=m +CONFIG_SCSI_DEBUG=m +# CONFIG_SCSI_DH is not set +CONFIG_SCSI_DMA=y +CONFIG_SCSI_DMX3191D=m +CONFIG_SCSI_DPT_I2O=m +CONFIG_SCSI_DTC3280=m +CONFIG_SCSI_EATA=m +CONFIG_SCSI_EATA_LINKED_COMMANDS=y +CONFIG_SCSI_EATA_MAX_TAGS=16 +CONFIG_SCSI_EATA_TAGGED_QUEUE=y +CONFIG_SCSI_ENCLOSURE=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_FC_TGT_ATTRS=y +CONFIG_SCSI_FD_MCS=m +# CONFIG_SCSI_FLASHPOINT is not set +CONFIG_SCSI_FUTURE_DOMAIN=m +CONFIG_SCSI_GDTH=m +CONFIG_SCSI_GENERIC_NCR5380=m +CONFIG_SCSI_GENERIC_NCR5380_MMIO=m +CONFIG_SCSI_GENERIC_NCR53C400=y +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_IBMMCA=m +CONFIG_SCSI_IMM=m +CONFIG_SCSI_IN2000=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_IPR=m +# CONFIG_SCSI_IPR_DUMP is not set +# CONFIG_SCSI_IPR_TRACE is not set +CONFIG_SCSI_IPS=m +CONFIG_SCSI_ISCSITARGET=m +CONFIG_SCSI_ISCSI_ATTRS=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_LOWLEVEL=y +CONFIG_SCSI_LOWLEVEL_PCMCIA=y +CONFIG_SCSI_LPFC=m +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_MVSAS is not set +CONFIG_SCSI_NCR53C406A=m +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=4 +CONFIG_SCSI_NCR53C8XX_SYNC=5 +CONFIG_SCSI_NCR_D700=m +CONFIG_SCSI_NCR_Q720=m +CONFIG_SCSI_NETLINK=y +CONFIG_SCSI_NSP32=m +CONFIG_SCSI_PAS16=m +CONFIG_SCSI_PPA=m +CONFIG_SCSI_PROC_FS=y +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_QLOGIC_FAS=m +CONFIG_SCSI_SAS_ATA=y +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_HOST_SMP=y +CONFIG_SCSI_SAS_LIBSAS=m +# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_SIM710=m +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_SRP=m +CONFIG_SCSI_SRP_ATTRS=m +CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C416=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_T128=m +CONFIG_SCSI_TGT=m +CONFIG_SCSI_U14_34F=m +CONFIG_SCSI_U14_34F_LINKED_COMMANDS=y +CONFIG_SCSI_U14_34F_MAX_TAGS=8 +CONFIG_SCSI_U14_34F_TAGGED_QUEUE=y +CONFIG_SCSI_ULTRASTOR=m +CONFIG_SCSI_WAIT_SCAN=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_HMAC_MD5=y +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCx200=m +CONFIG_SCx200HR_TIMER=m +CONFIG_SCx200_ACB=m +CONFIG_SCx200_GPIO=m +CONFIG_SCx200_I2C=m +CONFIG_SCx200_I2C_SCL=12 +CONFIG_SCx200_I2C_SDA=13 +CONFIG_SCx200_WDT=m +CONFIG_SDIO_UART=m +# CONFIG_SEALEVEL_4021 is not set +CONFIG_SECCOMP=y +CONFIG_SECURITY=y +CONFIG_SECURITYFS=y +CONFIG_SECURITY_APPARMOR=y +CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 +# CONFIG_SECURITY_APPARMOR_DISABLE is not set +CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=65536 +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_DISABLE=y +# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set +# CONFIG_SECURITY_SMACK is not set +CONFIG_SEEQ8005=m +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_ABITUGURU3=m +CONFIG_SENSORS_AD7414=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADCXX=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ADS7828=m +# CONFIG_SENSORS_ADT7462 is not set +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_ADT7473=m +CONFIG_SENSORS_APPLESMC=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_CORETEMP=m +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_FSCHMD=m +CONFIG_SENSORS_FSCPOS=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_HDAPS=m +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_IBMAEM=m +CONFIG_SENSORS_IBMPEX=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_K8TEMP=m +# CONFIG_SENSORS_LIS3LV02D is not set +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_LM93=m +# CONFIG_SENSORS_MAX1111 is not set +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCA9539=m +CONFIG_SENSORS_PCF8574=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_TSL2550=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SENSORS_W83L786NG=m +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_ACCENT=m +CONFIG_SERIAL_8250_BOCA=m +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_CS=m +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_EXAR_ST16C554=m +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_FOURPORT=m +CONFIG_SERIAL_8250_HUB6=m +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_MCA=m +CONFIG_SERIAL_8250_NR_UARTS=48 +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_PNP=y +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_JSM=m +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_SERIO=y +CONFIG_SERIO_CT82C710=m +CONFIG_SERIO_I8042=y +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_PARKBD=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SERIO_RAW=m +CONFIG_SERIO_SERPORT=m +CONFIG_SFC=m +CONFIG_SGI_IOC4=m +CONFIG_SGI_PARTITION=y +CONFIG_SHMEM=y +CONFIG_SIGMATEL_FIR=m +CONFIG_SIGNALFD=y +CONFIG_SIS190=m +CONFIG_SIS900=m +CONFIG_SKGE=m +# CONFIG_SKGE_DEBUG is not set +CONFIG_SKISA=m +CONFIG_SKY2=m +# CONFIG_SKY2_DEBUG is not set +# CONFIG_SLAB is not set +CONFIG_SLABINFO=y +CONFIG_SLHC=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_MODE_SLIP6=y +CONFIG_SLIP_SMART=y +# CONFIG_SLOB is not set +CONFIG_SLUB=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_SMC9194=m +CONFIG_SMCTR=m +CONFIG_SMC_IRCC_FIR=m +CONFIG_SMP=y +CONFIG_SMSC37B787_WDT=m +# CONFIG_SMSC911X is not set +CONFIG_SMSC_PHY=m +CONFIG_SND=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_AC97_POWER_SAVE=y +CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0 +CONFIG_SND_AD1889=m +CONFIG_SND_ALI5451=m +CONFIG_SND_ALS300=m +CONFIG_SND_ALS4000=m +CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m +CONFIG_SND_AU8810=m +CONFIG_SND_AU8820=m +CONFIG_SND_AU8830=m +CONFIG_SND_AW2=m +CONFIG_SND_AZT3328=m +CONFIG_SND_BT87X=m +# CONFIG_SND_BT87X_OVERCLOCK is not set +CONFIG_SND_BTSCO=m +CONFIG_SND_CA0106=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_CS4281=m +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_CS5530=m +CONFIG_SND_CS5535AUDIO=m +CONFIG_SND_DARLA20=m +CONFIG_SND_DARLA24=m +# CONFIG_SND_DEBUG is not set +CONFIG_SND_DRIVERS=y +CONFIG_SND_DUMMY=m +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_ECHO3G=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_EMU10K1X=m +CONFIG_SND_ENS1370=m +CONFIG_SND_ENS1371=m +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +CONFIG_SND_FM801=m +CONFIG_SND_FM801_TEA575X=m +CONFIG_SND_FM801_TEA575X_BOOL=y +CONFIG_SND_GINA20=m +CONFIG_SND_GINA24=m +CONFIG_SND_HDA_CODEC_ANALOG=y +CONFIG_SND_HDA_CODEC_ATIHDMI=y +CONFIG_SND_HDA_CODEC_CMEDIA=y +CONFIG_SND_HDA_CODEC_CONEXANT=y +CONFIG_SND_HDA_CODEC_INTELHDMI=y +CONFIG_SND_HDA_CODEC_NVHDMI=y +CONFIG_SND_HDA_CODEC_REALTEK=y +CONFIG_SND_HDA_CODEC_SI3054=y +# CONFIG_SND_HDA_CODEC_SIGMATEL is not set +CONFIG_SND_HDA_CODEC_VIA=y +CONFIG_SND_HDA_ELD=y +CONFIG_SND_HDA_GENERIC=y +# CONFIG_SND_HDA_HWDEP is not set +# CONFIG_SND_HDA_INPUT_BEEP is not set +CONFIG_SND_HDA_INTEL=m +CONFIG_SND_HDA_POWER_SAVE=y +CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 +CONFIG_SND_HDSP=m +CONFIG_SND_HDSPM=m +CONFIG_SND_HIFIER=m +CONFIG_SND_HWDEP=m +CONFIG_SND_ICE1712=m +CONFIG_SND_ICE1724=m +CONFIG_SND_INDIGO=m +CONFIG_SND_INDIGODJ=m +CONFIG_SND_INDIGOIO=m +CONFIG_SND_INTEL8X0=m +CONFIG_SND_INTEL8X0M=m +# CONFIG_SND_ISA is not set +CONFIG_SND_KORG1212=m +CONFIG_SND_LAYLA20=m +CONFIG_SND_LAYLA24=m +CONFIG_SND_LPIA_HDA_CODEC_SIGMATEL=y +CONFIG_SND_MAESTRO3=m +CONFIG_SND_MIA=m +CONFIG_SND_MIXART=m +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_MONA=m +CONFIG_SND_MPU401=m +CONFIG_SND_MPU401_UART=m +CONFIG_SND_MTPAV=m +CONFIG_SND_MTS64=m +CONFIG_SND_NM256=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_OXYGEN=m +CONFIG_SND_OXYGEN_LIB=m +CONFIG_SND_PCI=y +CONFIG_SND_PCM=m +# CONFIG_SND_PCMCIA is not set +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_PCSP=m +CONFIG_SND_PCXHR=m +CONFIG_SND_PORTMAN2X4=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_RIPTIDE=m +CONFIG_SND_RME32=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m +CONFIG_SND_SB16_DSP=m +CONFIG_SND_SB_COMMON=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_SIS7019=m +CONFIG_SND_SOC=m +# CONFIG_SND_SOC_ALL_CODECS is not set +CONFIG_SND_SONICVIBES=m +CONFIG_SND_SPI=y +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_TIMER=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +# CONFIG_SND_USB_US122L is not set +CONFIG_SND_USB_USX2Y=m +# CONFIG_SND_VERBOSE_PRINTK is not set +CONFIG_SND_VERBOSE_PROCFS=y +CONFIG_SND_VIA82XX=m +CONFIG_SND_VIA82XX_MODEM=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_VIRTUOSO=m +CONFIG_SND_VMASTER=y +CONFIG_SND_VX222=m +CONFIG_SND_VX_LIB=m +CONFIG_SND_YMFPCI=m +CONFIG_SOC_CAMERA=m +CONFIG_SOC_CAMERA_MT9M001=m +# CONFIG_SOC_CAMERA_MT9M111 is not set +CONFIG_SOC_CAMERA_MT9V022=m +CONFIG_SOC_CAMERA_PLATFORM=m +CONFIG_SOFT_WATCHDOG=m +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_SONYPI=m +CONFIG_SONYPI_COMPAT=y +CONFIG_SONY_LAPTOP=m +CONFIG_SOUND=m +CONFIG_SOUND_OSS_CORE=y +# CONFIG_SOUND_PRIME is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_SPARSEMEM_STATIC=y +CONFIG_SPECIALIX=m +CONFIG_SPI=y +CONFIG_SPI_AT25=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_LM70_LLP=m +CONFIG_SPI_MASTER=y +CONFIG_SPI_SPIDEV=m +CONFIG_SPI_TLE62X0=m +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_SQUASHFS=m +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +CONFIG_SSB=m +CONFIG_SSB_B43_PCI_BRIDGE=y +# CONFIG_SSB_DEBUG is not set +CONFIG_SSB_DRIVER_PCICORE=y +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +# CONFIG_SSB_PCMCIAHOST is not set +CONFIG_SSB_PCMCIAHOST_POSSIBLE=y +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB_SILENT is not set +CONFIG_SSB_SPROM=y +CONFIG_SSFDC=m +CONFIG_STACKTRACE=y +CONFIG_STACKTRACE_SUPPORT=y +# CONFIG_STACK_TRACER is not set +# CONFIG_STAGING is not set +CONFIG_STALDRV=y +# CONFIG_STALLION is not set +# CONFIG_STANDALONE is not set +CONFIG_STOP_MACHINE=y +CONFIG_STP=m +CONFIG_STRICT_DEVMEM=y +CONFIG_STRIP=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_SUNGEM=m +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +# CONFIG_SUNRPC_REGISTER_V4 is not set +CONFIG_SUNRPC_XPRT_RDMA=m +CONFIG_SUN_PARTITION=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_SWAP=y +CONFIG_SX=m +CONFIG_SYNCLINK=m +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_CS=m +CONFIG_SYNCLINK_GT=m +CONFIG_SYN_COOKIES=y +CONFIG_SYSCTL=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_SYSFS=y +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSPROF_TRACER is not set +CONFIG_SYSV68_PARTITION=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_SYSV_FS=m +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +CONFIG_TASKSTATS=y +# CONFIG_TASK_DELAY_ACCT is not set +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_TASK_XACCT=y +# CONFIG_TC1100_WMI is not set +CONFIG_TCG_ATMEL=m +CONFIG_TCG_INFINEON=m +CONFIG_TCG_NSC=m +CONFIG_TCG_TIS=m +CONFIG_TCG_TPM=m +CONFIG_TCIC=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_MD5SIG=y +CONFIG_TEHUTI=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TELCLOCK=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_TEXTSEARCH_KMP=m +CONFIG_THERMAL=y +CONFIG_THERMAL_HWMON=y +CONFIG_THINKPAD_ACPI=m +CONFIG_THINKPAD_ACPI_BAY=y +# CONFIG_THINKPAD_ACPI_DEBUG is not set +CONFIG_THINKPAD_ACPI_HOTKEY_POLL=y +CONFIG_THINKPAD_ACPI_VIDEO=y +# CONFIG_THRUSTMASTER_FF is not set +CONFIG_TICK_ONESHOT=y +CONFIG_TIFM_7XX1=m +CONFIG_TIFM_CORE=m +CONFIG_TIGON3=m +CONFIG_TIMERFD=y +CONFIG_TIMER_STATS=y +# CONFIG_TINY_SHMEM is not set +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set +CONFIG_TLAN=m +CONFIG_TLSF=m +# CONFIG_TLSF_DEBUG is not set +# CONFIG_TLSF_STATS is not set +CONFIG_TLSUP=m +CONFIG_TMD_HERMES=m +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMS380TR=m +CONFIG_TMSPCI=m +# CONFIG_TOIM3232_DONGLE is not set +CONFIG_TOSHIBA=m +CONFIG_TOSHIBA_FIR=m +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_HTCPEN=m +CONFIG_TOUCHSCREEN_INEXIO=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TOUCHIT213=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +# CONFIG_TOUCHSCREEN_WM9705 is not set +# CONFIG_TOUCHSCREEN_WM9712 is not set +# CONFIG_TOUCHSCREEN_WM9713 is not set +CONFIG_TOUCHSCREEN_WM97XX=m +CONFIG_TP_SMAPI=m +CONFIG_TP_SMAPI_EC=m +CONFIG_TR=y +CONFIG_TRACEPOINTS=y +CONFIG_TRACER_MAX_TRACE=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_TRACING=y +CONFIG_TTPCI_EEPROM=m +CONFIG_TULIP=m +# CONFIG_TULIP_MMIO is not set +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_NAPI is not set +CONFIG_TUN=m +CONFIG_TYPHOON=m +CONFIG_UBIFS_FS=m +CONFIG_UBIFS_FS_ADVANCED_COMPR=y +# CONFIG_UBIFS_FS_DEBUG is not set +CONFIG_UBIFS_FS_LZO=y +# CONFIG_UBIFS_FS_XATTR is not set +CONFIG_UBIFS_FS_ZLIB=y +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +CONFIG_UEVENT_HELPER_PATH="" +# CONFIG_UFS_DEBUG is not set +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +CONFIG_UID16=y +CONFIG_UIO=m +CONFIG_UIO_CIF=m +# CONFIG_UIO_PDRV is not set +# CONFIG_UIO_PDRV_GENIRQ is not set +# CONFIG_UIO_SERCOS3 is not set +CONFIG_UIO_SMX=m +CONFIG_ULI526X=m +CONFIG_ULTRA=m +CONFIG_ULTRA32=m +CONFIG_ULTRAMCA=m +CONFIG_ULTRIX_PARTITION=y +CONFIG_UNEVICTABLE_LRU=y +CONFIG_UNIX=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_USB=m +CONFIG_USBPCWATCHDOG=m +CONFIG_USB_ACM=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_APPLEIR=m +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_ATMEL=m +CONFIG_USB_BELKIN=y +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_C67X00_HCD=m +CONFIG_USB_CATC=m +CONFIG_USB_CDC_COMPOSITE=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +CONFIG_USB_DSBR=m +CONFIG_USB_DUMMY_HCD=m +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_EHCI_HCD=m +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EMI26=m +CONFIG_USB_EMI62=m +CONFIG_USB_EPSON2888=y +CONFIG_USB_ET61X251=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_EZUSB=y +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_GADGET=m +CONFIG_USB_GADGETFS=m +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_ARC is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_DUALSPEED=y +CONFIG_USB_GADGET_DUMMY_HCD=y +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C2410 is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GSPCA=m +# CONFIG_USB_GSPCA_CONEX is not set +# CONFIG_USB_GSPCA_ETOMS is not set +# CONFIG_USB_GSPCA_FINEPIX is not set +# CONFIG_USB_GSPCA_MARS is not set +# CONFIG_USB_GSPCA_OV519 is not set +# CONFIG_USB_GSPCA_PAC207 is not set +# CONFIG_USB_GSPCA_PAC7311 is not set +# CONFIG_USB_GSPCA_SONIXB is not set +# CONFIG_USB_GSPCA_SONIXJ is not set +# CONFIG_USB_GSPCA_SPCA500 is not set +# CONFIG_USB_GSPCA_SPCA501 is not set +# CONFIG_USB_GSPCA_SPCA505 is not set +# CONFIG_USB_GSPCA_SPCA506 is not set +# CONFIG_USB_GSPCA_SPCA508 is not set +# CONFIG_USB_GSPCA_SPCA561 is not set +# CONFIG_USB_GSPCA_STK014 is not set +# CONFIG_USB_GSPCA_SUNPLUS is not set +# CONFIG_USB_GSPCA_T613 is not set +# CONFIG_USB_GSPCA_TV8532 is not set +# CONFIG_USB_GSPCA_VC032X is not set +# CONFIG_USB_GSPCA_ZC3XX is not set +# CONFIG_USB_G_PRINTER is not set +CONFIG_USB_G_SERIAL=m +CONFIG_USB_HID=m +CONFIG_USB_HIDDEV=y +CONFIG_USB_HSO=m +# CONFIG_USB_HWA_HCD is not set +CONFIG_USB_IBMCAM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_IRDA=m +CONFIG_USB_ISIGHTFW=m +CONFIG_USB_ISP116X_HCD=m +CONFIG_USB_ISP1760_HCD=m +CONFIG_USB_KAWETH=m +CONFIG_USB_KBD=m +CONFIG_USB_KC2190=y +CONFIG_USB_KONICAWC=m +CONFIG_USB_LCD=m +CONFIG_USB_LD=m +CONFIG_USB_LED=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LIBUSUAL=y +# CONFIG_USB_M5602 is not set +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_USB_MON=y +CONFIG_USB_MOUSE=m +# CONFIG_USB_MR800 is not set +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_RNDIS_WLAN=m +# CONFIG_USB_NET_SMSC95XX is not set +CONFIG_USB_NET_ZAURUS=m +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_OHCI_HCD_SSB is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OV511 is not set +CONFIG_USB_OV511_NEW=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_PRINTER=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_R8A66597_HCD=m +CONFIG_USB_RIO500=m +CONFIG_USB_RTL8150=m +CONFIG_USB_S2255=m +CONFIG_USB_SE401=m +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IPW=m +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_IUU is not set +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_MOTOROLA=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_XIRCOM=m +# CONFIG_USB_SEVSEG is not set +CONFIG_USB_SI470X=m +CONFIG_USB_SISUSBVGA=m +# CONFIG_USB_SISUSBVGA_CON is not set +CONFIG_USB_SL811_CS=m +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SN9C102=m +CONFIG_USB_STKWEBCAM=m +CONFIG_USB_STORAGE=m +CONFIG_USB_STORAGE_ALAUDA=y +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +CONFIG_USB_STORAGE_DATAFAB=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_KARMA=y +# CONFIG_USB_STORAGE_ONETOUCH is not set +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STV680=m +CONFIG_USB_SUPPORT=y +CONFIG_USB_SUSPEND=y +# CONFIG_USB_TEST is not set +# CONFIG_USB_TMC is not set +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_U132_HCD=m +CONFIG_USB_UHCI_HCD=m +CONFIG_USB_USBNET=m +CONFIG_USB_USS720=m +CONFIG_USB_VICAM=m +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +# CONFIG_USB_VST is not set +CONFIG_USB_W9968CF=m +CONFIG_USB_WDM=m +# CONFIG_USB_WHCI_HCD is not set +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set +CONFIG_USB_ZC0301=m +CONFIG_USB_ZD1201=m +CONFIG_USB_ZERO=m +CONFIG_USB_ZR364XX=m +# CONFIG_USER_SCHED is not set +CONFIG_USE_GENERIC_SMP_HELPERS=y +# CONFIG_UWB is not set +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VERSION_SIGNATURE="" +CONFIG_VETH=m +CONFIG_VFAT_FS=m +# CONFIG_VGACON_SOFT_SCROLLBACK is not set +CONFIG_VGASTATE=m +CONFIG_VGA_CONSOLE=y +CONFIG_VIA_FIR=m +CONFIG_VIA_RHINE=m +CONFIG_VIA_RHINE_MMIO=y +CONFIG_VIA_VELOCITY=m +CONFIG_VIDEOBUF_DMA_SG=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_ALLOW_V4L1=y +CONFIG_VIDEO_AU0828=m +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BTCX=m +CONFIG_VIDEO_BWQCAM=m +CONFIG_VIDEO_CAFE_CCIC=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_CPIA_PP=m +CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_CS5345=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_CX18=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_CX23885=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_ALSA=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_EM28XX_ALSA=m +CONFIG_VIDEO_EM28XX_DVB=m +CONFIG_VIDEO_FB_IVTV=m +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_IR_I2C=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_M52790=m +CONFIG_VIDEO_MEDIA=m +CONFIG_VIDEO_MEYE=m +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_MXB=m +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_VIDEO_PMS=m +CONFIG_VIDEO_PVRUSB2=m +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_PVRUSB2_DVB=y +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA7111=m +CONFIG_VIDEO_SAA7114=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_ALSA=m +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_SAA717X=m +CONFIG_VIDEO_SAA7185=m +# CONFIG_VIDEO_SH_MOBILE_CEU is not set +CONFIG_VIDEO_STRADIS=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TDA9875=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_V4L1=m +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=m +CONFIG_VIDEO_V4L2_COMMON=m +CONFIG_VIDEO_VIVI=m +CONFIG_VIDEO_VP27SMPX=m +CONFIG_VIDEO_VPX3220=m +CONFIG_VIDEO_W9966=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_ZR36060=m +CONFIG_VIRTIO=y +CONFIG_VIRTIO_BALLOON=m +CONFIG_VIRTIO_BLK=m +CONFIG_VIRTIO_CONSOLE=y +CONFIG_VIRTIO_NET=m +CONFIG_VIRTIO_PCI=m +CONFIG_VIRTIO_RING=y +CONFIG_VIRTUALIZATION=y +CONFIG_VIRT_TO_BUS=y +CONFIG_VITESSE_PHY=m +CONFIG_VLAN_8021Q=m +# CONFIG_VLAN_8021Q_GVRP is not set +CONFIG_VLSI_FIR=m +CONFIG_VM86=y +# CONFIG_VMI is not set +# CONFIG_VMSPLIT_1G is not set +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_2G_OPT is not set +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_3G_OPT is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VORTEX=m +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_VXFS_FS=m +CONFIG_W1=m +CONFIG_W1_CON=y +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_MATROX=m +# CONFIG_W1_SLAVE_BQ27000 is not set +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +# CONFIG_W1_SLAVE_DS2438 is not set +CONFIG_W1_SLAVE_DS2760=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_THERM=m +CONFIG_W83627HF_WDT=m +CONFIG_W83697HF_WDT=m +# CONFIG_W83697UG_WDT is not set +CONFIG_W83877F_WDT=m +CONFIG_W83977F_WDT=m +CONFIG_WAFER_WDT=m +CONFIG_WAN=y +# CONFIG_WANXL is not set +# CONFIG_WAN_ROUTER is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +CONFIG_WAVELAN=m +CONFIG_WD80x3=m +CONFIG_WDT=m +CONFIG_WDTPCI=m +CONFIG_WDT_501=y +CONFIG_WDT_501_PCI=y +CONFIG_WINBOND_840=m +CONFIG_WINBOND_FIR=m +CONFIG_WIRELESS=y +CONFIG_WIRELESS_ACX=m +CONFIG_WIRELESS_EXT=y +# CONFIG_WIRELESS_EXT_SYSFS is not set +# CONFIG_WIRELESS_OLD_REGULATORY is not set +CONFIG_WLAN_80211=y +CONFIG_WLAN_PRE80211=y +# CONFIG_X25 is not set +CONFIG_X86=y +CONFIG_X86_32=y +CONFIG_X86_32_SMP=y +# CONFIG_X86_64 is not set +CONFIG_X86_ACPI_CPUFREQ=y +# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set +CONFIG_X86_ALIGNMENT_16=y +CONFIG_X86_BIOS_REBOOT=y +CONFIG_X86_BSWAP=y +# CONFIG_X86_CHECK_BIOS_CORRUPTION is not set +CONFIG_X86_CMPXCHG=y +CONFIG_X86_CPU=y +CONFIG_X86_CPUFREQ_NFORCE2=y +CONFIG_X86_CPUID=m +# CONFIG_X86_ELAN is not set +# CONFIG_X86_E_POWERSAVER is not set +CONFIG_X86_F00F_BUG=y +CONFIG_X86_FIND_SMP_CONFIG=y +CONFIG_X86_GENERIC=y +# CONFIG_X86_GENERICARCH is not set +CONFIG_X86_GX_SUSPMOD=y +CONFIG_X86_HT=y +CONFIG_X86_INTEL_USERCOPY=y +CONFIG_X86_INVLPG=y +CONFIG_X86_IO_APIC=y +CONFIG_X86_L1_CACHE_SHIFT=7 +CONFIG_X86_LOCAL_APIC=y +CONFIG_X86_LONGHAUL=y +CONFIG_X86_LONGRUN=y +CONFIG_X86_LPIA=y +# CONFIG_X86_MCE is not set +CONFIG_X86_MINIMUM_CPU_FAMILY=4 +CONFIG_X86_MPPARSE=y +CONFIG_X86_MSR=m +CONFIG_X86_P4_CLOCKMOD=m +CONFIG_X86_PAT=y +CONFIG_X86_PC=y +CONFIG_X86_PM_TIMER=y +CONFIG_X86_POPAD_OK=y +CONFIG_X86_POWERNOW_K6=y +CONFIG_X86_POWERNOW_K7=y +CONFIG_X86_POWERNOW_K7_ACPI=y +CONFIG_X86_POWERNOW_K8=y +CONFIG_X86_POWERNOW_K8_ACPI=y +CONFIG_X86_PPRO_FENCE=y +# CONFIG_X86_PTDUMP is not set +# CONFIG_X86_RDC321X is not set +CONFIG_X86_REBOOTFIXUPS=y +CONFIG_X86_RESERVE_LOW_64K=y +CONFIG_X86_SMP=y +CONFIG_X86_SPEEDSTEP_CENTRINO=y +CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE=y +CONFIG_X86_SPEEDSTEP_ICH=y +CONFIG_X86_SPEEDSTEP_LIB=y +CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK=y +CONFIG_X86_SPEEDSTEP_SMI=y +CONFIG_X86_TRAMPOLINE=y +CONFIG_X86_VERBOSE_BOOTUP=y +# CONFIG_X86_VOYAGER is not set +# CONFIG_X86_VSMP is not set +CONFIG_X86_WP_WORKS_OK=y +CONFIG_X86_XADD=y +CONFIG_XFRM=y +CONFIG_XFRM_IPCOMP=m +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_XFRM_USER=m +# CONFIG_XFS_DEBUG is not set +CONFIG_XFS_FS=m +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_QUOTA=y +CONFIG_XFS_RT=y +CONFIG_XOR_BLOCKS=m +CONFIG_YELLOWFIN=m +CONFIG_YENTA=m +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +# CONFIG_ZEROPLUS_FF is not set +CONFIG_ZISOFS=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZNET=m +CONFIG_ZONE_DMA=y +# CONFIG_ZONE_DMA32 is not set +CONFIG_ZONE_DMA_FLAG=1 --- linux-2.6.28.orig/debian/config/amd64/config.generic +++ linux-2.6.28/debian/config/amd64/config.generic @@ -0,0 +1,11 @@ +# +# Config options for config.generic automatically generated by splitconfig.pl +# +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y --- linux-2.6.28.orig/debian/config/amd64/config.server +++ linux-2.6.28/debian/config/amd64/config.server @@ -0,0 +1,11 @@ +# +# Config options for config.server automatically generated by splitconfig.pl +# +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_DEADLINE=y +CONFIG_DEFAULT_IOSCHED="deadline" +CONFIG_HZ=100 +CONFIG_HZ_100=y +# CONFIG_HZ_250 is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set --- linux-2.6.28.orig/debian/config/amd64/config +++ linux-2.6.28/debian/config/amd64/config @@ -0,0 +1,3681 @@ +# +# Common config options automatically generated by splitconfig.pl +# +CONFIG_3C359=m +CONFIG_60XX_WDT=m +CONFIG_64BIT=y +CONFIG_6PACK=m +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_8129=y +CONFIG_8139TOO_PIO=y +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139_OLD_RX_RESET is not set +CONFIG_9P_FS=m +CONFIG_ABYSS=m +CONFIG_AC97_BUS=m +# CONFIG_ACCESSIBILITY is not set +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_ACER_WMI=m +CONFIG_ACORN_PARTITION=y +# CONFIG_ACORN_PARTITION_ADFS is not set +# CONFIG_ACORN_PARTITION_CUMANA is not set +# CONFIG_ACORN_PARTITION_EESOX is not set +CONFIG_ACORN_PARTITION_ICS=y +# CONFIG_ACORN_PARTITION_POWERTEC is not set +CONFIG_ACORN_PARTITION_RISCIX=y +CONFIG_ACPI=y +CONFIG_ACPI_AC=y +# CONFIG_ACPI_ASUS is not set +CONFIG_ACPI_BATTERY=y +CONFIG_ACPI_BLACKLIST_YEAR=0 +CONFIG_ACPI_BUTTON=y +CONFIG_ACPI_CONTAINER=y +# CONFIG_ACPI_CUSTOM_DSDT is not set +CONFIG_ACPI_CUSTOM_DSDT_FILE="" +CONFIG_ACPI_CUSTOM_DSDT_INITRD=y +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_DOCK=y +CONFIG_ACPI_FAN=y +CONFIG_ACPI_HOTPLUG_CPU=y +CONFIG_ACPI_PCI_SLOT=y +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_PROCFS=y +CONFIG_ACPI_PROCFS_POWER=y +CONFIG_ACPI_PROC_EVENT=y +CONFIG_ACPI_SBS=y +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_SYSFS_POWER=y +CONFIG_ACPI_SYSTEM=y +CONFIG_ACPI_THERMAL=y +CONFIG_ACPI_TOSHIBA=m +CONFIG_ACPI_VIDEO=m +CONFIG_ACPI_WMI=y +CONFIG_ACQUIRE_WDT=m +CONFIG_ACT200L_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_ADAPTEC_STARFIRE=m +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_ADM8211=m +CONFIG_ADVANTECH_WDT=m +CONFIG_AFFS_FS=m +# CONFIG_AFS_DEBUG is not set +CONFIG_AFS_FS=m +CONFIG_AF_RXRPC=m +# CONFIG_AF_RXRPC_DEBUG is not set +CONFIG_AGP=y +CONFIG_AGP_AMD64=y +CONFIG_AGP_INTEL=m +CONFIG_AGP_SIS=m +CONFIG_AGP_VIA=m +CONFIG_AIC79XX_CMDS_PER_DEVICE=32 +CONFIG_AIC79XX_DEBUG_ENABLE=y +CONFIG_AIC79XX_DEBUG_MASK=0 +CONFIG_AIC79XX_REG_PRETTY_PRINT=y +CONFIG_AIC79XX_RESET_DELAY_MS=15000 +CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 +CONFIG_AIC7XXX_DEBUG_ENABLE=y +CONFIG_AIC7XXX_DEBUG_MASK=0 +CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC94XX_DEBUG is not set +CONFIG_AIO=y +CONFIG_AIRO=m +CONFIG_AIRO_CS=m +CONFIG_ALIM1535_WDT=m +CONFIG_ALIM7101_WDT=m +CONFIG_ALI_FIR=m +CONFIG_AMD8111_ETH=m +CONFIG_AMD_IOMMU=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ANON_INODES=y +CONFIG_APPLICOM=m +CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig" +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_ARCH_HAS_CPU_RELAX=y +CONFIG_ARCH_HAS_DEFAULT_IDLE=y +CONFIG_ARCH_HIBERNATION_HEADER=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_ARCH_PHYS_ADDR_T_64BIT=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUPPORTS_MSI=y +CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +CONFIG_ARCNET=m +CONFIG_ARCNET_1051=m +CONFIG_ARCNET_1201=m +CONFIG_ARCNET_CAP=m +CONFIG_ARCNET_COM20020=m +CONFIG_ARCNET_COM20020_CS=m +CONFIG_ARCNET_COM20020_PCI=m +CONFIG_ARCNET_COM90xx=m +CONFIG_ARCNET_COM90xxIO=m +CONFIG_ARCNET_RAW=m +CONFIG_ARCNET_RIM_I=m +# CONFIG_ARPD is not set +CONFIG_ASK_IP_FIB_HASH=y +CONFIG_ASUS_LAPTOP=m +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_AT24=m +CONFIG_ATA=y +CONFIG_ATALK=m +CONFIG_ATARI_PARTITION=y +CONFIG_ATA_ACPI=y +CONFIG_ATA_GENERIC=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_OVER_ETH=m +CONFIG_ATA_PIIX=y +CONFIG_ATA_SFF=y +CONFIG_ATH5K=m +# CONFIG_ATH5K_DEBUG is not set +CONFIG_ATH9K=m +CONFIG_ATL1=m +CONFIG_ATL1E=m +CONFIG_ATL2=m +CONFIG_ATM=y +CONFIG_ATMEL=m +CONFIG_ATM_AMBASSADOR=m +# CONFIG_ATM_AMBASSADOR_DEBUG is not set +CONFIG_ATM_BR2684=m +# CONFIG_ATM_BR2684_IPFILTER is not set +CONFIG_ATM_CLIP=y +# CONFIG_ATM_CLIP_NO_ICMP is not set +CONFIG_ATM_DRIVERS=y +# CONFIG_ATM_DUMMY is not set +CONFIG_ATM_ENI=m +# CONFIG_ATM_ENI_DEBUG is not set +# CONFIG_ATM_ENI_TUNE_BURST is not set +CONFIG_ATM_FIRESTREAM=m +CONFIG_ATM_FORE200E=m +CONFIG_ATM_FORE200E_DEBUG=0 +CONFIG_ATM_FORE200E_TX_RETRY=16 +# CONFIG_ATM_FORE200E_USE_TASKLET is not set +CONFIG_ATM_HE=m +CONFIG_ATM_HE_USE_SUNI=y +CONFIG_ATM_HORIZON=m +# CONFIG_ATM_HORIZON_DEBUG is not set +CONFIG_ATM_IA=m +# CONFIG_ATM_IA_DEBUG is not set +CONFIG_ATM_IDT77252=m +# CONFIG_ATM_IDT77252_DEBUG is not set +# CONFIG_ATM_IDT77252_RCV_ALL is not set +CONFIG_ATM_IDT77252_USE_SUNI=y +CONFIG_ATM_LANAI=m +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_TCP=m +CONFIG_ATM_ZATM=m +# CONFIG_ATM_ZATM_DEBUG is not set +CONFIG_ATP=m +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y +CONFIG_AUDIT_ARCH=y +CONFIG_AUDIT_TREE=y +CONFIG_AUFS=m +# CONFIG_AUFS_BRANCH_MAX_1023 is not set +CONFIG_AUFS_BRANCH_MAX_127=y +# CONFIG_AUFS_BRANCH_MAX_32767 is not set +# CONFIG_AUFS_BRANCH_MAX_511 is not set +CONFIG_AUFS_BR_NFS=y +CONFIG_AUFS_BR_XFS=y +# CONFIG_AUFS_COMPAT is not set +# CONFIG_AUFS_DEBUG is not set +CONFIG_AUFS_DENY_WRITE_ACCESS_PATCH=y +# CONFIG_AUFS_DLGT is not set +CONFIG_AUFS_EXPORT=y +# CONFIG_AUFS_FSYNC_SUPER_PATCH is not set +CONFIG_AUFS_HINOTIFY=y +CONFIG_AUFS_HIN_OR_DLGT=y +CONFIG_AUFS_HIN_OR_FUSE=y +CONFIG_AUFS_INO_T_64=y +CONFIG_AUFS_LHASH_PATCH=y +CONFIG_AUFS_PUT_FILP_PATCH=y +# CONFIG_AUFS_ROBR is not set +CONFIG_AUFS_RR_SQUASHFS=y +CONFIG_AUFS_SEC_PERM_PATCH=y +CONFIG_AUFS_SHWH=y +CONFIG_AUFS_SPLICE_PATCH=y +CONFIG_AUFS_STAT=y +# CONFIG_AUFS_UNIONFS22_PATCH is not set +# CONFIG_AUFS_UNIONFS23_PATCH is not set +# CONFIG_AUFS_WORKAROUND_FUSE is not set +CONFIG_AUTOFS4_FS=m +CONFIG_AUTOFS_FS=m +CONFIG_AUXDISPLAY=y +CONFIG_AVERATEC_5100P=m +CONFIG_AX25=m +CONFIG_AX25_DAMA_SLAVE=y +CONFIG_B43=m +CONFIG_B43LEGACY=m +CONFIG_B43LEGACY_DEBUG=y +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +CONFIG_B43LEGACY_LEDS=y +CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y +CONFIG_B43LEGACY_PCI_AUTOSELECT=y +CONFIG_B43LEGACY_PIO=y +# CONFIG_B43LEGACY_PIO_MODE is not set +CONFIG_B43LEGACY_RFKILL=y +# CONFIG_B43_DEBUG is not set +CONFIG_B43_LEDS=y +CONFIG_B43_PCICORE_AUTOSELECT=y +CONFIG_B43_PCI_AUTOSELECT=y +# CONFIG_B43_PCMCIA is not set +CONFIG_B43_RFKILL=y +CONFIG_B44=m +CONFIG_B44_PCI=y +CONFIG_B44_PCICORE_AUTOSELECT=y +CONFIG_B44_PCI_AUTOSELECT=y +CONFIG_BACKLIGHT_CARILLO_RANCH=m +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_CORGI=m +CONFIG_BACKLIGHT_DA903X=m +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_MBP_NVIDIA=m +CONFIG_BACKLIGHT_PROGEAR=m +CONFIG_BACKLIGHT_SAHARA=m +# CONFIG_BACKTRACE_SELF_TEST is not set +CONFIG_BASE_FULL=y +CONFIG_BASE_SMALL=0 +CONFIG_BATTERY_BQ27x00=m +CONFIG_BATTERY_DS2760=m +CONFIG_BAYCOM_PAR=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +# CONFIG_BEFS_DEBUG is not set +CONFIG_BEFS_FS=m +CONFIG_BFS_FS=m +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=m +CONFIG_BITREVERSE=y +CONFIG_BLK_CPQ_CISS_DA=m +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_DEV=y +CONFIG_BLK_DEV_3W_XXXX_RAID=m +# CONFIG_BLK_DEV_BSG is not set +CONFIG_BLK_DEV_COMPCACHE=m +# CONFIG_BLK_DEV_COMPCACHE_DEBUG is not set +# CONFIG_BLK_DEV_COMPCACHE_STATS is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_DM=y +CONFIG_BLK_DEV_DM_BBR=m +CONFIG_BLK_DEV_DRBD=m +CONFIG_BLK_DEV_FD=m +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_INTEGRITY=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_MD=y +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_BLK_DEV_SX8=m +CONFIG_BLK_DEV_UB=m +CONFIG_BLK_DEV_UMEM=m +# CONFIG_BLK_DEV_XIP is not set +CONFIG_BLOCK=y +CONFIG_BLOCK_COMPAT=y +CONFIG_BNX2=m +CONFIG_BNX2X=m +CONFIG_BONDING=m +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BOUNCE=y +CONFIG_BPQETHER=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_IP6=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_NFLOG=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_ULOG=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_NETFILTER=y +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BROADCOM_PHY=m +CONFIG_BSD_DISKLABEL=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_BT=y +CONFIG_BT_BNEP=m +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_CMTP=m +CONFIG_BT_HCIBCM203X=m +CONFIG_BT_HCIBFUSB=m +CONFIG_BT_HCIBLUECARD=m +CONFIG_BT_HCIBPA10X=m +CONFIG_BT_HCIBT3C=m +CONFIG_BT_HCIBTSDIO=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HIDP=m +CONFIG_BT_L2CAP=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_SCO=y +CONFIG_BUG=y +CONFIG_C2PORT=m +CONFIG_C2PORT_DURAMAR_2150=m +CONFIG_CALGARY_IOMMU=y +CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT=y +# CONFIG_CAN is not set +CONFIG_CAN_PM_TRACE=y +CONFIG_CAPI_AVM=y +CONFIG_CAPI_EICON=y +CONFIG_CAPI_TRACE=y +CONFIG_CARDBUS=y +CONFIG_CARDMAN_4000=m +CONFIG_CARDMAN_4040=m +# CONFIG_CARMINE_DRAM_CUSTOM is not set +CONFIG_CASSINI=m +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_CDROM_PKTCDVD=y +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_CFAG12864B=m +CONFIG_CFAG12864B_RATE=20 +CONFIG_CFG80211=m +CONFIG_CGROUPS=y +CONFIG_CGROUP_CPUACCT=y +# CONFIG_CGROUP_DEBUG is not set +# CONFIG_CGROUP_DEVICE is not set +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_MEM_RES_CTLR=y +CONFIG_CGROUP_NS=y +CONFIG_CGROUP_SCHED=y +CONFIG_CHECK_SIGNATURE=y +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T3=m +CONFIG_CHR_DEV_OSST=m +CONFIG_CHR_DEV_SCH=m +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_ST=m +CONFIG_CICADA_PHY=m +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG2 is not set +CONFIG_CIFS_DFS_UPCALL=y +CONFIG_CIFS_EXPERIMENTAL=y +CONFIG_CIFS_POSIX=y +# CONFIG_CIFS_STATS is not set +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_WEAK_PW_HASH=y +CONFIG_CIFS_XATTR=y +CONFIG_CISS_SCSI_TAPE=y +CONFIG_CLASSIC_RCU=y +CONFIG_CLOCKSOURCE_WATCHDOG=y +CONFIG_CLS_U32_MARK=y +# CONFIG_CLS_U32_PERF is not set +# CONFIG_CMDLINE_BOOL is not set +CONFIG_CODA_FS=m +CONFIG_COMPAL_LAPTOP=m +CONFIG_COMPAT=y +CONFIG_COMPAT_BINFMT_ELF=y +# CONFIG_COMPAT_BRK is not set +CONFIG_COMPAT_FOR_U64_ALIGNMENT=y +# CONFIG_COMPAT_VDSO is not set +CONFIG_COMPUTONE=m +CONFIG_CONFIGFS_FS=m +CONFIG_CONNECTOR=y +CONFIG_CONSOLE_POLL=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_CONTEXT_SWITCH_TRACER=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_CPA_DEBUG is not set +CONFIG_CPU5_WDT=m +CONFIG_CPUSETS=y +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_DEBUG is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y +CONFIG_CPU_SUP_AMD=y +CONFIG_CPU_SUP_CENTAUR_64=y +CONFIG_CPU_SUP_INTEL=y +CONFIG_CRAMFS=y +CONFIG_CRASH_DUMP=y +CONFIG_CRC16=y +CONFIG_CRC32=y +CONFIG_CRC7=m +CONFIG_CRC_CCITT=m +CONFIG_CRC_ITU_T=m +CONFIG_CRC_T10DIF=y +CONFIG_CRYPTO=y +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_AES_X86_64=m +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_CRC32C_INTEL=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_DEV_HIFN_795X=m +CONFIG_CRYPTO_DEV_HIFN_795X_RNG=y +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_FIPS=y +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_LZO=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SALSA20_X86_64=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SEQIV=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_TWOFISH_X86_64=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_XCBC=m +CONFIG_CRYPTO_XTS=m +CONFIG_CYCLADES=m +CONFIG_CYCLADES_SYNC=m +CONFIG_CYCLOMX_X25=y +# CONFIG_CYZ_INTR is not set +# CONFIG_DAB is not set +CONFIG_DAVICOM_PHY=m +CONFIG_DCA=m +CONFIG_DCDBAS=m +CONFIG_DE2104X=m +CONFIG_DE4X5=m +CONFIG_DE600=m +CONFIG_DE620=m +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_BOOT_PARAMS is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_DRIVER is not set +CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_NX_TEST is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +CONFIG_DEBUG_RODATA=y +# CONFIG_DEBUG_RODATA_TEST is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_VIRTUAL is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +CONFIG_DECNET=m +CONFIG_DECNET_NF_GRABULATOR=m +# CONFIG_DECNET_ROUTER is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_BIC is not set +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_HTCP is not set +CONFIG_DEFAULT_IO_DELAY_TYPE=1 +# CONFIG_DEFAULT_NOOP is not set +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_WESTWOOD is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_DEFXX=m +# CONFIG_DEFXX_MMIO is not set +CONFIG_DELL_RBU=m +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_DEVKMEM is not set +CONFIG_DEVPORT=y +CONFIG_DEV_APPLETALK=m +CONFIG_DE_AOC=y +CONFIG_DIGIEPCA=m +# CONFIG_DIRECT_GBPAGES is not set +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_DISPLAY_SUPPORT=m +# CONFIG_DL2K is not set +CONFIG_DLCI=m +CONFIG_DLCI_MAX=8 +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +CONFIG_DM9102=m +CONFIG_DMADEVICES=y +# CONFIG_DMAR is not set +# CONFIG_DMATEST is not set +CONFIG_DMA_ENGINE=y +CONFIG_DMI=y +CONFIG_DMIID=y +CONFIG_DM_CRYPT=m +# CONFIG_DM_DEBUG is not set +# CONFIG_DM_DELAY is not set +CONFIG_DM_LOOP=m +CONFIG_DM_MIRROR=y +CONFIG_DM_MULTIPATH=y +CONFIG_DM_RAID45=m +CONFIG_DM_SNAPSHOT=y +CONFIG_DM_UEVENT=y +CONFIG_DM_ZERO=m +CONFIG_DNOTIFY=y +CONFIG_DONGLE=y +CONFIG_DRM=m +CONFIG_DRM_I810=m +CONFIG_DRM_I830=m +CONFIG_DRM_I915=m +CONFIG_DRM_MGA=m +CONFIG_DRM_R128=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_SAVAGE=m +CONFIG_DRM_SIS=m +CONFIG_DRM_TDFX=m +CONFIG_DRM_VIA=m +CONFIG_DS1682=m +CONFIG_DSCC4=m +CONFIG_DSCC4_PCISYNC=y +CONFIG_DSCC4_PCI_RST=y +CONFIG_DUMMY=m +CONFIG_DUMMY_CONSOLE=y +CONFIG_DVB_AF9013=m +CONFIG_DVB_AU8522=m +CONFIG_DVB_AV7110=m +# CONFIG_DVB_AV7110_FIRMWARE is not set +CONFIG_DVB_AV7110_OSD=y +CONFIG_DVB_B2C2_FLEXCOP=m +# CONFIG_DVB_B2C2_FLEXCOP_DEBUG is not set +CONFIG_DVB_B2C2_FLEXCOP_PCI=m +CONFIG_DVB_B2C2_FLEXCOP_USB=m +CONFIG_DVB_BCM3510=m +CONFIG_DVB_BT8XX=m +CONFIG_DVB_BUDGET=m +CONFIG_DVB_BUDGET_AV=m +CONFIG_DVB_BUDGET_CI=m +CONFIG_DVB_BUDGET_CORE=m +CONFIG_DVB_BUDGET_PATCH=m +CONFIG_DVB_CAPTURE_DRIVERS=y +CONFIG_DVB_CORE=m +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +CONFIG_DVB_DM1105=m +CONFIG_DVB_DRX397XD=m +# CONFIG_DVB_DUMMY_FE is not set +# CONFIG_DVB_FE_CUSTOMISE is not set +CONFIG_DVB_ISL6405=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_L64781=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LGS8GL5=m +CONFIG_DVB_LNBP21=m +CONFIG_DVB_MT312=m +CONFIG_DVB_MT352=m +CONFIG_DVB_NXT200X=m +CONFIG_DVB_NXT6000=m +CONFIG_DVB_OR51132=m +CONFIG_DVB_OR51211=m +CONFIG_DVB_PLL=m +CONFIG_DVB_PLUTO2=m +CONFIG_DVB_S5H1409=m +CONFIG_DVB_S5H1411=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_SI21XX=m +CONFIG_DVB_SIANO_SMS1XXX=m +CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS=y +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_STB6000=m +CONFIG_DVB_STV0288=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_TDA10048=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_USB=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_CINERGY_T2=m +CONFIG_DVB_USB_CXUSB=m +# CONFIG_DVB_USB_DEBUG is not set +CONFIG_DVB_USB_DIB0700=m +CONFIG_DVB_USB_DIBUSB_MB=m +# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_DW2102=m +CONFIG_DVB_USB_GL861=m +CONFIG_DVB_USB_GP8PSK=m +CONFIG_DVB_USB_M920X=m +CONFIG_DVB_USB_NOVA_T_USB2=m +CONFIG_DVB_USB_OPERA1=m +CONFIG_DVB_USB_TTUSB2=m +CONFIG_DVB_USB_UMT_010=m +CONFIG_DVB_USB_VP702X=m +CONFIG_DVB_USB_VP7045=m +CONFIG_DVB_VES1820=m +CONFIG_DVB_VES1X93=m +CONFIG_DVB_ZL10353=m +# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +CONFIG_E100=m +CONFIG_E1000=m +CONFIG_E1000E=m +CONFIG_EARLY_PRINTK=y +# CONFIG_EARLY_PRINTK_DBGP is not set +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +CONFIG_ECRYPT_FS=y +CONFIG_EDAC=y +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_E752X=m +CONFIG_EDAC_I3000=m +CONFIG_EDAC_I5000=m +CONFIG_EDAC_I5100=m +CONFIG_EDAC_I82975X=m +CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC_X38=m +CONFIG_EDD=y +CONFIG_EDD_OFF=y +CONFIG_EEEPC_LAPTOP=m +CONFIG_EEPRO100=m +CONFIG_EEPROM_93CX6=m +CONFIG_EFI=y +CONFIG_EFI_PARTITION=y +CONFIG_EFI_VARS=y +CONFIG_EFS_FS=m +CONFIG_ELF_CORE=y +# CONFIG_EMBEDDED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENC28J60 is not set +CONFIG_ENCLOSURE_SERVICES=m +CONFIG_ENIC=m +CONFIG_EPIC100=m +CONFIG_EPOLL=y +CONFIG_EQUALIZER=m +CONFIG_ESI_DONGLE=m +CONFIG_EUROTECH_WDT=m +CONFIG_EVENTFD=y +CONFIG_EXPERIMENTAL=y +CONFIG_EXPORTFS=m +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT4DEV_COMPAT is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_EXT4_FS_XATTR=y +CONFIG_EXTRA_FIRMWARE="" +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FARSYNC=m +CONFIG_FAST_CMPXCHG_LOCAL=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_FAT_FS=m +# CONFIG_FAULT_INJECTION is not set +CONFIG_FB=y +CONFIG_FB_3DFX=m +# CONFIG_FB_3DFX_ACCEL is not set +CONFIG_FB_ARC=m +CONFIG_FB_ARK=m +CONFIG_FB_ASILIANT=y +CONFIG_FB_ATY=m +CONFIG_FB_ATY128=m +CONFIG_FB_ATY128_BACKLIGHT=y +CONFIG_FB_ATY_BACKLIGHT=y +CONFIG_FB_ATY_CT=y +CONFIG_FB_ATY_GENERIC_LCD=y +CONFIG_FB_ATY_GX=y +CONFIG_FB_BACKLIGHT=y +CONFIG_FB_BOOT_VESA_SUPPORT=y +CONFIG_FB_CARILLO_RANCH=m +CONFIG_FB_CARMINE=m +CONFIG_FB_CARMINE_DRAM_EVAL=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +CONFIG_FB_CIRRUS=m +CONFIG_FB_CYBER2000=m +CONFIG_FB_DDC=m +CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_EFI=y +# CONFIG_FB_FOREIGN_ENDIAN is not set +CONFIG_FB_GEODE=y +CONFIG_FB_GEODE_GX=m +CONFIG_FB_GEODE_GX1=m +CONFIG_FB_GEODE_LX=m +CONFIG_FB_HECUBA=m +CONFIG_FB_HGA=m +# CONFIG_FB_HGA_ACCEL is not set +CONFIG_FB_IMSTT=y +CONFIG_FB_INTEL=m +# CONFIG_FB_INTEL_DEBUG is not set +CONFIG_FB_INTEL_I2C=y +CONFIG_FB_KYRO=m +CONFIG_FB_LE80578=m +# CONFIG_FB_MACMODES is not set +CONFIG_FB_MATROX=m +CONFIG_FB_MATROX_G=y +CONFIG_FB_MATROX_I2C=m +CONFIG_FB_MATROX_MAVEN=m +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MULTIHEAD=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MB862XX=m +CONFIG_FB_MB862XX_PCI_GDC=y +CONFIG_FB_METRONOME=m +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_N411=m +CONFIG_FB_NEOMAGIC=m +CONFIG_FB_NVIDIA=m +CONFIG_FB_NVIDIA_BACKLIGHT=y +# CONFIG_FB_NVIDIA_DEBUG is not set +CONFIG_FB_NVIDIA_I2C=y +CONFIG_FB_PM2=m +CONFIG_FB_PM2_FIFO_DISCONNECT=y +CONFIG_FB_PM3=m +CONFIG_FB_RADEON=m +CONFIG_FB_RADEON_BACKLIGHT=y +# CONFIG_FB_RADEON_DEBUG is not set +CONFIG_FB_RADEON_I2C=y +CONFIG_FB_RIVA=m +CONFIG_FB_RIVA_BACKLIGHT=y +# CONFIG_FB_RIVA_DEBUG is not set +CONFIG_FB_RIVA_I2C=y +CONFIG_FB_S1D13XXX=m +CONFIG_FB_S3=m +CONFIG_FB_SAVAGE=m +CONFIG_FB_SAVAGE_ACCEL=y +CONFIG_FB_SAVAGE_I2C=y +CONFIG_FB_SIS=m +CONFIG_FB_SIS_300=y +CONFIG_FB_SIS_315=y +CONFIG_FB_SM501=m +CONFIG_FB_SVGALIB=m +CONFIG_FB_SYS_COPYAREA=m +CONFIG_FB_SYS_FILLRECT=m +CONFIG_FB_SYS_FOPS=m +CONFIG_FB_SYS_IMAGEBLIT=m +CONFIG_FB_TILEBLITTING=y +CONFIG_FB_TRIDENT=m +# CONFIG_FB_TRIDENT_ACCEL is not set +CONFIG_FB_UVESA=m +CONFIG_FB_VESA=m +CONFIG_FB_VGA16=m +CONFIG_FB_VIA=m +# CONFIG_FB_VIRTUAL is not set +CONFIG_FB_VOODOO1=m +CONFIG_FB_VT8623=m +CONFIG_FDDI=y +CONFIG_FEALNX=m +CONFIG_FIB_RULES=y +CONFIG_FILE_LOCKING=y +CONFIG_FIREWIRE=m +CONFIG_FIREWIRE_OHCI=m +CONFIG_FIREWIRE_OHCI_DEBUG=y +# CONFIG_FIREWIRE_OHCI_REMOTE_DMA is not set +CONFIG_FIREWIRE_SBP2=m +CONFIG_FIRMWARE_EDID=y +# CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_FIRMWARE_MEMMAP=y +CONFIG_FIXED_PHY=y +CONFIG_FIX_EARLYCON_MEM=y +# CONFIG_FLATMEM_MANUAL is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x16=y +CONFIG_FONT_8x8=y +CONFIG_FORCEDETH=m +# CONFIG_FORCEDETH_NAPI is not set +CONFIG_FRAMEBUFFER_CONSOLE=m +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FRAME_POINTER=y +CONFIG_FRAME_WARN=1024 +CONFIG_FREEZER=y +CONFIG_FSAM7400=m +CONFIG_FS_MBCACHE=y +CONFIG_FS_POSIX_ACL=y +CONFIG_FS_UNIONFS=m +CONFIG_FTL=m +# CONFIG_FTRACE_STARTUP_TEST is not set +CONFIG_FUJITSU_LAPTOP=m +# CONFIG_FUJITSU_LAPTOP_DEBUG is not set +# CONFIG_FUNCTION_TRACER is not set +CONFIG_FUSE_FS=y +CONFIG_FUSION=y +CONFIG_FUSION_CTL=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_LAN=m +CONFIG_FUSION_LOGGING=y +CONFIG_FUSION_MAX_SGE=128 +CONFIG_FUSION_SAS=m +CONFIG_FUSION_SPI=m +CONFIG_FUTEX=y +CONFIG_FW_LOADER=y +CONFIG_GACT_PROB=y +CONFIG_GAMEPORT=m +CONFIG_GAMEPORT_EMU10K1=m +CONFIG_GAMEPORT_FM801=m +CONFIG_GAMEPORT_L4=m +CONFIG_GAMEPORT_NS558=m +CONFIG_GARP=m +CONFIG_GART_IOMMU=y +CONFIG_GENERIC_ACL=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_CPU=y +CONFIG_GENERIC_FIND_FIRST_BIT=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_ISA_DMA=y +CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=m +CONFIG_GFS_FS=m +CONFIG_GIGASET_BASE=m +# CONFIG_GIGASET_DEBUG is not set +CONFIG_GIGASET_M101=m +CONFIG_GIGASET_M105=m +# CONFIG_GIGASET_UNDOCREQ is not set +CONFIG_GIRBIL_DONGLE=m +CONFIG_GPIOLIB=y +CONFIG_GPIO_MAX7301=m +CONFIG_GPIO_MAX732X=m +CONFIG_GPIO_MCP23S08=m +CONFIG_GPIO_PCA953X=m +CONFIG_GPIO_PCF857X=m +CONFIG_GPIO_SYSFS=y +CONFIG_GROUP_SCHED=y +CONFIG_HAMACHI=m +CONFIG_HAMRADIO=y +CONFIG_HANGCHECK_TIMER=m +CONFIG_HAPPYMEAL=m +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +# CONFIG_HAVE_AOUT is not set +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_CPUMASK_OF_CPU_MAP=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FUNCTION_TRACER=y +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_HAVE_IDE=y +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_KVM=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_HAVE_MEMORY_PRESENT=y +CONFIG_HAVE_MTD_OTP=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_SETUP_PER_CPU_AREA=y +CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y +CONFIG_HDLC=m +CONFIG_HDLC_CISCO=m +CONFIG_HDLC_FR=m +CONFIG_HDLC_PPP=m +CONFIG_HDLC_RAW=m +CONFIG_HDLC_RAW_ETH=m +CONFIG_HDLC_X25=m +# CONFIG_HEADERS_CHECK is not set +CONFIG_HECI=m +CONFIG_HERMES=m +CONFIG_HFSPLUS_FS=m +CONFIG_HFS_FS=m +CONFIG_HIBERNATION=y +CONFIG_HID=y +CONFIG_HIDRAW=y +CONFIG_HID_A4TECH=m +CONFIG_HID_APPLE=m +CONFIG_HID_BELKIN=m +CONFIG_HID_BRIGHT=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +# CONFIG_HID_COMPAT is not set +CONFIG_HID_CYPRESS=m +# CONFIG_HID_DEBUG is not set +CONFIG_HID_DELL=m +CONFIG_HID_EZKEY=m +CONFIG_HID_GYRATION=m +CONFIG_HID_LOGITECH=m +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_PANTHERLORD=m +CONFIG_HID_PETALYNX=m +CONFIG_HID_PID=y +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_HID_SUNPLUS=m +CONFIG_HID_SUPPORT=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_HIPPI=y +CONFIG_HISAX_16_3=y +CONFIG_HISAX_1TR6=y +CONFIG_HISAX_AVM_A1_CS=m +CONFIG_HISAX_AVM_A1_PCMCIA=y +CONFIG_HISAX_BKM_A4T=y +# CONFIG_HISAX_DEBUG is not set +CONFIG_HISAX_DIEHLDIVA=y +CONFIG_HISAX_ELSA=y +CONFIG_HISAX_ELSA_CS=m +CONFIG_HISAX_ENTERNOW_PCI=y +CONFIG_HISAX_EURO=y +CONFIG_HISAX_FRITZPCI=y +CONFIG_HISAX_FRITZ_PCIPNP=m +CONFIG_HISAX_GAZEL=y +CONFIG_HISAX_HDLC=y +CONFIG_HISAX_HFC4S8S=m +CONFIG_HISAX_HFCUSB=m +CONFIG_HISAX_HFC_PCI=y +CONFIG_HISAX_HFC_SX=y +CONFIG_HISAX_MAX_CARDS=8 +CONFIG_HISAX_NETJET=y +CONFIG_HISAX_NETJET_U=y +CONFIG_HISAX_NI1=y +CONFIG_HISAX_NICCY=y +# CONFIG_HISAX_NO_KEYPAD is not set +# CONFIG_HISAX_NO_LLC is not set +# CONFIG_HISAX_NO_SENDCOMPLETE is not set +CONFIG_HISAX_S0BOX=y +CONFIG_HISAX_SCT_QUADRO=y +CONFIG_HISAX_SEDLBAUER=y +CONFIG_HISAX_SEDLBAUER_CS=m +CONFIG_HISAX_ST5481=m +CONFIG_HISAX_TELESPCI=y +CONFIG_HISAX_TELES_CS=m +CONFIG_HISAX_W6692=y +CONFIG_HOSTAP=m +CONFIG_HOSTAP_CS=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +CONFIG_HOSTAP_PCI=m +CONFIG_HOSTAP_PLX=m +CONFIG_HOTPLUG=y +CONFIG_HOTPLUG_CPU=y +CONFIG_HOTPLUG_PCI=y +CONFIG_HOTPLUG_PCI_ACPI=m +CONFIG_HOTPLUG_PCI_ACPI_IBM=m +CONFIG_HOTPLUG_PCI_CPCI=y +CONFIG_HOTPLUG_PCI_CPCI_GENERIC=m +CONFIG_HOTPLUG_PCI_CPCI_ZT5550=m +CONFIG_HOTPLUG_PCI_FAKE=m +CONFIG_HOTPLUG_PCI_PCIE=y +CONFIG_HOTPLUG_PCI_SHPC=m +CONFIG_HP100=m +CONFIG_HPET=y +CONFIG_HPET_EMULATE_RTC=y +CONFIG_HPET_MMAP=y +CONFIG_HPET_TIMER=y +CONFIG_HPFS_FS=m +CONFIG_HP_ILO=m +# CONFIG_HP_WATCHDOG is not set +CONFIG_HP_WMI=m +CONFIG_HTC_PASIC3=m +CONFIG_HT_IRQ=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_HVC_DRIVER=y +CONFIG_HVC_IRQ=y +CONFIG_HVC_XEN=y +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_HWMON_VID=m +CONFIG_HW_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_AMD=m +CONFIG_HW_RANDOM_INTEL=m +CONFIG_HW_RANDOM_VIRTIO=m +CONFIG_HYSDN=m +CONFIG_HYSDN_CAPI=y +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_300 is not set +CONFIG_I2C=y +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCA=m +CONFIG_I2C_ALGOPCF=m +CONFIG_I2C_ALI1535=m +CONFIG_I2C_ALI1563=m +CONFIG_I2C_ALI15X3=m +CONFIG_I2C_AMD756=m +CONFIG_I2C_AMD756_S4882=m +CONFIG_I2C_AMD8111=m +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=m +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set +# CONFIG_I2C_DEBUG_CORE is not set +CONFIG_I2C_GPIO=m +# CONFIG_I2C_HELPER_AUTO is not set +CONFIG_I2C_I801=m +CONFIG_I2C_ISCH=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_NFORCE2_S4985=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_PCA_PLATFORM=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_STUB=m +CONFIG_I2C_TAOS_EVM=m +CONFIG_I2C_TINY_USB=m +CONFIG_I2C_VIA=m +CONFIG_I2C_VIAPRO=m +CONFIG_I2C_VOODOO3=m +CONFIG_I2O=m +CONFIG_I2O_BLOCK=m +CONFIG_I2O_BUS=m +CONFIG_I2O_CONFIG=m +CONFIG_I2O_CONFIG_OLD_IOCTL=y +CONFIG_I2O_EXT_ADAPTEC=y +CONFIG_I2O_EXT_ADAPTEC_DMA64=y +CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y +CONFIG_I2O_PROC=m +CONFIG_I2O_SCSI=m +CONFIG_I6300ESB_WDT=m +CONFIG_I7300_IDLE=m +CONFIG_I7300_IDLE_IOAT_CHANNEL=y +CONFIG_I82092=m +CONFIG_I8K=m +# CONFIG_IA32_AOUT is not set +CONFIG_IA32_EMULATION=y +CONFIG_IB700_WDT=m +CONFIG_IBMASR=m +CONFIG_IBMOL=m +CONFIG_IBM_ASM=m +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +CONFIG_ICPLUS_PHY=m +CONFIG_ICS932S401=m +# CONFIG_IDE is not set +CONFIG_IEEE1394=m +CONFIG_IEEE1394_DV1394=m +CONFIG_IEEE1394_ETH1394=m +CONFIG_IEEE1394_ETH1394_ROM_ENTRY=y +CONFIG_IEEE1394_OHCI1394=m +CONFIG_IEEE1394_PCILYNX=m +CONFIG_IEEE1394_RAWIO=m +CONFIG_IEEE1394_SBP2=m +# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set +# CONFIG_IEEE1394_VERBOSEDEBUG is not set +CONFIG_IEEE1394_VIDEO1394=m +CONFIG_IEEE80211=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_CRYPT_WEP=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IFB=m +CONFIG_IGB=m +CONFIG_IGB_DCA=y +# CONFIG_IGB_LRO is not set +# CONFIG_IKCONFIG is not set +CONFIG_INET=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_TUNNEL=m +CONFIG_INET_AH=m +CONFIG_INET_DCCP_DIAG=m +CONFIG_INET_DIAG=y +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m +CONFIG_INET_LRO=m +CONFIG_INET_TCP_DIAG=y +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_TUNNEL=m +CONFIG_INFINIBAND=m +CONFIG_INFINIBAND_ADDR_TRANS=y +CONFIG_INFINIBAND_AMSO1100=m +CONFIG_INFINIBAND_AMSO1100_DEBUG=y +CONFIG_INFINIBAND_CXGB3=m +# CONFIG_INFINIBAND_CXGB3_DEBUG is not set +CONFIG_INFINIBAND_IPATH=m +CONFIG_INFINIBAND_IPOIB=m +CONFIG_INFINIBAND_IPOIB_CM=y +CONFIG_INFINIBAND_IPOIB_DEBUG=y +# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set +CONFIG_INFINIBAND_ISER=m +CONFIG_INFINIBAND_MTHCA=m +CONFIG_INFINIBAND_MTHCA_DEBUG=y +# CONFIG_INFINIBAND_NES is not set +CONFIG_INFINIBAND_SRP=m +CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_USER_MAD=m +CONFIG_INFINIBAND_USER_MEM=y +CONFIG_INFTL=m +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_INPUT=y +# CONFIG_INPUT_APANEL is not set +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_ATLAS_BTNS=m +CONFIG_INPUT_CM109=m +CONFIG_INPUT_EVBUG=m +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_FF_MEMLESS=m +CONFIG_INPUT_JOYDEV=m +CONFIG_INPUT_JOYSTICK=y +CONFIG_INPUT_KEYBOARD=y +CONFIG_INPUT_KEYSPAN_REMOTE=m +CONFIG_INPUT_MISC=y +CONFIG_INPUT_MOUSE=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_PCSPKR=m +CONFIG_INPUT_POLLDEV=m +CONFIG_INPUT_POWERMATE=m +CONFIG_INPUT_TABLET=y +CONFIG_INPUT_TOUCHSCREEN=y +CONFIG_INPUT_UINPUT=m +CONFIG_INPUT_YEALINK=m +CONFIG_INTEL_IOATDMA=m +CONFIG_INTEL_MENLOW=m +# CONFIG_INTR_REMAP is not set +# CONFIG_IOMMU_DEBUG is not set +CONFIG_IOMMU_HELPER=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_CFQ=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_NOOP=y +# CONFIG_IO_DELAY_0X80 is not set +CONFIG_IO_DELAY_0XED=y +# CONFIG_IO_DELAY_NONE is not set +CONFIG_IO_DELAY_TYPE_0X80=0 +CONFIG_IO_DELAY_TYPE_0XED=1 +CONFIG_IO_DELAY_TYPE_NONE=3 +CONFIG_IO_DELAY_TYPE_UDELAY=2 +# CONFIG_IO_DELAY_UDELAY is not set +CONFIG_IP1000=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_MATCH_AH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_MH=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_SECURITY=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IPC_NS=y +CONFIG_IPDDP=m +CONFIG_IPDDP_DECAP=y +CONFIG_IPDDP_ENCAP=y +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_POWEROFF=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPPP_FILTER=y +CONFIG_IPV6=y +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_MROUTE is not set +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_IPV6_SIT=m +# CONFIG_IPV6_SUBTREES is not set +CONFIG_IPV6_TUNNEL=m +CONFIG_IPW2100=m +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2100_MONITOR=y +CONFIG_IPW2200=m +# CONFIG_IPW2200_DEBUG is not set +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW2200_PROMISCUOUS=y +CONFIG_IPW2200_QOS=y +CONFIG_IPW2200_RADIOTAP=y +CONFIG_IPWIRELESS=m +CONFIG_IPX=m +# CONFIG_IPX_INTERN is not set +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_DCCP=m +CONFIG_IP_DCCP_ACKVEC=y +CONFIG_IP_DCCP_CCID2=m +# CONFIG_IP_DCCP_CCID2_DEBUG is not set +CONFIG_IP_DCCP_CCID3=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 +# CONFIG_IP_DCCP_DEBUG is not set +CONFIG_IP_DCCP_TFRC_LIB=m +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_MROUTE=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_AH=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_SECURITY=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_IP_PNP is not set +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_SCTP=m +CONFIG_IP_VS=m +# CONFIG_IP_VS_DEBUG is not set +CONFIG_IP_VS_DH=m +CONFIG_IP_VS_FTP=m +CONFIG_IP_VS_IPV6=y +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_LC=m +CONFIG_IP_VS_NQ=m +CONFIG_IP_VS_PROTO_AH=y +CONFIG_IP_VS_PROTO_AH_ESP=y +CONFIG_IP_VS_PROTO_ESP=y +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_SED=m +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_TAB_BITS=12 +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_WRR=m +CONFIG_IRCOMM=m +CONFIG_IRDA=m +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_DEBUG=y +CONFIG_IRDA_FAST_RR=y +CONFIG_IRDA_ULTRA=y +CONFIG_IRLAN=m +CONFIG_IRNET=m +# CONFIG_IRQSOFF_TRACER is not set +CONFIG_IRTTY_SIR=m +CONFIG_ISA_DMA_API=y +CONFIG_ISCSI_IBFT=m +CONFIG_ISCSI_IBFT_FIND=y +CONFIG_ISCSI_TCP=m +CONFIG_ISDN=y +CONFIG_ISDN_AUDIO=y +CONFIG_ISDN_CAPI=m +CONFIG_ISDN_CAPI_CAPI20=m +CONFIG_ISDN_CAPI_CAPIDRV=m +CONFIG_ISDN_CAPI_CAPIFS=m +CONFIG_ISDN_CAPI_CAPIFS_BOOL=y +CONFIG_ISDN_CAPI_MIDDLEWARE=y +CONFIG_ISDN_DIVAS=m +CONFIG_ISDN_DIVAS_BRIPCI=y +CONFIG_ISDN_DIVAS_DIVACAPI=m +CONFIG_ISDN_DIVAS_MAINT=m +CONFIG_ISDN_DIVAS_PRIPCI=y +CONFIG_ISDN_DIVAS_USERIDI=m +CONFIG_ISDN_DIVERSION=m +CONFIG_ISDN_DRV_AVMB1_AVM_CS=m +CONFIG_ISDN_DRV_AVMB1_B1PCI=m +CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y +CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m +CONFIG_ISDN_DRV_AVMB1_C4=m +CONFIG_ISDN_DRV_AVMB1_T1PCI=m +CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y +CONFIG_ISDN_DRV_GIGASET=m +CONFIG_ISDN_DRV_HISAX=m +CONFIG_ISDN_I4L=m +CONFIG_ISDN_MPP=y +CONFIG_ISDN_PPP=y +CONFIG_ISDN_PPP_BSDCOMP=m +CONFIG_ISDN_PPP_VJ=y +CONFIG_ISDN_TTY_FAX=y +CONFIG_ISDN_X25=y +# CONFIG_ISI is not set +CONFIG_ISO9660_FS=m +CONFIG_ISTALLION=m +CONFIG_IT8712F_WDT=m +CONFIG_IT87_WDT=m +CONFIG_ITCO_VENDOR_SUPPORT=y +CONFIG_ITCO_WDT=m +CONFIG_IWL3945=m +# CONFIG_IWL3945_DEBUG is not set +CONFIG_IWL3945_LEDS=y +CONFIG_IWL3945_RFKILL=y +CONFIG_IWL3945_SPECTRUM_MEASUREMENT=y +CONFIG_IWL4965=y +CONFIG_IWL5000=y +CONFIG_IWLAGN=m +CONFIG_IWLAGN_LEDS=y +CONFIG_IWLAGN_SPECTRUM_MEASUREMENT=y +CONFIG_IWLCORE=m +CONFIG_IWLWIFI=m +# CONFIG_IWLWIFI_DEBUG is not set +CONFIG_IWLWIFI_LEDS=y +CONFIG_IWLWIFI_RFKILL=y +CONFIG_IXGB=m +CONFIG_IXGBE=m +CONFIG_IXGBE_DCA=y +CONFIG_JBD=y +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +# CONFIG_JBD_DEBUG is not set +CONFIG_JFFS2_CMODE_FAVOURLZO=y +# CONFIG_JFFS2_CMODE_NONE is not set +# CONFIG_JFFS2_CMODE_PRIORITY is not set +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_LZO=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_SUMMARY is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFS_DEBUG is not set +CONFIG_JFS_FS=m +CONFIG_JFS_POSIX_ACL=y +CONFIG_JFS_SECURITY=y +CONFIG_JFS_STATISTICS=y +CONFIG_JME=m +CONFIG_JOLIET=y +CONFIG_JOYSTICK_A3D=m +CONFIG_JOYSTICK_ADI=m +CONFIG_JOYSTICK_ANALOG=m +CONFIG_JOYSTICK_COBRA=m +CONFIG_JOYSTICK_DB9=m +CONFIG_JOYSTICK_GAMECON=m +CONFIG_JOYSTICK_GF2K=m +CONFIG_JOYSTICK_GRIP=m +CONFIG_JOYSTICK_GRIP_MP=m +CONFIG_JOYSTICK_GUILLEMOT=m +CONFIG_JOYSTICK_IFORCE=m +CONFIG_JOYSTICK_IFORCE_232=y +CONFIG_JOYSTICK_IFORCE_USB=y +CONFIG_JOYSTICK_INTERACT=m +CONFIG_JOYSTICK_JOYDUMP=m +CONFIG_JOYSTICK_MAGELLAN=m +CONFIG_JOYSTICK_SIDEWINDER=m +CONFIG_JOYSTICK_SPACEBALL=m +CONFIG_JOYSTICK_SPACEORB=m +CONFIG_JOYSTICK_STINGER=m +CONFIG_JOYSTICK_TMDC=m +CONFIG_JOYSTICK_TURBOGRAFX=m +CONFIG_JOYSTICK_TWIDJOY=m +CONFIG_JOYSTICK_WARRIOR=m +CONFIG_JOYSTICK_XPAD=m +CONFIG_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_JOYSTICK_ZHENHUA=m +CONFIG_K8_NB=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_KARMA_PARTITION=y +CONFIG_KEXEC=y +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_GPIO=m +CONFIG_KEYBOARD_LKKBD=m +CONFIG_KEYBOARD_NEWTON=m +CONFIG_KEYBOARD_STOWAWAY=m +CONFIG_KEYBOARD_SUNKBD=m +CONFIG_KEYBOARD_XTKBD=m +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_KGDB=y +CONFIG_KGDB_SERIAL_CONSOLE=y +# CONFIG_KGDB_TESTS is not set +CONFIG_KINGSUN_DONGLE=m +CONFIG_KMOD=y +CONFIG_KPROBES=y +# CONFIG_KPROBES_SANITY_TEST is not set +CONFIG_KRETPROBES=y +CONFIG_KS0108=m +CONFIG_KS0108_DELAY=2 +CONFIG_KS0108_PORT=0x378 +CONFIG_KS959_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +# CONFIG_KTIME_SCALAR is not set +CONFIG_KVM=m +CONFIG_KVM_AMD=m +CONFIG_KVM_CLOCK=y +CONFIG_KVM_GUEST=y +CONFIG_KVM_INTEL=m +# CONFIG_KVM_TRACE is not set +CONFIG_LANMEDIA=m +CONFIG_LAPB=m +CONFIG_LAPBETHER=m +CONFIG_LATENCYTOP=y +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_ILI9320=m +CONFIG_LCD_LTV350QV=m +CONFIG_LCD_PLATFORM=m +CONFIG_LCD_TDO24M=m +CONFIG_LCD_VGG2432A4=m +# CONFIG_LDM_DEBUG is not set +CONFIG_LDM_PARTITION=y +CONFIG_LEDS_CLASS=m +# CONFIG_LEDS_CLEVO_MAIL is not set +CONFIG_LEDS_DA903X=m +CONFIG_LEDS_GPIO=m +CONFIG_LEDS_HP_DISK=m +CONFIG_LEDS_PCA9532=m +CONFIG_LEDS_PCA955X=m +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=m +CONFIG_LEDS_TRIGGER_DEFAULT_ON=m +CONFIG_LEDS_TRIGGER_HEARTBEAT=m +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=0 +CONFIG_LIBCRC32C=m +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_CS=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_SDIO=m +CONFIG_LIBERTAS_THINFIRM=m +CONFIG_LIBERTAS_THINFIRM_USB=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIRC_ATIUSB=m +CONFIG_LIRC_BT829=m +CONFIG_LIRC_CMDIR=m +CONFIG_LIRC_DEV=m +CONFIG_LIRC_GPIO=m +CONFIG_LIRC_I2C=m +CONFIG_LIRC_IGORPLUGUSB=m +CONFIG_LIRC_IMON=m +CONFIG_LIRC_IT87=m +CONFIG_LIRC_MCEUSB=m +CONFIG_LIRC_MCEUSB2=m +# CONFIG_LIRC_PARALLEL is not set +CONFIG_LIRC_PVR150=m +CONFIG_LIRC_SASEM=m +CONFIG_LIRC_SERIAL=m +CONFIG_LIRC_SERIAL_IGOR=m +CONFIG_LIRC_SIR=m +CONFIG_LIRC_STREAMZAP=m +CONFIG_LIRC_TTUSBIR=m +CONFIG_LITELINK_DONGLE=m +# CONFIG_LKDTM is not set +CONFIG_LLC=y +CONFIG_LLC2=m +CONFIG_LMPCM_USB=m +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_LOCKD=m +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_LOCKD_V4=y +CONFIG_LOCK_KERNEL=y +# CONFIG_LOCK_STAT is not set +CONFIG_LOGIRUMBLEPAD2_FF=y +CONFIG_LOGITECH_FF=y +# CONFIG_LOGO is not set +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_LP_CONSOLE is not set +CONFIG_LXT_PHY=m +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +CONFIG_M25PXX_USE_FAST_READ=y +# CONFIG_M386 is not set +# CONFIG_M486 is not set +# CONFIG_M586 is not set +# CONFIG_M586MMX is not set +# CONFIG_M586TSC is not set +# CONFIG_M686 is not set +CONFIG_MA600_DONGLE=m +CONFIG_MAC80211=m +CONFIG_MAC80211_DEBUGFS=y +# CONFIG_MAC80211_DEBUG_MENU is not set +# CONFIG_MAC80211_HWSIM is not set +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_MESH=y +CONFIG_MAC80211_RC_DEFAULT="pid" +# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set +CONFIG_MAC80211_RC_DEFAULT_PID=y +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_PID=y +CONFIG_MACHZ_WDT=m +CONFIG_MACINTOSH_DRIVERS=y +CONFIG_MACVLAN=m +CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_MAC_PARTITION=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_MARKERS=y +CONFIG_MARVELL_PHY=m +CONFIG_MAX_RAW_DEVS=256 +# CONFIG_MCORE2 is not set +CONFIG_MCP2120_DONGLE=m +# CONFIG_MCRUSOE is not set +CONFIG_MCS_FIR=m +# CONFIG_MCYRIXIII is not set +CONFIG_MD=y +CONFIG_MDIO_BITBANG=m +CONFIG_MD_AUTODETECT=y +CONFIG_MD_FAULTY=m +CONFIG_MD_LINEAR=m +CONFIG_MD_MULTIPATH=m +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +CONFIG_MD_RAID5_RESHAPE=y +CONFIG_MEDIA_ATTACH=y +CONFIG_MEDIA_TUNER=m +# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2131=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +# CONFIG_MEFFICEON is not set +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_SAS=m +# CONFIG_MEMSTICK is not set +# CONFIG_MEMTEST is not set +# CONFIG_MFD_CORE is not set +CONFIG_MFD_SM501=m +# CONFIG_MFD_SM501_GPIO is not set +# CONFIG_MFD_TMIO is not set +CONFIG_MFD_WM8350=m +CONFIG_MFD_WM8350_I2C=m +CONFIG_MFD_WM8400=m +# CONFIG_MGEODEGX1 is not set +# CONFIG_MGEODE_LX is not set +CONFIG_MICROCODE=m +CONFIG_MICROCODE_AMD=y +CONFIG_MICROCODE_INTEL=y +CONFIG_MICROCODE_OLD_INTERFACE=y +CONFIG_MII=m +CONFIG_MINIX_FS=m +CONFIG_MINIX_SUBPARTITION=y +CONFIG_MISC_DEVICES=y +CONFIG_MISDN=m +CONFIG_MISDN_DSP=m +CONFIG_MISDN_HFCMULTI=m +CONFIG_MISDN_HFCPCI=m +CONFIG_MISDN_L1OIP=m +# CONFIG_MK6 is not set +# CONFIG_MK7 is not set +# CONFIG_MK8 is not set +CONFIG_MKISS=m +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_MLX4_EN=m +CONFIG_MLX4_INFINIBAND=m +CONFIG_MMC=y +CONFIG_MMC_BLOCK=m +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_RICOH_MMC=m +CONFIG_MMC_SDHCI=m +CONFIG_MMC_SDHCI_PCI=m +CONFIG_MMC_SDRICOH_CS=m +CONFIG_MMC_SPI=m +# CONFIG_MMC_TEST is not set +CONFIG_MMC_TIFM_SD=m +# CONFIG_MMC_UNSAFE_RESUME is not set +CONFIG_MMC_WBSD=m +# CONFIG_MMIOTRACE is not set +CONFIG_MMU=y +CONFIG_MMU_NOTIFIER=y +CONFIG_MM_OWNER=y +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_MOUSE_APPLETOUCH=m +CONFIG_MOUSE_BCM5974=m +CONFIG_MOUSE_GPIO=m +CONFIG_MOUSE_PS2=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_ELANTECH=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_SYNAPTICS=y +# CONFIG_MOUSE_PS2_TOUCHKIT is not set +CONFIG_MOUSE_PS2_TRACKPOINT=y +CONFIG_MOUSE_SERIAL=m +CONFIG_MOUSE_VSXXXAA=m +CONFIG_MOXA_INTELLIO=m +CONFIG_MOXA_SMARTIO=m +# CONFIG_MPENTIUM4 is not set +# CONFIG_MPENTIUMII is not set +# CONFIG_MPENTIUMIII is not set +# CONFIG_MPENTIUMM is not set +# CONFIG_MPSC is not set +CONFIG_MSDOS_FS=m +CONFIG_MSDOS_PARTITION=y +CONFIG_MSI_LAPTOP=m +CONFIG_MT9M001_PCA9536_SWITCH=y +CONFIG_MT9V022_PCA9536_SWITCH=y +CONFIG_MTD=m +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTD_ABSENT=m +CONFIG_MTD_ALAUDA=m +CONFIG_MTD_AMD76XROM=m +CONFIG_MTD_AR7_PARTS=m +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +CONFIG_MTD_BLOCK2MTD=m +CONFIG_MTD_BLOCK_RO=m +CONFIG_MTD_CFI=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_CFI_AMDSTD=m +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=m +CONFIG_MTD_CFI_STAA=m +CONFIG_MTD_CFI_UTIL=m +CONFIG_MTD_CHAR=m +CONFIG_MTD_CK804XROM=m +CONFIG_MTD_COMPLEX_MAPPINGS=y +CONFIG_MTD_CONCAT=m +CONFIG_MTD_DATAFLASH=m +CONFIG_MTD_DATAFLASH_OTP=y +# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_DILNETPC=m +CONFIG_MTD_DILNETPC_BOOTSIZE=0x80000 +CONFIG_MTD_DOC2000=m +CONFIG_MTD_DOC2001=m +CONFIG_MTD_DOC2001PLUS=m +CONFIG_MTD_DOCECC=m +CONFIG_MTD_DOCPROBE=m +CONFIG_MTD_DOCPROBE_ADDRESS=0 +# CONFIG_MTD_DOCPROBE_ADVANCED is not set +CONFIG_MTD_ESB2ROM=m +CONFIG_MTD_GEN_PROBE=m +CONFIG_MTD_ICHXROM=m +CONFIG_MTD_INTEL_VR_NOR=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_L440GX=m +CONFIG_MTD_M25P80=m +CONFIG_MTD_MAP_BANK_WIDTH_1=y +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +CONFIG_MTD_MAP_BANK_WIDTH_2=y +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +CONFIG_MTD_MTDRAM=m +CONFIG_MTD_NAND=m +CONFIG_MTD_NAND_CAFE=m +CONFIG_MTD_NAND_DISKONCHIP=m +# CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE is not set +CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0 +# CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +CONFIG_MTD_NAND_NANDSIM=m +CONFIG_MTD_NAND_PLATFORM=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NETSC520=m +CONFIG_MTD_NETtel=m +CONFIG_MTD_ONENAND=m +CONFIG_MTD_ONENAND_2X_PROGRAM=y +# CONFIG_MTD_ONENAND_OTP is not set +CONFIG_MTD_ONENAND_SIM=m +CONFIG_MTD_ONENAND_VERIFY_WRITE=y +CONFIG_MTD_OOPS=m +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_PCI=m +CONFIG_MTD_PHRAM=m +CONFIG_MTD_PHYSMAP=m +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PHYSMAP_LEN=0x4000000 +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PLATRAM=m +CONFIG_MTD_PMC551=m +# CONFIG_MTD_PMC551_BUGFIX is not set +# CONFIG_MTD_PMC551_DEBUG is not set +CONFIG_MTD_RAM=m +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS=m +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +CONFIG_MTD_ROM=m +CONFIG_MTD_SBC_GXX=m +CONFIG_MTD_SC520CDP=m +CONFIG_MTD_SCB2_FLASH=m +CONFIG_MTD_SLRAM=m +CONFIG_MTD_TS5500=m +CONFIG_MTD_UBI=m +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_DEBUG is not set +CONFIG_MTD_UBI_GLUEBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTRR=y +CONFIG_MTRR_SANITIZER=y +CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0 +CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1 +# CONFIG_MVIAC3_2 is not set +# CONFIG_MVIAC7 is not set +CONFIG_MWAVE=m +# CONFIG_MWINCHIP3D is not set +# CONFIG_MWINCHIPC6 is not set +CONFIG_MYRI10GE=m +CONFIG_MYRI10GE_DCA=y +CONFIG_NAMESPACES=y +CONFIG_NATSEMI=m +CONFIG_NCPFS_EXTRAS=y +CONFIG_NCPFS_IOCTL_LOCKING=y +CONFIG_NCPFS_NFS_NS=y +CONFIG_NCPFS_NLS=y +CONFIG_NCPFS_OS2_NS=y +CONFIG_NCPFS_PACKET_SIGNING=y +# CONFIG_NCPFS_SMALLDOS is not set +CONFIG_NCPFS_STRONG=y +CONFIG_NCP_FS=m +CONFIG_NDISWRAPPER=m +CONFIG_NE2K_PCI=m +CONFIG_NET=y +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETDEVICES=y +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y +CONFIG_NETFILTER=y +CONFIG_NETFILTER_ADVANCED=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_TPROXY=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=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_HASHLIMIT=m +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_IPRANGE=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_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_OWNER=m +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=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_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m +CONFIG_NETFILTER_XT_TARGET_DSCP=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +CONFIG_NETFILTER_XT_TARGET_NOTRACK=m +CONFIG_NETFILTER_XT_TARGET_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETLABEL=y +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NETROM=m +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NETWORK_SECMARK=y +CONFIG_NETXEN_NIC=m +CONFIG_NET_9P=m +# CONFIG_NET_9P_DEBUG is not set +CONFIG_NET_9P_RDMA=m +CONFIG_NET_9P_VIRTIO=m +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_CLS=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_BASIC=m +# CONFIG_NET_CLS_FLOW is not set +CONFIG_NET_CLS_FW=m +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_DCCPPROBE=m +CONFIG_NET_DMA=y +CONFIG_NET_DSA=y +CONFIG_NET_DSA_MV88E6060=y +CONFIG_NET_DSA_MV88E6123_61_65=y +CONFIG_NET_DSA_MV88E6131=y +CONFIG_NET_DSA_MV88E6XXX=y +CONFIG_NET_DSA_MV88E6XXX_NEED_PPU=y +CONFIG_NET_DSA_TAG_DSA=y +CONFIG_NET_DSA_TAG_EDSA=y +CONFIG_NET_DSA_TAG_TRAILER=y +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_ET131X=m +CONFIG_NET_ETHERNET=y +CONFIG_NET_FC=y +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_NET_IPIP=m +CONFIG_NET_KEY=m +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_NET_PCI=y +CONFIG_NET_PCMCIA=y +CONFIG_NET_PKTGEN=m +CONFIG_NET_POCKET=y +CONFIG_NET_POLL_CONTROLLER=y +CONFIG_NET_SB1000=m +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_FIFO=y +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_SCH_MULTIQ=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_TCPPROBE=m +CONFIG_NET_TULIP=y +CONFIG_NET_VENDOR_3COM=y +CONFIG_NEW_LEDS=y +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_AMANDA=m +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_H323=m +CONFIG_NF_CONNTRACK_IPV4=m +CONFIG_NF_CONNTRACK_IPV6=m +CONFIG_NF_CONNTRACK_IRC=m +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=m +CONFIG_NF_CONNTRACK_PPTP=m +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_NF_CONNTRACK_SANE is not set +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_SIP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NF_CT_ACCT=y +CONFIG_NF_CT_NETLINK=m +# CONFIG_NF_CT_PROTO_DCCP is not set +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_DEFRAG_IPV4=m +CONFIG_NF_NAT=m +CONFIG_NF_NAT_AMANDA=m +CONFIG_NF_NAT_FTP=m +CONFIG_NF_NAT_H323=m +CONFIG_NF_NAT_IRC=m +CONFIG_NF_NAT_NEEDED=y +CONFIG_NF_NAT_PPTP=m +CONFIG_NF_NAT_PROTO_GRE=m +CONFIG_NF_NAT_PROTO_SCTP=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NIU=m +CONFIG_NL80211=y +CONFIG_NLS=y +CONFIG_NLS_ASCII=m +CONFIG_NLS_CODEPAGE_1250=m +CONFIG_NLS_CODEPAGE_1251=m +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_874=m +CONFIG_NLS_CODEPAGE_932=m +CONFIG_NLS_CODEPAGE_936=m +CONFIG_NLS_CODEPAGE_949=m +CONFIG_NLS_CODEPAGE_950=m +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_ISO8859_1=m +CONFIG_NLS_ISO8859_13=m +CONFIG_NLS_ISO8859_14=m +CONFIG_NLS_ISO8859_15=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_8=m +CONFIG_NLS_ISO8859_9=m +CONFIG_NLS_KOI8_R=m +CONFIG_NLS_KOI8_U=m +CONFIG_NLS_UTF8=m +CONFIG_NOP_TRACER=y +CONFIG_NORTEL_HERMES=m +CONFIG_NOZOMI=m +CONFIG_NO_HZ=y +CONFIG_NR_CPUS=64 +CONFIG_NS83820=m +CONFIG_NSC_FIR=m +CONFIG_NSC_GPIO=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_FS=m +# CONFIG_NTFS_RW is not set +# CONFIG_NUMA is not set +CONFIG_NVRAM=m +CONFIG_N_HDLC=m +# CONFIG_OCFS2_COMPAT_JBD is not set +# CONFIG_OCFS2_DEBUG_FS is not set +CONFIG_OCFS2_DEBUG_MASKLOG=y +CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_STATS=y +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_OMFS_FS=m +CONFIG_OPEN_TRACER=y +CONFIG_OPROFILE=m +CONFIG_OPROFILE_IBS=y +CONFIG_OPTIMIZE_INLINING=y +CONFIG_OSF_PARTITION=y +CONFIG_P54_COMMON=m +CONFIG_P54_PCI=m +CONFIG_P54_USB=m +CONFIG_P80211=m +CONFIG_PACKARDBELL_E5=m +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_PANASONIC_LAPTOP=m +CONFIG_PANTHERLORD_FF=y +CONFIG_PARAVIRT=y +CONFIG_PARAVIRT_CLOCK=y +# CONFIG_PARAVIRT_DEBUG is not set +CONFIG_PARAVIRT_GUEST=y +CONFIG_PARIDE=m +CONFIG_PARIDE_ATEN=m +CONFIG_PARIDE_BPCK=m +CONFIG_PARIDE_COMM=m +CONFIG_PARIDE_DSTR=m +CONFIG_PARIDE_EPAT=m +# CONFIG_PARIDE_EPATC8 is not set +CONFIG_PARIDE_EPIA=m +CONFIG_PARIDE_FIT2=m +CONFIG_PARIDE_FIT3=m +CONFIG_PARIDE_FRIQ=m +CONFIG_PARIDE_FRPW=m +CONFIG_PARIDE_KBIC=m +CONFIG_PARIDE_KTTI=m +CONFIG_PARIDE_ON20=m +CONFIG_PARIDE_ON26=m +CONFIG_PARIDE_PCD=m +CONFIG_PARIDE_PD=m +CONFIG_PARIDE_PF=m +CONFIG_PARIDE_PG=m +CONFIG_PARIDE_PT=m +CONFIG_PARPORT=m +CONFIG_PARPORT_1284=y +CONFIG_PARPORT_AX88796=m +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_NOT_PC=y +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_FIFO=y +CONFIG_PARPORT_PC_PCMCIA=m +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_SERIAL=m +CONFIG_PARTITION_ADVANCED=y +CONFIG_PATA_ACPI=y +CONFIG_PATA_ALI=y +CONFIG_PATA_AMD=y +CONFIG_PATA_ARTOP=y +CONFIG_PATA_ATIIXP=y +CONFIG_PATA_CMD640_PCI=m +CONFIG_PATA_CMD64X=y +CONFIG_PATA_CS5520=y +CONFIG_PATA_CS5530=y +CONFIG_PATA_CYPRESS=m +CONFIG_PATA_EFAR=y +CONFIG_PATA_HPT366=y +CONFIG_PATA_HPT37X=y +CONFIG_PATA_HPT3X2N=m +CONFIG_PATA_HPT3X3=y +# CONFIG_PATA_HPT3X3_DMA is not set +CONFIG_PATA_IT8213=m +CONFIG_PATA_IT821X=y +CONFIG_PATA_JMICRON=y +CONFIG_PATA_MARVELL=y +CONFIG_PATA_MPIIX=y +CONFIG_PATA_NETCELL=y +CONFIG_PATA_NINJA32=m +CONFIG_PATA_NS87410=y +CONFIG_PATA_NS87415=y +CONFIG_PATA_OLDPIIX=y +CONFIG_PATA_OPTI=m +CONFIG_PATA_OPTIDMA=m +CONFIG_PATA_PCMCIA=m +CONFIG_PATA_PDC2027X=y +CONFIG_PATA_PDC_OLD=y +CONFIG_PATA_RADISYS=m +CONFIG_PATA_RZ1000=y +CONFIG_PATA_SC1200=y +CONFIG_PATA_SCH=y +CONFIG_PATA_SERVERWORKS=y +CONFIG_PATA_SIL680=y +CONFIG_PATA_SIS=y +CONFIG_PATA_TRIFLEX=y +CONFIG_PATA_VIA=y +CONFIG_PATA_WINBOND=y +# CONFIG_PC300TOO is not set +CONFIG_PC8736x_GPIO=m +CONFIG_PC87413_WDT=m +CONFIG_PCCARD=m +CONFIG_PCCARD_NONSTATIC=m +CONFIG_PCI=y +CONFIG_PCI200SYN=m +CONFIG_PCIEAER=y +# CONFIG_PCIEASPM is not set +CONFIG_PCIEPORTBUS=y +CONFIG_PCIPCWATCHDOG=m +CONFIG_PCI_ATMEL=m +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_DIRECT=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_HERMES=m +CONFIG_PCI_LEGACY=y +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_MSI=y +CONFIG_PCI_QUIRKS=y +CONFIG_PCMCIA=m +CONFIG_PCMCIA_3C574=m +CONFIG_PCMCIA_3C589=m +CONFIG_PCMCIA_ATMEL=m +CONFIG_PCMCIA_AXNET=m +# CONFIG_PCMCIA_DEBUG is not set +CONFIG_PCMCIA_FDOMAIN=m +CONFIG_PCMCIA_FMVJ18X=m +CONFIG_PCMCIA_HERMES=m +CONFIG_PCMCIA_IBMTR=m +CONFIG_PCMCIA_IOCTL=y +CONFIG_PCMCIA_LOAD_CIS=y +CONFIG_PCMCIA_NETWAVE=m +CONFIG_PCMCIA_NMCLAN=m +CONFIG_PCMCIA_PCNET=m +CONFIG_PCMCIA_QLOGIC=m +CONFIG_PCMCIA_RAYCS=m +CONFIG_PCMCIA_SMC91C92=m +CONFIG_PCMCIA_SPECTRUM=m +CONFIG_PCMCIA_SYM53C500=m +CONFIG_PCMCIA_WAVELAN=m +CONFIG_PCMCIA_WL3501=m +CONFIG_PCMCIA_XIRC2PS=m +CONFIG_PCMCIA_XIRCOM=m +CONFIG_PCNET32=m +CONFIG_PCSPKR_PLATFORM=y +CONFIG_PD6729=m +CONFIG_PDA_POWER=m +CONFIG_PDC_ADMA=y +CONFIG_PHANTOM=m +CONFIG_PHONE=m +CONFIG_PHONET=m +CONFIG_PHONE_IXJ=m +CONFIG_PHONE_IXJ_PCMCIA=m +CONFIG_PHYLIB=y +CONFIG_PHYSICAL_ALIGN=0x200000 +CONFIG_PHYSICAL_START=0x200000 +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_PID_NS=y +CONFIG_PLIP=m +CONFIG_PLIST=y +CONFIG_PLX_HERMES=m +CONFIG_PM=y +CONFIG_PMIC_DA903X=y +CONFIG_PM_DEBUG=y +CONFIG_PM_DISABLE_CONSOLE=y +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +CONFIG_PM_STD_PARTITION="" +CONFIG_PM_TEST_SUSPEND=y +CONFIG_PM_TRACE=y +CONFIG_PM_TRACE_RTC=y +# CONFIG_PM_VERBOSE is not set +CONFIG_PNP=y +CONFIG_PNPACPI=y +CONFIG_PNP_DEBUG_MESSAGES=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +CONFIG_PPDEV=m +CONFIG_PPP=y +CONFIG_PPPOATM=m +CONFIG_PPPOE=m +CONFIG_PPPOL2TP=m +CONFIG_PPP_ASYNC=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_FILTER=y +CONFIG_PPP_MPPE=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_SYNC_TTY=m +# CONFIG_PREEMPT is not set +CONFIG_PREEMPT_NOTIFIERS=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_PRINTER=m +CONFIG_PRINTK=y +CONFIG_PRINTK_TIME=y +CONFIG_PRINT_QUOTA_WARNING=y +CONFIG_PRISM2_USB=m +CONFIG_PRISM54=m +CONFIG_PROC_EVENTS=y +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_VMCORE=y +CONFIG_PROFILING=y +# CONFIG_PROVE_LOCKING is not set +# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set +# CONFIG_PSS_HAVE_BOOT is not set +CONFIG_PSS_MIXER=y +CONFIG_QC_USB=m +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_QLA3XXX=m +CONFIG_QLGE=m +CONFIG_QNX4FS_FS=m +CONFIG_QSEMI_PHY=m +CONFIG_QUOTA=y +CONFIG_QUOTACTL=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +CONFIG_R3964=m +# CONFIG_R6040 is not set +CONFIG_R8169=m +CONFIG_R8169_VLAN=y +CONFIG_RADIO_ADAPTERS=y +CONFIG_RADIO_GEMTEK_PCI=m +CONFIG_RADIO_MAESTRO=m +CONFIG_RADIO_MAXIRADIO=m +CONFIG_RAID_ATTRS=m +CONFIG_RAW_DRIVER=m +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_REALTEK_PHY is not set +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_DEC16=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_BQ24022=m +CONFIG_REGULATOR_DA903X=m +# CONFIG_REGULATOR_DEBUG is not set +# CONFIG_REGULATOR_FIXED_VOLTAGE is not set +CONFIG_REGULATOR_VIRTUAL_CONSUMER=m +CONFIG_REGULATOR_WM8350=m +CONFIG_REGULATOR_WM8400=m +# CONFIG_REISERFS_CHECK is not set +CONFIG_REISERFS_FS=m +CONFIG_REISERFS_FS_POSIX_ACL=y +CONFIG_REISERFS_FS_SECURITY=y +CONFIG_REISERFS_FS_XATTR=y +# CONFIG_REISERFS_PROC_INFO is not set +CONFIG_RELAY=y +CONFIG_RELOCATABLE=y +CONFIG_RESOURCES_64BIT=y +CONFIG_RESOURCE_COUNTERS=y +CONFIG_RFD_FTL=m +CONFIG_RFKILL=y +CONFIG_RFKILL_INPUT=m +CONFIG_RFKILL_LEDS=y +CONFIG_RING_BUFFER=y +CONFIG_RIO=m +# CONFIG_RIO_OLDPCI is not set +CONFIG_RISCOM8=m +CONFIG_ROADRUNNER=m +# CONFIG_ROADRUNNER_LARGE_RINGS is not set +CONFIG_ROCKETPORT=m +CONFIG_ROMFS_FS=m +CONFIG_ROSE=m +CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_RPCSEC_GSS_SPKM3=m +CONFIG_RT2400PCI=m +CONFIG_RT2500PCI=m +CONFIG_RT2500USB=m +CONFIG_RT2860=m +CONFIG_RT2870=m +CONFIG_RT2X00=m +# CONFIG_RT2X00_DEBUG is not set +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_CRYPTO=y +# CONFIG_RT2X00_LIB_DEBUGFS is not set +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_LEDS=y +CONFIG_RT2X00_LIB_PCI=m +CONFIG_RT2X00_LIB_RFKILL=y +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT61PCI=m +CONFIG_RT73USB=m +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DEBUG is not set +CONFIG_RTC_DRV_BQ4802=m +CONFIG_RTC_DRV_CMOS=y +CONFIG_RTC_DRV_DS1286=m +CONFIG_RTC_DRV_DS1305=m +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1390=m +# CONFIG_RTC_DRV_DS1511 is not set +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_DS3234=m +CONFIG_RTC_DRV_FM3130=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_M41T80_WDT=y +CONFIG_RTC_DRV_M41T94=m +CONFIG_RTC_DRV_M48T35=m +CONFIG_RTC_DRV_M48T59=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_MAX6900=m +CONFIG_RTC_DRV_MAX6902=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_PCF8583=m +# CONFIG_RTC_DRV_R9701 is not set +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_RX8581=m +# CONFIG_RTC_DRV_S35390A is not set +CONFIG_RTC_DRV_STK17TA8=m +CONFIG_RTC_DRV_TEST=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_WM8350=m +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_LIB=y +CONFIG_RTL8180=m +CONFIG_RTL8187=m +CONFIG_RTL8187SE=m +CONFIG_RT_GROUP_SCHED=y +CONFIG_RT_MUTEXES=y +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_RXKAD=m +CONFIG_S2IO=m +# CONFIG_SAMPLES is not set +CONFIG_SATA_AHCI=y +CONFIG_SATA_INIC162X=y +CONFIG_SATA_MV=m +CONFIG_SATA_NV=y +CONFIG_SATA_PMP=y +CONFIG_SATA_PROMISE=y +CONFIG_SATA_QSTOR=y +CONFIG_SATA_SIL=y +CONFIG_SATA_SIL24=y +CONFIG_SATA_SIS=y +CONFIG_SATA_SVW=y +CONFIG_SATA_SX4=y +CONFIG_SATA_ULI=y +CONFIG_SATA_VIA=y +CONFIG_SATA_VITESSE=y +CONFIG_SBC8360_WDT=m +CONFIG_SBC_EPX_C3_WATCHDOG=m +CONFIG_SBNI=m +# CONFIG_SBNI_MULTILINE is not set +CONFIG_SC1200_WDT=m +CONFIG_SC520_WDT=m +CONFIG_SC6600=y +CONFIG_SC6600_CDROM=4 +CONFIG_SC6600_CDROMBASE=0 +CONFIG_SC6600_JOY=y +CONFIG_SC92031=m +CONFIG_SCHEDSTATS=y +CONFIG_SCHED_DEBUG=y +CONFIG_SCHED_HRTICK=y +CONFIG_SCHED_MC=y +CONFIG_SCHED_SMT=y +# CONFIG_SCHED_TRACER is not set +CONFIG_SCSI=y +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_ADVANSYS=m +CONFIG_SCSI_AIC79XX=m +CONFIG_SCSI_AIC7XXX=m +# CONFIG_SCSI_AIC7XXX_OLD is not set +CONFIG_SCSI_AIC94XX=m +CONFIG_SCSI_ARCMSR=m +CONFIG_SCSI_ARCMSR_AER=y +CONFIG_SCSI_BUSLOGIC=m +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_DC390T=m +CONFIG_SCSI_DC395x=m +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_DH=y +CONFIG_SCSI_DH_ALUA=m +CONFIG_SCSI_DH_EMC=m +CONFIG_SCSI_DH_HP_SW=m +CONFIG_SCSI_DH_RDAC=m +CONFIG_SCSI_DMA=y +CONFIG_SCSI_DMX3191D=m +CONFIG_SCSI_DPT_I2O=m +CONFIG_SCSI_EATA=m +CONFIG_SCSI_EATA_LINKED_COMMANDS=y +CONFIG_SCSI_EATA_MAX_TAGS=16 +CONFIG_SCSI_EATA_TAGGED_QUEUE=y +CONFIG_SCSI_ENCLOSURE=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_FC_TGT_ATTRS=y +CONFIG_SCSI_FUTURE_DOMAIN=m +CONFIG_SCSI_GDTH=m +CONFIG_SCSI_HPTIOP=m +CONFIG_SCSI_IMM=m +CONFIG_SCSI_INIA100=m +CONFIG_SCSI_INITIO=m +CONFIG_SCSI_IPR=m +# CONFIG_SCSI_IPR_DUMP is not set +# CONFIG_SCSI_IPR_TRACE is not set +CONFIG_SCSI_IPS=m +CONFIG_SCSI_ISCSITARGET=m +CONFIG_SCSI_ISCSI_ATTRS=m +# CONFIG_SCSI_IZIP_EPP16 is not set +# CONFIG_SCSI_IZIP_SLOW_CTR is not set +CONFIG_SCSI_LOGGING=y +CONFIG_SCSI_LOWLEVEL=y +CONFIG_SCSI_LOWLEVEL_PCMCIA=y +CONFIG_SCSI_LPFC=m +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_MVSAS is not set +CONFIG_SCSI_NETLINK=y +CONFIG_SCSI_PPA=m +CONFIG_SCSI_PROC_FS=y +CONFIG_SCSI_QLA_FC=m +CONFIG_SCSI_QLA_ISCSI=m +CONFIG_SCSI_QLOGIC_1280=m +CONFIG_SCSI_SAS_ATA=y +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_HOST_SMP=y +CONFIG_SCSI_SAS_LIBSAS=m +# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_SRP=m +CONFIG_SCSI_SRP_ATTRS=m +CONFIG_SCSI_SRP_TGT_ATTRS=y +CONFIG_SCSI_STEX=m +CONFIG_SCSI_SYM53C8XX_2=m +CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 +CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 +CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 +CONFIG_SCSI_SYM53C8XX_MMIO=y +CONFIG_SCSI_TGT=m +CONFIG_SCSI_WAIT_SCAN=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +CONFIG_SCTP_HMAC_MD5=y +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SDIO_UART=m +CONFIG_SECCOMP=y +CONFIG_SECURITY=y +CONFIG_SECURITYFS=y +CONFIG_SECURITY_APPARMOR=y +CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 +CONFIG_SECURITY_APPARMOR_DISABLE=y +CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=65536 +CONFIG_SECURITY_FILE_CAPABILITIES=y +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +# CONFIG_SECURITY_ROOTPLUG is not set +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SELINUX_AVC_STATS=y +CONFIG_SECURITY_SELINUX_BOOTPARAM=y +CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0 +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 +CONFIG_SECURITY_SELINUX_DEVELOP=y +CONFIG_SECURITY_SELINUX_DISABLE=y +# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set +# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set +CONFIG_SECURITY_SMACK=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_ABITUGURU3=m +CONFIG_SENSORS_AD7414=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADCXX=m +CONFIG_SENSORS_ADM1021=m +CONFIG_SENSORS_ADM1025=m +CONFIG_SENSORS_ADM1026=m +CONFIG_SENSORS_ADM1029=m +CONFIG_SENSORS_ADM1031=m +CONFIG_SENSORS_ADM9240=m +CONFIG_SENSORS_ADS7828=m +CONFIG_SENSORS_ADT7462=m +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_ADT7473=m +CONFIG_SENSORS_APPLESMC=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_CORETEMP=m +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_FSCHMD=m +CONFIG_SENSORS_FSCPOS=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_HDAPS=m +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_IBMAEM=m +CONFIG_SENSORS_IBMPEX=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_K8TEMP=m +CONFIG_SENSORS_LIS3LV02D=m +CONFIG_SENSORS_LM63=m +CONFIG_SENSORS_LM70=m +CONFIG_SENSORS_LM75=m +CONFIG_SENSORS_LM77=m +CONFIG_SENSORS_LM78=m +CONFIG_SENSORS_LM80=m +CONFIG_SENSORS_LM83=m +CONFIG_SENSORS_LM85=m +CONFIG_SENSORS_LM87=m +CONFIG_SENSORS_LM90=m +CONFIG_SENSORS_LM92=m +CONFIG_SENSORS_LM93=m +CONFIG_SENSORS_MAX1111=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_TSL2550=m +CONFIG_SENSORS_VIA686A=m +CONFIG_SENSORS_VT1211=m +CONFIG_SENSORS_VT8231=m +CONFIG_SENSORS_W83627EHF=m +CONFIG_SENSORS_W83627HF=m +CONFIG_SENSORS_W83781D=m +CONFIG_SENSORS_W83791D=m +CONFIG_SENSORS_W83792D=m +CONFIG_SENSORS_W83793=m +CONFIG_SENSORS_W83L785TS=m +CONFIG_SENSORS_W83L786NG=m +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_CS=m +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_NR_UARTS=48 +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_PNP=y +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_JSM=m +CONFIG_SERIAL_NONSTANDARD=y +CONFIG_SERIO=y +CONFIG_SERIO_CT82C710=m +CONFIG_SERIO_I8042=y +CONFIG_SERIO_LIBPS2=y +CONFIG_SERIO_PARKBD=m +CONFIG_SERIO_PCIPS2=m +CONFIG_SERIO_RAW=m +CONFIG_SERIO_SERPORT=m +CONFIG_SFC=m +CONFIG_SGI_GRU=m +# CONFIG_SGI_GRU_DEBUG is not set +CONFIG_SGI_IOC4=m +CONFIG_SGI_PARTITION=y +CONFIG_SGI_XP=m +CONFIG_SHMEM=y +CONFIG_SIGMATEL_FIR=m +CONFIG_SIGNALFD=y +CONFIG_SIS190=m +CONFIG_SIS900=m +CONFIG_SKFP=m +CONFIG_SKGE=m +# CONFIG_SKGE_DEBUG is not set +CONFIG_SKY2=m +# CONFIG_SKY2_DEBUG is not set +# CONFIG_SLAB is not set +CONFIG_SLABINFO=y +CONFIG_SLHC=y +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_MODE_SLIP6=y +CONFIG_SLIP_SMART=y +# CONFIG_SLOB is not set +CONFIG_SLUB=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_SMC_IRCC_FIR=m +CONFIG_SMP=y +CONFIG_SMSC37B787_WDT=m +# CONFIG_SMSC911X is not set +CONFIG_SMSC_PHY=m +CONFIG_SND=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_AC97_POWER_SAVE=y +CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0 +CONFIG_SND_AD1889=m +CONFIG_SND_ALI5451=m +CONFIG_SND_ALS300=m +CONFIG_SND_ALS4000=m +CONFIG_SND_ATIIXP=m +CONFIG_SND_ATIIXP_MODEM=m +CONFIG_SND_AU8810=m +CONFIG_SND_AU8820=m +CONFIG_SND_AU8830=m +CONFIG_SND_AW2=m +CONFIG_SND_AZT3328=m +CONFIG_SND_BT87X=m +# CONFIG_SND_BT87X_OVERCLOCK is not set +CONFIG_SND_BTSCO=m +CONFIG_SND_CA0106=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_CS4281=m +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_CS5530=m +CONFIG_SND_DARLA20=m +CONFIG_SND_DARLA24=m +# CONFIG_SND_DEBUG is not set +CONFIG_SND_DRIVERS=y +CONFIG_SND_DUMMY=m +CONFIG_SND_DYNAMIC_MINORS=y +CONFIG_SND_ECHO3G=m +CONFIG_SND_EMU10K1=m +CONFIG_SND_EMU10K1X=m +CONFIG_SND_ENS1370=m +CONFIG_SND_ENS1371=m +CONFIG_SND_ES1938=m +CONFIG_SND_ES1968=m +CONFIG_SND_FM801=m +CONFIG_SND_FM801_TEA575X=m +CONFIG_SND_FM801_TEA575X_BOOL=y +CONFIG_SND_GINA20=m +CONFIG_SND_GINA24=m +CONFIG_SND_HDA_CODEC_ANALOG=y +CONFIG_SND_HDA_CODEC_ATIHDMI=y +CONFIG_SND_HDA_CODEC_CMEDIA=y +CONFIG_SND_HDA_CODEC_CONEXANT=y +CONFIG_SND_HDA_CODEC_INTELHDMI=y +CONFIG_SND_HDA_CODEC_NVHDMI=y +CONFIG_SND_HDA_CODEC_REALTEK=y +CONFIG_SND_HDA_CODEC_SI3054=y +CONFIG_SND_HDA_CODEC_SIGMATEL=y +CONFIG_SND_HDA_CODEC_VIA=y +CONFIG_SND_HDA_ELD=y +CONFIG_SND_HDA_GENERIC=y +# CONFIG_SND_HDA_HWDEP is not set +CONFIG_SND_HDA_INPUT_BEEP=y +CONFIG_SND_HDA_INTEL=m +CONFIG_SND_HDA_POWER_SAVE=y +CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 +CONFIG_SND_HDSP=m +CONFIG_SND_HDSPM=m +CONFIG_SND_HIFIER=m +CONFIG_SND_HWDEP=m +CONFIG_SND_ICE1712=m +CONFIG_SND_ICE1724=m +CONFIG_SND_INDIGO=m +CONFIG_SND_INDIGODJ=m +CONFIG_SND_INDIGOIO=m +CONFIG_SND_INTEL8X0=m +CONFIG_SND_INTEL8X0M=m +CONFIG_SND_KORG1212=m +CONFIG_SND_LAYLA20=m +CONFIG_SND_LAYLA24=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_MIA=m +CONFIG_SND_MIXART=m +CONFIG_SND_MIXER_OSS=m +CONFIG_SND_MONA=m +CONFIG_SND_MPU401=m +CONFIG_SND_MPU401_UART=m +CONFIG_SND_MTPAV=m +CONFIG_SND_MTS64=m +CONFIG_SND_NM256=m +CONFIG_SND_OPL3_LIB=m +CONFIG_SND_OSSEMUL=y +CONFIG_SND_OXYGEN=m +CONFIG_SND_OXYGEN_LIB=m +CONFIG_SND_PCI=y +CONFIG_SND_PCM=m +CONFIG_SND_PCMCIA=y +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_PCSP=m +CONFIG_SND_PCXHR=m +CONFIG_SND_PDAUDIOCF=m +CONFIG_SND_PORTMAN2X4=m +CONFIG_SND_RAWMIDI=m +CONFIG_SND_RIPTIDE=m +CONFIG_SND_RME32=m +CONFIG_SND_RME96=m +CONFIG_SND_RME9652=m +CONFIG_SND_SB16_DSP=m +CONFIG_SND_SB_COMMON=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_SOC=m +CONFIG_SND_SOC_AD73311=m +CONFIG_SND_SOC_AK4535=m +CONFIG_SND_SOC_ALL_CODECS=m +CONFIG_SND_SOC_CS4270=m +CONFIG_SND_SOC_SSM2602=m +CONFIG_SND_SOC_TLV320AIC23=m +CONFIG_SND_SOC_TLV320AIC26=m +CONFIG_SND_SOC_TLV320AIC3X=m +CONFIG_SND_SOC_UDA1380=m +CONFIG_SND_SOC_WM8510=m +CONFIG_SND_SOC_WM8580=m +CONFIG_SND_SOC_WM8731=m +CONFIG_SND_SOC_WM8750=m +CONFIG_SND_SOC_WM8753=m +CONFIG_SND_SOC_WM8900=m +CONFIG_SND_SOC_WM8903=m +CONFIG_SND_SOC_WM8971=m +CONFIG_SND_SOC_WM8990=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_SPI=y +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_TIMER=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_USB_US122L=m +CONFIG_SND_USB_USX2Y=m +# CONFIG_SND_VERBOSE_PRINTK is not set +CONFIG_SND_VERBOSE_PROCFS=y +CONFIG_SND_VIA82XX=m +CONFIG_SND_VIA82XX_MODEM=m +CONFIG_SND_VIRMIDI=m +CONFIG_SND_VIRTUOSO=m +CONFIG_SND_VMASTER=y +CONFIG_SND_VX222=m +CONFIG_SND_VXPOCKET=m +CONFIG_SND_VX_LIB=m +CONFIG_SND_YMFPCI=m +CONFIG_SOC_CAMERA=m +CONFIG_SOC_CAMERA_MT9M001=m +CONFIG_SOC_CAMERA_MT9M111=m +CONFIG_SOC_CAMERA_MT9V022=m +CONFIG_SOC_CAMERA_PLATFORM=m +CONFIG_SOFT_WATCHDOG=m +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_SONYPI_COMPAT=y +CONFIG_SONY_LAPTOP=m +CONFIG_SOUND=m +CONFIG_SOUND_AEDSP16=m +CONFIG_SOUND_DMAP=y +CONFIG_SOUND_KAHLUA=m +CONFIG_SOUND_MPU401=m +CONFIG_SOUND_MSS=m +CONFIG_SOUND_OSS=m +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_PAS=m +CONFIG_SOUND_PRIME=m +CONFIG_SOUND_PSS=m +CONFIG_SOUND_SB=m +CONFIG_SOUND_SSCAPE=m +# CONFIG_SOUND_TRACEINIT is not set +CONFIG_SOUND_TRIX=m +CONFIG_SOUND_UART6850=m +CONFIG_SOUND_VMIDI=m +CONFIG_SOUND_YM3812=m +CONFIG_SPARSEMEM=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPECIALIX=m +CONFIG_SPI=y +CONFIG_SPI_AT25=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_LM70_LLP=m +CONFIG_SPI_MASTER=y +CONFIG_SPI_SPIDEV=m +CONFIG_SPI_TLE62X0=m +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_SQUASHFS=m +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +CONFIG_SSB=m +CONFIG_SSB_B43_PCI_BRIDGE=y +# CONFIG_SSB_DEBUG is not set +CONFIG_SSB_DRIVER_PCICORE=y +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +# CONFIG_SSB_PCMCIAHOST is not set +CONFIG_SSB_PCMCIAHOST_POSSIBLE=y +CONFIG_SSB_POSSIBLE=y +CONFIG_SSB_SPROM=y +CONFIG_SSFDC=m +CONFIG_STACKTRACE=y +CONFIG_STACKTRACE_SUPPORT=y +# CONFIG_STACK_TRACER is not set +CONFIG_STAGING=y +CONFIG_STAGING_EXCLUDE_BUILD=y +CONFIG_STALDRV=y +CONFIG_STALLION=m +# CONFIG_STANDALONE is not set +CONFIG_STOP_MACHINE=y +CONFIG_STP=m +CONFIG_STRICT_DEVMEM=y +CONFIG_STRIP=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_SUNGEM=m +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +# CONFIG_SUNRPC_REGISTER_V4 is not set +CONFIG_SUNRPC_XPRT_RDMA=m +CONFIG_SUN_PARTITION=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_SWAP=y +CONFIG_SWIOTLB=y +CONFIG_SX=m +CONFIG_SYNCLINK=m +CONFIG_SYNCLINKMP=m +CONFIG_SYNCLINK_CS=m +CONFIG_SYNCLINK_GT=m +CONFIG_SYN_COOKIES=y +CONFIG_SYSCTL=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_SYSFS=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_SYSPROF_TRACER is not set +CONFIG_SYSV68_PARTITION=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_SYSV_FS=m +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_TABLET_USB_ACECAD=m +CONFIG_TABLET_USB_AIPTEK=m +CONFIG_TABLET_USB_GTCO=m +CONFIG_TABLET_USB_KBTAB=m +CONFIG_TABLET_USB_WACOM=m +CONFIG_TASKSTATS=y +# CONFIG_TASK_DELAY_ACCT is not set +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_TASK_XACCT=y +CONFIG_TCG_ATMEL=m +CONFIG_TCG_INFINEON=m +CONFIG_TCG_NSC=m +CONFIG_TCG_TIS=m +CONFIG_TCG_TPM=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_MD5SIG=y +CONFIG_TEHUTI=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TELCLOCK=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_TEXTSEARCH_KMP=m +CONFIG_THERMAL=y +CONFIG_THERMAL_HWMON=y +CONFIG_THINKPAD_ACPI=m +CONFIG_THINKPAD_ACPI_BAY=y +# CONFIG_THINKPAD_ACPI_DEBUG is not set +CONFIG_THINKPAD_ACPI_HOTKEY_POLL=y +CONFIG_THINKPAD_ACPI_VIDEO=y +CONFIG_THRUSTMASTER_FF=m +CONFIG_TICK_ONESHOT=y +CONFIG_TIFM_7XX1=m +CONFIG_TIFM_CORE=m +CONFIG_TIGON3=m +CONFIG_TIMERFD=y +CONFIG_TIMER_STATS=y +# CONFIG_TINY_SHMEM is not set +CONFIG_TIPC=m +# CONFIG_TIPC_ADVANCED is not set +# CONFIG_TIPC_DEBUG is not set +CONFIG_TLAN=m +CONFIG_TLSF=m +# CONFIG_TLSF_DEBUG is not set +# CONFIG_TLSF_STATS is not set +# CONFIG_TLSUP is not set +CONFIG_TMD_HERMES=m +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMS380TR=m +CONFIG_TMSPCI=m +# CONFIG_TOIM3232_DONGLE is not set +CONFIG_TOUCHSCREEN_ADS7846=m +CONFIG_TOUCHSCREEN_ELO=m +CONFIG_TOUCHSCREEN_FUJITSU=m +CONFIG_TOUCHSCREEN_GUNZE=m +CONFIG_TOUCHSCREEN_INEXIO=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TOUCHIT213=m +CONFIG_TOUCHSCREEN_TOUCHRIGHT=m +CONFIG_TOUCHSCREEN_TOUCHWIN=m +CONFIG_TOUCHSCREEN_UCB1400=m +CONFIG_TOUCHSCREEN_USB_3M=y +CONFIG_TOUCHSCREEN_USB_COMPOSITE=m +CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y +CONFIG_TOUCHSCREEN_USB_EGALAX=y +CONFIG_TOUCHSCREEN_USB_ETURBO=y +CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TOUCHSCREEN_WM9705=y +CONFIG_TOUCHSCREEN_WM9712=y +CONFIG_TOUCHSCREEN_WM9713=y +CONFIG_TOUCHSCREEN_WM97XX=m +CONFIG_TPS65010=m +CONFIG_TP_SMAPI=m +CONFIG_TP_SMAPI_EC=m +CONFIG_TR=y +CONFIG_TRACEPOINTS=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_TRACING=y +CONFIG_TTPCI_EEPROM=m +CONFIG_TULIP=m +# CONFIG_TULIP_MMIO is not set +# CONFIG_TULIP_MWI is not set +# CONFIG_TULIP_NAPI is not set +CONFIG_TUN=m +CONFIG_TYPHOON=m +CONFIG_UBIFS_FS=m +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +# CONFIG_UBIFS_FS_DEBUG is not set +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_XATTR=y +CONFIG_UBIFS_FS_ZLIB=y +CONFIG_UCB1400_CORE=m +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +CONFIG_UEVENT_HELPER_PATH="" +# CONFIG_UFS_DEBUG is not set +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +CONFIG_UID16=y +CONFIG_UIO=m +CONFIG_UIO_CIF=m +CONFIG_UIO_PDRV=m +CONFIG_UIO_PDRV_GENIRQ=m +CONFIG_UIO_SERCOS3=m +CONFIG_UIO_SMX=m +CONFIG_ULI526X=m +CONFIG_ULTRIX_PARTITION=y +CONFIG_UNEVICTABLE_LRU=y +CONFIG_UNIX=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_USB=y +CONFIG_USBPCWATCHDOG=m +CONFIG_USB_ACM=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_APPLEIR=m +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARMLINUX=y +CONFIG_USB_ATM=m +CONFIG_USB_ATMEL=m +CONFIG_USB_BELKIN=y +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_C67X00_HCD=m +CONFIG_USB_CATC=m +CONFIG_USB_CDC_COMPOSITE=m +CONFIG_USB_CXACRU=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +CONFIG_USB_DSBR=m +CONFIG_USB_DUMMY_HCD=m +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EMI26=m +CONFIG_USB_EMI62=m +CONFIG_USB_EPSON2888=y +CONFIG_USB_ET61X251=m +CONFIG_USB_ETH=m +CONFIG_USB_ETH_RNDIS=y +CONFIG_USB_EZUSB=y +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_FTDI_ELAN=m +CONFIG_USB_GADGET=m +CONFIG_USB_GADGETFS=m +# CONFIG_USB_GADGET_AMD5536UDC is not set +# CONFIG_USB_GADGET_ARC is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_DUALSPEED=y +CONFIG_USB_GADGET_DUMMY_HCD=y +# CONFIG_USB_GADGET_FSL_QE is not set +# CONFIG_USB_GADGET_FSL_USB2 is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C2410 is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GSPCA=m +CONFIG_USB_GSPCA_CONEX=m +CONFIG_USB_GSPCA_ETOMS=m +CONFIG_USB_GSPCA_FINEPIX=m +CONFIG_USB_GSPCA_MARS=m +CONFIG_USB_GSPCA_OV519=m +CONFIG_USB_GSPCA_PAC207=m +CONFIG_USB_GSPCA_PAC7311=m +CONFIG_USB_GSPCA_SONIXB=m +CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_USB_GSPCA_SPCA500=m +CONFIG_USB_GSPCA_SPCA501=m +CONFIG_USB_GSPCA_SPCA505=m +CONFIG_USB_GSPCA_SPCA506=m +CONFIG_USB_GSPCA_SPCA508=m +CONFIG_USB_GSPCA_SPCA561=m +CONFIG_USB_GSPCA_STK014=m +CONFIG_USB_GSPCA_SUNPLUS=m +CONFIG_USB_GSPCA_T613=m +CONFIG_USB_GSPCA_TV8532=m +CONFIG_USB_GSPCA_VC032X=m +CONFIG_USB_GSPCA_ZC3XX=m +# CONFIG_USB_G_PRINTER is not set +CONFIG_USB_G_SERIAL=m +CONFIG_USB_HID=m +CONFIG_USB_HIDDEV=y +CONFIG_USB_HSO=m +CONFIG_USB_HWA_HCD=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_IRDA=m +CONFIG_USB_ISIGHTFW=m +CONFIG_USB_ISP116X_HCD=m +CONFIG_USB_ISP1760_HCD=m +CONFIG_USB_KAWETH=m +CONFIG_USB_KBD=m +CONFIG_USB_KC2190=y +CONFIG_USB_KONICAWC=m +CONFIG_USB_LCD=m +CONFIG_USB_LD=m +CONFIG_USB_LED=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LIBUSUAL=y +CONFIG_USB_M5602=m +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_USB_MON=y +CONFIG_USB_MOUSE=m +CONFIG_USB_MR800=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_DM9601=m +CONFIG_USB_NET_GL620A=m +CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +CONFIG_USB_NET_RNDIS_HOST=m +CONFIG_USB_NET_RNDIS_WLAN=m +CONFIG_USB_NET_SMSC95XX=m +CONFIG_USB_NET_ZAURUS=m +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OV511 is not set +CONFIG_USB_OV511_NEW=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_PHIDGET=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETMOTORCONTROL=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_PRINTER=m +CONFIG_USB_PWC=m +# CONFIG_USB_PWC_DEBUG is not set +CONFIG_USB_QUICKCAM_MESSENGER=m +CONFIG_USB_R8A66597_HCD=m +CONFIG_USB_RIO500=m +CONFIG_USB_RTL8150=m +CONFIG_USB_S2255=m +CONFIG_USB_SE401=m +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_CONSOLE=y +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_DEBUG=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_EMPEG=m +CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IPW=m +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_IUU is not set +CONFIG_USB_SERIAL_KEYSPAN=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_MOS7720=m +CONFIG_USB_SERIAL_MOS7840=m +CONFIG_USB_SERIAL_MOTOROLA=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OTI6858=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_USB_SERIAL_SAFE=m +# CONFIG_USB_SERIAL_SAFE_PADDED is not set +CONFIG_USB_SERIAL_SIERRAWIRELESS=m +CONFIG_USB_SERIAL_SPCP8X5=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SEVSEG=m +CONFIG_USB_SI470X=m +CONFIG_USB_SISUSBVGA=m +# CONFIG_USB_SISUSBVGA_CON is not set +CONFIG_USB_SL811_CS=m +CONFIG_USB_SL811_HCD=m +CONFIG_USB_SN9C102=m +CONFIG_USB_SPEEDTOUCH=m +CONFIG_USB_STKWEBCAM=m +CONFIG_USB_STORAGE=m +CONFIG_USB_STORAGE_ALAUDA=y +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +CONFIG_USB_STORAGE_DATAFAB=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_JUMPSHOT=y +CONFIG_USB_STORAGE_KARMA=y +# CONFIG_USB_STORAGE_ONETOUCH is not set +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STV680=m +CONFIG_USB_SUPPORT=y +CONFIG_USB_SUSPEND=y +# CONFIG_USB_TEST is not set +CONFIG_USB_TMC=m +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_U132_HCD=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_UHCI_HCD=y +CONFIG_USB_USBNET=m +CONFIG_USB_USS720=m +CONFIG_USB_VICAM=m +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_VST=m +CONFIG_USB_W9968CF=m +CONFIG_USB_WDM=m +CONFIG_USB_WHCI_HCD=m +CONFIG_USB_WUSB=m +CONFIG_USB_WUSB_CBAF=m +# CONFIG_USB_WUSB_CBAF_DEBUG is not set +CONFIG_USB_XUSBATM=m +CONFIG_USB_ZC0301=m +CONFIG_USB_ZD1201=m +CONFIG_USB_ZERO=m +CONFIG_USB_ZR364XX=m +# CONFIG_USER_NS is not set +# CONFIG_USER_SCHED is not set +CONFIG_USE_GENERIC_SMP_HELPERS=y +CONFIG_UTS_NS=y +CONFIG_UWB=m +CONFIG_UWB_HWA=m +CONFIG_UWB_I1480U=m +CONFIG_UWB_I1480U_WLP=m +CONFIG_UWB_WHCI=m +CONFIG_UWB_WLP=m +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VERSION_SIGNATURE="" +CONFIG_VETH=m +CONFIG_VFAT_FS=m +# CONFIG_VGACON_SOFT_SCROLLBACK is not set +CONFIG_VGASTATE=m +CONFIG_VGA_CONSOLE=y +CONFIG_VIA_FIR=m +CONFIG_VIA_RHINE=m +CONFIG_VIA_RHINE_MMIO=y +CONFIG_VIA_VELOCITY=m +CONFIG_VIDEOBUF_DMA_CONTIG=m +CONFIG_VIDEOBUF_DMA_SG=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_ALLOW_V4L1=y +CONFIG_VIDEO_AU0828=m +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BTCX=m +CONFIG_VIDEO_BWQCAM=m +CONFIG_VIDEO_CAFE_CCIC=m +CONFIG_VIDEO_CAPTURE_DRIVERS=y +CONFIG_VIDEO_CPIA=m +CONFIG_VIDEO_CPIA2=m +CONFIG_VIDEO_CPIA_PP=m +CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CQCAM=m +CONFIG_VIDEO_CS5345=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_CX18=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_CX23885=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_CX88=m +CONFIG_VIDEO_CX88_ALSA=m +CONFIG_VIDEO_CX88_BLACKBIRD=m +CONFIG_VIDEO_CX88_DVB=m +CONFIG_VIDEO_CX88_VP3054=m +CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_EM28XX=m +CONFIG_VIDEO_EM28XX_ALSA=m +CONFIG_VIDEO_EM28XX_DVB=m +CONFIG_VIDEO_FB_IVTV=m +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_IR_I2C=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_M52790=m +CONFIG_VIDEO_MEDIA=m +CONFIG_VIDEO_MEYE=m +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_MXB=m +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_VIDEO_PVRUSB2=m +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_PVRUSB2_DVB=y +CONFIG_VIDEO_PVRUSB2_SYSFS=y +CONFIG_VIDEO_SAA5246A=m +CONFIG_VIDEO_SAA5249=m +CONFIG_VIDEO_SAA6588=m +CONFIG_VIDEO_SAA7110=m +CONFIG_VIDEO_SAA7111=m +CONFIG_VIDEO_SAA7114=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_SAA7134=m +CONFIG_VIDEO_SAA7134_ALSA=m +CONFIG_VIDEO_SAA7134_DVB=m +CONFIG_VIDEO_SAA7146=m +CONFIG_VIDEO_SAA7146_VV=m +CONFIG_VIDEO_SAA717X=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_SH_MOBILE_CEU=m +CONFIG_VIDEO_STRADIS=m +CONFIG_VIDEO_TDA7432=m +CONFIG_VIDEO_TDA9840=m +CONFIG_VIDEO_TDA9875=m +CONFIG_VIDEO_TEA6415C=m +CONFIG_VIDEO_TEA6420=m +CONFIG_VIDEO_TUNER=m +CONFIG_VIDEO_TVAUDIO=m +CONFIG_VIDEO_TVEEPROM=m +CONFIG_VIDEO_TVP5150=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_VIDEO_USBVISION=m +CONFIG_VIDEO_V4L1=m +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=m +CONFIG_VIDEO_V4L2_COMMON=m +CONFIG_VIDEO_VIVI=m +CONFIG_VIDEO_VP27SMPX=m +CONFIG_VIDEO_VPX3220=m +CONFIG_VIDEO_W9966=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_ZORAN=m +CONFIG_VIDEO_ZORAN_AVS6EYES=m +CONFIG_VIDEO_ZORAN_BUZ=m +CONFIG_VIDEO_ZORAN_DC10=m +CONFIG_VIDEO_ZORAN_DC30=m +CONFIG_VIDEO_ZORAN_LML33=m +CONFIG_VIDEO_ZORAN_LML33R10=m +CONFIG_VIDEO_ZORAN_ZR36060=m +CONFIG_VIRTIO=m +CONFIG_VIRTIO_BALLOON=m +CONFIG_VIRTIO_BLK=m +CONFIG_VIRTIO_CONSOLE=m +CONFIG_VIRTIO_NET=m +CONFIG_VIRTIO_PCI=m +CONFIG_VIRTIO_RING=m +CONFIG_VIRTUALIZATION=y +CONFIG_VIRT_TO_BUS=y +CONFIG_VITESSE_PHY=m +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_VLSI_FIR=m +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VORTEX=m +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_VXFS_FS=m +CONFIG_W1=m +CONFIG_W1_CON=y +CONFIG_W1_MASTER_DS2482=m +CONFIG_W1_MASTER_DS2490=m +CONFIG_W1_MASTER_GPIO=m +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_SLAVE_BQ27000=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +# CONFIG_W1_SLAVE_DS2438 is not set +CONFIG_W1_SLAVE_DS2760=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_THERM=m +CONFIG_W83627HF_WDT=m +CONFIG_W83697HF_WDT=m +CONFIG_W83697UG_WDT=m +CONFIG_W83877F_WDT=m +CONFIG_W83977F_WDT=m +CONFIG_WAFER_WDT=m +CONFIG_WAN=y +CONFIG_WANXL=m +CONFIG_WAN_ROUTER=m +CONFIG_WAN_ROUTER_DRIVERS=m +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set +CONFIG_WDTPCI=m +CONFIG_WDT_501_PCI=y +CONFIG_WINBOND_840=m +CONFIG_WINBOND_FIR=m +CONFIG_WIRELESS=y +CONFIG_WIRELESS_ACX=m +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +# CONFIG_WIRELESS_OLD_REGULATORY is not set +CONFIG_WLAN_80211=y +CONFIG_WLAN_PRE80211=y +CONFIG_X25=m +CONFIG_X25_ASY=m +CONFIG_X86=y +# CONFIG_X86_32 is not set +CONFIG_X86_64=y +CONFIG_X86_64_SMP=y +CONFIG_X86_ACPI_CPUFREQ=y +# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set +CONFIG_X86_BIOS_REBOOT=y +CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y +CONFIG_X86_CHECK_BIOS_CORRUPTION=y +CONFIG_X86_CMOV=y +CONFIG_X86_CMPXCHG=y +CONFIG_X86_CMPXCHG64=y +CONFIG_X86_CPU=y +CONFIG_X86_CPUID=m +CONFIG_X86_DEBUGCTLMSR=y +# CONFIG_X86_DS is not set +# CONFIG_X86_ELAN is not set +CONFIG_X86_FIND_SMP_CONFIG=y +# CONFIG_X86_GENERICARCH is not set +CONFIG_X86_HT=y +CONFIG_X86_INTERNODE_CACHE_BYTES=128 +CONFIG_X86_IO_APIC=y +CONFIG_X86_L1_CACHE_BYTES=128 +CONFIG_X86_L1_CACHE_SHIFT=7 +CONFIG_X86_LOCAL_APIC=y +# CONFIG_X86_MCE is not set +CONFIG_X86_MINIMUM_CPU_FAMILY=64 +CONFIG_X86_MPPARSE=y +CONFIG_X86_MSR=m +CONFIG_X86_P4_CLOCKMOD=m +# CONFIG_X86_PAT is not set +CONFIG_X86_PC=y +CONFIG_X86_PM_TIMER=y +CONFIG_X86_POWERNOW_K8=y +CONFIG_X86_POWERNOW_K8_ACPI=y +# CONFIG_X86_PTDUMP is not set +CONFIG_X86_RESERVE_LOW_64K=y +CONFIG_X86_SMP=y +CONFIG_X86_SPEEDSTEP_CENTRINO=y +CONFIG_X86_SPEEDSTEP_LIB=m +CONFIG_X86_TRAMPOLINE=y +CONFIG_X86_TSC=y +# CONFIG_X86_VERBOSE_BOOTUP is not set +# CONFIG_X86_VOYAGER is not set +# CONFIG_X86_VSMP is not set +CONFIG_X86_WP_WORKS_OK=y +CONFIG_XEN=y +CONFIG_XEN_BALLOON=y +CONFIG_XEN_BLKDEV_FRONTEND=m +# CONFIG_XEN_DEBUG_FS is not set +CONFIG_XEN_FBDEV_FRONTEND=m +CONFIG_XEN_KBDDEV_FRONTEND=m +CONFIG_XEN_MAX_DOMAIN_MEMORY=32 +CONFIG_XEN_NETDEV_FRONTEND=m +CONFIG_XEN_SAVE_RESTORE=y +CONFIG_XEN_SCRUB_PAGES=y +CONFIG_XFRM=y +CONFIG_XFRM_IPCOMP=m +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_XFRM_USER=m +# CONFIG_XFS_DEBUG is not set +CONFIG_XFS_FS=m +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_QUOTA=y +CONFIG_XFS_RT=y +CONFIG_XOR_BLOCKS=m +CONFIG_YAM=m +CONFIG_YELLOWFIN=m +CONFIG_YENTA=m +CONFIG_YENTA_ENE_TUNE=y +CONFIG_YENTA_O2=y +CONFIG_YENTA_RICOH=y +CONFIG_YENTA_TI=y +CONFIG_YENTA_TOSHIBA=y +CONFIG_ZD1211RW=m +# CONFIG_ZD1211RW_DEBUG is not set +CONFIG_ZEROPLUS_FF=m +CONFIG_ZISOFS=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZONE_DMA=y +CONFIG_ZONE_DMA32=y +CONFIG_ZONE_DMA_FLAG=1 --- linux-2.6.28.orig/scripts/kernel-doc +++ linux-2.6.28/scripts/kernel-doc @@ -1762,6 +1762,40 @@ $state = 0; } +sub syscall_munge() { + my $void = 0; + + $prototype =~ s@[\r\n\t]+@ @gos; # strip newlines/CR's/tabs +## if ($prototype =~ m/SYSCALL_DEFINE0\s*\(\s*(a-zA-Z0-9_)*\s*\)/) { + if ($prototype =~ m/SYSCALL_DEFINE0/) { + $void = 1; +## $prototype = "long sys_$1(void)"; + } + + $prototype =~ s/SYSCALL_DEFINE.*\(/long sys_/; # fix return type & func name + if ($prototype =~ m/long (sys_.*?),/) { + $prototype =~ s/,/\(/; + } elsif ($void) { + $prototype =~ s/\)/\(void\)/; + } + + # now delete all of the odd-number commas in $prototype + # so that arg types & arg names don't have a comma between them + my $count = 0; + my $len = length($prototype); + if ($void) { + $len = 0; # skip the for-loop + } + for (my $ix = 0; $ix < $len; $ix++) { + if (substr($prototype, $ix, 1) eq ',') { + $count++; + if ($count % 2 == 1) { + substr($prototype, $ix, 1) = ' '; + } + } + } +} + sub process_state3_function($$) { my $x = shift; my $file = shift; @@ -1774,11 +1808,15 @@ elsif ($x =~ /([^\{]*)/) { $prototype .= $1; } + if (($x =~ /\{/) || ($x =~ /\#\s*define/) || ($x =~ /;/)) { $prototype =~ s@/\*.*?\*/@@gos; # strip comments. $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's. $prototype =~ s@^\s+@@gos; # strip leading spaces - dump_function($prototype,$file); + if ($prototype =~ /SYSCALL_DEFINE/) { + syscall_munge(); + } + dump_function($prototype, $file); reset_state(); } } --- linux-2.6.28.orig/scripts/mod/file2alias.c +++ linux-2.6.28/scripts/mod/file2alias.c @@ -210,6 +210,7 @@ static int do_hid_entry(const char *filename, struct hid_device_id *id, char *alias) { + id->bus = TO_NATIVE(id->bus); id->vendor = TO_NATIVE(id->vendor); id->product = TO_NATIVE(id->product); --- linux-2.6.28.orig/net/socket.c +++ linux-2.6.28/net/socket.c @@ -1215,7 +1215,7 @@ return __sock_create(&init_net, family, type, protocol, res, 1); } -asmlinkage long sys_socket(int family, int type, int protocol) +SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol) { int retval; struct socket *sock; @@ -1256,8 +1256,8 @@ * Create a pair of connected sockets. */ -asmlinkage long sys_socketpair(int family, int type, int protocol, - int __user *usockvec) +SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol, + int __user *, usockvec) { struct socket *sock1, *sock2; int fd1, fd2, err; @@ -1364,7 +1364,7 @@ * the protocol layer (having also checked the address is ok). */ -asmlinkage long sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen) +SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen) { struct socket *sock; struct sockaddr_storage address; @@ -1393,7 +1393,7 @@ * ready for listening. */ -asmlinkage long sys_listen(int fd, int backlog) +SYSCALL_DEFINE2(listen, int, fd, int, backlog) { struct socket *sock; int err, fput_needed; @@ -1426,8 +1426,8 @@ * clean when we restucture accept also. */ -asmlinkage long sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr, - int __user *upeer_addrlen, int flags) +SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr, + int __user *, upeer_addrlen, int, flags) { struct socket *sock, *newsock; struct file *newfile; @@ -1510,8 +1510,8 @@ goto out_put; } -asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, - int __user *upeer_addrlen) +SYSCALL_DEFINE3(accept, int, fd, struct sockaddr __user *, upeer_sockaddr, + int __user *, upeer_addrlen) { return sys_accept4(fd, upeer_sockaddr, upeer_addrlen, 0); } @@ -1528,8 +1528,8 @@ * include the -EINPROGRESS status for such sockets. */ -asmlinkage long sys_connect(int fd, struct sockaddr __user *uservaddr, - int addrlen) +SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr, + int, addrlen) { struct socket *sock; struct sockaddr_storage address; @@ -1560,8 +1560,8 @@ * name to user space. */ -asmlinkage long sys_getsockname(int fd, struct sockaddr __user *usockaddr, - int __user *usockaddr_len) +SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr, + int __user *, usockaddr_len) { struct socket *sock; struct sockaddr_storage address; @@ -1591,8 +1591,8 @@ * name to user space. */ -asmlinkage long sys_getpeername(int fd, struct sockaddr __user *usockaddr, - int __user *usockaddr_len) +SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr, + int __user *, usockaddr_len) { struct socket *sock; struct sockaddr_storage address; @@ -1623,9 +1623,9 @@ * the protocol. */ -asmlinkage long sys_sendto(int fd, void __user *buff, size_t len, - unsigned flags, struct sockaddr __user *addr, - int addr_len) +SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len, + unsigned, flags, struct sockaddr __user *, addr, + int, addr_len) { struct socket *sock; struct sockaddr_storage address; @@ -1668,7 +1668,8 @@ * Send a datagram down a socket. */ -asmlinkage long sys_send(int fd, void __user *buff, size_t len, unsigned flags) +SYSCALL_DEFINE4(send, int, fd, void __user *, buff, size_t, len, + unsigned, flags) { return sys_sendto(fd, buff, len, flags, NULL, 0); } @@ -1679,9 +1680,9 @@ * sender address from kernel to user space. */ -asmlinkage long sys_recvfrom(int fd, void __user *ubuf, size_t size, - unsigned flags, struct sockaddr __user *addr, - int __user *addr_len) +SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size, + unsigned, flags, struct sockaddr __user *, addr, + int __user *, addr_len) { struct socket *sock; struct iovec iov; @@ -1733,8 +1734,8 @@ * to pass the user mode parameter for the protocols to sort out. */ -asmlinkage long sys_setsockopt(int fd, int level, int optname, - char __user *optval, int optlen) +SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname, + char __user *, optval, int, optlen) { int err, fput_needed; struct socket *sock; @@ -1767,8 +1768,8 @@ * to pass a user mode parameter for the protocols to sort out. */ -asmlinkage long sys_getsockopt(int fd, int level, int optname, - char __user *optval, int __user *optlen) +SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname, + char __user *, optval, int __user *, optlen) { int err, fput_needed; struct socket *sock; @@ -1797,7 +1798,7 @@ * Shutdown a socket. */ -asmlinkage long sys_shutdown(int fd, int how) +SYSCALL_DEFINE2(shutdown, int, fd, int, how) { int err, fput_needed; struct socket *sock; @@ -1823,7 +1824,7 @@ * BSD sendmsg interface */ -asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags) +SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags) { struct compat_msghdr __user *msg_compat = (struct compat_msghdr __user *)msg; @@ -1929,8 +1930,8 @@ * BSD recvmsg interface */ -asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, - unsigned int flags) +SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg, + unsigned int, flags) { struct compat_msghdr __user *msg_compat = (struct compat_msghdr __user *)msg; @@ -2053,7 +2054,7 @@ * it is set by the callees. */ -asmlinkage long sys_socketcall(int call, unsigned long __user *args) +SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) { unsigned long a[6]; unsigned long a0, a1; --- linux-2.6.28.orig/net/mac80211/tx.c +++ linux-2.6.28/net/mac80211/tx.c @@ -1299,8 +1299,10 @@ if (is_multicast_ether_addr(hdr->addr3)) memcpy(hdr->addr1, hdr->addr3, ETH_ALEN); else - if (mesh_nexthop_lookup(skb, osdata)) - return 0; + if (mesh_nexthop_lookup(skb, osdata)) { + dev_put(odev); + return 0; + } if (memcmp(odev->dev_addr, hdr->addr4, ETH_ALEN) != 0) IEEE80211_IFSTA_MESH_CTR_INC(&osdata->u.mesh, fwded_frames); @@ -1333,6 +1335,8 @@ list) { if (!netif_running(sdata->dev)) continue; + if (sdata->vif.type != NL80211_IFTYPE_AP) + continue; if (compare_ether_addr(sdata->dev->dev_addr, hdr->addr2)) { dev_hold(sdata->dev); --- linux-2.6.28.orig/net/mac80211/rc80211_minstrel.c +++ linux-2.6.28/net/mac80211/rc80211_minstrel.c @@ -389,13 +389,15 @@ { struct minstrel_sta_info *mi = priv_sta; struct minstrel_priv *mp = priv; - struct minstrel_rate *mr_ctl; + struct ieee80211_local *local = hw_to_local(mp->hw); + struct ieee80211_rate *ctl_rate; unsigned int i, n = 0; unsigned int t_slot = 9; /* FIXME: get real slot time */ mi->lowest_rix = rate_lowest_index(sband, sta); - mr_ctl = &mi->r[rix_to_ndx(mi, mi->lowest_rix)]; - mi->sp_ack_dur = mr_ctl->ack_time; + ctl_rate = &sband->bitrates[mi->lowest_rix]; + mi->sp_ack_dur = ieee80211_frame_duration(local, 10, ctl_rate->bitrate, + !!(ctl_rate->flags & IEEE80211_RATE_ERP_G), 1); for (i = 0; i < sband->n_bitrates; i++) { struct minstrel_rate *mr = &mi->r[n]; @@ -410,7 +412,7 @@ mr->rix = i; mr->bitrate = sband->bitrates[i].bitrate / 5; - calc_rate_durations(mi, hw_to_local(mp->hw), mr, + calc_rate_durations(mi, local, mr, &sband->bitrates[i]); /* calculate maximum number of retransmissions before --- linux-2.6.28.orig/net/mac80211/debugfs_netdev.c +++ linux-2.6.28/net/mac80211/debugfs_netdev.c @@ -531,6 +531,7 @@ { struct net_device *dev = ndev; struct dentry *dir; + struct ieee80211_local *local; struct ieee80211_sub_if_data *sdata; char buf[10+IFNAMSIZ]; @@ -543,7 +544,12 @@ if (dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid) return 0; - sdata = IEEE80211_DEV_TO_SUB_IF(dev); + /* + * Do not use IEEE80211_DEV_TO_SUB_IF because that + * BUG_ONs for the master netdev which we need to + * handle here. + */ + sdata = netdev_priv(dev); dir = sdata->debugfsdir; --- linux-2.6.28.orig/net/bridge/br.c +++ linux-2.6.28/net/bridge/br.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -108,3 +109,4 @@ module_exit(br_deinit) MODULE_LICENSE("GPL"); MODULE_VERSION(BR_VERSION); +MODULE_ALIAS_NETPROTO(PF_BRIDGE); --- linux-2.6.28.orig/net/bridge/netfilter/ebtables.c +++ linux-2.6.28/net/bridge/netfilter/ebtables.c @@ -80,7 +80,7 @@ { par->match = m->u.match; par->matchinfo = m->data; - return m->u.match->match(skb, par); + return m->u.match->match(skb, par) ? EBT_MATCH : EBT_NOMATCH; } static inline int ebt_dev_check(char *entry, const struct net_device *device) --- linux-2.6.28.orig/net/wanrouter/wanmain.c +++ linux-2.6.28/net/wanrouter/wanmain.c @@ -791,6 +791,7 @@ EXPORT_SYMBOL(unregister_wan_device); MODULE_LICENSE("GPL"); +MODULE_ALIAS_NETPROTO(PF_WANPIPE); /* * End --- linux-2.6.28.orig/net/ipv4/udp.c +++ linux-2.6.28/net/ipv4/udp.c @@ -942,9 +942,11 @@ if ((rc = sock_queue_rcv_skb(sk, skb)) < 0) { /* Note that an ENOMEM error is charged twice */ - if (rc == -ENOMEM) + if (rc == -ENOMEM) { UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_RCVBUFERRORS, is_udplite); + atomic_inc(&sk->sk_drops); + } goto drop; } @@ -1155,7 +1157,7 @@ int proto) { struct sock *sk; - struct udphdr *uh = udp_hdr(skb); + struct udphdr *uh; unsigned short ulen; struct rtable *rt = (struct rtable*)skb->dst; __be32 saddr = ip_hdr(skb)->saddr; @@ -1168,6 +1170,7 @@ if (!pskb_may_pull(skb, sizeof(struct udphdr))) goto drop; /* No space for header. */ + uh = udp_hdr(skb); ulen = ntohs(uh->len); if (ulen > skb->len) goto short_packet; --- linux-2.6.28.orig/net/ipv4/ipconfig.c +++ linux-2.6.28/net/ipv4/ipconfig.c @@ -1272,6 +1272,9 @@ static int __init ip_auto_config(void) { __be32 addr; +#ifdef IPCONFIG_DYNAMIC + int retries = CONF_OPEN_RETRIES; +#endif #ifdef CONFIG_PROC_FS proc_net_fops_create(&init_net, "pnp", S_IRUGO, &pnp_seq_fops); @@ -1308,9 +1311,6 @@ #endif ic_first_dev->next) { #ifdef IPCONFIG_DYNAMIC - - int retries = CONF_OPEN_RETRIES; - if (ic_dynamic() < 0) { ic_close_devs(); --- linux-2.6.28.orig/net/ipv4/tcp.c +++ linux-2.6.28/net/ipv4/tcp.c @@ -520,8 +520,13 @@ unsigned int offset, size_t len) { struct tcp_splice_state *tss = rd_desc->arg.data; + int ret; - return skb_splice_bits(skb, offset, tss->pipe, tss->len, tss->flags); + ret = skb_splice_bits(skb, offset, tss->pipe, min(rd_desc->count, len), + tss->flags); + if (ret > 0) + rd_desc->count -= ret; + return ret; } static int __tcp_splice_read(struct sock *sk, struct tcp_splice_state *tss) @@ -529,6 +534,7 @@ /* Store TCP splice context information in read_descriptor_t. */ read_descriptor_t rd_desc = { .arg.data = tss, + .count = tss->len, }; return tcp_read_sock(sk, &rd_desc, tcp_splice_data_recv); @@ -578,10 +584,6 @@ else if (!ret) { if (spliced) break; - if (flags & SPLICE_F_NONBLOCK) { - ret = -EAGAIN; - break; - } if (sock_flag(sk, SOCK_DONE)) break; if (sk->sk_err) { @@ -599,6 +601,10 @@ ret = -ENOTCONN; break; } + if (flags & SPLICE_F_NONBLOCK) { + ret = -EAGAIN; + break; + } if (!timeo) { ret = -EAGAIN; break; @@ -613,11 +619,13 @@ tss.len -= ret; spliced += ret; + if (!timeo) + break; release_sock(sk); lock_sock(sk); if (sk->sk_err || sk->sk_state == TCP_CLOSE || - (sk->sk_shutdown & RCV_SHUTDOWN) || !timeo || + (sk->sk_shutdown & RCV_SHUTDOWN) || signal_pending(current)) break; } --- linux-2.6.28.orig/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ linux-2.6.28/net/ipv4/netfilter/nf_conntrack_proto_icmp.c @@ -20,7 +20,7 @@ #include #include -static unsigned long nf_ct_icmp_timeout __read_mostly = 30*HZ; +static unsigned int nf_ct_icmp_timeout __read_mostly = 30*HZ; static bool icmp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, struct nf_conntrack_tuple *tuple) --- linux-2.6.28.orig/net/ipv4/netfilter/ip_queue.c +++ linux-2.6.28/net/ipv4/netfilter/ip_queue.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -640,6 +641,7 @@ MODULE_DESCRIPTION("IPv4 packet queue handler"); MODULE_AUTHOR("James Morris "); MODULE_LICENSE("GPL"); +MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_FIREWALL); module_init(ip_queue_init); module_exit(ip_queue_fini); --- linux-2.6.28.orig/net/core/skbuff.c +++ linux-2.6.28/net/core/skbuff.c @@ -73,17 +73,13 @@ static void sock_pipe_buf_release(struct pipe_inode_info *pipe, struct pipe_buffer *buf) { - struct sk_buff *skb = (struct sk_buff *) buf->private; - - kfree_skb(skb); + put_page(buf->page); } static void sock_pipe_buf_get(struct pipe_inode_info *pipe, struct pipe_buffer *buf) { - struct sk_buff *skb = (struct sk_buff *) buf->private; - - skb_get(skb); + get_page(buf->page); } static int sock_pipe_buf_steal(struct pipe_inode_info *pipe, @@ -147,14 +143,6 @@ BUG(); } -void skb_truesize_bug(struct sk_buff *skb) -{ - WARN(net_ratelimit(), KERN_ERR "SKB BUG: Invalid truesize (%u) " - "len=%u, sizeof(sk_buff)=%Zd\n", - skb->truesize, skb->len, sizeof(struct sk_buff)); -} -EXPORT_SYMBOL(skb_truesize_bug); - /* Allocate a new skbuff. We do this ourselves so we can fill in a few * 'private' fields and also do memory statistics to find all the * [BEEP] leaks. @@ -1333,9 +1321,19 @@ */ static void sock_spd_release(struct splice_pipe_desc *spd, unsigned int i) { - struct sk_buff *skb = (struct sk_buff *) spd->partial[i].private; + put_page(spd->pages[i]); +} - kfree_skb(skb); +static inline struct page *linear_to_page(struct page *page, unsigned int len, + unsigned int offset) +{ + struct page *p = alloc_pages(GFP_KERNEL, 0); + + if (!p) + return NULL; + memcpy(page_address(p) + offset, page_address(page) + offset, len); + + return p; } /* @@ -1343,16 +1341,23 @@ */ static inline int spd_fill_page(struct splice_pipe_desc *spd, struct page *page, unsigned int len, unsigned int offset, - struct sk_buff *skb) + struct sk_buff *skb, int linear) { if (unlikely(spd->nr_pages == PIPE_BUFFERS)) return 1; + if (linear) { + page = linear_to_page(page, len, offset); + if (!page) + return 1; + } else + get_page(page); + spd->pages[spd->nr_pages] = page; spd->partial[spd->nr_pages].len = len; spd->partial[spd->nr_pages].offset = offset; - spd->partial[spd->nr_pages].private = (unsigned long) skb_get(skb); spd->nr_pages++; + return 0; } @@ -1368,7 +1373,7 @@ static inline int __splice_segment(struct page *page, unsigned int poff, unsigned int plen, unsigned int *off, unsigned int *len, struct sk_buff *skb, - struct splice_pipe_desc *spd) + struct splice_pipe_desc *spd, int linear) { if (!*len) return 1; @@ -1391,7 +1396,7 @@ /* the linear region may spread across several pages */ flen = min_t(unsigned int, flen, PAGE_SIZE - poff); - if (spd_fill_page(spd, page, flen, poff, skb)) + if (spd_fill_page(spd, page, flen, poff, skb, linear)) return 1; __segment_seek(&page, &poff, &plen, flen); @@ -1418,7 +1423,7 @@ if (__splice_segment(virt_to_page(skb->data), (unsigned long) skb->data & (PAGE_SIZE - 1), skb_headlen(skb), - offset, len, skb, spd)) + offset, len, skb, spd, 1)) return 1; /* @@ -1428,7 +1433,7 @@ const skb_frag_t *f = &skb_shinfo(skb)->frags[seg]; if (__splice_segment(f->page, f->page_offset, f->size, - offset, len, skb, spd)) + offset, len, skb, spd, 0)) return 1; } @@ -1441,7 +1446,7 @@ * the frag list, if such a thing exists. We'd probably need to recurse to * handle that cleanly. */ -int skb_splice_bits(struct sk_buff *__skb, unsigned int offset, +int skb_splice_bits(struct sk_buff *skb, unsigned int offset, struct pipe_inode_info *pipe, unsigned int tlen, unsigned int flags) { @@ -1454,16 +1459,6 @@ .ops = &sock_pipe_buf_ops, .spd_release = sock_spd_release, }; - struct sk_buff *skb; - - /* - * I'd love to avoid the clone here, but tcp_read_sock() - * ignores reference counts and unconditonally kills the sk_buff - * on return from the actor. - */ - skb = skb_clone(__skb, GFP_KERNEL); - if (unlikely(!skb)) - return -ENOMEM; /* * __skb_splice_bits() only fails if the output has no room left, @@ -1487,15 +1482,9 @@ } done: - /* - * drop our reference to the clone, the pipe consumption will - * drop the rest. - */ - kfree_skb(skb); - if (spd.nr_pages) { + struct sock *sk = skb->sk; int ret; - struct sock *sk = __skb->sk; /* * Drop the socket lock, otherwise we have reverse @@ -2072,10 +2061,10 @@ return 0; next_skb: - block_limit = skb_headlen(st->cur_skb); + block_limit = skb_headlen(st->cur_skb) + st->stepped_offset; if (abs_offset < block_limit) { - *data = st->cur_skb->data + abs_offset; + *data = st->cur_skb->data + (abs_offset - st->stepped_offset); return block_limit - abs_offset; } @@ -2110,13 +2099,14 @@ st->frag_data = NULL; } - if (st->cur_skb->next) { - st->cur_skb = st->cur_skb->next; + if (st->root_skb == st->cur_skb && + skb_shinfo(st->root_skb)->frag_list) { + st->cur_skb = skb_shinfo(st->root_skb)->frag_list; st->frag_idx = 0; goto next_skb; - } else if (st->root_skb == st->cur_skb && - skb_shinfo(st->root_skb)->frag_list) { - st->cur_skb = skb_shinfo(st->root_skb)->frag_list; + } else if (st->cur_skb->next) { + st->cur_skb = st->cur_skb->next; + st->frag_idx = 0; goto next_skb; } --- linux-2.6.28.orig/net/core/sock.c +++ linux-2.6.28/net/core/sock.c @@ -696,6 +696,8 @@ if (len < 0) return -EINVAL; + memset(&v, 0, sizeof(v)); + switch(optname) { case SO_DEBUG: v.val = sock_flag(sk, SOCK_DBG); @@ -1135,7 +1137,6 @@ { struct sock *sk = skb->sk; - skb_truesize_check(skb); atomic_sub(skb->truesize, &sk->sk_rmem_alloc); sk_mem_uncharge(skb->sk, skb->truesize); } --- linux-2.6.28.orig/net/core/net_namespace.c +++ linux-2.6.28/net/core/net_namespace.c @@ -342,8 +342,8 @@ rv = register_pernet_operations(first_device, ops); if (rv < 0) ida_remove(&net_generic_ids, *id); - mutex_unlock(&net_mutex); out: + mutex_unlock(&net_mutex); return rv; } EXPORT_SYMBOL_GPL(register_pernet_gen_subsys); --- linux-2.6.28.orig/net/packet/af_packet.c +++ linux-2.6.28/net/packet/af_packet.c @@ -77,6 +77,7 @@ #include #include #include +#include #ifdef CONFIG_INET #include @@ -175,6 +176,7 @@ #endif struct packet_type prot_hook; spinlock_t bind_lock; + struct mutex pg_vec_lock; unsigned int running:1, /* prot_hook is attached*/ auxdata:1, origdev:1; @@ -220,13 +222,13 @@ h.raw = po->pg_vec[pg_vec_pos] + (frame_offset * po->frame_size); switch (po->tp_version) { case TPACKET_V1: - if (status != h.h1->tp_status ? TP_STATUS_USER : - TP_STATUS_KERNEL) + if (status != (h.h1->tp_status ? TP_STATUS_USER : + TP_STATUS_KERNEL)) return NULL; break; case TPACKET_V2: - if (status != h.h2->tp_status ? TP_STATUS_USER : - TP_STATUS_KERNEL) + if (status != (h.h2->tp_status ? TP_STATUS_USER : + TP_STATUS_KERNEL)) return NULL; break; } @@ -1068,6 +1070,7 @@ */ spin_lock_init(&po->bind_lock); + mutex_init(&po->pg_vec_lock); po->prot_hook.func = packet_rcv; if (sock->type == SOCK_PACKET) @@ -1863,6 +1866,7 @@ synchronize_net(); err = -EBUSY; + mutex_lock(&po->pg_vec_lock); if (closing || atomic_read(&po->mapped) == 0) { err = 0; #define XC(a, b) ({ __typeof__ ((a)) __t; __t = (a); (a) = (b); __t; }) @@ -1884,6 +1888,7 @@ if (atomic_read(&po->mapped)) printk(KERN_DEBUG "packet_mmap: vma is busy: %d\n", atomic_read(&po->mapped)); } + mutex_unlock(&po->pg_vec_lock); spin_lock(&po->bind_lock); if (was_running && !po->running) { @@ -1916,7 +1921,7 @@ size = vma->vm_end - vma->vm_start; - lock_sock(sk); + mutex_lock(&po->pg_vec_lock); if (po->pg_vec == NULL) goto out; if (size != po->pg_vec_len*po->pg_vec_pages*PAGE_SIZE) @@ -1939,7 +1944,7 @@ err = 0; out: - release_sock(sk); + mutex_unlock(&po->pg_vec_lock); return err; } #endif --- linux-2.6.28.orig/net/netfilter/x_tables.c +++ linux-2.6.28/net/netfilter/x_tables.c @@ -273,6 +273,10 @@ have_rev = 1; } } + + if (af != NFPROTO_UNSPEC && !have_rev) + return match_revfn(NFPROTO_UNSPEC, name, revision, bestp); + return have_rev; } @@ -289,6 +293,10 @@ have_rev = 1; } } + + if (af != NFPROTO_UNSPEC && !have_rev) + return target_revfn(NFPROTO_UNSPEC, name, revision, bestp); + return have_rev; } --- linux-2.6.28.orig/net/netfilter/nf_conntrack_netlink.c +++ linux-2.6.28/net/netfilter/nf_conntrack_netlink.c @@ -825,13 +825,16 @@ if (!parse_nat_setup) { #ifdef CONFIG_MODULES rcu_read_unlock(); + spin_unlock_bh(&nf_conntrack_lock); nfnl_unlock(); if (request_module("nf-nat-ipv4") < 0) { nfnl_lock(); + spin_lock_bh(&nf_conntrack_lock); rcu_read_lock(); return -EOPNOTSUPP; } nfnl_lock(); + spin_lock_bh(&nf_conntrack_lock); rcu_read_lock(); if (nfnetlink_parse_nat_setup_hook) return -EAGAIN; --- linux-2.6.28.orig/net/netfilter/xt_sctp.c +++ linux-2.6.28/net/netfilter/xt_sctp.c @@ -105,7 +105,7 @@ switch (chunk_match_type) { case SCTP_CHUNK_MATCH_ALL: - return SCTP_CHUNKMAP_IS_CLEAR(info->chunkmap); + return SCTP_CHUNKMAP_IS_CLEAR(chunkmapcopy); case SCTP_CHUNK_MATCH_ANY: return false; case SCTP_CHUNK_MATCH_ONLY: --- linux-2.6.28.orig/net/netlink/af_netlink.c +++ linux-2.6.28/net/netlink/af_netlink.c @@ -1992,3 +1992,5 @@ } core_initcall(netlink_proto_init); + +MODULE_ALIAS_NETPROTO(PF_NETLINK); --- linux-2.6.28.orig/net/sched/cls_u32.c +++ linux-2.6.28/net/sched/cls_u32.c @@ -637,8 +637,9 @@ break; n->next = *ins; - wmb(); + tcf_tree_lock(tp); *ins = n; + tcf_tree_unlock(tp); *arg = (unsigned long)n; return 0; --- linux-2.6.28.orig/net/sched/sch_htb.c +++ linux-2.6.28/net/sched/sch_htb.c @@ -924,6 +924,7 @@ } } sch->qstats.overlimits++; + qdisc_watchdog_cancel(&q->watchdog); qdisc_watchdog_schedule(&q->watchdog, next_event); fin: return skb; --- linux-2.6.28.orig/net/sctp/input.c +++ linux-2.6.28/net/sctp/input.c @@ -249,6 +249,19 @@ */ sctp_bh_lock_sock(sk); + if (sk != rcvr->sk) { + /* Our cached sk is different from the rcvr->sk. This is + * because migrate()/accept() may have moved the association + * to a new socket and released all the sockets. So now we + * are holding a lock on the old socket while the user may + * be doing something with the new socket. Switch our veiw + * of the current sk. + */ + sctp_bh_unlock_sock(sk); + sk = rcvr->sk; + sctp_bh_lock_sock(sk); + } + if (sock_owned_by_user(sk)) { SCTP_INC_STATS_BH(SCTP_MIB_IN_PKT_BACKLOG); sctp_add_backlog(sk, skb); --- linux-2.6.28.orig/net/sctp/outqueue.c +++ linux-2.6.28/net/sctp/outqueue.c @@ -929,7 +929,6 @@ } /* Finally, transmit new packets. */ - start_timer = 0; while ((chunk = sctp_outq_dequeue_data(q)) != NULL) { /* RFC 2960 6.5 Every DATA chunk MUST carry a valid * stream identifier. @@ -1028,7 +1027,7 @@ list_add_tail(&chunk->transmitted_list, &transport->transmitted); - sctp_transport_reset_timers(transport, start_timer-1); + sctp_transport_reset_timers(transport, 0); q->empty = 0; --- linux-2.6.28.orig/net/sctp/sm_statefuns.c +++ linux-2.6.28/net/sctp/sm_statefuns.c @@ -3691,6 +3691,7 @@ { struct sctp_chunk *chunk = arg; struct sctp_fwdtsn_hdr *fwdtsn_hdr; + struct sctp_fwdtsn_skip *skip; __u16 len; __u32 tsn; @@ -3720,6 +3721,12 @@ if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0) goto discard_noforce; + /* Silently discard the chunk if stream-id is not valid */ + sctp_walk_fwdtsn(skip, chunk) { + if (ntohs(skip->stream) >= asoc->c.sinit_max_instreams) + goto discard_noforce; + } + sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn)); if (len > sizeof(struct sctp_fwdtsn_hdr)) sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN, @@ -3751,6 +3758,7 @@ { struct sctp_chunk *chunk = arg; struct sctp_fwdtsn_hdr *fwdtsn_hdr; + struct sctp_fwdtsn_skip *skip; __u16 len; __u32 tsn; @@ -3780,6 +3788,12 @@ if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0) goto gen_shutdown; + /* Silently discard the chunk if stream-id is not valid */ + sctp_walk_fwdtsn(skip, chunk) { + if (ntohs(skip->stream) >= asoc->c.sinit_max_instreams) + goto gen_shutdown; + } + sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn)); if (len > sizeof(struct sctp_fwdtsn_hdr)) sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN, --- linux-2.6.28.orig/net/sctp/output.c +++ linux-2.6.28/net/sctp/output.c @@ -324,14 +324,16 @@ switch (chunk->chunk_hdr->type) { case SCTP_CID_DATA: retval = sctp_packet_append_data(packet, chunk); + if (SCTP_XMIT_OK != retval) + goto finish; /* Disallow SACK bundling after DATA. */ packet->has_sack = 1; /* Disallow AUTH bundling after DATA */ packet->has_auth = 1; /* Let it be knows that packet has DATA in it */ packet->has_data = 1; - if (SCTP_XMIT_OK != retval) - goto finish; + /* timestamp the chunk for rtx purposes */ + chunk->sent_at = jiffies; break; case SCTP_CID_COOKIE_ECHO: packet->has_cookie_echo = 1; @@ -470,7 +472,6 @@ } else chunk->resent = 1; - chunk->sent_at = jiffies; has_data = 1; } --- linux-2.6.28.orig/net/unix/af_unix.c +++ linux-2.6.28/net/unix/af_unix.c @@ -829,7 +829,8 @@ err = mnt_want_write(nd.path.mnt); if (err) goto out_mknod_dput; - err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0); + err = vfs_mknod(nd.path.dentry->d_inode, dentry, nd.path.mnt, + mode, 0); mnt_drop_write(nd.path.mnt); if (err) goto out_mknod_dput; --- linux-2.6.28.orig/net/ipv6/ip6_flowlabel.c +++ linux-2.6.28/net/ipv6/ip6_flowlabel.c @@ -323,17 +323,21 @@ fl_create(struct net *net, struct in6_flowlabel_req *freq, char __user *optval, int optlen, int *err_p) { - struct ip6_flowlabel *fl; + struct ip6_flowlabel *fl = NULL; int olen; int addr_type; int err; + olen = optlen - CMSG_ALIGN(sizeof(*freq)); + err = -EINVAL; + if (olen > 64 * 1024) + goto done; + err = -ENOMEM; fl = kzalloc(sizeof(*fl), GFP_KERNEL); if (fl == NULL) goto done; - olen = optlen - CMSG_ALIGN(sizeof(*freq)); if (olen > 0) { struct msghdr msg; struct flowi flowi; --- linux-2.6.28.orig/net/ipv6/ip6_output.c +++ linux-2.6.28/net/ipv6/ip6_output.c @@ -1104,6 +1104,18 @@ return err; } +static inline struct ipv6_opt_hdr *ip6_opt_dup(struct ipv6_opt_hdr *src, + gfp_t gfp) +{ + return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL; +} + +static inline struct ipv6_rt_hdr *ip6_rthdr_dup(struct ipv6_rt_hdr *src, + gfp_t gfp) +{ + return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL; +} + int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), void *from, int length, int transhdrlen, @@ -1129,17 +1141,37 @@ * setup for corking */ if (opt) { - if (np->cork.opt == NULL) { - np->cork.opt = kmalloc(opt->tot_len, - sk->sk_allocation); - if (unlikely(np->cork.opt == NULL)) - return -ENOBUFS; - } else if (np->cork.opt->tot_len < opt->tot_len) { - printk(KERN_DEBUG "ip6_append_data: invalid option length\n"); + if (WARN_ON(np->cork.opt)) return -EINVAL; - } - memcpy(np->cork.opt, opt, opt->tot_len); - inet->cork.flags |= IPCORK_OPT; + + np->cork.opt = kmalloc(opt->tot_len, sk->sk_allocation); + if (unlikely(np->cork.opt == NULL)) + return -ENOBUFS; + + np->cork.opt->tot_len = opt->tot_len; + np->cork.opt->opt_flen = opt->opt_flen; + np->cork.opt->opt_nflen = opt->opt_nflen; + + np->cork.opt->dst0opt = ip6_opt_dup(opt->dst0opt, + sk->sk_allocation); + if (opt->dst0opt && !np->cork.opt->dst0opt) + return -ENOBUFS; + + np->cork.opt->dst1opt = ip6_opt_dup(opt->dst1opt, + sk->sk_allocation); + if (opt->dst1opt && !np->cork.opt->dst1opt) + return -ENOBUFS; + + np->cork.opt->hopopt = ip6_opt_dup(opt->hopopt, + sk->sk_allocation); + if (opt->hopopt && !np->cork.opt->hopopt) + return -ENOBUFS; + + np->cork.opt->srcrt = ip6_rthdr_dup(opt->srcrt, + sk->sk_allocation); + if (opt->srcrt && !np->cork.opt->srcrt) + return -ENOBUFS; + /* need source address above miyazawa*/ } dst_hold(&rt->u.dst); @@ -1166,8 +1198,7 @@ } else { rt = (struct rt6_info *)inet->cork.dst; fl = &inet->cork.fl; - if (inet->cork.flags & IPCORK_OPT) - opt = np->cork.opt; + opt = np->cork.opt; transhdrlen = 0; exthdrlen = 0; mtu = inet->cork.fragsize; @@ -1406,9 +1437,15 @@ static void ip6_cork_release(struct inet_sock *inet, struct ipv6_pinfo *np) { - inet->cork.flags &= ~IPCORK_OPT; - kfree(np->cork.opt); - np->cork.opt = NULL; + if (np->cork.opt) { + kfree(np->cork.opt->dst0opt); + kfree(np->cork.opt->dst1opt); + kfree(np->cork.opt->hopopt); + kfree(np->cork.opt->srcrt); + kfree(np->cork.opt); + np->cork.opt = NULL; + } + if (inet->cork.dst) { dst_release(inet->cork.dst); inet->cork.dst = NULL; --- linux-2.6.28.orig/net/ipv6/ip6_fib.c +++ linux-2.6.28/net/ipv6/ip6_fib.c @@ -298,6 +298,10 @@ struct fib6_walker_t *w = (void*)cb->args[2]; if (w) { + if (cb->args[4]) { + cb->args[4] = 0; + fib6_walker_unlink(w); + } cb->args[2] = 0; kfree(w); } @@ -330,15 +334,12 @@ read_lock_bh(&table->tb6_lock); res = fib6_walk_continue(w); read_unlock_bh(&table->tb6_lock); - if (res != 0) { - if (res < 0) - fib6_walker_unlink(w); - goto end; + if (res <= 0) { + fib6_walker_unlink(w); + cb->args[4] = 0; } - fib6_walker_unlink(w); - cb->args[4] = 0; } -end: + return res; } --- linux-2.6.28.orig/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ linux-2.6.28/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c @@ -26,7 +26,7 @@ #include #include -static unsigned long nf_ct_icmpv6_timeout __read_mostly = 30*HZ; +static unsigned int nf_ct_icmpv6_timeout __read_mostly = 30*HZ; static bool icmpv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, @@ -49,8 +49,8 @@ static const u_int8_t invmap[] = { [ICMPV6_ECHO_REQUEST - 128] = ICMPV6_ECHO_REPLY + 1, [ICMPV6_ECHO_REPLY - 128] = ICMPV6_ECHO_REQUEST + 1, - [ICMPV6_NI_QUERY - 128] = ICMPV6_NI_QUERY + 1, - [ICMPV6_NI_REPLY - 128] = ICMPV6_NI_REPLY +1 + [ICMPV6_NI_QUERY - 128] = ICMPV6_NI_REPLY + 1, + [ICMPV6_NI_REPLY - 128] = ICMPV6_NI_QUERY +1 }; static bool icmpv6_invert_tuple(struct nf_conntrack_tuple *tuple, --- linux-2.6.28.orig/net/ipv6/netfilter/ip6_queue.c +++ linux-2.6.28/net/ipv6/netfilter/ip6_queue.c @@ -643,6 +643,7 @@ MODULE_DESCRIPTION("IPv6 packet queue handler"); MODULE_LICENSE("GPL"); +MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_IP6_FW); module_init(ip6_queue_init); module_exit(ip6_queue_fini); --- linux-2.6.28.orig/net/ieee80211/ieee80211_module.c +++ linux-2.6.28/net/ieee80211/ieee80211_module.c @@ -105,6 +105,21 @@ ieee->networks = NULL; } +void ieee80211_networks_age(struct ieee80211_device *ieee, + unsigned long age_secs) +{ + struct ieee80211_network *network = NULL; + unsigned long flags; + unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC); + + spin_lock_irqsave(&ieee->lock, flags); + list_for_each_entry(network, &ieee->network_list, list) { + network->last_scanned -= age_jiffies; + } + spin_unlock_irqrestore(&ieee->lock, flags); +} +EXPORT_SYMBOL(ieee80211_networks_age); + static void ieee80211_networks_initialize(struct ieee80211_device *ieee) { int i; --- linux-2.6.28.orig/net/ieee80211/ieee80211_rx.c +++ linux-2.6.28/net/ieee80211/ieee80211_rx.c @@ -1647,7 +1647,7 @@ break; if ((oldest == NULL) || - (target->last_scanned < oldest->last_scanned)) + time_before(target->last_scanned, oldest->last_scanned)) oldest = target; } --- linux-2.6.28.orig/net/ieee80211/ieee80211_wx.c +++ linux-2.6.28/net/ieee80211/ieee80211_wx.c @@ -41,6 +41,16 @@ "?", "a", "b", "ab", "g", "ag", "bg", "abg" }; +static inline unsigned int elapsed_jiffies_msecs(unsigned long start) +{ + unsigned long end = jiffies; + + if (end >= start) + return jiffies_to_msecs(end - start); + + return jiffies_to_msecs(end + (MAX_JIFFY_OFFSET - start) + 1); +} + #define MAX_CUSTOM_LEN 64 static char *ieee80211_translate_scan(struct ieee80211_device *ieee, char *start, char *stop, @@ -220,8 +230,8 @@ iwe.cmd = IWEVCUSTOM; p = custom; p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), - " Last beacon: %dms ago", - jiffies_to_msecs(jiffies - network->last_scanned)); + " Last beacon: %ums ago", + elapsed_jiffies_msecs(network->last_scanned)); iwe.u.data.length = p - custom; if (iwe.u.data.length) start = iwe_stream_add_point(info, start, stop, &iwe, custom); @@ -281,15 +291,15 @@ time_after(network->last_scanned + ieee->scan_age, jiffies)) ev = ieee80211_translate_scan(ieee, ev, stop, network, info); - else + else { IEEE80211_DEBUG_SCAN("Not showing network '%s (" - "%s)' due to age (%dms).\n", + "%s)' due to age (%ums).\n", escape_essid(network->ssid, network->ssid_len), print_mac(mac, network->bssid), - jiffies_to_msecs(jiffies - - network-> - last_scanned)); + elapsed_jiffies_msecs( + network->last_scanned)); + } } spin_unlock_irqrestore(&ieee->lock, flags); --- linux-2.6.28.orig/kernel/fork.c +++ linux-2.6.28/kernel/fork.c @@ -894,7 +894,7 @@ clear_freeze_flag(p); } -asmlinkage long sys_set_tid_address(int __user *tidptr) +SYSCALL_DEFINE1(set_tid_address, int __user *, tidptr) { current->clear_child_tid = tidptr; @@ -1176,10 +1176,6 @@ #endif clear_all_latency_tracing(p); - /* Our parent execution domain becomes current domain - These must match for thread signalling to apply */ - p->parent_exec_id = p->self_exec_id; - /* ok, now we should be set up.. */ p->exit_signal = (clone_flags & CLONE_THREAD) ? -1 : (clone_flags & CSIGNAL); p->pdeath_signal = 0; @@ -1217,10 +1213,13 @@ set_task_cpu(p, smp_processor_id()); /* CLONE_PARENT re-uses the old parent */ - if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) + if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) { p->real_parent = current->real_parent; - else + p->parent_exec_id = current->parent_exec_id; + } else { p->real_parent = current; + p->parent_exec_id = current->self_exec_id; + } spin_lock(¤t->sighand->siglock); @@ -1589,7 +1588,7 @@ * constructed. Here we are modifying the current, active, * task_struct. */ -asmlinkage long sys_unshare(unsigned long unshare_flags) +SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags) { int err = 0; struct fs_struct *fs, *new_fs = NULL; --- linux-2.6.28.orig/kernel/wait.c +++ linux-2.6.28/kernel/wait.c @@ -91,6 +91,15 @@ } EXPORT_SYMBOL(prepare_to_wait_exclusive); +/* + * finish_wait - clean up after waiting in a queue + * @q: waitqueue waited on + * @wait: wait descriptor + * + * Sets current thread back to running state and removes + * the wait descriptor from the given waitqueue if still + * queued. + */ void finish_wait(wait_queue_head_t *q, wait_queue_t *wait) { unsigned long flags; @@ -117,6 +126,39 @@ } EXPORT_SYMBOL(finish_wait); +/* + * abort_exclusive_wait - abort exclusive waiting in a queue + * @q: waitqueue waited on + * @wait: wait descriptor + * @state: runstate of the waiter to be woken + * @key: key to identify a wait bit queue or %NULL + * + * Sets current thread back to running state and removes + * the wait descriptor from the given waitqueue if still + * queued. + * + * Wakes up the next waiter if the caller is concurrently + * woken up through the queue. + * + * This prevents waiter starvation where an exclusive waiter + * aborts and is woken up concurrently and noone wakes up + * the next waiter. + */ +void abort_exclusive_wait(wait_queue_head_t *q, wait_queue_t *wait, + unsigned int mode, void *key) +{ + unsigned long flags; + + __set_current_state(TASK_RUNNING); + spin_lock_irqsave(&q->lock, flags); + if (!list_empty(&wait->task_list)) + list_del_init(&wait->task_list); + else if (waitqueue_active(q)) + __wake_up_common(q, mode, 1, 0, key); + spin_unlock_irqrestore(&q->lock, flags); +} +EXPORT_SYMBOL(abort_exclusive_wait); + int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key) { int ret = default_wake_function(wait, mode, sync, key); @@ -177,17 +219,20 @@ __wait_on_bit_lock(wait_queue_head_t *wq, struct wait_bit_queue *q, int (*action)(void *), unsigned mode) { - int ret = 0; - do { + int ret; + prepare_to_wait_exclusive(wq, &q->wait, mode); - if (test_bit(q->key.bit_nr, q->key.flags)) { - if ((ret = (*action)(q->key.flags))) - break; - } + if (!test_bit(q->key.bit_nr, q->key.flags)) + continue; + ret = action(q->key.flags); + if (!ret) + continue; + abort_exclusive_wait(wq, &q->wait, mode, &q->key); + return ret; } while (test_and_set_bit(q->key.bit_nr, q->key.flags)); finish_wait(wq, &q->wait); - return ret; + return 0; } EXPORT_SYMBOL(__wait_on_bit_lock); --- linux-2.6.28.orig/kernel/audit.c +++ linux-2.6.28/kernel/audit.c @@ -1243,8 +1243,7 @@ * will be called a second time. Currently, we assume that a printk * can't format message larger than 1024 bytes, so we don't either. */ -static void audit_log_vformat(struct audit_buffer *ab, const char *fmt, - va_list args) +void audit_log_vformat(struct audit_buffer *ab, const char *fmt, va_list args) { int len, avail; struct sk_buff *skb; @@ -1518,3 +1517,6 @@ EXPORT_SYMBOL(audit_log_end); EXPORT_SYMBOL(audit_log_format); EXPORT_SYMBOL(audit_log); +EXPORT_SYMBOL_GPL(audit_log_vformat); +EXPORT_SYMBOL_GPL(audit_log_untrustedstring); +EXPORT_SYMBOL_GPL(audit_log_d_path); --- linux-2.6.28.orig/kernel/timer.c +++ linux-2.6.28/kernel/timer.c @@ -1144,7 +1144,7 @@ * For backwards compatibility? This can be done in libc so Alpha * and all newer ports shouldn't need it. */ -asmlinkage unsigned long sys_alarm(unsigned int seconds) +SYSCALL_DEFINE1(alarm, unsigned int, seconds) { return alarm_setitimer(seconds); } @@ -1167,7 +1167,7 @@ * * This is SMP safe as current->tgid does not change. */ -asmlinkage long sys_getpid(void) +SYSCALL_DEFINE0(getpid) { return task_tgid_vnr(current); } @@ -1178,7 +1178,7 @@ * value of ->real_parent under rcu_read_lock(), see * release_task()->call_rcu(delayed_put_task_struct). */ -asmlinkage long sys_getppid(void) +SYSCALL_DEFINE0(getppid) { int pid; @@ -1189,25 +1189,25 @@ return pid; } -asmlinkage long sys_getuid(void) +SYSCALL_DEFINE0(getuid) { /* Only we change this so SMP safe */ return current->uid; } -asmlinkage long sys_geteuid(void) +SYSCALL_DEFINE0(geteuid) { /* Only we change this so SMP safe */ return current->euid; } -asmlinkage long sys_getgid(void) +SYSCALL_DEFINE0(getgid) { /* Only we change this so SMP safe */ return current->gid; } -asmlinkage long sys_getegid(void) +SYSCALL_DEFINE0(getegid) { /* Only we change this so SMP safe */ return current->egid; @@ -1323,7 +1323,7 @@ EXPORT_SYMBOL(schedule_timeout_uninterruptible); /* Thread ID - the internal kernel "pid" */ -asmlinkage long sys_gettid(void) +SYSCALL_DEFINE0(gettid) { return task_pid_vnr(current); } @@ -1415,7 +1415,7 @@ return 0; } -asmlinkage long sys_sysinfo(struct sysinfo __user *info) +SYSCALL_DEFINE1(sysinfo, struct sysinfo __user *, info) { struct sysinfo val; --- linux-2.6.28.orig/kernel/futex.c +++ linux-2.6.28/kernel/futex.c @@ -1800,9 +1800,8 @@ * @head: pointer to the list-head * @len: length of the list-head, as userspace expects */ -asmlinkage long -sys_set_robust_list(struct robust_list_head __user *head, - size_t len) +SYSCALL_DEFINE2(set_robust_list, struct robust_list_head __user *, head, + size_t, len) { if (!futex_cmpxchg_enabled) return -ENOSYS; @@ -1823,9 +1822,9 @@ * @head_ptr: pointer to a list-head pointer, the kernel fills it in * @len_ptr: pointer to a length field, the kernel fills in the header size */ -asmlinkage long -sys_get_robust_list(int pid, struct robust_list_head __user * __user *head_ptr, - size_t __user *len_ptr) +SYSCALL_DEFINE3(get_robust_list, int, pid, + struct robust_list_head __user * __user *, head_ptr, + size_t __user *, len_ptr) { struct robust_list_head __user *head; unsigned long ret; @@ -2039,9 +2038,9 @@ } -asmlinkage long sys_futex(u32 __user *uaddr, int op, u32 val, - struct timespec __user *utime, u32 __user *uaddr2, - u32 val3) +SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val, + struct timespec __user *, utime, u32 __user *, uaddr2, + u32, val3) { struct timespec ts; ktime_t t, *tp = NULL; --- linux-2.6.28.orig/kernel/kexec.c +++ linux-2.6.28/kernel/kexec.c @@ -934,9 +934,8 @@ static DEFINE_MUTEX(kexec_mutex); -asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments, - struct kexec_segment __user *segments, - unsigned long flags) +SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments, + struct kexec_segment __user *, segments, unsigned long, flags) { struct kimage **dest_image, *image; int result; --- linux-2.6.28.orig/kernel/sys.c +++ linux-2.6.28/kernel/sys.c @@ -137,7 +137,7 @@ return error; } -asmlinkage long sys_setpriority(int which, int who, int niceval) +SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval) { struct task_struct *g, *p; struct user_struct *user; @@ -201,7 +201,7 @@ * has been offset by 20 (ie it returns 40..1 instead of -20..19) * to stay compatible. */ -asmlinkage long sys_getpriority(int which, int who) +SYSCALL_DEFINE2(getpriority, int, which, int, who) { struct task_struct *g, *p; struct user_struct *user; @@ -347,7 +347,8 @@ * * reboot doesn't sync: do that yourself before calling this. */ -asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user * arg) +SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd, + void __user *, arg) { char buffer[256]; @@ -470,7 +471,7 @@ * SMP: There are not races, the GIDs are checked only by filesystem * operations (as far as semantic preservation is concerned). */ -asmlinkage long sys_setregid(gid_t rgid, gid_t egid) +SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid) { int old_rgid = current->gid; int old_egid = current->egid; @@ -519,7 +520,7 @@ * * SMP: Same implicit races as above. */ -asmlinkage long sys_setgid(gid_t gid) +SYSCALL_DEFINE1(setgid, gid_t, gid) { int old_egid = current->egid; int retval; @@ -589,7 +590,7 @@ * 100% compatible with BSD. A program which uses just setuid() will be * 100% compatible with POSIX with saved IDs. */ -asmlinkage long sys_setreuid(uid_t ruid, uid_t euid) +SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid) { int old_ruid, old_euid, old_suid, new_ruid, new_euid; int retval; @@ -651,7 +652,7 @@ * will allow a root program to temporarily drop privileges and be able to * regain them by swapping the real and effective uid. */ -asmlinkage long sys_setuid(uid_t uid) +SYSCALL_DEFINE1(setuid, uid_t, uid) { int old_euid = current->euid; int old_ruid, old_suid, new_suid; @@ -690,7 +691,7 @@ * This function implements a generic ability to update ruid, euid, * and suid. This allows you to implement the 4.4 compatible seteuid(). */ -asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid) +SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid) { int old_ruid = current->uid; int old_euid = current->euid; @@ -733,7 +734,7 @@ return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_RES); } -asmlinkage long sys_getresuid(uid_t __user *ruid, uid_t __user *euid, uid_t __user *suid) +SYSCALL_DEFINE3(getresuid, uid_t __user *, ruid, uid_t __user *, euid, uid_t __user *, suid) { int retval; @@ -747,7 +748,7 @@ /* * Same as above, but for rgid, egid, sgid. */ -asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid) +SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid) { int retval; @@ -784,7 +785,7 @@ return 0; } -asmlinkage long sys_getresgid(gid_t __user *rgid, gid_t __user *egid, gid_t __user *sgid) +SYSCALL_DEFINE3(getresgid, gid_t __user *, rgid, gid_t __user *, egid, gid_t __user *, sgid) { int retval; @@ -802,7 +803,7 @@ * whatever uid it wants to). It normally shadows "euid", except when * explicitly set by setfsuid() or for access.. */ -asmlinkage long sys_setfsuid(uid_t uid) +SYSCALL_DEFINE1(setfsuid, uid_t, uid) { int old_fsuid; @@ -831,7 +832,7 @@ /* * Samma pÃ¥ svenska.. */ -asmlinkage long sys_setfsgid(gid_t gid) +SYSCALL_DEFINE1(setfsgid, gid_t, gid) { int old_fsgid; @@ -869,7 +870,7 @@ tms->tms_cstime = cputime_to_clock_t(cstime); } -asmlinkage long sys_times(struct tms __user * tbuf) +SYSCALL_DEFINE1(times, struct tms __user *, tbuf) { if (tbuf) { struct tms tmp; @@ -893,7 +894,7 @@ * Auch. Had to add the 'did_exec' flag to conform completely to POSIX. * LBT 04.03.94 */ -asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) +SYSCALL_DEFINE2(setpgid, pid_t, pid, pid_t, pgid) { struct task_struct *p; struct task_struct *group_leader = current->group_leader; @@ -964,7 +965,7 @@ return err; } -asmlinkage long sys_getpgid(pid_t pid) +SYSCALL_DEFINE1(getpgid, pid_t, pid) { struct task_struct *p; struct pid *grp; @@ -994,14 +995,14 @@ #ifdef __ARCH_WANT_SYS_GETPGRP -asmlinkage long sys_getpgrp(void) +SYSCALL_DEFINE0(getpgrp) { return sys_getpgid(0); } #endif -asmlinkage long sys_getsid(pid_t pid) +SYSCALL_DEFINE1(getsid, pid_t, pid) { struct task_struct *p; struct pid *sid; @@ -1029,7 +1030,7 @@ return retval; } -asmlinkage long sys_setsid(void) +SYSCALL_DEFINE0(setsid) { struct task_struct *group_leader = current->group_leader; struct pid *sid = task_pid(group_leader); @@ -1233,7 +1234,7 @@ EXPORT_SYMBOL(set_current_groups); -asmlinkage long sys_getgroups(int gidsetsize, gid_t __user *grouplist) +SYSCALL_DEFINE2(getgroups, int, gidsetsize, gid_t __user *, grouplist) { int i = 0; @@ -1266,7 +1267,7 @@ * without another task interfering. */ -asmlinkage long sys_setgroups(int gidsetsize, gid_t __user *grouplist) +SYSCALL_DEFINE2(setgroups, int, gidsetsize, gid_t __user *, grouplist) { struct group_info *group_info; int retval; @@ -1316,7 +1317,7 @@ DECLARE_RWSEM(uts_sem); -asmlinkage long sys_newuname(struct new_utsname __user * name) +SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name) { int errno = 0; @@ -1327,7 +1328,7 @@ return errno; } -asmlinkage long sys_sethostname(char __user *name, int len) +SYSCALL_DEFINE2(sethostname, char __user *, name, int, len) { int errno; char tmp[__NEW_UTS_LEN]; @@ -1351,7 +1352,7 @@ #ifdef __ARCH_WANT_SYS_GETHOSTNAME -asmlinkage long sys_gethostname(char __user *name, int len) +SYSCALL_DEFINE2(gethostname, char __user *, name, int, len) { int i, errno; struct new_utsname *u; @@ -1376,7 +1377,7 @@ * Only setdomainname; getdomainname can be implemented by calling * uname() */ -asmlinkage long sys_setdomainname(char __user *name, int len) +SYSCALL_DEFINE2(setdomainname, char __user *, name, int, len) { int errno; char tmp[__NEW_UTS_LEN]; @@ -1399,7 +1400,7 @@ return errno; } -asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit __user *rlim) +SYSCALL_DEFINE2(getrlimit, unsigned int, resource, struct rlimit __user *, rlim) { if (resource >= RLIM_NLIMITS) return -EINVAL; @@ -1418,7 +1419,8 @@ * Back compatibility for getrlimit. Needed for some apps. */ -asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit __user *rlim) +SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource, + struct rlimit __user *, rlim) { struct rlimit x; if (resource >= RLIM_NLIMITS) @@ -1436,7 +1438,7 @@ #endif -asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim) +SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim) { struct rlimit new_rlim, *old_rlim; int retval; @@ -1445,22 +1447,14 @@ return -EINVAL; if (copy_from_user(&new_rlim, rlim, sizeof(*rlim))) return -EFAULT; + if (new_rlim.rlim_cur > new_rlim.rlim_max) + return -EINVAL; old_rlim = current->signal->rlim + resource; if ((new_rlim.rlim_max > old_rlim->rlim_max) && !capable(CAP_SYS_RESOURCE)) return -EPERM; - - if (resource == RLIMIT_NOFILE) { - if (new_rlim.rlim_max == RLIM_INFINITY) - new_rlim.rlim_max = sysctl_nr_open; - if (new_rlim.rlim_cur == RLIM_INFINITY) - new_rlim.rlim_cur = sysctl_nr_open; - if (new_rlim.rlim_max > sysctl_nr_open) - return -EPERM; - } - - if (new_rlim.rlim_cur > new_rlim.rlim_max) - return -EINVAL; + if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open) + return -EPERM; retval = security_task_setrlimit(resource, &new_rlim); if (retval) @@ -1551,6 +1545,8 @@ utime = stime = cputime_zero; if (who == RUSAGE_THREAD) { + utime = task_utime(current); + stime = task_stime(current); accumulate_thread_rusage(p, r); goto out; } @@ -1607,7 +1603,7 @@ return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0; } -asmlinkage long sys_getrusage(int who, struct rusage __user *ru) +SYSCALL_DEFINE2(getrusage, int, who, struct rusage __user *, ru) { if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN && who != RUSAGE_THREAD) @@ -1615,14 +1611,14 @@ return getrusage(current, who, ru); } -asmlinkage long sys_umask(int mask) +SYSCALL_DEFINE1(umask, int, mask) { mask = xchg(¤t->fs->umask, mask & S_IRWXUGO); return mask; } -asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3, - unsigned long arg4, unsigned long arg5) +SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, + unsigned long, arg4, unsigned long, arg5) { long error = 0; @@ -1733,8 +1729,8 @@ return error; } -asmlinkage long sys_getcpu(unsigned __user *cpup, unsigned __user *nodep, - struct getcpu_cache __user *unused) +SYSCALL_DEFINE3(getcpu, unsigned __user *, cpup, unsigned __user *, nodep, + struct getcpu_cache __user *, unused) { int err = 0; int cpu = raw_smp_processor_id(); --- linux-2.6.28.orig/kernel/exec_domain.c +++ linux-2.6.28/kernel/exec_domain.c @@ -209,8 +209,7 @@ module_init(proc_execdomains_init); #endif -asmlinkage long -sys_personality(u_long personality) +SYSCALL_DEFINE1(personality, u_long, personality) { u_long old = current->personality; --- linux-2.6.28.orig/kernel/sys_ni.c +++ linux-2.6.28/kernel/sys_ni.c @@ -131,6 +131,7 @@ cond_syscall(sys_io_submit); cond_syscall(sys_io_cancel); cond_syscall(sys_io_getevents); +cond_syscall(sys_syslog); /* arch-specific weak syscall entries */ cond_syscall(sys_pciconfig_read); --- linux-2.6.28.orig/kernel/relay.c +++ linux-2.6.28/kernel/relay.c @@ -663,8 +663,10 @@ mutex_lock(&relay_channels_mutex); /* Is chan already set up? */ - if (unlikely(chan->has_base_filename)) + if (unlikely(chan->has_base_filename)) { + mutex_unlock(&relay_channels_mutex); return -EEXIST; + } chan->has_base_filename = 1; chan->parent = parent; curr_cpu = get_cpu(); --- linux-2.6.28.orig/kernel/time.c +++ linux-2.6.28/kernel/time.c @@ -59,7 +59,7 @@ * why not move it into the appropriate arch directory (for those * architectures that need it). */ -asmlinkage long sys_time(time_t __user * tloc) +SYSCALL_DEFINE1(time, time_t __user *, tloc) { time_t i = get_seconds(); @@ -77,7 +77,7 @@ * architectures that need it). */ -asmlinkage long sys_stime(time_t __user *tptr) +SYSCALL_DEFINE1(stime, time_t __user *, tptr) { struct timespec tv; int err; @@ -97,8 +97,8 @@ #endif /* __ARCH_WANT_SYS_TIME */ -asmlinkage long sys_gettimeofday(struct timeval __user *tv, - struct timezone __user *tz) +SYSCALL_DEFINE2(gettimeofday, struct timeval __user *, tv, + struct timezone __user *, tz) { if (likely(tv != NULL)) { struct timeval ktv; @@ -182,8 +182,8 @@ return 0; } -asmlinkage long sys_settimeofday(struct timeval __user *tv, - struct timezone __user *tz) +SYSCALL_DEFINE2(settimeofday, struct timeval __user *, tv, + struct timezone __user *, tz) { struct timeval user_tv; struct timespec new_ts; @@ -203,7 +203,7 @@ return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL); } -asmlinkage long sys_adjtimex(struct timex __user *txc_p) +SYSCALL_DEFINE1(adjtimex, struct timex __user *, txc_p) { struct timex txc; /* Local copy of parameter */ int ret; --- linux-2.6.28.orig/kernel/exit.c +++ linux-2.6.28/kernel/exit.c @@ -1143,7 +1143,7 @@ EXPORT_SYMBOL(complete_and_exit); -asmlinkage long sys_exit(int error_code) +SYSCALL_DEFINE1(exit, int, error_code) { do_exit((error_code&0xff)<<8); } @@ -1184,9 +1184,11 @@ * wait4()-ing process will get the correct exit code - even if this * thread is not the thread group leader. */ -asmlinkage void sys_exit_group(int error_code) +SYSCALL_DEFINE1(exit_group, int, error_code) { do_group_exit((error_code & 0xff) << 8); + /* NOTREACHED */ + return 0; } static struct pid *task_pid_type(struct task_struct *task, enum pid_type type) @@ -1753,9 +1755,8 @@ return retval; } -asmlinkage long sys_waitid(int which, pid_t upid, - struct siginfo __user *infop, int options, - struct rusage __user *ru) +SYSCALL_DEFINE5(waitid, int, which, pid_t, upid, struct siginfo __user *, + infop, int, options, struct rusage __user *, ru) { struct pid *pid = NULL; enum pid_type type; @@ -1794,8 +1795,8 @@ return ret; } -asmlinkage long sys_wait4(pid_t upid, int __user *stat_addr, - int options, struct rusage __user *ru) +SYSCALL_DEFINE4(wait4, pid_t, upid, int __user *, stat_addr, + int, options, struct rusage __user *, ru) { struct pid *pid = NULL; enum pid_type type; @@ -1832,7 +1833,7 @@ * sys_waitpid() remains for compatibility. waitpid() should be * implemented by calling sys_wait4() from libc.a. */ -asmlinkage long sys_waitpid(pid_t pid, int __user *stat_addr, int options) +SYSCALL_DEFINE3(waitpid, pid_t, pid, int __user *, stat_addr, int, options) { return sys_wait4(pid, stat_addr, options, NULL); } --- linux-2.6.28.orig/kernel/hrtimer.c +++ linux-2.6.28/kernel/hrtimer.c @@ -1628,8 +1628,8 @@ return ret; } -asmlinkage long -sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp) +SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp, + struct timespec __user *, rmtp) { struct timespec tu; --- linux-2.6.28.orig/kernel/sysctl.c +++ linux-2.6.28/kernel/sysctl.c @@ -1528,6 +1528,33 @@ spin_unlock(&sysctl_lock); } +char *sysctl_pathname(struct ctl_table *table, char *buffer, int buflen) +{ + if (buflen < 1) + return NULL; + buffer += --buflen; + *buffer = '\0'; + + while (table) { + int namelen = strlen(table->procname); + + if (buflen < namelen + 1) + return NULL; + buflen -= namelen + 1; + buffer -= namelen; + memcpy(buffer, table->procname, namelen); + *--buffer = '/'; + table = table->parent; + } + if (buflen < 4) + return NULL; + buffer -= 4; + memcpy(buffer, "/sys", 4); + + return buffer; +} +EXPORT_SYMBOL_GPL(sysctl_pathname); + #ifdef CONFIG_SYSCTL_SYSCALL /* Perform the actual read/write of a sysctl table entry. */ static int do_sysctl_strategy(struct ctl_table_root *root, @@ -1623,7 +1650,7 @@ return error; } -asmlinkage long sys_sysctl(struct __sysctl_args __user *args) +SYSCALL_DEFINE1(sysctl, struct __sysctl_args __user *, args) { struct __sysctl_args tmp; int error; @@ -2924,7 +2951,7 @@ #else /* CONFIG_SYSCTL_SYSCALL */ -asmlinkage long sys_sysctl(struct __sysctl_args __user *args) +SYSCALL_DEFINE1(sysctl, struct __sysctl_args __user *, args) { struct __sysctl_args tmp; int error; --- linux-2.6.28.orig/kernel/sched_fair.c +++ linux-2.6.28/kernel/sched_fair.c @@ -283,7 +283,7 @@ struct sched_entity, run_node); - if (vruntime == cfs_rq->min_vruntime) + if (!cfs_rq->curr) vruntime = se->vruntime; else vruntime = min_vruntime(vruntime, se->vruntime); @@ -681,9 +681,13 @@ unsigned long thresh = sysctl_sched_latency; /* - * convert the sleeper threshold into virtual time + * Convert the sleeper threshold into virtual time. + * SCHED_IDLE is a special sub-class. We care about + * fairness only relative to other SCHED_IDLE tasks, + * all of which have the same weight. */ - if (sched_feat(NORMALIZED_SLEEPER)) + if (sched_feat(NORMALIZED_SLEEPER) && + task_of(se)->policy != SCHED_IDLE) thresh = calc_delta_fair(thresh, se); vruntime -= thresh; @@ -1328,14 +1332,18 @@ static void set_last_buddy(struct sched_entity *se) { - for_each_sched_entity(se) - cfs_rq_of(se)->last = se; + if (likely(task_of(se)->policy != SCHED_IDLE)) { + for_each_sched_entity(se) + cfs_rq_of(se)->last = se; + } } static void set_next_buddy(struct sched_entity *se) { - for_each_sched_entity(se) - cfs_rq_of(se)->next = se; + if (likely(task_of(se)->policy != SCHED_IDLE)) { + for_each_sched_entity(se) + cfs_rq_of(se)->next = se; + } } /* @@ -1382,12 +1390,18 @@ return; /* - * Batch tasks do not preempt (their preemption is driven by + * Batch and idle tasks do not preempt (their preemption is driven by * the tick): */ - if (unlikely(p->policy == SCHED_BATCH)) + if (unlikely(p->policy != SCHED_NORMAL)) return; + /* Idle tasks are by definition preempted by everybody. */ + if (unlikely(curr->policy == SCHED_IDLE)) { + resched_task(curr); + return; + } + if (!sched_feat(WAKEUP_PREEMPT)) return; --- linux-2.6.28.orig/kernel/cgroup.c +++ linux-2.6.28/kernel/cgroup.c @@ -2942,7 +2942,11 @@ parent = task_cgroup(tsk, subsys->subsys_id); /* Pin the hierarchy */ - atomic_inc(&parent->root->sb->s_active); + if (!atomic_inc_not_zero(&parent->root->sb->s_active)) { + /* We race with the final deactivate_super() */ + mutex_unlock(&cgroup_mutex); + return 0; + } /* Keep the cgroup alive */ get_css_set(cg); @@ -2964,7 +2968,7 @@ } /* Create the cgroup directory, which also creates the cgroup */ - ret = vfs_mkdir(inode, dentry, S_IFDIR | 0755); + ret = vfs_mkdir(inode, dentry, NULL, S_IFDIR | 0755); child = __d_cgrp(dentry); dput(dentry); if (ret) { --- linux-2.6.28.orig/kernel/module.c +++ linux-2.6.28/kernel/module.c @@ -743,8 +743,8 @@ mutex_lock(&module_mutex); } -asmlinkage long -sys_delete_module(const char __user *name_user, unsigned int flags) +SYSCALL_DEFINE2(delete_module, const char __user *, name_user, + unsigned int, flags) { struct module *mod; char name[MODULE_NAME_LEN]; @@ -2288,10 +2288,8 @@ } /* This is where the real work happens */ -asmlinkage long -sys_init_module(void __user *umod, - unsigned long len, - const char __user *uargs) +SYSCALL_DEFINE3(init_module, void __user *, umod, + unsigned long, len, const char __user *, uargs) { struct module *mod; int ret = 0; --- linux-2.6.28.orig/kernel/ptrace.c +++ linux-2.6.28/kernel/ptrace.c @@ -545,7 +545,7 @@ #define arch_ptrace_attach(child) do { } while (0) #endif -asmlinkage long sys_ptrace(long request, long pid, long addr, long data) +SYSCALL_DEFINE4(ptrace, long, request, long, pid, long, addr, long, data) { struct task_struct *child; long ret; --- linux-2.6.28.orig/kernel/tsacct.c +++ linux-2.6.28/kernel/tsacct.c @@ -120,8 +120,10 @@ if (likely(tsk->mm)) { cputime_t time, dtime; struct timeval value; + unsigned long flags; u64 delta; + local_irq_save(flags); time = tsk->stime + tsk->utime; dtime = cputime_sub(time, tsk->acct_timexpd); jiffies_to_timeval(cputime_to_jiffies(dtime), &value); @@ -129,10 +131,12 @@ delta = delta * USEC_PER_SEC + value.tv_usec; if (delta == 0) - return; + goto out; tsk->acct_timexpd = time; tsk->acct_rss_mem1 += delta * get_mm_rss(tsk->mm); tsk->acct_vm_mem1 += delta * tsk->mm->total_vm; + out: + local_irq_restore(flags); } } --- linux-2.6.28.orig/kernel/itimer.c +++ linux-2.6.28/kernel/itimer.c @@ -100,7 +100,7 @@ return 0; } -asmlinkage long sys_getitimer(int which, struct itimerval __user *value) +SYSCALL_DEFINE2(getitimer, int, which, struct itimerval __user *, value) { int error = -EFAULT; struct itimerval get_buffer; @@ -260,9 +260,8 @@ return it_old.it_value.tv_sec; } -asmlinkage long sys_setitimer(int which, - struct itimerval __user *value, - struct itimerval __user *ovalue) +SYSCALL_DEFINE3(setitimer, int, which, struct itimerval __user *, value, + struct itimerval __user *, ovalue) { struct itimerval set_buffer, get_buffer; int error; --- linux-2.6.28.orig/kernel/seccomp.c +++ linux-2.6.28/kernel/seccomp.c @@ -8,6 +8,7 @@ #include #include +#include /* #define SECCOMP_DEBUG 1 */ #define NR_SECCOMP_MODES 1 @@ -22,7 +23,7 @@ 0, /* null terminated */ }; -#ifdef TIF_32BIT +#ifdef CONFIG_COMPAT static int mode1_syscalls_32[] = { __NR_seccomp_read_32, __NR_seccomp_write_32, __NR_seccomp_exit_32, __NR_seccomp_sigreturn_32, 0, /* null terminated */ @@ -37,8 +38,8 @@ switch (mode) { case 1: syscall = mode1_syscalls; -#ifdef TIF_32BIT - if (test_thread_flag(TIF_32BIT)) +#ifdef CONFIG_COMPAT + if (is_compat_task()) syscall = mode1_syscalls_32; #endif do { --- linux-2.6.28.orig/kernel/acct.c +++ linux-2.6.28/kernel/acct.c @@ -277,7 +277,7 @@ * should be written. If the filename is NULL, accounting will be * shutdown. */ -asmlinkage long sys_acct(const char __user *name) +SYSCALL_DEFINE1(acct, const char __user *, name) { int error; --- linux-2.6.28.orig/kernel/signal.c +++ linux-2.6.28/kernel/signal.c @@ -1940,7 +1940,7 @@ * System call entry points. */ -asmlinkage long sys_restart_syscall(void) +SYSCALL_DEFINE0(restart_syscall) { struct restart_block *restart = ¤t_thread_info()->restart_block; return restart->fn(restart); @@ -1993,8 +1993,8 @@ return error; } -asmlinkage long -sys_rt_sigprocmask(int how, sigset_t __user *set, sigset_t __user *oset, size_t sigsetsize) +SYSCALL_DEFINE4(rt_sigprocmask, int, how, sigset_t __user *, set, + sigset_t __user *, oset, size_t, sigsetsize) { int error = -EINVAL; sigset_t old_set, new_set; @@ -2053,8 +2053,7 @@ return error; } -asmlinkage long -sys_rt_sigpending(sigset_t __user *set, size_t sigsetsize) +SYSCALL_DEFINE2(rt_sigpending, sigset_t __user *, set, size_t, sigsetsize) { return do_sigpending(set, sigsetsize); } @@ -2125,11 +2124,9 @@ #endif -asmlinkage long -sys_rt_sigtimedwait(const sigset_t __user *uthese, - siginfo_t __user *uinfo, - const struct timespec __user *uts, - size_t sigsetsize) +SYSCALL_DEFINE4(rt_sigtimedwait, const sigset_t __user *, uthese, + siginfo_t __user *, uinfo, const struct timespec __user *, uts, + size_t, sigsetsize) { int ret, sig; sigset_t these; @@ -2202,8 +2199,7 @@ return ret; } -asmlinkage long -sys_kill(pid_t pid, int sig) +SYSCALL_DEFINE2(kill, pid_t, pid, int, sig) { struct siginfo info; @@ -2262,7 +2258,7 @@ * exists but it's not belonging to the target process anymore. This * method solves the problem of threads exiting and PIDs getting reused. */ -asmlinkage long sys_tgkill(pid_t tgid, pid_t pid, int sig) +SYSCALL_DEFINE3(tgkill, pid_t, tgid, pid_t, pid, int, sig) { /* This is only valid for single tasks */ if (pid <= 0 || tgid <= 0) @@ -2274,8 +2270,7 @@ /* * Send a signal to only one task, even if it's a CLONE_THREAD task. */ -asmlinkage long -sys_tkill(pid_t pid, int sig) +SYSCALL_DEFINE2(tkill, pid_t, pid, int, sig) { /* This is only valid for single tasks */ if (pid <= 0) @@ -2284,8 +2279,8 @@ return do_tkill(0, pid, sig); } -asmlinkage long -sys_rt_sigqueueinfo(pid_t pid, int sig, siginfo_t __user *uinfo) +SYSCALL_DEFINE3(rt_sigqueueinfo, pid_t, pid, int, sig, + siginfo_t __user *, uinfo) { siginfo_t info; @@ -2413,8 +2408,7 @@ #ifdef __ARCH_WANT_SYS_SIGPENDING -asmlinkage long -sys_sigpending(old_sigset_t __user *set) +SYSCALL_DEFINE1(sigpending, old_sigset_t __user *, set) { return do_sigpending(set, sizeof(*set)); } @@ -2425,8 +2419,8 @@ /* Some platforms have their own version with special arguments others support only sys_rt_sigprocmask. */ -asmlinkage long -sys_sigprocmask(int how, old_sigset_t __user *set, old_sigset_t __user *oset) +SYSCALL_DEFINE3(sigprocmask, int, how, old_sigset_t __user *, set, + old_sigset_t __user *, oset) { int error; old_sigset_t old_set, new_set; @@ -2476,11 +2470,10 @@ #endif /* __ARCH_WANT_SYS_SIGPROCMASK */ #ifdef __ARCH_WANT_SYS_RT_SIGACTION -asmlinkage long -sys_rt_sigaction(int sig, - const struct sigaction __user *act, - struct sigaction __user *oact, - size_t sigsetsize) +SYSCALL_DEFINE4(rt_sigaction, int, sig, + const struct sigaction __user *, act, + struct sigaction __user *, oact, + size_t, sigsetsize) { struct k_sigaction new_sa, old_sa; int ret = -EINVAL; @@ -2510,15 +2503,13 @@ /* * For backwards compatibility. Functionality superseded by sigprocmask. */ -asmlinkage long -sys_sgetmask(void) +SYSCALL_DEFINE0(sgetmask) { /* SMP safe */ return current->blocked.sig[0]; } -asmlinkage long -sys_ssetmask(int newmask) +SYSCALL_DEFINE1(ssetmask, int, newmask) { int old; @@ -2538,8 +2529,7 @@ /* * For backwards compatibility. Functionality superseded by sigaction. */ -asmlinkage unsigned long -sys_signal(int sig, __sighandler_t handler) +SYSCALL_DEFINE2(signal, int, sig, __sighandler_t, handler) { struct k_sigaction new_sa, old_sa; int ret; @@ -2556,8 +2546,7 @@ #ifdef __ARCH_WANT_SYS_PAUSE -asmlinkage long -sys_pause(void) +SYSCALL_DEFINE0(pause) { current->state = TASK_INTERRUPTIBLE; schedule(); @@ -2567,7 +2556,7 @@ #endif #ifdef __ARCH_WANT_SYS_RT_SIGSUSPEND -asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize) +SYSCALL_DEFINE2(rt_sigsuspend, sigset_t __user *, unewset, size_t, sigsetsize) { sigset_t newset; --- linux-2.6.28.orig/kernel/printk.c +++ linux-2.6.28/kernel/printk.c @@ -382,7 +382,7 @@ return error; } -asmlinkage long sys_syslog(int type, char __user *buf, int len) +SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len) { return do_syslog(type, buf, len); } @@ -742,11 +742,6 @@ #else -asmlinkage long sys_syslog(int type, char __user *buf, int len) -{ - return -ENOSYS; -} - static void call_console_drivers(unsigned start, unsigned end) { } --- linux-2.6.28.orig/kernel/posix-timers.c +++ linux-2.6.28/kernel/posix-timers.c @@ -470,10 +470,9 @@ /* Create a POSIX.1b interval timer. */ -asmlinkage long -sys_timer_create(const clockid_t which_clock, - struct sigevent __user *timer_event_spec, - timer_t __user * created_timer_id) +SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock, + struct sigevent __user *, timer_event_spec, + timer_t __user *, created_timer_id) { struct k_itimer *new_timer; int error, new_timer_id; @@ -659,8 +658,8 @@ } /* Get the time remaining on a POSIX.1b interval timer. */ -asmlinkage long -sys_timer_gettime(timer_t timer_id, struct itimerspec __user *setting) +SYSCALL_DEFINE2(timer_gettime, timer_t, timer_id, + struct itimerspec __user *, setting) { struct k_itimer *timr; struct itimerspec cur_setting; @@ -689,8 +688,7 @@ * the call back to do_schedule_next_timer(). So all we need to do is * to pick up the frozen overrun. */ -asmlinkage long -sys_timer_getoverrun(timer_t timer_id) +SYSCALL_DEFINE1(timer_getoverrun, timer_t, timer_id) { struct k_itimer *timr; int overrun; @@ -758,10 +756,9 @@ } /* Set a POSIX.1b interval timer */ -asmlinkage long -sys_timer_settime(timer_t timer_id, int flags, - const struct itimerspec __user *new_setting, - struct itimerspec __user *old_setting) +SYSCALL_DEFINE4(timer_settime, timer_t, timer_id, int, flags, + const struct itimerspec __user *, new_setting, + struct itimerspec __user *, old_setting) { struct k_itimer *timr; struct itimerspec new_spec, old_spec; @@ -814,8 +811,7 @@ } /* Delete a POSIX.1b interval timer. */ -asmlinkage long -sys_timer_delete(timer_t timer_id) +SYSCALL_DEFINE1(timer_delete, timer_t, timer_id) { struct k_itimer *timer; unsigned long flags; @@ -903,8 +899,8 @@ } EXPORT_SYMBOL_GPL(do_posix_clock_nonanosleep); -asmlinkage long sys_clock_settime(const clockid_t which_clock, - const struct timespec __user *tp) +SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, + const struct timespec __user *, tp) { struct timespec new_tp; @@ -916,8 +912,8 @@ return CLOCK_DISPATCH(which_clock, clock_set, (which_clock, &new_tp)); } -asmlinkage long -sys_clock_gettime(const clockid_t which_clock, struct timespec __user *tp) +SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock, + struct timespec __user *,tp) { struct timespec kernel_tp; int error; @@ -933,8 +929,8 @@ } -asmlinkage long -sys_clock_getres(const clockid_t which_clock, struct timespec __user *tp) +SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, + struct timespec __user *, tp) { struct timespec rtn_tp; int error; @@ -963,10 +959,9 @@ which_clock); } -asmlinkage long -sys_clock_nanosleep(const clockid_t which_clock, int flags, - const struct timespec __user *rqtp, - struct timespec __user *rmtp) +SYSCALL_DEFINE4(clock_nanosleep, const clockid_t, which_clock, int, flags, + const struct timespec __user *, rqtp, + struct timespec __user *, rmtp) { struct timespec t; --- linux-2.6.28.orig/kernel/sched.c +++ linux-2.6.28/kernel/sched.c @@ -4586,8 +4586,8 @@ * started to run but is not in state TASK_RUNNING. try_to_wake_up() returns * zero in this (rare) case, and we handle it by continuing to scan the queue. */ -static void __wake_up_common(wait_queue_head_t *q, unsigned int mode, - int nr_exclusive, int sync, void *key) +void __wake_up_common(wait_queue_head_t *q, unsigned int mode, + int nr_exclusive, int sync, void *key) { wait_queue_t *curr, *next; @@ -5025,7 +5025,7 @@ * sys_setpriority is a more generic, but much slower function that * does similar things. */ -asmlinkage long sys_nice(int increment) +SYSCALL_DEFINE1(nice, int, increment) { long nice, retval; @@ -5317,8 +5317,8 @@ * @policy: new policy. * @param: structure containing the new RT priority. */ -asmlinkage long -sys_sched_setscheduler(pid_t pid, int policy, struct sched_param __user *param) +SYSCALL_DEFINE3(sched_setscheduler, pid_t, pid, int, policy, + struct sched_param __user *, param) { /* negative values for policy are not valid */ if (policy < 0) @@ -5332,7 +5332,7 @@ * @pid: the pid in question. * @param: structure containing the new RT priority. */ -asmlinkage long sys_sched_setparam(pid_t pid, struct sched_param __user *param) +SYSCALL_DEFINE2(sched_setparam, pid_t, pid, struct sched_param __user *, param) { return do_sched_setscheduler(pid, -1, param); } @@ -5341,7 +5341,7 @@ * sys_sched_getscheduler - get the policy (scheduling class) of a thread * @pid: the pid in question. */ -asmlinkage long sys_sched_getscheduler(pid_t pid) +SYSCALL_DEFINE1(sched_getscheduler, pid_t, pid) { struct task_struct *p; int retval; @@ -5366,7 +5366,7 @@ * @pid: the pid in question. * @param: structure containing the RT priority. */ -asmlinkage long sys_sched_getparam(pid_t pid, struct sched_param __user *param) +SYSCALL_DEFINE2(sched_getparam, pid_t, pid, struct sched_param __user *, param) { struct sched_param lp; struct task_struct *p; @@ -5474,8 +5474,8 @@ * @len: length in bytes of the bitmask pointed to by user_mask_ptr * @user_mask_ptr: user-space pointer to the new cpu mask */ -asmlinkage long sys_sched_setaffinity(pid_t pid, unsigned int len, - unsigned long __user *user_mask_ptr) +SYSCALL_DEFINE3(sched_setaffinity, pid_t, pid, unsigned int, len, + unsigned long __user *, user_mask_ptr) { cpumask_t new_mask; int retval; @@ -5519,8 +5519,8 @@ * @len: length in bytes of the bitmask pointed to by user_mask_ptr * @user_mask_ptr: user-space pointer to hold the current cpu mask */ -asmlinkage long sys_sched_getaffinity(pid_t pid, unsigned int len, - unsigned long __user *user_mask_ptr) +SYSCALL_DEFINE3(sched_getaffinity, pid_t, pid, unsigned int, len, + unsigned long __user *, user_mask_ptr) { int ret; cpumask_t mask; @@ -5544,7 +5544,7 @@ * This function yields the current CPU to other tasks. If there are no * other threads running on this CPU then this function will return. */ -asmlinkage long sys_sched_yield(void) +SYSCALL_DEFINE0(sched_yield) { struct rq *rq = this_rq_lock(); @@ -5685,7 +5685,7 @@ * this syscall returns the maximum rt_priority that can be used * by a given scheduling class. */ -asmlinkage long sys_sched_get_priority_max(int policy) +SYSCALL_DEFINE1(sched_get_priority_max, int, policy) { int ret = -EINVAL; @@ -5710,7 +5710,7 @@ * this syscall returns the minimum rt_priority that can be used * by a given scheduling class. */ -asmlinkage long sys_sched_get_priority_min(int policy) +SYSCALL_DEFINE1(sched_get_priority_min, int, policy) { int ret = -EINVAL; @@ -5735,8 +5735,8 @@ * this syscall writes the default timeslice value of a given process * into the user-space timespec buffer. A value of '0' means infinity. */ -asmlinkage -long sys_sched_rr_get_interval(pid_t pid, struct timespec __user *interval) +SYSCALL_DEFINE2(sched_rr_get_interval, pid_t, pid, + struct timespec __user *, interval) { struct task_struct *p; unsigned int time_slice; --- linux-2.6.28.orig/kernel/resource.c +++ linux-2.6.28/kernel/resource.c @@ -853,6 +853,15 @@ if (PFN_DOWN(p->start) <= PFN_DOWN(addr) && PFN_DOWN(p->end) >= PFN_DOWN(addr + size - 1)) continue; + /* + * if a resource is "BUSY", it's not a hardware resource + * but a driver mapping of such a resource; we don't want + * to warn for those; some drivers legitimately map only + * partial hardware resources. (example: vesafb) + */ + if (p->flags & IORESOURCE_BUSY) + continue; + printk(KERN_WARNING "resource map sanity check conflict: " "0x%llx 0x%llx 0x%llx 0x%llx %s\n", (unsigned long long)addr, --- linux-2.6.28.orig/kernel/sched_clock.c +++ linux-2.6.28/kernel/sched_clock.c @@ -124,7 +124,7 @@ clock = scd->tick_gtod + delta; min_clock = wrap_max(scd->tick_gtod, scd->clock); - max_clock = scd->tick_gtod + TICK_NSEC; + max_clock = wrap_max(scd->clock, scd->tick_gtod + TICK_NSEC); clock = wrap_max(clock, min_clock); clock = wrap_min(clock, max_clock); @@ -227,6 +227,9 @@ */ void sched_clock_idle_wakeup_event(u64 delta_ns) { + if (timekeeping_suspended) + return; + sched_clock_tick(); touch_softlockup_watchdog(); } --- linux-2.6.28.orig/kernel/uid16.c +++ linux-2.6.28/kernel/uid16.c @@ -17,7 +17,7 @@ #include -asmlinkage long sys_chown16(const char __user * filename, old_uid_t user, old_gid_t group) +SYSCALL_DEFINE3(chown16, const char __user *, filename, old_uid_t, user, old_gid_t, group) { long ret = sys_chown(filename, low2highuid(user), low2highgid(group)); /* avoid REGPARM breakage on x86: */ @@ -25,7 +25,7 @@ return ret; } -asmlinkage long sys_lchown16(const char __user * filename, old_uid_t user, old_gid_t group) +SYSCALL_DEFINE3(lchown16, const char __user *, filename, old_uid_t, user, old_gid_t, group) { long ret = sys_lchown(filename, low2highuid(user), low2highgid(group)); /* avoid REGPARM breakage on x86: */ @@ -33,7 +33,7 @@ return ret; } -asmlinkage long sys_fchown16(unsigned int fd, old_uid_t user, old_gid_t group) +SYSCALL_DEFINE3(fchown16, unsigned int, fd, old_uid_t, user, old_gid_t, group) { long ret = sys_fchown(fd, low2highuid(user), low2highgid(group)); /* avoid REGPARM breakage on x86: */ @@ -41,7 +41,7 @@ return ret; } -asmlinkage long sys_setregid16(old_gid_t rgid, old_gid_t egid) +SYSCALL_DEFINE2(setregid16, old_gid_t, rgid, old_gid_t, egid) { long ret = sys_setregid(low2highgid(rgid), low2highgid(egid)); /* avoid REGPARM breakage on x86: */ @@ -49,7 +49,7 @@ return ret; } -asmlinkage long sys_setgid16(old_gid_t gid) +SYSCALL_DEFINE1(setgid16, old_gid_t, gid) { long ret = sys_setgid(low2highgid(gid)); /* avoid REGPARM breakage on x86: */ @@ -57,7 +57,7 @@ return ret; } -asmlinkage long sys_setreuid16(old_uid_t ruid, old_uid_t euid) +SYSCALL_DEFINE2(setreuid16, old_uid_t, ruid, old_uid_t, euid) { long ret = sys_setreuid(low2highuid(ruid), low2highuid(euid)); /* avoid REGPARM breakage on x86: */ @@ -65,7 +65,7 @@ return ret; } -asmlinkage long sys_setuid16(old_uid_t uid) +SYSCALL_DEFINE1(setuid16, old_uid_t, uid) { long ret = sys_setuid(low2highuid(uid)); /* avoid REGPARM breakage on x86: */ @@ -73,7 +73,7 @@ return ret; } -asmlinkage long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid) +SYSCALL_DEFINE3(setresuid16, old_uid_t, ruid, old_uid_t, euid, old_uid_t, suid) { long ret = sys_setresuid(low2highuid(ruid), low2highuid(euid), low2highuid(suid)); @@ -82,7 +82,7 @@ return ret; } -asmlinkage long sys_getresuid16(old_uid_t __user *ruid, old_uid_t __user *euid, old_uid_t __user *suid) +SYSCALL_DEFINE3(getresuid16, old_uid_t __user *, ruid, old_uid_t __user *, euid, old_uid_t __user *, suid) { int retval; @@ -93,7 +93,7 @@ return retval; } -asmlinkage long sys_setresgid16(old_gid_t rgid, old_gid_t egid, old_gid_t sgid) +SYSCALL_DEFINE3(setresgid16, old_gid_t, rgid, old_gid_t, egid, old_gid_t, sgid) { long ret = sys_setresgid(low2highgid(rgid), low2highgid(egid), low2highgid(sgid)); @@ -102,7 +102,8 @@ return ret; } -asmlinkage long sys_getresgid16(old_gid_t __user *rgid, old_gid_t __user *egid, old_gid_t __user *sgid) + +SYSCALL_DEFINE3(getresgid16, old_gid_t __user *, rgid, old_gid_t __user *, egid, old_gid_t __user *, sgid) { int retval; @@ -113,7 +114,7 @@ return retval; } -asmlinkage long sys_setfsuid16(old_uid_t uid) +SYSCALL_DEFINE1(setfsuid16, old_uid_t, uid) { long ret = sys_setfsuid(low2highuid(uid)); /* avoid REGPARM breakage on x86: */ @@ -121,7 +122,7 @@ return ret; } -asmlinkage long sys_setfsgid16(old_gid_t gid) +SYSCALL_DEFINE1(setfsgid16, old_gid_t, gid) { long ret = sys_setfsgid(low2highgid(gid)); /* avoid REGPARM breakage on x86: */ @@ -159,7 +160,7 @@ return 0; } -asmlinkage long sys_getgroups16(int gidsetsize, old_gid_t __user *grouplist) +SYSCALL_DEFINE2(getgroups16, int, gidsetsize, old_gid_t __user *, grouplist) { int i = 0; @@ -183,7 +184,7 @@ return i; } -asmlinkage long sys_setgroups16(int gidsetsize, old_gid_t __user *grouplist) +SYSCALL_DEFINE2(setgroups16, int, gidsetsize, old_gid_t __user *, grouplist) { struct group_info *group_info; int retval; @@ -208,22 +209,22 @@ return retval; } -asmlinkage long sys_getuid16(void) +SYSCALL_DEFINE0(getuid16) { return high2lowuid(current->uid); } -asmlinkage long sys_geteuid16(void) +SYSCALL_DEFINE0(geteuid16) { return high2lowuid(current->euid); } -asmlinkage long sys_getgid16(void) +SYSCALL_DEFINE0(getgid16) { return high2lowgid(current->gid); } -asmlinkage long sys_getegid16(void) +SYSCALL_DEFINE0(getegid16) { return high2lowgid(current->egid); } --- linux-2.6.28.orig/kernel/capability.c +++ linux-2.6.28/kernel/capability.c @@ -348,7 +348,7 @@ * * Returns 0 on success and < 0 on error. */ -asmlinkage long sys_capget(cap_user_header_t header, cap_user_data_t dataptr) +SYSCALL_DEFINE2(capget, cap_user_header_t, header, cap_user_data_t, dataptr) { int ret = 0; pid_t pid; @@ -425,7 +425,7 @@ * * Returns 0 on success and < 0 on error. */ -asmlinkage long sys_capset(cap_user_header_t header, const cap_user_data_t data) +SYSCALL_DEFINE2(capset, cap_user_header_t, header, const cap_user_data_t, data) { struct __user_cap_data_struct kdata[_KERNEL_CAPABILITY_U32S]; unsigned i, tocopy; --- linux-2.6.28.orig/kernel/time/timekeeping.c +++ linux-2.6.28/kernel/time/timekeeping.c @@ -46,6 +46,9 @@ struct timespec wall_to_monotonic __attribute__ ((aligned (16))); static unsigned long total_sleep_time; /* seconds */ +/* flag for if timekeeping is suspended */ +int __read_mostly timekeeping_suspended; + static struct timespec xtime_cache __attribute__ ((aligned (16))); void update_xtime_cache(u64 nsec) { @@ -92,6 +95,8 @@ unsigned long seq; s64 nsecs; + WARN_ON(timekeeping_suspended); + do { seq = read_seqbegin(&xtime_lock); @@ -299,8 +304,6 @@ write_sequnlock_irqrestore(&xtime_lock, flags); } -/* flag for if timekeeping is suspended */ -static int timekeeping_suspended; /* time in seconds when suspend began */ static unsigned long timekeeping_suspend_time; --- linux-2.6.28.orig/kernel/trace/Kconfig +++ linux-2.6.28/kernel/trace/Kconfig @@ -119,6 +119,15 @@ This tracer gets called from the context switch and records all switching of tasks. +config OPEN_TRACER + bool "Trace open() calls" + depends on DEBUG_KERNEL + select TRACING + select MARKERS + help + This tracer records open() syscalls. These calls are made when + files are accessed on disk. + config BOOT_TRACER bool "Trace boot initcalls" depends on DEBUG_KERNEL --- linux-2.6.28.orig/kernel/trace/ring_buffer.c +++ linux-2.6.28/kernel/trace/ring_buffer.c @@ -769,6 +769,7 @@ * back to us). This allows us to do a simple loop to * assign the commit to the tail. */ + again: while (cpu_buffer->commit_page != cpu_buffer->tail_page) { cpu_buffer->commit_page->commit = cpu_buffer->commit_page->write; @@ -783,6 +784,17 @@ cpu_buffer->commit_page->write; barrier(); } + + /* again, keep gcc from optimizing */ + barrier(); + + /* + * If an interrupt came in just after the first while loop + * and pushed the tail page forward, we will be left with + * a dangling commit that will never go forward. + */ + if (unlikely(cpu_buffer->commit_page != cpu_buffer->tail_page)) + goto again; } static void rb_reset_reader_page(struct ring_buffer_per_cpu *cpu_buffer) @@ -880,12 +892,15 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer, unsigned type, unsigned long length, u64 *ts) { - struct buffer_page *tail_page, *head_page, *reader_page; + struct buffer_page *tail_page, *head_page, *reader_page, *commit_page; unsigned long tail, write; struct ring_buffer *buffer = cpu_buffer->buffer; struct ring_buffer_event *event; unsigned long flags; + commit_page = cpu_buffer->commit_page; + /* we just need to protect against interrupts */ + barrier(); tail_page = cpu_buffer->tail_page; write = local_add_return(length, &tail_page->write); tail = write - length; @@ -909,7 +924,7 @@ * it all the way around the buffer, bail, and warn * about it. */ - if (unlikely(next_page == cpu_buffer->commit_page)) { + if (unlikely(next_page == commit_page)) { WARN_ON_ONCE(1); goto out_unlock; } --- linux-2.6.28.orig/kernel/trace/trace_open.c +++ linux-2.6.28/kernel/trace/trace_open.c @@ -0,0 +1,153 @@ +/* + * trace open calls + * Copyright (C) 2009 Intel Corporation + * + * Based extensively on trace_sched_switch.c + * 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 open_trace_enabled; +static atomic_t open_ref; + +static void probe_do_sys_open(struct file *filp, int flags, int mode, long fd) +{ + char *buf; + char *fname; + + if (!atomic_read(&open_ref)) + return; + + if (!open_trace_enabled) + return; + + buf = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (!buf) + return; + + fname = d_path(&filp->f_path, buf, PAGE_SIZE); + if (IS_ERR(fname)) + goto out; + + ftrace_printk("%s: open(\"%s\", %d, %d) = %ld\n", + current->comm, fname, flags, mode, fd); + +out: + kfree(buf); +} + +static void open_trace_reset(struct trace_array *tr) +{ + int cpu; + + tr->time_start = ftrace_now(tr->cpu); + + for_each_online_cpu(cpu) + tracing_reset(tr, cpu); +} + +static int open_trace_register(void) +{ + int ret; + + ret = register_trace_do_sys_open(probe_do_sys_open); + if (ret) { + pr_info("open trace: Could not activate tracepoint" + " probe to do_open\n"); + } + + return ret; +} + +static void open_trace_unregister(void) +{ + unregister_trace_do_sys_open(probe_do_sys_open); +} + +static void open_trace_start(void) +{ + long ref; + + ref = atomic_inc_return(&open_ref); + if (ref == 1) + open_trace_register(); +} + +static void open_trace_stop(void) +{ + long ref; + + ref = atomic_dec_and_test(&open_ref); + if (ref) + open_trace_unregister(); +} + +void open_trace_start_cmdline_record(void) +{ + open_trace_start(); +} + +void open_trace_stop_cmdline_record(void) +{ + open_trace_stop(); +} + +static void open_start_trace(struct trace_array *tr) +{ + open_trace_reset(tr); + open_trace_start_cmdline_record(); + open_trace_enabled = 1; +} + +static void open_stop_trace(struct trace_array *tr) +{ + open_trace_enabled = 0; + open_trace_stop_cmdline_record(); +} + +static int open_trace_init(struct trace_array *tr) +{ + ctx_trace = tr; + + open_start_trace(tr); + return 0; +} + +static void reset_open_trace(struct trace_array *tr) +{ + open_stop_trace(tr); +} + +static struct tracer open_trace __read_mostly = +{ + .name = "open", + .init = open_trace_init, + .reset = reset_open_trace, +}; + +__init static int init_open_trace(void) +{ + int ret = 0; + + if (atomic_read(&open_ref)) + ret = open_trace_register(); + if (ret) { + pr_info("error registering open trace\n"); + return ret; + } + return register_tracer(&open_trace); +} +device_initcall(init_open_trace); + --- linux-2.6.28.orig/kernel/trace/Makefile +++ linux-2.6.28/kernel/trace/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_TRACING) += trace.o obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o +obj-$(CONFIG_OPEN_TRACER) += trace_open.o obj-$(CONFIG_SYSPROF_TRACER) += trace_sysprof.o obj-$(CONFIG_FUNCTION_TRACER) += trace_functions.o obj-$(CONFIG_IRQSOFF_TRACER) += trace_irqsoff.o --- linux-2.6.28.orig/kernel/trace/trace.h +++ linux-2.6.28/kernel/trace/trace.h @@ -22,6 +22,7 @@ TRACE_MMIO_RW, TRACE_MMIO_MAP, TRACE_BOOT, + TRACE_OPEN, __TRACE_LAST_TYPE }; --- linux-2.6.28.orig/kernel/power/Kconfig +++ linux-2.6.28/kernel/power/Kconfig @@ -116,6 +116,21 @@ Turning OFF this setting is NOT recommended! If in doubt, say Y. +config PM_DISABLE_CONSOLE + bool "Disable Power Management messing with the active console" + depends on PM + default n + ---help--- + By default, PM will take over the active console (generally, this means + switching to the console when suspending from X). This can at times cause + problems, especially if userspace suspend scripts try to do things with + the console before or after suspending (e.g. calling vbestate). + + To work around this, enable this option so that PM will not handle the + console. + + If unsure, say N. + config HIBERNATION bool "Hibernation (aka 'suspend to disk')" depends on PM && SWAP && ARCH_HIBERNATION_POSSIBLE --- linux-2.6.28.orig/kernel/power/console.c +++ linux-2.6.28/kernel/power/console.c @@ -33,6 +33,7 @@ int pm_prepare_console(void) { +#ifndef CONFIG_PM_DISABLE_CONSOLE acquire_console_sem(); if (disable_vt_switch) { @@ -66,11 +67,13 @@ } orig_kmsg = kmsg_redirect; kmsg_redirect = SUSPEND_CONSOLE; +#endif return 0; } void pm_restore_console(void) { +#ifndef CONFIG_PM_DISABLE_CONSOLE acquire_console_sem(); if (disable_vt_switch) { release_console_sem(); @@ -79,5 +82,6 @@ set_console(orig_fgconsole); release_console_sem(); kmsg_redirect = orig_kmsg; +#endif } #endif --- linux-2.6.28.orig/ubuntu/Kconfig +++ linux-2.6.28/ubuntu/Kconfig @@ -0,0 +1,26 @@ +menu "Ubuntu Supplied Third-Party Device Drivers" + +source "ubuntu/drbd/Kconfig" +source "ubuntu/iscsitarget/Kconfig" +source "ubuntu/squashfs/Kconfig" +source "ubuntu/aufs/Kconfig" +source "ubuntu/atl2/Kconfig" +source "ubuntu/et131x/Kconfig" +source "ubuntu/dm-raid4-5/Kconfig" +source "ubuntu/dm-loop/Kconfig" +source "ubuntu/ndiswrapper/Kconfig" +source "ubuntu/compcache/Kconfig" +source "ubuntu/misc/Kconfig" +source "ubuntu/heci/Kconfig" +source "ubuntu/qc-usb/Kconfig" +source "ubuntu/rfkill/Kconfig" +source "ubuntu/unionfs/Kconfig" +source "ubuntu/lirc/Kconfig" +source "ubuntu/gfs/Kconfig" +source "ubuntu/tlsup/Kconfig" +source "drivers/staging/rt2860/Kconfig" +source "drivers/staging/rt2870/Kconfig" +source "drivers/staging/rtl8187se/Kconfig" +source "drivers/staging/at76_usb/Kconfig" + +endmenu --- linux-2.6.28.orig/ubuntu/Makefile +++ linux-2.6.28/ubuntu/Makefile @@ -0,0 +1,27 @@ +# +# Makefile for the Linux kernel ubuntu supplied third-party device drivers. +# + +obj-$(CONFIG_BLK_DEV_DRBD) += drbd/ +obj-$(CONFIG_SCSI_ISCSITARGET) += iscsitarget/ +obj-$(CONFIG_SQUASHFS) += squashfs/ +obj-$(CONFIG_AUFS) += aufs/ +obj-$(CONFIG_ATL2) += atl2/ +obj-$(CONFIG_NET_ET131X) += et131x/ +obj-$(CONFIG_DM_RAID45) += dm-raid4-5/ +obj-$(CONFIG_DM_LOOP) += dm-loop/ +obj-$(CONFIG_NDISWRAPPER) += ndiswrapper/ +obj-$(CONFIG_TLSF) += compcache/ +obj-$(CONFIG_HECI) += heci/ +obj-$(CONFIG_QC_USB) += qc-usb/ +obj-$(CONFIG_FS_UNIONFS) += unionfs/ +obj-$(CONFIG_LIRC_DEV) += lirc/ +obj-$(CONFIG_GFS_FS) += gfs/ +obj-$(CONFIG_TLSUP) += tlsup/ +obj-$(CONFIG_RT2860) += ../drivers/staging/rt2860 +obj-$(CONFIG_RT2870) += ../drivers/staging/rt2870 + +obj-m += misc/ rfkill/ + +# This is a stupid trick to get kbuild to create ubuntu/built-in.o +obj- += foo.o --- linux-2.6.28.orig/ubuntu/drbd/drbd_worker.c +++ linux-2.6.28/ubuntu/drbd/drbd_worker.c @@ -0,0 +1,1514 @@ +/* +-*- linux-c -*- + drbd_worker.c + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2001-2008, LINBIT Information Technologies GmbH. + Copyright (C) 1999-2008, Philipp Reisner . + Copyright (C) 2002-2008, Lars Ellenberg . + + drbd is free software; you can redistribute 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. + + drbd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_LINUX_SCATTERLIST_H +/* 2.6.11 (suse 9.3, fc4) does not include requisites + * from linux/scatterlist.h :( */ +#include +#include +#include +#include +#endif + +#include +#include "drbd_int.h" +#include "drbd_req.h" + +/* defined here: + drbd_md_io_complete + drbd_endio_write_sec + drbd_endio_read_sec + drbd_endio_pri + + * more endio handlers: + atodb_endio in drbd_actlog.c + drbd_bm_async_io_complete in drbd_bitmap.c + + * For all these callbacks, note the follwing: + * The callbacks will be called in irq context by the IDE drivers, + * and in Softirqs/Tasklets/BH context by the SCSI drivers. + * Try to get the locking right :) + * + */ + +/* used for synchronous meta data and bitmap IO + * submitted by drbd_md_sync_page_io() + */ +BIO_ENDIO_TYPE drbd_md_io_complete BIO_ENDIO_ARGS(struct bio *bio, int error) +{ + struct drbd_md_io *md_io; + + BIO_ENDIO_FN_START; + /* error parameter ignored: + * drbd_md_sync_page_io explicitly tests bio_uptodate(bio); */ + + md_io = (struct drbd_md_io *)bio->bi_private; + + md_io->error = error; + + dump_internal_bio("Md", md_io->mdev, bio, 1); + + complete(&md_io->event); + BIO_ENDIO_FN_RETURN; +} + +/* reads on behalf of the partner, + * "submitted" by the receiver + */ +BIO_ENDIO_TYPE drbd_endio_read_sec BIO_ENDIO_ARGS(struct bio *bio, int error) __releases(local) +{ + unsigned long flags = 0; + struct Tl_epoch_entry *e = NULL; + struct drbd_conf *mdev; + int uptodate = bio_flagged(bio, BIO_UPTODATE); + + e = bio->bi_private; + mdev = e->mdev; + + BIO_ENDIO_FN_START; + if (!error && !uptodate) { + /* strange behaviour of some lower level drivers... + * fail the request by clearing the uptodate flag, + * but do not return any error?! + * do we want to drbd_WARN() on this? */ + error = -EIO; + } + + D_ASSERT(e->block_id != ID_VACANT); + + dump_internal_bio("Sec", mdev, bio, 1); + + spin_lock_irqsave(&mdev->req_lock, flags); + mdev->read_cnt += e->size >> 9; + list_del(&e->w.list); + if (list_empty(&mdev->read_ee)) + wake_up(&mdev->ee_wait); + spin_unlock_irqrestore(&mdev->req_lock, flags); + + drbd_chk_io_error(mdev, error, FALSE); + drbd_queue_work(&mdev->data.work, &e->w); + dec_local(mdev); + + MTRACE(TraceTypeEE, TraceLvlAll, + INFO("Moved EE (READ) to worker sec=%llus size=%u ee=%p\n", + (unsigned long long)e->sector, e->size, e); + ); + BIO_ENDIO_FN_RETURN; +} + +/* writes on behalf of the partner, or resync writes, + * "submitted" by the receiver. + */ +BIO_ENDIO_TYPE drbd_endio_write_sec BIO_ENDIO_ARGS(struct bio *bio, int error) __releases(local) +{ + unsigned long flags = 0; + struct Tl_epoch_entry *e = NULL; + struct drbd_conf *mdev; + sector_t e_sector; + int do_wake; + int is_syncer_req; + int do_al_complete_io; + int uptodate = bio_flagged(bio, BIO_UPTODATE); + + e = bio->bi_private; + mdev = e->mdev; + + BIO_ENDIO_FN_START; + if (!error && !uptodate) { + /* strange behaviour of some lower level drivers... + * fail the request by clearing the uptodate flag, + * but do not return any error?! + * do we want to drbd_WARN() on this? */ + error = -EIO; + } + + /* error == -ENOTSUPP would be a better test, + * alas it is not reliable */ + if (error && e->flags & EE_IS_BARRIER) { + drbd_bump_write_ordering(mdev, WO_bdev_flush); + spin_lock_irqsave(&mdev->req_lock, flags); + list_del(&e->w.list); + e->w.cb = w_e_reissue; + __release(local); /* Actually happens in w_e_reissue. */ + spin_unlock_irqrestore(&mdev->req_lock, flags); + drbd_queue_work(&mdev->data.work, &e->w); + BIO_ENDIO_FN_RETURN; + } + + D_ASSERT(e->block_id != ID_VACANT); + + dump_internal_bio("Sec", mdev, bio, 1); + + spin_lock_irqsave(&mdev->req_lock, flags); + mdev->writ_cnt += e->size >> 9; + is_syncer_req = is_syncer_block_id(e->block_id); + + /* after we moved e to done_ee, + * we may no longer access it, + * it may be freed/reused already! + * (as soon as we release the req_lock) */ + e_sector = e->sector; + do_al_complete_io = e->flags & EE_CALL_AL_COMPLETE_IO; + + list_del(&e->w.list); /* has been on active_ee or sync_ee */ + list_add_tail(&e->w.list, &mdev->done_ee); + + MTRACE(TraceTypeEE, TraceLvlAll, + INFO("Moved EE (WRITE) to done_ee sec=%llus size=%u ee=%p\n", + (unsigned long long)e->sector, e->size, e); + ); + + /* No hlist_del_init(&e->colision) here, we did not send the Ack yet, + * neither did we wake possibly waiting conflicting requests. + * done from "drbd_process_done_ee" within the appropriate w.cb + * (e_end_block/e_end_resync_block) or from _drbd_clear_done_ee */ + + do_wake = is_syncer_req + ? list_empty(&mdev->sync_ee) + : list_empty(&mdev->active_ee); + + if (error) + __drbd_chk_io_error(mdev, FALSE); + spin_unlock_irqrestore(&mdev->req_lock, flags); + + if (is_syncer_req) + drbd_rs_complete_io(mdev, e_sector); + + if (do_wake) + wake_up(&mdev->ee_wait); + + if (do_al_complete_io) + drbd_al_complete_io(mdev, e_sector); + + wake_asender(mdev); + dec_local(mdev); + + BIO_ENDIO_FN_RETURN; +} + +/* read, readA or write requests on Primary comming from drbd_make_request + */ +BIO_ENDIO_TYPE drbd_endio_pri BIO_ENDIO_ARGS(struct bio *bio, int error) +{ + unsigned long flags; + struct drbd_request *req = bio->bi_private; + struct drbd_conf *mdev = req->mdev; + enum drbd_req_event what; + int uptodate = bio_flagged(bio, BIO_UPTODATE); + + BIO_ENDIO_FN_START; + if (!error && !uptodate) { + /* strange behaviour of some lower level drivers... + * fail the request by clearing the uptodate flag, + * but do not return any error?! + * do we want to drbd_WARN() on this? */ + error = -EIO; + } + + dump_internal_bio("Pri", mdev, bio, 1); + + /* to avoid recursion in _req_mod */ + what = error + ? (bio_data_dir(bio) == WRITE) + ? write_completed_with_error + : read_completed_with_error + : completed_ok; + spin_lock_irqsave(&mdev->req_lock, flags); + _req_mod(req, what, error); + spin_unlock_irqrestore(&mdev->req_lock, flags); + BIO_ENDIO_FN_RETURN; +} + +int w_io_error(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + struct drbd_request *req = (struct drbd_request *)w; + int ok; + + /* FIXME send a "set_out_of_sync" packet to the peer + * in the PassOn case... + * in the Detach (or Panic) case, we (try to) send + * a "we are diskless" param packet anyways, and the peer + * will then set the FullSync bit in the meta data ... + */ + /* NOTE: mdev->bc can be NULL by the time we get here! */ + /* D_ASSERT(mdev->bc->dc.on_io_error != PassOn); */ + + /* the only way this callback is scheduled is from _req_may_be_done, + * when it is done and had a local write error, see comments there */ + drbd_req_free(req); + + ok = drbd_io_error(mdev, FALSE); + if (unlikely(!ok)) + ERR("Sending in w_io_error() failed\n"); + return ok; +} + +int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + struct drbd_request *req = (struct drbd_request *)w; + + /* FIXME this is ugly. we should not detach for read io-error, + * but try to WRITE the DataReply to the failed location, + * to give the disk the chance to relocate that block */ + drbd_io_error(mdev, FALSE); /* tries to schedule a detach and notifies peer */ + + spin_lock_irq(&mdev->req_lock); + if (cancel || + mdev->state.conn < Connected || + mdev->state.pdsk <= Inconsistent) { + _req_mod(req, send_canceled, 0); /* FIXME freeze? ... */ + spin_unlock_irq(&mdev->req_lock); + ALERT("WE ARE LOST. Local IO failure, no peer.\n"); + return 1; + } + spin_unlock_irq(&mdev->req_lock); + + return w_send_read_req(mdev, w, 0); +} + +int w_resync_inactive(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + ERR_IF(cancel) return 1; + ERR("resync inactive, but callback triggered??\n"); + return 1; /* Simply ignore this! */ +} + +STATIC void drbd_csum(struct drbd_conf *mdev, struct crypto_hash *tfm, struct bio *bio, void *digest) +{ + struct hash_desc desc; + struct scatterlist sg; + struct bio_vec *bvec; + int i; + + desc.tfm=tfm; + desc.flags=0; + + sg_init_table(&sg, 1); + crypto_hash_init(&desc); + + __bio_for_each_segment(bvec, bio, i, 0) { + sg_set_page(&sg, bvec->bv_page, bvec->bv_len, bvec->bv_offset); + crypto_hash_update(&desc, &sg, sg.length); + } + crypto_hash_final(&desc, digest); +} + +STATIC int w_e_send_csum(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + struct Tl_epoch_entry *e = (struct Tl_epoch_entry*)w; + int digest_size; + void *digest; + int ok; + + D_ASSERT( e->block_id == DRBD_MAGIC + 0xbeef ); + + if(unlikely(cancel)) { + drbd_free_ee(mdev,e); + return 1; + } + + if(likely(drbd_bio_uptodate(e->private_bio))) { + digest_size = crypto_hash_digestsize(mdev->csums_tfm); + digest = kmalloc(digest_size,GFP_KERNEL); + if(digest) { + drbd_csum(mdev, mdev->csums_tfm, e->private_bio, digest); + + inc_rs_pending(mdev); + ok = drbd_send_drequest_csum(mdev, + e->sector, + e->size, + digest, + digest_size, + CsumRSRequest); + kfree(digest); + } else { + ERR("kmalloc() of digest failed.\n"); + ok = 0; + } + } else { + drbd_io_error(mdev, FALSE); + ok=1; + } + + drbd_free_ee(mdev,e); + + if(unlikely(!ok)) ERR("drbd_send_drequest(..., csum) failed\n"); + return ok; +} + +#define GFP_TRY ( __GFP_HIGHMEM | __GFP_NOWARN ) + +STATIC int read_for_csum(struct drbd_conf *mdev, sector_t sector, int size) +{ + struct Tl_epoch_entry *e; + + if (!inc_local(mdev)) + return 0; + + if (FAULT_ACTIVE(mdev, DRBD_FAULT_AL_EE)) + return 2; + + e = drbd_alloc_ee(mdev, DRBD_MAGIC+0xbeef, sector, size, GFP_TRY); + if (!e) { + dec_local(mdev); + return 2; + } + + spin_lock_irq(&mdev->req_lock); + list_add(&e->w.list, &mdev->read_ee); + spin_unlock_irq(&mdev->req_lock); + + e->private_bio->bi_end_io = drbd_endio_read_sec; + e->private_bio->bi_rw = READ; + e->w.cb = w_e_send_csum; + + mdev->read_cnt += size >> 9; + drbd_generic_make_request(mdev,DRBD_FAULT_RS_RD,e->private_bio); + + return 1; +} + +int w_make_ov_request(struct drbd_conf *mdev, struct drbd_work *w, int cancel); + +void resync_timer_fn(unsigned long data) +{ + unsigned long flags; + struct drbd_conf *mdev = (struct drbd_conf *) data; + int queue; + + spin_lock_irqsave(&mdev->req_lock, flags); + + if (likely(!test_and_clear_bit(STOP_SYNC_TIMER, &mdev->flags))) { + queue = 1; + if (mdev->state.conn == VerifyS) + mdev->resync_work.cb = w_make_ov_request; + else + mdev->resync_work.cb = w_make_resync_request; + } else { + queue = 0; + mdev->resync_work.cb = w_resync_inactive; + } + + spin_unlock_irqrestore(&mdev->req_lock, flags); + + /* harmless race: list_empty outside data.work.q_lock */ + if (list_empty(&mdev->resync_work.list) && queue) + drbd_queue_work(&mdev->data.work, &mdev->resync_work); +} + +#define SLEEP_TIME (HZ/10) + +int w_make_resync_request(struct drbd_conf *mdev, + struct drbd_work *w, int cancel) +{ + unsigned long bit; + sector_t sector; + const sector_t capacity = drbd_get_capacity(mdev->this_bdev); + int max_segment_size = mdev->rq_queue->max_segment_size; + int number, i, size; + int align; + + PARANOIA_BUG_ON(w != &mdev->resync_work); + + if (unlikely(cancel)) + return 1; + + if (unlikely(mdev->state.conn < Connected)) { + ERR("Confused in w_make_resync_request()! cstate < Connected"); + return 0; + } + + if (mdev->state.conn != SyncTarget) + ERR("%s in w_make_resync_request\n", + conns_to_name(mdev->state.conn)); + + if (!inc_local(mdev)) { + /* Since we only need to access mdev->rsync a + inc_local_if_state(mdev,Failed) would be sufficient, but + to continue resync with a broken disk makes no sense at + all */ + ERR("Disk broke down during resync!\n"); + mdev->resync_work.cb = w_resync_inactive; + return 1; + } + /* All goto requeses have to happend after this block: inc_local() */ + + number = SLEEP_TIME*mdev->sync_conf.rate / ((BM_BLOCK_SIZE/1024)*HZ); + + if (atomic_read(&mdev->rs_pending_cnt) > number) + goto requeue; + number -= atomic_read(&mdev->rs_pending_cnt); + + for (i = 0; i < number; i++) { +next_sector: + size = BM_BLOCK_SIZE; + /* as of now, we are the only user of drbd_bm_find_next */ + bit = drbd_bm_find_next(mdev); + + if (bit == -1UL) { + /* FIXME either test_and_set some bit, + * or make this the _only_ place that is allowed + * to assign w_resync_inactive! */ + mdev->resync_work.cb = w_resync_inactive; + dec_local(mdev); + return 1; + } + + sector = BM_BIT_TO_SECT(bit); + + if (drbd_try_rs_begin_io(mdev, sector)) { + drbd_bm_set_find(mdev, bit); + goto requeue; + } + + if (unlikely(drbd_bm_test_bit(mdev, bit) == 0)) { + drbd_rs_complete_io(mdev, sector); + goto next_sector; + } + +#if DRBD_MAX_SEGMENT_SIZE > BM_BLOCK_SIZE + /* try to find some adjacent bits. + * we stop if we have already the maximum req size. + * + * Aditionally always align bigger requests, in order to + * be prepared for all stripe sizes of software RAIDs. + * + * we _do_ care about the agreed-uppon q->max_segment_size + * here, as splitting up the requests on the other side is more + * difficult. the consequence is, that on lvm and md and other + * "indirect" devices, this is dead code, since + * q->max_segment_size will be PAGE_SIZE. + */ + align = 1; + for (;;) { + if (size + BM_BLOCK_SIZE > max_segment_size) + break; + + /* Be always aligned */ + if (sector & ((1<<(align+3))-1)) + break; + + /* do not cross extent boundaries */ + if (((bit+1) & BM_BLOCKS_PER_BM_EXT_MASK) == 0) + break; + /* now, is it actually dirty, after all? + * caution, drbd_bm_test_bit is tri-state for some + * obscure reason; ( b == 0 ) would get the out-of-band + * only accidentally right because of the "oddly sized" + * adjustment below */ + if (drbd_bm_test_bit(mdev, bit+1) != 1) + break; + bit++; + size += BM_BLOCK_SIZE; + if ((BM_BLOCK_SIZE << align) <= size) + align++; + i++; + } + /* if we merged some, + * reset the offset to start the next drbd_bm_find_next from */ + if (size > BM_BLOCK_SIZE) + drbd_bm_set_find(mdev, bit+1); +#endif + + /* adjust very last sectors, in case we are oddly sized */ + if (sector + (size>>9) > capacity) + size = (capacity-sector)<<9; + if (mdev->agreed_pro_version >= 89 && mdev->csums_tfm) { + switch (read_for_csum(mdev, sector, size)) { + case 0: /* Disk failure*/ + dec_local(mdev); + return 0; + case 2: /* Allocation failed */ + drbd_rs_complete_io(mdev, sector); + drbd_bm_set_find(mdev, BM_SECT_TO_BIT(sector)); + goto requeue; + /* case 1: everything ok */ + } + } else { + inc_rs_pending(mdev); + if (!drbd_send_drequest(mdev, RSDataRequest, + sector, size, ID_SYNCER)) { + ERR("drbd_send_drequest() failed, aborting...\n"); + dec_rs_pending(mdev); + dec_local(mdev); + return 0; + } + } + } + + if (drbd_bm_rs_done(mdev)) { + /* last syncer _request_ was sent, + * but the RSDataReply not yet received. sync will end (and + * next sync group will resume), as soon as we receive the last + * resync data block, and the last bit is cleared. + * until then resync "work" is "inactive" ... + */ + mdev->resync_work.cb = w_resync_inactive; + dec_local(mdev); + return 1; + } + + requeue: + mod_timer(&mdev->resync_timer, jiffies + SLEEP_TIME); + dec_local(mdev); + return 1; +} + +int w_make_ov_request(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + int number,i,size; + sector_t sector; + const sector_t capacity = drbd_get_capacity(mdev->this_bdev); + + if(unlikely(cancel)) return 1; + + if (unlikely(mdev->state.conn < Connected)) { + ERR("Confused in w_make_ov_request()! cstate < Connected"); + return 0; + } + + number = SLEEP_TIME*mdev->sync_conf.rate / ((BM_BLOCK_SIZE/1024)*HZ); + if (atomic_read(&mdev->rs_pending_cnt)>number) { + goto requeue; + } + number -= atomic_read(&mdev->rs_pending_cnt); + + sector = mdev->ov_position; + for(i=0;iov_position = sector; + goto requeue; + } + + if (sector + (size>>9) > capacity) size = (capacity-sector)<<9; + + inc_rs_pending(mdev); + if(!drbd_send_ov_request(mdev, sector, size)) { + dec_rs_pending(mdev); + return 0; + } + sector += BM_SECT_PER_BIT; + if(sector >= capacity) { + mdev->resync_work.cb = w_resync_inactive; + + return 1; + } + } + mdev->ov_position = sector; + + requeue: + mod_timer(&mdev->resync_timer, jiffies + SLEEP_TIME); + return 1; +} + + +int w_ov_finished(struct drbd_conf *mdev, struct drbd_work* w,int cancel) +{ + kfree(w); + ov_oos_print(mdev); + drbd_resync_finished(mdev); + + return 1; +} + +STATIC int w_resync_finished(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + kfree(w); + + drbd_resync_finished(mdev); + + return 1; +} + +int drbd_resync_finished(struct drbd_conf *mdev) +{ + unsigned long db, dt, dbdt; + unsigned long n_oos; + union drbd_state_t os, ns; + struct drbd_work *w; + char * khelper_cmd = NULL; + + /* Remove all elements from the resync LRU. Since future actions + * might set bits in the (main) bitmap, then the entries in the + * resync LRU would be wrong. */ + if (drbd_rs_del_all(mdev)) { + /* In case this is not possible now, most probabely because + * there are RSDataReply Packets lingering on the worker's + * queue (or even the read operations for those packets + * is not finished by now). Retry in 100ms. */ + + drbd_kick_lo(mdev); + __set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ / 10); + w = kmalloc(sizeof(struct drbd_work), GFP_ATOMIC); + if (w) { + w->cb = w_resync_finished; + drbd_queue_work(&mdev->data.work, w); + return 1; + } + ERR("Warn failed to drbd_rs_del_all() and to kmalloc(w).\n"); + } + + dt = (jiffies - mdev->rs_start - mdev->rs_paused) / HZ; + if (dt <= 0) + dt = 1; + db = mdev->rs_total; + dbdt = Bit2KB(db/dt); + mdev->rs_paused /= HZ; + + if (!inc_local(mdev)) + goto out; + + spin_lock_irq(&mdev->req_lock); + os = mdev->state; + + /* This protects us against multiple calls (that can happen in the presence + of application IO), and against connectivity loss just before we arrive here. */ + if (os.conn <= Connected) + goto out_unlock; + + ns = os; + ns.conn = Connected; + + INFO("%s done (total %lu sec; paused %lu sec; %lu K/sec)\n", + (os.conn == VerifyS || os.conn == VerifyT) ? + "Online verify " : "Resync", + dt + mdev->rs_paused, mdev->rs_paused, dbdt); + + n_oos = drbd_bm_total_weight(mdev); + + if (os.conn == VerifyS || os.conn == VerifyT) { + if (n_oos) { + ALERT("Online verify found %lu %dk block out of sync!\n", + n_oos, Bit2KB(1)); + khelper_cmd = "out-of-sync"; + } + } else { + D_ASSERT((n_oos - mdev->rs_failed) == 0); + + if (os.conn == SyncTarget || os.conn == PausedSyncT) + khelper_cmd = "after-resync-target"; + + if (mdev->csums_tfm && mdev->rs_total) { + const unsigned long s = mdev->rs_same_csum; + const unsigned long t = mdev->rs_total; + const int ratio = + (t == 0) ? 0 : + (t < 100000) ? ((s*100)/t) : (s/(t/100)); + INFO("%u %% had equal check sums, eliminated: %luK; " + "transferred %luK total %luK\n", + ratio, + Bit2KB(mdev->rs_same_csum), + Bit2KB(mdev->rs_total - mdev->rs_same_csum), + Bit2KB(mdev->rs_total)); + } + } + + if (mdev->rs_failed) { + INFO(" %lu failed blocks\n", mdev->rs_failed); + + if (os.conn == SyncTarget || os.conn == PausedSyncT) { + ns.disk = Inconsistent; + ns.pdsk = UpToDate; + } else { + ns.disk = UpToDate; + ns.pdsk = Inconsistent; + } + } else { + ns.disk = UpToDate; + ns.pdsk = UpToDate; + + if (os.conn == SyncTarget || os.conn == PausedSyncT) { + if (mdev->p_uuid) { + int i; + for (i = Bitmap ; i <= History_end ; i++) + _drbd_uuid_set(mdev, i, mdev->p_uuid[i]); + drbd_uuid_set(mdev, Bitmap, mdev->bc->md.uuid[Current]); + _drbd_uuid_set(mdev, Current, mdev->p_uuid[Current]); + } else { + ERR("mdev->p_uuid is NULL! BUG\n"); + } + } + + drbd_uuid_set_bm(mdev, 0UL); + + if (mdev->p_uuid) { + /* Now the two UUID sets are equal, update what we + * know of the peer. */ + int i; + for (i = Current ; i <= History_end ; i++) + mdev->p_uuid[i] = mdev->bc->md.uuid[i]; + } + } + + DRBD_STATE_DEBUG_INIT_VAL(ns); + _drbd_set_state(mdev, ns, ChgStateVerbose, NULL); +out_unlock: + spin_unlock_irq(&mdev->req_lock); + dec_local(mdev); +out: + mdev->rs_total = 0; + mdev->rs_failed = 0; + mdev->rs_paused = 0; + + if (test_and_clear_bit(WRITE_BM_AFTER_RESYNC, &mdev->flags)) { + drbd_WARN("Writing the whole bitmap, due to failed kmalloc\n"); + drbd_queue_bitmap_io(mdev, &drbd_bm_write, NULL, "write from resync_finished"); + } + + drbd_bm_recount_bits(mdev); + + if (khelper_cmd) + drbd_khelper(mdev, khelper_cmd); + + return 1; +} + +/** + * w_e_end_data_req: Send the answer (DataReply) in response to a DataRequest. + */ +int w_e_end_data_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + struct Tl_epoch_entry *e = (struct Tl_epoch_entry *)w; + int ok; + + if (unlikely(cancel)) { + drbd_free_ee(mdev, e); + dec_unacked(mdev); + return 1; + } + + if (likely(drbd_bio_uptodate(e->private_bio))) { + ok = drbd_send_block(mdev, DataReply, e); + } else { + if (DRBD_ratelimit(5*HZ, 5)) + ERR("Sending NegDReply. sector=%llus.\n", + (unsigned long long)e->sector); + + ok = drbd_send_ack(mdev, NegDReply, e); + + /* FIXME we should not detach for read io-errors, in particular + * not now: when the peer asked us for our data, we are likely + * the only remaining disk... */ + drbd_io_error(mdev, FALSE); + } + + dec_unacked(mdev); + + spin_lock_irq(&mdev->req_lock); + if (drbd_bio_has_active_page(e->private_bio)) { + /* This might happen if sendpage() has not finished */ + list_add_tail(&e->w.list, &mdev->net_ee); + } else { + drbd_free_ee(mdev, e); + } + spin_unlock_irq(&mdev->req_lock); + + if (unlikely(!ok)) + ERR("drbd_send_block() failed\n"); + return ok; +} + +/** + * w_e_end_rsdata_req: Send the answer (RSDataReply) to a RSDataRequest. + */ +int w_e_end_rsdata_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + struct Tl_epoch_entry *e = (struct Tl_epoch_entry *)w; + int ok; + + if (unlikely(cancel)) { + drbd_free_ee(mdev, e); + dec_unacked(mdev); + return 1; + } + + if (inc_local_if_state(mdev, Failed)) { + drbd_rs_complete_io(mdev, e->sector); + dec_local(mdev); + } + + if (likely(drbd_bio_uptodate(e->private_bio))) { + if (likely(mdev->state.pdsk >= Inconsistent)) { + inc_rs_pending(mdev); + ok = drbd_send_block(mdev, RSDataReply, e); + } else { + if (DRBD_ratelimit(5*HZ, 5)) + ERR("Not sending RSDataReply, " + "partner DISKLESS!\n"); + ok = 1; + } + } else { + if (DRBD_ratelimit(5*HZ, 5)) + ERR("Sending NegRSDReply. sector %llus.\n", + (unsigned long long)e->sector); + + ok = drbd_send_ack(mdev, NegRSDReply, e); + + drbd_io_error(mdev, FALSE); + + /* update resync data with failure */ + drbd_rs_failed_io(mdev, e->sector, e->size); + } + + dec_unacked(mdev); + + spin_lock_irq(&mdev->req_lock); + if (drbd_bio_has_active_page(e->private_bio)) { + /* This might happen if sendpage() has not finished */ + list_add_tail(&e->w.list, &mdev->net_ee); + } else { + drbd_free_ee(mdev, e); + } + spin_unlock_irq(&mdev->req_lock); + + if (unlikely(!ok)) + ERR("drbd_send_block() failed\n"); + return ok; +} + +int w_e_end_csum_rs_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + struct Tl_epoch_entry *e = (struct Tl_epoch_entry*)w; + struct digest_info *di; + int digest_size; + void *digest = NULL; + int ok,eq=0; + + if (unlikely(cancel)) { + drbd_free_ee(mdev,e); + dec_unacked(mdev); + return 1; + } + + drbd_rs_complete_io(mdev, e->sector); + + di = (struct digest_info *)(unsigned long)e->block_id; + + if (likely(drbd_bio_uptodate(e->private_bio))) { + /* quick hack to try to avoid a race against reconfiguration. + * a real fix would be much more involved, + * introducing more locking mechanisms */ + if (mdev->csums_tfm) { + digest_size = crypto_hash_digestsize(mdev->csums_tfm); + D_ASSERT(digest_size == di->digest_size); + digest = kmalloc(digest_size,GFP_KERNEL); + } + if (digest) { + drbd_csum(mdev, mdev->csums_tfm, e->private_bio, digest); + eq = !memcmp(digest, di->digest, digest_size); + kfree(digest); + } + + if (eq) { + drbd_set_in_sync(mdev, e->sector,e->size); + mdev->rs_same_csum++; + ok=drbd_send_ack(mdev, RSIsInSync, e); + } else { + inc_rs_pending(mdev); + e->block_id = ID_SYNCER; + ok=drbd_send_block(mdev, RSDataReply, e); + } + } else { + ok=drbd_send_ack(mdev,NegRSDReply,e); + if (DRBD_ratelimit(5*HZ,5)) + ERR("Sending NegDReply. I guess it gets messy.\n"); + drbd_io_error(mdev, FALSE); + } + + dec_unacked(mdev); + + kfree(di); + + spin_lock_irq(&mdev->req_lock); + if (drbd_bio_has_active_page(e->private_bio)) { + /* This might happen if sendpage() has not finished */ + list_add_tail(&e->w.list,&mdev->net_ee); + } else { + drbd_free_ee(mdev,e); + } + spin_unlock_irq(&mdev->req_lock); + + if (unlikely(!ok)) + ERR("drbd_send_block/ack() failed\n"); + return ok; +} + +int w_e_end_ov_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + struct Tl_epoch_entry *e = (struct Tl_epoch_entry*)w; + int digest_size; + void *digest; + int ok=1; + + if(unlikely(cancel)) { + drbd_free_ee(mdev,e); + dec_unacked(mdev); + return 1; + } + + if(likely(drbd_bio_uptodate(e->private_bio))) { + digest_size = crypto_hash_digestsize(mdev->verify_tfm); + digest = kmalloc(digest_size,GFP_KERNEL); + if(digest) { + drbd_csum(mdev,mdev->verify_tfm,e->private_bio,digest); + ok = drbd_send_drequest_csum(mdev, e->sector, e->size, + digest, digest_size, OVReply); + if (ok) inc_rs_pending(mdev); + kfree(digest); + } + } + + dec_unacked(mdev); + + spin_lock_irq(&mdev->req_lock); + drbd_free_ee(mdev,e); + spin_unlock_irq(&mdev->req_lock); + + return ok; +} + +void drbd_ov_oos_found(struct drbd_conf *mdev, sector_t sector, int size) +{ + if (mdev->ov_last_oos_start + mdev->ov_last_oos_size == sector) { + mdev->ov_last_oos_size += size>>9; + } else { + mdev->ov_last_oos_start = sector; + mdev->ov_last_oos_size = size>>9; + } + drbd_set_out_of_sync(mdev, sector, size); + set_bit(WRITE_BM_AFTER_RESYNC, &mdev->flags); +} + +int w_e_end_ov_reply(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + struct Tl_epoch_entry *e = (struct Tl_epoch_entry*)w; + struct digest_info *di; + int digest_size; + void *digest; + int ok,eq=0; + + if(unlikely(cancel)) { + drbd_free_ee(mdev,e); + dec_unacked(mdev); + return 1; + } + + /* after "cancel", because after drbd_disconnect/drbd_rs_cancel_all + * the resync lru has been cleaned up already */ + drbd_rs_complete_io(mdev,e->sector); + + di = (struct digest_info *)(unsigned long)e->block_id; + + if(likely(drbd_bio_uptodate(e->private_bio))) { + digest_size = crypto_hash_digestsize(mdev->verify_tfm); + digest = kmalloc(digest_size,GFP_KERNEL); + if(digest) { + drbd_csum(mdev, mdev->verify_tfm, e->private_bio, digest); + + D_ASSERT(digest_size == di->digest_size); + eq = !memcmp(digest, di->digest, digest_size); + kfree(digest); + } + } else { + ok=drbd_send_ack(mdev,NegRSDReply,e); + if (DRBD_ratelimit(5*HZ,5)) + ERR("Sending NegDReply. I guess it gets messy.\n"); + drbd_io_error(mdev, FALSE); + } + + dec_unacked(mdev); + + kfree(di); + + if (!eq) drbd_ov_oos_found(mdev,e->sector,e->size); + else ov_oos_print(mdev); + + ok = drbd_send_ack_ex(mdev,OVResult,e->sector,e->size, + eq ? ID_IN_SYNC : ID_OUT_OF_SYNC); + + spin_lock_irq(&mdev->req_lock); + drbd_free_ee(mdev,e); + spin_unlock_irq(&mdev->req_lock); + + if( --mdev->ov_left == 0 ) { + ov_oos_print(mdev); + drbd_resync_finished(mdev); + } + + return ok; +} + +int w_prev_work_done(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + clear_bit(WORK_PENDING, &mdev->flags); + wake_up(&mdev->misc_wait); + return 1; +} + +int w_send_barrier(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + struct drbd_barrier *b = (struct drbd_barrier *)w; + struct Drbd_Barrier_Packet *p = &mdev->data.sbuf.Barrier; + int ok = 1; + + /* really avoid racing with tl_clear. w.cb may have been referenced + * just before it was reassigned and requeued, so double check that. + * actually, this race was harmless, since we only try to send the + * barrier packet here, and otherwise do nothing with the object. + * but compare with the head of w_clear_epoch */ + spin_lock_irq(&mdev->req_lock); + if (w->cb != w_send_barrier || mdev->state.conn < Connected) + cancel = 1; + spin_unlock_irq(&mdev->req_lock); + if (cancel) + return 1; + + if (!drbd_get_data_sock(mdev)) + return 0; + p->barrier = b->br_number; + /* inc_ap_pending was done where this was queued. + * dec_ap_pending will be done in got_BarrierAck + * or (on connection loss) in w_clear_epoch. */ + ok = _drbd_send_cmd(mdev, mdev->data.socket, Barrier, + (struct Drbd_Header *)p, sizeof(*p), 0); + drbd_put_data_sock(mdev); + + return ok; +} + +int w_send_write_hint(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + if (cancel) + return 1; + return drbd_send_short_cmd(mdev, UnplugRemote); +} + +/** + * w_send_dblock: Send a mirrored write request. + */ +int w_send_dblock(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + struct drbd_request *req = (struct drbd_request *)w; + int ok; + + if (unlikely(cancel)) { + req_mod(req, send_canceled, 0); + return 1; + } + + ok = drbd_send_dblock(mdev, req); + req_mod(req, ok ? handed_over_to_network : send_failed, 0); + + return ok; +} + +/** + * w_send_read_req: Send a read requests. + */ +int w_send_read_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + struct drbd_request *req = (struct drbd_request *)w; + int ok; + + if (unlikely(cancel)) { + req_mod(req, send_canceled, 0); + return 1; + } + + ok = drbd_send_drequest(mdev, DataRequest, req->sector, req->size, + (unsigned long)req); + + if (!ok) { + /* ?? we set Timeout or BrokenPipe in drbd_send(); + * so this is probably redundant */ + if (mdev->state.conn >= Connected) + drbd_force_state(mdev, NS(conn, NetworkFailure)); + } + req_mod(req, ok ? handed_over_to_network : send_failed, 0); + + return ok; +} + +STATIC void drbd_global_lock(void) __acquires(drbd_global_lock) +{ + struct drbd_conf *mdev; + int i; + + __acquire(drbd_global_lock); + local_irq_disable(); + for (i = 0; i < minor_count; i++) { + mdev = minor_to_mdev(i); + if (!mdev) + continue; + spin_lock(&mdev->req_lock); + __release(&mdev->req_lock); /* annihilate the spin_lock's annotation here */ + } +} + +STATIC void drbd_global_unlock(void) __releases(drbd_global_lock) +{ + struct drbd_conf *mdev; + int i; + + for (i = 0; i < minor_count; i++) { + mdev = minor_to_mdev(i); + if (!mdev) + continue; + __acquire(&mdev->req_lock); + spin_unlock(&mdev->req_lock); + } + local_irq_enable(); + __release(drbd_global_lock); +} + +STATIC int _drbd_may_sync_now(struct drbd_conf *mdev) +{ + struct drbd_conf *odev = mdev; + + while (1) { + if (odev->sync_conf.after == -1) + return 1; + odev = minor_to_mdev(odev->sync_conf.after); + ERR_IF(!odev) return 1; + if ((odev->state.conn >= SyncSource && + odev->state.conn <= PausedSyncT) || + odev->state.aftr_isp || odev->state.peer_isp || + odev->state.user_isp) + return 0; + } +} + +/** + * _drbd_pause_after: + * Finds all devices that may not resync now, and causes them to + * pause their resynchronisation. + * Called from process context only (admin command and after_state_ch). + */ +STATIC int _drbd_pause_after(struct drbd_conf *mdev) +{ + struct drbd_conf *odev; + int i, rv = 0; + + for (i = 0; i < minor_count; i++) { + odev = minor_to_mdev(i); + if (!odev) + continue; + if (odev->state.conn == StandAlone && odev->state.disk == Diskless) + continue; + if (!_drbd_may_sync_now(odev)) + rv |= (_drbd_set_state(_NS(odev, aftr_isp, 1), ChgStateHard, NULL) + != SS_NothingToDo); + } + + return rv; +} + +/** + * _drbd_resume_next: + * Finds all devices that can resume resynchronisation + * process, and causes them to resume. + * Called from process context only (admin command and worker). + */ +STATIC int _drbd_resume_next(struct drbd_conf *mdev) +{ + struct drbd_conf *odev; + int i, rv = 0; + + for (i = 0; i < minor_count; i++) { + odev = minor_to_mdev(i); + if (!odev) + continue; + if (odev->state.aftr_isp) { + if (_drbd_may_sync_now(odev)) + rv |= (_drbd_set_state(_NS(odev, aftr_isp, 0), + ChgStateHard, NULL) + != SS_NothingToDo) ; + } + } + return rv; +} + +void resume_next_sg(struct drbd_conf *mdev) +{ + drbd_global_lock(); + _drbd_resume_next(mdev); + drbd_global_unlock(); +} + +void suspend_other_sg(struct drbd_conf *mdev) +{ + drbd_global_lock(); + _drbd_pause_after(mdev); + drbd_global_unlock(); +} + +void drbd_alter_sa(struct drbd_conf *mdev, int na) +{ + int changes; + + drbd_global_lock(); + mdev->sync_conf.after = na; + + do { + changes = _drbd_pause_after(mdev); + changes |= _drbd_resume_next(mdev); + } while (changes); + + drbd_global_unlock(); +} + +/** + * drbd_start_resync: + * @side: Either SyncSource or SyncTarget + * Start the resync process. Called from process context only, + * either admin command or drbd_receiver. + * Note, this function might bring you directly into one of the + * PausedSync* states. + */ +void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side) +{ + union drbd_state_t ns; + int r; + + MTRACE(TraceTypeResync, TraceLvlSummary, + INFO("Resync starting: side=%s\n", + side == SyncTarget ? "SyncTarget" : "SyncSource"); + ); + + drbd_bm_recount_bits(mdev); + + /* In case a previous resync run was aborted by an IO error... */ + drbd_rs_cancel_all(mdev); + + if (side == SyncTarget) { + /* Since application IO was locked out during WFBitMapT and + WFSyncUUID we are still unmodified. Before going to SyncTarget + we check that we might make the data inconsistent. */ + r = drbd_khelper(mdev, "before-resync-target"); + r = (r >> 8) & 0xff; + if (r > 0) { + INFO("before-resync-target handler returned %d, " + "dropping connection.\n", r); + drbd_force_state(mdev, NS(conn, Disconnecting)); + return; + } + } + + drbd_state_lock(mdev); + + if (!inc_local_if_state(mdev, Negotiating)) { + drbd_state_unlock(mdev); + return; + } + + if (side == SyncTarget) { + drbd_bm_reset_find(mdev); + } else /* side == SyncSource */ { + u64 uuid; + + get_random_bytes(&uuid, sizeof(u64)); + drbd_uuid_set(mdev, Bitmap, uuid); + drbd_send_sync_uuid(mdev, uuid); + + D_ASSERT(mdev->state.disk == UpToDate); + } + + drbd_global_lock(); + ns = mdev->state; + + ns.aftr_isp = !_drbd_may_sync_now(mdev); + + ns.conn = side; + + if (side == SyncTarget) + ns.disk = Inconsistent; + else /* side == SyncSource */ + ns.pdsk = Inconsistent; + + DRBD_STATE_DEBUG_INIT_VAL(ns); + r = _drbd_set_state(mdev, ns, ChgStateVerbose, NULL); + ns = mdev->state; + + if (ns.conn < Connected) + r = SS_UnknownError; + + if (r == SS_Success) { + mdev->rs_total = + mdev->rs_mark_left = drbd_bm_total_weight(mdev); + mdev->rs_failed = 0; + mdev->rs_paused = 0; + mdev->rs_start = + mdev->rs_mark_time = jiffies; + mdev->rs_same_csum = 0; + _drbd_pause_after(mdev); + } + drbd_global_unlock(); + drbd_state_unlock(mdev); + dec_local(mdev); + + if (r == SS_Success) { + INFO("Began resync as %s (will sync %lu KB [%lu bits set]).\n", + conns_to_name(ns.conn), + (unsigned long) mdev->rs_total << (BM_BLOCK_SIZE_B-10), + (unsigned long) mdev->rs_total); + + if (mdev->rs_total == 0) { + drbd_resync_finished(mdev); + return; + } + + if (ns.conn == SyncTarget) { + D_ASSERT(!test_bit(STOP_SYNC_TIMER, &mdev->flags)); + mod_timer(&mdev->resync_timer, jiffies); + } + + drbd_md_sync(mdev); + } +} + +int drbd_worker(struct Drbd_thread *thi) +{ + struct drbd_conf *mdev = thi->mdev; + struct drbd_work *w = NULL; + LIST_HEAD(work_list); + int intr = 0, i; + + sprintf(current->comm, "drbd%d_worker", mdev_to_minor(mdev)); + + while (get_t_state(thi) == Running) { + drbd_thread_current_set_cpu(mdev); + + if (down_trylock(&mdev->data.work.s)) { + down(&mdev->data.mutex); + if (mdev->data.socket && !mdev->net_conf->no_cork) + drbd_tcp_uncork(mdev->data.socket); + up(&mdev->data.mutex); + + intr = down_interruptible(&mdev->data.work.s); + + down(&mdev->data.mutex); + if (mdev->data.socket && !mdev->net_conf->no_cork) + drbd_tcp_cork(mdev->data.socket); + up(&mdev->data.mutex); + } + + if (intr) { + D_ASSERT(intr == -EINTR); + flush_signals(current); + ERR_IF (get_t_state(thi) == Running) + continue; + break; + } + + if (get_t_state(thi) != Running) + break; + /* With this break, we have done a down() but not consumed + the entry from the list. The cleanup code takes care of + this... */ + + w = NULL; + spin_lock_irq(&mdev->data.work.q_lock); + ERR_IF(list_empty(&mdev->data.work.q)) { + /* something terribly wrong in our logic. + * we were able to down() the semaphore, + * but the list is empty... doh. + * + * what is the best thing to do now? + * try again from scratch, restarting the receiver, + * asender, whatnot? could break even more ugly, + * e.g. when we are primary, but no good local data. + * + * I'll try to get away just starting over this loop. + */ + spin_unlock_irq(&mdev->data.work.q_lock); + continue; + } + w = list_entry(mdev->data.work.q.next, struct drbd_work, list); + list_del_init(&w->list); + spin_unlock_irq(&mdev->data.work.q_lock); + + if (!w->cb(mdev, w, mdev->state.conn < Connected)) { + /* drbd_WARN("worker: a callback failed! \n"); */ + if (mdev->state.conn >= Connected) + drbd_force_state(mdev, + NS(conn, NetworkFailure)); + } + } + + spin_lock_irq(&mdev->data.work.q_lock); + i = 0; + while (!list_empty(&mdev->data.work.q)) { + list_splice_init(&mdev->data.work.q, &work_list); + spin_unlock_irq(&mdev->data.work.q_lock); + + while (!list_empty(&work_list)) { + w = list_entry(work_list.next, struct drbd_work, list); + list_del_init(&w->list); + w->cb(mdev, w, 1); + i++; /* dead debugging code */ + } + + spin_lock_irq(&mdev->data.work.q_lock); + } + sema_init(&mdev->data.work.s, 0); + /* DANGEROUS race: if someone did queue his work within the spinlock, + * but up() ed outside the spinlock, we could get an up() on the + * semaphore without corresponding list entry. + * So don't do that. + */ + spin_unlock_irq(&mdev->data.work.q_lock); + /* FIXME verify that there absolutely can not be any more work + * on the queue now... + * if so, the comment above is no longer true, but historic + * from the times when the worker did not live as long as the + * device.. */ + + D_ASSERT(mdev->state.disk == Diskless && mdev->state.conn == StandAlone); + /* _drbd_set_state only uses stop_nowait. + * wait here for the Exiting receiver. */ + drbd_thread_stop(&mdev->receiver); + drbd_mdev_cleanup(mdev); + + INFO("worker terminated\n"); + + return 0; +} --- linux-2.6.28.orig/ubuntu/drbd/drbd_buildtag.c +++ linux-2.6.28/ubuntu/drbd/drbd_buildtag.c @@ -0,0 +1,7 @@ +/* automatically generated. DO NOT EDIT. */ +#include +const char *drbd_buildtag(void) +{ + return "GIT-hash: 9ba8b93e24d842f0dd3fb1f9b90e8348ddb95829" + " build by ivoks@ubuntu, 2009-01-17 07:49:56"; +} --- linux-2.6.28.orig/ubuntu/drbd/drbd_nl.c +++ linux-2.6.28/ubuntu/drbd/drbd_nl.c @@ -0,0 +1,2422 @@ +/* +-*- linux-c -*- + drbd_nl.c + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2001-2008, LINBIT Information Technologies GmbH. + Copyright (C) 1999-2008, Philipp Reisner . + Copyright (C) 2002-2008, Lars Ellenberg . + + drbd is free software; you can redistribute 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. + + drbd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + */ + +#include +#include +#include +#include +#include /* for fsync_bdev */ +#include +#include +#include +#include +#include +#include + +#include "drbd_int.h" +#include +#include + +/* see get_sb_bdev and bd_claim */ +static char *drbd_m_holder = "Hands off! this is DRBD's meta data device."; + +/* Generate the tag_list to struct functions */ +#define NL_PACKET(name, number, fields) \ +STATIC int name ## _from_tags (struct drbd_conf *mdev, \ + unsigned short *tags, struct name *arg) \ +{ \ + int tag; \ + int dlen; \ + \ + while ((tag = *tags++) != TT_END) { \ + dlen = *tags++; \ + switch (tag_number(tag)) { \ + fields \ + default: \ + if (tag & T_MANDATORY) { \ + ERR("Unknown tag: %d\n", tag_number(tag)); \ + return 0; \ + } \ + } \ + tags = (unsigned short *)((char *)tags + dlen); \ + } \ + return 1; \ +} +#define NL_INTEGER(pn, pr, member) \ + case pn: /* D_ASSERT( tag_type(tag) == TT_INTEGER ); */ \ + arg->member = *(int *)(tags); \ + break; +#define NL_INT64(pn, pr, member) \ + case pn: /* D_ASSERT( tag_type(tag) == TT_INT64 ); */ \ + arg->member = *(u64 *)(tags); \ + break; +#define NL_BIT(pn, pr, member) \ + case pn: /* D_ASSERT( tag_type(tag) == TT_BIT ); */ \ + arg->member = *(char *)(tags) ? 1 : 0; \ + break; +#define NL_STRING(pn, pr, member, len) \ + case pn: /* D_ASSERT( tag_type(tag) == TT_STRING ); */ \ + if (dlen > len) { \ + ERR("arg too long: %s (%u wanted, max len: %u bytes)\n", \ + #member, dlen, (unsigned int)len); \ + return 0; \ + } \ + arg->member ## _len = dlen; \ + memcpy(arg->member, tags, min_t(size_t, dlen, len)); \ + break; +#include "linux/drbd_nl.h" + +/* Generate the struct to tag_list functions */ +#define NL_PACKET(name, number, fields) \ +STATIC unsigned short* \ +name ## _to_tags (struct drbd_conf *mdev, \ + struct name *arg, unsigned short *tags) \ +{ \ + fields \ + return tags; \ +} + +#define NL_INTEGER(pn, pr, member) \ + *tags++ = pn | pr | TT_INTEGER; \ + *tags++ = sizeof(int); \ + *(int *)tags = arg->member; \ + tags = (unsigned short *)((char *)tags+sizeof(int)); +#define NL_INT64(pn, pr, member) \ + *tags++ = pn | pr | TT_INT64; \ + *tags++ = sizeof(u64); \ + *(u64 *)tags = arg->member; \ + tags = (unsigned short *)((char *)tags+sizeof(u64)); +#define NL_BIT(pn, pr, member) \ + *tags++ = pn | pr | TT_BIT; \ + *tags++ = sizeof(char); \ + *(char *)tags = arg->member; \ + tags = (unsigned short *)((char *)tags+sizeof(char)); +#define NL_STRING(pn, pr, member, len) \ + *tags++ = pn | pr | TT_STRING; \ + *tags++ = arg->member ## _len; \ + memcpy(tags, arg->member, arg->member ## _len); \ + tags = (unsigned short *)((char *)tags + arg->member ## _len); +#include "linux/drbd_nl.h" + +void drbd_bcast_ev_helper(struct drbd_conf *mdev, char *helper_name); +void drbd_nl_send_reply(struct cn_msg *, int); + +STATIC char *nl_packet_name(int packet_type) +{ +/* Generate packet type strings */ +#define NL_PACKET(name, number, fields) \ + [ P_ ## name ] = # name, +#define NL_INTEGER Argh! +#define NL_BIT Argh! +#define NL_INT64 Argh! +#define NL_STRING Argh! + + static char *nl_tag_name[P_nl_after_last_packet] = { +#include "linux/drbd_nl.h" + }; + + return (packet_type < sizeof(nl_tag_name)/sizeof(nl_tag_name[0])) ? + nl_tag_name[packet_type] : "*Unknown*"; +} + +STATIC void nl_trace_packet(void *data) +{ + struct cn_msg *req = data; + struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req *)req->data; + + printk(KERN_INFO "drbd%d: " + "Netlink: << %s (%d) - seq: %x, ack: %x, len: %x\n", + nlp->drbd_minor, + nl_packet_name(nlp->packet_type), + nlp->packet_type, + req->seq, req->ack, req->len); +} + +STATIC void nl_trace_reply(void *data) +{ + struct cn_msg *req = data; + struct drbd_nl_cfg_reply *nlp = (struct drbd_nl_cfg_reply *)req->data; + + printk(KERN_INFO "drbd%d: " + "Netlink: >> %s (%d) - seq: %x, ack: %x, len: %x\n", + nlp->minor, + nlp->packet_type == P_nl_after_last_packet ? + "Empty-Reply" : nl_packet_name(nlp->packet_type), + nlp->packet_type, + req->seq, req->ack, req->len); +} + +int drbd_khelper(struct drbd_conf *mdev, char *cmd) +{ + char mb[12]; + char *argv[] = {usermode_helper, cmd, mb, NULL }; + int ret; + static char *envp[] = { "HOME=/", + "TERM=linux", + "PATH=/sbin:/usr/sbin:/bin:/usr/bin", + NULL }; + + snprintf(mb, 12, "minor-%d", mdev_to_minor(mdev)); + + INFO("helper command: %s %s %s\n", usermode_helper, cmd, mb); + + drbd_bcast_ev_helper(mdev, cmd); + ret = call_usermodehelper(usermode_helper, argv, envp, 1); + if (ret) + drbd_WARN("helper command: %s %s %s exit code %u (0x%x)\n", + usermode_helper, cmd, mb, + (ret >> 8) & 0xff, ret); + else + INFO("helper command: %s %s %s exit code %u (0x%x)\n", + usermode_helper, cmd, mb, + (ret >> 8) & 0xff, ret); + + if (ret < 0) /* Ignore any ERRNOs we got. */ + ret = 0; + + return ret; +} + +enum drbd_disk_state drbd_try_outdate_peer(struct drbd_conf *mdev) +{ + char *ex_to_string; + int r; + enum drbd_disk_state nps; + enum fencing_policy fp; + + D_ASSERT(mdev->state.pdsk == DUnknown); + + if (inc_local_if_state(mdev, Consistent)) { + fp = mdev->bc->dc.fencing; + dec_local(mdev); + } else { + drbd_WARN("Not fencing peer, I'm not even Consistent myself.\n"); + return mdev->state.pdsk; + } + + if (fp == Stonith) + _drbd_request_state(mdev, NS(susp, 1), ChgWaitComplete); + + r = drbd_khelper(mdev, "fence-peer"); + + switch ((r>>8) & 0xff) { + case 3: /* peer is inconsistent */ + ex_to_string = "peer is inconsistent or worse"; + nps = Inconsistent; + break; + case 4: + ex_to_string = "peer is outdated"; + nps = Outdated; + break; + case 5: /* peer was down, we will(have) create(d) a new UUID anyways... */ + /* If we would be more strict, we would return DUnknown here. */ + ex_to_string = "peer is unreachable, assumed to be dead"; + nps = Outdated; + break; + case 6: /* Peer is primary, voluntarily outdate myself. + * This is useful when an unconnected Secondary is asked to + * become Primary, but findes the other peer being active. */ + ex_to_string = "peer is active"; + drbd_WARN("Peer is primary, outdating myself.\n"); + nps = DUnknown; + _drbd_request_state(mdev, NS(disk, Outdated), ChgWaitComplete); + break; + case 7: + if (fp != Stonith) + ERR("fence-peer() = 7 && fencing != Stonith !!!\n"); + ex_to_string = "peer was stonithed"; + nps = Outdated; + break; + default: + /* The script is broken ... */ + nps = DUnknown; + ERR("fence-peer helper broken, returned %d\n", (r>>8)&0xff); + return nps; + } + + INFO("fence-peer helper returned %d (%s)\n", + (r>>8) & 0xff, ex_to_string); + return nps; +} + + +int drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force) +{ + const int max_tries = 4; + int r = 0; + int try = 0; + int forced = 0; + union drbd_state_t mask, val; + enum drbd_disk_state nps; + + if (new_role == Primary) + request_ping(mdev); /* Detect a dead peer ASAP */ + + mutex_lock(&mdev->state_mutex); + + mask.i = 0; mask.role = role_mask; + val.i = 0; val.role = new_role; + + while (try++ < max_tries) { + DRBD_STATE_DEBUG_INIT_VAL(val); + r = _drbd_request_state(mdev, mask, val, ChgWaitComplete); + + /* in case we first succeeded to outdate, + * but now suddenly could establish a connection */ + if (r == SS_CW_FailedByPeer && mask.pdsk != 0) { + val.pdsk = 0; + mask.pdsk = 0; + continue; + } + + if (r == SS_NoUpToDateDisk && force && + (mdev->state.disk == Inconsistent || + mdev->state.disk == Outdated)) { + mask.disk = disk_mask; + val.disk = UpToDate; + forced = 1; + continue; + } + + if (r == SS_NoUpToDateDisk && + mdev->state.disk == Consistent) { + D_ASSERT(mdev->state.pdsk == DUnknown); + nps = drbd_try_outdate_peer(mdev); + + if (nps == Outdated) { + val.disk = UpToDate; + mask.disk = disk_mask; + } + + val.pdsk = nps; + mask.pdsk = disk_mask; + + continue; + } + + if (r == SS_NothingToDo) + goto fail; + if (r == SS_PrimaryNOP) { + nps = drbd_try_outdate_peer(mdev); + + if (force && nps > Outdated) { + drbd_WARN("Forced into split brain situation!\n"); + nps = Outdated; + } + + mask.pdsk = disk_mask; + val.pdsk = nps; + + continue; + } + if (r == SS_TwoPrimaries) { + /* Maybe the peer is detected as dead very soon... + retry at most once more in this case. */ + __set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout((mdev->net_conf->ping_timeo+1)*HZ/10); + if (try < max_tries) + try = max_tries - 1; + continue; + } + if (r < SS_Success) { + DRBD_STATE_DEBUG_INIT_VAL(val); + r = _drbd_request_state(mdev, mask, val, + ChgStateVerbose + ChgWaitComplete); + if (r < SS_Success) + goto fail; + } + break; + } + + if (forced) + drbd_WARN("Forced to consider local data as UpToDate!\n"); + + fsync_bdev(mdev->this_bdev); + + /* Wait until nothing is on the fly :) */ + wait_event(mdev->misc_wait, atomic_read(&mdev->ap_pending_cnt) == 0); + + /* FIXME RACE here: if our direct user is not using bd_claim (i.e. + * not a filesystem) since cstate might still be >= Connected, new + * ap requests may come in and increase ap_pending_cnt again! + * but that means someone is misusing DRBD... + * */ + + if (new_role == Secondary) { + set_disk_ro(mdev->vdisk, TRUE); + if (inc_local(mdev)) { + mdev->bc->md.uuid[Current] &= ~(u64)1; + dec_local(mdev); + } + } else { + if (inc_net(mdev)) { + mdev->net_conf->want_lose = 0; + dec_net(mdev); + } + set_disk_ro(mdev->vdisk, FALSE); + if (inc_local(mdev)) { + if (((mdev->state.conn < Connected || + mdev->state.pdsk <= Failed) + && mdev->bc->md.uuid[Bitmap] == 0) || forced) + drbd_uuid_new_current(mdev); + + mdev->bc->md.uuid[Current] |= (u64)1; + dec_local(mdev); + } + } + + if ((new_role == Secondary) && inc_local(mdev)) { + drbd_al_to_on_disk_bm(mdev); + dec_local(mdev); + } + + if (mdev->state.conn >= WFReportParams) { + /* if this was forced, we should consider sync */ + if (forced) + drbd_send_uuids(mdev); + drbd_send_state(mdev); + } + + drbd_md_sync(mdev); + + fail: + mutex_unlock(&mdev->state_mutex); + return r; +} + + +STATIC int drbd_nl_primary(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + struct primary primary_args; + + memset(&primary_args, 0, sizeof(struct primary)); + if (!primary_from_tags(mdev, nlp->tag_list, &primary_args)) { + reply->ret_code = UnknownMandatoryTag; + return 0; + } + + reply->ret_code = + drbd_set_role(mdev, Primary, primary_args.overwrite_peer); + + return 0; +} + +STATIC int drbd_nl_secondary(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + reply->ret_code = drbd_set_role(mdev, Secondary, 0); + + return 0; +} + +/* initializes the md.*_offset members, so we are able to find + * the on disk meta data */ +STATIC void drbd_md_set_sector_offsets(struct drbd_conf *mdev, + struct drbd_backing_dev *bdev) +{ + sector_t md_size_sect = 0; + switch (bdev->dc.meta_dev_idx) { + default: + /* v07 style fixed size indexed meta data */ + bdev->md.md_size_sect = MD_RESERVED_SECT; + bdev->md.md_offset = drbd_md_ss__(mdev, bdev); + bdev->md.al_offset = MD_AL_OFFSET; + bdev->md.bm_offset = MD_BM_OFFSET; + break; + case DRBD_MD_INDEX_FLEX_EXT: + /* just occupy the full device; unit: sectors */ + bdev->md.md_size_sect = drbd_get_capacity(bdev->md_bdev); + bdev->md.md_offset = 0; + bdev->md.al_offset = MD_AL_OFFSET; + bdev->md.bm_offset = MD_BM_OFFSET; + break; + case DRBD_MD_INDEX_INTERNAL: + case DRBD_MD_INDEX_FLEX_INT: + bdev->md.md_offset = drbd_md_ss__(mdev, bdev); + /* al size is still fixed */ + bdev->md.al_offset = -MD_AL_MAX_SIZE; + /* LGE FIXME max size check missing. */ + /* we need (slightly less than) ~ this much bitmap sectors: */ + md_size_sect = drbd_get_capacity(bdev->backing_bdev); + md_size_sect = ALIGN(md_size_sect, BM_SECT_PER_EXT); + md_size_sect = BM_SECT_TO_EXT(md_size_sect); + md_size_sect = ALIGN(md_size_sect, 8); + + /* plus the "drbd meta data super block", + * and the activity log; */ + md_size_sect += MD_BM_OFFSET; + + bdev->md.md_size_sect = md_size_sect; + /* bitmap offset is adjusted by 'super' block size */ + bdev->md.bm_offset = -md_size_sect + MD_AL_OFFSET; + break; + } +} + +char *ppsize(char *buf, unsigned long long size) +{ + /* Needs 9 bytes at max. */ + static char units[] = { 'K', 'M', 'G', 'T', 'P', 'E' }; + int base = 0; + while (size >= 10000) { + /* shift + round */ + size = (size >> 10) + !!(size & (1<<9)); + base++; + } + sprintf(buf, "%lu %cB", (long)size, units[base]); + + return buf; +} + +/* there is still a theoretical deadlock when called from receiver + * on an Inconsistent Primary: + * remote READ does inc_ap_bio, receiver would need to receive answer + * packet from remote to dec_ap_bio again. + * receiver receive_sizes(), comes here, + * waits for ap_bio_cnt == 0. -> deadlock. + * but this cannot happen, actually, because: + * Primary Inconsistent, and peer's disk is unreachable + * (not connected, * or bad/no disk on peer): + * see drbd_fail_request_early, ap_bio_cnt is zero. + * Primary Inconsistent, and SyncTarget: + * peer may not initiate a resize. + */ +void drbd_suspend_io(struct drbd_conf *mdev) +{ + int in_flight; + set_bit(SUSPEND_IO, &mdev->flags); + in_flight = atomic_read(&mdev->ap_bio_cnt); + if (in_flight) + wait_event(mdev->misc_wait, !atomic_read(&mdev->ap_bio_cnt)); +} + +void drbd_resume_io(struct drbd_conf *mdev) +{ + clear_bit(SUSPEND_IO, &mdev->flags); + wake_up(&mdev->misc_wait); +} + +/** + * drbd_determin_dev_size: + * Evaluates all constraints and sets our correct device size. + * Negative return values indicate errors. 0 and positive values + * indicate success. + * You should call drbd_md_sync() after calling this function. + */ +enum determin_dev_size_enum drbd_determin_dev_size(struct drbd_conf *mdev) __must_hold(local) +{ + sector_t prev_first_sect, prev_size; /* previous meta location */ + sector_t la_size; + sector_t size; + char ppb[10]; + + int md_moved, la_size_changed; + enum determin_dev_size_enum rv = unchanged; + + /* race: + * application request passes inc_ap_bio, + * but then cannot get an AL-reference. + * this function later may wait on ap_bio_cnt == 0. -> deadlock. + * + * to avoid that: + * Suspend IO right here. + * still lock the act_log to not trigger ASSERTs there. + */ + drbd_suspend_io(mdev); + + /* no wait necessary anymore, actually we could assert that */ + wait_event(mdev->al_wait, lc_try_lock(mdev->act_log)); + + prev_first_sect = drbd_md_first_sector(mdev->bc); + prev_size = mdev->bc->md.md_size_sect; + la_size = mdev->bc->md.la_size_sect; + + /* TODO: should only be some assert here, not (re)init... */ + drbd_md_set_sector_offsets(mdev, mdev->bc); + + size = drbd_new_dev_size(mdev, mdev->bc); + + if (drbd_get_capacity(mdev->this_bdev) != size || + drbd_bm_capacity(mdev) != size) { + int err; + err = drbd_bm_resize(mdev, size); + if (unlikely(err)) { + /* currently there is only one error: ENOMEM! */ + size = drbd_bm_capacity(mdev)>>1; + if (size == 0) { + ERR("OUT OF MEMORY! " + "Could not allocate bitmap! "); + } else { + /* FIXME this is problematic, + * if we in fact are smaller now! */ + ERR("BM resizing failed. " + "Leaving size unchanged at size = %lu KB\n", + (unsigned long)size); + } + rv = dev_size_error; + } + /* racy, see comments above. */ + drbd_set_my_capacity(mdev, size); + mdev->bc->md.la_size_sect = size; + INFO("size = %s (%llu KB)\n", ppsize(ppb, size>>1), + (unsigned long long)size>>1); + } + if (rv == dev_size_error) + goto out; + + la_size_changed = (la_size != mdev->bc->md.la_size_sect); + + md_moved = prev_first_sect != drbd_md_first_sector(mdev->bc) + || prev_size != mdev->bc->md.md_size_sect; + + if (md_moved) { + drbd_WARN("Moving meta-data.\n"); + /* assert: (flexible) internal meta data */ + } + + if (la_size_changed || md_moved) { + drbd_al_shrink(mdev); /* All extents inactive. */ + INFO("Writing the whole bitmap, size changed\n"); + rv = drbd_bitmap_io(mdev, &drbd_bm_write, "size changed"); + drbd_md_mark_dirty(mdev); + } + + if (size > la_size) + rv = grew; + if (size < la_size) + rv = shrunk; +out: + lc_unlock(mdev->act_log); + wake_up(&mdev->al_wait); + drbd_resume_io(mdev); + + return rv; +} + +sector_t +drbd_new_dev_size(struct drbd_conf *mdev, struct drbd_backing_dev *bdev) +{ + sector_t p_size = mdev->p_size; /* partner's disk size. */ + sector_t la_size = bdev->md.la_size_sect; /* last agreed size. */ + sector_t m_size; /* my size */ + sector_t u_size = bdev->dc.disk_size; /* size requested by user. */ + sector_t size = 0; + + m_size = drbd_get_max_capacity(bdev); + + if (p_size && m_size) { + size = min_t(sector_t, p_size, m_size); + } else { + if (la_size) { + size = la_size; + if (m_size && m_size < size) + size = m_size; + if (p_size && p_size < size) + size = p_size; + } else { + if (m_size) + size = m_size; + if (p_size) + size = p_size; + } + } + + if (size == 0) + ERR("Both nodes diskless!\n"); + + if (u_size) { + if (u_size > size) + ERR("Requested disk size is too big (%lu > %lu)\n", + (unsigned long)u_size>>1, (unsigned long)size>>1); + else + size = u_size; + } + + return size; +} + +/** + * drbd_check_al_size: + * checks that the al lru is of requested size, and if neccessary tries to + * allocate a new one. returns -EBUSY if current al lru is still used, + * -ENOMEM when allocation failed, and 0 on success. You should call + * drbd_md_sync() after you called this function. + */ +STATIC int drbd_check_al_size(struct drbd_conf *mdev) +{ + struct lru_cache *n, *t; + struct lc_element *e; + unsigned int in_use; + int i; + + ERR_IF(mdev->sync_conf.al_extents < 7) + mdev->sync_conf.al_extents = 127; + + if (mdev->act_log && + mdev->act_log->nr_elements == mdev->sync_conf.al_extents) + return 0; + + in_use = 0; + t = mdev->act_log; + n = lc_alloc("act_log", mdev->sync_conf.al_extents, + sizeof(struct lc_element), mdev); + + if (n == NULL) { + ERR("Cannot allocate act_log lru!\n"); + return -ENOMEM; + } + spin_lock_irq(&mdev->al_lock); + if (t) { + for (i = 0; i < t->nr_elements; i++) { + e = lc_entry(t, i); + if (e->refcnt) + ERR("refcnt(%d)==%d\n", + e->lc_number, e->refcnt); + in_use += e->refcnt; + } + } + if (!in_use) + mdev->act_log = n; + spin_unlock_irq(&mdev->al_lock); + if (in_use) { + ERR("Activity log still in use!\n"); + lc_free(n); + return -EBUSY; + } else { + if (t) + lc_free(t); + } + drbd_md_mark_dirty(mdev); /* we changed mdev->act_log->nr_elemens */ + return 0; +} + +void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int max_seg_s) __must_hold(local) +{ + struct request_queue * const q = mdev->rq_queue; + struct request_queue * const b = mdev->bc->backing_bdev->bd_disk->queue; + /* unsigned int old_max_seg_s = q->max_segment_size; */ + int max_segments = mdev->bc->dc.max_bio_bvecs; + + if (b->merge_bvec_fn && !mdev->bc->dc.use_bmbv) + max_seg_s = PAGE_SIZE; + + max_seg_s = min(b->max_sectors * b->hardsect_size, max_seg_s); + + MTRACE(TraceTypeRq, TraceLvlSummary, + DUMPI(b->max_sectors); + DUMPI(b->max_phys_segments); + DUMPI(b->max_hw_segments); + DUMPI(b->max_segment_size); + DUMPI(b->hardsect_size); + DUMPI(b->seg_boundary_mask); + ); + + q->max_sectors = max_seg_s >> 9; + if (max_segments) { + q->max_phys_segments = max_segments; + q->max_hw_segments = max_segments; + } else { + q->max_phys_segments = MAX_PHYS_SEGMENTS; + q->max_hw_segments = MAX_HW_SEGMENTS; + } + q->max_segment_size = max_seg_s; + q->hardsect_size = 512; + q->seg_boundary_mask = PAGE_SIZE-1; + blk_queue_stack_limits(q, b); + + /* KERNEL BUG. in ll_rw_blk.c ?? + * t->max_segment_size = min(t->max_segment_size,b->max_segment_size); + * should be + * t->max_segment_size = min_not_zero(...,...) + * workaround here: */ + if (q->max_segment_size == 0) + q->max_segment_size = max_seg_s; + + MTRACE(TraceTypeRq, TraceLvlSummary, + DUMPI(q->max_sectors); + DUMPI(q->max_phys_segments); + DUMPI(q->max_hw_segments); + DUMPI(q->max_segment_size); + DUMPI(q->hardsect_size); + DUMPI(q->seg_boundary_mask); + ); + + if (b->merge_bvec_fn) + drbd_WARN("Backing device's merge_bvec_fn() = %p\n", + b->merge_bvec_fn); + INFO("max_segment_size ( = BIO size ) = %u\n", q->max_segment_size); + + if (q->backing_dev_info.ra_pages != b->backing_dev_info.ra_pages) { + INFO("Adjusting my ra_pages to backing device's (%lu -> %lu)\n", + q->backing_dev_info.ra_pages, + b->backing_dev_info.ra_pages); + q->backing_dev_info.ra_pages = b->backing_dev_info.ra_pages; + } +} + +/* does always return 0; + * interesting return code is in reply->ret_code */ +STATIC int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + enum ret_codes retcode; + enum determin_dev_size_enum dd; + sector_t max_possible_sectors; + sector_t min_md_device_sectors; + struct drbd_backing_dev *nbc = NULL; /* new_backing_conf */ + struct inode *inode, *inode2; + struct lru_cache *resync_lru = NULL; + union drbd_state_t ns, os; + int rv, ntries = 0; + + /* if you want to reconfigure, please tear down first */ + if (mdev->state.disk > Diskless) { + retcode = HaveDiskConfig; + goto fail; + } + + /* + * We may have gotten here very quickly from a detach. Wait for a bit + * then fail. + */ + while (1) { + __no_warn(local, nbc = mdev->bc; ); + if (nbc == NULL) + break; + if (ntries++ >= 5) { + drbd_WARN("drbd_nl_disk_conf: mdev->bc not NULL.\n"); + retcode = HaveDiskConfig; + goto fail; + } + __set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ/10); + } + + nbc = kmalloc(sizeof(struct drbd_backing_dev), GFP_KERNEL); + if (!nbc) { + retcode = KMallocFailed; + goto fail; + } + + memset(&nbc->md, 0, sizeof(struct drbd_md)); + + if (!(nlp->flags & DRBD_NL_SET_DEFAULTS) && inc_local(mdev)) { + memcpy(&nbc->dc, &mdev->bc->dc, sizeof(struct disk_conf)); + dec_local(mdev); + } else { + memset(&nbc->dc, 0, sizeof(struct disk_conf)); + nbc->dc.disk_size = DRBD_DISK_SIZE_SECT_DEF; + nbc->dc.on_io_error = DRBD_ON_IO_ERROR_DEF; + nbc->dc.fencing = DRBD_FENCING_DEF; + nbc->dc.max_bio_bvecs= DRBD_MAX_BIO_BVECS_DEF; + } + + if (!disk_conf_from_tags(mdev, nlp->tag_list, &nbc->dc)) { + retcode = UnknownMandatoryTag; + goto fail; + } + + nbc->lo_file = NULL; + nbc->md_file = NULL; + + if (nbc->dc.meta_dev_idx < DRBD_MD_INDEX_FLEX_INT) { + retcode = LDMDInvalid; + goto fail; + } + + nbc->lo_file = filp_open(nbc->dc.backing_dev, O_RDWR, 0); + if (IS_ERR(nbc->lo_file)) { + ERR("open(\"%s\") failed with %ld\n", nbc->dc.backing_dev, + PTR_ERR(nbc->lo_file)); + nbc->lo_file = NULL; + retcode = LDNameInvalid; + goto fail; + } + + inode = nbc->lo_file->f_dentry->d_inode; + + if (!S_ISBLK(inode->i_mode)) { + retcode = LDNoBlockDev; + goto fail; + } + + nbc->md_file = filp_open(nbc->dc.meta_dev, O_RDWR, 0); + if (IS_ERR(nbc->md_file)) { + ERR("open(\"%s\") failed with %ld\n", nbc->dc.meta_dev, + PTR_ERR(nbc->md_file)); + nbc->md_file = NULL; + retcode = MDNameInvalid; + goto fail; + } + + inode2 = nbc->md_file->f_dentry->d_inode; + + if (!S_ISBLK(inode2->i_mode)) { + retcode = MDNoBlockDev; + goto fail; + } + + nbc->backing_bdev = inode->i_bdev; + if (bd_claim(nbc->backing_bdev, mdev)) { + printk(KERN_ERR "drbd: bd_claim(%p,%p); failed [%p;%p;%u]\n", + nbc->backing_bdev, mdev, + nbc->backing_bdev->bd_holder, + nbc->backing_bdev->bd_contains->bd_holder, + nbc->backing_bdev->bd_holders); + retcode = LDMounted; + goto fail; + } + + resync_lru = lc_alloc("resync", 61, sizeof(struct bm_extent), mdev); + if (!resync_lru) { + retcode = KMallocFailed; + goto fail; + } + + if (!mdev->bitmap) { + if(drbd_bm_init(mdev)) { + retcode = KMallocFailed; + goto fail; + } + } + + nbc->md_bdev = inode2->i_bdev; + if (bd_claim(nbc->md_bdev, + (nbc->dc.meta_dev_idx == DRBD_MD_INDEX_INTERNAL || + nbc->dc.meta_dev_idx == DRBD_MD_INDEX_FLEX_INT) ? + (void *)mdev : (void *) drbd_m_holder)) { + retcode = MDMounted; + goto release_bdev_fail; + } + + if ((nbc->backing_bdev == nbc->md_bdev) != + (nbc->dc.meta_dev_idx == DRBD_MD_INDEX_INTERNAL || + nbc->dc.meta_dev_idx == DRBD_MD_INDEX_FLEX_INT)) { + retcode = LDMDInvalid; + goto release_bdev2_fail; + } + + /* RT - for drbd_get_max_capacity() DRBD_MD_INDEX_FLEX_INT */ + drbd_md_set_sector_offsets(mdev, nbc); + + if (drbd_get_max_capacity(nbc) < nbc->dc.disk_size) { + ERR("max capacity %llu smaller than disk size %llu\n", + (unsigned long long) drbd_get_max_capacity(nbc), + (unsigned long long) nbc->dc.disk_size); + retcode = LDDeviceTooSmall; + goto release_bdev2_fail; + } + + if (nbc->dc.meta_dev_idx < 0) { + max_possible_sectors = DRBD_MAX_SECTORS_FLEX; + /* at least one MB, otherwise it does not make sense */ + min_md_device_sectors = (2<<10); + } else { + max_possible_sectors = DRBD_MAX_SECTORS; + min_md_device_sectors = MD_RESERVED_SECT * (nbc->dc.meta_dev_idx + 1); + } + + if (drbd_get_capacity(nbc->md_bdev) > max_possible_sectors) + drbd_WARN("truncating very big lower level device " + "to currently maximum possible %llu sectors\n", + (unsigned long long) max_possible_sectors); + + if (drbd_get_capacity(nbc->md_bdev) < min_md_device_sectors) { + retcode = MDDeviceTooSmall; + drbd_WARN("refusing attach: md-device too small, " + "at least %llu sectors needed for this meta-disk type\n", + (unsigned long long) min_md_device_sectors); + goto release_bdev2_fail; + } + + /* Make sure the new disk is big enough + * (we may currently be Primary with no local disk...) */ + if (drbd_get_max_capacity(nbc) < + drbd_get_capacity(mdev->this_bdev)) { + retcode = LDDeviceTooSmall; + goto release_bdev2_fail; + } + + nbc->known_size = drbd_get_capacity(nbc->backing_bdev); + + drbd_suspend_io(mdev); + wait_event(mdev->misc_wait, !atomic_read(&mdev->ap_pending_cnt)); + retcode = _drbd_request_state(mdev, NS(disk, Attaching), ChgStateVerbose); + drbd_resume_io(mdev); + if (retcode < SS_Success) + goto release_bdev2_fail; + + if (!inc_local_if_state(mdev, Attaching)) + goto force_diskless; + + drbd_thread_start(&mdev->worker); + drbd_md_set_sector_offsets(mdev, nbc); + + retcode = drbd_md_read(mdev, nbc); + if (retcode != NoError) + goto force_diskless_dec; + + if (mdev->state.conn < Connected && + mdev->state.role == Primary && + (mdev->ed_uuid & ~((u64)1)) != (nbc->md.uuid[Current] & ~((u64)1))) { + ERR("Can only attach to data with current UUID=%016llX\n", + (unsigned long long)mdev->ed_uuid); + retcode = DataOfWrongCurrent; + goto force_diskless_dec; + } + + /* Since we are diskless, fix the AL first... */ + if (drbd_check_al_size(mdev)) { + retcode = KMallocFailed; + goto force_diskless_dec; + } + + /* Prevent shrinking of consistent devices ! */ + if (drbd_md_test_flag(nbc, MDF_Consistent) && + drbd_new_dev_size(mdev, nbc) < nbc->md.la_size_sect) { + drbd_WARN("refusing to truncate a consistent device\n"); + retcode = LDDeviceTooSmall; + goto force_diskless_dec; + } + + if (!drbd_al_read_log(mdev, nbc)) { + retcode = MDIOError; + goto force_diskless_dec; + } + + /* Reset the "barriers don't work" bits here, then force meta data to + * be written, to ensure we determine if barriers are supported. */ + if (nbc->dc.no_md_flush) + set_bit(MD_NO_BARRIER, &mdev->flags); + else + clear_bit(MD_NO_BARRIER, &mdev->flags); + + /* Point of no return reached. + * Devices and memory are no longer released by error cleanup below. + * now mdev takes over responsibility, and the state engine should + * clean it up somewhere. */ + D_ASSERT(mdev->bc == NULL); + mdev->bc = nbc; + mdev->resync = resync_lru; + nbc = NULL; + resync_lru = NULL; + + mdev->write_ordering = WO_bio_barrier; + drbd_bump_write_ordering(mdev, WO_bio_barrier); + + if (drbd_md_test_flag(mdev->bc, MDF_PrimaryInd)) + set_bit(CRASHED_PRIMARY, &mdev->flags); + else + clear_bit(CRASHED_PRIMARY, &mdev->flags); + + mdev->send_cnt = 0; + mdev->recv_cnt = 0; + mdev->read_cnt = 0; + mdev->writ_cnt = 0; + + drbd_setup_queue_param(mdev, DRBD_MAX_SEGMENT_SIZE); + /* + * FIXME currently broken. + * drbd_set_recv_tcq(mdev, + * drbd_queue_order_type(mdev)==QUEUE_ORDERED_TAG); + */ + + /* If I am currently not Primary, + * but meta data primary indicator is set, + * I just now recover from a hard crash, + * and have been Primary before that crash. + * + * Now, if I had no connection before that crash + * (have been degraded Primary), chances are that + * I won't find my peer now either. + * + * In that case, and _only_ in that case, + * we use the degr-wfc-timeout instead of the default, + * so we can automatically recover from a crash of a + * degraded but active "cluster" after a certain timeout. + */ + clear_bit(USE_DEGR_WFC_T, &mdev->flags); + if (mdev->state.role != Primary && + drbd_md_test_flag(mdev->bc, MDF_PrimaryInd) && + !drbd_md_test_flag(mdev->bc, MDF_ConnectedInd)) + set_bit(USE_DEGR_WFC_T, &mdev->flags); + + dd = drbd_determin_dev_size(mdev); + if (dd == dev_size_error) { + retcode = VMallocFailed; + goto force_diskless_dec; + } else if (dd == grew) + set_bit(RESYNC_AFTER_NEG, &mdev->flags); + + if (drbd_md_test_flag(mdev->bc, MDF_FullSync)) { + INFO("Assuming that all blocks are out of sync " + "(aka FullSync)\n"); + if (drbd_bitmap_io(mdev, &drbd_bmio_set_n_write, "set_n_write from attaching")) { + retcode = MDIOError; + goto force_diskless_dec; + } + } else { + if (drbd_bitmap_io(mdev, &drbd_bm_read, "read from attaching") < 0) { + retcode = MDIOError; + goto force_diskless_dec; + } + } + + if (test_bit(CRASHED_PRIMARY, &mdev->flags)) { + drbd_al_apply_to_bm(mdev); + drbd_al_to_on_disk_bm(mdev); + } + /* else { + FIXME wipe out on disk al! + } */ + + spin_lock_irq(&mdev->req_lock); + os = mdev->state; + ns.i = os.i; + /* If MDF_Consistent is not set go into inconsistent state, + otherwise investige MDF_WasUpToDate... + If MDF_WasUpToDate is not set go into Outdated disk state, + otherwise into Consistent state. + */ + if (drbd_md_test_flag(mdev->bc, MDF_Consistent)) { + if (drbd_md_test_flag(mdev->bc, MDF_WasUpToDate)) + ns.disk = Consistent; + else + ns.disk = Outdated; + } else { + ns.disk = Inconsistent; + } + + if (drbd_md_test_flag(mdev->bc, MDF_PeerOutDated)) + ns.pdsk = Outdated; + + if ( ns.disk == Consistent && + (ns.pdsk == Outdated || mdev->bc->dc.fencing == DontCare)) + ns.disk = UpToDate; + + /* All tests on MDF_PrimaryInd, MDF_ConnectedInd, + MDF_Consistent and MDF_WasUpToDate must happen before + this point, because drbd_request_state() modifies these + flags. */ + + /* In case we are Connected postpone any desicion on the new disk + state after the negotiation phase. */ + if (mdev->state.conn == Connected) { + mdev->new_state_tmp.i = ns.i; + ns.i = os.i; + ns.disk = Negotiating; + } + + DRBD_STATE_DEBUG_INIT_VAL(ns); + rv = _drbd_set_state(mdev, ns, ChgStateVerbose, NULL); + ns = mdev->state; + spin_unlock_irq(&mdev->req_lock); + + if (rv < SS_Success) + goto force_diskless_dec; + + if (mdev->state.role == Primary) + mdev->bc->md.uuid[Current] |= (u64)1; + else + mdev->bc->md.uuid[Current] &= ~(u64)1; + + drbd_md_mark_dirty(mdev); + drbd_md_sync(mdev); + + dec_local(mdev); + reply->ret_code = retcode; + return 0; + + force_diskless_dec: + dec_local(mdev); + force_diskless: + drbd_force_state(mdev, NS(disk, Diskless)); + drbd_md_sync(mdev); + release_bdev2_fail: + if (nbc) + bd_release(nbc->md_bdev); + release_bdev_fail: + if (nbc) + bd_release(nbc->backing_bdev); + fail: + if (nbc) { + if (nbc->lo_file) + fput(nbc->lo_file); + if (nbc->md_file) + fput(nbc->md_file); + kfree(nbc); + } + if (resync_lru) + lc_free(resync_lru); + + reply->ret_code = retcode; + return 0; +} + +STATIC int drbd_nl_detach(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + fsync_bdev(mdev->this_bdev); + reply->ret_code = drbd_request_state(mdev, NS(disk, Diskless)); + + __set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ/20); /* 50ms; Time for worker to finally terminate */ + + return 0; +} + +#define HMAC_NAME_L 20 + +STATIC int drbd_nl_net_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + int i, ns; + enum ret_codes retcode; + struct net_conf *new_conf = NULL; + struct crypto_hash *tfm = NULL; + struct crypto_hash *integrity_w_tfm = NULL; + struct crypto_hash *integrity_r_tfm = NULL; + struct hlist_head *new_tl_hash = NULL; + struct hlist_head *new_ee_hash = NULL; + struct drbd_conf *odev; + char hmac_name[HMAC_NAME_L]; + void *int_dig_out = NULL; + void *int_dig_in = NULL; + void *int_dig_vv = NULL; + + if (mdev->state.conn > StandAlone) { + retcode = HaveNetConfig; + goto fail; + } + + new_conf = kmalloc(sizeof(struct net_conf), GFP_KERNEL); + if (!new_conf) { + retcode = KMallocFailed; + goto fail; + } + + if (!(nlp->flags & DRBD_NL_SET_DEFAULTS) && inc_net(mdev)) { + memcpy(new_conf, mdev->net_conf, sizeof(struct net_conf)); + dec_net(mdev); + } else { + memset(new_conf, 0, sizeof(struct net_conf)); + new_conf->timeout = DRBD_TIMEOUT_DEF; + new_conf->try_connect_int = DRBD_CONNECT_INT_DEF; + new_conf->ping_int = DRBD_PING_INT_DEF; + new_conf->max_epoch_size = DRBD_MAX_EPOCH_SIZE_DEF; + new_conf->max_buffers = DRBD_MAX_BUFFERS_DEF; + new_conf->unplug_watermark = DRBD_UNPLUG_WATERMARK_DEF; + new_conf->sndbuf_size = DRBD_SNDBUF_SIZE_DEF; + new_conf->ko_count = DRBD_KO_COUNT_DEF; + new_conf->after_sb_0p = DRBD_AFTER_SB_0P_DEF; + new_conf->after_sb_1p = DRBD_AFTER_SB_1P_DEF; + new_conf->after_sb_2p = DRBD_AFTER_SB_2P_DEF; + new_conf->want_lose = 0; + new_conf->two_primaries = 0; + new_conf->wire_protocol = DRBD_PROT_C; + new_conf->ping_timeo = DRBD_PING_TIMEO_DEF; + new_conf->rr_conflict = DRBD_RR_CONFLICT_DEF; + } + + if (!net_conf_from_tags(mdev, nlp->tag_list, new_conf)) { + retcode = UnknownMandatoryTag; + goto fail; + } + + if (new_conf->two_primaries + && (new_conf->wire_protocol != DRBD_PROT_C)) { + retcode = ProtocolCRequired; + goto fail; + }; + + if (mdev->state.role == Primary && new_conf->want_lose) { + retcode = DiscardNotAllowed; + goto fail; + } + +#define M_ADDR(A) (((struct sockaddr_in *)&A->my_addr)->sin_addr.s_addr) +#define M_PORT(A) (((struct sockaddr_in *)&A->my_addr)->sin_port) +#define O_ADDR(A) (((struct sockaddr_in *)&A->peer_addr)->sin_addr.s_addr) +#define O_PORT(A) (((struct sockaddr_in *)&A->peer_addr)->sin_port) + retcode = NoError; + for (i = 0; i < minor_count; i++) { + odev = minor_to_mdev(i); + if (!odev || odev == mdev) + continue; + if (inc_net(odev)) { + if (M_ADDR(new_conf) == M_ADDR(odev->net_conf) && + M_PORT(new_conf) == M_PORT(odev->net_conf)) + retcode = LAAlreadyInUse; + + if (O_ADDR(new_conf) == O_ADDR(odev->net_conf) && + O_PORT(new_conf) == O_PORT(odev->net_conf)) + retcode = OAAlreadyInUse; + + dec_net(odev); + if (retcode != NoError) + goto fail; + } + } +#undef M_ADDR +#undef M_PORT +#undef O_ADDR +#undef O_PORT + + if (new_conf->cram_hmac_alg[0] != 0) { + snprintf(hmac_name, HMAC_NAME_L, "hmac(%s)", + new_conf->cram_hmac_alg); + tfm = crypto_alloc_hash(hmac_name, 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(tfm)) { + tfm = NULL; + retcode = CRAMAlgNotAvail; + goto fail; + } + + if (crypto_tfm_alg_type(crypto_hash_tfm(tfm)) + != CRYPTO_ALG_TYPE_HASH) { + retcode = CRAMAlgNotDigest; + goto fail; + } + } + + if (new_conf->integrity_alg[0]) { + integrity_w_tfm = crypto_alloc_hash(new_conf->integrity_alg, 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(integrity_w_tfm)) { + integrity_w_tfm = NULL; + retcode=IntegrityAlgNotAvail; + goto fail; + } + + if (crypto_tfm_alg_type(crypto_hash_tfm(integrity_w_tfm)) != CRYPTO_ALG_TYPE_DIGEST) { + retcode=IntegrityAlgNotDigest; + goto fail; + } + + integrity_r_tfm = crypto_alloc_hash(new_conf->integrity_alg, 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(integrity_r_tfm)) { + integrity_r_tfm = NULL; + retcode=IntegrityAlgNotAvail; + goto fail; + } + } + + ns = new_conf->max_epoch_size/8; + if (mdev->tl_hash_s != ns) { + new_tl_hash = kzalloc(ns*sizeof(void *), GFP_KERNEL); + if (!new_tl_hash) { + retcode = KMallocFailed; + goto fail; + } + } + + ns = new_conf->max_buffers/8; + if (new_conf->two_primaries && (mdev->ee_hash_s != ns)) { + new_ee_hash = kzalloc(ns*sizeof(void *), GFP_KERNEL); + if (!new_ee_hash) { + retcode = KMallocFailed; + goto fail; + } + } + + ((char *)new_conf->shared_secret)[SHARED_SECRET_MAX-1] = 0; + +#if 0 + /* for the connection loss logic in drbd_recv + * I _need_ the resulting timeo in jiffies to be + * non-zero and different + * + * XXX maybe rather store the value scaled to jiffies? + * Note: MAX_SCHEDULE_TIMEOUT/HZ*HZ != MAX_SCHEDULE_TIMEOUT + * and HZ > 10; which is unlikely to change... + * Thus, if interrupted by a signal, + * sock_{send,recv}msg returns -EINTR, + * if the timeout expires, -EAGAIN. + */ + /* unlikely: someone disabled the timeouts ... + * just put some huge values in there. */ + if (!new_conf->ping_int) + new_conf->ping_int = MAX_SCHEDULE_TIMEOUT/HZ; + if (!new_conf->timeout) + new_conf->timeout = MAX_SCHEDULE_TIMEOUT/HZ*10; + if (new_conf->ping_int*10 < new_conf->timeout) + new_conf->timeout = new_conf->ping_int*10/6; + if (new_conf->ping_int*10 == new_conf->timeout) + new_conf->ping_int = new_conf->ping_int+1; +#endif + + if (integrity_w_tfm) { + i = crypto_hash_digestsize(integrity_w_tfm); + int_dig_out = kmalloc(i, GFP_KERNEL); + if (!int_dig_out) { + retcode = KMallocFailed; + goto fail; + } + int_dig_in = kmalloc(i, GFP_KERNEL); + if (!int_dig_in) { + retcode = KMallocFailed; + goto fail; + } + int_dig_vv = kmalloc(i, GFP_KERNEL); + if (!int_dig_vv) { + retcode = KMallocFailed; + goto fail; + } + } + + if (!mdev->bitmap) { + if(drbd_bm_init(mdev)) { + retcode = KMallocFailed; + goto fail; + } + } + + D_ASSERT(mdev->net_conf == NULL); + mdev->net_conf = new_conf; + + mdev->send_cnt = 0; + mdev->recv_cnt = 0; + + if (new_tl_hash) { + kfree(mdev->tl_hash); + mdev->tl_hash_s = mdev->net_conf->max_epoch_size/8; + mdev->tl_hash = new_tl_hash; + } + + if (new_ee_hash) { + kfree(mdev->ee_hash); + mdev->ee_hash_s = mdev->net_conf->max_buffers/8; + mdev->ee_hash = new_ee_hash; + } + + crypto_free_hash(mdev->cram_hmac_tfm); + mdev->cram_hmac_tfm = tfm; + + crypto_free_hash(mdev->integrity_w_tfm); + mdev->integrity_w_tfm = integrity_w_tfm; + + crypto_free_hash(mdev->integrity_r_tfm); + mdev->integrity_r_tfm = integrity_r_tfm; + + kfree(mdev->int_dig_out); + kfree(mdev->int_dig_in); + kfree(mdev->int_dig_vv); + mdev->int_dig_out=int_dig_out; + mdev->int_dig_in=int_dig_in; + mdev->int_dig_vv=int_dig_vv; + + retcode = _drbd_request_state(mdev, NS(conn, Unconnected), ChgStateVerbose); + if (retcode >= SS_Success) + drbd_thread_start(&mdev->worker); + + reply->ret_code = retcode; + return 0; + +fail: + kfree(int_dig_out); + kfree(int_dig_in); + kfree(int_dig_vv); + crypto_free_hash(tfm); + crypto_free_hash(integrity_w_tfm); + crypto_free_hash(integrity_r_tfm); + kfree(new_tl_hash); + kfree(new_ee_hash); + kfree(new_conf); + + reply->ret_code = retcode; + return 0; +} + +STATIC int drbd_nl_disconnect(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + int retcode; + + retcode = _drbd_request_state(mdev, NS(conn, Disconnecting), ChgOrdered); + + if (retcode == SS_NothingToDo) + goto done; + else if (retcode == SS_AlreadyStandAlone) + goto done; + else if (retcode == SS_PrimaryNOP) { + /* Our statche checking code wants to see the peer outdated. */ + retcode = drbd_request_state(mdev, NS2(conn, Disconnecting, + pdsk, Outdated)); + } else if (retcode == SS_CW_FailedByPeer) { + /* The peer probabely wants to see us outdated. */ + retcode = _drbd_request_state(mdev, NS2(conn, Disconnecting, + disk, Outdated), + ChgOrdered); + if (retcode == SS_IsDiskLess || retcode == SS_LowerThanOutdated) { + drbd_force_state(mdev, NS(conn, Disconnecting)); + retcode = SS_Success; + } + } + + if (retcode < SS_Success) + goto fail; + + if (wait_event_interruptible(mdev->state_wait, + mdev->state.conn != Disconnecting)) { + /* Do not test for mdev->state.conn == StandAlone, since + someone else might connect us in the mean time! */ + retcode = GotSignal; + goto fail; + } + + done: + retcode = NoError; + fail: + drbd_md_sync(mdev); + reply->ret_code = retcode; + return 0; +} + +void resync_after_online_grow(struct drbd_conf *mdev) +{ + int iass; /* I am sync source */ + + INFO("Resync of new storage after online grow\n"); + if (mdev->state.role != mdev->state.peer) + iass = (mdev->state.role == Primary); + else + iass = test_bit(DISCARD_CONCURRENT, &mdev->flags); + + if (iass) + drbd_start_resync(mdev, SyncSource); + else + _drbd_request_state(mdev, NS(conn, WFSyncUUID), ChgStateVerbose + ChgSerialize); +} + +STATIC int drbd_nl_resize(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + struct resize rs; + int retcode = NoError; + int ldsc = 0; /* local disk size changed */ + enum determin_dev_size_enum dd; + + memset(&rs, 0, sizeof(struct resize)); + if (!resize_from_tags(mdev, nlp->tag_list, &rs)) { + retcode = UnknownMandatoryTag; + goto fail; + } + + if (mdev->state.conn > Connected) { + retcode = NoResizeDuringResync; + goto fail; + } + + if (mdev->state.role == Secondary && + mdev->state.peer == Secondary) { + retcode = APrimaryNodeNeeded; + goto fail; + } + + if (!inc_local(mdev)) { + retcode = HaveNoDiskConfig; + goto fail; + } + + if (mdev->bc->known_size != drbd_get_capacity(mdev->bc->backing_bdev)) { + mdev->bc->known_size = drbd_get_capacity(mdev->bc->backing_bdev); + ldsc = 1; + } + + mdev->bc->dc.disk_size = (sector_t)rs.resize_size; + dd = drbd_determin_dev_size(mdev); + drbd_md_sync(mdev); + dec_local(mdev); + if (dd == dev_size_error) { + retcode = VMallocFailed; + goto fail; + } + + if (mdev->state.conn == Connected && (dd != unchanged || ldsc)) { + drbd_send_uuids(mdev); + drbd_send_sizes(mdev); + if (dd == grew) + resync_after_online_grow(mdev); + } + + fail: + reply->ret_code = retcode; + return 0; +} + +STATIC int drbd_nl_syncer_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + int retcode = NoError; + int err; + int ovr; /* online verify running */ + int rsr; /* re-sync running */ + struct drbd_conf *odev; + struct crypto_hash *verify_tfm = NULL; + struct crypto_hash *csums_tfm = NULL; + struct syncer_conf sc; + cpumask_t n_cpu_mask = CPU_MASK_NONE; + + memcpy(&sc, &mdev->sync_conf, sizeof(struct syncer_conf)); + + if (nlp->flags & DRBD_NL_SET_DEFAULTS) { + memset(&sc, 0, sizeof(struct syncer_conf)); + sc.rate = DRBD_RATE_DEF; + sc.after = DRBD_AFTER_DEF; + sc.al_extents = DRBD_AL_EXTENTS_DEF; + } + + if (!syncer_conf_from_tags(mdev, nlp->tag_list, &sc)) { + retcode = UnknownMandatoryTag; + goto fail; + } + + if (sc.after != -1) { + if (sc.after < -1 || minor_to_mdev(sc.after) == NULL) { + retcode = SyncAfterInvalid; + goto fail; + } + odev = minor_to_mdev(sc.after); /* check against loops in */ + while (1) { + if (odev == mdev) { + retcode = SyncAfterCycle; + goto fail; + } + if (odev->sync_conf.after == -1) + break; /* no cycles. */ + odev = minor_to_mdev(odev->sync_conf.after); + } + } + + /* re-sync running */ + rsr = ( mdev->state.conn == SyncSource || + mdev->state.conn == SyncTarget || + mdev->state.conn == PausedSyncS || + mdev->state.conn == PausedSyncT ); + + if (rsr && strcmp(sc.csums_alg, mdev->sync_conf.csums_alg)) { + retcode = CSUMSResyncRunning; + goto fail; + } + + if (!rsr && sc.csums_alg[0]) { + csums_tfm = crypto_alloc_hash(sc.csums_alg, 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(csums_tfm)) { + csums_tfm = NULL; + retcode = CSUMSAlgNotAvail; + goto fail; + } + + if (crypto_tfm_alg_type(crypto_hash_tfm(csums_tfm)) != CRYPTO_ALG_TYPE_DIGEST) { + retcode = CSUMSAlgNotDigest; + goto fail; + } + } + + /* online verify running */ + ovr = (mdev->state.conn == VerifyS || mdev->state.conn == VerifyT); + + if (ovr) { + if (strcmp(sc.verify_alg, mdev->sync_conf.verify_alg)) { + retcode = VERIFYIsRunning; + goto fail; + } + } + + if (!ovr && sc.verify_alg[0]) { + verify_tfm = crypto_alloc_hash(sc.verify_alg, 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(verify_tfm)) { + verify_tfm = NULL; + retcode = VERIFYAlgNotAvail; + goto fail; + } + + if (crypto_tfm_alg_type(crypto_hash_tfm(verify_tfm)) != CRYPTO_ALG_TYPE_DIGEST) { + retcode = VERIFYAlgNotDigest; + goto fail; + } + } + + if (sc.cpu_mask[0] != 0) { + err = __bitmap_parse(sc.cpu_mask, 32, 0, (unsigned long *)&n_cpu_mask, NR_CPUS); + if (err) { + drbd_WARN("__bitmap_parse() failed with %d\n", err); + retcode = CPUMaskParseFailed; + goto fail; + } + } + + ERR_IF (sc.rate < 1) sc.rate = 1; + ERR_IF (sc.al_extents < 7) sc.al_extents = 127; /* arbitrary minimum */ +#define AL_MAX ((MD_AL_MAX_SIZE-1) * AL_EXTENTS_PT) + if (sc.al_extents > AL_MAX) { + ERR("sc.al_extents > %d\n", AL_MAX); + sc.al_extents = AL_MAX; + } +#undef AL_MAX + + spin_lock(&mdev->peer_seq_lock); + /* lock against receive_SyncParam() */ + mdev->sync_conf = sc; + + if (!rsr) { + crypto_free_hash(mdev->csums_tfm); + mdev->csums_tfm = csums_tfm; + csums_tfm = NULL; + } + + if (!ovr) { + crypto_free_hash(mdev->verify_tfm); + mdev->verify_tfm = verify_tfm; + verify_tfm = NULL; + } + spin_unlock(&mdev->peer_seq_lock); + + if (inc_local(mdev)) { + wait_event(mdev->al_wait, lc_try_lock(mdev->act_log)); + drbd_al_shrink(mdev); + err = drbd_check_al_size(mdev); + lc_unlock(mdev->act_log); + wake_up(&mdev->al_wait); + + dec_local(mdev); + drbd_md_sync(mdev); + + if (err) { + retcode = KMallocFailed; + goto fail; + } + } + + if (mdev->state.conn >= Connected) + drbd_send_sync_param(mdev, &sc); + + drbd_alter_sa(mdev, sc.after); + + if (!cpus_equal(mdev->cpu_mask, n_cpu_mask)) { + mdev->cpu_mask = n_cpu_mask; + mdev->cpu_mask = drbd_calc_cpu_mask(mdev); + mdev->receiver.reset_cpu_mask = 1; + mdev->asender.reset_cpu_mask = 1; + mdev->worker.reset_cpu_mask = 1; + } + +fail: + crypto_free_hash(csums_tfm); + crypto_free_hash(verify_tfm); + reply->ret_code = retcode; + return 0; +} + +STATIC int drbd_nl_invalidate(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + int retcode; + + retcode = _drbd_request_state(mdev, NS(conn, StartingSyncT), ChgOrdered); + + if (retcode < SS_Success && retcode != SS_NeedConnection) + retcode = drbd_request_state(mdev, NS(conn, StartingSyncT)); + + while (retcode == SS_NeedConnection) { + spin_lock_irq(&mdev->req_lock); + if (mdev->state.conn < Connected) + retcode = _drbd_set_state(_NS(mdev, disk, Inconsistent), ChgStateVerbose, NULL); + spin_unlock_irq(&mdev->req_lock); + + if (retcode != SS_NeedConnection) + break; + + retcode = drbd_request_state(mdev, NS(conn, StartingSyncT)); + } + + reply->ret_code = retcode; + return 0; +} + +STATIC int drbd_nl_invalidate_peer(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + + reply->ret_code = drbd_request_state(mdev, NS(conn, StartingSyncS)); + + return 0; +} + +STATIC int drbd_nl_pause_sync(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + int retcode = NoError; + + if (drbd_request_state(mdev, NS(user_isp, 1)) == SS_NothingToDo) + retcode = PauseFlagAlreadySet; + + reply->ret_code = retcode; + return 0; +} + +STATIC int drbd_nl_resume_sync(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + int retcode = NoError; + + if (drbd_request_state(mdev, NS(user_isp, 0)) == SS_NothingToDo) + retcode = PauseFlagAlreadyClear; + + reply->ret_code = retcode; + return 0; +} + +STATIC int drbd_nl_suspend_io(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + reply->ret_code = drbd_request_state(mdev, NS(susp, 1)); + + return 0; +} + +STATIC int drbd_nl_resume_io(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + reply->ret_code = drbd_request_state(mdev, NS(susp, 0)); + return 0; +} + +STATIC int drbd_nl_outdate(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + reply->ret_code = drbd_request_state(mdev, NS(disk, Outdated)); + return 0; +} + +STATIC int drbd_nl_get_config(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + unsigned short *tl; + + tl = reply->tag_list; + + if (inc_local(mdev)) { + tl = disk_conf_to_tags(mdev, &mdev->bc->dc, tl); + dec_local(mdev); + } + + if (inc_net(mdev)) { + tl = net_conf_to_tags(mdev, mdev->net_conf, tl); + dec_net(mdev); + } + tl = syncer_conf_to_tags(mdev, &mdev->sync_conf, tl); + + *tl++ = TT_END; /* Close the tag list */ + + return (int)((char *)tl - (char *)reply->tag_list); +} + +STATIC int drbd_nl_get_state(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + unsigned short *tl = reply->tag_list; + union drbd_state_t s = mdev->state; + unsigned long rs_left; + unsigned int res; + + tl = get_state_to_tags(mdev, (struct get_state *)&s, tl); + + /* no local ref, no bitmap, no syncer progress. */ + if (s.conn >= SyncSource && s.conn <= PausedSyncT) { + if (inc_local(mdev)) { + drbd_get_syncer_progress(mdev, &rs_left, &res); + *tl++ = T_sync_progress; + *tl++ = sizeof(int); + memcpy(tl, &res, sizeof(int)); + tl = (unsigned short *)((char *)tl + sizeof(int)); + dec_local(mdev); + } + } + *tl++ = TT_END; /* Close the tag list */ + + return (int)((char *)tl - (char *)reply->tag_list); +} + +STATIC int drbd_nl_get_uuids(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + unsigned short *tl; + + tl = reply->tag_list; + + if (inc_local(mdev)) { + /* This is a hand crafted add tag ;) */ + *tl++ = T_uuids; + *tl++ = UUID_SIZE*sizeof(u64); + memcpy(tl, mdev->bc->md.uuid, UUID_SIZE*sizeof(u64)); + tl = (unsigned short *)((char *)tl + UUID_SIZE*sizeof(u64)); + *tl++ = T_uuids_flags; + *tl++ = sizeof(int); + memcpy(tl, &mdev->bc->md.flags, sizeof(int)); + tl = (unsigned short *)((char *)tl + sizeof(int)); + dec_local(mdev); + } + *tl++ = TT_END; /* Close the tag list */ + + return (int)((char *)tl - (char *)reply->tag_list); +} + + +STATIC int drbd_nl_get_timeout_flag(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + unsigned short *tl; + + tl = reply->tag_list; + + /* This is a hand crafted add tag ;) */ + *tl++ = T_use_degraded; + *tl++ = sizeof(char); + *((char *)tl) = test_bit(USE_DEGR_WFC_T, &mdev->flags) ? 1 : 0 ; + tl = (unsigned short *)((char *)tl + sizeof(char)); + *tl++ = TT_END; + + return (int)((char *)tl - (char *)reply->tag_list); +} + +STATIC int drbd_nl_start_ov(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + reply->ret_code = drbd_request_state(mdev,NS(conn,VerifyS)); + + return 0; +} + + +STATIC int drbd_nl_new_c_uuid(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + int retcode = NoError; + int err; + + struct new_c_uuid args; + + memset(&args, 0, sizeof(struct new_c_uuid)); + if (!new_c_uuid_from_tags(mdev, nlp->tag_list, &args)) { + reply->ret_code = UnknownMandatoryTag; + return 0; + } + + mutex_lock(&mdev->state_mutex); /* Protects us against serialized state changes. */ + + if (mdev->state.conn >= Connected) { + retcode = MayNotBeConnected; + goto out; + } + + if (!inc_local(mdev)) { + retcode = HaveNoDiskConfig; + goto out; + } + + drbd_uuid_set(mdev, Bitmap, 0); /* Rotate Bitmap to History 1, etc... */ + drbd_uuid_new_current(mdev); /* New current, previous to Bitmap */ + + if (args.clear_bm) { + err = drbd_bitmap_io(mdev, &drbd_bmio_clear_n_write, "clear_n_write from new_c_uuid"); + if (err) { + ERR("Writing bitmap failed with %d\n",err); + retcode = MDIOError; + } + } + + drbd_md_sync(mdev); + dec_local(mdev); +out: + mutex_unlock(&mdev->state_mutex); + + reply->ret_code = retcode; + return 0; +} + +STATIC struct drbd_conf *ensure_mdev(struct drbd_nl_cfg_req *nlp) +{ + struct drbd_conf *mdev; + + mdev = minor_to_mdev(nlp->drbd_minor); + + if (!mdev && (nlp->flags & DRBD_NL_CREATE_DEVICE)) { + mdev = drbd_new_device(nlp->drbd_minor); + + spin_lock_irq(&drbd_pp_lock); + if (minor_table[nlp->drbd_minor] == NULL) { + minor_table[nlp->drbd_minor] = mdev; + mdev = NULL; + } + spin_unlock_irq(&drbd_pp_lock); + + if (mdev) { + kfree(mdev->app_reads_hash); + if (mdev->md_io_page) + __free_page(mdev->md_io_page); + kfree(mdev); + mdev = NULL; + } + + mdev = minor_to_mdev(nlp->drbd_minor); + } + + return mdev; +} + +struct cn_handler_struct { + int (*function)(struct drbd_conf *, + struct drbd_nl_cfg_req *, + struct drbd_nl_cfg_reply *); + int reply_body_size; +}; + +static struct cn_handler_struct cnd_table[] = { + [ P_primary ] = { &drbd_nl_primary, 0 }, + [ P_secondary ] = { &drbd_nl_secondary, 0 }, + [ P_disk_conf ] = { &drbd_nl_disk_conf, 0 }, + [ P_detach ] = { &drbd_nl_detach, 0 }, + [ P_net_conf ] = { &drbd_nl_net_conf, 0 }, + [ P_disconnect ] = { &drbd_nl_disconnect, 0 }, + [ P_resize ] = { &drbd_nl_resize, 0 }, + [ P_syncer_conf ] = { &drbd_nl_syncer_conf, 0 }, + [ P_invalidate ] = { &drbd_nl_invalidate, 0 }, + [ P_invalidate_peer ] = { &drbd_nl_invalidate_peer, 0 }, + [ P_pause_sync ] = { &drbd_nl_pause_sync, 0 }, + [ P_resume_sync ] = { &drbd_nl_resume_sync, 0 }, + [ P_suspend_io ] = { &drbd_nl_suspend_io, 0 }, + [ P_resume_io ] = { &drbd_nl_resume_io, 0 }, + [ P_outdate ] = { &drbd_nl_outdate, 0 }, + [ P_get_config ] = { &drbd_nl_get_config, + sizeof(struct syncer_conf_tag_len_struct) + + sizeof(struct disk_conf_tag_len_struct) + + sizeof(struct net_conf_tag_len_struct) }, + [ P_get_state ] = { &drbd_nl_get_state, + sizeof(struct get_state_tag_len_struct) + + sizeof(struct sync_progress_tag_len_struct) }, + [ P_get_uuids ] = { &drbd_nl_get_uuids, + sizeof(struct get_uuids_tag_len_struct) }, + [ P_get_timeout_flag ] = { &drbd_nl_get_timeout_flag, + sizeof(struct get_timeout_flag_tag_len_struct)}, + [ P_start_ov ] = { &drbd_nl_start_ov, 0 }, + [ P_new_c_uuid ] = { &drbd_nl_new_c_uuid, 0 }, +}; + +STATIC void drbd_connector_callback(void *data) +{ + struct cn_msg *req = data; + struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req *)req->data; + struct cn_handler_struct *cm; + struct cn_msg *cn_reply; + struct drbd_nl_cfg_reply *reply; + struct drbd_conf *mdev; + int retcode, rr; + int reply_size = sizeof(struct cn_msg) + + sizeof(struct drbd_nl_cfg_reply) + + sizeof(short int); + + if (!try_module_get(THIS_MODULE)) { + printk(KERN_ERR "drbd: try_module_get() failed!\n"); + return; + } + + mdev = ensure_mdev(nlp); + if (!mdev) { + retcode = MinorNotKnown; + goto fail; + } + + TRACE(TraceTypeNl, TraceLvlSummary, nl_trace_packet(data);); + + if (nlp->packet_type >= P_nl_after_last_packet) { + retcode = UnknownNetLinkPacket; + goto fail; + } + + cm = cnd_table + nlp->packet_type; + + /* This may happen if packet number is 0: */ + if (cm->function == NULL) { + retcode = UnknownNetLinkPacket; + goto fail; + } + + reply_size += cm->reply_body_size; + + cn_reply = kmalloc(reply_size, GFP_KERNEL); + if (!cn_reply) { + retcode = KMallocFailed; + goto fail; + } + reply = (struct drbd_nl_cfg_reply *) cn_reply->data; + + reply->packet_type = + cm->reply_body_size ? nlp->packet_type : P_nl_after_last_packet; + reply->minor = nlp->drbd_minor; + reply->ret_code = NoError; /* Might by modified by cm->function. */ + /* reply->tag_list; might be modified by cm->fucntion. */ + + rr = cm->function(mdev, nlp, reply); + + cn_reply->id = req->id; + cn_reply->seq = req->seq; + cn_reply->ack = req->ack + 1; + cn_reply->len = sizeof(struct drbd_nl_cfg_reply) + rr; + cn_reply->flags = 0; + + TRACE(TraceTypeNl, TraceLvlSummary, nl_trace_reply(cn_reply);); + + rr = cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL); + if (rr && rr != -ESRCH) + printk(KERN_INFO "drbd: cn_netlink_send()=%d\n", rr); + + kfree(cn_reply); + module_put(THIS_MODULE); + return; + fail: + drbd_nl_send_reply(req, retcode); + module_put(THIS_MODULE); +} + +static atomic_t drbd_nl_seq = ATOMIC_INIT(2); /* two. */ + +static inline unsigned short * +__tl_add_blob(unsigned short *tl, enum drbd_tags tag, const void *data, + int len, int nul_terminated) +{ + int l = tag_descriptions[tag_number(tag)].max_len; + l = (len < l) ? len : l; + *tl++ = tag; + *tl++ = len; + memcpy(tl, data, len); + /* TODO + * maybe we need to add some padding to the data stream. + * otherwise we may get strange effects on architectures + * that require certain data types to be strictly aligned, + * because now the next "unsigned short" may be misaligned. */ + tl = (unsigned short*)((char*)tl + len); + if (nul_terminated) + *((char*)tl - 1) = 0; + return tl; +} + +static inline unsigned short * +tl_add_blob(unsigned short *tl, enum drbd_tags tag, const void *data, int len) +{ + return __tl_add_blob(tl, tag, data, len, 0); +} + +static inline unsigned short * +tl_add_str(unsigned short *tl, enum drbd_tags tag, const char *str) +{ + return __tl_add_blob(tl, tag, str, strlen(str)+1, 0); +} + +static inline unsigned short * +tl_add_int(unsigned short *tl, enum drbd_tags tag, const void *val) +{ + switch(tag_type(tag)) { + case TT_INTEGER: + *tl++ = tag; + *tl++ = sizeof(int); + *(int*)tl = *(int*)val; + tl = (unsigned short*)((char*)tl+sizeof(int)); + break; + case TT_INT64: + *tl++ = tag; + *tl++ = sizeof(u64); + *(u64*)tl = *(u64*)val; + tl = (unsigned short*)((char*)tl+sizeof(u64)); + break; + default: + /* someone did something stupid. */ + ; + } + return tl; +} + +void drbd_bcast_state(struct drbd_conf *mdev, union drbd_state_t state) +{ + char buffer[sizeof(struct cn_msg)+ + sizeof(struct drbd_nl_cfg_reply)+ + sizeof(struct get_state_tag_len_struct)+ + sizeof(short int)]; + struct cn_msg *cn_reply = (struct cn_msg *) buffer; + struct drbd_nl_cfg_reply *reply = + (struct drbd_nl_cfg_reply *)cn_reply->data; + unsigned short *tl = reply->tag_list; + + /* drbd_WARN("drbd_bcast_state() got called\n"); */ + + tl = get_state_to_tags(mdev, (struct get_state *)&state, tl); + *tl++ = TT_END; /* Close the tag list */ + + cn_reply->id.idx = CN_IDX_DRBD; + cn_reply->id.val = CN_VAL_DRBD; + + cn_reply->seq = atomic_add_return(1, &drbd_nl_seq); + cn_reply->ack = 0; /* not used here. */ + cn_reply->len = sizeof(struct drbd_nl_cfg_reply) + + (int)((char *)tl - (char *)reply->tag_list); + cn_reply->flags = 0; + + reply->packet_type = P_get_state; + reply->minor = mdev_to_minor(mdev); + reply->ret_code = NoError; + + TRACE(TraceTypeNl, TraceLvlSummary, nl_trace_reply(cn_reply);); + + cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL); +} + +void drbd_bcast_ev_helper(struct drbd_conf *mdev, char *helper_name) +{ + char buffer[sizeof(struct cn_msg)+ + sizeof(struct drbd_nl_cfg_reply)+ + sizeof(struct call_helper_tag_len_struct)+ + sizeof(short int)]; + struct cn_msg *cn_reply = (struct cn_msg *) buffer; + struct drbd_nl_cfg_reply *reply = + (struct drbd_nl_cfg_reply *)cn_reply->data; + unsigned short *tl = reply->tag_list; + int str_len; + + /* drbd_WARN("drbd_bcast_state() got called\n"); */ + + str_len = strlen(helper_name)+1; + *tl++ = T_helper; + *tl++ = str_len; + memcpy(tl, helper_name, str_len); + tl = (unsigned short *)((char *)tl + str_len); + *tl++ = TT_END; /* Close the tag list */ + + cn_reply->id.idx = CN_IDX_DRBD; + cn_reply->id.val = CN_VAL_DRBD; + + cn_reply->seq = atomic_add_return(1, &drbd_nl_seq); + cn_reply->ack = 0; /* not used here. */ + cn_reply->len = sizeof(struct drbd_nl_cfg_reply) + + (int)((char *)tl - (char *)reply->tag_list); + cn_reply->flags = 0; + + reply->packet_type = P_call_helper; + reply->minor = mdev_to_minor(mdev); + reply->ret_code = NoError; + + TRACE(TraceTypeNl, TraceLvlSummary, nl_trace_reply(cn_reply);); + + cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL); +} + +void drbd_bcast_ee(struct drbd_conf *mdev, + const char *reason, const int dgs, + const char* seen_hash, const char* calc_hash, + const struct Tl_epoch_entry* e) +{ + struct cn_msg *cn_reply; + struct drbd_nl_cfg_reply *reply; + struct bio_vec *bvec; + unsigned short *tl; + int i; + + if (!e) + return; + if (!reason || !reason[0]) + return; + + /* aparently we have to memcpy twice, first to prepare the data for the + * struct cn_msg, then within cn_netlink_send from the cn_msg to the + * netlink skb. */ + cn_reply = kmalloc( + sizeof(struct cn_msg)+ + sizeof(struct drbd_nl_cfg_reply)+ + sizeof(struct dump_ee_tag_len_struct)+ + sizeof(short int) + , GFP_KERNEL); + + if (!cn_reply) { + ERR("could not kmalloc buffer for drbd_bcast_ee, sector %llu, size %u\n", + (unsigned long long)e->sector, e->size); + return; + } + + reply = (struct drbd_nl_cfg_reply*)cn_reply->data; + tl = reply->tag_list; + + tl = tl_add_str(tl, T_dump_ee_reason, reason); + tl = tl_add_blob(tl, T_seen_digest, seen_hash, dgs); + tl = tl_add_blob(tl, T_calc_digest, calc_hash, dgs); + tl = tl_add_int(tl, T_ee_sector, &e->sector); + tl = tl_add_int(tl, T_ee_block_id, &e->block_id); + + *tl++ = T_ee_data; + *tl++ = e->size; + + __bio_for_each_segment(bvec, e->private_bio, i, 0) { + void *d = kmap(bvec->bv_page); + memcpy(tl, d + bvec->bv_offset, bvec->bv_len); + kunmap(bvec->bv_page); + tl=(unsigned short*)((char*)tl + bvec->bv_len); + } + *tl++ = TT_END; /* Close the tag list */ + + cn_reply->id.idx = CN_IDX_DRBD; + cn_reply->id.val = CN_VAL_DRBD; + + cn_reply->seq = atomic_add_return(1,&drbd_nl_seq); + cn_reply->ack = 0; // not used here. + cn_reply->len = sizeof(struct drbd_nl_cfg_reply) + + (int)((char*)tl - (char*)reply->tag_list); + cn_reply->flags = 0; + + reply->packet_type = P_dump_ee; + reply->minor = mdev_to_minor(mdev); + reply->ret_code = NoError; + + TRACE(TraceTypeNl, TraceLvlSummary, nl_trace_reply(cn_reply);); + + cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL); + kfree(cn_reply); +} + +void drbd_bcast_sync_progress(struct drbd_conf *mdev) +{ + char buffer[sizeof(struct cn_msg)+ + sizeof(struct drbd_nl_cfg_reply)+ + sizeof(struct sync_progress_tag_len_struct)+ + sizeof(short int)]; + struct cn_msg *cn_reply = (struct cn_msg *) buffer; + struct drbd_nl_cfg_reply *reply = + (struct drbd_nl_cfg_reply *)cn_reply->data; + unsigned short *tl = reply->tag_list; + unsigned long rs_left; + unsigned int res; + + /* no local ref, no bitmap, no syncer progress, no broadcast. */ + if (!inc_local(mdev)) + return; + drbd_get_syncer_progress(mdev, &rs_left, &res); + dec_local(mdev); + + *tl++ = T_sync_progress; + *tl++ = sizeof(int); + memcpy(tl, &res, sizeof(int)); + tl = (unsigned short *)((char *)tl + sizeof(int)); + *tl++ = TT_END; /* Close the tag list */ + + cn_reply->id.idx = CN_IDX_DRBD; + cn_reply->id.val = CN_VAL_DRBD; + + cn_reply->seq = atomic_add_return(1, &drbd_nl_seq); + cn_reply->ack = 0; /* not used here. */ + cn_reply->len = sizeof(struct drbd_nl_cfg_reply) + + (int)((char *)tl - (char *)reply->tag_list); + cn_reply->flags = 0; + + reply->packet_type = P_sync_progress; + reply->minor = mdev_to_minor(mdev); + reply->ret_code = NoError; + + TRACE(TraceTypeNl, TraceLvlSummary, nl_trace_reply(cn_reply);); + + cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL); +} + +#ifdef NETLINK_ROUTE6 +int __init cn_init(void); +void __exit cn_fini(void); +#endif + +int __init drbd_nl_init(void) +{ + static struct cb_id cn_id_drbd; + int err, try=10; + +#ifdef NETLINK_ROUTE6 + /* pre 2.6.16 */ + err = cn_init(); + if (err) + return err; +#endif + cn_id_drbd.val = CN_VAL_DRBD; + do { + cn_id_drbd.idx = cn_idx; + err = cn_add_callback(&cn_id_drbd, "cn_drbd", &drbd_connector_callback); + if (!err) + break; + cn_idx = (cn_idx + CN_IDX_STEP); + } while (try--); + + if (err) { + printk(KERN_ERR "drbd: cn_drbd failed to register\n"); + return err; + } + + return 0; +} + +void drbd_nl_cleanup(void) +{ + static struct cb_id cn_id_drbd; + + cn_id_drbd.idx = cn_idx; + cn_id_drbd.val = CN_VAL_DRBD; + + cn_del_callback(&cn_id_drbd); + +#ifdef NETLINK_ROUTE6 + /* pre 2.6.16 */ + cn_fini(); +#endif +} + +void drbd_nl_send_reply(struct cn_msg *req, int ret_code) +{ + char buffer[sizeof(struct cn_msg)+sizeof(struct drbd_nl_cfg_reply)]; + struct cn_msg *cn_reply = (struct cn_msg *) buffer; + struct drbd_nl_cfg_reply *reply = + (struct drbd_nl_cfg_reply *)cn_reply->data; + int rr; + + cn_reply->id = req->id; + + cn_reply->seq = req->seq; + cn_reply->ack = req->ack + 1; + cn_reply->len = sizeof(struct drbd_nl_cfg_reply); + cn_reply->flags = 0; + + reply->minor = ((struct drbd_nl_cfg_req *)req->data)->drbd_minor; + reply->ret_code = ret_code; + + TRACE(TraceTypeNl, TraceLvlSummary, nl_trace_reply(cn_reply);); + + rr = cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL); + if (rr && rr != -ESRCH) + printk(KERN_INFO "drbd: cn_netlink_send()=%d\n", rr); +} + --- linux-2.6.28.orig/ubuntu/drbd/drbd_bitmap.c +++ linux-2.6.28/ubuntu/drbd/drbd_bitmap.c @@ -0,0 +1,1306 @@ +/* +-*- linux-c -*- + drbd_bitmap.c + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2004-2008, LINBIT Information Technologies GmbH. + Copyright (C) 2004-2008, Philipp Reisner . + Copyright (C) 2004-2008, Lars Ellenberg . + + drbd is free software; you can redistribute 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. + + drbd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include "drbd_int.h" + +/* OPAQUE outside this file! + * interface defined in drbd_int.h + + * convetion: + * function name drbd_bm_... => used elsewhere, "public". + * function name bm_... => internal to implementation, "private". + + * Note that since find_first_bit returns int, at the current granularity of + * the bitmap (4KB per byte), this implementation "only" supports up to + * 1<<(32+12) == 16 TB... + * + * we will eventually change the implementation to not allways hold the full + * bitmap in memory, but only some 'lru_cache' of the on disk bitmap. + + * THINK + * I'm not yet sure whether this file should be bits only, + * or wether I want it to do all the sector<->bit calculation in here. + */ + +/* + * NOTE + * Access to the *bm_pages is protected by bm_lock. + * It is safe to read the other members within the lock. + * + * drbd_bm_set_bits is called from bio_endio callbacks, + * We may be called with irq already disabled, + * so we need spin_lock_irqsave(). + * And we need the kmap_atomic. + * FIXME + * for performance reasons, when we _know_ we have irq disabled, we should + * probably introduce some _in_irq variants, so we know to only spin_lock(). + * + * FIXME + * Actually you need to serialize all resize operations. + * but then, resize is a drbd state change, and it should be serialized + * already. Unfortunately it is not (yet), so two concurrent resizes, like + * attach storage (drbdsetup) and receive the peers size (drbd receiver) + * may eventually blow things up. + * Therefore, + * you may only change the other members when holding + * the bm_change mutex _and_ the bm_lock. + * thus reading them holding either is safe. + * this is sort of overkill, but I rather do it right + * than have two resize operations interfere somewhen. + */ +struct drbd_bitmap { + struct page **bm_pages; + spinlock_t bm_lock; + /* WARNING unsigned long bm_fo and friends: + * 32bit number of bit offset is just enough for 512 MB bitmap. + * it will blow up if we make the bitmap bigger... + * not that it makes much sense to have a bitmap that large, + * rather change the granularity to 16k or 64k or something. + * (that implies other problems, however...) + */ + unsigned long bm_fo; /* next offset for drbd_bm_find_next */ + unsigned long bm_set; /* nr of set bits; THINK maybe atomic_t? */ + unsigned long bm_bits; + size_t bm_words; + size_t bm_number_of_pages; + sector_t bm_dev_capacity; + struct semaphore bm_change; /* serializes resize operations */ + + atomic_t bm_async_io; + wait_queue_head_t bm_io_wait; + + unsigned long bm_flags; + + /* debugging aid, in case we are still racy somewhere */ + char *bm_why; + struct task_struct *bm_task; +}; + +/* definition of bits in bm_flags */ +#define BM_LOCKED 0 +#define BM_MD_IO_ERROR (BITS_PER_LONG-1) /* 31? 63? */ + +static inline int bm_is_locked(struct drbd_bitmap *b) +{ + return test_bit(BM_LOCKED, &b->bm_flags); +} + +#define bm_print_lock_info(m) __bm_print_lock_info(m, __func__) +static void __bm_print_lock_info(struct drbd_conf *mdev, const char *func) +{ + struct drbd_bitmap *b = mdev->bitmap; + if (!DRBD_ratelimit(5*HZ, 5)) + return; + ERR("FIXME %s in %s, bitmap locked for '%s' by %s\n", + current == mdev->receiver.task ? "receiver" : + current == mdev->asender.task ? "asender" : + current == mdev->worker.task ? "worker" : current->comm, + func, b->bm_why ?: "?", + b->bm_task == mdev->receiver.task ? "receiver" : + b->bm_task == mdev->asender.task ? "asender" : + b->bm_task == mdev->worker.task ? "worker" : "?"); +} + +void drbd_bm_lock(struct drbd_conf *mdev, char *why) +{ + struct drbd_bitmap *b = mdev->bitmap; + int trylock_failed; + + if (!b) { + ERR("FIXME no bitmap in drbd_bm_lock!?\n"); + return; + } + + trylock_failed = down_trylock(&b->bm_change); + + if (trylock_failed) { + DBG("%s going to '%s' but bitmap already locked for '%s' by %s\n", + current == mdev->receiver.task ? "receiver" : + current == mdev->asender.task ? "asender" : + current == mdev->worker.task ? "worker" : "?", + why, b->bm_why ?: "?", + b->bm_task == mdev->receiver.task ? "receiver" : + b->bm_task == mdev->asender.task ? "asender" : + b->bm_task == mdev->worker.task ? "worker" : "?"); + down(&b->bm_change); + } + if (__test_and_set_bit(BM_LOCKED, &b->bm_flags)) + ERR("FIXME bitmap already locked in bm_lock\n"); + + b->bm_why = why; + b->bm_task = current; +} + +void drbd_bm_unlock(struct drbd_conf *mdev) +{ + struct drbd_bitmap *b = mdev->bitmap; + if (!b) { + ERR("FIXME no bitmap in drbd_bm_unlock!?\n"); + return; + } + + if (!__test_and_clear_bit(BM_LOCKED, &mdev->bitmap->bm_flags)) + ERR("FIXME bitmap not locked in bm_unlock\n"); + + b->bm_why = NULL; + b->bm_task = NULL; + up(&b->bm_change); +} + +#define bm_end_info(ignored...) ((void)(0)) + +#if 0 +#define catch_oob_access_start() do { \ + do { \ + if ((bm-p_addr) >= PAGE_SIZE/sizeof(long)) { \ + printk(KERN_ALERT "drbd_bitmap.c:%u %s: p_addr:%p bm:%p %d\n", \ + __LINE__ , __func__ , p_addr, bm, (bm-p_addr)); \ + break; \ + } +#define catch_oob_access_end() \ + } while (0); } while (0) +#else +#define catch_oob_access_start() do { +#define catch_oob_access_end() } while (0) +#endif + +/* word offset to long pointer */ +STATIC unsigned long * bm_map_paddr(struct drbd_bitmap *b, unsigned long offset) +{ + struct page *page; + unsigned long page_nr; + + /* page_nr = (word*sizeof(long)) >> PAGE_SHIFT; */ + page_nr = offset >> (PAGE_SHIFT - LN2_BPL + 3); + BUG_ON(page_nr >= b->bm_number_of_pages); + page = b->bm_pages[page_nr]; + + return (unsigned long *) kmap_atomic(page, KM_IRQ1); +} + +STATIC void bm_unmap(unsigned long *p_addr) +{ + kunmap_atomic(p_addr, KM_IRQ1); +}; + +/* long word offset of _bitmap_ sector */ +#define S2W(s) ((s)<<(BM_EXT_SIZE_B-BM_BLOCK_SIZE_B-LN2_BPL)) +/* word offset from start of bitmap to word number _in_page_ + * modulo longs per page +#define MLPP(X) ((X) % (PAGE_SIZE/sizeof(long)) + hm, well, Philipp thinks gcc might not optimze the % into & (... - 1) + so do it explicitly: + */ +#define MLPP(X) ((X) & ((PAGE_SIZE/sizeof(long))-1)) + +/* Long words per page */ +#define LWPP (PAGE_SIZE/sizeof(long)) + +/* + * actually most functions herein should take a struct drbd_bitmap*, not a + * struct drbd_conf*, but for the debug macros I like to have the mdev around + * to be able to report device specific. + */ + +/* FIXME TODO sometimes I use "int offset" as index into the bitmap. + * since we currently are LIMITED to (128<<11)-64-8 sectors of bitmap, + * this is ok [as long as we dont run on a 24 bit arch :)]. + * But it is NOT strictly ok. + */ + +STATIC void bm_free_pages(struct page **pages, unsigned long number) +{ + unsigned long i; + if (!pages) + return; + + for (i = 0; i < number; i++) { + if (!pages[i]) { + printk(KERN_ALERT "drbd: bm_free_pages tried to free " + "a NULL pointer; i=%lu n=%lu\n", + i, number); + continue; + } + __free_page(pages[i]); + pages[i] = NULL; + } +} + +/* + * "have" and "want" are NUMBER OF PAGES. + */ +STATIC struct page **bm_realloc_pages(struct page **old_pages, + unsigned long have, + unsigned long want) +{ + struct page** new_pages, *page; + unsigned int i, bytes; + + BUG_ON(have == 0 && old_pages != NULL); + BUG_ON(have != 0 && old_pages == NULL); + + if (have == want) + return old_pages; + + /* To use kmalloc here is ok, as long as we support 4TB at max... + * otherwise this might become bigger than 128KB, which is + * the maximum for kmalloc. + * + * no, it is not: on 64bit boxes, sizeof(void*) == 8, + * 128MB bitmap @ 4K pages -> 256K of page pointers. + * ==> use vmalloc for now again. + * then again, we could do something like + * if (nr_pages > watermark) vmalloc else kmalloc :*> ... + * or do cascading page arrays: + * one page for the page array of the page array, + * those pages for the real bitmap pages. + * there we could even add some optimization members, + * so we won't need to kmap_atomic in bm_find_next_bit just to see + * that the page has no bits set ... + * or we can try a "huge" page ;-) + */ + bytes = sizeof(struct page*)*want; + new_pages = vmalloc(bytes); + if (!new_pages) + return NULL; + + memset(new_pages, 0, bytes); + if (want >= have) { + for (i = 0; i < have; i++) + new_pages[i] = old_pages[i]; + for (; i < want; i++) { + if (!(page = alloc_page(GFP_HIGHUSER))) { + bm_free_pages(new_pages + have, i - have); + vfree(new_pages); + return NULL; + } + new_pages[i] = page; + } + } else { + for (i = 0; i < want; i++) + new_pages[i] = old_pages[i]; + /* NOT HERE, we are outside the spinlock! + bm_free_pages(old_pages + want, have - want); + */ + } + + return new_pages; +} + +/* + * called on driver init only. TODO call when a device is created. + * allocates the drbd_bitmap, and stores it in mdev->bitmap. + */ +int drbd_bm_init(struct drbd_conf *mdev) +{ + struct drbd_bitmap *b = mdev->bitmap; + WARN_ON(b != NULL); + b = kzalloc(sizeof(struct drbd_bitmap), GFP_KERNEL); + if (!b) + return -ENOMEM; + spin_lock_init(&b->bm_lock); + init_MUTEX(&b->bm_change); + init_waitqueue_head(&b->bm_io_wait); + + mdev->bitmap = b; + + return 0; +} + +sector_t drbd_bm_capacity(struct drbd_conf *mdev) +{ + ERR_IF(!mdev->bitmap) return 0; + return mdev->bitmap->bm_dev_capacity; +} + +/* called on driver unload. TODO: call when a device is destroyed. + */ +void drbd_bm_cleanup(struct drbd_conf *mdev) +{ + ERR_IF (!mdev->bitmap) return; + /* FIXME I think we should explicitly change the device size to zero + * before this... + * + WARN_ON(mdev->bitmap->bm); + */ + bm_free_pages(mdev->bitmap->bm_pages, mdev->bitmap->bm_number_of_pages); + vfree(mdev->bitmap->bm_pages); + kfree(mdev->bitmap); + mdev->bitmap = NULL; +} + +/* + * since (b->bm_bits % BITS_PER_LONG) != 0, + * this masks out the remaining bits. + * Rerturns the number of bits cleared. + */ +STATIC int bm_clear_surplus(struct drbd_bitmap *b) +{ + const unsigned long mask = (1UL << (b->bm_bits & (BITS_PER_LONG-1))) - 1; + size_t w = b->bm_bits >> LN2_BPL; + int cleared = 0; + unsigned long *p_addr, *bm; + + p_addr = bm_map_paddr(b, w); + bm = p_addr + MLPP(w); + if (w < b->bm_words) { + catch_oob_access_start(); + cleared = hweight_long(*bm & ~mask); + *bm &= mask; + catch_oob_access_end(); + w++; bm++; + } + + if (w < b->bm_words) { + catch_oob_access_start(); + cleared += hweight_long(*bm); + *bm = 0; + catch_oob_access_end(); + } + bm_unmap(p_addr); + return cleared; +} + +STATIC void bm_set_surplus(struct drbd_bitmap *b) +{ + const unsigned long mask = (1UL << (b->bm_bits & (BITS_PER_LONG-1))) - 1; + size_t w = b->bm_bits >> LN2_BPL; + unsigned long *p_addr, *bm; + + p_addr = bm_map_paddr(b, w); + bm = p_addr + MLPP(w); + if (w < b->bm_words) { + catch_oob_access_start(); + *bm |= ~mask; + bm++; w++; + catch_oob_access_end(); + } + + if (w < b->bm_words) { + catch_oob_access_start(); + *bm = ~(0UL); + catch_oob_access_end(); + } + bm_unmap(p_addr); +} + +STATIC unsigned long __bm_count_bits(struct drbd_bitmap *b, const int swap_endian) +{ + unsigned long *p_addr, *bm, offset = 0; + unsigned long bits = 0; + unsigned long i, do_now; + + while (offset < b->bm_words) { + i = do_now = min_t(size_t, b->bm_words-offset, LWPP); + p_addr = bm_map_paddr(b, offset); + bm = p_addr + MLPP(offset); + while (i--) { + catch_oob_access_start(); +#ifndef __LITTLE_ENDIAN + if (swap_endian) + *bm = lel_to_cpu(*bm); +#endif + bits += hweight_long(*bm++); + catch_oob_access_end(); + } + bm_unmap(p_addr); + offset += do_now; + } + + return bits; +} + +static inline unsigned long bm_count_bits(struct drbd_bitmap *b) +{ + return __bm_count_bits(b, 0); +} + +static inline unsigned long bm_count_bits_swap_endian(struct drbd_bitmap *b) +{ + return __bm_count_bits(b, 1); +} + +void _drbd_bm_recount_bits(struct drbd_conf *mdev, char *file, int line) +{ + struct drbd_bitmap *b = mdev->bitmap; + unsigned long flags, bits; + + ERR_IF(!b) return; + + /* IMO this should be inside drbd_bm_lock/unlock. + * Unfortunately it is used outside of the locks. + * And I'm not yet sure where we need to place the + * lock/unlock correctly. + */ + + spin_lock_irqsave(&b->bm_lock, flags); + bits = bm_count_bits(b); + if (bits != b->bm_set) { + ERR("bm_set was %lu, corrected to %lu. %s:%d\n", + b->bm_set, bits, file, line); + b->bm_set = bits; + } + spin_unlock_irqrestore(&b->bm_lock, flags); +} + +/* offset and len in long words.*/ +STATIC void bm_memset(struct drbd_bitmap * b, size_t offset, int c, size_t len) +{ + unsigned long *p_addr, *bm; + size_t do_now, end; + +#define BM_SECTORS_PER_BIT (BM_BLOCK_SIZE/512) + + end = offset + len; + + if (end > b->bm_words) { + printk(KERN_ALERT "drbd: bm_memset end > bm_words\n"); + return; + } + + while (offset < end) { + do_now = min_t(size_t, ALIGN(offset + 1, LWPP), end) - offset; + p_addr = bm_map_paddr(b, offset); + bm = p_addr + MLPP(offset); + catch_oob_access_start(); + if (bm+do_now > p_addr + LWPP) { + printk(KERN_ALERT "drbd: BUG BUG BUG! p_addr:%p bm:%p do_now:%d\n", + p_addr, bm, (int)do_now); + break; /* breaks to after catch_oob_access_end() only! */ + } + memset(bm, c, do_now * sizeof(long)); + catch_oob_access_end(); + bm_unmap(p_addr); + offset += do_now; + } +} + +/* + * make sure the bitmap has enough room for the attached storage, + * if neccessary, resize. + * called whenever we may have changed the device size. + * returns -ENOMEM if we could not allocate enough memory, 0 on success. + * In case this is actually a resize, we copy the old bitmap into the new one. + * Otherwise, the bitmap is initiallized to all bits set. + */ +int drbd_bm_resize(struct drbd_conf *mdev, sector_t capacity) +{ + struct drbd_bitmap *b = mdev->bitmap; + unsigned long bits, words, owords, obits, *p_addr, *bm; + unsigned long want, have, onpages; /* number of pages */ + struct page **npages, **opages = NULL; + int err = 0, growing; + + ERR_IF(!b) return -ENOMEM; + + drbd_bm_lock(mdev, "resize"); + + INFO("drbd_bm_resize called with capacity == %llu\n", + (unsigned long long)capacity); + + if (capacity == b->bm_dev_capacity) + goto out; + + if (capacity == 0) { + spin_lock_irq(&b->bm_lock); + opages = b->bm_pages; + onpages = b->bm_number_of_pages; + owords = b->bm_words; + b->bm_pages = NULL; + b->bm_number_of_pages = + b->bm_fo = + b->bm_set = + b->bm_bits = + b->bm_words = + b->bm_dev_capacity = 0; + spin_unlock_irq(&b->bm_lock); + bm_free_pages(opages, onpages); + vfree(opages); + goto out; + } + bits = BM_SECT_TO_BIT(ALIGN(capacity, BM_SECT_PER_BIT)); + + /* if we would use + words = ALIGN(bits,BITS_PER_LONG) >> LN2_BPL; + a 32bit host could present the wrong number of words + to a 64bit host. + */ + words = ALIGN(bits, 64) >> LN2_BPL; + + if (inc_local(mdev)) { + D_ASSERT((u64)bits <= (((u64)mdev->bc->md.md_size_sect-MD_BM_OFFSET) << 12)); + dec_local(mdev); + } + + /* one extra long to catch off by one errors */ + want = ALIGN((words+1)*sizeof(long), PAGE_SIZE) >> PAGE_SHIFT; + have = b->bm_number_of_pages; + if (want == have) { + D_ASSERT(b->bm_pages != NULL); + npages = b->bm_pages; + } else + npages = bm_realloc_pages(b->bm_pages, have, want); + + if (!npages) { + err = -ENOMEM; + goto out; + } + + spin_lock_irq(&b->bm_lock); + opages = b->bm_pages; + owords = b->bm_words; + obits = b->bm_bits; + + growing = bits > obits; + if (opages) + bm_set_surplus(b); + + b->bm_pages = npages; + b->bm_number_of_pages = want; + b->bm_bits = bits; + b->bm_words = words; + b->bm_dev_capacity = capacity; + + if (growing) { + bm_memset(b, owords, 0xff, words-owords); + b->bm_set += bits - obits; + } + + if (want < have) { + /* implicit: (opages != NULL) && (opages != npages) */ + bm_free_pages(opages + want, have - want); + } + + p_addr = bm_map_paddr(b, words); + bm = p_addr + MLPP(words); + catch_oob_access_start(); + *bm = DRBD_MAGIC; + catch_oob_access_end(); + bm_unmap(p_addr); + + (void)bm_clear_surplus(b); + if (!growing) + b->bm_set = bm_count_bits(b); + + bm_end_info(mdev, __FUNCTION__); + spin_unlock_irq(&b->bm_lock); + if (opages != npages) + vfree(opages); + INFO("resync bitmap: bits=%lu words=%lu\n", bits, words); + + out: + drbd_bm_unlock(mdev); + return err; +} + +/* inherently racy: + * if not protected by other means, return value may be out of date when + * leaving this function... + * we still need to lock it, since it is important that this returns + * bm_set == 0 precisely. + * + * maybe bm_set should be atomic_t ? + */ +unsigned long drbd_bm_total_weight(struct drbd_conf *mdev) +{ + struct drbd_bitmap *b = mdev->bitmap; + unsigned long s; + unsigned long flags; + + ERR_IF(!b) return 0; + ERR_IF(!b->bm_pages) return 0; + + spin_lock_irqsave(&b->bm_lock, flags); + s = b->bm_set; + spin_unlock_irqrestore(&b->bm_lock, flags); + + return s; +} + +size_t drbd_bm_words(struct drbd_conf *mdev) +{ + struct drbd_bitmap *b = mdev->bitmap; + ERR_IF(!b) return 0; + ERR_IF(!b->bm_pages) return 0; + + return b->bm_words; +} + +unsigned long drbd_bm_bits(struct drbd_conf *mdev) +{ + struct drbd_bitmap *b = mdev->bitmap; + ERR_IF(!b) return 0; + + return b->bm_bits; +} + +/* merge number words from buffer into the bitmap starting at offset. + * buffer[i] is expected to be little endian unsigned long. + * bitmap must be locked by drbd_bm_lock. + * currently only used from receive_bitmap. + */ +void drbd_bm_merge_lel(struct drbd_conf *mdev, size_t offset, size_t number, + unsigned long *buffer) +{ + struct drbd_bitmap *b = mdev->bitmap; + unsigned long *p_addr, *bm; + unsigned long word, bits; + size_t end, do_now; + + end = offset + number; + + ERR_IF(!b) return; + ERR_IF(!b->bm_pages) return; + if (number == 0) + return; + WARN_ON(offset >= b->bm_words); + WARN_ON(end > b->bm_words); + + spin_lock_irq(&b->bm_lock); + while (offset < end) { + do_now = min_t(size_t, ALIGN(offset+1, LWPP), end) - offset; + p_addr = bm_map_paddr(b, offset); + bm = p_addr + MLPP(offset); + offset += do_now; + while (do_now--) { + catch_oob_access_start(); + bits = hweight_long(*bm); + word = *bm | lel_to_cpu(*buffer++); + *bm++ = word; + b->bm_set += hweight_long(word) - bits; + catch_oob_access_end(); + } + bm_unmap(p_addr); + } + /* with 32bit <-> 64bit cross-platform connect + * this is only correct for current usage, + * where we _know_ that we are 64 bit aligned, + * and know that this function is used in this way, too... + */ + if (end == b->bm_words) { + b->bm_set -= bm_clear_surplus(b); + bm_end_info(mdev, __func__); + } + spin_unlock_irq(&b->bm_lock); +} + +/* copy number words from the bitmap starting at offset into the buffer. + * buffer[i] will be little endian unsigned long. + */ +void drbd_bm_get_lel(struct drbd_conf *mdev, size_t offset, size_t number, + unsigned long *buffer) +{ + struct drbd_bitmap *b = mdev->bitmap; + unsigned long *p_addr, *bm; + size_t end, do_now; + + end = offset + number; + + ERR_IF(!b) return; + ERR_IF(!b->bm_pages) return; + + spin_lock_irq(&b->bm_lock); + if ((offset >= b->bm_words) || + (end > b->bm_words) || + (number <= 0)) + ERR("offset=%lu number=%lu bm_words=%lu\n", + (unsigned long) offset, + (unsigned long) number, + (unsigned long) b->bm_words); + else { + while (offset < end) { + do_now = min_t(size_t, ALIGN(offset+1, LWPP), end) - offset; + p_addr = bm_map_paddr(b, offset); + bm = p_addr + MLPP(offset); + offset += do_now; + while (do_now--) { + catch_oob_access_start(); + *buffer++ = cpu_to_lel(*bm++); + catch_oob_access_end(); + } + bm_unmap(p_addr); + } + } + spin_unlock_irq(&b->bm_lock); +} + +/* set all bits in the bitmap */ +void drbd_bm_set_all(struct drbd_conf *mdev) +{ + struct drbd_bitmap *b = mdev->bitmap; + ERR_IF(!b) return; + ERR_IF(!b->bm_pages) return; + + spin_lock_irq(&b->bm_lock); + bm_memset(b, 0, 0xff, b->bm_words); + (void)bm_clear_surplus(b); + b->bm_set = b->bm_bits; + spin_unlock_irq(&b->bm_lock); +} + +/* clear all bits in the bitmap */ +void drbd_bm_clear_all(struct drbd_conf *mdev) +{ + struct drbd_bitmap *b = mdev->bitmap; + ERR_IF(!b) return; + ERR_IF(!b->bm_pages) return; + + spin_lock_irq(&b->bm_lock); + bm_memset(b, 0, 0, b->bm_words); + b->bm_set = 0; + spin_unlock_irq(&b->bm_lock); +} + +static BIO_ENDIO_TYPE bm_async_io_complete BIO_ENDIO_ARGS(struct bio *bio, int error) +{ + struct drbd_bitmap *b = bio->bi_private; + int uptodate = bio_flagged(bio, BIO_UPTODATE); + + BIO_ENDIO_FN_START; + + /* strange behaviour of some lower level drivers... + * fail the request by clearing the uptodate flag, + * but do not return any error?! + * do we want to WARN() on this? */ + if (!error && !uptodate) + error = -EIO; + + if (error) { + /* doh. what now? + * for now, set all bits, and flag MD_IO_ERROR + */ + /* FIXME kmap_atomic memset etc. pp. */ + __set_bit(BM_MD_IO_ERROR, &b->bm_flags); + } + if (atomic_dec_and_test(&b->bm_async_io)) + wake_up(&b->bm_io_wait); + + bio_put(bio); + + BIO_ENDIO_FN_RETURN; +} + +STATIC void bm_page_io_async(struct drbd_conf *mdev, struct drbd_bitmap *b, int page_nr, int rw) __must_hold(local) +{ + /* we are process context. we always get a bio */ + struct bio *bio = bio_alloc(GFP_KERNEL, 1); + unsigned int len; + sector_t on_disk_sector = + mdev->bc->md.md_offset + mdev->bc->md.bm_offset; + on_disk_sector += ((sector_t)page_nr) << (PAGE_SHIFT-9); + + /* this might happen with very small + * flexible external meta data device */ + len = min_t(unsigned int, PAGE_SIZE, + (drbd_md_last_sector(mdev->bc) - on_disk_sector + 1)<<9); + + D_DUMPLU(on_disk_sector); + D_DUMPI(len); + + bio->bi_bdev = mdev->bc->md_bdev; + bio->bi_sector = on_disk_sector; + bio_add_page(bio, b->bm_pages[page_nr], len, 0); + bio->bi_private = b; + bio->bi_end_io = bm_async_io_complete; + + if (FAULT_ACTIVE(mdev, (rw & WRITE) ? DRBD_FAULT_MD_WR : DRBD_FAULT_MD_RD)) { + bio->bi_rw |= rw; + bio_endio(bio, -EIO); + } else { + submit_bio(rw, bio); + } +} + +# if defined(__LITTLE_ENDIAN) + /* nothing to do, on disk == in memory */ +# define bm_cpu_to_lel(x) ((void)0) +# else +void bm_cpu_to_lel(struct drbd_bitmap *b) +{ + /* need to cpu_to_lel all the pages ... + * this may be optimized by using + * cpu_to_lel(-1) == -1 and cpu_to_lel(0) == 0; + * the following is still not optimal, but better than nothing */ + if (b->bm_set == 0) { + /* no page at all; avoid swap if all is 0 */ + i = b->bm_number_of_pages; + } else if (b->bm_set == b->bm_bits) { + /* only the last page */ + i = b->bm_number_of_pages -1; + } else { + /* all pages */ + i = 0; + } + for (; i < b->bm_number_of_pages; i++) { + unsigned long *bm; + /* if you'd want to use kmap_atomic, you'd have to disable irq! */ + p_addr = kmap(b->bm_pages[i]); + for (bm = p_addr; bm < p_addr + PAGE_SIZE/sizeof(long); bm++) { + *bm = cpu_to_lel(*bm); + } + kunmap(p_addr); + } +} +# endif +/* lel_to_cpu == cpu_to_lel */ +# define bm_lel_to_cpu(x) bm_cpu_to_lel(x) + +/* + * bm_rw: read/write the whole bitmap from/to its on disk location. + */ +STATIC int bm_rw(struct drbd_conf *mdev, int rw) __must_hold(local) +{ + struct drbd_bitmap *b = mdev->bitmap; + /* sector_t sector; */ + int bm_words, num_pages, i; + unsigned long now; + char ppb[10]; + int err = 0; + + WARN_ON(!bm_is_locked(b)); + + /* no spinlock here, the drbd_bm_lock should be enough! */ + + bm_words = drbd_bm_words(mdev); + num_pages = (bm_words*sizeof(long) + PAGE_SIZE-1) >> PAGE_SHIFT; + + /* on disk bitmap is little endian */ + if (rw == WRITE) + bm_cpu_to_lel(b); + + now = jiffies; + atomic_set(&b->bm_async_io, num_pages); + __clear_bit(BM_MD_IO_ERROR, &b->bm_flags); + + /* let the layers below us try to merge these bios... */ + for (i = 0; i < num_pages; i++) + bm_page_io_async(mdev, b, i, rw); + + drbd_blk_run_queue(bdev_get_queue(mdev->bc->md_bdev)); + wait_event(b->bm_io_wait, atomic_read(&b->bm_async_io) == 0); + + MTRACE(TraceTypeMDIO, TraceLvlSummary, + INFO("%s of bitmap took %lu jiffies\n", + rw == READ ? "reading" : "writing", jiffies - now); + ); + + if (test_bit(BM_MD_IO_ERROR, &b->bm_flags)) { + ALERT("we had at least one MD IO ERROR during bitmap IO\n"); + drbd_chk_io_error(mdev, 1, TRUE); + drbd_io_error(mdev, TRUE); + err = -EIO; + } + + now = jiffies; + if (rw == WRITE) { + /* swap back endianness */ + bm_lel_to_cpu(b); + /* flush bitmap to stable storage */ + drbd_md_flush(mdev); + } else /* rw == READ */ { + /* just read, if neccessary adjust endianness */ + b->bm_set = bm_count_bits_swap_endian(b); + INFO("recounting of set bits took additional %lu jiffies\n", + jiffies - now); + } + now = b->bm_set; + + INFO("%s (%lu bits) marked out-of-sync by on disk bit-map.\n", + ppsize(ppb, now << (BM_BLOCK_SIZE_B-10)), now); + + return err; +} + +/** + * drbd_bm_read: Read the whole bitmap from its on disk location. + * + * currently only called from "drbd_nl_disk_conf" + */ +int drbd_bm_read(struct drbd_conf *mdev) __must_hold(local) +{ + return bm_rw(mdev, READ); +} + +/** + * drbd_bm_write: Write the whole bitmap to its on disk location. + * + * called at various occasions. + */ +int drbd_bm_write(struct drbd_conf *mdev) __must_hold(local) +{ + return bm_rw(mdev, WRITE); +} + +/** + * drbd_bm_write_sect: Writes a 512 byte piece of the bitmap to its + * on disk location. On disk bitmap is little endian. + * + * @enr: The _sector_ offset from the start of the bitmap. + * + */ +int drbd_bm_write_sect(struct drbd_conf *mdev, unsigned long enr) __must_hold(local) +{ + sector_t on_disk_sector = enr + mdev->bc->md.md_offset + + mdev->bc->md.bm_offset; + int bm_words, num_words, offset; + int err = 0; + + down(&mdev->md_io_mutex); + bm_words = drbd_bm_words(mdev); + offset = S2W(enr); /* word offset into bitmap */ + num_words = min(S2W(1), bm_words - offset); +#if DUMP_MD >= 3 + INFO("write_sect: sector=%lu offset=%u num_words=%u\n", + enr, offset, num_words); +#endif + if (num_words < S2W(1)) + memset(page_address(mdev->md_io_page), 0, MD_HARDSECT); + drbd_bm_get_lel(mdev, offset, num_words, + page_address(mdev->md_io_page)); + if (!drbd_md_sync_page_io(mdev, mdev->bc, on_disk_sector, WRITE)) { + int i; + err = -EIO; + ERR("IO ERROR writing bitmap sector %lu " + "(meta-disk sector %llus)\n", + enr, (unsigned long long)on_disk_sector); + drbd_chk_io_error(mdev, 1, TRUE); + drbd_io_error(mdev, TRUE); + for (i = 0; i < AL_EXT_PER_BM_SECT; i++) + drbd_bm_ALe_set_all(mdev, enr*AL_EXT_PER_BM_SECT+i); + } + mdev->bm_writ_cnt++; + up(&mdev->md_io_mutex); + return err; +} + +void drbd_bm_reset_find(struct drbd_conf *mdev) +{ + struct drbd_bitmap *b = mdev->bitmap; + + ERR_IF(!b) return; + + spin_lock_irq(&b->bm_lock); + if (bm_is_locked(b)) + bm_print_lock_info(mdev); + b->bm_fo = 0; + spin_unlock_irq(&b->bm_lock); + +} + +/* NOTE + * find_first_bit returns int, we return unsigned long. + * should not make much difference anyways, but ... + * + * this returns a bit number, NOT a sector! + */ +#define BPP_MASK ((1UL << (PAGE_SHIFT+3)) - 1) +unsigned long drbd_bm_find_next(struct drbd_conf *mdev) +{ + struct drbd_bitmap *b = mdev->bitmap; + unsigned long i = -1UL; + unsigned long *p_addr; + unsigned long bit_offset; /* bit offset of the mapped page. */ + + ERR_IF(!b) return i; + ERR_IF(!b->bm_pages) return i; + + spin_lock_irq(&b->bm_lock); + if (bm_is_locked(b)) + bm_print_lock_info(mdev); + if (b->bm_fo > b->bm_bits) { + ERR("bm_fo=%lu bm_bits=%lu\n", b->bm_fo, b->bm_bits); + } else { + while (b->bm_fo < b->bm_bits) { + unsigned long offset; + bit_offset = b->bm_fo & ~BPP_MASK; /* bit offset of the page */ + offset = bit_offset >> LN2_BPL; /* word offset of the page */ + p_addr = bm_map_paddr(b, offset); + i = find_next_bit(p_addr, PAGE_SIZE*8, b->bm_fo & BPP_MASK); + bm_unmap(p_addr); + if (i < PAGE_SIZE*8) { + i = bit_offset + i; + if (i >= b->bm_bits) + break; + b->bm_fo = i+1; + goto found; + } + b->bm_fo = bit_offset + PAGE_SIZE*8; + } + i = -1UL; + /* leave b->bm_fo unchanged. */ + } + found: + spin_unlock_irq(&b->bm_lock); + return i; +} + +void drbd_bm_set_find(struct drbd_conf *mdev, unsigned long i) +{ + struct drbd_bitmap *b = mdev->bitmap; + + spin_lock_irq(&b->bm_lock); + + b->bm_fo = min_t(unsigned long, i, b->bm_bits); + + spin_unlock_irq(&b->bm_lock); +} + +int drbd_bm_rs_done(struct drbd_conf *mdev) +{ + D_ASSERT(mdev->bitmap); + return mdev->bitmap->bm_fo >= mdev->bitmap->bm_bits; +} + +/* returns number of bits actually changed. + * for val != 0, we change 0 -> 1, return code positiv + * for val == 0, we change 1 -> 0, return code negative + * wants bitnr, not sector */ +static int bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, + const unsigned long e, int val) +{ + unsigned long flags; + struct drbd_bitmap *b = mdev->bitmap; + unsigned long *p_addr = NULL; + unsigned long bitnr; + unsigned long last_page_nr = -1UL; + int c = 0; + + ERR_IF(!b) return 1; + ERR_IF(!b->bm_pages) return 0; + + spin_lock_irqsave(&b->bm_lock, flags); + if (bm_is_locked(b)) + bm_print_lock_info(mdev); + for (bitnr = s; bitnr <= e; bitnr++) { + ERR_IF (bitnr >= b->bm_bits) { + ERR("bitnr=%lu bm_bits=%lu\n", bitnr, b->bm_bits); + } else { + unsigned long offset = bitnr>>LN2_BPL; + unsigned long page_nr = offset >> (PAGE_SHIFT - LN2_BPL + 3); + if (page_nr != last_page_nr) { + if (p_addr) + bm_unmap(p_addr); + p_addr = bm_map_paddr(b, offset); + last_page_nr = page_nr; + } + if (val) + c += (0 == __test_and_set_bit(bitnr & BPP_MASK, p_addr)); + else + c -= (0 != __test_and_clear_bit(bitnr & BPP_MASK, p_addr)); + } + } + if (p_addr) + bm_unmap(p_addr); + b->bm_set += c; + spin_unlock_irqrestore(&b->bm_lock, flags); + return c; +} + +/* returns number of bits changed 0 -> 1 */ +int drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsigned long e) +{ + return bm_change_bits_to(mdev, s, e, 1); +} + +/* returns number of bits changed 1 -> 0 */ +int drbd_bm_clear_bits(struct drbd_conf *mdev, const unsigned long s, const unsigned long e) +{ + return -bm_change_bits_to(mdev, s, e, 0); +} + +/* returns bit state + * wants bitnr, NOT sector. + * inherently racy... area needs to be locked by means of {al,rs}_lru + * 1 ... bit set + * 0 ... bit not set + * -1 ... first out of bounds access, stop testing for bits! + */ +int drbd_bm_test_bit(struct drbd_conf *mdev, const unsigned long bitnr) +{ + unsigned long flags; + struct drbd_bitmap *b = mdev->bitmap; + unsigned long *p_addr; + int i; + + ERR_IF(!b) return 0; + ERR_IF(!b->bm_pages) return 0; + + spin_lock_irqsave(&b->bm_lock, flags); + if (bm_is_locked(b)) + bm_print_lock_info(mdev); + if (bitnr < b->bm_bits) { + unsigned long offset = bitnr>>LN2_BPL; + p_addr = bm_map_paddr(b, offset); + i = test_bit(bitnr & BPP_MASK, p_addr) ? 1 : 0; + bm_unmap(p_addr); + } else if (bitnr == b->bm_bits) { + i = -1; + } else { /* (bitnr > b->bm_bits) */ + ERR("bitnr=%lu > bm_bits=%lu\n", bitnr, b->bm_bits); + i = 0; + } + + spin_unlock_irqrestore(&b->bm_lock, flags); + return i; +} + +/* returns number of bits set */ +int drbd_bm_count_bits(struct drbd_conf *mdev, const unsigned long s, const unsigned long e) +{ + unsigned long flags; + struct drbd_bitmap *b = mdev->bitmap; + unsigned long *p_addr = NULL, page_nr = -1; + unsigned long bitnr; + int c = 0; + size_t w; + + /* If this is called without a bitmap, that is a bug. But just to be + * robust in case we screwed up elsewhere, in that case pretend there + * was one dirty bit in the requested area, so we won't try to do a + * local read there (no bitmap probably implies no disk) */ + ERR_IF(!b) return 1; + ERR_IF(!b->bm_pages) return 1; + + spin_lock_irqsave(&b->bm_lock, flags); + for (bitnr = s; bitnr <= e; bitnr++) { + w = bitnr >> LN2_BPL; + if (page_nr != w >> (PAGE_SHIFT - LN2_BPL + 3)) { + page_nr = w >> (PAGE_SHIFT - LN2_BPL + 3); + if (p_addr) + bm_unmap(p_addr); + p_addr = bm_map_paddr(b, w); + } + ERR_IF (bitnr >= b->bm_bits) { + ERR("bitnr=%lu bm_bits=%lu\n", bitnr, b->bm_bits); + } else { + c += (0 != test_bit(bitnr - (page_nr << (PAGE_SHIFT+3)), p_addr)); + } + } + if (p_addr) + bm_unmap(p_addr); + spin_unlock_irqrestore(&b->bm_lock, flags); + return c; +} + + +/* inherently racy... + * return value may be already out-of-date when this function returns. + * but the general usage is that this is only use during a cstate when bits are + * only cleared, not set, and typically only care for the case when the return + * value is zero, or we already "locked" this "bitmap extent" by other means. + * + * enr is bm-extent number, since we chose to name one sector (512 bytes) + * worth of the bitmap a "bitmap extent". + * + * TODO + * I think since we use it like a reference count, we should use the real + * reference count of some bitmap extent element from some lru instead... + * + */ +int drbd_bm_e_weight(struct drbd_conf *mdev, unsigned long enr) +{ + struct drbd_bitmap *b = mdev->bitmap; + int count, s, e; + unsigned long flags; + unsigned long *p_addr, *bm; + + ERR_IF(!b) return 0; + ERR_IF(!b->bm_pages) return 0; + + spin_lock_irqsave(&b->bm_lock, flags); + if (bm_is_locked(b)) + bm_print_lock_info(mdev); + + s = S2W(enr); + e = min((size_t)S2W(enr+1), b->bm_words); + count = 0; + if (s < b->bm_words) { + int n = e-s; + p_addr = bm_map_paddr(b, s); + bm = p_addr + MLPP(s); + while (n--) { + catch_oob_access_start(); + count += hweight_long(*bm++); + catch_oob_access_end(); + } + bm_unmap(p_addr); + } else { + ERR("start offset (%d) too large in drbd_bm_e_weight\n", s); + } + spin_unlock_irqrestore(&b->bm_lock, flags); +#if DUMP_MD >= 3 + INFO("enr=%lu weight=%d e=%d s=%d\n", enr, count, e, s); +#endif + return count; +} + +/* set all bits covered by the AL-extent al_enr */ +unsigned long drbd_bm_ALe_set_all(struct drbd_conf *mdev, unsigned long al_enr) +{ + struct drbd_bitmap *b = mdev->bitmap; + unsigned long *p_addr, *bm; + unsigned long weight; + int count, s, e, i, do_now; + ERR_IF(!b) return 0; + ERR_IF(!b->bm_pages) return 0; + + spin_lock_irq(&b->bm_lock); + if (bm_is_locked(b)) + bm_print_lock_info(mdev); + weight = b->bm_set; + + s = al_enr * BM_WORDS_PER_AL_EXT; + e = min_t(size_t, s + BM_WORDS_PER_AL_EXT, b->bm_words); + /* assert that s and e are on the same page */ + D_ASSERT((e-1) >> (PAGE_SHIFT - LN2_BPL + 3) + == s >> (PAGE_SHIFT - LN2_BPL + 3)); + count = 0; + if (s < b->bm_words) { + i = do_now = e-s; + p_addr = bm_map_paddr(b, s); + bm = p_addr + MLPP(s); + while (i--) { + catch_oob_access_start(); + count += hweight_long(*bm); + *bm = -1UL; + catch_oob_access_end(); + bm++; + } + bm_unmap(p_addr); + b->bm_set += do_now*BITS_PER_LONG - count; + if (e == b->bm_words) + b->bm_set -= bm_clear_surplus(b); + } else { + ERR("start offset (%d) too large in drbd_bm_ALe_set_all\n", s); + } + weight = b->bm_set - weight; + spin_unlock_irq(&b->bm_lock); + return weight; +} --- linux-2.6.28.orig/ubuntu/drbd/Kconfig +++ linux-2.6.28/ubuntu/drbd/Kconfig @@ -0,0 +1,32 @@ +# +# DRBD device driver configuration +# +config BLK_DEV_DRBD + tristate "DRBD Distributed Replicated Block Device support" + select INET + select PROC_FS + select CONNECTOR + select CRYPTO + select CRYPTO_HMAC + ---help--- + DRBD is a block device which is designed to build high availability + clusters. This is done by mirroring a whole block device via (a + dedicated) network. You could see it as a network RAID 1. + + Each minor device has a state, which can be 'primary' or 'secondary'. + On the node with the primary device the application is supposed to + run and to access the device (/dev/drbdX). Every write is sent to the + local 'lower level block device' and via network to the node with the + device in 'secondary' state. + The secondary device simply writes the data to its lower level block + device. Currently no read-balancing via the network is done. + + DRBD can also be used with "shared-disk semantics" (primary-primary), + even though it is a "shared-nothing cluster". You'd need to use a + cluster file system on top of that for cache coherency. + + DRBD management is done through user-space tools. + For automatic failover you need a cluster manager (e.g. heartbeat). + See also: http://www.drbd.org/, http://www.linux-ha.org + + If unsure, say N. --- linux-2.6.28.orig/ubuntu/drbd/drbd_main.c +++ linux-2.6.28/ubuntu/drbd/drbd_main.c @@ -0,0 +1,4054 @@ +/* +-*- Linux-c -*- + drbd.c + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2001-2008, LINBIT Information Technologies GmbH. + Copyright (C) 1999-2008, Philipp Reisner . + Copyright (C) 2002-2008, Lars Ellenberg . + + drbd is free software; you can redistribute 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. + + drbd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with drbd; see the file COPYING. If not, write to + the Free Software Foundation, 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 +#include +#include + +#define __KERNEL_SYSCALLS__ +#include +#include + +#include +#include +#include "drbd_int.h" +#include "drbd_req.h" /* only for _req_mod in tl_release and tl_clear */ + +struct after_state_chg_work { + struct drbd_work w; + union drbd_state_t os; + union drbd_state_t ns; + enum chg_state_flags flags; + struct completion *done; +}; + +int drbdd_init(struct Drbd_thread *); +int drbd_worker(struct Drbd_thread *); +int drbd_asender(struct Drbd_thread *); + +int drbd_init(void); +#ifdef BD_OPS_USE_FMODE +static int drbd_open(struct block_device *bdev, fmode_t mode); +static int drbd_release(struct gendisk *gd, fmode_t mode); +#else +static int drbd_open(struct inode *inode, struct file *file); +static int drbd_release(struct inode *inode, struct file *file); +#endif +STATIC int w_after_state_ch(struct drbd_conf *mdev, struct drbd_work *w, int unused); +STATIC void after_state_ch(struct drbd_conf *mdev, union drbd_state_t os, + union drbd_state_t ns, enum chg_state_flags flags); +STATIC int w_md_sync(struct drbd_conf *mdev, struct drbd_work *w, int unused); +STATIC void md_sync_timer_fn(unsigned long data); + +MODULE_AUTHOR("Philipp Reisner , " + "Lars Ellenberg "); +MODULE_DESCRIPTION("drbd - Distributed Replicated Block Device v" REL_VERSION); +MODULE_LICENSE("GPL"); +MODULE_PARM_DESC(minor_count, "Maximum number of drbd devices (1-255)"); +MODULE_ALIAS_BLOCKDEV_MAJOR(DRBD_MAJOR); + +#include +/* allow_open_on_secondary */ +MODULE_PARM_DESC(allow_oos, "DONT USE!"); +/* thanks to these macros, if compiled into the kernel (not-module), + * this becomes the boot parameter drbd.minor_count */ +module_param(minor_count, uint, 0444); +module_param(allow_oos, bool, 0); +module_param(cn_idx, uint, 0444); + +#ifdef DRBD_ENABLE_FAULTS +int enable_faults; +int fault_rate; +static int fault_count; +int fault_devs; +/* bitmap of enabled faults */ +module_param(enable_faults, int, 0664); +/* fault rate % value - applies to all enabled faults */ +module_param(fault_rate, int, 0664); +/* count of faults inserted */ +module_param(fault_count, int, 0664); +/* bitmap of devices to insert faults on */ +module_param(fault_devs, int, 0644); +#endif + +/* module parameter, defined */ +unsigned int minor_count = 32; +int allow_oos; +unsigned int cn_idx = CN_IDX_DRBD; + +#ifdef ENABLE_DYNAMIC_TRACE +int trace_type; /* Bitmap of trace types to enable */ +int trace_level; /* Current trace level */ +int trace_devs; /* Bitmap of devices to trace */ +int proc_details; /* Detail level in proc drbd*/ + +module_param(trace_level, int, 0644); +module_param(trace_type, int, 0644); +module_param(trace_devs, int, 0644); +module_param(proc_details, int, 0644); +#endif + +/* Module parameter for setting the user mode helper program + * to run. Default is /sbin/drbdadm */ +char usermode_helper[80] = "/sbin/drbdadm"; + +module_param_string(usermode_helper, usermode_helper, sizeof(usermode_helper), 0644); + +/* in 2.6.x, our device mapping and config info contains our virtual gendisks + * as member "struct gendisk *vdisk;" + */ +struct drbd_conf **minor_table; + +struct kmem_cache *drbd_request_cache; +struct kmem_cache *drbd_ee_cache; +mempool_t *drbd_request_mempool; +mempool_t *drbd_ee_mempool; + +/* I do not use a standard mempool, because: + 1) I want to hand out the preallocated objects first. + 2) I want to be able to interrupt sleeping allocation with a signal. + Note: This is a single linked list, the next pointer is the private + member of struct page. + */ +struct page *drbd_pp_pool; +spinlock_t drbd_pp_lock; +int drbd_pp_vacant; +wait_queue_head_t drbd_pp_wait; + +STATIC struct block_device_operations drbd_ops = { + .owner = THIS_MODULE, + .open = drbd_open, + .release = drbd_release, +}; + +#define ARRY_SIZE(A) (sizeof(A)/sizeof(A[0])) + +#ifdef __CHECKER__ +/* When checking with sparse, and this is an inline function, sparse will + give tons of false positives. When this is a real functions sparse works. + */ +int _inc_local_if_state(struct drbd_conf *mdev, enum drbd_disk_state mins) +{ + int io_allowed; + + atomic_inc(&mdev->local_cnt); + io_allowed = (mdev->state.disk >= mins); + if (!io_allowed) { + if (atomic_dec_and_test(&mdev->local_cnt)) + wake_up(&mdev->misc_wait); + } + return io_allowed; +} + +#endif + +/************************* The transfer log start */ +STATIC int tl_init(struct drbd_conf *mdev) +{ + struct drbd_barrier *b; + + b = kmalloc(sizeof(struct drbd_barrier), GFP_KERNEL); + if (!b) + return 0; + INIT_LIST_HEAD(&b->requests); + INIT_LIST_HEAD(&b->w.list); + b->next = NULL; + b->br_number = 4711; + b->n_req = 0; + b->w.cb = NULL; /* if this is != NULL, we need to dec_ap_pending in tl_clear */ + + mdev->oldest_barrier = b; + mdev->newest_barrier = b; + INIT_LIST_HEAD(&mdev->out_of_sequence_requests); + + mdev->tl_hash = NULL; + mdev->tl_hash_s = 0; + + return 1; +} + +STATIC void tl_cleanup(struct drbd_conf *mdev) +{ + D_ASSERT(mdev->oldest_barrier == mdev->newest_barrier); + D_ASSERT(list_empty(&mdev->out_of_sequence_requests)); + kfree(mdev->oldest_barrier); + kfree(mdev->unused_spare_barrier); + kfree(mdev->tl_hash); + mdev->tl_hash_s = 0; +} + +/** + * _tl_add_barrier: Adds a barrier to the TL. + */ +void _tl_add_barrier(struct drbd_conf *mdev, struct drbd_barrier *new) +{ + struct drbd_barrier *newest_before; + + INIT_LIST_HEAD(&new->requests); + INIT_LIST_HEAD(&new->w.list); + new->w.cb = NULL; /* if this is != NULL, we need to dec_ap_pending in tl_clear */ + new->next = NULL; + new->n_req = 0; + + newest_before = mdev->newest_barrier; + /* never send a barrier number == 0, because that is special-cased + * when using TCQ for our write ordering code */ + new->br_number = (newest_before->br_number+1) ?: 1; + if (mdev->newest_barrier != new) { + mdev->newest_barrier->next = new; + mdev->newest_barrier = new; + } +} + +/* when we receive a barrier ack */ +void tl_release(struct drbd_conf *mdev, unsigned int barrier_nr, + unsigned int set_size) +{ + struct drbd_barrier *b, *nob; /* next old barrier */ + struct list_head *le, *tle; + struct drbd_request *r; + + spin_lock_irq(&mdev->req_lock); + + b = mdev->oldest_barrier; + + /* first some paranoia code */ + if (b == NULL) { + ERR("BAD! BarrierAck #%u received, but no epoch in tl!?\n", + barrier_nr); + goto bail; + } + if (b->br_number != barrier_nr) { + ERR("BAD! BarrierAck #%u received, expected #%u!\n", + barrier_nr, b->br_number); + goto bail; + } + if (b->n_req != set_size) { + ERR("BAD! BarrierAck #%u received with n_req=%u, expected n_req=%u!\n", + barrier_nr, set_size, b->n_req); + goto bail; + } + + /* Clean up list of requests processed during current epoch */ + list_for_each_safe(le, tle, &b->requests) { + r = list_entry(le, struct drbd_request, tl_requests); + _req_mod(r, barrier_acked, 0); + } + /* There could be requests on the list waiting for completion + of the write to the local disk. To avoid corruptions of + slab's data structures we have to remove the lists head. + + Also there could have been a barrier ack out of sequence, overtaking + the write acks - which would be a but and violating write ordering. + To not deadlock in case we lose connection while such requests are + still pending, we need some way to find them for the + _req_mode(connection_lost_while_pending). + + These have been list_move'd to the out_of_sequence_requests list in + _req_mod(, barrier_acked,) above. + */ + list_del_init(&b->requests); + + nob = b->next; + if (test_and_clear_bit(CREATE_BARRIER, &mdev->flags)) { + _tl_add_barrier(mdev, b); + if (nob) + mdev->oldest_barrier = nob; + /* if nob == NULL b was the only barrier, and becomes the new + barrer. Threfore mdev->oldest_barrier points already to b */ + } else { + D_ASSERT(nob != NULL); + mdev->oldest_barrier = nob; + kfree(b); + } + + spin_unlock_irq(&mdev->req_lock); + dec_ap_pending(mdev); + + return; + +bail: + spin_unlock_irq(&mdev->req_lock); + drbd_force_state(mdev, NS(conn, ProtocolError)); +} + + +/* called by drbd_disconnect (exiting receiver thread) + * or from some after_state_ch */ +void tl_clear(struct drbd_conf *mdev) +{ + struct drbd_barrier *b, *tmp; + struct list_head *le, *tle; + struct drbd_request *r; + int new_initial_bnr = net_random(); + + spin_lock_irq(&mdev->req_lock); + + b = mdev->oldest_barrier; + while (b) { + list_for_each_safe(le, tle, &b->requests) { + r = list_entry(le, struct drbd_request, tl_requests); + _req_mod(r, connection_lost_while_pending, 0); + } + tmp = b->next; + + /* there could still be requests on that ring list, + * in case local io is still pending */ + list_del(&b->requests); + + /* dec_ap_pending corresponding to queue_barrier. + * the newest barrier may not have been queued yet, + * in which case w.cb is still NULL. */ + if (b->w.cb != NULL) + dec_ap_pending(mdev); + + if (b == mdev->newest_barrier) { + /* recycle, but reinit! */ + D_ASSERT(tmp == NULL); + INIT_LIST_HEAD(&b->requests); + INIT_LIST_HEAD(&b->w.list); + b->w.cb = NULL; + b->br_number = new_initial_bnr; + b->n_req = 0; + + mdev->oldest_barrier = b; + break; + } + kfree(b); + b = tmp; + } + + /* we expect this list to be empty. */ + D_ASSERT(list_empty(&mdev->out_of_sequence_requests)); + + /* but just in case, clean it up anyways! */ + list_for_each_safe(le, tle, &mdev->out_of_sequence_requests) { + r = list_entry(le, struct drbd_request, tl_requests); + _req_mod(r, connection_lost_while_pending, 0); + } + + /* ensure bit indicating barrier is required is clear */ + clear_bit(CREATE_BARRIER, &mdev->flags); + + spin_unlock_irq(&mdev->req_lock); +} + +/** + * drbd_io_error: Handles the on_io_error setting, should be called in the + * unlikely(!drbd_bio_uptodate(e->bio)) case from kernel thread context. + * See also drbd_chk_io_error + * + * NOTE: we set ourselves FAILED here if on_io_error is Detach or Panic OR + * if the forcedetach flag is set. This flag is set when failures + * occur writing the meta data portion of the disk as they are + * not recoverable. We also try to write the "need full sync bit" here + * anyways. This is to make sure that you get a resynchronisation of + * the full device the next time you connect. + */ +int drbd_io_error(struct drbd_conf *mdev, int forcedetach) +{ + enum io_error_handler eh; + unsigned long flags; + int send; + int ok = 1; + + eh = PassOn; + if (inc_local_if_state(mdev, Failed)) { + eh = mdev->bc->dc.on_io_error; + dec_local(mdev); + } + + if (!forcedetach && eh == PassOn) + return 1; + + spin_lock_irqsave(&mdev->req_lock, flags); + send = (mdev->state.disk == Failed); + if (send) + _drbd_set_state(_NS(mdev, disk, Diskless), ChgStateHard, NULL); + spin_unlock_irqrestore(&mdev->req_lock, flags); + + if (!send) + return ok; + + if (mdev->state.conn >= Connected) { + ok = drbd_send_state(mdev); + if (ok) + drbd_WARN("Notified peer that my disk is broken.\n"); + else + ERR("Sending state in drbd_io_error() failed\n"); + } + + /* Make sure we try to flush meta-data to disk - we come + * in here because of a local disk error so it might fail + * but we still need to try -- both because the error might + * be in the data portion of the disk and because we need + * to ensure the md-sync-timer is stopped if running. */ + drbd_md_sync(mdev); + + /* Releasing the backing device is done in after_state_ch() */ + + if (eh == CallIOEHelper) + drbd_khelper(mdev, "local-io-error"); + + return ok; +} + +#if DRBD_DEBUG_STATE_CHANGES +static void trace_st(struct drbd_conf *mdev, const unsigned long long seq, + const char *func, unsigned int line, + const char *name, union drbd_state_t s); +#endif + +/** + * cl_wide_st_chg: + * Returns TRUE if this state change should be preformed as a cluster wide + * transaction. Of course it returns 0 as soon as the connection is lost. + */ +STATIC int cl_wide_st_chg(struct drbd_conf *mdev, + union drbd_state_t os, union drbd_state_t ns) +{ + return (os.conn >= Connected && ns.conn >= Connected && + ((os.role != Primary && ns.role == Primary) || + (os.conn != StartingSyncT && ns.conn == StartingSyncT) || + (os.conn != StartingSyncS && ns.conn == StartingSyncS) || + (os.disk != Diskless && ns.disk == Diskless))) || + (os.conn >= Connected && ns.conn == Disconnecting) || + (os.conn == Connected && ns.conn == VerifyS); +} + +int drbd_change_state(struct drbd_conf *mdev, enum chg_state_flags f, + union drbd_state_t mask, union drbd_state_t val) +{ +#if DRBD_DEBUG_STATE_CHANGES + static unsigned long long sseq = 0xf0000000LLU; + unsigned long seq; + unsigned int line = val.line; + const char *func = val.func; +#endif + + unsigned long flags; + union drbd_state_t os, ns; + int rv; + + spin_lock_irqsave(&mdev->req_lock, flags); + os = mdev->state; + ns.i = (os.i & ~mask.i) | val.i; +#if DRBD_DEBUG_STATE_CHANGES + seq = ++sseq; + trace_st(mdev, seq, func, line, "!os", os); + trace_st(mdev, seq, func, line, "!ns", ns); + ns.func = NULL; +#endif + rv = _drbd_set_state(mdev, ns, f, NULL); + ns = mdev->state; +#if DRBD_DEBUG_STATE_CHANGES + trace_st(mdev, seq, func, line, "=ns", ns); +#endif + spin_unlock_irqrestore(&mdev->req_lock, flags); + + return rv; +} + +void drbd_force_state(struct drbd_conf *mdev, + union drbd_state_t mask, union drbd_state_t val) +{ + drbd_change_state(mdev, ChgStateHard, mask, val); +} + +int is_valid_state(struct drbd_conf *mdev, union drbd_state_t ns); +int is_valid_state_transition(struct drbd_conf *, + union drbd_state_t, union drbd_state_t); +int drbd_send_state_req(struct drbd_conf *, + union drbd_state_t, union drbd_state_t); + +STATIC enum set_st_err _req_st_cond(struct drbd_conf *mdev, + union drbd_state_t mask, union drbd_state_t val) +{ + union drbd_state_t os, ns; + unsigned long flags; + int rv; + + if (test_and_clear_bit(CL_ST_CHG_SUCCESS, &mdev->flags)) + return SS_CW_Success; + + if (test_and_clear_bit(CL_ST_CHG_FAIL, &mdev->flags)) + return SS_CW_FailedByPeer; + + rv = 0; + spin_lock_irqsave(&mdev->req_lock, flags); + os = mdev->state; + ns.i = (os.i & ~mask.i) | val.i; + if (!cl_wide_st_chg(mdev, os, ns)) + rv = SS_CW_NoNeed; + if (!rv) { + rv = is_valid_state(mdev, ns); + if (rv == SS_Success) { + rv = is_valid_state_transition(mdev, ns, os); + if (rv == SS_Success) + rv = 0; /* cont waiting, otherwise fail. */ + } + } + spin_unlock_irqrestore(&mdev->req_lock, flags); + + return rv; +} + +/** + * _drbd_request_state: + * This function is the most gracefull way to change state. For some state + * transition this function even does a cluster wide transaction. + * It has a cousin named drbd_request_state(), which is always verbose. + */ +STATIC int drbd_req_state(struct drbd_conf *mdev, + union drbd_state_t mask, union drbd_state_t val, + enum chg_state_flags f) +{ +#if DRBD_DEBUG_STATE_CHANGES + static unsigned long long sseq = 0; + unsigned long seq; + unsigned int line = val.line; + const char *func = val.func; +#endif + + struct completion done; + unsigned long flags; + union drbd_state_t os, ns; + int rv; + + init_completion(&done); + + if (f & ChgSerialize) + mutex_lock(&mdev->state_mutex); + + spin_lock_irqsave(&mdev->req_lock, flags); + os = mdev->state; + ns.i = (os.i & ~mask.i) | val.i; + +#if DRBD_DEBUG_STATE_CHANGES + seq = ++sseq; + trace_st(mdev, seq, func, line, "?os", os); + trace_st(mdev, seq, func, line, "?ns", ns); + ns.func = NULL; +#endif + + if (cl_wide_st_chg(mdev, os, ns)) { + rv = is_valid_state(mdev, ns); + if (rv == SS_Success) + rv = is_valid_state_transition(mdev, ns, os); + spin_unlock_irqrestore(&mdev->req_lock, flags); + + if (rv < SS_Success) { + if (f & ChgStateVerbose) + print_st_err(mdev, os, ns, rv); + goto abort; + } + + drbd_state_lock(mdev); + if (!drbd_send_state_req(mdev, mask, val)) { + drbd_state_unlock(mdev); + rv = SS_CW_FailedByPeer; + if (f & ChgStateVerbose) + print_st_err(mdev, os, ns, rv); + goto abort; + } + + wait_event(mdev->state_wait, + (rv = _req_st_cond(mdev, mask, val))); + + if (rv < SS_Success) { + /* nearly dead code. */ + drbd_state_unlock(mdev); + if (f & ChgStateVerbose) + print_st_err(mdev, os, ns, rv); + goto abort; + } + spin_lock_irqsave(&mdev->req_lock, flags); + os = mdev->state; + ns.i = (os.i & ~mask.i) | val.i; + rv = _drbd_set_state(mdev, ns, f, &done); + drbd_state_unlock(mdev); + } else { + rv = _drbd_set_state(mdev, ns, f, &done); + } + + spin_unlock_irqrestore(&mdev->req_lock, flags); + + if (f & ChgWaitComplete && rv == SS_Success) { + D_ASSERT(current != mdev->worker.task); + wait_for_completion(&done); + } + +abort: +#if DRBD_DEBUG_STATE_CHANGES + trace_st(mdev, seq, func, line, ":os", os); + trace_st(mdev, seq, func, line, ":ns", ns); +#endif + + if (f & ChgSerialize) + mutex_unlock(&mdev->state_mutex); + + return rv; +} + +/** + * _drbd_request_state: + * This function is the most gracefull way to change state. For some state + * transition this function even does a cluster wide transaction. + * It has a cousin named drbd_request_state(), which is always verbose. + */ +int _drbd_request_state(struct drbd_conf *mdev, union drbd_state_t mask, + union drbd_state_t val, enum chg_state_flags f) +{ + int rv; + + wait_event(mdev->state_wait, + (rv = drbd_req_state(mdev, mask, val, f)) != SS_InTransientState); + + return rv; +} + +#if DRBD_DEBUG_STATE_CHANGES +static void trace_st(struct drbd_conf *mdev, const unsigned long long seq, + const char *func, unsigned int line, + const char *name, union drbd_state_t s) +{ + + const struct task_struct *c = current; + const char *context = + c == mdev->worker.task ? "worker" : + c == mdev->receiver.task ? "receiver" : + c == mdev->asender.task ? "asender" : "other"; + + DBG(" %8llx [%s] %s:%u %s = { cs:%s ro:%s/%s ds:%s/%s %c%c%c%c }\n", + seq, context, func, line, + name, + conns_to_name(s.conn), + roles_to_name(s.role), + roles_to_name(s.peer), + disks_to_name(s.disk), + disks_to_name(s.pdsk), + s.susp ? 's' : 'r', + s.aftr_isp ? 'a' : '-', + s.peer_isp ? 'p' : '-', + s.user_isp ? 'u' : '-' + ); +} +#else +#define trace_st(...) do { } while (0) +#endif + +STATIC void print_st(struct drbd_conf *mdev, char *name, union drbd_state_t ns) +{ + ERR(" %s = { cs:%s ro:%s/%s ds:%s/%s %c%c%c%c }\n", + name, + conns_to_name(ns.conn), + roles_to_name(ns.role), + roles_to_name(ns.peer), + disks_to_name(ns.disk), + disks_to_name(ns.pdsk), + ns.susp ? 's' : 'r', + ns.aftr_isp ? 'a' : '-', + ns.peer_isp ? 'p' : '-', + ns.user_isp ? 'u' : '-' + ); +} + +void print_st_err(struct drbd_conf *mdev, + union drbd_state_t os, union drbd_state_t ns, int err) +{ + if (err == SS_InTransientState) + return; + ERR("State change failed: %s\n", set_st_err_name(err)); + print_st(mdev, " state", os); + print_st(mdev, "wanted", ns); +} + + +#define peers_to_name roles_to_name +#define pdsks_to_name disks_to_name + +#define susps_to_name(A) ((A) ? "1" : "0") +#define aftr_isps_to_name(A) ((A) ? "1" : "0") +#define peer_isps_to_name(A) ((A) ? "1" : "0") +#define user_isps_to_name(A) ((A) ? "1" : "0") + +#define PSC(A) \ + ({ if (ns.A != os.A) { \ + pbp += sprintf(pbp, #A "( %s -> %s ) ", \ + A##s_to_name(os.A), \ + A##s_to_name(ns.A)); \ + } }) + +int is_valid_state(struct drbd_conf *mdev, union drbd_state_t ns) +{ + /* See drbd_state_sw_errors in drbd_strings.c */ + + enum fencing_policy fp; + int rv = SS_Success; + + fp = DontCare; + if (inc_local(mdev)) { + fp = mdev->bc->dc.fencing; + dec_local(mdev); + } + + if (inc_net(mdev)) { + if (!mdev->net_conf->two_primaries && + ns.role == Primary && ns.peer == Primary) + rv = SS_TwoPrimaries; + dec_net(mdev); + } + + if (rv <= 0) + /* already found a reason to abort */; + else if (ns.role == Secondary && mdev->open_cnt) + rv = SS_DeviceInUse; + + else if (ns.role == Primary && ns.conn < Connected && ns.disk < UpToDate) + rv = SS_NoUpToDateDisk; + + else if (fp >= Resource && + ns.role == Primary && ns.conn < Connected && ns.pdsk >= DUnknown) + rv = SS_PrimaryNOP; + + else if (ns.role == Primary && ns.disk <= Inconsistent && ns.pdsk <= Inconsistent) + rv = SS_NoUpToDateDisk; + + else if (ns.conn > Connected && ns.disk < UpToDate && ns.pdsk < UpToDate) + rv = SS_BothInconsistent; + + else if (ns.conn > Connected && (ns.disk == Diskless || ns.pdsk == Diskless)) + rv = SS_SyncingDiskless; + + else if ((ns.conn == Connected || + ns.conn == WFBitMapS || + ns.conn == SyncSource || + ns.conn == PausedSyncS) && + ns.disk == Outdated) + rv = SS_ConnectedOutdates; + + else if( (ns.conn == VerifyS || + ns.conn == VerifyT) && + (mdev->sync_conf.verify_alg[0] == 0)) rv=SS_NoVerifyAlg; + + else if( (ns.conn == VerifyS || + ns.conn == VerifyT) && + mdev->agreed_pro_version < 88) rv = SS_NotSupported; + + return rv; +} + +int is_valid_state_transition(struct drbd_conf *mdev, + union drbd_state_t ns, union drbd_state_t os) +{ + int rv = SS_Success; + + if ((ns.conn == StartingSyncT || ns.conn == StartingSyncS) && + os.conn > Connected) + rv = SS_ResyncRunning; + + if (ns.conn == Disconnecting && os.conn == StandAlone) + rv = SS_AlreadyStandAlone; + + if (ns.disk > Attaching && os.disk == Diskless) + rv = SS_IsDiskLess; + + if (ns.conn == WFConnection && os.conn < Unconnected) + rv = SS_NoNetConfig; + + if (ns.disk == Outdated && os.disk < Outdated && os.disk != Attaching) + rv = SS_LowerThanOutdated; + + if (ns.conn == Disconnecting && os.conn == Unconnected) + rv = SS_InTransientState; + + if (ns.conn == os.conn && ns.conn == WFReportParams) + rv = SS_InTransientState; + + if ((ns.conn == VerifyS || ns.conn == VerifyT) && os.conn < Connected) + rv=SS_NeedConnection; + + if ((ns.conn == VerifyS || ns.conn == VerifyT) && + ns.conn != os.conn && os.conn > Connected) + rv = SS_ResyncRunning; + + if ((ns.conn == StartingSyncS || ns.conn == StartingSyncT) && + os.conn < Connected) + rv = SS_NeedConnection; + + return rv; +} + +int _drbd_set_state(struct drbd_conf *mdev, + union drbd_state_t ns, enum chg_state_flags flags, + struct completion *done) +{ +#if DRBD_DEBUG_STATE_CHANGES + static unsigned long long sseq = 0xff000000LLU; + unsigned long long seq = 0; +#endif + union drbd_state_t os; + int rv = SS_Success; + int warn_sync_abort = 0; + enum fencing_policy fp; + struct after_state_chg_work *ascw; + + MUST_HOLD(&mdev->req_lock); + + os = mdev->state; + +#if DRBD_DEBUG_STATE_CHANGES + if (ns.func) { + seq = ++sseq; + trace_st(mdev, seq, ns.func, ns.line, "==os", os); + trace_st(mdev, seq, ns.func, ns.line, "==ns", ns); + } +#endif + + fp = DontCare; + if (inc_local(mdev)) { + fp = mdev->bc->dc.fencing; + dec_local(mdev); + } + + /* Early state sanitising. */ + + /* Dissalow the invalidate command to connect */ + if ((ns.conn == StartingSyncS || ns.conn == StartingSyncT) && + os.conn < Connected) { + ns.conn = os.conn; + ns.pdsk = os.pdsk; + } + + /* Dissalow Network errors to configure a device's network part */ + if ((ns.conn >= Timeout && ns.conn <= TearDown) && + os.conn <= Disconnecting) + ns.conn = os.conn; + + /* After a network error (+TearDown) only Unconnected or Disconnecting can follow */ + if (os.conn >= Timeout && os.conn <= TearDown && + ns.conn != Unconnected && ns.conn != Disconnecting) + ns.conn = os.conn; + + /* After Disconnecting only StandAlone may follow */ + if (os.conn == Disconnecting && ns.conn != StandAlone) + ns.conn = os.conn; + + if (ns.conn < Connected) { + ns.peer_isp = 0; + ns.peer = Unknown; + if (ns.pdsk > DUnknown || ns.pdsk < Inconsistent) + ns.pdsk = DUnknown; + } + + if (ns.conn <= Disconnecting && ns.disk == Diskless) + ns.pdsk = DUnknown; + + if (os.conn > Connected && ns.conn > Connected && + (ns.disk <= Failed || ns.pdsk <= Failed)) { + warn_sync_abort = 1; + ns.conn = Connected; + } + + if (ns.conn >= Connected && + ((ns.disk == Consistent || ns.disk == Outdated) || + (ns.disk == Negotiating && ns.conn == WFBitMapT))) { + switch (ns.conn) { + case WFBitMapT: + case PausedSyncT: + ns.disk = Outdated; + break; + case Connected: + case WFBitMapS: + case SyncSource: + case PausedSyncS: + ns.disk = UpToDate; + break; + case SyncTarget: + ns.disk = Inconsistent; + drbd_WARN("Implicit set disk state Inconsistent!\n"); + break; + } + if (os.disk == Outdated && ns.disk == UpToDate) + drbd_WARN("Implicit set disk from Outdate to UpToDate\n"); + } + + if (ns.conn >= Connected && + (ns.pdsk == Consistent || ns.pdsk == Outdated)) { + switch (ns.conn) { + case Connected: + case WFBitMapT: + case PausedSyncT: + case SyncTarget: + ns.pdsk = UpToDate; + break; + case WFBitMapS: + case PausedSyncS: + ns.pdsk = Outdated; + break; + case SyncSource: + ns.pdsk = Inconsistent; + drbd_WARN("Implicit set pdsk Inconsistent!\n"); + break; + } + if (os.pdsk == Outdated && ns.pdsk == UpToDate) + drbd_WARN("Implicit set pdsk from Outdate to UpToDate\n"); + } + + /* Connection breaks down before we finished "Negotiating" */ + if (ns.conn < Connected && ns.disk == Negotiating && + inc_local_if_state(mdev, Negotiating)) { + if (mdev->ed_uuid == mdev->bc->md.uuid[Current]) { + ns.disk = mdev->new_state_tmp.disk; + ns.pdsk = mdev->new_state_tmp.pdsk; + } else { + ALERT("Connection lost while negotiating, no data!\n"); + ns.disk = Diskless; + ns.pdsk = DUnknown; + } + dec_local(mdev); + } + + if (fp == Stonith && + (ns.role == Primary && + ns.conn < Connected && + ns.pdsk > Outdated)) + ns.susp = 1; + + if (ns.aftr_isp || ns.peer_isp || ns.user_isp) { + if (ns.conn == SyncSource) + ns.conn = PausedSyncS; + if (ns.conn == SyncTarget) + ns.conn = PausedSyncT; + } else { + if (ns.conn == PausedSyncS) + ns.conn = SyncSource; + if (ns.conn == PausedSyncT) + ns.conn = SyncTarget; + } + +#if DRBD_DEBUG_STATE_CHANGES + if (ns.func) + trace_st(mdev, seq, ns.func, ns.line, "==ns", ns); +#endif + + if (ns.i == os.i) + return SS_NothingToDo; + + if (!(flags & ChgStateHard)) { + /* pre-state-change checks ; only look at ns */ + /* See drbd_state_sw_errors in drbd_strings.c */ + + rv = is_valid_state(mdev, ns); + if (rv < SS_Success) { + /* If the old state was illegal as well, then let + this happen...*/ + + if (is_valid_state(mdev, os) == rv) { + ERR("Considering state change from bad state. " + "Error would be: '%s'\n", + set_st_err_name(rv)); + print_st(mdev, "old", os); + print_st(mdev, "new", ns); + rv = is_valid_state_transition(mdev, ns, os); + } + } else + rv = is_valid_state_transition(mdev, ns, os); + } + + if (rv < SS_Success) { + if (flags & ChgStateVerbose) + print_st_err(mdev, os, ns, rv); + return rv; + } + + if (warn_sync_abort) + drbd_WARN("Resync aborted.\n"); + +#if DUMP_MD >= 2 + { + char *pbp, pb[300]; + pbp = pb; + *pbp = 0; + PSC(role); + PSC(peer); + PSC(conn); + PSC(disk); + PSC(pdsk); + PSC(susp); + PSC(aftr_isp); + PSC(peer_isp); + PSC(user_isp); + INFO("%s\n", pb); + } +#endif + +#if DRBD_DEBUG_STATE_CHANGES + if (ns.func) + trace_st(mdev, seq, ns.func, ns.line, ":=ns", ns); +#endif + + mdev->state.i = ns.i; + wake_up(&mdev->misc_wait); + wake_up(&mdev->state_wait); + + /** post-state-change actions **/ + if (os.conn >= SyncSource && ns.conn <= Connected) { + set_bit(STOP_SYNC_TIMER, &mdev->flags); + mod_timer(&mdev->resync_timer, jiffies); + } + + if ((os.conn == PausedSyncT || os.conn == PausedSyncS) && + (ns.conn == SyncTarget || ns.conn == SyncSource)) { + INFO("Syncer continues.\n"); + mdev->rs_paused += (long)jiffies-(long)mdev->rs_mark_time; + if (ns.conn == SyncTarget) { + if (!test_and_clear_bit(STOP_SYNC_TIMER, &mdev->flags)) + mod_timer(&mdev->resync_timer, jiffies); + /* This if (!test_bit) is only needed for the case + that a device that has ceased to used its timer, + i.e. it is already in drbd_resync_finished() gets + paused and resumed. */ + } + } + + if ((os.conn == SyncTarget || os.conn == SyncSource) && + (ns.conn == PausedSyncT || ns.conn == PausedSyncS)) { + INFO("Resync suspended\n"); + mdev->rs_mark_time = jiffies; + if (ns.conn == PausedSyncT) + set_bit(STOP_SYNC_TIMER, &mdev->flags); + } + + if (os.conn == Connected && + (ns.conn == VerifyS || ns.conn == VerifyT )) { + mdev->ov_position = 0; + mdev->ov_left = + mdev->rs_total = + mdev->rs_mark_left = drbd_bm_bits(mdev); + mdev->rs_start = + mdev->rs_mark_time = jiffies; + mdev->ov_last_oos_size = 0; + mdev->ov_last_oos_start = 0; + + if (ns.conn == VerifyS) + mod_timer(&mdev->resync_timer,jiffies); + } + + if (inc_local(mdev)) { + u32 mdf = mdev->bc->md.flags & ~(MDF_Consistent|MDF_PrimaryInd| + MDF_ConnectedInd|MDF_WasUpToDate| + MDF_PeerOutDated); + + if (test_bit(CRASHED_PRIMARY, &mdev->flags) || + mdev->state.role == Primary || + (mdev->state.pdsk < Inconsistent && mdev->state.peer == Primary)) + mdf |= MDF_PrimaryInd; + if (mdev->state.conn > WFReportParams) + mdf |= MDF_ConnectedInd; + if (mdev->state.disk > Inconsistent) + mdf |= MDF_Consistent; + if (mdev->state.disk > Outdated) + mdf |= MDF_WasUpToDate; + if (mdev->state.pdsk <= Outdated && mdev->state.pdsk >= Inconsistent) + mdf |= MDF_PeerOutDated; + if (mdf != mdev->bc->md.flags) { + mdev->bc->md.flags = mdf; + drbd_md_mark_dirty(mdev); + } + if (os.disk < Consistent && ns.disk >= Consistent) + drbd_set_ed_uuid(mdev, mdev->bc->md.uuid[Current]); + dec_local(mdev); + } + + /* Peer was forced UpToDate & Primary, consider to resync */ + if (os.disk == Inconsistent && os.pdsk == Inconsistent && + os.peer == Secondary && ns.peer == Primary) + set_bit(CONSIDER_RESYNC, &mdev->flags); + + /* Receiver should clean up itself */ + if (os.conn != Disconnecting && ns.conn == Disconnecting) + drbd_thread_stop_nowait(&mdev->receiver); + + /* Now the receiver finished cleaning up itself, it should die */ + if (os.conn != StandAlone && ns.conn == StandAlone) + drbd_thread_stop_nowait(&mdev->receiver); + + /* Upon network failure, we need to restart the receiver. */ + if (os.conn > TearDown && + ns.conn <= TearDown && ns.conn >= Timeout) + drbd_thread_restart_nowait(&mdev->receiver); + + ascw = kmalloc(sizeof(*ascw), GFP_ATOMIC); + if (ascw) { + ascw->os = os; + ascw->ns = ns; + ascw->flags = flags; + ascw->w.cb = w_after_state_ch; + ascw->done = done; + drbd_queue_work(&mdev->data.work, &ascw->w); + } else { + drbd_WARN("Could not kmalloc an ascw\n"); + } + + return rv; +} + +STATIC int w_after_state_ch(struct drbd_conf *mdev, struct drbd_work *w, int unused) +{ + struct after_state_chg_work *ascw; + + ascw = (struct after_state_chg_work *) w; + after_state_ch(mdev, ascw->os, ascw->ns, ascw->flags); + if (ascw->flags & ChgWaitComplete) { + D_ASSERT(ascw->done != NULL); + complete(ascw->done); + } + kfree(ascw); + + return 1; +} + +static void abw_start_sync(struct drbd_conf *mdev, int rv) +{ + if (rv) { + ERR("Writing the bitmap failed not starting resync.\n"); + _drbd_request_state(mdev, NS(conn, Connected), ChgStateVerbose); + return; + } + + switch (mdev->state.conn) { + case StartingSyncT: + _drbd_request_state(mdev, NS(conn, WFSyncUUID), ChgStateVerbose); + break; + case StartingSyncS: + drbd_start_resync(mdev, SyncSource); + break; + } +} + +STATIC void after_state_ch(struct drbd_conf *mdev, union drbd_state_t os, + union drbd_state_t ns, enum chg_state_flags flags) +{ + enum fencing_policy fp; + + if (os.conn != Connected && ns.conn == Connected) { + clear_bit(CRASHED_PRIMARY, &mdev->flags); + if (mdev->p_uuid) + mdev->p_uuid[UUID_FLAGS] &= ~((u64)2); + } + + fp = DontCare; + if (inc_local(mdev)) { + fp = mdev->bc->dc.fencing; + dec_local(mdev); + } + + /* Inform userspace about the change... */ + drbd_bcast_state(mdev, ns); + + if (!(os.role == Primary && os.disk < UpToDate && os.pdsk < UpToDate) && + (ns.role == Primary && ns.disk < UpToDate && ns.pdsk < UpToDate)) + drbd_khelper(mdev, "pri-on-incon-degr"); + + /* Here we have the actions that are performed after a + state change. This function might sleep */ + + if (fp == Stonith && ns.susp) { + /* case1: The outdate peer handler is successfull: + * case2: The connection was established again: */ + if ((os.pdsk > Outdated && ns.pdsk <= Outdated) || + (os.conn < Connected && ns.conn >= Connected)) { + tl_clear(mdev); + spin_lock_irq(&mdev->req_lock); + _drbd_set_state(_NS(mdev, susp, 0), ChgStateVerbose, NULL); + spin_unlock_irq(&mdev->req_lock); + } + } + /* Do not change the order of the if above and the two below... */ + if (os.pdsk == Diskless && ns.pdsk > Diskless) { /* attach on the peer */ + drbd_send_uuids(mdev); + drbd_send_state(mdev); + } + if (os.conn != WFBitMapS && ns.conn == WFBitMapS) + drbd_queue_bitmap_io(mdev, &drbd_send_bitmap, NULL, "send_bitmap (WFBitMapS)"); + + /* Lost contact to peer's copy of the data */ + if ((os.pdsk >= Inconsistent && + os.pdsk != DUnknown && + os.pdsk != Outdated) + && (ns.pdsk < Inconsistent || + ns.pdsk == DUnknown || + ns.pdsk == Outdated)) { + /* FIXME race with drbd_sync_handshake accessing this! */ + kfree(mdev->p_uuid); + mdev->p_uuid = NULL; + if (inc_local(mdev)) { + if (ns.role == Primary && mdev->bc->md.uuid[Bitmap] == 0 && + ns.disk >= UpToDate) + drbd_uuid_new_current(mdev); + if (ns.peer == Primary) { + /* Note: The condition ns.peer == Primary implies + that we are connected. Otherwise it would + be ns.peer == Unknown. */ + /* A FullSync is required after a + primary detached from its disk! */ + _drbd_uuid_new_current(mdev); + drbd_send_uuids(mdev); + } + dec_local(mdev); + } + } + + if (ns.pdsk < Inconsistent && inc_local(mdev)) { + if (ns.peer == Primary && mdev->bc->md.uuid[Bitmap] == 0) { + /* Diskless Peer becomes primary */ + if (os.peer == Secondary) + drbd_uuid_new_current(mdev); + + /* Got connected to diskless, primary peer */ + if (os.peer == Unknown) + _drbd_uuid_new_current(mdev); + } + + /* Diskless Peer becomes secondary */ + if (os.peer == Primary && ns.peer == Secondary) + drbd_al_to_on_disk_bm(mdev); + dec_local(mdev); + } + + /* Last part of the attaching process ... */ + if (ns.conn >= Connected && + os.disk == Attaching && ns.disk == Negotiating) { + kfree(mdev->p_uuid); /* We expect to receive up-to-date UUIDs soon. */ + mdev->p_uuid = NULL; /* ...to not use the old ones in the mean time */ + drbd_send_sizes(mdev); /* to start sync... */ + drbd_send_uuids(mdev); + drbd_send_state(mdev); + } + + /* We want to pause/continue resync, tell peer. */ + if (ns.conn >= Connected && + ((os.aftr_isp != ns.aftr_isp) || + (os.user_isp != ns.user_isp))) + drbd_send_state(mdev); + + /* In case one of the isp bits got set, suspend other devices. */ + if ((!os.aftr_isp && !os.peer_isp && !os.user_isp) && + (ns.aftr_isp || ns.peer_isp || ns.user_isp)) + suspend_other_sg(mdev); + + /* Make sure the peer gets informed about eventual state + changes (ISP bits) while we were in WFReportParams. */ + if (os.conn == WFReportParams && ns.conn >= Connected) + drbd_send_state(mdev); + + /* We are in the progress to start a full sync... */ + if ((os.conn != StartingSyncT && ns.conn == StartingSyncT) || + (os.conn != StartingSyncS && ns.conn == StartingSyncS)) + drbd_queue_bitmap_io(mdev, &drbd_bmio_set_n_write, &abw_start_sync, "set_n_write from StartingSync"); + + /* We are invalidating our self... */ + if (os.conn < Connected && ns.conn < Connected && + os.disk > Inconsistent && ns.disk == Inconsistent) + drbd_queue_bitmap_io(mdev, &drbd_bmio_set_n_write, NULL, "set_n_write from invalidate"); + + if (os.disk > Diskless && ns.disk == Diskless) { + /* since inc_local() only works as long as disk>=Inconsistent, + and it is Diskless here, local_cnt can only go down, it can + not increase... It will reach zero */ + wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt)); + + lc_free(mdev->resync); + mdev->resync = NULL; + lc_free(mdev->act_log); + mdev->act_log = NULL; + __no_warn(local, drbd_free_bc(mdev->bc);); + wmb(); /* see begin of drbd_nl_disk_conf() */ + __no_warn(local, mdev->bc = NULL;); + } + + /* Disks got bigger while they were detached */ + if (ns.disk > Negotiating && ns.pdsk > Negotiating && + test_and_clear_bit(RESYNC_AFTER_NEG, &mdev->flags)) { + if (ns.conn == Connected) + resync_after_online_grow(mdev); + } + + /* A resync finished or aborted, wake paused devices... */ + if ((os.conn > Connected && ns.conn <= Connected) || + (os.peer_isp && !ns.peer_isp) || + (os.user_isp && !ns.user_isp)) + resume_next_sg(mdev); + + /* Upon network connection, we need to start the received */ + if (os.conn == StandAlone && ns.conn == Unconnected) + drbd_thread_start(&mdev->receiver); + + /* Terminate worker thread if we are unconfigured - it will be + restarted as needed... */ + if (ns.disk == Diskless && ns.conn == StandAlone && ns.role == Secondary) + drbd_thread_stop_nowait(&mdev->worker); + + drbd_md_sync(mdev); +} + + +STATIC int drbd_thread_setup(void *arg) +{ + struct Drbd_thread *thi = (struct Drbd_thread *) arg; + struct drbd_conf *mdev = thi->mdev; + long timeout; + int retval; + const char *me = + thi == &mdev->receiver ? "receiver" : + thi == &mdev->asender ? "asender" : + thi == &mdev->worker ? "worker" : "NONSENSE"; + + daemonize("drbd_thread"); + D_ASSERT(get_t_state(thi) == Running); + D_ASSERT(thi->task == NULL); + spin_lock(&thi->t_lock); + thi->task = current; + smp_mb(); + spin_unlock(&thi->t_lock); + + /* stolen from kthread; FIXME we need to convert to kthread api! + * wait for wakeup */ + __set_current_state(TASK_UNINTERRUPTIBLE); + complete(&thi->startstop); /* notify: thi->task is set. */ + timeout = schedule_timeout(10*HZ); + D_ASSERT(timeout != 0); + +restart: + retval = thi->function(thi); + + spin_lock(&thi->t_lock); + + /* if the receiver has been "Exiting", the last thing it did + * was set the conn state to "StandAlone", + * if now a re-connect request comes in, conn state goes Unconnected, + * and receiver thread will be "started". + * drbd_thread_start needs to set "Restarting" in that case. + * t_state check and assignement needs to be within the same spinlock, + * so either thread_start sees Exiting, and can remap to Restarting, + * or thread_start see None, and can proceed as normal. + */ + + if (thi->t_state == Restarting) { + INFO("Restarting %s thread\n", me); + thi->t_state = Running; + spin_unlock(&thi->t_lock); + goto restart; + } + + thi->task = NULL; + thi->t_state = None; + smp_mb(); + + /* THINK maybe two different completions? */ + complete(&thi->startstop); /* notify: thi->task unset. */ + INFO("Terminating %s thread\n", me); + spin_unlock(&thi->t_lock); + + /* Release mod reference taken when thread was started */ + module_put(THIS_MODULE); + return retval; +} + +STATIC void drbd_thread_init(struct drbd_conf *mdev, struct Drbd_thread *thi, + int (*func) (struct Drbd_thread *)) +{ + spin_lock_init(&thi->t_lock); + thi->task = NULL; + thi->t_state = None; + thi->function = func; + thi->mdev = mdev; +} + +int drbd_thread_start(struct Drbd_thread *thi) +{ + int pid; + struct drbd_conf *mdev = thi->mdev; + const char *me = + thi == &mdev->receiver ? "receiver" : + thi == &mdev->asender ? "asender" : + thi == &mdev->worker ? "worker" : "NONSENSE"; + + spin_lock(&thi->t_lock); + + switch (thi->t_state) { + case None: + INFO("Starting %s thread (from %s [%d])\n", + me, current->comm, current->pid); + + /* Get ref on module for thread - this is released when thread exits */ + if (!try_module_get(THIS_MODULE)) { + ERR("Failed to get module reference in drbd_thread_start\n"); + spin_unlock(&thi->t_lock); + return FALSE; + } + + init_completion(&thi->startstop); + D_ASSERT(thi->task == NULL); + thi->reset_cpu_mask = 1; + thi->t_state = Running; + spin_unlock(&thi->t_lock); + flush_signals(current); /* otherw. may get -ERESTARTNOINTR */ + + /* FIXME rewrite to use kthread interface */ + pid = kernel_thread(drbd_thread_setup, (void *) thi, CLONE_FS); + if (pid < 0) { + ERR("Couldn't start thread (%d)\n", pid); + + module_put(THIS_MODULE); + return FALSE; + } + /* waits until thi->task is set */ + wait_for_completion(&thi->startstop); + if (thi->t_state != Running) + ERR("ASSERT FAILED: %s t_state == %d expected %d.\n", + me, thi->t_state, Running); + if (thi->task) + wake_up_process(thi->task); + else + ERR("ASSERT FAILED thi->task is NULL where it should be set!?\n"); + break; + case Exiting: + thi->t_state = Restarting; + INFO("Restarting %s thread (from %s [%d])\n", + me, current->comm, current->pid); + case Running: + case Restarting: + default: + spin_unlock(&thi->t_lock); + break; + } + + return TRUE; +} + + +void _drbd_thread_stop(struct Drbd_thread *thi, int restart, int wait) +{ + struct drbd_conf *mdev = thi->mdev; + enum Drbd_thread_state ns = restart ? Restarting : Exiting; + const char *me = + thi == &mdev->receiver ? "receiver" : + thi == &mdev->asender ? "asender" : + thi == &mdev->worker ? "worker" : "NONSENSE"; + + spin_lock(&thi->t_lock); + + /* INFO("drbd_thread_stop: %s [%d]: %s %d -> %d; %d\n", + current->comm, current->pid, + thi->task ? thi->task->comm : "NULL", thi->t_state, ns, wait); */ + + if (thi->t_state == None) { + spin_unlock(&thi->t_lock); + if (restart) + drbd_thread_start(thi); + return; + } + + if (thi->t_state != ns) { + if (thi->task == NULL) { + spin_unlock(&thi->t_lock); + return; + } + + thi->t_state = ns; + smp_mb(); + init_completion(&thi->startstop); + if (thi->task != current) { + force_sig(DRBD_SIGKILL, thi->task); + } else + D_ASSERT(!wait); + } + spin_unlock(&thi->t_lock); + + if (wait) { + D_ASSERT(thi->task != current); + wait_for_completion(&thi->startstop); + spin_lock(&thi->t_lock); + D_ASSERT(thi->task == NULL); + if (thi->t_state != None) + ERR("ASSERT FAILED: %s t_state == %d expected %d.\n", + me, thi->t_state, None); + spin_unlock(&thi->t_lock); + } +} + +#ifdef CONFIG_SMP +/** + * drbd_calc_cpu_mask: Generates CPU masks, sprad over all CPUs. + * Forces all threads of a device onto the same CPU. This is benificial for + * DRBD's performance. May be overwritten by user's configuration. + */ +cpumask_t drbd_calc_cpu_mask(struct drbd_conf *mdev) +{ + int sv, cpu; + cpumask_t av_cpu_m; + + if (cpus_weight(mdev->cpu_mask)) + return mdev->cpu_mask; + + av_cpu_m = cpu_online_map; + sv = mdev_to_minor(mdev) % cpus_weight(av_cpu_m); + + for_each_cpu_mask(cpu, av_cpu_m) { + if (sv-- == 0) + return cpumask_of_cpu(cpu); + } + + /* some kernel versions "forget" to add the (cpumask_t) typecast + * to that macro, which results in "parse error before '{'" ;-> */ + return (cpumask_t) CPU_MASK_ALL; /* Never reached. */ +} + +/* modifies the cpu mask of the _current_ thread, + * call in the "main loop" of _all_ threads. + * no need for any mutex, current won't die prematurely. + */ +void drbd_thread_current_set_cpu(struct drbd_conf *mdev) +{ + struct task_struct *p = current; + struct Drbd_thread *thi = + p == mdev->asender.task ? &mdev->asender : + p == mdev->receiver.task ? &mdev->receiver : + p == mdev->worker.task ? &mdev->worker : + NULL; + ERR_IF(thi == NULL) + return; + if (!thi->reset_cpu_mask) + return; + thi->reset_cpu_mask = 0; + /* preempt_disable(); + Thas was a kernel that warned about a call to smp_processor_id() while preemt + was not disabled. It seems that this was fixed in manline. */ + set_cpus_allowed(p, mdev->cpu_mask); + /* preempt_enable(); */ +} +#endif + +/* the appropriate socket mutex must be held already */ +int _drbd_send_cmd(struct drbd_conf *mdev, struct socket *sock, + enum Drbd_Packet_Cmd cmd, struct Drbd_Header *h, + size_t size, unsigned msg_flags) +{ + int sent, ok; + + ERR_IF(!h) return FALSE; + ERR_IF(!size) return FALSE; + + h->magic = BE_DRBD_MAGIC; + h->command = cpu_to_be16(cmd); + h->length = cpu_to_be16(size-sizeof(struct Drbd_Header)); + + dump_packet(mdev, sock, 0, (void *)h, __FILE__, __LINE__); + sent = drbd_send(mdev, sock, h, size, msg_flags); + + ok = (sent == size); + if (!ok) + ERR("short sent %s size=%d sent=%d\n", + cmdname(cmd), (int)size, sent); + return ok; +} + +/* don't pass the socket. we may only look at it + * when we hold the appropriate socket mutex. + */ +int drbd_send_cmd(struct drbd_conf *mdev, int use_data_socket, + enum Drbd_Packet_Cmd cmd, struct Drbd_Header *h, size_t size) +{ + int ok = 0; + struct socket *sock; + + if (use_data_socket) { + down(&mdev->data.mutex); + sock = mdev->data.socket; + } else { + down(&mdev->meta.mutex); + sock = mdev->meta.socket; + } + + /* drbd_disconnect() could have called drbd_free_sock() + * while we were waiting in down()... */ + if (likely(sock != NULL)) + ok = _drbd_send_cmd(mdev, sock, cmd, h, size, 0); + + if (use_data_socket) + up(&mdev->data.mutex); + else + up(&mdev->meta.mutex); + return ok; +} + +int drbd_send_cmd2(struct drbd_conf *mdev, enum Drbd_Packet_Cmd cmd, char *data, + size_t size) +{ + struct Drbd_Header h; + int ok; + + h.magic = BE_DRBD_MAGIC; + h.command = cpu_to_be16(cmd); + h.length = cpu_to_be16(size); + + if (!drbd_get_data_sock(mdev)) + return 0; + + dump_packet(mdev, mdev->data.socket, 0, (void *)&h, __FILE__, __LINE__); + + ok = (sizeof(h) == + drbd_send(mdev, mdev->data.socket, &h, sizeof(h), 0)); + ok = ok && (size == + drbd_send(mdev, mdev->data.socket, data, size, 0)); + + drbd_put_data_sock(mdev); + + return ok; +} + +int drbd_send_sync_param(struct drbd_conf *mdev, struct syncer_conf *sc) +{ + struct Drbd_SyncParam89_Packet *p; + struct socket *sock; + int size, rv; + const int apv = mdev->agreed_pro_version; + + size = apv <= 87 ? sizeof(struct Drbd_SyncParam_Packet) + : apv == 88 ? sizeof(struct Drbd_SyncParam_Packet) + + strlen(mdev->sync_conf.verify_alg) + 1 + : /* 89 */ sizeof(struct Drbd_SyncParam89_Packet); + + /* used from admin command context and receiver/worker context. + * to avoid kmalloc, grab the socket right here, + * then use the pre-allocated sbuf there */ + down(&mdev->data.mutex); + sock = mdev->data.socket; + + if (likely(sock != NULL)) { + enum Drbd_Packet_Cmd cmd = apv >= 89 ? SyncParam89 : SyncParam; + + p = &mdev->data.sbuf.SyncParam89; + + /* initialize verify_alg and csums_alg */ + memset(p->verify_alg, 0, 2 * SHARED_SECRET_MAX); + + p->rate = cpu_to_be32(sc->rate); + + if (apv >= 88) + strcpy(p->verify_alg, mdev->sync_conf.verify_alg); + if (apv >= 89) + strcpy(p->csums_alg, mdev->sync_conf.csums_alg); + + rv = _drbd_send_cmd(mdev, sock, cmd, &p->head, size, 0); + } else + rv = 0; /* not ok */ + + up(&mdev->data.mutex); + + return rv; +} + +int drbd_send_protocol(struct drbd_conf *mdev) +{ + struct Drbd_Protocol_Packet *p; + int size,rv; + + size = sizeof(struct Drbd_Protocol_Packet); + + if (mdev->agreed_pro_version >= 87) + size += strlen(mdev->net_conf->integrity_alg) + 1; + + if ((p = kmalloc(size, GFP_KERNEL)) == NULL) + return 0; + + p->protocol = cpu_to_be32(mdev->net_conf->wire_protocol); + p->after_sb_0p = cpu_to_be32(mdev->net_conf->after_sb_0p); + p->after_sb_1p = cpu_to_be32(mdev->net_conf->after_sb_1p); + p->after_sb_2p = cpu_to_be32(mdev->net_conf->after_sb_2p); + p->want_lose = cpu_to_be32(mdev->net_conf->want_lose); + p->two_primaries = cpu_to_be32(mdev->net_conf->two_primaries); + + if (mdev->agreed_pro_version >= 87) + strcpy(p->integrity_alg, mdev->net_conf->integrity_alg); + + rv = drbd_send_cmd(mdev, USE_DATA_SOCKET, ReportProtocol, + (struct Drbd_Header *)p, size); + kfree(p); + return rv; +} + +int drbd_send_uuids(struct drbd_conf *mdev) +{ + struct Drbd_GenCnt_Packet p; + int i; + + u64 uuid_flags = 0; + + if (!inc_local_if_state(mdev, Negotiating)) + return 1; + + /* FIXME howto handle diskless ? */ + for (i = Current; i < UUID_SIZE; i++) + p.uuid[i] = mdev->bc ? cpu_to_be64(mdev->bc->md.uuid[i]) : 0; + + mdev->comm_bm_set = drbd_bm_total_weight(mdev); + p.uuid[UUID_SIZE] = cpu_to_be64(mdev->comm_bm_set); + uuid_flags |= mdev->net_conf->want_lose ? 1 : 0; + uuid_flags |= test_bit(CRASHED_PRIMARY, &mdev->flags) ? 2 : 0; + uuid_flags |= mdev->new_state_tmp.disk == Inconsistent ? 4 : 0; + p.uuid[UUID_FLAGS] = cpu_to_be64(uuid_flags); + + dec_local(mdev); + + return drbd_send_cmd(mdev, USE_DATA_SOCKET, ReportUUIDs, + (struct Drbd_Header *)&p, sizeof(p)); +} + +int drbd_send_sync_uuid(struct drbd_conf *mdev, u64 val) +{ + struct Drbd_SyncUUID_Packet p; + + p.uuid = cpu_to_be64(val); + + return drbd_send_cmd(mdev, USE_DATA_SOCKET, ReportSyncUUID, + (struct Drbd_Header *)&p, sizeof(p)); +} + +int drbd_send_sizes(struct drbd_conf *mdev) +{ + struct Drbd_Sizes_Packet p; + sector_t d_size, u_size; + int q_order_type; + int ok; + + if (inc_local_if_state(mdev, Negotiating)) { + D_ASSERT(mdev->bc->backing_bdev); + d_size = drbd_get_max_capacity(mdev->bc); + u_size = mdev->bc->dc.disk_size; + q_order_type = drbd_queue_order_type(mdev); + p.queue_order_type = cpu_to_be32(drbd_queue_order_type(mdev)); + dec_local(mdev); + } else { + d_size = 0; + u_size = 0; + q_order_type = QUEUE_ORDERED_NONE; + } + + p.d_size = cpu_to_be64(d_size); + p.u_size = cpu_to_be64(u_size); + p.c_size = cpu_to_be64(drbd_get_capacity(mdev->this_bdev)); + p.max_segment_size = cpu_to_be32(mdev->rq_queue->max_segment_size); + p.queue_order_type = cpu_to_be32(q_order_type); + + ok = drbd_send_cmd(mdev, USE_DATA_SOCKET, ReportSizes, + (struct Drbd_Header *)&p, sizeof(p)); + return ok; +} + +/** + * drbd_send_state: + * Informs the peer about our state. Only call it when + * mdev->state.conn >= Connected (I.e. you may not call it while in + * WFReportParams. Though there is one valid and necessary exception, + * drbd_connect() calls drbd_send_state() while in it WFReportParams. + */ +int drbd_send_state(struct drbd_conf *mdev) +{ + struct socket *sock; + struct Drbd_State_Packet p; + int ok = 0; + + /* Grab state lock so we wont send state if we're in the middle + * of a cluster wide state change on another thread */ + drbd_state_lock(mdev); + + down(&mdev->data.mutex); + + p.state = cpu_to_be32(mdev->state.i); /* Within the send mutex */ + sock = mdev->data.socket; + + if (likely(sock != NULL)) { + ok = _drbd_send_cmd(mdev, sock, ReportState, + (struct Drbd_Header *)&p, sizeof(p), 0); + } + + up(&mdev->data.mutex); + + drbd_state_unlock(mdev); + return ok; +} + +int drbd_send_state_req(struct drbd_conf *mdev, + union drbd_state_t mask, union drbd_state_t val) +{ + struct Drbd_Req_State_Packet p; + + p.mask = cpu_to_be32(mask.i); + p.val = cpu_to_be32(val.i); + + return drbd_send_cmd(mdev, USE_DATA_SOCKET, StateChgRequest, + (struct Drbd_Header *)&p, sizeof(p)); +} + +int drbd_send_sr_reply(struct drbd_conf *mdev, int retcode) +{ + struct Drbd_RqS_Reply_Packet p; + + p.retcode = cpu_to_be32(retcode); + + return drbd_send_cmd(mdev, USE_META_SOCKET, StateChgReply, + (struct Drbd_Header *)&p, sizeof(p)); +} + + +/* See the comment at receive_bitmap() */ +int _drbd_send_bitmap(struct drbd_conf *mdev) +{ + int want; + int ok = TRUE; + int bm_i = 0; + size_t bm_words, num_words; + unsigned long *buffer; + struct Drbd_Header *p; + + ERR_IF(!mdev->bitmap) return FALSE; + + /* maybe we should use some per thread scratch page, + * and allocate that during initial device creation? */ + p = (struct Drbd_Header *) __get_free_page(GFP_NOIO); + if (!p) { + ERR("failed to allocate one page buffer in %s\n", __func__); + return FALSE; + } + bm_words = drbd_bm_words(mdev); + buffer = (unsigned long *)p->payload; + + if (inc_local(mdev)) { + if (drbd_md_test_flag(mdev->bc, MDF_FullSync)) { + INFO("Writing the whole bitmap, MDF_FullSync was set.\n"); + drbd_bm_set_all(mdev); + if (drbd_bm_write(mdev)) { + /* write_bm did fail! Leave full sync flag set in Meta Data + * but otherwise process as per normal - need to tell other + * side that a full resync is required! */ + ERR("Failed to write bitmap to disk!\n"); + } else { + drbd_md_clear_flag(mdev, MDF_FullSync); + drbd_md_sync(mdev); + } + } + dec_local(mdev); + } + + /* + * maybe TODO use some simple compression scheme, nowadays there are + * some such algorithms in the kernel anyways. + */ + do { + num_words = min_t(size_t, BM_PACKET_WORDS, bm_words - bm_i); + want = num_words * sizeof(long); + if (want) + drbd_bm_get_lel(mdev, bm_i, num_words, buffer); + ok = _drbd_send_cmd(mdev, mdev->data.socket, ReportBitMap, + p, sizeof(*p) + want, 0); + bm_i += num_words; + } while (ok && want); + + free_page((unsigned long) p); + return ok; +} + +int drbd_send_bitmap(struct drbd_conf *mdev) +{ + int err; + + if (!drbd_get_data_sock(mdev)) + return -1; + err = !_drbd_send_bitmap(mdev); + drbd_put_data_sock(mdev); + return err; +} + +int drbd_send_b_ack(struct drbd_conf *mdev, u32 barrier_nr, u32 set_size) +{ + int ok; + struct Drbd_BarrierAck_Packet p; + + p.barrier = barrier_nr; + p.set_size = cpu_to_be32(set_size); + + if (mdev->state.conn < Connected) + return FALSE; + ok = drbd_send_cmd(mdev, USE_META_SOCKET, BarrierAck, + (struct Drbd_Header *)&p, sizeof(p)); + return ok; +} + +/** + * _drbd_send_ack: + * This helper function expects the sector and block_id parameter already + * in big endian! + */ +STATIC int _drbd_send_ack(struct drbd_conf *mdev, enum Drbd_Packet_Cmd cmd, + u64 sector, + u32 blksize, + u64 block_id) +{ + int ok; + struct Drbd_BlockAck_Packet p; + + p.sector = sector; + p.block_id = block_id; + p.blksize = blksize; + p.seq_num = cpu_to_be32(atomic_add_return(1, &mdev->packet_seq)); + + if (!mdev->meta.socket || mdev->state.conn < Connected) + return FALSE; + ok = drbd_send_cmd(mdev, USE_META_SOCKET, cmd, + (struct Drbd_Header *)&p, sizeof(p)); + return ok; +} + +int drbd_send_ack_dp(struct drbd_conf *mdev, enum Drbd_Packet_Cmd cmd, + struct Drbd_Data_Packet *dp) +{ + const int header_size = sizeof(struct Drbd_Data_Packet) + - sizeof(struct Drbd_Header); + int data_size = ((struct Drbd_Header *)dp)->length - header_size; + + return _drbd_send_ack(mdev, cmd, dp->sector, cpu_to_be32(data_size), + dp->block_id); +} + +int drbd_send_ack_rp(struct drbd_conf *mdev, enum Drbd_Packet_Cmd cmd, + struct Drbd_BlockRequest_Packet *rp) +{ + return _drbd_send_ack(mdev, cmd, rp->sector, rp->blksize, rp->block_id); +} + +int drbd_send_ack(struct drbd_conf *mdev, + enum Drbd_Packet_Cmd cmd, struct Tl_epoch_entry *e) +{ + return _drbd_send_ack(mdev, cmd, + cpu_to_be64(e->sector), + cpu_to_be32(e->size), + e->block_id); +} + +/* This function misuses the block_id field to signal if the blocks + * are is sync or not. */ +int drbd_send_ack_ex(struct drbd_conf *mdev, enum Drbd_Packet_Cmd cmd, + sector_t sector, int blksize, u64 block_id) +{ + return _drbd_send_ack(mdev, cmd, + cpu_to_be64(sector), + cpu_to_be32(blksize), + cpu_to_be64(block_id)); +} + +int drbd_send_drequest(struct drbd_conf *mdev, int cmd, + sector_t sector, int size, u64 block_id) +{ + int ok; + struct Drbd_BlockRequest_Packet p; + + p.sector = cpu_to_be64(sector); + p.block_id = block_id; + p.blksize = cpu_to_be32(size); + + /* FIXME BIO_RW_SYNC ? */ + + ok = drbd_send_cmd(mdev, USE_DATA_SOCKET, cmd, + (struct Drbd_Header *)&p, sizeof(p)); + return ok; +} + +int drbd_send_drequest_csum(struct drbd_conf *mdev, + sector_t sector,int size, + void *digest, int digest_size, + enum Drbd_Packet_Cmd cmd) +{ + int ok; + struct Drbd_BlockRequest_Packet p; + + p.sector = cpu_to_be64(sector); + p.block_id = BE_DRBD_MAGIC + 0xbeef; + p.blksize = cpu_to_be32(size); + + p.head.magic = BE_DRBD_MAGIC; + p.head.command = cpu_to_be16(cmd); + p.head.length = cpu_to_be16(sizeof(p) - sizeof(struct Drbd_Header) + digest_size); + + down(&mdev->data.mutex); + + ok = (sizeof(p) == drbd_send(mdev, mdev->data.socket, &p, sizeof(p), 0)); + ok = ok && (digest_size == drbd_send(mdev, mdev->data.socket, digest, digest_size, 0)); + + up(&mdev->data.mutex); + + return ok; +} + +int drbd_send_ov_request(struct drbd_conf *mdev,sector_t sector,int size) +{ + int ok; + struct Drbd_BlockRequest_Packet p; + + p.sector = cpu_to_be64(sector); + p.block_id = BE_DRBD_MAGIC + 0xbabe; + p.blksize = cpu_to_be32(size); + + ok = drbd_send_cmd(mdev,USE_DATA_SOCKET, OVRequest, + (struct Drbd_Header*)&p,sizeof(p)); + return ok; +} + +/* called on sndtimeo + * returns FALSE if we should retry, + * TRUE if we think connection is dead + */ +STATIC int we_should_drop_the_connection(struct drbd_conf *mdev, struct socket *sock) +{ + int drop_it; + /* long elapsed = (long)(jiffies - mdev->last_received); */ + /* DUMPLU(elapsed); // elapsed ignored for now. */ + + drop_it = mdev->meta.socket == sock + || !mdev->asender.task + || get_t_state(&mdev->asender) != Running + || mdev->state.conn < Connected; + + if (drop_it) + return TRUE; + + drop_it = !--mdev->ko_count; + if (!drop_it) { + ERR("[%s/%d] sock_sendmsg time expired, ko = %u\n", + current->comm, current->pid, mdev->ko_count); + request_ping(mdev); + } + + return drop_it; /* && (mdev->state == Primary) */; +} + +/* The idea of sendpage seems to be to put some kind of reference + * to the page into the skb, and to hand it over to the NIC. In + * this process get_page() gets called. + * + * As soon as the page was really sent over the network put_page() + * gets called by some part of the network layer. [ NIC driver? ] + * + * [ get_page() / put_page() increment/decrement the count. If count + * reaches 0 the page will be freed. ] + * + * This works nicely with pages from FSs. + * But this means that in protocol A we might signal IO completion too early! + * + * In order not to corrupt data during a resync we must make sure + * that we do not reuse our own buffer pages (EEs) to early, therefore + * we have the net_ee list. + * + * XFS seems to have problems, still, it submits pages with page_count == 0! + * As a workaround, we disable sendpage on pages + * with page_count == 0 or PageSlab. + */ +STATIC int _drbd_no_send_page(struct drbd_conf *mdev, struct page *page, + int offset, size_t size) +{ + int ret; + ret = drbd_send(mdev, mdev->data.socket, kmap(page) + offset, size, 0); + kunmap(page); + return ret; +} + +int _drbd_send_page(struct drbd_conf *mdev, struct page *page, + int offset, size_t size) +{ + mm_segment_t oldfs = get_fs(); + int sent, ok; + int len = size; + +#ifdef SHOW_SENDPAGE_USAGE + unsigned long now = jiffies; + static unsigned long total; + static unsigned long fallback; + static unsigned long last_rep; + + /* report statistics every hour, + * if we had at least one fallback. + */ + ++total; + if (fallback && time_before(last_rep+3600*HZ, now)) { + last_rep = now; + printk(KERN_INFO "drbd: sendpage() omitted: %lu/%lu\n", + fallback, total); + } +#endif + + /* PARANOIA. if this ever triggers, + * something in the layers above us is really kaputt. + *one roundtrip later: + * doh. it triggered. so XFS _IS_ really kaputt ... + * oh well... + */ + if ((page_count(page) < 1) || PageSlab(page)) { + /* e.g. XFS meta- & log-data is in slab pages, which have a + * page_count of 0 and/or have PageSlab() set... + */ +#ifdef SHOW_SENDPAGE_USAGE + ++fallback; +#endif + sent = _drbd_no_send_page(mdev, page, offset, size); + if (likely(sent > 0)) + len -= sent; + goto out; + } + + set_fs(KERNEL_DS); + do { + sent = mdev->data.socket->ops->sendpage(mdev->data.socket, page, + offset, len, + MSG_NOSIGNAL); + if (sent == -EAGAIN) { + if (we_should_drop_the_connection(mdev, + mdev->data.socket)) + break; + else + continue; + } + if (sent <= 0) { + drbd_WARN("%s: size=%d len=%d sent=%d\n", + __func__, (int)size, len, sent); + break; + } + len -= sent; + offset += sent; + /* FIXME test "last_received" ... */ + } while (len > 0 /* THINK && mdev->cstate >= Connected*/); + set_fs(oldfs); + +out: + ok = (len == 0); + if (likely(ok)) + mdev->send_cnt += size>>9; + return ok; +} + +static inline int _drbd_send_bio(struct drbd_conf *mdev, struct bio *bio) +{ + struct bio_vec *bvec; + int i; + __bio_for_each_segment(bvec, bio, i, 0) { + if (!_drbd_no_send_page(mdev, bvec->bv_page, + bvec->bv_offset, bvec->bv_len)) + return 0; + } + return 1; +} + +static inline int _drbd_send_zc_bio(struct drbd_conf *mdev, struct bio *bio) +{ + struct bio_vec *bvec; + int i; + __bio_for_each_segment(bvec, bio, i, 0) { + if (!_drbd_send_page(mdev, bvec->bv_page, + bvec->bv_offset, bvec->bv_len)) + return 0; + } + + return 1; +} + +/* Used to send write requests + * Primary -> Peer (Data) + */ +int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req) +{ + int ok = 1; + struct Drbd_Data_Packet p; + unsigned int dp_flags = 0; + void *dgb; + int dgs; + + if (!drbd_get_data_sock(mdev)) + return 0; + + dgs = (mdev->agreed_pro_version >= 87 && mdev->integrity_w_tfm) ? + crypto_hash_digestsize(mdev->integrity_w_tfm) : 0; + + p.head.magic = BE_DRBD_MAGIC; + p.head.command = cpu_to_be16(Data); + p.head.length = + cpu_to_be16(sizeof(p) - sizeof(struct Drbd_Header) + dgs + req->size); + + p.sector = cpu_to_be64(req->sector); + p.block_id = (unsigned long)req; + p.seq_num = cpu_to_be32(req->seq_num = + atomic_add_return(1, &mdev->packet_seq)); + dp_flags = 0; + + /* NOTE: no need to check if barriers supported here as we would + * not pass the test in make_request_common in that case + */ + if (bio_barrier(req->master_bio)) + dp_flags |= DP_HARDBARRIER; + if (bio_sync(req->master_bio)) + dp_flags |= DP_RW_SYNC; + if (mdev->state.conn >= SyncSource && + mdev->state.conn <= PausedSyncT) + dp_flags |= DP_MAY_SET_IN_SYNC; + + p.dp_flags = cpu_to_be32(dp_flags); + dump_packet(mdev, mdev->data.socket, 0, (void *)&p, __FILE__, __LINE__); + set_bit(UNPLUG_REMOTE, &mdev->flags); + ok = (sizeof(p) == + drbd_send(mdev, mdev->data.socket, &p, sizeof(p), MSG_MORE)); + if (ok && dgs) { + dgb = mdev->int_dig_out; + drbd_csum(mdev, mdev->integrity_w_tfm, req->master_bio, dgb); + ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, MSG_MORE); + } + if (ok) { + if (mdev->net_conf->wire_protocol == DRBD_PROT_A) + ok = _drbd_send_bio(mdev, req->master_bio); + else + ok = _drbd_send_zc_bio(mdev, req->master_bio); + } + + drbd_put_data_sock(mdev); + return ok; +} + +/* answer packet, used to send data back for read requests: + * Peer -> (diskless) Primary (DataReply) + * SyncSource -> SyncTarget (RSDataReply) + */ +int drbd_send_block(struct drbd_conf *mdev, enum Drbd_Packet_Cmd cmd, + struct Tl_epoch_entry *e) +{ + int ok; + struct Drbd_Data_Packet p; + void *dgb; + int dgs; + + dgs = (mdev->agreed_pro_version >= 87 && mdev->integrity_w_tfm) ? + crypto_hash_digestsize(mdev->integrity_w_tfm) : 0; + + p.head.magic = BE_DRBD_MAGIC; + p.head.command = cpu_to_be16(cmd); + p.head.length = + cpu_to_be16(sizeof(p) - sizeof(struct Drbd_Header) + dgs + e->size); + + p.sector = cpu_to_be64(e->sector); + p.block_id = e->block_id; + /* p.seq_num = 0; No sequence numbers here.. */ + + /* Only called by our kernel thread. + * This one may be interupted by DRBD_SIG and/or DRBD_SIGKILL + * in response to admin command or module unload. + */ + if (!drbd_get_data_sock(mdev)) + return 0; + + dump_packet(mdev, mdev->data.socket, 0, (void *)&p, __FILE__, __LINE__); + ok = sizeof(p) == drbd_send(mdev, mdev->data.socket, &p, + sizeof(p), MSG_MORE); + if (ok && dgs) { + dgb = mdev->int_dig_out; + drbd_csum(mdev, mdev->integrity_w_tfm, e->private_bio, dgb); + ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, MSG_MORE); + } + if (ok) + ok = _drbd_send_zc_bio(mdev, e->private_bio); + + drbd_put_data_sock(mdev); + return ok; +} + +/* + drbd_send distinguishes two cases: + + Packets sent via the data socket "sock" + and packets sent via the meta data socket "msock" + + sock msock + -----------------+-------------------------+------------------------------ + timeout conf.timeout / 2 conf.timeout / 2 + timeout action send a ping via msock Abort communication + and close all sockets +*/ + +/* + * you must have down()ed the appropriate [m]sock_mutex elsewhere! + */ +int drbd_send(struct drbd_conf *mdev, struct socket *sock, + void *buf, size_t size, unsigned msg_flags) +{ +#if !HAVE_KERNEL_SENDMSG + mm_segment_t oldfs; + struct iovec iov; +#else + struct kvec iov; +#endif + struct msghdr msg; + int rv, sent = 0; + + if (!sock) + return -1000; + + /* THINK if (signal_pending) return ... ? */ + + iov.iov_base = buf; + iov.iov_len = size; + + msg.msg_name = NULL; + msg.msg_namelen = 0; +#if !HAVE_KERNEL_SENDMSG + msg.msg_iov = &iov; + msg.msg_iovlen = 1; +#endif + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = msg_flags | MSG_NOSIGNAL; + +#if !HAVE_KERNEL_SENDMSG + oldfs = get_fs(); + set_fs(KERNEL_DS); +#endif + + if (sock == mdev->data.socket) + mdev->ko_count = mdev->net_conf->ko_count; + do { + /* STRANGE + * tcp_sendmsg does _not_ use its size parameter at all ? + * + * -EAGAIN on timeout, -EINTR on signal. + */ +/* THINK + * do we need to block DRBD_SIG if sock == &meta.socket ?? + * otherwise wake_asender() might interrupt some send_*Ack ! + */ +#if !HAVE_KERNEL_SENDMSG + rv = sock_sendmsg(sock, &msg, iov.iov_len); +#else + rv = kernel_sendmsg(sock, &msg, &iov, 1, size); +#endif + if (rv == -EAGAIN) { + if (we_should_drop_the_connection(mdev, sock)) + break; + else + continue; + } + D_ASSERT(rv != 0); + if (rv == -EINTR) { +#if 0 + /* FIXME this happens all the time. + * we don't care for now! + * eventually this should be sorted out be the proper + * use of the SIGNAL_ASENDER bit... */ + if (DRBD_ratelimit(5*HZ, 5)) { + DBG("Got a signal in drbd_send(,%c,)!\n", + sock == mdev->meta.socket ? 'm' : 's'); + /* dump_stack(); */ + } +#endif + flush_signals(current); + rv = 0; + } + if (rv < 0) + break; + sent += rv; + iov.iov_base += rv; + iov.iov_len -= rv; + } while (sent < size); + +#if !HAVE_KERNEL_SENDMSG + set_fs(oldfs); +#endif + + if (rv <= 0) { + if (rv != -EAGAIN) { + ERR("%s_sendmsg returned %d\n", + sock == mdev->meta.socket ? "msock" : "sock", + rv); + drbd_force_state(mdev, NS(conn, BrokenPipe)); + } else + drbd_force_state(mdev, NS(conn, Timeout)); + } + + return sent; +} + +#ifdef BD_OPS_USE_FMODE +static int drbd_open(struct block_device *bdev, fmode_t mode) +#else +static int drbd_open(struct inode *inode, struct file *file) +#endif +{ +#ifdef BD_OPS_USE_FMODE + struct drbd_conf *mdev = bdev->bd_disk->private_data; +#else + int mode = file->f_mode; + struct drbd_conf *mdev = inode->i_bdev->bd_disk->private_data; +#endif + unsigned long flags; + int rv = 0; + + spin_lock_irqsave(&mdev->req_lock, flags); + /* to have a stable mdev->state.role + * and no race with updating open_cnt */ + + if (mdev->state.role != Primary) { + if (mode & FMODE_WRITE) + rv = -EROFS; + else if (!allow_oos) + rv = -EMEDIUMTYPE; + } + + if (!rv) + mdev->open_cnt++; + spin_unlock_irqrestore(&mdev->req_lock, flags); + + return rv; +} + +#ifdef BD_OPS_USE_FMODE +static int drbd_release(struct gendisk *gd, fmode_t mode) +{ + struct drbd_conf *mdev = gd->private_data; + mdev->open_cnt--; + return 0; +} +#else +static int drbd_release(struct inode *inode, struct file *file) +{ + struct drbd_conf *mdev = inode->i_bdev->bd_disk->private_data; + mdev->open_cnt--; + return 0; +} +#endif + +STATIC void drbd_unplug_fn(struct request_queue *q) +{ + struct drbd_conf *mdev = q->queuedata; + + MTRACE(TraceTypeUnplug, TraceLvlSummary, + INFO("got unplugged ap_bio_count=%d\n", + atomic_read(&mdev->ap_bio_cnt)); + ); + + /* unplug FIRST */ + spin_lock_irq(q->queue_lock); + blk_remove_plug(q); + spin_unlock_irq(q->queue_lock); + + /* only if connected */ + spin_lock_irq(&mdev->req_lock); + if (mdev->state.pdsk >= Inconsistent && mdev->state.conn >= Connected) { + D_ASSERT(mdev->state.role == Primary); + if (test_and_clear_bit(UNPLUG_REMOTE, &mdev->flags)) { + /* add to the data.work queue, + * unless already queued. + * XXX this might be a good addition to drbd_queue_work + * anyways, to detect "double queuing" ... */ + if (list_empty(&mdev->unplug_work.list)) + drbd_queue_work(&mdev->data.work, + &mdev->unplug_work); + } + } + spin_unlock_irq(&mdev->req_lock); + + if (mdev->state.disk >= Inconsistent) + drbd_kick_lo(mdev); +} + +STATIC void drbd_set_defaults(struct drbd_conf *mdev) +{ + mdev->sync_conf.after = DRBD_AFTER_DEF; + mdev->sync_conf.rate = DRBD_RATE_DEF; + mdev->sync_conf.al_extents = DRBD_AL_EXTENTS_DEF; + mdev->state = (union drbd_state_t) { + { .role = Secondary, + .peer = Unknown, + .conn = StandAlone, + .disk = Diskless, + .pdsk = DUnknown, + .susp = 0 + } }; +} + +int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused); + +void drbd_init_set_defaults(struct drbd_conf *mdev) +{ + /* the memset(,0,) did most of this. + * note: only assignments, no allocation in here */ + +#ifdef PARANOIA + SET_MDEV_MAGIC(mdev); +#endif + + drbd_set_defaults(mdev); + + /* for now, we do NOT yet support it, + * even though we start some framework + * to eventually support barriers */ + set_bit(NO_BARRIER_SUPP, &mdev->flags); + + atomic_set(&mdev->ap_bio_cnt, 0); + atomic_set(&mdev->ap_pending_cnt, 0); + atomic_set(&mdev->rs_pending_cnt, 0); + atomic_set(&mdev->unacked_cnt, 0); + atomic_set(&mdev->local_cnt, 0); + atomic_set(&mdev->net_cnt, 0); + atomic_set(&mdev->packet_seq, 0); + atomic_set(&mdev->pp_in_use, 0); + + init_MUTEX(&mdev->md_io_mutex); + init_MUTEX(&mdev->data.mutex); + init_MUTEX(&mdev->meta.mutex); + sema_init(&mdev->data.work.s, 0); + sema_init(&mdev->meta.work.s, 0); + mutex_init(&mdev->state_mutex); + + spin_lock_init(&mdev->data.work.q_lock); + spin_lock_init(&mdev->meta.work.q_lock); + + spin_lock_init(&mdev->al_lock); + spin_lock_init(&mdev->req_lock); + spin_lock_init(&mdev->peer_seq_lock); + spin_lock_init(&mdev->epoch_lock); + + INIT_LIST_HEAD(&mdev->active_ee); + INIT_LIST_HEAD(&mdev->sync_ee); + INIT_LIST_HEAD(&mdev->done_ee); + INIT_LIST_HEAD(&mdev->read_ee); + INIT_LIST_HEAD(&mdev->net_ee); + INIT_LIST_HEAD(&mdev->resync_reads); + INIT_LIST_HEAD(&mdev->data.work.q); + INIT_LIST_HEAD(&mdev->meta.work.q); + INIT_LIST_HEAD(&mdev->resync_work.list); + INIT_LIST_HEAD(&mdev->unplug_work.list); + INIT_LIST_HEAD(&mdev->md_sync_work.list); + INIT_LIST_HEAD(&mdev->bm_io_work.w.list); + mdev->resync_work.cb = w_resync_inactive; + mdev->unplug_work.cb = w_send_write_hint; + mdev->md_sync_work.cb = w_md_sync; + mdev->bm_io_work.w.cb = w_bitmap_io; + init_timer(&mdev->resync_timer); + init_timer(&mdev->md_sync_timer); + mdev->resync_timer.function = resync_timer_fn; + mdev->resync_timer.data = (unsigned long) mdev; + mdev->md_sync_timer.function = md_sync_timer_fn; + mdev->md_sync_timer.data = (unsigned long) mdev; + + init_waitqueue_head(&mdev->misc_wait); + init_waitqueue_head(&mdev->state_wait); + init_waitqueue_head(&mdev->ee_wait); + init_waitqueue_head(&mdev->al_wait); + init_waitqueue_head(&mdev->seq_wait); + + drbd_thread_init(mdev, &mdev->receiver, drbdd_init); + drbd_thread_init(mdev, &mdev->worker, drbd_worker); + drbd_thread_init(mdev, &mdev->asender, drbd_asender); + + mdev->agreed_pro_version = PRO_VERSION_MAX; + mdev->write_ordering = WO_bio_barrier; +#ifdef __arch_um__ + INFO("mdev = 0x%p\n", mdev); +#endif + mdev->resync_wenr = LC_FREE; +} + +void drbd_mdev_cleanup(struct drbd_conf *mdev) +{ + /* I'd like to cleanup completely, and memset(,0,) it. + * but I'd have to reinit it. + * FIXME: do the right thing... + */ + + /* list of things that may still + * hold data of the previous config + + * act_log ** re-initialized in set_disk + * on_io_error + + * al_tr_cycle ** re-initialized in ... FIXME?? + * al_tr_number + * al_tr_pos + + * backing_bdev ** re-initialized in drbd_free_ll_dev + * lo_file + * md_bdev + * md_file + * md_index + + * ko_count ** re-initialized in set_net + + * last_received ** currently ignored + + * mbds_id ** re-initialized in ... FIXME?? + + * resync ** re-initialized in ... FIXME?? + + *** no re-init necessary (?) *** + * md_io_page + * this_bdev + + * vdisk ? + + * rq_queue ** FIXME ASSERT ?? + * newest_barrier + * oldest_barrier + */ + + if (mdev->receiver.t_state != None) + ERR("ASSERT FAILED: receiver t_state == %d expected 0.\n", + mdev->receiver.t_state); + + crypto_free_hash(mdev->csums_tfm); + mdev->csums_tfm = NULL; + + crypto_free_hash(mdev->verify_tfm); + mdev->verify_tfm = NULL; + + crypto_free_hash(mdev->integrity_w_tfm); + mdev->integrity_w_tfm = NULL; + + crypto_free_hash(mdev->integrity_r_tfm); + mdev->integrity_r_tfm = NULL; + /* no need to lock it, I'm the only thread alive */ + if (atomic_read(&mdev->current_epoch->epoch_size) != 0) + ERR("epoch_size:%d\n", atomic_read(&mdev->current_epoch->epoch_size)); + mdev->al_writ_cnt = + mdev->bm_writ_cnt = + mdev->read_cnt = + mdev->recv_cnt = + mdev->send_cnt = + mdev->writ_cnt = + mdev->p_size = + mdev->rs_start = + mdev->rs_total = + mdev->rs_failed = + mdev->rs_mark_left = + mdev->rs_mark_time = 0; + D_ASSERT(mdev->net_conf == NULL); + drbd_set_my_capacity(mdev, 0); + drbd_bm_resize(mdev, 0); + drbd_bm_cleanup(mdev); + + /* just in case */ + drbd_free_resources(mdev); + + /* + * currently we drbd_init_ee only on module load, so + * we may do drbd_release_ee only on module unload! + */ + D_ASSERT(list_empty(&mdev->active_ee)); + D_ASSERT(list_empty(&mdev->sync_ee)); + D_ASSERT(list_empty(&mdev->done_ee)); + D_ASSERT(list_empty(&mdev->read_ee)); + D_ASSERT(list_empty(&mdev->net_ee)); + D_ASSERT(list_empty(&mdev->resync_reads)); + D_ASSERT(list_empty(&mdev->data.work.q)); + D_ASSERT(list_empty(&mdev->meta.work.q)); + D_ASSERT(list_empty(&mdev->resync_work.list)); + D_ASSERT(list_empty(&mdev->unplug_work.list)); + +} + + +STATIC void drbd_destroy_mempools(void) +{ + struct page *page; + + while (drbd_pp_pool) { + page = drbd_pp_pool; + drbd_pp_pool = (struct page *)page_private(page); + __free_page(page); + drbd_pp_vacant--; + } + + /* D_ASSERT(atomic_read(&drbd_pp_vacant)==0); */ + + if (drbd_ee_mempool) + mempool_destroy(drbd_ee_mempool); + if (drbd_request_mempool) + mempool_destroy(drbd_request_mempool); + if (drbd_ee_cache) + kmem_cache_destroy(drbd_ee_cache); + if (drbd_request_cache) + kmem_cache_destroy(drbd_request_cache); + + drbd_ee_mempool = NULL; + drbd_request_mempool = NULL; + drbd_ee_cache = NULL; + drbd_request_cache = NULL; + + return; +} + +STATIC int drbd_create_mempools(void) +{ + struct page *page; + const int number = (DRBD_MAX_SEGMENT_SIZE/PAGE_SIZE) * minor_count; + int i; + + /* prepare our caches and mempools */ + drbd_request_mempool = NULL; + drbd_ee_cache = NULL; + drbd_request_cache = NULL; + drbd_pp_pool = NULL; + + /* caches */ + drbd_request_cache = kmem_cache_create( + "drbd_req_cache", sizeof(struct drbd_request), 0, 0, NULL); + if (drbd_request_cache == NULL) + goto Enomem; + + drbd_ee_cache = kmem_cache_create( + "drbd_ee_cache", sizeof(struct Tl_epoch_entry), 0, 0, NULL); + if (drbd_ee_cache == NULL) + goto Enomem; + + /* mempools */ + drbd_request_mempool = mempool_create(number, + mempool_alloc_slab, mempool_free_slab, drbd_request_cache); + if (drbd_request_mempool == NULL) + goto Enomem; + + drbd_ee_mempool = mempool_create(number, + mempool_alloc_slab, mempool_free_slab, drbd_ee_cache); + if (drbd_request_mempool == NULL) + goto Enomem; + + /* drbd's page pool */ + spin_lock_init(&drbd_pp_lock); + + for (i = 0; i < number; i++) { + page = alloc_page(GFP_HIGHUSER); + if (!page) + goto Enomem; + set_page_private(page, (unsigned long)drbd_pp_pool); + drbd_pp_pool = page; + } + drbd_pp_vacant = number; + + return 0; + +Enomem: + drbd_destroy_mempools(); /* in case we allocated some */ + return -ENOMEM; +} + +STATIC int drbd_notify_sys(struct notifier_block *this, unsigned long code, + void *unused) +{ + /* just so we have it. you never know what interessting things we + * might want to do here some day... + */ + + return NOTIFY_DONE; +} + +STATIC struct notifier_block drbd_notifier = { + .notifier_call = drbd_notify_sys, +}; + + +STATIC void drbd_cleanup(void) +{ + int i, rr; + + unregister_reboot_notifier(&drbd_notifier); + + drbd_nl_cleanup(); + + if (minor_table) { + if (drbd_proc) + remove_proc_entry("drbd", NULL); + i = minor_count; + while (i--) { + struct drbd_conf *mdev = minor_to_mdev(i); + struct gendisk **disk = &mdev->vdisk; + struct request_queue **q = &mdev->rq_queue; + + if (!mdev) + continue; + drbd_free_resources(mdev); + + if (*disk) { + del_gendisk(*disk); + put_disk(*disk); + *disk = NULL; + } + if (*q) + blk_cleanup_queue(*q); + *q = NULL; + + D_ASSERT(mdev->open_cnt == 0); + if (mdev->this_bdev) + bdput(mdev->this_bdev); + + tl_cleanup(mdev); + if (mdev->bitmap) + drbd_bm_cleanup(mdev); + if (mdev->resync) + lc_free(mdev->resync); + + rr = drbd_release_ee(mdev, &mdev->active_ee); + if (rr) + ERR("%d EEs in active list found!\n", rr); + + rr = drbd_release_ee(mdev, &mdev->sync_ee); + if (rr) + ERR("%d EEs in sync list found!\n", rr); + + rr = drbd_release_ee(mdev, &mdev->read_ee); + if (rr) + ERR("%d EEs in read list found!\n", rr); + + rr = drbd_release_ee(mdev, &mdev->done_ee); + if (rr) + ERR("%d EEs in done list found!\n", rr); + + rr = drbd_release_ee(mdev, &mdev->net_ee); + if (rr) + ERR("%d EEs in net list found!\n", rr); + + ERR_IF (!list_empty(&mdev->data.work.q)) { + struct list_head *lp; + list_for_each(lp, &mdev->data.work.q) { + DUMPP(lp); + } + }; + + if (mdev->md_io_page) + __free_page(mdev->md_io_page); + + if (mdev->md_io_tmpp) + __free_page(mdev->md_io_tmpp); + + if (mdev->act_log) + lc_free(mdev->act_log); + + kfree(mdev->ee_hash); + mdev->ee_hash_s = 0; + mdev->ee_hash = NULL; + + kfree(mdev->tl_hash); + mdev->tl_hash_s = 0; + mdev->tl_hash = NULL; + + kfree(mdev->app_reads_hash); + mdev->app_reads_hash = NULL; + + kfree(mdev->p_uuid); + mdev->p_uuid = NULL; + + kfree(mdev->int_dig_out); + kfree(mdev->int_dig_in); + kfree(mdev->int_dig_vv); + + kfree(mdev->current_epoch); + } + drbd_destroy_mempools(); + } + + kfree(minor_table); + + drbd_unregister_blkdev(DRBD_MAJOR, "drbd"); + + printk(KERN_INFO "drbd: module cleanup done.\n"); +} + +struct drbd_conf *drbd_new_device(int minor) +{ + struct drbd_conf *mdev = NULL; + struct gendisk *disk; + struct request_queue *q; + + mdev = kzalloc(sizeof(struct drbd_conf), GFP_KERNEL); + if (!mdev) + goto Enomem; + + mdev->minor = minor; + + drbd_init_set_defaults(mdev); + + q = blk_alloc_queue(GFP_KERNEL); + if (!q) + goto Enomem; + mdev->rq_queue = q; + q->queuedata = mdev; + q->max_segment_size = DRBD_MAX_SEGMENT_SIZE; + + disk = alloc_disk(1); + if (!disk) + goto Enomem; + mdev->vdisk = disk; + + set_disk_ro(disk, TRUE); + + disk->queue = q; + disk->major = DRBD_MAJOR; + disk->first_minor = minor; + disk->fops = &drbd_ops; + sprintf(disk->disk_name, "drbd%d", minor); + disk->private_data = mdev; + add_disk(disk); + + mdev->this_bdev = bdget(MKDEV(DRBD_MAJOR, minor)); + /* we have no partitions. we contain only ourselves. */ + mdev->this_bdev->bd_contains = mdev->this_bdev; + + blk_queue_make_request(q, drbd_make_request_26); + blk_queue_bounce_limit(q, BLK_BOUNCE_ANY); + blk_queue_merge_bvec(q, drbd_merge_bvec); + q->queue_lock = &mdev->req_lock; /* needed since we use */ + /* plugging on a queue, that actually has no requests! */ + q->unplug_fn = drbd_unplug_fn; + + mdev->md_io_page = alloc_page(GFP_KERNEL); + if (!mdev->md_io_page) + goto Enomem; + + if (drbd_bm_init(mdev)) + goto Enomem; + /* no need to lock access, we are still initializing the module. */ + if (!tl_init(mdev)) + goto Enomem; + + mdev->app_reads_hash = kzalloc(APP_R_HSIZE*sizeof(void *), GFP_KERNEL); + if (!mdev->app_reads_hash) + goto Enomem; + + mdev->current_epoch = kzalloc(sizeof(struct drbd_epoch), GFP_KERNEL); + INIT_LIST_HEAD(&mdev->current_epoch->list); + mdev->epochs = 1; + + return mdev; + + Enomem: + if (mdev) { + kfree(mdev->app_reads_hash); + if (mdev->md_io_page) + __free_page(mdev->md_io_page); + kfree(mdev->current_epoch); + kfree(mdev); + } + return NULL; +} + +int __init drbd_init(void) +{ + int err; + +#ifdef __arch_um__ + printk(KERN_INFO "drbd_module = 0x%p core = 0x%p\n", + THIS_MODULE, THIS_MODULE->module_core); +#endif + + if (sizeof(struct Drbd_HandShake_Packet) != 80) { + printk(KERN_ERR + "drbd: never change the size or layout " + "of the HandShake packet.\n"); + return -EINVAL; + } + + if (1 > minor_count || minor_count > 255) { + printk(KERN_ERR + "drbd: invalid minor_count (%d)\n", minor_count); +#ifdef MODULE + return -EINVAL; +#else + minor_count = 8; +#endif + } + + err = drbd_nl_init(); + if (err) + return err; + + err = register_blkdev(DRBD_MAJOR, "drbd"); + if (err) { + printk(KERN_ERR + "drbd: unable to register block device major %d\n", + DRBD_MAJOR); + return err; + } + + register_reboot_notifier(&drbd_notifier); + + /* + * allocate all necessary structs + */ + err = -ENOMEM; + + init_waitqueue_head(&drbd_pp_wait); + + drbd_proc = NULL; /* play safe for drbd_cleanup */ + minor_table = kzalloc(sizeof(struct drbd_conf *)*minor_count, + GFP_KERNEL); + if (!minor_table) + goto Enomem; + + err = drbd_create_mempools(); + if (err) + goto Enomem; + +#if CONFIG_PROC_FS + /* + * register with procfs + */ + drbd_proc = create_proc_entry("drbd", S_IFREG | S_IRUGO , NULL); + + if (!drbd_proc) { + printk(KERN_ERR "drbd: unable to register proc file\n"); + goto Enomem; + } + + drbd_proc->proc_fops = &drbd_proc_fops; + drbd_proc->owner = THIS_MODULE; +#else +# error "Currently drbd depends on the proc file system (CONFIG_PROC_FS)" +#endif + + printk(KERN_INFO "drbd: initialised. " + "Version: " REL_VERSION " (api:%d/proto:%d-%d)\n", + API_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX); + printk(KERN_INFO "drbd: %s\n", drbd_buildtag()); + printk(KERN_INFO "drbd: registered as block device major %d\n", + DRBD_MAJOR); + printk(KERN_INFO "drbd: minor_table @ 0x%p\n", minor_table); + + return 0; /* Success! */ + +Enomem: + drbd_cleanup(); + if (err == -ENOMEM) + /* currently always the case */ + printk(KERN_ERR "drbd: ran out of memory\n"); + else + printk(KERN_ERR "drbd: initialization failure\n"); + return err; +} + +void drbd_free_bc(struct drbd_backing_dev *bc) +{ + if (bc == NULL) + return; + + bd_release(bc->backing_bdev); + bd_release(bc->md_bdev); + + fput(bc->lo_file); + fput(bc->md_file); + + kfree(bc); +} + +void drbd_free_sock(struct drbd_conf *mdev) +{ + if (mdev->data.socket) { + sock_release(mdev->data.socket); + mdev->data.socket = NULL; + } + if (mdev->meta.socket) { + sock_release(mdev->meta.socket); + mdev->meta.socket = NULL; + } +} + + +void drbd_free_resources(struct drbd_conf *mdev) +{ + crypto_free_hash(mdev->cram_hmac_tfm); + mdev->cram_hmac_tfm = NULL; + crypto_free_hash(mdev->integrity_w_tfm); + mdev->integrity_w_tfm=NULL; + crypto_free_hash(mdev->integrity_r_tfm); + mdev->integrity_r_tfm=NULL; + drbd_free_sock(mdev); + __no_warn(local, + drbd_free_bc(mdev->bc); + mdev->bc = NULL;); +} + +/*********************************/ +/* meta data management */ + +struct meta_data_on_disk { + u64 la_size; /* last agreed size. */ + u64 uuid[UUID_SIZE]; /* UUIDs. */ + u64 device_uuid; + u64 reserved_u64_1; + u32 flags; /* MDF */ + u32 magic; + u32 md_size_sect; + u32 al_offset; /* offset to this block */ + u32 al_nr_extents; /* important for restoring the AL */ + /* `-- act_log->nr_elements <-- sync_conf.al_extents */ + u32 bm_offset; /* offset to the bitmap, from here */ + u32 bm_bytes_per_bit; /* BM_BLOCK_SIZE */ + u32 reserved_u32[4]; + +} __attribute((packed)); + +/** + * drbd_md_sync: + * Writes the meta data super block if the MD_DIRTY flag bit is set. + */ +void drbd_md_sync(struct drbd_conf *mdev) +{ + struct meta_data_on_disk *buffer; + sector_t sector; + int i; + + if (!test_and_clear_bit(MD_DIRTY, &mdev->flags)) + return; + del_timer(&mdev->md_sync_timer); + + /* We use here Failed and not Attaching because we try to write + * metadata even if we detach due to a disk failure! */ + if (!inc_local_if_state(mdev, Failed)) + return; + + MTRACE(TraceTypeMDIO, TraceLvlSummary, + INFO("Writing meta data super block now.\n"); + ); + + down(&mdev->md_io_mutex); + buffer = (struct meta_data_on_disk *)page_address(mdev->md_io_page); + memset(buffer, 0, 512); + + buffer->la_size = cpu_to_be64(drbd_get_capacity(mdev->this_bdev)); + for (i = Current; i < UUID_SIZE; i++) + buffer->uuid[i] = cpu_to_be64(mdev->bc->md.uuid[i]); + buffer->flags = cpu_to_be32(mdev->bc->md.flags); + buffer->magic = cpu_to_be32(DRBD_MD_MAGIC); + + buffer->md_size_sect = cpu_to_be32(mdev->bc->md.md_size_sect); + buffer->al_offset = cpu_to_be32(mdev->bc->md.al_offset); + buffer->al_nr_extents = cpu_to_be32(mdev->act_log->nr_elements); + buffer->bm_bytes_per_bit = cpu_to_be32(BM_BLOCK_SIZE); + buffer->device_uuid = cpu_to_be64(mdev->bc->md.device_uuid); + + buffer->bm_offset = cpu_to_be32(mdev->bc->md.bm_offset); + + D_ASSERT(drbd_md_ss__(mdev, mdev->bc) == mdev->bc->md.md_offset); + sector = mdev->bc->md.md_offset; + + if (drbd_md_sync_page_io(mdev, mdev->bc, sector, WRITE)) { + clear_bit(MD_DIRTY, &mdev->flags); + } else { + /* this was a try anyways ... */ + ERR("meta data update failed!\n"); + + drbd_chk_io_error(mdev, 1, TRUE); + drbd_io_error(mdev, TRUE); + } + + /* Update mdev->bc->md.la_size_sect, + * since we updated it on metadata. */ + mdev->bc->md.la_size_sect = drbd_get_capacity(mdev->this_bdev); + + up(&mdev->md_io_mutex); + dec_local(mdev); +} + +/** + * drbd_md_read: + * @bdev: describes the backing storage and the meta-data storage + * Reads the meta data from bdev. Return 0 (NoError) on success, and an + * enum ret_codes in case something goes wrong. + * Currently only: MDIOError, MDInvalid. + */ +int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev) +{ + struct meta_data_on_disk *buffer; + int i, rv = NoError; + + if (!inc_local_if_state(mdev, Attaching)) + return MDIOError; + + down(&mdev->md_io_mutex); + buffer = (struct meta_data_on_disk *)page_address(mdev->md_io_page); + + if (!drbd_md_sync_page_io(mdev, bdev, bdev->md.md_offset, READ)) { + /* NOTE: cant do normal error processing here as this is + called BEFORE disk is attached */ + ERR("Error while reading metadata.\n"); + rv = MDIOError; + goto err; + } + + if (be32_to_cpu(buffer->magic) != DRBD_MD_MAGIC) { + ERR("Error while reading metadata, magic not found.\n"); + rv = MDInvalid; + goto err; + } + if (be32_to_cpu(buffer->al_offset) != bdev->md.al_offset) { + ERR("unexpected al_offset: %d (expected %d)\n", + be32_to_cpu(buffer->al_offset), bdev->md.al_offset); + rv = MDInvalid; + goto err; + } + if (be32_to_cpu(buffer->bm_offset) != bdev->md.bm_offset) { + ERR("unexpected bm_offset: %d (expected %d)\n", + be32_to_cpu(buffer->bm_offset), bdev->md.bm_offset); + rv = MDInvalid; + goto err; + } + if (be32_to_cpu(buffer->md_size_sect) != bdev->md.md_size_sect) { + ERR("unexpected md_size: %u (expected %u)\n", + be32_to_cpu(buffer->md_size_sect), bdev->md.md_size_sect); + rv = MDInvalid; + goto err; + } + + if (be32_to_cpu(buffer->bm_bytes_per_bit) != BM_BLOCK_SIZE) { + ERR("unexpected bm_bytes_per_bit: %u (expected %u)\n", + be32_to_cpu(buffer->bm_bytes_per_bit), BM_BLOCK_SIZE); + rv = MDInvalid; + goto err; + } + + bdev->md.la_size_sect = be64_to_cpu(buffer->la_size); + for (i = Current; i < UUID_SIZE; i++) + bdev->md.uuid[i] = be64_to_cpu(buffer->uuid[i]); + bdev->md.flags = be32_to_cpu(buffer->flags); + mdev->sync_conf.al_extents = be32_to_cpu(buffer->al_nr_extents); + bdev->md.device_uuid = be64_to_cpu(buffer->device_uuid); + + if (mdev->sync_conf.al_extents < 7) + mdev->sync_conf.al_extents = 127; + /* FIXME if this ever happens when reading meta data, + * it possibly screws up reading of the activity log? + */ + + err: + up(&mdev->md_io_mutex); + dec_local(mdev); + + return rv; +} + +/** + * drbd_md_mark_dirty: + * Call this function if you change enything that should be written to + * the meta-data super block. This function sets MD_DIRTY, and starts a + * timer that ensures that within five seconds you have to call drbd_md_sync(). + */ +void drbd_md_mark_dirty(struct drbd_conf *mdev) +{ + set_bit(MD_DIRTY, &mdev->flags); + mod_timer(&mdev->md_sync_timer, jiffies + 5*HZ); +} + + +STATIC void drbd_uuid_move_history(struct drbd_conf *mdev) __must_hold(local) +{ + int i; + + for (i = History_start; i < History_end; i++) { + mdev->bc->md.uuid[i+1] = mdev->bc->md.uuid[i]; + + MTRACE(TraceTypeUuid, TraceLvlAll, + drbd_print_uuid(mdev, i+1); + ); + } +} + +void _drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local) +{ + if (idx == Current) { + if (mdev->state.role == Primary) + val |= 1; + else + val &= ~((u64)1); + + drbd_set_ed_uuid(mdev, val); + } + + mdev->bc->md.uuid[idx] = val; + + MTRACE(TraceTypeUuid, TraceLvlSummary, + drbd_print_uuid(mdev, idx); + ); + + drbd_md_mark_dirty(mdev); +} + + +void drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local) +{ + if (mdev->bc->md.uuid[idx]) { + drbd_uuid_move_history(mdev); + mdev->bc->md.uuid[History_start] = mdev->bc->md.uuid[idx]; + MTRACE(TraceTypeUuid, TraceLvlMetrics, + drbd_print_uuid(mdev, History_start); + ); + } + _drbd_uuid_set(mdev, idx, val); +} + +/** + * _drbd_uuid_new_current: + * Creates a new current UUID, but does NOT rotate the old current + * UUID into the bitmap slot (but into history). This causes a full + * sync upon next connect. Aditionally the full sync is also requested + * by the FullSync bit. + */ +void _drbd_uuid_new_current(struct drbd_conf *mdev) __must_hold(local) +{ + u64 uuid; + + /* Actually a seperate bit names DisklessPeer, would be + the right thing. But for now the FullSync bit is a + working substitute, to avoid repetitive generating + of new current UUIDs in case we loose connection + and reconnect in a loop. */ + if (mdev->bc->md.flags & MDF_FullSync) + return; + INFO("Creating new current UUID [no BitMap]\n"); + get_random_bytes(&uuid, sizeof(u64)); + drbd_uuid_set(mdev, Current, uuid); + drbd_md_set_flag(mdev, MDF_FullSync); +} + +/** + * drbd_uuid_new_current: + * Creates a new current UUID, and rotates the old current UUID into + * the bitmap slot. Causes an incremental resync upon next connect. + */ +void drbd_uuid_new_current(struct drbd_conf *mdev) __must_hold(local) +{ + u64 val; + + INFO("Creating new current UUID\n"); + D_ASSERT(mdev->bc->md.uuid[Bitmap] == 0); + mdev->bc->md.uuid[Bitmap] = mdev->bc->md.uuid[Current]; + MTRACE(TraceTypeUuid, TraceLvlMetrics, + drbd_print_uuid(mdev, Bitmap); + ); + + get_random_bytes(&val, sizeof(u64)); + _drbd_uuid_set(mdev, Current, val); +} + +void drbd_uuid_set_bm(struct drbd_conf *mdev, u64 val) __must_hold(local) +{ + if (mdev->bc->md.uuid[Bitmap] == 0 && val == 0) + return; + + if (val == 0) { + drbd_uuid_move_history(mdev); + mdev->bc->md.uuid[History_start] = mdev->bc->md.uuid[Bitmap]; + mdev->bc->md.uuid[Bitmap] = 0; + + MTRACE(TraceTypeUuid, TraceLvlMetrics, + drbd_print_uuid(mdev, History_start); + drbd_print_uuid(mdev, Bitmap); + ); + } else { + if (mdev->bc->md.uuid[Bitmap]) + drbd_WARN("bm UUID already set"); + + mdev->bc->md.uuid[Bitmap] = val; + mdev->bc->md.uuid[Bitmap] &= ~((u64)1); + + MTRACE(TraceTypeUuid, TraceLvlMetrics, + drbd_print_uuid(mdev, Bitmap); + ); + } + drbd_md_mark_dirty(mdev); +} + +/** + * drbd_bmio_set_n_write: + * Is an io_fn for drbd_queue_bitmap_io() or drbd_bitmap_io() that sets + * all bits in the bitmap and writes the whole bitmap to stable storage. + */ +int drbd_bmio_set_n_write(struct drbd_conf *mdev) +{ + int rv = -EIO; + + if (inc_local_if_state(mdev, Attaching)) { + drbd_md_set_flag(mdev, MDF_FullSync); + drbd_md_sync(mdev); + drbd_bm_set_all(mdev); + + rv = drbd_bm_write(mdev); + + if (!rv) { + drbd_md_clear_flag(mdev, MDF_FullSync); + drbd_md_sync(mdev); + } + + dec_local(mdev); + } + + return rv; +} + +/** + * drbd_bmio_clear_n_write: + * Is an io_fn for drbd_queue_bitmap_io() or drbd_bitmap_io() that clears + * all bits in the bitmap and writes the whole bitmap to stable storage. + */ +int drbd_bmio_clear_n_write(struct drbd_conf *mdev) +{ + int rv = -EIO; + + if (inc_local_if_state(mdev, Attaching)) { + drbd_bm_clear_all(mdev); + rv = drbd_bm_write(mdev); + dec_local(mdev); + } + + return rv; +} + +int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused) +{ + struct bm_io_work *work = (struct bm_io_work *)w; + int rv; + + D_ASSERT(atomic_read(&mdev->ap_bio_cnt) == 0); + + drbd_bm_lock(mdev, work->why); + rv = work->io_fn(mdev); + drbd_bm_unlock(mdev); + + clear_bit(BITMAP_IO, &mdev->flags); + wake_up(&mdev->misc_wait); + + if (work->done) + work->done(mdev, rv); + + clear_bit(BITMAP_IO_QUEUED, &mdev->flags); + work->why = NULL; + + return 1; +} + +/** + * drbd_queue_bitmap_io: + * Queues an IO operation on the whole bitmap. + * While IO on the bitmap happens we freeze appliation IO thus we ensure + * that drbd_set_out_of_sync() can not be called. + * This function MUST ONLY be called from worker context. + * BAD API ALERT! + * It MUST NOT be used while a previous such work is still pending! + */ +void drbd_queue_bitmap_io(struct drbd_conf *mdev, + int (*io_fn)(struct drbd_conf *), + void (*done)(struct drbd_conf *, int), + char *why) +{ + D_ASSERT(current == mdev->worker.task); + + D_ASSERT(!test_bit(BITMAP_IO_QUEUED, &mdev->flags)); + D_ASSERT(!test_bit(BITMAP_IO, &mdev->flags)); + D_ASSERT(list_empty(&mdev->bm_io_work.w.list)); + if (mdev->bm_io_work.why) + ERR("FIXME going to queue '%s' but '%s' still pending?\n", + why, mdev->bm_io_work.why); + + mdev->bm_io_work.io_fn = io_fn; + mdev->bm_io_work.done = done; + mdev->bm_io_work.why = why; + + set_bit(BITMAP_IO, &mdev->flags); + if (atomic_read(&mdev->ap_bio_cnt) == 0) { + if (list_empty(&mdev->bm_io_work.w.list)) { + set_bit(BITMAP_IO_QUEUED, &mdev->flags); + drbd_queue_work(&mdev->data.work, &mdev->bm_io_work.w); + } else + ERR("FIXME avoided double queuing bm_io_work\n"); + } +} + +/** + * drbd_bitmap_io: + * Does an IO operation on the bitmap, freezing application IO while that + * IO operations runs. This functions MUST NOT be called from worker context. + */ +int drbd_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf *), char *why) +{ + int rv; + + D_ASSERT(current != mdev->worker.task); + + drbd_suspend_io(mdev); + + drbd_bm_lock(mdev, why); + rv = io_fn(mdev); + drbd_bm_unlock(mdev); + + drbd_resume_io(mdev); + + return rv; +} + +void drbd_md_set_flag(struct drbd_conf *mdev, int flag) __must_hold(local) +{ + MUST_HOLD(mdev->req_lock); + if ((mdev->bc->md.flags & flag) != flag) { + drbd_md_mark_dirty(mdev); + mdev->bc->md.flags |= flag; + } +} + +void drbd_md_clear_flag(struct drbd_conf *mdev, int flag) __must_hold(local) +{ + MUST_HOLD(mdev->req_lock); + if ((mdev->bc->md.flags & flag) != 0) { + drbd_md_mark_dirty(mdev); + mdev->bc->md.flags &= ~flag; + } +} +int drbd_md_test_flag(struct drbd_backing_dev *bdev, int flag) +{ + return (bdev->md.flags & flag) != 0; +} + +STATIC void md_sync_timer_fn(unsigned long data) +{ + struct drbd_conf *mdev = (struct drbd_conf *) data; + + drbd_queue_work_front(&mdev->data.work, &mdev->md_sync_work); +} + +STATIC int w_md_sync(struct drbd_conf *mdev, struct drbd_work *w, int unused) +{ + drbd_WARN("md_sync_timer expired! Worker calls drbd_md_sync().\n"); + drbd_md_sync(mdev); + + return 1; +} + +#ifdef DRBD_ENABLE_FAULTS +/* Fault insertion support including random number generator shamelessly + * stolen from kernel/rcutorture.c */ +struct fault_random_state { + unsigned long state; + unsigned long count; +}; + +#define FAULT_RANDOM_MULT 39916801 /* prime */ +#define FAULT_RANDOM_ADD 479001701 /* prime */ +#define FAULT_RANDOM_REFRESH 10000 + +/* + * Crude but fast random-number generator. Uses a linear congruential + * generator, with occasional help from get_random_bytes(). + */ +STATIC unsigned long +_drbd_fault_random(struct fault_random_state *rsp) +{ + long refresh; + + if (--rsp->count < 0) { + get_random_bytes(&refresh, sizeof(refresh)); + rsp->state += refresh; + rsp->count = FAULT_RANDOM_REFRESH; + } + rsp->state = rsp->state * FAULT_RANDOM_MULT + FAULT_RANDOM_ADD; + return swahw32(rsp->state); +} + +STATIC char * +_drbd_fault_str(unsigned int type) { + static char *_faults[] = { + "Meta-data write", + "Meta-data read", + "Resync write", + "Resync read", + "Data write", + "Data read", + "Data read ahead", + }; + + return (type < DRBD_FAULT_MAX) ? _faults[type] : "**Unknown**"; +} + +unsigned int +_drbd_insert_fault(struct drbd_conf *mdev, unsigned int type) +{ + static struct fault_random_state rrs = {0, 0}; + + unsigned int ret = ( + (fault_devs == 0 || + ((1 << mdev_to_minor(mdev)) & fault_devs) != 0) && + (((_drbd_fault_random(&rrs) % 100) + 1) <= fault_rate)); + + if (ret) { + fault_count++; + + if (printk_ratelimit()) + drbd_WARN("***Simulating %s failure\n", + _drbd_fault_str(type)); + } + + return ret; +} +#endif + +#ifdef ENABLE_DYNAMIC_TRACE + +STATIC char *_drbd_uuid_str(unsigned int idx) +{ + static char *uuid_str[] = { + "Current", + "Bitmap", + "History_start", + "History_end", + "UUID_SIZE", + "UUID_FLAGS", + }; + + return (idx < EXT_UUID_SIZE) ? uuid_str[idx] : "*Unknown UUID index*"; +} + +/* Pretty print a UUID value */ +void drbd_print_uuid(struct drbd_conf *mdev, unsigned int idx) __must_hold(local) +{ + INFO(" uuid[%s] now %016llX\n", + _drbd_uuid_str(idx), (unsigned long long)mdev->bc->md.uuid[idx]); +} + + +/* + * + * drbd_print_buffer + * + * This routine dumps binary data to the debugging output. Can be + * called at interrupt level. + * + * Arguments: + * + * prefix - String is output at the beginning of each line output + * flags - Control operation of the routine. Currently defined + * Flags are: + * DBGPRINT_BUFFADDR; if set, each line starts with the + * virtual address of the line being outupt. If clear, + * each line starts with the offset from the beginning + * of the buffer. + * size - Indicates the size of each entry in the buffer. Supported + * values are sizeof(char), sizeof(short) and sizeof(int) + * buffer - Start address of buffer + * buffer_va - Virtual address of start of buffer (normally the same + * as Buffer, but having it separate allows it to hold + * file address for example) + * length - length of buffer + * + */ +void +drbd_print_buffer(const char *prefix, unsigned int flags, int size, + const void *buffer, const void *buffer_va, + unsigned int length) + +#define LINE_SIZE 16 +#define LINE_ENTRIES (int)(LINE_SIZE/size) +{ + const unsigned char *pstart; + const unsigned char *pstart_va; + const unsigned char *pend; + char bytes_str[LINE_SIZE*3+8], ascii_str[LINE_SIZE+8]; + char *pbytes = bytes_str, *pascii = ascii_str; + int offset = 0; + long sizemask; + int field_width; + int index; + const unsigned char *pend_str; + const unsigned char *p; + int count; + + /* verify size parameter */ + if (size != sizeof(char) && + size != sizeof(short) && + size != sizeof(int)) { + printk(KERN_DEBUG "drbd_print_buffer: " + "ERROR invalid size %d\n", size); + return; + } + + sizemask = size-1; + field_width = size*2; + + /* Adjust start/end to be on appropriate boundary for size */ + buffer = (const char *)((long)buffer & ~sizemask); + pend = (const unsigned char *) + (((long)buffer + length + sizemask) & ~sizemask); + + if (flags & DBGPRINT_BUFFADDR) { + /* Move start back to nearest multiple of line size, + * if printing address. This results in nicely formatted output + * with addresses being on line size (16) byte boundaries */ + pstart = (const unsigned char *)((long)buffer & ~(LINE_SIZE-1)); + } else { + pstart = (const unsigned char *)buffer; + } + + /* Set value of start VA to print if addresses asked for */ + pstart_va = (const unsigned char *)buffer_va + - ((const unsigned char *)buffer-pstart); + + /* Calculate end position to nicely align right hand side */ + pend_str = pstart + (((pend-pstart) + LINE_SIZE-1) & ~(LINE_SIZE-1)); + + /* Init strings */ + *pbytes = *pascii = '\0'; + + /* Start at beginning of first line */ + p = pstart; + count = 0; + + while (p < pend_str) { + if (p < (const unsigned char *)buffer || p >= pend) { + /* Before start of buffer or after end- print spaces */ + pbytes += sprintf(pbytes, "%*c ", field_width, ' '); + pascii += sprintf(pascii, "%*c", size, ' '); + p += size; + } else { + /* Add hex and ascii to strings */ + int val; + switch (size) { + default: + case 1: + val = *(unsigned char *)p; + break; + case 2: + val = *(unsigned short *)p; + break; + case 4: + val = *(unsigned int *)p; + break; + } + + pbytes += sprintf(pbytes, "%0*x ", field_width, val); + + for (index = size; index; index--) { + *pascii++ = isprint(*p) ? *p : '.'; + p++; + } + } + + count++; + + if (count == LINE_ENTRIES || p >= pend_str) { + /* Null terminate and print record */ + *pascii = '\0'; + printk(KERN_DEBUG "%s%8.8lx: %*s|%*s|\n", + prefix, + (flags & DBGPRINT_BUFFADDR) + ? (long)pstart_va : (long)offset, + LINE_ENTRIES*(field_width+1), bytes_str, + LINE_SIZE, ascii_str); + + /* Move onto next line */ + pstart_va += (p-pstart); + pstart = p; + count = 0; + offset += LINE_SIZE; + + /* Re-init strings */ + pbytes = bytes_str; + pascii = ascii_str; + *pbytes = *pascii = '\0'; + } + } +} + +#define PSM(A) \ +do { \ + if (mask.A) { \ + int i = snprintf(p, len, " " #A "( %s )", \ + A##s_to_name(val.A)); \ + if (i >= len) \ + return op; \ + p += i; \ + len -= i; \ + } \ +} while (0) + +STATIC char *dump_st(char *p, int len, union drbd_state_t mask, union drbd_state_t val) +{ + char *op = p; + *p = '\0'; + PSM(role); + PSM(peer); + PSM(conn); + PSM(disk); + PSM(pdsk); + + return op; +} + +#define INFOP(fmt, args...) \ +do { \ + if (trace_level >= TraceLvlAll) { \ + INFO("%s:%d: %s [%d] %s %s " fmt , \ + file, line, current->comm, current->pid, \ + sockname, recv ? "<<<" : ">>>" , \ + ## args); \ + } else { \ + INFO("%s %s " fmt, sockname, \ + recv ? "<<<" : ">>>" , \ + ## args); \ + } \ +} while (0) + +STATIC char *_dump_block_id(u64 block_id, char *buff) +{ + if (is_syncer_block_id(block_id)) + strcpy(buff, "SyncerId"); + else + sprintf(buff, "%llx", (unsigned long long)block_id); + + return buff; +} + +void +_dump_packet(struct drbd_conf *mdev, struct socket *sock, + int recv, union Drbd_Polymorph_Packet *p, char *file, int line) +{ + char *sockname = sock == mdev->meta.socket ? "meta" : "data"; + int cmd = (recv == 2) ? p->head.command : be16_to_cpu(p->head.command); + char tmp[300]; + union drbd_state_t m, v; + + switch (cmd) { + case HandShake: + INFOP("%s (protocol %u-%u)\n", cmdname(cmd), + be32_to_cpu(p->HandShake.protocol_min), + be32_to_cpu(p->HandShake.protocol_max)); + break; + + case ReportBitMap: /* don't report this */ + break; + + case Data: + INFOP("%s (sector %llus, id %s, seq %u, f %x)\n", cmdname(cmd), + (unsigned long long)be64_to_cpu(p->Data.sector), + _dump_block_id(p->Data.block_id, tmp), + be32_to_cpu(p->Data.seq_num), + be32_to_cpu(p->Data.dp_flags) + ); + break; + + case DataReply: + case RSDataReply: + INFOP("%s (sector %llus, id %s)\n", cmdname(cmd), + (unsigned long long)be64_to_cpu(p->Data.sector), + _dump_block_id(p->Data.block_id, tmp) + ); + break; + + case RecvAck: + case WriteAck: + case RSWriteAck: + case DiscardAck: + case NegAck: + case NegRSDReply: + INFOP("%s (sector %llus, size %u, id %s, seq %u)\n", + cmdname(cmd), + (long long)be64_to_cpu(p->BlockAck.sector), + be32_to_cpu(p->BlockAck.blksize), + _dump_block_id(p->BlockAck.block_id, tmp), + be32_to_cpu(p->BlockAck.seq_num) + ); + break; + + case DataRequest: + case RSDataRequest: + INFOP("%s (sector %llus, size %u, id %s)\n", cmdname(cmd), + (long long)be64_to_cpu(p->BlockRequest.sector), + be32_to_cpu(p->BlockRequest.blksize), + _dump_block_id(p->BlockRequest.block_id, tmp) + ); + break; + + case Barrier: + case BarrierAck: + INFOP("%s (barrier %u)\n", cmdname(cmd), p->Barrier.barrier); + break; + + case SyncParam: + case SyncParam89: + INFOP("%s (rate %u, verify-alg \"%.64s\", csums-alg \"%.64s\")\n", + cmdname(cmd), be32_to_cpu(p->SyncParam89.rate), + p->SyncParam89.verify_alg, p->SyncParam89.csums_alg); + break; + + case ReportUUIDs: + INFOP("%s Curr:%016llX, Bitmap:%016llX, " + "HisSt:%016llX, HisEnd:%016llX\n", + cmdname(cmd), + (unsigned long long)be64_to_cpu(p->GenCnt.uuid[Current]), + (unsigned long long)be64_to_cpu(p->GenCnt.uuid[Bitmap]), + (unsigned long long)be64_to_cpu(p->GenCnt.uuid[History_start]), + (unsigned long long)be64_to_cpu(p->GenCnt.uuid[History_end])); + break; + + case ReportSizes: + INFOP("%s (d %lluMiB, u %lluMiB, c %lldMiB, " + "max bio %x, q order %x)\n", + cmdname(cmd), + (long long)(be64_to_cpu(p->Sizes.d_size)>>(20-9)), + (long long)(be64_to_cpu(p->Sizes.u_size)>>(20-9)), + (long long)(be64_to_cpu(p->Sizes.c_size)>>(20-9)), + be32_to_cpu(p->Sizes.max_segment_size), + be32_to_cpu(p->Sizes.queue_order_type)); + break; + + case ReportState: + v.i = be32_to_cpu(p->State.state); + m.i = 0xffffffff; + dump_st(tmp, sizeof(tmp), m, v); + INFOP("%s (s %x {%s})\n", cmdname(cmd), v.i, tmp); + break; + + case StateChgRequest: + m.i = be32_to_cpu(p->ReqState.mask); + v.i = be32_to_cpu(p->ReqState.val); + dump_st(tmp, sizeof(tmp), m, v); + INFOP("%s (m %x v %x {%s})\n", cmdname(cmd), m.i, v.i, tmp); + break; + + case StateChgReply: + INFOP("%s (ret %x)\n", cmdname(cmd), + be32_to_cpu(p->RqSReply.retcode)); + break; + + case Ping: + case PingAck: + /* + * Dont trace pings at summary level + */ + if (trace_level < TraceLvlAll) + break; + /* fall through... */ + default: + INFOP("%s (%u)\n", cmdname(cmd), cmd); + break; + } +} + +/* Debug routine to dump info about bio */ + +void _dump_bio(const char *pfx, struct drbd_conf *mdev, struct bio *bio, int complete, struct drbd_request *r) +{ +#ifdef CONFIG_LBD +#define SECTOR_FORMAT "%Lx" +#else +#define SECTOR_FORMAT "%lx" +#endif +#define SECTOR_SHIFT 9 + + unsigned long lowaddr = (unsigned long)(bio->bi_sector << SECTOR_SHIFT); + char *faddr = (char *)(lowaddr); + char rb[sizeof(void*)*2+6] = { 0, }; + struct bio_vec *bvec; + int segno; + + const int rw = bio->bi_rw; + const int biorw = (rw & (RW_MASK|RWA_MASK)); + const int biobarrier = (rw & (1<>>", + pfx, + biorw == WRITE ? "Write" : "Read", + biobarrier ? " : B" : "", + biosync ? " : S" : "", + bio, + rb, + complete ? (drbd_bio_uptodate(bio) ? "Success, " : "Failed, ") : "", + bio->bi_sector << SECTOR_SHIFT, + bio->bi_size); + + if (trace_level >= TraceLvlMetrics && + ((biorw == WRITE) ^ complete)) { + printk(KERN_DEBUG " ind page offset length\n"); + __bio_for_each_segment(bvec, bio, segno, 0) { + printk(KERN_DEBUG " [%d] %p %8.8x %8.8x\n", segno, + bvec->bv_page, bvec->bv_offset, bvec->bv_len); + + if (trace_level >= TraceLvlAll) { + char *bvec_buf; + unsigned long flags; + + bvec_buf = bvec_kmap_irq(bvec, &flags); + + drbd_print_buffer(" ", DBGPRINT_BUFFADDR, 1, + bvec_buf, + faddr, + (bvec->bv_len <= 0x80) + ? bvec->bv_len : 0x80); + + bvec_kunmap_irq(bvec_buf, &flags); + + if (bvec->bv_len > 0x40) + printk(KERN_DEBUG " ....\n"); + + faddr += bvec->bv_len; + } + } + } +} +#endif + +module_init(drbd_init) +module_exit(drbd_cleanup) --- linux-2.6.28.orig/ubuntu/drbd/drbd_int.h +++ linux-2.6.28/ubuntu/drbd/drbd_int.h @@ -0,0 +1,2332 @@ +/* + drbd_int.h + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2001-2008, LINBIT Information Technologies GmbH. + Copyright (C) 1999-2008, Philipp Reisner . + Copyright (C) 2002-2008, Lars Ellenberg . + + drbd is free software; you can redistribute 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. + + drbd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef _DRBD_INT_H +#define _DRBD_INT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lru_cache.h" + +#ifdef __CHECKER__ +# define __protected_by(x) __attribute__((require_context(x,1,999,"rdwr"))) +# define __protected_read_by(x) __attribute__((require_context(x,1,999,"read"))) +# define __protected_write_by(x) __attribute__((require_context(x,1,999,"write"))) +# define __must_hold(x) __attribute__((context(x,1,1), require_context(x,1,999,"call"))) +#else +# define __protected_by(x) +# define __protected_read_by(x) +# define __protected_write_by(x) +# define __must_hold(x) +#endif + +#define __no_warn(lock, stmt) do { __acquire(lock); stmt; __release(lock); } while (0) + +/* Compatibility for older kernels */ +#ifndef __acquires +# ifdef __CHECKER__ +# define __acquires(x) __attribute__((context(x,0,1))) +# define __releases(x) __attribute__((context(x,1,0))) +# define __acquire(x) __context__(x,1) +# define __release(x) __context__(x,-1) +# define __cond_lock(x,c) ((c) ? ({ __acquire(x); 1; }) : 0) +# else +# define __acquires(x) +# define __releases(x) +# define __acquire(x) (void)0 +# define __release(x) (void)0 +# define __cond_lock(x,c) (c) +# endif +#endif + +/* module parameter, defined in drbd_main.c */ +extern unsigned int minor_count; +extern int allow_oos; +extern unsigned int cn_idx; + +#ifdef DRBD_ENABLE_FAULTS +extern int enable_faults; +extern int fault_rate; +extern int fault_devs; +#endif + +extern char usermode_helper[]; + +#include +#ifndef DRBD_MAJOR +# define DRBD_MAJOR 147 +#endif + +#include +#include + +/* XXX do we need this? */ +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +/* I don't remember why XCPU ... + * This is used to wake the asender, + * and to interrupt sending the sending task + * on disconnect. + */ +#define DRBD_SIG SIGXCPU + +/* This is used to stop/restart our threads. + * Cannot use SIGTERM nor SIGKILL, since these + * are sent out by init on runlevel changes + * I choose SIGHUP for now. + * + * FIXME btw, we should register some reboot notifier. + */ +#define DRBD_SIGKILL SIGHUP + +/* All EEs on the free list should have ID_VACANT (== 0) + * freshly allocated EEs get !ID_VACANT (== 1) + * so if it says "cannot dereference null pointer at adress 0x00000001", + * it is most likely one of these :( */ + +#define ID_IN_SYNC (4711ULL) +#define ID_OUT_OF_SYNC (4712ULL) + +#define ID_SYNCER (-1ULL) +#define ID_VACANT 0 +#define is_syncer_block_id(id) ((id) == ID_SYNCER) + +struct drbd_conf; + +#ifdef DBG_ALL_SYMBOLS +# define STATIC +#else +# define STATIC static +#endif + +#ifdef PARANOIA +# define PARANOIA_BUG_ON(x) BUG_ON(x) +#else +# define PARANOIA_BUG_ON(x) +#endif + +/* + * Some Message Macros + *************************/ + +/* handy macro: DUMPP(somepointer) */ +#define DUMPP(A) ERR(#A " = %p in %s:%d\n", (A), __FILE__, __LINE__); +#define DUMPLU(A) ERR(#A " = %lu in %s:%d\n", (unsigned long)(A), __FILE__, __LINE__); +#define DUMPLLU(A) ERR(#A " = %llu in %s:%d\n", (unsigned long long)(A), __FILE__, __LINE__); +#define DUMPLX(A) ERR(#A " = %lx in %s:%d\n", (A), __FILE__, __LINE__); +#define DUMPI(A) ERR(#A " = %d in %s:%d\n", (int)(A), __FILE__, __LINE__); + +#define DUMPST(A) DUMPLLU((unsigned long long)(A)) + +#if 0 +#define D_DUMPP(A) DUMPP(A) +#define D_DUMPLU(A) DUMPLU(A) +#define D_DUMPLLU(A) DUMPLLU(A) +#define D_DUMPLX(A) DUMPLX(A) +#define D_DUMPI(A) DUMPI(A) +#else +#define D_DUMPP(A) +#define D_DUMPLU(A) +#define D_DUMPLLU(A) +#define D_DUMPLX(A) +#define D_DUMPI(A) +#endif + +#define PRINTK(level, fmt, args...) \ + printk(level "drbd%d: " fmt, \ + mdev->minor , ##args) + +#define ALERT(fmt, args...) PRINTK(KERN_ALERT, fmt , ##args) +#define ERR(fmt, args...) PRINTK(KERN_ERR, fmt , ##args) +/* nowadays, WARN() is defined as BUG() without crash in bug.h */ +#define drbd_WARN(fmt, args...) PRINTK(KERN_WARNING, fmt , ##args) +#define INFO(fmt, args...) PRINTK(KERN_INFO, fmt , ##args) +#define DBG(fmt, args...) PRINTK(KERN_DEBUG, fmt , ##args) + +/* see kernel/printk.c:printk_ratelimit + * macro, so it is easy do have independend rate limits at different locations + * "initializer element not constant ..." with kernel 2.4 :( + * so I initialize toks to something large + */ +#define DRBD_ratelimit(ratelimit_jiffies, ratelimit_burst) \ +({ \ + int __ret; \ + static unsigned long toks = 0x80000000UL; \ + static unsigned long last_msg; \ + static int missed; \ + unsigned long now = jiffies; \ + toks += now - last_msg; \ + last_msg = now; \ + if (toks > (ratelimit_burst * ratelimit_jiffies)) \ + toks = ratelimit_burst * ratelimit_jiffies; \ + if (toks >= ratelimit_jiffies) { \ + int lost = missed; \ + missed = 0; \ + toks -= ratelimit_jiffies; \ + if (lost) \ + drbd_WARN("%d messages suppressed in %s:%d.\n", \ + lost, __FILE__, __LINE__); \ + __ret = 1; \ + } else { \ + missed++; \ + __ret = 0; \ + } \ + __ret; \ +}) + + +#ifdef DBG_ASSERTS +extern void drbd_assert_breakpoint(struct drbd_conf *, char *, char *, int); +# define D_ASSERT(exp) if (!(exp)) \ + drbd_assert_breakpoint(mdev, #exp, __FILE__, __LINE__) +#else +# define D_ASSERT(exp) if (!(exp)) \ + ERR("ASSERT( " #exp " ) in %s:%d\n", __FILE__, __LINE__) +#endif +#define ERR_IF(exp) if (({ \ + int _b = (exp) != 0; \ + if (_b) ERR("%s: (%s) in %s:%d\n", \ + __func__, #exp, __FILE__, __LINE__); \ + _b; \ + })) + +/* Defines to control fault insertion */ +enum { + DRBD_FAULT_MD_WR = 0, /* meta data write */ + DRBD_FAULT_MD_RD, /* read */ + DRBD_FAULT_RS_WR, /* resync */ + DRBD_FAULT_RS_RD, + DRBD_FAULT_DT_WR, /* data */ + DRBD_FAULT_DT_RD, + DRBD_FAULT_DT_RA, /* data read ahead */ + DRBD_FAULT_AL_EE, /* alloc ee */ + + DRBD_FAULT_MAX, +}; + +#ifdef DRBD_ENABLE_FAULTS +extern unsigned int +_drbd_insert_fault(struct drbd_conf *mdev, unsigned int type); +static inline int +drbd_insert_fault(struct drbd_conf *mdev, unsigned int type) { + return fault_rate && + (enable_faults & (1< +/* integer division, round _UP_ to the next integer */ +#define div_ceil(A, B) ((A)/(B) + ((A)%(B) ? 1 : 0)) +/* usual integer division */ +#define div_floor(A, B) ((A)/(B)) + +/* + * Compatibility Section + *************************/ + +#define LOCK_SIGMASK(task, flags) spin_lock_irqsave(&task->sighand->siglock, flags) +#define UNLOCK_SIGMASK(task, flags) spin_unlock_irqrestore(&task->sighand->siglock, flags) +#define RECALC_SIGPENDING() recalc_sigpending(); + +#if defined(DBG_SPINLOCKS) && defined(__SMP__) +# define MUST_HOLD(lock) if (!spin_is_locked(lock)) ERR("Not holding lock! in %s\n", __func__); +#else +# define MUST_HOLD(lock) +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8) +# define HAVE_KERNEL_SENDMSG 1 +#else +# define HAVE_KERNEL_SENDMSG 0 +#endif + +#ifndef uninitialized_var +/* in upstream since 9490991482a2091a828d997adbc088e24c310a4d + * Date: Sun May 6 14:49:17 2007 -0700 */ +/* + * A trick to suppress uninitialized variable warning without generating any + * code + */ +#define uninitialized_var(x) x = x +#endif + + + +/* + * our structs + *************************/ + +#define SET_MDEV_MAGIC(x) \ + ({ typecheck(struct drbd_conf*, x); \ + (x)->magic = (long)(x) ^ DRBD_MAGIC; }) +#define IS_VALID_MDEV(x) \ + (typecheck(struct drbd_conf*, x) && \ + ((x) ? (((x)->magic ^ DRBD_MAGIC) == (long)(x)) : 0)) + +/* drbd_meta-data.c (still in drbd_main.c) */ +/* 4th incarnation of the disk layout. */ +#define DRBD_MD_MAGIC (DRBD_MAGIC+4) + +extern struct drbd_conf **minor_table; + +/*** + * on the wire + *********************************************************************/ + +enum Drbd_Packet_Cmd { + /* receiver (data socket) */ + Data = 0x00, + DataReply = 0x01, /* Response to DataRequest */ + RSDataReply = 0x02, /* Response to RSDataRequest */ + Barrier = 0x03, + ReportBitMap = 0x04, + BecomeSyncTarget = 0x05, + BecomeSyncSource = 0x06, + UnplugRemote = 0x07, /* Used at various times to hint the peer */ + DataRequest = 0x08, /* Used to ask for a data block */ + RSDataRequest = 0x09, /* Used to ask for a data block for resync */ + SyncParam = 0x0a, + ReportProtocol = 0x0b, + ReportUUIDs = 0x0c, + ReportSizes = 0x0d, + ReportState = 0x0e, + ReportSyncUUID = 0x0f, + AuthChallenge = 0x10, + AuthResponse = 0x11, + StateChgRequest = 0x12, + + /* asender (meta socket */ + Ping = 0x13, + PingAck = 0x14, + RecvAck = 0x15, /* Used in protocol B */ + WriteAck = 0x16, /* Used in protocol C */ + RSWriteAck = 0x17, /* Is a WriteAck, additionally call set_in_sync(). */ + DiscardAck = 0x18, /* Used in proto C, two-primaries conflict detection */ + NegAck = 0x19, /* Sent if local disk is unusable */ + NegDReply = 0x1a, /* Local disk is broken... */ + NegRSDReply = 0x1b, /* Local disk is broken... */ + BarrierAck = 0x1c, + StateChgReply = 0x1d, + + /* "new" commands, no longer fitting into the ordering scheme above */ + + OVRequest = 0x1e, /* data socket */ + OVReply = 0x1f, + OVResult = 0x20, /* meta socket */ + CsumRSRequest = 0x21, /* data socket */ + RSIsInSync = 0x22, /* meta socket */ + SyncParam89 = 0x23, /* data socket, protocol version 89 replacement for SyncParam */ + + MAX_CMD = 0x24, + MayIgnore = 0x100, /* Flag to test if (cmd > MayIgnore) ... */ + MAX_OPT_CMD = 0x101, + + /* special command ids for handshake */ + + HandShakeM = 0xfff1, /* First Packet on the MetaSock */ + HandShakeS = 0xfff2, /* First Packet on the Socket */ + + HandShake = 0xfffe /* FIXED for the next century! */ +}; + +static inline const char *cmdname(enum Drbd_Packet_Cmd cmd) +{ + /* THINK may need to become several global tables + * when we want to support more than + * one PRO_VERSION */ + static const char *cmdnames[] = { + [Data] = "Data", + [DataReply] = "DataReply", + [RSDataReply] = "RSDataReply", + [Barrier] = "Barrier", + [ReportBitMap] = "ReportBitMap", + [BecomeSyncTarget] = "BecomeSyncTarget", + [BecomeSyncSource] = "BecomeSyncSource", + [UnplugRemote] = "UnplugRemote", + [DataRequest] = "DataRequest", + [RSDataRequest] = "RSDataRequest", + [SyncParam] = "SyncParam", + [SyncParam89] = "SyncParam89", + [ReportProtocol] = "ReportProtocol", + [ReportUUIDs] = "ReportUUIDs", + [ReportSizes] = "ReportSizes", + [ReportState] = "ReportState", + [ReportSyncUUID] = "ReportSyncUUID", + [AuthChallenge] = "AuthChallenge", + [AuthResponse] = "AuthResponse", + [Ping] = "Ping", + [PingAck] = "PingAck", + [RecvAck] = "RecvAck", + [WriteAck] = "WriteAck", + [RSWriteAck] = "RSWriteAck", + [DiscardAck] = "DiscardAck", + [NegAck] = "NegAck", + [NegDReply] = "NegDReply", + [NegRSDReply] = "NegRSDReply", + [BarrierAck] = "BarrierAck", + [StateChgRequest] = "StateChgRequest", + [StateChgReply] = "StateChgReply", + [OVRequest] = "OVRequest", + [OVReply] = "OVReply", + [OVResult] = "OVResult", + [CsumRSRequest] = "CsumRSRequest", + [RSIsInSync] = "RSIsInSync", + [MAX_CMD] = NULL, + }; + + if (cmd == HandShakeM) + return "HandShakeM"; + if (cmd == HandShakeS) + return "HandShakeS"; + if (cmd == HandShake) + return "HandShake"; + if (cmd >= MAX_CMD) + return "Unknown"; + return cmdnames[cmd]; +} + + +/* This is the layout for a packet on the wire. + * The byteorder is the network byte order. + * (except block_id and barrier fields. + * these are pointers to local structs + * and have no relevance for the partner, + * which just echoes them as received.) + * + * NOTE that the payload starts at a long aligned offset, + * regardless of 32 or 64 bit arch! + */ +struct Drbd_Header { + u32 magic; + u16 command; + u16 length; /* bytes of data after this header */ + char payload[0]; +} __attribute((packed)); +/* 8 bytes. packet FIXED for the next century! */ + +/* + * short commands, packets without payload, plain Drbd_Header: + * Ping + * PingAck + * BecomeSyncTarget + * BecomeSyncSource + * UnplugRemote + */ + +/* + * commands with out-of-struct payload: + * ReportBitMap (no additional fields) + * Data, DataReply (see Drbd_Data_Packet) + */ + +#define DP_HARDBARRIER 1 +#define DP_RW_SYNC 2 +#define DP_MAY_SET_IN_SYNC 4 + +struct Drbd_Data_Packet { + struct Drbd_Header head; + u64 sector; /* 64 bits sector number */ + u64 block_id; /* to identify the request in protocol B&C */ + u32 seq_num; + u32 dp_flags; +} __attribute((packed)); + +/* + * commands which share a struct: + * Drbd_BlockAck_Packet: + * RecvAck (proto B), WriteAck (proto C), + * DiscardAck (proto C, two-primaries conflict detection) + * Drbd_BlockRequest_Packet: + * DataRequest, RSDataRequest + */ +struct Drbd_BlockAck_Packet { + struct Drbd_Header head; + u64 sector; + u64 block_id; + u32 blksize; + u32 seq_num; +} __attribute((packed)); + + +struct Drbd_BlockRequest_Packet { + struct Drbd_Header head; + u64 sector; + u64 block_id; + u32 blksize; + u32 pad; /* to multiple of 8 Byte */ +} __attribute((packed)); + +/* + * commands with their own struct for additional fields: + * HandShake + * Barrier + * BarrierAck + * SyncParam + * ReportParams + */ + +struct Drbd_HandShake_Packet { + struct Drbd_Header head; /* 8 bytes */ + u32 protocol_min; + u32 feature_flags; + u32 protocol_max; + + /* should be more than enough for future enhancements + * for now, feature_flags and the reserverd array shall be zero. + */ + + u32 _pad; + u64 reserverd[7]; +} __attribute((packed)); +/* 80 bytes, FIXED for the next century */ + +struct Drbd_Barrier_Packet { + struct Drbd_Header head; + u32 barrier; /* barrier number _handle_ only */ + u32 pad; /* to multiple of 8 Byte */ +} __attribute((packed)); + +struct Drbd_BarrierAck_Packet { + struct Drbd_Header head; + u32 barrier; + u32 set_size; +} __attribute((packed)); + +struct Drbd_SyncParam_Packet { + struct Drbd_Header head; + u32 rate; + + /* Since protocol version 88 and higher. */ + char verify_alg[0]; +} __attribute((packed)); + +struct Drbd_SyncParam89_Packet { + struct Drbd_Header head; + u32 rate; + /* protocol version 89: */ + char verify_alg[SHARED_SECRET_MAX]; + char csums_alg[SHARED_SECRET_MAX]; +} __attribute((packed)); + +struct Drbd_Protocol_Packet { + struct Drbd_Header head; + u32 protocol; + u32 after_sb_0p; + u32 after_sb_1p; + u32 after_sb_2p; + u32 want_lose; + u32 two_primaries; + + /* Since protocol version 87 and higher. */ + char integrity_alg[0]; + +} __attribute((packed)); + +struct Drbd_GenCnt_Packet { + struct Drbd_Header head; + u64 uuid[EXT_UUID_SIZE]; +} __attribute((packed)); + +struct Drbd_SyncUUID_Packet { + struct Drbd_Header head; + u64 uuid; +} __attribute((packed)); + +struct Drbd_Sizes_Packet { + struct Drbd_Header head; + u64 d_size; /* size of disk */ + u64 u_size; /* user requested size */ + u64 c_size; /* current exported size */ + u32 max_segment_size; /* Maximal size of a BIO */ + u32 queue_order_type; +} __attribute((packed)); + +struct Drbd_State_Packet { + struct Drbd_Header head; + u32 state; +} __attribute((packed)); + +struct Drbd_Req_State_Packet { + struct Drbd_Header head; + u32 mask; + u32 val; +} __attribute((packed)); + +struct Drbd_RqS_Reply_Packet { + struct Drbd_Header head; + u32 retcode; +} __attribute((packed)); + +struct Drbd06_Parameter_P { + u64 size; + u32 state; + u32 blksize; + u32 protocol; + u32 version; + u32 gen_cnt[5]; + u32 bit_map_gen[5]; +} __attribute((packed)); + +struct Drbd_Discard_Packet { + struct Drbd_Header head; + u64 block_id; + u32 seq_num; + u32 pad; +} __attribute((packed)); + +union Drbd_Polymorph_Packet { + struct Drbd_Header head; + struct Drbd_HandShake_Packet HandShake; + struct Drbd_Data_Packet Data; + struct Drbd_BlockAck_Packet BlockAck; + struct Drbd_Barrier_Packet Barrier; + struct Drbd_BarrierAck_Packet BarrierAck; + struct Drbd_SyncParam89_Packet SyncParam89; + struct Drbd_Protocol_Packet Protocol; + struct Drbd_Sizes_Packet Sizes; + struct Drbd_GenCnt_Packet GenCnt; + struct Drbd_State_Packet State; + struct Drbd_Req_State_Packet ReqState; + struct Drbd_RqS_Reply_Packet RqSReply; + struct Drbd_BlockRequest_Packet BlockRequest; +} __attribute((packed)); + +/**********************************************************************/ +enum Drbd_thread_state { + None, + Running, + Exiting, + Restarting +}; + +struct Drbd_thread { + spinlock_t t_lock; + struct task_struct *task; + struct completion startstop; + enum Drbd_thread_state t_state; + int (*function) (struct Drbd_thread *); + struct drbd_conf *mdev; + int reset_cpu_mask; +}; + +static inline enum Drbd_thread_state get_t_state(struct Drbd_thread *thi) +{ + /* THINK testing the t_state seems to be uncritical in all cases + * (but thread_{start,stop}), so we can read it *without* the lock. + * --lge */ + + smp_rmb(); + return thi->t_state; +} + + +/* + * Having this as the first member of a struct provides sort of "inheritance". + * "derived" structs can be "drbd_queue_work()"ed. + * The callback should know and cast back to the descendant struct. + * drbd_request and Tl_epoch_entry are descendants of drbd_work. + */ +struct drbd_work; +typedef int (*drbd_work_cb)(struct drbd_conf *, struct drbd_work *, int cancel); +struct drbd_work { + struct list_head list; + drbd_work_cb cb; +}; + +struct drbd_barrier; +struct drbd_request { + struct drbd_work w; + struct drbd_conf *mdev; + struct bio *private_bio; + struct hlist_node colision; + sector_t sector; + unsigned int size; + unsigned int epoch; /* barrier_nr */ + + /* barrier_nr: used to check on "completion" whether this req was in + * the current epoch, and we therefore have to close it, + * starting a new epoch... + */ + + /* up to here, the struct layout is identical to Tl_epoch_entry; + * we might be able to use that to our advantage... */ + + struct list_head tl_requests; /* ring list in the transfer log */ + struct bio *master_bio; /* master bio pointer */ + unsigned long rq_state; /* see comments above _req_mod() */ + int seq_num; + unsigned long start_time; +}; + +struct drbd_barrier { + struct drbd_work w; + struct list_head requests; /* requests before */ + struct drbd_barrier *next; /* pointer to the next barrier */ + unsigned int br_number; /* the barriers identifier. */ + int n_req; /* number of requests attached before this barrier */ +}; + +struct drbd_request; + +/* These Tl_epoch_entries may be in one of 6 lists: + active_ee .. data packet being written + sync_ee .. syncer block being written + done_ee .. block written, need to send WriteAck + read_ee .. [RS]DataRequest being read +*/ + +struct drbd_epoch { + struct list_head list; + unsigned int barrier_nr; + atomic_t epoch_size; /* increased on every request added. */ + atomic_t active; /* increased on every req. added, and dec on every finished. */ + unsigned long flags; +}; + +/* drbd_epoch flag bits */ +enum { + DE_BARRIER_IN_NEXT_EPOCH_ISSUED, + DE_BARRIER_IN_NEXT_EPOCH_DONE, + DE_CONTAINS_A_BARRIER, + DE_HAVE_BARRIER_NUMBER, + DE_IS_FINISHING, +}; + +struct Tl_epoch_entry { + struct drbd_work w; + struct drbd_conf *mdev; + struct bio *private_bio; + struct hlist_node colision; + sector_t sector; + unsigned int size; + struct drbd_epoch *epoch; + + /* up to here, the struct layout is identical to drbd_request; + * we might be able to use that to our advantage... */ + + unsigned int flags; + u64 block_id; +}; + +struct digest_info { + int digest_size; + void *digest; +}; + +/* ee flag bits */ +enum { + __EE_CALL_AL_COMPLETE_IO, + __EE_CONFLICT_PENDING, + __EE_MAY_SET_IN_SYNC, + __EE_IS_BARRIER, +}; +#define EE_CALL_AL_COMPLETE_IO (1<<__EE_CALL_AL_COMPLETE_IO) +#define EE_CONFLICT_PENDING (1<<__EE_CONFLICT_PENDING) +#define EE_MAY_SET_IN_SYNC (1<<__EE_MAY_SET_IN_SYNC) +#define EE_IS_BARRIER (1<<__EE_IS_BARRIER) + +/* global flag bits */ +enum { + CREATE_BARRIER, /* next Data is preceeded by a Barrier */ + SIGNAL_ASENDER, /* whether asender wants to be interrupted */ + SEND_PING, /* whether asender should send a ping asap */ + WORK_PENDING, /* completion flag for drbd_disconnect */ + STOP_SYNC_TIMER, /* tell timer to cancel itself */ + UNPLUG_QUEUED, /* only relevant with kernel 2.4 */ + UNPLUG_REMOTE, /* sending a "UnplugRemote" could help */ + MD_DIRTY, /* current uuids and flags not yet on disk */ + DISCARD_CONCURRENT, /* Set on one node, cleared on the peer! */ + USE_DEGR_WFC_T, /* degr-wfc-timeout instead of wfc-timeout. */ + CLUSTER_ST_CHANGE, /* Cluster wide state change going on... */ + CL_ST_CHG_SUCCESS, + CL_ST_CHG_FAIL, + CRASHED_PRIMARY, /* This node was a crashed primary. + * Gets cleared when the state.conn + * goes into Connected state. */ + WRITE_BM_AFTER_RESYNC, /* A kmalloc() during resync failed */ + NO_BARRIER_SUPP, /* underlying block device doesn't implement barriers */ + CONSIDER_RESYNC, + + MD_NO_BARRIER, /* meta data device does not support barriers, + so don't even try */ + SUSPEND_IO, /* suspend application io */ + BITMAP_IO, /* suspend application io; + once no more io in flight, start bitmap io */ + BITMAP_IO_QUEUED, /* Started bitmap IO */ + RESYNC_AFTER_NEG, /* Resync after online grow after the attach&negotiate finished. */ +}; + +struct drbd_bitmap; /* opaque for drbd_conf */ + +/* TODO sort members for performance + * MAYBE group them further */ + +/* THINK maybe we actually want to use the default "event/%s" worker threads + * or similar in linux 2.6, which uses per cpu data and threads. + * + * To be general, this might need a spin_lock member. + * For now, please use the mdev->req_lock to protect list_head, + * see drbd_queue_work below. + */ +struct drbd_work_queue { + struct list_head q; + struct semaphore s; /* producers up it, worker down()s it */ + spinlock_t q_lock; /* to protect the list. */ +}; + +/* If Philipp agrees, we remove the "mutex", and make_request will only + * (throttle on "queue full" condition and) queue it to the worker thread... + * which then is free to do whatever is needed, and has exclusive send access + * to the data socket ... + */ +struct drbd_socket { + struct drbd_work_queue work; + struct semaphore mutex; + struct socket *socket; + /* this way we get our + * send/receive buffers off the stack */ + union Drbd_Polymorph_Packet sbuf; + union Drbd_Polymorph_Packet rbuf; +}; + +struct drbd_md { + u64 md_offset; /* sector offset to 'super' block */ + + u64 la_size_sect; /* last agreed size, unit sectors */ + u64 uuid[UUID_SIZE]; + u64 device_uuid; + u32 flags; + u32 md_size_sect; + + s32 al_offset; /* signed relative sector offset to al area */ + s32 bm_offset; /* signed relative sector offset to bitmap */ + + /* u32 al_nr_extents; important for restoring the AL + * is stored into sync_conf.al_extents, which in turn + * gets applied to act_log->nr_elements + */ +}; + +/* for sync_conf and other types... */ +#define NL_PACKET(name, number, fields) struct name { fields }; +#define NL_INTEGER(pn,pr,member) int member; +#define NL_INT64(pn,pr,member) __u64 member; +#define NL_BIT(pn,pr,member) unsigned member:1; +#define NL_STRING(pn,pr,member,len) unsigned char member[len]; int member ## _len; +#include "linux/drbd_nl.h" + +struct drbd_backing_dev { + struct block_device *backing_bdev; + struct block_device *md_bdev; + struct file *lo_file; + struct file *md_file; + struct drbd_md md; + struct disk_conf dc; /* The user provided config... */ + sector_t known_size; /* last known size of that backing device */ +}; + +struct drbd_md_io { + struct drbd_conf *mdev; + struct completion event; + int error; +}; + +struct bm_io_work { + struct drbd_work w; + char *why; + int (*io_fn)(struct drbd_conf *mdev); + void (*done)(struct drbd_conf *mdev, int rv); +}; + +enum write_ordering_e { + WO_none, + WO_drain_io, + WO_bdev_flush, + WO_bio_barrier +}; + +struct drbd_conf { +#ifdef PARANOIA + long magic; +#endif + /* things that are stored as / read from meta data on disk */ + unsigned long flags; + + /* configured by drbdsetup */ + struct net_conf *net_conf; /* protected by inc_net() and dec_net() */ + struct syncer_conf sync_conf; + struct drbd_backing_dev *bc __protected_by(local); + + sector_t p_size; /* partner's disk size */ + struct request_queue *rq_queue; + struct block_device *this_bdev; + struct gendisk *vdisk; + + struct drbd_socket data; /* data/barrier/cstate/parameter packets */ + struct drbd_socket meta; /* ping/ack (metadata) packets */ + int agreed_pro_version; /* actually used protocol version */ + unsigned long last_received; /* in jiffies, either socket */ + unsigned int ko_count; + struct drbd_work resync_work, + unplug_work, + md_sync_work; + struct timer_list resync_timer; + struct timer_list md_sync_timer; + + /* Used after attach while negotiating new disk state. */ + union drbd_state_t new_state_tmp; + + union drbd_state_t state; + wait_queue_head_t misc_wait; + wait_queue_head_t state_wait; /* upon each state change. */ + unsigned int send_cnt; + unsigned int recv_cnt; + unsigned int read_cnt; + unsigned int writ_cnt; + unsigned int al_writ_cnt; + unsigned int bm_writ_cnt; + atomic_t ap_bio_cnt; /* Requests we need to complete */ + atomic_t ap_pending_cnt; /* AP data packets on the wire, ack expected */ + atomic_t rs_pending_cnt; /* RS request/data packets on the wire */ + atomic_t unacked_cnt; /* Need to send replys for */ + atomic_t local_cnt; /* Waiting for local completion */ + atomic_t net_cnt; /* Users of net_conf */ + spinlock_t req_lock; + struct drbd_barrier *unused_spare_barrier; /* for pre-allocation */ + struct drbd_barrier *newest_barrier; + struct drbd_barrier *oldest_barrier; + struct list_head out_of_sequence_requests; + struct hlist_head *tl_hash; + unsigned int tl_hash_s; + + /* blocks to sync in this run [unit BM_BLOCK_SIZE] */ + unsigned long rs_total; + /* number of sync IOs that failed in this run */ + unsigned long rs_failed; + /* Syncer's start time [unit jiffies] */ + unsigned long rs_start; + /* cumulated time in PausedSyncX state [unit jiffies] */ + unsigned long rs_paused; + /* block not up-to-date at mark [unit BM_BLOCK_SIZE] */ + unsigned long rs_mark_left; + /* marks's time [unit jiffies] */ + unsigned long rs_mark_time; + /* skipped because csum was equeal [unit BM_BLOCK_SIZE] */ + unsigned long rs_same_csum; + sector_t ov_position; + /* Start sector of out of sync range. */ + sector_t ov_last_oos_start; + /* size of out-of-sync range in sectors. */ + sector_t ov_last_oos_size; + unsigned long ov_left; + struct crypto_hash *csums_tfm; + struct crypto_hash *verify_tfm; + + struct Drbd_thread receiver; + struct Drbd_thread worker; + struct Drbd_thread asender; + struct drbd_bitmap *bitmap; + + /* Used to track operations of resync... */ + struct lru_cache *resync; + /* Number of locked elements in resync LRU */ + unsigned int resync_locked; + /* resync extent number waiting for application requests */ + unsigned int resync_wenr; + + int open_cnt; + u64 *p_uuid; + /* FIXME clean comments, restructure so it is more obvious which + * members are protected by what */ + struct drbd_epoch *current_epoch; + spinlock_t epoch_lock; + unsigned int epochs; + enum write_ordering_e write_ordering; + struct list_head active_ee; /* IO in progress */ + struct list_head sync_ee; /* IO in progress */ + struct list_head done_ee; /* send ack */ + struct list_head read_ee; /* IO in progress */ + struct list_head net_ee; /* zero-copy network send in progress */ + struct hlist_head *ee_hash; /* is proteced by req_lock! */ + unsigned int ee_hash_s; + + /* this one is protected by ee_lock, single thread */ + struct Tl_epoch_entry *last_write_w_barrier; + + int next_barrier_nr; + struct hlist_head *app_reads_hash; /* is proteced by req_lock */ + struct list_head resync_reads; + atomic_t pp_in_use; + wait_queue_head_t ee_wait; + struct page *md_io_page; /* one page buffer for md_io */ + struct page *md_io_tmpp; /* for hardsect != 512 [s390 only?] */ + struct semaphore md_io_mutex; /* protects the md_io_buffer */ + spinlock_t al_lock; + wait_queue_head_t al_wait; + struct lru_cache *act_log; /* activity log */ + unsigned int al_tr_number; + int al_tr_cycle; + int al_tr_pos; /* position of the next transaction in the journal */ + struct crypto_hash *cram_hmac_tfm; + struct crypto_hash *integrity_w_tfm; /* to be used by the worker thread */ + struct crypto_hash *integrity_r_tfm; /* to be used by the receiver thread */ + void *int_dig_out; + void *int_dig_in; + void *int_dig_vv; + wait_queue_head_t seq_wait; + atomic_t packet_seq; + unsigned int peer_seq; + spinlock_t peer_seq_lock; + int minor; + unsigned long comm_bm_set; /* communicated number of set bits. */ + cpumask_t cpu_mask; + struct bm_io_work bm_io_work; + u64 ed_uuid; /* UUID of the exposed data */ + struct mutex state_mutex; +}; + +static inline struct drbd_conf *minor_to_mdev(unsigned int minor) +{ + struct drbd_conf *mdev; + + mdev = minor < minor_count ? minor_table[minor] : NULL; + + return mdev; +} + +static inline int mdev_to_minor(struct drbd_conf *mdev) +{ + return mdev->minor; +} + +/* returns 1 if it was successfull, + * returns 0 if there was no data socket. + * so wherever you are going to use the data.socket, e.g. do + * if (!drbd_get_data_sock(mdev)) + * return 0; + * CODE(); + * drbd_put_data_sock(mdev); + */ +static inline int drbd_get_data_sock(struct drbd_conf *mdev) +{ + down(&mdev->data.mutex); + /* drbd_disconnect() could have called drbd_free_sock() + * while we were waiting in down()... */ + if (unlikely(mdev->data.socket == NULL)) { + up(&mdev->data.mutex); + return 0; + } + return 1; +} + +static inline void drbd_put_data_sock(struct drbd_conf *mdev) +{ + up(&mdev->data.mutex); +} + +/* + * function declarations + *************************/ + +/* drbd_main.c */ + +enum chg_state_flags { + ChgStateHard = 1, + ChgStateVerbose = 2, + ChgWaitComplete = 4, + ChgSerialize = 8, + ChgOrdered = ChgWaitComplete + ChgSerialize, +}; + +extern void drbd_init_set_defaults(struct drbd_conf *mdev); +extern int drbd_change_state(struct drbd_conf *mdev, enum chg_state_flags f, + union drbd_state_t mask, union drbd_state_t val); +extern void drbd_force_state(struct drbd_conf *, union drbd_state_t, + union drbd_state_t); +extern int _drbd_request_state(struct drbd_conf *, union drbd_state_t, + union drbd_state_t, enum chg_state_flags); +extern int _drbd_set_state(struct drbd_conf *, union drbd_state_t, + enum chg_state_flags, struct completion *done); +extern void print_st_err(struct drbd_conf *, union drbd_state_t, + union drbd_state_t, int); +extern int drbd_thread_start(struct Drbd_thread *thi); +extern void _drbd_thread_stop(struct Drbd_thread *thi, int restart, int wait); +#ifdef CONFIG_SMP +extern void drbd_thread_current_set_cpu(struct drbd_conf *mdev); +extern cpumask_t drbd_calc_cpu_mask(struct drbd_conf *mdev); +#else +#define drbd_thread_current_set_cpu(A) ({}) +#define drbd_calc_cpu_mask(A) CPU_MASK_ALL +#endif +extern void drbd_free_resources(struct drbd_conf *mdev); +extern void tl_release(struct drbd_conf *mdev, unsigned int barrier_nr, + unsigned int set_size); +extern void tl_clear(struct drbd_conf *mdev); +extern void _tl_add_barrier(struct drbd_conf *, struct drbd_barrier *); +extern void drbd_free_sock(struct drbd_conf *mdev); +extern int drbd_send(struct drbd_conf *mdev, struct socket *sock, + void *buf, size_t size, unsigned msg_flags); +extern int drbd_send_protocol(struct drbd_conf *mdev); +extern int _drbd_send_uuids(struct drbd_conf *mdev); +extern int drbd_send_uuids(struct drbd_conf *mdev); +extern int drbd_send_sync_uuid(struct drbd_conf *mdev, u64 val); +extern int drbd_send_sizes(struct drbd_conf *mdev); +extern int _drbd_send_state(struct drbd_conf *mdev); +extern int drbd_send_state(struct drbd_conf *mdev); +extern int _drbd_send_cmd(struct drbd_conf *mdev, struct socket *sock, + enum Drbd_Packet_Cmd cmd, struct Drbd_Header *h, + size_t size, unsigned msg_flags); +#define USE_DATA_SOCKET 1 +#define USE_META_SOCKET 0 +extern int drbd_send_cmd(struct drbd_conf *mdev, int use_data_socket, + enum Drbd_Packet_Cmd cmd, struct Drbd_Header *h, + size_t size); +extern int drbd_send_cmd2(struct drbd_conf *mdev, enum Drbd_Packet_Cmd cmd, + char *data, size_t size); +extern int drbd_send_sync_param(struct drbd_conf *mdev, struct syncer_conf *sc); +extern int drbd_send_b_ack(struct drbd_conf *mdev, u32 barrier_nr, + u32 set_size); +extern int drbd_send_ack(struct drbd_conf *mdev, enum Drbd_Packet_Cmd cmd, + struct Tl_epoch_entry *e); +extern int drbd_send_ack_rp(struct drbd_conf *mdev, enum Drbd_Packet_Cmd cmd, + struct Drbd_BlockRequest_Packet *rp); +extern int drbd_send_ack_dp(struct drbd_conf *mdev, enum Drbd_Packet_Cmd cmd, + struct Drbd_Data_Packet *dp); +extern int drbd_send_ack_ex(struct drbd_conf *mdev, enum Drbd_Packet_Cmd cmd, + sector_t sector, int blksize, u64 block_id); +extern int _drbd_send_page(struct drbd_conf *mdev, struct page *page, + int offset, size_t size); +extern int drbd_send_block(struct drbd_conf *mdev, enum Drbd_Packet_Cmd cmd, + struct Tl_epoch_entry *e); +extern int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req); +extern int _drbd_send_barrier(struct drbd_conf *mdev, + struct drbd_barrier *barrier); +extern int drbd_send_drequest(struct drbd_conf *mdev, int cmd, + sector_t sector, int size, u64 block_id); +extern int drbd_send_drequest_csum(struct drbd_conf *mdev, + sector_t sector,int size, + void *digest, int digest_size, + enum Drbd_Packet_Cmd cmd); +extern int drbd_send_ov_request(struct drbd_conf *mdev,sector_t sector,int size); + +extern int drbd_send_bitmap(struct drbd_conf *mdev); +extern int _drbd_send_bitmap(struct drbd_conf *mdev); +extern int drbd_send_sr_reply(struct drbd_conf *mdev, int retcode); +extern void drbd_free_bc(struct drbd_backing_dev *bc); +extern int drbd_io_error(struct drbd_conf *mdev, int forcedetach); +extern void drbd_mdev_cleanup(struct drbd_conf *mdev); + +/* drbd_meta-data.c (still in drbd_main.c) */ +extern void drbd_md_sync(struct drbd_conf *mdev); +extern int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev); +/* maybe define them below as inline? */ +extern void drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local); +extern void _drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local); +extern void drbd_uuid_new_current(struct drbd_conf *mdev) __must_hold(local); +extern void _drbd_uuid_new_current(struct drbd_conf *mdev) __must_hold(local); +extern void drbd_uuid_set_bm(struct drbd_conf *mdev, u64 val) __must_hold(local); +extern void drbd_md_set_flag(struct drbd_conf *mdev, int flags) __must_hold(local); +extern void drbd_md_clear_flag(struct drbd_conf *mdev, int flags)__must_hold(local); +extern int drbd_md_test_flag(struct drbd_backing_dev *, int); +extern void drbd_md_mark_dirty(struct drbd_conf *mdev); +extern void drbd_queue_bitmap_io(struct drbd_conf *mdev, + int (*io_fn)(struct drbd_conf *), + void (*done)(struct drbd_conf *, int), + char *why); +extern int drbd_bmio_set_n_write(struct drbd_conf *mdev); +extern int drbd_bmio_clear_n_write(struct drbd_conf *mdev); +extern int drbd_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf *), char *why); + + +/* Meta data layout + We reserve a 128MB Block (4k aligned) + * either at the end of the backing device + * or on a seperate meta data device. */ + +#define MD_RESERVED_SECT (128LU << 11) /* 128 MB, unit sectors */ +/* The following numbers are sectors */ +#define MD_AL_OFFSET 8 /* 8 Sectors after start of meta area */ +#define MD_AL_MAX_SIZE 64 /* = 32 kb LOG ~ 3776 extents ~ 14 GB Storage */ +/* Allows up to about 3.8TB */ +#define MD_BM_OFFSET (MD_AL_OFFSET + MD_AL_MAX_SIZE) + +/* Since the smalles IO unit is usually 512 byte */ +#define MD_HARDSECT_B 9 +#define MD_HARDSECT (1< we need 32 KB bitmap. + * Bit 0 ==> local node thinks this block is binary identical on both nodes + * Bit 1 ==> local node thinks this block needs to be synced. + */ + +#define BM_BLOCK_SIZE_B 12 /* 4k per bit */ +#define BM_BLOCK_SIZE (1<>(BM_BLOCK_SIZE_B-9)) +#define BM_BIT_TO_SECT(x) ((sector_t)(x)<<(BM_BLOCK_SIZE_B-9)) +#define BM_SECT_PER_BIT BM_BIT_TO_SECT(1) + +/* bit to represented kilo byte conversion */ +#define Bit2KB(bits) ((bits)<<(BM_BLOCK_SIZE_B-10)) + +/* in which _bitmap_ extent (resp. sector) the bit for a certain + * _storage_ sector is located in */ +#define BM_SECT_TO_EXT(x) ((x)>>(BM_EXT_SIZE_B-9)) + +/* how much _storage_ sectors we have per bitmap sector */ +#define BM_EXT_TO_SECT(x) ((sector_t)(x) << (BM_EXT_SIZE_B-9)) +#define BM_SECT_PER_EXT BM_EXT_TO_SECT(1) + +/* in one sector of the bitmap, we have this many activity_log extents. */ +#define AL_EXT_PER_BM_SECT (1 << (BM_EXT_SIZE_B - AL_EXTENT_SIZE_B)) +#define BM_WORDS_PER_AL_EXT (1 << (AL_EXTENT_SIZE_B-BM_BLOCK_SIZE_B-LN2_BPL)) + + +#define BM_BLOCKS_PER_BM_EXT_B (BM_EXT_SIZE_B - BM_BLOCK_SIZE_B) +#define BM_BLOCKS_PER_BM_EXT_MASK ((1<= level) && (type & trace_type); +} +static inline int +is_mdev_trace(struct drbd_conf *mdev, unsigned int type, unsigned int level) { + return is_trace(type, level) && + ((1 << mdev_to_minor(mdev)) & trace_devs); +} + +#define MTRACE(type, lvl, code...) \ +do { \ + if (unlikely(is_mdev_trace(mdev, type, lvl))) { \ + code \ + } \ +} while (0) + +#define TRACE(type, lvl, code...) \ +do { \ + if (unlikely(is_trace(type, lvl))) { \ + code \ + } \ +} while (0) + +/* Buffer printing support + * dbg_print_flags: used for Flags arg to drbd_print_buffer + * - DBGPRINT_BUFFADDR; if set, each line starts with the + * virtual address of the line being output. If clear, + * each line starts with the offset from the beginning + * of the buffer. */ +enum dbg_print_flags { + DBGPRINT_BUFFADDR = 0x0001, +}; + +extern void drbd_print_uuid(struct drbd_conf *mdev, unsigned int idx); + +extern void drbd_print_buffer(const char *prefix, unsigned int flags, int size, + const void *buffer, const void *buffer_va, + unsigned int length); + +/* Bio printing support */ +extern void _dump_bio(const char *pfx, struct drbd_conf *mdev, struct bio *bio, int complete, struct drbd_request *r); + +static inline void dump_bio(struct drbd_conf *mdev, + struct bio *bio, int complete, struct drbd_request *r) +{ + MTRACE(TraceTypeRq, TraceLvlSummary, + _dump_bio("Rq", mdev, bio, complete, r); + ); +} + +static inline void dump_internal_bio(const char *pfx, struct drbd_conf *mdev, struct bio *bio, int complete) +{ + MTRACE(TraceTypeIntRq, TraceLvlSummary, + _dump_bio(pfx, mdev, bio, complete, NULL); + ); +} + +/* Packet dumping support */ +extern void _dump_packet(struct drbd_conf *mdev, struct socket *sock, + int recv, union Drbd_Polymorph_Packet *p, + char *file, int line); + +static inline void +dump_packet(struct drbd_conf *mdev, struct socket *sock, + int recv, union Drbd_Polymorph_Packet *p, char *file, int line) +{ + MTRACE(TraceTypePacket, TraceLvlSummary, + _dump_packet(mdev, sock, recv, p, file, line); + ); +} + +#else + +#define MTRACE(ignored...) ((void)0) +#define TRACE(ignored...) ((void)0) + +#define dump_bio(ignored...) ((void)0) +#define dump_internal_bio(ignored...) ((void)0) +#define dump_packet(ignored...) ((void)0) +#endif + +/* drbd_req */ +extern int drbd_make_request_26(struct request_queue *q, struct bio *bio); +extern int drbd_read_remote(struct drbd_conf *mdev, struct drbd_request *req); +extern int drbd_merge_bvec(struct request_queue *q, +#ifdef HAVE_bvec_merge_data + struct bvec_merge_data *bvm, +#else + struct bio *bvm, +#endif + struct bio_vec *bvec); +extern int is_valid_ar_handle(struct drbd_request *, sector_t); + + +/* drbd_nl.c */ +extern void drbd_suspend_io(struct drbd_conf *mdev); +extern void drbd_resume_io(struct drbd_conf *mdev); +extern char *ppsize(char *buf, unsigned long long size); +extern sector_t drbd_new_dev_size(struct drbd_conf *, + struct drbd_backing_dev *); +enum determin_dev_size_enum { dev_size_error = -1, unchanged = 0, shrunk = 1, grew = 2 }; +extern enum determin_dev_size_enum drbd_determin_dev_size(struct drbd_conf *) __must_hold(local); +extern void resync_after_online_grow(struct drbd_conf *); +extern void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int) __must_hold(local); +extern int drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, + int force); +enum drbd_disk_state drbd_try_outdate_peer(struct drbd_conf *mdev); +extern int drbd_khelper(struct drbd_conf *mdev, char *cmd); + +/* drbd_worker.c */ +extern int drbd_worker(struct Drbd_thread *thi); +extern void drbd_alter_sa(struct drbd_conf *mdev, int na); +extern void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side); +extern void resume_next_sg(struct drbd_conf *mdev); +extern void suspend_other_sg(struct drbd_conf *mdev); +extern int drbd_resync_finished(struct drbd_conf *mdev); +/* maybe rather drbd_main.c ? */ +extern int drbd_md_sync_page_io(struct drbd_conf *mdev, + struct drbd_backing_dev *bdev, sector_t sector, int rw); +extern void drbd_ov_oos_found(struct drbd_conf*, sector_t, int); + +static inline void ov_oos_print(struct drbd_conf *mdev) +{ + if (mdev->ov_last_oos_size) { + ERR("Out of sync: start=%llu, size=%lu (sectors)\n", + (unsigned long long)mdev->ov_last_oos_start, + (unsigned long)mdev->ov_last_oos_size); + } + mdev->ov_last_oos_size=0; +} + + +void drbd_csum(struct drbd_conf *, struct crypto_hash *, struct bio *, void *); +/* worker callbacks */ +extern int w_req_cancel_conflict(struct drbd_conf *, struct drbd_work *, int); +extern int w_read_retry_remote(struct drbd_conf *, struct drbd_work *, int); +extern int w_e_end_data_req(struct drbd_conf *, struct drbd_work *, int); +extern int w_e_end_rsdata_req(struct drbd_conf *, struct drbd_work *, int); +extern int w_e_end_csum_rs_req(struct drbd_conf *, struct drbd_work *, int); +extern int w_e_end_ov_reply(struct drbd_conf *, struct drbd_work *, int); +extern int w_e_end_ov_req(struct drbd_conf *, struct drbd_work *, int); +extern int w_ov_finished(struct drbd_conf *, struct drbd_work *, int); +extern int w_resync_inactive(struct drbd_conf *, struct drbd_work *, int); +extern int w_resume_next_sg(struct drbd_conf *, struct drbd_work *, int); +extern int w_io_error(struct drbd_conf *, struct drbd_work *, int); +extern int w_send_write_hint(struct drbd_conf *, struct drbd_work *, int); +extern int w_make_resync_request(struct drbd_conf *, struct drbd_work *, int); +extern int w_send_dblock(struct drbd_conf *, struct drbd_work *, int); +extern int w_send_barrier(struct drbd_conf *, struct drbd_work *, int); +extern int w_send_read_req(struct drbd_conf *, struct drbd_work *, int); +extern int w_prev_work_done(struct drbd_conf *, struct drbd_work *, int); +extern int w_e_reissue(struct drbd_conf *, struct drbd_work *, int); + +extern void resync_timer_fn(unsigned long data); + +/* drbd_receiver.c */ +extern int drbd_release_ee(struct drbd_conf *mdev, struct list_head *list); +extern struct Tl_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev, + u64 id, + sector_t sector, + unsigned int data_size, + gfp_t gfp_mask) __must_hold(local); +extern void drbd_free_ee(struct drbd_conf *mdev, struct Tl_epoch_entry *e); +extern void drbd_wait_ee_list_empty(struct drbd_conf *mdev, + struct list_head *head); +extern void _drbd_wait_ee_list_empty(struct drbd_conf *mdev, + struct list_head *head); +extern void drbd_set_recv_tcq(struct drbd_conf *mdev, int tcq_enabled); +extern void _drbd_clear_done_ee(struct drbd_conf *mdev); + +/* yes, there is kernel_setsockopt, but only since 2.6.18. we don't need to + * mess with get_fs/set_fs, we know we are KERNEL_DS always. */ +static inline int drbd_setsockopt(struct socket *sock, int level, int optname, + char __user *optval, int optlen) +{ + int err; + if (level == SOL_SOCKET) + err = sock_setsockopt(sock, level, optname, optval, optlen); + else + err = sock->ops->setsockopt(sock, level, optname, optval, + optlen); + return err; +} + +static inline void drbd_tcp_cork(struct socket *sock) +{ + int __user val = 1; + (void) drbd_setsockopt(sock, SOL_TCP, TCP_CORK, + (char __user *)&val, sizeof(val)); +} + +static inline void drbd_tcp_uncork(struct socket *sock) +{ + int __user val = 0; + (void) drbd_setsockopt(sock, SOL_TCP, TCP_CORK, + (char __user *)&val, sizeof(val)); +} + +static inline void drbd_tcp_nodelay(struct socket *sock) +{ + int __user val = 1; + (void) drbd_setsockopt(sock, SOL_TCP, TCP_NODELAY, + (char __user *)&val, sizeof(val)); +} + +static inline void drbd_tcp_quickack(struct socket *sock) +{ + int __user val = 1; + (void) drbd_setsockopt(sock, SOL_TCP, TCP_QUICKACK, + (char __user *)&val, sizeof(val)); +} + +void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo); + +/* drbd_proc.c */ +extern struct proc_dir_entry *drbd_proc; +extern struct file_operations drbd_proc_fops; +extern const char *conns_to_name(enum drbd_conns s); +extern const char *roles_to_name(enum drbd_role s); + +/* drbd_actlog.c */ +extern void drbd_al_begin_io(struct drbd_conf *mdev, sector_t sector); +extern void drbd_al_complete_io(struct drbd_conf *mdev, sector_t sector); +extern void drbd_rs_complete_io(struct drbd_conf *mdev, sector_t sector); +extern int drbd_rs_begin_io(struct drbd_conf *mdev, sector_t sector); +extern int drbd_try_rs_begin_io(struct drbd_conf *mdev, sector_t sector); +extern void drbd_rs_cancel_all(struct drbd_conf *mdev); +extern int drbd_rs_del_all(struct drbd_conf *mdev); +extern void drbd_rs_failed_io(struct drbd_conf *mdev, + sector_t sector, int size); +extern int drbd_al_read_log(struct drbd_conf *mdev, struct drbd_backing_dev *); +extern void __drbd_set_in_sync(struct drbd_conf *mdev, sector_t sector, + int size, const char *file, const unsigned int line); +#define drbd_set_in_sync(mdev, sector, size) \ + __drbd_set_in_sync(mdev, sector, size, __FILE__, __LINE__) +extern void __drbd_set_out_of_sync(struct drbd_conf *mdev, sector_t sector, + int size, const char *file, const unsigned int line); +#define drbd_set_out_of_sync(mdev, sector, size) \ + __drbd_set_out_of_sync(mdev, sector, size, __FILE__, __LINE__) +extern void drbd_al_apply_to_bm(struct drbd_conf *mdev); +extern void drbd_al_to_on_disk_bm(struct drbd_conf *mdev); +extern void drbd_al_shrink(struct drbd_conf *mdev); + + +/* drbd_nl.c */ + +void drbd_nl_cleanup(void); +int __init drbd_nl_init(void); +void drbd_bcast_state(struct drbd_conf *mdev, union drbd_state_t); +void drbd_bcast_sync_progress(struct drbd_conf *mdev); +void drbd_bcast_ee(struct drbd_conf *mdev, + const char *reason, const int dgs, + const char* seen_hash, const char* calc_hash, + const struct Tl_epoch_entry* e); + +/* + * inline helper functions + *************************/ + +#define peer_mask role_mask +#define pdsk_mask disk_mask +#define susp_mask 1 +#define user_isp_mask 1 +#define aftr_isp_mask 1 + +/* drbd state debug */ +#if DRBD_DEBUG_STATE_CHANGES +#define DRBD_STATE_DEBUG_INIT_VAL(s) ({ (s).line = __LINE__; (s).func = __func__; }) +#else +#define DRBD_STATE_DEBUG_INIT_VAL(s) do { } while (0) +#endif + +#define NS(T, S) \ + ({ union drbd_state_t mask; mask.i = 0; mask.T = T##_mask; mask; }), \ + ({ union drbd_state_t val; DRBD_STATE_DEBUG_INIT_VAL(val); val.i = 0; val.T = (S); val; }) +#define NS2(T1, S1, T2, S2) \ + ({ union drbd_state_t mask; mask.i = 0; mask.T1 = T1##_mask; \ + mask.T2 = T2##_mask; mask; }), \ + ({ union drbd_state_t val; DRBD_STATE_DEBUG_INIT_VAL(val); val.i = 0; val.T1 = (S1); \ + val.T2 = (S2); val; }) +#define NS3(T1, S1, T2, S2, T3, S3) \ + ({ union drbd_state_t mask; mask.i = 0; mask.T1 = T1##_mask; \ + mask.T2 = T2##_mask; mask.T3 = T3##_mask; mask; }), \ + ({ union drbd_state_t val; DRBD_STATE_DEBUG_INIT_VAL(val); val.i = 0; val.T1 = (S1); \ + val.T2 = (S2); val.T3 = (S3); val; }) + +#define _NS(D, T, S) \ + D, ({ union drbd_state_t __ns; DRBD_STATE_DEBUG_INIT_VAL(__ns); __ns.i = D->state.i; __ns.T = (S); __ns; }) +#define _NS2(D, T1, S1, T2, S2) \ + D, ({ union drbd_state_t __ns; DRBD_STATE_DEBUG_INIT_VAL(__ns); __ns.i = D->state.i; __ns.T1 = (S1); \ + __ns.T2 = (S2); __ns; }) +#define _NS3(D, T1, S1, T2, S2, T3, S3) \ + D, ({ union drbd_state_t __ns; DRBD_STATE_DEBUG_INIT_VAL(__ns); __ns.i = D->state.i; __ns.T1 = (S1); \ + __ns.T2 = (S2); __ns.T3 = (S3); __ns; }) + +static inline void drbd_state_lock(struct drbd_conf *mdev) +{ + wait_event(mdev->misc_wait, + !test_and_set_bit(CLUSTER_ST_CHANGE, &mdev->flags)); +} + +static inline void drbd_state_unlock(struct drbd_conf *mdev) +{ + clear_bit(CLUSTER_ST_CHANGE, &mdev->flags); + wake_up(&mdev->misc_wait); +} + +static inline int drbd_request_state(struct drbd_conf *mdev, + union drbd_state_t mask, + union drbd_state_t val) +{ + return _drbd_request_state(mdev, mask, val, ChgStateVerbose + ChgOrdered); +} + +/** + * drbd_chk_io_error: Handles the on_io_error setting, should be called from + * all io completion handlers. See also drbd_io_error(). + */ +static inline void __drbd_chk_io_error(struct drbd_conf *mdev, int forcedetach) +{ + switch (mdev->bc->dc.on_io_error) { + case PassOn: /* FIXME would this be better named "Ignore"? */ + if (!forcedetach) { + if (printk_ratelimit()) + ERR("Local IO failed. Passing error on...\n"); + break; + } + /* NOTE fall through to detach case if forcedetach set */ + case Detach: + case CallIOEHelper: + if (mdev->state.disk > Failed) { + _drbd_set_state(_NS(mdev, disk, Failed), ChgStateHard, NULL); + ERR("Local IO failed. Detaching...\n"); + } + break; + } +} + +static inline void drbd_chk_io_error(struct drbd_conf *mdev, + int error, int forcedetach) +{ + if (error) { + unsigned long flags; + spin_lock_irqsave(&mdev->req_lock, flags); + __drbd_chk_io_error(mdev, forcedetach); + spin_unlock_irqrestore(&mdev->req_lock, flags); + } +} + +static inline int semaphore_is_locked(struct semaphore *s) +{ + if (!down_trylock(s)) { + up(s); + return 0; + } + return 1; +} + +/* Returns the first sector number of our meta data, + * which, for internal meta data, happens to be the maximum capacity + * we could agree upon with our peer + */ +static inline sector_t drbd_md_first_sector(struct drbd_backing_dev *bdev) +{ + switch (bdev->dc.meta_dev_idx) { + case DRBD_MD_INDEX_INTERNAL: + case DRBD_MD_INDEX_FLEX_INT: + return bdev->md.md_offset + bdev->md.bm_offset; + case DRBD_MD_INDEX_FLEX_EXT: + default: + return bdev->md.md_offset; + } +} + +/* returns the last sector number of our meta data, + * to be able to catch out of band md access */ +static inline sector_t drbd_md_last_sector(struct drbd_backing_dev *bdev) +{ + switch (bdev->dc.meta_dev_idx) { + case DRBD_MD_INDEX_INTERNAL: + case DRBD_MD_INDEX_FLEX_INT: + return bdev->md.md_offset + MD_AL_OFFSET - 1; + case DRBD_MD_INDEX_FLEX_EXT: + default: + return bdev->md.md_offset + bdev->md.md_size_sect; + } +} + +/* returns the capacity we announce to out peer. + * we clip ourselves at the various MAX_SECTORS, because if we don't, + * current implementation will oops sooner or later */ +static inline sector_t drbd_get_max_capacity(struct drbd_backing_dev *bdev) +{ + sector_t s; + switch (bdev->dc.meta_dev_idx) { + case DRBD_MD_INDEX_INTERNAL: + case DRBD_MD_INDEX_FLEX_INT: + s = drbd_get_capacity(bdev->backing_bdev) + ? min_t(sector_t, DRBD_MAX_SECTORS_FLEX, + drbd_md_first_sector(bdev)) + : 0; + break; + case DRBD_MD_INDEX_FLEX_EXT: + s = min_t(sector_t, DRBD_MAX_SECTORS_FLEX, + drbd_get_capacity(bdev->backing_bdev)); + /* clip at maximum size the meta device can support */ + s = min_t(sector_t, s, + BM_EXT_TO_SECT(bdev->md.md_size_sect + - bdev->md.bm_offset)); + break; + default: + s = min_t(sector_t, DRBD_MAX_SECTORS, + drbd_get_capacity(bdev->backing_bdev)); + } + return s; +} + +/* returns the sector number of our meta data 'super' block */ +static inline sector_t drbd_md_ss__(struct drbd_conf *mdev, + struct drbd_backing_dev *bdev) +{ + switch (bdev->dc.meta_dev_idx) { + default: /* external, some index */ + return MD_RESERVED_SECT * bdev->dc.meta_dev_idx; + case DRBD_MD_INDEX_INTERNAL: + /* with drbd08, internal meta data is always "flexible" */ + case DRBD_MD_INDEX_FLEX_INT: + /* sizeof(struct md_on_disk_07) == 4k + * position: last 4k aligned block of 4k size */ + if (!bdev->backing_bdev) { + if (DRBD_ratelimit(5*HZ, 5)) { + ERR("bdev->backing_bdev==NULL\n"); + dump_stack(); + } + return 0; + } + return (drbd_get_capacity(bdev->backing_bdev) & ~7ULL) + - MD_AL_OFFSET; + case DRBD_MD_INDEX_FLEX_EXT: + return 0; + } +} + +static inline void +_drbd_queue_work(struct drbd_work_queue *q, struct drbd_work *w) +{ + list_add_tail(&w->list, &q->q); + up(&q->s); +} + +static inline void +drbd_queue_work_front(struct drbd_work_queue *q, struct drbd_work *w) +{ + unsigned long flags; + spin_lock_irqsave(&q->q_lock, flags); + list_add(&w->list, &q->q); + up(&q->s); /* within the spinlock, + see comment near end of drbd_worker() */ + spin_unlock_irqrestore(&q->q_lock, flags); +} + +static inline void +drbd_queue_work(struct drbd_work_queue *q, struct drbd_work *w) +{ + unsigned long flags; + spin_lock_irqsave(&q->q_lock, flags); + list_add_tail(&w->list, &q->q); + up(&q->s); /* within the spinlock, + see comment near end of drbd_worker() */ + spin_unlock_irqrestore(&q->q_lock, flags); +} + +static inline void wake_asender(struct drbd_conf *mdev) +{ + if (test_bit(SIGNAL_ASENDER, &mdev->flags)) + force_sig(DRBD_SIG, mdev->asender.task); +} + +static inline void request_ping(struct drbd_conf *mdev) +{ + set_bit(SEND_PING, &mdev->flags); + wake_asender(mdev); +} + +static inline int drbd_send_short_cmd(struct drbd_conf *mdev, + enum Drbd_Packet_Cmd cmd) +{ + struct Drbd_Header h; + return drbd_send_cmd(mdev, USE_DATA_SOCKET, cmd, &h, sizeof(h)); +} + +static inline int drbd_send_ping(struct drbd_conf *mdev) +{ + struct Drbd_Header h; + return drbd_send_cmd(mdev, USE_META_SOCKET, Ping, &h, sizeof(h)); +} + +static inline int drbd_send_ping_ack(struct drbd_conf *mdev) +{ + struct Drbd_Header h; + return drbd_send_cmd(mdev, USE_META_SOCKET, PingAck, &h, sizeof(h)); +} + +static inline void drbd_thread_stop(struct Drbd_thread *thi) +{ + _drbd_thread_stop(thi, FALSE, TRUE); +} + +static inline void drbd_thread_stop_nowait(struct Drbd_thread *thi) +{ + _drbd_thread_stop(thi, FALSE, FALSE); +} + +static inline void drbd_thread_restart_nowait(struct Drbd_thread *thi) +{ + _drbd_thread_stop(thi, TRUE, FALSE); +} + +/* counts how many answer packets packets we expect from our peer, + * for either explicit application requests, + * or implicit barrier packets as necessary. + * increased: + * w_send_barrier + * _req_mod(req, queue_for_net_write or queue_for_net_read); + * it is much easier and equally valid to count what we queue for the + * worker, even before it actually was queued or send. + * (drbd_make_request_common; recovery path on read io-error) + * decreased: + * got_BarrierAck (respective tl_clear, tl_clear_barrier) + * _req_mod(req, data_received) + * [from receive_DataReply] + * _req_mod(req, write_acked_by_peer or recv_acked_by_peer or neg_acked) + * [from got_BlockAck (WriteAck, RecvAck)] + * FIXME + * for some reason it is NOT decreased in got_NegAck, + * but in the resulting cleanup code from report_params. + * we should try to remember the reason for that... + * _req_mod(req, send_failed or send_canceled) + * _req_mod(req, connection_lost_while_pending) + * [from tl_clear_barrier] + */ +static inline void inc_ap_pending(struct drbd_conf *mdev) +{ + atomic_inc(&mdev->ap_pending_cnt); +} + +#define ERR_IF_CNT_IS_NEGATIVE(which) \ + if (atomic_read(&mdev->which) < 0) \ + ERR("in %s:%d: " #which " = %d < 0 !\n", \ + __func__ , __LINE__ , \ + atomic_read(&mdev->which)) + +#define dec_ap_pending(mdev) do { \ + typecheck(struct drbd_conf *, mdev); \ + if (atomic_dec_and_test(&mdev->ap_pending_cnt)) \ + wake_up(&mdev->misc_wait); \ + ERR_IF_CNT_IS_NEGATIVE(ap_pending_cnt); } while (0) + +/* counts how many resync-related answers we still expect from the peer + * increase decrease + * SyncTarget sends RSDataRequest (and expects RSDataReply) + * SyncSource sends RSDataReply (and expects WriteAck whith ID_SYNCER) + * (or NegAck with ID_SYNCER) + */ +static inline void inc_rs_pending(struct drbd_conf *mdev) +{ + atomic_inc(&mdev->rs_pending_cnt); +} + +#define dec_rs_pending(mdev) do { \ + typecheck(struct drbd_conf *, mdev); \ + atomic_dec(&mdev->rs_pending_cnt); \ + ERR_IF_CNT_IS_NEGATIVE(rs_pending_cnt); } while (0) + +/* counts how many answers we still need to send to the peer. + * increased on + * receive_Data unless protocol A; + * we need to send a RecvAck (proto B) + * or WriteAck (proto C) + * receive_RSDataReply (recv_resync_read) we need to send a WriteAck + * receive_DataRequest (receive_RSDataRequest) we need to send back Data + * receive_Barrier_* we need to send a BarrierAck + */ +static inline void inc_unacked(struct drbd_conf *mdev) +{ + atomic_inc(&mdev->unacked_cnt); +} + +#define dec_unacked(mdev) do { \ + typecheck(struct drbd_conf *, mdev); \ + atomic_dec(&mdev->unacked_cnt); \ + ERR_IF_CNT_IS_NEGATIVE(unacked_cnt); } while (0) + +#define sub_unacked(mdev, n) do { \ + typecheck(struct drbd_conf *, mdev); \ + atomic_sub(n, &mdev->unacked_cnt); \ + ERR_IF_CNT_IS_NEGATIVE(unacked_cnt); } while (0) + + +static inline void dec_net(struct drbd_conf *mdev) +{ + if (atomic_dec_and_test(&mdev->net_cnt)) + wake_up(&mdev->misc_wait); +} + +/** + * inc_net: Returns TRUE when it is ok to access mdev->net_conf. You + * should call dec_net() when finished looking at mdev->net_conf. + */ +static inline int inc_net(struct drbd_conf *mdev) +{ + int have_net_conf; + + atomic_inc(&mdev->net_cnt); + have_net_conf = mdev->state.conn >= Unconnected; + if (!have_net_conf) + dec_net(mdev); + return have_net_conf; +} + +/** + * inc_local: Returns TRUE when local IO is possible. If it returns + * TRUE you should call dec_local() after IO is completed. + */ +#define inc_local_if_state(M,MINS) __cond_lock(local, _inc_local_if_state(M,MINS)) +#define inc_local(M) __cond_lock(local, _inc_local_if_state(M,Inconsistent)) + +static inline void dec_local(struct drbd_conf *mdev) +{ + __release(local); + if (atomic_dec_and_test(&mdev->local_cnt)) + wake_up(&mdev->misc_wait); + D_ASSERT(atomic_read(&mdev->local_cnt) >= 0); +} + +#ifndef __CHECKER__ +static inline int _inc_local_if_state(struct drbd_conf *mdev, enum drbd_disk_state mins) +{ + int io_allowed; + + atomic_inc(&mdev->local_cnt); + io_allowed = (mdev->state.disk >= mins); + if (!io_allowed) + dec_local(mdev); + return io_allowed; +} +#else +extern int _inc_local_if_state(struct drbd_conf *mdev, enum drbd_disk_state mins); +#endif + +/* you must have an "inc_local" reference */ +static inline void drbd_get_syncer_progress(struct drbd_conf *mdev, + unsigned long *bits_left, unsigned int *per_mil_done) +{ + /* + * this is to break it at compile time when we change that + * (we may feel 4TB maximum storage per drbd is not enough) + */ + typecheck(unsigned long, mdev->rs_total); + + /* note: both rs_total and rs_left are in bits, i.e. in + * units of BM_BLOCK_SIZE. + * for the percentage, we don't care. */ + + *bits_left = drbd_bm_total_weight(mdev) - mdev->rs_failed; + /* >> 10 to prevent overflow, + * +1 to prevent division by zero */ + if (*bits_left > mdev->rs_total) { + /* doh. maybe a logic bug somewhere. + * may also be just a race condition + * between this and a disconnect during sync. + * for now, just prevent in-kernel buffer overflow. + */ + smp_rmb(); + drbd_WARN("cs:%s rs_left=%lu > rs_total=%lu (rs_failed %lu)\n", + conns_to_name(mdev->state.conn), + *bits_left, mdev->rs_total, mdev->rs_failed); + *per_mil_done = 0; + } else { + /* make sure the calculation happens in long context */ + unsigned long tmp = 1000UL - + (*bits_left >> 10)*1000UL + / ((mdev->rs_total >> 10) + 1UL); + *per_mil_done = tmp; + } +} + + +/* this throttles on-the-fly application requests + * according to max_buffers settings; + * maybe re-implement using semaphores? */ +static inline int drbd_get_max_buffers(struct drbd_conf *mdev) +{ + int mxb = 1000000; /* arbitrary limit on open requests */ + if (inc_net(mdev)) { + mxb = mdev->net_conf->max_buffers; + dec_net(mdev); + } + return mxb; +} + +static inline int drbd_state_is_stable(union drbd_state_t s) +{ + + /* DO NOT add a default clause, we want the compiler to warn us + * for any newly introduced state we may have forgotten to add here */ + + switch ((enum drbd_conns)s.conn) { + /* new io only accepted when there is no connection, ... */ + case StandAlone: + case WFConnection: + /* ... or there is a well established connection. */ + case Connected: + case SyncSource: + case SyncTarget: + case VerifyS: + case VerifyT: + case PausedSyncS: + case PausedSyncT: + /* maybe stable, look at the disk state */ + break; + + /* no new io accepted during tansitional states + * like handshake or teardown */ + case Disconnecting: + case Unconnected: + case Timeout: + case BrokenPipe: + case NetworkFailure: + case ProtocolError: + case TearDown: + case WFReportParams: + case StartingSyncS: + case StartingSyncT: + case WFBitMapS: + case WFBitMapT: + case WFSyncUUID: + case conn_mask: + /* not "stable" */ + return 0; + } + + switch ((enum drbd_disk_state)s.disk) { + case Diskless: + case Inconsistent: + case Outdated: + case Consistent: + case UpToDate: + /* disk state is stable as well. */ + break; + + /* no new io accepted during tansitional states */ + case Attaching: + case Failed: + case Negotiating: + case DUnknown: + case disk_mask: + /* not "stable" */ + return 0; + } + + return 1; +} + +static inline int __inc_ap_bio_cond(struct drbd_conf *mdev) +{ + int mxb = drbd_get_max_buffers(mdev); + + if (mdev->state.susp) + return 0; + if (test_bit(SUSPEND_IO, &mdev->flags)) + return 0; + + /* to avoid potential deadlock or bitmap corruption, + * in various places, we only allow new application io + * to start during "stable" states. */ + + /* no new io accepted when attaching or detaching the disk */ + if (!drbd_state_is_stable(mdev->state)) + return 0; + + /* since some older kernels don't have atomic_add_unless, + * and we are within the spinlock anyways, we have this workaround. */ + if (atomic_read(&mdev->ap_bio_cnt) > mxb) + return 0; + if (test_bit(BITMAP_IO, &mdev->flags)) + return 0; + return 1; +} + +/* I'd like to use wait_event_lock_irq, + * but I'm not sure when it got introduced, + * and not sure when it has 3 or 4 arguments */ +static inline void inc_ap_bio(struct drbd_conf *mdev, int one_or_two) +{ + /* compare with after_state_ch, + * os.conn != WFBitMapS && ns.conn == WFBitMapS */ + DEFINE_WAIT(wait); + + /* we wait here + * as long as the device is suspended + * until the bitmap is no longer on the fly during connection + * handshake as long as we would exeed the max_buffer limit. + * + * to avoid races with the reconnect code, + * we need to atomic_inc within the spinlock. */ + + spin_lock_irq(&mdev->req_lock); + while (!__inc_ap_bio_cond(mdev)) { + prepare_to_wait(&mdev->misc_wait, &wait, TASK_UNINTERRUPTIBLE); + spin_unlock_irq(&mdev->req_lock); + schedule(); + finish_wait(&mdev->misc_wait, &wait); + spin_lock_irq(&mdev->req_lock); + } + atomic_add(one_or_two, &mdev->ap_bio_cnt); + spin_unlock_irq(&mdev->req_lock); +} + +static inline void dec_ap_bio(struct drbd_conf *mdev) +{ + int mxb = drbd_get_max_buffers(mdev); + int ap_bio = atomic_dec_return(&mdev->ap_bio_cnt); + + D_ASSERT(ap_bio >= 0); + /* this currently does wake_up for every dec_ap_bio! + * maybe rather introduce some type of hysteresis? + * e.g. (ap_bio == mxb/2 || ap_bio == 0) ? */ + if (ap_bio < mxb) + wake_up(&mdev->misc_wait); + if (ap_bio == 0 && test_bit(BITMAP_IO, &mdev->flags)) { + if (!test_and_set_bit(BITMAP_IO_QUEUED, &mdev->flags)) + drbd_queue_work(&mdev->data.work, &mdev->bm_io_work.w); + } +} + +static inline void drbd_set_ed_uuid(struct drbd_conf *mdev, u64 val) +{ + mdev->ed_uuid = val; + + MTRACE(TraceTypeUuid, TraceLvlMetrics, + INFO(" exposed data uuid now %016llX\n", + (unsigned long long)val); + ); +} + +static inline int seq_cmp(u32 a, u32 b) +{ + /* we assume wrap around at 32bit. + * for wrap around at 24bit (old atomic_t), + * we'd have to + * a <<= 8; b <<= 8; + */ + return (s32)(a) - (s32)(b); +} +#define seq_lt(a, b) (seq_cmp((a), (b)) < 0) +#define seq_gt(a, b) (seq_cmp((a), (b)) > 0) +#define seq_ge(a, b) (seq_cmp((a), (b)) >= 0) +#define seq_le(a, b) (seq_cmp((a), (b)) <= 0) +/* CAUTION: please no side effects in arguments! */ +#define seq_max(a, b) ((u32)(seq_gt((a), (b)) ? (a) : (b))) + +static inline void update_peer_seq(struct drbd_conf *mdev, unsigned int new_seq) +{ + unsigned int m; + spin_lock(&mdev->peer_seq_lock); + m = seq_max(mdev->peer_seq, new_seq); + mdev->peer_seq = m; + spin_unlock(&mdev->peer_seq_lock); + if (m == new_seq) + wake_up(&mdev->seq_wait); +} + +static inline int drbd_queue_order_type(struct drbd_conf *mdev) +{ + /* sorry, we currently have no working implementation + * of distributed TCQ stuff */ +#ifndef QUEUE_ORDERED_NONE +#define QUEUE_ORDERED_NONE 0 +#endif + return QUEUE_ORDERED_NONE; +} + +/* + * FIXME investigate what makes most sense: + * a) blk_run_queue(q); + * + * b) struct backing_dev_info *bdi; + * b1) bdi = &q->backing_dev_info; + * b2) bdi = mdev->bc->backing_bdev->bd_inode->i_mapping->backing_dev_info; + * blk_run_backing_dev(bdi,NULL); + * + * c) generic_unplug(q) ? __generic_unplug(q) ? + * + * d) q->unplug_fn(q), which is what all the drivers/md/ stuff uses... + * + */ +static inline void drbd_blk_run_queue(struct request_queue *q) +{ + if (q && q->unplug_fn) + q->unplug_fn(q); +} + +static inline void drbd_kick_lo(struct drbd_conf *mdev) +{ + if (inc_local(mdev)) { + drbd_blk_run_queue(bdev_get_queue(mdev->bc->backing_bdev)); + dec_local(mdev); + } +} + +static inline void drbd_md_flush(struct drbd_conf *mdev) +{ + int r; + + if (test_bit(MD_NO_BARRIER, &mdev->flags)) + return; + + r = blkdev_issue_flush(mdev->bc->md_bdev, NULL); + if (r) { + set_bit(MD_NO_BARRIER, &mdev->flags); + ERR("meta data flush failed with status %d, disabling md-flushes\n", r); + } +} + +#endif --- linux-2.6.28.orig/ubuntu/drbd/drbd_proc.c +++ linux-2.6.28/ubuntu/drbd/drbd_proc.c @@ -0,0 +1,272 @@ +/* +-*- linux-c -*- + drbd_proc.c + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2001-2008, LINBIT Information Technologies GmbH. + Copyright (C) 1999-2008, Philipp Reisner . + Copyright (C) 2002-2008, Lars Ellenberg . + + drbd is free software; you can redistribute 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. + + drbd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "drbd_int.h" +#include "lru_cache.h" /* for lc_sprintf_stats */ + +STATIC int drbd_proc_open(struct inode *inode, struct file *file); + + +struct proc_dir_entry *drbd_proc; +struct file_operations drbd_proc_fops = { + .owner = THIS_MODULE, + .open = drbd_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + + +/*lge + * progress bars shamelessly adapted from driver/md/md.c + * output looks like + * [=====>..............] 33.5% (23456/123456) + * finish: 2:20:20 speed: 6,345 (6,456) K/sec + */ +STATIC void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq) +{ + unsigned long db, dt, dbdt, rt, rs_left; + unsigned int res; + int i, x, y; + + drbd_get_syncer_progress(mdev, &rs_left, &res); + + x = res/50; + y = 20-x; + seq_printf(seq, "\t["); + for (i = 1; i < x; i++) + seq_printf(seq, "="); + seq_printf(seq, ">"); + for (i = 0; i < y; i++) + seq_printf(seq, "."); + seq_printf(seq, "] "); + + seq_printf(seq, "sync'ed:%3u.%u%% ", res / 10, res % 10); + /* if more than 1 GB display in MB */ + if (mdev->rs_total > 0x100000L) + seq_printf(seq, "(%lu/%lu)M\n\t", + (unsigned long) Bit2KB(rs_left) >> 10, + (unsigned long) Bit2KB(mdev->rs_total) >> 10); + else + seq_printf(seq, "(%lu/%lu)K\n\t", + (unsigned long) Bit2KB(rs_left), + (unsigned long) Bit2KB(mdev->rs_total)); + + /* see drivers/md/md.c + * We do not want to overflow, so the order of operands and + * the * 100 / 100 trick are important. We do a +1 to be + * safe against division by zero. We only estimate anyway. + * + * dt: time from mark until now + * db: blocks written from mark until now + * rt: remaining time + */ + dt = (jiffies - mdev->rs_mark_time) / HZ; + + if (dt > 20) { + /* if we made no update to rs_mark_time for too long, + * we are stalled. show that. */ + seq_printf(seq, "stalled\n"); + return; + } + + if (!dt) + dt++; + db = mdev->rs_mark_left - rs_left; + rt = (dt * (rs_left / (db/100+1)))/100; /* seconds */ + + seq_printf(seq, "finish: %lu:%02lu:%02lu", + rt / 3600, (rt % 3600) / 60, rt % 60); + + /* current speed average over (SYNC_MARKS * SYNC_MARK_STEP) jiffies */ + dbdt = Bit2KB(db/dt); + if (dbdt > 1000) + seq_printf(seq, " speed: %ld,%03ld", + dbdt/1000, dbdt % 1000); + else + seq_printf(seq, " speed: %ld", dbdt); + + /* mean speed since syncer started + * we do account for PausedSync periods */ + dt = (jiffies - mdev->rs_start - mdev->rs_paused) / HZ; + if (dt <= 0) + dt = 1; + db = mdev->rs_total - rs_left; + dbdt = Bit2KB(db/dt); + if (dbdt > 1000) + seq_printf(seq, " (%ld,%03ld)", + dbdt/1000, dbdt % 1000); + else + seq_printf(seq, " (%ld)", dbdt); + + seq_printf(seq, " K/sec\n"); +} + +#ifdef ENABLE_DYNAMIC_TRACE +STATIC void resync_dump_detail(struct seq_file *seq, struct lc_element *e) +{ + struct bm_extent *bme = (struct bm_extent *)e; + + seq_printf(seq, "%5d %s %s\n", bme->rs_left, + bme->flags & BME_NO_WRITES ? "NO_WRITES" : "---------", + bme->flags & BME_LOCKED ? "LOCKED" : "------" + ); +} +#endif + +STATIC int drbd_seq_show(struct seq_file *seq, void *v) +{ + int i, hole = 0; + const char *sn; + struct drbd_conf *mdev; + + static char write_ordering_chars[] = { + [WO_none] = 'n', + [WO_drain_io] = 'd', + [WO_bdev_flush] = 'f', + [WO_bio_barrier] = 'b', + }; + + seq_printf(seq, "version: " REL_VERSION " (api:%d/proto:%d-%d)\n%s\n", + API_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX, drbd_buildtag()); + + /* + cs .. connection state + ro .. node role (local/remote) + ds .. disk state (local/remote) + protocol + various flags + ns .. network send + nr .. network receive + dw .. disk write + dr .. disk read + al .. activity log write count + bm .. bitmap update write count + pe .. pending (waiting for ack or data reply) + ua .. unack'd (still need to send ack or data reply) + ap .. application requests accepted, but not yet completed + ep .. number of epochs currently "on the fly", BarrierAck pending + wo .. write ordering mode currently in use + oos .. known out-of-sync kB + */ + + for (i = 0; i < minor_count; i++) { + mdev = minor_to_mdev(i); + if (!mdev) { + hole = 1; + continue; + } + if (hole) { + hole = 0; + seq_printf(seq, "\n"); + } + + sn = conns_to_name(mdev->state.conn); + + if (mdev->state.conn == StandAlone && + mdev->state.disk == Diskless && + mdev->state.role == Secondary) { + seq_printf(seq, "%2d: cs:Unconfigured\n", i); + } else { + seq_printf(seq, + "%2d: cs:%s ro:%s/%s ds:%s/%s %c %c%c%c%c\n" + " ns:%u nr:%u dw:%u dr:%u al:%u bm:%u " + "lo:%d pe:%d ua:%d ap:%d ep:%d wo:%c", + i, sn, + roles_to_name(mdev->state.role), + roles_to_name(mdev->state.peer), + disks_to_name(mdev->state.disk), + disks_to_name(mdev->state.pdsk), + (mdev->net_conf == NULL ? ' ' : + (mdev->net_conf->wire_protocol - DRBD_PROT_A+'A')), + mdev->state.susp ? 's' : 'r', + mdev->state.aftr_isp ? 'a' : '-', + mdev->state.peer_isp ? 'p' : '-', + mdev->state.user_isp ? 'u' : '-', + mdev->send_cnt/2, + mdev->recv_cnt/2, + mdev->writ_cnt/2, + mdev->read_cnt/2, + mdev->al_writ_cnt, + mdev->bm_writ_cnt, + atomic_read(&mdev->local_cnt), + atomic_read(&mdev->ap_pending_cnt) + + atomic_read(&mdev->rs_pending_cnt), + atomic_read(&mdev->unacked_cnt), + atomic_read(&mdev->ap_bio_cnt), + mdev->epochs, + write_ordering_chars[mdev->write_ordering] + ); + seq_printf(seq, " oos:%lu\n", + Bit2KB(drbd_bm_total_weight(mdev))); + } + if (mdev->state.conn == SyncSource || + mdev->state.conn == SyncTarget) + drbd_syncer_progress(mdev, seq); + + if (mdev->state.conn == VerifyS || mdev->state.conn == VerifyT) + seq_printf(seq,"\t%3d%% %lu/%lu\n", + (int)((mdev->rs_total-mdev->ov_left) / + (mdev->rs_total/100+1)), + mdev->rs_total - mdev->ov_left, + mdev->rs_total); + +#ifdef ENABLE_DYNAMIC_TRACE + if (proc_details >= 1 && inc_local_if_state(mdev, Failed)) { + lc_printf_stats(seq, mdev->resync); + lc_printf_stats(seq, mdev->act_log); + dec_local(mdev); + } + + if (proc_details >= 2) { + if (mdev->resync) { + lc_dump(mdev->resync, seq, "rs_left", + resync_dump_detail); + } + } +#endif + } + + return 0; +} + +STATIC int drbd_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, drbd_seq_show, PDE(inode)->data); +} + +/* PROC FS stuff end */ --- linux-2.6.28.orig/ubuntu/drbd/drbd_strings.c +++ linux-2.6.28/ubuntu/drbd/drbd_strings.c @@ -0,0 +1,116 @@ +/* + drbd.h + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2003-2008, LINBIT Information Technologies GmbH. + Copyright (C) 2003-2008, Philipp Reisner . + Copyright (C) 2003-2008, Lars Ellenberg . + + drbd is free software; you can redistribute 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. + + drbd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include + +static const char *drbd_conn_s_names[] = { + [StandAlone] = "StandAlone", + [Disconnecting] = "Disconnecting", + [Unconnected] = "Unconnected", + [Timeout] = "Timeout", + [BrokenPipe] = "BrokenPipe", + [NetworkFailure] = "NetworkFailure", + [ProtocolError] = "ProtocolError", + [WFConnection] = "WFConnection", + [WFReportParams] = "WFReportParams", + [TearDown] = "TearDown", + [Connected] = "Connected", + [StartingSyncS] = "StartingSyncS", + [StartingSyncT] = "StartingSyncT", + [WFBitMapS] = "WFBitMapS", + [WFBitMapT] = "WFBitMapT", + [WFSyncUUID] = "WFSyncUUID", + [SyncSource] = "SyncSource", + [SyncTarget] = "SyncTarget", + [VerifyS] = "VerifyS", + [VerifyT] = "VerifyT", + [PausedSyncS] = "PausedSyncS", + [PausedSyncT] = "PausedSyncT" +}; + +static const char *drbd_role_s_names[] = { + [Primary] = "Primary", + [Secondary] = "Secondary", + [Unknown] = "Unknown" +}; + +static const char *drbd_disk_s_names[] = { + [Diskless] = "Diskless", + [Attaching] = "Attaching", + [Failed] = "Failed", + [Negotiating] = "Negotiating", + [Inconsistent] = "Inconsistent", + [Outdated] = "Outdated", + [DUnknown] = "DUnknown", + [Consistent] = "Consistent", + [UpToDate] = "UpToDate", +}; + +static const char *drbd_state_sw_errors[] = { + [-SS_TwoPrimaries] = "Multiple primaries not allowed by config", + [-SS_NoUpToDateDisk] = + "Refusing to be Primary without at least one UpToDate disk", + [-SS_BothInconsistent] = "Refusing to be inconsistent on both nodes", + [-SS_SyncingDiskless] = "Refusing to be syncing and diskless", + [-SS_ConnectedOutdates] = "Refusing to be Outdated while Connected", + [-SS_PrimaryNOP] = "Refusing to be Primary while peer is not outdated", + [-SS_ResyncRunning] = "Can not start OV/resync since it is already active", + [-SS_AlreadyStandAlone] = "Can not disconnect a StandAlone device", + [-SS_CW_FailedByPeer] = "State changed was refused by peer node", + [-SS_IsDiskLess] = + "Device is diskless, the requesed operation requires a disk", + [-SS_DeviceInUse] = "Device is held open by someone", + [-SS_NoNetConfig] = "Have no net/connection configuration", + [-SS_NoVerifyAlg] = "Need a verify algorithm to start online verify", + [-SS_NeedConnection] = "Need a connection to start verify or resync", + [-SS_NotSupported] = "Peer does not support protocol", + [-SS_LowerThanOutdated] = "Disk state is lower than outdated", + [-SS_InTransientState] = "In transient state, retry after next state change", + [-SS_ConcurrentStChg] = "Concurrent state changes detected and aborted", +}; + +const char *conns_to_name(enum drbd_conns s) +{ + /* enums are unsigned... */ + return s > PausedSyncT ? "TOO_LARGE" : drbd_conn_s_names[s]; +} + +const char *roles_to_name(enum drbd_role s) +{ + return s > Secondary ? "TOO_LARGE" : drbd_role_s_names[s]; +} + +const char *disks_to_name(enum drbd_disk_state s) +{ + return s > UpToDate ? "TOO_LARGE" : drbd_disk_s_names[s]; +} + +const char *set_st_err_name(enum set_st_err err) +{ + return err <= SS_AfterLastError ? "TOO_SMALL" : + err > SS_TwoPrimaries ? "TOO_LARGE" + : drbd_state_sw_errors[-err]; +} --- linux-2.6.28.orig/ubuntu/drbd/drbd_receiver.c +++ linux-2.6.28/ubuntu/drbd/drbd_receiver.c @@ -0,0 +1,4231 @@ +/* +-*- linux-c -*- + drbd_receiver.c + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2001-2008, LINBIT Information Technologies GmbH. + Copyright (C) 1999-2008, Philipp Reisner . + Copyright (C) 2002-2008, Lars Ellenberg . + + drbd is free software; you can redistribute 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. + + drbd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define __KERNEL_SYSCALLS__ +#include +#include +#include +#ifdef HAVE_LINUX_SCATTERLIST_H +/* 2.6.11 (suse 9.3, fc4) does not include requisites + * from linux/scatterlist.h :( */ +#include +#include +#include +#include +#endif +#include +#include "drbd_int.h" +#include "drbd_req.h" + +struct flush_work { + struct drbd_work w; + struct drbd_epoch *epoch; +}; + +enum epoch_event { + EV_put, + EV_got_barrier_nr, + EV_barrier_done, + EV_became_last, + EV_cleanup = 32, /* used as flag */ +}; + +enum finish_epoch { + FE_still_live, + FE_destroyed, + FE_recycled, +}; + +STATIC enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *, struct drbd_epoch *, enum epoch_event); +STATIC int e_end_block(struct drbd_conf *, struct drbd_work *, int); +static inline struct drbd_epoch *previous_epoch(struct drbd_conf *mdev, struct drbd_epoch *epoch) +{ + struct drbd_epoch *prev; + spin_lock(&mdev->epoch_lock); + prev = list_entry(epoch->list.prev, struct drbd_epoch, list); + if (prev == epoch || prev == mdev->current_epoch) + prev = NULL; + spin_unlock(&mdev->epoch_lock); + return prev; +} + +#ifdef DBG_ASSERTS +void drbd_assert_breakpoint(struct drbd_conf *mdev, char *exp, + char *file, int line) +{ + ERR("ASSERT( %s ) in %s:%d\n", exp, file, line); +} +#endif + +#define GFP_TRY (__GFP_HIGHMEM | __GFP_NOWARN) + +/** + * drbd_bp_alloc: Returns a page. Fails only if a signal comes in. + */ +STATIC struct page *drbd_pp_alloc(struct drbd_conf *mdev, gfp_t gfp_mask) +{ + unsigned long flags = 0; + struct page *page; + DEFINE_WAIT(wait); + + /* FIXME Add some usefull watermark again to "kick_lo", if pages get + * used up too quickly. The watermark that had been in place here did + * not make sense. + */ + + spin_lock_irqsave(&drbd_pp_lock, flags); + /* This lock needs to lock out irq because we might call drbd_pp_free() + from IRQ context. + FIXME but why irq _save_ ? + this is only called from drbd_alloc_ee, + and that is strictly process context! */ + page = drbd_pp_pool; + if (page) { + drbd_pp_pool = (struct page *)page_private(page); + set_page_private(page, 0); /* just to be polite */ + drbd_pp_vacant--; + } + spin_unlock_irqrestore(&drbd_pp_lock, flags); + if (page) + goto got_page; + + drbd_kick_lo(mdev); + + for (;;) { + prepare_to_wait(&drbd_pp_wait, &wait, TASK_INTERRUPTIBLE); + + /* try the pool again, maybe the drbd_kick_lo set some free */ + spin_lock_irqsave(&drbd_pp_lock, flags); + page = drbd_pp_pool; + if (page) { + drbd_pp_pool = (struct page *)page_private(page); + drbd_pp_vacant--; + } + spin_unlock_irqrestore(&drbd_pp_lock, flags); + + if (page) + break; + + /* hm. pool was empty. try to allocate from kernel. + * don't wait, if none is available, though. + */ + if (atomic_read(&mdev->pp_in_use) + < mdev->net_conf->max_buffers) { + page = alloc_page(GFP_TRY); + if (page) + break; + } + + /* doh. still no page. + * either used up the configured maximum number, + * or we are low on memory. + * wait for someone to return a page into the pool. + * unless, of course, someone signalled us. + */ + if (signal_pending(current)) { + drbd_WARN("drbd_pp_alloc interrupted!\n"); + finish_wait(&drbd_pp_wait, &wait); + return NULL; + } + drbd_kick_lo(mdev); + if (!(gfp_mask & __GFP_WAIT)) { + finish_wait(&drbd_pp_wait, &wait); + return NULL; + } + schedule(); + } + finish_wait(&drbd_pp_wait, &wait); + + got_page: + atomic_inc(&mdev->pp_in_use); + return page; +} + +STATIC void drbd_pp_free(struct drbd_conf *mdev, struct page *page) +{ + unsigned long flags = 0; + int free_it; + + spin_lock_irqsave(&drbd_pp_lock, flags); + if (drbd_pp_vacant > (DRBD_MAX_SEGMENT_SIZE/PAGE_SIZE)*minor_count) { + free_it = 1; + } else { + set_page_private(page, (unsigned long)drbd_pp_pool); + drbd_pp_pool = page; + drbd_pp_vacant++; + free_it = 0; + } + spin_unlock_irqrestore(&drbd_pp_lock, flags); + + atomic_dec(&mdev->pp_in_use); + + if (free_it) + __free_page(page); + + /* + * FIXME + * typically there are no waiters. + * we should try to avoid any unnecessary call to wake_up. + */ + wake_up(&drbd_pp_wait); +} + +/* +You need to hold the req_lock: + drbd_free_ee() + _drbd_wait_ee_list_empty() + +You must not have the req_lock: + drbd_alloc_ee() + drbd_init_ee() + drbd_release_ee() + drbd_ee_fix_bhs() + drbd_process_done_ee() + drbd_clear_done_ee() + drbd_wait_ee_list_empty() +*/ + +struct Tl_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev, + u64 id, + sector_t sector, + unsigned int data_size, + gfp_t gfp_mask) __must_hold(local) +{ + struct request_queue *q; + struct Tl_epoch_entry *e; + struct bio_vec *bvec; + struct page *page; + struct bio *bio; + unsigned int ds; + int i; + + e = mempool_alloc(drbd_ee_mempool, gfp_mask & ~__GFP_HIGHMEM); + if (!e) { + if (!(gfp_mask & __GFP_NOWARN)) + ERR("alloc_ee: Allocation of an EE failed\n"); + return NULL; + } + + bio = bio_alloc(gfp_mask & ~__GFP_HIGHMEM, div_ceil(data_size, PAGE_SIZE)); + if (!bio) { + if (!(gfp_mask & __GFP_NOWARN)) + ERR("alloc_ee: Allocation of a bio failed\n"); + goto fail1; + } + + bio->bi_bdev = mdev->bc->backing_bdev; + bio->bi_sector = sector; + + ds = data_size; + while (ds) { + page = drbd_pp_alloc(mdev, gfp_mask); + if (!page) { + if (!(gfp_mask & __GFP_NOWARN)) + ERR("alloc_ee: Allocation of a page failed\n"); + goto fail2; + } + if (!bio_add_page(bio, page, min_t(int, ds, PAGE_SIZE), 0)) { + drbd_pp_free(mdev, page); + ERR("alloc_ee: bio_add_page(s=%llu," + "data_size=%u,ds=%u) failed\n", + (unsigned long long)sector, data_size, ds); + + q = bdev_get_queue(bio->bi_bdev); + if (q->merge_bvec_fn) { +#ifdef HAVE_bvec_merge_data + struct bvec_merge_data bvm = { + .bi_bdev = bio->bi_bdev, + .bi_sector = bio->bi_sector, + .bi_size = bio->bi_size, + .bi_rw = bio->bi_rw, + }; + int l = q->merge_bvec_fn(q, &bvm, + &bio->bi_io_vec[bio->bi_vcnt]); +#else + int l = q->merge_bvec_fn(q, bio, + &bio->bi_io_vec[bio->bi_vcnt]); +#endif + ERR("merge_bvec_fn() = %d\n", l); + } + + /* dump more of the bio. */ + DUMPI(bio->bi_max_vecs); + DUMPI(bio->bi_vcnt); + DUMPI(bio->bi_size); + DUMPI(bio->bi_phys_segments); + + goto fail2; + break; + } + ds -= min_t(int, ds, PAGE_SIZE); + } + + D_ASSERT(data_size == bio->bi_size); + + bio->bi_private = e; + e->mdev = mdev; + e->sector = sector; + e->size = bio->bi_size; + + e->private_bio = bio; + e->block_id = id; + INIT_HLIST_NODE(&e->colision); + e->epoch = NULL; + e->flags = 0; + + MTRACE(TraceTypeEE, TraceLvlAll, + INFO("allocated EE sec=%llus size=%u ee=%p\n", + (unsigned long long)sector, data_size, e); + ); + + return e; + + fail2: + __bio_for_each_segment(bvec, bio, i, 0) { + drbd_pp_free(mdev, bvec->bv_page); + } + bio_put(bio); + fail1: + mempool_free(e, drbd_ee_mempool); + + return NULL; +} + +void drbd_free_ee(struct drbd_conf *mdev, struct Tl_epoch_entry *e) +{ + struct bio *bio = e->private_bio; + struct bio_vec *bvec; + int i; + + MTRACE(TraceTypeEE, TraceLvlAll, + INFO("Free EE sec=%llus size=%u ee=%p\n", + (unsigned long long)e->sector, e->size, e); + ); + + __bio_for_each_segment(bvec, bio, i, 0) { + drbd_pp_free(mdev, bvec->bv_page); + } + + bio_put(bio); + + D_ASSERT(hlist_unhashed(&e->colision)); + + mempool_free(e, drbd_ee_mempool); +} + +/* currently on module unload only */ +int drbd_release_ee(struct drbd_conf *mdev, struct list_head *list) +{ + int count = 0; + struct Tl_epoch_entry *e; + struct list_head *le; + + spin_lock_irq(&mdev->req_lock); + while (!list_empty(list)) { + le = list->next; + list_del(le); + e = list_entry(le, struct Tl_epoch_entry, w.list); + drbd_free_ee(mdev, e); + count++; + } + spin_unlock_irq(&mdev->req_lock); + + return count; +} + + +STATIC void reclaim_net_ee(struct drbd_conf *mdev) +{ + struct Tl_epoch_entry *e; + struct list_head *le, *tle; + + /* The EEs are always appended to the end of the list. Since + they are sent in order over the wire, they have to finish + in order. As soon as we see the first not finished we can + stop to examine the list... */ + + list_for_each_safe(le, tle, &mdev->net_ee) { + e = list_entry(le, struct Tl_epoch_entry, w.list); + if (drbd_bio_has_active_page(e->private_bio)) + break; + list_del(le); + drbd_free_ee(mdev, e); + } +} + + +/* + * This function is called from _asender only_ + * but see also comments in _req_mod(,barrier_acked) + * and receive_Barrier. + * + * Move entries from net_ee to done_ee, if ready. + * Grab done_ee, call all callbacks, free the entries. + * The callbacks typically send out ACKs. + */ +STATIC int drbd_process_done_ee(struct drbd_conf *mdev) +{ + LIST_HEAD(work_list); + struct Tl_epoch_entry *e, *t; + int ok = 1; + + spin_lock_irq(&mdev->req_lock); + reclaim_net_ee(mdev); + list_splice_init(&mdev->done_ee, &work_list); + spin_unlock_irq(&mdev->req_lock); + + /* possible callbacks here: + * e_end_block, and e_end_resync_block, e_send_discard_ack. + * all ignore the last argument. + */ + list_for_each_entry_safe(e, t, &work_list, w.list) { + MTRACE(TraceTypeEE, TraceLvlAll, + INFO("Process EE on done_ee sec=%llus size=%u ee=%p\n", + (unsigned long long)e->sector, e->size, e); + ); + /* list_del not necessary, next/prev members not touched */ + if (e->w.cb(mdev, &e->w, 0) == 0) + ok = 0; + drbd_free_ee(mdev, e); + } + wake_up(&mdev->ee_wait); + + return ok; +} + + + +/* clean-up helper for drbd_disconnect */ +void _drbd_clear_done_ee(struct drbd_conf *mdev) +{ + struct list_head *le; + struct Tl_epoch_entry *e; + struct drbd_epoch *epoch; + int n = 0; + + MUST_HOLD(&mdev->req_lock); + + reclaim_net_ee(mdev); + + while (!list_empty(&mdev->done_ee)) { + le = mdev->done_ee.next; + list_del(le); + e = list_entry(le, struct Tl_epoch_entry, w.list); + if (mdev->net_conf->wire_protocol == DRBD_PROT_C + || is_syncer_block_id(e->block_id)) + ++n; + + if (!hlist_unhashed(&e->colision)) + hlist_del_init(&e->colision); + + if (e->epoch) { + if (e->flags & EE_IS_BARRIER) { + epoch = previous_epoch(mdev, e->epoch); + if (epoch) + drbd_may_finish_epoch(mdev, epoch, EV_barrier_done + EV_cleanup); + } + drbd_may_finish_epoch(mdev, e->epoch, EV_put + EV_cleanup); + } + drbd_free_ee(mdev, e); + } + + sub_unacked(mdev, n); +} + +void _drbd_wait_ee_list_empty(struct drbd_conf *mdev, struct list_head *head) +{ + DEFINE_WAIT(wait); + MUST_HOLD(&mdev->req_lock); + + /* avoids spin_lock/unlock + * and calling prepare_to_wait in the fast path */ + while (!list_empty(head)) { + prepare_to_wait(&mdev->ee_wait, &wait, TASK_UNINTERRUPTIBLE); + spin_unlock_irq(&mdev->req_lock); + drbd_kick_lo(mdev); + schedule(); + finish_wait(&mdev->ee_wait, &wait); + spin_lock_irq(&mdev->req_lock); + } +} + +void drbd_wait_ee_list_empty(struct drbd_conf *mdev, struct list_head *head) +{ + spin_lock_irq(&mdev->req_lock); + _drbd_wait_ee_list_empty(mdev, head); + spin_unlock_irq(&mdev->req_lock); +} + +#ifdef DEFINE_SOCK_CREATE_KERN +/* if there is no sock_create_kern, + * tthere is also sock_create_lite missing */ +int sock_create_lite(int family, int type, int protocol, struct socket **res) +{ + int err = 0; + struct socket *sock = NULL; + + sock = sock_alloc(); + if (!sock) + err = -ENOMEM; + else + sock->type = type; + + *res = sock; + return err; +} +#endif + +/* see also kernel_accept; which is only present since 2.6.18. + * also we want to log which part of it failed, exactly */ +STATIC int drbd_accept(struct drbd_conf *mdev, const char **what, + struct socket *sock, struct socket **newsock) +{ + struct sock *sk = sock->sk; + int err = 0; + + *what = "listen"; + err = sock->ops->listen(sock, 5); + if (err < 0) + goto out; + + *what = "sock_create_lite"; + err = sock_create_lite(sk->sk_family, sk->sk_type, sk->sk_protocol, + newsock); + if (err < 0) + goto out; + + *what = "accept"; + err = sock->ops->accept(sock, *newsock, 0); + if (err < 0) { + sock_release(*newsock); + *newsock = NULL; + goto out; + } + (*newsock)->ops = sock->ops; + +out: + return err; +} + +STATIC int drbd_recv_short(struct drbd_conf *mdev, struct socket *sock, + void *buf, size_t size, int flags) +{ + mm_segment_t oldfs; + struct kvec iov = { + .iov_base = buf, + .iov_len = size, + }; + struct msghdr msg = { + .msg_iovlen = 1, + .msg_iov = (struct iovec *)&iov, + .msg_flags = (flags ? flags : MSG_WAITALL | MSG_NOSIGNAL) + }; + int rv; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + rv = sock_recvmsg(sock, &msg, size, msg.msg_flags); + set_fs(oldfs); + + return rv; +} + +STATIC int drbd_recv(struct drbd_conf *mdev, void *buf, size_t size) +{ + mm_segment_t oldfs; + struct kvec iov = { + .iov_base = buf, + .iov_len = size, + }; + struct msghdr msg = { + .msg_iovlen = 1, + .msg_iov = (struct iovec *)&iov, + .msg_flags = MSG_WAITALL | MSG_NOSIGNAL + }; + int rv; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + + for (;;) { + rv = sock_recvmsg(mdev->data.socket, &msg, size, msg.msg_flags); + if (rv == size) + break; + + /* Note: + * ECONNRESET other side closed the connection + * ERESTARTSYS (on sock) we got a signal + */ + + if (rv < 0) { + if (rv == -ECONNRESET) + INFO("sock was reset by peer\n"); + else if (rv != -ERESTARTSYS) + ERR("sock_recvmsg returned %d\n", rv); + break; + } else if (rv == 0) { + INFO("sock was shut down by peer\n"); + break; + } else { + /* signal came in, or peer/link went down, + * after we read a partial message + */ + /* D_ASSERT(signal_pending(current)); */ + break; + } + }; + + set_fs(oldfs); + + if (rv != size) + drbd_force_state(mdev, NS(conn, BrokenPipe)); + + return rv; +} + +STATIC struct socket *drbd_try_connect(struct drbd_conf *mdev) +{ + const char *what; + struct socket *sock; + struct sockaddr_in6 src_in6; + int err; + int disconnect_on_error = 1; + + if (!inc_net(mdev)) + return NULL; + + what = "sock_create_kern"; + err = sock_create_kern(((struct sockaddr *)mdev->net_conf->my_addr)->sa_family, + SOCK_STREAM, IPPROTO_TCP, &sock); + if (err < 0) { + sock = NULL; + goto out; + } + + sock->sk->sk_rcvtimeo = + sock->sk->sk_sndtimeo = mdev->net_conf->try_connect_int*HZ; + + /* explicitly bind to the configured IP as source IP + * for the outgoing connections. + * This is needed for multihomed hosts and to be + * able to use lo: interfaces for drbd. + * Make sure to use 0 as portnumber, so linux selects + * a free one dynamically. + */ + memcpy(&src_in6, mdev->net_conf->my_addr, + min_t(int, mdev->net_conf->my_addr_len, sizeof(src_in6))); + if(((struct sockaddr *)mdev->net_conf->my_addr)->sa_family == AF_INET6) + src_in6.sin6_port = 0; + else + ((struct sockaddr_in *)&src_in6)->sin_port = 0; /* AF_INET & AF_SCI */ + + what = "bind before connect"; + err = sock->ops->bind(sock, + (struct sockaddr *) &src_in6, + mdev->net_conf->my_addr_len); + if (err < 0) + goto out; + + /* connect may fail, peer not yet available. + * stay WFConnection, don't go Disconnecting! */ + disconnect_on_error = 0; + what = "connect"; + err = sock->ops->connect(sock, + (struct sockaddr *)mdev->net_conf->peer_addr, + mdev->net_conf->peer_addr_len, 0); + +out: + if (err < 0) { + if (sock) { + sock_release(sock); + sock = NULL; + } + switch (-err) { + /* timeout, busy, signal pending */ + case ETIMEDOUT: case EAGAIN: case EINPROGRESS: + case EINTR: case ERESTARTSYS: + /* peer not (yet) available, network problem */ + case ECONNREFUSED: case ENETUNREACH: + case EHOSTDOWN: case EHOSTUNREACH: +#if 0 + DBG("%s failure ignored, err = %d\n", + what, err); +#endif + disconnect_on_error = 0; + break; + default: + ERR("%s failed, err = %d\n", what, err); + } + if (disconnect_on_error) + drbd_force_state(mdev, NS(conn, Disconnecting)); + } + dec_net(mdev); + return sock; +} + +STATIC struct socket *drbd_wait_for_connect(struct drbd_conf *mdev) +{ + int err; + struct socket *s_estab = NULL, *s_listen; + const char *what; + + if (!inc_net(mdev)) + return NULL; + + what = "sock_create_kern"; + err = sock_create_kern(((struct sockaddr *)mdev->net_conf->my_addr)->sa_family, + SOCK_STREAM, IPPROTO_TCP, &s_listen); + if (err) { + s_listen = NULL; + goto out; + } + + s_listen->sk->sk_reuse = 1; /* SO_REUSEADDR */ + s_listen->sk->sk_rcvtimeo = + s_listen->sk->sk_sndtimeo = mdev->net_conf->try_connect_int*HZ; + + what = "bind before listen"; + err = s_listen->ops->bind(s_listen, + (struct sockaddr *) mdev->net_conf->my_addr, + mdev->net_conf->my_addr_len); + if (err < 0) + goto out; + + err = drbd_accept(mdev, &what, s_listen, &s_estab); + +out: + if (s_listen) + sock_release(s_listen); + if (err < 0) { + if (err != -EAGAIN && err != -EINTR && err != -ERESTARTSYS) { + ERR("%s failed, err = %d\n", what, err); + drbd_force_state(mdev, NS(conn, Disconnecting)); + } +#if 0 + else { + DBG("%s failure ignored, err = %d, not Disconnecting\n", + what, err); + } +#endif + } + dec_net(mdev); + + return s_estab; +} + +int drbd_do_handshake(struct drbd_conf *mdev); +int drbd_do_auth(struct drbd_conf *mdev); + +STATIC int drbd_send_fp(struct drbd_conf *mdev, + struct socket *sock, enum Drbd_Packet_Cmd cmd) +{ + struct Drbd_Header *h = (struct Drbd_Header *) &mdev->data.sbuf.head; + + return _drbd_send_cmd(mdev, sock, cmd, h, sizeof(*h), 0); +} + +STATIC enum Drbd_Packet_Cmd drbd_recv_fp(struct drbd_conf *mdev, struct socket *sock) +{ + struct Drbd_Header *h = (struct Drbd_Header *) &mdev->data.sbuf.head; + int rr; + + rr = drbd_recv_short(mdev, sock, h, sizeof(*h), 0); + + if (rr == sizeof(*h) && h->magic == BE_DRBD_MAGIC) + return be16_to_cpu(h->command); + + return 0xffff; +} + +/** + * drbd_socket_okay: + * Tests if the connection behind the socket still exists. If not it frees + * the socket. + */ +static int drbd_socket_okay(struct drbd_conf *mdev, struct socket **sock) +{ + int rr; + char tb[4]; + + rr = drbd_recv_short(mdev, *sock, tb, 4, MSG_DONTWAIT | MSG_PEEK); + + if (rr > 0 || rr == -EAGAIN) { + return TRUE; + } else { + sock_release(*sock); + *sock = NULL; + return FALSE; + } +} + +/* + * return values: + * 1 yess, we have a valid connection + * 0 oops, did not work out, please try again + * -1 peer talks different language, + * no point in trying again, please go standalone. + * -2 We do not have a network config... + */ +STATIC int drbd_connect(struct drbd_conf *mdev) +{ + struct socket *s, *sock, *msock; + int try, h, ok; + + D_ASSERT(!mdev->data.socket); + + if (test_and_clear_bit(CREATE_BARRIER, &mdev->flags)) + ERR("CREATE_BARRIER flag was set in drbd_connect - now cleared!\n"); + + if (drbd_request_state(mdev, NS(conn, WFConnection)) < SS_Success) + return -2; + + clear_bit(DISCARD_CONCURRENT, &mdev->flags); + + sock = NULL; + msock = NULL; + + do { + for (try = 0;;) { + /* 3 tries, this should take less than a second! */ + s = drbd_try_connect(mdev); + if (s || ++try >= 3) + break; + /* give the other side time to call bind() & listen() */ + __set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ / 10); + } + + if (s) { + if (!sock) { + drbd_send_fp(mdev, s, HandShakeS); + sock = s; + s = NULL; + } else if (!msock) { + drbd_send_fp(mdev, s, HandShakeM); + msock = s; + s = NULL; + } else { + ERR("Logic error in drbd_connect()\n"); + return -1; + } + } + + if (sock && msock) { + __set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ / 10); + ok = drbd_socket_okay(mdev, &sock); + ok = drbd_socket_okay(mdev, &msock) && ok; + if (ok) + break; + } + + s = drbd_wait_for_connect(mdev); + if (s) { + switch (drbd_recv_fp(mdev, s)) { + case HandShakeS: + if (sock) + sock_release(sock); + sock = s; + break; + case HandShakeM: + if (msock) + sock_release(msock); + msock = s; + set_bit(DISCARD_CONCURRENT, &mdev->flags); + break; + default: + drbd_WARN("Error receiving initial packet\n"); + sock_release(s); + } + } + + if (mdev->state.conn <= Disconnecting) + return -1; + if (signal_pending(current)) { + flush_signals(current); + smp_rmb(); + if (get_t_state(&mdev->receiver) == Exiting) { + if (sock) + sock_release(sock); + if (msock) + sock_release(msock); + return -1; + } + } + + if (sock && msock) { + ok = drbd_socket_okay(mdev, &sock); + ok = drbd_socket_okay(mdev, &msock) && ok; + if (ok) + break; + } + } while (1); + + msock->sk->sk_reuse = 1; /* SO_REUSEADDR */ + sock->sk->sk_reuse = 1; /* SO_REUSEADDR */ + + sock->sk->sk_allocation = GFP_NOIO; + msock->sk->sk_allocation = GFP_NOIO; + + sock->sk->sk_priority = TC_PRIO_INTERACTIVE_BULK; + msock->sk->sk_priority = TC_PRIO_INTERACTIVE; + + if (mdev->net_conf->sndbuf_size) { + /* FIXME fold to limits. should be done during configuration */ + /* this is setsockopt SO_SNDBUFFORCE and SO_RCVBUFFORCE, + * done directly. */ + sock->sk->sk_sndbuf = mdev->net_conf->sndbuf_size; + sock->sk->sk_rcvbuf = mdev->net_conf->sndbuf_size; + sock->sk->sk_userlocks |= SOCK_SNDBUF_LOCK | SOCK_RCVBUF_LOCK; + } + +#if 0 /* don't pin the msock bufsize, autotuning should work better */ + msock->sk->sk_sndbuf = 2*32767; + msock->sk->sk_userlocks |= SOCK_SNDBUF_LOCK; +#endif + + /* NOT YET ... + * sock->sk->sk_sndtimeo = mdev->net_conf->timeout*HZ/10; + * sock->sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT; + * first set it to the HandShake timeout, wich is hardcoded for now: */ + sock->sk->sk_sndtimeo = + sock->sk->sk_rcvtimeo = 2*HZ; + + msock->sk->sk_sndtimeo = mdev->net_conf->timeout*HZ/10; + msock->sk->sk_rcvtimeo = mdev->net_conf->ping_int*HZ; + + /* we don't want delays. + * we use TCP_CORK where apropriate, though */ + drbd_tcp_nodelay(sock); + drbd_tcp_nodelay(msock); + + mdev->data.socket = sock; + mdev->meta.socket = msock; + mdev->last_received = jiffies; + + D_ASSERT(mdev->asender.task == NULL); + + h = drbd_do_handshake(mdev); + if (h <= 0) + return h; + + if (mdev->cram_hmac_tfm) { + /* drbd_request_state(mdev, NS(conn, WFAuth)); */ + if (!drbd_do_auth(mdev)) { + ERR("Authentication of peer failed\n"); + return -1; + } + } + + if (drbd_request_state(mdev, NS(conn, WFReportParams)) < SS_Success) + return 0; + + sock->sk->sk_sndtimeo = mdev->net_conf->timeout*HZ/10; + sock->sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT; + + atomic_set(&mdev->packet_seq, 0); + mdev->peer_seq = 0; + + drbd_thread_start(&mdev->asender); + + drbd_send_protocol(mdev); + drbd_send_sync_param(mdev, &mdev->sync_conf); + drbd_send_sizes(mdev); + drbd_send_uuids(mdev); + drbd_send_state(mdev); + clear_bit(USE_DEGR_WFC_T, &mdev->flags); + + return 1; +} + +STATIC int drbd_recv_header(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + int r; + + r = drbd_recv(mdev, h, sizeof(*h)); + + if (unlikely(r != sizeof(*h))) { + ERR("short read expecting header on sock: r=%d\n", r); + return FALSE; + }; + h->command = be16_to_cpu(h->command); + h->length = be16_to_cpu(h->length); + if (unlikely(h->magic != BE_DRBD_MAGIC)) { + ERR("magic?? on data m: 0x%lx c: %d l: %d\n", + (long)be32_to_cpu(h->magic), + h->command, h->length); + return FALSE; + } + mdev->last_received = jiffies; + + return TRUE; +} + +STATIC enum finish_epoch drbd_flush_after_epoch(struct drbd_conf *mdev, struct drbd_epoch *epoch) +{ + int rv; + + if (mdev->write_ordering >= WO_bdev_flush && inc_local(mdev)) { + rv = blkdev_issue_flush(mdev->bc->backing_bdev, NULL); + if (rv) { + ERR("local disk flush failed with status %d\n",rv); + /* would rather check on EOPNOTSUPP, but that is not reliable. + * don't try again for ANY return value != 0 + * if (rv == -EOPNOTSUPP) */ + drbd_bump_write_ordering(mdev, WO_drain_io); + } + dec_local(mdev); + } + + return drbd_may_finish_epoch(mdev, epoch, EV_barrier_done); +} + +/** + * w_flush: Checks if an epoch can be closed and therefore might + * close and/or free the epoch object. + */ +STATIC int w_flush(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + struct flush_work *fw = (struct flush_work *)w; + struct drbd_epoch *epoch = fw->epoch; + + kfree(w); + + if (!test_and_set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags)) + drbd_flush_after_epoch(mdev, epoch); + + drbd_may_finish_epoch(mdev, epoch, EV_put | + (mdev->state.conn < Connected ? EV_cleanup : 0)); + + return 1; +} + +/** + * drbd_may_finish_epoch: Checks if an epoch can be closed and therefore might + * close and/or free the epoch object. + */ +STATIC enum finish_epoch drbd_may_finish_epoch(struct drbd_conf *mdev, + struct drbd_epoch *epoch, + enum epoch_event ev) +{ + int finish, epoch_size; + struct drbd_epoch *next_epoch; + int schedule_flush = 0; + enum finish_epoch rv = FE_still_live; + + static char *epoch_event_str[] = { + [EV_put] = "put", + [EV_got_barrier_nr] = "got_barrier_nr", + [EV_barrier_done] = "barrier_done", + [EV_became_last] = "became_last", + }; + + spin_lock(&mdev->epoch_lock); + do { + next_epoch = NULL; + finish = 0; + + epoch_size = atomic_read(&epoch->epoch_size); + + switch (ev & ~EV_cleanup) { + case EV_put: + atomic_dec(&epoch->active); + break; + case EV_got_barrier_nr: + set_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags); + + /* Special case: If we just switched from WO_bio_barrier to + WO_bdev_flush we should not finish the current epoch */ + if (test_bit(DE_CONTAINS_A_BARRIER, &epoch->flags) && epoch_size == 1 && + mdev->write_ordering != WO_bio_barrier && + epoch == mdev->current_epoch) + clear_bit(DE_CONTAINS_A_BARRIER, &epoch->flags); + break; + case EV_barrier_done: + set_bit(DE_BARRIER_IN_NEXT_EPOCH_DONE, &epoch->flags); + break; + case EV_became_last: + /* nothing to do*/ + break; + } + + MTRACE(TraceTypeEpochs, TraceLvlAll, + INFO("Update epoch %p/%d { size=%d active=%d %c%c n%c%c } ev=%s\n", + epoch, epoch->barrier_nr, epoch_size, atomic_read(&epoch->active), + test_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags) ? 'n' : '-', + test_bit(DE_CONTAINS_A_BARRIER, &epoch->flags) ? 'b' : '-', + test_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags) ? 'i' : '-', + test_bit(DE_BARRIER_IN_NEXT_EPOCH_DONE, &epoch->flags) ? 'd' : '-', + epoch_event_str[ev]); + ); + + if (epoch_size != 0 && + atomic_read(&epoch->active) == 0 && + test_bit(DE_HAVE_BARRIER_NUMBER, &epoch->flags) && + epoch->list.prev == &mdev->current_epoch->list && + !test_bit(DE_IS_FINISHING, &epoch->flags)) { + /* Nearly all conditions are met to finish that epoch... */ + if (test_bit(DE_BARRIER_IN_NEXT_EPOCH_DONE, &epoch->flags) || + mdev->write_ordering == WO_none || + (epoch_size == 1 && test_bit(DE_CONTAINS_A_BARRIER, &epoch->flags)) || + ev & EV_cleanup) { + finish = 1; + set_bit(DE_IS_FINISHING, &epoch->flags); + } else if (!test_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags) && + mdev->write_ordering == WO_bio_barrier) { + atomic_inc(&epoch->active); + schedule_flush = 1; + } + } + if (finish) { + if (!(ev & EV_cleanup)) { + spin_unlock(&mdev->epoch_lock); + drbd_send_b_ack(mdev, epoch->barrier_nr, epoch_size); + spin_lock(&mdev->epoch_lock); + } + dec_unacked(mdev); + + if (mdev->current_epoch != epoch) { + next_epoch = list_entry(epoch->list.next, struct drbd_epoch, list); + list_del(&epoch->list); + ev = EV_became_last | (ev & EV_cleanup); + mdev->epochs--; + MTRACE(TraceTypeEpochs, TraceLvlSummary, + INFO("Freeing epoch %p/%d { size=%d } nr_epochs=%d\n", + epoch, epoch->barrier_nr, epoch_size, mdev->epochs); + ); + kfree(epoch); + + if (rv == FE_still_live) + rv = FE_destroyed; + } else { + epoch->flags = 0; + atomic_set(&epoch->epoch_size, 0); + /* atomic_set(&epoch->active, 0); is alrady zero */ + if (rv == FE_still_live) + rv = FE_recycled; + } + } + + if (!next_epoch) + break; + + epoch = next_epoch; + } while (1); + + spin_unlock(&mdev->epoch_lock); + + if (schedule_flush) { + struct flush_work *fw; + fw = kmalloc(sizeof(*fw), GFP_ATOMIC); + if (fw) { + MTRACE(TraceTypeEpochs, TraceLvlMetrics, + INFO("Schedul flush %p/%d { size=%d } nr_epochs=%d\n", + epoch, epoch->barrier_nr, epoch_size, mdev->epochs); + ); + fw->w.cb = w_flush; + fw->epoch = epoch; + drbd_queue_work(&mdev->data.work, &fw->w); + } else { + drbd_WARN("Could not kmalloc a flush_work obj\n"); + set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags); + /* That is not a recursion, only one level */ + drbd_may_finish_epoch(mdev, epoch, EV_barrier_done); + drbd_may_finish_epoch(mdev, epoch, EV_put); + } + } + + return rv; +} + +/** + * drbd_bump_write_ordering: It turned out that the current mdev->write_ordering + * method does not work on the backing block device. Try the next allowed method. + */ +void drbd_bump_write_ordering(struct drbd_conf *mdev, enum write_ordering_e wo) __must_hold(local) +{ + enum write_ordering_e pwo; + static char *write_ordering_str[] = { + [WO_none] = "none", + [WO_drain_io] = "drain", + [WO_bdev_flush] = "flush", + [WO_bio_barrier] = "barrier", + }; + + pwo = mdev->write_ordering; + wo = min(pwo, wo); + if (wo == WO_bio_barrier && mdev->bc->dc.no_disk_barrier) + wo = WO_bdev_flush; + if (wo == WO_bdev_flush && mdev->bc->dc.no_disk_flush) + wo = WO_drain_io; + if (wo == WO_drain_io && mdev->bc->dc.no_disk_drain) + wo = WO_none; + mdev->write_ordering = wo; + if (pwo != mdev->write_ordering || wo == WO_bio_barrier) + INFO("Method to ensure write ordering: %s\n", write_ordering_str[mdev->write_ordering]); +} + +/** + * w_e_reissue: In case the IO subsystem delivered an error for an BIO with the + * BIO_RW_BARRIER flag set, retry that bio without the barrier flag set. + */ +int w_e_reissue(struct drbd_conf *mdev, struct drbd_work *w, int cancel) __releases(local) +{ + struct Tl_epoch_entry *e = (struct Tl_epoch_entry *)w; + struct bio* bio = e->private_bio; + + /* We leave DE_CONTAINS_A_BARRIER and EE_IS_BARRIER in place, + (and DE_BARRIER_IN_NEXT_EPOCH_ISSUED in the previous Epoch) + so that we can finish that epoch in drbd_may_finish_epoch(). + That is necessary if we already have a long chain of Epochs, before + we realize that BIO_RW_BARRIER is actually not supported */ + + /* As long as the -ENOTSUPP on the barrier is reported immediately + that will never trigger. It it is reported late, we will just + print that warning an continue corretly for all future requests + with WO_bdev_flush */ + if (previous_epoch(mdev, e->epoch)) + drbd_WARN("Write ordering was not enforced (one time event)\n"); + + /* prepare bio for re-submit, + * re-init volatile members */ + /* we still have a local reference, + * inc_local was done in receive_Data. */ + bio->bi_bdev = mdev->bc->backing_bdev; + bio->bi_sector = e->sector; + bio->bi_size = e->size; + bio->bi_idx = 0; + + bio->bi_flags &= ~(BIO_POOL_MASK - 1); + bio->bi_flags |= 1 << BIO_UPTODATE; + + /* don't know whether this is necessary: */ + bio->bi_phys_segments = 0; + bio->bi_next = NULL; + + /* these should be unchanged: */ + /* bio->bi_end_io = drbd_endio_write_sec; */ + /* bio->bi_vcnt = whatever; */ + + e->w.cb = e_end_block; + + /* This is no longer a barrier request. */ + bio->bi_rw &= ~(1UL << BIO_RW_BARRIER); + + drbd_generic_make_request(mdev, DRBD_FAULT_DT_WR, bio); + + return 1; +} + +STATIC int receive_Barrier(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + int rv, issue_flush; + struct Drbd_Barrier_Packet *p = (struct Drbd_Barrier_Packet *)h; + struct drbd_epoch *epoch; + + ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE; + + rv = drbd_recv(mdev, h->payload, h->length); + ERR_IF(rv != h->length) return FALSE; + + inc_unacked(mdev); + + if (mdev->net_conf->wire_protocol != DRBD_PROT_C) + drbd_kick_lo(mdev); + + mdev->current_epoch->barrier_nr = p->barrier; + rv = drbd_may_finish_epoch(mdev, mdev->current_epoch, EV_got_barrier_nr); + + /* BarrierAck may imply that the corresponding extent is dropped from + * the activity log, which means it would not be resynced in case the + * Primary crashes now. + * Therefore we must send the barrier_ack after the barrier request was + * completed. */ + switch (mdev->write_ordering) { + case WO_bio_barrier: + case WO_none: + if (rv == FE_recycled) + return TRUE; + break; + + case WO_bdev_flush: + case WO_drain_io: + D_ASSERT(rv == FE_still_live); + set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &mdev->current_epoch->flags); + drbd_wait_ee_list_empty(mdev, &mdev->active_ee); + rv = drbd_flush_after_epoch(mdev, mdev->current_epoch); + if (rv == FE_recycled) + return TRUE; + + /* The asender will send all the ACKs and barrier ACKs out, since + all EEs moved from the active_ee to the done_ee. We need to + provide a new epoch object for the EEs that come in soon */ + break; + } + + epoch = kmalloc(sizeof(struct drbd_epoch), GFP_KERNEL); + if (!epoch) { + drbd_WARN("Allocation of an epoch failed, slowing down\n"); + issue_flush = !test_and_set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags); + drbd_wait_ee_list_empty(mdev, &mdev->active_ee); + if (issue_flush) { + rv = drbd_flush_after_epoch(mdev, mdev->current_epoch); + if (rv == FE_recycled) + return TRUE; + } + + drbd_wait_ee_list_empty(mdev, &mdev->done_ee); + + return TRUE; + } + + epoch->flags = 0; + atomic_set(&epoch->epoch_size, 0); + atomic_set(&epoch->active, 0); + + spin_lock(&mdev->epoch_lock); + if (atomic_read(&mdev->current_epoch->epoch_size)) { + list_add(&epoch->list, &mdev->current_epoch->list); + mdev->current_epoch = epoch; + mdev->epochs++; + MTRACE(TraceTypeEpochs, TraceLvlMetrics, + INFO("Allocat epoch %p/xxxx { } nr_epochs=%d\n", epoch, mdev->epochs); + ); + } else { + /* The current_epoch got recycled while we allocated this one... */ + kfree(epoch); + } + spin_unlock(&mdev->epoch_lock); + + return TRUE; +} + +/* used from receive_RSDataReply (recv_resync_read) + * and from receive_Data */ +STATIC struct Tl_epoch_entry * +read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector, int data_size) __must_hold(local) +{ + struct Tl_epoch_entry *e; + struct bio_vec *bvec; + struct page *page; + struct bio *bio; + int dgs, ds, i, rr; + void *dig_in = mdev->int_dig_in; + void *dig_vv = mdev->int_dig_vv; + + dgs = (mdev->agreed_pro_version >= 87 && mdev->integrity_r_tfm) ? + crypto_hash_digestsize(mdev->integrity_r_tfm) : 0; + + if (dgs) { + rr = drbd_recv(mdev, dig_in, dgs); + if (rr != dgs) { + drbd_WARN("short read receiving data digest: read %d expected %d\n", + rr, dgs); + return NULL; + } + } + + data_size -= dgs; + + ERR_IF(data_size & 0x1ff) return NULL; + ERR_IF(data_size > DRBD_MAX_SEGMENT_SIZE) return NULL; + + e = drbd_alloc_ee(mdev, id, sector, data_size, GFP_KERNEL); + if (!e) + return NULL; + bio = e->private_bio; + ds = data_size; + bio_for_each_segment(bvec, bio, i) { + page = bvec->bv_page; + rr = drbd_recv(mdev, kmap(page), min_t(int, ds, PAGE_SIZE)); + kunmap(page); + if (rr != min_t(int, ds, PAGE_SIZE)) { + drbd_free_ee(mdev, e); + drbd_WARN("short read receiving data: read %d expected %d\n", + rr, min_t(int, ds, PAGE_SIZE)); + return NULL; + } + ds -= rr; + } + + if (dgs) { + drbd_csum(mdev, mdev->integrity_r_tfm, bio, dig_vv); + if (memcmp(dig_in,dig_vv,dgs)) { + ERR("Digest integrity check FAILED.\n"); + drbd_bcast_ee(mdev, "digest failed", + dgs, dig_in, dig_vv, e); + drbd_free_ee(mdev, e); + return NULL; + } + } + mdev->recv_cnt += data_size>>9; + return e; +} + +/* drbd_drain_block() just takes a data block + * out of the socket input buffer, and discards it. + */ +STATIC int drbd_drain_block(struct drbd_conf *mdev, int data_size) +{ + struct page *page; + int rr, rv = 1; + void *data; + + page = drbd_pp_alloc(mdev, GFP_KERNEL); + + data = kmap(page); + while (data_size) { + rr = drbd_recv(mdev, data, min_t(int, data_size, PAGE_SIZE)); + if (rr != min_t(int, data_size, PAGE_SIZE)) { + rv = 0; + drbd_WARN("short read receiving data: read %d expected %d\n", + rr, min_t(int, data_size, PAGE_SIZE)); + break; + } + data_size -= rr; + } + kunmap(page); + drbd_pp_free(mdev, page); + return rv; +} + +/* kick lower level device, if we have more than (arbitrary number) + * reference counts on it, which typically are locally submitted io + * requests. don't use unacked_cnt, so we speed up proto A and B, too. */ +static void maybe_kick_lo(struct drbd_conf *mdev) +{ + /* FIXME hysteresis ?? */ + if (atomic_read(&mdev->local_cnt) >= mdev->net_conf->unplug_watermark) + drbd_kick_lo(mdev); +} + +STATIC int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req, + sector_t sector, int data_size) +{ + struct bio_vec *bvec; + struct bio *bio; + int dgs, rr, i, expect; + void *dig_in = mdev->int_dig_in; + void *dig_vv = mdev->int_dig_vv; + + dgs = (mdev->agreed_pro_version >= 87 && mdev->integrity_r_tfm) ? + crypto_hash_digestsize(mdev->integrity_r_tfm) : 0; + + if (dgs) { + rr = drbd_recv(mdev, dig_in, dgs); + if (rr != dgs) { + drbd_WARN("short read receiving data reply digest: read %d expected %d\n", + rr, dgs); + return 0; + } + } + + data_size -= dgs; + + bio = req->master_bio; + D_ASSERT(sector == bio->bi_sector); + + bio_for_each_segment(bvec, bio, i) { + expect = min_t(int, data_size, bvec->bv_len); + rr = drbd_recv(mdev, + kmap(bvec->bv_page)+bvec->bv_offset, + expect); + kunmap(bvec->bv_page); + if (rr != expect) { + drbd_WARN("short read receiving data reply: " + "read %d expected %d\n", + rr, expect); + return 0; + } + data_size -= rr; + } + + if (dgs) { + drbd_csum(mdev, mdev->integrity_r_tfm, bio, dig_vv); + if (memcmp(dig_in,dig_vv,dgs)) { + ERR("Digest integrity check FAILED. Broken NICs?\n"); + return 0; + } + } + + D_ASSERT(data_size == 0); + /* FIXME recv_cnt accounting ?? */ + return 1; +} + +/* e_end_resync_block() is called via + * drbd_process_done_ee() by asender only */ +STATIC int e_end_resync_block(struct drbd_conf *mdev, struct drbd_work *w, int unused) +{ + struct Tl_epoch_entry *e = (struct Tl_epoch_entry *)w; + sector_t sector = e->sector; + int ok; + + D_ASSERT(hlist_unhashed(&e->colision)); + + if (likely(drbd_bio_uptodate(e->private_bio))) { + drbd_set_in_sync(mdev, sector, e->size); + ok = drbd_send_ack(mdev, RSWriteAck, e); + } else { + /* Record failure to sync */ + drbd_rs_failed_io(mdev, sector, e->size); + + ok = drbd_send_ack(mdev, NegAck, e); + ok &= drbd_io_error(mdev, FALSE); + } + dec_unacked(mdev); + + return ok; +} + +STATIC int recv_resync_read(struct drbd_conf *mdev, sector_t sector, int data_size) __releases(local) +{ + struct Tl_epoch_entry *e; + + e = read_in_block(mdev, ID_SYNCER, sector, data_size); + if (!e) { + dec_local(mdev); + return FALSE; + } + + dec_rs_pending(mdev); + + e->private_bio->bi_end_io = drbd_endio_write_sec; + e->private_bio->bi_rw = WRITE; + e->w.cb = e_end_resync_block; + + inc_unacked(mdev); + /* corresponding dec_unacked() in e_end_resync_block() + * respective _drbd_clear_done_ee */ + + spin_lock_irq(&mdev->req_lock); + list_add(&e->w.list, &mdev->sync_ee); + spin_unlock_irq(&mdev->req_lock); + + MTRACE(TraceTypeEE, TraceLvlAll, + INFO("submit EE (RS)WRITE sec=%llus size=%u ee=%p\n", + (unsigned long long)e->sector, e->size, e); + ); + dump_internal_bio("Sec", mdev, e->private_bio, 0); + drbd_generic_make_request(mdev, DRBD_FAULT_RS_WR, e->private_bio); + /* accounting done in endio */ + + maybe_kick_lo(mdev); + return TRUE; +} + +STATIC int receive_DataReply(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + struct drbd_request *req; + sector_t sector; + unsigned int header_size, data_size; + int ok; + struct Drbd_Data_Packet *p = (struct Drbd_Data_Packet *)h; + + header_size = sizeof(*p) - sizeof(*h); + data_size = h->length - header_size; + + ERR_IF(data_size == 0) return FALSE; + + if (drbd_recv(mdev, h->payload, header_size) != header_size) + return FALSE; + + sector = be64_to_cpu(p->sector); + + spin_lock_irq(&mdev->req_lock); + req = _ar_id_to_req(mdev, p->block_id, sector); + spin_unlock_irq(&mdev->req_lock); + if (unlikely(!req)) { + ERR("Got a corrupt block_id/sector pair(1).\n"); + return FALSE; + } + + /* hlist_del(&req->colision) is done in _req_may_be_done, to avoid + * special casing it there for the various failure cases. + * still no race with drbd_fail_pending_reads */ + ok = recv_dless_read(mdev, req, sector, data_size); + + if (ok) + req_mod(req, data_received, 0); + /* else: nothing. handled from drbd_disconnect... + * I don't think we may complete this just yet + * in case we are "on-disconnect: freeze" */ + + return ok; +} + +STATIC int receive_RSDataReply(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + sector_t sector; + unsigned int header_size, data_size; + int ok; + struct Drbd_Data_Packet *p = (struct Drbd_Data_Packet *)h; + + header_size = sizeof(*p) - sizeof(*h); + data_size = h->length - header_size; + + ERR_IF(data_size == 0) return FALSE; + + if (drbd_recv(mdev, h->payload, header_size) != header_size) + return FALSE; + + sector = be64_to_cpu(p->sector); + D_ASSERT(p->block_id == ID_SYNCER); + + if (inc_local(mdev)) { + /* data is submitted to disk within recv_resync_read. + * corresponding dec_local done below on error, + * or in drbd_endio_write_sec. */ + /* FIXME paranoia: + * verify that the corresponding bit is set. + * in case we are Primary SyncTarget, + * verify there are no pending write request to that area. + */ + ok = recv_resync_read(mdev, sector, data_size); + } else { + if (DRBD_ratelimit(5*HZ, 5)) + ERR("Can not write resync data to local disk.\n"); + + ok = drbd_drain_block(mdev, data_size); + + drbd_send_ack_dp(mdev, NegAck, p); + } + + return ok; +} + +/* e_end_block() is called via drbd_process_done_ee(). + * this means this function only runs in the asender thread + */ +STATIC int e_end_block(struct drbd_conf *mdev, struct drbd_work *w, int unused) +{ + struct Tl_epoch_entry *e = (struct Tl_epoch_entry *)w; + sector_t sector = e->sector; + struct drbd_epoch *epoch; + int ok = 1, pcmd; + + if (e->flags & EE_IS_BARRIER) { + epoch = previous_epoch(mdev, e->epoch); + if (epoch) + drbd_may_finish_epoch(mdev, epoch, EV_barrier_done); + } + + if (mdev->net_conf->wire_protocol == DRBD_PROT_C) { + if (likely(drbd_bio_uptodate(e->private_bio))) { + pcmd = (mdev->state.conn >= SyncSource && + mdev->state.conn <= PausedSyncT && + e->flags & EE_MAY_SET_IN_SYNC) ? + RSWriteAck : WriteAck; + ok &= drbd_send_ack(mdev, pcmd, e); + if (pcmd == RSWriteAck) + drbd_set_in_sync(mdev, sector, e->size); + } else { + /* FIXME I think we should send a NegAck regardless of + * which protocol is in effect. + * In which case we would need to make sure that any + * NegAck is sent. Basically that means that + * drbd_process_done_ee may not list_del() the ee + * before this callback did run... + * maybe even move the list_del(e) in here... */ + ok = drbd_send_ack(mdev, NegAck, e); + ok &= drbd_io_error(mdev, FALSE); + /* we expect it to be marked out of sync anyways... + * maybe assert this? */ + } + dec_unacked(mdev); + } else if (unlikely(!drbd_bio_uptodate(e->private_bio))) { + ok = drbd_io_error(mdev, FALSE); + } + + /* we delete from the conflict detection hash _after_ we sent out the + * WriteAck / NegAck, to get the sequence number right. */ + if (mdev->net_conf->two_primaries) { + spin_lock_irq(&mdev->req_lock); + D_ASSERT(!hlist_unhashed(&e->colision)); + hlist_del_init(&e->colision); + spin_unlock_irq(&mdev->req_lock); + } else { + D_ASSERT(hlist_unhashed(&e->colision)); + } + + drbd_may_finish_epoch(mdev, e->epoch, EV_put); + + return ok; +} + +STATIC int e_send_discard_ack(struct drbd_conf *mdev, struct drbd_work *w, int unused) +{ + struct Tl_epoch_entry *e = (struct Tl_epoch_entry *)w; + int ok = 1; + + D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C); + ok = drbd_send_ack(mdev, DiscardAck, e); + + spin_lock_irq(&mdev->req_lock); + D_ASSERT(!hlist_unhashed(&e->colision)); + hlist_del_init(&e->colision); + spin_unlock_irq(&mdev->req_lock); + + dec_unacked(mdev); + + return ok; +} + +/* Called from receive_Data. + * Synchronize packets on sock with packets on msock. + * + * This is here so even when a Data packet traveling via sock overtook an Ack + * packet traveling on msock, they are still processed in the order they have + * been sent. + * + * Note: we don't care for Ack packets overtaking Data packets. + * + * In case packet_seq is larger than mdev->peer_seq number, there are + * outstanding packets on the msock. We wait for them to arrive. + * In case we are the logically next packet, we update mdev->peer_seq + * ourselves. Correctly handles 32bit wrap around. + * FIXME verify that atomic_t guarantees 32bit wrap around, + * otherwise we have to play tricks with << ... + * + * Assume we have a 10 GBit connection, that is about 1<<30 byte per second, + * about 1<<21 sectors per second. So "worst" case, we have 1<<3 == 8 seconds + * for the 24bit wrap (historical atomic_t guarantee on some archs), and we have + * 1<<9 == 512 seconds aka ages for the 32bit wrap around... + * + * returns 0 if we may process the packet, + * -ERESTARTSYS if we were interrupted (by disconnect signal). */ +static int drbd_wait_peer_seq(struct drbd_conf *mdev, const u32 packet_seq) +{ + DEFINE_WAIT(wait); + unsigned int p_seq; + long timeout; + int ret = 0; + spin_lock(&mdev->peer_seq_lock); + for (;;) { + prepare_to_wait(&mdev->seq_wait, &wait, TASK_INTERRUPTIBLE); + if (seq_le(packet_seq, mdev->peer_seq+1)) + break; + if (signal_pending(current)) { + ret = -ERESTARTSYS; + break; + } + p_seq = mdev->peer_seq; + spin_unlock(&mdev->peer_seq_lock); + timeout = schedule_timeout(30*HZ); + spin_lock(&mdev->peer_seq_lock); + if (timeout == 0 && p_seq == mdev->peer_seq) { + ret = -ETIMEDOUT; + ERR("ASSERT FAILED waited 30 seconds for sequence update, forcing reconnect\n"); + break; + } + } + finish_wait(&mdev->seq_wait, &wait); + if (mdev->peer_seq+1 == packet_seq) + mdev->peer_seq++; + spin_unlock(&mdev->peer_seq_lock); + return ret; +} + +/* mirrored write */ +STATIC int receive_Data(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + sector_t sector; + struct Tl_epoch_entry *e; + struct Drbd_Data_Packet *p = (struct Drbd_Data_Packet *)h; + int header_size, data_size; + int rw = WRITE; + u32 dp_flags; + + /* FIXME merge this code dups into some helper function */ + header_size = sizeof(*p) - sizeof(*h); + data_size = h->length - header_size; + + ERR_IF(data_size == 0) return FALSE; + + if (drbd_recv(mdev, h->payload, header_size) != header_size) + return FALSE; + + if (!inc_local(mdev)) { + /* data is submitted to disk at the end of this function. + * corresponding dec_local done either below (on error), + * or in drbd_endio_write_sec. */ + if (DRBD_ratelimit(5*HZ, 5)) + ERR("Can not write mirrored data block " + "to local disk.\n"); + spin_lock(&mdev->peer_seq_lock); + if (mdev->peer_seq+1 == be32_to_cpu(p->seq_num)) + mdev->peer_seq++; + spin_unlock(&mdev->peer_seq_lock); + + drbd_send_ack_dp(mdev, NegAck, p); + atomic_inc(&mdev->current_epoch->epoch_size); + return drbd_drain_block(mdev, data_size); + } + + sector = be64_to_cpu(p->sector); + e = read_in_block(mdev, p->block_id, sector, data_size); + if (!e) { + dec_local(mdev); + return FALSE; + } + + e->private_bio->bi_end_io = drbd_endio_write_sec; + e->w.cb = e_end_block; + + spin_lock(&mdev->epoch_lock); + e->epoch = mdev->current_epoch; + atomic_inc(&e->epoch->epoch_size); + atomic_inc(&e->epoch->active); + + if (mdev->write_ordering == WO_bio_barrier && atomic_read(&e->epoch->epoch_size) == 1) { + struct drbd_epoch *epoch; + /* Issue a barrier if we start a new epoch, and the previous epoch + was not a epoch containing a single request which already was + a Barrier. */ + epoch = list_entry(e->epoch->list.prev, struct drbd_epoch, list); + if (epoch == e->epoch) { + MTRACE(TraceTypeEpochs, TraceLvlMetrics, + INFO("Add barrier %p/%d\n", + epoch, epoch->barrier_nr); + ); + set_bit(DE_CONTAINS_A_BARRIER, &e->epoch->flags); + rw |= (1<flags |= EE_IS_BARRIER; + } else { + if (atomic_read(&epoch->epoch_size) > 1 || + !test_bit(DE_CONTAINS_A_BARRIER, &epoch->flags)) { + MTRACE(TraceTypeEpochs, TraceLvlMetrics, + INFO("Add barrier %p/%d, setting bi in %p/%d\n", + e->epoch, e->epoch->barrier_nr, + epoch, epoch->barrier_nr); + ); + set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags); + set_bit(DE_CONTAINS_A_BARRIER, &e->epoch->flags); + rw |= (1<flags |= EE_IS_BARRIER; + } + } + } + spin_unlock(&mdev->epoch_lock); + + dp_flags = be32_to_cpu(p->dp_flags); + if (dp_flags & DP_HARDBARRIER) + rw |= (1<flags |= EE_MAY_SET_IN_SYNC; + + /* I'm the receiver, I do hold a net_cnt reference. */ + if (!mdev->net_conf->two_primaries) { + spin_lock_irq(&mdev->req_lock); + } else { + /* don't get the req_lock yet, + * we may sleep in drbd_wait_peer_seq */ + const int size = e->size; + const int discard = test_bit(DISCARD_CONCURRENT, &mdev->flags); + DEFINE_WAIT(wait); + struct drbd_request *i; + struct hlist_node *n; + struct hlist_head *slot; + int first; + + D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C); + BUG_ON(mdev->ee_hash == NULL); + BUG_ON(mdev->tl_hash == NULL); + + /* conflict detection and handling: + * 1. wait on the sequence number, + * in case this data packet overtook ACK packets. + * 2. check our hash tables for conflicting requests. + * we only need to walk the tl_hash, since an ee can not + * have a conflict with an other ee: on the submitting + * node, the corresponding req had already been conflicting, + * and a conflicting req is never sent. + * + * Note: for two_primaries, we are protocol C, + * so there cannot be any request that is DONE + * but still on the transfer log. + * + * unconditionally add to the ee_hash. + * + * if no conflicting request is found: + * submit. + * + * if any conflicting request is found + * that has not yet been acked, + * AND I have the "discard concurrent writes" flag: + * queue (via done_ee) the DiscardAck; OUT. + * + * if any conflicting request is found: + * block the receiver, waiting on misc_wait + * until no more conflicting requests are there, + * or we get interrupted (disconnect). + * + * we do not just write after local io completion of those + * requests, but only after req is done completely, i.e. + * we wait for the DiscardAck to arrive! + * + * then proceed normally, i.e. submit. + */ + if (drbd_wait_peer_seq(mdev, be32_to_cpu(p->seq_num))) + goto out_interrupted; + + spin_lock_irq(&mdev->req_lock); + + hlist_add_head(&e->colision, ee_hash_slot(mdev, sector)); + +#define OVERLAPS overlaps(i->sector, i->size, sector, size) + slot = tl_hash_slot(mdev, sector); + first = 1; + for (;;) { + int have_unacked = 0; + int have_conflict = 0; + prepare_to_wait(&mdev->misc_wait, &wait, + TASK_INTERRUPTIBLE); + hlist_for_each_entry(i, n, slot, colision) { + if (OVERLAPS) { + /* only ALERT on first iteration, + * we may be woken up early... */ + if (first) + ALERT("%s[%u] Concurrent local write detected!" + " new: %llus +%u; pending: %llus +%u\n", + current->comm, current->pid, + (unsigned long long)sector, size, + (unsigned long long)i->sector, i->size); + if (i->rq_state & RQ_NET_PENDING) + ++have_unacked; + ++have_conflict; + } + } +#undef OVERLAPS + if (!have_conflict) + break; + + /* Discard Ack only for the _first_ iteration */ + if (first && discard && have_unacked) { + ALERT("Concurrent write! [DISCARD BY FLAG] sec=%llus\n", + (unsigned long long)sector); + inc_unacked(mdev); + e->w.cb = e_send_discard_ack; + list_add_tail(&e->w.list, &mdev->done_ee); + + spin_unlock_irq(&mdev->req_lock); + + /* we could probably send that DiscardAck ourselves, + * but I don't like the receiver using the msock */ + + dec_local(mdev); + wake_asender(mdev); + finish_wait(&mdev->misc_wait, &wait); + return TRUE; + } + + if (signal_pending(current)) { + hlist_del_init(&e->colision); + + spin_unlock_irq(&mdev->req_lock); + + finish_wait(&mdev->misc_wait, &wait); + goto out_interrupted; + } + + spin_unlock_irq(&mdev->req_lock); + if (first) { + first = 0; + ALERT("Concurrent write! [W AFTERWARDS] " + "sec=%llus\n", (unsigned long long)sector); + } else if (discard) { + /* we had none on the first iteration. + * there must be none now. */ + D_ASSERT(have_unacked == 0); + } + schedule(); + spin_lock_irq(&mdev->req_lock); + } + finish_wait(&mdev->misc_wait, &wait); + } + + list_add(&e->w.list, &mdev->active_ee); + spin_unlock_irq(&mdev->req_lock); + + switch (mdev->net_conf->wire_protocol) { + case DRBD_PROT_C: + inc_unacked(mdev); + /* corresponding dec_unacked() in e_end_block() + * respective _drbd_clear_done_ee */ + break; + case DRBD_PROT_B: + /* I really don't like it that the receiver thread + * sends on the msock, but anyways */ + drbd_send_ack(mdev, RecvAck, e); + break; + case DRBD_PROT_A: + /* nothing to do */ + break; + } + + if (mdev->state.pdsk == Diskless) { + /* In case we have the only disk of the cluster, */ + drbd_set_out_of_sync(mdev, e->sector, e->size); + e->flags |= EE_CALL_AL_COMPLETE_IO; + drbd_al_begin_io(mdev, e->sector); + } + + MTRACE(TraceTypeEE, TraceLvlAll, + INFO("submit EE (DATA)WRITE sec=%llus size=%u ee=%p\n", + (unsigned long long)e->sector, e->size, e); + ); + /* FIXME drbd_al_begin_io in case we have two primaries... */ + e->private_bio->bi_rw = rw; + dump_internal_bio("Sec", mdev, e->private_bio, 0); + drbd_generic_make_request(mdev, DRBD_FAULT_DT_WR, e->private_bio); + /* accounting done in endio */ + + maybe_kick_lo(mdev); + return TRUE; + +out_interrupted: + /* yes, the epoch_size now is imbalanced. + * but we drop the connection anyways, so we don't have a chance to + * receive a barrier... atomic_inc(&mdev->epoch_size); */ + dec_local(mdev); + drbd_free_ee(mdev, e); + return FALSE; +} + +STATIC int receive_DataRequest(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + sector_t sector; + const sector_t capacity = drbd_get_capacity(mdev->this_bdev); + struct Tl_epoch_entry *e; + struct digest_info *di; + int size,digest_size; + unsigned int fault_type; + struct Drbd_BlockRequest_Packet *p = + (struct Drbd_BlockRequest_Packet *)h; + const int brps = sizeof(*p)-sizeof(*h); + + if (drbd_recv(mdev, h->payload, brps) != brps) + return FALSE; + + sector = be64_to_cpu(p->sector); + size = be32_to_cpu(p->blksize); + + if (size <= 0 || (size & 0x1ff) != 0 || size > DRBD_MAX_SEGMENT_SIZE) { + ERR("%s:%d: sector: %llus, size: %u\n", __FILE__, __LINE__, + (unsigned long long)sector, size); + return FALSE; + } + if (sector + (size>>9) > capacity) { + ERR("%s:%d: sector: %llus, size: %u\n", __FILE__, __LINE__, + (unsigned long long)sector, size); + return FALSE; + } + + if (!inc_local_if_state(mdev, UpToDate)) { + if (DRBD_ratelimit(5*HZ, 5)) + ERR("Can not satisfy peer's read request, " + "no local data.\n"); + drbd_send_ack_rp(mdev, h->command == DataRequest ? NegDReply : + NegRSDReply , p); + return TRUE; + } + + e = drbd_alloc_ee(mdev, p->block_id, sector, size, GFP_KERNEL); + if (!e) { + dec_local(mdev); + return FALSE; + } + + /* FIXME actually, it could be a READA originating from the peer, + * also it could have set some flags (e.g. BIO_RW_SYNC) ... */ + e->private_bio->bi_rw = READ; + e->private_bio->bi_end_io = drbd_endio_read_sec; + + switch (h->command) { + case DataRequest: + e->w.cb = w_e_end_data_req; + fault_type = DRBD_FAULT_DT_RD; + break; + case RSDataRequest: + e->w.cb = w_e_end_rsdata_req; + fault_type = DRBD_FAULT_RS_RD; + /* Eventually this should become asynchrously. Currently it + * blocks the whole receiver just to delay the reading of a + * resync data block. + * the drbd_work_queue mechanism is made for this... + */ + if (!drbd_rs_begin_io(mdev, sector)) { + /* we have been interrupted, + * probably connection lost! */ + D_ASSERT(signal_pending(current)); + dec_local(mdev); + drbd_free_ee(mdev, e); + return 0; + } + break; + + case OVReply: + case CsumRSRequest: + fault_type = DRBD_FAULT_RS_RD; + digest_size = h->length - brps ; + di = kmalloc(sizeof(*di) + digest_size ,GFP_KERNEL); + if (!di) { + dec_local(mdev); + drbd_free_ee(mdev,e); + return 0; + } + + di->digest_size = digest_size; + di->digest = (((char *)di)+sizeof(struct digest_info)); + + if (drbd_recv(mdev, di->digest, digest_size) != digest_size) { + dec_local(mdev); + drbd_free_ee(mdev,e); + kfree(di); + return FALSE; + } + + e->block_id = (u64)(unsigned long)di; + if (h->command == CsumRSRequest) { + D_ASSERT(mdev->agreed_pro_version >= 89); + e->w.cb = w_e_end_csum_rs_req; + } else if (h->command == OVReply) { + e->w.cb = w_e_end_ov_reply; + dec_rs_pending(mdev); + break; + } + + if (!drbd_rs_begin_io(mdev,sector)) { + // we have been interrupted, probably connection lost! + D_ASSERT(signal_pending(current)); + drbd_free_ee(mdev,e); + kfree(di); + dec_local(mdev); + return FALSE; + } + break; + + case OVRequest: + e->w.cb = w_e_end_ov_req; + fault_type = DRBD_FAULT_RS_RD; + /* Eventually this should become asynchrously. Currently it + * blocks the whole receiver just to delay the reading of a + * resync data block. + * the drbd_work_queue mechanism is made for this... + */ + if (!drbd_rs_begin_io(mdev,sector)) { + /* we have been interrupted, + * probably connection lost! */ + D_ASSERT(signal_pending(current)); + dec_local(mdev); + drbd_free_ee(mdev,e); + return 0; + } + break; + + + default: + ERR("unexpected command (%s) in receive_DataRequest\n", + cmdname(h->command)); + fault_type = DRBD_FAULT_MAX; + } + + spin_lock_irq(&mdev->req_lock); + list_add(&e->w.list, &mdev->read_ee); + spin_unlock_irq(&mdev->req_lock); + + inc_unacked(mdev); + + MTRACE(TraceTypeEE, TraceLvlAll, + INFO("submit EE READ sec=%llus size=%u ee=%p\n", + (unsigned long long)e->sector, e->size, e); + ); + + dump_internal_bio("Sec", mdev, e->private_bio, 0); + drbd_generic_make_request(mdev, fault_type, e->private_bio); + maybe_kick_lo(mdev); + + return TRUE; +} + +STATIC int drbd_asb_recover_0p(struct drbd_conf *mdev) __must_hold(local) +{ + int self, peer, rv = -100; + unsigned long ch_self, ch_peer; + + self = mdev->bc->md.uuid[Bitmap] & 1; + peer = mdev->p_uuid[Bitmap] & 1; + + ch_peer = mdev->p_uuid[UUID_SIZE]; + ch_self = mdev->comm_bm_set; + + switch (mdev->net_conf->after_sb_0p) { + case Consensus: + case DiscardSecondary: + case CallHelper: + ERR("Configuration error.\n"); + break; + case Disconnect: + break; + case DiscardYoungerPri: + if (self == 0 && peer == 1) { rv = -1; break; } + if (self == 1 && peer == 0) { rv = 1; break; } + /* Else fall through to one of the other strategies... */ + case DiscardOlderPri: + if (self == 0 && peer == 1) { rv = 1; break; } + if (self == 1 && peer == 0) { rv = -1; break; } + /* Else fall through to one of the other strategies... */ + drbd_WARN("Discard younger/older primary did not found a decision\n" + "Using discard-least-changes instead\n"); + case DiscardZeroChg: + if (ch_peer == 0 && ch_self == 0) { + rv = test_bit(DISCARD_CONCURRENT, &mdev->flags) + ? -1 : 1; + break; + } else { + if (ch_peer == 0) { rv = 1; break; } + if (ch_self == 0) { rv = -1; break; } + } + if (mdev->net_conf->after_sb_0p == DiscardZeroChg) + break; + case DiscardLeastChg: + if (ch_self < ch_peer) + rv = -1; + else if (ch_self > ch_peer) + rv = 1; + else /* ( ch_self == ch_peer ) */ + /* Well, then use something else. */ + rv = test_bit(DISCARD_CONCURRENT, &mdev->flags) + ? -1 : 1; + break; + case DiscardLocal: + rv = -1; + break; + case DiscardRemote: + rv = 1; + } + + return rv; +} + +STATIC int drbd_asb_recover_1p(struct drbd_conf *mdev) __must_hold(local) +{ + int self, peer, hg, rv = -100; + + self = mdev->bc->md.uuid[Bitmap] & 1; + peer = mdev->p_uuid[Bitmap] & 1; + + switch (mdev->net_conf->after_sb_1p) { + case DiscardYoungerPri: + case DiscardOlderPri: + case DiscardLeastChg: + case DiscardLocal: + case DiscardRemote: + ERR("Configuration error.\n"); + break; + case Disconnect: + break; + case Consensus: + hg = drbd_asb_recover_0p(mdev); + if (hg == -1 && mdev->state.role == Secondary) + rv = hg; + if (hg == 1 && mdev->state.role == Primary) + rv = hg; + break; + case Violently: + rv = drbd_asb_recover_0p(mdev); + break; + case DiscardSecondary: + return mdev->state.role == Primary ? 1 : -1; + case CallHelper: + hg = drbd_asb_recover_0p(mdev); + if (hg == -1 && mdev->state.role == Primary) { + self = drbd_set_role(mdev, Secondary, 0); + if (self != SS_Success) { + drbd_khelper(mdev, "pri-lost-after-sb"); + } else { + drbd_WARN("Sucessfully gave up primary role.\n"); + rv = hg; + } + } else + rv = hg; + } + + return rv; +} + +STATIC int drbd_asb_recover_2p(struct drbd_conf *mdev) __must_hold(local) +{ + int self, peer, hg, rv = -100; + + self = mdev->bc->md.uuid[Bitmap] & 1; + peer = mdev->p_uuid[Bitmap] & 1; + + switch (mdev->net_conf->after_sb_2p) { + case DiscardYoungerPri: + case DiscardOlderPri: + case DiscardLeastChg: + case DiscardLocal: + case DiscardRemote: + case Consensus: + case DiscardSecondary: + ERR("Configuration error.\n"); + break; + case Violently: + rv = drbd_asb_recover_0p(mdev); + break; + case Disconnect: + break; + case CallHelper: + hg = drbd_asb_recover_0p(mdev); + if (hg == -1) { + self = drbd_set_role(mdev, Secondary, 0); + if (self != SS_Success) { + drbd_khelper(mdev, "pri-lost-after-sb"); + } else { + drbd_WARN("Sucessfully gave up primary role.\n"); + rv = hg; + } + } else + rv = hg; + } + + return rv; +} + +STATIC void drbd_uuid_dump(struct drbd_conf *mdev, char *text, u64 *uuid) +{ + if (!uuid) { + INFO("%s uuid info vanished while I was looking!\n", text); + return; + } + INFO("%s %016llX:%016llX:%016llX:%016llX\n", + text, + (unsigned long long)uuid[Current], + (unsigned long long)uuid[Bitmap], + (unsigned long long)uuid[History_start], + (unsigned long long)uuid[History_end]); +} + +/* + 100 after split brain try auto recover + 2 SyncSource set BitMap + 1 SyncSource use BitMap + 0 no Sync + -1 SyncTarget use BitMap + -2 SyncTarget set BitMap + -100 after split brain, disconnect +-1000 unrelated data + */ +STATIC int drbd_uuid_compare(struct drbd_conf *mdev, int *rule_nr) __must_hold(local) +{ + u64 self, peer; + int i, j; + + self = mdev->bc->md.uuid[Current] & ~((u64)1); + peer = mdev->p_uuid[Current] & ~((u64)1); + + *rule_nr = 1; + if (self == UUID_JUST_CREATED && + peer == UUID_JUST_CREATED) return 0; + + *rule_nr = 2; + if ((self == UUID_JUST_CREATED || self == (u64)0) && + peer != UUID_JUST_CREATED) return -2; + + *rule_nr = 3; + if ( self != UUID_JUST_CREATED && + (peer == UUID_JUST_CREATED || peer == (u64)0)) return 2; + + *rule_nr = 4; + if (self == peer) { /* Common power [off|failure] */ + int rct, dc; /* roles at crash time */ + + rct = (test_bit(CRASHED_PRIMARY, &mdev->flags) ? 1 : 0) + + (mdev->p_uuid[UUID_FLAGS] & 2); + /* lowest bit is set when we were primary, + * next bit (weight 2) is set when peer was primary */ + + MTRACE(TraceTypeUuid, TraceLvlMetrics, DUMPI(rct); ); + + switch (rct) { + case 0: /* !self_pri && !peer_pri */ return 0; + case 1: /* self_pri && !peer_pri */ return 1; + case 2: /* !self_pri && peer_pri */ return -1; + case 3: /* self_pri && peer_pri */ + dc = test_bit(DISCARD_CONCURRENT, &mdev->flags); + MTRACE(TraceTypeUuid, TraceLvlMetrics, DUMPI(dc); ); + return dc ? -1 : 1; + } + } + + *rule_nr = 5; + peer = mdev->p_uuid[Bitmap] & ~((u64)1); + if (self == peer) + return -1; + + *rule_nr = 6; + for (i = History_start; i <= History_end; i++) { + peer = mdev->p_uuid[i] & ~((u64)1); + if (self == peer) + return -2; + } + + *rule_nr = 7; + self = mdev->bc->md.uuid[Bitmap] & ~((u64)1); + peer = mdev->p_uuid[Current] & ~((u64)1); + if (self == peer) + return 1; + + *rule_nr = 8; + for (i = History_start; i <= History_end; i++) { + self = mdev->bc->md.uuid[i] & ~((u64)1); + if (self == peer) + return 2; + } + + *rule_nr = 9; + self = mdev->bc->md.uuid[Bitmap] & ~((u64)1); + peer = mdev->p_uuid[Bitmap] & ~((u64)1); + if (self == peer && self != ((u64)0)) + return 100; + + *rule_nr = 10; + for (i = History_start; i <= History_end; i++) { + self = mdev->p_uuid[i] & ~((u64)1); + for (j = History_start; j <= History_end; j++) { + peer = mdev->p_uuid[j] & ~((u64)1); + if (self == peer) + return -100; + } + } + + return -1000; +} + +/* drbd_sync_handshake() returns the new conn state on success, or + conn_mask (-1) on failure. + */ +STATIC enum drbd_conns drbd_sync_handshake(struct drbd_conf *mdev, enum drbd_role peer_role, + enum drbd_disk_state peer_disk) __must_hold(local) +{ + int hg, rule_nr; + enum drbd_conns rv = conn_mask; + enum drbd_disk_state mydisk; + + mydisk = mdev->state.disk; + if (mydisk == Negotiating) + mydisk = mdev->new_state_tmp.disk; + + hg = drbd_uuid_compare(mdev, &rule_nr); + + INFO("drbd_sync_handshake:\n"); + drbd_uuid_dump(mdev, "self", mdev->bc->md.uuid); + drbd_uuid_dump(mdev, "peer", mdev->p_uuid); + INFO("uuid_compare()=%d by rule %d\n", hg, rule_nr); + + if (hg == -1000) { + ALERT("Unrelated data, aborting!\n"); + return conn_mask; + } + + if ( (mydisk == Inconsistent && peer_disk > Inconsistent) || + (peer_disk == Inconsistent && mydisk > Inconsistent)) { + int f = (hg == -100) || abs(hg) == 2; + hg = mydisk > Inconsistent ? 1 : -1; + if (f) + hg = hg*2; + INFO("Becoming sync %s due to disk states.\n", + hg > 0 ? "source" : "target"); + } + + if (hg == 100 || (hg == -100 && mdev->net_conf->always_asbp)) { + int pcount = (mdev->state.role == Primary) + + (peer_role == Primary); + int forced = (hg == -100); + + switch (pcount) { + case 0: + hg = drbd_asb_recover_0p(mdev); + break; + case 1: + hg = drbd_asb_recover_1p(mdev); + break; + case 2: + hg = drbd_asb_recover_2p(mdev); + break; + } + if (abs(hg) < 100) { + drbd_WARN("Split-Brain detected, %d primaries, " + "automatically solved. Sync from %s node\n", + pcount, (hg < 0) ? "peer" : "this"); + if (forced) { + drbd_WARN("Doing a full sync, since" + " UUIDs where ambiguous.\n"); + drbd_uuid_dump(mdev, "self", mdev->bc->md.uuid); + drbd_uuid_dump(mdev, "peer", mdev->p_uuid); + hg = hg*2; + } + } + } + + if (hg == -100) { + if (mdev->net_conf->want_lose && !(mdev->p_uuid[UUID_FLAGS]&1)) + hg = -1; + if (!mdev->net_conf->want_lose && (mdev->p_uuid[UUID_FLAGS]&1)) + hg = 1; + + if (abs(hg) < 100) + drbd_WARN("Split-Brain detected, manually solved. " + "Sync from %s node\n", + (hg < 0) ? "peer" : "this"); + } + + if (hg == -100) { + ALERT("Split-Brain detected, dropping connection!\n"); + drbd_uuid_dump(mdev, "self", mdev->bc->md.uuid); + drbd_uuid_dump(mdev, "peer", mdev->p_uuid); + drbd_khelper(mdev, "split-brain"); + return conn_mask; + } + + if (hg > 0 && mydisk <= Inconsistent) { + ERR("I shall become SyncSource, but I am inconsistent!\n"); + return conn_mask; + } + + if (hg < 0 && /* by intention we do not use mydisk here. */ + mdev->state.role == Primary && mdev->state.disk >= Consistent) { + switch (mdev->net_conf->rr_conflict) { + case CallHelper: + drbd_khelper(mdev, "pri-lost"); + /* fall through */ + case Disconnect: + ERR("I shall become SyncTarget, but I am primary!\n"); + return conn_mask; + case Violently: + drbd_WARN("Becoming SyncTarget, violating the stable-data" + "assumption\n"); + } + } + + if (abs(hg) >= 2) { + INFO("Writing the whole bitmap, full sync required after drbd_sync_handshake.\n"); + if (drbd_bitmap_io(mdev, &drbd_bmio_set_n_write, "set_n_write from sync_handshake")) + return conn_mask; + } + + if (hg > 0) { /* become sync source. */ + rv = WFBitMapS; + } else if (hg < 0) { /* become sync target */ + rv = WFBitMapT; + } else { + rv = Connected; + if (drbd_bm_total_weight(mdev)) { + INFO("No resync, but %lu bits in bitmap!\n", + drbd_bm_total_weight(mdev)); + } + } + + drbd_bm_recount_bits(mdev); + + return rv; +} + +/* returns 1 if invalid */ +STATIC int cmp_after_sb(enum after_sb_handler peer, enum after_sb_handler self) +{ + /* DiscardRemote - DiscardLocal is valid */ + if ((peer == DiscardRemote && self == DiscardLocal) || + (self == DiscardRemote && peer == DiscardLocal)) + return 0; + + /* any other things with DiscardRemote or DiscardLocal are invalid */ + if (peer == DiscardRemote || peer == DiscardLocal || + self == DiscardRemote || self == DiscardLocal) + return 1; + + /* everything else is valid if they are equal on both sides. */ + if (peer == self) + return 0; + + /* everything es is invalid. */ + return 1; +} + +STATIC int receive_protocol(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + struct Drbd_Protocol_Packet *p = (struct Drbd_Protocol_Packet *)h; + int header_size, data_size; + int p_proto, p_after_sb_0p, p_after_sb_1p, p_after_sb_2p; + int p_want_lose, p_two_primaries; + char p_integrity_alg[SHARED_SECRET_MAX] = ""; + + header_size = sizeof(*p) - sizeof(*h); + data_size = h->length - header_size; + + if (drbd_recv(mdev, h->payload, header_size) != header_size) + return FALSE; + + p_proto = be32_to_cpu(p->protocol); + p_after_sb_0p = be32_to_cpu(p->after_sb_0p); + p_after_sb_1p = be32_to_cpu(p->after_sb_1p); + p_after_sb_2p = be32_to_cpu(p->after_sb_2p); + p_want_lose = be32_to_cpu(p->want_lose); + p_two_primaries = be32_to_cpu(p->two_primaries); + + if (p_proto != mdev->net_conf->wire_protocol) { + ERR("incompatible communication protocols\n"); + goto disconnect; + } + + if (cmp_after_sb(p_after_sb_0p, mdev->net_conf->after_sb_0p)) { + ERR("incompatible after-sb-0pri settings\n"); + goto disconnect; + } + + if (cmp_after_sb(p_after_sb_1p, mdev->net_conf->after_sb_1p)) { + ERR("incompatible after-sb-1pri settings\n"); + goto disconnect; + } + + if (cmp_after_sb(p_after_sb_2p, mdev->net_conf->after_sb_2p)) { + ERR("incompatible after-sb-2pri settings\n"); + goto disconnect; + } + + if (p_want_lose && mdev->net_conf->want_lose) { + ERR("both sides have the 'want_lose' flag set\n"); + goto disconnect; + } + + if (p_two_primaries != mdev->net_conf->two_primaries) { + ERR("incompatible setting of the two-primaries options\n"); + goto disconnect; + } + + if (mdev->agreed_pro_version >= 87) { + unsigned char *my_alg = mdev->net_conf->integrity_alg; + + if (drbd_recv(mdev, p_integrity_alg, data_size) != data_size) + return FALSE; + + p_integrity_alg[SHARED_SECRET_MAX-1] = 0; + if (strcmp(p_integrity_alg, my_alg)) { + ERR("incompatible setting of the data-integrity-alg\n"); + goto disconnect; + } + INFO("data-integrity-alg: %s\n", + my_alg[0] ? my_alg : (unsigned char *)""); + } + + return TRUE; + +disconnect: + drbd_force_state(mdev, NS(conn, Disconnecting)); + return FALSE; +} + +/* helper function + * input: alg name, feature name + * return: NULL (alg name was "") + * ERR_PTR(error) if something goes wrong + * or the crypto hash ptr, if it worked out ok. */ +struct crypto_hash *drbd_crypto_alloc_digest_safe(const struct drbd_conf *mdev, + const char *alg, const char *name) +{ + struct crypto_hash *tfm; + + if (!alg[0]) + return NULL; + + tfm = crypto_alloc_hash(alg, 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(tfm)) { + ERR("Can not allocate \"%s\" as %s (reason: %ld)\n", + alg, name, PTR_ERR(tfm)); + return tfm; + } + if (crypto_tfm_alg_type(crypto_hash_tfm(tfm)) != CRYPTO_ALG_TYPE_DIGEST) { + crypto_free_hash(tfm); + ERR("\"%s\" is not a digest (%s)\n", alg, name); + return ERR_PTR(-EINVAL); + } + return tfm; +} + +STATIC int receive_SyncParam(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + int ok = TRUE; + struct Drbd_SyncParam89_Packet *p = (struct Drbd_SyncParam89_Packet *)h; + unsigned int header_size, data_size, exp_max_sz; + struct crypto_hash *verify_tfm = NULL; + struct crypto_hash *csums_tfm = NULL; + const int apv = mdev->agreed_pro_version; + + exp_max_sz = apv <= 87 ? sizeof(struct Drbd_SyncParam_Packet) + : apv == 88 ? sizeof(struct Drbd_SyncParam_Packet) + + SHARED_SECRET_MAX + : /* 89 */ sizeof(struct Drbd_SyncParam89_Packet); + + if (h->length > exp_max_sz) { + ERR("SyncParam packet too long: received %u, expected <= %u bytes\n", + h->length, exp_max_sz); + return FALSE; + } + + if (apv <= 88) { + header_size = sizeof(struct Drbd_SyncParam_Packet) - sizeof(*h); + data_size = h->length - header_size; + } else /* apv >= 89 */ { + header_size = sizeof(struct Drbd_SyncParam89_Packet) - sizeof(*h); + data_size = h->length - header_size; + D_ASSERT(data_size == 0); + } + + /* initialize verify_alg and csums_alg */ + memset(p->verify_alg, 0, 2 * SHARED_SECRET_MAX); + + if (drbd_recv(mdev, h->payload, header_size) != header_size) + return FALSE; + + mdev->sync_conf.rate = be32_to_cpu(p->rate); + + if (apv >= 88) { + if (apv == 88) { + if (data_size > SHARED_SECRET_MAX) { + ERR("verify-alg too long, " + "peer wants %u, accepting only %u byte\n", + data_size, SHARED_SECRET_MAX); + return FALSE; + } + + if (drbd_recv(mdev, p->verify_alg, data_size) != data_size) + return FALSE; + + /* we expect NUL terminated string */ + /* but just in case someone tries to be evil */ + D_ASSERT(p->verify_alg[data_size-1] == 0); + p->verify_alg[data_size-1] = 0; + + } else /* apv >= 89 */ { + /* we still expect NUL terminated strings */ + /* but just in case someone tries to be evil */ + D_ASSERT(p->verify_alg[SHARED_SECRET_MAX-1] == 0); + D_ASSERT(p->csums_alg[SHARED_SECRET_MAX-1] == 0); + p->verify_alg[SHARED_SECRET_MAX-1] = 0; + p->csums_alg[SHARED_SECRET_MAX-1] = 0; + } + + if (strcmp(mdev->sync_conf.verify_alg, p->verify_alg)) { + if (mdev->state.conn == WFReportParams) { + ERR("Different verify-alg settings. me=\"%s\" peer=\"%s\"\n", + mdev->sync_conf.verify_alg, p->verify_alg); + goto disconnect; + } + verify_tfm = drbd_crypto_alloc_digest_safe(mdev, + p->verify_alg, "verify-alg"); + if (IS_ERR(verify_tfm)) + goto disconnect; + } + + if (apv >= 89 && strcmp(mdev->sync_conf.csums_alg, p->csums_alg)) { + if (mdev->state.conn == WFReportParams) { + ERR("Different csums-alg settings. me=\"%s\" peer=\"%s\"\n", + mdev->sync_conf.csums_alg, p->csums_alg); + goto disconnect; + } + csums_tfm = drbd_crypto_alloc_digest_safe(mdev, + p->csums_alg, "csums-alg"); + if (IS_ERR(csums_tfm)) + goto disconnect; + } + + + spin_lock(&mdev->peer_seq_lock); + /* lock against drbd_nl_syncer_conf() */ + if (verify_tfm) { + strcpy(mdev->sync_conf.verify_alg, p->verify_alg); + mdev->sync_conf.verify_alg_len = strlen(p->verify_alg) + 1; + crypto_free_hash(mdev->verify_tfm); + mdev->verify_tfm = verify_tfm; + INFO("using verify-alg: \"%s\"\n", p->verify_alg); + } + if (csums_tfm) { + strcpy(mdev->sync_conf.csums_alg, p->csums_alg); + mdev->sync_conf.csums_alg_len = strlen(p->csums_alg) + 1; + crypto_free_hash(mdev->csums_tfm); + mdev->csums_tfm = csums_tfm; + INFO("using csums-alg: \"%s\"\n", p->csums_alg); + } + spin_unlock(&mdev->peer_seq_lock); + } + + return ok; +disconnect: + crypto_free_hash(verify_tfm); + drbd_force_state(mdev, NS(conn, Disconnecting)); + return FALSE; +} + +STATIC void drbd_setup_order_type(struct drbd_conf *mdev, int peer) +{ + /* sorry, we currently have no working implementation + * of distributed TCQ */ +} + +/* warn if the arguments differ by more than 12.5% */ +static void warn_if_differ_considerably(struct drbd_conf *mdev, + const char *s, sector_t a, sector_t b) +{ + sector_t d; + if (a == 0 || b == 0) + return; + d = (a > b) ? (a - b) : (b - a); + if (d > (a>>3) || d > (b>>3)) + drbd_WARN("Considerable difference in %s: %llus vs. %llus\n", s, + (unsigned long long)a, (unsigned long long)b); +} + +STATIC int receive_sizes(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + struct Drbd_Sizes_Packet *p = (struct Drbd_Sizes_Packet *)h; + enum determin_dev_size_enum dd = unchanged; + unsigned int max_seg_s; + sector_t p_size, p_usize, my_usize; + int ldsc = 0; /* local disk size changed */ + enum drbd_conns nconn; + + ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE; + if (drbd_recv(mdev, h->payload, h->length) != h->length) + return FALSE; + + p_size = be64_to_cpu(p->d_size); + p_usize = be64_to_cpu(p->u_size); + + if (p_size == 0 && mdev->state.disk == Diskless) { + ERR("some backing storage is needed\n"); + drbd_force_state(mdev, NS(conn, Disconnecting)); + return FALSE; + } + + /* just store the peer's disk size for now. + * we still need to figure out wether we accept that. */ + mdev->p_size = p_size; + +#define min_not_zero(l, r) (l == 0) ? r : ((r == 0) ? l : min(l, r)) + if (inc_local(mdev)) { + warn_if_differ_considerably(mdev, "lower level device sizes", + p_size, drbd_get_max_capacity(mdev->bc)); + warn_if_differ_considerably(mdev, "user requested size", + p_usize, mdev->bc->dc.disk_size); + + /* if this is the first connect, or an otherwise expected + * param exchange, choose the minimum */ + if (mdev->state.conn == WFReportParams) + p_usize = min_not_zero((sector_t)mdev->bc->dc.disk_size, + p_usize); + + my_usize = mdev->bc->dc.disk_size; + + if (mdev->bc->dc.disk_size != p_usize) { + mdev->bc->dc.disk_size = p_usize; + INFO("Peer sets u_size to %lu sectors\n", + (unsigned long)mdev->bc->dc.disk_size); + } + + /* Never shrink a device with usable data during connect. + But allow online shrinking if we are connected. */ + if (drbd_new_dev_size(mdev, mdev->bc) < + drbd_get_capacity(mdev->this_bdev) && + mdev->state.disk >= Outdated && + mdev->state.conn < Connected) { + ERR("The peer's disk size is too small!\n"); + drbd_force_state(mdev, NS(conn, Disconnecting)); + mdev->bc->dc.disk_size = my_usize; + dec_local(mdev); + return FALSE; + } + dec_local(mdev); + } +#undef min_not_zero + + if (inc_local(mdev)) { + dd = drbd_determin_dev_size(mdev); + dec_local(mdev); + if (dd == dev_size_error) + return FALSE; + drbd_md_sync(mdev); + } else { + /* I am diskless, need to accept the peer's size. */ + drbd_set_my_capacity(mdev, p_size); + } + + if (mdev->p_uuid && mdev->state.conn <= Connected && inc_local(mdev)) { + nconn = drbd_sync_handshake(mdev, + mdev->state.peer, mdev->state.pdsk); + dec_local(mdev); + + if (nconn == conn_mask) { + drbd_force_state(mdev, NS(conn, Disconnecting)); + return FALSE; + } + + if (drbd_request_state(mdev, NS(conn, nconn)) < SS_Success) { + drbd_force_state(mdev, NS(conn, Disconnecting)); + return FALSE; + } + } + + if (inc_local(mdev)) { + if (mdev->bc->known_size != drbd_get_capacity(mdev->bc->backing_bdev)) { + mdev->bc->known_size = drbd_get_capacity(mdev->bc->backing_bdev); + ldsc = 1; + } + + max_seg_s = be32_to_cpu(p->max_segment_size); + if (max_seg_s != mdev->rq_queue->max_segment_size) + drbd_setup_queue_param(mdev, max_seg_s); + + drbd_setup_order_type(mdev, be32_to_cpu(p->queue_order_type)); + dec_local(mdev); + } + + if (mdev->state.conn > WFReportParams) { + if (be64_to_cpu(p->c_size) != + drbd_get_capacity(mdev->this_bdev) || ldsc) { + /* we have different sizes, probabely peer + * needs to know my new size... */ + drbd_send_sizes(mdev); + } + if (dd == grew && mdev->state.conn == Connected) { + if (mdev->state.pdsk >= Inconsistent && + mdev->state.disk >= Inconsistent) + resync_after_online_grow(mdev); + else + set_bit(RESYNC_AFTER_NEG, &mdev->flags); + } + } + + return TRUE; +} + +STATIC int receive_uuids(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + struct Drbd_GenCnt_Packet *p = (struct Drbd_GenCnt_Packet *)h; + u64 *p_uuid; + int i; + + ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE; + if (drbd_recv(mdev, h->payload, h->length) != h->length) + return FALSE; + + p_uuid = kmalloc(sizeof(u64)*EXT_UUID_SIZE, GFP_KERNEL); + + for (i = Current; i < EXT_UUID_SIZE; i++) + p_uuid[i] = be64_to_cpu(p->uuid[i]); + + kfree(mdev->p_uuid); + mdev->p_uuid = p_uuid; + + if (mdev->state.conn < Connected && + mdev->state.disk < Inconsistent && + mdev->state.role == Primary && + (mdev->ed_uuid & ~((u64)1)) != (p_uuid[Current] & ~((u64)1))) { + ERR("Can only connect to data with current UUID=%016llX\n", + (unsigned long long)mdev->ed_uuid); + drbd_force_state(mdev, NS(conn, Disconnecting)); + return FALSE; + } + + /* Before we test for the disk state, we should wait until an eventually + ongoing cluster wide state change is finished. That is important if + we are primary and are detaching from our disk. We need to see the + new disk state... */ + wait_event(mdev->misc_wait, !test_bit(CLUSTER_ST_CHANGE, &mdev->flags)); + if (mdev->state.conn >= Connected && mdev->state.disk < Inconsistent) + drbd_set_ed_uuid(mdev, p_uuid[Current]); + + return TRUE; +} + +/** + * convert_state: + * Switches the view of the state. + */ +STATIC union drbd_state_t convert_state(union drbd_state_t ps) +{ + union drbd_state_t ms; + + static enum drbd_conns c_tab[] = { + [Connected] = Connected, + + [StartingSyncS] = StartingSyncT, + [StartingSyncT] = StartingSyncS, + [Disconnecting] = TearDown, /* NetworkFailure, */ + [VerifyS] = VerifyT, + [conn_mask] = conn_mask, + }; + + ms.i = ps.i; + + ms.conn = c_tab[ps.conn]; + ms.peer = ps.role; + ms.role = ps.peer; + ms.pdsk = ps.disk; + ms.disk = ps.pdsk; + ms.peer_isp = (ps.aftr_isp | ps.user_isp); + + return ms; +} + +STATIC int receive_req_state(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + struct Drbd_Req_State_Packet *p = (struct Drbd_Req_State_Packet *)h; + union drbd_state_t mask, val; + int rv; + + ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE; + if (drbd_recv(mdev, h->payload, h->length) != h->length) + return FALSE; + + mask.i = be32_to_cpu(p->mask); + val.i = be32_to_cpu(p->val); + + if (test_bit(DISCARD_CONCURRENT, &mdev->flags) && + test_bit(CLUSTER_ST_CHANGE, &mdev->flags)) { + drbd_send_sr_reply(mdev, SS_ConcurrentStChg); + return TRUE; + } + + mask = convert_state(mask); + val = convert_state(val); + + DRBD_STATE_DEBUG_INIT_VAL(val); + rv = drbd_change_state(mdev, ChgStateVerbose, mask, val); + + drbd_send_sr_reply(mdev, rv); + drbd_md_sync(mdev); + + return TRUE; +} + +STATIC int receive_state(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + struct Drbd_State_Packet *p = (struct Drbd_State_Packet *)h; + enum drbd_conns nconn, oconn; + union drbd_state_t ns, peer_state; + enum drbd_disk_state real_peer_disk; + int rv; + + ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) + return FALSE; + + if (drbd_recv(mdev, h->payload, h->length) != h->length) + return FALSE; + + peer_state.i = be32_to_cpu(p->state); + + real_peer_disk = peer_state.disk; + if (peer_state.disk == Negotiating) { + real_peer_disk = mdev->p_uuid[UUID_FLAGS] & 4 ? Inconsistent : Consistent; + INFO("real peer disk state = %s\n", disks_to_name(real_peer_disk)); + } + + spin_lock_irq(&mdev->req_lock); + retry: + oconn = nconn = mdev->state.conn; + spin_unlock_irq(&mdev->req_lock); + + if (nconn == WFReportParams) + nconn = Connected; + + if (mdev->p_uuid && peer_state.disk >= Negotiating && + inc_local_if_state(mdev, Negotiating)) { + int cr; /* consider resync */ + + cr = (oconn < Connected); + cr |= (oconn == Connected && + (peer_state.disk == Negotiating || + mdev->state.disk == Negotiating)); + cr |= test_bit(CONSIDER_RESYNC, &mdev->flags); /* peer forced */ + cr |= (oconn == Connected && peer_state.conn > Connected); + + if (cr) + nconn = drbd_sync_handshake(mdev, peer_state.role, real_peer_disk); + + dec_local(mdev); + if (nconn == conn_mask) { + if (mdev->state.disk == Negotiating) { + drbd_force_state(mdev, NS(disk, Diskless)); + nconn = Connected; + } else if (peer_state.disk == Negotiating) { + ERR("Disk attach process on the peer node was aborted.\n"); + peer_state.disk = Diskless; + } else { + D_ASSERT(oconn == WFReportParams); + drbd_force_state(mdev, NS(conn, Disconnecting)); + return FALSE; + } + } + } + + spin_lock_irq(&mdev->req_lock); + if (mdev->state.conn != oconn) + goto retry; + clear_bit(CONSIDER_RESYNC, &mdev->flags); + ns.i = mdev->state.i; + ns.conn = nconn; + ns.peer = peer_state.role; + ns.pdsk = real_peer_disk; + ns.peer_isp = (peer_state.aftr_isp | peer_state.user_isp); + if ((nconn == Connected || nconn == WFBitMapS) && ns.disk == Negotiating) + ns.disk = mdev->new_state_tmp.disk; + DRBD_STATE_DEBUG_INIT_VAL(ns); + rv = _drbd_set_state(mdev, ns, ChgStateVerbose | ChgStateHard, NULL); + ns = mdev->state; + spin_unlock_irq(&mdev->req_lock); + + if (rv < SS_Success) { + drbd_force_state(mdev, NS(conn, Disconnecting)); + return FALSE; + } + + if (oconn > WFReportParams) { + if (nconn > Connected && peer_state.conn <= Connected && + peer_state.disk != Negotiating ) { + /* we want resync, peer has not yet decided to sync... */ + /* Nowadays only used when forcing a node into primary role and + setting its disk to UpTpDate with that */ + drbd_send_uuids(mdev); + drbd_send_state(mdev); + } + } + + mdev->net_conf->want_lose = 0; + + /* FIXME assertion for (gencounts do not diverge) */ + drbd_md_sync(mdev); /* update connected indicator, la_size, ... */ + + return TRUE; +} + +STATIC int receive_sync_uuid(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + struct Drbd_SyncUUID_Packet *p = (struct Drbd_SyncUUID_Packet *)h; + + wait_event(mdev->misc_wait, + mdev->state.conn < Connected || + mdev->state.conn == WFSyncUUID); + + /* D_ASSERT( mdev->state.conn == WFSyncUUID ); */ + + ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE; + if (drbd_recv(mdev, h->payload, h->length) != h->length) + return FALSE; + + /* Here the _drbd_uuid_ functions are right, current should + _not_ be rotated into the history */ + if (inc_local_if_state(mdev, Negotiating)) { + _drbd_uuid_set(mdev, Current, be64_to_cpu(p->uuid)); + _drbd_uuid_set(mdev, Bitmap, 0UL); + + drbd_start_resync(mdev, SyncTarget); + + dec_local(mdev); + } else + ERR("Ignoring SyncUUID packet!\n"); + + return TRUE; +} + +/* Since we are processing the bitfild from lower addresses to higher, + it does not matter if the process it in 32 bit chunks or 64 bit + chunks as long as it is little endian. (Understand it as byte stream, + beginning with the lowest byte...) If we would use big endian + we would need to process it from the highest address to the lowest, + in order to be agnostic to the 32 vs 64 bits issue. + + returns 0 on failure, 1 if we suceessfully received it. */ +STATIC int receive_bitmap(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + size_t bm_words, bm_i, want, num_words; + unsigned long *buffer; + int ok = FALSE; + + wait_event(mdev->misc_wait, !atomic_read(&mdev->ap_bio_cnt)); + + drbd_bm_lock(mdev, "receive bitmap"); + + bm_words = drbd_bm_words(mdev); + bm_i = 0; + /* maybe we should use some per thread scratch page, + * and allocate that during initial device creation? */ + buffer = (unsigned long *) __get_free_page(GFP_NOIO); + if (!buffer) { + ERR("failed to allocate one page buffer in %s\n", __func__); + goto out; + } + + while (1) { + num_words = min_t(size_t, BM_PACKET_WORDS, bm_words-bm_i); + want = num_words * sizeof(long); + ERR_IF(want != h->length) goto out; + if (want == 0) + break; + if (drbd_recv(mdev, buffer, want) != want) + goto out; + + drbd_bm_merge_lel(mdev, bm_i, num_words, buffer); + bm_i += num_words; + + if (!drbd_recv_header(mdev, h)) + goto out; + D_ASSERT(h->command == ReportBitMap); + } + + if (mdev->state.conn == WFBitMapT) { + ok = !drbd_send_bitmap(mdev); + if (!ok) + goto out; + /* Omit ChgOrdered with this state transition to avoid deadlocks. */ + ok = _drbd_request_state(mdev, NS(conn, WFSyncUUID), ChgStateVerbose); + D_ASSERT(ok == SS_Success); + } else if (mdev->state.conn != WFBitMapS) { + /* admin may have requested Disconnecting, + * other threads may have noticed network errors */ + INFO("unexpected cstate (%s) in receive_bitmap\n", + conns_to_name(mdev->state.conn)); + } + + ok = TRUE; + out: + drbd_bm_unlock(mdev); + if (ok && mdev->state.conn == WFBitMapS) + drbd_start_resync(mdev, SyncSource); + free_page((unsigned long) buffer); + return ok; +} + +STATIC int receive_skip(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + /* TODO zero copy sink :) */ + static char sink[128]; + int size, want, r; + + drbd_WARN("skipping unknown optional packet type %d, l: %d!\n", + h->command, h->length); + + size = h->length; + while (size > 0) { + want = min_t(int, size, sizeof(sink)); + r = drbd_recv(mdev, sink, want); + ERR_IF(r < 0) break; + size -= r; + } + return size == 0; +} + +STATIC int receive_UnplugRemote(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + if (mdev->state.disk >= Inconsistent) + drbd_kick_lo(mdev); + + /* Make sure we've acked all the TCP data associated + * with the data requests being unplugged */ + drbd_tcp_quickack(mdev->data.socket); + + return TRUE; +} + +typedef int (*drbd_cmd_handler_f)(struct drbd_conf *, struct Drbd_Header *); + +static drbd_cmd_handler_f drbd_default_handler[] = { + [Data] = receive_Data, + [DataReply] = receive_DataReply, + [RSDataReply] = receive_RSDataReply, + [Barrier] = receive_Barrier, + [ReportBitMap] = receive_bitmap, + [UnplugRemote] = receive_UnplugRemote, + [DataRequest] = receive_DataRequest, + [RSDataRequest] = receive_DataRequest, + [SyncParam] = receive_SyncParam, + [SyncParam89] = receive_SyncParam, + [ReportProtocol] = receive_protocol, + [ReportUUIDs] = receive_uuids, + [ReportSizes] = receive_sizes, + [ReportState] = receive_state, + [StateChgRequest] = receive_req_state, + [ReportSyncUUID] = receive_sync_uuid, + [OVRequest] = receive_DataRequest, + [OVReply] = receive_DataRequest, + [CsumRSRequest] = receive_DataRequest, + /* anything missing from this table is in + * the asender_tbl, see get_asender_cmd */ + [MAX_CMD] = NULL, +}; + +static drbd_cmd_handler_f *drbd_cmd_handler = drbd_default_handler; +static drbd_cmd_handler_f *drbd_opt_cmd_handler; + +STATIC void drbdd(struct drbd_conf *mdev) +{ + drbd_cmd_handler_f handler; + struct Drbd_Header *header = &mdev->data.rbuf.head; + + while (get_t_state(&mdev->receiver) == Running) { + drbd_thread_current_set_cpu(mdev); + if (!drbd_recv_header(mdev, header)) + break; + + if (header->command < MAX_CMD) + handler = drbd_cmd_handler[header->command]; + else if (MayIgnore < header->command + && header->command < MAX_OPT_CMD) + handler = drbd_opt_cmd_handler[header->command-MayIgnore]; + else if (header->command > MAX_OPT_CMD) + handler = receive_skip; + else + handler = NULL; + + if (unlikely(!handler)) { + ERR("unknown packet type %d, l: %d!\n", + header->command, header->length); + drbd_force_state(mdev, NS(conn, ProtocolError)); + break; + } + if (unlikely(!handler(mdev, header))) { + ERR("error receiving %s, l: %d!\n", + cmdname(header->command), header->length); + drbd_force_state(mdev, NS(conn, ProtocolError)); + break; + } + + dump_packet(mdev, mdev->data.socket, 2, &mdev->data.rbuf, + __FILE__, __LINE__); + } +} + +/* FIXME how should freeze-io be handled? */ +STATIC void drbd_fail_pending_reads(struct drbd_conf *mdev) +{ + struct hlist_head *slot; + struct hlist_node *pos; + struct hlist_node *tmp; + struct drbd_request *req; + int i; + + /* + * Application READ requests + */ + spin_lock_irq(&mdev->req_lock); + for (i = 0; i < APP_R_HSIZE; i++) { + slot = mdev->app_reads_hash+i; + hlist_for_each_entry_safe(req, pos, tmp, slot, colision) { + /* it may (but should not any longer!) + * be on the work queue; if that assert triggers, + * we need to also grab the + * spin_lock_irq(&mdev->data.work.q_lock); + * and list_del_init here. */ + D_ASSERT(list_empty(&req->w.list)); + _req_mod(req, connection_lost_while_pending, 0); + } + } + for (i = 0; i < APP_R_HSIZE; i++) + if (!hlist_empty(mdev->app_reads_hash+i)) + drbd_WARN("ASSERT FAILED: app_reads_hash[%d].first: " + "%p, should be NULL\n", i, mdev->app_reads_hash[i].first); + + memset(mdev->app_reads_hash, 0, APP_R_HSIZE*sizeof(void *)); + spin_unlock_irq(&mdev->req_lock); +} + +STATIC void drbd_disconnect(struct drbd_conf *mdev) +{ + struct drbd_work prev_work_done; + enum fencing_policy fp; + union drbd_state_t os, ns; + int rv = SS_UnknownError; + unsigned int i; + + if (mdev->state.conn == StandAlone) + return; + /* FIXME verify that: + * the state change magic prevents us from becoming >= Connected again + * while we are still cleaning up. + */ + if (mdev->state.conn >= WFConnection) + ERR("ASSERT FAILED cstate = %s, expected < WFConnection\n", + conns_to_name(mdev->state.conn)); + + /* asender does not clean up anything. it must not interfere, either */ + drbd_thread_stop(&mdev->asender); + + down(&mdev->data.mutex); + drbd_free_sock(mdev); + up(&mdev->data.mutex); + + spin_lock_irq(&mdev->req_lock); + _drbd_wait_ee_list_empty(mdev, &mdev->active_ee); + _drbd_wait_ee_list_empty(mdev, &mdev->sync_ee); + _drbd_clear_done_ee(mdev); + _drbd_wait_ee_list_empty(mdev, &mdev->read_ee); + reclaim_net_ee(mdev); + spin_unlock_irq(&mdev->req_lock); + + /* We do not have data structures that would allow us to + * get the rs_pending_cnt down to 0 again. + * * On SyncTarget we do not have any data structures describing + * the pending RSDataRequest's we have sent. + * * On SyncSource there is no data structure that tracks + * the RSDataReply blocks that we sent to the SyncTarget. + * And no, it is not the sum of the reference counts in the + * resync_LRU. The resync_LRU tracks the whole operation including + * the disk-IO, while the rs_pending_cnt only tracks the blocks + * on the fly. */ + drbd_rs_cancel_all(mdev); + mdev->rs_total = 0; + mdev->rs_failed = 0; + atomic_set(&mdev->rs_pending_cnt, 0); + wake_up(&mdev->misc_wait); + + /* make sure syncer is stopped and w_resume_next_sg queued */ + del_timer_sync(&mdev->resync_timer); + set_bit(STOP_SYNC_TIMER, &mdev->flags); + resync_timer_fn((unsigned long)mdev); + + /* wait for all w_e_end_data_req, w_e_end_rsdata_req, w_send_barrier, + * w_make_resync_request etc. which may still be on the worker queue + * to be "canceled" */ + set_bit(WORK_PENDING, &mdev->flags); + prev_work_done.cb = w_prev_work_done; + drbd_queue_work(&mdev->data.work, &prev_work_done); + wait_event(mdev->misc_wait, !test_bit(WORK_PENDING, &mdev->flags)); + + kfree(mdev->p_uuid); + mdev->p_uuid = NULL; + + /* queue cleanup for the worker. + * FIXME this should go into after_state_ch */ + if (!mdev->state.susp) + tl_clear(mdev); + + /* FIXME: fail pending reads? + * when we are configured for freeze io, + * we could retry them once we un-freeze. */ + drbd_fail_pending_reads(mdev); + + INFO("Connection closed\n"); + + drbd_md_sync(mdev); + + fp = DontCare; + if (inc_local(mdev)) { + fp = mdev->bc->dc.fencing; + dec_local(mdev); + } + + if (mdev->state.role == Primary) { + if (fp >= Resource && mdev->state.pdsk >= DUnknown) { + enum drbd_disk_state nps = drbd_try_outdate_peer(mdev); + drbd_request_state(mdev, NS(pdsk, nps)); + } + } + + spin_lock_irq(&mdev->req_lock); + os = mdev->state; + if (os.conn >= Unconnected) { + /* Do not restart in case we are Disconnecting */ + ns = os; + ns.conn = Unconnected; + DRBD_STATE_DEBUG_INIT_VAL(ns); + rv = _drbd_set_state(mdev, ns, ChgStateVerbose, NULL); + } + spin_unlock_irq(&mdev->req_lock); + + if (os.conn == Disconnecting) { + struct hlist_head *h; + wait_event(mdev->misc_wait, atomic_read(&mdev->net_cnt) == 0); + + /* we must not free the tl_hash + * while application io is still on the fly */ + wait_event(mdev->misc_wait, atomic_read(&mdev->ap_bio_cnt) == 0); + + spin_lock_irq(&mdev->req_lock); + /* paranoia code */ + for (h = mdev->ee_hash; h < mdev->ee_hash + mdev->ee_hash_s; h++) + if (h->first) + ERR("ASSERT FAILED ee_hash[%u].first == %p, expected NULL\n", + (int)(h - mdev->ee_hash), h->first); + kfree(mdev->ee_hash); + mdev->ee_hash = NULL; + mdev->ee_hash_s = 0; + + /* paranoia code */ + for (h = mdev->tl_hash; h < mdev->tl_hash + mdev->tl_hash_s; h++) + if (h->first) + ERR("ASSERT FAILED tl_hash[%u] == %p, expected NULL\n", + (int)(h - mdev->tl_hash), h->first); + kfree(mdev->tl_hash); + mdev->tl_hash = NULL; + mdev->tl_hash_s = 0; + spin_unlock_irq(&mdev->req_lock); + + crypto_free_hash(mdev->cram_hmac_tfm); + mdev->cram_hmac_tfm = NULL; + + kfree(mdev->net_conf); + mdev->net_conf = NULL; + drbd_request_state(mdev, NS(conn, StandAlone)); + } + + /* they do trigger all the time. + * hm. why won't tcp release the page references, + * we already released the socket!? */ + i = atomic_read(&mdev->pp_in_use); + if (i) + DBG("pp_in_use = %u, expected 0\n", i); + if (!list_empty(&mdev->net_ee)) + DBG("net_ee not empty!\n"); + + D_ASSERT(list_empty(&mdev->read_ee)); + D_ASSERT(list_empty(&mdev->active_ee)); + D_ASSERT(list_empty(&mdev->sync_ee)); + D_ASSERT(list_empty(&mdev->done_ee)); + + /* ok, no more ee's on the fly, it is safe to reset the epoch_size */ + atomic_set(&mdev->current_epoch->epoch_size, 0); + D_ASSERT(list_empty(&mdev->current_epoch->list)); +} + +/* + * We support PRO_VERSION_MIN to PRO_VERSION_MAX. The protocol version + * we can agree on is stored in agreed_pro_version. + * + * feature flags and the reserved array should be enough room for future + * enhancements of the handshake protocol, and possible plugins... + * + * for now, they are expected to be zero, but ignored. + */ +STATIC int drbd_send_handshake(struct drbd_conf *mdev) +{ + /* ASSERT current == mdev->receiver ... */ + struct Drbd_HandShake_Packet *p = &mdev->data.sbuf.HandShake; + int ok; + + if (down_interruptible(&mdev->data.mutex)) { + ERR("interrupted during initial handshake\n"); + return 0; /* interrupted. not ok. */ + } + /* FIXME do we need to verify this here? */ + if (mdev->data.socket == NULL) { + up(&mdev->data.mutex); + return 0; + } + + memset(p, 0, sizeof(*p)); + p->protocol_min = cpu_to_be32(PRO_VERSION_MIN); + p->protocol_max = cpu_to_be32(PRO_VERSION_MAX); + ok = _drbd_send_cmd( mdev, mdev->data.socket, HandShake, + (struct Drbd_Header *)p, sizeof(*p), 0 ); + up(&mdev->data.mutex); + return ok; +} + +/* + * return values: + * 1 yess, we have a valid connection + * 0 oops, did not work out, please try again + * -1 peer talks different language, + * no point in trying again, please go standalone. + */ +int drbd_do_handshake(struct drbd_conf *mdev) +{ + /* ASSERT current == mdev->receiver ... */ + struct Drbd_HandShake_Packet *p = &mdev->data.rbuf.HandShake; + const int expect = sizeof(struct Drbd_HandShake_Packet) + -sizeof(struct Drbd_Header); + int rv; + + rv = drbd_send_handshake(mdev); + if (!rv) + return 0; + + rv = drbd_recv_header(mdev, &p->head); + if (!rv) + return 0; + + if (p->head.command != HandShake) { + ERR("expected HandShake packet, received: %s (0x%04x)\n", + cmdname(p->head.command), p->head.command); + return -1; + } + + if (p->head.length != expect) { + ERR("expected HandShake length: %u, received: %u\n", + expect, p->head.length); + return -1; + } + + rv = drbd_recv(mdev, &p->head.payload, expect); + + if (rv != expect) { + ERR("short read receiving handshake packet: l=%u\n", rv); + return 0; + } + + dump_packet(mdev, mdev->data.socket, 2, &mdev->data.rbuf, + __FILE__, __LINE__); + + p->protocol_min = be32_to_cpu(p->protocol_min); + p->protocol_max = be32_to_cpu(p->protocol_max); + if (p->protocol_max == 0) + p->protocol_max = p->protocol_min; + + if (PRO_VERSION_MAX < p->protocol_min || + PRO_VERSION_MIN > p->protocol_max) + goto incompat; + + mdev->agreed_pro_version = min_t(int,PRO_VERSION_MAX,p->protocol_max); + + INFO("Handshake successful: " + "Agreed network protocol version %d\n", mdev->agreed_pro_version); + + return 1; + + incompat: + ERR("incompatible DRBD dialects: " + "I support %d-%d, peer supports %d-%d\n", + PRO_VERSION_MIN, PRO_VERSION_MAX, + p->protocol_min, p->protocol_max); + return -1; +} + +#if !defined(CONFIG_CRYPTO_HMAC) && !defined(CONFIG_CRYPTO_HMAC_MODULE) +int drbd_do_auth(struct drbd_conf *mdev) +{ + ERR("This kernel was build without CONFIG_CRYPTO_HMAC.\n"); + ERR("You need to disable 'cram-hmac-alg' in drbd.conf.\n"); + return 0; +} +#else +#define CHALLENGE_LEN 64 +int drbd_do_auth(struct drbd_conf *mdev) +{ + char my_challenge[CHALLENGE_LEN]; /* 64 Bytes... */ + struct scatterlist sg; + char *response = NULL; + char *right_response = NULL; + char *peers_ch = NULL; + struct Drbd_Header p; + unsigned int key_len = strlen(mdev->net_conf->shared_secret); + unsigned int resp_size; + struct hash_desc desc; + int rv; + + desc.tfm = mdev->cram_hmac_tfm; + desc.flags = 0; + + rv = crypto_hash_setkey(mdev->cram_hmac_tfm, + (u8 *)mdev->net_conf->shared_secret, key_len); + if (rv) { + ERR("crypto_hash_setkey() failed with %d\n", rv); + rv = 0; + goto fail; + } + + get_random_bytes(my_challenge, CHALLENGE_LEN); + + rv = drbd_send_cmd2(mdev, AuthChallenge, my_challenge, CHALLENGE_LEN); + if (!rv) + goto fail; + + rv = drbd_recv_header(mdev, &p); + if (!rv) + goto fail; + + if (p.command != AuthChallenge) { + ERR("expected AuthChallenge packet, received: %s (0x%04x)\n", + cmdname(p.command), p.command); + rv = 0; + goto fail; + } + + if (p.length > CHALLENGE_LEN*2) { + ERR("expected AuthChallenge payload too big.\n"); + rv = 0; + goto fail; + } + + peers_ch = kmalloc(p.length, GFP_KERNEL); + if (peers_ch == NULL) { + ERR("kmalloc of peers_ch failed\n"); + rv = 0; + goto fail; + } + + rv = drbd_recv(mdev, peers_ch, p.length); + + if (rv != p.length) { + ERR("short read AuthChallenge: l=%u\n", rv); + rv = 0; + goto fail; + } + + resp_size = crypto_hash_digestsize(mdev->cram_hmac_tfm); + response = kmalloc(resp_size, GFP_KERNEL); + if (response == NULL) { + ERR("kmalloc of response failed\n"); + rv = 0; + goto fail; + } + + sg_init_table(&sg, 1); + sg_set_buf(&sg, peers_ch, p.length); + + rv = crypto_hash_digest(&desc, &sg, sg.length, response); + if (rv) { + ERR("crypto_hash_digest() failed with %d\n", rv); + rv = 0; + goto fail; + } + + rv = drbd_send_cmd2(mdev, AuthResponse, response, resp_size); + if (!rv) + goto fail; + + rv = drbd_recv_header(mdev, &p); + if (!rv) + goto fail; + + if (p.command != AuthResponse) { + ERR("expected AuthResponse packet, received: %s (0x%04x)\n", + cmdname(p.command), p.command); + rv = 0; + goto fail; + } + + if (p.length != resp_size) { + ERR("expected AuthResponse payload of wrong size\n"); + rv = 0; + goto fail; + } + + rv = drbd_recv(mdev, response , resp_size); + + if (rv != resp_size) { + ERR("short read receiving AuthResponse: l=%u\n", rv); + rv = 0; + goto fail; + } + + right_response = kmalloc(resp_size, GFP_KERNEL); + if (response == NULL) { + ERR("kmalloc of right_response failed\n"); + rv = 0; + goto fail; + } + + sg_set_buf(&sg, my_challenge, CHALLENGE_LEN); + + rv = crypto_hash_digest(&desc, &sg, sg.length, right_response); + if (rv) { + ERR("crypto_hash_digest() failed with %d\n", rv); + rv = 0; + goto fail; + } + + rv = !memcmp(response, right_response, resp_size); + + if (rv) + INFO("Peer authenticated using %d bytes of '%s' HMAC\n", + resp_size, mdev->net_conf->cram_hmac_alg); + + fail: + kfree(peers_ch); + kfree(response); + kfree(right_response); + + return rv; +} +#endif + +STATIC int drbdd_init(struct Drbd_thread *thi) +{ + struct drbd_conf *mdev = thi->mdev; + int minor = mdev_to_minor(mdev); + int h; + + sprintf(current->comm, "drbd%d_receiver", minor); + + INFO("receiver (re)started\n"); + + do { + h = drbd_connect(mdev); + if (h == 0) { + drbd_disconnect(mdev); + __set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ); + } + if (h == -1) { + drbd_WARN("Discarding network configuration.\n"); + drbd_force_state(mdev, NS(conn, Disconnecting)); + } + } while (h == 0); + + if (h > 0) { + if (inc_net(mdev)) { + drbdd(mdev); + dec_net(mdev); + } + } + + drbd_disconnect(mdev); + + INFO("receiver terminated\n"); + return 0; +} + +/* ********* acknowledge sender ******** */ + +STATIC int got_RqSReply(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + struct Drbd_RqS_Reply_Packet *p = (struct Drbd_RqS_Reply_Packet *)h; + + int retcode = be32_to_cpu(p->retcode); + + if (retcode >= SS_Success) { + set_bit(CL_ST_CHG_SUCCESS, &mdev->flags); + } else { + set_bit(CL_ST_CHG_FAIL, &mdev->flags); + ERR("Requested state change failed by peer: %s (%d)\n", + set_st_err_name(retcode), retcode); + } + wake_up(&mdev->state_wait); + + return TRUE; +} + +STATIC int got_Ping(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + return drbd_send_ping_ack(mdev); + +} + +STATIC int got_PingAck(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + /* restore idle timeout */ + mdev->meta.socket->sk->sk_rcvtimeo = mdev->net_conf->ping_int*HZ; + + return TRUE; +} + +STATIC int got_IsInSync(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + struct Drbd_BlockAck_Packet *p = (struct Drbd_BlockAck_Packet *)h; + sector_t sector = be64_to_cpu(p->sector); + int blksize = be32_to_cpu(p->blksize); + + D_ASSERT(mdev->agreed_pro_version >= 89); + + update_peer_seq(mdev, be32_to_cpu(p->seq_num)); + + drbd_rs_complete_io(mdev, sector); + drbd_set_in_sync(mdev, sector, blksize); + /* rs_same_csums is supposed to count in units of BM_BLOCK_SIZE */ + mdev->rs_same_csum += (blksize >> BM_BLOCK_SIZE_B); + dec_rs_pending(mdev); + + return TRUE; +} + +STATIC int got_BlockAck(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + struct drbd_request *req; + struct Drbd_BlockAck_Packet *p = (struct Drbd_BlockAck_Packet *)h; + sector_t sector = be64_to_cpu(p->sector); + int blksize = be32_to_cpu(p->blksize); + + update_peer_seq(mdev, be32_to_cpu(p->seq_num)); + + if (is_syncer_block_id(p->block_id)) { + drbd_set_in_sync(mdev, sector, blksize); + dec_rs_pending(mdev); + } else { + spin_lock_irq(&mdev->req_lock); + req = _ack_id_to_req(mdev, p->block_id, sector); + + if (unlikely(!req)) { + spin_unlock_irq(&mdev->req_lock); + ERR("Got a corrupt block_id/sector pair(2).\n"); + return FALSE; + } + + switch (be16_to_cpu(h->command)) { + case RSWriteAck: + D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C); + _req_mod(req, write_acked_by_peer_and_sis, 0); + break; + case WriteAck: + D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C); + _req_mod(req, write_acked_by_peer, 0); + break; + case RecvAck: + D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_B); + _req_mod(req, recv_acked_by_peer, 0); + break; + case DiscardAck: + D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C); + ALERT("Got DiscardAck packet %llus +%u!" + " DRBD is not a random data generator!\n", + (unsigned long long)req->sector, req->size); + _req_mod(req, conflict_discarded_by_peer, 0); + break; + default: + D_ASSERT(0); + } + spin_unlock_irq(&mdev->req_lock); + } + /* dec_ap_pending is handled within _req_mod */ + + return TRUE; +} + +STATIC int got_NegAck(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + struct Drbd_BlockAck_Packet *p = (struct Drbd_BlockAck_Packet *)h; + sector_t sector = be64_to_cpu(p->sector); + struct drbd_request *req; + + if (DRBD_ratelimit(5*HZ, 5)) + drbd_WARN("Got NegAck packet. Peer is in troubles?\n"); + + update_peer_seq(mdev, be32_to_cpu(p->seq_num)); + + if (is_syncer_block_id(p->block_id)) { + int size = be32_to_cpu(p->blksize); + + dec_rs_pending(mdev); + + drbd_rs_failed_io(mdev, sector, size); + } else { + spin_lock_irq(&mdev->req_lock); + req = _ack_id_to_req(mdev, p->block_id, sector); + + if (unlikely(!req)) { + spin_unlock_irq(&mdev->req_lock); + ERR("Got a corrupt block_id/sector pair(2).\n"); + return FALSE; + } + + _req_mod(req, neg_acked, 0); + spin_unlock_irq(&mdev->req_lock); + } + + return TRUE; +} + +STATIC int got_NegDReply(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + struct drbd_request *req; + struct Drbd_BlockAck_Packet *p = (struct Drbd_BlockAck_Packet *)h; + sector_t sector = be64_to_cpu(p->sector); + + spin_lock_irq(&mdev->req_lock); + req = _ar_id_to_req(mdev, p->block_id, sector); + if (unlikely(!req)) { + spin_unlock_irq(&mdev->req_lock); + ERR("Got a corrupt block_id/sector pair(3).\n"); + return FALSE; + } + + _req_mod(req, neg_acked, 0); + spin_unlock_irq(&mdev->req_lock); + + update_peer_seq(mdev, be32_to_cpu(p->seq_num)); + + ERR("Got NegDReply; Sector %llus, len %u; Fail original request.\n", + (unsigned long long)sector, be32_to_cpu(p->blksize)); + + return TRUE; +} + +STATIC int got_NegRSDReply(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + sector_t sector; + int size; + struct Drbd_BlockAck_Packet *p = (struct Drbd_BlockAck_Packet *)h; + + sector = be64_to_cpu(p->sector); + size = be32_to_cpu(p->blksize); + D_ASSERT(p->block_id == ID_SYNCER); + + update_peer_seq(mdev, be32_to_cpu(p->seq_num)); + + dec_rs_pending(mdev); + + if (inc_local_if_state(mdev, Failed)) { + drbd_rs_complete_io(mdev, sector); + drbd_rs_failed_io(mdev, sector, size); + dec_local(mdev); + } + + return TRUE; +} + +STATIC int got_BarrierAck(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + struct Drbd_BarrierAck_Packet *p = (struct Drbd_BarrierAck_Packet *)h; + + tl_release(mdev, p->barrier, be32_to_cpu(p->set_size)); + + return TRUE; +} + +STATIC int got_OVResult(struct drbd_conf *mdev, struct Drbd_Header* h) +{ + struct Drbd_BlockAck_Packet *p = (struct Drbd_BlockAck_Packet*)h; + struct drbd_work* w; + sector_t sector; + int size; + + sector = be64_to_cpu(p->sector); + size = be32_to_cpu(p->blksize); + + update_peer_seq(mdev, be32_to_cpu(p->seq_num)); + + if (be64_to_cpu(p->block_id) == ID_OUT_OF_SYNC) { + drbd_ov_oos_found(mdev, sector, size); + } else ov_oos_print(mdev); + + drbd_rs_complete_io(mdev, sector); + dec_rs_pending(mdev); + + if (--mdev->ov_left == 0) { + w = kmalloc(sizeof(*w), GFP_KERNEL); + if (w) { + w->cb = w_ov_finished; + drbd_queue_work_front(&mdev->data.work, w); + } else { + ERR("kmalloc(w) failed."); + drbd_resync_finished(mdev); + } + } + return TRUE; +} + +struct asender_cmd { + size_t pkt_size; + int (*process)(struct drbd_conf *mdev, struct Drbd_Header *h); +}; + +static struct asender_cmd *get_asender_cmd(int cmd) +{ + static struct asender_cmd asender_tbl[] = { + /* anything missing from this table is in + * the drbd_cmd_handler (drbd_default_handler) table, + * see the beginning of drbdd() */ + [Ping] = { sizeof(struct Drbd_Header), got_Ping }, + [PingAck] = { sizeof(struct Drbd_Header), got_PingAck }, + [RecvAck] = { sizeof(struct Drbd_BlockAck_Packet), got_BlockAck }, + [WriteAck] = { sizeof(struct Drbd_BlockAck_Packet), got_BlockAck }, + [RSWriteAck] = { sizeof(struct Drbd_BlockAck_Packet), got_BlockAck }, + [DiscardAck] = { sizeof(struct Drbd_BlockAck_Packet), got_BlockAck }, + [NegAck] = { sizeof(struct Drbd_BlockAck_Packet), got_NegAck }, + [NegDReply] = { sizeof(struct Drbd_BlockAck_Packet), got_NegDReply }, + [NegRSDReply] = { sizeof(struct Drbd_BlockAck_Packet), got_NegRSDReply}, + [OVResult] = { sizeof(struct Drbd_BlockAck_Packet), got_OVResult }, + [BarrierAck] = { sizeof(struct Drbd_BarrierAck_Packet), got_BarrierAck }, + [StateChgReply] = { sizeof(struct Drbd_RqS_Reply_Packet), got_RqSReply }, + [RSIsInSync] = { sizeof(struct Drbd_BlockAck_Packet), got_IsInSync }, + [MAX_CMD] = { 0, NULL }, + }; + if (cmd > MAX_CMD) + return NULL; + return &asender_tbl[cmd]; +} + +STATIC int drbd_asender(struct Drbd_thread *thi) +{ + struct drbd_conf *mdev = thi->mdev; + struct Drbd_Header *h = &mdev->meta.rbuf.head; + struct asender_cmd *cmd = NULL; + + int rv, len; + void *buf = h; + int received = 0; + int expect = sizeof(struct Drbd_Header); + int empty; + + sprintf(current->comm, "drbd%d_asender", mdev_to_minor(mdev)); + + current->policy = SCHED_RR; /* Make this a realtime task! */ + current->rt_priority = 2; /* more important than all other tasks */ + + while (get_t_state(thi) == Running) { + drbd_thread_current_set_cpu(mdev); + if (test_and_clear_bit(SEND_PING, &mdev->flags)) { + ERR_IF(!drbd_send_ping(mdev)) goto reconnect; + mdev->meta.socket->sk->sk_rcvtimeo = + mdev->net_conf->ping_timeo*HZ/10; + } + + /* conditionally cork; + * it may hurt latency if we cork without much to send */ + if (!mdev->net_conf->no_cork && + 3 < atomic_read(&mdev->unacked_cnt)) + drbd_tcp_cork(mdev->meta.socket); + while (1) { + clear_bit(SIGNAL_ASENDER, &mdev->flags); + flush_signals(current); + if (!drbd_process_done_ee(mdev)) { + ERR("process_done_ee() = NOT_OK\n"); + goto reconnect; + } + /* to avoid race with newly queued ACKs */ + set_bit(SIGNAL_ASENDER, &mdev->flags); + spin_lock_irq(&mdev->req_lock); + empty = list_empty(&mdev->done_ee); + spin_unlock_irq(&mdev->req_lock); + /* new ack may have been queued right here, + * but then there is also a signal pending, + * and we start over... */ + if (empty) + break; + } + /* but unconditionally uncork unless disabled */ + if (!mdev->net_conf->no_cork) + drbd_tcp_uncork(mdev->meta.socket); + + /* short circuit, recv_msg would return EINTR anyways. */ + if (signal_pending(current)) + continue; + + rv = drbd_recv_short(mdev, mdev->meta.socket, + buf, expect-received, 0); + clear_bit(SIGNAL_ASENDER, &mdev->flags); + + flush_signals(current); + + /* Note: + * -EINTR (on meta) we got a signal + * -EAGAIN (on meta) rcvtimeo expired + * -ECONNRESET other side closed the connection + * -ERESTARTSYS (on data) we got a signal + * rv < 0 other than above: unexpected error! + * rv == expected: full header or command + * rv < expected: "woken" by signal during receive + * rv == 0 : "connection shut down by peer" + */ + if (likely(rv > 0)) { + received += rv; + buf += rv; + } else if (rv == 0) { + ERR("meta connection shut down by peer.\n"); + goto reconnect; + } else if (rv == -EAGAIN) { + if (mdev->meta.socket->sk->sk_rcvtimeo == + mdev->net_conf->ping_timeo*HZ/10) { + ERR("PingAck did not arrive in time.\n"); + goto reconnect; + } + set_bit(SEND_PING, &mdev->flags); + continue; + } else if (rv == -EINTR) { + continue; + } else { + ERR("sock_recvmsg returned %d\n", rv); + goto reconnect; + } + + if (received == expect && cmd == NULL) { + if (unlikely(h->magic != BE_DRBD_MAGIC)) { + ERR("magic?? on meta m: 0x%lx c: %d l: %d\n", + (long)be32_to_cpu(h->magic), + h->command, h->length); + goto reconnect; + } + cmd = get_asender_cmd(be16_to_cpu(h->command)); + len = be16_to_cpu(h->length); + if (unlikely(cmd == NULL)) { + ERR("unknown command?? on meta m: 0x%lx c: %d l: %d\n", + (long)be32_to_cpu(h->magic), + h->command, h->length); + goto disconnect; + } + expect = cmd->pkt_size; + ERR_IF(len != expect-sizeof(struct Drbd_Header)) { + dump_packet(mdev, mdev->meta.socket, 1, (void *)h, __FILE__, __LINE__); + DUMPI(expect); + goto reconnect; + } + } + if (received == expect) { + D_ASSERT(cmd != NULL); + dump_packet(mdev, mdev->meta.socket, 1, (void *)h, __FILE__, __LINE__); + if (!cmd->process(mdev, h)) + goto reconnect; + + buf = h; + received = 0; + expect = sizeof(struct Drbd_Header); + cmd = NULL; + } + } + + if (0) { +reconnect: + drbd_force_state(mdev, NS(conn, NetworkFailure)); + } + if (0) { +disconnect: + drbd_force_state(mdev, NS(conn, Disconnecting)); + } + clear_bit(SIGNAL_ASENDER, &mdev->flags); + + D_ASSERT(mdev->state.conn < Connected); + INFO("asender terminated\n"); + + return 0; +} --- linux-2.6.28.orig/ubuntu/drbd/drbd_wrappers.h +++ linux-2.6.28/ubuntu/drbd/drbd_wrappers.h @@ -0,0 +1,467 @@ +#include + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) +# error "use a 2.6 kernel, please" +#endif + + +/* struct page has a union in 2.6.15 ... + * an anonymous union and struct since 2.6.16 + * or in fc5 "2.6.15" */ +#include +#ifndef page_private +# define page_private(page) ((page)->private) +# define set_page_private(page, v) ((page)->private = (v)) +#endif + +/* see get_sb_bdev and bd_claim */ +extern char *drbd_sec_holder; + +static inline sector_t drbd_get_hardsect(struct block_device *bdev) +{ + return bdev->bd_disk->queue->hardsect_size; +} + +/* Returns the number of 512 byte sectors of the device */ +static inline sector_t drbd_get_capacity(struct block_device *bdev) +{ + /* return bdev ? get_capacity(bdev->bd_disk) : 0; */ + return bdev ? bdev->bd_inode->i_size >> 9 : 0; +} + +/* sets the number of 512 byte sectors of our virtual device */ +static inline void drbd_set_my_capacity(struct drbd_conf *mdev, + sector_t size) +{ + /* set_capacity(mdev->this_bdev->bd_disk, size); */ + set_capacity(mdev->vdisk, size); + mdev->this_bdev->bd_inode->i_size = (loff_t)size << 9; +} + +#define drbd_bio_uptodate(bio) bio_flagged(bio, BIO_UPTODATE) + +static inline int drbd_bio_has_active_page(struct bio *bio) +{ + struct bio_vec *bvec; + int i; + + __bio_for_each_segment(bvec, bio, i, 0) { + if (page_count(bvec->bv_page) > 1) + return 1; + } + + return 0; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) +/* Before Linux-2.6.24 bie_endio() had the size of the bio as second argument. + See 6712ecf8f648118c3363c142196418f89a510b90 */ +#define bio_endio(B,E) bio_endio(B, (B)->bi_size, E) +#define BIO_ENDIO_TYPE int +#define BIO_ENDIO_ARGS(b,e) (b, unsigned int bytes_done, e) +#define BIO_ENDIO_FN_START if (bio->bi_size) return 1 +#define BIO_ENDIO_FN_RETURN return 0 +#else +#define BIO_ENDIO_TYPE void +#define BIO_ENDIO_ARGS(b,e) (b,e) +#define BIO_ENDIO_FN_START do {} while (0) +#define BIO_ENDIO_FN_RETURN return +#endif + +/* bi_end_io handlers */ +extern BIO_ENDIO_TYPE drbd_md_io_complete BIO_ENDIO_ARGS(struct bio *bio, int error); +extern BIO_ENDIO_TYPE drbd_endio_read_sec BIO_ENDIO_ARGS(struct bio *bio, int error); +extern BIO_ENDIO_TYPE drbd_endio_write_sec BIO_ENDIO_ARGS(struct bio *bio, int error); +extern BIO_ENDIO_TYPE drbd_endio_pri BIO_ENDIO_ARGS(struct bio *bio, int error); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) +/* Before 2.6.23 (with 20c2df83d25c6a95affe6157a4c9cac4cf5ffaac) kmem_cache_create had a + ctor and a dtor */ +#define kmem_cache_create(N,S,A,F,C) kmem_cache_create(N,S,A,F,C,NULL) +#endif + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26) +# undef HAVE_bvec_merge_data +# define HAVE_bvec_merge_data 1 +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) +static inline void sg_set_page(struct scatterlist *sg, struct page *page, + unsigned int len, unsigned int offset) +{ + sg->page = page; + sg->offset = offset; + sg->length = len; +} + +#define sg_init_table(S,N) ({}) + +#ifdef NEED_SG_SET_BUF +static inline void sg_set_buf(struct scatterlist *sg, const void *buf, + unsigned int buflen) +{ + sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf)); +} +#endif + +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) +# define BD_OPS_USE_FMODE +#endif + +/* + * used to submit our private bio + */ +static inline void drbd_generic_make_request(struct drbd_conf *mdev, + int fault_type, struct bio *bio) +{ + __release(local); + if (!bio->bi_bdev) { + printk(KERN_ERR "drbd%d: drbd_generic_make_request: " + "bio->bi_bdev == NULL\n", + mdev_to_minor(mdev)); + dump_stack(); + bio_endio(bio, -ENODEV); + return; + } + + if (FAULT_ACTIVE(mdev, fault_type)) + bio_endio(bio, -EIO); + else + generic_make_request(bio); +} + +static inline void drbd_plug_device(struct drbd_conf *mdev) +{ + struct request_queue *q; + q = bdev_get_queue(mdev->this_bdev); + + spin_lock_irq(q->queue_lock); + +/* XXX the check on !blk_queue_plugged is redundant, + * implicitly checked in blk_plug_device */ + + if (!blk_queue_plugged(q)) { + blk_plug_device(q); + del_timer(&q->unplug_timer); + /* unplugging should not happen automatically... */ + } + spin_unlock_irq(q->queue_lock); +} + +#ifdef DEFINE_SOCK_CREATE_KERN +#define sock_create_kern sock_create +#endif + +#ifdef USE_KMEM_CACHE_S +#define kmem_cache kmem_cache_s +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) +static inline void drbd_unregister_blkdev(unsigned int major, const char *name) +{ + int ret = unregister_blkdev(major, name); + if (ret) + printk(KERN_ERR "drbd: unregister of device failed\n"); +} +#else +#define drbd_unregister_blkdev unregister_blkdev +#endif + +#ifdef NEED_BACKPORT_OF_ATOMIC_ADD + +#if defined(__x86_64__) + +static __inline__ int atomic_add_return(int i, atomic_t *v) +{ + int __i = i; + __asm__ __volatile__( + LOCK_PREFIX "xaddl %0, %1;" + :"=r"(i) + :"m"(v->counter), "0"(i)); + return i + __i; +} + +static __inline__ int atomic_sub_return(int i, atomic_t *v) +{ + return atomic_add_return(-i, v); +} + +#define atomic_inc_return(v) (atomic_add_return(1,v)) +#define atomic_dec_return(v) (atomic_sub_return(1,v)) + +#elif defined(__i386__) || defined(__arch_um__) + +static __inline__ int atomic_add_return(int i, atomic_t *v) +{ + int __i; +#ifdef CONFIG_M386 + unsigned long flags; + if(unlikely(boot_cpu_data.x86==3)) + goto no_xadd; +#endif + /* Modern 486+ processor */ + __i = i; + __asm__ __volatile__( + LOCK_PREFIX "xaddl %0, %1;" + :"=r"(i) + :"m"(v->counter), "0"(i)); + return i + __i; + +#ifdef CONFIG_M386 +no_xadd: /* Legacy 386 processor */ + local_irq_save(flags); + __i = atomic_read(v); + atomic_set(v, i + __i); + local_irq_restore(flags); + return i + __i; +#endif +} + +static __inline__ int atomic_sub_return(int i, atomic_t *v) +{ + return atomic_add_return(-i, v); +} + +#define atomic_inc_return(v) (atomic_add_return(1,v)) +#define atomic_dec_return(v) (atomic_sub_return(1,v)) + +#else +# error "You need to copy/past atomic_inc_return()/atomic_dec_return() here" +# error "for your architecture. (Hint: Kernels after 2.6.10 have those" +# error "by default! Using a later kernel might be less effort!)" +#endif + +#endif + +#if !defined(CRYPTO_ALG_ASYNC) +/* With Linux-2.6.19 the crypto API changed! */ +/* This is not a generic backport of the new api, it just implements + the corner case of "hmac(xxx)". */ + +#define CRYPTO_ALG_ASYNC 4711 +#define CRYPTO_ALG_TYPE_HASH CRYPTO_ALG_TYPE_DIGEST + +struct crypto_hash { + struct crypto_tfm *base; + const u8 *key; + int keylen; +}; + +struct hash_desc { + struct crypto_hash *tfm; + u32 flags; +}; + +static inline struct crypto_hash * +crypto_alloc_hash(char *alg_name, u32 type, u32 mask) +{ + struct crypto_hash *ch; + char *closing_bracket; + + /* "hmac(xxx)" is in alg_name we need that xxx. */ + closing_bracket = strchr(alg_name, ')'); + if (!closing_bracket) { + ch = kmalloc(sizeof(struct crypto_hash), GFP_KERNEL); + if (!ch) + return ERR_PTR(-ENOMEM); + ch->base = crypto_alloc_tfm(alg_name, 0); + if (ch->base == NULL) { + kfree(ch); + return ERR_PTR(-ENOMEM); + } + return ch; + } + if (closing_bracket-alg_name < 6) + return ERR_PTR(-ENOENT); + + ch = kmalloc(sizeof(struct crypto_hash), GFP_KERNEL); + if (!ch) + return ERR_PTR(-ENOMEM); + + *closing_bracket = 0; + ch->base = crypto_alloc_tfm(alg_name + 5, 0); + *closing_bracket = ')'; + + if (ch->base == NULL) { + kfree(ch); + return ERR_PTR(-ENOMEM); + } + + return ch; +} + +static inline int +crypto_hash_setkey(struct crypto_hash *hash, const u8 *key, unsigned int keylen) +{ + hash->key = key; + hash->keylen = keylen; + + return 0; +} + +static inline int +crypto_hash_digest(struct hash_desc *desc, struct scatterlist *sg, + unsigned int nbytes, u8 *out) +{ + + crypto_hmac(desc->tfm->base, (u8 *)desc->tfm->key, + &desc->tfm->keylen, sg, 1 /* ! */ , out); + /* ! this is not generic. Would need to convert nbytes -> nsg */ + + return 0; +} + +static inline void crypto_free_hash(struct crypto_hash *tfm) +{ + if (!tfm) + return; + crypto_free_tfm(tfm->base); + kfree(tfm); +} + +static inline unsigned int crypto_hash_digestsize(struct crypto_hash *tfm) +{ + return crypto_tfm_alg_digestsize(tfm->base); +} + +static inline struct crypto_tfm *crypto_hash_tfm(struct crypto_hash *tfm) +{ + return tfm->base; +} + +static inline int crypto_hash_init(struct hash_desc *desc) +{ + crypto_digest_init(desc->tfm->base); + return 0; +} + +static inline int crypto_hash_update(struct hash_desc *desc, + struct scatterlist *sg, + unsigned int nbytes) +{ + crypto_digest_update(desc->tfm->base,sg,1 /* ! */ ); + /* ! this is not generic. Would need to convert nbytes -> nsg */ + + return 0; +} + +static inline int crypto_hash_final(struct hash_desc *desc, u8 *out) +{ + crypto_digest_final(desc->tfm->base, out); + return 0; +} + +#endif + +#ifdef NEED_BACKPORT_OF_KZALLOC +static inline void *kzalloc(size_t size, int flags) +{ + void *rv = kmalloc(size, flags); + if (rv) + memset(rv, 0, size); + + return rv; +} +#endif + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) +#define __bitmap_parse(BUF, BUFLEN, ISUSR, MASKP, NMASK) \ + backport_bitmap_parse(BUF, BUFLEN, ISUSR, MASKP, NMASK) + +#define CHUNKSZ 32 +#define nbits_to_hold_value(val) fls(val) +#define unhex(c) (isdigit(c) ? (c - '0') : (toupper(c) - 'A' + 10)) + +static inline int backport_bitmap_parse(const char *buf, unsigned int buflen, + int is_user, unsigned long *maskp, + int nmaskbits) +{ + int c, old_c, totaldigits, ndigits, nchunks, nbits; + u32 chunk; + const char __user *ubuf = buf; + + bitmap_zero(maskp, nmaskbits); + + nchunks = nbits = totaldigits = c = 0; + do { + chunk = ndigits = 0; + + /* Get the next chunk of the bitmap */ + while (buflen) { + old_c = c; + if (is_user) { + if (__get_user(c, ubuf++)) + return -EFAULT; + } + else + c = *buf++; + buflen--; + if (isspace(c)) + continue; + + /* + * If the last character was a space and the current + * character isn't '\0', we've got embedded whitespace. + * This is a no-no, so throw an error. + */ + if (totaldigits && c && isspace(old_c)) + return -EINVAL; + + /* A '\0' or a ',' signal the end of the chunk */ + if (c == '\0' || c == ',') + break; + + if (!isxdigit(c)) + return -EINVAL; + + /* + * Make sure there are at least 4 free bits in 'chunk'. + * If not, this hexdigit will overflow 'chunk', so + * throw an error. + */ + if (chunk & ~((1UL << (CHUNKSZ - 4)) - 1)) + return -EOVERFLOW; + + chunk = (chunk << 4) | unhex(c); + ndigits++; totaldigits++; + } + if (ndigits == 0) + return -EINVAL; + if (nchunks == 0 && chunk == 0) + continue; + + bitmap_shift_left(maskp, maskp, CHUNKSZ, nmaskbits); + *maskp |= chunk; + nchunks++; + nbits += (nchunks == 1) ? nbits_to_hold_value(chunk) : CHUNKSZ; + if (nbits > nmaskbits) + return -EOVERFLOW; + } while (buflen && c == ','); + + return 0; +} +#endif + +#ifndef __CHECKER__ +# undef __cond_lock +# define __cond_lock(x,c) (c) +#endif + +#ifndef KERNEL_HAS_GFP_T +#define KERNEL_HAS_GFP_T +typedef unsigned gfp_t; +#endif + + +/* struct kvec didn't exist before 2.6.8, this is an ugly + * #define to work around it ... - jt */ + +#ifndef KERNEL_HAS_KVEC +#define kvec iovec +#endif + + --- linux-2.6.28.orig/ubuntu/drbd/drbd_req.c +++ linux-2.6.28/ubuntu/drbd/drbd_req.c @@ -0,0 +1,1322 @@ +/* +-*- linux-c -*- + drbd_req.c + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2001-2008, LINBIT Information Technologies GmbH. + Copyright (C) 1999-2008, Philipp Reisner . + Copyright (C) 2002-2008, Lars Ellenberg . + + drbd is free software; you can redistribute 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. + + drbd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + */ + +#include +#include + +#include +#include +#include "drbd_int.h" +#include "drbd_req.h" + +/* outside of the ifdef + * because of the _print_rq_state(,FIXME) in barrier_acked */ +STATIC void _print_rq_state(struct drbd_request *req, const char *txt) +{ + const unsigned long s = req->rq_state; + struct drbd_conf *mdev = req->mdev; + const int rw = (req->master_bio == NULL || + bio_data_dir(req->master_bio) == WRITE) ? + 'W' : 'R'; + + INFO("%s %p %c L%c%c%cN%c%c%c%c%c %u (%llus +%u) %s\n", + txt, req, rw, + s & RQ_LOCAL_PENDING ? 'p' : '-', + s & RQ_LOCAL_COMPLETED ? 'c' : '-', + s & RQ_LOCAL_OK ? 'o' : '-', + s & RQ_NET_PENDING ? 'p' : '-', + s & RQ_NET_QUEUED ? 'q' : '-', + s & RQ_NET_SENT ? 's' : '-', + s & RQ_NET_DONE ? 'd' : '-', + s & RQ_NET_OK ? 'o' : '-', + req->epoch, + (unsigned long long)req->sector, + req->size, + conns_to_name(mdev->state.conn)); +} + +/* #define VERBOSE_REQUEST_CODE */ +#if defined(VERBOSE_REQUEST_CODE) || defined(ENABLE_DYNAMIC_TRACE) +STATIC void _print_req_mod(struct drbd_request *req, enum drbd_req_event what) +{ + struct drbd_conf *mdev = req->mdev; + const int rw = (req->master_bio == NULL || + bio_data_dir(req->master_bio) == WRITE) ? + 'W' : 'R'; + + static const char *rq_event_names[] = { + [created] = "created", + [to_be_send] = "to_be_send", + [to_be_submitted] = "to_be_submitted", + [queue_for_net_write] = "queue_for_net_write", + [queue_for_net_read] = "queue_for_net_read", + [send_canceled] = "send_canceled", + [send_failed] = "send_failed", + [handed_over_to_network] = "handed_over_to_network", + [connection_lost_while_pending] = + "connection_lost_while_pending", + [recv_acked_by_peer] = "recv_acked_by_peer", + [write_acked_by_peer] = "write_acked_by_peer", + [neg_acked] = "neg_acked", + [conflict_discarded_by_peer] = "conflict_discarded_by_peer", + [barrier_acked] = "barrier_acked", + [data_received] = "data_received", + [read_completed_with_error] = "read_completed_with_error", + [write_completed_with_error] = "write_completed_with_error", + [completed_ok] = "completed_ok", + }; + + INFO("_req_mod(%p %c ,%s)\n", req, rw, rq_event_names[what]); +} + +# ifdef ENABLE_DYNAMIC_TRACE +# define print_rq_state(R, T) \ + MTRACE(TraceTypeRq, TraceLvlMetrics, _print_rq_state(R, T);) +# define print_req_mod(T, W) \ + MTRACE(TraceTypeRq, TraceLvlMetrics, _print_req_mod(T, W);) +# else +# define print_rq_state(R, T) _print_rq_state(R, T) +# define print_req_mod(T, W) _print_req_mod(T, W) +# endif + +#else +#define print_rq_state(R, T) +#define print_req_mod(T, W) +#endif + +/* We only support diskstats for 2.6.16 and up. + * see also commit commit a362357b6cd62643d4dda3b152639303d78473da + * Author: Jens Axboe + * Date: Tue Nov 1 09:26:16 2005 +0100 + * [BLOCK] Unify the seperate read/write io stat fields into arrays */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16) +#define _drbd_start_io_acct(...) do {} while (0) +#define _drbd_end_io_acct(...) do {} while (0) +#else + +/* Update disk stats at start of I/O request */ +static inline void _drbd_start_io_acct(struct drbd_conf *mdev, struct drbd_request *req, struct bio *bio) +{ + const int rw = bio_data_dir(bio); +#ifndef __disk_stat_inc + int cpu; +#endif + + MUST_HOLD(&mdev->req_lock) +#ifdef __disk_stat_inc + __disk_stat_inc(mdev->vdisk, ios[rw]); + __disk_stat_add(mdev->vdisk, sectors[rw], bio_sectors(bio)); + disk_round_stats(mdev->vdisk); + mdev->vdisk->in_flight++; +#else + cpu = part_stat_lock(); + part_stat_inc(cpu, &mdev->vdisk->part0, ios[rw]); + part_stat_add(cpu, &mdev->vdisk->part0, sectors[rw], bio_sectors(bio)); + part_stat_unlock(); + mdev->vdisk->part0.in_flight++; +#endif +} + +/* Update disk stats when completing request upwards */ +static inline void _drbd_end_io_acct(struct drbd_conf *mdev, struct drbd_request *req) +{ + int rw = bio_data_dir(req->master_bio); + unsigned long duration = jiffies - req->start_time; +#ifndef __disk_stat_inc + int cpu; +#endif + + MUST_HOLD(&mdev->req_lock) +#ifdef __disk_stat_add + __disk_stat_add(mdev->vdisk, ticks[rw], duration); + disk_round_stats(mdev->vdisk); + mdev->vdisk->in_flight--; +#else + cpu = part_stat_lock(); + part_stat_add(cpu, &mdev->vdisk->part0, ticks[rw], duration); + part_round_stats(cpu, &mdev->vdisk->part0); + part_stat_unlock(); +#endif +} + +#endif + +static void _req_is_done(struct drbd_conf *mdev, struct drbd_request *req, const int rw) +{ + const unsigned long s = req->rq_state; + /* if it was a write, we may have to set the corresponding + * bit(s) out-of-sync first. If it had a local part, we need to + * release the reference to the activity log. */ + if (rw == WRITE) { + /* remove it from the transfer log. + * well, only if it had been there in the first + * place... if it had not (local only or conflicting + * and never sent), it should still be "empty" as + * initialised in drbd_req_new(), so we can list_del() it + * here unconditionally */ + list_del(&req->tl_requests); + /* Set out-of-sync unless both OK flags are set + * (local only or remote failed). + * Other places where we set out-of-sync: + * READ with local io-error */ + if (!(s & RQ_NET_OK) || !(s & RQ_LOCAL_OK)) + drbd_set_out_of_sync(mdev, req->sector, req->size); + + if ((s & RQ_NET_OK) && (s & RQ_LOCAL_OK) && (s & RQ_NET_SIS)) + drbd_set_in_sync(mdev, req->sector, req->size); + + /* one might be tempted to move the drbd_al_complete_io + * to the local io completion callback drbd_endio_pri. + * but, if this was a mirror write, we may only + * drbd_al_complete_io after this is RQ_NET_DONE, + * otherwise the extent could be dropped from the al + * before it has actually been written on the peer. + * if we crash before our peer knows about the request, + * but after the extent has been dropped from the al, + * we would forget to resync the corresponding extent. + */ + if (s & RQ_LOCAL_MASK) { + if (inc_local_if_state(mdev, Failed)) { + drbd_al_complete_io(mdev, req->sector); + dec_local(mdev); + } else if (DRBD_ratelimit(5*HZ,3)) { + drbd_WARN("Should have called drbd_al_complete_io(, %llu), " + "but my Disk seems to have failed :(\n", + (unsigned long long) req->sector); + } + } + } + + /* if it was a local io error, we want to notify our + * peer about that, and see if we need to + * detach the disk and stuff. + * to avoid allocating some special work + * struct, reuse the request. */ + + /* THINK + * why do we do this not when we detect the error, + * but delay it until it is "done", i.e. possibly + * until the next barrier ack? */ + + if (rw == WRITE && + ((s & RQ_LOCAL_MASK) && !(s & RQ_LOCAL_OK))) { + if (!(req->w.list.next == LIST_POISON1 || + list_empty(&req->w.list))) { + /* DEBUG ASSERT only; if this triggers, we + * probably corrupt the worker list here */ + DUMPP(req->w.list.next); + DUMPP(req->w.list.prev); + } + req->w.cb = w_io_error; + drbd_queue_work(&mdev->data.work, &req->w); + /* drbd_req_free() is done in w_io_error */ + } else { + drbd_req_free(req); + } +} + +static void queue_barrier(struct drbd_conf *mdev) +{ + struct drbd_barrier *b; + + /* We are within the req_lock. Once we queued the barrier for sending, + * we set the CREATE_BARRIER bit. It is cleared as soon as a new + * barrier/epoch object is added. This is the only place this bit is + * set. It indicates that the barrier for this epoch is already queued, + * and no new epoch has been created yet. */ + if (test_bit(CREATE_BARRIER, &mdev->flags)) + return; + + b = mdev->newest_barrier; + b->w.cb = w_send_barrier; + /* inc_ap_pending done here, so we won't + * get imbalanced on connection loss. + * dec_ap_pending will be done in got_BarrierAck + * or (on connection loss) in tl_clear. */ + inc_ap_pending(mdev); + drbd_queue_work(&mdev->data.work, &b->w); + set_bit(CREATE_BARRIER, &mdev->flags); +} + +static void _about_to_complete_local_write(struct drbd_conf *mdev, + struct drbd_request *req) +{ + const unsigned long s = req->rq_state; + struct drbd_request *i; + struct Tl_epoch_entry *e; + struct hlist_node *n; + struct hlist_head *slot; + + /* before we can signal completion to the upper layers, + * we may need to close the current epoch */ + if (mdev->state.conn >= Connected && + req->epoch == mdev->newest_barrier->br_number) + queue_barrier(mdev); + + /* we need to do the conflict detection stuff, + * if we have the ee_hash (two_primaries) and + * this has been on the network */ + if ((s & RQ_NET_DONE) && mdev->ee_hash != NULL) { + const sector_t sector = req->sector; + const int size = req->size; + + /* ASSERT: + * there must be no conflicting requests, since + * they must have been failed on the spot */ +#define OVERLAPS overlaps(sector, size, i->sector, i->size) + slot = tl_hash_slot(mdev, sector); + hlist_for_each_entry(i, n, slot, colision) { + if (OVERLAPS) { + ALERT("LOGIC BUG: completed: %p %llus +%u; " + "other: %p %llus +%u\n", + req, (unsigned long long)sector, size, + i, (unsigned long long)i->sector, i->size); + } + } + + /* maybe "wake" those conflicting epoch entries + * that wait for this request to finish. + * + * currently, there can be only _one_ such ee + * (well, or some more, which would be pending + * DiscardAck not yet sent by the asender...), + * since we block the receiver thread upon the + * first conflict detection, which will wait on + * misc_wait. maybe we want to assert that? + * + * anyways, if we found one, + * we just have to do a wake_up. */ +#undef OVERLAPS +#define OVERLAPS overlaps(sector, size, e->sector, e->size) + slot = ee_hash_slot(mdev, req->sector); + hlist_for_each_entry(e, n, slot, colision) { + if (OVERLAPS) { + wake_up(&mdev->misc_wait); + break; + } + } + } +#undef OVERLAPS +} + +static void _complete_master_bio(struct drbd_conf *mdev, + struct drbd_request *req, int error) +{ + dump_bio(mdev, req->master_bio, 1, req); + bio_endio(req->master_bio, error); + req->master_bio = NULL; + dec_ap_bio(mdev); +} + +void _req_may_be_done(struct drbd_request *req, int error) +{ + const unsigned long s = req->rq_state; + struct drbd_conf *mdev = req->mdev; + int rw; + + print_rq_state(req, "_req_may_be_done"); + MUST_HOLD(&mdev->req_lock) + + /* we must not complete the master bio, while it is + * still being processed by _drbd_send_zc_bio (drbd_send_dblock) + * not yet acknowledged by the peer + * not yet completed by the local io subsystem + * these flags may get cleared in any order by + * the worker, + * the receiver, + * the bio_endio completion callbacks. + */ + if (s & RQ_NET_QUEUED) + return; + if (s & RQ_NET_PENDING) + return; + if (s & RQ_LOCAL_PENDING) + return; + + if (req->master_bio) { + /* this is data_received (remote read) + * or protocol C WriteAck + * or protocol B RecvAck + * or protocol A "handed_over_to_network" (SendAck) + * or canceled or failed, + * or killed from the transfer log due to connection loss. + */ + + /* + * figure out whether to report success or failure. + * + * report success when at least one of the operations suceeded. + * or, to put the other way, + * only report failure, when both operations failed. + * + * what to do about the failures is handled elsewhere. + * what we need to do here is just: complete the master_bio. + */ + int ok = (s & RQ_LOCAL_OK) || (s & RQ_NET_OK); + rw = bio_data_dir(req->master_bio); + + /* remove the request from the conflict detection + * respective block_id verification hash */ + if (!hlist_unhashed(&req->colision)) + hlist_del(&req->colision); + else + D_ASSERT((s & RQ_NET_MASK) == 0); + + /* for writes we need to do some extra housekeeping */ + if (rw == WRITE) + _about_to_complete_local_write(mdev, req); + + /* FIXME not yet implemented... + * in case we got "suspended" (on_disconnect: freeze io) + * we may not yet complete the request... + * though, this is probably best handled elsewhere by not + * walking the transfer log until "unfreeze", so we won't end + * up here anyways during the freeze ... + * then again, if it is a READ, it is not in the TL at all. + * is it still leagal to complete a READ during freeze? */ + + /* Update disk stats */ + _drbd_end_io_acct(mdev, req); + + _complete_master_bio(mdev, req, + ok ? 0 : (error ? error : -EIO)); + } else { + /* only WRITE requests can end up here without a master_bio */ + rw = WRITE; + } + + if ((s & RQ_NET_MASK) == 0 || (s & RQ_NET_DONE)) { + /* this is disconnected (local only) operation, + * or protocol C WriteAck, + * or protocol A or B BarrierAck, + * or killed from the transfer log due to connection loss. */ + _req_is_done(mdev, req, rw); + } + /* else: network part and not DONE yet. that is + * protocol A or B, barrier ack still pending... */ +} + +/* + * checks whether there was an overlapping request + * or ee already registered. + * + * if so, return 1, in which case this request is completed on the spot, + * without ever being submitted or send. + * + * return 0 if it is ok to submit this request. + * + * NOTE: + * paranoia: assume something above us is broken, and issues different write + * requests for the same block simultaneously... + * + * To ensure these won't be reordered differently on both nodes, resulting in + * diverging data sets, we discard the later one(s). Not that this is supposed + * to happen, but this is the rationale why we also have to check for + * conflicting requests with local origin, and why we have to do so regardless + * of whether we allowed multiple primaries. + * + * BTW, in case we only have one primary, the ee_hash is empty anyways, and the + * second hlist_for_each_entry becomes a noop. This is even simpler than to + * grab a reference on the net_conf, and check for the two_primaries flag... + */ +STATIC int _req_conflicts(struct drbd_request *req) +{ + struct drbd_conf *mdev = req->mdev; + const sector_t sector = req->sector; + const int size = req->size; + struct drbd_request *i; + struct Tl_epoch_entry *e; + struct hlist_node *n; + struct hlist_head *slot; + + MUST_HOLD(&mdev->req_lock); + D_ASSERT(hlist_unhashed(&req->colision)); + + /* FIXME should this inc_net/dec_net + * rather be done in drbd_make_request_common? */ + if (!inc_net(mdev)) + return 0; + + /* BUG_ON */ + ERR_IF (mdev->tl_hash_s == 0) + goto out_no_conflict; + BUG_ON(mdev->tl_hash == NULL); + +#define OVERLAPS overlaps(i->sector, i->size, sector, size) + slot = tl_hash_slot(mdev, sector); + hlist_for_each_entry(i, n, slot, colision) { + if (OVERLAPS) { + ALERT("%s[%u] Concurrent local write detected! " + "[DISCARD L] new: %llus +%u; " + "pending: %llus +%u\n", + current->comm, current->pid, + (unsigned long long)sector, size, + (unsigned long long)i->sector, i->size); + goto out_conflict; + } + } + + if (mdev->ee_hash_s) { + /* now, check for overlapping requests with remote origin */ + BUG_ON(mdev->ee_hash == NULL); +#undef OVERLAPS +#define OVERLAPS overlaps(e->sector, e->size, sector, size) + slot = ee_hash_slot(mdev, sector); + hlist_for_each_entry(e, n, slot, colision) { + if (OVERLAPS) { + ALERT("%s[%u] Concurrent remote write detected!" + " [DISCARD L] new: %llus +%u; " + "pending: %llus +%u\n", + current->comm, current->pid, + (unsigned long long)sector, size, + (unsigned long long)e->sector, e->size); + goto out_conflict; + } + } + } +#undef OVERLAPS + +out_no_conflict: + /* this is like it should be, and what we expected. + * our users do behave after all... */ + dec_net(mdev); + return 0; + +out_conflict: + dec_net(mdev); + return 1; +} + +/* obviously this could be coded as many single functions + * instead of one huge switch, + * or by putting the code directly in the respective locations + * (as it has been before). + * + * but having it this way + * enforces that it is all in this one place, where it is easier to audit, + * it makes it obvious that whatever "event" "happens" to a request should + * happen "atomically" within the req_lock, + * and it enforces that we have to think in a very structured manner + * about the "events" that may happen to a request during its life time ... + * + * Though I think it is likely that we break this again into many + * static inline void _req_mod_ ## what (req) ... + */ +void _req_mod(struct drbd_request *req, enum drbd_req_event what, int error) +{ + struct drbd_conf *mdev = req->mdev; + MUST_HOLD(&mdev->req_lock); + + if (error && (bio_rw(req->master_bio) != READA)) + ERR("got an _req_mod() errno of %d\n", error); + + print_req_mod(req, what); + + switch (what) { + default: + ERR("LOGIC BUG in %s:%u\n", __FILE__ , __LINE__); + return; + + /* does not happen... + * initialization done in drbd_req_new + case created: + break; + */ + + case to_be_send: /* via network */ + /* reached via drbd_make_request_common + * and from FIXME w_read_retry_remote */ + D_ASSERT(!(req->rq_state & RQ_NET_MASK)); + req->rq_state |= RQ_NET_PENDING; + inc_ap_pending(mdev); + break; + + case to_be_submitted: /* locally */ + /* reached via drbd_make_request_common */ + D_ASSERT(!(req->rq_state & RQ_LOCAL_MASK)); + req->rq_state |= RQ_LOCAL_PENDING; + break; + + /* FIXME these *_completed_* are basically the same. + * can probably be merged with some if (what == xy) */ + + case completed_ok: + if (bio_data_dir(req->private_bio) == WRITE) + mdev->writ_cnt += req->size>>9; + else + mdev->read_cnt += req->size>>9; + + bio_put(req->private_bio); + req->private_bio = NULL; + + req->rq_state |= (RQ_LOCAL_COMPLETED|RQ_LOCAL_OK); + req->rq_state &= ~RQ_LOCAL_PENDING; + + _req_may_be_done(req, error); + dec_local(mdev); + break; + + case write_completed_with_error: + req->rq_state |= RQ_LOCAL_COMPLETED; + req->rq_state &= ~RQ_LOCAL_PENDING; + + bio_put(req->private_bio); + req->private_bio = NULL; + ALERT("Local WRITE failed sec=%llus size=%u\n", + (unsigned long long)req->sector, req->size); + /* and now: check how to handle local io error. + * FIXME see comment below in read_completed_with_error */ + __drbd_chk_io_error(mdev, FALSE); + _req_may_be_done(req, error); + dec_local(mdev); + break; + + case read_completed_with_error: + if (bio_rw(req->master_bio) != READA) + drbd_set_out_of_sync(mdev, req->sector, req->size); + + req->rq_state |= RQ_LOCAL_COMPLETED; + req->rq_state &= ~RQ_LOCAL_PENDING; + + bio_put(req->private_bio); + req->private_bio = NULL; + if (bio_rw(req->master_bio) == READA) { + /* it is legal to fail READA */ + _req_may_be_done(req, error); + dec_local(mdev); + break; + } + /* else */ + ALERT("Local READ failed sec=%llus size=%u\n", + (unsigned long long)req->sector, req->size); + /* _req_mod(req,to_be_send); oops, recursion in static inline */ + D_ASSERT(!(req->rq_state & RQ_NET_MASK)); + req->rq_state |= RQ_NET_PENDING; + inc_ap_pending(mdev); + + /* and now: check how to handle local io error. + * + * FIXME we should not handle WRITE and READ io errors + * the same. When we retry the READ, and then write + * the answer, that might suceed because modern drives + * would relocate the sectors. We'd need to keep our + * private bio then, and round the offset and size so + * we get back enough data to be able to clear the bits again. + */ + __drbd_chk_io_error(mdev, FALSE); + dec_local(mdev); + /* NOTE: if we have no connection, + * or know the peer has no good data either, + * then we don't actually need to "queue_for_net_read", + * but we do so anyways, since the drbd_io_error() + * and the potential state change to "Diskless" + * needs to be done from process context */ + + /* fall through: _req_mod(req,queue_for_net_read); */ + + case queue_for_net_read: + /* READ or READA, and + * no local disk, + * or target area marked as invalid, + * or just got an io-error. */ + /* from drbd_make_request_common + * or from bio_endio during read io-error recovery */ + + /* so we can verify the handle in the answer packet + * corresponding hlist_del is in _req_may_be_done() */ + hlist_add_head(&req->colision, ar_hash_slot(mdev, req->sector)); + + set_bit(UNPLUG_REMOTE, &mdev->flags); /* why? */ + + D_ASSERT(req->rq_state & RQ_NET_PENDING); + req->rq_state |= RQ_NET_QUEUED; + req->w.cb = (req->rq_state & RQ_LOCAL_MASK) + ? w_read_retry_remote + : w_send_read_req; + drbd_queue_work(&mdev->data.work, &req->w); + break; + + case queue_for_net_write: + /* assert something? */ + /* from drbd_make_request_common only */ + + hlist_add_head(&req->colision, tl_hash_slot(mdev, req->sector)); + /* corresponding hlist_del is in _req_may_be_done() */ + + /* NOTE + * In case the req ended up on the transfer log before being + * queued on the worker, it could lead to this request being + * missed during cleanup after connection loss. + * So we have to do both operations here, + * within the same lock that protects the transfer log. + * + * _req_add_to_epoch(req); this has to be after the + * _maybe_start_new_epoch(req); which happened in + * drbd_make_request_common, because we now may set the bit + * again ourselves to close the current epoch. + * + * Add req to the (now) current epoch (barrier). */ + + /* see drbd_make_request_common, + * just after it grabs the req_lock */ + D_ASSERT(test_bit(CREATE_BARRIER, &mdev->flags) == 0); + + req->epoch = mdev->newest_barrier->br_number; + list_add_tail(&req->tl_requests, + &mdev->newest_barrier->requests); + + /* increment size of current epoch */ + mdev->newest_barrier->n_req++; + + /* queue work item to send data */ + D_ASSERT(req->rq_state & RQ_NET_PENDING); + req->rq_state |= RQ_NET_QUEUED; + req->w.cb = w_send_dblock; + drbd_queue_work(&mdev->data.work, &req->w); + + /* close the epoch, in case it outgrew the limit */ + if (mdev->newest_barrier->n_req >= mdev->net_conf->max_epoch_size) + queue_barrier(mdev); + + break; + + /* FIXME + * to implement freeze-io, + * we may not finish the request just yet. + */ + case send_canceled: + /* treat it the same */ + case send_failed: + /* real cleanup will be done from tl_clear. just update flags + * so it is no longer marked as on the worker queue */ + req->rq_state &= ~RQ_NET_QUEUED; + /* if we did it right, tl_clear should be scheduled only after + * this, so this should not be necessary! */ + _req_may_be_done(req, error); + break; + + case handed_over_to_network: + /* assert something? */ + if (bio_data_dir(req->master_bio) == WRITE && + mdev->net_conf->wire_protocol == DRBD_PROT_A) { + /* this is what is dangerous about protocol A: + * pretend it was sucessfully written on the peer. + * FIXME in case we get a local io-error in + * protocol != C, we might want to defer comletion + * until we get the barrier ack, and send a NegAck + * in case the other node had an io-error, too... + * That way we would at least not report "success" + * if it was not written at all. */ + if (req->rq_state & RQ_NET_PENDING) { + dec_ap_pending(mdev); + req->rq_state &= ~RQ_NET_PENDING; + req->rq_state |= RQ_NET_OK; + } /* else: neg-ack was faster... */ + /* it is still not yet RQ_NET_DONE until the + * corresponding epoch barrier got acked as well, + * so we know what to dirty on connection loss */ + } + req->rq_state &= ~RQ_NET_QUEUED; + req->rq_state |= RQ_NET_SENT; + /* because _drbd_send_zc_bio could sleep, and may want to + * dereference the bio even after the "write_acked_by_peer" and + * "completed_ok" events came in, once we return from + * _drbd_send_zc_bio (drbd_send_dblock), we have to check + * whether it is done already, and end it. */ + _req_may_be_done(req, error); + break; + + case connection_lost_while_pending: + /* transfer log cleanup after connection loss */ + /* assert something? */ + if (req->rq_state & RQ_NET_PENDING) + dec_ap_pending(mdev); + req->rq_state &= ~(RQ_NET_OK|RQ_NET_PENDING); + req->rq_state |= RQ_NET_DONE; + /* if it is still queued, we may not complete it here. + * it will be canceled soon. + * FIXME we should change the code so this can not happen. */ + if (!(req->rq_state & RQ_NET_QUEUED)) + _req_may_be_done(req, error); + break; + + case write_acked_by_peer_and_sis: + req->rq_state |= RQ_NET_SIS; + case conflict_discarded_by_peer: + /* for discarded conflicting writes of multiple primarys, + * there is no need to keep anything in the tl, potential + * node crashes are covered by the activity log. */ + req->rq_state |= RQ_NET_DONE; + /* fall through */ + case write_acked_by_peer: + /* protocol C; successfully written on peer. + * Nothing to do here. + * We want to keep the tl in place for all protocols, to cater + * for volatile write-back caches on lower level devices. + * + * A barrier request is expected to have forced all prior + * requests onto stable storage, so completion of a barrier + * request could set NET_DONE right here, and not wait for the + * BarrierAck, but that is an unecessary optimisation. */ + + /* this makes it effectively the same as for: */ + case recv_acked_by_peer: + /* protocol B; pretends to be sucessfully written on peer. + * see also notes above in handed_over_to_network about + * protocol != C */ + req->rq_state |= RQ_NET_OK; + D_ASSERT(req->rq_state & RQ_NET_PENDING); + dec_ap_pending(mdev); + req->rq_state &= ~RQ_NET_PENDING; + _req_may_be_done(req, error); + break; + + case neg_acked: + /* assert something? */ + if (req->rq_state & RQ_NET_PENDING) + dec_ap_pending(mdev); + req->rq_state &= ~(RQ_NET_OK|RQ_NET_PENDING); + /* FIXME THINK! is it DONE now, or is it not? */ + req->rq_state |= RQ_NET_DONE; + _req_may_be_done(req, error); + /* else: done by handed_over_to_network */ + break; + + case barrier_acked: + if (req->rq_state & RQ_NET_PENDING) { + /* barrier came in before all requests have been acked. + * this is bad, because if the connection is lost now, + * we won't be able to clean them up... */ + _print_rq_state(req, + "FIXME (barrier_acked but pending)"); + list_move(&req->tl_requests, &mdev->out_of_sequence_requests); + } + D_ASSERT(req->rq_state & RQ_NET_SENT); + req->rq_state |= RQ_NET_DONE; + _req_may_be_done(req, error); + break; + + case data_received: + D_ASSERT(req->rq_state & RQ_NET_PENDING); + dec_ap_pending(mdev); + req->rq_state &= ~RQ_NET_PENDING; + req->rq_state |= (RQ_NET_OK|RQ_NET_DONE); + _req_may_be_done(req, error); + break; + }; +} + +/* we may do a local read if: + * - we are consistent (of course), + * - or we are generally inconsistent, + * BUT we are still/already IN SYNC for this area. + * since size may be bigger than BM_BLOCK_SIZE, + * we may need to check several bits. + */ +STATIC int drbd_may_do_local_read(struct drbd_conf *mdev, sector_t sector, int size) +{ + unsigned long sbnr, ebnr; + sector_t esector, nr_sectors; + + if (mdev->state.disk == UpToDate) + return 1; + if (mdev->state.disk >= Outdated) + return 0; + if (mdev->state.disk < Inconsistent) + return 0; + /* state.disk == Inconsistent We will have a look at the BitMap */ + nr_sectors = drbd_get_capacity(mdev->this_bdev); + esector = sector + (size >> 9) - 1; + + D_ASSERT(sector < nr_sectors); + D_ASSERT(esector < nr_sectors); + + sbnr = BM_SECT_TO_BIT(sector); + ebnr = BM_SECT_TO_BIT(esector); + + return 0 == drbd_bm_count_bits(mdev, sbnr, ebnr); +} + +/* + * general note: + * looking at the state (conn, disk, susp, pdsk) outside of the spinlock that + * protects the state changes is inherently racy. + * + * FIXME verify this rationale why we may do so anyways: + * + * I think it "should" be like this: + * as soon as we have a "ap_bio_cnt" reference we may test for "bad" states, + * because the transition from "bad" to "good" states may only happen while no + * application request is on the fly, so once we are positive about a "bad" + * state, we know it won't get better during the lifetime of this request. + * + * In case we think we are ok, but "asynchronously" some interrupt or other + * thread marks some operation as impossible, we are still ok, since we would + * just try anyways, and then see that it does not work there and then. + */ + +STATIC int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio) +{ + const int rw = bio_rw(bio); + const int size = bio->bi_size; + const sector_t sector = bio->bi_sector; + struct drbd_barrier *b = NULL; + struct drbd_request *req; + int local, remote; + int err = -EIO; + + /* allocate outside of all locks; */ + req = drbd_req_new(mdev, bio); + if (!req) { + dec_ap_bio(mdev); + /* only pass the error to the upper layers. + * if user cannot handle io errors, thats not our business. */ + ERR("could not kmalloc() req\n"); + bio_endio(bio, -ENOMEM); + return 0; + } + + dump_bio(mdev, bio, 0, req); + + local = inc_local(mdev); + if (!local) { + bio_put(req->private_bio); /* or we get a bio leak */ + req->private_bio = NULL; + } + if (rw == WRITE) { + remote = 1; + } else { + /* READ || READA */ + if (local) { + if (!drbd_may_do_local_read(mdev, sector, size)) { + /* we could kick the syncer to + * sync this extent asap, wait for + * it, then continue locally. + * Or just issue the request remotely. + */ + /* FIXME + * I think we have a RACE here. We request + * something from the peer, then later some + * write starts ... and finished *before* + * the answer to the read comes in, because + * the ACK for the WRITE goes over + * meta-socket ... + * Maybe we need to properly lock reads + * against the syncer, too. But if we have + * some user issuing writes on an area that + * he has pending reads on, _he_ is really + * broke anyways, and would get "undefined + * results" on _any_ io stack, even just the + * local io stack. + */ + + local = 0; + bio_put(req->private_bio); + req->private_bio = NULL; + dec_local(mdev); + } + } + remote = !local && mdev->state.pdsk >= UpToDate; + } + + /* If we have a disk, but a READA request is mapped to remote, + * we are Primary, Inconsistent, SyncTarget. + * Just fail that READA request right here. + * + * THINK: maybe fail all READA when not local? + * or make this configurable... + * if network is slow, READA won't do any good. + */ + if (rw == READA && mdev->state.disk >= Inconsistent && !local) { + err = -EWOULDBLOCK; + goto fail_and_free_req; + } + + /* For WRITES going to the local disk, grab a reference on the target + * extent. This waits for any resync activity in the corresponding + * resync extent to finish, and, if necessary, pulls in the target + * extent into the activity log, which involves further disk io because + * of transactional on-disk meta data updates. */ + if (rw == WRITE && local) + drbd_al_begin_io(mdev, sector); + + remote = remote && (mdev->state.pdsk == UpToDate || + (mdev->state.pdsk == Inconsistent && + mdev->state.conn >= Connected)); + + if (!(local || remote)) { + ERR("IO ERROR: neither local nor remote disk\n"); + goto fail_free_complete; + } + + /* For WRITE request, we have to make sure that we have an + * unused_spare_barrier, in case we need to start a new epoch. + * I try to be smart and avoid to pre-allocate always "just in case", + * but there is a race between testing the bit and pointer outside the + * spinlock, and grabbing the spinlock. + * if we lost that race, we retry. */ + if (rw == WRITE && remote && + mdev->unused_spare_barrier == NULL && + test_bit(CREATE_BARRIER, &mdev->flags)) { +allocate_barrier: + b = kmalloc(sizeof(struct drbd_barrier), GFP_NOIO); + if (!b) { + ERR("Failed to alloc barrier.\n"); + err = -ENOMEM; + goto fail_free_complete; + } + } + + /* GOOD, everything prepared, grab the spin_lock */ + spin_lock_irq(&mdev->req_lock); + + /* FIXME race with drbd_disconnect and tl_clear? */ + if (remote) { + remote = (mdev->state.pdsk == UpToDate || + (mdev->state.pdsk == Inconsistent && + mdev->state.conn >= Connected)); + if (!remote) + drbd_WARN("lost connection while grabbing the req_lock!\n"); + if (!(local || remote)) { + ERR("IO ERROR: neither local nor remote disk\n"); + spin_unlock_irq(&mdev->req_lock); + goto fail_free_complete; + } + } + + if (b && mdev->unused_spare_barrier == NULL) { + mdev->unused_spare_barrier = b; + b = NULL; + } + if (rw == WRITE && remote && + mdev->unused_spare_barrier == NULL && + test_bit(CREATE_BARRIER, &mdev->flags)) { + /* someone closed the current epoch + * while we were grabbing the spinlock */ + spin_unlock_irq(&mdev->req_lock); + goto allocate_barrier; + } + + + /* Update disk stats */ + _drbd_start_io_acct(mdev, req, bio); + + /* _maybe_start_new_epoch(mdev); + * If we need to generate a write barrier packet, we have to add the + * new epoch (barrier) object, and queue the barrier packet for sending, + * and queue the req's data after it _within the same lock_, otherwise + * we have race conditions were the reorder domains could be mixed up. + * + * Even read requests may start a new epoch and queue the corresponding + * barrier packet. To get the write ordering right, we only have to + * make sure that, if this is a write request and it triggered a + * barrier packet, this request is queued within the same spinlock. */ + if (remote && mdev->unused_spare_barrier && + test_and_clear_bit(CREATE_BARRIER, &mdev->flags)) { + _tl_add_barrier(mdev, mdev->unused_spare_barrier); + mdev->unused_spare_barrier = NULL; + } else { + D_ASSERT(!(remote && rw == WRITE && + test_bit(CREATE_BARRIER, &mdev->flags))); + } + + /* NOTE + * Actually, 'local' may be wrong here already, since we may have failed + * to write to the meta data, and may become wrong anytime because of + * local io-error for some other request, which would lead to us + * "detaching" the local disk. + * + * 'remote' may become wrong any time because the network could fail. + * + * This is a harmless race condition, though, since it is handled + * correctly at the appropriate places; so it just deferres the failure + * of the respective operation. + */ + + /* mark them early for readability. + * this just sets some state flags. */ + if (remote) + _req_mod(req, to_be_send, 0); + if (local) + _req_mod(req, to_be_submitted, 0); + + /* check this request on the colison detection hash tables. + * if we have a conflict, just complete it here. + * THINK do we want to check reads, too? (I don't think so...) */ + if (rw == WRITE && _req_conflicts(req)) { + /* this is a conflicting request. + * even though it may have been only _partially_ + * overlapping with one of the currently pending requests, + * without even submitting or sending it, we will + * pretend that it was successfully served right now. + */ + if (local) { + bio_put(req->private_bio); + req->private_bio = NULL; + drbd_al_complete_io(mdev, req->sector); + dec_local(mdev); + local = 0; + } + if (remote) + dec_ap_pending(mdev); + _drbd_end_io_acct(mdev, req); + /* THINK: do we want to fail it (-EIO), or pretend success? */ + bio_endio(req->master_bio, 0); + req->master_bio = NULL; + dec_ap_bio(mdev); + drbd_req_free(req); + remote = 0; + } + + /* NOTE remote first: to get the concurrent write detection right, + * we must register the request before start of local IO. */ + if (remote) { + /* either WRITE and Connected, + * or READ, and no local disk, + * or READ, but not in sync. + */ + if (rw == WRITE) + _req_mod(req, queue_for_net_write, 0); + else + _req_mod(req, queue_for_net_read, 0); + } + spin_unlock_irq(&mdev->req_lock); + kfree(b); /* if someone else has beaten us to it... */ + + if (local) { + req->private_bio->bi_bdev = mdev->bc->backing_bdev; + + dump_internal_bio("Pri", mdev, req->private_bio, 0); + + if (FAULT_ACTIVE(mdev, rw == WRITE ? DRBD_FAULT_DT_WR + : rw == READ ? DRBD_FAULT_DT_RD + : DRBD_FAULT_DT_RA)) + bio_endio(req->private_bio, -EIO); + else + generic_make_request(req->private_bio); + } + + /* we need to plug ALWAYS since we possibly need to kick lo_dev. + * we plug after submit, so we won't miss an unplug event */ + drbd_plug_device(mdev); + + return 0; + +fail_free_complete: + if (rw == WRITE && local) + drbd_al_complete_io(mdev, sector); +fail_and_free_req: + if (local) { + bio_put(req->private_bio); + req->private_bio = NULL; + dec_local(mdev); + } + bio_endio(bio, err); + drbd_req_free(req); + dec_ap_bio(mdev); + kfree(b); + + return 0; +} + +/* helper function for drbd_make_request + * if we can determine just by the mdev (state) that this request will fail, + * return 1 + * otherwise return 0 + */ +static int drbd_fail_request_early(struct drbd_conf *mdev, int is_write) +{ + /* Unconfigured */ + if (mdev->state.conn == Disconnecting && + mdev->state.disk == Diskless) + return 1; + + if (mdev->state.role != Primary && + (!allow_oos || is_write)) { + if (DRBD_ratelimit(5*HZ, 5)) { + ERR("Process %s[%u] tried to %s; " + "since we are not in Primary state, " + "we cannot allow this\n", + current->comm, current->pid, + is_write ? "WRITE" : "READ"); + } + return 1; + } + + /* + * Paranoia: we might have been primary, but sync target, or + * even diskless, then lost the connection. + * This should have been handled (panic? suspend?) somehwere + * else. But maybe it was not, so check again here. + * Caution: as long as we do not have a read/write lock on mdev, + * to serialize state changes, this is racy, since we may lose + * the connection *after* we test for the cstate. + */ + if (mdev->state.disk < UpToDate && mdev->state.pdsk < UpToDate) { + if (DRBD_ratelimit(5*HZ, 5)) + ERR("Sorry, I have no access to good data anymore.\n"); + /* + * FIXME suspend, loop waiting on cstate wait? + */ + return 1; + } + + return 0; +} + +int drbd_make_request_26(struct request_queue *q, struct bio *bio) +{ + unsigned int s_enr, e_enr; + struct drbd_conf *mdev = (struct drbd_conf *) q->queuedata; + + if (drbd_fail_request_early(mdev, bio_data_dir(bio) & WRITE)) { + bio_endio(bio, -EPERM); + return 0; + } + + /* Reject barrier requests if we know the underlying device does + * not support them. + * XXX: Need to get this info from peer as well some how so we + * XXX: reject if EITHER side/data/metadata area does not support them. + * + * because of those XXX, this is not yet enabled, + * i.e. in drbd_init_set_defaults we set the NO_BARRIER_SUPP bit. + */ + if (unlikely(bio_barrier(bio) && test_bit(NO_BARRIER_SUPP, &mdev->flags))) { + /* drbd_WARN("Rejecting barrier request as underlying device does not support\n"); */ + bio_endio(bio, -EOPNOTSUPP); + return 0; + } + + /* + * what we "blindly" assume: + */ + D_ASSERT(bio->bi_size > 0); + D_ASSERT((bio->bi_size & 0x1ff) == 0); + D_ASSERT(bio->bi_idx == 0); + + /* to make some things easier, force allignment of requests within the + * granularity of our hash tables */ + s_enr = bio->bi_sector >> HT_SHIFT; + e_enr = (bio->bi_sector+(bio->bi_size>>9)-1) >> HT_SHIFT; + + if (likely(s_enr == e_enr)) { + inc_ap_bio(mdev, 1); + return drbd_make_request_common(mdev, bio); + } + + /* can this bio be split generically? + * Maybe add our own split-arbitrary-bios function. */ + if (bio->bi_vcnt != 1 || bio->bi_idx != 0 || bio->bi_size > DRBD_MAX_SEGMENT_SIZE) { + /* rather error out here than BUG in bio_split */ + ERR("bio would need to, but cannot, be split: " + "(vcnt=%u,idx=%u,size=%u,sector=%llu)\n", + bio->bi_vcnt, bio->bi_idx, bio->bi_size, + (unsigned long long)bio->bi_sector); + bio_endio(bio, -EINVAL); + } else { + /* This bio crosses some boundary, so we have to split it. */ + struct bio_pair *bp; + /* works for the "do not cross hash slot boundaries" case + * e.g. sector 262269, size 4096 + * s_enr = 262269 >> 6 = 4097 + * e_enr = (262269+8-1) >> 6 = 4098 + * HT_SHIFT = 6 + * sps = 64, mask = 63 + * first_sectors = 64 - (262269 & 63) = 3 + */ + const sector_t sect = bio->bi_sector; + const int sps = 1 << HT_SHIFT; /* sectors per slot */ + const int mask = sps - 1; + const sector_t first_sectors = sps - (sect & mask); + bp = bio_split(bio, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) + bio_split_pool, +#endif + first_sectors); + + /* we need to get a "reference count" (ap_bio_cnt) + * to avoid races with the disconnect/reconnect/suspend code. + * In case we need to split the bio here, we need to get two references + * atomically, otherwise we might deadlock when trying to submit the + * second one! */ + inc_ap_bio(mdev, 2); + + D_ASSERT(e_enr == s_enr + 1); + + drbd_make_request_common(mdev, &bp->bio1); + drbd_make_request_common(mdev, &bp->bio2); + bio_pair_release(bp); + } + return 0; +} + +/* This is called by bio_add_page(). With this function we reduce + * the number of BIOs that span over multiple DRBD_MAX_SEGMENT_SIZEs + * units (was AL_EXTENTs). + * + * we do the calculation within the lower 32bit of the byte offsets, + * since we don't care for actual offset, but only check whether it + * would cross "activity log extent" boundaries. + * + * As long as the BIO is emtpy we have to allow at least one bvec, + * regardless of size and offset. so the resulting bio may still + * cross extent boundaries. those are dealt with (bio_split) in + * drbd_make_request_26. + */ +int drbd_merge_bvec(struct request_queue *q, +#ifdef HAVE_bvec_merge_data + struct bvec_merge_data *bvm, +#else + struct bio *bvm, +#endif + struct bio_vec *bvec) +{ + struct drbd_conf *mdev = (struct drbd_conf *) q->queuedata; + unsigned int bio_offset = + (unsigned int)bvm->bi_sector << 9; /* 32 bit */ + unsigned int bio_size = bvm->bi_size; + int limit, backing_limit; + + limit = DRBD_MAX_SEGMENT_SIZE + - ((bio_offset & (DRBD_MAX_SEGMENT_SIZE-1)) + bio_size); + if (limit < 0) + limit = 0; + if (bio_size == 0) { + if (limit <= bvec->bv_len) + limit = bvec->bv_len; + } else if (limit && inc_local(mdev)) { + struct request_queue * const b = + mdev->bc->backing_bdev->bd_disk->queue; + if (b->merge_bvec_fn && mdev->bc->dc.use_bmbv) { + backing_limit = b->merge_bvec_fn(b, bvm, bvec); + limit = min(limit, backing_limit); + } + dec_local(mdev); + } + return limit; +} --- linux-2.6.28.orig/ubuntu/drbd/Makefile +++ linux-2.6.28/ubuntu/drbd/Makefile @@ -0,0 +1,9 @@ +#CFLAGS_drbd_sizeof_sanity_check.o = -Wpadded # -Werror + +drbd-objs := drbd_buildtag.o drbd_bitmap.o drbd_proc.o \ + drbd_worker.o drbd_receiver.o drbd_req.o drbd_actlog.o \ + lru_cache.o drbd_main.o drbd_strings.o drbd_nl.o + +EXTRA_CFLAGS += -I$(src) + +obj-$(CONFIG_BLK_DEV_DRBD) += drbd.o --- linux-2.6.28.orig/ubuntu/drbd/drbd_actlog.c +++ linux-2.6.28/ubuntu/drbd/drbd_actlog.c @@ -0,0 +1,1514 @@ +/* +-*- linux-c -*- + drbd_actlog.c + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2003-2008, LINBIT Information Technologies GmbH. + Copyright (C) 2003-2008, Philipp Reisner . + Copyright (C) 2003-2008, Lars Ellenberg . + + drbd is free software; you can redistribute 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. + + drbd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + */ + +#include +#include +#include "drbd_int.h" + +/* This is what I like so much about the linux kernel: + * if you have a close look, you can almost always reuse code by someone else + * ;) + * this is mostly from drivers/md/md.c + */ +STATIC int _drbd_md_sync_page_io(struct drbd_conf *mdev, + struct drbd_backing_dev *bdev, + struct page *page, sector_t sector, + int rw, int size) +{ + struct bio *bio; + struct drbd_md_io md_io; + int ok; + + md_io.mdev = mdev; + init_completion(&md_io.event); + md_io.error = 0; + + if (rw == WRITE && !test_bit(MD_NO_BARRIER, &mdev->flags)) + rw |= (1<bi_bdev = bdev->md_bdev; + bio->bi_sector = sector; + ok = (bio_add_page(bio, page, size, 0) == size); + if (!ok) + goto out; + bio->bi_private = &md_io; + bio->bi_end_io = drbd_md_io_complete; + bio->bi_rw = rw; + + dump_internal_bio("Md", mdev, bio, 0); + + if (FAULT_ACTIVE(mdev, (rw & WRITE) ? DRBD_FAULT_MD_WR : DRBD_FAULT_MD_RD)) + bio_endio(bio, -EIO); + else + submit_bio(rw, bio); + wait_for_completion(&md_io.event); + ok = bio_flagged(bio, BIO_UPTODATE) && md_io.error == 0; + + /* check for unsupported barrier op. + * would rather check on EOPNOTSUPP, but that is not reliable. + * don't try again for ANY return value != 0 */ + if (unlikely(bio_barrier(bio) && !ok)) { + /* Try again with no barrier */ + drbd_WARN("Barriers not supported on meta data device - disabling\n"); + set_bit(MD_NO_BARRIER, &mdev->flags); + rw &= ~(1 << BIO_RW_BARRIER); + bio_put(bio); + goto retry; + } + out: + bio_put(bio); + return ok; +} + +int drbd_md_sync_page_io(struct drbd_conf *mdev, struct drbd_backing_dev *bdev, + sector_t sector, int rw) +{ + int hardsect, mask, ok; + int offset = 0; + struct page *iop = mdev->md_io_page; + + D_ASSERT(semaphore_is_locked(&mdev->md_io_mutex)); + + if (!bdev->md_bdev) { + if (DRBD_ratelimit(5*HZ, 5)) { + ERR("bdev->md_bdev==NULL\n"); + dump_stack(); + } + return 0; + } + + hardsect = drbd_get_hardsect(bdev->md_bdev); + if (hardsect == 0) + hardsect = MD_HARDSECT; + + /* in case hardsect != 512 [ s390 only? ] */ + if (hardsect != MD_HARDSECT) { + if (!mdev->md_io_tmpp) { + struct page *page = alloc_page(GFP_NOIO); + if (!page) + return 0; + + drbd_WARN("Meta data's bdev hardsect = %d != %d\n", + hardsect, MD_HARDSECT); + drbd_WARN("Workaround engaged (has performace impact).\n"); + + mdev->md_io_tmpp = page; + } + + mask = (hardsect / MD_HARDSECT) - 1; + D_ASSERT(mask == 1 || mask == 3 || mask == 7); + D_ASSERT(hardsect == (mask+1) * MD_HARDSECT); + offset = sector & mask; + sector = sector & ~mask; + iop = mdev->md_io_tmpp; + + if (rw == WRITE) { + void *p = page_address(mdev->md_io_page); + void *hp = page_address(mdev->md_io_tmpp); + + ok = _drbd_md_sync_page_io(mdev, bdev, iop, + sector, READ, hardsect); + + if (unlikely(!ok)) { + ERR("drbd_md_sync_page_io(,%llus," + "READ [hardsect!=512]) failed!\n", + (unsigned long long)sector); + return 0; + } + + memcpy(hp + offset*MD_HARDSECT , p, MD_HARDSECT); + } + } + +#if DUMP_MD >= 3 + INFO("%s [%d]:%s(,%llus,%s)\n", + current->comm, current->pid, __func__, + (unsigned long long)sector, rw ? "WRITE" : "READ"); +#endif + + if (sector < drbd_md_first_sector(bdev) || + sector > drbd_md_last_sector(bdev)) + ALERT("%s [%d]:%s(,%llus,%s) out of range md access!\n", + current->comm, current->pid, __func__, + (unsigned long long)sector, rw ? "WRITE" : "READ"); + + ok = _drbd_md_sync_page_io(mdev, bdev, iop, sector, rw, hardsect); + if (unlikely(!ok)) { + ERR("drbd_md_sync_page_io(,%llus,%s) failed!\n", + (unsigned long long)sector, rw ? "WRITE" : "READ"); + return 0; + } + + if (hardsect != MD_HARDSECT && rw == READ) { + void *p = page_address(mdev->md_io_page); + void *hp = page_address(mdev->md_io_tmpp); + + memcpy(p, hp + offset*MD_HARDSECT, MD_HARDSECT); + } + + return ok; +} + +/* I do not believe that all storage medias can guarantee atomic + * 512 byte write operations. When the journal is read, only + * transactions with correct xor_sums are considered. + * sizeof() = 512 byte */ +struct __attribute__((packed)) al_transaction { + u32 magic; + u32 tr_number; + /* u32 tr_generation; TODO */ + struct __attribute__((packed)) { + u32 pos; + u32 extent; } updates[1 + AL_EXTENTS_PT]; + u32 xor_sum; +}; + +struct update_odbm_work { + struct drbd_work w; + unsigned int enr; +}; + +struct update_al_work { + struct drbd_work w; + struct lc_element *al_ext; + struct completion event; + unsigned int enr; + /* if old_enr != LC_FREE, write corresponding bitmap sector, too */ + unsigned int old_enr; +}; + +int w_al_write_transaction(struct drbd_conf *, struct drbd_work *, int); + +static inline +struct lc_element *_al_get(struct drbd_conf *mdev, unsigned int enr) +{ + struct lc_element *al_ext; + struct bm_extent *bm_ext; + unsigned long al_flags = 0; + + spin_lock_irq(&mdev->al_lock); + bm_ext = (struct bm_extent *) + lc_find(mdev->resync, enr/AL_EXT_PER_BM_SECT); + if (unlikely(bm_ext != NULL)) { + if (test_bit(BME_NO_WRITES, &bm_ext->flags)) { + spin_unlock_irq(&mdev->al_lock); + return NULL; + } + } + al_ext = lc_get(mdev->act_log, enr); + al_flags = mdev->act_log->flags; + spin_unlock_irq(&mdev->al_lock); + + /* + if (!al_ext) { + if (al_flags & LC_STARVING) + drbd_WARN("Have to wait for LRU element (AL too small?)\n"); + if (al_flags & LC_DIRTY) + drbd_WARN("Ongoing AL update (AL device too slow?)\n"); + } + */ + + return al_ext; +} + +/* FIXME + * this should be able to return failure when meta data update has failed. + */ +void drbd_al_begin_io(struct drbd_conf *mdev, sector_t sector) +{ + unsigned int enr = (sector >> (AL_EXTENT_SIZE_B-9)); + struct lc_element *al_ext; + struct update_al_work al_work; + + D_ASSERT(atomic_read(&mdev->local_cnt) > 0); + + MTRACE(TraceTypeALExts, TraceLvlMetrics, + INFO("al_begin_io( sec=%llus (al_enr=%u) (rs_enr=%d) )\n", + (unsigned long long) sector, enr, + (int)BM_SECT_TO_EXT(sector)); + ); + + wait_event(mdev->al_wait, (al_ext = _al_get(mdev, enr))); + + if (al_ext->lc_number != enr) { + /* drbd_al_write_transaction(mdev,al_ext,enr); + generic_make_request() are serialized on the + current->bio_tail list now. Therefore we have + to deligate writing something to AL to the + worker thread. */ + init_completion(&al_work.event); + al_work.al_ext = al_ext; + al_work.enr = enr; + al_work.old_enr = al_ext->lc_number; + al_work.w.cb = w_al_write_transaction; + drbd_queue_work_front(&mdev->data.work, &al_work.w); + wait_for_completion(&al_work.event); + + mdev->al_writ_cnt++; + + /* + DUMPI(al_ext->lc_number); + DUMPI(mdev->act_log->new_number); + */ + spin_lock_irq(&mdev->al_lock); + lc_changed(mdev->act_log, al_ext); + spin_unlock_irq(&mdev->al_lock); + wake_up(&mdev->al_wait); + } +} + +void drbd_al_complete_io(struct drbd_conf *mdev, sector_t sector) +{ + unsigned int enr = (sector >> (AL_EXTENT_SIZE_B-9)); + struct lc_element *extent; + unsigned long flags; + + MTRACE(TraceTypeALExts, TraceLvlMetrics, + INFO("al_complete_io( sec=%llus (al_enr=%u) (rs_enr=%d) )\n", + (unsigned long long) sector, enr, + (int)BM_SECT_TO_EXT(sector)); + ); + + spin_lock_irqsave(&mdev->al_lock, flags); + + extent = lc_find(mdev->act_log, enr); + + if (!extent) { + spin_unlock_irqrestore(&mdev->al_lock, flags); + ERR("al_complete_io() called on inactive extent %u\n", enr); + return; + } + + if (lc_put(mdev->act_log, extent) == 0) + wake_up(&mdev->al_wait); + + spin_unlock_irqrestore(&mdev->al_lock, flags); +} + +int +w_al_write_transaction(struct drbd_conf *mdev, struct drbd_work *w, int unused) +{ + struct update_al_work *aw = (struct update_al_work *)w; + struct lc_element *updated = aw->al_ext; + const unsigned int new_enr = aw->enr; + const unsigned int evicted = aw->old_enr; + + struct al_transaction *buffer; + sector_t sector; + int i, n, mx; + unsigned int extent_nr; + u32 xor_sum = 0; + + if (!inc_local(mdev)) { + ERR("inc_local() failed in w_al_write_transaction\n"); + complete(&((struct update_al_work *)w)->event); + return 1; + } + /* do we have to do a bitmap write, first? + * TODO reduce maximum latency: + * submit both bios, then wait for both, + * instead of doing two synchronous sector writes. */ + if (mdev->state.conn < Connected && evicted != LC_FREE) + drbd_bm_write_sect(mdev, evicted/AL_EXT_PER_BM_SECT); + + down(&mdev->md_io_mutex); /* protects md_io_buffer, al_tr_cycle, ... */ + buffer = (struct al_transaction *)page_address(mdev->md_io_page); + + buffer->magic = __constant_cpu_to_be32(DRBD_MAGIC); + buffer->tr_number = cpu_to_be32(mdev->al_tr_number); + + n = lc_index_of(mdev->act_log, updated); + + buffer->updates[0].pos = cpu_to_be32(n); + buffer->updates[0].extent = cpu_to_be32(new_enr); + + xor_sum ^= new_enr; + + mx = min_t(int, AL_EXTENTS_PT, + mdev->act_log->nr_elements - mdev->al_tr_cycle); + for (i = 0; i < mx; i++) { + extent_nr = lc_entry(mdev->act_log, + mdev->al_tr_cycle+i)->lc_number; + buffer->updates[i+1].pos = cpu_to_be32(mdev->al_tr_cycle+i); + buffer->updates[i+1].extent = cpu_to_be32(extent_nr); + xor_sum ^= extent_nr; + } + for (; i < AL_EXTENTS_PT; i++) { + buffer->updates[i+1].pos = __constant_cpu_to_be32(-1); + buffer->updates[i+1].extent = __constant_cpu_to_be32(LC_FREE); + xor_sum ^= LC_FREE; + } + mdev->al_tr_cycle += AL_EXTENTS_PT; + if (mdev->al_tr_cycle >= mdev->act_log->nr_elements) + mdev->al_tr_cycle = 0; + + buffer->xor_sum = cpu_to_be32(xor_sum); + + sector = mdev->bc->md.md_offset + + mdev->bc->md.al_offset + mdev->al_tr_pos; + + if (!drbd_md_sync_page_io(mdev, mdev->bc, sector, WRITE)) { + drbd_chk_io_error(mdev, 1, TRUE); + drbd_io_error(mdev, TRUE); + } + + if (++mdev->al_tr_pos > + div_ceil(mdev->act_log->nr_elements, AL_EXTENTS_PT)) + mdev->al_tr_pos = 0; + + D_ASSERT(mdev->al_tr_pos < MD_AL_MAX_SIZE); + mdev->al_tr_number++; + + up(&mdev->md_io_mutex); + + complete(&((struct update_al_work *)w)->event); + dec_local(mdev); + + return 1; +} + +/** + * drbd_al_read_tr: Reads a single transaction record form the + * on disk activity log. + * Returns -1 on IO error, 0 on checksum error and 1 if it is a valid + * record. + */ +STATIC int drbd_al_read_tr(struct drbd_conf *mdev, + struct drbd_backing_dev *bdev, + struct al_transaction *b, + int index) +{ + sector_t sector; + int rv, i; + u32 xor_sum = 0; + + sector = bdev->md.md_offset + bdev->md.al_offset + index; + + /* Dont process error normally, + * as this is done before disk is atached! */ + if (!drbd_md_sync_page_io(mdev, bdev, sector, READ)) + return -1; + + rv = (be32_to_cpu(b->magic) == DRBD_MAGIC); + + for (i = 0; i < AL_EXTENTS_PT + 1; i++) + xor_sum ^= be32_to_cpu(b->updates[i].extent); + rv &= (xor_sum == be32_to_cpu(b->xor_sum)); + + return rv; +} + +/** + * drbd_al_read_log: Restores the activity log from its on disk + * representation. Returns 1 on success, returns 0 when + * reading the log failed due to IO errors. + */ +int drbd_al_read_log(struct drbd_conf *mdev, struct drbd_backing_dev *bdev) +{ + struct al_transaction *buffer; + int i; + int rv; + int mx; + int cnr; + int active_extents = 0; + int transactions = 0; + int overflow = 0; + int from = -1; + int to = -1; + u32 from_tnr = -1; + u32 to_tnr = 0; + + mx = div_ceil(mdev->act_log->nr_elements, AL_EXTENTS_PT); + + /* lock out all other meta data io for now, + * and make sure the page is mapped. + */ + down(&mdev->md_io_mutex); + buffer = page_address(mdev->md_io_page); + + /* Find the valid transaction in the log */ + for (i = 0; i <= mx; i++) { + rv = drbd_al_read_tr(mdev, bdev, buffer, i); + if (rv == 0) + continue; + if (rv == -1) { + up(&mdev->md_io_mutex); + return 0; + } + cnr = be32_to_cpu(buffer->tr_number); + + if (cnr == -1) + overflow = 1; + + if (cnr < from_tnr && !overflow) { + from = i; + from_tnr = cnr; + } + if (cnr > to_tnr) { + to = i; + to_tnr = cnr; + } + } + + if (from == -1 || to == -1) { + drbd_WARN("No usable activity log found.\n"); + + up(&mdev->md_io_mutex); + return 1; + } + + /* Read the valid transactions. + * INFO("Reading from %d to %d.\n",from,to); */ + i = from; + while (1) { + int j, pos; + unsigned int extent_nr; + unsigned int trn; + + rv = drbd_al_read_tr(mdev, bdev, buffer, i); + ERR_IF(rv == 0) goto cancel; + if (rv == -1) { + up(&mdev->md_io_mutex); + return 0; + } + + trn = be32_to_cpu(buffer->tr_number); + + spin_lock_irq(&mdev->al_lock); + + /* This loop runs backwards because in the cyclic + elements there might be an old version of the + updated element (in slot 0). So the element in slot 0 + can overwrite old versions. */ + for (j = AL_EXTENTS_PT; j >= 0; j--) { + pos = be32_to_cpu(buffer->updates[j].pos); + extent_nr = be32_to_cpu(buffer->updates[j].extent); + + if (extent_nr == LC_FREE) + continue; + + lc_set(mdev->act_log, extent_nr, pos); + active_extents++; + } + spin_unlock_irq(&mdev->al_lock); + + transactions++; + +cancel: + if (i == to) + break; + i++; + if (i > mx) + i = 0; + } + + mdev->al_tr_number = to_tnr+1; + mdev->al_tr_pos = to; + if (++mdev->al_tr_pos > + div_ceil(mdev->act_log->nr_elements, AL_EXTENTS_PT)) + mdev->al_tr_pos = 0; + + /* ok, we are done with it */ + up(&mdev->md_io_mutex); + + INFO("Found %d transactions (%d active extents) in activity log.\n", + transactions, active_extents); + + return 1; +} + +struct drbd_atodb_wait { + atomic_t count; + struct completion io_done; + struct drbd_conf *mdev; + int error; +}; + +STATIC BIO_ENDIO_TYPE atodb_endio BIO_ENDIO_ARGS(struct bio *bio, int error) +{ + struct drbd_atodb_wait *wc = bio->bi_private; + struct drbd_conf *mdev = wc->mdev; + struct page *page; + int uptodate = bio_flagged(bio, BIO_UPTODATE); + + BIO_ENDIO_FN_START; + /* strange behaviour of some lower level drivers... + * fail the request by clearing the uptodate flag, + * but do not return any error?! */ + if (!error && !uptodate) + error = -EIO; + + /* corresponding drbd_io_error is in drbd_al_to_on_disk_bm */ + drbd_chk_io_error(mdev, error, TRUE); + if (error && wc->error == 0) + wc->error = error; + + if (atomic_dec_and_test(&wc->count)) + complete(&wc->io_done); + + page = bio->bi_io_vec[0].bv_page; + put_page(page); + bio_put(bio); + mdev->bm_writ_cnt++; + dec_local(mdev); + + BIO_ENDIO_FN_RETURN; +} + +#define S2W(s) ((s)<<(BM_EXT_SIZE_B-BM_BLOCK_SIZE_B-LN2_BPL)) +/* activity log to on disk bitmap -- prepare bio unless that sector + * is already covered by previously prepared bios */ +STATIC int atodb_prepare_unless_covered(struct drbd_conf *mdev, + struct bio **bios, + unsigned int enr, + struct drbd_atodb_wait *wc) __must_hold(local) +{ + struct bio *bio; + struct page *page; + sector_t on_disk_sector = enr + mdev->bc->md.md_offset + + mdev->bc->md.bm_offset; + unsigned int page_offset = PAGE_SIZE; + int offset; + int i = 0; + int err = -ENOMEM; + + /* Check if that enr is already covered by an already created bio. + * Caution, bios[] is not NULL terminated, + * but only initialized to all NULL. + * For completely scattered activity log, + * the last invocation iterates over all bios, + * and finds the last NULL entry. + */ + while ((bio = bios[i])) { + if (bio->bi_sector == on_disk_sector) + return 0; + i++; + } + /* bios[i] == NULL, the next not yet used slot */ + + bio = bio_alloc(GFP_KERNEL, 1); + if (bio == NULL) + return -ENOMEM; + + if (i > 0) { + const struct bio_vec *prev_bv = bios[i-1]->bi_io_vec; + page_offset = prev_bv->bv_offset + prev_bv->bv_len; + page = prev_bv->bv_page; + } + if (page_offset == PAGE_SIZE) { + page = alloc_page(__GFP_HIGHMEM); + if (page == NULL) + goto out_bio_put; + page_offset = 0; + } else { + get_page(page); + } + + offset = S2W(enr); + drbd_bm_get_lel(mdev, offset, + min_t(size_t, S2W(1), drbd_bm_words(mdev) - offset), + kmap(page) + page_offset); + kunmap(page); + + bio->bi_private = wc; + bio->bi_end_io = atodb_endio; + bio->bi_bdev = mdev->bc->md_bdev; + bio->bi_sector = on_disk_sector; + + if (bio_add_page(bio, page, MD_HARDSECT, page_offset) != MD_HARDSECT) + goto out_put_page; + + atomic_inc(&wc->count); + /* we already know that we may do this... + * inc_local_if_state(mdev,Attaching); + * just get the extra reference, so that the local_cnt reflects + * the number of pending IO requests DRBD at its backing device. + */ + atomic_inc(&mdev->local_cnt); + + bios[i] = bio; + + return 0; + +out_put_page: + err = -EINVAL; + put_page(page); +out_bio_put: + bio_put(bio); + return err; +} + +/** + * drbd_al_to_on_disk_bm: + * Writes the areas of the bitmap which are covered by the AL. + * called when we detach (unconfigure) local storage, + * or when we go from Primary to Secondary state. + */ +void drbd_al_to_on_disk_bm(struct drbd_conf *mdev) +{ + int i, nr_elements; + unsigned int enr; + struct bio **bios; + struct drbd_atodb_wait wc; + + ERR_IF (!inc_local_if_state(mdev, Attaching)) + return; /* sorry, I don't have any act_log etc... */ + + wait_event(mdev->al_wait, lc_try_lock(mdev->act_log)); + + nr_elements = mdev->act_log->nr_elements; + + bios = kzalloc(sizeof(struct bio *) * nr_elements, GFP_KERNEL); + if (!bios) + goto submit_one_by_one; + + atomic_set(&wc.count, 0); + init_completion(&wc.io_done); + wc.mdev = mdev; + wc.error = 0; + + for (i = 0; i < nr_elements; i++) { + enr = lc_entry(mdev->act_log, i)->lc_number; + if (enr == LC_FREE) + continue; + /* next statement also does atomic_inc wc.count and local_cnt */ + if (atodb_prepare_unless_covered(mdev, bios, + enr/AL_EXT_PER_BM_SECT, + &wc)) + goto free_bios_submit_one_by_one; + } + + /* unneccessary optimization? */ + lc_unlock(mdev->act_log); + wake_up(&mdev->al_wait); + + /* all prepared, submit them */ + for (i = 0; i < nr_elements; i++) { + if (bios[i] == NULL) + break; + if (FAULT_ACTIVE(mdev, DRBD_FAULT_MD_WR)) { + bios[i]->bi_rw = WRITE; + bio_endio(bios[i], -EIO); + } else { + submit_bio(WRITE, bios[i]); + } + } + + drbd_blk_run_queue(bdev_get_queue(mdev->bc->md_bdev)); + + /* always (try to) flush bitmap to stable storage */ + drbd_md_flush(mdev); + + /* In case we did not submit a single IO do not wait for + * them to complete. ( Because we would wait forever here. ) + * + * In case we had IOs and they are already complete, there + * is not point in waiting anyways. + * Therefore this if () ... */ + if (atomic_read(&wc.count)) + wait_for_completion(&wc.io_done); + + dec_local(mdev); + + if (wc.error) + drbd_io_error(mdev, TRUE); + kfree(bios); + return; + + free_bios_submit_one_by_one: + /* free everything by calling the endio callback directly. */ + for (i = 0; i < nr_elements && bios[i]; i++) + bio_endio(bios[i], 0); + + kfree(bios); + + submit_one_by_one: + drbd_WARN("Using the slow drbd_al_to_on_disk_bm()\n"); + + for (i = 0; i < mdev->act_log->nr_elements; i++) { + enr = lc_entry(mdev->act_log, i)->lc_number; + if (enr == LC_FREE) + continue; + /* Really slow: if we have al-extents 16..19 active, + * sector 4 will be written four times! Synchronous! */ + drbd_bm_write_sect(mdev, enr/AL_EXT_PER_BM_SECT); + } + + lc_unlock(mdev->act_log); + wake_up(&mdev->al_wait); + dec_local(mdev); +} + +/** + * drbd_al_apply_to_bm: Sets the bits in the bitmap that are described + * by the active extents of the AL. + */ +void drbd_al_apply_to_bm(struct drbd_conf *mdev) +{ + unsigned int enr; + unsigned long add = 0; + char ppb[10]; + int i; + + wait_event(mdev->al_wait, lc_try_lock(mdev->act_log)); + + for (i = 0; i < mdev->act_log->nr_elements; i++) { + enr = lc_entry(mdev->act_log, i)->lc_number; + if (enr == LC_FREE) + continue; + add += drbd_bm_ALe_set_all(mdev, enr); + } + + lc_unlock(mdev->act_log); + wake_up(&mdev->al_wait); + + INFO("Marked additional %s as out-of-sync based on AL.\n", + ppsize(ppb, Bit2KB(add))); +} + +static inline int _try_lc_del(struct drbd_conf *mdev, struct lc_element *al_ext) +{ + int rv; + + spin_lock_irq(&mdev->al_lock); + rv = (al_ext->refcnt == 0); + if (likely(rv)) + lc_del(mdev->act_log, al_ext); + spin_unlock_irq(&mdev->al_lock); + + MTRACE(TraceTypeALExts, TraceLvlMetrics, + if (unlikely(!rv)) + INFO("Waiting for extent in drbd_al_shrink()\n"); + ); + + return rv; +} + +/** + * drbd_al_shrink: Removes all active extents form the AL. (but does not + * write any transactions) + * You need to lock mdev->act_log with lc_try_lock() / lc_unlock() + */ +void drbd_al_shrink(struct drbd_conf *mdev) +{ + struct lc_element *al_ext; + int i; + + D_ASSERT(test_bit(__LC_DIRTY, &mdev->act_log->flags)); + + for (i = 0; i < mdev->act_log->nr_elements; i++) { + al_ext = lc_entry(mdev->act_log, i); + if (al_ext->lc_number == LC_FREE) + continue; + wait_event(mdev->al_wait, _try_lc_del(mdev, al_ext)); + } + + wake_up(&mdev->al_wait); +} + +STATIC int w_update_odbm(struct drbd_conf *mdev, struct drbd_work *w, int unused) +{ + struct update_odbm_work *udw = (struct update_odbm_work *)w; + + if (!inc_local(mdev)) { + if (DRBD_ratelimit(5*HZ, 5)) + drbd_WARN("Can not update on disk bitmap, local IO disabled.\n"); + return 1; + } + + drbd_bm_write_sect(mdev, udw->enr); + dec_local(mdev); + + kfree(udw); + + if (drbd_bm_total_weight(mdev) <= mdev->rs_failed) { + switch (mdev->state.conn) { + case SyncSource: case SyncTarget: + case PausedSyncS: case PausedSyncT: + drbd_resync_finished(mdev); + default: + /* nothing to do */ + break; + } + } + drbd_bcast_sync_progress(mdev); + + return 1; +} + + +/* ATTENTION. The AL's extents are 4MB each, while the extents in the + * resync LRU-cache are 16MB each. + * The caller of this function has to hold an inc_local() reference. + * + * TODO will be obsoleted once we have a caching lru of the on disk bitmap + */ +STATIC void drbd_try_clear_on_disk_bm(struct drbd_conf *mdev, sector_t sector, + int count, int success) +{ + struct bm_extent *ext; + struct update_odbm_work *udw; + + unsigned int enr; + + MUST_HOLD(&mdev->al_lock); + D_ASSERT(atomic_read(&mdev->local_cnt)); + + /* I simply assume that a sector/size pair never crosses + * a 16 MB extent border. (Currently this is true...) */ + enr = BM_SECT_TO_EXT(sector); + + ext = (struct bm_extent *) lc_get(mdev->resync, enr); + if (ext) { + if (ext->lce.lc_number == enr) { + if (success) + ext->rs_left -= count; + else + ext->rs_failed += count; + if (ext->rs_left < ext->rs_failed) { + ERR("BAD! sector=%llus enr=%u rs_left=%d " + "rs_failed=%d count=%d\n", + (unsigned long long)sector, + ext->lce.lc_number, ext->rs_left, + ext->rs_failed, count); + dump_stack(); + /* FIXME brrrgs. should never happen! */ + lc_put(mdev->resync, &ext->lce); + drbd_force_state(mdev, NS(conn, Disconnecting)); + return; + } + } else { + /* Normally this element should be in the cache, + * since drbd_rs_begin_io() pulled it already in. + * + * But maybe an application write finished, and we set + * something outside the resync lru_cache in sync. + */ + int rs_left = drbd_bm_e_weight(mdev, enr); + if (ext->flags != 0) { + drbd_WARN("changing resync lce: %d[%u;%02lx]" + " -> %d[%u;00]\n", + ext->lce.lc_number, ext->rs_left, + ext->flags, enr, rs_left); + ext->flags = 0; + } + if (ext->rs_failed) { + drbd_WARN("Kicking resync_lru element enr=%u " + "out with rs_failed=%d\n", + ext->lce.lc_number, ext->rs_failed); + set_bit(WRITE_BM_AFTER_RESYNC, &mdev->flags); + } + ext->rs_left = rs_left; + ext->rs_failed = success ? 0 : count; + lc_changed(mdev->resync, &ext->lce); + } + lc_put(mdev->resync, &ext->lce); + /* no race, we are within the al_lock! */ + + if (ext->rs_left == ext->rs_failed) { + ext->rs_failed = 0; + + udw = kmalloc(sizeof(*udw), GFP_ATOMIC); + if (udw) { + udw->enr = ext->lce.lc_number; + udw->w.cb = w_update_odbm; + drbd_queue_work_front(&mdev->data.work, &udw->w); + } else { + drbd_WARN("Could not kmalloc an udw\n"); + set_bit(WRITE_BM_AFTER_RESYNC, &mdev->flags); + } + } + } else { + ERR("lc_get() failed! locked=%d/%d flags=%lu\n", + mdev->resync_locked, + mdev->resync->nr_elements, + mdev->resync->flags); + } +} + +/* clear the bit corresponding to the piece of storage in question: + * size byte of data starting from sector. Only clear a bits of the affected + * one ore more _aligned_ BM_BLOCK_SIZE blocks. + * + * called by worker on SyncTarget and receiver on SyncSource. + * + */ +void __drbd_set_in_sync(struct drbd_conf *mdev, sector_t sector, int size, + const char *file, const unsigned int line) +{ + /* Is called from worker and receiver context _only_ */ + unsigned long sbnr, ebnr, lbnr; + unsigned long count = 0; + sector_t esector, nr_sectors; + int wake_up = 0; + unsigned long flags; + + if (size <= 0 || (size & 0x1ff) != 0 || size > DRBD_MAX_SEGMENT_SIZE) { + ERR("drbd_set_in_sync: sector=%llus size=%d nonsense!\n", + (unsigned long long)sector, size); + return; + } + nr_sectors = drbd_get_capacity(mdev->this_bdev); + esector = sector + (size >> 9) - 1; + + ERR_IF(sector >= nr_sectors) return; + ERR_IF(esector >= nr_sectors) esector = (nr_sectors-1); + + lbnr = BM_SECT_TO_BIT(nr_sectors-1); + + /* we clear it (in sync). + * round up start sector, round down end sector. we make sure we only + * clear full, alligned, BM_BLOCK_SIZE (4K) blocks */ + if (unlikely(esector < BM_SECT_PER_BIT-1)) + return; + if (unlikely(esector == (nr_sectors-1))) + ebnr = lbnr; + else + ebnr = BM_SECT_TO_BIT(esector - (BM_SECT_PER_BIT-1)); + sbnr = BM_SECT_TO_BIT(sector + BM_SECT_PER_BIT-1); + + MTRACE(TraceTypeResync, TraceLvlMetrics, + INFO("drbd_set_in_sync: sector=%llus size=%u sbnr=%lu ebnr=%lu\n", + (unsigned long long)sector, size, sbnr, ebnr); + ); + + if (sbnr > ebnr) + return; + + /* + * ok, (capacity & 7) != 0 sometimes, but who cares... + * we count rs_{total,left} in bits, not sectors. + */ + spin_lock_irqsave(&mdev->al_lock, flags); + count = drbd_bm_clear_bits(mdev, sbnr, ebnr); + if (count) { + /* we need the lock for drbd_try_clear_on_disk_bm */ + if (jiffies - mdev->rs_mark_time > HZ*10) { + /* should be roling marks, + * but we estimate only anyways. */ + if (mdev->rs_mark_left != drbd_bm_total_weight(mdev) && + mdev->state.conn != PausedSyncT && + mdev->state.conn != PausedSyncS) { + mdev->rs_mark_time = jiffies; + mdev->rs_mark_left = drbd_bm_total_weight(mdev); + } + } + if (inc_local(mdev)) { + drbd_try_clear_on_disk_bm(mdev, sector, count, TRUE); + dec_local(mdev); + } + /* just wake_up unconditional now, various lc_chaged(), + * lc_put() in drbd_try_clear_on_disk_bm(). */ + wake_up = 1; + } + spin_unlock_irqrestore(&mdev->al_lock, flags); + if (wake_up) + wake_up(&mdev->al_wait); +} + +/* + * this is intended to set one request worth of data out of sync. + * affects at least 1 bit, + * and at most 1+DRBD_MAX_SEGMENT_SIZE/BM_BLOCK_SIZE bits. + * + * called by tl_clear and drbd_send_dblock (==drbd_make_request). + * so this can be _any_ process. + */ +void __drbd_set_out_of_sync(struct drbd_conf *mdev, sector_t sector, int size, + const char *file, const unsigned int line) +{ + unsigned long sbnr, ebnr, lbnr, flags; + sector_t esector, nr_sectors; + unsigned int enr, count; + struct bm_extent* ext; + + if (size <= 0 || (size & 0x1ff) != 0 || size > DRBD_MAX_SEGMENT_SIZE) { + ERR("sector: %llus, size: %d\n", + (unsigned long long)sector, size); + return; + } + + if (!inc_local(mdev)) + return; /* no disk, no metadata, no bitmap to set bits in */ + + nr_sectors = drbd_get_capacity(mdev->this_bdev); + esector = sector + (size >> 9) - 1; + + ERR_IF(sector >= nr_sectors) + goto out; + ERR_IF(esector >= nr_sectors) + esector = (nr_sectors-1); + + lbnr = BM_SECT_TO_BIT(nr_sectors-1); + + /* we set it out of sync, + * we do not need to round anything here */ + sbnr = BM_SECT_TO_BIT(sector); + ebnr = BM_SECT_TO_BIT(esector); + + MTRACE(TraceTypeResync, TraceLvlMetrics, + INFO("drbd_set_out_of_sync: sector=%llus size=%u " + "sbnr=%lu ebnr=%lu\n", + (unsigned long long)sector, size, sbnr, ebnr); + ); + + /* ok, (capacity & 7) != 0 sometimes, but who cares... + * we count rs_{total,left} in bits, not sectors. */ + spin_lock_irqsave(&mdev->al_lock, flags); + count = drbd_bm_set_bits(mdev, sbnr, ebnr); + + enr = BM_SECT_TO_EXT(sector); + ext = (struct bm_extent *) lc_find(mdev->resync, enr); + if (ext) + ext->rs_left += count; + spin_unlock_irqrestore(&mdev->al_lock, flags); + +out: + dec_local(mdev); +} + +static inline +struct bm_extent *_bme_get(struct drbd_conf *mdev, unsigned int enr) +{ + struct bm_extent *bm_ext; + int wakeup = 0; + unsigned long rs_flags; + + spin_lock_irq(&mdev->al_lock); + if (mdev->resync_locked > mdev->resync->nr_elements/2) { + spin_unlock_irq(&mdev->al_lock); + return NULL; + } + bm_ext = (struct bm_extent *) lc_get(mdev->resync, enr); + if (bm_ext) { + if (bm_ext->lce.lc_number != enr) { + bm_ext->rs_left = drbd_bm_e_weight(mdev, enr); + bm_ext->rs_failed = 0; + lc_changed(mdev->resync, (struct lc_element *)bm_ext); + wakeup = 1; + } + if (bm_ext->lce.refcnt == 1) + mdev->resync_locked++; + set_bit(BME_NO_WRITES, &bm_ext->flags); + } + rs_flags = mdev->resync->flags; + spin_unlock_irq(&mdev->al_lock); + if (wakeup) + wake_up(&mdev->al_wait); + + if (!bm_ext) { + if (rs_flags & LC_STARVING) + drbd_WARN("Have to wait for element" + " (resync LRU too small?)\n"); + BUG_ON(rs_flags & LC_DIRTY); + } + + return bm_ext; +} + +static inline int _is_in_al(struct drbd_conf *mdev, unsigned int enr) +{ + struct lc_element *al_ext; + int rv = 0; + + spin_lock_irq(&mdev->al_lock); + if (unlikely(enr == mdev->act_log->new_number)) + rv = 1; + else { + al_ext = lc_find(mdev->act_log, enr); + if (al_ext) { + if (al_ext->refcnt) + rv = 1; + } + } + spin_unlock_irq(&mdev->al_lock); + + /* + if (unlikely(rv)) { + INFO("Delaying sync read until app's write is done\n"); + } + */ + return rv; +} + +/** + * drbd_rs_begin_io: Gets an extent in the resync LRU cache and sets it + * to BME_LOCKED. + * + * @sector: The sector number + * + * sleeps on al_wait. + * returns 1 if successful. + * returns 0 if interrupted. + */ +int drbd_rs_begin_io(struct drbd_conf *mdev, sector_t sector) +{ + unsigned int enr = BM_SECT_TO_EXT(sector); + struct bm_extent *bm_ext; + int i, sig; + + MTRACE(TraceTypeResync, TraceLvlAll, + INFO("drbd_rs_begin_io: sector=%llus (rs_end=%d)\n", + (unsigned long long)sector, enr); + ); + + sig = wait_event_interruptible(mdev->al_wait, + (bm_ext = _bme_get(mdev, enr))); + if (sig) + return 0; + + if (test_bit(BME_LOCKED, &bm_ext->flags)) + return 1; + + for (i = 0; i < AL_EXT_PER_BM_SECT; i++) { + sig = wait_event_interruptible(mdev->al_wait, + !_is_in_al(mdev, enr * AL_EXT_PER_BM_SECT + i)); + if (sig) { + spin_lock_irq(&mdev->al_lock); + if (lc_put(mdev->resync, &bm_ext->lce) == 0) { + clear_bit(BME_NO_WRITES, &bm_ext->flags); + mdev->resync_locked--; + wake_up(&mdev->al_wait); + } + spin_unlock_irq(&mdev->al_lock); + return 0; + } + } + + set_bit(BME_LOCKED, &bm_ext->flags); + + return 1; +} + +/** + * drbd_try_rs_begin_io: Gets an extent in the resync LRU cache, sets it + * to BME_NO_WRITES, then tries to set it to BME_LOCKED. + * + * @sector: The sector number + * + * does not sleep. + * returns zero if we could set BME_LOCKED and can proceed, + * -EAGAIN if we need to try again. + */ +int drbd_try_rs_begin_io(struct drbd_conf *mdev, sector_t sector) +{ + unsigned int enr = BM_SECT_TO_EXT(sector); + const unsigned int al_enr = enr*AL_EXT_PER_BM_SECT; + struct bm_extent *bm_ext; + int i; + + MTRACE(TraceTypeResync, TraceLvlAll, + INFO("drbd_try_rs_begin_io: sector=%llus\n", + (unsigned long long)sector); + ); + + spin_lock_irq(&mdev->al_lock); + if (mdev->resync_wenr != LC_FREE && mdev->resync_wenr != enr) { + /* in case you have very heavy scattered io, it may + * stall the syncer undefined if we giveup the ref count + * when we try again and requeue. + * + * if we don't give up the refcount, but the next time + * we are scheduled this extent has been "synced" by new + * application writes, we'd miss the lc_put on the + * extent we keept the refcount on. + * so we remembered which extent we had to try agin, and + * if the next requested one is something else, we do + * the lc_put here... + * we also have to wake_up + */ + MTRACE(TraceTypeResync, TraceLvlAll, + INFO("dropping %u, aparently got 'synced' " + "by application io\n", mdev->resync_wenr); + ); + bm_ext = (struct bm_extent *) + lc_find(mdev->resync, mdev->resync_wenr); + if (bm_ext) { + D_ASSERT(!test_bit(BME_LOCKED, &bm_ext->flags)); + D_ASSERT(test_bit(BME_NO_WRITES, &bm_ext->flags)); + clear_bit(BME_NO_WRITES, &bm_ext->flags); + mdev->resync_wenr = LC_FREE; + if (lc_put(mdev->resync, &bm_ext->lce) == 0) + mdev->resync_locked--; + wake_up(&mdev->al_wait); + } else { + ALERT("LOGIC BUG\n"); + } + } + bm_ext = (struct bm_extent *)lc_try_get(mdev->resync, enr); + if (bm_ext) { + if (test_bit(BME_LOCKED, &bm_ext->flags)) + goto proceed; + if (!test_and_set_bit(BME_NO_WRITES, &bm_ext->flags)) { + mdev->resync_locked++; + } else { + /* we did set the BME_NO_WRITES, + * but then could not set BME_LOCKED, + * so we tried again. + * drop the extra reference. */ + MTRACE(TraceTypeResync, TraceLvlAll, + INFO("dropping extra reference on %u\n", enr); + ); + bm_ext->lce.refcnt--; + D_ASSERT(bm_ext->lce.refcnt > 0); + } + goto check_al; + } else { + if (mdev->resync_locked > mdev->resync->nr_elements-3) { + MTRACE(TraceTypeResync, TraceLvlAll, + INFO("resync_locked = %u!\n", mdev->resync_locked); + ); + goto try_again; + } + bm_ext = (struct bm_extent *)lc_get(mdev->resync, enr); + if (!bm_ext) { + const unsigned long rs_flags = mdev->resync->flags; + if (rs_flags & LC_STARVING) + drbd_WARN("Have to wait for element" + " (resync LRU too small?)\n"); + BUG_ON(rs_flags & LC_DIRTY); + goto try_again; + } + if (bm_ext->lce.lc_number != enr) { + bm_ext->rs_left = drbd_bm_e_weight(mdev, enr); + bm_ext->rs_failed = 0; + lc_changed(mdev->resync, (struct lc_element *)bm_ext); + wake_up(&mdev->al_wait); + D_ASSERT(test_bit(BME_LOCKED, &bm_ext->flags) == 0); + } + set_bit(BME_NO_WRITES, &bm_ext->flags); + D_ASSERT(bm_ext->lce.refcnt == 1); + mdev->resync_locked++; + goto check_al; + } +check_al: + MTRACE(TraceTypeResync, TraceLvlAll, + INFO("checking al for %u\n", enr); + ); + for (i = 0; i < AL_EXT_PER_BM_SECT; i++) { + if (unlikely(al_enr+i == mdev->act_log->new_number)) + goto try_again; + if (lc_is_used(mdev->act_log, al_enr+i)) + goto try_again; + } + set_bit(BME_LOCKED, &bm_ext->flags); +proceed: + mdev->resync_wenr = LC_FREE; + spin_unlock_irq(&mdev->al_lock); + return 0; + +try_again: + MTRACE(TraceTypeResync, TraceLvlAll, + INFO("need to try again for %u\n", enr); + ); + if (bm_ext) + mdev->resync_wenr = enr; + spin_unlock_irq(&mdev->al_lock); + return -EAGAIN; +} + +void drbd_rs_complete_io(struct drbd_conf *mdev, sector_t sector) +{ + unsigned int enr = BM_SECT_TO_EXT(sector); + struct bm_extent *bm_ext; + unsigned long flags; + + MTRACE(TraceTypeResync, TraceLvlAll, + INFO("drbd_rs_complete_io: sector=%llus (rs_enr=%d)\n", + (long long)sector, enr); + ); + + spin_lock_irqsave(&mdev->al_lock, flags); + bm_ext = (struct bm_extent *) lc_find(mdev->resync, enr); + if (!bm_ext) { + spin_unlock_irqrestore(&mdev->al_lock, flags); + ERR("drbd_rs_complete_io() called, but extent not found\n"); + return; + } + + if (bm_ext->lce.refcnt == 0) { + spin_unlock_irqrestore(&mdev->al_lock, flags); + ERR("drbd_rs_complete_io(,%llu [=%u]) called, " + "but refcnt is 0!?\n", + (unsigned long long)sector, enr); + return; + } + + if (lc_put(mdev->resync, (struct lc_element *)bm_ext) == 0) { + clear_bit(BME_LOCKED, &bm_ext->flags); + clear_bit(BME_NO_WRITES, &bm_ext->flags); + mdev->resync_locked--; + wake_up(&mdev->al_wait); + } + + spin_unlock_irqrestore(&mdev->al_lock, flags); +} + +/** + * drbd_rs_cancel_all: Removes extents from the resync LRU. Even + * if they are BME_LOCKED. + */ +void drbd_rs_cancel_all(struct drbd_conf *mdev) +{ + MTRACE(TraceTypeResync, TraceLvlMetrics, + INFO("drbd_rs_cancel_all\n"); + ); + + spin_lock_irq(&mdev->al_lock); + + if (inc_local_if_state(mdev, Failed)) { /* Makes sure ->resync is there. */ + lc_reset(mdev->resync); + dec_local(mdev); + } + mdev->resync_locked = 0; + mdev->resync_wenr = LC_FREE; + spin_unlock_irq(&mdev->al_lock); + wake_up(&mdev->al_wait); +} + +/** + * drbd_rs_del_all: Gracefully remove all extents from the resync LRU. + * there may be still a reference hold by someone. In that case this function + * returns -EAGAIN. + * In case all elements got removed it returns zero. + */ +int drbd_rs_del_all(struct drbd_conf *mdev) +{ + struct bm_extent *bm_ext; + int i; + + MTRACE(TraceTypeResync, TraceLvlMetrics, + INFO("drbd_rs_del_all\n"); + ); + + spin_lock_irq(&mdev->al_lock); + + if (inc_local_if_state(mdev, Failed)) { + /* ok, ->resync is there. */ + for (i = 0; i < mdev->resync->nr_elements; i++) { + bm_ext = (struct bm_extent *) lc_entry(mdev->resync, i); + if (bm_ext->lce.lc_number == LC_FREE) + continue; + if (bm_ext->lce.lc_number == mdev->resync_wenr) { + INFO("dropping %u in drbd_rs_del_all, apparently" + " got 'synced' by application io\n", + mdev->resync_wenr); + D_ASSERT(!test_bit(BME_LOCKED, &bm_ext->flags)); + D_ASSERT(test_bit(BME_NO_WRITES, &bm_ext->flags)); + clear_bit(BME_NO_WRITES, &bm_ext->flags); + mdev->resync_wenr = LC_FREE; + lc_put(mdev->resync, &bm_ext->lce); + } + if (bm_ext->lce.refcnt != 0) { + INFO("Retrying drbd_rs_del_all() later. " + "refcnt=%d\n", bm_ext->lce.refcnt); + dec_local(mdev); + spin_unlock_irq(&mdev->al_lock); + return -EAGAIN; + } + D_ASSERT(!test_bit(BME_LOCKED, &bm_ext->flags)); + D_ASSERT(!test_bit(BME_NO_WRITES, &bm_ext->flags)); + lc_del(mdev->resync, &bm_ext->lce); + } + D_ASSERT(mdev->resync->used == 0); + dec_local(mdev); + } + spin_unlock_irq(&mdev->al_lock); + + return 0; +} + +/* Record information on a failure to resync the specified blocks + * + * called on SyncTarget when resync write fails or NegRSDReply received + * + */ +void drbd_rs_failed_io(struct drbd_conf *mdev, sector_t sector, int size) +{ + /* Is called from worker and receiver context _only_ */ + unsigned long sbnr, ebnr, lbnr; + unsigned long count; + sector_t esector, nr_sectors; + int wake_up = 0; + + MTRACE(TraceTypeResync, TraceLvlSummary, + INFO("drbd_rs_failed_io: sector=%llus, size=%u\n", + (unsigned long long)sector, size); + ); + + if (size <= 0 || (size & 0x1ff) != 0 || size > DRBD_MAX_SEGMENT_SIZE) { + ERR("drbd_rs_failed_io: sector=%llus size=%d nonsense!\n", + (unsigned long long)sector, size); + return; + } + nr_sectors = drbd_get_capacity(mdev->this_bdev); + esector = sector + (size >> 9) - 1; + + ERR_IF(sector >= nr_sectors) return; + ERR_IF(esector >= nr_sectors) esector = (nr_sectors-1); + + lbnr = BM_SECT_TO_BIT(nr_sectors-1); + + /* + * round up start sector, round down end sector. we make sure we only + * handle full, alligned, BM_BLOCK_SIZE (4K) blocks */ + if (unlikely(esector < BM_SECT_PER_BIT-1)) + return; + if (unlikely(esector == (nr_sectors-1))) + ebnr = lbnr; + else + ebnr = BM_SECT_TO_BIT(esector - (BM_SECT_PER_BIT-1)); + sbnr = BM_SECT_TO_BIT(sector + BM_SECT_PER_BIT-1); + + if (sbnr > ebnr) + return; + + /* + * ok, (capacity & 7) != 0 sometimes, but who cares... + * we count rs_{total,left} in bits, not sectors. + */ + spin_lock_irq(&mdev->al_lock); + count = drbd_bm_count_bits(mdev, sbnr, ebnr); + if (count) { + mdev->rs_failed += count; + + if (inc_local(mdev)) { + drbd_try_clear_on_disk_bm(mdev, sector, count, FALSE); + dec_local(mdev); + } + + /* just wake_up unconditional now, various lc_chaged(), + * lc_put() in drbd_try_clear_on_disk_bm(). */ + wake_up = 1; + } + spin_unlock_irq(&mdev->al_lock); + if (wake_up) + wake_up(&mdev->al_wait); +} --- linux-2.6.28.orig/ubuntu/drbd/lru_cache.c +++ linux-2.6.28/ubuntu/drbd/lru_cache.c @@ -0,0 +1,402 @@ +/* +-*- linux-c -*- + lru_cache.c + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2003-2008, LINBIT Information Technologies GmbH. + Copyright (C) 2003-2008, Philipp Reisner . + Copyright (C) 2003-2008, Lars Ellenberg . + + drbd is free software; you can redistribute 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. + + drbd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + */ + +#include +#include +#include /* for memset */ +#include /* for seq_printf */ +#include "lru_cache.h" + +#define STATIC static + +/* this is developers aid only! */ +#define PARANOIA_ENTRY() BUG_ON(test_and_set_bit(__LC_PARANOIA, &lc->flags)) +#define PARANOIA_LEAVE() do { clear_bit(__LC_PARANOIA, &lc->flags); smp_mb__after_clear_bit(); } while (0) +#define RETURN(x...) do { PARANOIA_LEAVE(); return x ; } while (0) + +static inline size_t size_of_lc(unsigned int e_count, size_t e_size) +{ + return sizeof(struct lru_cache) + + e_count * (e_size + sizeof(struct hlist_head)); +} + +static inline void lc_init(struct lru_cache *lc, + const size_t bytes, const char *name, + const unsigned int e_count, const size_t e_size, + void *private_p) +{ + struct lc_element *e; + unsigned int i; + + memset(lc, 0, bytes); + INIT_LIST_HEAD(&lc->in_use); + INIT_LIST_HEAD(&lc->lru); + INIT_LIST_HEAD(&lc->free); + lc->element_size = e_size; + lc->nr_elements = e_count; + lc->new_number = -1; + lc->lc_private = private_p; + lc->name = name; + for (i = 0; i < e_count; i++) { + e = lc_entry(lc, i); + e->lc_number = LC_FREE; + list_add(&e->list, &lc->free); + /* memset(,0,) did the rest of init for us */ + } +} + +/** + * lc_alloc: allocates memory for @e_count objects of @e_size bytes plus the + * struct lru_cache, and the hash table slots. + * returns pointer to a newly initialized lru_cache object with said parameters. + */ +struct lru_cache *lc_alloc(const char *name, unsigned int e_count, + size_t e_size, void *private_p) +{ + struct lru_cache *lc; + size_t bytes; + + BUG_ON(!e_count); + e_size = max(sizeof(struct lc_element), e_size); + bytes = size_of_lc(e_count, e_size); + lc = vmalloc(bytes); + if (lc) + lc_init(lc, bytes, name, e_count, e_size, private_p); + return lc; +} + +/** + * lc_free: Frees memory allocated by lc_alloc. + * @lc: The lru_cache object + */ +void lc_free(struct lru_cache *lc) +{ + vfree(lc); +} + +/** + * lc_reset: does a full reset for @lc and the hash table slots. + * It is roughly the equivalent of re-allocating a fresh lru_cache object, + * basically a short cut to lc_free(lc); lc = lc_alloc(...); + */ +void lc_reset(struct lru_cache *lc) +{ + lc_init(lc, size_of_lc(lc->nr_elements, lc->element_size), lc->name, + lc->nr_elements, lc->element_size, lc->lc_private); +} + +size_t lc_printf_stats(struct seq_file *seq, struct lru_cache *lc) +{ + /* NOTE: + * total calls to lc_get are + * (starving + hits + misses) + * misses include "dirty" count (update from an other thread in + * progress) and "changed", when this in fact lead to an successful + * update of the cache. + */ + return seq_printf(seq, "\t%s: used:%u/%u " + "hits:%lu misses:%lu starving:%lu dirty:%lu changed:%lu\n", + lc->name, lc->used, lc->nr_elements, + lc->hits, lc->misses, lc->starving, lc->dirty, lc->changed); +} + +static unsigned int lc_hash_fn(struct lru_cache *lc, unsigned int enr) +{ + return enr % lc->nr_elements; +} + + +/** + * lc_find: Returns the pointer to an element, if the element is present + * in the hash table. In case it is not this function returns NULL. + * @lc: The lru_cache object + * @enr: element number + */ +struct lc_element *lc_find(struct lru_cache *lc, unsigned int enr) +{ + struct hlist_node *n; + struct lc_element *e; + + BUG_ON(!lc); + BUG_ON(!lc->nr_elements); + hlist_for_each_entry(e, n, lc->slot + lc_hash_fn(lc, enr), colision) { + if (e->lc_number == enr) + return e; + } + return NULL; +} + +STATIC struct lc_element *lc_evict(struct lru_cache *lc) +{ + struct list_head *n; + struct lc_element *e; + + if (list_empty(&lc->lru)) + return NULL; + + n = lc->lru.prev; + e = list_entry(n, struct lc_element, list); + + list_del(&e->list); + hlist_del(&e->colision); + return e; +} + +/** + * lc_del: Removes an element from the cache (and therefore adds the + * element's storage to the free list) + * + * @lc: The lru_cache object + * @e: The element to remove + */ +void lc_del(struct lru_cache *lc, struct lc_element *e) +{ + /* FIXME what to do with refcnt != 0 ? */ + PARANOIA_ENTRY(); + BUG_ON(e->refcnt); + list_del(&e->list); + hlist_del_init(&e->colision); + e->lc_number = LC_FREE; + e->refcnt = 0; + list_add(&e->list, &lc->free); + RETURN(); +} + +STATIC struct lc_element *lc_get_unused_element(struct lru_cache *lc) +{ + struct list_head *n; + + if (list_empty(&lc->free)) + return lc_evict(lc); + + n = lc->free.next; + list_del(n); + return list_entry(n, struct lc_element, list); +} + +STATIC int lc_unused_element_available(struct lru_cache *lc) +{ + if (!list_empty(&lc->free)) + return 1; /* something on the free list */ + if (!list_empty(&lc->lru)) + return 1; /* something to evict */ + + return 0; +} + + +/** + * lc_get: Finds an element in the cache, increases its usage count, + * "touches" and returns it. + * In case the requested number is not present, it needs to be added to the + * cache. Therefore it is possible that an other element becomes eviced from + * the cache. In either case, the user is notified so he is able to e.g. keep + * a persistent log of the cache changes, and therefore the objects in use. + * + * Return values: + * NULL if the requested element number was not in the cache, and no unused + * element could be recycled + * pointer to the element with the REQUESTED element number + * In this case, it can be used right away + * + * pointer to an UNUSED element with some different element number. + * In this case, the cache is marked dirty, and the returned element + * pointer is removed from the lru list and hash collision chains. + * The user now should do whatever houskeeping is necessary. Then he + * needs to call lc_element_changed(lc,element_pointer), to finish the + * change. + * + * NOTE: The user needs to check the lc_number on EACH use, so he recognizes + * any cache set change. + * + * @lc: The lru_cache object + * @enr: element number + */ +struct lc_element *lc_get(struct lru_cache *lc, unsigned int enr) +{ + struct lc_element *e; + + BUG_ON(!lc); + BUG_ON(!lc->nr_elements); + + PARANOIA_ENTRY(); + if (lc->flags & LC_STARVING) { + ++lc->starving; + RETURN(NULL); + } + + e = lc_find(lc, enr); + if (e) { + ++lc->hits; + if (e->refcnt++ == 0) + lc->used++; + list_move(&e->list, &lc->in_use); /* Not evictable... */ + RETURN(e); + } + + ++lc->misses; + + /* In case there is nothing available and we can not kick out + * the LRU element, we have to wait ... + */ + if (!lc_unused_element_available(lc)) { + __set_bit(__LC_STARVING, &lc->flags); + RETURN(NULL); + } + + /* it was not present in the cache, find an unused element, + * which then is replaced. + * we need to update the cache; serialize on lc->flags & LC_DIRTY + */ + if (test_and_set_bit(__LC_DIRTY, &lc->flags)) { + ++lc->dirty; + RETURN(NULL); + } + + e = lc_get_unused_element(lc); + BUG_ON(!e); + + clear_bit(__LC_STARVING, &lc->flags); + BUG_ON(++e->refcnt != 1); + lc->used++; + + lc->changing_element = e; + lc->new_number = enr; + + RETURN(e); +} + +/* similar to lc_get, + * but only gets a new reference on an existing element. + * you either get the requested element, or NULL. + */ +struct lc_element *lc_try_get(struct lru_cache *lc, unsigned int enr) +{ + struct lc_element *e; + + BUG_ON(!lc); + BUG_ON(!lc->nr_elements); + + PARANOIA_ENTRY(); + if (lc->flags & LC_STARVING) { + ++lc->starving; + RETURN(NULL); + } + + e = lc_find(lc, enr); + if (e) { + ++lc->hits; + if (e->refcnt++ == 0) + lc->used++; + list_move(&e->list, &lc->in_use); /* Not evictable... */ + } + RETURN(e); +} + +void lc_changed(struct lru_cache *lc, struct lc_element *e) +{ + PARANOIA_ENTRY(); + BUG_ON(e != lc->changing_element); + ++lc->changed; + e->lc_number = lc->new_number; + list_add(&e->list, &lc->in_use); + hlist_add_head(&e->colision, + lc->slot + lc_hash_fn(lc, lc->new_number)); + lc->changing_element = NULL; + lc->new_number = -1; + clear_bit(__LC_DIRTY, &lc->flags); + smp_mb__after_clear_bit(); + PARANOIA_LEAVE(); +} + + +unsigned int lc_put(struct lru_cache *lc, struct lc_element *e) +{ + BUG_ON(!lc); + BUG_ON(!lc->nr_elements); + BUG_ON(!e); + + PARANOIA_ENTRY(); + BUG_ON(e->refcnt == 0); + BUG_ON(e == lc->changing_element); + if (--e->refcnt == 0) { + /* move it to the front of LRU. */ + list_move(&e->list, &lc->lru); + lc->used--; + clear_bit(__LC_STARVING, &lc->flags); + smp_mb__after_clear_bit(); + } + RETURN(e->refcnt); +} + + +/** + * lc_set: Sets an element in the cache. You might use this function to + * setup the cache. It is expected that the elements are properly initialized. + * @lc: The lru_cache object + * @enr: element number + * @index: The elements' position in the cache + */ +void lc_set(struct lru_cache *lc, unsigned int enr, int index) +{ + struct lc_element *e; + + if (index < 0 || index >= lc->nr_elements) + return; + + e = lc_entry(lc, index); + e->lc_number = enr; + + hlist_del_init(&e->colision); + hlist_add_head(&e->colision, lc->slot + lc_hash_fn(lc, enr)); + list_move(&e->list, e->refcnt ? &lc->in_use : &lc->lru); +} + +/** + * lc_dump: Dump a complete LRU cache to seq in textual form. + */ +void lc_dump(struct lru_cache *lc, struct seq_file *seq, char *utext, + void (*detail) (struct seq_file *, struct lc_element *)) +{ + unsigned int nr_elements = lc->nr_elements; + struct lc_element *e; + int i; + + seq_printf(seq, "\tnn: lc_number refcnt %s\n ", utext); + for (i = 0; i < nr_elements; i++) { + e = lc_entry(lc, i); + if (e->lc_number == LC_FREE) { + seq_printf(seq, "\t%2d: FREE\n", i); + } else { + seq_printf(seq, "\t%2d: %4u %4u ", i, + e->lc_number, + e->refcnt); + detail(seq, e); + } + } +} + --- linux-2.6.28.orig/ubuntu/drbd/lru_cache.h +++ linux-2.6.28/ubuntu/drbd/lru_cache.h @@ -0,0 +1,149 @@ +/* +-*- linux-c -*- + lru_cache.c + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2003-2008, LINBIT Information Technologies GmbH. + Copyright (C) 2003-2008, Philipp Reisner . + Copyright (C) 2003-2008, Lars Ellenberg . + + drbd is free software; you can redistribute 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. + + drbd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + */ + +/* + * The lru_cache describes a big set of objects that are addressed + * by an index number (=lc_number). Only a small fraction of this set + * is present in the cache. + * (You set the size of the cache during lc_alloc) + * Once created, the api consists of + * lc_find(,nr) -- finds the object with the given number, if present + * lc_get(,nr) -- finds the object and increases the usage count + * if not present, actions are taken to make sure that + * the cache is updated, the user is notified of this by a callback. + * Return value is NULL in this case. + * As soon as the user informs the cache that it has been updated, + * the next lc_get on that very object number will be successfull. + * lc_put(,lc_element*) + * -- decreases the usage count of this object, and returns the new value. + * + * NOTE: It is the USERS responsibility + * to make sure that calls do not happen concurrently. + */ + +#ifndef LRU_CACHE_H +#define LRU_CACHE_H + +#include +#ifndef HLIST_HEAD_INIT +# include "hlist.h" +#endif + +#include + +/* FIXME + * I want these structs opaque outside of lru_cache.c + */ + +struct lc_element { + struct hlist_node colision; + struct list_head list; /* LRU list or free list */ + unsigned int refcnt; + unsigned int lc_number; +}; + +struct lru_cache { + struct list_head lru; + struct list_head free; + struct list_head in_use; + size_t element_size; + unsigned int nr_elements; + unsigned int new_number; + + /* here may or may not be a pad... */ + + unsigned int used; + unsigned long flags; + unsigned long hits, misses, starving, dirty, changed; + struct lc_element *changing_element; /* just for paranoia */ + + void *lc_private; + const char *name; + + struct hlist_head slot[0]; + /* hash colision chains here, then element storage. */ +}; + + +/* flag-bits for lru_cache */ +enum { + __LC_PARANOIA, + __LC_DIRTY, + __LC_STARVING, +}; +#define LC_PARANOIA (1<<__LC_PARANOIA) +#define LC_DIRTY (1<<__LC_DIRTY) +#define LC_STARVING (1<<__LC_STARVING) + +extern struct lru_cache *lc_alloc(const char *name, unsigned int e_count, + size_t e_size, void *private_p); +extern void lc_reset(struct lru_cache *lc); +extern void lc_free(struct lru_cache *lc); +extern void lc_set(struct lru_cache *lc, unsigned int enr, int index); +extern void lc_del(struct lru_cache *lc, struct lc_element *element); + +extern struct lc_element *lc_try_get(struct lru_cache *lc, unsigned int enr); +extern struct lc_element *lc_find(struct lru_cache *lc, unsigned int enr); +extern struct lc_element *lc_get(struct lru_cache *lc, unsigned int enr); +extern unsigned int lc_put(struct lru_cache *lc, struct lc_element *e); +extern void lc_changed(struct lru_cache *lc, struct lc_element *e); + +struct seq_file; +extern size_t lc_printf_stats(struct seq_file *seq, struct lru_cache *lc); + +void lc_dump(struct lru_cache *lc, struct seq_file *seq, char *utext, + void (*detail) (struct seq_file *, struct lc_element *)); + +/* This can be used to stop lc_get from changing the set of active elements. + * Note that the reference counts and order on the lru list may still change. + * returns true if we aquired the lock. + */ +static inline int lc_try_lock(struct lru_cache *lc) +{ + return !test_and_set_bit(__LC_DIRTY, &lc->flags); +} + +static inline void lc_unlock(struct lru_cache *lc) +{ + clear_bit(__LC_DIRTY, &lc->flags); + smp_mb__after_clear_bit(); +} + +static inline int lc_is_used(struct lru_cache *lc, unsigned int enr) +{ + struct lc_element *e = lc_find(lc, enr); + return e && e->refcnt; +} + +#define LC_FREE (-1U) + +#define lc_e_base(lc) ((char *)((lc)->slot + (lc)->nr_elements)) +#define lc_entry(lc, i) ((struct lc_element *) \ + (lc_e_base(lc) + (i)*(lc)->element_size)) +#define lc_index_of(lc, e) (((char *)(e) - lc_e_base(lc))/(lc)->element_size) + +#endif --- linux-2.6.28.orig/ubuntu/drbd/drbd_req.h +++ linux-2.6.28/ubuntu/drbd/drbd_req.h @@ -0,0 +1,331 @@ +/* + drbd_req.h + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2006-2008, LINBIT Information Technologies GmbH. + Copyright (C) 2006-2008, Lars Ellenberg . + Copyright (C) 2006-2008, Philipp Reisner . + + DRBD is free software; you can redistribute 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. + + DRBD is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _DRBD_REQ_H +#define _DRBD_REQ_H + +#include +#include + +#include +#include +#include "drbd_int.h" + +/* The request callbacks will be called in irq context by the IDE drivers, + and in Softirqs/Tasklets/BH context by the SCSI drivers, + and by the receiver and worker in kernel-thread context. + Try to get the locking right :) */ + +/* + * Objects of type struct drbd_request do only exist on a Primary node, and are + * associated with IO requests originating from the block layer above us. + * + * There are quite a few things that may happen to a drbd request + * during its lifetime. + * + * It will be created. + * It will be marked with the intention to be + * submitted to local disk and/or + * send via the network. + * + * It has to be placed on the transfer log and other housekeeping lists, + * In case we have a network connection. + * FIXME I believe that for consistency we should place even READ requests + * on these lists, so we can moan when we detect that the other node is + * writing to an area that we currently read from (when this happens, our + * users are broken). + * + * It may be identified as a concurrent (write) request + * and be handled accordingly. + * + * It may me handed over to the local disk subsystem. + * It may be completed by the local disk subsystem, + * either sucessfully or with io-error. + * In case it is a READ request, and it failed locally, + * it may be retried remotely. + * + * It may be queued for sending. + * It may be handed over to the network stack, + * which may fail. + * It may be acknowledged by the "peer" according to the wire_protocol in use. + * this may be a negative ack. + * It may receive a faked ack when the network connection is lost and the + * transfer log is cleaned up. + * Sending may be canceled due to network connection loss. + * When it finally has outlived its time, + * corresponding dirty bits in the resync-bitmap may be cleared or set, + * it will be destroyed, + * and completion will be signalled to the originator, + * with or without "success". + * + * See also documentation/drbd-request-state-overview.dot + * (dot -Tps2 documentation/drbd-request-state-overview.dot | display -) + */ + +enum drbd_req_event { + created, + to_be_send, + to_be_submitted, + + /* XXX yes, now I am inconsistent... + * these two are not "events" but "actions" + * oh, well... */ + queue_for_net_write, + queue_for_net_read, + + send_canceled, + send_failed, + handed_over_to_network, + connection_lost_while_pending, + recv_acked_by_peer, + write_acked_by_peer, + write_acked_by_peer_and_sis, /* and set_in_sync */ + conflict_discarded_by_peer, + neg_acked, + barrier_acked, /* in protocol A and B */ + data_received, /* (remote read) */ + + read_completed_with_error, + write_completed_with_error, + completed_ok, +}; + +/* encoding of request states for now. we don't actually need that many bits. + * we don't need to do atomic bit operations either, since most of the time we + * need to look at the connection state and/or manipulate some lists at the + * same time, so we should hold the request lock anyways. + */ +enum drbd_req_state_bits { + /* 210 + * 000: no local possible + * 001: to be submitted + * UNUSED, we could map: 011: submitted, completion still pending + * 110: completed ok + * 010: completed with error + */ + __RQ_LOCAL_PENDING, + __RQ_LOCAL_COMPLETED, + __RQ_LOCAL_OK, + + /* 76543 + * 00000: no network possible + * 00001: to be send + * 00011: to be send, on worker queue + * 00101: sent, expecting recv_ack (B) or write_ack (C) + * 11101: sent, + * recv_ack (B) or implicit "ack" (A), + * still waiting for the barrier ack. + * master_bio may already be completed and invalidated. + * 11100: write_acked (C), + * data_received (for remote read, any protocol) + * or finally the barrier ack has arrived (B,A)... + * request can be freed + * 01100: neg-acked (write, protocol C) + * or neg-d-acked (read, any protocol) + * or killed from the transfer log + * during cleanup after connection loss + * request can be freed + * 01000: canceled or send failed... + * request can be freed + */ + + /* if "SENT" is not set, yet, this can still fail or be canceled. + * if "SENT" is set already, we still wait for an Ack packet. + * when cleared, the master_bio may be completed. + * in (B,A) the request object may still linger on the transaction log + * until the corresponding barrier ack comes in */ + __RQ_NET_PENDING, + + /* If it is QUEUED, and it is a WRITE, it is also registered in the + * transfer log. Currently we need this flag to avoid conflicts between + * worker canceling the request and tl_clear_barrier killing it from + * transfer log. We should restructure the code so this conflict does + * no longer occur. */ + __RQ_NET_QUEUED, + + /* well, actually only "handed over to the network stack". + * + * TODO can potentially be dropped because of the similar meaning + * of RQ_NET_SENT and ~RQ_NET_QUEUED. + * however it is not exactly the same. before we drop it + * we must ensure that we can tell a request with network part + * from a request without, regardless of what happens to it. */ + __RQ_NET_SENT, + + /* when set, the request may be freed (if RQ_NET_QUEUED is clear). + * basically this means the corresponding BarrierAck was received */ + __RQ_NET_DONE, + + /* whether or not we know (C) or pretend (B,A) that the write + * was successfully written on the peer. + */ + __RQ_NET_OK, + + /* peer called drbd_set_in_sync() for this write */ + __RQ_NET_SIS, + + /* keep this last, its for the RQ_NET_MASK */ + __RQ_NET_MAX, +}; + +#define RQ_LOCAL_PENDING (1UL << __RQ_LOCAL_PENDING) +#define RQ_LOCAL_COMPLETED (1UL << __RQ_LOCAL_COMPLETED) +#define RQ_LOCAL_OK (1UL << __RQ_LOCAL_OK) + +#define RQ_LOCAL_MASK ((RQ_LOCAL_OK << 1)-1) /* 0x07 */ + +#define RQ_NET_PENDING (1UL << __RQ_NET_PENDING) +#define RQ_NET_QUEUED (1UL << __RQ_NET_QUEUED) +#define RQ_NET_SENT (1UL << __RQ_NET_SENT) +#define RQ_NET_DONE (1UL << __RQ_NET_DONE) +#define RQ_NET_OK (1UL << __RQ_NET_OK) +#define RQ_NET_SIS (1UL << __RQ_NET_SIS) + +/* 0x1f8 */ +#define RQ_NET_MASK (((1UL << __RQ_NET_MAX)-1) & ~RQ_LOCAL_MASK) + +/* epoch entries */ +static inline +struct hlist_head *ee_hash_slot(struct drbd_conf *mdev, sector_t sector) +{ + BUG_ON(mdev->ee_hash_s == 0); + return mdev->ee_hash + + ((unsigned int)(sector>>HT_SHIFT) % mdev->ee_hash_s); +} + +/* transfer log (drbd_request objects) */ +static inline +struct hlist_head *tl_hash_slot(struct drbd_conf *mdev, sector_t sector) +{ + BUG_ON(mdev->tl_hash_s == 0); + return mdev->tl_hash + + ((unsigned int)(sector>>HT_SHIFT) % mdev->tl_hash_s); +} + +/* when we receive the ACK for a write request, + * verify that we actually know about it */ +static inline struct drbd_request *_ack_id_to_req(struct drbd_conf *mdev, + u64 id, sector_t sector) +{ + struct hlist_head *slot = tl_hash_slot(mdev, sector); + struct hlist_node *n; + struct drbd_request *req; + + hlist_for_each_entry(req, n, slot, colision) { + if ((unsigned long)req == (unsigned long)id) { + if (req->sector != sector) { + ERR("_ack_id_to_req: found req %p but it has " + "wrong sector (%llus versus %llus)\n", req, + (unsigned long long)req->sector, + (unsigned long long)sector); + break; + } + return req; + } + } + ERR("_ack_id_to_req: failed to find req %p, sector %llus in list\n", + (void *)(unsigned long)id, (unsigned long long)sector); + return NULL; +} + +/* application reads (drbd_request objects) */ +static struct hlist_head *ar_hash_slot(struct drbd_conf *mdev, sector_t sector) +{ + return mdev->app_reads_hash + + ((unsigned int)(sector) % APP_R_HSIZE); +} + +/* when we receive the answer for a read request, + * verify that we actually know about it */ +static inline struct drbd_request *_ar_id_to_req(struct drbd_conf *mdev, + u64 id, sector_t sector) +{ + struct hlist_head *slot = ar_hash_slot(mdev, sector); + struct hlist_node *n; + struct drbd_request *req; + + hlist_for_each_entry(req, n, slot, colision) { + if ((unsigned long)req == (unsigned long)id) { + D_ASSERT(req->sector == sector); + return req; + } + } + return NULL; +} + +static inline struct drbd_request *drbd_req_new(struct drbd_conf *mdev, + struct bio *bio_src) +{ + struct bio *bio; + struct drbd_request *req = + mempool_alloc(drbd_request_mempool, GFP_NOIO); + if (likely(req)) { + bio = bio_clone(bio_src, GFP_NOIO); /* XXX cannot fail?? */ + + req->rq_state = 0; + req->mdev = mdev; + req->master_bio = bio_src; + req->private_bio = bio; + req->epoch = 0; + req->sector = bio->bi_sector; + req->size = bio->bi_size; + req->start_time = jiffies; + INIT_HLIST_NODE(&req->colision); + INIT_LIST_HEAD(&req->tl_requests); + INIT_LIST_HEAD(&req->w.list); + + bio->bi_private = req; + bio->bi_end_io = drbd_endio_pri; + bio->bi_next = NULL; + } + return req; +} + +static inline void drbd_req_free(struct drbd_request *req) +{ + mempool_free(req, drbd_request_mempool); +} + +static inline int overlaps(sector_t s1, int l1, sector_t s2, int l2) +{ + return !((s1 + (l1>>9) <= s2) || (s1 >= s2 + (l2>>9))); +} + +/* aparently too large to be inlined... + * moved to drbd_req.c */ +extern void _req_may_be_done(struct drbd_request *req, int error); +extern void _req_mod(struct drbd_request *req, + enum drbd_req_event what, int error); + +/* If you need it irqsave, do it your self! */ +static inline void req_mod(struct drbd_request *req, + enum drbd_req_event what, int error) +{ + struct drbd_conf *mdev = req->mdev; + spin_lock_irq(&mdev->req_lock); + _req_mod(req, what, error); + spin_unlock_irq(&mdev->req_lock); +} +#endif --- linux-2.6.28.orig/ubuntu/drbd/BOM +++ linux-2.6.28/ubuntu/drbd/BOM @@ -0,0 +1,2 @@ +Downloaded from: http://oss.linbit.com/drbd/ +Current Version: 8.3.0 --- linux-2.6.28.orig/ubuntu/drbd/linux/drbd_tag_magic.h +++ linux-2.6.28/ubuntu/drbd/linux/drbd_tag_magic.h @@ -0,0 +1,83 @@ +#ifndef DRBD_TAG_MAGIC_H +#define DRBD_TAG_MAGIC_H + +#define TT_END 0 +#define TT_REMOVED 0xE000 + +/* declare packet_type enums */ +enum packet_types { +#define NL_PACKET(name, number, fields) P_ ## name = number, +#define NL_INTEGER(pn, pr, member) +#define NL_INT64(pn, pr, member) +#define NL_BIT(pn, pr, member) +#define NL_STRING(pn, pr, member, len) +#include "drbd_nl.h" + P_nl_after_last_packet, +}; + +/* These struct are used to deduce the size of the tag lists: */ +#define NL_PACKET(name, number, fields) \ + struct name ## _tag_len_struct { fields }; +#define NL_INTEGER(pn, pr, member) \ + int member; int tag_and_len ## member; +#define NL_INT64(pn, pr, member) \ + __u64 member; int tag_and_len ## member; +#define NL_BIT(pn, pr, member) \ + unsigned char member:1; int tag_and_len ## member; +#define NL_STRING(pn, pr, member, len) \ + unsigned char member[len]; int member ## _len; \ + int tag_and_len ## member; +#include "linux/drbd_nl.h" + +/* declate tag-list-sizes */ +static const int tag_list_sizes[] = { +#define NL_PACKET(name, number, fields) 2 fields , +#define NL_INTEGER(pn, pr, member) + 4 + 4 +#define NL_INT64(pn, pr, member) + 4 + 8 +#define NL_BIT(pn, pr, member) + 4 + 1 +#define NL_STRING(pn, pr, member, len) + 4 + (len) +#include "drbd_nl.h" +}; + +/* The two highest bits are used for the tag type */ +#define TT_MASK 0xC000 +#define TT_INTEGER 0x0000 +#define TT_INT64 0x4000 +#define TT_BIT 0x8000 +#define TT_STRING 0xC000 +/* The next bit indicates if processing of the tag is mandatory */ +#define T_MANDATORY 0x2000 +#define T_MAY_IGNORE 0x0000 +#define TN_MASK 0x1fff +/* The remaining 13 bits are used to enumerate the tags */ + +#define tag_type(T) ((T) & TT_MASK) +#define tag_number(T) ((T) & TN_MASK) + +/* declare tag enums */ +#define NL_PACKET(name, number, fields) fields +enum drbd_tags { +#define NL_INTEGER(pn, pr, member) T_ ## member = pn | TT_INTEGER | pr , +#define NL_INT64(pn, pr, member) T_ ## member = pn | TT_INT64 | pr , +#define NL_BIT(pn, pr, member) T_ ## member = pn | TT_BIT | pr , +#define NL_STRING(pn, pr, member, len) T_ ## member = pn | TT_STRING | pr , +#include "drbd_nl.h" +}; + +struct tag { + const char *name; + int type_n_flags; + int max_len; +}; + +/* declare tag names */ +#define NL_PACKET(name, number, fields) fields +static const struct tag tag_descriptions[] = { +#define NL_INTEGER(pn, pr, member) [ pn ] = { #member, TT_INTEGER | pr, sizeof(int) }, +#define NL_INT64(pn, pr, member) [ pn ] = { #member, TT_INT64 | pr, sizeof(__u64) }, +#define NL_BIT(pn, pr, member) [ pn ] = { #member, TT_BIT | pr, sizeof(int) }, +#define NL_STRING(pn, pr, member, len) [ pn ] = { #member, TT_STRING | pr, (len) }, +#include "drbd_nl.h" +}; + +#endif --- linux-2.6.28.orig/ubuntu/drbd/linux/drbd_limits.h +++ linux-2.6.28/ubuntu/drbd/linux/drbd_limits.h @@ -0,0 +1,130 @@ +/* + drbd_limits.h + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. +*/ + +/* + * Our current limitations. + * Some of them are hard limits, + * some of them are arbitrary range limits, that make it easier to provide + * feedback about nonsense settings for certain configurable values. + */ + +#ifndef DRBD_LIMITS_H +#define DRBD_LIMITS_H 1 + +#define DEBUG_RANGE_CHECK 0 + +#define DRBD_MINOR_COUNT_MIN 1 +#define DRBD_MINOR_COUNT_MAX 255 + +#define DRBD_DIALOG_REFRESH_MIN 0 +#define DRBD_DIALOG_REFRESH_MAX 600 + +/* valid port number */ +#define DRBD_PORT_MIN 1 +#define DRBD_PORT_MAX 0xffff + +/* startup { */ + /* if you want more than 3.4 days, disable */ +#define DRBD_WFC_TIMEOUT_MIN 0 +#define DRBD_WFC_TIMEOUT_MAX 300000 +#define DRBD_WFC_TIMEOUT_DEF 0 + +#define DRBD_DEGR_WFC_TIMEOUT_MIN 0 +#define DRBD_DEGR_WFC_TIMEOUT_MAX 300000 +#define DRBD_DEGR_WFC_TIMEOUT_DEF 60 + +/* }*/ + +/* net { */ + /* timeout, unit centi seconds + * more than one minute timeout is not usefull */ +#define DRBD_TIMEOUT_MIN 1 +#define DRBD_TIMEOUT_MAX 600 +#define DRBD_TIMEOUT_DEF 60 /* 6 seconds */ + + /* active connection retries when WFConnection */ +#define DRBD_CONNECT_INT_MIN 1 +#define DRBD_CONNECT_INT_MAX 120 +#define DRBD_CONNECT_INT_DEF 10 /* seconds */ + + /* keep-alive probes when idle */ +#define DRBD_PING_INT_MIN 1 +#define DRBD_PING_INT_MAX 120 +#define DRBD_PING_INT_DEF 10 + + /* timeout for the ping packets.*/ +#define DRBD_PING_TIMEO_MIN 1 +#define DRBD_PING_TIMEO_MAX 100 +#define DRBD_PING_TIMEO_DEF 5 + + /* max number of write requests between write barriers */ +#define DRBD_MAX_EPOCH_SIZE_MIN 1 +#define DRBD_MAX_EPOCH_SIZE_MAX 20000 +#define DRBD_MAX_EPOCH_SIZE_DEF 2048 + + /* I don't think that a tcp send buffer of more than 10M is usefull */ +#define DRBD_SNDBUF_SIZE_MIN 0 +#define DRBD_SNDBUF_SIZE_MAX (10<<20) +#define DRBD_SNDBUF_SIZE_DEF (2*65535) + + /* @4k PageSize -> 128kB - 512MB */ +#define DRBD_MAX_BUFFERS_MIN 32 +#define DRBD_MAX_BUFFERS_MAX 131072 +#define DRBD_MAX_BUFFERS_DEF 2048 + + /* @4k PageSize -> 4kB - 512MB */ +#define DRBD_UNPLUG_WATERMARK_MIN 1 +#define DRBD_UNPLUG_WATERMARK_MAX 131072 +#define DRBD_UNPLUG_WATERMARK_DEF (DRBD_MAX_BUFFERS_DEF/16) + + /* 0 is disabled. + * 200 should be more than enough even for very short timeouts */ +#define DRBD_KO_COUNT_MIN 0 +#define DRBD_KO_COUNT_MAX 200 +#define DRBD_KO_COUNT_DEF 0 +/* } */ + +/* syncer { */ + /* FIXME allow rate to be zero? */ +#define DRBD_RATE_MIN 1 +/* channel bonding 10 GbE, or other hardware */ +#define DRBD_RATE_MAX (4 << 20) +#define DRBD_RATE_DEF 250 /* kb/second */ + + /* less than 7 would hit performance unneccessarily. + * 3833 is the largest prime that still does fit + * into 64 sectors of activity log */ +#define DRBD_AL_EXTENTS_MIN 7 +#define DRBD_AL_EXTENTS_MAX 3833 +#define DRBD_AL_EXTENTS_DEF 127 + +#define DRBD_AFTER_MIN -1 +#define DRBD_AFTER_MAX 255 +#define DRBD_AFTER_DEF -1 + +/* } */ + +/* drbdsetup XY resize -d Z + * you are free to reduce the device size to nothing, if you want to. + * the upper limit with 64bit kernel, enough ram and flexible meta data + * is 16 TB, currently. */ +/* DRBD_MAX_SECTORS */ +#define DRBD_DISK_SIZE_SECT_MIN 0 +#define DRBD_DISK_SIZE_SECT_MAX (16 * (2LLU << 30)) +#define DRBD_DISK_SIZE_SECT_DEF 0 /* = disabled = no user size... */ + +#define DRBD_ON_IO_ERROR_DEF PassOn +#define DRBD_FENCING_DEF DontCare +#define DRBD_AFTER_SB_0P_DEF Disconnect +#define DRBD_AFTER_SB_1P_DEF Disconnect +#define DRBD_AFTER_SB_2P_DEF Disconnect +#define DRBD_RR_CONFLICT_DEF Disconnect + +#define DRBD_MAX_BIO_BVECS_MIN 0 +#define DRBD_MAX_BIO_BVECS_MAX 128 +#define DRBD_MAX_BIO_BVECS_DEF 0 + +#undef RANGE +#endif --- linux-2.6.28.orig/ubuntu/drbd/linux/drbd_config.h +++ linux-2.6.28/ubuntu/drbd/linux/drbd_config.h @@ -0,0 +1,99 @@ +/* + drbd_config.h + DRBD's compile time configuration. + + drbd is free software; you can redistribute 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. + + drbd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef DRBD_CONFIG_H +#define DRBD_CONFIG_H + +extern const char *drbd_buildtag(void); + +#define REL_VERSION "8.3.0" +#define API_VERSION 88 +#define PRO_VERSION_MIN 86 +#define PRO_VERSION_MAX 89 + +#ifndef __CHECKER__ /* for a sparse run, we need all STATICs */ +#define DBG_ALL_SYMBOLS /* no static functs, improves quality of OOPS traces */ +#endif + +/* drbd_assert_breakpoint() function +#define DBG_ASSERTS + */ + +/* Dump all cstate changes */ +#define DUMP_MD 2 + +/* some extra checks +#define PARANOIA + */ + +/* Dump every hour the usage / not usage of zero copy IO */ +/* #define SHOW_SENDPAGE_USAGE */ + +/* Define this to enable dynamic tracing controlled by module parameters + * at run time. This enables ALL use of dynamic tracing including packet + * and bio dumping, etc */ +#define ENABLE_DYNAMIC_TRACE + +/* You can disable the use of the sendpage() call (= zero copy IO) + * If you have the feeling that this might be the cause for troubles. +#define DRBD_DISABLE_SENDPAGE + */ + +/* Enable fault insertion code */ +#define DRBD_ENABLE_FAULTS + +/* RedHat's 2.6.9 kernels have the gfp_t type. Mainline has this feature + * since 2.6.16. If you build for RedHat enable the line below. */ +#define KERNEL_HAS_GFP_T + +/* kernel.org has atomic_add_return since 2.6.10. some vendor kernels + * have it backported, though. Others don't. */ +//#define NEED_BACKPORT_OF_ATOMIC_ADD + +/* 2.6.something has deprecated kmem_cache_t + * some older still use it. + * some have it defined as struct kmem_cache_s, some as struct kmem_cache */ +//#define USE_KMEM_CACHE_S + +/* 2.6.something has sock_create_kern (SE-linux security context stuff) + * some older distribution kernels don't. */ +//#define DEFINE_SOCK_CREATE_KERN + +/* in older kernels (vanilla < 2.6.16) struct netlink_skb_parms has a + * member called dst_groups. Later it is called dst_group (without 's'). */ +//#define DRBD_NL_DST_GROUPS + +/* in older kernels (vanilla < 2.6.14) is no kzalloc() */ +//#define NEED_BACKPORT_OF_KZALLOC + +// some vendor kernels have it, some don't +//#define NEED_SG_SET_BUF +#define HAVE_LINUX_SCATTERLIST_H + +/* Some vendor kernels < 2.6.7 might define msleep in one or + * another way .. */ + +#define KERNEL_HAS_MSLEEP + +/* Some other kernels < 2.6.8 do not have struct kvec, + * others do.. */ + +#define KERNEL_HAS_KVEC + +#endif --- linux-2.6.28.orig/ubuntu/drbd/linux/drbd_nl.h +++ linux-2.6.28/ubuntu/drbd/linux/drbd_nl.h @@ -0,0 +1,134 @@ +/* + PAKET( name, + TYPE ( pn, pr, member ) + ... + ) + + You may never reissue one of the pn arguments +*/ + +#if !defined(NL_PACKET) || !defined(NL_STRING) || !defined(NL_INTEGER) || !defined(NL_BIT) || !defined(NL_INT64) +#error "The macros NL_PACKET, NL_STRING, NL_INTEGER, NL_INT64 and NL_BIT needs to be defined" +#endif + +NL_PACKET(primary, 1, + NL_BIT( 1, T_MAY_IGNORE, overwrite_peer) +) + +NL_PACKET(secondary, 2, ) + +NL_PACKET(disk_conf, 3, + NL_INT64( 2, T_MAY_IGNORE, disk_size) + NL_STRING( 3, T_MANDATORY, backing_dev, 128) + NL_STRING( 4, T_MANDATORY, meta_dev, 128) + NL_INTEGER( 5, T_MANDATORY, meta_dev_idx) + NL_INTEGER( 6, T_MAY_IGNORE, on_io_error) + NL_INTEGER( 7, T_MAY_IGNORE, fencing) + NL_BIT( 37, T_MAY_IGNORE, use_bmbv) + NL_BIT( 53, T_MAY_IGNORE, no_disk_flush) + NL_BIT( 54, T_MAY_IGNORE, no_md_flush) + /* 55 max_bio_size was available in 8.2.6rc2 */ + NL_INTEGER( 56, T_MAY_IGNORE, max_bio_bvecs) + NL_BIT( 57, T_MAY_IGNORE, no_disk_barrier) + NL_BIT( 58, T_MAY_IGNORE, no_disk_drain) +) + +NL_PACKET(detach, 4, ) + +NL_PACKET(net_conf, 5, + NL_STRING( 8, T_MANDATORY, my_addr, 128) + NL_STRING( 9, T_MANDATORY, peer_addr, 128) + NL_STRING( 10, T_MAY_IGNORE, shared_secret, SHARED_SECRET_MAX) + NL_STRING( 11, T_MAY_IGNORE, cram_hmac_alg, SHARED_SECRET_MAX) + NL_STRING( 44, T_MAY_IGNORE, integrity_alg, SHARED_SECRET_MAX) + NL_INTEGER( 14, T_MAY_IGNORE, timeout) + NL_INTEGER( 15, T_MANDATORY, wire_protocol) + NL_INTEGER( 16, T_MAY_IGNORE, try_connect_int) + NL_INTEGER( 17, T_MAY_IGNORE, ping_int) + NL_INTEGER( 18, T_MAY_IGNORE, max_epoch_size) + NL_INTEGER( 19, T_MAY_IGNORE, max_buffers) + NL_INTEGER( 20, T_MAY_IGNORE, unplug_watermark) + NL_INTEGER( 21, T_MAY_IGNORE, sndbuf_size) + NL_INTEGER( 22, T_MAY_IGNORE, ko_count) + NL_INTEGER( 24, T_MAY_IGNORE, after_sb_0p) + NL_INTEGER( 25, T_MAY_IGNORE, after_sb_1p) + NL_INTEGER( 26, T_MAY_IGNORE, after_sb_2p) + NL_INTEGER( 39, T_MAY_IGNORE, rr_conflict) + NL_INTEGER( 40, T_MAY_IGNORE, ping_timeo) + /* 59 addr_family was available in GIT, never released */ + NL_BIT( 60, T_MANDATORY, mind_af) + NL_BIT( 27, T_MAY_IGNORE, want_lose) + NL_BIT( 28, T_MAY_IGNORE, two_primaries) + NL_BIT( 41, T_MAY_IGNORE, always_asbp) + NL_BIT( 61, T_MAY_IGNORE, no_cork) + NL_BIT( 62, T_MANDATORY, auto_sndbuf_size) +) + +NL_PACKET(disconnect, 6, ) + +NL_PACKET(resize, 7, + NL_INT64( 29, T_MAY_IGNORE, resize_size) +) + +NL_PACKET(syncer_conf, 8, + NL_INTEGER( 30, T_MAY_IGNORE, rate) + NL_INTEGER( 31, T_MAY_IGNORE, after) + NL_INTEGER( 32, T_MAY_IGNORE, al_extents) + NL_STRING( 52, T_MAY_IGNORE, verify_alg, SHARED_SECRET_MAX) + NL_STRING( 51, T_MAY_IGNORE, cpu_mask, 32) + NL_STRING( 64, T_MAY_IGNORE, csums_alg, SHARED_SECRET_MAX) +) + +NL_PACKET(invalidate, 9, ) +NL_PACKET(invalidate_peer, 10, ) +NL_PACKET(pause_sync, 11, ) +NL_PACKET(resume_sync, 12, ) +NL_PACKET(suspend_io, 13, ) +NL_PACKET(resume_io, 14, ) +NL_PACKET(outdate, 15, ) +NL_PACKET(get_config, 16, ) +NL_PACKET(get_state, 17, + NL_INTEGER( 33, T_MAY_IGNORE, state_i) +) + +NL_PACKET(get_uuids, 18, + NL_STRING( 34, T_MAY_IGNORE, uuids, (UUID_SIZE*sizeof(__u64))) + NL_INTEGER( 35, T_MAY_IGNORE, uuids_flags) +) + +NL_PACKET(get_timeout_flag, 19, + NL_BIT( 36, T_MAY_IGNORE, use_degraded) +) + +NL_PACKET(call_helper, 20, + NL_STRING( 38, T_MAY_IGNORE, helper, 32) +) + +/* Tag nr 42 already allocated in drbd-8.1 development. */ + +NL_PACKET(sync_progress, 23, + NL_INTEGER( 43, T_MAY_IGNORE, sync_progress) +) + +NL_PACKET(dump_ee, 24, + NL_STRING( 45, T_MAY_IGNORE, dump_ee_reason, 32) + NL_STRING( 46, T_MAY_IGNORE, seen_digest, SHARED_SECRET_MAX) + NL_STRING( 47, T_MAY_IGNORE, calc_digest, SHARED_SECRET_MAX) + NL_INT64( 48, T_MAY_IGNORE, ee_sector) + NL_INT64( 49, T_MAY_IGNORE, ee_block_id) + NL_STRING( 50, T_MAY_IGNORE, ee_data, 32 << 10) +) + +NL_PACKET(start_ov, 25, +) + +NL_PACKET(new_c_uuid, 26, + NL_BIT( 63, T_MANDATORY, clear_bm) +) + +#undef NL_PACKET +#undef NL_INTEGER +#undef NL_INT64 +#undef NL_BIT +#undef NL_STRING + --- linux-2.6.28.orig/ubuntu/drbd/linux/drbd.h +++ linux-2.6.28/ubuntu/drbd/linux/drbd.h @@ -0,0 +1,368 @@ +/* + drbd.h + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2001-2008, LINBIT Information Technologies GmbH. + Copyright (C) 2001-2008, Philipp Reisner . + Copyright (C) 2001-2008, Lars Ellenberg . + + drbd is free software; you can redistribute 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. + + drbd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +#ifndef DRBD_H +#define DRBD_H +#include +#include + +#include + +#ifdef __KERNEL__ +#include +#include +#else +#include +#include +#include + +/* Altough the Linux source code makes a difference between + generic endiness and the bitfields' endianess, there is no + architecture as of Linux-2.6.24-rc4 where the bitfileds' endianess + does not match the generic endianess. */ + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define __LITTLE_ENDIAN_BITFIELD +#elif __BYTE_ORDER == __BIG_ENDIAN +#define __BIG_ENDIAN_BITFIELD +#else +# error "sorry, weird endianness on this box" +#endif + +#endif + + +enum io_error_handler { + PassOn, /* FIXME should the better be named "Ignore"? */ + CallIOEHelper, + Detach +}; + +enum fencing_policy { + DontCare, + Resource, + Stonith +}; + +enum disconnect_handler { + Reconnect, + DropNetConf, + FreezeIO +}; + +enum after_sb_handler { + Disconnect, + DiscardYoungerPri, + DiscardOlderPri, + DiscardZeroChg, + DiscardLeastChg, + DiscardLocal, + DiscardRemote, + Consensus, + DiscardSecondary, + CallHelper, + Violently +}; + +/* KEEP the order, do not delete or insert! + * Or change the API_VERSION, too. */ +enum ret_codes { + RetCodeBase = 100, + NoError, /* 101 ... */ + LAAlreadyInUse, + OAAlreadyInUse, + LDNameInvalid, + MDNameInvalid, + LDAlreadyInUse, + LDNoBlockDev, + MDNoBlockDev, + LDOpenFailed, + MDOpenFailed, + LDDeviceTooSmall, + MDDeviceTooSmall, + LDNoConfig, + LDMounted, + MDMounted, + LDMDInvalid, + LDDeviceTooLarge, + MDIOError, + MDInvalid, + CRAMAlgNotAvail, + CRAMAlgNotDigest, + KMallocFailed, + DiscardNotAllowed, + HaveDiskConfig, + HaveNetConfig, + UnknownMandatoryTag, + MinorNotKnown, + StateNotAllowed, + GotSignal, /* EINTR */ + NoResizeDuringResync, + APrimaryNodeNeeded, + SyncAfterInvalid, + SyncAfterCycle, + PauseFlagAlreadySet, + PauseFlagAlreadyClear, + DiskLowerThanOutdated, /* obsolete, now SS_LowerThanOutdated */ + UnknownNetLinkPacket, + HaveNoDiskConfig, + ProtocolCRequired, + VMallocFailed, + IntegrityAlgNotAvail, + IntegrityAlgNotDigest, + CPUMaskParseFailed, + CSUMSAlgNotAvail, + CSUMSAlgNotDigest, + VERIFYAlgNotAvail, + VERIFYAlgNotDigest, + CSUMSResyncRunning, + VERIFYIsRunning, + DataOfWrongCurrent, + MayNotBeConnected, + + /* insert new ones above this line */ + AfterLastRetCode, +}; + +#define DRBD_PROT_A 1 +#define DRBD_PROT_B 2 +#define DRBD_PROT_C 3 + +enum drbd_role { + Unknown = 0, + Primary = 1, /* role */ + Secondary = 2, /* role */ + role_mask = 3, +}; + +/* The order of these constants is important. + * The lower ones (=WFReportParams ==> There is a socket + * + * THINK + * Skipped should be < Connected, + * so writes on a Primary after Skipped sync are not mirrored either ? + */ +enum drbd_conns { + StandAlone, + Disconnecting, /* Temporal state on the way to StandAlone. */ + Unconnected, /* >= Unconnected -> inc_net() succeeds */ + + /* These temporal states are all used on the way + * from >= Connected to Unconnected. + * The 'disconnect reason' states + * I do not allow to change beween them. */ + Timeout, + BrokenPipe, + NetworkFailure, + ProtocolError, + TearDown, + + WFConnection, + WFReportParams, /* we have a socket */ + Connected, /* we have introduced each other */ + StartingSyncS, /* starting full sync by IOCTL. */ + StartingSyncT, /* stariing full sync by IOCTL. */ + WFBitMapS, + WFBitMapT, + WFSyncUUID, + + /* All SyncStates are tested with this comparison + * xx >= SyncSource && xx <= PausedSyncT */ + SyncSource, + SyncTarget, + VerifyS, + VerifyT, + PausedSyncS, + PausedSyncT, + conn_mask = 31 +}; + +enum drbd_disk_state { + Diskless, + Attaching, /* In the process of reading the meta-data */ + Failed, /* Becomes Diskless as soon as we told it the peer */ + /* when >= Failed it is legal to access mdev->bc */ + Negotiating, /* Late attaching state, we need to talk to the peer */ + Inconsistent, + Outdated, + DUnknown, /* Only used for the peer, never for myself */ + Consistent, /* Might be Outdated, might be UpToDate ... */ + UpToDate, /* Only this disk state allows applications' IO ! */ + disk_mask = 15 +}; + +union drbd_state_t { +/* According to gcc's docs is the ... + * The order of allocation of bit-fields within a unit (C90 6.5.2.1, C99 6.7.2.1). + * Determined by ABI. + * pointed out by Maxim Uvarov q + * even though we transmit as "cpu_to_be32(state)", + * the offsets of the bitfields still need to be swapped + * on different endianess. + */ + struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + unsigned role:2 ; /* 3/4 primary/secondary/unknown */ + unsigned peer:2 ; /* 3/4 primary/secondary/unknown */ + unsigned conn:5 ; /* 17/32 cstates */ + unsigned disk:4 ; /* 8/16 from Diskless to UpToDate */ + unsigned pdsk:4 ; /* 8/16 from Diskless to UpToDate */ + unsigned susp:1 ; /* 2/2 IO suspended no/yes */ + unsigned aftr_isp:1 ; /* isp .. imposed sync pause */ + unsigned peer_isp:1 ; + unsigned user_isp:1 ; + unsigned _pad:11; /* 0 unused */ +#elif defined(__BIG_ENDIAN_BITFIELD) + unsigned _pad:11; /* 0 unused */ + unsigned user_isp:1 ; + unsigned peer_isp:1 ; + unsigned aftr_isp:1 ; /* isp .. imposed sync pause */ + unsigned susp:1 ; /* 2/2 IO suspended no/yes */ + unsigned pdsk:4 ; /* 8/16 from Diskless to UpToDate */ + unsigned disk:4 ; /* 8/16 from Diskless to UpToDate */ + unsigned conn:5 ; /* 17/32 cstates */ + unsigned peer:2 ; /* 3/4 primary/secondary/unknown */ + unsigned role:2 ; /* 3/4 primary/secondary/unknown */ +#else +# error "this endianess is not supported" +#endif +#ifndef DRBD_DEBUG_STATE_CHANGES +#define DRBD_DEBUG_STATE_CHANGES 0 +#endif +#if DRBD_DEBUG_STATE_CHANGES + unsigned int line; + const char *func; +#endif + }; + unsigned int i; +}; + +enum set_st_err { + SS_CW_NoNeed = 4, + SS_CW_Success = 3, + SS_NothingToDo = 2, + SS_Success = 1, + SS_UnknownError = 0, /* Used to sleep longer in _drbd_request_state */ + SS_TwoPrimaries = -1, + SS_NoUpToDateDisk = -2, + SS_BothInconsistent = -4, + SS_SyncingDiskless = -5, + SS_ConnectedOutdates = -6, + SS_PrimaryNOP = -7, + SS_ResyncRunning = -8, + SS_AlreadyStandAlone = -9, + SS_CW_FailedByPeer = -10, + SS_IsDiskLess = -11, + SS_DeviceInUse = -12, + SS_NoNetConfig = -13, + SS_NoVerifyAlg = -14, /* drbd-8.2 only */ + SS_NeedConnection = -15, /* drbd-8.2 only */ + SS_LowerThanOutdated = -16, + SS_NotSupported = -17, /* drbd-8.2 only */ + SS_InTransientState = -18, /* Retry after the next state change */ + SS_ConcurrentStChg = -19, /* Concurrent cluster side state change! */ + SS_AfterLastError = -20, /* Keep this at bottom */ +}; + +/* from drbd_strings.c */ +extern const char *conns_to_name(enum drbd_conns); +extern const char *roles_to_name(enum drbd_role); +extern const char *disks_to_name(enum drbd_disk_state); +extern const char *set_st_err_name(enum set_st_err); + +#ifndef BDEVNAME_SIZE +# define BDEVNAME_SIZE 32 +#endif + +#define SHARED_SECRET_MAX 64 + +enum MetaDataFlags { + __MDF_Consistent, + __MDF_PrimaryInd, + __MDF_ConnectedInd, + __MDF_FullSync, + __MDF_WasUpToDate, + __MDF_PeerOutDated /* or worse (e.g. invalid). */ +}; +#define MDF_Consistent (1<<__MDF_Consistent) +#define MDF_PrimaryInd (1<<__MDF_PrimaryInd) +#define MDF_ConnectedInd (1<<__MDF_ConnectedInd) +#define MDF_FullSync (1<<__MDF_FullSync) +#define MDF_WasUpToDate (1<<__MDF_WasUpToDate) +#define MDF_PeerOutDated (1<<__MDF_PeerOutDated) + +enum UuidIndex { + Current, + Bitmap, + History_start, + History_end, + UUID_SIZE, /* nl-packet: number of dirty bits */ + UUID_FLAGS, /* nl-packet: flags */ + EXT_UUID_SIZE /* Everything. */ +}; + +#define UUID_JUST_CREATED ((__u64)4) + +#define DRBD_MAGIC 0x83740267 +#define BE_DRBD_MAGIC __constant_cpu_to_be32(DRBD_MAGIC) + +/* these are of type "int" */ +#define DRBD_MD_INDEX_INTERNAL -1 +#define DRBD_MD_INDEX_FLEX_EXT -2 +#define DRBD_MD_INDEX_FLEX_INT -3 + +/* Start of the new netlink/connector stuff */ + +#define DRBD_NL_CREATE_DEVICE 0x01 +#define DRBD_NL_SET_DEFAULTS 0x02 + +/* The following line should be moved over to linux/connector.h + * when the time comes */ +#ifndef CN_IDX_DRBD +# define CN_IDX_DRBD 0x6 +/* Ubuntu "intrepid ibex" release defined CN_IDX_DRBD as 0x6 */ +#endif +#define CN_VAL_DRBD 0x1 + +/* For searching a vacant cn_idx value */ +#define CN_IDX_STEP 6977 + +struct drbd_nl_cfg_req { + int packet_type; + int drbd_minor; + int flags; + unsigned short tag_list[]; +}; + +struct drbd_nl_cfg_reply { + int packet_type; + int minor; + int ret_code; /* enum ret_code or set_st_err_t */ + unsigned short tag_list[]; /* only used with get_* calls */ +}; + +#endif --- linux-2.6.28.orig/ubuntu/qc-usb/qc-pb0100.c +++ linux-2.6.28/ubuntu/qc-usb/qc-pb0100.c @@ -0,0 +1,377 @@ +/* Start of file */ + +/* {{{ [fold] Comments */ +/* + * qce-ga, linux V4L driver for the QuickCam Express and Dexxa QuickCam + * + * pb0100.c - PB0100 Sensor Implementation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 "quickcam.h" + +/* I2C Address */ +#define PB_ADDR 0xBA + +/* {{{ [fold] I2C Registers */ +#define PB_IDENT 0x00 /* R0 Chip Version */ +#define PB_RSTART 0x01 /* R1 Row Window Start */ +#define PB_CSTART 0x02 /* R2 Column Window Start */ +#define PB_RWSIZE 0x03 /* R3 Row Window Size */ +#define PB_CWSIZE 0x04 /* R4 Column Window Size */ +#define PB_CFILLIN 0x05 /* R5 Column Fill-In */ +#define PB_VBL 0x06 /* R6 Vertical Blank Count */ +#define PB_CONTROL 0x07 /* R7 Control Mode */ +#define PB_FINTTIME 0x08 /* R8 Integration Time/Frame Unit Count */ +#define PB_RINTTIME 0x09 /* R9 Integration Time/Row Unit Count */ +#define PB_ROWSPEED 0x0A /* R10 Row Speed Control */ +#define PB_ABORTFRAME 0x0B /* R11 Abort Frame */ +/* #define PB_R12 0x0C R12 Reserved */ +#define PB_RESET 0x0D /* R13 Reset */ +#define PB_EXPGAIN 0x0E /* R14 Exposure Gain Command */ +#define PB_R15 0x0F /* R15 Expose0 */ +#define PB_R16 0x10 /* R16 Expose1 */ +#define PB_R17 0x11 /* R17 Expose2 */ +#define PB_R18 0x12 /* R18 Low0_DAC */ +#define PB_R19 0x13 /* R19 Low1_DAC */ +#define PB_R20 0x14 /* R20 Low2_DAC */ +#define PB_R21 0x15 /* R21 Threshold11 */ +#define PB_R22 0x16 /* R22 Threshold0x */ +#define PB_UPDATEINT 0x17 /* R23 Update Interval */ +#define PB_R24 0x18 /* R24 High_DAC */ +#define PB_R25 0x19 /* R25 Trans0H */ +#define PB_R26 0x1A /* R26 Trans1L */ +#define PB_R27 0x1B /* R27 Trans1H */ +#define PB_R28 0x1C /* R28 Trans2L */ +/* #define PB_R29 0x1D R29 Reserved */ +/* #define PB_R30 0x1E R30 Reserved */ +#define PB_R31 0x1F /* R31 Wait to Read */ +#define PB_PREADCTRL 0x20 /* R32 Pixel Read Control Mode */ +#define PB_R33 0x21 /* R33 IREF_VLN */ +#define PB_R34 0x22 /* R34 IREF_VLP */ +#define PB_R35 0x23 /* R35 IREF_VLN_INTEG */ +#define PB_R36 0x24 /* R36 IREF_MASTER */ +#define PB_R37 0x25 /* R37 IDACP */ +#define PB_R38 0x26 /* R38 IDACN */ +#define PB_R39 0x27 /* R39 DAC_Control_Reg */ +#define PB_R40 0x28 /* R40 VCL */ +#define PB_R41 0x29 /* R41 IREF_VLN_ADCIN */ +/* #define PB_R42 0x2A R42 Reserved */ +#define PB_G1GAIN 0x2B /* R43 Green 1 Gain */ +#define PB_BGAIN 0x2C /* R44 Blue Gain */ +#define PB_RGAIN 0x2D /* R45 Red Gain */ +#define PB_G2GAIN 0x2E /* R46 Green 2 Gain */ +#define PB_R47 0x2F /* R47 Dark Row Address */ +#define PB_R48 0x30 /* R48 Dark Row Options */ +/* #define PB_R49 0x31 R49 Reserved */ +#define PB_R50 0x32 /* R50 Image Test Data */ +#define PB_ADCMAXGAIN 0x33 /* R51 Maximum Gain */ +#define PB_ADCMINGAIN 0x34 /* R52 Minimum Gain */ +#define PB_ADCGLOBALGAIN 0x35 /* R53 Global Gain */ +#define PB_R54 0x36 /* R54 Maximum Frame */ +#define PB_R55 0x37 /* R55 Minimum Frame */ +/* #define PB_R56 0x38 R56 Reserved */ +#define PB_VOFFSET 0x39 /* R57 VOFFSET */ +#define PB_R58 0x3A /* R58 Snap-Shot Sequence Trigger */ +#define PB_ADCGAINH 0x3B /* R59 VREF_HI */ +#define PB_ADCGAINL 0x3C /* R60 VREF_LO */ +/* #define PB_R61 0x3D R61 Reserved */ +/* #define PB_R62 0x3E R62 Reserved */ +/* #define PB_R63 0x3F R63 Reserved */ +#define PB_R64 0x40 /* R64 Red/Blue Gain */ +#define PB_R65 0x41 /* R65 Green 2/Green 1 Gain */ +#define PB_R66 0x42 /* R66 VREF_HI/LO */ +#define PB_R67 0x43 /* R67 Integration Time/Row Unit Count */ +#define PB_R240 0xF0 /* R240 ADC Test */ +#define PB_R241 0xF1 /* R241 Chip Enable */ +/* #define PB_R242 0xF2 R242 Reserved */ +/* }}} */ + +#define I2C_SETW_CHECK(reg,val) if ((r = qc_i2c_setw(qc,(reg),(val)))<0) goto fail +#define STV_SET_CHECK(reg,val) if ((r = qc_stv_set(qc,(reg),(val)))<0) goto fail +#define STV_SETW_CHECK(reg,val) if ((r = qc_stv_setw(qc,(reg),(val)))<0) goto fail + +/* + * The spec file for the PB-0100 suggests the following for best quality + * images after the sensor has been reset : + * + * PB_ADCGAINL = R60 = 0x03 (3 dec) : sets low reference of ADC to produce good black level + * PB_PREADCTRL = R32 = 0x1400 (5120 dec) : Enables global gain changes through R53 + * PB_ADCMINGAIN = R52 = 0x10 (16 dec) : Sets the minimum gain for auto-exposure + * PB_ADCGLOBALGAIN = R53 = 0x10 (16 dec) : Sets the global gain + * PB_EXPGAIN = R14 = 0x11 (17 dec) : Sets the auto-exposure value + * PB_UPDATEINT = R23 = 0x02 (2 dec) : Sets the speed on auto-exposure routine + * PB_CFILLIN = R5 = 0x0E (14 dec) : Sets the frame rate + */ + +/* {{{ [fold] pb0100_init: Initialise parameters of PB100 sensor */ +static int pb0100_init(struct quickcam *qc) +{ + static const Bool natural = TRUE; /* Disable flicker control for natural lighting? */ + struct qc_sensor_data *sd = &qc->sensor_data; + int r; + + if (sd->compress) return -EINVAL; + sd->maxwidth = 360; + sd->maxheight = 288; /* Sensor has 296 rows but top 8 are opaque */ + if (sd->subsample) { + sd->maxwidth /= 2; + sd->maxheight /= 2; + } + sd->exposure = 0; + + STV_SET_CHECK(STV_REG00, 1); + STV_SET_CHECK(STV_SCAN_RATE, 0); + + /* Reset sensor */ + I2C_SETW_CHECK(PB_RESET, 1); + if ((r = qc_i2c_wait(qc))<0) goto fail; + I2C_SETW_CHECK(PB_RESET, 0); + if ((r = qc_i2c_wait(qc))<0) goto fail; + + /* Disable chip */ + I2C_SETW_CHECK(PB_CONTROL, BIT(5)|BIT(3)); + if ((r = qc_i2c_wait(qc))<0) goto fail; + + /* Gain stuff...*/ + I2C_SETW_CHECK(PB_PREADCTRL, BIT(12)|BIT(10)|BIT(6)); + I2C_SETW_CHECK(PB_ADCGLOBALGAIN, 12); + if ((r = qc_i2c_wait(qc))<0) goto fail; + + /* Set up auto-exposure */ + I2C_SETW_CHECK(PB_R28, 12); /* ADC VREF_HI new setting for a transition from the Expose1 to the Expose2 setting */ + I2C_SETW_CHECK(PB_ADCMAXGAIN, 180); /* gain max for autoexposure */ + I2C_SETW_CHECK(PB_ADCMINGAIN, 12); /* gain min for autoexposure */ + I2C_SETW_CHECK(PB_R54, 3); /* Maximum frame integration time (programmed into R8) allowed for auto-exposure routine */ + I2C_SETW_CHECK(PB_R55, 0); /* Minimum frame integration time (programmed into R8) allowed for auto-exposure routine */ + I2C_SETW_CHECK(PB_UPDATEINT, 1); + I2C_SETW_CHECK(PB_R15, 800); /* R15 Expose0 (maximum that auto-exposure may use) */ + I2C_SETW_CHECK(PB_R17, 10); /* R17 Expose2 (minimum that auto-exposure may use) */ + + if (qc->settings.adaptive) { + I2C_SETW_CHECK(PB_EXPGAIN, (natural?BIT(6):0)|BIT(4)|BIT(0)); + } else { + I2C_SETW_CHECK(PB_EXPGAIN, 0); + } + if ((r = qc_i2c_wait(qc))<0) goto fail; + + I2C_SETW_CHECK(PB_VOFFSET, 0); /* 0x14 */ + I2C_SETW_CHECK(PB_ADCGAINH, 11); /* 0x0D */ + I2C_SETW_CHECK(PB_ADCGAINL, 0); /* Set black level (important!) */ + + /* ??? */ + STV_SET_CHECK(STV_REG04, 0x07); + STV_SET_CHECK(STV_REG03, 0x45); + STV_SET_CHECK(STV_REG00, 0x11); + + /* Set mode */ + STV_SET_CHECK(STV_Y_CTRL, sd->subsample ? 2 : 1); /* 0x02: half, 0x01: full FIXME: this doesn't work! */ + STV_SET_CHECK(STV_X_CTRL, sd->subsample ? 6 : 0x0A); /* 0x06: Half, 0x0A: Full */ + + /* ISO-Size (0x27b: 635... why? - HDCS uses 847) */ + STV_SETW_CHECK(STV_ISO_SIZE, 847); + + /* Setup sensor window */ + I2C_SETW_CHECK(PB_RSTART, 0); + I2C_SETW_CHECK(PB_CSTART, 0); + I2C_SETW_CHECK(PB_RWSIZE, 240-1); /* 0xF7: 240 */ + I2C_SETW_CHECK(PB_CWSIZE, 320-1); /* 0x13F: 320 */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + + /* Scan rate? */ + STV_SET_CHECK(STV_SCAN_RATE, sd->subsample ? 0x10 : 0x20); /* larger -> slower */ + + /* Scan/timing for the sensor */ + I2C_SETW_CHECK(PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1)); + I2C_SETW_CHECK(PB_CFILLIN, 14); + I2C_SETW_CHECK(PB_VBL, 0); + I2C_SETW_CHECK(PB_FINTTIME, 0); + I2C_SETW_CHECK(PB_RINTTIME, 123); + if ((r = qc_i2c_wait(qc))<0) goto fail; + + STV_SET_CHECK(STV_REG01, 0xC2); + STV_SET_CHECK(STV_REG02, 0xB0); + +fail: return r; +} +/* }}} */ +/* {{{ [fold] pb0100_set_exposure() */ +static int pb0100_set_exposure(struct quickcam *qc, unsigned int val) +{ + int r; + struct qc_sensor_data *sd = &qc->sensor_data; + val >>= 7; + if (val==sd->exposure) return 0; + sd->exposure = val; + I2C_SETW_CHECK(PB_RINTTIME, val); /* R9 */ +fail: return r; +} +/* }}} */ +/* {{{ [fold] pb0100_set_gains() */ +static int pb0100_set_gains(struct quickcam *qc, u16 hue, u16 sat, u16 val) +{ + struct qc_sensor_data *sd = &qc->sensor_data; + unsigned int rgain, bgain, ggain; + int r; + qc_hsv2rgb(hue, sat, val, &rgain, &bgain, &ggain); + rgain >>= 8; /* After this the values are 0..255 */ + ggain >>= 8; + bgain >>= 8; + if (rgain==sd->rgain && ggain==sd->ggain && bgain==sd->bgain) return 0; + sd->rgain = rgain; + sd->ggain = ggain; + sd->bgain = bgain; + I2C_SETW_CHECK(PB_RGAIN, rgain); /* R43 */ + I2C_SETW_CHECK(PB_G1GAIN, ggain); /* R44 */ + I2C_SETW_CHECK(PB_G2GAIN, ggain); /* R45 */ + I2C_SETW_CHECK(PB_BGAIN, bgain); /* R46 */ +fail: return r; +} +/* }}} */ +/* {{{ [fold] pb0100_set_levels() */ +static int pb0100_set_levels(struct quickcam *qc, unsigned int exp, unsigned int gain, unsigned int hue, unsigned int sat) +{ + int r; + /* When automatic exposure control in Photobit is used, the exposure/gain + * registers shouldn't be touched. The sensor may update them only rarely + * and if they're changed they may be incorrect until the sensor updates + * the registers next time. + * FIXME: shouldn't qc-driver.c ensure this function isnt called when adaptive is used? + */ + if (qc->settings.adaptive) return 0; + if ((r = pb0100_set_exposure(qc, exp))<0) goto fail; + pb0100_set_gains(qc, hue, sat, gain); +fail: return r; +} +/* }}} */ +/* {{{ [fold] pb0100_set_target: Set target brightness for sensor autoexposure, val=0..65535 */ +static int pb0100_set_target(struct quickcam *qc, unsigned int val) +{ + struct qc_sensor_data *sd = &qc->sensor_data; + unsigned int totalpixels, brightpixels, darkpixels; + int r; + + val >>= 8; /* val = 0..255 (0-50% of bright pixels) */ + if (val==sd->exposure) return 0; + sd->exposure = val; + + /* Number of pixels counted by the sensor when subsampling the pixels. + * Slightly larger than the real value to avoid oscillation */ + totalpixels = sd->width * sd->height; + totalpixels = totalpixels/(8*8) + totalpixels/(64*64); + + brightpixels = (totalpixels * val) >> 8; + darkpixels = totalpixels - brightpixels; + I2C_SETW_CHECK(PB_R21, brightpixels); /* R21 */ + I2C_SETW_CHECK(PB_R22, darkpixels); /* R22 */ +fail: return r; +} +/* }}} */ +/* {{{ [fold] pb0100_set_size: Set window size */ +/* Window location and size are controlled by R1, R2, R3 and R4. + * The default size is CIF (352x288) with to right at (4,12) + * and bottom left at (355, 299) + * + * We try to ensure that the captured area is in the center of + * the camera purely because that's nicer. It would be better + * if the PB0100 sensor supported capture scaling! + * + * We do it in on step otherwise size change may take more + * than one frame (like xawtv who tests 64x48 and uses 352x288) + * 3072 = 64x48, 16896 = 352x48, 101376 = 352x288. + */ +static int pb0100_set_size(struct quickcam *qc, unsigned int w, unsigned int h) +{ + static const unsigned int originx = 0; /* First visible pixel */ + static const unsigned int originy = 8; + static const unsigned int maxwidth = 360; /* Visible sensor size */ + static const unsigned int maxheight = 288; + struct qc_sensor_data *sd = &qc->sensor_data; + int x, y; + int r; + + sd->width = w; + sd->height = h; + if (sd->subsample) { + w *= 2; + h *= 2; + } + x = (maxwidth - w)/2; /* Center image by computing upper-left corner */ + y = (maxheight - h)/2; + x = (x + originx) & ~1; /* Must be even to align to the Bayer pattern */ + y = (y + originy) & ~1; + I2C_SETW_CHECK(PB_RSTART, y); /* PB_RSTART = 12 + y */ + I2C_SETW_CHECK(PB_CSTART, x); /* PB_CSTART = 4 + x */ + I2C_SETW_CHECK(PB_RWSIZE, h - 1); /* PB_RWSIZE = h - 1 */ + I2C_SETW_CHECK(PB_CWSIZE, w - 1); /* PB_CWSIZE = w - 1 */ + + if (qc->settings.adaptive) { + /* The automatic exposure counts need to be recomputed when size is changed */ + x = sd->exposure << 8; + sd->exposure = -1; + if ((r = pb0100_set_target(qc, x))<0) goto fail; + } + + r = qc_i2c_wait(qc); +fail: return r; +} +/* }}} */ +/* {{{ [fold] pb0100_start: Start grabbing */ +static int pb0100_start(struct quickcam *qc) +{ + int r; + I2C_SETW_CHECK(PB_CONTROL, BIT(5)|BIT(3)|BIT(1)); + r = qc_i2c_wait(qc); +fail: return r; +} +/* }}} */ +/* {{{ [fold] pb0100_stop: Stop grabbing */ +static int pb0100_stop(struct quickcam *qc) +{ + int r; + I2C_SETW_CHECK(PB_ABORTFRAME, 1); + if ((r = qc_i2c_wait(qc))<0) goto fail; + I2C_SETW_CHECK(PB_CONTROL, BIT(5)|BIT(3)); /* Set bit 1 to zero */ + r = qc_i2c_wait(qc); +fail: return r; +} +/* }}} */ + +/* {{{ [fold] struct qc_sensor qc_sensor_pb0100 */ +const struct qc_sensor qc_sensor_pb0100 = { + name: "PB-0100/0101", + manufacturer: "Photobit", + init: pb0100_init, + start: pb0100_start, + stop: pb0100_stop, + set_size: pb0100_set_size, + set_levels: pb0100_set_levels, + set_target: pb0100_set_target, + /* Exposure and gain control information */ + autoexposure: TRUE, + /* Information needed to access the sensor via I2C */ + reg23: 1, + i2c_addr: PB_ADDR, + /* Identification information used for auto-detection */ + id_reg: PB_IDENT, + id: 0x64, + length_id: 2, +}; +/* }}} */ + +/* End of file */ --- linux-2.6.28.orig/ubuntu/qc-usb/qc-hdcs.c +++ linux-2.6.28/ubuntu/qc-usb/qc-hdcs.c @@ -0,0 +1,734 @@ +/* Start of file */ + +/* {{{ [fold] Comments */ +/* + * qc-usb, linux V4L driver for the Logitech QuickCam USB camera family + * + * qc-hdcs.c - HDCS Sensor Implementation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 "quickcam.h" + +/* LSB bit of I2C or register address signifies write (0) or read (1) */ + +/* I2C Address */ +#define HDCS_ADDR (0x55<<1) + +/* {{{ [fold] I2C registers */ +/* I2C Registers common for both HDCS-1000/1100 and HDCS-1020 */ +#define HDCS_IDENT (0x00<<1) /* Identifications Register */ +#define HDCS_STATUS (0x01<<1) /* Status Register */ +#define HDCS_IMASK (0x02<<1) /* Interrupt Mask Register */ +#define HDCS_PCTRL (0x03<<1) /* Pad Control Register */ +#define HDCS_PDRV (0x04<<1) /* Pad Drive Control Register */ +#define HDCS_ICTRL (0x05<<1) /* Interface Control Register */ +#define HDCS_ITMG (0x06<<1) /* Interface Timing Register */ +#define HDCS_BFRAC (0x07<<1) /* Baud Fraction Register */ +#define HDCS_BRATE (0x08<<1) /* Baud Rate Register */ +#define HDCS_ADCCTRL (0x09<<1) /* ADC Control Register */ +#define HDCS_FWROW (0x0A<<1) /* First Window Row Register */ +#define HDCS_FWCOL (0x0B<<1) /* First Window Column Register */ +#define HDCS_LWROW (0x0C<<1) /* Last Window Row Register */ +#define HDCS_LWCOL (0x0D<<1) /* Last Window Column Register */ +#define HDCS_TCTRL (0x0E<<1) /* Timing Control Register */ +#define HDCS_ERECPGA (0x0F<<1) /* PGA Gain Register: Even Row, Even Column */ +#define HDCS_EROCPGA (0x10<<1) /* PGA Gain Register: Even Row, Odd Column */ +#define HDCS_ORECPGA (0x11<<1) /* PGA Gain Register: Odd Row, Even Column */ +#define HDCS_OROCPGA (0x12<<1) /* PGA Gain Register: Odd Row, Odd Column */ +#define HDCS_ROWEXPL (0x13<<1) /* Row Exposure Low Register */ +#define HDCS_ROWEXPH (0x14<<1) /* Row Exposure High Register */ + +/* I2C Registers only for HDCS-1000/1100 */ +#define HDCS00_SROWEXPL (0x15<<1) /* Sub-Row Exposure Low Register */ +#define HDCS00_SROWEXPH (0x16<<1) /* Sub-Row Exposure High Register */ +#define HDCS00_CONFIG (0x17<<1) /* Configuration Register */ +#define HDCS00_CONTROL (0x18<<1) /* Control Register */ + +/* I2C Registers only for HDCS-1020 */ +#define HDCS20_SROWEXP (0x15<<1) /* Sub-Row Exposure Register */ +#define HDCS20_ERROR (0x16<<1) /* Error Control Register */ +#define HDCS20_ITMG2 (0x17<<1) /* Interface Timing 2 Register */ +#define HDCS20_ICTRL2 (0x18<<1) /* Interface Control 2 Register */ +#define HDCS20_HBLANK (0x19<<1) /* Horizontal Blank Register */ +#define HDCS20_VBLANK (0x1A<<1) /* Vertical Blank Register */ +#define HDCS20_CONFIG (0x1B<<1) /* Configuration Register */ +#define HDCS20_CONTROL (0x1C<<1) /* Control Register */ +/* }}} */ + +#define IS_870(qc) (GET_PRODUCTID(qc)==0x870) +#define IS_1020(qc) ((qc)->sensor_data.sensor->flag != 0) +#define GET_CONTROL (IS_1020(qc) ? HDCS20_CONTROL : HDCS00_CONTROL) +#define GET_CONFIG (IS_1020(qc) ? HDCS20_CONFIG : HDCS00_CONFIG) + +#define I2C_SET_CHECK(reg,val) if ((r = qc_i2c_set(qc,(reg),(val)))<0) goto fail +#define STV_SET_CHECK(reg,val) if ((r = qc_stv_set(qc,(reg),(val)))<0) goto fail +#define STV_SETW_CHECK(reg,val) if ((r = qc_stv_setw(qc,(reg),(val)))<0) goto fail + +/* Enables experimental compressed mode, works with HDCS-1000/0x840, + mode derived from USB logs obtained from HDCS-1020/0x870 + (should give 640x480), not tested with HDCS-1020. + On HDCS-1000, gives 30 fps but data is in unknown format, + observed image width 163 bytes (how many pixels?). + Frame length appears to vary, typically 3300-4550 bytes. + (apparently quite simple, however). + Use this with DUMPDATA mode. */ +#define HDCS_COMPRESS 0 + +#if HDCS_COMPRESS +/* {{{ [fold] hdcs_compress_init(struct quickcam *qc, int flags) */ +static int hdcs_compress_init(struct quickcam *qc, int flags) +{ + int r; + + if (flags & 1) { + /************************************** Plugin camera **************************************/ + + STV_SET_CHECK(0x1440, 0x00); /* Turn on/off isochronous stream */ + // if ((r = qc_stv_getw(qc, 0xE00A)) != 0x0870) /* ProductId */ + // PDEBUG("Bad value 0x%02X in reg 0xE00A, should be 0x0870", r); + + STV_SET_CHECK(0x0423, 0x05); /* Unknown (sometimes 4, sometimes 5) */ + // Warning: I2C address 0xBA is invalid + // if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0) /* Identifications Register */ + // PDEBUG("error reading sensor reg HDCS_IDENT"); + // if ((r = qc_stv_get(qc, 0x0424)) != 0x0a) /* Successfully transmitted I2C commands */ + // PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x0a", r); + STV_SET_CHECK(0x0423, 0x04); /* Unknown (sometimes 4, sometimes 5) */ + + if ((r = qc_stv_get(qc, 0x1444)) != 0x10) /* ? */ + PDEBUG("Bad value 0x%02X in reg 0x1444, should be 0x10", r); + if ((r = qc_stv_get(qc, 0x1444)) != 0x10) /* ? */ + PDEBUG("Bad value 0x%02X in reg 0x1444, should be 0x10", r); + if ((r = qc_stv_get(qc, 0x1444)) != 0x10) /* ? */ + PDEBUG("Bad value 0x%02X in reg 0x1444, should be 0x10", r); + + STV_SET_CHECK(0x0423, 0x05); /* Unknown (sometimes 4, sometimes 5) */ + // Warning: I2C address 0x20 is invalid + // if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0) /* Identifications Register */ + // PDEBUG("error reading sensor reg HDCS_IDENT"); + // if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0) /* Identifications Register */ + // PDEBUG("error reading sensor reg HDCS_IDENT"); + // if ((r = qc_stv_get(qc, 0x0424)) != 0x0a) /* Successfully transmitted I2C commands */ + // PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x0a", r); + // Warning: I2C address 0x20 is invalid + // if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0) /* Identifications Register */ + // PDEBUG("error reading sensor reg HDCS_IDENT"); + // if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0) /* Identifications Register */ + // PDEBUG("error reading sensor reg HDCS_IDENT"); + // if ((r = qc_stv_get(qc, 0x0424)) != 0x0a) /* Successfully transmitted I2C commands */ + // PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x0a", r); + // Warning: I2C address 0x20 is invalid + // if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0) /* Identifications Register */ + // PDEBUG("error reading sensor reg HDCS_IDENT"); + // if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0) /* Identifications Register */ + // PDEBUG("error reading sensor reg HDCS_IDENT"); + // if ((r = qc_stv_get(qc, 0x0424)) != 0x0a) /* Successfully transmitted I2C commands */ + // PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x0a", r); + STV_SET_CHECK(0x0423, 0x04); /* Unknown (sometimes 4, sometimes 5) */ + STV_SET_CHECK(0x0423, 0x04); /* Unknown (sometimes 4, sometimes 5) */ + + // if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0) /* Identifications Register */ + // PDEBUG("error reading sensor reg HDCS_IDENT"); + // if ((r = qc_stv_get(qc, 0x0424)) != 0x02) /* Successfully transmitted I2C commands */ + // PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x02", r); + // if ((r = qc_stv_get(qc, 0x1410)) != 0x10) /* I2C area, first reg value */ + // PDEBUG("Bad value 0x%02X in reg 0x1410, should be 0x10", r); + + // if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0) /* Identifications Register */ + // PDEBUG("error reading sensor reg HDCS_IDENT"); + // if ((r = qc_stv_get(qc, 0x0424)) != 0x02) /* Successfully transmitted I2C commands */ + // PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x02", r); + // if ((r = qc_stv_get(qc, 0x1410)) != 0x10) /* I2C area, first reg value */ + // PDEBUG("Bad value 0x%02X in reg 0x1410, should be 0x10", r); + + STV_SET_CHECK(0x0423, 0x04); /* Unknown (sometimes 4, sometimes 5) */ + if ((r = qc_stv_get(qc, 0x0424)) != 0x02) /* Successfully transmitted I2C commands */ + PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x02", r); + STV_SET_CHECK(0x0423, 0x04); /* Unknown (sometimes 4, sometimes 5) */ + + // if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0) /* Identifications Register */ + // PDEBUG("error reading sensor reg HDCS_IDENT"); + // if ((r = qc_stv_get(qc, 0x0424)) != 0x02) /* Successfully transmitted I2C commands */ + // PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x02", r); + // if ((r = qc_stv_get(qc, 0x1410)) != 0x10) /* I2C area, first reg value */ + // PDEBUG("Bad value 0x%02X in reg 0x1410, should be 0x10", r); + + // if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0) /* Identifications Register */ + // PDEBUG("error reading sensor reg HDCS_IDENT"); + // if ((r = qc_stv_get(qc, 0x0424)) != 0x02) /* Successfully transmitted I2C commands */ + // PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x02", r); + // if ((r = qc_stv_get(qc, 0x1410)) != 0x10) /* I2C area, first reg value */ + // PDEBUG("Bad value 0x%02X in reg 0x1410, should be 0x10", r); + + STV_SET_CHECK(0x1500, 0x1D); /* ? */ + if ((r = qc_stv_get(qc, 0x1443)) != 0x00) /* Scan rate? */ + PDEBUG("Bad value 0x%02X in reg 0x1443, should be 0x00", r); + STV_SET_CHECK(0x1443, 0x01); /* Scan rate? */ + if ((r = qc_stv_get(qc, 0x1443)) != 0x01) /* Scan rate? */ + PDEBUG("Bad value 0x%02X in reg 0x1443, should be 0x01", r); + STV_SET_CHECK(0x1443, 0x00); /* Scan rate? */ + + I2C_SET_CHECK(HDCS_PCTRL, 0x63); /* Pad Control Register */ + I2C_SET_CHECK(HDCS_PDRV, 0x00); /* Pad Drive Control Register */ + I2C_SET_CHECK(GET_CONFIG, 0x08); /* Configuration Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + I2C_SET_CHECK(GET_CONTROL, 0x04); /* Control Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + I2C_SET_CHECK(GET_CONTROL, 0x00); /* Control Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1446, 0x00); /* ? */ + I2C_SET_CHECK(HDCS_PCTRL, 0x63); /* Pad Control Register */ + I2C_SET_CHECK(HDCS_PDRV, 0x00); /* Pad Drive Control Register */ + I2C_SET_CHECK(GET_CONFIG, 0x08); /* Configuration Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + if ((r = qc_stv_get(qc, 0x1445)) != 0x04) /* Turn LED on/off? */ + PDEBUG("Bad value 0x%02X in reg 0x1445, should be 0x04", r); + I2C_SET_CHECK(HDCS_ERECPGA, 0x3B); /* PGA Gain Register: Even Row, Even Column */ + I2C_SET_CHECK(HDCS_EROCPGA, 0x3B); /* PGA Gain Register: Even Row, Odd Column */ + I2C_SET_CHECK(HDCS_ORECPGA, 0x3B); /* PGA Gain Register: Odd Row, Even Column */ + I2C_SET_CHECK(HDCS_OROCPGA, 0x3B); /* PGA Gain Register: Odd Row, Odd Column */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1504, 0x07); /* ? */ + STV_SET_CHECK(0x1503, 0x45); /* ? */ + if ((r = qc_stv_get(qc, 0x1500)) != 0x1d) /* ? */ + PDEBUG("Bad value 0x%02X in reg 0x1500, should be 0x1d", r); + STV_SET_CHECK(0x1500, 0x1D); /* ? */ + // if ((r = qc_stv_getw(qc, 0xE00A)) != 0x0870) /* ProductId */ + // PDEBUG("Bad value 0x%02X in reg 0xE00A, should be 0x0870", r); + } + + if (flags & 2) { + /************************************** Start grabbing **************************************/ + + // if ((r = qc_stv_getw(qc, 0xE00A)) != 0x0870) /* ProductId */ + // PDEBUG("Bad value 0x%02X in reg 0xE00A, should be 0x0870", r); + STV_SET_CHECK(0x0423, 0x04); /* Unknown (sometimes 4, sometimes 5) */ + STV_SET_CHECK(0x1500, 0x1D); /* ? */ + I2C_SET_CHECK(HDCS_PCTRL, 0x63); /* Pad Control Register */ + I2C_SET_CHECK(HDCS_PDRV, 0x00); /* Pad Drive Control Register */ + I2C_SET_CHECK(GET_CONFIG, 0x08); /* Configuration Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x15C3, 0x02); /* Y-Control, 1: 288 lines, 2: 144 lines */ + STV_SETW_CHECK(0x15C1, 0x027B); /* Max. ISO packet size */ + I2C_SET_CHECK(HDCS_FWROW, 0x00); /* First Window Row Register */ + I2C_SET_CHECK(HDCS_FWCOL, 0x0B); /* First Window Column Register */ + I2C_SET_CHECK(HDCS_LWROW, 0x3D); /* Last Window Row Register */ + I2C_SET_CHECK(HDCS_LWCOL, 0x5A); /* Last Window Column Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1680, 0x00); /* X-Control, 0xa: 352 columns, 6: 176 columns */ + I2C_SET_CHECK(HDCS_TCTRL, IS_1020(qc) ? 0xCB : 0x6B); /* Timing Control Register */ + I2C_SET_CHECK(HDCS_ICTRL, 0x00); /* Interface Control Register */ + I2C_SET_CHECK(HDCS_ITMG, 0x16); /* Interface Timing Register */ + if (IS_1020(qc)) I2C_SET_CHECK(HDCS20_HBLANK, 0xD6); /* Horizontal Blank Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1446, 0x00); /* ? */ + if ((r = qc_stv_get(qc, 0x1446)) != 0x00) /* ? */ + PDEBUG("Bad value 0x%02X in reg 0x1446, should be 0x00", r); + STV_SET_CHECK(0x1446, 0x00); /* ? */ + I2C_SET_CHECK(HDCS_ROWEXPL, 0x7B); /* Row Exposure Low Register */ + I2C_SET_CHECK(HDCS_ROWEXPH, 0x00); /* Row Exposure High Register */ + if (IS_1020(qc)) { + I2C_SET_CHECK(HDCS20_SROWEXP, 0x01); /* Sub-Row Exposure Register */ + } else { + I2C_SET_CHECK(HDCS00_SROWEXPL, 0x01<<2); + I2C_SET_CHECK(HDCS00_SROWEXPH, 0x00); + } + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1501, 0xC2); /* ? */ + STV_SET_CHECK(0x1502, 0xB0); /* ? */ + I2C_SET_CHECK(HDCS_PCTRL, 0x63); /* Pad Control Register */ + I2C_SET_CHECK(HDCS_PDRV, 0x00); /* Pad Drive Control Register */ + I2C_SET_CHECK(GET_CONFIG, 0x08); /* Configuration Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + + /* Start isochronous streaming */ + I2C_SET_CHECK(GET_CONTROL, 0x04); /* Control Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1440, 0x01); /* Turn on/off isochronous stream */ + + if ((r = qc_stv_get(qc, 0x1445)) != 0x04) /* Turn LED on/off? */ + PDEBUG("Bad value 0x%02X in reg 0x1445, should be 0x04", r); + if ((r = qc_stv_get(qc, 0x1445)) != 0x04) /* Turn LED on/off? */ + PDEBUG("Bad value 0x%02X in reg 0x1445, should be 0x04", r); + if ((r = qc_stv_get(qc, 0x1445)) != 0x04) /* Turn LED on/off? */ + PDEBUG("Bad value 0x%02X in reg 0x1445, should be 0x04", r); + + /* Stop isochronous streaming */ + STV_SET_CHECK(0x1440, 0x00); /* Turn on/off isochronous stream */ + I2C_SET_CHECK(GET_CONTROL, 0x00); /* Control Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + + STV_SET_CHECK(0x0423, 0x04); /* Unknown (sometimes 4, sometimes 5) */ + STV_SET_CHECK(0x1500, 0x1D); /* ? */ + I2C_SET_CHECK(HDCS_PCTRL, 0x63); /* Pad Control Register */ + I2C_SET_CHECK(HDCS_PDRV, 0x00); /* Pad Drive Control Register */ + I2C_SET_CHECK(GET_CONFIG, 0x08); /* Configuration Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x15C3, 0x02); /* Y-Control, 1: 288 lines, 2: 144 lines */ + STV_SETW_CHECK(0x15C1, 0x027B); /* Max. ISO packet size */ + I2C_SET_CHECK(HDCS_FWROW, 0x00); /* First Window Row Register */ + I2C_SET_CHECK(HDCS_FWCOL, 0x0B); /* First Window Column Register */ + I2C_SET_CHECK(HDCS_LWROW, 0x3D); /* Last Window Row Register */ + I2C_SET_CHECK(HDCS_LWCOL, 0x5A); /* Last Window Column Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1680, 0x00); /* X-Control, 0xa: 352 columns, 6: 176 columns */ + I2C_SET_CHECK(HDCS_TCTRL, IS_1020(qc) ? 0xCB : 0x6B); /* Timing Control Register */ + I2C_SET_CHECK(HDCS_ICTRL, 0x00); /* Interface Control Register */ + I2C_SET_CHECK(HDCS_ITMG, 0x16); /* Interface Timing Register */ + if (IS_1020(qc)) I2C_SET_CHECK(HDCS20_HBLANK, 0xD6); /* Horizontal Blank Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1446, 0x00); /* ? */ + if ((r = qc_stv_get(qc, 0x1446)) != 0x00) /* ? */ + PDEBUG("Bad value 0x%02X in reg 0x1446, should be 0x00", r); + STV_SET_CHECK(0x1446, 0x00); /* ? */ + I2C_SET_CHECK(HDCS_ROWEXPL, 0x7B); /* Row Exposure Low Register */ + I2C_SET_CHECK(HDCS_ROWEXPH, 0x00); /* Row Exposure High Register */ + if (IS_1020(qc)) { + I2C_SET_CHECK(HDCS20_SROWEXP, 0x01); /* Sub-Row Exposure Register */ + } else { + I2C_SET_CHECK(HDCS00_SROWEXPL, 0x01<<2); + I2C_SET_CHECK(HDCS00_SROWEXPH, 0x00); + } + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1501, 0xC2); /* ? */ + STV_SET_CHECK(0x1502, 0xB0); /* ? */ + I2C_SET_CHECK(HDCS_PCTRL, 0x63); /* Pad Control Register */ + I2C_SET_CHECK(HDCS_PDRV, 0x00); /* Pad Drive Control Register */ + I2C_SET_CHECK(GET_CONFIG, 0x08); /* Configuration Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + + /* Start isochronous streaming */ + I2C_SET_CHECK(GET_CONTROL, 0x04); /* Control Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + if ((r = qc_stv_get(qc, 0x1445)) != 0x04) /* Turn LED on/off? */ + PDEBUG("Bad value 0x%02X in reg 0x1445, should be 0x04", r); + STV_SET_CHECK(0x1440, 0x01); /* Turn on/off isochronous stream */ + + /* Stop isochronous streaming */ + STV_SET_CHECK(0x1440, 0x00); /* Turn on/off isochronous stream */ + I2C_SET_CHECK(GET_CONTROL, 0x00); /* Control Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + + STV_SET_CHECK(0x0423, 0x04); /* Unknown (sometimes 4, sometimes 5) */ + STV_SET_CHECK(0x1500, 0x1D); /* ? */ + I2C_SET_CHECK(HDCS_PCTRL, 0x63); /* Pad Control Register */ + I2C_SET_CHECK(HDCS_PDRV, 0x00); /* Pad Drive Control Register */ + I2C_SET_CHECK(GET_CONFIG, 0x08); /* Configuration Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x15C3, 0x02); /* Y-Control, 1: 288 lines, 2: 144 lines */ + STV_SETW_CHECK(0x15C1, 0x0230); /* Max. ISO packet size */ + I2C_SET_CHECK(HDCS_FWROW, 0x00); /* First Window Row Register */ + I2C_SET_CHECK(HDCS_FWCOL, 0x07); /* First Window Column Register */ + I2C_SET_CHECK(HDCS_LWROW, 0x49); /* Last Window Row Register */ + I2C_SET_CHECK(HDCS_LWCOL, 0x5E); /* Last Window Column Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1680, 0x00); /* X-Control, 0xa: 352 columns, 6: 176 columns */ + I2C_SET_CHECK(HDCS_TCTRL, IS_1020(qc) ? 0xCE : 0x6E); /* Timing Control Register */ + I2C_SET_CHECK(HDCS_ICTRL, 0x00); /* Interface Control Register */ + I2C_SET_CHECK(HDCS_ITMG, 0x16); /* Interface Timing Register */ + if (IS_1020(qc)) I2C_SET_CHECK(HDCS20_HBLANK, 0xCF); /* Horizontal Blank Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1446, 0x00); /* ? */ + if ((r = qc_stv_get(qc, 0x1446)) != 0x00) /* ? */ + PDEBUG("Bad value 0x%02X in reg 0x1446, should be 0x00", r); + STV_SET_CHECK(0x1446, 0x00); /* ? */ + I2C_SET_CHECK(HDCS_ROWEXPL, 0x62); /* Row Exposure Low Register */ + I2C_SET_CHECK(HDCS_ROWEXPH, 0x00); /* Row Exposure High Register */ + if (IS_1020(qc)) { + I2C_SET_CHECK(HDCS20_SROWEXP, 0x1A); /* Sub-Row Exposure Register */ + } else { + I2C_SET_CHECK(HDCS00_SROWEXPL, 0x1A<<2); + I2C_SET_CHECK(HDCS00_SROWEXPH, 0x00); + } + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1501, 0xB6); /* ? */ + STV_SET_CHECK(0x1502, 0xA8); /* ? */ + I2C_SET_CHECK(HDCS_PCTRL, 0x63); /* Pad Control Register */ + I2C_SET_CHECK(HDCS_PDRV, 0x00); /* Pad Drive Control Register */ + I2C_SET_CHECK(GET_CONFIG, 0x08); /* Configuration Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + + /* Start isochronous streaming */ + I2C_SET_CHECK(GET_CONTROL, 0x04); /* Control Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1440, 0x01); /* Turn on/off isochronous stream */ + + if ((r = qc_stv_get(qc, 0x1445)) != 0x04) /* Turn LED on/off? */ + PDEBUG("Bad value 0x%02X in reg 0x1445, should be 0x04", r); + } + + return 0; +fail: return r; +} +/* }}} */ +#endif +/* {{{ [fold] hdcs_init: Initialise parameters (from Georg Acher's user module for hdcs sensor) */ +static int hdcs_init(struct quickcam *qc) +{ + struct qc_sensor_data *sd = &qc->sensor_data; + unsigned char control = GET_CONTROL; + unsigned char config = GET_CONFIG; + int r,tctrl,astrt,psmp; + + if (sd->compress) return -EINVAL; + sd->maxwidth = IS_1020(qc) ? 352 : 360; /* CIF */ + sd->maxheight = IS_1020(qc) ? 292 : 296; + if (sd->subsample) { + sd->maxwidth /= 2; /* QCIF */ + sd->maxheight /= 2; + } + if ((r = qc_i2c_break(qc))<0) goto fail; /* The following setting must go into same I2C packet */ +#if HDCS_COMPRESS +r = hdcs_compress_init(qc, 3); +qc_i2c_wait(qc); +qc_i2c_break(qc); +qc_stv_set(qc, 0x1440, 0x00); /* Turn on/off isochronous stream */ +qc_i2c_set(qc, GET_CONTROL, BIT(1)); /* Stop and enter sleep mode */ +qc_i2c_wait(qc); +if (r) PDEBUG("hdcs_compress_init(1) = %i", r); +return 0; +#endif + STV_SET_CHECK(STV_REG23, 0); + + /* Set the STV0602AA in STV0600 emulation mode */ + if (IS_870(qc)) STV_SET_CHECK(0x1446, 1); + + /* Reset the image sensor (keeping it to 1 is a problem) */ + I2C_SET_CHECK(control, 1); + if ((r = qc_i2c_wait(qc))<0) goto fail; + I2C_SET_CHECK(control, 0); + if ((r = qc_i2c_wait(qc))<0) goto fail; + + I2C_SET_CHECK(HDCS_STATUS, BIT(6)|BIT(5)|BIT(4)|BIT(3)|BIT(2)|BIT(1)); /* Clear status (writing 1 will clear the corresponding status bit) */ + + I2C_SET_CHECK(HDCS_IMASK, 0x00); /* Disable all interrupts */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + + STV_SET_CHECK(STV_REG00, 0x1D); + STV_SET_CHECK(STV_REG04, 0x07); + STV_SET_CHECK(STV_REG03, 0x95); + + STV_SET_CHECK(STV_REG23, 0); + + STV_SET_CHECK(STV_SCAN_RATE, 0x20); /* Larger -> slower */ + + STV_SETW_CHECK(STV_ISO_SIZE, 847); /* ISO-Size, 0x34F = 847 .. 0x284 = 644 */ + + /* Set mode */ + STV_SET_CHECK(STV_Y_CTRL, 0x01); /* 0x02: half, 0x01: full */ + STV_SET_CHECK(STV_X_CTRL, 0x0A); /* 0x06: half, 0x0A: full */ + + /* These are not good final values, which will be set in set_size */ + /* However, it looks like it's best to set some values at this point nevertheless */ + I2C_SET_CHECK(HDCS_FWROW, 0); /* Start at row 0 */ + I2C_SET_CHECK(HDCS_FWCOL, 0); /* Start at column 0 */ + I2C_SET_CHECK(HDCS_LWROW, 0x47); /* End at row 288 */ + I2C_SET_CHECK(HDCS_LWCOL, 0x57); /* End at column 352 */ + + /* 0x07 - 0x50 */ + astrt = 3; /* 0..3, doesn't seem to have any effect... hmm.. smaller is slower with subsampling */ + if (!IS_1020(qc)) { + /* HDCS-1000 (tctrl was 0x09, but caused some HDCS-1000 not to work) */ + /* Frame rate on HDCS-1000 0x46D:0x840 depending on PSMP: + * 4 = doesn't work at all + * 5 = 7.8 fps, + * 6 = 6.9 fps, + * 8 = 6.3 fps, + * 10 = 5.5 fps, + * 15 = 4.4 fps, + * 31 = 2.8 fps */ + /* Frame rate on HDCS-1000 0x46D:0x870 depending on PSMP: + * 15 = doesn't work at all + * 18 = doesn't work at all + * 19 = 7.3 fps + * 20 = 7.4 fps + * 21 = 7.4 fps + * 22 = 7.4 fps + * 24 = 6.3 fps + * 30 = 5.4 fps */ + psmp = IS_870(qc) ? 20 : 5; /* 4..31 (was 30, changed to 20) */ + tctrl = (astrt<<5) | psmp; + } else { + /* HDCS-1020 (tctrl was 0x7E, but causes slow frame rate on HDCS-1020) */ + /* Changed to 6 which should give 8.1 fps */ + psmp = 6; /* 4..31 (was 9, changed to 6 to improve fps */ + tctrl = (astrt<<6) | psmp; + } + I2C_SET_CHECK(HDCS_TCTRL, tctrl); /* Set PGA sample duration (was 0x7E for IS_870, but caused slow framerate with HDCS-1020) */ + + I2C_SET_CHECK(control, 0); /* FIXME:should not be anymore necessary (already done) */ + + I2C_SET_CHECK(HDCS_ROWEXPL, 0); + I2C_SET_CHECK(HDCS_ROWEXPH, 0); + if (IS_1020(qc)) { + I2C_SET_CHECK(HDCS20_SROWEXP, 0); + I2C_SET_CHECK(HDCS20_ERROR, BIT(0)|BIT(2)); /* Clear error conditions by writing 1 */ + } else { + I2C_SET_CHECK(HDCS00_SROWEXPL, 0); + I2C_SET_CHECK(HDCS00_SROWEXPH, 0); + } + if ((r = qc_i2c_wait(qc))<0) goto fail; + + STV_SET_CHECK(STV_REG01, 0xB5); + STV_SET_CHECK(STV_REG02, 0xA8); + + I2C_SET_CHECK(HDCS_PCTRL, BIT(6)|BIT(5)|BIT(1)|BIT(0)); + I2C_SET_CHECK(HDCS_PDRV, 0x00); + I2C_SET_CHECK(HDCS_ICTRL, (sd->subsample ? BIT(7) : 0) | BIT(5)); + I2C_SET_CHECK(HDCS_ITMG, BIT(4)|BIT(1)); + + /* CONFIG: Bit 3: continous frame capture, bit 2: stop when frame complete */ + I2C_SET_CHECK(config, (sd->subsample ? BIT(5) : 0) | BIT(3)); + I2C_SET_CHECK(HDCS_ADCCTRL, 10); /* ADC output resolution to 10 bits */ + if ((r = qc_i2c_wait(qc))<0) goto fail; +fail: return r; +} +/* }}} */ +/* {{{ [fold] hdcs_start: Start grabbing */ +static int hdcs_start(struct quickcam *qc) +{ + int r; +#if HDCS_COMPRESS +r = hdcs_compress_init(qc, 2); +qc_i2c_wait(qc); +if (r) PDEBUG("hdcs_compress_init(1) = %i", r); +return 0; +#endif + if ((r = qc_i2c_break(qc))<0) goto fail; + I2C_SET_CHECK(GET_CONTROL, BIT(2)); /* Run enable */ + if ((r = qc_i2c_break(qc))<0) goto fail; +fail: return r; +} +/* }}} */ +/* {{{ [fold] hdcs_stop: Stop grabbing */ +static int hdcs_stop(struct quickcam *qc) +{ + int r; + if ((r = qc_i2c_break(qc))<0) goto fail; + I2C_SET_CHECK(GET_CONTROL, BIT(1)); /* Stop and enter sleep mode */ + r = qc_i2c_wait(qc); +fail: return r; +} +/* }}} */ +/* {{{ [fold] hdcs_set_exposure: Set exposure time, val=0..65535 */ +static int hdcs_set_exposure(struct quickcam *qc, unsigned int val) +{ + struct qc_sensor_data *sd = &qc->sensor_data; + unsigned char control = GET_CONTROL; + unsigned int rowexp; /* rowexp,srowexp = 15 bits (0..32767) */ + unsigned int srowexp; /* sub-row exposure (smaller is brighter) */ + unsigned int max_srowexp; /* Maximum srowexp value + 1 */ + int r; + + /* Absolute black at srowexp=2672,width=360; 2616, width=352; 1896, width=256 for hdcs1000 */ + + if (val==sd->exposure) return 0; + sd->exposure = val; + val *= 16; /* 16 seems to be the smallest change that actually affects brightness */ + max_srowexp = sd->width*15/2 - 104 + 1; + srowexp = max_srowexp - (val % max_srowexp) - 1; + rowexp = val / max_srowexp; + if (qcdebug&QC_DEBUGCAMERA) PDEBUG("width=%i height=%i rowexp=%i srowexp=%i",sd->width,sd->height,rowexp,srowexp); + if ((r = qc_i2c_break(qc))<0) goto fail; /* The following setting must go into same I2C packet */ + I2C_SET_CHECK(control, 0); /* Stop grabbing */ + I2C_SET_CHECK(HDCS_ROWEXPL, rowexp & 0xFF); /* Number of rows to expose */ + I2C_SET_CHECK(HDCS_ROWEXPH, rowexp >> 8); + if (IS_1020(qc)) { + srowexp = 0; //FIXME:need formula to compute srowexp for HDCS1020! + srowexp >>= 2; /* Bits 0..1 are hardwired to 0 */ + I2C_SET_CHECK(HDCS20_SROWEXP, srowexp & 0xFF); /* Number of pixels to expose */ + } else { + I2C_SET_CHECK(HDCS00_SROWEXPL, srowexp & 0xFF); /* Number of pixels to expose */ + I2C_SET_CHECK(HDCS00_SROWEXPH, srowexp >> 8); + } + if (IS_1020(qc)) { + I2C_SET_CHECK(HDCS20_ERROR, BIT(0)); /* Reset exposure error flag */ + } else { + I2C_SET_CHECK(HDCS_STATUS, BIT(4)); /* Reset exposure error flag */ + } + I2C_SET_CHECK(control, BIT(2)); /* Restart grabbing */ + if ((r = qc_i2c_break(qc))<0) goto fail; +#if 0 + /* Warning: the code below will cause about 0.1 second delay and may cause lost frames */ + if (PARANOID) { + /* Check if the new exposure setting is valid */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + if (IS_1020(qc)) { + if ((r = qc_get_i2c(qc,qc->sensor_data.sensor, HDCS20_ERROR))<0) goto fail; + if (r & BIT(0)) PDEBUG("exposure error (1020)"); + } else { + if ((r = qc_get_i2c(qc,qc->sensor_data.sensor, HDCS_STATUS))<0) goto fail; + if (r & BIT(4)) PDEBUG("exposure error (1000)"); + } + } + if ((r = qc_i2c_wait(qc))<0) goto fail; +#endif + qc_frame_flush(qc); +fail: return (r<0) ? r : 0; +} +/* }}} */ +/* {{{ [fold] hdcs_set_gains: Set gains */ +static int hdcs_set_gains(struct quickcam *qc, unsigned int hue, unsigned int sat, unsigned int val) +{ + static const unsigned int min_gain = 8; + struct qc_sensor_data *sd = &qc->sensor_data; + unsigned int rgain, bgain, ggain; + int r; + qc_hsv2rgb(hue, sat, val, &rgain, &bgain, &ggain); + rgain >>= 8; /* After this the values are 0..255 */ + ggain >>= 8; + bgain >>= 8; + rgain = MAX(rgain, min_gain); /* Do not allow very small values, they cause bad (low-contrast) image */ + ggain = MAX(ggain, min_gain); + bgain = MAX(bgain, min_gain); + if (rgain==sd->rgain && ggain==sd->ggain && bgain==sd->bgain) return 0; + sd->rgain = rgain; + sd->ggain = ggain; + sd->bgain = bgain; + if (rgain > 127) rgain = rgain/2 | BIT(7); /* Bit 7 doubles the programmed values */ + if (ggain > 127) ggain = ggain/2 | BIT(7); /* Double programmed value if necessary */ + if (bgain > 127) bgain = bgain/2 | BIT(7); + if ((r = qc_i2c_break(qc))<0) goto fail; + I2C_SET_CHECK(HDCS_ERECPGA, ggain); + I2C_SET_CHECK(HDCS_EROCPGA, rgain); + I2C_SET_CHECK(HDCS_ORECPGA, bgain); + I2C_SET_CHECK(HDCS_OROCPGA, ggain); +fail: return r; +} +/* }}} */ +/* {{{ [fold] hdcs_set_levels() */ +static int hdcs_set_levels(struct quickcam *qc, unsigned int exp, unsigned int gain, unsigned int hue, unsigned int sat) +{ + int r = 0; +//#if !HDCS_COMPRESS + if ((r = hdcs_set_exposure(qc, gain))<0) goto fail; +//#endif + hdcs_set_gains(qc, hue, sat, exp); +fail: return r; +} +/* }}} */ +/* {{{ [fold] hdcs_set_size: Sets the size of the capture window */ +/* + * Sets the size (scaling) of the capture window. + * If subsample could return the image size we use subsample. + */ +static int hdcs_set_size(struct quickcam *qc, unsigned int width, unsigned int height) +{ + /* The datasheet doesn't seem to say this, but HDCS-1000 + * has visible windows size of 360x296 pixels, the first upper-left + * visible pixel is at 8,8. + * From Andrey's test image: looks like HDCS-1020 upper-left + * visible pixel is at 24,8 (y maybe even smaller?) and lower-right + * visible pixel at 375,299 (x maybe even larger?) + */ + unsigned int originx = IS_1020(qc) ? 24 : 8; /* First visible pixel */ + unsigned int maxwidth = IS_1020(qc) ? 352 : 360; /* Visible sensor size */ + unsigned int originy = 8; + unsigned int maxheight = IS_1020(qc) ? 292 : 296; + + unsigned char control = GET_CONTROL; + struct qc_sensor_data *sd = &qc->sensor_data; + int r; + unsigned int x, y; + +#if HDCS_COMPRESS + return 0; +#endif + if (sd->subsample) { + width *= 2; + height *= 2; + width = (width + 3)/4*4; /* Width must be multiple of 4 */ + height = (height + 3)/4*4; /* Height must be multiple of 4 */ + sd->width = width / 2; + sd->height = height / 2; /* The image sent will be subsampled by 2 */ + } else { + sd->width = width = (width + 3)/4*4; /* Width must be multiple of 4 */ + sd->height = height = (height + 3)/4*4; /* Height must be multiple of 4 */ + } + x = (maxwidth - width)/2; /* Center image by computing upper-left corner */ + y = (maxheight - height)/2; + width /= 4; + height /= 4; + x = (x + originx)/4; /* Must be multiple of 4 (low bits wired to 0) */ + y = (y + originy)/4; + + if ((r = qc_i2c_break(qc))<0) goto fail; + I2C_SET_CHECK(control, 0); /* Stop grabbing */ + I2C_SET_CHECK(HDCS_FWROW, y); + I2C_SET_CHECK(HDCS_FWCOL, x); + I2C_SET_CHECK(HDCS_LWROW, y+height-1); + I2C_SET_CHECK(HDCS_LWCOL, x+width-1); + I2C_SET_CHECK(control, BIT(2)); /* Restart grabbing */ + + /* The exposure timings need to be recomputed when size is changed */ + x = sd->exposure; + sd->exposure = -1; + if ((r = hdcs_set_exposure(qc, x))<0) goto fail; +fail: return r; +} +/* }}} */ + +/* {{{ [fold] struct qc_sensor qc_sensor_hdcs1000 */ +const struct qc_sensor qc_sensor_hdcs1000 = { + name: "HDCS-1000/1100", + manufacturer: "Hewlett Packard", + init: hdcs_init, + start: hdcs_start, + stop: hdcs_stop, + set_size: hdcs_set_size, + set_levels: hdcs_set_levels, + /* Exposure and gain control information */ + autoexposure: FALSE, + adapt_gainlow: 20, + adapt_gainhigh: 20000, + /* Information needed to access the sensor via I2C */ + reg23: 0, + i2c_addr: HDCS_ADDR, + /* Identification information used for auto-detection */ + id_reg: HDCS_IDENT | 1, + id: 0x08, + length_id: 1, + flag: 0, +}; +/* }}} */ +/* {{{ [fold] struct qc_sensor qc_sensor_hdcs1020 */ +const struct qc_sensor qc_sensor_hdcs1020 = { + name: "HDCS-1020", + manufacturer: "Agilent Technologies", + init: hdcs_init, + start: hdcs_start, + stop: hdcs_stop, + set_size: hdcs_set_size, + set_levels: hdcs_set_levels, + /* Exposure and gain control information */ + autoexposure: FALSE, + adapt_gainlow: 20, + adapt_gainhigh: 20000, + /* Information needed to access the sensor via I2C */ + reg23: 0, + i2c_addr: HDCS_ADDR, + /* Identification information used for auto-detection */ + id_reg: HDCS_IDENT | 1, + id: 0x10, + length_id: 1, + flag: 1, +}; +/* }}} */ + +/* End of file */ --- linux-2.6.28.orig/ubuntu/qc-usb/qc-mjpeg.c +++ linux-2.6.28/ubuntu/qc-usb/qc-mjpeg.c @@ -0,0 +1,1936 @@ +/* Start of file */ + +/* {{{ [fold] Comments */ +/* + * MJPEG decompression routines are from mpeg2dec, + * Copyright (C) 1999-2001 Aaron Holtzman + * Modified by Tuukka Toivonen and Jochen Hoenicke. + * + * Portions of this code are from the MPEG software simulation group + * idct implementation. This code will be replaced with a new + * implementation soon. + * + * The MJPEG routines are from mpeg2dec, a free MPEG-2 video stream decoder. + * + * mpeg2dec is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * mpeg2dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You 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 "quickcam.h" + +#ifdef __KERNEL__ /* show.c will include this file directly into compilation for userspace */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#include +#else +#include +#endif +#endif /* __KERNEL__ */ + +#if COMPRESS +/* {{{ [fold] **** qc_mjpeg_yuv2rgb: MJPEG decoding: YUV to RGB conversion routines *************** */ + +/* {{{ [fold] Macros */ +#define MODE_RGB 1 +#define MODE_BGR 2 + +#define RGB(i) \ + U = pu[i]; \ + V = pv[i]; \ + r = md->table_rV[V]; \ + g = (void *)(((u8 *)md->table_gU[U]) + md->table_gV[V]);\ + b = md->table_bU[U]; + +#define DST1(i) \ + Y = py_1[2*i]; \ + dst_1[2*i] = r[Y] + g[Y] + b[Y]; \ + Y = py_1[2*i+1]; \ + dst_1[2*i+1] = r[Y] + g[Y] + b[Y]; + +#define DST2(i) \ + Y = py_2[2*i]; \ + dst_2[2*i] = r[Y] + g[Y] + b[Y]; \ + Y = py_2[2*i+1]; \ + dst_2[2*i+1] = r[Y] + g[Y] + b[Y]; + +#define DST1RGB(i) \ + Y = py_1[2*i]; \ + dst_1[6*i] = r[Y]; dst_1[6*i+1] = g[Y]; dst_1[6*i+2] = b[Y]; \ + Y = py_1[2*i+1]; \ + dst_1[6*i+3] = r[Y]; dst_1[6*i+4] = g[Y]; dst_1[6*i+5] = b[Y]; + +#define DST2RGB(i) \ + Y = py_2[2*i]; \ + dst_2[6*i] = r[Y]; dst_2[6*i+1] = g[Y]; dst_2[6*i+2] = b[Y]; \ + Y = py_2[2*i+1]; \ + dst_2[6*i+3] = r[Y]; dst_2[6*i+4] = g[Y]; dst_2[6*i+5] = b[Y]; + +#define DST1BGR(i) \ + Y = py_1[2*i]; \ + dst_1[6*i] = b[Y]; dst_1[6*i+1] = g[Y]; dst_1[6*i+2] = r[Y]; \ + Y = py_1[2*i+1]; \ + dst_1[6*i+3] = b[Y]; dst_1[6*i+4] = g[Y]; dst_1[6*i+5] = r[Y]; + +#define DST2BGR(i) \ + Y = py_2[2*i]; \ + dst_2[6*i] = b[Y]; dst_2[6*i+1] = g[Y]; dst_2[6*i+2] = r[Y]; \ + Y = py_2[2*i+1]; \ + dst_2[6*i+3] = b[Y]; dst_2[6*i+4] = g[Y]; dst_2[6*i+5] = r[Y]; +/* }}} */ + +/* {{{ [fold] qc_mjpeg_yuv2rgb_32() */ +static void qc_mjpeg_yuv2rgb_32(struct qc_mjpeg_data *md, u8 *py_1, u8 *py_2, u8 *pu, u8 *pv, + void *_dst_1, void *_dst_2, int width) +{ + int U, V, Y; + u32 *r, *g, *b; + u32 *dst_1, *dst_2; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb_32(md=%p, py_1=%p, py_2=%p, pu=%p, pv=%p, _dst_1=%p, _dst_2=%p, width=%i",md,py_1,py_2,pu,pv,_dst_1,_dst_2,width); + width >>= 3; + dst_1 = _dst_1; + dst_2 = _dst_2; + + do { + RGB(0); + DST1(0); + DST2(0); + + RGB(1); + DST2(1); + DST1(1); + + RGB(2); + DST1(2); + DST2(2); + + RGB(3); + DST2(3); + DST1(3); + + pu += 4; + pv += 4; + py_1 += 8; + py_2 += 8; + dst_1 += 8; + dst_2 += 8; + } while (--width); + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb_32() done"); +} +/* }}} */ +/* {{{ [fold] qc_mjpeg_yuv2rgb_24rgb() */ +/* This is very near from the yuv2rgb_32 code */ +static void qc_mjpeg_yuv2rgb_24rgb(struct qc_mjpeg_data *md, u8 *py_1, u8 *py_2, u8 *pu, u8 *pv, + void *_dst_1, void *_dst_2, int width) +{ + int U, V, Y; + u8 *r, *g, *b; + u8 *dst_1, *dst_2; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb_24rgb(md=%p, py_1=%p, py_2=%p, pu=%p, pv=%p, _dst_1=%p, _dst_2=%p, width=%i",md,py_1,py_2,pu,pv,_dst_1,_dst_2,width); + + width >>= 3; + dst_1 = _dst_1; + dst_2 = _dst_2; + + do { + RGB(0); + DST1RGB(0); + DST2RGB(0); + + RGB(1); + DST2RGB(1); + DST1RGB(1); + + RGB(2); + DST1RGB(2); + DST2RGB(2); + + RGB(3); + DST2RGB(3); + DST1RGB(3); + + pu += 4; + pv += 4; + py_1 += 8; + py_2 += 8; + dst_1 += 24; + dst_2 += 24; + } while (--width); + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb_24rgb() done"); +} +/* }}} */ +/* {{{ [fold] qc_mjpeg_yuv2rgb_24bgr() */ +/* only trivial mods from yuv2rgb_24rgb */ +static void qc_mjpeg_yuv2rgb_24bgr(struct qc_mjpeg_data *md, u8 *py_1, u8 *py_2, u8 *pu, u8 *pv, + void *_dst_1, void *_dst_2, int width) +{ + int U, V, Y; + u8 *r, *g, *b; + u8 *dst_1, *dst_2; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb_24bgr(md=%p, py_1=%p, py_2=%p, pu=%p, pv=%p, _dst_1=%p, _dst_2=%p, width=%i",md,py_1,py_2,pu,pv,_dst_1,_dst_2,width); + width >>= 3; + dst_1 = _dst_1; + dst_2 = _dst_2; + + do { + RGB(0); + DST1BGR(0); + DST2BGR(0); + + RGB(1); + DST2BGR(1); + DST1BGR(1); + + RGB(2); + DST1BGR(2); + DST2BGR(2); + + RGB(3); + DST2BGR(3); + DST1BGR(3); + + pu += 4; + pv += 4; + py_1 += 8; + py_2 += 8; + dst_1 += 24; + dst_2 += 24; + } while (--width); + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb_24bgr() done"); +} +/* }}} */ +/* {{{ [fold] qc_mjpeg_yuv2rgb_16() */ +/* This is exactly the same code as yuv2rgb_32 except for the types of */ +/* r, g, b, dst_1, dst_2 */ +static void qc_mjpeg_yuv2rgb_16(struct qc_mjpeg_data *md, u8 *py_1, u8 *py_2, u8 *pu, u8 *pv, + void *_dst_1, void *_dst_2, int width) +{ + int U, V, Y; + u16 *r, *g, *b; + u16 *dst_1, *dst_2; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb_16(md=%p, py_1=%p, py_2=%p, pu=%p, pv=%p, _dst_1=%p, _dst_2=%p, width=%i",md,py_1,py_2,pu,pv,_dst_1,_dst_2,width); + width >>= 3; + dst_1 = _dst_1; + dst_2 = _dst_2; + + do { + RGB(0); + DST1(0); + DST2(0); + + RGB(1); + DST2(1); + DST1(1); + + RGB(2); + DST1(2); + DST2(2); + + RGB(3); + DST2(3); + DST1(3); + + pu += 4; + pv += 4; + py_1 += 8; + py_2 += 8; + dst_1 += 8; + dst_2 += 8; + } while (--width); + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb_16() done"); +} +/* }}} */ +/* {{{ [fold] qc_mjpeg_yuv2rgb() */ +/* Convert YUV image to RGB */ +static void qc_mjpeg_yuv2rgb(struct qc_mjpeg_data *md, void *dst, u8 *py, u8 *pu, u8 *pv, + int width, int height, int rgb_stride, int y_stride, int uv_stride) +{ + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb(md=%p, dst=%p, py=%p, pu=%p, pv=%p, width=%i, height=%i, rgb_stride=%i, y_stride=%i, uv_stride=%i",md,dst,py,pu,pv,width,height,rgb_stride,y_stride,uv_stride); + height >>= 1; + do { + md->yuv2rgb_func(md, py, py + y_stride, pu, pv, dst, ((u8 *)dst) + rgb_stride, width); + py += 2 * y_stride; + pu += uv_stride; + pv += uv_stride; + dst = ((u8 *)dst) + 2 * rgb_stride; + } while (--height); + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb() done"); +} +/* }}} */ + +static const u32 matrix_coefficients = 6; +static const s32 Inverse_Table_6_9[8][4] = { + { 117504, 138453, 13954, 34903 }, /* 0: no sequence_display_extension */ + { 117504, 138453, 13954, 34903 }, /* 1: ITU-R Rec. 709 (1990) */ + { 104597, 132201, 25675, 53279 }, /* 2: unspecified */ + { 104597, 132201, 25675, 53279 }, /* 3: reserved */ + { 104448, 132798, 24759, 53109 }, /* 4: FCC */ + { 104597, 132201, 25675, 53279 }, /* 5: ITU-R Rec. 624-4 System B, G */ + { 104597, 132201, 25675, 53279 }, /* 6: SMPTE 170M */ + { 117579, 136230, 16907, 35559 } /* 7: SMPTE 240M (1987) */ +}; + +/* {{{ [fold] div_round(int dividend, int divisor) */ +static int div_round(int dividend, int divisor) +{ + if (dividend > 0) + return (dividend + (divisor>>1)) / divisor; + else + return -((-dividend + (divisor>>1)) / divisor); +} +/* }}} */ +/* {{{ [fold] qc_mjpeg_yuv2rgb_init(struct qc_mjpeg_data *md, int bpp, int mode) */ +/* Initialization of yuv2rgb routines. Return error code if failure */ +static inline int qc_mjpeg_yuv2rgb_init(struct qc_mjpeg_data *md, int bpp, int mode) +{ + static const int table_Y_size = 1024; + u8 *table_Y; + int i, ret = -ENOMEM; + int entry_size = 0; + void *table_r = NULL, *table_g = NULL, *table_b = NULL; + int crv = Inverse_Table_6_9[matrix_coefficients][0]; + int cbu = Inverse_Table_6_9[matrix_coefficients][1]; + int cgu = -Inverse_Table_6_9[matrix_coefficients][2]; + int cgv = -Inverse_Table_6_9[matrix_coefficients][3]; + u32 *table_32; + u16 *table_16; + u8 *table_8; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb_init(md=%p, bpp=%i, mode=%i)",md,bpp,mode); + table_Y = kmalloc(table_Y_size,GFP_KERNEL); /* Allocate with kmalloc(), it might not fit into stack */ + if (table_Y==NULL) return -ENOMEM; + + for (i=0; i<1024; i++) { + int j; + j = (76309 * (i - 384 - 16) + 32768) >> 16; + j = (j < 0) ? 0 : ((j > 255) ? 255 : j); + table_Y[i] = j; + } + + switch (bpp) { + case 32: + md->yuv2rgb_func = qc_mjpeg_yuv2rgb_32; + table_32 = md->table = kmalloc((197 + 2*682 + 256 + 132) * sizeof(u32), GFP_KERNEL); /* 0..1948 x 4 */ + if (!md->table) goto fail; + entry_size = sizeof(u32); + table_r = table_32 + 197; /* R: -197..1751 */ + table_b = table_32 + 197 + 685; /* B: -882..1066 */ + table_g = table_32 + 197 + 2*682; /* G: -1561..387 */ + for (i=-197; i<256+197; i++) /* Ri = -197...452 */ + ((u32 *) table_r)[i] = table_Y[i+384] << ((mode==MODE_RGB) ? 16 : 0); + for (i=-132; i<256+132; i++) /* Gi = -132...387 */ + ((u32 *) table_g)[i] = table_Y[i+384] << 8; + for (i=-232; i<256+232; i++) /* Bi = -232...487 */ + ((u32 *) table_b)[i] = table_Y[i+384] << ((mode==MODE_RGB) ? 0 : 16); + break; + case 24: + md->yuv2rgb_func = (mode==MODE_RGB) ? qc_mjpeg_yuv2rgb_24rgb : qc_mjpeg_yuv2rgb_24bgr; + table_8 = md->table = kmalloc((256 + 2*232) * sizeof(u8), GFP_KERNEL); /* 0..719 x 1 */ + if (!md->table) goto fail; + entry_size = sizeof(u8); + table_r = table_g = table_b = table_8 + 232; /* -232..487 */ + for (i=-232; i<256+232; i++) /* i = -232..487 */ + ((u8 *)table_b)[i] = table_Y[i+384]; + break; + case 15: + case 16: + md->yuv2rgb_func = qc_mjpeg_yuv2rgb_16; + table_16 = md->table = kmalloc((197 + 2*682 + 256 + 132) * sizeof(u16), GFP_KERNEL); /* 0..1948 x 2 */ + if (!md->table) goto fail; + entry_size = sizeof(u16); + table_r = table_16 + 197; /* R: -197..1751 */ + table_b = table_16 + 197 + 685; /* B: -882..1066 */ + table_g = table_16 + 197 + 2*682; /* G: -1561..387 */ + for (i=-197; i<256+197; i++) { /* Ri = -197..452 */ + int j = table_Y[i+384] >> 3; + if (mode == MODE_RGB) j <<= ((bpp==16) ? 11 : 10); + ((u16 *)table_r)[i] = j; + } + for (i=-132; i<256+132; i++) { /* Gi = -132..387 */ + int j = table_Y[i+384] >> ((bpp==16) ? 2 : 3); + ((u16 *)table_g)[i] = j << 5; + } + for (i=-232; i<256+232; i++) { /* Bi = -232..487 */ + int j = table_Y[i+384] >> 3; + if (mode == MODE_BGR) j <<= ((bpp==16) ? 11 : 10); + ((u16 *)table_b)[i] = j; + } + break; + default: + PDEBUG("%i bpp not supported by yuv2rgb", bpp); + ret = -EINVAL; + goto fail; + } + for (i=0; i<256; i++) { + md->table_rV[i] = (((u8 *)table_r) + entry_size * div_round(crv * (i-128), 76309)); + md->table_gU[i] = (((u8 *)table_g) + entry_size * div_round(cgu * (i-128), 76309)); + md->table_gV[i] = entry_size * div_round(cgv * (i-128), 76309); + md->table_bU[i] = (((u8 *)table_b) + entry_size * div_round(cbu * (i-128), 76309)); + } + ret = 0; +fail: if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb_init()=%i done", ret); + if (PARANOID) memset(table_Y, POISON_VAL, table_Y_size); + kfree(table_Y); + return ret; +} +/* }}} */ +/* {{{ [fold] qc_mjpeg_yuv2rgb_exit(struct qc_mjpeg_data *md) */ +static inline void qc_mjpeg_yuv2rgb_exit(struct qc_mjpeg_data *md) +{ + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb_exit(md=%p)",md); + kfree(md->table); + POISON(md->table); + POISON(md->yuv2rgb_func); + POISON(md->table_rV); + POISON(md->table_gU); + POISON(md->table_bU); + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb_exit() done"); +} +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** qc_mjpeg_idct: MJPEG decoding: Inverse DCT routines ************************* */ +/**********************************************************/ +/* inverse two dimensional DCT, Chen-Wang algorithm */ +/* (cf. IEEE ASSP-32, pp. 803-816, Aug. 1984) */ +/* 32-bit integer arithmetic (8 bit coefficients) */ +/* 11 mults, 29 adds per DCT */ +/* sE, 18.8.91 */ +/**********************************************************/ +/* coefficients extended to 12 bit for IEEE1180-1990 */ +/* compliance sE, 2.1.94 */ +/**********************************************************/ + +/* this code assumes >> to be a two's-complement arithmetic */ +/* right shift: (-2)>>1 == -1 , (-3)>>1 == -2 */ + +#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */ +#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */ +#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */ +#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */ +#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */ +#define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */ + +/* {{{ [fold] qc_mjpeg_idct_row(s16 *block) */ +/* row (horizontal) IDCT + * + * 7 pi 1 + * dst[k] = sum c[l] * src[l] * cos ( -- * ( k + - ) * l ) + * l=0 8 2 + * + * where: c[0] = 128 + * c[1..7] = 128*sqrt (2) + */ +static void inline qc_mjpeg_idct_row(s16 *block) +{ + int x0, x1, x2, x3, x4, x5, x6, x7, x8; + + x1 = block[4] << 11; + x2 = block[6]; + x3 = block[2]; + x4 = block[1]; + x5 = block[7]; + x6 = block[5]; + x7 = block[3]; + + /* shortcut */ + if (! (x1 | x2 | x3 | x4 | x5 | x6 | x7)) { + block[0] = block[1] = block[2] = block[3] = block[4] = + block[5] = block[6] = block[7] = block[0]<<3; + return; + } + + x0 = (block[0] << 11) + 128; /* for proper rounding in the fourth stage */ + + /* first stage */ + x8 = W7 * (x4 + x5); + x4 = x8 + (W1 - W7) * x4; + x5 = x8 - (W1 + W7) * x5; + x8 = W3 * (x6 + x7); + x6 = x8 - (W3 - W5) * x6; + x7 = x8 - (W3 + W5) * x7; + + /* second stage */ + x8 = x0 + x1; + x0 -= x1; + x1 = W6 * (x3 + x2); + x2 = x1 - (W2 + W6) * x2; + x3 = x1 + (W2 - W6) * x3; + x1 = x4 + x6; + x4 -= x6; + x6 = x5 + x7; + x5 -= x7; + + /* third stage */ + x7 = x8 + x3; + x8 -= x3; + x3 = x0 + x2; + x0 -= x2; + x2 = (181 * (x4 + x5) + 128) >> 8; + x4 = (181 * (x4 - x5) + 128) >> 8; + + /* fourth stage */ + block[0] = (x7 + x1) >> 8; + block[1] = (x3 + x2) >> 8; + block[2] = (x0 + x4) >> 8; + block[3] = (x8 + x6) >> 8; + block[4] = (x8 - x6) >> 8; + block[5] = (x0 - x4) >> 8; + block[6] = (x3 - x2) >> 8; + block[7] = (x7 - x1) >> 8; +} +/* }}} */ +/* {{{ [fold] qc_mjpeg_idct_col(s16 *block) */ +/* column (vertical) IDCT + * + * 7 pi 1 + * dst[8*k] = sum c[l] * src[8*l] * cos ( -- * ( k + - ) * l ) + * l=0 8 2 + * + * where: c[0] = 1/1024 + * c[1..7] = (1/1024)*sqrt (2) + */ +static void inline qc_mjpeg_idct_col(s16 *block) +{ + int x0, x1, x2, x3, x4, x5, x6, x7, x8; + + /* shortcut */ + x1 = block [8*4] << 8; + x2 = block [8*6]; + x3 = block [8*2]; + x4 = block [8*1]; + x5 = block [8*7]; + x6 = block [8*5]; + x7 = block [8*3]; +#if 0 + if (! (x1 | x2 | x3 | x4 | x5 | x6 | x7 )) { + block[8*0] = block[8*1] = block[8*2] = block[8*3] = block[8*4] = + block[8*5] = block[8*6] = block[8*7] = (block[8*0] + 32) >> 6; + return; + } +#endif + x0 = (block[8*0] << 8) + 8192; + + /* first stage */ + x8 = W7 * (x4 + x5) + 4; + x4 = (x8 + (W1 - W7) * x4) >> 3; + x5 = (x8 - (W1 + W7) * x5) >> 3; + x8 = W3 * (x6 + x7) + 4; + x6 = (x8 - (W3 - W5) * x6) >> 3; + x7 = (x8 - (W3 + W5) * x7) >> 3; + + /* second stage */ + x8 = x0 + x1; + x0 -= x1; + x1 = W6 * (x3 + x2) + 4; + x2 = (x1 - (W2 + W6) * x2) >> 3; + x3 = (x1 + (W2 - W6) * x3) >> 3; + x1 = x4 + x6; + x4 -= x6; + x6 = x5 + x7; + x5 -= x7; + + /* third stage */ + x7 = x8 + x3; + x8 -= x3; + x3 = x0 + x2; + x0 -= x2; + x2 = (181 * (x4 + x5) + 128) >> 8; + x4 = (181 * (x4 - x5) + 128) >> 8; + + /* fourth stage */ + block[8*0] = (x7 + x1) >> 14; + block[8*1] = (x3 + x2) >> 14; + block[8*2] = (x0 + x4) >> 14; + block[8*3] = (x8 + x6) >> 14; + block[8*4] = (x8 - x6) >> 14; + block[8*5] = (x0 - x4) >> 14; + block[8*6] = (x3 - x2) >> 14; + block[8*7] = (x7 - x1) >> 14; +} +/* }}} */ +/* {{{ [fold] qc_mjpeg_idct(s16 *block, u8 *dest, int stride) */ +/* Inverse discrete cosine transform block, store result to dest */ +static void qc_mjpeg_idct(s16 *block, u8 *dest, int stride) +{ + int i; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_idct(block=%p,dest=%p,stride=%i)",block,dest,stride); + for (i=0; i<8; i++) qc_mjpeg_idct_row(block + 8*i); + for (i=0; i<8; i++) qc_mjpeg_idct_col(block + i); + i = 8; + do { + /* The original code used lookup-tables instead of explicit + * comparisons (as CLIP is doing here). However, sometimes + * the values pointed outside the LUT which caused problems + * in the kernel driver. Thus, the LUTs are removed here. */ + dest[0] = CLIP(block[0],0,255); + dest[1] = CLIP(block[1],0,255); + dest[2] = CLIP(block[2],0,255); + dest[3] = CLIP(block[3],0,255); + dest[4] = CLIP(block[4],0,255); + dest[5] = CLIP(block[5],0,255); + dest[6] = CLIP(block[6],0,255); + dest[7] = CLIP(block[7],0,255); + dest += stride; + block += 8; + } while (--i); +} +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** MJPEG decoding: bitstream processing (structures and macros) * */ +/* the idea is taken from zlib, but the bits are ordered the other way, so + * I modified the code. + * Variables: + * p points to next unread byte in stream. + * k number of bits read but not processed. + * b contains the read but not processed bits in the k most significant bits. + */ +struct bitstream { + u32 b; + u8 *p; + u8 *end; + int k; +}; + +#define GETWORD(p) ((p)[0] << 8 | (p)[1]) +#define NEEDBITS(b,k,p) \ + do { \ + if ((k) > 0) { \ + (b) |= GETWORD(p) << (k); \ + (p) += 2; \ + (k) -= 16; \ + } \ + } while(0) +#define DUMPBITS(b,k,j) do { (k) += (j); (b) <<= (j); } while (0) +#define BITVALUE(b,j) ((b)>>(32-(j))) +/* }}} */ +/* {{{ [fold] **** qc_mjpeg_lvc: MJPEG decoding: variable length code decoding **************** */ + +/* {{{ [fold] u8 shiftTables[18][64] */ +static const u8 shiftTables[18][64] = { + {2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, + {2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 }, + {2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 }, + {2,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 }, + {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 }, + {2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, + 3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 }, + {2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 }, + {2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 }, + {2,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6 }, + {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 }, + {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 }, + {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 }, + {2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, + 3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 }, + {2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 }, + {2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 }, + {2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 }, + {2,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6 }, + {2,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 }, +}; +/* }}} */ +/* {{{ [fold] u8 shiftTblIndex[] */ +static const u8 shiftTblIndex[] = { + 8, 17, 8, 16, 7, 16, 7, 15, + 6, 15, 6, 14, 5, 14, 5, 13, + 4, 13, 4, 12, 3, 12, 3, 11, + 2, 11, 2, 10, 1, 9, 0, 9 +}; +/* }}} */ +/* {{{ [fold] s16 scaleTable[64] */ +static const s16 scaleTable[64] = { + 8192, 16704, 16704, 17733, 17032, 17733, 18204, 18081, + 18081, 18204, 18724, 18561, 19195, 18561, 18724, 19265, + 19091, 19704, 19704, 19091, 19265, 21406, 19642, 20267, + 20228, 20267, 19642, 21406, 22725, 21826, 20852, 20805, + 20805, 20852, 21826, 22725, 23170, 23170, 21406, 21399, + 21406, 23170, 23170, 24597, 23785, 22017, 22017, 23785, + 24597, 25250, 24464, 22653, 24464, 25250, 25971, 25171, + 25171, 25971, 26722, 27969, 26722, 29691, 29691, 31520 +}; +/* }}} */ +/* {{{ [fold] u8 scan_norm[64] */ +static const u8 scan_norm[64] = { /* Octals */ + 000, 001, 010, 020, 011, 002, 003, 012, + 021, 030, 040, 031, 022, 013, 004, 005, + 014, 023, 032, 041, 050, 060, 051, 042, + 033, 024, 015, 006, 007, 016, 025, 034, + 043, 052, 061, 070, 071, 062, 053, 044, + 035, 026, 017, 027, 036, 045, 054, 063, + 072, 073, 064, 055, 046, 037, 047, 056, + 065, 074, 075, 066, 057, 067, 076, 077 +}; +/* }}} */ +/* {{{ [fold] hufftable[960] */ +struct hufftable_entry { + s16 value; + u8 bits; + u8 skip; +}; +static const struct hufftable_entry hufftable[960] = { + /* first level entries */ + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 1, 5, 2 }, + { 1, 5, 2 }, + { 1, 5, 2 }, + { 1, 5, 2 }, + { 1, 5, 2 }, + { 1, 5, 2 }, + { 1, 5, 2 }, + { 1, 5, 2 }, + { -1, 5, 2 }, + { -1, 5, 2 }, + { -1, 5, 2 }, + { -1, 5, 2 }, + { -1, 5, 2 }, + { -1, 5, 2 }, + { -1, 5, 2 }, + { -1, 5, 2 }, + { 3, 5, 1 }, + { 3, 5, 1 }, + { 3, 5, 1 }, + { 3, 5, 1 }, + { 3, 5, 1 }, + { 3, 5, 1 }, + { 3, 5, 1 }, + { 3, 5, 1 }, + { -3, 5, 1 }, + { -3, 5, 1 }, + { -3, 5, 1 }, + { -3, 5, 1 }, + { -3, 5, 1 }, + { -3, 5, 1 }, + { -3, 5, 1 }, + { -3, 5, 1 }, + { 4, 5, 1 }, + { 4, 5, 1 }, + { 4, 5, 1 }, + { 4, 5, 1 }, + { 4, 5, 1 }, + { 4, 5, 1 }, + { 4, 5, 1 }, + { 4, 5, 1 }, + { -4, 5, 1 }, + { -4, 5, 1 }, + { -4, 5, 1 }, + { -4, 5, 1 }, + { -4, 5, 1 }, + { -4, 5, 1 }, + { -4, 5, 1 }, + { -4, 5, 1 }, + { 1, 6, 3 }, + { 1, 6, 3 }, + { 1, 6, 3 }, + { 1, 6, 3 }, + { -1, 6, 3 }, + { -1, 6, 3 }, + { -1, 6, 3 }, + { -1, 6, 3 }, + { 2, 6, 2 }, + { 2, 6, 2 }, + { 2, 6, 2 }, + { 2, 6, 2 }, + { -2, 6, 2 }, + { -2, 6, 2 }, + { -2, 6, 2 }, + { -2, 6, 2 }, + { 5, 6, 1 }, + { 5, 6, 1 }, + { 5, 6, 1 }, + { 5, 6, 1 }, + { -5, 6, 1 }, + { -5, 6, 1 }, + { -5, 6, 1 }, + { -5, 6, 1 }, + { 6, 6, 1 }, + { 6, 6, 1 }, + { 6, 6, 1 }, + { 6, 6, 1 }, + { -6, 6, 1 }, + { -6, 6, 1 }, + { -6, 6, 1 }, + { -6, 6, 1 }, + { 1, 7, 4 }, + { 1, 7, 4 }, + { -1, 7, 4 }, + { -1, 7, 4 }, + { 1, 7, 5 }, + { 1, 7, 5 }, + { -1, 7, 5 }, + { -1, 7, 5 }, + { 7, 7, 1 }, + { 7, 7, 1 }, + { -7, 7, 1 }, + { -7, 7, 1 }, + { 8, 7, 1 }, + { 8, 7, 1 }, + { -8, 7, 1 }, + { -8, 7, 1 }, + { 1, 8, 6 }, + { -1, 8, 6 }, + { 1, 8, 7 }, + { -1, 8, 7 }, + { 2, 8, 3 }, + { -2, 8, 3 }, + { 3, 8, 2 }, + { -3, 8, 2 }, + { 4, 8, 2 }, + { -4, 8, 2 }, + { 9, 8, 1 }, + { -9, 8, 1 }, + { 10, 8, 1 }, + { -10, 8, 1 }, + { 11, 8, 1 }, + { -11, 8, 1 }, + { 256, 9, 99 }, + { 258, 9, 99 }, + { 260, 9, 99 }, + { 262, 9, 99 }, + { 264, 9, 99 }, + { 266, 9, 99 }, + { 268, 9, 99 }, + { 270, 9, 99 }, + { 272, 9, 99 }, + { 274, 9, 99 }, + { 276, 9, 99 }, + { 278, 9, 99 }, + { 280, 9, 99 }, + { 282, 9, 99 }, + { 284, 9, 99 }, + { 286, 9, 99 }, + { 288, 10, 99 }, + { 292, 10, 99 }, + { 296, 10, 99 }, + { 300, 10, 99 }, + { 304, 10, 99 }, + { 308, 10, 99 }, + { 312, 10, 99 }, + { 316, 10, 99 }, + { 320, 11, 99 }, + { 328, 11, 99 }, + { 336, 12, 99 }, + { 352, 13, 99 }, + { 384, 13, 99 }, + { 416, 13, 99 }, + { 448, 16, 99 }, + { 704, 16, 99 }, + /* indirect entries */ + { 1, 9, 8 }, + { -1, 9, 8 }, + { 1, 9, 9 }, + { -1, 9, 9 }, + { 1, 9, 10 }, + { -1, 9, 10 }, + { 1, 9, 11 }, + { -1, 9, 11 }, + { 2, 9, 4 }, + { -2, 9, 4 }, + { 2, 9, 5 }, + { -2, 9, 5 }, + { 3, 9, 3 }, + { -3, 9, 3 }, + { 5, 9, 2 }, + { -5, 9, 2 }, + { 6, 9, 2 }, + { -6, 9, 2 }, + { 7, 9, 2 }, + { -7, 9, 2 }, + { 12, 9, 1 }, + { -12, 9, 1 }, + { 13, 9, 1 }, + { -13, 9, 1 }, + { 14, 9, 1 }, + { -14, 9, 1 }, + { 15, 9, 1 }, + { -15, 9, 1 }, + { 16, 9, 1 }, + { -16, 9, 1 }, + { 17, 9, 1 }, + { -17, 9, 1 }, + { 1, 10, 12 }, + { -1, 10, 12 }, + { 1, 10, 13 }, + { -1, 10, 13 }, + { 1, 10, 14 }, + { -1, 10, 14 }, + { 1, 10, 15 }, + { -1, 10, 15 }, + { 2, 10, 6 }, + { -2, 10, 6 }, + { 2, 10, 7 }, + { -2, 10, 7 }, + { 3, 10, 4 }, + { -3, 10, 4 }, + { 3, 10, 5 }, + { -3, 10, 5 }, + { 4, 10, 3 }, + { -4, 10, 3 }, + { 5, 10, 3 }, + { -5, 10, 3 }, + { 8, 10, 2 }, + { -8, 10, 2 }, + { 18, 10, 1 }, + { -18, 10, 1 }, + { 19, 10, 1 }, + { -19, 10, 1 }, + { 20, 10, 1 }, + { -20, 10, 1 }, + { 21, 10, 1 }, + { -21, 10, 1 }, + { 22, 10, 1 }, + { -22, 10, 1 }, + { 3, 11, 6 }, + { -3, 11, 6 }, + { 4, 11, 4 }, + { -4, 11, 4 }, + { 5, 11, 4 }, + { -5, 11, 4 }, + { 6, 11, 3 }, + { -6, 11, 3 }, + { 9, 11, 2 }, + { -9, 11, 2 }, + { 10, 11, 2 }, + { -10, 11, 2 }, + { 11, 11, 2 }, + { -11, 11, 2 }, + { 0, 11, 1 }, + { 0, 11, 2 }, + { 3, 12, 7 }, + { -3, 12, 7 }, + { 4, 12, 5 }, + { -4, 12, 5 }, + { 6, 12, 4 }, + { -6, 12, 4 }, + { 12, 12, 2 }, + { -12, 12, 2 }, + { 13, 12, 2 }, + { -13, 12, 2 }, + { 14, 12, 2 }, + { -14, 12, 2 }, + { 0, 12, 3 }, + { 0, 12, 4 }, + { 0, 12, 5 }, + { 0, 12, 6 }, + { 2, 13, 8 }, + { -2, 13, 8 }, + { 2, 13, 9 }, + { -2, 13, 9 }, + { 2, 13, 10 }, + { -2, 13, 10 }, + { 2, 13, 11 }, + { -2, 13, 11 }, + { 3, 13, 8 }, + { -3, 13, 8 }, + { 3, 13, 9 }, + { -3, 13, 9 }, + { 5, 13, 5 }, + { -5, 13, 5 }, + { 7, 13, 4 }, + { -7, 13, 4 }, + { 7, 13, 3 }, + { -7, 13, 3 }, + { 8, 13, 3 }, + { -8, 13, 3 }, + { 9, 13, 3 }, + { -9, 13, 3 }, + { 10, 13, 3 }, + { -10, 13, 3 }, + { 11, 13, 3 }, + { -11, 13, 3 }, + { 15, 13, 2 }, + { -15, 13, 2 }, + { 16, 13, 2 }, + { -16, 13, 2 }, + { 17, 13, 2 }, + { -17, 13, 2 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 0, 13, 7 }, + { 0, 13, 8 }, + { 0, 13, 9 }, + { 0, 13, 10 }, + { 0, 13, 11 }, + { 0, 13, 12 }, + { 0, 13, 13 }, + { 0, 13, 14 }, + { 0, 13, 15 }, + { 0, 13, 16 }, + { 0, 13, 17 }, + { 0, 13, 18 }, + { 0, 13, 19 }, + { 0, 13, 20 }, + { 0, 13, 21 }, + { 0, 13, 22 }, + { 0, 13, 23 }, + { 0, 13, 24 }, + { 0, 13, 25 }, + { 0, 13, 26 }, + { 0, 13, 27 }, + { 0, 13, 28 }, + { 0, 13, 29 }, + { 0, 13, 30 }, + { 0, 13, 31 }, + { 0, 13, 32 }, + { 0, 13, 33 }, + { 0, 13, 34 }, + { 0, 13, 35 }, + { 0, 13, 36 }, + { 0, 13, 37 }, + { 0, 13, 38 }, + { 0, 13, 39 }, + { 0, 13, 40 }, + { 0, 13, 41 }, + { 0, 13, 42 }, + { 0, 13, 43 }, + { 0, 13, 44 }, + { 0, 13, 45 }, + { 0, 13, 46 }, + { 0, 13, 47 }, + { 0, 13, 48 }, + { 0, 13, 49 }, + { 0, 13, 50 }, + { 0, 13, 51 }, + { 0, 13, 52 }, + { 0, 13, 53 }, + { 0, 13, 54 }, + { 0, 13, 55 }, + { 0, 13, 56 }, + { 0, 13, 57 }, + { 0, 13, 58 }, + { 0, 13, 59 }, + { 0, 13, 60 }, + { 0, 13, 61 }, + { 0, 13, 62 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 23, 16, 1 }, + { -23, 16, 1 }, + { 24, 16, 1 }, + { -24, 16, 1 }, + { 25, 16, 1 }, + { -25, 16, 1 }, + { 26, 16, 1 }, + { -26, 16, 1 }, + { 27, 16, 1 }, + { -27, 16, 1 }, + { 28, 16, 1 }, + { -28, 16, 1 }, + { 29, 16, 1 }, + { -29, 16, 1 }, + { 30, 16, 1 }, + { -30, 16, 1 }, + { 31, 16, 1 }, + { -31, 16, 1 }, + { 32, 16, 1 }, + { -32, 16, 1 }, + { 33, 16, 1 }, + { -33, 16, 1 }, + { 34, 16, 1 }, + { -34, 16, 1 }, + { 35, 16, 1 }, + { -35, 16, 1 }, + { 36, 16, 1 }, + { -36, 16, 1 }, + { 37, 16, 1 }, + { -37, 16, 1 }, + { 38, 16, 1 }, + { -38, 16, 1 }, + { 39, 16, 1 }, + { -39, 16, 1 }, + { 40, 16, 1 }, + { -40, 16, 1 }, + { 41, 16, 1 }, + { -41, 16, 1 }, + { 42, 16, 1 }, + { -42, 16, 1 }, + { 43, 16, 1 }, + { -43, 16, 1 }, + { 44, 16, 1 }, + { -44, 16, 1 }, + { 45, 16, 1 }, + { -45, 16, 1 }, + { 46, 16, 1 }, + { -46, 16, 1 }, + { 47, 16, 1 }, + { -47, 16, 1 }, + { 48, 16, 1 }, + { -48, 16, 1 }, + { 49, 16, 1 }, + { -49, 16, 1 }, + { 50, 16, 1 }, + { -50, 16, 1 }, + { 51, 16, 1 }, + { -51, 16, 1 }, + { 52, 16, 1 }, + { -52, 16, 1 }, + { 53, 16, 1 }, + { -53, 16, 1 }, + { 54, 16, 1 }, + { -54, 16, 1 }, + { 55, 16, 1 }, + { -55, 16, 1 }, + { 56, 16, 1 }, + { -56, 16, 1 }, + { 57, 16, 1 }, + { -57, 16, 1 }, + { 58, 16, 1 }, + { -58, 16, 1 }, + { 59, 16, 1 }, + { -59, 16, 1 }, + { 60, 16, 1 }, + { -60, 16, 1 }, + { 61, 16, 1 }, + { -61, 16, 1 }, + { 62, 16, 1 }, + { -62, 16, 1 }, + { 63, 16, 1 }, + { -63, 16, 1 }, + { 64, 16, 1 }, + { -64, 16, 1 }, + { 65, 16, 1 }, + { -65, 16, 1 }, + { 66, 16, 1 }, + { -66, 16, 1 }, + { 67, 16, 1 }, + { -67, 16, 1 }, + { 68, 16, 1 }, + { -68, 16, 1 }, + { 69, 16, 1 }, + { -69, 16, 1 }, + { 70, 16, 1 }, + { -70, 16, 1 }, + { 71, 16, 1 }, + { -71, 16, 1 }, + { 72, 16, 1 }, + { -72, 16, 1 }, + { 73, 16, 1 }, + { -73, 16, 1 }, + { 74, 16, 1 }, + { -74, 16, 1 }, + { 75, 16, 1 }, + { -75, 16, 1 }, + { 76, 16, 1 }, + { -76, 16, 1 }, + { 77, 16, 1 }, + { -77, 16, 1 }, + { 78, 16, 1 }, + { -78, 16, 1 }, + { 79, 16, 1 }, + { -79, 16, 1 }, + { 80, 16, 1 }, + { -80, 16, 1 }, + { 81, 16, 1 }, + { -81, 16, 1 }, + { 82, 16, 1 }, + { -82, 16, 1 }, + { 83, 16, 1 }, + { -83, 16, 1 }, + { 84, 16, 1 }, + { -84, 16, 1 }, + { 85, 16, 1 }, + { -85, 16, 1 }, + { 86, 16, 1 }, + { -86, 16, 1 }, + { 87, 16, 1 }, + { -87, 16, 1 }, + { 88, 16, 1 }, + { -88, 16, 1 }, + { 89, 16, 1 }, + { -89, 16, 1 }, + { 90, 16, 1 }, + { -90, 16, 1 }, + { 91, 16, 1 }, + { -91, 16, 1 }, + { 92, 16, 1 }, + { -92, 16, 1 }, + { 93, 16, 1 }, + { -93, 16, 1 }, + { 94, 16, 1 }, + { -94, 16, 1 }, + { 95, 16, 1 }, + { -95, 16, 1 }, + { 96, 16, 1 }, + { -96, 16, 1 }, + { 97, 16, 1 }, + { -97, 16, 1 }, + { 98, 16, 1 }, + { -98, 16, 1 }, + { 99, 16, 1 }, + { -99, 16, 1 }, + { 100, 16, 1 }, + { -100, 16, 1 }, + { 101, 16, 1 }, + { -101, 16, 1 }, + { 102, 16, 1 }, + { -102, 16, 1 }, + { 103, 16, 1 }, + { -103, 16, 1 }, + { 104, 16, 1 }, + { -104, 16, 1 }, + { 105, 16, 1 }, + { -105, 16, 1 }, + { 106, 16, 1 }, + { -106, 16, 1 }, + { 107, 16, 1 }, + { -107, 16, 1 }, + { 108, 16, 1 }, + { -108, 16, 1 }, + { 109, 16, 1 }, + { -109, 16, 1 }, + { 110, 16, 1 }, + { -110, 16, 1 }, + { 111, 16, 1 }, + { -111, 16, 1 }, + { 112, 16, 1 }, + { -112, 16, 1 }, + { 113, 16, 1 }, + { -113, 16, 1 }, + { 114, 16, 1 }, + { -114, 16, 1 }, + { 115, 16, 1 }, + { -115, 16, 1 }, + { 116, 16, 1 }, + { -116, 16, 1 }, + { 117, 16, 1 }, + { -117, 16, 1 }, + { 118, 16, 1 }, + { -118, 16, 1 }, + { 119, 16, 1 }, + { -119, 16, 1 }, + { 120, 16, 1 }, + { -120, 16, 1 }, + { 121, 16, 1 }, + { -121, 16, 1 }, + { 122, 16, 1 }, + { -122, 16, 1 }, + { 123, 16, 1 }, + { -123, 16, 1 }, + { 124, 16, 1 }, + { -124, 16, 1 }, + { 125, 16, 1 }, + { -125, 16, 1 }, + { 126, 16, 1 }, + { -126, 16, 1 }, + { 127, 16, 1 }, + { -127, 16, 1 }, + { 128, 16, 1 }, + { -128, 16, 1 }, + { 129, 16, 1 }, + { -129, 16, 1 }, + { 130, 16, 1 }, + { -130, 16, 1 }, + { 131, 16, 1 }, + { -131, 16, 1 }, + { 132, 16, 1 }, + { -132, 16, 1 }, + { 133, 16, 1 }, + { -133, 16, 1 }, + { 134, 16, 1 }, + { -134, 16, 1 }, + { 135, 16, 1 }, + { -135, 16, 1 }, + { 136, 16, 1 }, + { -136, 16, 1 }, + { 137, 16, 1 }, + { -137, 16, 1 }, + { 138, 16, 1 }, + { -138, 16, 1 }, + { 139, 16, 1 }, + { -139, 16, 1 }, + { 140, 16, 1 }, + { -140, 16, 1 }, + { 141, 16, 1 }, + { -141, 16, 1 }, + { 142, 16, 1 }, + { -142, 16, 1 }, + { 143, 16, 1 }, + { -143, 16, 1 }, + { 144, 16, 1 }, + { -144, 16, 1 }, + { 145, 16, 1 }, + { -145, 16, 1 }, + { 146, 16, 1 }, + { -146, 16, 1 }, + { 147, 16, 1 }, + { -147, 16, 1 }, + { 148, 16, 1 }, + { -148, 16, 1 }, + { 149, 16, 1 }, + { -149, 16, 1 }, + { 150, 16, 1 }, + { -150, 16, 1 }, + { 151, 16, 1 }, + { -151, 16, 1 }, + { 152, 16, 1 }, + { -152, 16, 1 }, + { 153, 16, 1 }, + { -153, 16, 1 }, + { 154, 16, 1 }, + { -154, 16, 1 }, + { 155, 16, 1 }, + { -155, 16, 1 }, + { 156, 16, 1 }, + { -156, 16, 1 }, + { 157, 16, 1 }, + { -157, 16, 1 }, + { 158, 16, 1 }, + { -158, 16, 1 }, + { 159, 16, 1 }, + { -159, 16, 1 }, + { 160, 16, 1 }, + { -160, 16, 1 }, + { 161, 16, 1 }, + { -161, 16, 1 }, + { 162, 16, 1 }, + { -162, 16, 1 }, + { 163, 16, 1 }, + { -163, 16, 1 }, + { 164, 16, 1 }, + { -164, 16, 1 }, + { 165, 16, 1 }, + { -165, 16, 1 }, + { 166, 16, 1 }, + { -166, 16, 1 }, + { 167, 16, 1 }, + { -167, 16, 1 }, + { 168, 16, 1 }, + { -168, 16, 1 }, + { 169, 16, 1 }, + { -169, 16, 1 }, + { 170, 16, 1 }, + { -170, 16, 1 }, + { 171, 16, 1 }, + { -171, 16, 1 }, + { 172, 16, 1 }, + { -172, 16, 1 }, + { 173, 16, 1 }, + { -173, 16, 1 }, + { 174, 16, 1 }, + { -174, 16, 1 }, + { 175, 16, 1 }, + { -175, 16, 1 }, + { 176, 16, 1 }, + { -176, 16, 1 }, + { 177, 16, 1 }, + { -177, 16, 1 }, + { 178, 16, 1 }, + { -178, 16, 1 }, + { 179, 16, 1 }, + { -179, 16, 1 }, + { 180, 16, 1 }, + { -180, 16, 1 }, + { 181, 16, 1 }, + { -181, 16, 1 }, + { 182, 16, 1 }, + { -182, 16, 1 }, + { 183, 16, 1 }, + { -183, 16, 1 }, + { 184, 16, 1 }, + { -184, 16, 1 }, + { 185, 16, 1 }, + { -185, 16, 1 }, + { 186, 16, 1 }, + { -186, 16, 1 }, + { 187, 16, 1 }, + { -187, 16, 1 }, + { 188, 16, 1 }, + { -188, 16, 1 }, + { 189, 16, 1 }, + { -189, 16, 1 }, + { 190, 16, 1 }, + { -190, 16, 1 }, + { 191, 16, 1 }, + { -191, 16, 1 }, + { 192, 16, 1 }, + { -192, 16, 1 }, + { 193, 16, 1 }, + { -193, 16, 1 }, + { 194, 16, 1 }, + { -194, 16, 1 }, + { 195, 16, 1 }, + { -195, 16, 1 }, + { 196, 16, 1 }, + { -196, 16, 1 }, + { 197, 16, 1 }, + { -197, 16, 1 }, + { 198, 16, 1 }, + { -198, 16, 1 }, + { 199, 16, 1 }, + { -199, 16, 1 }, + { 200, 16, 1 }, + { -200, 16, 1 }, + { 201, 16, 1 }, + { -201, 16, 1 }, + { 202, 16, 1 }, + { -202, 16, 1 }, + { 203, 16, 1 }, + { -203, 16, 1 }, + { 204, 16, 1 }, + { -204, 16, 1 }, + { 205, 16, 1 }, + { -205, 16, 1 }, + { 206, 16, 1 }, + { -206, 16, 1 }, + { 207, 16, 1 }, + { -207, 16, 1 }, + { 208, 16, 1 }, + { -208, 16, 1 }, + { 209, 16, 1 }, + { -209, 16, 1 }, + { 210, 16, 1 }, + { -210, 16, 1 }, + { 211, 16, 1 }, + { -211, 16, 1 }, + { 212, 16, 1 }, + { -212, 16, 1 }, + { 213, 16, 1 }, + { -213, 16, 1 }, + { 214, 16, 1 }, + { -214, 16, 1 }, + { 215, 16, 1 }, + { -215, 16, 1 }, + { 216, 16, 1 }, + { -216, 16, 1 }, + { 217, 16, 1 }, + { -217, 16, 1 }, + { 218, 16, 1 }, + { -218, 16, 1 }, + { 219, 16, 1 }, + { -219, 16, 1 }, + { 220, 16, 1 }, + { -220, 16, 1 }, + { 221, 16, 1 }, + { -221, 16, 1 }, + { 222, 16, 1 }, + { -222, 16, 1 }, + { 223, 16, 1 }, + { -223, 16, 1 }, + { 224, 16, 1 }, + { -224, 16, 1 }, + { 225, 16, 1 }, + { -225, 16, 1 }, + { 226, 16, 1 }, + { -226, 16, 1 }, + { 227, 16, 1 }, + { -227, 16, 1 }, + { 228, 16, 1 }, + { -228, 16, 1 }, + { 229, 16, 1 }, + { -229, 16, 1 }, + { 230, 16, 1 }, + { -230, 16, 1 }, + { 231, 16, 1 }, + { -231, 16, 1 }, + { 232, 16, 1 }, + { -232, 16, 1 }, + { 233, 16, 1 }, + { -233, 16, 1 }, + { 234, 16, 1 }, + { -234, 16, 1 }, + { 235, 16, 1 }, + { -235, 16, 1 }, + { 236, 16, 1 }, + { -236, 16, 1 }, + { 237, 16, 1 }, + { -237, 16, 1 }, + { 238, 16, 1 }, + { -238, 16, 1 }, + { 239, 16, 1 }, + { -239, 16, 1 }, + { 240, 16, 1 }, + { -240, 16, 1 }, + { 241, 16, 1 }, + { -241, 16, 1 }, + { 242, 16, 1 }, + { -242, 16, 1 }, + { 243, 16, 1 }, + { -243, 16, 1 }, + { 244, 16, 1 }, + { -244, 16, 1 }, + { 245, 16, 1 }, + { -245, 16, 1 }, + { 246, 16, 1 }, + { -246, 16, 1 }, + { 247, 16, 1 }, + { -247, 16, 1 }, + { 248, 16, 1 }, + { -248, 16, 1 }, + { 249, 16, 1 }, + { -249, 16, 1 }, + { 250, 16, 1 }, + { -250, 16, 1 }, + { 251, 16, 1 }, + { -251, 16, 1 }, + { 252, 16, 1 }, + { -252, 16, 1 }, + { 253, 16, 1 }, + { -253, 16, 1 }, + { 254, 16, 1 }, + { -254, 16, 1 }, + { 255, 16, 1 }, + { -255, 16, 1 } +}; +/* }}} */ +/* {{{ [fold] qc_mjpeg_lvc_decode_block(struct bitstream *bitsrc, s16 *output, int blockval) */ +static inline void qc_mjpeg_lvc_decode_block(struct bitstream *bitsrc, s16 *output, int blockval) +{ + u32 b; + u8 *p; + int k; + int value, skip, bits; + struct hufftable_entry entry; + int offset = 0; + const u8 *shiftPtr; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_lvc_decode_block(bitsrc=%p, output=%p, blockval=%i)", bitsrc, output, blockval); + b = bitsrc->b; + k = bitsrc->k; + p = bitsrc->p; + memset(output, 0, 64 * sizeof(s16)); + if (blockval!=7) PDEBUG("blockval=%i",blockval); + NEEDBITS(b,k,p); + shiftPtr = shiftTables[shiftTblIndex[2*blockval+BITVALUE(b,1)]]; + DUMPBITS(b,k,1); + value = BITVALUE(((signed)b),10); + DUMPBITS(b,k,10); + do { + value = ((value << shiftPtr[offset]) * scaleTable[offset]) >> 14; + output[scan_norm[offset]] = value; + NEEDBITS(b,k,p); + entry = hufftable[BITVALUE(b,8)]; + bits = entry.bits; + if (bits > 8) { + entry = hufftable[entry.value + ((b & 0x00ffffff) >> (32 - bits))]; + if (PARANOID && entry.bits!=bits) { + PDEBUG("entry.bits!=bits shouldn't happen"); + bits = entry.bits; + } + } + DUMPBITS(b,k,bits); + skip = entry.skip; + value = entry.value; + offset += skip; + } while (offset < 64); + bitsrc->b = b; + bitsrc->k = k; + bitsrc->p = p; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_lvc_decode_block() exit"); +} +/* }}} */ + +/* {{{ [fold] struct blockorder */ +struct blockorder { + char widthPad; /* pad width to multiple of this */ + char heightPad; /* pad height to multiple of this */ + char uvWshift; /* shift width by this to get width of U/V image */ + char uvHshift; /* dito for height */ + char blockWidth[2]; /* width of a block for each pass*/ + char subblockCount[2]; /* number of sub block in a block for each pass */ + u32 subblockMap[2]; +}; +static const struct blockorder order_I420 = { + 32, 16, 1, 1, + { 32, 16 }, { 4, 4 }, + { 0x00, 0x90 } +}; +#if 0 +static const struct blockorder order_L422 = { + 16, 16, 1, 0, + { 16, 16 }, { 4, 4 }, + { 0x90, 0x90 } +}; + +static const struct blockorder order_L410 = { + 64, 16, 2, 1, + { 32, 64 }, { 4, 12 }, + { 0x00, 0x909000 } +}; +#endif +/* }}} */ +/* {{{ [fold] qc_mjpeg_lvc_decode() */ +/* Decode given compressed image to YUV image. Return error code if bad data */ +static int qc_mjpeg_lvc_decode(u8 *outY, u8 *outU, u8 *outV, + u8 *input, u32 length, unsigned int width, unsigned int height) +{ + struct bitstream stream; + const struct blockorder *blkorder; + + unsigned int blockx, blocky; + unsigned int pass, subblock, blockval = 0; + unsigned int blocknr = 0; + unsigned int uvWidth; + + s16 blockbuffer[64]; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_lvc_decode(outY=%p, outU=%p, outV=%p)", outY, outU, outV); + stream.b = 0; + stream.k = 16; + stream.p = input; + stream.end = input+length; + + blkorder = &order_I420; /* Select compression type */ + + uvWidth = (width >> blkorder->uvWshift); + + if ((width & (blkorder->widthPad - 1)) || (height & (blkorder->heightPad - 1))) { + PDEBUG("something's wrong"); + return -EILSEQ; + } + + for (blocky=0; blockyheightPad) { + for (pass = 0; pass < 2; pass++) { + int blockwidth = blkorder->blockWidth[pass]; + int subblockcount = blkorder->subblockCount[pass]; + u32 map = blkorder->subblockMap[pass]; + for (blockx=0; blockx stream.end) { + PDEBUG("p>stream.end"); + return -EILSEQ; + } + + blockval = BITVALUE(b, 4); + DUMPBITS(b,k,4); + stream.b = b; + stream.k = k; + stream.p = p; + } + qc_mjpeg_lvc_decode_block(&stream, blockbuffer, blockval); + blockbuffer[0] += 1024; + switch (subblkmap & 3) { + case 0: + qc_mjpeg_idct(blockbuffer, outY, width); + outY += 8; + break; + case 1: + qc_mjpeg_idct(blockbuffer, outU, uvWidth); + outU += 8; + break; + case 2: + qc_mjpeg_idct(blockbuffer, outV, uvWidth); + outV += 8; + break; + } + subblkmap >>= 2; + } /* for (subblock = 0; subblock < subblockcount; subblock++) */ + } /* for (blockx = 0; blockx < width; blockx += blockwidth) */ + outY += 7 * width; + if (map) { + outU += 7 * uvWidth; + outV += 7 * uvWidth; + } + } /* for (pass = 0; pass < 2; pass++) */ + + /* next block starts at next 4 byte boundary */ + stream.p -= (16 - stream.k) >> 3; /* push back unread bits */ + stream.p += (input - stream.p) & 3; + stream.k = 16; + stream.b = 0; + } /* for (blocky=0; blockyheightPad) */ + + if (stream.p != stream.end) { + PDEBUG("stream.p != stream.end"); + return -EILSEQ; + } + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_lvc_decode() done"); + return 0; +} +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** qc_mjpeg: Motion JPEG decoding main routines *************************** */ + +static const int qc_mjpeg_width = 320; /* Size of the compressed image */ +static const int qc_mjpeg_height = 240; + +/* {{{ [fold] qc_mjpeg_decode() */ +/* Decode and uncompress given data, return error code if failure + * src = points to compressed bitstream data + * src_len = compressed data length in bytes + * dst = decompressed image will be stored here, size 320x240 x bytes per pixel (2-4) + */ +int qc_mjpeg_decode(struct qc_mjpeg_data *md, unsigned char *src, int src_len, unsigned char *dst) +{ + int r; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_decode(src_len=%i,W=%i,H=%i,depth=%i)",src_len,qc_mjpeg_width,qc_mjpeg_height,md->depth); + IDEBUG_TEST(*md); + if (src_len >= 100000) { + PDEBUG("long frame, length=%i", src_len); + return -EILSEQ; + } + r = qc_mjpeg_lvc_decode(md->encY, md->encU, md->encV, src, src_len, qc_mjpeg_width, qc_mjpeg_height); + if (r<0) { + PRINTK(KERN_ERR,"frame corrupted, len=%i",src_len); + return r; + } + qc_mjpeg_yuv2rgb(md, dst, md->encY, md->encU, md->encV, + qc_mjpeg_width, qc_mjpeg_height, /* Image size */ + qc_mjpeg_width * ((md->depth+1)/8), /* RGB stride */ + qc_mjpeg_width, /* Y stride */ + qc_mjpeg_width/2); /* U and V stride */ + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_decode() done"); + return 0; +} +/* }}} */ +/* {{{ [fold] qc_mjpeg_init(struct qc_mjpeg_data *md, int depth, Bool tobgr) */ +/* Initialize Motion JPEG decompression. + * depth = bit depth of the decoded image, either 15=16,24 or 32 + * tobgr = use blue in the lowest address (red otherwise) + */ +int qc_mjpeg_init(struct qc_mjpeg_data *md, int depth, Bool tobgr) +{ + int r = -ENOMEM; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_init(depth=%i)",depth); + md->depth = depth; + /* Temporary buffers used for decoding the image (FIXME:too big for stack?) */ + /* Note: originally this allocated one extra byte for encY/U/V. I removed that. */ + md->encY = kmalloc(qc_mjpeg_width*qc_mjpeg_height, GFP_KERNEL); + if (!md->encY) goto fail1; + md->encU = kmalloc(qc_mjpeg_width*qc_mjpeg_height/4, GFP_KERNEL); + if (!md->encU) goto fail2; + md->encV = kmalloc(qc_mjpeg_width*qc_mjpeg_height/4, GFP_KERNEL); + if (!md->encV) goto fail3; + if ((r=qc_mjpeg_yuv2rgb_init(md, depth, tobgr ? MODE_BGR : MODE_RGB))<0) goto fail4; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_init() done"); + IDEBUG_INIT(*md); + return 0; + +fail4: kfree(md->encV); +fail3: kfree(md->encU); +fail2: kfree(md->encY); +fail1: PDEBUG("failed qc_mjpeg_init() = %i", r); + POISON(*md); + return r; +} +/* }}} */ +/* {{{ [fold] qc_mjpeg_exit(struct qc_mjpeg_data *md) */ +/* Free up resources allocated for image decompression */ +void qc_mjpeg_exit(struct qc_mjpeg_data *md) +{ + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_exit()"); + IDEBUG_TEST(*md); + qc_mjpeg_yuv2rgb_exit(md); + kfree(md->encV); + kfree(md->encU); + kfree(md->encY); + POISON(md->encV); + POISON(md->encU); + POISON(md->encY); + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_exit() done"); + IDEBUG_EXIT(*md); +} +/* }}} */ + +/* }}} */ + +#else /* COMPRESS=0 */ +int qc_mjpeg_decode(struct qc_mjpeg_data *md, unsigned char *src, int src_len, unsigned char *dst) { return -ENXIO; } +int qc_mjpeg_init(struct qc_mjpeg_data *md, int depth, Bool tobgr) { return -ENXIO; } +void qc_mjpeg_exit(struct qc_mjpeg_data *md) { } +#endif + +/* End of file */ --- linux-2.6.28.orig/ubuntu/qc-usb/qc-driver.c +++ linux-2.6.28/ubuntu/qc-usb/qc-driver.c @@ -0,0 +1,3438 @@ +/* Start of file */ + +/* {{{ [fold] Comments */ + +/* + * qc-usb, Logitech QuickCam video driver with V4L support + * Derived from qce-ga, linux V4L driver for the QuickCam Express and Dexxa QuickCam + * + * qc-driver.c - main driver part + * + * Copyright (C) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher + * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland + * Copyright (C) 2002,2003 Tuukka Toivonen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + * + */ + +/* Cam variations of Logitech QuickCam: + P/N 861037: Sensor HDCS1000 ASIC STV0600 + P/N 861050-0010: Sensor HDCS1000 ASIC STV0600 + P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 ("QuickCam Express") + P/N 861055: Sensor ST VV6410 ASIC STV0610 ("LEGO cam") + P/N 861075-0040: Sensor HDCS1000 ASIC + P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 (Dexxa WebCam USB) + P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 ("QuickCam Web") + + For any questions ask + qce-ga-devel@lists.sourceforge.net - about code + qce-ga-discussion@lists.sourceforge.net - about usage +*/ +/* }}} */ +/* {{{ [fold] Includes */ +#include "quickcam.h" + +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) +#include +#endif +#include + +#include "qc-memory.h" + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +#include +#endif +/* }}} */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) +/* Make this a bit backwards compatible... hack hack... */ +#ifndef module_param +#define module_param(a, b, c) MODULE_PARM(a, "i") +#endif +#endif + +/* {{{ [fold] Module parameters */ +MODULE_PARM_DESC(qcdebug, "Sets the debug output (bitfield)"); +int qcdebug = DEBUGLEVEL; +module_param(qcdebug, int, 0444); + +MODULE_PARM_DESC(keepsettings, "Keep picture settings across one open to another (0-1)"); +static int keepsettings = 0; +module_param(keepsettings, int, 0444); + +MODULE_PARM_DESC(settle, "Maximum number of frames to wait picture brightness to settle (0-255)"); +static int settle = 0; +module_param(settle, int, 0444); + +/* Subsampling is used to allow higher scan rate with smaller images. */ +MODULE_PARM_DESC(subsample, "Sets subsampling (0-1)"); +static int subsample = 0; /* normal or sub-sample (sub-sample to increase the speed) */ +module_param(subsample, int, 0444); + +MODULE_PARM_DESC(compress, "Enable compressed mode (0-1)"); +static int compress = 0; /* Enable compressed mode if available (higher framerate) */ +module_param(compress, int, 0444); + +MODULE_PARM_DESC(frameskip, "How frequently capture frames (0-10)"); +static int frameskip = 0; +module_param(frameskip, int, 0444); + +MODULE_PARM_DESC(quality, "Sets the picture quality (0-5)"); +static int quality = 5; /* 5 = generalized adjustable Pei-Tam method */ +module_param(quality, int, 0444); + +MODULE_PARM_DESC(adaptive, "Automatic adaptive brightness control (0-1)"); +static int adaptive = 1; +module_param(adaptive, int, 0444); + +MODULE_PARM_DESC(equalize, "Equalize image (0-1)"); +static int equalize = 0; /* Disabled by default */ +module_param(equalize, int, 0444); + +MODULE_PARM_DESC(userlut, "Apply user-specified lookup-table (0-1)"); +static int userlut = 0; /* Disabled by default */ +module_param(userlut, int, 0444); + +MODULE_PARM_DESC(retryerrors, "Retry if image capture fails, otherwise return error code (0-1)"); +static int retryerrors = 1; /* Enabled by default */ +module_param(retryerrors, int, 0444); + +/* Bug in Xvideo(?): if the width is not divisible by 8 and Xvideo is used, the frame is shown wrongly */ +MODULE_PARM_DESC(compatible, "Enable workaround for bugs in application programs (bitfield)"); +static int compatible = 2; /* Enable double-buffering by default */ +module_param(compatible, int, 0444); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,5) +MODULE_PARM_DESC(video_nr, "Set videodevice number (/dev/videoX)"); +static int video_nr = -1; +module_param(video_nr, int, 0444); +/* video_nr option allows to specify a certain /dev/videoX device */ +/* (like /dev/video0 or /dev/video1 ...) */ +/* for autodetect first available use video_nr=-1 (defaultvalue) */ +#endif +/* }}} */ +/* {{{ [fold] Miscellaneous data */ +#ifndef MODULE_LICENSE /* Appeared in 2.4.10 */ +#ifdef MODULE +#define MODULE_LICENSE(license) \ +static const char __module_license[] __attribute__((section(".modinfo"))) = \ + "license=" license +#else +#define MODULE_LICENSE(license) +#endif +#endif + +MODULE_SUPPORTED_DEVICE("video"); +MODULE_DESCRIPTION("Logitech QuickCam USB driver"); +MODULE_AUTHOR("See README"); +MODULE_LICENSE("GPL"); +EXPORT_NO_SYMBOLS; + +static const int min_framewidth = 32; /* Minimum image size we allow delivering to user application */ +static const int min_frameheight = 32; + +static const char qc_proc_name[] = "video/quickcam"; +#define qc_name (&qc_proc_name[6]) + +static struct usb_device_id qc_device_table[] = { + { USB_DEVICE(0x046D, 0x0840) }, /* QuickCam Express */ + { USB_DEVICE(0x046D, 0x0850) }, /* LEGO cam / QuickCam Web */ + { USB_DEVICE(0x046D, 0x0870) }, /* Dexxa WebCam USB */ + { USB_DEVICE(0x046D, 0x08F6) }, /* Logitech QuickCam Messenger */ + { } +}; +MODULE_DEVICE_TABLE(usb, qc_device_table); + +extern const struct qc_sensor qc_sensor_pb0100; +extern const struct qc_sensor qc_sensor_hdcs1000; +extern const struct qc_sensor qc_sensor_hdcs1020; +extern const struct qc_sensor qc_sensor_vv6410; + +static const struct qc_sensor *sensors[] = { + &qc_sensor_hdcs1000, + &qc_sensor_hdcs1020, + &qc_sensor_pb0100, + &qc_sensor_vv6410, +}; + +static LIST_HEAD(quickcam_list); /* Linked list containing all QuickCams */ +static DECLARE_MUTEX(quickcam_list_lock); /* Always lock first quickcam_list_lock, then qc->lock */ + +/* Default values for user-specified lookup-table; may be overwritten by user */ +static unsigned char userlut_contents[QC_LUT_SIZE] = { + /* Red */ + 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 25, 30, 35, 38, 42, + 44, 47, 50, 53, 54, 57, 59, 61, 63, 65, 67, 69, + 71, 71, 73, 75, 77, 78, 80, 81, 82, 84, 85, 87, + 88, 89, 90, 91, 93, 94, 95, 97, 98, 98, 99, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 125, 126, 127, 128, 129, 129, 130, 131, 132, 133, 134, + 134, 135, 135, 136, 137, 138, 139, 140, 140, 141, 142, 143, + 143, 143, 144, 145, 146, 147, 147, 148, 149, 150, 150, 151, + 152, 152, 152, 153, 154, 154, 155, 156, 157, 157, 158, 159, + 159, 160, 161, 161, 161, 162, 163, 163, 164, 165, 165, 166, + 167, 167, 168, 168, 169, 170, 170, 170, 171, 171, 172, 173, + 173, 174, 174, 175, 176, 176, 177, 178, 178, 179, 179, 179, + 180, 180, 181, 181, 182, 183, 183, 184, 184, 185, 185, 186, + 187, 187, 188, 188, 188, 188, 189, 190, 190, 191, 191, 192, + 192, 193, 193, 194, 195, 195, 196, 196, 197, 197, 197, 197, + 198, 198, 199, 199, 200, 201, 201, 202, 202, 203, 203, 204, + 204, 205, 205, 206, 206, 206, 206, 207, 207, 208, 208, 209, + 209, 210, 210, 211, 211, 212, 212, 213, 213, 214, 214, 215, + 215, 215, 215, 216, 216, 217, 217, 218, 218, 218, 219, 219, + 220, 220, 221, 221, + + /* Green */ + 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 28, 34, 39, 43, 47, + 50, 53, 56, 59, 61, 64, 66, 68, 71, 73, 75, 77, + 79, 80, 82, 84, 86, 87, 89, 91, 92, 94, 95, 97, + 98, 100, 101, 102, 104, 105, 106, 108, 109, 110, 111, 113, + 114, 115, 116, 117, 118, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 144, 145, 146, 147, 148, 149, + 150, 151, 151, 152, 153, 154, 155, 156, 156, 157, 158, 159, + 160, 160, 161, 162, 163, 164, 164, 165, 166, 167, 167, 168, + 169, 170, 170, 171, 172, 172, 173, 174, 175, 175, 176, 177, + 177, 178, 179, 179, 180, 181, 182, 182, 183, 184, 184, 185, + 186, 186, 187, 187, 188, 189, 189, 190, 191, 191, 192, 193, + 193, 194, 194, 195, 196, 196, 197, 198, 198, 199, 199, 200, + 201, 201, 202, 202, 203, 204, 204, 205, 205, 206, 206, 207, + 208, 208, 209, 209, 210, 210, 211, 212, 212, 213, 213, 214, + 214, 215, 215, 216, 217, 217, 218, 218, 219, 219, 220, 220, + 221, 221, 222, 222, 223, 224, 224, 225, 225, 226, 226, 227, + 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, 233, + 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 239, + 239, 240, 240, 241, 241, 242, 242, 243, 243, 243, 244, 244, + 245, 245, 246, 246, + + /* Blue */ + 0, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 30, 37, 42, 47, 51, + 55, 58, 61, 64, 67, 70, 72, 74, 78, 80, 82, 84, + 86, 88, 90, 92, 94, 95, 97, 100, 101, 103, 104, 106, + 107, 110, 111, 112, 114, 115, 116, 118, 119, 121, 122, 124, + 125, 126, 127, 128, 129, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 143, 144, 145, 146, 147, 148, 149, 150, 151, + 152, 154, 155, 156, 157, 158, 158, 159, 160, 161, 162, 163, + 165, 166, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, + 176, 176, 177, 178, 179, 180, 180, 181, 182, 183, 183, 184, + 185, 187, 187, 188, 189, 189, 190, 191, 192, 192, 193, 194, + 194, 195, 196, 196, 198, 199, 200, 200, 201, 202, 202, 203, + 204, 204, 205, 205, 206, 207, 207, 209, 210, 210, 211, 212, + 212, 213, 213, 214, 215, 215, 216, 217, 217, 218, 218, 220, + 221, 221, 222, 222, 223, 224, 224, 225, 225, 226, 226, 227, + 228, 228, 229, 229, 231, 231, 232, 233, 233, 234, 234, 235, + 235, 236, 236, 237, 238, 238, 239, 239, 240, 240, 242, 242, + 243, 243, 244, 244, 245, 246, 246, 247, 247, 248, 248, 249, + 249, 250, 250, 251, 251, 253, 253, 254, 254, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255 +}; + +static void qc_usb_exit(struct quickcam *qc); +static int qc_capt_init(struct quickcam *qc); +static void qc_capt_exit(struct quickcam *qc); +static int qc_capt_get(struct quickcam *qc, unsigned char **frame); +static int qc_isoc_init(struct quickcam *qc); +static void qc_isoc_exit(struct quickcam *qc); +/* }}} */ + +/* {{{ [fold] **** Miscellaneous functions ************************************** */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) +/* {{{ [fold] usb_kill_urb(struct urb *urb) */ +/* Unlink URB synchronously (usb_unlink_urb may not be synchronous). + * Note: at this moment the URB completion handler must not resubmit the same URB. + */ +static void qc_usb_kill_urb(struct urb *urb) { + int r; + while ((r=usb_unlink_urb(urb)) == -EBUSY) { + /* The URB is not anymore linked (status!=-EINPROGRESS) but + * usb_unlink_urb() was asynchronous and URB's completion handler still will run */ + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout( (HZ/100)==0 ? 1 : HZ/100); + } + /* if (r!=-EBUSY), + * usb_unlink_urb() called synchronously the completion handler and + * there's no need to wait or anything else */ + if (r) PDEBUG("qc_usb_kill_urb(%p): r=%i", urb, r); +} +#undef usb_kill_urb +#define usb_kill_urb(urb) qc_usb_kill_urb(urb) +/* }}} */ +#endif +/* {{{ [fold] qc_usleep(long usec) */ +void qc_usleep(unsigned long usec) +{ + wait_queue_head_t wq; + init_waitqueue_head(&wq); + interruptible_sleep_on_timeout(&wq, usec*HZ/1000000); +} +/* }}} */ +/* {{{ [fold] int qc_get_i2c(struct quickcam *qc, const struct qc_sensor *sensor, int reg) */ +/* Read a sensor byte or word wide register value via STV0600 I2C bus + * qc_i2c_init() must be called first! + */ +int qc_get_i2c(struct quickcam *qc, const struct qc_sensor *sensor, int reg) +{ + struct usb_device *dev = qc->dev; + int ret; + + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGCAMERA) PDEBUG("qc_get_i2c(qc=%p,sensor=%p,reg=0x%04X)",qc,sensor,reg); + TEST_BUGR(dev==NULL); + if (sizeof(qc->dmabuf)<35) BUG(); + + /* We need here extra write to the STV register before reading the I2C register */ + /* Also wait until there are no pending control URB requests */ + if ((ret = qc_stv_set(qc, STV_REG23, sensor->reg23))<0) goto fail; + + memset(qc->dmabuf, 0, 35); + qc->dmabuf[0] = reg; + qc->dmabuf[0x20] = sensor->i2c_addr; + qc->dmabuf[0x21] = 0; /* 0+1 = 1 value, one byte or word wide register */ + qc->dmabuf[0x22] = 3; /* Read I2C register */ + ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + 0x04, + 0x40, + 0x1400, 0, /* Write I2C register address, 35 bytes */ + qc->dmabuf, 0x23, 3*HZ); + if (ret < 0) goto fail; + ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + 0x04, + 0xC0, + 0x1410, 0, /* Read register contents from I2C, 1 or 2 bytes */ + qc->dmabuf, sensor->length_id, 3*HZ); + if (ret < 0) goto fail; + ret = qc->dmabuf[0]; + if (sensor->length_id>1) ret |= qc->dmabuf[1]<<8; /* Assume LSB is always first from data received via USB */ + if (qcdebug&QC_DEBUGCAMERA) PDEBUG("qc_get_i2c(reg=0x%04X) = %04X", reg, ret); + return ret; + +fail: PDEBUG("qc_get_i2c failed, code=%i",ret); + return ret; +} +/* }}} */ +/* {{{ [fold] int qc_stv_set(struct quickcam *qc, unsigned short reg, unsigned char val) */ +/* + * Set one byte register in the STV-chip. qc_i2c_init() must be called first! + */ +int qc_stv_set(struct quickcam *qc, unsigned short reg, unsigned char val) +{ + int ret; + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGCAMERA) PDEBUG("qc_stv_set(qc=%p,reg=0x%04X,val=%u)",qc,(int)reg,(int)val); + TEST_BUGR(qc==NULL); + if (sizeof(qc->dmabuf)<1) BUG(); + qc_i2c_wait(qc); /* Wait until no pending commands from qc_i2c_* */ + qc->dmabuf[0] = val; + ret = usb_control_msg(qc->dev, usb_sndctrlpipe(qc->dev, 0), + 0x04, /* Request */ + 0x40, /* RequestType */ + reg, 0, /* Value, Index */ + qc->dmabuf, 1, 3*HZ); + if ((qcdebug&QC_DEBUGERRORS || qcdebug&QC_DEBUGLOGIC) && ret<0) PDEBUG("Failed qc_stv_set()=%i", ret); + if (ret<0) return ret; + return 0; +} +/* }}} */ +/* {{{ [fold] int qc_stv_get(struct quickcam *qc, unsigned short reg) */ +/* + * Read one byte register in the STV-chip. qc_i2c_init() must be called first! + * Return the unsigned register value or negative error code on error. + */ +int qc_stv_get(struct quickcam *qc, unsigned short reg) +{ + int ret; + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGCAMERA) PDEBUG("qc_stv_get(qc=%p,reg=0x%04X)",qc,(int)reg); + TEST_BUGR(qc==NULL); + if (sizeof(qc->dmabuf)<1) BUG(); + qc_i2c_wait(qc); /* Wait until no pending commands from qc_i2c_* */ + ret = usb_control_msg(qc->dev, usb_rcvctrlpipe(qc->dev, 0), + 0x04, /* Request */ + 0xC0, /* RequestType */ + reg, 0, /* Value, Index */ + qc->dmabuf, 1, 3*HZ); + if ((qcdebug&QC_DEBUGERRORS || qcdebug&QC_DEBUGLOGIC) && ret<0) PDEBUG("Failed qc_stv_get()=%i", ret); + if (ret<0) return ret; + if (qcdebug&QC_DEBUGCAMERA) PDEBUG("qc_stv_get(reg=0x%04X)=%02X", reg, qc->dmabuf[0]); + return qc->dmabuf[0]; +} +/* }}} */ +/* {{{ [fold] int qc_stv_setw(struct quickcam *qc, unsigned short reg, unsigned short val) */ +/* + * Set two byte register in the STV-chip. qc_i2c_init() must be called first! + * "w" means either "word" or "wide", depending on your religion ;) + */ +int qc_stv_setw(struct quickcam *qc, unsigned short reg, unsigned short val) +{ + int ret; + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGCAMERA) PDEBUG("qc_stv_setw(qc=%p,reg=0x%04X,val=%i)",qc,(int)reg,(int)val); + TEST_BUGR(qc==NULL); + if (sizeof(qc->dmabuf)<2) BUG(); + qc_i2c_wait(qc); + qc->dmabuf[0] = val & 0xFF; + qc->dmabuf[1] = (val >> 8) & 0xFF; + ret = usb_control_msg(qc->dev, usb_sndctrlpipe(qc->dev, 0), + 0x04, + 0x40, + reg, 0, + qc->dmabuf, 2, 3*HZ); + if ((qcdebug&QC_DEBUGERRORS || qcdebug&QC_DEBUGLOGIC) && ret<0) PDEBUG("Failed qc_stv_setw()=%i", ret); + if (ret<0) return ret; + return 0; +} +/* }}} */ +/* {{{ [fold] void qc_hsv2rgb(s16 hue, u16 sat, u16 val, int *red, int *green, int *blue) */ +/* Convert HSI (hue, saturation, intensity) to RGB (red, green, blue). + * All input and output values are 0..65535. + * Hue is actually signed, so it is -32768..32767, but this is equivalent + * since it is the angle around full circle (0=Red, 21845=Green, 43690=Blue). + * Based on libgimp, converted to 16.16 fixed point by tuukkat. + */ +void qc_hsv2rgb(s16 hue, u16 sat, u16 val, int *red, int *green, int *blue) +{ + unsigned int segment, valsat; + signed int h = (u16)hue; + unsigned int s = (sat<32768) ? 0 : (sat-32768)*2; /* 32768 or less = no saturation */ + unsigned int v = val; /* value = intensity */ + unsigned int p; + +#if 1 /* Make common case more efficient */ + if (s == 0) { + *red = v; + *green = v; + *blue = v; + return; + } +#endif + segment = (h + 10923) & 0xFFFF; + segment = segment*3 >> 16; /* 0..2: 0=R, 1=G, 2=B */ + hue -= segment * 21845; /* -10923..10923 */ + h = hue; + h *= 3; + valsat = v*s >> 16; /* 0..65534 */ + p = v - valsat; + if (h>=0) { + unsigned int t = v - (valsat * (32769 - h) >> 15); + switch (segment) { + default: + PDEBUG("hsi2rgb: this can never happen!"); + case 0: /* R-> */ + *red = v; + *green = t; + *blue = p; + break; + case 1: /* G-> */ + *red = p; + *green = v; + *blue = t; + break; + case 2: /* B-> */ + *red = t; + *green = p; + *blue = v; + break; + } + } else { + unsigned int q = v - (valsat * (32769 + h) >> 15); + switch (segment) { + default: + PDEBUG("hsi2rgb: this can never happen!"); + case 0: /* ->R */ + *red = v; + *green = p; + *blue = q; + break; + case 1: /* ->G */ + *red = q; + *green = v; + *blue = p; + break; + case 2: /* ->B */ + *red = p; + *green = q; + *blue = v; + break; + } + } + //PDEBUG("hue=%i sat=%i val=%i segment=%i h=%i r=%i g=%i b=%i",hue,sat,val, segment,h, *red,*green,*blue); +} + +/* }}} */ +/* {{{ [fold] int qc_lock(struct quickcam *qc) */ +/* Takes a lock on quickcam_list_lock and verifies that the given qc is available */ +/* Returns 0 on success in which case the lock must be freed later or negative error code */ +static int qc_lock(struct quickcam *qc) +{ + struct quickcam *q; + + if (down_interruptible(&quickcam_list_lock)) return -ERESTARTSYS; + + /* Search for the device in the list of plugged quickcams (this prevents a race condition) */ + list_for_each_entry(q, &quickcam_list, list) { + if (q == qc) break; /* Found it? */ + } + if (q != qc) { + PDEBUG("can not find the device to open"); + up(&quickcam_list_lock); + return -ENODEV; + } + return 0; +} +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** qc_i2c: I2C URB messaging routines (qc_i2c_*) ************* */ + +/* We have here a quite typical producer-consumer scheme: + * URB interrupt handler routine consumes i2c data, while + * kernel mode processes create more of it. + * Ref: Linux Device Drivers, Alessandro Rubini et al, 2nd edition, pg. 279 + * "Using Circular Buffers" + */ + +static const int qc_i2c_maxbufsize = 0x23; + +/* {{{ [fold] (private) qc_i2c_nextpacket(struct quickcam *qc) */ +/* Fill URB and submit it, if there are more data to send + * Consume data from "commands" array. May be called from interrupt context. + * Return standard error code. + */ +static int qc_i2c_nextpacket(struct quickcam *qc) +{ + struct qc_i2c_data *id = &qc->i2c_data; + struct urb *urb = id->urb; + u8 *tb = urb->transfer_buffer, flags; + struct usb_ctrlrequest *cr = (struct usb_ctrlrequest *)urb->setup_packet; + unsigned int newtail, length, regnum, i, j; + signed int r; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_i2c_nextpacket(quickcam=%p), tail=%i, head=%i, interrupt=%i",qc,id->tail,id->head,(int)in_interrupt()); + IDEBUG_TEST(*id); + + if (!qc->connected) { + /* Device was disconnected, cancel all pending packets and return */ + id->tail = id->head = id->newhead = 0; + id->packets = 0; + return -ENODEV; + } + + newtail = id->tail; /* First data to fetch */ + if (id->packets<=1 && newtail==id->head) { /* packets==0 or 1: no extra URB need to be scheduled */ + if (qcdebug&QC_DEBUGCONTROLURBS) PDEBUG("No more control URBs to send"); + r = 0; + goto nourbs; + } + if (id->packets<=1) { + /* Collect data from circular buffer to URB transfer buffer */ + /* Now id->tail!=id->head: there's at least one packet to send */ + TEST_BUGR(newtail==id->head); + id->packets = 1; + if (GET_PRODUCTID(qc)==0x0850) id->packets = 2; + regnum = 0x0400; + length = qc_i2c_maxbufsize; + + i = 0; /* Transfer buffer position */ + if (!(id->commands[newtail].flags & I2C_FLAG_WORD)) { + /* Normal byte-wide register write */ + if (qcdebug&QC_DEBUGCONTROLURBS) PDEBUG("Setting byte-wide registers"); + do { + tb[i] = id->commands[newtail].regnum; + tb[i+0x10] = id->commands[newtail].loval; + flags = id->commands[newtail].flags; + i++; + newtail = (newtail + 1) % I2C_MAXCOMMANDS; /* Next data to fetch */ + if (flags & I2C_FLAG_BREAK) break; /* Start new packet */ + if (newtail == id->head) break; /* No more data? */ + if (i > 0x0F) break; /* Transfer buffer full? */ + if (id->commands[newtail].flags & I2C_FLAG_WORD) break; + } while (TRUE); +/*if (flags&I2C_FLAG_BREAK) PDEBUG("breaking!!!!!!!!!!"); +{ +int mm; +for(mm=0;mmcommands[newtail].regnum; + tb[i*2+0x10] = id->commands[newtail].loval; + tb[i*2+0x11] = id->commands[newtail].hival; + flags = id->commands[newtail].flags; + i++; + newtail = (newtail + 1) % I2C_MAXCOMMANDS; /* Next data to fetch */ + if (flags & I2C_FLAG_BREAK) break; /* Start new packet */ + if (newtail == id->head) break; /* No more data? */ + if (i > 0x07) break; /* Transfer buffer full? */ + if (!(id->commands[newtail].flags & I2C_FLAG_WORD)) break; + } while (TRUE); + for (j=i*2; j<0x10; j++) tb[j+0x10] = 0; /* Zero out unused register values just to be sure */ + } + for (j=i; j<0x10; j++) tb[j] = 0; /* Zero out unused register addresses just to be sure */ + tb[0x20] = qc->sensor_data.sensor->i2c_addr; + tb[0x21] = i-1; /* Number of commands to send - 1 */ + tb[0x22] = 1; /* Write cmd, 03 would be read. */ + id->tail = newtail; + if (qcdebug&QC_DEBUGCONTROLURBS) PDEBUG("sending i2c packet, cmds=%i, reg0=%02X, val0=%02X",tb[0x21]+1,tb[0],tb[0x10]); + } else { + /* id->packets==2: send extra packet for QuickCam Web */ + if (qcdebug&QC_DEBUGCONTROLURBS) PDEBUG("sending finalization packet"); + id->packets = 1; + regnum = 0x1704; + length = 1; + tb[0] = 1; + } + urb->dev = qc->dev; /* 2.4.x zeroes urb->dev after submission */ + urb->pipe = usb_sndctrlpipe(qc->dev, 0); + urb->transfer_buffer_length = length; + cr->wValue = cpu_to_le16(regnum); + cr->wLength = cpu_to_le16(length); + r = usb_submit_urb(urb,GFP_ATOMIC); + CHECK_ERROR(r<0, nourbs, "Failed qc_i2c_nextpacket()=%i", r); + return 0; + +nourbs: id->packets = 0; /* No more URBs are scheduled */ + wake_up(&id->wq); //FIXME: race condition: now packets=0, so id could be freed and wake_up do oops + return r; +} +/* }}} */ +/* {{{ [fold] (private) qc_i2c_handler(struct urb *urb) */ +/* This is URB completion handler and is called in interrupt context. + * For each submitted URB, this function is guaranteed to be called exactly once. + * This function may not be called reentrantly for the same qc (should be ok, IRQs don't nest). + * It will resubmit the same URB, if + * - The previous URB completed without error + * - Camera is still connected (qc->connected == TRUE) + * - There is still commands to be sent in commands buffer or pid=0x850 and finalization packet is not yet sent. + */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +static void qc_i2c_handler(struct urb *urb, struct pt_regs *ptregs) +#else +static void qc_i2c_handler(struct urb *urb) +#endif +{ + struct quickcam *qc = urb->context; + + if (qcdebug&QC_DEBUGINTERRUPTS) PDEBUG("[INTR] qc_i2c_handler(urb=%p)",urb); + TEST_BUG(urb==NULL); + TEST_BUG(qc==NULL); + IDEBUG_TEST(qc->i2c_data); + if (urb->status<0) { + switch (urb->status) { + default: + /* Seen here: ECONNABORTED 103 Software caused connection abort */ + PRINTK(KERN_ERR,"Unhandled control URB error %i",urb->status); + case -EPROTO: /* Bitstuff error or unknown USB error */ + case -EILSEQ: /* CRC mismatch */ + case -ETIMEDOUT: /* Transfer timed out */ + case -EREMOTEIO: /* Short packet detected */ + case -EPIPE: /* Babble detect or endpoint stalled */ + /* We could try resubmitting the URB here */ + case -ENOENT: /* URB was unlinked */ + case -ENODEV: /* Device was removed */ + case -ECONNRESET: /* Asynchronous unlink, should not happen */ + PRINTK(KERN_ERR,"Control URB error %i",urb->status); + qc->i2c_data.packets = 0; /* Don't schedule more URBs */ + wake_up(&qc->i2c_data.wq); + return; + } + } + qc_i2c_nextpacket(qc); +} +/* }}} */ +/* {{{ [fold] qc_i2c_flush(struct quickcam *qc) */ +/* Allow all register settings set earlier to be scheduled and sent to camera */ +static int qc_i2c_flush(struct quickcam *qc) +{ + struct qc_i2c_data *id = &qc->i2c_data; + int r = 0; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_i2c_flush(quickcam=%p,regs=%i)",qc, + (id->newhead+I2C_MAXCOMMANDS-id->head)%I2C_MAXCOMMANDS); + IDEBUG_TEST(*id); + id->head = id->newhead; + if (id->packets==0) /* Schedule URB if there aren't any in progress */ + r = qc_i2c_nextpacket(qc); + return r; +} +/* }}} */ +/* {{{ [fold] qc_i2c_wait(struct quickcam *qc) */ +/* Wait until all previosly set registers are set or abort all transmissions + * and return error code. + * After this function returns, there will not be uncompleted I2C URBs. + */ +int qc_i2c_wait(struct quickcam *qc) +{ + struct qc_i2c_data *id = &qc->i2c_data; + int r; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_i2c_wait(quickcam=%p)",qc); + TEST_BUGR(in_interrupt()); + TEST_BUGR(qc==NULL); + IDEBUG_TEST(*id); + + if (!qc->connected) goto cancel; + r = qc_i2c_flush(qc); + if (r>=0) r = wait_event_interruptible(id->wq, id->packets==0); + if (r<0) goto cancel; + return 0; + +cancel: if (qcdebug&QC_DEBUGLOGIC) PDEBUG("Canceling pending URB %p, packets=%i", id->urb, id->packets); + PDEBUG("i2c_cancel: qc=%p, id=%p",qc,id); + PDEBUG("i2c_cancel: id->urb=%p", id->urb); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + if (qc->connected) { + PDEBUG("i2c_cancel: id->urb->dev=%p", id->urb->dev); + if (id->urb->dev!=NULL) { + PDEBUG("i2c_cancel: id->urb->dev->bus=%p", id->urb->dev->bus); + if (id->urb->dev->bus!=NULL) { + PDEBUG("i2c_cancel: id->urb->dev->bus->op=%p", id->urb->dev->bus->op); + //PDEBUG("id->urb->dev->bus->op->unlink=%p", id->urb->dev->bus->op->unlink); + } + } + } +#endif + /* Cancel URB if it is in progress or in completion handler */ + if (id->packets > 0) usb_kill_urb(id->urb); + TEST_BUGR_MSG(id->packets!=0, "i2c_wait: packets=%i", id->packets); + return 0; +} +/* }}} */ +/* {{{ [fold] (private) qc_i2c_set0(struct quickcam *qc, unsigned char regnum, unsigned char loval, unsigned char hival, int flags) */ +/* Called from qc_i2c_set and qc_i2c_setw, should not be called elsewhere */ +static int qc_i2c_set0(struct quickcam *qc, unsigned char regnum, unsigned char loval, unsigned char hival, int flags) +{ + struct qc_i2c_data *id = &qc->i2c_data; + unsigned int newhead; + signed int r; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_i2c_set0(quickcam=%p,reg=%02X,val=%02X%02X)",qc,regnum,hival,loval); + TEST_BUGR(qc==NULL); + IDEBUG_TEST(*id); + newhead = id->newhead; + id->commands[newhead].loval = loval; + id->commands[newhead].hival = hival; + id->commands[newhead].regnum = regnum; + id->commands[newhead].flags = flags; + newhead = (newhead + 1) % I2C_MAXCOMMANDS; + if (newhead == id->tail) { /* If buffer is full, wait until it's empty */ + if (qcdebug&QC_DEBUGCONTROLURBS) PDEBUG("i2c buffer is full, waiting"); + r = qc_i2c_wait(qc); + if (r<0) return r; + } + TEST_BUGR(newhead==id->tail); /* no i2c buffer space but nothing to send!!! */ + id->newhead = newhead; + return 0; +} +/* }}} */ +/* {{{ [fold] qc_i2c_set(struct quickcam *qc, unsigned char reg, unsigned char val) */ +/* Set an I2C register to desired value */ +/* (queue setting to be sent later when qc_i2c_flush() is called) */ +inline int qc_i2c_set(struct quickcam *qc, unsigned char reg, unsigned char val) +{ + return qc_i2c_set0(qc, reg, val, 0, 0); +} +/* }}} */ +/* {{{ [fold] qc_i2c_setw(struct quickcam *qc, unsigned char reg, unsigned short val) */ +/* Set a two-byte (word length) I2C register to desired value (queue setting to be sent later) */ +/* (queue setting to be sent later when qc_i2c_flush() is called) */ +inline int qc_i2c_setw(struct quickcam *qc, unsigned char reg, unsigned short val) +{ + return qc_i2c_set0(qc, reg, val & 0xFF, (val >> 8) & 0xFF, I2C_FLAG_WORD); +} +/* }}} */ +/* {{{ [fold] qc_i2c_break(struct quickcam *qc) */ +/* The next register written will be sent in another packet */ +int qc_i2c_break(struct quickcam *qc) +{ + struct qc_i2c_data *id = &qc->i2c_data; + unsigned int prevhead; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_i2c_break(quickcam=%p)",qc); + TEST_BUGR(qc==NULL); + IDEBUG_TEST(*id); + /* We access an entry that may be already submitted and even finished */ + /* But it should not harm */ + prevhead = (id->newhead + I2C_MAXCOMMANDS - 1) % I2C_MAXCOMMANDS; + id->commands[prevhead].flags |= I2C_FLAG_BREAK; + barrier(); + return qc_i2c_flush(qc); +} +/* }}} */ +/* {{{ [fold] qc_i2c_init(struct quickcam *qc) */ +/* Initialize structures and hardware for I2C communication */ +static int qc_i2c_init(struct quickcam *qc) +{ + struct qc_i2c_data *id = &qc->i2c_data; + struct urb *urb; + struct usb_ctrlrequest *cr; + int r = -ENOMEM; + + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_i2c_init(quickcam=%p)",qc); + TEST_BUGR(qc==NULL); + + id->tail = id->head = id->newhead = 0; /* Next position to be filled and sent is 0 */ + id->packets = 0; + init_waitqueue_head(&id->wq); + + /* Allocate an URB and associated buffers and fill them */ + urb = id->urb = usb_alloc_urb(0,GFP_KERNEL); + if (!urb) goto fail1; + cr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); + urb->setup_packet = (unsigned char *)cr; + if (!cr) goto fail2; + urb->transfer_buffer = kmalloc(qc_i2c_maxbufsize*sizeof(u8), GFP_KERNEL); /* Allocate maximum ever needed */ + if (!urb->transfer_buffer) goto fail3; + urb->complete = qc_i2c_handler; + urb->context = qc; +#if (LINUX_VERSION_CODEtimeout = 3*HZ; /* 1 s */ +#endif + cr->bRequestType = 0x40; + cr->bRequest = 0x04; + cr->wIndex = 0; + IDEBUG_INIT(*id); + return 0; + +fail3: kfree(cr); +fail2: usb_free_urb(urb); + POISON(id->urb); +fail1: return r; +} +/* }}} */ +/* {{{ [fold] qc_i2c_exit(struct quickcam *qc) */ +/* Close messaging, free up memory, stop messaging */ +static void qc_i2c_exit(struct quickcam *qc) +{ + struct qc_i2c_data *id = &qc->i2c_data; + + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_i2c_exit(qc=%p)",qc); + TEST_BUG(qc==NULL); + qc_i2c_wait(qc); + kfree(id->urb->setup_packet); + kfree(id->urb->transfer_buffer); + POISON(id->urb->setup_packet); + POISON(id->urb->transfer_buffer); + usb_free_urb(id->urb); + IDEBUG_EXIT(*id); +} +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** qc_proc: /proc interface *********************************** */ +#if HAVE_PROCFS + +static struct proc_dir_entry *qc_proc_entry = NULL; /* Initialization should not be necessary, but just in case... */ + +/* {{{ [fold] qc_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data) */ +static inline const char *qc_proc_yesno(Bool b) +{ + return b ? "Yes" : "No"; +} + +static int qc_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + struct quickcam *qc = data; + char *out = page; + int len; + + if (qc_lock(qc) < 0) return 0; + + out += sprintf(out, "\tGeneral driver status\n"); + out += sprintf(out, "Driver version : %s\n", VERSION); + out += sprintf(out, "Kernel version : %s\n", UTS_RELEASE); + if (qc->dev!=NULL) { + out += sprintf(out, "Device Id : %04X:%04X\n", (int)GET_VENDORID(qc), (int)GET_PRODUCTID(qc)); + out += sprintf(out, "USB bus number : %i\n", qc->dev->bus->busnum); + } + out += sprintf(out, "Users : %i\n", qc->users); + out += sprintf(out, "Connected : %s\n", qc_proc_yesno(qc->connected)); + + out += sprintf(out, "\n\tPicture settings set by user\n"); + out += sprintf(out, "Brightness : %d\n", (int)qc->vpic.brightness); + out += sprintf(out, "Hue : %d\n", (int)qc->vpic.hue); + out += sprintf(out, "Color : %d\n", (int)qc->vpic.colour); + out += sprintf(out, "Contrast : %d\n", (int)qc->vpic.contrast); + out += sprintf(out, "Whiteness : %d\n", (int)qc->vpic.whiteness); + if (qc->users > 0) { + out += sprintf(out, "Depth : %d\n", (int)qc->vpic.depth); + out += sprintf(out, "Palette : %s\n", qc_fmt_getname(qc->vpic.palette)); + } + + if (qc->users > 0) { + out += sprintf(out, "\n\tOutput window\n"); + out += sprintf(out, "Width : %d\n", (int)qc->vwin.width); + out += sprintf(out, "Height : %d\n", (int)qc->vwin.height); + } + + out += sprintf(out, "\n\tSensor\n"); + out += sprintf(out, "Type : %s\n", qc->sensor_data.sensor->name); + out += sprintf(out, "Manufacturer : %s\n", qc->sensor_data.sensor->manufacturer); + if (qc->users > 0) { + out += sprintf(out, "Maximum width : %d\n", qc->sensor_data.maxwidth); + out += sprintf(out, "Maximum height : %d\n", qc->sensor_data.maxheight); + out += sprintf(out, "Current width : %d\n", qc->sensor_data.width); + out += sprintf(out, "Current height : %d\n", qc->sensor_data.height); + } + + out += sprintf(out, "\n\tI2C command stream\n"); + out += sprintf(out, "Scheduled packets: %d\n", qc->i2c_data.packets); + out += sprintf(out, "Packets on queue : %d\n", (I2C_MAXCOMMANDS + qc->i2c_data.head - qc->i2c_data.tail) % I2C_MAXCOMMANDS); + + if (qc->users > 0) { + out += sprintf(out, "\n\tIsochronous data stream\n"); + out += sprintf(out, "Stream enabled : %s\n", qc_proc_yesno(qc->isoc_data.streaming)); + out += sprintf(out, "Transfer errors : %d\n", qc->isoc_data.errorcount); + + out += sprintf(out, "\n\tFrame buffering\n"); + out += sprintf(out, "Frames on queue : %d\n", (FRAME_BUFFERS + qc->frame_data.head - qc->frame_data.tail) % FRAME_BUFFERS); + out += sprintf(out, "Capturing : %s\n", qc_proc_yesno(qc->stream_data.capturing)); + out += sprintf(out, "Waiting processes: %d\n", qc->frame_data.waiting); + } + + out += sprintf(out, "\n\tAutomatic exposure control\n"); + out += sprintf(out, "Picture intensity: %d\n", qc->adapt_data.oldmidvalue); + out += sprintf(out, "Exposure setting : %d\n", qc->adapt_data.exposure); + out += sprintf(out, "Gain setting : %d\n", qc->adapt_data.gain); + out += sprintf(out, "Delta value : %d\n", qc->adapt_data.olddelta); + out += sprintf(out, "Control algorithm: "); + switch (qc->adapt_data.controlalg) { + case EXPCONTROL_SATURATED: out += sprintf(out, "Saturated\n"); break; + case EXPCONTROL_NEWTON: out += sprintf(out, "Newton\n"); break; + case EXPCONTROL_FLOAT: out += sprintf(out, "Float\n"); break; + default: out += sprintf(out, "?\n"); break; + } + + out += sprintf(out, "\n\tDefault settings\n"); + out += sprintf(out, "Debug : 0x%02X\n", qcdebug); + out += sprintf(out, "Keep settings : %s\n", qc_proc_yesno(qc->settings.keepsettings)); + out += sprintf(out, "Settle max frames: %i\n", qc->settings.settle); + out += sprintf(out, "Subsampling : %s\n", qc_proc_yesno(qc->settings.subsample)); + out += sprintf(out, "Compress : %s\n", qc_proc_yesno(qc->settings.compress)); + out += sprintf(out, "Frame skipping : %i\n", qc->settings.frameskip); + out += sprintf(out, "Image quality : %i\n", qc->settings.quality); + out += sprintf(out, "Adaptive : %s\n", qc_proc_yesno(qc->settings.adaptive)); + out += sprintf(out, "Equalize : %s\n", qc_proc_yesno(qc->settings.equalize)); + out += sprintf(out, "User lookup-table: %s\n", qc_proc_yesno(qc->settings.userlut)); + out += sprintf(out, "Retryerrors : %s\n", qc_proc_yesno(qc->settings.retryerrors)); + out += sprintf(out, "Compatible 16x : %s\n", qc_proc_yesno(qc->settings.compat_16x)); + out += sprintf(out, "Compatible DblBuf: %s\n", qc_proc_yesno(qc->settings.compat_dblbuf)); + out += sprintf(out, "Compatible ToRgb : %s\n", qc_proc_yesno(qc->settings.compat_torgb)); + + up(&quickcam_list_lock); + + len = out - page; + len -= off; + if (len < count) { + *eof = 1; + if (len <= 0) return 0; + } else + len = count; + *start = page + off; + return len; +} +/* }}} */ +/* {{{ [fold] qc_proc_write(struct file *file, const char *buffer, unsigned long count, void *data) */ +static int qc_proc_write(struct file *file, const char *buffer, unsigned long count, void *data) +{ + /* we don't support this....yet? Might replace qcset some day */ + return -EINVAL; +} +/* }}} */ +/* {{{ [fold] qc_proc_create(struct quickcam *qc) */ +/* Called for each camera plugged in, create file containing information of the camera */ +static int qc_proc_create(struct quickcam *qc) +{ + char name[9]; + struct proc_dir_entry *entry; + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_proc_create(quickcam=%p)",qc); + TEST_BUGR(!qc); + qc->proc_entry = NULL; + if (qc_proc_entry==NULL) return -ENOTDIR; + sprintf(name, "video%d", qc->vdev.minor); + entry = create_proc_entry(name, S_IFREG | S_IRUGO | S_IWUSR, qc_proc_entry); + if (!entry) { + PRINTK(KERN_WARNING,"Could not register procfs file entry"); + return -ENXIO; + } + entry->owner = THIS_MODULE; + entry->data = qc; + entry->read_proc = qc_proc_read; + entry->write_proc = qc_proc_write; + qc->proc_entry = entry; + return 0; +} +/* }}} */ +/* {{{ [fold] qc_proc_destroy(struct quickcam *qc) */ +/* qc_proc_destroy may be called after qc_proc_create for given quickcam even if it failed */ +static void qc_proc_destroy(struct quickcam *qc) +{ + char name[9]; + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_proc_destroy(quickcam=%p)",qc); + TEST_BUG(!qc); + if (!qc->proc_entry) return; + TEST_BUG(!qc_proc_entry); + sprintf(name, "video%d", qc->vdev.minor); + remove_proc_entry(name, qc_proc_entry); + POISON(qc->proc_entry); + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_proc_destroy() done"); +} +/* }}} */ +/* {{{ [fold] qc_proc_init(void) */ +/* Called when the driver is initially loaded, creates "/proc/video/quickcam" subdirectory */ +static int qc_proc_init(void) +{ + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_proc_init()"); + qc_proc_entry = create_proc_entry(qc_proc_name, S_IFDIR, NULL); /* Create /proc/video/quickcam */ + if (!qc_proc_entry) { + /* create_proc_entry failed, possibly because /proc/video is missing (patch by aceJacek ) */ + proc_mkdir("video", NULL); /* Might fail, if the directory already exists, but we don't care */ + qc_proc_entry = create_proc_entry(qc_proc_name, S_IFDIR, NULL); + if (!qc_proc_entry) { + PRINTK(KERN_WARNING,"Could not register procfs dir entry"); + return -ENXIO; + } + } + qc_proc_entry->owner = THIS_MODULE; + return 0; +} +/* }}} */ +/* {{{ [fold] qc_proc_exit(void) */ +/* Can be called after qc_proc_init() even if it has failed, in which case this does nothing */ +static void qc_proc_exit(void) +{ + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_proc_exit()"); + if (!qc_proc_entry) return; + remove_proc_entry(qc_proc_name, NULL); + POISON(qc_proc_entry); +} +/* }}} */ + +#else +static inline int qc_proc_create(struct quickcam *qc) { return 0; } +static inline void qc_proc_destroy(struct quickcam *qc) { } +static inline int qc_proc_init(void) { return 0; } +static inline void qc_proc_exit(void) { } +#endif /* HAVE_PROCFS */ +/* }}} */ +/* {{{ [fold] **** qc_adapt: Automatic exposure control ************************ */ + +#define MEASURE_ADAPT_DELAY 0 /* Measure adaptation delay, only for test purposes */ + +/* {{{ [fold] qc_adapt_init(struct quickcam *qc) */ +/* Initialize automatic exposure control structure. */ +static int qc_adapt_init(struct quickcam *qc) +{ + struct qc_adapt_data *ctrl = &qc->adapt_data; + ctrl->gain = 32768; + ctrl->olddelta = 4*256; /* best guess */ + ctrl->exposure = 32768; + ctrl->oldexposure = ctrl->exposure + 1; /* Slightly different for _issettled() */ + ctrl->midvaluesum = ctrl->oldmidvalue = 0; + ctrl->framecounter = 0; + ctrl->controlalg = EXPCONTROL_SATURATED; + IDEBUG_INIT(*ctrl); + return 0; +} +/* }}} */ +/* {{{ [fold] qc_adapt_exit(struct quickcam *qc) */ + +static inline void qc_adapt_exit(struct quickcam *qc) +{ +#ifdef DEBUG + struct qc_adapt_data *ctrl = &qc->adapt_data; + if (qcdebug&QC_DEBUGINIT) PDEBUG("qc_adapt_exit(ctrl=%p)",ctrl); + IDEBUG_EXIT(*ctrl); +#endif +} + +/* }}} */ +/* {{{ [fold] qc_adapt_reset(struct quickcam *qc) */ +/* Must be called each time just before starting video adaptation */ +static inline void qc_adapt_reset(struct quickcam *qc) +{ + IDEBUG_TEST(qc->adapt_data); + if (!qc->settings.keepsettings) { + IDEBUG_EXIT(qc->adapt_data); + qc_adapt_init(qc); + } +} +/* }}} */ +/* {{{ [fold] qc_adapt_hassettled(struct quickcam *qc) */ +/* Return TRUE if the image brightness has settled */ +static inline Bool qc_adapt_hassettled(struct quickcam *qc) +{ + struct qc_adapt_data *ctrl = &qc->adapt_data; + IDEBUG_TEST(*ctrl); + if (ctrl->framecounter != 0) return FALSE; +//PDEBUG("control=%i oldexp=%i exp=%i",ctrl->controlalg,ctrl->oldexposure,ctrl->exposure); + return ctrl->controlalg==EXPCONTROL_FLOAT || ctrl->oldexposure==ctrl->exposure; +} +/* }}} */ +/* {{{ [fold] qc_adapt(struct quickcam *qc, int midvalue, int target, int *ret_exposure, int *ret_gain) */ + +/* Set image exposure and gain so that computed midvalue approaches the target value. + * midvalue = average pixel intensity on image 0..255 + * target = user settable preferable intensity 0..255 + * *ret_exposure = the exposure value to use for the camera, 0..65535 + * *ret_gain = the gain to use for the camera, 0..65535. + */ +static void qc_adapt(struct quickcam *qc, int midvalue, int target, int *ret_exposure, int *ret_gain) +{ +#if !MEASURE_ADAPT_DELAY + struct qc_adapt_data *ctrl = &qc->adapt_data; + /* Here are some constant for controlling the adaptation algorithm. You may play with them. */ + static const int saturation_min = 32; /* (0-127) If midvalue is out of this range, image is */ + static const int saturation_max = 256 - 8; /* (128-255) considered saturated and no Newton is used */ + + static const int adaptation_min = 5; /* (0-128) For small variations, do not change exposure */ + + static const int delta_min = 256/2; /* (2-16*256) Minimum and maximum value for delta */ + static const int delta_max = 256*256; /* (4*256-1024*256) */ + + static const int dmidvalue_min = 400; /* (1-128) Minimum differences, under which delta estimation (FIXME:disabled by changing values very big) */ + static const int dexposure_min = 400; /* (1-32000) will not be done due to inaccuracies */ + + static const int delta_speed = 256; /* (0-256) How fast or slowly delta can change */ + static const int small_adapt = 4; /* (0-1024) When very near optimal, exposure change size */ + static const int underestimate = 16; /* (0-250) Underestimation, may prevent oscillation */ + static const int bestguess = 256/2; /* (2-1024*256) If delta can not be computed, guess this */ + static const int midvalueaccum = 2; /* (1-100) How many frames to use for midvalue averaging */ + static const int framedelay = 5; /* (0-8) How many frames there are before a new exposure setting in effect */ + /* With QuickCam Web: if set at frame #0, it will be in effect at frame #4; skip 3 frames #1,#2,#3 */ + /* -> should be 3 with QuickCam Web, but it oscillates, FIXME:why? Setting to 4 fixes this */ + static const int gainstep = 256; /* (0-32768) Amount to change gain at one step */ + static const int gainneeded = 10; /* (0-255) How eagerly to change brightness with gain */ + /* End of tunable constants */ + + int newexposure, delta=0; + int dexposure=0, dmidvalue=0; + int deviation=0; /* Deviation of actual brightness from target brightness */ + int smoothdelta=0; /* Final, smoothed, value of delta */ + + TEST_BUG(ctrl==NULL || ret_gain==NULL || ret_exposure==NULL); + IDEBUG_TEST(*ctrl); + + if (ctrl->framecounter >= framedelay) + ctrl->midvaluesum += midvalue; + ctrl->framecounter++; + if (ctrl->framecounter < framedelay+midvalueaccum) { + *ret_exposure = ctrl->exposure; + *ret_gain = ctrl->gain; + return; + } + + midvalue = ctrl->midvaluesum / midvalueaccum; + ctrl->framecounter = 0; + ctrl->midvaluesum = 0; + + if (ctrl->exposure >= qc->sensor_data.sensor->adapt_gainhigh && + ctrl->oldexposure >= qc->sensor_data.sensor->adapt_gainhigh && + target - ctrl->oldmidvalue > gainneeded && + target - midvalue > gainneeded) + { + /* Exposure is at maximum, but image is still too dark. Increase gain.*/ + ctrl->gain = ctrl->gain + ctrl->gain/2 + gainstep; + if (ctrl->gain > 65535) ctrl->gain = 65535; + if (qcdebug&QC_DEBUGADAPTATION) PDEBUG("increasing gain to %i", ctrl->gain); + } else + if (ctrl->exposure <= qc->sensor_data.sensor->adapt_gainlow && + ctrl->oldexposure <= qc->sensor_data.sensor->adapt_gainlow && + target - ctrl->oldmidvalue <= gainneeded && + target - midvalue <= gainneeded) + { + /* Decrease gain if unnecessarily high */ + ctrl->gain = ctrl->gain - ctrl->gain/2 - gainstep; + if (ctrl->gain < 0) ctrl->gain = 0; + if (qcdebug&QC_DEBUGADAPTATION) PDEBUG("decreasing gain to %i", ctrl->gain); + } + + if (ctrl->oldmidvaluecontrolalg = EXPCONTROL_SATURATED; + newexposure = ctrl->exposure * 2; + } else + if (ctrl->oldmidvalue>=saturation_max || midvalue>=saturation_max) { + /* Image is oversaturated, Newton method would give inaccurate results */ + if (qcdebug&QC_DEBUGADAPTATION) PDEBUG("Decreasing exposure"); + ctrl->controlalg = EXPCONTROL_SATURATED; + newexposure = ctrl->exposure / 2; + } else { + deviation = target - midvalue; + if (ABS(deviation) < adaptation_min) { + /* For small variations, adapt linearly */ + if (qcdebug&QC_DEBUGADAPTATION) PDEBUG("Small deviation %i",deviation); + ctrl->controlalg = EXPCONTROL_FLOAT; + newexposure = small_adapt * SGN(deviation) + ctrl->exposure; + } else { + /* Try using Newton method for estimating correct exposure value */ + ctrl->controlalg = EXPCONTROL_NEWTON; + dmidvalue = midvalue - ctrl->oldmidvalue; + dexposure = ctrl->exposure - ctrl->oldexposure; + if (ABS(dmidvalue) < dmidvalue_min || + ABS(dexposure) < dexposure_min || + SGN(dmidvalue) != SGN(dexposure)) + { + /* Can not estimate delta with Newton method, just guess */ + if (ctrl->olddelta < 2) { + if (qcdebug&QC_DEBUGADAPTATION) PDEBUG("Best guessing"); + smoothdelta = bestguess; + } else { + Bool cross = SGN(midvalue-target) != SGN(ctrl->oldmidvalue-target); + smoothdelta = cross ? (ctrl->olddelta / 2) : (ctrl->olddelta * 3 / 2); + if (qcdebug&QC_DEBUGADAPTATION) PDEBUG("Change more exposure, smoothdelta=%i",smoothdelta); + } + } else { + /* Everything is well, use here actual Newton method */ + delta = (256 - underestimate) * dexposure / dmidvalue; + smoothdelta = (delta_speed*delta + (256-delta_speed)*ctrl->olddelta) / 256; + if (qcdebug&QC_DEBUGADAPTATION) PDEBUG("Using Newton, delta=%i",delta); + } + } + /* Compute new exposure based on guessed/computed delta */ + smoothdelta = CLIP(smoothdelta, delta_min,delta_max); + dexposure = deviation * smoothdelta / 256; + /* Newton works linearly, but exposure/brightness are not linearly related */ + /* The following test fixes the worst deficiencies due to that (I hope) */ + if (-dexposure > ctrl->exposure/2) + dexposure = -ctrl->exposure/2; + newexposure = dexposure + ctrl->exposure; + ctrl->olddelta = smoothdelta; + } + + newexposure = CLIP(newexposure, 2,65535); + + if (qcdebug&QC_DEBUGADAPTATION) + PDEBUG("midval=%i dev=%i dmidv=%i dexp=%i smdelta=%i olddelta=%i newexp=%i gain=%i", + midvalue,deviation,dmidvalue,dexposure,smoothdelta,ctrl->olddelta,newexposure,ctrl->gain); + + ctrl->oldexposure = ctrl->exposure; + ctrl->exposure = newexposure; + ctrl->oldmidvalue = midvalue; + *ret_exposure = newexposure; + *ret_gain = ctrl->gain; +#else + /* This code is for measuring the delay between an exposure settings and until + * it becomes in effect. Only useful for developing the adaptation algorithm. */ + /* Some delays: when a setting is changed at frame number #0, + * it becomes in effect in frame xx for exposure gain + * QuickCam Web/0850/normal mode 4 4 + * QuickCam Web/0850/compressed mode 5 5 + * QuickCam Express/840 2 1-5 + * + */ + static int exp = 0; + static int gain = 0; + static const int changedel = 20; + static int state = 0; + static int framenum = 0; + PRINTK(KERN_CRIT,"Measuring: framenum=%i, midvalue=%i",framenum,midvalue); + if ((framenum%changedel)==0) { + switch (state) { + default: + case 0: + PRINTK(KERN_CRIT,"Measuring: set to black"); + exp = 0; + gain = 0; + break; + case 1: + PRINTK(KERN_CRIT,"Measuring: changing exposure"); + exp = 65535; + break; + case 2: + PRINTK(KERN_CRIT,"Measuring: changing gain"); + gain = 32535; + break; + } + state = ((state+1) % 3); + } + *ret_exposure = exp; + *ret_gain = gain; + framenum++; +#endif +} + +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** qc_frame: Frame capturing functions ************************* */ + +/* From /usr/src/linux/Documentation/smp.tex: + * + Kernel mode process (e.g. system calls): + * - No other kernel mode processes may run simultaneously/pre-empt + * (kernel mode processes are atomic with respect to each other) + * (Does not hold for 2.6.x) + * - Exception is voluntary sleeping, in which case re-entry is allowed + * (Does not hold for 2.6.x) + * - Interrupts may pre-empt (but return to same process) + * (interrupts can be disabled if necessary) + * + Interrupt mode execution + * - Kernel mode process may not pre-empt/execute simultaneously + * - Other interrupts may pre-empt, however same interrupt is not nested + */ + +/* We have here a quite typical producer-consumer scheme: + * Interrupt routine produces more frame data, while + * kernel mode processes consume it + * Read: Linux Device Drivers, Alessandro Rubini et al, 2nd edition, pg. 279 + * "Using Circular Buffers" + */ + +/* Initialization and cleanup routines, called from kernel mode processes */ +/* {{{ [fold] qc_frame_init(struct quickcam *qc) */ +static int qc_frame_init(struct quickcam *qc) +{ + struct qc_frame_data *fd = &qc->frame_data; + int n; + + if (qcdebug&QC_DEBUGFRAME || qcdebug&QC_DEBUGINIT) PDEBUG("qc_frame_init(qc=%p)",qc); + TEST_BUGR(qc==NULL || fd==NULL); + TEST_BUGR(in_interrupt()); + fd->rawdatabuf = vmalloc(FRAME_DATASIZE * FRAME_BUFFERS); + if (!fd->rawdatabuf) return -ENOMEM; + memset(fd->rawdatabuf, 0, FRAME_DATASIZE * FRAME_BUFFERS); /* Never let user access random kernel data */ + fd->head = 0; /* First buffer to fill */ + fd->tail = 0; /* First buffer to get */ + spin_lock_init(&fd->tail_lock); + fd->tail_in_use= FALSE; + init_waitqueue_head(&fd->wq); + fd->waiting = 0; + fd->exiting = FALSE; + for (n=0; nbuffers[n].rawdatalen = 0; + fd->lost_frames = 0; + IDEBUG_INIT(*fd); + return 0; +} +/* }}} */ +/* {{{ [fold] qc_frame_exit(struct quickcam *qc) */ +/* This function must be called with qc->lock acquired + * (it may release it temporarily and sleep) */ +static void qc_frame_exit(struct quickcam *qc) +{ + struct qc_frame_data *fd = &qc->frame_data; +#if PARANOID + unsigned long startjiffy = jiffies; +#endif + if (qcdebug&QC_DEBUGFRAME || qcdebug&QC_DEBUGINIT) PDEBUG("qc_frame_exit(qc=%p,tail=%i,head=%i)",qc,fd->tail,fd->head); + TEST_BUG(in_interrupt()); + TEST_BUG(qc==NULL || fd==NULL); + fd->exiting = TRUE; + fd->maxrawdatalen = 0; /* Hopefully stops all ongoing captures, might need locking though */ + wake_up(&fd->wq); + if (qcdebug&QC_DEBUGFRAME) PDEBUG("waiting=%i",fd->waiting); + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(%p) in qc_frame_exit() : %i", qc, sem_getcount(&qc->lock)); + up(&qc->lock); /* The lock was down when entering this function */ + while (fd->waiting > 0) { + schedule(); +#if PARANOID + if (jiffies-startjiffy > 60*HZ) { + PRINTK(KERN_CRIT,"Wait queue never completing!! (waiting=%i)",fd->waiting); + break; + } +#endif + } + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("down(%p) in qc_frame_exit() : %i", qc, sem_getcount(&qc->lock)); + down(&qc->lock); + vfree(fd->rawdatabuf); + POISON(fd->rawdatabuf); + IDEBUG_EXIT(*fd); +} +/* }}} */ + +/* Consumer routines, called from kernel mode processes */ +/* {{{ [fold] qc_frame_get(struct quickcam *qc, unsigned char **buf) */ +/* Wait until next frame is ready and return the frame length + * and set buf to point to the frame. If error happens, + * return standard Linux negative error number. + * qc_frame_free() must be called after the frame is not needed anymore. + * qc->lock must be acquired when entering this routine + * (it may release it temporarily and sleep). + */ +static int qc_frame_get(struct quickcam *qc, unsigned char **buf) +{ + struct qc_frame_data *fd = &qc->frame_data; + int ret; + + TEST_BUGR(qc==NULL || fd==NULL || fd->tail_in_use); + TEST_BUGR(in_interrupt()); + IDEBUG_TEST(*fd); + + /* Wait until the next frame is available */ + if (qcdebug&QC_DEBUGFRAME) PDEBUG("qc_frame_get/consume(qc=%p,tail=%i,head=%i)",qc,fd->tail,fd->head); + fd->waiting++; + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(%p) in qc_frame_get() : %i", qc, sem_getcount(&qc->lock)); + up(&qc->lock); /* Release lock while waiting */ + + ret = wait_event_interruptible(fd->wq, fd->head!=fd->tail || fd->exiting); //FIXME:What if we get -ERESTARTSYS? + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("down(%p) in qc_frame_get() : %i", qc, sem_getcount(&qc->lock)); + down(&qc->lock); + if (!ret) { + if (!fd->exiting) { + unsigned int t; + unsigned long flags; + spin_lock_irqsave(&fd->tail_lock, flags); + fd->tail_in_use = TRUE; + t = fd->tail; + spin_unlock_irqrestore(&fd->tail_lock, flags); + if (qcdebug&QC_DEBUGFRAME) PDEBUG("qc_frame_get/consume(qc=%p,tail=%i,head=%i,tail->rawdatalen=%i), got frame",qc,t,fd->head,fd->buffers[t].rawdatalen); + *buf = fd->rawdatabuf + t*FRAME_DATASIZE; + ret = fd->buffers[t].rawdatalen; + } else { + ret = -ENODATA; + } + } + fd->waiting--; + fd->lost_frames = 0; + if (ret<0 && (qcdebug&(QC_DEBUGERRORS|QC_DEBUGFRAME))) PDEBUG("failed qc_frame_get()=%i",ret); + return ret; +} +/* }}} */ +/* {{{ [fold] qc_frame_free(struct quickcam *qc) */ +/* Free up the last frame returned from qc_frame_get() (it must be called first) */ +static inline void qc_frame_free(struct quickcam *qc) +{ + struct qc_frame_data *fd = &qc->frame_data; + unsigned long flags; + TEST_BUG(qc==NULL || fd==NULL); + TEST_BUG(in_interrupt()); + TEST_BUG(fd->head==fd->tail); /* The current fd->tail is not available to be freed! */ + IDEBUG_TEST(*fd); + if (qcdebug&QC_DEBUGFRAME) PDEBUG("qc_frame_free/consume(qc=%p,tail=%i,head=%i)",qc,fd->tail,fd->head); + /* Free up previous frame and advance to next */ + spin_lock_irqsave(&fd->tail_lock, flags); + fd->tail_in_use = FALSE; + fd->tail = (fd->tail + 1) % FRAME_BUFFERS; + spin_unlock_irqrestore(&fd->tail_lock, flags); +} +/* }}} */ +/* {{{ [fold] qc_frame_test(struct quickcam *qc) */ +/* Return TRUE if next frame is immediately available, FALSE otherwise. */ +static inline Bool qc_frame_test(struct quickcam *qc) +{ + struct qc_frame_data *fd = &qc->frame_data; + IDEBUG_TEST(*fd); + if (qcdebug&QC_DEBUGFRAME) PDEBUG("qc_frame_test/consume(qc=%p,tail=%i,head=%i)",qc,fd->tail,fd->head); + return fd->head != fd->tail; +} +/* }}} */ + +/* Producer routines, called from interrupt context */ +/* {{{ [fold] qc_frame_begin(struct quickcam *qc) */ +/* Begin capturing next frame from camera. If buffer is full, the frame will be lost */ +static void qc_frame_begin(struct quickcam *qc) +{ + struct qc_frame_data *fd = &qc->frame_data; + int framesize, h; + TEST_BUG(qc==NULL || fd==NULL); + IDEBUG_TEST(*fd); + if (qcdebug&QC_DEBUGFRAME) PDEBUG("qc_frame_begin/produce(qc=%p,tail=%i,head=%i)",qc,fd->tail,fd->head); + if (fd->exiting) return; + TEST_BUG(fd->rawdatabuf==NULL); + h = fd->head; + fd->buffers[h].rawdatalen = 0; + + /* Use sensor information to get the framesize (i.e. how much we expect to receive bytes per image) */ + /* FIXME: should compute data size differently in compressed mode */ + framesize = qc->sensor_data.width * qc->sensor_data.height; + fd->maxrawdatalen = MIN(framesize, FRAME_DATASIZE); +} +/* }}} */ +/* {{{ [fold] qc_frame_add(struct quickcam *qc, unsigned char *data, int datalen) */ +/* Store more data for a frame, return nonzero if too much data or other error */ +static int qc_frame_add(struct quickcam *qc, unsigned char *data, int datalen) +{ + struct qc_frame_data *fd = &qc->frame_data; + int h = fd->head; + int bytes; + + TEST_BUGR(qc==NULL || fd==NULL); + IDEBUG_TEST(*fd); + TEST_BUGR(fd->rawdatabuf==NULL); + if (fd->maxrawdatalen <= fd->buffers[h].rawdatalen) { + if (qcdebug&QC_DEBUGERRORS) PDEBUG("buffer disabled, maxrawdatalen=%i rawdatalen=%i datalen=%i",fd->maxrawdatalen,fd->buffers[h].rawdatalen, datalen); + return -EBUSY; + } + bytes = MIN(datalen, fd->maxrawdatalen - fd->buffers[h].rawdatalen); + memcpy(fd->rawdatabuf + h*FRAME_DATASIZE + fd->buffers[h].rawdatalen, data, bytes); + fd->buffers[h].rawdatalen += bytes; + if (bytes < datalen) { + if (qcdebug&QC_DEBUGERRORS) PRINTK(KERN_ERR,"out of buffer space by %i, maxrawdatalen=%i rawdatalen=%i datalen=%i", datalen-bytes,fd->maxrawdatalen,fd->buffers[h].rawdatalen, datalen); + return -ENOSPC; + } + return 0; +} +/* }}} */ +/* {{{ [fold] qc_frame_end(struct quickcam *qc) */ +/* Finished capturing most recent frame from camera */ +/* (may be premature end, in which case some data is missing) */ +static void qc_frame_end(struct quickcam *qc) +{ + static const int minrawdatalen = 32*32; /* If frame length is less than this many bytes, discard it */ + struct qc_frame_data *fd = &qc->frame_data; + unsigned int t, h; + unsigned long flags; + Bool lost_frame; + TEST_BUG(qc==NULL || fd==NULL); + h = fd->head; + if (qcdebug&QC_DEBUGFRAME) PDEBUG("qc_frame_end/produce(qc=%p,tail=%i,head=%i), got %i bytes",qc,fd->tail,h,fd->buffers[h].rawdatalen); + IDEBUG_TEST(*fd); + fd->maxrawdatalen = 0; /* Stop frame data capturing */ +#if DUMPDATA + PDEBUG("frame_end: got %i bytes", fd->buffers[h].rawdatalen); +#endif + if (fd->buffers[h].rawdatalen < minrawdatalen) { + /* No enough data in buffer, don't advance index */ + if (qcdebug&QC_DEBUGERRORS) PDEBUG("discarding frame with only %u bytes", fd->buffers[h].rawdatalen); + return; + } + h = (h + 1) % FRAME_BUFFERS; /* Select next frame buffer to fill */ + + lost_frame = FALSE; + spin_lock_irqsave(&fd->tail_lock, flags); + t = fd->tail; + if (t == h) { + lost_frame = TRUE; + /* FIXME: the below should work fine for two buffers, but not so well for more. It should be possible + * to drop oldest frame even when the current tail is in use. */ + if (fd->tail_in_use) { + /* Can not drop the oldest frame, it is in use. Drop the newest frame */ + h = (h + FRAME_BUFFERS - 1) % FRAME_BUFFERS; /* Decrease head by one back to the original */ + if (qcdebug&QC_DEBUGFRAME) PDEBUG("dropping newest frame"); + } else { + /* Drop the oldest frame */ + fd->tail = (t + 1) % FRAME_BUFFERS; /* Drop the oldest frame away */ + if (qcdebug&QC_DEBUGFRAME) PDEBUG("dropping oldest frame"); + } + } + spin_unlock_irqrestore(&fd->tail_lock, flags); + if (lost_frame) { + if (qcdebug&QC_DEBUGCOMMON || qcdebug&QC_DEBUGFRAME) PRINTK(KERN_NOTICE,"frame lost"); + fd->lost_frames++; + if (fd->lost_frames > 10) { + /* Here we should call qc_isoc_stop() to stop isochronous + * streaming since the application is clearly not reading frames at all. + * However, we are now in interrupt context but qc_isoc_stop() has + * to be in process context... so we can't do that. + * FIXME: add tasklet/bottomhalf/whatever needed to do it. + */ + if (qcdebug&QC_DEBUGFRAME) PDEBUG("too many lost frames: %i", fd->lost_frames); + } + } + fd->head = h; + wake_up(&fd->wq); +} +/* }}} */ +/* {{{ [fold] qc_frame_flush(struct quickcam *qc) */ +/* Reject the current data already captured into buffer and end frame */ +void qc_frame_flush(struct quickcam *qc) +{ + struct qc_frame_data *fd = &qc->frame_data; + unsigned int h = fd->head; + TEST_BUG(qc==NULL || fd==NULL); + IDEBUG_TEST(*fd); + if (qcdebug&QC_DEBUGFRAME) PDEBUG("qc_frame_flush/produce(qc=%p,tail=%i,head=%i), flush %i bytes",qc,fd->tail,h,fd->buffers[h].rawdatalen); + fd->buffers[h].rawdatalen = 0; /* Empty buffer */ + fd->maxrawdatalen = 0; /* Stop frame data capturing */ +} +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** qc_stream: USB datastream processing functions *************** */ + +/* {{{ [fold] qc_stream_init(struct quickcam *qc) */ +/* Initialize datastream processing */ +static int qc_stream_init(struct quickcam *qc) +{ + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_stream_init(quickcam=%p)",qc); + qc->stream_data.capturing = FALSE; + qc->stream_data.frameskip = qc->settings.frameskip; + IDEBUG_INIT(qc->stream_data); + return 0; +} +/* }}} */ +/* {{{ [fold] qc_stream_exit(struct quickcam *qc) */ +/* Stop datastream processing, after this qc_stream_add should not be called */ +static void qc_stream_exit(struct quickcam *qc) +{ + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_stream_exit(quickcam=%p)",qc); + if (qc->stream_data.capturing) + qc_frame_end(qc); + IDEBUG_EXIT(qc->stream_data); +} +/* }}} */ +/* {{{ [fold] qc_stream_error(struct quickcam *qc) */ +/* This is called when there are data lost due to errors in the stream */ +static void qc_stream_error(struct quickcam *qc) +{ + /* Skip rest of data for this frame */ + if (qcdebug&QC_DEBUGERRORS) PDEBUG("qc_stream_error(qc=%p)", qc); + if (qc->stream_data.capturing) + qc_frame_end(qc); + IDEBUG_EXIT(qc->stream_data); + qc_stream_init(qc); +} +/* }}} */ +/* {{{ [fold] qc_stream_add(struct quickcam *qc, unsigned char *data, int datalen) */ +/* + * Analyse an USB packet of the data stream and store it appropriately. + * Each packet contains an integral number of chunks. Each chunk has + * 2-bytes identification, followed by 2-bytes that describe the chunk + * length. Known/guessed chunk identifications are: + * 8001/8005/C001/C005 - Begin new frame + * 8002/8006/C002/C006 - End frame + * 0200/4200 - Contains actual image data, bayer or compressed + * 0005 - 11 bytes of unknown data + * 0100 - 2 bytes of unknown data + * The 0005 and 0100 chunks seem to appear only in compressed stream. + * Return the amount of image data received or negative value on error. + */ +static int qc_stream_add(struct quickcam *qc, unsigned char *data, int datalen) +{ + struct qc_stream_data *sd = &qc->stream_data; + int id, len, error, totaldata = 0; + + IDEBUG_TEST(*sd); + while (datalen) { + if (datalen < 4) { + if (qcdebug&QC_DEBUGBITSTREAM) PRINTK(KERN_ERR,"missing chunk header"); + break; + } + id = (data[0]<<8) | data[1]; + len = (data[2]<<8) | data[3]; + data += 4; + datalen -= 4; + if (datalen < len) { + if (qcdebug&QC_DEBUGBITSTREAM) PRINTK(KERN_ERR,"missing chunk contents"); + break; + } + switch (id) { + case 0x8001: + case 0x8005: + case 0xC001: + case 0xC005: + /* Begin new frame, len should be zero */ + if (PARANOID && len!=0) PDEBUG("New frame: len!=0"); + if (sd->capturing) { + if (qcdebug&QC_DEBUGBITSTREAM) PDEBUG("Missing frame end mark in stream"); + qc_frame_end(qc); + } + sd->capturing = TRUE; + if (--sd->frameskip < 0) sd->frameskip = qc->settings.frameskip; + if (sd->frameskip==0) qc_frame_begin(qc); + break; + case 0x8002: + case 0x8006: + case 0xC002: + case 0xC006: + /* End frame, len should be zero */ + if (PARANOID && len!=0) PDEBUG("End frame: len!=0"); + if (sd->capturing) { + if (sd->frameskip==0) qc_frame_end(qc); + } else { + if (qcdebug&QC_DEBUGBITSTREAM) PDEBUG("Missing frame begin mark in stream"); + } + sd->capturing = FALSE; + break; + case 0x0200: + case 0x4200: + /* Image data */ + if (!sd->capturing && (qcdebug&QC_DEBUGBITSTREAM)) PDEBUG("Chunk of data outside frames!"); + if (sd->capturing && sd->frameskip==0) { + error = qc_frame_add(qc, data, len); + } else { + error = 0; + } + if (error) { + /* If qc_frame_add returns error, there is more data than the frame may have, + * in which case we assume stream is corrupted and skip rest packet */ + if (qcdebug&QC_DEBUGERRORS) PDEBUG("qc_frame_add error %i",error); + } else { + totaldata += len; + } + break; + case 0x0005: + /* Unknown chunk with 11 bytes of data, occurs just before end of each frame in compressed mode */ + if (len==11) break; + case 0x0100: + /* Unknown chunk with 2 bytes of data, occurs 2-3 times per USB interrupt */ + if (len==2) break; + default: + /* Unknown chunk */ + #ifdef DEBUG + if (qcdebug&QC_DEBUGBITSTREAM) { + static char dump[4*1024]; + char *dump_p = dump; + int i; + for (i=0; i= KERNEL_VERSION(2,6,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +static void qc_isoc_handler(struct urb *urb, struct pt_regs *ptregs) +#else +static void qc_isoc_handler(struct urb *urb) +#endif +{ + struct quickcam *qc; + int payload = 0; /* Amount of all data camera sent */ + int totaldata = 0; /* Amount of image data camera sent */ + int i; +#ifdef DEBUG + /* Check for nested interrupts, shouldn't happen */ + volatile static Bool in_progress = FALSE; + TEST_BUG(in_progress); + in_progress = TRUE; +#endif + + if (qcdebug&QC_DEBUGINTERRUPTS) PDEBUG("[INTR] qc_isoc_handler(urb=%p)",urb); + TEST_BUG(urb==NULL); + qc = urb->context; + TEST_BUG(qc==NULL); + IDEBUG_TEST(qc->isoc_data); + + if (!qc->connected || !qc->isoc_data.streaming) { + /* Camera was disconnected or isochronous stream just disabled--must not resubmit urb */ + PDEBUG("Ignoring isoc interrupt, dev=%p streaming=%i status=%i", qc->dev, qc->isoc_data.streaming, urb->status); + goto out; + } + + if (urb->status<0) { + qc->isoc_data.errorcount++; + switch (urb->status) { + case -EXDEV: /* Partially completed, look at individual frame status */ + break; + default: + /* Seen here: -EOVERFLOW (75): Value too large for defined data type */ + case -EPROTO: /* Bitstuff error or unknown USB error */ + case -EILSEQ: /* CRC mismatch */ + case -ETIMEDOUT: /* Transfer timed out */ + case -EREMOTEIO: /* Short packet detected */ + case -EPIPE: /* Babble detect or endpoint stalled */ + case -ECONNRESET: /* Asynchronous unlink, should not happen, but does with 2.6.x */ + if (qcdebug&QC_DEBUGERRORS) PRINTK(KERN_ERR,"isoc URB error %i, resubmitting",urb->status); + goto resubmit; + case -ESHUTDOWN: + case -ENOENT: /* URB was unlinked */ + case -ENODEV: /* Device was removed */ + if (qcdebug&QC_DEBUGERRORS) PRINTK(KERN_ERR,"isoc URB error %i, returning",urb->status); + goto out; + } + } + + for (i=0; inumber_of_packets; i++) { + if ((int)urb->iso_frame_desc[i].status<0) { /* Note that the cast to int MUST be here! */ + if (qcdebug&QC_DEBUGERRORS) PDEBUG("USB transfer error %i", urb->iso_frame_desc[i].status); + qc->isoc_data.errorcount++; + qc_stream_error(qc); + continue; + } + qc->isoc_data.errorcount = 0; + payload += urb->iso_frame_desc[i].actual_length; +#if PARANOID +{ +int xx = urb->iso_frame_desc[i].actual_length; +if (xx>2000) { +PDEBUG("i=%i status=%i transfer_buffer=%p transfer_buffer_length=%i actual_length=%i number_of_packets=%i", + i, urb->status, urb->transfer_buffer, urb->transfer_buffer_length, urb->actual_length, urb->number_of_packets); +PDEBUG("offset=%i length=%i actual_length=%i pstatus=%i", +urb->iso_frame_desc[i].offset, urb->iso_frame_desc[i].length, urb->iso_frame_desc[i].actual_length, urb->iso_frame_desc[i].status); +goto out; +} +} +#endif + totaldata += qc_stream_add(qc, urb->transfer_buffer + urb->iso_frame_desc[i].offset, + urb->iso_frame_desc[i].actual_length); + } + if (qcdebug&QC_DEBUGBITSTREAM) PDEBUG("payload=%i totaldata=%i",payload,totaldata); + if (qcdebug&(QC_DEBUGBITSTREAM|QC_DEBUGERRORS)) if (payload==0) PDEBUG("USB interrupt, but no data received!"); +resubmit: + /* Resubmit URB */ + if (qc->isoc_data.errorcount < ISOC_PACKETS*ISOC_URBS*8) { + urb->dev = qc->dev; /* Required for 2.4.x */ + i = usb_submit_urb(urb,GFP_ATOMIC); + if (i) PDEBUG("failed to resubmit URB, code=%i, dev=%p",i,urb->dev); + } else { + PDEBUG("Too many errors, giving up"); + } +out: +#ifdef DEBUG + in_progress = FALSE; +#endif + return; +} +/* }}} */ +/* {{{ [fold] qc_isoc_start(struct quickcam *qc) */ +/* + * Start USB isochronous image transfer from camera to computer + * (Set USB camera interface and allocate URBs and submit them) + * Sensor must be initialized beforehand (qc_init_sensor) + */ +static int qc_isoc_start(struct quickcam *qc) +{ + struct qc_isoc_data *id = &qc->isoc_data; + int ret = -ENOMEM; /* Return value on error */ + struct urb *urb; + int i, b; + + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_isoc_start(qc=%p)",qc); + TEST_BUGR_MSG(qc==NULL || id==NULL, "qc||id==NULL"); + IDEBUG_TEST(*id); + + if (id->streaming) return 0; /* Already started */ + id->streaming = TRUE; + id->errorcount = 0; + + /* Allocate transfer buffer */ + id->buffer = kmalloc(ISOC_URBS * ISOC_PACKETS * ISOC_PACKET_SIZE, GFP_KERNEL); + CHECK_ERROR(!id->buffer, fail1, "Out of memory allocating id->buffer"); + + /* Allocate URBs, fill them, and put them in the URB array */ + for (b=0; burbs[b] = usb_alloc_urb(ISOC_PACKETS,GFP_KERNEL); /* Zeroes the allocated data up to iso_frame_desc[], *not* including the last! */ + CHECK_ERROR(!urb, fail2, "Out of memory allocating urbs"); + urb->dev = qc->dev; + urb->context = qc; + urb->pipe = usb_rcvisocpipe(qc->dev, QUICKCAM_ISOPIPE); + urb->transfer_flags = URB_ISO_ASAP; /* Leave URB_ASYNC_UNLINK clear and never call usb_unlink_urb() */ + urb->complete = qc_isoc_handler; + urb->number_of_packets = ISOC_PACKETS; + urb->transfer_buffer = id->buffer; + urb->transfer_buffer_length = ISOC_URBS * ISOC_PACKETS * ISOC_PACKET_SIZE; + urb->interval = 1; /* See Table 9-10 of the USB 1.1 specification */ + for (i=0; iiso_frame_desc[i].offset = b*ISOC_PACKETS*ISOC_PACKET_SIZE + i*ISOC_PACKET_SIZE; + urb->iso_frame_desc[i].length = ISOC_PACKET_SIZE; + } + } + + /* Alternate interface 3 is the biggest frame size */ + /* JFC use 1: but do not know why */ + /* QuickCam Web: Interface 0, alternate 1, endpoint 0x81 -tuukkat */ + qc_i2c_wait(qc); /* There must not be control URBs going when calling set_interface() */ + ret = usb_set_interface(qc->dev, qc->iface, 1); + CHECK_ERROR(ret<0, fail3, "set_interface failed"); + + /* Submit URBs */ + for (b=0; burbs[b],GFP_KERNEL); + CHECK_ERROR(ret<0, fail4, "submit urbs failed"); + } + + /* Tell camera to start sending data */ + ret = qc->sensor_data.sensor->start(qc); /* Start current frame */ + CHECK_ERROR(ret<0, fail5, "sensor_data.start failed"); + ret = qc_stv_set(qc, STV_ISO_ENABLE, 1); /* Start isochronous streaming */ + CHECK_ERROR(ret<0, fail6, "qc_stv_set() failed"); + return 0; + + /* Cleanup and return error code on failure */ +fail6: qc->sensor_data.sensor->stop(qc); /* stop current frame. */ +fail5: b = ISOC_URBS; +fail4: while (--b >= 0) usb_kill_urb(id->urbs[b]); + usb_set_interface(qc->dev, qc->iface, 0); /* Set packet size to 0 (Interface 0, alternate 0, endpoint 0x81 -tuukkat) */ +fail3: b = ISOC_URBS; +fail2: while (--b >= 0) usb_free_urb(id->urbs[b]); + kfree(id->buffer); +fail1: if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGERRORS) PDEBUG("failed qc_isoc_init()=%i",ret); + return ret; +} +/* }}} */ +/* {{{ [fold] qc_isoc_stop(struct quickcam *qc) */ +/* + * Stop USB isochronous image transfer from camera to computer + * (Tell camera to stop sending images, set idle USB interface and free URBs) + * There must be no more isochronous transfer interrupts after this returns + * nor any running handlers anymore. + */ +static void qc_isoc_stop(struct quickcam *qc) +{ + struct qc_isoc_data *id = &qc->isoc_data; + int b, r; + + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_isoc_stop(quickcam=%p)",qc); + TEST_BUG_MSG(qc==NULL || id==NULL, "qc||id==NULL"); + IDEBUG_TEST(*id); + + if (!id->streaming) return; /* Already stopped */ + if (qc->connected) { + if ((r=qc_stv_set(qc, STV_ISO_ENABLE, 0))<0) /* stop ISO-streaming. */ + PRINTK(KERN_ERR,"qc_stv_set error %i",r); + if ((r=qc->sensor_data.sensor->stop(qc))<0) /* stop current frame. */ + PRINTK(KERN_ERR,"sensor_data.stop error %i",r); + qc_i2c_wait(qc); /* When calling set_interface(), there must not be control URBs on way */ + if (usb_set_interface(qc->dev, qc->iface, 0) < 0) /* Set packet size to 0 (Interface 0, alternate 0, endpoint 0x81 -tuukkat) */ + PRINTK(KERN_ERR,"usb_set_interface error"); + } + id->streaming = FALSE; /* Ensure that no more isochronous URBs will be submitted from the interrupt handler */ + mb(); + for (b=0; bstatus = %i", b, id->urbs[b]->status); + usb_kill_urb(id->urbs[b]); + usb_free_urb(id->urbs[b]); + POISON(id->urbs[b]); + } + + kfree(id->buffer); + POISON(id->buffer); + return; +} +/* }}} */ +/* {{{ [fold] qc_isoc_init(struct quickcam *qc) */ +/* + * Initialize isochronous streaming functions + */ +static int qc_isoc_init(struct quickcam *qc) +{ + struct qc_isoc_data *id = &qc->isoc_data; + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_isoc_init(quickcam=%p)",qc); + TEST_BUGR_MSG(qc==NULL || id==NULL, "qc||id==NULL"); + IDEBUG_INIT(*id); + id->streaming = FALSE; + return 0; +} +/* }}} */ +/* {{{ [fold] qc_isoc_exit(struct quickcam *qc) */ +/* + * Uninitialize isochronous streaming functions + */ +static inline void qc_isoc_exit(struct quickcam *qc) +{ + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_isoc_exit(quickcam=%p)",qc); + qc_isoc_stop(qc); + IDEBUG_EXIT(qc->isoc_data); +} +/* }}} */ +/* {{{ [fold] Bool qc_isoc_streaming(struct quickcam *qc) */ +static inline Bool qc_isoc_streaming(struct quickcam *qc) +{ + struct qc_isoc_data *id = &qc->isoc_data; + + TEST_BUGR_MSG(qc==NULL || id==NULL, "qc||id==NULL"); + IDEBUG_TEST(*id); + return id->streaming; +} +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** qc_sensor: Common routines for all sensors ******************* */ + +/* {{{ [fold] qc_sensor_setsize0(struct quickcam *qc, unsigned int width, unsigned int height) */ +/* Called when the application requests a specific image size. Should set the + * actual delivered image size to as close to the requested as possible. + * The image size, as delivered from the camera, can be also set to reduce + * required bandwidth, if possible, but it is not necessary. + * This is a private function to qc_sensor_*, other modules should use qc_sensor_setsize() + * If capt is TRUE, then qc_capt_get may be called (and qc_capt_init must be called before). + */ +static int qc_sensor_setsize0(struct quickcam *qc, unsigned int width, unsigned int height, Bool capt) +{ + unsigned char *f; + int r; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_sensor_setsize(qc=%p,width=%i,height=%i)",qc,width,height); + TEST_BUGR_MSG(qc==NULL, "qc==NULL!"); + + if (width < min_framewidth || width > qc->sensor_data.maxwidth) return -EINVAL; + if (height < min_frameheight || height > qc->sensor_data.maxheight) return -EINVAL; + + /* Applications require, when using Xvideo extension, that the + * frame size is multiple of 8. This is a bug in apps or Xvideo. -tuukkat */ + if (qc->settings.compat_16x) { + width = (width /16)*16; + height = (height/16)*16; + } + /* Set the size only if changed */ + if (qc->vwin.width==width && qc->vwin.height==height) return 0; + + /* For HDCS-1000 we must wait for frame before setting size */ + if (capt) qc_capt_get(qc, &f); + + qc->sensor_data.width = width; /* The sensor-specific code may modify these if not suitable */ + qc->sensor_data.height = height; + if ((r = qc->sensor_data.sensor->set_size(qc, width, height))<0) { + PDEBUG("set_size sensor failed"); + return r; + } + + /* Set the closest size we can actually deliver to application */ + qc->vwin.width = width; + qc->vwin.height = height; + if ((r = qc_i2c_wait(qc))<0) return r; + qc_frame_flush(qc); + return 0; +} +/* }}} */ +/* {{{ [fold] qc_sensor_setsize(struct quickcam *qc, unsigned int width, unsigned int height) */ +/* Called when the application requests a specific image size. Should set the + * actual delivered image size to as close to the requested as possible. + * The image size, as delivered from the camera, can be also set to reduce + * required bandwidth, if possible, but it is not necessary. + * qc_isoc_init() and qc_capt_init() have to be called before this function. + */ +static inline int qc_sensor_setsize(struct quickcam *qc, unsigned int width, unsigned int height) +{ + int r; + r = qc_sensor_setsize0(qc, width, height, qc_isoc_streaming(qc)); + return r; +} +/* }}} */ +/* {{{ [fold] qc_sensor_init(struct quickcam *qc) */ +/* + * Initialise sensor. Initializes all data in qc->sensor which is common to all + * types of sensors and calls the sensor-specific initialization routine. + * The Photobit starts the pixel integration immediately after the reset. + * Note: must call qc_i2c_init() and qc_frame_init() before this function! + */ +static int qc_sensor_init(struct quickcam *qc) +{ + int r; + + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_init_sensor(qc=%p)",qc); + TEST_BUGR_MSG(qc==NULL, "qc==NULL!"); + + qc->sensor_data.width = -1; + qc->sensor_data.height = -1; + qc->sensor_data.exposure = -1; + qc->sensor_data.rgain = -1; + qc->sensor_data.ggain = -1; + qc->sensor_data.bgain = -1; + qc->sensor_data.subsample = qc->settings.subsample; + qc->sensor_data.compress = qc->settings.compress; + + if ((r = qc->sensor_data.sensor->init(qc))<0) goto fail; + if ((r = qc_stv_set(qc, STV_ISO_ENABLE, 0))<0) goto fail; /* Stop isochronous streaming */ + if ((r = qc->sensor_data.sensor->stop(qc))<0) goto fail; /* Stop current frame */ + + /* Set capture size */ + qc->vwin.width = 0; /* Set to illegal value (ensures resetting) */ + qc->vwin.height = 0; + if ((r = qc_sensor_setsize0(qc, qc->sensor_data.maxwidth, qc->sensor_data.maxheight, FALSE))<0) goto fail; + + /* Set brightness settings */ + if ((r = qc->sensor_data.sensor->set_levels(qc, qc->vpic.brightness, qc->vpic.contrast, qc->vpic.hue, qc->vpic.colour))<0) goto fail; + if (qc->sensor_data.sensor->set_target!=NULL) + if ((r = qc->sensor_data.sensor->set_target(qc, qc->vpic.brightness))<0) goto fail; + return 0; + +fail: PRINTK(KERN_ERR,"sensor initialization failed: %i",r); + return r; +} +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** qc_capt: User image capturing functions ******************** */ + +/* {{{ [fold] qc_capt_get(struct quickcam *qc, unsigned char **frame) */ +/* Wait until next image is ready and return the image length in bytes + * and set "frame" to point to the image. If error happens, + * return standard Linux negative error number. The image will be in + * palette and size requested by the user (quickcam->vpic,vwin). + */ +static int qc_capt_get(struct quickcam *qc, unsigned char **frame) +{ + struct qc_capt_data *cd = &qc->capt_data; + unsigned char *rawdata=NULL; /* Raw data from camera */ + int rawdatalen; + int retrycount = qc->settings.retryerrors ? 8 : 0; + int settlecount = cd->settled ? 0 : qc->settings.settle; /* If the picture has already settled, do not wait for it again */ + int midvalue; + int r; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_capt_get(quickcam=%p)",qc); + IDEBUG_TEST(*cd); + if ((r = qc_isoc_start(qc))<0) goto fail; /* Start receiving data */ + + do { + r = qc_frame_get(qc, &rawdata); + if (r < 0) goto error; + rawdatalen = r; + r = qc_fmt_convert(qc, rawdata, rawdatalen, cd->frame, MAX_FRAME_SIZE, &midvalue); + if (r < 0) { + qc_frame_free(qc); + goto error; + } + + if (qc->vpic_pending) { + qc->vpic_pending = FALSE; + if (!qc->settings.adaptive) { + /* Set new values now */ + qc->sensor_data.sensor->set_levels(qc, qc->vpic.brightness, qc->vpic.contrast, qc->vpic.hue, qc->vpic.colour); + } else { + if (qc->sensor_data.sensor->set_target!=NULL) + qc->sensor_data.sensor->set_target(qc, qc->vpic.brightness); + } + } + + if (qc->settings.adaptive && !qc->sensor_data.sensor->autoexposure && r>=0 && midvalue>=0) { + int ex = 0, gn = 0; + qc_adapt(qc, midvalue, qc->vpic.brightness>>8, &ex, &gn); + qc->sensor_data.sensor->set_levels(qc, ex, gn, qc->vpic.hue, qc->vpic.colour); + } + qc_frame_free(qc); + + if (qc_adapt_hassettled(qc) || settlecount<=0) break; + settlecount--; + +error: if (r < 0) { + if (qcdebug&QC_DEBUGERRORS) PDEBUG("retrying failed qc_frame_get... rounds=%i", retrycount); + if (r==-ERESTARTSYS || retrycount<=0) break; + retrycount--; + } + qc_i2c_flush(qc); /* Send all pending I2C transfers */ + schedule(); + } while (TRUE); + if (r<0) goto fail; + qc_i2c_flush(qc); /* Send all pending I2C transfers */ + cd->settled = TRUE; + if (frame) *frame = cd->frame; + return r; + +fail: if (qcdebug&(QC_DEBUGERRORS|QC_DEBUGLOGIC)) PDEBUG("failed qc_capt_get()=%i", r); + return r; +} +/* }}} */ +/* {{{ [fold] qc_capt_frameaddr(struct quickcam *qc, unsigned char **frame) */ +/* Return size and address of the capture buffer that is suitable for mmapping, + * Standard Linux errno on error */ +static inline int qc_capt_frameaddr(struct quickcam *qc, unsigned char **frame) +{ + IDEBUG_TEST(qc->capt_data); + if (frame!=NULL) *frame = qc->capt_data.frame; + return MAX_FRAME_SIZE; +} +/* }}} */ +/* {{{ [fold] qc_capt_test(struct quickcam *qc) */ +/* Return TRUE if next image is immediately available, FALSE otherwise. + * Also starts streaming video from camera if not already done so. + * Before calling this function, qc_isoc_init() must be called first. */ +static inline Bool qc_capt_test(struct quickcam *qc) +{ + int e; + IDEBUG_TEST(qc->capt_data); + e = qc_isoc_start(qc); + if (qcdebug&QC_DEBUGERRORS && e<0) PDEBUG("qc_capt_test: qc_isoc_start failed"); + return qc_frame_test(qc); +} +/* }}} */ +/* {{{ [fold] qc_capt_init(struct quickcam *qc) */ +static int qc_capt_init(struct quickcam *qc) +{ + struct qc_capt_data *cd = &qc->capt_data; + int r; + + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_capt_init(quickcam=%p)",qc); + + cd->settled = !(qc->settings.settle>0 && qc->settings.adaptive); + + /* Allocate memory for the (mmappable) capture buffer */ + cd->frame = qc_mm_rvmalloc(MAX_FRAME_SIZE); + if (!cd->frame) { + PRINTK(KERN_ERR, "unable to allocate frame"); + r = -ENOMEM; + goto fail1; + } + + /* Initialize submodules */ + if ((r=qc_frame_init(qc))<0) goto fail2; /* Must be before sensor_init() */ + r = qc_sensor_init(qc); /* Start the sensor (must be after qc_i2c_init but before qc_adapt_init) */ + if (r<0 && qc->settings.compress) { + /* Sensor init failed with compression. Try again without compression */ + PRINTK(KERN_NOTICE, "sensor init failed, disabling compression"); + qc->settings.compress = 0; + r = qc_sensor_init(qc); + } + if (r<0) goto fail3; + if ((r=qc_stream_init(qc))<0) goto fail3; + if ((r=qc_fmt_init(qc))<0) goto fail4; + if ((r=qc_isoc_init(qc))<0) goto fail5; + IDEBUG_INIT(*cd); + return 0; + +fail5: qc_fmt_exit(qc); +fail4: qc_stream_exit(qc); +fail3: qc_frame_exit(qc); +fail2: qc_mm_rvfree(cd->frame, MAX_FRAME_SIZE); +fail1: PDEBUG("failed qc_capt_init()=%i",r); + return r; +} +/* }}} */ +/* {{{ [fold] qc_capt_exit(struct quickcam *qc) */ +static void qc_capt_exit(struct quickcam *qc) +{ + struct qc_capt_data *cd = &qc->capt_data; + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_capt_exit(quickcam=%p)",qc); + qc_isoc_exit(qc); + qc_fmt_exit(qc); + qc_stream_exit(qc); + qc_frame_exit(qc); + qc_mm_rvfree(cd->frame, MAX_FRAME_SIZE); + POISON(cd->frame); + IDEBUG_EXIT(*cd); +} +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** qc_v4l: Start of Video 4 Linux API ************************ */ + +/* {{{ [fold] qc_v4l_poll(struct video_device *dev, struct file *file, poll_table *wait) */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +static unsigned int qc_v4l_poll(struct file *file, poll_table *wait) +#else +static unsigned int qc_v4l_poll(struct video_device *dev, struct file *file, poll_table *wait) +#endif +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + struct video_device *dev = video_devdata(file); +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) + struct quickcam *qc = (struct quickcam *)video_get_drvdata(dev); +#else + struct quickcam *qc = (struct quickcam *)dev->priv; +#endif + struct qc_frame_data *fd = &qc->frame_data; + int mask; + + if (qcdebug&QC_DEBUGUSER) PDEBUG("qc_v4l_poll(dev=%p,file=%p,wait=%p)",dev,file,wait); + if (down_interruptible(&qc->lock)) return -ERESTARTSYS; + poll_wait(file, &fd->wq, wait); + mask = qc_capt_test(qc) ? (POLLIN | POLLRDNORM) : 0; + up(&qc->lock); + return mask; +} +/* }}} */ +/* {{{ [fold] qc_v4l_init(struct quickcam *qc) */ +/* Called when the device is opened */ +static int qc_v4l_init(struct quickcam *qc) +{ + int r, fps; + + if (!qc->settings.keepsettings) { + /* Reset brightness settings */ + qc->vpic.brightness = 32768; + qc->vpic.hue = 32768; + qc->vpic.colour = 32768; + qc->vpic.contrast = 32768; + qc->vpic.whiteness = 32768; + qc_adapt_reset(qc); /* qc_adapt_init() is called from qc_usb_init() */ + } + qc->vpic.palette = VIDEO_PALETTE_RGB24; + qc->vpic.depth = qc_fmt_getdepth(qc->vpic.palette); + qc->vpic_pending = FALSE; + + fps = qc->settings.subsample ? 30 : 8; /* May actually vary depending on image size */ + fps = qc->settings.compress ? 15 : fps; /* Actually 7.5 fps, but we must round it */ + qc->vwin.flags = fps << 16; /* Bits 22..16 contain framerate in Philips driver. We do the same. */ + + if ((r = qc_capt_init(qc))<0) goto fail; + return 0; + +fail: if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGERRORS) PDEBUG("failed qc_v4l_init()=%i",r); + return r; +} +/* }}} */ +/* {{{ [fold] qc_v4l_open(struct video_device *dev, int flags) */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +static int qc_v4l_open(struct inode *inode, struct file *file) +#else +static int qc_v4l_open(struct video_device *dev, int flags) +#endif +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + struct video_device *dev = video_devdata(file); +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) + struct quickcam *qc = (struct quickcam *)video_get_drvdata(dev); +#else + struct quickcam *qc = (struct quickcam *)dev->priv; +#endif + int r; + + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGUSER) PDEBUG("qc_v4l_open(qc=%p)", qc); +//PDEBUG("sleeping 10 sec..."); +//qc_usleep(1000000*10); +//PDEBUG("sleep done"); + // FIXME: if the module is tried to be unloaded at this point, + // v4l_close() and MOD_DEC_USE_COUNT will never be called + // According to "Linux Device drivers" pg.70, it's ok if called before sleeping? + // 2.2 will crash, 2.4 will hang and show "quickcam 1 (deleted)" if sleeping + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("MOD_INC_USE_COUNT in qc_v4l_open() : %i",GET_USE_COUNT(THIS_MODULE)); + MOD_INC_USE_COUNT; + + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("down_intr(quickcam_list) in qc_v4l_open() : %i", sem_getcount(&quickcam_list_lock)); + + r = qc_lock(qc); + if (r<0) goto fail1; + + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("down_intr(%p) in qc_v4l_open() : %i", qc, sem_getcount(&qc->lock)); + if (down_interruptible(&qc->lock)) { + r = -ERESTARTSYS; + goto fail2; + } + if (!qc->connected) { + r = -ENODEV; + goto fail3; + } + qc->users++; + PDEBUG("open users=%i", qc->users); + if (qc->users == 1) { + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("First user, initializing"); + if ((r = qc_v4l_init(qc))<0) goto fail4; + } + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(%p) in qc_v4l_open() : %i",qc, sem_getcount(&qc->lock)); + up(&qc->lock); + up(&quickcam_list_lock); + return 0; + +fail4: qc->users--; +fail3: if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(%p) in qc_v4l_open()=failed : %i",qc, sem_getcount(&qc->lock)); + up(&qc->lock); +fail2: if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(quickcam_list) in qc_v4l_open()=failed : %i", sem_getcount(&qc->lock)); + up(&quickcam_list_lock); +fail1: if (qcdebug&QC_DEBUGMUTEX) PDEBUG("MOD_DEC_USE_COUNT in qc_v4l_open() : %i",GET_USE_COUNT(THIS_MODULE)); + MOD_DEC_USE_COUNT; + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGERRORS) PDEBUG("failed qc_v4l_open()=%i",r); + return r; +} +/* }}} */ +/* {{{ [fold] qc_v4l_exit(struct quickcam *qc) */ +/* Release all resources allocated at qc_v4l_init() */ +static inline void qc_v4l_exit(struct quickcam *qc) +{ + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_v4l_cleanup(%p)", qc); + qc_capt_exit(qc); +} +/* }}} */ +/* {{{ [fold] qc_v4l_close(struct video_device *dev) */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +static int qc_v4l_close(struct inode *inode, struct file *file) +#else +static void qc_v4l_close(struct video_device *dev) +#endif +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + struct video_device *dev = video_devdata(file); +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) + struct quickcam *qc = (struct quickcam *)video_get_drvdata(dev); +#else + struct quickcam *qc = (struct quickcam *)dev->priv; +#endif + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGUSER) PDEBUG("qc_v4l_close(dev=%p,qc=%p)",dev,qc); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + TEST_BUGR_MSG(qc==NULL, "qc==NULL"); +#else + TEST_BUG_MSG(qc==NULL, "qc==NULL"); +#endif + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("down(quickcam_list) in qc_v4l_close() : %i", sem_getcount(&quickcam_list_lock)); + down(&quickcam_list_lock); /* Can not interrupt, we must success */ + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("down(%p) in qc_v4l_close() : %i", qc, sem_getcount(&qc->lock)); + down(&qc->lock); /* Can not interrupt, we must success */ + qc->users--; + PDEBUG("close users=%i", qc->users); + if (qc->users == 0) { + /* No more users, device is deallocated */ + qc_v4l_exit(qc); + if (qc->dev == NULL) { /* Test qc->dev instead of qc->connected because disconnection routine sets the latter before locking camera */ + /* Camera was unplugged and freeing was postponed: free resources now here */ + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("Performing postponed free"); + qc_usb_exit(qc); + qc = NULL; + } + } + if (qc) { + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(%p) in qc_v4l_close() : %i", qc, sem_getcount(&qc->lock)); + up(&qc->lock); + } + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(quickcam_list) in qc_v4l_close() : %i", sem_getcount(&quickcam_list_lock)); + up(&quickcam_list_lock); + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("MOD_DEC_USE_COUNT in qc_v4l_close() : %i", GET_USE_COUNT(THIS_MODULE)); + MOD_DEC_USE_COUNT; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("v4l_close() ok"); +#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,0) + return 0; +#endif +} +/* }}} */ +/* {{{ [fold] qc_v4l_read(struct video_device *dev, char *buf, unsigned long count, int noblock) */ +static ssize_t qc_v4l_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + struct video_device *dev = video_devdata(file); + int noblock = file->f_flags & O_NONBLOCK; +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) + struct quickcam *qc = (struct quickcam *)video_get_drvdata(dev); +#else + struct quickcam *qc = (struct quickcam *)dev->priv; +#endif + int frame_len; + unsigned char *frame; + long r = 0; + + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGUSER) + PDEBUG("qc_v4l_read(dev=%p,buf=%p,count=%li,noblock=%i,qc=%p)",dev,buf,(long)count,noblock,qc); + if (!qc || !buf) { + PDEBUG("qc_read: no video_device available or no buffer attached :( EFAULT"); + return -EFAULT; + } + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("down_intr(%p) in qc_v4l_read() : %i", qc, sem_getcount(&qc->lock)); + if (down_interruptible(&qc->lock)) return -ERESTARTSYS; + if (!qc->connected) { + r = -ENODEV; + goto fail; + } + if (noblock && !qc_capt_test(qc)) { + r = -EAGAIN; + goto fail; + } + frame_len = qc_capt_get(qc, &frame); + if (frame_len < 0) { + r = frame_len; + goto fail; + } + if (count > frame_len) count = frame_len; + if (copy_to_user(buf, frame, count)) { + r = -EFAULT; + goto fail; + } + r = count; + +fail: if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(%p) in qc_v4l_read() : %i", qc, sem_getcount(&qc->lock)); + up(&qc->lock); + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGERRORS) if (r<0) PDEBUG("failed qc_v4l_read()=%i", (int)r); + return r; +} +/* }}} */ +/* {{{ [fold] qc_v4l_mmap(struct vm_area_struct *vma, struct video_device *dev, const char *adr, unsigned long size) */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +static int qc_v4l_mmap(struct file *file, struct vm_area_struct *vma) +#else +static int qc_v4l_mmap( +#if HAVE_VMA + struct vm_area_struct *vma, +#endif + struct video_device *dev, const char *start, unsigned long size) +#endif /* 2.6.x */ +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + struct video_device *dev = video_devdata(file); + const void *start = (void *)vma->vm_start; + unsigned long size = vma->vm_end - vma->vm_start; +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) + struct quickcam *qc = (struct quickcam *)video_get_drvdata(dev); +#else + struct quickcam *qc = (struct quickcam *)dev->priv; +#endif + unsigned char *frame; + int ret = 0, frame_size; +#if !HAVE_VMA && LINUX_VERSION_CODElock)); + if (down_interruptible(&qc->lock)) return -ERESTARTSYS; + if (!qc->connected) { ret = -ENODEV; goto fail; } + frame_size = qc_capt_frameaddr(qc, &frame); + if (frame_size<0) { ret = frame_size; goto fail; } /* Should never happen */ + ret = qc_mm_remap(vma, frame, frame_size, start, size); + +fail: if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(%p) in qc_v4l_mmap() : %i", qc, sem_getcount(&qc->lock)); + up(&qc->lock); + if (ret<0) if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGERRORS) PDEBUG("failed qc_v4l_mmap()=%i",ret); + return ret; +} +/* }}} */ +/* {{{ [fold] qc_v4l_ioctl(struct video_device *dev, unsigned int cmd, void *arg) */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +static int qc_v4l_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +#else +static int qc_v4l_ioctl(struct video_device *dev, unsigned int cmd, void *argp) +#endif +{ + static const Bool ignore_channel = TRUE; /* RealProducer is reported to fail if driver doesn't accept channel change */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + struct video_device *dev = video_devdata(file); + void *argp = (void *)arg; +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) + struct quickcam *qc = (struct quickcam *)video_get_drvdata(dev); +#else + struct quickcam *qc = (struct quickcam *)dev->priv; +#endif + int i, retval = 0; + + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGUSER) PDEBUG("qc_v4l_ioctl(dev=%p,cmd=%u,arg=%p,qc=%p)",dev,cmd,argp,qc); + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("down_intr(%p) in qc_v4l_ioctl() : %i", qc, sem_getcount(&qc->lock)); + if (down_interruptible(&qc->lock)) return -ERESTARTSYS; + if (!qc->connected) { + retval = -ENODEV; + goto fail; + } + switch (cmd) { +/* {{{ [fold] VIDIOCGCAP: Capability query */ + case VIDIOCGCAP: /* Capability query */ + { + struct video_capability b; + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCGCAP"); + memset(&b, 0, sizeof(b)); + strcpy(b.name, "Logitech QuickCam USB"); /* Max 31 characters */ + b.type = qc->vdev.vfl_type; + b.channels = 1; + b.audios = 0; + b.maxwidth = qc->sensor_data.maxwidth; + b.maxheight = qc->sensor_data.maxheight; + if (qc->settings.compat_16x) { + b.maxwidth = (b.maxwidth /16)*16; + b.maxheight = (b.maxheight/16)*16; + } + b.minwidth = min_framewidth; + b.minheight = min_frameheight; + if (copy_to_user(argp, &b, sizeof(b))) retval = -EFAULT; + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCGCHAN: Get properties of the specified channel */ + case VIDIOCGCHAN: /* Get properties of the specified channel */ + { + struct video_channel v; + if (copy_from_user(&v, argp, sizeof(v))) { + retval = -EFAULT; + break; + } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCGCHAN channel:%i",v.channel); + if (!ignore_channel && v.channel != 0) { + retval = -EINVAL; + break; + } + v.flags = 0; + v.tuners = 0; + v.type = VIDEO_TYPE_CAMERA; + strcpy(v.name, "Camera"); + if (copy_to_user(argp, &v, sizeof(v))) retval = -EFAULT; + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCSCHAN: Select channel to capture */ + case VIDIOCSCHAN: /* Select channel to capture */ + { + if (copy_from_user(&i, argp, sizeof(i))) { + retval = -EFAULT; + break; + } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCSCHAN channel:%i",i); + if (!ignore_channel && i!=0) retval = -EINVAL; + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCGPICT: Get image properties (brightness, palette, etc.) */ + case VIDIOCGPICT: /* Get image properties */ + { + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCGPICT"); + if (copy_to_user(argp, &qc->vpic, sizeof(qc->vpic))) retval = -EFAULT; + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCSPICT: Set image properties */ + case VIDIOCSPICT: /* Set image properties */ + { + struct video_picture p; + if (copy_from_user(&p, argp, sizeof(p))) { + retval = -EFAULT; + break; + } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCSPICT depth:%d palette:%s(%i) bright=%i",p.depth,qc_fmt_getname(p.palette),p.palette,p.brightness); + + if (p.palette != 0) { /* 0 = do not change palette */ + retval = qc_fmt_issupported(p.palette); + if (retval<0) break; + qc->vpic.palette = p.palette; + qc->vpic.depth = qc_fmt_getdepth(p.palette); + if (qc->vpic.depth != p.depth) PDEBUG("warning: palette depth mismatch"); + } + qc->vpic.brightness = p.brightness; + qc->vpic.hue = p.hue; + qc->vpic.colour = p.colour; + qc->vpic.contrast = p.contrast; + qc->vpic.whiteness = p.whiteness; /* Used for sharpness */ + qc->vpic_pending = TRUE; + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCSWIN: Set capture area width and height */ + case VIDIOCSWIN: /* Set capture area width and height */ + { + struct video_window vw; + int fps; + if (copy_from_user(&vw, argp, sizeof(vw))) { + retval = -EFAULT; + break; + } + fps = (vw.flags>>16) & 0x3F; /* 6 bits for framerate */ + if (fps && ((qc->vwin.flags>>16)&0x3F)!=fps) { + PDEBUG("Application tries to change framerate"); + } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCSWIN width:%i height:%i flags:%d clipcount:%d",vw.width,vw.height,vw.flags,vw.clipcount); + retval = qc_sensor_setsize(qc, vw.width, vw.height); + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCGWIN: Get current capture area */ + case VIDIOCGWIN: /* Get current capture area */ + { + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCGWIN"); + if (copy_to_user(argp, &qc->vwin, sizeof(qc->vwin))) retval = -EFAULT; + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCGMBUF: Get mmap buffer size and frame offsets */ + case VIDIOCGMBUF: /* Get mmap buffer size and frame offsets */ + { + struct video_mbuf vm; + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCGMBUF"); + memset(&vm, 0, sizeof(vm)); + vm.size = qc_capt_frameaddr(qc, NULL); + if (vm.size<0) { /* Negative value denotes error */ + retval = vm.size; + break; + } + vm.frames = 1; + vm.offsets[0] = 0; + if (qc->settings.compat_dblbuf) { + /* Really many applications are broken and don't work with a single buffer */ + vm.frames = 2; + vm.offsets[1] = 0; + } + if (copy_to_user(argp, &vm, sizeof(vm))) retval = -EFAULT; + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCMCAPTURE: Start capturing specified frame in the mmap buffer with specified size */ + case VIDIOCMCAPTURE: /* Start capturing specified frame in the mmap buffer with specified size */ + { + struct video_mmap vm; + if (copy_from_user(&vm, argp, sizeof(vm))) { + retval = -EFAULT; + break; + } + /* Bug in V4L: sometimes it's called palette, sometimes format. We'll stick with palette */ + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCMCAPTURE frame:%d size:%dx%d palette:%s", vm.frame, vm.width, vm.height, qc_fmt_getname(vm.format)); + if (vm.frame!=0 && !(qc->settings.compat_dblbuf)) { + PRINTK(KERN_NOTICE,"Bug detected in user program, use qcset compat=dblbuf"); + retval = -EINVAL; + break; + } + if (vm.format!=0 && qc->vpic.palette!=vm.format) { /* 0 = do not change palette */ + retval = qc_fmt_issupported(vm.format); + if (retval) { + if (qcdebug&QC_DEBUGERRORS) PDEBUG("unsupported image format"); + break; + } + qc->vpic.palette = vm.format; + qc->vpic.depth = qc_fmt_getdepth(vm.format); + } + retval = qc_sensor_setsize(qc, vm.width, vm.height); + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCSYNC: Wait until specified frame in the mmap buffer has been captured */ + case VIDIOCSYNC: /* Wait until specified frame in the mmap buffer has been captured */ + { + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCSYNC"); + retval = qc_capt_get(qc, NULL); + if (retval>0) retval = 0; + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCGFBUF: Get currently used frame buffer parameters */ + case VIDIOCGFBUF: /* Get currently used frame buffer parameters */ + { + struct video_buffer vb; + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCGFBUF"); + memset(&vb, 0, sizeof(vb)); + if (copy_to_user(argp, &vb, sizeof(vb))) retval = -EFAULT; + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCKEY: Undocumented? */ + case VIDIOCKEY: /* Undocumented? */ + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCKEY"); + retval = -EINVAL; + break; +/* }}} */ +/* {{{ [fold] VIDIOCCAPTURE: Activate overlay capturing directly to framebuffer */ + case VIDIOCCAPTURE: /* Activate overlay capturing directly to framebuffer */ + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCCAPTURE"); + retval = -EINVAL; + break; +/* }}} */ +/* {{{ [fold] VIDIOCSFBUF: Set frame buffer parameters for the capture card */ + case VIDIOCSFBUF: /* Set frame buffer parameters for the capture card */ + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCSFBUF"); + retval = -EINVAL; + break; +/* }}} */ +/* {{{ [fold] VIDIOCxTUNER: Get properties of the specified tuner / Select tuner to use */ + case VIDIOCGTUNER: /* Get properties of the specified tuner */ + case VIDIOCSTUNER: /* Select tuner to use */ + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxTUNER"); + retval = -EINVAL; + break; +/* }}} */ +/* {{{ [fold] VIDIOCxFREQ: Get current tuner frequency / Set tuner frequency */ + case VIDIOCGFREQ: /* Get current tuner frequency */ + case VIDIOCSFREQ: /* Set tuner frequency */ + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxFREQ"); + retval = -EINVAL; + break; +/* }}} */ +/* {{{ [fold] VIDIOCxAUDIO: Get/Set audio properties */ + case VIDIOCGAUDIO: /* Get audio properties */ + case VIDIOCSAUDIO: /* Set audio properties */ + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxAUDIO"); + retval = -EINVAL; + break; +/* }}} */ + /********** Private IOCTLs ***********/ +/* {{{ [fold] VIDIOCQCxDEBUG: Sets/gets the qcdebug output (1,2,4,8,16,32) */ + case VIDIOCQCSDEBUG: /* Sets the qcdebug output (1,2,4,8,16,32) */ + if (get_user(qcdebug, (int *)argp)) { retval=-EFAULT; break; } + case VIDIOCQCGDEBUG: /* Gets the qcdebug output (1,2,4,8,16,32) */ + if (put_user(qcdebug, (int *)argp)) { retval=-EFAULT; break; } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxDEBUG"); + break; +/* }}} */ +/* {{{ [fold] VIDIOCQCxKEEPSETTINGS: Set/get keep gain settings across one open to another (0-1) */ + case VIDIOCQCSKEEPSETTINGS: /* Set keep gain settings across one open to another (0-1) */ + if (get_user(i, (int *)argp)) { retval=-EFAULT; break; } + qc->settings.keepsettings = i; + case VIDIOCQCGKEEPSETTINGS: /* Get keep gain settings across one open to another (0-1) */ + i = qc->settings.keepsettings; + if (put_user(i, (int *)argp)) { retval=-EFAULT; break; } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxKEEPSETTINGS"); + break; +/* }}} */ +/* {{{ [fold] VIDIOCQCxSETTLE: Set/get if we let image brightness to settle (0-1) */ + case VIDIOCQCSSETTLE: /* Set if we let image brightness to settle (0-1) */ + if (get_user(i, (int *)argp)) { retval=-EFAULT; break; } + qc->settings.settle = i; + case VIDIOCQCGSETTLE: /* Get if we let image brightness to settle (0-1) */ + i = qc->settings.settle; + if (put_user(i, (int *)argp)) { retval=-EFAULT; break; } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxSETTLE"); + break; +/* }}} */ +/* {{{ [fold] VIDIOCQCxSUBSAMPLE: Sets/gets the speed (0-1) */ + case VIDIOCQCSSUBSAMPLE: /* Sets the speed (0-1) */ + if (get_user(i, (int *)argp)) { retval=-EFAULT; break; } + qc->settings.subsample = i; + case VIDIOCQCGSUBSAMPLE: /* Gets the speed (0-1) */ + i = qc->settings.subsample; + if (put_user(i, (int *)argp)) { retval=-EFAULT; break; } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxSUBSAMPLE"); + break; +/* }}} */ +/* {{{ [fold] VIDIOCQCxCOMPRESS: Sets/gets the compression mode (0-1) */ + case VIDIOCQCSCOMPRESS: /* Sets the compression mode (0-1) */ + if (get_user(i, (int *)argp)) { retval=-EFAULT; break; } + qc->settings.compress = i; + case VIDIOCQCGCOMPRESS: /* Gets the compression mode (0-1) */ + i = qc->settings.compress; + if (put_user(i, (int *)argp)) { retval=-EFAULT; break; } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxCOMPRESS"); + break; +/* }}} */ +/* {{{ [fold] VIDIOCQCxFRAMESKIP: Set/get frame capture frequency (0-10) */ + case VIDIOCQCSFRAMESKIP: /* Set frame capture frequency (0-10) */ + if (get_user(i, (int *)argp)) { retval=-EFAULT; break; } + qc->settings.frameskip = i; + case VIDIOCQCGFRAMESKIP: /* Get frame capture frequency (0-10) */ + i = qc->settings.frameskip; + if (put_user(i, (int *)argp)) { retval=-EFAULT; break; } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxFRAMESKIP"); + break; +/* }}} */ +/* {{{ [fold] VIDIOCQCxQUALITY: Sets/gets the interpolation mode (0-2) */ + case VIDIOCQCSQUALITY: /* Sets the interpolation mode (0-5) */ + if (get_user(i, (int *)argp)) { retval=-EFAULT; break; } + qc->settings.quality = i; + case VIDIOCQCGQUALITY: /* Gets the interpolation mode (0-5) */ + i = qc->settings.quality; + if (put_user(i, (int *)argp)) { retval=-EFAULT; break; } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxQUALITY"); + break; +/* }}} */ +/* {{{ [fold] VIDIOCQCxADAPTIVE: Set/get automatic adaptive brightness control (0-1) */ + case VIDIOCQCSADAPTIVE: /* Set automatic adaptive brightness control (0-1) */ + if (get_user(i, (int *)argp)) { retval=-EFAULT; break; } + qc->settings.adaptive = i; + case VIDIOCQCGADAPTIVE: /* Get automatic adaptive brightness control (0-1) */ + i = qc->settings.adaptive; + if (put_user(i, (int *)argp)) { retval=-EFAULT; break; } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxADAPTIVE"); + break; +/* }}} */ +/* {{{ [fold] VIDIOCQCxEQUALIZE: Set/get equalize image (0-1) */ + case VIDIOCQCSEQUALIZE: /* Set equalize image (0-1) */ + if (get_user(i, (int *)argp)) { retval=-EFAULT; break; } + qc->settings.equalize = i; + case VIDIOCQCGEQUALIZE: /* Get equalize image (0-1) */ + i = qc->settings.equalize; + if (put_user(i, (int *)argp)) { retval=-EFAULT; break; } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxEQUALIZE"); + break; +/* }}} */ +/* {{{ [fold] VIDIOCQCxUSERLUT: Set/get user-specified lookup-table */ + case VIDIOCQCSUSERLUT: /* Set user-specified lookup-table [struct qc_userlut] */ + { + unsigned int flags; + retval = -EFAULT; + if (get_user(flags, &(((struct qc_userlut*)argp)->flags))) break; + if (flags & QC_USERLUT_DEFAULT) { + userlut = ((flags & QC_USERLUT_ENABLE) != 0); + } else { + qc->settings.userlut = ((flags & QC_USERLUT_ENABLE) != 0); + } + if (flags & QC_USERLUT_VALUES) { + for (i=0; ilut[i]))) break; + if (flags & QC_USERLUT_DEFAULT) { + userlut_contents[i] = p; + } else { + qc->fmt_data.userlut[i] = p; + } + } + if (i < QC_LUT_SIZE) break; + } + retval = 0; + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCSUSERLUT"); + break; + } + case VIDIOCQCGUSERLUT: /* Get user-specified lookup-table [struct qc_userlut] */ + { + unsigned int flags; + retval = -EFAULT; + if (get_user(flags, &(((struct qc_userlut*)argp)->flags))) break; + flags &= (~QC_USERLUT_ENABLE); + if ((flags & QC_USERLUT_DEFAULT) ? userlut : qc->settings.userlut) flags |= QC_USERLUT_ENABLE; + if (put_user(flags, &(((struct qc_userlut*)argp)->flags))) break; + if (flags & QC_USERLUT_VALUES) { + for (i=0; ifmt_data.userlut[i]; + } + if (put_user(p, &(((struct qc_userlut*)argp)->lut[i]))) break; + } + if (i < QC_LUT_SIZE) break; + } + retval = 0; + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCGUSERLUT"); + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCQCxRETRYERRORS: Set/get if we retry when error happen in capture (0-1) */ + case VIDIOCQCSRETRYERRORS: /* Set if we retry when error happen in capture (0-1) */ + if (get_user(i, (int *)argp)) { retval=-EFAULT; break; } + qc->settings.retryerrors = i; + case VIDIOCQCGRETRYERRORS: /* Get if we retry when error happen in capture (0-1) */ + i = qc->settings.retryerrors; + if (put_user(i, (int *)argp)) { retval=-EFAULT; break; } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxRETRYERRORS"); + break; +/* }}} */ +/* {{{ [fold] VIDIOCQCxCOMPATIBLE: Set enable workaround for Xawtv/Motv bugs (0-1) */ + case VIDIOCQCSCOMPATIBLE: /* Set enable workaround for Xawtv/Motv bugs (0-1) */ + if (get_user(i, (int *)argp)) { retval=-EFAULT; break; } + qc->settings.compat_16x = (i & QC_COMPAT_16X) != 0; + qc->settings.compat_dblbuf = (i & QC_COMPAT_DBLBUF) != 0; + qc->settings.compat_torgb = (i & QC_COMPAT_TORGB) != 0; + case VIDIOCQCGCOMPATIBLE: /* Get enable workaround for Xawtv/Motv bugs (0-1) */ + i = ~(qc->settings.compat_16x -1) & QC_COMPAT_16X; + i |= ~(qc->settings.compat_dblbuf-1) & QC_COMPAT_DBLBUF; + i |= ~(qc->settings.compat_torgb -1) & QC_COMPAT_TORGB; + if (put_user(i, (int *)argp)) { retval=-EFAULT; break; } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxCOMPATIBLE"); + break; +/* }}} */ +/* {{{ [fold] VIDIOCQCxVIDEONR: Set videodevice number (/dev/videoX) */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,5) + case VIDIOCQCSVIDEONR: /* Set videodevice number (/dev/videoX) */ + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCSVIDEONR"); + retval = -EINVAL; /* Can not set after the module is loaded */ + break; + case VIDIOCQCGVIDEONR: /* Get videodevice number (/dev/videoX) */ + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCGVIDEONR"); + if (put_user(video_nr, (int *)argp)) { retval=-EFAULT; break; } + break; +#endif +/* }}} */ +/* {{{ [fold] VIDIOCQCxSTV: Read/write STV chip register value */ + /* Encoding: bits 31..16 of the int argument contain register value, 15..0 the reg number */ + case VIDIOCQCGSTV: /* Read STV chip register value */ + { + int reg, val; + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCQCGSTV"); + if (get_user(reg, (int *)argp)) { retval=-EFAULT; break; } + reg &= 0xFFFF; + val = qc_stv_get(qc, reg); + if (val<0) { retval=val; break; } + val = (val<<16) | reg; + if (put_user(val, (int *)argp)) { retval=-EFAULT; break; } + break; + } + case VIDIOCQCSSTV: /* Write STV chip register value */ + { + int regval; + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCQCSSTV"); + if (!capable(CAP_SYS_RAWIO)) { retval=-EPERM; break; } + if (get_user(regval, (int *)argp)) { retval=-EFAULT; break; } + retval = qc_stv_set(qc, regval & 0xFFFF, regval >> 16); + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCQCxI2C: Read/write sensor chip register value via I2C */ + case VIDIOCQCGI2C: /* Read sensor chip register value via I2C */ + { + int reg, val; + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCQCGI2C"); + if (get_user(reg, (int *)argp)) { retval=-EFAULT; break; } + reg &= 0xFFFF; + val = qc_get_i2c(qc, qc->sensor_data.sensor, reg); + if (val<0) { retval=val; break; } + val = (val<<16) | reg; + if (put_user(val, (int *)argp)) { retval=-EFAULT; break; } + break; + } + case VIDIOCQCSI2C: /* Write sensor chip register value via I2C */ + { + int regval; + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCQCSI2C"); + if (!capable(CAP_SYS_RAWIO)) { retval=-EPERM; break; } + if (get_user(regval, (int *)argp)) { retval=-EFAULT; break; } + retval = qc_i2c_set(qc, regval & 0xFFFF, regval >> 16); + if (retval<0) break; + retval = qc_i2c_wait(qc); + break; + } +/* }}} */ + default: + if (qcdebug&QC_DEBUGUSER) PDEBUG("Unknown IOCTL %08X",cmd); + retval = -ENOIOCTLCMD; + break; + } +fail: if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(%p) in qc_v4l_ioctl() : %i", qc, sem_getcount(&qc->lock)); + up(&qc->lock); + if (retval<0) if (qcdebug&(QC_DEBUGLOGIC|QC_DEBUGUSER|QC_DEBUGERRORS)) PDEBUG("failed qc_v4l_ioctl()=%i",retval); + return retval; +} +/* }}} */ +/* {{{ [fold] qc_v4l_write(struct video_device *dev, const char *buf, unsigned long count, int noblock) */ +#if LINUX_VERSION_CODE= KERNEL_VERSION(2,6,0) +static void qc_v4l_release(struct video_device *vfd) { } +static struct file_operations qc_v4l_fops = { + owner: THIS_MODULE, + open: qc_v4l_open, + release: qc_v4l_close, + read: qc_v4l_read, +// write: qc_v4l_write, + ioctl: qc_v4l_ioctl, + mmap: qc_v4l_mmap, + poll: qc_v4l_poll, +}; +#endif + +static struct video_device qc_v4l_template = { + name: "QuickCam USB", + minor: -1, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + release: qc_v4l_release, + fops: &qc_v4l_fops, +#else + initialize: NULL, + open: qc_v4l_open, + close: qc_v4l_close, + read: qc_v4l_read, + write: qc_v4l_write, + ioctl: qc_v4l_ioctl, + mmap: qc_v4l_mmap, + poll: qc_v4l_poll, +#endif +}; +/* }}} */ +/* {{{ [fold] **** qc_usb: Start of USB API ********************************** */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +static int qc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +static void *qc_usb_probe(struct usb_device *dev, unsigned int iface, const struct usb_device_id *id); +#else +static void *qc_usb_probe(struct usb_device *dev, unsigned int iface); +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +static void qc_usb_disconnect(struct usb_interface *intf); +#else +static void qc_usb_disconnect(struct usb_device *dev, void *ptr); +#endif + +static struct usb_driver qc_usb_driver = { + name: qc_name, + probe: qc_usb_probe, + disconnect: qc_usb_disconnect, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) \ + && LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) + owner: THIS_MODULE, +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + id_table: qc_device_table, +#endif +}; + +/* {{{ [fold] qc_usb_init(struct usb_device *dev, unsigned int ifacenum) */ +/* Detect sensor, initialize the quickcam structure, register V4L device, create /proc entry. + * Return pointer to the allocated quickcam structure or NULL on error. + * If there is some camera already open but disconnected, reuse the quickcam structure. */ +static struct quickcam *qc_usb_init(struct usb_device *usbdev, unsigned int ifacenum) +{ + struct quickcam *qc; + Bool reuse_qc; + int i, r = 0; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_usb_init(usbdev=%p)", usbdev); + if (PARANOID && usbdev==NULL) { PRINTK(KERN_CRIT,"usbdev==NULL"); return NULL; } + + /* Check if there is already a suitable quickcam struct that can be reused */ + reuse_qc = FALSE; + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("down_intr(quickcam_list_lock) in qc_usb_init() : %i", sem_getcount(&quickcam_list_lock)); + if (down_interruptible(&quickcam_list_lock)) return NULL; + list_for_each_entry(qc, &quickcam_list, list) { + if (qc->dev!=NULL) continue; /* quickcam_list_lock protects this test */ + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("down_intr(%p) in qc_usb_init() : %i",qc, sem_getcount(&qc->lock)); + if (down_interruptible(&qc->lock)) { + /* Failed to lock the camera. Move on in the list, skipping this camera */ + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("failed locking the camera %p in qc_usb_init() : %i",qc,sem_getcount(&qc->lock)); + continue; + } + if (qc->users<=0) { + PRINTK(KERN_NOTICE, "Unplugged unused camera detected!"); + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(%p) in qc_usb_init() : %i",qc, sem_getcount(&qc->lock)); + up(&qc->lock); + continue; + } + /* Found and locked unplugged but used camera */ + reuse_qc = TRUE; + break; + } + + if (reuse_qc) { + /* Reuse existing quickcam (which is already opened) */ + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("Reusing existing quickcam"); + if (PARANOID && qc->users<=0) PRINTK(KERN_CRIT, "Unplugged JUST closed camera detected!"); + qc_isoc_stop(qc); + qc_i2c_wait(qc); + qc_frame_flush(qc); + } else { + /* Allocate and initialize some members of the new qc */ + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("Allocating new quickcam"); + qc = kmalloc(sizeof(*qc), GFP_KERNEL); + CHECK_ERROR(qc==NULL, fail1, "couldn't kmalloc quickcam struct"); + memset(qc, 0, sizeof(*qc)); /* No garbage to user */ +PDEBUG("poisoning qc in qc_usb_init"); + POISON(*qc); + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("init down(%p) in qc_usb_init()", qc); +#ifdef CONFIG_PREEMPT_RT + init_MUTEX(&qc->lock); + down(&qc->lock); +#else + init_MUTEX_LOCKED(&qc->lock); +#endif + qc->users = 0; + if ((r=qc_i2c_init(qc))<0) goto fail2; + } + qc->dev = usbdev; + qc->iface = ifacenum; + qc->connected = TRUE; + + /* Probe for the sensor type */ + qc_i2c_wait(qc); /* Necessary before set_interface() */ + if ((r=usb_set_interface(usbdev, qc->iface, 0))<0) goto fail3; /* Set altsetting 0 */ + if ((r=qc_stv_set(qc, STV_ISO_ENABLE, 0))<0) goto fail3; /* Disable isochronous stream */ + for (i=0; iid_reg))<0) goto fail3; + r = (r >> (sensors[i]->length_id-1) * 8) & 0xFF; /* Get MSB of received value */ + if (qcdebug&QC_DEBUGCAMERA) PDEBUG("Probing %s: expecting %02X, got %02X", sensors[i]->name, sensors[i]->id, r); + if (r == sensors[i]->id) break; + } + if (i>=SIZE(sensors)) { + PRINTK(KERN_INFO,"unsupported sensor"); + goto fail3; + } + qc->sensor_data.sensor = sensors[i]; + PRINTK(KERN_INFO,"Sensor %s detected", sensors[i]->name); + + if ((r=qc_stv_set(qc, STV_ISO_ENABLE, 0))<0) goto fail3; /* Disable isochronous streaming */ + if ((r=qc_stv_set(qc, STV_REG23, 1))<0) goto fail3; + + if (!reuse_qc) { + /* Set default settings */ + qc->vpic.brightness = 32768; + qc->vpic.hue = 32768; + qc->vpic.colour = 32768; + qc->vpic.contrast = 32768; + qc->vpic.whiteness = 32768; /* Used for sharpness at quality=5 */ + qc->settings.keepsettings = keepsettings; + qc->settings.settle = settle; + qc->settings.subsample = subsample; + qc->settings.compress = compress; + qc->settings.frameskip = frameskip; + qc->settings.quality = quality; + qc->settings.adaptive = adaptive; + qc->settings.equalize = equalize; + qc->settings.userlut = userlut; + qc->settings.retryerrors = retryerrors; + qc->settings.compat_16x = compatible & QC_COMPAT_16X ? 1 : 0; + qc->settings.compat_dblbuf = compatible & QC_COMPAT_DBLBUF ? 1 : 0; + qc->settings.compat_torgb = compatible & QC_COMPAT_TORGB ? 1 : 0; + memcpy(&qc->fmt_data.userlut, userlut_contents, sizeof(qc->fmt_data.userlut)); + + /* Register V4L video device */ + memcpy(&qc->vdev, &qc_v4l_template, sizeof(qc_v4l_template)); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28) + video_set_drvdata(&(qc->vdev), qc); +#else + qc->vdev.priv = qc; +#endif + r = video_register_device(&qc->vdev, VFL_TYPE_GRABBER, video_nr); + if (r<0) goto fail3; + PRINTK(KERN_INFO, "Registered device: /dev/video%i", qc->vdev.minor); + if ((r=qc_adapt_init(qc))<0) goto fail4; + qc_proc_create(qc); /* Create /proc entry, ignore if it fails */ + list_add(&qc->list, &quickcam_list); + } + + if (reuse_qc && qc->frame_data.waiting>0) { + /* Restart capturing */ + int width = qc->vwin.width; + int height = qc->vwin.height; +//qc_usleep(1000000); + qc_isoc_stop(qc); + r = qc_sensor_init(qc); + r = qc_isoc_start(qc); + r = qc_sensor_setsize(qc, width, height); + /* Ignore return codes for now, if it fails, too bad, but shouldn't crash */ + /* FIXME: proper error handling */ + +/*qc_usleep(1000000); + qc_sensor_setsize(qc, width, height); +qc_usleep(1000000); + qc_sensor_setsize(qc, 32, 32); +qc_usleep(1000000); + qc_sensor_setsize(qc, width, height); +qc_usleep(1000000);*/ + +#if 0 +/* The following tries to initialize VV6410 really hard. still doesn't work */ +{ +int r,c; +for(c=0;c<10;c++) { +//r = qc_sensor_init(qc); +//PDEBUG("c=%i init=%i",c,r); +//r = qc_sensor_setsize(qc, width, height); +//PDEBUG("size=%i",r); +//r = usb_set_interface(qc->dev, qc->iface, 1); +//PDEBUG("set_interf=%i",r); +//r = qc->sensor_data.sensor->start(qc); /* Start current frame */ +//PDEBUG("start=%i",r); +//r = qc_stv_set(qc, STV_ISO_ENABLE, 1); +//PDEBUG("stv_set=%i",r); +//qc_isoc_stop(qc); +//qc_usleep(1000000); +//qc_isoc_start(qc); +//qc_usleep(1000000); +}} +#endif + } + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(%p) in qc_usb_init() : %i",qc, sem_getcount(&qc->lock)); + up(&qc->lock); + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(quickcam_list) in qc_usb_init() : %i", sem_getcount(&quickcam_list_lock)); + up(&quickcam_list_lock); + return qc; + +fail4: video_unregister_device(&qc->vdev); +fail3: if (!reuse_qc) qc_i2c_exit(qc); + qc->dev = NULL; + qc->connected = FALSE; + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(%p) in qc_usb_init()=failed : %i",qc, sem_getcount(&qc->lock)); + up(&qc->lock); +fail2: if (!reuse_qc) kfree(qc); +fail1: if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGERRORS) PDEBUG("failed qc_usb_init()=%i",r); + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(quickcam_list) in qc_usb_init()=failed : %i", sem_getcount(&quickcam_list_lock)); + up(&quickcam_list_lock); + return NULL; +} +/* }}} */ +/* FIXME: can usb_disconnect and usb_probe pre-empt other kernel mode processes? Assume no */ +/* {{{ [fold] qc_usb_probe(...) */ +/* Called when any USB device is connected, check if it is a supported camera */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +static int qc_usb_probe(struct usb_interface *interface, const struct usb_device_id *id) +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +static void *qc_usb_probe(struct usb_device *usbdev, unsigned int ifacenum, const struct usb_device_id *id) +#else /* 2.2.x */ +static void *qc_usb_probe(struct usb_device *usbdev, unsigned int ifacenum) +#endif +{ + struct quickcam *qc; + struct usb_interface_descriptor *ifacedesc; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + unsigned int ifacenum; + struct usb_device *usbdev = interface_to_usbdev(interface); + static const int ERROR_CODE = -ENODEV; +#else + static void * const ERROR_CODE = NULL; +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) + /* Check if the device has a product number that we support */ + struct usb_device_id *i; + for (i=qc_device_table; i->idVendor; i++) { + if (usbdev->descriptor.idVendor == i->idVendor && + usbdev->descriptor.idProduct == i->idProduct) break; + } + if (!i->idVendor) return ERROR_CODE; +#endif + if (PARANOID && usbdev==NULL) { PRINTK(KERN_CRIT,"usbdev==NULL"); return ERROR_CODE; } + + /* We don't handle multi-config cameras */ + if (usbdev->descriptor.bNumConfigurations != 1) return ERROR_CODE; + + /* + * Checking vendor/product is not enough + * In case on QuickCam Web the audio is at class 1 and subclass 1/2. + * one /dev/dsp and one /dev/mixer + */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + ifacedesc = &interface->altsetting[0].desc; + ifacenum = ifacedesc->bInterfaceNumber; +#else + ifacedesc = &usbdev->actconfig->interface[ifacenum].altsetting[0]; +#endif + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGCAMERA) PDEBUG("qc_usb_probe(usbdev=%p,ifacenum=%i)", usbdev, ifacenum); + if (PARANOID && ifacedesc->bInterfaceNumber!=ifacenum) PRINTK(KERN_CRIT,"bInterfaceNumber(%i)!=ifacenum(%i)!!",ifacedesc->bInterfaceNumber,ifacenum); + if (ifacedesc->bInterfaceClass != 0xFF) return ERROR_CODE; + if (ifacedesc->bInterfaceSubClass != 0xFF) return ERROR_CODE; + + /* We found a QuickCam */ + PRINTK(KERN_INFO,"QuickCam USB camera found (driver version %s)", VERSION); + PRINTK(KERN_INFO,"Kernel:%s bus:%i class:%02X subclass:%02X vendor:%04X product:%04X", + UTS_RELEASE, usbdev->bus->busnum, ifacedesc->bInterfaceClass, ifacedesc->bInterfaceSubClass, + usbdev->descriptor.idVendor, usbdev->descriptor.idProduct); + + /* The interface is claimed (bound) automatically to us when we return from this function (without error code) */ + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("MOD_INC_USE_COUNT in qc_usb_probe() : %i",GET_USE_COUNT(THIS_MODULE)); + MOD_INC_USE_COUNT; /* Increase count to 1, which locks the module--it can't be removed */ + qc = qc_usb_init(usbdev, ifacenum); + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("MOD_DEC_USE_COUNT in qc_usb_probe() : %i",GET_USE_COUNT(THIS_MODULE)); + MOD_DEC_USE_COUNT; /* Release lock: module can be now removed again */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + if (!qc) return ERROR_CODE; + usb_set_intfdata(interface, qc); /* FIXME: why? */ + return 0; +#else + return qc; +#endif +} +/* }}} */ +/* {{{ [fold] qc_usb_exit(struct quickcam *qc) */ +/* Free up resources allocated in qc_usb_init() when not needed anymore + * Note: quickcam_list_lock and qc->lock must be acquired before entering this function! + * qc may not be accessed after this function returns! + */ +static void qc_usb_exit(struct quickcam *qc) +{ + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_usb_exit(qc=%p)",qc); + TEST_BUG_MSG(qc==NULL, "qc==NULL"); + + qc_proc_destroy(qc); + qc_adapt_exit(qc); + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("video_unregister_device(%p)", &qc->vdev); + video_unregister_device(&qc->vdev); + qc_i2c_exit(qc); + list_del(&qc->list); +PDEBUG("poisoning qc in qc_usb_exit"); + POISON(*qc); + kfree(qc); + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_usb_exit() done"); +} +/* }}} */ +/* {{{ [fold] qc_usb_disconnect(...) */ +/* Called when the camera is disconnected. We might not free struct quickcam here, + * because the camera might be in use (open() called). In that case, the freeing is + * postponed to the last close() call. However, all submitted URBs must be unlinked. + */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +static void qc_usb_disconnect(struct usb_interface *interface) +#else +static void qc_usb_disconnect(struct usb_device *usbdev, void *ptr) +#endif +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + struct quickcam *qc = usb_get_intfdata(interface); +#ifdef DEBUG + struct usb_device *usbdev = interface_to_usbdev(interface); +#endif +#else + struct quickcam *qc = (struct quickcam *)ptr; +#endif + + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGCAMERA) PDEBUG("qc_usb_disconnect(qc=%p)",qc); + TEST_BUG_MSG(qc==NULL, "qc==NULL in qc_usb_disconnect!"); + TEST_BUG_MSG(qc->dev==NULL || qc->connected==FALSE, "disconnecting disconnected device!!"); + TEST_BUG_MSG(usbdev!=qc->dev, "disconnecting not our device!!"); + + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("MOD_INC_USE_COUNT in qc_usb_disconnect() : %i",GET_USE_COUNT(THIS_MODULE)); + MOD_INC_USE_COUNT; /* Increase count to 1, which locks the module--it can't be removed */ + + /* + * When the camera is unplugged (maybe even when it is capturing), quickcam->connected is set to FALSE. + * All functions called from user mode and all _exit functions must check for this. + */ + qc->connected = FALSE; + + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("down(quickcam_list) in qc_usb_disconnect() : %i", sem_getcount(&quickcam_list_lock)); + down(&quickcam_list_lock); /* Also avoids race condition with open() */ + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("down(%p) in qc_usb_disconnect() : %i", qc, sem_getcount(&qc->lock)); + down(&qc->lock); /* Can not interrupt, we must success */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + usb_set_intfdata(interface, NULL); /* FIXME: why? */ +#endif + if (qc->users <= 0) { + /* Free resources */ + qc_usb_exit(qc); + } else { + /* Can not free resources if device is open: postpone to when it is closed */ + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("Disconnect while device open: postponing cleanup"); + qc_isoc_stop(qc); /* Unlink and free isochronous URBs */ + qc_i2c_wait(qc); /* Wait until there are no more I2C packets on way */ + qc->dev = NULL; /* Must be set to NULL only after interrupts are guaranteed to be disabled! */ + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(%p) in qc_usb_disconnect() : %i",qc, sem_getcount(&qc->lock)); + up(&qc->lock); + } + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(quickcam_list) in qc_usb_disconnect() : %i", sem_getcount(&quickcam_list_lock)); + up(&quickcam_list_lock); + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("MOD_DEC_USE_COUNT in qc_usb_disconnect() : %i",GET_USE_COUNT(THIS_MODULE)); + MOD_DEC_USE_COUNT; /* Release lock--if device is not open, module can be now freed */ + /* The interface is released automatically when we return from this function */ +} +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** qc: Start of module API ******************************* */ + +/* {{{ [fold] qc_init(void) */ +static int __init qc_init(void) +{ + int r; + if (qcdebug) PDEBUG("----------LOADING QUICKCAM MODULE------------"); + if (qcdebug) PDEBUG("struct quickcam size: %i", (int)sizeof(struct quickcam)); + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_init()"); + qc_proc_init(); /* Ignore if procfs entry creation fails */ + r = usb_register(&qc_usb_driver); + if (r<0) qc_proc_exit(); + if (r<0) if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGERRORS) PDEBUG("failed qc_init()=%i",r); + return r; +} +/* }}} */ +/* {{{ [fold] qc_exit(void) */ +static void __exit qc_exit(void) +{ + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_exit()"); + usb_deregister(&qc_usb_driver); /* Will also call qc_usb_disconnect() if necessary */ + qc_proc_exit(); +} +/* }}} */ + +module_init(qc_init); +module_exit(qc_exit); +/* }}} */ + +/* End of file */ --- linux-2.6.28.orig/ubuntu/qc-usb/quickcam.h +++ linux-2.6.28/ubuntu/qc-usb/quickcam.h @@ -0,0 +1,585 @@ +#ifndef _LINUX_QUICKCAM_H +#define _LINUX_QUICKCAM_H + +/* {{{ [fold] SECTION: common definitions with userspace applications */ +#define QC_LUT_SIZE (3*256) /* Lookup table definition for equalization */ +#define QC_LUT_RED 0 +#define QC_LUT_GREEN 256 +#define QC_LUT_BLUE 512 + +struct qc_userlut { + unsigned int flags; +#define QC_USERLUT_DEFAULT 1 /* If set, change default settings or the current camera otherwise */ +#define QC_USERLUT_ENABLE 2 /* If set, enable user-specified LUT, or otherwise disable it */ +#define QC_USERLUT_VALUES 4 /* Load new (or store old) values into the lookup-table */ + unsigned char lut[QC_LUT_SIZE]; /* Lookup table to set or read */ +}; + +#define VIDEO_PALETTE_BAYER (('q'<<8) | 1) /* Grab video in raw Bayer format */ +#define VIDEO_PALETTE_MJPEG (('q'<<8) | 2) /* Grab video in compressed MJPEG format */ +#define VID_HARDWARE_QCAM_USB (('q'<<8) | 50) /* Device type */ + +/* Private IOCTL calls */ +#define QC_IOCTLBASE 220 /* Don't use same numbers as Philips driver */ +#define VIDIOCQCGDEBUG _IOR ('v',QC_IOCTLBASE+0, int) /* Gets the debug output, bitfield */ +#define VIDIOCQCSDEBUG _IOWR('v',QC_IOCTLBASE+0, int) /* Sets the debug output, bitfield */ +#define VIDIOCQCGKEEPSETTINGS _IOR ('v',QC_IOCTLBASE+1, int) /* Get keep picture settings across one open to another (0-1) */ +#define VIDIOCQCSKEEPSETTINGS _IOWR('v',QC_IOCTLBASE+1, int) /* Set keep picture settings across one open to another (0-1) */ +#define VIDIOCQCGSETTLE _IOR ('v',QC_IOCTLBASE+2, int) /* Get if we let image brightness settle (0-1) */ +#define VIDIOCQCSSETTLE _IOWR('v',QC_IOCTLBASE+2, int) /* Set if we let image brightness settle (0-1) */ +#define VIDIOCQCGSUBSAMPLE _IOR ('v',QC_IOCTLBASE+3, int) /* Gets the speed (0-1) */ +#define VIDIOCQCSSUBSAMPLE _IOWR('v',QC_IOCTLBASE+3, int) /* Sets the speed (0-1) */ +#define VIDIOCQCGCOMPRESS _IOR ('v',QC_IOCTLBASE+4, int) /* Gets the compression mode (0-1) */ +#define VIDIOCQCSCOMPRESS _IOWR('v',QC_IOCTLBASE+4, int) /* Sets the compression mode (0-1) */ +#define VIDIOCQCGFRAMESKIP _IOR ('v',QC_IOCTLBASE+5, int) /* Get frame capture frequency (0-10) */ +#define VIDIOCQCSFRAMESKIP _IOWR('v',QC_IOCTLBASE+5, int) /* Set frame capture frequency (0-10) */ +#define VIDIOCQCGQUALITY _IOR ('v',QC_IOCTLBASE+6, int) /* Gets the interpolation mode (0-2) */ +#define VIDIOCQCSQUALITY _IOWR('v',QC_IOCTLBASE+6, int) /* Sets the interpolation mode (0-2) */ +#define VIDIOCQCGADAPTIVE _IOR ('v',QC_IOCTLBASE+7, int) /* Get automatic adaptive brightness control (0-1) */ +#define VIDIOCQCSADAPTIVE _IOWR('v',QC_IOCTLBASE+7, int) /* Set automatic adaptive brightness control (0-1) */ +#define VIDIOCQCGEQUALIZE _IOR ('v',QC_IOCTLBASE+8, int) /* Get equalize image (0-1) */ +#define VIDIOCQCSEQUALIZE _IOWR('v',QC_IOCTLBASE+8, int) /* Set equalize image (0-1) */ +#define VIDIOCQCGRETRYERRORS _IOR ('v',QC_IOCTLBASE+9, int) /* Get if we retry when capture fails (0-1) */ +#define VIDIOCQCSRETRYERRORS _IOWR('v',QC_IOCTLBASE+9, int) /* Set if we retry when capture fails (0-1) */ +#define VIDIOCQCGCOMPATIBLE _IOR ('v',QC_IOCTLBASE+10,int) /* Get enable workaround for bugs, bitfield */ +#define VIDIOCQCSCOMPATIBLE _IOWR('v',QC_IOCTLBASE+10,int) /* Set enable workaround for bugs, bitfield */ +#define VIDIOCQCGVIDEONR _IOR ('v',QC_IOCTLBASE+11,int) /* Get videodevice number (/dev/videoX) */ +#define VIDIOCQCSVIDEONR _IOWR('v',QC_IOCTLBASE+11,int) /* Set videodevice number (/dev/videoX) */ +#define VIDIOCQCGUSERLUT _IOR ('v',QC_IOCTLBASE+12,struct qc_userlut) /* Get user-specified lookup-table correction */ +#define VIDIOCQCSUSERLUT _IOWR('v',QC_IOCTLBASE+12,struct qc_userlut) /* Set user-specified lookup-table correction */ + +#define VIDIOCQCGSTV _IOWR('v',QC_IOCTLBASE+20,int) /* Read STV chip register */ +#define VIDIOCQCSSTV _IOW ('v',QC_IOCTLBASE+20,int) /* Write STV chip register */ +#define VIDIOCQCGI2C _IOWR('v',QC_IOCTLBASE+21,int) /* Read I2C chip register */ +#define VIDIOCQCSI2C _IOW ('v',QC_IOCTLBASE+21,int) /* Write I2C chip register */ + +/* Debugging message choices */ +#define QC_DEBUGUSER (1<<0) /* Messages for interaction with user space (system calls) */ +#define QC_DEBUGCAMERA (1<<1) /* Messages for interaction with the camera */ +#define QC_DEBUGINIT (1<<2) /* Messages for each submodule initialization/deinit */ +#define QC_DEBUGLOGIC (1<<3) /* Messages for entering and failing important functions */ +#define QC_DEBUGERRORS (1<<4) /* Messages for all error conditions */ +#define QC_DEBUGADAPTATION (1<<5) /* Messages for automatic exposure control workings */ +#define QC_DEBUGCONTROLURBS (1<<6) /* Messages for sending I2C control messages via USB */ +#define QC_DEBUGBITSTREAM (1<<7) /* Messages for finding chunk codes from camera bitstream */ +#define QC_DEBUGINTERRUPTS (1<<8) /* Messages for each interrupt */ +#define QC_DEBUGMUTEX (1<<9) /* Messages for acquiring/releasing the mutex */ +#define QC_DEBUGCOMMON (1<<10) /* Messages for some common warnings */ +#define QC_DEBUGFRAME (1<<11) /* Messages related to producer-consumer in qc_frame_* functions */ +#define QC_DEBUGALL (~0) /* Messages for everything */ + +/* Compatibility choices */ +#define QC_COMPAT_16X (1<<0) +#define QC_COMPAT_DBLBUF (1<<1) +#define QC_COMPAT_TORGB (1<<2) /* Video4Linux API is buggy and doesn't specify byte order for RGB images */ +/* }}} */ + +#ifdef __KERNEL__ + +#include +#include + +#ifdef CONFIG_SMP +#define __SMP__ +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS) +#define MODVERSIONS +#endif +#ifdef MODVERSIONS +#include +#endif +#endif + +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) +#include +#endif +#include +#include /* This is required for testing pte_offset_map */ +#include + +/* {{{ [fold] SECTION: user configuration */ +#define VERSION "QuickCam USB 0.6.6 $Date: 2006/11/04 08:38:14 $" +#ifndef COMPRESS +#define COMPRESS 1 /* 1=include compression support, 0=otherwise */ +#endif +#ifndef DEBUGLEVEL +#define DEBUGLEVEL QC_DEBUGCOMMON +#endif +#ifdef NDEBUG /* Enable debugging if DEBUG is defined; if (also) NDEBUG is defined, disable debugging */ +#undef DEBUG +#endif +//#define DEBUG /* Enable debug code */ +#ifdef DEBUG +#define PARANOID 1 /* Check consistency of driver state */ +#else +#define PARANOID 0 +#endif +/* Default (initial) values */ +#define DEFAULT_BGR TRUE /* Use BGR byte order by default (and torgb converts to RGB)? */ + +#define DUMPDATA 0 /* Dump data from camera to user, no conversion nor length checks (see show.c) */ +/* }}} */ +/* {{{ [fold] SECTION: general utility definitions and macros */ +#define FALSE 0 +#define TRUE (!FALSE) +typedef unsigned char Bool; +//#define BIT(x) (1<<(x)) +#define SIZE(a) (sizeof(a)/sizeof((a)[0])) +#define MAX(a,b) ((a)>(b)?(a):(b)) +#define MIN(a,b) ((a)<(b)?(a):(b)) +#define MAX3(a,b,c) (MAX(a,MAX(b,c))) +#define MIN3(a,b,c) (MIN(a,MIN(b,c))) +#define CLIP(a,low,high) MAX((low),MIN((high),(a))) +#define ABS(a) ((a)>0?(a):-(a)) +#define SGN(a) ((a)<0 ? -1 : ((a)>0 ? 1 : 0)) +#define CHECK_ERROR(cond,jump,msg,args...) if (cond) { PDEBUG(msg, ## args); goto jump; } +#define GET_VENDORID(qc) ((qc)->dev->descriptor.idVendor) +#define GET_PRODUCTID(qc) ((qc)->dev->descriptor.idProduct) +/* }}} */ +/* {{{ [fold] SECTION: compatibility */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18) +#error "Too old kernel. At least Linux 2.2.18 is required." +#endif + +#if LINUX_VERSION_CODE==KERNEL_VERSION(2,4,19) || LINUX_VERSION_CODE==KERNEL_VERSION(2,4,20) +#warning "Kernels 2.4.19 and 2.4.20 are buggy! Be sure to install patch from:" +#warning "http://www.ee.oulu.fi/~tuukkat/quickcam/linux-2.4.20-videodevfix.patch" +#endif + +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,5,0) && LINUX_VERSION_CODE=KERNEL_VERSION(2,7,0) +#warning "Unsupported kernel, may or may not work. Good luck!" +#endif + +#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,4,0) && defined(CONFIG_PROC_FS) +#define HAVE_PROCFS 1 /* FIXME: I don't think there's any reason to disable procfs with 2.2.x */ +#else +#define HAVE_PROCFS 0 +#warning "procfs support disabled" +#endif + +#ifndef HAVE_VMA +#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,5,3) || (defined(RED_HAT_LINUX_KERNEL) && defined(pte_offset_map)) +/* Some RedHat 9 2.4.x patched-to-death kernels need this too */ +#define HAVE_VMA 1 +#else +#define HAVE_VMA 0 +#endif +#endif + +#if HAVE_VMA && LINUX_VERSION_CODE=KERNEL_VERSION(2,6,0) +/* Things come and go... */ +/* Used only for debugging, so this could be actually removed if needed */ +#define sem_getcount(sem) atomic_read(&(sem)->count) +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) +static inline int qc_usb_submit_urb(struct urb *urb) { return usb_submit_urb(urb); } +static inline struct urb *qc_usb_alloc_urb(int packets) { return usb_alloc_urb(packets); } +#undef usb_submit_urb +#undef usb_alloc_urb +#define usb_submit_urb(u,f) qc_usb_submit_urb(u) +#define usb_alloc_urb(u,f) qc_usb_alloc_urb(u) +#define URB_ISO_ASAP USB_ISO_ASAP +#endif + +#ifndef list_for_each_entry +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member)) +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +#undef MOD_INC_USE_COUNT +#undef MOD_DEC_USE_COUNT +#define MOD_INC_USE_COUNT +#define MOD_DEC_USE_COUNT +#define GET_USE_COUNT(module) 1 +#define EXPORT_NO_SYMBOLS +#endif + +/* }}} */ +/* {{{ [fold] SECTION: debugging */ +#undef PDEBUG /* undef it, just in case */ +#define POISON_VAL 0x5B + +#ifdef DEBUG + +#include +/* PDEBUG is rather heavyweight macro and should be used only for debugging--not for general messages */ +/* Based on timestamp by Roger Wolff */ +#define PDEBUG(fmt, args...) \ + do { \ + struct timeval __tv_val; \ + do_gettimeofday(&__tv_val); \ + printk(KERN_DEBUG "quickcam [%2ld.%06ld]: ", __tv_val.tv_sec%60, __tv_val.tv_usec); \ + printk(fmt, ## args); \ + printk("\n"); \ + } while(0) +#define IDEBUG_VAR char *idebug_var; +#define IDEBUG_INIT(x) do { \ + if ((x).idebug_var==((char*)&((x).idebug_var)) + 0xB967E57D) printk(KERN_CRIT __FILE__ ":%i: Init already done\n",__LINE__); \ + (x).idebug_var = ((char*)&((x).idebug_var)) + 0xB967E57D; \ +} while(0) +#define IDEBUG_TEST(x) do { \ + if ((x).idebug_var!=((char*)&((x).idebug_var)) + 0xB967E57D) printk(KERN_CRIT __FILE__ ":%i: Init missing\n",__LINE__); \ +} while(0) +#define IDEBUG_EXIT(x) do { \ + IDEBUG_TEST(x); \ + (x).idebug_var = NULL; \ + POISON(x); \ +} while(0) +#define IDEBUG_EXIT_NOPOISON(x) do { \ + IDEBUG_TEST(x); \ + (x).idebug_var = NULL; \ +} while(0) +#define TEST_BUG(condition) \ + do { \ + if ((condition)!=0) { \ + PDEBUG("Badness in %s at %s:%d", __FUNCTION__, __FILE__, __LINE__); \ + return; \ + } \ + } while (0) +#define TEST_BUGR(condition) \ + do { \ + if ((condition)!=0) { \ + PDEBUG("Badness in %s at %s:%d", __FUNCTION__, __FILE__, __LINE__); \ + return -EFAULT; \ + } \ + } while (0) +#define TEST_BUG_MSG(cond, fmt, args...) \ + do { \ + if ((cond)!=0) { \ + PDEBUG(fmt, ## args); \ + PDEBUG("Badness in %s at %s:%d", __FUNCTION__, __FILE__, __LINE__); \ + return; \ + } \ + } while (0) +#define TEST_BUGR_MSG(cond, fmt, args...) \ + do { \ + if ((cond)!=0) { \ + PDEBUG(fmt, ## args); \ + PDEBUG("Badness in %s at %s:%d", __FUNCTION__, __FILE__, __LINE__); \ + return -EFAULT; \ + } \ + } while (0) +#define POISON(obj) do { memset(&(obj),POISON_VAL,sizeof(obj)); } while(0) + +#else + +#define PDEBUG(fmt, args...) +#define IDEBUG_VAR +#define IDEBUG_INIT(x) +#define IDEBUG_TEST(x) +#define IDEBUG_EXIT(x) +#define IDEBUG_EXIT_NOPOISON(x) +#define TEST_BUG(x) +#define TEST_BUGR(x) +#define TEST_BUG_MSG(cond, fmt, args...) +#define TEST_BUGR_MSG(cond, fmt, args...) +#define POISON(obj) + +#endif /* DEBUG */ + +//gcc is buggy? This doesn't work +//#define PRINTK(lvl, fmt, args...) printk(lvl "quickcam: " fmt "\n", ## args) +#define PRINTK(lvl, fmt, args...) do { printk(lvl "quickcam: " fmt, ## args); printk("\n"); } while (0) +/* }}} */ +/* {{{ [fold] SECTION: hardware related stuff */ +#define QUICKCAM_ISOPIPE 0x81 + +/* Control register of the STV0600 ASIC */ +#define STV_ISO_ENABLE 0x1440 +#define STV_SCAN_RATE 0x1443 +#define STV_ISO_SIZE 0x15C1 +#define STV_Y_CTRL 0x15C3 +#define STV_X_CTRL 0x1680 +#define STV_REG00 0x1500 +#define STV_REG01 0x1501 +#define STV_REG02 0x1502 +#define STV_REG03 0x1503 +#define STV_REG04 0x1504 +#define STV_REG23 0x0423 + +/* Maximum frame size that any sensor can deliver */ +#define MAX_FRAME_WIDTH 360 +#define MAX_FRAME_HEIGHT 296 +/* }}} */ +/* {{{ [fold] SECTION: struct quickcam datatype and related values */ + +/* {{{ [fold] qc_sensor_data: Sensor related data (unique to each camera) */ +struct qc_sensor_data { + const struct qc_sensor *sensor; /* Autodetected when camera is plugged in */ + int maxwidth; /* Maximum size the sensor can deliver */ + int maxheight; + int width; /* Size delivered by the sensor (-1=unknown) */ + int height; + int exposure; /* Current exposure in effect (sensor-specific value, -1=unknown) */ + int rgain, ggain, bgain; /* Current gains in effect (sensor-specific values, -1=unknown) */ + unsigned int subsample : 1; /* Set into subsampling mode? */ + unsigned int compress : 1; /* Set into compressed mode? */ +}; +/* }}} */ +/* {{{ [fold] qc_i2c_data: I2C command queue for writing commands to camera */ +#define I2C_MAXCOMMANDS 16 /* Should be about 1-2 times the size of transfer buffer (=16) for maximum performance */ +#define I2C_FLAG_WORD BIT(0) /* Set if a 16-bit value is sent, otherwise 8-bit value */ +#define I2C_FLAG_BREAK BIT(1) /* Set if this is the last command in a packet */ +struct qc_i2c_data { + struct urb *urb; + struct { + u8 loval; + u8 hival; + u8 regnum; + u8 flags; + } commands[I2C_MAXCOMMANDS]; + /* 2=URB scheduled, need to schedule extra packet for QuickCam Web at completion */ + volatile int packets; /* 0=no URBs scheduled, 1=URB scheduled */ + volatile unsigned int newhead; /* Points to first free buffer position */ + volatile unsigned int head; /* Points to oldest command which was not yet flushed */ + volatile unsigned int tail; /* Points to next position which needs to be send, modified from interrupt */ + wait_queue_head_t wq; /* Woken up when all pending data is sent */ + IDEBUG_VAR +}; +/* }}} */ +/* {{{ [fold] qc_isoc_data: Isochronous transfer queue control data for reading from camera */ +#define ISOC_URBS 2 /* Number of URBs to use */ +#define ISOC_PACKETS 10 /* How many isochronous data packets per URB */ +#define ISOC_PACKET_SIZE 1023 /* Max size of one packet (shouldn't be hardcoded JFC was 960) */ +struct qc_isoc_data { + struct urb *urbs[ISOC_URBS]; + unsigned char *buffer; /* Isochronous data transfer buffers */ + int errorcount; + Bool streaming; /* TRUE if URBs are allocated and submitted */ + IDEBUG_VAR +}; +/* }}} */ +/* {{{ [fold] qc_stream_data: Camera data stream control data */ +struct qc_stream_data { + Bool capturing; /* Are we capturing data for a frame? */ + int frameskip; /* How frequently to capture frames? 0=each frame, 1=every other */ + IDEBUG_VAR +}; +/* }}} */ +/* {{{ [fold] qc_frame_data: Raw frame (bayer/mjpeg) buffers */ +#define FRAME_BUFFERS 2 /* We are double buffering */ +#define FRAME_DATASIZE (MAX_FRAME_WIDTH*MAX_FRAME_HEIGHT) /* About 101 kilobytes (assume that compressed frame is always smaller) */ +struct qc_frame_data { + struct { + int rawdatalen; /* Number of used bytes of this frame buffer */ + } buffers[FRAME_BUFFERS]; + unsigned char *rawdatabuf; /* vmalloc'd chunk containing the all raw frame data buffers concatenated */ + int maxrawdatalen; /* Maximum amount of data we are willing to accept in bytes, */ + /* zero indicates that we are not grabbing current frame (but just throwing data away) */ + volatile unsigned int head; /* The buffer to be captured next (empty or grabbing, if full, then whole buffer is full) */ + volatile unsigned int tail; /* The buffer to be consumed next (full, unless equals head, then it is empty/grabbing) */ + spinlock_t tail_lock; /* Protects tail changes */ + volatile Bool tail_in_use; /* TRUE, when consumer is processing the frame pointed to by tail */ + + wait_queue_head_t wq; /* Processes waiting for more data in the buffer */ + volatile int waiting; /* Number of processes waiting in the wait queues */ + volatile Bool exiting; /* Set to TRUE when we want to quit */ + volatile int lost_frames; /* Increased by one for every lost (non-captured by applications) frame, reset when a frame is captured */ + IDEBUG_VAR +}; +/* }}} */ +/* {{{ [fold] qc_mjpeg_data: MJPEG decoding data */ +struct qc_mjpeg_data { + int depth; /* Bits per pixel in the final RGB image: 16 or 24 */ + u8 *encV; /* Temporary buffers for holding YUV image data */ + u8 *encU; + u8 *encY; + /* yuv2rgb private data */ + void *table; + void *table_rV[256]; + void *table_gU[256]; + int table_gV[256]; + void *table_bU[256]; + void (*yuv2rgb_func)(struct qc_mjpeg_data *, u8 *, u8 *, u8 *, u8 *, void *, void *, int); + IDEBUG_VAR +}; +/* }}} */ +/* {{{ [fold] qc_fmt_data: Format conversion routines private data */ +struct qc_fmt_data { + unsigned char userlut[QC_LUT_SIZE]; /* User specified fixed look-up table, initialized when camera is plugged in */ + unsigned char lut[QC_LUT_SIZE]; /* Dynamically calculated LUT, for which userlut is applied to */ +#if COMPRESS + struct qc_mjpeg_data mjpeg_data; + Bool compress; /* Was compression subsystem initialized? */ +#endif + IDEBUG_VAR +}; +/* }}} */ +/* {{{ [fold] qc_capt_data: Formatted image capturing control data */ +/* qc_capt_data: Formatted image capturing control data. */ +#define MAX_FRAME_SIZE (MAX_FRAME_WIDTH*MAX_FRAME_HEIGHT*4) /* Video Size 356x292x4 bytes for 0RGB 32 bpp mode */ +struct qc_capt_data { + unsigned char *frame; /* Final image data buffer given to application, size MAX_FRAME_SIZE (mmappable) */ + Bool settled; /* Has the picture settled after last open? */ + IDEBUG_VAR +}; +/* }}} */ +/* {{{ [fold] qc_adapt_data: Automatic exposure control data */ +/* There are three different exposure control algorithms for different cases */ +struct qc_adapt_data { + int olddelta; + int oldmidvalue, midvaluesum; + int oldexposure, exposure; + int gain; + int framecounter; + enum { + EXPCONTROL_SATURATED, /* Picture is over/undersaturated, halve/double brightness */ + EXPCONTROL_NEWTON, /* Using Newton linear estimation */ + EXPCONTROL_FLOAT, /* Very near correct brightness, float exposure slightly */ + } controlalg; + IDEBUG_VAR +}; +/* }}} */ +/* {{{ [fold] qc_settings_data: User settings given by qcset or module parameters, initialized when camera is plugged in */ +struct qc_settings_data { + unsigned int keepsettings : 1; /* Keep all settings at each camera open (or reset most of them) */ + unsigned int subsample : 1; /* Normal or sub-sample (sub-sample to increase the speed) */ + unsigned int compress : 1; /* Enable compressed mode if available (higher framerate) */ + unsigned int frameskip : 4; /* How many frames to skip (higher=lower framerate) */ + unsigned int quality : 3; /* Quality of format conversion (higher=better but slower) */ + unsigned int adaptive : 1; /* Use automatic exposure control */ + unsigned int equalize : 1; /* Equalize images */ + unsigned int userlut : 1; /* Apply user-specified lookup-table */ + unsigned int retryerrors : 1; /* If errors happen when capturing an image, retry a few times? */ + unsigned int compat_16x : 1; /* Compatibility: force image size to multiple of 16 */ + unsigned int compat_dblbuf : 1; /* Compatibility: fake doublebuffering for applications */ + unsigned int compat_torgb : 1; /* Compatibility: use RGB data order, not BGR */ + unsigned int settle : 8; /* Maximum number of frames to wait image brightness to settle */ + /* Total: 25 bits */ +}; +/* }}} */ + +/* Main per-camera data structure, most important thing in whole driver */ +struct quickcam { + /* The following entries are initialized in qc_usb_init() when camera is plugged in */ + struct semaphore lock; /* Allow only one process to access quickcam at a time */ + struct list_head list; /* All cameras are in a doubly linked list */ + int users; /* User count (simultaneous open count) */ + struct usb_device *dev; /* USB device, set to NULL when camera disconnected and interrupts disabled */ + unsigned char iface; /* The interface number in the camera device we are bound to */ + Bool connected; /* Set to FALSE immediately when the camera is disconnected (even before interrupts are disabled) */ + struct video_device vdev; /* Used for registering the camera driver for Video4Linux */ + struct qc_settings_data settings; /* General user settings set with e.g. qcset */ +#if HAVE_PROCFS + struct proc_dir_entry *proc_entry; +#endif + /* The following entries are initialized in qc_v4l_init() when the camera device is opened */ + struct video_picture vpic; /* Contains the last values set by user (which is reported to user) */ + Bool vpic_pending; /* Settings in vpic were changed but are not yet in effect */ + struct video_window vwin; /* Contains the image size and position the user is expecting */ + + /* Private structures for each module, initialized in corresponding init-function */ + struct qc_i2c_data i2c_data; /* Filled when the camera is plugged in or driver loaded */ + struct qc_adapt_data adapt_data; /* Filled when the camera is plugged in or driver loaded */ + struct qc_sensor_data sensor_data; /* Mostly filled when the device is opened */ + struct qc_stream_data stream_data; /* Filled when the device is opened */ + struct qc_frame_data frame_data; /* Filled when the device is opened */ + struct qc_capt_data capt_data; /* Filled when the device is opened */ + struct qc_isoc_data isoc_data; /* Filled when the device is opened */ + struct qc_fmt_data fmt_data; /* Mostly filled when the device is opened, except for userlut */ + + u8 dmabuf[35]; /* Temporary buffer which may be used for DMA transfer */ +}; +/* }}} */ +/* {{{ [fold] SECTION: miscelleneous */ +/* Constant information related to a sensor type */ +struct qc_sensor { + char *name; + char *manufacturer; + int (*init)(struct quickcam *qc); /* Initialize sensor */ + int (*start)(struct quickcam *qc); /* Start sending image data */ + int (*stop)(struct quickcam *qc); /* Stop sending image data */ + int (*set_size)(struct quickcam *qc, unsigned int w, unsigned int h); /* Request camera to send the given image size */ + /* Set primary brightness value exp (usually exposure time) and HSV 0-65535 (usually gains) */ + int (*set_levels)(struct quickcam *qc, unsigned int exp, unsigned int gain, unsigned int hue, unsigned int sat); + int (*set_target)(struct quickcam *qc, unsigned int val); /* Set target brightness for sensor autoexposure 0-65535 */ + /* Exposure and gain control information */ + Bool autoexposure; /* Sensor has automatic exposure control */ + int adapt_gainlow; /* (0-65535) How eagerly to decrease gain when necessary */ + int adapt_gainhigh; /* (0-65535) How eagerly to increase gain when necessary */ + /* Information needed to access the sensor via I2C */ + int reg23; + unsigned char i2c_addr; + /* Identification information used for auto-detection */ + int id_reg; + unsigned char id; + int length_id; + int flag; /* May be used by sensor driver for private purposes */ +}; +/* }}} */ +/* {{{ [fold] SECTION: function prototypes */ +/* USB interface chip control */ +int qc_i2c_break(struct quickcam *qc); +int qc_i2c_wait(struct quickcam *qc); +int qc_i2c_set(struct quickcam *qc, unsigned char reg, unsigned char val); +int qc_i2c_setw(struct quickcam *qc, unsigned char reg, unsigned short val); + +int qc_stv_set(struct quickcam *qc, unsigned short reg, unsigned char val); +int qc_stv_setw(struct quickcam *qc, unsigned short reg, unsigned short val); +int qc_stv_get(struct quickcam *qc, unsigned short reg); + +/* Image format conversion routines */ +int qc_fmt_convert(struct quickcam *qc, unsigned char *src, unsigned int src_len, unsigned char *dst, unsigned int dst_len, int *midvalue); +int qc_fmt_issupported(int format); +const char *qc_fmt_getname(int format); +int qc_fmt_getdepth(int format); +int qc_fmt_init(struct quickcam *qc); +void qc_fmt_exit(struct quickcam *qc); + +int qc_mjpeg_decode(struct qc_mjpeg_data *md, unsigned char *src, int src_len, unsigned char *dst); +int qc_mjpeg_init(struct qc_mjpeg_data *md, int depth, Bool tobgr); +void qc_mjpeg_exit(struct qc_mjpeg_data *md); + +void qc_hsv2rgb(s16 hue, u16 sat, u16 val, int *red, int *green, int *blue); +int qc_get_i2c(struct quickcam *qc, const struct qc_sensor *sensor, int reg); +void qc_frame_flush(struct quickcam *qc); + +void qc_usleep(unsigned long usec); +extern int qcdebug; /* Driver debuglevel */ +/* }}} */ + +#endif /* __KERNEL__ */ + +#endif /* __LINUX_QUICKCAM_H */ --- linux-2.6.28.orig/ubuntu/qc-usb/qc-formats.c +++ linux-2.6.28/ubuntu/qc-usb/qc-formats.c @@ -0,0 +1,1545 @@ +/* Start of file */ + +/* {{{ [fold] Comments */ +/* + * qc-usb, linux V4L driver for the Logitech QuickCam family + * + * qc-formats.c - converts color formats + * + * Copyright (c) 2001 Jean-Frederic Clere (RGB->YUV conversion) + * 2001 Aaron Holtzman (YUV->RGB conversion, from mpeg2dec) + * 2003 Tuukka Toivonen (Bayer->RGB conversion) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 "quickcam.h" +#include + +#ifndef v4l2_fourcc +/* Four-character-code (FOURCC) */ +#define v4l2_fourcc(a,b,c,d)\ + (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24)) +#endif + +/* {{{ [fold] **** qc_yuv: Start of RGB to YUV conversion functions ******************** */ + +/* {{{ [fold] qc_yuv_interp[256][8] */ +static signed short qc_yuv_interp[256][8] = { +{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,1,0,0,0,1,0,0},{0,1,0,0,0,1,-1,0}, +{1,2,0,0,-1,2,-1,0},{1,2,0,0,-1,2,-2,0},{1,3,0,-1,-1,3,-2,0},{2,3,0,-1,-2,3,-2,0}, +{2,4,0,-1,-2,4,-3,0},{2,5,1,-1,-2,4,-3,0},{2,5,1,-1,-3,5,-4,0},{3,6,1,-1,-3,5,-4,0}, +{3,6,1,-2,-3,6,-5,0},{3,7,1,-2,-4,6,-5,-1},{4,7,1,-2,-4,7,-5,-1},{4,8,1,-2,-4,7,-6,-1}, +{4,9,1,-2,-5,8,-6,-1},{5,9,1,-2,-5,8,-7,-1},{5,10,2,-3,-5,9,-7,-1},{5,10,2,-3,-6,9,-7,-1}, +{5,11,2,-3,-6,10,-8,-1},{6,11,2,-3,-6,10,-8,-1},{6,12,2,-3,-7,11,-9,-1},{6,13,2,-3,-7,11,-9,-1}, +{7,13,2,-4,-7,12,-10,-1},{7,14,2,-4,-8,12,-10,-2},{7,14,2,-4,-8,13,-10,-2},{8,15,3,-4,-8,13,-11,-2}, +{8,15,3,-4,-9,14,-11,-2},{8,16,3,-4,-9,14,-12,-2},{8,17,3,-5,-9,15,-12,-2},{9,17,3,-5,-10,15,-12,-2}, +{9,18,3,-5,-10,16,-13,-2},{9,18,3,-5,-10,16,-13,-2},{10,19,3,-5,-11,17,-14,-2},{10,19,3,-5,-11,17,-14,-2}, +{10,20,4,-6,-11,18,-15,-2},{11,20,4,-6,-12,18,-15,-3},{11,21,4,-6,-12,19,-15,-3},{11,22,4,-6,-12,19,-16,-3}, +{11,22,4,-6,-13,20,-16,-3},{12,23,4,-6,-13,20,-17,-3},{12,23,4,-7,-13,21,-17,-3},{12,24,4,-7,-14,21,-18,-3}, +{13,24,5,-7,-14,22,-18,-3},{13,25,5,-7,-14,22,-18,-3},{13,26,5,-7,-15,23,-19,-3},{14,26,5,-7,-15,23,-19,-3}, +{14,27,5,-8,-15,24,-20,-3},{14,27,5,-8,-16,24,-20,-3},{14,28,5,-8,-16,25,-20,-4},{15,28,5,-8,-16,25,-21,-4}, +{15,29,5,-8,-17,26,-21,-4},{15,30,6,-8,-17,26,-22,-4},{16,30,6,-9,-17,27,-22,-4},{16,31,6,-9,-18,27,-23,-4}, +{16,31,6,-9,-18,28,-23,-4},{17,32,6,-9,-18,28,-23,-4},{17,32,6,-9,-19,29,-24,-4},{17,33,6,-9,-19,29,-24,-4}, +{17,34,6,-10,-19,30,-25,-4},{18,34,6,-10,-20,30,-25,-4},{18,35,7,-10,-20,31,-25,-5},{18,35,7,-10,-20,31,-26,-5}, +{19,36,7,-10,-21,32,-26,-5},{19,36,7,-10,-21,32,-27,-5},{19,37,7,-11,-21,33,-27,-5},{20,37,7,-11,-22,33,-28,-5}, +{20,38,7,-11,-22,34,-28,-5},{20,39,7,-11,-22,34,-28,-5},{20,39,7,-11,-23,35,-29,-5},{21,40,8,-11,-23,35,-29,-5}, +{21,40,8,-12,-23,36,-30,-5},{21,41,8,-12,-24,36,-30,-5},{22,41,8,-12,-24,37,-30,-6},{22,42,8,-12,-24,37,-31,-6}, +{22,43,8,-12,-25,38,-31,-6},{23,43,8,-12,-25,38,-32,-6},{23,44,8,-13,-25,39,-32,-6},{23,44,9,-13,-26,39,-33,-6}, +{23,45,9,-13,-26,40,-33,-6},{24,45,9,-13,-26,40,-33,-6},{24,46,9,-13,-27,41,-34,-6},{24,47,9,-14,-27,41,-34,-6}, +{25,47,9,-14,-27,42,-35,-6},{25,48,9,-14,-28,42,-35,-6},{25,48,9,-14,-28,43,-36,-6},{26,49,9,-14,-28,43,-36,-7}, +{26,49,10,-14,-29,44,-36,-7},{26,50,10,-15,-29,44,-37,-7},{26,51,10,-15,-29,45,-37,-7},{27,51,10,-15,-30,45,-38,-7}, +{27,52,10,-15,-30,46,-38,-7},{27,52,10,-15,-30,46,-38,-7},{28,53,10,-15,-31,47,-39,-7},{28,53,10,-16,-31,47,-39,-7}, +{28,54,10,-16,-31,48,-40,-7},{29,54,11,-16,-32,48,-40,-7},{29,55,11,-16,-32,49,-41,-7},{29,56,11,-16,-32,49,-41,-8}, +{29,56,11,-16,-33,50,-41,-8},{30,57,11,-17,-33,50,-42,-8},{30,57,11,-17,-33,51,-42,-8},{30,58,11,-17,-34,51,-43,-8}, +{31,58,11,-17,-34,52,-43,-8},{31,59,11,-17,-34,52,-43,-8},{31,60,12,-17,-35,53,-44,-8},{31,60,12,-18,-35,53,-44,-8}, +{32,61,12,-18,-35,54,-45,-8},{32,61,12,-18,-36,54,-45,-8},{32,62,12,-18,-36,55,-46,-8},{33,62,12,-18,-36,55,-46,-9}, +{33,63,12,-18,-37,56,-46,-9},{33,64,12,-19,-37,56,-47,-9},{34,64,12,-19,-37,57,-47,-9},{34,65,13,-19,-38,57,-48,-9}, +{34,65,13,-19,-38,58,-48,-9},{34,66,13,-19,-38,58,-48,-9},{35,66,13,-19,-39,59,-49,-9},{35,67,13,-20,-39,59,-49,-9}, +{35,68,13,-20,-39,60,-50,-9},{36,68,13,-20,-40,60,-50,-9},{36,69,13,-20,-40,61,-51,-9},{36,69,14,-20,-40,61,-51,-9}, +{37,70,14,-20,-41,62,-51,-10},{37,70,14,-21,-41,62,-52,-10},{37,71,14,-21,-41,63,-52,-10},{37,72,14,-21,-42,63,-53,-10}, +{38,72,14,-21,-42,64,-53,-10},{38,73,14,-21,-42,64,-54,-10},{38,73,14,-21,-43,65,-54,-10},{39,74,14,-22,-43,65,-54,-10}, +{39,74,15,-22,-43,66,-55,-10},{39,75,15,-22,-44,66,-55,-10},{40,75,15,-22,-44,67,-56,-10},{40,76,15,-22,-44,67,-56,-10}, +{40,77,15,-22,-45,68,-56,-11},{40,77,15,-23,-45,68,-57,-11},{41,78,15,-23,-45,69,-57,-11},{41,78,15,-23,-46,69,-58,-11}, +{41,79,15,-23,-46,70,-58,-11},{42,79,16,-23,-46,70,-59,-11},{42,80,16,-23,-47,71,-59,-11},{42,81,16,-24,-47,71,-59,-11}, +{43,81,16,-24,-47,72,-60,-11},{43,82,16,-24,-48,72,-60,-11},{43,82,16,-24,-48,73,-61,-11},{43,83,16,-24,-48,73,-61,-11}, +{44,83,16,-24,-49,74,-61,-12},{44,84,16,-25,-49,74,-62,-12},{44,85,17,-25,-49,75,-62,-12},{45,85,17,-25,-50,75,-63,-12}, +{45,86,17,-25,-50,76,-63,-12},{45,86,17,-25,-50,76,-64,-12},{46,87,17,-25,-51,77,-64,-12},{46,87,17,-26,-51,77,-64,-12}, +{46,88,17,-26,-51,78,-65,-12},{46,89,17,-26,-52,78,-65,-12},{47,89,18,-26,-52,79,-66,-12},{47,90,18,-26,-52,79,-66,-12}, +{47,90,18,-26,-53,80,-66,-13},{48,91,18,-27,-53,80,-67,-13},{48,91,18,-27,-53,81,-67,-13},{48,92,18,-27,-54,81,-68,-13}, +{49,92,18,-27,-54,82,-68,-13},{49,93,18,-27,-54,82,-69,-13},{49,94,18,-28,-54,83,-69,-13},{49,94,19,-28,-55,83,-69,-13}, +{50,95,19,-28,-55,84,-70,-13},{50,95,19,-28,-55,84,-70,-13},{50,96,19,-28,-56,85,-71,-13},{51,96,19,-28,-56,85,-71,-13}, +{51,97,19,-29,-56,86,-72,-13},{51,98,19,-29,-57,86,-72,-14},{52,98,19,-29,-57,87,-72,-14},{52,99,19,-29,-57,87,-73,-14}, +{52,99,20,-29,-58,88,-73,-14},{52,100,20,-29,-58,88,-74,-14},{53,100,20,-30,-58,89,-74,-14},{53,101,20,-30,-59,89,-74,-14}, +{53,102,20,-30,-59,90,-75,-14},{54,102,20,-30,-59,90,-75,-14},{54,103,20,-30,-60,91,-76,-14},{54,103,20,-30,-60,91,-76,-14}, +{55,104,20,-31,-60,92,-77,-14},{55,104,21,-31,-61,92,-77,-15},{55,105,21,-31,-61,93,-77,-15},{55,106,21,-31,-61,93,-78,-15}, +{56,106,21,-31,-62,94,-78,-15},{56,107,21,-31,-62,94,-79,-15},{56,107,21,-32,-62,95,-79,-15},{57,108,21,-32,-63,95,-79,-15}, +{57,108,21,-32,-63,96,-80,-15},{57,109,22,-32,-63,96,-80,-15},{58,109,22,-32,-64,97,-81,-15},{58,110,22,-32,-64,97,-81,-15}, +{58,111,22,-33,-64,98,-82,-15},{58,111,22,-33,-65,98,-82,-16},{59,112,22,-33,-65,99,-82,-16},{59,112,22,-33,-65,99,-83,-16}, +{59,113,22,-33,-66,100,-83,-16},{60,113,22,-33,-66,100,-84,-16},{60,114,23,-34,-66,101,-84,-16},{60,115,23,-34,-67,101,-84,-16}, +{60,115,23,-34,-67,102,-85,-16},{61,116,23,-34,-67,102,-85,-16},{61,116,23,-34,-68,103,-86,-16},{61,117,23,-34,-68,103,-86,-16}, +{62,117,23,-35,-68,104,-87,-16},{62,118,23,-35,-69,104,-87,-16},{62,119,23,-35,-69,105,-87,-17},{63,119,24,-35,-69,105,-88,-17}, +{63,120,24,-35,-70,106,-88,-17},{63,120,24,-35,-70,106,-89,-17},{63,121,24,-36,-70,107,-89,-17},{64,121,24,-36,-71,107,-90,-17}, +{64,122,24,-36,-71,108,-90,-17},{64,123,24,-36,-71,108,-90,-17},{65,123,24,-36,-72,109,-91,-17},{65,124,24,-36,-72,109,-91,-17}, +{65,124,25,-37,-72,110,-92,-17},{66,125,25,-37,-73,110,-92,-17},{66,125,25,-37,-73,111,-92,-18},{66,126,25,-37,-73,111,-93,-18}, +{66,127,25,-37,-74,112,-93,-18},{67,127,25,-37,-74,112,-94,-18},{67,128,25,-38,-74,113,-94,-18},{67,128,25,-38,-75,113,-95,-18}, +{68,129,25,-38,-75,114,-95,-18},{68,129,26,-38,-75,114,-95,-18},{68,130,26,-38,-76,115,-96,-18},{69,130,26,-38,-76,115,-96,-18}, +{69,131,26,-39,-76,116,-97,-18},{69,132,26,-39,-77,116,-97,-18},{69,132,26,-39,-77,117,-97,-19},{70,133,26,-39,-77,117,-98,-19}, +{70,133,26,-39,-78,118,-98,-19},{70,134,27,-39,-78,118,-99,-19},{71,134,27,-40,-78,119,-99,-19},{71,135,27,-40,-79,119,-100,-19}, +{71,136,27,-40,-79,120,-100,-19},{72,136,27,-40,-79,120,-100,-19},{72,137,27,-40,-80,121,-101,-19},{72,137,27,-40,-80,121,-101,-19}, +{72,138,27,-41,-80,122,-102,-19},{73,138,27,-41,-81,122,-102,-19},{73,139,28,-41,-81,123,-103,-19},{73,140,28,-41,-81,123,-103,-20}, +{74,140,28,-41,-82,124,-103,-20},{74,141,28,-42,-82,124,-104,-20},{74,141,28,-42,-82,125,-104,-20},{75,142,28,-42,-83,125,-105,-20}, +{75,142,28,-42,-83,126,-105,-20},{75,143,28,-42,-83,126,-105,-20},{75,144,28,-42,-84,127,-106,-20},{76,144,29,-43,-84,127,-106,-20}}; +/* }}} */ + +/* {{{ [fold] qc_yuv_toplanar(unsigned char *rgb24frame, int length, int format) */ +/* + * Convert to planar formats + * The input is an YCbYCr format. + * Input: len : 2/3 maxi. + * | YUYV | free | + * | 2/3 | 1/3 | + * 1th conversion: + * | YY | free | U|V | + * | 1/3 | 1/3 | 1/3 | + * 2d conversion: + * | YY | U | V | free | + * | 1/3 | 1/6|1/6 | 1/3 | + * That the Y422P conversion. + */ +static int qc_yuv_toplanar(unsigned char *rgb24frame, int length, int format) +{ + unsigned char *ptr; + int n = 0, l = 0, i; + unsigned char *cr; + unsigned char *cb; + unsigned char *crptr, *cbptr; + int mode = 0; + + l = length/2; + switch(format) { + case VIDEO_PALETTE_YUV411P: + n = length/8; + mode = 1; + break; + case VIDEO_PALETTE_YUV422P: + n = length/4; + break; + } + + ptr = rgb24frame; + crptr = &rgb24frame[length]; + cr = crptr; + cbptr = &rgb24frame[length+n]; + cb = cbptr; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_yuv_toplanar: %d (%d + 2 * %d)",length, l, n); + + /* separate Y , U and V */ + for (i=0; iscanlength = length/2+ (2 * n); + return length; +} +/* }}} */ +/* {{{ [fold] qc_yuv_rgb2yuv(unsigned char *rgb24frame, int length, int format) */ +/* + * Convert the RGB24 image to YUV422. + * return the size of the converted frame + */ +int qc_yuv_rgb2yuv(unsigned char *rgb24frame, int length, int format) +{ + int i; + int l; /* Data length */ + short Y; + short U; + short V; + unsigned char *ptr; + unsigned short w; + + //if (qcdebug&QC_DEBUGLOGIC)PDEBUG("qc_yuv_rgb2yuv(frame=%p,length=%i,palette=%s)",rgb24frame,length,qc_fmt_getname(format)); + ptr = rgb24frame; + l = 0; + + if (format==VIDEO_PALETTE_RGB32) { + /* we need to convert in reverse so as to not overwrite ourselves */ + for (ptr=ptr+length*4/3,i=length-3; i>=0; i-=3) { + *--ptr = 0; + *--ptr = (unsigned char) rgb24frame[i + 2]; + *--ptr = (unsigned char) rgb24frame[i + 1]; + *--ptr = (unsigned char) rgb24frame[i + 0]; + l += 4; + } + } else + for (i=0; i> 3))); + *ptr++ = (unsigned char) (w & 0xFF); + *ptr++ = (unsigned char) (w >> 8); + l += 2; + break; + case VIDEO_PALETTE_RGB555: + w = ((unsigned short) + ((unsigned short) (rgb24frame[i + 2] & 0xf8) << (10 - 3)) | + ((unsigned short) (rgb24frame[i + 1] & 0xf8) << (5 - 3)) | + ((unsigned short) (rgb24frame[i + 0] >> 3))); + *ptr++ = (unsigned char) (w & 0xFF); + *ptr++ = (unsigned char) (w >> 8); + l += 2; + break; + default: + *ptr++ = (219 * Y)/255 + 16; + l++; + *ptr = (112 * U)/127 + 128; /* Cb */ + ptr++; + l++; + *ptr = (112 * V)/127 + 128; /* Cr */ + ptr++; + l++; + } + } + if (format >= VIDEO_PALETTE_PLANAR) { + length = qc_yuv_toplanar(rgb24frame, l, format); + } else { + length = l; + } + return length; +} +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** qc_imag: Start of image processing functions ************************** */ + +/* {{{ [fold] qc_imag_bayer_midvalue(char *bay, int bay_line, int columns, int rows) */ +/* Compute and return the average pixel intensity from the bayer data. + * The result can be used for automatic software exposure/gain control. + * bay = points to the bayer image data (upper left pixel is green) + * bay_line = bytes between the beginnings of two consecutive rows + * columns, rows = bayer image size (both must be even) + */ +static unsigned char qc_imag_bayer_midvalue(unsigned char *bay, int bay_line, + unsigned int columns, unsigned int rows) +{ + static const unsigned int stepsize = 8; /* Larger = faster and less accurate */ + unsigned char *cur_bay; + unsigned int sum = 0; + int column_cnt; + int row_cnt; + + /* Skip 1/4 of left, right, top, and bottom pixels (use only center pixels) */ + columns /= 2; + rows /= 2; + bay += rows/4*2*bay_line + columns/4*2; + + columns /= stepsize*2; + rows /= stepsize*2; + + row_cnt = rows; + do { + column_cnt = columns; + cur_bay = bay; + do { + sum += cur_bay[0] + cur_bay[1] + cur_bay[bay_line]; /* R + G + B */ + cur_bay += 2*stepsize; + } while (--column_cnt > 0); + bay += 2*stepsize*bay_line; + } while (--row_cnt > 0); + sum /= 3 * columns * rows; + return sum; +} +/* }}} */ +#if COMPRESS +/* {{{ [fold] qc_imag_rgb24_midvalue(char *rgb, int rgb_line, int columns, int rows) */ +/* Compute and return the average pixel intensity from the RGB/BGR24 data. + * The result can be used for automatic software exposure/gain control. + * rgb = points to the RGB image data + * rgb_line = bytes between the beginnings of two consecutive rows + * columns, rows = RGB image size + */ +static unsigned char qc_imag_rgb24_midvalue(unsigned char *rgb, int rgb_line, + unsigned int columns, unsigned int rows) +{ + static const unsigned int stepsize = 8; /* Larger = faster and less accurate */ + unsigned char *cur_rgb; + unsigned int sum = 0; + int column_cnt; + int row_cnt; + + /* Skip 1/4 of left, right, top, and bottom pixels (use only center pixels) */ + columns /= 2; + rows /= 2; + rgb += rows/2*rgb_line + columns/2*3; + + columns /= stepsize; + rows /= stepsize; + + row_cnt = rows; + do { + column_cnt = columns; + cur_rgb = rgb; + do { + sum += cur_rgb[0] + cur_rgb[1] + cur_rgb[2]; /* R + G + B */ + cur_rgb += 3*stepsize; + } while (--column_cnt > 0); + rgb += stepsize*rgb_line; + } while (--row_cnt > 0); + sum /= 3 * columns * rows; + return sum; +} +/* }}} */ +#endif +/* {{{ [fold] qc_imag_userlut(unsigned char (*userlut)[QC_LUT_SIZE], unsigned char (*lut)[QC_LUT_SIZE]) */ +/* Apply user-defined lookup-table to the given preinitialized lut */ +static inline void qc_imag_userlut(unsigned char (*userlut)[QC_LUT_SIZE], unsigned char (*lut)[QC_LUT_SIZE]) +{ + unsigned int i,p; + for (i=0; i<256; i++) { + p = (*lut)[QC_LUT_RED + i]; + p = (*userlut)[QC_LUT_RED + p]; + (*lut)[QC_LUT_RED + i] = p; + } + for (i=0; i<256; i++) { + p = (*lut)[QC_LUT_GREEN + i]; + p = (*userlut)[QC_LUT_GREEN + p]; + (*lut)[QC_LUT_GREEN + i] = p; + } + for (i=0; i<256; i++) { + p = (*lut)[QC_LUT_BLUE + i]; + p = (*userlut)[QC_LUT_BLUE + p]; + (*lut)[QC_LUT_BLUE + i] = p; + } +} +/* }}} */ +/* {{{ [fold] qc_imag_bayer_equalize(char *bay, int bay_line, int columns, int rows, char (*lut)[]) */ +/* Compute and fill a lookup table which will equalize the image. + * bay = points to the bayer image data (upper left pixel is green) + * bay_line = bytes between the beginnings of two consecutive rows + * columns, rows = bayer image size (both must be even) + * lut = lookup table to be filled, 3*256 char array + */ +static void qc_imag_bayer_equalize(unsigned char *bay, int bay_line, + unsigned int columns, unsigned int rows, unsigned char (*lut)[QC_LUT_SIZE]) +{ + static const unsigned int stepsize = 4; /* Larger = faster and less accurate */ + unsigned short red_cnt[256], green_cnt[256], blue_cnt[256]; /* FIXME: how much we can use stack? */ + unsigned int red_sum, green_sum, blue_sum; + unsigned int red_tot, green_tot, blue_tot; + unsigned char *cur_bay; + int i, column_cnt, row_cnt; + + memset(red_cnt, 0, sizeof(red_cnt)); + memset(green_cnt, 0, sizeof(green_cnt)); + memset(blue_cnt, 0, sizeof(blue_cnt)); + + columns /= 2*stepsize; + rows /= 2*stepsize; + + /* Compute histogram */ + row_cnt = rows; + do { + column_cnt = columns; + cur_bay = bay; + do { + green_cnt[cur_bay[0]]++; + red_cnt [cur_bay[1]]++; + blue_cnt [cur_bay[bay_line]]++; + green_cnt[cur_bay[bay_line+1]]++; + cur_bay += 2*stepsize; + } while (--column_cnt > 0); + bay += 2*stepsize*bay_line; + } while (--row_cnt > 0); + + /* Compute lookup table based on the histogram */ + red_tot = columns * rows; /* Total number of pixels of each primary color */ + green_tot = red_tot * 2; + blue_tot = red_tot; + red_sum = 0; + green_sum = 0; + blue_sum = 0; + for (i=0; i<256; i++) { + (*lut)[QC_LUT_RED + i] = 255 * red_sum / red_tot; + (*lut)[QC_LUT_GREEN + i] = 255 * green_sum / green_tot; + (*lut)[QC_LUT_BLUE + i] = 255 * blue_sum / blue_tot; + red_sum += red_cnt[i]; + green_sum += green_cnt[i]; + blue_sum += blue_cnt[i]; + } +} +/* }}} */ +/* {{{ [fold] qc_imag_bayer_lut(char *bay, int bay_line, int columns, int rows, char (*lut)[]) */ +/* Transform pixel values in a bayer image with a given lookup table. + * bay = points to the bayer image data (upper left pixel is green) + * bay_line = bytes between the beginnings of two consecutive rows + * columns, rows = bayer image size (both must be even) + * lut = lookup table to be used, 3*256 char array + */ +static void qc_imag_bayer_lut(unsigned char *bay, int bay_line, + unsigned int columns, unsigned int rows, unsigned char (*lut)[QC_LUT_SIZE]) +{ + unsigned char *cur_bay; + unsigned int total_columns; + + total_columns = columns / 2; /* Number of 2x2 bayer blocks */ + rows /= 2; + do { + columns = total_columns; + cur_bay = bay; + do { + cur_bay[0] = (*lut)[QC_LUT_GREEN + cur_bay[0]]; + cur_bay[1] = (*lut)[QC_LUT_RED + cur_bay[1]]; + cur_bay += 2; + } while (--columns); + bay += bay_line; + columns = total_columns; + cur_bay = bay; + do { + cur_bay[0] = (*lut)[QC_LUT_BLUE + cur_bay[0]]; + cur_bay[1] = (*lut)[QC_LUT_GREEN + cur_bay[1]]; + cur_bay += 2; + } while (--columns); + bay += bay_line; + } while (--rows); +} +/* }}} */ +/* {{{ [fold] qc_imag_writergb(void *addr, int bpp, unsigned char r, unsigned char g, unsigned char b) */ +/* Write RGB pixel value to the given address. + * addr = memory address, to which the pixel is written + * bpp = number of bytes in the pixel (should be 3 or 4) + * r, g, b = pixel component values to be written (red, green, blue) + * Looks horribly slow but the compiler should be able to inline optimize it. + */ +static inline void qc_imag_writergb(void *addr, int bpp, + unsigned char r, unsigned char g, unsigned char b) +{ + if (DEFAULT_BGR) { + /* Blue is first (in the lowest memory address */ + if (bpp==4) { +#if defined(__LITTLE_ENDIAN) + *(unsigned int *)addr = + (unsigned int)r << 16 | + (unsigned int)g << 8 | + (unsigned int)b; +#elif defined(__BIG_ENDIAN) + *(unsigned int *)addr = + (unsigned int)r << 8 | + (unsigned int)g << 16 | + (unsigned int)b << 24; +#else + unsigned char *addr2 = (unsigned char *)addr; + addr2[0] = b; + addr2[1] = g; + addr2[2] = r; + addr2[3] = 0; +#endif + } else { + unsigned char *addr2 = (unsigned char *)addr; + addr2[0] = b; + addr2[1] = g; + addr2[2] = r; + } + } else { + /* Red is first (in the lowest memory address */ + if (bpp==4) { +#if defined(__LITTLE_ENDIAN) + *(unsigned int *)addr = + (unsigned int)b << 16 | + (unsigned int)g << 8 | + (unsigned int)r; +#elif defined(__BIG_ENDIAN) + *(unsigned int *)addr = + (unsigned int)b << 8 | + (unsigned int)g << 16 | + (unsigned int)r << 24; +#else + unsigned char *addr2 = (unsigned char *)addr; + addr2[0] = r; + addr2[1] = g; + addr2[2] = b; + addr2[3] = 0; +#endif + } else { + unsigned char *addr2 = (unsigned char *)addr; + addr2[0] = r; + addr2[1] = g; + addr2[2] = b; + } + } +} +/* }}} */ + +/* + * Raw image data for Bayer-RGB-matrix: + * G R for even rows + * B G for odd rows + */ + +#if 0 +/* {{{ [fold] qc_imag_bay2rgb_noip(char *bay, int bay_line, char *rgb, int rgb_line, int columns, rows, bpp) */ +/* Convert bayer image to RGB image without using interpolation. + * bay = points to the bayer image data (upper left pixel is green) + * bay_line = bytes between the beginnings of two consecutive rows + * rgb = points to the rgb image data that is written + * rgb_line = bytes between the beginnings of two consecutive rows + * columns, rows = bayer image size (both must be even) + * bpp = number of bytes in each pixel in the RGB image (should be 3 or 4) + */ +/* Execution time: 2391747-2653574 clock cycles for CIF image (Pentium II) */ +/* Do NOT use this routine: cottnoip is faster with better image quality */ +static inline void qc_imag_bay2rgb_noip(unsigned char *bay, int bay_line, + unsigned char *rgb, int rgb_line, + int columns, int rows, int bpp) +{ + unsigned char *cur_bay, *cur_rgb; + int bay_line2, rgb_line2; + int total_columns; + + /* Process 2 lines and rows per each iteration */ + total_columns = columns >> 1; + rows >>= 1; + bay_line2 = 2*bay_line; + rgb_line2 = 2*rgb_line; + do { + cur_bay = bay; + cur_rgb = rgb; + columns = total_columns; + do { + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--columns); + bay += bay_line2; + rgb += rgb_line2; + } while (--rows); +} +/* }}} */ +#endif +/* {{{ [fold] qc_imag_bay2rgb_horip(char *bay, int bay_line, char *rgb, int rgb_line, columns, rows, bpp) */ +/* Convert bayer image to RGB image using fast horizontal-only interpolation. + * bay = points to the bayer image data (upper left pixel is green) + * bay_line = bytes between the beginnings of two consecutive rows + * rgb = points to the rgb image data that is written + * rgb_line = bytes between the beginnings of two consecutive rows + * columns, rows = bayer image size (both must be even) + * bpp = number of bytes in each pixel in the RGB image (should be 3 or 4) + */ +/* Execution time: 2735776-3095322 clock cycles for CIF image (Pentium II) */ +/* Not recommended: ip seems to be somewhat faster, probably with better image quality. + * cott is quite much faster, but possibly with slightly worse image quality */ +static inline void qc_imag_bay2rgb_horip(unsigned char *bay, int bay_line, + unsigned char *rgb, int rgb_line, + unsigned int columns, unsigned int rows, int bpp) +{ + unsigned char *cur_bay, *cur_rgb; + int bay_line2, rgb_line2; + int total_columns; + unsigned char red, green, blue; + unsigned int column_cnt, row_cnt; + + /* Process 2 lines and rows per each iteration */ + total_columns = (columns-2) / 2; + row_cnt = rows / 2; + bay_line2 = 2*bay_line; + rgb_line2 = 2*rgb_line; + + do { + qc_imag_writergb(rgb+0, bpp, bay[1], bay[0], bay[bay_line]); + qc_imag_writergb(rgb+rgb_line, bpp, bay[1], bay[0], bay[bay_line]); + cur_bay = bay + 1; + cur_rgb = rgb + bpp; + column_cnt = total_columns; + do { + green = ((unsigned int)cur_bay[-1]+cur_bay[1]) / 2; + blue = ((unsigned int)cur_bay[bay_line-1]+cur_bay[bay_line+1]) / 2; + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[0], green, blue); + red = ((unsigned int)cur_bay[0]+cur_bay[2]) / 2; + qc_imag_writergb(cur_rgb+bpp, bpp, red, cur_bay[1], cur_bay[bay_line+1]); + green = ((unsigned int)cur_bay[bay_line]+cur_bay[bay_line+2]) / 2; + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[0], cur_bay[bay_line], blue); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, red, cur_bay[1], cur_bay[bay_line+1]); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--column_cnt); + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[0], cur_bay[-1], cur_bay[bay_line-1]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[0], cur_bay[bay_line], cur_bay[bay_line-1]); + bay += bay_line2; + rgb += rgb_line2; + } while (--row_cnt); +} +/* }}} */ +/* {{{ [fold] qc_imag_bay2rgb_ip(char *bay, int bay_line, char *rgb, int rgb_line, columns, rows, bpp) */ +/* Convert bayer image to RGB image using full (slow) linear interpolation. + * bay = points to the bayer image data (upper left pixel is green) + * bay_line = bytes between the beginnings of two consecutive rows + * rgb = points to the rgb image data that is written + * rgb_line = bytes between the beginnings of two consecutive rows + * columns, rows = bayer image size (both must be even) + * bpp = number of bytes in each pixel in the RGB image (should be 3 or 4) + */ +/* Execution time: 2714077-2827455 clock cycles for CIF image (Pentium II) */ +static inline void qc_imag_bay2rgb_ip(unsigned char *bay, int bay_line, + unsigned char *rgb, int rgb_line, + unsigned int columns, unsigned int rows, int bpp) +{ + unsigned char *cur_bay, *cur_rgb; + int bay_line2, rgb_line2; + int total_columns; + unsigned char red, green, blue; + unsigned int column_cnt, row_cnt; + + /* Process 2 rows and columns each iteration */ + total_columns = (columns-2) / 2; + row_cnt = (rows-2) / 2; + bay_line2 = 2*bay_line; + rgb_line2 = 2*rgb_line; + + /* First scanline is handled here as a special case */ + qc_imag_writergb(rgb, bpp, bay[1], bay[0], bay[bay_line]); + cur_bay = bay + 1; + cur_rgb = rgb + bpp; + column_cnt = total_columns; + do { + green = ((unsigned int)cur_bay[-1] + cur_bay[1] + cur_bay[bay_line]) / 3; + blue = ((unsigned int)cur_bay[bay_line-1] + cur_bay[bay_line+1]) / 2; + qc_imag_writergb(cur_rgb, bpp, cur_bay[0], green, blue); + red = ((unsigned int)cur_bay[0] + cur_bay[2]) / 2; + qc_imag_writergb(cur_rgb+bpp, bpp, red, cur_bay[1], cur_bay[bay_line+1]); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--column_cnt); + green = ((unsigned int)cur_bay[-1] + cur_bay[bay_line]) / 2; + qc_imag_writergb(cur_rgb, bpp, cur_bay[0], green, cur_bay[bay_line-1]); + + /* Process here all other scanlines except first and last */ + bay += bay_line; + rgb += rgb_line; + do { + red = ((unsigned int)bay[-bay_line+1] + bay[bay_line+1]) / 2; + green = ((unsigned int)bay[-bay_line] + bay[1] + bay[bay_line]) / 3; + qc_imag_writergb(rgb+0, bpp, red, green, bay[0]); + blue = ((unsigned int)bay[0] + bay[bay_line2]) / 2; + qc_imag_writergb(rgb+rgb_line, bpp, bay[bay_line+1], bay[bay_line], blue); + cur_bay = bay + 1; + cur_rgb = rgb + bpp; + column_cnt = total_columns; + do { + red = ((unsigned int)cur_bay[-bay_line]+cur_bay[bay_line]) / 2; + blue = ((unsigned int)cur_bay[-1]+cur_bay[1]) / 2; + qc_imag_writergb(cur_rgb+0, bpp, red, cur_bay[0], blue); + red = ((unsigned int)cur_bay[-bay_line]+cur_bay[-bay_line+2]+cur_bay[bay_line]+cur_bay[bay_line+2]) / 4; + green = ((unsigned int)cur_bay[0]+cur_bay[2]+cur_bay[-bay_line+1]+cur_bay[bay_line+1]) / 4; + qc_imag_writergb(cur_rgb+bpp, bpp, red, green, cur_bay[1]); + green = ((unsigned int)cur_bay[0]+cur_bay[bay_line2]+cur_bay[bay_line-1]+cur_bay[bay_line+1]) / 4; + blue = ((unsigned int)cur_bay[-1]+cur_bay[1]+cur_bay[bay_line2-1]+cur_bay[bay_line2+1]) / 4; + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[bay_line], green, blue); + red = ((unsigned int)cur_bay[bay_line]+cur_bay[bay_line+2]) / 2; + blue = ((unsigned int)cur_bay[1]+cur_bay[bay_line2+1]) / 2; + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, red, cur_bay[bay_line+1], blue); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--column_cnt); + red = ((unsigned int)cur_bay[-bay_line] + cur_bay[bay_line]) / 2; + qc_imag_writergb(cur_rgb, bpp, red, cur_bay[0], cur_bay[-1]); + green = ((unsigned int)cur_bay[0] + cur_bay[bay_line-1] + cur_bay[bay_line2]) / 3; + blue = ((unsigned int)cur_bay[-1] + cur_bay[bay_line2-1]) / 2; + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[bay_line], green, blue); + bay += bay_line2; + rgb += rgb_line2; + } while (--row_cnt); + + /* Last scanline is handled here as a special case */ + green = ((unsigned int)bay[-bay_line] + bay[1]) / 2; + qc_imag_writergb(rgb, bpp, bay[-bay_line+1], green, bay[0]); + cur_bay = bay + 1; + cur_rgb = rgb + bpp; + column_cnt = total_columns; + do { + blue = ((unsigned int)cur_bay[-1] + cur_bay[1]) / 2; + qc_imag_writergb(cur_rgb, bpp, cur_bay[-bay_line], cur_bay[0], blue); + red = ((unsigned int)cur_bay[-bay_line] + cur_bay[-bay_line+2]) / 2; + green = ((unsigned int)cur_bay[0] + cur_bay[-bay_line+1] + cur_bay[2]) / 3; + qc_imag_writergb(cur_rgb+bpp, bpp, red, green, cur_bay[1]); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--column_cnt); + qc_imag_writergb(cur_rgb, bpp, cur_bay[-bay_line], cur_bay[0], cur_bay[-1]); +} +/* }}} */ +/* {{{ [fold] qc_imag_bay2rgb_cott(unsigned char *bay, int bay_line, unsigned char *rgb, int rgb_line, int columns, int rows, int bpp) */ +/* Convert bayer image to RGB image using 0.5 displaced light linear interpolation. + * bay = points to the bayer image data (upper left pixel is green) + * bay_line = bytes between the beginnings of two consecutive rows + * rgb = points to the rgb image data that is written + * rgb_line = bytes between the beginnings of two consecutive rows + * columns, rows = bayer image size (both must be even) + * bpp = number of bytes in each pixel in the RGB image (should be 3 or 4) + */ +/* Execution time: 2167685 clock cycles for CIF image (Pentium II) */ +/* Original idea for this routine from Cagdas Ogut */ +static inline void qc_imag_bay2rgb_cott(unsigned char *bay, int bay_line, + unsigned char *rgb, int rgb_line, + int columns, int rows, int bpp) +{ + unsigned char *cur_bay, *cur_rgb; + int bay_line2, rgb_line2; + int total_columns; + + /* Process 2 lines and rows per each iteration, but process the last row and column separately */ + total_columns = (columns>>1) - 1; + rows = (rows>>1) - 1; + bay_line2 = 2*bay_line; + rgb_line2 = 2*rgb_line; + do { + cur_bay = bay; + cur_rgb = rgb; + columns = total_columns; + do { + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], ((unsigned int)cur_bay[0] + cur_bay[bay_line+1]) /2, cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], ((unsigned int)cur_bay[2] + cur_bay[bay_line+1]) /2, cur_bay[bay_line+2]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[bay_line2+1], ((unsigned int)cur_bay[bay_line2] + cur_bay[bay_line+1]) /2, cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[bay_line2+1], ((unsigned int)cur_bay[bay_line2+2] + cur_bay[bay_line+1])/2, cur_bay[bay_line+2]); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--columns); + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], ((unsigned int)cur_bay[0] + cur_bay[bay_line+1])/2, cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[bay_line2+1], ((unsigned int)cur_bay[bay_line2] + cur_bay[bay_line+1])/2, cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[bay_line2+1], cur_bay[bay_line+1], cur_bay[bay_line]); + bay += bay_line2; + rgb += rgb_line2; + } while (--rows); + /* Last scanline handled here as special case */ + cur_bay = bay; + cur_rgb = rgb; + columns = total_columns; + do { + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], ((unsigned int)cur_bay[0] + cur_bay[bay_line+1])/2, cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], ((unsigned int)cur_bay[2] + cur_bay[bay_line+1])/2, cur_bay[bay_line+2]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line+2]); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--columns); + /* Last lower-right pixel is handled here as special case */ + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], ((unsigned int)cur_bay[0] + cur_bay[bay_line+1])/2, cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); +} +/* }}} */ +/* {{{ [fold] qc_imag_bay2rgb_cottnoip(unsigned char *bay, int bay_line, unsigned char *rgb, int rgb_line, int columns, int rows, int bpp) */ +/* Convert bayer image to RGB image using 0.5 displaced nearest neighbor. + * bay = points to the bayer image data (upper left pixel is green) + * bay_line = bytes between the beginnings of two consecutive rows + * rgb = points to the rgb image data that is written + * rgb_line = bytes between the beginnings of two consecutive rows + * columns, rows = bayer image size (both must be even) + * bpp = number of bytes in each pixel in the RGB image (should be 3 or 4) + */ +/* Execution time: 2133302 clock cycles for CIF image (Pentium II), fastest */ +static inline void qc_imag_bay2rgb_cottnoip(unsigned char *bay, int bay_line, + unsigned char *rgb, int rgb_line, + int columns, int rows, int bpp) +{ + unsigned char *cur_bay, *cur_rgb; + int bay_line2, rgb_line2; + int total_columns; + + /* Process 2 lines and rows per each iteration, but process the last row and column separately */ + total_columns = (columns>>1) - 1; + rows = (rows>>1) - 1; + bay_line2 = 2*bay_line; + rgb_line2 = 2*rgb_line; + do { + cur_bay = bay; + cur_rgb = rgb; + columns = total_columns; + do { + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[2], cur_bay[bay_line+2]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[bay_line2+1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[bay_line2+1], cur_bay[bay_line+1], cur_bay[bay_line+2]); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--columns); + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[bay_line2+1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[bay_line2+1], cur_bay[bay_line+1], cur_bay[bay_line]); + bay += bay_line2; + rgb += rgb_line2; + } while (--rows); + /* Last scanline handled here as special case */ + cur_bay = bay; + cur_rgb = rgb; + columns = total_columns; + do { + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[2], cur_bay[bay_line+2]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line+2]); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--columns); + /* Last lower-right pixel is handled here as special case */ + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); +} +/* }}} */ +/* {{{ [fold] qc_imag_bay2rgb_gptm_fast(unsigned char *bay, int bay_line, unsigned char *rgb, int rgb_line, int columns, int rows, int bpp) */ +/* Convert Bayer image to RGB image using Generalized Pei-Tam method + * Uses fixed weights */ +/* Execution time: 3795517 clock cycles */ +static inline void qc_imag_bay2rgb_gptm_fast(unsigned char *bay, int bay_line, + unsigned char *rgb, int rgb_line, + int columns, int rows, int bpp) +{ + int r,g,b,w; + unsigned char *cur_bay, *cur_rgb; + int bay_line2, bay_line3, rgb_line2; + int total_columns; + + /* Process 2 lines and rows per each iteration, but process the first and last two columns and rows separately */ + total_columns = (columns>>1) - 2; + rows = (rows>>1) - 2; + bay_line2 = 2*bay_line; + bay_line3 = 3*bay_line; + rgb_line2 = 2*rgb_line; + + /* Process first two pixel rows here */ + cur_bay = bay; + cur_rgb = rgb; + columns = total_columns + 2; + do { + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--columns); + bay += bay_line2; + rgb += rgb_line2; + + do { + cur_bay = bay; + cur_rgb = rgb; + columns = total_columns; + + /* Process first 2x2 pixel block in a row here */ + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + cur_bay += 2; + cur_rgb += 2*bpp; + + do { + w = 4*cur_bay[0] - (cur_bay[-bay_line-1] + cur_bay[-bay_line+1] + cur_bay[bay_line-1] + cur_bay[bay_line+1]); + r = (2*(cur_bay[-1] + cur_bay[1]) + w) >> 2; + b = (2*(cur_bay[-bay_line] + cur_bay[bay_line]) + w) >> 2; + qc_imag_writergb(cur_rgb+0, bpp, CLIP(r,0,255), cur_bay[0], CLIP(b,0,255)); + + w = 4*cur_bay[1] - (cur_bay[-bay_line2+1] + cur_bay[-1] + cur_bay[3] + cur_bay[bay_line2+1]); + g = (2*(cur_bay[-bay_line+1] + cur_bay[0] + cur_bay[2] + cur_bay[bay_line+1]) + w) >> 3; + b = (2*(cur_bay[-bay_line] + cur_bay[-bay_line+2] + cur_bay[bay_line] + cur_bay[bay_line+2]) + w) >> 3; + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], CLIP(g,0,255), CLIP(b,0,255)); + + w = 4*cur_bay[bay_line] - (cur_bay[-bay_line] + cur_bay[bay_line-2] + cur_bay[bay_line+2] + cur_bay[bay_line3]); + r = ((cur_bay[-1] + cur_bay[1] + cur_bay[bay_line2-1] + cur_bay[bay_line2+1]) + w) >> 2; + g = ((cur_bay[0] + cur_bay[bay_line-1] + cur_bay[bay_line+1] + cur_bay[bay_line2]) + w) >> 2; + qc_imag_writergb(cur_rgb+rgb_line, bpp, CLIP(r,0,255), CLIP(g,0,255), cur_bay[bay_line]); + + w = 4*cur_bay[bay_line+1] - (cur_bay[0] + cur_bay[2] + cur_bay[bay_line2] + cur_bay[bay_line2+2]); + r = (2*(cur_bay[1] + cur_bay[bay_line2+1]) + w) >> 2; + b = (2*(cur_bay[bay_line] + cur_bay[bay_line+2]) + w) >> 2; + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, CLIP(r,0,255), cur_bay[bay_line+1], CLIP(b,0,255)); + + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--columns); + + /* Process last 2x2 pixel block in a row here */ + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + + bay += bay_line2; + rgb += rgb_line2; + } while (--rows); + + /* Process last two pixel rows here */ + cur_bay = bay; + cur_rgb = rgb; + columns = total_columns + 2; + do { + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--columns); +} +/* }}} */ +/* {{{ [fold] qc_imag_bay2rgb_gptm(unsigned char *bay, int bay_line, unsigned char *rgb, int rgb_line, int columns, int rows, int bpp, int sharpness) */ +/* Convert Bayer image to RGB image using Generalized Pei-Tam method (See: + * "Effective Color Interpolation in CCD Color Filter Arrays Using Signal Correlation" + * IEEE Transactions on Circuits and Systems for Video Technology, vol. 13, no. 6, June 2003. + * Note that this is much improved version of the algorithm described in the paper) + * bay = points to the bayer image data (upper left pixel is green) + * bay_line = bytes between the beginnings of two consecutive rows + * rgb = points to the rgb image data that is written + * rgb_line = bytes between the beginnings of two consecutive rows + * columns, rows = bayer image size (both must be even) + * bpp = number of bytes in each pixel in the RGB image (should be 3 or 4) + * sharpness = how sharp the image should be, between 0..65535 inclusive. + * 23170 gives in theory image that corresponds to the original + * best, but human eye likes slightly sharper picture... 32768 is a good bet. + * When sharpness = 0, this routine is same as bilinear interpolation. + */ +/* Execution time: 4344042 clock cycles for CIF image (Pentium II) */ +static inline void qc_imag_bay2rgb_gptm(unsigned char *bay, int bay_line, + unsigned char *rgb, int rgb_line, + int columns, int rows, int bpp, unsigned int sharpness) +{ + + /* 0.8 fixed point weights, should be between 0-256. Larger value = sharper, zero corresponds to bilinear interpolation. */ + /* Best PSNR with sharpness = 23170 */ + static const int wrg0 = 144; /* Weight for Red on Green */ + static const int wbg0 = 160; + static const int wgr0 = 120; + static const int wbr0 = 192; + static const int wgb0 = 120; + static const int wrb0 = 168; + + int wrg; + int wbg; + int wgr; + int wbr; + int wgb; + int wrb; + + unsigned int wu; + int r,g,b,w; + unsigned char *cur_bay, *cur_rgb; + int bay_line2, bay_line3, rgb_line2; + int total_columns; + + /* Compute weights */ + wu = (sharpness * sharpness) >> 16; + wu = (wu * wu) >> 16; + wrg = (wrg0 * wu) >> 10; + wbg = (wbg0 * wu) >> 10; + wgr = (wgr0 * wu) >> 10; + wbr = (wbr0 * wu) >> 10; + wgb = (wgb0 * wu) >> 10; + wrb = (wrb0 * wu) >> 10; + + /* Process 2 lines and rows per each iteration, but process the first and last two columns and rows separately */ + total_columns = (columns>>1) - 2; + rows = (rows>>1) - 2; + bay_line2 = 2*bay_line; + bay_line3 = 3*bay_line; + rgb_line2 = 2*rgb_line; + + /* Process first two pixel rows here */ + cur_bay = bay; + cur_rgb = rgb; + columns = total_columns + 2; + do { + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--columns); + bay += bay_line2; + rgb += rgb_line2; + + do { + cur_bay = bay; + cur_rgb = rgb; + columns = total_columns; + + /* Process first 2x2 pixel block in a row here */ + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + cur_bay += 2; + cur_rgb += 2*bpp; + + do { + w = 4*cur_bay[0] - (cur_bay[-bay_line-1] + cur_bay[-bay_line+1] + cur_bay[bay_line-1] + cur_bay[bay_line+1]); + r = (512*(cur_bay[-1] + cur_bay[1]) + w*wrg) >> 10; + b = (512*(cur_bay[-bay_line] + cur_bay[bay_line]) + w*wbg) >> 10; + qc_imag_writergb(cur_rgb+0, bpp, CLIP(r,0,255), cur_bay[0], CLIP(b,0,255)); + + w = 4*cur_bay[1] - (cur_bay[-bay_line2+1] + cur_bay[-1] + cur_bay[3] + cur_bay[bay_line2+1]); + g = (256*(cur_bay[-bay_line+1] + cur_bay[0] + cur_bay[2] + cur_bay[bay_line+1]) + w*wgr) >> 10; + b = (256*(cur_bay[-bay_line] + cur_bay[-bay_line+2] + cur_bay[bay_line] + cur_bay[bay_line+2]) + w*wbr) >> 10; + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], CLIP(g,0,255), CLIP(b,0,255)); + + w = 4*cur_bay[bay_line] - (cur_bay[-bay_line] + cur_bay[bay_line-2] + cur_bay[bay_line+2] + cur_bay[bay_line3]); + r = (256*(cur_bay[-1] + cur_bay[1] + cur_bay[bay_line2-1] + cur_bay[bay_line2+1]) + w*wrb) >> 10; + g = (256*(cur_bay[0] + cur_bay[bay_line-1] + cur_bay[bay_line+1] + cur_bay[bay_line2]) + w*wgb) >> 10; + qc_imag_writergb(cur_rgb+rgb_line, bpp, CLIP(r,0,255), CLIP(g,0,255), cur_bay[bay_line]); + + w = 4*cur_bay[bay_line+1] - (cur_bay[0] + cur_bay[2] + cur_bay[bay_line2] + cur_bay[bay_line2+2]); + r = (512*(cur_bay[1] + cur_bay[bay_line2+1]) + w*wrg) >> 10; + b = (512*(cur_bay[bay_line] + cur_bay[bay_line+2]) + w*wbg) >> 10; + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, CLIP(r,0,255), cur_bay[bay_line+1], CLIP(b,0,255)); + + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--columns); + + /* Process last 2x2 pixel block in a row here */ + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + + bay += bay_line2; + rgb += rgb_line2; + } while (--rows); + + /* Process last two pixel rows here */ + cur_bay = bay; + cur_rgb = rgb; + columns = total_columns + 2; + do { + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--columns); +} +/* }}} */ +/* {{{ [fold] qc_imag_rgbbgr(unsigned char *dst, int pixels, int bpp) */ +/* Convert RGB image to BGR or vice versa with the given number of pixels and + * bytes per pixel + */ +static void inline qc_imag_rgbbgr(unsigned char *dst, int pixels, int bpp) +{ + unsigned char r,b; + do { + r = dst[0]; + b = dst[2]; + dst[0] = b; + dst[2] = r; + dst += bpp; + } while (--pixels); +} +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** qc_fmt: Start of generic format query functions ********************** */ + +/* {{{ [fold] struct qc_fmt_format: a format definition */ +struct qc_fmt_format { + u32 fcc; /* M$ defined fourcc code, see http://www.fourcc.org */ + signed char bpp; /* 0=variable, -1=unknown (FIXME:what bpps do AVIs use here?) */ + char order; /* 'R' = RGB, 'B'=BGR, 0=not specified */ + unsigned char nr, ng, nb; /* Number of red, green, blue levels (0=256 levels) */ + char *name; /* Human-readable name */ + Bool supported; /* Can be converted to? */ + /* Here we could add a pointer to list containing conversion routines to other fourcc's */ + /* Then write code to create minimum spanning tree of format conversions */ + /* Include estimated cost per pixel to apply a conversion routine to weight edges */ +}; +/* }}} */ +/* {{{ [fold] List of supported formats */ +#define BF_RGB(r,g,b) 'R', (b)&0xFF, (g)&0xFF, (r)&0xFF +#define BF_BGR(r,g,b) 'B', (b)&0xFF, (g)&0xFF, (r)&0xFF +#define NO_BF 0, 0, 0, 0 +#define FORMAT(ID,FCC1,FCC2,FCC3,FCC4,BPP,BF,NAME,SUPP) \ +static const struct qc_fmt_format qc_fmt_formats_##ID = { v4l2_fourcc(FCC1,FCC2,FCC3,FCC4), BPP, BF, NAME, SUPP } +FORMAT(Y800, 'Y','8','0','0', 8, NO_BF, "GREY", TRUE); +FORMAT(RGB_HI, 'q','c','R','B', 8, BF_RGB(6, 6, 6), "HI240", FALSE); /* Not sure: BF_RGB or BF_BGR? Same as BT20? Don't think so */ +FORMAT(RGB_332, 3,0,0,0, 8, BF_RGB(8, 8, 4), "RGB332", FALSE); +/* Little endian RGB formats (least significant byte at lowest address) */ +FORMAT(RGB_555L, 3,0,0,0, 16, BF_RGB(32, 32, 32), "RGB555L",TRUE); /* Should this be 15 or 16 bpp? Is this same as RGB2? */ +FORMAT(RGB_565L, 3,0,0,0, 16, BF_RGB(32, 64, 32), "RGB565L",TRUE); /* Is this same as RGB2? */ +FORMAT(RGB_24L, 'R','G','B','2', 24, BF_RGB(256, 256, 256), "RGB24L", TRUE); +FORMAT(BGR_24L, 'R','G','B','2', 24, BF_BGR(256, 256, 256), "BGR24L", TRUE); +FORMAT(RGB_32L, 'R','G','B','2', 32, BF_RGB(256, 256, 256), "RGB32L", TRUE); +FORMAT(BGR_32L, 'R','G','B','2', 32, BF_BGR(256, 256, 256), "BGR32L", TRUE); +/* Big endian RGB formats (most significant byte at lowest address) */ +FORMAT(RGB_555B, 'q','c','R','B', 16, BF_RGB(32, 32, 32), "RGB555B",FALSE); +FORMAT(RGB_565B, 'q','c','R','B', 16, BF_RGB(32, 64, 32), "RGB565B",FALSE); +/* Component YUV formats */ +FORMAT(YUY2, 'Y','U','Y','2', 16, NO_BF, "YUV422", TRUE); /* 4:2:2 packed pixel YUYV */ +FORMAT(UYVY, 'U','Y','V','Y', 16, NO_BF, "UYVY", FALSE); +FORMAT(IYUV, 'I','Y','U','V', 12, NO_BF, "YUV420", FALSE); +/* Planar YUV formats */ +FORMAT(YV12, 'Y','V','1','2', 12, NO_BF, "YV12", FALSE); +FORMAT(YVU9, 'Y','V','U','9', 9, NO_BF, "YVU9", FALSE); +FORMAT(Y41P, 'Y','4','1','P', 12, NO_BF, "Y41P", FALSE); /* 4:1:1 packed pixel UYVY UYVY YYYY */ +FORMAT(qcY1, 'q','c','Y','1', 12, NO_BF, "YUV411P", FALSE); /* Like Y41P but planar and Y, U and V planes are in this order */ +FORMAT(qcY2, 'q','c','Y','2', 16, NO_BF, "YUV422P", TRUE); /* Like YUY2 but planar */ +FORMAT(qcV1, 'q','c','V','1', 12, NO_BF, "YVU411P", FALSE); /* Like qcY1 but V and U planes are in this order */ +FORMAT(qcV2, 'q','c','V','2', 16, NO_BF, "YVU422P", FALSE); /* Like qcY2 but V and U planes are in this order */ +FORMAT(qcU9, 'q','c','U','9', 9, NO_BF, "YUV410P", TRUE); /* Like YVU9 but U and V planes are in this order */ +FORMAT(qcYY, 'q','c','Y','Y', 12, NO_BF, "YYUV", FALSE); /* Packed 4:2:2 sampling, Y, Y, U, V */ +FORMAT(NV12, 'N','V','1','2', 12, NO_BF, "NV12", FALSE); +FORMAT(NV21, 'N','V','2','1', 12, NO_BF, "NV21", FALSE); +/* Special formats */ +FORMAT(qcBT, 'q','c','B','T', -1, NO_BF, "BT848 RAW", FALSE); /* RAW is raw scanline data sampled (before PAL decoding) */ +FORMAT(qcBR, 'q','c','B','R', 8, NO_BF, "BAYER", TRUE); /* Same as STVA? */ +FORMAT(qcMJ, 'q','c','M','J', 0, NO_BF, "MJPEG", TRUE); /* Same as MJPG? */ +FORMAT(qcWN, 'q','c','W','N', -1, NO_BF, "Winnov hw", FALSE); /* Same as WNV1 (or CHAM, WINX, YUV8)? */ +/* }}} */ +/* {{{ [fold] struct qc_fmt_alias: Alias fourcc codes for above formats */ +static struct qc_fmt_alias { + u32 fcc; + struct qc_fmt_format const *format; +} const qc_fmt_aliases[] = { + { v4l2_fourcc(0,0,0,0), &qc_fmt_formats_RGB_24L }, /* Could be any format with fourcc 'RGB2' */ + { v4l2_fourcc('Y','8',' ',' '), &qc_fmt_formats_Y800 }, + { v4l2_fourcc('Y','U','N','V'), &qc_fmt_formats_YUY2 }, + { v4l2_fourcc('V','4','2','2'), &qc_fmt_formats_YUY2 }, + { v4l2_fourcc('Y','4','2','2'), &qc_fmt_formats_UYVY }, + { v4l2_fourcc('U','Y','N','V'), &qc_fmt_formats_UYVY }, + { v4l2_fourcc('I','4','2','0'), &qc_fmt_formats_IYUV }, +}; +/* }}} */ +/* {{{ [fold] struct qc_fmt_palette: table to convert V4L code into fourcc, supported formats */ +static struct qc_fmt_palette { + int palette; /* V4L1 standard palette type */ + struct qc_fmt_format const *format; +} const qc_fmt_palettes[] = { + { VIDEO_PALETTE_GREY, &qc_fmt_formats_Y800 }, + { VIDEO_PALETTE_HI240, &qc_fmt_formats_RGB_HI }, + /* RGB formats */ + { VIDEO_PALETTE_RGB565, &qc_fmt_formats_RGB_565L }, + { VIDEO_PALETTE_RGB24, &qc_fmt_formats_BGR_24L }, + { VIDEO_PALETTE_RGB32, &qc_fmt_formats_BGR_32L }, + { VIDEO_PALETTE_RGB555, &qc_fmt_formats_RGB_555L }, + /* Component YUV formats */ + { VIDEO_PALETTE_YUV422, &qc_fmt_formats_YUY2 }, /* Assume this is YUY2, even though V4L1 docs say this is 8 bpp format */ + { VIDEO_PALETTE_YUYV, &qc_fmt_formats_YUY2 }, /* Benedict Bridgwater : Bt848 maps this to Y41P, but it is simply wrong--we follow V4L2 v4l_compat.c */ + { VIDEO_PALETTE_UYVY, &qc_fmt_formats_UYVY }, + { VIDEO_PALETTE_YUV420, &qc_fmt_formats_IYUV }, /* Assume this is planar, even though V4L1 header file indicates otherwise */ + { VIDEO_PALETTE_YUV411, &qc_fmt_formats_qcY1 }, /* Assume this is planar, even though V4L1 header file indicates otherwise (could be also fourcc 'Y41P') -from benedict */ + { VIDEO_PALETTE_RAW, &qc_fmt_formats_qcBT }, + /* Planar YUV formats */ + { VIDEO_PALETTE_YUV422P, &qc_fmt_formats_qcY2 }, + { VIDEO_PALETTE_YUV411P, &qc_fmt_formats_qcY1 }, + { VIDEO_PALETTE_YUV420P, &qc_fmt_formats_IYUV }, + { VIDEO_PALETTE_YUV410P, &qc_fmt_formats_qcU9 }, + /* Special formats */ + { VIDEO_PALETTE_BAYER, &qc_fmt_formats_qcBR }, + { VIDEO_PALETTE_MJPEG, &qc_fmt_formats_qcMJ }, +}; +/* }}} */ +/* {{{ [fold] struct qc_fmt_v4l2: V4L2 defines its own conflicting format codes */ +static struct qc_fmt_v4l2 { + u32 v4l2code; + struct qc_fmt_format const *format; +} const qc_fmt_v4l2s[] = { + { v4l2_fourcc('R','G','B','1'), &qc_fmt_formats_RGB_332 }, /* V4L2_PIX_FMT_RGB332 8 RGB-3-3-2 */ + { v4l2_fourcc('R','G','B','O'), &qc_fmt_formats_RGB_555L }, /* V4L2_PIX_FMT_RGB555 16 RGB-5-5-5 */ + { v4l2_fourcc('R','G','B','P'), &qc_fmt_formats_RGB_565L }, /* V4L2_PIX_FMT_RGB565 16 RGB-5-6-5 */ + { v4l2_fourcc('R','G','B','Q'), &qc_fmt_formats_RGB_555B }, /* V4L2_PIX_FMT_RGB555X 16 RGB-5-5-5 BE */ + { v4l2_fourcc('R','G','B','R'), &qc_fmt_formats_RGB_565B }, /* V4L2_PIX_FMT_RGB565X 16 RGB-5-6-5 BE */ + { v4l2_fourcc('B','G','R','3'), &qc_fmt_formats_BGR_24L }, /* V4L2_PIX_FMT_BGR24 24 BGR-8-8-8 */ + { v4l2_fourcc('R','G','B','3'), &qc_fmt_formats_RGB_24L }, /* V4L2_PIX_FMT_RGB24 24 RGB-8-8-8 */ + { v4l2_fourcc('B','G','R','4'), &qc_fmt_formats_BGR_32L }, /* V4L2_PIX_FMT_BGR32 32 BGR-8-8-8-8 */ + { v4l2_fourcc('R','G','B','4'), &qc_fmt_formats_RGB_32L }, /* V4L2_PIX_FMT_RGB32 32 RGB-8-8-8-8 */ + { v4l2_fourcc('G','R','E','Y'), &qc_fmt_formats_Y800 }, /* V4L2_PIX_FMT_GREY 8 Greyscale */ + { v4l2_fourcc('Y','V','U','9'), &qc_fmt_formats_YVU9 }, /* V4L2_PIX_FMT_YVU410 9 YVU 4:1:0 */ + { v4l2_fourcc('Y','V','1','2'), &qc_fmt_formats_YV12 }, /* V4L2_PIX_FMT_YVU420 12 YVU 4:2:0 */ + { v4l2_fourcc('Y','U','Y','V'), &qc_fmt_formats_YUY2 }, /* V4L2_PIX_FMT_YUYV 16 YUV 4:2:2 */ + { v4l2_fourcc('Y','U','Y','2'), &qc_fmt_formats_YUY2 }, /* V4L2_PIX_FMT_YUY2 16 YUV 4:2:2: undocumented, guess same as YUY2 */ + { v4l2_fourcc('U','Y','V','Y'), &qc_fmt_formats_UYVY }, /* V4L2_PIX_FMT_UYVY 16 YUV 4:2:2 */ + { v4l2_fourcc('Y','4','1','P'), &qc_fmt_formats_Y41P }, /* V4L2_PIX_FMT_Y41P 12 YUV 4:1:1 */ + { v4l2_fourcc('Y','U','V','9'), &qc_fmt_formats_qcU9 }, /* V4L2_PIX_FMT_YUV410 9 YUV 4:1:0 */ + { v4l2_fourcc('Y','U','1','2'), &qc_fmt_formats_IYUV }, /* V4L2_PIX_FMT_YUV420 12 YUV 4:2:0 */ + { v4l2_fourcc('P','4','2','2'), &qc_fmt_formats_qcY2 }, /* V4L2_PIX_FMT_YUV422P 16 YUV422 planar */ + { v4l2_fourcc('P','4','1','1'), &qc_fmt_formats_qcY1 }, /* V4L2_PIX_FMT_YUV411P 16 YUV411 planar: assume bpp should be 12 */ + { v4l2_fourcc('N','V','1','2'), &qc_fmt_formats_NV12 }, /* V4L2_PIX_FMT_NV12 12 Y/UV 4:2:0 */ + { v4l2_fourcc('4','2','2','P'), &qc_fmt_formats_qcV2 }, /* V4L2_PIX_FMT_YVU422P 16 YVU422 planar */ + { v4l2_fourcc('4','1','1','P'), &qc_fmt_formats_qcV1 }, /* V4L2_PIX_FMT_YVU411P 16 YVU411 planar: assume bpp should be 12 */ + { v4l2_fourcc('Y','Y','U','V'), &qc_fmt_formats_qcYY }, /* V4L2_PIX_FMT_YYUV 16 YUV 4:2:2: undocumented, guess this is qc YY */ + { v4l2_fourcc('H','I','2','4'), &qc_fmt_formats_RGB_HI }, /* V4L2_PIX_FMT_HI240 8 8-bit color */ + { v4l2_fourcc('N','V','2','1'), &qc_fmt_formats_NV21 }, /* V4L2_PIX_FMT_NV21 12 Y/UV 4:2:0 */ + { v4l2_fourcc('W','N','V','A'), &qc_fmt_formats_qcWN }, /* V4L2_PIX_FMT_WNVA Winnov hw compres */ +}; +/* }}} */ + +/* {{{ [fold] qc_fmt_issupported(int palette) */ +/* Check the format (can be called even before qc_fmt_init) */ +int qc_fmt_issupported(int palette) +{ + int i; + for (i=0; isupported) + return 0; + } + return -EINVAL; +} +/* }}} */ +/* {{{ [fold] qc_fmt_getname(int palette) */ +/* Return the format name (can be called even before qc_fmt_init) */ +const char *qc_fmt_getname(int palette) +{ + int i; + for (i=0; iname; + } + return "Unknown"; +} +/* }}} */ +/* {{{ [fold] qc_fmt_getdepth(int palette) */ +/* Return bits per pixel for the format, or + * 0=variable number (compressed formats), -1=unknown + * (can be called even before qc_fmt_init) */ +int qc_fmt_getdepth(int palette) +{ + int i; + for (i=0; ibpp; + } + return -1; /* Unknown bit depth */ +} +/* }}} */ +/* {{{ [fold] qc_fmt_init(struct quickcam *qc) */ +int qc_fmt_init(struct quickcam *qc) +{ + int r = 0; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_fmt_init(qc=%p/compr=%i)",qc,qc->settings.compress); +#if COMPRESS + if (qc->settings.compress) { + qc->fmt_data.compress = TRUE; + r = qc_mjpeg_init(&qc->fmt_data.mjpeg_data, 24, DEFAULT_BGR); + } else { + qc->fmt_data.compress = FALSE; + } +#endif + if (r>=0) IDEBUG_INIT(qc->fmt_data); + return r; +} +/* }}} */ +/* {{{ [fold] qc_fmt_exit(struct quickcam *qc) */ +void qc_fmt_exit(struct quickcam *qc) +{ + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_fmt_exit(qc=%p)",qc); +#if COMPRESS + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_fmt_exit/compress=%i",qc->fmt_data.compress); + if (qc->fmt_data.compress) qc_mjpeg_exit(&qc->fmt_data.mjpeg_data); + POISON(qc->fmt_data.compress); + POISON(qc->fmt_data.mjpeg_data); +#endif + POISON(qc->fmt_data.lut); + IDEBUG_EXIT_NOPOISON(qc->fmt_data); +} +/* }}} */ +/* {{{ [fold] qc_fmt_convert(struct quickcam *qc, unsigned char *src, unsigned int src_len, unsigned char *dst, unsigned int dst_len, int *midvalue) */ +/* Called after each full frame of bayer or compressed image obtained */ +/* Convert camera data in src to the application requested palette in dst */ +/* Return negative error code if failure, otherwise data length stored in dst */ +/* src_len is the length of actual data in src, dst_len is the maximum data size storable in dst */ +/* Also src buffer may be modified */ +/* Return image average brightness in midvalue (or -1 if not computed) */ +int qc_fmt_convert(struct quickcam *qc, unsigned char *src, unsigned int src_len, unsigned char *dst, unsigned int dst_len, int *midvalue) +{ + signed int originx, originy; /* Upper-left corner coordinates of the capture window in the bayer image */ + unsigned char *bayerwin; + int length; /* Converted image data length in bytes */ + int r = 0; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_imag_convert(qc=%p,src=%p,src_len=%i,dst=%p,dst_len=%i)",qc,src,src_len,dst,dst_len); + if (PARANOID && (qc==NULL || src==NULL || dst==NULL)) { PRINTK(KERN_CRIT,"NULL"); return -EINVAL; } + if (PARANOID && midvalue==NULL) { PRINTK(KERN_CRIT,"NULL"); return -EINVAL; } + IDEBUG_TEST(qc->fmt_data); + *midvalue = -1; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("sensor_width=%i sensor_height=%i vwin.width=%i vwin.height=%i", + qc->sensor_data.width,qc->sensor_data.height,qc->vwin.width,qc->vwin.height); + + if (qc->sensor_data.width < qc->vwin.width || qc->sensor_data.height < qc->vwin.height) { + if (qcdebug&QC_DEBUGERRORS) PDEBUG("sensor window is smaller than requested"); + r = -ENOMSG; + goto fail; + } + +#if DUMPDATA + if (midvalue) *midvalue = -1; + memset(dst, 0, dst_len); + memcpy(dst, src, src_len>dst_len ? dst_len : src_len); + length = (int)qc->vwin.width * (int)qc->vwin.height * 3; + return length; +#endif + +#if COMPRESS + if (!qc->sensor_data.compress) { +#endif + /* src buffer contains fixed length data in bayer format */ + /* sensor_data.height/width = frame size that is captured from the camera */ + /* vwin.height/width = frame size that the application is expecting */ + + /* Check if src buffer contains enough data */ + if (src_len < qc->sensor_data.width * qc->sensor_data.height) { + if (qcdebug&QC_DEBUGERRORS) PDEBUG("too little data by %i (expected %i)", qc->sensor_data.width*qc->sensor_data.height - src_len, qc->sensor_data.width * qc->sensor_data.height); + r = -EBADE; + goto fail; + } + /* calculate view window origin inside the whole frame */ + originy = ((signed int)qc->sensor_data.height - (signed int)qc->vwin.height) / 2; + originx = ((signed int)qc->sensor_data.width - (signed int)qc->vwin.width) / 2; + originx &= ~1; /* Set upper-left corner to a even coordinate */ + originy &= ~1; /* so that the first bayer pixel is green */ + bayerwin = src + originy * qc->sensor_data.width + originx; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("originy=%i originx=%i", originy,originx); + + if (qc->settings.adaptive && midvalue!=NULL) + *midvalue = qc_imag_bayer_midvalue(bayerwin, qc->sensor_data.width, qc->vwin.width, qc->vwin.height); + if (qc->settings.equalize || qc->settings.userlut) { + if (qc->settings.equalize) { + qc_imag_bayer_equalize(bayerwin, qc->sensor_data.width, qc->vwin.width, qc->vwin.height, &qc->fmt_data.lut); + } else { + /* Initialize LUT */ + int i; + for (i=0; i<256; i++) qc->fmt_data.lut[QC_LUT_RED+i] = i; + for (i=0; i<256; i++) qc->fmt_data.lut[QC_LUT_GREEN+i] = i; + for (i=0; i<256; i++) qc->fmt_data.lut[QC_LUT_BLUE+i] = i; + } + if (qc->settings.userlut) { + qc_imag_userlut(&qc->fmt_data.userlut, &qc->fmt_data.lut); + } + /* Could do here other effects to the lookup table */ + qc_imag_bayer_lut(bayerwin, qc->sensor_data.width, qc->vwin.width, qc->vwin.height, &qc->fmt_data.lut); + } + + if (qc->vpic.palette==VIDEO_PALETTE_BAYER) { + int i; + length = (int)qc->vwin.width * (int)qc->vwin.height; + if (length > dst_len) { + r = -ENOSPC; + goto fail; + } + /* It would be more efficient to capture data directly to the mmapped buffer, + * but more complex and hardly any application will use bayer palette anyway */ + for (i=0; ivwin.height; i++) { + memcpy(dst, bayerwin, qc->vwin.width); + bayerwin += qc->sensor_data.width; + dst += qc->vwin.width; + } + } else { + /* Convert the current frame to RGB */ + length = (int)qc->vwin.width * (int)qc->vwin.height * 3; + if (length > dst_len) { + r = -ENOSPC; + goto fail; + } + switch (qc->settings.quality) { + case 0: + qc_imag_bay2rgb_cottnoip(bayerwin, qc->sensor_data.width, + dst, 3*qc->vwin.width, + qc->vwin.width, qc->vwin.height, 3); + break; + case 1: + qc_imag_bay2rgb_cott(bayerwin, qc->sensor_data.width, + dst, 3*qc->vwin.width, + qc->vwin.width, qc->vwin.height, 3); + break; + case 2: + qc_imag_bay2rgb_horip(bayerwin, qc->sensor_data.width, + dst, 3*qc->vwin.width, + qc->vwin.width, qc->vwin.height, 3); + break; + case 3: + qc_imag_bay2rgb_ip(bayerwin, qc->sensor_data.width, + dst, 3*qc->vwin.width, + qc->vwin.width, qc->vwin.height, 3); + break; + default: + case 4: + qc_imag_bay2rgb_gptm_fast(bayerwin, qc->sensor_data.width, + dst, 3*qc->vwin.width, + qc->vwin.width, qc->vwin.height, 3); + break; + case 5: + qc_imag_bay2rgb_gptm(bayerwin, qc->sensor_data.width, + dst, 3*qc->vwin.width, + qc->vwin.width, qc->vwin.height, 3, qc->vpic.whiteness); + break; + } + goto rgb24; + } + +#if COMPRESS + } else { + /* src buffer contains variable length data in mjpeg format */ + if (qc->vpic.palette==VIDEO_PALETTE_MJPEG) { + /* Directly copy data from src to dst, can not resize */ + length = src_len; + if (length > dst_len) { + r = -ENOSPC; + goto fail; + } + memcpy(dst, src, src_len); + } else { + /* Decode compressed images */ + if (!qc->fmt_data.compress) { + r = -EINVAL; + goto fail; + } + length = qc->sensor_data.width * qc->sensor_data.height * 3; + if (length > dst_len) { + r = -ENOSPC; + goto fail; + } + r = qc_mjpeg_decode(&qc->fmt_data.mjpeg_data, src, src_len, dst); + if (r<0) goto fail; + + if ((int)qc->vwin.width < qc->sensor_data.width || (int)qc->vwin.height < qc->sensor_data.height) { + /* User requested smaller image than camera sent, so crop the image */ + unsigned char *s, *d = dst; + int i; + s = dst; + s += (qc->sensor_data.height - (int)qc->vwin.height)/2 * qc->sensor_data.width*3; + s += (qc->sensor_data.width - (int)qc->vwin.width)/2 * 3; + for (i=0; ivwin.height; i++) { + memcpy(d, s, (int)qc->vwin.width*3); + s += qc->sensor_data.width * 3; + d += (int)qc->vwin.width * 3; + } + /* vwin.width/height is always smaller or equal to sensor_data.width/height */ + length = (int)qc->vwin.width * (int)qc->vwin.height * 3; + } + if (qc->settings.adaptive && midvalue!=NULL) *midvalue = qc_imag_rgb24_midvalue(dst, 3*qc->sensor_data.width, (int)qc->vwin.width, (int)qc->vwin.height); + goto rgb24; + } + } +#endif + return length; + +rgb24: /* We have now RGB (24 bpp) data in dst. If some other format is desired, */ + /* convert the RGB image to it (e.g. YUV) */ + +#ifdef DEBUG +#if 1 +{ +/* Draw red rectangle around image (useful for debugging boundaries) */ +static const int R = 255; +static const int G = 0; +static const int B = 0; + int ty,tx; + for (tx=0; txvwin.width; tx++) { + ty=0; + dst[ty*qc->vwin.width*3+tx*3] = B; + dst[ty*qc->vwin.width*3+tx*3+1] = G; + dst[ty*qc->vwin.width*3+tx*3+2] = R; + ty=qc->vwin.height-1; + dst[ty*qc->vwin.width*3+tx*3] = B; + dst[ty*qc->vwin.width*3+tx*3+1] = G; + dst[ty*qc->vwin.width*3+tx*3+2] = R; + } + for (ty=0; tyvwin.height; ty++) { + tx=0; + dst[ty*qc->vwin.width*3+tx*3] = B; + dst[ty*qc->vwin.width*3+tx*3+1] = G; + dst[ty*qc->vwin.width*3+tx*3+2] = R; + tx=qc->vwin.width-1; + dst[ty*qc->vwin.width*3+tx*3] = B; + dst[ty*qc->vwin.width*3+tx*3+1] = G; + dst[ty*qc->vwin.width*3+tx*3+2] = R; + } +} +#endif +#endif + + if (qc->vpic.palette != VIDEO_PALETTE_RGB24) { + // FIXME: should check here that dst_len <= resulted image length + length = qc_yuv_rgb2yuv(dst, length, qc->vpic.palette); + } else if (qc->settings.compat_torgb) { + qc_imag_rgbbgr(dst, length/3, 3); + } + return length; + +fail: if (qcdebug&(QC_DEBUGERRORS|QC_DEBUGLOGIC)) PDEBUG("failed qc_imag_convert()=%i",r); + return r; +} +/* }}} */ + +/* }}} */ + +/* End of file */ --- linux-2.6.28.orig/ubuntu/qc-usb/videodev2.h +++ linux-2.6.28/ubuntu/qc-usb/videodev2.h @@ -0,0 +1,1156 @@ +/* + * Video for Linux Two + * + * Header file for V4L2 drivers and applications. + * + * Author: Bill Dirks + */ + +#ifndef __LINUX_VIDEODEV_H +#define __LINUX_VIDEODEV_H + +#define V4L2_MAJOR_VERSION 0 +#define V4L2_MINOR_VERSION 20 + +#include "videodevfix.h" + + +/* + * M I S C E L L A N E O U S + */ + +/* Four-character-code (FOURCC) */ +#define fourcc(a,b,c,d)\ + (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24)) + +/* Open flag for non-capturing opens on capture devices */ +#define O_NONCAP O_TRUNC +#define O_NOIO O_TRUNC + +/* Timestamp data type, 64-bit signed integer */ +/* Should be removed from here when UST is added to kernel */ +#ifndef STAMP_T +#define STAMP_T +typedef __s64 stamp_t; +#endif + +/* + * D R I V E R C A P A B I L I T I E S + */ +struct v4l2_capability +{ + char name[32]; /* Descriptive, and unique */ + int type; /* Device type, see below */ + int inputs; /* Num video inputs */ + int outputs; /* Num video outputs */ + int audios; /* Num audio devices */ + int maxwidth; + int maxheight; + int minwidth; + int minheight; + int maxframerate; + __u32 flags; /* Feature flags, see below */ + __u32 reserved[4]; +}; +/* Values for 'type' field */ +#define V4L2_TYPE_CAPTURE 0 /* Is a video capture device */ +#define V4L2_TYPE_CODEC 1 /* Is a CODEC device */ +#define V4L2_TYPE_OUTPUT 2 /* Is a video output device */ +#define V4L2_TYPE_FX 3 /* Is a video effects device */ +#define V4L2_TYPE_VBI 4 /* Is a VBI capture device */ +#define V4L2_TYPE_VTR 5 /* Is a tape recorder controller */ +#define V4L2_TYPE_VTX 6 /* Is a teletext device */ +#define V4L2_TYPE_RADIO 7 /* Is a radio device */ +#define V4L2_TYPE_PRIVATE 1000 /* Start of driver private types */ +/* Flags for 'flags' field */ +#define V4L2_FLAG_READ 0x00001 /* Can capture via read() call */ +#define V4L2_FLAG_WRITE 0x00002 /* Can accept data via write() */ +#define V4L2_FLAG_STREAMING 0x00004 /* Can capture streaming video */ +#define V4L2_FLAG_PREVIEW 0x00008 /* Can do automatic preview */ +#define V4L2_FLAG_SELECT 0x00010 /* Supports the select() call */ +#define V4L2_FLAG_TUNER 0x00020 /* Can tune */ +#define V4L2_FLAG_MONOCHROME 0x00040 /* Monochrome only */ +#define V4L2_FLAG_DATA_SERVICE 0x00080 /* Has a related data service dev. */ + + +/* + * V I D E O I M A G E F O R M A T + */ +struct v4l2_pix_format +{ + __u32 width; + __u32 height; + __u32 depth; + __u32 pixelformat; + __u32 flags; + __u32 bytesperline; /* only used when there are pad bytes */ + __u32 sizeimage; + __u32 priv; /* private data, depends on pixelformat */ +}; +/* Pixel format FOURCC depth Description */ +#define V4L2_PIX_FMT_RGB332 fourcc('R','G','B','1') /* 8 RGB-3-3-2 */ +#define V4L2_PIX_FMT_RGB555 fourcc('R','G','B','O') /* 16 RGB-5-5-5 */ +#define V4L2_PIX_FMT_RGB565 fourcc('R','G','B','P') /* 16 RGB-5-6-5 */ +#define V4L2_PIX_FMT_BGR24 fourcc('B','G','R','3') /* 24 BGR-8-8-8 */ +#define V4L2_PIX_FMT_RGB24 fourcc('R','G','B','3') /* 24 RGB-8-8-8 */ +#define V4L2_PIX_FMT_BGR32 fourcc('B','G','R','4') /* 32 BGR-8-8-8-8 */ +#define V4L2_PIX_FMT_RGB32 fourcc('R','G','B','4') /* 32 RGB-8-8-8-8 */ +#define V4L2_PIX_FMT_GREY fourcc('G','R','E','Y') /* 8 Greyscale */ +#define V4L2_PIX_FMT_YVU410 fourcc('Y','V','U','9') /* 9 YVU 4:1:0 */ +#define V4L2_PIX_FMT_YVU420 fourcc('Y','V','1','2') /* 12 YVU 4:2:0 */ +#define V4L2_PIX_FMT_YUYV fourcc('Y','U','Y','V') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_UYVY fourcc('U','Y','V','Y') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_YVU422P fourcc('4','2','2','P') /* 16 YVU422 planar */ +#define V4L2_PIX_FMT_YVU411P fourcc('4','1','1','P') /* 16 YVU411 planar */ + +/* The following formats are not defined in the V4L2 specification */ +#define V4L2_PIX_FMT_YUV410 fourcc('Y','U','V','9') /* 9 YUV 4:1:0 */ +#define V4L2_PIX_FMT_YUV420 fourcc('Y','U','1','2') /* 12 YUV 4:2:0 */ +#define V4L2_PIX_FMT_YYUV fourcc('Y','Y','U','V') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_HI240 fourcc('H','I','2','4') /* 8 8-bit color */ + + +/* Flags */ +#define V4L2_FMT_FLAG_COMPRESSED 0x0001 /* Compressed format */ +#define V4L2_FMT_FLAG_BYTESPERLINE 0x0002 /* bytesperline field valid */ +#define V4L2_FMT_FLAG_INTERLACED 0x0004 /* Image is interlaced */ +#define V4L2_FMT_FLAG_TOPFIELD 0x0008 /* is a top field only */ +#define V4L2_FMT_FLAG_BOTFIELD 0x0010 /* is a bottom field only */ +#define V4L2_FMT_FLAG_ODDFIELD V4L2_FMT_FLAG_TOPFIELD +#define V4L2_FMT_FLAG_EVENFIELD V4L2_FMT_FLAG_BOTFIELD +#define V4L2_FMT_FLAG_COMBINED V4L2_FMT_FLAG_INTERLACED +#define V4L2_FMT_CS_field 0xF000 /* Color space field mask */ +#define V4L2_FMT_CS_601YUV 0x1000 /* ITU YCrCb color space */ +#define V4L2_FMT_FLAG_SWCONVERSION 0x0800 /* used only in format enum. */ +/* SWCONVERSION indicates the format is not natively supported by the */ +/* driver and the driver uses software conversion to support it */ + + +/* + * F O R M A T E N U M E R A T I O N + */ +struct v4l2_fmtdesc +{ + int index; /* Format number */ + char description[32]; /* Description string */ + __u32 pixelformat; /* Format fourcc */ + __u32 flags; /* Format flags */ + __u32 depth; /* Bits per pixel */ + __u32 reserved[2]; +}; + +struct v4l2_cvtdesc +{ + int index; + struct + { + __u32 pixelformat; + __u32 flags; + __u32 depth; + __u32 reserved[2]; + } in, out; +}; + +struct v4l2_fxdesc +{ + int index; + char name[32]; + __u32 flags; + __u32 inputs; + __u32 controls; + __u32 reserved[2]; +}; + + +/* + * T I M E C O D E + */ +struct v4l2_timecode +{ + __u8 frames; + __u8 seconds; + __u8 minutes; + __u8 hours; + __u8 userbits[4]; + __u32 flags; + __u32 type; +}; +/* Type */ +#define V4L2_TC_TYPE_24FPS 1 +#define V4L2_TC_TYPE_25FPS 2 +#define V4L2_TC_TYPE_30FPS 3 +#define V4L2_TC_TYPE_50FPS 4 +#define V4L2_TC_TYPE_60FPS 5 + + +/* Flags */ +#define V4L2_TC_FLAG_DROPFRAME 0x0001 /* "drop-frame" mode */ +#define V4L2_TC_FLAG_COLORFRAME 0x0002 +#define V4L2_TC_USERBITS_field 0x000C +#define V4L2_TC_USERBITS_USERDEFINED 0x0000 +#define V4L2_TC_USERBITS_8BITCHARS 0x0008 +/* The above is based on SMPTE timecodes */ + + +/* + * C O M P R E S S I O N P A R A M E T E R S + */ +struct v4l2_compression +{ + int quality; + int keyframerate; + int pframerate; + __u32 reserved[5]; +}; + + +/* + * M E M O R Y - M A P P I N G B U F F E R S + */ +struct v4l2_requestbuffers +{ + int count; + __u32 type; + __u32 reserved[2]; +}; +struct v4l2_buffer +{ + int index; + __u32 type; + __u32 offset; + __u32 length; + __u32 bytesused; + __u32 flags; + stamp_t timestamp; + struct v4l2_timecode timecode; + __u32 sequence; + __u32 reserved[3]; +}; +/* Buffer type codes and flags for 'type' field */ +#define V4L2_BUF_TYPE_field 0x00001FFF /* Type field mask */ +#define V4L2_BUF_TYPE_CAPTURE 0x00000001 +#define V4L2_BUF_TYPE_CODECIN 0x00000002 +#define V4L2_BUF_TYPE_CODECOUT 0x00000003 +#define V4L2_BUF_TYPE_EFFECTSIN 0x00000004 +#define V4L2_BUF_TYPE_EFFECTSIN2 0x00000005 +#define V4L2_BUF_TYPE_EFFECTSOUT 0x00000006 +#define V4L2_BUF_TYPE_VIDEOOUT 0x00000007 +#define V4L2_BUF_TYPE_FXCONTROL 0x00000008 + +/* Starting value of driver private buffer types */ +#define V4L2_BUF_TYPE_PRIVATE 0x00001000 + +#define V4L2_BUF_ATTR_DEVICEMEM 0x00010000 /* Buffer is on device (flag) */ + +/* Flags used only in VIDIOC_REQBUFS */ +#define V4L2_BUF_REQ_field 0xF0000000 +#define V4L2_BUF_REQ_CONTIG 0x10000000 /* Map all buffers in one + contiguous mmap(). This flag + only used in VIDIOC_REQBUFS */ + +/* Flags for 'flags' field */ +#define V4L2_BUF_FLAG_MAPPED 0x0001 /* Buffer is mapped (flag) */ +#define V4L2_BUF_FLAG_QUEUED 0x0002 /* Buffer is queued for processing */ +#define V4L2_BUF_FLAG_DONE 0x0004 /* Buffer is ready */ +#define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */ +#define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */ +#define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */ +#define V4L2_BUF_FLAG_TOPFIELD 0x0040 /* Image is a top field only */ +#define V4L2_BUF_FLAG_BOTFIELD 0x0080 /* Image is a bottom field only */ +#define V4L2_BUF_FLAG_ODDFIELD V4L2_BUF_FLAG_TOPFIELD +#define V4L2_BUF_FLAG_EVENFIELD V4L2_BUF_FLAG_BOTFIELD +#define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */ + +/* + * O V E R L A Y P R E V I E W + */ +struct v4l2_framebuffer +{ + __u32 capability; + __u32 flags; + void *base[3]; + struct v4l2_pix_format fmt; +}; +/* Flags for the 'capability' field. Read only */ +#define V4L2_FBUF_CAP_EXTERNOVERLAY 0x0001 +#define V4L2_FBUF_CAP_CHROMAKEY 0x0002 +#define V4L2_FBUF_CAP_CLIPPING 0x0004 +#define V4L2_FBUF_CAP_SCALEUP 0x0008 +#define V4L2_FBUF_CAP_SCALEDOWN 0x0010 +#define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0020 +/* Flags for the 'flags' field. */ +#define V4L2_FBUF_FLAG_PRIMARY 0x0001 +#define V4L2_FBUF_FLAG_OVERLAY 0x0002 +#define V4L2_FBUF_FLAG_CHROMAKEY 0x0004 + +struct v4l2_clip +{ + int x; + int y; + int width; + int height; + struct v4l2_clip *next; +}; +struct v4l2_window +{ + int x; + int y; + int width; + int height; + __u32 chromakey; + struct v4l2_clip *clips; + int clipcount; + void *bitmap; +}; + + +/* + * D E V I C E P E R F O R M A N C E + */ +struct v4l2_performance +{ + int frames; + int framesdropped; + __u64 bytesin; + __u64 bytesout; + __u32 reserved[4]; +}; + +/* + * C A P T U R E P A R A M E T E R S + */ +struct v4l2_captureparm +{ + __u32 capability; /* Supported modes */ + __u32 capturemode; /* Current mode */ + unsigned long timeperframe; /* Time per frame in .1us units */ + __u32 extendedmode; /* Driver-specific extensions */ + __u32 reserved[4]; +}; +/* Flags for 'capability' and 'capturemode' fields */ +#define V4L2_MODE_HIGHQUALITY 0x0001 /* High quality imaging mode */ +//#define V4L2_MODE_VFLIP 0x0002 /* Flip image vertically */ +//#define V4L2_MODE_HFLIP 0x0004 /* Flip image horizontally */ +#define V4L2_CAP_TIMEPERFRAME 0x1000 /* timeperframe field is supported */ + +struct v4l2_outputparm +{ + __u32 capability; /* Supported modes */ + __u32 outputmode; /* Current mode */ + unsigned long timeperframe; /* Time per frame in .1us units */ + __u32 extendedmode; /* Driver-specific extensions */ + __u32 reserved[4]; +}; + +/* + * I N P U T I M A G E C R O P P I N G + */ +struct v4l2_cropcap +{ + __u32 capability; + int min_x; + int min_y; + int max_x; + int max_y; + int default_left; + int default_top; + int default_right; + int default_bottom; + __u32 reserved[2]; +}; +struct v4l2_crop +{ + int left; + int top; + int right; + int bottom; + __u32 reserved; +}; + +/* + * D I G I T A L Z O O M + */ +struct v4l2_zoomcap +{ + __u32 capability; + __u32 maxwidth; + __u32 maxheight; + __u32 minwidth; + __u32 minheight; + __u32 reserved[2]; +}; +/* Flags for the capability field */ +#define V4L2_ZOOM_NONCAP 0x0001 +#define V4L2_ZOOM_WHILESTREAMING 0x0002 + +struct v4l2_zoom +{ + __u32 x; + __u32 y; + __u32 width; + __u32 height; + __u32 reserved; +}; + + +/* + * A N A L O G V I D E O S T A N D A R D + */ +struct v4l2_standard +{ + __u8 name[24]; + struct { + __u32 numerator; + __u32 denominator; /* >= 1 */ + } framerate; /* Frames, not fields */ + __u32 framelines; + __u32 reserved1; + __u32 colorstandard; + union { + struct { + __u32 colorsubcarrier; /* Hz */ + } pal; + struct { + __u32 colorsubcarrier; /* Hz */ + } ntsc; + struct { + __u32 f0b; /* Hz (blue) */ + __u32 f0r; /* Hz (red) */ + } secam; + __u8 reserved[12]; + } colorstandard_data; + __u32 transmission; /* Bit field. Must be zero for + non-modulators/demodulators. */ + __u32 reserved2; /* Must be set to zero */ +}; + +/* Values for the 'colorstandard' field */ +#define V4L2_COLOR_STD_PAL 1 +#define V4L2_COLOR_STD_NTSC 2 +#define V4L2_COLOR_STD_SECAM 3 + +/* Values for the color subcarrier fields */ +#define V4L2_COLOR_SUBC_PAL 4433619 /* PAL BGHI, NTSC-44 */ +#define V4L2_COLOR_SUBC_PAL_M 3575611 /* PAL M (Brazil) */ +#define V4L2_COLOR_SUBC_PAL_N 3582056 /* PAL N */ +#define V4L2_COLOR_SUBC_NTSC 3579545 /* NTSC M, NTSC-Japan */ +#define V4L2_COLOR_SUBC_SECAMB 4250000 /* SECAM B - Y carrier */ +#define V4L2_COLOR_SUBC_SECAMR 4406250 /* SECAM R - Y carrier */ + +/* Flags for the 'transmission' field */ +#define V4L2_TRANSM_STD_B (1<<1) +#define V4L2_TRANSM_STD_D (1<<3) +#define V4L2_TRANSM_STD_G (1<<6) +#define V4L2_TRANSM_STD_H (1<<7) +#define V4L2_TRANSM_STD_I (1<<8) +#define V4L2_TRANSM_STD_K (1<<10) +#define V4L2_TRANSM_STD_K1 (1<<11) +#define V4L2_TRANSM_STD_L (1<<12) +#define V4L2_TRANSM_STD_M (1<<13) +#define V4L2_TRANSM_STD_N (1<<14) + + +/* Used in the VIDIOC_ENUMSTD ioctl for querying supported standards */ +struct v4l2_enumstd +{ + int index; + struct v4l2_standard std; + __u32 inputs; /* set of inputs that */ + /* support this standard */ + __u32 outputs; /* set of outputs that */ + /* support this standard */ + __u32 reserved[2]; +}; + + +/* + * V I D E O I N P U T S + */ +struct v4l2_input +{ + int index; /* Which input */ + char name[32]; /* Label */ + int type; /* Type of input */ + __u32 capability; /* Capability flags */ + int assoc_audio; /* Associated audio input */ + __u32 reserved[4]; +}; +/* Values for the 'type' field */ +#define V4L2_INPUT_TYPE_TUNER 1 +#define V4L2_INPUT_TYPE_CAMERA 2 + +/* Flags for the 'capability' field */ +#define V4L2_INPUT_CAP_AUDIO 0x0001 /* assoc_audio */ + + +/* + * V I D E O O U T P U T S + */ +struct v4l2_output +{ + int index; /* Which output */ + char name[32]; /* Label */ + int type; /* Type of output */ + __u32 capability; /* Capability flags */ + int assoc_audio; /* Associated audio */ + __u32 reserved[4]; +}; +/* Values for the 'type' field */ +#define V4L2_OUTPUT_TYPE_MODULATOR 1 +#define V4L2_OUTPUT_TYPE_ANALOG 2 +#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3 + +/* Flags for the 'capability' field */ +#define V4L2_OUTPUT_CAP_AUDIO 0x0001 /* assoc_audio */ + + +/* + * C O N T R O L S + */ +struct v4l2_control +{ + __u32 id; + int value; +}; + +/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */ +struct v4l2_queryctrl +{ + __u32 id; + __u8 name[32]; /* Whatever */ + int minimum; /* Note signedness */ + int maximum; + unsigned int step; + int default_value; + __u32 type; + __u32 flags; + __u32 category; /* Automatically filled in by V4L2 */ + __u8 group[32]; /* for pre-defined controls */ + __u32 reserved[2]; +}; + +/* Used in the VIDIOC_QUERYMENU ioctl for querying menu items */ +struct v4l2_querymenu +{ + __u32 id; + int index; + __u8 name[32]; /* Whatever */ + int reserved; +}; + +/* Used in V4L2_BUF_TYPE_FXCONTROL buffers */ +struct v4l2_fxcontrol +{ + __u32 id; + __u32 value; +}; + +/* Control types */ +#define V4L2_CTRL_TYPE_INTEGER 0 +#define V4L2_CTRL_TYPE_BOOLEAN 1 +#define V4L2_CTRL_TYPE_MENU 2 +#define V4L2_CTRL_TYPE_BUTTON 3 + +/* Control flags */ +#define V4L2_CTRL_FLAG_DISABLED 0x0001 +#define V4L2_CTRL_FLAG_GRABBED 0x0002 + +/* Control categories */ +#define V4L2_CTRL_CAT_VIDEO 1 /* "Video" */ +#define V4L2_CTRL_CAT_AUDIO 2 /* "Audio" */ +#define V4L2_CTRL_CAT_EFFECT 3 /* "Effect" */ + +/* Control IDs defined by V4L2 */ +#define V4L2_CID_BASE 0x00980900 +/* IDs reserved for driver specific controls */ +#define V4L2_CID_PRIVATE_BASE 0x08000000 +/* IDs reserved for effect-specific controls on effects devices */ +#define V4L2_CID_EFFECT_BASE 0x0A00B000 + +#define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0) +#define V4L2_CID_CONTRAST (V4L2_CID_BASE+1) +#define V4L2_CID_SATURATION (V4L2_CID_BASE+2) +#define V4L2_CID_HUE (V4L2_CID_BASE+3) +#define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE+5) +#define V4L2_CID_AUDIO_BALANCE (V4L2_CID_BASE+6) +#define V4L2_CID_AUDIO_BASS (V4L2_CID_BASE+7) +#define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8) +#define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9) +#define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10) +#define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11) +#define V4l2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12) +#define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13) +#define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14) +#define V4L2_CID_BLUE_BALANCE (V4L2_CID_BASE+15) +#define V4L2_CID_GAMMA (V4L2_CID_BASE+16) +#define V4L2_CID_WHITENESS (V4L2_CID_GAMMA) /* ? Not sure */ +#define V4L2_CID_EXPOSURE (V4L2_CID_BASE+17) +#define V4L2_CID_AUTOGAIN (V4L2_CID_BASE+18) +#define V4L2_CID_GAIN (V4L2_CID_BASE+19) +#define V4L2_CID_HFLIP (V4L2_CID_BASE+20) +#define V4L2_CID_VFLIP (V4L2_CID_BASE+21) +#define V4L2_CID_HCENTER (V4L2_CID_BASE+22) +#define V4L2_CID_VCENTER (V4l2_CID_BASE+23) +#define V4L2_CID_LASTP1 (V4L2_CID_BASE+24) /* last CID + 1 */ +/* Remember to change fill_ctrl_category() in videodev.c */ + +/* + * T U N I N G + */ +struct v4l2_tuner +{ + int input; + char name[32]; + struct v4l2_standard std; + __u32 capability; + __u32 rangelow; + __u32 rangehigh; + __u32 rxsubchans; + __u32 audmode; + int signal; + int afc; + __u32 reserved[4]; +}; +struct v4l2_modulator +{ + int output; + char name[32]; + struct v4l2_standard std; + __u32 capability; + __u32 rangelow; + __u32 rangehigh; + __u32 txsubchans; + __u32 reserved[4]; +}; +/* Flags for the 'capability' field */ +#define V4L2_TUNER_CAP_LOW 0x0001 +#define V4L2_TUNER_CAP_NORM 0x0002 +#define V4L2_TUNER_CAP_STEREO 0x0010 +#define V4L2_TUNER_CAP_LANG2 0x0020 +#define V4L2_TUNER_CAP_SAP 0x0020 +#define V4L2_TUNER_CAP_LANG1 0x0040 + +/* Flags for the 'rxsubchans' field */ +#define V4L2_TUNER_SUB_MONO 0x0001 +#define V4L2_TUNER_SUB_STEREO 0x0002 +#define V4L2_TUNER_SUB_LANG2 0x0004 +#define V4L2_TUNER_SUB_SAP 0x0004 +#define V4L2_TUNER_SUB_LANG1 0x0008 + +/* Values for the 'audmode' field */ +#define V4L2_TUNER_MODE_MONO 0x0000 +#define V4L2_TUNER_MODE_STEREO 0x0001 +#define V4L2_TUNER_MODE_LANG2 0x0002 +#define V4L2_TUNER_MODE_SAP 0x0002 +#define V4L2_TUNER_MODE_LANG1 0x0003 + +struct v4l2_frequency +{ + int port; + __u32 frequency; + __u32 reserved[2]; +}; + +/* + * A U D I O + */ +struct v4l2_audio +{ + int audio; + char name[32]; + __u32 capability; + __u32 mode; + __u32 reserved[2]; +}; +/* Flags for the 'capability' field */ +#define V4L2_AUDCAP_EFFECTS 0x0020 +#define V4L2_AUDCAP_LOUDNESS 0x0040 +#define V4L2_AUDCAP_AVL 0x0080 + +/* Flags for the 'mode' field */ +#define V4L2_AUDMODE_LOUDNESS 0x00002 +#define V4L2_AUDMODE_AVL 0x00004 +#define V4L2_AUDMODE_STEREO_field 0x0FF00 +#define V4L2_AUDMODE_STEREO_LINEAR 0x00100 +#define V4L2_AUDMODE_STEREO_PSEUDO 0x00200 +#define V4L2_AUDMODE_STEREO_SPATIAL30 0x00300 +#define V4L2_AUDMODE_STEREO_SPATIAL50 0x00400 + +struct v4l2_audioout +{ + int audio; + char name[32]; + __u32 capability; + __u32 mode; + __u32 reserved[2]; +}; + +/* + * D A T A S E R V I C E S ( V B I ) + */ + +struct v4l2_vbi_format +{ + __u32 sampling_rate; /* in 1 Hz */ + __u32 reserved1; /* must be zero */ + __u32 samples_per_line; + __u32 sample_format; /* V4L2_VBI_SF_* */ + __s32 start[2]; + __u32 count[2]; + __u32 flags; /* V4L2_VBI_* */ + __u32 reserved2; /* must be zero */ +}; + +/* VBI sampling formats */ +#define V4L2_VBI_SF_UBYTE 1 + +/* VBI flags */ +#define V4L2_VBI_UNSYNC (1<< 0) +#define V4L2_VBI_INTERLACED (1<< 1) + + +/* + * A G G R E G A T E S T R U C T U R E S + */ + +/* Stream data format + */ +struct v4l2_format +{ + __u32 type; + union + { + struct v4l2_pix_format pix; /* image format */ + struct v4l2_vbi_format vbi; /* VBI data */ + /* add more */ + __u8 raw_data[200]; /* user-defined */ + } fmt; +}; + + +/* Stream type-dependent parameters + */ +struct v4l2_streamparm +{ + __u32 type; + union + { + struct v4l2_captureparm capture; + struct v4l2_outputparm output; + /* add more */ + __u8 raw_data[200]; /* user-defined */ + } parm; +}; + + + +/* + * I O C T L C O D E S F O R V I D E O D E V I C E S + * + */ +#define VIDIOC_QUERYCAP _IOR ('V', 0, struct v4l2_capability) +#define VIDIOC_RESERVED _IO ('V', 1) +#define VIDIOC_ENUM_PIXFMT _IOWR ('V', 2, struct v4l2_fmtdesc) +#define VIDIOC_ENUM_FBUFFMT _IOWR ('V', 3, struct v4l2_fmtdesc) +#define VIDIOC_G_FMT _IOWR ('V', 4, struct v4l2_format) +#define VIDIOC_S_FMT _IOWR ('V', 5, struct v4l2_format) +#define VIDIOC_G_COMP _IOR ('V', 6, struct v4l2_compression) +#define VIDIOC_S_COMP _IOW ('V', 7, struct v4l2_compression) +#define VIDIOC_REQBUFS _IOWR ('V', 8, struct v4l2_requestbuffers) +#define VIDIOC_QUERYBUF _IOWR ('V', 9, struct v4l2_buffer) +#define VIDIOC_G_FBUF _IOR ('V', 10, struct v4l2_framebuffer) +#define VIDIOC_S_FBUF _IOW ('V', 11, struct v4l2_framebuffer) +#define VIDIOC_G_WIN _IOR ('V', 12, struct v4l2_window) +#define VIDIOC_S_WIN _IOW ('V', 13, struct v4l2_window) +#define VIDIOC_PREVIEW _IOWR ('V', 14, int) +#define VIDIOC_QBUF _IOWR ('V', 15, struct v4l2_buffer) +#define VIDIOC_DQBUF _IOWR ('V', 17, struct v4l2_buffer) +#define VIDIOC_STREAMON _IOW ('V', 18, int) +#define VIDIOC_STREAMOFF _IOW ('V', 19, int) +#define VIDIOC_G_PERF _IOR ('V', 20, struct v4l2_performance) +#define VIDIOC_G_PARM _IOWR ('V', 21, struct v4l2_streamparm) +#define VIDIOC_S_PARM _IOW ('V', 22, struct v4l2_streamparm) +#define VIDIOC_G_STD _IOR ('V', 23, struct v4l2_standard) +#define VIDIOC_S_STD _IOW ('V', 24, struct v4l2_standard) +#define VIDIOC_ENUMSTD _IOWR ('V', 25, struct v4l2_enumstd) +#define VIDIOC_ENUMINPUT _IOWR ('V', 26, struct v4l2_input) +#define VIDIOC_G_CTRL _IOWR ('V', 27, struct v4l2_control) +#define VIDIOC_S_CTRL _IOW ('V', 28, struct v4l2_control) +#define VIDIOC_G_TUNER _IOWR ('V', 29, struct v4l2_tuner) +#define VIDIOC_S_TUNER _IOW ('V', 30, struct v4l2_tuner) +#define VIDIOC_G_FREQ _IOR ('V', 31, int) +#define VIDIOC_S_FREQ _IOWR ('V', 32, int) +#define VIDIOC_G_AUDIO _IOWR ('V', 33, struct v4l2_audio) +#define VIDIOC_S_AUDIO _IOW ('V', 34, struct v4l2_audio) +#define VIDIOC_QUERYCTRL _IOWR ('V', 36, struct v4l2_queryctrl) +#define VIDIOC_QUERYMENU _IOWR ('V', 37, struct v4l2_querymenu) +#define VIDIOC_G_INPUT _IOR ('V', 38, int) +#define VIDIOC_S_INPUT _IOWR ('V', 39, int) +#define VIDIOC_ENUMCVT _IOWR ('V', 40, struct v4l2_cvtdesc) +#define VIDIOC_G_OUTPUT _IOR ('V', 46, int) +#define VIDIOC_S_OUTPUT _IOWR ('V', 47, int) +#define VIDIOC_ENUMOUTPUT _IOWR ('V', 48, struct v4l2_output) +#define VIDIOC_G_AUDOUT _IOWR ('V', 49, struct v4l2_audioout) +#define VIDIOC_S_AUDOUT _IOW ('V', 50, struct v4l2_audioout) +#define VIDIOC_ENUMFX _IOWR ('V', 51, struct v4l2_fxdesc) +#define VIDIOC_G_EFFECT _IOR ('V', 52, int) +#define VIDIOC_S_EFFECT _IOWR ('V', 53, int) +#define VIDIOC_G_MODULATOR _IOWR ('V', 54, struct v4l2_modulator) +#define VIDIOC_S_MODULATOR _IOW ('V', 55, struct v4l2_modulator) + +#define VIDIOC_ENUM_CAPFMT VIDIOC_ENUM_PIXFMT +#define VIDIOC_ENUM_OUTFMT VIDIOC_ENUM_PIXFMT +#define VIDIOC_ENUM_SRCFMT VIDIOC_ENUM_PIXFMT +#define VIDIOC_ENUMFMT VIDIOC_ENUM_PIXFMT + +#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */ + + +#ifdef __KERNEL__ +/* + * These things are used only by drivers. + */ + +extern int videodev_init(void); + +/* + * + * V 4 L 2 D R I V E R H E L P E R A P I + * + * Some commonly needed functions for drivers. + */ + +extern void v4l2_version(int *major, int *minor); +extern int v4l2_major_number(void); + +/* Memory management */ +extern unsigned long v4l2_vmalloc_to_bus(void *virt); +extern unsigned long v4l2_vmalloc_to_page(void *virt); + +/* Simple queue management */ +struct v4l2_q_node +{ + struct v4l2_q_node *forw, *back; +}; +struct v4l2_queue +{ + struct v4l2_q_node *forw, *back; + rwlock_t qlock; +}; +extern void v4l2_q_init(struct v4l2_queue *q); +extern void v4l2_q_add_head(struct v4l2_queue *q, struct v4l2_q_node *node); +extern void v4l2_q_add_tail(struct v4l2_queue *q, struct v4l2_q_node *node); +extern void *v4l2_q_del_head(struct v4l2_queue *q); +extern void *v4l2_q_del_tail(struct v4l2_queue *q); +extern void *v4l2_q_peek_head(struct v4l2_queue *q); +extern void *v4l2_q_peek_tail(struct v4l2_queue *q); +extern void *v4l2_q_yank_node(struct v4l2_queue *q, struct v4l2_q_node *node); + +/* Math functions */ +extern u32 v4l2_math_div6432(u64 a, u32 d, u32 *r); + +/* Time functions */ +extern unsigned long v4l2_timestamp_divide(stamp_t t, + unsigned long p_100ns); +extern unsigned long v4l2_timestamp_correct(stamp_t *t, + unsigned long p_100ns); + +/* Master Clock functions */ +struct v4l2_clock +{ + void (*gettime)(stamp_t *); +}; +extern int v4l2_masterclock_register(struct v4l2_clock *clock); +extern void v4l2_masterclock_unregister(struct v4l2_clock *clock); +extern void v4l2_masterclock_gettime(stamp_t *curr); + +/* Video standard functions */ +extern unsigned int v4l2_video_std_fps(struct v4l2_standard *vs); +extern unsigned long v4l2_video_std_tpf(struct v4l2_standard *vs); +extern int v4l2_video_std_confirm(struct v4l2_standard *vs); +extern int v4l2_video_std_construct(struct v4l2_standard *vs, + int id, __u32 transmission); + +#define V4L2_STD_PAL 1 /* PAL B, G, H, I (...) */ +#define V4L2_STD_PAL_M 5 /* (Brazil) */ +#define V4L2_STD_PAL_N 6 /* (Argentina, Paraguay, Uruguay) */ +#define V4L2_STD_PAL_60 10 /* PAL/NTSC hybrid */ +#define V4L2_STD_NTSC 11 /* NTSC M (USA, ...) */ +#define V4L2_STD_NTSC_N 12 /* (Barbados, Bolivia, Colombia, + S. Korea) */ +#define V4L2_STD_NTSC_44 15 /* PAL/NTSC hybrid */ +#define V4L2_STD_SECAM 21 /* SECAM B, D, G, K, K1 (...) */ +//#define V4L2_STD_SECAM_H 27 /* (Greece, Iran, Morocco) */ +//#define V4L2_STD_SECAM_L 28 /* (France, Luxembourg, Monaco) */ +//#define V4L2_STD_SECAM_M 29 /* (Jamaica) */ + +/* + * D E V I C E D R I V E R R E G I S T R A T I O N + * + */ +struct v4l2_device +{ + char name[32]; + int type; + int minor; + + int (*open)(struct v4l2_device *v, + int flags, void **idptr); + void (*close)(void *id); + long (*read)(void *id, + char *buf, unsigned long count, int noblock); + long (*write)(void *id, + const char *buf, unsigned long count, int noblock); + int (*ioctl)(void *id, + unsigned int cmd, void *arg); + int (*mmap)(void *id, + struct vm_area_struct *vma); + int (*poll)(void *id, + struct file *file, poll_table *table); + + int (*initialize)(struct v4l2_device *v); + void *priv; /* may be used by the driver */ + + int busy; /* open count maintained by videodev.c */ + void *v4l2_priv; /* for V4L2 use */ + int v4l2_reserved[4]; /* for V4L2 use */ +}; + +/* Size of kernel ioctl arg buffer used in ioctl handler */ +#define V4L2_MAX_IOCTL_SIZE 256 + +extern int v4l2_register_device(struct v4l2_device *); +extern void v4l2_unregister_device(struct v4l2_device *); + +/* V4L2 structures */ +extern struct v4l2_device *v4l2_device_from_file(struct file *file); +extern void *v4l2_openid_from_file(struct file *file); + +#endif/*ifdef __KERNEL__ */ + + +/*---------------------------------------------------------------------- + Old Video for Linux backward compatibility below this line. + ---------------------------------------------------------------------- + + All new applications should use the new API calls. + + (These definitions taken from 2.2.1.) + + */ + + +#define VID_TYPE_CAPTURE 1 /* Can capture */ +#define VID_TYPE_TUNER 2 /* Can tune */ +#define VID_TYPE_TELETEXT 4 /* Does teletext */ +#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */ +#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */ +#define VID_TYPE_CLIPPING 32 /* Can clip */ +#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */ +#define VID_TYPE_SCALES 128 /* Scalable */ +#define VID_TYPE_MONOCHROME 256 /* Monochrome only */ +#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */ + +struct video_capability +{ + char name[32]; + int type; + int channels; /* Num channels */ + int audios; /* Num audio devices */ + int maxwidth; /* Supported width */ + int maxheight; /* And height */ + int minwidth; /* Supported width */ + int minheight; /* And height */ +}; + + +struct video_channel +{ + int channel; + char name[32]; + int tuners; + __u32 flags; +#define VIDEO_VC_TUNER 1 /* Channel has a tuner */ +#define VIDEO_VC_AUDIO 2 /* Channel has audio */ + __u16 type; +#define VIDEO_TYPE_TV 1 +#define VIDEO_TYPE_CAMERA 2 + __u16 norm; /* Norm set by channel */ +}; + +struct video_tuner +{ + int tuner; + char name[32]; + ulong rangelow, rangehigh; /* Tuner range */ + __u32 flags; +#define VIDEO_TUNER_PAL 1 +#define VIDEO_TUNER_NTSC 2 +#define VIDEO_TUNER_SECAM 4 +#define VIDEO_TUNER_LOW 8 /* Uses KHz not MHz */ +#define VIDEO_TUNER_NORM 16 /* Tuner can set norm */ +#define VIDEO_TUNER_STEREO_ON 128 /* Tuner is seeing stereo */ +#define VIDEO_TUNER_RDS_ON 256 /* Tuner is seeing an RDS datastream */ +#define VIDEO_TUNER_MBS_ON 512 /* Tuner is seeing an MBS datastream */ + __u16 mode; /* PAL/NTSC/SECAM/OTHER */ +#define VIDEO_MODE_PAL 0 +#define VIDEO_MODE_NTSC 1 +#define VIDEO_MODE_SECAM 2 +#define VIDEO_MODE_AUTO 3 + __u16 signal; /* Signal strength 16bit scale */ +}; + +struct video_picture +{ + __u16 brightness; + __u16 hue; + __u16 colour; + __u16 contrast; + __u16 whiteness; /* Black and white only */ + __u16 depth; /* Capture depth */ + __u16 palette; /* Palette in use */ +#define VIDEO_PALETTE_GREY 1 /* Linear greyscale */ +#define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */ +#define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */ +#define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */ +#define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */ +#define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */ +#define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */ +#define VIDEO_PALETTE_YUYV 8 +#define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */ +#define VIDEO_PALETTE_YUV420 10 +#define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */ +#define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */ +#define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */ +#define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */ +#define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */ +#define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */ +#define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */ +#define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */ +}; + +struct video_audio +{ + int audio; /* Audio channel */ + __u16 volume; /* If settable */ + __u16 bass, treble; + __u32 flags; +#define VIDEO_AUDIO_MUTE 1 +#define VIDEO_AUDIO_MUTABLE 2 +#define VIDEO_AUDIO_VOLUME 4 +#define VIDEO_AUDIO_BASS 8 +#define VIDEO_AUDIO_TREBLE 16 +#define VIDEO_AUDIO_BALANCE 32 + char name[16]; +#define VIDEO_SOUND_MONO 1 +#define VIDEO_SOUND_STEREO 2 +#define VIDEO_SOUND_LANG1 4 +#define VIDEO_SOUND_LANG2 8 + __u16 mode; + __u16 balance; /* Stereo balance */ + __u16 step; /* Step actual volume uses */ +}; + +struct video_clip +{ + __s32 x,y; + __s32 width, height; + struct video_clip *next; /* For user use/driver use only */ +}; + +struct video_window +{ + __u32 x,y; /* Position of window */ + __u32 width,height; /* Its size */ + __u32 chromakey; + __u32 flags; + struct video_clip *clips; /* Set only */ + int clipcount; +#define VIDEO_WINDOW_INTERLACE 1 +#define VIDEO_CLIP_BITMAP -1 +/* bitmap is 1024x625, a '1' bit represents a clipped pixel */ +#define VIDEO_CLIPMAP_SIZE (128 * 625) +}; + +struct video_capture +{ + __u32 x,y; /* Offsets into image */ + __u32 width, height; /* Area to capture */ + __u16 decimation; /* Decimation divder */ + __u16 flags; /* Flags for capture */ +#define VIDEO_CAPTURE_ODD 0 /* Temporal */ +#define VIDEO_CAPTURE_EVEN 1 +}; + +struct video_buffer +{ + void *base; + int height,width; + int depth; + int bytesperline; +}; + +struct video_mmap +{ + unsigned int frame; /* Frame (0 - n) for double buffer */ + int height,width; + unsigned int format; /* should be VIDEO_PALETTE_* */ +}; + +struct video_key +{ + __u8 key[8]; + __u32 flags; +}; + + +#define VIDEO_MAX_FRAME 32 + +struct video_mbuf +{ + int size; /* Total memory to map */ + int frames; /* Frames */ + int offsets[VIDEO_MAX_FRAME]; +}; + + +#define VIDEO_NO_UNIT (-1) + + +struct video_unit +{ + int video; /* Video minor */ + int vbi; /* VBI minor */ + int radio; /* Radio minor */ + int audio; /* Audio minor */ + int teletext; /* Teletext minor */ +}; + +#define VIDIOCGCAP _IOR('v',1,struct video_capability) /* Get capabilities */ +#define VIDIOCGCHAN _IOWR('v',2,struct video_channel) /* Get channel info (sources) */ +#define VIDIOCSCHAN _IOW('v',3,struct video_channel) /* Set channel */ +#define VIDIOCGTUNER _IOWR('v',4,struct video_tuner) /* Get tuner abilities */ +#define VIDIOCSTUNER _IOW('v',5,struct video_tuner) /* Tune the tuner for the current channel */ +#define VIDIOCGPICT _IOR('v',6,struct video_picture) /* Get picture properties */ +#define VIDIOCSPICT _IOW('v',7,struct video_picture) /* Set picture properties */ +#define VIDIOCCAPTURE _IOW('v',8,int) /* Start, end capture */ +#define VIDIOCGWIN _IOR('v',9, struct video_window) /* Set the video overlay window */ +#define VIDIOCSWIN _IOW('v',10, struct video_window) /* Set the video overlay window - passes clip list for hardware smarts , chromakey etc */ +#define VIDIOCGFBUF _IOR('v',11, struct video_buffer) /* Get frame buffer */ +#define VIDIOCSFBUF _IOW('v',12, struct video_buffer) /* Set frame buffer - root only */ +#define VIDIOCKEY _IOR('v',13, struct video_key) /* Video key event - to dev 255 is to all - cuts capture on all DMA windows with this key (0xFFFFFFFF == all) */ +#define VIDIOCGFREQ _IOR('v',14, unsigned long) /* Set tuner */ +#define VIDIOCSFREQ _IOW('v',15, unsigned long) /* Set tuner */ +#define VIDIOCGAUDIO _IOR('v',16, struct video_audio) /* Get audio info */ +#define VIDIOCSAUDIO _IOW('v',17, struct video_audio) /* Audio source, mute etc */ +#define VIDIOCSYNC _IOW('v',18, int) /* Sync with mmap grabbing */ +#define VIDIOCMCAPTURE _IOW('v',19, struct video_mmap) /* Grab frames */ +#define VIDIOCGMBUF _IOR('v', 20, struct video_mbuf) /* Memory map buffer info */ +#define VIDIOCGUNIT _IOR('v', 21, struct video_unit) /* Get attached units */ +#define VIDIOCGCAPTURE _IOR('v',22, struct video_capture) /* Get frame buffer */ +#define VIDIOCSCAPTURE _IOW('v',23, struct video_capture) /* Set frame buffer - root only */ +#define BASE_VIDIOCPRIVATE 192 /* 192-255 are private */ + + + +#endif/*ifndef __LINUX_VIDEODEV_H*/ --- linux-2.6.28.orig/ubuntu/qc-usb/Kconfig +++ linux-2.6.28/ubuntu/qc-usb/Kconfig @@ -0,0 +1,4 @@ +config QC_USB + tristate "Quickcam USB Driver" + default m + depends on USB --- linux-2.6.28.orig/ubuntu/qc-usb/videodevfix.h +++ linux-2.6.28/ubuntu/qc-usb/videodevfix.h @@ -0,0 +1,15 @@ +#ifndef VIDEODEVFIX_H +#define VIDEODEVFIX_H + +#include + +typedef int8_t __s8; +typedef u_int8_t __u8; +typedef int16_t __s16; +typedef u_int16_t __u16; +typedef int32_t __s32; +typedef u_int32_t __u32; +typedef int64_t __s64; +typedef u_int64_t __u64; + +#endif --- linux-2.6.28.orig/ubuntu/qc-usb/qc-memory.h +++ linux-2.6.28/ubuntu/qc-usb/qc-memory.h @@ -0,0 +1,10 @@ +#ifndef _LINUX_QC_MEMORY_H +#define _LINUX_QC_MEMORY_H + +#include + +void *qc_mm_rvmalloc(unsigned long size); +void qc_mm_rvfree(void *mem, unsigned long size); +int qc_mm_remap(struct vm_area_struct *vma, void *src, unsigned long src_size, const void *dst, unsigned long dst_size); + +#endif --- linux-2.6.28.orig/ubuntu/qc-usb/Makefile +++ linux-2.6.28/ubuntu/qc-usb/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_QC_USB) := quickcam.o + +quickcam-objs := qc-driver.o qc-hdcs.o qc-pb0100.o qc-vv6410.o qc-formats.o qc-mjpeg.o qc-memory.o --- linux-2.6.28.orig/ubuntu/qc-usb/qc-vv6410.c +++ linux-2.6.28/ubuntu/qc-usb/qc-vv6410.c @@ -0,0 +1,650 @@ +/* Start of file */ + +/* {{{ [fold] Comments */ +/* + * qce-ga, linux V4L driver for the QuickCam Express and Dexxa QuickCam + * + * vv6410.c - VV6410 Sensor Implementation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 "quickcam.h" + +#ifndef QCEGA_MODE +#define QCEGA_MODE 0 /* If the driver doesn't work for you, try changing this to "1" */ +#endif + +/* LSB bit of I2C address signifies write (0) or read (1) */ + +/* I2C Address */ +#define VV6410_ADDR (0x10<<1) + +/* {{{ [fold] I2C Registers */ +/* Status registers */ +#define VV6410_DEVICEH 0x00 /* Chip identification number including revision indicator */ +#define VV6410_DEVICEL 0x01 +#define VV6410_STATUS0 0x02 /* User can determine whether timed I2C data has been consumed by interrogating flag states */ +#define VV6410_LINECOUNTH 0x03 /* Current line counter value */ +#define VV6410_LINECOUNTL 0x04 +#define VV6410_XENDH 0x05 /* End x coordinate of image size */ +#define VV6410_XENDL 0x06 +#define VV6410_YENDH 0x07 /* End y coordinate of image size */ +#define VV6410_YENDL 0x08 +#define VV6410_DARKAVGH 0x09 /* This is the average pixel value returned from the dark line offset cancellation algorithm */ +#define VV6410_DARKAVGL 0x0A +#define VV6410_BLACKAVGH 0x0B /* This is the average pixel value returned from the black line offset cancellation algorithm */ +#define VV6410_BLACKAVGL 0x0C +#define VV6410_STATUS1 0x0D /* Flags to indicate whether the x or y image coordinates have been clipped */ + +/* Setup registers */ +#define VV6410_SETUP0 0x10 /* Low-power/sleep modes & video timing */ +#define VV6410_SETUP1 0x11 /* Various parameters */ +#define VV6410_SYNCVALUE 0x12 /* Contains pixel counter reset value used by external sync */ +#define VV6410_FGMODES 0x14 /* Frame grabbing modes (FST, LST and QCK) */ +#define VV6410_PINMAPPING 0x15 /* FST and QCK mapping modes. */ +#define VV6410_DATAFORMAT 0x16 /* Data resolution */ +#define VV6410_OPFORMAT 0x17 /* Output coding formats */ +#define VV6410_MODESELECT 0x18 /* Various mode select bits */ + +/* Exposure registers */ +#define VV6410_FINEH 0x20 /* Fine exposure. */ +#define VV6410_FINEL 0x21 +#define VV6410_COARSEH 0x22 /* Coarse exposure */ +#define VV6410_COARSEL 0x23 +#define VV6410_ANALOGGAIN 0x24 /* Analog gain setting */ +#define VV6410_CLKDIV 0x25 /* Clock division */ +#define VV6410_DARKOFFSETH 0x2C /* Dark line offset cancellation value */ +#define VV6410_DARKOFFSETL 0x2D +#define VV6410_DARKOFFSETSETUP 0x2E /* Dark line offset cancellation enable */ + +/* Colour registers (none on this camera!) */ + +/* Video timing registers */ +#define VV6410_LINELENGTHH 0x52 /* Line Length (Pixel Clocks) */ +#define VV6410_LINELENGTHL 0x53 +#define VV6410_XOFFSETH 0x57 /* X-co-ordinate of top left corner of region of interest (x-offset) */ +#define VV6410_XOFFSETL 0x58 +#define VV6410_YOFFSETH 0x59 /* Y-co-ordinate of top left corner of region of interest (y-offset) */ +#define VV6410_YOFFSETL 0x5A +#define VV6410_FIELDLENGTHH 0x61 /* Field length (Lines) */ +#define VV6410_FIELDLENGTHL 0x62 + +/* Text overlay registers (none on this camera!) */ + +/* I2C autoload registers (none on this camera!) */ + +/* System registers */ +#define VV6410_BLACKOFFSETH 0x70 /* Black offset cancellation default value */ +#define VV6410_BLACKOFFSETL 0x71 +#define VV6410_BLACKOFFSETSETUP 0x72 /* Black offset cancellation setup */ +#define VV6410_CR0 0x75 /* Analog Control Register 0 */ +#define VV6410_CR1 0x76 /* Analog Control Register 1 */ +#define VV6410_AS0 0x77 /* ADC Setup Register */ +#define VV6410_AT0 0x78 /* Analog Test Register */ +#define VV6410_AT1 0x79 /* Audio Amplifier Setup Register */ +/* }}} */ + +#define I2C_SET_CHECK(reg,val) if ((r = qc_i2c_set(qc,(reg),(val)))<0) goto fail +#define STV_SET_CHECK(reg,val) if ((r = qc_stv_set(qc,(reg),(val)))<0) goto fail +#define STV_SETW_CHECK(reg,val) if ((r = qc_stv_setw(qc,(reg),(val)))<0) goto fail +#define IS_850(qc) (GET_PRODUCTID(qc)==0x850) /* Is it QuickCam Web/Legocam? */ + +#if QCEGA_MODE +#warning "Using old compatible code (QCEGA_MODE=1)" +#warning "If this works but otherwise it doesn't work, let me know!" +static int mode = 0; +#define VV6410_CONTROL 0x10 // Setup0 +#define VV6410_GAIN 0x24 +/* {{{ [fold] vv6410_set_window() */ +static int vv6410_set_window(struct quickcam *qc, int x, int y,int width, int height) +{ + int r = 0; + + // x offset + x = MAX(1,x); + I2C_SET_CHECK(0x57,x >> 8); + I2C_SET_CHECK(0x58,x & 0xff); + + // y offset + y = MAX(1,y); + I2C_SET_CHECK(0x59,y >> 8); + I2C_SET_CHECK(0x5a,y & 0xff); + + // Set the real + if (qc->sensor_data.subsample) { + qc->sensor_data.width=180; + qc->sensor_data.height=148; + } else { + qc->sensor_data.width=356; + qc->sensor_data.height=292; + } + + // line length + if (qc->sensor_data.subsample) { + if (IS_850(qc)) + width=250; + else + width=360; /* 180 * 2 (CLK-DIV is 2) */ + } + else { + if (IS_850(qc)) + width=416; + else + width=712; /* 356 * 2 */ + } + + I2C_SET_CHECK(0x52, width >> 8); + I2C_SET_CHECK(0x53, width & 0xff); + + // field length (num lines) + if (qc->sensor_data.subsample) + height=160; /* nearest of 148 = 10 * 16 */ + else + height=320; // 304; /* nearest of 292 = 19 * 16 */ + + I2C_SET_CHECK(0x61,height >> 8); + I2C_SET_CHECK(0x62,height & 0xff); + + // usb_quickcam_i2c_add(&i2cbuff,0x25,0x02); + if ((r = qc_i2c_wait(qc))<0) goto fail; + + return 0; +fail: + return -ENAMETOOLONG; //some silly code just for testing +} +/* }}} */ +#endif + +/* {{{ [fold] vv6410_set_size: Set window size */ +static int vv6410_set_size(struct quickcam *qc, unsigned int width, unsigned int height) +{ + struct qc_sensor_data *sd = &qc->sensor_data; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("vv6410_set_size(qc=%p,width=%i,height=%i)",qc,width,height); + /* VV6410 appears to always give fixed 356*292 pixels */ + sd->width = sd->maxwidth; + sd->height = sd->maxheight; + return 0; +} +/* }}} */ +/* {{{ [fold] vv6410_start: Start grabbing */ +static int vv6410_start(struct quickcam *qc) +{ + struct qc_sensor_data *sd = &qc->sensor_data; + int r; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("vv6410_start(qc=%p)",qc); + if (PARANOID && !qc) { PDEBUG("qc==NULL"); return -EINVAL; } + I2C_SET_CHECK(VV6410_SETUP0, sd->subsample ? (BIT(7)|BIT(6)) : 0x00); + if (IS_850(qc)) qc_stv_set(qc, 0x1445, 1); /* Turn on LED */ + r = qc_i2c_wait(qc); +fail: return r; +} +/* }}} */ +/* {{{ [fold] vv6410_stop: Stop grabbing */ +static int vv6410_stop(struct quickcam *qc) +{ + static const int low_power_mode = 0; //1; + static const int sleep_mode = 1; + struct qc_sensor_data *sd = &qc->sensor_data; + unsigned char cmd; + int r; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("vv6410_stop(qc=%p)",qc); + if (IS_850(qc)) qc_stv_set(qc, 0x1445, 0); /* Turn off LED */ + cmd = (sleep_mode << 1) | low_power_mode; + if (sd->subsample) cmd |= BIT(7)|BIT(6); /* sub-sampled QCIF mode */ + I2C_SET_CHECK(VV6410_SETUP0, cmd); + r = qc_i2c_wait(qc); +fail: return r; +} +/* }}} */ +#if COMPRESS +struct stv_init { + const u8 *data; /* If NULL, only single value to write, stored in len */ + u16 start; + u8 len; +}; +#endif +/* {{{ [fold] vv6410_init: Initialise parameters for vv6410 sensor. */ +/* Just try to send the same commands as Windoze QuickCam soft */ +static int vv6410_init(struct quickcam *qc) +{ + struct qc_sensor_data *sd = &qc->sensor_data; + int r; + +#if COMPRESS + if (IS_850(qc)) { +/* {{{ [fold] Initialization with compression support */ + +/* {{{ [fold] [fold] stv_init[] */ + static const u8 x0540[] = { /* 0x0540 - 0x0551 */ + 0x97,0x0B,0x4C,0xFC,0x36,0x00,0x75,0x00,0x59,0x02,0x32,0x01,0x56,0xFD,0xEE,0xFF, + 0xB8,0x05 }; + static const u8 x0560[] = { /* 0x0560 - 0x0563 */ + 0x40,0xFF,0xBF,0xBF }; + static const u8 x1500[] = { /* 0x1500 - 0x150F */ + 0x0B,0xA7,0xB7,0x00,0x00,0x00,0x14,0x14,0x14,0x14,0x2B,0x02,0x2B,0x02,0x2B,0x02 }; + static const u8 x1520[] = { /* 0x1520 - 0x152A */ + 0x05,0x14,0x0F,0x0F,0x98,0x98,0x98,0x98,0x2D,0x00,0x01 }; + static const u8 x1530[] = { /* 0x1530 - 0x153B */ + 0x08,0x02,0x00,0x00,0x02,0x00,0x02,0x00,0x60,0x01,0x20,0x01 }; + static const u8 x1552[] = { /* 0x1552 - 0x1558 */ + 0x72,0x90,0x00,0xB0,0xF0,0x77,0x72 }; + static const u8 x1564[] = { /* 0x1564 - 0x1567 */ + 0x00,0xFF,0x0C,0x00 }; + static const u8 x1580[] = { /* 0x1580 - 0x158F */ + 0x02,0x40,0x01,0xF0,0x00,0xD1,0x01,0xAC,0x01,0x07,0x00,0x00,0x00,0x00,0x00,0x00 }; + static const u8 x1590[] = { /* 0x1590 - 0x15A5 */ + 0xA8,0x05,0x64,0x07,0x0F,0x03,0xD8,0x07,0xA6,0x06,0x71,0x04,0x8F,0x01,0xFF,0xFB, + 0xEC,0xE6,0xE0,0xD9,0xC4,0xB8 }; + static const u8 x15C1[] = { /* 0x15C1 - 0x15C2 */ + 0x4B, 0x02 }; /* Output word 0x024B=587 (ISO size) */ + static const struct stv_init stv_init[] = { + { NULL, 0x1620, 0x80 }, /* This reg is written twice. Some kind of reset? */ + { NULL, 0x1620, 0x00 }, + { x0540, 0x0540, SIZE(x0540) }, + { x0560, 0x0560, SIZE(x0560) }, + { NULL, 0x1423, 0x04 }, + { NULL, 0x1440, 0x00 }, + { NULL, 0x1443, 0x00 }, + { NULL, 0x1445, 0x01 }, + { x1500, 0x1500, SIZE(x1500) }, + { x1520, 0x1520, SIZE(x1520) }, + { x1530, 0x1530, SIZE(x1530) }, + { x1552, 0x1552, SIZE(x1552) }, + { x1564, 0x1564, SIZE(x1564) }, + { x1580, 0x1580, SIZE(x1580) }, + { x1590, 0x1590, SIZE(x1590) }, + { x15C1, 0x15C1, SIZE(x15C1) }, + { NULL, 0x15C3, 0x00 }, + { NULL, 0x15C9, 0x01 }, + { NULL, 0x1704, 0x00 }, + }; +/* }}} */ +/* {{{ [fold] vv_init[][2] */ + static const u8 vv_init[][2] = { + /* Setup registers */ + { VV6410_SETUP0, BIT(2) }, /* Soft reset */ + { VV6410_SETUP0, BIT(1)|BIT(0) }, /* 25 fps PAL (30 fps NTSC doesn't work!), sleep mode */ + { VV6410_SETUP1, BIT(6) }, /* Use unsuffled read-out mode */ + { VV6410_FGMODES, BIT(6)|BIT(4)|BIT(2)|BIT(0) }, /* All modes to 1 */ + { VV6410_PINMAPPING, 0x00 }, + { VV6410_DATAFORMAT, BIT(7)|BIT(0) }, /* Pre-clock generator divide off */ + { VV6410_OPFORMAT, BIT(3)|BIT(4) }, + /* Exposure registers */ + { VV6410_FINEH, 320 >> 8 }, /* Initial exposure */ + { VV6410_FINEL, 320 & 0xFF }, + { VV6410_COARSEH, 192 >> 8 }, + { VV6410_COARSEL, 192 & 0xFF }, + { VV6410_ANALOGGAIN, 0xF0 | 11 }, /* Gain to 11 */ + { VV6410_CLKDIV, 0x01 }, /* Pixel clock divisor 2 */ + /* Video timing registers */ + { VV6410_LINELENGTHH, (416-1) >> 8 }, /* Set line length (columns) to 417 */ + { VV6410_LINELENGTHL, (416-1) & 0xFF }, + { VV6410_FIELDLENGTHH, (320-1) >> 8 }, /* Set field length (rows) to 320 */ + { VV6410_FIELDLENGTHL, (320-1) & 0xFF }, + /* System registers */ + { VV6410_AS0, BIT(6)|BIT(4)|BIT(3)|BIT(2)|BIT(1) }, /* Enable voltage doubler */ + { VV6410_AT0, 0x00 }, + { VV6410_AT1, BIT(4)|BIT(0) }, /* Power up audio, differential */ + }; +/* }}} */ + + unsigned int cols = 416; + unsigned int rows = 320; + unsigned int x = 1; + unsigned int y = 1; + int i,j; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("vv6410_init(qc=%p)",qc); + if (PARANOID && !qc) { PDEBUG("qc==NULL"); return -EINVAL; } + + sd->width = 320; /* Default to compressed mode */ + sd->height = 240; + + for (i=0; isubsample ? 0x10 : 0x20); /* Scan rate */ + STV_SET_CHECK(0x1446,1); + STV_SETW_CHECK(0x15C1,600); /* ISO size, 0x380|orig:600 */ + STV_SET_CHECK(0x1680,0x14); /* X ctrl */ + } + + for (i=0; icompress) { + /* Disable compression */ + STV_SET_CHECK(0x1443, sd->subsample ? 0x00 : 0x10); /* Scan rate: Larger -> slower */ + STV_SETW_CHECK(0x15C1, 1023); /* ISO-Size */ + STV_SET_CHECK(0x15C3, 1); /* Y control */ + sd->width = 356; + sd->height = 292; + if (qc->settings.subsample) { + //FIXME:subsampling (still) doesn't work yet + cols=250; + rows=160; + sd->width = 180; + sd->height = 148; + I2C_SET_CHECK(VV6410_SETUP0, BIT(7)|BIT(6)|BIT(1)|BIT(0)); /* Subsampled timing mode */ + } + } + I2C_SET_CHECK(VV6410_XOFFSETH, x >> 8); + I2C_SET_CHECK(VV6410_XOFFSETL, x & 0xFF); + I2C_SET_CHECK(VV6410_YOFFSETH, y >> 8); + I2C_SET_CHECK(VV6410_YOFFSETL, y & 0xFF); + I2C_SET_CHECK(VV6410_LINELENGTHH, (cols-1) >> 8); + I2C_SET_CHECK(VV6410_LINELENGTHL, (cols-1) & 0xFF); + I2C_SET_CHECK(VV6410_FIELDLENGTHH, (rows-1) >> 8); + I2C_SET_CHECK(VV6410_FIELDLENGTHL, (rows-1) & 0xFF); + sd->maxwidth = sd->width; + sd->maxheight = sd->height; + return 0; +/* }}} */ + } else { +#endif +/* {{{ [fold] Initialization without compression support */ + if (sd->compress) return -EINVAL; + if (sd->subsample) { + sd->maxwidth = 180; + sd->maxheight = 148; + } else { + sd->maxwidth = 356; + sd->maxheight = 292; + } + + +#if QCEGA_MODE +{ +int line_length = mode?250:416;//415; + + if (mode) { + sd->subsample=1; // quater. + sd->width = 180; + sd->height = 148; + } else { + sd->subsample=0; + sd->width = 356; + sd->height = 292; + } + + STV_SET_CHECK(STV_REG23, 5); // was 5. + + + if (!IS_850(qc)) { + /* logitech quickcam web has 0x850 as idProduct */ + STV_SET_CHECK(0x1446, 1); + } + + + STV_SET_CHECK(STV_SCAN_RATE, 0x00); + + + STV_SET_CHECK(0x1423, 0x04); + + + STV_SET_CHECK(STV_REG00, 0x1b); // 0x0b + + + + I2C_SET_CHECK(VV6410_CONTROL,0x04); // reset to defaults + if ((r = qc_i2c_wait(qc))<0) goto fail; + + + + + // CIF or QCIF and sleep. + if (IS_850(qc)) { + I2C_SET_CHECK(VV6410_CONTROL,(mode?0xa2:0x02)); + } else { + I2C_SET_CHECK(VV6410_CONTROL,(mode?0xc2:0x02)); + } + + if ((r = qc_i2c_wait(qc))<0) goto fail; + + + + I2C_SET_CHECK(VV6410_GAIN,0xfb); + if ((r = qc_i2c_wait(qc))<0) goto fail; + + + + + + STV_SET_CHECK(STV_REG04, 0x07); + + + STV_SET_CHECK(STV_REG03, 0x45); + + + /* set window size */ + if ((r=vv6410_set_window(qc,0,0,48,64)) < 0) { + PRINTK(KERN_ERR, "vv6410_set_window failed"); + goto fail; + } + + + /* EXPERIMENTAL */ + /* + * line length default is 415 so it's the value we use to + * calculate values for registers 0x20-0x21 + * Ref. DS Pag. 67 + */ + I2C_SET_CHECK(0x20,mode? ((line_length-23)>>8):((line_length-51)>>8)); + + I2C_SET_CHECK(0x21,mode?((line_length-23)&0xff):((line_length-51)&0xff)); + + I2C_SET_CHECK(0x22,mode?0x00:0x01); + //usb_quickcam_i2c_add(&i2cbuff,0x23,mode?0x9e:0x3e); + I2C_SET_CHECK(0x23,mode?158:318&0xff); + I2C_SET_CHECK(0x24,0xfa); + // clock divisor. + I2C_SET_CHECK(0x25,0x01); + + if ((r = qc_i2c_wait(qc))<0) goto fail; + + + /* + if (isaweb(dev)) + { + //EXPERIMENTAL: dark/black pixel cancellation + usb_quickcam_i2c_add(&i2cbuff,0x3e,0x01); + usb_quickcam_i2c_add(&i2cbuff,0x72,0x01); + if (usb_quickcam_i2c_send(dev,&i2cbuff,VV6410_ADDR) < 0) { + printk(KERN_ERR "usb_control_msg dark/black pixel failed"); + goto error; + } + } + */ + STV_SET_CHECK(STV_REG01, 0xb7); + + STV_SET_CHECK(STV_REG02, 0xa7); + + + + // setup + I2C_SET_CHECK(0x11,0x18); // 0x18 or Jochen 0x40 + I2C_SET_CHECK(0x14,0x55); // was 0x55 + I2C_SET_CHECK(0x15,0x10); // 0x10 or Jochen:0x00 + I2C_SET_CHECK(0x16,0x81); // Pre clock dividor. + I2C_SET_CHECK(0x17,0x18); // they are reserved. + I2C_SET_CHECK(0x18,0x00); + I2C_SET_CHECK(0x77,0x5e); + I2C_SET_CHECK(0x78,0x04);// 0x04 or Jochen:0x00 + if (IS_850(qc)) { + I2C_SET_CHECK(0x79,0x11);//audio init + } + if ((r = qc_i2c_wait(qc))<0) goto fail; + + + + + STV_SETW_CHECK(STV_ISO_SIZE, IS_850(qc)?1023:600); // 0x380|orig:600 + + + + + STV_SET_CHECK(STV_Y_CTRL, 1); + + + STV_SET_CHECK(STV_SCAN_RATE, mode?0x00:0x10); + + + + if (!IS_850(qc)) { + /* logitech quickam web has 0x0850 as idProduct */ + STV_SET_CHECK(STV_X_CTRL, 0x14); + } +} + +#else + STV_SET_CHECK(0x0423,0x05); /* Unknown register, 0x04 or 0x05 */ + STV_SET_CHECK(0x1423,0x04); /* Unknown register, 0x04 or 0x05 */ + STV_SET_CHECK(0x1443,0x00); /* Scan rate */ + STV_SET_CHECK(0x1500,0x1B); /* 0x0B */ + STV_SET_CHECK(0x1501,0xB7); + STV_SET_CHECK(0x1502,0xA7); + STV_SET_CHECK(0x1503,0x45); + STV_SET_CHECK(0x1504,0x07); + STV_SET_CHECK(0x15C3,1); /* Y ctrl */ + if (IS_850(qc)) { + STV_SET_CHECK(0x1443, sd->subsample ? 0x20 : 0x10); /* Scan rate */ + STV_SETW_CHECK(0x15C1,1023); /* ISO size, 0x380|orig:600 */ + } else { + STV_SET_CHECK(0x1443, sd->subsample ? 0x10 : 0x20); /* Scan rate */ + STV_SET_CHECK(0x1446,1); + STV_SETW_CHECK(0x15C1,600); /* ISO size, 0x380|orig:600 */ + STV_SET_CHECK(0x1680,0x14); /* X ctrl */ + } + + I2C_SET_CHECK(0x10,0x04); /* Control register: reset to defaults */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + I2C_SET_CHECK(0x10,sd->subsample ? 0xC2 : 0x02);/* Control register: CIF or QCIF and sleep */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + I2C_SET_CHECK(0x11,0x18); /* 0x18 or Jochen 0x40 */ + I2C_SET_CHECK(0x14,0x55); + I2C_SET_CHECK(0x15,0x10); /* 0x10 or Jochen:0x00 */ + I2C_SET_CHECK(0x16,0x81); /* Pre clock dividor. */ + I2C_SET_CHECK(0x17,0x18); /* they are reserved. */ + I2C_SET_CHECK(0x18,0x00); + I2C_SET_CHECK(0x24,0xFB); /* Set gain value */ + I2C_SET_CHECK(0x25,0x01); /* Clock divisor value */ + I2C_SET_CHECK(0x77,0x5E); + I2C_SET_CHECK(0x78,0x04); /* 0x04 or Jochen:0x00 */ + if (IS_850(qc)) { + I2C_SET_CHECK(0x3E,0x01); /* EXPERIMENTAL: dark/black pixel cancellation */ + I2C_SET_CHECK(0x72,0x01); + } + + if ((r = qc_i2c_wait(qc))<0) goto fail; +#endif + + return 0; +/* }}} */ +#if COMPRESS + } +#endif + +fail: return r; +} +/* }}} */ +/* {{{ [fold] vv6410_set_exposure() */ +static int vv6410_set_exposure(struct quickcam *qc, unsigned int val) +{ + struct qc_sensor_data *sd = &qc->sensor_data; + static const unsigned int linelength = 415; /* For CIF */ + unsigned int fine; + unsigned int coarse; + int r; + + val = (val*val >> 14) + val/4; + if (sd->exposure==val) return 0; + sd->exposure = val; + fine = val % linelength; + coarse = val / linelength; + if (coarse>=512) coarse = 512; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("vv6410_set_exposure %d (%i,%i)",val,coarse,fine); + I2C_SET_CHECK(VV6410_FINEH, fine >> 8); + I2C_SET_CHECK(VV6410_FINEL, fine & 0xFF); + I2C_SET_CHECK(VV6410_COARSEH, coarse >> 8); + I2C_SET_CHECK(VV6410_COARSEL, coarse & 0xFF); +fail: return r; +} +/* }}} */ +/* {{{ [fold] vv6410_set_gains() */ +static int vv6410_set_gains(struct quickcam *qc, unsigned int hue, unsigned int sat, unsigned int val) +{ + static const int maxgain = 13; /* Absolute maximum is 14, recommended is 12 */ + struct qc_sensor_data *sd = &qc->sensor_data; + unsigned int gain; + int r; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("vv6410_set_gains %d %d %d", hue, sat, val); + gain = val / 256; + gain >>= 4; + if (gain > maxgain) gain = maxgain; + if (sd->rgain==gain) return 0; + sd->rgain = gain; + r = qc_i2c_set(qc, VV6410_ANALOGGAIN, 0xF0 | gain); + return r; +} +/* }}} */ +/* {{{ [fold] vv6410_set_levels() */ +static int vv6410_set_levels(struct quickcam *qc, unsigned int exp, unsigned int gain, unsigned int hue, unsigned int sat) +{ + int r; + if ((r = vv6410_set_exposure(qc, exp))<0) goto fail; + vv6410_set_gains(qc, hue, sat, gain); +fail: return r; +} +/* }}} */ + +/* {{{ [fold] struct qc_sensor qc_sensor_vv6410 */ +const struct qc_sensor qc_sensor_vv6410 = { + name: "VV6410", + manufacturer: "ST Microelectronics", + init: vv6410_init, + start: vv6410_start, + stop: vv6410_stop, + set_size: vv6410_set_size, + set_levels: vv6410_set_levels, + /* Exposure and gain control information */ + autoexposure: FALSE, + adapt_gainlow: 40000, + adapt_gainhigh: 65535, + /* Information needed to access the sensor via I2C */ + reg23: 5, + i2c_addr: VV6410_ADDR, + /* Identification information used for auto-detection */ + id_reg: VV6410_DEVICEH, + id: 0x19, + length_id: 1, +}; +/* }}} */ + +/* End of file */ --- linux-2.6.28.orig/ubuntu/qc-usb/qc-memory.c +++ linux-2.6.28/ubuntu/qc-usb/qc-memory.c @@ -0,0 +1,252 @@ +/* Start of file */ + +/* {{{ [fold] Comments */ +/* + * qce-ga, linux V4L driver for the QuickCam Express and Dexxa QuickCam + * + * memory.c - contains all needed memory management 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 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 + * + */ + +/* These routines have been derived from the ov511 driver, into which they + * were derived from the bttv driver. + */ +/* }}} */ +/* {{{ [fold] Includes */ +#include +#include + +#ifdef CONFIG_SMP +#define __SMP__ +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS) +#define MODVERSIONS +#endif +#ifdef MODVERSIONS +#include +#endif +#endif + +#include "qc-memory.h" +#include +#include /* Required on Alpha, from Bob McElrath */ +#include /* Required on Alpha */ +#include /* Required on Alpha */ +#include /* pmd_offset requires this on SuSE supplied kernels */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) +#include /* For proper mem_map_(un)reserve define, the compatibility define below might not work */ +#endif +/* }}} */ +/* {{{ [fold] Compatibility wrappers */ +#ifndef HAVE_VMA +#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,5,3) || (defined(RED_HAT_LINUX_KERNEL) && defined(pte_offset_map)) +#define HAVE_VMA 1 +#else +#define HAVE_VMA 0 +#endif +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) +#if HAVE_VMA +#warning "HAVE_VMA=1" +/* remap_page_range is still emulated in 2.6.10, in 2.6.11 it's completely removed */ +static inline int qc_remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot) { return remap_page_range(vma, from, pfn<=KERNEL_VERSION(2,5,3) || defined(pte_offset_map) +#define pte_offset(pmd,adr) pte_offset_map(pmd,adr) /* Emulation for a kernel using the new rmap-vm */ +#endif /* Fix by Michele Balistreri */ + +/* }}} */ + +/* {{{ [fold] kvirt_to_pa(): obtain physical address from virtual address obtained by vmalloc() */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +/* {{{ [fold] kvirt_to_pa(), 2.4.x and 2.6.x */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) +static struct page *vmalloc_to_page(void * vmalloc_addr); +#endif + +/* Here we want the physical address of the memory obtained by vmalloc(). + */ +static inline unsigned long kvirt_to_pa(unsigned long adr) +{ + unsigned long kva, ret; + + kva = (unsigned long) page_address(vmalloc_to_page((void *)adr)); + kva |= adr & (PAGE_SIZE-1); /* restore the offset */ + ret = __pa(kva); + return ret; +} +/* }}} */ +#else +/* {{{ [fold] kvirt_to_pa() for 2.2.x */ +#define page_address(x) (x | PAGE_OFFSET) /* Damn ugly hack from kcomp.h; replaces original page_address() that made different thing! */ + +/* Given PGD from the address space's page table, return the kernel + * virtual mapping of the physical memory mapped at ADR. + */ +static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr) +{ + unsigned long ret = 0UL; + pmd_t *pmd; + pte_t *ptep, pte; + + if (!pgd_none(*pgd)) { + pmd = pmd_offset(pgd, adr); + if (!pmd_none(*pmd)) { + ptep = pte_offset(pmd, adr); + pte = *ptep; + if (pte_present(pte)) { + ret = (unsigned long) page_address(pte_page(pte)); + ret |= (adr & (PAGE_SIZE - 1)); + } + } + } + + return ret; +} + +/* Here we want the physical address of the memory obtained by vmalloc(). + * This is used when initializing the contents of the + * area and marking the pages as reserved. + */ +static unsigned long kvirt_to_pa(unsigned long adr) +{ + unsigned long va, kva, ret; + + va = VMALLOC_VMADDR(adr); + kva = uvirt_to_kva(pgd_offset_k(va), va); + ret = __pa(kva); + return ret; +} +/* }}} */ +#endif +/* }}} */ +/* {{{ [fold] vmalloc_to_page(): obtain pointer to struct page from virtual address obtained by vmalloc() */ +#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,4,0) && LINUX_VERSION_CODE 0) { + SetPageReserved(vmalloc_to_page((void *)adr)); + adr += PAGE_SIZE; + size -= PAGE_SIZE; + } + + return mem; +} +/* }}} */ +/* {{{ [fold] qc_mm_rvfree(mem, size) */ +void qc_mm_rvfree(void *mem, unsigned long size) +{ + unsigned long adr; + + if (!mem) + return; + + adr = (unsigned long) mem; + while ((long) size > 0) { + ClearPageReserved(vmalloc_to_page((void *)adr)); + adr += PAGE_SIZE; + size -= PAGE_SIZE; + } + vfree(mem); +} +/* }}} */ +/* {{{ [fold] qc_mm_remap(vma, src, src_size, dst, dst_size) */ +int qc_mm_remap(struct vm_area_struct *vma, void *src, unsigned long src_size, const void *dst, unsigned long dst_size) +{ + unsigned long start = (unsigned long)dst; + unsigned long size = dst_size; + unsigned long physaddr, pos; + + pos = (unsigned long)src; + while ((long)size > 0) { + physaddr = kvirt_to_pa(pos); +#if 1 + if ((physaddr & ~PAGE_MASK)!=0) { + printk(KERN_CRIT "qc_mm_remap: physaddr=%08X not page aligned!\n", (int)physaddr); + return -EIO; + } +#endif + if (remap_pfn_range(vma, start, physaddr>>PAGE_SHIFT, PAGE_SIZE, PAGE_SHARED)) + return -EAGAIN; + start += PAGE_SIZE; + pos += PAGE_SIZE; + size -= PAGE_SIZE; + } + return 0; +} +/* }}} */ + +/* End of file */ --- linux-2.6.28.orig/ubuntu/qc-usb/BOM +++ linux-2.6.28/ubuntu/qc-usb/BOM @@ -0,0 +1,4 @@ +Downloaded from: http://sourceforge.net/project/showfiles.php?group_id=12924 +Current Version: 0.6.6 + +Took a bit of forward porting. Upstream project seems dead anyway. --- linux-2.6.28.orig/ubuntu/tlsup/tlsup_hotkeys.c +++ linux-2.6.28/ubuntu/tlsup/tlsup_hotkeys.c @@ -0,0 +1,238 @@ +/* Toshiba Laptop Support -- tlsup_hotkeys.c + * + * Hotkeys input support for T.L.S. + * + * Copyright 2008 Daniel Silverstone + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; specifically version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You 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. + * + * + * Credits: + * Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse + * engineering the Windows drivers + * Rob Miller - TV out and hotkeys help + * John Belmonte - The toshiba_acpi driver maintainance for some time. + */ + +#include +#include +#include +#include +#include +#include + +#include "tlsup.h" + +/* HCI registers */ +#define HCI_SYSTEM_EVENT 0x0016 + +/* Value manipulation */ + +/* Module stuff */ +static int hotkeys_checks_per_second = 4; +module_param(hotkeys_checks_per_second, uint, 0400); +MODULE_PARM_DESC(hotkeys_checks_per_second, "The number of times per second that the kernel will poll the HCI for hotkey events."); + +/* Keycode system */ + +struct key_entry { + u8 fncode; + u16 keycode; +}; + +static struct key_entry tlsup_hotkey_map[] = { + {2, KEY_FN_1}, + {0, 0} +}; + +static struct key_entry *tlsup_get_entry_by_scancode(int code) +{ + struct key_entry *key; + + for (key = tlsup_hotkey_map; key->fncode != 0; key++) { + if (key->fncode == code) + return key; + } + + return NULL; +} + +static struct key_entry *tlsup_get_entry_by_keycode(int code) +{ + struct key_entry *key; + + for (key = tlsup_hotkey_map; key->fncode != 0; key++) { + if (key->keycode == code) + return key; + } + + return NULL; +} + +static int tlsup_get_keycode(struct input_dev *dev, int scancode, int *keycode) +{ + struct key_entry *key = tlsup_get_entry_by_scancode(scancode); + + if (key != NULL) { + *keycode = key->keycode; + return 0; + } + + return -EINVAL; +} + +static int tlsup_set_keycode(struct input_dev *dev, int scancode, int keycode) +{ + struct key_entry *key = tlsup_get_entry_by_scancode(scancode); + int old_keycode; + + if (keycode < 0 || keycode > KEY_MAX) + return -EINVAL; + + if (key != NULL) { + old_keycode = key->keycode; + key->keycode = keycode; + set_bit(keycode, dev->keybit); + if (tlsup_get_entry_by_keycode(old_keycode) == NULL) + clear_bit(old_keycode, dev->keybit); + return 0; + } + + return -EINVAL; +} + +/* Hotkey system */ + +static struct input_polled_dev *tlsup_polled_dev = NULL; + +static int tlsup_read_hotkey_event(void) +{ + u32 value, hci_result; + if (tlsup_hci_read_1_reg(HCI_SYSTEM_EVENT, &value, &hci_result)) + return -EFAULT; + + if (hci_result == HCI_EMPTY) { + /* better luck next time */ + return 0; + } else if (hci_result == HCI_NOT_SUPPORTED) { + /* This is a workaround for an unresolved issue on + * some machines where system events sporadically + * become disabled. */ + tlsup_hci_write_1_reg(HCI_SYSTEM_EVENT, 1, &hci_result); + tlsup_info("Had to re-enable hotkeys.\n"); + return 0; + } else if (hci_result == HCI_SUCCESS) { + /* Process key */ + if (value == 0x0100) { + /* Fn+ */ + return 0; + } else { + return value; + } + } else { + /* Unknown result */ + return -EFAULT; + } + /* Not reached */ + BUG(); +} + +static void tlsup_polled_dev_poll(struct input_polled_dev *dev) +{ + int scancode = tlsup_read_hotkey_event(); + struct key_entry *key; + + if (scancode <= 0) + return; + + key = tlsup_get_entry_by_scancode(scancode & 0x7F); + + if (key != NULL) { + input_report_key(dev->input, key->keycode, + !(scancode & 0x80)); + input_sync(dev->input); + } + +} + +/* Registration functions */ + +int tlsup_register_hotkeys(void) +{ + int ret; + struct input_dev *input; + struct key_entry *key; + + /* Swallow what's there already */ + while ((ret = tlsup_read_hotkey_event()) > 0); + + if (ret < 0) + return -EFAULT; + + + + /* Present and results are sane, register the backlight driver. */ + tlsup_polled_dev = input_allocate_polled_device(); + if (tlsup_polled_dev == NULL) { + tlsup_err("Could not allocate polled device for hotkeys\n"); + return -ENOMEM; + } + + tlsup_polled_dev->private = kmalloc(sizeof(tlsup_hotkey_map), GFP_KERNEL); + + tlsup_polled_dev->poll = tlsup_polled_dev_poll; + tlsup_polled_dev->poll_interval = 1000 / hotkeys_checks_per_second; + + /* id name phys bits */ + + input = tlsup_polled_dev->input; + + input->id.bustype = BUS_HOST; + input->name = "tlsup: Toshiba Fn Hotkeys"; + input->phys = "toshiba/hotkeys0"; + + input->keycode = tlsup_polled_dev->private; + input->keycodemax = ARRAY_SIZE(tlsup_hotkey_map); + input->keycodesize = sizeof(unsigned short); + + input->getkeycode = tlsup_get_keycode; + input->setkeycode = tlsup_set_keycode; + + set_bit(EV_KEY, input->evbit); + for (key = tlsup_hotkey_map; key->fncode != 0; key++) + set_bit(key->keycode, input->keybit); + clear_bit(KEY_RESERVED, input->keybit); + + if ((ret = input_register_polled_device(tlsup_polled_dev)) < 0) { + input_free_polled_device(tlsup_polled_dev); + tlsup_err("Could not register polled device for hotkeys\n"); + tlsup_polled_dev = NULL; + return ret; + } + + tlsup_info("Hotkeys polled every %dms.\n", 1000 / hotkeys_checks_per_second); + + return 1; +} + +void tlsup_deregister_hotkeys(void) +{ + if (tlsup_polled_dev != NULL) { + input_unregister_polled_device(tlsup_polled_dev); + input_free_polled_device(tlsup_polled_dev); + tlsup_polled_dev = NULL; + } +} --- linux-2.6.28.orig/ubuntu/tlsup/tlsup.h +++ linux-2.6.28/ubuntu/tlsup/tlsup.h @@ -0,0 +1,44 @@ +/* Toshiba Laptop Support -- tlsup.h + * + * General top level definitions etc for T.L.S. + * + * Copyright 2008 Daniel Silverstone + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; specifically version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You 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. + * + * + * Credits: + * Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse + * engineering the Windows drivers + * Rob Miller - TV out and hotkeys help + * John Belmonte - The toshiba_acpi driver maintainance for some time. + */ + +#ifndef TLSUP_H +#define TLSUP_H + +#define MODULE_LOGPREFIX "tlsup: " + +#define tlsup_info(X...) printk(KERN_INFO MODULE_LOGPREFIX X) +#define tlsup_err(X...) printk(KERN_ERR MODULE_LOGPREFIX X) +#define tlsup_notice(X...) printk(KERN_NOTICE MODULE_LOGPREFIX X) + +#include "tlsup_acpi.h" +#include "tlsup_backlight.h" +#include "tlsup_hotkeys.h" +#include "tlsup_radios.h" + +#endif /* TLSUP_H */ --- linux-2.6.28.orig/ubuntu/tlsup/Kconfig +++ linux-2.6.28/ubuntu/tlsup/Kconfig @@ -0,0 +1,4 @@ +config TLSUP + tristate "Toshiba ACPI laptop driver" + depends on ACPI && X86 + default m --- linux-2.6.28.orig/ubuntu/tlsup/tlsup_backlight.h +++ linux-2.6.28/ubuntu/tlsup/tlsup_backlight.h @@ -0,0 +1,44 @@ +/* Toshiba Laptop Support -- tlsup_backlight.h + * + * LCD Backlight support for T.L.S. + * + * Copyright 2008 Daniel Silverstone + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; specifically version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You 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. + * + * + * Credits: + * Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse + * engineering the Windows drivers + * Rob Miller - TV out and hotkeys help + * John Belmonte - The toshiba_acpi driver maintainance for some time. + */ + +#ifndef TLSUP_BACKLIGHT_H +#define TLSUP_BACKLIGHT_H + +/* Look for the LCD backlight support and if present, register a backlight + * class device to manage it. + * + * Returns -errno on error, 0 on success (but no registration) or 1 if + * a backlight was registered. + */ +extern int tlsup_register_backlight(void); + +/* Remove the registration of the backlight. */ +extern void tlsup_deregister_backlight(void); + +#endif /* TLSUP_BACKLIGHT_H */ --- linux-2.6.28.orig/ubuntu/tlsup/tlsup_acpi.h +++ linux-2.6.28/ubuntu/tlsup/tlsup_acpi.h @@ -0,0 +1,81 @@ +/* Toshiba Laptop Support -- tlsup_acpi.h + * + * ACPI support for T.L.S. + * + * Copyright 2008 Daniel Silverstone + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; specifically version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You 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. + * + * + * Credits: + * Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse + * engineering the Windows drivers + * Rob Miller - TV out and hotkeys help + * John Belmonte - The toshiba_acpi driver maintainance for some time. + */ + +#ifndef TLSUP_ACPI_H +#define TLSUP_ACPI_H + +/* Detect the toshiba ACPI support and prepare the HCI. + * Returns zero on success, -errno on failure. + */ +extern int tlsup_acpi_detect(void); + +/* Report the details of the chosen/found ACPI interface to the kernel + * log + */ +extern void tlsup_acpi_report(void); + +/* Toshiba HCI */ + +#define HCI_SUCCESS 0x0000 +#define HCI_FAILURE 0x1000 +#define HCI_NOT_SUPPORTED 0x8000 +#define HCI_EMPTY 0x8c00 + +/* perform an HCI read operation, returning one u32 value and the + * HCI status. + * + * The function itself returns 0 on success, -errno on failure. + */ +extern int tlsup_hci_read_1_reg(u32 reg, u32 *result, u32 *hci_status); + +/* perform an HCI write operation with one u32 value and returning the + * HCI status. + * + * The function itself returns 0 on success, -errno on failure. + */ +extern int tlsup_hci_write_1_reg(u32 reg, u32 value, u32 *hci_status); + +/* perform an HCI read operation, returning two u32 values and the HCI + * status. + * + * The two values are passed to the call, so zero them if you don't + * want that. + * + * The function itself returns 0 on success, -errno on failure. + */ +extern int tlsup_hci_read_2_reg(u32 reg, u32 *result1, u32 *result2, u32 *hci_status); + +/* perform an HCI write operation with two u32 values and returning + * the HCI status. + * + * The function itself returns 0 on success, -errno on failure. + */ +extern int tlsup_hci_write_2_reg(u32 reg, u32 value1, u32 value2, u32 *hci_status); + +#endif /* TLSUP_ACPI_H */ --- linux-2.6.28.orig/ubuntu/tlsup/tlsup_acpi.c +++ linux-2.6.28/ubuntu/tlsup/tlsup_acpi.c @@ -0,0 +1,162 @@ +/* Toshiba Laptop Support -- tlsup_acpi.c + * + * ACPI support for T.L.S. + * + * Copyright 2008 Daniel Silverstone + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; specifically version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You 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. + * + * + * Credits: + * Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse + * engineering the Windows drivers + * Rob Miller - TV out and hotkeys help + * John Belmonte - The toshiba_acpi driver maintainance for some time. + */ + +#include +#include +#include +#include + +#include + +#include "tlsup.h" + +/* Toshibas use one of two ACPI method named typically. + * + * The one we detect goes in here. + */ +static const char *hci_method = NULL; + +#define HCI_METHOD_1 "\\_SB_.VALD.GHCI" +#define HCI_METHOD_2 "\\_SB_.VALZ.GHCI" + +/* Check if the provided method name is a valid ACPI method for + * the machine. + * + * Return 0 if it is not valid, 1 if it is. + */ +static int is_valid_acpi_path(const char *method_name) +{ + acpi_handle handle; + acpi_status status; + + status = acpi_get_handle(NULL, (char *)method_name, &handle); + return !ACPI_FAILURE(status); +} + + +/* Detect the toshiba ACPI support and prepare the HCI. + * Returns zero on success, -errno on failure. + */ +int tlsup_acpi_detect(void) +{ + if (acpi_disabled) + return -ENODEV; + + if (is_valid_acpi_path(HCI_METHOD_1)) + hci_method = HCI_METHOD_1; + else if (is_valid_acpi_path(HCI_METHOD_2)) + hci_method = HCI_METHOD_2; + else + return -ENODEV; + + return 0; +} + +void tlsup_acpi_report(void) +{ + tlsup_info(" HCI method: %s\n", hci_method); +} + +/* Toshiba HCI IO */ + +#define HCI_WORDS (6) + +/* operations */ +#define HCI_SET 0xff00 +#define HCI_GET 0xfe00 + +static acpi_status tlsup_hci_raw_io(const u32 input[HCI_WORDS], u32 output[HCI_WORDS]) +{ + struct acpi_object_list params; + union acpi_object in_objs[HCI_WORDS]; + struct acpi_buffer results; + union acpi_object out_objs[HCI_WORDS + 1]; + acpi_status status; + int i; + + params.count = HCI_WORDS; + params.pointer = in_objs; + for (i = 0; i < HCI_WORDS; ++i) { + in_objs[i].type = ACPI_TYPE_INTEGER; + in_objs[i].integer.value = input[i]; + } + + results.length = sizeof(out_objs); + results.pointer = out_objs; + + status = acpi_evaluate_object(NULL, (char *)hci_method, ¶ms, + &results); + if ((status == AE_OK) && (out_objs->package.count <= HCI_WORDS)) { + for (i = 0; i < out_objs->package.count; ++i) { + output[i] = out_objs->package.elements[i].integer.value; + } + } + + return status; +} + +int tlsup_hci_read_1_reg(u32 reg, u32 *result, u32 *hci_status) +{ + u32 hci_input[HCI_WORDS] = { HCI_GET, reg, 0, 0, 0, 0 }; + u32 hci_output[HCI_WORDS]; + acpi_status status = tlsup_hci_raw_io(hci_input, hci_output); + *result = hci_output[2]; + *hci_status = (status == AE_OK) ? hci_output[0] : HCI_FAILURE; + return (status == AE_OK) ? 0 : -EIO; +} + +int tlsup_hci_write_1_reg(u32 reg, u32 value, u32 *hci_status) +{ + u32 hci_input[HCI_WORDS] = { HCI_SET, reg, value, 0, 0, 0 }; + u32 hci_output[HCI_WORDS]; + acpi_status status = tlsup_hci_raw_io(hci_input, hci_output); + *hci_status = (status == AE_OK) ? hci_output[0] : HCI_FAILURE; + return (status == AE_OK) ? 0 : -EIO; +} + +int tlsup_hci_read_2_reg(u32 reg, u32 *result1, u32 *result2, u32 *hci_status) +{ + u32 hci_input[HCI_WORDS] = { HCI_GET, reg, *result1, *result2, 0, 0 }; + u32 hci_output[HCI_WORDS]; + acpi_status status = tlsup_hci_raw_io(hci_input, hci_output); + *result1 = hci_output[2]; + *result2 = hci_output[3]; + *hci_status = (status == AE_OK) ? hci_output[0] : HCI_FAILURE; + return (status == AE_OK) ? 0 : -EIO; +} + +int tlsup_hci_write_2_reg(u32 reg, u32 value1, u32 value2, u32 *hci_status) +{ + u32 hci_input[HCI_WORDS] = { HCI_SET, reg, value1, value2, 0, 0 }; + u32 hci_output[HCI_WORDS]; + acpi_status status = tlsup_hci_raw_io(hci_input, hci_output); + *hci_status = (status == AE_OK) ? hci_output[0] : HCI_FAILURE; + return (status == AE_OK) ? 0 : -EIO; +} + --- linux-2.6.28.orig/ubuntu/tlsup/tlsup_radios.h +++ linux-2.6.28/ubuntu/tlsup/tlsup_radios.h @@ -0,0 +1,45 @@ +/* Toshiba Laptop Support -- tlsup_radios.h + * + * Radio kill-switch support for T.L.S. + * + * Copyright 2008 Daniel Silverstone + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; specifically version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You 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. + * + * + * Credits: + * Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse + * engineering the Windows drivers + * Rob Miller - TV out and hotkeys help + * John Belmonte - The toshiba_acpi driver maintainance for some time. + */ + +#ifndef TLSUP_RADIOS_H +#define TLSUP_RADIOS_H + +/* Look for the radio kill switch support and if present, register + * rfkill devices to manage them. This supports wifi, bluetooth and + * hsdpa modem. + * + * Returns -errno on error, 0 on success (but no registration) or the + * number of rfkills registered. + */ +extern int tlsup_register_radios(void); + +/* Remove the registration of the radios. */ +extern void tlsup_deregister_radios(void); + +#endif /* TLSUP_RADIOS_H */ --- linux-2.6.28.orig/ubuntu/tlsup/Makefile +++ linux-2.6.28/ubuntu/tlsup/Makefile @@ -0,0 +1,6 @@ +TLSUP_VERSION := 0.10 +EXTRA_CFLAGS += '-DTLSUP_VERSION="$(TLSUP_VERSION)"' + +obj-$(CONFIG_TLSUP) := tlsup.o + +tlsup-objs := tlsup_mod.o tlsup_acpi.o tlsup_backlight.o tlsup_hotkeys.o tlsup_radios.o --- linux-2.6.28.orig/ubuntu/tlsup/tlsup_hotkeys.h +++ linux-2.6.28/ubuntu/tlsup/tlsup_hotkeys.h @@ -0,0 +1,45 @@ +/* Toshiba Laptop Support -- tlsup_hotkeys.h + * + * Hotkeys input support for T.L.S. + * + * Copyright 2008 Daniel Silverstone + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; specifically version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You 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. + * + * + * Credits: + * Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse + * engineering the Windows drivers + * Rob Miller - TV out and hotkeys help + * John Belmonte - The toshiba_acpi driver maintainance for some time. + */ + +#ifndef TLSUP_HOTKEYS_H +#define TLSUP_HOTKEYS_H + +/* Look for the hotkey support in the HCI and if found, register with + * input-polldev to get an input device to provide events to userland + * with. + * + * Returns -errno on error, 0 on success (but no registration) or 1 if + * an input device was registered. + */ +extern int tlsup_register_hotkeys(void); + +/* Remove the registration of the hotkeys input device. */ +extern void tlsup_deregister_hotkeys(void); + +#endif /* TLSUP_BACKLIGHT_H */ --- linux-2.6.28.orig/ubuntu/tlsup/tlsup_backlight.c +++ linux-2.6.28/ubuntu/tlsup/tlsup_backlight.c @@ -0,0 +1,115 @@ +/* Toshiba Laptop Support -- tlsup_backlight.c + * + * LCD Backlight support for T.L.S. + * + * Copyright 2008 Daniel Silverstone + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; specifically version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You 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. + * + * + * Credits: + * Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse + * engineering the Windows drivers + * Rob Miller - TV out and hotkeys help + * John Belmonte - The toshiba_acpi driver maintainance for some time. + */ + +#include +#include +#include +#include +#include +#include + +#include "tlsup.h" + +/* HCI registers */ +#define HCI_REG_LCD_BRIGHTNESS 0x002a + +/* Value manipulation */ +#define HCI_LCD_BRIGHTNESS_BITS 3 +#define HCI_LCD_BRIGHTNESS_SHIFT (16-HCI_LCD_BRIGHTNESS_BITS) +#define HCI_LCD_BRIGHTNESS_LEVELS (1 << HCI_LCD_BRIGHTNESS_BITS) + + +/* Backlight driver */ +static struct backlight_device *tlsup_backlight_device = NULL; + +static int tlsup_read_brightness(struct backlight_device *bd) +{ + u32 hci_result; + u32 value; + + if (tlsup_hci_read_1_reg(HCI_REG_LCD_BRIGHTNESS, &value, &hci_result)) + return -EFAULT; + + if (hci_result != HCI_SUCCESS) + return -EFAULT; + + return (value >> HCI_LCD_BRIGHTNESS_SHIFT); +} + +static int tlsup_set_brightness(struct backlight_device *bd) +{ + u32 hci_result; + u32 value = bd->props.brightness << HCI_LCD_BRIGHTNESS_SHIFT; + + if (tlsup_hci_write_1_reg(HCI_REG_LCD_BRIGHTNESS, value, &hci_result)) + return -EFAULT; + + if (hci_result != HCI_SUCCESS) + return -EFAULT; + + return 0; +} + +static struct backlight_ops tlsup_backlight_data = { + .get_brightness = tlsup_read_brightness, + .update_status = tlsup_set_brightness, +}; + +/* Registration functions */ + +int tlsup_register_backlight(void) +{ + u32 hci_result, ignored; + if (tlsup_hci_read_1_reg(HCI_REG_LCD_BRIGHTNESS, &ignored, &hci_result)) + return -EFAULT; + if (hci_result != HCI_SUCCESS) + return 0; + /* Present and results are sane, register the backlight driver. */ + tlsup_backlight_device = backlight_device_register("toshiba", + NULL, + NULL, + &tlsup_backlight_data); + + if (IS_ERR(tlsup_backlight_device)) { + int ret = PTR_ERR(tlsup_backlight_device); + tlsup_err("Could not register backlight device\n"); + tlsup_backlight_device = NULL; + return ret; + } + + tlsup_backlight_device->props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; + + return 1; +} + +void tlsup_deregister_backlight(void) +{ + if (tlsup_backlight_device) + backlight_device_unregister(tlsup_backlight_device); +} --- linux-2.6.28.orig/ubuntu/tlsup/tlsup_mod.c +++ linux-2.6.28/ubuntu/tlsup/tlsup_mod.c @@ -0,0 +1,87 @@ +/* Toshiba Laptop Support -- tlsup_mod.c + * + * Aggregation and module structural support for T.L.S. + * + * Copyright 2008 Daniel Silverstone + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; specifically version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You 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. + * + * + * Credits: + * Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse + * engineering the Windows drivers + * Rob Miller - TV out and hotkeys help + * John Belmonte - The toshiba_acpi driver maintainance for some time. + */ + +#include +#include +#include +#include + +#include "tlsup.h" + +MODULE_AUTHOR("Daniel Silverstone"); +MODULE_DESCRIPTION("Toshiba Laptop Support Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_VERSION(TLSUP_VERSION); + +/* The following ACPI devices tend to be exported by toshiba laptops */ +MODULE_ALIAS("acpi:TOS6200"); +MODULE_ALIAS("acpi:TOS6207"); +MODULE_ALIAS("acpi:TOS6208"); + +static void toshiba_laptop_support_exit(void) +{ + tlsup_deregister_radios(); + tlsup_deregister_hotkeys(); + tlsup_deregister_backlight(); +} + +static int __init toshiba_laptop_support_init(void) +{ + int ret; + + if ((ret = tlsup_acpi_detect()) < 0) + return ret; + + tlsup_info("Toshiba Laptop Support version %s initialising...\n", + TLSUP_VERSION); + + tlsup_acpi_report(); + + if ((ret = tlsup_register_backlight()) < 0) + return ret; + + if ((ret = tlsup_register_hotkeys()) < 0) { + tlsup_deregister_backlight(); + return ret; + } + + if ((ret = tlsup_register_radios()) < 0) { + tlsup_deregister_hotkeys(); + tlsup_deregister_backlight(); + return ret; + } + + tlsup_info("Toshiba Laptop Support version %s loaded.\n", + TLSUP_VERSION); + + return 0; +} + +module_init(toshiba_laptop_support_init); +module_exit(toshiba_laptop_support_exit); --- linux-2.6.28.orig/ubuntu/tlsup/BOM +++ linux-2.6.28/ubuntu/tlsup/BOM @@ -0,0 +1,4 @@ +Downloaded from: http://bzr.digital-scurf.org/trees/dsilvers/toshiba-laptop-support/ +Current Version: Mon, 11 Aug 2008 13:07:54 -0400 +Comments: Supercedes toshiba and toshiba_acpi drivers. + --- linux-2.6.28.orig/ubuntu/tlsup/tlsup_radios.c +++ linux-2.6.28/ubuntu/tlsup/tlsup_radios.c @@ -0,0 +1,334 @@ +/* Toshiba Laptop Support -- tlsup_radios.c + * + * Radio kill switch support for T.L.S. + * + * Copyright 2008 Daniel Silverstone + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; specifically version 2 + * of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You 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. + * + * + * Credits: + * Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse + * engineering the Windows drivers + * Rob Miller - TV out and hotkeys help + * John Belmonte - The toshiba_acpi driver maintainance for some time. + */ + +#include +#include +#include +#include +#include +#include + +#include "tlsup.h" + +/* Module stuff */ +static int radio_powerdown_time = 100; +static int powerup_settle_time = 200; + +module_param(radio_powerdown_time, uint, 0400); +MODULE_PARM_DESC(radio_powerdown_time, "The number of milliseconds between powering off a radio and the device power."); +module_param(powerup_settle_time, uint, 0400); +MODULE_PARM_DESC(powerup_settle_time, "The number of milliseconds between powering on a device and applying radio power."); + +/* HCI registers */ +#define HCI_WIRELESS 0x0056 + +/* Value manipulation */ +#define HCI_WIRELESS_PRESENT 0x0000 +#define HCI_WIRELESS_STATUS 0x0001 +#define HCI_WIRELESS_GLOBAL_RADIO_SWITCH 0x0001 +#define HCI_WIRELESS_3GHSDPA_POWER 0x4000 +#define HCI_WIRELESS_3GHSDPA_RADIO 0x2000 +#define HCI_WIRELESS_BLUETOOTH_POWER 0x0040 +#define HCI_WIRELESS_BLUETOOTH_RADIO 0x0080 +#define HCI_WIRELESS_WLAN_RADIO 0x0200 + +/* Radio manipulation functions */ + +static u32 tlsup_radios_present = 0; + +static int tlsup_test_radio_presence(u32 this_switch) +{ + u32 swvalue; + u32 swaddr; + u32 hci_result; + u32 current_status; + + swvalue = 0; + swaddr = HCI_WIRELESS_STATUS; + + if (tlsup_hci_read_2_reg(HCI_WIRELESS, &swvalue, &swaddr, &hci_result)) + return 0; + if (hci_result != HCI_SUCCESS) + return 0; + + current_status = (swvalue & this_switch) ? 1 : 0; + + /* Attempt to invert the current state */ + + swvalue = !current_status; + swaddr = this_switch; + if (tlsup_hci_write_2_reg(HCI_WIRELESS, swvalue, swaddr, &hci_result)) + return 0; + if (hci_result != HCI_SUCCESS) + return 0; + + /* Read back the allegedly inverted switch status */ + swvalue = 0; + swaddr = HCI_WIRELESS_STATUS; + + if (tlsup_hci_read_2_reg(HCI_WIRELESS, &swvalue, &swaddr, &hci_result)) + return 0; + if (hci_result != HCI_SUCCESS) + return 0; + + if (((swvalue & this_switch) ? 1 : 0) != !current_status) + /* Failed to invert */ + return 0; + + /* inversion successful, attempt to restore previous value */ + + swvalue = current_status; + swaddr = this_switch; + + if (tlsup_hci_write_2_reg(HCI_WIRELESS, swvalue, swaddr, &hci_result)) + return 0; + if (hci_result != HCI_SUCCESS) + return 0; + + /* verify restoration of value */ + + swvalue = 0; + swaddr = HCI_WIRELESS_STATUS; + + if (tlsup_hci_read_2_reg(HCI_WIRELESS, &swvalue, &swaddr, &hci_result)) + return 0; + if (hci_result != HCI_SUCCESS) + return 0; + + if (((swvalue & this_switch) ? 1 : 0) != current_status) + /* Failed to restore */ + return 0; + + /* Restoration successful */ + + tlsup_radios_present |= this_switch; + return 1; +} + +static enum rfkill_state tlsup_read_switch_state(u32 this_switch) +{ + u32 swvalue = 0; + u32 swaddr = HCI_WIRELESS_STATUS; + u32 hci_result; + + if (tlsup_hci_read_2_reg(HCI_WIRELESS, &swvalue, &swaddr, &hci_result)) + return 0; + if (hci_result != HCI_SUCCESS) + return 0; + + return (swvalue & this_switch) ? RFKILL_STATE_ON : RFKILL_STATE_OFF; +} + +static void tlsup_set_switch_state(u32 this_switch, enum rfkill_state state) +{ + u32 swvalue = state; + u32 swaddr = this_switch; + u32 hci_result; + + if (tlsup_hci_write_2_reg(HCI_WIRELESS, swvalue, swaddr, &hci_result)) { + tlsup_err("Error setting switch state\n"); + } + if (hci_result != HCI_SUCCESS) { + tlsup_err("Error setting switch state\n"); + } +} + +/* Radio rfkill driver */ + +struct tlsup_radio_power_control { + u32 power_reg; + u32 radio_reg; +}; + +static int tlsup_radio_switch_set(void *data, enum rfkill_state state) +{ + struct tlsup_radio_power_control *rpc = (struct tlsup_radio_power_control *)data; + + if (state == RFKILL_STATE_OFF) { + if (rpc->radio_reg) { + tlsup_set_switch_state(rpc->radio_reg, RFKILL_STATE_OFF); + msleep(radio_powerdown_time); + } + + if (rpc->power_reg) + tlsup_set_switch_state(rpc->power_reg, RFKILL_STATE_OFF); + } else { + if (rpc->power_reg) { + tlsup_set_switch_state(rpc->power_reg, RFKILL_STATE_ON); + msleep(powerup_settle_time); + } + if (rpc->radio_reg) + tlsup_set_switch_state(rpc->radio_reg, RFKILL_STATE_ON); + } + + return 0; +} + +static struct rfkill *hsdpa_rfkill_dev = NULL; +static struct rfkill *bluetooth_rfkill_dev = NULL; +static struct rfkill *wlan_rfkill_dev = NULL; + +static struct rfkill *tlsup_register_rfkill(const char *name, enum rfkill_type rft, + u32 optional_power, + u32 optional_radio) +{ + struct tlsup_radio_power_control *rpc; + struct rfkill *ret; + enum rfkill_state curstate = RFKILL_STATE_OFF; + + ret = rfkill_allocate(NULL, rft); + + if (ret == NULL) + return NULL; + + rpc = kmalloc(sizeof(struct tlsup_radio_power_control), GFP_KERNEL); + if (rpc == NULL) { + rfkill_free(ret); + return NULL; + } + + ret->name = name; + ret->data = rpc; + + rpc->power_reg = optional_power; + rpc->radio_reg = optional_radio; + + if (optional_power) + curstate |= tlsup_read_switch_state(optional_power); + if (optional_radio) + curstate |= tlsup_read_switch_state(optional_radio); + + ret->state = curstate; + + if (optional_power) + tlsup_set_switch_state(optional_power, curstate); + if (optional_radio) + tlsup_set_switch_state(optional_radio, curstate); + + ret->toggle_radio = tlsup_radio_switch_set; + ret->user_claim_unsupported = 1; + + rfkill_register(ret); + + return ret; +} + +/* Registration functions */ + +int tlsup_register_radios(void) +{ + int hsdpa_present = 0, bluetooth_present = 0, wlan_present = 0; + int registered = 0; + + if (tlsup_test_radio_presence(HCI_WIRELESS_3GHSDPA_POWER)) { + hsdpa_present = 1; + } + + if (tlsup_test_radio_presence(HCI_WIRELESS_3GHSDPA_RADIO)) { + hsdpa_present = 1; + } + + if (tlsup_test_radio_presence(HCI_WIRELESS_BLUETOOTH_POWER)) { + bluetooth_present = 1; + } + + if (tlsup_test_radio_presence(HCI_WIRELESS_BLUETOOTH_RADIO)) { + bluetooth_present = 1; + } + + if (tlsup_test_radio_presence(HCI_WIRELESS_WLAN_RADIO)) { + wlan_present = 1; + } + + if (hsdpa_present) { + tlsup_info("HSDPA Modem power switch %spresent, radio switch %spresent\n", + (tlsup_radios_present & HCI_WIRELESS_3GHSDPA_POWER) ? "" : "not ", + (tlsup_radios_present & HCI_WIRELESS_3GHSDPA_RADIO) ? "" : "not "); + hsdpa_rfkill_dev = tlsup_register_rfkill("tlsup-hsdpa_3g_modem", RFKILL_TYPE_WLAN, + HCI_WIRELESS_3GHSDPA_POWER, + HCI_WIRELESS_3GHSDPA_RADIO); + if (hsdpa_rfkill_dev) { + tlsup_info("HSDPA Modem claims to be %s\n", + (hsdpa_rfkill_dev->state == RFKILL_STATE_OFF) ? "off" : "on"); + registered++; + } else { + tlsup_err("Failed to register HSDPA modem switch\n"); + } + } + + if (bluetooth_present) { + tlsup_info("Bluetooth power switch %spresent, radio switch %spresent\n", + (tlsup_radios_present & HCI_WIRELESS_BLUETOOTH_POWER) ? "" : "not ", + (tlsup_radios_present & HCI_WIRELESS_BLUETOOTH_RADIO) ? "" : "not "); + bluetooth_rfkill_dev = tlsup_register_rfkill("tlsup-bluetooth", RFKILL_TYPE_BLUETOOTH, + HCI_WIRELESS_BLUETOOTH_POWER, + HCI_WIRELESS_BLUETOOTH_RADIO); + if (bluetooth_rfkill_dev) { + tlsup_info("Bluetooth claims to be %s\n", + (bluetooth_rfkill_dev->state == RFKILL_STATE_OFF) ? "off" : "on"); + registered++; + } else { + tlsup_err("Failed to register bluetooth switch\n"); + } + } + + if (wlan_present) { + tlsup_info("WLAN radio switch %spresent\n", + (tlsup_radios_present & HCI_WIRELESS_WLAN_RADIO) ? "" : "not "); + wlan_rfkill_dev = tlsup_register_rfkill("tlsup-wlan", RFKILL_TYPE_WLAN, + 0, + HCI_WIRELESS_WLAN_RADIO); + if (wlan_rfkill_dev) { + tlsup_info("WLAN claims to be %s\n", + (wlan_rfkill_dev->state == RFKILL_STATE_OFF) ? "off" : "on"); + registered++; + } else { + tlsup_err("Failed to register WLAN switch\n"); + } + } + + return registered; +} + +static inline void tlsup_free_rfkill_dev(struct rfkill *d) +{ + void *data = d->data; + rfkill_unregister(d); + kfree(data); +} + +void tlsup_deregister_radios(void) +{ + if (hsdpa_rfkill_dev) + tlsup_free_rfkill_dev(hsdpa_rfkill_dev); + if (bluetooth_rfkill_dev) + tlsup_free_rfkill_dev(bluetooth_rfkill_dev); + if (wlan_rfkill_dev) + tlsup_free_rfkill_dev(wlan_rfkill_dev); +} --- linux-2.6.28.orig/ubuntu/heci/heci_data_structures.h +++ linux-2.6.28/ubuntu/heci/heci_data_structures.h @@ -0,0 +1,538 @@ +/* + * Part of Intel(R) Manageability Engine Interface Linux driver + * + * Copyright (c) 2003 - 2007 Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. + * + */ + +#ifndef _HECI_DATA_STRUCTURES_H_ +#define _HECI_DATA_STRUCTURES_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * error code definition + */ +#define ESUCCESS 0 +#define ESLOTS_OVERFLOW 1 +#define ECORRUPTED_MESSAGE_HEADER 1000 +#define ECOMPLETE_MESSAGE 1001 +#define FC_MESSAGE_RESERVED_LENGTH 5 + +/** + * Number of queue lists used by this driver + */ +#define NUMBER_OF_LISTS 7 + +#define LEGACY_MTU 4160 +#pragma pack(1) + + +/** + * HECI HW Section + */ + +/* HECI addresses and defines */ +#define H_CB_WW 0 +#define H_CSR 4 +#define ME_CB_RW 8 +#define ME_CSR_HA 0xC + + +/* register bits - H_CSR */ + +#define H_CBD 0xFF000000 +#define H_CBWP 0x00FF0000 +#define H_CBRP 0x0000FF00 +#define H_RST 0x00000010 +#define H_RDY 0x00000008 +#define H_IG 0x00000004 +#define H_IS 0x00000002 +#define H_IE 0x00000001 + + +/* register bits - ME_CSR_HA */ +#define ME_CBD_HRA 0xFF000000 +#define ME_CBWP_HRA 0x00FF0000 +#define ME_CBRP_HRA 0x0000FF00 +#define ME_RST_HRA 0x00000010 +#define ME_RDY_HRA 0x00000008 +#define ME_IG_HRA 0x00000004 +#define ME_IS_HRA 0x00000002 +#define ME_IE_HRA 0x00000001 + +/** + * heci driver use additional char device for legacy mode + */ +#define MINORS_COUNT 2 + +#define LEGACY_MINOR_NUMBER 0 +#define HECI_MINOR_NUMBER 1 +#define MAX_OPEN_HANDLE_COUNT 253 +/** + * debug kernel print macro define + */ +#define HECI_INFO(format, arg...) printk(KERN_INFO "%s: " format, THIS_MODULE->name, ## arg) +#define HECI_ERR(format, arg...) printk(KERN_ERR "%s: " format, THIS_MODULE->name, ## arg) +#define HECI_WARN(format, arg...) printk(KERN_WARNING "%s: " format, THIS_MODULE->name, ## arg) + + +/* Module Parameters */ +#define DEF_PARM(type, name, init, perm, desc) \ + type name = (init); \ + MODULE_PARM_DESC(name, desc); \ + module_param(name, type, perm) + +extern int heci_debug; + +#define DBG(format, arg...) do {if (heci_debug) \ +printk(KERN_ERR "%s: " format , __func__ , ## arg); \ +} while (0) + +#ifdef HECI_DEBUG +#define assert(expr) do {} while (0) +#else +#define assert(expr) \ + if (!(expr)) { \ + printk("Assertion failed! %s, %s, %s, line=%d\n", \ + #expr, __FILE__, __func__, __LINE__); \ + } +#endif + +/** + * time to wait event + */ +#define HECI_INTEROP_TIMEOUT (HZ * 7) + +/** + * watch dog definition + */ +#define HECI_WATCHDOG_DATA_SIZE 16 +#define HECI_START_WD_DATA_SIZE 20 +#define HECI_WD_PARAMS_SIZE 4 + +#define HECI_NO_MSG_SENT 0 +#define HECI_WD_STATE_INDEPENDENCE_MSG_SENT (1 << 0) + + +#define HECI_WD_HOST_CLIENT_ID 1 +#define HECI_LEGACY_HOST_CLIENT_ID 2 + +#undef FALSE +#undef TRUE +#define TRUE 1 +#define FALSE 0 + +struct guid { + __u32 data1; + __u16 data2; + __u16 data3; + __u8 data4[8]; +}; + +/* File state */ +enum file_state { + HECI_FILE_INITIALIZING = 0, + HECI_FILE_CONNECTING, + HECI_FILE_CONNECTED, + HECI_FILE_DISCONNECTING, + HECI_FILE_DISCONNECTED +}; + +/* HECI states */ +enum heci_states{ + HECI_INITIALIZING = 0, + HECI_ENABLED, + HECI_RESETING, + HECI_DISABLED, + HECI_RECOVERING_FROM_RESET, + HECI_POWER_DOWN, + HECI_POWER_UP +}; + +enum legacy_states { + HECI_LEGACY_IDLE, + HECI_LEGACY_WRITING, + HECI_LEGACY_FLOW_CONTROL, + HECI_LEGACY_READING, + HECI_LEGACY_READ_COMPLETE +}; + +enum heci_file_transaction_states { + HECI_IDLE, + HECI_WRITING, + HECI_WRITE_COMPLETE, + HECI_FLOW_CONTROL, + HECI_READING, + HECI_READ_COMPLETE +}; + +/* HECI CB */ +enum heci_cb_major_types { + HECI_READ = 0, + HECI_WRITE, + HECI_IOCTL, + HECI_OPEN, + HECI_CLOSE +}; + +/* HECI user data struct */ +struct heci_message_data { + __u32 size; + char *data; +}; +#define SECOND_TO_MILLI 1000 +#define SECOND_TO_MICRO SECOND_TO_MILLI * 1000 +#define SECOND_TO_100NANO SECOND_TO_MICRO * 10 + +#define CONNECT_TIMEOUT 3 /* at least 2 seconds */ + +#define LEGACY_STALL_TIMER 12 /* seconds */ +#define LEGACY_READ_TIMER 15 /* seconds */ + +struct heci_cb_private { + struct list_head cb_list; + enum heci_cb_major_types major_file_operations; + void *file_private; + struct heci_message_data request_buffer; + struct heci_message_data response_buffer; + unsigned long information; + unsigned long read_time; + struct file *file_object; +}; + +/* Private file struct */ +struct heci_file_private { + struct list_head link; + struct file *file; + enum file_state state; + wait_queue_head_t tx_wait; + wait_queue_head_t rx_wait; + wait_queue_head_t wait; + spinlock_t file_lock; + spinlock_t read_io_lock; + spinlock_t write_io_lock; + int read_pending; + int status; + /* ID of client connected */ + __u8 host_client_id; + __u8 me_client_id; + __u8 flow_control_credentials; + __u8 timer_count; + enum heci_file_transaction_states reading_state; + enum heci_file_transaction_states writing_state; + int sm_state; + struct heci_cb_private *read_cb; +}; + +struct io_heci_list { + struct heci_cb_private heci_cb; + int status; + struct iamt_heci_device *device_extension; +}; + +struct heci_driver_version { + __u8 major; + __u8 minor; + __u8 hotfix; + __u16 build; +}; + + +struct heci_client { + __u32 max_message_length; + __u8 protocol_version; +}; +/* + * HECI BUS Interface Section + */ +struct heci_message_header { + __u32 me_address:8; + __u32 host_address:8; + __u32 length:9; + __u32 reserved:6; + __u32 message_complete:1; +}; + + +struct hbm_command { + __u8 command:7; + __u8 is_response:1; +}; + + +struct heci_bus_message { + struct hbm_command command; + __u8 command_specific_data[]; +}; + +struct hbm_version { + __u8 minor_version; + __u8 major_version; +}; + +struct hbm_host_version_request { + struct hbm_command command; + __u8 reserved; + struct hbm_version host_version; +}; + +struct hbm_host_version_response { + struct hbm_command command; + int host_version_supported; + struct hbm_version me_max_version; +}; + +struct hbm_host_stop_request { + struct hbm_command command; + __u8 reason; + __u8 reserved[2]; +}; + +struct hbm_host_stop_response { + struct hbm_command command; + __u8 reserved[3]; +}; + +struct hbm_me_stop_request { + struct hbm_command command; + __u8 reason; + __u8 reserved[2]; +}; + +struct hbm_host_enumeration_request { + struct hbm_command command; + __u8 reserved[3]; +}; + +struct hbm_host_enumeration_response { + struct hbm_command command; + __u8 reserved[3]; + __u8 valid_addresses[32]; +}; + +struct heci_client_properties { + struct guid protocol_name; + __u8 protocol_version; + __u8 max_number_of_connections; + __u8 fixed_address; + __u8 single_receive_buffer; + __u32 max_message_length; +}; + +struct hbm_host_client_properties_request { + struct hbm_command command; + __u8 address; + __u8 reserved[2]; +}; + + +struct hbm_host_client_properties_response { + struct hbm_command command; + __u8 address; + __u8 status; + __u8 reserved[1]; + struct heci_client_properties client_properties; +}; + +struct hbm_client_connect_request { + struct hbm_command command; + __u8 me_address; + __u8 host_address; + __u8 reserved; +}; + +struct hbm_client_connect_response { + struct hbm_command command; + __u8 me_address; + __u8 host_address; + __u8 status; +}; + +struct hbm_client_disconnect_request { + struct hbm_command command; + __u8 me_address; + __u8 host_address; + __u8 reserved[1]; +}; + +struct hbm_flow_control { + struct hbm_command command; + __u8 me_address; + __u8 host_address; + __u8 reserved[FC_MESSAGE_RESERVED_LENGTH]; +}; + +struct heci_me_client { + struct heci_client_properties properteis; + __u8 client_id; + __u8 flow_control_credentials; +}; + +/* private device struct */ +struct iamt_heci_device { + struct pci_dev *pdev; /* pointer to pci device struct */ + /* + * lists of queues + */ + struct io_heci_list *io_list_array[NUMBER_OF_LISTS]; /* array of pointers to aio lists */ + struct io_heci_list read_list; /* driver read queue */ + struct io_heci_list write_list; /* driver write queue */ + struct io_heci_list write_waiting_list; /* driver write waiting queue */ + struct io_heci_list control_write_list; /* driver managed write IOCTL list */ + struct io_heci_list control_read_list; /* driver managed read IOCTL list */ + struct io_heci_list pthi_cmd_list; /* driver managed PTHI list for cmd waiting */ + struct io_heci_list pthi_read_complete_list; /* driver managed PTHI list for read completed pthi command data */ + /* + * list of files + */ + struct list_head file_list; + /* + * memory of device + */ + unsigned int mem_base; + unsigned int mem_length; + char *mem_addr; + /* + * lock for the device + */ + spinlock_t device_lock; + spinlock_t extra_lock; + /* + * intterupts + */ + int irq; + struct work_struct work; + int received_message; + + struct timer_list timer; + struct timer_list wd_timer; + /* + * hw states of host and fw(ME) + */ + __u32 host_hw_state; + __u32 me_hw_state; + /* + * waiting queue for receive message from FW + */ + wait_queue_head_t wait_received_message; + wait_queue_head_t wait_stop_wd; + /* + * heci device states + */ + enum heci_states heci_state; + int stop; + /** + * virtual void GetParam(const char* UserParam); + * read write messages to/from heci fw + */ + __u32 extra_write_index; + __u32 read_message_buffer[128]; /* used for control messages */ + __u32 write_message_buffer[128]; /* used for control messages */ + __u32 extra_message_buffer[8]; /* for control responses */ + __u32 read_message_header; + + struct hbm_version version; + + int host_buffer_is_empty; + struct heci_file_private wd_file_extension; + struct heci_me_client *me_clients; /* Note: memory has to be allocated */ + __u8 heci_me_clients[32]; /* list of existing clients */ + __u8 num_heci_me_clients; + __u8 heci_host_clients[32]; /* list of existing clients */ + __u8 current_host_client_id; + + int wd_pending; + int wd_stoped; + __u16 wd_timeout; /* seconds ((wd_data[1] << 8) + wd_data[0]) */ + unsigned char wd_data[HECI_START_WD_DATA_SIZE]; + + + __u16 wd_due_counter; + int asf_mode; + int wd_bypass; /* if true,don't refresh watchdog ME client */ + + /* maybe this is not required */ + struct file *legacy_file_object; + struct heci_file_private legacy_file_extension; + int legacy_ioctl; + int legacy_canceled; + __u32 legacy_timer; + __u32 legacy_stall_timer; + unsigned char legacy_message_buffer[LEGACY_MTU]; + __u32 legacy_message_buffer_size; + __u32 legacy_message_buffer_index; + int legacy_flow_control_pending; + enum legacy_states legacy_state; + + struct heci_cb_private *legacy_current_cb; + __u8 write_hang; + int need_reset; + long open_handle_count; + +}; + +/** + * read_heci_register - Read a byte from the heci device + * @device: the device structure + * @offset: offset from which to read the data + * + * Return: + * the byte read. + */ +__u32 read_heci_register(struct iamt_heci_device * device, + unsigned long offset); + +/** + * write_heci_register - Write 4 bytes to the heci device + * @device: the device structure + * @offset: offset from which to write the data + * + * @value: the byte to write + */ +void write_heci_register(struct iamt_heci_device * device, unsigned long offset, + __u32 value); + +#endif /* _HECI_DATA_STRUCTURES_H_ */ --- linux-2.6.28.orig/ubuntu/heci/heci_main.c +++ linux-2.6.28/ubuntu/heci/heci_main.c @@ -0,0 +1,1444 @@ +/* + * Part of Intel(R) Manageability Engine Interface Linux driver + * + * Copyright (c) 2003 - 2007 Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kcompat.h" +#include "heci.h" +#include "heci_interface.h" +#include "version.h" + + +#define HECI_READ_TIMEOUT 45 + +#define MAX_OPEN_HANDLE_COUNT 253 +/** + * heci driver strings + */ +char heci_driver_name[] = "heci"; +char heci_driver_string[] = "Intel(R) AMT Management Interface"; +char heci_driver_version[] = DRIVER_VERSION; +char heci_copyright[] = "Copyright (c) 2003 - 2007 Intel Corporation."; + + +#ifdef HECI_DEBUG +DEF_PARM(int, heci_debug, 1, 0644, "Debug enabled or not"); +#else +DEF_PARM(int, heci_debug, 0, 0644, "Debug enabled or not"); +#endif + +/* heci char device for registration */ +static struct cdev heci_cdev = { + .kobj = {.name = "heci", }, + .owner = THIS_MODULE, +}; + +/* iamt legacy char device for registration */ +static struct cdev iamt_legacy_cdev = { + .kobj = {.name = "iamt_legacy", }, + .owner = THIS_MODULE, +}; + +/* major number for device */ +static int heci_major; +/* The device pointer */ +static struct pci_dev *heci_device; + +/* heci_pci_tbl - PCI Device ID Table */ +static struct pci_device_id heci_pci_tbl[] = { + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_HECI_DEVICE_ID1)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_HECI_DEVICE_ID2)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_HECI_DEVICE_ID3)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_HECI_DEVICE_ID4)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_HECI_DEVICE_ID5)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_HECI_DEVICE_ID6)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_HECI_DEVICE_ID7)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_HECI_DEVICE_ID8)}, + /* required last entry */ + {0, } +}; + +MODULE_DEVICE_TABLE(pci, heci_pci_tbl); + +/** + * Local Function Prototypes + */ +static int __init heci_init_module(void); +static void __exit heci_exit_module(void); +static int __devinit heci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent); +static void __devexit heci_remove(struct pci_dev *pdev); +static int heci_open(struct inode *inode, struct file *file); +static int heci_release(struct inode *inode, struct file *file); +static unsigned int heci_legacy_poll(struct file *file, poll_table * wait); +static ssize_t heci_read(struct file *file, char __user * ubuf, + size_t length, loff_t * offset); +static int heci_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long data); +static ssize_t heci_write(struct file *file, const char __user * ubuf, + size_t length, loff_t * offset); +static unsigned int heci_poll(struct file *file, poll_table * wait); +#ifdef CONFIG_PM +static int heci_suspend(struct pci_dev* pdev, pm_message_t state); +static int heci_resume(struct pci_dev* pdev); +static __u16 g_sus_wd_timeout; +#endif +/** + * PCI driver structure + */ +static struct pci_driver heci_driver = { + .name = heci_driver_name, + .id_table = heci_pci_tbl, + .probe = heci_probe, + .remove = heci_remove, + SHUTDOWN_METHOD(heci_remove) +#ifdef CONFIG_PM + .suspend = heci_suspend, + .resume = heci_resume +#endif +}; + +/** + * file operations structure will be use heci char device. + */ +static struct file_operations heci_fops = { + .owner = THIS_MODULE, + .read = heci_read, + .ioctl = heci_ioctl, + .open = heci_open, + .release = heci_release, + .write = heci_write, + .poll = heci_poll, +}; + +/** + * file operations structure will be use iamt legacy char device. + */ +static struct file_operations iamt_legacy_fops = { + .owner = THIS_MODULE, + .ioctl = heci_ioctl, + .open = heci_open, + .release = heci_release, + .poll = heci_legacy_poll, +}; + +/** + * For kernels withouth PCI shutdown support reboot notifier is essential + */ +HECI_REBOOT_NOTIFIER(heci_reboot_notifier, heci_driver, heci_remove) + +/** + * Set up the cdev structure for heci device. + * @dev - char device struct + * @minor - minor number for registration char device + * @fops - file operations structure + * @return : + * 0 on success, + * negative on failure + */ +static int heci_registration_cdev(struct cdev *dev, int minor, + struct file_operations *fops) +{ + int ret = ESUCCESS, devno = MKDEV(heci_major, minor); + + cdev_init(dev, fops); + dev->owner = THIS_MODULE; + dev->ops = fops; + ret = cdev_add(dev, devno, 1); + /* Fail gracefully if need be */ + if (ret) { + kobject_put(&dev->kobj); + HECI_ERR("Error %d registering heci device %d", ret, minor); + } + return ret; +} + + + +/** + * heci_init_module - Driver Registration Routine + * + * heci_init_module is the first routine called when the driver is + * loaded. All it does is register with the PCI subsystem. + * + * @return : + * 0 on success, + * negative on failure + */ +static int __init heci_init_module(void) +{ + int ret = ESUCCESS; + dev_t dev; + HECI_INFO("%s - version %s\n", heci_driver_string, heci_driver_version); + HECI_INFO("%s\n", heci_copyright); + + /* init pci module */ + ret = pci_register_driver(&heci_driver); + if (ret < 0) + goto end; + + REGISTER_REBOOT_NOTIFIER(heci_reboot_notifier); + /* registration char devices */ + ret = alloc_chrdev_region(&dev, 0, MINORS_COUNT, "heci"); + + heci_major = MAJOR(dev); + /* Now registration two cdevs. */ + ret = heci_registration_cdev(&iamt_legacy_cdev, LEGACY_MINOR_NUMBER, + &iamt_legacy_fops); + if (ret) + goto unregister; + + ret = heci_registration_cdev(&heci_cdev, HECI_MINOR_NUMBER, + &heci_fops); + if (ret) { + cdev_del(&iamt_legacy_cdev); + goto unregister; + } + return ret; + +unregister: + pci_unregister_driver(&heci_driver); + unregister_chrdev_region(MKDEV(heci_major, 0), MINORS_COUNT); +end: + return ret; +} + +module_init(heci_init_module); + + +/** + * heci_exit_module - Driver Exit Cleanup Routine + * + * heci_exit_module is called just before the driver is removed + * from memory. + * + * @return : + * none; + */ + +static void __exit heci_exit_module(void) +{ + UNREGISTER_REBOOT_NOTIFIER(heci_reboot_notifier); + pci_unregister_driver(&heci_driver); + /* Now unregister two cdevs. */ + cdev_del(&iamt_legacy_cdev); + cdev_del(&heci_cdev); + unregister_chrdev_region(MKDEV(heci_major, 0), MINORS_COUNT); +} + +module_exit(heci_exit_module); + + +/** + * heci_probe - Device Initialization Routine + * + * @pdev: PCI device information struct + * @ent: entry in kcs_pci_tbl + * + * @return : + * 0 on success, + * negative on failure + */ +static int __devinit heci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct iamt_heci_device *device = NULL; + int i, err = 0; + if (heci_device) { + err = -EEXIST; + goto end; + } + /* enable pci device */ + err = pci_enable_device(pdev); + if (err) { + HECI_ERR("Failed to enable pci device\n"); + goto end; + } + /* set PCI host mastering */ + pci_set_master(pdev); + /* pci request regions for heci driver */ + err = pci_request_regions(pdev, heci_driver_name); + if (err) { + HECI_ERR("Failed to get pci regions\n"); + goto disable_device; + } + /* allocates and initializes the heci device structure */ + device = init_heci_device(pdev); + if (!device) { + err = -ENOMEM; + goto release_regions; + } + /* mapping IO device memory */ + for (i = BAR_0; i <= BAR_5; i++) { + if (pci_resource_len(pdev, i) == 0) { + continue; + } + if (pci_resource_flags(pdev, i) & IORESOURCE_IO) { + HECI_ERR("heci has an IO ports.\n"); + goto free_device; + } else if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) { + if (device->mem_base) { + HECI_ERR("Too many mem addresses.\n"); + goto free_device; + } + device->mem_base = pci_resource_start(pdev, i); + device->mem_length = pci_resource_len(pdev, i); + } + } + if (!device->mem_base) { + HECI_ERR("No address to use.\n"); + err = -ENODEV; + goto free_device; + } + device->mem_addr = ioremap_nocache(device->mem_base, device->mem_length); + if (!device->mem_addr) { + HECI_ERR(" Remap IO device memory failure.\n"); + err = -ENOMEM; + goto free_device; + } + /* request and enable interrupt */ + device->irq = pdev->irq; + err = request_irq(device->irq, heci_isr_interrupt, IRQF_SHARED, + heci_driver_name, device); + if (err) { + HECI_ERR("Request_irq failure. irq = %d \n", device->irq); + goto unmap_memory; + } + + if (heci_hw_init(device)) { + HECI_ERR("init hw failure.\n"); + err = -ENODEV; + goto release_irq; + } + init_timer(&device->wd_timer); + heci_initialize_clients(device); + if (device->heci_state != HECI_ENABLED) { + err = -ENODEV; + goto release_hw; + } + spin_lock_bh(&device->device_lock); + heci_device = pdev; + pci_set_drvdata(pdev, device); + spin_unlock_bh(&device->device_lock); + if (device->wd_timeout) { + mod_timer(&device->wd_timer, jiffies); + } +#ifdef CONFIG_PM + g_sus_wd_timeout = 0; +#endif + HECI_INFO("heci driver initialization successful.\n"); + return ESUCCESS; + +release_hw: + /* disable interrupts */ + device->host_hw_state = read_heci_register(device, H_CSR); + device->host_hw_state &= ~H_IE; + /* acknowledge interrupt and stop interupts */ + write_heci_register(device, H_CSR, device->host_hw_state); + + del_timer_sync(&device->wd_timer); + + + flush_scheduled_work(); + +release_irq: + free_irq(pdev->irq, device); +unmap_memory: + if (device->mem_addr) + iounmap(device->mem_addr); +free_device: + kfree(device); +release_regions: + pci_release_regions(pdev); +disable_device: + pci_disable_device(pdev); +end: + HECI_ERR("heci driver initialization failed.\n"); + return err; +} + +/** + * heci_remove - Device Removal Routine + * @pdev: PCI device information struct + * + * heci_remove is called by the PCI subsystem to alert the driver + * that it should release a PCI device. + * + * @return : + * none; + */ +static void __devexit heci_remove(struct pci_dev *pdev) +{ + struct iamt_heci_device *device = pci_get_drvdata(pdev); + int err = 0; + + if (heci_device != pdev) + return; + del_timer_sync(&device->wd_timer); + if (device->wd_file_extension.state == HECI_FILE_CONNECTED + && device->wd_timeout) { + spin_lock_bh(&device->device_lock); + device->wd_timeout = 0; + device->wd_due_counter = 0; + memcpy(device->wd_data, stop_wd_params, HECI_WD_PARAMS_SIZE); + device->stop = TRUE; + if (device->host_buffer_is_empty && + flow_control_credentials(device, &device->wd_file_extension)) { + device->host_buffer_is_empty = FALSE; + + if (!heci_send_wd(device)) + DBG("Send stop WD failed\n"); + else + flow_control_reduce(device, &device->wd_file_extension); + device->wd_pending = FALSE; + + } else { + device->wd_pending = TRUE; + } + spin_unlock_bh(&device->device_lock); + device->wd_stoped = FALSE; + + err = + wait_event_interruptible_timeout(device->wait_stop_wd, + (TRUE == + device->wd_stoped), + 10 * HZ); + if (!device->wd_stoped) + DBG("stop wd failed to complete.\n"); + else + DBG("stop wd complete.\n"); + } + + heci_device = NULL; + if (device->legacy_file_extension.status == HECI_FILE_CONNECTED) { + device->legacy_file_extension.status = HECI_FILE_DISCONNECTING; + heci_disconnect_host_client(device, + &device->legacy_file_extension); + } + if (device->wd_file_extension.status == HECI_FILE_CONNECTED) { + device->wd_file_extension.status = HECI_FILE_DISCONNECTING; + heci_disconnect_host_client(device, + &device->wd_file_extension); + } + /* remove entry if already in list */ + DBG("list del legacy and wd file list.\n"); + heci_remove_client_from_file_list(device, device->wd_file_extension. + host_client_id); + heci_remove_client_from_file_list(device, device->legacy_file_extension. + host_client_id); + flush_scheduled_work(); + /* disable interrupts */ + device->host_hw_state &= ~H_IE; + /* acknowledge interrupt and stop interupts */ + write_heci_register(device, H_CSR, device->host_hw_state); + free_irq(pdev->irq, device); + pci_set_drvdata(pdev, NULL); + + if (device->mem_addr) + iounmap(device->mem_addr); + kfree(device); + + pci_release_regions(pdev); + pci_disable_device(pdev); +} +/** + * heci_clear_list - remove all callbacks associated with file + * from heci_cb_list + * @file: file informtion struct + * @heci_cb_list: callbacks list + * heci_clear_list is called to clear resources associated with file + * when application calls close function or Ctrl-C was pressed + * + * @return :true if callback removed from the list, false otherwise + */ +static int heci_clear_list(struct iamt_heci_device *device, struct file *file, struct list_head *heci_cb_list) { + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + struct file *file_temp = NULL; + int return_status = FALSE; + + /* list all list member */ + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, heci_cb_list, cb_list){ + file_temp = (struct file *)kernel_priv_cb_pos->file_object; + /* check if list member associated with a file */ + if (file_temp == file) { + /* remove member from the list */ + list_del(&kernel_priv_cb_pos->cb_list); + /* check if cb equal to current legacy cb */ + if (device->legacy_current_cb == kernel_priv_cb_pos) { + device->legacy_current_cb = NULL; + /* send flow control to legacy client */ + heci_send_flow_control(device, &device->legacy_file_extension); + } + /* free all allocated buffers */ + kfree (kernel_priv_cb_pos->request_buffer.data); + kernel_priv_cb_pos->request_buffer.data = NULL; + kfree (kernel_priv_cb_pos->response_buffer.data); + kernel_priv_cb_pos->response_buffer.data = NULL; + kfree(kernel_priv_cb_pos); + return_status = TRUE; + } + } + return return_status; +} + +/** + * heci_clear_lists - remove all callbacks associated with file + * @device: device informtion struct + * @file: file informtion struct + * heci_clear_lists is called to clear resources associated with file + * when application calls close function or Ctrl-C was pressed + * + * @return :true if callback removed from the list, false otherwise + */ +static int heci_clear_lists(struct iamt_heci_device *device, struct file *file) +{ + int return_status = FALSE; + + /* remove callbacks associated with a file */ + heci_clear_list(device, file, &device->pthi_cmd_list.heci_cb.cb_list); + if (heci_clear_list(device, file, &device->pthi_read_complete_list.heci_cb.cb_list)) + return_status = TRUE; + heci_clear_list(device, file, &device->control_read_list.heci_cb.cb_list); + if (heci_clear_list(device, file, &device->control_write_list.heci_cb.cb_list)) + return_status = TRUE; + if (heci_clear_list(device, file, &device->write_waiting_list.heci_cb.cb_list)) + return_status = TRUE; + if (heci_clear_list(device, file, &device->write_list.heci_cb.cb_list)) + return_status = TRUE; + /* check if legacy_current_cb not NULL */ + if (device->legacy_current_cb && (!return_status)) { + /* check file and legacy current cb association */ + if (device->legacy_current_cb->file_object == file) { + /* remove cb */ + kfree (device->legacy_current_cb->request_buffer.data); + device->legacy_current_cb->request_buffer.data = NULL; + kfree (device->legacy_current_cb->response_buffer.data); + device->legacy_current_cb->response_buffer.data = NULL; + kfree(device->legacy_current_cb); + device->legacy_current_cb = NULL; + return_status = TRUE; + } + } + return return_status; +} + +/** + * heci_open - the open function + */ +static int heci_open(struct inode *inode, struct file *file) +{ + struct heci_file_private *file_extension = NULL; + int if_num = MINOR(inode->i_rdev); + struct iamt_heci_device *device = NULL; + if (!heci_device) + return -ENODEV; + device = pci_get_drvdata(heci_device); + if (((if_num != LEGACY_MINOR_NUMBER) + && (if_num != HECI_MINOR_NUMBER)) || (!device)) + return -ENODEV; + + if (if_num != LEGACY_MINOR_NUMBER) { + file_extension = alloc_priv(file); + if (!file_extension) + return -ENOMEM; + } else { + file->private_data = + (void *) &device->legacy_file_extension; + return ESUCCESS; + } + spin_lock_bh(&device->device_lock); + if (device->heci_state != HECI_ENABLED) { + spin_unlock_bh(&device->device_lock); + kfree(file_extension); + file_extension = NULL; + return -ENODEV; + } + if (device->open_handle_count >= MAX_OPEN_HANDLE_COUNT) { + spin_unlock_bh(&device->device_lock); + kfree(file_extension); + file_extension = NULL; + return -ENFILE; + }; + device->open_handle_count++; + list_add_tail(&file_extension->link, &device->file_list); + while ((device->heci_host_clients[device->current_host_client_id / 8] + & (1 << (device->current_host_client_id % 8))) != 0) { + device->current_host_client_id++; /* allow overflow */ + DBG("current_host_client_id = %d\n", device->current_host_client_id); + DBG("device->open_handle_count = %lu\n", device->open_handle_count); + } + DBG("current_host_client_id = %d\n", device->current_host_client_id); + file_extension->host_client_id = device->current_host_client_id; + device->heci_host_clients[file_extension->host_client_id / 8] |= + (1 << (file_extension->host_client_id % 8)); + spin_unlock_bh(&device->device_lock); + spin_lock(&file_extension->file_lock); + file_extension->state = HECI_FILE_INITIALIZING; + file_extension->sm_state = 0; + + file->private_data = file_extension; + spin_unlock(&file_extension->file_lock); + + return ESUCCESS; +} + +/** + * heci_release - the release function + */ +static int heci_release(struct inode *inode, struct file *file) +{ + int return_status = ESUCCESS; + int if_num = MINOR(inode->i_rdev); + struct heci_file_private *file_extension = file->private_data; + struct heci_cb_private *kernel_priv_cb = NULL; + struct iamt_heci_device *device = NULL; + + if (!heci_device) + return -ENODEV; + + device = pci_get_drvdata(heci_device); + if (((if_num != LEGACY_MINOR_NUMBER) + && (if_num != HECI_MINOR_NUMBER)) || (!device) + || (!file_extension)) + return -ENODEV; + if (file_extension != &device->legacy_file_extension) { + + spin_lock(&file_extension->file_lock); + if (file_extension->state == HECI_FILE_CONNECTED) { + file_extension->state = HECI_FILE_DISCONNECTING; + spin_unlock(&file_extension->file_lock); + DBG("disconnecting client host client = %d, ME client = %d\n", + file_extension->host_client_id, + file_extension->me_client_id); + return_status = + heci_disconnect_host_client(device, + file_extension); + spin_lock(&file_extension->file_lock); + } + spin_lock_bh(&device->device_lock); + heci_flush_queues(device, file_extension); + DBG("remove client host client = %d, ME client = %d\n", + file_extension->host_client_id, + file_extension->me_client_id); + device->heci_host_clients[file_extension->host_client_id / 8] &= ~(1 << (file_extension->host_client_id % 8)); + device->open_handle_count--; + heci_remove_client_from_file_list(device, file_extension->host_client_id); + spin_unlock_bh(&device->device_lock); + + /* free read cb */ + if (file_extension->read_cb != NULL) { + spin_unlock(&file_extension->file_lock); + kernel_priv_cb = file_extension->read_cb; + kfree(kernel_priv_cb->response_buffer.data); + kernel_priv_cb->response_buffer.data = NULL; + kfree(kernel_priv_cb); + kernel_priv_cb = NULL; + + file_extension->read_cb = NULL; + spin_lock(&file_extension->file_lock); + } + spin_unlock(&file_extension->file_lock); + kfree(file_extension); + file->private_data = NULL; + } else { + spin_lock_bh(&device->device_lock); + if (if_num != LEGACY_MINOR_NUMBER) { + device->open_handle_count--; + } + if (device->legacy_file_object == file + && device->legacy_state != HECI_LEGACY_IDLE) { + + DBG("pthi canceled legacy state %d\n", + device->legacy_state); + device->legacy_canceled = TRUE; + if (device->legacy_state == HECI_LEGACY_READ_COMPLETE) { + DBG("run next pthi legacy cb\n"); + run_next_legacy_cmd(device); + } + } + + if (heci_clear_lists(device, file)) { + device->legacy_state = HECI_LEGACY_IDLE; + } + spin_unlock_bh(&device->device_lock); + } + return return_status; +} + + +static struct heci_cb_private *find_read_list_entry(struct iamt_heci_device* device, + struct heci_file_private *file_extension) +{ + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + struct heci_file_private *file_extension_list_temp = NULL; + + if (device->read_list.status == ESUCCESS + && !list_empty(&device->read_list.heci_cb.cb_list)) { + DBG("remove read_list CB \n"); + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device->read_list.heci_cb.cb_list, cb_list){ + file_extension_list_temp = + (struct heci_file_private *) + kernel_priv_cb_pos->file_private; + if (file_extension_list_temp) { + if ((file_extension->host_client_id == file_extension_list_temp->host_client_id) + && (file_extension->me_client_id == file_extension_list_temp->me_client_id)) + return kernel_priv_cb_pos; + } + } + } + return NULL; +} +/** + * heci_read - the read client message function. + */ +static ssize_t heci_read(struct file *file, char __user * ubuf, + size_t length, loff_t * offset) +{ + int i; + int return_status = ESUCCESS, err = ESUCCESS; + int if_num = MINOR((file->f_dentry->d_inode->i_rdev)); + struct heci_file_private *file_extension = file->private_data; + struct heci_cb_private *kernel_priv_cb_pos = NULL; + struct heci_cb_private *kernel_priv_cb = NULL; + struct iamt_heci_device *device = NULL; + + if (!heci_device) + return -ENODEV; + + device = pci_get_drvdata(heci_device); + if ((if_num != HECI_MINOR_NUMBER) || (!device) || (!file_extension)) + return -ENODEV; + + spin_lock_bh(&device->device_lock); + if (device->heci_state != HECI_ENABLED) { + spin_unlock_bh(&device->device_lock); + return -ENODEV; + } + spin_unlock_bh(&device->device_lock); + if (!file_extension) + return -ENODEV; + + spin_lock(&file_extension->file_lock); + if((file_extension->sm_state & HECI_WD_STATE_INDEPENDENCE_MSG_SENT) == 0) { + spin_unlock(&file_extension->file_lock); + /* Do not allow to read watchdog client */ + for (i = 0; i < device->num_heci_me_clients; i++) { + if (0 == memcmp(&heci_wd_guid, &device->me_clients[i].properteis.protocol_name, sizeof(struct guid))) { + if (file_extension->me_client_id == device->me_clients[i].client_id) + return -EBADF; + } + } + } else { + file_extension->sm_state &= ~HECI_WD_STATE_INDEPENDENCE_MSG_SENT; + spin_unlock(&file_extension->file_lock); + } + if (file_extension == &device->legacy_file_extension) { + return_status = pthi_read(device, if_num, file, ubuf, length, offset); + goto out; + } + + if (file_extension->read_cb && file_extension->read_cb->information > *offset) { + kernel_priv_cb = file_extension->read_cb; + goto copy_buffer; + } + else if (file_extension->read_cb && file_extension->read_cb->information > 0 && + file_extension->read_cb->information <= *offset) { + kernel_priv_cb = file_extension->read_cb; + return_status = 0; + goto free; + } + else if ((!file_extension->read_cb || file_extension->read_cb->information == 0) && + *offset > 0) { + *offset = 0; /*Offset needs to be cleaned for contingous reads*/ + return_status = 0; + goto out; + } + + spin_lock(&file_extension->read_io_lock); + err = heci_start_read(device, if_num, file_extension); + if (err != ESUCCESS && err != -EBUSY) { + DBG("heci start read failure with status = %d\n", err); + spin_unlock(&file_extension->read_io_lock); + return_status = err; + goto out; + } + if (HECI_READ_COMPLETE != file_extension->reading_state && !waitqueue_active (&file_extension->rx_wait)) { + if (file->f_flags & O_NONBLOCK) { + return_status = -EAGAIN; + spin_unlock(&file_extension->read_io_lock); + goto out; + } + spin_unlock(&file_extension->read_io_lock); + + if (wait_event_interruptible(file_extension->rx_wait, + (HECI_READ_COMPLETE == file_extension->reading_state || + HECI_FILE_INITIALIZING == file_extension->state || + HECI_FILE_DISCONNECTED == file_extension->state || + HECI_FILE_DISCONNECTING == file_extension->state))) { + if (signal_pending (current)) { + return_status = -EINTR; + goto out; + } + return -ERESTARTSYS; + } + + if (HECI_FILE_INITIALIZING == file_extension->state || + HECI_FILE_DISCONNECTED == file_extension->state || + HECI_FILE_DISCONNECTING == file_extension->state) { + return_status = -EBUSY; + goto out; + } + spin_lock(&file_extension->read_io_lock); + } + + kernel_priv_cb = file_extension->read_cb; + + if (!kernel_priv_cb) { + spin_unlock(&file_extension->read_io_lock); + return -ENODEV; + } + if (file_extension->reading_state != HECI_READ_COMPLETE) { + spin_unlock(&file_extension->read_io_lock); + return ESUCCESS; + } + spin_unlock(&file_extension->read_io_lock); + /* now copy the data to user space */ +copy_buffer: + DBG("kernel_priv_cb->response_buffer size - %d\n", kernel_priv_cb->response_buffer.size); + DBG("kernel_priv_cb->information - %lu\n", kernel_priv_cb->information); + if (length == 0 || ubuf == NULL || *offset > kernel_priv_cb->information) { + return_status = -EMSGSIZE; + goto free; + } + + /* length is being turncated to PAGE_SIZE, however, information size may be longer */ + length = (length < (kernel_priv_cb->information - *offset) ? + length : (kernel_priv_cb->information - *offset)); + + if (copy_to_user(ubuf, kernel_priv_cb->response_buffer.data + *offset, length)) { + return_status = -EFAULT; + goto free; + } + else { + return_status = length; + *offset += length; + if ((unsigned long)*offset < kernel_priv_cb->information) { + goto out; + } + } +free: + spin_lock_bh(&device->device_lock); + kernel_priv_cb_pos = find_read_list_entry(device, file_extension); + /* Remove entry from read list */ + if (kernel_priv_cb_pos != NULL) + list_del(&kernel_priv_cb_pos->cb_list); + spin_unlock_bh(&device->device_lock); + kfree(kernel_priv_cb->response_buffer.data); + kernel_priv_cb->response_buffer.data = NULL; + kfree(kernel_priv_cb); + kernel_priv_cb = NULL; + spin_lock(&file_extension->read_io_lock); + file_extension->reading_state = HECI_IDLE; + file_extension->read_cb = NULL; + file_extension->read_pending = FALSE; + spin_unlock(&file_extension->read_io_lock); +out: DBG("end heci read return_status= %d\n", return_status); + return return_status; +} + +/** + * heci_write - the write function. + */ +static ssize_t heci_write(struct file *file, const char __user * ubuf, + size_t length, loff_t * offset) +{ + int return_status = ESUCCESS; + __u8 i; + int if_num = MINOR((file->f_dentry->d_inode->i_rdev)); + struct heci_file_private *file_extension = file->private_data; + struct heci_cb_private *priv_write_cb = NULL; + struct heci_message_header heci_header; + struct iamt_heci_device *device = NULL; + unsigned long currtime = get_seconds(); + + if (!heci_device) + return -ENODEV; + device = pci_get_drvdata(heci_device); + + if ((if_num != HECI_MINOR_NUMBER) || (!device) || (!file_extension)) + return -ENODEV; + spin_lock_bh(&device->device_lock); + + if (device->heci_state != HECI_ENABLED) { + spin_unlock_bh(&device->device_lock); + return -ENODEV; + } + if (file_extension == &device->legacy_file_extension) { + priv_write_cb = find_pthi_read_list_entry(device, file, file_extension); + if ((priv_write_cb && currtime - priv_write_cb->read_time > LEGACY_READ_TIMER) || + (priv_write_cb && file_extension->reading_state == HECI_READ_COMPLETE)) { + *offset = 0; + list_del(&priv_write_cb->cb_list); + kfree(priv_write_cb->request_buffer.data); + kfree(priv_write_cb->response_buffer.data); + kfree(priv_write_cb); + } + } + + //free entry used in read + if (file_extension->reading_state == HECI_READ_COMPLETE) + { + *offset = 0; + priv_write_cb = find_read_list_entry(device, file_extension); + if ( priv_write_cb != NULL) { + list_del(&priv_write_cb->cb_list); + kfree(priv_write_cb->response_buffer.data); + priv_write_cb->response_buffer.data = NULL; + kfree(priv_write_cb); + priv_write_cb = NULL; + spin_lock(&file_extension->read_io_lock); + file_extension->reading_state = HECI_IDLE; + file_extension->read_cb = NULL; + file_extension->read_pending = FALSE; + spin_unlock(&file_extension->read_io_lock); + } + } + else if (file_extension->reading_state == HECI_IDLE && + file_extension->read_pending == FALSE){ + *offset = 0; + } + + spin_unlock_bh(&device->device_lock); + + priv_write_cb = kmalloc(sizeof(struct heci_cb_private), GFP_KERNEL); + if (!priv_write_cb) + return -ENOMEM; + spin_lock(&file_extension->file_lock); + priv_write_cb->request_buffer.data = NULL; + priv_write_cb->response_buffer.data = NULL; + priv_write_cb->file_object = file; + priv_write_cb->file_private = file_extension; + spin_unlock(&file_extension->file_lock); + priv_write_cb->request_buffer.data = kmalloc(length, GFP_KERNEL); + if (!priv_write_cb->request_buffer.data) { + kfree(priv_write_cb); + return -ENOMEM; + } + DBG("length =%d\n", (int) length); + + if (copy_from_user(priv_write_cb->request_buffer.data, + ubuf, length)) { + return_status = -EFAULT; + goto fail; + } + + spin_lock(&file_extension->file_lock); + file_extension->sm_state = 0; + if (length == 4 && + ((memcmp(heci_wd_state_independence_msg[0], ubuf, 4) == 0) || + (memcmp(heci_wd_state_independence_msg[1], ubuf, 4) == 0))) { + file_extension->sm_state |= HECI_WD_STATE_INDEPENDENCE_MSG_SENT; + } + spin_unlock(&file_extension->file_lock); + + INIT_LIST_HEAD(&priv_write_cb->cb_list); + if (file_extension == &device->legacy_file_extension) { + priv_write_cb->response_buffer.data = + kmalloc(LEGACY_MTU, GFP_KERNEL); + if (!priv_write_cb->response_buffer.data) { + return_status = -ENOMEM; + goto fail; + } + spin_lock_bh(&device->device_lock); + if (device->heci_state != HECI_ENABLED) { + spin_unlock_bh(&device->device_lock); + return_status = -ENODEV; + goto fail; + } + for (i = 0; i < device->num_heci_me_clients; i++) { + if (device->me_clients[i].client_id == + device->legacy_file_extension.me_client_id) + break; + } + + BUG_ON(device->me_clients[i].client_id != + file_extension->me_client_id); + if ((i == device->num_heci_me_clients) + || (device->me_clients[i].client_id != device->legacy_file_extension.me_client_id)) { + spin_unlock_bh(&device->device_lock); + return_status = -ENODEV; + goto fail; + } else if (length > device->me_clients[i].properteis.max_message_length || length <= 0) { + spin_unlock_bh(&device->device_lock); + return_status = -EMSGSIZE; + goto fail; + } + + + priv_write_cb->response_buffer.size = LEGACY_MTU; + priv_write_cb->major_file_operations = HECI_IOCTL; + priv_write_cb->information = 0; + priv_write_cb->request_buffer.size = length; + if (device->legacy_file_extension.state != HECI_FILE_CONNECTED) { + spin_unlock_bh(&device->device_lock); + return_status = -ENODEV; + goto fail; + } + + if (!list_empty(&device->pthi_cmd_list.heci_cb.cb_list) + || device->legacy_state != HECI_LEGACY_IDLE) { + DBG("pthi_state = %d\n", (int) device->legacy_state); + DBG("add PTHI cb to pthi cmd waiting list\n"); + list_add_tail(&priv_write_cb->cb_list, + &device->pthi_cmd_list.heci_cb. + cb_list); + return_status = length; + } else { + DBG("call pthi write"); + return_status = pthi_write(device, priv_write_cb); + + if (ESUCCESS != return_status) { + DBG("pthi write failed with status = %d\n", + return_status); + spin_unlock_bh(&device->device_lock); + goto fail; + }; + return_status = length; + } + spin_unlock_bh(&device->device_lock); + return return_status; + } + + priv_write_cb->major_file_operations = HECI_WRITE; + /* make sure information is zero before we start */ + + priv_write_cb->information = 0; + priv_write_cb->request_buffer.size = length; + + spin_lock(&file_extension->write_io_lock); + DBG("host client = %d, ME client = %d\n", + file_extension->host_client_id, file_extension->me_client_id); + if (file_extension->state != HECI_FILE_CONNECTED) { + return_status = -ENODEV; + DBG("host client = %d, is not connected to ME client = %d", + file_extension->host_client_id, + file_extension->me_client_id); + + goto unlock; + } + for (i = 0; i < device->num_heci_me_clients; i++) { + if (device->me_clients[i].client_id == + file_extension->me_client_id) + break; + } + BUG_ON(device->me_clients[i].client_id != file_extension->me_client_id); + if (i == device->num_heci_me_clients) { + return_status = -ENODEV; + goto unlock; + } + if (length > device->me_clients[i].properteis.max_message_length + || length <= 0) { + return_status = -EINVAL; + goto unlock; + } + priv_write_cb->file_private = file_extension; + + spin_lock_bh(&device->device_lock); + if (flow_control_credentials(device, file_extension) && + device->host_buffer_is_empty) { + spin_unlock_bh(&device->device_lock); + device->host_buffer_is_empty = FALSE; + if (length > ((((device->host_hw_state & H_CBD) >> 24) * sizeof(__u32)) - sizeof(struct heci_message_header))) { + heci_header.length = (((device->host_hw_state & H_CBD) >> 24) + * sizeof(__u32)) - sizeof(struct heci_message_header); + heci_header.message_complete = 0; + } else { + heci_header.length = length; + heci_header.message_complete = 1; + } + heci_header.host_address = file_extension->host_client_id; + heci_header.me_address = file_extension->me_client_id; + heci_header.reserved = 0; + DBG("call heci_write_message header=%08x.\n", + *((__u32 *) & heci_header)); + spin_unlock(&file_extension->write_io_lock); + /* protect heci low level write */ + spin_lock_bh(&device->device_lock); + if (!heci_write_message(device, &heci_header, (unsigned char *) (priv_write_cb->request_buffer.data), + heci_header.length)) { + spin_unlock_bh(&device->device_lock); + kfree(priv_write_cb->request_buffer.data); + priv_write_cb->request_buffer.data = NULL; + kfree(priv_write_cb); + return_status = -ENODEV; + priv_write_cb->information = 0; + return return_status; + } + file_extension->writing_state = HECI_WRITING; + priv_write_cb->information = heci_header.length; + if (heci_header.message_complete) { + flow_control_reduce(device, file_extension); + list_add_tail(&priv_write_cb->cb_list, + &device->write_waiting_list.heci_cb. + cb_list); + } else { + list_add_tail(&priv_write_cb->cb_list, + &device->write_list.heci_cb.cb_list); + } + spin_unlock_bh(&device->device_lock); + + } else { + + spin_unlock_bh(&device->device_lock); + priv_write_cb->information = 0; + file_extension->writing_state = HECI_WRITING; + spin_unlock(&file_extension->write_io_lock); + list_add_tail(&priv_write_cb->cb_list, + &device->write_list.heci_cb.cb_list); + } + return length; + +unlock: + spin_unlock(&file_extension->write_io_lock); +fail: + kfree(priv_write_cb->request_buffer.data); + priv_write_cb->request_buffer.data = NULL; + kfree(priv_write_cb->response_buffer.data); + priv_write_cb->response_buffer.data = NULL; + kfree(priv_write_cb); + return return_status; + +} + +/** + * heci_ioctl - the IOCTL function + */ +static int heci_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long data) +{ + + int return_status = ESUCCESS; + int if_num = MINOR(inode->i_rdev); + struct heci_file_private *file_extension = file->private_data; + struct heci_message_data *u_msg = (struct heci_message_data *) data; /* in user space */ + struct heci_message_data k_msg; /* all in kernel on the stack */ + struct iamt_heci_device *device = NULL; + + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + if (!heci_device) + return -ENODEV; + device = pci_get_drvdata(heci_device); + if (((if_num != LEGACY_MINOR_NUMBER) + && (if_num != HECI_MINOR_NUMBER)) || (!device) + || (!file_extension)) + return -ENODEV; + if (device->heci_state != HECI_ENABLED) + return -ENODEV; + /* first copy from user all data needed */ + if (copy_from_user(&k_msg, u_msg, sizeof(k_msg))) { + DBG("first copy from user all data needed filed\n"); + return -EFAULT; + } + DBG("user message size is %d\n", k_msg.size); + + switch (cmd) { + case IOCTL_HECI_GET_VERSION: + DBG(": IOCTL_HECI_GET_VERSION\n"); + return_status = + heci_ioctl_get_version(device, if_num, u_msg, k_msg, + file_extension); + break; + case IOCTL_HECI_CONNECT_CLIENT: + DBG(": IOCTL_HECI_CONNECT_CLIENT.\n"); + return_status = + heci_ioctl_connect_client(device, if_num, u_msg, k_msg, + file); + break; + case IOCTL_HECI_WD: + DBG(": IOCTL_HECI_WD.\n"); + return_status = + heci_ioctl_wd(device, if_num, k_msg, file_extension); + break; + case IOCTL_HECI_BYPASS_WD: + DBG(":IOCTL_HECI_BYPASS_WD.\n"); + return_status = + heci_ioctl_bypass_wd(device,if_num,k_msg,file_extension); + break; + case IAMT_KCS_SEND_MESSAGE_COMMAND: + DBG(": IAMT_KCS_SEND_MESSAGE_COMMAND.\n"); + return_status = + legacy_ioctl_send_message(device, if_num, k_msg, file); + break; + case IAMT_KCS_RECEIVE_MESSAGE_COMMAND: + DBG(": IAMT_KCS_RECEIVE_MESSAGE_COMMAND.\n"); + return_status = + legacy_ioctl_receive_message(device, if_num, u_msg, + k_msg, file); + break; + + default: + return_status = -EINVAL; + break; + } + return return_status; +} + +/** + * heci_legacy_poll - the poll function + */ +static unsigned int heci_legacy_poll(struct file *file, poll_table * wait) +{ + int if_num = MINOR((file->f_dentry->d_inode->i_rdev)); + unsigned int mask = 0; + struct iamt_heci_device *device = NULL; + struct heci_file_private *file_extension = file->private_data; + + + if (!heci_device || !file_extension) + return mask; + + device = pci_get_drvdata(heci_device); + + if ((if_num != LEGACY_MINOR_NUMBER) || (!device)) + return mask; + + spin_lock_bh(&device->device_lock); + if (device->heci_state != HECI_ENABLED){ + spin_unlock_bh(&device->device_lock); + return mask; + } + spin_unlock_bh(&device->device_lock); + if (file_extension == &device->legacy_file_extension) { + + poll_wait(file, &device->legacy_file_extension.wait, wait); + spin_lock(&device->legacy_file_extension.file_lock); + if (device->legacy_state == HECI_LEGACY_READ_COMPLETE + && device->legacy_file_object == file) { + mask |= (POLLIN | POLLRDNORM); + spin_lock_bh(&device->device_lock); + DBG("run next pthi legacy cb\n"); + run_next_legacy_cmd(device); + spin_unlock_bh(&device->device_lock); + } + spin_unlock(&device->legacy_file_extension.file_lock); + } + return mask; +} + +/** + * heci_poll - the poll function + */ +static unsigned int heci_poll(struct file *file, poll_table * wait) +{ + int if_num = MINOR((file->f_dentry->d_inode->i_rdev)); + unsigned int mask = 0; + struct heci_file_private *file_extension = file->private_data; + struct iamt_heci_device *device = NULL; + + if (!heci_device) + return mask; + + + device = pci_get_drvdata(heci_device); + + if ((if_num != HECI_MINOR_NUMBER) || (!device) + || (!file_extension)) + return mask; + + spin_lock_bh(&device->device_lock); + if (device->heci_state != HECI_ENABLED){ + spin_unlock_bh(&device->device_lock); + return mask; + + } + spin_unlock_bh(&device->device_lock); + if (file_extension == &device->legacy_file_extension) { + + + poll_wait(file, &device->legacy_file_extension.wait, wait); + spin_lock(&device->legacy_file_extension.file_lock); + if (device->legacy_state == HECI_LEGACY_READ_COMPLETE + && device->legacy_file_object == file) { + mask |= (POLLIN | POLLRDNORM); + spin_lock_bh(&device->device_lock); + DBG("run next pthi cb"); + run_next_legacy_cmd(device); + spin_unlock_bh(&device->device_lock); + } + spin_unlock(&device->legacy_file_extension.file_lock); + + } else{ + poll_wait(file, &file_extension->tx_wait, wait); + spin_lock(&file_extension->write_io_lock); + if (HECI_WRITE_COMPLETE == file_extension->writing_state) + mask |= (POLLIN | POLLRDNORM); + spin_unlock(&file_extension->write_io_lock); + } + return mask; +} + +#ifdef CONFIG_PM +static int heci_suspend(struct pci_dev* pdev, pm_message_t state) +{ + struct iamt_heci_device *device = pci_get_drvdata(pdev); + int err = 0; + + //Stop watchdog if exists + del_timer_sync(&device->wd_timer); + if (device->wd_file_extension.state == HECI_FILE_CONNECTED + && device->wd_timeout) { + spin_lock_bh(&device->device_lock); + g_sus_wd_timeout = device->wd_timeout; + device->wd_timeout = 0; + device->wd_due_counter = 0; + memcpy(device->wd_data, stop_wd_params, HECI_WD_PARAMS_SIZE); + device->stop = TRUE; + if (device->host_buffer_is_empty && + flow_control_credentials(device, &device->wd_file_extension)) { + device->host_buffer_is_empty = FALSE; + + if (!heci_send_wd(device)) + DBG("Send stop WD failed\n"); + else + flow_control_reduce(device, &device->wd_file_extension); + device->wd_pending = FALSE; + } else { + device->wd_pending = TRUE; + } + spin_unlock_bh(&device->device_lock); + device->wd_stoped = FALSE; + + err = + wait_event_interruptible_timeout(device->wait_stop_wd, + (TRUE == device->wd_stoped), 10 * HZ); + if (!device->wd_stoped) + DBG("stop wd failed to complete.\n"); + else { + DBG("stop wd complete %d.\n", err); + err = 0; + } + } + //Set new heci state + spin_lock_bh(&device->device_lock); + if (device->heci_state == HECI_ENABLED || + device->heci_state == HECI_RECOVERING_FROM_RESET) { + device->heci_state = HECI_POWER_DOWN; + heci_reset(device, FALSE); + } + spin_unlock_bh(&device->device_lock); + + pci_save_state(pdev); + + + pci_disable_device(pdev); + free_irq(pdev->irq, device); + + pci_set_power_state(pdev, PCI_D3hot); + + return err; +} + +static int heci_resume(struct pci_dev* pdev) +{ + struct iamt_heci_device *device = NULL; + int err = 0; + + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + + device = pci_get_drvdata(pdev); + if (!device) { + return -ENODEV; + } + + /* request and enable interrupt */ + device->irq = pdev->irq; + err = request_irq(device->irq, heci_isr_interrupt, IRQF_SHARED, + heci_driver_name, device); + if (err) { + HECI_ERR("Request_irq failure. irq = %d \n", device->irq); + return err; + } + + spin_lock_bh(&device->device_lock); + device->heci_state = HECI_POWER_UP; + heci_reset(device, TRUE); + spin_unlock_bh(&device->device_lock); + + //Start watchdog if stopped in suspend + if (g_sus_wd_timeout != 0) { + device->wd_timeout = g_sus_wd_timeout; + + memcpy(device->wd_data, start_wd_params, HECI_WD_PARAMS_SIZE); + memcpy(device->wd_data + HECI_WD_PARAMS_SIZE, &device->wd_timeout, + sizeof(__u16)); + device->wd_due_counter = 1; + + if (device->wd_timeout) + mod_timer(&device->wd_timer, jiffies); + g_sus_wd_timeout = 0; + } + return err; +} +#endif +MODULE_AUTHOR("Intel Corporation"); /* FIXME: Add email address here */ +MODULE_DESCRIPTION("Intel(R) AMT Management Interface"); +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_VERSION(DRIVER_VERSION); --- linux-2.6.28.orig/ubuntu/heci/io_heci.c +++ linux-2.6.28/ubuntu/heci/io_heci.c @@ -0,0 +1,1138 @@ +/* + * Part of Intel(R) Manageability Engine Interface Linux driver + * + * Copyright (c) 2003 - 2007 Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "heci_data_structures.h" +#include "heci.h" +#include "heci_interface.h" +#include "version.h" + + +/** + * heci_ioctl_get_version - the get driver version IOCTL function + * @device_object -Device object for our driver + * @if_num minor number + * @*u_msg pointer to user data struct in user space + * @k_msg data in kernel on the stack + * @file_extension -extension of the file object + * + * @return : + * 0 on success, + * negative on failure. + */ +int heci_ioctl_get_version(struct iamt_heci_device * device, int if_num, + struct heci_message_data *u_msg, + struct heci_message_data k_msg, + struct heci_file_private * file_extension) +{ + + int return_status = ESUCCESS; + struct heci_driver_version *version; + struct heci_message_data res_msg; + res_msg.data = NULL; + if ((if_num != HECI_MINOR_NUMBER) || (!device) + || (!file_extension)) + return -ENODEV; + + + if (k_msg.size < (sizeof(struct heci_driver_version) - 2)) { + DBG("user buffer less than heci_driver_version.\n"); + return -EMSGSIZE; + } + + res_msg.data = kmalloc(sizeof(struct heci_driver_version), GFP_KERNEL); + if (!res_msg.data) { + DBG("failed allocation response buffer size = %d.\n", + (int) sizeof(struct heci_driver_version)); + return -ENOMEM; + + } + version = (struct heci_driver_version *) res_msg.data; + version->major = MAJOR_VERSION; + version->minor = MINOR_VERSION; + version->hotfix = QUICK_FIX_NUMBER; + if (k_msg.size < sizeof(struct heci_driver_version)) { + res_msg.size = sizeof(struct heci_driver_version) - 2; + } else { + version->build = VER_BUILD; + res_msg.size = sizeof(struct heci_driver_version); + } + return_status = file_extension->status; + /* now copy the data to user space */ + if (copy_to_user(k_msg.data, res_msg.data, res_msg.size)) { + return_status = -EFAULT; + goto end; + } + if (put_user(res_msg.size, &u_msg->size)) { + return_status = -EFAULT; + goto end; + } +end: + kfree(res_msg.data); + return return_status; +} + +/** + * heci_ioctl_connect_client - the connect to fw client IOCTL function + * @device_object -Device object for our driver + * @if_num minor number + * @*u_msg pointer to user data struct in user space + * @k_msg data in kernel on the stack + * @file_extension -extension of the file object + * + * @return : + * 0 on success, + * negative on failure. + */ +int heci_ioctl_connect_client(struct iamt_heci_device * device, int if_num, + struct heci_message_data *u_msg, + struct heci_message_data k_msg, + struct file *file) +{ + + int return_status = ESUCCESS; + struct heci_message_data req_msg, res_msg; + struct heci_cb_private *kernel_priv_cb = NULL; + struct heci_client *client; + struct heci_file_private *file_extension = NULL; + struct heci_file_private *file_extension_pos = NULL; + struct heci_file_private *file_extension_next = NULL; + struct heci_file_private *file_extension_list_temp = NULL; + + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + long timeout = 15; /*15 second */ + __u8 i; + int err = 0; + res_msg.data = NULL; + req_msg.data = NULL; + if ((if_num != HECI_MINOR_NUMBER) || (!device) + || (!file)) + return -ENODEV; + file_extension = file->private_data; + if (!file_extension) + return -ENODEV; + if (k_msg.size != sizeof(struct guid)) { + DBG("user buffer size is not equal to size of struct guid(16).\n"); + return -EMSGSIZE; + } + req_msg.data = kmalloc(sizeof(struct guid), GFP_KERNEL); + res_msg.data = kmalloc(sizeof(struct heci_client), GFP_KERNEL); + + + if (!res_msg.data) { + DBG("failed allocation response buffer size = %d.\n", + (int) sizeof(struct heci_client)); + if (req_msg.data) { + kfree(req_msg.data); + req_msg.data = NULL; + goto fail; + } + } + if (!req_msg.data) { + DBG("failed allocation request buffer size = %d.\n", + (int) sizeof(struct guid)); + if (res_msg.data) { + kfree(res_msg.data); + res_msg.data = NULL; + goto fail; + } + fail: + return -ENOMEM; + } + req_msg.size = sizeof(struct guid); + res_msg.size = sizeof(struct heci_client); + if (!k_msg.data) { + return_status = -EIO; + goto end; + } + + /* copy the message to kernel space - use a pointer already copied into kernel space */ + if (copy_from_user(req_msg.data, k_msg.data, k_msg.size)) { + return_status = -EFAULT; + goto end; + } + /* buffered ioctl cb */ + kernel_priv_cb = + kmalloc(sizeof(struct heci_cb_private), GFP_KERNEL); + if (!kernel_priv_cb) { + return_status = -ENOMEM; + goto end; + } + INIT_LIST_HEAD(&kernel_priv_cb->cb_list); + kernel_priv_cb->response_buffer.data = res_msg.data; + kernel_priv_cb->response_buffer.size = res_msg.size; + kernel_priv_cb->request_buffer.data = req_msg.data; + kernel_priv_cb->request_buffer.size = req_msg.size; + kernel_priv_cb->major_file_operations = HECI_IOCTL; + spin_lock_bh(&device->device_lock); + if (device->heci_state != HECI_ENABLED) { + return_status = -ENODEV; + spin_unlock_bh(&device->device_lock); + goto end; + } + if ((file_extension->state != HECI_FILE_INITIALIZING) && + (file_extension->state != HECI_FILE_DISCONNECTED)) { + return_status = -EBUSY; + spin_unlock_bh(&device->device_lock); + goto end; + } + + /* find ME client we're trying to connect to */ + for (i = 0; i < device->num_heci_me_clients; i++) { + if (0 == memcmp((struct guid *) req_msg.data, + &device->me_clients[i].properteis.protocol_name, + sizeof(struct guid))) { + if (device->me_clients[i].properteis.fixed_address == 0) { + file_extension->me_client_id = + device->me_clients[i].client_id; + file_extension->state = + HECI_FILE_CONNECTING; + } + break; + } + } + /*if we're connecting to PTHI client so we will use the exist connection */ + if (0 == memcmp((struct guid *) req_msg.data, &heci_pthi_guid, + sizeof(struct guid))) { + + if (device->legacy_file_extension.state != HECI_FILE_CONNECTED) { + return_status = -ENODEV; + spin_unlock_bh(&device->device_lock); + goto end; + } + device->heci_host_clients[file_extension->host_client_id / 8] &= + ~(1 << (file_extension->host_client_id % 8)); + list_for_each_entry_safe(file_extension_pos, file_extension_next, &device->file_list, link) { + if ((file_extension->host_client_id == + file_extension_pos->host_client_id) + && (file_extension->me_client_id == + file_extension_pos->me_client_id)) { + + DBG("remove file extension node host client = %d, ME client = %d\n", + file_extension_pos->host_client_id, + file_extension_pos->me_client_id); + list_del(&file_extension_pos->link); + } + + } + DBG("free file extension memory\n"); + kfree(file_extension); + file_extension = NULL; + file->private_data = &device->legacy_file_extension; + client = (struct heci_client *) res_msg.data; + client->max_message_length = + device->me_clients[i].properteis.max_message_length; + client->protocol_version = + device->me_clients[i].properteis.protocol_version; + return_status = device->legacy_file_extension.status; + spin_unlock_bh(&device->device_lock); + + /* now copy the data to user space */ + if (copy_to_user(k_msg.data, res_msg.data, res_msg.size)) { + return_status = -EFAULT; + goto end; + } + if (put_user(res_msg.size, &u_msg->size)) { + return_status = -EFAULT; + goto end; + } + goto end; + } + spin_lock(&file_extension->file_lock); + if (file_extension->state != HECI_FILE_CONNECTING) { + return_status = -ENODEV; + spin_unlock(&file_extension->file_lock); + spin_unlock_bh(&device->device_lock); + goto end; + } + spin_unlock(&file_extension->file_lock); + /* prepare the output buffer */ + client = (struct heci_client *) res_msg.data; + client->max_message_length = + device->me_clients[i].properteis.max_message_length; + client->protocol_version = + device->me_clients[i].properteis.protocol_version; + if (device->host_buffer_is_empty + && !other_client_is_connecting(device, file_extension)) { + device->host_buffer_is_empty = FALSE; + if (!heci_connect(device, file_extension)) { + return_status = -ENODEV; + spin_unlock_bh(&device->device_lock); + goto end; + } else { + file_extension->timer_count = CONNECT_TIMEOUT; + kernel_priv_cb->file_private = file_extension; + list_add_tail(&kernel_priv_cb->cb_list, + &device->control_read_list.heci_cb. + cb_list); + } + + + } else { + kernel_priv_cb->file_private = file_extension; + DBG("add connect cb to control write list\n"); + list_add_tail(&kernel_priv_cb->cb_list, + &device->control_write_list.heci_cb.cb_list); + } + spin_unlock_bh(&device->device_lock); + err = + wait_event_timeout(device->wait_received_message, + (HECI_FILE_CONNECTED == file_extension->state || HECI_FILE_DISCONNECTED == file_extension->state), + timeout * HZ); + if (HECI_FILE_CONNECTED == file_extension->state) { + DBG("successfully to connect to FW client.\n"); + return_status = file_extension->status; + /* now copy the data to user space */ + if (copy_to_user(k_msg.data, res_msg.data, res_msg.size)) { + return_status = -EFAULT; + goto end; + } + if (put_user(res_msg.size, &u_msg->size)) { + return_status = -EFAULT; + goto end; + } + goto end; + } else { + DBG("failed to connect to FW client.file_extension->state = %d\n", file_extension->state); + if (!err) + DBG("wait_event_interruptible_timeout failed on client connect message fw response message\n"); + + return_status = -EFAULT; + goto remove_list; + } + +remove_list: + if (kernel_priv_cb) { + spin_lock_bh(&device->device_lock); + if (device->control_read_list.status == ESUCCESS + && !list_empty(&device->control_read_list.heci_cb.cb_list)) { + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device->control_read_list.heci_cb.cb_list, cb_list){ + file_extension_list_temp = + (struct heci_file_private *) + kernel_priv_cb_pos->file_private; + if (file_extension_list_temp) { + if ((file_extension->host_client_id == file_extension_list_temp->host_client_id) + && (file_extension->me_client_id == file_extension_list_temp->me_client_id)) + list_del(&kernel_priv_cb_pos->cb_list); + + } + + } + } + if (device->control_write_list.status == ESUCCESS + && !list_empty(&device->control_write_list.heci_cb.cb_list)) { + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device->control_write_list.heci_cb.cb_list, cb_list){ + file_extension_list_temp = + (struct heci_file_private *) + kernel_priv_cb_pos->file_private; + if (file_extension_list_temp) { + if ((file_extension->host_client_id == file_extension_list_temp->host_client_id) + && (file_extension->me_client_id == file_extension_list_temp->me_client_id)) + list_del(&kernel_priv_cb_pos->cb_list); + + } + + } + } + spin_unlock_bh(&device->device_lock); + } +end: + DBG("free connect cb memory"); + kfree(req_msg.data); + req_msg.data = NULL; + kfree(res_msg.data); + res_msg.data = NULL; + kfree(kernel_priv_cb); + kernel_priv_cb = NULL; + return return_status; +} + +/** + * heci_ioctl_wd - the wd IOCTL function + * @device_object -Device object for our driver + * @if_num minor number + * @k_msg data in kernel on the stack + * @file_extension -extension of the file object + * + * @return : + * 0 on success, + * negative on failure. + */ +int heci_ioctl_wd(struct iamt_heci_device * device, int if_num, + struct heci_message_data k_msg, + struct heci_file_private * file_extension) +{ + int return_status = ESUCCESS; + struct heci_message_data req_msg; /*in kernel on the stack */ + if (if_num != HECI_MINOR_NUMBER) + return -ENODEV; + spin_lock(&file_extension->file_lock); + if (k_msg.size != HECI_WATCHDOG_DATA_SIZE) { + DBG("User buffer has invalid size.\n"); + spin_unlock(&file_extension->file_lock); + return -EMSGSIZE; + } + spin_unlock(&file_extension->file_lock); + req_msg.data = kmalloc(HECI_WATCHDOG_DATA_SIZE, GFP_KERNEL); + if (!req_msg.data) { + DBG("failed allocation request buffer size = %d.\n", + HECI_WATCHDOG_DATA_SIZE); + return -ENOMEM; + } + req_msg.size = HECI_WATCHDOG_DATA_SIZE; + + /* copy the message to kernel space - use a pointer already copied into kernel space */ + if (copy_from_user(req_msg.data, k_msg.data, req_msg.size)) { + return_status = -EFAULT; + goto end; + } + spin_lock_bh(&device->device_lock); + if (device->heci_state != HECI_ENABLED) { + return_status = -ENODEV; + spin_unlock_bh(&device->device_lock); + goto end; + } + + if (device->wd_file_extension.state != HECI_FILE_CONNECTED) { + return_status = -ENODEV; + spin_unlock_bh(&device->device_lock); + goto end; + } + if (!device->asf_mode) { + return_status = -EIO; + spin_unlock_bh(&device->device_lock); + goto end; + } + + memcpy(&device->wd_data[HECI_WD_PARAMS_SIZE], req_msg.data, + HECI_WATCHDOG_DATA_SIZE); + + device->wd_timeout = (req_msg.data[1] << 8) + + req_msg.data[0]; + if (device->wd_timeout == 0) { + memcpy(device->wd_data, &stop_wd_params, + HECI_WD_PARAMS_SIZE); + device->wd_pending = FALSE; + device->wd_due_counter = 1; /* next timer */ + } else { + memcpy(device->wd_data, &start_wd_params, + HECI_WD_PARAMS_SIZE); + device->wd_pending = FALSE; + device->wd_due_counter = 1; + } + spin_unlock_bh(&device->device_lock); +end: + kfree(req_msg.data); + req_msg.data = NULL; + return return_status; +} + + +/** + * heci_ioctl_bypass_wd - the bypass_wd IOCTL function + * @device_object -Device object for our driver + * @if_num minor number + * @k_msg data in kernel on the stack + * @file_extension -extension of the file object + * + * @return : + * 0 on success, + * negative on failure. + */ +int heci_ioctl_bypass_wd(struct iamt_heci_device * device, int if_num, + struct heci_message_data k_msg, + struct heci_file_private * file_extension) +{ + __u8 flag=0; + int return_status = ESUCCESS; + + if (if_num != HECI_MINOR_NUMBER) + return -ENODEV; + spin_lock(&file_extension->file_lock); + if (k_msg.size < 1) { + DBG("user buffer less than HECI_WATCHDOG_DATA_SIZE .\n"); + spin_unlock(&file_extension->file_lock); + return -EMSGSIZE; + } + spin_unlock(&file_extension->file_lock); + if (copy_from_user(&flag,k_msg.data,1)) { + return_status = -EFAULT; + goto end; + } + + spin_lock_bh(&device->device_lock); + flag = flag ?(TRUE):(FALSE); + device->wd_bypass = flag; + spin_unlock_bh(&device->device_lock); +end: + return return_status; +} + + +/** + * legacy_ioctl_send_message - send command data to pthi client + * @device_object -Device object for our driver + * @if_num minor number + * @*u_msg pointer to user data struct in user space + * @k_msg data in kernel on the stack + * @file_extension -extension of the file object + * + * @return : + * 0 on success, + * negative on failure. + */ +int legacy_ioctl_send_message(struct iamt_heci_device * device, int if_num, + struct heci_message_data k_msg, + struct file *file) +{ + + int return_status = ESUCCESS; + struct heci_message_data req_msg, res_msg; /*in kernel on the stack */ + struct heci_cb_private *kernel_priv_cb = NULL; + struct heci_file_private *file_extension = file->private_data; + __u8 i; + req_msg.data = NULL; + res_msg.data = NULL; + if ((if_num != LEGACY_MINOR_NUMBER) || (!device)) + return -ENODEV; + if (!file_extension) + return -ENODEV; + spin_lock_bh(&device->device_lock); + for (i = 0; i < device->num_heci_me_clients; i++) { + if (device->me_clients[i].client_id == + device->legacy_file_extension.me_client_id) + break; + } + + BUG_ON(device->me_clients[i].client_id != file_extension->me_client_id); + if ((i == device->num_heci_me_clients) + || (device->me_clients[i].client_id != + device->legacy_file_extension.me_client_id)) { + spin_unlock_bh(&device->device_lock); + return -ENODEV; + } else if (k_msg.size > + device->me_clients[i].properteis.max_message_length + || k_msg.size <= 0) { + spin_unlock_bh(&device->device_lock); + return -EMSGSIZE; + } + + + spin_unlock_bh(&device->device_lock); + req_msg.data = kmalloc(k_msg.size, GFP_KERNEL); + res_msg.data = kmalloc(LEGACY_MTU, GFP_KERNEL); + + if (!res_msg.data) { + DBG("failed allocation response buffer size = %d.\n", + (int) sizeof(struct heci_client)); + if (req_msg.data) { + + kfree(req_msg.data); + req_msg.data = NULL; + return -ENOMEM; + } + } + if (!req_msg.data) { + DBG("failed allocation request buffer size = %d.\n", + (int) sizeof(struct guid)); + if (res_msg.data) { + kfree(res_msg.data); + res_msg.data = NULL; + return -ENOMEM; + } + } + req_msg.size = k_msg.size; + res_msg.size = LEGACY_MTU; + if (!k_msg.data) { + return_status = -EIO; + goto end; + } + + /* copy the message to kernel space - use a pointer already copied into kernel space */ + if (copy_from_user(req_msg.data, k_msg.data, k_msg.size)) { + return_status = -EFAULT; + goto end; + } + /* buffered ioctl cb */ + kernel_priv_cb = + kmalloc(sizeof(struct heci_cb_private), GFP_KERNEL); + if (!kernel_priv_cb) { + return_status = -ENOMEM; + goto end; + } + INIT_LIST_HEAD(&kernel_priv_cb->cb_list); + + kernel_priv_cb->request_buffer.data = req_msg.data; + kernel_priv_cb->request_buffer.size = req_msg.size; + kernel_priv_cb->response_buffer.data = res_msg.data; + kernel_priv_cb->response_buffer.size = res_msg.size; + kernel_priv_cb->major_file_operations = HECI_IOCTL; + kernel_priv_cb->information = 0; + kernel_priv_cb->file_object = file; + kernel_priv_cb->file_private = file_extension; + spin_lock_bh(&device->device_lock); + + if (device->heci_state != HECI_ENABLED) { + return_status = -ENODEV; + spin_unlock_bh(&device->device_lock); + goto end; + } + if (device->legacy_file_extension.state != HECI_FILE_CONNECTED) { + return_status = -ENODEV; + spin_unlock_bh(&device->device_lock); + goto end; + } + + + if (!list_empty(&device->pthi_cmd_list.heci_cb.cb_list) + || device->legacy_state != HECI_LEGACY_IDLE) { + DBG("pthi_state = %d\n", (int) device->legacy_state); + DBG("add PTHI cb to pthi cmd waiting list"); + list_add_tail(&kernel_priv_cb->cb_list, + &device->pthi_cmd_list.heci_cb.cb_list); + + } else { + DBG("call pthi write\n"); + return_status = pthi_write(device, kernel_priv_cb); + + if (ESUCCESS != return_status) { + DBG("pthi write failed with status = %d\n", + return_status); + spin_unlock_bh(&device->device_lock); + goto end; + } + } + spin_unlock_bh(&device->device_lock); + return return_status; +end: + kfree(req_msg.data); + req_msg.data = NULL; + kfree(res_msg.data); + res_msg.data = NULL; + kfree(kernel_priv_cb); + kernel_priv_cb = NULL; + return return_status; +} + + +/** + * legacy_ioctl_receive_message - receive command data from pthi client + * @device_object -Device object for our driver + * @if_num minor number + * @*u_msg pointer to user data struct in user space + * @k_msg data in kernel on the stack + * @file_extension -extension of the file object + * + * @return : + * 0 on success, + * negative on failure. + */ +int legacy_ioctl_receive_message(struct iamt_heci_device * device, int if_num, + struct heci_message_data *u_msg, + struct heci_message_data k_msg, + struct file *file) +{ + + int return_status = ESUCCESS; + struct heci_message_data req_msg, res_msg; + struct heci_cb_private *kernel_priv_cb = NULL; + struct heci_file_private *file_extension = file->private_data; + __u8 i; + struct heci_file_private *file_extension_list_temp = NULL; + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + + + res_msg.data = NULL; + req_msg.data = NULL; + + if ((if_num != LEGACY_MINOR_NUMBER) || (!device)) + return -ENODEV; + spin_lock_bh(&device->device_lock); + if (!file_extension) { + spin_unlock_bh(&device->device_lock); + return -ENODEV; + } + for (i = 0; i < device->num_heci_me_clients; i++) + if (device->me_clients[i].client_id == + device->legacy_file_extension.me_client_id) + break; + + BUG_ON(device->me_clients[i].client_id != + file_extension->me_client_id); + if ((i == device->num_heci_me_clients) + || (device->me_clients[i].client_id != + device->legacy_file_extension.me_client_id)) { + spin_unlock_bh(&device->device_lock); + return -ENODEV; + } + + if (device->pthi_read_complete_list.status == ESUCCESS) { + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device->pthi_read_complete_list.heci_cb.cb_list, cb_list){ + file_extension_list_temp = + (struct heci_file_private *) + kernel_priv_cb_pos->file_private; + if (file_extension_list_temp) { + if ((file_extension == &device->legacy_file_extension) + && (kernel_priv_cb_pos->file_object == file)) { + list_del(&kernel_priv_cb_pos->cb_list); + kernel_priv_cb = + kernel_priv_cb_pos; + break; + } + } + + } + } + if (!kernel_priv_cb) { + spin_unlock_bh(&device->device_lock); + return -EAGAIN; + } + + + res_msg.data = kernel_priv_cb->response_buffer.data; + res_msg.size = kernel_priv_cb->response_buffer.size; + req_msg.data = kernel_priv_cb->request_buffer.data; + req_msg.size = kernel_priv_cb->request_buffer.size; + DBG("pthi kernel_priv_cb->response_buffer size - %d\n", + kernel_priv_cb->response_buffer.size); + DBG("pthi kernel_priv_cb->information - %lu\n", + kernel_priv_cb->information); + spin_unlock_bh(&device->device_lock); + + if (res_msg.size < kernel_priv_cb->information) { + return_status = -EMSGSIZE; + goto end; + } + /* now copy the data to user space */ + if (copy_to_user(k_msg.data, + res_msg.data, + kernel_priv_cb->information)) { + return_status = -EFAULT; + goto end; + } + if (put_user(kernel_priv_cb->information, &u_msg->size)) { + return_status = -EFAULT; + goto end; + } +end: + kfree(req_msg.data); + kfree(res_msg.data); + kfree(kernel_priv_cb); + return return_status; +} + +/** + * find_pthi_read_list_entry - finds a PTHIlist entry for current file + * @device_object -Device object for our driver + * + * @return : + * returned a list entry on success, + * NULL on failure. + */ +struct heci_cb_private* find_pthi_read_list_entry(struct iamt_heci_device* device, + struct file* file, struct heci_file_private* file_extension) +{ + struct heci_file_private *file_extension_list_temp = NULL; + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + + if (device->pthi_read_complete_list.status == ESUCCESS + && !list_empty(&device->pthi_read_complete_list.heci_cb. + cb_list)) { + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device->pthi_read_complete_list.heci_cb.cb_list, cb_list){ + file_extension_list_temp = + (struct heci_file_private *) + kernel_priv_cb_pos->file_private; + if (file_extension_list_temp) { + if ((file_extension == &device->legacy_file_extension) + && (kernel_priv_cb_pos->file_object == file)) { + return kernel_priv_cb_pos; + } + } + } + } + return NULL; +} +/** + * pthi_read - read data from pthi client + * @device_object -Device object for our driver + * @if_num minor number + * @*u_msg pointer to user data in user space + * @length-user data length + * + * @return : + * returned data length on success, + * zero if no data to read, + * negative on failure. + */ +int pthi_read(struct iamt_heci_device * device, int if_num, struct file *file, + char *ubuf, size_t length, loff_t * offset) +{ + + int return_status = ESUCCESS; + struct heci_cb_private *kernel_priv_cb = NULL; + struct heci_file_private *file_extension = file->private_data; + __u8 i; + unsigned long currtime = get_seconds(); + + if ((if_num != HECI_MINOR_NUMBER) || (!device)) + return -ENODEV; + + if (!file_extension) + return -ENODEV; + + spin_lock_bh(&device->device_lock); + for (i = 0; i < device->num_heci_me_clients; i++) + if (device->me_clients[i].client_id == + device->legacy_file_extension.me_client_id) + break; + BUG_ON(device->me_clients[i].client_id != file_extension->me_client_id); + if ((i == device->num_heci_me_clients) + || (device->me_clients[i].client_id != + device->legacy_file_extension.me_client_id)) { + DBG("PTHI client not found\n"); + spin_unlock_bh(&device->device_lock); + return -ENODEV; + } + kernel_priv_cb = find_pthi_read_list_entry(device, file, file_extension); + if (!kernel_priv_cb) { + spin_unlock_bh(&device->device_lock); + return 0; /* No more data to read */ + } + else { + /* 15 sec for the message has expired */ + if (kernel_priv_cb && currtime - kernel_priv_cb->read_time > LEGACY_READ_TIMER) { + list_del(&kernel_priv_cb->cb_list); + spin_unlock_bh(&device->device_lock); + return_status = -ETIMEDOUT; + goto free; + } + /* if the whole message will fit remove it from the list */ + if ((kernel_priv_cb->information >= *offset) && + (length >= (kernel_priv_cb->information - *offset))) { + list_del(&kernel_priv_cb->cb_list); + } + /* end of the message has been reached */ + else if ((kernel_priv_cb->information > 0) && + (kernel_priv_cb->information <= *offset)) { + list_del(&kernel_priv_cb->cb_list); + return_status = 0; + spin_unlock_bh(&device->device_lock); + goto free; + } + /* else means that not full buffer will be read and do not remove message from deletion list */ + } + DBG("pthi kernel_priv_cb->response_buffer size - %d\n", + kernel_priv_cb->response_buffer.size); + DBG("pthi kernel_priv_cb->information - %lu\n", + kernel_priv_cb->information); + spin_unlock_bh(&device->device_lock); + + /* length is being turncated to PAGE_SIZE, however, the information may be longer */ + length = length < (kernel_priv_cb->information - *offset) ? + length : (kernel_priv_cb->information - *offset); + + if (copy_to_user + (ubuf, kernel_priv_cb->response_buffer.data + *offset, length)) { + return_status = -EFAULT; + } else { + return_status = length; + if ((*offset + length) < kernel_priv_cb->information) { + *offset += length; + goto out; + } + } + DBG("free pthi cb memory\n"); +free: + *offset = 0; + kfree(kernel_priv_cb->request_buffer.data); + kfree(kernel_priv_cb->response_buffer.data); + kfree(kernel_priv_cb); +out: + return return_status; +} + +/** + * heci_start_read - the start read client message function. + * @device_object -Device object for our driver + * @if_num minor number + * @file_extension -extension of the file object + * + * @return : + * 0 on success, + * negative on failure. + */ +int heci_start_read(struct iamt_heci_device * device, int if_num, + struct heci_file_private * file_extension) +{ + int return_status = ESUCCESS; + __u8 i; + struct heci_cb_private *priv_cb = NULL; + if ((if_num != HECI_MINOR_NUMBER) || (!device) + || (!file_extension)) { + DBG("receive wrong function input param\n."); + return -ENODEV; + } + if (file_extension->state != HECI_FILE_CONNECTED) + return -ENODEV; + spin_lock_bh(&device->device_lock); + if (device->heci_state != HECI_ENABLED) { + spin_unlock_bh(&device->device_lock); + return -ENODEV; + } + spin_unlock_bh(&device->device_lock); + DBG("check if read is pending\n"); + if (file_extension->read_pending + || file_extension->read_cb != NULL) { + DBG("read is pending"); + return -EBUSY; + } + priv_cb = kmalloc(sizeof(struct heci_cb_private), GFP_KERNEL); + if (!priv_cb) + return -ENOMEM; + + DBG("allocation call back success\n"); + DBG("host client = %d, ME client = %d\n", + file_extension->host_client_id, file_extension->me_client_id); + spin_lock_bh(&device->device_lock); + for (i = 0; i < device->num_heci_me_clients; i++) + if (device->me_clients[i].client_id == + file_extension->me_client_id) + break; + + BUG_ON(device->me_clients[i].client_id != + file_extension->me_client_id); + if ((i == device->num_heci_me_clients)) { + return_status = -ENODEV; + goto unlock; + } + + priv_cb->response_buffer.size = + device->me_clients[i].properteis.max_message_length; + spin_unlock_bh(&device->device_lock); + priv_cb->response_buffer.data = + kmalloc(priv_cb->response_buffer.size, GFP_KERNEL); + if (!priv_cb->response_buffer.data) { + return_status = -ENOMEM; + goto fail; + } + DBG("allocation call back data success\n"); + priv_cb->major_file_operations = HECI_READ; + /* make sure information is zero before we start */ + priv_cb->information = 0; + priv_cb->file_private = (void *) file_extension; + file_extension->read_cb = priv_cb; + spin_lock_bh(&device->device_lock); + if (device->host_buffer_is_empty) { + device->host_buffer_is_empty = FALSE; + if (!heci_send_flow_control(device, file_extension)) { + return_status = -ENODEV; + goto unlock; + } else { + list_add_tail(&priv_cb->cb_list, + &device->read_list.heci_cb.cb_list); + } + } else { + list_add_tail(&priv_cb->cb_list, + &device->control_write_list.heci_cb.cb_list); + } + spin_unlock_bh(&device->device_lock); + return return_status; +unlock: + spin_unlock_bh(&device->device_lock); +fail: + kfree(priv_cb->response_buffer.data); + priv_cb->response_buffer.data = NULL; + priv_cb->file_private = NULL; + kfree(priv_cb); + return return_status; +} + +/** + * pthi_write - write legacy data to pthi client + * @device -Device object for our driver + * @kernel_priv_cb - heci call back struct + * @return : + * 0 on success, + * negative on failure. + */ +int pthi_write(struct iamt_heci_device * device, + struct heci_cb_private *kernel_priv_cb) +{ + int return_status = ESUCCESS; + struct heci_message_header heci_header; + + if ((!device) || (!kernel_priv_cb)) + return -ENODEV; + + DBG("write data to pthi client\n"); + + device->legacy_state = HECI_LEGACY_WRITING; + device->legacy_current_cb = kernel_priv_cb; + device->legacy_file_object = kernel_priv_cb->file_object; + device->legacy_canceled = FALSE; + device->legacy_ioctl = TRUE; + device->legacy_message_buffer_size = + kernel_priv_cb->request_buffer.size; + memcpy(device->legacy_message_buffer, + kernel_priv_cb->request_buffer.data, + kernel_priv_cb->request_buffer.size); + if (flow_control_credentials + (device, &device->legacy_file_extension) + && device->host_buffer_is_empty) { + device->host_buffer_is_empty = FALSE; + if (kernel_priv_cb->request_buffer.size > + (((device->host_hw_state & H_CBD) >> 24) * sizeof(__u32)) - sizeof(struct heci_message_header)) { + heci_header.length = + (((device->host_hw_state & H_CBD) >> 24) * sizeof(__u32)) - sizeof(struct heci_message_header); + heci_header.message_complete = 0; + } else { + heci_header.length = + kernel_priv_cb->request_buffer.size; + heci_header.message_complete = 1; + } + + heci_header.host_address = + device->legacy_file_extension.host_client_id; + heci_header.me_address = + device->legacy_file_extension.me_client_id; + heci_header.reserved = 0; + device->legacy_message_buffer_index += heci_header.length; + if (!heci_write_message(device, &heci_header, + (unsigned char *) (device->legacy_message_buffer), + heci_header.length)) + return -ENODEV; + + if (heci_header.message_complete) { + + flow_control_reduce(device, + &device-> + legacy_file_extension); + device->legacy_flow_control_pending = TRUE; + device->legacy_state = HECI_LEGACY_FLOW_CONTROL; + DBG("add pthi cb to write waiting list\n"); + device->legacy_current_cb = kernel_priv_cb; + device->legacy_file_object = kernel_priv_cb->file_object; + list_add_tail(&kernel_priv_cb->cb_list, + &device->write_waiting_list.heci_cb. + cb_list); + + } else { + DBG("message does not complete, so add pthi cb to write list\n"); + list_add_tail(&kernel_priv_cb->cb_list, + &device->write_list.heci_cb.cb_list); + } + + + + } else { + if (TRUE != device->host_buffer_is_empty) + DBG("host buffer is not empty"); + DBG("No flow control credentials, so add legacy cb to write list\n"); + list_add_tail(&kernel_priv_cb->cb_list, + &device->write_list.heci_cb.cb_list); + } + return return_status; +} + +/** + * legacy_ioctl_send_message - send command data to pthi client + * @device -Device object for our driver + * @return : + * 0 on success, + * negative on failure. + */ +void run_next_legacy_cmd(struct iamt_heci_device * device) +{ + struct heci_file_private *file_extension_temp = NULL; + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + int legacy_write_status = ESUCCESS; + + if (!device) + return; + device->legacy_message_buffer_size = 0; + device->legacy_message_buffer_index = 0; + device->legacy_canceled = FALSE; + device->legacy_ioctl = TRUE; + device->legacy_state = HECI_LEGACY_IDLE; + device->legacy_timer = 0; + device->legacy_file_object = NULL; + + if (device->pthi_cmd_list.status == ESUCCESS + && !list_empty(&device->pthi_cmd_list.heci_cb.cb_list)) { + DBG("complete pthi cmd_list CB\n "); + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device->pthi_cmd_list.heci_cb.cb_list, cb_list){ + list_del(&kernel_priv_cb_pos->cb_list); + file_extension_temp = (struct heci_file_private *) kernel_priv_cb_pos->file_private; + + if ((file_extension_temp) + && (file_extension_temp == &device->legacy_file_extension)) { + legacy_write_status = + pthi_write(device, kernel_priv_cb_pos); + if (legacy_write_status != ESUCCESS) { + DBG("pthi write failed with status = %d\n", + legacy_write_status); + return; + } + break; + } + } + } + return; +} --- linux-2.6.28.orig/ubuntu/heci/Kconfig +++ linux-2.6.28/ubuntu/heci/Kconfig @@ -0,0 +1,3 @@ +config HECI + tristate "Intel(R) Manageability Engine Interface Driver" + default m --- linux-2.6.28.orig/ubuntu/heci/heci_init.c +++ linux-2.6.28/ubuntu/heci/heci_init.c @@ -0,0 +1,1121 @@ +/* + * Part of Intel(R) Manageability Engine Interface Linux driver + * + * Copyright (c) 2007 Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kcompat.h" +#include "heci_data_structures.h" +#include "heci_interface.h" +#include "heci.h" + + +const __u8 watch_dog_data[] = + { 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }; +const __u8 start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 }; +const __u8 stop_wd_params[] = { 0x02, 0x02, 0x14, 0x10 }; +const __u8 heci_wd_state_independence_msg[2][4] = { + {0x05, 0x02, 0x51, 0x10}, + {0x05, 0x02, 0x52, 0x10} }; +const struct guid heci_asf_guid = + { 0x75B30CD6, 0xA29E, 0x4AF7, {0xA7, 0x12, 0xE6, 0x17, 0x43, 0x93, + 0xC8, 0xA6} }; +const struct guid heci_wd_guid = + { 0x05B79A6F, 0x4628, 0x4D7F, {0x89, 0x9D, 0xA9, 0x15, 0x14, 0xCB, + 0x32, 0xAB} }; +const struct guid heci_pthi_guid = + { 0x12f80028, 0xb4b7, 0x4b2d, {0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, + 0x81, 0x4c} }; + + +/** + * heci init function prototypes + */ +int host_start_message(struct iamt_heci_device * device_object); +int host_enum_clients_message(struct iamt_heci_device * device_object); +int allocate_me_clents_storage(struct iamt_heci_device * device_object); +void heci_disable(struct iamt_heci_device * device_object); +void host_init_wd(struct iamt_heci_device * device_object); +void host_init_legacy(struct iamt_heci_device * device_object); + + +/** + * heci_initialize_list - Sets up a queue list. + * + * @list - An instance of our list structure + * @device_object -Device object for our driver + * + * @return : + * none; + */ +void heci_initialize_list(struct io_heci_list *list, + struct iamt_heci_device * device_object) +{ + /* initialize our queue list */ + INIT_LIST_HEAD(&list->heci_cb.cb_list); + list->status = ESUCCESS; + list->device_extension = device_object; + return; +} + +/** + * heci_flush_queues - flush our queues list belong to file_extension. + * + * @device_object -Device object for our driver + * + * @return : + * none; + */ +void heci_flush_queues(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension) +{ + int i; + if (!device_object || !file_extension) + return; + /* flush our queue list belong to file_extension */ + for (i = 0; i < NUMBER_OF_LISTS; i++) { + DBG("remove list etnry belong to file_extension\n"); + heci_flush_list(device_object->io_list_array[i], + file_extension); + } + +} + + +/** + * heci_flush_list - remove list etnry belong to file_extension. + * + * @list - An instance of our list structure + * @file_extension -extension of the file object + + * @return : + * none; + */ +void heci_flush_list(struct io_heci_list *list, + struct heci_file_private * file_extension) +{ + struct heci_file_private *file_extension_temp = NULL; + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + + if (!list || !file_extension) + return; + if (list->status == ESUCCESS + && !list_empty(&list->heci_cb.cb_list)) { + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &list->heci_cb.cb_list, cb_list){ + + if (kernel_priv_cb_pos) { + file_extension_temp = + (struct heci_file_private *) + kernel_priv_cb_pos->file_private; + } + if (file_extension_temp) { + if ((file_extension->host_client_id == file_extension_temp-> host_client_id) + && (file_extension->me_client_id == file_extension_temp-> me_client_id)) + list_del(&kernel_priv_cb_pos->cb_list); + } + + } + } + return; +} + +/** + * init_heci_device - allocates and initializes the heci device structure + * @pdev: The pci device structure + * + * @return : + * The heci_device_device pointer on success, NULL on failure. + */ +struct iamt_heci_device *init_heci_device(struct pci_dev * pdev) +{ + int i; + struct iamt_heci_device *device; + device = kmalloc(sizeof(struct iamt_heci_device), GFP_KERNEL); + if (!device) { + return NULL; + } + + /* setup our list array */ + device->io_list_array[0] = &device->read_list; + device->io_list_array[1] = &device->write_list; + device->io_list_array[2] = &device->write_waiting_list; + device->io_list_array[3] = &device->control_write_list; + device->io_list_array[4] = &device->control_read_list; + device->io_list_array[5] = &device->pthi_cmd_list; + device->io_list_array[6] = &device->pthi_read_complete_list; + INIT_LIST_HEAD(&device->file_list); + INIT_LIST_HEAD(&device->wd_file_extension.link); + INIT_LIST_HEAD(&device->legacy_file_extension.link); + spin_lock_init(&device->device_lock); + init_waitqueue_head(&device->wait_received_message); + init_waitqueue_head(&device->wait_stop_wd); + device->open_handle_count = 0; + device->num_heci_me_clients = 0; + device->mem_base = 0; + device->mem_length = 0; + device->extra_write_index = 0; + device->read_message_header = 0; + device->mem_addr = NULL; + device->asf_mode = FALSE; + device->need_reset = FALSE; + device->received_message = FALSE; + device->heci_state = HECI_INITIALIZING; + + device->num_heci_me_clients = 0; + device->legacy_current_cb = NULL; + device->legacy_file_object = NULL; + device->legacy_canceled = FALSE; + device->legacy_flow_control_pending = FALSE; + device->legacy_state = HECI_LEGACY_IDLE; + device->legacy_message_buffer_index = 0; + device->wd_pending = FALSE; + device->wd_stoped = FALSE; + device->wd_bypass = FALSE; + + device->me_clients = NULL; + /* init work for schedule work */ + INIT_WORK(&device->work, NULL); + for (i = 0; i < NUMBER_OF_LISTS; i++) + heci_initialize_list(device->io_list_array[i], device); + device->pdev = pdev; + return device; +} + +/** + * heci_hw_init - init host and fw to start work. + * + * @device_object -Device object for our driver + * + *@return: + * 0 on success. + * negative on failure + */ +int heci_hw_init(struct iamt_heci_device * device_object) +{ + int err = 0; + device_object->host_hw_state = + read_heci_register(device_object, H_CSR); + device_object->me_hw_state = + read_heci_register(device_object, ME_CSR_HA); + DBG("host_hw_state = 0x%08x, mestate = 0x%08x.\n", + device_object->host_hw_state, device_object->me_hw_state); + + if ((device_object->host_hw_state & H_IS) == H_IS) { + /* acknowledge interrupt and stop interupts */ + write_heci_register(device_object, H_CSR, + device_object->host_hw_state); + } + device_object->received_message = FALSE; + DBG("reset in start the heci device.\n"); + + heci_reset(device_object, TRUE); + + DBG("host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", + device_object->host_hw_state, device_object->me_hw_state); + + /* wait for ME to turn on ME_RDY */ + if (!device_object->received_message) { + err = + wait_event_interruptible_timeout(device_object-> + wait_received_message, + (device_object-> + received_message), + HECI_INTEROP_TIMEOUT); + } + + if (!err && !device_object->received_message) { + device_object->heci_state = HECI_DISABLED; + DBG("wait_event_interruptible_timeout failed on wait for ME to turn on ME_RDY.\n"); + return -ENODEV; + } else { + if (!(((device_object->host_hw_state & H_RDY) == H_RDY) + && ((device_object->me_hw_state & ME_RDY_HRA) == + ME_RDY_HRA))) { + device_object->heci_state = HECI_DISABLED; + DBG("host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", + device_object->host_hw_state, + device_object->me_hw_state); + + if (!(device_object->host_hw_state & H_RDY) != H_RDY) + DBG("host turn off H_RDY.\n"); + if (!(device_object->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA) + DBG("ME turn off ME_RDY.\n"); + HECI_ERR("link layer initialization failed.\n"); + return -ENODEV; + } + } + device_object->received_message = FALSE; + DBG("host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", + device_object->host_hw_state, device_object->me_hw_state); + DBG("ME turn on ME_RDY and host turn on H_RDY.\n"); + HECI_INFO("link layer has been established.\n"); + return ESUCCESS; +} + +/** + * heci_reset - reset host and fw. + * + * @device_object -Device object for our driver + * @interrupts - if interrupt should be enable after reset. + * + * @return: + * none; + */ +void heci_reset(struct iamt_heci_device * device_object, int interrupts) +{ + struct heci_file_private *file_extension_pos = NULL; + struct heci_file_private *file_extension_next = NULL; + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + int unexpected = 0; + + if (device_object->heci_state == HECI_RECOVERING_FROM_RESET) { + device_object->need_reset = TRUE; + return; + } + + if (device_object->heci_state != HECI_INITIALIZING && + device_object->heci_state != HECI_DISABLED && + device_object->heci_state != HECI_POWER_DOWN && + device_object->heci_state != HECI_POWER_UP) + unexpected = 1; + + device_object->host_hw_state = + read_heci_register(device_object, H_CSR); + + DBG("before reset host_hw_state = 0x%08x.\n", + device_object->host_hw_state); + + device_object->host_hw_state |= (H_RST | H_IG); + + if (interrupts) + device_object->host_hw_state |= (H_IE); + else + device_object->host_hw_state &= ~(H_IE); + + write_heci_register(device_object, H_CSR, + device_object->host_hw_state); + + device_object->host_hw_state = + read_heci_register(device_object, H_CSR); + BUG_ON((device_object->host_hw_state & H_RST) != H_RST); + BUG_ON((device_object->host_hw_state & H_RDY) != 0); + + device_object->host_hw_state &= ~H_RST; + device_object->host_hw_state |= H_IG; + + write_heci_register(device_object, H_CSR, + device_object->host_hw_state); + + DBG("currently saved host_hw_state = 0x%08x.\n", + device_object->host_hw_state); + + device_object->need_reset = FALSE; + + if (device_object->heci_state != HECI_INITIALIZING) { + if (device_object->heci_state != HECI_DISABLED && + device_object->heci_state != HECI_POWER_DOWN) { + device_object->heci_state = HECI_RESETING; + } + list_for_each_entry_safe(file_extension_pos, file_extension_next, &device_object->file_list, link) { + file_extension_pos->state =HECI_FILE_DISCONNECTED; + file_extension_pos->flow_control_credentials =0; + file_extension_pos->read_cb = NULL; + file_extension_pos->timer_count = 0; + } + /* remove entry if already in list */ + DBG("list del legacy and wd file list.\n"); + heci_remove_client_from_file_list(device_object, + device_object-> + wd_file_extension. + host_client_id); + + heci_remove_client_from_file_list(device_object, + device_object-> + legacy_file_extension. + host_client_id); + /* reset legacy parameters. */ + device_object->legacy_current_cb = NULL; + device_object->legacy_message_buffer_size = 0; + device_object->legacy_message_buffer_index = 0; + device_object->legacy_canceled = FALSE; + device_object->legacy_file_extension.file = NULL; + device_object->legacy_ioctl = FALSE; + device_object->legacy_state = HECI_LEGACY_IDLE; + device_object->legacy_timer = 0; + device_object->wd_due_counter = 0; + device_object->extra_write_index = 0; + device_object->wd_pending = FALSE; + } + + device_object->num_heci_me_clients = 0; + device_object->read_message_header = 0; + device_object->stop = FALSE; + device_object->wd_pending = 0; + + /* update the state of the registers after reset */ + device_object->host_hw_state = + read_heci_register(device_object, H_CSR); + device_object->me_hw_state = + read_heci_register(device_object, ME_CSR_HA); + + DBG("after reset host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", + device_object->host_hw_state, device_object->me_hw_state); + + if (unexpected) + HECI_ERR("unexpected heci reset.\n"); + //Wake up all readings so they can be interrupted + list_for_each_entry_safe(file_extension_pos,file_extension_next, &device_object->file_list,link) { + if (&file_extension_pos->rx_wait && + waitqueue_active (&file_extension_pos->rx_wait)) { + HECI_INFO("Waking up client!\n"); + wake_up_interruptible(&file_extension_pos->rx_wait); + } + } + // remove all waiting requests + if (device_object->write_list.status == ESUCCESS && !list_empty(&device_object->write_list.heci_cb.cb_list)) { + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device_object->write_list.heci_cb.cb_list, cb_list){ + if (kernel_priv_cb_pos) { + list_del(&kernel_priv_cb_pos->cb_list); + kfree(kernel_priv_cb_pos->request_buffer.data); + kernel_priv_cb_pos->request_buffer.data = NULL; + kfree(kernel_priv_cb_pos->response_buffer.data); + kernel_priv_cb_pos->response_buffer.data = NULL; + kfree(kernel_priv_cb_pos); + kernel_priv_cb_pos = NULL; + } + } + } +} + +/** + * heci_disable - reseting in disable routine. + * + * @device_object -Device object for our driver + * + * @return: + * none; + */ +void heci_disable(struct iamt_heci_device * device_object) +{ + if (device_object->heci_state != HECI_INITIALIZING) + HECI_ERR("driver stop request heci state is disable.\n"); + device_object->heci_state = HECI_DISABLED; +} + +/** + * heci_initialize_clients - routine. + * + * @device_object -Device object for our driver + * + * @return: + * none; + */ +int heci_initialize_clients(void *data) +{ + + int status; + struct iamt_heci_device *device_object = (struct iamt_heci_device *) data; + DBG("link is established start sending messages.\n"); + /* link is established start sending messages. */ + status = host_start_message(device_object); + if (status) { + DBG("start sending messages failed.\n"); + return -ENODEV; + } + /* enumerate clients */ + + status = host_enum_clients_message(device_object); + if (status) { + DBG("enum clients failed.\n"); + return -ENODEV; + } + /* allocate storage for ME clients representation */ + status = allocate_me_clents_storage(device_object); + if (status) { + DBG("allocate clients failed.\n"); + return -ENODEV; + } + /*heci initialization wd */ + host_init_wd(device_object); + /*heci initialization legacy client */ + host_init_legacy(device_object); + if (device_object->need_reset) { + device_object->need_reset = FALSE; + device_object->heci_state = HECI_DISABLED; + return -ENODEV; + } + + memset(device_object->heci_host_clients, 0, + sizeof(device_object->heci_host_clients)); + device_object->open_handle_count = 0; + device_object->heci_host_clients[0] |= 7; + device_object->current_host_client_id = 3; + device_object->heci_state = HECI_ENABLED; + DBG("initialization heci clients successful.\n"); + return ESUCCESS; +} + +/** + * host_start_message - heci host send start message. + * + * @device_object - Device object for our driver + * + * @return : + * 0 on success, + * negative on failure. + */ +int host_start_message(struct iamt_heci_device * device_object) +{ + long timeout = 60; /* 60 second */ + + struct heci_message_header *heci_header; + struct hbm_host_version_request *host_start_req; + struct hbm_host_stop_request *host_stop_req; + int err = 0; + /* host start message */ + msleep(100); + heci_header = + (struct heci_message_header *) & device_object-> + write_message_buffer[0]; + heci_header->host_address = 0; + heci_header->me_address = 0; + heci_header->length = sizeof(struct hbm_host_version_request); + heci_header->message_complete = 1; + heci_header->reserved = 0; + + host_start_req = + (struct hbm_host_version_request *) & device_object-> + write_message_buffer[1]; + memset(host_start_req, 0, sizeof(host_start_req)); + host_start_req->command.command = HOST_START_REQ_CMD; + host_start_req->reserved = 0; + host_start_req->host_version.major_version = HBM_MAJOR_VERSION; + host_start_req->host_version.minor_version = HBM_MINOR_VERSION; + device_object->received_message = FALSE; + if (!heci_write_message(device_object, heci_header, + (unsigned char *) (host_start_req), + heci_header->length)) { + device_object->heci_state = HECI_DISABLED; + DBG("send version to fw fail.\n"); + return -ENODEV; + } + DBG("call wait_event_interruptible_timeout for response message. \n"); + /* wait for response */ + err = + wait_event_interruptible_timeout(device_object-> + wait_received_message, + (device_object-> + received_message), + timeout * HZ); + if (!err && !device_object->received_message) { + device_object->heci_state = HECI_DISABLED; + DBG("wait_event_interruptible_timeout failed on host start response message. \n"); + return -ENODEV; + } + device_object->received_message = FALSE; + DBG("wait_event_interruptible_timeout successful on host start response message. \n"); + if ((device_object->version.major_version != HBM_MAJOR_VERSION) || + (device_object->version.minor_version != HBM_MINOR_VERSION)) { + /* send stop message */ + heci_header->host_address = 0; + heci_header->me_address = 0; + heci_header->length = sizeof(struct hbm_host_stop_request); + heci_header->message_complete = 1; + heci_header->reserved = 0; + + host_stop_req = + (struct hbm_host_stop_request *) & device_object-> + write_message_buffer[1]; + + memset(host_stop_req, 0, sizeof(host_stop_req)); + host_stop_req->command.command = HOST_STOP_REQ_CMD; + host_stop_req->reason = DRIVER_STOP_REQUEST; + memset(host_stop_req->reserved, 0, + sizeof(host_stop_req->reserved)); + heci_write_message(device_object, heci_header, + (unsigned char *) (host_stop_req), + heci_header->length); + DBG("version mismatch.\n"); + return -ENODEV; + } + + return ESUCCESS; +} + +/** + * host_enum_clients_message - host send enumeration client request message. + * + * @device_object - Device object for our driver + * + * @return : + * 0 on success, + * negative on failure. + */ +int host_enum_clients_message(struct iamt_heci_device * device_object) +{ + long timeout = 5; /*5 second */ + + struct heci_message_header *heci_header; + struct hbm_host_enumeration_request *host_enum_req; + int err = 0; + __u8 i, j; + heci_header = + (struct heci_message_header *) & device_object-> + write_message_buffer[0]; + /* enumerate clients */ + heci_header->host_address = 0; + heci_header->me_address = 0; + heci_header->length = sizeof(struct hbm_host_enumeration_request); + heci_header->message_complete = 1; + heci_header->reserved = 0; + + host_enum_req = + (struct hbm_host_enumeration_request *) & device_object-> + write_message_buffer[1]; + memset(host_enum_req, 0, sizeof(host_enum_req)); + host_enum_req->command.command = HOST_ENUM_REQ_CMD; + memset(host_enum_req->reserved, 0, + sizeof(host_enum_req->reserved)); + if (!heci_write_message(device_object, heci_header, + (unsigned char *) (host_enum_req), + heci_header->length)) { + device_object->heci_state = HECI_DISABLED; + DBG("send enumeration request fail.\n"); + return -ENODEV; + } + /* wait for response */ + device_object->received_message = FALSE; + err = + wait_event_interruptible_timeout(device_object-> + wait_received_message, + (device_object-> + received_message), + timeout * HZ); + if (!err && !device_object->received_message) { + + device_object->heci_state = HECI_DISABLED; + + DBG("wait_event_interruptible_timeout failed on enumeration cients response message. \n"); + return -ENODEV; + } + device_object->received_message = FALSE; + /* count how many ME clients we have */ + for (i = 0; i < sizeof(device_object->heci_me_clients); i++) + for (j = 0; j < 8; j++) + if ((device_object->heci_me_clients[i] & (1 << j)) != 0) + device_object->num_heci_me_clients++; + return ESUCCESS; +} + +/** + * allocate_me_clents_storage - allocate storage for me clients + * + * @device_object - Device object for our driver + * + * @return : + * 0 on success, + * negative on failure. + */ +int allocate_me_clents_storage(struct iamt_heci_device * device_object) +{ + long timeout = 10; /*10 second */ + struct heci_message_header *heci_header; + struct hbm_host_client_properties_request *host_cli_req; + __u8 client_num, i, j; + int err; + heci_header = + (struct heci_message_header *) & device_object-> + write_message_buffer[0]; + /* allocate storage for ME clients representation */ + if (device_object->num_heci_me_clients > 0) { + kfree(device_object->me_clients); + device_object->me_clients = + kcalloc(device_object->num_heci_me_clients, + sizeof(struct heci_me_client), + GFP_KERNEL); + if (!device_object->me_clients) { + device_object->heci_state = HECI_DISABLED; + DBG("allocate me clents memory failed.\n"); + return -ENOMEM; + } + + client_num = 0; + + for (i = 0; i < sizeof(device_object->heci_me_clients); + i++) { + for (j = 0; j < 8; j++) { + if ((device_object->heci_me_clients[i] & (1 << j)) != 0) { + device_object->me_clients[client_num].client_id = (i * 8) + j; + device_object->me_clients[client_num].flow_control_credentials = 0; + heci_header->host_address = 0; + heci_header->me_address = 0; + heci_header->length = sizeof(struct hbm_host_client_properties_request); + heci_header->message_complete = 1; + heci_header->reserved = 0; + + host_cli_req = (struct hbm_host_client_properties_request *)& device_object->write_message_buffer[1]; + memset(host_cli_req, 0, sizeof(struct hbm_host_client_properties_request)); + host_cli_req->command.command = HOST_CLIENT_PROPERTEIS_REQ_CMD; + host_cli_req->address = device_object->me_clients[client_num].client_id; + memset(host_cli_req->reserved, 0, sizeof(host_cli_req->reserved)); + if (!heci_write_message(device_object, heci_header, + (unsigned char *) (host_cli_req), heci_header->length)) { + DBG("send client properteis request fail.\n"); + device_object->heci_state = HECI_DISABLED; + kfree(device_object->me_clients); + return -ENODEV; + } + /* wait for response */ + device_object->received_message = FALSE; + err = wait_event_interruptible_timeout (device_object->wait_received_message, + (device_object->received_message), timeout * HZ); + if (!err && !device_object->received_message) { + DBG("wait_event_interruptible_timeout failed on client properteis response message.\n"); + device_object->heci_state = HECI_DISABLED; + kfree(device_object->me_clients); + return -ENODEV; + } + device_object->received_message = FALSE; + client_num++; + } + } + } + } + return ESUCCESS; +} + +/** + * host_init_wd - heci initialization wd. + * + * @device_object - Device object for our driver + * + * @return : + * none; + */ +void host_init_wd(struct iamt_heci_device * device_object) +{ + long timeout = 15; /*15 second */ + __u8 i; + int err = 0; + /*look for WD client and connect to it */ + spin_lock_init(&device_object->wd_file_extension.file_lock); + init_waitqueue_head(&device_object->wd_file_extension.wait); + device_object->wd_file_extension.file = NULL; + device_object->wd_file_extension.state = HECI_FILE_DISCONNECTED; + device_object->wd_timeout = 0; + device_object->asf_mode = FALSE; + /*find ME ASF client - otherwise assume AMT mode */ + DBG("find ME ASF client - otherwise assume AMT mode.\n"); + for (i = 0; i < device_object->num_heci_me_clients; i++) { + if (memcmp(&heci_asf_guid, + &device_object->me_clients[i].properteis. + protocol_name, sizeof(struct guid))==0) { + device_object->asf_mode = TRUE; + DBG("found ME ASF client.\n"); + } + } + if (device_object->asf_mode) { + memcpy(device_object->wd_data, + stop_wd_params, HECI_WD_PARAMS_SIZE); + + } + else { /* AMT mode */ + + DBG("assume AMT mode.\n"); + device_object->wd_timeout = AMT_WD_VALUE; + DBG("device_object->wd_timeout=%d.\n", + device_object->wd_timeout); + memcpy(device_object->wd_data, start_wd_params, HECI_WD_PARAMS_SIZE); + memcpy(device_object->wd_data + HECI_WD_PARAMS_SIZE, + &device_object->wd_timeout, sizeof(__u16)); + } + + /* find ME WD client */ + for (i = 0; i < device_object->num_heci_me_clients; i++) { + if (0 == memcmp(&heci_wd_guid, &device_object->me_clients[i].properteis.protocol_name, sizeof(struct guid))) { + + spin_lock_bh(&device_object->device_lock); + device_object->wd_file_extension.me_client_id = + device_object->me_clients[i].client_id; + device_object->wd_file_extension.state = + HECI_FILE_CONNECTING; + + device_object->wd_file_extension.host_client_id = + HECI_WD_HOST_CLIENT_ID; + + device_object->wd_file_extension. + flow_control_credentials = 0; + device_object->wd_file_extension.timer_count = 0; + list_add_tail(&device_object->wd_file_extension. + link, &device_object->file_list); + spin_unlock_bh(&device_object->device_lock); + break; + } + } + DBG("check wd_file_ext\n"); + if (HECI_FILE_CONNECTING == device_object->wd_file_extension.state) { + if (heci_connect(device_object, + &device_object->wd_file_extension)) { + + err = + wait_event_timeout + (device_object->wait_received_message, + (HECI_FILE_CONNECTED == device_object->wd_file_extension.state ||HECI_FILE_DISCONNECTED == device_object->wd_file_extension.state), + timeout * HZ); + if (HECI_FILE_CONNECTED == device_object->wd_file_extension.state) { + DBG("device_object->wd_timeout=%d.\n", + device_object->wd_timeout); + if (device_object->wd_timeout != 0) + device_object->wd_due_counter = 1; + else + device_object->wd_due_counter = 0; + DBG("successfully to connect to WD client.\n"); + } else { + + heci_remove_client_from_file_list + (device_object, + device_object->wd_file_extension. + host_client_id); + if (HECI_FILE_CONNECTED != + device_object->wd_file_extension.state) + DBG("wrong status received for WD client.\n"); + if (!err) + DBG("wait_event_interruptible_timeout failed on client connect message fw response message err=%08x\n", err); + DBG("failed to connect to WD client.\n"); + device_object->wd_file_extension.state = + HECI_FILE_DISCONNECTED; + } + } else { + DBG("failed to call heci_connect for wd_file_extension.\n"); + heci_remove_client_from_file_list(device_object, + device_object-> + wd_file_extension. + host_client_id); + device_object->wd_file_extension.state = + HECI_FILE_DISCONNECTED; + } + } else { + DBG("failed to find WD client.\n"); + } + + device_object->wd_timer.function = &heci_wd_timer; + device_object->wd_timer.data = (unsigned long) device_object; + return; +} + + +/** + * host_init_legacy - heci initialization legacy client. + * + * @device_object - Device object for our driver + * + * @return : + * none; + */ +void host_init_legacy(struct iamt_heci_device * device_object) +{ + long timeout = 15; /*15 second */ + __u8 i; + int err; + + + spin_lock_init(&device_object->legacy_file_extension.file_lock); + init_waitqueue_head(&device_object->legacy_file_extension.wait); + spin_lock_init(&device_object->legacy_file_extension.read_io_lock); + spin_lock_init(&device_object->legacy_file_extension. + write_io_lock); + init_waitqueue_head(&device_object->legacy_file_extension.rx_wait); + init_waitqueue_head(&device_object->legacy_file_extension.tx_wait); + device_object->legacy_file_extension.reading_state = HECI_IDLE; + device_object->legacy_file_extension.writing_state = HECI_IDLE; + device_object->legacy_file_extension.read_pending = FALSE; + device_object->legacy_file_extension.flow_control_credentials = 0; + device_object->legacy_file_extension.read_cb = NULL; + /* look for legacy client and connect to it */ + device_object->legacy_file_extension.file = NULL; + device_object->legacy_file_extension.state = + HECI_FILE_DISCONNECTED; + + /* find ME PTHI client */ + for (i = 0; i < device_object->num_heci_me_clients; i++) { + if (0 == memcmp(&heci_pthi_guid, &device_object->me_clients[i].properteis. protocol_name, sizeof(struct guid))) { + spin_lock_bh(&device_object->device_lock); + device_object->legacy_file_extension.me_client_id = + device_object->me_clients[i].client_id; + device_object->legacy_file_extension.state = + HECI_FILE_CONNECTING; + device_object->legacy_file_extension. + host_client_id = HECI_LEGACY_HOST_CLIENT_ID; + device_object->legacy_file_extension. + flow_control_credentials = 0; + device_object->legacy_file_extension.timer_count = 0; + list_add_tail(&device_object-> + legacy_file_extension.link, + &device_object->file_list); + spin_unlock_bh(&device_object->device_lock); + break; + } + } + if (device_object->asf_mode){ + device_object->legacy_file_extension.state = + HECI_FILE_DISCONNECTED; + heci_remove_client_from_file_list(device_object, + device_object-> + legacy_file_extension. + host_client_id); + return; + + } + if (device_object->legacy_file_extension.state == HECI_FILE_CONNECTING) { + BUG_ON(device_object->me_clients[i].properteis.max_message_length != LEGACY_MTU); + + if (device_object->me_clients[i].properteis.max_message_length < LEGACY_MTU) { + device_object->legacy_file_extension.state = + HECI_FILE_DISCONNECTED; + DBG("legacy client buffer too small.\n"); + } else { + if (heci_connect(device_object, &device_object-> legacy_file_extension)) { + err = wait_event_timeout (device_object->wait_received_message, + (device_object->legacy_file_extension.state == HECI_FILE_CONNECTED || + device_object->legacy_file_extension.state == HECI_FILE_DISCONNECTED), timeout * HZ); + if ((device_object->legacy_file_extension.state != HECI_FILE_CONNECTED)) { + heci_remove_client_from_file_list + (device_object, + device_object-> + legacy_file_extension. + host_client_id); + DBG("failed to connect to legacy client.\n"); + device_object-> + legacy_file_extension.state = + HECI_FILE_DISCONNECTED; + } else { + DBG("successfully to connect to legacy client.\n"); + device_object->legacy_state = + HECI_LEGACY_IDLE; + } + } else { + DBG("failed to call heci_connect for legacy_file_extension.\n"); + heci_remove_client_from_file_list + (device_object, + device_object->legacy_file_extension. + host_client_id); + device_object->legacy_file_extension. + state = HECI_FILE_DISCONNECTED; + } + } + } else { + if (!device_object->asf_mode) + DBG("failed to find legacy client.\n"); + } + return; +} + +/** + * alloc_priv - allocates a private file structure and set it up. + * @file: the file structure + * + * @return : + * The allocated file or NULL on failure + */ +struct heci_file_private *alloc_priv(struct file * file) +{ + struct heci_file_private *priv; + + priv = kmalloc(sizeof(struct heci_file_private), GFP_KERNEL); + if (!priv) + return NULL; + + spin_lock_init(&priv->file_lock); + spin_lock_init(&priv->read_io_lock); + spin_lock_init(&priv->write_io_lock); + init_waitqueue_head(&priv->wait); + init_waitqueue_head(&priv->rx_wait); + DBG("priv->rx_wait =%p\n", &priv->rx_wait); + init_waitqueue_head(&priv->tx_wait); + INIT_LIST_HEAD(&priv->link); + priv->reading_state = HECI_IDLE; + priv->writing_state = HECI_IDLE; + priv->file = file; + priv->flow_control_credentials = 0; + priv->timer_count = 0; + priv->me_client_id = 0; + priv->read_cb = NULL; + priv->status = ESUCCESS; + priv->read_pending = FALSE; + return priv; +} + + + +/** + * heci_disconnect_host_client - send disconnect message to fw from host client. + * + * @device_object -Device object for our driver + * @file_extension -extension of the file object + * + * @return : + * 0 on success, + * negative on failure. + */ +int heci_disconnect_host_client(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension) +{ + int return_status = ESUCCESS, err = 0; + long timeout = 15; /*15 second */ + + struct heci_cb_private *kernel_priv_cb = NULL; + + struct heci_file_private *file_extension_list_temp = NULL; + + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + + if ((!device_object) || (!file_extension)) + return -ENODEV; + kernel_priv_cb = kmalloc(sizeof(struct heci_cb_private), GFP_KERNEL); + if (!kernel_priv_cb) + return -ENOMEM; + if (file_extension->state == HECI_FILE_DISCONNECTING) { + INIT_LIST_HEAD(&kernel_priv_cb->cb_list); + kernel_priv_cb->file_private = file_extension; + kernel_priv_cb->major_file_operations = HECI_CLOSE; + spin_lock_bh(&device_object->device_lock); + if (device_object->host_buffer_is_empty){ + device_object->host_buffer_is_empty =FALSE; + if (heci_disconnect(device_object, file_extension)) { + list_add_tail(&kernel_priv_cb->cb_list, + &device_object->control_read_list. + heci_cb.cb_list); + } + else{ + spin_unlock_bh(&device_object->device_lock); + return_status = -ENODEV; + DBG("failed to call heci_disconnect for file_extension.\n"); + goto free; + } + } + else{ + kernel_priv_cb->file_private = file_extension; + DBG("add disconnect cb to control write list\n"); + list_add_tail(&kernel_priv_cb->cb_list, + &device_object->control_write_list.heci_cb.cb_list); + } + spin_unlock_bh(&device_object->device_lock); + + err = + wait_event_timeout + (device_object->wait_received_message, + (HECI_FILE_DISCONNECTED == file_extension->state), + timeout * HZ); + if (HECI_FILE_DISCONNECTED == file_extension->state) { + return_status = ESUCCESS; + DBG("successfully to disconnect from fw client.\n"); + } else { + return_status = -ENODEV; + if (HECI_FILE_DISCONNECTED != file_extension->state) + DBG("wrong status received for client disconnect.\n"); + if (!err) + DBG("wait_event_interruptible_timeout failed on client disconnect message fw response message err=%08x\n", err); + DBG("failed to diconnect to fw client.\n"); + } + + } + if (kernel_priv_cb) { + spin_lock_bh(&device_object->device_lock); + if (device_object->control_read_list.status == ESUCCESS + && !list_empty(&device_object->control_read_list.heci_cb.cb_list)) { + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device_object->control_read_list.heci_cb.cb_list, cb_list){ + file_extension_list_temp = + (struct heci_file_private *) + kernel_priv_cb_pos->file_private; + if (file_extension_list_temp) { + if ((file_extension->host_client_id == file_extension_list_temp->host_client_id) + && (file_extension->me_client_id == file_extension_list_temp->me_client_id)) { + list_del(&kernel_priv_cb_pos->cb_list); + } + } + + } + } + spin_unlock_bh(&device_object->device_lock); +free: + kfree(kernel_priv_cb); + kernel_priv_cb = NULL; + + + } + + return return_status; +} + + +/** + * heci_remove_client_from_file_list - remove file extension from device file list + * + * @device_object -Device object for our driver + * @host_client_id -host client id to be removed + * + * @return : + * none; + */ +void heci_remove_client_from_file_list(struct iamt_heci_device * device_object, + __u8 host_client_id) +{ + struct heci_file_private *file_extension_pos = NULL; + struct heci_file_private *file_extension_next = NULL; + list_for_each_entry_safe(file_extension_pos, file_extension_next, &device_object->file_list, link) { + if (host_client_id == file_extension_pos->host_client_id) { + DBG("remove file extension node host client = %d, ME client = %d\n", + file_extension_pos->host_client_id, + file_extension_pos->me_client_id); + list_del(&file_extension_pos->link); + break; + } + + + } +} --- linux-2.6.28.orig/ubuntu/heci/kcompat.h +++ linux-2.6.28/ubuntu/heci/kcompat.h @@ -0,0 +1,165 @@ +/* + * Part of Intel(R) Manageability Engine Interface Linux driver + * + * Copyright (c) 2003 - 2007 Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. + * + */ + +#ifndef _KCOMPAT_H_ +#define _KCOMPAT_H_ + +#include +#include +#include +#include +#include +#include +#include + + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) ) +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,28) ) +#undef INIT_WORK +#define INIT_WORK(_work, _func) \ +do { \ + INIT_LIST_HEAD(&(_work)->entry); \ + (_work)->pending = 0; \ + (_work)->func = (void (*)(void *))_func; \ + (_work)->data = _work; \ + init_timer(&(_work)->timer); \ +} while (0) +#undef PREPARE_WORK +#define PREPARE_WORK(_work, _func) \ + do { \ + (_work)->func = (void (*)(void *))_func;\ + (_work)->data = _work;\ + } while (0) + + +#endif + +#ifndef round_jiffies +#define round_jiffies(x) x +#endif + +#endif /* < 2.6.20 */ + + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) ) + +#ifndef IRQF_PROBE_SHARED +#ifdef SA_PROBEIRQ +#define IRQF_PROBE_SHARED SA_PROBEIRQ +#else +#define IRQF_PROBE_SHARED 0 +#endif +#endif + +#ifndef IRQF_SHARED +#define IRQF_SHARED SA_SHIRQ +#endif + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + +#endif /* < 2.6.18 */ + + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) ) + +#ifndef RHEL_VERSION +#define RHEL_VERSION 0 +#endif +#if (!(( RHEL_VERSION == 4 ) && ( RHEL_UPDATE >= 5 ))) +typedef irqreturn_t (*irq_handler_t)(int, void*, struct pt_regs *); +#endif +typedef irqreturn_t (*new_handler_t)(int, void*); +static inline irqreturn_t _kc_request_irq(unsigned int irq, new_handler_t handler, unsigned long flags, const char *devname, void *dev_id) +{ + irq_handler_t new_handler = (irq_handler_t) handler; + return request_irq(irq, new_handler, flags, devname, dev_id); +} + +#undef request_irq +#define request_irq(irq, handler, flags, devname, dev_id) _kc_request_irq((irq), (handler), (flags), (devname), (dev_id)) + +#endif + + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) ) +#define SHUTDOWN_METHOD(method) +#define HECI_REBOOT_NOTIFIER(reboot_notifier, driver, reboot_function) \ +static int heci_notify_reboot(struct notifier_block *nb, unsigned long event, void *p) \ +{ \ + struct pci_dev *pdev = NULL; \ +\ + switch(event){ \ + case SYS_DOWN: \ + case SYS_HALT: \ + case SYS_POWER_OFF: \ + while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev))) { \ + if (pci_dev_driver(pdev) == &driver) { \ + reboot_function(pdev); \ + } \ + } \ + } \ + return NOTIFY_DONE; \ +};\ +static struct notifier_block reboot_notifier = { \ + .notifier_call = heci_notify_reboot, \ + .next = NULL, \ + .priority = 0 \ +}; + +#define REGISTER_REBOOT_NOTIFIER(reboot_notifier) \ + register_reboot_notifier(&reboot_notifier); +#define UNREGISTER_REBOOT_NOTIFIER(reboot_notifier) \ + unregister_reboot_notifier(&reboot_notifier); +#else +#define SHUTDOWN_METHOD(method) .shutdown = method, +#define HECI_REBOOT_NOTIFIER(reboot_notifier, driver, reboot_function) +#define REGISTER_REBOOT_NOTIFIER(reboot_notifier) +#define UNREGISTER_REBOOT_NOTIFIER(reboot_notifier) +#define heci_reboot_notifier +#endif //( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) ) + + +#endif --- linux-2.6.28.orig/ubuntu/heci/heci_interface.h +++ linux-2.6.28/ubuntu/heci/heci_interface.h @@ -0,0 +1,177 @@ +/* + * Part of Intel(R) Manageability Engine Interface Linux driver + * + * Copyright (c) 2003 - 2007 Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. + * + */ + + +#ifndef _HECI_INTERFACE_H_ +#define _HECI_INTERFACE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "heci_data_structures.h" + + +#define HBM_MINOR_VERSION 0 +#define HBM_MAJOR_VERSION 1 +#define HBM_TIMEOUT 1 /* 1 second */ + + +#define HOST_START_REQ_CMD 0x01 +#define HOST_START_RES_CMD 0x81 + +#define HOST_STOP_REQ_CMD 0x02 +#define HOST_STOP_RES_CMD 0x82 + +#define ME_STOP_REQ_CMD 0x03 + +#define HOST_ENUM_REQ_CMD 0x04 +#define HOST_ENUM_RES_CMD 0x84 + +#define HOST_CLIENT_PROPERTEIS_REQ_CMD 0x05 +#define HOST_CLIENT_PROPERTEIS_RES_CMD 0x85 + +#define CLIENT_CONNECT_REQ_CMD 0x06 +#define CLIENT_CONNECT_RES_CMD 0x86 + +#define CLIENT_DISCONNECT_REQ_CMD 0x07 +#define CLIENT_DISCONNECT_RES_CMD 0x87 + +#define FLOW_CONTROL_CMD 0x08 + + +#define AMT_WD_VALUE 120 /* seconds */ + +#define HECI_WATCHDOG_DATA_SIZE 16 +#define HECI_START_WD_DATA_SIZE 20 +#define HECI_WD_PARAMS_SIZE 4 + +/* IOCTL commands */ +#define HECI_IOCTL_LETTER 'H' + + +#define IOCTL_HECI_GET_VERSION \ + _IOWR(HECI_IOCTL_LETTER , 0x800, struct heci_message_data) +#define IOCTL_HECI_CONNECT_CLIENT \ + _IOWR(HECI_IOCTL_LETTER , 0x801, struct heci_message_data) +#define IOCTL_HECI_WD \ + _IOWR(HECI_IOCTL_LETTER , 0x802, struct heci_message_data) +#define IOCTL_HECI_BYPASS_WD \ + _IOWR(HECI_IOCTL_LETTER , 0x810, struct heci_message_data) + +#define IAMT_IOC_MAGIC 'i' +#define IAMT_KCS_SEND_MESSAGE_COMMAND _IOR(IAMT_IOC_MAGIC, 1, struct heci_message_data) +#define IAMT_KCS_RECEIVE_MESSAGE_COMMAND _IOW(IAMT_IOC_MAGIC, 2, struct heci_message_data) + + +#pragma pack(1) + + +enum heci_stop_reason_types{ + DRIVER_STOP_REQUEST = 0x00, + DEVICE_D1_ENTRY = 0x01, + DEVICE_D2_ENTRY = 0x02, + DEVICE_D3_ENTRY = 0x03, + SYSTEM_S1_ENTRY = 0x04, + SYSTEM_S2_ENTRY = 0x05, + SYSTEM_S3_ENTRY = 0x06, + SYSTEM_S4_ENTRY = 0x07, + SYSTEM_S5_ENTRY = 0x08 +}; + +enum me_stop_reason_types{ + FW_UPDATE = 0x00 +}; + +enum client_connect_status_types{ + CCS_SUCCESS = 0x00, + CCS_NOT_FOUND = 0x01, + CCS_ALREADY_STARTED = 0x02, + CCS_OUT_OF_RESOURCES = 0x03, + CCS_MESSAGE_SMALL = 0x04 +}; + +enum client_disconnect_status_types{ + CDS_SUCCESS = 0x00 +}; + + +/** + * heci interface function prototypes + */ +void heci_read_slots(struct iamt_heci_device * device_object, + unsigned char *buffer, unsigned long buffer_length); + +int heci_write_message(struct iamt_heci_device * device_object, + struct heci_message_header * header, + unsigned char *write_buffer, + unsigned long write_length); + +int host_buffer_is_empty(struct iamt_heci_device * device_object); + +__s32 count_full_read_slots(struct iamt_heci_device * device_object); + +__s32 count_empty_write_slots(struct iamt_heci_device * device_object); + +int flow_control_credentials(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension); + +int heci_send_wd(struct iamt_heci_device * device_object); + +void flow_control_reduce(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension); + +int heci_send_flow_control(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension); + +int heci_disconnect(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension); +int other_client_is_connecting(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension); +int heci_connect(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension); + +#endif /* _HECI_INTERFACE_H_ */ --- linux-2.6.28.orig/ubuntu/heci/heci_interface.c +++ linux-2.6.28/ubuntu/heci/heci_interface.c @@ -0,0 +1,525 @@ +/* + * Part of Intel(R) Manageability Engine Interface Linux driver + * + * Copyright (c) 2003 - 2007 Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. + * + */ + + +#include "heci.h" +#include "heci_interface.h" + + + +static const __u8 interface_start_wd_params[] = + { 0x02, 0x12, 0x13, 0x10 }; +static const __u8 interface_stop_wd_params[] = + { 0x02, 0x02, 0x14, 0x10 }; + +/** + * read_heci_register - Read a byte from the heci device + * @device: the device structure + * @offset: offset from which to read the data + * + * Return: + * the byte read. + */ +__u32 read_heci_register(struct iamt_heci_device * device, + unsigned long offset) +{ + return readl(device->mem_addr + offset); +} + +/** + * write_heci_register - Write 4 bytes to the heci device + * @device: the device structure + * @offset: offset from which to write the data + * + * @value: the byte to write + */ +void write_heci_register(struct iamt_heci_device * device, unsigned long offset, + __u32 value) +{ + writel(value, device->mem_addr + offset); +} + +/** + * host_buffer_is_empty - check if host buffer is empty. + * + * @device_object -Device object for our driver + * + * @return : + * TRUE if empty + * FALSE - otherwise. + */ +int host_buffer_is_empty(struct iamt_heci_device * device_object) +{ + char read_ptr, write_ptr; + unsigned char buffer_depth, filled_slots, empty_slots; + device_object->host_hw_state = + read_heci_register(device_object, H_CSR); + read_ptr = (char) ((device_object->host_hw_state & H_CBRP) >> 8); + write_ptr = (char) ((device_object->host_hw_state & H_CBWP) >> 16); + buffer_depth = + (unsigned char) ((device_object->host_hw_state & H_CBD) >> 24); + filled_slots = (unsigned char) (write_ptr - read_ptr); + empty_slots = buffer_depth - filled_slots; + + if (filled_slots > 0) + return FALSE; + return TRUE; +} + +/** + * count_empty_write_slots - count write empty slots. + * + * @device_object - Device object for our driver + * + * + * @return : + * -1(ESLOTS_OVERFLOW) if overflow + * otherwise filed slots count + */ +__s32 count_empty_write_slots(struct iamt_heci_device * device_object) +{ + char read_ptr, write_ptr; + unsigned char buffer_depth, filled_slots, empty_slots; + + read_ptr = (char) ((device_object->host_hw_state & H_CBRP) >> 8); + write_ptr = (char) ((device_object->host_hw_state & H_CBWP) >> 16); + buffer_depth = + (unsigned char) ((device_object->host_hw_state & H_CBD) >> 24); + filled_slots = (unsigned char) (write_ptr - read_ptr); + empty_slots = buffer_depth - filled_slots; + + if (filled_slots > buffer_depth) + /* overfolw */ + return -ESLOTS_OVERFLOW; + + return (__s32) empty_slots; +} + +/** + * heci_write_message - write a message to heci device. + * + * @heci_header - header of message + * @write_buffer - message buffer will be write + * @write_length - message size will be write + * + * @return : + * TRUE if success + * FALSE - otherwise. + */ +int heci_write_message(struct iamt_heci_device * device_object, + struct heci_message_header * header, + unsigned char *write_buffer, + unsigned long write_length) +{ + __u32 temp_msg = 0; + unsigned long bytes_written = 0; + char read_ptr, write_ptr; + unsigned char buffer_depth, filled_slots, empty_slots; + unsigned long dw_to_write; + dw_to_write = ((write_length + 3) / 4); + DBG("host_hw_state = 0x%08x.\n", device_object->host_hw_state); + DBG("heci_write_message header=%08x.\n", *((__u32 *) header)); + + read_ptr = (char) ((device_object->host_hw_state & H_CBRP) >> 8); + write_ptr = (char) ((device_object->host_hw_state & H_CBWP) >> 16); + buffer_depth = + (unsigned char) ((device_object->host_hw_state & H_CBD) >> 24); + filled_slots = (unsigned char) (write_ptr - read_ptr); + empty_slots = buffer_depth - filled_slots; + DBG("filled = %hu, empty = %hu.\n", filled_slots, empty_slots); + + if (dw_to_write > empty_slots) { + return FALSE; + } + + write_heci_register(device_object, H_CB_WW, + *((__u32 *) header)); + + while (write_length >= 4) { + write_heci_register(device_object, H_CB_WW, + *(__u32 *) (write_buffer + + bytes_written)); + bytes_written += 4; + write_length -= 4; + } + + if (write_length > 0) { + memcpy(&temp_msg, &write_buffer[bytes_written], write_length); + write_heci_register(device_object, H_CB_WW, temp_msg); + } + + device_object->host_hw_state |= H_IG; + write_heci_register(device_object, H_CSR, + device_object->host_hw_state); + device_object->me_hw_state = + read_heci_register(device_object, ME_CSR_HA); + if ((device_object->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA) + return FALSE; + + device_object->write_hang = 0; + return TRUE; +} + +/** + * count_full_read_slots - reset host and fw. + * + * @device_object -Device object for our driver + * + * + * @return : + * -1(ESLOTS_OVERFLOW) if overflow + * otherwise filed slots count + */ +__s32 count_full_read_slots(struct iamt_heci_device * device_object) +{ + + char read_ptr, write_ptr; + unsigned char buffer_depth, filled_slots, empty_slots; + + device_object->me_hw_state = read_heci_register(device_object, ME_CSR_HA); + read_ptr = (char) ((device_object->me_hw_state & ME_CBRP_HRA) >> 8); + write_ptr = (char) ((device_object->me_hw_state & ME_CBWP_HRA) >> 16); + buffer_depth = (unsigned char) ((device_object->me_hw_state & ME_CBD_HRA) >> + 24); + filled_slots = (unsigned char) (write_ptr - read_ptr); + empty_slots = buffer_depth - filled_slots; + + if (filled_slots > buffer_depth) + /* overflow */ + return -ESLOTS_OVERFLOW; + + DBG("filled_slots =%08x \n", filled_slots); + return (__s32) filled_slots; +} + +/** + * heci_read_slots - read a message from heci device. + * + * @device_object - device object for our driver + * @buffer - message buffer will be write + * @buffer_length - message size will be read + * + * @return : + * none; + */ +void heci_read_slots(struct iamt_heci_device * device_object, + unsigned char *buffer, unsigned long buffer_length) +{ + __u32 i = 0; + unsigned char temp_buf[sizeof(__u32)]; + + while (buffer_length >= sizeof(__u32)) { + ((__u32 *) buffer)[i] = + read_heci_register(device_object, ME_CB_RW); + DBG("buffer[%d]= %d\n", i, ((__u32 *) buffer)[i]); + i++; + buffer_length -= sizeof(__u32); + } + + if (buffer_length > 0) { + *((__u32 *) & temp_buf) = + read_heci_register(device_object, ME_CB_RW); + memcpy(&buffer[i * 4], temp_buf, buffer_length); + } + + device_object->host_hw_state |= H_IG; + write_heci_register(device_object, H_CSR, + device_object->host_hw_state); + return; +} + +/** + * flow_control_credentials - check flow_control credentials. + * + * @device_object -Device object for our driver + * @file_extension -extension of the file object + * + * @return : + * TRUE if flow_control_credentials >0 + * FALSE - otherwise. + */ +int flow_control_credentials(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension) +{ + __u8 i; + + if (!device_object->num_heci_me_clients) + return FALSE; + if (file_extension == NULL) + return FALSE; + if (file_extension->flow_control_credentials > 0) + return TRUE; + + for (i = 0; i < device_object->num_heci_me_clients; i++) { + if (device_object->me_clients[i].client_id == + file_extension->me_client_id) { + if (device_object->me_clients[i].flow_control_credentials > 0) { + BUG_ON(device_object->me_clients[i]. + properteis.single_receive_buffer == 0); + return TRUE; + } + return FALSE; + } + } + BUG_ON(1); + return FALSE; +} + +/** + * flow_control_reduce - reduce flow_control . + * + * @device_object -Device object for our driver + * @file_extension -extension of the file object + * + * @return : + * none; + */ +void flow_control_reduce(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension) +{ + __u8 i; + + if (!device_object->num_heci_me_clients) + return; + + for (i = 0; i < device_object->num_heci_me_clients; i++) { + if (device_object->me_clients[i].client_id == file_extension->me_client_id) { + if (device_object->me_clients[i].properteis.single_receive_buffer != 0) { + BUG_ON(device_object->me_clients[i]. + flow_control_credentials <= 0); + device_object->me_clients[i]. + flow_control_credentials--; + } else { + BUG_ON(file_extension-> + flow_control_credentials <= 0); + file_extension->flow_control_credentials--; + } + return; + } + } + BUG_ON(1); +} + +/** + * heci_send_flow_control - send flow control to fw. + * + * @device_object -Device object for our driver + * @file_extension -extension of the file object + * + * @return : + * TRUE if success + * FALSE - otherwise. + */ +int heci_send_flow_control(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension) +{ + struct heci_message_header *heci_header; + struct hbm_flow_control *heci_flow_control; + + heci_header = + (struct heci_message_header *) & device_object-> + write_message_buffer[0]; + heci_header->host_address = 0; + heci_header->me_address = 0; + heci_header->length = sizeof(struct hbm_flow_control); + heci_header->message_complete = 1; + heci_header->reserved = 0; + + heci_flow_control = + (struct hbm_flow_control *) & device_object-> + write_message_buffer[1]; + memset(heci_flow_control, 0, sizeof(heci_flow_control)); + heci_flow_control->host_address = file_extension->host_client_id; + heci_flow_control->me_address = file_extension->me_client_id; + heci_flow_control->command.command = FLOW_CONTROL_CMD; + memset(heci_flow_control->reserved, 0, sizeof(heci_flow_control->reserved)); + DBG("sending flow control host client = %d, me client = %d\n", + file_extension->host_client_id, file_extension->me_client_id); + if (!heci_write_message(device_object, heci_header, + (unsigned char *) heci_flow_control, sizeof(struct hbm_flow_control))) + return FALSE; + return TRUE; + +} + +/** + * other_client_is_connecting - check if other + * client with the same client id is connected. + * + * @device_object -Device object for our driver + * @file_extension -extension of the file object + * + * @return : + * TRUE if other client is connected. + * FALSE - otherwise. + */ +int other_client_is_connecting(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension) +{ + + struct heci_file_private *file_extension_pos = NULL; + struct heci_file_private *file_extension_next = NULL; + list_for_each_entry_safe(file_extension_pos, file_extension_next, &device_object->file_list, link) { + if ((file_extension_pos->state == HECI_FILE_CONNECTING) + && (file_extension_pos != file_extension) + && file_extension->me_client_id == + file_extension_pos->me_client_id) + return TRUE; + } + return FALSE; +} + +/** + * heci_send_wd - send watch dog message to fw. + * + * @device_object -Device object for our driver + * + * @return : + * TRUE if success + * FALSE - otherwise. + */ +int heci_send_wd(struct iamt_heci_device * device_object) +{ + struct heci_message_header *heci_header; + + heci_header = + (struct heci_message_header *) & device_object-> + write_message_buffer[0]; + heci_header->host_address = + device_object->wd_file_extension.host_client_id; + heci_header->me_address = + device_object->wd_file_extension.me_client_id; + heci_header->message_complete = 1; + heci_header->reserved = 0; + + if (!memcmp(device_object->wd_data, interface_start_wd_params, + HECI_WD_PARAMS_SIZE)) { + heci_header->length = HECI_START_WD_DATA_SIZE; + } else { + BUG_ON(memcmp(device_object->wd_data, interface_stop_wd_params, + HECI_WD_PARAMS_SIZE)); + heci_header->length = HECI_WD_PARAMS_SIZE; + } + + if (!heci_write_message(device_object, heci_header, + device_object->wd_data, + heci_header->length)) + return FALSE; + return TRUE; +} + + +/** + * heci_disconnect - send disconnect message to fw. + * + * @device_object -Device object for our driver + * @file_extension -extension of the file object + * + * @return : + * TRUE if success + * FALSE - otherwise. + */ +int heci_disconnect(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension) +{ + struct heci_message_header *heci_header; + struct hbm_client_disconnect_request *heci_cli_disconnect; + + heci_header = + (struct heci_message_header *) & device_object-> + write_message_buffer[0]; + heci_header->host_address = 0; + heci_header->me_address = 0; + heci_header->length = sizeof(struct hbm_client_disconnect_request); + heci_header->message_complete = 1; + heci_header->reserved = 0; + + heci_cli_disconnect = + (struct hbm_client_disconnect_request *) & device_object-> + write_message_buffer[1]; + memset(heci_cli_disconnect, 0, sizeof(heci_cli_disconnect)); + heci_cli_disconnect->host_address = file_extension->host_client_id; + heci_cli_disconnect->me_address = file_extension->me_client_id; + heci_cli_disconnect->command.command = CLIENT_DISCONNECT_REQ_CMD; + heci_cli_disconnect->reserved[0] = 0; + + if (TRUE != heci_write_message(device_object, heci_header, + (unsigned char *) heci_cli_disconnect, sizeof(struct hbm_client_disconnect_request))) + return FALSE; + return TRUE; +} + +/** + * heci_connect - send connect message to fw. + * + * @device_object -Device object for our driver + * @file_extension -extension of the file object + * + * @return : + * TRUE if success + * FALSE - otherwise. + */ +int heci_connect(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension) +{ + struct heci_message_header *heci_header; + struct hbm_client_connect_request *heci_cli_connect; + + heci_header = + (struct heci_message_header *) & device_object-> + write_message_buffer[0]; + heci_header->host_address = 0; + heci_header->me_address = 0; + heci_header->length = sizeof(struct hbm_client_connect_request); + heci_header->message_complete = 1; + heci_header->reserved = 0; + + heci_cli_connect = + (struct hbm_client_connect_request *) & device_object-> + write_message_buffer[1]; + heci_cli_connect->host_address = file_extension->host_client_id; + heci_cli_connect->me_address = file_extension->me_client_id; + heci_cli_connect->command.command = CLIENT_CONNECT_REQ_CMD; + heci_cli_connect->reserved = 0; + if (TRUE != heci_write_message(device_object, heci_header, + (unsigned char *) heci_cli_connect, sizeof(struct hbm_client_connect_request))) + return FALSE; + return TRUE; +} --- linux-2.6.28.orig/ubuntu/heci/Makefile +++ linux-2.6.28/ubuntu/heci/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_HECI) += heci.o + +heci-objs := heci_init.o interrupt.o heci_interface.o io_heci.o heci_main.o --- linux-2.6.28.orig/ubuntu/heci/version.h +++ linux-2.6.28/ubuntu/heci/version.h @@ -0,0 +1,53 @@ +/* + * Part of Intel(R) Manageability Engine Interface Linux driver + * + * Copyright (c) 2006-2007 Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. + * + */ + +#ifndef HECI_VERSION_H +#define HECI_VERSION_H + +#define MAJOR_VERSION 3 +#define MINOR_VERSION 2 +#define QUICK_FIX_NUMBER 0 +#define VER_BUILD 24 + +#define str(s) name(s) +#define name(s) #s +#define DRIVER_VERSION str(MAJOR_VERSION) "." str(MINOR_VERSION) "." str(QUICK_FIX_NUMBER) "." str(VER_BUILD) + +#endif --- linux-2.6.28.orig/ubuntu/heci/interrupt.c +++ linux-2.6.28/ubuntu/heci/interrupt.c @@ -0,0 +1,1413 @@ +/* + * Part of Intel(R) Manageability Engine Interface Linux driver + * + * Copyright (c) 2006-2007 Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. + * + */ + +#include +#include +#include "kcompat.h" +#include "heci.h" +#include "heci_interface.h" + +/** + * interrupt function prototypes + */ + +void heci_bh_handler(struct work_struct *work); +int heci_bh_read_handler(struct io_heci_list *complete_list, + struct iamt_heci_device * device_object, + __s32 * slots); +int heci_bh_write_handler(struct io_heci_list *complete_list, + struct iamt_heci_device * device_object, + __s32 * slots); +void heci_bh_read_bus_message(struct iamt_heci_device * device_object, + struct heci_message_header * heci_header); +int heci_bh_read_pthi_message(struct io_heci_list *complete_list, + struct iamt_heci_device * device_object, + struct heci_message_header * heci_header); +int heci_bh_read_client_message(struct io_heci_list *complete_list, + struct iamt_heci_device * device_object, + struct heci_message_header * heci_header); +void heci_client_connect_response(struct iamt_heci_device * device_object, + struct hbm_client_connect_response * + connect_res); +void heci_client_disconnect_response(struct iamt_heci_device * device_object, + struct hbm_client_connect_response * + disconnect_res); +void heci_client_flow_control_response(struct iamt_heci_device * device_object, + struct hbm_flow_control * flow_control); +void heci_client_disconnect_request(struct iamt_heci_device * device_object, + struct hbm_client_disconnect_request * + disconnect_req); + + +/** + * heci_isr_interrupt - The ISR of the HECI device + * @irq: The irq number + * @dev_id: pointer to the device structure + * @regs: the register values + * + * @return : + * irqreturn_t + */ +irqreturn_t heci_isr_interrupt(int irq, void *dev_id) +{ + int err; + struct iamt_heci_device *device = (struct iamt_heci_device *) dev_id; + device->host_hw_state = read_heci_register(device, H_CSR); + + if ((device->host_hw_state & H_IS) != H_IS) + return IRQ_NONE; + + /* disable interrupts */ + device->host_hw_state &= ~H_IE; + /* acknowledge interrupt and stop interupts */ + write_heci_register(device, H_CSR, device->host_hw_state); + /** + * Our device interrupted, schedule work the heci_bh_handler + * to handle the interrupt processing. This needs to be a + * workqueue item since the handler can sleep. + */ + PREPARE_WORK(&device->work, heci_bh_handler); + DBG("schedule work the heci_bh_handler \n"); + err = schedule_work(&device->work); + if (!err) + HECI_ERR("schedule work the heci_bh_handler failed error=%x\n", + err); + return IRQ_HANDLED; +} + +/** + * heci_bh_handler - function called after ISR to handle the interrupt processing. + * @data: pointer to the device structure + * + * NOTE: This function is called by schedule work + * @return : + * none; + */ +void heci_bh_handler(struct work_struct *work) +{ + struct iamt_heci_device *device = container_of(work, struct iamt_heci_device, work); + struct io_heci_list complete_list; + __s32 slots; + int return_status; + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + struct heci_file_private *file_extension = NULL; + int bus_message_received = FALSE; + struct task_struct *tsk; + + DBG("function called after ISR to handle the interrupt processing.\n"); + /* initialize our complete list */ + spin_lock_bh(&device->device_lock); + heci_initialize_list(&complete_list, device); + device->host_hw_state = read_heci_register(device, H_CSR); + device->me_hw_state = read_heci_register(device, ME_CSR_HA); + + /* check if ME wants a reset */ + if (((device->me_hw_state & ME_RDY_HRA) == 0) && + (device->heci_state != HECI_RESETING) + && (device->heci_state != HECI_INITIALIZING)) { + DBG("FW not ready.\n"); + heci_reset(device, TRUE); + spin_unlock_bh(&device->device_lock); + return; + } + + /* check if we need to start the device */ + if ((device->host_hw_state & H_RDY) == 0) { + + if ((device->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA) { + DBG("we need to start the device.\n"); + device->host_hw_state |= (H_IE | H_IG | H_RDY); + write_heci_register(device, H_CSR, + device->host_hw_state); + if (device->heci_state == HECI_INITIALIZING) { + + device->received_message = TRUE; + spin_unlock_bh(&device->device_lock); + wake_up_interruptible(&device-> + wait_received_message); + return; + + } else { + spin_unlock_bh(&device->device_lock); + tsk = kthread_run(heci_initialize_clients, + device, "heci"); + if (IS_ERR(tsk)) { + int rc = PTR_ERR(tsk); + printk(KERN_WARNING "heci: " + "Unable to start the thread for heci: %d\n", + rc); + } + return; + } + + + } else { + DBG("Enable interrupt FW not ready \n"); + device->host_hw_state |= (H_IE); + write_heci_register(device, H_CSR, + device->host_hw_state); + spin_unlock_bh(&device->device_lock); + return; + } + } + /* check slots avalable for reading */ + slots = count_full_read_slots(device); + DBG("slots =%08x extra_write_index =%08x.\n", slots, + device->extra_write_index); + while ((slots > 0) && (!device->extra_write_index)) { + DBG("slots =%08x extra_write_index =%08x.\n", slots, + device->extra_write_index); + DBG("call heci_bh_read_handler.\n"); + return_status = + heci_bh_read_handler(&complete_list, device, &slots); + if (return_status != ESUCCESS) + goto end; + } + return_status = + heci_bh_write_handler(&complete_list, device, &slots); +end: + DBG("end of bottom half function.\n"); + device->host_hw_state = read_heci_register(device, H_CSR); + device->host_buffer_is_empty = host_buffer_is_empty(device); + + if ((device->host_hw_state & H_IS) == H_IS) { + PREPARE_WORK(&device->work, heci_bh_handler); + DBG("schedule work the heci_bh_handler.\n"); + return_status = schedule_work(&device->work); + if (!return_status) + HECI_ERR("schedule work the heci_bh_handler failed error=%x\n", return_status); + } else { + device->host_hw_state |= H_IE; + } + + write_heci_register(device, H_CSR, device->host_hw_state); + + + if (device->received_message + && waitqueue_active(&device->wait_received_message)) { + DBG("received waiting bus message\n"); + bus_message_received = TRUE; + } + spin_unlock_bh(&device->device_lock); + if (bus_message_received) { + DBG("wake up device->wait_received_message\n"); + wake_up_interruptible(&device->wait_received_message); + bus_message_received = FALSE; + } + if (complete_list.status != ESUCCESS || list_empty(&complete_list.heci_cb.cb_list)){ + return; + } + + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &complete_list.heci_cb.cb_list, cb_list){ + + file_extension = + (struct heci_file_private *) kernel_priv_cb_pos-> + file_private; + list_del(&kernel_priv_cb_pos->cb_list); + if (file_extension && file_extension != &device->legacy_file_extension) { + DBG("completing call back.\n"); + if (kernel_priv_cb_pos->major_file_operations == HECI_WRITE) { + + kfree(kernel_priv_cb_pos-> request_buffer.data); + kernel_priv_cb_pos->request_buffer.data = NULL; + kfree(kernel_priv_cb_pos); + kernel_priv_cb_pos = NULL; + DBG("completing write call back.\n"); + file_extension->writing_state = + HECI_WRITE_COMPLETE; + if (&file_extension->tx_wait && + waitqueue_active (&file_extension->tx_wait)) { + wake_up_interruptible + (&file_extension->tx_wait); + } + } else if (kernel_priv_cb_pos->major_file_operations == HECI_READ + && HECI_READING == file_extension->reading_state) { + DBG("completing read call back information= %lu\n", + kernel_priv_cb_pos->information); + file_extension->reading_state = HECI_READ_COMPLETE; + if (&file_extension->rx_wait + && waitqueue_active (&file_extension->rx_wait)) { + wake_up_interruptible + (&file_extension->rx_wait); + } + + } + } else if (file_extension == &device->legacy_file_extension) { + if (device->legacy_canceled != TRUE) { + device->legacy_state = HECI_LEGACY_READ_COMPLETE; + device->legacy_stall_timer = 0; + memcpy(kernel_priv_cb_pos->response_buffer. + data, + device-> + legacy_message_buffer, + device-> + legacy_message_buffer_index); + list_add_tail(&kernel_priv_cb_pos->cb_list, + &device-> + pthi_read_complete_list. + heci_cb.cb_list); + DBG("pthi read completed\n"); + } else { + run_next_legacy_cmd(device); + } + if (&device->legacy_file_extension.wait) { + DBG("completing pthi call back.\n"); + wake_up_interruptible(&device-> + legacy_file_extension. + wait); + + } + + } + } + return; +} + + +/** + * heci_bh_read_handler - bottom half read routine after ISR to handle the read processing. + * + * + * @complete_list - An instance of our list structure + * @device_object - Device object for our driver + * @slots - slots to read. + * @return : + * 0 on success, + * negative on failure. + */ +int heci_bh_read_handler(struct io_heci_list *complete_list, + struct iamt_heci_device * device_object, + __s32 * slots) +{ + struct heci_message_header *heci_header; + int ret = ESUCCESS; + struct heci_file_private *file_extension_pos = NULL; + struct heci_file_private *file_extension_next = NULL; + if (!device_object->read_message_header) { + device_object->read_message_header = + read_heci_register(device_object, ME_CB_RW); + DBG("slots=%08x.\n", *slots); + (*slots)--; + DBG("slots=%08x.\n", *slots); + } + heci_header = + (struct heci_message_header *) & device_object->read_message_header; + DBG("heci_header->length =%d\n", heci_header->length); + + if ((heci_header->reserved) + || !(device_object->read_message_header)) { + DBG("corrupted message header.\n"); + ret = -ECORRUPTED_MESSAGE_HEADER; + goto end; + } + if (heci_header->host_address || heci_header->me_address) { + + list_for_each_entry_safe(file_extension_pos, file_extension_next, &device_object->file_list, link) { + DBG("list_for_each_entry_safe read host client = %d, ME client = %d\n", + file_extension_pos->host_client_id, + file_extension_pos->me_client_id); + if ((file_extension_pos->host_client_id == heci_header->host_address) + && (file_extension_pos->me_client_id == heci_header->me_address)) + break; + } + + if (&file_extension_pos->link==&device_object->file_list) { + DBG("corrupted message header\n"); + ret = -ECORRUPTED_MESSAGE_HEADER; + goto end; + + } + } + if (((*slots) * sizeof(__u32)) < heci_header->length) { + DBG("we can't read the message slots=%08x.\n", *slots); + /* we can't read the message */ + ret = -ERANGE; + goto end; + } + + + /* decide where to read the message too */ + if (!heci_header->host_address) { + DBG("call heci_bh_read_bus_message.\n"); + heci_bh_read_bus_message(device_object, heci_header); + DBG("end heci_bh_read_bus_message.\n"); + } else if (heci_header->host_address == + device_object->legacy_file_extension.host_client_id + && HECI_FILE_CONNECTED == + device_object->legacy_file_extension.state + && device_object->legacy_state == HECI_LEGACY_READING) { + DBG("call heci_bh_read_legacy_message.\n"); + DBG("heci_header->length =%d\n", heci_header->length); + ret = + heci_bh_read_pthi_message(complete_list, device_object, + heci_header); + if (ret != ESUCCESS) + goto end; + } else { + DBG("call heci_bh_read_client_message.\n"); + ret = heci_bh_read_client_message(complete_list, + device_object, + heci_header); + if (ret != ESUCCESS) + goto end; + } + + /* reset the number of slots and header */ + *slots = count_full_read_slots(device_object); + device_object->read_message_header = 0; + + if (*slots == -ESLOTS_OVERFLOW) { /* overflow - reset */ + DBG("reseting due to slots overflow\n"); + /* set the event since message has been read */ + ret = -ERANGE; + goto end; + } +end: + + return ret; + +} + + +/** + * heci_bh_read_bus_message - bottom half read routine after ISR to handle the read bus message + * command processing. + * + * + * @complete_list - An instance of our list structure + * @device_object - Device object for our driver + * @buffer - message buffer will be filled + * @heci_header - header of bus message + * + * @return : + * none; + */ +void heci_bh_read_bus_message(struct iamt_heci_device * device_object, + struct heci_message_header * heci_header) +{ + struct heci_bus_message *heci_message; + struct hbm_host_version_response *version_res; + struct hbm_client_connect_response *connect_res; + struct hbm_client_connect_response *disconnect_res; + struct hbm_flow_control *flow_control; + struct hbm_host_client_properties_response *properteis_res; + struct hbm_host_enumeration_response *enum_res; + struct hbm_client_disconnect_request *disconnect_req; + struct hbm_host_stop_request *h_stop_req; + int i; + unsigned char *buffer; + buffer = NULL; + /* read the message to our buffer */ + buffer = (unsigned char *) device_object->read_message_buffer; + BUG_ON(heci_header->length >= + sizeof(device_object->read_message_buffer)); + heci_read_slots(device_object, buffer, heci_header->length); + heci_message = (struct heci_bus_message *) buffer; + + switch (*(__u8 *) heci_message) { + case HOST_START_RES_CMD: + version_res = (struct hbm_host_version_response *) heci_message; + if (version_res->host_version_supported) { + device_object->version.major_version = + HBM_MAJOR_VERSION; + device_object->version.minor_version = + HBM_MINOR_VERSION; + } else { + device_object->version = + version_res->me_max_version; + } + device_object->received_message = TRUE; + DBG("host start response message received.\n"); + break; + + case CLIENT_CONNECT_RES_CMD: + connect_res = + (struct hbm_client_connect_response *) heci_message; + heci_client_connect_response(device_object, connect_res); + DBG("client connect response message received.\n"); + wake_up(&device_object->wait_received_message); + break; + + case CLIENT_DISCONNECT_RES_CMD: + disconnect_res = + (struct hbm_client_connect_response *) heci_message; + heci_client_disconnect_response(device_object, + disconnect_res); + DBG("client disconnect response message received.\n"); + wake_up(&device_object->wait_received_message); + break; + + case FLOW_CONTROL_CMD: + flow_control = (struct hbm_flow_control *) heci_message; + heci_client_flow_control_response(device_object, + flow_control); + DBG("client flow control response message received.\n"); + break; + case HOST_CLIENT_PROPERTEIS_RES_CMD: + properteis_res = + (struct hbm_host_client_properties_response *) heci_message; + + + if (properteis_res->status != 0) { + BUG_ON(1); + break; + } + for (i = 0; i < device_object->num_heci_me_clients; i++) { + if (device_object->me_clients[i].client_id == + properteis_res->address) { + device_object->me_clients[i].properteis = + properteis_res->client_properties; + break; + } + + } + device_object->received_message = TRUE; + break; + case HOST_ENUM_RES_CMD: + enum_res = + (struct hbm_host_enumeration_response *) heci_message; + memcpy(device_object->heci_me_clients, + enum_res->valid_addresses, 32); + device_object->received_message = TRUE; + break; + case HOST_STOP_RES_CMD: + device_object->heci_state = HECI_DISABLED; + DBG("Reseting becase of FW stop response\n"); + heci_reset(device_object, TRUE); + break; + case CLIENT_DISCONNECT_REQ_CMD: + /* search for client */ + disconnect_req = + (struct hbm_client_disconnect_request *) heci_message; + heci_client_disconnect_request(device_object, + disconnect_req); + break; + case ME_STOP_REQ_CMD: + /* prepare stop request */ + heci_header = + (struct heci_message_header *) & device_object-> + extra_message_buffer[0]; + heci_header->host_address = 0; + heci_header->me_address = 0; + heci_header->length = sizeof(struct hbm_host_stop_request); + heci_header->message_complete = 1; + heci_header->reserved = 0; + h_stop_req = + (struct hbm_host_stop_request *) & device_object-> + extra_message_buffer[1]; + memset(h_stop_req, 0, sizeof(struct hbm_host_stop_request)); + h_stop_req->command.command = HOST_STOP_REQ_CMD; + h_stop_req->reason = DRIVER_STOP_REQUEST; + h_stop_req->reserved[0] = 0; + h_stop_req->reserved[1] = 0; + device_object->extra_write_index = 2; + break; + + default: + BUG_ON(1); + break; + + } + + return; + +} + +/** + * heci_bh_read_legacy_message - bottom half read routine after ISR to handle the read legacy message + * data processing. + * + * + * @complete_list - An instance of our list structure + * @device_object - Device object for our driver + * @buffer - message buffer will be filled + * @heci_header - header of legacy message + * + * @return : + * 0 on success, + * negative on failure. + */ +int heci_bh_read_pthi_message(struct io_heci_list *complete_list, + struct iamt_heci_device * device_object, + struct heci_message_header * heci_header) +{ + struct heci_file_private *file_extension = NULL; + struct heci_cb_private *priv_cb = NULL; + int return_status = ESUCCESS; + unsigned char *buffer = NULL; + BUG_ON(heci_header->me_address != + device_object->legacy_file_extension.me_client_id); + BUG_ON(device_object->legacy_state != HECI_LEGACY_READING); + buffer = + (unsigned char *) (device_object->legacy_message_buffer + + device_object->legacy_message_buffer_index); + BUG_ON(sizeof(device_object->legacy_message_buffer) < + (device_object->legacy_message_buffer_index + + heci_header->length)); + heci_read_slots(device_object, buffer, heci_header->length); + + device_object->legacy_message_buffer_index += heci_header->length; + + if (heci_header->message_complete) { + DBG("pthi_message_buffer_index=%d\n", heci_header->length); + DBG("completed pthi read.\n "); + if (!device_object->legacy_current_cb) + return -ENODEV; + priv_cb = device_object->legacy_current_cb; + device_object->legacy_current_cb = NULL; + file_extension = + (struct heci_file_private *) priv_cb->file_private; + if (!file_extension) + return -ENODEV; + device_object->legacy_stall_timer = 0; + priv_cb->information = + device_object->legacy_message_buffer_index; + priv_cb->read_time = get_seconds(); + if (device_object->legacy_ioctl + && file_extension == &device_object->legacy_file_extension) { + /* found the legacy cb */ + DBG("complete the pthi read cb.\n "); + if (&device_object->legacy_file_extension) { + DBG("add the pthi read cb to complete.\n "); + list_add_tail(&priv_cb->cb_list, + &complete_list->heci_cb. + cb_list); + + } + } + } + return return_status; + +} + +/** + * heci_bh_read_client_message - bottom half read routine after ISR to handle the read heci client message + * data processing. + * + * + * @complete_list - An instance of our list structure + * @device_object - Device object for our driver + * @buffer - message buffer will be filled + * @heci_header - header of heci client message + * + * @return : + * 0 on success, + * negative on failure. + */ +int heci_bh_read_client_message(struct io_heci_list *complete_list, + struct iamt_heci_device * device_object, + struct heci_message_header * heci_header) +{ + struct heci_file_private *file_extension = NULL; + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + unsigned char *buffer = NULL; + DBG ("Start client msg \n"); + if (device_object->read_list.status == ESUCCESS + && !list_empty(&device_object->read_list.heci_cb.cb_list)) { + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device_object-> + read_list.heci_cb.cb_list, cb_list){ + file_extension = (struct heci_file_private *) kernel_priv_cb_pos->file_private; + if ((file_extension->host_client_id == heci_header->host_address) + && (file_extension->me_client_id == heci_header->me_address) + && (file_extension->state == HECI_FILE_CONNECTED) + && (HECI_READ_COMPLETE != file_extension->reading_state)) { + spin_lock(&file_extension->read_io_lock); + file_extension->reading_state = + HECI_READING; + buffer = (unsigned char *) (kernel_priv_cb_pos->response_buffer.data + + kernel_priv_cb_pos->information); + BUG_ON(kernel_priv_cb_pos->response_buffer.size < heci_header->length + + kernel_priv_cb_pos->information); + + if (kernel_priv_cb_pos->response_buffer.size < heci_header->length + + kernel_priv_cb_pos->information) { + DBG(" message overflow.\n"); + list_del(&kernel_priv_cb_pos->cb_list); + spin_unlock(&file_extension-> + read_io_lock); + return -ENOMEM; + } + if (buffer) + heci_read_slots(device_object, + buffer, + heci_header-> + length); + kernel_priv_cb_pos->information += + heci_header->length; + if (heci_header->message_complete) { + file_extension->status = ESUCCESS; + list_del(&kernel_priv_cb_pos->cb_list); + spin_unlock(&file_extension-> + read_io_lock); + DBG("completed read host client = %d, ME client = %d, data length = %lu\n", + file_extension->host_client_id, + file_extension->me_client_id, + kernel_priv_cb_pos->information); + *(kernel_priv_cb_pos->response_buffer.data + kernel_priv_cb_pos->information) = '\0'; + DBG("kernel_priv_cb_pos->response_buffer - %s\n", + kernel_priv_cb_pos->response_buffer.data); + list_add_tail(&kernel_priv_cb_pos->cb_list, + &complete_list->heci_cb.cb_list); + } else { + spin_unlock(&file_extension-> + read_io_lock); + } + + break; + } + + } + + } + DBG ("Message read\n"); + if (!buffer) { + heci_read_slots(device_object, + (unsigned char *) device_object-> + read_message_buffer, heci_header->length); + DBG("discarding message, header=%08x.\n", + *(__u32 *) device_object->read_message_buffer); + } + + return ESUCCESS; +} + + +/** + * heci_bh_write_handler - bottom half write routine after ISR to handle the write processing. + * + * + * @complete_list - An instance of our list structure + * @device_object - Device object for our driver + * @slots - slots to write. + * @return : + * 0 on success, + * negative on failure. + */ +int heci_bh_write_handler(struct io_heci_list *complete_list, + struct iamt_heci_device * device_object, + __s32 * slots) +{ + + struct heci_message_header *heci_header = NULL; + struct heci_file_private *file_extension = NULL; + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + + + if (!host_buffer_is_empty(device_object)) { + DBG("host buffer is not empty.\n"); + return ESUCCESS; + } + device_object->write_hang = -1; + *slots = count_empty_write_slots(device_object); + /* complete all waiting for write CB */ + DBG("complete all waiting for write CB.\n"); + if (device_object->write_waiting_list.status == ESUCCESS + && !list_empty(&device_object->write_waiting_list.heci_cb.cb_list)) { + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device_object-> + write_waiting_list.heci_cb.cb_list, cb_list){ + file_extension = (struct heci_file_private *) kernel_priv_cb_pos->file_private; + file_extension->status = ESUCCESS; + list_del(&kernel_priv_cb_pos->cb_list); + if (HECI_WRITING == file_extension->writing_state + && kernel_priv_cb_pos->major_file_operations == HECI_WRITING + && file_extension != &device_object->legacy_file_extension) { + DBG("HECI WRITE COMPLETE\n"); + file_extension->writing_state = HECI_WRITE_COMPLETE; + list_add_tail(&kernel_priv_cb_pos->cb_list, + &complete_list->heci_cb. + cb_list); + } + if (file_extension == &device_object->legacy_file_extension) { + DBG("check legacy flow control\n"); + if (device_object-> legacy_flow_control_pending) { + if (((*slots) * sizeof(__u32)) >= (sizeof(struct heci_message_header) + + sizeof(struct hbm_flow_control))) { + *slots -= (sizeof(struct heci_message_header) + + sizeof(struct hbm_flow_control) + 3) / 4; + if (!heci_send_flow_control (device_object, + &device_object->legacy_file_extension)) { + DBG("legacy flow control failed\n"); + } else { + DBG("legacy flow control success\n"); + device_object->legacy_state = HECI_LEGACY_READING; + device_object->legacy_flow_control_pending = FALSE; + device_object->legacy_message_buffer_index = 0; + device_object->legacy_message_buffer_size = 0; + device_object->legacy_stall_timer = LEGACY_STALL_TIMER; + device_object->host_buffer_is_empty = + host_buffer_is_empty(device_object); + } + } else { + return -ECOMPLETE_MESSAGE; + } + } + } + + } + } + + if (device_object->stop && !device_object->wd_pending) { + device_object->wd_stoped = TRUE; + wake_up_interruptible(&device_object->wait_stop_wd); + return ESUCCESS; + } + + if (device_object->extra_write_index != 0) { + DBG("extra_write_index =%d\n", + device_object->extra_write_index); + heci_write_message(device_object, + (struct heci_message_header *) & + device_object->extra_message_buffer[0], + (unsigned char *) &device_object-> + extra_message_buffer[1], + (device_object->extra_write_index - + 1) * sizeof(__u32)); + *slots -= device_object->extra_write_index; + device_object->extra_write_index = 0; + } + if (device_object->heci_state == HECI_ENABLED){ + if (device_object->wd_pending + && flow_control_credentials(device_object, + &device_object->wd_file_extension)) { + if (!heci_send_wd(device_object)) + DBG("Wd send failed\n"); + else + flow_control_reduce(device_object, + &device_object-> + wd_file_extension); + device_object->wd_pending = 0; + + if (device_object->wd_timeout != 0) { + *slots -= + (sizeof(struct heci_message_header) + + HECI_START_WD_DATA_SIZE + 3) / 4; + device_object->wd_due_counter = 2; + } else { + *slots -= + (sizeof(struct heci_message_header) + + HECI_WD_PARAMS_SIZE + 3) / 4; + device_object->wd_due_counter = 0; + } + + } + } + if (device_object->stop) + return ~ENODEV; + + /* complete control write list CB */ + if (device_object->control_write_list.status == ESUCCESS) { + /* complete control write list CB */ + DBG("complete control write list CB\n "); + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device_object-> + control_write_list.heci_cb.cb_list, cb_list){ + file_extension = + (struct heci_file_private *) kernel_priv_cb_pos-> + file_private; + if (!file_extension) { + list_del(&kernel_priv_cb_pos->cb_list); + return -ENODEV; + } + switch (kernel_priv_cb_pos->major_file_operations) { + case HECI_CLOSE: + /* send disconnect message */ + if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_message_header) + + sizeof(struct hbm_client_disconnect_request))) { + *slots -= (sizeof(struct heci_message_header) + + sizeof(struct hbm_client_disconnect_request) + 3) / 4; + if (!heci_disconnect(device_object, + file_extension)) { + file_extension->status = ESUCCESS; + kernel_priv_cb_pos->information = 0; + list_del(&kernel_priv_cb_pos->cb_list); + list_add_tail(&kernel_priv_cb_pos->cb_list, + &complete_list->heci_cb. + cb_list); + return -ECOMPLETE_MESSAGE; + } else { + file_extension->state = HECI_FILE_DISCONNECTING; + file_extension->status = ESUCCESS; + kernel_priv_cb_pos->information = 0; + list_del(&kernel_priv_cb_pos->cb_list); + list_add_tail(&kernel_priv_cb_pos->cb_list, + &device_object->control_read_list. + heci_cb.cb_list); + file_extension->timer_count = CONNECT_TIMEOUT; + } + } else { + /* return the cancel routine */ + return -ECORRUPTED_MESSAGE_HEADER; + } + break; + case HECI_READ: + /* send flow control message */ + if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_message_header) + + sizeof(struct hbm_flow_control))) { + *slots -= (sizeof(struct heci_message_header) + + sizeof(struct hbm_flow_control) + 3) / 4; + if (!heci_send_flow_control(device_object, file_extension)) { + file_extension->status = -ENODEV; + kernel_priv_cb_pos->information = 0; + list_del(&kernel_priv_cb_pos->cb_list); + list_add_tail(&kernel_priv_cb_pos->cb_list, + &complete_list->heci_cb. + cb_list); + return -ENODEV; + + } else { + list_del(&kernel_priv_cb_pos->cb_list); + list_add_tail(&kernel_priv_cb_pos->cb_list, + &device_object->read_list. + heci_cb.cb_list); + } + } else { + /* return the cancel routine */ + list_del(&kernel_priv_cb_pos->cb_list); + return -ECORRUPTED_MESSAGE_HEADER; + } + break; + case HECI_IOCTL: + /* connect message */ + if (!other_client_is_connecting(device_object, file_extension)) { + continue; + } + if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_message_header) + + sizeof(struct hbm_client_connect_request))) { + file_extension->state = HECI_FILE_CONNECTING; + *slots -= (sizeof(struct heci_message_header) + + sizeof(struct hbm_client_connect_request) + 3) / 4; + if (!heci_connect(device_object, file_extension)) { + file_extension->status = -ENODEV; + kernel_priv_cb_pos->information = 0; + list_del(&kernel_priv_cb_pos->cb_list); + return -ENODEV; + } else { + list_del(&kernel_priv_cb_pos->cb_list); + list_add_tail(&kernel_priv_cb_pos->cb_list, + &device_object->control_read_list. + heci_cb.cb_list); + file_extension->timer_count = CONNECT_TIMEOUT; + } + } else { + /* return the cancel routine */ + list_del(&kernel_priv_cb_pos->cb_list); + return -ECORRUPTED_MESSAGE_HEADER; + } + break; + + default: + BUG_ON(1); + } + + } + } + /* complete write list CB */ + if (device_object->write_list.status == ESUCCESS + && !list_empty(&device_object->write_list.heci_cb.cb_list)) { + DBG("complete write list CB \n"); + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device_object-> + write_list.heci_cb.cb_list, cb_list){ + file_extension = (struct heci_file_private *) kernel_priv_cb_pos->file_private; + + if ((file_extension != NULL) + && (file_extension != &device_object->legacy_file_extension)) { + if (!flow_control_credentials(device_object, + file_extension)) { + DBG("No flow control credentials for client %d, not sending\n", + file_extension->host_client_id); + continue; + } + if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_message_header) + + (kernel_priv_cb_pos->request_buffer.size - kernel_priv_cb_pos->information))) { + heci_header = (struct heci_message_header *) & device_object->write_message_buffer[0]; + heci_header->host_address = file_extension->host_client_id; + heci_header->me_address = file_extension->me_client_id; + heci_header->length = ((kernel_priv_cb_pos->request_buffer.size) - + (kernel_priv_cb_pos->information)); + heci_header->message_complete = 1; + heci_header->reserved = 0; + DBG("kernel_priv_cb_pos->request_buffer.size =%d heci_header->message_complete= %d\n", + kernel_priv_cb_pos->request_buffer.size, + heci_header->message_complete); + DBG("kernel_priv_cb_pos->information =%lu\n", + kernel_priv_cb_pos->information); + DBG("heci_header->length =%d\n", + heci_header->length); + *slots -= (sizeof(struct heci_message_header) + heci_header->length + 3) / 4; + if (!heci_write_message (device_object, heci_header, + (unsigned char *) (kernel_priv_cb_pos-> request_buffer.data + kernel_priv_cb_pos->information), + heci_header->length)) { + file_extension->status = -ENODEV; + list_del(&kernel_priv_cb_pos->cb_list); + list_add_tail(&kernel_priv_cb_pos->cb_list, + &complete_list->heci_cb. + cb_list); + return -ENODEV; + } else { + flow_control_reduce + (device_object, file_extension); + file_extension->status = ESUCCESS; + kernel_priv_cb_pos->information += heci_header->length; + list_del(&kernel_priv_cb_pos->cb_list); + list_add_tail(&kernel_priv_cb_pos->cb_list, + &device_object->write_waiting_list. + heci_cb.cb_list); + } + } else if (*slots == ((device_object->host_hw_state & H_CBD) >> 24)) { /* buffer is still empty */ + heci_header = (struct heci_message_header *) & device_object->write_message_buffer[0]; + heci_header->host_address = file_extension->host_client_id; + heci_header->me_address = file_extension->me_client_id; + heci_header->length = (*slots * sizeof(__u32)) - sizeof(struct heci_message_header); + heci_header->message_complete = 0; + heci_header->reserved = 0; + + (*slots) -= (sizeof(struct heci_message_header) + heci_header->length + 3) / 4; + if (!heci_write_message(device_object, heci_header, + (unsigned char *) (kernel_priv_cb_pos->request_buffer. data + kernel_priv_cb_pos->information), + heci_header->length)) { + file_extension->status = -ENODEV; + list_del(&kernel_priv_cb_pos->cb_list); + list_add_tail(&kernel_priv_cb_pos->cb_list, &complete_list->heci_cb.cb_list); + return -ENODEV; + } else { + kernel_priv_cb_pos->information += heci_header->length; + DBG("kernel_priv_cb_pos->request_buffer.size =%d heci_header->message_complete= %d\n", + kernel_priv_cb_pos->request_buffer.size, + heci_header->message_complete); + DBG("kernel_priv_cb_pos->information =%lu\n", kernel_priv_cb_pos->information); + DBG("heci_header->length =%d\n", heci_header->length); + } + return -ECOMPLETE_MESSAGE; + } else { + return -ECORRUPTED_MESSAGE_HEADER; + } + } else if (file_extension == &device_object->legacy_file_extension) { /* LEGACY IOCTL */ + DBG("complete pthi write cb\n"); + if (!flow_control_credentials(device_object, file_extension)) { + DBG("No flow control credentials for pthi client %d, not sending\n", + file_extension->host_client_id); + continue; + } + if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_message_header) + + device_object->legacy_message_buffer_size - device_object->legacy_message_buffer_index)) { + heci_header = (struct heci_message_header *) & device_object->write_message_buffer[0]; + heci_header->host_address = file_extension->host_client_id; + heci_header->me_address = file_extension->me_client_id; + heci_header->length = device_object->legacy_message_buffer_size - + device_object->legacy_message_buffer_index; + heci_header->message_complete = 1; + heci_header->reserved = 0; + + *slots -= (sizeof(struct heci_message_header) + heci_header->length + 3) / 4; + + if (!heci_write_message (device_object, heci_header, + (device_object->legacy_message_buffer + device_object->legacy_message_buffer_index), + heci_header->length)) { + device_object->legacy_state = HECI_LEGACY_IDLE; + file_extension->status = -ENODEV; + list_del(&kernel_priv_cb_pos->cb_list); + return -ENODEV; + } else { + flow_control_reduce (device_object, file_extension); + device_object->legacy_message_buffer_index += heci_header->length; + list_del(&kernel_priv_cb_pos->cb_list); + kernel_priv_cb_pos->information = device_object->legacy_message_buffer_index; + file_extension->status = ESUCCESS; + device_object->legacy_state = HECI_LEGACY_FLOW_CONTROL; + device_object->legacy_flow_control_pending = TRUE; + /* save legacy cb sent to pthi client */ + device_object->legacy_current_cb = kernel_priv_cb_pos; + list_add_tail(&kernel_priv_cb_pos->cb_list, + &device_object->write_waiting_list.heci_cb. cb_list); + + } + } else if (*slots == ((device_object->host_hw_state & H_CBD) >> 24)) { /* buffer is still empty */ + heci_header = (struct heci_message_header *) & device_object->write_message_buffer[0]; + heci_header->host_address = file_extension->host_client_id; + heci_header->me_address = file_extension->me_client_id; + heci_header->length = (*slots * sizeof(__u32)) - sizeof(struct heci_message_header); + heci_header->message_complete = 0; + heci_header->reserved = 0; + + *slots -= (sizeof(struct heci_message_header) + heci_header->length + 3) / 4; + + if (!heci_write_message (device_object, heci_header, (device_object->legacy_message_buffer + + device_object->legacy_message_buffer_index), heci_header->length)) { + file_extension->status = -ENODEV; + list_del(&kernel_priv_cb_pos->cb_list); + } else { + device_object->legacy_message_buffer_index += heci_header->length; + } + return -ECOMPLETE_MESSAGE; + } else { + return -ECORRUPTED_MESSAGE_HEADER;; + } + } + + } + + } + return ESUCCESS; +} + + +/** + * is_treat_specially_client - check if the message belong + * to the file extension . + * @file_extension -extension of the file object + * @connect_res -connect response bus message + * @device_object -Device object for our driver + * + * @return : + * TRUE if empty + * FALSE - otherwise. + */ +int is_treat_specially_client(struct heci_file_private * file_extension, + struct hbm_client_connect_response * + connect_res) +{ + int ret = FALSE; + if ((file_extension->host_client_id == connect_res->host_address) + && (file_extension->me_client_id == connect_res->me_address)) { + + if (connect_res->status == 0) { + DBG("client connect status = 0x%08x.\n", + connect_res->status); + file_extension->state = HECI_FILE_CONNECTED; + file_extension->status = ESUCCESS; + } else { + DBG("client connect status = 0x%08x.\n", + connect_res->status); + file_extension->state = HECI_FILE_DISCONNECTED; + file_extension->status = -ENODEV; + } + ret = TRUE; + } + DBG("client state = %d.\n", file_extension->state); + return ret; + +} + +/** + * heci_client_connect_response - connect response bh routine + * + * @device_object -Device object for our driver + * @connect_res -connect response bus message + * @complete_list - An instance of our list structure + * + * @return : + * none; + */ +void heci_client_connect_response(struct iamt_heci_device * device_object, + struct hbm_client_connect_response * + connect_res) +{ + + struct heci_file_private *file_extension = NULL; + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + + /* if WD or legacy client treat specially */ + + if ((is_treat_specially_client(&(device_object->wd_file_extension), + connect_res)) + || (is_treat_specially_client(& + (device_object-> + legacy_file_extension), + connect_res))) { + return; + } + + if (device_object->control_read_list.status == ESUCCESS + && !list_empty(&device_object->control_read_list.heci_cb. + cb_list)) { + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device_object->control_read_list.heci_cb.cb_list, cb_list){ + file_extension = + (struct heci_file_private *) kernel_priv_cb_pos-> + file_private; + if (!file_extension) { + list_del(&kernel_priv_cb_pos->cb_list); + return; + } + if (HECI_IOCTL == kernel_priv_cb_pos->major_file_operations) { + + if (is_treat_specially_client (file_extension, connect_res)) { + list_del(&kernel_priv_cb_pos->cb_list); + file_extension->status = ESUCCESS; + file_extension->timer_count = 0; + break; + } + } + } + } + return; +} + +/** + * heci_client_disconnect_response - disconnect response bh routine + * + * @device_object -Device object for our driver + * @disconnect_res -disconnect response bus message + * @complete_list - An instance of our list structure + * + * @return : + * none; + */ +void heci_client_disconnect_response(struct iamt_heci_device * device_object, + struct hbm_client_connect_response * + disconnect_res) +{ + struct heci_file_private *file_extension = NULL; + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + if (device_object->control_read_list.status == ESUCCESS + && !list_empty(&device_object->control_read_list.heci_cb. + cb_list)) { + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device_object->control_read_list.heci_cb.cb_list, cb_list){ + file_extension = + (struct heci_file_private *) kernel_priv_cb_pos-> + file_private; + + if (!file_extension) { + list_del(&kernel_priv_cb_pos->cb_list); + return; + } + + DBG("list_for_each_entry_safe in control_read_list.\n"); + if ((file_extension->host_client_id == disconnect_res->host_address) + && (file_extension->me_client_id == disconnect_res->me_address)) { + list_del(&kernel_priv_cb_pos->cb_list); + if (disconnect_res->status == 0) + file_extension->state = HECI_FILE_DISCONNECTED; + file_extension->status = ESUCCESS; + file_extension->timer_count = 0; + break; + } + } + } + return; +} + +/** + * heci_client_flow_control_response - flow control response bh routine + * + * @device_object -Device object for our driver + * @flow_control -flow control response bus message + * + * @return : + * none; + */ +void heci_client_flow_control_response(struct iamt_heci_device * device_object, + struct hbm_flow_control * flow_control) +{ + struct heci_file_private *file_extension_pos = NULL; + struct heci_file_private *file_extension_next = NULL; + int i; + if (flow_control->host_address == 0) { /* single receive buffer */ + for (i = 0; i < device_object->num_heci_me_clients; i++) { + if (flow_control->me_address == + device_object->me_clients[i].client_id) { + if (device_object->me_clients[i].properteis.single_receive_buffer != 0) { + device_object->me_clients[i]. + flow_control_credentials++; + DBG("received flow control message for ME client %d (single receive buffer).\n", + flow_control->me_address); + DBG("flow control credentials=%d.\n", + device_object->me_clients[i].flow_control_credentials); + } else { + BUG_ON(1); /* error in flow control */ + } + } + } + } else { /* normal connection */ + list_for_each_entry_safe(file_extension_pos, file_extension_next, &device_object->file_list, link) { + DBG("list_for_each_entry_safe in file_list\n"); + + DBG("file_extension of host client %d ME client %d.\n", + file_extension_pos->host_client_id, + file_extension_pos->me_client_id); + DBG("flow control message for host client %d ME client %d.\n", + flow_control->host_address, + flow_control->me_address); + if ((file_extension_pos->host_client_id == flow_control->host_address) + && (file_extension_pos->me_client_id == flow_control->me_address)) { + DBG("received flow control message for host client %d ME client %d.\n", + flow_control->host_address, + flow_control->me_address); + file_extension_pos->flow_control_credentials++; + DBG("flow control credentials=%d.\n", + file_extension_pos->flow_control_credentials); + break; + } + } + } + return; +} + +/** + * heci_client_disconnect_request - disconnect request bh routine + * + * @device_object -Device object for our driver + * @disconnect_req -disconnect request bus message + * + * @return : + * none; + */ +void heci_client_disconnect_request(struct iamt_heci_device * device_object, + struct hbm_client_disconnect_request * + disconnect_req) +{ + struct heci_message_header *heci_header; + struct hbm_client_connect_response *disconnect_res; + struct heci_file_private *file_extension_pos = NULL; + struct heci_file_private *file_extension_next = NULL; + + list_for_each_entry_safe(file_extension_pos, file_extension_next, &device_object->file_list, link) { + if ((file_extension_pos->host_client_id == disconnect_req->host_address) + && (file_extension_pos->me_client_id == disconnect_req->me_address)) { + DBG("received disconnect request for host client %d ME client %d.\n", + disconnect_req->host_address, + disconnect_req->me_address); + file_extension_pos->state = HECI_FILE_DISCONNECTED; + file_extension_pos->timer_count = 0; + if (file_extension_pos == &device_object->wd_file_extension) { + device_object->wd_due_counter = 0; + device_object->wd_pending = FALSE; + } else if (file_extension_pos == + &device_object->legacy_file_extension) { + device_object->legacy_timer = 0; + } + + /* prepare disconnect response */ + heci_header = (struct heci_message_header *) & device_object->extra_message_buffer[0]; + heci_header->host_address = 0; + heci_header->me_address = 0; + heci_header->length = sizeof(struct hbm_client_connect_response); + heci_header->message_complete = 1; + heci_header->reserved = 0; + + disconnect_res = (struct hbm_client_connect_response *) & + device_object->extra_message_buffer[1]; + disconnect_res->host_address = + file_extension_pos->host_client_id; + disconnect_res->me_address = file_extension_pos->me_client_id; + *(__u8 *) (&disconnect_res->command) = CLIENT_DISCONNECT_RES_CMD; + disconnect_res->status = 0; + device_object->extra_write_index = 2; + break; + } + } + return; +} + + +/** + * heci_timer - timer function . + * @data: pointer to the device structure + * + * NOTE: This function is called by timer interrupt work + * @return : + * none; + */ +void heci_wd_timer(unsigned long data) +{ + struct iamt_heci_device *device = (struct iamt_heci_device *) data; + DBG("send watchdog.\n"); + spin_lock_bh(&device->device_lock); + if (device->heci_state != HECI_ENABLED) { + mod_timer(&device->wd_timer, round_jiffies(jiffies + 2 * HZ)); + spin_unlock_bh(&device->device_lock); + return; + } + if (device->wd_file_extension.state != HECI_FILE_CONNECTED) { + mod_timer(&device->wd_timer, round_jiffies(jiffies + 2 * HZ)); + spin_unlock_bh(&device->device_lock); + return; + } + /*** Watchdog ***/ + if (device->wd_due_counter != 0 && FALSE == device->wd_bypass) { + if (--device->wd_due_counter == 0) { + if (device->host_buffer_is_empty && + flow_control_credentials(device, + &device-> + wd_file_extension)) { + device->host_buffer_is_empty = FALSE; + + if (!heci_send_wd(device)) + DBG("Wd send failed\n"); + else + flow_control_reduce(device, + &device-> + wd_file_extension); + if (device->wd_timeout != 0) + device->wd_due_counter = 2; + else + device->wd_due_counter = 0; + } else { + device->wd_pending = TRUE; + } + } + } + if (device->legacy_stall_timer != 0) { + if (--device->legacy_stall_timer == 0) { + DBG("Reseting because of hang to PTHI\n"); + heci_reset(device, TRUE); + device->legacy_message_buffer_size = 0; + device->legacy_message_buffer_index = 0; + device->legacy_canceled = FALSE; + device->legacy_ioctl = TRUE; + device->legacy_state = HECI_LEGACY_IDLE; + device->legacy_timer = 0; + spin_unlock_bh(&device->device_lock); + + if (device->legacy_current_cb) { + kfree(device->legacy_current_cb->request_buffer.data); + device->legacy_current_cb->request_buffer.data = NULL; + kfree(device->legacy_current_cb->response_buffer.data); + device->legacy_current_cb->response_buffer.data = NULL; + kfree(device->legacy_current_cb); + } + spin_lock_bh(&device->device_lock); + device->legacy_file_object = NULL; + device->legacy_current_cb = NULL; + run_next_legacy_cmd(device); + } + } + mod_timer(&device->wd_timer, round_jiffies(jiffies + 2 * HZ)); + spin_unlock_bh(&device->device_lock); + return; +} --- linux-2.6.28.orig/ubuntu/heci/BOM +++ linux-2.6.28/ubuntu/heci/BOM @@ -0,0 +1,2 @@ +Downloaded from: http://sourceforge.net/project/showfiles.php?group_id=193428 +Current Version: 3.2.0.24 --- linux-2.6.28.orig/ubuntu/heci/heci.h +++ linux-2.6.28/ubuntu/heci/heci.h @@ -0,0 +1,141 @@ +/* + * Part of Intel(R) Manageability Engine Interface Linux driver + * + * Copyright (c) 2003 - 2007 Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. + * + */ + +#ifndef _HECI_H_ +#define _HECI_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "heci_data_structures.h" + + +extern const struct guid heci_pthi_guid; +extern const struct guid heci_wd_guid; +extern const __u8 start_wd_params[]; +extern const __u8 stop_wd_params[]; +extern const __u8 heci_wd_state_independence_msg[2][4]; + +/** + * memory IO BAR definition + */ +#define BAR_0 0 +#define BAR_1 1 +#define BAR_5 5 +/** + * Number of queue lists used by this driver + */ +#define PCI_HECI_DEVICE_ID1 0x2974 +#define PCI_HECI_DEVICE_ID2 0x2984 +#define PCI_HECI_DEVICE_ID3 0x2994 +#define PCI_HECI_DEVICE_ID4 0x29A4 +#define PCI_HECI_DEVICE_ID5 0x29B4 +#define PCI_HECI_DEVICE_ID6 0x29C4 +#define PCI_HECI_DEVICE_ID7 0x29E4 +#define PCI_HECI_DEVICE_ID8 0x29F4 + +/** + * heci init function prototypes + */ +struct iamt_heci_device *init_heci_device(struct pci_dev *pdev); +void heci_reset(struct iamt_heci_device * device_object, int interrupts); +int heci_hw_init(struct iamt_heci_device * device_object); +int heci_initialize_clients(void *data); +struct heci_file_private *alloc_priv(struct file *file); +int heci_disconnect_host_client(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension); +void heci_initialize_list(struct io_heci_list *list, + struct iamt_heci_device * device_object); +void heci_flush_list(struct io_heci_list *list, + struct heci_file_private * file_extension); +void heci_flush_queues(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension); + +void heci_remove_client_from_file_list(struct iamt_heci_device * device_object, + __u8 host_client_id); + +/** + * interrupt function prototype + */ +irqreturn_t heci_isr_interrupt(int irq, void *dev_id); +void heci_wd_timer(unsigned long data); +void heci_bh_handler(struct work_struct *work); +/** + * input output function prototype + */ +int heci_ioctl_get_version(struct iamt_heci_device * device, int if_num, + struct heci_message_data *u_msg, + struct heci_message_data k_msg, + struct heci_file_private * file_extension); +int heci_ioctl_connect_client(struct iamt_heci_device * device, int if_num, + struct heci_message_data *u_msg, + struct heci_message_data k_msg, + struct file *file); +int heci_ioctl_wd(struct iamt_heci_device * device, int if_num, + struct heci_message_data k_msg, + struct heci_file_private * file_extension); +int heci_ioctl_bypass_wd(struct iamt_heci_device * device, int if_num, + struct heci_message_data k_msg, + struct heci_file_private * file_extension); +int legacy_ioctl_send_message(struct iamt_heci_device * device, int if_num, + struct heci_message_data k_msg, + struct file *file); +int legacy_ioctl_receive_message(struct iamt_heci_device * device, int if_num, + struct heci_message_data *u_msg, + struct heci_message_data k_msg, + struct file *file); +int heci_start_read(struct iamt_heci_device * device, int if_num, + struct heci_file_private * file_extension); +int pthi_write(struct iamt_heci_device * device, + struct heci_cb_private *kernel_priv_cb); +int pthi_read(struct iamt_heci_device * device, int if_num, struct file *file, + char *ubuf, size_t length, loff_t* offset); +struct heci_cb_private* find_pthi_read_list_entry(struct iamt_heci_device* device, + struct file* file, struct heci_file_private* file_extension); +void run_next_legacy_cmd(struct iamt_heci_device * device); + +#endif /* _HECI_H_ */ --- linux-2.6.28.orig/ubuntu/gfs/util.c +++ linux-2.6.28/ubuntu/gfs/util.c @@ -0,0 +1,571 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "glock.h" +#include "lm.h" + +uint32_t gfs_random_number; + +struct kmem_cache *gfs_glock_cachep = NULL; +struct kmem_cache *gfs_inode_cachep = NULL; +struct kmem_cache *gfs_bufdata_cachep = NULL; +struct kmem_cache *gfs_mhc_cachep = NULL; + +/** + * gfs_random - Generate a random 32-bit number + * + * Generate a semi-crappy 32-bit pseudo-random number without using + * floating point. + * + * The PRNG is from "Numerical Recipes in C" (second edition), page 284. + * + * Returns: a 32-bit random number + */ + +uint32_t +gfs_random(void) +{ + gfs_random_number = 0x0019660D * gfs_random_number + 0x3C6EF35F; + return gfs_random_number; +} + +/** + * hash_more_internal - hash an array of data + * @data: the data to be hashed + * @len: the length of data to be hashed + * @hash: the hash from a previous call + * + * Take some data and convert it to a 32-bit hash. + * + * This is the 32-bit FNV-1a hash from: + * http://www.isthe.com/chongo/tech/comp/fnv/ + * + * Hash guts + * + * Returns: the hash + */ + +static __inline__ uint32_t +hash_more_internal(const void *data, unsigned int len, uint32_t hash) +{ + unsigned char *p = (unsigned char *)data; + unsigned char *e = p + len; + uint32_t h = hash; + + while (p < e) { + h ^= (uint32_t)(*p++); + h *= 0x01000193; + } + + return h; +} + +/** + * gfs_hash - hash an array of data + * @data: the data to be hashed + * @len: the length of data to be hashed + * + * Take some data and convert it to a 32-bit hash. + * + * This is the 32-bit FNV-1a hash from: + * http://www.isthe.com/chongo/tech/comp/fnv/ + * + * Returns: the hash + */ + +uint32_t +gfs_hash(const void *data, unsigned int len) +{ + uint32_t h = 0x811C9DC5; + h = hash_more_internal(data, len, h); + return h; +} + +/** + * gfs_hash_more - hash an array of data + * @data: the data to be hashed + * @len: the length of data to be hashed + * @hash: the hash from a previous call + * + * Take some data and convert it to a 32-bit hash. + * + * This is the 32-bit FNV-1a hash from: + * http://www.isthe.com/chongo/tech/comp/fnv/ + * + * This version let's you hash together discontinuous regions. + * For example, to compute the combined hash of the memory in + * (data1, len1), (data2, len2), and (data3, len3) you: + * + * h = gfs_hash(data1, len1); + * h = gfs_hash_more(data2, len2, h); + * h = gfs_hash_more(data3, len3, h); + * + * Returns: the hash + */ + +uint32_t +gfs_hash_more(const void *data, unsigned int len, uint32_t hash) +{ + uint32_t h; + h = hash_more_internal(data, len, hash); + return h; +} + +/* Byte-wise swap two items of size SIZE. */ + +#define SWAP(a, b, size) \ +do { \ + register size_t __size = (size); \ + register char *__a = (a), *__b = (b); \ + do { \ + char __tmp = *__a; \ + *__a++ = *__b; \ + *__b++ = __tmp; \ + } while (__size-- > 1); \ +} while (0) + +/** + * gfs_sort - Sort base array using shell sort algorithm + * @base: the input array + * @num_elem: number of elements in array + * @size: size of each element in array + * @compar: fxn to compare array elements (returns negative + * for lt, 0 for eq, and positive for gt + * + * Sorts the array passed in using the compar fxn to compare elements using + * the shell sort algorithm + */ + +void +gfs_sort(void *base, unsigned int num_elem, unsigned int size, + int (*compar) (const void *, const void *)) +{ + register char *pbase = (char *)base; + int i, j, k, h; + static int cols[16] = {1391376, 463792, 198768, 86961, + 33936, 13776, 4592, 1968, + 861, 336, 112, 48, + 21, 7, 3, 1}; + + for (k = 0; k < 16; k++) { + h = cols[k]; + for (i = h; i < num_elem; i++) { + j = i; + while (j >= h && + (*compar)((void *)(pbase + size * (j - h)), + (void *)(pbase + size * j)) > 0) { + SWAP(pbase + size * j, + pbase + size * (j - h), + size); + j = j - h; + } + } + } +} + +/** + * gfs_assert_i - Cause the machine to panic if @assertion is false + * @sdp: + * @assertion: + * @function: + * @file: + * @line: + * + */ + +void +gfs_assert_i(struct gfs_sbd *sdp, + char *assertion, + const char *function, + char *file, unsigned int line) +{ + if (sdp->sd_args.ar_oopses_ok) { + printk("GFS: fsid=%s: assertion \"%s\" failed\n" + "GFS: fsid=%s: function = %s\n" + "GFS: fsid=%s: file = %s, line = %u\n" + "GFS: fsid=%s: time = %lu\n", + sdp->sd_fsname, assertion, + sdp->sd_fsname, function, + sdp->sd_fsname, file, line, + sdp->sd_fsname, get_seconds()); + BUG(); + } + dump_stack(); + panic("GFS: fsid=%s: assertion \"%s\" failed\n" + "GFS: fsid=%s: function = %s\n" + "GFS: fsid=%s: file = %s, line = %u\n" + "GFS: fsid=%s: time = %lu\n", + sdp->sd_fsname, assertion, + sdp->sd_fsname, function, + sdp->sd_fsname, file, line, + sdp->sd_fsname, get_seconds()); +} + +/** + * gfs_assert_withdraw_i - Cause the machine to withdraw if @assertion is false + * @sdp: + * @assertion: + * @function: + * @file: + * @line: + * + * Returns: -1 if this call withdrew the machine, + * -2 if it was already withdrawn + */ + +int +gfs_assert_withdraw_i(struct gfs_sbd *sdp, + char *assertion, + const char *function, + char *file, unsigned int line) +{ + int me; + me = gfs_lm_withdraw(sdp, + "GFS: fsid=%s: fatal: assertion \"%s\" failed\n" + "GFS: fsid=%s: function = %s\n" + "GFS: fsid=%s: file = %s, line = %u\n" + "GFS: fsid=%s: time = %lu\n", + sdp->sd_fsname, assertion, + sdp->sd_fsname, function, + sdp->sd_fsname, file, line, + sdp->sd_fsname, get_seconds()); + return (me) ? -1 : -2; +} + +/** + * gfs_assert_warn_i - Print a message to the console if @assertion is false + * @sdp: + * @assertion: + * @function: + * @file: + * @line: + * + * Returns: -1 if we printed something + * -2 if we didn't + */ + +int +gfs_assert_warn_i(struct gfs_sbd *sdp, + char *assertion, + const char *function, + char *file, unsigned int line) +{ + if (time_before(jiffies, + sdp->sd_last_warning + + gfs_tune_get(sdp, gt_complain_secs) * HZ)) + return -2; + + printk("GFS: fsid=%s: warning: assertion \"%s\" failed\n" + "GFS: fsid=%s: function = %s\n" + "GFS: fsid=%s: file = %s, line = %u\n" + "GFS: fsid=%s: time = %lu\n", + sdp->sd_fsname, assertion, + sdp->sd_fsname, function, + sdp->sd_fsname, file, line, + sdp->sd_fsname, get_seconds()); + + sdp->sd_last_warning = jiffies; + if (sdp->sd_args.ar_debug) + BUG(); + + + return -1; +} + +/** + * gfs_consist_i - Flag a filesystem consistency error and withdraw + * @sdp: + * @cluster_wide: + * @function: + * @file: + * @line: + * + * Returns: -1 if this call withdrew the machine, + * 0 if it was already withdrawn + */ + +int +gfs_consist_i(struct gfs_sbd *sdp, int cluster_wide, + const char *function, + char *file, unsigned int line) +{ + return gfs_lm_withdraw(sdp, + "GFS: fsid=%s: fatal: filesystem consistency error\n" + "GFS: fsid=%s: function = %s\n" + "GFS: fsid=%s: file = %s, line = %u\n" + "GFS: fsid=%s: time = %lu\n", + sdp->sd_fsname, + sdp->sd_fsname, function, + sdp->sd_fsname, file, line, + sdp->sd_fsname, get_seconds()); +} + +/** + * gfs_consist_inode_i - Flag an inode consistency error and withdraw + * @ip: + * @cluster_wide: + * @function: + * @file: + * @line: + * + * Returns: -1 if this call withdrew the machine, + * 0 if it was already withdrawn + */ + +int +gfs_consist_inode_i(struct gfs_inode *ip, int cluster_wide, + const char *function, + char *file, unsigned int line) +{ + struct gfs_sbd *sdp = ip->i_sbd; + return gfs_lm_withdraw(sdp, + "GFS: fsid=%s: fatal: filesystem consistency error\n" + "GFS: fsid=%s: inode = %"PRIu64"/%"PRIu64"\n" + "GFS: fsid=%s: function = %s\n" + "GFS: fsid=%s: file = %s, line = %u\n" + "GFS: fsid=%s: time = %lu\n", + sdp->sd_fsname, + sdp->sd_fsname, ip->i_num.no_formal_ino, ip->i_num.no_addr, + sdp->sd_fsname, function, + sdp->sd_fsname, file, line, + sdp->sd_fsname, get_seconds()); +} + +/** + * gfs_consist_rgrpd_i - Flag a RG consistency error and withdraw + * @rgd: + * @cluster_wide: + * @function: + * @file: + * @line: + * + * Returns: -1 if this call withdrew the machine, + * 0 if it was already withdrawn + */ + +int +gfs_consist_rgrpd_i(struct gfs_rgrpd *rgd, int cluster_wide, + const char *function, + char *file, unsigned int line) +{ + struct gfs_sbd *sdp = rgd->rd_sbd; + return gfs_lm_withdraw(sdp, + "GFS: fsid=%s: fatal: filesystem consistency error\n" + "GFS: fsid=%s: RG = %"PRIu64"\n" + "GFS: fsid=%s: function = %s\n" + "GFS: fsid=%s: file = %s, line = %u\n" + "GFS: fsid=%s: time = %lu\n", + sdp->sd_fsname, + sdp->sd_fsname, rgd->rd_ri.ri_addr, + sdp->sd_fsname, function, + sdp->sd_fsname, file, line, + sdp->sd_fsname, get_seconds()); +} + +/** + * gfs_meta_check_ii - Flag a magic number consistency error and withdraw + * @sdp: + * @bh: + * @function: + * @file: + * @line: + * + * Returns: -1 if this call withdrew the machine, + * -2 if it was already withdrawn + */ + +int +gfs_meta_check_ii(struct gfs_sbd *sdp, struct buffer_head *bh, + const char *function, + char *file, unsigned int line) +{ + int me; + me = gfs_lm_withdraw(sdp, + "GFS: fsid=%s: fatal: invalid metadata block\n" + "GFS: fsid=%s: bh = %"PRIu64" (magic)\n" + "GFS: fsid=%s: function = %s\n" + "GFS: fsid=%s: file = %s, line = %u\n" + "GFS: fsid=%s: time = %lu\n", + sdp->sd_fsname, + sdp->sd_fsname, (uint64_t)bh->b_blocknr, + sdp->sd_fsname, function, + sdp->sd_fsname, file, line, + sdp->sd_fsname, get_seconds()); + return (me) ? -1 : -2; +} + +/** + * gfs_metatype_check_ii - Flag a metadata type consistency error and withdraw + * @sdp: + * @bh: + * @type: + * @t: + * @function: + * @file: + * @line: + * + * Returns: -1 if this call withdrew the machine, + * -2 if it was already withdrawn + */ + +int +gfs_metatype_check_ii(struct gfs_sbd *sdp, struct buffer_head *bh, + uint32_t type, uint32_t t, + const char *function, + char *file, unsigned int line) +{ + int me; + me = gfs_lm_withdraw(sdp, + "GFS: fsid=%s: fatal: invalid metadata block\n" + "GFS: fsid=%s: bh = %"PRIu64" (type: exp=%u, found=%u)\n" + "GFS: fsid=%s: function = %s\n" + "GFS: fsid=%s: file = %s, line = %u\n" + "GFS: fsid=%s: time = %lu\n", + sdp->sd_fsname, + sdp->sd_fsname, (uint64_t)bh->b_blocknr, type, t, + sdp->sd_fsname, function, + sdp->sd_fsname, file, line, + sdp->sd_fsname, get_seconds()); + return (me) ? -1 : -2; +} + +/** + * gfs_io_error_i - Flag an I/O error and withdraw + * @sdp: + * @function: + * @file: + * @line: + * + * Returns: -1 if this call withdrew the machine, + * 0 if it was already withdrawn + */ + +int +gfs_io_error_i(struct gfs_sbd *sdp, + const char *function, + char *file, unsigned int line) +{ + return gfs_lm_withdraw(sdp, + "GFS: fsid=%s: fatal: I/O error\n" + "GFS: fsid=%s: function = %s\n" + "GFS: fsid=%s: file = %s, line = %u\n" + "GFS: fsid=%s: time = %lu\n", + sdp->sd_fsname, + sdp->sd_fsname, function, + sdp->sd_fsname, file, line, + sdp->sd_fsname, get_seconds()); +} + +/** + * gfs_io_error_inode_i - Flag an inode I/O error and withdraw + * @ip: + * @function: + * @file: + * @line: + * + * Returns: -1 if this call withdrew the machine, + * 0 if it was already withdrawn + */ + +int +gfs_io_error_inode_i(struct gfs_inode *ip, + const char *function, + char *file, unsigned int line) +{ + struct gfs_sbd *sdp = ip->i_sbd; + return gfs_lm_withdraw(sdp, + "GFS: fsid=%s: fatal: I/O error\n" + "GFS: fsid=%s: inode = %"PRIu64"/%"PRIu64"\n" + "GFS: fsid=%s: function = %s\n" + "GFS: fsid=%s: file = %s, line = %u\n" + "GFS: fsid=%s: time = %lu\n", + sdp->sd_fsname, + sdp->sd_fsname, ip->i_num.no_formal_ino, ip->i_num.no_addr, + sdp->sd_fsname, function, + sdp->sd_fsname, file, line, + sdp->sd_fsname, get_seconds()); +} + +/** + * gfs_io_error_bh_i - Flag a buffer I/O error and withdraw + * @sdp: + * @bh: + * @function: + * @file: + * @line: + * + * Returns: -1 if this call withdrew the machine, + * 0 if it was already withdrawn + */ + +int +gfs_io_error_bh_i(struct gfs_sbd *sdp, struct buffer_head *bh, + const char *function, + char *file, unsigned int line) +{ + return gfs_lm_withdraw(sdp, + "GFS: fsid=%s: fatal: I/O error\n" + "GFS: fsid=%s: block = %"PRIu64"\n" + "GFS: fsid=%s: function = %s\n" + "GFS: fsid=%s: file = %s, line = %u\n" + "GFS: fsid=%s: time = %lu\n", + sdp->sd_fsname, + sdp->sd_fsname, (uint64_t)bh->b_blocknr, + sdp->sd_fsname, function, + sdp->sd_fsname, file, line, + sdp->sd_fsname, get_seconds()); +} + +/** + * gmalloc - malloc a small amount of memory + * @size: the number of bytes to malloc + * + * Returns: the memory + */ + +void * +gmalloc(unsigned int size) +{ + void *p; + RETRY_MALLOC(p = kmalloc(size, GFP_KERNEL), p); + return p; +} + +/** + * gfs_add_bh_to_ub - copy a buffer up to user space + * @ub: the structure representing where to copy + * @bh: the buffer + * + * Returns: errno + */ + +int +gfs_add_bh_to_ub(struct gfs_user_buffer *ub, struct buffer_head *bh) +{ + uint64_t blkno = bh->b_blocknr; + + if (ub->ub_count + sizeof(uint64_t) + bh->b_size > ub->ub_size) + return -ENOMEM; + + if (copy_to_user(ub->ub_data + ub->ub_count, + &blkno, + sizeof(uint64_t))) + return -EFAULT; + ub->ub_count += sizeof(uint64_t); + + if (copy_to_user(ub->ub_data + ub->ub_count, + bh->b_data, + bh->b_size)) + return -EFAULT; + ub->ub_count += bh->b_size; + + return 0; +} + --- linux-2.6.28.orig/ubuntu/gfs/ops_super.c +++ linux-2.6.28/ubuntu/gfs/ops_super.c @@ -0,0 +1,455 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "dio.h" +#include "glock.h" +#include "inode.h" +#include "lm.h" +#include "log.h" +#include "ops_fstype.h" +#include "ops_super.h" +#include "page.h" +#include "proc.h" +#include "quota.h" +#include "recovery.h" +#include "rgrp.h" +#include "super.h" +#include "sys.h" +#include "mount.h" + +/** + * gfs_write_inode - Make sure the inode is stable on the disk + * @inode: The inode + * @sync: synchronous write flag + * + * Returns: errno + */ + +static int +gfs_write_inode(struct inode *inode, int sync) +{ + struct gfs_inode *ip = get_v2ip(inode); + + atomic_inc(&ip->i_sbd->sd_ops_super); + + if (ip && sync) + gfs_log_flush_glock(ip->i_gl); + + return 0; +} + +/** + * gfs_drop_inode - drop an inode + * @inode: The inode + * + * If i_nlink is zero, any dirty data for the inode is thrown away. + * If a process on another machine has the file open, it may need that + * data. So, sync it out. + */ + +static void +gfs_drop_inode(struct inode *inode) +{ + struct gfs_sbd *sdp = get_v2sdp(inode->i_sb); + struct gfs_inode *ip = get_v2ip(inode); + + atomic_inc(&sdp->sd_ops_super); + + if (ip && + !inode->i_nlink && + S_ISREG(inode->i_mode) && + !sdp->sd_args.ar_localcaching) + gfs_sync_page_i(inode, DIO_START | DIO_WAIT); + generic_drop_inode(inode); +} + +/** + * gfs_put_super - Unmount the filesystem + * @sb: The VFS superblock + * + */ + +static void +gfs_put_super(struct super_block *sb) +{ + struct gfs_sbd *sdp = get_v2sdp(sb); + int error; + + if (!sdp) + return; + + atomic_inc(&sdp->sd_ops_super); + + gfs_proc_fs_del(sdp); + + /* Unfreeze the filesystem, if we need to */ + + down(&sdp->sd_freeze_lock); + if (sdp->sd_freeze_count) + gfs_glock_dq_uninit(&sdp->sd_freeze_gh); + up(&sdp->sd_freeze_lock); + + /* Kill off the inode thread */ + kthread_stop(sdp->sd_inoded_process); + + /* Kill off the quota thread */ + kthread_stop(sdp->sd_quotad_process); + + /* Kill off the log thread */ + kthread_stop(sdp->sd_logd_process); + + /* Kill off the recoverd thread */ + kthread_stop(sdp->sd_recoverd_process); + + /* Kill off the glockd threads */ + while (sdp->sd_glockd_num--) + kthread_stop(sdp->sd_glockd_process[sdp->sd_glockd_num]); + + /* Kill off the scand thread */ + kthread_stop(sdp->sd_scand_process); + + if (!test_bit(SDF_ROFS, &sdp->sd_flags)) { + error = gfs_make_fs_ro(sdp); + if (error) + gfs_io_error(sdp); + } + + /* At this point, we're through modifying the disk */ + + /* Release stuff */ + + gfs_inode_put(sdp->sd_riinode); + gfs_inode_put(sdp->sd_jiinode); + gfs_inode_put(sdp->sd_rooti); + gfs_inode_put(sdp->sd_qinode); + gfs_inode_put(sdp->sd_linode); + gfs_glock_put(sdp->sd_trans_gl); + gfs_glock_put(sdp->sd_rename_gl); + + if (!sdp->sd_args.ar_spectator) + gfs_glock_dq_uninit(&sdp->sd_journal_gh); + + gfs_glock_dq_uninit(&sdp->sd_live_gh); + + /* Get rid of rgrp bitmap structures */ + gfs_clear_rgrpd(sdp); + gfs_clear_journals(sdp); + + /* Take apart glock structures and buffer lists */ + gfs_gl_hash_clear(sdp, TRUE); + + /* Unmount the locking protocol */ + gfs_lm_unmount(sdp); + + /* At this point, we're through participating in the lockspace */ + + gfs_sys_fs_del(sdp); + + gfs_clear_dirty_j(sdp); + + /* Get rid of any extra inodes */ + while (invalidate_inodes(sb)) + yield(); + + vfree(sdp); + + set_v2sdp(sb, NULL); +} + +/** + * gfs_write_super - disk commit all incore transactions + * @sb: the filesystem + * + * This function is called every time sync(2) is called. + * After this exits, all dirty buffers and synced. + */ + +static void +gfs_write_super(struct super_block *sb) +{ + struct gfs_sbd *sdp = get_v2sdp(sb); + atomic_inc(&sdp->sd_ops_super); + gfs_log_flush(sdp); +} + +/** + * gfs_write_super_lockfs - prevent further writes to the filesystem + * @sb: the VFS structure for the filesystem + * + */ + +static void +gfs_write_super_lockfs(struct super_block *sb) +{ + struct gfs_sbd *sdp = get_v2sdp(sb); + int error; + + if (test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) + return; + + atomic_inc(&sdp->sd_ops_super); + + for (;;) { + error = gfs_freeze_fs(sdp); + if (!error) + break; + + switch (error) { + case -EBUSY: + printk("GFS: fsid=%s: waiting for recovery before freeze\n", + sdp->sd_fsname); + break; + + default: + printk("GFS: fsid=%s: error freezing FS: %d\n", + sdp->sd_fsname, error); + break; + } + + printk("GFS: fsid=%s: retrying...\n", sdp->sd_fsname); + + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ); + } +} + +/** + * gfs_unlockfs - reallow writes to the filesystem + * @sb: the VFS structure for the filesystem + * + */ + +static void +gfs_unlockfs(struct super_block *sb) +{ + struct gfs_sbd *sdp = get_v2sdp(sb); + + atomic_inc(&sdp->sd_ops_super); + + gfs_unfreeze_fs(sdp); +} + +/** + * gfs_statfs - Gather and return stats about the filesystem + * @sb: The superblock + * @statfsbuf: The buffer + * + * Returns: 0 on success or error code + */ + +static int gfs_statfs(struct dentry *dentry, struct kstatfs *buf) +{ + struct super_block *sb = dentry->d_inode->i_sb; + struct gfs_sbd *sdp = get_v2sdp(sb); + struct gfs_stat_gfs sg; + int error; + + atomic_inc(&sdp->sd_ops_super); + + if (gfs_tune_get(sdp, gt_statfs_fast)) + return(gfs_statfs_fast(sdp, (void *)buf)); + + error = gfs_stat_gfs(sdp, &sg, TRUE); + if (error) + return error; + + memset(buf, 0, sizeof(struct kstatfs)); + + buf->f_type = GFS_MAGIC; + buf->f_bsize = sdp->sd_sb.sb_bsize; + buf->f_blocks = sg.sg_total_blocks; + buf->f_bfree = sg.sg_free + sg.sg_free_dinode + sg.sg_free_meta; + buf->f_bavail = sg.sg_free + sg.sg_free_dinode + sg.sg_free_meta; + buf->f_files = sg.sg_used_dinode + sg.sg_free_dinode + + sg.sg_free_meta + sg.sg_free; + buf->f_ffree = sg.sg_free_dinode + sg.sg_free_meta + sg.sg_free; + buf->f_namelen = GFS_FNAMESIZE; + + return 0; +} + +/** + * gfs_remount_fs - called when the FS is remounted + * @sb: the filesystem + * @flags: the remount flags + * @data: extra data passed in (not used right now) + * + * Returns: errno + */ + +static int +gfs_remount_fs(struct super_block *sb, int *flags, char *data) +{ + struct gfs_sbd *sdp = get_v2sdp(sb); + struct gfs_tune *gt = &sdp->sd_tune; + int error = 0; + struct gfs_args *args; + + atomic_inc(&sdp->sd_ops_super); + + args = kmalloc(sizeof(struct gfs_args), GFP_KERNEL); + if (!args) + return -ENOMEM; + + error = gfs_make_args(data, args, TRUE); + if (error) { + printk("GFS: can't parse remount arguments\n"); + goto out; + } + if (args->ar_posix_acls) { + sdp->sd_args.ar_posix_acls = TRUE; + sb->s_flags |= MS_POSIXACL; + } + else { + sdp->sd_args.ar_posix_acls = FALSE; + sb->s_flags &= ~MS_POSIXACL; + } + + if (*flags & (MS_NOATIME | MS_NODIRATIME)) + set_bit(SDF_NOATIME, &sdp->sd_flags); + else + clear_bit(SDF_NOATIME, &sdp->sd_flags); + + if (sdp->sd_args.ar_spectator) + *flags |= MS_RDONLY; + else { + if (*flags & MS_RDONLY) { + if (!test_bit(SDF_ROFS, &sdp->sd_flags)) + error = gfs_make_fs_ro(sdp); + } else if (!(*flags & MS_RDONLY) && + test_bit(SDF_ROFS, &sdp->sd_flags)) { + error = gfs_make_fs_rw(sdp); + } + } + + if (args->ar_noquota) { + if (sdp->sd_args.ar_noquota == FALSE) + printk("GFS: remounting without quota\n"); + sdp->sd_args.ar_noquota = TRUE; + spin_lock(>->gt_spin); + gt->gt_quota_enforce = 0; + gt->gt_quota_account = 0; + spin_unlock(>->gt_spin); + } + else { + if (sdp->sd_args.ar_noquota == TRUE) + printk("GFS: remounting with quota\n"); + sdp->sd_args.ar_noquota = FALSE; + spin_lock(>->gt_spin); + gt->gt_quota_enforce = 1; + gt->gt_quota_account = 1; + spin_unlock(>->gt_spin); + } + + /* Don't let the VFS update atimes. GFS handles this itself. */ + *flags |= MS_NOATIME | MS_NODIRATIME; + +out: + kfree(args); + return error; +} + +/** + * gfs_clear_inode - Deallocate an inode when VFS is done with it + * @inode: The VFS inode + * + * If there's a GFS incore inode structure attached to the VFS inode: + * -- Detach them from one another. + * -- Schedule reclaim of GFS inode struct, the glock protecting it, and + * the associated iopen glock. + */ + +static void +gfs_clear_inode(struct inode *inode) +{ + struct gfs_inode *ip = get_v2ip(inode); + + atomic_inc(&get_v2sdp(inode->i_sb)->sd_ops_super); + + if (ip) { + spin_lock(&ip->i_spin); + ip->i_vnode = NULL; + set_v2ip(inode, NULL); + spin_unlock(&ip->i_spin); + + gfs_glock_schedule_for_reclaim(ip->i_gl); + gfs_inode_put(ip); + } +} + +/** + * gfs_show_options - Show mount options for /proc/mounts + * @s: seq_file structure + * @mnt: vfsmount + * + * Returns: 0 on success or error code + */ + +static int +gfs_show_options(struct seq_file *s, struct vfsmount *mnt) +{ + struct gfs_sbd *sdp = get_v2sdp(mnt->mnt_sb); + struct gfs_args *args = &sdp->sd_args; + + atomic_inc(&sdp->sd_ops_super); + + if (args->ar_lockproto[0]) { + seq_printf(s, ",lockproto="); + seq_puts(s, args->ar_lockproto); + } + if (args->ar_locktable[0]) { + seq_printf(s, ",locktable="); + seq_puts(s, args->ar_locktable); + } + if (args->ar_hostdata[0]) { + seq_printf(s, ",hostdata="); + seq_puts(s, args->ar_hostdata); + } + if (args->ar_spectator) + seq_printf(s, ",spectator"); + if (args->ar_ignore_local_fs) + seq_printf(s, ",ignore_local_fs"); + if (args->ar_localflocks) + seq_printf(s, ",localflocks"); + if (args->ar_localcaching) + seq_printf(s, ",localcaching"); + if (args->ar_oopses_ok) + seq_printf(s, ",oopses_ok"); + if (args->ar_debug) + seq_printf(s, ",debug"); + if (args->ar_upgrade) + seq_printf(s, ",upgrade"); + if (args->ar_num_glockd != GFS_GLOCKD_DEFAULT) + seq_printf(s, ",num_glockd=%u", args->ar_num_glockd); + if (args->ar_posix_acls) + seq_printf(s, ",acl"); + if (args->ar_noquota) + seq_printf(s, ",noquota"); + if (args->ar_suiddir) + seq_printf(s, ",suiddir"); + + return 0; +} + +struct super_operations gfs_super_ops = { + .write_inode = gfs_write_inode, + .drop_inode = gfs_drop_inode, + .put_super = gfs_put_super, + .write_super = gfs_write_super, + .write_super_lockfs = gfs_write_super_lockfs, + .unlockfs = gfs_unlockfs, + .statfs = gfs_statfs, + .remount_fs = gfs_remount_fs, + .clear_inode = gfs_clear_inode, + .show_options = gfs_show_options, +}; --- linux-2.6.28.orig/ubuntu/gfs/proc.c +++ linux-2.6.28/ubuntu/gfs/proc.c @@ -0,0 +1,491 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "glock.h" +#include "lm.h" +#include "proc.h" +#include "super.h" + +struct list_head gfs_fs_list; +struct semaphore gfs_fs_lock; +char *gfs_proc_margs; +spinlock_t gfs_proc_margs_lock; +spinlock_t gfs_req_lock; + +/** + * gfs_proc_fs_add - Add a FS to the list of mounted FSs + * @sdp: + * + */ + +void +gfs_proc_fs_add(struct gfs_sbd *sdp) +{ + down(&gfs_fs_lock); + list_add(&sdp->sd_list, &gfs_fs_list); + up(&gfs_fs_lock); +} + +/** + * gfs_proc_fs_del - Remove a FS from the list of mounted FSs + * @sdp: + * + */ + +void +gfs_proc_fs_del(struct gfs_sbd *sdp) +{ + down(&gfs_fs_lock); + list_del(&sdp->sd_list); + up(&gfs_fs_lock); +} + +/** + * do_list - Copy the list of mountes FSs to userspace + * @user_buf: + * @size: + * + * @Returns: -errno, or the number of bytes copied to userspace + */ + +static ssize_t +do_list(char *user_buf, size_t size) +{ + struct list_head *tmp; + struct gfs_sbd *sdp = NULL; + unsigned int x; + char num[21]; + char device_id[32]; + char *buf; + int error = 0; + + down(&gfs_fs_lock); + + x = 0; + for (tmp = gfs_fs_list.next; tmp != &gfs_fs_list; tmp = tmp->next) { + sdp = list_entry(tmp, struct gfs_sbd, sd_list); + sprintf(device_id, "%u:%u", MAJOR(sdp->sd_vfs->s_dev), + MINOR(sdp->sd_vfs->s_dev)); + x += sprintf(num, "%lu", (unsigned long)sdp) + + strlen(device_id) + + strlen(sdp->sd_fsname) + 3; + } + + if (!x) + goto out; + + error = -EFBIG; + if (x > size) + goto out; + + error = -ENOMEM; + buf = kmalloc(x + 1, GFP_KERNEL); + if (!buf) + goto out; + + x = 0; + for (tmp = gfs_fs_list.next; tmp != &gfs_fs_list; tmp = tmp->next) { + sdp = list_entry(tmp, struct gfs_sbd, sd_list); + sprintf(device_id, "%u:%u", MAJOR(sdp->sd_vfs->s_dev), + MINOR(sdp->sd_vfs->s_dev)); + x += sprintf(buf + x, "%lu %s %s\n", + (unsigned long)sdp, device_id, sdp->sd_fsname); + } + + if (copy_to_user(user_buf, buf, x)) + error = -EFAULT; + else + error = x; + + kfree(buf); + + out: + up(&gfs_fs_lock); + + return error; +} + +/** + * find_argument - + * @p: + * + * Returns: + */ + +static char * +find_argument(char *p) +{ + char *p2; + + while (*p == ' ' || *p == '\n') + p++; + if (!*p) + return NULL; + for (p2 = p; *p2; p2++) /* do nothing */; + p2--; + while (*p2 == ' ' || *p2 == '\n') + *p2-- = 0; + + return p; +} + +/** + * do_freeze - freeze a filesystem + * @p: the freeze command + * + * Returns: errno + */ + +static int +do_freeze(char *p) +{ + struct list_head *tmp; + struct gfs_sbd *sdp; + char num[21]; + int error = 0; + + p = find_argument(p + 6); + if (!p) + return -ENOENT; + + down(&gfs_fs_lock); + + for (tmp = gfs_fs_list.next; tmp != &gfs_fs_list; tmp = tmp->next) { + sdp = list_entry(tmp, struct gfs_sbd, sd_list); + sprintf(num, "%lu", (unsigned long)sdp); + if (strcmp(num, p) == 0) + break; + } + + if (tmp == &gfs_fs_list) + error = -ENOENT; + else + error = gfs_freeze_fs(sdp); + + up(&gfs_fs_lock); + + return error; +} + +/** + * do_unfreeze - unfreeze a filesystem + * @p: the unfreeze command + * + * Returns: errno + */ + +static int +do_unfreeze(char *p) +{ + struct list_head *tmp; + struct gfs_sbd *sdp; + char num[21]; + int error = 0; + + p = find_argument(p + 8); + if (!p) + return -ENOENT; + + down(&gfs_fs_lock); + + for (tmp = gfs_fs_list.next; tmp != &gfs_fs_list; tmp = tmp->next) { + sdp = list_entry(tmp, struct gfs_sbd, sd_list); + sprintf(num, "%lu", (unsigned long)sdp); + if (strcmp(num, p) == 0) + break; + } + + if (tmp == &gfs_fs_list) + error = -ENOENT; + else + gfs_unfreeze_fs(sdp); + + up(&gfs_fs_lock); + + return error; +} + +/** + * do_margs - Pass in mount arguments + * @p: the margs command + * + * Returns: errno + */ + +static int +do_margs(char *p) +{ + char *new_buf, *old_buf; + + p = find_argument(p + 5); + if (!p) + return -ENOENT; + + new_buf = kmalloc(strlen(p) + 1, GFP_KERNEL); + if (!new_buf) + return -ENOMEM; + strcpy(new_buf, p); + + spin_lock(&gfs_proc_margs_lock); + old_buf = gfs_proc_margs; + gfs_proc_margs = new_buf; + spin_unlock(&gfs_proc_margs_lock); + + if (old_buf) + kfree(old_buf); + + return 0; +} + +/** + * do_withdraw - withdraw a from the cluster for one filesystem + * @p: the cookie of the filesystem + * + * Returns: errno + */ + +static int +do_withdraw(char *p) +{ + struct list_head *tmp; + struct gfs_sbd *sdp; + char num[21]; + int error = 0; + + p = find_argument(p + 8); + if (!p) + return -ENOENT; + + down(&gfs_fs_lock); + + for (tmp = gfs_fs_list.next; tmp != &gfs_fs_list; tmp = tmp->next) { + sdp = list_entry(tmp, struct gfs_sbd, sd_list); + sprintf(num, "%lu", (unsigned long)sdp); + if (strcmp(num, p) == 0) + break; + } + + if (tmp == &gfs_fs_list) + error = -ENOENT; + else + gfs_lm_withdraw(sdp, + "GFS: fsid=%s: withdrawing from cluster at user's request\n", + sdp->sd_fsname); + + up(&gfs_fs_lock); + + return error; +} + +/** + * do_lockdump - Copy out the lock hash table to userspace + * @p: the cookie of the filesystem + * @buf: + * @size: + * + * Returns: errno + */ + +static int +do_lockdump(char *p, char *buf, size_t size) +{ + struct list_head *tmp; + struct gfs_sbd *sdp; + char num[21]; + struct gfs_user_buffer ub; + int error = 0; + + p = find_argument(p + 8); + if (!p) + return -ENOENT; + + down(&gfs_fs_lock); + + for (tmp = gfs_fs_list.next; tmp != &gfs_fs_list; tmp = tmp->next) { + sdp = list_entry(tmp, struct gfs_sbd, sd_list); + sprintf(num, "%lu", (unsigned long)sdp); + if (strcmp(num, p) == 0) + break; + } + + if (tmp == &gfs_fs_list) + error = -ENOENT; + else { + ub.ub_data = buf; + ub.ub_size = size; + ub.ub_count = 0; + + error = gfs_dump_lockstate(sdp, &ub); + if (!error) + error = ub.ub_count; + } + + up(&gfs_fs_lock); + + return error; +} + +/** + * gfs_proc_write - take a command from userspace + * @file: + * @buf: + * @size: + * @offset: + * + * Returns: -errno or the number of bytes taken + */ + +static ssize_t +gfs_proc_write(struct file *file, const char *buf, size_t size, loff_t *offset) +{ + char *p; + + spin_lock(&gfs_req_lock); + p = file->private_data; + file->private_data = NULL; + spin_unlock(&gfs_req_lock); + + if (p) + kfree(p); + + if (!size) + return -EINVAL; + + p = kmalloc(size + 1, GFP_KERNEL); + if (!p) + return -ENOMEM; + p[size] = 0; + + if (copy_from_user(p, buf, size)) { + kfree(p); + return -EFAULT; + } + + spin_lock(&gfs_req_lock); + file->private_data = p; + spin_unlock(&gfs_req_lock); + + return size; +} + +/** + * gfs_proc_read - return the results of a command + * @file: + * @buf: + * @size: + * @offset: + * + * Returns: -errno or the number of bytes returned + */ + +static ssize_t +gfs_proc_read(struct file *file, char *buf, size_t size, loff_t *offset) +{ + char *p; + int error; + + spin_lock(&gfs_req_lock); + p = file->private_data; + file->private_data = NULL; + spin_unlock(&gfs_req_lock); + + if (!p) + return -ENOENT; + + if (!size) { + kfree(p); + return -EINVAL; + } + + if (strncmp(p, "list", 4) == 0) + error = do_list(buf, size); + else if (strncmp(p, "freeze", 6) == 0) + error = do_freeze(p); + else if (strncmp(p, "unfreeze", 8) == 0) + error = do_unfreeze(p); + else if (strncmp(p, "margs", 5) == 0) + error = do_margs(p); + else if (strncmp(p, "withdraw", 8) == 0) + error = do_withdraw(p); + else if (strncmp(p, "lockdump", 8) == 0) + error = do_lockdump(p, buf, size); + else + error = -ENOSYS; + + kfree(p); + + return error; +} + +/** + * gfs_proc_close - free any mismatches writes + * @inode: + * @file: + * + * Returns: 0 + */ + +static int +gfs_proc_close(struct inode *inode, struct file *file) +{ + if (file->private_data) + kfree(file->private_data); + return 0; +} + +static struct file_operations gfs_proc_fops = +{ + .owner = THIS_MODULE, + .write = gfs_proc_write, + .read = gfs_proc_read, + .release = gfs_proc_close, +}; + +/** + * gfs_proc_init - initialize GFS' proc interface + * + */ + +int +gfs_proc_init(void) +{ + struct proc_dir_entry *pde; + + INIT_LIST_HEAD(&gfs_fs_list); + init_MUTEX(&gfs_fs_lock); + gfs_proc_margs = NULL; + spin_lock_init(&gfs_proc_margs_lock); + spin_lock_init(&gfs_req_lock); + + pde = create_proc_entry("fs/gfs", S_IFREG | 0600, NULL); + if (!pde) + return -ENOMEM; + + pde->owner = THIS_MODULE; + pde->proc_fops = &gfs_proc_fops; + + return 0; +} + +/** + * gfs_proc_uninit - uninitialize GFS' proc interface + * + */ + +void +gfs_proc_uninit(void) +{ + if (gfs_proc_margs) + kfree(gfs_proc_margs); + remove_proc_entry("fs/gfs", NULL); +} + --- linux-2.6.28.orig/ubuntu/gfs/locking.c +++ linux-2.6.28/ubuntu/gfs/locking.c @@ -0,0 +1,180 @@ +/* + * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. + * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License version 2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lm_interface.h" + +struct lmh_wrapper { + struct list_head lw_list; + const struct lm_lockops *lw_ops; +}; + +/* List of registered low-level locking protocols. A file system selects one + of them by name at mount time, e.g. lock_nolock, lock_dlm. */ + +static LIST_HEAD(lmh_list); +static DEFINE_MUTEX(lmh_lock); + +/** + * gfs_register_lockproto - Register a low-level locking protocol + * @proto: the protocol definition + * + * Returns: 0 on success, -EXXX on failure + */ + +int gfs_register_lockproto(const struct lm_lockops *proto) +{ + struct lmh_wrapper *lw; + + mutex_lock(&lmh_lock); + + list_for_each_entry(lw, &lmh_list, lw_list) { + if (!strcmp(lw->lw_ops->lm_proto_name, proto->lm_proto_name)) { + mutex_unlock(&lmh_lock); + printk(KERN_INFO "GFS2: protocol %s already exists\n", + proto->lm_proto_name); + return -EEXIST; + } + } + + lw = kzalloc(sizeof(struct lmh_wrapper), GFP_KERNEL); + if (!lw) { + mutex_unlock(&lmh_lock); + return -ENOMEM; + } + + lw->lw_ops = proto; + list_add(&lw->lw_list, &lmh_list); + + mutex_unlock(&lmh_lock); + + return 0; +} + +/** + * gfs_unregister_lockproto - Unregister a low-level locking protocol + * @proto: the protocol definition + * + */ + +void gfs_unregister_lockproto(const struct lm_lockops *proto) +{ + struct lmh_wrapper *lw; + + mutex_lock(&lmh_lock); + + list_for_each_entry(lw, &lmh_list, lw_list) { + if (!strcmp(lw->lw_ops->lm_proto_name, proto->lm_proto_name)) { + list_del(&lw->lw_list); + mutex_unlock(&lmh_lock); + kfree(lw); + return; + } + } + + mutex_unlock(&lmh_lock); + + printk(KERN_WARNING "GFS2: can't unregister lock protocol %s\n", + proto->lm_proto_name); +} + +/** + * gfs_mount_lockproto - Mount a lock protocol + * @proto_name - the name of the protocol + * @table_name - the name of the lock space + * @host_data - data specific to this host + * @cb - the callback to the code using the lock module + * @sdp - The GFS2 superblock + * @min_lvb_size - the mininum LVB size that the caller can deal with + * @flags - LM_MFLAG_* + * @lockstruct - a structure returned describing the mount + * + * Returns: 0 on success, -EXXX on failure + */ + +int gfs_mount_lockproto(char *proto_name, char *table_name, char *host_data, + lm_callback_t cb, void *cb_data, + unsigned int min_lvb_size, int flags, + struct lm_lockstruct *lockstruct, + struct kobject *fskobj) +{ + struct lmh_wrapper *lw = NULL; + int try = 0; + int error, found; + +retry: + mutex_lock(&lmh_lock); + + found = 0; + list_for_each_entry(lw, &lmh_list, lw_list) { + if (!strcmp(lw->lw_ops->lm_proto_name, proto_name)) { + found = 1; + break; + } + } + + if (!found) { + if (!try && capable(CAP_SYS_MODULE)) { + try = 1; + mutex_unlock(&lmh_lock); + request_module(proto_name); + goto retry; + } + printk(KERN_INFO "GFS2: can't find protocol %s\n", proto_name); + error = -ENOENT; + goto out; + } + + if (!try_module_get(lw->lw_ops->lm_owner)) { + try = 0; + mutex_unlock(&lmh_lock); + msleep(1000); + goto retry; + } + + error = lw->lw_ops->lm_mount(table_name, host_data, cb, cb_data, + min_lvb_size, flags, lockstruct, fskobj); + if (error) + module_put(lw->lw_ops->lm_owner); +out: + mutex_unlock(&lmh_lock); + return error; +} + +void gfs_unmount_lockproto(struct lm_lockstruct *lockstruct) +{ + mutex_lock(&lmh_lock); + lockstruct->ls_ops->lm_unmount(lockstruct->ls_lockspace); + if (lockstruct->ls_ops->lm_owner) + module_put(lockstruct->ls_ops->lm_owner); + mutex_unlock(&lmh_lock); +} + +/** + * gfs_withdraw_lockproto - abnormally unmount a lock module + * @lockstruct: the lockstruct passed into mount + * + */ + +void gfs_withdraw_lockproto(struct lm_lockstruct *lockstruct) +{ + mutex_lock(&lmh_lock); + lockstruct->ls_ops->lm_withdraw(lockstruct->ls_lockspace); + if (lockstruct->ls_ops->lm_owner) + module_put(lockstruct->ls_ops->lm_owner); + mutex_unlock(&lmh_lock); +} --- linux-2.6.28.orig/ubuntu/gfs/lock_dlm_sysfs.c +++ linux-2.6.28/ubuntu/gfs/lock_dlm_sysfs.c @@ -0,0 +1,225 @@ +/* + * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. + * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License version 2. + */ + +#include +#include + +#include "lock_dlm.h" + +static ssize_t proto_name_show(struct gdlm_ls *ls, char *buf) +{ + return sprintf(buf, "%s\n", gdlm_ops.lm_proto_name); +} + +static ssize_t block_show(struct gdlm_ls *ls, char *buf) +{ + ssize_t ret; + int val = 0; + + if (test_bit(DFL_BLOCK_LOCKS, &ls->flags)) + val = 1; + ret = sprintf(buf, "%d\n", val); + return ret; +} + +static ssize_t block_store(struct gdlm_ls *ls, const char *buf, size_t len) +{ + ssize_t ret = len; + int val; + + val = simple_strtol(buf, NULL, 0); + + if (val == 1) + set_bit(DFL_BLOCK_LOCKS, &ls->flags); + else if (val == 0) { + clear_bit(DFL_BLOCK_LOCKS, &ls->flags); + gdlm_submit_delayed(ls); + } else { + ret = -EINVAL; + } + return ret; +} + +static ssize_t withdraw_show(struct gdlm_ls *ls, char *buf) +{ + ssize_t ret; + int val = 0; + + if (test_bit(DFL_WITHDRAW, &ls->flags)) + val = 1; + ret = sprintf(buf, "%d\n", val); + return ret; +} + +static ssize_t withdraw_store(struct gdlm_ls *ls, const char *buf, size_t len) +{ + ssize_t ret = len; + int val; + + val = simple_strtol(buf, NULL, 0); + + if (val == 1) + set_bit(DFL_WITHDRAW, &ls->flags); + else + ret = -EINVAL; + wake_up(&ls->wait_control); + return ret; +} + +static ssize_t id_show(struct gdlm_ls *ls, char *buf) +{ + return sprintf(buf, "%u\n", ls->id); +} + +static ssize_t jid_show(struct gdlm_ls *ls, char *buf) +{ + return sprintf(buf, "%d\n", ls->jid); +} + +static ssize_t first_show(struct gdlm_ls *ls, char *buf) +{ + return sprintf(buf, "%d\n", ls->first); +} + +static ssize_t first_done_show(struct gdlm_ls *ls, char *buf) +{ + return sprintf(buf, "%d\n", ls->first_done); +} + +static ssize_t recover_show(struct gdlm_ls *ls, char *buf) +{ + return sprintf(buf, "%d\n", ls->recover_jid); +} + +static ssize_t recover_store(struct gdlm_ls *ls, const char *buf, size_t len) +{ + ls->recover_jid = simple_strtol(buf, NULL, 0); + ls->fscb(ls->sdp, LM_CB_NEED_RECOVERY, &ls->recover_jid); + return len; +} + +static ssize_t recover_done_show(struct gdlm_ls *ls, char *buf) +{ + return sprintf(buf, "%d\n", ls->recover_jid_done); +} + +static ssize_t recover_status_show(struct gdlm_ls *ls, char *buf) +{ + return sprintf(buf, "%d\n", ls->recover_jid_status); +} + +static ssize_t drop_count_show(struct gdlm_ls *ls, char *buf) +{ + return sprintf(buf, "%d\n", ls->drop_locks_count); +} + +static ssize_t drop_count_store(struct gdlm_ls *ls, const char *buf, size_t len) +{ + ls->drop_locks_count = simple_strtol(buf, NULL, 0); + return len; +} + +struct gdlm_attr { + struct attribute attr; + ssize_t (*show)(struct gdlm_ls *, char *); + ssize_t (*store)(struct gdlm_ls *, const char *, size_t); +}; + +#define GDLM_ATTR(_name,_mode,_show,_store) \ +static struct gdlm_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store) + +GDLM_ATTR(proto_name, 0444, proto_name_show, NULL); +GDLM_ATTR(block, 0644, block_show, block_store); +GDLM_ATTR(withdraw, 0644, withdraw_show, withdraw_store); +GDLM_ATTR(id, 0444, id_show, NULL); +GDLM_ATTR(jid, 0444, jid_show, NULL); +GDLM_ATTR(first, 0444, first_show, NULL); +GDLM_ATTR(first_done, 0444, first_done_show, NULL); +GDLM_ATTR(recover, 0644, recover_show, recover_store); +GDLM_ATTR(recover_done, 0444, recover_done_show, NULL); +GDLM_ATTR(recover_status, 0444, recover_status_show, NULL); +GDLM_ATTR(drop_count, 0644, drop_count_show, drop_count_store); + +static struct attribute *gdlm_attrs[] = { + &gdlm_attr_proto_name.attr, + &gdlm_attr_block.attr, + &gdlm_attr_withdraw.attr, + &gdlm_attr_id.attr, + &gdlm_attr_jid.attr, + &gdlm_attr_first.attr, + &gdlm_attr_first_done.attr, + &gdlm_attr_recover.attr, + &gdlm_attr_recover_done.attr, + &gdlm_attr_recover_status.attr, + &gdlm_attr_drop_count.attr, + NULL, +}; + +static ssize_t gdlm_attr_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + struct gdlm_ls *ls = container_of(kobj, struct gdlm_ls, kobj); + struct gdlm_attr *a = container_of(attr, struct gdlm_attr, attr); + return a->show ? a->show(ls, buf) : 0; +} + +static ssize_t gdlm_attr_store(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t len) +{ + struct gdlm_ls *ls = container_of(kobj, struct gdlm_ls, kobj); + struct gdlm_attr *a = container_of(attr, struct gdlm_attr, attr); + return a->store ? a->store(ls, buf, len) : len; +} + +static struct sysfs_ops gdlm_attr_ops = { + .show = gdlm_attr_show, + .store = gdlm_attr_store, +}; + +static struct kobj_type gdlm_ktype = { + .default_attrs = gdlm_attrs, + .sysfs_ops = &gdlm_attr_ops, +}; + +static struct kset *gdlm_kset; + +int gdlm_kobject_setup(struct gdlm_ls *ls, struct kobject *fskobj) +{ + int error; + + ls->kobj.kset = gdlm_kset; + error = kobject_init_and_add(&ls->kobj, &gdlm_ktype, fskobj, + "lock_module"); + if (error) + log_error("can't register kobj %d", error); + kobject_uevent(&ls->kobj, KOBJ_ADD); + + return error; +} + +void gdlm_kobject_release(struct gdlm_ls *ls) +{ + kobject_put(&ls->kobj); +} + +int gdlm_sysfs_init(void) +{ + gdlm_kset = kset_create_and_add("lock_dlm_gfs", NULL, kernel_kobj); + if (!gdlm_kset) { + printk(KERN_WARNING "%s: can not create kset\n", __FUNCTION__); + return -ENOMEM; + } + return 0; +} + +void gdlm_sysfs_exit(void) +{ + kset_unregister(gdlm_kset); +} + --- linux-2.6.28.orig/ubuntu/gfs/lock_dlm_lock.c +++ linux-2.6.28/ubuntu/gfs/lock_dlm_lock.c @@ -0,0 +1,527 @@ +/* + * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. + * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License version 2. + */ + +#include "lock_dlm.h" + +static char junk_lvb[GDLM_LVB_SIZE]; + +static void queue_complete(struct gdlm_lock *lp) +{ + struct gdlm_ls *ls = lp->ls; + + clear_bit(LFL_ACTIVE, &lp->flags); + + spin_lock(&ls->async_lock); + list_add_tail(&lp->clist, &ls->complete); + spin_unlock(&ls->async_lock); + wake_up(&ls->thread_wait); +} + +static inline void gdlm_ast(void *astarg) +{ + queue_complete(astarg); +} + +static inline void gdlm_bast(void *astarg, int mode) +{ + struct gdlm_lock *lp = astarg; + struct gdlm_ls *ls = lp->ls; + + if (!mode) { + printk(KERN_INFO "lock_dlm: bast mode zero %x,%llx\n", + lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number); + return; + } + + spin_lock(&ls->async_lock); + if (!lp->bast_mode) { + list_add_tail(&lp->blist, &ls->blocking); + lp->bast_mode = mode; + } else if (lp->bast_mode < mode) + lp->bast_mode = mode; + spin_unlock(&ls->async_lock); + wake_up(&ls->thread_wait); +} + +void gdlm_queue_delayed(struct gdlm_lock *lp) +{ + struct gdlm_ls *ls = lp->ls; + + spin_lock(&ls->async_lock); + list_add_tail(&lp->delay_list, &ls->delayed); + spin_unlock(&ls->async_lock); +} + +/* convert gfs lock-state to dlm lock-mode */ + +static s16 make_mode(s16 lmstate) +{ + switch (lmstate) { + case LM_ST_UNLOCKED: + return DLM_LOCK_NL; + case LM_ST_EXCLUSIVE: + return DLM_LOCK_EX; + case LM_ST_DEFERRED: + return DLM_LOCK_CW; + case LM_ST_SHARED: + return DLM_LOCK_PR; + } + gdlm_assert(0, "unknown LM state %d", lmstate); + return -1; +} + +/* convert dlm lock-mode to gfs lock-state */ + +s16 gdlm_make_lmstate(s16 dlmmode) +{ + switch (dlmmode) { + case DLM_LOCK_IV: + case DLM_LOCK_NL: + return LM_ST_UNLOCKED; + case DLM_LOCK_EX: + return LM_ST_EXCLUSIVE; + case DLM_LOCK_CW: + return LM_ST_DEFERRED; + case DLM_LOCK_PR: + return LM_ST_SHARED; + } + gdlm_assert(0, "unknown DLM mode %d", dlmmode); + return -1; +} + +/* verify agreement with GFS on the current lock state, NB: DLM_LOCK_NL and + DLM_LOCK_IV are both considered LM_ST_UNLOCKED by GFS. */ + +static void check_cur_state(struct gdlm_lock *lp, unsigned int cur_state) +{ + s16 cur = make_mode(cur_state); + if (lp->cur != DLM_LOCK_IV) + gdlm_assert(lp->cur == cur, "%d, %d", lp->cur, cur); +} + +static inline unsigned int make_flags(struct gdlm_lock *lp, + unsigned int gfs_flags, + s16 cur, s16 req) +{ + unsigned int lkf = 0; + + if (gfs_flags & LM_FLAG_TRY) + lkf |= DLM_LKF_NOQUEUE; + + if (gfs_flags & LM_FLAG_TRY_1CB) { + lkf |= DLM_LKF_NOQUEUE; + lkf |= DLM_LKF_NOQUEUEBAST; + } + + if (gfs_flags & LM_FLAG_PRIORITY) { + lkf |= DLM_LKF_NOORDER; + lkf |= DLM_LKF_HEADQUE; + } + + if (gfs_flags & LM_FLAG_ANY) { + if (req == DLM_LOCK_PR) + lkf |= DLM_LKF_ALTCW; + else if (req == DLM_LOCK_CW) + lkf |= DLM_LKF_ALTPR; + } + + if (lp->lksb.sb_lkid != 0) { + lkf |= DLM_LKF_CONVERT; + + /* Conversion deadlock avoidance by DLM */ + + if (!test_bit(LFL_FORCE_PROMOTE, &lp->flags) && + !(lkf & DLM_LKF_NOQUEUE) && + cur > DLM_LOCK_NL && req > DLM_LOCK_NL && cur != req) + lkf |= DLM_LKF_CONVDEADLK; + } + + if (lp->lvb) + lkf |= DLM_LKF_VALBLK; + + return lkf; +} + +/* make_strname - convert GFS lock numbers to a string */ + +static inline void make_strname(const struct lm_lockname *lockname, + struct gdlm_strname *str) +{ + sprintf(str->name, "%8x%16llx", lockname->ln_type, + (unsigned long long)lockname->ln_number); + str->namelen = GDLM_STRNAME_BYTES; +} + +static int gdlm_create_lp(struct gdlm_ls *ls, struct lm_lockname *name, + struct gdlm_lock **lpp) +{ + struct gdlm_lock *lp; + + lp = kzalloc(sizeof(struct gdlm_lock), GFP_NOFS); + if (!lp) + return -ENOMEM; + + lp->lockname = *name; + make_strname(name, &lp->strname); + lp->ls = ls; + lp->cur = DLM_LOCK_IV; + lp->lvb = NULL; + lp->hold_null = NULL; + INIT_LIST_HEAD(&lp->clist); + INIT_LIST_HEAD(&lp->blist); + INIT_LIST_HEAD(&lp->delay_list); + + spin_lock(&ls->async_lock); + list_add(&lp->all_list, &ls->all_locks); + ls->all_locks_count++; + spin_unlock(&ls->async_lock); + + *lpp = lp; + return 0; +} + +void gdlm_delete_lp(struct gdlm_lock *lp) +{ + struct gdlm_ls *ls = lp->ls; + + spin_lock(&ls->async_lock); + if (!list_empty(&lp->clist)) + list_del_init(&lp->clist); + if (!list_empty(&lp->blist)) + list_del_init(&lp->blist); + if (!list_empty(&lp->delay_list)) + list_del_init(&lp->delay_list); + gdlm_assert(!list_empty(&lp->all_list), "%x,%llx", lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number); + list_del_init(&lp->all_list); + ls->all_locks_count--; + spin_unlock(&ls->async_lock); + + kfree(lp); +} + +int gdlm_get_lock(void *lockspace, struct lm_lockname *name, + void **lockp) +{ + struct gdlm_lock *lp; + int error; + + error = gdlm_create_lp(lockspace, name, &lp); + + *lockp = lp; + return error; +} + +void gdlm_put_lock(void *lock) +{ + gdlm_delete_lp(lock); +} + +unsigned int gdlm_do_lock(struct gdlm_lock *lp) +{ + struct gdlm_ls *ls = lp->ls; + int error, bast = 1; + + /* + * When recovery is in progress, delay lock requests for submission + * once recovery is done. Requests for recovery (NOEXP) and unlocks + * can pass. + */ + + if (test_bit(DFL_BLOCK_LOCKS, &ls->flags) && + !test_bit(LFL_NOBLOCK, &lp->flags) && lp->req != DLM_LOCK_NL) { + gdlm_queue_delayed(lp); + return LM_OUT_ASYNC; + } + + /* + * Submit the actual lock request. + */ + + if (test_bit(LFL_NOBAST, &lp->flags)) + bast = 0; + + set_bit(LFL_ACTIVE, &lp->flags); + + log_debug("lk %x,%llx id %x %d,%d %x", lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number, lp->lksb.sb_lkid, + lp->cur, lp->req, lp->lkf); + + error = dlm_lock(ls->dlm_lockspace, lp->req, &lp->lksb, lp->lkf, + lp->strname.name, lp->strname.namelen, 0, gdlm_ast, + lp, bast ? gdlm_bast : NULL); + + if ((error == -EAGAIN) && (lp->lkf & DLM_LKF_NOQUEUE)) { + lp->lksb.sb_status = -EAGAIN; + queue_complete(lp); + error = 0; + } + + if (error) { + log_error("%s: gdlm_lock %x,%llx err=%d cur=%d req=%d lkf=%x " + "flags=%lx", ls->fsname, lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number, error, + lp->cur, lp->req, lp->lkf, lp->flags); + return LM_OUT_ERROR; + } + return LM_OUT_ASYNC; +} + +static unsigned int gdlm_do_unlock(struct gdlm_lock *lp) +{ + struct gdlm_ls *ls = lp->ls; + unsigned int lkf = 0; + int error; + + set_bit(LFL_DLM_UNLOCK, &lp->flags); + set_bit(LFL_ACTIVE, &lp->flags); + + if (lp->lvb) + lkf = DLM_LKF_VALBLK; + + log_debug("un %x,%llx %x %d %x", lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number, + lp->lksb.sb_lkid, lp->cur, lkf); + + error = dlm_unlock(ls->dlm_lockspace, lp->lksb.sb_lkid, lkf, NULL, lp); + + if (error) { + log_error("%s: gdlm_unlock %x,%llx err=%d cur=%d req=%d lkf=%x " + "flags=%lx", ls->fsname, lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number, error, + lp->cur, lp->req, lp->lkf, lp->flags); + return LM_OUT_ERROR; + } + return LM_OUT_ASYNC; +} + +unsigned int gdlm_lock(void *lock, unsigned int cur_state, + unsigned int req_state, unsigned int flags) +{ + struct gdlm_lock *lp = lock; + + clear_bit(LFL_DLM_CANCEL, &lp->flags); + if (flags & LM_FLAG_NOEXP) + set_bit(LFL_NOBLOCK, &lp->flags); + + check_cur_state(lp, cur_state); + lp->req = make_mode(req_state); + lp->lkf = make_flags(lp, flags, lp->cur, lp->req); + + return gdlm_do_lock(lp); +} + +unsigned int gdlm_unlock(void *lock, unsigned int cur_state) +{ + struct gdlm_lock *lp = lock; + + clear_bit(LFL_DLM_CANCEL, &lp->flags); + if (lp->cur == DLM_LOCK_IV) + return 0; + return gdlm_do_unlock(lp); +} + +void gdlm_cancel(void *lock) +{ + struct gdlm_lock *lp = lock; + struct gdlm_ls *ls = lp->ls; + int error, delay_list = 0; + + if (test_bit(LFL_DLM_CANCEL, &lp->flags)) + return; + + log_info("gdlm_cancel %x,%llx flags %lx", lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number, lp->flags); + + spin_lock(&ls->async_lock); + if (!list_empty(&lp->delay_list)) { + list_del_init(&lp->delay_list); + delay_list = 1; + } + spin_unlock(&ls->async_lock); + + if (delay_list) { + set_bit(LFL_CANCEL, &lp->flags); + set_bit(LFL_ACTIVE, &lp->flags); + queue_complete(lp); + return; + } + + if (!test_bit(LFL_ACTIVE, &lp->flags) || + test_bit(LFL_DLM_UNLOCK, &lp->flags)) { + log_info("gdlm_cancel skip %x,%llx flags %lx", + lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number, lp->flags); + return; + } + + /* the lock is blocked in the dlm */ + + set_bit(LFL_DLM_CANCEL, &lp->flags); + set_bit(LFL_ACTIVE, &lp->flags); + + error = dlm_unlock(ls->dlm_lockspace, lp->lksb.sb_lkid, DLM_LKF_CANCEL, + NULL, lp); + + log_info("gdlm_cancel rv %d %x,%llx flags %lx", error, + lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number, lp->flags); + + if (error == -EBUSY) + clear_bit(LFL_DLM_CANCEL, &lp->flags); +} + +static int gdlm_add_lvb(struct gdlm_lock *lp) +{ + char *lvb; + + lvb = kzalloc(GDLM_LVB_SIZE, GFP_NOFS); + if (!lvb) + return -ENOMEM; + + lp->lksb.sb_lvbptr = lvb; + lp->lvb = lvb; + return 0; +} + +static void gdlm_del_lvb(struct gdlm_lock *lp) +{ + kfree(lp->lvb); + lp->lvb = NULL; + lp->lksb.sb_lvbptr = NULL; +} + +static int gdlm_ast_wait(void *word) +{ + schedule(); + return 0; +} + +/* This can do a synchronous dlm request (requiring a lock_dlm thread to get + the completion) because gfs won't call hold_lvb() during a callback (from + the context of a lock_dlm thread). */ + +static int hold_null_lock(struct gdlm_lock *lp) +{ + struct gdlm_lock *lpn = NULL; + int error; + + if (lp->hold_null) { + printk(KERN_INFO "lock_dlm: lvb already held\n"); + return 0; + } + + error = gdlm_create_lp(lp->ls, &lp->lockname, &lpn); + if (error) + goto out; + + lpn->lksb.sb_lvbptr = junk_lvb; + lpn->lvb = junk_lvb; + + lpn->req = DLM_LOCK_NL; + lpn->lkf = DLM_LKF_VALBLK | DLM_LKF_EXPEDITE; + set_bit(LFL_NOBAST, &lpn->flags); + set_bit(LFL_INLOCK, &lpn->flags); + set_bit(LFL_AST_WAIT, &lpn->flags); + + gdlm_do_lock(lpn); + wait_on_bit(&lpn->flags, LFL_AST_WAIT, gdlm_ast_wait, TASK_UNINTERRUPTIBLE); + error = lpn->lksb.sb_status; + if (error) { + printk(KERN_INFO "lock_dlm: hold_null_lock dlm error %d\n", + error); + gdlm_delete_lp(lpn); + lpn = NULL; + } +out: + lp->hold_null = lpn; + return error; +} + +/* This cannot do a synchronous dlm request (requiring a lock_dlm thread to get + the completion) because gfs may call unhold_lvb() during a callback (from + the context of a lock_dlm thread) which could cause a deadlock since the + other lock_dlm thread could be engaged in recovery. */ + +static void unhold_null_lock(struct gdlm_lock *lp) +{ + struct gdlm_lock *lpn = lp->hold_null; + + gdlm_assert(lpn, "%x,%llx", lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number); + lpn->lksb.sb_lvbptr = NULL; + lpn->lvb = NULL; + set_bit(LFL_UNLOCK_DELETE, &lpn->flags); + gdlm_do_unlock(lpn); + lp->hold_null = NULL; +} + +/* Acquire a NL lock because gfs requires the value block to remain + intact on the resource while the lvb is "held" even if it's holding no locks + on the resource. */ + +int gdlm_hold_lvb(void *lock, char **lvbp) +{ + struct gdlm_lock *lp = lock; + int error; + + error = gdlm_add_lvb(lp); + if (error) + return error; + + *lvbp = lp->lvb; + + error = hold_null_lock(lp); + if (error) + gdlm_del_lvb(lp); + + return error; +} + +void gdlm_unhold_lvb(void *lock, char *lvb) +{ + struct gdlm_lock *lp = lock; + + unhold_null_lock(lp); + gdlm_del_lvb(lp); +} + +void gdlm_submit_delayed(struct gdlm_ls *ls) +{ + struct gdlm_lock *lp, *safe; + + spin_lock(&ls->async_lock); + list_for_each_entry_safe(lp, safe, &ls->delayed, delay_list) { + list_del_init(&lp->delay_list); + list_add_tail(&lp->delay_list, &ls->submit); + } + spin_unlock(&ls->async_lock); + wake_up(&ls->thread_wait); +} + +int gdlm_release_all_locks(struct gdlm_ls *ls) +{ + struct gdlm_lock *lp, *safe; + int count = 0; + + spin_lock(&ls->async_lock); + list_for_each_entry_safe(lp, safe, &ls->all_locks, all_list) { + list_del_init(&lp->all_list); + + if (lp->lvb && lp->lvb != junk_lvb) + kfree(lp->lvb); + kfree(lp); + count++; + } + spin_unlock(&ls->async_lock); + + return count; +} + --- linux-2.6.28.orig/ubuntu/gfs/util.h +++ linux-2.6.28/ubuntu/gfs/util.h @@ -0,0 +1,330 @@ +#ifndef __UTIL_DOT_H__ +#define __UTIL_DOT_H__ + + +/* Utility functions */ + +extern uint32_t gfs_random_number; +uint32_t gfs_random(void); + +uint32_t gfs_hash(const void *data, unsigned int len); +uint32_t gfs_hash_more(const void *data, unsigned int len, uint32_t hash); + +void gfs_sort(void *base, unsigned int num_elem, unsigned int size, + int (*compar) (const void *, const void *)); + + +/* Error handling */ + +/** + * gfs_assert - Cause the machine to panic if @assertion is false + * @sdp: + * @assertion: + * @todo: + * + */ + +void gfs_assert_i(struct gfs_sbd *sdp, + char *assertion, + const char *function, + char *file, unsigned int line) +__attribute__ ((noreturn)); +#define gfs_assert(sdp, assertion, todo) \ +do { \ + if (unlikely(!(assertion))) { \ + {todo} \ + gfs_assert_i((sdp), #assertion, \ + __FUNCTION__, __FILE__, __LINE__); \ + } \ +} while (0) + +/** + * gfs_assert_withdraw - Cause the machine to withdraw if @assertion is false + * @sdp: + * @assertion: + * + * Returns: 0 if things are ok, + * -1 if this call withdrew the machine, + * -2 if it was already withdrawn + */ + +int gfs_assert_withdraw_i(struct gfs_sbd *sdp, + char *assertion, + const char *function, + char *file, unsigned int line); +#define gfs_assert_withdraw(sdp, assertion) \ +((likely(assertion)) ? 0 : \ + gfs_assert_withdraw_i((sdp), #assertion, \ + __FUNCTION__, __FILE__, __LINE__)) + +/** + * gfs_assert_warn - Print a message to the console if @assertion is false + * @sdp: + * @assertion: + * + * Returns: 0 if things are ok, + * -1 if we printed something + * -2 if we didn't + */ + +int gfs_assert_warn_i(struct gfs_sbd *sdp, + char *assertion, + const char *function, + char *file, unsigned int line); +#define gfs_assert_warn(sdp, assertion) \ +((likely(assertion)) ? 0 : \ + gfs_assert_warn_i((sdp), #assertion, \ + __FUNCTION__, __FILE__, __LINE__)) + +/** + * gfs_consist - Flag a filesystem consistency error and withdraw + * gfs_cconsist - Flag a filesystem consistency error and withdraw cluster + * @sdp: + * + * Returns: -1 if this call withdrew the machine, + * 0 if it was already withdrawn + */ + +int gfs_consist_i(struct gfs_sbd *sdp, int cluster_wide, + const char *function, + char *file, unsigned int line); +#define gfs_consist(sdp)\ +gfs_consist_i((sdp), FALSE, __FUNCTION__, __FILE__, __LINE__) +#define gfs_cconsist(sdp)\ +gfs_consist_i((sdp), TRUE, __FUNCTION__, __FILE__, __LINE__) + +/** + * gfs_consist_inode - Flag an inode consistency error and withdraw + * gfs_cconsist_inode - Flag an inode consistency error and withdraw cluster + * @ip: + * + * Returns: -1 if this call withdrew the machine, + * 0 if it was already withdrawn + */ + +int gfs_consist_inode_i(struct gfs_inode *ip, int cluster_wide, + const char *function, + char *file, unsigned int line); +#define gfs_consist_inode(ip) \ +gfs_consist_inode_i((ip), FALSE, __FUNCTION__, __FILE__, __LINE__) +#define gfs_cconsist_inode(ip) \ +gfs_consist_inode_i((ip), TRUE, __FUNCTION__, __FILE__, __LINE__) + +/** + * gfs_consist_rgrpd - Flag a RG consistency error and withdraw + * gfs_cconsist_rgrpd - Flag a RG consistency error and withdraw cluster + * @rgd: + * + * Returns: -1 if this call withdrew the machine, + * 0 if it was already withdrawn + */ + +int gfs_consist_rgrpd_i(struct gfs_rgrpd *rgd, int cluster_wide, + const char *function, + char *file, unsigned int line); +#define gfs_consist_rgrpd(rgd) \ +gfs_consist_rgrpd_i((rgd), FALSE, __FUNCTION__, __FILE__, __LINE__) +#define gfs_cconsist_rgrpd(rgd) \ +gfs_consist_rgrpd_i((rgd), TRUE, __FUNCTION__, __FILE__, __LINE__) + +/** + * gfs_meta_check - Flag a magic number consistency error and withdraw + * @sdp: + * @bh: + * + * Returns: 0 if things are ok, + * -1 if this call withdrew the machine, + * -2 if it was already withdrawn + */ + +int gfs_meta_check_ii(struct gfs_sbd *sdp, struct buffer_head *bh, + const char *function, + char *file, unsigned int line); +static __inline__ int +gfs_meta_check_i(struct gfs_sbd *sdp, struct buffer_head *bh, + const char *function, + char *file, unsigned int line) +{ + uint32_t magic; + magic = ((struct gfs_meta_header *)(bh)->b_data)->mh_magic; + magic = gfs32_to_cpu(magic); + if (likely(magic == GFS_MAGIC)) + return 0; + return gfs_meta_check_ii(sdp, bh, function, file, line); +} +#define gfs_meta_check(sdp, bh) \ +gfs_meta_check_i((sdp), (bh), \ + __FUNCTION__, __FILE__, __LINE__) + +/** + * gfs_metatype_check - Flag a metadata type consistency error and withdraw + * @sdp: + * @bh: + * @type: + * + * Returns: 0 if things are ok, + * -1 if this call withdrew the machine, + * -2 if it was already withdrawn + */ + +int gfs_metatype_check_ii(struct gfs_sbd *sdp, struct buffer_head *bh, + uint32_t type, uint32_t t, + const char *function, + char *file, unsigned int line); +static __inline__ int +gfs_metatype_check_i(struct gfs_sbd *sdp, struct buffer_head *bh, + uint32_t type, + const char *function, + char *file, unsigned int line) +{ + uint32_t magic, t; + magic = ((struct gfs_meta_header *)(bh)->b_data)->mh_magic; + magic = gfs32_to_cpu(magic); + if (unlikely(magic != GFS_MAGIC)) + return gfs_meta_check_ii(sdp, bh, function, file, line); + t = ((struct gfs_meta_header *)(bh)->b_data)->mh_type; + t = gfs32_to_cpu(t); + if (unlikely(t != type)) + return gfs_metatype_check_ii(sdp, bh, type, t, function, file, line); + return 0; +} +#define gfs_metatype_check(sdp, bh, type) \ +gfs_metatype_check_i((sdp), (bh), (type), \ + __FUNCTION__, __FILE__, __LINE__) + +/** + * gfs_metatype_check2 - Flag a metadata type consistency error and withdraw + * @sdp: + * @bh: + * @type1: + * @type2: + * + * Returns: 0 if things are ok, + * -1 if this call withdrew the machine, + * -2 if it was already withdrawn + */ + +static __inline__ int +gfs_metatype_check2_i(struct gfs_sbd *sdp, struct buffer_head *bh, + uint32_t type1, uint32_t type2, + const char *function, + char *file, unsigned int line) +{ + uint32_t magic, t; + magic = ((struct gfs_meta_header *)(bh)->b_data)->mh_magic; + magic = gfs32_to_cpu(magic); + if (unlikely(magic != GFS_MAGIC)) + return gfs_meta_check_ii(sdp, bh, function, file, line); + t = ((struct gfs_meta_header *)(bh)->b_data)->mh_type; + t = gfs32_to_cpu(t); + if (unlikely(t != type1 && t != type2)) + return gfs_metatype_check_ii(sdp, bh, type1, t, function, file, line); + return 0; +} +#define gfs_metatype_check2(sdp, bh, type1, type2) \ +gfs_metatype_check2_i((sdp), (bh), (type1), (type2), \ + __FUNCTION__, __FILE__, __LINE__) + +/** + * gfs_metatype_set - set the metadata type on a buffer + * @bh: + * @type: + * @format: + * + */ + +static __inline__ void +gfs_metatype_set(struct buffer_head *bh, uint32_t type, uint32_t format) +{ + struct gfs_meta_header *mh; + mh = (struct gfs_meta_header *)bh->b_data; + mh->mh_type = cpu_to_gfs32(type); + mh->mh_format = cpu_to_gfs32(format); +} + +/** + * gfs_io_error - Flag an I/O error and withdraw + * @sdp: + * + * Returns: -1 if this call withdrew the machine, + * 0 if it was already withdrawn + */ + +int gfs_io_error_i(struct gfs_sbd *sdp, + const char *function, + char *file, unsigned int line); +#define gfs_io_error(sdp) \ +gfs_io_error_i((sdp), __FUNCTION__, __FILE__, __LINE__); + +/** + * gfs_io_error_inode - Flag an inode I/O error and withdraw + * @ip: + * + * Returns: -1 if this call withdrew the machine, + * 0 if it was already withdrawn + */ + +int gfs_io_error_inode_i(struct gfs_inode *ip, + const char *function, + char *file, unsigned int line); +#define gfs_io_error_inode(ip) \ +gfs_io_error_inode_i((ip), __FUNCTION__, __FILE__, __LINE__); + +/** + * gfs_io_error_bh - Flag a buffer I/O error and withdraw + * @sdp: + * @bh: + * + * Returns: -1 if this call withdrew the machine, + * 0 if it was already withdrawn + */ + +int gfs_io_error_bh_i(struct gfs_sbd *sdp, struct buffer_head *bh, + const char *function, + char *file, unsigned int line); +#define gfs_io_error_bh(sdp, bh) \ +gfs_io_error_bh_i((sdp), (bh), __FUNCTION__, __FILE__, __LINE__); + + +/* Memory stuff */ + +#define RETRY_MALLOC(do_this, until_this) \ +for (;;) { \ + { do_this; } \ + if (until_this) \ + break; \ + printk("GFS: out of memory: %s, %u\n", __FILE__, __LINE__); \ + dump_stack(); \ + yield(); \ +} + +extern struct kmem_cache *gfs_glock_cachep; +extern struct kmem_cache *gfs_inode_cachep; +extern struct kmem_cache *gfs_bufdata_cachep; +extern struct kmem_cache *gfs_mhc_cachep; + +void *gmalloc(unsigned int size); + + +struct gfs_user_buffer { + char *ub_data; + unsigned int ub_size; + unsigned int ub_count; +}; +int gfs_add_bh_to_ub(struct gfs_user_buffer *ub, struct buffer_head *bh); + + +static __inline__ unsigned int +gfs_tune_get_i(struct gfs_tune *gt, unsigned int *p) +{ + unsigned int x; + spin_lock(>->gt_spin); + x = *p; + spin_unlock(>->gt_spin); + return x; +} +#define gfs_tune_get(sdp, field) \ +gfs_tune_get_i(&(sdp)->sd_tune, &(sdp)->sd_tune.field) + + +#endif /* __UTIL_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/lock_dlm_main.c +++ linux-2.6.28/ubuntu/gfs/lock_dlm_main.c @@ -0,0 +1,40 @@ +/* + * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. + * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License version 2. + */ + +#include + +#include "lock_dlm.h" + +int init_lock_dlm() +{ + int error; + + error = gfs_register_lockproto(&gdlm_ops); + if (error) { + printk(KERN_WARNING "lock_dlm: can't register protocol: %d\n", + error); + return error; + } + + error = gdlm_sysfs_init(); + if (error) { + gfs_unregister_lockproto(&gdlm_ops); + return error; + } + + printk(KERN_INFO + "Lock_DLM (built %s %s) installed\n", __DATE__, __TIME__); + return 0; +} + +void exit_lock_dlm() +{ + gdlm_sysfs_exit(); + gfs_unregister_lockproto(&gdlm_ops); +} --- linux-2.6.28.orig/ubuntu/gfs/ops_super.h +++ linux-2.6.28/ubuntu/gfs/ops_super.h @@ -0,0 +1,6 @@ +#ifndef __OPS_SUPER_DOT_H__ +#define __OPS_SUPER_DOT_H__ + +extern struct super_operations gfs_super_ops; + +#endif /* __OPS_SUPER_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/acl.c +++ linux-2.6.28/ubuntu/gfs/acl.c @@ -0,0 +1,396 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "acl.h" +#include "eattr.h" +#include "inode.h" + +/** + * gfs_acl_validate_set - + * @ip: + * @access: + * @er: + * @mode: + * @remove: + * + * Returns: errno + */ + +int +gfs_acl_validate_set(struct gfs_inode *ip, int access, + struct gfs_ea_request *er, + int *remove, mode_t *mode) +{ + struct posix_acl *acl; + int error; + + error = gfs_acl_validate_remove(ip, access); + if (error) + return error; + + if (!er->er_data) + return -EINVAL; + + acl = posix_acl_from_xattr(er->er_data, er->er_data_len); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (!acl) { + *remove = TRUE; + return 0; + } + + error = posix_acl_valid(acl); + if (error) + goto out; + + if (access) { + error = posix_acl_equiv_mode(acl, mode); + if (!error) + *remove = TRUE; + else if (error > 0) + error = 0; + } + + out: + posix_acl_release(acl); + + return error; +} + +/** + * gfs_acl_validate_remove - + * @ip: + * @access: + * + * Returns: errno + */ + +int +gfs_acl_validate_remove(struct gfs_inode *ip, int access) +{ + if (!ip->i_sbd->sd_args.ar_posix_acls) + return -EOPNOTSUPP; + if (current->fsuid != ip->i_di.di_uid && !capable(CAP_FOWNER)) + return -EPERM; + if (ip->i_di.di_type == GFS_FILE_LNK) + return -EOPNOTSUPP; + if (!access && ip->i_di.di_type != GFS_FILE_DIR) + return -EACCES; + + return 0; +} + +/** + * gfs_acl_get - + * @ip: + * @access: + * @acl: + * + * Returns: errno + */ + +int +gfs_acl_get(struct gfs_inode *ip, int access, struct posix_acl **acl) +{ + struct gfs_ea_request er; + struct gfs_ea_location el; + int error; + + if (!ip->i_di.di_eattr) + return 0; + + memset(&er, 0, sizeof(struct gfs_ea_request)); + if (access) { + er.er_name = GFS_POSIX_ACL_ACCESS; + er.er_name_len = GFS_POSIX_ACL_ACCESS_LEN; + } else { + er.er_name = GFS_POSIX_ACL_DEFAULT; + er.er_name_len = GFS_POSIX_ACL_DEFAULT_LEN; + } + er.er_type = GFS_EATYPE_SYS; + + error = gfs_ea_find(ip, &er, &el); + if (error) + return error; + if (!el.el_ea) + return 0; + if (!GFS_EA_DATA_LEN(el.el_ea)) + goto out; + + er.er_data = kmalloc(GFS_EA_DATA_LEN(el.el_ea), GFP_KERNEL); + error = -ENOMEM; + if (!er.er_data) + goto out; + + error = gfs_ea_get_copy(ip, &el, er.er_data); + if (error) + goto out_kfree; + + *acl = posix_acl_from_xattr(er.er_data, GFS_EA_DATA_LEN(el.el_ea)); + if (IS_ERR(*acl)) + error = PTR_ERR(*acl); + + out_kfree: + kfree(er.er_data); + + out: + brelse(el.el_bh); + + return error; +} + +/** + * gfs_check_acl - Check an ACL for to see if we're allowed to do something + * @inode: the file we want to do something to + * @mask: what we want to do + * + * Returns: errno + */ + +int +gfs_check_acl(struct inode *inode, int mask) +{ + struct posix_acl *acl = NULL; + int error; + + error = gfs_acl_get(get_v2ip(inode), TRUE, &acl); + if (error) + return error; + + if (acl) { + error = posix_acl_permission(inode, acl, mask); + posix_acl_release(acl); + return error; + } + + return -EAGAIN; +} + +/** + * gfs_acl_new_prep - + * @dip: + * @type: + * @mode: + * @a_acl: + * @d_acl: + * @blocks: + * @data: + * + * Returns: errno + */ + +int +gfs_acl_new_prep(struct gfs_inode *dip, + unsigned int type, mode_t *mode, + void **a_data, void **d_data, + unsigned int *size, + unsigned int *blocks) +{ + struct posix_acl *acl = NULL; + int set_a = FALSE, set_d = FALSE; + int error; + + if (!dip->i_sbd->sd_args.ar_posix_acls) + return 0; + if (type == GFS_FILE_LNK) + return 0; + + error = gfs_acl_get(dip, FALSE, &acl); + if (error) + return error; + if (!acl) { + (*mode) &= ~current->fs->umask; + return 0; + } + + { + struct posix_acl *clone = posix_acl_clone(acl, GFP_KERNEL); + error = -ENOMEM; + if (!clone) + goto out; + posix_acl_release(acl); + acl = clone; + } + + error = posix_acl_create_masq(acl, mode); + if (error < 0) + goto out; + if (error > 0) { + set_a = TRUE; + error = 0; + } + if (type == GFS_FILE_DIR) + set_d = TRUE; + + if (set_a || set_d) { + struct gfs_ea_request er; + void *d; + unsigned int s = posix_acl_xattr_size(acl->a_count); + unsigned int b; + + memset(&er, 0, sizeof(struct gfs_ea_request)); + er.er_name_len = GFS_POSIX_ACL_DEFAULT_LEN; + er.er_data_len = s; + error = gfs_ea_check_size(dip->i_sbd, &er); + if (error) + goto out; + + b = DIV_RU(er.er_data_len, dip->i_sbd->sd_jbsize); + if (set_a && set_d) + b *= 2; + b++; + + d = kmalloc(s, GFP_KERNEL); + error = -ENOMEM; + if (!d) + goto out; + posix_acl_to_xattr(acl, d, s); + + if (set_a) + *a_data = d; + if (set_d) + *d_data = d; + *size = s; + *blocks = b; + + error = 0; + } + + out: + posix_acl_release(acl); + + return error; +} + +/** + * gfs_acl_new_init - + * @dip: + * @ip: + * @a_data: + * @d_data: + * @size: + * + * Returns: errno + */ + +int gfs_acl_new_init(struct gfs_inode *dip, struct gfs_inode *ip, + void *a_data, void *d_data, unsigned int size) +{ + void *data = (a_data) ? a_data : d_data; + unsigned int x; + int error = 0; + + ip->i_alloc = dip->i_alloc; /* Cheesy, but it works. */ + + for (x = 0; x < 2; x++) { + struct gfs_ea_request er; + + memset(&er, 0, sizeof(struct gfs_ea_request)); + if (x) { + if (!a_data) + continue; + er.er_name = GFS_POSIX_ACL_ACCESS; + er.er_name_len = GFS_POSIX_ACL_ACCESS_LEN; + } else { + if (!d_data) + continue; + er.er_name = GFS_POSIX_ACL_DEFAULT; + er.er_name_len = GFS_POSIX_ACL_DEFAULT_LEN; + } + er.er_data = data; + er.er_data_len = size; + er.er_type = GFS_EATYPE_SYS; + + error = gfs_ea_acl_init(ip, &er); + if (error) + break; + } + + ip->i_alloc = NULL; + + kfree(data); + + return error; +} + +/** + * gfs_acl_chmod - + * @ip: + * @attr: + * + * Returns: errno + */ + +int +gfs_acl_chmod(struct gfs_inode *ip, struct iattr *attr) +{ + struct gfs_ea_request er; + struct gfs_ea_location el; + struct posix_acl *acl; + int error; + + if (!ip->i_di.di_eattr) + goto simple; + + memset(&er, 0, sizeof(struct gfs_ea_request)); + er.er_name = GFS_POSIX_ACL_ACCESS; + er.er_name_len = GFS_POSIX_ACL_ACCESS_LEN; + er.er_type = GFS_EATYPE_SYS; + + error = gfs_ea_find(ip, &er, &el); + if (error) + return error; + if (!el.el_ea) + goto simple; + if (!GFS_EA_DATA_LEN(el.el_ea)) + goto simple; + + er.er_data = kmalloc(GFS_EA_DATA_LEN(el.el_ea), GFP_KERNEL); + error = -ENOMEM; + if (!er.er_data) + goto out; + + error = gfs_ea_get_copy(ip, &el, er.er_data); + if (error) + goto out_kfree; + + acl = posix_acl_from_xattr(er.er_data, GFS_EA_DATA_LEN(el.el_ea)); + if (IS_ERR(acl)) { + error = PTR_ERR(acl); + goto out_kfree; + } else if (!acl) { + kfree(er.er_data); + brelse(el.el_bh); + goto simple; + } + + error = posix_acl_chmod_masq(acl, attr->ia_mode); + if (error) + goto out_acl; + + posix_acl_to_xattr(acl, er.er_data, GFS_EA_DATA_LEN(el.el_ea)); + + error = gfs_ea_acl_chmod(ip, &el, attr, er.er_data); + + out_acl: + posix_acl_release(acl); + + out_kfree: + kfree(er.er_data); + + out: + brelse(el.el_bh); + + return error; + + simple: + return gfs_setattr_simple(ip, attr); +} --- linux-2.6.28.orig/ubuntu/gfs/bits.c +++ linux-2.6.28/ubuntu/gfs/bits.c @@ -0,0 +1,211 @@ +/* + * These routines are used by the resource group routines (rgrp.c) + * to keep track of block allocation. Each block is represented by two + * bits. One bit indicates whether or not the block is used. (1=used, + * 0=free) The other bit indicates whether or not the block contains a + * dinode or not. (1=dinode, 0=data block) So, each byte represents + * GFS_NBBY (i.e. 4) blocks. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "bits.h" + +#if BITS_PER_LONG == 32 +#define LBITMASK (0x55555555UL) +#define LBITSKIP55 (0x55555555UL) +#define LBITSKIP00 (0x00000000UL) +#else +#define LBITMASK (0x5555555555555555UL) +#define LBITSKIP55 (0x5555555555555555UL) +#define LBITSKIP00 (0x0000000000000000UL) +#endif + +static const char valid_change[16] = { + /* current */ + /* n */ 0, 1, 1, 1, + /* e */ 1, 0, 0, 0, + /* w */ 1, 0, 0, 1, + 0, 0, 1, 0 +}; + +/** + * gfs_setbit - Set a bit in the bitmaps + * @buffer: the buffer that holds the bitmaps + * @buflen: the length (in bytes) of the buffer + * @block: the block to set + * @new_state: the new state of the block + * + */ + +void +gfs_setbit(struct gfs_rgrpd *rgd, + unsigned char *buffer, unsigned int buflen, + uint32_t block, unsigned char new_state) +{ + unsigned char *byte, *end, cur_state; + unsigned int bit; + + byte = buffer + (block / GFS_NBBY); + bit = (block % GFS_NBBY) * GFS_BIT_SIZE; + end = buffer + buflen; + + gfs_assert(rgd->rd_sbd, byte < end,); + + cur_state = (*byte >> bit) & GFS_BIT_MASK; + + if (valid_change[new_state * 4 + cur_state]) { + *byte ^= cur_state << bit; + *byte |= new_state << bit; + } else + gfs_consist_rgrpd(rgd); +} + +/** + * gfs_testbit - test a bit in the bitmaps + * @buffer: the buffer that holds the bitmaps + * @buflen: the length (in bytes) of the buffer + * @block: the block to read + * + */ + +unsigned char +gfs_testbit(struct gfs_rgrpd *rgd, + unsigned char *buffer, unsigned int buflen, uint32_t block) +{ + unsigned char *byte, *end, cur_state; + unsigned int bit; + + byte = buffer + (block / GFS_NBBY); + bit = (block % GFS_NBBY) * GFS_BIT_SIZE; + end = buffer + buflen; + + gfs_assert(rgd->rd_sbd, byte < end,); + + cur_state = (*byte >> bit) & GFS_BIT_MASK; + + return cur_state; +} + +/** + * gfs_bitfit - Search an rgrp's bitmap buffer to find a bit-pair representing + * a block in a given allocation state. + * @buffer: the buffer that holds the bitmaps + * @buflen: the length (in bytes) of the buffer + * @goal: start search at this block's bit-pair (within @buffer) + * @old_state: GFS_BLKST_XXX the state of the block we're looking for; + * bit 0 = alloc(1)/free(0), bit 1 = meta(1)/data(0) + * + * Scope of @goal and returned block number is only within this bitmap buffer, + * not entire rgrp or filesystem. + * @buffer will be offset from the actual beginning of a bitmap block buffer, + * skipping any header structures. + * + * Return: the block number (bitmap buffer scope) that was found + */ + +uint32_t +gfs_bitfit(unsigned char *buffer, unsigned int buflen, + uint32_t goal, unsigned char old_state) +{ + const u8 *byte, *start, *end; + int bit, startbit; + u32 g1, g2, misaligned; + unsigned long *plong; + unsigned long lskipval; + + lskipval = (old_state & GFS_BLKST_USED) ? LBITSKIP00 : LBITSKIP55; + g1 = (goal / GFS_NBBY); + start = buffer + g1; + byte = start; + end = buffer + buflen; + g2 = ALIGN(g1, sizeof(unsigned long)); + plong = (unsigned long *)(buffer + g2); + startbit = bit = (goal % GFS_NBBY) * GFS_BIT_SIZE; + misaligned = g2 - g1; + if (!misaligned) + goto ulong_aligned; +/* parse the bitmap a byte at a time */ +misaligned: + while (byte < end) { + if (((*byte >> bit) & GFS_BIT_MASK) == old_state) { + return goal + + (((byte - start) * GFS_NBBY) + + ((bit - startbit) >> 1)); + } + bit += GFS_BIT_SIZE; + if (bit >= GFS_NBBY * GFS_BIT_SIZE) { + bit = 0; + byte++; + misaligned--; + if (!misaligned) { + plong = (unsigned long *)byte; + goto ulong_aligned; + } + } + } + return BFITNOENT; + +/* parse the bitmap a unsigned long at a time */ +ulong_aligned: + /* Stop at "end - 1" or else prefetch can go past the end and segfault. + We could "if" it but we'd lose some of the performance gained. + This way will only slow down searching the very last 4/8 bytes + depending on architecture. I've experimented with several ways + of writing this section such as using an else before the goto + but this one seems to be the fastest. */ + while ((unsigned char *)plong < end - sizeof(unsigned long)) { + prefetch(plong + 1); + if (((*plong) & LBITMASK) != lskipval) + break; + plong++; + } + if ((unsigned char *)plong < end) { + byte = (const u8 *)plong; + misaligned += sizeof(unsigned long) - 1; + goto misaligned; + } + return BFITNOENT; +} + +/** + * gfs_bitcount - count the number of bits in a certain state + * @buffer: the buffer that holds the bitmaps + * @buflen: the length (in bytes) of the buffer + * @state: the state of the block we're looking for + * + * Returns: The number of bits + */ + +uint32_t +gfs_bitcount(struct gfs_rgrpd *rgd, + unsigned char *buffer, unsigned int buflen, + unsigned char state) +{ + unsigned char *byte = buffer; + unsigned char *end = buffer + buflen; + unsigned char state1 = state << 2; + unsigned char state2 = state << 4; + unsigned char state3 = state << 6; + uint32_t count = 0; + + for (; byte < end; byte++) { + if (((*byte) & 0x03) == state) + count++; + if (((*byte) & 0x0C) == state1) + count++; + if (((*byte) & 0x30) == state2) + count++; + if (((*byte) & 0xC0) == state3) + count++; + } + + return count; +} --- linux-2.6.28.orig/ubuntu/gfs/proc.h +++ linux-2.6.28/ubuntu/gfs/proc.h @@ -0,0 +1,14 @@ +#ifndef __PROC_DOT_H__ +#define __PROC_DOT_H__ + +/* Allow args to be passed to GFS when using an initial ram disk */ +extern char *gfs_proc_margs; +extern spinlock_t gfs_proc_margs_lock; + +void gfs_proc_fs_add(struct gfs_sbd *sdp); +void gfs_proc_fs_del(struct gfs_sbd *sdp); + +int gfs_proc_init(void); +void gfs_proc_uninit(void); + +#endif /* __PROC_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/lops.h +++ linux-2.6.28/ubuntu/gfs/lops.h @@ -0,0 +1,166 @@ +#ifndef __LOPS_DOT_H__ +#define __LOPS_DOT_H__ + +extern struct gfs_log_operations gfs_glock_lops; +extern struct gfs_log_operations gfs_buf_lops; +extern struct gfs_log_operations gfs_unlinked_lops; +extern struct gfs_log_operations gfs_quota_lops; + +extern struct gfs_log_operations *gfs_log_ops[]; + +#define INIT_LE(le, lops) \ +do \ +{ \ + (le)->le_ops = (lops); \ + (le)->le_trans = NULL; \ + INIT_LIST_HEAD(&(le)->le_list); \ +} \ +while (0) + +#define LO_ADD(sdp, le) \ +do \ +{ \ + if ((le)->le_ops->lo_add) \ + (le)->le_ops->lo_add((sdp), (le)); \ +} \ +while (0) + +#define LO_TRANS_END(sdp, le) \ +do \ +{ \ + if ((le)->le_ops->lo_trans_end) \ + (le)->le_ops->lo_trans_end((sdp), (le)); \ +} \ +while (0) + +#define LO_PRINT(sdp, le, where) \ +do \ +{ \ + if ((le)->le_ops->lo_print) \ + (le)->le_ops->lo_print((sdp), (le), (where)); \ +} \ +while (0) + +static __inline__ struct gfs_trans * +LO_OVERLAP_TRANS(struct gfs_sbd *sdp, struct gfs_log_element *le) +{ + if (le->le_ops->lo_overlap_trans) + return le->le_ops->lo_overlap_trans(sdp, le); + else + return NULL; +} + +#define LO_INCORE_COMMIT(sdp, tr, le) \ +do \ +{ \ + if ((le)->le_ops->lo_incore_commit) \ + (le)->le_ops->lo_incore_commit((sdp), (tr), (le)); \ +} \ +while (0) + +#define LO_ADD_TO_AIL(sdp, le) \ +do \ +{ \ + if ((le)->le_ops->lo_add_to_ail) \ + (le)->le_ops->lo_add_to_ail((sdp), (le)); \ +} \ +while (0) + +#define LO_CLEAN_DUMP(sdp, le) \ +do \ +{ \ + if ((le)->le_ops->lo_clean_dump) \ + (le)->le_ops->lo_clean_dump((sdp), (le)); \ +} \ +while (0) + +#define LO_TRANS_SIZE(sdp, tr, mblks, eblks, blocks, bmem) \ +do \ +{ \ + int __lops_x; \ + for (__lops_x = 0; gfs_log_ops[__lops_x]; __lops_x++) \ + if (gfs_log_ops[__lops_x]->lo_trans_size) \ + gfs_log_ops[__lops_x]->lo_trans_size((sdp), (tr), (mblks), (eblks), (blocks), (bmem)); \ +} \ +while (0) + +#define LO_TRANS_COMBINE(sdp, tr, new_tr) \ +do \ +{ \ + int __lops_x; \ + for (__lops_x = 0; gfs_log_ops[__lops_x]; __lops_x++) \ + if (gfs_log_ops[__lops_x]->lo_trans_combine) \ + gfs_log_ops[__lops_x]->lo_trans_combine((sdp), (tr), (new_tr)); \ +} \ +while (0) + +#define LO_BUILD_BHLIST(sdp, tr) \ +do \ +{ \ + int __lops_x; \ + for (__lops_x = 0; gfs_log_ops[__lops_x]; __lops_x++) \ + if (gfs_log_ops[__lops_x]->lo_build_bhlist) \ + gfs_log_ops[__lops_x]->lo_build_bhlist((sdp), (tr)); \ +} \ +while (0) + +#define LO_DUMP_SIZE(sdp, elements, blocks, bmem) \ +do \ +{ \ + int __lops_x; \ + for (__lops_x = 0; gfs_log_ops[__lops_x]; __lops_x++) \ + if (gfs_log_ops[__lops_x]->lo_dump_size) \ + gfs_log_ops[__lops_x]->lo_dump_size((sdp), (elements), (blocks), (bmem)); \ +} \ +while (0) + +#define LO_BUILD_DUMP(sdp, tr) \ +do \ +{ \ + int __lops_x; \ + for (__lops_x = 0; gfs_log_ops[__lops_x]; __lops_x++) \ + if (gfs_log_ops[__lops_x]->lo_build_dump) \ + gfs_log_ops[__lops_x]->lo_build_dump((sdp), (tr)); \ +} \ +while (0) + +#define LO_BEFORE_SCAN(sdp, jid, head, pass) \ +do \ +{ \ + int __lops_x; \ + for (__lops_x = 0; gfs_log_ops[__lops_x]; __lops_x++) \ + if (gfs_log_ops[__lops_x]->lo_before_scan) \ + gfs_log_ops[__lops_x]->lo_before_scan((sdp), (jid), (head), (pass)); \ +} \ +while (0) + +static __inline__ int +LO_SCAN_ELEMENTS(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, uint64_t start, + struct gfs_log_descriptor *desc, unsigned int pass) +{ + int x; + int error; + + for (x = 0; gfs_log_ops[x]; x++) + if (gfs_log_ops[x]->lo_scan_elements) { + error = gfs_log_ops[x]->lo_scan_elements(sdp, jdesc, gl, + start, desc, pass); + if (error) + return error; + } + + return 0; +} + +#define LO_AFTER_SCAN(sdp, jid, pass) \ +do \ +{ \ + int __lops_x; \ + for (__lops_x = 0; gfs_log_ops[__lops_x]; __lops_x++) \ + if (gfs_log_ops[__lops_x]->lo_after_scan) \ + gfs_log_ops[__lops_x]->lo_after_scan((sdp), (jid), (pass)); \ +} \ +while (0) + +#endif /* __LOPS_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/file.h +++ linux-2.6.28/ubuntu/gfs/file.h @@ -0,0 +1,42 @@ +#ifndef __FILE_DOT_H__ +#define __FILE_DOT_H__ + +typedef int (*read_copy_fn_t) (struct buffer_head *bh, void **buf, + unsigned int offset, unsigned int size); +typedef int (*write_copy_fn_t) (struct gfs_inode *ip, struct buffer_head *bh, + void **buf, unsigned int offset, + unsigned int size, int new); + +int gfs_copy2mem(struct buffer_head *bh, void **buf, + unsigned int offset, unsigned int size); +int gfs_copy2user(struct buffer_head *bh, void **buf, + unsigned int offset, unsigned int size); +int gfs_readi(struct gfs_inode *ip, void *buf, uint64_t offset, + unsigned int size, read_copy_fn_t copy_fn); + +int gfs_copy_from_mem(struct gfs_inode *ip, struct buffer_head *bh, void **buf, + unsigned int offset, unsigned int size, int new); +int gfs_copy_from_user(struct gfs_inode *ip, struct buffer_head *bh, void **buf, + unsigned int offset, unsigned int size, int new); +int gfs_writei(struct gfs_inode *ip, void *buf, uint64_t offset, + unsigned int size, write_copy_fn_t copy_fn, + struct kiocb *iocb); + +int gfs_zero_blocks(struct gfs_inode *ip, struct buffer_head *bh, void **buf, + unsigned int offset, unsigned int size, int new); + +static __inline__ int +gfs_internal_read(struct gfs_inode *ip, char *buf, uint64_t offset, + unsigned int size) +{ + return gfs_readi(ip, buf, offset, size, gfs_copy2mem); +} + +static __inline__ int +gfs_internal_write(struct gfs_inode *ip, char *buf, uint64_t offset, + unsigned int size) +{ + return gfs_writei(ip, buf, offset, size, gfs_copy_from_mem, NULL); +} + +#endif /* __FILE_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/ops_export.h +++ linux-2.6.28/ubuntu/gfs/ops_export.h @@ -0,0 +1,6 @@ +#ifndef __OPS_EXPORT_DOT_H__ +#define __OPS_EXPORT_DOT_H__ + +extern const struct export_operations gfs_export_ops; + +#endif /* __OPS_EXPORT_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/bits.h +++ linux-2.6.28/ubuntu/gfs/bits.h @@ -0,0 +1,18 @@ +#ifndef __BITS_DOT_H__ +#define __BITS_DOT_H__ + +#define BFITNOENT (0xFFFFFFFF) + +void gfs_setbit(struct gfs_rgrpd *rgd, + unsigned char *buffer, unsigned int buflen, + uint32_t block, unsigned char new_state); +unsigned char gfs_testbit(struct gfs_rgrpd *rgd, + unsigned char *buffer, unsigned int buflen, + uint32_t block); +uint32_t gfs_bitfit(unsigned char *buffer, unsigned int buflen, + uint32_t goal, unsigned char old_state); +uint32_t gfs_bitcount(struct gfs_rgrpd *rgd, + unsigned char *buffer, unsigned int buflen, + unsigned char state); + +#endif /* __BITS_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/sys.h +++ linux-2.6.28/ubuntu/gfs/sys.h @@ -0,0 +1,14 @@ +#ifndef __SYS_DOT_H__ +#define __SYS_DOT_H__ + +/* Allow args to be passed to GFS when using an initial ram disk */ +extern char *gfs_sys_margs; +extern spinlock_t gfs_sys_margs_lock; + +int gfs_sys_fs_add(struct gfs_sbd *sdp); +void gfs_sys_fs_del(struct gfs_sbd *sdp); + +int gfs_sys_init(void); +void gfs_sys_uninit(void); + +#endif /* __SYS_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/ops_file.c +++ linux-2.6.28/ubuntu/gfs/ops_file.c @@ -0,0 +1,1820 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs_ioctl.h" +#include "gfs.h" +#include "bmap.h" +#include "dio.h" +#include "dir.h" +#include "file.h" +#include "glock.h" +#include "glops.h" +#include "inode.h" +#include "ioctl.h" +#include "lm.h" +#include "log.h" +#include "ops_file.h" +#include "ops_vm.h" +#include "quota.h" +#include "rgrp.h" +#include "trans.h" + +/* "bad" is for NFS support */ +struct filldir_bad_entry { + char *fbe_name; + unsigned int fbe_length; + uint64_t fbe_offset; + struct gfs_inum fbe_inum; + unsigned int fbe_type; +}; + +struct filldir_bad { + struct gfs_sbd *fdb_sbd; + + struct filldir_bad_entry *fdb_entry; + unsigned int fdb_entry_num; + unsigned int fdb_entry_off; + + char *fdb_name; + unsigned int fdb_name_size; + unsigned int fdb_name_off; +}; + +/* For regular, non-NFS */ +struct filldir_reg { + struct gfs_sbd *fdr_sbd; + int fdr_prefetch; + + filldir_t fdr_filldir; + void *fdr_opaque; +}; + +typedef ssize_t(*do_rw_t) (struct file * file, + char *buf, + size_t size, loff_t * offset, + struct kiocb *iocb, + unsigned int num_gh, struct gfs_holder * ghs); + +/** + * gfs_llseek - seek to a location in a file + * @file: the file + * @offset: the offset + * @origin: Where to seek from (SEEK_SET, SEEK_CUR, or SEEK_END) + * + * SEEK_END requires the glock for the file because it references the + * file's size. + * + * Returns: The new offset, or errno + */ + +static loff_t +gfs_llseek(struct file *file, loff_t offset, int origin) +{ + struct gfs_inode *ip = get_v2ip(file->f_mapping->host); + struct gfs_holder i_gh; + loff_t error; + + atomic_inc(&ip->i_sbd->sd_ops_file); + + if (origin == 2) { + error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); + if (!error) { + error = generic_file_llseek_unlocked(file, offset, origin); + gfs_glock_dq_uninit(&i_gh); + } + } else + error = generic_file_llseek_unlocked(file, offset, origin); + + return error; +} + +#define vma2state(vma) \ +((((vma)->vm_flags & (VM_MAYWRITE | VM_MAYSHARE)) == \ + (VM_MAYWRITE | VM_MAYSHARE)) ? \ + LM_ST_EXCLUSIVE : LM_ST_SHARED) \ + +/** + * functionname - summary + * @param1: description + * @param2: description + * @param3: description + * + * Function description + * + * Returns: what is returned + */ + +static ssize_t +walk_vm_hard(struct file *file, char *buf, size_t size, loff_t *offset, + struct kiocb *iocb, do_rw_t operation) +{ + struct gfs_holder *ghs; + unsigned int num_gh = 0; + ssize_t count; + + { + struct super_block *sb = file->f_dentry->d_inode->i_sb; + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + unsigned long start = (unsigned long)buf; + unsigned long end = start + size; + int dumping = (current->flags & PF_DUMPCORE); + unsigned int x = 0; + + for (vma = find_vma(mm, start); vma; vma = vma->vm_next) { + if (end <= vma->vm_start) + break; + if (vma->vm_file && + vma->vm_file->f_dentry->d_inode->i_sb == sb) { + num_gh++; + } + } + + ghs = kmalloc((num_gh + 1) * sizeof(struct gfs_holder), GFP_KERNEL); + if (!ghs) { + if (!dumping) + up_read(&mm->mmap_sem); + return -ENOMEM; + } + + for (vma = find_vma(mm, start); vma; vma = vma->vm_next) { + if (end <= vma->vm_start) + break; + if (vma->vm_file) { + struct inode *inode = vma->vm_file->f_dentry->d_inode; + if (inode->i_sb == sb) + gfs_holder_init(get_v2ip(inode)->i_gl, + vma2state(vma), + 0, &ghs[x++]); + } + } + + if (!dumping) + up_read(&mm->mmap_sem); + + gfs_assert(get_v2sdp(sb), x == num_gh,); + } + + count = operation(file, buf, size, offset, iocb, num_gh, ghs); + + while (num_gh--) + gfs_holder_uninit(&ghs[num_gh]); + kfree(ghs); + + return count; +} + +/** + * walk_vm - Walk the vmas associated with a buffer for read or write. + * If any of them are gfs, pass the gfs inode down to the read/write + * worker function so that locks can be acquired in the correct order. + * @file: The file to read/write from/to + * @buf: The buffer to copy to/from + * @size: The amount of data requested + * @offset: The current file offset + * @operation: The read or write worker function + * + * Outputs: Offset - updated according to number of bytes written + * + * Returns: The number of bytes written, errno on failure + */ + +static ssize_t +walk_vm(struct file *file, char *buf, size_t size, loff_t *offset, + struct kiocb *iocb, + do_rw_t operation) +{ + if (current->mm) { + struct super_block *sb = file->f_dentry->d_inode->i_sb; + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + unsigned long start = (unsigned long)buf; + unsigned long end = start + size; + int dumping = (current->flags & PF_DUMPCORE); + + if (!dumping) + down_read(&mm->mmap_sem); + + for (vma = find_vma(mm, start); vma; vma = vma->vm_next) { + if (end <= vma->vm_start) + break; + if (vma->vm_file && + vma->vm_file->f_dentry->d_inode->i_sb == sb) + goto do_locks; + } + + if (!dumping) + up_read(&mm->mmap_sem); + } + + { + struct gfs_holder gh; + return operation(file, buf, size, offset, iocb, 0, &gh); + } + + do_locks: + return walk_vm_hard(file, buf, size, offset, iocb, operation); +} + +/** + * functionname - summary + * @param1: description + * @param2: description + * @param3: description + * + * Function description + * + * Returns: what is returned + */ + +static ssize_t +do_read_readi(struct file *file, char *buf, size_t size, loff_t *offset, + struct kiocb *iocb) +{ + struct gfs_inode *ip = get_v2ip(file->f_mapping->host); + ssize_t count = 0; + + if (*offset < 0) + return -EINVAL; + if (!access_ok(VERIFY_WRITE, buf, size)) + return -EFAULT; + + if (!(file->f_flags & O_LARGEFILE)) { + if (*offset >= 0x7FFFFFFFull) + return -EFBIG; + if (*offset + size > 0x7FFFFFFFull) + size = 0x7FFFFFFFull - *offset; + } + + /* ToDo: not sure about iocb .. wcheng + */ + count = gfs_readi(ip, buf, *offset, size, gfs_copy2user); + + if (count > 0) + *offset += count; + + return count; +} + +/** + * do_read_direct - Read bytes from a file + * @file: The file to read from + * @buf: The buffer to copy into + * @size: The amount of data requested + * @offset: The current file offset + * @num_gh: The number of other locks we need to do the read + * @ghs: the locks we need plus one for our lock + * + * Outputs: Offset - updated according to number of bytes read + * + * Returns: The number of bytes read, errno on failure + */ + +static ssize_t +do_read_direct(struct file *file, char *buf, size_t size, loff_t *offset, + struct kiocb *iocb, + unsigned int num_gh, struct gfs_holder *ghs) +{ + struct inode *inode = file->f_mapping->host; + struct gfs_inode *ip = get_v2ip(inode); + unsigned int state = LM_ST_DEFERRED; + int flags = 0; + unsigned int x; + ssize_t count = 0; + int error; + + for (x = 0; x < num_gh; x++) + if (ghs[x].gh_gl == ip->i_gl) { + state = LM_ST_SHARED; + flags |= GL_LOCAL_EXCL; + break; + } + + gfs_holder_init(ip->i_gl, state, flags, &ghs[num_gh]); + + error = gfs_glock_nq_m(num_gh + 1, ghs); + if (error) + goto out; + + error = -EINVAL; + if (gfs_is_jdata(ip)) + goto out_gunlock; + + if (gfs_is_stuffed(ip)) { + size_t mask = bdev_hardsect_size(inode->i_sb->s_bdev) - 1; + + if (((*offset) & mask) || (((unsigned long)buf) & mask)) + goto out_gunlock; + + count = do_read_readi(file, buf, size & ~mask, offset, iocb); + } + else { + if (!iocb) + count = do_sync_read(file, buf, size, offset); + else { + struct iovec local_iov = { .iov_base = buf, .iov_len = size}; + + count = generic_file_aio_read(iocb, &local_iov, 1, *offset); + iocb->ki_pos = *offset; + } + } + + error = 0; + + out_gunlock: + gfs_glock_dq_m(num_gh + 1, ghs); + + out: + gfs_holder_uninit(&ghs[num_gh]); + + return (count) ? count : error; +} + +/** + * do_read_buf - Read bytes from a file + * @file: The file to read from + * @buf: The buffer to copy into + * @size: The amount of data requested + * @offset: The current file offset + * @num_gh: The number of other locks we need to do the read + * @ghs: the locks we need plus one for our lock + * + * Outputs: Offset - updated according to number of bytes read + * + * Returns: The number of bytes read, errno on failure + */ + +static ssize_t +do_read_buf(struct file *file, char *buf, size_t size, loff_t *offset, + struct kiocb *iocb, + unsigned int num_gh, struct gfs_holder *ghs) +{ + struct gfs_inode *ip = get_v2ip(file->f_mapping->host); + ssize_t count = 0; + int error; + + gfs_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &ghs[num_gh]); + + error = gfs_glock_nq_m_atime(num_gh + 1, ghs); + if (error) + goto out; + + if (gfs_is_jdata(ip) || + (gfs_is_stuffed(ip) && !test_bit(GIF_PAGED, &ip->i_flags))) + count = do_read_readi(file, buf, size, offset, iocb); + else { + if (!iocb) { + count = do_sync_read(file, buf, size, offset); + } else { + struct iovec local_iov = { .iov_base = buf, .iov_len = size}; + + count = generic_file_aio_read(iocb, &local_iov, 1, *offset); + iocb->ki_pos = *offset; + } + } + + gfs_glock_dq_m(num_gh + 1, ghs); + + out: + gfs_holder_uninit(&ghs[num_gh]); + + return (count) ? count : error; +} + +static ssize_t +__gfs_read(struct file *file, char *buf, size_t size, loff_t *offset, struct kiocb *iocb) +{ + atomic_inc(&get_v2sdp(file->f_mapping->host->i_sb)->sd_ops_file); + + if (file->f_flags & O_DIRECT) + return walk_vm(file, buf, size, offset, iocb, do_read_direct); + else + return walk_vm(file, buf, size, offset, iocb, do_read_buf); +} + +/** + * gfs_read - Read bytes from a file + * @file: The file to read from + * @buf: The buffer to copy into + * @size: The amount of data requested + * @offset: The current file offset + * + * Outputs: Offset - updated according to number of bytes read + * + * Returns: The number of bytes read, errno on failure + */ + +static ssize_t +gfs_read(struct file *file, char *buf, size_t size, loff_t *offset) +{ + return(__gfs_read(file, buf, size, offset, NULL)); +} + +/* + * gfs_aio_read: match with vfs generic_file_aio_read as: + * (struct kiocb *iocb, char __user *buf, size_t count, loff_t pos) + */ +static ssize_t +gfs_aio_read(struct kiocb *iocb, const struct iovec *iov, unsigned long count, + loff_t pos) +{ + struct file *filp = iocb->ki_filp; + + BUG_ON(iocb->ki_pos != pos); + return(__gfs_read(filp, iov->iov_base, iov->iov_len, &iocb->ki_pos, iocb)); +} + +/** + * grope_mapping - feel up a mapping that needs to be written + * @buf: the start of the memory to be written + * @size: the size of the memory to be written + * + * We do this after acquiring the locks on the mapping, + * but before starting the write transaction. We need to make + * sure that we don't cause recursive transactions if blocks + * need to be allocated to the file backing the mapping. + * + * Returns: errno + */ + +static int +grope_mapping(char *buf, size_t size) +{ + unsigned long start = (unsigned long)buf; + unsigned long stop = start + size; + char c; + + while (start < stop) { + if (copy_from_user(&c, (char *)start, 1)) + return -EFAULT; + + start += PAGE_CACHE_SIZE; + start &= PAGE_CACHE_MASK; + } + + return 0; +} + +/** + * gfs_file_aio_write_nolock - Call vfs aio layer to write bytes to a file + * @file: The file to write to + * @buf: The buffer to copy from + * @size: The amount of data requested + * @offset: The offset in the file to write + * @iocb: The io control block. If NULL, a temporary one will be used. + * + * Returns: The number of bytes written, errno on failure + */ +static ssize_t +gfs_file_aio_write_nolock(struct file *file, char *buf, size_t size, + loff_t *offset, struct kiocb *iocb) +{ + struct iovec local_iov = { .iov_base = buf, .iov_len = size }; + struct kiocb local_iocb, *kiocb = NULL; + ssize_t count; + + if (!iocb) { + init_sync_kiocb(&local_iocb, file); + local_iocb.ki_nr_segs = 1; + kiocb = &local_iocb; + } + else + kiocb = iocb; + + kiocb->ki_pos = *offset; + count = generic_file_aio_write_nolock(kiocb, &local_iov, kiocb->ki_nr_segs, + kiocb->ki_pos); + *offset = kiocb->ki_pos; + if (kiocb == &local_iocb && count == -EIOCBQUEUED) + count = wait_on_sync_kiocb(kiocb); + return count; +} + +/** + * do_write_direct_alloc - Write bytes to a file + * @file: The file to write to + * @buf: The buffer to copy from + * @size: The amount of data requested + * @offset: The current file offset + * + * Outputs: Offset - updated according to number of bytes written + * + * Returns: The number of bytes written, errno on failure + */ + +static ssize_t +do_write_direct_alloc(struct file *file, char *buf, size_t size, loff_t *offset, + struct kiocb *iocb) +{ + struct inode *inode = file->f_mapping->host; + struct gfs_inode *ip = get_v2ip(inode); + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al = NULL; + struct buffer_head *dibh; + unsigned int data_blocks, ind_blocks; + ssize_t count; + int error; + + gfs_write_calc_reserv(ip, size, &data_blocks, &ind_blocks); + + al = gfs_alloc_get(ip); + + error = gfs_quota_lock_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + if (error) + goto fail; + + error = gfs_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); + if (error) + goto fail_gunlock_q; + + al->al_requested_meta = ind_blocks; + al->al_requested_data = data_blocks; + + error = gfs_inplace_reserve(ip); + if (error) + goto fail_gunlock_q; + + /* Trans may require: + All blocks for a RG bitmap, whatever indirect blocks we + need, a modified dinode, and a quota change. */ + + error = gfs_trans_begin(sdp, + 1 + al->al_rgd->rd_ri.ri_length + ind_blocks, + 1); + if (error) + goto fail_ipres; + + if ((ip->i_di.di_mode & (S_ISUID | S_ISGID)) && !capable(CAP_FSETID)) { + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto fail_end_trans; + + ip->i_di.di_mode &= (ip->i_di.di_mode & S_IXGRP) ? (~(S_ISUID | S_ISGID)) : (~S_ISUID); + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + + if (gfs_is_stuffed(ip)) { error = gfs_unstuff_dinode(ip, gfs_unstuffer_sync, NULL); if (error) + goto fail_end_trans; + } + + count = gfs_file_aio_write_nolock(file, buf, size, offset, iocb); + if (count < 0) { + error = count; + goto fail_end_trans; + } + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto fail_end_trans; + + if (ip->i_di.di_size < inode->i_size) + ip->i_di.di_size = inode->i_size; + ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + + gfs_trans_end(sdp); + + /* Question (wcheng) + * 1. should IS_SYNC flush glock ? + * 2. does gfs_log_flush_glock flush data ? + */ + if (file->f_flags & O_SYNC) + gfs_log_flush_glock(ip->i_gl); + + gfs_inplace_release(ip); + gfs_quota_unlock_m(ip); + gfs_alloc_put(ip); + + if (file->f_mapping->nrpages) { + error = filemap_fdatawrite(file->f_mapping); + if (!error) + error = filemap_fdatawait(file->f_mapping); + } + if (error) + return error; + + return count; + + fail_end_trans: + gfs_trans_end(sdp); + + fail_ipres: + gfs_inplace_release(ip); + + fail_gunlock_q: + gfs_quota_unlock_m(ip); + + fail: + gfs_alloc_put(ip); + + return error; +} + +/** + * do_write_direct - Write bytes to a file + * @file: The file to write to + * @buf: The buffer to copy from + * @size: The amount of data requested + * @offset: The current file offset + * @num_gh: The number of other locks we need to do the read + * @gh: the locks we need plus one for our lock + * + * Outputs: Offset - updated according to number of bytes written + * + * Returns: The number of bytes written, errno on failure + */ + +static ssize_t +do_write_direct(struct file *file, char *buf, size_t size, loff_t *offset, + struct kiocb *iocb, + unsigned int num_gh, struct gfs_holder *ghs) +{ + struct gfs_inode *ip = get_v2ip(file->f_mapping->host); + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_file *fp = get_v2fp(file); + unsigned int state = LM_ST_DEFERRED; + int alloc_required; + unsigned int x; + size_t s; + ssize_t count = 0; + int error; + + if (test_bit(GFF_DID_DIRECT_ALLOC, &fp->f_flags)) + state = LM_ST_EXCLUSIVE; + else + for (x = 0; x < num_gh; x++) + if (ghs[x].gh_gl == ip->i_gl) { + state = LM_ST_EXCLUSIVE; + break; + } + + restart: + gfs_holder_init(ip->i_gl, state, 0, &ghs[num_gh]); + + error = gfs_glock_nq_m(num_gh + 1, ghs); + if (error) + goto out; + + error = -EINVAL; + if (gfs_is_jdata(ip)) + goto out_gunlock; + + if (num_gh) { + error = grope_mapping(buf, size); + if (error) + goto out_gunlock; + } + + if (file->f_flags & O_APPEND) + *offset = ip->i_di.di_size; + + if (!(file->f_flags & O_LARGEFILE)) { + error = -EFBIG; + if (*offset >= 0x7FFFFFFFull) + goto out_gunlock; + if (*offset + size > 0x7FFFFFFFull) + size = 0x7FFFFFFFull - *offset; + } + + if (gfs_is_stuffed(ip) || + *offset + size > ip->i_di.di_size || + ((ip->i_di.di_mode & (S_ISUID | S_ISGID)) && !capable(CAP_FSETID))) + alloc_required = TRUE; + else { + error = gfs_write_alloc_required(ip, *offset, size, + &alloc_required); + if (error) + goto out_gunlock; + } + + if (alloc_required && state != LM_ST_EXCLUSIVE) { + gfs_glock_dq_m(num_gh + 1, ghs); + gfs_holder_uninit(&ghs[num_gh]); + state = LM_ST_EXCLUSIVE; + goto restart; + } + + if (alloc_required) { + set_bit(GFF_DID_DIRECT_ALLOC, &fp->f_flags); + + /* for asynchronous IO, the buffer can not be splitted */ + if (iocb) { + count = do_write_direct_alloc(file, buf, size, offset, iocb); + goto out_iocb_write; + } + + /* split large writes into smaller atomic transactions */ + while (size) { + s = gfs_tune_get(sdp, gt_max_atomic_write); + if (s > size) + s = size; + + error = do_write_direct_alloc(file, buf, s, offset, iocb); + if (error < 0) + goto out_gunlock; + + buf += error; + size -= error; + count += error; + } + } else { + struct gfs_holder t_gh; + + clear_bit(GFF_DID_DIRECT_ALLOC, &fp->f_flags); + + error = gfs_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, 0, &t_gh); + if (error) + goto out_gunlock; + + /* Todo: It would be nice if init_sync_kiocb is exported. + * .. wcheng + */ + count = gfs_file_aio_write_nolock(file, buf, size, offset, iocb); + gfs_glock_dq_uninit(&t_gh); + } + +out_iocb_write: + error = 0; + +out_gunlock: + gfs_glock_dq_m(num_gh + 1, ghs); + +out: + gfs_holder_uninit(&ghs[num_gh]); + + return (count) ? count : error; +} + +/** + * do_do_write_buf - Write bytes to a file + * @file: The file to write to + * @buf: The buffer to copy from + * @size: The amount of data requested + * @offset: The current file offset + * + * Outputs: Offset - updated according to number of bytes written + * + * Returns: The number of bytes written, errno on failure + */ + +static ssize_t +do_do_write_buf(struct file *file, char *buf, size_t size, loff_t *offset, + struct kiocb *iocb) +{ + struct inode *inode = file->f_mapping->host; + struct gfs_inode *ip = get_v2ip(inode); + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al = NULL; + struct buffer_head *dibh; + unsigned int data_blocks, ind_blocks; + int alloc_required, journaled; + ssize_t count; + int error; + + journaled = gfs_is_jdata(ip); + + gfs_write_calc_reserv(ip, size, &data_blocks, &ind_blocks); + + error = gfs_write_alloc_required(ip, *offset, size, &alloc_required); + if (error) + return error; + + if (alloc_required) { + al = gfs_alloc_get(ip); + + error = gfs_quota_lock_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + if (error) + goto fail; + + error = gfs_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); + if (error) + goto fail_gunlock_q; + + if (journaled) + al->al_requested_meta = ind_blocks + data_blocks; + else { + al->al_requested_meta = ind_blocks; + al->al_requested_data = data_blocks; + } + + error = gfs_inplace_reserve(ip); + if (error) + goto fail_gunlock_q; + + /* Trans may require: + All blocks for a RG bitmap, whatever indirect blocks we + need, a modified dinode, and a quota change. */ + + error = gfs_trans_begin(sdp, + 1 + al->al_rgd->rd_ri.ri_length + + ind_blocks + + ((journaled) ? data_blocks : 0), 1); + if (error) + goto fail_ipres; + } else { + /* Trans may require: + A modified dinode. */ + + error = gfs_trans_begin(sdp, + 1 + ((journaled) ? data_blocks : 0), 0); + if (error) + goto fail_ipres; + } + + if ((ip->i_di.di_mode & (S_ISUID | S_ISGID)) && !capable(CAP_FSETID)) { + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto fail_end_trans; + + ip->i_di.di_mode &= (ip->i_di.di_mode & S_IXGRP) ? (~(S_ISUID | S_ISGID)) : (~S_ISUID); + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + + if (journaled || + (gfs_is_stuffed(ip) && !test_bit(GIF_PAGED, &ip->i_flags) && + *offset + size <= sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode))) { + + count = gfs_writei(ip, buf, *offset, size, gfs_copy_from_user, iocb); + if (count < 0) { + error = count; + goto fail_end_trans; + } + if (gfs_is_stuffed(ip)){ + struct page *page; + page = find_get_page(file->f_mapping, 0); + if (page) { + ClearPageUptodate(page); + page_cache_release(page); + } + } + *offset += count; + } else { + count = gfs_file_aio_write_nolock(file, buf, size, offset, iocb); + if (count < 0) { + error = count; + goto fail_end_trans; + } + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto fail_end_trans; + + if (ip->i_di.di_size < inode->i_size) + ip->i_di.di_size = inode->i_size; + ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + + gfs_trans_end(sdp); + + if (file->f_flags & O_SYNC || IS_SYNC(inode)) { + gfs_log_flush_glock(ip->i_gl); + error = filemap_fdatawrite(file->f_mapping); + if (error == 0) + error = filemap_fdatawait(file->f_mapping); + if (error) + goto fail_ipres; + } + + if (alloc_required) { + gfs_assert_warn(sdp, count != size || + al->al_alloced_meta || + al->al_alloced_data); + gfs_inplace_release(ip); + gfs_quota_unlock_m(ip); + gfs_alloc_put(ip); + } + + return count; + + fail_end_trans: + gfs_trans_end(sdp); + + fail_ipres: + if (alloc_required) + gfs_inplace_release(ip); + + fail_gunlock_q: + if (alloc_required) + gfs_quota_unlock_m(ip); + + fail: + if (alloc_required) + gfs_alloc_put(ip); + + return error; +} + +/** + * do_write_buf - Write bytes to a file + * @file: The file to write to + * @buf: The buffer to copy from + * @size: The amount of data requested + * @offset: The current file offset + * @num_gh: The number of other locks we need to do the read + * @gh: the locks we need plus one for our lock + * + * Outputs: Offset - updated according to number of bytes written + * + * Returns: The number of bytes written, errno on failure + */ + +static ssize_t +do_write_buf(struct file *file, + char *buf, size_t size, loff_t *offset, + struct kiocb *iocb, + unsigned int num_gh, struct gfs_holder *ghs) +{ + struct gfs_inode *ip = get_v2ip(file->f_mapping->host); + struct gfs_sbd *sdp = ip->i_sbd; + size_t s; + ssize_t count = 0; + int error; + + gfs_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[num_gh]); + + error = gfs_glock_nq_m(num_gh + 1, ghs); + if (error) + goto out; + + if (num_gh) { + error = grope_mapping(buf, size); + if (error) + goto out_gunlock; + } + + if (file->f_flags & O_APPEND) + *offset = ip->i_di.di_size; + + if (!(file->f_flags & O_LARGEFILE)) { + error = -EFBIG; + if (*offset >= 0x7FFFFFFFull) + goto out_gunlock; + if (*offset + size > 0x7FFFFFFFull) + size = 0x7FFFFFFFull - *offset; + } + + /* split large writes into smaller atomic transactions */ + while (size) { + s = gfs_tune_get(sdp, gt_max_atomic_write); + if (s > size) + s = size; + + error = do_do_write_buf(file, buf, s, offset, iocb); + if (error < 0) + goto out_gunlock; + + buf += error; + size -= error; + count += error; + } + + error = 0; + + out_gunlock: + gfs_glock_dq_m(num_gh + 1, ghs); + + out: + gfs_holder_uninit(&ghs[num_gh]); + + return (count) ? count : error; +} + +/** + * gfs_write - Write bytes to a file + * @file: The file to write to + * @buf: The buffer to copy from + * @size: The amount of data requested + * @offset: The current file offset + * + * Outputs: Offset - updated according to number of bytes written + * + * Returns: The number of bytes written, errno on failure + */ + +static ssize_t +__gfs_write(struct file *file, const char *buf, size_t size, loff_t *offset, struct kiocb *iocb) +{ + struct inode *inode = file->f_mapping->host; + ssize_t count; + + atomic_inc(&get_v2sdp(inode->i_sb)->sd_ops_file); + + if (*offset < 0) + return -EINVAL; + if (!access_ok(VERIFY_READ, buf, size)) + return -EFAULT; + + mutex_lock(&inode->i_mutex); + if (file->f_flags & O_DIRECT) + count = walk_vm(file, (char *)buf, size, offset, iocb, do_write_direct); + else + count = walk_vm(file, (char *)buf, size, offset, iocb, do_write_buf); + mutex_unlock(&inode->i_mutex); + + return count; +} + +static ssize_t +gfs_write(struct file *file, const char *buf, size_t size, loff_t *offset) +{ + return(__gfs_write(file, buf, size, offset, NULL)); +} + +static ssize_t +gfs_aio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long segs, + loff_t pos) +{ + struct file *file = iocb->ki_filp; + + BUG_ON(iocb->ki_pos != pos); + + return(__gfs_write(file, iov->iov_base, iov->iov_len, &iocb->ki_pos, + iocb)); +} + +/** + * filldir_reg_func - Report a directory entry to the caller of gfs_dir_read() + * @opaque: opaque data used by the function + * @name: the name of the directory entry + * @length: the length of the name + * @offset: the entry's offset in the directory + * @inum: the inode number the entry points to + * @type: the type of inode the entry points to + * + * Returns: 0 on success, 1 if buffer full + */ + +static int +filldir_reg_func(void *opaque, + const char *name, unsigned int length, + uint64_t offset, + struct gfs_inum *inum, unsigned int type) +{ + struct filldir_reg *fdr = (struct filldir_reg *)opaque; + struct gfs_sbd *sdp = fdr->fdr_sbd; + unsigned int vfs_type; + int error; + + switch (type) { + case GFS_FILE_NON: + vfs_type = DT_UNKNOWN; + break; + case GFS_FILE_REG: + vfs_type = DT_REG; + break; + case GFS_FILE_DIR: + vfs_type = DT_DIR; + break; + case GFS_FILE_LNK: + vfs_type = DT_LNK; + break; + case GFS_FILE_BLK: + vfs_type = DT_BLK; + break; + case GFS_FILE_CHR: + vfs_type = DT_CHR; + break; + case GFS_FILE_FIFO: + vfs_type = DT_FIFO; + break; + case GFS_FILE_SOCK: + vfs_type = DT_SOCK; + break; + default: + if (gfs_consist(sdp)) + printk("GFS: fsid=%s: type = %u\n", + sdp->sd_fsname, type); + return -EIO; + } + + error = fdr->fdr_filldir(fdr->fdr_opaque, name, length, offset, + inum->no_formal_ino, vfs_type); + if (error) + return 1; + + /* Prefetch locks */ + if (fdr->fdr_prefetch && !(length == 1 && *name == '.')) { + gfs_glock_prefetch_num(sdp, + inum->no_formal_ino, &gfs_inode_glops, + LM_ST_SHARED, LM_FLAG_TRY | LM_FLAG_ANY); + gfs_glock_prefetch_num(sdp, + inum->no_addr, &gfs_iopen_glops, + LM_ST_SHARED, LM_FLAG_TRY); + } + + return 0; +} + +/** + * readdir_reg - Read directory entries from a directory + * @file: The directory to read from + * @dirent: Buffer for dirents + * @filldir: Function used to do the copying + * + * Returns: errno + */ + +static int +readdir_reg(struct file *file, void *dirent, filldir_t filldir) +{ + struct gfs_inode *dip = get_v2ip(file->f_mapping->host); + struct filldir_reg fdr; + struct gfs_holder d_gh; + uint64_t offset = file->f_pos; + int error; + + fdr.fdr_sbd = dip->i_sbd; + fdr.fdr_prefetch = TRUE; + fdr.fdr_filldir = filldir; + fdr.fdr_opaque = dirent; + + gfs_holder_init(dip->i_gl, LM_ST_SHARED, GL_ATIME, &d_gh); + error = gfs_glock_nq_atime(&d_gh); + if (error) { + gfs_holder_uninit(&d_gh); + return error; + } + + error = gfs_dir_read(dip, &offset, &fdr, filldir_reg_func); + + gfs_glock_dq_uninit(&d_gh); + + file->f_pos = offset; + + return error; +} + +/** + * filldir_bad_func - Report a directory entry to the caller of gfs_dir_read() + * @opaque: opaque data used by the function + * @name: the name of the directory entry + * @length: the length of the name + * @offset: the entry's offset in the directory + * @inum: the inode number the entry points to + * @type: the type of inode the entry points to + * + * For supporting NFS. + * + * Returns: 0 on success, 1 if buffer full + */ + +static int +filldir_bad_func(void *opaque, + const char *name, unsigned int length, + uint64_t offset, + struct gfs_inum *inum, unsigned int type) +{ + struct filldir_bad *fdb = (struct filldir_bad *)opaque; + struct gfs_sbd *sdp = fdb->fdb_sbd; + struct filldir_bad_entry *fbe; + + if (fdb->fdb_entry_off == fdb->fdb_entry_num || + fdb->fdb_name_off + length > fdb->fdb_name_size) + return 1; + + fbe = &fdb->fdb_entry[fdb->fdb_entry_off]; + fbe->fbe_name = fdb->fdb_name + fdb->fdb_name_off; + memcpy(fbe->fbe_name, name, length); + fbe->fbe_length = length; + fbe->fbe_offset = offset; + fbe->fbe_inum = *inum; + fbe->fbe_type = type; + + fdb->fdb_entry_off++; + fdb->fdb_name_off += length; + + /* Prefetch locks */ + if (!(length == 1 && *name == '.')) { + gfs_glock_prefetch_num(sdp, + inum->no_formal_ino, &gfs_inode_glops, + LM_ST_SHARED, LM_FLAG_TRY | LM_FLAG_ANY); + gfs_glock_prefetch_num(sdp, + inum->no_addr, &gfs_iopen_glops, + LM_ST_SHARED, LM_FLAG_TRY); + } + + return 0; +} + +/** + * readdir_bad - Read directory entries from a directory + * @file: The directory to read from + * @dirent: Buffer for dirents + * @filldir: Function used to do the copying + * + * For supporting NFS. + * + * Returns: errno + */ + +static int +readdir_bad(struct file *file, void *dirent, filldir_t filldir) +{ + struct gfs_inode *dip = get_v2ip(file->f_mapping->host); + struct gfs_sbd *sdp = dip->i_sbd; + struct filldir_reg fdr; + unsigned int entries, size; + struct filldir_bad *fdb; + struct gfs_holder d_gh; + uint64_t offset = file->f_pos; + unsigned int x; + struct filldir_bad_entry *fbe; + int error; + + entries = gfs_tune_get(sdp, gt_entries_per_readdir); + size = sizeof(struct filldir_bad) + + entries * (sizeof(struct filldir_bad_entry) + GFS_FAST_NAME_SIZE); + + fdb = kmalloc(size, GFP_KERNEL); + if (!fdb) + return -ENOMEM; + memset(fdb, 0, size); + + fdb->fdb_sbd = sdp; + fdb->fdb_entry = (struct filldir_bad_entry *)(fdb + 1); + fdb->fdb_entry_num = entries; + fdb->fdb_name = ((char *)fdb) + sizeof(struct filldir_bad) + + entries * sizeof(struct filldir_bad_entry); + fdb->fdb_name_size = entries * GFS_FAST_NAME_SIZE; + + gfs_holder_init(dip->i_gl, LM_ST_SHARED, GL_ATIME, &d_gh); + error = gfs_glock_nq_atime(&d_gh); + if (error) { + gfs_holder_uninit(&d_gh); + goto out; + } + + error = gfs_dir_read(dip, &offset, fdb, filldir_bad_func); + + gfs_glock_dq_uninit(&d_gh); + + fdr.fdr_sbd = sdp; + fdr.fdr_prefetch = FALSE; + fdr.fdr_filldir = filldir; + fdr.fdr_opaque = dirent; + + for (x = 0; x < fdb->fdb_entry_off; x++) { + fbe = &fdb->fdb_entry[x]; + + error = filldir_reg_func(&fdr, + fbe->fbe_name, fbe->fbe_length, + fbe->fbe_offset, + &fbe->fbe_inum, fbe->fbe_type); + if (error) { + file->f_pos = fbe->fbe_offset; + error = 0; + goto out; + } + } + + file->f_pos = offset; + + out: + kfree(fdb); + + return error; +} + +/** + * gfs_readdir - Read directory entries from a directory + * @file: The directory to read from + * @dirent: Buffer for dirents + * @filldir: Function used to do the copying + * + * Returns: errno + */ + +static int +gfs_readdir(struct file *file, void *dirent, filldir_t filldir) +{ + int error; + + atomic_inc(&get_v2sdp(file->f_mapping->host->i_sb)->sd_ops_file); + + /* Use "bad" one if we're called from NFS daemon */ + if (strcmp(current->comm, "nfsd") != 0) + error = readdir_reg(file, dirent, filldir); + else + error = readdir_bad(file, dirent, filldir); + + return error; +} + +/** + * gfs_ioctl - do an ioctl on a file + * @inode: the inode + * @file: the file pointer + * @cmd: the ioctl command + * @arg: the argument + * + * Returns: errno + */ + +static int +gfs_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct gfs_inode *ip = get_v2ip(inode); + + atomic_inc(&ip->i_sbd->sd_ops_file); + + switch (cmd) { + case GFS_IOCTL_IDENTIFY: { + unsigned int x = GFS_MAGIC; + if (copy_to_user((unsigned int *)arg, &x, sizeof(unsigned int))) + return -EFAULT; + return 0; + } + + case GFS_IOCTL_SUPER: + return gfs_ioctl_i(ip, (void *)arg); + + default: + return -ENOTTY; + } +} + +#ifdef CONFIG_COMPAT +/** + * gfs_compat_ioctl - do an ioctl on a file - compatible between 32-64 bit + * @inode: the inode + * @file: the file pointer + * @cmd: the ioctl command + * @arg: the argument + * + * Returns: errno + */ + +static long +gfs_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg) +{ + struct gfs_inode *ip = get_v2ip(file->f_mapping->host); + + atomic_inc(&ip->i_sbd->sd_ops_file); + + switch (cmd) { + case GFS_IOCTL_IDENTIFY: { + unsigned int x = GFS_MAGIC; + if (copy_to_user((unsigned int *)arg, &x, sizeof(unsigned int))) + return -EFAULT; + return 0; + } + + case GFS_IOCTL_SUPER: + return gfs_ioctl_i_compat(ip, arg); + + default: + return -ENOTTY; + } +} +#endif + +/** + * gfs_mmap - We don't support shared writable mappings right now + * @file: The file to map + * @vma: The VMA which described the mapping + * + * Returns: 0 or error code + */ + +static int +gfs_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct gfs_inode *ip = get_v2ip(file->f_mapping->host); + struct gfs_holder i_gh; + int error; + + atomic_inc(&ip->i_sbd->sd_ops_file); + + gfs_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &i_gh); + error = gfs_glock_nq_atime(&i_gh); + if (error) { + gfs_holder_uninit(&i_gh); + return error; + } + + if (gfs_is_jdata(ip)) { + if (vma->vm_flags & VM_MAYSHARE) + error = -ENOSYS; + else + vma->vm_ops = &gfs_vm_ops_private; + } else { + /* This is VM_MAYWRITE instead of VM_WRITE because a call + to mprotect() can turn on VM_WRITE later. */ + + if ((vma->vm_flags & (VM_MAYSHARE | VM_MAYWRITE)) == (VM_MAYSHARE | VM_MAYWRITE)) + vma->vm_ops = &gfs_vm_ops_sharewrite; + else + vma->vm_ops = &gfs_vm_ops_private; + } + + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gfs_open - open a file + * @inode: the inode to open + * @file: the struct file for this opening + * + * Returns: errno + */ + +static int +gfs_open(struct inode *inode, struct file *file) +{ + struct gfs_inode *ip = get_v2ip(inode); + struct gfs_holder i_gh; + struct gfs_file *fp; + int error; + + atomic_inc(&ip->i_sbd->sd_ops_file); + + fp = kmalloc(sizeof(struct gfs_file), GFP_KERNEL); + if (!fp) + return -ENOMEM; + memset(fp, 0, sizeof(struct gfs_file)); + + init_MUTEX(&fp->f_fl_lock); + + fp->f_inode = ip; + fp->f_vfile = file; + + gfs_assert_warn(ip->i_sbd, !get_v2fp(file)); + set_v2fp(file, fp); + + if (ip->i_di.di_type == GFS_FILE_REG) { + error = gfs_glock_nq_init(ip->i_gl, + LM_ST_SHARED, LM_FLAG_ANY, + &i_gh); + if (error) + goto fail; + + if (!(file->f_flags & O_LARGEFILE) && + ip->i_di.di_size > 0x7FFFFFFFull) { + error = -EFBIG; + goto fail_gunlock; + } + + /* Listen to the Direct I/O flag */ + + if (ip->i_di.di_flags & GFS_DIF_DIRECTIO) + file->f_flags |= O_DIRECT; + + /* Don't let the user open O_DIRECT on a jdata file */ + + if ((file->f_flags & O_DIRECT) && gfs_is_jdata(ip)) { + error = -EINVAL; + goto fail_gunlock; + } + + gfs_glock_dq_uninit(&i_gh); + } + + return 0; + + fail_gunlock: + gfs_glock_dq_uninit(&i_gh); + + fail: + set_v2fp(file, NULL); + kfree(fp); + + return error; +} + +/** + * gfs_close - called to close a struct file + * @inode: the inode the struct file belongs to + * @file: the struct file being closed + * + * Returns: errno + */ + +static int +gfs_close(struct inode *inode, struct file *file) +{ + struct gfs_sbd *sdp = get_v2sdp(inode->i_sb); + struct gfs_file *fp; + + atomic_inc(&sdp->sd_ops_file); + + fp = get_v2fp(file); + set_v2fp(file, NULL); + + if (!gfs_assert_warn(sdp, fp)) + kfree(fp); + + return 0; +} + +/** + * gfs_fsync - sync the dirty data for a file (across the cluster) + * @file: the file that points to the dentry (we ignore this) + * @dentry: the dentry that points to the inode to sync + * + * Returns: errno + * + * Obtain a SHARED lock on the file, to force any node with an EXCLUSIVE lock + * to sync file's dirty data to disk, as it releases the EXCLUSIVE lock. + */ + +static int +gfs_fsync(struct file *file, struct dentry *dentry, int datasync) +{ + struct gfs_inode *ip = get_v2ip(dentry->d_inode); + struct gfs_holder i_gh; + struct inode *inode = dentry->d_inode; + int error; + + atomic_inc(&ip->i_sbd->sd_ops_file); + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); + if (error) + return error; + + if (gfs_is_jdata(ip)) + gfs_log_flush_glock(ip->i_gl); + else { + if ((!datasync) || (inode->i_state & I_DIRTY_DATASYNC)) { + struct writeback_control wbc = { + .sync_mode = WB_SYNC_ALL, + .nr_to_write = 0, + }; + error = sync_inode(inode, &wbc); + } + } + + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gfs_lock - acquire/release a posix lock on a file + * @file: the file pointer + * @cmd: either modify or retrieve lock state, possibly wait + * @fl: type and range of lock + * + * Returns: errno + */ + +static int +gfs_lock(struct file *file, int cmd, struct file_lock *fl) +{ + struct gfs_inode *ip = get_v2ip(file->f_mapping->host); + struct gfs_sbd *sdp = ip->i_sbd; + struct lm_lockname name = + { .ln_number = ip->i_num.no_formal_ino, + .ln_type = LM_TYPE_PLOCK }; + + atomic_inc(&sdp->sd_ops_file); + + if (!(fl->fl_flags & FL_POSIX)) + return -ENOLCK; + if ((ip->i_di.di_mode & (S_ISGID | S_IXGRP)) == S_ISGID) + return -ENOLCK; + + if (IS_GETLK(cmd)) + return gfs_lm_plock_get(sdp, &name, file, fl); + else if (fl->fl_type == F_UNLCK) + return gfs_lm_punlock(sdp, &name, file, fl); + else + return gfs_lm_plock(sdp, &name, file, cmd, fl); +} + +/** + * gfs_splice_read - Send bytes to a file or socket + * @in_file: The file to read from + * @out_file: The file to write to + * @count: The amount of data + * @ppos: The beginning file offset + * + * Outputs: offset - updated according to number of bytes read + * + * Returns: The number of bytes sent, errno on failure + */ + +static ssize_t +gfs_splice_read(struct file *in_file, loff_t *ppos, struct pipe_inode_info *pipe, size_t count, unsigned int flags) +{ + struct gfs_inode *ip = get_v2ip(in_file->f_mapping->host); + struct gfs_holder gh; + ssize_t retval; + + atomic_inc(&ip->i_sbd->sd_ops_file); + + gfs_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); + + retval = gfs_glock_nq_atime(&gh); + if (retval) + goto out; + + if (gfs_is_jdata(ip)) + retval = -ENOSYS; + else + retval = generic_file_splice_read(in_file, ppos, pipe, count, flags); + + gfs_glock_dq(&gh); + + out: + gfs_holder_uninit(&gh); + + return retval; +} + +/** + * do_flock - Acquire a flock on a file + * @file: + * @cmd: + * @fl: + * + * Returns: errno + */ + +static int +do_flock(struct file *file, int cmd, struct file_lock *fl) +{ + struct gfs_file *fp = get_v2fp(file); + struct gfs_holder *fl_gh = &fp->f_fl_gh; + struct gfs_inode *ip = fp->f_inode; + struct gfs_glock *gl; + unsigned int state; + int flags; + int error = 0; + + state = (fl->fl_type == F_WRLCK) ? LM_ST_EXCLUSIVE : LM_ST_SHARED; + flags = ((IS_SETLKW(cmd)) ? 0 : LM_FLAG_TRY) | GL_EXACT | GL_NOCACHE; + + down(&fp->f_fl_lock); + + gl = fl_gh->gh_gl; + if (gl) { + if (fl_gh->gh_state == state) + goto out; + gfs_glock_hold(gl); + flock_lock_file_wait(file, + &(struct file_lock){.fl_type = F_UNLCK}); + gfs_glock_dq_uninit(fl_gh); + } else { + error = gfs_glock_get(ip->i_sbd, + ip->i_num.no_formal_ino, &gfs_flock_glops, + CREATE, &gl); + if (error) + goto out; + } + + gfs_holder_init(gl, state, flags, fl_gh); + gfs_glock_put(gl); + + error = gfs_glock_nq(fl_gh); + if (error) { + gfs_holder_uninit(fl_gh); + if (error == GLR_TRYFAILED) + error = -EAGAIN; + } else { + error = flock_lock_file_wait(file, fl); + gfs_assert_warn(ip->i_sbd, !error); + } + + out: + up(&fp->f_fl_lock); + + return error; +} + +/** + * do_unflock - Release a flock on a file + * @file: the file + * @fl: + * + */ + +static void +do_unflock(struct file *file, struct file_lock *fl) +{ + struct gfs_file *fp = get_v2fp(file); + struct gfs_holder *fl_gh = &fp->f_fl_gh; + + down(&fp->f_fl_lock); + flock_lock_file_wait(file, fl); + if (fl_gh->gh_gl) + gfs_glock_dq_uninit(fl_gh); + up(&fp->f_fl_lock); +} + +/** + * gfs_flock - acquire/release a flock lock on a file + * @file: the file pointer + * @cmd: either modify or retrieve lock state, possibly wait + * @fl: type and range of lock + * + * Returns: errno + */ + +static int +gfs_flock(struct file *file, int cmd, struct file_lock *fl) +{ + struct gfs_inode *ip = get_v2ip(file->f_mapping->host); + + atomic_inc(&ip->i_sbd->sd_ops_file); + + if (!(fl->fl_flags & FL_FLOCK)) + return -ENOLCK; + if ((ip->i_di.di_mode & (S_ISGID | S_IXGRP)) == S_ISGID) + return -ENOLCK; + + if (fl->fl_type == F_UNLCK) { + do_unflock(file, fl); + return 0; + } else + return do_flock(file, cmd, fl); +} + +struct file_operations gfs_file_fops = { + .llseek = gfs_llseek, + .read = gfs_read, + .write = gfs_write, + .aio_read = gfs_aio_read, + .aio_write = gfs_aio_write, + .ioctl = gfs_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = gfs_compat_ioctl, +#endif + .mmap = gfs_mmap, + .open = gfs_open, + .release = gfs_close, + .fsync = gfs_fsync, + .lock = gfs_lock, + .splice_read = gfs_splice_read, + .flock = gfs_flock, +}; + +struct file_operations gfs_dir_fops = { + .readdir = gfs_readdir, + .ioctl = gfs_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = gfs_compat_ioctl, +#endif + .open = gfs_open, + .release = gfs_close, + .fsync = gfs_fsync, + .lock = gfs_lock, + .flock = gfs_flock, +}; + +struct file_operations gfs_file_fops_nolock = { + .llseek = gfs_llseek, + .read = gfs_read, + .write = gfs_write, + .aio_read = gfs_aio_read, + .aio_write = gfs_aio_write, + .ioctl = gfs_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = gfs_compat_ioctl, +#endif + .mmap = gfs_mmap, + .open = gfs_open, + .release = gfs_close, + .fsync = gfs_fsync, + .splice_read = gfs_splice_read, +}; + +struct file_operations gfs_dir_fops_nolock = { + .readdir = gfs_readdir, + .ioctl = gfs_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = gfs_compat_ioctl, +#endif + .open = gfs_open, + .release = gfs_close, + .fsync = gfs_fsync, +}; --- linux-2.6.28.orig/ubuntu/gfs/trans.c +++ linux-2.6.28/ubuntu/gfs/trans.c @@ -0,0 +1,453 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "dio.h" +#include "glock.h" +#include "log.h" +#include "lops.h" +#include "quota.h" +#include "trans.h" +#include "unlinked.h" + +/** + * gfs_trans_print - Print a transaction to the console + * @sdp: the filesystem + * @tr: The GFS transaction + * @where: Situation of transaction + * + */ + +void +gfs_trans_print(struct gfs_sbd *sdp, struct gfs_trans *tr, unsigned int where) +{ + struct gfs_log_element *le; + struct list_head *tmp, *head; + unsigned int mblks = 0, eblks = 0; + + LO_TRANS_SIZE(sdp, tr, &mblks, &eblks, NULL, NULL); + + printk("Transaction: (%s, %u)\n", tr->tr_file, tr->tr_line); + printk(" tr_mblks_asked = %u, tr_eblks_asked = %u, tr_seg_reserved = %u\n", + tr->tr_mblks_asked, tr->tr_eblks_asked, tr->tr_seg_reserved); + printk(" mblks = %u, eblks = %u\n", mblks, eblks); + printk(" tr_flags = 0x%.8X\n", tr->tr_flags); + + for (head = &tr->tr_elements, tmp = head->next; + tmp != head; + tmp = tmp->next) { + le = list_entry(tmp, struct gfs_log_element, le_list); + LO_PRINT(sdp, le, where); + } + + printk("End Trans\n"); +} + +/** + * gfs_trans_begin_i - Prepare to start a transaction + * @sdp: The GFS superblock + * @meta_blocks: Reserve this many metadata blocks in the log + * @extra_blocks: Number of non-metadata blocks to reserve + * + * Allocate the struct gfs_trans struct. + * Grab a shared TRANSaction lock (protects this transaction from + * overlapping with unusual fs writes, e.g. journal replay, fs upgrade, + * while allowing simultaneous transaction writes throughout cluster). + * Reserve space in the log. @meta_blocks and @extra_blocks must indicate + * the worst case (maximum) size of the transaction. + * Record this transaction as the *one* transaction being built by this + * Linux process, in current->journal_info. + * + * Returns: errno + */ + +int +gfs_trans_begin_i(struct gfs_sbd *sdp, + unsigned int meta_blocks, unsigned int extra_blocks, + char *file, unsigned int line) +{ + struct gfs_trans *tr; + unsigned int blocks; + int error; + + tr = kmalloc(sizeof(struct gfs_trans), GFP_KERNEL); + if (!tr) + return -ENOMEM; + memset(tr, 0, sizeof(struct gfs_trans)); + + INIT_LIST_HEAD(&tr->tr_elements); + INIT_LIST_HEAD(&tr->tr_free_bufs); + INIT_LIST_HEAD(&tr->tr_free_bmem); + INIT_LIST_HEAD(&tr->tr_bufs); + INIT_LIST_HEAD(&tr->tr_ail_bufs); + tr->tr_file = file; + tr->tr_line = line; + + error = -ENOMEM; + tr->tr_t_gh = gfs_holder_get(sdp->sd_trans_gl, LM_ST_SHARED, 0); + if (!tr->tr_t_gh) + goto fail; + + error = gfs_glock_nq(tr->tr_t_gh); + if (error) + goto fail_holder_put; + + if (test_bit(SDF_ROFS, &sdp->sd_flags)) { + tr->tr_t_gh->gh_flags |= GL_NOCACHE; + error = -EROFS; + goto fail_gunlock; + } + + /* Do log reservation */ + + tr->tr_mblks_asked = meta_blocks; + tr->tr_eblks_asked = extra_blocks; + + blocks = 1; + if (meta_blocks) + blocks += gfs_struct2blk(sdp, meta_blocks, + sizeof(struct gfs_block_tag)) + + meta_blocks; + blocks += extra_blocks; + tr->tr_seg_reserved = gfs_blk2seg(sdp, blocks); + + error = gfs_log_reserve(sdp, tr->tr_seg_reserved, FALSE); + if (error) + goto fail_gunlock; + + gfs_assert(sdp, !get_transaction,); + set_transaction(tr); + + return 0; + + fail_gunlock: + gfs_glock_dq(tr->tr_t_gh); + + fail_holder_put: + gfs_holder_put(tr->tr_t_gh); + + fail: + kfree(tr); + + return error; +} + +/** + * gfs_trans_end - End a transaction + * @sdp: The GFS superblock + * + * If buffers were actually added to the transaction, + * commit it. + * + */ + +void +gfs_trans_end(struct gfs_sbd *sdp) +{ + struct gfs_trans *tr; + struct gfs_holder *t_gh; + struct list_head *tmp, *head; + struct gfs_log_element *le; + + /* Linux task struct indicates current new trans for this process. + * We're done building it, so set it to NULL */ + tr = get_transaction; + gfs_assert(sdp, tr,); + set_transaction(NULL); + + t_gh = tr->tr_t_gh; + tr->tr_t_gh = NULL; + + /* If no buffers were ever added to trans, forget it */ + if (list_empty(&tr->tr_elements)) { + gfs_log_release(sdp, tr->tr_seg_reserved); + kfree(tr); + + gfs_glock_dq(t_gh); + gfs_holder_put(t_gh); + + return; + } + + /* Do trans_end log-operation for each log element */ + for (head = &tr->tr_elements, tmp = head->next; + tmp != head; + tmp = tmp->next) { + le = list_entry(tmp, struct gfs_log_element, le_list); + LO_TRANS_END(sdp, le); + } + + gfs_log_commit(sdp, tr); + + gfs_glock_dq(t_gh); + gfs_holder_put(t_gh); + + if (sdp->sd_vfs->s_flags & MS_SYNCHRONOUS) + gfs_log_flush(sdp); +} + +/** + * gfs_trans_add_gl - Add a glock to a transaction + * @gl: the glock + * + * If not already attached, add the given glock to this process's transaction. + * + * Even though no glock info will be written to the on-disk log, the glocks + * associated with a transaction provide bridges by which to combine + * a just-built transaction with an earlier incore committed transaction + * that was protected by the same glock. See incore_commit(). + * Combining transactions makes for more efficient logging. + * + * Note that more than one glock may be associated with a single transaction. + * However, a given glock protects no more than *one* transaction at a + * given stage in the transaction pipeline (i.e. new or incore-committed). + * After all, the process holds the glock EX (so no other process can be + * building a separate trans protected by this glock), and the process can + * build only one transaction at a time. + * + * Rules: + * This process must hold the glock in EXclusive mode, since we're going + * to be writing to something protected by this glock. + */ + +void +gfs_trans_add_gl(struct gfs_glock *gl) +{ + if (!gl->gl_new_le.le_trans) { + gfs_assert_withdraw(gl->gl_sbd, + gfs_glock_is_locked_by_me(gl) && + gfs_glock_is_held_excl(gl)); + gfs_glock_hold(gl); /* Released in glock_trans_end() */ + + /* Ask for eventual flush of (meta)data protected by this glock, + once trans is complete and logged. */ + set_bit(GLF_DIRTY, &gl->gl_flags); + + /* Invoke generic_le_add() */ + LO_ADD(gl->gl_sbd, &gl->gl_new_le); + gl->gl_new_le.le_trans->tr_num_gl++; + } +} + +/** + * gfs_trans_add_bh - Add a to-be-modified buffer to the current transaction + * @gl: the glock the buffer belongs to + * @bh: The buffer to add + * + * Add a to-be-modified buffer to the current being-built (i.e. new) trans, + * and pin the buffer in memory. + * + * Caller must hold the glock protecting this buffer. + * + * Call this as many times as you want during transaction formation. It does + * its attachment work only once. After buffer is attached to trans, the + * process building the trans can modify the buffer again and again (calling + * this function before each change). Only the final result (within this trans) + * will be written to log. A good example is when allocating blocks in an RG, + * a given bitmap buffer may be updated many times within a transaction. + * + * Note: This final result will also be written to its in-place location, + * unless this transaction gets combined with a later transaction, + * in which case only the later result will go to in-place. + * + */ + +void +gfs_trans_add_bh(struct gfs_glock *gl, struct buffer_head *bh) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_bufdata *bd; + + /* Make sure GFS private info struct is attached to buffer head */ + bd = get_v2bd(bh); + if (!bd) { + gfs_attach_bufdata(bh, gl); + bd = get_v2bd(bh); + } + + /* If buffer has already been attached to trans, we're done */ + if (bd->bd_new_le.le_trans) + return; + + gfs_meta_check(sdp, bh); + + gfs_assert(sdp, bd->bd_gl == gl,); + + /* Make sure glock is attached to trans */ + if (!gl->gl_new_le.le_trans) + gfs_trans_add_gl(gl); + + gfs_dpin(sdp, bh); + + /* Attach buffer to trans */ + LO_ADD(sdp, &bd->bd_new_le); + bd->bd_new_le.le_trans->tr_num_buf++; +} + +/** + * gfs_trans_add_unlinked - Add an unlinked or dealloced tag to + * the current transaction + * @sdp: the filesystem + * @type: the type of entry + * @inum: the inode number + * + * Returns: the unlinked structure + */ + +struct gfs_unlinked * +gfs_trans_add_unlinked(struct gfs_sbd *sdp, unsigned int type, + struct gfs_inum *inum) +{ + struct gfs_unlinked *ul; + + /* Find in fileystem's unlinked list, or create */ + ul = gfs_unlinked_get(sdp, inum, CREATE); + + LO_ADD(sdp, &ul->ul_new_le); + + switch (type) { + case GFS_LOG_DESC_IUL: + set_bit(ULF_NEW_UL, &ul->ul_flags); + ul->ul_new_le.le_trans->tr_num_iul++; + break; + case GFS_LOG_DESC_IDA: + clear_bit(ULF_NEW_UL, &ul->ul_flags); + ul->ul_new_le.le_trans->tr_num_ida++; + break; + default: + gfs_assert(sdp, FALSE,); + break; + } + + return ul; +} + +/** + * gfs_trans_add_quota - Add quota changes to a transaction + * @sdp: the filesystem + * @change: The number of blocks allocated (positive) or freed (negative) + * @uid: the user ID doing the change + * @gid: the group ID doing the change + * + */ + +void +gfs_trans_add_quota(struct gfs_sbd *sdp, int64_t change, + uint32_t uid, uint32_t gid) +{ + struct gfs_trans *tr; + struct list_head *tmp, *head, *next; + struct gfs_log_element *le; + struct gfs_quota_le *ql; + int found_uid, found_gid; + int error; + + if (!gfs_tune_get(sdp, gt_quota_account)) + return; + if (gfs_assert_warn(sdp, change)) + return; + + found_uid = (uid == NO_QUOTA_CHANGE); + found_gid = (gid == NO_QUOTA_CHANGE); + + if (gfs_assert_warn(sdp, !found_uid || !found_gid)) + return; + + tr = get_transaction; + gfs_assert(sdp, tr,); + + for (head = &tr->tr_elements, tmp = head->next, next = tmp->next; + tmp != head; + tmp = next, next = next->next) { + le = list_entry(tmp, struct gfs_log_element, le_list); + if (le->le_ops != &gfs_quota_lops) + continue; + + ql = container_of(le, struct gfs_quota_le, ql_le); + + if (test_bit(QDF_USER, &ql->ql_data->qd_flags)) { + if (ql->ql_data->qd_id == uid) { + ql->ql_change += change; + + spin_lock(&sdp->sd_quota_lock); + ql->ql_data->qd_change_new += change; + spin_unlock(&sdp->sd_quota_lock); + + list_del(&le->le_list); + + if (ql->ql_change) + list_add(&le->le_list, + &tr->tr_elements); + else { + gfs_quota_put(sdp, ql->ql_data); + kfree(ql); + tr->tr_num_q--; + } + + gfs_assert(sdp, !found_uid,); + found_uid = TRUE; + if (found_gid) + break; + } + } else { + if (ql->ql_data->qd_id == gid) { + ql->ql_change += change; + + spin_lock(&sdp->sd_quota_lock); + ql->ql_data->qd_change_new += change; + spin_unlock(&sdp->sd_quota_lock); + + list_del(&le->le_list); + + if (ql->ql_change) + list_add(&le->le_list, + &tr->tr_elements); + else { + gfs_quota_put(sdp, ql->ql_data); + kfree(ql); + tr->tr_num_q--; + } + + gfs_assert(sdp, !found_gid,); + found_gid = TRUE; + if (found_uid) + break; + } + } + } + + while (!found_uid || !found_gid) { + ql = gmalloc(sizeof(struct gfs_quota_le)); + memset(ql, 0, sizeof(struct gfs_quota_le)); + + INIT_LE(&ql->ql_le, &gfs_quota_lops); + + if (found_uid) { + error = gfs_quota_get(sdp, FALSE, gid, + NO_CREATE, + &ql->ql_data); + found_gid = TRUE; + } else { + error = gfs_quota_get(sdp, TRUE, uid, + NO_CREATE, + &ql->ql_data); + found_uid = TRUE; + } + + gfs_assert(sdp, !error && ql->ql_data,); + + ql->ql_change = change; + + spin_lock(&sdp->sd_quota_lock); + ql->ql_data->qd_change_new += change; + spin_unlock(&sdp->sd_quota_lock); + + LO_ADD(sdp, &ql->ql_le); + tr->tr_num_q++; + } +} --- linux-2.6.28.orig/ubuntu/gfs/glock.c +++ linux-2.6.28/ubuntu/gfs/glock.c @@ -0,0 +1,2996 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "dio.h" +#include "glock.h" +#include "glops.h" +#include "inode.h" +#include "lm.h" +#include "lops.h" +#include "quota.h" +#include "recovery.h" + +/* Must be kept in sync with the beginning of struct gfs_glock */ +struct glock_plug { + struct list_head gl_list; + unsigned long gl_flags; +}; + +struct greedy { + struct gfs_holder gr_gh; + struct delayed_work gr_work; +}; + +typedef void (*glock_examiner) (struct gfs_glock * gl, unsigned int *cnt); + +/** + * relaxed_state_ok - is a requested lock compatible with the current lock mode? + * @actual: the current state of the lock + * @requested: the lock state that was requested by the caller + * @flags: the modifier flags passed in by the caller + * + * Returns: TRUE if the locks are compatible, FALSE otherwise + * + * It's often possible that a holder B may request the lock in SHARED mode, + * while another holder A (on this same node) has the lock in EXCLUSIVE mode + * (node must hold the glock in EXCLUSIVE mode for this situation, of course). + * This is okay to grant, in some cases, since both holders would have access + * to the in-core up-to-date cached data that the EX holder would write to disk. + * This is the default behavior. + * + * The EXACT flag disallows this behavior, though. A SHARED request would + * compatible only with a SHARED lock with this flag. + * + * The ANY flag provides broader permission to grant the lock to a holder, + * whatever the requested state is, as long as the lock is locked in any mode. + */ + +static __inline__ int +relaxed_state_ok(unsigned int actual, unsigned requested, int flags) +{ + if (actual == requested) + return TRUE; + + if (flags & GL_EXACT) + return FALSE; + + if (actual == LM_ST_EXCLUSIVE && requested == LM_ST_SHARED) + return TRUE; + + if (actual != LM_ST_UNLOCKED && (flags & LM_FLAG_ANY)) + return TRUE; + + return FALSE; +} + +/** + * gl_hash() - Turn glock number into hash bucket number + * @lock: The glock number + * + * Returns: The number of the corresponding hash bucket + */ + +static unsigned int +gl_hash(struct lm_lockname *name) +{ + unsigned int h; + + h = gfs_hash(&name->ln_number, sizeof(uint64_t)); + h = gfs_hash_more(&name->ln_type, sizeof(unsigned int), h); + h &= GFS_GL_HASH_MASK; + + return h; +} + +/** + * glock_hold() - increment reference count on glock + * @gl: The glock to hold + * + */ + +static __inline__ void +glock_hold(struct gfs_glock *gl) +{ + gfs_assert(gl->gl_sbd, atomic_read(&gl->gl_count) > 0,); + atomic_inc(&gl->gl_count); +} + +/** + * glock_put() - Decrement reference count on glock + * @gl: The glock to put + * + */ + +static __inline__ void +glock_put(struct gfs_glock *gl) +{ + if (atomic_read(&gl->gl_count) == 1) + gfs_glock_schedule_for_reclaim(gl); + gfs_assert(gl->gl_sbd, atomic_read(&gl->gl_count) > 0,); + atomic_dec(&gl->gl_count); +} + +/** + * queue_empty - check to see if a glock's queue is empty + * @gl: the glock + * @head: the head of the queue to check + * + * Returns: TRUE if the queue is empty + */ + +static __inline__ int +queue_empty(struct gfs_glock *gl, struct list_head *head) +{ + int empty; + spin_lock(&gl->gl_spin); + empty = list_empty(head); + spin_unlock(&gl->gl_spin); + return empty; +} + +/** + * search_bucket() - Find struct gfs_glock by lock number + * @bucket: the bucket to search + * @name: The lock name + * + * Returns: NULL, or the struct gfs_glock with the requested number + */ + +static struct gfs_glock * +search_bucket(struct gfs_gl_hash_bucket *bucket, struct lm_lockname *name) +{ + struct list_head *tmp, *head; + struct gfs_glock *gl; + + for (head = &bucket->hb_list, tmp = head->next; + tmp != head; + tmp = tmp->next) { + gl = list_entry(tmp, struct gfs_glock, gl_list); + + if (test_bit(GLF_PLUG, &gl->gl_flags)) + continue; + if (!lm_name_equal(&gl->gl_name, name)) + continue; + + atomic_inc(&gl->gl_count); + + return gl; + } + + return NULL; +} + +/** + * gfs_glock_find() - Find glock by lock number + * @sdp: The GFS superblock + * @name: The lock name + * + * Figure out what bucket the lock is in, acquire the read lock on + * it and call search_bucket(). + * + * Returns: NULL, or the struct gfs_glock with the requested number + */ + +struct gfs_glock * +gfs_glock_find(struct gfs_sbd *sdp, struct lm_lockname *name) +{ + struct gfs_gl_hash_bucket *bucket = &sdp->sd_gl_hash[gl_hash(name)]; + struct gfs_glock *gl; + + read_lock(&bucket->hb_lock); + gl = search_bucket(bucket, name); + read_unlock(&bucket->hb_lock); + + return gl; +} + +/** + * glock_free() - Perform a few checks and then release struct gfs_glock + * @gl: The glock to release + * + * Also calls lock module to release its internal structure for this glock. + * + */ + +static void +glock_free(struct gfs_glock *gl) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct inode *aspace = gl->gl_aspace; + + gfs_assert_warn(sdp, list_empty(&gl->gl_list)); + gfs_assert_warn(sdp, atomic_read(&gl->gl_count) == 1); + gfs_assert_warn(sdp, list_empty(&gl->gl_holders)); + gfs_assert_warn(sdp, list_empty(&gl->gl_waiters1)); + gfs_assert_warn(sdp, list_empty(&gl->gl_waiters2)); + gfs_assert_warn(sdp, list_empty(&gl->gl_waiters3)); + gfs_assert_warn(sdp, gl->gl_state == LM_ST_UNLOCKED); + gfs_assert_warn(sdp, !gl->gl_object); + gfs_assert_warn(sdp, !gl->gl_lvb); + gfs_assert_warn(sdp, list_empty(&gl->gl_reclaim)); + + gfs_lm_put_lock(sdp, gl->gl_lock); + + if (aspace) + gfs_aspace_put(aspace); + + kmem_cache_free(gfs_glock_cachep, gl); + + atomic_dec(&sdp->sd_glock_count); +} + +/** + * gfs_glock_get() - Get a glock, or create one if one doesn't exist + * @sdp: The GFS superblock + * @number: the lock number + * @glops: The glock_operations to use + * @create: If FALSE, don't create the glock if it doesn't exist + * @glp: the glock is returned here + * + * This does not lock a glock, just finds/creates structures for one. + * + * Returns: errno + */ + +int +gfs_glock_get(struct gfs_sbd *sdp, + uint64_t number, struct gfs_glock_operations *glops, + int create, struct gfs_glock **glp) +{ + struct lm_lockname name; + struct gfs_glock *gl, *tmp; + struct gfs_gl_hash_bucket *bucket; + int error; + + /* Look for pre-existing glock in hash table */ + name.ln_number = number; + name.ln_type = glops->go_type; + bucket = &sdp->sd_gl_hash[gl_hash(&name)]; + + read_lock(&bucket->hb_lock); + gl = search_bucket(bucket, &name); + read_unlock(&bucket->hb_lock); + + if (gl || !create) { + *glp = gl; + return 0; + } + + /* None found; create a new one */ + gl = kmem_cache_alloc(gfs_glock_cachep, GFP_KERNEL); + if (!gl) + return -ENOMEM; + + memset(gl, 0, sizeof(struct gfs_glock)); + + INIT_LIST_HEAD(&gl->gl_list); + gl->gl_name = name; + atomic_set(&gl->gl_count, 1); + + spin_lock_init(&gl->gl_spin); + + gl->gl_state = LM_ST_UNLOCKED; + INIT_LIST_HEAD(&gl->gl_holders); + INIT_LIST_HEAD(&gl->gl_waiters1); + INIT_LIST_HEAD(&gl->gl_waiters2); + INIT_LIST_HEAD(&gl->gl_waiters3); + + gl->gl_ops = glops; + + INIT_LE(&gl->gl_new_le, &gfs_glock_lops); + INIT_LE(&gl->gl_incore_le, &gfs_glock_lops); + + gl->gl_bucket = bucket; + INIT_LIST_HEAD(&gl->gl_reclaim); + + gl->gl_sbd = sdp; + + INIT_LIST_HEAD(&gl->gl_ail_bufs); + + /* If this glock protects actual on-disk data or metadata blocks, + create a VFS inode to manage the pages/buffers holding them. */ + if (glops == &gfs_inode_glops || + glops == &gfs_rgrp_glops || + glops == &gfs_meta_glops) { + gl->gl_aspace = gfs_aspace_get(sdp); + if (!gl->gl_aspace) { + error = -ENOMEM; + goto fail; + } + } + + /* Ask lock module to find/create its structure for this lock + (but this doesn't lock the inter-node lock yet) */ + error = gfs_lm_get_lock(sdp, &name, &gl->gl_lock); + if (error) + goto fail_aspace; + + atomic_inc(&sdp->sd_glock_count); + + /* Double-check, in case another process created the glock, and has + put it in the hash table while we were preparing this one */ + write_lock(&bucket->hb_lock); + tmp = search_bucket(bucket, &name); + if (tmp) { + /* Somebody beat us to it; forget the one we prepared */ + write_unlock(&bucket->hb_lock); + glock_free(gl); + gl = tmp; + } else { + /* Add our glock to hash table */ + list_add_tail(&gl->gl_list, &bucket->hb_list); + write_unlock(&bucket->hb_lock); + } + + *glp = gl; + + return 0; + + fail_aspace: + if (gl->gl_aspace) + gfs_aspace_put(gl->gl_aspace); + + fail: + kmem_cache_free(gfs_glock_cachep, gl); + + return error; +} + +/** + * gfs_glock_hold() - As glock_hold(), but suitable for exporting + * @gl: The glock to hold + * + */ + +void +gfs_glock_hold(struct gfs_glock *gl) +{ + glock_hold(gl); +} + +/** + * gfs_glock_put() - As glock_put(), but suitable for exporting + * @gl: The glock to put + * + */ + +void +gfs_glock_put(struct gfs_glock *gl) +{ + glock_put(gl); +} + +/** + * gfs_holder_init - initialize a struct gfs_holder in the default way + * @gl: the glock + * @state: the state we're requesting + * @flags: the modifier flags + * @gh: the holder structure + * + */ + +void +gfs_holder_init(struct gfs_glock *gl, unsigned int state, int flags, + struct gfs_holder *gh) +{ + memset(gh, 0, sizeof(struct gfs_holder)); + + INIT_LIST_HEAD(&gh->gh_list); + gh->gh_gl = gl; + gh->gh_owner = current; + gh->gh_state = state; + gh->gh_flags = flags; + + if (gh->gh_state == LM_ST_EXCLUSIVE) + gh->gh_flags |= GL_LOCAL_EXCL; + + init_completion(&gh->gh_wait); + + glock_hold(gl); +} + +/** + * gfs_holder_reinit - reinitialize a struct gfs_holder so we can requeue it + * @state: the state we're requesting + * @flags: the modifier flags + * @gh: the holder structure + * + * Preserve holder's associated glock and owning process. + * Reset all holder state flags (we're starting a new request from scratch), + * except for HIF_ALLOCED. + * Don't do glock_hold() again (it was done in gfs_holder_init()). + * Don't mess with the glock. + * + * Rules: + * Holder must have been gfs_holder_init()d already + * Holder must *not* be in glock's holder list or wait queues now + */ + +void +gfs_holder_reinit(unsigned int state, int flags, struct gfs_holder *gh) +{ + int alloced; + + gfs_assert_warn(gh->gh_gl->gl_sbd, + list_empty(&gh->gh_list)); + + gh->gh_state = state; + gh->gh_flags = flags; + + if (gh->gh_state == LM_ST_EXCLUSIVE) + gh->gh_flags |= GL_LOCAL_EXCL; + + alloced = test_bit(HIF_ALLOCED, &gh->gh_iflags); + memset(&gh->gh_iflags, 0, sizeof(unsigned long)); + if (alloced) + set_bit(HIF_ALLOCED, &gh->gh_iflags); +} + +/** + * gfs_holder_uninit - uninitialize a holder structure (drop reference on glock) + * @gh: the holder structure + * + */ + +void +gfs_holder_uninit(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + + gfs_assert_warn(gl->gl_sbd, list_empty(&gh->gh_list)); + gh->gh_gl = NULL; + + glock_put(gl); +} + +/** + * gfs_holder_get - get a struct gfs_holder structure + * @gl: the glock + * @state: the state we're requesting + * @flags: the modifier flags + * + * Figure out how big an impact this function has. Either: + * 1) Replace it with a cache of structures hanging off the struct gfs_sbd + * 2) Leave it like it is + * + * Returns: the holder structure, NULL on ENOMEM + */ + +struct gfs_holder * +gfs_holder_get(struct gfs_glock *gl, unsigned int state, int flags) +{ + struct gfs_holder *gh; + + gh = kmalloc(sizeof(struct gfs_holder), GFP_KERNEL); + if (!gh) + return NULL; + + gfs_holder_init(gl, state, flags, gh); + set_bit(HIF_ALLOCED, &gh->gh_iflags); + + return gh; +} + +/** + * gfs_holder_put - get rid of a struct gfs_holder structure + * @gh: the holder structure + * + */ + +void +gfs_holder_put(struct gfs_holder *gh) +{ + if (gfs_assert_warn(gh->gh_gl->gl_sbd, + test_bit(HIF_ALLOCED, &gh->gh_iflags))) + return; + gfs_holder_uninit(gh); + kfree(gh); +} + +/** + * handle_recurse - put other holder structures (marked recursive) into the holders list + * @gh: the holder structure + * + */ + +static void +handle_recurse(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + struct gfs_sbd *sdp = gl->gl_sbd; + struct list_head *tmp, *head, *next; + struct gfs_holder *tmp_gh; + int found = FALSE; + + if (gfs_assert_warn(sdp, gh->gh_owner)) + return; + + for (head = &gl->gl_waiters3, tmp = head->next, next = tmp->next; + tmp != head; + tmp = next, next = tmp->next) { + tmp_gh = list_entry(tmp, struct gfs_holder, gh_list); + if (tmp_gh->gh_owner != gh->gh_owner) + continue; + + gfs_assert_warn(sdp, test_bit(HIF_RECURSE, &tmp_gh->gh_iflags)); + + list_move_tail(&tmp_gh->gh_list, &gl->gl_holders); + tmp_gh->gh_error = 0; + set_bit(HIF_HOLDER, &tmp_gh->gh_iflags); + + complete(&tmp_gh->gh_wait); + + found = TRUE; + } + + gfs_assert_warn(sdp, found); +} + +/** + * do_unrecurse - a recursive holder was just dropped of the waiters3 list + * @gh: the holder + * + * If there is only one other recursive holder, clear its HIF_RECURSE bit + * (it's no longer a recursive request). + * If there is more than one, leave them alone (they're recursive!). + * + */ + +static void +do_unrecurse(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + struct gfs_sbd *sdp = gl->gl_sbd; + struct list_head *tmp, *head; + struct gfs_holder *tmp_gh, *last_gh = NULL; + int found = FALSE; + + if (gfs_assert_warn(sdp, gh->gh_owner)) + return; + + for (head = &gl->gl_waiters3, tmp = head->next; + tmp != head; + tmp = tmp->next) { + tmp_gh = list_entry(tmp, struct gfs_holder, gh_list); + if (tmp_gh->gh_owner != gh->gh_owner) + continue; + + gfs_assert_warn(sdp, test_bit(HIF_RECURSE, &tmp_gh->gh_iflags)); + + /* found more than one */ + if (found) + return; + + found = TRUE; + last_gh = tmp_gh; + } + + /* found just one */ + if (!gfs_assert_warn(sdp, found)) + clear_bit(HIF_RECURSE, &last_gh->gh_iflags); +} + +/** + * rq_mutex - process a mutex request in the queue + * @gh: the glock holder + * + * Returns: TRUE if the queue is blocked (always, since there can be only one + * holder of the mutex). + * + * See lock_on_glock() + */ + +static int +rq_mutex(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + + list_del_init(&gh->gh_list); + /* gh->gh_error never examined. */ + set_bit(GLF_LOCK, &gl->gl_flags); + complete(&gh->gh_wait); + + return TRUE; +} + +/** + * rq_promote - process a promote request in the queue + * @gh: the glock holder + * + * Acquire a new inter-node lock, or change a lock state to more restrictive. + * + * Returns: TRUE if the queue is blocked + */ + +static int +rq_promote(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_glock_operations *glops = gl->gl_ops; + int recurse; + + if (!relaxed_state_ok(gl->gl_state, gh->gh_state, gh->gh_flags)) { + if (list_empty(&gl->gl_holders)) { + gl->gl_req_gh = gh; + set_bit(GLF_LOCK, &gl->gl_flags); + spin_unlock(&gl->gl_spin); + + /* If we notice a lot of glocks in reclaim list, free + up memory for 2 of them before locking a new one */ + if (atomic_read(&sdp->sd_reclaim_count) > + gfs_tune_get(sdp, gt_reclaim_limit) && + !(gh->gh_flags & LM_FLAG_PRIORITY)) { + gfs_reclaim_glock(sdp); + gfs_reclaim_glock(sdp); + } + + glops->go_xmote_th(gl, gh->gh_state, + gh->gh_flags); + + spin_lock(&gl->gl_spin); + } + return TRUE; + } + + if (list_empty(&gl->gl_holders)) { + set_bit(HIF_FIRST, &gh->gh_iflags); + set_bit(GLF_LOCK, &gl->gl_flags); + recurse = FALSE; + } else { + struct gfs_holder *next_gh; + if (gh->gh_flags & GL_LOCAL_EXCL) + return TRUE; + next_gh = list_entry(gl->gl_holders.next, struct gfs_holder, gh_list); + if (next_gh->gh_flags & GL_LOCAL_EXCL) + return TRUE; + recurse = test_bit(HIF_RECURSE, &gh->gh_iflags); + } + + list_move_tail(&gh->gh_list, &gl->gl_holders); + gh->gh_error = 0; + set_bit(HIF_HOLDER, &gh->gh_iflags); + + if (recurse) + handle_recurse(gh); + + complete(&gh->gh_wait); + + return FALSE; +} + +/** + * rq_demote - process a demote request in the queue + * @gh: the glock holder + * + * Returns: TRUE if the queue is blocked + * + * Unlock an inter-node lock, or change a lock state to less restrictive. + * If the glock is already the same as the holder's requested state, or is + * UNLOCKED, no lock module request is required. + * Otherwise, we need to ask lock module to unlock or change locked state + * of the glock. + * If requested state is UNLOCKED, or current glock state is SHARED or + * DEFERRED (neither of which have a less restrictive state other than + * UNLOCK), we call go_drop_th() to unlock the lock. + * Otherwise (i.e. requested is SHARED or DEFERRED, and current is EXCLUSIVE), + * we can continue to hold the lock, and just ask for a new state; + * we call go_xmote_th() to change state. + * + * Must be called with glock's gl->gl_spin locked. + */ + +static int +rq_demote(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + struct gfs_glock_operations *glops = gl->gl_ops; + + if (!list_empty(&gl->gl_holders)) + return TRUE; + + if (gl->gl_state == gh->gh_state || gl->gl_state == LM_ST_UNLOCKED) { + list_del_init(&gh->gh_list); + gh->gh_error = 0; + spin_unlock(&gl->gl_spin); + if (test_bit(HIF_DEALLOC, &gh->gh_iflags)) + gfs_holder_put(gh); + else + complete(&gh->gh_wait); + spin_lock(&gl->gl_spin); + } else { + gl->gl_req_gh = gh; + set_bit(GLF_LOCK, &gl->gl_flags); + spin_unlock(&gl->gl_spin); + + if (gh->gh_state == LM_ST_UNLOCKED || + gl->gl_state != LM_ST_EXCLUSIVE) + /* Unlock */ + glops->go_drop_th(gl); + else + /* Change state while holding lock */ + glops->go_xmote_th(gl, gh->gh_state, gh->gh_flags); + + spin_lock(&gl->gl_spin); + } + + return FALSE; +} + +/** + * rq_greedy - process a queued request to drop greedy status + * @gh: the glock holder + * + * Returns: TRUE if the queue is blocked + */ + +static int +rq_greedy(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + + list_del_init(&gh->gh_list); + /* gh->gh_error never examined. */ + clear_bit(GLF_GREEDY, &gl->gl_flags); + spin_unlock(&gl->gl_spin); + + gfs_holder_uninit(gh); + kfree(container_of(gh, struct greedy, gr_gh)); + + spin_lock(&gl->gl_spin); + + return FALSE; +} + +/** + * run_queue - process holder structures on the glock's wait queues + * @gl: the glock + * + * Rules: + * Caller must hold gl->gl_spin. + */ + +static void +run_queue(struct gfs_glock *gl) +{ + struct gfs_holder *gh; + int blocked = TRUE; + + for (;;) { + /* Another process is manipulating the glock structure; + we can't do anything now */ + if (test_bit(GLF_LOCK, &gl->gl_flags)) + break; + + /* Waiting to manipulate the glock structure */ + if (!list_empty(&gl->gl_waiters1)) { + gh = list_entry(gl->gl_waiters1.next, + struct gfs_holder, gh_list); + + if (test_bit(HIF_MUTEX, &gh->gh_iflags)) + blocked = rq_mutex(gh); + else + gfs_assert_warn(gl->gl_sbd, FALSE); + + /* Waiting to demote the lock, or drop greedy status */ + } else if (!list_empty(&gl->gl_waiters2) && + !test_bit(GLF_SKIP_WAITERS2, &gl->gl_flags)) { + gh = list_entry(gl->gl_waiters2.next, + struct gfs_holder, gh_list); + + if (test_bit(HIF_DEMOTE, &gh->gh_iflags)) + blocked = rq_demote(gh); + else if (test_bit(HIF_GREEDY, &gh->gh_iflags)) + blocked = rq_greedy(gh); + else + gfs_assert_warn(gl->gl_sbd, FALSE); + + /* Waiting to promote the lock */ + } else if (!list_empty(&gl->gl_waiters3)) { + gh = list_entry(gl->gl_waiters3.next, + struct gfs_holder, gh_list); + + if (test_bit(HIF_PROMOTE, &gh->gh_iflags)) + blocked = rq_promote(gh); + else + gfs_assert_warn(gl->gl_sbd, FALSE); + + } else + break; + + if (blocked) + break; + } +} + +/** + * lock_on_glock - acquire a local lock on a glock (structure) + * @gl: the glock + * + * Gives caller exclusive access to manipulate a glock structure. + * Has nothing to do with inter-node lock state or GL_LOCAL_EXCL! + * + * If structure already locked, places temporary holder structure on glock's + * wait-for-exclusive-access queue, and blocks until exclusive access granted. + */ + +static void +lock_on_glock(struct gfs_glock *gl) +{ + struct gfs_holder gh; + + gfs_holder_init(gl, 0, 0, &gh); + set_bit(HIF_MUTEX, &gh.gh_iflags); + + spin_lock(&gl->gl_spin); + if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) + list_add_tail(&gh.gh_list, &gl->gl_waiters1); + else + complete(&gh.gh_wait); + spin_unlock(&gl->gl_spin); + + wait_for_completion(&gh.gh_wait); + gfs_holder_uninit(&gh); +} + +/** + * trylock_on_glock - try to acquire a local lock on a glock (structure) + * @gl: the glock + * + * Returns: TRUE if the glock is acquired + * + * Tries to give caller exclusive access to manipulate a glock structure. + * Has nothing to do with inter-node lock state or LOCAL_EXCL! + * + * If structure already locked, does not block to wait; returns FALSE. + */ + +static int +trylock_on_glock(struct gfs_glock *gl) +{ + int acquired = TRUE; + + spin_lock(&gl->gl_spin); + if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) + acquired = FALSE; + spin_unlock(&gl->gl_spin); + + return acquired; +} + +/** + * unlock_on_glock - release a local lock on a glock (structure) + * @gl: the glock + * + * Caller is done manipulating glock structure. + * Service any others waiting for exclusive access. + */ + +static void +unlock_on_glock(struct gfs_glock *gl) +{ + spin_lock(&gl->gl_spin); + clear_bit(GLF_LOCK, &gl->gl_flags); + run_queue(gl); + spin_unlock(&gl->gl_spin); +} + +/** + * handle_callback - add a demote request to a lock's queue + * @gl: the glock + * @state: the state the caller wants us to change to + * + * Called when we learn that another node needs a lock held by this node, + * or when this node simply wants to drop a lock as soon as it's done with + * it (NOCACHE flag), or dump a glock out of glock cache (reclaim it). + * + * We are told the @state that will satisfy the needs of the caller, so + * we can ask for a demote to that state. + * + * If another demote request is already on the queue for a different state, just + * set its request to UNLOCK (and don't bother queueing a request for us). + * This consolidates LM requests and moves the lock to the least restrictive + * state, so it will be compatible with whatever reason we were called. + * No need to be too smart here. Demotes between the shared and deferred + * states will often fail, so don't even try. + * + * Otherwise, queue a demote request to the requested state. + */ + +static void +handle_callback(struct gfs_glock *gl, unsigned int state) +{ + struct list_head *tmp, *head; + struct gfs_holder *gh, *new_gh = NULL; + + if (gfs_assert_warn(gl->gl_sbd, state != LM_ST_EXCLUSIVE)) + return; + + restart: + spin_lock(&gl->gl_spin); + + /* If another queued demote request is for a different state, + set its request to UNLOCKED */ + for (head = &gl->gl_waiters2, tmp = head->next; + tmp != head; + tmp = tmp->next) { + gh = list_entry(tmp, struct gfs_holder, gh_list); + if (test_bit(HIF_DEMOTE, &gh->gh_iflags) && + gl->gl_req_gh != gh) { + if (gh->gh_state != state) + gh->gh_state = LM_ST_UNLOCKED; + goto out; + } + } + + /* pass 2; add new holder to glock's demote request queue */ + if (new_gh) { + list_add_tail(&new_gh->gh_list, &gl->gl_waiters2); + new_gh = NULL; + + /* pass 1; set up a new holder struct for a demote request, then + check again to see if another process added a demote request + while we were preparing this one. */ + } else { + spin_unlock(&gl->gl_spin); + + RETRY_MALLOC(new_gh = gfs_holder_get(gl, state, LM_FLAG_TRY), + new_gh); + set_bit(HIF_DEMOTE, &new_gh->gh_iflags); + set_bit(HIF_DEALLOC, &new_gh->gh_iflags); + new_gh->gh_owner = NULL; + + goto restart; + } + + out: + spin_unlock(&gl->gl_spin); + + if (new_gh) + gfs_holder_put(new_gh); +} + +/** + * state_change - record that the glock is now in a different state + * @gl: the glock + * @new_state the new state + * + */ + +static void +state_change(struct gfs_glock *gl, unsigned int new_state) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + int held1, held2; + + held1 = (gl->gl_state != LM_ST_UNLOCKED); + held2 = (new_state != LM_ST_UNLOCKED); + + if (held1 != held2) { + if (held2) { + atomic_inc(&sdp->sd_glock_held_count); + glock_hold(gl); + } else { + atomic_dec(&sdp->sd_glock_held_count); + glock_put(gl); + } + } + + gl->gl_state = new_state; +} + +/** + * xmote_bh - Called after the lock module is done acquiring a lock + * @gl: The glock in question + * @ret: the int returned from the lock module + * + */ + +static void +xmote_bh(struct gfs_glock *gl, unsigned int ret) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_glock_operations *glops = gl->gl_ops; + struct gfs_holder *gh = gl->gl_req_gh; + int prev_state = gl->gl_state; + int op_done = TRUE; + + gfs_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags)); + gfs_assert_warn(sdp, queue_empty(gl, &gl->gl_holders)); + gfs_assert_warn(sdp, !(ret & LM_OUT_ASYNC)); + + state_change(gl, ret & LM_OUT_ST_MASK); + + if (prev_state != LM_ST_UNLOCKED && !(ret & LM_OUT_CACHEABLE)) { + if (glops->go_inval) + glops->go_inval(gl, DIO_METADATA | DIO_DATA); + } else if (gl->gl_state == LM_ST_DEFERRED) { + /* We might not want to do this here. + Look at moving to the inode glops. */ + if (glops->go_inval) + glops->go_inval(gl, DIO_DATA); + } + + /* Deal with each possible exit condition */ + + if (!gh) + gl->gl_stamp = jiffies; + + else if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) { + spin_lock(&gl->gl_spin); + list_del_init(&gh->gh_list); + gh->gh_error = -EIO; + if (test_bit(HIF_RECURSE, &gh->gh_iflags)) + do_unrecurse(gh); + spin_unlock(&gl->gl_spin); + + } else if (test_bit(HIF_DEMOTE, &gh->gh_iflags)) { + spin_lock(&gl->gl_spin); + list_del_init(&gh->gh_list); + if (gl->gl_state == gh->gh_state || + gl->gl_state == LM_ST_UNLOCKED) + gh->gh_error = 0; + else { + if (gfs_assert_warn(sdp, gh->gh_flags & + (LM_FLAG_TRY | LM_FLAG_TRY_1CB)) == -1) + printk("GFS: fsid=%s: ret = 0x%.8X\n", + sdp->sd_fsname, ret); + gh->gh_error = GLR_TRYFAILED; + } + spin_unlock(&gl->gl_spin); + + if (ret & LM_OUT_CANCELED) + handle_callback(gl, LM_ST_UNLOCKED); /* Lame */ + + } else if (ret & LM_OUT_CANCELED) { + spin_lock(&gl->gl_spin); + list_del_init(&gh->gh_list); + gh->gh_error = GLR_CANCELED; + if (test_bit(HIF_RECURSE, &gh->gh_iflags)) + do_unrecurse(gh); + spin_unlock(&gl->gl_spin); + + } else if (relaxed_state_ok(gl->gl_state, gh->gh_state, gh->gh_flags)) { + spin_lock(&gl->gl_spin); + list_move_tail(&gh->gh_list, &gl->gl_holders); + gh->gh_error = 0; + set_bit(HIF_HOLDER, &gh->gh_iflags); + spin_unlock(&gl->gl_spin); + + set_bit(HIF_FIRST, &gh->gh_iflags); + + op_done = FALSE; + + } else if (gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB)) { + spin_lock(&gl->gl_spin); + list_del_init(&gh->gh_list); + gh->gh_error = GLR_TRYFAILED; + if (test_bit(HIF_RECURSE, &gh->gh_iflags)) + do_unrecurse(gh); + spin_unlock(&gl->gl_spin); + + } else { + if (gfs_assert_withdraw(sdp, FALSE) == -1) + printk("GFS: fsid=%s: ret = 0x%.8X\n", + sdp->sd_fsname, ret); + } + + if (glops->go_xmote_bh) + glops->go_xmote_bh(gl); + + if (op_done) { + spin_lock(&gl->gl_spin); + gl->gl_req_gh = NULL; + gl->gl_req_bh = NULL; + clear_bit(GLF_LOCK, &gl->gl_flags); + run_queue(gl); + spin_unlock(&gl->gl_spin); + } + + glock_put(gl); + + if (gh) { + if (test_bit(HIF_DEALLOC, &gh->gh_iflags)) + gfs_holder_put(gh); + else + complete(&gh->gh_wait); + } +} + +/** + * gfs_glock_xmote_th - Call into the lock module to acquire or change a glock + * @gl: The glock in question + * @state: the requested state + * @flags: modifier flags to the lock call + * + * Used to acquire a new glock, or to change an already-acquired glock to + * more/less restrictive state (other than LM_ST_UNLOCKED). + * + * *Not* used to unlock a glock; use gfs_glock_drop_th() for that. + */ + +void +gfs_glock_xmote_th(struct gfs_glock *gl, unsigned int state, int flags) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_glock_operations *glops = gl->gl_ops; + int lck_flags = flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB | + LM_FLAG_NOEXP | LM_FLAG_ANY | + LM_FLAG_PRIORITY); + unsigned int lck_ret; + + gfs_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags)); + gfs_assert_warn(sdp, queue_empty(gl, &gl->gl_holders)); + gfs_assert_warn(sdp, state != LM_ST_UNLOCKED); + gfs_assert_warn(sdp, state != gl->gl_state); + + /* Current state EX, may need to sync log/data/metadata to disk */ + if (gl->gl_state == LM_ST_EXCLUSIVE) { + if (glops->go_sync) + glops->go_sync(gl, DIO_METADATA | DIO_DATA); + } + + glock_hold(gl); + gl->gl_req_bh = xmote_bh; + + atomic_inc(&sdp->sd_lm_lock_calls); + + lck_ret = gfs_lm_lock(sdp, gl->gl_lock, + gl->gl_state, state, + lck_flags); + + if (gfs_assert_withdraw(sdp, !(lck_ret & LM_OUT_ERROR))) + goto out; + + if (lck_ret & LM_OUT_ASYNC) + gfs_assert_warn(sdp, lck_ret == LM_OUT_ASYNC); + else + xmote_bh(gl, lck_ret); + out: + return; +} + +/** + * drop_bh - Called after a lock module unlock completes + * @gl: the glock + * @ret: the return status + * + * Doesn't wake up the process waiting on the struct gfs_holder (if any) + * Doesn't drop the reference on the glock the top half took out + * + */ + +static void +drop_bh(struct gfs_glock *gl, unsigned int ret) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_glock_operations *glops = gl->gl_ops; + struct gfs_holder *gh = gl->gl_req_gh; + + clear_bit(GLF_PREFETCH, &gl->gl_flags); + + gfs_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags)); + gfs_assert_warn(sdp, queue_empty(gl, &gl->gl_holders)); + gfs_assert_warn(sdp, !ret); + + state_change(gl, LM_ST_UNLOCKED); + + if (glops->go_inval) + glops->go_inval(gl, DIO_METADATA | DIO_DATA); + + if (gh) { + spin_lock(&gl->gl_spin); + list_del_init(&gh->gh_list); + gh->gh_error = 0; + spin_unlock(&gl->gl_spin); + } + + if (glops->go_drop_bh) + glops->go_drop_bh(gl); + + spin_lock(&gl->gl_spin); + gl->gl_req_gh = NULL; + gl->gl_req_bh = NULL; + clear_bit(GLF_LOCK, &gl->gl_flags); + run_queue(gl); + spin_unlock(&gl->gl_spin); + + glock_put(gl); + + if (gh) { + if (test_bit(HIF_DEALLOC, &gh->gh_iflags)) + gfs_holder_put(gh); + else + complete(&gh->gh_wait); + } +} + +/** + * gfs_glock_drop_th - call into the lock module to unlock a lock + * @gl: the glock + * + */ + +void +gfs_glock_drop_th(struct gfs_glock *gl) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_glock_operations *glops = gl->gl_ops; + unsigned int ret; + + gfs_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags)); + gfs_assert_warn(sdp, queue_empty(gl, &gl->gl_holders)); + gfs_assert_warn(sdp, gl->gl_state != LM_ST_UNLOCKED); + + /* Leaving state EX, may need to sync log/data/metadata to disk */ + if (gl->gl_state == LM_ST_EXCLUSIVE) { + if (glops->go_sync) + glops->go_sync(gl, DIO_METADATA | DIO_DATA); + } + + glock_hold(gl); + gl->gl_req_bh = drop_bh; + + atomic_inc(&sdp->sd_lm_unlock_calls); + + ret = gfs_lm_unlock(sdp, gl->gl_lock, gl->gl_state); + + if (gfs_assert_withdraw(sdp, !(ret & LM_OUT_ERROR))) + goto out; + + if (!ret) + drop_bh(gl, ret); + else + gfs_assert_warn(sdp, ret == LM_OUT_ASYNC); + out: + return; +} + +/** + * do_cancels - cancel requests for locks stuck waiting on an expire flag + * @gh: the LM_FLAG_PRIORITY holder waiting to acquire the lock + * + * Don't cancel GL_NOCANCEL requests. + */ + +static void +do_cancels(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + + spin_lock(&gl->gl_spin); + + while (gl->gl_req_gh != gh && + !test_bit(HIF_HOLDER, &gh->gh_iflags) && + !list_empty(&gh->gh_list)) { + if (gl->gl_req_bh && + !(gl->gl_req_gh && + (gl->gl_req_gh->gh_flags & GL_NOCANCEL))) { + spin_unlock(&gl->gl_spin); + gfs_lm_cancel(gl->gl_sbd, gl->gl_lock); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ / 10); + spin_lock(&gl->gl_spin); + } else { + spin_unlock(&gl->gl_spin); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ / 10); + spin_lock(&gl->gl_spin); + } + } + + spin_unlock(&gl->gl_spin); +} + +/** + * glock_wait_internal - wait on a glock acquisition + * @gh: the glock holder + * + * Returns: 0 on success + */ + +static int +glock_wait_internal(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_glock_operations *glops = gl->gl_ops; + int error = 0; + + if (test_bit(HIF_ABORTED, &gh->gh_iflags)) + return -EIO; + + if (gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB)) { + spin_lock(&gl->gl_spin); + if (gl->gl_req_gh != gh && + !test_bit(HIF_HOLDER, &gh->gh_iflags) && + !list_empty(&gh->gh_list)) { + list_del_init(&gh->gh_list); + gh->gh_error = GLR_TRYFAILED; + if (test_bit(HIF_RECURSE, &gh->gh_iflags)) + do_unrecurse(gh); + run_queue(gl); + spin_unlock(&gl->gl_spin); + return GLR_TRYFAILED; + } + spin_unlock(&gl->gl_spin); + } + + if ((gh->gh_flags & LM_FLAG_PRIORITY) && + !(gh->gh_flags & GL_NOCANCEL_OTHER)) + do_cancels(gh); + + wait_for_completion(&gh->gh_wait); + + if (gh->gh_error) + return gh->gh_error; + + gfs_assert_withdraw(sdp, test_bit(HIF_HOLDER, &gh->gh_iflags)); + gfs_assert_withdraw(sdp, relaxed_state_ok(gl->gl_state, + gh->gh_state, + gh->gh_flags)); + + if (test_bit(HIF_FIRST, &gh->gh_iflags)) { + gfs_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags)); + + if (glops->go_lock) { + error = glops->go_lock(gl, gh->gh_flags); + if (error) { + spin_lock(&gl->gl_spin); + list_del_init(&gh->gh_list); + gh->gh_error = error; + if (test_and_clear_bit(HIF_RECURSE, &gh->gh_iflags)) + do_unrecurse(gh); + spin_unlock(&gl->gl_spin); + } + } + + spin_lock(&gl->gl_spin); + gl->gl_req_gh = NULL; + gl->gl_req_bh = NULL; + clear_bit(GLF_LOCK, &gl->gl_flags); + if (test_bit(HIF_RECURSE, &gh->gh_iflags)) + handle_recurse(gh); + run_queue(gl); + spin_unlock(&gl->gl_spin); + } + + return error; +} + +/** + * add_to_queue - Add a holder to the wait-for-promotion queue or holder list + * (according to recursion) + * @gh: the holder structure to add + * + * If the hold requestor's process already has a granted lock (on holder list), + * and this new request is compatible, go ahead and grant it, adding this + * new holder to the glock's holder list. + * + * If the hold requestor's process has earlier requested a lock, and is still + * waiting for it to be granted, and this new request is compatible with + * the earlier one, they can be handled at the same time when the request + * is finally granted. Mark both (all) with RECURSE flags, and add new + * holder to wait-for-promotion queue. + * + * If there is no previous holder from this process (on holder list or wait- + * for-promotion queue), simply add new holder to wait-for-promotion queue. + */ + +static void +add_to_queue(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + struct gfs_sbd *sdp = gl->gl_sbd; + struct list_head *tmp, *head; + struct gfs_holder *tmp_gh; + + if (gh->gh_owner) { + /* Search through glock's holders list to see if this process + already holds a granted lock. */ + for (head = &gl->gl_holders, tmp = head->next; + tmp != head; + tmp = tmp->next) { + tmp_gh = list_entry(tmp, struct gfs_holder, gh_list); + if (tmp_gh->gh_owner == gh->gh_owner) { + /* Make sure pre-existing holder is compatible + with this new one. */ + if (gfs_assert_warn(sdp, (gh->gh_flags & LM_FLAG_ANY) || + !(tmp_gh->gh_flags & LM_FLAG_ANY)) || + gfs_assert_warn(sdp, (tmp_gh->gh_flags & GL_LOCAL_EXCL) || + !(gh->gh_flags & GL_LOCAL_EXCL)) || + gfs_assert_warn(sdp, relaxed_state_ok(gl->gl_state, + gh->gh_state, + gh->gh_flags))) + goto fail; + + /* We're good! Grant the hold. */ + list_add_tail(&gh->gh_list, &gl->gl_holders); + set_bit(HIF_HOLDER, &gh->gh_iflags); + + gh->gh_error = 0; + complete(&gh->gh_wait); + + return; + } + } + + /* If not, Search through glock's wait-for-promotion list to + see if this process already is waiting for a grant. */ + for (head = &gl->gl_waiters3, tmp = head->next; + tmp != head; + tmp = tmp->next) { + tmp_gh = list_entry(tmp, struct gfs_holder, gh_list); + if (tmp_gh->gh_owner == gh->gh_owner) { + /* Yes, make sure it is compatible with new */ + if (gfs_assert_warn(sdp, test_bit(HIF_PROMOTE, + &tmp_gh->gh_iflags)) || + gfs_assert_warn(sdp, (gh->gh_flags & LM_FLAG_ANY) || + !(tmp_gh->gh_flags & LM_FLAG_ANY)) || + gfs_assert_warn(sdp, (tmp_gh->gh_flags & GL_LOCAL_EXCL) || + !(gh->gh_flags & GL_LOCAL_EXCL)) || + gfs_assert_warn(sdp, relaxed_state_ok(tmp_gh->gh_state, + gh->gh_state, + gh->gh_flags))) + goto fail; + + /* OK, make sure they're marked, so + * when one gets granted, the other will too. */ + set_bit(HIF_RECURSE, &gh->gh_iflags); + set_bit(HIF_RECURSE, &tmp_gh->gh_iflags); + + list_add_tail(&gh->gh_list, &gl->gl_waiters3); + + return; + } + } + } + + /* Else, no recursion ... + If high priority request, add to head of promote queue, else tail */ + if (gh->gh_flags & LM_FLAG_PRIORITY) + list_add(&gh->gh_list, &gl->gl_waiters3); + else + list_add_tail(&gh->gh_list, &gl->gl_waiters3); + + return; + + fail: + set_bit(HIF_ABORTED, &gh->gh_iflags); +} + +/** + * gfs_glock_nq - enqueue a struct gfs_holder onto a glock (acquire a glock) + * @gh: the holder structure + * + * if (gh->gh_flags & GL_ASYNC), this never returns an error + * + * Returns: 0, GLR_TRYFAILED, or errno on failure + * + * Rules: + * @gh must not be already attached to a glock. + * Don't ask for UNLOCKED state (use gfs_glock_dq() for that). + * LM_FLAG_ANY (liberal) and GL_EXACT (restrictive) are mutually exclusive. + */ + +int +gfs_glock_nq(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + struct gfs_sbd *sdp = gl->gl_sbd; + int error = 0; + + atomic_inc(&sdp->sd_glock_nq_calls); + + restart: + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) || + gfs_assert_warn(sdp, list_empty(&gh->gh_list)) || + gfs_assert_warn(sdp, gh->gh_state != LM_ST_UNLOCKED) || + gfs_assert_warn(sdp, (gh->gh_flags & (LM_FLAG_ANY | GL_EXACT)) != + (LM_FLAG_ANY | GL_EXACT))) { + set_bit(HIF_ABORTED, &gh->gh_iflags); + return -EIO; + } + + set_bit(HIF_PROMOTE, &gh->gh_iflags); + + spin_lock(&gl->gl_spin); + add_to_queue(gh); + run_queue(gl); + spin_unlock(&gl->gl_spin); + + if (!(gh->gh_flags & GL_ASYNC)) { + error = glock_wait_internal(gh); + if (error == GLR_CANCELED) { + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ); + goto restart; + } + } + + clear_bit(GLF_PREFETCH, &gl->gl_flags); + + return error; +} + +/** + * gfs_glock_poll - poll to see if an async request has been completed + * @gh: the holder + * + * Returns: TRUE if the request is ready to be gfs_glock_wait()ed on + */ + +int +gfs_glock_poll(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + int ready = FALSE; + + gfs_assert_warn(gl->gl_sbd, gh->gh_flags & GL_ASYNC); + + spin_lock(&gl->gl_spin); + + if (test_bit(HIF_HOLDER, &gh->gh_iflags)) + ready = TRUE; + else if (list_empty(&gh->gh_list)) { + if (gh->gh_error == GLR_CANCELED) { + spin_unlock(&gl->gl_spin); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ); + if (gfs_glock_nq(gh)) + return TRUE; + return FALSE; + } else + ready = TRUE; + } + + spin_unlock(&gl->gl_spin); + + return ready; +} + +/** + * gfs_glock_wait - wait for a lock acquisition that ended in a GLR_ASYNC + * @gh: the holder structure + * + * Returns: 0, GLR_TRYFAILED, or errno on failure + */ + +int +gfs_glock_wait(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + int error; + + gfs_assert_warn(gl->gl_sbd, gh->gh_flags & GL_ASYNC); + + error = glock_wait_internal(gh); + if (error == GLR_CANCELED) { + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ); + gh->gh_flags &= ~GL_ASYNC; + error = gfs_glock_nq(gh); + } + + return error; +} + +/** + * gfs_glock_dq - dequeue a struct gfs_holder from a glock (release a glock) + * @gh: the glock holder + * + * This releases a local process' hold on a glock, and services other waiters. + * If this is the last holder on this node, calls glock operation go_unlock(), + * and go_sync() if requested by glock's GL_SYNC flag. + * If glock's GL_NOCACHE flag is set, requests demotion to unlock the inter- + * node lock now, rather than caching the glock for later use. + * Otherwise, this function does *not* release the glock at inter-node scope. + * The glock will stay in glock cache until: + * -- This node uses it again (extending residence in glock cache), or + * -- Another node asks (via callback) for the lock, or + * -- The glock sits unused in glock cache for a while, and the cleanup + * daemons (gfs_scand and gfs_glockd) reclaim it. + */ + +void +gfs_glock_dq(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_glock_operations *glops = gl->gl_ops; + + atomic_inc(&gl->gl_sbd->sd_glock_dq_calls); + + gfs_assert_withdraw(sdp, !queue_empty(gl, &gh->gh_list)); + gfs_assert_withdraw(sdp, test_bit(HIF_HOLDER, &gh->gh_iflags)); + + if (gh->gh_flags & GL_SYNC) + set_bit(GLF_SYNC, &gl->gl_flags); + + /* Don't cache glock; request demote to unlock at inter-node scope */ + if (gh->gh_flags & GL_NOCACHE && gl->gl_holders.next == &gh->gh_list && + gl->gl_holders.prev == &gh->gh_list) + /* There's a race here. If there are two holders, and both + * are dq'ed at almost the same time, you can't guarantee that + * you will call handle_callback. Fixing this will require + * some refactoring */ + handle_callback(gl, LM_ST_UNLOCKED); + + lock_on_glock(gl); + + spin_lock(&gl->gl_spin); + list_del_init(&gh->gh_list); + + /* If last holder, do appropriate glock operations, set cache timer */ + if (list_empty(&gl->gl_holders)) { + spin_unlock(&gl->gl_spin); + + if (glops->go_unlock) + glops->go_unlock(gl, gh->gh_flags); + + /* Do "early" sync, if requested by holder */ + if (test_bit(GLF_SYNC, &gl->gl_flags)) { + if (glops->go_sync) + glops->go_sync(gl, + DIO_METADATA | + DIO_DATA | + DIO_INVISIBLE); + } + + gl->gl_stamp = jiffies; + + spin_lock(&gl->gl_spin); + } + + clear_bit(GLF_LOCK, &gl->gl_flags); + run_queue(gl); + spin_unlock(&gl->gl_spin); +} + +/** + * gfs_glock_prefetch - Try to prefetch a glock + * @gl: the glock + * @state: the state to prefetch in + * @flags: flags passed to go_xmote_th() + * + * Bypass request queues of glock (i.e. no holder involved), and directly call + * go_xmote_th() to ask lock module for lock, to put in glock cache for + * later use. + * + * Will not prefetch the lock (no need to) if a process on this node is already + * interested in the lock, or if it's sitting in glock cache in a compatible + * state. + * + * Rules: + * Don't ask for UNLOCKED state (use gfs_glock_dq() for that). + * LM_FLAG_ANY (liberal) and GL_EXACT (restrictive) are mutually exclusive. + */ + +void +gfs_glock_prefetch(struct gfs_glock *gl, unsigned int state, int flags) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_glock_operations *glops = gl->gl_ops; + + if (gfs_assert_warn(sdp, state != LM_ST_UNLOCKED) || + gfs_assert_warn(sdp, (flags & (LM_FLAG_ANY | GL_EXACT)) != + (LM_FLAG_ANY | GL_EXACT))) + return; + + spin_lock(&gl->gl_spin); + + /* Should we prefetch? */ + if (test_bit(GLF_LOCK, &gl->gl_flags) || + !list_empty(&gl->gl_holders) || + !list_empty(&gl->gl_waiters1) || + !list_empty(&gl->gl_waiters2) || + !list_empty(&gl->gl_waiters3) || + relaxed_state_ok(gl->gl_state, state, flags)) { + spin_unlock(&gl->gl_spin); + return; + } + + /* Let bottom half know we're prefetching, ask lock module for lock */ + set_bit(GLF_PREFETCH, &gl->gl_flags); + + if (gfs_assert_warn(sdp, !gl->gl_req_gh)) + gl->gl_req_gh = NULL; + set_bit(GLF_LOCK, &gl->gl_flags); + spin_unlock(&gl->gl_spin); + + glops->go_xmote_th(gl, state, flags); + + atomic_inc(&gl->gl_sbd->sd_glock_prefetch_calls); +} + +/** + * gfs_glock_force_drop - Force a glock to be uncached + * @gl: the glock + * + */ + +void +gfs_glock_force_drop(struct gfs_glock *gl) +{ + struct gfs_holder gh; + + gfs_holder_init(gl, LM_ST_UNLOCKED, 0, &gh); + set_bit(HIF_DEMOTE, &gh.gh_iflags); + gh.gh_owner = NULL; + + spin_lock(&gl->gl_spin); + list_add_tail(&gh.gh_list, &gl->gl_waiters2); + run_queue(gl); + spin_unlock(&gl->gl_spin); + + wait_for_completion(&gh.gh_wait); + gfs_holder_uninit(&gh); +} + +/** + * greedy_work - + * @data: + * + */ + +static void +greedy_work(struct work_struct *work) +{ + struct greedy *gr = container_of(work, struct greedy, gr_work.work); + struct gfs_holder *gh = &gr->gr_gh; + struct gfs_glock *gl = gh->gh_gl; + struct gfs_glock_operations *glops = gl->gl_ops; + + clear_bit(GLF_SKIP_WAITERS2, &gl->gl_flags); + + if (glops->go_greedy) + glops->go_greedy(gl); + + spin_lock(&gl->gl_spin); + + if (list_empty(&gl->gl_waiters2)) { + clear_bit(GLF_GREEDY, &gl->gl_flags); + spin_unlock(&gl->gl_spin); + gfs_holder_uninit(gh); + kfree(gr); + } else { + glock_hold(gl); + list_add_tail(&gh->gh_list, &gl->gl_waiters2); + run_queue(gl); + spin_unlock(&gl->gl_spin); + glock_put(gl); + } +} + +/** + * gfs_glock_be_greedy - + * @gl: + * @time: + * + * Returns: 0 if go_greedy will be called, 1 otherwise + */ + +int +gfs_glock_be_greedy(struct gfs_glock *gl, unsigned int time) +{ + struct greedy *gr; + struct gfs_holder *gh; + + if (!time || + gl->gl_sbd->sd_args.ar_localcaching || + test_and_set_bit(GLF_GREEDY, &gl->gl_flags)) + return 1; + + gr = kmalloc(sizeof(struct greedy), GFP_KERNEL); + if (!gr) { + clear_bit(GLF_GREEDY, &gl->gl_flags); + return 1; + } + gh = &gr->gr_gh; + + gfs_holder_init(gl, 0, 0, gh); + set_bit(HIF_GREEDY, &gh->gh_iflags); + gh->gh_owner = NULL; + INIT_DELAYED_WORK(&gr->gr_work, greedy_work); + + set_bit(GLF_SKIP_WAITERS2, &gl->gl_flags); + schedule_delayed_work(&gr->gr_work, time); + + return 0; +} + +/** + * gfs_glock_nq_init - intialize a holder and enqueue it on a glock + * @gl: the glock + * @state: the state we're requesting + * @flags: the modifier flags + * @gh: the holder structure + * + * Returns: 0, GLR_*, or errno + */ + +int +gfs_glock_nq_init(struct gfs_glock *gl, unsigned int state, int flags, + struct gfs_holder *gh) +{ + int error; + + gfs_holder_init(gl, state, flags, gh); + + error = gfs_glock_nq(gh); + if (error) + gfs_holder_uninit(gh); + + return error; +} + +/** + * gfs_glock_dq_uninit - dequeue a holder from a glock and initialize it + * @gh: the holder structure + * + */ + +void +gfs_glock_dq_uninit(struct gfs_holder *gh) +{ + gfs_glock_dq(gh); + gfs_holder_uninit(gh); +} + +/** + * gfs_glock_nq_num - acquire a glock based on lock number + * @sdp: the filesystem + * @number: the lock number + * @glops: the glock operations for the type of glock + * @state: the state to acquire the glock in + * @flags: modifier flags for the aquisition + * @gh: the struct gfs_holder + * + * Returns: errno + */ + +int +gfs_glock_nq_num(struct gfs_sbd *sdp, + uint64_t number, struct gfs_glock_operations *glops, + unsigned int state, int flags, struct gfs_holder *gh) +{ + struct gfs_glock *gl; + int error; + + error = gfs_glock_get(sdp, number, glops, CREATE, &gl); + if (!error) { + error = gfs_glock_nq_init(gl, state, flags, gh); + glock_put(gl); + } + + return error; +} + +/** + * glock_compare - Compare two struct gfs_glock structures for sorting + * @arg_a: the first structure + * @arg_b: the second structure + * + */ + +static int +glock_compare(const void *arg_a, const void *arg_b) +{ + struct gfs_holder *gh_a = *(struct gfs_holder **)arg_a; + struct gfs_holder *gh_b = *(struct gfs_holder **)arg_b; + struct lm_lockname *a = &gh_a->gh_gl->gl_name; + struct lm_lockname *b = &gh_b->gh_gl->gl_name; + int ret = 0; + + if (a->ln_number > b->ln_number) + ret = 1; + else if (a->ln_number < b->ln_number) + ret = -1; + else { + if (gh_a->gh_state == LM_ST_SHARED && + gh_b->gh_state == LM_ST_EXCLUSIVE) + ret = 1; + else if (!(gh_a->gh_flags & GL_LOCAL_EXCL) && + (gh_b->gh_flags & GL_LOCAL_EXCL)) + ret = 1; + } + + return ret; +} + +/** + * nq_m_sync - synchonously acquire more than one glock in deadlock free order + * @num_gh: the number of structures + * @ghs: an array of struct gfs_holder structures + * + * Returns: 0 on success (all glocks acquired), errno on failure (no glocks acquired) + */ + +static int +nq_m_sync(unsigned int num_gh, struct gfs_holder *ghs, struct gfs_holder **p) +{ + unsigned int x; + int error = 0; + + for (x = 0; x < num_gh; x++) + p[x] = &ghs[x]; + + gfs_sort(p, num_gh, sizeof(struct gfs_holder *), glock_compare); + + for (x = 0; x < num_gh; x++) { + p[x]->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); + + error = gfs_glock_nq(p[x]); + if (error) { + while (x--) + gfs_glock_dq(p[x]); + break; + } + } + + return error; +} + +/** + * gfs_glock_nq_m - acquire multiple glocks + * @num_gh: the number of structures + * @ghs: an array of struct gfs_holder structures + * + * Figure out how big an impact this function has. Either: + * 1) Replace this code with code that calls gfs_glock_prefetch() + * 2) Forget async stuff and just call nq_m_sync() + * 3) Leave it like it is + * + * Returns: 0 on success (all glocks acquired), errno on failure (no glocks acquired) + */ + +int +gfs_glock_nq_m(unsigned int num_gh, struct gfs_holder *ghs) +{ + int *e; + unsigned int x; + int borked = FALSE, serious = 0; + int error = 0; + + if (!num_gh) + return 0; + + /* For just one gh, do request synchronously */ + if (num_gh == 1) { + ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); + return gfs_glock_nq(ghs); + } + + /* using sizeof(struct gfs_holder *) instead of sizeof(int), because + * we're also using this memory for nq_m_sync and ints should never be + * larger than pointers.... I hope + */ + e = kmalloc(num_gh * sizeof(struct gfs_holder *), GFP_KERNEL); + if (!e) + return -ENOMEM; + + /* Send off asynchronous requests */ + for (x = 0; x < num_gh; x++) { + ghs[x].gh_flags |= LM_FLAG_TRY | GL_ASYNC; + error = gfs_glock_nq(&ghs[x]); + if (error) { + borked = TRUE; + serious = error; + num_gh = x; + break; + } + } + + /* Wait for all to complete */ + for (x = 0; x < num_gh; x++) { + error = e[x] = glock_wait_internal(&ghs[x]); + if (error) { + borked = TRUE; + if (error != GLR_TRYFAILED && error != GLR_CANCELED) + serious = error; + } + } + + /* If all good, done! */ + if (!borked) { + kfree(e); + return 0; + } + + for (x = 0; x < num_gh; x++) + if (!e[x]) + gfs_glock_dq(&ghs[x]); + + if (serious) + error = serious; + else { + for (x = 0; x < num_gh; x++) + gfs_holder_reinit(ghs[x].gh_state, ghs[x].gh_flags, + &ghs[x]); + error = nq_m_sync(num_gh, ghs, (struct gfs_holder **)e); + } + + kfree(e); + return error; +} + +/** + * gfs_glock_dq_m - release multiple glocks + * @num_gh: the number of structures + * @ghs: an array of struct gfs_holder structures + * + */ + +void +gfs_glock_dq_m(unsigned int num_gh, struct gfs_holder *ghs) +{ + unsigned int x; + + for (x = 0; x < num_gh; x++) + gfs_glock_dq(&ghs[x]); +} + +/** + * gfs_glock_prefetch_num - prefetch a glock based on lock number + * @sdp: the filesystem + * @number: the lock number + * @glops: the glock operations for the type of glock + * @state: the state to acquire the glock in + * @flags: modifier flags for the aquisition + * + * Returns: errno + */ + +void +gfs_glock_prefetch_num(struct gfs_sbd *sdp, + uint64_t number, struct gfs_glock_operations *glops, + unsigned int state, int flags) +{ + struct gfs_glock *gl; + int error; + + if (atomic_read(&sdp->sd_reclaim_count) < gfs_tune_get(sdp, gt_reclaim_limit)) { + error = gfs_glock_get(sdp, number, glops, CREATE, &gl); + if (!error) { + gfs_glock_prefetch(gl, state, flags); + glock_put(gl); + } + } +} + +/** + * gfs_lvb_hold - attach a LVB from a glock + * @gl: The glock in question + * + */ + +int +gfs_lvb_hold(struct gfs_glock *gl) +{ + int error; + + lock_on_glock(gl); + + if (!atomic_read(&gl->gl_lvb_count)) { + gfs_assert_warn(gl->gl_sbd, !gl->gl_lvb); + error = gfs_lm_hold_lvb(gl->gl_sbd, gl->gl_lock, &gl->gl_lvb); + if (error) { + unlock_on_glock(gl); + return error; + } + glock_hold(gl); + } + atomic_inc(&gl->gl_lvb_count); + + unlock_on_glock(gl); + + return 0; +} + +/** + * gfs_lvb_unhold - detach a LVB from a glock + * @gl: The glock in question + * + */ + +void +gfs_lvb_unhold(struct gfs_glock *gl) +{ + glock_hold(gl); + + lock_on_glock(gl); + + if (!gfs_assert_warn(gl->gl_sbd, atomic_read(&gl->gl_lvb_count) > 0) && + atomic_dec_and_test(&gl->gl_lvb_count)) { + gfs_assert_warn(gl->gl_sbd, gl->gl_lvb); + gfs_lm_unhold_lvb(gl->gl_sbd, gl->gl_lock, gl->gl_lvb); + gl->gl_lvb = NULL; + glock_put(gl); + } + + unlock_on_glock(gl); + + glock_put(gl); +} + +#if 0 +/** + * gfs_lvb_sync - sync a LVB + * @gl: The glock in question + * + */ + +void +gfs_lvb_sync(struct gfs_glock *gl) +{ + if (gfs_assert_warn(gl->gl_sbd, atomic_read(&gl->gl_lvb_count))) + return; + + lock_on_glock(gl); + + if (!gfs_assert_warn(gl->gl_sbd, gfs_glock_is_held_excl(gl))) + gfs_lm_sync_lvb(gl->gl_sbd, gl->gl_lock, gl->gl_lvb); + + unlock_on_glock(gl); +} +#endif + +/** + * blocking_cb - + * @sdp: + * @name: + * @state: + * + */ + +void +blocking_cb(struct gfs_sbd *sdp, struct lm_lockname *name, unsigned int state) +{ + struct gfs_glock *gl; + + gl = gfs_glock_find(sdp, name); + if (!gl) + return; + + if (gl->gl_ops->go_callback) + gl->gl_ops->go_callback(gl, state); + handle_callback(gl, state); + + spin_lock(&gl->gl_spin); + run_queue(gl); + spin_unlock(&gl->gl_spin); + + glock_put(gl); +} + +/** + * gfs_glock_cb - Callback used by locking module + * @fsdata: Pointer to the superblock + * @type: Type of callback + * @data: Type dependent data pointer + * + * Called by the locking module when it wants to tell us something. + * Either we need to drop a lock, one of our ASYNC requests completed, or + * another client expired (crashed/died) and we need to recover its journal. + * If another node needs a lock held by this node, we queue a request to demote + * our lock to a state compatible with that needed by the other node. + * For example, if the other node needs EXCLUSIVE, we request UNLOCKED. + * SHARED and DEFERRED modes can be shared with other nodes, so we request + * accordingly. + * Once all incompatible holders on this node are done with the lock, the + * queued request will cause run_queue() to call the lock module to demote + * our lock to a compatible state, allowing the other node to grab the lock. + */ + +void +gfs_glock_cb(void *fsdata, unsigned int type, void *data) +{ + struct gfs_sbd *sdp = fsdata; + + atomic_inc(&sdp->sd_lm_callbacks); + + switch (type) { + case LM_CB_NEED_E: + blocking_cb(sdp, (struct lm_lockname *)data, LM_ST_UNLOCKED); + return; + + case LM_CB_NEED_D: + blocking_cb(sdp, (struct lm_lockname *)data, LM_ST_DEFERRED); + return; + + case LM_CB_NEED_S: + blocking_cb(sdp, (struct lm_lockname *)data, LM_ST_SHARED); + return; + + case LM_CB_ASYNC: { + struct lm_async_cb *async = (struct lm_async_cb *)data; + struct gfs_glock *gl; + + gl = gfs_glock_find(sdp, &async->lc_name); + if (gfs_assert_warn(sdp, gl)) + return; + if (!gfs_assert_warn(sdp, gl->gl_req_bh)) + gl->gl_req_bh(gl, async->lc_ret); + glock_put(gl); + + return; + } + + case LM_CB_NEED_RECOVERY: + gfs_add_dirty_j(sdp, *(unsigned int *)data); + if (sdp->sd_recoverd_process) + wake_up_process(sdp->sd_recoverd_process); + return; + + case LM_CB_DROPLOCKS: + gfs_gl_hash_clear(sdp, FALSE); + gfs_quota_scan(sdp); + return; + + default: + gfs_assert_warn(sdp, FALSE); + return; + } +} + +/** + * gfs_try_toss_inode - try to remove a particular GFS inode struct from cache + * sdp: the filesystem + * inum: the inode number + * + * Look for the glock protecting the inode of interest. + * If no process is manipulating or holding the glock, see if the glock + * has a gfs_inode attached. + * If gfs_inode has no references, unhold its iopen glock, release any + * indirect addressing buffers, and destroy the gfs_inode. + */ + +void +gfs_try_toss_inode(struct gfs_sbd *sdp, struct gfs_inum *inum) +{ + struct gfs_glock *gl; + struct gfs_inode *ip; + int error; + + error = gfs_glock_get(sdp, + inum->no_formal_ino, &gfs_inode_glops, + NO_CREATE, &gl); + if (error || !gl) + return; + + if (!trylock_on_glock(gl)) + goto out; + + if (!queue_empty(gl, &gl->gl_holders)) + goto out_unlock; + + ip = get_gl2ip(gl); + if (!ip) + goto out_unlock; + + if (atomic_read(&ip->i_count)) + goto out_unlock; + + gfs_inode_destroy(ip); + + out_unlock: + unlock_on_glock(gl); + + out: + glock_put(gl); +} + +/** + * gfs_iopen_go_callback - Try to kick the inode/vnode associated with an iopen glock from memory + * @io_gl: the iopen glock + * @state: the state into which the glock should be put + * + */ + +void +gfs_iopen_go_callback(struct gfs_glock *io_gl, unsigned int state) +{ + struct gfs_glock *i_gl; + struct gfs_inode *ip; + + if (state != LM_ST_UNLOCKED) + return; + + spin_lock(&io_gl->gl_spin); + i_gl = get_gl2gl(io_gl); + if (i_gl) { + glock_hold(i_gl); + spin_unlock(&io_gl->gl_spin); + } else { + spin_unlock(&io_gl->gl_spin); + return; + } + + if (trylock_on_glock(i_gl)) { + if (queue_empty(i_gl, &i_gl->gl_holders)) { + ip = get_gl2ip(i_gl); + if (ip) { + gfs_try_toss_vnode(ip); + unlock_on_glock(i_gl); + gfs_glock_schedule_for_reclaim(i_gl); + goto out; + } + } + unlock_on_glock(i_gl); + } + + out: + glock_put(i_gl); +} + +/** + * demote_ok - Check to see if it's ok to unlock a glock (to remove it + * from glock cache) + * @gl: the glock + * + * Called when trying to reclaim glocks, once it's determined that the glock + * has no holders on this node. + * + * Returns: TRUE if it's ok + * + * It's not okay if: + * -- glock is STICKY + * -- PREFETCHed glock has not been given enough chance to be used + * -- glock-type-specific test says "no" + */ + +static int +demote_ok(struct gfs_glock *gl) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_glock_operations *glops = gl->gl_ops; + int demote = TRUE; + + if (test_bit(GLF_STICKY, &gl->gl_flags)) + demote = FALSE; + else if (test_bit(GLF_PREFETCH, &gl->gl_flags)) + demote = time_after_eq(jiffies, + gl->gl_stamp + + gfs_tune_get(sdp, gt_prefetch_secs) * HZ); + else if (glops->go_demote_ok) + demote = glops->go_demote_ok(gl); + + return demote; +} + +/** + * gfs_glock_schedule_for_reclaim - Add a glock to the reclaim list + * @gl: the glock + * + */ + +void +gfs_glock_schedule_for_reclaim(struct gfs_glock *gl) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + + spin_lock(&sdp->sd_reclaim_lock); + if (list_empty(&gl->gl_reclaim)) { + glock_hold(gl); + list_add(&gl->gl_reclaim, &sdp->sd_reclaim_list); + atomic_inc(&sdp->sd_reclaim_count); + } + spin_unlock(&sdp->sd_reclaim_lock); + + wake_up(&sdp->sd_reclaim_wchan); +} + +/** + * gfs_reclaim_glock - process the next glock on the filesystem's reclaim list + * @sdp: the filesystem + * + * Called from gfs_glockd() glock reclaim daemon, or when promoting a + * (different) glock and we notice that there are a lot of glocks in the + * reclaim list. + * + * Remove glock from filesystem's reclaim list, update reclaim statistics. + * If no holders (might have gotten added since glock was placed on reclaim + * list): + * -- Destroy any now-unused inode protected by glock + * (and release hold on iopen glock). + * -- Ask for demote to UNLOCKED to enable removal of glock from glock cache. + * + * If no further interest in glock struct, remove it from glock cache, and + * free it from memory. (During normal operation, this is the only place + * that this is done). + * + * Glock-type-specific considerations for permission to demote are handled + * in demote_ok(). This includes how long to retain a glock in cache after it + * is no longer held by any process. + */ + +void +gfs_reclaim_glock(struct gfs_sbd *sdp) +{ + struct gfs_glock *gl; + struct gfs_gl_hash_bucket *bucket; + + spin_lock(&sdp->sd_reclaim_lock); + + /* Nothing to reclaim? Done! */ + if (list_empty(&sdp->sd_reclaim_list)) { + spin_unlock(&sdp->sd_reclaim_lock); + return; + } + + /* Remove next victim from reclaim list */ + gl = list_entry(sdp->sd_reclaim_list.next, + struct gfs_glock, gl_reclaim); + list_del_init(&gl->gl_reclaim); + + spin_unlock(&sdp->sd_reclaim_lock); + + atomic_dec(&sdp->sd_reclaim_count); + atomic_inc(&sdp->sd_reclaimed); + + if (trylock_on_glock(gl)) { + if (queue_empty(gl, &gl->gl_holders)) { + /* Inode glock-type-specific; free unused gfs inode, + and release hold on iopen glock */ + if (gl->gl_ops == &gfs_inode_glops) { + struct gfs_inode *ip = get_gl2ip(gl); + if (ip && !atomic_read(&ip->i_count)) + gfs_inode_destroy(ip); + } + /* Generic (including inodes); try to unlock glock */ + if (gl->gl_state != LM_ST_UNLOCKED && + demote_ok(gl)) + handle_callback(gl, LM_ST_UNLOCKED); + } + unlock_on_glock(gl); + } + + bucket = gl->gl_bucket; + + /* If glock struct's only remaining reference is from being put on + the reclaim list, remove glock from hash table (sd_gl_hash), + and free the glock's memory */ + write_lock(&bucket->hb_lock); + if (atomic_read(&gl->gl_count) == 1) { + list_del_init(&gl->gl_list); + write_unlock(&bucket->hb_lock); + glock_free(gl); + } else { + write_unlock(&bucket->hb_lock); + glock_put(gl); /* see gfs_glock_schedule_for_reclaim() */ + } +} + +/** + * examine_bucket - Call a function for glock in a hash bucket + * @examiner: the function + * @sdp: the filesystem + * @bucket: the bucket + * + * Returns: TRUE if the bucket has entries + */ + +static int +examine_bucket(glock_examiner examiner, + struct gfs_sbd *sdp, struct gfs_gl_hash_bucket *bucket, + unsigned int *purge_nr) +{ + struct glock_plug plug; + struct list_head *tmp; + struct gfs_glock *gl; + int entries; + + /* Add "plug" to end of bucket list, work back up list from there */ + memset(&plug.gl_flags, 0, sizeof(unsigned long)); + set_bit(GLF_PLUG, &plug.gl_flags); + + write_lock(&bucket->hb_lock); + list_add(&plug.gl_list, &bucket->hb_list); + write_unlock(&bucket->hb_lock); + + /* Look at each bucket entry */ + for (;;) { + write_lock(&bucket->hb_lock); + + /* Work back up list from plug */ + for (;;) { + tmp = plug.gl_list.next; + + /* Top of list; we're done */ + if (tmp == &bucket->hb_list) { + list_del(&plug.gl_list); + entries = !list_empty(&bucket->hb_list); + write_unlock(&bucket->hb_lock); + return entries; + } + gl = list_entry(tmp, struct gfs_glock, gl_list); + + /* Move plug up list */ + list_move(&plug.gl_list, &gl->gl_list); + + if (test_bit(GLF_PLUG, &gl->gl_flags)) + continue; + + /* glock_hold; examiner must glock_put() */ + atomic_inc(&gl->gl_count); + + break; + } + + write_unlock(&bucket->hb_lock); + + examiner(gl, purge_nr); + } +} + +static void +try_purge_iopen(struct gfs_glock *gl, unsigned int *p_count) +{ + struct gfs_glock *i_gl; + + if (*p_count == 0) + return; + + /* find the associated inode glock */ + i_gl = get_gl2gl(gl); + if (!i_gl) + return; + + /* + * If the associated inode glock has been in unlocked + * state, try to purge it. + */ + if (trylock_on_glock(i_gl)) { + if (i_gl->gl_state == LM_ST_UNLOCKED) { + *p_count = *p_count - 1; + unlock_on_glock(i_gl); + atomic_inc(&gl->gl_count); + gfs_iopen_go_callback(gl, LM_ST_UNLOCKED); + handle_callback(gl, LM_ST_UNLOCKED); + spin_lock(&gl->gl_spin); + run_queue(gl); + spin_unlock(&gl->gl_spin); + glock_put(gl); + } else + unlock_on_glock(i_gl); + } + + return; +} + +/** + * scan_glock - look at a glock and see if we can reclaim it + * @gl: the glock to look at + * + * Called via examine_bucket() when trying to release glocks from glock cache, + * during normal operation (i.e. not unmount time). + * + * Place glock on filesystem's reclaim list if, on this node: + * -- No process is manipulating glock struct, and + * -- No current holders, and either: + * -- GFS incore inode, protected by glock, is no longer in use, or + * -- Glock-type-specific demote_ok glops gives permission + */ + +static void +scan_glock(struct gfs_glock *gl, unsigned int *p_count) +{ + if (trylock_on_glock(gl)) { + if (queue_empty(gl, &gl->gl_holders)) { + /* Inode glock-type-specific; reclaim glock if gfs inode + no longer in use. */ + if (gl->gl_ops == &gfs_inode_glops) { + struct gfs_inode *ip = get_gl2ip(gl); + if (ip && !atomic_read(&ip->i_count)) { + unlock_on_glock(gl); + gfs_glock_schedule_for_reclaim(gl); + goto out; + } + } + /* Generic (including inodes not scheduled above) */ + if (gl->gl_state != LM_ST_UNLOCKED && + demote_ok(gl)) { + unlock_on_glock(gl); + gfs_glock_schedule_for_reclaim(gl); + goto out; + } + } + /* iopen always has holder(s) */ + if (gl->gl_name.ln_type == LM_TYPE_IOPEN) { + unlock_on_glock(gl); + try_purge_iopen(gl, p_count); + goto out; + } + unlock_on_glock(gl); + } + + out: + glock_put(gl); /* see examine_bucket() */ +} + +/** + * gfs_scand_internal - Look for glocks and inodes to toss from memory + * @sdp: the filesystem + * + * Invokes scan_glock() for each glock in each cache bucket. + * + * Steps of reclaiming a glock: + * -- scan_glock() places eligible glocks on filesystem's reclaim list. + * -- gfs_reclaim_glock() processes list members, attaches demotion requests + * to wait queues of glocks still locked at inter-node scope. + * -- Demote to UNLOCKED state (if not already unlocked). + * -- gfs_reclaim_lock() cleans up glock structure. + */ + +void +gfs_scand_internal(struct gfs_sbd *sdp) +{ + unsigned int x, purge_nr; + + if (!sdp->sd_tune.gt_glock_purge) + purge_nr = 0; + else + purge_nr = atomic_read(&sdp->sd_glock_count) * + sdp->sd_tune.gt_glock_purge / 100; + + for (x = 0; x < GFS_GL_HASH_SIZE; x++) { + examine_bucket(scan_glock, sdp, &sdp->sd_gl_hash[x], &purge_nr); + cond_resched(); + } +} + +/** + * clear_glock - look at a glock and see if we can free it from glock cache + * @gl: the glock to look at + * + * Called via examine_bucket() when unmounting the filesystem, or + * when inter-node lock manager requests DROPLOCKS because it is running + * out of capacity. + * + * Similar to gfs_reclaim_glock(), except does *not*: + * -- Consult demote_ok() for permission + * -- Increment sdp->sd_reclaimed statistic + * + */ + +static void +clear_glock(struct gfs_glock *gl, unsigned int *unused) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_gl_hash_bucket *bucket = gl->gl_bucket; + + spin_lock(&sdp->sd_reclaim_lock); + if (!list_empty(&gl->gl_reclaim)) { + list_del_init(&gl->gl_reclaim); + atomic_dec(&sdp->sd_reclaim_count); + glock_put(gl); /* see gfs_glock_schedule_for_reclaim() */ + } + spin_unlock(&sdp->sd_reclaim_lock); + + if (trylock_on_glock(gl)) { + if (queue_empty(gl, &gl->gl_holders)) { + /* Inode glock-type-specific; free unused gfs inode, + and release hold on iopen glock */ + if (gl->gl_ops == &gfs_inode_glops) { + struct gfs_inode *ip = get_gl2ip(gl); + if (ip && !atomic_read(&ip->i_count)) + gfs_inode_destroy(ip); + } + /* Generic (including inodes); unlock glock */ + if (gl->gl_state != LM_ST_UNLOCKED) + handle_callback(gl, LM_ST_UNLOCKED); + } + + unlock_on_glock(gl); + } + + /* If glock struct's only remaining reference is from examine_bucket(), + remove glock from hash table (sd_gl_hash), and free glock's memory */ + write_lock(&bucket->hb_lock); + if (atomic_read(&gl->gl_count) == 1) { + list_del_init(&gl->gl_list); + write_unlock(&bucket->hb_lock); + glock_free(gl); + } else { + write_unlock(&bucket->hb_lock); + glock_put(gl); /* see examine_bucket() */ + } +} + +/** + * gfs_gl_hash_clear - Empty out the glock hash table + * @sdp: the filesystem + * @wait: wait until it's all gone + * + * Called when unmounting the filesystem, or when inter-node lock manager + * requests DROPLOCKS because it is running out of capacity. + */ + +void +gfs_gl_hash_clear(struct gfs_sbd *sdp, int wait) +{ + unsigned long t; + unsigned int x; + int cont; + + t = jiffies; + + for (;;) { + cont = FALSE; + + for (x = 0; x < GFS_GL_HASH_SIZE; x++) + if (examine_bucket(clear_glock, sdp, &sdp->sd_gl_hash[x], 0)) + cont = TRUE; + + if (!wait || !cont) + break; + + if (time_after_eq(jiffies, t + gfs_tune_get(sdp, gt_stall_secs) * HZ)) { + printk("GFS: fsid=%s: Unmount seems to be stalled. Dumping lock state...\n", + sdp->sd_fsname); + gfs_dump_lockstate(sdp, NULL); + t = jiffies; + } + + invalidate_inodes(sdp->sd_vfs); + schedule_timeout_interruptible(HZ / 10); + } +} + +/* + * Diagnostic routines to help debug distributed deadlock + */ + +/** + * dump_holder - print information about a glock holder + * @str: a string naming the type of holder + * @gh: the glock holder + * @buf: the buffer + * @size: the size of the buffer + * @count: where we are in the buffer + * + * Returns: 0 on success, -ENOBUFS when we run out of space + */ + +static int +dump_holder(char *str, struct gfs_holder *gh, + char *buf, unsigned int size, unsigned int *count) +{ + unsigned int x; + int error = -ENOBUFS; + + gfs_printf(" %s\n", str); + gfs_printf(" owner = %ld\n", + (gh->gh_owner) ? (long)gh->gh_owner->pid : -1); + gfs_printf(" gh_state = %u\n", gh->gh_state); + gfs_printf(" gh_flags ="); + for (x = 0; x < 32; x++) + if (gh->gh_flags & (1 << x)) + gfs_printf(" %u", x); + gfs_printf(" \n"); + gfs_printf(" error = %d\n", gh->gh_error); + gfs_printf(" gh_iflags ="); + for (x = 0; x < 32; x++) + if (test_bit(x, &gh->gh_iflags)) + gfs_printf(" %u", x); + gfs_printf(" \n"); + + error = 0; + + out: + return error; +} + +/** + * dump_inode - print information about an inode + * @ip: the inode + * @buf: the buffer + * @size: the size of the buffer + * @count: where we are in the buffer + * + * Returns: 0 on success, -ENOBUFS when we run out of space + */ + +static int +dump_inode(struct gfs_inode *ip, + char *buf, unsigned int size, unsigned int *count) +{ + unsigned int x; + int error = -ENOBUFS; + + gfs_printf(" Inode:\n"); + gfs_printf(" num = %" PRIu64 "/%" PRIu64 "\n", + ip->i_num.no_formal_ino, ip->i_num.no_addr); + gfs_printf(" type = %u\n", ip->i_di.di_type); + gfs_printf(" i_count = %d\n", atomic_read(&ip->i_count)); + gfs_printf(" i_flags ="); + for (x = 0; x < 32; x++) + if (test_bit(x, &ip->i_flags)) + gfs_printf(" %u", x); + gfs_printf(" \n"); + gfs_printf(" vnode = %s\n", (ip->i_vnode) ? "yes" : "no"); + + error = 0; + + out: + return error; +} + +/** + * dump_glock - print information about a glock + * @gl: the glock + * @buf: the buffer + * @size: the size of the buffer + * @count: where we are in the buffer + * + * Returns: 0 on success, -ENOBUFS when we run out of space + */ + +static int +dump_glock(struct gfs_glock *gl, + char *buf, unsigned int size, unsigned int *count) +{ + struct list_head *head, *tmp; + struct gfs_holder *gh; + unsigned int x; + int error = -ENOBUFS; + + spin_lock(&gl->gl_spin); + + gfs_printf("Glock (%u, %" PRIu64 ")\n", + gl->gl_name.ln_type, + gl->gl_name.ln_number); + gfs_printf(" gl_flags ="); + for (x = 0; x < 32; x++) + if (test_bit(x, &gl->gl_flags)) + gfs_printf(" %u", x); + gfs_printf(" \n"); + gfs_printf(" gl_count = %d\n", atomic_read(&gl->gl_count)); + gfs_printf(" gl_state = %u\n", gl->gl_state); + gfs_printf(" req_gh = %s\n", (gl->gl_req_gh) ? "yes" : "no"); + gfs_printf(" req_bh = %s\n", (gl->gl_req_bh) ? "yes" : "no"); + gfs_printf(" lvb_count = %d\n", atomic_read(&gl->gl_lvb_count)); + gfs_printf(" object = %s\n", (gl->gl_object) ? "yes" : "no"); + gfs_printf(" new_le = %s\n", (gl->gl_new_le.le_trans) ? "yes" : "no"); + gfs_printf(" incore_le = %s\n", (gl->gl_incore_le.le_trans) ? "yes" : "no"); + gfs_printf(" reclaim = %s\n", + (list_empty(&gl->gl_reclaim)) ? "no" : "yes"); + if (gl->gl_aspace) + gfs_printf(" aspace = %lu\n", + gl->gl_aspace->i_mapping->nrpages); + else + gfs_printf(" aspace = no\n"); + gfs_printf(" ail_bufs = %s\n", + (list_empty(&gl->gl_ail_bufs)) ? "no" : "yes"); + if (gl->gl_req_gh) { + error = dump_holder("Request", gl->gl_req_gh, buf, size, count); + if (error) + goto out; + } + for (head = &gl->gl_holders, tmp = head->next; + tmp != head; + tmp = tmp->next) { + gh = list_entry(tmp, struct gfs_holder, gh_list); + error = dump_holder("Holder", gh, buf, size, count); + if (error) + goto out; + } + for (head = &gl->gl_waiters1, tmp = head->next; + tmp != head; + tmp = tmp->next) { + gh = list_entry(tmp, struct gfs_holder, gh_list); + error = dump_holder("Waiter1", gh, buf, size, count); + if (error) + goto out; + } + for (head = &gl->gl_waiters2, tmp = head->next; + tmp != head; + tmp = tmp->next) { + gh = list_entry(tmp, struct gfs_holder, gh_list); + error = dump_holder("Waiter2", gh, buf, size, count); + if (error) + goto out; + } + for (head = &gl->gl_waiters3, tmp = head->next; + tmp != head; + tmp = tmp->next) { + gh = list_entry(tmp, struct gfs_holder, gh_list); + error = dump_holder("Waiter3", gh, buf, size, count); + if (error) + goto out; + } + if (gl->gl_ops == &gfs_inode_glops && get_gl2ip(gl)) { + if (!test_bit(GLF_LOCK, &gl->gl_flags) && + list_empty(&gl->gl_holders)) { + error = dump_inode(get_gl2ip(gl), buf, size, count); + if (error) + goto out; + } else { + error = -ENOBUFS; + gfs_printf(" Inode: busy\n"); + } + } + + error = 0; + + out: + spin_unlock(&gl->gl_spin); + + return error; +} + +/** + * gfs_dump_lockstate - print out the current lockstate + * @sdp: the filesystem + * @ub: the buffer to copy the information into + * + * If @ub is NULL, dump the lockstate to the console. + * + */ + +int +gfs_dump_lockstate(struct gfs_sbd *sdp, struct gfs_user_buffer *ub) +{ + struct gfs_gl_hash_bucket *bucket; + struct list_head *tmp, *head; + struct gfs_glock *gl; + char *buf = NULL; + unsigned int size = gfs_tune_get(sdp, gt_lockdump_size); + unsigned int x, count; + int error = 0; + + if (ub) { + buf = kmalloc(size, GFP_KERNEL); + if (!buf) + return -ENOMEM; + } + + for (x = 0; x < GFS_GL_HASH_SIZE; x++) { + bucket = &sdp->sd_gl_hash[x]; + count = 0; + + read_lock(&bucket->hb_lock); + + for (head = &bucket->hb_list, tmp = head->next; + tmp != head; + tmp = tmp->next) { + gl = list_entry(tmp, struct gfs_glock, gl_list); + + if (test_bit(GLF_PLUG, &gl->gl_flags)) + continue; + + error = dump_glock(gl, buf, size, &count); + if (error) + break; + } + + read_unlock(&bucket->hb_lock); + + if (error) + break; + + if (ub) { + if (ub->ub_count + count > ub->ub_size) { + error = -ENOMEM; + break; + } + if (copy_to_user(ub->ub_data + ub->ub_count, buf, count)) { + error = -EFAULT; + break; + } + ub->ub_count += count; + } + } + + if (ub) + kfree(buf); + + return error; +} --- linux-2.6.28.orig/ubuntu/gfs/ops_export.c +++ linux-2.6.28/ubuntu/gfs/ops_export.c @@ -0,0 +1,403 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "dio.h" +#include "dir.h" +#include "glock.h" +#include "glops.h" +#include "inode.h" +#include "ops_dentry.h" +#include "ops_export.h" +#include "rgrp.h" + +struct inode_cookie +{ + uint64_t formal_ino; + uint32_t gen; + int gen_valid; +}; + +struct get_name_filldir +{ + uint64_t formal_ino; + char *name; +}; + +/** + * gfs_encode_fh - + * @param1: description + * @param2: description + * @param3: description + * + * Function description + * + * Returns: what is returned + */ + +int +gfs_encode_fh(struct dentry *dentry, __u32 *fh, int *len, + int connectable) +{ + struct inode *inode = dentry->d_inode; + struct gfs_inode *ip = get_v2ip(inode); + int maxlen = *len; + + atomic_inc(&ip->i_sbd->sd_ops_export); + + if (maxlen < 3) + return 255; + + fh[0] = cpu_to_gfs32((uint32_t)(ip->i_num.no_formal_ino >> 32)); + fh[1] = cpu_to_gfs32((uint32_t)(ip->i_num.no_formal_ino & 0xFFFFFFFF)); + fh[2] = cpu_to_gfs32(inode->i_generation); /* dinode's mh_incarn */ + *len = 3; + + if (maxlen < 5 || !connectable) + return 3; + + spin_lock(&dentry->d_lock); + + inode = dentry->d_parent->d_inode; + ip = get_v2ip(inode); + + fh[3] = cpu_to_gfs32((uint32_t)(ip->i_num.no_formal_ino >> 32)); + fh[4] = cpu_to_gfs32((uint32_t)(ip->i_num.no_formal_ino & 0xFFFFFFFF)); + *len = 5; + + if (maxlen < 6) { + spin_unlock(&dentry->d_lock); + return 5; + } + + fh[5] = cpu_to_gfs32(inode->i_generation); /* dinode's mh_incarn */ + + spin_unlock(&dentry->d_lock); + + *len = 6; + + return 6; +} + +/** + * get_name_filldir - + * @param1: description + * @param2: description + * @param3: description + * + * Function description + * + * Returns: what is returned + */ + +static int +get_name_filldir(void *opaque, + const char *name, unsigned int length, + uint64_t offset, + struct gfs_inum *inum, unsigned int type) +{ + struct get_name_filldir *gnfd = (struct get_name_filldir *)opaque; + + if (inum->no_formal_ino != gnfd->formal_ino) + return 0; + + memcpy(gnfd->name, name, length); + gnfd->name[length] = 0; + + return 1; +} + +/** + * gfs_get_name - + * @param1: description + * @param2: description + * @param3: description + * + * Function description + * + * Returns: what is returned + */ + +int gfs_get_name(struct dentry *parent, char *name, + struct dentry *child) +{ + struct inode *dir = parent->d_inode; + struct inode *inode = child->d_inode; + struct gfs_inode *dip, *ip; + struct get_name_filldir gnfd; + struct gfs_holder gh; + uint64_t offset = 0; + int error; + + if (!dir) + return -EINVAL; + + atomic_inc(&get_v2sdp(dir->i_sb)->sd_ops_export); + + if (!S_ISDIR(dir->i_mode) || !inode) + return -EINVAL; + + dip = get_v2ip(dir); + ip = get_v2ip(inode); + + *name = 0; + gnfd.formal_ino = ip->i_num.no_formal_ino; + gnfd.name = name; + + error = gfs_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &gh); + if (error) + return error; + + error = gfs_dir_read(dip, &offset, &gnfd, get_name_filldir); + + gfs_glock_dq_uninit(&gh); + + if (!error & !*name) + error = -ENOENT; + + return error; +} + +/** + * gfs_get_parent - + * @param1: description + * @param2: description + * @param3: description + * + * Function description + * + * Returns: what is returned + */ + +struct dentry * +gfs_get_parent(struct dentry *child) +{ + struct gfs_inode *dip = get_v2ip(child->d_inode); + struct gfs_holder d_gh, i_gh; + struct qstr dotdot = { .name = "..", .len = 2 }; + struct gfs_inode *ip; + struct inode *inode; + struct dentry *dentry; + int error; + + atomic_inc(&dip->i_sbd->sd_ops_export); + + gfs_holder_init(dip->i_gl, 0, 0, &d_gh); + error = gfs_lookupi(&d_gh, &dotdot, TRUE, &i_gh); + if (error) + goto fail; + + error = -ENOENT; + if (!i_gh.gh_gl) + goto fail; + + ip = get_gl2ip(i_gh.gh_gl); + + inode = gfs_iget(ip, CREATE); + gfs_inode_put(ip); + + gfs_glock_dq_uninit(&d_gh); + gfs_glock_dq_uninit(&i_gh); + + if (!inode) + return ERR_PTR(-ENOMEM); + + dentry = d_alloc_anon(inode); + if (!dentry) { + iput(inode); + return ERR_PTR(-ENOMEM); + } + + dentry->d_op = &gfs_dops; + return dentry; + + fail: + gfs_holder_uninit(&d_gh); + return ERR_PTR(error); +} + +/** + * gfs_get_dentry - + * @param1: description + * @param2: description + * @param3: description + * + * Function description + * + * Returns: what is returned + */ + +struct dentry * +gfs_get_dentry(struct super_block *sb, struct inode_cookie *cookie) +{ + struct gfs_sbd *sdp = get_v2sdp(sb); + struct gfs_inum inum; + struct gfs_holder i_gh, ri_gh, rgd_gh; + struct gfs_rgrpd *rgd; + struct buffer_head *bh; + struct gfs_dinode *di; + struct gfs_inode *ip; + struct inode *inode; + struct dentry *dentry; + int error; + + atomic_inc(&sdp->sd_ops_export); + + if (!cookie->formal_ino || + cookie->formal_ino == sdp->sd_jiinode->i_num.no_formal_ino || + cookie->formal_ino == sdp->sd_riinode->i_num.no_formal_ino || + cookie->formal_ino == sdp->sd_qinode->i_num.no_formal_ino) + return ERR_PTR(-EINVAL); + + inum.no_formal_ino = cookie->formal_ino; + inum.no_addr = cookie->formal_ino; + + error = gfs_glock_nq_num(sdp, + inum.no_formal_ino, &gfs_inode_glops, + LM_ST_SHARED, LM_FLAG_ANY | GL_LOCAL_EXCL, + &i_gh); + if (error) + return ERR_PTR(error); + + error = gfs_inode_get(i_gh.gh_gl, &inum, NO_CREATE, &ip); + if (error) + goto fail; + if (ip) + goto out; + + error = gfs_rindex_hold(sdp, &ri_gh); + if (error) + goto fail; + + error = -EINVAL; + rgd = gfs_blk2rgrpd(sdp, inum.no_addr); + if (!rgd) + goto fail_rindex; + + error = gfs_glock_nq_init(rgd->rd_gl, LM_ST_SHARED, 0, &rgd_gh); + if (error) + goto fail_rindex; + + error = -ESTALE; + if (gfs_get_block_type(rgd, inum.no_addr) != GFS_BLKST_USEDMETA) + goto fail_rgd; + + error = gfs_dread(i_gh.gh_gl, inum.no_addr, + DIO_START | DIO_WAIT, &bh); + if (error) + goto fail_rgd; + + di = (struct gfs_dinode *)bh->b_data; + + error = -ESTALE; + if (gfs32_to_cpu(di->di_header.mh_magic) != GFS_MAGIC || + gfs32_to_cpu(di->di_header.mh_type) != GFS_METATYPE_DI || + (gfs32_to_cpu(di->di_flags) & GFS_DIF_UNUSED)) + goto fail_relse; + + brelse(bh); + gfs_glock_dq_uninit(&rgd_gh); + gfs_glock_dq_uninit(&ri_gh); + + error = gfs_inode_get(i_gh.gh_gl, &inum, CREATE, &ip); + if (error) + goto fail; + + atomic_inc(&sdp->sd_fh2dentry_misses); + + out: + inode = gfs_iget(ip, CREATE); + gfs_inode_put(ip); + + gfs_glock_dq_uninit(&i_gh); + + if (!inode) + return ERR_PTR(-ENOMEM); + + /* inode->i_generation is GFS dinode's mh_incarn value */ + if (cookie->gen_valid && cookie->gen != inode->i_generation) { + iput(inode); + return ERR_PTR(-ESTALE); + } + + dentry = d_alloc_anon(inode); + if (!dentry) { + iput(inode); + return ERR_PTR(-ENOMEM); + } + + dentry->d_op = &gfs_dops; + return dentry; + + fail_relse: + brelse(bh); + + fail_rgd: + gfs_glock_dq_uninit(&rgd_gh); + + fail_rindex: + gfs_glock_dq_uninit(&ri_gh); + + fail: + gfs_glock_dq_uninit(&i_gh); + return ERR_PTR(error); +} + +static struct dentry *gfs_fh_to_dentry(struct super_block *sb, struct fid *fid, + int fh_len, int fh_type) +{ + struct inode_cookie this; + __u32 *fh = fid->raw; + + atomic_inc(&get_v2sdp(sb)->sd_ops_export); + + switch (fh_type) { + case 6: + case 5: + case 3: + this.gen_valid = TRUE; + this.gen = gfs32_to_cpu(fh[2]); + this.formal_ino = ((uint64_t)gfs32_to_cpu(fh[0])) << 32; + this.formal_ino |= (uint64_t)gfs32_to_cpu(fh[1]); + return gfs_get_dentry(sb, &this); + default: + return NULL; + } +} + +static struct dentry *gfs_fh_to_parent(struct super_block *sb, struct fid *fid, + int fh_len, int fh_type) +{ + struct inode_cookie parent; + __u32 *fh = fid->raw; + + atomic_inc(&get_v2sdp(sb)->sd_ops_export); + + switch (fh_type) { + case 6: + parent.gen_valid = TRUE; + parent.gen = gfs32_to_cpu(fh[5]); + case 5: + parent.formal_ino = ((uint64_t)gfs32_to_cpu(fh[3])) << 32; + parent.formal_ino |= (uint64_t)gfs32_to_cpu(fh[4]); + default: + return NULL; + } + + return gfs_get_dentry(sb, &parent); +} + +const struct export_operations gfs_export_ops = { + .encode_fh = gfs_encode_fh, + .fh_to_dentry = gfs_fh_to_dentry, + .fh_to_parent = gfs_fh_to_parent, + .get_name = gfs_get_name, + .get_parent = gfs_get_parent, +}; + --- linux-2.6.28.orig/ubuntu/gfs/lvb.c +++ linux-2.6.28/ubuntu/gfs/lvb.c @@ -0,0 +1,135 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" + +#define pv(struct, member, fmt) printk(" "#member" = "fmt"\n", struct->member); + +#define CPIN_08(s1, s2, member, count) {memcpy((s1->member), (s2->member), (count));} +#define CPOUT_08(s1, s2, member, count) {memcpy((s2->member), (s1->member), (count));} +#define CPIN_16(s1, s2, member) {(s1->member) = gfs16_to_cpu((s2->member));} +#define CPOUT_16(s1, s2, member) {(s2->member) = cpu_to_gfs16((s1->member));} +#define CPIN_32(s1, s2, member) {(s1->member) = gfs32_to_cpu((s2->member));} +#define CPOUT_32(s1, s2, member) {(s2->member) = cpu_to_gfs32((s1->member));} +#define CPIN_64(s1, s2, member) {(s1->member) = gfs64_to_cpu((s2->member));} +#define CPOUT_64(s1, s2, member) {(s2->member) = cpu_to_gfs64((s1->member));} + +/** + * gfs_rgrp_lvb_in - Read in rgrp data + * @rb: the cpu-order structure + * @lvb: the lvb + * + */ + +void +gfs_rgrp_lvb_in(struct gfs_rgrp_lvb *rb, char *lvb) +{ + struct gfs_rgrp_lvb *str = (struct gfs_rgrp_lvb *)lvb; + + CPIN_32(rb, str, rb_magic); + CPIN_32(rb, str, rb_free); + CPIN_32(rb, str, rb_useddi); + CPIN_32(rb, str, rb_freedi); + CPIN_32(rb, str, rb_usedmeta); + CPIN_32(rb, str, rb_freemeta); +} + +/** + * gfs_rgrp_lvb_out - Write out rgrp data + * @rb: the cpu-order structure + * @lvb: the lvb + * + */ + +void +gfs_rgrp_lvb_out(struct gfs_rgrp_lvb *rb, char *lvb) +{ + struct gfs_rgrp_lvb *str = (struct gfs_rgrp_lvb *)lvb; + + CPOUT_32(rb, str, rb_magic); + CPOUT_32(rb, str, rb_free); + CPOUT_32(rb, str, rb_useddi); + CPOUT_32(rb, str, rb_freedi); + CPOUT_32(rb, str, rb_usedmeta); + CPOUT_32(rb, str, rb_freemeta); +} + +/** + * gfs_rgrp_lvb_print - Print out rgrp data + * @rb: the cpu-order structure + * @console - TRUE if this should be printed to the console, + * FALSE if it should be just printed to the incore debug + * buffer + */ + +void +gfs_rgrp_lvb_print(struct gfs_rgrp_lvb *rb) +{ + pv(rb, rb_magic, "%u"); + pv(rb, rb_free, "%u"); + pv(rb, rb_useddi, "%u"); + pv(rb, rb_freedi, "%u"); + pv(rb, rb_usedmeta, "%u"); + pv(rb, rb_freemeta, "%u"); +} + +/** + * gfs_quota_lvb_in - Read in quota data + * @rb: the cpu-order structure + * @lvb: the lvb + * + */ + +void +gfs_quota_lvb_in(struct gfs_quota_lvb *qb, char *lvb) +{ + struct gfs_quota_lvb *str = (struct gfs_quota_lvb *)lvb; + + CPIN_32(qb, str, qb_magic); + CPIN_32(qb, str, qb_pad); + CPIN_64(qb, str, qb_limit); + CPIN_64(qb, str, qb_warn); + CPIN_64(qb, str, qb_value); +} + +/** + * gfs_quota_lvb_out - Write out quota data + * @rb: the cpu-order structure + * @lvb: the lvb + * + */ + +void +gfs_quota_lvb_out(struct gfs_quota_lvb *qb, char *lvb) +{ + struct gfs_quota_lvb *str = (struct gfs_quota_lvb *)lvb; + + CPOUT_32(qb, str, qb_magic); + CPOUT_32(qb, str, qb_pad); + CPOUT_64(qb, str, qb_limit); + CPOUT_64(qb, str, qb_warn); + CPOUT_64(qb, str, qb_value); +} + +/** + * gfs_quota_lvb_print - Print out quota data + * @rb: the cpu-order structure + * @console - TRUE if this should be printed to the console, + * FALSE if it should be just printed to the incore debug + * buffer + */ + +void +gfs_quota_lvb_print(struct gfs_quota_lvb *qb) +{ + pv(qb, qb_magic, "%u"); + pv(qb, qb_pad, "%u"); + pv(qb, qb_limit, "%"PRIu64); + pv(qb, qb_warn, "%"PRIu64); + pv(qb, qb_value, "%"PRId64); +} --- linux-2.6.28.orig/ubuntu/gfs/sys.c +++ linux-2.6.28/ubuntu/gfs/sys.c @@ -0,0 +1,115 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "glock.h" +#include "lm.h" +#include "sys.h" +#include "super.h" + +char *gfs_sys_margs; +spinlock_t gfs_sys_margs_lock; + +static ssize_t id_show(struct gfs_sbd *sdp, char *buf) +{ + return sprintf(buf, "%s\n", sdp->sd_vfs->s_id); +} + +static ssize_t fsname_show(struct gfs_sbd *sdp, char *buf) +{ + return sprintf(buf, "%s\n", sdp->sd_fsname); +} + +struct gfs_attr { + struct attribute attr; + ssize_t (*show)(struct gfs_sbd *, char *); + ssize_t (*store)(struct gfs_sbd *, const char *, size_t); +}; + +#define GFS_ATTR(name, mode, show, store) \ +static struct gfs_attr gfs_attr_##name = __ATTR(name, mode, show, store) + +GFS_ATTR(id, 0444, id_show, NULL); +GFS_ATTR(fsname, 0444, fsname_show, NULL); + +static struct attribute *gfs_attrs[] = { + &gfs_attr_id.attr, + &gfs_attr_fsname.attr, + NULL, +}; + +static ssize_t gfs_attr_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + struct gfs_sbd *sdp = container_of(kobj, struct gfs_sbd, sd_kobj); + struct gfs_attr *a = container_of(attr, struct gfs_attr, attr); + return a->show ? a->show(sdp, buf) : 0; +} + +static ssize_t gfs_attr_store(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t len) +{ + struct gfs_sbd *sdp = container_of(kobj, struct gfs_sbd, sd_kobj); + struct gfs_attr *a = container_of(attr, struct gfs_attr, attr); + return a->store ? a->store(sdp, buf, len) : len; +} + +static struct sysfs_ops gfs_attr_ops = { + .show = gfs_attr_show, + .store = gfs_attr_store, +}; + +static struct kobj_type gfs_ktype = { + .default_attrs = gfs_attrs, + .sysfs_ops = &gfs_attr_ops, +}; + +static struct kset *gfs_kset; + +int gfs_sys_fs_add(struct gfs_sbd *sdp) +{ + int error; + + sdp->sd_kobj.kset = gfs_kset; + + error = kobject_init_and_add(&sdp->sd_kobj, &gfs_ktype, NULL, + "%s", sdp->sd_table_name); + if (error) + goto fail; + + kobject_uevent(&sdp->sd_kobj, KOBJ_ADD); + + return 0; + + fail: + return error; +} + +void gfs_sys_fs_del(struct gfs_sbd *sdp) +{ + kobject_put(&sdp->sd_kobj); +} + +int gfs_sys_init(void) +{ + gfs_sys_margs = NULL; + spin_lock_init(&gfs_sys_margs_lock); + gfs_kset = kset_create_and_add("gfs", NULL, fs_kobj); + if (!gfs_kset) + return -ENOMEM; + return 0; +} + +void gfs_sys_uninit(void) +{ + kfree(gfs_sys_margs); + kset_unregister(gfs_kset); +} --- linux-2.6.28.orig/ubuntu/gfs/ops_dentry.h +++ linux-2.6.28/ubuntu/gfs/ops_dentry.h @@ -0,0 +1,6 @@ +#ifndef __OPS_DENTRY_DOT_H__ +#define __OPS_DENTRY_DOT_H__ + +extern struct dentry_operations gfs_dops; + +#endif /* __OPS_DENTRY_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/ops_vm.h +++ linux-2.6.28/ubuntu/gfs/ops_vm.h @@ -0,0 +1,7 @@ +#ifndef __OPS_VM_DOT_H__ +#define __OPS_VM_DOT_H__ + +extern struct vm_operations_struct gfs_vm_ops_private; +extern struct vm_operations_struct gfs_vm_ops_sharewrite; + +#endif /* __OPS_VM_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/lops.c +++ linux-2.6.28/ubuntu/gfs/lops.c @@ -0,0 +1,1648 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "dio.h" +#include "glock.h" +#include "log.h" +#include "lops.h" +#include "quota.h" +#include "recovery.h" +#include "trans.h" +#include "unlinked.h" + +/** + * generic_le_add - generic routine to add a log element to a transaction + * @sdp: the filesystem + * @le: the log entry + * + */ + +static void +generic_le_add(struct gfs_sbd *sdp, struct gfs_log_element *le) +{ + struct gfs_trans *tr; + + /* Make sure it's not attached to a transaction already */ + gfs_assert(sdp, le->le_ops && + !le->le_trans && + list_empty(&le->le_list),); + + /* Attach it to the (one) transaction being built by this process */ + tr = get_transaction; + gfs_assert(sdp, tr,); + + le->le_trans = tr; + list_add(&le->le_list, &tr->tr_elements); +} + +/** + * glock_trans_end - drop a glock reference + * @sdp: the filesystem + * @le: the log element + * + * Called before incore-committing a transaction + * Release reference that was taken in gfs_trans_add_gl() + */ + +static void +glock_trans_end(struct gfs_sbd *sdp, struct gfs_log_element *le) +{ + struct gfs_glock *gl = container_of(le, struct gfs_glock, gl_new_le); + + gfs_assert(sdp, gfs_glock_is_locked_by_me(gl) && + gfs_glock_is_held_excl(gl),); + gfs_glock_put(gl); +} + +/** + * glock_print - print debug info about a log element + * @sdp: the filesystem + * @le: the log element + * @where: is this a new transaction or a incore transaction + * + */ + +static void +glock_print(struct gfs_sbd *sdp, struct gfs_log_element *le, unsigned int where) +{ + struct gfs_glock *gl; + + switch (where) { + case TRANS_IS_NEW: + gl = container_of(le, struct gfs_glock, gl_new_le); + break; + case TRANS_IS_INCORE: + gl = container_of(le, struct gfs_glock, gl_incore_le); + break; + default: + gfs_assert_warn(sdp, FALSE); + return; + } + + printk(" Glock: (%u, %"PRIu64")\n", + gl->gl_name.ln_type, + gl->gl_name.ln_number); +} + +/** + * glock_overlap_trans - Find any incore transactions that might overlap with + * (i.e. be combinable with the transaction containing) this LE + * @sdp: the filesystem + * @le: the log element + * + * Transactions that share a given glock are combinable. + * + * For a glock, the scope of the "search" is just the (max) one unique incore + * committed transaction to which the glock may be attached via its + * gl->gl_incore_le embedded log element. This trans may have previously + * been combined with other transactions, though (i.e. previous + * incore committed transactions that shared the same glock). + * + * Called as a beginning part of the incore commit of a transaction. + */ + +static struct gfs_trans * +glock_overlap_trans(struct gfs_sbd *sdp, struct gfs_log_element *le) +{ + struct gfs_glock *gl = container_of(le, struct gfs_glock, gl_new_le); + + return gl->gl_incore_le.le_trans; +} + +/** + * glock_incore_commit - commit this LE to the incore log + * @sdp: the filesystem + * @tr: the being-incore-committed transaction this LE is to be a part of + * @le: the log element (should be a gl->gl_new_le), which is attached + * to a "new" (just-ended) transaction. + * + * Attach glock's gl_incore_le to the being-incore-committed trans' LE list. + * Remove glock's gl_new_le from the just-ended new trans' LE list. + * If the just-ended new trans (le->le_trans) was combined (in incore_commit()) + * with a pre-existing incore trans (tr), this function effectively moves + * the LE from the new to the combined incore trans. + * If there was no combining, then the new trans itself is being committed + * (le->le_trans == tr); this function simply replaces the gl_new_le with a + * gl_incore_le on the trans' LE list. + * + * Make sure that this glock's gl_incore_le is attached to one and only one + * incore-committed transaction's (this one's) tr_elements list. + * One transaction (instead of a list of transactions) is sufficient, + * because incore_commit() combines multiple transactions that share a glock + * into one trans. + * Since transactions can contain multiple glocks, there are multiple + * possibilities for shared glocks, therefore multiple potential "bridges" + * for combining transactions. + */ + +static void +glock_incore_commit(struct gfs_sbd *sdp, struct gfs_trans *tr, + struct gfs_log_element *le) +{ + struct gfs_glock *gl = container_of(le, struct gfs_glock, gl_new_le); + + /* Transactions were combined, based on this glock */ + if (gl->gl_incore_le.le_trans) + gfs_assert(sdp, gl->gl_incore_le.le_trans == tr,); + else { + /* Attach gl->gl_incore_le to being-committed trans */ + gl->gl_incore_le.le_trans = tr; + list_add(&gl->gl_incore_le.le_list, &tr->tr_elements); + + /* If transactions were combined (via another shared glock), + the combined trans is getting a new glock log element */ + if (tr != le->le_trans) + tr->tr_num_gl++; + } + + /* Remove gl->gl_new_le from "new" trans */ + le->le_trans = NULL; + list_del_init(&le->le_list); +} + +/** + * glock_add_to_ail - Add this LE to the AIL + * @sdp: the filesystem + * @le: the log element + * + * Glocks don't really get added to AIL (there's nothing to write to disk), + * they just get removed from the transaction at this time. + */ + +static void +glock_add_to_ail(struct gfs_sbd *sdp, struct gfs_log_element *le) +{ + le->le_trans = NULL; + list_del_init(&le->le_list); +} + +/** + * glock_trans_combine - combine two incore transactions + * @sdp: the filesystem + * @tr: the surviving transaction + * @new_tr: the transaction that's going to disappear + * + */ + +static void +glock_trans_combine(struct gfs_sbd *sdp, struct gfs_trans *tr, + struct gfs_trans *new_tr) +{ + tr->tr_num_gl += new_tr->tr_num_gl; +} + +/** + * buf_print - print debug info about a log element + * @sdp: the filesystem + * @le: the log element + * @where: is this a new transaction or a incore transaction + * + */ + +static void +buf_print(struct gfs_sbd *sdp, struct gfs_log_element *le, unsigned int where) +{ + struct gfs_bufdata *bd; + + switch (where) { + case TRANS_IS_NEW: + bd = container_of(le, struct gfs_bufdata, bd_new_le); + break; + case TRANS_IS_INCORE: + bd = container_of(le, struct gfs_bufdata, bd_incore_le); + break; + default: + gfs_assert_warn(sdp, FALSE); + return; + } + + printk(" Buffer: %"PRIu64"\n", (uint64_t)bd->bd_bh->b_blocknr); +} + +/** + * buf_incore_commit - commit this buffer LE to the incore log + * @sdp: the filesystem + * @tr: the incore transaction this LE is a part of + * @le: the log element for the "new" (just now complete) trans + * + * Invoked from incore_commit(). + * Move this buffer from "new" stage to "incore committed" stage of the + * transaction pipeline. + * If this buffer was already attached to a pre-existing incore trans, GFS is + * combining the new and incore transactions; decrement buffer's recursive + * pin count that was incremented when it was added to the new transaction, + * and remove the reference to the "new" (being swallowed) trans. + * Else, move this buffer's attach point from "new" to "incore" embedded LE + * (same transaction, just new status) and add this buf to (incore) trans' + * LE list. + */ + +static void +buf_incore_commit(struct gfs_sbd *sdp, struct gfs_trans *tr, + struct gfs_log_element *le) +{ + struct gfs_bufdata *bd = container_of(le, struct gfs_bufdata, bd_new_le); + + /* We've completed our (atomic) changes to this buffer for this trans. + We no longer need the frozen copy. If frozen copy was not written + to on-disk log already, there's no longer a need to; we can now + write the "real" buffer (with more up-to-date content) instead. */ + if (bd->bd_frozen) { + kfree(bd->bd_frozen); + bd->bd_frozen = NULL; + } + + /* New trans being combined with pre-existing incore trans? */ + if (bd->bd_incore_le.le_trans) { + gfs_assert(sdp, bd->bd_incore_le.le_trans == tr,); + gfs_dunpin(sdp, bd->bd_bh, NULL); + } else { + bd->bd_incore_le.le_trans = tr; + list_add(&bd->bd_incore_le.le_list, &tr->tr_elements); + if (tr != le->le_trans) + tr->tr_num_buf++; + + sdp->sd_log_buffers++; + } + + /* Reset buffer's bd_new_le */ + le->le_trans = NULL; + list_del_init(&le->le_list); +} + +/** + * buf_add_to_ail - Add this LE to the AIL + * @sdp: the filesystem + * @le: the log element + * + */ + +static void +buf_add_to_ail(struct gfs_sbd *sdp, struct gfs_log_element *le) +{ + struct gfs_bufdata *bd = container_of(le, + struct gfs_bufdata, + bd_incore_le); + + gfs_dunpin(sdp, bd->bd_bh, le->le_trans); + + le->le_trans = NULL; + list_del_init(&le->le_list); + + gfs_assert(sdp, sdp->sd_log_buffers,); + sdp->sd_log_buffers--; +} + +/** + * buf_trans_size - compute how much space the LE class takes up in a transaction + * @sdp: the filesystem + * @tr: the transaction + * @mblks: the number of regular metadata blocks + * @eblks: the number of extra blocks + * @blocks: the number of log blocks + * @bmem: the number of buffer-sized chunks of memory we need + * + */ + +static void +buf_trans_size(struct gfs_sbd *sdp, struct gfs_trans *tr, + unsigned int *mblks, unsigned int *eblks, + unsigned int *blocks, unsigned int *bmem) +{ + unsigned int cblks; + + if (tr->tr_num_buf) { + cblks = gfs_struct2blk(sdp, tr->tr_num_buf, + sizeof(struct gfs_block_tag)); + + if (mblks) + *mblks += tr->tr_num_buf; + if (blocks) + *blocks += tr->tr_num_buf + cblks; + if (bmem) + *bmem += cblks; + } +} + +/** + * buf_trans_combine - combine two incore transactions + * @sdp: the filesystem + * @tr: the surviving transaction + * @new_tr: the transaction that's going to disappear + * + */ + +static void +buf_trans_combine(struct gfs_sbd *sdp, struct gfs_trans *tr, + struct gfs_trans *new_tr) +{ + tr->tr_num_buf += new_tr->tr_num_buf; +} + +/** + * increment_generation - increment the generation number in metadata buffer + * @sdp: the filesystem + * @bd: the struct gfs_bufdata structure associated with the buffer + * + * Increment the generation # of the most recent buffer contents, as well as + * that of frozen buffer, if any. If there is a frozen buffer, only *it* + * will be going to the log now ... in this case, the current buffer will + * have its gen # incremented again later, when it gets written to log. + * Gen # is used by journal recovery (replay_block()) to determine whether + * to overwrite an inplace block with the logged block contents. + */ + +static void +increment_generation(struct gfs_sbd *sdp, struct gfs_bufdata *bd) +{ + struct gfs_meta_header *mh, *mh2; + uint64_t tmp64; + + mh = (struct gfs_meta_header *)bd->bd_bh->b_data; + + tmp64 = gfs64_to_cpu(mh->mh_generation) + 1; + tmp64 = cpu_to_gfs64(tmp64); + + if (bd->bd_frozen) { + mh2 = (struct gfs_meta_header *)bd->bd_frozen; + gfs_assert(sdp, mh->mh_generation == mh2->mh_generation,); + mh2->mh_generation = tmp64; + } + mh->mh_generation = tmp64; +} + +/** + * buf_build_bhlist - create the buffers that will make up the ondisk part of a transaction + * @sdp: the filesystem + * @tr: the transaction + * + * Create the log (transaction) descriptor block + */ + +static void +buf_build_bhlist(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct list_head *tmp, *head; + struct gfs_log_element *le; + struct gfs_bufdata *bd; + struct gfs_log_descriptor desc; + struct gfs_block_tag tag; + struct gfs_log_buf *clb = NULL; + unsigned int num_ctl; + unsigned int offset = sizeof(struct gfs_log_descriptor); + unsigned int x, bufs; + + if (!tr->tr_num_buf) + return; + + /* set up control buffers for descriptor and tags */ + + num_ctl = gfs_struct2blk(sdp, tr->tr_num_buf, + sizeof(struct gfs_block_tag)); + + for (x = 0; x < num_ctl; x++) { + if (clb) + gfs_log_get_buf(sdp, tr); + else + clb = gfs_log_get_buf(sdp, tr); + } + + /* Init and copy log descriptor into 1st control block */ + memset(&desc, 0, sizeof(struct gfs_log_descriptor)); + desc.ld_header.mh_magic = GFS_MAGIC; + desc.ld_header.mh_type = GFS_METATYPE_LD; + desc.ld_header.mh_format = GFS_FORMAT_LD; + desc.ld_type = GFS_LOG_DESC_METADATA; + desc.ld_length = num_ctl + tr->tr_num_buf; + desc.ld_data1 = tr->tr_num_buf; + gfs_desc_out(&desc, clb->lb_bh.b_data); + + x = 1; + bufs = 0; + + for (head = &tr->tr_elements, tmp = head->next; + tmp != head; + tmp = tmp->next) { + le = list_entry(tmp, struct gfs_log_element, le_list); + + /* Skip over non-buffer (e.g. glock, unlinked, etc.) LEs */ + if (le->le_ops != &gfs_buf_lops) + continue; + + bd = container_of(le, struct gfs_bufdata, bd_incore_le); + + gfs_meta_check(sdp, bd->bd_bh); + + gfs_lock_buffer(bd->bd_bh); + + increment_generation(sdp, bd); + + /* Create "fake" buffer head to write block to on-disk log. Use + frozen copy if another transaction is modifying the "real" + buffer contents. Unlock real bh after log write completes, + so Linux can write real contents to inplace block. */ + gfs_log_fake_buf(sdp, tr, + (bd->bd_frozen) ? bd->bd_frozen : bd->bd_bh->b_data, + bd->bd_bh); + + /* find another buffer for tags if we're overflowing this one */ + if (offset + sizeof(struct gfs_block_tag) > sdp->sd_sb.sb_bsize) { + clb = list_entry(clb->lb_list.prev, + struct gfs_log_buf, lb_list); + if (gfs_log_is_header(sdp, clb->lb_bh.b_blocknr)) + clb = list_entry(clb->lb_list.prev, + struct gfs_log_buf, lb_list); + x++; + offset = 0; + } + + /* Write this LE's tag into a control buffer */ + memset(&tag, 0, sizeof(struct gfs_block_tag)); + tag.bt_blkno = bd->bd_bh->b_blocknr; + + gfs_block_tag_out(&tag, clb->lb_bh.b_data + offset); + + offset += sizeof(struct gfs_block_tag); + bufs++; + } + + gfs_assert(sdp, x == num_ctl,); + gfs_assert(sdp, bufs == tr->tr_num_buf,); +} + +/** + * buf_before_scan - called before journal replay + * @sdp: the filesystem + * @jid: the journal ID about to be replayed + * @head: the current head of the log + * @pass: the pass through the journal + * + */ + +static void +buf_before_scan(struct gfs_sbd *sdp, unsigned int jid, + struct gfs_log_header *head, unsigned int pass) +{ + if (pass == GFS_RECPASS_A1) + sdp->sd_recovery_replays = + sdp->sd_recovery_skips = + sdp->sd_recovery_sames = 0; +} + +/** + * replay_block - Replay a single metadata block + * @sdp: the filesystem + * @jdesc: the struct gfs_jindex structure for the journal being replayed + * @gl: the journal's glock + * @tag: the block tag describing the inplace location of the block + * @blkno: the location of the log's copy of the block + * + * Returns: errno + * + * Read in-place block from disk + * Read log (journal) block from disk + * Compare generation numbers + * Copy log block to in-place block on-disk if: + * log generation # > in-place generation # + * OR generation #s are ==, but data contained in block is different (corrupt) + */ + +static int +replay_block(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, struct gfs_block_tag *tag, uint64_t blkno) +{ + struct buffer_head *inplace_bh, *log_bh; + struct gfs_meta_header inplace_mh, log_mh; + int replay_block = TRUE; + int error = 0; + + gfs_replay_check(sdp); + + /* Warning: Using a real buffer here instead of a tempbh can be bad + on a OS that won't support multiple simultaneous buffers for the + same block on different glocks. */ + + error = gfs_dread(gl, tag->bt_blkno, + DIO_START | DIO_WAIT, &inplace_bh); + if (error) + return error; + if (gfs_meta_check(sdp, inplace_bh)) { + brelse(inplace_bh); + return -EIO; + } + gfs_meta_header_in(&inplace_mh, inplace_bh->b_data); + + error = gfs_dread(gl, blkno, DIO_START | DIO_WAIT, &log_bh); + if (error) { + brelse(inplace_bh); + return error; + } + if (gfs_meta_check(sdp, log_bh)) { + brelse(inplace_bh); + brelse(log_bh); + return -EIO; + } + gfs_meta_header_in(&log_mh, log_bh->b_data); + + if (log_mh.mh_generation < inplace_mh.mh_generation) { + replay_block = FALSE; + sdp->sd_recovery_skips++; + } else if (log_mh.mh_generation == inplace_mh.mh_generation) { + if (memcmp(log_bh->b_data, + inplace_bh->b_data, + sdp->sd_sb.sb_bsize) == 0) { + replay_block = FALSE; + sdp->sd_recovery_sames++; + } + } + + if (replay_block) { + memcpy(inplace_bh->b_data, + log_bh->b_data, + sdp->sd_sb.sb_bsize); + + error = gfs_replay_buf(gl, inplace_bh); + if (!error) + sdp->sd_recovery_replays++; + } + + brelse(log_bh); + brelse(inplace_bh); + + return error; +} + +/** + * buf_scan_elements - Replay a metadata log descriptor + * @sdp: the filesystem + * @jdesc: the struct gfs_jindex structure for the journal being replayed + * @gl: the journal's glock + * @start: the starting block of the descriptor + * @desc: the descriptor structure + * @pass: the pass through the journal + * + * Returns: errno + */ + +static int +buf_scan_elements(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, uint64_t start, + struct gfs_log_descriptor *desc, unsigned int pass) +{ + struct gfs_block_tag tag; + struct buffer_head *bh; + uint64_t cblk = start; + unsigned int num_tags = desc->ld_data1; + unsigned int offset = sizeof(struct gfs_log_descriptor); + unsigned int x; + int error; + + if (pass != GFS_RECPASS_A1) + return 0; + if (desc->ld_type != GFS_LOG_DESC_METADATA) + return 0; + + x = gfs_struct2blk(sdp, num_tags, sizeof(struct gfs_block_tag)); + while (x--) { + error = gfs_increment_blkno(sdp, jdesc, gl, &start, TRUE); + if (error) + return error; + } + + for (;;) { + gfs_assert(sdp, num_tags,); + + error = gfs_dread(gl, cblk, DIO_START | DIO_WAIT, &bh); + if (error) + return error; + + /* Do readahead for the inplace blocks in this control block */ + { + unsigned int o2 = offset; + unsigned int nt2 = num_tags; + + while (o2 + sizeof(struct gfs_block_tag) <= + sdp->sd_sb.sb_bsize) { + gfs_block_tag_in(&tag, bh->b_data + o2); + gfs_start_ra(gl, tag.bt_blkno, 1); + if (!--nt2) + break; + o2 += sizeof(struct gfs_block_tag); + } + } + + while (offset + sizeof(struct gfs_block_tag) <= + sdp->sd_sb.sb_bsize) { + gfs_block_tag_in(&tag, bh->b_data + offset); + + error = replay_block(sdp, jdesc, gl, &tag, start); + if (error) + goto out_drelse; + + if (!--num_tags) + goto out_drelse; + + error = gfs_increment_blkno(sdp, jdesc, gl, &start, TRUE); + if (error) + goto out_drelse; + + offset += sizeof(struct gfs_block_tag); + } + + brelse(bh); + + error = gfs_increment_blkno(sdp, jdesc, gl, &cblk, TRUE); + if (error) + return error; + + offset = 0; + } + + return 0; + + out_drelse: + brelse(bh); + + return error; +} + +/** + * buf_after_scan - called after journal replay + * @sdp: the filesystem + * @jid: the journal ID about to be replayed + * @pass: the pass through the journal + * + */ + +static void +buf_after_scan(struct gfs_sbd *sdp, unsigned int jid, unsigned int pass) +{ + if (pass == GFS_RECPASS_A1) { + printk("GFS: fsid=%s: jid=%u: Replayed %u of %u blocks\n", + sdp->sd_fsname, jid, + sdp->sd_recovery_replays, + sdp->sd_recovery_replays + sdp->sd_recovery_skips + + sdp->sd_recovery_sames); + printk("GFS: fsid=%s: jid=%u: replays = %u, skips = %u, sames = %u\n", + sdp->sd_fsname, jid, sdp->sd_recovery_replays, + sdp->sd_recovery_skips, sdp->sd_recovery_sames); + } +} + +/** + * unlinked_print - print debug info about a log element + * @sdp: the filesystem + * @le: the log element + * @where: is this a new transaction or a incore transaction + * + */ + +static void +unlinked_print(struct gfs_sbd *sdp, struct gfs_log_element *le, + unsigned int where) +{ + struct gfs_unlinked *ul; + char *type; + + switch (where) { + case TRANS_IS_NEW: + ul = container_of(le, struct gfs_unlinked, ul_new_le); + type = (test_bit(ULF_NEW_UL, &ul->ul_flags)) ? + "unlink" : "dealloc"; + break; + case TRANS_IS_INCORE: + ul = container_of(le, struct gfs_unlinked, ul_incore_le); + type = (test_bit(ULF_INCORE_UL, &ul->ul_flags)) ? + "unlink" : "dealloc"; + break; + default: + gfs_assert_warn(sdp, FALSE); + return; + } + + printk(" unlinked: %"PRIu64"/%"PRIu64", %s\n", + ul->ul_inum.no_formal_ino, ul->ul_inum.no_addr, + type); +} + +/** + * unlinked_incore_commit - commit this LE to the incore log + * @sdp: the filesystem + * @tr: the incore transaction this LE is a part of + * @le: the log element + * + */ + +static void +unlinked_incore_commit(struct gfs_sbd *sdp, struct gfs_trans *tr, + struct gfs_log_element *le) +{ + struct gfs_unlinked *ul = container_of(le, + struct gfs_unlinked, + ul_new_le); + int n = !!test_bit(ULF_NEW_UL, &ul->ul_flags); + int i = !!test_bit(ULF_INCORE_UL, &ul->ul_flags); + + if (ul->ul_incore_le.le_trans) { + gfs_assert(sdp, ul->ul_incore_le.le_trans == tr,); + gfs_assert(sdp, n != i,); + + ul->ul_incore_le.le_trans = NULL; + list_del_init(&ul->ul_incore_le.le_list); + gfs_unlinked_put(sdp, ul); + + if (i) { + gfs_assert(sdp, tr->tr_num_iul,); + tr->tr_num_iul--; + } else { + gfs_assert(sdp, tr->tr_num_ida,); + tr->tr_num_ida--; + } + } else { + gfs_unlinked_hold(sdp, ul); + ul->ul_incore_le.le_trans = tr; + list_add(&ul->ul_incore_le.le_list, &tr->tr_elements); + + if (n) { + set_bit(ULF_INCORE_UL, &ul->ul_flags); + if (tr != le->le_trans) + tr->tr_num_iul++; + } else { + clear_bit(ULF_INCORE_UL, &ul->ul_flags); + if (tr != le->le_trans) + tr->tr_num_ida++; + } + } + + if (n) { + gfs_unlinked_hold(sdp, ul); + gfs_assert(sdp, !test_bit(ULF_IC_LIST, &ul->ul_flags),); + set_bit(ULF_IC_LIST, &ul->ul_flags); + atomic_inc(&sdp->sd_unlinked_ic_count); + } else { + gfs_assert(sdp, test_bit(ULF_IC_LIST, &ul->ul_flags),); + clear_bit(ULF_IC_LIST, &ul->ul_flags); + gfs_unlinked_put(sdp, ul); + gfs_assert(sdp, atomic_read(&sdp->sd_unlinked_ic_count),); + atomic_dec(&sdp->sd_unlinked_ic_count); + } + + le->le_trans = NULL; + list_del_init(&le->le_list); + gfs_unlinked_put(sdp, ul); +} + +/** + * unlinked_add_to_ail - Add this LE to the AIL + * @sdp: the filesystem + * @le: the log element + * + */ + +static void +unlinked_add_to_ail(struct gfs_sbd *sdp, struct gfs_log_element *le) +{ + struct gfs_unlinked *ul = container_of(le, + struct gfs_unlinked, + ul_incore_le); + int i = !!test_bit(ULF_INCORE_UL, &ul->ul_flags); + + if (i) { + gfs_unlinked_hold(sdp, ul); + gfs_assert(sdp, !test_bit(ULF_OD_LIST, &ul->ul_flags),); + set_bit(ULF_OD_LIST, &ul->ul_flags); + atomic_inc(&sdp->sd_unlinked_od_count); + } else { + gfs_assert(sdp, test_bit(ULF_OD_LIST, &ul->ul_flags),); + clear_bit(ULF_OD_LIST, &ul->ul_flags); + gfs_unlinked_put(sdp, ul); + gfs_assert(sdp, atomic_read(&sdp->sd_unlinked_od_count),); + atomic_dec(&sdp->sd_unlinked_od_count); + } + + le->le_trans = NULL; + list_del_init(&le->le_list); + gfs_unlinked_put(sdp, ul); +} + +/** + * unlinked_clean_dump - clean up a LE after a log dump + * @sdp: the filesystem + * @le: the log element + * + */ + +static void +unlinked_clean_dump(struct gfs_sbd *sdp, struct gfs_log_element *le) +{ + le->le_trans = NULL; + list_del_init(&le->le_list); +} + +/** + * unlinked_trans_size - compute how much space the LE class takes up in a transaction + * @sdp: the filesystem + * @tr: the transaction + * @mblks: the number of regular metadata blocks + * @eblks: the number of extra blocks + * @blocks: the number of log blocks + * @bmem: the number of buffer-sized chunks of memory we need + * + */ + +static void +unlinked_trans_size(struct gfs_sbd *sdp, struct gfs_trans *tr, + unsigned int *mblks, unsigned int *eblks, + unsigned int *blocks, unsigned int *bmem) +{ + unsigned int ublks = 0; + + if (tr->tr_num_iul) + ublks = gfs_struct2blk(sdp, tr->tr_num_iul, + sizeof(struct gfs_inum)); + if (tr->tr_num_ida) + ublks += gfs_struct2blk(sdp, tr->tr_num_ida, + sizeof(struct gfs_inum)); + + if (eblks) + *eblks += ublks; + if (blocks) + *blocks += ublks; + if (bmem) + *bmem += ublks; +} + +/** + * unlinked_trans_combine - combine two incore transactions + * @sdp: the filesystem + * @tr: the surviving transaction + * @new_tr: the transaction that's going to disappear + * + */ + +static void +unlinked_trans_combine(struct gfs_sbd *sdp, struct gfs_trans *tr, + struct gfs_trans *new_tr) +{ + tr->tr_num_iul += new_tr->tr_num_iul; + tr->tr_num_ida += new_tr->tr_num_ida; +} + +/** + * unlinked_build_bhlist - create the buffers that will make up the ondisk part of a transaction + * @sdp: the filesystem + * @tr: the transaction + * + * For unlinked and/or deallocated inode log elements (separately): + * Get a log block + * Create a log descriptor in beginning of that block + * Fill rest of block with gfs_inum structs to identify each inode + * that became unlinked/deallocated during this transaction. + * Get another log block if needed, continue filling with gfs_inums. + */ + +static void +unlinked_build_bhlist(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct list_head *tmp, *head; + struct gfs_log_element *le; + struct gfs_unlinked *ul; + struct gfs_log_descriptor desc; + struct gfs_log_buf *lb; + unsigned int pass = 2; + unsigned int type, number; + unsigned int offset, entries; + + /* 2 passes: 1st for Unlinked, 2nd for De-Alloced inodes, + unless this is a log dump: just 1 pass, for Unlinked */ + while (pass--) { + if (tr->tr_flags & TRF_LOG_DUMP) { + if (pass) { + type = GFS_LOG_DESC_IUL; + number = tr->tr_num_iul; + } else + break; + } else { + if (pass) { + type = GFS_LOG_DESC_IUL; + number = tr->tr_num_iul; + } else { + type = GFS_LOG_DESC_IDA; + number = tr->tr_num_ida; + } + + if (!number) + continue; + } + + lb = gfs_log_get_buf(sdp, tr); + + /* Header: log descriptor */ + memset(&desc, 0, sizeof(struct gfs_log_descriptor)); + desc.ld_header.mh_magic = GFS_MAGIC; + desc.ld_header.mh_type = GFS_METATYPE_LD; + desc.ld_header.mh_format = GFS_FORMAT_LD; + desc.ld_type = type; + desc.ld_length = gfs_struct2blk(sdp, number, sizeof(struct gfs_inum)); + desc.ld_data1 = (tr->tr_flags & TRF_LOG_DUMP) ? TRUE : FALSE; + gfs_desc_out(&desc, lb->lb_bh.b_data); + + offset = sizeof(struct gfs_log_descriptor); + entries = 0; + + /* Look through transaction's log elements for Unlinked LEs */ + for (head = &tr->tr_elements, tmp = head->next; + tmp != head; + tmp = tmp->next) { + le = list_entry(tmp, struct gfs_log_element, le_list); + if (le->le_ops != &gfs_unlinked_lops) + continue; + if (tr->tr_flags & TRF_LOG_DUMP) + ul = container_of(le, + struct gfs_unlinked, + ul_ondisk_le); + else { + ul = container_of(le, + struct gfs_unlinked, + ul_incore_le); + if (!!test_bit(ULF_INCORE_UL, &ul->ul_flags) != pass) + continue; + } + + if (offset + sizeof(struct gfs_inum) > sdp->sd_sb.sb_bsize) { + offset = 0; + lb = gfs_log_get_buf(sdp, tr); + } + + /* Payload: write the inode identifier */ + gfs_inum_out(&ul->ul_inum, + lb->lb_bh.b_data + offset); + + offset += sizeof(struct gfs_inum); + entries++; + } + + gfs_assert(sdp, entries == number,); + } +} + +/** + * unlinked_dump_size - compute how much space the LE class takes up in a log dump + * @sdp: the filesystem + * @elements: the number of log elements in the dump + * @blocks: the number of blocks in the dump + * @bmem: the number of buffer-sized chunks of memory we need + * + */ + +static void +unlinked_dump_size(struct gfs_sbd *sdp, unsigned int *elements, + unsigned int *blocks, unsigned int *bmem) +{ + unsigned int c = atomic_read(&sdp->sd_unlinked_od_count); + unsigned int b = gfs_struct2blk(sdp, c, sizeof(struct gfs_inum)); + + if (elements) + *elements += c; + if (blocks) + *blocks += b; + if (bmem) + *bmem += b; +} + +/** + * unlinked_build_dump - create a transaction that represents a log dump for this LE class + * @sdp: the filesystem + * @tr: the transaction to fill + * + */ + +static void +unlinked_build_dump(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct list_head *tmp, *head; + struct gfs_unlinked *ul; + unsigned int x = 0; + + tr->tr_num_iul = atomic_read(&sdp->sd_unlinked_od_count); + + spin_lock(&sdp->sd_unlinked_lock); + + for (head = &sdp->sd_unlinked_list, tmp = head->next; + tmp != head; + tmp = tmp->next) { + ul = list_entry(tmp, struct gfs_unlinked, ul_list); + if (!test_bit(ULF_OD_LIST, &ul->ul_flags)) + continue; + + gfs_assert(sdp, !ul->ul_ondisk_le.le_trans,); + ul->ul_ondisk_le.le_trans = tr; + list_add(&ul->ul_ondisk_le.le_list, &tr->tr_elements); + + x++; + } + + spin_unlock(&sdp->sd_unlinked_lock); + + gfs_assert(sdp, x == atomic_read(&sdp->sd_unlinked_od_count),); +} + +/** + * unlinked_before_scan - called before a log dump is recovered + * @sdp: the filesystem + * @jid: the journal ID about to be scanned + * @head: the current head of the log + * @pass: the pass through the journal + * + */ + +static void +unlinked_before_scan(struct gfs_sbd *sdp, unsigned int jid, + struct gfs_log_header *head, unsigned int pass) +{ + if (pass == GFS_RECPASS_B1) + clear_bit(SDF_FOUND_UL_DUMP, &sdp->sd_flags); +} + +/** + * unlinked_scan_elements - scan unlinked inodes from the journal + * @sdp: the filesystem + * @jdesc: the struct gfs_jindex structure for the journal being scaned + * @gl: the journal's glock + * @start: the starting block of the descriptor + * @desc: the descriptor structure + * @pass: the pass through the journal + * + * Returns: errno + */ + +static int +unlinked_scan_elements(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, uint64_t start, + struct gfs_log_descriptor *desc, unsigned int pass) +{ + struct gfs_inum inum; + struct buffer_head *bh; + unsigned int offset = sizeof(struct gfs_log_descriptor); + unsigned int x; + int error; + + if (pass != GFS_RECPASS_B1) + return 0; + + switch (desc->ld_type) { + case GFS_LOG_DESC_IUL: + if (test_bit(SDF_FOUND_UL_DUMP, &sdp->sd_flags)) + gfs_assert(sdp, !desc->ld_data1,); + else { + gfs_assert(sdp, desc->ld_data1,); + set_bit(SDF_FOUND_UL_DUMP, &sdp->sd_flags); + } + break; + + case GFS_LOG_DESC_IDA: + gfs_assert(sdp, test_bit(SDF_FOUND_UL_DUMP, &sdp->sd_flags),); + break; + + default: + return 0; + } + + for (x = 0; x < desc->ld_length; x++) { + error = gfs_dread(gl, start, DIO_START | DIO_WAIT, &bh); + if (error) + return error; + + for (; + offset + sizeof(struct gfs_inum) <= sdp->sd_sb.sb_bsize; + offset += sizeof(struct gfs_inum)) { + gfs_inum_in(&inum, bh->b_data + offset); + + if (inum.no_addr) + gfs_unlinked_merge(sdp, desc->ld_type, &inum); + } + + brelse(bh); + + error = gfs_increment_blkno(sdp, jdesc, gl, &start, TRUE); + if (error) + return error; + + offset = 0; + } + + return 0; +} + +/** + * unlinked_after_scan - called after a log dump is recovered + * @sdp: the filesystem + * @jid: the journal ID about to be scanned + * @pass: the pass through the journal + * + */ + +static void +unlinked_after_scan(struct gfs_sbd *sdp, unsigned int jid, unsigned int pass) +{ + if (pass == GFS_RECPASS_B1) { + gfs_assert(sdp, test_bit(SDF_FOUND_UL_DUMP, &sdp->sd_flags),); + printk("GFS: fsid=%s: Found %d unlinked inodes\n", + sdp->sd_fsname, atomic_read(&sdp->sd_unlinked_ic_count)); + } +} + +/** + * quota_print - print debug info about a log element + * @sdp: the filesystem + * @le: the log element + * @where: is this a new transaction or a incore transaction + * + */ + +static void +quota_print(struct gfs_sbd *sdp, struct gfs_log_element *le, unsigned int where) +{ + struct gfs_quota_le *ql; + + ql = container_of(le, struct gfs_quota_le, ql_le); + printk(" quota: %s %u: %"PRId64" blocks\n", + (test_bit(QDF_USER, &ql->ql_data->qd_flags)) ? "user" : "group", + ql->ql_data->qd_id, ql->ql_change); +} + +/** + * quota_incore_commit - commit this LE to the incore log + * @sdp: the filesystem + * @tr: the incore transaction this LE is a part of + * @le: the log element + * + */ + +static void +quota_incore_commit(struct gfs_sbd *sdp, struct gfs_trans *tr, + struct gfs_log_element *le) +{ + struct gfs_quota_le *ql = container_of(le, struct gfs_quota_le, ql_le); + struct gfs_quota_data *qd = ql->ql_data; + + gfs_assert(sdp, ql->ql_change,); + + /* Make this change under the sd_quota_lock, so other processes + checking qd_change_ic don't have to acquire the log lock. */ + + spin_lock(&sdp->sd_quota_lock); + qd->qd_change_new -= ql->ql_change; + qd->qd_change_ic += ql->ql_change; + spin_unlock(&sdp->sd_quota_lock); + + if (le->le_trans == tr) + list_add(&ql->ql_data_list, &qd->qd_le_list); + else { + struct list_head *tmp, *head; + struct gfs_quota_le *tmp_ql; + int found = FALSE; + + for (head = &qd->qd_le_list, tmp = head->next; + tmp != head; + tmp = tmp->next) { + tmp_ql = list_entry(tmp, struct gfs_quota_le, ql_data_list); + if (tmp_ql->ql_le.le_trans != tr) + continue; + + tmp_ql->ql_change += ql->ql_change; + + list_del(&le->le_list); + gfs_quota_put(sdp, qd); + kfree(ql); + + if (!tmp_ql->ql_change) { + list_del(&tmp_ql->ql_data_list); + list_del(&tmp_ql->ql_le.le_list); + gfs_quota_put(sdp, tmp_ql->ql_data); + kfree(tmp_ql); + tr->tr_num_q--; + } + + found = TRUE; + break; + } + + if (!found) { + le->le_trans = tr; + list_move(&le->le_list, &tr->tr_elements); + tr->tr_num_q++; + list_add(&ql->ql_data_list, &qd->qd_le_list); + } + } +} + +/** + * quota_add_to_ail - Add this LE to the AIL + * @sdp: the filesystem + * @le: the log element + * + */ + +static void +quota_add_to_ail(struct gfs_sbd *sdp, struct gfs_log_element *le) +{ + struct gfs_quota_le *ql = container_of(le, struct gfs_quota_le, ql_le); + struct gfs_quota_data *qd = ql->ql_data; + + qd->qd_change_od += ql->ql_change; + if (qd->qd_change_od) { + if (!test_bit(QDF_OD_LIST, &qd->qd_flags)) { + gfs_quota_hold(sdp, qd); + set_bit(QDF_OD_LIST, &qd->qd_flags); + atomic_inc(&sdp->sd_quota_od_count); + } + } else { + gfs_assert(sdp, test_bit(QDF_OD_LIST, &qd->qd_flags),); + clear_bit(QDF_OD_LIST, &qd->qd_flags); + gfs_quota_put(sdp, qd); + gfs_assert(sdp, atomic_read(&sdp->sd_quota_od_count),); + atomic_dec(&sdp->sd_quota_od_count); + } + + list_del(&ql->ql_data_list); + list_del(&le->le_list); + gfs_quota_put(sdp, qd); + kfree(ql); +} + +/** + * quota_clean_dump - clean up a LE after a log dump + * @sdp: the filesystem + * @le: the log element + * + */ + +static void +quota_clean_dump(struct gfs_sbd *sdp, struct gfs_log_element *le) +{ + le->le_trans = NULL; + list_del_init(&le->le_list); +} + +/** + * quota_trans_size - compute how much space the LE class takes up in a transaction + * @sdp: the filesystem + * @tr: the transaction + * @mblks: the number of regular metadata blocks + * @eblks: the number of extra blocks + * @blocks: the number of log blocks + * @bmem: the number of buffer-sized chunks of memory we need + * + */ + +static void +quota_trans_size(struct gfs_sbd *sdp, struct gfs_trans *tr, + unsigned int *mblks, unsigned int *eblks, + unsigned int *blocks, unsigned int *bmem) +{ + unsigned int qblks; + + if (tr->tr_num_q) { + qblks = gfs_struct2blk(sdp, tr->tr_num_q, + sizeof(struct gfs_quota_tag)); + + if (eblks) + *eblks += qblks; + if (blocks) + *blocks += qblks; + if (bmem) + *bmem += qblks; + } +} + +/** + * quota_trans_combine - combine two incore transactions + * @sdp: the filesystem + * @tr: the surviving transaction + * @new_tr: the transaction that's going to disappear + * + */ + +static void +quota_trans_combine(struct gfs_sbd *sdp, struct gfs_trans *tr, + struct gfs_trans *new_tr) +{ + tr->tr_num_q += new_tr->tr_num_q; +} + +/** + * quota_build_bhlist - create the buffers that will make up the ondisk part of a transaction + * @sdp: the filesystem + * @tr: the transaction + * + */ + +static void +quota_build_bhlist(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct list_head *tmp, *head; + struct gfs_log_element *le; + struct gfs_quota_le *ql; + struct gfs_log_descriptor desc; + struct gfs_quota_tag tag; + struct gfs_log_buf *lb; + unsigned int offset = sizeof(struct gfs_log_descriptor), entries = 0; + + if (!tr->tr_num_q && !(tr->tr_flags & TRF_LOG_DUMP)) + return; + + lb = gfs_log_get_buf(sdp, tr); + + memset(&desc, 0, sizeof(struct gfs_log_descriptor)); + desc.ld_header.mh_magic = GFS_MAGIC; + desc.ld_header.mh_type = GFS_METATYPE_LD; + desc.ld_header.mh_format = GFS_FORMAT_LD; + desc.ld_type = GFS_LOG_DESC_Q; + desc.ld_length = gfs_struct2blk(sdp, tr->tr_num_q, + sizeof(struct gfs_quota_tag)); + desc.ld_data1 = tr->tr_num_q; + desc.ld_data2 = (tr->tr_flags & TRF_LOG_DUMP) ? TRUE : FALSE; + gfs_desc_out(&desc, lb->lb_bh.b_data); + + for (head = &tr->tr_elements, tmp = head->next; + tmp != head; + tmp = tmp->next) { + le = list_entry(tmp, struct gfs_log_element, le_list); + if (le->le_ops != &gfs_quota_lops) + continue; + + ql = container_of(le, struct gfs_quota_le, ql_le); + + if (offset + sizeof(struct gfs_quota_tag) > + sdp->sd_sb.sb_bsize) { + offset = 0; + lb = gfs_log_get_buf(sdp, tr); + } + + memset(&tag, 0, sizeof(struct gfs_quota_tag)); + tag.qt_change = ql->ql_change; + tag.qt_flags = (test_bit(QDF_USER, &ql->ql_data->qd_flags)) ? + GFS_QTF_USER : 0; + tag.qt_id = ql->ql_data->qd_id; + + gfs_quota_tag_out(&tag, lb->lb_bh.b_data + offset); + + offset += sizeof(struct gfs_quota_tag); + entries++; + } + + gfs_assert(sdp, entries == tr->tr_num_q,); +} + +/** + * quota_dump_size - compute how much space the LE class takes up in a log dump + * @sdp: the filesystem + * @elements: the number of log elements in the dump + * @blocks: the number of blocks in the dump + * @bmem: the number of buffer-sized chunks of memory we need + * + */ + +static void +quota_dump_size(struct gfs_sbd *sdp, unsigned int *elements, + unsigned int *blocks, unsigned int *bmem) +{ + unsigned int c = atomic_read(&sdp->sd_quota_od_count); + unsigned int b = gfs_struct2blk(sdp, c, sizeof(struct gfs_quota_tag)); + + if (elements) + *elements += c; + if (blocks) + *blocks += b; + if (bmem) + *bmem += b; +} + +/** + * quota_build_dump - create a transaction that represents a log dump for this LE class + * @sdp: the filesystem + * @tr: the transaction to fill + * + */ + +static void +quota_build_dump(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct list_head *tmp, *head; + struct gfs_quota_data *qd; + struct gfs_quota_le *ql; + unsigned int x = 0; + + tr->tr_num_q = atomic_read(&sdp->sd_quota_od_count); + + spin_lock(&sdp->sd_quota_lock); + + for (head = &sdp->sd_quota_list, tmp = head->next; + tmp != head; + tmp = tmp->next) { + qd = list_entry(tmp, struct gfs_quota_data, qd_list); + if (!test_bit(QDF_OD_LIST, &qd->qd_flags)) + continue; + + ql = &qd->qd_ondisk_ql; + + ql->ql_le.le_ops = &gfs_quota_lops; + gfs_assert(sdp, !ql->ql_le.le_trans,); + ql->ql_le.le_trans = tr; + list_add(&ql->ql_le.le_list, &tr->tr_elements); + + ql->ql_data = qd; + ql->ql_change = qd->qd_change_od; + + x++; + } + + spin_unlock(&sdp->sd_quota_lock); + + gfs_assert(sdp, x == atomic_read(&sdp->sd_quota_od_count),); +} + +/** + * quota_before_scan - called before a log dump is recovered + * @sdp: the filesystem + * @jid: the journal ID about to be scanned + * @head: the current head of the log + * @pass: the pass through the journal + * + */ + +static void +quota_before_scan(struct gfs_sbd *sdp, unsigned int jid, + struct gfs_log_header *head, unsigned int pass) +{ + if (pass == GFS_RECPASS_B1) + clear_bit(SDF_FOUND_Q_DUMP, &sdp->sd_flags); +} + +/** + * quota_scan_elements - scan quota inodes from the journal + * @sdp: the filesystem + * @jdesc: the struct gfs_jindex structure for the journal being scaned + * @gl: the journal's glock + * @start: the starting block of the descriptor + * @desc: the descriptor structure + * @pass: the pass through the journal + * + * Returns: errno + */ + +static int +quota_scan_elements(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, uint64_t start, + struct gfs_log_descriptor *desc, unsigned int pass) +{ + struct gfs_quota_tag tag; + struct buffer_head *bh; + unsigned int num_tags = desc->ld_data1; + unsigned int offset = sizeof(struct gfs_log_descriptor); + unsigned int x; + int error; + + if (pass != GFS_RECPASS_B1) + return 0; + if (desc->ld_type != GFS_LOG_DESC_Q) + return 0; + + if (test_bit(SDF_FOUND_Q_DUMP, &sdp->sd_flags)) + gfs_assert(sdp, !desc->ld_data2,); + else { + gfs_assert(sdp, desc->ld_data2,); + set_bit(SDF_FOUND_Q_DUMP, &sdp->sd_flags); + } + + if (!num_tags) + return 0; + + for (x = 0; x < desc->ld_length; x++) { + error = gfs_dread(gl, start, DIO_START | DIO_WAIT, &bh); + if (error) + return error; + + while (offset + sizeof(struct gfs_quota_tag) <= + sdp->sd_sb.sb_bsize) { + gfs_quota_tag_in(&tag, bh->b_data + offset); + + error = gfs_quota_merge(sdp, &tag); + if (error) + goto out_drelse; + + if (!--num_tags) + goto out_drelse; + + offset += sizeof(struct gfs_quota_tag); + } + + brelse(bh); + + error = gfs_increment_blkno(sdp, jdesc, gl, &start, TRUE); + if (error) + return error; + + offset = 0; + } + + return 0; + + out_drelse: + brelse(bh); + + return error; +} + +/** + * quota_after_scan - called after a log dump is recovered + * @sdp: the filesystem + * @jid: the journal ID about to be scanned + * @pass: the pass through the journal + * + */ + +static void +quota_after_scan(struct gfs_sbd *sdp, unsigned int jid, unsigned int pass) +{ + if (pass == GFS_RECPASS_B1) { + gfs_assert(sdp, !sdp->sd_sb.sb_quota_di.no_formal_ino || + test_bit(SDF_FOUND_Q_DUMP, &sdp->sd_flags),); + printk("GFS: fsid=%s: Found quota changes for %d IDs\n", + sdp->sd_fsname, atomic_read(&sdp->sd_quota_od_count)); + } +} + +struct gfs_log_operations gfs_glock_lops = { + .lo_add = generic_le_add, + .lo_trans_end = glock_trans_end, + .lo_print = glock_print, + .lo_overlap_trans = glock_overlap_trans, + .lo_incore_commit = glock_incore_commit, + .lo_add_to_ail = glock_add_to_ail, + .lo_trans_combine = glock_trans_combine, + .lo_name = "glock" +}; + +struct gfs_log_operations gfs_buf_lops = { + .lo_add = generic_le_add, + .lo_print = buf_print, + .lo_incore_commit = buf_incore_commit, + .lo_add_to_ail = buf_add_to_ail, + .lo_trans_size = buf_trans_size, + .lo_trans_combine = buf_trans_combine, + .lo_build_bhlist = buf_build_bhlist, + .lo_before_scan = buf_before_scan, + .lo_scan_elements = buf_scan_elements, + .lo_after_scan = buf_after_scan, + .lo_name = "buf" +}; + +struct gfs_log_operations gfs_unlinked_lops = { + .lo_add = generic_le_add, + .lo_print = unlinked_print, + .lo_incore_commit = unlinked_incore_commit, + .lo_add_to_ail = unlinked_add_to_ail, + .lo_clean_dump = unlinked_clean_dump, + .lo_trans_size = unlinked_trans_size, + .lo_trans_combine = unlinked_trans_combine, + .lo_build_bhlist = unlinked_build_bhlist, + .lo_dump_size = unlinked_dump_size, + .lo_build_dump = unlinked_build_dump, + .lo_before_scan = unlinked_before_scan, + .lo_scan_elements = unlinked_scan_elements, + .lo_after_scan = unlinked_after_scan, + .lo_name = "unlinked" +}; + +struct gfs_log_operations gfs_quota_lops = { + .lo_add = generic_le_add, + .lo_print = quota_print, + .lo_incore_commit = quota_incore_commit, + .lo_add_to_ail = quota_add_to_ail, + .lo_clean_dump = quota_clean_dump, + .lo_trans_size = quota_trans_size, + .lo_trans_combine = quota_trans_combine, + .lo_build_bhlist = quota_build_bhlist, + .lo_dump_size = quota_dump_size, + .lo_build_dump = quota_build_dump, + .lo_before_scan = quota_before_scan, + .lo_scan_elements = quota_scan_elements, + .lo_after_scan = quota_after_scan, + .lo_name = "quota" +}; + +struct gfs_log_operations *gfs_log_ops[] = { + &gfs_glock_lops, + &gfs_buf_lops, + &gfs_unlinked_lops, + &gfs_quota_lops, + NULL +}; --- linux-2.6.28.orig/ubuntu/gfs/daemon.c +++ linux-2.6.28/ubuntu/gfs/daemon.c @@ -0,0 +1,181 @@ +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "daemon.h" +#include "glock.h" +#include "log.h" +#include "quota.h" +#include "recovery.h" +#include "super.h" +#include "unlinked.h" + +/** + * gfs_scand - Look for cached glocks and inodes to toss from memory + * @sdp: Pointer to GFS superblock + * + * One of these daemons runs, finding candidates to add to sd_reclaim_list. + * See gfs_glockd() + */ + +int +gfs_scand(void *data) +{ + struct gfs_sbd *sdp = (struct gfs_sbd *)data; + + while (!kthread_should_stop()) { + gfs_scand_internal(sdp); + schedule_timeout_interruptible(gfs_tune_get(sdp, gt_scand_secs) * HZ); + } + + return 0; +} + +/** + * gfs_glockd - Reclaim unused glock structures + * @sdp: Pointer to GFS superblock + * + * One or more of these daemons run, reclaiming glocks on sd_reclaim_list. + * sd_glockd_num says how many daemons are running now. + * Number of daemons can be set by user, with num_glockd mount option. + * See gfs_scand() + */ + +int +gfs_glockd(void *data) +{ + struct gfs_sbd *sdp = (struct gfs_sbd *)data; + + while (!kthread_should_stop()) { + while (atomic_read(&sdp->sd_reclaim_count)) + gfs_reclaim_glock(sdp); + + wait_event_interruptible(sdp->sd_reclaim_wchan, + (atomic_read(&sdp->sd_reclaim_count) || + kthread_should_stop())); + } + + return 0; +} + +/** + * gfs_recoverd - Recover dead machine's journals + * @sdp: Pointer to GFS superblock + * + */ + +int +gfs_recoverd(void *data) +{ + struct gfs_sbd *sdp = (struct gfs_sbd *)data; + + while (!kthread_should_stop()) { + gfs_check_journals(sdp); + schedule_timeout_interruptible(gfs_tune_get(sdp, gt_recoverd_secs) * HZ); + } + + return 0; +} + +/** + * gfs_logd - Update log tail as Active Items get flushed to in-place blocks + * @sdp: Pointer to GFS superblock + * + * Also, periodically check to make sure that we're using the most recent + * journal index. + */ + +int +gfs_logd(void *data) +{ + struct gfs_sbd *sdp = (struct gfs_sbd *)data; + struct gfs_holder ji_gh; + + while (!kthread_should_stop()) { + /* Advance the log tail */ + gfs_ail_empty(sdp); + + /* Check for latest journal index */ + if (time_after_eq(jiffies, + sdp->sd_jindex_refresh_time + + gfs_tune_get(sdp, gt_jindex_refresh_secs) * HZ)) { + if (test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags) && + !gfs_jindex_hold(sdp, &ji_gh)) + gfs_glock_dq_uninit(&ji_gh); + sdp->sd_jindex_refresh_time = jiffies; + } + + schedule_timeout_interruptible(gfs_tune_get(sdp, gt_logd_secs) * HZ); + } + + return 0; +} + +/** + * gfs_quotad - Write cached quota changes into the quota file + * @sdp: Pointer to GFS superblock + * + */ + +int +gfs_quotad(void *data) +{ + struct gfs_sbd *sdp = (struct gfs_sbd *)data; + int error; + + while (!kthread_should_stop()) { + /* Update statfs file */ + if (gfs_tune_get(sdp, gt_statfs_fast) && + time_after_eq(jiffies, + sdp->sd_statfs_sync_time + + gfs_tune_get(sdp, gt_statfs_fast) * HZ)) { + error = gfs_statfs_sync(sdp); + if (error && error != -EROFS && + !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) + printk("GFS: fsid=%s: statfs: error = %d\n", + sdp->sd_fsname, error); + sdp->sd_statfs_sync_time = jiffies; + } + /* Update quota file */ + if (time_after_eq(jiffies, + sdp->sd_quota_sync_time + + gfs_tune_get(sdp, gt_quota_quantum) * HZ)) { + error = gfs_quota_sync(sdp); + if (error && + error != -EROFS && + !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) + printk("GFS: fsid=%s: quotad: error = %d\n", + sdp->sd_fsname, error); + sdp->sd_quota_sync_time = jiffies; + } + + /* Clean up */ + gfs_quota_scan(sdp); + schedule_timeout_interruptible(gfs_tune_get(sdp, gt_quotad_secs) * HZ); + } + + return 0; +} + +/** + * gfs_inoded - Deallocate unlinked inodes + * @sdp: Pointer to GFS superblock + * + */ + +int +gfs_inoded(void *data) +{ + struct gfs_sbd *sdp = (struct gfs_sbd *)data; + + while (!kthread_should_stop()) { + gfs_unlinked_dealloc(sdp); + schedule_timeout_interruptible(gfs_tune_get(sdp, gt_inoded_secs) * HZ); + } + + return 0; +} --- linux-2.6.28.orig/ubuntu/gfs/Kconfig +++ linux-2.6.28/ubuntu/gfs/Kconfig @@ -0,0 +1,18 @@ +config GFS_FS + tristate "GFS file system support" + select FS_POSIX_ACL + select CRC32 + help + A cluster filesystem. + + Allows a cluster of computers to simultaneously use a block device + that is shared between them (with FC, iSCSI, NBD, etc...). GFS reads + and writes to the block device like a local filesystem, but also uses + a lock module to allow the computers coordinate their I/O so + filesystem consistency is maintained. One of the nifty features of + GFS is perfect consistency -- changes made to the filesystem on one + machine show up immediately on all other machines in the cluster. + + To use the GFS filesystem, you will need to enable one or more of + the below locking modules. Documentation and utilities for GFS can + be found here: http://sources.redhat.com/cluster --- linux-2.6.28.orig/ubuntu/gfs/glops.h +++ linux-2.6.28/ubuntu/gfs/glops.h @@ -0,0 +1,13 @@ +#ifndef __GLOPS_DOT_H__ +#define __GLOPS_DOT_H__ + +extern struct gfs_glock_operations gfs_meta_glops; +extern struct gfs_glock_operations gfs_inode_glops; +extern struct gfs_glock_operations gfs_rgrp_glops; +extern struct gfs_glock_operations gfs_trans_glops; +extern struct gfs_glock_operations gfs_iopen_glops; +extern struct gfs_glock_operations gfs_flock_glops; +extern struct gfs_glock_operations gfs_nondisk_glops; +extern struct gfs_glock_operations gfs_quota_glops; + +#endif /* __GLOPS_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/ops_fstype.c +++ linux-2.6.28/ubuntu/gfs/ops_fstype.c @@ -0,0 +1,816 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "daemon.h" +#include "glock.h" +#include "glops.h" +#include "inode.h" +#include "lm.h" +#include "mount.h" +#include "ops_export.h" +#include "ops_fstype.h" +#include "ops_super.h" +#include "proc.h" +#include "quota.h" +#include "recovery.h" +#include "rgrp.h" +#include "super.h" +#include "sys.h" +#include "unlinked.h" + +#define DO 0 +#define UNDO 1 + +extern struct dentry_operations gfs_dops; + +static struct gfs_sbd *init_sbd(struct super_block *sb) +{ + struct gfs_sbd *sdp; + unsigned int x; + + sdp = vmalloc(sizeof(struct gfs_sbd)); + if (!sdp) + return NULL; + + memset(sdp, 0, sizeof(struct gfs_sbd)); + + set_v2sdp(sb, sdp); + sdp->sd_vfs = sb; + gfs_tune_init(&sdp->sd_tune); + + /* Init rgrp variables */ + + INIT_LIST_HEAD(&sdp->sd_rglist); + init_MUTEX(&sdp->sd_rindex_lock); + INIT_LIST_HEAD(&sdp->sd_rg_mru_list); + spin_lock_init(&sdp->sd_rg_mru_lock); + INIT_LIST_HEAD(&sdp->sd_rg_recent); + spin_lock_init(&sdp->sd_rg_recent_lock); + spin_lock_init(&sdp->sd_rg_forward_lock); + + spin_lock_init(&sdp->sd_statfs_spin); + + for (x = 0; x < GFS_GL_HASH_SIZE; x++) { + sdp->sd_gl_hash[x].hb_lock = RW_LOCK_UNLOCKED; + INIT_LIST_HEAD(&sdp->sd_gl_hash[x].hb_list); + } + + INIT_LIST_HEAD(&sdp->sd_reclaim_list); + spin_lock_init(&sdp->sd_reclaim_lock); + init_waitqueue_head(&sdp->sd_reclaim_wchan); + + for (x = 0; x < GFS_MHC_HASH_SIZE; x++) + INIT_LIST_HEAD(&sdp->sd_mhc[x]); + INIT_LIST_HEAD(&sdp->sd_mhc_single); + spin_lock_init(&sdp->sd_mhc_lock); + + for (x = 0; x < GFS_DEPEND_HASH_SIZE; x++) + INIT_LIST_HEAD(&sdp->sd_depend[x]); + spin_lock_init(&sdp->sd_depend_lock); + + init_MUTEX(&sdp->sd_freeze_lock); + + spin_lock_init(&sdp->sd_log_seg_lock); + INIT_LIST_HEAD(&sdp->sd_log_seg_list); + init_waitqueue_head(&sdp->sd_log_seg_wait); + INIT_LIST_HEAD(&sdp->sd_log_ail); + INIT_LIST_HEAD(&sdp->sd_log_incore); + init_rwsem(&sdp->sd_log_lock); + INIT_LIST_HEAD(&sdp->sd_unlinked_list); + spin_lock_init(&sdp->sd_unlinked_lock); + INIT_LIST_HEAD(&sdp->sd_quota_list); + spin_lock_init(&sdp->sd_quota_lock); + + INIT_LIST_HEAD(&sdp->sd_dirty_j); + spin_lock_init(&sdp->sd_dirty_j_lock); + + spin_lock_init(&sdp->sd_ail_lock); + INIT_LIST_HEAD(&sdp->sd_recovery_bufs); + + return sdp; +} + +static void init_vfs(struct super_block *sb, unsigned noatime) +{ + struct gfs_sbd *sdp = sb->s_fs_info; + + /* Set up Linux Virtual (VFS) Super Block */ + + sb->s_magic = GFS_MAGIC; + sb->s_op = &gfs_super_ops; + sb->s_export_op = &gfs_export_ops; + + /* Don't let the VFS update atimes. GFS handles this itself. */ + sb->s_flags |= MS_NOATIME | MS_NODIRATIME; + sb->s_maxbytes = MAX_LFS_FILESIZE; + + /* If we were mounted with -o acl (to support POSIX access control + lists), tell VFS */ + if (sdp->sd_args.ar_posix_acls) + sb->s_flags |= MS_POSIXACL; +} + +int init_names(struct gfs_sbd *sdp, int silent) +{ + struct gfs_sb *sb = NULL; + char *proto, *table; + int error = 0; + + proto = sdp->sd_args.ar_lockproto; + table = sdp->sd_args.ar_locktable; + + /* Try to autodetect */ + + if (!proto[0] || !table[0]) { + struct buffer_head *bh; + + bh = sb_getblk(sdp->sd_vfs, + GFS_SB_ADDR >> sdp->sd_fsb2bb_shift); + lock_buffer(bh); + clear_buffer_uptodate(bh); + clear_buffer_dirty(bh); + unlock_buffer(bh); + ll_rw_block(READ, 1, &bh); + wait_on_buffer(bh); + + if (!buffer_uptodate(bh)) { + brelse(bh); + return -EIO; + } + + sb = kmalloc(sizeof(struct gfs_sb), GFP_KERNEL); + if (!sb) { + brelse(bh); + return -ENOMEM; + } + gfs_sb_in(sb, bh->b_data); + brelse(bh); + + error = gfs_check_sb(sdp, sb, silent); + if (error) + goto out; + + if (!proto[0]) + proto = sb->sb_lockproto; + if (!table[0]) + table = sb->sb_locktable; + } + + if (!table[0]) + table = sdp->sd_vfs->s_id; + + snprintf(sdp->sd_proto_name, 256, "%s", proto); + snprintf(sdp->sd_table_name, 256, "%s", table); + + while ((table = strchr(sdp->sd_table_name, '/'))) + *table = '_'; + + out: + kfree(sb); + + return error; +} + +static int init_locking(struct gfs_sbd *sdp, struct gfs_holder *mount_gh, + int undo) +{ + struct task_struct *p; + int error = 0; + + if (undo) + goto fail_live; + + if ((sdp->sd_lockstruct.ls_flags & LM_LSFLAG_LOCAL) && + !sdp->sd_args.ar_ignore_local_fs) { + /* Force local [p|f]locks */ + sdp->sd_args.ar_localflocks = TRUE; + + /* Force local read ahead and caching */ + sdp->sd_args.ar_localcaching = TRUE; + + /* Allow the machine to oops */ + sdp->sd_args.ar_oopses_ok = TRUE; + } + + /* Start up the scand thread */ + + p = kthread_run(gfs_scand, sdp, "gfs_scand"); + error = IS_ERR(p); + if (error) { + printk("GFS: fsid=%s: can't start scand thread: %d\n", + sdp->sd_fsname, error); + return error; + } + sdp->sd_scand_process = p; + + /* Start up the glockd thread */ + + for (sdp->sd_glockd_num = 0; + sdp->sd_glockd_num < sdp->sd_args.ar_num_glockd; + sdp->sd_glockd_num++) { + p = kthread_run(gfs_glockd, sdp, "gfs_glockd"); + error = IS_ERR(p); + if (error) { + printk("GFS: fsid=%s: can't start glockd thread: %d\n", + sdp->sd_fsname, error); + goto fail; + } + sdp->sd_glockd_process[sdp->sd_glockd_num] = p; + } + + /* Only one node may mount at a time */ + error = gfs_glock_nq_num(sdp, + GFS_MOUNT_LOCK, &gfs_nondisk_glops, + LM_ST_EXCLUSIVE, LM_FLAG_NOEXP | GL_NOCACHE, + mount_gh); + if (error) { + printk("GFS: fsid=%s: can't acquire mount glock: %d\n", + sdp->sd_fsname, error); + goto fail; + } + + /* Show that cluster is alive */ + error = gfs_glock_nq_num(sdp, + GFS_LIVE_LOCK, &gfs_nondisk_glops, + LM_ST_SHARED, LM_FLAG_NOEXP | GL_EXACT, + &sdp->sd_live_gh); + if (error) { + printk("GFS: fsid=%s: can't acquire live glock: %d\n", + sdp->sd_fsname, error); + goto fail_mount; + } + + sdp->sd_live_gh.gh_owner = NULL; + return 0; + +fail_live: + gfs_glock_dq_uninit(&sdp->sd_live_gh); + +fail_mount: + gfs_glock_dq_uninit(mount_gh); + +fail: + while (sdp->sd_glockd_num--) + kthread_stop(sdp->sd_glockd_process[sdp->sd_glockd_num]); + + kthread_stop(sdp->sd_scand_process); + + return error; +} + +static int init_sb(struct gfs_sbd *sdp, int silent, int undo) +{ + struct super_block *sb = sdp->sd_vfs; + struct gfs_holder sb_gh; + int error = 0; + struct inode *inode; + + if (undo) + goto fail_dput; + + /* Read the SuperBlock from disk, get enough info to enable us + to read-in the journal index and replay all journals. */ + + error = gfs_glock_nq_num(sdp, + GFS_SB_LOCK, &gfs_meta_glops, + (sdp->sd_args.ar_upgrade) ? LM_ST_EXCLUSIVE : LM_ST_SHARED, + 0, &sb_gh); + if (error) { + printk("GFS: fsid=%s: can't acquire superblock glock: %d\n", + sdp->sd_fsname, error); + return error; + } + + error = gfs_read_sb(sdp, sb_gh.gh_gl, silent); + if (error) { + printk("GFS: fsid=%s: can't read superblock: %d\n", + sdp->sd_fsname, error); + goto out; + } + + /* Set up the buffer cache and SB for real, now that we know block + sizes, version #s, locations of important on-disk inodes, etc. */ + + error = -EINVAL; + if (sdp->sd_sb.sb_bsize < bdev_hardsect_size(sb->s_bdev)) { + printk("GFS: fsid=%s: FS block size (%u) is too small for device block size (%u)\n", + sdp->sd_fsname, sdp->sd_sb.sb_bsize, bdev_hardsect_size(sb->s_bdev)); + goto fail; + } + if (sdp->sd_sb.sb_bsize > PAGE_SIZE) { + printk("GFS: fsid=%s: FS block size (%u) is too big for machine page size (%u)\n", + sdp->sd_fsname, sdp->sd_sb.sb_bsize, + (unsigned int)PAGE_SIZE); + goto fail; + } + + /* Get rid of buffers from the original block size */ + sb_gh.gh_gl->gl_ops->go_inval(sb_gh.gh_gl, DIO_METADATA | DIO_DATA); + sb_gh.gh_gl->gl_aspace->i_blkbits = sdp->sd_sb.sb_bsize_shift; + + sb_set_blocksize(sb, sdp->sd_sb.sb_bsize); + + /* Read in the resource index inode */ + + error = gfs_get_riinode(sdp); + if (error) { + printk("GFS: fsid=%s: can't get resource index inode: %d\n", + sdp->sd_fsname, error); + goto fail; + } + + /* Get the root inode */ + error = gfs_get_rootinode(sdp); + if (error) { + printk("GFS: fsid=%s: can't read in root inode: %d\n", + sdp->sd_fsname, error); + goto fail_ri_free; + } + /* Get the root inode/dentry */ + + inode = gfs_iget(sdp->sd_rooti, CREATE); + if (!inode) { + printk("GFS: fsid=%s: can't get root inode\n", sdp->sd_fsname); + error = -ENOMEM; + goto fail_ri_free; + } + sb->s_root = d_alloc_root(inode); + if (!sb->s_root) { + iput(inode); + printk("GFS: fsid=%s: can't get root dentry\n", sdp->sd_fsname); + error = -ENOMEM; + goto fail_root_free; + } + sb->s_root->d_op = &gfs_dops; + + /* Read in the quota inode */ + error = gfs_get_qinode(sdp); + if (error) { + printk("GFS: fsid=%s: can't get quota file inode: %d\n", + sdp->sd_fsname, error); + goto fail_root_free; + } + + /* Implement fast statfs on the unused license inode location. + * sb->sb_quota_di.no_formal_ino = jindex_dinode + 2; + * sb->sb_quota_di.no_addr = jindex_dinode + 2; + * sb->sb_license_di.no_formal_ino = jindex_dinode + 3; + * sb->sb_license_di.no_addr = jindex_dinode + 3; + */ + error = gfs_get_linode(sdp); + if (error) { + printk("GFS: fsid=%s: can't get statfs file inode: %d\n", + sdp->sd_fsname, error); + goto fail_qi_free; + } + + /* We're through with the superblock lock */ +out: + gfs_glock_dq_uninit(&sb_gh); + return error; + +fail_dput: + gfs_inode_put(sdp->sd_linode); + if (sb->s_root) { + dput(sb->s_root); + sb->s_root = NULL; + } +fail_qi_free: + gfs_inode_put(sdp->sd_qinode); +fail_root_free: + gfs_inode_put(sdp->sd_rooti); +fail_ri_free: + gfs_inode_put(sdp->sd_riinode); + gfs_clear_rgrpd(sdp); +fail: + if (!undo) + gfs_glock_dq_uninit(&sb_gh); + return error; +} + +static int init_journal(struct gfs_sbd *sdp, int undo) +{ + struct gfs_holder ji_gh; + int error = 0; + unsigned int x; + int jindex = TRUE; + struct task_struct *p; + + if (undo) { + jindex = 0; + goto fail_recoverd; + } + + init_MUTEX(&sdp->sd_jindex_lock); + + /* Get a handle on the transaction glock; we need this for disk format + upgrade and journal replays, as well as normal operation. */ + + error = gfs_glock_get(sdp, GFS_TRANS_LOCK, &gfs_trans_glops, + CREATE, &sdp->sd_trans_gl); + if (error) + return error; + set_bit(GLF_STICKY, &sdp->sd_trans_gl->gl_flags); + + /* Load in the journal index special file */ + + error = gfs_jindex_hold(sdp, &ji_gh); + if (error) { + printk("GFS: fsid=%s: can't read journal index: %d\n", + sdp->sd_fsname, error); + goto fail_jhold; + } + + if (sdp->sd_args.ar_spectator) { + sdp->sd_jdesc = sdp->sd_jindex[0]; + sdp->sd_log_seg_free = sdp->sd_jdesc.ji_nsegment; + sdp->sd_log_seg_ail2 = 0; + } + else { + /* Discover this node's journal number (lock module tells us + which one to use), and lock it */ + error = -EINVAL; + if (sdp->sd_lockstruct.ls_jid >= sdp->sd_journals) { + printk("GFS: fsid=%s: can't mount journal #%u\n", + sdp->sd_fsname, sdp->sd_lockstruct.ls_jid); + printk("GFS: fsid=%s: there are only %u journals (0 - %u)\n", + sdp->sd_fsname, sdp->sd_journals, sdp->sd_journals - 1); + goto fail_jindex; + } + sdp->sd_jdesc = sdp->sd_jindex[sdp->sd_lockstruct.ls_jid]; + sdp->sd_log_seg_free = sdp->sd_jdesc.ji_nsegment; + sdp->sd_log_seg_ail2 = 0; + + error = gfs_glock_nq_num(sdp, + sdp->sd_jdesc.ji_addr, &gfs_meta_glops, + LM_ST_EXCLUSIVE, LM_FLAG_NOEXP, + &sdp->sd_journal_gh); + if (error) { + printk("GFS: fsid=%s: can't acquire the journal glock: %d\n", + sdp->sd_fsname, error); + goto fail_jindex; + } + } + + if (sdp->sd_lockstruct.ls_first) { + /* We're first node within cluster to mount this filesystem, + replay ALL of the journals, then let lock module know + that we're done. */ + for (x = 0; x < sdp->sd_journals; x++) { + error = gfs_recover_journal(sdp, + x, sdp->sd_jindex + x, + FALSE); + if (error) { + printk("GFS: fsid=%s: error recovering journal %u: %d\n", + sdp->sd_fsname, x, error); + goto fail_journal_gh; + } + } + + gfs_lm_others_may_mount(sdp); + } else if (!sdp->sd_args.ar_spectator) { + /* We're not the first; replay only our own journal. */ + error = gfs_recover_journal(sdp, sdp->sd_lockstruct.ls_jid, + &sdp->sd_jdesc, TRUE); + if (error) { + printk("GFS: fsid=%s: error recovering my journal: %d\n", + sdp->sd_fsname, error); + goto fail_journal_gh; + } + } + + gfs_glock_dq_uninit(&ji_gh); + jindex = FALSE; + + /* Disown my Journal glock */ + sdp->sd_journal_gh.gh_owner = NULL; + + /* Make the FS read/write */ + + if (!test_bit(SDF_ROFS, &sdp->sd_flags)) { + error = gfs_make_fs_rw(sdp); + if (error) { + printk("GFS: fsid=%s: can't make file system RW: %d\n", + sdp->sd_fsname, error); + goto fail_journal_gh; + } + } + + /* Start up the journal recovery thread */ + + p = kthread_run(gfs_recoverd, sdp, "gfs_recoverd"); + error = IS_ERR(p); + if (error) { + printk("GFS: fsid=%s: can't start recoverd thread: %d\n", + sdp->sd_fsname, error); + goto fail_journal_gh; + } + sdp->sd_recoverd_process = p; + + return 0; + +fail_recoverd: + kthread_stop(sdp->sd_recoverd_process); + sdp->sd_recoverd_process = NULL; + +fail_journal_gh: + if (!sdp->sd_args.ar_spectator) + gfs_glock_dq_uninit(&sdp->sd_journal_gh); + +fail_jindex: + if (jindex) + gfs_glock_dq_uninit(&ji_gh); + +fail_jhold: + gfs_glock_put(sdp->sd_trans_gl); + return error; +} + +static int init_threads(struct gfs_sbd *sdp, int undo) +{ + struct task_struct *p; + int error = 0; + + if (undo) + goto fail_logd; + + sdp->sd_jindex_refresh_time = jiffies; + + /* Start up the logd thread */ + p = kthread_run(gfs_logd, sdp, "gfs_logd"); + error = IS_ERR(p); + if (error) { + printk("GFS: fsid=%s: can't start logd thread: %d\n", + sdp->sd_fsname, error); + goto fail; + } + sdp->sd_logd_process = p; + + /* Start up the quotad thread */ + + p = kthread_run(gfs_quotad, sdp, "gfs_quotad"); + if (error < 0) { + printk("GFS: fsid=%s: can't start quotad thread: %d\n", + sdp->sd_fsname, error); + goto fail_quotad; + } + sdp->sd_quotad_process = p; + + /* Start up the inoded thread */ + + p = kthread_run(gfs_inoded, sdp, "gfs_inoded"); + if (error < 0) { + printk("GFS: fsid=%s: can't start inoded thread: %d\n", + sdp->sd_fsname, error); + goto fail_inoded; + } + sdp->sd_inoded_process = p; + return 0; + +fail_logd: + kthread_stop(sdp->sd_inoded_process); +fail_inoded: + kthread_stop(sdp->sd_quotad_process); +fail_quotad: + kthread_stop(sdp->sd_logd_process); +fail: + return error; +} + +/** + * fill_super - Read in superblock + * @sb: The VFS superblock + * @data: Mount options + * @silent: Don't complain if it's not a GFS filesystem + * + * Returns: errno + * + * After cross-linking Linux VFS incore superblock and our GFS incore + * superblock (filesystem instance structures) to one another, we: + * -- Init some of our GFS incore superblock, including some temporary + * block-size values (enough to read on-disk superblock). + * -- Set up some things in Linux VFS superblock. + * -- Mount a lock module, init glock system (incl. glock reclaim daemons), + * and init some important inter-node locks (MOUNT, LIVE, SuperBlock). + * -- Read-in the GFS on-disk superblock (1st time, to get enough info + * to do filesystem upgrade and journal replay, incl. journal index). + * -- Upgrade on-disk filesystem format (rarely needed). + * -- Replay journals (always; replay *all* journals if we're first-to-mount). + * -- Read-in on-disk superblock and journal index special file again + * (2nd time, assumed 100% valid now after journal replay). + * -- Read-in info on other special (hidden) files (root inode, resource index, + * quota inode, license inode). + * -- Start other daemons (journal/log recovery, log tail, quota updates, inode + * reclaim) for periodic maintenance. + * + */ + +static int fill_super(struct super_block *sb, void *data, int silent) +{ + struct gfs_sbd *sdp; + struct gfs_holder mount_gh; + int error; + + sdp = init_sbd(sb); + if (!sdp) { + printk(KERN_WARNING "GFS: can't alloc struct gfs_sbd\n"); + return -ENOMEM; + } + + error = gfs_make_args((char *)data, &sdp->sd_args, FALSE); + if (error) { + printk("GFS: can't parse mount arguments\n"); + goto fail; + } + + if (sdp->sd_args.ar_spectator) { + sb->s_flags |= MS_RDONLY; + set_bit(SDF_ROFS, &sdp->sd_flags); + } + + /* Copy VFS mount flags */ + + if (sb->s_flags & (MS_NOATIME | MS_NODIRATIME)) + set_bit(SDF_NOATIME, &sdp->sd_flags); + if (sb->s_flags & MS_RDONLY) + set_bit(SDF_ROFS, &sdp->sd_flags); + + init_vfs(sb, SDF_NOATIME); + + /* Turn off quota stuff if we get the noquota mount option, don't + need to grab the sd_tune lock here since its before anything + touches the sd_tune values */ + if (sdp->sd_args.ar_noquota) { + sdp->sd_tune.gt_quota_enforce = 0; + sdp->sd_tune.gt_quota_account = 0; + } + + /* Set up the buffer cache and fill in some fake block size values + to allow us to read-in the on-disk superblock. */ + + sdp->sd_sb.sb_bsize = sb_min_blocksize(sb, GFS_BASIC_BLOCK); + sdp->sd_sb.sb_bsize_shift = sb->s_blocksize_bits; + sdp->sd_fsb2bb_shift = sdp->sd_sb.sb_bsize_shift - GFS_BASIC_BLOCK_SHIFT; + sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift; + + if (sizeof(struct gfs_sb) > sdp->sd_sb.sb_bsize) { + printk("GFS: sizeof(struct gfs_sb) > sdp->sd_sb.sb_bsize\n" + "GFS: %u > %u\n", + (unsigned int)sizeof(struct gfs_sb), sdp->sd_sb.sb_bsize); + error = -EINVAL; + goto fail; + } + error = init_names(sdp, silent); + if (error) + goto fail; + + error = gfs_sys_fs_add(sdp); + if (error) + goto fail; + + /* Mount an inter-node lock module, check for local optimizations */ + + error = gfs_lm_mount(sdp, silent); + if (error) + goto fail_sys; + + error = init_locking(sdp, &mount_gh, DO); + if (error) + goto fail_lm; + + error = init_sb(sdp, silent, DO); + if (error) + goto fail_locking; + + /* Read-in journal index inode (but not the file contents, yet) */ + + error = gfs_get_jiinode(sdp); + if (error) { + printk("GFS: fsid=%s: can't get journal index inode: %d\n", + sdp->sd_fsname, error); + goto fail_jiinode; + } + + error = init_journal(sdp, DO); + if (error) + goto fail_sb; + /* Get a handle on the rename lock */ + + error = gfs_glock_get(sdp, GFS_RENAME_LOCK, &gfs_nondisk_glops, + CREATE, &sdp->sd_rename_gl); + if (error) + goto fail_journal; + + error = init_threads(sdp, DO); + if (error) + goto fail_journal; + + gfs_proc_fs_add(sdp); + gfs_glock_dq_uninit(&mount_gh); + + return 0; + +fail_journal: + init_journal(sdp, UNDO); + +fail_sb: + gfs_inode_put(sdp->sd_jiinode); + +fail_jiinode: + init_sb(sdp, 0, UNDO); + +fail_locking: + init_locking(sdp, &mount_gh, UNDO); + +fail_lm: + gfs_gl_hash_clear(sdp, TRUE); + gfs_lm_unmount(sdp); + gfs_clear_dirty_j(sdp); + while (invalidate_inodes(sb)) + yield(); + +fail_sys: + gfs_sys_fs_del(sdp); + +fail: + vfree(sdp); + sb->s_fs_info = NULL; + + return error; +} + +/** + * gfs_test_bdev_super - + * @sb: + * @data: + * + */ + +int +gfs_test_bdev_super(struct super_block *sb, void *data) +{ + return (void *)sb->s_bdev == data; +} + +/** + * gfs_test_bdev_super - + * @sb: + * @data: + * + */ + +int +gfs_set_bdev_super(struct super_block *sb, void *data) +{ + sb->s_bdev = data; + sb->s_dev = sb->s_bdev->bd_dev; + return 0; +} + +/** + * gfs_get_sb - + * @fs_type: + * @flags: + * @dev_name: + * @data: + * + * Rip off of get_sb_bdev(). + * + * Returns: the new superblock + */ + +static int gfs_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *data, struct vfsmount *mnt) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, fill_super, mnt); +} + +/** + * gfs_kill_sb - + * @sb: + * + * Rip off of kill_block_super(). + * + */ + +void +gfs_kill_sb(struct super_block *sb) +{ + kill_block_super(sb); +} + +struct file_system_type gfs_fs_type = { + .name = "gfs", + .fs_flags = FS_REQUIRES_DEV, + .get_sb = gfs_get_sb, + .kill_sb = gfs_kill_sb, + .owner = THIS_MODULE, +}; --- linux-2.6.28.orig/ubuntu/gfs/ops_vm.c +++ linux-2.6.28/ubuntu/gfs/ops_vm.c @@ -0,0 +1,233 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "bmap.h" +#include "glock.h" +#include "inode.h" +#include "ops_vm.h" +#include "page.h" +#include "quota.h" +#include "rgrp.h" +#include "trans.h" + +/** + * pfault_be_greedy - + * @ip: + * + */ + +static void +pfault_be_greedy(struct gfs_inode *ip) +{ + unsigned int time; + + spin_lock(&ip->i_spin); + time = ip->i_greedy; + ip->i_last_pfault = jiffies; + spin_unlock(&ip->i_spin); + + gfs_inode_hold(ip); + if (gfs_glock_be_greedy(ip->i_gl, time)) + gfs_inode_put(ip); +} + +/** + * gfs_private_fault - + * @area: + * @address: + * @type: + * + * Returns: the page + */ + +static int gfs_private_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + struct gfs_inode *ip = get_v2ip(vma->vm_file->f_mapping->host); + struct gfs_holder i_gh; + int error; + int ret = 0; + + atomic_inc(&ip->i_sbd->sd_ops_vm); + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh); + if (error) + goto out; + + set_bit(GIF_PAGED, &ip->i_flags); + + ret = filemap_fault(vma, vmf); + + if (ret && ret != VM_FAULT_OOM) + pfault_be_greedy(ip); + + gfs_glock_dq_uninit(&i_gh); + out: + return ret; +} + +/** + * alloc_page_backing - + * @ip: + * @index: + * + * Returns: errno + */ + +static int +alloc_page_backing(struct gfs_inode *ip, struct page *page) +{ + struct gfs_sbd *sdp = ip->i_sbd; + unsigned long index = page->index; + uint64_t lblock = index << (PAGE_CACHE_SHIFT - sdp->sd_sb.sb_bsize_shift); + unsigned int blocks = PAGE_CACHE_SIZE >> sdp->sd_sb.sb_bsize_shift; + struct gfs_alloc *al; + unsigned int x; + int error; + + al = gfs_alloc_get(ip); + + error = gfs_quota_lock_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + if (error) + goto out; + + error = gfs_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); + if (error) + goto out_gunlock_q; + + gfs_write_calc_reserv(ip, PAGE_CACHE_SIZE, + &al->al_requested_data, &al->al_requested_meta); + + error = gfs_inplace_reserve(ip); + if (error) + goto out_gunlock_q; + + /* Trans may require: + a dinode block, RG bitmaps to allocate from, + indirect blocks, and a quota block */ + + error = gfs_trans_begin(sdp, + 1 + al->al_rgd->rd_ri.ri_length + + al->al_requested_meta, 1); + if (error) + goto out_ipres; + + if (gfs_is_stuffed(ip)) { + error = gfs_unstuff_dinode(ip, gfs_unstuffer_page, NULL); + if (error) + goto out_trans; + } + + for (x = 0; x < blocks; ) { + uint64_t dblock; + unsigned int extlen; + int new = TRUE; + + error = gfs_block_map(ip, lblock, &new, &dblock, &extlen); + if (error) + goto out_trans; + + lblock += extlen; + x += extlen; + } + + gfs_assert_warn(sdp, al->al_alloced_meta || al->al_alloced_data); + + out_trans: + gfs_trans_end(sdp); + + out_ipres: + gfs_inplace_release(ip); + + out_gunlock_q: + gfs_quota_unlock_m(ip); + + out: + gfs_alloc_put(ip); + + return error; +} + +/** + * gfs_sharewrite_fault - + * @area: + * @address: + * @type: + * + * Returns: the page + */ + +static int gfs_sharewrite_fault(struct vm_area_struct *vma, + struct vm_fault *vmf) +{ + struct file *file = vma->vm_file; + struct gfs_inode *ip = get_v2ip(file->f_mapping->host); + struct gfs_holder i_gh; + int alloc_required; + int error; + int ret = 0; + + atomic_inc(&ip->i_sbd->sd_ops_vm); + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); + if (error) + goto out; + + if (gfs_is_jdata(ip)) + goto out_unlock; + + set_bit(GIF_PAGED, &ip->i_flags); + set_bit(GIF_SW_PAGED, &ip->i_flags); + + error = gfs_write_alloc_required(ip, + (u64)vmf->pgoff << PAGE_CACHE_SHIFT, + PAGE_CACHE_SIZE, &alloc_required); + if (error) { + ret = VM_FAULT_OOM; /* XXX: are these right? */ + goto out_unlock; + } + + ret = filemap_fault(vma, vmf); + if (ret & VM_FAULT_ERROR) + goto out_unlock; + + if (alloc_required) { + /* XXX: do we need to drop page lock around alloc_page_backing?*/ + error = alloc_page_backing(ip, vmf->page); + if (error) { + /* + * VM_FAULT_LOCKED should always be the case for + * filemap_fault, but it may not be in a future + * implementation. + */ + if (ret & VM_FAULT_LOCKED) + unlock_page(vmf->page); + page_cache_release(vmf->page); + ret = VM_FAULT_OOM; + goto out_unlock; + } + set_page_dirty(vmf->page); + } + + pfault_be_greedy(ip); + + out_unlock: + gfs_glock_dq_uninit(&i_gh); + out: + return ret; +} + +struct vm_operations_struct gfs_vm_ops_private = { + .fault = gfs_private_fault, +}; + +struct vm_operations_struct gfs_vm_ops_sharewrite = { + .fault = gfs_sharewrite_fault, +}; + --- linux-2.6.28.orig/ubuntu/gfs/lock_dlm_thread.c +++ linux-2.6.28/ubuntu/gfs/lock_dlm_thread.c @@ -0,0 +1,367 @@ +/* + * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. + * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License version 2. + */ + +#include "lock_dlm.h" + +/* A lock placed on this queue is re-submitted to DLM as soon as the lock_dlm + thread gets to it. */ + +static void queue_submit(struct gdlm_lock *lp) +{ + struct gdlm_ls *ls = lp->ls; + + spin_lock(&ls->async_lock); + list_add_tail(&lp->delay_list, &ls->submit); + spin_unlock(&ls->async_lock); + wake_up(&ls->thread_wait); +} + +static void process_blocking(struct gdlm_lock *lp, int bast_mode) +{ + struct gdlm_ls *ls = lp->ls; + unsigned int cb = 0; + + switch (gdlm_make_lmstate(bast_mode)) { + case LM_ST_EXCLUSIVE: + cb = LM_CB_NEED_E; + break; + case LM_ST_DEFERRED: + cb = LM_CB_NEED_D; + break; + case LM_ST_SHARED: + cb = LM_CB_NEED_S; + break; + default: + gdlm_assert(0, "unknown bast mode %u", lp->bast_mode); + } + + ls->fscb(ls->sdp, cb, &lp->lockname); +} + +static void wake_up_ast(struct gdlm_lock *lp) +{ + clear_bit(LFL_AST_WAIT, &lp->flags); + smp_mb__after_clear_bit(); + wake_up_bit(&lp->flags, LFL_AST_WAIT); +} + +static void process_complete(struct gdlm_lock *lp) +{ + struct gdlm_ls *ls = lp->ls; + struct lm_async_cb acb; + s16 prev_mode = lp->cur; + + memset(&acb, 0, sizeof(acb)); + + if (lp->lksb.sb_status == -DLM_ECANCEL) { + log_info("complete dlm cancel %x,%llx flags %lx", + lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number, + lp->flags); + + lp->req = lp->cur; + acb.lc_ret |= LM_OUT_CANCELED; + if (lp->cur == DLM_LOCK_IV) + lp->lksb.sb_lkid = 0; + goto out; + } + + if (test_and_clear_bit(LFL_DLM_UNLOCK, &lp->flags)) { + if (lp->lksb.sb_status != -DLM_EUNLOCK) { + log_info("unlock sb_status %d %x,%llx flags %lx", + lp->lksb.sb_status, lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number, + lp->flags); + return; + } + + lp->cur = DLM_LOCK_IV; + lp->req = DLM_LOCK_IV; + lp->lksb.sb_lkid = 0; + + if (test_and_clear_bit(LFL_UNLOCK_DELETE, &lp->flags)) { + gdlm_delete_lp(lp); + return; + } + goto out; + } + + if (lp->lksb.sb_flags & DLM_SBF_VALNOTVALID) + memset(lp->lksb.sb_lvbptr, 0, GDLM_LVB_SIZE); + + if (lp->lksb.sb_flags & DLM_SBF_ALTMODE) { + if (lp->req == DLM_LOCK_PR) + lp->req = DLM_LOCK_CW; + else if (lp->req == DLM_LOCK_CW) + lp->req = DLM_LOCK_PR; + } + + /* + * A canceled lock request. The lock was just taken off the delayed + * list and was never even submitted to dlm. + */ + + if (test_and_clear_bit(LFL_CANCEL, &lp->flags)) { + log_info("complete internal cancel %x,%llx", + lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number); + lp->req = lp->cur; + acb.lc_ret |= LM_OUT_CANCELED; + goto out; + } + + /* + * An error occured. + */ + + if (lp->lksb.sb_status) { + /* a "normal" error */ + if ((lp->lksb.sb_status == -EAGAIN) && + (lp->lkf & DLM_LKF_NOQUEUE)) { + lp->req = lp->cur; + if (lp->cur == DLM_LOCK_IV) + lp->lksb.sb_lkid = 0; + goto out; + } + + /* this could only happen with cancels I think */ + log_info("ast sb_status %d %x,%llx flags %lx", + lp->lksb.sb_status, lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number, + lp->flags); + return; + } + + /* + * This is an AST for an EX->EX conversion for sync_lvb from GFS. + */ + + if (test_and_clear_bit(LFL_SYNC_LVB, &lp->flags)) { + wake_up_ast(lp); + return; + } + + /* + * A lock has been demoted to NL because it initially completed during + * BLOCK_LOCKS. Now it must be requested in the originally requested + * mode. + */ + + if (test_and_clear_bit(LFL_REREQUEST, &lp->flags)) { + gdlm_assert(lp->req == DLM_LOCK_NL, "%x,%llx", + lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number); + gdlm_assert(lp->prev_req > DLM_LOCK_NL, "%x,%llx", + lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number); + + lp->cur = DLM_LOCK_NL; + lp->req = lp->prev_req; + lp->prev_req = DLM_LOCK_IV; + lp->lkf &= ~DLM_LKF_CONVDEADLK; + + set_bit(LFL_NOCACHE, &lp->flags); + + if (test_bit(DFL_BLOCK_LOCKS, &ls->flags) && + !test_bit(LFL_NOBLOCK, &lp->flags)) + gdlm_queue_delayed(lp); + else + queue_submit(lp); + return; + } + + /* + * A request is granted during dlm recovery. It may be granted + * because the locks of a failed node were cleared. In that case, + * there may be inconsistent data beneath this lock and we must wait + * for recovery to complete to use it. When gfs recovery is done this + * granted lock will be converted to NL and then reacquired in this + * granted state. + */ + + if (test_bit(DFL_BLOCK_LOCKS, &ls->flags) && + !test_bit(LFL_NOBLOCK, &lp->flags) && + lp->req != DLM_LOCK_NL) { + + lp->cur = lp->req; + lp->prev_req = lp->req; + lp->req = DLM_LOCK_NL; + lp->lkf |= DLM_LKF_CONVERT; + lp->lkf &= ~DLM_LKF_CONVDEADLK; + + log_debug("rereq %x,%llx id %x %d,%d", + lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number, + lp->lksb.sb_lkid, lp->cur, lp->req); + + set_bit(LFL_REREQUEST, &lp->flags); + queue_submit(lp); + return; + } + + /* + * DLM demoted the lock to NL before it was granted so GFS must be + * told it cannot cache data for this lock. + */ + + if (lp->lksb.sb_flags & DLM_SBF_DEMOTED) + set_bit(LFL_NOCACHE, &lp->flags); + +out: + /* + * This is an internal lock_dlm lock + */ + + if (test_bit(LFL_INLOCK, &lp->flags)) { + clear_bit(LFL_NOBLOCK, &lp->flags); + lp->cur = lp->req; + wake_up_ast(lp); + return; + } + + /* + * Normal completion of a lock request. Tell GFS it now has the lock. + */ + + clear_bit(LFL_NOBLOCK, &lp->flags); + lp->cur = lp->req; + + acb.lc_name = lp->lockname; + acb.lc_ret |= gdlm_make_lmstate(lp->cur); + + if (!test_and_clear_bit(LFL_NOCACHE, &lp->flags) && + (lp->cur > DLM_LOCK_NL) && (prev_mode > DLM_LOCK_NL)) + acb.lc_ret |= LM_OUT_CACHEABLE; + + ls->fscb(ls->sdp, LM_CB_ASYNC, &acb); +} + +static inline int no_work(struct gdlm_ls *ls, int blocking) +{ + int ret; + + spin_lock(&ls->async_lock); + ret = list_empty(&ls->complete) && list_empty(&ls->submit); + if (ret && blocking) + ret = list_empty(&ls->blocking); + spin_unlock(&ls->async_lock); + + return ret; +} + +static inline int check_drop(struct gdlm_ls *ls) +{ + if (!ls->drop_locks_count) + return 0; + + if (time_after(jiffies, ls->drop_time + ls->drop_locks_period * HZ)) { + ls->drop_time = jiffies; + if (ls->all_locks_count >= ls->drop_locks_count) + return 1; + } + return 0; +} + +static int gdlm_thread(void *data, int blist) +{ + struct gdlm_ls *ls = (struct gdlm_ls *) data; + struct gdlm_lock *lp = NULL; + uint8_t complete, blocking, submit, drop; + + /* Only thread1 is allowed to do blocking callbacks since gfs + may wait for a completion callback within a blocking cb. */ + + while (!kthread_should_stop()) { + wait_event_interruptible(ls->thread_wait, + !no_work(ls, blist) || kthread_should_stop()); + + complete = blocking = submit = drop = 0; + + spin_lock(&ls->async_lock); + + if (blist && !list_empty(&ls->blocking)) { + lp = list_entry(ls->blocking.next, struct gdlm_lock, + blist); + list_del_init(&lp->blist); + blocking = lp->bast_mode; + lp->bast_mode = 0; + } else if (!list_empty(&ls->complete)) { + lp = list_entry(ls->complete.next, struct gdlm_lock, + clist); + list_del_init(&lp->clist); + complete = 1; + } else if (!list_empty(&ls->submit)) { + lp = list_entry(ls->submit.next, struct gdlm_lock, + delay_list); + list_del_init(&lp->delay_list); + submit = 1; + } + + drop = check_drop(ls); + spin_unlock(&ls->async_lock); + + if (complete) + process_complete(lp); + + else if (blocking) + process_blocking(lp, blocking); + + else if (submit) + gdlm_do_lock(lp); + + if (drop) + ls->fscb(ls->sdp, LM_CB_DROPLOCKS, NULL); + + schedule(); + } + + return 0; +} + +static int gdlm_thread1(void *data) +{ + return gdlm_thread(data, 1); +} + +static int gdlm_thread2(void *data) +{ + return gdlm_thread(data, 0); +} + +int gdlm_init_threads(struct gdlm_ls *ls) +{ + struct task_struct *p; + int error; + + p = kthread_run(gdlm_thread1, ls, "lock_dlm1"); + error = IS_ERR(p); + if (error) { + log_error("can't start lock_dlm1 thread %d", error); + return error; + } + ls->thread1 = p; + + p = kthread_run(gdlm_thread2, ls, "lock_dlm2"); + error = IS_ERR(p); + if (error) { + log_error("can't start lock_dlm2 thread %d", error); + kthread_stop(ls->thread1); + return error; + } + ls->thread2 = p; + + return 0; +} + +void gdlm_release_threads(struct gdlm_ls *ls) +{ + kthread_stop(ls->thread1); + kthread_stop(ls->thread2); +} + --- linux-2.6.28.orig/ubuntu/gfs/mount.c +++ linux-2.6.28/ubuntu/gfs/mount.c @@ -0,0 +1,163 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "mount.h" +#include "proc.h" +#include "sys.h" + +/** + * gfs_make_args - Parse mount arguments + * @data: + * @args: + * + * Return: errno + */ + +int +gfs_make_args(char *data_arg, struct gfs_args *args, int remount) +{ + char *data = data_arg; + char *options, *x, *y; + int error = 0; + + /* If someone preloaded options, use those instead */ + + spin_lock(&gfs_proc_margs_lock); + if (!remount && gfs_proc_margs) { + data = gfs_proc_margs; + gfs_proc_margs = NULL; + } + spin_unlock(&gfs_proc_margs_lock); + + /* Set some defaults */ + + memset(args, 0, sizeof(struct gfs_args)); + args->ar_num_glockd = GFS_GLOCKD_DEFAULT; + + if (!remount) { + /* If someone preloaded options, use those instead */ + spin_lock(&gfs_sys_margs_lock); + if (gfs_sys_margs) { + data = gfs_sys_margs; + gfs_sys_margs = NULL; + } + spin_unlock(&gfs_sys_margs_lock); + + /* Set some defaults */ + args->ar_num_glockd = GFS_GLOCKD_DEFAULT; + } + + /* Split the options into tokens with the "," character and + process them */ + + for (options = data; (x = strsep(&options, ",")); ) { + if (!*x) + continue; + + y = strchr(x, '='); + if (y) + *y++ = 0; + + if (!strcmp(x, "lockproto")) { + if (!y) { + printk("GFS: need argument to lockproto\n"); + error = -EINVAL; + break; + } + strncpy(args->ar_lockproto, y, GFS_LOCKNAME_LEN); + args->ar_lockproto[GFS_LOCKNAME_LEN - 1] = 0; + } + + else if (!strcmp(x, "locktable")) { + if (!y) { + printk("GFS: need argument to locktable\n"); + error = -EINVAL; + break; + } + strncpy(args->ar_locktable, y, GFS_LOCKNAME_LEN); + args->ar_locktable[GFS_LOCKNAME_LEN - 1] = 0; + } + + else if (!strcmp(x, "hostdata")) { + if (!y) { + printk("GFS: need argument to hostdata\n"); + error = -EINVAL; + break; + } + strncpy(args->ar_hostdata, y, GFS_LOCKNAME_LEN); + args->ar_hostdata[GFS_LOCKNAME_LEN - 1] = 0; + } + + else if (!strcmp(x, "spectator")) + args->ar_spectator = TRUE; + + else if (!strcmp(x, "ignore_local_fs")) + args->ar_ignore_local_fs = TRUE; + + else if (!strcmp(x, "localflocks")) + args->ar_localflocks = TRUE; + + else if (!strcmp(x, "localcaching")) + args->ar_localcaching = TRUE; + + else if (!strcmp(x, "oopses_ok")) + args->ar_oopses_ok = TRUE; + + else if (!strcmp(x, "debug")) { + args->ar_oopses_ok = TRUE; + args->ar_debug = TRUE; + + } else if (!strcmp(x, "upgrade")) + args->ar_upgrade = TRUE; + + else if (!strcmp(x, "num_glockd")) { + if (!y) { + printk("GFS: need argument to num_glockd\n"); + error = -EINVAL; + break; + } + sscanf(y, "%u", &args->ar_num_glockd); + if (!args->ar_num_glockd || args->ar_num_glockd > GFS_GLOCKD_MAX) { + printk("GFS: 0 < num_glockd <= %u (not %u)\n", + GFS_GLOCKD_MAX, args->ar_num_glockd); + error = -EINVAL; + break; + } + } + + else if (!strcmp(x, "acl")) + args->ar_posix_acls = TRUE; + + else if (!strcmp(x, "noacl")) + args->ar_posix_acls = FALSE; + + else if (!strcmp(x, "suiddir")) + args->ar_suiddir = TRUE; + + else if (!strcmp(x, "noquota")) + args->ar_noquota = TRUE; + + /* Unknown */ + + else { + printk("GFS: unknown option: %s\n", x); + error = -EINVAL; + break; + } + } + + if (error) + printk("GFS: invalid mount option(s)\n"); + + if (data != data_arg) + kfree(data); + + return error; +} + --- linux-2.6.28.orig/ubuntu/gfs/file.c +++ linux-2.6.28/ubuntu/gfs/file.c @@ -0,0 +1,437 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "bmap.h" +#include "dio.h" +#include "file.h" +#include "inode.h" +#include "trans.h" + +/** + * gfs_copy2mem - Trivial copy function for gfs_readi() + * @bh: The buffer to copy from, or NULL meaning zero the buffer + * @buf: The buffer to copy/zero + * @offset: The offset in the buffer to copy from + * @size: The amount of data to copy/zero + * + * Returns: errno + */ + +int +gfs_copy2mem(struct buffer_head *bh, void **buf, unsigned int offset, + unsigned int size) +{ + char **p = (char **)buf; + + if (bh) + memcpy(*p, bh->b_data + offset, size); + else + memset(*p, 0, size); + + *p += size; + + return 0; +} + +/** + * gfs_copy2user - Copy data to user space + * @bh: The buffer + * @buf: The destination of the data + * @offset: The offset into the buffer + * @size: The amount of data to copy + * + * Returns: errno + */ + +int +gfs_copy2user(struct buffer_head *bh, void **buf, + unsigned int offset, unsigned int size) +{ + char **p = (char **)buf; + int error; + + if (bh) + error = copy_to_user(*p, bh->b_data + offset, size); + else + error = clear_user(*p, size); + + if (error) + error = -EFAULT; + else + *p += size; + + return error; +} + +/** + * gfs_readi - Read a file + * @ip: The GFS Inode + * @buf: The buffer to place result into + * @offset: File offset to begin reading from + * @size: Amount of data to transfer + * @copy_fn: Function to actually perform the copy + * + * The @copy_fn only copies a maximum of a single block at once so + * we are safe calling it with int arguments. It is done so that + * we don't needlessly put 64bit arguments on the stack and it + * also makes the code in the @copy_fn nicer too. + * + * Returns: The amount of data actually copied or the error + */ + +int +gfs_readi(struct gfs_inode *ip, void *buf, + uint64_t offset, unsigned int size, + read_copy_fn_t copy_fn) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head *bh; + uint64_t lblock, dblock; + unsigned int o; + uint32_t extlen = 0; + unsigned int amount; + int not_new = 0; + int journaled = gfs_is_jdata(ip); + int copied = 0; + int error = 0; + + if (offset >= ip->i_di.di_size) + return 0; + + if ((offset + size) > ip->i_di.di_size) + size = ip->i_di.di_size - offset; + + if (!size) + return 0; + + if (journaled) { + lblock = offset; + o = do_div(lblock, sdp->sd_jbsize); + } else { + lblock = offset >> sdp->sd_sb.sb_bsize_shift; + o = offset & (sdp->sd_sb.sb_bsize - 1); + } + + if (gfs_is_stuffed(ip)) + o += sizeof(struct gfs_dinode); + else if (journaled) + o += sizeof(struct gfs_meta_header); + + while (copied < size) { + amount = size - copied; + if (amount > sdp->sd_sb.sb_bsize - o) + amount = sdp->sd_sb.sb_bsize - o; + + if (!extlen) { + if (!gfs_is_stuffed(ip)) { + error = gfs_block_map(ip, lblock, ¬_new, + &dblock, &extlen); + if (error) + goto fail; + } else if (!lblock) { + dblock = ip->i_num.no_addr; + extlen = 1; + } else + dblock = 0; + } + + if (extlen > 1) + gfs_start_ra(ip->i_gl, dblock, extlen); + + if (dblock) { + error = gfs_get_data_buffer(ip, dblock, not_new, &bh); + if (error) + goto fail; + + dblock++; + extlen--; + } else + bh = NULL; + + error = copy_fn(bh, &buf, o, amount); + if (bh) + brelse(bh); + if (error) + goto fail; + + copied += amount; + lblock++; + + o = (journaled) ? sizeof(struct gfs_meta_header) : 0; + } + + return copied; + + fail: + return (copied) ? copied : error; +} + +/** + * gfs_copy_from_mem - Trivial copy function for gfs_writei() + * @ip: The file to write to + * @bh: The buffer to copy to or clear + * @buf: The buffer to copy from + * @offset: The offset in the buffer to write to + * @size: The amount of data to write + * @new: Flag indicating that remaining space in the buffer should be zeroed + * + * Returns: errno + */ + +int +gfs_copy_from_mem(struct gfs_inode *ip, struct buffer_head *bh, void **buf, + unsigned int offset, unsigned int size, int new) +{ + char **p = (char **)buf; + int error = 0; + + /* The dinode block always gets journaled */ + if (bh->b_blocknr == ip->i_num.no_addr) { + if (gfs_assert_warn(ip->i_sbd, !new)) + return -EIO; + gfs_trans_add_bh(ip->i_gl, bh); + memcpy(bh->b_data + offset, *p, size); + + /* Data blocks for journaled files get written added to the journal */ + } else if (gfs_is_jdata(ip)) { + gfs_trans_add_bh(ip->i_gl, bh); + memcpy(bh->b_data + offset, *p, size); + if (new) + gfs_buffer_clear_ends(bh, offset, size, TRUE); + + /* Non-journaled data blocks get written to in-place disk blocks */ + } else { + memcpy(bh->b_data + offset, *p, size); + if (new) + gfs_buffer_clear_ends(bh, offset, size, FALSE); + error = gfs_dwrite(ip->i_sbd, bh, DIO_DIRTY); + } + + if (!error) + *p += size; + + return error; +} + +/** + * gfs_copy_from_user - Copy bytes from user space for gfs_writei() + * @ip: The file to write to + * @bh: The buffer to copy to or clear + * @buf: The buffer to copy from + * @offset: The offset in the buffer to write to + * @size: The amount of data to write + * @new: Flag indicating that remaining space in the buffer should be zeroed + * + * Returns: errno + */ + +int +gfs_copy_from_user(struct gfs_inode *ip, struct buffer_head *bh, void **buf, + unsigned int offset, unsigned int size, int new) +{ + char **p = (char **)buf; + int error = 0; + + /* the dinode block always gets journaled */ + if (bh->b_blocknr == ip->i_num.no_addr) { + if (gfs_assert_warn(ip->i_sbd, !new)) + return -EIO; + gfs_trans_add_bh(ip->i_gl, bh); + if (copy_from_user(bh->b_data + offset, *p, size)) + error = -EFAULT; + + /* Data blocks for journaled files get written added to the journal */ + } else if (gfs_is_jdata(ip)) { + gfs_trans_add_bh(ip->i_gl, bh); + if (copy_from_user(bh->b_data + offset, *p, size)) + error = -EFAULT; + if (new) { + gfs_buffer_clear_ends(bh, offset, size, TRUE); + if (error) + memset(bh->b_data + offset, 0, size); + } + + /* non-journaled data blocks get written to in-place disk blocks */ + } else { + if (copy_from_user(bh->b_data + offset, *p, size)) + error = -EFAULT; + if (error) { + if (new) + gfs_buffer_clear(bh); + gfs_dwrite(ip->i_sbd, bh, DIO_DIRTY); + } else { + if (new) + gfs_buffer_clear_ends(bh, offset, size, FALSE); + error = gfs_dwrite(ip->i_sbd, bh, DIO_DIRTY); + } + } + + if (!error) + *p += size; + + return error; +} + +/** + * gfs_writei - Write bytes to a file + * @ip: The GFS inode + * @buf: The buffer containing information to be written + * @offset: The file offset to start writing at + * @size: The amount of data to write + * @copy_fn: Function to do the actual copying + * + * Returns: The number of bytes correctly written or error code + */ + +int +gfs_writei(struct gfs_inode *ip, void *buf, + uint64_t offset, unsigned int size, + write_copy_fn_t copy_fn, + struct kiocb *iocb) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head *dibh, *bh; + uint64_t lblock, dblock; + unsigned int o; + uint32_t extlen = 0; + unsigned int amount; + int new; + int journaled = gfs_is_jdata(ip); + const uint64_t start = offset; + int copied = 0; + int error = 0; + + if (!size) + return 0; + + if (gfs_is_stuffed(ip) && + ((start + size) > (sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode)))) { + error = gfs_unstuff_dinode(ip, gfs_unstuffer_async, NULL); + if (error) + return error; + } + + if (journaled) { + lblock = offset; + o = do_div(lblock, sdp->sd_jbsize); + } else { + lblock = offset >> sdp->sd_sb.sb_bsize_shift; + o = offset & (sdp->sd_sb.sb_bsize - 1); + } + + if (gfs_is_stuffed(ip)) + o += sizeof(struct gfs_dinode); + else if (journaled) + o += sizeof(struct gfs_meta_header); + + while (copied < size) { + amount = size - copied; + if (amount > sdp->sd_sb.sb_bsize - o) + amount = sdp->sd_sb.sb_bsize - o; + + if (!extlen) { + if (!gfs_is_stuffed(ip)) { + new = TRUE; + error = gfs_block_map(ip, lblock, &new, &dblock, &extlen); + if (error) + goto fail; + } else { + new = FALSE; + dblock = ip->i_num.no_addr; + extlen = 1; + } + } + + if (journaled && extlen > 1) + gfs_start_ra(ip->i_gl, dblock, extlen); + + error = gfs_get_data_buffer(ip, dblock, + (amount == sdp->sd_sb.sb_bsize) ? TRUE : new, + &bh); + if (error) + goto fail; + + error = copy_fn(ip, bh, &buf, o, amount, new); + brelse(bh); + if (error) + goto fail; + + copied += amount; + lblock++; + dblock++; + extlen--; + + o = (journaled) ? sizeof(struct gfs_meta_header) : 0; + } + + out: + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + return error; + + if (ip->i_di.di_size < start + copied) + ip->i_di.di_size = start + copied; + ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + + return copied; + + fail: + if (copied) + goto out; + return error; +} + +/* + * gfs_zero_blocks - zero out disk blocks via gfs_writei() + * @ip: The file to write to + * @bh: The buffer to clear + * @buf: The pseudo buffer (not used but added to keep interface unchanged) + * @offset: The offset in the buffer to write to + * @size: The size to zero out + * @new: Flag indicating that remaining space in the buffer should be zeroed + * + * Returns: 0 on success, -EXXX on failure + */ + +int +gfs_zero_blocks(struct gfs_inode *ip, struct buffer_head *bh, void **buf, + unsigned int offset, unsigned int size, int new) +{ + int error = 0; + + /* The dinode block always gets journaled */ + if (bh->b_blocknr == ip->i_num.no_addr) { + if (gfs_assert_warn(ip->i_sbd, !new)) + return -EIO; + gfs_trans_add_bh(ip->i_gl, bh); + memset((bh)->b_data + offset, 0, size); + + /* Data blocks for journaled files get written added to the journal */ + } else if (gfs_is_jdata(ip)) { + gfs_trans_add_bh(ip->i_gl, bh); + memset((bh)->b_data + offset, 0, size); + if (new) + gfs_buffer_clear_ends(bh, offset, size, TRUE); + + /* Non-journaled data blocks get written to in-place disk blocks */ + } else { + memset((bh)->b_data + offset, 0, size); + if (new) + gfs_buffer_clear_ends(bh, offset, size, FALSE); + error = gfs_dwrite(ip->i_sbd, bh, DIO_DIRTY); + } + + return error; +} + --- linux-2.6.28.orig/ubuntu/gfs/ops_address.c +++ linux-2.6.28/ubuntu/gfs/ops_address.c @@ -0,0 +1,504 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "bmap.h" +#include "dio.h" +#include "file.h" +#include "glock.h" +#include "inode.h" +#include "ops_address.h" +#include "page.h" +#include "quota.h" +#include "trans.h" + +static int gfs_commit_write(struct file *file, struct page *page, + unsigned from, unsigned to); +/** + * get_block - Fills in a buffer head with details about a block + * @inode: The inode + * @lblock: The block number to look up + * @bh_result: The buffer head to return the result in + * @create: Non-zero if we may add block to the file + * + * Returns: errno + */ + +static int +get_block(struct inode *inode, sector_t lblock, + struct buffer_head *bh_result, int create) +{ + struct gfs_inode *ip = get_v2ip(inode); + int new = create; + uint64_t dblock; + int error; + + error = gfs_block_map(ip, lblock, &new, &dblock, NULL); + if (error) + return error; + + if (!dblock) + return 0; + + map_bh(bh_result, inode->i_sb, dblock); + if (new) + set_buffer_new(bh_result); + + return 0; +} + +/** + * get_block_noalloc - Fills in a buffer head with details about a block + * @inode: The inode + * @lblock: The block number to look up + * @bh_result: The buffer head to return the result in + * @create: Non-zero if we may add block to the file + * + * Returns: errno + */ + +static int +get_block_noalloc(struct inode *inode, sector_t lblock, + struct buffer_head *bh_result, int create) +{ + int error; + + error = get_block(inode, lblock, bh_result, FALSE); + if (error) + return error; + + if (gfs_assert_withdraw(get_v2sdp(inode->i_sb), + !create || buffer_mapped(bh_result))) + return -EIO; + + return 0; +} + +/** + * get_blocks - + * @inode: + * @lblock: + * @max_blocks: + * @bh_result: + * @create: + * + * Returns: errno + */ + +static int +get_blocks(struct inode *inode, sector_t lblock, + struct buffer_head *bh_result, int create) +{ + struct gfs_inode *ip = get_v2ip(inode); + int new = create; + uint64_t dblock; + int error; + + error = gfs_block_map(ip, lblock, &new, &dblock, NULL); + if (error) + return error; + + if (!dblock) + return 0; + + map_bh(bh_result, inode->i_sb, dblock); + if (new) + set_buffer_new(bh_result); + + return 0; +} + +/** + * get_blocks_noalloc - + * @inode: + * @lblock: + * @max_blocks: + * @bh_result: + * @create: + * + * Returns: errno + */ + +static int +get_blocks_noalloc(struct inode *inode, sector_t lblock, + struct buffer_head *bh_result, int create) +{ + int error; + + error = get_blocks(inode, lblock, bh_result, FALSE); + if (error) + return error; + + if (gfs_assert_withdraw(get_v2sdp(inode->i_sb), + !create || buffer_mapped(bh_result))) + return -EIO; + + return 0; +} + +/** + * gfs_writepage - Write complete page + * @page: Page to write + * + * Returns: errno + * + * Use Linux VFS block_write_full_page() to write one page, + * using GFS's get_block_noalloc to find which blocks to write. + */ + +static int +gfs_writepage(struct page *page, struct writeback_control *wbc) +{ + struct gfs_inode *ip = get_v2ip(page->mapping->host); + struct gfs_sbd *sdp = ip->i_sbd; + int error; + + atomic_inc(&sdp->sd_ops_address); + + if (gfs_assert_withdraw(sdp, gfs_glock_is_held_excl(ip->i_gl))) { + unlock_page(page); + return -EIO; + } + if (get_transaction) { + redirty_page_for_writepage(wbc, page); + unlock_page(page); + return 0; + } + + error = block_write_full_page(page, get_block_noalloc, wbc); + + gfs_flush_meta_cache(ip); + + return error; +} + +/** + * stuffed_readpage - Fill in a Linux page with stuffed file data + * @ip: the inode + * @page: the page + * + * Returns: errno + */ + +static int +stuffed_readpage(struct gfs_inode *ip, struct page *page) +{ + struct buffer_head *dibh; + void *kaddr; + int error; + + error = gfs_get_inode_buffer(ip, &dibh); + if (!error) { + kaddr = kmap(page); + memcpy((char *)kaddr, + dibh->b_data + sizeof(struct gfs_dinode), + ip->i_di.di_size); + memset((char *)kaddr + ip->i_di.di_size, + 0, + PAGE_CACHE_SIZE - ip->i_di.di_size); + kunmap(page); + + brelse(dibh); + + SetPageUptodate(page); + } + + return error; +} + +/** + * readi_readpage - readpage that goes through gfs_internal_read() + * @page: The page to read + * + * Returns: errno + */ + +static int +readi_readpage(struct page *page) +{ + struct gfs_inode *ip = get_v2ip(page->mapping->host); + void *kaddr; + int ret; + + kaddr = kmap(page); + + ret = gfs_internal_read(ip, kaddr, + (uint64_t)page->index << PAGE_CACHE_SHIFT, + PAGE_CACHE_SIZE); + if (ret >= 0) { + if (ret < PAGE_CACHE_SIZE) + memset(kaddr + ret, 0, PAGE_CACHE_SIZE - ret); + SetPageUptodate(page); + ret = 0; + } + + kunmap(page); + + unlock_page(page); + + return ret; +} + +/** + * gfs_readpage - readpage with locking + * @file: The file to read a page for + * @page: The page to read + * + * Returns: errno + */ + +static int +gfs_readpage(struct file *file, struct page *page) +{ + struct gfs_inode *ip = get_v2ip(page->mapping->host); + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_holder *gh; + int error; + + atomic_inc(&sdp->sd_ops_address); + + /* When gfs_readpage is called from the sys_madvise code through the + * readahead code, the inode glock is not held. In this case, we hold + * the inode glock, unlock the page and return AOP_TRUNCATED_PAGE. The + * caller will then reload the page and call gfs_readpage again. We + * also add the flag GL_READPAGE to denote that the glock was held in + * this function and if so, we unlock it before leaving this function + */ + gh = gfs_glock_is_locked_by_me(ip->i_gl); + if (!gh) { + gh = kmalloc(sizeof(struct gfs_holder), GFP_NOFS); + if (!gh) + return -ENOBUFS; + gfs_holder_init(ip->i_gl, LM_ST_SHARED, + GL_READPAGE | LM_FLAG_ANY, gh); + unlock_page(page); + error = gfs_glock_nq(gh); + if (error) { + gfs_holder_uninit(gh); + kfree(gh); + goto out; + } + return AOP_TRUNCATED_PAGE; + } + + if (!gfs_is_jdata(ip)) { + if (gfs_is_stuffed(ip) && !page->index) { + error = stuffed_readpage(ip, page); + unlock_page(page); + } else + error = block_read_full_page(page, get_block); + } else + error = readi_readpage(page); + + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + error = -EIO; + + if (gh->gh_flags & GL_READPAGE) { /* If we grabbed the glock here */ + gfs_glock_dq_uninit(gh); + kfree(gh); + } +out: + return error; +} + +/** + * gfs_prepare_write - Prepare to write a page to a file + * @file: The file to write to + * @page: The page which is to be prepared for writing + * @from: From (byte range within page) + * @to: To (byte range within page) + * + * Returns: errno + * + * Make sure file's inode is glocked; we shouldn't write without that! + * If GFS dinode is currently stuffed (small enough that all data fits within + * the dinode block), and new file size is too large, unstuff it. + * Use Linux VFS block_prepare_write() to write blocks, using GFS' get_block() + * to find which blocks to write. + */ + +static int +gfs_prepare_write(struct file *file, struct page *page, + unsigned from, unsigned to) +{ + struct gfs_inode *ip = get_v2ip(page->mapping->host); + struct gfs_sbd *sdp = ip->i_sbd; + int error = 0; + + atomic_inc(&sdp->sd_ops_address); + + /* We can't set commit_write in the structure in the declare */ + /* because if we do, loopback (loop.c) will interpret that to mean */ + /* it's okay to do buffered writes without locking through sendfile. */ + /* This is a kludge to get around the problem with loop.c because */ + /* the upstream community rejected my changes to loop.c. */ + ip->gfs_file_aops.commit_write = gfs_commit_write; + + if (gfs_assert_warn(sdp, gfs_glock_is_locked_by_me(ip->i_gl))) + return -ENOSYS; + + if (gfs_is_stuffed(ip)) { + uint64_t file_size = ((uint64_t)page->index << PAGE_CACHE_SHIFT) + to; + + if (file_size > sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode)) { + error = gfs_unstuff_dinode(ip, gfs_unstuffer_page, page); + if (!error) + error = block_prepare_write(page, from, to, get_block); + } else if (!PageUptodate(page)) + error = stuffed_readpage(ip, page); + } else + error = block_prepare_write(page, from, to, get_block); + + return error; +} + +/** + * gfs_commit_write - Commit write to a file + * @file: The file to write to + * @page: The page containing the data + * @from: From (byte range within page) + * @to: To (byte range within page) + * + * Returns: errno + */ + +static int +gfs_commit_write(struct file *file, struct page *page, + unsigned from, unsigned to) +{ + struct inode *inode = page->mapping->host; + struct gfs_inode *ip = get_v2ip(inode); + struct gfs_sbd *sdp = ip->i_sbd; + int error; + + atomic_inc(&sdp->sd_ops_address); + + if (gfs_is_stuffed(ip)) { + struct buffer_head *dibh; + uint64_t file_size = ((uint64_t)page->index << PAGE_CACHE_SHIFT) + to; + void *kaddr; + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto fail; + + gfs_trans_add_bh(ip->i_gl, dibh); + + kaddr = kmap(page); + memcpy(dibh->b_data + sizeof(struct gfs_dinode) + from, + (char *)kaddr + from, + to - from); + kunmap(page); + + brelse(dibh); + + SetPageUptodate(page); + + if (inode->i_size < file_size) + i_size_write(inode, file_size); + } else { + loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; + error = block_commit_write(page, from, to); + if (error) + goto fail; + if (pos > inode->i_size) { + i_size_write(inode, pos); + mark_inode_dirty(inode); + } + } + + ip->gfs_file_aops.commit_write = NULL; + return 0; + + fail: + ClearPageUptodate(page); + + return error; +} + +/** + * gfs_bmap - Block map function + * @mapping: Address space info + * @lblock: The block to map + * + * Returns: The disk address for the block or 0 on hole or error + */ + +static sector_t +gfs_bmap(struct address_space *mapping, sector_t lblock) +{ + struct gfs_inode *ip = get_v2ip(mapping->host); + struct gfs_holder i_gh; + int dblock = 0; + int error; + + atomic_inc(&ip->i_sbd->sd_ops_address); + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); + if (error) + return 0; + + if (!gfs_is_stuffed(ip)) + dblock = generic_block_bmap(mapping, lblock, get_block); + + gfs_glock_dq_uninit(&i_gh); + + return dblock; +} + +/** + * gfs_direct_IO - + * @rw: + * @iocb: + * @iov: + * @offset: + * @nr_segs: + * + * Returns: errno + */ + +static ssize_t +gfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, + loff_t offset, unsigned long nr_segs) +{ + struct file *file = iocb->ki_filp; + struct inode *inode = file->f_mapping->host; + struct gfs_inode *ip = get_v2ip(inode); + struct gfs_sbd *sdp = ip->i_sbd; + get_block_t *gb = get_blocks; + + atomic_inc(&sdp->sd_ops_address); + + if (gfs_assert_warn(sdp, gfs_glock_is_locked_by_me(ip->i_gl)) || + gfs_assert_warn(sdp, !gfs_is_stuffed(ip))) + return -EINVAL; + + if (rw == WRITE && !get_transaction) + gb = get_blocks_noalloc; + + if (rw == WRITE) + return blockdev_direct_IO(rw, iocb, inode, + inode->i_sb->s_bdev, iov, + offset, nr_segs, gb, NULL); + else + return blockdev_direct_IO_no_locking(rw, iocb, inode, + inode->i_sb->s_bdev, iov, + offset, nr_segs, gb, NULL); + +} + +struct address_space_operations gfs_file_aops = { + .writepage = gfs_writepage, + .readpage = gfs_readpage, + .sync_page = block_sync_page, + .prepare_write = gfs_prepare_write, + .bmap = gfs_bmap, + .direct_IO = gfs_direct_IO, +}; --- linux-2.6.28.orig/ubuntu/gfs/incore.h +++ linux-2.6.28/ubuntu/gfs/incore.h @@ -0,0 +1,1207 @@ +/* + * In-core (memory/RAM) structures. + * These do not appear on-disk. See gfs_ondisk.h for on-disk structures. + */ + +#ifndef __INCORE_DOT_H__ +#define __INCORE_DOT_H__ + +/* flags used in function call parameters */ + +#define DIO_NEW (0x00000001) /* Newly allocated metadata */ +#define DIO_FORCE (0x00000002) /* Force read of block from disk */ +#define DIO_CLEAN (0x00000004) /* Don't write to disk */ +#define DIO_DIRTY (0x00000008) /* Data changed, must write to disk */ +#define DIO_START (0x00000010) /* Start disk read or write */ +#define DIO_WAIT (0x00000020) /* Wait for disk r/w to complete */ + +#define DIO_METADATA (0x00000040) /* Process glock's protected metadata */ +#define DIO_DATA (0x00000080) /* Process glock's protected filedata */ +#define DIO_INVISIBLE (0x00000100) /* Don't monkey with glock's dirty bit */ +#define DIO_CHECK (0x00000200) /* Make sure all metadata has been synced */ +#define DIO_ALL (0x00000400) /* Flush all AIL transactions to disk */ + +/* Structure prototypes */ + +struct gfs_log_operations; +struct gfs_log_element; +struct gfs_meta_header_cache; +struct gfs_depend; +struct gfs_bitmap; +struct gfs_rgrpd; +struct gfs_bufdata; +struct gfs_glock_operations; +struct gfs_holder; +struct gfs_glock; +struct gfs_alloc; +struct gfs_inode; +struct gfs_file; +struct gfs_unlinked; +struct gfs_quota_le; +struct gfs_quota_data; +struct gfs_log_buf; +struct gfs_trans; +struct gfs_gl_hash_bucket; +struct gfs_sbd; + +typedef void (*gfs_glop_bh_t) (struct gfs_glock * gl, unsigned int ret); + +/* + * Structure of operations that are associated with each + * type of element in the log. + */ +struct gfs_log_operations { + /* + * Operations specific to a given log element (LE). + * These are typically executed individually via macros such as LO_ADD. + */ + + /* Add new LE to transaction */ + void (*lo_add) (struct gfs_sbd * sdp, struct gfs_log_element * le); + + /* Do any cleanup, etc., needed just before commit to incore log */ + void (*lo_trans_end) (struct gfs_sbd * sdp, + struct gfs_log_element * le); + + /* Print LE-specific info via printk() */ + void (*lo_print) (struct gfs_sbd * sdp, struct gfs_log_element * le, + unsigned int where); + + /* Find any incore transactions that overlap through this LE (e.g. + * share glocks), to determine if any transactions can be combined. */ + struct gfs_trans *(*lo_overlap_trans) (struct gfs_sbd * sdp, + struct gfs_log_element * le); + + /* Change LE from "new" to "incore" status, before write to log */ + void (*lo_incore_commit) (struct gfs_sbd * sdp, struct gfs_trans * tr, + struct gfs_log_element * le); + + /* Allow writes to in-place locations, after log is on-disk */ + void (*lo_add_to_ail) (struct gfs_sbd * sdp, + struct gfs_log_element * le); + + /* Clean up LE after log dump */ + void (*lo_clean_dump) (struct gfs_sbd * sdp, + struct gfs_log_element * le); + + /* + * Operations specific to a class of log elements. + * These are typically executed over a whole transaction by + * macros such as LO_TRANS_SIZE. Each LE-type-specific operation + * for each LE contributes its part to the overall result. + */ + + /* Determine LE-type-specific quantities of blocks of various types + * required for writing the log */ + void (*lo_trans_size) (struct gfs_sbd * sdp, struct gfs_trans * tr, + unsigned int *mblks, unsigned int *eblks, + unsigned int *blocks, unsigned int *bmem); + + /* Combine LE-type-specific values in new_tr and tr, result is in tr */ + void (*lo_trans_combine) (struct gfs_sbd * sdp, struct gfs_trans * tr, + struct gfs_trans * new_tr); + + /* Create control and metadata buffers that will make up the log */ + void (*lo_build_bhlist) (struct gfs_sbd * sdp, struct gfs_trans * tr); + + /* Calculate log space needed for this LE in a log dump */ + void (*lo_dump_size) (struct gfs_sbd * sdp, unsigned int *elements, + unsigned int *blocks, unsigned int *bmem); + + /* Add LE to log dump */ + void (*lo_build_dump) (struct gfs_sbd * sdp, struct gfs_trans * tr); + + /* + * Operations that happen at recovery time + */ + + /* Reset/init whatever before doing recovery */ + void (*lo_before_scan) (struct gfs_sbd * sdp, unsigned int jid, + struct gfs_log_header * head, + unsigned int pass); + + /* LE-specific recovery procedure */ + int (*lo_scan_elements) (struct gfs_sbd * sdp, + struct gfs_jindex * jdesc, + struct gfs_glock * gl, uint64_t start, + struct gfs_log_descriptor * desc, + unsigned int pass); + + /* Verify and report recovery results/statistics */ + void (*lo_after_scan) (struct gfs_sbd * sdp, unsigned int jid, + unsigned int pass); + + + /* + * Type of element (glock/buf/unlinked/quota) + */ + char *lo_name; +}; + +/* + * Structure that gets added to struct gfs_trans->tr_elements. They + * make up the "stuff" in each transaction. + */ +struct gfs_log_element { + struct gfs_log_operations *le_ops; /* Vector of functions */ + + struct gfs_trans *le_trans; /* We're part of this transaction */ + struct list_head le_list; /* Link to transaction's element list */ +}; + +/* + * Meta-header cache structure. + * One for each metadata block that we've de-allocated. + * Used to temporarily store gfs_meta_header structs for meta blocks that + * have been freshly turned into FREEMETA (alloc'd or de-alloc'd). Storing + * these (small) structures in-core allows us to release the (large) buffers, + * and not need to re-read the header from disk if/when we re-allocate the + * blocks to USEDMETA, as long as this node holds the EXCLUSIVE lock for the + * resource group containing the blocks. If we release the EX lock, we must + * throw away the rgrp's cached meta headers, since another node could change + * the blocks' contents. + * In-core superblock structure hosts the hashed cache, as well as a + * linear list of all cached, in most-recently-added order. + * Also, each resource group keeps a list of cached blocks within its scope. + */ +struct gfs_meta_header_cache { + /* Links to various lists */ + struct list_head mc_list_hash; /* Superblock's hashed list */ + struct list_head mc_list_single; /* Superblock's list, MRU order */ + struct list_head mc_list_rgd; /* Resource group's list */ + + uint64_t mc_block; /* Block # (in-place address) */ + struct gfs_meta_header mc_mh; /* Payload: the block's meta-header */ +}; + +/* + * Dependency cache structure. + * In-core superblock structure hosts the actual cache. + * Also, each resource group keeps a list of dependency blocks within its scope. + */ +struct gfs_depend { + /* Links to various lists */ + struct list_head gd_list_hash; /* Superblock's hashed list */ + struct list_head gd_list_rgd; /* Resource group's list */ + + struct gfs_rgrpd *gd_rgd; /* Resource group descriptor */ + uint64_t gd_formal_ino; /* Inode ID */ + unsigned long gd_time; /* Time (jiffies) when put on list */ +}; + +/* + * Block allocation bitmap descriptor structure. + * One of these for each FS block that contains bitmap data + * (i.e. the resource group header blocks and their following bitmap blocks). + * Each allocatable FS data block is represented by 2 bits (4 alloc states). + */ +struct gfs_bitmap { + uint32_t bi_offset; /* Byte offset of bitmap within this bit block + (non-zero only for an rgrp header block) */ + uint32_t bi_start; /* Data block (rgrp scope, 32-bit) represented + by the first bit-pair in this bit block */ + uint32_t bi_len; /* The number of bitmap bytes in this bit block */ +}; + +/* + * Resource Group (Rgrp) descriptor structure. + * There is one of these for each resource (block) group in the FS. + * The filesystem is divided into a number of resource groups to allow + * simultaneous block alloc operations by a number of nodes. + */ +struct gfs_rgrpd { + /* Links to superblock lists */ + struct list_head rd_list; /* On-disk-order list of all rgrps */ + struct list_head rd_list_mru; /* Most Recently Used list of all rgs */ + struct list_head rd_recent; /* recently used rgrps */ + uint32_t rd_try_counter; /* # of times we fail a try lock */ + + struct gfs_glock *rd_gl; /* Glock for this rgrp */ + + struct gfs_rindex rd_ri; /* Resource Index (on-disk) structure */ + struct gfs_rgrp rd_rg; /* Resource Group (on-disk) structure */ + uint64_t rd_rg_vn; /* Version #: if != glock's gl_vn, + we need to read rgrp fm disk */ + + /* Block alloc bitmap cache */ + struct gfs_bitmap *rd_bits; /* Array of block bitmap descriptors */ + struct buffer_head **rd_bh; /* Array of ptrs to block bitmap bh's */ + + /* Block allocation strategy, rgrp scope. Start at these blocks when + searching for next data/meta block to alloc */ + uint32_t rd_last_alloc_data; /* Most recent data block allocated */ + uint32_t rd_last_alloc_meta; /* Most recent meta block allocated */ + + struct list_head rd_mhc; /* Cached meta-headers for this rgrp */ + struct list_head rd_depend; /* Dependent inodes (MRU order) */ + + struct gfs_sbd *rd_sbd; /* FS incore superblock (fs instance) */ +}; + +/* + * Per-buffer data + * One of these is attached as GFS private data to each FS block's buffer_head. + * These keep track of a buffer's progress through the transaction pipeline, + * using the "new" embedded log element to attach it to a being-built + * transaction, and moving the attachment point to the "incore" LE once + * the transaction completes (at which time the buffer becomes a candidate + * to be written to the on-disk log). + * A buffer may be attached simultaneously to a new and an incore transaction, + * but no more than one of each: Only one new trans may be built at a time + * for a given buffer, obviously, since the buffer's contents are protected + * by an EXclusive glock when writing. And, when a transaction is completely + * built, GFS combines incore transactions that share glocks (see + * incore_commit()), i.e. the glock that protects the buffer, so a buffer + * never needs to be attached to more than one (combined) incore trans. + * Note that multiple transactions can modify the buffer since its most + * recent writes to disk. This principle applies to both in-place and + * journal block locations on-disk, allowing this node to keep modifying the + * cached data without writing it to disk, unless/until another node needs + * to access the data, or the Linux OS tells us to sync to disk. + * If a transaction follows another transaction before the first transaction's + * log completes (indicated by the in-place buffer head still being pinned + * in RAM), GFS copies the first transaction's results to a "frozen" + * image of the buffer, so the first transaction results (an atomic + * snapshot) can be logged properly, while the second transaction is + * modifying the "real" buffer. This frozen copy lives only until the new + * transaction is complete, at which point one of two things has occurred: + * 1). Buffer was logged successfully; frozen copy's job is done. + * 2). Buffer was not yet logged; frozen copy no longer needed, newer + * buffer becomes the log candidate. + * + * gfs_bufdata structs also link into the Active Items Lists (AIL) (buffers + * flushed to on-disk log, but not yet flushed to on-disk in-place locations) + * attached to: + * 1). The latest transaction to modify and log (on-disk) the buffer, and + * 2). The glock that protects the buffer's contents. + * The buffer is attached to only the most recent transaction's AIL + * list for a couple of reasons. One is that only the most up-to-date + * buffer content needs to be written to the in-place block on-disk. The + * other is that since there is a more recent copy of the block in + * the log, we don't need to keep the older copies in the log. We can + * remove them from the AIL and let the log space be reused for new + * transactions (GFS advances the log tail when removing buffers from AIL). + */ +struct gfs_bufdata { + struct buffer_head *bd_bh; /* We belong to this Linux buffer_head */ + struct gfs_glock *bd_gl; /* This glock protects buffer's payload */ + + /* Log elements map us to a particular set of log operations functions, + and to a particular transaction */ + struct gfs_log_element bd_new_le; /* New, incomplete transaction */ + struct gfs_log_element bd_incore_le; /* Complete (committed) trans */ + + char *bd_frozen; /* "Frozen" copy of buffer's data */ + struct semaphore bd_lock; /* Protects access to this structure */ + + /* "Pin" means keep buffer in RAM, don't write to disk (yet) */ + unsigned int bd_pinned; /* Recursive pin count */ + + /* Links to Active Items Lists */ + struct list_head bd_ail_tr_list; /* This buf's most recent trans' AIL */ + struct list_head bd_ail_gl_list; /* This buf's glock's AIL */ +}; + +/* + * Glock operations + * One set of operations for each glock, the set selected by type of glock. + * These functions get called at various points in a glock's lifetime. + * "xmote" = promote or demote (change lock state) a glock at inter-node scope. + * "th" = top half, "bh" = bottom half + * Some operations/fields are required (GFS assumes they are there): + * go_xmote_th + * go_drop_th + * go_type + * Other operations are optional (GFS checks for presence before calling). + */ +struct gfs_glock_operations { + + /* Acquire lock or change lock state at inter-node scope: + Does type-specific preparation (if any) + Uses gfs_glock_xmote_th to call lock module. */ + void (*go_xmote_th) (struct gfs_glock * gl, unsigned int state, + int flags); + + /* After acquiring or changing a lock at inter-node scope */ + void (*go_xmote_bh) (struct gfs_glock * gl); + + /* Release (unlock) a lock at inter-node scope: + Does type-specific preparation (if any) + Uses gfs_glock_drop_th to call lock module. */ + void (*go_drop_th) (struct gfs_glock * gl); + + /* After releasing a lock at inter-node scope */ + void (*go_drop_bh) (struct gfs_glock * gl); + + /* Sync dirty data to disk (e.g. before demoting an EX inter-node lock) + (another node needs to read the updated data from disk) */ + void (*go_sync) (struct gfs_glock * gl, int flags); + + /* Invalidate local cached data just after releasing an inter-node lock + (another node may change the on-disk data, so it's no good to us) */ + void (*go_inval) (struct gfs_glock * gl, int flags); + + /* Lock-type-specific check to see if it's okay to unlock a glock + at inter-node scope (and remove it from our glock cache) */ + int (*go_demote_ok) (struct gfs_glock * gl); + + /* After getting lock for first holder (within this node) */ + int (*go_lock) (struct gfs_glock * gl, int flags); + + /* After last holder (within this node) gives up lock (glock may + remain in glock cache, though) */ + void (*go_unlock) (struct gfs_glock * gl, int flags); + + /* After receiving a callback: another node needs the lock */ + void (*go_callback) (struct gfs_glock * gl, unsigned int state); + + /* Called when the glock layer marks a lock as being not greedy + anymore */ + void (*go_greedy) (struct gfs_glock * gl); + + /* Lock type: locks with same lock # (often an FS block #), + but different types, are different locks */ + int go_type; +}; + +/* + * Glock holder structure + * One for each holder of a glock. + * These coordinate the use, within this node, of an acquired inter-node glock. + * Once a node has acquired a glock, it may be shared within that node by + * several processes, or even by several recursive requests from the same + * process. Each is a separate "holder". Different holders may co-exist + * having requested different lock states, as long as the node holds the + * glock in a state that is compatible. A hold requestor may select, via + * flags, the rules by which sharing within the node is granted: + * LM_FLAG_ANY: Grant if glock state is any other than UNLOCKED. + * GL_EXACT: Grant only if glock state is exactly the requested state. + * GL_LOCAL_EXCL: Grant only one holder at a time within this node. + * With no flags, a hold will be granted to a SHARED request even if the + * node holds the glock in EXCLUSIVE mode. See relaxed_state_ok(). + * When a process needs to manipulate a lock, it requests it via one of + * these holder structures. If the request cannot be satisfied immediately, + * the holder structure gets queued on one of these lists in gfs_glock: + * 1) waiters1, for gaining exclusive access to the (local) glock structure. + * 2) waiters2, for demoting a lock (unlocking a glock, or changing its state + * to be less restrictive) or relenquishing "greedy" status. + * 3) waiters3, for promoting (locking a new glock, or changing a glock state + * to be more restrictive). + * When holding a lock, gfs_holder struct stays on glock's holder list. + * See gfs-kernel/src/harness/lm_interface.h for gh_state (LM_ST_...) + * and gh_flags (LM_FLAG...) fields. + * Also see glock.h for gh_flags field (GL_...) flags. + */ + +/* Action requests */ +#define HIF_MUTEX (0) /* Exclusive (local) access to glock struct */ +#define HIF_PROMOTE (1) /* Change lock to more restrictive state */ +#define HIF_DEMOTE (2) /* Change lock to less restrictive state */ +#define HIF_GREEDY (3) /* Wait for the glock to be unlocked */ + +/* States */ +#define HIF_ALLOCED (4) /* Holder structure is or was in use */ +#define HIF_DEALLOC (5) /* Toss holder struct as soon as queued request + * is satisfied */ +#define HIF_HOLDER (6) /* We have been granted a hold on the lock */ +#define HIF_FIRST (7) /* We are first holder to get the lock */ +#define HIF_RECURSE (8) /* >1 hold requests on same glock by same process*/ +#define HIF_ABORTED (9) /* Aborted before being submitted */ + +struct gfs_holder { + struct list_head gh_list; /* Link to one of glock's holder lists */ + + struct gfs_glock *gh_gl; /* Glock that we're holding */ + struct task_struct *gh_owner; /* Linux process that is the holder */ + + /* request to change lock state */ + unsigned int gh_state; /* LM_ST_... requested lock state */ + int gh_flags; /* GL_... or LM_FLAG_... req modifiers */ + + int gh_error; /* GLR_... CANCELLED/TRYFAILED/-errno */ + unsigned long gh_iflags; /* HIF_... holder state, see above */ + struct completion gh_wait; /* Wait for completion of ... */ +}; + +/* + * Glock Structure + * One for each inter-node lock held by this node. + * A glock is a local representation/abstraction of an inter-node lock. + * Inter-node locks are managed by a "lock module" (LM) which plugs in to + * the lock harness / glock interface (see gfs-kernel/harness). Different + * lock modules support different lock protocols (e.g. GULM, GDLM, no_lock). + * A glock may have one or more holders within a node. See gfs_holder above. + * Glocks are managed within a hash table hosted by the in-core superblock. + * After all holders have released a glock, it will stay in the hash table + * cache for a time (depending on lock type), during which the inter-node + * lock will not be released unless another node needs the lock (lock + * manager requests this via callback to GFS through LM on this node). This + * provides better performance in case this node needs the glock again soon. + * See comments for meta_go_demote_ok(), glops.c. + * Each glock has an associated vector of lock-type-specific "glops" functions + * which are called at important times during the life of a glock, and + * which define the type of lock (e.g. dinode, rgrp, non-disk, etc). + * See gfs_glock_operations above. + * A glock, at inter-node scope, is identified by the following dimensions: + * 1) lock number (usually a block # for on-disk protected entities, + * or a fixed assigned number for non-disk locks, e.g. MOUNT). + * 2) lock type (actually, the type of entity protected by the lock). + * 3) lock namespace, to support multiple GFS filesystems simultaneously. + * Namespace (usually cluster:filesystem) is specified when mounting. + * See man page for gfs_mount. + * Glocks require support of Lock Value Blocks (LVBs) by the inter-node lock + * manager. LVBs are small (32-byte) chunks of data associated with a given + * lock, that can be quickly shared between cluster nodes. Used for certain + * purposes such as sharing an rgroup's block usage statistics without + * requiring the overhead of: + * -- sync-to-disk by one node, then a + * -- read from disk by another node. + * + */ + +#define GLF_PLUG (0) /* Dummy */ +#define GLF_LOCK (1) /* Exclusive (local) access to glock + * structure */ +#define GLF_STICKY (2) /* Don't release this inter-node lock + * unless another node explicitly asks */ +#define GLF_PREFETCH (3) /* This lock has been (speculatively) + * prefetched, demote if not used soon */ +#define GLF_SYNC (4) /* Sync lock's protected data as soon as + * there are no more holders */ +#define GLF_DIRTY (5) /* There is dirty data for this lock, + * sync before releasing inter-node */ +#define GLF_SKIP_WAITERS2 (6) /* Make run_queue() ignore gl_waiters2 + * (demote/greedy) holders */ +#define GLF_GREEDY (7) /* This lock is ignoring callbacks + * (requests from other nodes) for now */ + +struct gfs_glock { + struct list_head gl_list; /* Link to hb_list in one of superblock's + * sd_gl_hash glock hash table buckets */ + unsigned long gl_flags; /* GLF_... see above */ + struct lm_lockname gl_name; /* Lock number and lock type */ + atomic_t gl_count; /* Usage count */ + + spinlock_t gl_spin; /* Protects some members of this struct */ + + /* Lock state reflects inter-node manager's lock state */ + unsigned int gl_state; /* LM_ST_... see harness/lm_interface.h */ + + /* Lists of gfs_holders */ + struct list_head gl_holders; /* all current holders of the glock */ + struct list_head gl_waiters1; /* HIF_MUTEX */ + struct list_head gl_waiters2; /* HIF_DEMOTE, HIF_GREEDY */ + struct list_head gl_waiters3; /* HIF_PROMOTE */ + + struct gfs_glock_operations *gl_ops; /* function vector, defines type */ + + /* State to remember for async lock requests */ + struct gfs_holder *gl_req_gh; /* Holder for request being serviced */ + gfs_glop_bh_t gl_req_bh; /* The bottom half to execute */ + + void *gl_lock; /* Lock module's private lock data */ + char *gl_lvb; /* Lock Value Block */ + atomic_t gl_lvb_count; /* LVB recursive usage (hold/unhold) count */ + + uint64_t gl_vn; /* Incremented when protected data changes */ + unsigned long gl_stamp; /* Glock cache retention timer */ + void *gl_object; /* The protected entity (e.g. a dinode) */ + + /* Incore transaction stuff */ + /* Log elements map us to a particular set of log operations functions, + and to a particular transaction */ + struct gfs_log_element gl_new_le; /* New, incomplete transaction */ + struct gfs_log_element gl_incore_le; /* Complete (committed) trans */ + + struct gfs_gl_hash_bucket *gl_bucket; /* Our bucket in sd_gl_hash */ + struct list_head gl_reclaim; /* Link to sd_reclaim_list */ + + struct gfs_sbd *gl_sbd; /* Superblock (FS instance) */ + + struct inode *gl_aspace; /* The buffers protected by this lock */ + struct list_head gl_ail_bufs; /* AIL buffers protected by us */ +}; + +/* + * In-Place Reservation structure + * Coordinates allocation of "in-place" (as opposed to journal) FS blocks, + * which contain persistent inode/file/directory data and metadata. + * These blocks are the allocatable blocks within resource groups (i.e. + * not including rgrp header and block alloc bitmap blocks). + * gfs_inplace_reserve() calculates a fulfillment plan for allocating blocks, + * based on block statistics in the resource group headers. + * Then, gfs_blkalloc() or gfs_metaalloc() walks the block alloc bitmaps + * to do the actual allocation. + */ +struct gfs_alloc { + /* Up to 4 quotas (including an inode's user and group quotas) + can track changes in block allocation */ + + unsigned int al_qd_num; /* # of quotas tracking changes */ + struct gfs_quota_data *al_qd[4]; /* Ptrs to quota structures */ + struct gfs_holder al_qd_ghs[4]; /* Holders for quota glocks */ + + /* Request, filled in by the caller to gfs_inplace_reserve() */ + + uint32_t al_requested_di; /* Number of dinodes to reserve */ + uint32_t al_requested_meta; /* Number of metadata blocks to reserve */ + uint32_t al_requested_data; /* Number of data blocks to reserve */ + + /* Fulfillment plan, filled in by gfs_inplace_reserve() */ + + char *al_file; /* Debug info, .c file making request */ + unsigned int al_line; /* Debug info, line of code making req */ + struct gfs_holder al_ri_gh; /* Glock holder for resource grp index */ + struct gfs_holder al_rgd_gh; /* Glock holder for al_rgd rgrp */ + struct gfs_rgrpd *al_rgd; /* Resource group from which to alloc */ + uint32_t al_reserved_meta; /* Alloc up to this # meta blocks from al_rgd */ + uint32_t al_reserved_data; /* Alloc up to this # data blocks from al_rgd */ + + /* Actual alloc, filled in by gfs_blkalloc()/gfs_metaalloc(), etc. */ + + uint32_t al_alloced_di; /* # dinode blocks allocated */ + uint32_t al_alloced_meta; /* # meta blocks allocated */ + uint32_t al_alloced_data; /* # data blocks allocated */ + + /* Dinode allocation crap */ + + struct gfs_unlinked *al_ul; /* Unlinked dinode log entry */ +}; + +/* + * Incore inode structure + */ + +#define GIF_QD_LOCKED (0) +#define GIF_PAGED (1) +#define GIF_SW_PAGED (2) + +struct gfs_inode { + struct gfs_inum i_num; /* Formal inode # and block address */ + + atomic_t i_count; /* Usage count */ + unsigned long i_flags; /* GIF_... see above */ + + uint64_t i_vn; /* Version #: if different from glock's vn, + we need to read inode from disk */ + struct gfs_dinode i_di; /* Dinode (on-disk) structure */ + + struct gfs_glock *i_gl; /* This glock protects this inode */ + struct gfs_sbd *i_sbd; /* Superblock (fs instance structure) */ + struct inode *i_vnode; /* Linux VFS inode structure */ + + struct gfs_holder i_iopen_gh; /* Glock holder for Inode Open lock */ + + /* Block allocation strategy, inode scope */ + struct gfs_alloc *i_alloc; /* In-place block reservation structure */ + uint64_t i_last_rg_alloc; /* Most recent blk alloc was fm this rgrp */ + + spinlock_t i_spin; + struct rw_semaphore i_rw_mutex; + + /* Cache of most-recently used buffers in indirect addressing chain */ + struct buffer_head *i_cache[GFS_MAX_META_HEIGHT]; + + unsigned int i_greedy; /* The amount of time to be greedy */ + unsigned long i_last_pfault; /* The time of the last page fault */ + struct address_space_operations gfs_file_aops; +}; + +/* + * GFS per-fd structure + */ + +#define GFF_DID_DIRECT_ALLOC (0) + +struct gfs_file { + unsigned long f_flags; /* GFF_... see above */ + + struct semaphore f_fl_lock; /* Lock to protect flock operations */ + struct gfs_holder f_fl_gh; /* Holder for this f_vfile's flock */ + + struct gfs_inode *f_inode; /* Incore GFS inode */ + struct file *f_vfile; /* Linux file struct */ +}; + +/* + * Unlinked inode log entry incore structure + */ + +#define ULF_NEW_UL (0) /* Part of new (being built) trans */ +#define ULF_INCORE_UL (1) /* Part of incore-committed trans */ +#define ULF_IC_LIST (2) +#define ULF_OD_LIST (3) +#define ULF_LOCK (4) /* Protects access to this structure */ + +struct gfs_unlinked { + struct list_head ul_list; /* Link to superblock's sd_unlinked_list */ + unsigned int ul_count; /* Usage count */ + + struct gfs_inum ul_inum; /* Formal inode #, block addr */ + unsigned long ul_flags; /* ULF_... */ + + /* Log elements map us to a particular set of log operations functions, + and to a particular transaction */ + struct gfs_log_element ul_new_le; /* New, not yet committed */ + struct gfs_log_element ul_incore_le; /* Committed to incore log */ + struct gfs_log_element ul_ondisk_le; /* Committed to ondisk log */ +}; + +/* + * Quota log element + * One for each logged change in a block alloc value affecting a given quota. + * Only one of these for a given quota within a given transaction; + * multiple changes, within one transaction, for a given quota will be + * combined into one log element. + */ +struct gfs_quota_le { + /* Log element maps us to a particular set of log operations functions, + and to a particular transaction */ + struct gfs_log_element ql_le; /* Generic log element structure */ + + struct gfs_quota_data *ql_data; /* The quota we're changing */ + struct list_head ql_data_list; /* Link to quota's log element list */ + + int64_t ql_change; /* # of blocks alloc'd (+) or freed (-) */ +}; + +/* + * Quota structure + * One for each user or group quota. + * Summarizes all block allocation activity for a given quota, and supports + * recording updates of current block alloc values in GFS' special quota + * file, including the journaling of these updates, encompassing + * multiple transactions and log dumps. + */ + +#define QDF_USER (0) /* User (1) vs. group (0) quota */ +#define QDF_OD_LIST (1) /* Waiting for sync to quota file */ +#define QDF_LOCK (2) /* Protects access to this structure */ + +struct gfs_quota_data { + struct list_head qd_list; /* Link to superblock's sd_quota_list */ + unsigned int qd_count; /* Usage count */ + + uint32_t qd_id; /* User or group ID number */ + unsigned long qd_flags; /* QDF_... */ + + /* This list is for non-log-dump transactions */ + struct list_head qd_le_list; /* List of gfs_quota_le log elements */ + + /* Summary of block alloc changes affecting this quota, in various + stages of logging & syncing changes to the special quota file */ + int64_t qd_change_new; /* New, not yet committed to in-core log*/ + int64_t qd_change_ic; /* Committed to in-core log */ + int64_t qd_change_od; /* Committed to on-disk log */ + int64_t qd_change_sync; /* Being synced to the in-place quota file */ + + struct gfs_quota_le qd_ondisk_ql; /* Log element for log dump */ + uint64_t qd_sync_gen; /* Sync-to-quota-file generation # */ + + /* Glock provides protection for quota, *and* provides + lock value block (LVB) communication, between nodes, of current + quota values. Shared lock -> LVB read. EX lock -> LVB write. */ + struct gfs_glock *qd_gl; /* glock for this quota */ + struct gfs_quota_lvb qd_qb; /* LVB (limit/warn/value) */ + + unsigned long qd_last_warn; /* Jiffies of last warning to user */ +}; + +/* + * Log Buffer descriptor structure. + * One for each block buffer recorded in the log. + * When beginning a new transaction, GFS pre-allocates a number of these, + * and puts them on transaction's tr_free_bufs list. + * Logged buffers are of two types: + * 1). Exact copies of buffers to be written to in-place location in FS. + * 2). Log-only buffers such as log headers and control blocks (e.g. tags). + * A gfs_log_buf is required for both types; the ones for log-only buffers + * contain NULL in lb_unlock, and get cleaned up after the log write. + * lb_bh is a "fake" buffer head that directs Linux block I/O to write the buf + * to the on-disk log location, rather than the on-disk in-place location. + * Used for both types. + * lb_unlock points to the "real" buffer head that directs Linux to write the + * buf to its regular on-disk in-place filesystem location. Once the commit + * to the on-disk log is finished, GFS unlocks the "real" buffer so it can be + * written to in-place block, or modified by another transaction. + * Used only for type 1). + */ +struct gfs_log_buf { + /* Link to one of the transaction structure's lists */ + struct list_head lb_list; /* Link to tr_free_bufs or tr_list */ + + struct buffer_head lb_bh; /* "Fake" bh; for the log block */ + struct buffer_head *lb_unlock; /* "Real" bh; for the in-place block */ +}; + +/* + * Transaction structure + * One for each transaction + * This coordinates the logging and flushing of written metadata. + */ + +#define TRF_LOG_DUMP (0x00000001) +#define TRF_DUMMY (0x00000002) + +struct gfs_trans { + + /* Link to various lists */ + struct list_head tr_list; /* Superblk's incore trans or AIL list*/ + + /* Initial creation stuff */ + + char *tr_file; /* Debug info: .c file creating trans */ + unsigned int tr_line; /* Debug info: codeline creating trans */ + + /* Reservations for on-disk space in journal. + Meta blocks are copies of in-place filesystem blocks. + Extra blocks are log-only (log header and control blocks) */ + unsigned int tr_mblks_asked; /* # of meta log blocks requested */ + unsigned int tr_eblks_asked; /* # of extra log blocks requested */ + unsigned int tr_seg_reserved; /* # of segments actually reserved */ + + struct gfs_holder *tr_t_gh; /* Glock holder for this transaction */ + + /* Stuff filled in during creation */ + + unsigned int tr_flags; /* TRF_... */ + struct list_head tr_elements; /* List of this trans' log elements */ + + /* Stuff modified during the commit */ + + /* When creating a new transaction, GFS pre-allocates as many of + these buffers and descriptor structures as it might need for + all loggable filesystem (meta)data, and log-control (log-only, not + going to filesystem in-place location) data going to on-disk log. + It keeps them on these "free" lists until they get used (and linked + into tr_bufs list, below) or "refunded" if not needed. */ + unsigned int tr_num_free_bufs; /* List of free gfs_log_buf structs */ + struct list_head tr_free_bufs; /* .. 1 for each log block */ + unsigned int tr_num_free_bmem; /* List of free fs-block-size buffers */ + struct list_head tr_free_bmem; /* .. for log-only (e.g. tag) blocks */ + + /* Logged transaction starts with a (first) log header at a segment + boundary, and fills contiguous blocks after that. Each segment + boundary block gets another log header. */ + uint64_t tr_log_head; /* The next log block # to fill */ + uint64_t tr_first_head; /* Trans' first log header's block # */ + + /* gfs_log_buf structs move from tr_free_bufs to here when being used */ + struct list_head tr_bufs; /* List of buffers going to the log */ + + /* Stuff that's part of the Active Items List (AIL) */ + + struct list_head tr_ail_bufs; /* List of buffers on AIL list */ + + /* # log elements of various types on tr_elements list */ + + unsigned int tr_num_gl; /* Glocks */ + unsigned int tr_num_buf; /* Buffers */ + unsigned int tr_num_iul; /* Unlinked inodes */ + unsigned int tr_num_ida; /* De-allocated inodes */ + unsigned int tr_num_q; /* Quotas */ +}; + +#define GFS_GLOCKD_DEFAULT (1) +#define GFS_GLOCKD_MAX (32) + +#define GFS_QUOTA_DEFAULT GFS_QUOTA_OFF +#define GFS_QUOTA_OFF 0 +#define GFS_QUOTA_ACCOUNT 1 +#define GFS_QUOTA_ON 2 + +#define GFS_DATA_DEFAULT GFS_DATA_ORDERED +#define GFS_DATA_WRITEBACK 1 +#define GFS_DATA_ORDERED 2 + + +struct gfs_args { + char ar_lockproto[GFS_LOCKNAME_LEN]; /* The name of the Lock Protocol */ + char ar_locktable[GFS_LOCKNAME_LEN]; /* The name of the Lock Table */ + char ar_hostdata[GFS_LOCKNAME_LEN]; /* The host specific data */ + + int ar_spectator; /* Don't get a journal because we're always RO. */ + /* + * GFS can invoke some flock and disk caching optimizations if it is + * not in a cluster, i.e. is a local filesystem. The chosen lock + * module tells GFS, at mount time, if it supports clustering. + * The nolock module is the only one that does not support clustering; + * it sets to TRUE the local_fs field in the struct lm_lockops. + * GFS can either optimize, or ignore the opportunity. + * The user controls behavior via the following mount options. + */ + int ar_ignore_local_fs; /* Don't optimize even if local_fs is TRUE */ + int ar_localflocks; /* Let the VFS do flock|fcntl locks for us */ + int ar_localcaching; /* Local-style caching (dangerous on multihost) */ + int ar_oopses_ok; /* Allow oopses */ + + int ar_debug; /* Oops on errors instead of trying to be graceful */ + int ar_upgrade; /* Upgrade ondisk/multihost format */ + + unsigned int ar_num_glockd; /* # of glock cleanup daemons to run + (more daemons => faster cleanup) */ + int ar_posix_acls; /* Enable posix acls */ + int ar_suiddir; /* suiddir support */ + int ar_noquota; /* Turn off quota support */ +}; + +struct gfs_tune { + spinlock_t gt_spin; + + unsigned int gt_ilimit1; + unsigned int gt_ilimit1_tries; + unsigned int gt_ilimit1_min; + unsigned int gt_ilimit2; + unsigned int gt_ilimit2_tries; + unsigned int gt_ilimit2_min; + unsigned int gt_demote_secs; /* Cache retention for unheld glock */ + unsigned int gt_incore_log_blocks; + unsigned int gt_jindex_refresh_secs; /* Check for new journal index */ + unsigned int gt_depend_secs; + + /* How often various daemons run (seconds) */ + unsigned int gt_scand_secs; /* Find unused glocks and inodes */ + unsigned int gt_recoverd_secs; /* Recover journal of crashed node */ + unsigned int gt_logd_secs; /* Update log tail as AIL flushes */ + unsigned int gt_quotad_secs; /* Sync changes to quota file, clean*/ + unsigned int gt_inoded_secs; /* Toss unused inodes */ + unsigned int gt_glock_purge; /* Purge glock */ + + unsigned int gt_quota_simul_sync; /* Max # quotavals to sync at once */ + unsigned int gt_quota_warn_period; /* Secs between quota warn msgs */ + unsigned int gt_atime_quantum; /* Min secs between atime updates */ + unsigned int gt_quota_quantum; /* Secs between syncs to quota file */ + unsigned int gt_quota_scale_num; /* Numerator */ + unsigned int gt_quota_scale_den; /* Denominator */ + unsigned int gt_quota_enforce; + unsigned int gt_quota_account; + unsigned int gt_new_files_jdata; + unsigned int gt_new_files_directio; + unsigned int gt_max_atomic_write; /* Split large writes into this size*/ + unsigned int gt_max_readahead; /* Max bytes to read-ahead from disk */ + unsigned int gt_lockdump_size; + unsigned int gt_stall_secs; /* Detects trouble! */ + unsigned int gt_complain_secs; + unsigned int gt_reclaim_limit; /* Max # glocks in reclaim list */ + unsigned int gt_entries_per_readdir; + unsigned int gt_prefetch_secs; /* Usage window for prefetched glocks */ + unsigned int gt_statfs_slots; + unsigned int gt_max_mhc; /* Max # of meta headers in mhc cache */ + unsigned int gt_greedy_default; + unsigned int gt_greedy_quantum; + unsigned int gt_greedy_max; + unsigned int gt_rgrp_try_threshold; + unsigned int gt_statfs_fast; +}; + +/* + * One bucket of the filesystem's sd_gl_hash glock hash table. + * + * A gfs_glock links into a bucket's list via glock's gl_list member. + * + */ +struct gfs_gl_hash_bucket { + rwlock_t hb_lock; /* Protects list */ + struct list_head hb_list; /* List of glocks in this bucket */ +}; + +/* + * "Super Block" Data Structure + * One per mounted filesystem. + * This is the big instance structure that ties everything together for + * a given mounted filesystem. Each GFS mount has its own, supporting + * mounts of multiple GFS filesystems on each node. + * Pointer to this is usually seen as "sdp" throughout code. + * This is a very large structure, as structures go, in part because it + * contains arrays of hash buckets for various in-core caches. + */ + +#define SDF_JOURNAL_LIVE (0) /* Journaling is active (journal is writeable)*/ +#define SDF_SHUTDOWN (1) /* FS abnormaly shutdown */ + +/* (Re)mount options from Linux VFS */ +#define SDF_NOATIME (8) /* Don't change access time */ +#define SDF_ROFS (9) /* Read-only mode */ + +/* Journal log dump support */ +#define SDF_NEED_LOG_DUMP (10) /* Need to rewrite unlink and quota tags */ +#define SDF_FOUND_UL_DUMP (11) /* Recovery found unlinked tags */ +#define SDF_FOUND_Q_DUMP (12) /* Recovery found qutoa tags */ +#define SDF_IN_LOG_DUMP (13) /* Serializes log dumps */ + +/* Glock cache */ +#define GFS_GL_HASH_SHIFT (13) /* # hash buckets = 8K */ +#define GFS_GL_HASH_SIZE (1 << GFS_GL_HASH_SHIFT) +#define GFS_GL_HASH_MASK (GFS_GL_HASH_SIZE - 1) + +/* Meta header cache */ +#define GFS_MHC_HASH_SHIFT (10) /* # hash buckets = 1K */ +#define GFS_MHC_HASH_SIZE (1 << GFS_MHC_HASH_SHIFT) +#define GFS_MHC_HASH_MASK (GFS_MHC_HASH_SIZE - 1) + +/* Dependency cache */ +#define GFS_DEPEND_HASH_SHIFT (10) /* # hash buckets = 1K */ +#define GFS_DEPEND_HASH_SIZE (1 << GFS_DEPEND_HASH_SHIFT) +#define GFS_DEPEND_HASH_MASK (GFS_DEPEND_HASH_SIZE - 1) + +struct gfs_sbd { + struct gfs_sb sd_sb; /* GFS on-disk Super Block image */ + + struct super_block *sd_vfs; /* Linux VFS device independent sb */ + + struct gfs_args sd_args; /* Mount arguments */ + unsigned long sd_flags; /* SDF_... see above */ + + struct gfs_tune sd_tune; /* Filesystem tuning structure */ + + /* statfs */ + struct inode *sd_statfs_inode; + spinlock_t sd_statfs_spin; + struct gfs_statfs_change_host sd_statfs_master; + struct gfs_statfs_change_host sd_statfs_local; + unsigned long sd_statfs_sync_time; + + /* Resource group stuff */ + + struct gfs_inode *sd_riinode; /* Resource Index (rindex) inode */ + uint64_t sd_riinode_vn; /* Resource Index version # (detects + whether new rgrps have been added) */ + + struct list_head sd_rglist; /* List of all resource groups, + on-disk order */ + struct semaphore sd_rindex_lock;/* Serializes RIndex rereads */ + struct list_head sd_rg_mru_list;/* List of all resource groups, + most-recently-used (MRU) order */ + spinlock_t sd_rg_mru_lock; /* Protect mru list */ + struct list_head sd_rg_recent; /* List of rgrps from which blocks + were recently allocated */ + spinlock_t sd_rg_recent_lock; /* Protect recent list */ + struct gfs_rgrpd *sd_rg_forward;/* Next rgrp from which to attempt + a block alloc */ + spinlock_t sd_rg_forward_lock; /* Protect forward pointer */ + + unsigned int sd_rgcount; /* Total # of resource groups */ + + /* Constants computed on mount */ + + /* "bb" == "basic block" == 512Byte sector */ + uint32_t sd_fsb2bb; /* # 512B basic blocks in a FS block */ + uint32_t sd_fsb2bb_shift; /* Shift sector # to the right by + this to get FileSystem block addr */ + uint32_t sd_diptrs; /* Max # of block pointers in a dinode */ + uint32_t sd_inptrs; /* Max # of block pointers in an indirect blk */ + uint32_t sd_jbsize; /* Payload size (bytes) of a journaled metadata + block (GFS journals all meta blocks) */ + uint32_t sd_hash_bsize; /* sizeof(exhash hash block) */ + uint32_t sd_hash_bsize_shift; + uint32_t sd_hash_ptrs; /* Number of points in a hash block */ + uint32_t sd_max_dirres; /* Max blocks needed to add a directory entry */ + uint32_t sd_max_height; /* Max height of a file's tree */ + uint64_t sd_heightsize[GFS_MAX_META_HEIGHT]; + uint32_t sd_max_jheight; /* Max height, journaled file's tree */ + uint64_t sd_jheightsize[GFS_MAX_META_HEIGHT]; + + /* Lock Stuff */ + + /* Glock cache (all glocks currently held by this node for this FS) */ + struct gfs_gl_hash_bucket sd_gl_hash[GFS_GL_HASH_SIZE]; + + /* Glock reclaim support for scand and glockd */ + struct list_head sd_reclaim_list; /* List of glocks to reclaim */ + spinlock_t sd_reclaim_lock; + wait_queue_head_t sd_reclaim_wchan; + atomic_t sd_reclaim_count; /* # glocks on reclaim list */ + + /* Lock module tells us if we're first-to-mount, + which journal to use, etc. */ + struct lm_lockstruct sd_lockstruct; /* Info provided by lock module */ + + /* Other caches */ + + /* Meta-header cache (incore copies of on-disk meta headers) */ + struct list_head sd_mhc[GFS_MHC_HASH_SIZE]; /* hash buckets */ + struct list_head sd_mhc_single; /* Non-hashed list of all MHCs */ + spinlock_t sd_mhc_lock; + atomic_t sd_mhc_count; /* # MHCs in cache */ + + /* Dependency cache */ + struct list_head sd_depend[GFS_DEPEND_HASH_SIZE]; /* Hash buckets */ + spinlock_t sd_depend_lock; + atomic_t sd_depend_count; /* # dependencies in cache */ + + /* LIVE inter-node lock indicates that FS is mounted on at least + one node */ + struct gfs_holder sd_live_gh; /* Glock holder for LIVE lock */ + + /* For quiescing the filesystem */ + struct gfs_holder sd_freeze_gh; + struct semaphore sd_freeze_lock; + unsigned int sd_freeze_count; + + /* Inode Stuff */ + + struct gfs_inode *sd_rooti; /* FS's root inode */ + + /* Only 1 node at a time may rename (e.g. mv) directory from + one directory to another. */ + struct gfs_glock *sd_rename_gl; /* Rename glock */ + + /* Daemon stuff */ + + /* Scan for glocks and inodes to toss from memory */ + struct task_struct *sd_scand_process; /* Scand places on reclaim list*/ + struct task_struct *sd_glockd_process[GFS_GLOCKD_MAX]; + unsigned int sd_glockd_num; /* # of glockd procs to do reclaiming*/ + + /* Recover journal of a crashed node */ + struct task_struct *sd_recoverd_process; + + /* Update log tail as AIL gets flushed to in-place on-disk blocks */ + struct task_struct *sd_logd_process; + + /* Sync quota updates to disk, and clean up unused quota structs */ + struct task_struct *sd_quotad_process; + + /* Clean up unused inode structures */ + struct task_struct *sd_inoded_process; + + /* Log stuff */ + + /* Transaction lock protects the following from one another: + normal write transaction, journal replay (recovery), fs upgrade, + fs read-only => read/write and read/write => read-only conversions. + Also, acquiring the transaction lock in a state other than shared + causes all other machines in the cluster to sync out their dirty + data, mark their journal as being clean, and prevent any new FS + modifications from occuring (i.e. quiesces the FS). */ + struct gfs_glock *sd_trans_gl; /* Transaction glock structure */ + + struct gfs_inode *sd_jiinode; /* Journal index inode */ + uint64_t sd_jiinode_vn; /* Journal index version # (detects + if new journals have been added) */ + + unsigned int sd_journals; /* Number of journals in the FS */ + struct gfs_jindex *sd_jindex; /* Array of journal descriptors */ + struct semaphore sd_jindex_lock; + unsigned long sd_jindex_refresh_time; /* Poll for new journals (secs) */ + + struct gfs_jindex sd_jdesc; /* This machine's journal descriptor */ + struct gfs_holder sd_journal_gh; /* This machine's jrnl glock holder */ + + uint64_t sd_sequence; /* Assigned to xactions in order they commit */ + uint64_t sd_log_head; /* Block number of next journal write */ + uint64_t sd_log_wrap; + + spinlock_t sd_log_seg_lock; + unsigned int sd_log_seg_free; /* # of free segments in the log */ + unsigned int sd_log_seg_ail2; /* # of freeable segments in the log */ + struct list_head sd_log_seg_list; + wait_queue_head_t sd_log_seg_wait; + + /* "Active Items List" of transactions that have been flushed to + on-disk log, and are waiting for flush to in-place on-disk blocks */ + struct list_head sd_log_ail; /* "next" is head, "prev" is tail */ + + /* Transactions committed incore, but not yet flushed to on-disk log */ + struct list_head sd_log_incore; /* "Next" is newest, "prev" is oldest */ + unsigned int sd_log_buffers; /* # of buffers in the incore log */ + + struct rw_semaphore sd_log_lock; /* Lock for access to log values */ + + uint64_t sd_log_dump_last; + uint64_t sd_log_dump_last_wrap; + + /* + * Unlinked inode crap. + * List includes newly created, not-yet-linked inodes, + * as well as inodes that have been unlinked and are waiting + * to be de-allocated. + */ + struct list_head sd_unlinked_list; /* List of unlinked inodes */ + spinlock_t sd_unlinked_lock; /* Protects list and members */ + + atomic_t sd_unlinked_ic_count; + atomic_t sd_unlinked_od_count; + + /* Quota crap */ + + struct list_head sd_quota_list; /* List of all gfs_quota_data structs */ + spinlock_t sd_quota_lock; + + atomic_t sd_quota_count; /* # quotas on sd_quota_list */ + atomic_t sd_quota_od_count; /* # quotas waiting for sync to + special on-disk quota file */ + + struct gfs_inode *sd_qinode; /* Special on-disk quota file */ + + uint64_t sd_quota_sync_gen; /* Generation, incr when sync to file */ + unsigned long sd_quota_sync_time; /* Jiffies, last sync to quota file */ + + /* License crap */ + + struct gfs_inode *sd_linode; /* Special on-disk license file */ + + /* Recovery stuff */ + + /* Lock module tells GFS, via callback, when a journal needs recovery. + It stays on this list until recovery daemon performs recovery. */ + struct list_head sd_dirty_j; /* List of dirty journals */ + spinlock_t sd_dirty_j_lock; /* Protects list */ + + /* Statistics for 3 possible recovery actions for each buffer in log, + determined by comparing generation #s of logged block and + in-place block. Scope of stats is for one journal. */ + unsigned int sd_recovery_replays; /* newer than in-place; copy it */ + unsigned int sd_recovery_skips; /* older than in-place; ignore it */ + unsigned int sd_recovery_sames; /* same as in-place; ignore it */ + + /* Counters */ + + /* current quantities of various things */ + atomic_t sd_glock_count; /* # of gfs_glock structs alloc'd */ + atomic_t sd_glock_held_count; /* # of glocks locked by this node */ + atomic_t sd_inode_count; /* # of gfs_inode structs alloc'd */ + atomic_t sd_bufdata_count; /* # of gfs_bufdata structs alloc'd */ + + atomic_t sd_fh2dentry_misses; /* total # get_dentry misses */ + atomic_t sd_reclaimed; /* total # glocks reclaimed since mount */ + + /* total lock-related calls handled since mount */ + atomic_t sd_glock_nq_calls; + atomic_t sd_glock_dq_calls; + atomic_t sd_glock_prefetch_calls; + atomic_t sd_lm_lock_calls; + atomic_t sd_lm_unlock_calls; + atomic_t sd_lm_callbacks; + + atomic_t sd_lm_outstanding; + atomic_t sd_bio_reads; + atomic_t sd_bio_writes; + atomic_t sd_bio_outstanding; + + /* total calls from Linux VFS handled since mount */ + atomic_t sd_ops_address; + atomic_t sd_ops_dentry; + atomic_t sd_ops_export; + atomic_t sd_ops_file; + atomic_t sd_ops_inode; + atomic_t sd_ops_super; + atomic_t sd_ops_vm; + + char sd_fsname[256]; + char sd_table_name[256]; + char sd_proto_name[256]; + + struct kobject sd_kobj; + + /* Debugging crud */ + + unsigned long sd_last_warning; + + spinlock_t sd_ail_lock; + struct list_head sd_recovery_bufs; + + struct list_head sd_list; +}; + +#endif /* __INCORE_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/quota.c +++ linux-2.6.28/ubuntu/gfs/quota.c @@ -0,0 +1,1139 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "bmap.h" +#include "file.h" +#include "glock.h" +#include "glops.h" +#include "log.h" +#include "quota.h" +#include "rgrp.h" +#include "super.h" +#include "trans.h" + +/** + * gfs_quota_get - Get a structure to represent a quota change + * @sdp: the filesystem + * @user: TRUE if this is a user quota + * @id: the uid or gid + * @create: if TRUE, create the structure, otherwise return NULL + * @qdp: the returned quota structure + * + * Returns: errno + */ + +int +gfs_quota_get(struct gfs_sbd *sdp, int user, uint32_t id, int create, + struct gfs_quota_data **qdp) +{ + struct gfs_quota_data *qd = NULL, *new_qd = NULL; + struct list_head *tmp, *head; + int error; + + *qdp = NULL; + + for (;;) { + spin_lock(&sdp->sd_quota_lock); + + for (head = &sdp->sd_quota_list, tmp = head->next; + tmp != head; + tmp = tmp->next) { + qd = list_entry(tmp, struct gfs_quota_data, qd_list); + if (qd->qd_id == id && + !test_bit(QDF_USER, &qd->qd_flags) == !user) { + qd->qd_count++; + break; + } + } + + if (tmp == head) + qd = NULL; + + if (!qd && new_qd) { + qd = new_qd; + list_add(&qd->qd_list, &sdp->sd_quota_list); + new_qd = NULL; + } + + spin_unlock(&sdp->sd_quota_lock); + + if (qd || !create) { + if (new_qd) { + gfs_lvb_unhold(new_qd->qd_gl); + kfree(new_qd); + atomic_dec(&sdp->sd_quota_count); + } + *qdp = qd; + return 0; + } + + new_qd = kmalloc(sizeof(struct gfs_quota_data), GFP_KERNEL); + if (!new_qd) + return -ENOMEM; + memset(new_qd, 0, sizeof(struct gfs_quota_data)); + + new_qd->qd_count = 1; + + new_qd->qd_id = id; + if (user) + set_bit(QDF_USER, &new_qd->qd_flags); + + INIT_LIST_HEAD(&new_qd->qd_le_list); + + error = gfs_glock_get(sdp, 2 * (uint64_t)id + ((user) ? 0 : 1), + &gfs_quota_glops, CREATE, + &new_qd->qd_gl); + if (error) { + kfree(new_qd); + return error; + } + + error = gfs_lvb_hold(new_qd->qd_gl); + + gfs_glock_put(new_qd->qd_gl); + + if (error) { + kfree(new_qd); + return error; + } + + atomic_inc(&sdp->sd_quota_count); + } +} + +/** + * gfs_quota_hold - increment the usage count on a struct gfs_quota_data + * @sdp: the filesystem + * @qd: the structure + * + */ + +void +gfs_quota_hold(struct gfs_sbd *sdp, struct gfs_quota_data *qd) +{ + spin_lock(&sdp->sd_quota_lock); + gfs_assert(sdp, qd->qd_count,); + qd->qd_count++; + spin_unlock(&sdp->sd_quota_lock); +} + +/** + * gfs_quota_put - decrement the usage count on a struct gfs_quota_data + * @sdp: the filesystem + * @qd: the structure + * + * Free the structure if its reference count hits zero. + * + */ + +void +gfs_quota_put(struct gfs_sbd *sdp, struct gfs_quota_data *qd) +{ + spin_lock(&sdp->sd_quota_lock); + gfs_assert(sdp, qd->qd_count,); + qd->qd_count--; + spin_unlock(&sdp->sd_quota_lock); +} + +/** + * quota_find - Find a quota change to sync to the quota file + * @sdp: the filesystem + * + * The returned structure is locked and needs to be unlocked + * with quota_unlock(). + * + * Returns: A quota structure, or NULL + */ + +static struct gfs_quota_data * +quota_find(struct gfs_sbd *sdp) +{ + struct list_head *tmp, *head; + struct gfs_quota_data *qd = NULL; + + if (test_bit(SDF_ROFS, &sdp->sd_flags)) + return NULL; + + gfs_log_lock(sdp); + spin_lock(&sdp->sd_quota_lock); + + if (!atomic_read(&sdp->sd_quota_od_count)) + goto out; + + for (head = &sdp->sd_quota_list, tmp = head->next; + tmp != head; + tmp = tmp->next) { + qd = list_entry(tmp, struct gfs_quota_data, qd_list); + + if (test_bit(QDF_LOCK, &qd->qd_flags)) + continue; + if (!test_bit(QDF_OD_LIST, &qd->qd_flags)) + continue; + if (qd->qd_sync_gen >= sdp->sd_quota_sync_gen) + continue; + + list_move_tail(&qd->qd_list, &sdp->sd_quota_list); + + set_bit(QDF_LOCK, &qd->qd_flags); + qd->qd_count++; + qd->qd_change_sync = qd->qd_change_od; + + goto out; + } + + qd = NULL; + + out: + spin_unlock(&sdp->sd_quota_lock); + gfs_log_unlock(sdp); + + return qd; +} + +/** + * quota_trylock - Try to lock a given quota entry + * @sdp: the filesystem + * @qd: the quota data structure + * + * Returns: TRUE if the lock was successful, FALSE, otherwise + */ + +static int +quota_trylock(struct gfs_sbd *sdp, struct gfs_quota_data *qd) +{ + int ret = FALSE; + + if (test_bit(SDF_ROFS, &sdp->sd_flags)) + return FALSE; + + gfs_log_lock(sdp); + spin_lock(&sdp->sd_quota_lock); + + if (test_bit(QDF_LOCK, &qd->qd_flags)) + goto out; + if (!test_bit(QDF_OD_LIST, &qd->qd_flags)) + goto out; + + list_move_tail(&qd->qd_list, &sdp->sd_quota_list); + + set_bit(QDF_LOCK, &qd->qd_flags); + qd->qd_count++; + qd->qd_change_sync = qd->qd_change_od; + + ret = TRUE; + + out: + spin_unlock(&sdp->sd_quota_lock); + gfs_log_unlock(sdp); + + return ret; +} + +/** + * quota_unlock - drop and a reference on a quota structure + * @sdp: the filesystem + * @qd: the quota inode structure + * + */ + +static void +quota_unlock(struct gfs_sbd *sdp, struct gfs_quota_data *qd) +{ + spin_lock(&sdp->sd_quota_lock); + + gfs_assert_warn(sdp, test_bit(QDF_LOCK, &qd->qd_flags)); + clear_bit(QDF_LOCK, &qd->qd_flags); + + gfs_assert(sdp, qd->qd_count,); + qd->qd_count--; + + spin_unlock(&sdp->sd_quota_lock); +} + +/** + * gfs_quota_merge - add/remove a quota change from the in-memory list + * @sdp: the filesystem + * @tag: the quota change tag + * + * Returns: errno + */ + +int +gfs_quota_merge(struct gfs_sbd *sdp, struct gfs_quota_tag *tag) +{ + struct gfs_quota_data *qd; + int error; + + error = gfs_quota_get(sdp, + tag->qt_flags & GFS_QTF_USER, tag->qt_id, + CREATE, &qd); + if (error) + return error; + + gfs_assert(sdp, qd->qd_change_ic == qd->qd_change_od,); + + gfs_log_lock(sdp); + + qd->qd_change_ic += tag->qt_change; + qd->qd_change_od += tag->qt_change; + + if (qd->qd_change_od) { + if (!test_bit(QDF_OD_LIST, &qd->qd_flags)) { + gfs_quota_hold(sdp, qd); + set_bit(QDF_OD_LIST, &qd->qd_flags); + atomic_inc(&sdp->sd_quota_od_count); + } + } else { + gfs_assert_warn(sdp, test_bit(QDF_OD_LIST, &qd->qd_flags)); + clear_bit(QDF_OD_LIST, &qd->qd_flags); + gfs_quota_put(sdp, qd); + gfs_assert(sdp, atomic_read(&sdp->sd_quota_od_count) > 0,); + atomic_dec(&sdp->sd_quota_od_count); + } + + gfs_log_unlock(sdp); + + gfs_quota_put(sdp, qd); + + return 0; +} + +/** + * gfs_quota_scan - Look for unused struct gfs_quota_data structures to throw away + * @sdp: the filesystem + * + */ + +void +gfs_quota_scan(struct gfs_sbd *sdp) +{ + struct list_head *head, *tmp, *next; + struct gfs_quota_data *qd; + LIST_HEAD(dead); + + spin_lock(&sdp->sd_quota_lock); + + for (head = &sdp->sd_quota_list, tmp = head->next, next = tmp->next; + tmp != head; + tmp = next, next = next->next) { + qd = list_entry(tmp, struct gfs_quota_data, qd_list); + if (!qd->qd_count) + list_move(&qd->qd_list, &dead); + } + + spin_unlock(&sdp->sd_quota_lock); + + while (!list_empty(&dead)) { + qd = list_entry(dead.next, struct gfs_quota_data, qd_list); + + gfs_assert_warn(sdp, !qd->qd_count); + gfs_assert_warn(sdp, !test_bit(QDF_OD_LIST, &qd->qd_flags) && + !test_bit(QDF_LOCK, &qd->qd_flags)); + gfs_assert_warn(sdp, !qd->qd_change_new && !qd->qd_change_ic && + !qd->qd_change_od); + + list_del(&qd->qd_list); + gfs_lvb_unhold(qd->qd_gl); + kfree(qd); + atomic_dec(&sdp->sd_quota_count); + } +} + +/** + * gfs_quota_cleanup - get rid of any extra struct gfs_quota_data structures + * @sdp: the filesystem + * + */ + +void +gfs_quota_cleanup(struct gfs_sbd *sdp) +{ + struct gfs_quota_data *qd; + + restart: + gfs_log_lock(sdp); + + spin_lock(&sdp->sd_quota_lock); + + while (!list_empty(&sdp->sd_quota_list)) { + qd = list_entry(sdp->sd_quota_list.next, + struct gfs_quota_data, + qd_list); + + if (qd->qd_count > 1) { + spin_unlock(&sdp->sd_quota_lock); + gfs_log_unlock(sdp); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ); + goto restart; + + } else if (qd->qd_count) { + gfs_assert_warn(sdp, + test_bit(QDF_OD_LIST, &qd->qd_flags) && + !test_bit(QDF_LOCK, &qd->qd_flags)); + gfs_assert_warn(sdp, qd->qd_change_od && + qd->qd_change_od == qd->qd_change_ic); + gfs_assert_warn(sdp, !qd->qd_change_new); + + list_del(&qd->qd_list); + atomic_dec(&sdp->sd_quota_od_count); + + spin_unlock(&sdp->sd_quota_lock); + gfs_lvb_unhold(qd->qd_gl); + kfree(qd); + atomic_dec(&sdp->sd_quota_count); + spin_lock(&sdp->sd_quota_lock); + + } else { + gfs_assert_warn(sdp, + !test_bit(QDF_OD_LIST, &qd->qd_flags) && + !test_bit(QDF_LOCK, &qd->qd_flags)); + gfs_assert_warn(sdp, !qd->qd_change_new && + !qd->qd_change_ic && + !qd->qd_change_od); + + list_del(&qd->qd_list); + + spin_unlock(&sdp->sd_quota_lock); + gfs_lvb_unhold(qd->qd_gl); + kfree(qd); + atomic_dec(&sdp->sd_quota_count); + spin_lock(&sdp->sd_quota_lock); + } + } + + spin_unlock(&sdp->sd_quota_lock); + + gfs_assert(sdp, !atomic_read(&sdp->sd_quota_od_count),); + + gfs_log_unlock(sdp); +} + +/** + * sort_qd - figure out the order between two quota data structures + * @a: first quota data structure + * @b: second quota data structure + * + * Returns: -1 if @a comes before @b, 0 if @a equals @b, 1 if @b comes before @a + */ + +static int +sort_qd(const void *a, const void *b) +{ + struct gfs_quota_data *qd_a = *(struct gfs_quota_data **)a; + struct gfs_quota_data *qd_b = *(struct gfs_quota_data **)b; + int ret = 0; + + if (!test_bit(QDF_USER, &qd_a->qd_flags) != + !test_bit(QDF_USER, &qd_b->qd_flags)) { + if (test_bit(QDF_USER, &qd_a->qd_flags)) + ret = -1; + else + ret = 1; + } else { + if (qd_a->qd_id < qd_b->qd_id) + ret = -1; + else if (qd_a->qd_id > qd_b->qd_id) + ret = 1; + } + + return ret; +} + +/** + * do_quota_sync - Sync a bunch quota changes to the quota file + * @sdp: the filesystem + * @qda: an array of struct gfs_quota_data structures to be synced + * @num_qd: the number of elements in @qda + * + * Returns: errno + */ + +static int +do_quota_sync(struct gfs_sbd *sdp, struct gfs_quota_data **qda, + unsigned int num_qd) +{ + struct gfs_inode *ip = sdp->sd_qinode; + struct gfs_alloc *al = NULL; + struct gfs_holder i_gh, *ghs; + struct gfs_quota q; + char buf[sizeof(struct gfs_quota)]; + uint64_t offset; + unsigned int qx, x; + int ar; + unsigned int nalloc = 0; + unsigned int data_blocks, ind_blocks; + int error; + + gfs_write_calc_reserv(ip, sizeof(struct gfs_quota), &data_blocks, + &ind_blocks); + + ghs = kmalloc(num_qd * sizeof(struct gfs_holder), GFP_KERNEL); + if (!ghs) + return -ENOMEM; + + gfs_sort(qda, num_qd, sizeof (struct gfs_quota_data *), sort_qd); + for (qx = 0; qx < num_qd; qx++) { + error = gfs_glock_nq_init(qda[qx]->qd_gl, + LM_ST_EXCLUSIVE, + GL_NOCACHE, &ghs[qx]); + if (error) + goto fail; + } + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); + if (error) + goto fail; + + for (x = 0; x < num_qd; x++) { + offset = (2 * (uint64_t)qda[x]->qd_id + + ((test_bit(QDF_USER, &qda[x]->qd_flags)) ? 0 : 1)) * + sizeof(struct gfs_quota); + + error = gfs_write_alloc_required(ip, offset, + sizeof(struct gfs_quota), + &ar); + if (error) + goto fail_gunlock; + + if (ar) + nalloc++; + } + + if (nalloc) { + al = gfs_alloc_get(ip); + + error = + gfs_quota_hold_m(ip, NO_QUOTA_CHANGE, + NO_QUOTA_CHANGE); + if (error) + goto fail_alloc; + + al->al_requested_meta = nalloc * (data_blocks + ind_blocks); + + error = gfs_inplace_reserve(ip); + if (error) + goto fail_qs; + + /* Trans may require: + two (journaled) data blocks, a dinode block, RG bitmaps to allocate from, + indirect blocks, and a quota block */ + + error = gfs_trans_begin(sdp, + 1 + al->al_rgd->rd_ri.ri_length + + num_qd * data_blocks + + nalloc * ind_blocks, + gfs_struct2blk(sdp, num_qd + 2, + sizeof(struct gfs_quota_tag))); + if (error) + goto fail_ipres; + } else { + /* Trans may require: + Data blocks, a dinode block, and quota blocks */ + + error = gfs_trans_begin(sdp, + 1 + data_blocks * num_qd, + gfs_struct2blk(sdp, num_qd, + sizeof(struct gfs_quota_tag))); + if (error) + goto fail_gunlock; + } + + for (x = 0; x < num_qd; x++) { + offset = (2 * (uint64_t)qda[x]->qd_id + + ((test_bit(QDF_USER, &qda[x]->qd_flags)) ? 0 : 1)) * + sizeof(struct gfs_quota); + + /* The quota file may not be a multiple of sizeof(struct gfs_quota) bytes. */ + memset(buf, 0, sizeof(struct gfs_quota)); + + error = gfs_internal_read(ip, buf, offset, + sizeof(struct gfs_quota)); + if (error < 0) + goto fail_end_trans; + + gfs_quota_in(&q, buf); + q.qu_value += qda[x]->qd_change_sync; + gfs_quota_out(&q, buf); + + error = gfs_internal_write(ip, buf, offset, + sizeof(struct gfs_quota)); + if (error < 0) + goto fail_end_trans; + else if (error != sizeof(struct gfs_quota)) { + error = -EIO; + goto fail_end_trans; + } + + if (test_bit(QDF_USER, &qda[x]->qd_flags)) + gfs_trans_add_quota(sdp, -qda[x]->qd_change_sync, + qda[x]->qd_id, NO_QUOTA_CHANGE); + else + gfs_trans_add_quota(sdp, -qda[x]->qd_change_sync, + NO_QUOTA_CHANGE, qda[x]->qd_id); + + memset(&qda[x]->qd_qb, 0, sizeof(struct gfs_quota_lvb)); + qda[x]->qd_qb.qb_magic = GFS_MAGIC; + qda[x]->qd_qb.qb_limit = q.qu_limit; + qda[x]->qd_qb.qb_warn = q.qu_warn; + qda[x]->qd_qb.qb_value = q.qu_value; + + gfs_quota_lvb_out(&qda[x]->qd_qb, qda[x]->qd_gl->gl_lvb); + } + + gfs_trans_end(sdp); + + if (nalloc) { + gfs_assert_warn(sdp, al->al_alloced_meta); + gfs_inplace_release(ip); + gfs_quota_unhold_m(ip); + gfs_alloc_put(ip); + } + + gfs_glock_dq_uninit(&i_gh); + + for (x = 0; x < num_qd; x++) + gfs_glock_dq_uninit(&ghs[x]); + + kfree(ghs); + + gfs_log_flush_glock(ip->i_gl); + + return 0; + + fail_end_trans: + gfs_trans_end(sdp); + + fail_ipres: + if (nalloc) + gfs_inplace_release(ip); + + fail_qs: + if (nalloc) + gfs_quota_unhold_m(ip); + + fail_alloc: + if (nalloc) + gfs_alloc_put(ip); + + fail_gunlock: + gfs_glock_dq_uninit(&i_gh); + + fail: + while (qx--) + gfs_glock_dq_uninit(&ghs[qx]); + + kfree(ghs); + + return error; +} + +/** + * glock_q - Acquire a lock for a quota entry + * @sdp: the filesystem + * @qd: the quota data structure to glock + * @force_refresh: If TRUE, always read from the quota file + * @q_gh: the glock holder for the quota lock + * + * Returns: errno + */ + +static int +glock_q(struct gfs_sbd *sdp, struct gfs_quota_data *qd, int force_refresh, + struct gfs_holder *q_gh) +{ + struct gfs_holder i_gh; + struct gfs_quota q; + char buf[sizeof(struct gfs_quota)]; + int error; + + restart: + error = gfs_glock_nq_init(qd->qd_gl, LM_ST_SHARED, 0, q_gh); + if (error) + return error; + + gfs_quota_lvb_in(&qd->qd_qb, qd->qd_gl->gl_lvb); + + if (force_refresh || + qd->qd_qb.qb_magic != GFS_MAGIC) { + gfs_glock_dq_uninit(q_gh); + error = gfs_glock_nq_init(qd->qd_gl, + LM_ST_EXCLUSIVE, GL_NOCACHE, + q_gh); + if (error) + return error; + + error = gfs_glock_nq_init(sdp->sd_qinode->i_gl, + LM_ST_SHARED, 0, + &i_gh); + if (error) + goto fail; + + memset(buf, 0, sizeof(struct gfs_quota)); + + error = gfs_internal_read(sdp->sd_qinode, buf, + (2 * (uint64_t)qd->qd_id + + ((test_bit(QDF_USER, &qd->qd_flags)) ? 0 : 1)) * + sizeof(struct gfs_quota), + sizeof(struct gfs_quota)); + if (error < 0) + goto fail_gunlock; + + gfs_glock_dq_uninit(&i_gh); + + gfs_quota_in(&q, buf); + + memset(&qd->qd_qb, 0, sizeof(struct gfs_quota_lvb)); + qd->qd_qb.qb_magic = GFS_MAGIC; + qd->qd_qb.qb_limit = q.qu_limit; + qd->qd_qb.qb_warn = q.qu_warn; + qd->qd_qb.qb_value = q.qu_value; + + gfs_quota_lvb_out(&qd->qd_qb, qd->qd_gl->gl_lvb); + + gfs_glock_dq_uninit(q_gh); + force_refresh = FALSE; + goto restart; + } + + return 0; + + fail_gunlock: + gfs_glock_dq_uninit(&i_gh); + + fail: + gfs_glock_dq_uninit(q_gh); + + return error; +} + +/** + * gfs_quota_hold_m - Hold the quota structures for up to 4 IDs + * @ip: Two of the IDs are the UID and GID from this file + * @uid: a UID or the constant NO_QUOTA_CHANGE + * @gid: a GID or the constant NO_QUOTA_CHANGE + * + * The struct gfs_quota_data structures representing the locks are + * stored in the ip->i_alloc->al_qd array. + * + * Returns: errno + */ + +int +gfs_quota_hold_m(struct gfs_inode *ip, uint32_t uid, uint32_t gid) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al = ip->i_alloc; + unsigned int x = 0; + int error; + + if (gfs_assert_warn(sdp, !al->al_qd_num && + !test_bit(GIF_QD_LOCKED, &ip->i_flags))) + return -EIO; + + if (!gfs_tune_get(sdp, gt_quota_account)) + return 0; + + error = gfs_quota_get(sdp, TRUE, ip->i_di.di_uid, + CREATE, &al->al_qd[x]); + if (error) + goto fail; + x++; + + error = gfs_quota_get(sdp, FALSE, ip->i_di.di_gid, + CREATE, &al->al_qd[x]); + if (error) + goto fail; + x++; + + if (uid != NO_QUOTA_CHANGE) { + error = gfs_quota_get(sdp, TRUE, uid, + CREATE, &al->al_qd[x]); + if (error) + goto fail; + x++; + } + + if (gid != NO_QUOTA_CHANGE) { + error = gfs_quota_get(sdp, FALSE, gid, + CREATE, &al->al_qd[x]); + if (error) + goto fail; + x++; + } + + al->al_qd_num = x; + + return 0; + + fail: + if (x) { + al->al_qd_num = x; + gfs_quota_unhold_m(ip); + } + + return error; +} + +/** + * gfs_quota_unhold_m - throw away some quota locks + * @ip: the inode who's ip->i_alloc->al_qd array holds the structures + * + */ + +void +gfs_quota_unhold_m(struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al = ip->i_alloc; + unsigned int x; + + gfs_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &ip->i_flags)); + + for (x = 0; x < al->al_qd_num; x++) { + gfs_quota_put(sdp, al->al_qd[x]); + al->al_qd[x] = NULL; + } + al->al_qd_num = 0; +} + +/** + * gfs_quota_lock_m - Acquire the quota locks for up to 4 IDs + * @ip: Two of the IDs are the UID and GID from this file + * @uid: a UID or the constant NO_QUOTA_CHANGE + * @gid: a GID or the constant NO_QUOTA_CHANGE + * + * The struct gfs_quota_data structures representing the locks are + * stored in the ip->i_alloc->al_qd array. + * + * Returns: errno + */ + +int +gfs_quota_lock_m(struct gfs_inode *ip, uint32_t uid, uint32_t gid) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al = ip->i_alloc; + unsigned int x; + int error; + + gfs_quota_hold_m(ip, uid, gid); + + if (!gfs_tune_get(sdp, gt_quota_enforce)) + return 0; + if (capable(CAP_SYS_RESOURCE)) + return 0; + + gfs_sort(al->al_qd, al->al_qd_num, + sizeof(struct gfs_quota_data *), sort_qd); + + for (x = 0; x < al->al_qd_num; x++) { + error = glock_q(sdp, al->al_qd[x], FALSE, &al->al_qd_ghs[x]); + if (error) + goto fail; + } + + set_bit(GIF_QD_LOCKED, &ip->i_flags); + + return 0; + + fail: + while (x--) + gfs_glock_dq_uninit(&al->al_qd_ghs[x]); + + return error; +} + +/** + * gfs_quota_unlock_m - drop some quota locks + * @ip: the inode who's ip->i_alloc->al_qd array holds the locks + * + */ + +void +gfs_quota_unlock_m(struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al = ip->i_alloc; + struct gfs_quota_data *qd, *qda[4]; + int64_t value; + unsigned int count = 0; + unsigned int x; + int do_sync; + + if (!test_and_clear_bit(GIF_QD_LOCKED, &ip->i_flags)) + goto out; + + for (x = 0; x < al->al_qd_num; x++) { + qd = al->al_qd[x]; + + spin_lock(&sdp->sd_quota_lock); + value = qd->qd_change_new + qd->qd_change_ic; + spin_unlock(&sdp->sd_quota_lock); + + do_sync = TRUE; + if (!qd->qd_qb.qb_limit) + do_sync = FALSE; + else if (qd->qd_qb.qb_value >= (int64_t)qd->qd_qb.qb_limit) + do_sync = FALSE; + else { + struct gfs_tune *gt = &sdp->sd_tune; + unsigned int num, den; + int64_t v; + + spin_lock(>->gt_spin); + num = gt->gt_quota_scale_num; + den = gt->gt_quota_scale_den; + spin_unlock(>->gt_spin); + + v = value * gfs_num_journals(sdp) * num; + do_div(v, den); + v += qd->qd_qb.qb_value; + if (v < (int64_t)qd->qd_qb.qb_limit) + do_sync = FALSE; + } + + gfs_glock_dq_uninit(&al->al_qd_ghs[x]); + + if (do_sync) { + gfs_log_flush(sdp); + if (quota_trylock(sdp, qd)) + qda[count++] = qd; + } + } + + if (count) { + do_quota_sync(sdp, qda, count); + + for (x = 0; x < count; x++) + quota_unlock(sdp, qda[x]); + } + + out: + gfs_quota_unhold_m(ip); +} + +/** + * print_quota_message - print a message to the user's tty about quotas + * @sdp: the filesystem + * @qd: the quota ID that the message is about + * @type: the type of message ("exceeded" or "warning") + * + * Returns: errno + */ + +static int +print_quota_message(struct gfs_sbd *sdp, struct gfs_quota_data *qd, char *type) +{ + struct tty_struct *tty; + char *line; + int len; + + line = kmalloc(256, GFP_KERNEL); + if (!line) + return -ENOMEM; + + len = snprintf(line, 256, "GFS: fsid=%s: quota %s for %s %u\r\n", + sdp->sd_fsname, type, + (test_bit(QDF_USER, &qd->qd_flags)) ? "user" : "group", + qd->qd_id); + + if (current->signal) { + tty = current->signal->tty; + if (tty && tty->ops->write) + tty->ops->write(tty, line, len); + } + + kfree(line); + + return 0; +} + +/** + * gfs_quota_check - Check to see if a block allocation is possible + * @ip: the inode who's ip->i_res.ir_qd array holds the quota locks + * @uid: the UID the block is allocated for + * @gid: the GID the block is allocated for + * + */ + +int +gfs_quota_check(struct gfs_inode *ip, uint32_t uid, uint32_t gid) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al = ip->i_alloc; + struct gfs_quota_data *qd; + int64_t value; + unsigned int x; + int error = 0; + + if (!al) + return 0; + + if (!gfs_tune_get(sdp, gt_quota_enforce)) + return 0; + + for (x = 0; x < al->al_qd_num; x++) { + qd = al->al_qd[x]; + + if (!((qd->qd_id == uid && test_bit(QDF_USER, &qd->qd_flags)) || + (qd->qd_id == gid && !test_bit(QDF_USER, &qd->qd_flags)))) + continue; + + spin_lock(&sdp->sd_quota_lock); + value = qd->qd_change_new + qd->qd_change_ic; + spin_unlock(&sdp->sd_quota_lock); + value += qd->qd_qb.qb_value; + + if (qd->qd_qb.qb_limit && (int64_t)qd->qd_qb.qb_limit < value) { + print_quota_message(sdp, qd, "exceeded"); + error = -EDQUOT; + break; + } else if (qd->qd_qb.qb_warn && + (int64_t)qd->qd_qb.qb_warn < value && + time_after_eq(jiffies, + qd->qd_last_warn + + gfs_tune_get(sdp, gt_quota_warn_period) * HZ)) { + error = print_quota_message(sdp, qd, "warning"); + qd->qd_last_warn = jiffies; + } + } + + return error; +} + +/** + * gfs_quota_sync - Sync quota changes to the quota file + * @sdp: the filesystem + * + * Returns: errno + */ + +int +gfs_quota_sync(struct gfs_sbd *sdp) +{ + struct gfs_quota_data **qda; + unsigned int max_qd = gfs_tune_get(sdp, gt_quota_simul_sync); + unsigned int num_qd; + unsigned int x; + int error = 0; + + sdp->sd_quota_sync_gen++; + + qda = kmalloc(max_qd * sizeof(struct gfs_quota_data *), GFP_KERNEL); + if (!qda) + return -ENOMEM; + memset(qda, 0, max_qd * sizeof(struct gfs_quota_data *)); + + do { + num_qd = 0; + + for (;;) { + qda[num_qd] = quota_find(sdp); + if (!qda[num_qd]) + break; + + if (++num_qd == max_qd) + break; + } + + if (num_qd) { + error = do_quota_sync(sdp, qda, num_qd); + if (!error) + for (x = 0; x < num_qd; x++) + qda[x]->qd_sync_gen = + sdp->sd_quota_sync_gen; + + for (x = 0; x < num_qd; x++) + quota_unlock(sdp, qda[x]); + } + } + while (!error && num_qd == max_qd); + + kfree(qda); + + return error; +} + +/** + * gfs_quota_refresh - Refresh the LVB for a given quota ID + * @sdp: the filesystem + * @user: + * @id: + * + * Returns: errno + */ + +int +gfs_quota_refresh(struct gfs_sbd *sdp, int user, uint32_t id) +{ + struct gfs_quota_data *qd; + struct gfs_holder q_gh; + int error; + + error = gfs_quota_get(sdp, user, id, CREATE, &qd); + if (error) + return error; + + error = glock_q(sdp, qd, TRUE, &q_gh); + if (!error) + gfs_glock_dq_uninit(&q_gh); + + gfs_quota_put(sdp, qd); + + return error; +} + +/** + * gfs_quota_read - Read the info a given quota ID + * @sdp: the filesystem + * @user: + * @id: + * @q: + * + * Returns: errno + */ + +int +gfs_quota_read(struct gfs_sbd *sdp, int user, uint32_t id, + struct gfs_quota *q) +{ + struct gfs_quota_data *qd; + struct gfs_holder q_gh; + int error; + + if (((user) ? (id != current->fsuid) : (!in_group_p(id))) && + !capable(CAP_SYS_ADMIN)) + return -EACCES; + + error = gfs_quota_get(sdp, user, id, CREATE, &qd); + if (error) + return error; + + error = glock_q(sdp, qd, FALSE, &q_gh); + if (error) + goto out; + + memset(q, 0, sizeof(struct gfs_quota)); + q->qu_limit = qd->qd_qb.qb_limit; + q->qu_warn = qd->qd_qb.qb_warn; + q->qu_value = qd->qd_qb.qb_value; + + spin_lock(&sdp->sd_quota_lock); + q->qu_value += qd->qd_change_new + qd->qd_change_ic; + spin_unlock(&sdp->sd_quota_lock); + + gfs_glock_dq_uninit(&q_gh); + + out: + gfs_quota_put(sdp, qd); + + return error; +} --- linux-2.6.28.orig/ubuntu/gfs/dio.h +++ linux-2.6.28/ubuntu/gfs/dio.h @@ -0,0 +1,157 @@ +#ifndef __DIO_DOT_H__ +#define __DIO_DOT_H__ + +void gfs_ail_start_trans(struct gfs_sbd *sdp, struct gfs_trans *tr); +int gfs_ail_empty_trans(struct gfs_sbd *sdp, struct gfs_trans *tr); + +/* Asynchronous I/O Routines */ + +struct buffer_head *gfs_dgetblk(struct gfs_glock *gl, uint64_t blkno); +int gfs_dread(struct gfs_glock *gl, uint64_t blkno, + int flags, struct buffer_head **bhp); + +void gfs_prep_new_buffer(struct buffer_head *bh); +int gfs_dreread(struct gfs_sbd *sdp, struct buffer_head *bh, int flags); +int gfs_dwrite(struct gfs_sbd *sdp, struct buffer_head *bh, int flags); + +void gfs_attach_bufdata(struct buffer_head *bh, struct gfs_glock *gl); +int gfs_is_pinned(struct gfs_sbd *sdp, struct buffer_head *bh); +void gfs_dpin(struct gfs_sbd *sdp, struct buffer_head *bh); +void gfs_dunpin(struct gfs_sbd *sdp, struct buffer_head *bh, + struct gfs_trans *tr); + +static __inline__ +void gfs_lock_buffer(struct buffer_head *bh) +{ + struct gfs_bufdata *bd = get_v2bd(bh); + down(&bd->bd_lock); +} +static __inline__ +int gfs_trylock_buffer(struct buffer_head *bh) +{ + struct gfs_bufdata *bd = get_v2bd(bh); + return down_trylock(&bd->bd_lock); +} +static __inline__ +void gfs_unlock_buffer(struct buffer_head *bh) +{ + struct gfs_bufdata *bd = get_v2bd(bh); + up(&bd->bd_lock); +} + +void gfs_logbh_init(struct gfs_sbd *sdp, struct buffer_head *bh, uint64_t blkno, + char *data); +void gfs_logbh_uninit(struct gfs_sbd *sdp, struct buffer_head *bh); +void gfs_logbh_start(struct gfs_sbd *sdp, struct buffer_head *bh); +int gfs_logbh_wait(struct gfs_sbd *sdp, struct buffer_head *bh); + +int gfs_replay_buf(struct gfs_glock *gl, struct buffer_head *bh); +void gfs_replay_check(struct gfs_sbd *sdp); +void gfs_replay_wait(struct gfs_sbd *sdp); + +void gfs_wipe_buffers(struct gfs_inode *ip, struct gfs_rgrpd *rgd, + uint64_t bstart, uint32_t blen); + +void gfs_sync_meta(struct gfs_sbd *sdp); + +/* Buffer Caching routines */ + +int gfs_get_meta_buffer(struct gfs_inode *ip, int height, uint64_t num, int new, + struct buffer_head **bhp); +int gfs_get_data_buffer(struct gfs_inode *ip, uint64_t block, int new, + struct buffer_head **bhp); +void gfs_start_ra(struct gfs_glock *gl, uint64_t dblock, uint32_t extlen); + +static __inline__ int +gfs_get_inode_buffer(struct gfs_inode *ip, struct buffer_head **bhp) +{ + return gfs_get_meta_buffer(ip, 0, ip->i_num.no_addr, FALSE, bhp); +} + +struct inode *gfs_aspace_get(struct gfs_sbd *sdp); +void gfs_aspace_put(struct inode *aspace); + +void gfs_inval_buf(struct gfs_glock *gl); +void gfs_sync_buf(struct gfs_glock *gl, int flags); + +void gfs_flush_meta_cache(struct gfs_inode *ip); + +/* Buffer Content Functions */ + +/** + * gfs_buffer_clear - Zeros out a buffer + * @ip: The GFS inode + * @bh: The buffer to zero + * + */ + +static __inline__ void +gfs_buffer_clear(struct buffer_head *bh) +{ + memset(bh->b_data, 0, bh->b_size); +} + +/** + * gfs_buffer_clear_tail - Clear buffer beyond the dinode + * @bh: The buffer containing the on-disk inode + * @head: the size of the head of the buffer + * + * Clears the remaining part of an on-disk inode that is not a dinode. + * i.e. The data part of a stuffed inode, or the top level of metadata + * of a non-stuffed inode. + */ + +static __inline__ void +gfs_buffer_clear_tail(struct buffer_head *bh, int head) +{ + memset(bh->b_data + head, 0, bh->b_size - head); +} + +/** + * gfs_buffer_clear_ends - Zero out any bits of a buffer which are not being written + * @bh: The buffer + * @offset: Offset in buffer where write starts + * @amount: Amount of data being written + * @journaled: TRUE if this is a journaled buffer + * + */ + +static __inline__ void +gfs_buffer_clear_ends(struct buffer_head *bh, int offset, int amount, + int journaled) +{ + int z_off1 = (journaled) ? sizeof(struct gfs_meta_header) : 0; + int z_len1 = offset - z_off1; + int z_off2 = offset + amount; + int z_len2 = (bh)->b_size - z_off2; + + if (z_len1) + memset(bh->b_data + z_off1, 0, z_len1); + + if (z_len2) + memset(bh->b_data + z_off2, 0, z_len2); +} + +/** + * gfs_buffer_copy_tail - copies the tail of one buffer to another + * @to_bh: the buffer to copy to + * @to_head: the size of the head of to_bh + * @from_bh: the buffer to copy from + * @from_head: the size of the head of from_bh + * + * from_head is guaranteed to bigger than to_head + */ + +static __inline__ void +gfs_buffer_copy_tail(struct buffer_head *to_bh, int to_head, + struct buffer_head *from_bh, int from_head) +{ + memcpy(to_bh->b_data + to_head, + from_bh->b_data + from_head, + from_bh->b_size - from_head); + memset(to_bh->b_data + to_bh->b_size + to_head - from_head, + 0, + from_head - to_head); +} + +#endif /* __DIO_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/inode.c +++ linux-2.6.28/ubuntu/gfs/inode.c @@ -0,0 +1,2212 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "acl.h" +#include "bmap.h" +#include "dio.h" +#include "dir.h" +#include "eattr.h" +#include "glock.h" +#include "glops.h" +#include "inode.h" +#include "log.h" +#include "ops_address.h" +#include "ops_file.h" +#include "ops_inode.h" +#include "quota.h" +#include "rgrp.h" +#include "trans.h" +#include "unlinked.h" + +/** + * inode_attr_in - Copy attributes from the dinode into the VFS inode + * @ip: The GFS inode (with embedded disk inode data) + * @inode: The Linux VFS inode + * + */ + +static void +inode_attr_in(struct gfs_inode *ip, struct inode *inode) +{ + unsigned int mode; + + inode->i_ino = ip->i_num.no_formal_ino; + + switch (ip->i_di.di_type) { + case GFS_FILE_REG: + mode = S_IFREG; + inode->i_rdev = 0; + break; + case GFS_FILE_DIR: + mode = S_IFDIR; + inode->i_rdev = 0; + break; + case GFS_FILE_LNK: + mode = S_IFLNK; + inode->i_rdev = 0; + break; + case GFS_FILE_BLK: + mode = S_IFBLK; + inode->i_rdev = MKDEV(ip->i_di.di_major, ip->i_di.di_minor); + break; + case GFS_FILE_CHR: + mode = S_IFCHR; + inode->i_rdev = MKDEV(ip->i_di.di_major, ip->i_di.di_minor); + break; + case GFS_FILE_FIFO: + mode = S_IFIFO; + inode->i_rdev = 0; + break; + case GFS_FILE_SOCK: + mode = S_IFSOCK; + inode->i_rdev = 0; + break; + default: + if (gfs_consist_inode(ip)) + printk("GFS: fsid=%s: type = %u\n", + ip->i_sbd->sd_fsname, ip->i_di.di_type); + return; + }; + + inode->i_mode = mode | (ip->i_di.di_mode & S_IALLUGO); + inode->i_nlink = ip->i_di.di_nlink; + inode->i_uid = ip->i_di.di_uid; + inode->i_gid = ip->i_di.di_gid; + i_size_write(inode, ip->i_di.di_size); + inode->i_atime.tv_sec = ip->i_di.di_atime; + inode->i_mtime.tv_sec = ip->i_di.di_mtime; + inode->i_ctime.tv_sec = ip->i_di.di_ctime; + inode->i_atime.tv_nsec = inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = 0; + inode->i_blocks = ip->i_di.di_blocks << + (ip->i_sbd->sd_sb.sb_bsize_shift - GFS_BASIC_BLOCK_SHIFT); + inode->i_generation = ip->i_di.di_header.mh_incarn; + + if (ip->i_di.di_flags & GFS_DIF_IMMUTABLE) + inode->i_flags |= S_IMMUTABLE; + else + inode->i_flags &= ~S_IMMUTABLE; + + if (ip->i_di.di_flags & GFS_DIF_APPENDONLY) + inode->i_flags |= S_APPEND; + else + inode->i_flags &= ~S_APPEND; +} + +/** + * gfs_inode_attr_in - Copy attributes from the dinode into the VFS inode + * @ip: The GFS inode (with embedded disk inode data) + * + */ + +void +gfs_inode_attr_in(struct gfs_inode *ip) +{ + struct inode *inode; + + inode = gfs_iget(ip, NO_CREATE); + if (inode) { + inode_attr_in(ip, inode); + iput(inode); + } + +} + +/** + * gfs_inode_attr_out - Copy attributes from VFS inode into the dinode + * @ip: The GFS inode + * + * Only copy out the attributes that we want the VFS layer + * to be able to modify. + */ + +void +gfs_inode_attr_out(struct gfs_inode *ip) +{ + struct inode *inode = ip->i_vnode; + + ip->i_di.di_mode = inode->i_mode & S_IALLUGO; + ip->i_di.di_uid = inode->i_uid; + ip->i_di.di_gid = inode->i_gid; + ip->i_di.di_atime = inode->i_atime.tv_sec; + ip->i_di.di_mtime = inode->i_mtime.tv_sec; + ip->i_di.di_ctime = inode->i_ctime.tv_sec; +} + +/** + * gfs_iget - Get/Create a struct inode for a struct gfs_inode + * @ip: the struct gfs_inode to get the struct inode for + * @create: CREATE -- create a new struct inode if one does not already exist + * NO_CREATE -- return NULL if inode doesn't exist + * + * Returns: A VFS inode, or NULL if NO_CREATE and none in existance + * + * If this function creates a new inode, it: + * Copies fields from the GFS on-disk (d)inode to the VFS inode + * Attaches the appropriate ops vectors to the VFS inode and address_space + * Attaches the VFS inode to the gfs_inode + * Inserts the new inode in the VFS inode hash, while avoiding races + */ + +struct inode * +gfs_iget(struct gfs_inode *ip, int create) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct inode *inode = NULL, *tmp; + + spin_lock(&ip->i_spin); + if (ip->i_vnode) + inode = igrab(ip->i_vnode); + spin_unlock(&ip->i_spin); + + if (inode || !create) + return inode; + + tmp = new_inode(ip->i_sbd->sd_vfs); + if (!tmp) + return NULL; + + inode_attr_in(ip, tmp); + + /* Attach GFS-specific ops vectors */ + if (ip->i_di.di_type == GFS_FILE_REG) { + tmp->i_op = &gfs_file_iops; + memcpy(&ip->gfs_file_aops, &gfs_file_aops, + sizeof(struct address_space_operations)); + tmp->i_mapping->a_ops = &ip->gfs_file_aops; + if (sdp->sd_args.ar_localflocks) + tmp->i_fop = &gfs_file_fops_nolock; + else + tmp->i_fop = &gfs_file_fops; + } else if (ip->i_di.di_type == GFS_FILE_DIR) { + tmp->i_op = &gfs_dir_iops; + if (sdp->sd_args.ar_localflocks) + tmp->i_fop = &gfs_dir_fops_nolock; + else + tmp->i_fop = &gfs_dir_fops; + } else if (ip->i_di.di_type == GFS_FILE_LNK) { + tmp->i_op = &gfs_symlink_iops; + } else { + tmp->i_op = &gfs_dev_iops; + init_special_inode(tmp, tmp->i_mode, tmp->i_rdev); + } + + set_v2ip(tmp, NULL); + + /* Did another process successfully create an inode while we were + preparing this (tmp) one? If so, we can use that other one, and + trash the one we were preparing. + The other process might not be done inserting the inode in the + VFS hash table. If so, we need to wait until it is done, then + we can use it. */ + for (;;) { + spin_lock(&ip->i_spin); + if (!ip->i_vnode) + break; + inode = igrab(ip->i_vnode); + spin_unlock(&ip->i_spin); + + if (inode) { + iput(tmp); + return inode; + } + yield(); + } + + inode = tmp; + + gfs_inode_hold(ip); + ip->i_vnode = inode; + set_v2ip(inode, ip); + + spin_unlock(&ip->i_spin); + + insert_inode_hash(inode); + + return inode; +} + +/** + * gfs_copyin_dinode - Refresh the incore copy of the dinode + * @ip: The GFS inode + * + * Returns: errno + */ + +int +gfs_copyin_dinode(struct gfs_inode *ip) +{ + struct buffer_head *dibh; + int error; + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + return error; + + if (gfs_metatype_check(ip->i_sbd, dibh, GFS_METATYPE_DI)) { + brelse(dibh); + return -EIO; + } + + gfs_dinode_in(&ip->i_di, dibh->b_data); + brelse(dibh); + + if (ip->i_num.no_formal_ino != ip->i_di.di_num.no_formal_ino) { + if (gfs_consist_inode(ip)) + gfs_dinode_print(&ip->i_di); + return -EIO; + } + + /* Handle a moved inode (not implemented yet) */ + if (ip->i_num.no_addr != ip->i_di.di_num.no_addr) { + if (gfs_consist_inode(ip)) + gfs_dinode_print(&ip->i_di); + return -EIO; + } + + ip->i_vn = ip->i_gl->gl_vn; + + return 0; +} + +/** + * inode_create - create a struct gfs_inode, acquire Inode-Open (iopen) glock, + * read dinode from disk + * @i_gl: The (already held) glock covering the inode + * @inum: The inode number + * @io_gl: the iopen glock to acquire/hold (using holder in new gfs_inode) + * @io_state: the state the iopen glock should be acquired in + * @ipp: pointer to put the returned inode in + * + * Returns: errno + */ + +static int +inode_create(struct gfs_glock *i_gl, struct gfs_inum *inum, + struct gfs_glock *io_gl, unsigned int io_state, + struct gfs_inode **ipp) +{ + struct gfs_sbd *sdp = i_gl->gl_sbd; + struct gfs_inode *ip; + int error = 0; + + RETRY_MALLOC(ip = kmem_cache_alloc(gfs_inode_cachep, GFP_KERNEL), ip); + memset(ip, 0, sizeof(struct gfs_inode)); + + ip->i_num = *inum; + + atomic_set(&ip->i_count, 1); + + ip->i_gl = i_gl; + ip->i_sbd = sdp; + + spin_lock_init(&ip->i_spin); + init_rwsem(&ip->i_rw_mutex); + + ip->i_greedy = gfs_tune_get(sdp, gt_greedy_default); + + /* Lock the iopen glock (may be recursive) */ + error = gfs_glock_nq_init(io_gl, + io_state, GL_LOCAL_EXCL | GL_EXACT, + &ip->i_iopen_gh); + if (error) + goto fail; + + ip->i_iopen_gh.gh_owner = NULL; + + /* Assign the inode's glock as this iopen glock's protected object */ + spin_lock(&io_gl->gl_spin); + gfs_glock_hold(i_gl); + set_gl2gl(io_gl, i_gl); + spin_unlock(&io_gl->gl_spin); + + /* Read dinode from disk */ + error = gfs_copyin_dinode(ip); + if (error) + goto fail_iopen; + + gfs_glock_hold(i_gl); + set_gl2ip(i_gl, ip); + + atomic_inc(&sdp->sd_inode_count); + + *ipp = ip; + + return 0; + + fail_iopen: + spin_lock(&io_gl->gl_spin); + set_gl2gl(io_gl, NULL); + gfs_glock_put(i_gl); + spin_unlock(&io_gl->gl_spin); + + gfs_glock_dq_uninit(&ip->i_iopen_gh); + + fail: + gfs_flush_meta_cache(ip); + kmem_cache_free(gfs_inode_cachep, ip); + *ipp = NULL; + + return error; +} + +/** + * gfs_inode_get - Get an inode given its number + * @i_gl: The glock covering the inode + * @inum: The inode number + * @create: Flag to say if we are allowed to create a new struct gfs_inode + * @ipp: pointer to put the returned inode in + * + * Returns: errno + * + * If creating a new gfs_inode structure, reads dinode from disk. + */ + +int +gfs_inode_get(struct gfs_glock *i_gl, struct gfs_inum *inum, int create, + struct gfs_inode **ipp) +{ + struct gfs_glock *io_gl; + int error = 0; + + *ipp = get_gl2ip(i_gl); + if (*ipp) { + atomic_inc(&(*ipp)->i_count); + gfs_assert_warn(i_gl->gl_sbd, + (*ipp)->i_num.no_formal_ino == + inum->no_formal_ino); + } else if (create) { + error = gfs_glock_get(i_gl->gl_sbd, + inum->no_addr, &gfs_iopen_glops, + CREATE, &io_gl); + if (!error) { + error = inode_create(i_gl, inum, io_gl, + LM_ST_SHARED, ipp); + gfs_glock_put(io_gl); + } + } + + return error; +} + +/** + * gfs_inode_hold - hold a struct gfs_inode structure + * @ip: The GFS inode + * + */ + +void +gfs_inode_hold(struct gfs_inode *ip) +{ + gfs_assert(ip->i_sbd, atomic_read(&ip->i_count) > 0,); + atomic_inc(&ip->i_count); +} + +/** + * gfs_inode_put - put a struct gfs_inode structure + * @ip: The GFS inode + * + */ + +void +gfs_inode_put(struct gfs_inode *ip) +{ + gfs_assert(ip->i_sbd, atomic_read(&ip->i_count) > 0,); + atomic_dec(&ip->i_count); +} + +/** + * gfs_inode_destroy - Destroy a GFS inode structure with no references on it + * @ip: The GFS inode + * + * Also, unhold the iopen glock and release indirect addressing buffers. + * This function must be called with a glocks held on the inode and + * the associated iopen. + * + */ + +void +gfs_inode_destroy(struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_glock *io_gl = ip->i_iopen_gh.gh_gl; + struct gfs_glock *i_gl = ip->i_gl; + + gfs_assert_warn(sdp, !atomic_read(&ip->i_count)); + gfs_assert(sdp, get_gl2gl(io_gl) == i_gl,); + + /* Unhold the iopen glock */ + spin_lock(&io_gl->gl_spin); + set_gl2gl(io_gl, NULL); + gfs_glock_put(i_gl); + spin_unlock(&io_gl->gl_spin); + + gfs_glock_dq_uninit(&ip->i_iopen_gh); + + /* Release indirect addressing buffers, destroy the GFS inode struct */ + gfs_flush_meta_cache(ip); + kmem_cache_free(gfs_inode_cachep, ip); + + set_gl2ip(i_gl, NULL); + gfs_glock_put(i_gl); + + atomic_dec(&sdp->sd_inode_count); +} + +/** + * dinode_mark_unused - Set UNUSED flag in on-disk dinode + * @ip: + * + * Also: + * -- Increment incarnation number, to indicate that it no longer + * represents the old inode. + * -- Update change time (ctime) + * + * Returns: errno + */ + +static int +dinode_mark_unused(struct gfs_inode *ip) +{ + struct buffer_head *dibh; + struct gfs_dinode *di; + uint32_t incarn; + uint64_t ctime; + uint32_t flags; + int error; + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + return error; + + di = (struct gfs_dinode *)dibh->b_data; + + gfs_trans_add_bh(ip->i_gl, dibh); + + incarn = gfs32_to_cpu(di->di_header.mh_incarn) + 1; + di->di_header.mh_incarn = cpu_to_gfs32(incarn); + + ctime = get_seconds(); + di->di_ctime = cpu_to_gfs64(ctime); + + flags = (gfs32_to_cpu(di->di_flags)) | GFS_DIF_UNUSED; + di->di_flags = cpu_to_gfs32(flags); + + brelse(dibh); + + return 0; +} + +/** + * dinode_dealloc - Put deallocate a dinode + * @ip: The GFS inode + * + * Returns: errno + */ + +static int +dinode_dealloc(struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al; + struct gfs_rgrpd *rgd; + int error; + + if (ip->i_di.di_blocks != 1) { + if (gfs_consist_inode(ip)) + gfs_dinode_print(&ip->i_di); + return -EIO; + } + + al = gfs_alloc_get(ip); + + error = gfs_quota_hold_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + if (error) + goto out; + + error = gfs_rindex_hold(sdp, &al->al_ri_gh); + if (error) + goto out_qs; + + rgd = gfs_blk2rgrpd(sdp, ip->i_num.no_addr); + if (!rgd) { + gfs_consist_inode(ip); + error = -EIO; + goto out_rindex_relse; + } + + error = gfs_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &al->al_rgd_gh); + if (error) + goto out_rindex_relse; + + /* Trans may require: + One block for the RG header. + One block for the dinode bit. + One block for the dinode. + We also need a block for the unlinked change. + One block for the quota change. */ + + error = gfs_trans_begin(sdp, 3, 2); + if (error) + goto out_rg_gunlock; + + /* Set the UNUSED flag in the on-disk dinode block, increment incarn */ + error = dinode_mark_unused(ip); + if (error) + goto out_end_trans; + + /* De-allocate on-disk dinode block to FREEMETA */ + gfs_difree(rgd, ip); + + gfs_trans_add_unlinked(sdp, GFS_LOG_DESC_IDA, &ip->i_num); + clear_bit(GLF_STICKY, &ip->i_gl->gl_flags); + + out_end_trans: + gfs_trans_end(sdp); + + out_rg_gunlock: + gfs_glock_dq_uninit(&al->al_rgd_gh); + + out_rindex_relse: + gfs_glock_dq_uninit(&al->al_ri_gh); + + out_qs: + gfs_quota_unhold_m(ip); + + out: + gfs_alloc_put(ip); + + return error; +} + +/** + * inode_dealloc - Deallocate all on-disk blocks for an inode (dinode) + * @sdp: the filesystem + * @inum: the inode number to deallocate + * @io_gh: a holder for the iopen glock for this inode + * + * De-allocates all on-disk blocks, data and metadata, associated with an inode. + * All metadata blocks become GFS_BLKST_FREEMETA. + * All data blocks become GFS_BLKST_FREE. + * Also de-allocates incore gfs_inode structure. + * + * Returns: errno + */ + +static int +inode_dealloc(struct gfs_sbd *sdp, struct gfs_inum *inum, + struct gfs_holder *io_gh) +{ + struct gfs_inode *ip; + struct gfs_holder i_gh; + int error; + + /* Lock the inode as we blow it away */ + error = gfs_glock_nq_num(sdp, + inum->no_formal_ino, &gfs_inode_glops, + LM_ST_EXCLUSIVE, 0, &i_gh); + if (error) + return error; + + /* We reacquire the iopen lock here to avoid a race with the NFS server + calling gfs_read_inode() with the inode number of a inode we're in + the process of deallocating. And we can't keep our hold on the lock + from inode_dealloc_init() for deadlock reasons. We do, however, + overlap this iopen lock with the one to be acquired EX within + inode_create(), below (recursive EX locks will be granted to same + holder process, i.e. this process). */ + + gfs_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY, io_gh); + error = gfs_glock_nq(io_gh); + switch (error) { + case 0: + break; + case GLR_TRYFAILED: + error = 0; + goto fail; + default: + goto fail; + } + + gfs_assert_warn(sdp, !get_gl2ip(i_gh.gh_gl)); + error = inode_create(i_gh.gh_gl, inum, io_gh->gh_gl, LM_ST_EXCLUSIVE, + &ip); + + gfs_glock_dq(io_gh); + + if (error) + goto fail; + + /* Verify disk (d)inode, gfs inode, and VFS (v)inode are unused */ + if (ip->i_di.di_nlink) { + if (gfs_consist_inode(ip)) + gfs_dinode_print(&ip->i_di); + error = -EIO; + goto fail_iput; + } + gfs_assert_warn(sdp, atomic_read(&ip->i_count) == 1); + gfs_assert_warn(sdp, !ip->i_vnode); + + /* Free all on-disk directory leaves (if any) to FREEMETA state */ + if (ip->i_di.di_type == GFS_FILE_DIR && + (ip->i_di.di_flags & GFS_DIF_EXHASH)) { + error = gfs_dir_exhash_free(ip); + if (error) + goto fail_iput; + } + + /* Free all on-disk extended attribute blocks to FREEMETA state */ + if (ip->i_di.di_eattr) { + error = gfs_ea_dealloc(ip); + if (error) + goto fail_iput; + } + + /* Free all data blocks to FREE state, and meta blocks to FREEMETA */ + error = gfs_shrink(ip, 0, NULL); + if (error) + goto fail_iput; + + /* Set UNUSED flag and increment incarn # in on-disk dinode block, + and de-alloc the block to FREEMETA */ + error = dinode_dealloc(ip); + if (error) + goto fail_iput; + + /* Free the GFS inode structure, unhold iopen and inode glocks */ + gfs_inode_put(ip); + gfs_inode_destroy(ip); + + gfs_glock_dq_uninit(&i_gh); + + return 0; + + fail_iput: + gfs_inode_put(ip); + gfs_inode_destroy(ip); + + fail: + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * inode_dealloc_init - Try to deallocate an initialized on-disk inode (dinode) + * and all of its associated data and meta blocks + * @sdp: the filesystem + * + * Returns: 0 on success, -errno on error, 1 on busy (inode open) + */ + +static int +inode_dealloc_init(struct gfs_sbd *sdp, struct gfs_inum *inum) +{ + struct gfs_holder io_gh; + int error = 0; + + /* If not busy (on this node), de-alloc GFS incore inode, releasing + any indirect addressing buffers, and unholding iopen glock */ + gfs_try_toss_inode(sdp, inum); + + /* Does another process (cluster-wide) have this inode open? */ + error = gfs_glock_nq_num(sdp, + inum->no_addr, &gfs_iopen_glops, + LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB, &io_gh); + switch (error) { + case 0: + break; + case GLR_TRYFAILED: + return 1; + default: + return error; + } + + /* Unlock here to prevent deadlock */ + gfs_glock_dq(&io_gh); + + /* No other process in the entire cluster has this inode open; + we can remove it and all of its associated blocks from disk */ + error = inode_dealloc(sdp, inum, &io_gh); + gfs_holder_uninit(&io_gh); + + return error; +} + +/** + * inode_dealloc_uninit - dealloc an uninitialized on-disk inode (dinode) block + * @sdp: the filesystem + * + * Create a transaction to change dinode block's alloc state to FREEMETA + * + * Returns: 0 on success, -errno on error, 1 on busy + */ + +static int +inode_dealloc_uninit(struct gfs_sbd *sdp, struct gfs_inum *inum) +{ + struct gfs_rgrpd *rgd; + struct gfs_holder ri_gh, rgd_gh; + int error; + + error = gfs_rindex_hold(sdp, &ri_gh); + if (error) + return error; + + rgd = gfs_blk2rgrpd(sdp, inum->no_addr); + if (!rgd) { + gfs_consist(sdp); + error = -EIO; + goto fail; + } + + error = gfs_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &rgd_gh); + if (error) + goto fail; + + /* Trans may require: + One block for the RG header. + One block for the dinode bit. + We also need a block for the unlinked change. */ + + error = gfs_trans_begin(sdp, 2, 1); + if (error) + goto fail_gunlock; + + gfs_difree_uninit(rgd, inum->no_addr); + gfs_trans_add_unlinked(sdp, GFS_LOG_DESC_IDA, inum); + + gfs_trans_end(sdp); + + gfs_glock_dq_uninit(&rgd_gh); + gfs_glock_dq_uninit(&ri_gh); + + return 0; + + fail_gunlock: + gfs_glock_dq_uninit(&rgd_gh); + + fail: + gfs_glock_dq_uninit(&ri_gh); + + return error; +} + +/** + * gfs_inode_dealloc - Grab an unlinked inode off the list and try to free it. + * @sdp: the filesystem + * + * Returns: 0 on success, -errno on error, 1 on busy + */ + +int +gfs_inode_dealloc(struct gfs_sbd *sdp, struct gfs_inum *inum) +{ + if (inum->no_formal_ino) + return inode_dealloc_init(sdp, inum); + else + return inode_dealloc_uninit(sdp, inum); +} + +/** + * gfs_change_nlink - Change nlink count on inode + * @ip: The GFS inode + * @diff: The change in the nlink count required + * + * Returns: errno + */ + +int +gfs_change_nlink(struct gfs_inode *ip, int diff) +{ + struct buffer_head *dibh; + uint32_t nlink; + int error; + + nlink = ip->i_di.di_nlink + diff; + + /* Tricky. If we are reducing the nlink count, + but the new value ends up being bigger than the + old one, we must have underflowed. */ + if (diff < 0 && nlink > ip->i_di.di_nlink) { + if (gfs_consist_inode(ip)) + gfs_dinode_print(&ip->i_di); + return -EIO; + } + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + return error; + + ip->i_di.di_nlink = nlink; + ip->i_di.di_ctime = get_seconds(); + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + + return 0; +} + +/** + * gfs_lookupi - Look up a filename in a directory and return its inode + * @d_gh: An initialized holder for the directory glock + * @name: The name of the inode to look for + * @is_root: If TRUE, ignore the caller's permissions + * @i_gh: An uninitialized holder for the new inode glock + * + * There will always be a vnode (Linux VFS inode) for the d_gh inode unless + * @is_root is true. + * + * Returns: errno + */ + +int +gfs_lookupi(struct gfs_holder *d_gh, struct qstr *name, + int is_root, struct gfs_holder *i_gh) +{ + struct gfs_inode *dip = get_gl2ip(d_gh->gh_gl); + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_glock *gl; + struct gfs_inode *ip; + struct gfs_inum inum, inum2; + unsigned int type; + int error; + + i_gh->gh_gl = NULL; + + if (!name->len || name->len > GFS_FNAMESIZE) + return -ENAMETOOLONG; + + if (gfs_filecmp(name, ".", 1) || + (gfs_filecmp(name, "..", 2) && dip == sdp->sd_rooti)) { + gfs_holder_reinit(LM_ST_SHARED, 0, d_gh); + error = gfs_glock_nq(d_gh); + if (!error) { + error = gfs_glock_nq_init(dip->i_gl, + LM_ST_SHARED, 0, + i_gh); + if (error) { + gfs_glock_dq(d_gh); + return error; + } + gfs_inode_hold(dip); + } + return error; + } + + if (gfs_assert_warn(sdp, !gfs_glock_is_locked_by_me(d_gh->gh_gl))) + return -EINVAL; + + gfs_holder_reinit(LM_ST_SHARED, 0, d_gh); + error = gfs_glock_nq(d_gh); + if (error) + return error; + + if (!is_root) { + error = inode_permission(dip->i_vnode, MAY_EXEC); + if (error) { + gfs_glock_dq(d_gh); + return error; + } + } + + error = gfs_dir_search(dip, name, &inum, &type); + if (error) { + gfs_glock_dq(d_gh); + if (error == -ENOENT) + error = 0; + return error; + } + + restart: + error = gfs_glock_get(sdp, inum.no_formal_ino, &gfs_inode_glops, + CREATE, &gl); + if (error) { + gfs_glock_dq(d_gh); + return error; + } + + /* Acquire the second lock */ + + if (gl->gl_name.ln_number < dip->i_gl->gl_name.ln_number) { + gfs_glock_dq(d_gh); + + error = gfs_glock_nq_init(gl, LM_ST_SHARED, + LM_FLAG_ANY | GL_LOCAL_EXCL, + i_gh); + if (error) + goto out; + + gfs_holder_reinit(LM_ST_SHARED, 0, d_gh); + error = gfs_glock_nq(d_gh); + if (error) { + gfs_glock_dq_uninit(i_gh); + goto out; + } + + if (!is_root) { + error = inode_permission(dip->i_vnode, MAY_EXEC); + if (error) { + gfs_glock_dq(d_gh); + gfs_glock_dq_uninit(i_gh); + goto out; + } + } + + error = gfs_dir_search(dip, name, &inum2, &type); + if (error) { + gfs_glock_dq(d_gh); + gfs_glock_dq_uninit(i_gh); + if (error == -ENOENT) + error = 0; + goto out; + } + + if (!gfs_inum_equal(&inum, &inum2)) { + gfs_glock_dq_uninit(i_gh); + gfs_glock_put(gl); + inum = inum2; + goto restart; + } + } else { + error = gfs_glock_nq_init(gl, LM_ST_SHARED, + LM_FLAG_ANY | GL_LOCAL_EXCL, + i_gh); + if (error) { + gfs_glock_dq(d_gh); + goto out; + } + } + + error = gfs_inode_get(gl, &inum, CREATE, &ip); + if (error) { + gfs_glock_dq(d_gh); + gfs_glock_dq_uninit(i_gh); + } else if (ip->i_di.di_type != type) { + gfs_consist_inode(dip); + gfs_inode_put(ip); + gfs_glock_dq(d_gh); + gfs_glock_dq_uninit(i_gh); + error = -EIO; + } + + out: + gfs_glock_put(gl); + + return error; +} + +/** + * create_ok - OK to create a new on-disk inode here? + * @dip: Directory in which dinode is to be created + * @name: Name of new dinode + * @type: GFS_FILE_XXX (regular file, dir, etc.) + * + * Returns: errno + */ + +static int +create_ok(struct gfs_inode *dip, struct qstr *name, unsigned int type) +{ + int error; + + error = inode_permission(dip->i_vnode, MAY_WRITE | MAY_EXEC); + if (error) + return error; + + /* Don't create entries in an unlinked directory */ + + if (!dip->i_di.di_nlink) + return -EPERM; + + error = gfs_dir_search(dip, name, NULL, NULL); + switch (error) { + case -ENOENT: + error = 0; + break; + case 0: + return -EEXIST; + default: + return error; + } + + if (dip->i_di.di_entries == (uint32_t)-1) + return -EFBIG; + if (type == GFS_FILE_DIR && dip->i_di.di_nlink == (uint32_t)-1) + return -EMLINK; + + return 0; +} + +/** + * dinode_alloc - Create an on-disk inode + * @dip: Directory in which to create the dinode + * @ul: + * + * Since this dinode is not yet linked, we also create an unlinked inode + * descriptor. + * + * Returns: errno + */ + +static int +dinode_alloc(struct gfs_inode *dip, struct gfs_unlinked **ul) +{ + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_alloc *al; + struct gfs_inum inum; + int error; + + /* Create in-place allocation structure, reserve 1 dinode */ + al = gfs_alloc_get(dip); + al->al_requested_di = 1; + error = gfs_inplace_reserve(dip); + if (error) + goto out; + + error = gfs_trans_begin(sdp, al->al_rgd->rd_ri.ri_length, 1); + if (error) + goto out_inplace; + + inum.no_formal_ino = 0; + error = gfs_dialloc(dip, &inum.no_addr); + if (error) + goto out_end_trans; + + *ul = gfs_trans_add_unlinked(sdp, GFS_LOG_DESC_IUL, &inum); + gfs_unlinked_lock(sdp, *ul); + + gfs_trans_add_gl(dip->i_gl); + + out_end_trans: + gfs_trans_end(sdp); + + out_inplace: + gfs_inplace_release(dip); + + out: + gfs_alloc_put(dip); + + return error; +} + +/** + * pick_formal_ino - Pick a formal inode number for a given inode + * @sdp: the filesystem + * @inum: the inode number structure + * + */ + +static void +pick_formal_ino(struct gfs_sbd *sdp, struct gfs_inum *inum) +{ + /* This won't always be true */ + inum->no_formal_ino = inum->no_addr; +} + +/** + * make_dinode - Fill in a new dinode structure + * @dip: the directory this inode is being created in + * @gl: The glock covering the new inode + * @inum: the inode number + * @type: the file type + * @mode: the file permissions + * @uid: + * @gid: + * + */ + +static int +make_dinode(struct gfs_inode *dip, + struct gfs_glock *gl, struct gfs_inum *inum, + unsigned int type, unsigned int mode, + unsigned int uid, unsigned int gid) +{ + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_dinode di; + struct buffer_head *dibh; + struct gfs_rgrpd *rgd; + int error; + + error = gfs_dread(gl, inum->no_addr, + DIO_NEW | DIO_START | DIO_WAIT, + &dibh); + if (error) + return error; + + gfs_trans_add_bh(gl, dibh); + gfs_metatype_set(dibh, GFS_METATYPE_DI, GFS_FORMAT_DI); + gfs_buffer_clear_tail(dibh, sizeof(struct gfs_dinode)); + + memset(&di, 0, sizeof(struct gfs_dinode)); + + gfs_meta_header_in(&di.di_header, dibh->b_data); + + di.di_num = *inum; + + di.di_mode = mode & S_IALLUGO; + di.di_uid = uid; + di.di_gid = gid; + di.di_nlink = 1; + di.di_blocks = 1; + di.di_atime = di.di_mtime = di.di_ctime = get_seconds(); + + rgd = gfs_blk2rgrpd(sdp, inum->no_addr); + if (!rgd) { + if (gfs_consist(sdp)) + printk("GFS: fsid=%s: block = %"PRIu64"\n", + sdp->sd_fsname, inum->no_addr); + brelse(dibh); + return -EIO; + } + + di.di_rgrp = rgd->rd_ri.ri_addr; + di.di_goal_rgrp = di.di_rgrp; + di.di_goal_dblk = di.di_goal_mblk = inum->no_addr - rgd->rd_ri.ri_data1; + + if (type == GFS_FILE_REG) { + if ((dip->i_di.di_flags & GFS_DIF_INHERIT_JDATA) || + gfs_tune_get(sdp, gt_new_files_jdata)) + di.di_flags |= GFS_DIF_JDATA; + if ((dip->i_di.di_flags & GFS_DIF_INHERIT_DIRECTIO) || + gfs_tune_get(sdp, gt_new_files_directio)) + di.di_flags |= GFS_DIF_DIRECTIO; + } else if (type == GFS_FILE_DIR) { + di.di_flags |= (dip->i_di.di_flags & GFS_DIF_INHERIT_DIRECTIO); + di.di_flags |= (dip->i_di.di_flags & GFS_DIF_INHERIT_JDATA); + } + + di.di_type = type; + + gfs_dinode_out(&di, dibh->b_data); + brelse(dibh); + + return 0; +} + +/** + * inode_init_and_link - + * @dip: + * @name: + * @inum: + * @gl: + * @type: + * @mode: + * + * Returns: errno + */ + +static int +inode_init_and_link(struct gfs_inode *dip, struct qstr *name, + struct gfs_inum *inum, struct gfs_glock *gl, + unsigned int type, mode_t mode) +{ + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_alloc *al; + struct gfs_inode *ip; + unsigned int uid, gid; + int alloc_required; + void *acl_a_data = NULL, *acl_d_data = NULL; + unsigned int acl_size = 0, acl_blocks = 0; + int error; + + if (sdp->sd_args.ar_suiddir && + (dip->i_di.di_mode & S_ISUID) && + dip->i_di.di_uid) { + if (type == GFS_FILE_DIR) + mode |= S_ISUID; + else if (dip->i_di.di_uid != current->fsuid) + mode &= ~07111; + uid = dip->i_di.di_uid; + } else + uid = current->fsuid; + + if (dip->i_di.di_mode & S_ISGID) { + if (type == GFS_FILE_DIR) + mode |= S_ISGID; + gid = dip->i_di.di_gid; + } else + gid = current->fsgid; + + error = gfs_acl_new_prep(dip, type, &mode, + &acl_a_data, &acl_d_data, + &acl_size, &acl_blocks); + if (error) + return error; + + al = gfs_alloc_get(dip); + + error = gfs_quota_lock_m(dip, uid, gid); + if (error) + goto fail; + + error = gfs_quota_check(dip, uid, gid); + if (error) + goto fail_gunlock_q; + + if (acl_blocks) + alloc_required = TRUE; + else { + error = gfs_diradd_alloc_required(dip, name, &alloc_required); + if (error) + goto fail_gunlock_q; + } + + if (alloc_required) { + error = gfs_quota_check(dip, dip->i_di.di_uid, dip->i_di.di_gid); + if (error) + goto fail_gunlock_q; + + al->al_requested_meta = sdp->sd_max_dirres + acl_blocks; + + error = gfs_inplace_reserve(dip); + if (error) + goto fail_gunlock_q; + + /* Trans may require: + blocks for two dinodes, the directory blocks necessary for + a new entry, RG bitmap blocks for an allocation, + and one block for a quota change and + one block for an unlinked tag. */ + + error = gfs_trans_begin(sdp, + 2 + sdp->sd_max_dirres + acl_blocks + + al->al_rgd->rd_ri.ri_length, 2); + if (error) + goto fail_inplace; + } else { + error = gfs_rindex_hold(sdp, &al->al_ri_gh); + if (error) + goto fail_gunlock_q; + + /* Trans may require: + blocks for two dinodes, a leaf block, + and one block for a quota change and + one block for an unlinked tag. */ + + error = gfs_trans_begin(sdp, 3, 2); + if (error) + goto fail_inplace; + } + + error = gfs_dir_add(dip, name, inum, type); + if (error) + goto fail_end_trans; + + error = make_dinode(dip, gl, inum, type, mode, uid, gid); + if (error) + goto fail_end_trans; + + al->al_ul = gfs_trans_add_unlinked(sdp, GFS_LOG_DESC_IDA, + &(struct gfs_inum){0, inum->no_addr}); + gfs_trans_add_quota(sdp, +1, uid, gid); + + error = gfs_inode_get(gl, inum, CREATE, &ip); + + /* This should only fail if we are already shutdown. */ + if (gfs_assert_withdraw(sdp, !error)) + goto fail_end_trans; + + if (acl_blocks) + error = gfs_acl_new_init(dip, ip, + acl_a_data, acl_d_data, + acl_size); + + if (!alloc_required) + gfs_glock_dq_uninit(&al->al_ri_gh); + + return error; + + fail_end_trans: + gfs_trans_end(sdp); + + fail_inplace: + if (alloc_required) + gfs_inplace_release(dip); + else + gfs_glock_dq_uninit(&al->al_ri_gh); + + fail_gunlock_q: + gfs_quota_unlock_m(dip); + + fail: + gfs_alloc_put(dip); + if (acl_a_data) + kfree(acl_a_data); + else if (acl_d_data) + kfree(acl_d_data); + + return error; +} + +/** + * gfs_createi - Create a new inode + * @d_gh: An initialized holder for the directory glock + * @name: The name of the new file + * @type: The type of dinode (GFS_FILE_REG, GFS_FILE_DIR, GFS_FILE_LNK, ...) + * @mode: the permissions on the new inode + * @i_gh: An uninitialized holder for the new inode glock + * + * If the return value is 0, the glocks on both the directory and the new + * file are held. A transaction has been started and an inplace reservation + * is held, as well. + * + * Returns: errno + */ + +int +gfs_createi(struct gfs_holder *d_gh, struct qstr *name, + unsigned int type, unsigned int mode, + struct gfs_holder *i_gh) +{ + struct gfs_inode *dip = get_gl2ip(d_gh->gh_gl); + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_unlinked *ul; + struct gfs_inum inum; + struct gfs_holder io_gh; + int error; + + if (!name->len || name->len > GFS_FNAMESIZE) + return -ENAMETOOLONG; + + gfs_holder_reinit(LM_ST_EXCLUSIVE, 0, d_gh); + error = gfs_glock_nq(d_gh); + if (error) + return error; + + error = create_ok(dip, name, type); + if (error) + goto fail; + + error = dinode_alloc(dip, &ul); + if (error) + goto fail; + + inum.no_addr = ul->ul_inum.no_addr; + pick_formal_ino(sdp, &inum); + + if (inum.no_formal_ino < dip->i_num.no_formal_ino) { + gfs_glock_dq(d_gh); + + error = gfs_glock_nq_num(sdp, + inum.no_formal_ino, &gfs_inode_glops, + LM_ST_EXCLUSIVE, GL_SKIP, i_gh); + if (error) { + gfs_unlinked_unlock(sdp, ul); + return error; + } + + gfs_holder_reinit(LM_ST_EXCLUSIVE, 0, d_gh); + error = gfs_glock_nq(d_gh); + if (error) { + gfs_glock_dq_uninit(i_gh); + gfs_unlinked_unlock(sdp, ul); + return error; + } + + error = create_ok(dip, name, type); + if (error) + goto fail_gunlock_i; + } else { + error = gfs_glock_nq_num(sdp, + inum.no_formal_ino, &gfs_inode_glops, + LM_ST_EXCLUSIVE, GL_SKIP, i_gh); + if (error) + goto fail_ul; + } + + error = gfs_glock_nq_num(sdp, + inum.no_addr, &gfs_iopen_glops, + LM_ST_SHARED, GL_LOCAL_EXCL | GL_EXACT, + &io_gh); + if (error) + goto fail_gunlock_i; + + error = inode_init_and_link(dip, name, &inum, i_gh->gh_gl, type, mode); + if (error) + goto fail_gunlock_io; + + gfs_glock_dq_uninit(&io_gh); + + return 0; + + fail_gunlock_io: + gfs_glock_dq_uninit(&io_gh); + + fail_gunlock_i: + gfs_glock_dq_uninit(i_gh); + + fail_ul: + gfs_unlinked_unlock(sdp, ul); + + fail: + gfs_glock_dq(d_gh); + + return error; +} + +/** + * gfs_unlinki - Unlink a file + * @dip: The inode of the directory + * @name: The name of the file to be unlinked + * @ip: The inode of the file to be removed + * + * Assumes Glocks on both dip and ip are held. + * + * Returns: errno + */ + +int +gfs_unlinki(struct gfs_inode *dip, struct qstr *name, struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = dip->i_sbd; + int error; + + error = gfs_dir_del(dip, name); + if (error) + return error; + + error = gfs_change_nlink(ip, -1); + if (error) + return error; + + /* If this inode is being unlinked from the directory structure, + we need to mark that in the log so that it isn't lost during + a crash. */ + + if (!ip->i_di.di_nlink) { + gfs_trans_add_unlinked(sdp, GFS_LOG_DESC_IUL, &ip->i_num); + set_bit(GLF_STICKY, &ip->i_gl->gl_flags); + } + + return 0; +} + +/** + * gfs_rmdiri - Remove a directory + * @dip: The parent directory of the directory to be removed + * @name: The name of the directory to be removed + * @ip: The GFS inode of the directory to be removed + * + * Assumes Glocks on dip and ip are held + * + * Returns: errno + */ + +int +gfs_rmdiri(struct gfs_inode *dip, struct qstr *name, struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = dip->i_sbd; + struct qstr dotname; + int error; + + if (ip->i_di.di_entries != 2) { + if (gfs_consist_inode(ip)) + gfs_dinode_print(&ip->i_di); + return -EIO; + } + + error = gfs_dir_del(dip, name); + if (error) + return error; + + error = gfs_change_nlink(dip, -1); + if (error) + return error; + + dotname.len = 1; + dotname.name = "."; + error = gfs_dir_del(ip, &dotname); + if (error) + return error; + + dotname.len = 2; + dotname.name = ".."; + error = gfs_dir_del(ip, &dotname); + if (error) + return error; + + error = gfs_change_nlink(ip, -2); + if (error) + return error; + + /* This inode is being unlinked from the directory structure and + we need to mark that in the log so that it isn't lost during + a crash. */ + + gfs_trans_add_unlinked(sdp, GFS_LOG_DESC_IUL, &ip->i_num); + set_bit(GLF_STICKY, &ip->i_gl->gl_flags); + + return 0; +} + +/* + * gfs_unlink_ok - check to see that a inode is still in a directory + * @dip: the directory + * @name: the name of the file + * @ip: the inode + * + * Assumes that the lock on (at least) @dip is held. + * + * Returns: 0 if the parent/child relationship is correct, errno if it isn't + */ + +int +gfs_unlink_ok(struct gfs_inode *dip, struct qstr *name, struct gfs_inode *ip) +{ + struct gfs_inum inum; + unsigned int type; + int error; + + if (IS_IMMUTABLE(ip->i_vnode) || IS_APPEND(ip->i_vnode)) + return -EPERM; + + if ((dip->i_di.di_mode & S_ISVTX) && + dip->i_di.di_uid != current->fsuid && + ip->i_di.di_uid != current->fsuid && + !capable(CAP_FOWNER)) + return -EPERM; + + if (IS_APPEND(dip->i_vnode)) + return -EPERM; + + error = inode_permission(dip->i_vnode, MAY_WRITE | MAY_EXEC); + if (error) + return error; + + error = gfs_dir_search(dip, name, &inum, &type); + if (error) + return error; + + if (inum.no_formal_ino != ip->i_num.no_formal_ino) + return -ENOENT; + + if (ip->i_di.di_type != type) { + gfs_consist_inode(dip); + return -EIO; + } + + return 0; +} + +/* + * gfs_ok_to_move - check if it's ok to move a directory to another directory + * @this: move this + * @to: to here + * + * Follow @to back to the root and make sure we don't encounter @this + * Assumes we already hold the rename lock. + * + * Returns: errno + */ + +int +gfs_ok_to_move(struct gfs_inode *this, struct gfs_inode *to) +{ + struct gfs_sbd *sdp = this->i_sbd; + struct gfs_inode *tmp; + struct gfs_holder to_gh, tmp_gh; + struct qstr dotdot; + int error = 0; + + memset(&dotdot, 0, sizeof (struct qstr)); + dotdot.name = ".."; + dotdot.len = 2; + + gfs_inode_hold(to); + + for (;;) { + if (to == this) { + error = -EINVAL; + break; + } + if (to == sdp->sd_rooti) { + error = 0; + break; + } + + gfs_holder_init(to->i_gl, 0, 0, &to_gh); + + error = gfs_lookupi(&to_gh, &dotdot, TRUE, &tmp_gh); + if (error) { + gfs_holder_uninit(&to_gh); + break; + } + if (!tmp_gh.gh_gl) { + gfs_holder_uninit(&to_gh); + error = -ENOENT; + break; + } + + tmp = get_gl2ip(tmp_gh.gh_gl); + + gfs_glock_dq_uninit(&to_gh); + gfs_glock_dq_uninit(&tmp_gh); + + gfs_inode_put(to); + to = tmp; + } + + gfs_inode_put(to); + + return error; +} + +/** + * gfs_readlinki - return the contents of a symlink + * @ip: the symlink's inode + * @buf: a pointer to the buffer to be filled + * @len: a pointer to the length of @buf + * + * If @buf is too small, a piece of memory is kmalloc()ed and needs + * to be freed by the caller. + * + * Returns: errno + */ + +int +gfs_readlinki(struct gfs_inode *ip, char **buf, unsigned int *len) +{ + struct gfs_holder i_gh; + struct buffer_head *dibh; + unsigned int x; + int error; + + gfs_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &i_gh); + error = gfs_glock_nq_atime(&i_gh); + if (error) { + gfs_holder_uninit(&i_gh); + return error; + } + + if (!ip->i_di.di_size) { + gfs_consist_inode(ip); + error = -EIO; + goto out; + } + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto out; + + x = ip->i_di.di_size + 1; + if (x > *len) { + *buf = kmalloc(x, GFP_KERNEL); + if (!*buf) { + error = -ENOMEM; + goto out_brelse; + } + } + + memcpy(*buf, dibh->b_data + sizeof(struct gfs_dinode), x); + *len = x; + + out_brelse: + brelse(dibh); + + out: + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gfs_glock_nq_atime - Acquire a hold on an inode's glock, and + * conditionally update the inode's atime + * @gh: the holder to acquire + * + * Tests atime (access time) for gfs_read, gfs_readdir and gfs_mmap + * Update if the difference between the current time and the inode's current + * atime is greater than an interval specified at mount (or default). + * + * Will not update if GFS mounted NOATIME (this is *the* place where NOATIME + * has an effect) or Read-Only. + * + * Returns: errno + */ + +int +gfs_glock_nq_atime(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_inode *ip = get_gl2ip(gl); + int64_t curtime, quantum = gfs_tune_get(sdp, gt_atime_quantum); + unsigned int state; + int flags; + int error; + + if (gfs_assert_warn(sdp, gh->gh_flags & GL_ATIME) || + gfs_assert_warn(sdp, !(gh->gh_flags & GL_ASYNC)) || + gfs_assert_warn(sdp, gl->gl_ops == &gfs_inode_glops)) + return -EINVAL; + + /* Save original request state of lock holder */ + state = gh->gh_state; + flags = gh->gh_flags; + + error = gfs_glock_nq(gh); + if (error) + return error; + + if (test_bit(SDF_NOATIME, &sdp->sd_flags) || + test_bit(SDF_ROFS, &sdp->sd_flags)) + return 0; + + curtime = get_seconds(); + if (curtime - ip->i_di.di_atime >= quantum) { + /* Get EX hold (force EX glock via !ANY) to write the dinode */ + gfs_glock_dq(gh); + gfs_holder_reinit(LM_ST_EXCLUSIVE, + gh->gh_flags & ~LM_FLAG_ANY, + gh); + error = gfs_glock_nq(gh); + if (error) + return error; + + /* Verify that atime hasn't been updated while we were + trying to get exclusive lock. */ + + curtime = get_seconds(); + if (curtime - ip->i_di.di_atime >= quantum) { + struct buffer_head *dibh; + + error = gfs_trans_begin(sdp, 1, 0); + if (error == -EROFS) + return 0; + if (error) + goto fail; + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto fail_end_trans; + + ip->i_di.di_atime = curtime; + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + + gfs_trans_end(sdp); + } + + /* If someone else has asked for the glock, + unlock and let them have it. Then reacquire + in the original state. */ + if (gfs_glock_is_blocking(gl)) { + gfs_glock_dq(gh); + gfs_holder_reinit(state, flags, gh); + return gfs_glock_nq(gh); + } + } + + return 0; + + fail_end_trans: + gfs_trans_end(sdp); + + fail: + gfs_glock_dq(gh); + + return error; +} + +/** + * glock_compare_atime - Compare two struct gfs_glock structures for gfs_sort() + * @arg_a: the first structure + * @arg_b: the second structure + * + * Sort order determined by (in order of priority): + * -- lock number + * -- lock state (SHARED > EXCLUSIVE or GL_ATIME, which can demand EXCLUSIVE) + * + * Returns: 1 if A > B + * -1 if A < B + * 0 if A = B + */ + +static int +glock_compare_atime(const void *arg_a, const void *arg_b) +{ + struct gfs_holder *gh_a = *(struct gfs_holder **)arg_a; + struct gfs_holder *gh_b = *(struct gfs_holder **)arg_b; + struct lm_lockname *a = &gh_a->gh_gl->gl_name; + struct lm_lockname *b = &gh_b->gh_gl->gl_name; + int ret = 0; + + if (a->ln_number > b->ln_number) + ret = 1; + else if (a->ln_number < b->ln_number) + ret = -1; + else { + if (gh_a->gh_state == LM_ST_SHARED && + gh_b->gh_state == LM_ST_EXCLUSIVE) + ret = 1; + else if (gh_a->gh_state == LM_ST_SHARED && + (gh_b->gh_flags & GL_ATIME)) + ret = 1; + } + + return ret; +} + +/** + * gfs_glock_nq_m_atime - acquire multiple glocks where one may need an + * atime update + * @num_gh: the number of structures + * @ghs: an array of struct gfs_holder structures + * + * Returns: 0 on success (all glocks acquired), + * errno on failure (no glocks acquired) + */ + +int +gfs_glock_nq_m_atime(unsigned int num_gh, struct gfs_holder *ghs) +{ + struct gfs_holder **p; + unsigned int x; + int error = 0; + + if (!num_gh) + return 0; + + if (num_gh == 1) { + ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); + if (ghs->gh_flags & GL_ATIME) + error = gfs_glock_nq_atime(ghs); + else + error = gfs_glock_nq(ghs); + return error; + } + + p = kmalloc(num_gh * sizeof(struct gfs_holder *), GFP_KERNEL); + if (!p) + return -ENOMEM; + + for (x = 0; x < num_gh; x++) + p[x] = &ghs[x]; + + gfs_sort(p, num_gh, sizeof(struct gfs_holder *), glock_compare_atime); + + for (x = 0; x < num_gh; x++) { + p[x]->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); + + if (p[x]->gh_flags & GL_ATIME) + error = gfs_glock_nq_atime(p[x]); + else + error = gfs_glock_nq(p[x]); + + if (error) { + while (x--) + gfs_glock_dq(p[x]); + break; + } + } + + kfree(p); + return error; +} + +/** + * gfs_try_toss_vnode - See if we can toss a vnode from memory + * @ip: the inode + * + * Returns: TRUE if the vnode was tossed + */ + +void +gfs_try_toss_vnode(struct gfs_inode *ip) +{ + struct inode *inode; + + inode = gfs_iget(ip, NO_CREATE); + if (!inode) + return; + + d_prune_aliases(inode); + + if (ip->i_di.di_type == GFS_FILE_DIR) { + struct list_head *head = &inode->i_dentry; + struct dentry *d = NULL; + + spin_lock(&dcache_lock); + if (list_empty(head)) + spin_unlock(&dcache_lock); + else { + d = list_entry(head->next, struct dentry, d_alias); + dget_locked(d); + spin_unlock(&dcache_lock); + + if (have_submounts(d)) + dput(d); + else { + shrink_dcache_parent(d); + dput(d); + d_prune_aliases(inode); + } + } + } + + inode->i_nlink = 0; + iput(inode); +} + + +static int +__gfs_setattr_simple(struct gfs_inode *ip, struct iattr *attr) +{ + struct buffer_head *dibh; + int error; + + error = gfs_get_inode_buffer(ip, &dibh); + if (!error) { + error = inode_setattr(ip->i_vnode, attr); + gfs_assert_warn(ip->i_sbd, !error); + gfs_inode_attr_out(ip); + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + + return error; +} + +/** + * gfs_setattr_simple - + * @ip: + * @attr: + * + * Called with a reference on the vnode. + * + * Returns: errno + */ + +int +gfs_setattr_simple(struct gfs_inode *ip, struct iattr *attr) +{ + int error; + + if (get_transaction) + return __gfs_setattr_simple(ip, attr); + + /* Trans may require: + one dinode block. */ + + error = gfs_trans_begin(ip->i_sbd, 1, 0); + if (error) + return error; + + error = __gfs_setattr_simple(ip, attr); + + gfs_trans_end(ip->i_sbd); + + return error; +} + +/** + * iah_make_jdata - + * @gl: + * @inum: + * + */ + +static void +iah_make_jdata(struct gfs_glock *gl, struct gfs_inum *inum) +{ + struct buffer_head *bh; + struct gfs_dinode *di; + uint32_t flags; + int error; + + error = gfs_dread(gl, inum->no_addr, DIO_START | DIO_WAIT, &bh); + + /* This should only fail if we are already shutdown. */ + if (gfs_assert_withdraw(gl->gl_sbd, !error)) + return; + + di = (struct gfs_dinode *)bh->b_data; + + flags = di->di_flags; + flags = gfs32_to_cpu(flags) | GFS_DIF_JDATA; + di->di_flags = cpu_to_gfs32(flags); + + brelse(bh); +} + +/** + * iah_super_update - Write superblock to disk + * @sdp: filesystem instance structure + * + * Returns: errno + * + * Update on-disk superblock, using (modified) data in sdp->sd_sb + */ + +static int +iah_super_update(struct gfs_sbd *sdp) +{ + struct gfs_glock *gl; + struct buffer_head *bh; + int error; + + error = gfs_glock_get(sdp, + GFS_SB_LOCK, &gfs_meta_glops, + NO_CREATE, &gl); + if (gfs_assert_withdraw(sdp, !error && gl)) /* This should already be held. */ + return -EINVAL; + + error = gfs_dread(gl, GFS_SB_ADDR >> sdp->sd_fsb2bb_shift, + DIO_START | DIO_WAIT, &bh); + if (!error) { + gfs_trans_add_bh(gl, bh); + gfs_sb_out(&sdp->sd_sb, bh->b_data); + brelse(bh); + } + + gfs_glock_put(gl); + + return error; +} + +/** + * inode_alloc_hidden - allocate on-disk inode for a special (hidden) file + * @sdp: the filesystem instance structure + * @inum: new dinode's block # and formal inode #, to be filled + * in by this function. + * + * Returns: errno + * + * This function is called only very rarely, when the first-to-mount + * node can't find a pre-existing special file (e.g. license or quota file) that + * it expects to find. This should happen only when upgrading from an older + * version of the filesystem. + * + * The @inum must be a member of sdp->sd_sb in order to get updated to on-disk + * superblock properly. + */ + +static int +inode_alloc_hidden(struct gfs_sbd *sdp, struct gfs_inum *inum) +{ + struct gfs_inode *dip = sdp->sd_rooti; + struct gfs_holder d_gh, i_gh; + struct gfs_unlinked *ul; + int error; + + error = gfs_glock_nq_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, &d_gh); + if (error) + return error; + + error = dinode_alloc(dip, &ul); + if (error) + goto fail; + + inum->no_addr = ul->ul_inum.no_addr; + pick_formal_ino(sdp, inum); + + /* Don't worry about deadlock ordering here. We're the first + mounter and still under the mount lock (i.e. there is no + contention). */ + + error = gfs_glock_nq_num(sdp, + inum->no_formal_ino, &gfs_inode_glops, + LM_ST_EXCLUSIVE, GL_SKIP, &i_gh); + if (error) + goto fail_ul; + + gfs_alloc_get(dip); + + error = gfs_quota_hold_m(dip, 0, 0); + if (error) + goto fail_al; + + /* Trans may require: + The new inode, the superblock, + and one block for a quota change and + one block for an unlinked tag. */ + + error = gfs_trans_begin(sdp, 2, 2); + if (error) + goto fail_unhold; + + error = make_dinode(dip, i_gh.gh_gl, inum, GFS_FILE_REG, 0600, 0, 0); + if (error) + goto fail_end_trans; + + /* Hidden files get all of their data (not just metadata) journaled */ + iah_make_jdata(i_gh.gh_gl, inum); + + error = iah_super_update(sdp); + if (error) + goto fail_end_trans; + + gfs_trans_add_unlinked(sdp, GFS_LOG_DESC_IDA, + &(struct gfs_inum){0, inum->no_addr}); + gfs_trans_add_quota(sdp, +1, 0, 0); + gfs_trans_add_gl(dip->i_gl); + + gfs_trans_end(sdp); + gfs_quota_unhold_m(dip); + gfs_alloc_put(dip); + + gfs_glock_dq_uninit(&i_gh); + gfs_glock_dq_uninit(&d_gh); + + gfs_unlinked_unlock(sdp, ul); + + gfs_log_flush(sdp); + + return 0; + + fail_end_trans: + gfs_trans_end(sdp); + + fail_unhold: + gfs_quota_unhold_m(dip); + + fail_al: + gfs_alloc_put(dip); + gfs_glock_dq_uninit(&i_gh); + + fail_ul: + gfs_unlinked_unlock(sdp, ul); + + fail: + gfs_glock_dq_uninit(&d_gh); + + return error; +} + +/** + * gfs_alloc_qinode - allocate a quota inode + * @sdp: The GFS superblock + * + * Returns: 0 on success, error code otherwise + */ + +int +gfs_alloc_qinode(struct gfs_sbd *sdp) +{ + return inode_alloc_hidden(sdp, &sdp->sd_sb.sb_quota_di); +} + +/** + * gfs_alloc_linode - allocate a license inode + * @sdp: The GFS superblock + * + * Returns: 0 on success, error code otherwise + */ + +int +gfs_alloc_linode(struct gfs_sbd *sdp) +{ + return inode_alloc_hidden(sdp, &sdp->sd_sb.sb_license_di); +} --- linux-2.6.28.orig/ubuntu/gfs/page.c +++ linux-2.6.28/ubuntu/gfs/page.c @@ -0,0 +1,266 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "bmap.h" +#include "inode.h" +#include "page.h" + +/** + * gfs_inval_pte - Sync and invalidate all PTEs associated with a glock + * @gl: the glock + * + */ + +void +gfs_inval_pte(struct gfs_glock *gl) +{ + struct gfs_inode *ip; + struct inode *inode; + + ip = get_gl2ip(gl); + if (!ip || + ip->i_di.di_type != GFS_FILE_REG) + return; + + if (!test_bit(GIF_PAGED, &ip->i_flags)) + return; + + inode = gfs_iget(ip, NO_CREATE); + if (inode) { + unmap_shared_mapping_range(inode->i_mapping, 0, 0); + iput(inode); + + if (test_bit(GIF_SW_PAGED, &ip->i_flags)) + set_bit(GLF_DIRTY, &gl->gl_flags); + } + + clear_bit(GIF_SW_PAGED, &ip->i_flags); +} + +/** + * gfs_inval_page - Invalidate all pages associated with a glock + * @gl: the glock + * + */ + +void +gfs_inval_page(struct gfs_glock *gl) +{ + struct gfs_inode *ip; + struct inode *inode; + + ip = get_gl2ip(gl); + if (!ip || + ip->i_di.di_type != GFS_FILE_REG) + return; + + inode = gfs_iget(ip, NO_CREATE); + if (inode) { + struct address_space *mapping = inode->i_mapping; + + truncate_inode_pages(mapping, 0); + gfs_assert_withdraw(ip->i_sbd, !mapping->nrpages); + + iput(inode); + } + + clear_bit(GIF_PAGED, &ip->i_flags); +} + +/** + * gfs_sync_page_i - Sync the data pages (not metadata) for a struct inode + * @inode: the inode + * @flags: DIO_START | DIO_WAIT + * + */ + +void +gfs_sync_page_i(struct inode *inode, int flags) +{ + struct address_space *mapping = inode->i_mapping; + int error = 0; + + if (flags & DIO_START) + error = filemap_fdatawrite(mapping); + if (!error && (flags & DIO_WAIT)) + error = filemap_fdatawait(mapping); + + /* Find a better way to report this to the user. */ + if (error) + gfs_io_error_inode(get_v2ip(inode)); +} + +/** + * gfs_sync_page - Sync the data pages (not metadata) associated with a glock + * @gl: the glock + * @flags: DIO_START | DIO_WAIT + * + * Syncs data (not metadata) for a regular file. + * No-op for all other types. + */ + +void +gfs_sync_page(struct gfs_glock *gl, int flags) +{ + struct gfs_inode *ip; + struct inode *inode; + + ip = get_gl2ip(gl); + if (!ip || + ip->i_di.di_type != GFS_FILE_REG) + return; + + inode = gfs_iget(ip, NO_CREATE); + if (inode) { + gfs_sync_page_i(inode, flags); + iput(inode); + } +} + +/** + * gfs_unstuffer_page - unstuff a stuffed inode into a block cached by a page + * @ip: the inode + * @dibh: the dinode buffer + * @block: the block number that was allocated + * @private: any locked page held by the caller process + * + * Returns: errno + */ + +int +gfs_unstuffer_page(struct gfs_inode *ip, struct buffer_head *dibh, + uint64_t block, void *private) +{ + struct inode *inode = ip->i_vnode; + struct page *page = (struct page *)private; + struct buffer_head *bh; + int release = FALSE; + + if (!page || page->index) { + page = grab_cache_page(inode->i_mapping, 0); + if (!page) + return -ENOMEM; + release = TRUE; + } + + if (!PageUptodate(page)) { + void *kaddr = kmap(page); + + memcpy(kaddr, + dibh->b_data + sizeof(struct gfs_dinode), + ip->i_di.di_size); + memset(kaddr + ip->i_di.di_size, + 0, + PAGE_CACHE_SIZE - ip->i_di.di_size); + kunmap(page); + + SetPageUptodate(page); + } + + if (!page_has_buffers(page)) + create_empty_buffers(page, 1 << inode->i_blkbits, + (1 << BH_Uptodate)); + + bh = page_buffers(page); + + if (!buffer_mapped(bh)) + map_bh(bh, inode->i_sb, block); + else if (gfs_assert_warn(ip->i_sbd, + bh->b_bdev == inode->i_sb->s_bdev && + bh->b_blocknr == block)) + map_bh(bh, inode->i_sb, block); + + set_buffer_uptodate(bh); + mark_buffer_dirty(bh); + + if (release) { + unlock_page(page); + page_cache_release(page); + } + + return 0; +} + +/** + * gfs_truncator_page - truncate a partial data block in the page cache + * @ip: the inode + * @size: the size the file should be + * + * Returns: errno + */ + +int +gfs_truncator_page(struct gfs_inode *ip, uint64_t size) +{ + struct inode *inode = ip->i_vnode; + struct page *page; + struct buffer_head *bh; + void *kaddr; + uint64_t lbn, dbn; + unsigned long index; + unsigned int offset; + unsigned int bufnum; + int not_new = 0; + int error; + + lbn = size >> inode->i_blkbits; + error = gfs_block_map(ip, + lbn, ¬_new, + &dbn, NULL); + if (error || !dbn) + return error; + + index = size >> PAGE_CACHE_SHIFT; + offset = size & (PAGE_CACHE_SIZE - 1); + bufnum = lbn - (index << (PAGE_CACHE_SHIFT - inode->i_blkbits)); + + /* Not in a transaction here -- a non-disk-I/O error is ok. */ + + page = read_cache_page(inode->i_mapping, index, + (filler_t *)inode->i_mapping->a_ops->readpage, + NULL); + if (IS_ERR(page)) + return PTR_ERR(page); + + lock_page(page); + + if (!PageUptodate(page) || PageError(page)) { + error = -EIO; + goto out; + } + + kaddr = kmap(page); + memset(kaddr + offset, 0, PAGE_CACHE_SIZE - offset); + kunmap(page); + + if (!page_has_buffers(page)) + create_empty_buffers(page, 1 << inode->i_blkbits, + (1 << BH_Uptodate)); + + for (bh = page_buffers(page); bufnum--; bh = bh->b_this_page) + /* Do nothing */; + + if (!buffer_mapped(bh)) + map_bh(bh, inode->i_sb, dbn); + else if (gfs_assert_warn(ip->i_sbd, + bh->b_bdev == inode->i_sb->s_bdev && + bh->b_blocknr == dbn)) + map_bh(bh, inode->i_sb, dbn); + + set_buffer_uptodate(bh); + mark_buffer_dirty(bh); + + out: + unlock_page(page); + page_cache_release(page); + + return error; +} --- linux-2.6.28.orig/ubuntu/gfs/lm.h +++ linux-2.6.28/ubuntu/gfs/lm.h @@ -0,0 +1,32 @@ +#ifndef __LM_DOT_H__ +#define __LM_DOT_H__ + +int gfs_lm_mount(struct gfs_sbd *sdp, int silent); +void gfs_lm_others_may_mount(struct gfs_sbd *sdp); +void gfs_lm_unmount(struct gfs_sbd *sdp); +int gfs_lm_withdraw(struct gfs_sbd *sdp, char *fmt, ...) +__attribute__ ((format(printf, 2, 3))); +int gfs_lm_get_lock(struct gfs_sbd *sdp, + struct lm_lockname *name, void **lockp); +void gfs_lm_put_lock(struct gfs_sbd *sdp, void *lock); +unsigned int gfs_lm_lock(struct gfs_sbd *sdp, void *lock, + unsigned int cur_state, unsigned int req_state, + unsigned int flags); +unsigned int gfs_lm_unlock(struct gfs_sbd *sdp, void *lock, + unsigned int cur_state); +void gfs_lm_cancel(struct gfs_sbd *sdp, void *lock); +int gfs_lm_hold_lvb(struct gfs_sbd *sdp, void *lock, char **lvbp); +void gfs_lm_unhold_lvb(struct gfs_sbd *sdp, void *lock, char *lvb); +int gfs_lm_plock_get(struct gfs_sbd *sdp, + struct lm_lockname *name, + struct file *file, struct file_lock *fl); +int gfs_lm_plock(struct gfs_sbd *sdp, + struct lm_lockname *name, + struct file *file, int cmd, struct file_lock *fl); +int gfs_lm_punlock(struct gfs_sbd *sdp, + struct lm_lockname *name, + struct file *file, struct file_lock *fl); +void gfs_lm_recovery_done(struct gfs_sbd *sdp, + unsigned int jid, unsigned int message); + +#endif /* __LM_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/page.h +++ linux-2.6.28/ubuntu/gfs/page.h @@ -0,0 +1,13 @@ +#ifndef __PAGE_DOT_H__ +#define __PAGE_DOT_H__ + +void gfs_inval_pte(struct gfs_glock *gl); +void gfs_inval_page(struct gfs_glock *gl); +void gfs_sync_page_i(struct inode *inode, int flags); +void gfs_sync_page(struct gfs_glock *gl, int flags); + +int gfs_unstuffer_page(struct gfs_inode *ip, struct buffer_head *dibh, + uint64_t block, void *private); +int gfs_truncator_page(struct gfs_inode *ip, uint64_t size); + +#endif /* __PAGE_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/Makefile +++ linux-2.6.28/ubuntu/gfs/Makefile @@ -0,0 +1,46 @@ +#obj-$(CONFIG_GFS_FS) += gfs.o +gfs-objs := acl.o \ + bits.o \ + bmap.o \ + daemon.o \ + dio.o \ + dir.o \ + eaops.o \ + eattr.o \ + file.o \ + glock.o \ + glops.o \ + inode.o \ + ioctl.o \ + lm.o \ + locking.o \ + lock_nolock_main.o \ + lock_dlm_lock.o \ + lock_dlm_main.o \ + lock_dlm_mount.o \ + lock_dlm_sysfs.o \ + lock_dlm_thread.o \ + log.o \ + lops.o \ + lvb.o \ + main.o \ + mount.o \ + ondisk.o \ + ops_address.o \ + ops_dentry.o \ + ops_export.o \ + ops_file.o \ + ops_fstype.o \ + ops_inode.o \ + ops_super.o \ + ops_vm.o \ + page.o \ + proc.o \ + quota.o \ + recovery.o \ + rgrp.o \ + super.o \ + sys.o \ + trans.o \ + unlinked.o \ + util.o --- linux-2.6.28.orig/ubuntu/gfs/ioctl.c +++ linux-2.6.28/ubuntu/gfs/ioctl.c @@ -0,0 +1,1605 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs_ioctl.h" +#include "gfs.h" +#include "bmap.h" +#include "dio.h" +#include "dir.h" +#include "eattr.h" +#include "file.h" +#include "glock.h" +#include "glops.h" +#include "inode.h" +#include "ioctl.h" +#include "log.h" +#include "quota.h" +#include "rgrp.h" +#include "super.h" +#include "trans.h" + +typedef int (*gi_filler_t) (struct gfs_inode *ip, + struct gfs_ioctl *gi, + char *buf, + unsigned int size, + unsigned int *count); + +#define ARG_SIZE (32) + +/** + * gi_skeleton - Setup a buffer that functions can print into + * @ip: + * @gi: + * @filler: + * + * Returns: -errno or count of bytes copied to userspace + */ + +static int +gi_skeleton(struct gfs_inode *ip, struct gfs_ioctl *gi, + gi_filler_t filler) +{ + unsigned int size = gfs_tune_get(ip->i_sbd, gt_lockdump_size); + char *buf; + unsigned int count = 0; + int error; + + if (size > gi->gi_size) + size = gi->gi_size; + + buf = kmalloc(size, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + error = filler(ip, gi, buf, size, &count); + if (error) + goto out; + + if (copy_to_user(gi->gi_data, buf, count + 1)) + error = -EFAULT; + else + error = count + 1; + + out: + kfree(buf); + + return error; +} + +/** + * gi_get_cookie - Return the "cookie" (identifying string) for a + * filesystem mount + * @ip: + * @gi: + * @buf: + * @size: + * @count: + * + * Returns: errno + */ + +static int +gi_get_cookie(struct gfs_inode *ip, + struct gfs_ioctl *gi, + char *buf, + unsigned int size, + unsigned int *count) +{ + int error = -ENOBUFS; + + if (gi->gi_argc != 1) + return -EINVAL; + + gfs_printf("version 0\n"); + gfs_printf("%lu", (unsigned long)ip->i_sbd); + + error = 0; + + out: + return error; +} + +/** + * gi_get_super - Return the "struct gfs_sb" for a filesystem + * @sdp: + * @gi: + * + * Returns: errno + */ + +static int +gi_get_super(struct gfs_sbd *sdp, struct gfs_ioctl *gi) +{ + struct gfs_holder sb_gh; + struct buffer_head *bh; + struct gfs_sb *sb; + int error; + + if (gi->gi_argc != 1) + return -EINVAL; + if (gi->gi_size != sizeof(struct gfs_sb)) + return -EINVAL; + + sb = kmalloc(sizeof(struct gfs_sb), GFP_KERNEL); + if (!sb) + return -ENOMEM; + + error = gfs_glock_nq_num(sdp, + GFS_SB_LOCK, &gfs_meta_glops, + LM_ST_SHARED, 0, &sb_gh); + if (error) + goto out; + + error = gfs_dread(sb_gh.gh_gl, GFS_SB_ADDR >> sdp->sd_fsb2bb_shift, + DIO_START | DIO_WAIT, &bh); + if (error) { + gfs_glock_dq_uninit(&sb_gh); + goto out; + } + gfs_sb_in(sb, bh->b_data); + brelse(bh); + + gfs_glock_dq_uninit(&sb_gh); + + if (copy_to_user(gi->gi_data, sb, + sizeof(struct gfs_sb))) + error = -EFAULT; + else + error = sizeof(struct gfs_sb); + + out: + kfree(sb); + + return error; +} + +/** + * gi_get_args - Return the mount arguments + * @ip: + * @gi: + * @buf: + * @size: + * @count: + * + * Returns: errno + */ + +static int +gi_get_args(struct gfs_inode *ip, + struct gfs_ioctl *gi, + char *buf, + unsigned int size, + unsigned int *count) +{ + struct gfs_args *args = &ip->i_sbd->sd_args; + int error = -ENOBUFS; + + if (gi->gi_argc != 1) + return -EINVAL; + + gfs_printf("version 0\n"); + gfs_printf("lockproto %s\n", args->ar_lockproto); + gfs_printf("locktable %s\n", args->ar_locktable); + gfs_printf("hostdata %s\n", args->ar_hostdata); + gfs_printf("ignore_local_fs %d\n", args->ar_ignore_local_fs); + gfs_printf("localcaching %d\n", args->ar_localcaching); + gfs_printf("localflocks %d\n", args->ar_localflocks); + gfs_printf("oopses_ok %d\n", args->ar_oopses_ok); + gfs_printf("upgrade %d\n", args->ar_upgrade); + gfs_printf("num_glockd %u\n", args->ar_num_glockd); + gfs_printf("posix_acls %d\n", args->ar_posix_acls); + gfs_printf("suiddir %d\n", args->ar_suiddir); + + error = 0; + + out: + return error; +} + +/** + * gi_get_lockstruct - Return the information in the FS' lockstruct + * @ip: + * @gi: + * @buf: + * @size: + * @count: + * + * Returns: errno + */ + +static int +gi_get_lockstruct(struct gfs_inode *ip, + struct gfs_ioctl *gi, + char *buf, + unsigned int size, + unsigned int *count) +{ + struct lm_lockstruct *ls = &ip->i_sbd->sd_lockstruct; + int error = -ENOBUFS; + + if (gi->gi_argc != 1) + return -EINVAL; + + gfs_printf("version 0\n"); + gfs_printf("jid %u\n", ls->ls_jid); + gfs_printf("first %u\n", ls->ls_first); + gfs_printf("lvb_size %u\n", ls->ls_lvb_size); + gfs_printf("flags %d\n", ls->ls_flags); + + error = 0; + + out: + return error; +} + +/** + * gi_get_stat_gfs - Return a filesystem's space usage information + * @ip: + * @gi: + * @buf: + * @size: + * @count: + * + * Returns: errno + */ + +static int +gi_get_stat_gfs(struct gfs_inode *ip, + struct gfs_ioctl *gi, + char *buf, + unsigned int size, + unsigned int *count) +{ + struct gfs_stat_gfs sg; + int error; + + if (gi->gi_argc != 1) + return -EINVAL; + + error = gfs_stat_gfs(ip->i_sbd, &sg, TRUE); + if (error) + return error; + + error = -ENOBUFS; + + gfs_printf("version 0\n"); + gfs_printf("bsize %u\n", ip->i_sbd->sd_sb.sb_bsize); + gfs_printf("total_blocks %"PRIu64"\n", sg.sg_total_blocks); + gfs_printf("free %"PRIu64"\n", sg.sg_free); + gfs_printf("used_dinode %"PRIu64"\n", sg.sg_used_dinode); + gfs_printf("free_dinode %"PRIu64"\n", sg.sg_free_dinode); + gfs_printf("used_meta %"PRIu64"\n", sg.sg_used_meta); + gfs_printf("free_meta %"PRIu64"\n", sg.sg_free_meta); + + error = 0; + + out: + return error; +} + +/** + * handle_roll - Read a atomic_t as an unsigned int + * @a: a counter + * + * if @a is negative, reset it to zero + * + * Returns: the value of the counter + */ + +static unsigned int +handle_roll(atomic_t *a) +{ + int x = atomic_read(a); + if (x < 0) { + atomic_set(a, 0); + return 0; + } + return (unsigned int)x; +} + +/** + * gi_get_counters - Return usage counters + * @ip: + * @gi: + * @buf: + * @size: + * @count: + * + * Returns: errno + */ + +static int +gi_get_counters(struct gfs_inode *ip, + struct gfs_ioctl *gi, + char *buf, + unsigned int size, + unsigned int *count) +{ + struct gfs_sbd *sdp = ip->i_sbd; + int error = -ENOBUFS; + + if (gi->gi_argc != 1) + return -EINVAL; + + gfs_printf("version 0\n"); + gfs_printf("sd_glock_count:locks::%d\n", + atomic_read(&sdp->sd_glock_count)); + gfs_printf("sd_glock_held_count:locks held::%d\n", + atomic_read(&sdp->sd_glock_held_count)); + gfs_printf("sd_freeze_count:freeze count::%d\n", + sdp->sd_freeze_count); + gfs_printf("sd_inode_count:incore inodes::%d\n", + atomic_read(&sdp->sd_inode_count)); + gfs_printf("sd_bufdata_count:metadata buffers::%d\n", + atomic_read(&sdp->sd_bufdata_count)); + gfs_printf("sd_unlinked_ic_count:unlinked inodes::%d\n", + atomic_read(&sdp->sd_unlinked_ic_count)); + gfs_printf("sd_quota_count:quota IDs::%d\n", + atomic_read(&sdp->sd_quota_count)); + gfs_printf("sd_log_buffers:incore log buffers::%u\n", + sdp->sd_log_buffers); + gfs_printf("sd_log_seg_free:log segments free::%u\n", + sdp->sd_log_seg_free); + gfs_printf("ji_nsegment:log segments total::%u\n", + sdp->sd_jdesc.ji_nsegment); + gfs_printf("sd_mhc_count:meta header cache entries::%d\n", + atomic_read(&sdp->sd_mhc_count)); + gfs_printf("sd_depend_count:glock dependencies::%d\n", + atomic_read(&sdp->sd_depend_count)); + gfs_printf("sd_reclaim_count:glocks on reclaim list::%d\n", + atomic_read(&sdp->sd_reclaim_count)); + gfs_printf("sd_log_wrap:log wraps::%"PRIu64"\n", + sdp->sd_log_wrap); + gfs_printf("sd_lm_outstanding:outstanding LM calls::%d\n", + atomic_read(&sdp->sd_lm_outstanding)); + gfs_printf("sd_bio_outstanding:outstanding BIO calls::%u\n", + atomic_read(&sdp->sd_bio_outstanding)); + gfs_printf("sd_fh2dentry_misses:fh2dentry misses:diff:%u\n", + handle_roll(&sdp->sd_fh2dentry_misses)); + gfs_printf("sd_reclaimed:glocks reclaimed:diff:%u\n", + handle_roll(&sdp->sd_reclaimed)); + gfs_printf("sd_glock_nq_calls:glock nq calls:diff:%u\n", + handle_roll(&sdp->sd_glock_nq_calls)); + gfs_printf("sd_glock_dq_calls:glock dq calls:diff:%u\n", + handle_roll(&sdp->sd_glock_dq_calls)); + gfs_printf("sd_glock_prefetch_calls:glock prefetch calls:diff:%u\n", + handle_roll(&sdp->sd_glock_prefetch_calls)); + gfs_printf("sd_lm_lock_calls:lm_lock calls:diff:%u\n", + handle_roll(&sdp->sd_lm_lock_calls)); + gfs_printf("sd_lm_unlock_calls:lm_unlock calls:diff:%u\n", + handle_roll(&sdp->sd_lm_unlock_calls)); + gfs_printf("sd_lm_callbacks:lm callbacks:diff:%u\n", + handle_roll(&sdp->sd_lm_callbacks)); + gfs_printf("sd_ops_address:address operations:diff:%u\n", + handle_roll(&sdp->sd_ops_address)); + gfs_printf("sd_ops_dentry:dentry operations:diff:%u\n", + handle_roll(&sdp->sd_ops_dentry)); + gfs_printf("sd_ops_export:export operations:diff:%u\n", + handle_roll(&sdp->sd_ops_export)); + gfs_printf("sd_ops_file:file operations:diff:%u\n", + handle_roll(&sdp->sd_ops_file)); + gfs_printf("sd_ops_inode:inode operations:diff:%u\n", + handle_roll(&sdp->sd_ops_inode)); + gfs_printf("sd_ops_super:super operations:diff:%u\n", + handle_roll(&sdp->sd_ops_super)); + gfs_printf("sd_ops_vm:vm operations:diff:%u\n", + handle_roll(&sdp->sd_ops_vm)); + gfs_printf("sd_bio_reads:block I/O reads:diff:%u\n", + handle_roll(&sdp->sd_bio_reads) >> + (sdp->sd_sb.sb_bsize_shift - 9)); + gfs_printf("sd_bio_writes:block I/O writes:diff:%u\n", + handle_roll(&sdp->sd_bio_writes) >> + (sdp->sd_sb.sb_bsize_shift - 9)); + + error = 0; + + out: + return error; +} + +/** + * gi_get_tune - Return current values of the tuneable parameters + * @ip: + * @gi: + * @buf: + * @size: + * @count: + * + * Returns: errno + */ + +static int +gi_get_tune(struct gfs_inode *ip, + struct gfs_ioctl *gi, + char *buf, + unsigned int size, + unsigned int *count) +{ + struct gfs_tune *gt = &ip->i_sbd->sd_tune; + int error = -ENOBUFS; + + if (gi->gi_argc != 1) + return -EINVAL; + + spin_lock(>->gt_spin); + + gfs_printf("version 0\n"); + gfs_printf("ilimit1 %u\n", gt->gt_ilimit1); + gfs_printf("ilimit1_tries %u\n", gt->gt_ilimit1_tries); + gfs_printf("ilimit1_min %u\n", gt->gt_ilimit1_min); + gfs_printf("ilimit2 %u\n", gt->gt_ilimit2); + gfs_printf("ilimit2_tries %u\n", gt->gt_ilimit2_tries); + gfs_printf("ilimit2_min %u\n", gt->gt_ilimit2_min); + gfs_printf("demote_secs %u\n", gt->gt_demote_secs); + gfs_printf("incore_log_blocks %u\n", gt->gt_incore_log_blocks); + gfs_printf("jindex_refresh_secs %u\n", gt->gt_jindex_refresh_secs); + gfs_printf("depend_secs %u\n", gt->gt_depend_secs); + gfs_printf("scand_secs %u\n", gt->gt_scand_secs); + gfs_printf("recoverd_secs %u\n", gt->gt_recoverd_secs); + gfs_printf("logd_secs %u\n", gt->gt_logd_secs); + gfs_printf("quotad_secs %u\n", gt->gt_quotad_secs); + gfs_printf("inoded_secs %u\n", gt->gt_inoded_secs); + gfs_printf("glock_purge %u\n", gt->gt_glock_purge); + gfs_printf("quota_simul_sync %u\n", gt->gt_quota_simul_sync); + gfs_printf("quota_warn_period %u\n", gt->gt_quota_warn_period); + gfs_printf("atime_quantum %u\n", gt->gt_atime_quantum); + gfs_printf("quota_quantum %u\n", gt->gt_quota_quantum); + gfs_printf("quota_scale_num %u\n", gt->gt_quota_scale_num); + gfs_printf("quota_scale_den %u\n", gt->gt_quota_scale_den); + gfs_printf("quota_enforce %u\n", gt->gt_quota_enforce); + gfs_printf("quota_account %u\n", gt->gt_quota_account); + gfs_printf("new_files_jdata %u\n", gt->gt_new_files_jdata); + gfs_printf("new_files_directio %u\n", gt->gt_new_files_directio); + gfs_printf("max_atomic_write %u\n", gt->gt_max_atomic_write); + gfs_printf("max_readahead %u\n", gt->gt_max_readahead); + gfs_printf("lockdump_size %u\n", gt->gt_lockdump_size); + gfs_printf("stall_secs %u\n", gt->gt_stall_secs); + gfs_printf("complain_secs %u\n", gt->gt_complain_secs); + gfs_printf("reclaim_limit %u\n", gt->gt_reclaim_limit); + gfs_printf("entries_per_readdir %u\n", gt->gt_entries_per_readdir); + gfs_printf("prefetch_secs %u\n", gt->gt_prefetch_secs); + gfs_printf("statfs_slots %u\n", gt->gt_statfs_slots); + gfs_printf("max_mhc %u\n", gt->gt_max_mhc); + gfs_printf("greedy_default %u\n", gt->gt_greedy_default); + gfs_printf("greedy_quantum %u\n", gt->gt_greedy_quantum); + gfs_printf("greedy_max %u\n", gt->gt_greedy_max); + gfs_printf("rgrp_try_threshold %u\n", gt->gt_rgrp_try_threshold); + gfs_printf("statfs_fast %u\n", gt->gt_statfs_fast); + + error = 0; + + out: + spin_unlock(>->gt_spin); + + return error; +} + +#define tune_set(f, v) \ +do { \ + spin_lock(>->gt_spin); \ + gt->f = (v); \ + spin_unlock(>->gt_spin); \ +} while (0) + +/** + * gi_set_tune - Set a tuneable parameter + * @sdp: + * @gi: + * + * Returns: errno + */ + +static int +gi_set_tune(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user) +{ + struct gfs_tune *gt = &sdp->sd_tune; + char param[ARG_SIZE], value[ARG_SIZE]; + unsigned int x; + int error; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + if (gi->gi_argc != 3) + return -EINVAL; + + if (from_user) { + if (strncpy_from_user(param, gi->gi_argv[1], ARG_SIZE) < 0) + return -EFAULT; + } else { + strncpy(param, gi->gi_argv[1], ARG_SIZE); + } + param[ARG_SIZE - 1] = 0; + + if (from_user) { + if (strncpy_from_user(value, gi->gi_argv[2], ARG_SIZE) < 0) + return -EFAULT; + } else { + strncpy(value, gi->gi_argv[2], ARG_SIZE); + } + + value[ARG_SIZE - 1] = 0; + + if (strcmp(param, "ilimit1") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_ilimit1, x); + + } else if (strcmp(param, "ilimit1_tries") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_ilimit1_tries, x); + + } else if (strcmp(param, "ilimit1_min") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_ilimit1_min, x); + + } else if (strcmp(param, "ilimit2") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_ilimit2, x); + + } else if (strcmp(param, "ilimit2_tries") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_ilimit2_tries, x); + + } else if (strcmp(param, "ilimit2_min") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_ilimit2_min, x); + + } else if (strcmp(param, "demote_secs") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_demote_secs, x); + + } else if (strcmp(param, "incore_log_blocks") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_incore_log_blocks, x); + + } else if (strcmp(param, "jindex_refresh_secs") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_jindex_refresh_secs, x); + + } else if (strcmp(param, "depend_secs") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_depend_secs, x); + + } else if (strcmp(param, "scand_secs") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_scand_secs, x); + wake_up_process(sdp->sd_scand_process); + + } else if (strcmp(param, "recoverd_secs") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_recoverd_secs, x); + wake_up_process(sdp->sd_recoverd_process); + + } else if (strcmp(param, "logd_secs") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_logd_secs, x); + wake_up_process(sdp->sd_logd_process); + + } else if (strcmp(param, "quotad_secs") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_quotad_secs, x); + wake_up_process(sdp->sd_quotad_process); + + } else if (strcmp(param, "inoded_secs") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_inoded_secs, x); + wake_up_process(sdp->sd_inoded_process); + + } else if (strcmp(param, "glock_purge") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_glock_purge, x); + + } else if (strcmp(param, "quota_simul_sync") == 0) { + if (sscanf(value, "%u", &x) != 1 || !x) + return -EINVAL; + tune_set(gt_quota_simul_sync, x); + + } else if (strcmp(param, "quota_warn_period") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_quota_warn_period, x); + + } else if (strcmp(param, "atime_quantum") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_atime_quantum, x); + + } else if (strcmp(param, "quota_quantum") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_quota_quantum, x); + + } else if (strcmp(param, "quota_scale") == 0) { + unsigned int y; + if (sscanf(value, "%u %u", &x, &y) != 2 || !y) + return -EINVAL; + spin_lock(>->gt_spin); + gt->gt_quota_scale_num = x; + gt->gt_quota_scale_den = y; + spin_unlock(>->gt_spin); + + } else if (strcmp(param, "quota_enforce") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + x = !!x; + spin_lock(>->gt_spin); + gt->gt_quota_enforce = x; + if (x) + gt->gt_quota_account = 1; + spin_unlock(>->gt_spin); + + } else if (strcmp(param, "quota_account") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + x = !!x; + spin_lock(>->gt_spin); + gt->gt_quota_account = x; + if (x) + spin_unlock(>->gt_spin); + else { + unsigned int y; + gt->gt_quota_enforce = 0; + spin_unlock(>->gt_spin); + for (y = 0; y < 2; y++) { + gfs_log_flush(sdp); + gfs_sync_meta(sdp); + gfs_quota_sync(sdp); + } + } + + } else if (strcmp(param, "new_files_jdata") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + x = !!x; + tune_set(gt_new_files_jdata, x); + + } else if (strcmp(param, "new_files_directio") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + x = !!x; + tune_set(gt_new_files_directio, x); + + } else if (strcmp(param, "max_atomic_write") == 0) { + if (sscanf(value, "%u", &x) != 1 || !x) + return -EINVAL; + tune_set(gt_max_atomic_write, x); + + } else if (strcmp(param, "max_readahead") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_max_readahead, x); + + } else if (strcmp(param, "lockdump_size") == 0) { + if (sscanf(value, "%u", &x) != 1 || !x) + return -EINVAL; + tune_set(gt_lockdump_size, x); + + } else if (strcmp(param, "stall_secs") == 0) { + if (sscanf(value, "%u", &x) != 1 || !x) + return -EINVAL; + tune_set(gt_stall_secs, x); + + } else if (strcmp(param, "complain_secs") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_complain_secs, x); + + } else if (strcmp(param, "reclaim_limit") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_reclaim_limit, x); + + } else if (strcmp(param, "entries_per_readdir") == 0) { + if (sscanf(value, "%u", &x) != 1 || !x) + return -EINVAL; + tune_set(gt_entries_per_readdir, x); + + } else if (strcmp(param, "prefetch_secs") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_prefetch_secs, x); + + } else if (strcmp(param, "statfs_slots") == 0) { + if (sscanf(value, "%u", &x) != 1 || !x) + return -EINVAL; + tune_set(gt_statfs_slots, x); + + } else if (strcmp(param, "max_mhc") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_max_mhc, x); + + } else if (strcmp(param, "greedy_default") == 0) { + if (sscanf(value, "%u", &x) != 1 || !x) + return -EINVAL; + tune_set(gt_greedy_default, x); + + } else if (strcmp(param, "greedy_quantum") == 0) { + if (sscanf(value, "%u", &x) != 1 || !x) + return -EINVAL; + tune_set(gt_greedy_quantum, x); + + } else if (strcmp(param, "greedy_max") == 0) { + if (sscanf(value, "%u", &x) != 1 || !x) + return -EINVAL; + tune_set(gt_greedy_max, x); + + } else if (strcmp(param, "rgrp_try_threshold") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_rgrp_try_threshold, x); + + } else if (strcmp(param, "statfs_fast") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + error = gfs_statfs_init(sdp, x); + if (error) + return error; + else + tune_set(gt_statfs_fast, x); + + + } else + return -EINVAL; + + return 0; +} + +/** + * gi_do_reclaim - Reclaim unused metadata + * @ip: + * @gi: + * @buf: + * @size: + * @count: + * + * Returns: errno + */ + +static int +gi_do_reclaim(struct gfs_inode *ip, + struct gfs_ioctl *gi, + char *buf, + unsigned int size, + unsigned int *count) +{ + uint64_t inodes, metadata; + int error; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + if (gi->gi_argc != 1) + return -EINVAL; + + error = gfs_reclaim_metadata(ip->i_sbd, + &inodes, + &metadata); + if (error) + return error; + + error = -ENOBUFS; + + gfs_printf("version 0\n"); + gfs_printf("inodes %"PRIu64"\n", inodes); + gfs_printf("metadata %"PRIu64"\n", metadata); + + error = 0; + + out: + return error; +} + +/** + * gi_do_shrink - throw out unused glocks + * @sdp: + * @gi: + * + * Returns: 0 + */ + +static int +gi_do_shrink(struct gfs_sbd *sdp, struct gfs_ioctl *gi) +{ + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + if (gi->gi_argc != 1) + return -EINVAL; + gfs_gl_hash_clear(sdp, FALSE); + return 0; +} + +/** + * gi_get_file_stat - + * @ip: + * @gi: + * + * Returns: the number of bytes copied, or -errno + */ + +static int +gi_get_file_stat(struct gfs_inode *ip, struct gfs_ioctl *gi) +{ + struct gfs_holder i_gh; + struct gfs_dinode *di; + int error; + + if (gi->gi_argc != 1) + return -EINVAL; + if (gi->gi_size != sizeof(struct gfs_dinode)) + return -EINVAL; + + di = kmalloc(sizeof(struct gfs_dinode), GFP_KERNEL); + if (!di) + return -ENOMEM; + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); + if (error) + goto out; + memcpy(di, &ip->i_di, sizeof(struct gfs_dinode)); + gfs_glock_dq_uninit(&i_gh); + + if (copy_to_user(gi->gi_data, di, + sizeof(struct gfs_dinode))) + error = -EFAULT; + else + error = sizeof(struct gfs_dinode); + + out: + kfree(di); + + return error; +} + +/** + * gi_set_file_flag - set or clear a flag on a file + * @ip: + * @gi: + * + * Returns: errno + */ + +static int +gi_set_file_flag(struct gfs_inode *ip, struct gfs_ioctl *gi, int from_user) +{ + char buf[ARG_SIZE]; + int set; + uint32_t flag; + struct gfs_holder i_gh; + struct buffer_head *dibh; + int error; + + if (gi->gi_argc != 3) + return -EINVAL; + + if (from_user) { + if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0) + return -EFAULT; + } else { + strncpy(buf, gi->gi_argv[1], ARG_SIZE); + } + buf[ARG_SIZE - 1] = 0; + + if (strcmp(buf, "set") == 0) + set = TRUE; + else if (strcmp(buf, "clear") == 0) + set = FALSE; + else + return -EINVAL; + + if (from_user) { + if (strncpy_from_user(buf, gi->gi_argv[2], ARG_SIZE) < 0) + return -EFAULT; + } else { + strncpy(buf, gi->gi_argv[2], ARG_SIZE); + } + buf[ARG_SIZE - 1] = 0; + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); + if (error) + return error; + + error = -EACCES; + if (ip->i_di.di_uid != current->fsuid && !capable(CAP_FOWNER)) + goto out; + + error = -EINVAL; + + if (strcmp(buf, "jdata") == 0) { + if (ip->i_di.di_type != GFS_FILE_REG || + ip->i_di.di_size) + goto out; + flag = GFS_DIF_JDATA; + } else if (strcmp(buf, "directio") == 0) { + if (ip->i_di.di_type != GFS_FILE_REG) + goto out; + flag = GFS_DIF_DIRECTIO; + } else if (strcmp(buf, "immutable") == 0) { + /* The IMMUTABLE flag can only be changed by + the relevant capability. */ + error = -EPERM; + if (!capable(CAP_LINUX_IMMUTABLE)) + goto out; + flag = GFS_DIF_IMMUTABLE; + } else if (strcmp(buf, "appendonly") == 0) { + /* The APPENDONLY flag can only be changed by + the relevant capability. */ + error = -EPERM; + if (!capable(CAP_LINUX_IMMUTABLE)) + goto out; + flag = GFS_DIF_APPENDONLY; + } else if (strcmp(buf, "inherit_jdata") == 0) { + if (ip->i_di.di_type != GFS_FILE_DIR) + goto out; + flag = GFS_DIF_INHERIT_JDATA; + } else if (strcmp(buf, "inherit_directio") == 0) { + if (ip->i_di.di_type != GFS_FILE_DIR) + goto out; + flag = GFS_DIF_INHERIT_DIRECTIO; + } else + goto out; + + error = gfs_trans_begin(ip->i_sbd, 1, 0); + if (error) + goto out; + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto out_trans_end; + + if (set) + ip->i_di.di_flags |= flag; + else + ip->i_di.di_flags &= ~flag; + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + + brelse(dibh); + + out_trans_end: + gfs_trans_end(ip->i_sbd); + + out: + gfs_glock_dq_uninit(&i_gh); + + return error; + +} + +/** + * gi_get_file_meta - Return all the metadata for a file + * @ip: + * @gi: + * + * Returns: the number of bytes copied, or -errno + */ + +static int +gi_get_file_meta(struct gfs_inode *ip, struct gfs_ioctl *gi) +{ + struct gfs_holder i_gh; + struct gfs_user_buffer ub; + int error; + + if (gi->gi_argc != 1) + return -EINVAL; + + ub.ub_data = gi->gi_data; + ub.ub_size = gi->gi_size; + ub.ub_count = 0; + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); + if (error) + return error; + + error = -EACCES; + if (ip->i_di.di_uid != current->fsuid && !capable(CAP_FOWNER)) + goto out; + + error = gfs_get_file_meta(ip, &ub); + if (error) + goto out; + + if (ip->i_di.di_type == GFS_FILE_DIR && + (ip->i_di.di_flags & GFS_DIF_EXHASH)) { + error = gfs_get_dir_meta(ip, &ub); + if (error) + goto out; + } + + if (ip->i_di.di_eattr) { + error = gfs_get_eattr_meta(ip, &ub); + if (error) + goto out; + } + + error = ub.ub_count; + + out: + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gi_do_file_flush - sync out all dirty data and + * drop the cache (and lock) for a file. + * @ip: + * @gi: + * + * Returns: errno + */ + +static int +gi_do_file_flush(struct gfs_inode *ip, struct gfs_ioctl *gi) +{ + if (gi->gi_argc != 1) + return -EINVAL; + gfs_glock_force_drop(ip->i_gl); + return 0; +} + +/** + * gi2hip - return the "struct gfs_inode" for a hidden file + * @sdp: + * @gi: + * + * Returns: the "struct gfs_inode" + */ + +static struct gfs_inode * +gi2hip(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user) +{ + char buf[ARG_SIZE]; + + if (gi->gi_argc != 2) + return ERR_PTR(-EINVAL); + + if (from_user) { + if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0) + return ERR_PTR(-EFAULT); + } else { + strncpy(buf, gi->gi_argv[1], ARG_SIZE); + } + buf[ARG_SIZE - 1] = 0; + + if (strcmp(buf, "jindex") == 0) + return sdp->sd_jiinode; + else if (strcmp(buf, "rindex") == 0) + return sdp->sd_riinode; + else if (strcmp(buf, "quota") == 0) + return sdp->sd_qinode; + else if (strcmp(buf, "license") == 0) + return sdp->sd_linode; + else + return ERR_PTR(-EINVAL); +} + +/** + * gi_get_hfile_stat - get stat info on a hidden file + * @sdp: + * @gi: + * + * Returns: the number of bytes copied, or -errno + */ + +static int +gi_get_hfile_stat(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user) +{ + struct gfs_inode *ip; + struct gfs_dinode *di; + struct gfs_holder i_gh; + int error; + + ip = gi2hip(sdp, gi, from_user); + if (IS_ERR(ip)) + return PTR_ERR(ip); + + if (gi->gi_size != sizeof(struct gfs_dinode)) + return -EINVAL; + + di = kmalloc(sizeof(struct gfs_dinode), GFP_KERNEL); + if (!di) + return -ENOMEM; + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); + if (error) + goto out; + memcpy(di, &ip->i_di, sizeof(struct gfs_dinode)); + gfs_glock_dq_uninit(&i_gh); + + if (copy_to_user(gi->gi_data, di, + sizeof(struct gfs_dinode))) + error = -EFAULT; + else + error = sizeof(struct gfs_dinode); + + out: + kfree(di); + + return error; +} + +/** + * gi_do_hfile_read - Read data from a hidden file + * @sdp: + * @gi: + * + * Returns: the number of bytes read, or -errno + */ + +static int +gi_do_hfile_read(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user) +{ + struct gfs_inode *ip; + struct gfs_holder i_gh; + int error; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + ip = gi2hip(sdp, gi, from_user); + if (IS_ERR(ip)) + return PTR_ERR(ip); + + if (!access_ok(VERIFY_WRITE, gi->gi_data, gi->gi_size)) + return -EFAULT; + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh); + if (error) + return error; + + error = gfs_readi(ip, gi->gi_data, gi->gi_offset, gi->gi_size, + gfs_copy2user); + + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gi_do_hfile_write - Write data to a hidden file + * @sdp: + * @gi: + * + * Returns: the number of bytes written, or -errno + */ + +static int +gi_do_hfile_write(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user) +{ + struct gfs_inode *ip; + struct gfs_alloc *al = NULL; + struct gfs_holder i_gh; + unsigned int data_blocks, ind_blocks; + int alloc_required; + int error; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + ip = gi2hip(sdp, gi, from_user); + if (IS_ERR(ip)) + return PTR_ERR(ip); + + if (!access_ok(VERIFY_READ, gi->gi_data, gi->gi_size)) + return -EFAULT; + + gfs_write_calc_reserv(ip, gi->gi_size, &data_blocks, &ind_blocks); + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, + LM_FLAG_PRIORITY | GL_SYNC | GL_NOCANCEL_OTHER, + &i_gh); + if (error) + return error; + + if (!gfs_is_jdata(ip)) { + gfs_consist_inode(ip); + error = -EIO; + goto out; + } + + error = gfs_write_alloc_required(ip, gi->gi_offset, gi->gi_size, + &alloc_required); + if (error) + goto out; + + if (alloc_required) { + al = gfs_alloc_get(ip); + + error = gfs_quota_hold_m(ip, NO_QUOTA_CHANGE, + NO_QUOTA_CHANGE); + if (error) + goto out_alloc; + + al->al_requested_meta = ind_blocks + data_blocks; + + error = gfs_inplace_reserve(ip); + if (error) + goto out_qs; + + /* Trans may require: + All blocks for a RG bitmap, all the "data" blocks, whatever + indirect blocks we need, a modified dinode, and a quota change */ + + error = gfs_trans_begin(sdp, + 1 + al->al_rgd->rd_ri.ri_length + + ind_blocks + data_blocks, 1); + if (error) + goto out_relse; + } else { + /* Trans may require: + All the "data" blocks and a modified dinode. */ + + error = gfs_trans_begin(sdp, 1 + data_blocks, 0); + if (error) + goto out_relse; + } + + if (from_user) + error = gfs_writei(ip, gi->gi_data, gi->gi_offset, gi->gi_size, + gfs_copy_from_user, NULL); + else + error = gfs_writei(ip, gi->gi_data, gi->gi_offset, gi->gi_size, + gfs_copy_from_mem, NULL); + + gfs_trans_end(sdp); + + out_relse: + if (alloc_required) { + gfs_assert_warn(sdp, error || al->al_alloced_meta); + gfs_inplace_release(ip); + } + + out_qs: + if (alloc_required) + gfs_quota_unhold_m(ip); + + out_alloc: + if (alloc_required) + gfs_alloc_put(ip); + + out: + ip->i_gl->gl_vn++; + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gi_do_hfile_trunc - truncate a hidden file + * @sdp: + * @gi: + * + * Returns: the number of bytes copied, or -errno + */ + +static int +gi_do_hfile_trunc(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user) +{ + struct gfs_inode *ip; + struct gfs_holder i_gh; + int error; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + ip = gi2hip(sdp, gi, from_user); + if (IS_ERR(ip)) + return PTR_ERR(ip); + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SYNC, &i_gh); + if (error) + return error; + + error = gfs_truncatei(ip, gi->gi_offset, NULL); + + ip->i_gl->gl_vn++; + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gi_do_quota_sync - sync the outstanding quota changes for a FS + * @sdp: + * @gi: + * + * Returns: errno + */ + +static int +gi_do_quota_sync(struct gfs_sbd *sdp, struct gfs_ioctl *gi) +{ + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + if (gi->gi_argc != 1) + return -EINVAL; + return gfs_quota_sync(sdp); +} + +/** + * gi_do_quota_refresh - Refresh the a quota LVB from the quota file + * @sdp: + * @gi: + * + * Returns: errno + */ + +static int +gi_do_quota_refresh(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user) +{ + char buf[ARG_SIZE]; + int user; + uint32_t id; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + if (gi->gi_argc != 2) + return -EINVAL; + + if (from_user) { + if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0) + return -EFAULT; + } else { + strncpy(buf, gi->gi_argv[1], ARG_SIZE); + } + buf[ARG_SIZE - 1] = 0; + + switch (buf[0]) { + case 'u': + user = TRUE; + break; + case 'g': + user = FALSE; + break; + default: + return -EINVAL; + } + + if (buf[1] != ':') + return -EINVAL; + + if (sscanf(buf + 2, "%u", &id) != 1) + return -EINVAL; + + return gfs_quota_refresh(sdp, user, id); +} + +/** + * gi_do_quota_read - read quota values from the quota file + * @sdp: + * @gi: + * + * Returns: errno + */ + +static int +gi_do_quota_read(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user) +{ + char buf[ARG_SIZE]; + int user; + uint32_t id; + struct gfs_quota q; + int error; + + if (gi->gi_argc != 2) + return -EINVAL; + if (gi->gi_size != sizeof(struct gfs_quota)) + return -EINVAL; + + if (from_user) { + if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0) + return -EFAULT; + } else { + strncpy(buf, gi->gi_argv[1], ARG_SIZE); + } + buf[ARG_SIZE - 1] = 0; + + switch (buf[0]) { + case 'u': + user = TRUE; + break; + case 'g': + user = FALSE; + break; + default: + return -EINVAL; + } + + if (buf[1] != ':') + return -EINVAL; + + if (sscanf(buf + 2, "%u", &id) != 1) + return -EINVAL; + + error = gfs_quota_read(sdp, user, id, &q); + if (error) + return error; + + if (copy_to_user(gi->gi_data, &q, sizeof(struct gfs_quota))) + return -EFAULT; + + return 0; +} + +int +gfs_ioctl_i_local(struct gfs_inode *ip, struct gfs_ioctl *gi, const char *arg0, + int from_user) +{ + int error = -EFAULT; + + if (strcmp(arg0, "get_cookie") == 0) + error = gi_skeleton(ip, gi, gi_get_cookie); + else if (strcmp(arg0, "get_super") == 0) + error = gi_get_super(ip->i_sbd, gi); + else if (strcmp(arg0, "get_args") == 0) + error = gi_skeleton(ip, gi, gi_get_args); + else if (strcmp(arg0, "get_lockstruct") == 0) + error = gi_skeleton(ip, gi, gi_get_lockstruct); + else if (strcmp(arg0, "get_stat_gfs") == 0) + error = gi_skeleton(ip, gi, gi_get_stat_gfs); + else if (strcmp(arg0, "get_counters") == 0) + error = gi_skeleton(ip, gi, gi_get_counters); + else if (strcmp(arg0, "get_tune") == 0) + error = gi_skeleton(ip, gi, gi_get_tune); + else if (strcmp(arg0, "set_tune") == 0) + error = gi_set_tune(ip->i_sbd, gi, from_user); + else if (strcmp(arg0, "do_reclaim") == 0) + error = gi_skeleton(ip, gi, gi_do_reclaim); + else if (strcmp(arg0, "do_shrink") == 0) + error = gi_do_shrink(ip->i_sbd, gi); + else if (strcmp(arg0, "get_file_stat") == 0) + error = gi_get_file_stat(ip, gi); + else if (strcmp(arg0, "set_file_flag") == 0) + error = gi_set_file_flag(ip, gi, from_user); + else if (strcmp(arg0, "get_file_meta") == 0) + error = gi_get_file_meta(ip, gi); + else if (strcmp(arg0, "get_file_meta_quota") == 0) + error = gi_get_file_meta(ip->i_sbd->sd_qinode, gi); + else if (strcmp(arg0, "do_file_flush") == 0) + error = gi_do_file_flush(ip, gi); + else if (strcmp(arg0, "get_hfile_stat") == 0) + error = gi_get_hfile_stat(ip->i_sbd, gi, from_user); + else if (strcmp(arg0, "do_hfile_read") == 0) + error = gi_do_hfile_read(ip->i_sbd, gi, from_user); + else if (strcmp(arg0, "do_hfile_write") == 0) + error = gi_do_hfile_write(ip->i_sbd, gi, from_user); + else if (strcmp(arg0, "do_hfile_trunc") == 0) + error = gi_do_hfile_trunc(ip->i_sbd, gi, from_user); + else if (strcmp(arg0, "do_quota_sync") == 0) + error = gi_do_quota_sync(ip->i_sbd, gi); + else if (strcmp(arg0, "do_quota_refresh") == 0) + error = gi_do_quota_refresh(ip->i_sbd, gi, from_user); + else if (strcmp(arg0, "do_quota_read") == 0) + error = gi_do_quota_read(ip->i_sbd, gi, from_user); + else + error = -ENOTTY; + + return error; +} + +/** + * gfs_ioctl_i - Normal ioctls + * @ip: + * @arg: + * + * Returns: -errno or positive byte count + */ + +int +gfs_ioctl_i(struct gfs_inode *ip, void *arg) +{ + struct gfs_ioctl *gi_user = (struct gfs_ioctl *)arg; + struct gfs_ioctl gi; + char **argv; + char arg0[ARG_SIZE]; + int error = -EFAULT; + + if (copy_from_user(&gi, gi_user, sizeof(struct gfs_ioctl))) + return -EFAULT; + if (!gi.gi_argc) + return -EINVAL; + argv = kmalloc(gi.gi_argc * sizeof(char *), GFP_KERNEL); + if (!argv) + return -ENOMEM; + if (copy_from_user(argv, gi.gi_argv, + gi.gi_argc * sizeof(char *))) + goto out; + gi.gi_argv = argv; + + if (strncpy_from_user(arg0, argv[0], ARG_SIZE) < 0) + goto out; + arg0[ARG_SIZE - 1] = 0; + error = gfs_ioctl_i_local(ip, &gi, arg0, 1); + out: + kfree(argv); + + return error; +} + +#ifdef CONFIG_COMPAT +/** + * gfs_ioctl_i_compat - compatibility ioctls + * These ioctls are used to provide ioctls for situations + * where userland and kernel arch is different. + * For example, userland may be 32-bit ppc whereas the + * kernel may be ppc64. In this case, we need to do + * extra translation between the addresses. + * @ip: + * @arg: + * + * Returns: -errno or positive byte count + */ + +int +gfs_ioctl_i_compat(struct gfs_inode *ip, unsigned long arg) +{ + struct gfs_ioctl_compat *src; + struct gfs_ioctl dst; + char **argv, *argptr; + uint32_t *ptr; + char arg0[ARG_SIZE]; + char *tmparg; + int i; + int error = -EFAULT; + + src = (struct gfs_ioctl_compat *)compat_ptr(arg); + + memset(&dst, 0, sizeof(dst)); + dst.gi_argc = src->gi_argc; + dst.gi_size = src->gi_size; + dst.gi_offset = src->gi_offset; + + argv = kmalloc(dst.gi_argc * sizeof(char *), GFP_KERNEL); + if (!argv) + return -ENOMEM; + + memset(argv, 0, dst.gi_argc * sizeof(char *)); + ptr = (uint32_t *)compat_ptr(src->gi_argv); + + for (i = 0; i < dst.gi_argc; i++) { /* for each parm */ + tmparg = kmalloc(ARG_SIZE * sizeof(char *), GFP_KERNEL); + if (!tmparg) + goto out; + argptr = (char *)compat_ptr(*ptr); + if (strncpy_from_user(tmparg, argptr, ARG_SIZE) < 0) + goto out; + argv[i] = tmparg; + ptr++; + } + + strncpy(arg0, argv[0], ARG_SIZE); + arg0[ARG_SIZE - 1] = 0; + dst.gi_argv = argv; + dst.gi_data = compat_ptr(src->gi_data); + error = gfs_ioctl_i_local(ip, &dst, arg0, 0); + out: + for (i = 0; i < dst.gi_argc; i++) + kfree(argv[i]); + kfree(argv); + return error; +} +#endif --- linux-2.6.28.orig/ubuntu/gfs/ioctl.h +++ linux-2.6.28/ubuntu/gfs/ioctl.h @@ -0,0 +1,9 @@ +#ifndef __IOCTL_DOT_H__ +#define __IOCTL_DOT_H__ + +int gfs_ioctl_i_local(struct gfs_inode *ip, struct gfs_ioctl *gi, + const char *arg0, int from_user); +int gfs_ioctl_i_compat(struct gfs_inode *ip, unsigned long arg); +int gfs_ioctl_i(struct gfs_inode *ip, void *arg); + +#endif /* __IOCTL_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/unlinked.h +++ linux-2.6.28/ubuntu/gfs/unlinked.h @@ -0,0 +1,19 @@ +#ifndef __UNLINKED_DOT_H__ +#define __UNLINKED_DOT_H__ + +struct gfs_unlinked *gfs_unlinked_get(struct gfs_sbd *sdp, + struct gfs_inum *inum, int create); +void gfs_unlinked_hold(struct gfs_sbd *sdp, struct gfs_unlinked *ul); +void gfs_unlinked_put(struct gfs_sbd *sdp, struct gfs_unlinked *ul); + +void gfs_unlinked_lock(struct gfs_sbd *sdp, struct gfs_unlinked *ul); +void gfs_unlinked_unlock(struct gfs_sbd *sdp, struct gfs_unlinked *ul); + +void gfs_unlinked_merge(struct gfs_sbd *sdp, unsigned int type, + struct gfs_inum *inum); +void gfs_unlinked_cleanup(struct gfs_sbd *sdp); + +void gfs_unlinked_limit(struct gfs_sbd *sdp); +void gfs_unlinked_dealloc(struct gfs_sbd *sdp); + +#endif /* __UNLINKED_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/glock.h +++ linux-2.6.28/ubuntu/gfs/glock.h @@ -0,0 +1,137 @@ +#ifndef __GFS_GLOCK_DOT_H__ +#define __GFS_GLOCK_DOT_H__ + +/* Flags for lock requests; used in gfs_holder gh_flag field. */ +/* These are defined in lm_interface.h, commented out here. +#define LM_FLAG_TRY (0x00000001) +#define LM_FLAG_TRY_1CB (0x00000002) +#define LM_FLAG_NOEXP (0x00000004) +#define LM_FLAG_ANY (0x00000008) +#define LM_FLAG_PRIORITY (0x00000010) + These are defined here. */ +#define GL_LOCAL_EXCL (0x00000020) /* Only one holder may be granted the + * lock on this node, even if SHARED */ +#define GL_ASYNC (0x00000040) /* Don't block waiting for lock ... + * must poll to wait for grant */ +#define GL_EXACT (0x00000080) /* Requested state must == current state + * for lock to be granted */ +#define GL_SKIP (0x00000100) /* Don't read from disk after grant */ +#define GL_ATIME (0x00000200) /* Update inode's ATIME after grant */ +#define GL_NOCACHE (0x00000400) /* Release glock when done, don't cache */ +#define GL_SYNC (0x00000800) /* Sync to disk when no more holders */ +#define GL_NOCANCEL (0x00001000) /* Don't ever cancel this request */ +#define GL_READPAGE (0x00002000) /* gfs_readpage() issued this lock request */ +#define GL_NOCANCEL_OTHER (0x00004000) /* Don't cancel other locks for this */ + +#define GLR_TRYFAILED (13) +#define GLR_CANCELED (14) + +static __inline__ struct gfs_holder* +gfs_glock_is_locked_by_me(struct gfs_glock *gl) +{ + struct list_head *tmp, *head; + struct gfs_holder *gh; + + /* Look in glock's list of holders for one with current task as owner */ + spin_lock(&gl->gl_spin); + for (head = &gl->gl_holders, tmp = head->next; + tmp != head; + tmp = tmp->next) { + gh = list_entry(tmp, struct gfs_holder, gh_list); + if (gh->gh_owner == current) + goto out; + } + gh = NULL; +out: + spin_unlock(&gl->gl_spin); + return gh; +} +static __inline__ int +gfs_glock_is_held_excl(struct gfs_glock *gl) +{ + return (gl->gl_state == LM_ST_EXCLUSIVE); +} +static __inline__ int +gfs_glock_is_held_dfrd(struct gfs_glock *gl) +{ + return (gl->gl_state == LM_ST_DEFERRED); +} +static __inline__ int +gfs_glock_is_held_shrd(struct gfs_glock *gl) +{ + return (gl->gl_state == LM_ST_SHARED); +} + +static __inline__ int +gfs_glock_is_blocking(struct gfs_glock *gl) +{ + int ret; + spin_lock(&gl->gl_spin); + ret = !list_empty(&gl->gl_waiters2) || !list_empty(&gl->gl_waiters3); + spin_unlock(&gl->gl_spin); + return ret; +} + +struct gfs_glock *gfs_glock_find(struct gfs_sbd *sdp, + struct lm_lockname *name); +int gfs_glock_get(struct gfs_sbd *sdp, + uint64_t number, struct gfs_glock_operations *glops, + int create, struct gfs_glock **glp); +void gfs_glock_hold(struct gfs_glock *gl); +void gfs_glock_put(struct gfs_glock *gl); + +void gfs_holder_init(struct gfs_glock *gl, unsigned int state, int flags, + struct gfs_holder *gh); +void gfs_holder_reinit(unsigned int state, int flags, struct gfs_holder *gh); +void gfs_holder_uninit(struct gfs_holder *gh); +struct gfs_holder *gfs_holder_get(struct gfs_glock *gl, unsigned int state, + int flags); +void gfs_holder_put(struct gfs_holder *gh); + +void gfs_glock_xmote_th(struct gfs_glock *gl, unsigned int state, int flags); +void gfs_glock_drop_th(struct gfs_glock *gl); + +int gfs_glock_nq(struct gfs_holder *gh); +int gfs_glock_poll(struct gfs_holder *gh); +int gfs_glock_wait(struct gfs_holder *gh); +void gfs_glock_dq(struct gfs_holder *gh); + +void gfs_glock_prefetch(struct gfs_glock *gl, unsigned int state, int flags); +void gfs_glock_force_drop(struct gfs_glock *gl); + +int gfs_glock_be_greedy(struct gfs_glock *gl, unsigned int time); + +int gfs_glock_nq_init(struct gfs_glock *gl, unsigned int state, int flags, + struct gfs_holder *gh); +void gfs_glock_dq_uninit(struct gfs_holder *gh); +int gfs_glock_nq_num(struct gfs_sbd *sdp, + uint64_t number, struct gfs_glock_operations *glops, + unsigned int state, int flags, struct gfs_holder *gh); + +int gfs_glock_nq_m(unsigned int num_gh, struct gfs_holder *ghs); +void gfs_glock_dq_m(unsigned int num_gh, struct gfs_holder *ghs); + +void gfs_glock_prefetch_num(struct gfs_sbd *sdp, + uint64_t number, struct gfs_glock_operations *glops, + unsigned int state, int flags); + +/* Lock Value Block functions */ + +int gfs_lvb_hold(struct gfs_glock *gl); +void gfs_lvb_unhold(struct gfs_glock *gl); +void gfs_lvb_sync(struct gfs_glock *gl); + +void gfs_glock_cb(void *fsdata, unsigned int type, void *data); + +void gfs_try_toss_inode(struct gfs_sbd *sdp, struct gfs_inum *inum); +void gfs_iopen_go_callback(struct gfs_glock *gl, unsigned int state); + +void gfs_glock_schedule_for_reclaim(struct gfs_glock *gl); +void gfs_reclaim_glock(struct gfs_sbd *sdp); + +void gfs_scand_internal(struct gfs_sbd *sdp); +void gfs_gl_hash_clear(struct gfs_sbd *sdp, int wait); + +int gfs_dump_lockstate(struct gfs_sbd *sdp, struct gfs_user_buffer *ub); + +#endif /* __GFS_GLOCK_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/ondisk.c +++ linux-2.6.28/ubuntu/gfs/ondisk.c @@ -0,0 +1,15 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" + +#define pv(struct, member, fmt) printk(" "#member" = "fmt"\n", struct->member); + +#define WANT_GFS_CONVERSION_FUNCTIONS +#include "gfs_ondisk.h" + --- linux-2.6.28.orig/ubuntu/gfs/lock_nolock_main.c +++ linux-2.6.28/ubuntu/gfs/lock_nolock_main.c @@ -0,0 +1,230 @@ +/* + * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. + * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License version 2. + */ + +#include +#include +#include +#include +#include +#include "lm_interface.h" + +struct nolock_lockspace { + unsigned int nl_lvb_size; +}; + +static const struct lm_lockops nolock_ops; + +static int nolock_mount(char *table_name, char *host_data, + lm_callback_t cb, void *cb_data, + unsigned int min_lvb_size, int flags, + struct lm_lockstruct *lockstruct, + struct kobject *fskobj) +{ + char *c; + unsigned int jid; + struct nolock_lockspace *nl; + + c = strstr(host_data, "jid="); + if (!c) + jid = 0; + else { + c += 4; + sscanf(c, "%u", &jid); + } + + nl = kzalloc(sizeof(struct nolock_lockspace), GFP_KERNEL); + if (!nl) + return -ENOMEM; + + nl->nl_lvb_size = min_lvb_size; + + lockstruct->ls_jid = jid; + lockstruct->ls_first = 1; + lockstruct->ls_lvb_size = min_lvb_size; + lockstruct->ls_lockspace = nl; + lockstruct->ls_ops = &nolock_ops; + lockstruct->ls_flags = LM_LSFLAG_LOCAL; + + return 0; +} + +static void nolock_others_may_mount(void *lockspace) +{ +} + +static void nolock_unmount(void *lockspace) +{ + struct nolock_lockspace *nl = lockspace; + kfree(nl); +} + +static void nolock_withdraw(void *lockspace) +{ +} + +/** + * nolock_get_lock - get a lm_lock_t given a descripton of the lock + * @lockspace: the lockspace the lock lives in + * @name: the name of the lock + * @lockp: return the lm_lock_t here + * + * Returns: 0 on success, -EXXX on failure + */ + +static int nolock_get_lock(void *lockspace, struct lm_lockname *name, + void **lockp) +{ + *lockp = lockspace; + return 0; +} + +/** + * nolock_put_lock - get rid of a lock structure + * @lock: the lock to throw away + * + */ + +static void nolock_put_lock(void *lock) +{ +} + +/** + * nolock_lock - acquire a lock + * @lock: the lock to manipulate + * @cur_state: the current state + * @req_state: the requested state + * @flags: modifier flags + * + * Returns: A bitmap of LM_OUT_* + */ + +static unsigned int nolock_lock(void *lock, unsigned int cur_state, + unsigned int req_state, unsigned int flags) +{ + return req_state | LM_OUT_CACHEABLE; +} + +/** + * nolock_unlock - unlock a lock + * @lock: the lock to manipulate + * @cur_state: the current state + * + * Returns: 0 + */ + +static unsigned int nolock_unlock(void *lock, unsigned int cur_state) +{ + return 0; +} + +static void nolock_cancel(void *lock) +{ +} + +/** + * nolock_hold_lvb - hold on to a lock value block + * @lock: the lock the LVB is associated with + * @lvbp: return the lm_lvb_t here + * + * Returns: 0 on success, -EXXX on failure + */ + +static int nolock_hold_lvb(void *lock, char **lvbp) +{ + struct nolock_lockspace *nl = lock; + int error = 0; + + *lvbp = kzalloc(nl->nl_lvb_size, GFP_NOFS); + if (!*lvbp) + error = -ENOMEM; + + return error; +} + +/** + * nolock_unhold_lvb - release a LVB + * @lock: the lock the LVB is associated with + * @lvb: the lock value block + * + */ + +static void nolock_unhold_lvb(void *lock, char *lvb) +{ + kfree(lvb); +} + +static int nolock_plock_get(void *lockspace, struct lm_lockname *name, + struct file *file, struct file_lock *fl) +{ + posix_test_lock(file, fl); + + return 0; +} + +static int nolock_plock(void *lockspace, struct lm_lockname *name, + struct file *file, int cmd, struct file_lock *fl) +{ + int error; + error = posix_lock_file_wait(file, fl); + return error; +} + +static int nolock_punlock(void *lockspace, struct lm_lockname *name, + struct file *file, struct file_lock *fl) +{ + int error; + error = posix_lock_file_wait(file, fl); + return error; +} + +static void nolock_recovery_done(void *lockspace, unsigned int jid, + unsigned int message) +{ +} + +static const struct lm_lockops nolock_ops = { + .lm_proto_name = "lock_nolock", + .lm_mount = nolock_mount, + .lm_others_may_mount = nolock_others_may_mount, + .lm_unmount = nolock_unmount, + .lm_withdraw = nolock_withdraw, + .lm_get_lock = nolock_get_lock, + .lm_put_lock = nolock_put_lock, + .lm_lock = nolock_lock, + .lm_unlock = nolock_unlock, + .lm_cancel = nolock_cancel, + .lm_hold_lvb = nolock_hold_lvb, + .lm_unhold_lvb = nolock_unhold_lvb, + .lm_plock_get = nolock_plock_get, + .lm_plock = nolock_plock, + .lm_punlock = nolock_punlock, + .lm_recovery_done = nolock_recovery_done, + .lm_owner = THIS_MODULE, +}; + +int init_nolock() +{ + int error; + + error = gfs_register_lockproto(&nolock_ops); + if (error) { + printk(KERN_WARNING + "lock_nolock: can't register protocol: %d\n", error); + return error; + } + + printk(KERN_INFO + "Lock_Nolock (built %s %s) installed\n", __DATE__, __TIME__); + return 0; +} + +void exit_nolock() +{ + gfs_unregister_lockproto(&nolock_ops); +} --- linux-2.6.28.orig/ubuntu/gfs/unlinked.c +++ linux-2.6.28/ubuntu/gfs/unlinked.c @@ -0,0 +1,432 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "inode.h" +#include "log.h" +#include "lops.h" +#include "unlinked.h" + +/** + * gfs_unlinked_get - Get a structure to represent an unlinked inode + * @sdp: the filesystem + * @inum: identifies the inode that's unlinked + * @create: if TRUE, we're allowed to create the structure if we can't find it, + * otherwise return NULL + * + * Returns: the structure, or NULL + * + * Search the filesystem's list of gfs_unlinked to find a match. + * If none found, create a new one and place on list. + */ + +struct gfs_unlinked * +gfs_unlinked_get(struct gfs_sbd *sdp, struct gfs_inum *inum, int create) +{ + struct gfs_unlinked *ul = NULL, *new_ul = NULL; + struct list_head *tmp, *head; + + for (;;) { + spin_lock(&sdp->sd_unlinked_lock); + + for (head = &sdp->sd_unlinked_list, tmp = head->next; + tmp != head; + tmp = tmp->next) { + ul = list_entry(tmp, struct gfs_unlinked, ul_list); + if (gfs_inum_equal(&ul->ul_inum, inum)) { + ul->ul_count++; + break; + } + } + + if (tmp == head) + ul = NULL; + + /* 2nd pass, still not there; add the new_ul we prepared */ + if (!ul && new_ul) { + ul = new_ul; + list_add(&ul->ul_list, &sdp->sd_unlinked_list); + new_ul = NULL; + } + + spin_unlock(&sdp->sd_unlinked_lock); + + /* 1st pass; we found pre-existing, OR not allowed to create. + 2nd pass; another process added it, or we did */ + if (ul || !create) { + if (new_ul) + /* someone beat us to it; forget our new_ul */ + kfree(new_ul); + return ul; + } + + /* No match on list, 1st time through loop. + Prepare new_ul, then repeat loop to find out if another + process has created or unlinked an inode and put its + gfs_unlinked on list while we've been preparing this one. */ + new_ul = gmalloc(sizeof(struct gfs_unlinked)); + memset(new_ul, 0, sizeof(struct gfs_unlinked)); + + new_ul->ul_count = 1; + new_ul->ul_inum = *inum; + + INIT_LE(&new_ul->ul_new_le, &gfs_unlinked_lops); + INIT_LE(&new_ul->ul_incore_le, &gfs_unlinked_lops); + INIT_LE(&new_ul->ul_ondisk_le, &gfs_unlinked_lops); + } +} + +/** + * gfs_unlinked_hold - increment the usage count on a struct gfs_unlinked + * @sdp: the filesystem + * @ul: the structure + * + */ + +void +gfs_unlinked_hold(struct gfs_sbd *sdp, struct gfs_unlinked *ul) +{ + spin_lock(&sdp->sd_unlinked_lock); + gfs_assert(sdp, ul->ul_count,); + ul->ul_count++; + spin_unlock(&sdp->sd_unlinked_lock); +} + +/** + * gfs_unlinked_put - decrement the usage count on a struct gfs_unlinked + * @sdp: the filesystem + * @ul: the structure + * + * Free the structure if its reference count hits zero. + * + */ + +void +gfs_unlinked_put(struct gfs_sbd *sdp, struct gfs_unlinked *ul) +{ + spin_lock(&sdp->sd_unlinked_lock); + + gfs_assert(sdp, ul->ul_count,); + ul->ul_count--; + + if (!ul->ul_count) { + gfs_assert_warn(sdp, + !test_bit(ULF_IC_LIST, &ul->ul_flags) && + !test_bit(ULF_OD_LIST, &ul->ul_flags) && + !test_bit(ULF_LOCK, &ul->ul_flags)); + list_del(&ul->ul_list); + spin_unlock(&sdp->sd_unlinked_lock); + kfree(ul); + } else + spin_unlock(&sdp->sd_unlinked_lock); +} + +/** + * unlinked_find - Find a inode to try to deallocate + * @sdp: the filesystem + * + * The returned structure is locked and needs to be unlocked + * with gfs_unlinked_unlock(). + * + * Returns: A unlinked structure, or NULL + */ + +struct gfs_unlinked * +unlinked_find(struct gfs_sbd *sdp) +{ + struct list_head *tmp, *head; + struct gfs_unlinked *ul = NULL; + + if (test_bit(SDF_ROFS, &sdp->sd_flags)) + return NULL; + + gfs_log_lock(sdp); + spin_lock(&sdp->sd_unlinked_lock); + + if (!atomic_read(&sdp->sd_unlinked_ic_count)) + goto out; + + for (head = &sdp->sd_unlinked_list, tmp = head->next; + tmp != head; + tmp = tmp->next) { + ul = list_entry(tmp, struct gfs_unlinked, ul_list); + + if (test_bit(ULF_LOCK, &ul->ul_flags)) + continue; + if (!test_bit(ULF_IC_LIST, &ul->ul_flags)) + continue; + + list_move_tail(&ul->ul_list, &sdp->sd_unlinked_list); + + set_bit(ULF_LOCK, &ul->ul_flags); + ul->ul_count++; + + goto out; + } + + ul = NULL; + + out: + spin_unlock(&sdp->sd_unlinked_lock); + gfs_log_unlock(sdp); + + return ul; +} + +/** + * gfs_unlinked_lock - lock a unlinked structure + * @sdp: the filesystem + * @ul: the unlinked inode structure + * + */ + +void +gfs_unlinked_lock(struct gfs_sbd *sdp, struct gfs_unlinked *ul) +{ + spin_lock(&sdp->sd_unlinked_lock); + + gfs_assert_warn(sdp, !test_bit(ULF_LOCK, &ul->ul_flags)); + set_bit(ULF_LOCK, &ul->ul_flags); + + ul->ul_count++; + + spin_unlock(&sdp->sd_unlinked_lock); +} + +/** + * gfs_unlinked_unlock - drop a reference on a unlinked structure + * @sdp: the filesystem + * @ul: the unlinked inode structure + * + */ + +void +gfs_unlinked_unlock(struct gfs_sbd *sdp, struct gfs_unlinked *ul) +{ + spin_lock(&sdp->sd_unlinked_lock); + + gfs_assert_warn(sdp, test_bit(ULF_LOCK, &ul->ul_flags)); + clear_bit(ULF_LOCK, &ul->ul_flags); + + gfs_assert(sdp, ul->ul_count,); + ul->ul_count--; + + if (!ul->ul_count) { + gfs_assert_warn(sdp, !test_bit(ULF_IC_LIST, &ul->ul_flags) && + !test_bit(ULF_OD_LIST, &ul->ul_flags)); + list_del(&ul->ul_list); + spin_unlock(&sdp->sd_unlinked_lock); + kfree(ul); + } else + spin_unlock(&sdp->sd_unlinked_lock); +} + +/** + * gfs_unlinked_merge - add/remove a unlinked inode from the in-memory list + * @sdp: the filesystem + * @type: is this a unlink tag or a dealloc tag + * @inum: the inode number + * + * Called during journal recovery. + */ + +void +gfs_unlinked_merge(struct gfs_sbd *sdp, unsigned int type, + struct gfs_inum *inum) +{ + struct gfs_unlinked *ul; + + gfs_assert(sdp, atomic_read(&sdp->sd_unlinked_ic_count) == + atomic_read(&sdp->sd_unlinked_od_count),); + + ul = gfs_unlinked_get(sdp, inum, CREATE); + + gfs_log_lock(sdp); + + switch (type) { + case GFS_LOG_DESC_IUL: + gfs_unlinked_hold(sdp, ul); + gfs_unlinked_hold(sdp, ul); + gfs_assert(sdp, !test_bit(ULF_IC_LIST, &ul->ul_flags) && + !test_bit(ULF_OD_LIST, &ul->ul_flags),); + set_bit(ULF_IC_LIST, &ul->ul_flags); + set_bit(ULF_OD_LIST, &ul->ul_flags); + atomic_inc(&sdp->sd_unlinked_ic_count); + atomic_inc(&sdp->sd_unlinked_od_count); + + break; + + case GFS_LOG_DESC_IDA: + gfs_assert(sdp, test_bit(ULF_IC_LIST, &ul->ul_flags) && + test_bit(ULF_OD_LIST, &ul->ul_flags),); + clear_bit(ULF_IC_LIST, &ul->ul_flags); + clear_bit(ULF_OD_LIST, &ul->ul_flags); + gfs_unlinked_put(sdp, ul); + gfs_unlinked_put(sdp, ul); + gfs_assert(sdp, atomic_read(&sdp->sd_unlinked_ic_count) > 0,); + atomic_dec(&sdp->sd_unlinked_ic_count); + gfs_assert(sdp, atomic_read(&sdp->sd_unlinked_od_count) > 0,); + atomic_dec(&sdp->sd_unlinked_od_count); + + break; + } + + gfs_log_unlock(sdp); + + gfs_unlinked_put(sdp, ul); +} + +/** + * gfs_unlinked_cleanup - get rid of any extra struct gfs_unlinked structures + * @sdp: the filesystem + * + */ + +void +gfs_unlinked_cleanup(struct gfs_sbd *sdp) +{ + struct gfs_unlinked *ul; + + restart: + gfs_log_lock(sdp); + + gfs_assert(sdp, atomic_read(&sdp->sd_unlinked_ic_count) == + atomic_read(&sdp->sd_unlinked_od_count),); + + spin_lock(&sdp->sd_unlinked_lock); + + while (!list_empty(&sdp->sd_unlinked_list)) { + ul = list_entry(sdp->sd_unlinked_list.next, + struct gfs_unlinked, ul_list); + + if (ul->ul_count > 2) { + spin_unlock(&sdp->sd_unlinked_lock); + gfs_log_unlock(sdp); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ); + goto restart; + } + gfs_assert(sdp, ul->ul_count == 2,); + + gfs_assert_warn(sdp, + test_bit(ULF_IC_LIST, &ul->ul_flags) && + test_bit(ULF_OD_LIST, &ul->ul_flags) && + !test_bit(ULF_LOCK, &ul->ul_flags)); + + list_del(&ul->ul_list); + + atomic_dec(&sdp->sd_unlinked_ic_count); + atomic_dec(&sdp->sd_unlinked_od_count); + + spin_unlock(&sdp->sd_unlinked_lock); + kfree(ul); + spin_lock(&sdp->sd_unlinked_lock); + } + + spin_unlock(&sdp->sd_unlinked_lock); + + gfs_assert(sdp, !atomic_read(&sdp->sd_unlinked_ic_count) && + !atomic_read(&sdp->sd_unlinked_od_count),); + + gfs_log_unlock(sdp); +} + +/** + * gfs_unlinked_limit - limit the number of inodes waiting to be deallocated + * @sdp: the filesystem + * + * Returns: errno + */ + +void +gfs_unlinked_limit(struct gfs_sbd *sdp) +{ + unsigned int tries = 0, min = 0; + int error; + + if (atomic_read(&sdp->sd_unlinked_ic_count) >= + gfs_tune_get(sdp, gt_ilimit2)) { + tries = gfs_tune_get(sdp, gt_ilimit2_tries); + min = gfs_tune_get(sdp, gt_ilimit2_min); + } else if (atomic_read(&sdp->sd_unlinked_ic_count) >= + gfs_tune_get(sdp, gt_ilimit1)) { + tries = gfs_tune_get(sdp, gt_ilimit1_tries); + min = gfs_tune_get(sdp, gt_ilimit1_min); + } + + while (tries--) { + struct gfs_unlinked *ul = unlinked_find(sdp); + if (!ul) + break; + + error = gfs_inode_dealloc(sdp, &ul->ul_inum); + + gfs_unlinked_unlock(sdp, ul); + + if (!error) { + if (!--min) + break; + } else if (error != 1) + break; + } +} + +/** + * gfs_unlinked_dealloc - Go through the list of inodes to be deallocated + * @sdp: the filesystem + * + * Returns: errno + */ + +void +gfs_unlinked_dealloc(struct gfs_sbd *sdp) +{ + unsigned int hits, strikes; + int error; + + for (;;) { + hits = 0; + strikes = 0; + + for (;;) { + struct gfs_unlinked *ul = unlinked_find(sdp); + if (!ul) + return; + + error = gfs_inode_dealloc(sdp, &ul->ul_inum); + + gfs_unlinked_unlock(sdp, ul); + + if (!error) { + hits++; + if (strikes) + strikes--; + } else if (error == 1) { + strikes++; + if (strikes >= atomic_read(&sdp->sd_unlinked_ic_count)) { + error = 0; + break; + } + } else + goto out; + } + + if (!hits || kthread_should_stop()) + break; + + cond_resched(); + } + + out: + if (error && + error != -EROFS && + !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) + printk("GFS: fsid=%s: error deallocating inodes: %d\n", + sdp->sd_fsname, error); +} --- linux-2.6.28.orig/ubuntu/gfs/ops_file.h +++ linux-2.6.28/ubuntu/gfs/ops_file.h @@ -0,0 +1,9 @@ +#ifndef __OPS_FILE_DOT_H__ +#define __OPS_FILE_DOT_H__ + +extern struct file_operations gfs_file_fops; +extern struct file_operations gfs_dir_fops; +extern struct file_operations gfs_file_fops_nolock; +extern struct file_operations gfs_dir_fops_nolock; + +#endif /* __OPS_FILE_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/rgrp.c +++ linux-2.6.28/ubuntu/gfs/rgrp.c @@ -0,0 +1,2152 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "bits.h" +#include "dio.h" +#include "file.h" +#include "glock.h" +#include "glops.h" +#include "rgrp.h" +#include "super.h" +#include "trans.h" + +/** + * mhc_hash: find the mhc hash bucket for a buffer + * @bh: the buffer + * + * Returns: The bucket number + */ + +static unsigned int +mhc_hash(struct buffer_head *bh) +{ + uint64_t blkno; + unsigned int h; + + blkno = bh->b_blocknr; + h = gfs_hash(&blkno, sizeof(uint64_t)) & GFS_MHC_HASH_MASK; + + return h; +} + +/** + * mhc_trim - Throw away cached meta-headers, if there are too many of them + * @sdp: The filesystem instance + * @max: Max # of cached meta-headers allowed to survive + * + * Walk filesystem's list of cached meta-headers, in least-recently-used order, + * and keep throwing them away until we're under the max threshold. + */ + +static void +mhc_trim(struct gfs_sbd *sdp, unsigned int max) +{ + struct gfs_meta_header_cache *mc; + + for (;;) { + spin_lock(&sdp->sd_mhc_lock); + if (list_empty(&sdp->sd_mhc_single)) { + spin_unlock(&sdp->sd_mhc_lock); + return; + } else { + mc = list_entry(sdp->sd_mhc_single.prev, + struct gfs_meta_header_cache, + mc_list_single); + list_del(&mc->mc_list_hash); + list_del(&mc->mc_list_single); + list_del(&mc->mc_list_rgd); + spin_unlock(&sdp->sd_mhc_lock); + + kmem_cache_free(gfs_mhc_cachep, mc); + atomic_dec(&sdp->sd_mhc_count); + + if (atomic_read(&sdp->sd_mhc_count) <= max) + return; + } + } +} + +/** + * gfs_mhc_add - add buffer(s) to the cache of metadata headers + * @rgd: Resource Group in which the buffered block(s) reside + * @bh: an array of buffer_head pointers + * @num: the number of bh pointers in the array + * + * Increment each meta-header's generation # by 2. + * Alloc and add each gfs_meta-header_cache to 3 lists/caches: + * Filesystem's meta-header cache (hash) + * Filesystem's list of cached meta-headers + * Resource Group's list of cached meta-headers + * If we now have too many cached, throw some older ones away + */ + +void +gfs_mhc_add(struct gfs_rgrpd *rgd, + struct buffer_head **bh, unsigned int num) +{ + struct gfs_sbd *sdp = rgd->rd_sbd; + unsigned int x; + + for (x = 0; x < num; x++) { + struct gfs_meta_header_cache *mc; + struct list_head *head; + uint64_t gen; + + if (gfs_meta_check(sdp, bh[x])) + return; + + mc = kmem_cache_alloc(gfs_mhc_cachep, GFP_KERNEL); + if (!mc) + return; + memset(mc, 0, sizeof(struct gfs_meta_header_cache)); + + mc->mc_block = bh[x]->b_blocknr; + memcpy(&mc->mc_mh, bh[x]->b_data, + sizeof(struct gfs_meta_header)); + + gen = gfs64_to_cpu(mc->mc_mh.mh_generation) + 2; + mc->mc_mh.mh_generation = cpu_to_gfs64(gen); + + head = &sdp->sd_mhc[mhc_hash(bh[x])]; + + spin_lock(&sdp->sd_mhc_lock); + list_add(&mc->mc_list_hash, head); + list_add(&mc->mc_list_single, &sdp->sd_mhc_single); + list_add(&mc->mc_list_rgd, &rgd->rd_mhc); + spin_unlock(&sdp->sd_mhc_lock); + + atomic_inc(&sdp->sd_mhc_count); + } + + x = gfs_tune_get(sdp, gt_max_mhc); + + /* If we've got too many cached, throw some older ones away */ + if (atomic_read(&sdp->sd_mhc_count) > x) + mhc_trim(sdp, x); +} + +/** + * gfs_mhc_fish - Try to fill in a meta buffer with meta-header from the cache + * @sdp: the filesystem + * @bh: the buffer to fill in + * + * Returns: TRUE if the buffer was cached, FALSE otherwise + * + * If buffer is referenced in meta-header cache (search using hash): + * Copy the cached meta-header into the buffer (instead of reading from disk). + * Note that only the meta-header portion of the buffer will have valid data + * (as would be on disk), rest of buffer does *not* reflect disk contents. + * Remove cached gfs_meta_header_cache from all cache lists, free its memory. + */ + +int +gfs_mhc_fish(struct gfs_sbd *sdp, struct buffer_head *bh) +{ + struct list_head *tmp, *head; + struct gfs_meta_header_cache *mc; + + head = &sdp->sd_mhc[mhc_hash(bh)]; + + spin_lock(&sdp->sd_mhc_lock); + + for (tmp = head->next; + tmp != head; + tmp = tmp->next) { + mc = list_entry(tmp, struct gfs_meta_header_cache, mc_list_hash); + if (mc->mc_block != bh->b_blocknr) + continue; + + list_del(&mc->mc_list_hash); + list_del(&mc->mc_list_single); + list_del(&mc->mc_list_rgd); + spin_unlock(&sdp->sd_mhc_lock); + + gfs_prep_new_buffer(bh); + memcpy(bh->b_data, &mc->mc_mh, + sizeof(struct gfs_meta_header)); + + kmem_cache_free(gfs_mhc_cachep, mc); + atomic_dec(&sdp->sd_mhc_count); + + return TRUE; + } + + spin_unlock(&sdp->sd_mhc_lock); + + return FALSE; +} + +/** + * gfs_mhc_zap - Throw away an RG's list of cached metadata headers + * @rgd: The resource group whose list we want to clear + * + * Simply throw away all cached metadata headers on RG's list, + * and free their memory. + */ + +void +gfs_mhc_zap(struct gfs_rgrpd *rgd) +{ + struct gfs_sbd *sdp = rgd->rd_sbd; + struct gfs_meta_header_cache *mc; + + spin_lock(&sdp->sd_mhc_lock); + + while (!list_empty(&rgd->rd_mhc)) { + mc = list_entry(rgd->rd_mhc.next, + struct gfs_meta_header_cache, + mc_list_rgd); + + list_del(&mc->mc_list_hash); + list_del(&mc->mc_list_single); + list_del(&mc->mc_list_rgd); + spin_unlock(&sdp->sd_mhc_lock); + + kmem_cache_free(gfs_mhc_cachep, mc); + atomic_dec(&sdp->sd_mhc_count); + + spin_lock(&sdp->sd_mhc_lock); + } + + spin_unlock(&sdp->sd_mhc_lock); +} + +/** + * depend_hash() - Turn glock number into hash bucket number + * @formal_ino: + * + * Returns: The number of the corresponding hash bucket + */ + +static unsigned int +depend_hash(uint64_t formal_ino) +{ + unsigned int h; + + h = gfs_hash(&formal_ino, sizeof(uint64_t)); + h &= GFS_DEPEND_HASH_MASK; + + return h; +} + +/** + * depend_sync_one - Sync metadata (not data) for a dependency inode + * @sdp: filesystem instance + * @gd: dependency descriptor + * + * Remove dependency from superblock's hash table and rgrp's list. + * Sync dependency inode's metadata to log and in-place location. + */ + +static void +depend_sync_one(struct gfs_sbd *sdp, struct gfs_depend *gd) +{ + struct gfs_glock *gl; + + spin_lock(&sdp->sd_depend_lock); + list_del(&gd->gd_list_hash); + spin_unlock(&sdp->sd_depend_lock); + list_del(&gd->gd_list_rgd); + + gl = gfs_glock_find(sdp, + &(struct lm_lockname){gd->gd_formal_ino, + LM_TYPE_INODE}); + if (gl) { + if (gl->gl_ops->go_sync) + gl->gl_ops->go_sync(gl, + DIO_METADATA | + DIO_INVISIBLE); + gfs_glock_put(gl); + } + + kfree(gd); + atomic_dec(&sdp->sd_depend_count); +} + +/** + * depend_sync_old - Sync older rgrp-dependent inodes to disk. + * @rgd: Resource group containing dependent inodes + * + * Look at oldest entries in resource group's dependency list, + * sync 'em if they're older than timeout threshold. + */ + +static void +depend_sync_old(struct gfs_rgrpd *rgd) +{ + struct gfs_sbd *sdp = rgd->rd_sbd; + struct gfs_depend *gd; + + while (!list_empty(&rgd->rd_depend)) { + /* Oldest entries are in prev direction */ + gd = list_entry(rgd->rd_depend.prev, + struct gfs_depend, + gd_list_rgd); + + if (time_before(jiffies, + gd->gd_time + + gfs_tune_get(sdp, gt_depend_secs) * HZ)) + return; + + depend_sync_one(sdp, gd); + } +} + +/** + * gfs_depend_add - Add a dependent inode to rgrp's and filesystem's list + * @rgd: Resource group containing blocks associated with inode + * @formal_ino: inode + * + * Dependent inodes must be flushed to log and in-place blocks before + * releasing an EXCLUSIVE rgrp lock. + * Find pre-existing dependency for this inode/rgrp combination in + * incore superblock struct's sd_depend hash table, or create a new one. + * Either way, move or attach dependency to head of superblock's hash bucket + * and top of rgrp's list. + * If we create a new one, take a moment to sync older dependencies to disk. + */ + +void +gfs_depend_add(struct gfs_rgrpd *rgd, uint64_t formal_ino) +{ + struct gfs_sbd *sdp = rgd->rd_sbd; + struct list_head *head, *tmp; + struct gfs_depend *gd; + + head = &sdp->sd_depend[depend_hash(formal_ino)]; + + spin_lock(&sdp->sd_depend_lock); + + for (tmp = head->next; + tmp != head; + tmp = tmp->next) { + gd = list_entry(tmp, struct gfs_depend, gd_list_hash); + if (gd->gd_rgd == rgd && + gd->gd_formal_ino == formal_ino) { + list_move(&gd->gd_list_hash, head); + spin_unlock(&sdp->sd_depend_lock); + list_move(&gd->gd_list_rgd, &rgd->rd_depend); + gd->gd_time = jiffies; + return; + } + } + + spin_unlock(&sdp->sd_depend_lock); + + gd = gmalloc(sizeof(struct gfs_depend)); + memset(gd, 0, sizeof(struct gfs_depend)); + + gd->gd_rgd = rgd; + gd->gd_formal_ino = formal_ino; + gd->gd_time = jiffies; + + spin_lock(&sdp->sd_depend_lock); + list_add(&gd->gd_list_hash, head); + spin_unlock(&sdp->sd_depend_lock); + list_add(&gd->gd_list_rgd, &rgd->rd_depend); + + atomic_inc(&sdp->sd_depend_count); + + depend_sync_old(rgd); +} + +/** + * gfs_depend_sync - Sync metadata (not data) for an rgrp's dependent inodes + * @rgd: Resource group containing the dependent inodes + * + * As long as this node owns an EXCLUSIVE lock on the rgrp, we can keep + * rgrp's modified metadata blocks in buffer cache. + * + * When this node releases the EX lock, we must flush metadata, so other + * nodes can read the modified content from disk. + */ + +void +gfs_depend_sync(struct gfs_rgrpd *rgd) +{ + struct gfs_sbd *sdp = rgd->rd_sbd; + struct gfs_depend *gd; + + while (!list_empty(&rgd->rd_depend)) { + gd = list_entry(rgd->rd_depend.next, + struct gfs_depend, + gd_list_rgd); + depend_sync_one(sdp, gd); + } +} + +/** + * rgrp_verify - Verify that a resource group is consistent + * @sdp: the filesystem + * @rgd: the rgrp + * + * Somebody should have already called gfs_glock_rg() on this RG. + */ + +static void +rgrp_verify(struct gfs_rgrpd *rgd) +{ + struct gfs_sbd *sdp = rgd->rd_sbd; + struct gfs_bitmap *bits = NULL; + uint32_t length = rgd->rd_ri.ri_length; + uint32_t count[4], tmp; + int buf, x; + + memset(count, 0, 4 * sizeof(uint32_t)); + + /* Count # blocks in each of 4 possible allocation states */ + for (buf = 0; buf < length; buf++) { + bits = &rgd->rd_bits[buf]; + for (x = 0; x < 4; x++) + count[x] += gfs_bitcount(rgd, + rgd->rd_bh[buf]->b_data + + bits->bi_offset, + bits->bi_len, x); + } + + if (count[0] != rgd->rd_rg.rg_free) { + if (gfs_consist_rgrpd(rgd)) + printk("GFS: fsid=%s: free data mismatch: %u != %u\n", + sdp->sd_fsname, count[0], rgd->rd_rg.rg_free); + return; + } + + tmp = rgd->rd_ri.ri_data - + (rgd->rd_rg.rg_usedmeta + rgd->rd_rg.rg_freemeta) - + (rgd->rd_rg.rg_useddi + rgd->rd_rg.rg_freedi) - + rgd->rd_rg.rg_free; + if (count[1] != tmp) { + if (gfs_consist_rgrpd(rgd)) + printk("GFS: fsid=%s: used data mismatch: %u != %u\n", + sdp->sd_fsname, count[1], tmp); + return; + } + + if (count[2] != rgd->rd_rg.rg_freemeta) { + if (gfs_consist_rgrpd(rgd)) + printk("GFS: fsid=%s: free metadata mismatch: %u != %u\n", + sdp->sd_fsname, count[2], rgd->rd_rg.rg_freemeta); + return; + } + + tmp = rgd->rd_rg.rg_usedmeta + + (rgd->rd_rg.rg_useddi + rgd->rd_rg.rg_freedi); + if (count[3] != tmp) { + if (gfs_consist_rgrpd(rgd)) + printk("GFS: fsid=%s: used metadata mismatch: %u != %u\n", + sdp->sd_fsname, count[3], tmp); + return; + } +} + +/** + * gfs_blk2rgrpd - Find resource group for a given data/meta block number + * @sdp: The GFS superblock + * @n: The data block number + * + * Returns: The resource group, or NULL if not found + * + * Don't try to use this for non-allocatable block numbers (i.e. rgrp header + * or bitmap blocks); it's for allocatable (data/meta) blocks only. + */ + +struct gfs_rgrpd * +gfs_blk2rgrpd(struct gfs_sbd *sdp, uint64_t blk) +{ + struct list_head *tmp, *head; + struct gfs_rgrpd *rgd = NULL; + struct gfs_rindex *ri; + + spin_lock(&sdp->sd_rg_mru_lock); + + for (head = &sdp->sd_rg_mru_list, tmp = head->next; + tmp != head; + tmp = tmp->next) { + rgd = list_entry(tmp, struct gfs_rgrpd, rd_list_mru); + ri = &rgd->rd_ri; + + if (ri->ri_data1 <= blk && blk < ri->ri_data1 + ri->ri_data) { + list_move(&rgd->rd_list_mru, &sdp->sd_rg_mru_list); + spin_unlock(&sdp->sd_rg_mru_lock); + return rgd; + } + } + + spin_unlock(&sdp->sd_rg_mru_lock); + + return NULL; +} + +/** + * gfs_rgrpd_get_first - get the first Resource Group in the filesystem + * @sdp: The GFS superblock + * + * Returns: The first rgrp in the filesystem + */ + +struct gfs_rgrpd * +gfs_rgrpd_get_first(struct gfs_sbd *sdp) +{ + gfs_assert(sdp, !list_empty(&sdp->sd_rglist),); + return list_entry(sdp->sd_rglist.next, struct gfs_rgrpd, rd_list); +} + +/** + * gfs_rgrpd_get_next - get the next RG + * @rgd: A RG + * + * Returns: The next rgrp + */ + +struct gfs_rgrpd * +gfs_rgrpd_get_next(struct gfs_rgrpd *rgd) +{ + if (rgd->rd_list.next == &rgd->rd_sbd->sd_rglist) + return NULL; + return list_entry(rgd->rd_list.next, struct gfs_rgrpd, rd_list); +} + +/** + * clear_rgrpdi - Clear up rgrps + * @sdp: The GFS superblock + * + */ + +void +clear_rgrpdi(struct gfs_sbd *sdp) +{ + struct gfs_rgrpd *rgd; + struct gfs_glock *gl; + + spin_lock(&sdp->sd_rg_forward_lock); + sdp->sd_rg_forward = NULL; + spin_unlock(&sdp->sd_rg_forward_lock); + + spin_lock(&sdp->sd_rg_recent_lock); + while (!list_empty(&sdp->sd_rg_recent)) { + rgd = list_entry(sdp->sd_rg_recent.next, + struct gfs_rgrpd, rd_recent); + list_del(&rgd->rd_recent); + } + spin_unlock(&sdp->sd_rg_recent_lock); + + while (!list_empty(&sdp->sd_rglist)) { + rgd = list_entry(sdp->sd_rglist.next, + struct gfs_rgrpd, rd_list); + gl = rgd->rd_gl; + + list_del(&rgd->rd_list); + list_del(&rgd->rd_list_mru); + + if (gl) { + gfs_glock_force_drop(gl); + if (atomic_read(&gl->gl_lvb_count)) + gfs_lvb_unhold(gl); + set_gl2rgd(gl, NULL); + gfs_glock_put(gl); + } + + if (rgd->rd_bits) + kfree(rgd->rd_bits); + if (rgd->rd_bh) + kfree(rgd->rd_bh); + + kfree(rgd); + } +} + +/** + * gfs_clear_rgrpd - Clear up rgrps + * @sdp: The GFS superblock + * + */ + +void +gfs_clear_rgrpd(struct gfs_sbd *sdp) +{ + down(&sdp->sd_rindex_lock); + clear_rgrpdi(sdp); + up(&sdp->sd_rindex_lock); +} + +/** + * gfs_compute_bitstructs - Compute the bitmap sizes + * @rgd: The resource group descriptor + * + * Calculates bitmap descriptors, one for each block that contains bitmap data + * + * Returns: errno + */ + +static int +compute_bitstructs(struct gfs_rgrpd *rgd) +{ + struct gfs_sbd *sdp = rgd->rd_sbd; + struct gfs_bitmap *bits; + uint32_t length = rgd->rd_ri.ri_length; /* # blocks in hdr & bitmap */ + uint32_t bytes_left, bytes; + int x; + + rgd->rd_bits = kmalloc(length * sizeof(struct gfs_bitmap), GFP_KERNEL); + if (!rgd->rd_bits) + return -ENOMEM; + memset(rgd->rd_bits, 0, length * sizeof(struct gfs_bitmap)); + + bytes_left = rgd->rd_ri.ri_bitbytes; + + for (x = 0; x < length; x++) { + bits = &rgd->rd_bits[x]; + + /* small rgrp; bitmap stored completely in header block */ + if (length == 1) { + bytes = bytes_left; + bits->bi_offset = sizeof(struct gfs_rgrp); + bits->bi_start = 0; + bits->bi_len = bytes; + /* header block */ + } else if (x == 0) { + bytes = sdp->sd_sb.sb_bsize - sizeof(struct gfs_rgrp); + bits->bi_offset = sizeof(struct gfs_rgrp); + bits->bi_start = 0; + bits->bi_len = bytes; + /* last block */ + } else if (x + 1 == length) { + bytes = bytes_left; + bits->bi_offset = sizeof(struct gfs_meta_header); + bits->bi_start = rgd->rd_ri.ri_bitbytes - bytes_left; + bits->bi_len = bytes; + /* other blocks */ + } else { + bytes = sdp->sd_sb.sb_bsize - sizeof(struct gfs_meta_header); + bits->bi_offset = sizeof(struct gfs_meta_header); + bits->bi_start = rgd->rd_ri.ri_bitbytes - bytes_left; + bits->bi_len = bytes; + } + + bytes_left -= bytes; + } + + if (bytes_left) { + gfs_consist_rgrpd(rgd); + return -EIO; + } + if ((rgd->rd_bits[length - 1].bi_start + + rgd->rd_bits[length - 1].bi_len) * GFS_NBBY != + rgd->rd_ri.ri_data) { + if (gfs_consist_rgrpd(rgd)) { + gfs_rindex_print(&rgd->rd_ri); + printk("GFS: fsid=%s: start=%u len=%u offset=%u\n", + sdp->sd_fsname, + rgd->rd_bits[length - 1].bi_start, + rgd->rd_bits[length - 1].bi_len, + rgd->rd_bits[length - 1].bi_offset); + } + return -EIO; + } + + rgd->rd_bh = kmalloc(length * sizeof(struct buffer_head *), GFP_KERNEL); + if (!rgd->rd_bh) { + kfree(rgd->rd_bits); + rgd->rd_bits = NULL; + return -ENOMEM; + } + memset(rgd->rd_bh, 0, length * sizeof(struct buffer_head *)); + + return 0; +} + +/** + * gfs_ri_update - Pull in a new resource index from the disk + * @gl: The glock covering the rindex inode + * + * Returns: 0 on successful update, error code otherwise + */ + +static int +gfs_ri_update(struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_rgrpd *rgd; + char buf[sizeof(struct gfs_rindex)]; + int error; + + if (do_mod(ip->i_di.di_size, sizeof(struct gfs_rindex))) { + gfs_consist_inode(ip); + return -EIO; + } + + clear_rgrpdi(sdp); + + for (sdp->sd_rgcount = 0;; sdp->sd_rgcount++) { + error = gfs_internal_read(ip, buf, + sdp->sd_rgcount * + sizeof(struct gfs_rindex), + sizeof(struct gfs_rindex)); + if (!error) + break; + if (error != sizeof(struct gfs_rindex)) { + if (error > 0) + error = -EIO; + goto fail; + } + + rgd = kmalloc(sizeof(struct gfs_rgrpd), GFP_KERNEL); + error = -ENOMEM; + if (!rgd) + goto fail; + memset(rgd, 0, sizeof(struct gfs_rgrpd)); + + INIT_LIST_HEAD(&rgd->rd_mhc); + INIT_LIST_HEAD(&rgd->rd_depend); + rgd->rd_sbd = sdp; + + list_add_tail(&rgd->rd_list, &sdp->sd_rglist); + list_add_tail(&rgd->rd_list_mru, &sdp->sd_rg_mru_list); + + gfs_rindex_in(&rgd->rd_ri, buf); + + error = compute_bitstructs(rgd); + if (error) + goto fail; + + error = gfs_glock_get(sdp, rgd->rd_ri.ri_addr, &gfs_rgrp_glops, + CREATE, &rgd->rd_gl); + if (error) + goto fail; + + error = gfs_lvb_hold(rgd->rd_gl); + if (error) + goto fail; + + set_gl2rgd(rgd->rd_gl, rgd); + rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1; + } + + sdp->sd_riinode_vn = ip->i_gl->gl_vn; + + return 0; + + fail: + clear_rgrpdi(sdp); + + return error; +} + +/** + * gfs_rindex_hold - Grab a lock on the rindex + * @sdp: The GFS superblock + * @ri_gh: the glock holder + * + * We grab a lock on the rindex inode to make sure that it doesn't + * change whilst we are performing an operation. We keep this lock + * for quite long periods of time compared to other locks. This + * doesn't matter, since it is shared and it is very, very rarely + * accessed in the exclusive mode (i.e. only when expanding the filesystem). + * + * This makes sure that we're using the latest copy of the resource index + * special file, which might have been updated if someone expanded the + * filesystem (via gfs_grow utility), which adds new resource groups. + * + * Returns: 0 on success, error code otherwise + */ + +int +gfs_rindex_hold(struct gfs_sbd *sdp, struct gfs_holder *ri_gh) +{ + struct gfs_inode *ip = sdp->sd_riinode; + struct gfs_glock *gl = ip->i_gl; + int error; + + error = gfs_glock_nq_init(gl, LM_ST_SHARED, 0, ri_gh); + if (error) + return error; + + /* Read new copy from disk if we don't have the latest */ + if (sdp->sd_riinode_vn != gl->gl_vn) { + down(&sdp->sd_rindex_lock); + if (sdp->sd_riinode_vn != gl->gl_vn) { + error = gfs_ri_update(ip); + if (error) + gfs_glock_dq_uninit(ri_gh); + } + up(&sdp->sd_rindex_lock); + } + + return error; +} + +/** + * gfs_rgrp_read - Read in a RG's header and bitmaps + * @rgd: the struct gfs_rgrpd describing the RG to read in + * + * Read in all of a Resource Group's header and bitmap blocks. + * Caller must eventually call gfs_rgrp_relse() to free the bitmaps. + * + * Returns: errno + */ + +int +gfs_rgrp_read(struct gfs_rgrpd *rgd) +{ + struct gfs_sbd *sdp = rgd->rd_sbd; + struct gfs_glock *gl = rgd->rd_gl; + unsigned int x, length = rgd->rd_ri.ri_length; + int error; + + for (x = 0; x < length; x++) { + gfs_assert_warn(sdp, !rgd->rd_bh[x]); + rgd->rd_bh[x] = gfs_dgetblk(gl, rgd->rd_ri.ri_addr + x); + } + + for (x = 0; x < length; x++) { + error = gfs_dreread(sdp, rgd->rd_bh[x], DIO_START); + if (error) + goto fail; + } + + for (x = length; x--;) { + error = gfs_dreread(sdp, rgd->rd_bh[x], DIO_WAIT); + if (error) + goto fail; + if (gfs_metatype_check(sdp, rgd->rd_bh[x], + (x) ? GFS_METATYPE_RB : GFS_METATYPE_RG)) { + error = -EIO; + goto fail; + } + } + + if (rgd->rd_rg_vn != gl->gl_vn) { + gfs_rgrp_in(&rgd->rd_rg, (rgd->rd_bh[0])->b_data); + rgd->rd_rg_vn = gl->gl_vn; + } + + return 0; + + fail: + for (x = 0; x < length; x++) { + brelse(rgd->rd_bh[x]); + rgd->rd_bh[x] = NULL; + } + + return error; +} + +/** + * gfs_rgrp_relse - Release RG bitmaps read in with gfs_rgrp_read() + * @rgd: the struct gfs_rgrpd describing the RG to read in + * + */ + +void +gfs_rgrp_relse(struct gfs_rgrpd *rgd) +{ + int x, length = rgd->rd_ri.ri_length; + + for (x = 0; x < length; x++) { + brelse(rgd->rd_bh[x]); + rgd->rd_bh[x] = NULL; + } +} + +/** + * gfs_rgrp_lvb_fill - copy RG usage data out of the struct gfs_rgrp into the struct gfs_rgrp_lvb + * @rgd: the resource group data structure + * + */ + +void +gfs_rgrp_lvb_fill(struct gfs_rgrpd *rgd) +{ + struct gfs_rgrp *rg = &rgd->rd_rg; + struct gfs_rgrp_lvb *rb = (struct gfs_rgrp_lvb *)rgd->rd_gl->gl_lvb; + + rb->rb_magic = cpu_to_gfs32(GFS_MAGIC); + rb->rb_free = cpu_to_gfs32(rg->rg_free); + rb->rb_useddi = cpu_to_gfs32(rg->rg_useddi); + rb->rb_freedi = cpu_to_gfs32(rg->rg_freedi); + rb->rb_usedmeta = cpu_to_gfs32(rg->rg_usedmeta); + rb->rb_freemeta = cpu_to_gfs32(rg->rg_freemeta); +} + +/** + * gfs_rgrp_lvb_init - Init the data of a RG LVB + * @rgd: the resource group data structure + * + * Returns: errno + */ + +int +gfs_rgrp_lvb_init(struct gfs_rgrpd *rgd) +{ + struct gfs_glock *gl = rgd->rd_gl; + struct gfs_holder rgd_gh; + int error; + + error = gfs_glock_nq_init(gl, LM_ST_EXCLUSIVE, 0, &rgd_gh); + if (!error) { + gfs_rgrp_lvb_fill(rgd); + gfs_glock_dq_uninit(&rgd_gh); + } + + return error; +} + +/** + * gfs_alloc_get - allocate a struct gfs_alloc structure for an inode + * @ip: the incore GFS inode structure + * + * Alloc and zero an in-place reservation structure, + * and attach it to the GFS incore inode. + * + * FIXME: Don't use gmalloc() + * + * Returns: the struct gfs_alloc + */ + +struct gfs_alloc * +gfs_alloc_get(struct gfs_inode *ip) +{ + struct gfs_alloc *al = ip->i_alloc; + + gfs_assert_warn(ip->i_sbd, !al); + + al = gmalloc(sizeof(struct gfs_alloc)); + memset(al, 0, sizeof(struct gfs_alloc)); + + ip->i_alloc = al; + + return al; +} + +/** + * gfs_alloc_put - throw away the struct gfs_alloc for an inode + * @ip: the inode + * + */ + +void +gfs_alloc_put(struct gfs_inode *ip) +{ + struct gfs_alloc *al = ip->i_alloc; + + if (gfs_assert_warn(ip->i_sbd, al)) + return; + + ip->i_alloc = NULL; + kfree(al); +} + +/** + * try_rgrp_fit - See if a given reservation will fit in a given RG + * @rgd: the RG data + * @al: the struct gfs_alloc structure describing the reservation + * + * If there's room for the requested blocks to be allocated from the RG: + * Sets the $al_reserved_data field in @al. + * Sets the $al_reserved_meta field in @al. + * Sets the $al_rgd field in @al. + * + * Returns: 1 on success (it fits), 0 on failure (it doesn't fit) + */ + +static int +try_rgrp_fit(struct gfs_rgrpd *rgd, struct gfs_alloc *al) +{ + uint32_t freeblks = rgd->rd_rg.rg_free; + uint32_t freemeta = rgd->rd_rg.rg_freemeta; + uint32_t metares = al->al_requested_meta; + uint32_t datares = al->al_requested_data; + + /* First take care of the data blocks required */ + + if (freeblks < al->al_requested_data) + return 0; + + freeblks -= al->al_requested_data; + + /* Then take care of the dinodes */ + + metares += al->al_requested_di; + + /* Then take care of the metadata blocks */ + + while (freemeta < metares) { + if (freeblks < GFS_META_CLUMP) + return 0; + + freeblks -= GFS_META_CLUMP; + freemeta += GFS_META_CLUMP; + + datares += GFS_META_CLUMP; + } + + al->al_rgd = rgd; + al->al_reserved_meta = metares; + al->al_reserved_data = datares; + + return 1; +} + +/** + * recent_rgrp_first - get first RG from "recent" list + * @sdp: The GFS superblock + * @rglast: address of the rgrp used last + * + * Returns: The first rgrp in the recent list + */ + +static struct gfs_rgrpd * +recent_rgrp_first(struct gfs_sbd *sdp, uint64_t rglast) +{ + struct list_head *tmp, *head; + struct gfs_rgrpd *rgd = NULL; + + spin_lock(&sdp->sd_rg_recent_lock); + + if (list_empty(&sdp->sd_rg_recent)) + goto out; + + if (!rglast) + goto first; + + for (head = &sdp->sd_rg_recent, tmp = head->next; + tmp != head; + tmp = tmp->next) { + rgd = list_entry(tmp, struct gfs_rgrpd, rd_recent); + if (rgd->rd_ri.ri_addr == rglast) + goto out; + } + + first: + rgd = list_entry(sdp->sd_rg_recent.next, struct gfs_rgrpd, rd_recent); + + out: + spin_unlock(&sdp->sd_rg_recent_lock); + + 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 gfs_rgrpd * +recent_rgrp_next(struct gfs_rgrpd *cur_rgd, int remove) +{ + struct gfs_sbd *sdp = cur_rgd->rd_sbd; + struct list_head *tmp, *head; + struct gfs_rgrpd *rgd; + + spin_lock(&sdp->sd_rg_recent_lock); + + for (head = &sdp->sd_rg_recent, tmp = head->next; + tmp != head; + tmp = tmp->next) { + rgd = list_entry(tmp, struct gfs_rgrpd, rd_recent); + if (rgd == cur_rgd) { + if (cur_rgd->rd_recent.next != head) + rgd = list_entry(cur_rgd->rd_recent.next, + struct gfs_rgrpd, rd_recent); + else + rgd = NULL; + + if (remove) + list_del(&cur_rgd->rd_recent); + + goto out; + } + } + + rgd = NULL; + if (!list_empty(head)) + rgd = list_entry(head->next, struct gfs_rgrpd, rd_recent); + + out: + spin_unlock(&sdp->sd_rg_recent_lock); + + return rgd; +} + +/** + * recent_rgrp_add - add an RG to tail of "recent" list + * @new_rgd: The rgrp to add + * + * Before adding, make sure that: + * 1) it's not already on the list + * 2) there's still room for more entries + * The capacity limit imposed on the "recent" list is basically a node's "share" + * of rgrps within a cluster, i.e. (total # rgrps) / (# nodes (journals)) + */ + +static void +recent_rgrp_add(struct gfs_rgrpd *new_rgd) +{ + struct gfs_sbd *sdp = new_rgd->rd_sbd; + struct list_head *tmp, *head; + struct gfs_rgrpd *rgd = NULL; + unsigned int count = 0; + unsigned int max = sdp->sd_rgcount / gfs_num_journals(sdp); + + spin_lock(&sdp->sd_rg_recent_lock); + + for (head = &sdp->sd_rg_recent, tmp = head->next; + tmp != head; + tmp = tmp->next) { + rgd = list_entry(tmp, struct gfs_rgrpd, rd_recent); + if (rgd == new_rgd) + goto out; + + if (++count >= max) + goto out; + } + new_rgd->rd_try_counter = 0; + list_add_tail(&new_rgd->rd_recent, &sdp->sd_rg_recent); + + out: + spin_unlock(&sdp->sd_rg_recent_lock); +} + +/** + * forward_rgrp_get - get an rgrp to try next from full list + * @sdp: The GFS superblock + * + * Returns: The rgrp to try next + */ + +static struct gfs_rgrpd * +forward_rgrp_get(struct gfs_sbd *sdp) +{ + struct gfs_rgrpd *rgd; + unsigned int journals = gfs_num_journals(sdp); + unsigned int rg = 0, x; + + spin_lock(&sdp->sd_rg_forward_lock); + + rgd = sdp->sd_rg_forward; + if (!rgd) { + if (sdp->sd_rgcount >= journals) + rg = sdp->sd_rgcount * + sdp->sd_lockstruct.ls_jid / + journals; + + for (x = 0, rgd = gfs_rgrpd_get_first(sdp); + x < rg; + x++, rgd = gfs_rgrpd_get_next(rgd)) + /* Do Nothing */; + + sdp->sd_rg_forward = rgd; + } + + spin_unlock(&sdp->sd_rg_forward_lock); + + return rgd; +} + +/** + * forward_rgrp_set - set the forward rgrp pointer + * @sdp: the filesystem + * @rgd: The new forward rgrp + * + */ + +static void +forward_rgrp_set(struct gfs_sbd *sdp, struct gfs_rgrpd *rgd) +{ + spin_lock(&sdp->sd_rg_forward_lock); + sdp->sd_rg_forward = rgd; + spin_unlock(&sdp->sd_rg_forward_lock); +} + +/** + * get_local_rgrp - Choose and lock a rgrp for allocation + * @ip: the inode to reserve space for + * @rgp: the chosen and locked rgrp + * + * Try to acquire rgrp in way which avoids contending with others. + * + * Returns: errno + */ + +static int +get_local_rgrp(struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_rgrpd *rgd, *begin = NULL; + struct gfs_alloc *al = ip->i_alloc; + int flags = LM_FLAG_TRY; + int skipped = 0; + int loops = 0; + int error; + int try_flag; + unsigned int try_threshold = gfs_tune_get(sdp, gt_rgrp_try_threshold); + + /* Try recently successful rgrps */ + + rgd = recent_rgrp_first(sdp, ip->i_last_rg_alloc); + + while (rgd) { + try_flag = (rgd->rd_try_counter >= try_threshold) ? + 0: LM_FLAG_TRY; + error = gfs_glock_nq_init(rgd->rd_gl, + LM_ST_EXCLUSIVE, try_flag, + &al->al_rgd_gh); + switch (error) { + case 0: + if (try_rgrp_fit(rgd, al)) { + rgd->rd_try_counter = 0; + goto out; + } + gfs_glock_dq_uninit(&al->al_rgd_gh); + rgd = recent_rgrp_next(rgd, TRUE); + break; + + case GLR_TRYFAILED: + rgd->rd_try_counter++; + rgd = recent_rgrp_next(rgd, FALSE); + break; + + default: + return error; + } + } + + /* Go through full list of rgrps */ + + begin = rgd = forward_rgrp_get(sdp); + + for (;;) { + error = gfs_glock_nq_init(rgd->rd_gl, + LM_ST_EXCLUSIVE, flags, + &al->al_rgd_gh); + switch (error) { + case 0: + if (try_rgrp_fit(rgd, al)) + goto out; + gfs_glock_dq_uninit(&al->al_rgd_gh); + break; + + case GLR_TRYFAILED: + skipped++; + break; + + default: + return error; + } + + rgd = gfs_rgrpd_get_next(rgd); + if (!rgd) + rgd = gfs_rgrpd_get_first(sdp); + + if (rgd == begin) { + if (++loops >= 2 || !skipped) + return -ENOSPC; + flags = 0; + } + } + + out: + ip->i_last_rg_alloc = rgd->rd_ri.ri_addr; + + if (begin) { + recent_rgrp_add(rgd); + rgd = gfs_rgrpd_get_next(rgd); + if (!rgd) + rgd = gfs_rgrpd_get_first(sdp); + forward_rgrp_set(sdp, rgd); + } + + return 0; +} + +/** + * gfs_inplace_reserve_i - Reserve space in the filesystem + * @ip: the inode to reserve space for + * + * Acquire resource group locks to allow for the maximum allocation + * described by "res". + * + * This should probably become more complex again, but for now, let's go + * for simple (one resource group) reservations. + * + * Returns: errno + */ + +int +gfs_inplace_reserve_i(struct gfs_inode *ip, + char *file, unsigned int line) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al = ip->i_alloc; + int error; + + if (gfs_assert_warn(sdp, + al->al_requested_di || + al->al_requested_data || + al->al_requested_meta)) + return -EINVAL; + + error = gfs_rindex_hold(sdp, &al->al_ri_gh); + if (error) + return error; + + error = get_local_rgrp(ip); + if (error) { + gfs_glock_dq_uninit(&al->al_ri_gh); + return error; + } + + gfs_depend_sync(al->al_rgd); + + al->al_file = file; + al->al_line = line; + + return 0; +} + +/** + * gfs_inplace_release - release an inplace reservation + * @ip: the inode the reservation was taken out on + * + * Release a reservation made by gfs_inplace_reserve(). + */ + +void +gfs_inplace_release(struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al = ip->i_alloc; + + if (gfs_assert_warn(sdp, al->al_alloced_di <= al->al_requested_di) == -1) + printk("GFS: fsid=%s: al_alloced_di = %u, al_requested_di = %u\n" + "GFS: fsid=%s: al_file = %s, al_line = %u\n", + sdp->sd_fsname, al->al_alloced_di, al->al_requested_di, + sdp->sd_fsname, al->al_file, al->al_line); + if (gfs_assert_warn(sdp, al->al_alloced_meta <= al->al_reserved_meta) == -1) + printk("GFS: fsid=%s: al_alloced_meta = %u, al_reserved_meta = %u\n" + "GFS: fsid=%s: al_file = %s, al_line = %u\n", + sdp->sd_fsname, al->al_alloced_meta, al->al_reserved_meta, + sdp->sd_fsname, al->al_file, al->al_line); + if (gfs_assert_warn(sdp, al->al_alloced_data <= al->al_reserved_data) == -1) + printk("GFS: fsid=%s: al_alloced_data = %u, al_reserved_data = %u\n" + "GFS: fsid=%s: al_file = %s, al_line = %u\n", + sdp->sd_fsname, al->al_alloced_data, al->al_reserved_data, + sdp->sd_fsname, al->al_file, al->al_line); + + al->al_rgd = NULL; + gfs_glock_dq_uninit(&al->al_rgd_gh); + gfs_glock_dq_uninit(&al->al_ri_gh); +} + +/** + * gfs_get_block_type - Check a block in a RG is of given type + * @rgd: the resource group holding the block + * @block: the block number + * + * Returns: The block type (GFS_BLKST_*) + */ + +unsigned char +gfs_get_block_type(struct gfs_rgrpd *rgd, uint64_t block) +{ + struct gfs_bitmap *bits = NULL; + uint32_t length, rgrp_block, buf_block; + unsigned int buf; + unsigned char type; + + length = rgd->rd_ri.ri_length; + rgrp_block = block - rgd->rd_ri.ri_data1; + + for (buf = 0; buf < length; buf++) { + bits = &rgd->rd_bits[buf]; + if (rgrp_block < (bits->bi_start + bits->bi_len) * GFS_NBBY) + break; + } + + gfs_assert(rgd->rd_sbd, buf < length,); + buf_block = rgrp_block - bits->bi_start * GFS_NBBY; + + type = gfs_testbit(rgd, + rgd->rd_bh[buf]->b_data + bits->bi_offset, + bits->bi_len, buf_block); + + return type; +} + +/** + * blkalloc_internal - find a block in @old_state, change allocation + * state to @new_state + * @rgd: the resource group descriptor + * @goal: the goal block within the RG (start here to search for avail block) + * @old_state: GFS_BLKST_XXX the before-allocation state to find + * @new_state: GFS_BLKST_XXX the after-allocation block state + * + * Walk rgrp's bitmap to find bits that represent a block in @old_state. + * Add the found bitmap buffer to the transaction. + * Set the found bits to @new_state to change block's allocation state. + * + * This function never fails, because we wouldn't call it unless we + * know (from reservation results, etc.) that a block is available. + * + * Scope of @goal and returned block is just within rgrp (32-bit), + * not the whole filesystem (64-bit). + * + * Returns: the block # allocated (32-bit rgrp scope) + */ + +static uint32_t +blkalloc_internal(struct gfs_rgrpd *rgd, + uint32_t goal, + unsigned char old_state, unsigned char new_state) +{ + struct gfs_bitmap *bits = NULL; + uint32_t length = rgd->rd_ri.ri_length; + uint32_t blk = 0; + unsigned int buf, x; + + /* Find bitmap block that contains bits for goal block */ + for (buf = 0; buf < length; buf++) { + bits = &rgd->rd_bits[buf]; + if (goal < (bits->bi_start + bits->bi_len) * GFS_NBBY) + break; + } + + gfs_assert(rgd->rd_sbd, buf < length,); + + /* Convert scope of "goal" from rgrp-wide to within found bit block */ + goal -= bits->bi_start * GFS_NBBY; + + /* Search (up to entire) bitmap in this rgrp for allocatable block. + "x <= length", instead of "x < length", because we typically start + the search in the middle of a bit block, but if we can't find an + allocatable block anywhere else, we want to be able wrap around and + search in the first part of our first-searched bit block. */ + for (x = 0; x <= length; x++) { + blk = gfs_bitfit(rgd->rd_bh[buf]->b_data + bits->bi_offset, + bits->bi_len, goal, old_state); + if (blk != BFITNOENT) + break; + + /* Try next bitmap block (wrap back to rgrp header if at end) */ + buf = (buf + 1) % length; + bits = &rgd->rd_bits[buf]; + goal = 0; + } + + if (unlikely(x > length)) { + printk("GFS error: possible RG corruption\n"); + printk(" please run gfs_fsck after withdraw\n"); + dump_stack(); + if (gfs_assert_withdraw(rgd->rd_sbd, x <= length)) + blk = 0; + } + + /* Attach bitmap buffer to trans, modify bits to do block alloc */ + gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[buf]); + gfs_setbit(rgd, + rgd->rd_bh[buf]->b_data + bits->bi_offset, + bits->bi_len, blk, new_state); + + /* Return allocated block #, rgrp scope (32-bit) */ + return bits->bi_start * GFS_NBBY + blk; +} + +/** + * blkfree_internal - Change alloc state of given block(s) + * @sdp: the filesystem + * @bstart: first block (64-bit filesystem scope) of a run of contiguous blocks + * @blen: the length of the block run (all must lie within ONE RG!) + * @new_state: GFS_BLKST_XXX the after-allocation block state + * + * Returns: Resource group containing the block(s) + * + * Find rgrp containing @bstart. + * For each block in run: + * Find allocation bitmap buffer. + * Add bitmap buffer to transaction. + * Set bits to new state. + * Typically used to free blocks to GFS_BLKST_FREE or GFS_BLKST_FREEMETA, + * but @new_state can be any GFS_BLKST_XXX + * + */ + +static struct gfs_rgrpd * +blkfree_internal(struct gfs_sbd *sdp, uint64_t bstart, uint32_t blen, + unsigned char new_state) +{ + struct gfs_rgrpd *rgd; + struct gfs_bitmap *bits = NULL; + uint32_t length, rgrp_blk, buf_blk; + unsigned int buf; + + /* Find rgrp */ + rgd = gfs_blk2rgrpd(sdp, bstart); + if (!rgd) { + if (gfs_consist(sdp)) + printk("GFS: fsid=%s: block = %llu\n", + sdp->sd_fsname, bstart); + return NULL; + } + + length = rgd->rd_ri.ri_length; + + /* Convert blk # from filesystem scope (64-bit) to RG scope (32-bit) */ + rgrp_blk = bstart - rgd->rd_ri.ri_data1; + + while (blen--) { + /* Find bitmap buffer for this block */ + for (buf = 0; buf < length; buf++) { + bits = &rgd->rd_bits[buf]; + if (rgrp_blk < (bits->bi_start + bits->bi_len) * GFS_NBBY) + break; + } + + gfs_assert(rgd->rd_sbd, buf < length,); + + /* Find bits and set 'em */ + buf_blk = rgrp_blk - bits->bi_start * GFS_NBBY; + rgrp_blk++; + + gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[buf]); + gfs_setbit(rgd, + rgd->rd_bh[buf]->b_data + bits->bi_offset, + bits->bi_len, buf_blk, new_state); + } + + return rgd; +} + +/** + * clump_alloc - Allocate a clump of metadata blocks + * @rgd: the resource group in which to allocate + * @first: returns the first block allocated + * + * Returns: errno + * + * Bitmap-allocate a clump of metadata blocks + * Write metadata blocks to disk with dummy meta-headers + * Add meta-headers to incore meta-header cache + */ + +static int +clump_alloc(struct gfs_rgrpd *rgd, uint32_t *first) +{ + struct gfs_sbd *sdp = rgd->rd_sbd; + struct gfs_meta_header mh; + struct buffer_head **bh; + uint32_t goal, blk; + unsigned int x; + int error = 0; + + /* Dummy meta-header template */ + memset(&mh, 0, sizeof(struct gfs_meta_header)); + mh.mh_magic = GFS_MAGIC; + mh.mh_type = GFS_METATYPE_NONE; + + /* Array of bh pointers used in several steps */ + bh = gmalloc(GFS_META_CLUMP * sizeof(struct buffer_head *)); + memset(bh, 0, GFS_META_CLUMP * sizeof(struct buffer_head *)); + + /* Since we're looking for data blocks to change into meta blocks, + use last alloc'd *data* (not meta) block as start point */ + goal = rgd->rd_last_alloc_data; + + for (x = 0; x < GFS_META_CLUMP; x++) { + blk = blkalloc_internal(rgd, goal, GFS_BLKST_FREE, + GFS_BLKST_FREEMETA); + if (!x) + *first = blk; + + bh[x] = gfs_dgetblk(rgd->rd_gl, rgd->rd_ri.ri_data1 + blk); + + gfs_prep_new_buffer(bh[x]); + + gfs_meta_header_out(&mh, bh[x]->b_data); + ((struct gfs_meta_header *)bh[x]->b_data)->mh_generation = 0; + + /* start write of new meta-buffer to disk */ + error = gfs_dwrite(sdp, bh[x], DIO_DIRTY | DIO_START); + if (error) + goto out; + + goal = blk; + } + + /* Block alloc start point for next time */ + rgd->rd_last_alloc_data = goal; + + /* Wait for all new meta-buffers to get on-disk */ + for (x = 0; x < GFS_META_CLUMP; x++) { + error = gfs_dwrite(sdp, bh[x], DIO_WAIT); + if (error) + goto out; + } + + /* Add all new meta-headers to meta-header cache */ + gfs_mhc_add(rgd, bh, GFS_META_CLUMP); + + gfs_assert_withdraw(sdp, rgd->rd_rg.rg_free >= GFS_META_CLUMP); + rgd->rd_rg.rg_free -= GFS_META_CLUMP; + rgd->rd_rg.rg_freemeta += GFS_META_CLUMP; + + out: + for (x = 0; x < GFS_META_CLUMP; x++) + if (bh[x]) { + gfs_dwrite(sdp, bh[x], DIO_WAIT); + brelse(bh[x]); + } + kfree(bh); + + return error; +} + +/** + * gfs_blkalloc - Allocate a data block + * @ip: the inode to allocate the data block for + * @block: the block allocated + * + */ + +void +gfs_blkalloc(struct gfs_inode *ip, uint64_t *block) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al = ip->i_alloc; + struct gfs_rgrpd *rgd = al->al_rgd; + uint32_t goal, blk; + int same; + + same = (rgd->rd_ri.ri_addr == ip->i_di.di_goal_rgrp); + goal = (same) ? ip->i_di.di_goal_dblk : rgd->rd_last_alloc_data; + + blk = blkalloc_internal(rgd, goal, + GFS_BLKST_FREE, GFS_BLKST_USED); + rgd->rd_last_alloc_data = blk; + + if (!same) { + ip->i_di.di_goal_rgrp = rgd->rd_ri.ri_addr; + ip->i_di.di_goal_mblk = 0; + } + ip->i_di.di_goal_dblk = blk; + + *block = rgd->rd_ri.ri_data1 + blk; + + gfs_assert_withdraw(sdp, rgd->rd_rg.rg_free); + rgd->rd_rg.rg_free--; + + gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[0]); + gfs_rgrp_out(&rgd->rd_rg, rgd->rd_bh[0]->b_data); + + al->al_alloced_data++; + + gfs_trans_add_quota(sdp, +1, ip->i_di.di_uid, ip->i_di.di_gid); + + /* total=0, free=-1, dinodes=0 */ + gfs_statfs_modify(sdp, 0, -1, 0); +} + +/** + * gfs_metaalloc - Allocate a metadata block to a file + * @ip: the file + * @block: the block allocated + * + * Returns: errno + */ + +int +gfs_metaalloc(struct gfs_inode *ip, uint64_t *block) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al = ip->i_alloc; + struct gfs_rgrpd *rgd = al->al_rgd; + uint32_t goal, blk; + int same; + int error; + + same = (rgd->rd_ri.ri_addr == ip->i_di.di_goal_rgrp); + + if (!rgd->rd_rg.rg_freemeta) { + error = clump_alloc(rgd, &goal); + if (error) + return error; + + al->al_alloced_data += GFS_META_CLUMP; + } else + goal = (same) ? ip->i_di.di_goal_mblk : rgd->rd_last_alloc_meta; + + blk = blkalloc_internal(rgd, goal, + GFS_BLKST_FREEMETA, GFS_BLKST_USEDMETA); + rgd->rd_last_alloc_meta = blk; + + if (!same) { + ip->i_di.di_goal_rgrp = rgd->rd_ri.ri_addr; + ip->i_di.di_goal_dblk = 0; + } + ip->i_di.di_goal_mblk = blk; + + *block = rgd->rd_ri.ri_data1 + blk; + + gfs_assert_withdraw(sdp, rgd->rd_rg.rg_freemeta); + rgd->rd_rg.rg_freemeta--; + rgd->rd_rg.rg_usedmeta++; + + gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[0]); + gfs_rgrp_out(&rgd->rd_rg, rgd->rd_bh[0]->b_data); + + al->al_alloced_meta++; + + gfs_trans_add_quota(sdp, +1, ip->i_di.di_uid, ip->i_di.di_gid); + + /* total=0, free=-1, dinode=0 */ + gfs_statfs_modify(sdp, 0, -1, 0); + + return 0; +} + +/** + * gfs_dialloc - Allocate a dinode + * @dip: the directory that the inode is going in + * @block: the block (result) which this function allocates as the dinode + * (64-bit filesystem scope) + * + * Returns: errno + */ + +int +gfs_dialloc(struct gfs_inode *dip, uint64_t *block) +{ + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_alloc *al = dip->i_alloc; + struct gfs_rgrpd *rgd = al->al_rgd; + uint32_t goal, blk; + int error = 0; + + if (rgd->rd_rg.rg_freemeta) + /* pick up where we left off last time */ + goal = rgd->rd_last_alloc_meta; + else { + /* no free meta blocks, allocate a bunch more */ + error = clump_alloc(rgd, &goal); + if (error) + return error; + + al->al_alloced_data += GFS_META_CLUMP; + } + + /* Alloc the dinode; 32-bit "blk" is block offset within rgrp */ + blk = blkalloc_internal(rgd, goal, + GFS_BLKST_FREEMETA, GFS_BLKST_USEDMETA); + + /* remember where we left off, for next time */ + rgd->rd_last_alloc_meta = blk; + + /* convert from rgrp scope (32-bit) to filesystem scope (64-bit) */ + *block = rgd->rd_ri.ri_data1 + blk; + + gfs_assert_withdraw(rgd->rd_sbd, rgd->rd_rg.rg_freemeta); + rgd->rd_rg.rg_freemeta--; + rgd->rd_rg.rg_useddi++; + + /* Attach rgrp header to trans, update freemeta and useddi stats */ + gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[0]); + gfs_rgrp_out(&rgd->rd_rg, rgd->rd_bh[0]->b_data); + + /* Update stats in in-place reservation struct */ + al->al_alloced_di++; + al->al_alloced_meta++; + + /* total=0, free=-1, dinodes=1 */ + gfs_statfs_modify(sdp, 0, -1, +1); + + return error; +} + +/** + * gfs_blkfree - free a contiguous run of data block(s) + * @ip: the inode these blocks are being freed from + * @bstart: first block (64-bit filesystem scope) of a run of contiguous blocks + * @blen: the length of the block run (all must lie within ONE RG!) + * + * Bitmap-deallocate the blocks (to FREE data state), add bitmap blks to trans + * Update rgrp alloc statistics in rgrp header, add rgrp header buf to trans + * Update quotas, add to trans. + */ + +void +gfs_blkfree(struct gfs_inode *ip, uint64_t bstart, uint32_t blen) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_rgrpd *rgd; + + rgd = blkfree_internal(sdp, bstart, blen, GFS_BLKST_FREE); + if (!rgd) + return; + + rgd->rd_rg.rg_free += blen; + + gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[0]); + gfs_rgrp_out(&rgd->rd_rg, rgd->rd_bh[0]->b_data); + + gfs_trans_add_quota(sdp, -(int64_t)blen, + ip->i_di.di_uid, + ip->i_di.di_gid); + + /* total=0, free=+blen, dinodes=0 */ + gfs_statfs_modify(sdp, 0, blen, 0); +} + +/** + * gfs_metafree - free a contiguous run of metadata block(s) + * @ip: the inode these blocks are being freed from + * @bstart: first block (64-bit filesystem scope) of a run of contiguous blocks + * @blen: the length of the block run (all must lie within ONE RG!) + * + * Bitmap-deallocate the blocks (to FREEMETA state), add bitmap blks to trans. + * Update rgrp alloc statistics in rgrp header, add rgrp header to trans. + * Update quotas (quotas include metadata, not just data block usage), + * add to trans. + * Release deallocated buffers, add to meta-header cache (we save these in-core + * so we don't need to re-read meta blocks if/when they are re-alloc'd). + */ + +void +gfs_metafree(struct gfs_inode *ip, uint64_t bstart, uint32_t blen) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_rgrpd *rgd; + + rgd = blkfree_internal(sdp, bstart, blen, GFS_BLKST_FREEMETA); + if (!rgd) + return; + + if (rgd->rd_rg.rg_usedmeta < blen) + gfs_consist_rgrpd(rgd); + rgd->rd_rg.rg_usedmeta -= blen; + rgd->rd_rg.rg_freemeta += blen; + + gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[0]); + gfs_rgrp_out(&rgd->rd_rg, rgd->rd_bh[0]->b_data); + + /* total=0, free=blen, dinode=0 */ + gfs_statfs_modify(sdp, 0, blen, 0); + + gfs_trans_add_quota(sdp, -(int64_t)blen, + ip->i_di.di_uid, + ip->i_di.di_gid); + gfs_wipe_buffers(ip, rgd, bstart, blen); +} + +/** + * gfs_difree_uninit - free a dinode block + * @rgd: the resource group that contains the dinode + * @addr: the dinode address + * + * De-allocate the dinode to FREEMETA using block alloc bitmap. + * Update rgrp's block usage statistics (used dinode--, free meta++). + * Add rgrp header to transaction. + */ + +void +gfs_difree_uninit(struct gfs_rgrpd *rgd, uint64_t addr) +{ + struct gfs_rgrpd *tmp_rgd; + + tmp_rgd = blkfree_internal(rgd->rd_sbd, addr, 1, + GFS_BLKST_FREEMETA); + if (!tmp_rgd) + return; + gfs_assert_withdraw(rgd->rd_sbd, rgd == tmp_rgd); + + if (!rgd->rd_rg.rg_useddi) + gfs_consist_rgrpd(rgd); + rgd->rd_rg.rg_useddi--; + rgd->rd_rg.rg_freemeta++; + + gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[0]); + gfs_rgrp_out(&rgd->rd_rg, rgd->rd_bh[0]->b_data); + + /* total=0, free=1, dinodes=-1 */ + gfs_statfs_modify(rgd->rd_sbd, 0, +1, -1); +} + +/** + * gfs_difree - free a dinode block + * @rgd: the resource group that contains the dinode + * @ip: the inode representing the dinode to free + * + * Free the dinode block to FREEMETA, update rgrp's block usage stats. + * Update quotas (quotas include metadata, not just data block usage), + * add to trans. + * Release deallocated buffers, add to meta-header cache (we save these in-core + * so we don't need to re-read meta blocks if/when they are re-alloc'd). + */ + +void +gfs_difree(struct gfs_rgrpd *rgd, struct gfs_inode *ip) +{ + gfs_difree_uninit(rgd, ip->i_num.no_addr); + gfs_trans_add_quota(ip->i_sbd, -1, ip->i_di.di_uid, ip->i_di.di_gid); + gfs_wipe_buffers(ip, rgd, ip->i_num.no_addr, 1); +} + +/** + * gfs_rlist_add - add a RG to a list of RGs + * @sdp: the filesystem + * @rlist: the list of resource groups + * @block: the block + * + * Figure out what RG a block belongs to and add that RG to the list + * + * FIXME: Don't use gmalloc() + * + */ + +void +gfs_rlist_add(struct gfs_sbd *sdp, struct gfs_rgrp_list *rlist, uint64_t block) +{ + struct gfs_rgrpd *rgd; + struct gfs_rgrpd **tmp; + unsigned int new_space; + unsigned int x; + + if (gfs_assert_warn(sdp, !rlist->rl_ghs)) + return; + + rgd = gfs_blk2rgrpd(sdp, block); + if (!rgd) { + if (gfs_consist(sdp)) + printk("GFS: fsid=%s: block = %llu\n", + sdp->sd_fsname, block); + return; + } + + for (x = 0; x < rlist->rl_rgrps; x++) + if (rlist->rl_rgd[x] == rgd) + return; + + if (rlist->rl_rgrps == rlist->rl_space) { + new_space = rlist->rl_space + 10; + + tmp = gmalloc(new_space * sizeof(struct gfs_rgrpd *)); + + if (rlist->rl_rgd) { + memcpy(tmp, rlist->rl_rgd, + rlist->rl_space * sizeof(struct gfs_rgrpd *)); + kfree(rlist->rl_rgd); + } + + rlist->rl_space = new_space; + rlist->rl_rgd = tmp; + } + + rlist->rl_rgd[rlist->rl_rgrps++] = rgd; +} + +/** + * gfs_rlist_alloc - all RGs have been added to the rlist, now allocate + * and initialize an array of glock holders for them + * @rlist: the list of resource groups + * @state: the lock state to acquire the RG lock in + * @flags: the modifier flags for the holder structures + * + * FIXME: Don't use gmalloc() + * + */ + +void +gfs_rlist_alloc(struct gfs_rgrp_list *rlist, unsigned int state, int flags) +{ + unsigned int x; + + rlist->rl_ghs = gmalloc(rlist->rl_rgrps * sizeof(struct gfs_holder)); + for (x = 0; x < rlist->rl_rgrps; x++) + gfs_holder_init(rlist->rl_rgd[x]->rd_gl, + state, flags, + &rlist->rl_ghs[x]); +} + +/** + * gfs_rlist_free - free a resource group list + * @list: the list of resource groups + * + */ + +void +gfs_rlist_free(struct gfs_rgrp_list *rlist) +{ + unsigned int x; + + if (rlist->rl_rgd) + kfree(rlist->rl_rgd); + + if (rlist->rl_ghs) { + for (x = 0; x < rlist->rl_rgrps; x++) + gfs_holder_uninit(&rlist->rl_ghs[x]); + kfree(rlist->rl_ghs); + } +} + +/** + * gfs_reclaim_metadata - reclaims unused metadata + * @sdp: the file system + * @inodes: + * @metadata: + * + * This function will look through the resource groups and + * free the unused metadata. + * + * Returns: errno + */ + +int +gfs_reclaim_metadata(struct gfs_sbd *sdp, + uint64_t *inodes, + uint64_t *metadata) +{ + struct gfs_holder ji_gh, ri_gh, rgd_gh, t_gh; + struct gfs_rgrpd *rgd; + struct gfs_rgrp *rg; + struct gfs_dinode *di; + struct gfs_inum next; + struct buffer_head *bh; + uint32_t flags; + uint32_t goal; + unsigned int x; + int error = 0; + + *inodes = *metadata = 0; + + /* Acquire the jindex lock here so we don't deadlock with a + process writing the the jindex inode. :-( */ + + error = gfs_jindex_hold(sdp, &ji_gh); + if (error) + goto fail; + + error = gfs_rindex_hold(sdp, &ri_gh); + if (error) + goto fail_jindex_relse; + + for (rgd = gfs_rgrpd_get_first(sdp); + rgd; + rgd = gfs_rgrpd_get_next(rgd)) { + error = gfs_glock_nq_init(rgd->rd_gl, + LM_ST_EXCLUSIVE, GL_NOCACHE, + &rgd_gh); + if (error) + goto fail_rindex_relse; + + rgrp_verify(rgd); + + rg = &rgd->rd_rg; + + if (!rg->rg_freedi && !rg->rg_freemeta) { + gfs_glock_dq_uninit(&rgd_gh); + continue; + } + + gfs_mhc_zap(rgd); + gfs_depend_sync(rgd); + + error = gfs_lock_fs_check_clean(sdp, LM_ST_EXCLUSIVE, &t_gh); + if (error) + goto fail_gunlock_rg; + + error = gfs_trans_begin(sdp, rgd->rd_ri.ri_length, 0); + if (error) + goto fail_unlock_fs; + + next = rg->rg_freedi_list; + + for (x = rg->rg_freedi; x--;) { + if (!next.no_formal_ino || !next.no_addr) { + gfs_consist_rgrpd(rgd); + error = -EIO; + goto fail_end_trans; + } + + blkfree_internal(sdp, next.no_addr, 1, GFS_BLKST_FREE); + + error = gfs_dread(rgd->rd_gl, next.no_addr, + DIO_FORCE | DIO_START | DIO_WAIT, &bh); + if (error) + goto fail_end_trans; + + di = (struct gfs_dinode *)bh->b_data; + flags = di->di_flags; + flags = gfs32_to_cpu(flags); + if (!(flags & GFS_DIF_UNUSED)) { + gfs_consist_rgrpd(rgd); + brelse(bh); + error = -EIO; + goto fail_end_trans; + } + + gfs_inum_in(&next, (char *)&di->di_next_unused); + + brelse(bh); + + rg->rg_freedi--; + rg->rg_free++; + (*inodes)++; + } + + if (next.no_formal_ino || next.no_addr) { + gfs_consist_rgrpd(rgd); + error = -EIO; + goto fail_end_trans; + } + rg->rg_freedi_list = next; + + goal = 0; + for (x = rg->rg_freemeta; x--;) { + goal = blkalloc_internal(rgd, goal, + GFS_BLKST_FREEMETA, GFS_BLKST_FREE); + rg->rg_freemeta--; + rg->rg_free++; + (*metadata)++; + } + + gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[0]); + gfs_rgrp_out(rg, rgd->rd_bh[0]->b_data); + + gfs_trans_end(sdp); + + gfs_glock_dq_uninit(&t_gh); + + gfs_glock_dq_uninit(&rgd_gh); + } + + gfs_glock_dq_uninit(&ri_gh); + + gfs_glock_dq_uninit(&ji_gh); + + return 0; + + fail_end_trans: + gfs_trans_end(sdp); + + fail_unlock_fs: + gfs_glock_dq_uninit(&t_gh); + + fail_gunlock_rg: + gfs_glock_dq_uninit(&rgd_gh); + + fail_rindex_relse: + gfs_glock_dq_uninit(&ri_gh); + + fail_jindex_relse: + gfs_glock_dq_uninit(&ji_gh); + + fail: + return error; +} --- linux-2.6.28.orig/ubuntu/gfs/lvb.h +++ linux-2.6.28/ubuntu/gfs/lvb.h @@ -0,0 +1,53 @@ +/* + * Formats of Lock Value Blocks (LVBs) for various types of locks. + * These 32-bit data chunks can be shared quickly between nodes + * via the inter-node lock manager (via LAN instead of on-disk). + */ + +#ifndef __LVB_DOT_H__ +#define __LVB_DOT_H__ + +#define GFS_MIN_LVB_SIZE (32) + +/* + * Resource Group block allocation statistics + * Each resource group lock contains one of these in its LVB. + * Used for sharing approximate current statistics for statfs. + * Not used for actual block allocation. + */ +struct gfs_rgrp_lvb { + uint32_t rb_magic; /* GFS_MAGIC sanity check value */ + uint32_t rb_free; /* # free data blocks */ + uint32_t rb_useddi; /* # used dinode blocks */ + uint32_t rb_freedi; /* # free dinode blocks */ + uint32_t rb_usedmeta; /* # used metadata blocks */ + uint32_t rb_freemeta; /* # free metadata blocks */ +}; + +/* + * Quota + * Each quota lock contains one of these in its LVB. + * Keeps track of block allocation limits and current block allocation + * for either a cluster-wide user or a cluster-wide group. + */ +struct gfs_quota_lvb { + uint32_t qb_magic; /* GFS_MAGIC sanity check value */ + uint32_t qb_pad; + uint64_t qb_limit; /* Hard limit of # blocks to alloc */ + uint64_t qb_warn; /* Warn user when alloc is above this # */ + int64_t qb_value; /* Current # blocks allocated */ +}; + +/* Translation functions */ + +void gfs_rgrp_lvb_in(struct gfs_rgrp_lvb *rb, char *lvb); +void gfs_rgrp_lvb_out(struct gfs_rgrp_lvb *rb, char *lvb); +void gfs_quota_lvb_in(struct gfs_quota_lvb *qb, char *lvb); +void gfs_quota_lvb_out(struct gfs_quota_lvb *qb, char *lvb); + +/* Printing functions */ + +void gfs_rgrp_lvb_print(struct gfs_rgrp_lvb *rb); +void gfs_quota_lvb_print(struct gfs_quota_lvb *qb); + +#endif /* __LVB_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/mount.h +++ linux-2.6.28/ubuntu/gfs/mount.h @@ -0,0 +1,6 @@ +#ifndef __MOUNT_DOT_H__ +#define __MOUNT_DOT_H__ + +int gfs_make_args(char *data, struct gfs_args *args, int remount); + +#endif /* __MOUNT_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/daemon.h +++ linux-2.6.28/ubuntu/gfs/daemon.h @@ -0,0 +1,11 @@ +#ifndef __DAEMON_DOT_H__ +#define __DAEMON_DOT_H__ + +int gfs_scand(void *data); +int gfs_glockd(void *data); +int gfs_recoverd(void *data); +int gfs_logd(void *data); +int gfs_quotad(void *data); +int gfs_inoded(void *data); + +#endif /* __DAEMON_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/quota.h +++ linux-2.6.28/ubuntu/gfs/quota.h @@ -0,0 +1,28 @@ +#ifndef __QUOTA_DOT_H__ +#define __QUOTA_DOT_H__ + +#define NO_QUOTA_CHANGE ((uint32_t)-1) + +int gfs_quota_get(struct gfs_sbd *sdp, int user, uint32_t id, int create, + struct gfs_quota_data **qdp); +void gfs_quota_hold(struct gfs_sbd *sdp, struct gfs_quota_data *qd); +void gfs_quota_put(struct gfs_sbd *sdp, struct gfs_quota_data *qd); + +int gfs_quota_merge(struct gfs_sbd *sdp, struct gfs_quota_tag *tag); +void gfs_quota_scan(struct gfs_sbd *sdp); +void gfs_quota_cleanup(struct gfs_sbd *sdp); + +int gfs_quota_hold_m(struct gfs_inode *ip, uint32_t uid, uint32_t gid); +void gfs_quota_unhold_m(struct gfs_inode *ip); + +int gfs_quota_lock_m(struct gfs_inode *ip, uint32_t uid, uint32_t gid); +void gfs_quota_unlock_m(struct gfs_inode *ip); + +int gfs_quota_check(struct gfs_inode *ip, uint32_t uid, uint32_t gid); + +int gfs_quota_sync(struct gfs_sbd *sdp); +int gfs_quota_refresh(struct gfs_sbd *sdp, int user, uint32_t id); +int gfs_quota_read(struct gfs_sbd *sdp, int user, uint32_t id, + struct gfs_quota *q); + +#endif /* __QUOTA_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/ops_address.h +++ linux-2.6.28/ubuntu/gfs/ops_address.h @@ -0,0 +1,6 @@ +#ifndef __OPS_ADDRESS_DOT_H__ +#define __OPS_ADDRESS_DOT_H__ + +extern struct address_space_operations gfs_file_aops; + +#endif /* __OPS_ADDRESS_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/bmap.h +++ linux-2.6.28/ubuntu/gfs/bmap.h @@ -0,0 +1,35 @@ +#ifndef __BMAP_DOT_H__ +#define __BMAP_DOT_H__ + +typedef int (*gfs_unstuffer_t) (struct gfs_inode * ip, + struct buffer_head * dibh, uint64_t block, + void *private); + +int gfs_unstuffer_sync(struct gfs_inode *ip, struct buffer_head *dibh, + uint64_t block, void *private); +int gfs_unstuffer_async(struct gfs_inode *ip, struct buffer_head *dibh, + uint64_t block, void *private); + +int gfs_unstuff_dinode(struct gfs_inode *ip, gfs_unstuffer_t unstuffer, + void *private); + +int gfs_block_map(struct gfs_inode *ip, + uint64_t lblock, int *new, + uint64_t *dblock, uint32_t *extlen); + +typedef int (*gfs_truncator_t) (struct gfs_inode * ip, uint64_t size); + +int gfs_truncator_default(struct gfs_inode *ip, uint64_t size); + +int gfs_shrink(struct gfs_inode *ip, uint64_t size, gfs_truncator_t truncator); +int gfs_truncatei(struct gfs_inode *ip, uint64_t size, + gfs_truncator_t truncator); + +void gfs_write_calc_reserv(struct gfs_inode *ip, unsigned int len, + unsigned int *data_blocks, unsigned int *ind_blocks); +int gfs_write_alloc_required(struct gfs_inode *ip, uint64_t offset, + unsigned int len, int *alloc_required); + +int gfs_get_file_meta(struct gfs_inode *ip, struct gfs_user_buffer *ub); + +#endif /* __BMAP_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/super.c +++ linux-2.6.28/ubuntu/gfs/super.c @@ -0,0 +1,1274 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "dio.h" +#include "file.h" +#include "format.h" +#include "glock.h" +#include "glops.h" +#include "inode.h" +#include "log.h" +#include "quota.h" +#include "recovery.h" +#include "rgrp.h" +#include "super.h" +#include "unlinked.h" +#include "trans.h" + +/** + * gfs_tune_init - Fill a gfs_tune structure with default values + * @gt: tune + * + */ + +void +gfs_tune_init(struct gfs_tune *gt) +{ + spin_lock_init(>->gt_spin); + + gt->gt_ilimit1 = 100; + gt->gt_ilimit1_tries = 3; + gt->gt_ilimit1_min = 1; + gt->gt_ilimit2 = 500; + gt->gt_ilimit2_tries = 10; + gt->gt_ilimit2_min = 3; + gt->gt_demote_secs = 300; + gt->gt_incore_log_blocks = 1024; + gt->gt_jindex_refresh_secs = 60; + gt->gt_depend_secs = 60; + gt->gt_scand_secs = 5; + gt->gt_recoverd_secs = 60; + gt->gt_logd_secs = 1; + gt->gt_quotad_secs = 5; + gt->gt_inoded_secs = 15; + gt->gt_glock_purge = 0; + gt->gt_quota_simul_sync = 64; + gt->gt_quota_warn_period = 10; + gt->gt_atime_quantum = 3600; + gt->gt_quota_quantum = 60; + gt->gt_quota_scale_num = 1; + gt->gt_quota_scale_den = 1; + gt->gt_quota_enforce = 1; + gt->gt_quota_account = 1; + gt->gt_new_files_jdata = 0; + gt->gt_new_files_directio = 0; + gt->gt_max_atomic_write = 4 << 20; + gt->gt_max_readahead = 1 << 18; + gt->gt_lockdump_size = 131072; + gt->gt_stall_secs = 600; + gt->gt_complain_secs = 10; + gt->gt_reclaim_limit = 5000; + gt->gt_entries_per_readdir = 32; + gt->gt_prefetch_secs = 10; + gt->gt_statfs_slots = 64; + gt->gt_max_mhc = 10000; + gt->gt_greedy_default = HZ / 10; + gt->gt_greedy_quantum = HZ / 40; + gt->gt_greedy_max = HZ / 4; + gt->gt_rgrp_try_threshold = 100; + gt->gt_statfs_fast = 0; +} + +/** + * gfs_check_sb - Check superblock + * @sdp: the filesystem + * @sb: The superblock + * @silent: Don't print a message if the check fails + * + * Checks the version code of the FS is one that we understand how to + * read and that the sizes of the various on-disk structures have not + * changed. + */ + +int +gfs_check_sb(struct gfs_sbd *sdp, struct gfs_sb *sb, int silent) +{ + unsigned int x; + + if (sb->sb_header.mh_magic != GFS_MAGIC || + sb->sb_header.mh_type != GFS_METATYPE_SB) { + if (!silent) + printk("GFS: not a GFS filesystem\n"); + return -EINVAL; + } + + /* If format numbers match exactly, we're done. */ + + if (sb->sb_fs_format == GFS_FORMAT_FS && + sb->sb_multihost_format == GFS_FORMAT_MULTI) + return 0; + + if (sb->sb_fs_format != GFS_FORMAT_FS) { + for (x = 0; gfs_old_fs_formats[x]; x++) + if (gfs_old_fs_formats[x] == sb->sb_fs_format) + break; + + if (!gfs_old_fs_formats[x]) { + printk("GFS: code version (%u, %u) is incompatible with ondisk format (%u, %u)\n", + GFS_FORMAT_FS, GFS_FORMAT_MULTI, + sb->sb_fs_format, sb->sb_multihost_format); + printk("GFS: I don't know how to upgrade this FS\n"); + return -EINVAL; + } + } + + if (sb->sb_multihost_format != GFS_FORMAT_MULTI) { + for (x = 0; gfs_old_multihost_formats[x]; x++) + if (gfs_old_multihost_formats[x] == sb->sb_multihost_format) + break; + + if (!gfs_old_multihost_formats[x]) { + printk("GFS: code version (%u, %u) is incompatible with ondisk format (%u, %u)\n", + GFS_FORMAT_FS, GFS_FORMAT_MULTI, + sb->sb_fs_format, sb->sb_multihost_format); + printk("GFS: I don't know how to upgrade this FS\n"); + return -EINVAL; + } + } + + if (!sdp->sd_args.ar_upgrade) { + printk("GFS: code version (%u, %u) is incompatible with ondisk format (%u, %u)\n", + GFS_FORMAT_FS, GFS_FORMAT_MULTI, + sb->sb_fs_format, sb->sb_multihost_format); + printk("GFS: Use the \"upgrade\" mount option to upgrade the FS\n"); + printk("GFS: See the manual for more details\n"); + return -EINVAL; + } + + return 0; +} + +/** + * gfs_read_sb - Read super block + * @sdp: The GFS superblock + * @gl: the glock for the superblock (assumed to be held) + * @silent: Don't print message if mount fails + * + */ + +int +gfs_read_sb(struct gfs_sbd *sdp, struct gfs_glock *gl, int silent) +{ + struct buffer_head *bh; + uint32_t hash_blocks, ind_blocks, leaf_blocks; + uint32_t tmp_blocks; + unsigned int x; + int error; + + error = gfs_dread(gl, GFS_SB_ADDR >> sdp->sd_fsb2bb_shift, + DIO_FORCE | DIO_START | DIO_WAIT, &bh); + if (error) { + if (!silent) + printk("GFS: fsid=%s: can't read superblock\n", + sdp->sd_fsname); + return error; + } + + gfs_assert(sdp, sizeof(struct gfs_sb) <= bh->b_size,); + gfs_sb_in(&sdp->sd_sb, bh->b_data); + brelse(bh); + + error = gfs_check_sb(sdp, &sdp->sd_sb, silent); + if (error) + return error; + + sdp->sd_fsb2bb_shift = sdp->sd_sb.sb_bsize_shift - + GFS_BASIC_BLOCK_SHIFT; + sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift; + sdp->sd_diptrs = (sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode)) / + sizeof(uint64_t); + sdp->sd_inptrs = (sdp->sd_sb.sb_bsize - sizeof(struct gfs_indirect)) / + sizeof(uint64_t); + sdp->sd_jbsize = sdp->sd_sb.sb_bsize - sizeof(struct gfs_meta_header); + sdp->sd_hash_bsize = sdp->sd_sb.sb_bsize / 2; + sdp->sd_hash_bsize_shift = sdp->sd_sb.sb_bsize_shift - 1; + sdp->sd_hash_ptrs = sdp->sd_hash_bsize / sizeof(uint64_t); + + /* Compute maximum reservation required to add a entry to a directory */ + + hash_blocks = DIV_RU(sizeof(uint64_t) * (1 << GFS_DIR_MAX_DEPTH), + sdp->sd_jbsize); + + ind_blocks = 0; + for (tmp_blocks = hash_blocks; tmp_blocks > sdp->sd_diptrs;) { + tmp_blocks = DIV_RU(tmp_blocks, sdp->sd_inptrs); + ind_blocks += tmp_blocks; + } + + leaf_blocks = 2 + GFS_DIR_MAX_DEPTH; + + sdp->sd_max_dirres = hash_blocks + ind_blocks + leaf_blocks; + + sdp->sd_heightsize[0] = sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode); + sdp->sd_heightsize[1] = sdp->sd_sb.sb_bsize * sdp->sd_diptrs; + for (x = 2;; x++) { + uint64_t space, d; + uint32_t m; + + space = sdp->sd_heightsize[x - 1] * sdp->sd_inptrs; + d = space; + m = do_div(d, sdp->sd_inptrs); + + if (d != sdp->sd_heightsize[x - 1] || m) + break; + sdp->sd_heightsize[x] = space; + } + sdp->sd_max_height = x; + gfs_assert(sdp, sdp->sd_max_height <= GFS_MAX_META_HEIGHT,); + + sdp->sd_jheightsize[0] = sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode); + sdp->sd_jheightsize[1] = sdp->sd_jbsize * sdp->sd_diptrs; + for (x = 2;; x++) { + uint64_t space, d; + uint32_t m; + + space = sdp->sd_jheightsize[x - 1] * sdp->sd_inptrs; + d = space; + m = do_div(d, sdp->sd_inptrs); + + if (d != sdp->sd_jheightsize[x - 1] || m) + break; + sdp->sd_jheightsize[x] = space; + } + sdp->sd_max_jheight = x; + gfs_assert(sdp, sdp->sd_max_jheight <= GFS_MAX_META_HEIGHT,); + + return 0; +} + +/** + * gfs_do_upgrade - upgrade a filesystem + * @sdp: The GFS superblock + * + */ + +int +gfs_do_upgrade(struct gfs_sbd *sdp, struct gfs_glock *sb_gl) +{ + struct gfs_holder ji_gh, t_gh, j_gh; + struct gfs_log_header lh; + struct buffer_head *bh; + unsigned int x; + int error; + + /* If format numbers match exactly, we're done. */ + + if (sdp->sd_sb.sb_fs_format == GFS_FORMAT_FS && + sdp->sd_sb.sb_multihost_format == GFS_FORMAT_MULTI) { + printk("GFS: fsid=%s: no upgrade necessary\n", + sdp->sd_fsname); + sdp->sd_args.ar_upgrade = FALSE; + return 0; + } + + error = gfs_jindex_hold(sdp, &ji_gh); + if (error) + goto fail; + + error = gfs_glock_nq_init(sdp->sd_trans_gl, + LM_ST_EXCLUSIVE, GL_NOCACHE, + &t_gh); + if (error) + goto fail_ji_relse; + + if (test_bit(SDF_ROFS, &sdp->sd_flags)) { + printk("GFS: fsid=%s: can't upgrade: read-only FS\n", + sdp->sd_fsname); + error = -EROFS; + goto fail_gunlock_tr; + } + + for (x = 0; x < sdp->sd_journals; x++) { + error = gfs_glock_nq_num(sdp, + sdp->sd_jindex[x].ji_addr, + &gfs_meta_glops, LM_ST_SHARED, + LM_FLAG_TRY | GL_NOCACHE, &j_gh); + switch (error) { + case 0: + break; + + case GLR_TRYFAILED: + printk("GFS: fsid=%s: journal %u is busy\n", + sdp->sd_fsname, x); + error = -EBUSY; + + default: + goto fail_gunlock_tr; + } + + error = gfs_find_jhead(sdp, &sdp->sd_jindex[x], + j_gh.gh_gl, &lh); + + gfs_glock_dq_uninit(&j_gh); + + if (error) + goto fail_gunlock_tr; + + if (!(lh.lh_flags & GFS_LOG_HEAD_UNMOUNT) || lh.lh_last_dump) { + printk("GFS: fsid=%s: journal %u is busy\n", + sdp->sd_fsname, x); + error = -EBUSY; + goto fail_gunlock_tr; + } + } + + /* We don't need to journal this change because we're changing + only one sector of one block. We definitely don't want to have + the journaling code running at this point. */ + + error = gfs_dread(sb_gl, GFS_SB_ADDR >> sdp->sd_fsb2bb_shift, + DIO_START | DIO_WAIT, &bh); + if (error) + goto fail_gunlock_tr; + + gfs_sb_in(&sdp->sd_sb, bh->b_data); + + error = gfs_check_sb(sdp, &sdp->sd_sb, FALSE); + if (error) { + gfs_consist(sdp); + brelse(bh); + goto fail_gunlock_tr; + } + + sdp->sd_sb.sb_fs_format = GFS_FORMAT_FS; + sdp->sd_sb.sb_multihost_format = GFS_FORMAT_MULTI; + + gfs_sb_out(&sdp->sd_sb, bh->b_data); + + set_bit(GLF_DIRTY, &sb_gl->gl_flags); + error = gfs_dwrite(sdp, bh, DIO_DIRTY | DIO_START | DIO_WAIT); + + brelse(bh); + + gfs_glock_dq_uninit(&t_gh); + + gfs_glock_dq_uninit(&ji_gh); + + if (!error) { + printk("GFS: fsid=%s: upgrade successful\n", + sdp->sd_fsname); + sdp->sd_args.ar_upgrade = FALSE; + } + + return error; + + fail_gunlock_tr: + gfs_glock_dq_uninit(&t_gh); + + fail_ji_relse: + gfs_glock_dq_uninit(&ji_gh); + + fail: + if (error == -EBUSY) + printk("GFS: fsid=%s: can't upgrade: the FS is still busy or contains dirty journals\n", + sdp->sd_fsname); + else + printk("GFS: fsid=%s: can't upgrade: %d\n", + sdp->sd_fsname, error); + + return error; +} + +/** + * clear_journalsi - Clear all the journal index information (without locking) + * @sdp: The GFS superblock + * + */ + +static void +clear_journalsi(struct gfs_sbd *sdp) +{ + if (sdp->sd_jindex) { + kfree(sdp->sd_jindex); + sdp->sd_jindex = NULL; + } + sdp->sd_journals = 0; +} + +/** + * gfs_clear_journals - Clear all the journal index information + * @sdp: The GFS superblock + * + */ + +void +gfs_clear_journals(struct gfs_sbd *sdp) +{ + down(&sdp->sd_jindex_lock); + clear_journalsi(sdp); + up(&sdp->sd_jindex_lock); +} + +/** + * gfs_ji_update - Update the journal index information + * @ip: The journal index inode + * + * Returns: errno + */ + +static int +gfs_ji_update(struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = ip->i_sbd; + char buf[sizeof(struct gfs_jindex)]; + unsigned int j; + int error; + + if (do_mod(ip->i_di.di_size, sizeof(struct gfs_jindex))) { + gfs_consist_inode(ip); + return -EIO; + } + + clear_journalsi(sdp); + + sdp->sd_jindex = kmalloc(ip->i_di.di_size, GFP_KERNEL); + if (!sdp->sd_jindex) + return -ENOMEM; + memset(sdp->sd_jindex, 0, ip->i_di.di_size); + + for (j = 0;; j++) { + error = gfs_internal_read(ip, buf, + j * sizeof(struct gfs_jindex), + sizeof(struct gfs_jindex)); + if (!error) + break; + if (error != sizeof(struct gfs_jindex)) { + if (error > 0) + error = -EIO; + goto fail; + } + + gfs_jindex_in(sdp->sd_jindex + j, buf); + } + + sdp->sd_journals = j; + sdp->sd_jiinode_vn = ip->i_gl->gl_vn; + + return 0; + + fail: + clear_journalsi(sdp); + return error; +} + +/** + * gfs_jindex_hold - Grab a lock on the jindex + * @sdp: The GFS superblock + * @ji_gh: the holder for the jindex glock + * + * This makes sure that we're using the latest copy of the journal index + * special file (this describes all of the journals for this filesystem), + * which might have been updated if someone added journals + * (via gfs_jadd utility). + * + * This is very similar to the gfs_rindex_hold() function, except that + * in general we hold the jindex lock for longer periods of time and + * we grab it far less frequently (in general) then the rgrp lock. + * + * Returns: errno + */ + +int +gfs_jindex_hold(struct gfs_sbd *sdp, struct gfs_holder *ji_gh) +{ + struct gfs_inode *ip = sdp->sd_jiinode; + struct gfs_glock *gl = ip->i_gl; + int error; + + error = gfs_glock_nq_init(gl, LM_ST_SHARED, 0, ji_gh); + if (error) + return error; + + /* Read new copy from disk if we don't have the latest */ + if (sdp->sd_jiinode_vn != gl->gl_vn) { + down(&sdp->sd_jindex_lock); + if (sdp->sd_jiinode_vn != gl->gl_vn) + error = gfs_ji_update(ip); + up(&sdp->sd_jindex_lock); + } + + if (error) + gfs_glock_dq_uninit(ji_gh); + + return error; +} + +/** + * gfs_get_jiinode - Read-in the special (hidden) journal index inode + * @sdp: The GFS superblock + * + * Returns: errno + * + * This reads-in just the dinode, not the special file contents that describe + * the journals themselves (see gfs_jindex_hold()). + */ + +int +gfs_get_jiinode(struct gfs_sbd *sdp) +{ + struct gfs_holder ji_gh; + int error; + + error = gfs_glock_nq_num(sdp, + sdp->sd_sb.sb_jindex_di.no_formal_ino, + &gfs_inode_glops, + LM_ST_SHARED, GL_LOCAL_EXCL, + &ji_gh); + if (error) + return error; + + error = gfs_inode_get(ji_gh.gh_gl, &sdp->sd_sb.sb_jindex_di, + CREATE, &sdp->sd_jiinode); + if (!error) { + sdp->sd_jiinode_vn = ji_gh.gh_gl->gl_vn - 1; + set_bit(GLF_STICKY, &ji_gh.gh_gl->gl_flags); + } + + gfs_glock_dq_uninit(&ji_gh); + + return error; +} + +/** + * gfs_get_riinode - Read in the special (hidden) resource group index inode + * @sdp: The GFS superblock + * + * Returns: errno + * + * This reads-in just the dinode, not the special file contents that describe + * the resource groups themselves (see gfs_rindex_hold()). + */ + +int +gfs_get_riinode(struct gfs_sbd *sdp) +{ + struct gfs_holder ri_gh; + int error; + + error = gfs_glock_nq_num(sdp, + sdp->sd_sb.sb_rindex_di.no_formal_ino, + &gfs_inode_glops, + LM_ST_SHARED, GL_LOCAL_EXCL, + &ri_gh); + if (error) + return error; + + error = gfs_inode_get(ri_gh.gh_gl, &sdp->sd_sb.sb_rindex_di, + CREATE, &sdp->sd_riinode); + if (!error) { + sdp->sd_riinode_vn = ri_gh.gh_gl->gl_vn - 1; + set_bit(GLF_STICKY, &ri_gh.gh_gl->gl_flags); + } + + gfs_glock_dq_uninit(&ri_gh); + + return error; +} + +/** + * gfs_get_rootinode - Read in the filesystem's root inode + * @sdp: The GFS superblock + * + * Returns: errno + */ + +int +gfs_get_rootinode(struct gfs_sbd *sdp) +{ + struct gfs_holder i_gh; + int error; + + error = gfs_glock_nq_num(sdp, + sdp->sd_sb.sb_root_di.no_formal_ino, + &gfs_inode_glops, + LM_ST_SHARED, GL_LOCAL_EXCL, + &i_gh); + if (error) + return error; + + error = gfs_inode_get(i_gh.gh_gl, &sdp->sd_sb.sb_root_di, + CREATE, &sdp->sd_rooti); + + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gfs_get_qinode - Read in the special (hidden) quota inode + * @sdp: The GFS superblock + * + * If one is not on-disk already, create a new one. + * Does not read in file contents, just the dinode. + * + * Returns: errno + */ + +int +gfs_get_qinode(struct gfs_sbd *sdp) +{ + struct gfs_holder i_gh; + int error; + + /* Create, if not on-disk already */ + if (!sdp->sd_sb.sb_quota_di.no_formal_ino) { + error = gfs_alloc_qinode(sdp); + if (error) + return error; + } + + error = gfs_glock_nq_num(sdp, + sdp->sd_sb.sb_quota_di.no_formal_ino, + &gfs_inode_glops, + LM_ST_SHARED, GL_LOCAL_EXCL, + &i_gh); + if (error) + return error; + + error = gfs_inode_get(i_gh.gh_gl, &sdp->sd_sb.sb_quota_di, + CREATE, &sdp->sd_qinode); + + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gfs_get_linode - Read in the special (hidden) license inode + * @sdp: The GFS superblock + * + * If one is not on-disk already, create a new one. + * Does not read in file contents, just the dinode. + * + * Returns: errno + */ + +int +gfs_get_linode(struct gfs_sbd *sdp) +{ + struct gfs_holder i_gh; + int error; + + /* Create, if not on-disk already */ + if (!sdp->sd_sb.sb_license_di.no_formal_ino) { + error = gfs_alloc_linode(sdp); + if (error) + return error; + } + + error = gfs_glock_nq_num(sdp, + sdp->sd_sb.sb_license_di.no_formal_ino, + &gfs_inode_glops, + LM_ST_SHARED, GL_LOCAL_EXCL, + &i_gh); + if (error) + return error; + + /* iopen obtained in via gfs_glock_get(..gfs_iopen_glops) */ + error = gfs_inode_get(i_gh.gh_gl, &sdp->sd_sb.sb_license_di, + CREATE, &sdp->sd_linode); + + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gfs_make_fs_rw - Turn a Read-Only FS into a Read-Write one + * @sdp: the filesystem + * + * Returns: errno + */ + +int +gfs_make_fs_rw(struct gfs_sbd *sdp) +{ + struct gfs_glock *j_gl = sdp->sd_journal_gh.gh_gl; + struct gfs_holder t_gh; + struct gfs_log_header head; + int error; + + error = gfs_glock_nq_init(sdp->sd_trans_gl, + LM_ST_SHARED, + GL_LOCAL_EXCL | GL_EXACT, + &t_gh); + if (error) + return error; + + j_gl->gl_ops->go_inval(j_gl, DIO_METADATA | DIO_DATA); + + error = gfs_find_jhead(sdp, &sdp->sd_jdesc, j_gl, &head); + if (error) + goto fail; + + if (!(head.lh_flags & GFS_LOG_HEAD_UNMOUNT)) { + gfs_consist(sdp); + error = -EIO; + goto fail; + } + + /* Initialize some head of the log stuff */ + sdp->sd_sequence = head.lh_sequence; + sdp->sd_log_head = head.lh_first + 1; + + error = gfs_recover_dump(sdp); + if (error) + goto fail; + + set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); + clear_bit(SDF_ROFS, &sdp->sd_flags); + + set_bit(GLF_DIRTY, &j_gl->gl_flags); + gfs_log_dump(sdp, TRUE); + + gfs_glock_dq_uninit(&t_gh); + + return 0; + + fail: + t_gh.gh_flags |= GL_NOCACHE; + gfs_glock_dq_uninit(&t_gh); + + return error; +} + +/** + * gfs_make_fs_ro - Turn a Read-Write FS into a Read-Only one + * @sdp: the filesystem + * + * Returns: errno + */ + +int +gfs_make_fs_ro(struct gfs_sbd *sdp) +{ + struct gfs_holder t_gh; + int error; + + error = gfs_glock_nq_init(sdp->sd_trans_gl, + LM_ST_SHARED, + GL_LOCAL_EXCL | GL_EXACT | GL_NOCACHE, + &t_gh); + if (error && + !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) + return error; + + gfs_statfs_sync(sdp); + + gfs_log_flush(sdp); + gfs_quota_sync(sdp); + gfs_quota_scan(sdp); + + gfs_sync_meta(sdp); + gfs_log_dump(sdp, TRUE); + gfs_log_shutdown(sdp); + + set_bit(SDF_ROFS, &sdp->sd_flags); + clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); + + if (t_gh.gh_gl) + gfs_glock_dq_uninit(&t_gh); + + gfs_unlinked_cleanup(sdp); + gfs_quota_cleanup(sdp); + + return error; +} + +/** + * stat_gfs_fill - fill in the sg for a given RG + * @rgd: the RG + * @sg: the sg structure + * + * Returns: 0 on success, -ESTALE if the LVB is invalid + */ + +static int +stat_gfs_fill(struct gfs_rgrpd *rgd, struct gfs_stat_gfs *sg) +{ + struct gfs_rgrp_lvb *rb = (struct gfs_rgrp_lvb *)rgd->rd_gl->gl_lvb; + + if (gfs32_to_cpu(rb->rb_magic) != GFS_MAGIC) + return -ESTALE; + + sg->sg_total_blocks += rgd->rd_ri.ri_data; + sg->sg_free += gfs32_to_cpu(rb->rb_free); + sg->sg_used_dinode += gfs32_to_cpu(rb->rb_useddi); + sg->sg_free_dinode += gfs32_to_cpu(rb->rb_freedi); + sg->sg_used_meta += gfs32_to_cpu(rb->rb_usedmeta); + sg->sg_free_meta += gfs32_to_cpu(rb->rb_freemeta); + + return 0; +} + +/** + * stat_gfs_async - Stat a filesystem using asynchronous locking + * @sdp: the filesystem + * @sg: the sg info that will be returned + * @interruptible: TRUE if we should look for signals. + * + * Any error (other than a signal) will cause this routine to fall back + * to the synchronous version. + * + * FIXME: This really shouldn't busy wait like this. + * + * Returns: errno + */ + +static int +stat_gfs_async(struct gfs_sbd *sdp, struct gfs_stat_gfs *sg, int interruptible) +{ + struct gfs_rgrpd *rgd_next = gfs_rgrpd_get_first(sdp); + struct gfs_holder *gha, *gh; + unsigned int slots = gfs_tune_get(sdp, gt_statfs_slots); + unsigned int x; + int done; + int error = 0, err; + + memset(sg, 0, sizeof(struct gfs_stat_gfs)); + + gha = vmalloc(slots * sizeof(struct gfs_holder)); + if (!gha) + return -ENOMEM; + memset(gha, 0, slots * sizeof(struct gfs_holder)); + + for (;;) { + done = TRUE; + + for (x = 0; x < slots; x++) { + gh = gha + x; + + if (gh->gh_gl && gfs_glock_poll(gh)) { + err = gfs_glock_wait(gh); + if (err) { + gfs_holder_uninit(gh); + error = err; + } else { + if (!error) + error = stat_gfs_fill(get_gl2rgd(gh->gh_gl), sg); + gfs_glock_dq_uninit(gh); + } + } + + if (gh->gh_gl) + done = FALSE; + else if (rgd_next && !error) { + error = gfs_glock_nq_init(rgd_next->rd_gl, + LM_ST_SHARED, + GL_LOCAL_EXCL | GL_SKIP | GL_ASYNC, + gh); + rgd_next = gfs_rgrpd_get_next(rgd_next); + done = FALSE; + } + + if (interruptible && signal_pending(current)) + error = -ERESTARTSYS; + } + + if (done) + break; + + yield(); + } + + vfree(gha); + + return error; +} + +/** + * stat_gfs_sync - Stat a filesystem using synchronous locking + * @sdp: the filesystem + * @sg: the sg info that will be returned + * @interruptible: TRUE if we should look for signals. + * + * Returns: errno + */ + +static int +stat_gfs_sync(struct gfs_sbd *sdp, struct gfs_stat_gfs *sg, int interruptible) +{ + struct gfs_holder rgd_gh; + struct gfs_rgrpd *rgd; + int error; + + memset(sg, 0, sizeof(struct gfs_stat_gfs)); + + for (rgd = gfs_rgrpd_get_first(sdp); + rgd; + rgd = gfs_rgrpd_get_next(rgd)) { + for (;;) { + error = gfs_glock_nq_init(rgd->rd_gl, + LM_ST_SHARED, + GL_LOCAL_EXCL | GL_SKIP, + &rgd_gh); + if (error) + return error; + + error = stat_gfs_fill(rgd, sg); + + gfs_glock_dq_uninit(&rgd_gh); + + if (!error) + break; + + error = gfs_rgrp_lvb_init(rgd); + if (error) + return error; + } + + if (interruptible && signal_pending(current)) + return -ERESTARTSYS; + } + + return 0; +} + +/** + * gfs_stat_gfs - Do a statfs + * @sdp: the filesystem + * @sg: the sg structure + * @interruptible: Stop if there is a signal pending + * + * Returns: errno + */ + +int +gfs_stat_gfs(struct gfs_sbd *sdp, struct gfs_stat_gfs *sg, int interruptible) +{ + struct gfs_holder ri_gh; + int error; + + error = gfs_rindex_hold(sdp, &ri_gh); + if (error) + return error; + + error = stat_gfs_async(sdp, sg, interruptible); + if (error == -ESTALE) + error = stat_gfs_sync(sdp, sg, interruptible); + + gfs_glock_dq_uninit(&ri_gh); + + return error; +} + +/** + * gfs_lock_fs_check_clean - Stop all writes to the FS and check that all journals are clean + * @sdp: the file system + * @state: the state to put the transaction lock into + * @t_gh: the hold on the transaction lock + * + * Returns: errno + */ + +int +gfs_lock_fs_check_clean(struct gfs_sbd *sdp, unsigned int state, + struct gfs_holder *t_gh) +{ + struct gfs_holder ji_gh, cl_gh; + struct gfs_log_header lh; + unsigned int x; + int error; + + error = gfs_jindex_hold(sdp, &ji_gh); + if (error) + return error; + + error = gfs_glock_nq_num(sdp, + GFS_CRAP_LOCK, &gfs_meta_glops, + LM_ST_SHARED, GL_NOCACHE, + &cl_gh); + if (error) + goto fail; + + error = gfs_glock_nq_init(sdp->sd_trans_gl, state, + LM_FLAG_PRIORITY | GL_EXACT | GL_NOCACHE, + t_gh); + if (error) + goto fail_gunlock_craplock; + + for (x = 0; x < sdp->sd_journals; x++) { + error = gfs_find_jhead(sdp, &sdp->sd_jindex[x], + cl_gh.gh_gl, &lh); + if (error) + goto fail_gunlock_trans; + + if (!(lh.lh_flags & GFS_LOG_HEAD_UNMOUNT)) { + error = -EBUSY; + goto fail_gunlock_trans; + } + } + + gfs_glock_dq_uninit(&cl_gh); + gfs_glock_dq_uninit(&ji_gh); + + return 0; + + fail_gunlock_trans: + gfs_glock_dq_uninit(t_gh); + + fail_gunlock_craplock: + gfs_glock_dq_uninit(&cl_gh); + + fail: + gfs_glock_dq_uninit(&ji_gh); + + return error; +} + +/** + * gfs_freeze_fs - freezes the file system + * @sdp: the file system + * + * This function flushes data and meta data for all machines by + * aquiring the transaction log exclusively. All journals are + * ensured to be in a clean state as well. + * + * Returns: errno + */ + +int +gfs_freeze_fs(struct gfs_sbd *sdp) +{ + int error = 0; + + down(&sdp->sd_freeze_lock); + + if (!sdp->sd_freeze_count++) { + error = gfs_lock_fs_check_clean(sdp, LM_ST_DEFERRED, + &sdp->sd_freeze_gh); + if (error) + sdp->sd_freeze_count--; + else + sdp->sd_freeze_gh.gh_owner = NULL; + } + + up(&sdp->sd_freeze_lock); + + return error; +} + +/** + * gfs_unfreeze_fs - unfreezes the file system + * @sdp: the file system + * + * This function allows the file system to proceed by unlocking + * the exclusively held transaction lock. Other GFS nodes are + * now free to acquire the lock shared and go on with their lives. + * + */ + +void +gfs_unfreeze_fs(struct gfs_sbd *sdp) +{ + down(&sdp->sd_freeze_lock); + + if (sdp->sd_freeze_count && !--sdp->sd_freeze_count) + gfs_glock_dq_uninit(&sdp->sd_freeze_gh); + + up(&sdp->sd_freeze_lock); +} + +/* + * Fast statfs implementation - mostly based on GFS2 implementation. + */ + +void gfs_statfs_change_in(struct gfs_statfs_change_host *sc, const void *buf) +{ + const struct gfs_statfs_change *str = buf; + + sc->sc_total = be64_to_cpu(str->sc_total); + sc->sc_free = be64_to_cpu(str->sc_free); + sc->sc_dinodes = be64_to_cpu(str->sc_dinodes); +} + +void gfs_statfs_change_out(const struct gfs_statfs_change_host *sc, void *buf) +{ + struct gfs_statfs_change *str = buf; + + str->sc_total = cpu_to_be64(sc->sc_total); + str->sc_free = cpu_to_be64(sc->sc_free); + str->sc_dinodes = cpu_to_be64(sc->sc_dinodes); +} + +int gfs_statfs_start(struct gfs_sbd *sdp) +{ + struct gfs_stat_gfs sg; + struct gfs_inode *m_ip; + struct gfs_statfs_change_host *m_sc = &sdp->sd_statfs_master; + struct gfs_statfs_change_host *l_sc = &sdp->sd_statfs_local; + struct buffer_head *m_bh; + struct gfs_holder gh; + int error; + + printk("GFS: fsid=%s: fast statfs start time = %lu\n", + sdp->sd_fsname, get_seconds()); + + /* created via gfs_get_linode() in fill_super(). */ + /* gfs_inode_glops */ + m_ip = sdp->sd_linode; + + /* get real statistics */ + error = gfs_stat_gfs(sdp, &sg, TRUE); + if (error) + return error; + + /* make sure the page is refreshed via glock flushing */ + error = gfs_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, GL_NOCACHE, + &gh); + if (error) + goto gfs_statfs_start_out; + + error = gfs_get_inode_buffer(m_ip, &m_bh); + if (error) + goto gfs_statfs_start_unlock; + + error = gfs_trans_begin(sdp, 1, 0); + if (error) + goto gfs_statfs_start_bh; + + spin_lock(&sdp->sd_statfs_spin); + m_sc->sc_total = sg.sg_total_blocks; + m_sc->sc_free = sg.sg_free + sg.sg_free_dinode + sg.sg_free_meta; + m_sc->sc_dinodes = sg.sg_used_dinode; + memset(l_sc, 0, sizeof(struct gfs_statfs_change_host)); + spin_unlock(&sdp->sd_statfs_spin); + + gfs_trans_add_bh(m_ip->i_gl, m_bh); + gfs_statfs_change_out(m_sc, m_bh->b_data + sizeof(struct gfs_dinode)); + + gfs_trans_end(sdp); + +gfs_statfs_start_bh: + brelse(m_bh); + +gfs_statfs_start_unlock: + gfs_glock_dq_uninit(&gh); + +gfs_statfs_start_out: + return 0; +} + +int gfs_statfs_init(struct gfs_sbd *sdp, int flag) +{ + int error; + + /* if flag == 0, do we want to turn this off ? */ + if (!flag) + return 0; + + error = gfs_statfs_start(sdp); + if (error) + printk("GFS: fsid=%s: can't initialize statfs subsystem: %d\n", + sdp->sd_fsname, error); + + return error; +} + +void gfs_statfs_modify(struct gfs_sbd *sdp, + int64_t total, + int64_t free, + int64_t dinodes) +{ + struct gfs_statfs_change_host *l_sc = &sdp->sd_statfs_local; + + spin_lock(&sdp->sd_statfs_spin); + l_sc->sc_total += total; + l_sc->sc_free += free; + l_sc->sc_dinodes += dinodes; + spin_unlock(&sdp->sd_statfs_spin); +} + +int gfs_statfs_sync(struct gfs_sbd *sdp) +{ + struct gfs_inode *m_ip = sdp->sd_linode; + struct gfs_statfs_change_host *m_sc = &sdp->sd_statfs_master; + struct gfs_statfs_change_host *l_sc = &sdp->sd_statfs_local; + struct gfs_holder gh; + struct buffer_head *m_bh; + int error; + + error = gfs_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, GL_NOCACHE, + &gh); + if (error) + return error; + + error = gfs_get_inode_buffer(m_ip, &m_bh); + if (error) + goto gfs_statfs_sync_out; + + /* if no change, simply return */ + spin_lock(&sdp->sd_statfs_spin); + gfs_statfs_change_in(m_sc, m_bh->b_data + + sizeof(struct gfs_dinode)); + if (!l_sc->sc_total && !l_sc->sc_free && !l_sc->sc_dinodes) { + spin_unlock(&sdp->sd_statfs_spin); + goto out_bh; + } + spin_unlock(&sdp->sd_statfs_spin); + + error = gfs_trans_begin(sdp, 1, 0); + if (error) + goto out_bh; + + spin_lock(&sdp->sd_statfs_spin); + m_sc->sc_total += l_sc->sc_total; + m_sc->sc_free += l_sc->sc_free; + m_sc->sc_dinodes += l_sc->sc_dinodes; + memset(l_sc, 0, sizeof(struct gfs_statfs_change_host)); + spin_unlock(&sdp->sd_statfs_spin); + + gfs_trans_add_bh(m_ip->i_gl, m_bh); + gfs_statfs_change_out(m_sc, m_bh->b_data + sizeof(struct gfs_dinode)); + + gfs_trans_end(sdp); + +out_bh: + brelse(m_bh); + +gfs_statfs_sync_out: + gfs_glock_dq_uninit(&gh); + return error; +} + +int gfs_statfs_fast(struct gfs_sbd *sdp, void *b) +{ + struct kstatfs *buf = (struct kstatfs *)b; + struct gfs_statfs_change_host sc, *m_sc = &sdp->sd_statfs_master; + struct gfs_statfs_change_host *l_sc = &sdp->sd_statfs_local; + + spin_lock(&sdp->sd_statfs_spin); + + sc.sc_total = m_sc->sc_total + l_sc->sc_total; + sc.sc_free = m_sc->sc_free + l_sc->sc_free; + sc.sc_dinodes = m_sc->sc_dinodes + l_sc->sc_dinodes; + spin_unlock(&sdp->sd_statfs_spin); + + if (sc.sc_free < 0) + sc.sc_free = 0; + if (sc.sc_free > sc.sc_total) + sc.sc_free = sc.sc_total; + if (sc.sc_dinodes < 0) + sc.sc_dinodes = 0; + + /* fill in the statistics */ + memset(buf, 0, sizeof(struct kstatfs)); + + buf->f_type = GFS_MAGIC; buf->f_bsize = sdp->sd_sb.sb_bsize; + buf->f_blocks = sc.sc_total; + buf->f_bfree = sc.sc_free; + buf->f_bavail = sc.sc_free; + buf->f_files = sc.sc_dinodes + sc.sc_free; + buf->f_ffree = sc.sc_free; + buf->f_namelen = GFS_FNAMESIZE; + + return 0; +} --- linux-2.6.28.orig/ubuntu/gfs/lm.c +++ linux-2.6.28/ubuntu/gfs/lm.c @@ -0,0 +1,233 @@ +#include +#include +#include +#include +#include +#include + +#include "gfs_ondisk.h" +#include "gfs.h" +#include "incore.h" +#include "glock.h" +#include "lm.h" +#include "super.h" +#include "util.h" +#include "lvb.h" + +/** + * gfs_lm_mount - mount a locking protocol + * @sdp: the filesystem + * @args: mount arguements + * @silent: if 1, don't complain if the FS isn't a GFS fs + * + * Returns: errno + */ + +int gfs_lm_mount(struct gfs_sbd *sdp, int silent) +{ + char *proto = sdp->sd_proto_name; + char *table = sdp->sd_table_name; + int flags = 0; + int error; + + if (sdp->sd_args.ar_spectator) + flags |= LM_MFLAG_SPECTATOR; + + printk("Trying to join cluster \"%s\", \"%s\"\n", proto, table); + + error = gfs_mount_lockproto(proto, table, sdp->sd_args.ar_hostdata, + gfs_glock_cb, sdp, + GFS_MIN_LVB_SIZE, flags, + &sdp->sd_lockstruct, &sdp->sd_kobj); + if (error) { + printk("can't mount proto=%s, table=%s, hostdata=%s\n", + proto, table, sdp->sd_args.ar_hostdata); + goto out; + } + + if (gfs_assert_warn(sdp, sdp->sd_lockstruct.ls_lockspace) || + gfs_assert_warn(sdp, sdp->sd_lockstruct.ls_ops) || + gfs_assert_warn(sdp, sdp->sd_lockstruct.ls_lvb_size >= + GFS_MIN_LVB_SIZE)) { + gfs_unmount_lockproto(&sdp->sd_lockstruct); + goto out; + } + + if (sdp->sd_args.ar_spectator) + snprintf(sdp->sd_fsname, 256, "%s.s", table); + else + snprintf(sdp->sd_fsname, 256, "%s.%u", table, + sdp->sd_lockstruct.ls_jid); + + printk("Joined cluster. Now mounting FS...\n"); + if ((sdp->sd_lockstruct.ls_flags & LM_LSFLAG_LOCAL) && + !sdp->sd_args.ar_ignore_local_fs) { + sdp->sd_args.ar_localflocks = 1; + sdp->sd_args.ar_localcaching = 1; + } + + out: + return error; +} + +void gfs_lm_others_may_mount(struct gfs_sbd *sdp) +{ + if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + sdp->sd_lockstruct.ls_ops->lm_others_may_mount( + sdp->sd_lockstruct.ls_lockspace); +} + +void gfs_lm_unmount(struct gfs_sbd *sdp) +{ + if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + gfs_unmount_lockproto(&sdp->sd_lockstruct); +} + +int gfs_lm_withdraw(struct gfs_sbd *sdp, char *fmt, ...) +{ + va_list args; + + if (test_and_set_bit(SDF_SHUTDOWN, &sdp->sd_flags)) + return 0; + + va_start(args, fmt); + vprintk(fmt, args); + va_end(args); + + printk("GFS: fsid=%s: about to withdraw from the cluster\n", + sdp->sd_fsname); + + BUG_ON(sdp->sd_args.ar_debug); + + printk("GFS: fsid=%s: telling LM to withdraw\n", + sdp->sd_fsname); + + gfs_withdraw_lockproto(&sdp->sd_lockstruct); + + printk("GFS: fsid=%s: withdrawn\n", + sdp->sd_fsname); + dump_stack(); + + return -1; +} + +int gfs_lm_get_lock(struct gfs_sbd *sdp, struct lm_lockname *name, + void **lockp) +{ + int error; + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + error = -EIO; + else + error = sdp->sd_lockstruct.ls_ops->lm_get_lock( + sdp->sd_lockstruct.ls_lockspace, name, lockp); + return error; +} + +void gfs_lm_put_lock(struct gfs_sbd *sdp, void *lock) +{ + if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + sdp->sd_lockstruct.ls_ops->lm_put_lock(lock); +} + +unsigned int gfs_lm_lock(struct gfs_sbd *sdp, void *lock, + unsigned int cur_state, unsigned int req_state, + unsigned int flags) +{ + int ret; + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + ret = 0; + else + ret = sdp->sd_lockstruct.ls_ops->lm_lock(lock, + cur_state, + req_state, flags); + return ret; +} + +unsigned int gfs_lm_unlock(struct gfs_sbd *sdp, void *lock, + unsigned int cur_state) +{ + int ret; + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + ret = 0; + else + ret = sdp->sd_lockstruct.ls_ops->lm_unlock(lock, cur_state); + return ret; +} + +void gfs_lm_cancel(struct gfs_sbd *sdp, void *lock) +{ + if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + sdp->sd_lockstruct.ls_ops->lm_cancel(lock); +} + +int gfs_lm_hold_lvb(struct gfs_sbd *sdp, void *lock, char **lvbp) +{ + int error; + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + error = -EIO; + else + error = sdp->sd_lockstruct.ls_ops->lm_hold_lvb(lock, lvbp); + return error; +} + +void gfs_lm_unhold_lvb(struct gfs_sbd *sdp, void *lock, char *lvb) +{ + if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + sdp->sd_lockstruct.ls_ops->lm_unhold_lvb(lock, lvb); +} + +#if 0 +void gfs_lm_sync_lvb(struct gfs_sbd *sdp, void *lock, char *lvb) +{ + if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + sdp->sd_lockstruct.ls_ops->lm_sync_lvb(lock, lvb); +} +#endif + +int gfs_lm_plock_get(struct gfs_sbd *sdp, struct lm_lockname *name, + struct file *file, struct file_lock *fl) +{ + int error; + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + error = -EIO; + else + error = sdp->sd_lockstruct.ls_ops->lm_plock_get( + sdp->sd_lockstruct.ls_lockspace, + name, file, fl); + return error; +} + +int gfs_lm_plock(struct gfs_sbd *sdp, struct lm_lockname *name, + struct file *file, int cmd, struct file_lock *fl) +{ + int error; + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + error = -EIO; + else + error = sdp->sd_lockstruct.ls_ops->lm_plock( + sdp->sd_lockstruct.ls_lockspace, + name, file, cmd, fl); + return error; +} + +int gfs_lm_punlock(struct gfs_sbd *sdp, struct lm_lockname *name, + struct file *file, struct file_lock *fl) +{ + int error; + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + error = -EIO; + else + error = sdp->sd_lockstruct.ls_ops->lm_punlock( + sdp->sd_lockstruct.ls_lockspace, + name, file, fl); + return error; +} + +void gfs_lm_recovery_done(struct gfs_sbd *sdp, unsigned int jid, + unsigned int message) +{ + if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + sdp->sd_lockstruct.ls_ops->lm_recovery_done( + sdp->sd_lockstruct.ls_lockspace, jid, message); +} + --- linux-2.6.28.orig/ubuntu/gfs/rgrp.h +++ linux-2.6.28/ubuntu/gfs/rgrp.h @@ -0,0 +1,75 @@ +#ifndef __RGRP_DOT_H__ +#define __RGRP_DOT_H__ + +void gfs_mhc_add(struct gfs_rgrpd *rgd, struct buffer_head **bh, + unsigned int num); +int gfs_mhc_fish(struct gfs_sbd *sdp, struct buffer_head *bh); +void gfs_mhc_zap(struct gfs_rgrpd *rgd); + +void gfs_depend_add(struct gfs_rgrpd *rgd, uint64_t formal_ino); +void gfs_depend_sync(struct gfs_rgrpd *rgd); + +struct gfs_rgrpd *gfs_blk2rgrpd(struct gfs_sbd *sdp, uint64_t blk); +struct gfs_rgrpd *gfs_rgrpd_get_first(struct gfs_sbd *sdp); +struct gfs_rgrpd *gfs_rgrpd_get_next(struct gfs_rgrpd *rgd); + +void gfs_clear_rgrpd(struct gfs_sbd *sdp); + +int gfs_rindex_hold(struct gfs_sbd *sdp, struct gfs_holder *ri_gh); + +int gfs_rgrp_read(struct gfs_rgrpd *rgd); +void gfs_rgrp_relse(struct gfs_rgrpd *rgd); + +void gfs_rgrp_lvb_fill(struct gfs_rgrpd *rgd); +int gfs_rgrp_lvb_init(struct gfs_rgrpd *rgd); + +struct gfs_alloc *gfs_alloc_get(struct gfs_inode *ip); +void gfs_alloc_put(struct gfs_inode *ip); + +int gfs_inplace_reserve_i(struct gfs_inode *ip, + char *file, unsigned int line); +#define gfs_inplace_reserve(ip) \ +gfs_inplace_reserve_i((ip), __FILE__, __LINE__) + +void gfs_inplace_release(struct gfs_inode *ip); + +unsigned char gfs_get_block_type(struct gfs_rgrpd *rgd, uint64_t block); + +void gfs_blkalloc(struct gfs_inode *ip, uint64_t *block); +int gfs_metaalloc(struct gfs_inode *ip, uint64_t *block); +int gfs_dialloc(struct gfs_inode *dip, uint64_t *block); + +void gfs_blkfree(struct gfs_inode *ip, uint64_t bstart, uint32_t blen); +void gfs_metafree(struct gfs_inode *ip, uint64_t bstart, uint32_t blen); +void gfs_difree_uninit(struct gfs_rgrpd *rgd, uint64_t addr); +void gfs_difree(struct gfs_rgrpd *rgd, struct gfs_inode *ip); + +extern void gfs_statfs_modify(struct gfs_sbd *sdp, + int64_t total, + int64_t free, + int64_t dinodes); + +/* + * gfs_rgrp_list + * + * Used to collect a list of all resource groups spanned by a given + * inode/file/directory + */ +struct gfs_rgrp_list { + unsigned int rl_rgrps; /* # (qty) of rgrps in list (array) */ + unsigned int rl_space; /* Current capacity in list for rgrps */ + struct gfs_rgrpd **rl_rgd; /* Array of ptrs to rgrp descriptors */ + struct gfs_holder *rl_ghs; /* Array of glock holders for rgrps */ +}; + +void gfs_rlist_add(struct gfs_sbd *sdp, struct gfs_rgrp_list *rlist, + uint64_t block); +void gfs_rlist_alloc(struct gfs_rgrp_list *rlist, unsigned int state, + int flags); +void gfs_rlist_free(struct gfs_rgrp_list *rlist); + +int gfs_reclaim_metadata(struct gfs_sbd *sdp, + uint64_t *inodes, + uint64_t *metadata); + +#endif /* __RGRP_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/ops_fstype.h +++ linux-2.6.28/ubuntu/gfs/ops_fstype.h @@ -0,0 +1,13 @@ +#ifndef __OPS_FSTYPE_DOT_H__ +#define __OPS_FSTYPE_DOT_H__ + +int gfs_sys_init(void); +void gfs_sys_uninit(void); +void gfs_sys_fs_del(struct gfs_sbd *sdp); +int gfs_test_bdev_super(struct super_block *sb, void *data); +int gfs_set_bdev_super(struct super_block *sb, void *data); +int init_names(struct gfs_sbd *sdp, int silent); + +extern struct file_system_type gfs_fs_type; + +#endif /* __OPS_FSTYPE_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/log.h +++ linux-2.6.28/ubuntu/gfs/log.h @@ -0,0 +1,66 @@ +#ifndef __LOG_DOT_H__ +#define __LOG_DOT_H__ + +/** + * gfs_log_lock - acquire the right to mess with the log manager + * @sdp: the filesystem + * + */ + +static __inline__ void +gfs_log_lock(struct gfs_sbd *sdp) +{ + down_write(&sdp->sd_log_lock); +} + +/** + * gfs_log_unlock - release the right to mess with the log manager + * @sdp: the filesystem + * + */ + +static __inline__ void +gfs_log_unlock(struct gfs_sbd *sdp) +{ + up_write(&sdp->sd_log_lock); +} + +unsigned int gfs_struct2blk(struct gfs_sbd *sdp, unsigned int nstruct, + unsigned int ssize); +unsigned int gfs_blk2seg(struct gfs_sbd *sdp, unsigned int blocks); + +int gfs_log_reserve(struct gfs_sbd *sdp, unsigned int segments, int jump_queue); +void gfs_log_release(struct gfs_sbd *sdp, unsigned int segments); + +void gfs_ail_start(struct gfs_sbd *sdp, int flags); +int gfs_ail_empty(struct gfs_sbd *sdp); + +void gfs_log_commit(struct gfs_sbd *sdp, struct gfs_trans *trans); +void gfs_log_flush(struct gfs_sbd *sdp); +void gfs_log_flush_glock(struct gfs_glock *gl); + +void gfs_log_shutdown(struct gfs_sbd *sdp); + +void gfs_log_dump(struct gfs_sbd *sdp, int force); + +/* Internal crap used the log operations */ + +/** + * gfs_log_is_header - Discover if block is on journal header + * @sdp: The GFS superblock + * @block: The block number + * + * Returns: TRUE if the block is on a journal segment boundary, FALSE otherwise + */ + +static __inline__ int +gfs_log_is_header(struct gfs_sbd *sdp, uint64_t block) +{ + return !do_mod(block, sdp->sd_sb.sb_seg_size); +} + +struct gfs_log_buf *gfs_log_get_buf(struct gfs_sbd *sdp, struct gfs_trans *tr); +void gfs_log_fake_buf(struct gfs_sbd *sdp, struct gfs_trans *tr, char *data, + struct buffer_head *unlock); + +#endif /* __LOG_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/format.h +++ linux-2.6.28/ubuntu/gfs/format.h @@ -0,0 +1,17 @@ +#ifndef __FORMAT_DOT_H__ +#define __FORMAT_DOT_H__ + +static const uint32_t gfs_old_fs_formats[] = { + 1308, + 1307, + 1306, + 1305, + 0 +}; + +static const uint32_t gfs_old_multihost_formats[] = { + 1400, + 0 +}; + +#endif /* __FORMAT_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/ops_dentry.c +++ linux-2.6.28/ubuntu/gfs/ops_dentry.c @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "dir.h" +#include "glock.h" +#include "ops_dentry.h" + +/** + * gfs_drevalidate - Check directory lookup consistency + * @dentry: the mapping to check + * @nd: + * + * Check to make sure the lookup necessary to arrive at this inode from its + * parent is still good. + * + * Returns: 1 if the dentry is ok, 0 if it isn't + */ + +static int +gfs_drevalidate(struct dentry *dentry, struct nameidata *nd) +{ + struct dentry *parent = dget_parent(dentry); + struct gfs_inode *dip = get_v2ip(parent->d_inode); + struct gfs_sbd *sdp = dip->i_sbd; + struct inode *inode; + struct gfs_holder d_gh; + struct gfs_inode *ip; + struct gfs_inum inum; + unsigned int type; + int error; + + lock_kernel(); + + atomic_inc(&sdp->sd_ops_dentry); + + if (sdp->sd_args.ar_localcaching) + goto valid; + + inode = dentry->d_inode; + if (inode && is_bad_inode(inode)) + goto invalid; + + error = gfs_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh); + if (error) + goto fail; + + error = gfs_dir_search(dip, &dentry->d_name, &inum, &type); + switch (error) { + case 0: + if (!inode) + goto invalid_gunlock; + break; + case -ENOENT: + if (!inode) + goto valid_gunlock; + goto invalid_gunlock; + default: + goto fail_gunlock; + } + + ip = get_v2ip(inode); + + if (ip->i_num.no_formal_ino != inum.no_formal_ino) + goto invalid_gunlock; + + if (ip->i_di.di_type != type) { + gfs_consist_inode(dip); + goto fail_gunlock; + } + + valid_gunlock: + gfs_glock_dq_uninit(&d_gh); + + valid: + unlock_kernel(); + dput(parent); + return 1; + + invalid_gunlock: + gfs_glock_dq_uninit(&d_gh); + + invalid: + if (inode && S_ISDIR(inode->i_mode)) { + if (have_submounts(dentry)) + goto valid; + shrink_dcache_parent(dentry); + } + d_drop(dentry); + + unlock_kernel(); + dput(parent); + return 0; + + fail_gunlock: + gfs_glock_dq_uninit(&d_gh); + + fail: + unlock_kernel(); + dput(parent); + return 0; +} + +struct dentry_operations gfs_dops = { + .d_revalidate = gfs_drevalidate, +}; --- linux-2.6.28.orig/ubuntu/gfs/ops_inode.c +++ linux-2.6.28/ubuntu/gfs/ops_inode.c @@ -0,0 +1,1670 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "acl.h" +#include "bmap.h" +#include "dio.h" +#include "dir.h" +#include "eaops.h" +#include "eattr.h" +#include "glock.h" +#include "inode.h" +#include "ops_dentry.h" +#include "ops_inode.h" +#include "page.h" +#include "quota.h" +#include "rgrp.h" +#include "trans.h" +#include "unlinked.h" + +/** + * gfs_security_init - + * @dip: + * @ip: + * + * Returns: errno + */ + +static int +gfs_security_init(struct gfs_inode *dip, struct gfs_inode *ip) +{ + int err; + size_t len; + void *value; + char *name; + struct gfs_ea_request er; + + err = security_inode_init_security(ip->i_vnode, dip->i_vnode, + &name, &value, &len); + + if (err) { + if (err == -EOPNOTSUPP) + return 0; + return err; + } + + memset(&er, 0, sizeof(struct gfs_ea_request)); + + er.er_type = GFS_EATYPE_SECURITY; + er.er_name = name; + er.er_data = value; + er.er_name_len = strlen(name); + er.er_data_len = len; + + err = gfs_ea_set_i(ip, &er); + + kfree(value); + kfree(name); + + return err; +} + +/** + * gfs_create - Create a file + * @dir: The directory in which to create the file + * @dentry: The dentry of the new file + * @mode: The mode of the new file + * + * Returns: errno + */ + +static int +gfs_create(struct inode *dir, struct dentry *dentry, + int mode, struct nameidata *nd) +{ + struct gfs_inode *dip = get_v2ip(dir), *ip; + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_holder d_gh, i_gh; + struct inode *inode; + int new = TRUE; + int error; + + atomic_inc(&sdp->sd_ops_inode); + + gfs_unlinked_limit(sdp); + + gfs_holder_init(dip->i_gl, 0, 0, &d_gh); + + for (;;) { + error = gfs_createi(&d_gh, &dentry->d_name, + GFS_FILE_REG, mode, + &i_gh); + if (!error) + break; + else if (error != -EEXIST || + (nd && (nd->intent.open.flags & O_EXCL))) { + gfs_holder_uninit(&d_gh); + return error; + } + + error = gfs_lookupi(&d_gh, &dentry->d_name, + FALSE, &i_gh); + if (!error) { + if (i_gh.gh_gl) { + new = FALSE; + break; + } + } else { + gfs_holder_uninit(&d_gh); + return error; + } + } + + ip = get_gl2ip(i_gh.gh_gl); + + if (new) { + gfs_trans_end(sdp); + if (dip->i_alloc->al_rgd) + gfs_inplace_release(dip); + gfs_quota_unlock_m(dip); + gfs_unlinked_unlock(sdp, dip->i_alloc->al_ul); + gfs_alloc_put(dip); + } + + inode = gfs_iget(ip, CREATE); + gfs_inode_put(ip); + + if (!inode) + error = -ENOMEM; + else + error = gfs_security_init(dip, ip); + + gfs_glock_dq_uninit(&d_gh); + gfs_glock_dq_uninit(&i_gh); + + if (error) + return error; + + d_instantiate(dentry, inode); + if (new) + mark_inode_dirty(inode); + + return 0; +} + +/** + * lookup_cdpn_sub_at - Maybe lookup a Context Dependent Pathname + * @sdp: the filesystem + * @dentry: the original dentry to lookup + * @new_dentry: the new dentry, if this was a substitutable path. + * + * Returns: the new dentry, a ERR_PTR, or NULL + */ + +static struct dentry * +lookup_cdpn_sub_at(struct gfs_sbd *sdp, struct dentry *dentry) +{ + struct dentry *parent, *new = NULL; + char *buf; + + buf = kmalloc(2 * __NEW_UTS_LEN + 2, GFP_KERNEL); + if (!buf) + return ERR_PTR(-ENOMEM); + + parent = dget_parent(dentry); + + if (gfs_filecmp(&dentry->d_name, "@hostname", 9)) + new = lookup_one_len(init_utsname()->nodename, + parent, + strlen(init_utsname()->nodename)); + else if (gfs_filecmp(&dentry->d_name, "@mach", 5)) + new = lookup_one_len(init_utsname()->machine, + parent, + strlen(init_utsname()->machine)); + else if (gfs_filecmp(&dentry->d_name, "@os", 3)) + new = lookup_one_len(init_utsname()->sysname, + parent, + strlen(init_utsname()->sysname)); + else if (gfs_filecmp(&dentry->d_name, "@uid", 4)) + new = lookup_one_len(buf, + parent, + sprintf(buf, "%u", current->fsuid)); + else if (gfs_filecmp(&dentry->d_name, "@gid", 4)) + new = lookup_one_len(buf, + parent, + sprintf(buf, "%u", current->fsgid)); + else if (gfs_filecmp(&dentry->d_name, "@sys", 4)) + new = lookup_one_len(buf, + parent, + sprintf(buf, "%s_%s", + init_utsname()->machine, + init_utsname()->sysname)); + else if (gfs_filecmp(&dentry->d_name, "@jid", 4)) + new = lookup_one_len(buf, + parent, + sprintf(buf, "%u", + sdp->sd_lockstruct.ls_jid)); + + dput(parent); + kfree(buf); + + return new; +} + +/** + * lookup_cdpn_sub_brace - Maybe lookup a Context Dependent Pathname + * @sdp: the filesystem + * @dentry: the original dentry to lookup + * @new_dentry: the new dentry, if this was a substitutable path. + * + * Returns: the new dentry, a ERR_PTR, or NULL + */ + +static struct dentry * +lookup_cdpn_sub_brace(struct gfs_sbd *sdp, struct dentry *dentry) +{ + struct dentry *parent, *new = NULL; + char *buf; + + buf = kmalloc(2 * __NEW_UTS_LEN + 2, GFP_KERNEL); + if (!buf) + return ERR_PTR(-ENOMEM); + + parent = dget_parent(dentry); + + if (gfs_filecmp(&dentry->d_name, "{hostname}", 10)) + new = lookup_one_len(init_utsname()->nodename, + parent, + strlen(init_utsname()->nodename)); + else if (gfs_filecmp(&dentry->d_name, "{mach}", 6)) + new = lookup_one_len(init_utsname()->machine, + parent, + strlen(init_utsname()->machine)); + else if (gfs_filecmp(&dentry->d_name, "{os}", 4)) + new = lookup_one_len(init_utsname()->sysname, + parent, + strlen(init_utsname()->sysname)); + else if (gfs_filecmp(&dentry->d_name, "{uid}", 5)) + new = lookup_one_len(buf, + parent, + sprintf(buf, "%u", current->fsuid)); + else if (gfs_filecmp(&dentry->d_name, "{gid}", 5)) + new = lookup_one_len(buf, + parent, + sprintf(buf, "%u", current->fsgid)); + else if (gfs_filecmp(&dentry->d_name, "{sys}", 5)) + new = lookup_one_len(buf, + parent, + sprintf(buf, "%s_%s", + init_utsname()->machine, + init_utsname()->sysname)); + else if (gfs_filecmp(&dentry->d_name, "{jid}", 5)) + new = lookup_one_len(buf, + parent, + sprintf(buf, "%u", + sdp->sd_lockstruct.ls_jid)); + + dput(parent); + kfree(buf); + + return new; +} + +/** + * gfs_lookup - Look up a filename in a directory and return its inode + * @dir: The directory inode + * @dentry: The dentry of the new inode + * @nd: passed from Linux VFS, ignored by us + * + * Called by the VFS layer. Lock dir and call gfs_lookupi() + * + * Returns: errno + */ + +static struct dentry * +gfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) +{ + struct gfs_inode *dip = get_v2ip(dir), *ip; + struct gfs_holder d_gh, i_gh; + struct inode *inode = NULL; + int error; + + atomic_inc(&dip->i_sbd->sd_ops_inode); + + /* Do Context Dependent Path Name expansion */ + + if (*dentry->d_name.name == '@' && dentry->d_name.len > 1) { + struct dentry *new_dentry; + new_dentry = lookup_cdpn_sub_at(dip->i_sbd, dentry); + if (new_dentry) + return new_dentry; + } else if (*dentry->d_name.name == '{' && dentry->d_name.len > 2) { + struct dentry *new_dentry; + new_dentry = lookup_cdpn_sub_brace(dip->i_sbd, dentry); + if (new_dentry) + return new_dentry; + } + + dentry->d_op = &gfs_dops; + + gfs_holder_init(dip->i_gl, 0, 0, &d_gh); + + error = gfs_lookupi(&d_gh, &dentry->d_name, FALSE, &i_gh); + if (error) { + gfs_holder_uninit(&d_gh); + return ERR_PTR(error); + } + + if (i_gh.gh_gl) { + ip = get_gl2ip(i_gh.gh_gl); + + inode = gfs_iget(ip, CREATE); + gfs_inode_put(ip); + + gfs_glock_dq_uninit(&d_gh); + gfs_glock_dq_uninit(&i_gh); + + if (!inode) + return ERR_PTR(-ENOMEM); + } else + gfs_holder_uninit(&d_gh); + + if (inode) + return d_splice_alias(inode, dentry); + d_add(dentry, inode); + + return NULL; +} + +/** + * gfs_link - Link to a file + * @old_dentry: The inode to link + * @dir: Add link to this directory + * @dentry: The name of the link + * + * Link the inode in "old_dentry" into the directory "dir" with the + * name in "dentry". + * + * Returns: errno + */ + +static int +gfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) +{ + struct gfs_inode *dip = get_v2ip(dir); + struct gfs_sbd *sdp = dip->i_sbd; + struct inode *inode = old_dentry->d_inode; + struct gfs_inode *ip = get_v2ip(inode); + struct gfs_alloc *al = NULL; + struct gfs_holder ghs[2]; + int alloc_required; + int error; + + atomic_inc(&sdp->sd_ops_inode); + + if (ip->i_di.di_type == GFS_FILE_DIR) + return -EPERM; + + gfs_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[0]); + gfs_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[1]); + + error = gfs_glock_nq_m(2, ghs); + if (error) + goto fail; + + error = inode_permission(dir, MAY_WRITE | MAY_EXEC); + if (error) + goto fail_gunlock; + + error = gfs_dir_search(dip, &dentry->d_name, NULL, NULL); + switch (error) { + case -ENOENT: + break; + case 0: + error = -EEXIST; + default: + goto fail_gunlock; + } + + if (!dip->i_di.di_nlink) { + error = -EINVAL; + goto fail_gunlock; + } + if (dip->i_di.di_entries == (uint32_t)-1) { + error = -EFBIG; + goto fail_gunlock; + } + if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) { + error = -EPERM; + goto fail_gunlock; + } + if (!ip->i_di.di_nlink) { + error = -EINVAL; + goto fail_gunlock; + } + if (ip->i_di.di_nlink == (uint32_t)-1) { + error = -EMLINK; + goto fail_gunlock; + } + + error = gfs_diradd_alloc_required(dip, &dentry->d_name, &alloc_required); + if (error) + goto fail_gunlock; + + if (alloc_required) { + al = gfs_alloc_get(dip); + + error = gfs_quota_lock_m(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + if (error) + goto fail_alloc; + + error = gfs_quota_check(dip, dip->i_di.di_uid, dip->i_di.di_gid); + if (error) + goto fail_gunlock_q; + + al->al_requested_meta = sdp->sd_max_dirres; + + error = gfs_inplace_reserve(dip); + if (error) + goto fail_gunlock_q; + + /* Trans may require: + two dinode blocks, directory modifications to add an entry, + RG bitmap blocks to allocate from, and quota change */ + + error = gfs_trans_begin(sdp, + 2 + sdp->sd_max_dirres + + al->al_rgd->rd_ri.ri_length, + 1); + if (error) + goto fail_ipres; + } else { + /* Trans may require: + Two dinode blocks and a leaf block. */ + + error = gfs_trans_begin(sdp, 3, 0); + if (error) + goto fail_ipres; + } + + error = gfs_dir_add(dip, &dentry->d_name, &ip->i_num, ip->i_di.di_type); + if (error) + goto fail_end_trans; + + error = gfs_change_nlink(ip, +1); + if (error) + goto fail_end_trans; + + gfs_trans_end(sdp); + + if (alloc_required) { + gfs_assert_warn(sdp, al->al_alloced_meta); + gfs_inplace_release(dip); + gfs_quota_unlock_m(dip); + gfs_alloc_put(dip); + } + + gfs_glock_dq_m(2, ghs); + + gfs_holder_uninit(&ghs[0]); + gfs_holder_uninit(&ghs[1]); + + atomic_inc(&inode->i_count); + + d_instantiate(dentry, inode); + mark_inode_dirty(inode); + + return 0; + + fail_end_trans: + gfs_trans_end(sdp); + + fail_ipres: + if (alloc_required) + gfs_inplace_release(dip); + + fail_gunlock_q: + if (alloc_required) + gfs_quota_unlock_m(dip); + + fail_alloc: + if (alloc_required) + gfs_alloc_put(dip); + + fail_gunlock: + gfs_glock_dq_m(2, ghs); + + fail: + gfs_holder_uninit(&ghs[0]); + gfs_holder_uninit(&ghs[1]); + + return error; +} + +/** + * gfs_unlink - Unlink a file + * @dir: The inode of the directory containing the file to unlink + * @dentry: The file itself + * + * Unlink a file. Call gfs_unlinki() + * + * Returns: errno + */ + +static int +gfs_unlink(struct inode *dir, struct dentry *dentry) +{ + struct gfs_inode *dip = get_v2ip(dir); + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_inode *ip = get_v2ip(dentry->d_inode); + struct gfs_holder ghs[2]; + int error; + + atomic_inc(&sdp->sd_ops_inode); + + gfs_unlinked_limit(sdp); + + gfs_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[0]); + gfs_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[1]); + + error = gfs_glock_nq_m(2, ghs); + if (error) + goto fail; + + error = gfs_unlink_ok(dip, &dentry->d_name, ip); + if (error) + goto fail_gunlock; + + /* Trans may require: + Two dinode blocks and one modified directory leaf block + and one unlinked tag. */ + + error = gfs_trans_begin(sdp, 3, 1); + if (error) + goto fail_gunlock; + + error = gfs_unlinki(dip, &dentry->d_name, ip); + if (error) + goto fail_end_trans; + + gfs_trans_end(sdp); + + gfs_glock_dq_m(2, ghs); + + gfs_holder_uninit(&ghs[0]); + gfs_holder_uninit(&ghs[1]); + + return 0; + + fail_end_trans: + gfs_trans_end(sdp); + + fail_gunlock: + gfs_glock_dq_m(2, ghs); + + fail: + gfs_holder_uninit(&ghs[0]); + gfs_holder_uninit(&ghs[1]); + + return error; +} + +/** + * gfs_symlink - Create a symlink + * @dir: The directory to create the symlink in + * @dentry: The dentry to put the symlink in + * @symname: The thing which the link points to + * + * Returns: errno + */ + +static int +gfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) +{ + struct gfs_inode *dip = get_v2ip(dir), *ip; + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_holder d_gh, i_gh; + struct inode *inode; + struct buffer_head *dibh; + int size; + int error; + + atomic_inc(&sdp->sd_ops_inode); + + gfs_unlinked_limit(sdp); + + /* Must be stuffed with a null terminator for gfs_follow_link() */ + size = strlen(symname); + if (size > sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode) - 1) + return -ENAMETOOLONG; + + gfs_holder_init(dip->i_gl, 0, 0, &d_gh); + + error = gfs_createi(&d_gh, &dentry->d_name, + GFS_FILE_LNK, S_IFLNK | S_IRWXUGO, + &i_gh); + if (error) { + gfs_holder_uninit(&d_gh); + return error; + } + + ip = get_gl2ip(i_gh.gh_gl); + + ip->i_di.di_size = size; + + error = gfs_get_inode_buffer(ip, &dibh); + + if (!gfs_assert_withdraw(sdp, !error)) { + gfs_dinode_out(&ip->i_di, dibh->b_data); + memcpy(dibh->b_data + sizeof(struct gfs_dinode), symname, size); + brelse(dibh); + } + + gfs_trans_end(sdp); + if (dip->i_alloc->al_rgd) + gfs_inplace_release(dip); + gfs_quota_unlock_m(dip); + gfs_unlinked_unlock(sdp, dip->i_alloc->al_ul); + gfs_alloc_put(dip); + + inode = gfs_iget(ip, CREATE); + gfs_inode_put(ip); + + error = gfs_security_init(dip, ip); + + gfs_glock_dq_uninit(&d_gh); + gfs_glock_dq_uninit(&i_gh); + + if (error) + return error; + + if (!inode) + return -ENOMEM; + + d_instantiate(dentry, inode); + mark_inode_dirty(inode); + + return 0; +} + +/** + * gfs_mkdir - Make a directory + * @dir: The parent directory of the new one + * @dentry: The dentry of the new directory + * @mode: The mode of the new directory + * + * Returns: errno + */ + +static int +gfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) +{ + struct gfs_inode *dip = get_v2ip(dir), *ip; + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_holder d_gh, i_gh; + struct inode *inode; + struct buffer_head *dibh; + int error; + + atomic_inc(&sdp->sd_ops_inode); + + gfs_unlinked_limit(sdp); + + gfs_holder_init(dip->i_gl, 0, 0, &d_gh); + + error = gfs_createi(&d_gh, &dentry->d_name, + GFS_FILE_DIR, S_IFDIR | mode, + &i_gh); + if (error) { + gfs_holder_uninit(&d_gh); + return error; + } + + ip = get_gl2ip(i_gh.gh_gl); + + ip->i_di.di_nlink = 2; + ip->i_di.di_size = sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode); + ip->i_di.di_flags |= GFS_DIF_JDATA; + ip->i_di.di_payload_format = GFS_FORMAT_DE; + ip->i_di.di_entries = 2; + + error = gfs_get_inode_buffer(ip, &dibh); + + if (!gfs_assert_withdraw(sdp, !error)) { + struct gfs_dinode *di = (struct gfs_dinode *)dibh->b_data; + struct gfs_dirent *dent; + + gfs_dirent_alloc(ip, dibh, 1, &dent); + + dent->de_inum = di->di_num; /* already GFS endian */ + dent->de_hash = gfs_dir_hash(".", 1); + dent->de_hash = cpu_to_gfs32(dent->de_hash); + dent->de_type = cpu_to_gfs16(GFS_FILE_DIR); + memcpy((char *) (dent + 1), ".", 1); + di->di_entries = cpu_to_gfs32(1); + + gfs_dirent_alloc(ip, dibh, 2, &dent); + + gfs_inum_out(&dip->i_num, (char *) &dent->de_inum); + dent->de_hash = gfs_dir_hash("..", 2); + dent->de_hash = cpu_to_gfs32(dent->de_hash); + dent->de_type = cpu_to_gfs16(GFS_FILE_DIR); + memcpy((char *) (dent + 1), "..", 2); + + gfs_dinode_out(&ip->i_di, (char *)di); + + brelse(dibh); + } + + error = gfs_change_nlink(dip, +1); + gfs_assert_withdraw(sdp, !error); /* dip already pinned */ + + gfs_trans_end(sdp); + if (dip->i_alloc->al_rgd) + gfs_inplace_release(dip); + gfs_quota_unlock_m(dip); + gfs_unlinked_unlock(sdp, dip->i_alloc->al_ul); + gfs_alloc_put(dip); + + inode = gfs_iget(ip, CREATE); + gfs_inode_put(ip); + + if (!inode) + return -ENOMEM; + + error = gfs_security_init(dip, ip); + + gfs_glock_dq_uninit(&d_gh); + gfs_glock_dq_uninit(&i_gh); + + if (error) + return error; + + d_instantiate(dentry, inode); + mark_inode_dirty(inode); + + return 0; +} + +/** + * gfs_rmdir - Remove a directory + * @dir: The parent directory of the directory to be removed + * @dentry: The dentry of the directory to remove + * + * Remove a directory. Call gfs_rmdiri() + * + * Returns: errno + */ + +static int +gfs_rmdir(struct inode *dir, struct dentry *dentry) +{ + struct gfs_inode *dip = get_v2ip(dir); + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_inode *ip = get_v2ip(dentry->d_inode); + struct gfs_holder ghs[2]; + int error; + + atomic_inc(&sdp->sd_ops_inode); + + gfs_unlinked_limit(sdp); + + gfs_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[0]); + gfs_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[1]); + + error = gfs_glock_nq_m(2, ghs); + if (error) + goto fail; + + error = gfs_unlink_ok(dip, &dentry->d_name, ip); + if (error) + goto fail_gunlock; + + if (ip->i_di.di_entries < 2) { + if (gfs_consist_inode(ip)) + gfs_dinode_print(&ip->i_di); + error = -EIO; + goto fail_gunlock; + } + if (ip->i_di.di_entries > 2) { + error = -ENOTEMPTY; + goto fail_gunlock; + } + + /* Trans may require: + Two dinode blocks, one directory leaf block containing the + entry to be rmdired, two leaf blocks containing . and .. of + the directory being rmdired, and one unlinked tag */ + + error = gfs_trans_begin(sdp, 5, 1); + if (error) + goto fail_gunlock; + + error = gfs_rmdiri(dip, &dentry->d_name, ip); + if (error) + goto fail_end_trans; + + gfs_trans_end(sdp); + + gfs_glock_dq_m(2, ghs); + + gfs_holder_uninit(&ghs[0]); + gfs_holder_uninit(&ghs[1]); + + return 0; + + fail_end_trans: + gfs_trans_end(sdp); + + fail_gunlock: + gfs_glock_dq_m(2, ghs); + + fail: + gfs_holder_uninit(&ghs[0]); + gfs_holder_uninit(&ghs[1]); + + return error; +} + +/** + * gfs_mknod - Make a special file + * @dir: The directory in which the special file will reside + * @dentry: The dentry of the special file + * @mode: The mode of the special file + * @rdev: The device specification of the special file + * + */ + +static int +gfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) +{ + struct gfs_inode *dip = get_v2ip(dir), *ip; + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_holder d_gh, i_gh; + struct inode *inode; + struct buffer_head *dibh; + uint16_t type = 0; + uint32_t major = 0, minor = 0; + int error; + + atomic_inc(&sdp->sd_ops_inode); + + gfs_unlinked_limit(sdp); + + switch (mode & S_IFMT) { + case S_IFBLK: + type = GFS_FILE_BLK; + major = MAJOR(dev); + minor = MINOR(dev); + break; + case S_IFCHR: + type = GFS_FILE_CHR; + major = MAJOR(dev); + minor = MINOR(dev); + break; + case S_IFIFO: + type = GFS_FILE_FIFO; + break; + case S_IFSOCK: + type = GFS_FILE_SOCK; + break; + default: + printk("GFS: fsid=%s: mknod() with invalid type (%d)\n", + sdp->sd_fsname, mode); + return -EINVAL; + }; + + gfs_holder_init(dip->i_gl, 0, 0, &d_gh); + + error = gfs_createi(&d_gh, &dentry->d_name, + type, mode, + &i_gh); + if (error) { + gfs_holder_uninit(&d_gh); + return error; + } + + ip = get_gl2ip(i_gh.gh_gl); + + ip->i_di.di_major = major; + ip->i_di.di_minor = minor; + + error = gfs_get_inode_buffer(ip, &dibh); + + if (!gfs_assert_withdraw(sdp, !error)) { + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + + gfs_trans_end(sdp); + if (dip->i_alloc->al_rgd) + gfs_inplace_release(dip); + gfs_quota_unlock_m(dip); + gfs_unlinked_unlock(sdp, dip->i_alloc->al_ul); + gfs_alloc_put(dip); + + inode = gfs_iget(ip, CREATE); + gfs_inode_put(ip); + + error = gfs_security_init(dip, ip); + + gfs_glock_dq_uninit(&d_gh); + gfs_glock_dq_uninit(&i_gh); + + if (error) + return error; + + if (!inode) + return -ENOMEM; + + d_instantiate(dentry, inode); + mark_inode_dirty(inode); + + return 0; +} + +/** + * gfs_rename - Rename a file + * @odir: Parent directory of old file name + * @odentry: The old dentry of the file + * @ndir: Parent directory of new file name + * @ndentry: The new dentry of the file + * + * Returns: errno + */ + +static int +gfs_rename(struct inode *odir, struct dentry *odentry, + struct inode *ndir, struct dentry *ndentry) +{ + struct gfs_inode *odip = get_v2ip(odir); + struct gfs_inode *ndip = get_v2ip(ndir); + struct gfs_inode *ip = get_v2ip(odentry->d_inode); + struct gfs_inode *nip = NULL; + struct gfs_sbd *sdp = odip->i_sbd; + struct qstr name; + struct gfs_alloc *al; + struct gfs_holder ghs[4], r_gh; + unsigned int num_gh; + int dir_rename = FALSE; + int alloc_required; + unsigned int x; + int error; + + atomic_inc(&sdp->sd_ops_inode); + + gfs_unlinked_limit(sdp); + + if (ndentry->d_inode) { + nip = get_v2ip(ndentry->d_inode); + if (ip == nip) + return 0; + } + + /* Make sure we aren't trying to move a dirctory into it's subdir */ + + if (ip->i_di.di_type == GFS_FILE_DIR && odip != ndip) { + dir_rename = TRUE; + + error = gfs_glock_nq_init(sdp->sd_rename_gl, + LM_ST_EXCLUSIVE, 0, + &r_gh); + if (error) + return error; + + error = gfs_ok_to_move(ip, ndip); + if (error) + goto fail; + } + + gfs_holder_init(odip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[0]); + gfs_holder_init(ndip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[1]); + num_gh = 2; + + if (nip) + gfs_holder_init(nip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[num_gh++]); + + if (dir_rename) + gfs_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[num_gh++]); + + error = gfs_glock_nq_m(num_gh, ghs); + if (error) + goto fail_uninit; + + /* Check out the old directory */ + + error = gfs_unlink_ok(odip, &odentry->d_name, ip); + if (error) + goto fail_gunlock; + + /* Check out the new directory */ + + if (nip) { + error = gfs_unlink_ok(ndip, &ndentry->d_name, nip); + if (error) + goto fail_gunlock; + + if (nip->i_di.di_type == GFS_FILE_DIR) { + if (nip->i_di.di_entries < 2) { + if (gfs_consist_inode(nip)) + gfs_dinode_print(&nip->i_di); + error = -EIO; + goto fail_gunlock; + } + if (nip->i_di.di_entries > 2) { + error = -ENOTEMPTY; + goto fail_gunlock; + } + } + } else { + error = inode_permission(ndir, MAY_WRITE | MAY_EXEC); + if (error) + goto fail_gunlock; + + error = gfs_dir_search(ndip, &ndentry->d_name, NULL, NULL); + switch (error) { + case -ENOENT: + error = 0; + break; + case 0: + error = -EEXIST; + default: + goto fail_gunlock; + }; + + if (odip != ndip) { + if (!ndip->i_di.di_nlink) { + error = -EINVAL; + goto fail_gunlock; + } + if (ndip->i_di.di_entries == (uint32_t)-1) { + error = -EFBIG; + goto fail_gunlock; + } + if (ip->i_di.di_type == GFS_FILE_DIR && + ndip->i_di.di_nlink == (uint32_t)-1) { + error = -EMLINK; + goto fail_gunlock; + } + } + } + + error = gfs_diradd_alloc_required(ndip, &ndentry->d_name, &alloc_required); + if (error) + goto fail_gunlock; + + if (alloc_required) { + al = gfs_alloc_get(ndip); + + error = gfs_quota_lock_m(ndip, + NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + if (error) + goto fail_alloc; + + error = gfs_quota_check(ndip, ndip->i_di.di_uid, ndip->i_di.di_gid); + if (error) + goto fail_gunlock_q; + + al->al_requested_meta = sdp->sd_max_dirres; + + error = gfs_inplace_reserve(ndip); + if (error) + goto fail_gunlock_q; + + /* Trans may require: + Dinodes for the srcdir, srcino, dstdir, dstino. Blocks for + adding the entry to dstdir. RG bitmaps for that allocation. + One leaf block in the srcdir for removal of the entry. + One leaf block for changing .. in srcino (if it's a directory). + Two leaf blocks for removing . and .. from dstino (if it exists + and it's a directory), one unlinked tag, and one quota block. */ + + error = gfs_trans_begin(sdp, + 8 + sdp->sd_max_dirres + + al->al_rgd->rd_ri.ri_length, + 2); + if (error) + goto fail_ipres; + } else { + /* Trans may require: + Dinodes for the srcdir, srcino, dstdir, dstino. One block for + adding the entry to dstdir. + One leaf block in the srcdir for removal of the entry. + One leaf block for changing .. in srcino (if it's a directory). + Two leaf blocks for removing . and .. from dstino (if it exists + and it's a directory), and one unlinked tag. */ + + error = gfs_trans_begin(sdp, 9, 1); + if (error) + goto fail_ipres; + } + + /* Remove the target file, if it exists */ + + if (nip) { + if (nip->i_di.di_type == GFS_FILE_DIR) + error = gfs_rmdiri(ndip, &ndentry->d_name, nip); + else + error = gfs_unlinki(ndip, &ndentry->d_name, nip); + + if (error) + goto fail_end_trans; + } + + if (dir_rename) { + error = gfs_change_nlink(ndip, +1); + if (error) + goto fail_end_trans; + error = gfs_change_nlink(odip, -1); + if (error) + goto fail_end_trans; + + name.len = 2; + name.name = ".."; + + error = gfs_dir_mvino(ip, &name, &ndip->i_num, GFS_FILE_DIR); + if (error) + goto fail_end_trans; + } + + error = gfs_dir_del(odip, &odentry->d_name); + if (error) + goto fail_end_trans; + + error = gfs_dir_add(ndip, &ndentry->d_name, &ip->i_num, ip->i_di.di_type); + if (error) + goto fail_end_trans; + + if (dir_rename) + gfs_trans_add_gl(sdp->sd_rename_gl); + + gfs_trans_end(sdp); + + if (alloc_required) { + /* Don't check al->al_alloced_meta and friends. */ + gfs_inplace_release(ndip); + gfs_quota_unlock_m(ndip); + gfs_alloc_put(ndip); + } + + gfs_glock_dq_m(num_gh, ghs); + + for (x = 0; x < num_gh; x++) + gfs_holder_uninit(&ghs[x]); + + if (dir_rename) + gfs_glock_dq_uninit(&r_gh); + + return 0; + + fail_end_trans: + gfs_trans_end(sdp); + + fail_ipres: + if (alloc_required) + gfs_inplace_release(ndip); + + fail_gunlock_q: + if (alloc_required) + gfs_quota_unlock_m(ndip); + + fail_alloc: + if (alloc_required) + gfs_alloc_put(ndip); + + fail_gunlock: + gfs_glock_dq_m(num_gh, ghs); + + fail_uninit: + for (x = 0; x < num_gh; x++) + gfs_holder_uninit(&ghs[x]); + + fail: + if (dir_rename) + gfs_glock_dq_uninit(&r_gh); + + return error; +} + +/** + * gfs_readlink - Read the value of a symlink + * @dentry: the symlink + * @buf: the buffer to read the symlink data into + * @size: the size of the buffer + * + * Returns: errno + */ + +static int +gfs_readlink(struct dentry *dentry, char *user_buf, int user_size) +{ + struct gfs_inode *ip = get_v2ip(dentry->d_inode); + char array[GFS_FAST_NAME_SIZE], *buf = array; + unsigned int len = GFS_FAST_NAME_SIZE; + int error; + + atomic_inc(&ip->i_sbd->sd_ops_inode); + + error = gfs_readlinki(ip, &buf, &len); + if (error) + return error; + + if (user_size > len - 1) + user_size = len - 1; + + if (copy_to_user(user_buf, buf, user_size)) + error = -EFAULT; + else + error = user_size; + + if (buf != array) + kfree(buf); + + return error; +} + +/** + * gfs_follow_link - Follow a symbolic link + * @dentry: The dentry of the link + * @nd: Data that we pass to vfs_follow_link() + * + * This can handle symlinks of any size. It is optimised for symlinks + * under GFS_FAST_NAME_SIZE. + * + * Returns: 0 on success or error code + */ + +static void * +gfs_follow_link(struct dentry *dentry, struct nameidata *nd) +{ + struct gfs_inode *ip = get_v2ip(dentry->d_inode); + char array[GFS_FAST_NAME_SIZE], *buf = array; + unsigned int len = GFS_FAST_NAME_SIZE; + int error; + + atomic_inc(&ip->i_sbd->sd_ops_inode); + + error = gfs_readlinki(ip, &buf, &len); + if (!error) { + error = vfs_follow_link(nd, buf); + if (buf != array) + kfree(buf); + } + + return ERR_PTR(error); +} + +/** + * gfs_permission_i - + * @inode: + * @mask: + * + * Shamelessly ripped from ext3 + * + * Returns: errno + */ + +static int +gfs_permission_i(struct inode *inode, int mask) +{ + return generic_permission(inode, mask, gfs_check_acl); +} + +/** + * gfs_permission - + * @inode: + * @mask: + * + * Returns: errno + */ + +static int +gfs_permission(struct inode *inode, int mask) +{ + struct gfs_inode *ip = get_v2ip(inode); + struct gfs_holder i_gh; + int error; + + atomic_inc(&ip->i_sbd->sd_ops_inode); + + error = gfs_glock_nq_init(ip->i_gl, + LM_ST_SHARED, LM_FLAG_ANY, + &i_gh); + if (error) + return error; + + error = gfs_permission_i(inode, mask); + + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gfs_setattr - Change attributes on an inode + * @dentry: The dentry which is changing + * @attr: The structure describing the change + * + * The VFS layer wants to change one or more of an inodes attributes. Write + * that change out to disk. + * + * Returns: errno + */ + +static int +gfs_setattr(struct dentry *dentry, struct iattr *attr) +{ + struct inode *inode = dentry->d_inode; + struct gfs_inode *ip = get_v2ip(inode); + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_holder i_gh; + int error; + + atomic_inc(&sdp->sd_ops_inode); + + /* Bugzilla 203170: we'll have the same deadlock as described + * in bugzilla 173912 if + * 1. without RHEL4's DIO_CLUSTER_LOCKING, and + * 2. we come down to this line of code from do_truncate() + * where i_sem(i_mutex) and i_alloc_sem have been taken, and + * 3. grab the exclusive glock here. + * To avoid this to happen, i_alloc_sem must be dropped and trust + * be put into glock that it can carry the same protection. + * + * One issue with dropping i_alloc_sem is that the gfs_setattr() + * can be invoked from other code path without this sempaphore. + * We'll need a new rwsem function that can "up" the semaphore + * only when it is needed. Before that happens (will research the + * possibility), i_alloc_sem (now) is a meaningless lock within + * GFS. If it is ever been used by other non-directIO code, this + * hack will fall apart. + * + * wcheng@redhat.com 10/14/06 + */ + if (attr->ia_valid & ATTR_SIZE) { + up_write(&dentry->d_inode->i_alloc_sem); + } + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); + + if (attr->ia_valid & ATTR_SIZE) { + down_write(&dentry->d_inode->i_alloc_sem); + } + + if (error) + return error; + + if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) { + error = -EPERM; + goto fail; + } + + error = inode_change_ok(inode, attr); + if (error) + goto fail; + + if (attr->ia_valid & ATTR_SIZE) { + error = inode_permission(inode, MAY_WRITE); + if (error) + goto fail; + + if (attr->ia_size != ip->i_di.di_size) { + error = vmtruncate(inode, attr->ia_size); + if (error) + goto fail; + } + + error = gfs_truncatei(ip, attr->ia_size, gfs_truncator_page); + if (error) { + if (inode->i_size != ip->i_di.di_size) + i_size_write(inode, ip->i_di.di_size); + goto fail; + } + + if ((sdp->sd_vfs->s_flags & MS_SYNCHRONOUS) && + !gfs_is_jdata(ip)) + i_gh.gh_flags |= GL_SYNC; + } + + else if (attr->ia_valid & (ATTR_UID | ATTR_GID)) { + struct gfs_alloc *al; + struct buffer_head *dibh; + uint32_t ouid, ogid, nuid, ngid; + + ouid = ip->i_di.di_uid; + ogid = ip->i_di.di_gid; + nuid = attr->ia_uid; + ngid = attr->ia_gid; + + if (!(attr->ia_valid & ATTR_UID) || ouid == nuid) + ouid = nuid = NO_QUOTA_CHANGE; + if (!(attr->ia_valid & ATTR_GID) || ogid == ngid) + ogid = ngid = NO_QUOTA_CHANGE; + + al = gfs_alloc_get(ip); + + error = gfs_quota_lock_m(ip, nuid, ngid); + if (error) + goto fail_alloc; + + if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { + error = gfs_quota_check(ip, nuid, ngid); + if (error) + goto fail_gunlock_q; + } + + /* Trans may require: + one dinode block and one quota change block */ + + error = gfs_trans_begin(sdp, 1, 1); + if (error) + goto fail_gunlock_q; + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto fail_end_trans; + + if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { + gfs_trans_add_quota(sdp, -ip->i_di.di_blocks, + ouid, ogid); + gfs_trans_add_quota(sdp, ip->i_di.di_blocks, + nuid, ngid); + } + + error = inode_setattr(inode, attr); + gfs_assert_warn(sdp, !error); + gfs_inode_attr_out(ip); + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + + gfs_trans_end(sdp); + + gfs_quota_unlock_m(ip); + gfs_alloc_put(ip); + } + + else if ((attr->ia_valid & ATTR_MODE) && IS_POSIXACL(inode)) { + error = gfs_acl_chmod(ip, attr); + if (error) + goto fail; + } + + else { + error = gfs_setattr_simple(ip, attr); + if (error) + goto fail; + } + + gfs_glock_dq_uninit(&i_gh); + + mark_inode_dirty(inode); + + return error; + + fail_end_trans: + gfs_trans_end(sdp); + + fail_gunlock_q: + gfs_quota_unlock_m(ip); + + fail_alloc: + gfs_alloc_put(ip); + + fail: + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gfs_getattr - Read out an inode's attributes + * @mnt: ? + * @dentry: The dentry to stat + * @stat: The inode's stats + * + * Returns: errno + */ + +static int +gfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) +{ + struct inode *inode = dentry->d_inode; + struct gfs_inode *ip = get_v2ip(inode); + struct gfs_holder gh; + int error; + + atomic_inc(&ip->i_sbd->sd_ops_inode); + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); + if (!error) { + generic_fillattr(inode, stat); + gfs_glock_dq_uninit(&gh); + } + + return error; +} + +/** + * gfs_setxattr - Set (or create or replace) an inode's extended attribute + * @dentry: + * @name: + * @data: + * @size: + * @flags: + * + * Returns: errno + */ + +int +gfs_setxattr(struct dentry *dentry, const char *name, + const void *data, size_t size, + int flags) +{ + struct gfs_ea_request er; + + atomic_inc(&get_v2sdp(dentry->d_inode->i_sb)->sd_ops_inode); + + memset(&er, 0, sizeof(struct gfs_ea_request)); + er.er_type = gfs_ea_name2type(name, &er.er_name); + if (er.er_type == GFS_EATYPE_UNUSED) + return -EOPNOTSUPP; + er.er_data = (char *)data; + er.er_name_len = strlen(er.er_name); + er.er_data_len = size; + er.er_flags = flags; + + return gfs_ea_set(get_v2ip(dentry->d_inode), &er); +} + +/** + * gfs_getxattr - + * @dentry: + * @name: + * @data: + * @size: + * + * Returns: The number of bytes put into data, or -errno + */ + +ssize_t +gfs_getxattr(struct dentry *dentry, const char *name, + void *data, size_t size) +{ + struct gfs_ea_request er; + + atomic_inc(&get_v2sdp(dentry->d_inode->i_sb)->sd_ops_inode); + + memset(&er, 0, sizeof(struct gfs_ea_request)); + er.er_type = gfs_ea_name2type(name, &er.er_name); + if (er.er_type == GFS_EATYPE_UNUSED) + return -EOPNOTSUPP; + er.er_data = data; + er.er_name_len = strlen(er.er_name); + er.er_data_len = size; + + return gfs_ea_get(get_v2ip(dentry->d_inode), &er); +} + +/** + * gfs_listxattr - + * @dentry: + * @buffer: + * @size: + * + * Returns: The number of bytes put into data, or -errno + */ + +ssize_t +gfs_listxattr(struct dentry *dentry, char *buffer, size_t size) +{ + struct gfs_ea_request er; + + atomic_inc(&get_v2sdp(dentry->d_inode->i_sb)->sd_ops_inode); + + memset(&er, 0, sizeof(struct gfs_ea_request)); + er.er_data = (size) ? buffer : NULL; + er.er_data_len = size; + + return gfs_ea_list(get_v2ip(dentry->d_inode), &er); +} + +/** + * gfs_removexattr - + * @dentry: + * @name: + * + * Returns: errno + */ + +int +gfs_removexattr(struct dentry *dentry, const char *name) +{ + struct gfs_ea_request er; + + atomic_inc(&get_v2sdp(dentry->d_inode->i_sb)->sd_ops_inode); + + memset(&er, 0, sizeof(struct gfs_ea_request)); + er.er_type = gfs_ea_name2type(name, &er.er_name); + if (er.er_type == GFS_EATYPE_UNUSED) + return -EOPNOTSUPP; + er.er_name_len = strlen(er.er_name); + + return gfs_ea_remove(get_v2ip(dentry->d_inode), &er); +} + +struct inode_operations gfs_file_iops = { + .permission = gfs_permission, + .setattr = gfs_setattr, + .getattr = gfs_getattr, + .setxattr = gfs_setxattr, + .getxattr = gfs_getxattr, + .listxattr = gfs_listxattr, + .removexattr = gfs_removexattr, +}; + +struct inode_operations gfs_dev_iops = { + .permission = gfs_permission, + .setattr = gfs_setattr, + .getattr = gfs_getattr, + .setxattr = gfs_setxattr, + .getxattr = gfs_getxattr, + .listxattr = gfs_listxattr, + .removexattr = gfs_removexattr, +}; + +struct inode_operations gfs_dir_iops = { + .create = gfs_create, + .lookup = gfs_lookup, + .link = gfs_link, + .unlink = gfs_unlink, + .symlink = gfs_symlink, + .mkdir = gfs_mkdir, + .rmdir = gfs_rmdir, + .mknod = gfs_mknod, + .rename = gfs_rename, + .permission = gfs_permission, + .setattr = gfs_setattr, + .getattr = gfs_getattr, + .setxattr = gfs_setxattr, + .getxattr = gfs_getxattr, + .listxattr = gfs_listxattr, + .removexattr = gfs_removexattr, +}; + +struct inode_operations gfs_symlink_iops = { + .readlink = gfs_readlink, + .follow_link = gfs_follow_link, + .permission = gfs_permission, + .setattr = gfs_setattr, + .getattr = gfs_getattr, + .setxattr = gfs_setxattr, + .getxattr = gfs_getxattr, + .listxattr = gfs_listxattr, + .removexattr = gfs_removexattr, +}; + --- linux-2.6.28.orig/ubuntu/gfs/eaops.h +++ linux-2.6.28/ubuntu/gfs/eaops.h @@ -0,0 +1,21 @@ +#ifndef __EAOPS_DOT_H__ +#define __EAOPS_DOT_H__ + +struct gfs_ea_request; + +struct gfs_eattr_operations { + int (*eo_get) (struct gfs_inode *ip, struct gfs_ea_request *er); + int (*eo_set) (struct gfs_inode *ip, struct gfs_ea_request *er); + int (*eo_remove) (struct gfs_inode *ip, struct gfs_ea_request *er); + char *eo_name; +}; + +unsigned int gfs_ea_name2type(const char *name, char **truncated_name); + +extern struct gfs_eattr_operations gfs_user_eaops; +extern struct gfs_eattr_operations gfs_system_eaops; + +extern struct gfs_eattr_operations *gfs_ea_ops[]; + +#endif /* __EAOPS_DOT_H__ */ + --- linux-2.6.28.orig/ubuntu/gfs/glops.c +++ linux-2.6.28/ubuntu/gfs/glops.c @@ -0,0 +1,664 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "dio.h" +#include "glock.h" +#include "glops.h" +#include "inode.h" +#include "log.h" +#include "page.h" +#include "recovery.h" +#include "rgrp.h" + +/** + * meta_go_sync - sync out the metadata for this glock + * @gl: the glock + * @flags: DIO_* + * + * Used for meta and rgrp glocks. + * + * Called when demoting (gfs_glock_xmote_th()) or unlocking + * (gfs_glock_drop_th() an EX glock at inter-node scope. We must flush + * to disk all dirty buffers/pages relating to this glock, and must not + * not return to caller to demote/unlock the glock until I/O is complete. + * + * This is *not* called from gfs_glock_dq(), because GL_SYNC flag is not + * currently used for anything but inode glocks. + */ + +static void +meta_go_sync(struct gfs_glock *gl, int flags) +{ + if (!(flags & DIO_METADATA)) + return; + + if (test_bit(GLF_DIRTY, &gl->gl_flags)) { + gfs_log_flush_glock(gl); + gfs_sync_buf(gl, flags | DIO_START | DIO_WAIT | DIO_CHECK); + } + + /* We've synced everything, clear SYNC request and DIRTY flags */ + clear_bit(GLF_DIRTY, &gl->gl_flags); + clear_bit(GLF_SYNC, &gl->gl_flags); +} + +/** + * meta_go_inval - invalidate the metadata for this glock + * @gl: the glock + * @flags: + * + */ + +static void +meta_go_inval(struct gfs_glock *gl, int flags) +{ + if (!(flags & DIO_METADATA)) + return; + + gfs_inval_buf(gl); + gl->gl_vn++; +} + +/** + * meta_go_demote_ok - Check to see if it's ok to unlock a meta glock + * @gl: the glock + * + * Returns: TRUE if we have no cached data; ok to demote meta glock + * + * Called when trying to dump (reclaim) a glock from the glock cache, after + * determining that there is currently no holder on this node for this glock, + * and before placing LM_ST_UNLOCKED request on glock's wait-for-demote queue. + * Note that callbacks from other nodes that need a lock do *not* + * seek permission from this function before requesting a demote. + * Nor do glocks obtained with the following flags (see demote_ok()): + * -- GL_NOCACHE: gets unlocked (and not cached) immediately after use + * -- GLF_STICKY: equivalent to always getting "FALSE" from this function + * -- GLF_PREFETCH: uses its own timeout + * + * For glocks that protect on-disk data (meta, inode, and rgrp glocks), disk + * accesses are slow, while lock manipulation is usually fast. Releasing + * a lock means that we: + * -- Must sync memory-cached write data to disk immediately, before another + * node can be granted the lock (at which point that node must read the + * data from disk). + * -- Must invalidate memory-cached data that we had read from or written + * to disk. Another node can change it if we don't have a lock, so it's + * now useless to us. + * + * Then, if we re-acquire the lock again in the future, we: + * -- Must (re-)read (perhaps unchanged) data from disk into memory. + * + * All of these are painful, so it pays to retain a glock in our glock cache + * as long as we have cached data (even though we have no active holders + * for this lock on this node currently), unless/until another node needs + * to change it. This allows Linux block I/O to sync write data to disk in + * a "lazy" way, rather than forcing an immediate sync (and resultant WAIT), + * and retains current data in memory as long as possible. + * + * This also helps GFS respond to memory pressure. There is no mechanism for + * the Linux virtual memory manager to directly call into GFS to ask it to + * drop locks. So, we take a hint from what the VM does to the page cache. + * When that cache is trimmed (and we see no more pages relating to this + * glock), we trim the glock cache as well, by releasing this lock. + */ + +static int +meta_go_demote_ok(struct gfs_glock *gl) +{ + return (gl->gl_aspace->i_mapping->nrpages) ? FALSE : TRUE; +} + +/** + * inode_go_xmote_th - promote/demote (but don't unlock) an inode glock + * @gl: the glock + * @state: the requested state + * @flags: the flags passed into gfs_glock() + * + * Acquire a new glock, or change an already-acquired glock to + * more/less restrictive state (other than LM_ST_UNLOCKED). + */ + +static void +inode_go_xmote_th(struct gfs_glock *gl, unsigned int state, int flags) +{ + if (gl->gl_state != LM_ST_UNLOCKED) + gfs_inval_pte(gl); + gfs_glock_xmote_th(gl, state, flags); +} + +/** + * inode_go_xmote_bh - After promoting/demoting (but not unlocking) + * an inode glock + * @gl: the glock + * + * FIXME: This will be really broken when (no_formal_ino != no_addr) + * and gl_name.ln_number no longer refers to the dinode block #. + * + * If we've just acquired the inter-node lock for an inode, + * read the dinode block from disk (but don't wait for I/O completion). + * Exceptions (don't read if): + * Glock state is UNLOCKED. + * Glock's requesting holder's GL_SKIP flag is set. + */ + +static void +inode_go_xmote_bh(struct gfs_glock *gl) +{ + struct gfs_holder *gh = gl->gl_req_gh; + struct buffer_head *bh; + int error; + + if (gl->gl_state != LM_ST_UNLOCKED && + (!gh || !(gh->gh_flags & GL_SKIP))) { + error = gfs_dread(gl, gl->gl_name.ln_number, DIO_START, &bh); + if (!error) + brelse(bh); + } +} + +/** + * inode_go_drop_th - unlock an inode glock + * @gl: the glock + * + * Invoked from rq_demote(). + * Another node needs the lock in EXCLUSIVE mode, or lock (unused for too long) + * is being purged from our node's glock cache; we're dropping lock. + */ + +static void +inode_go_drop_th(struct gfs_glock *gl) +{ + gfs_inval_pte(gl); + gfs_glock_drop_th(gl); +} + +/** + * inode_go_sync - Sync the dirty data and/or metadata for an inode glock + * @gl: the glock protecting the inode + * @flags: DIO_METADATA -- sync inode's metadata + * DIO_DATA -- sync inode's data + * DIO_INVISIBLE -- don't clear glock's DIRTY flag when done + * + * If DIO_INVISIBLE: + * 1) Called from gfs_glock_dq(), when releasing the last holder for an EX + * glock (but glock is still in our glock cache in EX state, and might + * stay there for a few minutes). Holder had GL_SYNC flag set, asking + * for early sync (i.e. now, instead of later when we release the EX at + * inter-node scope). GL_SYNC is currently used only for inodes in + * special cases, so inode is the only type of glock for which + * DIO_INVISIBLE would apply. + * 2) Called from depend_sync_one() to sync deallocated inode metadata + * before it can be reallocated by another process or machine. Since + * this call can happen at any time during the lifetime of the + * glock, don't clear the sync bit (more data might be dirtied + * momentarily). + * Else (later): + * Called when demoting (gfs_glock_xmote_th()) or unlocking + * (gfs_glock_drop_th() an EX glock at inter-node scope. We must flush + * to disk all dirty buffers/pages relating to this glock, and must not + * return to caller to demote/unlock the glock until I/O is complete. + * + * Syncs go in following order: + * Start data page writes + * Sync metadata to log (wait to complete I/O) + * Sync metadata to in-place location (wait to complete I/O) + * Wait for data page I/O to complete + * + */ + +static void +inode_go_sync(struct gfs_glock *gl, int flags) +{ + int meta = (flags & DIO_METADATA); + int data = (flags & DIO_DATA); + + if (test_bit(GLF_DIRTY, &gl->gl_flags)) { + if (meta && data) { + gfs_sync_page(gl, flags | DIO_START); + gfs_log_flush_glock(gl); + gfs_sync_buf(gl, flags | DIO_START | DIO_WAIT | DIO_CHECK); + gfs_sync_page(gl, flags | DIO_WAIT | DIO_CHECK); + } else if (meta) { + gfs_log_flush_glock(gl); + gfs_sync_buf(gl, flags | DIO_START | DIO_WAIT | DIO_CHECK); + } else if (data) + gfs_sync_page(gl, flags | DIO_START | DIO_WAIT | DIO_CHECK); + } + + /* If we've synced everything, clear the SYNC request. + If we're doing the final (not early) sync, clear DIRTY */ + if (meta && data) { + if (!(flags & DIO_INVISIBLE)) + clear_bit(GLF_DIRTY, &gl->gl_flags); + clear_bit(GLF_SYNC, &gl->gl_flags); + } +} + +/** + * inode_go_inval - prepare a inode glock to be released + * @gl: the glock + * @flags: + * + */ + +static void +inode_go_inval(struct gfs_glock *gl, int flags) +{ + int meta = (flags & DIO_METADATA); + int data = (flags & DIO_DATA); + + if (meta) { + gfs_inval_buf(gl); + gl->gl_vn++; + } + if (data) + gfs_inval_page(gl); +} + +/** + * inode_go_demote_ok - Check to see if it's ok to unlock an inode glock + * @gl: the glock + * + * See comments for meta_go_demote_ok(). + * + * While other glock types (meta, rgrp) that protect disk data can be retained + * indefinitely, GFS imposes a timeout (overridden when using no_lock lock + * module) for inode glocks, even if there is still data in page cache for + * this inode. + * + * Returns: TRUE if it's ok + */ + +static int +inode_go_demote_ok(struct gfs_glock *gl) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + int demote = FALSE; + + if (!get_gl2ip(gl) && !gl->gl_aspace->i_mapping->nrpages) + demote = TRUE; + else if (!sdp->sd_args.ar_localcaching && + time_after_eq(jiffies, gl->gl_stamp + gfs_tune_get(sdp, gt_demote_secs) * HZ)) + demote = TRUE; + + return demote; +} + +/** + * inode_go_lock - operation done after an inode lock is locked by + * a first holder on this node + * @gl: the glock + * @flags: the flags passed into gfs_glock() + * + * Returns: errno + */ + +static int +inode_go_lock(struct gfs_glock *gl, int flags) +{ + struct gfs_inode *ip = get_gl2ip(gl); + int error = 0; + + if (ip && ip->i_vn != gl->gl_vn) { + error = gfs_copyin_dinode(ip); + if (!error) + gfs_inode_attr_in(ip); + } + + return error; +} + +/** + * inode_go_unlock - operation done when an inode lock is unlocked by + * a last holder on this node + * @gl: the glock + * @flags: the flags passed into gfs_gunlock() + * + */ + +static void +inode_go_unlock(struct gfs_glock *gl, int flags) +{ + struct gfs_inode *ip = get_gl2ip(gl); + + if (ip && test_bit(GLF_DIRTY, &gl->gl_flags)) + gfs_inode_attr_in(ip); + + if (ip) + gfs_flush_meta_cache(ip); +} + +/** + * inode_greedy - + * @gl: the glock + * + */ + +static void +inode_greedy(struct gfs_glock *gl) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_inode *ip = get_gl2ip(gl); + unsigned int quantum = gfs_tune_get(sdp, gt_greedy_quantum); + unsigned int max = gfs_tune_get(sdp, gt_greedy_max); + unsigned int new_time; + + spin_lock(&ip->i_spin); + + if (time_after(ip->i_last_pfault + quantum, jiffies)) { + new_time = ip->i_greedy + quantum; + if (new_time > max) + new_time = max; + } else { + new_time = ip->i_greedy - quantum; + if (!new_time || new_time > max) + new_time = 1; + } + + ip->i_greedy = new_time; + + spin_unlock(&ip->i_spin); + + gfs_inode_put(ip); +} + +/** + * rgrp_go_xmote_th - promote/demote (but don't unlock) a resource group glock + * @gl: the glock + * @state: the requested state + * @flags: the flags passed into gfs_glock() + * + * Acquire a new glock, or change an already-acquired glock to + * more/less restrictive state (other than LM_ST_UNLOCKED). + * + * We're going to lock the lock in SHARED or EXCLUSIVE state, or + * demote it from EXCLUSIVE to SHARED (because another node needs it SHARED). + * When locking, gfs_mhc_zap() and gfs_depend_sync() are basically no-ops; + * meta-header cache and dependency lists should be empty. + * + */ + +static void +rgrp_go_xmote_th(struct gfs_glock *gl, unsigned int state, int flags) +{ + struct gfs_rgrpd *rgd = get_gl2rgd(gl); + + gfs_mhc_zap(rgd); + gfs_depend_sync(rgd); + gfs_glock_xmote_th(gl, state, flags); +} + +/** + * rgrp_go_drop_th - unlock a resource group glock + * @gl: the glock + * + * Invoked from rq_demote(). + * Another node needs the lock in EXCLUSIVE mode, or lock (unused for too long) + * is being purged from our node's glock cache; we're dropping lock. + */ + +static void +rgrp_go_drop_th(struct gfs_glock *gl) +{ + struct gfs_rgrpd *rgd = get_gl2rgd(gl); + + gfs_mhc_zap(rgd); + gfs_depend_sync(rgd); + gfs_glock_drop_th(gl); +} + +/** + * rgrp_go_demote_ok - Check to see if it's ok to unlock a RG's glock + * @gl: the glock + * + * See comments for meta_go_demote_ok(). + * + * In addition to Linux page cache, we also check GFS meta-header-cache. + * + * Returns: TRUE if it's ok + */ + +static int +rgrp_go_demote_ok(struct gfs_glock *gl) +{ + struct gfs_rgrpd *rgd = get_gl2rgd(gl); + int demote = TRUE; + + if (gl->gl_aspace->i_mapping->nrpages) + demote = FALSE; + else if (rgd && !list_empty(&rgd->rd_mhc)) /* Don't bother with lock here */ + demote = FALSE; + + return demote; +} + +/** + * rgrp_go_lock - operation done after an rgrp lock is locked by + * a first holder on this node. + * @gl: the glock + * @flags: the flags passed into gfs_glock() + * + * Returns: errno + * + * Read rgrp's header and block allocation bitmaps from disk. + */ + +static int +rgrp_go_lock(struct gfs_glock *gl, int flags) +{ + if (flags & GL_SKIP) + return 0; + return gfs_rgrp_read(get_gl2rgd(gl)); +} + +/** + * rgrp_go_unlock - operation done when an rgrp lock is unlocked by + * a last holder on this node. + * @gl: the glock + * @flags: the flags passed into gfs_gunlock() + * + * Release rgrp's bitmap buffers (read in when lock was first obtained). + * Make sure rgrp's glock's Lock Value Block has up-to-date block usage stats, + * so other nodes can see them. + */ + +static void +rgrp_go_unlock(struct gfs_glock *gl, int flags) +{ + struct gfs_rgrpd *rgd = get_gl2rgd(gl); + if (flags & GL_SKIP) + return; + gfs_rgrp_relse(rgd); + if (test_bit(GLF_DIRTY, &gl->gl_flags)) + gfs_rgrp_lvb_fill(rgd); +} + +/** + * trans_go_xmote_th - promote/demote (but don't unlock) the transaction glock + * @gl: the glock + * @state: the requested state + * @flags: the flags passed into gfs_glock() + * + * Acquire a new glock, or change an already-acquired glock to + * more/less restrictive state (other than LM_ST_UNLOCKED). + */ + +static void +trans_go_xmote_th(struct gfs_glock *gl, unsigned int state, int flags) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + + if (gl->gl_state != LM_ST_UNLOCKED && + test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { + gfs_sync_meta(sdp); + gfs_log_shutdown(sdp); + } + + gfs_glock_xmote_th(gl, state, flags); +} + +/** + * trans_go_xmote_bh - After promoting/demoting (but not unlocking) + * the transaction glock + * @gl: the glock + * + */ + +static void +trans_go_xmote_bh(struct gfs_glock *gl) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_glock *j_gl = sdp->sd_journal_gh.gh_gl; + struct gfs_log_header head; + int error; + + if (gl->gl_state != LM_ST_UNLOCKED && + test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { + j_gl->gl_ops->go_inval(j_gl, DIO_METADATA | DIO_DATA); + + error = gfs_find_jhead(sdp, &sdp->sd_jdesc, j_gl, &head); + if (error) + gfs_consist(sdp); + if (!(head.lh_flags & GFS_LOG_HEAD_UNMOUNT)) + gfs_consist(sdp); + + /* Initialize some head of the log stuff */ + if (!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) { + sdp->sd_sequence = head.lh_sequence; + sdp->sd_log_head = head.lh_first + 1; + } + } +} + +/** + * trans_go_drop_th - unlock the transaction glock + * @gl: the glock + * + * Invoked from rq_demote(). + * Another node needs the lock in EXCLUSIVE mode to quiesce the filesystem + * (for journal replay, etc.). + * + * We want to sync the device even with localcaching. Remember + * that localcaching journal replay only marks buffers dirty. + */ + +static void +trans_go_drop_th(struct gfs_glock *gl) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + + if (test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { + gfs_sync_meta(sdp); + gfs_log_shutdown(sdp); + } + + gfs_glock_drop_th(gl); +} + +/** + * nondisk_go_demote_ok - Check to see if it's ok to unlock a non-disk glock + * @gl: the glock + * + * See comments for meta_go_demote_ok(). + * + * We never give up a non-disk glock (unless another node needs it). + * Non-disk type used for GFS_MOUNT_LOCK, GFS_LIVE_LOCK, GFS_RENAME_LOCK. + * GFS_MOUNT_LOCK is always requested GL_NOCACHE, however, so it never uses + * this function. + * + * Returns: TRUE if it's ok + */ + +static int +nondisk_go_demote_ok(struct gfs_glock *gl) +{ + return FALSE; +} + +/** + * quota_go_demote_ok - Check to see if it's ok to unlock a quota glock + * @gl: the glock + * + * See comments for meta_go_demote_ok(). + * + * Returns: TRUE if it's ok + */ + +static int +quota_go_demote_ok(struct gfs_glock *gl) +{ + return !atomic_read(&gl->gl_lvb_count); +} + +struct gfs_glock_operations gfs_meta_glops = { + .go_xmote_th = gfs_glock_xmote_th, + .go_drop_th = gfs_glock_drop_th, + .go_sync = meta_go_sync, + .go_inval = meta_go_inval, + .go_demote_ok = meta_go_demote_ok, + .go_type = LM_TYPE_META +}; + +struct gfs_glock_operations gfs_inode_glops = { + .go_xmote_th = inode_go_xmote_th, + .go_xmote_bh = inode_go_xmote_bh, + .go_drop_th = inode_go_drop_th, + .go_sync = inode_go_sync, + .go_inval = inode_go_inval, + .go_demote_ok = inode_go_demote_ok, + .go_lock = inode_go_lock, + .go_unlock = inode_go_unlock, + .go_greedy = inode_greedy, + .go_type = LM_TYPE_INODE +}; + +struct gfs_glock_operations gfs_rgrp_glops = { + .go_xmote_th = rgrp_go_xmote_th, + .go_drop_th = rgrp_go_drop_th, + .go_sync = meta_go_sync, + .go_inval = meta_go_inval, + .go_demote_ok = rgrp_go_demote_ok, + .go_lock = rgrp_go_lock, + .go_unlock = rgrp_go_unlock, + .go_type = LM_TYPE_RGRP +}; + +struct gfs_glock_operations gfs_trans_glops = { + .go_xmote_th = trans_go_xmote_th, + .go_xmote_bh = trans_go_xmote_bh, + .go_drop_th = trans_go_drop_th, + .go_type = LM_TYPE_NONDISK +}; + +struct gfs_glock_operations gfs_iopen_glops = { + .go_xmote_th = gfs_glock_xmote_th, + .go_drop_th = gfs_glock_drop_th, + .go_callback = gfs_iopen_go_callback, + .go_type = LM_TYPE_IOPEN +}; + +struct gfs_glock_operations gfs_flock_glops = { + .go_xmote_th = gfs_glock_xmote_th, + .go_drop_th = gfs_glock_drop_th, + .go_type = LM_TYPE_FLOCK +}; + +struct gfs_glock_operations gfs_nondisk_glops = { + .go_xmote_th = gfs_glock_xmote_th, + .go_drop_th = gfs_glock_drop_th, + .go_demote_ok = nondisk_go_demote_ok, + .go_type = LM_TYPE_NONDISK +}; + +struct gfs_glock_operations gfs_quota_glops = { + .go_xmote_th = gfs_glock_xmote_th, + .go_drop_th = gfs_glock_drop_th, + .go_demote_ok = quota_go_demote_ok, + .go_type = LM_TYPE_QUOTA +}; --- linux-2.6.28.orig/ubuntu/gfs/lock_dlm.h +++ linux-2.6.28/ubuntu/gfs/lock_dlm.h @@ -0,0 +1,182 @@ +/* + * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. + * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License version 2. + */ + +#ifndef LOCK_DLM_DOT_H +#define LOCK_DLM_DOT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "lm_interface.h" + +/* + * Internally, we prefix things with gdlm_ and GDLM_ (for gfs-dlm) since a + * prefix of lock_dlm_ gets awkward. Externally, GFS refers to this module + * as "lock_dlm". + */ + +#define GDLM_STRNAME_BYTES 24 +#define GDLM_LVB_SIZE 32 +#define GDLM_DROP_COUNT 0 +#define GDLM_DROP_PERIOD 60 +#define GDLM_NAME_LEN 128 + +/* GFS uses 12 bytes to identify a resource (32 bit type + 64 bit number). + We sprintf these numbers into a 24 byte string of hex values to make them + human-readable (to make debugging simpler.) */ + +struct gdlm_strname { + unsigned char name[GDLM_STRNAME_BYTES]; + unsigned short namelen; +}; + +enum { + DFL_BLOCK_LOCKS = 0, + DFL_SPECTATOR = 1, + DFL_WITHDRAW = 2, +}; + +struct gdlm_ls { + u32 id; + int jid; + int first; + int first_done; + unsigned long flags; + struct kobject kobj; + char clustername[GDLM_NAME_LEN]; + char fsname[GDLM_NAME_LEN]; + int fsflags; + dlm_lockspace_t *dlm_lockspace; + lm_callback_t fscb; + struct gfs_sbd *sdp; + int recover_jid; + int recover_jid_done; + int recover_jid_status; + spinlock_t async_lock; + struct list_head complete; + struct list_head blocking; + struct list_head delayed; + struct list_head submit; + struct list_head all_locks; + u32 all_locks_count; + wait_queue_head_t wait_control; + struct task_struct *thread1; + struct task_struct *thread2; + wait_queue_head_t thread_wait; + unsigned long drop_time; + int drop_locks_count; + int drop_locks_period; +}; + +enum { + LFL_NOBLOCK = 0, + LFL_NOCACHE = 1, + LFL_DLM_UNLOCK = 2, + LFL_DLM_CANCEL = 3, + LFL_SYNC_LVB = 4, + LFL_FORCE_PROMOTE = 5, + LFL_REREQUEST = 6, + LFL_ACTIVE = 7, + LFL_INLOCK = 8, + LFL_CANCEL = 9, + LFL_NOBAST = 10, + LFL_HEADQUE = 11, + LFL_UNLOCK_DELETE = 12, + LFL_AST_WAIT = 13, +}; + +struct gdlm_lock { + struct gdlm_ls *ls; + struct lm_lockname lockname; + struct gdlm_strname strname; + char *lvb; + struct dlm_lksb lksb; + + s16 cur; + s16 req; + s16 prev_req; + u32 lkf; /* dlm flags DLM_LKF_ */ + unsigned long flags; /* lock_dlm flags LFL_ */ + + int bast_mode; /* protected by async_lock */ + + struct list_head clist; /* complete */ + struct list_head blist; /* blocking */ + struct list_head delay_list; /* delayed */ + struct list_head all_list; /* all locks for the fs */ + struct gdlm_lock *hold_null; /* NL lock for hold_lvb */ +}; + +#define gdlm_assert(assertion, fmt, args...) \ +do { \ + if (unlikely(!(assertion))) { \ + printk(KERN_EMERG "lock_dlm: fatal assertion failed \"%s\"\n" \ + "lock_dlm: " fmt "\n", \ + #assertion, ##args); \ + BUG(); \ + } \ +} while (0) + +#define log_print(lev, fmt, arg...) printk(lev "lock_dlm: " fmt "\n" , ## arg) +#define log_info(fmt, arg...) log_print(KERN_INFO , fmt , ## arg) +#define log_error(fmt, arg...) log_print(KERN_ERR , fmt , ## arg) +#ifdef LOCK_DLM_LOG_DEBUG +#define log_debug(fmt, arg...) log_print(KERN_DEBUG , fmt , ## arg) +#else +#define log_debug(fmt, arg...) +#endif + +/* sysfs.c */ + +int gdlm_sysfs_init(void); +void gdlm_sysfs_exit(void); +int gdlm_kobject_setup(struct gdlm_ls *, struct kobject *); +void gdlm_kobject_release(struct gdlm_ls *); + +/* thread.c */ + +int gdlm_init_threads(struct gdlm_ls *); +void gdlm_release_threads(struct gdlm_ls *); + +/* lock.c */ + +s16 gdlm_make_lmstate(s16); +void gdlm_queue_delayed(struct gdlm_lock *); +void gdlm_submit_delayed(struct gdlm_ls *); +int gdlm_release_all_locks(struct gdlm_ls *); +void gdlm_delete_lp(struct gdlm_lock *); +unsigned int gdlm_do_lock(struct gdlm_lock *); + +int gdlm_get_lock(void *, struct lm_lockname *, void **); +void gdlm_put_lock(void *); +unsigned int gdlm_lock(void *, unsigned int, unsigned int, unsigned int); +unsigned int gdlm_unlock(void *, unsigned int); +void gdlm_cancel(void *); +int gdlm_hold_lvb(void *, char **); +void gdlm_unhold_lvb(void *, char *); + +/* mount.c */ + +extern const struct lm_lockops gdlm_ops; + +#endif + --- linux-2.6.28.orig/ubuntu/gfs/lm_interface.h +++ linux-2.6.28/ubuntu/gfs/lm_interface.h @@ -0,0 +1,278 @@ +/* + * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. + * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License version 2. + */ + +#ifndef __LM_INTERFACE_DOT_H__ +#define __LM_INTERFACE_DOT_H__ + + +typedef void (*lm_callback_t) (void *ptr, unsigned int type, void *data); + +/* + * lm_mount() flags + * + * LM_MFLAG_SPECTATOR + * GFS is asking to join the filesystem's lockspace, but it doesn't want to + * modify the filesystem. The lock module shouldn't assign a journal to the FS + * mount. It shouldn't send recovery callbacks to the FS mount. If the node + * dies or withdraws, all locks can be wiped immediately. + */ + +#define LM_MFLAG_SPECTATOR 0x00000001 + +/* + * lm_lockstruct flags + * + * LM_LSFLAG_LOCAL + * The lock_nolock module returns LM_LSFLAG_LOCAL to GFS, indicating that GFS + * can make single-node optimizations. + */ + +#define LM_LSFLAG_LOCAL 0x00000001 + +/* + * lm_lockname types + */ + +#define LM_TYPE_RESERVED 0x00 +#define LM_TYPE_NONDISK 0x01 +#define LM_TYPE_INODE 0x02 +#define LM_TYPE_RGRP 0x03 +#define LM_TYPE_META 0x04 +#define LM_TYPE_IOPEN 0x05 +#define LM_TYPE_FLOCK 0x06 +#define LM_TYPE_PLOCK 0x07 +#define LM_TYPE_QUOTA 0x08 +#define LM_TYPE_JOURNAL 0x09 + +/* + * lm_lock() states + * + * SHARED is compatible with SHARED, not with DEFERRED or EX. + * DEFERRED is compatible with DEFERRED, not with SHARED or EX. + */ + +#define LM_ST_UNLOCKED 0 +#define LM_ST_EXCLUSIVE 1 +#define LM_ST_DEFERRED 2 +#define LM_ST_SHARED 3 + +/* + * lm_lock() flags + * + * LM_FLAG_TRY + * Don't wait to acquire the lock if it can't be granted immediately. + * + * LM_FLAG_TRY_1CB + * Send one blocking callback if TRY is set and the lock is not granted. + * + * LM_FLAG_NOEXP + * GFS sets this flag on lock requests it makes while doing journal recovery. + * These special requests should not be blocked due to the recovery like + * ordinary locks would be. + * + * LM_FLAG_ANY + * A SHARED request may also be granted in DEFERRED, or a DEFERRED request may + * also be granted in SHARED. The preferred state is whichever is compatible + * with other granted locks, or the specified state if no other locks exist. + * + * LM_FLAG_PRIORITY + * Override fairness considerations. Suppose a lock is held in a shared state + * and there is a pending request for the deferred state. A shared lock + * request with the priority flag would be allowed to bypass the deferred + * request and directly join the other shared lock. A shared lock request + * without the priority flag might be forced to wait until the deferred + * requested had acquired and released the lock. + */ + +#define LM_FLAG_TRY 0x00000001 +#define LM_FLAG_TRY_1CB 0x00000002 +#define LM_FLAG_NOEXP 0x00000004 +#define LM_FLAG_ANY 0x00000008 +#define LM_FLAG_PRIORITY 0x00000010 + +/* + * lm_lock() and lm_async_cb return flags + * + * LM_OUT_ST_MASK + * Masks the lower two bits of lock state in the returned value. + * + * LM_OUT_CACHEABLE + * The lock hasn't been released so GFS can continue to cache data for it. + * + * LM_OUT_CANCELED + * The lock request was canceled. + * + * LM_OUT_ASYNC + * The result of the request will be returned in an LM_CB_ASYNC callback. + */ + +#define LM_OUT_ST_MASK 0x00000003 +#define LM_OUT_CACHEABLE 0x00000004 +#define LM_OUT_CANCELED 0x00000008 +#define LM_OUT_ASYNC 0x00000080 +#define LM_OUT_ERROR 0x00000100 + +/* + * lm_callback_t types + * + * LM_CB_NEED_E LM_CB_NEED_D LM_CB_NEED_S + * Blocking callback, a remote node is requesting the given lock in + * EXCLUSIVE, DEFERRED, or SHARED. + * + * LM_CB_NEED_RECOVERY + * The given journal needs to be recovered. + * + * LM_CB_DROPLOCKS + * Reduce the number of cached locks. + * + * LM_CB_ASYNC + * The given lock has been granted. + */ + +#define LM_CB_NEED_E 257 +#define LM_CB_NEED_D 258 +#define LM_CB_NEED_S 259 +#define LM_CB_NEED_RECOVERY 260 +#define LM_CB_DROPLOCKS 261 +#define LM_CB_ASYNC 262 + +/* + * lm_recovery_done() messages + */ + +#define LM_RD_GAVEUP 308 +#define LM_RD_SUCCESS 309 + + +struct lm_lockname { + u64 ln_number; + unsigned int ln_type; +}; + +#define lm_name_equal(name1, name2) \ + (((name1)->ln_number == (name2)->ln_number) && \ + ((name1)->ln_type == (name2)->ln_type)) \ + +struct lm_async_cb { + struct lm_lockname lc_name; + int lc_ret; +}; + +struct lm_lockstruct; + +struct lm_lockops { + const char *lm_proto_name; + + /* + * Mount/Unmount + */ + + int (*lm_mount) (char *table_name, char *host_data, + lm_callback_t cb, void *cb_data, + unsigned int min_lvb_size, int flags, + struct lm_lockstruct *lockstruct, + struct kobject *fskobj); + + void (*lm_others_may_mount) (void *lockspace); + + void (*lm_unmount) (void *lockspace); + + void (*lm_withdraw) (void *lockspace); + + /* + * Lock oriented operations + */ + + int (*lm_get_lock) (void *lockspace, struct lm_lockname *name, void **lockp); + + void (*lm_put_lock) (void *lock); + + unsigned int (*lm_lock) (void *lock, unsigned int cur_state, + unsigned int req_state, unsigned int flags); + + unsigned int (*lm_unlock) (void *lock, unsigned int cur_state); + + void (*lm_cancel) (void *lock); + + int (*lm_hold_lvb) (void *lock, char **lvbp); + void (*lm_unhold_lvb) (void *lock, char *lvb); + + /* + * Posix Lock oriented operations + */ + + int (*lm_plock_get) (void *lockspace, struct lm_lockname *name, + struct file *file, struct file_lock *fl); + + int (*lm_plock) (void *lockspace, struct lm_lockname *name, + struct file *file, int cmd, struct file_lock *fl); + + int (*lm_punlock) (void *lockspace, struct lm_lockname *name, + struct file *file, struct file_lock *fl); + + /* + * Client oriented operations + */ + + void (*lm_recovery_done) (void *lockspace, unsigned int jid, + unsigned int message); + + struct module *lm_owner; +}; + +/* + * lm_mount() return values + * + * ls_jid - the journal ID this node should use + * ls_first - this node is the first to mount the file system + * ls_lvb_size - size in bytes of lock value blocks + * ls_lockspace - lock module's context for this file system + * ls_ops - lock module's functions + * ls_flags - lock module features + */ + +struct lm_lockstruct { + unsigned int ls_jid; + unsigned int ls_first; + unsigned int ls_lvb_size; + void *ls_lockspace; + const struct lm_lockops *ls_ops; + int ls_flags; +}; + +/* + * Lock module bottom interface. A lock module makes itself available to GFS + * with these functions. + */ + +int gfs_register_lockproto(const struct lm_lockops *proto); +void gfs_unregister_lockproto(const struct lm_lockops *proto); + +/* + * Lock module top interface. GFS calls these functions when mounting or + * unmounting a file system. + */ + +int gfs_mount_lockproto(char *proto_name, char *table_name, char *host_data, + lm_callback_t cb, void *cb_data, + unsigned int min_lvb_size, int flags, + struct lm_lockstruct *lockstruct, + struct kobject *fskobj); + +void gfs_unmount_lockproto(struct lm_lockstruct *lockstruct); + +void gfs_withdraw_lockproto(struct lm_lockstruct *lockstruct); + +int init_lock_dlm(void); +void exit_lock_dlm(void); +int init_nolock(void); +void exit_nolock(void); + +#endif /* __LM_INTERFACE_DOT_H__ */ + --- linux-2.6.28.orig/ubuntu/gfs/bmap.c +++ linux-2.6.28/ubuntu/gfs/bmap.c @@ -0,0 +1,1393 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "bmap.h" +#include "dio.h" +#include "glock.h" +#include "inode.h" +#include "quota.h" +#include "rgrp.h" +#include "trans.h" + +struct metapath { + unsigned int mp_list[GFS_MAX_META_HEIGHT]; +}; + +typedef int (*block_call_t) (struct gfs_inode *ip, struct buffer_head *dibh, + struct buffer_head *bh, uint64_t *top, + uint64_t *bottom, unsigned int height, + void *data); + +struct strip_mine { + int sm_first; + unsigned int sm_height; +}; + +/** + * gfs_unstuffer_sync - unstuff a dinode synchronously + * @ip: the inode + * @dibh: the dinode buffer + * @block: the block number that was allocated + * @private: not used + * + * Returns: errno + */ + +int +gfs_unstuffer_sync(struct gfs_inode *ip, struct buffer_head *dibh, + uint64_t block, void *private) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head *bh; + int error; + + error = gfs_get_data_buffer(ip, block, TRUE, &bh); + if (error) + return error; + + gfs_buffer_copy_tail(bh, 0, dibh, sizeof(struct gfs_dinode)); + + error = gfs_dwrite(sdp, bh, DIO_DIRTY | DIO_START | DIO_WAIT); + + brelse(bh); + + return error; +} + +/** + * gfs_unstuffer_async - unstuff a dinode asynchronously + * @ip: the inode + * @dibh: the dinode buffer + * @block: the block number that was allocated + * @private: not used + * + * Returns: errno + */ + +int +gfs_unstuffer_async(struct gfs_inode *ip, struct buffer_head *dibh, + uint64_t block, void *private) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head *bh; + int error; + + error = gfs_get_data_buffer(ip, block, TRUE, &bh); + if (error) + return error; + + gfs_buffer_copy_tail(bh, 0, dibh, sizeof(struct gfs_dinode)); + + error = gfs_dwrite(sdp, bh, DIO_DIRTY); + + brelse(bh); + + return error; +} + +/** + * gfs_unstuff_dinode - Unstuff a dinode when the data has grown too big + * @ip: The GFS inode to unstuff + * @unstuffer: the routine that handles unstuffing a non-zero length file + * @private: private data for the unstuffer + * + * This routine unstuffs a dinode and returns it to a "normal" state such + * that the height can be grown in the traditional way. + * + * Returns: errno + */ + +int +gfs_unstuff_dinode(struct gfs_inode *ip, gfs_unstuffer_t unstuffer, + void *private) +{ + struct buffer_head *bh, *dibh; + uint64_t block = 0; + int journaled = gfs_is_jdata(ip); + int error; + + down_write(&ip->i_rw_mutex); + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto out; + + if (ip->i_di.di_size) { + /* Get a free block, fill it with the stuffed data, + and write it out to disk */ + + if (journaled) { + error = gfs_metaalloc(ip, &block); + if (error) + goto out_brelse; + + error = gfs_get_data_buffer(ip, block, TRUE, &bh); + if (error) + goto out_brelse; + + gfs_buffer_copy_tail(bh, sizeof(struct gfs_meta_header), + dibh, sizeof(struct gfs_dinode)); + + brelse(bh); + } else { + gfs_blkalloc(ip, &block); + + error = unstuffer(ip, dibh, block, private); + if (error) + goto out_brelse; + } + } + + /* Set up the pointer to the new block */ + + gfs_trans_add_bh(ip->i_gl, dibh); + + gfs_buffer_clear_tail(dibh, sizeof(struct gfs_dinode)); + + if (ip->i_di.di_size) { + *(uint64_t *)(dibh->b_data + sizeof(struct gfs_dinode)) = cpu_to_gfs64(block); + ip->i_di.di_blocks++; + } + + ip->i_di.di_height = 1; + + gfs_dinode_out(&ip->i_di, dibh->b_data); + + out_brelse: + brelse(dibh); + + out: + up_write(&ip->i_rw_mutex); + + return error; +} + +/** + * calc_tree_height - Calculate the height of a metadata tree + * @ip: The GFS inode + * @size: The proposed size of the file + * + * Work out how tall a metadata tree needs to be in order to accommodate a + * file of a particular size. If size is less than the current size of + * the inode, then the current size of the inode is used instead of the + * supplied one. + * + * Returns: the height the tree should be + */ + +static unsigned int +calc_tree_height(struct gfs_inode *ip, uint64_t size) +{ + struct gfs_sbd *sdp = ip->i_sbd; + uint64_t *arr; + unsigned int max, height; + + if (ip->i_di.di_size > size) + size = ip->i_di.di_size; + + if (gfs_is_jdata(ip)) { + arr = sdp->sd_jheightsize; + max = sdp->sd_max_jheight; + } else { + arr = sdp->sd_heightsize; + max = sdp->sd_max_height; + } + + for (height = 0; height < max; height++) + if (arr[height] >= size) + break; + + return height; +} + +/** + * build_height - Build a metadata tree of the requested height + * @ip: The GFS inode + * @height: The height to build to + * + * This routine makes sure that the metadata tree is tall enough to hold + * "size" bytes of data. + * + * Returns: errno + */ + +static int +build_height(struct gfs_inode *ip, int height) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head *bh, *dibh; + uint64_t block, *bp; + unsigned int x; + int new_block; + int error; + + while (ip->i_di.di_height < height) { + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + return error; + + new_block = FALSE; + bp = (uint64_t *)(dibh->b_data + sizeof(struct gfs_dinode)); + for (x = 0; x < sdp->sd_diptrs; x++, bp++) + if (*bp) { + new_block = TRUE; + break; + } + + if (new_block) { + /* Get a new block, fill it with the old direct pointers, + and write it out */ + + error = gfs_metaalloc(ip, &block); + if (error) + goto fail; + + error = gfs_dread(ip->i_gl, block, + DIO_NEW | DIO_START | DIO_WAIT, &bh); + if (error) + goto fail; + + gfs_trans_add_bh(ip->i_gl, bh); + gfs_metatype_set(bh, + GFS_METATYPE_IN, + GFS_FORMAT_IN); + memset(bh->b_data + sizeof(struct gfs_meta_header), + 0, + sizeof(struct gfs_indirect) - + sizeof(struct gfs_meta_header)); + gfs_buffer_copy_tail(bh, sizeof(struct gfs_indirect), + dibh, sizeof(struct gfs_dinode)); + + brelse(bh); + } + + /* Set up the new direct pointer and write it out to disk */ + + gfs_trans_add_bh(ip->i_gl, dibh); + + gfs_buffer_clear_tail(dibh, sizeof(struct gfs_dinode)); + + if (new_block) { + *(uint64_t *)(dibh->b_data + sizeof(struct gfs_dinode)) = cpu_to_gfs64(block); + ip->i_di.di_blocks++; + } + + ip->i_di.di_height++; + + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + + return 0; + + fail: + brelse(dibh); + + return error; +} + +/** + * find_metapath - Find path through the metadata tree + * @ip: The inode pointer + * @mp: The metapath to return the result in + * @block: The disk block to look up + * + * This routine returns a struct metapath structure that defines a path through + * the metadata of inode "ip" to get to block "block". + * + * Example: + * Given: "ip" is a height 3 file, "offset" is 101342453, and this is a + * filesystem with a blocksize of 4096. + * + * find_metapath() would return a struct metapath structure set to: + * mp_offset = 101342453, mp_height = 3, mp_list[0] = 0, mp_list[1] = 48, + * and mp_list[2] = 165. + * + * That means that in order to get to the block containing the byte at + * offset 101342453, we would load the indirect block pointed to by pointer + * 0 in the dinode. We would then load the indirect block pointed to by + * pointer 48 in that indirect block. We would then load the data block + * pointed to by pointer 165 in that indirect block. + * + * ---------------------------------------- + * | Dinode | | + * | | 4| + * | |0 1 2 3 4 5 9| + * | | 6| + * ---------------------------------------- + * | + * | + * V + * ---------------------------------------- + * | Indirect Block | + * | 5| + * | 4 4 4 4 4 5 5 1| + * |0 5 6 7 8 9 0 1 2| + * ---------------------------------------- + * | + * | + * V + * ---------------------------------------- + * | Indirect Block | + * | 1 1 1 1 1 5| + * | 6 6 6 6 6 1| + * |0 3 4 5 6 7 2| + * ---------------------------------------- + * | + * | + * V + * ---------------------------------------- + * | Data block containing offset | + * | 101342453 | + * | | + * | | + * ---------------------------------------- + * + */ + +static struct metapath * +find_metapath(struct gfs_inode *ip, uint64_t block) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct metapath *mp; + uint64_t b = block; + unsigned int i; + + mp = gmalloc(sizeof(struct metapath)); + memset(mp, 0, sizeof(struct metapath)); + + for (i = ip->i_di.di_height; i--;) + mp->mp_list[i] = do_div(b, sdp->sd_inptrs); + + return mp; +} + +/** + * metapointer - Return pointer to start of metadata in a buffer + * @bh: The buffer + * @height: The metadata height (0 = dinode) + * @mp: The metapath + * + * Return a pointer to the block number of the next height of the metadata + * tree given a buffer containing the pointer to the current height of the + * metadata tree. + */ + +static __inline__ uint64_t * +metapointer(struct buffer_head *bh, unsigned int height, struct metapath *mp) +{ + unsigned int head_size = (height > 0) ? + sizeof(struct gfs_indirect) : sizeof(struct gfs_dinode); + + return ((uint64_t *)(bh->b_data + head_size)) + mp->mp_list[height]; +} + +/** + * get_metablock - Get the next metadata block in metadata tree + * @ip: The GFS inode + * @bh: Buffer containing the pointers to metadata blocks + * @height: The height of the tree (0 = dinode) + * @mp: The metapath + * @create: Non-zero if we may create a new meatdata block + * @new: Used to indicate if we did create a new metadata block + * @block: the returned disk block number + * + * Given a metatree, complete to a particular height, checks to see if the next + * height of the tree exists. If not the next height of the tree is created. + * The block number of the next height of the metadata tree is returned. + * + * Returns: errno + */ + +static int +get_metablock(struct gfs_inode *ip, + struct buffer_head *bh, unsigned int height, struct metapath *mp, + int create, int *new, uint64_t *block) +{ + uint64_t *ptr = metapointer(bh, height, mp); + int error; + + if (*ptr) { + *block = gfs64_to_cpu(*ptr); + return 0; + } + + *block = 0; + + if (!create) + return 0; + + error = gfs_metaalloc(ip, block); + if (error) + return error; + + gfs_trans_add_bh(ip->i_gl, bh); + + *ptr = cpu_to_gfs64(*block); + ip->i_di.di_blocks++; + + *new = 1; + + return 0; +} + +/** + * get_datablock - Get datablock number from metadata block + * @ip: The GFS inode + * @bh: The buffer containing pointers to datablocks + * @mp: The metapath + * @create: Non-zero if we may create a new data block + * @new: Used to indicate if we created a new data block + * @block: the returned disk block number + * + * Given a fully built metadata tree, checks to see if a particular data + * block exists. It is created if it does not exist and the block number + * on disk is returned. + * + * Returns: errno + */ + +static int +get_datablock(struct gfs_inode *ip, + struct buffer_head *bh, struct metapath *mp, + int create, int *new, uint64_t *block) +{ + uint64_t *ptr = metapointer(bh, ip->i_di.di_height - 1, mp); + + if (*ptr) { + *block = gfs64_to_cpu(*ptr); + return 0; + } + + *block = 0; + + if (!create) + return 0; + + if (gfs_is_jdata(ip)) { + int error; + error = gfs_metaalloc(ip, block); + if (error) + return error; + } else + gfs_blkalloc(ip, block); + + gfs_trans_add_bh(ip->i_gl, bh); + + *ptr = cpu_to_gfs64(*block); + ip->i_di.di_blocks++; + + *new = 1; + + return 0; +} + +/** + * gfs_block_map - Map a block from an inode to a disk block + * @ip: The GFS inode + * @lblock: The logical block number + * @new: Value/Result argument (1 = may create/did create new blocks) + * @dblock: the disk block number of the start of an extent + * @extlen: the size of the extent + * + * Find the block number on the current device which corresponds to an + * inode's block. If the block had to be created, "new" will be set. + * + * Returns: errno + */ + +int +gfs_block_map(struct gfs_inode *ip, + uint64_t lblock, int *new, + uint64_t *dblock, uint32_t *extlen) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head *bh; + struct metapath *mp; + int create = *new; + unsigned int bsize; + unsigned int height; + unsigned int end_of_metadata; + unsigned int x; + int error = 0; + + *new = 0; + *dblock = 0; + if (extlen) + *extlen = 0; + + if (create) + down_write(&ip->i_rw_mutex); + else + down_read(&ip->i_rw_mutex); + + if (gfs_assert_warn(sdp, !gfs_is_stuffed(ip))) + goto out; + + bsize = (gfs_is_jdata(ip)) ? sdp->sd_jbsize : sdp->sd_sb.sb_bsize; + + height = calc_tree_height(ip, (lblock + 1) * bsize); + if (ip->i_di.di_height < height) { + if (!create) + goto out; + + error = build_height(ip, height); + if (error) + goto out; + } + + mp = find_metapath(ip, lblock); + end_of_metadata = ip->i_di.di_height - 1; + + error = gfs_get_inode_buffer(ip, &bh); + if (error) + goto out_kfree; + + for (x = 0; x < end_of_metadata; x++) { + error = get_metablock(ip, bh, x, mp, create, new, dblock); + brelse(bh); + if (error || !*dblock) + goto out_kfree; + + error = gfs_get_meta_buffer(ip, x + 1, *dblock, *new, &bh); + if (error) + goto out_kfree; + } + + error = get_datablock(ip, bh, mp, create, new, dblock); + if (error) { + brelse(bh); + goto out_kfree; + } + + if (extlen && *dblock) { + *extlen = 1; + + if (!*new) { + uint64_t tmp_dblock; + int tmp_new; + unsigned int nptrs; + + nptrs = (end_of_metadata) ? sdp->sd_inptrs : sdp->sd_diptrs; + + while (++mp->mp_list[end_of_metadata] < nptrs) { + get_datablock(ip, bh, mp, + FALSE, &tmp_new, + &tmp_dblock); + + if (*dblock + *extlen != tmp_dblock) + break; + + (*extlen)++; + } + } + } + + brelse(bh); + + if (*new) { + error = gfs_get_inode_buffer(ip, &bh); + if (!error) { + gfs_trans_add_bh(ip->i_gl, bh); + gfs_dinode_out(&ip->i_di, bh->b_data); + brelse(bh); + } + } + + out_kfree: + kfree(mp); + + out: + if (create) + up_write(&ip->i_rw_mutex); + else + up_read(&ip->i_rw_mutex); + + return error; +} + +/** + * do_grow - Make a file look bigger than it is + * @ip: the inode + * @size: the size to set the file to + * + * Called with an exclusive lock on @ip. + * + * Returns: errno + */ + +static int +do_grow(struct gfs_inode *ip, uint64_t size) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al; + struct buffer_head *dibh; + unsigned int h; + int journaled = gfs_is_jdata(ip); + int error; + + al = gfs_alloc_get(ip); + + error = gfs_quota_lock_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + if (error) + goto out; + + error = gfs_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); + if (error) + goto out_gunlock_q; + + if (journaled) + al->al_requested_meta = sdp->sd_max_height + 1; + else { + al->al_requested_meta = sdp->sd_max_height; + al->al_requested_data = 1; + } + + error = gfs_inplace_reserve(ip); + if (error) + goto out_gunlock_q; + + /* Trans may require: + Full extention of the metadata tree, block allocation, + a dinode modification, and a quota change */ + + error = gfs_trans_begin(sdp, + sdp->sd_max_height + al->al_rgd->rd_ri.ri_length + + 1 + !!journaled, + 1); + if (error) + goto out_ipres; + + if (size > sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode)) { + if (gfs_is_stuffed(ip)) { + error = gfs_unstuff_dinode(ip, gfs_unstuffer_sync, NULL); + if (error) + goto out_end_trans; + } + + h = calc_tree_height(ip, size); + if (ip->i_di.di_height < h) { + down_write(&ip->i_rw_mutex); + error = build_height(ip, h); + up_write(&ip->i_rw_mutex); + if (error) + goto out_end_trans; + } + } + + ip->i_di.di_size = size; + ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto out_end_trans; + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + + out_end_trans: + gfs_trans_end(sdp); + + out_ipres: + gfs_inplace_release(ip); + + out_gunlock_q: + gfs_quota_unlock_m(ip); + + out: + gfs_alloc_put(ip); + + return error; +} + +/** + * recursive_scan - recursively scan through the end of a file + * @ip: the inode + * @dibh: the dinode buffer + * @mp: the path through the metadata to the point to start + * @height: the height the recursion is at + * @block: the indirect block to look at + * @first: TRUE if this is the first block + * @bc: the call to make for each piece of metadata + * @data: data opaque to this function to pass to @bc + * + * When this is first called @height and @block should be zero and + * @first should be TRUE. + * + * Returns: errno + */ + +static int +recursive_scan(struct gfs_inode *ip, struct buffer_head *dibh, + struct metapath *mp, unsigned int height, uint64_t block, + int first, block_call_t bc, void *data) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head *bh = NULL; + uint64_t *top, *bottom; + uint64_t bn; + int error; + + if (!height) { + error = gfs_get_inode_buffer(ip, &bh); + if (error) + goto fail; + dibh = bh; + + top = (uint64_t *)(bh->b_data + sizeof(struct gfs_dinode)) + + mp->mp_list[0]; + bottom = (uint64_t *)(bh->b_data + sizeof(struct gfs_dinode)) + + sdp->sd_diptrs; + } else { + error = gfs_get_meta_buffer(ip, height, block, FALSE, &bh); + if (error) + goto fail; + + top = (uint64_t *)(bh->b_data + sizeof(struct gfs_indirect)) + + ((first) ? mp->mp_list[height] : 0); + bottom = (uint64_t *)(bh->b_data + sizeof(struct gfs_indirect)) + + sdp->sd_inptrs; + } + + error = bc(ip, dibh, bh, top, bottom, height, data); + if (error) + goto fail; + + if (height < ip->i_di.di_height - 1) + for (; top < bottom; top++, first = FALSE) { + if (!*top) + continue; + + bn = gfs64_to_cpu(*top); + + error = recursive_scan(ip, dibh, mp, + height + 1, bn, first, + bc, data); + if (error) + goto fail; + } + + brelse(bh); + + return 0; + + fail: + if (bh) + brelse(bh); + + return error; +} + +/** + * do_strip - Look for a layer a particular layer of the file and strip it off + * @ip: the inode + * @dibh: the dinode buffer + * @bh: A buffer of pointers + * @top: The first pointer in the buffer + * @bottom: One more than the last pointer + * @height: the height this buffer is at + * @data: a pointer to a struct strip_mine + * + * Returns: errno + */ + +static int +do_strip(struct gfs_inode *ip, struct buffer_head *dibh, + struct buffer_head *bh, uint64_t *top, uint64_t *bottom, + unsigned int height, void *data) +{ + struct strip_mine *sm = (struct strip_mine *)data; + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_rgrp_list rlist; + uint64_t bn, bstart; + uint32_t blen; + uint64_t *p; + unsigned int rg_blocks = 0; + int metadata; + int x; + int error; + + if (!*top) + sm->sm_first = FALSE; + + if (height != sm->sm_height) + return 0; + + if (sm->sm_first) { + top++; + sm->sm_first = FALSE; + } + + metadata = (height != ip->i_di.di_height - 1) || gfs_is_jdata(ip); + + error = gfs_rindex_hold(sdp, &ip->i_alloc->al_ri_gh); + if (error) + return error; + + memset(&rlist, 0, sizeof(struct gfs_rgrp_list)); + bstart = 0; + blen = 0; + + for (p = top; p < bottom; p++) { + if (!*p) + continue; + + bn = gfs64_to_cpu(*p); + + if (bstart + blen == bn) + blen++; + else { + if (bstart) + gfs_rlist_add(sdp, &rlist, bstart); + + bstart = bn; + blen = 1; + } + } + + if (bstart) + gfs_rlist_add(sdp, &rlist, bstart); + else + goto out; /* Nothing to do */ + + gfs_rlist_alloc(&rlist, LM_ST_EXCLUSIVE, 0); + + for (x = 0; x < rlist.rl_rgrps; x++) { + struct gfs_rgrpd *rgd; + rgd = get_gl2rgd(rlist.rl_ghs[x].gh_gl); + rg_blocks += rgd->rd_ri.ri_length; + } + + error = gfs_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs); + if (error) + goto out_rlist; + + /* Trans may require: + All the bitmaps that were reserved. + One block for the dinode. + One block for the indirect block being cleared. + One block for a quota change. */ + + error = gfs_trans_begin(sdp, rg_blocks + 2, 1); + if (error) + goto out_rg_gunlock; + + down_write(&ip->i_rw_mutex); + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_trans_add_bh(ip->i_gl, bh); + + bstart = 0; + blen = 0; + + for (p = top; p < bottom; p++) { + if (!*p) + continue; + + bn = gfs64_to_cpu(*p); + + if (bstart + blen == bn) + blen++; + else { + if (bstart) { + if (metadata) + gfs_metafree(ip, bstart, blen); + else + gfs_blkfree(ip, bstart, blen); + } + + bstart = bn; + blen = 1; + } + + *p = 0; + if (!ip->i_di.di_blocks) + gfs_consist_inode(ip); + ip->i_di.di_blocks--; + } + if (bstart) { + if (metadata) + gfs_metafree(ip, bstart, blen); + else + gfs_blkfree(ip, bstart, blen); + } + + ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); + + gfs_dinode_out(&ip->i_di, dibh->b_data); + + up_write(&ip->i_rw_mutex); + + gfs_trans_end(sdp); + + out_rg_gunlock: + gfs_glock_dq_m(rlist.rl_rgrps, rlist.rl_ghs); + + out_rlist: + gfs_rlist_free(&rlist); + + out: + gfs_glock_dq_uninit(&ip->i_alloc->al_ri_gh); + + return error; +} + +/** + * gfs_truncator_default - truncate a partial data block + * @ip: the inode + * @size: the size the file should be + * + * Returns: errno + */ + +int +gfs_truncator_default(struct gfs_inode *ip, uint64_t size) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head *bh; + uint64_t bn; + int not_new = 0; + int error; + + error = gfs_block_map(ip, size >> sdp->sd_sb.sb_bsize_shift, ¬_new, + &bn, NULL); + if (error) + return error; + if (!bn) + return 0; + + error = gfs_get_data_buffer(ip, bn, FALSE, &bh); + if (error) + return error; + + gfs_buffer_clear_tail(bh, size & (sdp->sd_sb.sb_bsize - 1)); + + error = gfs_dwrite(sdp, bh, DIO_DIRTY); + + brelse(bh); + + return error; +} + +/** + * truncator_journaled - truncate a partial data block + * @ip: the inode + * @size: the size the file should be + * + * Returns: errno + */ + +static int +truncator_journaled(struct gfs_inode *ip, uint64_t size) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head *bh; + uint64_t lbn, dbn; + uint32_t off; + int not_new = 0; + int error; + + lbn = size; + off = do_div(lbn, sdp->sd_jbsize); + + error = gfs_block_map(ip, lbn, ¬_new, &dbn, NULL); + if (error) + return error; + if (!dbn) + return 0; + + error = gfs_trans_begin(sdp, 1, 0); + if (error) + return error; + + error = gfs_get_data_buffer(ip, dbn, FALSE, &bh); + if (!error) { + gfs_trans_add_bh(ip->i_gl, bh); + gfs_buffer_clear_tail(bh, + sizeof(struct gfs_meta_header) + + off); + brelse(bh); + } + + gfs_trans_end(sdp); + + return error; +} + +/** + * gfs_shrink - make a file smaller + * @ip: the inode + * @size: the size to make the file + * @truncator: function to truncate the last partial block + * + * Called with an exclusive lock on @ip. + * + * Returns: errno + */ + +int +gfs_shrink(struct gfs_inode *ip, uint64_t size, gfs_truncator_t truncator) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_holder ri_gh; + struct gfs_rgrpd *rgd; + struct buffer_head *dibh; + uint64_t block; + unsigned int height; + int journaled = gfs_is_jdata(ip); + int error; + + if (!size) + block = 0; + else if (journaled) { + block = size - 1; + do_div(block, sdp->sd_jbsize); + } + else + block = (size - 1) >> sdp->sd_sb.sb_bsize_shift; + + /* Get rid of all the data/metadata blocks */ + + height = ip->i_di.di_height; + if (height) { + struct metapath *mp = find_metapath(ip, block); + gfs_alloc_get(ip); + + error = gfs_quota_hold_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + if (error) { + gfs_alloc_put(ip); + kfree(mp); + return error; + } + + while (height--) { + struct strip_mine sm; + + sm.sm_first = (size) ? TRUE : FALSE; + sm.sm_height = height; + + error = recursive_scan(ip, NULL, mp, 0, 0, TRUE, + do_strip, &sm); + if (error) { + gfs_quota_unhold_m(ip); + gfs_alloc_put(ip); + kfree(mp); + return error; + } + } + + gfs_quota_unhold_m(ip); + gfs_alloc_put(ip); + kfree(mp); + } + + /* If we truncated in the middle of a block, zero out the leftovers. */ + + if (gfs_is_stuffed(ip)) { + /* Do nothing */ + } else if (journaled) { + if (do_mod(size, sdp->sd_jbsize)) { + error = truncator_journaled(ip, size); + if (error) + return error; + } + } else if (size & (uint64_t)(sdp->sd_sb.sb_bsize - 1)) { + error = truncator(ip, size); + if (error) + return error; + } + + /* Set the new size (and possibly the height) */ + + if (!size) { + error = gfs_rindex_hold(sdp, &ri_gh); + if (error) + return error; + } + + error = gfs_trans_begin(sdp, 1, 0); + if (error) + goto out; + + down_write(&ip->i_rw_mutex); + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto out_end_trans; + + if (!size) { + ip->i_di.di_height = 0; + + rgd = gfs_blk2rgrpd(sdp, ip->i_num.no_addr); + if (!rgd) { + gfs_consist_inode(ip); + error = -EIO; + goto out_end_trans; + } + + ip->i_di.di_goal_rgrp = rgd->rd_ri.ri_addr; + ip->i_di.di_goal_dblk = + ip->i_di.di_goal_mblk = + ip->i_num.no_addr - rgd->rd_ri.ri_data1; + } + + ip->i_di.di_size = size; + ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); + + gfs_trans_add_bh(ip->i_gl, dibh); + + if (!ip->i_di.di_height && + size < sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode)) + gfs_buffer_clear_tail(dibh, sizeof(struct gfs_dinode) + size); + + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + + out_end_trans: + up_write(&ip->i_rw_mutex); + + gfs_trans_end(sdp); + + out: + if (!size) + gfs_glock_dq_uninit(&ri_gh); + + return error; +} + +/** + * do_same - truncate to same size (update time stamps) + * @ip: + * + * Returns: errno + */ + +static int +do_same(struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head *dibh; + int error; + + error = gfs_trans_begin(sdp, 1, 0); + if (error) + return error; + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto out; + + ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + + brelse(dibh); + + out: + gfs_trans_end(sdp); + + return error; +} + +/** + * gfs_truncatei - make a file a give size + * @ip: the inode + * @size: the size to make the file + * @truncator: function to truncate the last partial block + * + * The file size can grow, shrink, or stay the same size. + * + * Returns: errno + */ + +int +gfs_truncatei(struct gfs_inode *ip, uint64_t size, + gfs_truncator_t truncator) +{ + if (gfs_assert_warn(ip->i_sbd, ip->i_di.di_type == GFS_FILE_REG)) + return -EINVAL; + + if (size == ip->i_di.di_size) + return do_same(ip); + else if (size > ip->i_di.di_size) + return do_grow(ip, size); + else + return gfs_shrink(ip, size, truncator); +} + +/** + * gfs_write_calc_reserv - calculate the number of blocks needed to write to a file + * @ip: the file + * @len: the number of bytes to be written to the file + * @data_blocks: returns the number of data blocks required + * @ind_blocks: returns the number of indirect blocks required + * + */ + +void +gfs_write_calc_reserv(struct gfs_inode *ip, unsigned int len, + unsigned int *data_blocks, unsigned int *ind_blocks) +{ + struct gfs_sbd *sdp = ip->i_sbd; + unsigned int tmp; + + if (gfs_is_jdata(ip)) { + *data_blocks = DIV_RU(len, sdp->sd_jbsize) + 2; + *ind_blocks = 3 * (sdp->sd_max_jheight - 1); + } else { + *data_blocks = (len >> sdp->sd_sb.sb_bsize_shift) + 3; + *ind_blocks = 3 * (sdp->sd_max_height - 1); + } + + for (tmp = *data_blocks; tmp > sdp->sd_diptrs;) { + tmp = DIV_RU(tmp, sdp->sd_inptrs); + *ind_blocks += tmp; + } +} + +/** + * gfs_write_alloc_required - figure out if a write is going to require an allocation + * @ip: the file being written to + * @offset: the offset to write to + * @len: the number of bytes being written + * @alloc_required: the int is set to TRUE if an alloc is required, FALSE otherwise + * + * Returns: errno + */ + +int +gfs_write_alloc_required(struct gfs_inode *ip, + uint64_t offset, unsigned int len, + int *alloc_required) +{ + struct gfs_sbd *sdp = ip->i_sbd; + uint64_t lblock, lblock_stop, dblock; + uint32_t extlen; + int not_new = FALSE; + int error = 0; + + *alloc_required = FALSE; + + if (!len) + return 0; + + if (gfs_is_stuffed(ip)) { + if (offset + len > sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode)) + *alloc_required = TRUE; + return 0; + } + + if (gfs_is_jdata(ip)) { + unsigned int bsize = sdp->sd_jbsize; + lblock = offset; + do_div(lblock, bsize); + lblock_stop = offset + len + bsize - 1; + do_div(lblock_stop, bsize); + } else { + unsigned int shift = sdp->sd_sb.sb_bsize_shift; + lblock = offset >> shift; + lblock_stop = (offset + len + sdp->sd_sb.sb_bsize - 1) >> shift; + } + + for (; lblock < lblock_stop; lblock += extlen) { + error = gfs_block_map(ip, lblock, ¬_new, &dblock, &extlen); + if (error) + return error; + + if (!dblock) { + *alloc_required = TRUE; + return 0; + } + } + + return 0; +} + +/** + * do_gfm - Copy out the dinode/indirect blocks of a file + * @ip: the file + * @dibh: the dinode buffer + * @bh: the indirect buffer we're looking at + * @top: the first pointer in the block + * @bottom: one more than the last pointer in the block + * @height: the height the block is at + * @data: a pointer to a struct gfs_user_buffer structure + * + * If this is a journaled file, copy out the data too. + * + * Returns: errno + */ + +static int +do_gfm(struct gfs_inode *ip, struct buffer_head *dibh, + struct buffer_head *bh, uint64_t *top, uint64_t *bottom, + unsigned int height, void *data) +{ + struct gfs_user_buffer *ub = (struct gfs_user_buffer *)data; + int error; + + error = gfs_add_bh_to_ub(ub, bh); + if (error) + return error; + + if (ip->i_di.di_type != GFS_FILE_DIR || + height + 1 != ip->i_di.di_height) + return 0; + + for (; top < bottom; top++) + if (*top) { + struct buffer_head *data_bh; + + error = gfs_dread(ip->i_gl, gfs64_to_cpu(*top), + DIO_START | DIO_WAIT, + &data_bh); + if (error) + return error; + + error = gfs_add_bh_to_ub(ub, data_bh); + + brelse(data_bh); + + if (error) + return error; + } + + return 0; +} + +/** + * gfs_get_file_meta - return all the metadata for a file + * @ip: the file + * @ub: the structure representing the meta + * + * Returns: errno + */ + +int +gfs_get_file_meta(struct gfs_inode *ip, struct gfs_user_buffer *ub) +{ + int error; + + if (gfs_is_stuffed(ip)) { + struct buffer_head *dibh; + error = gfs_get_inode_buffer(ip, &dibh); + if (!error) { + error = gfs_add_bh_to_ub(ub, dibh); + brelse(dibh); + } + } else { + struct metapath *mp = find_metapath(ip, 0); + error = recursive_scan(ip, NULL, mp, 0, 0, TRUE, do_gfm, ub); + kfree(mp); + } + + return error; +} --- linux-2.6.28.orig/ubuntu/gfs/recovery.h +++ linux-2.6.28/ubuntu/gfs/recovery.h @@ -0,0 +1,23 @@ +#ifndef __RECOVERY_DOT_H__ +#define __RECOVERY_DOT_H__ + +#define GFS_RECPASS_A1 (12) +#define GFS_RECPASS_B1 (14) + +void gfs_add_dirty_j(struct gfs_sbd *sdp, unsigned int jid); +void gfs_clear_dirty_j(struct gfs_sbd *sdp); + +int gfs_find_jhead(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, struct gfs_log_header *head); +int gfs_increment_blkno(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, uint64_t *addr, + int skip_headers); + +int gfs_recover_journal(struct gfs_sbd *sdp, + unsigned int jid, struct gfs_jindex *jdesc, + int wait); +void gfs_check_journals(struct gfs_sbd *sdp); + +int gfs_recover_dump(struct gfs_sbd *sdp); + +#endif /* __RECOVERY_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/fixed_div64.h +++ linux-2.6.28/ubuntu/gfs/fixed_div64.h @@ -0,0 +1,107 @@ +#ifndef __FIXED_DIV64_DOT_H__ +#define __FIXED_DIV64_DOT_H__ + +#include + +#if defined __i386__ +/* For ia32 we need to pull some tricks to get past various versions + * of the compiler which do not like us using do_div in the middle + * of large functions. + */ +static inline __u32 fixed_div64_do_div(void *a, __u32 b, int n) +{ + __u32 mod; + + switch (n) { + case 4: + mod = *(__u32 *)a % b; + *(__u32 *)a = *(__u32 *)a / b; + return mod; + case 8: + { + unsigned long __upper, __low, __high, __mod; + __u64 c = *(__u64 *)a; + __upper = __high = c >> 32; + __low = c; + if (__high) { + __upper = __high % (b); + __high = __high / (b); + } + asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (b), "0" (__low), "1" (__upper)); + asm("":"=A" (c):"a" (__low),"d" (__high)); + *(__u64 *)a = c; + return __mod; + } + } + + /* NOTREACHED */ + return 0; +} + +/* Side effect free 64 bit mod operation */ +static inline __u32 fixed_div64_do_mod(void *a, __u32 b, int n) +{ + switch (n) { + case 4: + return *(__u32 *)a % b; + case 8: + { + unsigned long __upper, __low, __high, __mod; + __u64 c = *(__u64 *)a; + __upper = __high = c >> 32; + __low = c; + if (__high) { + __upper = __high % (b); + __high = __high / (b); + } + asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (b), "0" (__low), "1" (__upper)); + asm("":"=A" (c):"a" (__low),"d" (__high)); + return __mod; + } + } + + /* NOTREACHED */ + return 0; +} +#else +static inline __u32 fixed_div64_do_div(void *a, __u32 b, int n) +{ + __u32 mod; + + switch (n) { + case 4: + mod = *(__u32 *)a % b; + *(__u32 *)a = *(__u32 *)a / b; + return mod; + case 8: + mod = do_div(*(__u64 *)a, b); + return mod; + } + + /* NOTREACHED */ + return 0; +} + +/* Side effect free 64 bit mod operation */ +static inline __u32 fixed_div64_do_mod(void *a, __u32 b, int n) +{ + switch (n) { + case 4: + return *(__u32 *)a % b; + case 8: + { + __u64 c = *(__u64 *)a; + return do_div(c, b); + } + } + + /* NOTREACHED */ + return 0; +} +#endif + +#undef do_div +#define do_div(a, b) fixed_div64_do_div(&(a), (b), sizeof(a)) +#define do_mod(a, b) fixed_div64_do_mod(&(a), (b), sizeof(a)) + +#endif /* __FIXED_DIV64_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/eattr.c +++ linux-2.6.28/ubuntu/gfs/eattr.c @@ -0,0 +1,2008 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "acl.h" +#include "dio.h" +#include "eaops.h" +#include "eattr.h" +#include "glock.h" +#include "inode.h" +#include "quota.h" +#include "rgrp.h" +#include "trans.h" + +/** + * ea_calc_size - returns the acutal number of bytes the request will take up + * (not counting any unstuffed data blocks) + * @sdp: + * @er: + * @size: + * + * Returns: TRUE if the EA should be stuffed + */ + +static int +ea_calc_size(struct gfs_sbd *sdp, + struct gfs_ea_request *er, + unsigned int *size) +{ + *size = GFS_EAREQ_SIZE_STUFFED(er); + if (*size <= sdp->sd_jbsize) + return TRUE; + + *size = GFS_EAREQ_SIZE_UNSTUFFED(sdp, er); + return FALSE; +} + +/** + * gfs_ea_check_size - + * @ip: + * @er: + * + * Returns: errno + */ + +int +gfs_ea_check_size(struct gfs_sbd *sdp, struct gfs_ea_request *er) +{ + unsigned int size; + + if (er->er_data_len > GFS_EA_MAX_DATA_LEN) + return -ERANGE; + + ea_calc_size(sdp, er, &size); + if (size > sdp->sd_jbsize) + return -ERANGE; /* This can only happen with 512 byte blocks */ + + return 0; +} + +typedef int (*ea_call_t) (struct gfs_inode *ip, + struct buffer_head *bh, + struct gfs_ea_header *ea, + struct gfs_ea_header *prev, + void *private); + +/** + * ea_foreach_i - + * @ip: + * @bh: + * @eabc: + * @data: + * + * Returns: errno + */ + +static int +ea_foreach_i(struct gfs_inode *ip, + struct buffer_head *bh, + ea_call_t ea_call, void *data) +{ + struct gfs_ea_header *ea, *prev = NULL; + int error = 0; + + if (gfs_metatype_check(ip->i_sbd, bh, GFS_METATYPE_EA)) + return -EIO; + + for (ea = GFS_EA_BH2FIRST(bh);; prev = ea, ea = GFS_EA2NEXT(ea)) { + if (!GFS_EA_REC_LEN(ea)) + goto fail; + if (!(bh->b_data <= (char *)ea && + (char *)GFS_EA2NEXT(ea) <= + bh->b_data + bh->b_size)) + goto fail; + if (!GFS_EATYPE_VALID(ea->ea_type)) + goto fail; + + error = ea_call(ip, bh, ea, prev, data); + if (error) + return error; + + if (GFS_EA_IS_LAST(ea)) { + if ((char *)GFS_EA2NEXT(ea) != + bh->b_data + bh->b_size) + goto fail; + break; + } + } + + return error; + + fail: + gfs_consist_inode(ip); + return -EIO; +} + +/** + * ea_foreach - + * @ip: + * @ea_call: + * @data: + * + * Returns: errno + */ + +static int +ea_foreach(struct gfs_inode *ip, + ea_call_t ea_call, + void *data) +{ + struct buffer_head *bh; + int error; + + error = gfs_dread(ip->i_gl, ip->i_di.di_eattr, + DIO_START | DIO_WAIT, &bh); + if (error) + return error; + + if (!(ip->i_di.di_flags & GFS_DIF_EA_INDIRECT)) + error = ea_foreach_i(ip, bh, ea_call, data); + else { + struct buffer_head *eabh; + uint64_t *eablk, *end; + + if (gfs_metatype_check(ip->i_sbd, bh, GFS_METATYPE_IN)) { + error = -EIO; + goto out; + } + + eablk = (uint64_t *)(bh->b_data + sizeof(struct gfs_indirect)); + end = eablk + ip->i_sbd->sd_inptrs; + + for (; eablk < end; eablk++) { + uint64_t bn; + + if (!*eablk) + break; + bn = gfs64_to_cpu(*eablk); + + error = gfs_dread(ip->i_gl, bn, + DIO_START | DIO_WAIT, &eabh); + if (error) + break; + error = ea_foreach_i(ip, eabh, ea_call, data); + brelse(eabh); + if (error) + break; + } + } + + out: + brelse(bh); + + return error; +} + +struct ea_find { + struct gfs_ea_request *ef_er; + struct gfs_ea_location *ef_el; +}; + +/** + * ea_find_i - + * @ip: + * @bh: + * @ea: + * @prev: + * @private: + * + * Returns: -errno on error, 1 if search is over, + * 0 if search should continue + */ + +static int +ea_find_i(struct gfs_inode *ip, + struct buffer_head *bh, + struct gfs_ea_header *ea, + struct gfs_ea_header *prev, + void *private) +{ + struct ea_find *ef = (struct ea_find *)private; + struct gfs_ea_request *er = ef->ef_er; + + if (ea->ea_type == GFS_EATYPE_UNUSED) + return 0; + + if (ea->ea_type == er->er_type) { + if (ea->ea_name_len == er->er_name_len && + !memcmp(GFS_EA2NAME(ea), er->er_name, ea->ea_name_len)) { + struct gfs_ea_location *el = ef->ef_el; + get_bh(bh); + el->el_bh = bh; + el->el_ea = ea; + el->el_prev = prev; + return 1; + } + } + +#if 0 + else if ((ip->i_di.di_flags & GFS_DIF_EA_PACKED) && + er->er_type == GFS_EATYPE_SYS) + return 1; +#endif + + return 0; +} + +/** + * gfs_ea_find - find a matching eattr + * @ip: + * @er: + * @el: + * + * Returns: errno + */ + +int +gfs_ea_find(struct gfs_inode *ip, + struct gfs_ea_request *er, + struct gfs_ea_location *el) +{ + struct ea_find ef; + int error; + + ef.ef_er = er; + ef.ef_el = el; + + memset(el, 0, sizeof(struct gfs_ea_location)); + + error = ea_foreach(ip, ea_find_i, &ef); + if (error > 0) + return 0; + + return error; +} + +/** + * ea_dealloc_unstuffed - + * @ip: + * @bh: + * @ea: + * @prev: + * @private: + * + * Take advantage of the fact that all unstuffed blocks are + * allocated from the same RG. But watch, this may not always + * be true. + * + * Returns: errno + */ + +static int +ea_dealloc_unstuffed(struct gfs_inode *ip, + struct buffer_head *bh, + struct gfs_ea_header *ea, + struct gfs_ea_header *prev, + void *private) +{ + int *leave = (int *)private; + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_rgrpd *rgd; + struct gfs_holder rg_gh; + struct buffer_head *dibh; + uint64_t *dataptrs, bn = 0; + uint64_t bstart = 0; + unsigned int blen = 0; + unsigned int x; + int error; + + if (GFS_EA_IS_STUFFED(ea)) + return 0; + + dataptrs = GFS_EA2DATAPTRS(ea); + for (x = 0; x < ea->ea_num_ptrs; x++, dataptrs++) + if (*dataptrs) { + bn = gfs64_to_cpu(*dataptrs); + break; + } + if (!bn) + return 0; + + rgd = gfs_blk2rgrpd(sdp, bn); + if (!rgd) { + gfs_consist_inode(ip); + return -EIO; + } + + error = gfs_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &rg_gh); + if (error) + return error; + + error = gfs_trans_begin(sdp, 2 + rgd->rd_ri.ri_length, 1); + if (error) + goto out_gunlock; + + gfs_trans_add_bh(ip->i_gl, bh); + + dataptrs = GFS_EA2DATAPTRS(ea); + for (x = 0; x < ea->ea_num_ptrs; x++, dataptrs++) { + if (!*dataptrs) + break; + bn = gfs64_to_cpu(*dataptrs); + + if (bstart + blen == bn) + blen++; + else { + if (bstart) + gfs_metafree(ip, bstart, blen); + bstart = bn; + blen = 1; + } + + *dataptrs = 0; + if (!ip->i_di.di_blocks) + gfs_consist_inode(ip); + ip->i_di.di_blocks--; + } + if (bstart) + gfs_metafree(ip, bstart, blen); + + if (prev && !leave) { + uint32_t len; + + len = GFS_EA_REC_LEN(prev) + GFS_EA_REC_LEN(ea); + prev->ea_rec_len = cpu_to_gfs32(len); + + if (GFS_EA_IS_LAST(ea)) + prev->ea_flags |= GFS_EAFLAG_LAST; + } else { + ea->ea_type = GFS_EATYPE_UNUSED; + ea->ea_num_ptrs = 0; + } + + error = gfs_get_inode_buffer(ip, &dibh); + if (!error) { + ip->i_di.di_ctime = get_seconds(); + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + + gfs_trans_end(sdp); + + out_gunlock: + gfs_glock_dq_uninit(&rg_gh); + + return error; +} + +/** + * ea_remove_unstuffed - + * @ip: + * @bh: + * @ea: + * @prev: + * @leave: + * + * Returns: errno + */ + +static int +ea_remove_unstuffed(struct gfs_inode *ip, + struct buffer_head *bh, + struct gfs_ea_header *ea, + struct gfs_ea_header *prev, + int leave) +{ + struct gfs_alloc *al; + int error; + + al = gfs_alloc_get(ip); + + error = gfs_quota_hold_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + if (error) + goto out_alloc; + + error = gfs_rindex_hold(ip->i_sbd, &al->al_ri_gh); + if (error) + goto out_quota; + + error = ea_dealloc_unstuffed(ip, + bh, ea, prev, + (leave) ? &error : NULL); + + gfs_glock_dq_uninit(&al->al_ri_gh); + + out_quota: + gfs_quota_unhold_m(ip); + + out_alloc: + gfs_alloc_put(ip); + + return error; +} + +/**************************************************************************************************/ + +/** + * gfs_ea_repack_i - + * @ip: + * + * Returns: errno + */ + +int +gfs_ea_repack_i(struct gfs_inode *ip) +{ + return -ENOSYS; +} + +/** + * gfs_ea_repack - + * @ip: + * + * Returns: errno + */ + +int gfs_ea_repack(struct gfs_inode *ip) +{ + struct gfs_holder gh; + int error; + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); + if (error) + return error; + + /* Some sort of permissions checking would be nice */ + + error = gfs_ea_repack_i(ip); + + gfs_glock_dq_uninit(&gh); + + return error; +} + +struct ea_list { + struct gfs_ea_request *ei_er; + unsigned int ei_size; +}; + +/** + * ea_list_i - + * @ip: + * @bh: + * @ea: + * @prev: + * @private: + * + * Returns: errno + */ + +static int +ea_list_i(struct gfs_inode *ip, + struct buffer_head *bh, + struct gfs_ea_header *ea, + struct gfs_ea_header *prev, + void *private) +{ + struct ea_list *ei = (struct ea_list *)private; + struct gfs_ea_request *er = ei->ei_er; + unsigned int ea_size = gfs_ea_strlen(ea); + + if (ea->ea_type == GFS_EATYPE_UNUSED) + return 0; + + if (er->er_data_len) { + char *prefix; + unsigned int l; + char c = 0; + + if (ei->ei_size + ea_size > er->er_data_len) + return -ERANGE; + + switch (ea->ea_type) { + case GFS_EATYPE_USR: + prefix = "user."; + l = 5; + break; + case GFS_EATYPE_SYS: + prefix = "system."; + l = 7; + break; + case GFS_EATYPE_SECURITY: + prefix = "security."; + l = 9; + break; + default: + prefix = NULL; + l = 0; + break; + } + + if (prefix == NULL || l == 0) + return -EIO; + + memcpy(er->er_data + ei->ei_size, + prefix, l); + memcpy(er->er_data + ei->ei_size + l, + GFS_EA2NAME(ea), + ea->ea_name_len); + memcpy(er->er_data + ei->ei_size + + ea_size - 1, + &c, 1); + } + + ei->ei_size += ea_size; + + return 0; +} + +/** + * gfs_ea_list - + * @ip: + * @er: + * + * Returns: actual size of data on success, -errno on error + */ + +int +gfs_ea_list(struct gfs_inode *ip, struct gfs_ea_request *er) +{ + struct gfs_holder i_gh; + int error; + + if (!er->er_data || !er->er_data_len) { + er->er_data = NULL; + er->er_data_len = 0; + } + + error = gfs_glock_nq_init(ip->i_gl, + LM_ST_SHARED, LM_FLAG_ANY, + &i_gh); + if (error) + return error; + + if (ip->i_di.di_eattr) { + struct ea_list ei = { .ei_er = er, .ei_size = 0 }; + + error = ea_foreach(ip, ea_list_i, &ei); + if (!error) + error = ei.ei_size; + } + + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * ea_get_unstuffed - actually copies the unstuffed data into the + * request buffer + * @ip: + * @ea: + * @data: + * + * Returns: errno + */ + +static int +ea_get_unstuffed(struct gfs_inode *ip, struct gfs_ea_header *ea, + char *data) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head **bh; + unsigned int amount = GFS_EA_DATA_LEN(ea); + unsigned int nptrs = DIV_RU(amount, sdp->sd_jbsize); + uint64_t *dataptrs = GFS_EA2DATAPTRS(ea); + unsigned int x; + int error = 0; + + bh = kmalloc(nptrs * sizeof(struct buffer_head *), GFP_KERNEL); + if (!bh) + return -ENOMEM; + + for (x = 0; x < nptrs; x++) { + error = gfs_dread(ip->i_gl, gfs64_to_cpu(*dataptrs), + DIO_START, bh + x); + if (error) { + while (x--) + brelse(bh[x]); + goto out; + } + dataptrs++; + } + + for (x = 0; x < nptrs; x++) { + error = gfs_dreread(sdp, bh[x], DIO_WAIT); + if (error) { + for (; x < nptrs; x++) + brelse(bh[x]); + goto out; + } + if (gfs_metatype_check2(sdp, bh[x], + GFS_METATYPE_ED, GFS_METATYPE_EA)) { + for (; x < nptrs; x++) + brelse(bh[x]); + error = -EIO; + goto out; + } + + memcpy(data, + bh[x]->b_data + sizeof(struct gfs_meta_header), + (sdp->sd_jbsize > amount) ? amount : sdp->sd_jbsize); + + amount -= sdp->sd_jbsize; + data += sdp->sd_jbsize; + + brelse(bh[x]); + } + + out: + kfree(bh); + + return error; +} + +/** + * gfs_ea_get_copy - + * @ip: + * @el: + * @data: + * + * Returns: errno + */ + +int +gfs_ea_get_copy(struct gfs_inode *ip, + struct gfs_ea_location *el, + char *data) +{ + if (GFS_EA_IS_STUFFED(el->el_ea)) { + memcpy(data, + GFS_EA2DATA(el->el_ea), + GFS_EA_DATA_LEN(el->el_ea)); + return 0; + } else + return ea_get_unstuffed(ip, el->el_ea, data); +} + +/** + * gfs_ea_get_i - + * @ip: + * @er: + * + * Returns: actual size of data on success, -errno on error + */ + +int +gfs_ea_get_i(struct gfs_inode *ip, struct gfs_ea_request *er) +{ + struct gfs_ea_location el; + int error; + + if (!ip->i_di.di_eattr) + return -ENODATA; + + error = gfs_ea_find(ip, er, &el); + if (error) + return error; + if (!el.el_ea) + return -ENODATA; + + if (er->er_data_len) { + if (GFS_EA_DATA_LEN(el.el_ea) > er->er_data_len) + error = -ERANGE; + else + error = gfs_ea_get_copy(ip, &el, er->er_data); + } + if (!error) + error = GFS_EA_DATA_LEN(el.el_ea); + + brelse(el.el_bh); + + return error; +} + +/** + * gfs_ea_get - + * @ip: + * @er: + * + * Returns: actual size of data on success, -errno on error + */ + +int +gfs_ea_get(struct gfs_inode *ip, struct gfs_ea_request *er) +{ + struct gfs_holder i_gh; + int error; + + if (!er->er_name_len || + er->er_name_len > GFS_EA_MAX_NAME_LEN) + return -EINVAL; + if (!er->er_data || !er->er_data_len) { + er->er_data = NULL; + er->er_data_len = 0; + } + + error = gfs_glock_nq_init(ip->i_gl, + LM_ST_SHARED, LM_FLAG_ANY, + &i_gh); + if (error) + return error; + + error = gfs_ea_ops[er->er_type]->eo_get(ip, er); + + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * ea_alloc_blk - allocates a new block for extended attributes. + * @ip: A pointer to the inode that's getting extended attributes + * @bhp: + * + * Returns: errno + */ + +static int +ea_alloc_blk(struct gfs_inode *ip, + struct buffer_head **bhp) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_ea_header *ea; + uint64_t block; + int error; + + error = gfs_metaalloc(ip, &block); + if (error) + return error; + + error = gfs_dread(ip->i_gl, block, + DIO_NEW | DIO_START | DIO_WAIT, bhp); + if (error) + return error; + + gfs_trans_add_bh(ip->i_gl, *bhp); + gfs_metatype_set(*bhp, GFS_METATYPE_EA, GFS_FORMAT_EA); + + ea = GFS_EA_BH2FIRST(*bhp); + ea->ea_rec_len = cpu_to_gfs32(sdp->sd_jbsize); + ea->ea_type = GFS_EATYPE_UNUSED; + ea->ea_flags = GFS_EAFLAG_LAST; + ea->ea_num_ptrs = 0; + + ip->i_di.di_blocks++; + + return 0; +} + +/** + * ea_write - writes the request info to an ea, creating new blocks if + * necessary + * @ip: inode that is being modified + * @ea: the location of the new ea in a block + * @er: the write request + * + * Note: does not update ea_rec_len or the GFS_EAFLAG_LAST bin of ea_flags + * + * returns : errno + */ + +static int +ea_write(struct gfs_inode *ip, + struct gfs_ea_header *ea, + struct gfs_ea_request *er) +{ + struct gfs_sbd *sdp = ip->i_sbd; + + ea->ea_data_len = cpu_to_gfs32(er->er_data_len); + ea->ea_name_len = er->er_name_len; + ea->ea_type = er->er_type; + ea->ea_pad = 0; + + memcpy(GFS_EA2NAME(ea), er->er_name, er->er_name_len); + + if (GFS_EAREQ_SIZE_STUFFED(er) <= sdp->sd_jbsize) { + ea->ea_num_ptrs = 0; + memcpy(GFS_EA2DATA(ea), er->er_data, er->er_data_len); + } else { + uint64_t *dataptr = GFS_EA2DATAPTRS(ea); + const char *data = er->er_data; + unsigned int data_len = er->er_data_len; + unsigned int copy; + unsigned int x; + + ea->ea_num_ptrs = DIV_RU(er->er_data_len, sdp->sd_jbsize); + for (x = 0; x < ea->ea_num_ptrs; x++) { + struct buffer_head *bh; + uint64_t block; + int error; + + error = gfs_metaalloc(ip, &block); + if (error) + return error; + + error = gfs_dread(ip->i_gl, block, + DIO_NEW | DIO_START | DIO_WAIT, &bh); + if (error) + return error; + + gfs_trans_add_bh(ip->i_gl, bh); + gfs_metatype_set(bh, GFS_METATYPE_ED, GFS_FORMAT_ED); + ip->i_di.di_blocks++; + + copy = (data_len > sdp->sd_jbsize) ? sdp->sd_jbsize : data_len; + memcpy(bh->b_data + sizeof(struct gfs_meta_header), + data, + copy); + + *dataptr++ = cpu_to_gfs64((uint64_t)bh->b_blocknr); + data += copy; + data_len -= copy; + + brelse(bh); + } + + gfs_assert_withdraw(sdp, !data_len); + } + + return 0; +} + +typedef int (*ea_skeleton_call_t) (struct gfs_inode *ip, + struct gfs_ea_request *er, + void *private); +/** + * ea_alloc_skeleton - + * @ip: + * @er: + * @blks: + * @skeleton_call: + * @private: + * + * Returns: errno + */ + +static int +ea_alloc_skeleton(struct gfs_inode *ip, struct gfs_ea_request *er, + unsigned int blks, + ea_skeleton_call_t skeleton_call, void *private) +{ + struct gfs_alloc *al; + struct buffer_head *dibh; + int error; + + al = gfs_alloc_get(ip); + + error = gfs_quota_lock_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + if (error) + goto out; + + error = gfs_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); + if (error) + goto out_gunlock_q; + + al->al_requested_meta = blks; + + error = gfs_inplace_reserve(ip); + if (error) + goto out_gunlock_q; + + /* Trans may require: + A modified dinode, multiple EA metadata blocks, and all blocks for a RG + bitmap */ + + error = gfs_trans_begin(ip->i_sbd, + 1 + blks + al->al_rgd->rd_ri.ri_length, 1); + if (error) + goto out_ipres; + + error = skeleton_call(ip, er, private); + if (error) + goto out_end_trans; + + error = gfs_get_inode_buffer(ip, &dibh); + if (!error) { + if (er->er_mode) { + ip->i_vnode->i_mode = er->er_mode; + gfs_inode_attr_out(ip); + } + ip->i_di.di_ctime = get_seconds(); + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + + out_end_trans: + gfs_trans_end(ip->i_sbd); + + out_ipres: + gfs_inplace_release(ip); + + out_gunlock_q: + gfs_quota_unlock_m(ip); + + out: + gfs_alloc_put(ip); + + return error; +} + +/** + * ea_init_i - initializes a new eattr block + * @ip: + * @er: + * @private: + * + * Returns: errno + */ + +static int +ea_init_i(struct gfs_inode *ip, + struct gfs_ea_request *er, + void *private) +{ + struct buffer_head *bh; + int error; + + error = ea_alloc_blk(ip, &bh); + if (error) + return error; + + ip->i_di.di_eattr = bh->b_blocknr; + error = ea_write(ip, GFS_EA_BH2FIRST(bh), er); + + brelse(bh); + + return error; +} + +/** + * ea_init - initializes a new eattr block + * @ip: + * @er: + * + * Returns: errno + */ + +static int +ea_init(struct gfs_inode *ip, struct gfs_ea_request *er) +{ + unsigned int jbsize = ip->i_sbd->sd_jbsize; + unsigned int blks = 1; + + if (GFS_EAREQ_SIZE_STUFFED(er) > jbsize) + blks += DIV_RU(er->er_data_len, jbsize); + + return ea_alloc_skeleton(ip, er, + blks, + ea_init_i, NULL); +} + +/** + * ea_split_ea - + * @ea: + * + * Returns: the new ea + */ + +static struct gfs_ea_header * +ea_split_ea(struct gfs_ea_header *ea) +{ + uint32_t ea_size = GFS_EA_SIZE(ea); + struct gfs_ea_header *new = (struct gfs_ea_header *)((char *)ea + ea_size); + uint32_t new_size = GFS_EA_REC_LEN(ea) - ea_size; + int last = ea->ea_flags & GFS_EAFLAG_LAST; + + ea->ea_rec_len = cpu_to_gfs32(ea_size); + ea->ea_flags ^= last; + + new->ea_rec_len = cpu_to_gfs32(new_size); + new->ea_flags = last; + + return new; +} + +/** + * ea_set_remove_stuffed - + * @ip: + * @ea: + * + */ + +static void +ea_set_remove_stuffed(struct gfs_inode *ip, struct gfs_ea_location *el) +{ + struct gfs_ea_header *ea = el->el_ea; + struct gfs_ea_header *prev = el->el_prev; + uint32_t len; + + gfs_trans_add_bh(ip->i_gl, el->el_bh); + + if (!prev || !GFS_EA_IS_STUFFED(ea)) { + ea->ea_type = GFS_EATYPE_UNUSED; + return; + } else if (GFS_EA2NEXT(prev) != ea) { + prev = GFS_EA2NEXT(prev); + gfs_assert_withdraw(ip->i_sbd, GFS_EA2NEXT(prev) == ea); + } + + len = GFS_EA_REC_LEN(prev) + GFS_EA_REC_LEN(ea); + prev->ea_rec_len = cpu_to_gfs32(len); + + if (GFS_EA_IS_LAST(ea)) + prev->ea_flags |= GFS_EAFLAG_LAST; +} + +struct ea_set { + int ea_split; + + struct gfs_ea_request *es_er; + struct gfs_ea_location *es_el; + + struct buffer_head *es_bh; + struct gfs_ea_header *es_ea; +}; + +/** + * ea_set_simple_noalloc - + * @ip: + * @ea: + * @es: + * + * Returns: errno + */ + +static int +ea_set_simple_noalloc(struct gfs_inode *ip, + struct buffer_head *bh, + struct gfs_ea_header *ea, + struct ea_set *es) +{ + struct gfs_ea_request *er = es->es_er; + int error; + + error = gfs_trans_begin(ip->i_sbd, 3, 0); + if (error) + return error; + + gfs_trans_add_bh(ip->i_gl, bh); + + if (es->ea_split) + ea = ea_split_ea(ea); + + ea_write(ip, ea, er); + + if (es->es_el) + ea_set_remove_stuffed(ip, es->es_el); + + { + struct buffer_head *dibh; + error = gfs_get_inode_buffer(ip, &dibh); + if (!error) { + if (er->er_mode) { + ip->i_vnode->i_mode = er->er_mode; + gfs_inode_attr_out(ip); + } + ip->i_di.di_ctime = get_seconds(); + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + } + + gfs_trans_end(ip->i_sbd); + + return error; +} + +/** + * ea_set_simple_alloc - + * @ip: + * @er: + * @private: + * + * Returns: errno + */ + +static int +ea_set_simple_alloc(struct gfs_inode *ip, + struct gfs_ea_request *er, + void *private) +{ + struct ea_set *es = (struct ea_set *)private; + struct gfs_ea_header *ea = es->es_ea; + int error; + + gfs_trans_add_bh(ip->i_gl, es->es_bh); + + if (es->ea_split) + ea = ea_split_ea(ea); + + error = ea_write(ip, ea, er); + if (error) + return error; + + if (es->es_el) + ea_set_remove_stuffed(ip, es->es_el); + + return 0; +} + +/** + * ea_set_simple - + * @ip: + * @el: + * + * Returns: errno + */ + +static int +ea_set_simple(struct gfs_inode *ip, + struct buffer_head *bh, + struct gfs_ea_header *ea, + struct gfs_ea_header *prev, + void *private) +{ + struct ea_set *es = (struct ea_set *)private; + unsigned int size; + int stuffed; + int error; + + stuffed = ea_calc_size(ip->i_sbd, es->es_er, &size); + + if (ea->ea_type == GFS_EATYPE_UNUSED) { + if (GFS_EA_REC_LEN(ea) < size) + return 0; + if (!GFS_EA_IS_STUFFED(ea)) { + error = ea_remove_unstuffed(ip, bh, ea, prev, TRUE); + if (error) + return error; + } + es->ea_split = FALSE; + } else if (GFS_EA_REC_LEN(ea) - GFS_EA_SIZE(ea) >= size) + es->ea_split = TRUE; + else + return 0; + + if (stuffed) { + error = ea_set_simple_noalloc(ip, bh, ea, es); + if (error) + return error; + } else { + unsigned int blks; + + es->es_bh = bh; + es->es_ea = ea; + blks = 2 + DIV_RU(es->es_er->er_data_len, + ip->i_sbd->sd_jbsize); + + error = ea_alloc_skeleton(ip, es->es_er, + blks, + ea_set_simple_alloc, es); + if (error) + return error; + } + + return 1; +} + +/** + * ea_set_block - + * @ip: + * @er: + * @private: + * + * Returns: errno + */ + +static int +ea_set_block(struct gfs_inode *ip, + struct gfs_ea_request *er, + void *private) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head *indbh, *newbh; + uint64_t *eablk; + int error; + + if (ip->i_di.di_flags & GFS_DIF_EA_INDIRECT) { + uint64_t *end; + + error = gfs_dread(ip->i_gl, ip->i_di.di_eattr, + DIO_START | DIO_WAIT, &indbh); + if (error) + return error; + + if (gfs_metatype_check(sdp, indbh, GFS_METATYPE_IN)) { + error = -EIO; + goto out; + } + + eablk = (uint64_t *)(indbh->b_data + sizeof(struct gfs_indirect)); + end = eablk + sdp->sd_inptrs; + + for (; eablk < end; eablk++) + if (!*eablk) + break; + + if (eablk == end) { + error = -ENOSPC; + goto out; + } + + gfs_trans_add_bh(ip->i_gl, indbh); + } else { + uint64_t blk; + + error = gfs_metaalloc(ip, &blk); + if (error) + return error; + + error = gfs_dread(ip->i_gl, blk, + DIO_NEW | DIO_START | DIO_WAIT, &indbh); + if (error) + return error; + + gfs_trans_add_bh(ip->i_gl, indbh); + gfs_metatype_set(indbh, GFS_METATYPE_IN, GFS_FORMAT_IN); + gfs_buffer_clear_tail(indbh, sizeof(struct gfs_meta_header)); + + eablk = (uint64_t *)(indbh->b_data + sizeof(struct gfs_indirect)); + *eablk = cpu_to_gfs64(ip->i_di.di_eattr); + ip->i_di.di_eattr = blk; + ip->i_di.di_flags |= GFS_DIF_EA_INDIRECT; + ip->i_di.di_blocks++; + + eablk++; + } + + error = ea_alloc_blk(ip, &newbh); + if (error) + goto out; + + *eablk = cpu_to_gfs64((uint64_t)newbh->b_blocknr); + error = ea_write(ip, GFS_EA_BH2FIRST(newbh), er); + brelse(newbh); + if (error) + goto out; + + if (private) + ea_set_remove_stuffed(ip, (struct gfs_ea_location *)private); + + out: + brelse(indbh); + + return error; +} + +/** + * ea_set_i - + * @ip: + * @el: + * + * Returns: errno + */ + +static int +ea_set_i(struct gfs_inode *ip, + struct gfs_ea_request *er, + struct gfs_ea_location *el) +{ + { + struct ea_set es; + int error; + + memset(&es, 0, sizeof(struct ea_set)); + es.es_er = er; + es.es_el = el; + + error = ea_foreach(ip, ea_set_simple, &es); + if (error > 0) + return 0; + if (error) + return error; + } + { + unsigned int blks = 2; + if (!(ip->i_di.di_flags & GFS_DIF_EA_INDIRECT)) + blks++; + if (GFS_EAREQ_SIZE_STUFFED(er) > ip->i_sbd->sd_jbsize) + blks += DIV_RU(er->er_data_len, + ip->i_sbd->sd_jbsize); + + return ea_alloc_skeleton(ip, er, blks, ea_set_block, el); + } +} + +/** + * ea_set_remove_unstuffed - + * @ip: + * @el: + * + * Returns: errno + */ + +static int +ea_set_remove_unstuffed(struct gfs_inode *ip, struct gfs_ea_location *el) +{ + if (el->el_prev && GFS_EA2NEXT(el->el_prev) != el->el_ea) { + el->el_prev = GFS_EA2NEXT(el->el_prev); + gfs_assert_withdraw(ip->i_sbd, + GFS_EA2NEXT(el->el_prev) == el->el_ea); + } + + return ea_remove_unstuffed(ip, el->el_bh, el->el_ea, el->el_prev, FALSE); +} + +/** + * gfs_ea_set_i - + * @ip: + * @er: + * + * Returns: errno + */ + +int +gfs_ea_set_i(struct gfs_inode *ip, struct gfs_ea_request *er) +{ + struct gfs_ea_location el; + int error; + + if (!ip->i_di.di_eattr) { + if (er->er_flags & XATTR_REPLACE) + return -ENODATA; + return ea_init(ip, er); + } + + error = gfs_ea_find(ip, er, &el); + if (error) + return error; + + if (el.el_ea) { + if (IS_APPEND(ip->i_vnode)) { + brelse(el.el_bh); + return -EPERM; + } + + error = -EEXIST; + if (!(er->er_flags & XATTR_CREATE)) { + int unstuffed = !GFS_EA_IS_STUFFED(el.el_ea); + error = ea_set_i(ip, er, &el); + if (!error && unstuffed) + ea_set_remove_unstuffed(ip, &el); + } + + brelse(el.el_bh); + } else { + error = -ENODATA; + if (!(er->er_flags & XATTR_REPLACE)) + error = ea_set_i(ip, er, NULL); + } + + return error; +} + +/** + * gfs_ea_set - + * @ip: + * @er: + * + * Returns: errno + */ + +int +gfs_ea_set(struct gfs_inode *ip, struct gfs_ea_request *er) +{ + struct gfs_holder i_gh; + int error; + + if (!er->er_name_len || + er->er_name_len > GFS_EA_MAX_NAME_LEN) + return -EINVAL; + if (!er->er_data || !er->er_data_len) { + er->er_data = NULL; + er->er_data_len = 0; + } + error = gfs_ea_check_size(ip->i_sbd, er); + if (error) + return error; + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); + if (error) + return error; + + if (IS_IMMUTABLE(ip->i_vnode)) + error = -EPERM; + else + error = gfs_ea_ops[er->er_type]->eo_set(ip, er); + + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * ea_remove_stuffed - + * @ip: + * @el: + * @mode: + * + * Returns: errno + */ + +static int +ea_remove_stuffed(struct gfs_inode *ip, + struct gfs_ea_location *el) +{ + struct gfs_ea_header *ea = el->el_ea; + struct gfs_ea_header *prev = el->el_prev; + int error; + + error = gfs_trans_begin(ip->i_sbd, 2, 0); + if (error) + return error; + + gfs_trans_add_bh(ip->i_gl, el->el_bh); + + if (prev) { + uint32_t len; + + len = GFS_EA_REC_LEN(prev) + GFS_EA_REC_LEN(ea); + prev->ea_rec_len = cpu_to_gfs32(len); + + if (GFS_EA_IS_LAST(ea)) + prev->ea_flags |= GFS_EAFLAG_LAST; + } else + ea->ea_type = GFS_EATYPE_UNUSED; + + { + struct buffer_head *dibh; + error = gfs_get_inode_buffer(ip, &dibh); + if (!error) { + ip->i_di.di_ctime = get_seconds(); + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + } + + gfs_trans_end(ip->i_sbd); + + return error; +} + +/** + * gfs_ea_remove_i - + * @ip: + * @er: + * + * Returns: errno + */ + +int +gfs_ea_remove_i(struct gfs_inode *ip, struct gfs_ea_request *er) +{ + struct gfs_ea_location el; + int error; + + if (!ip->i_di.di_eattr) + return -ENODATA; + + error = gfs_ea_find(ip, er, &el); + if (error) + return error; + if (!el.el_ea) + return -ENODATA; + + if (GFS_EA_IS_STUFFED(el.el_ea)) + error = ea_remove_stuffed(ip, &el); + else + error = ea_remove_unstuffed(ip, el.el_bh, el.el_ea, el.el_prev, FALSE); + + brelse(el.el_bh); + + return error; +} + +/** + * gfs_ea_remove - sets (or creates or replaces) an extended attribute + * @ip: pointer to the inode of the target file + * @er: request information + * + * Returns: errno + */ + +int +gfs_ea_remove(struct gfs_inode *ip, struct gfs_ea_request *er) +{ + struct gfs_holder i_gh; + int error; + + if (!er->er_name_len || + er->er_name_len > GFS_EA_MAX_NAME_LEN) + return -EINVAL; + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); + if (error) + return error; + + if (IS_IMMUTABLE(ip->i_vnode) || IS_APPEND(ip->i_vnode)) + error = -EPERM; + else + error = gfs_ea_ops[er->er_type]->eo_remove(ip, er); + + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gfs_ea_acl_init - + * @ip: + * @er: + * + * Returns: errno + */ + +int +gfs_ea_acl_init(struct gfs_inode *ip, struct gfs_ea_request *er) +{ + int error; + + if (!ip->i_di.di_eattr) + return ea_init_i(ip, er, NULL); + + { + struct buffer_head *bh; + struct gfs_ea_header *ea; + unsigned int size; + + ea_calc_size(ip->i_sbd, er, &size); + + error = gfs_dread(ip->i_gl, ip->i_di.di_eattr, + DIO_START | DIO_WAIT, &bh); + if (error) + return error; + + if (gfs_metatype_check(ip->i_sbd, bh, GFS_METATYPE_EA)) { + brelse(bh); + return -EIO; + } + + ea = GFS_EA_BH2FIRST(bh); + if (GFS_EA_REC_LEN(ea) - GFS_EA_SIZE(ea) >= size) { + ea = ea_split_ea(ea); + ea_write(ip, ea, er); + brelse(bh); + return 0; + } + + brelse(bh); + } + + error = ea_set_block(ip, er, NULL); + gfs_assert_withdraw(ip->i_sbd, error != -ENOSPC); + if (error) + return error; + + { + struct buffer_head *dibh; + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + return error; + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + + return error; +} + +/** + * ea_acl_chmod_unstuffed - + * @ip: + * @ea: + * @data: + * + * Returns: errno + */ + +static int +ea_acl_chmod_unstuffed(struct gfs_inode *ip, + struct gfs_ea_header *ea, + char *data) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head **bh; + unsigned int amount = GFS_EA_DATA_LEN(ea); + unsigned int nptrs = DIV_RU(amount, sdp->sd_jbsize); + uint64_t *dataptrs = GFS_EA2DATAPTRS(ea); + unsigned int x; + int error; + + bh = kmalloc(nptrs * sizeof(struct buffer_head *), GFP_KERNEL); + if (!bh) + return -ENOMEM; + + error = gfs_trans_begin(sdp, 1 + nptrs, 0); + if (error) + goto out; + + for (x = 0; x < nptrs; x++) { + error = gfs_dread(ip->i_gl, gfs64_to_cpu(*dataptrs), + DIO_START, bh + x); + if (error) { + while (x--) + brelse(bh[x]); + goto fail; + } + dataptrs++; + } + + for (x = 0; x < nptrs; x++) { + error = gfs_dreread(sdp, bh[x], DIO_WAIT); + if (error) { + for (; x < nptrs; x++) + brelse(bh[x]); + goto fail; + } + if (gfs_metatype_check2(sdp, bh[x], + GFS_METATYPE_ED, GFS_METATYPE_EA)) { + for (; x < nptrs; x++) + brelse(bh[x]); + error = -EIO; + goto fail; + } + + gfs_trans_add_bh(ip->i_gl, bh[x]); + + memcpy(bh[x]->b_data + sizeof(struct gfs_meta_header), + data, + (sdp->sd_jbsize > amount) ? amount : sdp->sd_jbsize); + + amount -= sdp->sd_jbsize; + data += sdp->sd_jbsize; + + brelse(bh[x]); + } + + out: + kfree(bh); + + return error; + + fail: + gfs_trans_end(sdp); + kfree(bh); + + return error; +} + +/** + * gfs_ea_acl_chmod - + * @ip: + * @el: + * @attr: + * @data: + * + * Returns: errno + */ + +int +gfs_ea_acl_chmod(struct gfs_inode *ip, struct gfs_ea_location *el, + struct iattr *attr, char *data) +{ + struct buffer_head *dibh; + int error; + + if (GFS_EA_IS_STUFFED(el->el_ea)) { + error = gfs_trans_begin(ip->i_sbd, 2, 0); + if (error) + return error; + + gfs_trans_add_bh(ip->i_gl, el->el_bh); + memcpy(GFS_EA2DATA(el->el_ea), + data, + GFS_EA_DATA_LEN(el->el_ea)); + } else + error = ea_acl_chmod_unstuffed(ip, el->el_ea, data); + + if (error) + return error; + + error = gfs_get_inode_buffer(ip, &dibh); + if (!error) { + error = inode_setattr(ip->i_vnode, attr); + gfs_assert_warn(ip->i_sbd, !error); + gfs_inode_attr_out(ip); + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + + gfs_trans_end(ip->i_sbd); + + return error; +} + +/** + * ea_dealloc_indirect - + * @ip: + * + * Returns: errno + */ + +static int +ea_dealloc_indirect(struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_rgrp_list rlist; + struct buffer_head *indbh, *dibh; + uint64_t *eablk, *end; + unsigned int rg_blocks = 0; + uint64_t bstart = 0; + unsigned int blen = 0; + unsigned int x; + int error; + + memset(&rlist, 0, sizeof(struct gfs_rgrp_list)); + + error = gfs_dread(ip->i_gl, ip->i_di.di_eattr, + DIO_START | DIO_WAIT, &indbh); + if (error) + return error; + + if (gfs_metatype_check(sdp, indbh, GFS_METATYPE_IN)) { + error = -EIO; + goto out; + } + + eablk = (uint64_t *)(indbh->b_data + sizeof(struct gfs_indirect)); + end = eablk + sdp->sd_inptrs; + + for (; eablk < end; eablk++) { + uint64_t bn; + + if (!*eablk) + break; + bn = gfs64_to_cpu(*eablk); + + if (bstart + blen == bn) + blen++; + else { + if (bstart) + gfs_rlist_add(sdp, &rlist, bstart); + bstart = bn; + blen = 1; + } + } + if (bstart) + gfs_rlist_add(sdp, &rlist, bstart); + else + goto out; + + gfs_rlist_alloc(&rlist, LM_ST_EXCLUSIVE, 0); + + for (x = 0; x < rlist.rl_rgrps; x++) { + struct gfs_rgrpd *rgd; + rgd = get_gl2rgd(rlist.rl_ghs[x].gh_gl); + rg_blocks += rgd->rd_ri.ri_length; + } + + error = gfs_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs); + if (error) + goto out_rlist_free; + + error = gfs_trans_begin(sdp, 2 + rg_blocks, 1); + if (error) + goto out_gunlock; + + gfs_trans_add_bh(ip->i_gl, indbh); + + eablk = (uint64_t *)(indbh->b_data + sizeof(struct gfs_indirect)); + bstart = 0; + blen = 0; + + for (; eablk < end; eablk++) { + uint64_t bn; + + if (!*eablk) + break; + bn = gfs64_to_cpu(*eablk); + + if (bstart + blen == bn) + blen++; + else { + if (bstart) + gfs_metafree(ip, bstart, blen); + bstart = bn; + blen = 1; + } + + *eablk = 0; + if (!ip->i_di.di_blocks) + gfs_consist_inode(ip); + ip->i_di.di_blocks--; + } + if (bstart) + gfs_metafree(ip, bstart, blen); + + ip->i_di.di_flags &= ~GFS_DIF_EA_INDIRECT; + + error = gfs_get_inode_buffer(ip, &dibh); + if (!error) { + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + + gfs_trans_end(sdp); + + out_gunlock: + gfs_glock_dq_m(rlist.rl_rgrps, rlist.rl_ghs); + + out_rlist_free: + gfs_rlist_free(&rlist); + + out: + brelse(indbh); + + return error; +} + +/** + * ea_dealloc_block - + * @ip: + * + * Returns: errno + */ + +static int +ea_dealloc_block(struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al = ip->i_alloc; + struct gfs_rgrpd *rgd; + struct buffer_head *dibh; + int error; + + rgd = gfs_blk2rgrpd(sdp, ip->i_di.di_eattr); + if (!rgd) { + gfs_consist_inode(ip); + return -EIO; + } + + error = gfs_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &al->al_rgd_gh); + if (error) + return error; + + error = gfs_trans_begin(sdp, 1 + rgd->rd_ri.ri_length, 1); + if (error) + goto out_gunlock; + + gfs_metafree(ip, ip->i_di.di_eattr, 1); + + ip->i_di.di_eattr = 0; + if (!ip->i_di.di_blocks) + gfs_consist_inode(ip); + ip->i_di.di_blocks--; + + error = gfs_get_inode_buffer(ip, &dibh); + if (!error) { + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + + gfs_trans_end(sdp); + + out_gunlock: + gfs_glock_dq_uninit(&al->al_rgd_gh); + + return error; +} + +/** + * gfs_ea_dealloc - deallocate the extended attribute fork + * @ip: the inode + * + * Returns: errno + */ + +int +gfs_ea_dealloc(struct gfs_inode *ip) +{ + struct gfs_alloc *al; + int error; + + al = gfs_alloc_get(ip); + + error = gfs_quota_hold_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + if (error) + goto out_alloc; + + error = gfs_rindex_hold(ip->i_sbd, &al->al_ri_gh); + if (error) + goto out_quota; + + error = ea_foreach(ip, ea_dealloc_unstuffed, NULL); + if (error) + goto out_rindex; + + if (ip->i_di.di_flags & GFS_DIF_EA_INDIRECT) { + error = ea_dealloc_indirect(ip); + if (error) + goto out_rindex; + } + + error = ea_dealloc_block(ip); + + out_rindex: + gfs_glock_dq_uninit(&al->al_ri_gh); + + out_quota: + gfs_quota_unhold_m(ip); + + out_alloc: + gfs_alloc_put(ip); + + return error; +} + +/** + * gfs_get_eattr_meta - return all the eattr blocks of a file + * @dip: the directory + * @ub: the structure representing the user buffer to copy to + * + * Returns: errno + */ + +int +gfs_get_eattr_meta(struct gfs_inode *ip, struct gfs_user_buffer *ub) +{ + struct buffer_head *bh; + int error; + + error = gfs_dread(ip->i_gl, ip->i_di.di_eattr, + DIO_START | DIO_WAIT, &bh); + if (error) + return error; + + gfs_add_bh_to_ub(ub, bh); + + if (ip->i_di.di_flags & GFS_DIF_EA_INDIRECT) { + struct buffer_head *eabh; + uint64_t *eablk, *end; + + if (gfs_metatype_check(ip->i_sbd, bh, GFS_METATYPE_IN)) { + error = -EIO; + goto out; + } + + eablk = (uint64_t *)(bh->b_data + sizeof(struct gfs_indirect)); + end = eablk + ip->i_sbd->sd_inptrs; + + for (; eablk < end; eablk++) { + uint64_t bn; + + if (!*eablk) + break; + bn = gfs64_to_cpu(*eablk); + + error = gfs_dread(ip->i_gl, bn, + DIO_START | DIO_WAIT, &eabh); + if (error) + break; + gfs_add_bh_to_ub(ub, eabh); + brelse(eabh); + if (error) + break; + } + } + + out: + brelse(bh); + + return error; +} --- linux-2.6.28.orig/ubuntu/gfs/dir.h +++ linux-2.6.28/ubuntu/gfs/dir.h @@ -0,0 +1,42 @@ +#ifndef __DIR_DOT_H__ +#define __DIR_DOT_H__ + +/** + * gfs_filldir_t - Report a directory entry to the caller of gfs_dir_read() + * @opaque: opaque data used by the function + * @name: the name of the directory entry + * @length: the length of the name + * @offset: the entry's offset in the directory + * @inum: the inode number the entry points to + * @type: the type of inode the entry points to + * + * Returns: 0 on success, 1 if buffer full + */ + +typedef int (*gfs_filldir_t) (void *opaque, + const char *name, unsigned int length, + uint64_t offset, + struct gfs_inum *inum, unsigned int type); + +int gfs_filecmp(struct qstr *file1, char *file2, int len_of_file2); +int gfs_dirent_alloc(struct gfs_inode *dip, struct buffer_head *bh, + int name_len, struct gfs_dirent **dent_out); + +int gfs_dir_search(struct gfs_inode *dip, struct qstr *filename, + struct gfs_inum *inum, unsigned int *type); +int gfs_dir_add(struct gfs_inode *dip, struct qstr *filename, + struct gfs_inum *inum, unsigned int type); +int gfs_dir_del(struct gfs_inode *dip, struct qstr *filename); +int gfs_dir_read(struct gfs_inode *dip, uint64_t * offset, void *opaque, + gfs_filldir_t filldir); +int gfs_dir_mvino(struct gfs_inode *dip, struct qstr *filename, + struct gfs_inum *new_inum, unsigned int new_type); + +int gfs_dir_exhash_free(struct gfs_inode *dip); + +int gfs_diradd_alloc_required(struct gfs_inode *dip, struct qstr *filename, + int *alloc_required); + +int gfs_get_dir_meta(struct gfs_inode *ip, struct gfs_user_buffer *ub); + +#endif /* __DIR_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/ops_inode.h +++ linux-2.6.28/ubuntu/gfs/ops_inode.h @@ -0,0 +1,9 @@ +#ifndef __OPS_INODE_DOT_H__ +#define __OPS_INODE_DOT_H__ + +extern struct inode_operations gfs_file_iops; +extern struct inode_operations gfs_dir_iops; +extern struct inode_operations gfs_symlink_iops; +extern struct inode_operations gfs_dev_iops; + +#endif /* __OPS_INODE_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/dio.c +++ linux-2.6.28/ubuntu/gfs/dio.c @@ -0,0 +1,1342 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "dio.h" +#include "glock.h" +#include "glops.h" +#include "inode.h" +#include "log.h" +#include "lops.h" +#include "rgrp.h" +#include "trans.h" + +#define buffer_busy(bh) ((bh)->b_state & ((1ul << BH_Dirty) | (1ul << BH_Lock))) + +/** + * aspace_get_block - + * @inode: + * @lblock: + * @bh_result: + * @create: + * + * Returns: errno + */ + +static int +aspace_get_block(struct inode *inode, sector_t lblock, + struct buffer_head *bh_result, int create) +{ + gfs_assert_warn(get_v2sdp(inode->i_sb), FALSE); + return -ENOSYS; +} + +/** + * gfs_aspace_writepage - write an aspace page + * @page: the page + * @wbc: + * + * Returns: errno + */ + +static int +gfs_aspace_writepage(struct page *page, struct writeback_control *wbc) +{ + return block_write_full_page(page, aspace_get_block, wbc); +} + +/** + * stuck_releasepage - We're stuck in gfs_releasepage(). Print stuff out. + * @bh: the buffer we're stuck on + * + */ + +static void +stuck_releasepage(struct buffer_head *bh) +{ + struct gfs_sbd *sdp = get_v2sdp(bh->b_page->mapping->host->i_sb); + struct gfs_bufdata *bd = get_v2bd(bh); + + printk("GFS: fsid=%s: stuck in gfs_releasepage()...\n", sdp->sd_fsname); + printk("GFS: fsid=%s: blkno = %"PRIu64", bh->b_count = %d\n", + sdp->sd_fsname, + (uint64_t)bh->b_blocknr, + atomic_read(&bh->b_count)); + printk("GFS: fsid=%s: get_v2bd(bh) = %s\n", + sdp->sd_fsname, + (bd) ? "!NULL" : "NULL"); + + if (bd) { + struct gfs_glock *gl = bd->bd_gl; + + printk("GFS: fsid=%s: gl = (%u, %"PRIu64")\n", + sdp->sd_fsname, + gl->gl_name.ln_type, + gl->gl_name.ln_number); + + printk("GFS: fsid=%s: bd_new_le.le_trans = %s\n", + sdp->sd_fsname, + (bd->bd_new_le.le_trans) ? "!NULL" : "NULL"); + printk("GFS: fsid=%s: bd_incore_le.le_trans = %s\n", + sdp->sd_fsname, + (bd->bd_incore_le.le_trans) ? "!NULL" : "NULL"); + printk("GFS: fsid=%s: bd_frozen = %s\n", + sdp->sd_fsname, + (bd->bd_frozen) ? "!NULL" : "NULL"); + printk("GFS: fsid=%s: bd_pinned = %u\n", + sdp->sd_fsname, bd->bd_pinned); + printk("GFS: fsid=%s: bd_ail_tr_list = %s\n", + sdp->sd_fsname, + (list_empty(&bd->bd_ail_tr_list)) ? "Empty" : "!Empty"); + + if (gl->gl_ops == &gfs_inode_glops) { + struct gfs_inode *ip = get_gl2ip(gl); + + if (ip) { + unsigned int x; + + printk("GFS: fsid=%s: ip = %"PRIu64"/%"PRIu64"\n", + sdp->sd_fsname, + ip->i_num.no_formal_ino, + ip->i_num.no_addr); + printk("GFS: fsid=%s: ip->i_count = %d, ip->i_vnode = %s\n", + sdp->sd_fsname, + atomic_read(&ip->i_count), + (ip->i_vnode) ? "!NULL" : "NULL"); + for (x = 0; x < GFS_MAX_META_HEIGHT; x++) + printk("GFS: fsid=%s: ip->i_cache[%u] = %s\n", + sdp->sd_fsname, x, + (ip->i_cache[x]) ? "!NULL" : "NULL"); + } + } + } +} + +/** + * gfs_aspace_releasepage - free the metadata associated with a page + * @page: the page that's being released + * @gfp_mask: passed from Linux VFS, ignored by us + * + * Call try_to_free_buffers() if the buffers in this page can be + * released. + * + * Returns: 0 + */ + +static int +gfs_aspace_releasepage(struct page *page, gfp_t gfp_mask) +{ + struct inode *aspace = page->mapping->host; + struct gfs_sbd *sdp = get_v2sdp(aspace->i_sb); + struct buffer_head *bh, *head; + struct gfs_bufdata *bd; + unsigned long t; + + if (!page_has_buffers(page)) + goto out; + + head = bh = page_buffers(page); + do { + t = jiffies; + + while (atomic_read(&bh->b_count)) { + if (atomic_read(&aspace->i_writecount)) { + if (time_after_eq(jiffies, + t + + gfs_tune_get(sdp, gt_stall_secs) * HZ)) { + stuck_releasepage(bh); + t = jiffies; + } + + yield(); + continue; + } + + return 0; + } + + bd = get_v2bd(bh); + if (bd) { + gfs_assert_warn(sdp, bd->bd_bh == bh); + gfs_assert_warn(sdp, !bd->bd_new_le.le_trans); + gfs_assert_warn(sdp, !bd->bd_incore_le.le_trans); + gfs_assert_warn(sdp, !bd->bd_frozen); + gfs_assert_warn(sdp, !bd->bd_pinned); + gfs_assert_warn(sdp, list_empty(&bd->bd_ail_tr_list)); + kmem_cache_free(gfs_bufdata_cachep, bd); + atomic_dec(&sdp->sd_bufdata_count); + set_v2bd(bh, NULL); + } + + bh = bh->b_this_page; + } + while (bh != head); + + out: + return try_to_free_buffers(page); +} + +static struct address_space_operations aspace_aops = { + .writepage = gfs_aspace_writepage, + .releasepage = gfs_aspace_releasepage, +}; + +/** + * gfs_aspace_get - Create and initialize a struct inode structure + * @sdp: the filesystem the aspace is in + * + * Right now a struct inode is just a struct inode. Maybe Linux + * will supply a more lightweight address space construct (that works) + * in the future. + * + * Make sure pages/buffers in this aspace aren't in high memory. + * + * Returns: the aspace + */ + +struct inode * +gfs_aspace_get(struct gfs_sbd *sdp) +{ + struct inode *aspace; + + aspace = new_inode(sdp->sd_vfs); + if (aspace) { + mapping_set_gfp_mask(aspace->i_mapping, GFP_KERNEL); + aspace->i_mapping->a_ops = &aspace_aops; + aspace->i_size = ~0ULL; + set_v2ip(aspace, NULL); + insert_inode_hash(aspace); + } + + return aspace; +} + +/** + * gfs_aspace_put - get rid of an aspace + * @aspace: + * + */ + +void +gfs_aspace_put(struct inode *aspace) +{ + remove_inode_hash(aspace); + iput(aspace); +} + +/** + * gfs_ail_start_trans - Start I/O on a part of the AIL + * @sdp: the filesystem + * @tr: the part of the AIL + * + */ + +void +gfs_ail_start_trans(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct list_head *head, *tmp, *prev; + struct gfs_bufdata *bd; + struct buffer_head *bh; + int retry; + + do { + retry = FALSE; + + spin_lock(&sdp->sd_ail_lock); + + for (head = &tr->tr_ail_bufs, tmp = head->prev, prev = tmp->prev; + tmp != head; + tmp = prev, prev = tmp->prev) { + bd = list_entry(tmp, struct gfs_bufdata, bd_ail_tr_list); + bh = bd->bd_bh; + + if (gfs_trylock_buffer(bh)) + continue; + + if (bd->bd_pinned) { + gfs_unlock_buffer(bh); + continue; + } + + if (!buffer_busy(bh)) { + if (!buffer_uptodate(bh)) + gfs_io_error_bh(sdp, bh); + + list_del_init(&bd->bd_ail_tr_list); + list_del(&bd->bd_ail_gl_list); + + gfs_unlock_buffer(bh); + brelse(bh); + continue; + } + + if (buffer_dirty(bh)) { + list_move(&bd->bd_ail_tr_list, head); + + spin_unlock(&sdp->sd_ail_lock); + wait_on_buffer(bh); + ll_rw_block(WRITE, 1, &bh); + spin_lock(&sdp->sd_ail_lock); + + gfs_unlock_buffer(bh); + retry = TRUE; + break; + } + + gfs_unlock_buffer(bh); + } + + spin_unlock(&sdp->sd_ail_lock); + } while (retry); +} + +/** + * gfs_ail_empty_trans - Check whether or not a trans in the AIL has been synced + * @sdp: the filesystem + * @tr: the transaction + * + */ + +int +gfs_ail_empty_trans(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct list_head *head, *tmp, *prev; + struct gfs_bufdata *bd; + struct buffer_head *bh; + int ret; + + spin_lock(&sdp->sd_ail_lock); + + for (head = &tr->tr_ail_bufs, tmp = head->prev, prev = tmp->prev; + tmp != head; + tmp = prev, prev = tmp->prev) { + bd = list_entry(tmp, struct gfs_bufdata, bd_ail_tr_list); + bh = bd->bd_bh; + + if (gfs_trylock_buffer(bh)) + continue; + + if (bd->bd_pinned || buffer_busy(bh)) { + gfs_unlock_buffer(bh); + continue; + } + + if (!buffer_uptodate(bh)) + gfs_io_error_bh(sdp, bh); + + list_del_init(&bd->bd_ail_tr_list); + list_del(&bd->bd_ail_gl_list); + + gfs_unlock_buffer(bh); + brelse(bh); + } + + ret = list_empty(head); + + spin_unlock(&sdp->sd_ail_lock); + + return ret; +} + +/** + * ail_empty_gl - remove all buffers for a given lock from the AIL + * @gl: the glock + * + * None of the buffers should be dirty, locked, or pinned. + */ + +static void +ail_empty_gl(struct gfs_glock *gl) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_bufdata *bd; + struct buffer_head *bh; + + spin_lock(&sdp->sd_ail_lock); + + while (!list_empty(&gl->gl_ail_bufs)) { + bd = list_entry(gl->gl_ail_bufs.next, + struct gfs_bufdata, bd_ail_gl_list); + bh = bd->bd_bh; + + gfs_assert_withdraw(sdp, !bd->bd_pinned && !buffer_busy(bh)); + if (!buffer_uptodate(bh)) + gfs_io_error_bh(sdp, bh); + + list_del_init(&bd->bd_ail_tr_list); + list_del(&bd->bd_ail_gl_list); + + brelse(bh); + } + + spin_unlock(&sdp->sd_ail_lock); +} + +/** + * gfs_inval_buf - Invalidate all buffers associated with a glock + * @gl: the glock + * + */ + +void +gfs_inval_buf(struct gfs_glock *gl) +{ + struct inode *aspace = gl->gl_aspace; + struct address_space *mapping = gl->gl_aspace->i_mapping; + + ail_empty_gl(gl); + + atomic_inc(&aspace->i_writecount); + truncate_inode_pages(mapping, 0); + atomic_dec(&aspace->i_writecount); + + gfs_assert_withdraw(gl->gl_sbd, !mapping->nrpages); +} + +/** + * gfs_sync_buf - Sync all buffers associated with a glock + * @gl: The glock + * @flags: DIO_START | DIO_WAIT | DIO_CHECK + * + */ + +void +gfs_sync_buf(struct gfs_glock *gl, int flags) +{ + struct address_space *mapping = gl->gl_aspace->i_mapping; + int error = 0; + + if (flags & DIO_START) + error = filemap_fdatawrite(mapping); + if (!error && (flags & DIO_WAIT)) + error = filemap_fdatawait(mapping); + if (!error && (flags & (DIO_INVISIBLE | DIO_CHECK)) == DIO_CHECK) + ail_empty_gl(gl); + + if (error) + gfs_io_error(gl->gl_sbd); +} + +/** + * getbuf - Get a buffer with a given address space + * @sdp: the filesystem + * @aspace: the address space + * @blkno: the block number (filesystem scope) + * @create: TRUE if the buffer should be created + * + * Returns: the buffer + */ + +static struct buffer_head * +getbuf(struct gfs_sbd *sdp, struct inode *aspace, uint64_t blkno, int create) +{ + struct page *page; + struct buffer_head *bh; + unsigned int shift; + unsigned long index; + unsigned int bufnum; + + shift = PAGE_CACHE_SHIFT - sdp->sd_sb.sb_bsize_shift; + index = blkno >> shift; /* convert block to page */ + bufnum = blkno - (index << shift); /* block buf index within page */ + + if (create) { + RETRY_MALLOC(page = grab_cache_page(aspace->i_mapping, index), page); + } else { + page = find_lock_page(aspace->i_mapping, index); + if (!page) + return NULL; + } + + if (!page_has_buffers(page)) + create_empty_buffers(page, sdp->sd_sb.sb_bsize, 0); + + /* Locate header for our buffer within our page */ + for (bh = page_buffers(page); bufnum--; bh = bh->b_this_page) + /* Do nothing */; + get_bh(bh); + + if (!buffer_mapped(bh)) + map_bh(bh, sdp->sd_vfs, blkno); + else if (gfs_assert_warn(sdp, bh->b_bdev == sdp->sd_vfs->s_bdev && + bh->b_blocknr == blkno)) + map_bh(bh, sdp->sd_vfs, blkno); + + unlock_page(page); + page_cache_release(page); + + return bh; +} + +/** + * gfs_dgetblk - Get a block + * @gl: The glock associated with this block + * @blkno: The block number + * + * Returns: The buffer + */ + +struct buffer_head * +gfs_dgetblk(struct gfs_glock *gl, uint64_t blkno) +{ + return getbuf(gl->gl_sbd, gl->gl_aspace, blkno, CREATE); +} + +/** + * gfs_dread - Read a block from disk + * @gl: The glock covering the block + * @blkno: The block number + * @flags: flags to gfs_dreread() + * @bhp: the place where the buffer is returned (NULL on failure) + * + * Returns: errno + */ + +int +gfs_dread(struct gfs_glock *gl, uint64_t blkno, + int flags, struct buffer_head **bhp) +{ + int error; + + *bhp = gfs_dgetblk(gl, blkno); + error = gfs_dreread(gl->gl_sbd, *bhp, flags); + if (error) + brelse(*bhp); + + return error; +} + +/** + * gfs_prep_new_buffer - Mark a new buffer we just gfs_dgetblk()ed uptodate + * @bh: the buffer + * + */ + +void +gfs_prep_new_buffer(struct buffer_head *bh) +{ + wait_on_buffer(bh); + clear_buffer_dirty(bh); + set_buffer_uptodate(bh); +} + +/** + * gfs_dreread - Reread a block from disk + * @sdp: the filesystem + * @bh: The block to read + * @flags: Flags that control the read + * + * Returns: errno + */ + +int +gfs_dreread(struct gfs_sbd *sdp, struct buffer_head *bh, int flags) +{ + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + return -EIO; + + /* Fill in meta-header if we have a cached copy, else read from disk */ + if (flags & DIO_NEW) { + if (gfs_mhc_fish(sdp, bh)) + return 0; + clear_buffer_uptodate(bh); + } + + if (flags & DIO_FORCE) + clear_buffer_uptodate(bh); + + if ((flags & DIO_START) && !buffer_uptodate(bh)) + ll_rw_block(READ, 1, &bh); + + if (flags & DIO_WAIT) { + wait_on_buffer(bh); + + if (!buffer_uptodate(bh)) { + gfs_io_error_bh(sdp, bh); + return -EIO; + } + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + return -EIO; + } + + return 0; +} + +/** + * gfs_dwrite - Write a buffer to disk (and/or wait for write to complete) + * @sdp: the filesystem + * @bh: The buffer to write + * @flags: DIO_XXX The type of write/wait operation to do + * + * Returns: errno + */ + +int +gfs_dwrite(struct gfs_sbd *sdp, struct buffer_head *bh, int flags) +{ + if (gfs_assert_warn(sdp, !test_bit(SDF_ROFS, &sdp->sd_flags))) + return -EIO; + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + return -EIO; + + if (flags & DIO_CLEAN) { + lock_buffer(bh); + clear_buffer_dirty(bh); + unlock_buffer(bh); + } + + if (flags & DIO_DIRTY) { + if (gfs_assert_warn(sdp, buffer_uptodate(bh))) + return -EIO; + mark_buffer_dirty(bh); + } + + if ((flags & DIO_START) && buffer_dirty(bh)) { + wait_on_buffer(bh); + ll_rw_block(WRITE, 1, &bh); + } + + if (flags & DIO_WAIT) { + wait_on_buffer(bh); + + if (!buffer_uptodate(bh) || buffer_dirty(bh)) { + gfs_io_error_bh(sdp, bh); + return -EIO; + } + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + return -EIO; + } + + return 0; +} + +/** + * gfs_attach_bufdata - attach a struct gfs_bufdata structure to a buffer + * @bh: The buffer to be attached to + * @gl: the glock the buffer belongs to + * + */ + +void +gfs_attach_bufdata(struct buffer_head *bh, struct gfs_glock *gl) +{ + struct gfs_bufdata *bd; + + lock_page(bh->b_page); + + /* If there's one attached already, we're done */ + if (get_v2bd(bh)) { + unlock_page(bh->b_page); + return; + } + + RETRY_MALLOC(bd = kmem_cache_alloc(gfs_bufdata_cachep, GFP_KERNEL), bd); + atomic_inc(&gl->gl_sbd->sd_bufdata_count); + + memset(bd, 0, sizeof(struct gfs_bufdata)); + + bd->bd_bh = bh; + bd->bd_gl = gl; + + INIT_LE(&bd->bd_new_le, &gfs_buf_lops); + INIT_LE(&bd->bd_incore_le, &gfs_buf_lops); + + init_MUTEX(&bd->bd_lock); + + INIT_LIST_HEAD(&bd->bd_ail_tr_list); + + set_v2bd(bh, bd); + + unlock_page(bh->b_page); +} + +/** + * gfs_is_pinned - Figure out if a buffer is pinned or not + * @sdp: the filesystem the buffer belongs to + * @bh: The buffer to be pinned + * + * Returns: TRUE if the buffer is pinned, FALSE otherwise + */ + +int +gfs_is_pinned(struct gfs_sbd *sdp, struct buffer_head *bh) +{ + struct gfs_bufdata *bd = get_v2bd(bh); + int ret = FALSE; + + if (bd) { + gfs_lock_buffer(bh); + if (bd->bd_pinned) + ret = TRUE; + gfs_unlock_buffer(bh); + } + + return ret; +} + +/** + * gfs_dpin - Pin a metadata buffer in memory + * @sdp: the filesystem the buffer belongs to + * @bh: The buffer to be pinned + * + * "Pinning" means keeping buffer from being written to its in-place location. + * A buffer should be pinned from the time it is added to a new transaction, + * until after it has been written to the log. + * If an earlier change to this buffer is still pinned, waiting to be written + * to on-disk log, we need to keep a "frozen" copy of the old data while this + * transaction is modifying the real data. We keep the frozen copy until + * this transaction's incore_commit(), i.e. until the transaction has + * finished modifying the real data, at which point we can use the real + * buffer for logging, even if the frozen copy didn't get written to the log. + * + */ + +void +gfs_dpin(struct gfs_sbd *sdp, struct buffer_head *bh) +{ + struct gfs_bufdata *bd = get_v2bd(bh); + char *data; + + gfs_assert_withdraw(sdp, !test_bit(SDF_ROFS, &sdp->sd_flags)); + + gfs_lock_buffer(bh); + + gfs_assert_warn(sdp, !bd->bd_frozen); + + if (!bd->bd_pinned++) { + wait_on_buffer(bh); + + /* If this buffer is in the AIL and it has already been written + to in-place disk block, remove it from the AIL. */ + + spin_lock(&sdp->sd_ail_lock); + if (!list_empty(&bd->bd_ail_tr_list) && !buffer_busy(bh)) { + list_del_init(&bd->bd_ail_tr_list); + list_del(&bd->bd_ail_gl_list); + brelse(bh); + } + spin_unlock(&sdp->sd_ail_lock); + + clear_buffer_dirty(bh); + wait_on_buffer(bh); + + if (!buffer_uptodate(bh)) + gfs_io_error_bh(sdp, bh); + } else { + gfs_unlock_buffer(bh); + + gfs_assert_withdraw(sdp, buffer_uptodate(bh)); + + data = gmalloc(sdp->sd_sb.sb_bsize); + + gfs_lock_buffer(bh); + + /* Create frozen copy, if needed. */ + if (bd->bd_pinned > 1) { + memcpy(data, bh->b_data, sdp->sd_sb.sb_bsize); + bd->bd_frozen = data; + } else + kfree(data); + } + + gfs_unlock_buffer(bh); + + get_bh(bh); +} + +/** + * gfs_dunpin - Unpin a buffer + * @sdp: the filesystem the buffer belongs to + * @bh: The buffer to unpin + * @tr: The transaction in the AIL that contains this buffer + * If NULL, don't attach buffer to any AIL list + * (i.e. when dropping a pin reference when merging a new transaction + * with an already existing incore transaction) + * + * Called for (meta) buffers, after they've been logged to on-disk journal. + * Make a (meta) buffer writeable to in-place location on-disk, if recursive + * pin count is 1 (i.e. no other, later transaction is modifying this buffer). + * Add buffer to AIL lists of 1) the latest transaction that's modified and + * logged (on-disk) the buffer, and of 2) the glock that protects the buffer. + * A single buffer might have been modified by more than one transaction + * since the buffer's previous write to disk (in-place location). We keep + * the buffer on only one transaction's AIL list, i.e. that of the latest + * transaction that's completed logging this buffer (no need to write it to + * in-place block multiple times for multiple transactions, only once with + * the most up-to-date data). + * A single buffer will be protected by one and only one glock. If buffer is + * already on a (previous) transaction's AIL, we know that we're already + * on buffer's glock's AIL. + * + */ + +void +gfs_dunpin(struct gfs_sbd *sdp, struct buffer_head *bh, struct gfs_trans *tr) +{ + struct gfs_bufdata *bd = get_v2bd(bh); + + gfs_assert_withdraw(sdp, buffer_uptodate(bh)); + + gfs_lock_buffer(bh); + + if (gfs_assert_warn(sdp, bd->bd_pinned)) { + gfs_unlock_buffer(bh); + return; + } + + /* No other (later) transaction is modifying buffer; ready to write */ + if (bd->bd_pinned == 1) + mark_buffer_dirty(bh); + + bd->bd_pinned--; + + gfs_unlock_buffer(bh); + + if (tr) { + spin_lock(&sdp->sd_ail_lock); + + if (list_empty(&bd->bd_ail_tr_list)) { + /* Buffer not attached to any earlier transaction. Add + it to glock's AIL, and this trans' AIL (below). */ + list_add(&bd->bd_ail_gl_list, &bd->bd_gl->gl_ail_bufs); + } else { + /* Was part of earlier transaction. + Move from that trans' AIL to this newer one's AIL. + Buf is already on glock's AIL. */ + list_del_init(&bd->bd_ail_tr_list); + brelse(bh); + } + list_add(&bd->bd_ail_tr_list, &tr->tr_ail_bufs); + + spin_unlock(&sdp->sd_ail_lock); + } else + brelse(bh); +} + +/** + * logbh_end_io - Called by OS at the end of a logbh ("fake" bh) write to log + * @bh: the buffer + * @uptodate: whether or not the write succeeded + * + * Interrupt context, no ENTER/RETURN + * + */ + +static void +logbh_end_io(struct buffer_head *bh, int uptodate) +{ + if (uptodate) + set_buffer_uptodate(bh); + else + clear_buffer_uptodate(bh); + unlock_buffer(bh); +} + +/** + * gfs_logbh_init - Initialize a fake buffer head + * @sdp: the filesystem + * @bh: the buffer to initialize + * @blkno: the block address of the buffer + * @data: the data to be written + * + */ + +void +gfs_logbh_init(struct gfs_sbd *sdp, struct buffer_head *bh, + uint64_t blkno, char *data) +{ + memset(bh, 0, sizeof(struct buffer_head)); + bh->b_state = (1 << BH_Mapped) | (1 << BH_Uptodate) | (1 << BH_Lock); + atomic_set(&bh->b_count, 1); + set_bh_page(bh, virt_to_page(data), ((unsigned long)data) & (PAGE_SIZE - 1)); + bh->b_blocknr = blkno; + bh->b_size = sdp->sd_sb.sb_bsize; + bh->b_bdev = sdp->sd_vfs->s_bdev; + init_buffer(bh, logbh_end_io, NULL); + INIT_LIST_HEAD(&bh->b_assoc_buffers); +} + +/** + * gfs_logbh_uninit - Clean up a fake buffer head + * @sdp: the filesystem + * @bh: the buffer to clean + * + */ + +void +gfs_logbh_uninit(struct gfs_sbd *sdp, struct buffer_head *bh) +{ + gfs_assert_warn(sdp, test_bit(SDF_SHUTDOWN, &sdp->sd_flags) || + !buffer_busy(bh)); + gfs_assert_warn(sdp, atomic_read(&bh->b_count) == 1); +} + +/** + * gfs_logbh_start - Start writing a fake buffer head + * @sdp: the filesystem + * @bh: the buffer to write + * + * This starts a block write to our journal. + */ + +void +gfs_logbh_start(struct gfs_sbd *sdp, struct buffer_head *bh) +{ + submit_bh(WRITE, bh); +} + +/** + * gfs_logbh_wait - Wait for the write of a fake buffer head to complete + * @sdp: the filesystem + * @bh: the buffer to write + * + * This waits for a block write to our journal to complete. + * + * Returns: errno + */ + +int +gfs_logbh_wait(struct gfs_sbd *sdp, struct buffer_head *bh) +{ + wait_on_buffer(bh); + + if (!buffer_uptodate(bh) || buffer_dirty(bh)) { + gfs_io_error_bh(sdp, bh); + return -EIO; + } + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + return -EIO; + + return 0; +} + +/** + * gfs_replay_buf - write a log buffer to its inplace location + * @gl: the journal's glock + * @bh: the buffer + * + * Returns: errno + */ + +int +gfs_replay_buf(struct gfs_glock *gl, struct buffer_head *bh) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_bufdata *bd; + + bd = get_v2bd(bh); + if (!bd) { + gfs_attach_bufdata(bh, gl); + bd = get_v2bd(bh); + } + + mark_buffer_dirty(bh); + + if (list_empty(&bd->bd_ail_tr_list)) { + get_bh(bh); + list_add(&bd->bd_ail_tr_list, &sdp->sd_recovery_bufs); + } + + return 0; +} + +/** + * gfs_replay_check - Check up on journal replay + * @sdp: the filesystem + * + */ + +void +gfs_replay_check(struct gfs_sbd *sdp) +{ + struct buffer_head *bh; + struct gfs_bufdata *bd; + + while (!list_empty(&sdp->sd_recovery_bufs)) { + bd = list_entry(sdp->sd_recovery_bufs.prev, + struct gfs_bufdata, bd_ail_tr_list); + bh = bd->bd_bh; + + if (buffer_busy(bh)) { + list_move(&bd->bd_ail_tr_list, + &sdp->sd_recovery_bufs); + break; + } else { + list_del_init(&bd->bd_ail_tr_list); + if (!buffer_uptodate(bh)) + gfs_io_error_bh(sdp, bh); + brelse(bh); + } + } +} + +/** + * gfs_replay_wait - Wait for all replayed buffers to hit the disk + * @sdp: the filesystem + * + */ + +void +gfs_replay_wait(struct gfs_sbd *sdp) +{ + struct list_head *head, *tmp, *prev; + struct buffer_head *bh; + struct gfs_bufdata *bd; + + for (head = &sdp->sd_recovery_bufs, tmp = head->prev, prev = tmp->prev; + tmp != head; + tmp = prev, prev = tmp->prev) { + bd = list_entry(tmp, struct gfs_bufdata, bd_ail_tr_list); + bh = bd->bd_bh; + + if (!buffer_busy(bh)) { + list_del_init(&bd->bd_ail_tr_list); + if (!buffer_uptodate(bh)) + gfs_io_error_bh(sdp, bh); + brelse(bh); + continue; + } + + if (buffer_dirty(bh)) { + wait_on_buffer(bh); + ll_rw_block(WRITE, 1, &bh); + } + } + + while (!list_empty(head)) { + bd = list_entry(head->prev, struct gfs_bufdata, bd_ail_tr_list); + bh = bd->bd_bh; + + wait_on_buffer(bh); + + gfs_assert_withdraw(sdp, !buffer_busy(bh)); + + list_del_init(&bd->bd_ail_tr_list); + if (!buffer_uptodate(bh)) + gfs_io_error_bh(sdp, bh); + brelse(bh); + } +} + +/** + * gfs_wipe_buffers - make inode's buffers so they aren't dirty/AILed anymore + * @ip: the inode who owns the buffers + * @rgd: the resource group + * @bstart: the first buffer in the run + * @blen: the number of buffers in the run + * + * Called when de-allocating a contiguous run of meta blocks within an rgrp. + * Make sure all buffers for de-alloc'd blocks are removed from the AIL, if + * they can be. Dirty or pinned blocks are left alone. Add relevant + * meta-headers to meta-header cache, so we don't need to read disk + * if we re-allocate blocks. + */ + +void +gfs_wipe_buffers(struct gfs_inode *ip, struct gfs_rgrpd *rgd, + uint64_t bstart, uint32_t blen) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct inode *aspace = ip->i_gl->gl_aspace; + struct buffer_head *bh; + struct gfs_bufdata *bd; + int busy; + int add = FALSE; + + while (blen) { + bh = getbuf(sdp, aspace, bstart, NO_CREATE); + if (bh) { + + bd = get_v2bd(bh); + + if (buffer_uptodate(bh)) { + if (bd) { + gfs_lock_buffer(bh); + gfs_mhc_add(rgd, &bh, 1); + busy = bd->bd_pinned || buffer_busy(bh); + gfs_unlock_buffer(bh); + + if (busy) + add = TRUE; + else { + spin_lock(&sdp->sd_ail_lock); + if (!list_empty(&bd->bd_ail_tr_list)) { + list_del_init(&bd->bd_ail_tr_list); + list_del(&bd->bd_ail_gl_list); + brelse(bh); + } + spin_unlock(&sdp->sd_ail_lock); + } + } else { + gfs_assert_withdraw(sdp, !buffer_dirty(bh)); + wait_on_buffer(bh); + gfs_assert_withdraw(sdp, !buffer_busy(bh)); + gfs_mhc_add(rgd, &bh, 1); + } + } else { + gfs_assert_withdraw(sdp, !bd || !bd->bd_pinned); + gfs_assert_withdraw(sdp, !buffer_dirty(bh)); + wait_on_buffer(bh); + gfs_assert_withdraw(sdp, !buffer_busy(bh)); + } + + brelse(bh); + } + + bstart++; + blen--; + } + + if (add) + gfs_depend_add(rgd, ip->i_num.no_formal_ino); +} + +/** + * gfs_sync_meta - sync all the buffers in a filesystem + * @sdp: the filesystem + * + * Flush metadata blocks to on-disk journal, then + * Flush metadata blocks (now in AIL) to on-disk in-place locations + * Periodically keep checking until done (AIL empty) + */ + +void +gfs_sync_meta(struct gfs_sbd *sdp) +{ + gfs_log_flush(sdp); + for (;;) { + gfs_ail_start(sdp, DIO_ALL); + if (gfs_ail_empty(sdp)) + break; + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ / 10); + } +} + +/** + * gfs_flush_meta_cache - get rid of any references on buffers for this inode + * @ip: The GFS inode + * + * This releases buffers that are in the most-recently-used array of + * blocks used for indirect block addressing for this inode. + * Don't confuse this with the meta-HEADER cache (mhc)! + */ + +void +gfs_flush_meta_cache(struct gfs_inode *ip) +{ + struct buffer_head **bh_slot; + unsigned int x; + + spin_lock(&ip->i_spin); + + for (x = 0; x < GFS_MAX_META_HEIGHT; x++) { + bh_slot = &ip->i_cache[x]; + if (*bh_slot) { + brelse(*bh_slot); + *bh_slot = NULL; + } + } + + spin_unlock(&ip->i_spin); +} + +/** + * gfs_get_meta_buffer - Get a metadata buffer + * @ip: The GFS inode + * @height: The level of this buf in the metadata (indir addr) tree (if any) + * @num: The block number (device relative) of the buffer + * @new: Non-zero if we may create a new buffer + * @bhp: the buffer is returned here + * + * Returns: errno + */ + +int +gfs_get_meta_buffer(struct gfs_inode *ip, int height, uint64_t num, int new, + struct buffer_head **bhp) +{ + struct buffer_head *bh, **bh_slot = &ip->i_cache[height]; + int flags = ((new) ? DIO_NEW : 0) | DIO_START | DIO_WAIT; + int error; + + /* Try to use the gfs_inode's MRU metadata tree cache */ + spin_lock(&ip->i_spin); + bh = *bh_slot; + if (bh) { + if (bh->b_blocknr == num) + get_bh(bh); + else + bh = NULL; + } + spin_unlock(&ip->i_spin); + + if (bh) { + error = gfs_dreread(ip->i_sbd, bh, flags); + if (error) { + brelse(bh); + return error; + } + } else { + error = gfs_dread(ip->i_gl, num, flags, &bh); + if (error) + return error; + + spin_lock(&ip->i_spin); + if (*bh_slot != bh) { + if (*bh_slot) + brelse(*bh_slot); + *bh_slot = bh; + get_bh(bh); + } + spin_unlock(&ip->i_spin); + } + + if (new) { + if (gfs_assert_warn(ip->i_sbd, height)) { + brelse(bh); + return -EIO; + } + gfs_trans_add_bh(ip->i_gl, bh); + gfs_metatype_set(bh, GFS_METATYPE_IN, GFS_FORMAT_IN); + gfs_buffer_clear_tail(bh, sizeof(struct gfs_meta_header)); + } else if (gfs_metatype_check(ip->i_sbd, bh, + (height) ? GFS_METATYPE_IN : GFS_METATYPE_DI)) { + brelse(bh); + return -EIO; + } + + *bhp = bh; + + return 0; +} + +/** + * gfs_get_data_buffer - Get a data buffer + * @ip: The GFS inode + * @num: The block number (device relative) of the data block + * @new: Non-zero if this is a new allocation + * @bhp: the buffer is returned here + * + * Returns: errno + */ + +int +gfs_get_data_buffer(struct gfs_inode *ip, uint64_t block, int new, + struct buffer_head **bhp) +{ + struct buffer_head *bh; + int error = 0; + + if (block == ip->i_num.no_addr) { + if (gfs_assert_warn(ip->i_sbd, !new)) + return -EIO; + error = gfs_dread(ip->i_gl, block, DIO_START | DIO_WAIT, &bh); + if (error) + return error; + if (gfs_metatype_check(ip->i_sbd, bh, GFS_METATYPE_DI)) { + brelse(bh); + return -EIO; + } + } else if (gfs_is_jdata(ip)) { + if (new) { + error = gfs_dread(ip->i_gl, block, + DIO_NEW | DIO_START | DIO_WAIT, &bh); + if (error) + return error; + gfs_trans_add_bh(ip->i_gl, bh); + gfs_metatype_set(bh, GFS_METATYPE_JD, GFS_FORMAT_JD); + gfs_buffer_clear_tail(bh, sizeof(struct gfs_meta_header)); + } else { + error = gfs_dread(ip->i_gl, block, + DIO_START | DIO_WAIT, &bh); + if (error) + return error; + if (gfs_metatype_check(ip->i_sbd, bh, GFS_METATYPE_JD)) { + brelse(bh); + return -EIO; + } + } + } else { + if (new) { + bh = gfs_dgetblk(ip->i_gl, block); + gfs_prep_new_buffer(bh); + } else { + error = gfs_dread(ip->i_gl, block, + DIO_START | DIO_WAIT, &bh); + if (error) + return error; + } + } + + *bhp = bh; + + return 0; +} + +/** + * gfs_start_ra - start readahead on an extent of a file + * @gl: the glock the blocks belong to + * @dblock: the starting disk block + * @extlen: the number of blocks in the extent + * + */ + +void +gfs_start_ra(struct gfs_glock *gl, uint64_t dblock, uint32_t extlen) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct inode *aspace = gl->gl_aspace; + struct buffer_head *first_bh, *bh; + uint32_t max_ra = gfs_tune_get(sdp, gt_max_readahead) >> sdp->sd_sb.sb_bsize_shift; + int error; + + if (!extlen) + return; + if (!max_ra) + return; + if (extlen > max_ra) + extlen = max_ra; + + first_bh = getbuf(sdp, aspace, dblock, CREATE); + + if (buffer_uptodate(first_bh)) + goto out; + if (!buffer_locked(first_bh)) { + error = gfs_dreread(sdp, first_bh, DIO_START); + if (error) + goto out; + } + + dblock++; + extlen--; + + while (extlen) { + bh = getbuf(sdp, aspace, dblock, CREATE); + + if (!buffer_uptodate(bh) && !buffer_locked(bh)) { + error = gfs_dreread(sdp, bh, DIO_START); + brelse(bh); + if (error) + goto out; + } else + brelse(bh); + + dblock++; + extlen--; + + if (buffer_uptodate(first_bh)) + break; + } + + out: + brelse(first_bh); +} --- linux-2.6.28.orig/ubuntu/gfs/acl.h +++ linux-2.6.28/ubuntu/gfs/acl.h @@ -0,0 +1,34 @@ +#ifndef __ACL_DOT_H__ +#define __ACL_DOT_H__ + +#define GFS_POSIX_ACL_ACCESS "posix_acl_access" +#define GFS_POSIX_ACL_ACCESS_LEN (16) +#define GFS_POSIX_ACL_DEFAULT "posix_acl_default" +#define GFS_POSIX_ACL_DEFAULT_LEN (17) + +#define GFS_ACL_IS_ACCESS(name, len) \ + ((len) == GFS_POSIX_ACL_ACCESS_LEN && \ + !memcmp(GFS_POSIX_ACL_ACCESS, (name), (len))) + +#define GFS_ACL_IS_DEFAULT(name, len) \ + ((len) == GFS_POSIX_ACL_DEFAULT_LEN && \ + !memcmp(GFS_POSIX_ACL_DEFAULT, (name), (len))) + +struct gfs_ea_request; + +int gfs_acl_validate_set(struct gfs_inode *ip, int access, + struct gfs_ea_request *er, + int *remove, mode_t *mode); +int gfs_acl_validate_remove(struct gfs_inode *ip, int access); +int gfs_acl_get(struct gfs_inode *ip, int access, struct posix_acl **acl); +int gfs_check_acl(struct inode *inode, int mask); +int gfs_acl_new_prep(struct gfs_inode *dip, + unsigned int type, mode_t *mode, + void **a_data, void **d_data, + unsigned int *size, + unsigned int *blocks); +int gfs_acl_new_init(struct gfs_inode *dip, struct gfs_inode *ip, + void *a_data, void *d_data, unsigned int size); +int gfs_acl_chmod(struct gfs_inode *ip, struct iattr *attr); + +#endif /* __ACL_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/eattr.h +++ linux-2.6.28/ubuntu/gfs/eattr.h @@ -0,0 +1,97 @@ +#ifndef __EATTR_DOT_H__ +#define __EATTR_DOT_H__ + +#define GFS_EA_REC_LEN(ea) gfs32_to_cpu((ea)->ea_rec_len) +#define GFS_EA_DATA_LEN(ea) gfs32_to_cpu((ea)->ea_data_len) + +#define GFS_EA_SIZE(ea) \ +MAKE_MULT8(sizeof(struct gfs_ea_header) + \ + (ea)->ea_name_len + \ + ((GFS_EA_IS_STUFFED(ea)) ? \ + GFS_EA_DATA_LEN(ea) : \ + (sizeof(uint64_t) * (ea)->ea_num_ptrs))) +#define GFS_EA_STRLEN(ea) \ +((((ea)->ea_type == GFS_EATYPE_USR) ? 5 : 7) + \ + (ea)->ea_name_len + 1) + +#define GFS_EA_IS_STUFFED(ea) (!(ea)->ea_num_ptrs) +#define GFS_EA_IS_LAST(ea) ((ea)->ea_flags & GFS_EAFLAG_LAST) + +#define GFS_EAREQ_SIZE_STUFFED(er) \ +MAKE_MULT8(sizeof(struct gfs_ea_header) + \ + (er)->er_name_len + (er)->er_data_len) +#define GFS_EAREQ_SIZE_UNSTUFFED(sdp, er) \ +MAKE_MULT8(sizeof(struct gfs_ea_header) + \ + (er)->er_name_len + \ + sizeof(uint64_t) * DIV_RU((er)->er_data_len, (sdp)->sd_jbsize)) + +#define GFS_EA2NAME(ea) ((char *)((struct gfs_ea_header *)(ea) + 1)) +#define GFS_EA2DATA(ea) (GFS_EA2NAME(ea) + (ea)->ea_name_len) +#define GFS_EA2DATAPTRS(ea) \ +((uint64_t *)(GFS_EA2NAME(ea) + MAKE_MULT8((ea)->ea_name_len))) +#define GFS_EA2NEXT(ea) \ +((struct gfs_ea_header *)((char *)(ea) + GFS_EA_REC_LEN(ea))) +#define GFS_EA_BH2FIRST(bh) \ +((struct gfs_ea_header *)((bh)->b_data + \ + sizeof(struct gfs_meta_header))) + +struct gfs_ea_request { + char *er_name; + char *er_data; + unsigned int er_name_len; + unsigned int er_data_len; + unsigned int er_type; /* GFS_EATYPE_... */ + int er_flags; + mode_t er_mode; +}; + +struct gfs_ea_location { + struct buffer_head *el_bh; + struct gfs_ea_header *el_ea; + struct gfs_ea_header *el_prev; +}; + +static inline unsigned int +gfs_ea_strlen(struct gfs_ea_header *ea) +{ + switch (ea->ea_type) { + case GFS_EATYPE_USR: + return (5 + (ea->ea_name_len + 1)); + case GFS_EATYPE_SYS: + return (7 + (ea->ea_name_len + 1)); + case GFS_EATYPE_SECURITY: + return (9 + (ea->ea_name_len + 1)); + default: + return (0); + } +} + +int gfs_ea_repack(struct gfs_inode *ip); + +int gfs_ea_get_i(struct gfs_inode *ip, struct gfs_ea_request *er); +int gfs_ea_set_i(struct gfs_inode *ip, struct gfs_ea_request *er); +int gfs_ea_remove_i(struct gfs_inode *ip, struct gfs_ea_request *er); + +int gfs_ea_list(struct gfs_inode *ip, struct gfs_ea_request *er); +int gfs_ea_get(struct gfs_inode *ip, struct gfs_ea_request *er); +int gfs_ea_set(struct gfs_inode *ip, struct gfs_ea_request *er); +int gfs_ea_remove(struct gfs_inode *ip, struct gfs_ea_request *er); + +int gfs_ea_dealloc(struct gfs_inode *ip); + +int gfs_get_eattr_meta(struct gfs_inode *ip, struct gfs_user_buffer *ub); + +/* Exported to acl.c */ + +int gfs_ea_check_size(struct gfs_sbd *sdp, struct gfs_ea_request *er); +int gfs_ea_find(struct gfs_inode *ip, + struct gfs_ea_request *er, + struct gfs_ea_location *el); +int gfs_ea_get_copy(struct gfs_inode *ip, + struct gfs_ea_location *el, + char *data); +int gfs_ea_acl_init(struct gfs_inode *ip, struct gfs_ea_request *er); +int gfs_ea_acl_chmod(struct gfs_inode *ip, struct gfs_ea_location *el, + struct iattr *attr, char *data); + +#endif /* __EATTR_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/eaops.c +++ linux-2.6.28/ubuntu/gfs/eaops.c @@ -0,0 +1,173 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "acl.h" +#include "eaops.h" +#include "eattr.h" + +/** + * gfs_ea_name2type - get the type of the ea, and trucate the type from the name + * @namep: ea name, possibly with type appended + * + * Returns: GFS_EATYPE_XXX + */ + +unsigned int +gfs_ea_name2type(const char *name, char **truncated_name) +{ + unsigned int type; + + if (strncmp(name, "system.", 7) == 0) { + type = GFS_EATYPE_SYS; + if (truncated_name) + *truncated_name = strchr(name, '.') + 1; + } else if (strncmp(name, "user.", 5) == 0) { + type = GFS_EATYPE_USR; + if (truncated_name) + *truncated_name = strchr(name, '.') + 1; + } else if (strncmp(name, "security.", 9) == 0) { + type = GFS_EATYPE_SECURITY; + if (truncated_name) + *truncated_name = strchr(name, '.') + 1; + } else { + type = GFS_EATYPE_UNUSED; + if (truncated_name) + *truncated_name = NULL; + } + + return type; +} + +/** + * system_eo_get - + * @ip: + * @er: + * + * Returns: errno + */ + +static int +system_eo_get(struct gfs_inode *ip, struct gfs_ea_request *er) +{ + if (!GFS_ACL_IS_ACCESS(er->er_name, er->er_name_len) && + !GFS_ACL_IS_DEFAULT(er->er_name, er->er_name_len) && + !capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (ip->i_sbd->sd_args.ar_posix_acls == FALSE && + (GFS_ACL_IS_ACCESS(er->er_name, er->er_name_len) || + GFS_ACL_IS_DEFAULT(er->er_name, er->er_name_len))) + return -EOPNOTSUPP; + + return gfs_ea_get_i(ip, er); +} + +/** + * system_eo_set - + * @ip: + * @er: + * + * Returns: errno + */ + +static int +system_eo_set(struct gfs_inode *ip, struct gfs_ea_request *er) +{ + int remove = FALSE; + int error; + + if (GFS_ACL_IS_ACCESS(er->er_name, er->er_name_len)) { + er->er_mode = ip->i_vnode->i_mode; + error = gfs_acl_validate_set(ip, TRUE, er, + &remove, &er->er_mode); + if (error) + return error; + error = gfs_ea_set_i(ip, er); + if (error) + return error; + if (remove) + gfs_ea_remove_i(ip, er); + return 0; + + } else if (GFS_ACL_IS_DEFAULT(er->er_name, er->er_name_len)) { + int error = gfs_acl_validate_set(ip, FALSE, er, + &remove, NULL); + if (error) + return error; + if (!remove) + error = gfs_ea_set_i(ip, er); + else { + error = gfs_ea_remove_i(ip, er); + if (error == -ENODATA) + error = 0; + } + return error; + } + + return -EPERM; +} + +/** + * system_eo_remove - + * @ip: + * @er: + * + * Returns: errno + */ + +static int +system_eo_remove(struct gfs_inode *ip, struct gfs_ea_request *er) +{ + if (GFS_ACL_IS_ACCESS(er->er_name, er->er_name_len)) { + int error = gfs_acl_validate_remove(ip, TRUE); + if (error) + return error; + + } else if (GFS_ACL_IS_DEFAULT(er->er_name, er->er_name_len)) { + int error = gfs_acl_validate_remove(ip, FALSE); + if (error) + return error; + + } else + return -EPERM; + + return gfs_ea_remove_i(ip, er); +} + +struct gfs_eattr_operations gfs_user_eaops = { + .eo_get = gfs_ea_get_i, + .eo_set = gfs_ea_set_i, + .eo_remove = gfs_ea_remove_i, + .eo_name = "user", +}; + +struct gfs_eattr_operations gfs_system_eaops = { + .eo_get = system_eo_get, + .eo_set = system_eo_set, + .eo_remove = system_eo_remove, + .eo_name = "system", +}; + +struct gfs_eattr_operations gfs_security_eaops = { + .eo_get = gfs_ea_get_i, + .eo_set = gfs_ea_set_i, + .eo_remove = gfs_ea_remove_i, + .eo_name = "security", +}; + +struct gfs_eattr_operations *gfs_ea_ops[] = { + NULL, + &gfs_user_eaops, + &gfs_system_eaops, + &gfs_security_eaops, +}; + --- linux-2.6.28.orig/ubuntu/gfs/gfs_ondisk.h +++ linux-2.6.28/ubuntu/gfs/gfs_ondisk.h @@ -0,0 +1,1904 @@ +/* + * On-disk structures. + * + * THE BIG PICTURE of on-disk layout: + * + * GFS filesystem code views the entire filesystem, including journals, as + * one contiguous group of blocks on one (perhaps virtual) storage device. + * The filesystem space is shared, not distributed; each node in the cluster + * must see the entire filesystem space. + * + * If the filesystem is spread across multiple physical storage devices, + * volume management (device mapping) must be used to present the fileystem + * space to GFS as one (virtual) device, with contiguous blocks. + * + * The superblock contains basic information about the filesytem, and appears + * at a location 64 KBytes into the filesystem. The first 64 KBytes of the + * filesystem are empty, providing a safety buffer against wayward volume + * management software (that sometimes write data into the first few bytes of + * a device) or administrators. + * + * After the superblock, the rest of the filesystem is divided into multiple + * Resource Groups and several journals. + * + * The Resource Groups (RGs or rgrps) contain the allocatable blocks that are + * used for storing files, directories, etc., and all of the associated + * metadata. Each RG has its own set of block allocation statistics (within + * the RG header), a number of blocks containing the block allocation bitmap, + * and a large number of allocatable blocks for file data and metadata. + * Multiple RGs allow multiple nodes to simultaneously allocate blocks from the + * filesystem (using different RGs), enhancing parallel access. RG size and + * number of RGs are determined by gfs_mkfs when creating the filesystem. + * An administrator can specify RG size (see man gfs_mkfs). + * + * The journals contain temporary copies of metadata blocks, along with + * other data, that allow GFS to recover the filesystem to a consistent state + * (at least as far as metadata is concerned) if a node fails in the midst + * of performing a write transaction. There must be one journal for each node + * in the cluster. Since access to the entire filesystem space is shared, + * if a node crashes, another node will be able to read the crashed node's + * journal, and perform recovery. + * + * Currently, gfs_mkfs places the journals right in the middle of a freshly + * created filesystem space, between 2 large groups of RGs. From a filesystem + * layout perspective, this placement is not a requirement; the journals + * could be placed anywhere within the filesystem space. + * + * New Resource Groups and Journals may be added to the filesystem after the + * filesystem has been created, if the filesystem's (virtual) device is made + * larger. See man gfs_grow and gfs_jadd. + * + * A few special hidden inodes are contained in a GFS filesystem. They do + * not appear in any directories; instead, the superblock points to them + * using block numbers for their location. The special inodes are: + * + * Root inode: Root directory of the filesystem + * Resource Group Index: A file containing block numbers and sizes of all RGs + * Journal Index: A file containing block numbers and sizes of all journals + * Quota: A file containing all quota information for the filesystem + * License: A file containing license information + * + * Note that there is NOTHING RELATED TO INTER-NODE LOCK MANAGEMENT ON-DISK. + * Locking is handled completely off-disk, typically via LAN. + * + * NOTE: + * If you add 8 byte fields to these structures, they must be 8 byte + * aligned. 4 byte field must be 4 byte aligned, etc... + * + * All structures must be a multiple of 8 bytes long. + * + * GRIPES: + * We should have forgetten about supporting 512B FS block sizes + * and made the di_reserved field in the struct gfs_dinode structure + * much bigger. + * + * de_rec_len in struct gfs_dirent should really have been a 32-bit value + * as it now limits us to a 64k FS block size (with the current code + * in dir.c). + */ + +#ifndef __GFS_ONDISK_DOT_H__ +#define __GFS_ONDISK_DOT_H__ + +#define GFS_MAGIC (0x01161970) /* for all on-disk headers */ +#define GFS_BASIC_BLOCK (512) /* "basic block" = "sector" = 512B */ +#define GFS_BASIC_BLOCK_SHIFT (9) + +/* Controls how much data can be logged in-core before dumping log to disk */ + +#define GFS_DUMPS_PER_LOG (4) /* 1/4 of on-disk journal size*/ + +/* Lock numbers of the LM_TYPE_NONDISK type. These protect certain + * cluster-wide operations (rather than on-disk entities). + * Currently, the LIVE lock is not used for any real purpose. */ + +#define GFS_MOUNT_LOCK (0) /* only one node can Mount at a time */ +#define GFS_LIVE_LOCK (1) /* shared by all mounted nodes */ +#define GFS_TRANS_LOCK (2) /* Transaction, protects jrnl recovery */ +#define GFS_RENAME_LOCK (3) /* only one node can Rename at a time */ + +/* On-disk format (version) numbers for various metadata types, + * used in gfs_meta_header */ + +#define GFS_FORMAT_SB (100) /* Super-Block */ +#define GFS_FORMAT_RG (200) /* Resource Group Header */ +#define GFS_FORMAT_RB (300) /* Resource Group Block Alloc BitBlock */ +#define GFS_FORMAT_DI (400) /* "Disk" inode (dinode) */ +#define GFS_FORMAT_IN (500) /* Indirect dinode block list */ +#define GFS_FORMAT_LF (600) /* Leaf dinode block list */ +#define GFS_FORMAT_JD (700) /* Journal Data */ +#define GFS_FORMAT_LH (800) /* Log Header */ +#define GFS_FORMAT_LD (900) /* Log Descriptor */ +/* These don't have actual struct gfs_meta_header structures to go with them */ +#define GFS_FORMAT_JI (1000) /* Journal Index */ +#define GFS_FORMAT_RI (1100) /* Resource Group Index */ +#define GFS_FORMAT_DE (1200) /* Directory Entry */ +#define GFS_FORMAT_QU (1500) /* Quota */ +#define GFS_FORMAT_EA (1600) /* Extended Attribute */ +#define GFS_FORMAT_ED (1700) /* Extended Attribute data */ +/* These version #s are embedded in the superblock */ +#define GFS_FORMAT_FS (1309) /* Filesystem (all-encompassing) */ +#define GFS_FORMAT_MULTI (1401) /* Multi-Host */ + +/* + * An on-disk inode number + * Initially, the on-disk block address of the inode block is assigned as the + * formal (permanent) ID as well. Block address can change (to move inode + * on-disk), but formal ID must stay unchanged once assigned. + */ + +#define gfs_inum_equal(ino1, ino2) \ +(((ino1)->no_formal_ino == (ino2)->no_formal_ino) && \ + ((ino1)->no_addr == (ino2)->no_addr)) + +struct gfs_inum { + uint64_t no_formal_ino; /* inode identifier */ + uint64_t no_addr; /* block # of dinode block */ +}; + +/* + * Generic metadata head structure + * + * Every inplace buffer logged in the journal must start + * with a struct gfs_meta_header. + * + * In addition to telling what kind of metadata is in the block, + * the metaheader contains the important generation and incarnation + * numbers. + * + * The generation number is used during journal recovery to determine + * whether an in-place block on-disk is older than an on-disk journaled copy + * of the block. If so, GFS overwrites the in-place block with the journaled + * version of the block. + * + * A meta block's generation number must increment monotonically across the + * cluster, each time new contents are committed to the block. This means + * that whenever GFS allocates a pre-existing metadata block, GFS must read + * that block from disk (in case another node has incremented it). It also + * means that GFS must sync the block (with incremented generation number) + * to disk (both log and in-place blocks), not only after changing contents + * of the block, but also after de-allocating the block (GFS can't just throw + * away incore metadata for a file that it's just erased). + * + * The incarnation number is used only for on-disk (d)inodes. GFS increments + * it each time it de-allocates a dinode block (i.e. each time the dinode + * loses its identity with a particular file, directory, etc.). When the + * dinode is later allocated (i.e. to be identified with a new file, etc.), + * GFS copies the incarnation number into the VFS inode's i_generation member. + * If GFS is used as the backing store for an NFS server, GFS uses this + * i_generation number as part of the NFS filehandle, which differentiates + * it from the previous identity of the dinode, and helps protect against + * filesystem corruption that could happen with the use of outdated, + * invalid, or malicious filehandles. See ops_export.c. + * + * GFS caches de-allocated meta-headers, to minimize disk reads. + * See struct gfs_meta_header_cache. + */ + +#define GFS_METATYPE_NONE (0) +#define GFS_METATYPE_SB (1) /* Super-Block */ +#define GFS_METATYPE_RG (2) /* Resource Group Header */ +#define GFS_METATYPE_RB (3) /* Resource Group Block Alloc BitBlock */ +#define GFS_METATYPE_DI (4) /* "Disk" inode (dinode) */ +#define GFS_METATYPE_IN (5) /* Indirect dinode block list */ +#define GFS_METATYPE_LF (6) /* Leaf dinode block list */ +#define GFS_METATYPE_JD (7) /* Journal Data */ +#define GFS_METATYPE_LH (8) /* Log Header (gfs_log_header) */ +#define GFS_METATYPE_LD (9) /* Log Descriptor (gfs_log_descriptor) */ +#define GFS_METATYPE_EA (10) /* Extended Attribute */ +#define GFS_METATYPE_ED (11) /* Extended Attribute data */ + +#define GFS_META_CLUMP (64) /* # blocks to convert fm data to meta */ + +struct gfs_meta_header { + uint32_t mh_magic; /* GFS_MAGIC sanity check magic number */ + uint32_t mh_type; /* GFS_METATYPE_XX type of metadata block */ + uint64_t mh_generation; /* increment before writing to journal */ + uint32_t mh_format; /* GFS_FORMAT_XX (version # for this type) */ + uint32_t mh_incarn; /* increment when marking dinode "unused" */ +}; + +/* + * super-block structure + * + * One of these is at beginning of filesystem. + * It's probably good if SIZEOF_SB <= GFS_BASIC_BLOCK (512 bytes) + */ + +/* Address of SuperBlock in GFS basic blocks. 1st 64K of filesystem is empty + for safety against getting clobbered by wayward volume managers, etc. + 64k was chosen because it's the largest GFS-supported fs block size. */ +#define GFS_SB_ADDR (128) + +/* The lock number for the superblock (must be zero) */ +#define GFS_SB_LOCK (0) +#define GFS_CRAP_LOCK (1) + +/* Requirement: GFS_LOCKNAME_LEN % 8 == 0 + Includes: the fencing zero at the end */ +#define GFS_LOCKNAME_LEN (64) + +struct gfs_sb { + /* Order is important; need to be able to read old superblocks + in order to support on-disk version upgrades */ + struct gfs_meta_header sb_header; + + uint32_t sb_fs_format; /* GFS_FORMAT_FS (on-disk version) */ + uint32_t sb_multihost_format; /* GFS_FORMAT_MULTI */ + uint32_t sb_flags; /* ?? */ + + uint32_t sb_bsize; /* fundamental FS block size in bytes */ + uint32_t sb_bsize_shift; /* log2(sb_bsize) */ + uint32_t sb_seg_size; /* Journal segment size in FS blocks */ + + /* These special inodes do not appear in any on-disk directory. */ + struct gfs_inum sb_jindex_di; /* journal index inode */ + struct gfs_inum sb_rindex_di; /* resource group index inode */ + struct gfs_inum sb_root_di; /* root directory inode */ + + /* Default inter-node locking protocol (lock module) and namespace */ + char sb_lockproto[GFS_LOCKNAME_LEN]; /* lock protocol name */ + char sb_locktable[GFS_LOCKNAME_LEN]; /* unique name for this FS */ + + /* More special inodes */ + struct gfs_inum sb_quota_di; /* quota inode */ + struct gfs_inum sb_license_di; /* license inode */ + + char sb_reserved[96]; +}; + +/* + * journal index structure + * + * One for each journal used by the filesystem. + * These descriptors are packed contiguously within the jindex inode (file). + */ + +struct gfs_jindex { + uint64_t ji_addr; /* starting block of the journal */ + uint32_t ji_nsegment; /* number (quantity) of segments in journal */ + uint32_t ji_pad; + + char ji_reserved[64]; +}; + +/* + * resource index structure + * + * One of these for each resource group in the filesystem. + * These descriptors are packed contiguously within the rindex inode (file). + * Also see struct gfs_rgrp. + */ + +struct gfs_rindex { + uint64_t ri_addr; /* block # of 1st block (header) in rgrp */ + uint32_t ri_length; /* # fs blocks containing rgrp header & bitmap */ + uint32_t ri_pad; + + uint64_t ri_data1; /* block # of first data/meta block in rgrp */ + uint32_t ri_data; /* number (qty) of data/meta blocks in rgrp */ + + uint32_t ri_bitbytes; /* total # bytes used by block alloc bitmap */ + + char ri_reserved[64]; +}; + +/* + * resource group header structure + * + * One of these at beginning of the first block of an rgrp, + * followed by block alloc bitmap data in remainder of first block. + * Each resource group contains: + * Header block, including block allocation statistics (struct gfs_rgrp) + * and first part of block alloc bitmap. + * Bitmap block(s), continuing block alloc bitmap started in header block. + * Data/meta blocks, allocatable blocks containing file data and metadata. + * + * In older versions, now-unused (but previously allocated) dinodes were + * saved for re-use in an on-disk linked list (chain). This is no longer + * done, but support still exists for reclaiming dinodes from this list, + * to support upgrades from older on-disk formats. + */ + +/* Each data block within rgrp is represented by 2 bits in the alloc bitmap */ +#define GFS_NBBY (4) /* # blocks represented by 1 bitmap byte */ +#define GFS_BIT_SIZE (2) +#define GFS_BIT_MASK (0x00000003) + +/* + * 4 possible block allocation states: + * bit 0 = alloc(1)/free(0) + * bit 1 = metadata(1)/data(0) + */ +#define GFS_BLKST_FREE (0) +#define GFS_BLKST_USED (1) +#define GFS_BLKST_FREEMETA (2) +#define GFS_BLKST_USEDMETA (3) + +struct gfs_rgrp { + struct gfs_meta_header rg_header; + + uint32_t rg_flags; /* ?? */ + + uint32_t rg_free; /* Number (qty) of free data blocks */ + + /* Dinodes are USEDMETA, but are handled separately from other METAs */ + uint32_t rg_useddi; /* Number (qty) of dinodes (used or free) */ + uint32_t rg_freedi; /* Number (qty) of unused (free) dinodes */ + struct gfs_inum rg_freedi_list; /* 1st block in chain of free dinodes */ + + /* These META statistics do not include dinodes (used or free) */ + uint32_t rg_usedmeta; /* Number (qty) of used metadata blocks */ + uint32_t rg_freemeta; /* Number (qty) of unused metadata blocks */ + + char rg_reserved[64]; +}; + +/* + * quota structure + */ + +struct gfs_quota { + uint64_t qu_limit; + uint64_t qu_warn; + int64_t qu_value; + + char qu_reserved[64]; +}; + +/* + * dinode (disk inode) structure + * The ondisk representation of inodes + * One for each file, directory, etc. + * GFS does not put more than one inode in a single block. + * The inode may be "stuffed", carrying file data along with metadata, + * if the file data is small enough. + * Otherwise, the inode block contains pointers to other blocks that contain + * either file data or other pointers to other blocks (indirect addressing + * via a metadata tree). + */ + +#define GFS_MAX_META_HEIGHT (10) +#define GFS_DIR_MAX_DEPTH (17) + +/* Dinode types */ +#define GFS_FILE_NON (0) +#define GFS_FILE_REG (1) /* regular file */ +#define GFS_FILE_DIR (2) /* directory */ +#define GFS_FILE_LNK (5) /* link */ +#define GFS_FILE_BLK (7) /* block device node */ +#define GFS_FILE_CHR (8) /* character device node */ +#define GFS_FILE_FIFO (101) /* fifo/pipe */ +#define GFS_FILE_SOCK (102) /* socket */ + +/* Dinode flags */ +#define GFS_DIF_JDATA (0x00000001) /* jrnl all data for this file */ +#define GFS_DIF_EXHASH (0x00000002) /* hashed directory (leaves) */ +#define GFS_DIF_UNUSED (0x00000004) /* unused dinode */ +#define GFS_DIF_EA_INDIRECT (0x00000008) /* extended attribute, indirect*/ +#define GFS_DIF_DIRECTIO (0x00000010) +#define GFS_DIF_IMMUTABLE (0x00000020) /* Can't change file */ +#define GFS_DIF_APPENDONLY (0x00000040) /* Can only add to end of file */ +#define GFS_DIF_NOATIME (0x00000080) /* Don't update access time + (currently unused/ignored) */ +#define GFS_DIF_SYNC (0x00000100) /* Flush to disk, don't cache + (currently unused/ignored) */ +#define GFS_DIF_INHERIT_DIRECTIO (0x40000000) /* new files get DIRECTIO flag */ +#define GFS_DIF_INHERIT_JDATA (0x80000000) /* new files get JDATA flag */ + +struct gfs_dinode { + struct gfs_meta_header di_header; + + struct gfs_inum di_num; /* formal inode # and block address */ + + uint32_t di_mode; /* mode of file */ + uint32_t di_uid; /* owner's user id */ + uint32_t di_gid; /* owner's group id */ + uint32_t di_nlink; /* number (qty) of links to this file */ + uint64_t di_size; /* number (qty) of bytes in file */ + uint64_t di_blocks; /* number (qty) of blocks in file */ + int64_t di_atime; /* time last accessed */ + int64_t di_mtime; /* time last modified */ + int64_t di_ctime; /* time last changed */ + + /* Non-zero only for character or block device nodes */ + uint32_t di_major; /* device major number */ + uint32_t di_minor; /* device minor number */ + + /* Block allocation strategy */ + uint64_t di_rgrp; /* dinode rgrp block number */ + uint64_t di_goal_rgrp; /* rgrp to alloc from next */ + uint32_t di_goal_dblk; /* data block goal */ + uint32_t di_goal_mblk; /* metadata block goal */ + + uint32_t di_flags; /* GFS_DIF_... */ + + /* struct gfs_rindex, struct gfs_jindex, or struct gfs_dirent */ + uint32_t di_payload_format; /* GFS_FORMAT_... */ + uint16_t di_type; /* GFS_FILE_... type of file */ + uint16_t di_height; /* height of metadata (0 == stuffed) */ + uint32_t di_incarn; /* incarnation (unused, see gfs_meta_header) */ + uint16_t di_pad; + + /* These only apply to directories */ + uint16_t di_depth; /* Number of bits in the table */ + uint32_t di_entries; /* The # (qty) of entries in the directory */ + + /* This formed an on-disk chain of unused dinodes */ + struct gfs_inum di_next_unused; /* used in old versions only */ + + uint64_t di_eattr; /* extended attribute block number */ + + char di_reserved[56]; +}; + +/* + * indirect block header + * + * A component of a dinode's indirect addressing metadata tree. + * These are pointed to by pointers in dinodes or other indirect blocks. + */ + +struct gfs_indirect { + struct gfs_meta_header in_header; + + char in_reserved[64]; +}; + +/* + * directory structure - many of these per directory file + * + * See comments at beginning of dir.c + */ + +#define GFS_FNAMESIZE (255) +#define GFS_DIRENT_SIZE(name_len) ((sizeof(struct gfs_dirent) + (name_len) + 7) & ~7) +#define IS_LEAF (1) /* Hashed (leaf) directory */ +#define IS_DINODE (2) /* Linear (stuffed dinode block) directory */ + +struct gfs_dirent { + struct gfs_inum de_inum; /* formal inode number and block address */ + uint32_t de_hash; /* hash of the filename */ + uint16_t de_rec_len; /* the length of the dirent */ + uint16_t de_name_len; /* the length of the name */ + uint16_t de_type; /* GFS_FILE_... type of dinode this points to */ + + char de_reserved[14]; +}; + +/* + * Header of leaf directory nodes + * + * See comments at beginning of dir.c + */ + +struct gfs_leaf { + struct gfs_meta_header lf_header; + + uint16_t lf_depth; /* Depth of leaf */ + uint16_t lf_entries; /* Number of dirents in leaf */ + uint32_t lf_dirent_format; /* GFS_FORMAT_DE (version #) */ + uint64_t lf_next; /* Next leaf, if overflow */ + + char lf_reserved[64]; +}; + +/* + * Log header structure + * + * Two of these are in the first block of a transaction log: + * 1) at beginning of block + * 2) at end of first 512-byte sector within block + */ + +#define GFS_LOG_HEAD_UNMOUNT (0x00000001) /* log is clean, can unmount fs */ + +struct gfs_log_header { + struct gfs_meta_header lh_header; + + uint32_t lh_flags; /* GFS_LOG_HEAD_... */ + uint32_t lh_pad; + + uint64_t lh_first; /* Block number of first header in this trans */ + uint64_t lh_sequence; /* Sequence number of this transaction */ + + uint64_t lh_tail; /* Block number of log tail */ + uint64_t lh_last_dump; /* Block number of last dump */ + + char lh_reserved[64]; +}; + +/* + * Log type descriptor + * + * One of these for each chunk in a transaction + */ + +#define GFS_LOG_DESC_METADATA (300) /* metadata */ +/* ld_data1 is the number (quantity) of metadata blocks in the descriptor. + ld_data2 is unused. + */ + +#define GFS_LOG_DESC_IUL (400) /* unlinked inode */ +/* ld_data1 is TRUE if this is a dump. + ld_data2 is unused. + FixMe!!! ld_data1 should be the number (quantity) of entries. + ld_data2 should be "TRUE if this is a dump". + */ + +#define GFS_LOG_DESC_IDA (401) /* de-allocated inode */ +/* ld_data1 is unused. + ld_data2 is unused. + FixMe!!! ld_data1 should be the number (quantity) of entries. + */ + +#define GFS_LOG_DESC_Q (402) /* quota */ +/* ld_data1 is the number of quota changes in the descriptor. + ld_data2 is TRUE if this is a dump. + */ + +#define GFS_LOG_DESC_LAST (500) /* final in a logged transaction */ +/* ld_data1 is unused. + ld_data2 is unused. + */ + +struct gfs_log_descriptor { + struct gfs_meta_header ld_header; + + uint32_t ld_type; /* GFS_LOG_DESC_... Type of this log chunk */ + uint32_t ld_length; /* Number of buffers in this chunk */ + uint32_t ld_data1; /* descriptor-specific field */ + uint32_t ld_data2; /* descriptor-specific field */ + + char ld_reserved[64]; +}; + +/* + * Metadata block tags + * + * One for each logged block. Tells where block really belongs on-disk. + * These descriptor tags are packed contiguously after a gfs_log_descriptor. + */ + +struct gfs_block_tag { + uint64_t bt_blkno; /* inplace block number */ + uint32_t bt_flags; /* ?? */ + uint32_t bt_pad; +}; + +/* + * Quota Journal Tag + */ + +#define GFS_QTF_USER (0x00000001) + +struct gfs_quota_tag { + int64_t qt_change; + uint32_t qt_flags; /* GFS_QTF_... */ + uint32_t qt_id; +}; + +/* + * Extended attribute header format + */ + +#define GFS_EA_MAX_NAME_LEN (255) +#define GFS_EA_MAX_DATA_LEN (65536) + +#define GFS_EATYPE_UNUSED (0) +#define GFS_EATYPE_USR (1) /* user attribute */ +#define GFS_EATYPE_SYS (2) /* system attribute */ +#define GFS_EATYPE_SECURITY (3) /* security attribute */ + +#define GFS_EATYPE_LAST (3) +#define GFS_EATYPE_VALID(x) ((x) <= GFS_EATYPE_LAST) + +#define GFS_EAFLAG_LAST (0x01) /* last ea in block */ + +struct gfs_ea_header { + uint32_t ea_rec_len; /* total record length: hdr + name + data */ + uint32_t ea_data_len; /* data length, in bytes */ + uint8_t ea_name_len; /* no NULL pointer after the string */ + uint8_t ea_type; /* GFS_EATYPE_... */ + uint8_t ea_flags; /* GFS_EAFLAG_... */ + uint8_t ea_num_ptrs; /* # fs blocks needed for EA */ + uint32_t ea_pad; +}; + +/* + * Statfs change + * Describes an change to the pool of free and allocated + * blocks. + */ + +struct gfs_statfs_change { + uint64_t sc_total; + uint64_t sc_free; + uint64_t sc_dinodes; +}; + +struct gfs_statfs_change_host { + int64_t sc_total; + int64_t sc_free; + int64_t sc_dinodes; +}; + +/* Endian functions */ + +#define GFS_ENDIAN_BIG + +#ifdef GFS_ENDIAN_BIG + +#define gfs16_to_cpu be16_to_cpu +#define gfs32_to_cpu be32_to_cpu +#define gfs64_to_cpu be64_to_cpu + +#define cpu_to_gfs16 cpu_to_be16 +#define cpu_to_gfs32 cpu_to_be32 +#define cpu_to_gfs64 cpu_to_be64 + +#else /* GFS_ENDIAN_BIG */ + +#define gfs16_to_cpu le16_to_cpu +#define gfs32_to_cpu le32_to_cpu +#define gfs64_to_cpu le64_to_cpu + +#define cpu_to_gfs16 cpu_to_le16 +#define cpu_to_gfs32 cpu_to_le32 +#define cpu_to_gfs64 cpu_to_le64 + +#endif /* GFS_ENDIAN_BIG */ + +/* Translation functions */ + +void gfs_inum_in(struct gfs_inum *no, char *buf); +void gfs_inum_out(struct gfs_inum *no, char *buf); +void gfs_meta_header_in(struct gfs_meta_header *mh, char *buf); +void gfs_meta_header_out(struct gfs_meta_header *mh, char *buf); +void gfs_sb_in(struct gfs_sb *sb, char *buf); +void gfs_sb_out(struct gfs_sb *sb, char *buf); +void gfs_jindex_in(struct gfs_jindex *jindex, char *buf); +void gfs_jindex_out(struct gfs_jindex *jindex, char *buf); +void gfs_rindex_in(struct gfs_rindex *rindex, char *buf); +void gfs_rindex_out(struct gfs_rindex *rindex, char *buf); +void gfs_rgrp_in(struct gfs_rgrp *rgrp, char *buf); +void gfs_rgrp_out(struct gfs_rgrp *rgrp, char *buf); +void gfs_quota_in(struct gfs_quota *quota, char *buf); +void gfs_quota_out(struct gfs_quota *quota, char *buf); +void gfs_dinode_in(struct gfs_dinode *dinode, char *buf); +void gfs_dinode_out(struct gfs_dinode *dinode, char *buf); +void gfs_indirect_in(struct gfs_indirect *indirect, char *buf); +void gfs_indirect_out(struct gfs_indirect *indirect, char *buf); +void gfs_dirent_in(struct gfs_dirent *dirent, char *buf); +void gfs_dirent_out(struct gfs_dirent *dirent, char *buf); +void gfs_leaf_in(struct gfs_leaf *leaf, char *buf); +void gfs_leaf_out(struct gfs_leaf *leaf, char *buf); +void gfs_log_header_in(struct gfs_log_header *head, char *buf); +void gfs_log_header_out(struct gfs_log_header *head, char *buf); +void gfs_desc_in(struct gfs_log_descriptor *desc, char *buf); +void gfs_desc_out(struct gfs_log_descriptor *desc, char *buf); +void gfs_block_tag_in(struct gfs_block_tag *btag, char *buf); +void gfs_block_tag_out(struct gfs_block_tag *btag, char *buf); +void gfs_quota_tag_in(struct gfs_quota_tag *qtag, char *buf); +void gfs_quota_tag_out(struct gfs_quota_tag *qtag, char *buf); +void gfs_ea_header_in(struct gfs_ea_header *qtag, char *buf); +void gfs_ea_header_out(struct gfs_ea_header *qtag, char *buf); + +/* Printing functions */ + +void gfs_inum_print(struct gfs_inum *no); +void gfs_meta_header_print(struct gfs_meta_header *mh); +void gfs_sb_print(struct gfs_sb *sb); +void gfs_jindex_print(struct gfs_jindex *jindex); +void gfs_rindex_print(struct gfs_rindex *rindex); +void gfs_rgrp_print(struct gfs_rgrp *rgrp); +void gfs_quota_print(struct gfs_quota *quota); +void gfs_dinode_print(struct gfs_dinode *dinode); +void gfs_indirect_print(struct gfs_indirect *indirect); +void gfs_dirent_print(struct gfs_dirent *dirent, char *name); +void gfs_leaf_print(struct gfs_leaf *leaf); +void gfs_log_header_print(struct gfs_log_header *head); +void gfs_desc_print(struct gfs_log_descriptor *desc); +void gfs_block_tag_print(struct gfs_block_tag *tag); +void gfs_quota_tag_print(struct gfs_quota_tag *tag); +void gfs_ea_header_print(struct gfs_ea_header *ea, char *name); + +/* The hash function for ExHash directories */ + +uint32_t gfs_dir_hash(const char *data, int len); + +#endif /* __GFS_ONDISK_DOT_H__ */ + + + +#ifdef WANT_GFS_CONVERSION_FUNCTIONS + +#define CPIN_08(s1, s2, member, count) {memcpy((s1->member), (s2->member), (count));} +#define CPOUT_08(s1, s2, member, count) {memcpy((s2->member), (s1->member), (count));} +#define CPIN_16(s1, s2, member) {(s1->member) = gfs16_to_cpu((s2->member));} +#define CPOUT_16(s1, s2, member) {(s2->member) = cpu_to_gfs16((s1->member));} +#define CPIN_32(s1, s2, member) {(s1->member) = gfs32_to_cpu((s2->member));} +#define CPOUT_32(s1, s2, member) {(s2->member) = cpu_to_gfs32((s1->member));} +#define CPIN_64(s1, s2, member) {(s1->member) = gfs64_to_cpu((s2->member));} +#define CPOUT_64(s1, s2, member) {(s2->member) = cpu_to_gfs64((s1->member));} + +#define pa(struct, member, count) print_array(#member, struct->member, count); + +/** + * print_array - Print out an array of bytes + * @title: what to print before the array + * @buf: the array + * @count: the number of bytes + * + */ + +static void +print_array(char *title, char *buf, int count) +{ + int x; + + printk(" %s =\n", title); + for (x = 0; x < count; x++) { + printk("%.2X ", (unsigned char)buf[x]); + if (x % 16 == 15) + printk("\n"); + } + if (x % 16) + printk("\n"); +} + +/** + * gfs_inum_in - Read in an inode number + * @no: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_inum_in(struct gfs_inum *no, char *buf) +{ + struct gfs_inum *str = (struct gfs_inum *)buf; + + CPIN_64(no, str, no_formal_ino); + CPIN_64(no, str, no_addr); +} + +/** + * gfs_inum_out - Write out an inode number + * @no: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_inum_out(struct gfs_inum *no, char *buf) +{ + struct gfs_inum *str = (struct gfs_inum *)buf; + + CPOUT_64(no, str, no_formal_ino); + CPOUT_64(no, str, no_addr); +} + +/** + * gfs_inum_print - Print out a inode number + * @no: the cpu-order buffer + * + */ + +void +gfs_inum_print(struct gfs_inum *no) +{ + pv(no, no_formal_ino, "%"PRIu64); + pv(no, no_addr, "%"PRIu64); +} + +/** + * gfs_meta_header_in - Read in a metadata header + * @mh: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_meta_header_in(struct gfs_meta_header *mh, char *buf) +{ + struct gfs_meta_header *str = (struct gfs_meta_header *)buf; + + CPIN_32(mh, str, mh_magic); + CPIN_32(mh, str, mh_type); + CPIN_64(mh, str, mh_generation); + CPIN_32(mh, str, mh_format); + CPIN_32(mh, str, mh_incarn); +} + +/** + * gfs_meta_header_in - Write out a metadata header + * @mh: the cpu-order structure + * @buf: the disk-order buffer + * + * Don't ever change the generation number in this routine. + * It's done manually in increment_generation(). + */ + +void +gfs_meta_header_out(struct gfs_meta_header *mh, char *buf) +{ + struct gfs_meta_header *str = (struct gfs_meta_header *)buf; + + CPOUT_32(mh, str, mh_magic); + CPOUT_32(mh, str, mh_type); +#if 0 + /* Don't do this! + Mh_generation should only be change manually. */ + CPOUT_64(mh, str, mh_generation); +#endif + CPOUT_32(mh, str, mh_format); + CPOUT_32(mh, str, mh_incarn); +} + +/** + * gfs_meta_header_print - Print out a metadata header + * @mh: the cpu-order buffer + * + */ + +void +gfs_meta_header_print(struct gfs_meta_header *mh) +{ + pv(mh, mh_magic, "0x%.8X"); + pv(mh, mh_type, "%u"); + pv(mh, mh_generation, "%"PRIu64); + pv(mh, mh_format, "%u"); + pv(mh, mh_incarn, "%u"); +} + +/** + * gfs_sb_in - Read in a superblock + * @sb: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_sb_in(struct gfs_sb *sb, char *buf) +{ + struct gfs_sb *str = (struct gfs_sb *)buf; + + gfs_meta_header_in(&sb->sb_header, buf); + + CPIN_32(sb, str, sb_fs_format); + CPIN_32(sb, str, sb_multihost_format); + CPIN_32(sb, str, sb_flags); + + CPIN_32(sb, str, sb_bsize); + CPIN_32(sb, str, sb_bsize_shift); + CPIN_32(sb, str, sb_seg_size); + + gfs_inum_in(&sb->sb_jindex_di, (char *)&str->sb_jindex_di); + gfs_inum_in(&sb->sb_rindex_di, (char *)&str->sb_rindex_di); + gfs_inum_in(&sb->sb_root_di, (char *)&str->sb_root_di); + + CPIN_08(sb, str, sb_lockproto, GFS_LOCKNAME_LEN); + CPIN_08(sb, str, sb_locktable, GFS_LOCKNAME_LEN); + + gfs_inum_in(&sb->sb_quota_di, (char *)&str->sb_quota_di); + gfs_inum_in(&sb->sb_license_di, (char *)&str->sb_license_di); + + CPIN_08(sb, str, sb_reserved, 96); +} + +/** + * gfs_sb_out - Write out a superblock + * @sb: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_sb_out(struct gfs_sb *sb, char *buf) +{ + struct gfs_sb *str = (struct gfs_sb *)buf; + + gfs_meta_header_out(&sb->sb_header, buf); + + CPOUT_32(sb, str, sb_fs_format); + CPOUT_32(sb, str, sb_multihost_format); + CPOUT_32(sb, str, sb_flags); + + CPOUT_32(sb, str, sb_bsize); + CPOUT_32(sb, str, sb_bsize_shift); + CPOUT_32(sb, str, sb_seg_size); + + gfs_inum_out(&sb->sb_jindex_di, (char *)&str->sb_jindex_di); + gfs_inum_out(&sb->sb_rindex_di, (char *)&str->sb_rindex_di); + gfs_inum_out(&sb->sb_root_di, (char *)&str->sb_root_di); + + CPOUT_08(sb, str, sb_lockproto, GFS_LOCKNAME_LEN); + CPOUT_08(sb, str, sb_locktable, GFS_LOCKNAME_LEN); + + gfs_inum_out(&sb->sb_quota_di, (char *)&str->sb_quota_di); + gfs_inum_out(&sb->sb_license_di, (char *)&str->sb_license_di); + + CPOUT_08(sb, str, sb_reserved, 96); +} + +/** + * gfs_sb_print - Print out a superblock + * @sb: the cpu-order buffer + * + */ + +void +gfs_sb_print(struct gfs_sb *sb) +{ + gfs_meta_header_print(&sb->sb_header); + + pv(sb, sb_fs_format, "%u"); + pv(sb, sb_multihost_format, "%u"); + pv(sb, sb_flags, "%u"); + + pv(sb, sb_bsize, "%u"); + pv(sb, sb_bsize_shift, "%u"); + pv(sb, sb_seg_size, "%u"); + + gfs_inum_print(&sb->sb_jindex_di); + gfs_inum_print(&sb->sb_rindex_di); + gfs_inum_print(&sb->sb_root_di); + + pv(sb, sb_lockproto, "%s"); + pv(sb, sb_locktable, "%s"); + + gfs_inum_print(&sb->sb_quota_di); + gfs_inum_print(&sb->sb_license_di); + + pa(sb, sb_reserved, 96); +} + +/** + * gfs_jindex_in - Read in a journal index structure + * @jindex: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_jindex_in(struct gfs_jindex *jindex, char *buf) +{ + struct gfs_jindex *str = (struct gfs_jindex *)buf; + + CPIN_64(jindex, str, ji_addr); + CPIN_32(jindex, str, ji_nsegment); + CPIN_32(jindex, str, ji_pad); + + CPIN_08(jindex, str, ji_reserved, 64); +} + +/** + * gfs_jindex_out - Write out a journal index structure + * @jindex: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_jindex_out(struct gfs_jindex *jindex, char *buf) +{ + struct gfs_jindex *str = (struct gfs_jindex *)buf; + + CPOUT_64(jindex, str, ji_addr); + CPOUT_32(jindex, str, ji_nsegment); + CPOUT_32(jindex, str, ji_pad); + + CPOUT_08(jindex, str, ji_reserved, 64); +} + +/** + * gfs_jindex_print - Print out a journal index structure + * @ji: the cpu-order buffer + * + */ + +void +gfs_jindex_print(struct gfs_jindex *ji) +{ + pv(ji, ji_addr, "%"PRIu64); + pv(ji, ji_nsegment, "%u"); + pv(ji, ji_pad, "%u"); + + pa(ji, ji_reserved, 64); +} + +/** + * gfs_rindex_in - Read in a resource index structure + * @rindex: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_rindex_in(struct gfs_rindex *rindex, char *buf) +{ + struct gfs_rindex *str = (struct gfs_rindex *)buf; + + CPIN_64(rindex, str, ri_addr); + CPIN_32(rindex, str, ri_length); + CPIN_32(rindex, str, ri_pad); + + CPIN_64(rindex, str, ri_data1); + CPIN_32(rindex, str, ri_data); + + CPIN_32(rindex, str, ri_bitbytes); + + CPIN_08(rindex, str, ri_reserved, 64); +} + +/** + * gfs_rindex_out - Write out a resource index structure + * @rindex: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_rindex_out(struct gfs_rindex *rindex, char *buf) +{ + struct gfs_rindex *str = (struct gfs_rindex *)buf; + + CPOUT_64(rindex, str, ri_addr); + CPOUT_32(rindex, str, ri_length); + CPOUT_32(rindex, str, ri_pad); + + CPOUT_64(rindex, str, ri_data1); + CPOUT_32(rindex, str, ri_data); + + CPOUT_32(rindex, str, ri_bitbytes); + + CPOUT_08(rindex, str, ri_reserved, 64); +} + +/** + * gfs_rindex_print - Print out a resource index structure + * @ri: the cpu-order buffer + * + */ + +void +gfs_rindex_print(struct gfs_rindex *ri) +{ + pv(ri, ri_addr, "%"PRIu64); + pv(ri, ri_length, "%u"); + pv(ri, ri_pad, "%u"); + + pv(ri, ri_data1, "%"PRIu64); + pv(ri, ri_data, "%u"); + + pv(ri, ri_bitbytes, "%u"); + + pa(ri, ri_reserved, 64); +} + +/** + * gfs_rgrp_in - Read in a resource group header + * @rgrp: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_rgrp_in(struct gfs_rgrp *rgrp, char *buf) +{ + struct gfs_rgrp *str = (struct gfs_rgrp *)buf; + + gfs_meta_header_in(&rgrp->rg_header, buf); + + CPIN_32(rgrp, str, rg_flags); + + CPIN_32(rgrp, str, rg_free); + + CPIN_32(rgrp, str, rg_useddi); + CPIN_32(rgrp, str, rg_freedi); + gfs_inum_in(&rgrp->rg_freedi_list, (char *)&str->rg_freedi_list); + + CPIN_32(rgrp, str, rg_usedmeta); + CPIN_32(rgrp, str, rg_freemeta); + + CPIN_08(rgrp, str, rg_reserved, 64); +} + +/** + * gfs_rgrp_out - Write out a resource group header + * @rgrp: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_rgrp_out(struct gfs_rgrp *rgrp, char *buf) +{ + struct gfs_rgrp *str = (struct gfs_rgrp *)buf; + + gfs_meta_header_out(&rgrp->rg_header, buf); + + CPOUT_32(rgrp, str, rg_flags); + + CPOUT_32(rgrp, str, rg_free); + + CPOUT_32(rgrp, str, rg_useddi); + CPOUT_32(rgrp, str, rg_freedi); + gfs_inum_out(&rgrp->rg_freedi_list, (char *)&str->rg_freedi_list); + + CPOUT_32(rgrp, str, rg_usedmeta); + CPOUT_32(rgrp, str, rg_freemeta); + + CPOUT_08(rgrp, str, rg_reserved, 64); +} + +/** + * gfs_rgrp_print - Print out a resource group header + * @rg: the cpu-order buffer + * + */ + +void +gfs_rgrp_print(struct gfs_rgrp *rg) +{ + gfs_meta_header_print(&rg->rg_header); + + pv(rg, rg_flags, "%u"); + + pv(rg, rg_free, "%u"); + + pv(rg, rg_useddi, "%u"); + pv(rg, rg_freedi, "%u"); + gfs_inum_print(&rg->rg_freedi_list); + + pv(rg, rg_usedmeta, "%u"); + pv(rg, rg_freemeta, "%u"); + + pa(rg, rg_reserved, 64); +} + +/** + * gfs_quota_in - Read in a quota structures + * @quota: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_quota_in(struct gfs_quota *quota, char *buf) +{ + struct gfs_quota *str = (struct gfs_quota *)buf; + + CPIN_64(quota, str, qu_limit); + CPIN_64(quota, str, qu_warn); + CPIN_64(quota, str, qu_value); + + CPIN_08(quota, str, qu_reserved, 64); +} + +/** + * gfs_quota_out - Write out a quota structure + * @quota: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_quota_out(struct gfs_quota *quota, char *buf) +{ + struct gfs_quota *str = (struct gfs_quota *)buf; + + CPOUT_64(quota, str, qu_limit); + CPOUT_64(quota, str, qu_warn); + CPOUT_64(quota, str, qu_value); + + CPOUT_08(quota, str, qu_reserved, 64); +} + +/** + * gfs_quota_print - Print out a quota structure + * @quota: the cpu-order buffer + * + */ + +void +gfs_quota_print(struct gfs_quota *quota) +{ + pv(quota, qu_limit, "%"PRIu64); + pv(quota, qu_warn, "%"PRIu64); + pv(quota, qu_value, "%"PRId64); + + pa(quota, qu_reserved, 64); +} + +/** + * gfs_dinode_in - Read in a dinode + * @dinode: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_dinode_in(struct gfs_dinode *dinode, char *buf) +{ + struct gfs_dinode *str = (struct gfs_dinode *)buf; + + gfs_meta_header_in(&dinode->di_header, buf); + + gfs_inum_in(&dinode->di_num, (char *)&str->di_num); + + CPIN_32(dinode, str, di_mode); + CPIN_32(dinode, str, di_uid); + CPIN_32(dinode, str, di_gid); + CPIN_32(dinode, str, di_nlink); + CPIN_64(dinode, str, di_size); + CPIN_64(dinode, str, di_blocks); + CPIN_64(dinode, str, di_atime); + CPIN_64(dinode, str, di_mtime); + CPIN_64(dinode, str, di_ctime); + CPIN_32(dinode, str, di_major); + CPIN_32(dinode, str, di_minor); + + CPIN_64(dinode, str, di_rgrp); + CPIN_64(dinode, str, di_goal_rgrp); + CPIN_32(dinode, str, di_goal_dblk); + CPIN_32(dinode, str, di_goal_mblk); + CPIN_32(dinode, str, di_flags); + CPIN_32(dinode, str, di_payload_format); + CPIN_16(dinode, str, di_type); + CPIN_16(dinode, str, di_height); + CPIN_32(dinode, str, di_incarn); + CPIN_16(dinode, str, di_pad); + + CPIN_16(dinode, str, di_depth); + CPIN_32(dinode, str, di_entries); + + gfs_inum_in(&dinode->di_next_unused, (char *)&str->di_next_unused); + + CPIN_64(dinode, str, di_eattr); + + CPIN_08(dinode, str, di_reserved, 56); +} + +/** + * gfs_dinode_out - Write out a dinode + * @dinode: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_dinode_out(struct gfs_dinode *dinode, char *buf) +{ + struct gfs_dinode *str = (struct gfs_dinode *)buf; + + gfs_meta_header_out(&dinode->di_header, buf); + + gfs_inum_out(&dinode->di_num, (char *)&str->di_num); + + CPOUT_32(dinode, str, di_mode); + CPOUT_32(dinode, str, di_uid); + CPOUT_32(dinode, str, di_gid); + CPOUT_32(dinode, str, di_nlink); + CPOUT_64(dinode, str, di_size); + CPOUT_64(dinode, str, di_blocks); + CPOUT_64(dinode, str, di_atime); + CPOUT_64(dinode, str, di_mtime); + CPOUT_64(dinode, str, di_ctime); + CPOUT_32(dinode, str, di_major); + CPOUT_32(dinode, str, di_minor); + + CPOUT_64(dinode, str, di_rgrp); + CPOUT_64(dinode, str, di_goal_rgrp); + CPOUT_32(dinode, str, di_goal_dblk); + CPOUT_32(dinode, str, di_goal_mblk); + CPOUT_32(dinode, str, di_flags); + CPOUT_32(dinode, str, di_payload_format); + CPOUT_16(dinode, str, di_type); + CPOUT_16(dinode, str, di_height); + CPOUT_32(dinode, str, di_incarn); + CPOUT_16(dinode, str, di_pad); + + CPOUT_16(dinode, str, di_depth); + CPOUT_32(dinode, str, di_entries); + + gfs_inum_out(&dinode->di_next_unused, (char *)&str->di_next_unused); + + CPOUT_64(dinode, str, di_eattr); + + CPOUT_08(dinode, str, di_reserved, 56); +} + +/** + * gfs_dinode_print - Print out a dinode + * @di: the cpu-order buffer + * + */ + +void +gfs_dinode_print(struct gfs_dinode *di) +{ + gfs_meta_header_print(&di->di_header); + + gfs_inum_print(&di->di_num); + + pv(di, di_mode, "0%o"); + pv(di, di_uid, "%u"); + pv(di, di_gid, "%u"); + pv(di, di_nlink, "%u"); + pv(di, di_size, "%"PRIu64); + pv(di, di_blocks, "%"PRIu64); + pv(di, di_atime, "%"PRId64); + pv(di, di_mtime, "%"PRId64); + pv(di, di_ctime, "%"PRId64); + pv(di, di_major, "%u"); + pv(di, di_minor, "%u"); + + pv(di, di_rgrp, "%"PRIu64); + pv(di, di_goal_rgrp, "%"PRIu64); + pv(di, di_goal_dblk, "%u"); + pv(di, di_goal_mblk, "%u"); + pv(di, di_flags, "0x%.8X"); + pv(di, di_payload_format, "%u"); + pv(di, di_type, "%u"); + pv(di, di_height, "%u"); + pv(di, di_incarn, "%u"); + pv(di, di_pad, "%u"); + + pv(di, di_depth, "%u"); + pv(di, di_entries, "%u"); + + gfs_inum_print(&di->di_next_unused); + + pv(di, di_eattr, "%"PRIu64); + + pa(di, di_reserved, 56); +} + +/** + * gfs_indirect_in - copy in the header of an indirect block + * @indirect: the in memory copy + * @buf: the buffer copy + * + */ + +void +gfs_indirect_in(struct gfs_indirect *indirect, char *buf) +{ + struct gfs_indirect *str = (struct gfs_indirect *)buf; + + gfs_meta_header_in(&indirect->in_header, buf); + + CPIN_08(indirect, str, in_reserved, 64); +} + +/** + * gfs_indirect_out - copy out the header of an indirect block + * @indirect: the in memory copy + * @buf: the buffer copy + * + */ + +void +gfs_indirect_out(struct gfs_indirect *indirect, char *buf) +{ + struct gfs_indirect *str = (struct gfs_indirect *)buf; + + gfs_meta_header_out(&indirect->in_header, buf); + + CPOUT_08(indirect, str, in_reserved, 64); +} + +/** + * gfs_indirect_print - Print out a indirect block header + * @indirect: the cpu-order buffer + * + */ + +void +gfs_indirect_print(struct gfs_indirect *indirect) +{ + gfs_meta_header_print(&indirect->in_header); + + pa(indirect, in_reserved, 64); +} + +/** + * gfs_dirent_in - Read in a directory entry + * @dirent: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_dirent_in(struct gfs_dirent *dirent, char *buf) +{ + struct gfs_dirent *str = (struct gfs_dirent *)buf; + + gfs_inum_in(&dirent->de_inum, (char *)&str->de_inum); + CPIN_32(dirent, str, de_hash); + CPIN_16(dirent, str, de_rec_len); + CPIN_16(dirent, str, de_name_len); + CPIN_16(dirent, str, de_type); + + CPIN_08(dirent, str, de_reserved, 14); +} + +/** + * gfs_dirent_out - Write out a directory entry + * @dirent: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_dirent_out(struct gfs_dirent *dirent, char *buf) +{ + struct gfs_dirent *str = (struct gfs_dirent *)buf; + + gfs_inum_out(&dirent->de_inum, (char *)&str->de_inum); + CPOUT_32(dirent, str, de_hash); + CPOUT_16(dirent, str, de_rec_len); + CPOUT_16(dirent, str, de_name_len); + CPOUT_16(dirent, str, de_type); + + CPOUT_08(dirent, str, de_reserved, 14); +} + +/** + * gfs_dirent_print - Print out a directory entry + * @de: the cpu-order buffer + * @name: the filename + * + */ + +void +gfs_dirent_print(struct gfs_dirent *de, char *name) +{ + char buf[GFS_FNAMESIZE + 1]; + + gfs_inum_print(&de->de_inum); + pv(de, de_hash, "0x%.8X"); + pv(de, de_rec_len, "%u"); + pv(de, de_name_len, "%u"); + pv(de, de_type, "%u"); + + pa(de, de_reserved, 14); + + memset(buf, 0, GFS_FNAMESIZE + 1); + memcpy(buf, name, de->de_name_len); + printk(" name = %s\n", buf); +} + +/** + * gfs_leaf_in - Read in a directory leaf header + * @leaf: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_leaf_in(struct gfs_leaf *leaf, char *buf) +{ + struct gfs_leaf *str = (struct gfs_leaf *)buf; + + gfs_meta_header_in(&leaf->lf_header, buf); + + CPIN_16(leaf, str, lf_depth); + CPIN_16(leaf, str, lf_entries); + CPIN_32(leaf, str, lf_dirent_format); + CPIN_64(leaf, str, lf_next); + + CPIN_08(leaf, str, lf_reserved, 64); +} + +/** + * gfs_leaf_out - Write out a directory leaf header + * @leaf: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_leaf_out(struct gfs_leaf *leaf, char *buf) +{ + struct gfs_leaf *str = (struct gfs_leaf *)buf; + + gfs_meta_header_out(&leaf->lf_header, buf); + + CPOUT_16(leaf, str, lf_depth); + CPOUT_16(leaf, str, lf_entries); + CPOUT_32(leaf, str, lf_dirent_format); + CPOUT_64(leaf, str, lf_next); + + CPOUT_08(leaf, str, lf_reserved, 64); +} + +/** + * gfs_leaf_print - Print out a directory leaf header + * @lf: the cpu-order buffer + * + */ + +void +gfs_leaf_print(struct gfs_leaf *lf) +{ + gfs_meta_header_print(&lf->lf_header); + + pv(lf, lf_depth, "%u"); + pv(lf, lf_entries, "%u"); + pv(lf, lf_dirent_format, "%u"); + pv(lf, lf_next, "%"PRIu64); + + pa(lf, lf_reserved, 64); +} + +/** + * gfs_log_header_in - Read in a log header + * @head: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_log_header_in(struct gfs_log_header *head, char *buf) +{ + struct gfs_log_header *str = (struct gfs_log_header *)buf; + + gfs_meta_header_in(&head->lh_header, buf); + + CPIN_32(head, str, lh_flags); + CPIN_32(head, str, lh_pad); + + CPIN_64(head, str, lh_first); + CPIN_64(head, str, lh_sequence); + + CPIN_64(head, str, lh_tail); + CPIN_64(head, str, lh_last_dump); + + CPIN_08(head, str, lh_reserved, 64); +} + +/** + * gfs_log_header_out - Write out a log header + * @head: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_log_header_out(struct gfs_log_header *head, char *buf) +{ + struct gfs_log_header *str = (struct gfs_log_header *)buf; + + gfs_meta_header_out(&head->lh_header, buf); + + CPOUT_32(head, str, lh_flags); + CPOUT_32(head, str, lh_pad); + + CPOUT_64(head, str, lh_first); + CPOUT_64(head, str, lh_sequence); + + CPOUT_64(head, str, lh_tail); + CPOUT_64(head, str, lh_last_dump); + + CPOUT_08(head, str, lh_reserved, 64); +} + +/** + * gfs_log_header_print - Print out a log header + * @head: the cpu-order buffer + * + */ + +void +gfs_log_header_print(struct gfs_log_header *lh) +{ + gfs_meta_header_print(&lh->lh_header); + + pv(lh, lh_flags, "0x%.8X"); + pv(lh, lh_pad, "%u"); + + pv(lh, lh_first, "%"PRIu64); + pv(lh, lh_sequence, "%"PRIu64); + + pv(lh, lh_tail, "%"PRIu64); + pv(lh, lh_last_dump, "%"PRIu64); + + pa(lh, lh_reserved, 64); +} + +/** + * gfs_desc_in - Read in a log descriptor + * @desc: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_desc_in(struct gfs_log_descriptor *desc, char *buf) +{ + struct gfs_log_descriptor *str = (struct gfs_log_descriptor *)buf; + + gfs_meta_header_in(&desc->ld_header, buf); + + CPIN_32(desc, str, ld_type); + CPIN_32(desc, str, ld_length); + CPIN_32(desc, str, ld_data1); + CPIN_32(desc, str, ld_data2); + + CPIN_08(desc, str, ld_reserved, 64); +} + +/** + * gfs_desc_out - Write out a log descriptor + * @desc: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_desc_out(struct gfs_log_descriptor *desc, char *buf) +{ + struct gfs_log_descriptor *str = (struct gfs_log_descriptor *)buf; + + gfs_meta_header_out(&desc->ld_header, buf); + + CPOUT_32(desc, str, ld_type); + CPOUT_32(desc, str, ld_length); + CPOUT_32(desc, str, ld_data1); + CPOUT_32(desc, str, ld_data2); + + CPOUT_08(desc, str, ld_reserved, 64); +} + +/** + * gfs_desc_print - Print out a log descriptor + * @ld: the cpu-order buffer + * + */ + +void +gfs_desc_print(struct gfs_log_descriptor *ld) +{ + gfs_meta_header_print(&ld->ld_header); + + pv(ld, ld_type, "%u"); + pv(ld, ld_length, "%u"); + pv(ld, ld_data1, "%u"); + pv(ld, ld_data2, "%u"); + + pa(ld, ld_reserved, 64); +} + +/** + * gfs_block_tag_in - Read in a block tag + * @tag: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_block_tag_in(struct gfs_block_tag *tag, char *buf) +{ + struct gfs_block_tag *str = (struct gfs_block_tag *)buf; + + CPIN_64(tag, str, bt_blkno); + CPIN_32(tag, str, bt_flags); + CPIN_32(tag, str, bt_pad); +} + +/** + * gfs_block_tag_out - Write out a block tag + * @tag: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_block_tag_out(struct gfs_block_tag *tag, char *buf) +{ + struct gfs_block_tag *str = (struct gfs_block_tag *)buf; + + CPOUT_64(tag, str, bt_blkno); + CPOUT_32(tag, str, bt_flags); + CPOUT_32(tag, str, bt_pad); +} + +/** + * gfs_block_tag_print - Print out a block tag + * @tag: the cpu-order buffer + * + */ + +void +gfs_block_tag_print(struct gfs_block_tag *tag) +{ + pv(tag, bt_blkno, "%"PRIu64); + pv(tag, bt_flags, "%u"); + pv(tag, bt_pad, "%u"); +} + +/** + * gfs_quota_tag_in - Read in a quota tag + * @tag: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_quota_tag_in(struct gfs_quota_tag *tag, char *buf) +{ + struct gfs_quota_tag *str = (struct gfs_quota_tag *)buf; + + CPIN_64(tag, str, qt_change); + CPIN_32(tag, str, qt_flags); + CPIN_32(tag, str, qt_id); +} + +/** + * gfs_quota_tag_out - Write out a quota tag + * @tag: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_quota_tag_out(struct gfs_quota_tag *tag, char *buf) +{ + struct gfs_quota_tag *str = (struct gfs_quota_tag *)buf; + + CPOUT_64(tag, str, qt_change); + CPOUT_32(tag, str, qt_flags); + CPOUT_32(tag, str, qt_id); +} + +/** + * gfs_quota_tag_print - Print out a quota tag + * @tag: the cpu-order buffer + * + */ + +void +gfs_quota_tag_print(struct gfs_quota_tag *tag) +{ + pv(tag, qt_change, "%"PRId64); + pv(tag, qt_flags, "0x%.8X"); + pv(tag, qt_id, "%u"); +} + +/** + * gfs_ea_header_in - Read in a Extended Attribute header + * @tag: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_ea_header_in(struct gfs_ea_header *ea, char *buf) +{ + struct gfs_ea_header *str = (struct gfs_ea_header *)buf; + + CPIN_32(ea, str, ea_rec_len); + CPIN_32(ea, str, ea_data_len); + ea->ea_name_len = str->ea_name_len; + ea->ea_type = str->ea_type; + ea->ea_flags = str->ea_flags; + ea->ea_num_ptrs = str->ea_num_ptrs; + CPIN_32(ea, str, ea_pad); +} + +/** + * gfs_ea_header_out - Write out a Extended Attribute header + * @ea: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_ea_header_out(struct gfs_ea_header *ea, char *buf) +{ + struct gfs_ea_header *str = (struct gfs_ea_header *)buf; + + CPOUT_32(ea, str, ea_rec_len); + CPOUT_32(ea, str, ea_data_len); + str->ea_name_len = ea->ea_name_len; + str->ea_type = ea->ea_type; + str->ea_flags = ea->ea_flags; + str->ea_num_ptrs = ea->ea_num_ptrs; + CPOUT_32(ea, str, ea_pad); +} + +/** + * gfs_ea_header_printt - Print out a Extended Attribute header + * @ea: the cpu-order buffer + * + */ + +void +gfs_ea_header_print(struct gfs_ea_header *ea, char *name) +{ + char buf[GFS_EA_MAX_NAME_LEN + 1]; + + pv(ea, ea_rec_len, "%u"); + pv(ea, ea_data_len, "%u"); + pv(ea, ea_name_len, "%u"); + pv(ea, ea_type, "%u"); + pv(ea, ea_flags, "%u"); + pv(ea, ea_num_ptrs, "%u"); + pv(ea, ea_pad, "%u"); + + memset(buf, 0, GFS_EA_MAX_NAME_LEN + 1); + memcpy(buf, name, ea->ea_name_len); + printk(" name = %s\n", buf); +} + +static const uint32_t crc_32_tab[] = +{ + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + +/** + * gfs_dir_hash - hash an array of data + * @data: the data to be hashed + * @len: the length of data to be hashed + * + * Take some data and convert it to a 32-bit hash. + * + * The hash function is a 32-bit CRC of the data. The algorithm uses + * the crc_32_tab table above. + * + * This may not be the fastest hash function, but it does a fair bit better + * at providing uniform results than the others I've looked at. That's + * really important for efficient directories. + * + * Returns: the hash + */ + +uint32_t +gfs_dir_hash(const char *data, int len) +{ + uint32_t hash = 0xFFFFFFFF; + + for (; len--; data++) + hash = crc_32_tab[(hash ^ *data) & 0xFF] ^ (hash >> 8); + + hash = ~hash; + + return hash; +} + +#endif /* WANT_GFS_CONVERSION_FUNCTIONS */ + --- linux-2.6.28.orig/ubuntu/gfs/super.h +++ linux-2.6.28/ubuntu/gfs/super.h @@ -0,0 +1,53 @@ +#ifndef __SUPER_DOT_H__ +#define __SUPER_DOT_H__ + +void gfs_tune_init(struct gfs_tune *gt); + +int gfs_check_sb(struct gfs_sbd *sdp, struct gfs_sb *sb, int silent); +int gfs_read_sb(struct gfs_sbd *sdp, struct gfs_glock *gl, int silent); +int gfs_do_upgrade(struct gfs_sbd *sdp, struct gfs_glock *gl_sb); + +static __inline__ unsigned int +gfs_num_journals(struct gfs_sbd *sdp) +{ + unsigned int num; + down(&sdp->sd_jindex_lock); + num = sdp->sd_journals; + up(&sdp->sd_jindex_lock); + return num; +} + +int gfs_jindex_hold(struct gfs_sbd *sdp, struct gfs_holder *ji_gh); +void gfs_clear_journals(struct gfs_sbd *sdp); + +int gfs_get_jiinode(struct gfs_sbd *sdp); +int gfs_get_riinode(struct gfs_sbd *sdp); +int gfs_get_rootinode(struct gfs_sbd *sdp); +int gfs_get_qinode(struct gfs_sbd *sdp); +int gfs_get_linode(struct gfs_sbd *sdp); + +int gfs_make_fs_rw(struct gfs_sbd *sdp); +int gfs_make_fs_ro(struct gfs_sbd *sdp); + +int gfs_statfs_init(struct gfs_sbd *sdp, int flag); +int gfs_statfs_sync(struct gfs_sbd *sdp); +int gfs_statfs_fast(struct gfs_sbd *sdp, void *buf); + +struct gfs_stat_gfs { + uint64_t sg_total_blocks; + uint64_t sg_free; + uint64_t sg_used_dinode; + uint64_t sg_free_dinode; + uint64_t sg_used_meta; + uint64_t sg_free_meta; +}; + +int gfs_stat_gfs(struct gfs_sbd *sdp, struct gfs_stat_gfs *sg, + int interruptible); + +int gfs_lock_fs_check_clean(struct gfs_sbd *sdp, unsigned int state, + struct gfs_holder *t_gh); +int gfs_freeze_fs(struct gfs_sbd *sdp); +void gfs_unfreeze_fs(struct gfs_sbd *sdp); + +#endif /* __SUPER_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/lock_dlm_mount.c +++ linux-2.6.28/ubuntu/gfs/lock_dlm_mount.c @@ -0,0 +1,279 @@ +/* + * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. + * Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License version 2. + */ + +#include "lock_dlm.h" + +const struct lm_lockops gdlm_ops; + + +static struct gdlm_ls *init_gdlm(lm_callback_t cb, struct gfs_sbd *sdp, + int flags, char *table_name) +{ + struct gdlm_ls *ls; + char buf[256], *p; + + ls = kzalloc(sizeof(struct gdlm_ls), GFP_KERNEL); + if (!ls) + return NULL; + + ls->drop_locks_count = GDLM_DROP_COUNT; + ls->drop_locks_period = GDLM_DROP_PERIOD; + ls->fscb = cb; + ls->sdp = sdp; + ls->fsflags = flags; + spin_lock_init(&ls->async_lock); + INIT_LIST_HEAD(&ls->complete); + INIT_LIST_HEAD(&ls->blocking); + INIT_LIST_HEAD(&ls->delayed); + INIT_LIST_HEAD(&ls->submit); + INIT_LIST_HEAD(&ls->all_locks); + init_waitqueue_head(&ls->thread_wait); + init_waitqueue_head(&ls->wait_control); + ls->thread1 = NULL; + ls->thread2 = NULL; + ls->drop_time = jiffies; + ls->jid = -1; + + strncpy(buf, table_name, 256); + buf[255] = '\0'; + + p = strchr(buf, ':'); + if (!p) { + log_info("invalid table_name \"%s\"", table_name); + kfree(ls); + return NULL; + } + *p = '\0'; + p++; + + strncpy(ls->clustername, buf, GDLM_NAME_LEN); + strncpy(ls->fsname, p, GDLM_NAME_LEN); + + return ls; +} + +static int make_args(struct gdlm_ls *ls, char *data_arg, int *nodir) +{ + char data[256]; + char *options, *x, *y; + int error = 0; + + memset(data, 0, 256); + strncpy(data, data_arg, 255); + + if (!strlen(data)) { + log_error("no mount options, (u)mount helpers not installed"); + return -EINVAL; + } + + for (options = data; (x = strsep(&options, ":")); ) { + if (!*x) + continue; + + y = strchr(x, '='); + if (y) + *y++ = 0; + + if (!strcmp(x, "jid")) { + if (!y) { + log_error("need argument to jid"); + error = -EINVAL; + break; + } + sscanf(y, "%u", &ls->jid); + + } else if (!strcmp(x, "first")) { + if (!y) { + log_error("need argument to first"); + error = -EINVAL; + break; + } + sscanf(y, "%u", &ls->first); + + } else if (!strcmp(x, "id")) { + if (!y) { + log_error("need argument to id"); + error = -EINVAL; + break; + } + sscanf(y, "%u", &ls->id); + + } else if (!strcmp(x, "nodir")) { + if (!y) { + log_error("need argument to nodir"); + error = -EINVAL; + break; + } + sscanf(y, "%u", nodir); + + } else { + log_error("unkonwn option: %s", x); + error = -EINVAL; + break; + } + } + + return error; +} + +static int gdlm_mount(char *table_name, char *host_data, + lm_callback_t cb, void *cb_data, + unsigned int min_lvb_size, int flags, + struct lm_lockstruct *lockstruct, + struct kobject *fskobj) +{ + struct gdlm_ls *ls; + int error = -ENOMEM, nodir = 0; + + if (min_lvb_size > GDLM_LVB_SIZE) + goto out; + + ls = init_gdlm(cb, cb_data, flags, table_name); + if (!ls) + goto out; + + error = make_args(ls, host_data, &nodir); + if (error) + goto out; + + error = gdlm_init_threads(ls); + if (error) + goto out_free; + + error = gdlm_kobject_setup(ls, fskobj); + if (error) + goto out_thread; + + error = dlm_new_lockspace(ls->fsname, strlen(ls->fsname), + &ls->dlm_lockspace, + DLM_LSFL_FS | (nodir ? DLM_LSFL_NODIR : 0), + GDLM_LVB_SIZE); + if (error) { + log_error("dlm_new_lockspace error %d", error); + goto out_kobj; + } + + lockstruct->ls_jid = ls->jid; + lockstruct->ls_first = ls->first; + lockstruct->ls_lockspace = ls; + lockstruct->ls_ops = &gdlm_ops; + lockstruct->ls_flags = 0; + lockstruct->ls_lvb_size = GDLM_LVB_SIZE; + return 0; + +out_kobj: + gdlm_kobject_release(ls); +out_thread: + gdlm_release_threads(ls); +out_free: + kfree(ls); +out: + return error; +} + +static void gdlm_unmount(void *lockspace) +{ + struct gdlm_ls *ls = lockspace; + int rv; + + log_debug("unmount flags %lx", ls->flags); + + /* FIXME: serialize unmount and withdraw in case they + happen at once. Also, if unmount follows withdraw, + wait for withdraw to finish. */ + + if (test_bit(DFL_WITHDRAW, &ls->flags)) + goto out; + + gdlm_kobject_release(ls); + dlm_release_lockspace(ls->dlm_lockspace, 2); + gdlm_release_threads(ls); + rv = gdlm_release_all_locks(ls); + if (rv) + log_info("gdlm_unmount: %d stray locks freed", rv); +out: + kfree(ls); +} + +static void gdlm_recovery_done(void *lockspace, unsigned int jid, + unsigned int message) +{ + struct gdlm_ls *ls = lockspace; + ls->recover_jid_done = jid; + ls->recover_jid_status = message; + kobject_uevent(&ls->kobj, KOBJ_CHANGE); +} + +static void gdlm_others_may_mount(void *lockspace) +{ + struct gdlm_ls *ls = lockspace; + ls->first_done = 1; + kobject_uevent(&ls->kobj, KOBJ_CHANGE); +} + +/* Userspace gets the offline uevent, blocks new gfs locks on + other mounters, and lets us know (sets WITHDRAW flag). Then, + userspace leaves the mount group while we leave the lockspace. */ + +static void gdlm_withdraw(void *lockspace) +{ + struct gdlm_ls *ls = lockspace; + + kobject_uevent(&ls->kobj, KOBJ_OFFLINE); + + wait_event_interruptible(ls->wait_control, + test_bit(DFL_WITHDRAW, &ls->flags)); + + dlm_release_lockspace(ls->dlm_lockspace, 2); + gdlm_release_threads(ls); + gdlm_release_all_locks(ls); + gdlm_kobject_release(ls); +} + +static int gdlm_plock(void *lockspace, struct lm_lockname *name, + struct file *file, int cmd, struct file_lock *fl) +{ + struct gdlm_ls *ls = lockspace; + return dlm_posix_lock(ls->dlm_lockspace, name->ln_number, file, cmd, fl); +} + +static int gdlm_punlock(void *lockspace, struct lm_lockname *name, + struct file *file, struct file_lock *fl) +{ + struct gdlm_ls *ls = lockspace; + return dlm_posix_unlock(ls->dlm_lockspace, name->ln_number, file, fl); +} + +static int gdlm_plock_get(void *lockspace, struct lm_lockname *name, + struct file *file, struct file_lock *fl) +{ + struct gdlm_ls *ls = lockspace; + return dlm_posix_get(ls->dlm_lockspace, name->ln_number, file, fl); +} + +const struct lm_lockops gdlm_ops = { + .lm_proto_name = "lock_dlm", + .lm_mount = gdlm_mount, + .lm_others_may_mount = gdlm_others_may_mount, + .lm_unmount = gdlm_unmount, + .lm_withdraw = gdlm_withdraw, + .lm_get_lock = gdlm_get_lock, + .lm_put_lock = gdlm_put_lock, + .lm_lock = gdlm_lock, + .lm_unlock = gdlm_unlock, + .lm_plock = gdlm_plock, + .lm_punlock = gdlm_punlock, + .lm_plock_get = gdlm_plock_get, + .lm_cancel = gdlm_cancel, + .lm_hold_lvb = gdlm_hold_lvb, + .lm_unhold_lvb = gdlm_unhold_lvb, + .lm_recovery_done = gdlm_recovery_done, + .lm_owner = THIS_MODULE, +}; + --- linux-2.6.28.orig/ubuntu/gfs/log.c +++ linux-2.6.28/ubuntu/gfs/log.c @@ -0,0 +1,1429 @@ +/* + What rolls down stairs + Alone or in pairs + Rolls over your neighbor's dog. + What's great for a snack + And fits on your back + It's log, log, log! + It's lo-og, lo-og, + It's big, it's heavy, it's wood. + It's lo-og, lo-og, + It's better than bad, it's good. + Everyone wants a log, + You're gonna love it, log + Come on and get your log, + Everyone needs a log... + LOG... FROM BLAMMO! + + -- The Ren and Stimpy Show +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "dio.h" +#include "log.h" +#include "lops.h" + +/** + * gfs_struct2blk - compute stuff + * @sdp: the filesystem + * @nstruct: the number of structures + * @ssize: the size of the structures + * + * Compute the number of log descriptor blocks needed to hold a certain number + * of structures of a certain size. + * + * Returns: the number of blocks needed (minimum is always 1) + */ + +unsigned int +gfs_struct2blk(struct gfs_sbd *sdp, unsigned int nstruct, unsigned int ssize) +{ + unsigned int blks; + unsigned int first, second; + + blks = 1; + first = (sdp->sd_sb.sb_bsize - sizeof(struct gfs_log_descriptor)) / ssize; + + if (nstruct > first) { + second = sdp->sd_sb.sb_bsize / ssize; + blks += DIV_RU(nstruct - first, second); + } + + return blks; +} + +/** + * gfs_blk2seg - Convert number of blocks into number of segments + * @sdp: The GFS superblock + * @blocks: The number of blocks + * + * Returns: The number of journal segments + */ + +unsigned int +gfs_blk2seg(struct gfs_sbd *sdp, unsigned int blocks) +{ + return DIV_RU(blocks, sdp->sd_sb.sb_seg_size - 1); +} + +/** + * log_distance - Compute distance between two journal blocks + * @sdp: The GFS superblock + * @newer: The most recent journal block of the pair + * @older: The older journal block of the pair + * + * Compute the distance (in the journal direction) between two + * blocks in the journal + * + * Returns: the distance in blocks + */ + +static __inline__ unsigned int +log_distance(struct gfs_sbd *sdp, uint64_t newer, uint64_t older) +{ + int64_t dist; + + dist = newer - older; + if (dist < 0) + dist += sdp->sd_jdesc.ji_nsegment * sdp->sd_sb.sb_seg_size; + + return dist; +} + +/** + * log_incr_head - Increment journal head (next block to fill in journal) + * @sdp: The GFS superblock + * @head: the variable holding the head of the journal + * + * Increment journal head by one. + * At the end of the journal, wrap head back to the start. + * Don't confuse journal/log head with a gfs_log_header! + */ + +static __inline__ void +log_incr_head(struct gfs_sbd *sdp, uint64_t * head) +{ + struct gfs_jindex *jdesc = &sdp->sd_jdesc; + + if (++*head == + jdesc->ji_addr + jdesc->ji_nsegment * sdp->sd_sb.sb_seg_size) + *head = jdesc->ji_addr; +} + +/** + * gfs_ail_start - Start I/O on the AIL + * @sdp: the filesystem + * @flags: DIO_ALL -- flush *all* AIL transactions to disk + * default -- flush first-on-list AIL transaction to disk + * + */ + +void +gfs_ail_start(struct gfs_sbd *sdp, int flags) +{ + struct list_head *head = &sdp->sd_log_ail; + struct list_head *first, *tmp; + struct gfs_trans *first_tr, *tr; + + gfs_log_lock(sdp); + + if (list_empty(head)) { + gfs_log_unlock(sdp); + return; + } + + first = head->prev; + first_tr = list_entry(first, struct gfs_trans, tr_list); + gfs_ail_start_trans(sdp, first_tr); + + if (flags & DIO_ALL) + first_tr = NULL; + + for (tmp = first->prev; tmp != head; tmp = tmp->prev) { + if (first_tr && gfs_ail_empty_trans(sdp, first_tr)) + break; + + tr = list_entry(tmp, struct gfs_trans, tr_list); + gfs_ail_start_trans(sdp, tr); + } + + gfs_log_unlock(sdp); +} + +/** + * current_tail - Find block number of current log tail + * @sdp: The GFS superblock + * + * Find the block number of the current tail of the log. + * Assumes that the log lock is held. + * + * Returns: The tail's block number (must be on a log segment boundary) + */ + +static uint64_t +current_tail(struct gfs_sbd *sdp) +{ + struct gfs_trans *tr; + uint64_t tail; + + if (list_empty(&sdp->sd_log_ail)) { + tail = sdp->sd_log_head; + + if (!gfs_log_is_header(sdp, tail)) { + tail--; + gfs_assert(sdp, gfs_log_is_header(sdp, tail), ); + } + } else { + tr = list_entry(sdp->sd_log_ail.prev, + struct gfs_trans, tr_list); + tail = tr->tr_first_head; + } + + return tail; +} + +/** + * gfs_ail_empty - move the tail of the log forward (if possible) + * @sdp: the filesystem + * + * Returns: TRUE if the AIL is empty + * + * Checks each transaction on sd_log_ail, to see if it has been successfully + * flushed to in-place blocks on disk. If so, removes trans from sd_log_ail, + * effectively advancing the tail of the log (freeing log segments so they + * can be overwritten). + * Adds # freed log segments to sd_log_seg_free. + */ + +int +gfs_ail_empty(struct gfs_sbd *sdp) +{ + struct list_head *head, *tmp, *prev; + struct gfs_trans *tr; + uint64_t oldtail, newtail; + unsigned int dist; + unsigned int segments; + int ret; + + gfs_log_lock(sdp); + + oldtail = current_tail(sdp); + + for (head = &sdp->sd_log_ail, tmp = head->prev, prev = tmp->prev; + tmp != head; + tmp = prev, prev = tmp->prev) { + tr = list_entry(tmp, struct gfs_trans, tr_list); + if (gfs_ail_empty_trans(sdp, tr)) { + list_del(&tr->tr_list); + kfree(tr); + } + } + + newtail = current_tail(sdp); + + if (oldtail != newtail) { + dist = log_distance(sdp, newtail, oldtail); + + segments = dist / sdp->sd_sb.sb_seg_size; + gfs_assert(sdp, segments * sdp->sd_sb.sb_seg_size == dist,); + + sdp->sd_log_seg_ail2 += segments; + gfs_assert(sdp, sdp->sd_log_seg_free + sdp->sd_log_seg_ail2 <= + sdp->sd_jdesc.ji_nsegment,); + } + + ret = list_empty(head); + + gfs_log_unlock(sdp); + + return ret; +} + +/** + * gfs_log_reserve - Make a log reservation + * @sdp: The GFS superblock + * @segments: The number of segments to reserve + * @jump_queue: if TRUE, don't care about fairness ordering + * + * Returns: errno + */ + +int +gfs_log_reserve(struct gfs_sbd *sdp, unsigned int segments, int jump_queue) +{ + struct list_head list; + unsigned int try = 0; + + if (gfs_assert_warn(sdp, segments)) + return -EINVAL; + if (gfs_assert_warn(sdp, segments < sdp->sd_jdesc.ji_nsegment)) + return -EINVAL; + + INIT_LIST_HEAD(&list); + + for (;;) { + spin_lock(&sdp->sd_log_seg_lock); + + if (list_empty(&list)) { + if (jump_queue) + list_add(&list, &sdp->sd_log_seg_list); + else { + list_add_tail(&list, &sdp->sd_log_seg_list); + while (sdp->sd_log_seg_list.next != &list) { + DECLARE_WAITQUEUE(__wait_chan, current); + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&sdp->sd_log_seg_wait, + &__wait_chan); + spin_unlock(&sdp->sd_log_seg_lock); + schedule(); + spin_lock(&sdp->sd_log_seg_lock); + remove_wait_queue(&sdp->sd_log_seg_wait, + &__wait_chan); + set_current_state(TASK_RUNNING); + } + } + } + + if (sdp->sd_log_seg_free > segments) { + sdp->sd_log_seg_free -= segments; + list_del(&list); + spin_unlock(&sdp->sd_log_seg_lock); + wake_up(&sdp->sd_log_seg_wait); + break; + } + + spin_unlock(&sdp->sd_log_seg_lock); + + if (try) { + gfs_log_flush(sdp); + gfs_ail_start(sdp, 0); + } + + gfs_ail_empty(sdp); + + try++; + yield(); + } + + return 0; +} + +/** + * gfs_log_release - Release a given number of log segments + * @sdp: The GFS superblock + * @segments: The number of segments + * + */ + +void +gfs_log_release(struct gfs_sbd *sdp, unsigned int segments) +{ + spin_lock(&sdp->sd_log_seg_lock); + sdp->sd_log_seg_free += segments; + gfs_assert(sdp, sdp->sd_log_seg_free + sdp->sd_log_seg_ail2 <= + sdp->sd_jdesc.ji_nsegment,); + spin_unlock(&sdp->sd_log_seg_lock); +} + +/** + * log_get_header - Get and initialize a journal header buffer + * @sdp: The GFS superblock + * @tr: The transaction that needs a log header + * @next: FALSE if this log header appears in midst of current transaction + * TRUE if this starts next transaction (and commits current trans) + * + * Returns: the initialized log buffer descriptor + * + * Initialize one of the transaction's pre-allocated buffers (and associated + * log buffer descriptor) to be a log header for this transaction. + * A log header gets written to *each* log segment boundary block, so journal + * recovery will quickly be able to get its bearings. A single transaction + * may span several log segments, which means that log headers will appear + * in the midst of that transaction (@next == FALSE). These headers get + * added to trans' list of buffers to write to log. + * Log commit is accomplished by writing the log header for the next + * transaction (@next == TRUE), with pre-incremented sequence number, + * and updated first-in-transaction block number. These headers do *not* get + * added to trans' buffer list, since they are written separately to disk + * *after* the trans gets completely flushed to on-disk log. + * NOTE: This buffer will *not* get written to an in-place location in the + * filesystem; it is for use only within the log. + */ + +static struct gfs_log_buf * +log_get_header(struct gfs_sbd *sdp, struct gfs_trans *tr, int next) +{ + struct gfs_log_buf *lb; + struct list_head *bmem; + struct gfs_log_header header; + + /* Make sure we're on a log segment boundary block */ + gfs_assert(sdp, gfs_log_is_header(sdp, tr->tr_log_head),); + + /* Grab a free log buffer descriptor (attached to trans) */ + gfs_assert(sdp, tr->tr_num_free_bufs && + !list_empty(&tr->tr_free_bufs),); + lb = list_entry(tr->tr_free_bufs.next, struct gfs_log_buf, lb_list); + list_del(&lb->lb_list); + tr->tr_num_free_bufs--; + + /* Grab a free log buffer (attached to trans) */ + gfs_assert(sdp, tr->tr_num_free_bmem && + !list_empty(&tr->tr_free_bmem),); + bmem = tr->tr_free_bmem.next; + list_del(bmem); + tr->tr_num_free_bmem--; + + /* Create "fake" bh to write bmem to log header block */ + gfs_logbh_init(sdp, &lb->lb_bh, tr->tr_log_head, (char *)bmem); + memset(bmem, 0, sdp->sd_sb.sb_bsize); + + memset(&header, 0, sizeof (header)); + + if (next) { + /* Fill in header for next transaction, committing previous */ + header.lh_header.mh_magic = GFS_MAGIC; + header.lh_header.mh_type = GFS_METATYPE_LH; + header.lh_header.mh_format = GFS_FORMAT_LH; + header.lh_first = tr->tr_log_head; + header.lh_sequence = sdp->sd_sequence + 1; + header.lh_tail = current_tail(sdp); + header.lh_last_dump = sdp->sd_log_dump_last; + } else { + /* Fill in another header for this transaction */ + header.lh_header.mh_magic = GFS_MAGIC; + header.lh_header.mh_type = GFS_METATYPE_LH; + header.lh_header.mh_format = GFS_FORMAT_LH; + header.lh_first = tr->tr_first_head; + header.lh_sequence = sdp->sd_sequence; + header.lh_tail = current_tail(sdp); + header.lh_last_dump = sdp->sd_log_dump_last; + + /* Attach log header buf to trans' list of bufs going to log */ + list_add(&lb->lb_list, &tr->tr_bufs); + } + + /* Copy log header struct to beginning and end of buffer's 1st 512B */ + gfs_log_header_out(&header, lb->lb_bh.b_data); + gfs_log_header_out(&header, + lb->lb_bh.b_data + GFS_BASIC_BLOCK - + sizeof(struct gfs_log_header)); + + /* Find next log buffer to fill */ + log_incr_head(sdp, &tr->tr_log_head); + + return lb; +} + +/** + * gfs_log_get_buf - Get and initialize a buffer to use for log control data + * @sdp: The GFS superblock + * @tr: The GFS transaction + * + * Initialize one of the transaction's pre-allocated buffers (and associated + * log buffer descriptor) to be used for log control data (e.g. log tags). + * Make sure this buffer is attached to the transaction, to be logged to disk. + * NOTE: This buffer will *not* get written to an in-place location in the + * filesystem; it is for use only within the log. + * + * Returns: the log buffer descriptor + */ + +struct gfs_log_buf * +gfs_log_get_buf(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct gfs_log_buf *lb; + struct list_head *bmem; + + /* If next block in log is on a segment boundary, we need to + write a log header */ + if (gfs_log_is_header(sdp, tr->tr_log_head)) + log_get_header(sdp, tr, FALSE); + + /* Grab a free buffer descriptor (attached to trans) */ + gfs_assert(sdp, tr->tr_num_free_bufs && + !list_empty(&tr->tr_free_bufs),); + lb = list_entry(tr->tr_free_bufs.next, struct gfs_log_buf, lb_list); + list_del(&lb->lb_list); + tr->tr_num_free_bufs--; + + /* Grab a free buffer (attached to trans) */ + gfs_assert(sdp, tr->tr_num_free_bmem + && !list_empty(&tr->tr_free_bmem),); + bmem = tr->tr_free_bmem.next; + list_del(bmem); + tr->tr_num_free_bmem--; + + /* Create "fake" bh to write bmem to log block */ + gfs_logbh_init(sdp, &lb->lb_bh, tr->tr_log_head, (char *)bmem); + memset(bmem, 0, sdp->sd_sb.sb_bsize); + + list_add(&lb->lb_list, &tr->tr_bufs); + + /* Find next log buffer to fill */ + log_incr_head(sdp, &tr->tr_log_head); + + return lb; +} + +/** + * gfs_log_fake_buf - Build a fake buffer head to write metadata buffer to log + * @sdp: the filesystem + * @tr: the transaction this is part of + * @data: the data the buffer_head should point to + * @unlock: a buffer_head to be unlocked when struct gfs_log_buf is torn down + * (i.e. the "real" buffer_head that will write to in-place location) + * + * Initialize one of the transaction's pre-allocated log buffer descriptors + * to be used for writing a metadata buffer into the log. + * Make sure this buffer is attached to the transaction, to be logged to disk. + * NOTE: This buffer *will* be written to in-place location within filesytem, + * in addition to being written into the log. + * + */ + +void +gfs_log_fake_buf(struct gfs_sbd *sdp, struct gfs_trans *tr, char *data, + struct buffer_head *unlock) +{ + struct gfs_log_buf *lb; + + if (gfs_log_is_header(sdp, tr->tr_log_head)) + log_get_header(sdp, tr, FALSE); + + /* Grab a free buffer descriptor (attached to trans) */ + gfs_assert(sdp, tr->tr_num_free_bufs && + !list_empty(&tr->tr_free_bufs),); + lb = list_entry(tr->tr_free_bufs.next, struct gfs_log_buf, lb_list); + list_del(&lb->lb_list); + tr->tr_num_free_bufs--; + + /* Create "fake" bh to write data to log block */ + gfs_logbh_init(sdp, &lb->lb_bh, tr->tr_log_head, data); + lb->lb_unlock = unlock; + + list_add(&lb->lb_list, &tr->tr_bufs); + + /* Find next log buffer to fill */ + log_incr_head(sdp, &tr->tr_log_head); +} + +/** + * check_seg_usage - Check that we didn't use too many segments + * @sdp: The GFS superblock + * @tr: The transaction + * + * Also, make sure we don't write ever get to a point where there are + * no dumps in the log (corrupting the log). Panic before we let + * that happen. + * + */ + +static void +check_seg_usage(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct gfs_jindex *jdesc = &sdp->sd_jdesc; + unsigned int dist; + unsigned int segments; + uint64_t head_off, head_wrap; + uint64_t dump_off, dump_wrap; + + dist = log_distance(sdp, tr->tr_log_head, tr->tr_first_head); + + segments = dist / sdp->sd_sb.sb_seg_size; + gfs_assert(sdp, segments * sdp->sd_sb.sb_seg_size == dist,); + gfs_assert(sdp, segments == tr->tr_seg_reserved,); + + if (sdp->sd_log_dump_last) { + int diff; + + head_off = tr->tr_first_head + + tr->tr_seg_reserved * sdp->sd_sb.sb_seg_size; + head_wrap = sdp->sd_log_wrap; + if (head_off >= jdesc->ji_addr + + jdesc->ji_nsegment * sdp->sd_sb.sb_seg_size) { + head_off -= jdesc->ji_nsegment * sdp->sd_sb.sb_seg_size; + head_wrap++; + } + + dump_off = sdp->sd_log_dump_last; + dump_wrap = sdp->sd_log_dump_last_wrap; + + diff = (int)(head_wrap - dump_wrap); + switch (diff) { + case 0: + break; + + case 1: + if (head_off < dump_off - sdp->sd_sb.sb_seg_size) + break; + else if (head_off <= dump_off && + (tr->tr_flags & TRF_LOG_DUMP)) + break; + + default: + gfs_assert(sdp, FALSE, + printk("GFS: fsid=%s: head_off = %"PRIu64", head_wrap = %"PRIu64"\n" + "GFS: fsid=%s: dump_off = %"PRIu64", dump_wrap = %"PRIu64"\n", + sdp->sd_fsname, head_off, head_wrap, + sdp->sd_fsname, dump_off, dump_wrap);); + break; + } + } +} + +/** + * log_free_buf - Free a struct gfs_log_buf (and possibly the data it points to) + * @sdp: the filesystem + * @lb: the log buffer descriptor + * + * If buffer contains (meta)data to be written into filesystem in-place block, + * descriptor will point to the "real" (lb_unlock) buffer head. Unlock it. + * If buffer was used only for log header or control data (e.g. tags), we're + * done with it as soon as it gets written to on-disk log. Free it. + * Either way, we can free the log descriptor structure. + */ + +static void +log_free_buf(struct gfs_sbd *sdp, struct gfs_log_buf *lb) +{ + char *bmem; + + bmem = lb->lb_bh.b_data; + gfs_logbh_uninit(sdp, &lb->lb_bh); + + if (lb->lb_unlock) + gfs_unlock_buffer(lb->lb_unlock); + else + kfree(bmem); + + kfree(lb); +} + +/** + * sync_trans - Add "last" descriptor, sync transaction to on-disk log + * @sdp: The GFS superblock + * @tr: The transaction + * + * Add the "last" descriptor onto the end of the current transaction + * and sync the whole transaction out to on-disk log. + * Don't log-commit (i.e. write next transaction's log header) yet, though. + * + * Returns: errno + */ + +static int +sync_trans(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct list_head *tmp, *head, *prev; + struct gfs_log_descriptor desc; + struct gfs_log_buf *lb; + uint64_t blk; + int error = 0, e; + + /* Build LAST descriptor */ + + lb = gfs_log_get_buf(sdp, tr); + + memset(&desc, 0, sizeof(struct gfs_log_descriptor)); + desc.ld_header.mh_magic = GFS_MAGIC; + desc.ld_header.mh_type = GFS_METATYPE_LD; + desc.ld_header.mh_format = GFS_FORMAT_LD; + desc.ld_type = GFS_LOG_DESC_LAST; + desc.ld_length = 1; + for (blk = tr->tr_log_head; !gfs_log_is_header(sdp, blk); blk++) + desc.ld_length++; + gfs_desc_out(&desc, lb->lb_bh.b_data); + + while (!gfs_log_is_header(sdp, tr->tr_log_head)) + log_incr_head(sdp, &tr->tr_log_head); + + check_seg_usage(sdp, tr); + + /* Start I/O + Go in "prev" direction to start the I/O in order. */ + + for (head = &tr->tr_bufs, tmp = head->prev, prev = tmp->prev; + tmp != head; + tmp = prev, prev = tmp->prev) { + lb = list_entry(tmp, struct gfs_log_buf, lb_list); + gfs_logbh_start(sdp, &lb->lb_bh); + } + + /* Wait on I/O + Go in "next" direction to minimize sleeps/wakeups. */ + + while (!list_empty(&tr->tr_bufs)) { + lb = list_entry(tr->tr_bufs.next, struct gfs_log_buf, lb_list); + + e = gfs_logbh_wait(sdp, &lb->lb_bh); + if (e) + error = e; + + list_del(&lb->lb_list); + log_free_buf(sdp, lb); + } + + return error; +} + +/** + * commit_trans - Commit the current transaction + * @sdp: The GFS superblock + * @tr: The transaction + * + * Write next header to commit + * + * Returns: errno + */ + +static int +commit_trans(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct gfs_log_buf *lb; + int error; + + lb = log_get_header(sdp, tr, TRUE); + + gfs_logbh_start(sdp, &lb->lb_bh); + error = gfs_logbh_wait(sdp, &lb->lb_bh); + if (!error) { + spin_lock(&sdp->sd_log_seg_lock); + if (!(tr->tr_flags & TRF_DUMMY)) + sdp->sd_log_seg_free += sdp->sd_log_seg_ail2; + else + sdp->sd_log_seg_free += (sdp->sd_log_seg_ail2 - 1); + sdp->sd_log_seg_ail2 = 0; + spin_unlock(&sdp->sd_log_seg_lock); + } + log_free_buf(sdp, lb); + + return error; +} + +/** + * disk_commit - Write a transaction to the on-disk journal + * @sdp: The GFS superblock + * @tr: The transaction + * + * Returns: errno + */ + +static int +disk_commit(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + uint64_t last_dump, last_dump_wrap; + int error = 0; + + gfs_assert(sdp, !test_bit(SDF_ROFS, &sdp->sd_flags),); + tr->tr_log_head = sdp->sd_log_head; + tr->tr_first_head = tr->tr_log_head - 1; + gfs_assert(sdp, gfs_log_is_header(sdp, tr->tr_first_head),); + + LO_BUILD_BHLIST(sdp, tr); + + if (!(tr->tr_flags & TRF_DUMMY)) + gfs_assert(sdp, !list_empty(&tr->tr_bufs),); + + error = sync_trans(sdp, tr); + if (error) { + /* Eat unusable commit buffer */ + log_free_buf(sdp, log_get_header(sdp, tr, TRUE)); + goto out; + } + + if (tr->tr_flags & TRF_LOG_DUMP) { + /* This commit header should point to the log dump we're + commiting as the current one. But save the copy of the + old one in case we have problems commiting the dump. */ + + last_dump = sdp->sd_log_dump_last; + last_dump_wrap = sdp->sd_log_dump_last_wrap; + + sdp->sd_log_dump_last = tr->tr_first_head; + sdp->sd_log_dump_last_wrap = sdp->sd_log_wrap; + + error = commit_trans(sdp, tr); + if (error) { + sdp->sd_log_dump_last = last_dump; + sdp->sd_log_dump_last_wrap = last_dump_wrap; + goto out; + } + } else { + error = commit_trans(sdp, tr); + if (error) + goto out; + } + + if (sdp->sd_log_head > tr->tr_log_head) + sdp->sd_log_wrap++; + sdp->sd_log_head = tr->tr_log_head; + sdp->sd_sequence++; + + out: + gfs_assert_warn(sdp, !tr->tr_num_free_bufs && + list_empty(&tr->tr_free_bufs)); + gfs_assert_warn(sdp, !tr->tr_num_free_bmem && + list_empty(&tr->tr_free_bmem)); + + return error; +} + +/** + * add_trans_to_ail - Add a ondisk commited transaction to the AIL + * @sdp: the filesystem + * @tr: the transaction + * + */ + +static void +add_trans_to_ail(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct gfs_log_element *le; + + while (!list_empty(&tr->tr_elements)) { + le = list_entry(tr->tr_elements.next, + struct gfs_log_element, le_list); + LO_ADD_TO_AIL(sdp, le); + } + + list_add(&tr->tr_list, &sdp->sd_log_ail); +} + +/** + * log_refund - Refund log segments to the free pool + * @sdp: The GFS superblock + * @tr: The transaction to examine + * + * Look at the number of segments reserved for this transaction and the + * number of segments actually needed for it. If they aren't the + * same, refund the difference to the free segment pool. + * + * De-alloc any unneeded log buffers and log buffer descriptors. + * + * Called with the log lock held. + */ + +static void +log_refund(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct gfs_log_buf *lb; + struct list_head *bmem; + unsigned int num_bufs = 0, num_bmem = 0; + unsigned int segments; + + LO_TRANS_SIZE(sdp, tr, NULL, NULL, &num_bufs, &num_bmem); + + segments = gfs_blk2seg(sdp, num_bufs + 1); + num_bufs += segments + 1; + num_bmem += segments + 1; + + /* Unreserve unneeded log segments */ + if (tr->tr_seg_reserved > segments) { + spin_lock(&sdp->sd_log_seg_lock); + sdp->sd_log_seg_free += tr->tr_seg_reserved - segments; + gfs_assert(sdp, sdp->sd_log_seg_free + sdp->sd_log_seg_ail2 <= + sdp->sd_jdesc.ji_nsegment,); + spin_unlock(&sdp->sd_log_seg_lock); + + tr->tr_seg_reserved = segments; + } else + gfs_assert(sdp, tr->tr_seg_reserved == segments,); + + /* De-alloc unneeded log buffer descriptors */ + gfs_assert(sdp, tr->tr_num_free_bufs >= num_bufs,); + while (tr->tr_num_free_bufs > num_bufs) { + lb = list_entry(tr->tr_free_bufs.next, + struct gfs_log_buf, lb_list); + list_del(&lb->lb_list); + kfree(lb); + tr->tr_num_free_bufs--; + } + + /* De-alloc unneeded log buffers */ + gfs_assert(sdp, tr->tr_num_free_bmem >= num_bmem,); + while (tr->tr_num_free_bmem > num_bmem) { + bmem = tr->tr_free_bmem.next; + list_del(bmem); + kfree(bmem); + tr->tr_num_free_bmem--; + } +} + +/** + * trans_combine - combine two transactions + * @sdp: the filesystem + * @tr: the surviving transaction + * @new_tr: the transaction that gets freed + * + * Assumes that the two transactions are independent. + */ + +static void +trans_combine(struct gfs_sbd *sdp, struct gfs_trans *tr, + struct gfs_trans *new_tr) +{ + struct gfs_log_element *le; + struct gfs_log_buf *lb; + struct list_head *bmem; + + tr->tr_file = __FILE__; + tr->tr_line = __LINE__; + tr->tr_seg_reserved += new_tr->tr_seg_reserved; + tr->tr_flags |= new_tr->tr_flags; + tr->tr_num_free_bufs += new_tr->tr_num_free_bufs; + tr->tr_num_free_bmem += new_tr->tr_num_free_bmem; + + /* Combine the log elements of the two transactions */ + + while (!list_empty(&new_tr->tr_elements)) { + le = list_entry(new_tr->tr_elements.next, + struct gfs_log_element, le_list); + gfs_assert(sdp, le->le_trans == new_tr,); + le->le_trans = tr; + list_move(&le->le_list, &tr->tr_elements); + } + + LO_TRANS_COMBINE(sdp, tr, new_tr); + + /* Move free log buffer descriptors to surviving trans */ + while (!list_empty(&new_tr->tr_free_bufs)) { + lb = list_entry(new_tr->tr_free_bufs.next, + struct gfs_log_buf, lb_list); + list_move(&lb->lb_list, &tr->tr_free_bufs); + new_tr->tr_num_free_bufs--; + } + /* Move free log buffers to surviving trans */ + while (!list_empty(&new_tr->tr_free_bmem)) { + bmem = new_tr->tr_free_bmem.next; + list_move(bmem, &tr->tr_free_bmem); + new_tr->tr_num_free_bmem--; + } + + gfs_assert_warn(sdp, !new_tr->tr_num_free_bufs); + gfs_assert_warn(sdp, !new_tr->tr_num_free_bmem); + + kfree(new_tr); +} + +static void +make_dummy_transaction(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct gfs_log_buf *lb; + struct list_head *bmem; + + memset(tr, 0, sizeof(struct gfs_trans)); + INIT_LIST_HEAD(&tr->tr_list); + INIT_LIST_HEAD(&tr->tr_elements); + INIT_LIST_HEAD(&tr->tr_free_bufs); + INIT_LIST_HEAD(&tr->tr_free_bmem); + INIT_LIST_HEAD(&tr->tr_bufs); + INIT_LIST_HEAD(&tr->tr_ail_bufs); + tr->tr_flags = TRF_DUMMY; + tr->tr_file = __FILE__; + tr->tr_line = __LINE__; + tr->tr_seg_reserved = 1; + while (tr->tr_num_free_bufs < 2) { + lb = gmalloc(sizeof(struct gfs_log_buf)); + memset(lb, 0, sizeof(struct gfs_log_buf)); + list_add(&lb->lb_list, &tr->tr_free_bufs); + tr->tr_num_free_bufs++; + } + while (tr->tr_num_free_bmem < 2) { + bmem = gmalloc(sdp->sd_sb.sb_bsize); + list_add(bmem, &tr->tr_free_bmem); + tr->tr_num_free_bmem++; + } +} + + +/** + * log_flush_internal - flush incore transaction(s) + * @sdp: the filesystem + * @gl: The glock structure to flush. If NULL, flush the whole incore log + * + * If a glock is provided, we flush, to on-disk log, all of the metadata for + * the one incore-committed (complete, but not-yet-flushed-to-log) + * transaction that the glock protects. + * If NULL, we combine *all* of the filesystem's incore-committed + * transactions into one big transaction, and flush it to the log. + */ + +static void +log_flush_internal(struct gfs_sbd *sdp, struct gfs_glock *gl) +{ + + struct gfs_trans *trans = NULL, *tr; + int error; + + gfs_log_lock(sdp); + + if (!gl && list_empty(&sdp->sd_log_incore)) { + if (sdp->sd_log_seg_ail2) { + trans = gmalloc(sizeof(struct gfs_trans)); + make_dummy_transaction(sdp, trans); + } + else + goto out; + } + + if (gl) { + if (!gl->gl_incore_le.le_trans) + goto out; + + trans = gl->gl_incore_le.le_trans; + + list_del(&trans->tr_list); + } else { + /* combine *all* transactions in incore list */ + while (!list_empty(&sdp->sd_log_incore)) { + tr = list_entry(sdp->sd_log_incore.next, + struct gfs_trans, tr_list); + + list_del(&tr->tr_list); + + if (trans) + trans_combine(sdp, trans, tr); + else + trans = tr; + } + } + + log_refund(sdp, trans); + + /* Actually do the stuff to commit the transaction */ + + error = disk_commit(sdp, trans); + if (error) + gfs_io_error(sdp); + + add_trans_to_ail(sdp, trans); + + if (log_distance(sdp, sdp->sd_log_head, sdp->sd_log_dump_last) * GFS_DUMPS_PER_LOG >= + sdp->sd_jdesc.ji_nsegment * sdp->sd_sb.sb_seg_size) + set_bit(SDF_NEED_LOG_DUMP, &sdp->sd_flags); + + out: + if (list_empty(&sdp->sd_log_incore)) + sdp->sd_vfs->s_dirt = FALSE; + + gfs_log_unlock(sdp); + + /* Dump if we need to. */ + + if (test_bit(SDF_NEED_LOG_DUMP, &sdp->sd_flags)) + gfs_log_dump(sdp, FALSE); +} + +/** + * gfs_log_flush - flush the whole incore log + * @sdp: the filesystem + * + */ + +void +gfs_log_flush(struct gfs_sbd *sdp) +{ + log_flush_internal(sdp, NULL); +} + +/** + * gfs_log_flush_glock - flush the incore log for a glock + * @gl: the glock + * + */ + +void +gfs_log_flush_glock(struct gfs_glock *gl) +{ + log_flush_internal(gl->gl_sbd, gl); +} + +/** + * incore_commit - commit a transaction in-core + * @sdp: the filesystem + * @new_tr: the transaction to commit + * + * Add the transaction @new_tr to the end of the incore commit list. + * Pull up and merge any previously committed transactions that share + * locks. Also pull up any rename transactions that need it. + */ + +static void +incore_commit(struct gfs_sbd *sdp, struct gfs_trans *new_tr) +{ + struct gfs_log_element *le; + struct gfs_trans *trans = NULL, *exist_tr; + struct gfs_log_buf *lb; + struct list_head *bmem; + struct list_head *tmp, *head, *next; + + for (head = &new_tr->tr_elements, tmp = head->next; + tmp != head; + tmp = tmp->next) { + le = list_entry(tmp, struct gfs_log_element, le_list); + + /* Do overlap_trans log-op, if any, to find another + incore transaction with which we can combine new_tr */ + exist_tr = LO_OVERLAP_TRANS(sdp, le); + if (!exist_tr) + continue; + + if (exist_tr != trans) { + /* remove trans from superblock's sd_log_incore list */ + list_del(&exist_tr->tr_list); + + /* Maybe there's more than one that can be combined. + If so, combine them together before merging new_tr */ + if (trans) + trans_combine(sdp, trans, exist_tr); + else + trans = exist_tr; + } + } + + /* Yes, we can combine new_tr with pre-existing transaction(s) */ + if (trans) { + trans->tr_file = __FILE__; + trans->tr_line = __LINE__; + trans->tr_seg_reserved += new_tr->tr_seg_reserved; + trans->tr_flags |= new_tr->tr_flags; + trans->tr_num_free_bufs += new_tr->tr_num_free_bufs; + trans->tr_num_free_bmem += new_tr->tr_num_free_bmem; + + /* Move free log buffer descriptors to surviving trans */ + while (!list_empty(&new_tr->tr_free_bufs)) { + lb = list_entry(new_tr->tr_free_bufs.next, + struct gfs_log_buf, lb_list); + list_move(&lb->lb_list, &trans->tr_free_bufs); + new_tr->tr_num_free_bufs--; + } + + /* Move free log buffers to surviving trans */ + while (!list_empty(&new_tr->tr_free_bmem)) { + bmem = new_tr->tr_free_bmem.next; + list_move(bmem, &trans->tr_free_bmem); + new_tr->tr_num_free_bmem--; + } + } else + trans = new_tr; + + /* Do incore_commit log-op for each *new* log element (in new_tr). + Each commit log-op removes its log element from "new_tr" LE list, + and attaches an LE to "trans" LE list; if there was no trans + combining, "new_tr" is the same transaction as "trans". */ + for (head = &new_tr->tr_elements, tmp = head->next, next = tmp->next; + tmp != head; + tmp = next, next = next->next) { + le = list_entry(tmp, struct gfs_log_element, le_list); + LO_INCORE_COMMIT(sdp, trans, le); + } + + /* If we successfully combined transactions, new_tr should be empty */ + if (trans != new_tr) { + gfs_assert_warn(sdp, !new_tr->tr_num_free_bufs); + gfs_assert_warn(sdp, !new_tr->tr_num_free_bmem); + gfs_assert_warn(sdp, list_empty(&new_tr->tr_elements)); + kfree(new_tr); + } + + /* If we successfully combined transactions, we might have some log + segments that we reserved, and log buffers and buffer descriptors + that we allocated, but now don't need. */ + log_refund(sdp, trans); + + list_add(&trans->tr_list, &sdp->sd_log_incore); +} + +/** + * gfs_log_commit - Commit a transaction to the log + * @sdp: the filesystem + * @tr: the transaction + * + * Returns: errno + */ + +void +gfs_log_commit(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct gfs_log_buf *lb; + struct list_head *bmem; + unsigned int num_mblks = 0, num_eblks = 0, num_bufs = 0, num_bmem = 0; + unsigned int segments; + + /* Calculate actual log area needed for this trans */ + LO_TRANS_SIZE(sdp, tr, &num_mblks, &num_eblks, &num_bufs, &num_bmem); + + gfs_assert(sdp, num_mblks <= tr->tr_mblks_asked && + num_eblks <= tr->tr_eblks_asked, + printk("GFS: fsid=%s: type = (%s, %u)\n" + "GFS: fsid=%s: num_mblks = %u, tr->tr_mblks_asked = %u\n" + "GFS: fsid=%s: num_eblks = %u, tr->tr_eblks_asked = %u\n", + sdp->sd_fsname, tr->tr_file, tr->tr_line, + sdp->sd_fsname, num_mblks, tr->tr_mblks_asked, + sdp->sd_fsname, num_eblks, tr->tr_eblks_asked);); + + segments = gfs_blk2seg(sdp, num_bufs + 1); + num_bufs += segments + 1; + num_bmem += segments + 1; + + /* Alloc log buffer descriptors */ + while (num_bufs--) { + lb = gmalloc(sizeof(struct gfs_log_buf)); + memset(lb, 0, sizeof(struct gfs_log_buf)); + list_add(&lb->lb_list, &tr->tr_free_bufs); + tr->tr_num_free_bufs++; + } + /* Alloc log buffers */ + while (num_bmem--) { + bmem = gmalloc(sdp->sd_sb.sb_bsize); + list_add(bmem, &tr->tr_free_bmem); + tr->tr_num_free_bmem++; + } + + gfs_log_lock(sdp); + + incore_commit(sdp, tr); + + /* Flush log buffers to disk if we're over the threshold */ + if (sdp->sd_log_buffers > gfs_tune_get(sdp, gt_incore_log_blocks)) { + gfs_log_unlock(sdp); + gfs_log_flush(sdp); + } else { + sdp->sd_vfs->s_dirt = TRUE; + gfs_log_unlock(sdp); + } + +} + +/** + * gfs_log_dump - make a Log Dump entry in the log + * @sdp: the filesystem + * @force: if TRUE, always make the dump even if one has been made recently + * + */ + +void +gfs_log_dump(struct gfs_sbd *sdp, int force) +{ + struct gfs_log_element *le; + struct gfs_trans tr; + struct gfs_log_buf *lb; + struct list_head *bmem; + unsigned int num_bufs, num_bmem; + unsigned int segments; + int error; + + if (test_and_set_bit(SDF_IN_LOG_DUMP, &sdp->sd_flags)) { + gfs_assert(sdp, !force,); + return; + } + + memset(&tr, 0, sizeof(struct gfs_trans)); + INIT_LIST_HEAD(&tr.tr_elements); + INIT_LIST_HEAD(&tr.tr_free_bufs); + INIT_LIST_HEAD(&tr.tr_free_bmem); + INIT_LIST_HEAD(&tr.tr_bufs); + tr.tr_flags = TRF_LOG_DUMP; + tr.tr_file = __FILE__; + tr.tr_line = __LINE__; + + for (;;) { + gfs_log_lock(sdp); + + if (!force && !test_bit(SDF_NEED_LOG_DUMP, &sdp->sd_flags)) + goto out; + + num_bufs = num_bmem = 0; + LO_DUMP_SIZE(sdp, NULL, &num_bufs, &num_bmem); + gfs_assert(sdp, num_bufs,); + segments = gfs_blk2seg(sdp, num_bufs + 1); + num_bufs += segments + 1; + num_bmem += segments + 1; + + if (tr.tr_seg_reserved >= segments && + tr.tr_num_free_bufs >= num_bufs && + tr.tr_num_free_bmem >= num_bmem) + break; + + gfs_log_unlock(sdp); + + if (tr.tr_seg_reserved < segments) { + error = gfs_log_reserve(sdp, + segments - tr.tr_seg_reserved, + TRUE); + gfs_assert(sdp, !error,); + tr.tr_seg_reserved = segments; + } + while (tr.tr_num_free_bufs < num_bufs) { + lb = gmalloc(sizeof(struct gfs_log_buf)); + memset(lb, 0, sizeof(struct gfs_log_buf)); + list_add(&lb->lb_list, &tr.tr_free_bufs); + tr.tr_num_free_bufs++; + } + while (tr.tr_num_free_bmem < num_bmem) { + bmem = gmalloc(sdp->sd_sb.sb_bsize); + list_add(bmem, &tr.tr_free_bmem); + tr.tr_num_free_bmem++; + } + } + + if (tr.tr_seg_reserved > segments) { + spin_lock(&sdp->sd_log_seg_lock); + sdp->sd_log_seg_free += tr.tr_seg_reserved - segments; + gfs_assert(sdp, sdp->sd_log_seg_free + sdp->sd_log_seg_ail2 <= + sdp->sd_jdesc.ji_nsegment,); + spin_unlock(&sdp->sd_log_seg_lock); + tr.tr_seg_reserved = segments; + } + while (tr.tr_num_free_bufs > num_bufs) { + lb = list_entry(tr.tr_free_bufs.next, + struct gfs_log_buf, lb_list); + list_del(&lb->lb_list); + kfree(lb); + tr.tr_num_free_bufs--; + } + while (tr.tr_num_free_bmem > num_bmem) { + bmem = tr.tr_free_bmem.next; + list_del(bmem); + kfree(bmem); + tr.tr_num_free_bmem--; + } + + LO_BUILD_DUMP(sdp, &tr); + + error = disk_commit(sdp, &tr); + if (error) + gfs_io_error(sdp); + + while (!list_empty(&tr.tr_elements)) { + le = list_entry(tr.tr_elements.next, + struct gfs_log_element, le_list); + LO_CLEAN_DUMP(sdp, le); + } + + /* If there isn't anything in the AIL, we won't get back the log + space we reserved unless we do it ourselves. */ + + if (list_empty(&sdp->sd_log_ail)) { + spin_lock(&sdp->sd_log_seg_lock); + sdp->sd_log_seg_free += tr.tr_seg_reserved; + gfs_assert(sdp, sdp->sd_log_seg_free + sdp->sd_log_seg_ail2 <= + sdp->sd_jdesc.ji_nsegment,); + spin_unlock(&sdp->sd_log_seg_lock); + } + + clear_bit(SDF_NEED_LOG_DUMP, &sdp->sd_flags); + + out: + gfs_log_unlock(sdp); + clear_bit(SDF_IN_LOG_DUMP, &sdp->sd_flags); +} + +/** + * gfs_log_shutdown - write a shutdown header into a journal + * @sdp: the filesystem + * + */ + +void +gfs_log_shutdown(struct gfs_sbd *sdp) +{ + struct gfs_log_buf *lb; + char *bmem; + struct gfs_log_header head; + struct gfs_log_descriptor desc; + unsigned int elements = 0; + int error; + + lb = gmalloc(sizeof(struct gfs_log_buf)); + memset(lb, 0, sizeof(struct gfs_log_buf)); + bmem = gmalloc(sdp->sd_sb.sb_bsize); + + gfs_log_lock(sdp); + + gfs_assert_withdraw(sdp, list_empty(&sdp->sd_log_ail)); + gfs_assert_withdraw(sdp, sdp->sd_log_seg_free + sdp->sd_log_seg_ail2 == + sdp->sd_jdesc.ji_nsegment); + gfs_assert_withdraw(sdp, !sdp->sd_log_buffers); + gfs_assert_withdraw(sdp, gfs_log_is_header(sdp, sdp->sd_log_head - 1)); + if (test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) + goto out; + + /* Build a "last" log descriptor */ + + memset(&desc, 0, sizeof(struct gfs_log_descriptor)); + desc.ld_header.mh_magic = GFS_MAGIC; + desc.ld_header.mh_type = GFS_METATYPE_LD; + desc.ld_header.mh_format = GFS_FORMAT_LD; + desc.ld_type = GFS_LOG_DESC_LAST; + desc.ld_length = sdp->sd_sb.sb_seg_size - 1; + + /* Write the descriptor */ + + gfs_logbh_init(sdp, &lb->lb_bh, sdp->sd_log_head, bmem); + memset(bmem, 0, sdp->sd_sb.sb_bsize); + gfs_desc_out(&desc, lb->lb_bh.b_data); + gfs_logbh_start(sdp, &lb->lb_bh); + error = gfs_logbh_wait(sdp, &lb->lb_bh); + gfs_logbh_uninit(sdp, &lb->lb_bh); + + if (error) + goto out; + + /* Move to the next header */ + + while (!gfs_log_is_header(sdp, sdp->sd_log_head)) + log_incr_head(sdp, &sdp->sd_log_head); + + LO_DUMP_SIZE(sdp, &elements, NULL, NULL); + + /* Build the shutdown header */ + + memset(&head, 0, sizeof (struct gfs_log_header)); + head.lh_header.mh_magic = GFS_MAGIC; + head.lh_header.mh_type = GFS_METATYPE_LH; + head.lh_header.mh_format = GFS_FORMAT_LH; + head.lh_flags = GFS_LOG_HEAD_UNMOUNT; + head.lh_first = sdp->sd_log_head; + head.lh_sequence = sdp->sd_sequence + 1; + /* Don't care about tail */ + head.lh_last_dump = (elements) ? sdp->sd_log_dump_last : 0; + + /* Write out the shutdown header */ + + gfs_logbh_init(sdp, &lb->lb_bh, sdp->sd_log_head, bmem); + memset(bmem, 0, sdp->sd_sb.sb_bsize); + gfs_log_header_out(&head, lb->lb_bh.b_data); + gfs_log_header_out(&head, + lb->lb_bh.b_data + GFS_BASIC_BLOCK - + sizeof(struct gfs_log_header)); + gfs_logbh_start(sdp, &lb->lb_bh); + gfs_logbh_wait(sdp, &lb->lb_bh); + gfs_logbh_uninit(sdp, &lb->lb_bh); + + /* If a withdraw is called before we've a chance to relock the trans + * lock, the sd_log_head points to the wrong place, and a umount will + * fail on asserts because of this. + * Adding one puts sd_log_head at a value that passes the assert. The + * value may not be correct for on disk, but we've withdrawn so there is + * no more disk io. + * If we're not withdrawn, the next io will grab the trans lock, which + * will fill sd_log_head with the correct value. + */ + sdp->sd_log_head += 1; + + out: + gfs_log_unlock(sdp); + + kfree(lb); + kfree(bmem); +} --- linux-2.6.28.orig/ubuntu/gfs/inode.h +++ linux-2.6.28/ubuntu/gfs/inode.h @@ -0,0 +1,57 @@ +#ifndef __INODE_DOT_H__ +#define __INODE_DOT_H__ + +void gfs_inode_attr_in(struct gfs_inode *ip); +void gfs_inode_attr_out(struct gfs_inode *ip); +struct inode *gfs_iget(struct gfs_inode *ip, int create); + +int gfs_copyin_dinode(struct gfs_inode *ip); + +int gfs_inode_get(struct gfs_glock *i_gl, struct gfs_inum *inum, int create, + struct gfs_inode **ipp); +void gfs_inode_hold(struct gfs_inode *ip); +void gfs_inode_put(struct gfs_inode *ip); +void gfs_inode_destroy(struct gfs_inode *ip); + +int gfs_inode_dealloc(struct gfs_sbd *sdp, struct gfs_inum *inum); + +int gfs_change_nlink(struct gfs_inode *ip, int diff); +int gfs_lookupi(struct gfs_holder *d_gh, struct qstr *name, + int is_root, struct gfs_holder *i_gh); +int gfs_createi(struct gfs_holder *d_gh, struct qstr *name, + unsigned int type, unsigned int mode, + struct gfs_holder *i_gh); +int gfs_unlinki(struct gfs_inode *dip, struct qstr *name, struct gfs_inode *ip); +int gfs_rmdiri(struct gfs_inode *dip, struct qstr *name, struct gfs_inode *ip); +int gfs_unlink_ok(struct gfs_inode *dip, struct qstr *name, + struct gfs_inode *ip); +int gfs_ok_to_move(struct gfs_inode *this, struct gfs_inode *to); +int gfs_readlinki(struct gfs_inode *ip, char **buf, unsigned int *len); + +int gfs_glock_nq_atime(struct gfs_holder *gh); +int gfs_glock_nq_m_atime(unsigned int num_gh, struct gfs_holder *ghs); + +void gfs_try_toss_vnode(struct gfs_inode *ip); + +int gfs_setattr_simple(struct gfs_inode *ip, struct iattr *attr); + +/* Backwards compatibility functions */ + +int gfs_alloc_qinode(struct gfs_sbd *sdp); +int gfs_alloc_linode(struct gfs_sbd *sdp); + +/* Inlines */ + +static __inline__ int +gfs_is_stuffed(struct gfs_inode *ip) +{ + return !ip->i_di.di_height; +} + +static __inline__ int +gfs_is_jdata(struct gfs_inode *ip) +{ + return ip->i_di.di_flags & GFS_DIF_JDATA; +} + +#endif /* __INODE_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/gfs_ioctl.h +++ linux-2.6.28/ubuntu/gfs/gfs_ioctl.h @@ -0,0 +1,31 @@ +#ifndef __GFS_IOCTL_DOT_H__ +#define __GFS_IOCTL_DOT_H__ + +#define _GFSC_(x) (('G' << 8) | (x)) + +/* Ioctls implemented */ + +#define GFS_IOCTL_IDENTIFY _GFSC_(35) +#define GFS_IOCTL_SUPER _GFSC_(45) + +struct gfs_ioctl { + unsigned int gi_argc; + char **gi_argv; + + char __user *gi_data; + unsigned int gi_size; + uint64_t gi_offset; +}; + +#ifdef CONFIG_COMPAT +struct gfs_ioctl_compat { + unsigned int gi_argc; + uint32_t gi_argv; + + uint32_t gi_data; + unsigned int gi_size; + uint64_t gi_offset; +}; +#endif + +#endif /* ___GFS_IOCTL_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/main.c +++ linux-2.6.28/ubuntu/gfs/main.c @@ -0,0 +1,134 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "ops_fstype.h" +#include "sys.h" +#include "proc.h" + +/** + * init_gfs_fs - Register GFS as a filesystem + * + * Returns: 0 on success, error code on failure + */ + +int __init init_gfs_fs(void) +{ + int error; + struct timespec tv; + +/* gfs2_init_lmh(); gfs2 should do this for us*/ + + error = gfs_sys_init(); + if (error) + return error; + error = gfs_proc_init(); + if (error) + goto fail; + + getnstimeofday(&tv); + gfs_random_number = tv.tv_nsec; + + gfs_glock_cachep = kmem_cache_create("gfs_glock", sizeof(struct gfs_glock), + 0, 0, + NULL); + gfs_inode_cachep = NULL; + gfs_bufdata_cachep = NULL; + gfs_mhc_cachep = NULL; + error = -ENOMEM; + if (!gfs_glock_cachep) + goto fail1; + + gfs_inode_cachep = kmem_cache_create("gfs_inode", sizeof(struct gfs_inode), + 0, 0, + NULL); + if (!gfs_inode_cachep) + goto fail1; + + gfs_bufdata_cachep = kmem_cache_create("gfs_bufdata", sizeof(struct gfs_bufdata), + 0, 0, + NULL); + if (!gfs_bufdata_cachep) + goto fail1; + + gfs_mhc_cachep = kmem_cache_create("gfs_meta_header_cache", sizeof(struct gfs_meta_header_cache), + 0, 0, + NULL); + if (!gfs_mhc_cachep) + goto fail; + + error = register_filesystem(&gfs_fs_type); + if (error) + goto fail; + + printk("GFS %s (built %s %s) installed\n", + RELEASE_VERSION, __DATE__, __TIME__); + + error = init_lock_dlm(); + if (error) + goto fail1; + + error = init_nolock(); + if (error) + goto fail1; + + return 0; + + fail1: + if (gfs_mhc_cachep) + kmem_cache_destroy(gfs_mhc_cachep); + + if (gfs_bufdata_cachep) + kmem_cache_destroy(gfs_bufdata_cachep); + + if (gfs_inode_cachep) + kmem_cache_destroy(gfs_inode_cachep); + + if (gfs_glock_cachep) + kmem_cache_destroy(gfs_glock_cachep); + + gfs_proc_uninit(); + + fail: + gfs_sys_uninit(); + + return error; +} + +/** + * exit_gfs_fs - Unregister the file system + * + */ + +void __exit +exit_gfs_fs(void) +{ + exit_nolock(); + exit_lock_dlm(); + unregister_filesystem(&gfs_fs_type); + + kmem_cache_destroy(gfs_mhc_cachep); + kmem_cache_destroy(gfs_bufdata_cachep); + kmem_cache_destroy(gfs_inode_cachep); + kmem_cache_destroy(gfs_glock_cachep); + + gfs_proc_uninit(); + gfs_sys_uninit(); +} + +MODULE_DESCRIPTION("Global File System " RELEASE_VERSION); +MODULE_AUTHOR("Red Hat, Inc."); +MODULE_LICENSE("GPL"); + +module_init(init_gfs_fs); +module_exit(exit_gfs_fs); + --- linux-2.6.28.orig/ubuntu/gfs/dir.c +++ linux-2.6.28/ubuntu/gfs/dir.c @@ -0,0 +1,2394 @@ +/* +* Implements Extendible Hashing as described in: +* "Extendible Hashing" by Fagin, et al in +* __ACM Trans. on Database Systems__, Sept 1979. +* +* +* Here's the layout of dirents which is essentially the same as that of ext2 +* within a single block. The field de_name_len is the number of bytes +* actually required for the name (no null terminator). The field de_rec_len +* is the number of bytes allocated to the dirent. The offset of the next +* dirent in the block is (dirent + dirent->de_rec_len). When a dirent is +* deleted, the preceding dirent inherits its allocated space, ie +* prev->de_rec_len += deleted->de_rec_len. Since the next dirent is obtained +* by adding de_rec_len to the current dirent, this essentially causes the +* deleted dirent to get jumped over when iterating through all the dirents. +* +* When deleting the first dirent in a block, there is no previous dirent so +* the field de_ino is set to zero to designate it as deleted. When allocating +* a dirent, gfs_dirent_alloc iterates through the dirents in a block. If the +* first dirent has (de_ino == 0) and de_rec_len is large enough, this first +* dirent is allocated. Otherwise it must go through all the 'used' dirents +* searching for one in which the amount of total space minus the amount of +* used space will provide enough space for the new dirent. +* +* There are two types of blocks in which dirents reside. In a stuffed dinode, +* the dirents begin at offset sizeof(struct gfs_dinode) from the beginning of +* the block. In leaves, they begin at offset sizeof (struct gfs_leaf) from the +* beginning of the leaf block. The dirents reside in leaves when +* +* dip->i_di.di_flags & GFS_DIF_EXHASH is true +* +* Otherwise, the dirents are "linear", within a single stuffed dinode block. +* +* When the dirents are in leaves, the actual contents of the directory file are +* used as an array of 64-bit block pointers pointing to the leaf blocks. The +* dirents are NOT in the directory file itself. There can be more than one block +* pointer in the array that points to the same leaf. In fact, when a directory +* is first converted from linear to exhash, all of the pointers point to the +* same leaf. +* +* When a leaf is completely full, the size of the hash table can be +* doubled unless it is already at the maximum size which is hard coded into +* GFS_DIR_MAX_DEPTH. After that, leaves are chained together in a linked list, +* but never before the maximum hash table size has been reached. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "dio.h" +#include "dir.h" +#include "file.h" +#include "glock.h" +#include "inode.h" +#include "quota.h" +#include "rgrp.h" +#include "trans.h" + +#if 1 +#define gfs_dir_hash2offset(h) (((uint64_t)(h)) >> 1) +#define gfs_dir_offset2hash(p) ((uint32_t)(((uint64_t)(p)) << 1)) +#else +#define gfs_dir_hash2offset(h) (((uint64_t)(h))) +#define gfs_dir_offset2hash(p) ((uint32_t)(((uint64_t)(p)))) +#endif + +typedef int (*leaf_call_t) (struct gfs_inode *dip, + uint32_t index, uint32_t len, uint64_t leaf_no, + void *data); + +/** + * int gfs_filecmp - Compare two filenames + * @file1: The first filename + * @file2: The second filename + * @len_of_file2: The length of the second file + * + * This routine compares two filenames and returns TRUE if they are equal. + * + * Returns: TRUE (!=0) if the files are the same, otherwise FALSE (0). + */ + +int +gfs_filecmp(struct qstr *file1, char *file2, int len_of_file2) +{ + if (file1->len != len_of_file2) + return FALSE; + if (memcmp(file1->name, file2, file1->len)) + return FALSE; + return TRUE; +} + +/** + * dirent_first - Return the first dirent + * @dip: the directory + * @bh: The buffer + * @dent: Pointer to list of dirents + * + * return first dirent whether bh points to leaf or stuffed dinode + * + * Returns: IS_LEAF, IS_DINODE, or -errno + */ + +static int +dirent_first(struct gfs_inode *dip, struct buffer_head *bh, + struct gfs_dirent **dent) +{ + struct gfs_meta_header *h = (struct gfs_meta_header *)bh->b_data; + + if (gfs32_to_cpu(h->mh_type) == GFS_METATYPE_LF) { + if (gfs_meta_check(dip->i_sbd, bh)) + return -EIO; + *dent = (struct gfs_dirent *)(bh->b_data + sizeof(struct gfs_leaf)); + return IS_LEAF; + } else { + if (gfs_metatype_check(dip->i_sbd, bh, GFS_METATYPE_DI)) + return -EIO; + *dent = (struct gfs_dirent *)(bh->b_data + sizeof(struct gfs_dinode)); + return IS_DINODE; + } +} + +/** + * dirent_next - Next dirent + * @dip: the directory + * @bh: The buffer + * @dent: Pointer to list of dirents + * + * Returns: 0 on success, error code otherwise + */ + +static int +dirent_next(struct gfs_inode *dip, struct buffer_head *bh, + struct gfs_dirent **dent) +{ + struct gfs_dirent *tmp, *cur; + char *bh_end; + uint32_t cur_rec_len; + + cur = *dent; + bh_end = bh->b_data + bh->b_size; + cur_rec_len = gfs16_to_cpu(cur->de_rec_len); + + if ((char *)cur + cur_rec_len >= bh_end) { + if ((char *)cur + cur_rec_len > bh_end) { + gfs_consist_inode(dip); + return -EIO; + } + return -ENOENT; + } + + tmp = (struct gfs_dirent *)((char *)cur + cur_rec_len); + + if ((char *)tmp + gfs16_to_cpu(tmp->de_rec_len) > bh_end) { + gfs_consist_inode(dip); + return -EIO; + } + /* Only the first dent could ever have de_ino == 0 */ + if (!tmp->de_inum.no_formal_ino) { + gfs_consist_inode(dip); + return -EIO; + } + + *dent = tmp; + + return 0; +} + +/** + * dirent_del - Delete a dirent + * @dip: The GFS inode + * @bh: The buffer + * @prev: The previous dirent + * @cur: The current dirent + * + */ + +static void +dirent_del(struct gfs_inode *dip, struct buffer_head *bh, + struct gfs_dirent *prev, struct gfs_dirent *cur) +{ + uint32_t cur_rec_len, prev_rec_len; + + if (!cur->de_inum.no_formal_ino) { + gfs_consist_inode(dip); + return; + } + + gfs_trans_add_bh(dip->i_gl, bh); + + /* If there is no prev entry, this is the first entry in the block. + The de_rec_len is already as big as it needs to be. Just zero + out the inode number and return. */ + + if (!prev) { + cur->de_inum.no_formal_ino = 0; /* No endianess worries */ + return; + } + + /* Combine this dentry with the previous one. */ + + prev_rec_len = gfs16_to_cpu(prev->de_rec_len); + cur_rec_len = gfs16_to_cpu(cur->de_rec_len); + + if ((char *)prev + prev_rec_len != (char *)cur) + gfs_consist_inode(dip); + if ((char *)cur + cur_rec_len > bh->b_data + bh->b_size) + gfs_consist_inode(dip); + + prev_rec_len += cur_rec_len; + prev->de_rec_len = cpu_to_gfs16(prev_rec_len); +} + +/** + * gfs_dirent_alloc - Allocate a directory entry + * @dip: The GFS inode + * @bh: The buffer + * @name_len: The length of the name + * @dent_out: Pointer to list of dirents + * + * Returns: 0 on success, error code otherwise + */ + +int +gfs_dirent_alloc(struct gfs_inode *dip, struct buffer_head *bh, int name_len, + struct gfs_dirent **dent_out) +{ + struct gfs_dirent *dent, *new; + unsigned int rec_len = GFS_DIRENT_SIZE(name_len); + unsigned int entries = 0, offset = 0; + int type; + + type = dirent_first(dip, bh, &dent); + if (type < 0) + return type; + + if (type == IS_LEAF) { + struct gfs_leaf *leaf = (struct gfs_leaf *)bh->b_data; + entries = gfs16_to_cpu(leaf->lf_entries); + offset = sizeof(struct gfs_leaf); + } else { + struct gfs_dinode *dinode = (struct gfs_dinode *)bh->b_data; + entries = gfs32_to_cpu(dinode->di_entries); + offset = sizeof(struct gfs_dinode); + } + + if (!entries) { + if (dent->de_inum.no_formal_ino) { + gfs_consist_inode(dip); + return -EIO; + } + + gfs_trans_add_bh(dip->i_gl, bh); + + dent->de_rec_len = bh->b_size - offset; + dent->de_rec_len = cpu_to_gfs16(dent->de_rec_len); + dent->de_name_len = cpu_to_gfs16(name_len); + + *dent_out = dent; + return 0; + } + + do { + uint32_t cur_rec_len, cur_name_len; + + cur_rec_len = gfs16_to_cpu(dent->de_rec_len); + cur_name_len = gfs16_to_cpu(dent->de_name_len); + + if ((!dent->de_inum.no_formal_ino && cur_rec_len >= rec_len) || + (cur_rec_len >= GFS_DIRENT_SIZE(cur_name_len) + rec_len)) { + gfs_trans_add_bh(dip->i_gl, bh); + + if (dent->de_inum.no_formal_ino) { + new = (struct gfs_dirent *)((char *)dent + + GFS_DIRENT_SIZE(cur_name_len)); + memset(new, 0, sizeof(struct gfs_dirent)); + + new->de_rec_len = cpu_to_gfs16(cur_rec_len - + GFS_DIRENT_SIZE(cur_name_len)); + new->de_name_len = cpu_to_gfs16(name_len); + + dent->de_rec_len = cur_rec_len - gfs16_to_cpu(new->de_rec_len); + dent->de_rec_len = cpu_to_gfs16(dent->de_rec_len); + + *dent_out = new; + return 0; + } + + dent->de_name_len = cpu_to_gfs16(name_len); + + *dent_out = dent; + return 0; + } + } while (dirent_next(dip, bh, &dent) == 0); + + return -ENOSPC; +} + +/** + * dirent_fits - See if we can fit a entry in this buffer + * @dip: The GFS inode + * @bh: The buffer + * @name_len: The length of the name + * + * Returns: TRUE if it can fit, FALSE otherwise + */ + +static int +dirent_fits(struct gfs_inode *dip, struct buffer_head *bh, int name_len) +{ + struct gfs_dirent *dent; + unsigned int rec_len = GFS_DIRENT_SIZE(name_len); + unsigned int entries = 0; + int type; + + type = dirent_first(dip, bh, &dent); + if (type < 0) + return type; + + if (type == IS_LEAF) { + struct gfs_leaf *leaf = (struct gfs_leaf *)bh->b_data; + entries = gfs16_to_cpu(leaf->lf_entries); + } else { + struct gfs_dinode *dinode = (struct gfs_dinode *)bh->b_data; + entries = gfs32_to_cpu(dinode->di_entries); + } + + if (!entries) + return TRUE; + + do { + uint32_t cur_rec_len, cur_name_len; + + cur_rec_len = gfs16_to_cpu(dent->de_rec_len); + cur_name_len = gfs16_to_cpu(dent->de_name_len); + + if ((!dent->de_inum.no_formal_ino && cur_rec_len >= rec_len) || + (cur_rec_len >= GFS_DIRENT_SIZE(cur_name_len) + rec_len)) + return TRUE; + } while (dirent_next(dip, bh, &dent) == 0); + + return FALSE; +} + +/** + * leaf_search + * @bh: + * @filename: + * @dent_out: + * @dent_prev: + * + * Returns: + */ + +static int +leaf_search(struct gfs_inode *dip, + struct buffer_head *bh, struct qstr *filename, + struct gfs_dirent **dent_out, struct gfs_dirent **dent_prev) +{ + uint32_t hash; + struct gfs_dirent *dent, *prev = NULL; + unsigned int entries = 0; + int type; + + type = dirent_first(dip, bh, &dent); + if (type < 0) + return type; + + if (type == IS_LEAF) { + struct gfs_leaf *leaf = (struct gfs_leaf *)bh->b_data; + entries = gfs16_to_cpu(leaf->lf_entries); + } else if (type == IS_DINODE) { + struct gfs_dinode *dinode = (struct gfs_dinode *)bh->b_data; + entries = gfs32_to_cpu(dinode->di_entries); + } + + hash = gfs_dir_hash(filename->name, filename->len); + + do { + if (!dent->de_inum.no_formal_ino) { + prev = dent; + continue; + } + + if (gfs32_to_cpu(dent->de_hash) == hash && + gfs_filecmp(filename, (char *)(dent + 1), + gfs16_to_cpu(dent->de_name_len))) { + *dent_out = dent; + if (dent_prev) + *dent_prev = prev; + + return 0; + } + + prev = dent; + } while (dirent_next(dip, bh, &dent) == 0); + + return -ENOENT; +} + +/** + * get_leaf - Get leaf + * @dip: + * @leaf_no: + * @bh_out: + * + * Returns: 0 on success, error code otherwise + */ + +static int +get_leaf(struct gfs_inode *dip, uint64_t leaf_no, struct buffer_head **bhp) +{ + int error; + + error = gfs_dread(dip->i_gl, leaf_no, DIO_START | DIO_WAIT, bhp); + if (!error && gfs_metatype_check(dip->i_sbd, *bhp, GFS_METATYPE_LF)) + error = -EIO; + + return error; +} + +/** + * get_leaf_nr - Get a leaf number associated with the index + * @dip: The GFS inode + * @index: + * @leaf_out: + * + * Returns: 0 on success, error code otherwise + */ + +static int +get_leaf_nr(struct gfs_inode *dip, uint32_t index, uint64_t *leaf_out) +{ + uint64_t leaf_no; + int error; + + error = gfs_internal_read(dip, (char *)&leaf_no, + index * sizeof(uint64_t), + sizeof(uint64_t)); + if (error != sizeof(uint64_t)) + return (error < 0) ? error : -EIO; + + *leaf_out = gfs64_to_cpu(leaf_no); + + return 0; +} + +/** + * get_first_leaf - Get first leaf + * @dip: The GFS inode + * @index: + * @bh_out: + * + * Returns: 0 on success, error code otherwise + */ + +static int +get_first_leaf(struct gfs_inode *dip, uint32_t index, + struct buffer_head **bh_out) +{ + uint64_t leaf_no; + int error; + + error = get_leaf_nr(dip, index, &leaf_no); + if (!error) + error = get_leaf(dip, leaf_no, bh_out); + + return error; +} + +/** + * get_next_leaf - Get next leaf + * @dip: The GFS inode + * @bh_in: The buffer + * @bh_out: + * + * Returns: 0 on success, error code otherwise + */ + +static int +get_next_leaf(struct gfs_inode *dip, struct buffer_head *bh_in, + struct buffer_head **bh_out) +{ + struct gfs_leaf *leaf; + int error; + + leaf = (struct gfs_leaf *)bh_in->b_data; + + if (!leaf->lf_next) + error = -ENOENT; + else + error = get_leaf(dip, gfs64_to_cpu(leaf->lf_next), bh_out); + + return error; +} + +/** + * linked_leaf_search - Linked leaf search + * @dip: The GFS inode + * @filename: The filename to search for + * @dent_out: + * @dent_prev: + * @bh_out: + * + * Returns: 0 on sucess, error code otherwise + */ + +static int +linked_leaf_search(struct gfs_inode *dip, struct qstr *filename, + struct gfs_dirent **dent_out, struct gfs_dirent **dent_prev, + struct buffer_head **bh_out) +{ + struct buffer_head *bh = NULL, *bh_next; + uint32_t hsize, index; + uint32_t hash; + int error; + + hsize = 1 << dip->i_di.di_depth; + if (hsize * sizeof(uint64_t) != dip->i_di.di_size) { + gfs_consist_inode(dip); + return -EIO; + } + + /* Figure out the address of the leaf node. */ + + hash = gfs_dir_hash(filename->name, filename->len); + index = hash >> (32 - dip->i_di.di_depth); + + error = get_first_leaf(dip, index, &bh_next); + if (error) + return error; + + /* Find the entry */ + + do { + if (bh) + brelse(bh); + + bh = bh_next; + + error = leaf_search(dip, bh, filename, dent_out, dent_prev); + switch (error) { + case 0: + *bh_out = bh; + return 0; + + case -ENOENT: + break; + + default: + brelse(bh); + return error; + } + + error = get_next_leaf(dip, bh, &bh_next); + } + while (!error); + + brelse(bh); + + return error; +} + +/** + * dir_make_exhash - Convert a stuffed directory into an ExHash directory + * @dip: The GFS inode + * + * Returns: 0 on success, error code otherwise + */ + +static int +dir_make_exhash(struct gfs_inode *dip) +{ + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_dirent *dent; + struct buffer_head *bh, *dibh; + struct gfs_leaf *leaf; + int y; + uint32_t x; + uint64_t *lp, bn; + int error; + + error = gfs_get_inode_buffer(dip, &dibh); + if (error) + return error; + + /* Allocate a new block for the first leaf node */ + + error = gfs_metaalloc(dip, &bn); + if (error) + goto fail; + + /* Turn over a new leaf */ + + error = gfs_dread(dip->i_gl, bn, DIO_NEW | DIO_START | DIO_WAIT, &bh); + if (error) + goto fail; + + gfs_trans_add_bh(dip->i_gl, bh); + gfs_metatype_set(bh, GFS_METATYPE_LF, GFS_FORMAT_LF); + gfs_buffer_clear_tail(bh, sizeof(struct gfs_meta_header)); + + /* Fill in the leaf structure */ + + leaf = (struct gfs_leaf *)bh->b_data; + + gfs_assert(sdp, dip->i_di.di_entries < (1 << 16),); + + leaf->lf_dirent_format = cpu_to_gfs32(GFS_FORMAT_DE); + leaf->lf_entries = cpu_to_gfs16(dip->i_di.di_entries); + + /* Copy dirents */ + + gfs_buffer_copy_tail(bh, sizeof(struct gfs_leaf), dibh, + sizeof(struct gfs_dinode)); + + /* Find last entry */ + + x = 0; + dirent_first(dip, bh, &dent); + + do { + if (!dent->de_inum.no_formal_ino) + continue; + if (++x == dip->i_di.di_entries) + break; + } + while (dirent_next(dip, bh, &dent) == 0); + + /* Adjust the last dirent's record length + (Remember that dent still points to the last entry.) */ + + dent->de_rec_len = gfs16_to_cpu(dent->de_rec_len) + + sizeof(struct gfs_dinode) - + sizeof(struct gfs_leaf); + dent->de_rec_len = cpu_to_gfs16(dent->de_rec_len); + + brelse(bh); + + /* We're done with the new leaf block, now setup the new + hash table. */ + + gfs_trans_add_bh(dip->i_gl, dibh); + gfs_buffer_clear_tail(dibh, sizeof (struct gfs_dinode)); + + lp = (uint64_t *)(dibh->b_data + sizeof(struct gfs_dinode)); + + for (x = sdp->sd_hash_ptrs; x--; lp++) + *lp = cpu_to_gfs64(bn); + + dip->i_di.di_size = sdp->sd_sb.sb_bsize / 2; + dip->i_di.di_blocks++; + dip->i_di.di_flags |= GFS_DIF_EXHASH; + dip->i_di.di_payload_format = 0; + + for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ; + dip->i_di.di_depth = y; + + gfs_dinode_out(&dip->i_di, dibh->b_data); + + brelse(dibh); + + return 0; + + fail: + brelse(dibh); + return error; +} + +/** + * dir_split_leaf - Split a leaf block into two + * @dip: The GFS inode + * @index: + * @leaf_no: + * + * Returns: 0 on success, error code on failure + */ + +static int +dir_split_leaf(struct gfs_inode *dip, uint32_t index, uint64_t leaf_no) +{ + struct buffer_head *nbh, *obh, *dibh; + struct gfs_leaf *nleaf, *oleaf; + struct gfs_dirent *dent, *prev = NULL, *next = NULL, *new; + uint32_t start, len, half_len, divider; + uint64_t bn, *lp; + uint32_t name_len; + int x, moved = FALSE; + int error, lp_vfree=0; + + /* Allocate the new leaf block */ + + error = gfs_metaalloc(dip, &bn); + if (error) + return error; + + /* Get the new leaf block */ + + error = gfs_dread(dip->i_gl, bn, + DIO_NEW | DIO_START | DIO_WAIT, &nbh); + if (error) + return error; + + gfs_trans_add_bh(dip->i_gl, nbh); + gfs_metatype_set(nbh, GFS_METATYPE_LF, GFS_FORMAT_LF); + gfs_buffer_clear_tail(nbh, sizeof (struct gfs_meta_header)); + + nleaf = (struct gfs_leaf *)nbh->b_data; + + nleaf->lf_dirent_format = cpu_to_gfs32(GFS_FORMAT_DE); + + /* Get the old leaf block */ + + error = get_leaf(dip, leaf_no, &obh); + if (error) + goto fail; + + gfs_trans_add_bh(dip->i_gl, obh); + + oleaf = (struct gfs_leaf *)obh->b_data; + + /* Compute the start and len of leaf pointers in the hash table. */ + + len = 1 << (dip->i_di.di_depth - gfs16_to_cpu(oleaf->lf_depth)); + half_len = len >> 1; + if (!half_len) { + gfs_consist_inode(dip); + error = -EIO; + goto fail_brelse; + } + + start = (index & ~(len - 1)); + + /* Change the pointers. + Don't bother distinguishing stuffed from non-stuffed. + This code is complicated enough already. */ + + lp = kmalloc(half_len * sizeof (uint64_t), GFP_KERNEL); + if (unlikely(!lp)) { + lp = vmalloc(half_len * sizeof (uint64_t)); + if (!lp) { + printk("GFS: dir_split_leaf vmalloc fail - half_len=%d\n", half_len); + error = -ENOMEM; + goto fail_brelse; + } else + lp_vfree = 1; + } + + error = gfs_internal_read(dip, (char *)lp, start * sizeof(uint64_t), + half_len * sizeof(uint64_t)); + if (error != half_len * sizeof(uint64_t)) { + if (error >= 0) + error = -EIO; + goto fail_lpfree; + } + + /* Change the pointers */ + + for (x = 0; x < half_len; x++) + lp[x] = cpu_to_gfs64(bn); + + error = gfs_internal_write(dip, (char *)lp, start * sizeof(uint64_t), + half_len * sizeof(uint64_t)); + if (error != half_len * sizeof(uint64_t)) { + if (error >= 0) + error = -EIO; + goto fail_lpfree; + } + + if (unlikely(lp_vfree)) + vfree(lp); + else + kfree(lp); + + /* Compute the divider */ + + divider = (start + half_len) << (32 - dip->i_di.di_depth); + + /* Copy the entries */ + + dirent_first(dip, obh, &dent); + + do { + next = dent; + if (dirent_next(dip, obh, &next)) + next = NULL; + + if (dent->de_inum.no_formal_ino && + gfs32_to_cpu(dent->de_hash) < divider) { + name_len = gfs16_to_cpu(dent->de_name_len); + + gfs_dirent_alloc(dip, nbh, name_len, &new); + + new->de_inum = dent->de_inum; /* No endianness worries */ + new->de_hash = dent->de_hash; /* No endianness worries */ + new->de_type = dent->de_type; /* No endianness worries */ + memcpy((char *)(new + 1), (char *)(dent + 1), + name_len); + + nleaf->lf_entries = gfs16_to_cpu(nleaf->lf_entries) + 1; + nleaf->lf_entries = cpu_to_gfs16(nleaf->lf_entries); + + dirent_del(dip, obh, prev, dent); + + if (!oleaf->lf_entries) + gfs_consist_inode(dip); + oleaf->lf_entries = gfs16_to_cpu(oleaf->lf_entries) - 1; + oleaf->lf_entries = cpu_to_gfs16(oleaf->lf_entries); + + if (!prev) + prev = dent; + + moved = TRUE; + } else + prev = dent; + + dent = next; + } + while (dent); + + /* If none of the entries got moved into the new leaf, + artificially fill in the first entry. */ + + if (!moved) { + gfs_dirent_alloc(dip, nbh, 0, &new); + new->de_inum.no_formal_ino = 0; + } + + oleaf->lf_depth = gfs16_to_cpu(oleaf->lf_depth) + 1; + oleaf->lf_depth = cpu_to_gfs16(oleaf->lf_depth); + nleaf->lf_depth = oleaf->lf_depth; + + error = gfs_get_inode_buffer(dip, &dibh); + if (!gfs_assert_withdraw(dip->i_sbd, !error)) { + dip->i_di.di_blocks++; + gfs_dinode_out(&dip->i_di, dibh->b_data); + brelse(dibh); + } + + brelse(obh); + brelse(nbh); + + return error; + + fail_lpfree: + if (unlikely(lp_vfree)) + vfree(lp); + else + kfree(lp); + + fail_brelse: + brelse(obh); + + fail: + brelse(nbh); + return error; +} + +/** + * dir_double_exhash - Double size of ExHash table + * @dip: The GFS dinode + * + * Returns: 0 on success, error code on failure + */ + +static int +dir_double_exhash(struct gfs_inode *dip) +{ + struct gfs_sbd *sdp = dip->i_sbd; + struct buffer_head *dibh; + uint32_t hsize; + uint64_t *buf; + uint64_t *from, *to; + uint64_t block; + int x; + int error = 0; + + hsize = 1 << dip->i_di.di_depth; + if (hsize * sizeof(uint64_t) != dip->i_di.di_size) { + gfs_consist_inode(dip); + return -EIO; + } + + /* Allocate both the "from" and "to" buffers in one big chunk */ + + buf = gmalloc(3 * sdp->sd_hash_bsize); + + for (block = dip->i_di.di_size >> sdp->sd_hash_bsize_shift; block--;) { + error = gfs_internal_read(dip, (char *)buf, + block * sdp->sd_hash_bsize, + sdp->sd_hash_bsize); + if (error != sdp->sd_hash_bsize) { + if (error >= 0) + error = -EIO; + goto fail; + } + + from = buf; + to = (uint64_t *)((char *)buf + sdp->sd_hash_bsize); + + for (x = sdp->sd_hash_ptrs; x--; from++) { + *to++ = *from; /* No endianess worries */ + *to++ = *from; + } + + error = gfs_internal_write(dip, (char *)buf + sdp->sd_hash_bsize, + block * sdp->sd_sb.sb_bsize, + sdp->sd_sb.sb_bsize); + if (error != sdp->sd_sb.sb_bsize) { + if (error >= 0) + error = -EIO; + goto fail; + } + } + + kfree(buf); + + error = gfs_get_inode_buffer(dip, &dibh); + if (!gfs_assert_withdraw(sdp, !error)) { + dip->i_di.di_depth++; + gfs_dinode_out(&dip->i_di, dibh->b_data); + brelse(dibh); + } + + return error; + + fail: + kfree(buf); + + return error; +} + +/** + * compare_dents - compare directory entries by hash value + * @a: first dent + * @b: second dent + * + * When comparing the hash entries of @a to @b: + * gt: returns 1 + * lt: returns -1 + * eq: returns 0 + */ + +static int +compare_dents(const void *a, const void *b) +{ + struct gfs_dirent *dent_a, *dent_b; + uint32_t hash_a, hash_b; + int ret = 0; + + dent_a = *(struct gfs_dirent **)a; + hash_a = dent_a->de_hash; + hash_a = gfs32_to_cpu(hash_a); + + dent_b = *(struct gfs_dirent **)b; + hash_b = dent_b->de_hash; + hash_b = gfs32_to_cpu(hash_b); + + if (hash_a > hash_b) + ret = 1; + else if (hash_a < hash_b) + ret = -1; + else { + unsigned int len_a = gfs16_to_cpu(dent_a->de_name_len); + unsigned int len_b = gfs16_to_cpu(dent_b->de_name_len); + + if (len_a > len_b) + ret = 1; + else if (len_a < len_b) + ret = -1; + else + ret = memcmp((char *)(dent_a + 1), + (char *)(dent_b + 1), + len_a); + } + + return ret; +} + +/** + * do_filldir_main - read out directory entries + * @dip: The GFS inode + * @offset: The offset in the file to read from + * @opaque: opaque data to pass to filldir + * @filldir: The function to pass entries to + * @darr: an array of struct gfs_dirent pointers to read + * @entries: the number of entries in darr + * @copied: pointer to int that's non-zero if a entry has been copied out + * + * Jump through some hoops to make sure that if there are hash collsions, + * they are read out at the beginning of a buffer. We want to minimize + * the possibility that they will fall into different readdir buffers or + * that someone will want to seek to that location. + * + * Returns: errno, >0 on exception from filldir + */ + +static int +do_filldir_main(struct gfs_inode *dip, uint64_t *offset, + void *opaque, gfs_filldir_t filldir, + struct gfs_dirent **darr, uint32_t entries, int *copied) +{ + struct gfs_dirent *dent, *dent_next; + struct gfs_inum inum; + uint64_t off, off_next; + unsigned int x, y; + int run = FALSE; + int error = 0; + + gfs_sort(darr, entries, sizeof(struct gfs_dirent *), compare_dents); + + dent_next = darr[0]; + off_next = gfs32_to_cpu(dent_next->de_hash); + off_next = gfs_dir_hash2offset(off_next); + + for (x = 0, y = 1; x < entries; x++, y++) { + dent = dent_next; + off = off_next; + + if (y < entries) { + dent_next = darr[y]; + off_next = gfs32_to_cpu(dent_next->de_hash); + off_next = gfs_dir_hash2offset(off_next); + + if (off < *offset) + continue; + *offset = off; + + if (off_next == off) { + if (*copied && !run) + return 1; + run = TRUE; + } else + run = FALSE; + } else { + if (off < *offset) + continue; + *offset = off; + } + + gfs_inum_in(&inum, (char *)&dent->de_inum); + + error = filldir(opaque, (char *)(dent + 1), + gfs16_to_cpu(dent->de_name_len), + off, &inum, + gfs16_to_cpu(dent->de_type)); + if (error) + return 1; + + *copied = TRUE; + } + + /* Increment the *offset by one, so the next time we come into the do_filldir fxn, + we get the next entry instead of the last one in the current leaf */ + + (*offset)++; + + return 0; +} + +/** + * do_filldir_single - Read directory entries out of a single block + * @dip: The GFS inode + * @offset: The offset in the file to read from + * @opaque: opaque data to pass to filldir + * @filldir: The function to pass entries to + * @bh: the block + * @entries: the number of entries in the block + * @copied: pointer to int that's non-zero if a entry has been copied out + * + * Returns: errno, >0 on exception from filldir + */ + +static int +do_filldir_single(struct gfs_inode *dip, uint64_t *offset, + void *opaque, gfs_filldir_t filldir, + struct buffer_head *bh, uint32_t entries, int *copied) +{ + struct gfs_dirent **darr; + struct gfs_dirent *de; + unsigned int e = 0; + int error, do_vfree=0; + + if (!entries) + return 0; + + darr = kmalloc(entries * sizeof(struct gfs_dirent *), GFP_KERNEL); + if (unlikely(!darr)) { + darr = vmalloc(entries * sizeof (struct gfs_dirent *)); + if (!darr) { + printk("GFS: do_filldir_single vmalloc fails, entries=%d\n", entries); + return -ENOMEM; + } + else + do_vfree = 1; + } + + dirent_first(dip, bh, &de); + do { + if (!de->de_inum.no_formal_ino) + continue; + if (e >= entries) { + gfs_consist_inode(dip); + error = -EIO; + goto out; + } + darr[e++] = de; + } + while (dirent_next(dip, bh, &de) == 0); + + if (e != entries) { + gfs_consist_inode(dip); + error = -EIO; + goto out; + } + + error = do_filldir_main(dip, offset, opaque, filldir, darr, + entries, copied); + + out: + if (unlikely(do_vfree)) + vfree(darr); + else + kfree(darr); + + return error; +} + +/** + * do_filldir_multi - Read directory entries out of a linked leaf list + * @dip: The GFS inode + * @offset: The offset in the file to read from + * @opaque: opaque data to pass to filldir + * @filldir: The function to pass entries to + * @bh: the first leaf in the list + * @copied: pointer to int that's non-zero if a entry has been copied out + * + * Returns: errno, >0 on exception from filldir + */ + +static int +do_filldir_multi(struct gfs_inode *dip, uint64_t *offset, + void *opaque, gfs_filldir_t filldir, + struct buffer_head *bh, int *copied) +{ + struct buffer_head **larr = NULL; + struct gfs_dirent **darr; + struct gfs_leaf *leaf; + struct buffer_head *tmp_bh; + struct gfs_dirent *de; + unsigned int entries, e = 0; + unsigned int leaves = 0, l = 0; + unsigned int x; + uint64_t ln; + int error = 0, leaves_vfree=0, entries_vfree=0; + + /* Count leaves and entries */ + + leaf = (struct gfs_leaf *)bh->b_data; + entries = gfs16_to_cpu(leaf->lf_entries); + ln = leaf->lf_next; + + while (ln) { + ln = gfs64_to_cpu(ln); + + error = get_leaf(dip, ln, &tmp_bh); + if (error) + return error; + + leaf = (struct gfs_leaf *)tmp_bh->b_data; + if (leaf->lf_entries) { + entries += gfs16_to_cpu(leaf->lf_entries); + leaves++; + } + ln = leaf->lf_next; + + brelse(tmp_bh); + } + + /* Bail out if there's nothing to do */ + + if (!entries) + return 0; + + /* Alloc arrays */ + + if (leaves) { + larr = kmalloc(leaves * sizeof(struct buffer_head *), GFP_KERNEL); + if (unlikely(!larr)) { + larr = vmalloc(leaves * sizeof (struct buffer_head *)); + if (!larr) { + printk("GFS: do_filldir_multi vmalloc fails leaves=%d\n", leaves); + return -ENOMEM; + } else + leaves_vfree = 1; + } + } + + darr = kmalloc(entries * sizeof(struct gfs_dirent *), GFP_KERNEL); + if (unlikely(!darr)) { + darr = vmalloc(entries * sizeof (struct gfs_dirent *)); + if (!darr) { + printk("GFS: do_filldir_multi vmalloc fails entries=%d\n", entries); + if (larr) { + if (leaves_vfree) + vfree(larr); + else + kfree(larr); + } + return -ENOMEM; + } else + entries_vfree = 1; + } + if (!darr) { + if (larr) + kfree(larr); + return -ENOMEM; + } + + /* Fill in arrays */ + + leaf = (struct gfs_leaf *)bh->b_data; + if (leaf->lf_entries) { + dirent_first(dip, bh, &de); + do { + if (!de->de_inum.no_formal_ino) + continue; + if (e >= entries) { + gfs_consist_inode(dip); + error = -EIO; + goto out; + } + darr[e++] = de; + } + while (dirent_next(dip, bh, &de) == 0); + } + ln = leaf->lf_next; + + while (ln) { + ln = gfs64_to_cpu(ln); + + error = get_leaf(dip, ln, &tmp_bh); + if (error) + goto out; + + leaf = (struct gfs_leaf *)tmp_bh->b_data; + if (leaf->lf_entries) { + dirent_first(dip, tmp_bh, &de); + do { + if (!de->de_inum.no_formal_ino) + continue; + if (e >= entries) { + gfs_consist_inode(dip); + error = -EIO; + goto out; + } + darr[e++] = de; + } + while (dirent_next(dip, tmp_bh, &de) == 0); + + larr[l++] = tmp_bh; + + ln = leaf->lf_next; + } else { + ln = leaf->lf_next; + brelse(tmp_bh); + } + } + + if (gfs_assert_withdraw(dip->i_sbd, l == leaves)) { + error = -EIO; + goto out; + } + if (e != entries) { + gfs_consist_inode(dip); + error = -EIO; + goto out; + } + + /* Do work */ + + error = do_filldir_main(dip, offset, opaque, filldir, darr, + entries, copied); + + /* Clean up */ + + out: + if (unlikely(entries_vfree)) + vfree(darr); + else + kfree(darr); + + for (x = 0; x < l; x++) + brelse(larr[x]); + + if (leaves) { + if (unlikely(leaves_vfree)) + vfree(larr); + else + kfree(larr); + } + + return error; +} + +/** + * dir_e_search - Search exhash (leaf) dir for inode matching name + * @dip: The GFS inode + * @filename: Filename string + * @inode: If non-NULL, function fills with formal inode # and block address + * @type: If non-NULL, function fills with GFS_FILE_... dinode type + * + * Returns: + */ + +static int +dir_e_search(struct gfs_inode *dip, struct qstr *filename, + struct gfs_inum *inum, unsigned int *type) +{ + struct buffer_head *bh; + struct gfs_dirent *dent; + int error; + + error = linked_leaf_search(dip, filename, &dent, NULL, &bh); + if (error) + return error; + + if (inum) + gfs_inum_in(inum, (char *)&dent->de_inum); + if (type) + *type = gfs16_to_cpu(dent->de_type); + + brelse(bh); + + return 0; +} + +/** + * dir_e_add - + * @dip: The GFS inode + * @filename: + * @inode: + * @type: + * + */ + +static int +dir_e_add(struct gfs_inode *dip, struct qstr *filename, + struct gfs_inum *inum, unsigned int type) +{ + struct buffer_head *bh, *nbh, *dibh; + struct gfs_leaf *leaf, *nleaf; + struct gfs_dirent *dent; + uint32_t hsize, index; + uint32_t hash; + uint64_t leaf_no, bn; + int error; + + restart: + hsize = 1 << dip->i_di.di_depth; + if (hsize * sizeof(uint64_t) != dip->i_di.di_size) { + gfs_consist_inode(dip); + return -EIO; + } + + /* Figure out the address of the leaf node. */ + + hash = gfs_dir_hash(filename->name, filename->len); + index = hash >> (32 - dip->i_di.di_depth); + + error = get_leaf_nr(dip, index, &leaf_no); + if (error) + return error; + + /* Add entry to the leaf */ + + for (;;) { + error = get_leaf(dip, leaf_no, &bh); + if (error) + return error; + + leaf = (struct gfs_leaf *)bh->b_data; + + if (gfs_dirent_alloc(dip, bh, filename->len, &dent)) { + + if (gfs16_to_cpu(leaf->lf_depth) < dip->i_di.di_depth) { + /* Can we split the leaf? */ + + brelse(bh); + + error = dir_split_leaf(dip, index, leaf_no); + if (error) + return error; + + goto restart; + + } else if (dip->i_di.di_depth < GFS_DIR_MAX_DEPTH) { + /* Can we double the hash table? */ + + brelse(bh); + + error = dir_double_exhash(dip); + if (error) + return error; + + goto restart; + + } else if (leaf->lf_next) { + /* Can we try the next leaf in the list? */ + leaf_no = gfs64_to_cpu(leaf->lf_next); + brelse(bh); + continue; + + } else { + /* Create a new leaf and add it to the list. */ + + error = gfs_metaalloc(dip, &bn); + if (error) { + brelse(bh); + return error; + } + + error = gfs_dread(dip->i_gl, bn, + DIO_NEW | DIO_START | DIO_WAIT, + &nbh); + if (error) { + brelse(bh); + return error; + } + + gfs_trans_add_bh(dip->i_gl, nbh); + gfs_metatype_set(nbh, + GFS_METATYPE_LF, + GFS_FORMAT_LF); + gfs_buffer_clear_tail(nbh, + sizeof(struct gfs_meta_header)); + + gfs_trans_add_bh(dip->i_gl, bh); + leaf->lf_next = cpu_to_gfs64(bn); + + nleaf = (struct gfs_leaf *)nbh->b_data; + nleaf->lf_depth = leaf->lf_depth; + nleaf->lf_dirent_format = cpu_to_gfs32(GFS_FORMAT_DE); + + gfs_dirent_alloc(dip, nbh, filename->len, &dent); + + dip->i_di.di_blocks++; + + brelse(bh); + + bh = nbh; + leaf = nleaf; + } + } + + /* If the gfs_dirent_alloc() succeeded, it pinned the "bh". */ + + gfs_inum_out(inum, (char *)&dent->de_inum); + dent->de_hash = cpu_to_gfs32(hash); + dent->de_type = cpu_to_gfs16(type); + memcpy((char *)(dent + 1), filename->name, filename->len); + + leaf->lf_entries = gfs16_to_cpu(leaf->lf_entries) + 1; + leaf->lf_entries = cpu_to_gfs16(leaf->lf_entries); + + brelse(bh); + + error = gfs_get_inode_buffer(dip, &dibh); + if (error) + return error; + + dip->i_di.di_entries++; + dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds(); + + gfs_trans_add_bh(dip->i_gl, dibh); + gfs_dinode_out(&dip->i_di, dibh->b_data); + brelse(dibh); + + return 0; + } + + return -ENOENT; +} + +/** + * dir_e_del - + * @dip: The GFS inode + * @filename: + * + * Returns: + */ + +static int +dir_e_del(struct gfs_inode *dip, struct qstr *filename) +{ + struct buffer_head *bh, *dibh; + struct gfs_dirent *dent, *prev; + struct gfs_leaf *leaf; + unsigned int entries; + int error; + + error = linked_leaf_search(dip, filename, &dent, &prev, &bh); + if (error == -ENOENT) { + gfs_consist_inode(dip); + return -EIO; + } + if (error) + return error; + + dirent_del(dip, bh, prev, dent); /* Pins bh */ + + leaf = (struct gfs_leaf *)bh->b_data; + entries = gfs16_to_cpu(leaf->lf_entries); + if (!entries) + gfs_consist_inode(dip); + entries--; + leaf->lf_entries = cpu_to_gfs16(entries); + + brelse(bh); + + error = gfs_get_inode_buffer(dip, &dibh); + if (error) + return error; + + if (!dip->i_di.di_entries) + gfs_consist_inode(dip); + dip->i_di.di_entries--; + dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds(); + + gfs_trans_add_bh(dip->i_gl, dibh); + gfs_dinode_out(&dip->i_di, dibh->b_data); + brelse(dibh); + + return 0; +} + +/** + * dir_e_read - Reads the entries from a directory into a filldir buffer + * @dip: dinode pointer + * @offset: the hash of the last entry read shifted to the right once + * @opaque: buffer for the filldir function to fill + * @filldir: points to the filldir function to use + * + * Returns: errno + */ + +static int +dir_e_read(struct gfs_inode *dip, uint64_t *offset, void *opaque, + gfs_filldir_t filldir) +{ + struct gfs_sbd *sdp = dip->i_sbd; + struct buffer_head *bh; + struct gfs_leaf leaf; + uint32_t hsize, len; + uint32_t ht_offset, lp_offset, ht_offset_cur = -1; + uint32_t hash, index; + uint64_t *lp; + int copied = FALSE; + int error = 0; + + hsize = 1 << dip->i_di.di_depth; + if (hsize * sizeof(uint64_t) != dip->i_di.di_size) { + gfs_consist_inode(dip); + return -EIO; + } + + hash = gfs_dir_offset2hash(*offset); + index = hash >> (32 - dip->i_di.di_depth); + + lp = kmalloc(sdp->sd_hash_bsize, GFP_KERNEL); + if (!lp) + return -ENOMEM; + + while (index < hsize) { + lp_offset = index & (sdp->sd_hash_ptrs - 1); + ht_offset = index - lp_offset; + + if (ht_offset_cur != ht_offset) { + error = gfs_internal_read(dip, (char *)lp, + ht_offset * sizeof(uint64_t), + sdp->sd_hash_bsize); + if (error != sdp->sd_hash_bsize) { + if (error >= 0) + error = -EIO; + goto out; + } + ht_offset_cur = ht_offset; + } + + error = get_leaf(dip, gfs64_to_cpu(lp[lp_offset]), &bh); + if (error) + goto out; + + gfs_leaf_in(&leaf, bh->b_data); + + if (leaf.lf_next) + error = do_filldir_multi(dip, offset, + opaque, filldir, + bh, &copied); + else + error = do_filldir_single(dip, offset, + opaque, filldir, + bh, leaf.lf_entries, + &copied); + + brelse(bh); + + if (error) { + if (error > 0) + error = 0; + goto out; + } + + len = 1 << (dip->i_di.di_depth - leaf.lf_depth); + index = (index & ~(len - 1)) + len; + } + + out: + kfree(lp); + + return error; +} + +/** + * dir_e_mvino - + * @dip: The GFS inode + * @filename: + * @new_inode: + * + * Returns: + */ + +static int +dir_e_mvino(struct gfs_inode *dip, struct qstr *filename, + struct gfs_inum *inum, unsigned int new_type) +{ + struct buffer_head *bh, *dibh; + struct gfs_dirent *dent; + int error; + + error = linked_leaf_search(dip, filename, &dent, NULL, &bh); + if (error == -ENOENT) { + gfs_consist_inode(dip); + return -EIO; + } + if (error) + return error; + + gfs_trans_add_bh(dip->i_gl, bh); + + gfs_inum_out(inum, (char *)&dent->de_inum); + dent->de_type = cpu_to_gfs16(new_type); + + brelse(bh); + + error = gfs_get_inode_buffer(dip, &dibh); + if (error) + return error; + + dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds(); + + gfs_trans_add_bh(dip->i_gl, dibh); + gfs_dinode_out(&dip->i_di, dibh->b_data); + brelse(dibh); + + return 0; +} + +/** + * dir_l_search - Search linear (stuffed dinode) dir for inode matching name + * @dip: The GFS inode + * @filename: Filename string + * @inode: If non-NULL, function fills with formal inode # and block address + * @type: If non-NULL, function fills with GFS_FILE_... dinode type + * + * Returns: + */ + +static int +dir_l_search(struct gfs_inode *dip, struct qstr *filename, + struct gfs_inum *inum, unsigned int *type) +{ + struct buffer_head *dibh; + struct gfs_dirent *dent; + int error; + + if (!gfs_is_stuffed(dip)) { + gfs_consist_inode(dip); + return -EIO; + } + + error = gfs_get_inode_buffer(dip, &dibh); + if (error) + return error; + + error = leaf_search(dip, dibh, filename, &dent, NULL); + if (!error) { + if (inum) + gfs_inum_in(inum, (char *)&dent->de_inum); + if (type) + *type = gfs16_to_cpu(dent->de_type); + } + + brelse(dibh); + + return error; +} + +/** + * dir_l_add - + * @dip: The GFS inode + * @filename: + * @inode: + * @type: + * + * Returns: + */ + +static int +dir_l_add(struct gfs_inode *dip, struct qstr *filename, + struct gfs_inum *inum, unsigned int type) +{ + struct buffer_head *dibh; + struct gfs_dirent *dent; + int error; + + if (!gfs_is_stuffed(dip)) { + gfs_consist_inode(dip); + return -EIO; + } + + error = gfs_get_inode_buffer(dip, &dibh); + if (error) + return error; + + if (gfs_dirent_alloc(dip, dibh, filename->len, &dent)) { + brelse(dibh); + + error = dir_make_exhash(dip); + if (!error) + error = dir_e_add(dip, filename, inum, type); + + return error; + } + + /* gfs_dirent_alloc() pins */ + + gfs_inum_out(inum, (char *)&dent->de_inum); + dent->de_hash = gfs_dir_hash(filename->name, filename->len); + dent->de_hash = cpu_to_gfs32(dent->de_hash); + dent->de_type = cpu_to_gfs16(type); + memcpy((char *)(dent + 1), filename->name, filename->len); + + dip->i_di.di_entries++; + dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds(); + + gfs_dinode_out(&dip->i_di, dibh->b_data); + brelse(dibh); + + return 0; +} + +/** + * dir_l_del - + * @dip: The GFS inode + * @filename: + * + * Returns: + */ + +static int +dir_l_del(struct gfs_inode *dip, struct qstr *filename) +{ + struct buffer_head *dibh; + struct gfs_dirent *dent, *prev; + int error; + + if (!gfs_is_stuffed(dip)) { + gfs_consist_inode(dip); + return -EIO; + } + + error = gfs_get_inode_buffer(dip, &dibh); + if (error) + return error; + + error = leaf_search(dip, dibh, filename, &dent, &prev); + if (error == -ENOENT) { + gfs_consist_inode(dip); + error = -EIO; + goto out; + } + if (error) + goto out; + + dirent_del(dip, dibh, prev, dent); + + /* dirent_del() pins */ + + if (!dip->i_di.di_entries) + gfs_consist_inode(dip); + dip->i_di.di_entries--; + + dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds(); + + gfs_dinode_out(&dip->i_di, dibh->b_data); + + out: + brelse(dibh); + + return error; +} + +/** + * dir_l_read - + * @dip: + * @offset: + * @opaque: + * @filldir: + * + * Returns: + */ + +static int +dir_l_read(struct gfs_inode *dip, uint64_t *offset, void *opaque, + gfs_filldir_t filldir) +{ + struct buffer_head *dibh; + int copied = FALSE; + int error; + + if (!gfs_is_stuffed(dip)) { + gfs_consist_inode(dip); + return -EIO; + } + + if (!dip->i_di.di_entries) + return 0; + + error = gfs_get_inode_buffer(dip, &dibh); + if (error) + return error; + + error = do_filldir_single(dip, offset, + opaque, filldir, + dibh, dip->i_di.di_entries, + &copied); + if (error > 0) + error = 0; + + brelse(dibh); + + return error; +} + +/** + * dir_l_mvino - + * @dip: + * @filename: + * @new_inode: + * + * Returns: + */ + +static int +dir_l_mvino(struct gfs_inode *dip, struct qstr *filename, + struct gfs_inum *inum, unsigned int new_type) +{ + struct buffer_head *dibh; + struct gfs_dirent *dent; + int error; + + if (!gfs_is_stuffed(dip)) { + gfs_consist_inode(dip); + return -EIO; + } + + error = gfs_get_inode_buffer(dip, &dibh); + if (error) + return error; + + error = leaf_search(dip, dibh, filename, &dent, NULL); + if (error == -ENOENT) { + gfs_consist_inode(dip); + error = -EIO; + goto out; + } + if (error) + goto out; + + gfs_trans_add_bh(dip->i_gl, dibh); + + gfs_inum_out(inum, (char *)&dent->de_inum); + dent->de_type = cpu_to_gfs16(new_type); + + dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds(); + + gfs_dinode_out(&dip->i_di, dibh->b_data); + + out: + brelse(dibh); + + return error; +} + +/** + * gfs_dir_search - Search a directory + * @dip: The GFS inode + * @filename: + * @inode: + * + * This routine searches a directory for a file or another directory. + * Assumes a glock is held on dip. + * + * Returns: errno + */ + +int +gfs_dir_search(struct gfs_inode *dip, struct qstr *filename, + struct gfs_inum *inum, unsigned int *type) +{ + int error; + + if (dip->i_di.di_flags & GFS_DIF_EXHASH) + error = dir_e_search(dip, filename, inum, type); + else + error = dir_l_search(dip, filename, inum, type); + + return error; +} + +/** + * gfs_dir_add - Add new filename into directory + * @dip: The GFS inode + * @filename: The new name + * @inode: The inode number of the entry + * @type: The type of the entry + * + * Returns: 0 on success, error code on failure + */ + +int +gfs_dir_add(struct gfs_inode *dip, struct qstr *filename, + struct gfs_inum *inum, unsigned int type) +{ + int error; + + if (dip->i_di.di_flags & GFS_DIF_EXHASH) + error = dir_e_add(dip, filename, inum, type); + else + error = dir_l_add(dip, filename, inum, type); + + return error; +} + +/** + * gfs_dir_del - Delete a directory entry + * @dip: The GFS inode + * @filename: The filename + * + * Returns: 0 on success, error code on failure + */ + +int +gfs_dir_del(struct gfs_inode *dip, struct qstr *filename) +{ + int error; + + if (dip->i_di.di_flags & GFS_DIF_EXHASH) + error = dir_e_del(dip, filename); + else + error = dir_l_del(dip, filename); + + return error; +} + +/** + * gfs_dir_read - Translate a GFS filename + * @dip: The GFS inode + * @offset: + * @opaque: + * @filldir: + * + * Returns: 0 on success, error code otherwise + */ + +int +gfs_dir_read(struct gfs_inode *dip, uint64_t * offset, void *opaque, + gfs_filldir_t filldir) +{ + int error; + + if (dip->i_di.di_flags & GFS_DIF_EXHASH) + error = dir_e_read(dip, offset, opaque, filldir); + else + error = dir_l_read(dip, offset, opaque, filldir); + + return error; +} + +/** + * gfs_dir_mvino - Change inode number of directory entry + * @dip: The GFS inode + * @filename: + * @new_inode: + * + * This routine changes the inode number of a directory entry. It's used + * by rename to change ".." when a directory is moved. + * Assumes a glock is held on dvp. + * + * Returns: errno + */ + +int +gfs_dir_mvino(struct gfs_inode *dip, struct qstr *filename, + struct gfs_inum *inum, unsigned int new_type) +{ + int error; + + if (dip->i_di.di_flags & GFS_DIF_EXHASH) + error = dir_e_mvino(dip, filename, inum, new_type); + else + error = dir_l_mvino(dip, filename, inum, new_type); + + return error; +} + +/** + * foreach_leaf - call a function for each leaf in a directory + * @dip: the directory + * @lc: the function to call for each each + * @data: private data to pass to it + * + * Returns: errno + */ + +static int +foreach_leaf(struct gfs_inode *dip, leaf_call_t lc, void *data) +{ + struct gfs_sbd *sdp = dip->i_sbd; + struct buffer_head *bh; + struct gfs_leaf leaf; + uint32_t hsize, len; + uint32_t ht_offset, lp_offset, ht_offset_cur = -1; + uint32_t index = 0; + uint64_t *lp; + uint64_t leaf_no; + int error = 0; + + hsize = 1 << dip->i_di.di_depth; + if (hsize * sizeof(uint64_t) != dip->i_di.di_size) { + gfs_consist_inode(dip); + return -EIO; + } + + lp = kmalloc(sdp->sd_hash_bsize, GFP_KERNEL); + if (!lp) + return -ENOMEM; + + while (index < hsize) { + lp_offset = index & (sdp->sd_hash_ptrs - 1); + ht_offset = index - lp_offset; + + if (ht_offset_cur != ht_offset) { + error = gfs_internal_read(dip, (char *)lp, + ht_offset * sizeof(uint64_t), + sdp->sd_hash_bsize); + if (error != sdp->sd_hash_bsize) { + if (error >= 0) + error = -EIO; + goto out; + } + ht_offset_cur = ht_offset; + } + + leaf_no = gfs64_to_cpu(lp[lp_offset]); + if (leaf_no) { + error = get_leaf(dip, leaf_no, &bh); + if (error) + goto out; + gfs_leaf_in(&leaf, bh->b_data); + brelse(bh); + + len = 1 << (dip->i_di.di_depth - leaf.lf_depth); + + error = lc(dip, index, len, leaf_no, data); + if (error) + goto out; + + index = (index & ~(len - 1)) + len; + } else + index++; + } + + if (index != hsize) { + gfs_consist_inode(dip); + error = -EIO; + } + + out: + kfree(lp); + + return error; +} + +/** + * leaf_free - Deallocate a directory leaf + * @dip: the directory + * @index: the hash table offset in the directory + * @len: the number of pointers to this leaf + * @leaf_no: the leaf number + * @data: not used + * + * Returns: errno + */ + +static int +leaf_free(struct gfs_inode *dip, + uint32_t index, uint32_t len, + uint64_t leaf_no, void *data) +{ + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_leaf tmp_leaf; + struct gfs_rgrp_list rlist; + struct buffer_head *bh, *dibh; + uint64_t blk; + unsigned int rg_blocks = 0; + char *ht=0; + unsigned int x, size = len * sizeof(uint64_t); + int error; + + memset(&rlist, 0, sizeof(struct gfs_rgrp_list)); + + gfs_alloc_get(dip); + + error = gfs_quota_hold_m(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + if (error) + goto out; + + error = gfs_rindex_hold(sdp, &dip->i_alloc->al_ri_gh); + if (error) + goto out_qs; + + /* Count the number of leaves */ + + for (blk = leaf_no; blk; blk = tmp_leaf.lf_next) { + error = get_leaf(dip, blk, &bh); + if (error) + goto out_rlist; + gfs_leaf_in(&tmp_leaf, (bh)->b_data); + brelse(bh); + + gfs_rlist_add(sdp, &rlist, blk); + } + + gfs_rlist_alloc(&rlist, LM_ST_EXCLUSIVE, 0); + + for (x = 0; x < rlist.rl_rgrps; x++) { + struct gfs_rgrpd *rgd; + rgd = get_gl2rgd(rlist.rl_ghs[x].gh_gl); + rg_blocks += rgd->rd_ri.ri_length; + } + + error = gfs_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs); + if (error) + goto out_rlist; + + /* Trans may require: + All the bitmaps that were reserved. + One block for the dinode. + All the hash blocks that will be changed. + One block for a quota change. */ + + error = gfs_trans_begin(sdp, + rg_blocks + 1 + (DIV_RU(size, sdp->sd_jbsize) + 1), + 1); + if (error) + goto out_rg_gunlock; + + for (blk = leaf_no; blk; blk = tmp_leaf.lf_next) { + error = get_leaf(dip, blk, &bh); + if (error) + goto out_end_trans; + gfs_leaf_in(&tmp_leaf, bh->b_data); + brelse(bh); + + gfs_metafree(dip, blk, 1); + + if (!dip->i_di.di_blocks) + gfs_consist_inode(dip); + dip->i_di.di_blocks--; + } + + error = gfs_writei(dip, ht, index * sizeof (uint64_t), size, gfs_zero_blocks, NULL); + + if (error != size) { + if (error >= 0) + error = -EIO; + goto out_end_trans; + } + + error = gfs_get_inode_buffer(dip, &dibh); + if (error) + goto out_end_trans; + + gfs_trans_add_bh(dip->i_gl, dibh); + gfs_dinode_out(&dip->i_di, dibh->b_data); + brelse(dibh); + + out_end_trans: + gfs_trans_end(sdp); + + out_rg_gunlock: + gfs_glock_dq_m(rlist.rl_rgrps, rlist.rl_ghs); + + out_rlist: + gfs_rlist_free(&rlist); + gfs_glock_dq_uninit(&dip->i_alloc->al_ri_gh); + + out_qs: + gfs_quota_unhold_m(dip); + + out: + gfs_alloc_put(dip); + + return error; +} + +/** + * gfs_dir_exhash_free - free all the leaf blocks in a directory + * @dip: the directory + * + * Dealloc all on-disk directory leaves to FREEMETA state + * Change on-disk inode type to "regular file" + * + * Returns: errno + */ + +int +gfs_dir_exhash_free(struct gfs_inode *dip) +{ + struct gfs_sbd *sdp = dip->i_sbd; + struct buffer_head *bh; + int error; + + /* Dealloc on-disk leaves to FREEMETA state */ + error = foreach_leaf(dip, leaf_free, NULL); + if (error) + return error; + + /* Make this a regular file in case we crash. + (We don't want to free these blocks a second time.) */ + + error = gfs_trans_begin(sdp, 1, 0); + if (error) + return error; + + error = gfs_get_inode_buffer(dip, &bh); + if (!error) { + gfs_trans_add_bh(dip->i_gl, bh); + ((struct gfs_dinode *)bh->b_data)->di_type = cpu_to_gfs16(GFS_FILE_REG); + brelse(bh); + } + + gfs_trans_end(sdp); + + return error; +} + +/** + * gfs_diradd_alloc_required - figure out if an entry addition is going to require an allocation + * @ip: the file being written to + * @filname: the filename that's going to be added + * @alloc_required: the int is set to TRUE if an alloc is required, FALSE otherwise + * + * Returns: errno + */ + +int +gfs_diradd_alloc_required(struct gfs_inode *dip, struct qstr *filename, + int *alloc_required) +{ + struct buffer_head *bh = NULL, *bh_next; + uint32_t hsize, hash, index; + int error = 0; + + *alloc_required = FALSE; + + if (dip->i_di.di_flags & GFS_DIF_EXHASH) { + hsize = 1 << dip->i_di.di_depth; + if (hsize * sizeof(uint64_t) != dip->i_di.di_size) { + gfs_consist_inode(dip); + return -EIO; + } + + hash = gfs_dir_hash(filename->name, filename->len); + index = hash >> (32 - dip->i_di.di_depth); + + error = get_first_leaf(dip, index, &bh_next); + if (error) + return error; + + do { + if (bh) + brelse(bh); + + bh = bh_next; + + if (dirent_fits(dip, bh, filename->len)) + break; + + error = get_next_leaf(dip, bh, &bh_next); + if (error == -ENOENT) { + *alloc_required = TRUE; + error = 0; + break; + } + } + while (!error); + + brelse(bh); + } else { + error = gfs_get_inode_buffer(dip, &bh); + if (error) + return error; + + if (!dirent_fits(dip, bh, filename->len)) + *alloc_required = TRUE; + + brelse(bh); + } + + return error; +} + +/** + * do_gdm - copy out one leaf (or list of leaves) + * @dip: the directory + * @index: the hash table offset in the directory + * @len: the number of pointers to this leaf + * @leaf_no: the leaf number + * @data: a pointer to a struct gfs_user_buffer structure + * + * Returns: errno + */ + +static int +do_gdm(struct gfs_inode *dip, + uint32_t index, uint32_t len, uint64_t leaf_no, + void *data) +{ + struct gfs_user_buffer *ub = (struct gfs_user_buffer *)data; + struct gfs_leaf leaf; + struct buffer_head *bh; + uint64_t blk; + int error = 0; + + for (blk = leaf_no; blk; blk = leaf.lf_next) { + error = get_leaf(dip, blk, &bh); + if (error) + break; + + gfs_leaf_in(&leaf, bh->b_data); + + error = gfs_add_bh_to_ub(ub, bh); + + brelse(bh); + + if (error) + break; + } + + return error; +} + +/** + * gfs_get_dir_meta - return all the leaf blocks of a directory + * @dip: the directory + * @ub: the structure representing the meta + * + * Returns: errno + */ + +int +gfs_get_dir_meta(struct gfs_inode *dip, struct gfs_user_buffer *ub) +{ + return foreach_leaf(dip, do_gdm, ub); +} --- linux-2.6.28.orig/ubuntu/gfs/trans.h +++ linux-2.6.28/ubuntu/gfs/trans.h @@ -0,0 +1,24 @@ +#ifndef __TRANS_DOT_H__ +#define __TRANS_DOT_H__ + +#define TRANS_IS_NEW (53) +#define TRANS_IS_INCORE (54) +void gfs_trans_print(struct gfs_sbd *sdp, struct gfs_trans *tr, + unsigned int where); + +int gfs_trans_begin_i(struct gfs_sbd *sdp, + unsigned int meta_blocks, unsigned int extra_blocks, + char *file, unsigned int line); +#define gfs_trans_begin(sdp, mb, eb) \ +gfs_trans_begin_i((sdp), (mb), (eb), __FILE__, __LINE__) + +void gfs_trans_end(struct gfs_sbd *sdp); + +void gfs_trans_add_gl(struct gfs_glock *gl); +void gfs_trans_add_bh(struct gfs_glock *gl, struct buffer_head *bh); +struct gfs_unlinked *gfs_trans_add_unlinked(struct gfs_sbd *sdp, unsigned int type, + struct gfs_inum *inum); +void gfs_trans_add_quota(struct gfs_sbd *sdp, int64_t change, uint32_t uid, + uint32_t gid); + +#endif /* __TRANS_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/gfs.h +++ linux-2.6.28/ubuntu/gfs/gfs.h @@ -0,0 +1,89 @@ +#ifndef __GFS_DOT_H__ +#define __GFS_DOT_H__ + +#define RELEASE_VERSION "" + +#include "lm_interface.h" + +#include "gfs_ondisk.h" +#include "fixed_div64.h" +#include "lvb.h" +#include "incore.h" +#include "util.h" + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + +#define NO_CREATE (0) +#define CREATE (1) + +#if (BITS_PER_LONG == 64) +#define PRIu64 "lu" +#define PRId64 "ld" +#define PRIo64 "lo" +#define PRIx64 "lx" +#define PRIX64 "lX" +#define SCNu64 "lu" +#define SCNd64 "ld" +#define SCNo64 "lo" +#define SCNx64 "lx" +#define SCNX64 "lX" +#else +#define PRIu64 "Lu" +#define PRId64 "Ld" +#define PRIo64 "Lo" +#define PRIx64 "Lx" +#define PRIX64 "LX" +#define SCNu64 "Lu" +#define SCNd64 "Ld" +#define SCNo64 "Lo" +#define SCNx64 "Lx" +#define SCNX64 "LX" +#endif + +/* Divide num by den. Round up if there is a remainder. */ +#define DIV_RU(num, den) (((num) + (den) - 1) / (den)) +#define MAKE_MULT8(x) (((x) + 7) & ~7) + +#define GFS_FAST_NAME_SIZE (8) + +#define get_v2sdp(sb) ((struct gfs_sbd *)(sb)->s_fs_info) +#define set_v2sdp(sb, sdp) (sb)->s_fs_info = (sdp) +#define get_v2ip(inode) ((struct gfs_inode *)(inode)->i_private) +#define set_v2ip(inode, ip) (inode)->i_private = (ip) +#define get_v2fp(file) ((struct gfs_file *)(file)->private_data) +#define set_v2fp(file, fp) (file)->private_data = (fp) +#define get_v2bd(bh) ((struct gfs_bufdata *)(bh)->b_private) +#define set_v2bd(bh, bd) (bh)->b_private = (bd) + +#define get_transaction ((struct gfs_trans *)(current->journal_info)) +#define set_transaction(tr) (current->journal_info) = (tr) + +#define get_gl2ip(gl) ((struct gfs_inode *)(gl)->gl_object) +#define set_gl2ip(gl, ip) (gl)->gl_object = (ip) +#define get_gl2rgd(gl) ((struct gfs_rgrpd *)(gl)->gl_object) +#define set_gl2rgd(gl, rgd) (gl)->gl_object = (rgd) +#define get_gl2gl(gl) ((struct gfs_glock *)(gl)->gl_object) +#define set_gl2gl(gl, gl2) (gl)->gl_object = (gl2) + +#define gfs_printf(fmt, args...) \ +do { \ + if (buf) { \ + int gspf_left = size - *count, gspf_out; \ + if (gspf_left <= 0) \ + goto out; \ + gspf_out = snprintf(buf + *count, gspf_left, fmt, ##args); \ + if (gspf_out < gspf_left) \ + *count += gspf_out; \ + else \ + goto out; \ + } else \ + printk(fmt, ##args); \ +} while (0) + +#endif /* __GFS_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/recovery.c +++ linux-2.6.28/ubuntu/gfs/recovery.c @@ -0,0 +1,780 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "dio.h" +#include "glock.h" +#include "glops.h" +#include "lm.h" +#include "lops.h" +#include "recovery.h" + +#define bn2seg(bn) (((uint32_t)((bn) - jdesc->ji_addr)) / sdp->sd_sb.sb_seg_size) +#define seg2bn(seg) ((seg) * sdp->sd_sb.sb_seg_size + jdesc->ji_addr) + +struct dirty_j { + struct list_head dj_list; + unsigned int dj_jid; + struct gfs_jindex dj_desc; +}; + +/** + * gfs_add_dirty_j - add a jid to the list of dirty journals + * @sdp: the filesystem + * @jid: the journal ID number + * + */ + +void +gfs_add_dirty_j(struct gfs_sbd *sdp, unsigned int jid) +{ + struct dirty_j *dj; + + dj = gmalloc(sizeof(struct dirty_j)); + memset(dj, 0, sizeof(struct dirty_j)); + + dj->dj_jid = jid; + + spin_lock(&sdp->sd_dirty_j_lock); + list_add(&dj->dj_list, &sdp->sd_dirty_j); + spin_unlock(&sdp->sd_dirty_j_lock); +} + +/** + * get_dirty_j - return a dirty journal from the list + * @sdp: the filesystem + * + * Returns: a struct dirty_j or NULL + */ + +static struct dirty_j * +get_dirty_j(struct gfs_sbd *sdp) +{ + struct dirty_j *dj = NULL; + + spin_lock(&sdp->sd_dirty_j_lock); + if (!list_empty(&sdp->sd_dirty_j)) { + dj = list_entry(sdp->sd_dirty_j.prev, struct dirty_j, dj_list); + list_del(&dj->dj_list); + } + spin_unlock(&sdp->sd_dirty_j_lock); + + return dj; +} + +/** + * gfs_clear_dirty_j - destroy the list of dirty journals + * @sdp: the filesystem + * + */ + +void +gfs_clear_dirty_j(struct gfs_sbd *sdp) +{ + struct dirty_j *dj; + for (;;) { + dj = get_dirty_j(sdp); + if (!dj) + break; + kfree(dj); + } +} + +/** + * gfs_log_header - read the log header for a given segment + * @sdp: the filesystem + * @jdesc: the journal + * @gl: the journal's glock + * @seg: the segment to look at + * @lh: the log header to return + * + * Read the log header for a given segement in a given journal. Do a few + * sanity checks on it. + * + * Returns: 0 on success, 1 if the header was invalid or incomplete and, errno on error + */ + +static int +get_log_header(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, uint32_t seg, struct gfs_log_header *lh) +{ + struct buffer_head *bh; + struct gfs_log_header lh2; + int error; + + error = gfs_dread(gl, seg2bn(seg), DIO_START | DIO_WAIT, &bh); + if (error) + return error; + + gfs_log_header_in(lh, bh->b_data); + gfs_log_header_in(&lh2, + bh->b_data + GFS_BASIC_BLOCK - + sizeof(struct gfs_log_header)); + + brelse(bh); + + if (memcmp(lh, &lh2, sizeof(struct gfs_log_header)) != 0 || + lh->lh_header.mh_magic != GFS_MAGIC || + lh->lh_header.mh_type != GFS_METATYPE_LH) + error = 1; + + return error; +} + +/** + * find_good_lh - find a good log header + * @sdp: the filesystem + * @jdesc: the journal + * @gl: the journal's glock + * @seg: the segment to start searching from (it's also filled in with a new value.) + * @lh: the log header to fill in + * @forward: if true search forward in the log, else search backward + * + * Call get_log_header() to get a log header for a segment, but if the + * segment is bad, either scan forward or backward until we find a good one. + * + * Returns: errno + */ + +static int +find_good_lh(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, uint32_t *seg, struct gfs_log_header *lh, + int forward) +{ + int error; + uint32_t orig_seg = *seg; + + for (;;) { + error = get_log_header(sdp, jdesc, gl, *seg, lh); + if (error <= 0) + return error; + + if (forward) { + if (++*seg == jdesc->ji_nsegment) + *seg = 0; + } else { + if ((*seg)-- == 0) + *seg = jdesc->ji_nsegment - 1; + } + + if (*seg == orig_seg) { + gfs_consist(sdp); + return -EIO; + } + } +} + +/** + * verify_jhead - make sure we've found the head of the log + * @sdp: the filesystem + * @jdesc: the journal + * @gl: the journal's glock + * @head: this is filled in with the log descriptor of the head + * + * At this point, seg and lh should be either the head of the log or just + * before. Scan forward until we find the head. + * + * Returns: errno + */ + +static int +verify_jhead(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, struct gfs_log_header *head) +{ + struct gfs_log_header lh; + uint32_t seg; + int error; + + seg = bn2seg(head->lh_first); + + for (;;) { + if (++seg == jdesc->ji_nsegment) + seg = 0; + + error = get_log_header(sdp, jdesc, gl, seg, &lh); + if (error < 0) + return error; + + if (error == 1) + continue; + if (lh.lh_sequence == head->lh_sequence) + continue; + + if (lh.lh_sequence < head->lh_sequence) + break; + + memcpy(head, &lh, sizeof(struct gfs_log_header)); + } + + return 0; +} + +/** + * gfs_find_jhead - find the head of a log + * @sdp: the filesystem + * @jdesc: the journal + * @gl: the journal's glock + * @head: the log descriptor for the head of the log is returned here + * + * Do a binary search of a journal and find the valid log entry with the + * highest sequence number. (i.e. the log head) + * + * Returns: errno + */ + +int +gfs_find_jhead(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, struct gfs_log_header *head) +{ + struct gfs_log_header lh; + uint32_t seg1, seg2, seg_m; + int error; + uint64_t lh1_sequence; + + seg1 = 0; + seg2 = jdesc->ji_nsegment - 1; + + for (;;) { + seg_m = (seg1 + seg2) / 2; + + error = find_good_lh(sdp, jdesc, gl, &seg1, &lh, TRUE); + if (error) + break; + + if (seg1 == seg_m) { + error = verify_jhead(sdp, jdesc, gl, &lh); + if (unlikely(error)) + printk("GFS: verify_jhead error=%d\n", error); + else + memcpy(head, &lh, sizeof(struct gfs_log_header)); + break; + } + + lh1_sequence = lh.lh_sequence; + + error = find_good_lh(sdp, jdesc, gl, &seg_m, &lh, FALSE); + if (error) + break; + + if (lh1_sequence <= lh.lh_sequence) + seg1 = seg_m; + else + seg2 = seg_m; + } + + return error; +} + +/** + * gfs_increment_blkno - move to the next block in a journal + * @sdp: the filesystem + * @jdesc: the journal + * @gl: the journal's glock + * @addr: the block number to increment + * @skip_header: if this is TRUE, skip log headers + * + * Replace @addr with the location of the next block in the log. + * Take care of journal wrap and skip of log header if necessary. + * + * Returns: errno + */ + +int +gfs_increment_blkno(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, uint64_t *addr, int skip_headers) +{ + struct gfs_log_header header; + int error; + + (*addr)++; + + /* Handle journal wrap */ + + if (*addr == seg2bn(jdesc->ji_nsegment)) + *addr -= jdesc->ji_nsegment * sdp->sd_sb.sb_seg_size; + + gfs_start_ra(gl, *addr, + jdesc->ji_addr + + jdesc->ji_nsegment * sdp->sd_sb.sb_seg_size - *addr); + + /* Handle landing on a header block */ + + if (skip_headers && !do_mod(*addr, sdp->sd_sb.sb_seg_size)) { + error = get_log_header(sdp, jdesc, gl, bn2seg(*addr), &header); + if (error < 0) + return error; + + if (error) { /* Corrupt headers here are bad */ + if (gfs_consist(sdp)) + printk("GFS: fsid=%s: *addr = %"PRIu64"\n", + sdp->sd_fsname, *addr); + return -EIO; + } + if (header.lh_first == *addr) { + if (gfs_consist(sdp)) + printk("GFS: fsid=%s: *addr = %"PRIu64"\n", + sdp->sd_fsname, *addr); + gfs_log_header_print(&header); + return -EIO; + } + + (*addr)++; + /* Can't wrap here */ + } + + return 0; +} + +/** + * foreach_descriptor - go through the active part of the log + * @sdp: the filesystem + * @jdesc: the journal + * @gl: the journal's glock + * @start: the first log header in the active region + * @end: the last log header (don't process the contents of this entry)) + * @pass: the recovery pass + * + * Call a given function once for every log descriptor in the active + * portion of the log. + * + * Returns: errno + */ + +static int +foreach_descriptor(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, uint64_t start, uint64_t end, + unsigned int pass) +{ + struct gfs_log_header header; + struct gfs_log_descriptor desc; + struct buffer_head *bh; + int error = 0; + + while (start != end) { + if (do_mod(start, sdp->sd_sb.sb_seg_size)) { + gfs_consist(sdp); + return -EIO; + } + + error = get_log_header(sdp, jdesc, gl, bn2seg(start), &header); + if (error < 0) + return error; + + if (error) { /* Corrupt headers here are bad */ + if (gfs_consist(sdp)) + printk("GFS: fsid=%s: start = %"PRIu64"\n", + sdp->sd_fsname, start); + return -EIO; + } + if (header.lh_first != start) { + if (gfs_consist(sdp)) + printk("GFS: fsid=%s: start = %"PRIu64"\n", + sdp->sd_fsname, start); + gfs_log_header_print(&header); + return -EIO; + } + + start++; + + for (;;) { + error = gfs_dread(gl, start, DIO_START | DIO_WAIT, &bh); + if (error) + return error; + + if (gfs_metatype_check(sdp, bh, GFS_METATYPE_LD)) { + brelse(bh); + return -EIO; + } + + gfs_desc_in(&desc, bh->b_data); + brelse(bh); + + if (desc.ld_type != GFS_LOG_DESC_LAST) { + error = LO_SCAN_ELEMENTS(sdp, jdesc, gl, start, + &desc, pass); + if (error) + return error; + + while (desc.ld_length--) { + error = gfs_increment_blkno(sdp, jdesc, gl, + &start, TRUE); + if (error) + return error; + } + } else { + while (desc.ld_length--) { + error = gfs_increment_blkno(sdp, jdesc, gl, + &start, + !!desc.ld_length); + if (error) + return error; + } + + break; + } + } + } + + return error; +} + +/** + * clean_journal - mark a dirty journal as being clean + * @sdp: the filesystem + * @jdesc: the journal + * @gl: the journal's glock + * @head: the head journal to start from + * + * Returns: errno + */ + +static int noinline +clean_journal(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, struct gfs_log_header *head) +{ + struct gfs_log_header lh; + struct gfs_log_descriptor desc; + struct buffer_head *bh; + uint32_t seg; + uint64_t blkno; + int error; + + seg = bn2seg(head->lh_first); + + for (;;) { + if (++seg == jdesc->ji_nsegment) + seg = 0; + + error = get_log_header(sdp, jdesc, gl, seg, &lh); + if (error < 0) + return error; + + /* Rewrite corrupt header blocks */ + + if (error == 1) { + bh = gfs_dgetblk(gl, seg2bn(seg)); + + gfs_prep_new_buffer(bh); + gfs_buffer_clear(bh); + gfs_log_header_out(head, bh->b_data); + gfs_log_header_out(head, + bh->b_data + GFS_BASIC_BLOCK - + sizeof(struct gfs_log_header)); + + error = gfs_dwrite(sdp, bh, DIO_DIRTY | DIO_START | DIO_WAIT); + brelse(bh); + if (error) + return error; + } + + /* Stop when we get to the end of the log. */ + + if (lh.lh_sequence < head->lh_sequence) + break; + } + + /* Build a "last" descriptor for the transaction we are + about to commit by writing the shutdown header. */ + + memset(&desc, 0, sizeof(struct gfs_log_descriptor)); + desc.ld_header.mh_magic = GFS_MAGIC; + desc.ld_header.mh_type = GFS_METATYPE_LD; + desc.ld_header.mh_format = GFS_FORMAT_LD; + desc.ld_type = GFS_LOG_DESC_LAST; + desc.ld_length = 0; + + for (blkno = head->lh_first + 1; blkno != seg2bn(seg);) { + if (do_mod(blkno, sdp->sd_sb.sb_seg_size)) + desc.ld_length++; + if (++blkno == seg2bn(jdesc->ji_nsegment)) + blkno -= jdesc->ji_nsegment * sdp->sd_sb.sb_seg_size; + } + + /* Write the descriptor */ + + bh = gfs_dgetblk(gl, head->lh_first + 1); + + gfs_prep_new_buffer(bh); + gfs_buffer_clear(bh); + gfs_desc_out(&desc, bh->b_data); + + error = gfs_dwrite(sdp, bh, DIO_DIRTY | DIO_START | DIO_WAIT); + brelse(bh); + if (error) + return error; + + /* Build a log header that says the journal is clean */ + + memset(&lh, 0, sizeof(struct gfs_log_header)); + lh.lh_header.mh_magic = GFS_MAGIC; + lh.lh_header.mh_type = GFS_METATYPE_LH; + lh.lh_header.mh_format = GFS_FORMAT_LH; + lh.lh_flags = GFS_LOG_HEAD_UNMOUNT; + lh.lh_first = seg2bn(seg); + lh.lh_sequence = head->lh_sequence + 1; + /* Don't care about tail */ + lh.lh_last_dump = head->lh_last_dump; + + /* Write the header */ + + bh = gfs_dgetblk(gl, lh.lh_first); + + gfs_prep_new_buffer(bh); + gfs_buffer_clear(bh); + gfs_log_header_out(&lh, bh->b_data); + gfs_log_header_out(&lh, + bh->b_data + GFS_BASIC_BLOCK - + sizeof(struct gfs_log_header)); + + error = gfs_dwrite(sdp, bh, DIO_DIRTY | DIO_START | DIO_WAIT); + brelse(bh); + + return error; +} + +/** + * gfs_recover_journal - recover a given journal + * @sdp: the filesystem + * @jid: the number of the journal to recover + * @jdesc: the struct gfs_jindex describing the journal + * @wait: Don't return until the journal is clean (or an error is encountered) + * + * Acquire the journal's lock, check to see if the journal is clean, and + * do recovery if necessary. + * + * Returns: errno + */ + +int +gfs_recover_journal(struct gfs_sbd *sdp, + unsigned int jid, struct gfs_jindex *jdesc, + int wait) +{ + struct gfs_log_header *head; + struct gfs_holder j_gh, t_gh; + unsigned long t; + int error; + + printk("GFS: fsid=%s: jid=%u: Trying to acquire journal lock...\n", + sdp->sd_fsname, jid); + + /* Acquire the journal lock so we can do recovery */ + + error = gfs_glock_nq_num(sdp, + jdesc->ji_addr, &gfs_meta_glops, + LM_ST_EXCLUSIVE, + LM_FLAG_NOEXP | + ((wait) ? 0 : LM_FLAG_TRY) | + GL_NOCACHE, &j_gh); + switch (error) { + case 0: + break; + + case GLR_TRYFAILED: + printk("GFS: fsid=%s: jid=%u: Busy\n", sdp->sd_fsname, jid); + error = 0; + + default: + goto fail; + }; + + printk("GFS: fsid=%s: jid=%u: Looking at journal...\n", + sdp->sd_fsname, jid); + + head = kmalloc(sizeof(struct gfs_log_header), GFP_KERNEL); + if (!head) { + printk("GFS: fsid=%s jid=%u: Can't replay: Not enough memory", + sdp->sd_fsname, jid); + goto fail_gunlock; + } + + error = gfs_find_jhead(sdp, jdesc, j_gh.gh_gl, head); + if (error) + goto fail_header; + + if (!(head->lh_flags & GFS_LOG_HEAD_UNMOUNT)) { + if (test_bit(SDF_ROFS, &sdp->sd_flags)) { + printk("GFS: fsid=%s: jid=%u: Can't replay: read-only FS\n", + sdp->sd_fsname, jid); + error = -EROFS; + goto fail_header; + } + + printk("GFS: fsid=%s: jid=%u: Acquiring the transaction lock...\n", + sdp->sd_fsname, jid); + + t = jiffies; + + /* Acquire an exclusive hold on the transaction lock */ + + error = gfs_glock_nq_init(sdp->sd_trans_gl, + LM_ST_EXCLUSIVE, + LM_FLAG_NOEXP | + LM_FLAG_PRIORITY | + GL_NOCANCEL | + GL_NOCACHE, + &t_gh); + if (error) + goto fail_header; + + if (test_bit(SDF_ROFS, &sdp->sd_flags)) { + printk("GFS: fsid=%s: jid=%u: Can't replay: read-only FS\n", + sdp->sd_fsname, jid); + error = -EROFS; + goto fail_gunlock_tr; + } + + printk("GFS: fsid=%s: jid=%u: Replaying journal...\n", + sdp->sd_fsname, jid); + + set_bit(GLF_DIRTY, &j_gh.gh_gl->gl_flags); + + LO_BEFORE_SCAN(sdp, jid, head, GFS_RECPASS_A1); + + error = foreach_descriptor(sdp, jdesc, j_gh.gh_gl, + head->lh_tail, head->lh_first, + GFS_RECPASS_A1); + if (error) + goto fail_gunlock_tr; + + LO_AFTER_SCAN(sdp, jid, GFS_RECPASS_A1); + + gfs_replay_wait(sdp); + + error = clean_journal(sdp, jdesc, j_gh.gh_gl, head); + if (error) + goto fail_gunlock_tr; + + gfs_glock_dq_uninit(&t_gh); + + t = DIV_RU(jiffies - t, HZ); + + printk("GFS: fsid=%s: jid=%u: Journal replayed in %lus\n", + sdp->sd_fsname, jid, t); + } + + gfs_lm_recovery_done(sdp, jid, LM_RD_SUCCESS); + + kfree(head); + + gfs_glock_dq_uninit(&j_gh); + + printk("GFS: fsid=%s: jid=%u: Done\n", sdp->sd_fsname, jid); + + return 0; + + fail_gunlock_tr: + gfs_replay_wait(sdp); + gfs_glock_dq_uninit(&t_gh); + + fail_header: + kfree(head); + + fail_gunlock: + gfs_glock_dq_uninit(&j_gh); + + printk("GFS: fsid=%s: jid=%u: %s\n", + sdp->sd_fsname, jid, (error) ? "Failed" : "Done"); + + fail: + gfs_lm_recovery_done(sdp, jid, LM_RD_GAVEUP); + + return error; +} + +/** + * gfs_check_journals - Recover any dirty journals + * @sdp: the filesystem + * + */ + +void +gfs_check_journals(struct gfs_sbd *sdp) +{ + struct dirty_j *dj; + + for (;;) { + dj = get_dirty_j(sdp); + if (!dj) + break; + + down(&sdp->sd_jindex_lock); + + if (dj->dj_jid != sdp->sd_lockstruct.ls_jid && + dj->dj_jid < sdp->sd_journals) { + memcpy(&dj->dj_desc, + sdp->sd_jindex + dj->dj_jid, + sizeof(struct gfs_jindex)); + up(&sdp->sd_jindex_lock); + + gfs_recover_journal(sdp, + dj->dj_jid, &dj->dj_desc, + FALSE); + + } else { + up(&sdp->sd_jindex_lock); + gfs_lm_recovery_done(sdp, dj->dj_jid, LM_RD_GAVEUP); + } + + kfree(dj); + } +} + +/** + * gfs_recover_dump - recover the log elements in this machine's journal + * @sdp: the filesystem + * + * Returns: errno + */ + +int +gfs_recover_dump(struct gfs_sbd *sdp) +{ + struct gfs_log_header head; + int error; + + error = gfs_find_jhead(sdp, &sdp->sd_jdesc, sdp->sd_journal_gh.gh_gl, + &head); + if (error) + goto fail; + + if (!(head.lh_flags & GFS_LOG_HEAD_UNMOUNT)) { + gfs_consist(sdp); + return -EIO; + } + if (!head.lh_last_dump) + return error; + + printk("GFS: fsid=%s: Scanning for log elements...\n", + sdp->sd_fsname); + + LO_BEFORE_SCAN(sdp, sdp->sd_lockstruct.ls_jid, &head, GFS_RECPASS_B1); + + error = foreach_descriptor(sdp, &sdp->sd_jdesc, sdp->sd_journal_gh.gh_gl, + head.lh_last_dump, head.lh_first, + GFS_RECPASS_B1); + if (error) + goto fail; + + LO_AFTER_SCAN(sdp, sdp->sd_lockstruct.ls_jid, GFS_RECPASS_B1); + + /* We need to make sure if we crash during the next log dump that + all intermediate headers in the transaction point to the last + log dump before the one we're making so we don't lose it. */ + + sdp->sd_log_dump_last = head.lh_last_dump; + + printk("GFS: fsid=%s: Done\n", sdp->sd_fsname); + + return 0; + + fail: + printk("GFS: fsid=%s: Failed\n", sdp->sd_fsname); + + return error; +} --- linux-2.6.28.orig/ubuntu/unionfs/rename.c +++ linux-2.6.28/ubuntu/unionfs/rename.c @@ -0,0 +1,943 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: rename.c,v 1.47 2006/08/05 01:28:46 jro Exp $ + */ + +#include "unionfs.h" + +static int do_rename(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry, + int bindex, struct dentry **wh_old) +{ + int err = 0; + struct dentry *hidden_old_dentry; + struct dentry *hidden_new_dentry; + struct dentry *hidden_old_dir_dentry; + struct dentry *hidden_new_dir_dentry; + struct dentry *hidden_wh_dentry; + struct dentry *hidden_wh_dir_dentry; + char *wh_name = NULL; + + print_entry(" bindex=%d", bindex); + + print_dentry("IN: do_rename, old_dentry", old_dentry); + print_dentry("IN: do_rename, new_dentry", new_dentry); + dprint(PRINT_DEBUG, "do_rename for bindex = %d\n", bindex); + + hidden_new_dentry = dtohd_index(new_dentry, bindex); + hidden_old_dentry = dtohd_index(old_dentry, bindex); + + if (!hidden_new_dentry) { + hidden_new_dentry = + create_parents(new_dentry->d_parent->d_inode, new_dentry, + bindex); + if (IS_ERR(hidden_new_dentry)) { + dprint(PRINT_DEBUG, + "error creating directory tree for rename, bindex = %d\n", + bindex); + err = PTR_ERR(hidden_new_dentry); + goto out; + } + } + + wh_name = alloc_whname(new_dentry->d_name.name, new_dentry->d_name.len); + if (IS_ERR(wh_name)) { + err = PTR_ERR(wh_name); + goto out; + } + + hidden_wh_dentry = + LOOKUP_ONE_LEN(wh_name, hidden_new_dentry->d_parent, + new_dentry->d_name.len + WHLEN); + if (IS_ERR(hidden_wh_dentry)) { + err = PTR_ERR(hidden_wh_dentry); + goto out; + } + + if (hidden_wh_dentry->d_inode) { + /* get rid of the whiteout that is existing */ + if (hidden_new_dentry->d_inode) { + printk(KERN_WARNING + "Both a whiteout and a dentry exist when doing a rename!\n"); + err = -EIO; + + DPUT(hidden_wh_dentry); + goto out; + } + + hidden_wh_dir_dentry = lock_parent(hidden_wh_dentry); + if (!(err = is_robranch_super(old_dentry->d_sb, bindex))) { + err = + vfs_unlink(hidden_wh_dir_dentry->d_inode, + hidden_wh_dentry, NULL); + } + DPUT(hidden_wh_dentry); + unlock_dir(hidden_wh_dir_dentry); + if (err) + goto out; + } else + DPUT(hidden_wh_dentry); + + DGET(hidden_old_dentry); + hidden_old_dir_dentry = GET_PARENT(hidden_old_dentry); + hidden_new_dir_dentry = GET_PARENT(hidden_new_dentry); + + lock_rename(hidden_old_dir_dentry, hidden_new_dir_dentry); + + err = is_robranch_super(old_dentry->d_sb, bindex); + if (err) + goto out_unlock; + + /* ready to whiteout for old_dentry. + caller will create the actual whiteout, + and must dput(*wh_old) */ + if (wh_old) { + char *whname; + whname = alloc_whname(old_dentry->d_name.name, + old_dentry->d_name.len); + err = PTR_ERR(whname); + if (IS_ERR(whname)) + goto out_unlock; + *wh_old = LOOKUP_ONE_LEN(whname, hidden_old_dir_dentry, + old_dentry->d_name.len + WHLEN); + KFREE(whname); + err = PTR_ERR(*wh_old); + if (IS_ERR(*wh_old)) { + *wh_old = NULL; + goto out_unlock; + } + } + + print_dentry("NEWBEF", new_dentry); + print_dentry("OLDBEF", old_dentry); + err = vfs_rename(hidden_old_dir_dentry->d_inode, hidden_old_dentry, + NULL, hidden_new_dir_dentry->d_inode, + hidden_new_dentry, NULL); + print_dentry("NEWAFT", new_dentry); + print_dentry("OLDAFT", old_dentry); + + out_unlock: + unlock_rename(hidden_old_dir_dentry, hidden_new_dir_dentry); + + DPUT(hidden_old_dir_dentry); + DPUT(hidden_new_dir_dentry); + DPUT(hidden_old_dentry); + + out: + if (!err) { + /* Fixup the newdentry. */ + if (bindex < dbstart(new_dentry)) + set_dbstart(new_dentry, bindex); + else if (bindex > dbend(new_dentry)) + set_dbend(new_dentry, bindex); + } + + KFREE(wh_name); + + print_dentry("OUT: do_rename, old_dentry", old_dentry); + print_dentry("OUT: do_rename, new_dentry", new_dentry); + + print_exit_status(err); + return err; +} + +static int unionfs_rename_whiteout(struct inode *old_dir, + struct dentry *old_dentry, + struct inode *new_dir, + struct dentry *new_dentry) +{ + int err = 0; + int bindex, bwh_old; + int old_bstart, old_bend; + int new_bstart, new_bend; + int do_copyup = -1; + struct dentry *parent_dentry; + int local_err = 0; + int eio = 0; + int revert = 0; + struct dentry *wh_old = NULL; + + print_entry_location(); + + old_bstart = dbstart(old_dentry); + bwh_old = old_bstart; + old_bend = dbend(old_dentry); + parent_dentry = old_dentry->d_parent; + + new_bstart = dbstart(new_dentry); + new_bend = dbend(new_dentry); + + /* Rename source to destination. */ + err = do_rename(old_dir, old_dentry, new_dir, new_dentry, old_bstart, + &wh_old); + if (err) { + if (!IS_COPYUP_ERR(err)) { + goto out; + } + do_copyup = old_bstart - 1; + } else { + revert = 1; + } + + /* Unlink all instances of destination that exist to the left of + * bstart of source. On error, revert back, goto out. + */ + for (bindex = old_bstart - 1; bindex >= new_bstart; bindex--) { + struct dentry *unlink_dentry; + struct dentry *unlink_dir_dentry; + + unlink_dentry = dtohd_index(new_dentry, bindex); + if (!unlink_dentry) { + continue; + } + + unlink_dir_dentry = lock_parent(unlink_dentry); + if (!(err = is_robranch_super(old_dir->i_sb, bindex))) { + err = + vfs_unlink(unlink_dir_dentry->d_inode, + unlink_dentry, NULL); + } + + fist_copy_attr_times(new_dentry->d_parent->d_inode, + unlink_dir_dentry->d_inode); + /* propagate number of hard-links */ + new_dentry->d_parent->d_inode->i_nlink = + get_nlinks(new_dentry->d_parent->d_inode); + + unlock_dir(unlink_dir_dentry); + if (!err) { + if (bindex != new_bstart) { + DPUT(unlink_dentry); + set_dtohd_index(new_dentry, bindex, NULL); + } + } else if (IS_COPYUP_ERR(err)) { + do_copyup = bindex - 1; + } else if (revert) { + DPUT(wh_old); + goto revert; + } + } + + if (do_copyup != -1) { + for (bindex = do_copyup; bindex >= 0; bindex--) { + /* copyup the file into some left directory, so that you can rename it */ + err = + copyup_dentry(old_dentry->d_parent->d_inode, + old_dentry, old_bstart, bindex, NULL, + old_dentry->d_inode->i_size); + if (!err) { + DPUT(wh_old); + bwh_old = bindex; + err = + do_rename(old_dir, old_dentry, new_dir, + new_dentry, bindex, &wh_old); + break; + } + } + } + + /* make it opaque */ + if (S_ISDIR(old_dentry->d_inode->i_mode)) { + err = make_dir_opaque(old_dentry, dbstart(old_dentry)); + if (err) + goto revert; + } + + /* Create whiteout for source, only if: + * (1) There is more than one underlying instance of source. + * (2) We did a copy_up + */ + if ((old_bstart != old_bend) || (do_copyup != -1)) { + struct dentry *hidden_parent; + BUG_ON(!wh_old || IS_ERR(wh_old) || wh_old->d_inode + || bwh_old < 0); + hidden_parent = lock_parent(wh_old); + local_err = vfs_create(hidden_parent->d_inode, wh_old, S_IRUGO, + NULL); + unlock_dir(hidden_parent); + if (!local_err) + set_dbopaque(old_dentry, bwh_old); + else { + /* We can't fix anything now, so we cop-out and use -EIO. */ + printk + ("<0>We can't create a whiteout for the source in rename!\n"); + err = -EIO; + } + } + + out: + DPUT(wh_old); + print_exit_status(err); + return err; + + revert: + /* Do revert here. */ + local_err = unionfs_refresh_hidden_dentry(new_dentry, old_bstart); + if (local_err) { + printk(KERN_WARNING + "Revert failed in rename: the new refresh failed.\n"); + eio = -EIO; + } + + local_err = unionfs_refresh_hidden_dentry(old_dentry, old_bstart); + if (local_err) { + printk(KERN_WARNING + "Revert failed in rename: the old refresh failed.\n"); + eio = -EIO; + goto revert_out; + } + + if (!dtohd_index(new_dentry, bindex) + || !dtohd_index(new_dentry, bindex)->d_inode) { + printk(KERN_WARNING + "Revert failed in rename: the object disappeared from under us!\n"); + eio = -EIO; + goto revert_out; + } + + if (dtohd_index(old_dentry, bindex) + && dtohd_index(old_dentry, bindex)->d_inode) { + printk(KERN_WARNING + "Revert failed in rename: the object was created underneath us!\n"); + eio = -EIO; + goto revert_out; + } + + local_err = + do_rename(new_dir, new_dentry, old_dir, old_dentry, old_bstart, + NULL); + + /* If we can't fix it, then we cop-out with -EIO. */ + if (local_err) { + printk(KERN_WARNING "Revert failed in rename!\n"); + eio = -EIO; + } + + local_err = unionfs_refresh_hidden_dentry(new_dentry, bindex); + if (local_err) + eio = -EIO; + local_err = unionfs_refresh_hidden_dentry(old_dentry, bindex); + if (local_err) + eio = -EIO; + + revert_out: + if (eio) + err = eio; + print_exit_status(err); + return err; +} + +/* + * Unfortunately, we cannot simply call things like dbstart() in different + * places of the rename code because we move things around. So, we use this + * structure to pass the necessary information around to all the places that + * need it. + */ +struct rename_info { + int do_copyup; + int do_whiteout; + int rename_ok; + + int old_bstart; + int old_bend; + int new_bstart; + int new_bend; + + int isdir; /* Is the source a directory? */ + int clobber; /* Are we clobbering the destination? */ + + int bwh_old; /* where we create the whiteout */ + struct dentry *wh_old; /* lookup and set by do_rename() */ +}; +#ifdef UNIONFS_DELETE_ALL +/* + * Rename all occurences of source except for the leftmost destination + */ +static int __rename_all(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry, + fd_set * success_mask, struct rename_info *info) +{ + int bindex; + int err = 0; + + print_entry_location(); + + /* Loop through all the branches from right to left and rename all + * instances of source to destination, except the leftmost destination + */ + for (bindex = info->old_bend; bindex >= info->old_bstart; bindex--) { + /* We don't rename if there is no source. */ + if (dtohd_index(old_dentry, bindex) == NULL) + continue; + + /* we rename the bstart of destination only at the last of + * all operations, so that we don't lose it on error + */ + if (info->clobber && (bindex == info->new_bstart)) + continue; + + DPUT(info->wh_old); + info->bwh_old = bindex; + /* We shouldn't have a handle on this if there is no inode. */ + err = + do_rename(old_dir, old_dentry, new_dir, new_dentry, bindex, + &info->wh_old); + if (!err) { + /* For reverting. */ + FD_SET(bindex, success_mask); + /* So we know not to copyup on failures the right */ + info->rename_ok = bindex; + } else if (IS_COPYUP_ERR(err)) { + if (info->isdir) { + err = -EXDEV; + break; + } + + /* we need a whiteout... */ + info->do_whiteout = bindex - 1; + + if (bindex == info->old_bstart) + /* ...and a copyup */ + info->do_copyup = bindex - 1; + + err = 0; /* reset error */ + } else + break; /* error is set by do_rename */ + } + + print_exit_status(err); + return err; +} + +/* + * Unlink all destinations (if they exist) to the left of the left-most + * source + */ +static int __rename_all_unlink(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry, + struct rename_info *info) +{ + int bindex; + + struct dentry *unlink_dentry; + struct dentry *unlink_dir_dentry; + + int err = 0; + + print_entry_location(); + + for (bindex = info->old_bstart - 1; bindex > info->new_bstart; bindex--) { + unlink_dentry = dtohd_index(new_dentry, bindex); + if (!unlink_dentry) + continue; + + /* lock, unlink if possible, copyup times, unlock */ + unlink_dir_dentry = lock_parent(unlink_dentry); + if (!(err = is_robranch_super(old_dir->i_sb, bindex))) + err = + vfs_unlink(unlink_dir_dentry->d_inode, + unlink_dentry, NULL); + + fist_copy_attr_times(new_dentry->d_parent->d_inode, + unlink_dir_dentry->d_inode); + new_dentry->d_parent->d_inode->i_nlink = + get_nlinks(new_dentry->d_parent->d_inode); + + unlock_dir(unlink_dir_dentry); + + if (!err) { + if (bindex != info->new_bstart) { + DPUT(unlink_dentry); + set_dtohd_index(new_dentry, bindex, NULL); + } + } else if (IS_COPYUP_ERR(err)) { + if (info->isdir) { + err = -EXDEV; + break; + } + info->do_copyup = bindex - 1; + + err = 0; /* reset error */ + } else + break; /* err is set by is_ro_branch_super or vfs_unlink */ + } + + print_exit_status(err); + return err; +} + +/* + * Try to revert everything we have done in __rename_all and __rename_all_unlink + */ +static int __rename_all_revert(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry, + fd_set * success_mask, struct rename_info *info) +{ + int bindex; + + int err; + int eio = 0; + + print_entry_location(); + + for (bindex = info->old_bstart; bindex <= info->old_bend; bindex++) { + if (!FD_ISSET(bindex, success_mask)) + continue; + + err = unionfs_refresh_hidden_dentry(new_dentry, bindex); + if (err) { + printk(KERN_WARNING "Revert failed in rename: " + "the new refresh failed.\n"); + eio = -EIO; + } + + err = unionfs_refresh_hidden_dentry(old_dentry, bindex); + if (err) { + printk(KERN_WARNING "Revert failed in rename: " + "the old refresh failed.\n"); + eio = -EIO; + continue; + } + + if (!dtohd_index(new_dentry, bindex) + || !dtohd_index(new_dentry, bindex)->d_inode) { + printk(KERN_WARNING "Revert failed in rename: " + "the object disappeared from under us!\n"); + eio = -EIO; + continue; + } + + if (dtohd_index(old_dentry, bindex) + && dtohd_index(old_dentry, bindex)->d_inode) { + printk(KERN_WARNING "Revert failed in rename: " + "the object was created underneath us!\n"); + eio = -EIO; + continue; + } + + err = + do_rename(new_dir, new_dentry, old_dir, old_dentry, bindex, + NULL); + /* If we can't fix it, then we cop-out with -EIO. */ + if (err) { + printk(KERN_WARNING "Revert failed in rename!\n"); + eio = -EIO; + } + + err = unionfs_refresh_hidden_dentry(new_dentry, bindex); + if (err) + eio = -EIO; + err = unionfs_refresh_hidden_dentry(old_dentry, bindex); + if (err) + eio = -EIO; + } + + print_exit_status(eio); + return eio; +} + +/* + * Finish off the rename, by either over writing the last destination or + * unlinking the last destination to the left of us + */ +static int __rename_all_clobber(struct inode *old_dir, + struct dentry *old_dentry, + struct inode *new_dir, + struct dentry *new_dentry, + struct rename_info *info) +{ + int err = 0; + + print_entry_location(); + + if (dtohd_index(old_dentry, info->new_bstart)) { + /* rename the last source, knowing we're overwriting something */ + DPUT(info->wh_old); + info->bwh_old = info->new_bstart; + err = + do_rename(old_dir, old_dentry, new_dir, new_dentry, + info->new_bstart, &info->wh_old); + if (IS_COPYUP_ERR(err)) { + if (info->isdir) { + err = -EXDEV; + goto out; + } + if (info->rename_ok > info->new_bstart) { + if ((info->do_copyup == -1) + || (info->new_bstart - 1 < info->do_copyup)) + info->do_copyup = info->new_bstart - 1; + } + if ((info->do_whiteout == -1) + || (info->new_bstart - 1 < info->do_whiteout)) { + info->do_whiteout = info->new_bstart - 1; + } + err = 0; // reset error + } + } else if (info->new_bstart < info->old_bstart) { + /* the newly renamed file would get hidden, let's unlink the + * file to the left of it */ + struct dentry *unlink_dentry; + struct dentry *unlink_dir_dentry; + + unlink_dentry = dtohd_index(new_dentry, info->new_bstart); + + unlink_dir_dentry = lock_parent(unlink_dentry); + if (!(err = is_robranch_super(old_dir->i_sb, info->new_bstart))) + err = vfs_unlink(unlink_dir_dentry->d_inode, + unlink_dentry, NULL); + + fist_copy_attr_times(new_dentry->d_parent->d_inode, + unlink_dir_dentry->d_inode); + new_dentry->d_parent->d_inode->i_nlink = + get_nlinks(new_dentry->d_parent->d_inode); + + unlock_dir(unlink_dir_dentry); + + if (IS_COPYUP_ERR(err)) { + if (info->isdir) { + err = -EXDEV; + goto out; + } + if ((info->do_copyup == -1) + || (info->new_bstart - 1 < info->do_copyup)) + info->do_copyup = info->new_bstart - 1; + + err = 0; // reset error + } + } + + out: + print_exit_status(err); + return err; +} + +/* + * The function is nasty, nasty, nasty, but so is rename. :( + */ +static int unionfs_rename_all(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry) +{ + struct dentry *parent_dentry = NULL; + int err = 0; + int eio; + + /* These variables control error handling. */ + fd_set success_mask; + char *name = NULL; + + /* unfortunately, we have to resort to this, because dbstart/dbend would + return different things in different place of the rename code */ + struct rename_info info; + + info.rename_ok = FD_SETSIZE; /* The last rename that is ok. */ + info.do_copyup = -1; /* Where we should start copyup. */ + info.do_whiteout = -1; /* Where we should start whiteouts of the source. */ + info.wh_old = NULL; + info.bwh_old = -1; + + print_entry_location(); + + parent_dentry = old_dentry->d_parent; + name = KMALLOC(old_dentry->d_name.len + 1, GFP_KERNEL); + if (!name) { + err = -ENOMEM; + goto out; + } + strncpy(name, old_dentry->d_name.name, old_dentry->d_name.len + 1); + + info.new_bstart = dbstart(new_dentry); + info.new_bend = dbend(new_dentry); + + info.old_bstart = dbstart(old_dentry); + info.old_bend = dbend(old_dentry); + + BUG_ON(info.new_bstart < 0); + BUG_ON(info.old_bstart < 0); + + /* The failure mask only can deal with FD_SETSIZE entries. */ + BUG_ON(info.old_bend > FD_SETSIZE); + BUG_ON(info.new_bend > FD_SETSIZE); + FD_ZERO(&success_mask); + + /* Life is simpler if the dentry doesn't exist. */ + info.clobber = + (dtohd_index(new_dentry, info.new_bstart)->d_inode) ? 1 : 0; + info.isdir = S_ISDIR(old_dentry->d_inode->i_mode); + + /* rename everything we can */ + err = + __rename_all(old_dir, old_dentry, new_dir, new_dentry, + &success_mask, &info); + if (err) + goto revert; + + /* unlink destinations even further left */ + err = + __rename_all_unlink(old_dir, old_dentry, new_dir, new_dentry, + &info); + if (err) + goto revert; + + if (info.clobber) { + /* Now we need to handle the leftmost of the destination. */ + err = + __rename_all_clobber(old_dir, old_dentry, new_dir, + new_dentry, &info); + if (err) + goto revert; + } + + /* Copy up if necessary */ + if (info.do_copyup != -1) { + int bindex; + + for (bindex = info.do_copyup; bindex >= 0; bindex--) { + err = + copyup_dentry(old_dentry->d_parent->d_inode, + old_dentry, info.old_bstart, bindex, + NULL, old_dentry->d_inode->i_size); + if (!err) { + DPUT(info.wh_old); + info.bwh_old = bindex; + err = + do_rename(old_dir, old_dentry, new_dir, + new_dentry, bindex, &info.wh_old); + break; + } + } + } + + /* make it opaque */ + if (S_ISDIR(old_dentry->d_inode->i_mode)) { + err = make_dir_opaque(old_dentry, dbstart(old_dentry)); + if (err) + goto revert; + } + + /* Create a whiteout for the source. */ + if (info.do_whiteout != -1) { + struct dentry *hidden_parent; + BUG_ON(info.do_whiteout < 0 + || !info.wh_old || IS_ERR(info.wh_old) + || info.wh_old->d_inode || info.bwh_old < 0); + hidden_parent = lock_parent(info.wh_old); + err = vfs_create(hidden_parent->d_inode, info.wh_old, S_IRUGO, + NULL); + unlock_dir(hidden_parent); + if (!err) + set_dbopaque(old_dentry, info.bwh_old); + else { + /* We can't fix anything now, so we -EIO. */ + printk(KERN_WARNING "We can't create a whiteout for the" + "source in rename!\n"); + err = -EIO; + goto out; + } + } + + /* We are at the point where reverting doesn't happen. */ + goto out; + + revert: + /* something bad happened, try to revert */ + eio = + __rename_all_revert(old_dir, old_dentry, new_dir, new_dentry, + &success_mask, &info); + if (eio) + err = eio; + + out: + DPUT(info.wh_old); + KFREE(name); + print_exit_status(err); + return err; +} +#endif + +static struct dentry *lookup_whiteout(struct dentry *dentry) +{ + char *whname; + int bindex = -1, bstart = -1, bend = -1; + struct dentry *parent, *hidden_parent, *wh_dentry; + + whname = alloc_whname(dentry->d_name.name, dentry->d_name.len); + if (IS_ERR(whname)) + return (void *)whname; + + parent = GET_PARENT(dentry); + lock_dentry(parent); + bstart = dbstart(parent); + bend = dbend(parent); + wh_dentry = ERR_PTR(-ENOENT); + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_parent = dtohd_index(parent, bindex); + if (!hidden_parent) + continue; + wh_dentry = + LOOKUP_ONE_LEN(whname, hidden_parent, + dentry->d_name.len + WHLEN); + if (IS_ERR(wh_dentry)) + continue; + if (wh_dentry->d_inode) + break; + DPUT(wh_dentry); + wh_dentry = ERR_PTR(-ENOENT); + } + unlock_dentry(parent); + DPUT(parent); + KFREE(whname); + return wh_dentry; +} + +/* We can't copyup a directory, because it may involve huge + * numbers of children, etc. Doing that in the kernel would + * be bad, so instead we let the userspace recurse and ask us + * to copy up each file separately + */ +static int may_rename_dir(struct dentry *dentry) +{ + int err, bstart; + + err = check_empty(dentry, NULL); + if (err == -ENOTEMPTY) { + if (is_robranch(dentry)) + return -EXDEV; + } else if (err) + return err; + + bstart = dbstart(dentry); + if (dbend(dentry) == bstart || dbopaque(dentry) == bstart) + return 0; + + set_dbstart(dentry, bstart + 1); + err = check_empty(dentry, NULL); + set_dbstart(dentry, bstart); + if (err == -ENOTEMPTY) + err = -EXDEV; + return err; +} + +int unionfs_rename(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry) +{ + int err = 0; + struct dentry *wh_dentry; + + print_entry_location(); + + double_lock_dentry(old_dentry, new_dentry); + + checkinode(old_dir, "unionfs_rename-old_dir"); + checkinode(new_dir, "unionfs_rename-new_dir"); + print_dentry("IN: unionfs_rename, old_dentry", old_dentry); + print_dentry("IN: unionfs_rename, new_dentry", new_dentry); + + if (!S_ISDIR(old_dentry->d_inode->i_mode)) + err = unionfs_partial_lookup(old_dentry); + else + err = may_rename_dir(old_dentry); + + if (err) + goto out; + + err = unionfs_partial_lookup(new_dentry); + if (err) + goto out; + + /* + * if new_dentry is already hidden because of whiteout, + * simply override it even if the whiteouted dir is not empty. + */ + wh_dentry = lookup_whiteout(new_dentry); + if (!IS_ERR(wh_dentry)) + DPUT(wh_dentry); + else if (new_dentry->d_inode) { + if (S_ISDIR(old_dentry->d_inode->i_mode) != + S_ISDIR(new_dentry->d_inode->i_mode)) { + err = + S_ISDIR(old_dentry->d_inode-> + i_mode) ? -ENOTDIR : -EISDIR; + goto out; + } + + if (S_ISDIR(new_dentry->d_inode->i_mode)) { + struct unionfs_dir_state *namelist; + /* check if this unionfs directory is empty or not */ + err = check_empty(new_dentry, &namelist); + if (err) + goto out; + + if (!is_robranch(new_dentry)) + err = delete_whiteouts(new_dentry, + dbstart(new_dentry), + namelist); + + free_rdstate(namelist); + + if (err) + goto out; + } + } +#ifdef UNIONFS_DELETE_ALL + if (IS_SET(old_dir->i_sb, DELETE_ALL)) + err = unionfs_rename_all(old_dir, old_dentry, new_dir, + new_dentry); + else +#endif + err = unionfs_rename_whiteout(old_dir, old_dentry, new_dir, + new_dentry); + + out: + checkinode(new_dir, "post unionfs_rename-new_dir"); + print_dentry("OUT: unionfs_rename, old_dentry", old_dentry); + + if (err) { + /* clear the new_dentry stuff created */ + d_drop(new_dentry); + } else { + /* force re-lookup since the dir on ro branch is not renamed, + and hidden dentries still indicate the un-renamed ones. */ + if (S_ISDIR(old_dentry->d_inode->i_mode)) + atomic_dec(&dtopd(old_dentry)->udi_generation); + print_dentry("OUT: unionfs_rename, new_dentry", + new_dentry); + } + + unlock_dentry(new_dentry); + unlock_dentry(old_dentry); + print_exit_status(err); + return err; +} + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/unionfs_macros.h +++ linux-2.6.28/ubuntu/unionfs/unionfs_macros.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef Sipek + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: unionfs_macros.h,v 1.13 2006/06/01 03:11:03 jsipek Exp $ + */ + +#ifndef __UNIONFS_H_ +#error This file should only be included from unionfs.h! +#endif + +/* Inode to private data */ +static inline struct unionfs_inode_info *itopd(const struct inode *inode) +{ + return + &(container_of(inode, struct unionfs_inode_container, vfs_inode)-> + info); +} + +#define itohi_ptr(ino) (itopd(ino)->uii_inode) +#define ibstart(ino) (itopd(ino)->b_start) +#define ibend(ino) (itopd(ino)->b_end) + +/* Superblock to private data */ +#define stopd(super) ((struct unionfs_sb_info *)(super)->s_fs_info) +#define stopd_lhs(super) ((super)->s_fs_info) +#define sbstart(sb) 0 +#define sbend(sb) stopd(sb)->b_end +#define sbmax(sb) (stopd(sb)->b_end + 1) + +/* File to private Data */ +#define ftopd(file) ((struct unionfs_file_info *)((file)->private_data)) +#define ftopd_lhs(file) ((file)->private_data) +#define ftohf_ptr(file) (ftopd(file)->ufi_file) +#define fbstart(file) (ftopd(file)->b_start) +#define fbend(file) (ftopd(file)->b_end) + +/* File to hidden file. */ +static inline struct file *ftohf(struct file *f) +{ + return ftopd(f)->ufi_file[fbstart(f)]; +} + +static inline struct file *ftohf_index(const struct file *f, int index) +{ + return ftopd(f)->ufi_file[index]; +} + +static inline void set_ftohf_index(struct file *f, int index, struct file *val) +{ + ftopd(f)->ufi_file[index] = val; +} + +static inline void set_ftohf(struct file *f, struct file *val) +{ + ftopd(f)->ufi_file[fbstart(f)] = val; +} + +/* Inode to hidden inode. */ +static inline struct inode *itohi(const struct inode *i) +{ + return itopd(i)->uii_inode[ibstart(i)]; +} + +static inline struct inode *itohi_index(const struct inode *i, int index) +{ + return itopd(i)->uii_inode[index]; +} + +static inline void set_itohi_index(struct inode *i, int index, + struct inode *val) +{ + itopd(i)->uii_inode[index] = val; +} + +static inline void set_itohi(struct inode *i, struct inode *val) +{ + itopd(i)->uii_inode[ibstart(i)] = val; +} + +/* Superblock to hidden superblock. */ +static inline struct super_block *stohs(const struct super_block *o) +{ + return stopd(o)->usi_data[sbstart(o)].sb; +} + +static inline struct super_block *stohs_index(const struct super_block *o, int index) +{ + return stopd(o)->usi_data[index].sb; +} + +static inline void set_stohs_index(struct super_block *o, int index, + struct super_block *val) +{ + stopd(o)->usi_data[index].sb = val; +} + +static inline void set_stohs(struct super_block *o, struct super_block *val) +{ + stopd(o)->usi_data[sbstart(o)].sb = val; +} + +/* Super to hidden mount. */ +static inline struct vfsmount *stohiddenmnt_index(struct super_block *o, + int index) +{ + return stopd(o)->usi_data[index].hidden_mnt; +} + +static inline void set_stohiddenmnt_index(struct super_block *o, int index, + struct vfsmount *val) +{ + stopd(o)->usi_data[index].hidden_mnt = val; +} + +/* Branch count macros. */ +static inline int branch_count(struct super_block *o, int index) +{ + return atomic_read(&stopd(o)->usi_data[index].sbcount); +} + +static inline void set_branch_count(struct super_block *o, int index, int val) +{ + atomic_set(&stopd(o)->usi_data[index].sbcount, val); +} + +static inline void branchget(struct super_block *o, int index) +{ + atomic_inc(&stopd(o)->usi_data[index].sbcount); +} + +static inline void branchput(struct super_block *o, int index) +{ + atomic_dec(&stopd(o)->usi_data[index].sbcount); +} + +/* Dentry macros */ +static inline struct unionfs_dentry_info *dtopd(const struct dentry *dent) +{ + return (struct unionfs_dentry_info *)dent->d_fsdata; +} + +#define dtopd_lhs(dent) ((dent)->d_fsdata) +#define dtopd_nocheck(dent) dtopd(dent) +#define dbstart(dent) (dtopd(dent)->udi_bstart) +#define set_dbstart(dent, val) do { dtopd(dent)->udi_bstart = val; } while(0) +#define dbend(dent) (dtopd(dent)->udi_bend) +#define set_dbend(dent, val) do { dtopd(dent)->udi_bend = val; } while(0) +#define dbopaque(dent) (dtopd(dent)->udi_bopaque) +#define set_dbopaque(dent, val) do { dtopd(dent)->udi_bopaque = val; } while (0) + +static inline void set_dtohd_index(struct dentry *dent, int index, + struct dentry *val) +{ + dtopd(dent)->udi_dentry[index] = val; +} + +static inline struct dentry *dtohd_index(const struct dentry *dent, int index) +{ + return dtopd(dent)->udi_dentry[index]; +} + +static inline struct dentry *dtohd(const struct dentry *dent) +{ + return dtopd(dent)->udi_dentry[dbstart(dent)]; +} + +#define set_dtohd_index_nocheck(dent, index, val) set_dtohd_index(dent, index, val) +#define dtohd_index_nocheck(dent, index) dtohd_index(dent, index) + +#define dtohd_ptr(dent) (dtopd_nocheck(dent)->udi_dentry) + +/* Macros for locking a dentry. */ +#define lock_dentry(d) down(&dtopd(d)->udi_sem) +#define unlock_dentry(d) up(&dtopd(d)->udi_sem) +#define verify_locked(d) + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/rdstate.c +++ linux-2.6.28/ubuntu/unionfs/rdstate.c @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: rdstate.c,v 1.34 2006/08/05 01:28:46 jro Exp $ + */ + +#include "unionfs.h" + +/* This file contains the routines for maintaining readdir state. */ +/* There are two structures here, rdstate which is a hash table + * of the second structure which is a filldir_node. */ + +/* This is a struct kmem_cache for filldir nodes, because we allocate a lot of them + * and they shouldn't waste memory. If the node has a small name (as defined + * by the dentry structure), then we use an inline name to preserve kmalloc + * space. */ +static struct kmem_cache *unionfs_filldir_cachep; +int init_filldir_cache(void) +{ + unionfs_filldir_cachep = + kmem_cache_create("unionfs_filldir", sizeof(struct filldir_node), 0, + SLAB_RECLAIM_ACCOUNT, NULL); + + if (!unionfs_filldir_cachep) + return -ENOMEM; + + return 0; +} + +void destroy_filldir_cache(void) +{ + if (!unionfs_filldir_cachep) + return; + kmem_cache_destroy(unionfs_filldir_cachep); + return; +} + +/* This is a tuning parameter that tells us roughly how big to make the + * hash table in directory entries per page. This isn't perfect, but + * at least we get a hash table size that shouldn't be too overloaded. + * The following averages are based on my home directory. + * 14.44693 Overall + * 12.29 Single Page Directories + * 117.93 Multi-page directories + */ +#define DENTPAGE 4096 +#define DENTPERONEPAGE 12 +#define DENTPERPAGE 118 +#define MINHASHSIZE 1 +static int guesstimate_hash_size(struct inode *inode) +{ + struct inode *hidden_inode; + int bindex; + int hashsize = MINHASHSIZE; + + if (itopd(inode)->uii_hashsize > 0) + return itopd(inode)->uii_hashsize; + + for (bindex = ibstart(inode); bindex <= ibend(inode); bindex++) { + if (!(hidden_inode = itohi_index(inode, bindex))) + continue; + + if (hidden_inode->i_size == DENTPAGE) { + hashsize += DENTPERONEPAGE; + } else { + hashsize += + (hidden_inode->i_size / DENTPAGE) * DENTPERPAGE; + } + } + + return hashsize; +} + +int init_rdstate(struct file *file) +{ + BUG_ON(sizeof(loff_t) != (sizeof(unsigned int) + sizeof(unsigned int))); + BUG_ON(ftopd(file)->rdstate != NULL); + + ftopd(file)->rdstate = + alloc_rdstate(file->f_dentry->d_inode, fbstart(file)); + if (!ftopd(file)->rdstate) + return -ENOMEM; + return 0; +} + +struct unionfs_dir_state *find_rdstate(struct inode *inode, loff_t fpos) +{ + struct unionfs_dir_state *rdstate = NULL; + struct list_head *pos; + + print_entry("f_pos: %lld", fpos); + spin_lock(&itopd(inode)->uii_rdlock); + list_for_each(pos, &itopd(inode)->uii_readdircache) { + struct unionfs_dir_state *r = + list_entry(pos, struct unionfs_dir_state, uds_cache); + if (fpos == rdstate2offset(r)) { + itopd(inode)->uii_rdcount--; + list_del(&r->uds_cache); + rdstate = r; + break; + } + } + spin_unlock(&itopd(inode)->uii_rdlock); + print_exit_pointer(rdstate); + return rdstate; +} + +struct unionfs_dir_state *alloc_rdstate(struct inode *inode, int bindex) +{ + int i = 0; + int hashsize; + int mallocsize = sizeof(struct unionfs_dir_state); + struct unionfs_dir_state *rdstate; + + hashsize = guesstimate_hash_size(inode); + mallocsize += hashsize * sizeof(struct list_head); + /* Round it up to the next highest power of two. */ + mallocsize--; + mallocsize |= mallocsize >> 1; + mallocsize |= mallocsize >> 2; + mallocsize |= mallocsize >> 4; + mallocsize |= mallocsize >> 8; + mallocsize |= mallocsize >> 16; + mallocsize++; + + /* This should give us about 500 entries anyway. */ + if (mallocsize > PAGE_SIZE) + mallocsize = PAGE_SIZE; + + hashsize = + (mallocsize - + sizeof(struct unionfs_dir_state)) / sizeof(struct list_head); + + rdstate = KMALLOC(mallocsize, GFP_KERNEL); + if (!rdstate) + return NULL; + + spin_lock(&itopd(inode)->uii_rdlock); + if (itopd(inode)->uii_cookie >= (MAXRDCOOKIE - 1)) + itopd(inode)->uii_cookie = 1; + else + itopd(inode)->uii_cookie++; + + rdstate->uds_cookie = itopd(inode)->uii_cookie; + spin_unlock(&itopd(inode)->uii_rdlock); + rdstate->uds_offset = 1; + rdstate->uds_access = jiffies; + rdstate->uds_bindex = bindex; + rdstate->uds_dirpos = 0; + rdstate->uds_hashentries = 0; + rdstate->uds_size = hashsize; + for (i = 0; i < rdstate->uds_size; i++) + INIT_LIST_HEAD(&rdstate->uds_list[i]); + + return rdstate; +} + +static void free_filldir_node(struct filldir_node *node) +{ + if (node->namelen >= DNAME_INLINE_LEN_MIN) + KFREE(node->name); + kmem_cache_free(unionfs_filldir_cachep, node); +} + +void free_rdstate(struct unionfs_dir_state *state) +{ + struct filldir_node *tmp; + int i; + + for (i = 0; i < state->uds_size; i++) { + struct list_head *head = &(state->uds_list[i]); + struct list_head *pos, *n; + + /* traverse the list and deallocate space */ + list_for_each_safe(pos, n, head) { + tmp = list_entry(pos, struct filldir_node, file_list); + list_del(&tmp->file_list); + free_filldir_node(tmp); + } + } + + KFREE(state); +} + +struct filldir_node *find_filldir_node(struct unionfs_dir_state *rdstate, + const char *name, int namelen) +{ + int index; + unsigned int hash; + struct list_head *head; + struct list_head *pos; + struct filldir_node *cursor = NULL; + int found = 0; + + /* If we print entry, we end up with spurious data. */ + /* print_entry("name = %*s", namelen, name); */ + print_entry_location(); + + BUG_ON(namelen <= 0); + + hash = full_name_hash(name, namelen); + index = hash % rdstate->uds_size; + + head = &(rdstate->uds_list[index]); + list_for_each(pos, head) { + cursor = list_entry(pos, struct filldir_node, file_list); + + if (cursor->namelen == namelen && cursor->hash == hash + && !strncmp(cursor->name, name, namelen)) { + /* a duplicate exists, and hence no need to create entry to the list */ + found = 1; + /* if the duplicate is in this branch, then the file system is corrupted. */ + if (cursor->bindex == rdstate->uds_bindex) { + //buf->error = err = -EIO; + dprint(PRINT_DEBUG, + "Possible I/O error unionfs_filldir: a file is duplicated in the same branch %d: %s\n", + rdstate->uds_bindex, cursor->name); + } + break; + } + } + + if (!found) { + cursor = NULL; + } + print_exit_pointer(cursor); + return cursor; +} + +inline struct filldir_node *alloc_filldir_node(const char *name, int namelen, + unsigned int hash, int bindex) +{ + struct filldir_node *newnode; + + newnode = + (struct filldir_node *)kmem_cache_alloc(unionfs_filldir_cachep, + GFP_KERNEL); + if (!newnode) + goto out; + + out: + return newnode; +} + +int add_filldir_node(struct unionfs_dir_state *rdstate, const char *name, + int namelen, int bindex, int whiteout) +{ + struct filldir_node *new; + unsigned int hash; + int index; + int err = 0; + struct list_head *head; + + /* We can't print this because we end up Oopsing. */ + /* print_entry("name = %*s", namelen, name); */ + print_entry_location(); + + BUG_ON(namelen <= 0); + + hash = full_name_hash(name, namelen); + index = hash % rdstate->uds_size; + head = &(rdstate->uds_list[index]); + + new = alloc_filldir_node(name, namelen, hash, bindex); + if (!new) { + err = -ENOMEM; + goto out; + } + + INIT_LIST_HEAD(&new->file_list); + new->namelen = namelen; + new->hash = hash; + new->bindex = bindex; + new->whiteout = whiteout; + + if (namelen < DNAME_INLINE_LEN_MIN) { + new->name = new->iname; + } else { + new->name = (char *)KMALLOC(namelen + 1, GFP_KERNEL); + if (!new->name) { + kmem_cache_free(unionfs_filldir_cachep, new); + new = NULL; + goto out; + } + } + + memcpy(new->name, name, namelen); + new->name[namelen] = '\0'; + + rdstate->uds_hashentries++; + + list_add(&(new->file_list), head); + out: + print_exit_status(err); + return err; +} + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/persistent_inode.c +++ linux-2.6.28/ubuntu/unionfs/persistent_inode.c @@ -0,0 +1,658 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef Sipek + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: persistent_inode.c,v 1.36 2006/07/08 17:58:31 ezk Exp $ + */ +#ifdef UNIONFS_IMAP + +#include "unionfs.h" + +static ssize_t __fread(struct file *filp, void *buf, size_t size, loff_t * pos) +{ + int err; + mm_segment_t oldfs; + ssize_t(*func) (struct file *, char __user *, size_t, loff_t *); + + func = do_sync_read; + if (filp->f_op && filp->f_op->read) + func = filp->f_op->read; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + do { + err = func(filp, (char __user *)buf, size, pos); + } while (err == -EAGAIN || err == -EINTR); + set_fs(oldfs); + return err; +} + +static ssize_t __fwrite(struct file *filp, void *buf, size_t size, loff_t * pos) +{ + int err; + mm_segment_t oldfs; + unsigned long flim; + struct rlimit *rl; + ssize_t(*func) (struct file *, const char __user *, size_t, loff_t *); + + func = do_sync_write; + if (filp->f_op && filp->f_op->write) + func = filp->f_op->write; + + /* + * it breaks RLIMIT_FSIZE, + * but users should be careful to quota. + */ + rl = current->signal->rlim + RLIMIT_FSIZE; + flim = rl->rlim_cur; + rl->rlim_cur = RLIM_INFINITY; + oldfs = get_fs(); + set_fs(KERNEL_DS); + do { + err = func(filp, (const char __user *)buf, size, pos); + } while (err == -EAGAIN || err == -EINTR); + set_fs(oldfs); + rl->rlim_cur = flim; + return err; +} + +/* + * verify_forwardmap(super_block *sb) + * sb: pointer to a superblock containing the forwardmap. + * returns: 0 on success EINVAL or ENOMEM on failure; + */ +static int verify_forwardmap(struct super_block *sb) +{ + int err = 0, bytesread = 0, bindex = 0, mallocsize = 0; + loff_t readpos = 0; + struct file *forwardmap = NULL; + struct fmaphdr header; + struct unionfs_sb_info *spd = NULL; + print_entry_location(); + + spd = stopd(sb); + BUG_ON(!spd); + + forwardmap = spd->usi_forwardmap; + if (!forwardmap) { + err = -EINVAL; + goto out; + } + bytesread = __fread(forwardmap, &header, sizeof(struct fmaphdr), + &readpos); + if (bytesread < sizeof(struct fmaphdr)) { + err = -EINVAL; + goto out; + } + if (header.magic != FORWARDMAP_MAGIC + || header.version != FORWARDMAP_VERSION) { + err = -EINVAL; + goto out; + } + spd->usi_bmap = + KMALLOC(sizeof(struct bmapent) * header.usedbranches, GFP_KERNEL); + + if (!spd->usi_bmap) { + err = -ENOMEM; + goto out; + } + + while (bindex < header.usedbranches) { + bytesread = __fread(forwardmap, &stopd(sb)->usi_bmap[bindex], + sizeof(struct bmapent), &readpos); + if (bytesread < sizeof(struct bmapent)) { + err = -EINVAL; + goto out_err; + } + bindex++; + } + + mallocsize = sizeof(int) * header.usedbranches; + goto out; + out_err: + if (spd->usi_bmap) + KFREE(spd->usi_bmap); + out: + print_exit_status(err); + return err; +} + +/* + * verify_reversemap(struct super_block sb, int rmapindex) + * + * sb: The unionfs superblock containing all of the current imap info + * rmapindex: the index in the usi_reversemaps array that we wish to + * verify + * + * Assumes the reverse maps less than rmapindex are valid. + * + * returns: 0 if the opperation succeds + * -EINVAL if the map file does not belong to the forward map + * + */ +static int verify_reversemap(struct super_block *sb, int rmapindex, + struct unionfs_dentry_info *hidden_root_info) +{ + int err = 0, i = 0, bindex = 0, found = 0, bytesread; + loff_t readpos = 0; + struct file *forwardmap, *reversemap; + struct fmaphdr fheader; + struct rmaphdr rheader; + struct kstatfs st; + struct unionfs_sb_info *spd = NULL; + + print_entry_location(); + + spd = stopd(sb); + BUG_ON(!spd); + + forwardmap = spd->usi_forwardmap; + if (!forwardmap) { + err = -EINVAL; + goto out; + } + reversemap = spd->usi_reversemaps[rmapindex]; + if (!reversemap) { + err = -EINVAL; + goto out; + } + bytesread = __fread(forwardmap, &fheader, sizeof(struct fmaphdr), + &readpos); + if (bytesread < sizeof(struct fmaphdr)) { + err = -EINVAL; + goto out; + } + readpos = 0; + bytesread = __fread(reversemap, &rheader, sizeof(struct rmaphdr), + &readpos); + if (bytesread < sizeof(struct rmaphdr)) { + err = -EINVAL; + goto out; + } + if (rheader.magic != REVERSEMAP_MAGIC + || rheader.version != REVERSEMAP_VERSION) { + err = -EINVAL; + goto out; + } + if (memcmp(fheader.uuid, rheader.fwduuid, sizeof(fheader.uuid))) { + err = -EINVAL; + goto out; + } + + /* XXX: Ok so here we take the new map and read the fsid from it. Then + * we go through all the branches in the union and see which ones it + * matches with*/ + for (i = 0; i < spd->usi_num_bmapents && !found; i++) { + if (memcmp + (rheader.revuuid, spd->usi_bmap[i].uuid, + sizeof(rheader.revuuid))) + continue; + + found = 1; + for (bindex = 0; bindex <= hidden_root_info->udi_bend; bindex++) { + struct dentry *d; + fsid_t fsid; + dev_t dev; + memset(&st, 0, sizeof(struct kstatfs)); + + d = hidden_root_info->udi_dentry[bindex]; + + err = d->d_sb->s_op->statfs(d->d_sb, &st); + if (err) + goto out; + + if (st.f_fsid.val[0] || st.f_fsid.val[1]) { + fsid = st.f_fsid; + } else { + + dev = d->d_sb->s_dev; + fsid.val[0] = MAJOR(dev); + fsid.val[1] = MINOR(dev); + } + + if (memcmp(&fsid, &rheader.fsid, sizeof(fsid))) + continue; + + if (spd->usi_bnum_table[bindex] == -1) + spd->usi_bnum_table[bindex] = i; + if (spd->usi_map_table[bindex]) { + printk(KERN_WARNING + "Two reverse maps share fsid %u%u!\n", + rheader.fsid.val[0], + rheader.fsid.val[1]); + err = -EINVAL; + goto out; + } else { + spd->usi_map_table[bindex] = reversemap; + } + } + } + if (!found) { + printk(KERN_WARNING + "Could not match the reversemap uuid with an entry in the forwardmap table\n"); + err = -EINVAL; + } + out: + print_exit_status(err); + return err; +} + +int init_imap_data(struct super_block *sb, + struct unionfs_dentry_info *hidden_root_info) +{ + int i, err = 0, mallocsize = 0; + struct unionfs_sb_info *spd; + + print_entry_location(); + + spd = stopd(sb); + + spd->usi_forwardmap = NULL; + spd->usi_reversemaps = NULL; + spd->usi_bnum_table = NULL; + + mallocsize = sizeof(struct file *) * (hidden_root_info->udi_bend + 1); + spd->usi_reversemaps = KZALLOC(mallocsize, GFP_KERNEL); + if (!spd->usi_reversemaps) { + err = -ENOMEM; + goto out_error; + } + + spd->usi_map_table = KZALLOC(mallocsize, GFP_KERNEL); + if (!spd->usi_map_table) { + err = -ENOMEM; + goto out_error; + } + + mallocsize = sizeof(int) * (hidden_root_info->udi_bend + 1); + spd->usi_bnum_table = KMALLOC(mallocsize, GFP_KERNEL); + if (!spd->usi_bnum_table) { + err = -ENOMEM; + goto out_error; + } + + for (i = 0; i <= hidden_root_info->udi_bend; i++) { + spd->usi_bnum_table[i] = -1; + } + + if (!err) + goto out; + out_error: + + if (spd->usi_reversemaps) { + KFREE(spd->usi_reversemaps); + spd->usi_reversemaps = NULL; + } + + if (spd->usi_map_table) { + KFREE(spd->usi_map_table); + spd->usi_map_table = NULL; + } + + if (spd->usi_bnum_table) { + KFREE(spd->usi_bnum_table); + spd->usi_bnum_table = NULL; + + } + + out: + print_exit_status(err); + return err; + +} + +void cleanup_imap_data(struct super_block *sb) +{ + int count = 0; + struct unionfs_sb_info *spd; + + print_entry_location(); + + spd = stopd(sb); + + spd->usi_persistent = 0; + count = spd->usi_num_bmapents; + while (count - 1 >= 0) { + if (spd->usi_reversemaps[count - 1]) { + filp_close(spd->usi_reversemaps[count - 1], NULL); + spd->usi_reversemaps[count - 1] = NULL; + } + count--; + } + if (spd->usi_reversemaps) { + KFREE(spd->usi_reversemaps); + spd->usi_reversemaps = NULL; + } + + if (spd->usi_map_table) { + KFREE(spd->usi_map_table); + spd->usi_map_table = NULL; + } + + if (spd->usi_bnum_table) { + KFREE(spd->usi_bnum_table); + spd->usi_bnum_table = NULL; + } + if (spd->usi_forwardmap) { + filp_close(spd->usi_forwardmap, NULL); + spd->usi_forwardmap = NULL; + } + print_exit_location(); +} + +int parse_imap_option(struct super_block *sb, + struct unionfs_dentry_info *hidden_root_info, + char *options) +{ + int count = 0, err = 0; + char *name; + struct unionfs_sb_info *spd = NULL; + + print_entry_location(); + spd = stopd(sb); + BUG_ON(!spd); + + err = init_imap_data(sb, hidden_root_info); + if (err) + goto out_error; + while ((name = strsep(&options, ":")) != NULL) { + if (!*name) + continue; + if (!spd->usi_forwardmap) { + spd->usi_forwardmap = filp_open(name, O_RDWR, 0); + if (IS_ERR(spd->usi_forwardmap)) { + err = PTR_ERR(spd->usi_forwardmap); + spd->usi_forwardmap = NULL; + goto out_error; + } + } else { + spd->usi_reversemaps[count] = + filp_open(name, O_RDWR, 0); + if (IS_ERR(spd->usi_reversemaps[count])) { + err = PTR_ERR(spd->usi_reversemaps[count]); + spd->usi_reversemaps[count] = NULL; + goto out_error; + + } + count++; + } + } + if (count <= 0) { + printk(KERN_WARNING "unionfs: no reverse maps specified.\n"); + err = -EINVAL; + } + if (err) + goto out_error; + + /* Initialize the super block's next_avail field */ + /* Dave, you can't use 64-bit division here because the i386 doesn't + * support it natively. Instead you need to punt if the size is + * greater than unsigned long, and then cast it down. Then you should + * be able to assign to this value, without having these problems. */ + + if (spd->usi_forwardmap->f_dentry->d_inode->i_size > ULONG_MAX) { + err = -EFBIG; + goto out_error; + } + spd->usi_next_avail = + ((unsigned long)(spd->usi_forwardmap->f_dentry->d_inode-> + i_size - (sizeof(struct fmaphdr) + + sizeof(struct bmapent[256]))) + / sizeof(struct fmapent)); + + if (spd->usi_next_avail < FIRST_VALID_INODE) + spd->usi_next_avail = FIRST_VALID_INODE; + + spd->usi_num_bmapents = count; + err = verify_forwardmap(sb); + if (err) + goto out_error; + while (count > 0) { + err = verify_reversemap(sb, --count, hidden_root_info); + if (err) + goto out_error; + } + spd->usi_persistent = 1; + + goto out; + + out_error: + spd->usi_num_bmapents = count; + cleanup_imap_data(sb); + + out: + print_exit_status(err); + return err; +} + + /* + * get @ino from @hidden_ino. + */ +static int __read_uin(struct unionfs_sb_info *sbi, ino_t hidden_ino, int bindex, + ino_t * ino) +{ + int err; + struct file *rev; + loff_t pos; + ssize_t sz; + uint64_t ino64; + const int elmnt = sizeof(ino64); + + rev = sbi->usi_map_table[bindex]; + pos = sizeof(struct rmaphdr) + elmnt * hidden_ino; + *ino = 0; + err = 0; + if (pos + elmnt > rev->f_dentry->d_inode->i_size) + goto out; + + sz = __fread(rev, &ino64, elmnt, &pos); + err = sz; + if (err < 0) + goto out; + err = 0; + *ino = -1; + if (sz != elmnt || ino64 > *ino) + err = -EIO; + *ino = ino64; + out: + print_exit_status(err); + return err; +} + +/* + * put unionfs @ino for @hidden_ino on @bindex. + */ +static int __write_uin(struct unionfs_sb_info *sbi, ino_t ino, int bindex, + ino_t hidden_ino) +{ + struct file *fwd, *rev; + struct fmapent ent; + loff_t pos; + ssize_t sz; + int err; + uint64_t ino64; + const int fwdhdr = sizeof(struct fmaphdr) + sizeof(struct bmapent[256]); + const int fwd_elmnt = sizeof(ent); + const int rev_elmnt = sizeof(ino64); + + err = -ENOSPC; + if (ino < FIRST_VALID_INODE) + goto out; + + fwd = sbi->usi_forwardmap; + ent.fsnum = sbi->usi_bnum_table[bindex]; + ent.inode = hidden_ino; + pos = fwdhdr + fwd_elmnt * ino; + sz = __fwrite(fwd, &ent, fwd_elmnt, &pos); + err = sz; + if (err < 0) + goto out; + err = -EIO; + if (sz != fwd_elmnt) + goto out; + + rev = sbi->usi_map_table[bindex]; + pos = sizeof(struct rmaphdr) + rev_elmnt * hidden_ino; + ino64 = ino; + sz = __fwrite(rev, &ino64, rev_elmnt, &pos); + err = sz; + if (err < 0) + goto out; + err = 0; + if (sz != rev_elmnt) + err = -EIO; + out: + print_exit_status(err); + return err; +} + +/* + * read_uin(struct super_block *sb, uint8_t branchnum, ino_t inode_number, int flag, ino_t *uino) + * fsnum: branch to reference when getting the inode number + * inode_number: lower level inode number use to reference the proper inode. + * flag: if set to O_CREAT it will creat the entry if it doesent exist + * otherwise it will return the existing one. + * returns: the unionfs inode number either created or retrieved based on + * the information. + */ +int read_uin(struct super_block *sb, uint8_t branchnum, ino_t inode_number, + int flag, ino_t * uino) +{ + int err = 0; + struct unionfs_sb_info *spd; + + print_entry_location(); + + spd = stopd(sb); + BUG_ON(!spd); + + /* Find appropriate reverse map and then read from the required position */ + /* get it from the array. */ + err = __read_uin(spd, inode_number, branchnum, uino); + if (err || *uino) + goto out; + + err = -EIO; + if (!(flag & O_CREAT)) + goto out; + + /* If we haven't found an entry and we have the O_CREAT flag set we want to + * create a new entry write it out to the file and return its index + */ + mutex_lock(&sb->s_lock); + *uino = spd->usi_next_avail++; + err = __write_uin(spd, *uino, branchnum, inode_number); + if (err) + spd->usi_next_avail--; + mutex_unlock(&sb->s_lock); + out: + print_exit_status(err); + return err; +} + +int write_uin(struct super_block *sb, ino_t ino, int bindex, ino_t hidden_ino) +{ + int err; + + print_entry_location(); + err = __write_uin(stopd(sb), ino, bindex, hidden_ino); + print_exit_status(err); + return err; +} + +/* + * get_lin(ino_t inode_number) + * inode_number : inode number for the unionfs inode + * returns: the lower level inode# and branch# + */ +/* entry should use a poiner on the stack. should be staticly allocated one + * level up*/ +int get_lin(struct super_block *sb, ino_t inode_number, struct fmapent *entry) +{ + struct file *forwardmap; + loff_t seek_size; + mm_segment_t oldfs; + int err = 0, bytesread = 0; + + print_entry_location(); + + if (!entry) { + entry = ERR_PTR(-ENOMEM); + goto out; + } + forwardmap = stopd(sb)->usi_forwardmap; + seek_size = + sizeof(struct fmaphdr) + sizeof(struct bmapent[256]) + + (sizeof(struct fmapent) * inode_number); + oldfs = get_fs(); + set_fs(KERNEL_DS); + bytesread = __fread(forwardmap, entry, sizeof(*entry), &seek_size); + set_fs(oldfs); + if (bytesread != sizeof(*entry)) + err = -EINVAL; + + out: + print_exit_location(); + return err; +} + +/* + * remove_map(struct super_block *sb,int bindex) + * + * sb: The super block containing all the current imap info + * bindex: the index of the branch that is being removed. + * + * This assumes that end hasen't been decremented yet. + * + * Returns: This function really can't fail. The only thing + * that could possibly happen is that it will oops but that + * requires unionfs to be in an inconsistant state which + * shoulden't happen. + */ +int remove_map(struct super_block *sb, int bindex) +{ + int i; + struct unionfs_sb_info *spd; + + print_entry_location(); + + spd = stopd(sb); + BUG_ON(!spd); + + for (i = bindex; i < sbend(sb); i++) { + spd->usi_map_table[i] = spd->usi_map_table[i + 1]; + spd->usi_bnum_table[i] = spd->usi_bnum_table[i + 1]; + } + return 0; +} + +#endif +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/subr.c +++ linux-2.6.28/ubuntu/unionfs/subr.c @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: subr.c,v 1.142 2006/09/21 18:19:36 jsipek Exp $ + */ + +#include "unionfs.h" +#include + +/* Pass an unionfs dentry and an index. It will try to create a whiteout + * for the filename in dentry, and will try in branch 'index'. On error, + * it will proceed to a branch to the left. + */ +int create_whiteout(struct dentry *dentry, int start) +{ + int bstart, bend, bindex; + struct dentry *hidden_dir_dentry; + struct dentry *hidden_dentry; + struct dentry *hidden_wh_dentry; + char *name = NULL; + int err = -EINVAL; + + print_entry("start = %d", start); + + verify_locked(dentry); + + print_dentry("IN create_whiteout", dentry); + bstart = dbstart(dentry); + bend = dbend(dentry); + + /* create dentry's whiteout equivalent */ + name = alloc_whname(dentry->d_name.name, dentry->d_name.len); + if (IS_ERR(name)) { + err = PTR_ERR(name); + goto out; + } + + for (bindex = start; bindex >= 0; bindex--) { + hidden_dentry = dtohd_index(dentry, bindex); + + if (!hidden_dentry) { + /* if hidden dentry is not present, create the entire + * hidden dentry directory structure and go ahead. + * Since we want to just create whiteout, we only want + * the parent dentry, and hence get rid of this dentry. + */ + hidden_dentry = create_parents(dentry->d_inode, + dentry, bindex); + if (!hidden_dentry || IS_ERR(hidden_dentry)) { + dprint(PRINT_DEBUG_WHITEOUT, + "create_parents failed for bindex = %d\n", + bindex); + continue; + } + } + hidden_wh_dentry = + LOOKUP_ONE_LEN(name, hidden_dentry->d_parent, + dentry->d_name.len + WHLEN); + if (IS_ERR(hidden_wh_dentry)) + continue; + + /* The whiteout already exists. This used to be impossible, but + * now is possible because of opaqueness. */ + if (hidden_wh_dentry->d_inode) { + DPUT(hidden_wh_dentry); + err = 0; + goto out; + } + + hidden_dir_dentry = lock_parent(hidden_wh_dentry); + if (!(err = is_robranch_super(dentry->d_sb, bindex))) { + err = + vfs_create(hidden_dir_dentry->d_inode, + hidden_wh_dentry, + ~current->fs->umask & S_IRWXUGO, NULL); + + } + unlock_dir(hidden_dir_dentry); + DPUT(hidden_wh_dentry); + + if (!err) + break; + + if (!IS_COPYUP_ERR(err)) + break; + } + + /* set dbopaque so that lookup will not proceed after this branch */ + if (!err) + set_dbopaque(dentry, bindex); + + print_dentry("OUT create_whiteout", dentry); + out: + KFREE(name); + print_exit_status(err); + return err; +} + +/* This is a helper function for rename, which ends up with hosed over dentries + * when it needs to revert. */ +int unionfs_refresh_hidden_dentry(struct dentry *dentry, int bindex) +{ + struct dentry *hidden_dentry; + struct dentry *hidden_parent; + int err = 0; + + print_entry(" bindex = %d", bindex); + + verify_locked(dentry); + lock_dentry(dentry->d_parent); + hidden_parent = dtohd_index(dentry->d_parent, bindex); + unlock_dentry(dentry->d_parent); + + BUG_ON(!S_ISDIR(hidden_parent->d_inode->i_mode)); + + hidden_dentry = + LOOKUP_ONE_LEN(dentry->d_name.name, hidden_parent, + dentry->d_name.len); + if (IS_ERR(hidden_dentry)) { + err = PTR_ERR(hidden_dentry); + goto out; + } + + if (dtohd_index(dentry, bindex)) + DPUT(dtohd_index(dentry, bindex)); + if (itohi_index(dentry->d_inode, bindex)) { + IPUT(itohi_index(dentry->d_inode, bindex)); + set_itohi_index(dentry->d_inode, bindex, NULL); + } + if (!hidden_dentry->d_inode) { + DPUT(hidden_dentry); + set_dtohd_index(dentry, bindex, NULL); + } else { + set_dtohd_index(dentry, bindex, hidden_dentry); + set_itohi_index(dentry->d_inode, bindex, + IGRAB(hidden_dentry->d_inode)); + } + + out: + print_exit_status(err); + return err; +} + +int make_dir_opaque(struct dentry *dentry, int bindex) +{ + int err; + struct dentry *hidden_dentry, *diropq; + struct inode *hidden_dir; + + hidden_dentry = dtohd_index(dentry, bindex); + hidden_dir = hidden_dentry->d_inode; + BUG_ON(!S_ISDIR(dentry->d_inode->i_mode) + || !S_ISDIR(hidden_dir->i_mode)); + + mutex_lock(&hidden_dir->i_mutex); + diropq = LOOKUP_ONE_LEN(UNIONFS_DIR_OPAQUE, hidden_dentry, + sizeof(UNIONFS_DIR_OPAQUE) - 1); + err = PTR_ERR(diropq); + if (IS_ERR(diropq)) + goto out; + err = 0; + + if (!diropq->d_inode) + err = vfs_create(hidden_dir, diropq, S_IRUGO, NULL); + DPUT(diropq); + if (!err) + set_dbopaque(dentry, bindex); + + out: + mutex_unlock(&hidden_dir->i_mutex); + return err; +} + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/dentry.c +++ linux-2.6.28/ubuntu/unionfs/dentry.c @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: dentry.c,v 1.77 2006/08/05 01:28:46 jro Exp $ + */ + +#include "unionfs.h" + +/* declarations added for "sparse" */ +extern int unionfs_d_revalidate_wrap(struct dentry *dentry, + struct nameidata *nd); +extern void unionfs_d_release(struct dentry *dentry); +extern void unionfs_d_iput(struct dentry *dentry, struct inode *inode); + +/* + * THIS IS A BOOLEAN FUNCTION: returns 1 if valid, 0 otherwise. + */ +int unionfs_d_revalidate(struct dentry *dentry, struct nameidata *nd) +{ + int valid = 1; /* default is valid (1); invalid is 0. */ + struct dentry *hidden_dentry; + int bindex, bstart, bend; + int sbgen, dgen; + int positive = 0; + int locked = 0; + int restart = 0; + int interpose_flag; + + struct nameidata lowernd; + + if(nd) + memcpy(&lowernd, nd, sizeof(struct nameidata)); + else + memset(&lowernd, 0, sizeof(struct nameidata)); + + print_util_entry_location(); + + restart: + verify_locked(dentry); + + /* if the dentry is unhashed, do NOT revalidate */ + if (d_deleted(dentry)) { + dprint(PRINT_DEBUG, "unhashed dentry being revalidated: %*s\n", + dentry->d_name.len, dentry->d_name.name); + goto out; + } + + BUG_ON(dbstart(dentry) == -1); + if (dentry->d_inode) + positive = 1; + dgen = atomic_read(&dtopd(dentry)->udi_generation); + sbgen = atomic_read(&stopd(dentry->d_sb)->usi_generation); + /* If we are working on an unconnected dentry, then there is no + * revalidation to be done, because this file does not exist within the + * namespace, and Unionfs operates on the namespace, not data. + */ + if (sbgen != dgen) { + struct dentry *result; + int pdgen; + + unionfs_read_lock(dentry->d_sb); + locked = 1; + + /* The root entry should always be valid */ + BUG_ON(IS_ROOT(dentry)); + + /* We can't work correctly if our parent isn't valid. */ + pdgen = atomic_read(&dtopd(dentry->d_parent)->udi_generation); + if (!restart && (pdgen != sbgen)) { + unionfs_read_unlock(dentry->d_sb); + locked = 0; + /* We must be locked before our parent. */ + if (! + (dentry->d_parent->d_op-> + d_revalidate(dentry->d_parent, nd))) { + valid = 0; + goto out; + } + restart = 1; + goto restart; + } + BUG_ON(pdgen != sbgen); + + /* Free the pointers for our inodes and this dentry. */ + bstart = dbstart(dentry); + bend = dbend(dentry); + if (bstart >= 0) { + struct dentry *hidden_dentry; + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_dentry = + dtohd_index_nocheck(dentry, bindex); + if (!hidden_dentry) + continue; + DPUT(hidden_dentry); + } + } + set_dbstart(dentry, -1); + set_dbend(dentry, -1); + + interpose_flag = INTERPOSE_REVAL_NEG; + if (positive) { + interpose_flag = INTERPOSE_REVAL; + mutex_lock(&dentry->d_inode->i_mutex); + bstart = ibstart(dentry->d_inode); + bend = ibend(dentry->d_inode); + if (bstart >= 0) { + struct inode *hidden_inode; + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_inode = + itohi_index(dentry->d_inode, + bindex); + if (!hidden_inode) + continue; + IPUT(hidden_inode); + } + } + KFREE(itohi_ptr(dentry->d_inode)); + itohi_ptr(dentry->d_inode) = NULL; + ibstart(dentry->d_inode) = -1; + ibend(dentry->d_inode) = -1; + mutex_unlock(&dentry->d_inode->i_mutex); + } + + result = unionfs_lookup_backend(dentry, &lowernd, interpose_flag); + if (result) { + if (IS_ERR(result)) { + valid = 0; + goto out; + } + /* current unionfs_lookup_backend() doesn't return + a valid dentry */ + DPUT(dentry); + dentry = result; + } + + if (positive && itopd(dentry->d_inode)->uii_stale) { + make_stale_inode(dentry->d_inode); + d_drop(dentry); + valid = 0; + goto out; + } + goto out; + } + + /* The revalidation must occur across all branches */ + bstart = dbstart(dentry); + bend = dbend(dentry); + BUG_ON(bstart == -1); + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry || !hidden_dentry->d_op + || !hidden_dentry->d_op->d_revalidate) + continue; + + if (!hidden_dentry->d_op->d_revalidate(hidden_dentry, nd)) + valid = 0; + } + + if (!dentry->d_inode) + valid = 0; + if (valid) + fist_copy_attr_all(dentry->d_inode, itohi(dentry->d_inode)); + + out: + if (locked) + unionfs_read_unlock(dentry->d_sb); + print_dentry("revalidate out", dentry); + print_util_exit_status(valid); + return valid; +} + +int unionfs_d_revalidate_wrap(struct dentry *dentry, struct nameidata *nd) +{ + int err; + + print_entry_location(); + lock_dentry(dentry); + + err = unionfs_d_revalidate(dentry, nd); + + unlock_dentry(dentry); + print_exit_status(err); + return err; +} + +void unionfs_d_release(struct dentry *dentry) +{ + struct dentry *hidden_dentry; + int bindex, bstart, bend; + + print_entry_location(); + /* There is no reason to lock the dentry, because we have the only + * reference, but the printing functions verify that we have a lock + * on the dentry before calling dbstart, etc. */ + lock_dentry(dentry); + print_dentry_nocheck("unionfs_d_release IN dentry", dentry); + + /* this could be a negative dentry, so check first */ + if (!dtopd(dentry)) { + dprint(PRINT_DEBUG, "dentry without private data: %*s", + dentry->d_name.len, dentry->d_name.name); + goto out; + } else if (dbstart(dentry) < 0) { + /* this is due to a failed lookup */ + /* the failed lookup has a dtohd_ptr set to null, + but this is a better check */ + dprint(PRINT_DEBUG, "dentry without hidden dentries : %*s", + dentry->d_name.len, dentry->d_name.name); + goto out_free; + } + + /* Release all the hidden dentries */ + bstart = dbstart(dentry); + bend = dbend(dentry); + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_dentry = dtohd_index(dentry, bindex); + DPUT(hidden_dentry); + set_dtohd_index(dentry, bindex, NULL); + } + /* free private data (unionfs_dentry_info) here */ + KFREE(dtohd_ptr(dentry)); + dtohd_ptr(dentry) = NULL; + out_free: + /* No need to unlock it, because it is disappeared. */ +#ifdef TRACKLOCK + printk("DESTROYLOCK:%p\n", dentry); +#endif + free_dentry_private_data(dtopd(dentry)); + dtopd_lhs(dentry) = NULL; /* just to be safe */ + out: + print_exit_location(); +} + +/* + * we don't really need unionfs_d_iput, because dentry_iput will call iput() if + * unionfs_d_iput is not defined. We left this implemented for ease of + * tracing/debugging. + */ +void unionfs_d_iput(struct dentry *dentry, struct inode *inode) +{ + print_entry_location(); + IPUT(inode); + print_exit_location(); +} + +struct dentry_operations unionfs_dops = { + .d_revalidate = unionfs_d_revalidate_wrap, + .d_release = unionfs_d_release, + .d_iput = unionfs_d_iput, +}; + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/unionfs_imap.h +++ linux-2.6.28/ubuntu/unionfs/unionfs_imap.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef Sipek + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: unionfs_imap.h,v 1.1 2006/05/30 21:38:45 jsipek Exp $ + */ + +#ifndef __UNIONFS_H_ +#error This file should only be included from unionfs.h! +#endif + +#ifdef UNIONFS_IMAP + +/*UUID typedef needed later*/ +typedef uint8_t uuid_t[16]; + +/* +* Defines,structs,and functions for persistent used by kernel and user +*/ +#define MAX_MAPS 256 +#define UUID_LEN 16 +#define FORWARDMAP_MAGIC 0x4b1cb38f +#define REVERSEMAP_MAGIC 0Xfcafad71 +#define FORWARDMAP_VERSION 0x02 +#define REVERSEMAP_VERSION 0x01 +#define FIRST_VALID_INODE 3 +struct fmaphdr { + uint32_t magic; + uint32_t version; + uint8_t usedbranches; + uint8_t uuid[UUID_LEN]; +}; + +struct rmaphdr { + uint32_t magic; + uint32_t version; + uint8_t fwduuid[UUID_LEN]; + uint8_t revuuid[UUID_LEN]; + fsid_t fsid; +}; +struct bmapent { + fsid_t fsid; + uint8_t uuid[UUID_LEN]; +}; +struct fmapent { + uint8_t fsnum; + uint64_t inode; +}; + +/* Persistant Inode functions */ +extern int read_uin(struct super_block *sb, uint8_t branchnum, + ino_t inode_number, int flag, ino_t * uino); +extern int write_uin(struct super_block *sb, ino_t ino, int bindex, + ino_t hidden_ino); +extern int get_lin(struct super_block *sb, ino_t inode_number, + struct fmapent *entry); +extern int parse_imap_option(struct super_block *sb, + struct unionfs_dentry_info *hidden_root_info, + char *options); +extern void cleanup_imap_data(struct super_block *sb); + +#endif /*#ifdef UNIONFS_IMAP */ + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/Kconfig +++ linux-2.6.28/ubuntu/unionfs/Kconfig @@ -0,0 +1,9 @@ +config FS_UNIONFS + tristate "UnionFS 1.4 Legacy" + default m + help + This is the v1.4 module, forward ported and beaten into + AppArmor submission. It is a fallback for aufs in case it ends + up being broken. We know this one works for the LiveCD, so + this is to keep the release managers from having to spend + long nights and pushing off deadlines. --- linux-2.6.28.orig/ubuntu/unionfs/stale_inode.c +++ linux-2.6.28/ubuntu/unionfs/stale_inode.c @@ -0,0 +1,133 @@ +/* + * Adpated from linux/fs/bad_inode.c + * + * Copyright (C) 1997, Stephen Tweedie + * + * Provide stub functions for "stale" inodes, a bit friendlier than the + * -EIO that bad_inode.c does. + */ +/* + * $Id: stale_inode.c,v 1.13 2006/03/21 09:22:11 jsipek Exp $ + */ + +#include + +#include +#include +#include + +static struct address_space_operations unionfs_stale_aops; + +/* declarations for "sparse */ +extern struct inode_operations stale_inode_ops; + +/* + * The follow_link operation is special: it must behave as a no-op + * so that a stale root inode can at least be unmounted. To do this + * we must dput() the base and return the dentry with a dget(). + */ +static void *stale_follow_link(struct dentry *dent, struct nameidata *nd) +{ + int err = vfs_follow_link(nd, ERR_PTR(-ESTALE)); + return ERR_PTR(err); +} + +static int return_ESTALE(void) +{ + return -ESTALE; +} + +#define ESTALE_ERROR ((void *) (return_ESTALE)) + +static struct file_operations stale_file_ops = { + .llseek = ESTALE_ERROR, + .read = ESTALE_ERROR, + .write = ESTALE_ERROR, + .readdir = ESTALE_ERROR, + .poll = ESTALE_ERROR, + .ioctl = ESTALE_ERROR, + .mmap = ESTALE_ERROR, + .open = ESTALE_ERROR, + .flush = ESTALE_ERROR, + .release = ESTALE_ERROR, + .fsync = ESTALE_ERROR, + .fasync = ESTALE_ERROR, + .lock = ESTALE_ERROR, +}; + +struct inode_operations stale_inode_ops = { + .create = ESTALE_ERROR, + .lookup = ESTALE_ERROR, + .link = ESTALE_ERROR, + .unlink = ESTALE_ERROR, + .symlink = ESTALE_ERROR, + .mkdir = ESTALE_ERROR, + .rmdir = ESTALE_ERROR, + .mknod = ESTALE_ERROR, + .rename = ESTALE_ERROR, + .readlink = ESTALE_ERROR, + .follow_link = stale_follow_link, + .truncate = ESTALE_ERROR, + .permission = ESTALE_ERROR, +}; + +/* + * When a filesystem is unable to read an inode due to an I/O error in + * its read_inode() function, it can call make_stale_inode() to return a + * set of stubs which will return ESTALE errors as required. + * + * We only need to do limited initialisation: all other fields are + * preinitialised to zero automatically. + */ + +/** + * make_stale_inode - mark an inode stale due to an I/O error + * @inode: Inode to mark stale + * + * When an inode cannot be read due to a media or remote network + * failure this function makes the inode "stale" and causes I/O operations + * on it to fail from this point on. + */ + +void make_stale_inode(struct inode *inode) +{ + inode->i_mode = S_IFREG; + inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; + inode->i_op = &stale_inode_ops; + inode->i_fop = &stale_file_ops; + inode->i_mapping->a_ops = &unionfs_stale_aops; +} + +/* + * This tests whether an inode has been flagged as stale. The test uses + * &stale_inode_ops to cover the case of invalidated inodes as well as + * those created by make_stale_inode() above. + */ + +/** + * is_stale_inode - is an inode errored + * @inode: inode to test + * + * Returns true if the inode in question has been marked as stale. + */ + +int is_stale_inode(struct inode *inode) +{ + return (inode->i_op == &stale_inode_ops); +} + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/unionfs.h +++ linux-2.6.28/ubuntu/unionfs/unionfs.h @@ -0,0 +1,736 @@ +#ifndef __UNIONFS_H_ +#define __UNIONFS_H_ + +#ifdef __KERNEL__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#ifndef UNIONFS_UNSUPPORTED +#if LINUX_VERSION_CODE != KERNEL_VERSION(SUP_MAJOR,SUP_MINOR,SUP_PATCH) +#warning You are compiling Unionfs on an unsupported kernel version. +#warning To compile Unionfs, you will need to define UNIONFS_UNSUPPORTED. +#warning Try adding: EXTRACFLAGS=-DUNIONFS_UNSUPPORTED to fistdev.mk +#endif +#endif + +/* the file system name */ +#define UNIONFS_NAME "unionfs" + +/* unionfs file systems superblock magic */ +#define UNIONFS_SUPER_MAGIC 0xf15f083d + +/* unionfs root inode number */ +#define UNIONFS_ROOT_INO 1 + +/* Mount time flags */ +#define MOUNT_FLAG(sb) (stopd(sb)->usi_mount_flag) + +/* number of characters while generating unique temporary file names */ +#define UNIONFS_TMPNAM_LEN 12 + +/* Operations vectors defined in specific files. */ +extern struct file_operations unionfs_main_fops; +extern struct file_operations unionfs_dir_fops; +extern struct inode_operations unionfs_main_iops; +extern struct inode_operations unionfs_dir_iops; +extern struct inode_operations unionfs_symlink_iops; +extern struct super_operations unionfs_sops; +extern struct dentry_operations unionfs_dops; +#ifdef CONFIG_EXPORTFS +extern struct export_operations unionfs_export_ops; +#endif + +/* How long should an entry be allowed to persist */ +#define RDCACHE_JIFFIES 5*HZ + +/* file private data. */ +struct unionfs_file_info { + int b_start; + int b_end; + atomic_t ufi_generation; + + struct unionfs_dir_state *rdstate; + struct file **ufi_file; +}; + +/* unionfs inode data in memory */ +struct unionfs_inode_info { + int b_start; + int b_end; + atomic_t uii_generation; + int uii_stale; + /* Stuff for readdir over NFS. */ + spinlock_t uii_rdlock; + struct list_head uii_readdircache; + int uii_rdcount; + int uii_hashsize; + int uii_cookie; + /* The hidden inodes */ + struct inode **uii_inode; + /* to keep track of reads/writes for unlinks before closes */ + atomic_t uii_totalopens; +}; + +struct unionfs_inode_container { + struct unionfs_inode_info info; + struct inode vfs_inode; +}; + +/* unionfs dentry data in memory */ +struct unionfs_dentry_info { + /* The semaphore is used to lock the dentry as soon as we get into a + * unionfs function from the VFS. Our lock ordering is that children + * go before their parents. */ + struct semaphore udi_sem; + int udi_bstart; + int udi_bend; + int udi_bopaque; + int udi_bcount; + atomic_t udi_generation; + struct dentry **udi_dentry; +}; + +/* A putmap is used so that older files can still do branchput correctly. */ +struct putmap { + atomic_t count; + int bend; + int map[0]; +}; + +/* These are the pointers to our various objects. */ +struct unionfs_usi_data { + struct super_block *sb; + struct vfsmount *hidden_mnt; + atomic_t sbcount; + int branchperms; +}; + +/* unionfs super-block data in memory */ +struct unionfs_sb_info { + int b_end; + + atomic_t usi_generation; + unsigned long usi_mount_flag; + struct rw_semaphore usi_rwsem; + + struct unionfs_usi_data *usi_data; + + /* These map branch numbers for old generation numbers to the new bindex, + * so that branchput will behave properly. */ + int usi_firstputmap; + int usi_lastputmap; + struct putmap **usi_putmaps; + +#ifdef UNIONFS_IMAP + int usi_persistent; + /* These will need a lock. */ + uint64_t usi_next_avail; + uint8_t usi_num_bmapents; + struct bmapent *usi_bmap; + struct file *usi_forwardmap; + struct file **usi_reversemaps; + struct file **usi_map_table; + int *usi_bnum_table; //This is a table of branches to fsnums. +#endif /* UNIONFS_IMAP */ +}; + +/* + * structure for making the linked list of entries by readdir on left branch + * to compare with entries on right branch + */ +struct filldir_node { + struct list_head file_list; // list for directory entries + char *name; // name entry + int hash; // name hash + int namelen; // name len since name is not 0 terminated + int bindex; // we can check for duplicate whiteouts and files in the same branch in order to return -EIO. + int whiteout; // is this a whiteout entry? + char iname[DNAME_INLINE_LEN_MIN]; // Inline name, so we don't need to separately kmalloc small ones +}; + +/* Directory hash table. */ +struct unionfs_dir_state { + unsigned int uds_cookie; /* The cookie, which is based off of uii_rdversion */ + unsigned int uds_offset; /* The entry we have returned. */ + int uds_bindex; + loff_t uds_dirpos; /* The offset within the lower level directory. */ + int uds_size; /* How big is the hash table? */ + int uds_hashentries; /* How many entries have been inserted? */ + unsigned long uds_access; + /* This cache list is used when the inode keeps us around. */ + struct list_head uds_cache; + struct list_head uds_list[0]; +}; + +/* privileged io workqueue */ +#include "sioq.h" + +/* include miscellaneous macros */ +#include "unionfs_macros.h" + +/* include debug macros */ +#include "unionfs_debug.h" + +/* include persistent imap code */ +#include "unionfs_imap.h" + +/* Cache creation/deletion routines. */ +void destroy_filldir_cache(void); +int init_filldir_cache(void); +int init_inode_cache(void); +void destroy_inode_cache(void); +int init_dentry_cache(void); +void destroy_dentry_cache(void); + +/* Initialize and free readdir-specific state. */ +int init_rdstate(struct file *file); +struct unionfs_dir_state *alloc_rdstate(struct inode *inode, int bindex); +struct unionfs_dir_state *find_rdstate(struct inode *inode, loff_t fpos); +void free_rdstate(struct unionfs_dir_state *state); +int add_filldir_node(struct unionfs_dir_state *rdstate, const char *name, + int namelen, int bindex, int whiteout); +struct filldir_node *find_filldir_node(struct unionfs_dir_state *rdstate, + const char *name, int namelen); + +struct dentry **alloc_new_dentries(int objs); +struct unionfs_usi_data *alloc_new_data(int objs); + +#ifdef FIST_MALLOC_DEBUG + +extern void *unionfs_kzalloc(size_t size, gfp_t flags, int line, + const char *file); +extern void *unionfs_kmalloc(size_t size, gfp_t flags, int line, + const char *file); +extern void unionfs_kfree(void *ptr, int line, const char *file); + +extern struct dentry *unionfs_dget_parent(struct dentry *child, int line, + const char *file); +extern struct dentry *unionfs_dget(struct dentry *ptr, int line, + const char *file); +extern void unionfs_dput(struct dentry *ptr, int line, const char *file); +extern struct inode *unionfs_igrab(struct inode *inode, int line, char *file); +extern void unionfs_iput(struct inode *inode, int line, char *file); +extern struct dentry *unionfs_lookup_one_len(const char *name, + struct dentry *parent, int len, + int line, const char *file); +void record_path_lookup(struct nameidata *nd, int line, const char *file); +void record_path_release(struct nameidata *nd, int line, const char *file); +struct file *unionfs_dentry_open(struct dentry *ptr, struct vfsmount *mnt, + int flags, int line, const char *file); +void record_set(struct dentry *upper, int index, struct dentry *ptr, + struct dentry *old, int line, const char *file); + +#define KZALLOC(size,flags) unionfs_kzalloc((size),(flags),__LINE__,__FILE__) +#define KMALLOC(size,flags) unionfs_kmalloc((size),(flags),__LINE__,__FILE__) +#define KFREE(ptr) unionfs_kfree((ptr),__LINE__,__FILE__) +#define DGET(d) unionfs_dget((d),__LINE__,__FILE__) +#define DPUT(d) unionfs_dput((d),__LINE__,__FILE__) +# define IPUT(a) unionfs_iput((a),__LINE__,__FILE__) +# define IGRAB(a) unionfs_igrab((a),__LINE__,__FILE__) +#define LOOKUP_ONE_LEN(name,parent,len) unionfs_lookup_one_len((name),(parent),(len),__LINE__,__FILE__) +# define RECORD_PATH_LOOKUP(nd) record_path_lookup((nd),__LINE__,__FILE__) +# define RECORD_PATH_RELEASE(nd) record_path_release((nd),__LINE__,__FILE__) +/* This has the effect of reducing the reference count sooner or later, + * if the file is closed. If it isn't then the mount will be busy and + * you can't unmount. + */ +# define DENTRY_OPEN(d,m,f) unionfs_dentry_open((d),(m),(f),__LINE__,__FILE__) +# define GET_PARENT(dentry) unionfs_dget_parent((dentry),__LINE__,__FILE__) +#else /* not FIST_MALLOC_DEBUG */ +# define KZALLOC(a,b) kzalloc((a),(b)) +# define KMALLOC(a,b) kmalloc((a),(b)) +# define KFREE(a) kfree((a)) +# define DPUT(a) dput((a)) +# define DGET(a) dget((a)) +# define IPUT(a) iput((a)) +# define IGRAB(a) igrab((a)) +# define LOOKUP_ONE_LEN(a,b,c) lookup_one_len((a),(b),(c)) +# define RECORD_PATH_LOOKUP(a) +# define RECORD_PATH_RELEASE(a) +# define DENTRY_OPEN(d,m,f) dentry_open((d),(m),(f)) +# define GET_PARENT(d) dget_parent(d) +#endif /* not FIST_MALLOC_DEBUG */ + +/* We can only use 32-bits of offset for rdstate --- blech! */ +#define DIREOF (0xfffff) +#define RDOFFBITS 20 /* This is the number of bits in DIREOF. */ +#define MAXRDCOOKIE (0xfff) +/* Turn an rdstate into an offset. */ +static inline off_t rdstate2offset(struct unionfs_dir_state *buf) +{ + off_t tmp; + tmp = + ((buf->uds_cookie & MAXRDCOOKIE) << RDOFFBITS) | (buf-> + uds_offset & + DIREOF); + return tmp; +} + +#define unionfs_read_lock(sb) down_read(&stopd(sb)->usi_rwsem) +#define unionfs_read_unlock(sb) up_read(&stopd(sb)->usi_rwsem) +#define unionfs_write_lock(sb) down_write(&stopd(sb)->usi_rwsem) +#define unionfs_write_unlock(sb) up_write(&stopd(sb)->usi_rwsem) + +/* The double lock function needs to go after the debugmacros, so that + * dtopd is defined. */ +static inline void double_lock_dentry(struct dentry *d1, struct dentry *d2) +{ + if (d2 < d1) { + struct dentry *tmp = d1; + d1 = d2; + d2 = tmp; + } + lock_dentry(d1); + lock_dentry(d2); +} + +extern int new_dentry_private_data(struct dentry *dentry); +void free_dentry_private_data(struct unionfs_dentry_info *udi); +void update_bstart(struct dentry *dentry); +#define sbt(sb) ((sb)->s_type->name) + +/* + * EXTERNALS: + */ +/* replicates the directory structure upto given dentry in given branch */ +extern struct dentry *create_parents(struct inode *dir, struct dentry *dentry, + int bindex); +struct dentry *create_parents_named(struct inode *dir, struct dentry *dentry, + const char *name, int bindex); + +/* check if two branches overlap */ +extern int is_branch_overlap(struct dentry *dent1, struct dentry *dent2); + +/* partial lookup */ +extern int unionfs_partial_lookup(struct dentry *dentry); + +/* Pass an unionfs dentry and an index and it will try to create a whiteout in branch 'index'. + On error, it will proceed to a branch to the left */ +extern int create_whiteout(struct dentry *dentry, int start); +/* copies a file from dbstart to newbindex branch */ +extern int copyup_file(struct inode *dir, struct file *file, int bstart, + int newbindex, loff_t size); +extern int copyup_named_file(struct inode *dir, struct file *file, + char *name, int bstart, int new_bindex, + loff_t len); + +/* copies a dentry from dbstart to newbindex branch */ +extern int copyup_dentry(struct inode *dir, struct dentry *dentry, int bstart, + int new_bindex, struct file **copyup_file, loff_t len); +extern int copyup_named_dentry(struct inode *dir, struct dentry *dentry, + int bstart, int new_bindex, const char *name, + int namelen, struct file **copyup_file, + loff_t len); + +extern int remove_whiteouts(struct dentry *dentry, struct dentry *hidden_dentry, + int bindex); + +/* Is this directory empty: 0 if it is empty, -ENOTEMPTY if not. */ +extern int check_empty(struct dentry *dentry, + struct unionfs_dir_state **namelist); +/* Delete whiteouts from this directory in branch bindex. */ +extern int delete_whiteouts(struct dentry *dentry, int bindex, + struct unionfs_dir_state *namelist); + +/* Re-lookup a hidden dentry. */ +extern int unionfs_refresh_hidden_dentry(struct dentry *dentry, int bindex); + +extern void unionfs_reinterpose(struct dentry *this_dentry); +extern struct super_block *unionfs_duplicate_super(struct super_block *sb); + +/* Locking functions. */ +extern int unionfs_setlk(struct file *file, int cmd, struct file_lock *fl); +extern int unionfs_getlk(struct file *file, struct file_lock *fl); + +/* Common file operations. */ +extern int unionfs_file_revalidate(struct file *file, int willwrite); +extern int unionfs_open(struct inode *inode, struct file *file); +extern int unionfs_file_release(struct inode *inode, struct file *file); +extern int unionfs_flush(struct file *file, fl_owner_t id); +extern long unionfs_ioctl(struct file *file, unsigned int cmd, + unsigned long arg); + +/* Inode operations */ +extern int unionfs_rename(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry); +int unionfs_unlink(struct inode *dir, struct dentry *dentry); +int unionfs_rmdir(struct inode *dir, struct dentry *dentry); + +int unionfs_d_revalidate(struct dentry *dentry, struct nameidata *nd); + +/* The values for unionfs_interpose's flag. */ +#define INTERPOSE_DEFAULT 0 +#define INTERPOSE_LOOKUP 1 +#define INTERPOSE_REVAL 2 +#define INTERPOSE_REVAL_NEG 3 +#define INTERPOSE_PARTIAL 4 + +extern int unionfs_interpose(struct dentry *this_dentry, struct super_block *sb, + int flag); + +/* Branch management ioctls. */ +int unionfs_ioctl_branchcount(struct file *file, unsigned int cmd, + unsigned long arg); +int unionfs_ioctl_incgen(struct file *file, unsigned int cmd, + unsigned long arg); +int unionfs_ioctl_addbranch(struct inode *inode, unsigned int cmd, + unsigned long arg); +int unionfs_ioctl_delbranch(struct super_block *sb, unsigned long arg); +int unionfs_ioctl_rdwrbranch(struct inode *inode, unsigned int cmd, + unsigned long arg); +int unionfs_ioctl_queryfile(struct file *file, unsigned int cmd, + unsigned long arg); + +/* Verify that a branch is valid. */ +int check_branch(struct nameidata *nd); + +/* Extended attribute functions. */ +extern void *xattr_alloc(size_t size, size_t limit); +extern void xattr_free(void *ptr, size_t size); + +extern ssize_t unionfs_getxattr(struct dentry *dentry, const char *name, + void *value, size_t size); +extern int unionfs_removexattr(struct dentry *dentry, const char *name); +extern ssize_t unionfs_listxattr(struct dentry *dentry, char *list, + size_t size); + +int unionfs_setxattr(struct dentry *dentry, const char *name, const void *value, + size_t size, int flags); + +/* The root directory is unhashed, but isn't deleted. */ +static inline int d_deleted(struct dentry *d) +{ + return d_unhashed(d) && (d != d->d_sb->s_root); +} + +/* returns the sum of the n_link values of all the underlying inodes of the passed inode */ +static inline int get_nlinks(struct inode *inode) +{ + int sum_nlinks = 0; + int dirs = 0; + int bindex; + struct inode *hidden_inode; + + if (!S_ISDIR(inode->i_mode)) + return itohi(inode)->i_nlink; + + for (bindex = ibstart(inode); bindex <= ibend(inode); bindex++) { + hidden_inode = itohi_index(inode, bindex); + if (!hidden_inode || !S_ISDIR(hidden_inode->i_mode)) + continue; + BUG_ON(hidden_inode->i_nlink < 0); + + /* A deleted directory. */ + if (hidden_inode->i_nlink == 0) + continue; + dirs++; + /* A broken directory (e.g., squashfs). */ + if (hidden_inode->i_nlink == 1) + sum_nlinks += 2; + else + sum_nlinks += (hidden_inode->i_nlink - 2); + } + + if (!dirs) + return 0; + return sum_nlinks + 2; +} + +static inline void fist_copy_attr_atime(struct inode *dest, + const struct inode *src) +{ + dest->i_atime = src->i_atime; +} +static inline void fist_copy_attr_times(struct inode *dest, + const struct inode *src) +{ + dest->i_atime = src->i_atime; + dest->i_mtime = src->i_mtime; + dest->i_ctime = src->i_ctime; +} +static inline void fist_copy_attr_timesizes(struct inode *dest, + const struct inode *src) +{ + dest->i_atime = src->i_atime; + dest->i_mtime = src->i_mtime; + dest->i_ctime = src->i_ctime; + dest->i_size = src->i_size; + dest->i_blocks = src->i_blocks; +} +static inline void fist_copy_attr_all(struct inode *dest, + const struct inode *src) +{ + print_entry_location(); + + dest->i_mode = src->i_mode; + /* we do not need to copy if the file is a deleted file */ + if (dest->i_nlink > 0) + dest->i_nlink = get_nlinks(dest); + dest->i_uid = src->i_uid; + dest->i_gid = src->i_gid; + dest->i_rdev = src->i_rdev; + dest->i_atime = src->i_atime; + dest->i_mtime = src->i_mtime; + dest->i_ctime = src->i_ctime; + dest->i_blkbits = src->i_blkbits; + dest->i_size = src->i_size; + dest->i_blocks = src->i_blocks; + dest->i_flags = src->i_flags; + + print_exit_location(); +} + +struct dentry *unionfs_lookup_backend(struct dentry *dentry, struct nameidata *nd, int lookupmode); +int is_stale_inode(struct inode *inode); +void make_stale_inode(struct inode *inode); + +#define IS_SET(sb, check_flag) (check_flag & MOUNT_FLAG(sb)) + +/* unionfs_permission, check if we should bypass error to facilitate copyup */ +#define IS_COPYUP_ERR(err) (err == -EROFS) + +/* unionfs_open, check if we need to copyup the file */ +#define OPEN_WRITE_FLAGS (O_WRONLY | O_RDWR | O_APPEND) +#define IS_WRITE_FLAG(flag) (flag & (OPEN_WRITE_FLAGS)) + +static inline int branchperms(struct super_block *sb, int index) +{ + BUG_ON(index < 0); + + return stopd(sb)->usi_data[index].branchperms; +} +static inline int set_branchperms(struct super_block *sb, int index, int perms) +{ + BUG_ON(index < 0); + + stopd(sb)->usi_data[index].branchperms = perms; + + return perms; +} + +/* Is this file on a read-only branch? */ +static inline int __is_robranch_super(struct super_block *sb, int index, + char *file, const char *function, + int line) +{ + int err = 0; + + print_util_entry_location(); + + if (!(branchperms(sb, index) & MAY_WRITE)) + err = -EROFS; + + print_util_exit_status(err); + return err; +} + +/* Is this file on a read-only branch? */ +static inline int __is_robranch_index(struct dentry *dentry, int index, + char *file, const char *function, + int line) +{ + int err = 0; + int perms; + + print_util_entry_location(); + + BUG_ON(index < 0); + + perms = stopd(dentry->d_sb)->usi_data[index].branchperms; + + if ((!(perms & MAY_WRITE)) + || (IS_RDONLY(dtohd_index(dentry, index)->d_inode))) + err = -EROFS; + + print_util_exit_status(err); + + return err; +} +static inline int __is_robranch(struct dentry *dentry, char *file, + const char *function, int line) +{ + int index; + int err; + + print_util_entry_location(); + + index = dtopd(dentry)->udi_bstart; + BUG_ON(index < 0); + + err = __is_robranch_index(dentry, index, file, function, line); + + print_util_exit_status(err); + + return err; +} + +#define is_robranch(d) __is_robranch(d, __FILE__, __FUNCTION__, __LINE__) +#define is_robranch_super(s, n) __is_robranch_super(s, n, __FILE__, __FUNCTION__, __LINE__) + +/* What do we use for whiteouts. */ +#define WHPFX ".wh." +#define WHLEN 4 +/* If a directory contains this file, then it is opaque. We start with the + * .wh. flag so that it is blocked by loomkup. + */ +#define UNIONFS_DIR_OPAQUE_NAME "__dir_opaque" +#define UNIONFS_DIR_OPAQUE WHPFX UNIONFS_DIR_OPAQUE_NAME + +/* construct whiteout filename */ +static inline char *alloc_whname(const char *name, int len) +{ + char *buf; + + buf = KMALLOC(len + WHLEN + 1, GFP_KERNEL); + if (!buf) + return ERR_PTR(-ENOMEM); + + strcpy(buf, WHPFX); + strlcat(buf, name, len + WHLEN + 1); + + return buf; +} + +/* Definitions for various ways to handle errors. + Each flag's value is its bit position */ + +/* 1 = DELETE_ALL, 0 = check for DELETE_WHITEOUT */ +#ifdef UNIONFS_DELETE_ALL +#define DELETE_ALL 4 +#else +#define DELETE_ALL 0 +#endif + +#define VALID_MOUNT_FLAGS (DELETE_ALL) + +/* + * MACROS: + */ + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif /* not SEEK_SET */ + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif /* not SEEK_CUR */ + +#ifndef SEEK_END +#define SEEK_END 2 +#endif /* not SEEK_END */ + +#ifndef DEFAULT_POLLMASK +#define DEFAULT_POLLMASK (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM) +#endif + +/* + * EXTERNALS: + */ + +/* JS: These two functions are here because it is kind of daft to copy and paste the + * contents of the two functions to 32+ places in unionfs + */ +static inline struct dentry *lock_parent(struct dentry *dentry) +{ + struct dentry *dir = DGET(dentry->d_parent); + + mutex_lock(&dir->d_inode->i_mutex); + return dir; +} + +static inline void unlock_dir(struct dentry *dir) +{ + mutex_unlock(&dir->d_inode->i_mutex); + DPUT(dir); +} + +extern int make_dir_opaque(struct dentry *dir, int bindex); + +#endif /* __KERNEL__ */ + +/* + * DEFINITIONS FOR USER AND KERNEL CODE: + * (Note: ioctl numbers 1--9 are reserved for fistgen, the rest + * are auto-generated automatically based on the user's .fist file.) + */ +# define FIST_IOCTL_GET_DEBUG_VALUE _IOR(0x15, 1, int) +# define FIST_IOCTL_SET_DEBUG_VALUE _IOW(0x15, 2, int) +# define UNIONFS_IOCTL_BRANCH_COUNT _IOR(0x15, 10, int) +# define UNIONFS_IOCTL_INCGEN _IOR(0x15, 11, int) +# define UNIONFS_IOCTL_ADDBRANCH _IOW(0x15, 12, int) +# define UNIONFS_IOCTL_DELBRANCH _IOW(0x15, 13, int) +# define UNIONFS_IOCTL_RDWRBRANCH _IOW(0x15, 14, int) +# define UNIONFS_IOCTL_QUERYFILE _IOR(0x15, 15, int) + +/* We don't support normal remount, but unionctl uses it. */ +# define UNIONFS_REMOUNT_MAGIC 0x4a5a4380 + +/* should be at least LAST_USED_UNIONFS_PERMISSION<<1 */ +#define MAY_NFSRO 16 + +struct unionfs_addbranch_args { + unsigned int ab_branch; + char *ab_path; + unsigned int ab_perms; +}; + +struct unionfs_rdwrbranch_args { + unsigned int rwb_branch; + unsigned int rwb_perms; +}; + +#endif /* not __UNIONFS_H_ */ +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/copyup.c +++ linux-2.6.28/ubuntu/unionfs/copyup.c @@ -0,0 +1,738 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York* + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: copyup.c,v 1.78 2006/10/31 18:05:33 yiannos Exp $ + */ + +#include "unionfs.h" + +/*Not Working Yet*/ +static int copyup_xattrs(struct dentry *old_hidden_dentry, + struct dentry *new_hidden_dentry) +{ + int err = 0; + ssize_t list_size = -1; + char *name_list = NULL; + char *attr_value = NULL; + char *name_list_orig = NULL; + + print_entry_location(); + + list_size = vfs_listxattr(old_hidden_dentry, NULL, NULL, 0, NULL); + + if (list_size <= 0) { + err = list_size; + goto out; + } + + name_list = xattr_alloc(list_size + 1, XATTR_LIST_MAX); + if (!name_list || IS_ERR(name_list)) { + err = PTR_ERR(name_list); + goto out; + } + list_size = vfs_listxattr(old_hidden_dentry, NULL, name_list, + list_size, NULL); + attr_value = xattr_alloc(XATTR_SIZE_MAX, XATTR_SIZE_MAX); + if (!attr_value || IS_ERR(attr_value)) { + err = PTR_ERR(name_list); + goto out; + } + name_list_orig = name_list; + while (*name_list) { + ssize_t size; + + //We need to lock here since vfs_getxattr doesn't lock for us. + mutex_lock(&old_hidden_dentry->d_inode->i_mutex); + size = vfs_getxattr(old_hidden_dentry, NULL, name_list, + attr_value, XATTR_SIZE_MAX, NULL); + mutex_unlock(&old_hidden_dentry->d_inode->i_mutex); + if (size < 0) { + err = size; + goto out; + } + + if (size > XATTR_SIZE_MAX) { + err = -E2BIG; + goto out; + } + //We don't need to lock here since vfs_setxattr does it for us. + err = vfs_setxattr(new_hidden_dentry, NULL, name_list, + attr_value, size, 0, NULL); + + if (err < 0) + goto out; + name_list += strlen(name_list) + 1; + } + out: + name_list = name_list_orig; + + if (name_list) + xattr_free(name_list, list_size + 1); + if (attr_value) + xattr_free(attr_value, XATTR_SIZE_MAX); + /* It is no big deal if this fails, we just roll with the punches. */ + if (err == -ENOTSUPP || err == -EOPNOTSUPP) + err = 0; + return err; +} + +/* Determine the mode based on the copyup flags, and the existing dentry. */ +static int copyup_permissions(struct super_block *sb, + struct dentry *old_hidden_dentry, + struct dentry *new_hidden_dentry) +{ + struct iattr newattrs; + int err; + + print_entry_location(); + + newattrs.ia_atime = old_hidden_dentry->d_inode->i_atime; + newattrs.ia_mtime = old_hidden_dentry->d_inode->i_mtime; + newattrs.ia_ctime = old_hidden_dentry->d_inode->i_ctime; + newattrs.ia_valid = ATTR_CTIME | ATTR_ATIME | ATTR_MTIME | + ATTR_ATIME_SET | ATTR_MTIME_SET; + /* original mode of old file */ + newattrs.ia_mode = old_hidden_dentry->d_inode->i_mode; + newattrs.ia_gid = old_hidden_dentry->d_inode->i_gid; + newattrs.ia_uid = old_hidden_dentry->d_inode->i_uid; + newattrs.ia_valid |= ATTR_FORCE | ATTR_GID | ATTR_UID | ATTR_MODE; + if (newattrs.ia_valid & ATTR_MODE) { + newattrs.ia_mode = + (newattrs.ia_mode & S_IALLUGO) | (old_hidden_dentry-> + d_inode-> + i_mode & ~S_IALLUGO); + } + + err = notify_change(new_hidden_dentry, NULL, &newattrs); + + print_exit_status(err); + return err; +} + +int copyup_dentry(struct inode *dir, struct dentry *dentry, + int bstart, int new_bindex, + struct file **copyup_file, loff_t len) +{ + return copyup_named_dentry(dir, dentry, bstart, new_bindex, + dentry->d_name.name, + dentry->d_name.len, copyup_file, len); +} + +int copyup_named_dentry(struct inode *dir, struct dentry *dentry, + int bstart, int new_bindex, const char *name, + int namelen, struct file **copyup_file, loff_t len) +{ + struct dentry *new_hidden_dentry; + struct dentry *old_hidden_dentry = NULL; + struct super_block *sb; + struct file *input_file = NULL; + struct file *output_file = NULL; + struct sioq_args args; + ssize_t read_bytes, write_bytes; + mm_segment_t old_fs; + int err = 0; + char *buf; + int old_bindex; + int got_branch_input = -1; + int got_branch_output = -1; + int old_bstart; + int old_bend; + int old_mode; + loff_t size = len; + struct dentry *new_hidden_parent_dentry = NULL; + mm_segment_t oldfs; + char *symbuf = NULL; + + print_entry_location(); + verify_locked(dentry); + print_dentry("IN: copyup_named_dentry", dentry); + + old_bindex = bstart; + old_bstart = dbstart(dentry); + old_bend = dbend(dentry); + + BUG_ON(new_bindex < 0); + BUG_ON(new_bindex >= old_bindex); + + sb = dir->i_sb; + + unionfs_read_lock(sb); + + if ((err = is_robranch_super(sb, new_bindex))) + goto out; + + /* Create the directory structure above this dentry. */ + new_hidden_dentry = create_parents_named(dir, dentry, name, new_bindex); + if (IS_ERR(new_hidden_dentry)) { + err = PTR_ERR(new_hidden_dentry); + goto out; + } + + print_dentry("Copyup Object", new_hidden_dentry); + + /* Now we actually create the object. */ + old_hidden_dentry = dtohd_index(dentry, old_bindex); + DGET(old_hidden_dentry); + + old_mode = old_hidden_dentry->d_inode->i_mode; + + /* For symlinks, we must read the link before we lock the directory. */ + if (S_ISLNK(old_mode)) { + + symbuf = KMALLOC(PATH_MAX, GFP_KERNEL); + if (!symbuf) { + err = -ENOMEM; + goto copyup_readlink_err; + } + + oldfs = get_fs(); + set_fs(KERNEL_DS); + err = + old_hidden_dentry->d_inode->i_op-> + readlink(old_hidden_dentry, (char __user *)symbuf, + PATH_MAX); + set_fs(oldfs); + if (err < 0) + goto copyup_readlink_err; + symbuf[err] = '\0'; + } + + /* Now we lock the parent, and create the object in the new branch. */ + new_hidden_parent_dentry = lock_parent(new_hidden_dentry); + if (S_ISDIR(old_mode)) { + args.mkdir.parent = new_hidden_parent_dentry->d_inode; + args.mkdir.dentry = new_hidden_dentry; + args.mkdir.mode = old_mode; /*S_IRWXU*/ + run_sioq(__unionfs_mkdir, &args); + err = args.err; + } else if (S_ISLNK(old_mode)) { + args.symlink.parent = new_hidden_parent_dentry->d_inode; + args.symlink.dentry = new_hidden_dentry; + args.symlink.symbuf = symbuf; + args.symlink.mode = old_mode; + run_sioq(__unionfs_symlink, &args); + err = args.err; + } else if (S_ISBLK(old_mode) + || S_ISCHR(old_mode) + || S_ISFIFO(old_mode) + || S_ISSOCK(old_mode)) { + args.mknod.parent = new_hidden_parent_dentry->d_inode; + args.mknod.dentry = new_hidden_dentry; + args.mknod.mode = old_mode; + args.mknod.dev = old_hidden_dentry->d_inode->i_rdev; + run_sioq(__unionfs_mknod, &args); + err = args.err; + } else if (S_ISREG(old_mode)) { + args.create.parent = new_hidden_parent_dentry->d_inode; + args.create.dentry = new_hidden_dentry; + args.create.mode = old_mode; + args.create.nd = NULL; + run_sioq(__unionfs_create, &args); + err = args.err; + } else { + printk(KERN_ERR "Unknown inode type %d\n", + old_hidden_dentry->d_inode->i_mode); + BUG(); + } + + copyup_readlink_err: + KFREE(symbuf); + if (err) { + /* get rid of the hidden dentry and all its traces */ + DPUT(new_hidden_dentry); + set_dtohd_index(dentry, new_bindex, NULL); + set_dbstart(dentry, old_bstart); + set_dbend(dentry, old_bend); + goto out_dir; + } +#ifdef UNIONFS_IMAP + if (stopd(sb)->usi_persistent) { + err = write_uin(dentry->d_sb, dentry->d_inode->i_ino, + new_bindex, new_hidden_dentry->d_inode->i_ino); + if (err) + goto out_dir; + } +#endif + /* We actually copyup the file here. */ + if (S_ISREG(old_hidden_dentry->d_inode->i_mode)) { + mntget(stohiddenmnt_index(sb, old_bindex)); + branchget(sb, old_bindex); + got_branch_input = old_bindex; + input_file = + DENTRY_OPEN(old_hidden_dentry, + stohiddenmnt_index(sb, old_bindex), + O_RDONLY | O_LARGEFILE); + if (IS_ERR(input_file)) { + err = PTR_ERR(input_file); + goto out_dir; + } + if (!input_file->f_op || !input_file->f_op->read) { + err = -EINVAL; + goto out_dir; + } + + /* copy the new file */ + DGET(new_hidden_dentry); + mntget(stohiddenmnt_index(sb, new_bindex)); + branchget(sb, new_bindex); + got_branch_output = new_bindex; + output_file = + DENTRY_OPEN(new_hidden_dentry, + stohiddenmnt_index(sb, new_bindex), + O_WRONLY | O_LARGEFILE); + if (IS_ERR(output_file)) { + err = PTR_ERR(output_file); + goto out_dir; + } + if (!output_file->f_op || !output_file->f_op->write) { + err = -EINVAL; + goto out_dir; + } + + /* allocating a buffer */ + buf = (char *)KMALLOC(PAGE_SIZE, GFP_KERNEL); + if (!buf) { + err = -ENOMEM; + goto out_dir; + } + + /* now read PAGE_SIZE bytes from offset 0 in a loop */ + old_fs = get_fs(); + + input_file->f_pos = 0; + output_file->f_pos = 0; + + err = 0; // reset error just in case + set_fs(KERNEL_DS); + do { + if (len >= PAGE_SIZE) + size = PAGE_SIZE; + else if ((len < PAGE_SIZE) && (len > 0)) + size = len; + + len -= PAGE_SIZE; + + read_bytes = + input_file->f_op->read(input_file, + (char __user *)buf, size, + &input_file->f_pos); + if (read_bytes <= 0) { + err = read_bytes; + break; + } + + write_bytes = + output_file->f_op->write(output_file, + (char __user *)buf, + read_bytes, + &output_file->f_pos); + if (write_bytes < 0 || (write_bytes < read_bytes)) { + err = write_bytes; + break; + } + } while ((read_bytes > 0) && (len > 0)); + set_fs(old_fs); + KFREE(buf); +#ifdef UNIONFS_MMAP + /* SP: Now that we copied up the file, have to sync its data + * as otherwise when we do a read_cache_page(), we'll possibly + * read crap. + * + * another posisble solution would be in the address op code + * would be to check the "lower" page to see if its dirty, + * and if it's dirty, use it directl + */ + if (!err) { + err = + output_file->f_op->fsync(output_file, + new_hidden_dentry, 0); + } +#endif + if (err) { + /* copyup failed, because we ran out of space or quota, + * or something else happened so let's unlink; we don't + * really care about the return value of vfs_unlink */ + vfs_unlink(new_hidden_parent_dentry->d_inode, + new_hidden_dentry, NULL); + + goto out_dir; + } + } + + /* Set permissions. */ + if ((err = + copyup_permissions(sb, old_hidden_dentry, new_hidden_dentry))) + goto out_dir; + /* Selinux uses extended attributes for permissions. */ + if ((err = copyup_xattrs(old_hidden_dentry, new_hidden_dentry))) + goto out_dir; + + /* do not allow files getting deleted to be reinterposed */ + if (!d_deleted(dentry)) + unionfs_reinterpose(dentry); + + out_dir: + if (new_hidden_parent_dentry) + unlock_dir(new_hidden_parent_dentry); + + out: + if (input_file && !IS_ERR(input_file)) { + fput(input_file); + } else { + /* since input file was not opened, we need to explicitly + * dput the old_hidden_dentry + */ + DPUT(old_hidden_dentry); + } + + /* in any case, we have to branchput */ + if (got_branch_input >= 0) + branchput(sb, got_branch_input); + + if (output_file) { + if (copyup_file && !err) { + *copyup_file = output_file; + } else { + /* close the file if there was no error, or if we ran + * out of space in which case we unlinked the file */ + if (!IS_ERR(output_file)) + fput(output_file); + branchput(sb, got_branch_output); + } + } + + unionfs_read_unlock(sb); + + print_dentry("OUT: copyup_dentry", dentry); + print_inode("OUT: copyup_dentry", dentry->d_inode); + + print_exit_status(err); + return err; +} + +/* This function creates a copy of a file represented by 'file' which currently + * resides in branch 'bstart' to branch 'new_bindex. The copy will be named + * "name". */ +int copyup_named_file(struct inode *dir, struct file *file, char *name, + int bstart, int new_bindex, loff_t len) +{ + int err = 0; + struct file *output_file = NULL; + + print_entry_location(); + + err = copyup_named_dentry(dir, file->f_dentry, bstart, + new_bindex, name, strlen(name), &output_file, + len); + if (!err) { + fbstart(file) = new_bindex; + set_ftohf_index(file, new_bindex, output_file); + } + + print_exit_status(err); + return err; +} + +/* This function creates a copy of a file represented by 'file' which currently + * resides in branch 'bstart' to branch 'new_bindex. + */ +int copyup_file(struct inode *dir, struct file *file, int bstart, + int new_bindex, loff_t len) +{ + int err = 0; + struct file *output_file = NULL; + + print_entry_location(); + + err = copyup_dentry(dir, file->f_dentry, bstart, new_bindex, + &output_file, len); + if (!err) { + fbstart(file) = new_bindex; + set_ftohf_index(file, new_bindex, output_file); + } + + print_exit_status(err); + return err; +} + +/* This function replicates the directory structure upto given dentry + * in the bindex branch. Can create directory structure recursively to the right + * also. + */ +struct dentry *create_parents(struct inode *dir, struct dentry *dentry, + int bindex) +{ + struct dentry *hidden_dentry; + + print_entry_location(); + hidden_dentry = + create_parents_named(dir, dentry, dentry->d_name.name, bindex); + print_exit_location(); + + return (hidden_dentry); +} + +/* This function replicates the directory structure upto given dentry + * in the bindex branch. */ +struct dentry *create_parents_named(struct inode *dir, struct dentry *dentry, + const char *name, int bindex) +{ + int err; + struct dentry *child_dentry; + struct dentry *parent_dentry; + struct dentry *hidden_parent_dentry = NULL; + struct dentry *hidden_dentry = NULL; + struct sioq_args args; + const char *childname; + unsigned int childnamelen; + + int old_kmalloc_size; + int kmalloc_size; + int num_dentry; + int count; + + int old_bstart; + int old_bend; + struct dentry **path = NULL; + struct dentry **tmp_path; + struct super_block *sb; +#ifdef UNIONFS_IMAP + int persistent; +#endif + print_entry_location(); + + verify_locked(dentry); + + /* There is no sense allocating any less than the minimum. */ + kmalloc_size = 128; + num_dentry = kmalloc_size / sizeof(struct dentry *); + + if ((err = is_robranch_super(dir->i_sb, bindex))) { + hidden_dentry = ERR_PTR(err); + goto out; + } + + print_dentry("IN: create_parents_named", dentry); + dprint(PRINT_DEBUG, "name = %s\n", name); + + old_bstart = dbstart(dentry); + old_bend = dbend(dentry); + + hidden_dentry = ERR_PTR(-ENOMEM); + path = (struct dentry **)KZALLOC(kmalloc_size, GFP_KERNEL); + if (!path) + goto out; + + /* assume the negative dentry of unionfs as the parent dentry */ + parent_dentry = dentry; + + count = 0; + /* This loop finds the first parent that exists in the given branch. + * We start building the directory structure from there. At the end + * of the loop, the following should hold: + * child_dentry is the first nonexistent child + * parent_dentry is the first existent parent + * path[0] is the = deepest child + * path[count] is the first child to create + */ + do { + child_dentry = parent_dentry; + + /* find the parent directory dentry in unionfs */ + parent_dentry = child_dentry->d_parent; + lock_dentry(parent_dentry); + + /* find out the hidden_parent_dentry in the given branch */ + hidden_parent_dentry = dtohd_index(parent_dentry, bindex); + + /* store the child dentry */ + path[count++] = child_dentry; + if (count == num_dentry) { + old_kmalloc_size = kmalloc_size; + kmalloc_size *= 2; + num_dentry = kmalloc_size / sizeof(struct dentry *); + + tmp_path = + (struct dentry **)KZALLOC(kmalloc_size, GFP_KERNEL); + if (!tmp_path) { + hidden_dentry = ERR_PTR(-ENOMEM); + goto out; + } + memcpy(tmp_path, path, old_kmalloc_size); + KFREE(path); + path = tmp_path; + tmp_path = NULL; + } + + } while (!hidden_parent_dentry); + count--; + + sb = dentry->d_sb; +#ifdef UNIONFS_IMAP + persistent = stopd(sb)->usi_persistent; +#endif + /* This is basically while(child_dentry != dentry). This loop is + * horrible to follow and should be replaced with cleaner code. */ + while (1) { + // get hidden parent dir in the current branch + hidden_parent_dentry = dtohd_index(parent_dentry, bindex); + unlock_dentry(parent_dentry); + + // init the values to lookup + childname = child_dentry->d_name.name; + childnamelen = child_dentry->d_name.len; + + if (child_dentry != dentry) { + // lookup child in the underlying file system + hidden_dentry = + LOOKUP_ONE_LEN(childname, hidden_parent_dentry, + childnamelen); + if (IS_ERR(hidden_dentry)) + goto out; + } else { + int loop_start; + int loop_end; + int new_bstart = -1; + int new_bend = -1; + int i; + + /* is the name a whiteout of the childname ? */ + //lookup the whiteout child in the underlying file system + hidden_dentry = + LOOKUP_ONE_LEN(name, hidden_parent_dentry, + strlen(name)); + if (IS_ERR(hidden_dentry)) + goto out; + + /* Replace the current dentry (if any) with the new one. */ + DPUT(dtohd_index(dentry, bindex)); + set_dtohd_index(dentry, bindex, hidden_dentry); + + loop_start = + (old_bstart < bindex) ? old_bstart : bindex; + loop_end = (old_bend > bindex) ? old_bend : bindex; + + /* This loop sets the bstart and bend for the new + * dentry by traversing from left to right. + * It also dputs all negative dentries except + * bindex (the newly looked dentry + */ + for (i = loop_start; i <= loop_end; i++) { + if (!dtohd_index(dentry, i)) + continue; + + if (i == bindex) { + new_bend = i; + if (new_bstart < 0) + new_bstart = i; + continue; + } + + if (!dtohd_index(dentry, i)->d_inode) { + DPUT(dtohd_index(dentry, i)); + set_dtohd_index(dentry, i, NULL); + } else { + if (new_bstart < 0) + new_bstart = i; + new_bend = i; + } + } + + if (new_bstart < 0) + new_bstart = bindex; + if (new_bend < 0) + new_bend = bindex; + set_dbstart(dentry, new_bstart); + set_dbend(dentry, new_bend); + break; + } + + if (hidden_dentry->d_inode) { + /* since this already exists we dput to avoid + * multiple references on the same dentry */ + DPUT(hidden_dentry); + } else { + + /* its a negative dentry, create a new dir */ + hidden_parent_dentry = lock_parent(hidden_dentry); + args.mkdir.parent = hidden_parent_dentry->d_inode; + args.mkdir.dentry = hidden_dentry; + args.mkdir.mode = child_dentry->d_inode->i_mode; + run_sioq(__unionfs_mkdir, &args); + err = args.err; + if (!err) + err = copyup_permissions + (dir->i_sb, child_dentry, hidden_dentry); + unlock_dir(hidden_parent_dentry); + if (err) { + DPUT(hidden_dentry); + hidden_dentry = ERR_PTR(err); + goto out; + } +#ifdef UNIONFS_IMAP + if (persistent) { + err = write_uin + (sb, child_dentry->d_inode->i_ino, + bindex, hidden_dentry->d_inode->i_ino); + if (err) { + DPUT(hidden_dentry); + hidden_dentry = ERR_PTR(err); + goto out; + } + } +#endif + set_itohi_index(child_dentry->d_inode, bindex, + IGRAB(hidden_dentry->d_inode)); + if (ibstart(child_dentry->d_inode) > bindex) + ibstart(child_dentry->d_inode) = bindex; + if (ibend(child_dentry->d_inode) < bindex) + ibend(child_dentry->d_inode) = bindex; + + set_dtohd_index(child_dentry, bindex, hidden_dentry); + if (dbstart(child_dentry) > bindex) + set_dbstart(child_dentry, bindex); + if (dbend(child_dentry) < bindex) + set_dbend(child_dentry, bindex); + } + + parent_dentry = child_dentry; + child_dentry = path[--count]; + } + out: + KFREE(path); + print_dentry("OUT: create_parents_named", dentry); + print_exit_pointer(hidden_dentry); + return hidden_dentry; +} + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/commonfops.c +++ linux-2.6.28/ubuntu/unionfs/commonfops.c @@ -0,0 +1,706 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: commonfops.c,v 1.61 2006/08/05 01:28:46 jro Exp $ + */ + +#include "unionfs.h" + +/* We only need this function here, but it could get promoted to unionfs.h, if + * other things need a generation specific branch putting function. */ +static inline void branchput_gen(int generation, struct super_block *sb, + int index) +{ + struct putmap *putmap; + + if (generation == atomic_read(&stopd(sb)->usi_generation)) { + branchput(sb, index); + return; + } + + BUG_ON(stopd(sb)->usi_firstputmap > generation); + BUG_ON(stopd(sb)->usi_lastputmap < generation); + + putmap = + stopd(sb)->usi_putmaps[generation - stopd(sb)->usi_firstputmap]; + BUG_ON(index < 0); + BUG_ON(index > putmap->bend); + BUG_ON(putmap->map[index] < 0); + branchput(sb, putmap->map[index]); + if (atomic_dec_and_test(&putmap->count)) { + stopd(sb)->usi_putmaps[generation - stopd(sb)->usi_firstputmap] + = NULL; + dprint(PRINT_DEBUG, "Freeing putmap %d.\n", generation); + KFREE(putmap); + } +} + +static char *get_random_name(int size, unsigned char *name) +{ + int i; + int j; + unsigned char *tmpbuf = NULL; + + if (size <= WHLEN) + return NULL; + + if (!name) + name = KMALLOC(size + 1, GFP_KERNEL); + if (!name) { + name = ERR_PTR(-ENOMEM); + goto out; + } + strncpy(name, WHPFX, WHLEN); + + tmpbuf = KMALLOC(size, GFP_KERNEL); + if (!tmpbuf) { + KFREE(name); + name = ERR_PTR(-ENOMEM); + goto out; + } + + get_random_bytes((void *)tmpbuf, (size - 3) / 2); + + j = WHLEN; + i = 0; + while ((i < (size - 3) / 2) && (j < size)) { + /* get characters in the 0-9, A-F range */ + + name[j] = + (tmpbuf[i] % 16) < + 10 ? (tmpbuf[i] % 16) + '0' : (tmpbuf[i] % 16) + 'a'; + j++; + if (j == size) + break; + name[j] = + (tmpbuf[i] >> 4) < + 10 ? (tmpbuf[i] >> 4) + '0' : (tmpbuf[i] >> 4) + 'a'; + j++; + + i++; + } + + name[size] = '\0'; + + out: + KFREE(tmpbuf); + return (name); + +} + +static int copyup_deleted_file(struct file *file, struct dentry *dentry, + int bstart, int bindex) +{ + int attempts = 0; + int err; + int exists = 1; + char *name = NULL; + struct dentry *tmp_dentry = NULL; + struct dentry *hidden_dentry = NULL; + struct dentry *hidden_dir_dentry = NULL; + + print_entry_location(); + + /* Try five times to get a unique file name, fail after that. Five is + * simply a magic number, because we shouldn't try forever. */ + while (exists) { + /* The first call allocates, the subsequent ones reuse. */ + name = get_random_name(UNIONFS_TMPNAM_LEN, name); + err = -ENOMEM; + if (!name) + goto out; + //XXX: Why do we do this every time? bstart never changes? + hidden_dentry = dtohd_index(dentry, bstart); + + tmp_dentry = LOOKUP_ONE_LEN(name, hidden_dentry->d_parent, + UNIONFS_TMPNAM_LEN); + err = PTR_ERR(tmp_dentry); + if (IS_ERR(tmp_dentry)) + goto out; + exists = tmp_dentry->d_inode ? 1 : 0; + DPUT(tmp_dentry); + + err = -EEXIST; + if (++attempts > 5) + goto out; + } + + err = copyup_named_file(dentry->d_parent->d_inode, file, name, bstart, + bindex, file->f_dentry->d_inode->i_size); + if (err) + goto out; + + /* bring it to the same state as an unlinked file */ + hidden_dentry = dtohd_index(dentry, dbstart(dentry)); + hidden_dir_dentry = lock_parent(hidden_dentry); + err = vfs_unlink(hidden_dir_dentry->d_inode, hidden_dentry, NULL); + unlock_dir(hidden_dir_dentry); + + out: + KFREE(name); + print_exit_status(err); + return err; +} + +int unionfs_file_revalidate(struct file *file, int willwrite) +{ + struct super_block *sb; + struct dentry *dentry; + int sbgen, fgen, dgen; + int bindex, bstart, bend; + struct file *hidden_file; + struct dentry *hidden_dentry; + int size; + + int err = 0; + + print_entry(" file = %p", file); + + dentry = file->f_dentry; + lock_dentry(dentry); + sb = dentry->d_sb; + unionfs_read_lock(sb); + if (!unionfs_d_revalidate(dentry, NULL) && !d_deleted(dentry)) { + err = -ESTALE; + goto out; + } + print_dentry("file revalidate in", dentry); + + sbgen = atomic_read(&stopd(sb)->usi_generation); + dgen = atomic_read(&dtopd(dentry)->udi_generation); + fgen = atomic_read(&ftopd(file)->ufi_generation); + + BUG_ON(sbgen > dgen); + + /* There are two cases we are interested in. The first is if the + * generation is lower than the super-block. The second is if someone + * has copied up this file from underneath us, we also need to refresh + * things. */ + if (!d_deleted(dentry) && + ((sbgen > fgen) || (dbstart(dentry) != fbstart(file)))) { + /* First we throw out the existing files. */ + bstart = fbstart(file); + bend = fbend(file); + for (bindex = bstart; bindex <= bend; bindex++) { + if (ftohf_index(file, bindex)) { + branchput_gen(fgen, dentry->d_sb, bindex); + fput(ftohf_index(file, bindex)); + } + } + + if (ftohf_ptr(file)) { + KFREE(ftohf_ptr(file)); + ftohf_ptr(file) = NULL; + } + + /* Now we reopen the file(s) as in unionfs_open. */ + bstart = fbstart(file) = dbstart(dentry); + bend = fbend(file) = dbend(dentry); + + size = sizeof(struct file *) * sbmax(sb); + ftohf_ptr(file) = KZALLOC(size, GFP_KERNEL); + if (!ftohf_ptr(file)) { + err = -ENOMEM; + goto out; + } + + if (S_ISDIR(dentry->d_inode->i_mode)) { + /* We need to open all the files. */ + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) + continue; + + DGET(hidden_dentry); + mntget(stohiddenmnt_index(sb, bindex)); + branchget(sb, bindex); + + hidden_file = + DENTRY_OPEN(hidden_dentry, + stohiddenmnt_index(sb, bindex), + file->f_flags); + if (IS_ERR(hidden_file)) { + err = PTR_ERR(hidden_file); + goto out; + } else { + set_ftohf_index(file, bindex, + hidden_file); + } + } + } else { + /* We only open the highest priority branch. */ + hidden_dentry = dtohd(dentry); + if (willwrite && IS_WRITE_FLAG(file->f_flags) + && is_robranch(dentry)) { + for (bindex = bstart - 1; bindex >= 0; bindex--) { + + err = copyup_file(dentry-> + d_parent-> + d_inode, + file, + bstart, + bindex, + file-> + f_dentry-> + d_inode->i_size); + + if (!err) + break; + else + continue; + + } + atomic_set(&ftopd(file)->ufi_generation, + atomic_read(&itopd(dentry->d_inode)-> + uii_generation)); + goto out; + } + + DGET(hidden_dentry); + mntget(stohiddenmnt_index(sb, bstart)); + branchget(sb, bstart); + hidden_file = + DENTRY_OPEN(hidden_dentry, + stohiddenmnt_index(sb, bstart), + file->f_flags); + if (IS_ERR(hidden_file)) { + err = PTR_ERR(hidden_file); + goto out; + } + set_ftohf(file, hidden_file); + /* Fix up the position. */ + hidden_file->f_pos = file->f_pos; + + memcpy(&(hidden_file->f_ra), &(file->f_ra), + sizeof(struct file_ra_state)); + } + atomic_set(&ftopd(file)->ufi_generation, + atomic_read(&itopd(dentry->d_inode)-> + uii_generation)); + } + + /* Copyup on the first write to a file on a readonly branch. */ + if (willwrite && IS_WRITE_FLAG(file->f_flags) + && !IS_WRITE_FLAG(ftohf(file)->f_flags) && is_robranch(dentry)) { + dprint(PRINT_DEBUG, + "Doing delayed copyup of a read-write file on a read-only branch.\n"); + bstart = fbstart(file); + bend = fbend(file); + + BUG_ON(!S_ISREG(file->f_dentry->d_inode->i_mode)); + + for (bindex = bstart - 1; bindex >= 0; bindex--) { + if (!d_deleted(file->f_dentry)) { + err = + copyup_file(dentry->d_parent-> + d_inode, file, bstart, + bindex, + file->f_dentry-> + d_inode->i_size); + } else { + err = + copyup_deleted_file(file, dentry, bstart, + bindex); + } + + if (!err) + break; + else + continue; + + } + if (!err && (bstart > fbstart(file))) { + bend = fbend(file); + for (bindex = bstart; bindex <= bend; bindex++) { + if (ftohf_index(file, bindex)) { + branchput(dentry->d_sb, bindex); + fput(ftohf_index(file, bindex)); + set_ftohf_index(file, bindex, NULL); + } + } + fbend(file) = bend; + } + } + + out: + print_dentry("file revalidate out", dentry); + unlock_dentry(dentry); + unionfs_read_unlock(dentry->d_sb); + print_exit_status(err); + return err; +} + +int unionfs_open(struct inode *inode, struct file *file) +{ + int err = 0; + int hidden_flags; + struct file *hidden_file = NULL; + struct dentry *hidden_dentry = NULL; + struct dentry *dentry = NULL; + int bindex = 0, bstart = 0, bend = 0; + int locked = 0; + int size; + + print_entry_location(); + + ftopd_lhs(file) = KZALLOC(sizeof(struct unionfs_file_info), GFP_KERNEL); + if (!ftopd(file)) { + err = -ENOMEM; + goto out; + } + fbstart(file) = -1; + fbend(file) = -1; + atomic_set(&ftopd(file)->ufi_generation, + atomic_read(&itopd(inode)->uii_generation)); + + size = sizeof(struct file *) * sbmax(inode->i_sb); + ftohf_ptr(file) = KZALLOC(size, GFP_KERNEL); + if (!ftohf_ptr(file)) { + err = -ENOMEM; + goto out; + } + + hidden_flags = file->f_flags; + + dentry = file->f_dentry; + dprint(PRINT_DEBUG, "dentry to open is %p\n", dentry); + lock_dentry(dentry); + unionfs_read_lock(inode->i_sb); + locked = 1; + + bstart = fbstart(file) = dbstart(dentry); + bend = fbend(file) = dbend(dentry); + + /* increment to show the kind of open, so that we can + * flush appropriately + */ + atomic_inc(&itopd(dentry->d_inode)->uii_totalopens); + + /* open all directories and make the unionfs file struct point to these hidden file structs */ + if (S_ISDIR(inode->i_mode)) { + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) + continue; + + DGET(hidden_dentry); + mntget(stohiddenmnt_index(inode->i_sb, bindex)); + hidden_file = + DENTRY_OPEN(hidden_dentry, + stohiddenmnt_index(inode->i_sb, bindex), + hidden_flags); + if (IS_ERR(hidden_file)) { + err = PTR_ERR(hidden_file); + goto out; + } + + set_ftohf_index(file, bindex, hidden_file); + /* The branchget goes after the open, because otherwise + * we would miss the reference on release. */ + branchget(inode->i_sb, bindex); + } + } else { + /* open a file */ + hidden_dentry = dtohd(dentry); + + /* check for the permission for hidden file. If the error is COPYUP_ERR, + * copyup the file. + */ + if (hidden_dentry->d_inode && is_robranch(dentry)) { + /* if the open will change the file, copy it up otherwise defer it. */ + if (hidden_flags & O_TRUNC) { + int size = 0; + + err = -EROFS; + /* copyup the file */ + for (bindex = bstart - 1; bindex >= 0; bindex--) { + err = + copyup_file(dentry-> + d_parent-> + d_inode, file, + bstart, bindex, size); + if (!err) { + break; + } + } + goto out; + } else { + hidden_flags &= ~(OPEN_WRITE_FLAGS); + } + } + + DGET(hidden_dentry); + /* dentry_open will decrement mnt refcnt if err. + * otherwise fput() will do an mntput() for us upon file close. + */ + mntget(stohiddenmnt_index(inode->i_sb, bstart)); + hidden_file = DENTRY_OPEN(hidden_dentry, + stohiddenmnt_index(inode->i_sb, + bstart), + hidden_flags); + if (IS_ERR(hidden_file)) { + err = PTR_ERR(hidden_file); + goto out; + } else { + set_ftohf(file, hidden_file); + branchget(inode->i_sb, bstart); + } + } + + out: + /* freeing the allocated resources, and fput the opened files */ + if (err < 0 && ftopd(file)) { + if (!locked) + unionfs_read_lock(file->f_dentry->d_sb); + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_file = ftohf_index(file, bindex); + if (hidden_file) { + branchput(file->f_dentry->d_sb, bindex); + /* fput calls dput for hidden_dentry */ + fput(hidden_file); + } + } + if (!locked) + unionfs_read_unlock(file->f_dentry->d_sb); + KFREE(ftohf_ptr(file)); + KFREE(ftopd(file)); + } + + print_file("OUT: unionfs_open", file); + + if (locked) { + unlock_dentry(dentry); + unionfs_read_unlock(inode->i_sb); + } + print_exit_status(err); + return err; +} + +int unionfs_file_release(struct inode *inode, struct file *file) +{ + int err = 0; + struct file *hidden_file = NULL; + int bindex, bstart, bend; + int fgen; + + print_entry_location(); + + checkinode(inode, "unionfs_release"); + + /* fput all the hidden files */ + fgen = atomic_read(&ftopd(file)->ufi_generation); + bstart = fbstart(file); + bend = fbend(file); + + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_file = ftohf_index(file, bindex); + + if (hidden_file) { + fput(hidden_file); + unionfs_read_lock(inode->i_sb); + branchput_gen(fgen, inode->i_sb, bindex); + unionfs_read_unlock(inode->i_sb); + } + } + KFREE(ftohf_ptr(file)); + + if (ftopd(file)->rdstate) { + ftopd(file)->rdstate->uds_access = jiffies; + dprint(PRINT_DEBUG, "Saving rdstate with cookie %u [%d.%lld]\n", + ftopd(file)->rdstate->uds_cookie, + ftopd(file)->rdstate->uds_bindex, + (long long)ftopd(file)->rdstate->uds_dirpos); + spin_lock(&itopd(inode)->uii_rdlock); + itopd(inode)->uii_rdcount++; + list_add_tail(&ftopd(file)->rdstate->uds_cache, + &itopd(inode)->uii_readdircache); + mark_inode_dirty(inode); + spin_unlock(&itopd(inode)->uii_rdlock); + ftopd(file)->rdstate = NULL; + } + KFREE(ftopd(file)); + + checkinode(inode, "post unionfs_release"); + + print_exit_status(err); + return err; +} + +long unionfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + long err = 0; /* don't fail by default */ + struct file *hidden_file = NULL; + int val; + + print_entry_location(); + + if ((err = unionfs_file_revalidate(file, 1))) + goto out; + + /* check if asked for local commands */ + switch (cmd) { + case FIST_IOCTL_GET_DEBUG_VALUE: + if (!capable(CAP_SYS_ADMIN)) { + err = -EACCES; + goto out; + } + val = get_debug_mask(); + err = put_user(val, (int __user *)arg); + break; + + case FIST_IOCTL_SET_DEBUG_VALUE: + if (!capable(CAP_SYS_ADMIN)) { + err = -EACCES; + goto out; + } + err = get_user(val, (int __user *)arg); + if (err) + break; + dprint(PRINT_DEBUG, "IOCTL SET: got arg %d\n", val); + if (val < 0 || val > PRINT_MAX) { + err = -EINVAL; + break; + } + set_debug_mask(val); + break; + + /* add non-debugging fist ioctl's here */ + + case UNIONFS_IOCTL_BRANCH_COUNT: + if (!capable(CAP_SYS_ADMIN)) { + err = -EACCES; + goto out; + } + err = unionfs_ioctl_branchcount(file, cmd, arg); + break; + + case UNIONFS_IOCTL_INCGEN: + if (!capable(CAP_SYS_ADMIN)) { + err = -EACCES; + goto out; + } + err = unionfs_ioctl_incgen(file, cmd, arg); + break; + + case UNIONFS_IOCTL_ADDBRANCH: + if (!capable(CAP_SYS_ADMIN)) { + err = -EACCES; + goto out; + } + err = + unionfs_ioctl_addbranch(file->f_dentry->d_inode, cmd, arg); + break; + + case UNIONFS_IOCTL_RDWRBRANCH: + if (!capable(CAP_SYS_ADMIN)) { + err = -EACCES; + goto out; + } + err = + unionfs_ioctl_rdwrbranch(file->f_dentry->d_inode, cmd, arg); + break; + + case UNIONFS_IOCTL_QUERYFILE: + /* XXX: This should take the file. */ + err = unionfs_ioctl_queryfile(file, cmd, arg); + break; + + default: + hidden_file = ftohf(file); + + err = -ENOTTY; + if (!hidden_file || !hidden_file->f_op) + goto out; + if (hidden_file->f_op->unlocked_ioctl) { + err = + hidden_file->f_op->unlocked_ioctl(hidden_file, cmd, + arg); + } else if (hidden_file->f_op->ioctl) { + lock_kernel(); + err = + hidden_file->f_op->ioctl(hidden_file->f_dentry-> + d_inode, hidden_file, cmd, + arg); + unlock_kernel(); + } + } /* end of outer switch statement */ + + out: + print_exit_status((int)err); + return err; +} + +int unionfs_flush(struct file *file, fl_owner_t id) +{ + int err = 0; /* assume ok (see open.c:close_fp) */ + struct file *hidden_file = NULL; + int bindex, bstart, bend; + + print_entry_location(); + + if ((err = unionfs_file_revalidate(file, 1))) + goto out; + if (!atomic_dec_and_test + (&itopd(file->f_dentry->d_inode)->uii_totalopens)) + goto out; + + lock_dentry(file->f_dentry); + + bstart = fbstart(file); + bend = fbend(file); + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_file = ftohf_index(file, bindex); + + if (hidden_file && hidden_file->f_op + && hidden_file->f_op->flush) { + err = hidden_file->f_op->flush(hidden_file, id); + if (err) + goto out_lock; + /* This was earlier done in the unlink_all function in unlink.c */ + /* if there are no more references to the dentry, dput it */ + if (d_deleted(file->f_dentry)) { + DPUT(dtohd_index(file->f_dentry, bindex)); + set_dtohd_index(file->f_dentry, bindex, NULL); + } + } + + } + + out_lock: + unlock_dentry(file->f_dentry); + out: + print_exit_status(err); + return err; +} + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/xattr.c +++ linux-2.6.28/ubuntu/unionfs/xattr.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef Sipek + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: xattr.c,v 1.32 2006/06/01 03:11:03 jsipek Exp $ + */ + +#include "unionfs.h" + +/* This is lifted from fs/xattr.c */ +void *xattr_alloc(size_t size, size_t limit) +{ + void *ptr; + + if (size > limit) + return ERR_PTR(-E2BIG); + + if (!size) /* size request, no buffer is needed */ + return NULL; + else if (size <= PAGE_SIZE) + ptr = KMALLOC((unsigned long)size, GFP_KERNEL); + else + ptr = vmalloc((unsigned long)size); + if (!ptr) + return ERR_PTR(-ENOMEM); + return ptr; +} + +void xattr_free(void *ptr, size_t size) +{ + if (!size) /* size request, no buffer was needed */ + return; + else if (size <= PAGE_SIZE) + KFREE(ptr); + else + vfree(ptr); +} + +/* BKL held by caller. + * dentry->d_inode->i_mutex locked + * ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t); + */ +ssize_t unionfs_getxattr(struct dentry * dentry, const char *name, void *value, + size_t size) +{ + struct dentry *hidden_dentry = NULL; + int err = -EOPNOTSUPP; + + print_entry_location(); + + dprint(PRINT_DEBUG_XATTR, "getxattr: name=\"%s\", value %lu bytes\n", + name, size); + + lock_dentry(dentry); + + hidden_dentry = dtohd(dentry); + + err = vfs_getxattr(hidden_dentry, NULL, (char*)name, value, size, + NULL); + + unlock_dentry(dentry); + print_exit_status(err); + return err; +} + +/* BKL held by caller. + * dentry->d_inode->i_mutex locked + */ +int +unionfs_setxattr(struct dentry *dentry, const char *name, const void *value, + size_t size, int flags) +{ + struct dentry *hidden_dentry = NULL; + int err = -EOPNOTSUPP; + + print_entry_location(); + + lock_dentry(dentry); + hidden_dentry = dtohd(dentry); + + dprint(PRINT_DEBUG_XATTR, "setxattr: name=\"%s\", value %lu bytes," + "flags=%x\n", name, (unsigned long)size, flags); + + err = + vfs_setxattr(hidden_dentry, NULL, (char *)name, (char *)value, + size, flags, NULL); + + unlock_dentry(dentry); + print_exit_status(err); + return err; +} + +/* BKL held by caller. + * dentry->d_inode->i_mutex locked + */ +int unionfs_removexattr(struct dentry *dentry, const char *name) +{ + struct dentry *hidden_dentry = NULL; + int err = -EOPNOTSUPP; + + print_entry_location(); + + lock_dentry(dentry); + hidden_dentry = dtohd(dentry); + + dprint(PRINT_DEBUG_XATTR, "removexattr: name=\"%s\"\n", name); + + err = vfs_removexattr(hidden_dentry, NULL, (char*)name, NULL); + + unlock_dentry(dentry); + print_exit_status(err); + return err; +} + +/* BKL held by caller. + * dentry->d_inode->i_mutex locked + */ +ssize_t unionfs_listxattr(struct dentry * dentry, char *list, size_t size) +{ + struct dentry *hidden_dentry = NULL; + int err = -EOPNOTSUPP; + char *encoded_list = NULL; + + print_entry_location(); + lock_dentry(dentry); + + hidden_dentry = dtohd(dentry); + + encoded_list = list; + err = vfs_listxattr(hidden_dentry, NULL, encoded_list, size, NULL); + + unlock_dentry(dentry); + print_exit_status(err); + return err; +} + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/dirfops.c +++ linux-2.6.28/ubuntu/unionfs/dirfops.c @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: dirfops.c,v 1.25 2006/08/05 01:28:46 jro Exp $ + */ + +#include "unionfs.h" + +/* Make sure our rdstate is playing by the rules. */ +static void verify_rdstate_offset(struct unionfs_dir_state *rdstate) +{ + BUG_ON(rdstate->uds_offset >= DIREOF); + BUG_ON(rdstate->uds_cookie >= MAXRDCOOKIE); +} + +struct unionfs_getdents_callback { + struct unionfs_dir_state *rdstate; + void *dirent; + int entries_written; + int filldir_called; + int filldir_error; + filldir_t filldir; + struct super_block *sb; +}; + +/* copied from generic filldir in fs/readir.c */ +static int unionfs_filldir(void *dirent, const char *name, int namelen, + loff_t offset, u64 ino, unsigned int d_type) +{ + struct unionfs_getdents_callback *buf = + (struct unionfs_getdents_callback *)dirent; + struct filldir_node *found = NULL; + int err = 0; + int is_wh_entry = 0; + + dprint(PRINT_DEBUG, "unionfs_filldir name=%*s\n", namelen, name); + + buf->filldir_called++; + + if ((namelen > WHLEN) && !strncmp(name, WHPFX, WHLEN)) { + name += WHLEN; + namelen -= WHLEN; + is_wh_entry = 1; + } + + found = find_filldir_node(buf->rdstate, name, namelen); + + if (found) + goto out; + + /* if 'name' isn't a whiteout filldir it. */ + if (!is_wh_entry) { + off_t pos = rdstate2offset(buf->rdstate); + ino_t unionfs_ino = ino; +#ifdef UNIONFS_IMAP + if (stopd(buf->sb)->usi_persistent) + err = read_uin(buf->sb, buf->rdstate->uds_bindex, + ino, O_CREAT, &unionfs_ino); +#endif + if (!err) { + err = buf->filldir(buf->dirent, name, namelen, pos, + unionfs_ino, d_type); + buf->rdstate->uds_offset++; + verify_rdstate_offset(buf->rdstate); + } + } + /* If we did fill it, stuff it in our hash, otherwise return an error */ + if (err) { + buf->filldir_error = err; + goto out; + } + buf->entries_written++; + if ((err = add_filldir_node(buf->rdstate, name, namelen, + buf->rdstate->uds_bindex, is_wh_entry))) + buf->filldir_error = err; + + out: + return err; +} + +static int unionfs_readdir(struct file *file, void *dirent, filldir_t filldir) +{ + int err = 0; + struct file *hidden_file = NULL; + struct inode *inode = NULL; + struct unionfs_getdents_callback buf; + struct unionfs_dir_state *uds; + int bend; + loff_t offset; + + print_entry("file = %p, pos = %llx", file, file->f_pos); + + print_file("In unionfs_readdir()", file); + + if ((err = unionfs_file_revalidate(file, 0))) + goto out; + + inode = file->f_dentry->d_inode; + checkinode(inode, "unionfs_readdir"); + + uds = ftopd(file)->rdstate; + if (!uds) { + if (file->f_pos == DIREOF) { + goto out; + } else if (file->f_pos > 0) { + uds = find_rdstate(inode, file->f_pos); + if (!uds) { + err = -ESTALE; + goto out; + } + ftopd(file)->rdstate = uds; + } else { + init_rdstate(file); + uds = ftopd(file)->rdstate; + } + } + bend = fbend(file); + + while (uds->uds_bindex <= bend) { + hidden_file = ftohf_index(file, uds->uds_bindex); + if (!hidden_file) { + dprint(PRINT_DEBUG, + "Incremented bindex to %d of %d," + " because hidden file is NULL.\n", + uds->uds_bindex, bend); + uds->uds_bindex++; + uds->uds_dirpos = 0; + continue; + } + + /* prepare callback buffer */ + buf.filldir_called = 0; + buf.filldir_error = 0; + buf.entries_written = 0; + buf.dirent = dirent; + buf.filldir = filldir; + buf.rdstate = uds; + buf.sb = inode->i_sb; + + /* Read starting from where we last left off. */ + offset = vfs_llseek(hidden_file, uds->uds_dirpos, 0); + if (offset < 0) { + err = offset; + goto out; + } + dprint(PRINT_DEBUG, "calling readdir for %d.%lld (offset = %lld)\n", + uds->uds_bindex, uds->uds_dirpos, offset); + err = vfs_readdir(hidden_file, unionfs_filldir, (void *)&buf); + dprint(PRINT_DEBUG, + "readdir on %d.%lld = %d (entries written %d, filldir called %d)\n", + uds->uds_bindex, (long long)uds->uds_dirpos, err, + buf.entries_written, buf.filldir_called); + /* Save the position for when we continue. */ + + offset = vfs_llseek(hidden_file, 0, 1); + if (offset < 0) { + err = offset; + goto out; + } + uds->uds_dirpos = offset; + + /* Copy the atime. */ + fist_copy_attr_atime(inode, hidden_file->f_dentry->d_inode); + + if (err < 0) { + goto out; + } + + if (buf.filldir_error) { + break; + } + + if (!buf.entries_written) { + uds->uds_bindex++; + uds->uds_dirpos = 0; + } + } + + if (!buf.filldir_error && uds->uds_bindex >= bend) { + dprint(PRINT_DEBUG, + "Discarding rdstate because readdir is over (hashsize = %d)\n", + uds->uds_hashentries); + /* Save the number of hash entries for next time. */ + itopd(inode)->uii_hashsize = uds->uds_hashentries; + free_rdstate(uds); + ftopd(file)->rdstate = NULL; + file->f_pos = DIREOF; + } else { + file->f_pos = rdstate2offset(uds); + dprint(PRINT_DEBUG, "rdstate now has a cookie of %u (err = %d)\n", + uds->uds_cookie, err); + } + + out: + checkinode(inode, "post unionfs_readdir"); + print_exit_status(err); + return err; +} + +/* This is not meant to be a generic repositioning function. If you do + * things that aren't supported, then we return EINVAL. + * + * What is allowed: + * (1) seeking to the same position that you are currently at + * This really has no effect, but returns where you are. + * (2) seeking to the end of the file, if you've read everything + * This really has no effect, but returns where you are. + * (3) seeking to the beginning of the file + * This throws out all state, and lets you begin again. + */ +static loff_t unionfs_dir_llseek(struct file *file, loff_t offset, int origin) +{ + struct unionfs_dir_state *rdstate; + loff_t err; + + print_entry(" file=%p, offset=0x%llx, origin = %d", file, offset, + origin); + + if ((err = unionfs_file_revalidate(file, 0))) + goto out; + + rdstate = ftopd(file)->rdstate; + + /* We let users seek to their current position, but not anywhere else. */ + if (!offset) { + switch (origin) { + case SEEK_SET: + if (rdstate) { + free_rdstate(rdstate); + ftopd(file)->rdstate = NULL; + } + init_rdstate(file); + err = 0; + break; + case SEEK_CUR: + if (file->f_pos) { + if (file->f_pos == DIREOF) + err = DIREOF; + else + BUG_ON(file->f_pos != + rdstate2offset(rdstate)); + err = file->f_pos; + } else { + err = 0; + } + break; + case SEEK_END: + /* Unsupported, because we would break everything. */ + err = -EINVAL; + break; + } + } else { + switch (origin) { + case SEEK_SET: + if (rdstate) { + if (offset == rdstate2offset(rdstate)) { + err = offset; + } else if (file->f_pos == DIREOF) { + err = DIREOF; + } else { + err = -EINVAL; + } + } else { + if ((rdstate = + find_rdstate(file->f_dentry->d_inode, + offset))) { + ftopd(file)->rdstate = rdstate; + err = rdstate->uds_offset; + } else { + err = -EINVAL; + } + } + break; + case SEEK_CUR: + case SEEK_END: + /* Unsupported, because we would break everything. */ + err = -EINVAL; + break; + } + } + + out: + print_exit_status((int)err); + return err; +} + +/* Trimmed directory options, we shouldn't pass everything down since + * we don't want to operate on partial directories. + */ +struct file_operations unionfs_dir_fops = { + .llseek = unionfs_dir_llseek, + .read = generic_read_dir, + .readdir = unionfs_readdir, + .unlocked_ioctl = unionfs_ioctl, + .open = unionfs_open, + .release = unionfs_file_release, + .flush = unionfs_flush, +}; + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/lookup.c +++ linux-2.6.28/ubuntu/unionfs/lookup.c @@ -0,0 +1,524 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: lookup.c,v 1.49 2006/10/31 18:05:33 yiannos Exp $ + */ + +#include "unionfs.h" + +static int is_opaque_dir(struct dentry *dentry, int bindex); +static int is_validname(const char *name); + +struct dentry *unionfs_lookup_backend(struct dentry *dentry, struct nameidata *nd, int lookupmode) +{ + int err = 0; + struct dentry *hidden_dentry = NULL; + struct dentry *wh_hidden_dentry = NULL; + struct dentry *hidden_dir_dentry = NULL; + struct dentry *parent_dentry = NULL; + int bindex, bstart, bend, bopaque; + int dentry_count = 0; /* Number of positive dentries. */ + int first_dentry_offset = -1; + struct dentry *first_hidden_dentry = NULL; + int locked_parent = 0; + int locked_child = 0; + + int opaque; + char *whname = NULL; + const char *name; + int namelen; + + print_entry("mode = %d", lookupmode); + + /* We should already have a lock on this dentry in the case of a + * partial lookup, or a revalidation. Otherwise it is returned from + * new_dentry_private_data already locked. */ + if (lookupmode == INTERPOSE_PARTIAL || lookupmode == INTERPOSE_REVAL + || lookupmode == INTERPOSE_REVAL_NEG) { + verify_locked(dentry); + } else { + BUG_ON(dtopd_nocheck(dentry) != NULL); + locked_child = 1; + } + if (lookupmode != INTERPOSE_PARTIAL) + if ((err = new_dentry_private_data(dentry))) + goto out; + /* must initialize dentry operations */ + dentry->d_op = &unionfs_dops; + + parent_dentry = GET_PARENT(dentry); + /* We never partial lookup the root directory. */ + if (parent_dentry != dentry) { + lock_dentry(parent_dentry); + locked_parent = 1; + } else { + DPUT(parent_dentry); + parent_dentry = NULL; + goto out; + } + + print_dentry("IN unionfs_lookup (parent)", parent_dentry); + print_dentry("IN unionfs_lookup (child)", dentry); + + name = dentry->d_name.name; + namelen = dentry->d_name.len; + + /* No dentries should get created for possible whiteout names. */ + if (!is_validname(name)) { + err = -EPERM; + goto out_free; + } + + /* Now start the actual lookup procedure. */ + bstart = dbstart(parent_dentry); + bend = dbend(parent_dentry); + bopaque = dbopaque(parent_dentry); + BUG_ON(bstart < 0); + + /* It would be ideal if we could convert partial lookups to only have + * to do this work when they really need to. It could probably improve + * performance quite a bit, and maybe simplify the rest of the code. */ + if (lookupmode == INTERPOSE_PARTIAL) { + bstart++; + if ((bopaque != -1) && (bopaque < bend)) + bend = bopaque; + } + + dprint(PRINT_DEBUG, "bstart = %d, bend = %d\n", bstart, bend); + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_dentry = dtohd_index(dentry, bindex); + if (lookupmode == INTERPOSE_PARTIAL && hidden_dentry) + continue; + BUG_ON(hidden_dentry != NULL); + + hidden_dir_dentry = dtohd_index(parent_dentry, bindex); + + /* if the parent hidden dentry does not exist skip this */ + if (!(hidden_dir_dentry && hidden_dir_dentry->d_inode)) + continue; + + /* also skip it if the parent isn't a directory. */ + if (!S_ISDIR(hidden_dir_dentry->d_inode->i_mode)) + continue; + + /* Reuse the whiteout name because its value doesn't change. */ + if (!whname) { + whname = alloc_whname(name, namelen); + if (IS_ERR(whname)) { + err = PTR_ERR(whname); + goto out_free; + } + } + + /* check if whiteout exists in this branch: lookup .wh.foo */ + wh_hidden_dentry = LOOKUP_ONE_LEN(whname, hidden_dir_dentry, + namelen + WHLEN); + if (IS_ERR(wh_hidden_dentry)) { + DPUT(first_hidden_dentry); + err = PTR_ERR(wh_hidden_dentry); + goto out_free; + } + + if (wh_hidden_dentry->d_inode) { + /* We found a whiteout so lets give up. */ + dprint(PRINT_DEBUG, "whiteout found in %d\n", bindex); + if (S_ISREG(wh_hidden_dentry->d_inode->i_mode)) { + set_dbend(dentry, bindex); + set_dbopaque(dentry, bindex); + DPUT(wh_hidden_dentry); + break; + } + err = -EIO; + printk(KERN_NOTICE "EIO: Invalid whiteout entry type" + " %d.\n", wh_hidden_dentry->d_inode->i_mode); + DPUT(wh_hidden_dentry); + DPUT(first_hidden_dentry); + goto out_free; + } + + DPUT(wh_hidden_dentry); + wh_hidden_dentry = NULL; + + /* Now do regular lookup; lookup foo */ + nd->path.dentry = dtohd_index(dentry, bindex); + /* FIXME: fix following line for mount point crossing */ + nd->path.mnt = stohiddenmnt_index(parent_dentry->d_sb, bindex); + + hidden_dentry = LOOKUP_ONE_LEN(name, hidden_dir_dentry, namelen); + print_dentry("hidden result", hidden_dentry); + if (IS_ERR(hidden_dentry)) { + DPUT(first_hidden_dentry); + err = PTR_ERR(hidden_dentry); + goto out_free; + } + + /* Store the first negative dentry specially, because if they + * are all negative we need this for future creates. */ + if (!hidden_dentry->d_inode) { + if (!first_hidden_dentry && (dbstart(dentry) == -1)) { + first_hidden_dentry = hidden_dentry; + first_dentry_offset = bindex; + } else { + DPUT(hidden_dentry); + } + continue; + } + + /* number of positive dentries */ + dentry_count++; + + /* store underlying dentry */ + if (dbstart(dentry) == -1) + set_dbstart(dentry, bindex); + set_dtohd_index(dentry, bindex, hidden_dentry); + set_dbend(dentry, bindex); + + /* update parent directory's atime with the bindex */ + fist_copy_attr_atime(parent_dentry->d_inode, + hidden_dir_dentry->d_inode); + + /* We terminate file lookups here. */ + if (!S_ISDIR(hidden_dentry->d_inode->i_mode)) { + if (lookupmode == INTERPOSE_PARTIAL) + continue; + if (dentry_count == 1) + goto out_positive; + /* This can only happen with mixed D-*-F-* */ + BUG_ON(!S_ISDIR(dtohd(dentry)->d_inode->i_mode)); + continue; + } + + opaque = is_opaque_dir(dentry, bindex); + if (opaque < 0) { + DPUT(first_hidden_dentry); + err = opaque; + goto out_free; + } + if (opaque) { + set_dbend(dentry, bindex); + set_dbopaque(dentry, bindex); + break; + } + } + + if (dentry_count) + goto out_positive; + else + goto out_negative; + + out_negative: + if (lookupmode == INTERPOSE_PARTIAL) + goto out; + + /* If we've only got negative dentries, then use the leftmost one. */ + if (lookupmode == INTERPOSE_REVAL) { + if (dentry->d_inode) { + itopd(dentry->d_inode)->uii_stale = 1; + } + goto out; + } + /* This should only happen if we found a whiteout. */ + if (first_dentry_offset == -1) { + nd->path.dentry = dentry; + /* FIXME: fix following line for mount point crossing */ + nd->path.mnt = stohiddenmnt_index(parent_dentry->d_sb, bindex); + + first_hidden_dentry = LOOKUP_ONE_LEN(name, hidden_dir_dentry, + namelen); + + first_dentry_offset = bindex; + if (IS_ERR(first_hidden_dentry)) { + err = PTR_ERR(first_hidden_dentry); + goto out; + } + } + set_dtohd_index(dentry, first_dentry_offset, first_hidden_dentry); + set_dbstart(dentry, first_dentry_offset); + set_dbend(dentry, first_dentry_offset); + + if (lookupmode == INTERPOSE_REVAL_NEG) + BUG_ON(dentry->d_inode != NULL); + else + d_add(dentry, NULL); + goto out; + +/* This part of the code is for positive dentries. */ + out_positive: + BUG_ON(dentry_count <= 0); + + /* If we're holding onto the first negative dentry throw it out. */ + DPUT(first_hidden_dentry); + + /* Partial lookups need to reinterpose, or throw away older negs. */ + if (lookupmode == INTERPOSE_PARTIAL) { + if (dentry->d_inode) { + unionfs_reinterpose(dentry); + goto out; + } + + /* This somehow turned positive, so it is as if we had a + * negative revalidation. */ + lookupmode = INTERPOSE_REVAL_NEG; + + update_bstart(dentry); + bstart = dbstart(dentry); + bend = dbend(dentry); + } + + err = unionfs_interpose(dentry, dentry->d_sb, lookupmode); + if (err) + goto out_drop; + + checkinode(dentry->d_inode, "unionfs_lookup OUT: child"); + checkinode(parent_dentry->d_inode, "unionfs_lookup OUT: dir"); + goto out; + + out_drop: + d_drop(dentry); + + out_free: + /* should dput all the underlying dentries on error condition */ + bstart = dbstart(dentry); + if (bstart >= 0) { + bend = dbend(dentry); + for (bindex = bstart; bindex <= bend; bindex++) + DPUT(dtohd_index(dentry, bindex)); + } + KFREE(dtohd_ptr(dentry)); + dtohd_ptr(dentry) = NULL; + set_dbstart(dentry, -1); + set_dbend(dentry, -1); + + out: + if (!err && dtopd(dentry)) { + BUG_ON(dbend(dentry) > dtopd(dentry)->udi_bcount); + BUG_ON(dbend(dentry) > sbmax(dentry->d_sb)); + BUG_ON(dbstart(dentry) < 0); + } + KFREE(whname); + print_dentry("OUT unionfs_lookup (parent)", parent_dentry); + print_dentry("OUT unionfs_lookup (child)", dentry); + if (locked_parent) + unlock_dentry(parent_dentry); + DPUT(parent_dentry); + if (locked_child) + unlock_dentry(dentry); + print_exit_status(err); + return ERR_PTR(err); +} + +/* This is a utility function that fills in a unionfs dentry.*/ +int unionfs_partial_lookup(struct dentry *dentry) +{ + struct dentry *tmp; + struct nameidata nd = { .flags = 0 }; + + tmp = unionfs_lookup_backend(dentry, &nd, INTERPOSE_PARTIAL); + if (!tmp) + return 0; + if (IS_ERR(tmp)) + return PTR_ERR(tmp); + /* need to change the interface */ + BUG_ON(tmp != dentry); + return -ENOSYS; +} + +/* The rest of these are utility functions for lookup. */ +static int is_opaque_dir(struct dentry *dentry, int bindex) +{ + int err = 0; + struct dentry *hidden_dentry; + struct dentry *wh_hidden_dentry; + struct inode *hidden_inode; + struct sioq_args args; + + print_entry_location(); + + hidden_dentry = dtohd_index(dentry, bindex); + hidden_inode = hidden_dentry->d_inode; + + BUG_ON(!S_ISDIR(hidden_inode->i_mode)); + + mutex_lock(&hidden_inode->i_mutex); + if (!inode_permission(hidden_inode, MAY_EXEC)) + wh_hidden_dentry = LOOKUP_ONE_LEN(UNIONFS_DIR_OPAQUE, + hidden_dentry, + sizeof(UNIONFS_DIR_OPAQUE) - 1); + else { + args.isopaque.dentry = hidden_dentry; + run_sioq(__is_opaque_dir, &args); + wh_hidden_dentry = args.ret; + } + + mutex_unlock(&hidden_inode->i_mutex); + if (IS_ERR(wh_hidden_dentry)) { + err = PTR_ERR(wh_hidden_dentry); + dprint(PRINT_DEBUG, "LOOKUP_ONE_LEN returned: %d\n", err); + goto out; + } + if (wh_hidden_dentry->d_inode) + err = 1; + DPUT(wh_hidden_dentry); + out: + print_exit_status(err); + return err; +} + +static int is_validname(const char *name) +{ + if (!strncmp(name, WHPFX, WHLEN)) + return 0; + if (!strncmp(name, UNIONFS_DIR_OPAQUE_NAME, + sizeof(UNIONFS_DIR_OPAQUE_NAME) - 1)) + return 0; + return 1; +} + +/* The dentry cache is just so we have properly sized dentries. */ +static struct kmem_cache *unionfs_dentry_cachep; +int init_dentry_cache(void) +{ + unionfs_dentry_cachep = + kmem_cache_create("unionfs_dentry", + sizeof(struct unionfs_dentry_info), 0, + SLAB_RECLAIM_ACCOUNT, NULL); + + if (!unionfs_dentry_cachep) + return -ENOMEM; + return 0; +} + +void destroy_dentry_cache(void) +{ + if (!unionfs_dentry_cachep) + return; + kmem_cache_destroy(unionfs_dentry_cachep); + return; +} + +void free_dentry_private_data(struct unionfs_dentry_info *udi) +{ + if (!udi) + return; + kmem_cache_free(unionfs_dentry_cachep, udi); +} + +int new_dentry_private_data(struct dentry *dentry) +{ + int newsize; + int oldsize = 0; + + spin_lock(&dentry->d_lock); + if (!dtopd_nocheck(dentry)) { + dtopd_lhs(dentry) = (struct unionfs_dentry_info *) + kmem_cache_alloc(unionfs_dentry_cachep, GFP_ATOMIC); + if (!dtopd_nocheck(dentry)) + goto out; +#ifdef CONFIG_PREEMPT_RT + init_MUTEX(&dtopd_nocheck(dentry)->udi_sem); + down(&dtopd_nocheck(dentry)->udi_sem); +#else + init_MUTEX_LOCKED(&dtopd_nocheck(dentry)->udi_sem); +#endif + +#ifdef TRACKLOCK + printk("INITLOCK:%p\n", dentry); +#endif + dtohd_ptr(dentry) = NULL; + } else { + oldsize = sizeof(struct dentry *) * dtopd(dentry)->udi_bcount; + } + + dtopd_nocheck(dentry)->udi_bstart = -1; + dtopd_nocheck(dentry)->udi_bend = -1; + dtopd_nocheck(dentry)->udi_bopaque = -1; + dtopd_nocheck(dentry)->udi_bcount = sbmax(dentry->d_sb); + atomic_set(&dtopd_nocheck(dentry)->udi_generation, + atomic_read(&stopd(dentry->d_sb)->usi_generation)); + newsize = sizeof(struct dentry *) * sbmax(dentry->d_sb); + + /* Don't reallocate when we already have enough space. */ + /* It would be ideal if we could actually use the slab macros to + * determine what our object sizes is, but those are not exported. + */ + if (oldsize) { + int minsize = 128; + + if (!newsize || ((oldsize < newsize) && (newsize > minsize))) { + KFREE(dtohd_ptr(dentry)); + dtohd_ptr(dentry) = NULL; + } + } + + if (!dtohd_ptr(dentry) && newsize) { + dtohd_ptr(dentry) = KMALLOC(newsize, GFP_ATOMIC); + if (!dtohd_ptr(dentry)) + goto out; + } + + if (oldsize > newsize) + memset(dtohd_ptr(dentry), 0, oldsize); + else + memset(dtohd_ptr(dentry), 0, newsize); + + spin_unlock(&dentry->d_lock); + return 0; + + out: + free_dentry_private_data(dtopd_nocheck(dentry)); + dtopd_lhs(dentry) = NULL; + spin_unlock(&dentry->d_lock); + return -ENOMEM; +} + +void update_bstart(struct dentry *dentry) +{ + int bindex; + int bstart = dbstart(dentry); + int bend = dbend(dentry); + struct dentry *hidden_dentry; + + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) + continue; + if (hidden_dentry->d_inode) { + set_dbstart(dentry, bindex); + break; + } + DPUT(hidden_dentry); + set_dtohd_index(dentry, bindex, NULL); + } +} + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/file.c +++ linux-2.6.28/ubuntu/unionfs/file.c @@ -0,0 +1,393 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: file.c,v 1.143 2006/08/05 01:28:46 jro Exp $ + */ + +#include "unionfs.h" + +/* declarations for sparse */ +extern ssize_t unionfs_read(struct file *, char __user *, size_t, loff_t *); +extern ssize_t unionfs_write(struct file *, const char __user *, size_t, + loff_t *); + +/******************* + * File Operations * + *******************/ + +#ifndef UNIONFS_MMAP +/* SP: Disable unionfs_llseek, as use generic_file_llseek on upper file */ +static loff_t unionfs_llseek(struct file *file, loff_t offset, int origin) +{ + loff_t err; + struct file *hidden_file = NULL; + + print_entry_location(); + + dprint(PRINT_DEBUG, "unionfs_llseek: file=%p, offset=0x%llx, origin=%d\n", + file, offset, origin); + + if ((err = unionfs_file_revalidate(file, 0))) + goto out; + + hidden_file = ftohf(file); + /* always set hidden position to this one */ + hidden_file->f_pos = file->f_pos; + + memcpy(&(hidden_file->f_ra), &(file->f_ra), + sizeof(struct file_ra_state)); + + if (hidden_file->f_op && hidden_file->f_op->llseek) + err = hidden_file->f_op->llseek(hidden_file, offset, origin); + else + err = generic_file_llseek(hidden_file, offset, origin); + + if (err < 0) + goto out; + if (err != file->f_pos) { + file->f_pos = err; + // ION maybe this? + // file->f_pos = hidden_file->f_pos; + + file->f_version++; + } + out: + print_exit_status((int)err); + return err; +} +#endif +ssize_t __unionfs_read(struct file * file, char __user * buf, size_t count, + loff_t * ppos) +{ + int err = -EINVAL; + struct file *hidden_file = NULL; + loff_t pos = *ppos; + + print_file("entering __unionfs_read()", file); + + hidden_file = ftohf(file); + if (!hidden_file->f_op || !hidden_file->f_op->read) + goto out; + + err = hidden_file->f_op->read(hidden_file, buf, count, &pos); + *ppos = pos; + + out: + print_file("leaving __unionfs_read()", file); + + print_exit_status(err); + return err; +} + +ssize_t unionfs_read(struct file * file, char __user * buf, size_t count, + loff_t * ppos) +{ + int err = -EINVAL; + + print_entry_location(); + + if ((err = unionfs_file_revalidate(file, 0))) + goto out; + +#ifdef UNIONFS_MMAP + err = generic_file_read(file, buf, count, ppos); + if (err >= 0) + file_accessed(ftohf(file)); +#else + err = __unionfs_read(file, buf, count, ppos); +#endif + + out: + + print_exit_status(err); + return err; +} + +/* SP: Sendfile code not updated, but should be able to use + * generic_file_sendfile, as it would use readpage, which we now have */ +#ifdef SUPPORT_BROKEN_LOSETUP +static ssize_t unionfs_sendfile(struct file *file, loff_t * ppos, + size_t count, read_actor_t actor, void *target) +{ + ssize_t err; + struct file *hidden_file = NULL; + + print_entry_location(); + + if ((err = unionfs_file_revalidate(file, 0))) + goto out; + + hidden_file = ftohf(file); + + err = -EINVAL; + if (!hidden_file->f_op || !hidden_file->f_op->sendfile) + goto out; + + err = hidden_file->f_op->sendfile(hidden_file, ppos, count, actor, + target); + + out: + print_exit_status(err); + return err; +} +#endif +ssize_t __unionfs_write(struct file * file, const char __user * buf, + size_t count, loff_t * ppos) +{ + int err = -EINVAL; + struct file *hidden_file = NULL; + struct inode *inode; + struct inode *hidden_inode; + loff_t pos = *ppos; + int bstart, bend; + + print_entry_location(); + + inode = file->f_dentry->d_inode; + + bstart = fbstart(file); + bend = fbend(file); + + BUG_ON(bstart == -1); + + hidden_file = ftohf(file); + hidden_inode = hidden_file->f_dentry->d_inode; + + if (!hidden_file->f_op || !hidden_file->f_op->write) + goto out; + + /* adjust for append -- seek to the end of the file */ + if (file->f_flags & O_APPEND) + pos = inode->i_size; + + err = hidden_file->f_op->write(hidden_file, buf, count, &pos); + + /* + * copy ctime and mtime from lower layer attributes + * atime is unchanged for both layers + */ + if (err >= 0) + fist_copy_attr_times(inode, hidden_inode); + + *ppos = pos; + + /* update this inode's size */ + if (pos > inode->i_size) + inode->i_size = pos; + out: + print_exit_status(err); + return err; +} + +ssize_t unionfs_write(struct file * file, const char __user * buf, size_t count, + loff_t * ppos) +{ + int err = 0; + + print_entry_location(); + + if ((err = unionfs_file_revalidate(file, 1))) + goto out; +#ifdef UNIONFS_MMAP + err = generic_file_write(file, buf, count, ppos); +#else + err = __unionfs_write(file, buf, count, ppos); +#endif + out: + print_exit_status(err); + return err; +} + +static int unionfs_file_readdir(struct file *file, void *dirent, + filldir_t filldir) +{ + int err = -ENOTDIR; + print_entry_location(); + print_exit_status(err); + return err; +} + +static unsigned int unionfs_poll(struct file *file, poll_table * wait) +{ + unsigned int mask = DEFAULT_POLLMASK; + struct file *hidden_file = NULL; + + print_entry_location(); + + if (unionfs_file_revalidate(file, 0)) { + /* We should pretend an error happend. */ + mask = POLLERR | POLLIN | POLLOUT; + goto out; + } + + hidden_file = ftohf(file); + + if (!hidden_file->f_op || !hidden_file->f_op->poll) + goto out; + + mask = hidden_file->f_op->poll(hidden_file, wait); + + out: + print_exit_status(mask); + return mask; +} + +#ifndef UNIONFS_MMAP +static int __do_mmap(struct file *file, struct vm_area_struct *vma) +{ + int err; + struct file *hidden_file; + + print_entry_location(); + hidden_file = ftohf(file); + + err = -ENODEV; + if (!hidden_file->f_op || !hidden_file->f_op->mmap) + goto out; + + vma->vm_file = hidden_file; + err = hidden_file->f_op->mmap(hidden_file, vma); + get_file(hidden_file); /* make sure it doesn't get freed on us */ + fput(file); /* no need to keep extra ref on ours */ + out: + print_exit_status(err); + return err; +} +#endif +/* SP: mmap code now maps upper file + * like old code, will only copyup at this point, it's possible to copyup + * in writepage(), but I haven't bothered with that, as only apt-get seem + * to want to write to a shared/write mapping + */ +static int unionfs_mmap(struct file *file, struct vm_area_struct *vma) +{ + int err = 0; + int willwrite; + + print_entry_location(); + + /* This might could be deferred to mmap's writepage. */ + willwrite = ((vma->vm_flags | VM_SHARED | VM_WRITE) == vma->vm_flags); + if ((err = unionfs_file_revalidate(file, willwrite))) + goto out; +#ifdef UNIONFS_MMAP + err = generic_file_mmap(file, vma); + if (err) { + printk("unionfs_mmap: generic_file_mmap failed\n"); + } +#else + err = __do_mmap(file, vma); +#endif + + out: + print_exit_status(err); + return err; +} + +/* SP: disabled as use the generic file_fsync */ +#ifndef UNIONFS_MMAP +static int unionfs_fsync(struct file *file, struct dentry *dentry, int datasync) +{ + int err; + struct file *hidden_file = NULL; + + print_entry_location(); + + if ((err = unionfs_file_revalidate(file, 1))) + goto out; + + hidden_file = ftohf(file); + + err = -EINVAL; + if (!hidden_file->f_op || !hidden_file->f_op->fsync) + goto out; + + mutex_lock(&hidden_file->f_dentry->d_inode->i_mutex); + err = hidden_file->f_op->fsync(hidden_file, hidden_file->f_dentry, + datasync); + mutex_unlock(&hidden_file->f_dentry->d_inode->i_mutex); + + out: + print_exit_status(err); + return err; +} +#endif + +/* SP: disabled as none of the other in kernel fs's seem to use it */ +static int unionfs_fasync(int fd, struct file *file, int flag) +{ + int err = 0; + struct file *hidden_file = NULL; + + print_entry_location(); + + if ((err = unionfs_file_revalidate(file, 1))) + goto out; + + hidden_file = ftohf(file); + + if (hidden_file->f_op && hidden_file->f_op->fasync) + err = hidden_file->f_op->fasync(fd, hidden_file, flag); + + out: + print_exit_status(err); + return err; +} + +struct file_operations unionfs_main_fops = { +#ifdef UNIONFS_MMAP + .llseek = generic_file_llseek, +#else + .llseek = unionfs_llseek, +#endif + .read = unionfs_read, + .write = unionfs_write, + .readdir = unionfs_file_readdir, + .poll = unionfs_poll, + .unlocked_ioctl = unionfs_ioctl, + .mmap = unionfs_mmap, + .open = unionfs_open, + .flush = unionfs_flush, + .release = unionfs_file_release, +#ifdef UNIONFS_MMAP + .fsync = file_fsync, +#else + .fsync = unionfs_fsync, +#endif + .fasync = unionfs_fasync, +#ifdef SUPPORT_BROKEN_LOSETUP + .sendfile = unionfs_sendfile, +#endif +}; + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/dirhelper.c +++ linux-2.6.28/ubuntu/unionfs/dirhelper.c @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: dirhelper.c,v 1.32 2006/10/31 18:05:33 yiannos Exp $ + */ + +#include "unionfs.h" + +/* Delete all of the whiteouts in a given directory for rmdir. */ +int do_delete_whiteouts(struct dentry *dentry, int bindex, + struct unionfs_dir_state *namelist) +{ + int err = 0; + struct dentry *hidden_dir_dentry = NULL; + struct dentry *hidden_dentry; + char *name = NULL, *p; + struct inode *hidden_dir; + + int i; + struct list_head *pos; + struct filldir_node *cursor; + + /* Find out hidden parent dentry */ + hidden_dir_dentry = dtohd_index(dentry, bindex); + BUG_ON(!S_ISDIR(hidden_dir_dentry->d_inode->i_mode)); + hidden_dir = hidden_dir_dentry->d_inode; + BUG_ON(!S_ISDIR(hidden_dir->i_mode)); + + err = -ENOMEM; + name = __getname(); + if (!name) + goto out; + strcpy(name, WHPFX); + p = name + WHLEN; + + err = 0; + for (i = 0; !err && i < namelist->uds_size; i++) { + list_for_each(pos, &namelist->uds_list[i]) { + cursor = + list_entry(pos, struct filldir_node, file_list); + /* Only operate on whiteouts in this branch. */ + if (cursor->bindex != bindex) + continue; + if (!cursor->whiteout) + continue; + + strcpy(p, cursor->name); + hidden_dentry = + lookup_one_len(name, hidden_dir_dentry, + cursor->namelen + WHLEN); + if (IS_ERR(hidden_dentry)) { + err = PTR_ERR(hidden_dentry); + break; + } + if (hidden_dentry->d_inode) + err = vfs_unlink(hidden_dir, hidden_dentry, + NULL); + dput(hidden_dentry); + if (err) + break; + } + } + + __putname(name); + + /* After all of the removals, we should copy the attributes once. */ + fist_copy_attr_times(dentry->d_inode, hidden_dir_dentry->d_inode); + +out: + return err; +} + +/* Delete all of the whiteouts in a given directory for rmdir. */ +int delete_whiteouts(struct dentry *dentry, int bindex, + struct unionfs_dir_state *namelist) +{ + int err = 0; + struct dentry *hidden_dir_dentry = NULL; + struct super_block *sb; + char *name = NULL, *p; + struct inode *hidden_dir; + + struct sioq_args args; + + print_entry_location(); + + sb = dentry->d_sb; + unionfs_read_lock(sb); + + BUG_ON(!S_ISDIR(dentry->d_inode->i_mode)); + BUG_ON(bindex < dbstart(dentry)); + BUG_ON(bindex > dbend(dentry)); + err = is_robranch_super(sb, bindex); + if (err) + goto out; + + /* Find out hidden parent dentry */ + hidden_dir_dentry = dtohd_index(dentry, bindex); + BUG_ON(!S_ISDIR(hidden_dir_dentry->d_inode->i_mode)); + hidden_dir = hidden_dir_dentry->d_inode; + BUG_ON(!S_ISDIR(hidden_dir->i_mode)); + + err = -ENOMEM; + name = __getname(); + if (!name) + goto out; + strcpy(name, WHPFX); + p = name + WHLEN; + + err = 0; + mutex_lock(&hidden_dir->i_mutex); + + if (!inode_permission(hidden_dir, MAY_WRITE | MAY_EXEC)) + err = do_delete_whiteouts(dentry, bindex, namelist); + else { + args.deletewh.namelist = namelist; + args.deletewh.dentry = dentry; + args.deletewh.bindex = bindex; + run_sioq(__delete_whiteouts, &args); + err = args.err; + } + + mutex_unlock(&hidden_dir->i_mutex); + + out: + unionfs_read_unlock(sb); + print_exit_status(err); + return err; +} + +#define RD_NONE 0 +#define RD_CHECK_EMPTY 1 +/* The callback structure for check_empty. */ +struct unionfs_rdutil_callback { + int err; + int filldir_called; + struct unionfs_dir_state *rdstate; + int mode; +}; + +/* This filldir function makes sure only whiteouts exist within a directory. */ +static int readdir_util_callback(void *dirent, const char *name, int namelen, + loff_t offset, u64 ino, unsigned int d_type) +{ + int err = 0; + struct unionfs_rdutil_callback *buf = + (struct unionfs_rdutil_callback *)dirent; + int whiteout = 0; + struct filldir_node *found; + + print_entry_location(); + + buf->filldir_called = 1; + + if (name[0] == '.' + && (namelen == 1 || (name[1] == '.' && namelen == 2))) + goto out; + + if ((namelen > WHLEN) && !strncmp(name, WHPFX, WHLEN)) { + namelen -= WHLEN; + name += WHLEN; + whiteout = 1; + } + + found = find_filldir_node(buf->rdstate, name, namelen); + /* If it was found in the table there was a previous whiteout. */ + if (found) + goto out; + + /* If it wasn't found and isn't a whiteout, the directory isn't empty. */ + err = -ENOTEMPTY; + if ((buf->mode == RD_CHECK_EMPTY) && !whiteout) + goto out; + + err = add_filldir_node(buf->rdstate, name, namelen, + buf->rdstate->uds_bindex, whiteout); + + out: + buf->err = err; + print_exit_status(err); + return err; +} + +/* Is a directory logically empty? */ +int check_empty(struct dentry *dentry, struct unionfs_dir_state **namelist) +{ + int err = 0; + struct dentry *hidden_dentry = NULL; + struct super_block *sb; + struct file *hidden_file; + struct unionfs_rdutil_callback *buf = NULL; + int bindex, bstart, bend, bopaque; + + print_entry_location(); + + sb = dentry->d_sb; + + unionfs_read_lock(sb); + + BUG_ON(!S_ISDIR(dentry->d_inode->i_mode)); + + if ((err = unionfs_partial_lookup(dentry))) + goto out; + + bstart = dbstart(dentry); + bend = dbend(dentry); + bopaque = dbopaque(dentry); + if (0 <= bopaque && bopaque < bend) + bend = bopaque; + + buf = KMALLOC(sizeof(struct unionfs_rdutil_callback), GFP_KERNEL); + if (!buf) { + err = -ENOMEM; + goto out; + } + buf->err = 0; + buf->mode = RD_CHECK_EMPTY; + buf->rdstate = alloc_rdstate(dentry->d_inode, bstart); + if (!buf->rdstate) { + err = -ENOMEM; + goto out; + } + + /* Process the hidden directories with rdutil_callback as a filldir. */ + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) + continue; + if (!hidden_dentry->d_inode) + continue; + if (!S_ISDIR(hidden_dentry->d_inode->i_mode)) + continue; + + DGET(hidden_dentry); + mntget(stohiddenmnt_index(sb, bindex)); + branchget(sb, bindex); + hidden_file = + DENTRY_OPEN(hidden_dentry, stohiddenmnt_index(sb, bindex), + O_RDONLY); + if (IS_ERR(hidden_file)) { + err = PTR_ERR(hidden_file); + DPUT(hidden_dentry); + branchput(sb, bindex); + goto out; + } + + do { + buf->filldir_called = 0; + buf->rdstate->uds_bindex = bindex; + err = vfs_readdir(hidden_file, + readdir_util_callback, buf); + if (buf->err) + err = buf->err; + } while ((err >= 0) && buf->filldir_called); + + /* fput calls dput for hidden_dentry */ + fput(hidden_file); + branchput(sb, bindex); + + if (err < 0) + goto out; + } + + out: + if (buf) { + if (namelist && !err) + *namelist = buf->rdstate; + else if (buf->rdstate) + free_rdstate(buf->rdstate); + KFREE(buf); + } + + unionfs_read_unlock(sb); + + print_exit_status(err); + return err; +} + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/inode.c +++ linux-2.6.28/ubuntu/unionfs/inode.c @@ -0,0 +1,1034 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: inode.c,v 1.275 2006/10/31 18:05:33 yiannos Exp $ + */ + +#include "unionfs.h" + +/* declarations added for "sparse" */ +extern struct dentry *unionfs_lookup(struct inode *, struct dentry *, + struct nameidata *); +extern int unionfs_readlink(struct dentry *dentry, char __user * buf, + int bufsiz); +extern void unionfs_put_link(struct dentry *dentry, struct nameidata *nd, + void *cookie); + +static int unionfs_create(struct inode *parent, struct dentry *dentry, + int mode, struct nameidata *nd) +{ + int err = 0; + struct dentry *hidden_dentry = NULL; + struct dentry *whiteout_dentry = NULL; + struct dentry *new_hidden_dentry; + struct dentry *hidden_parent_dentry = NULL; + int bindex = 0, bstart; + char *name = NULL; + + print_entry_location(); + lock_dentry(dentry); + print_dentry("IN unionfs_create", dentry); + + /* We start out in the leftmost branch. */ + bstart = dbstart(dentry); + hidden_dentry = dtohd(dentry); + + /* check if whiteout exists in this branch, i.e. lookup .wh.foo first */ + name = alloc_whname(dentry->d_name.name, dentry->d_name.len); + if (IS_ERR(name)) { + err = PTR_ERR(name); + goto out; + } + + whiteout_dentry = + LOOKUP_ONE_LEN(name, hidden_dentry->d_parent, + dentry->d_name.len + WHLEN); + if (IS_ERR(whiteout_dentry)) { + err = PTR_ERR(whiteout_dentry); + whiteout_dentry = NULL; + goto out; + } + + if (whiteout_dentry->d_inode) { + /* .wh.foo has been found. */ + /* First truncate it and then rename it to foo (hence having + * the same overall effect as a normal create. + * + * XXX: This is not strictly correct. If we have unlinked the + * file and it still has a reference count, then we should + * actually unlink the whiteout so that user's data isn't + * hosed over. + */ + struct dentry *hidden_dir_dentry; + struct iattr newattrs; + + mutex_lock(&whiteout_dentry->d_inode->i_mutex); + newattrs.ia_valid = ATTR_CTIME | ATTR_ATIME + | ATTR_MTIME | ATTR_UID | ATTR_GID | ATTR_FORCE + | ATTR_KILL_SUID | ATTR_KILL_SGID; + + newattrs.ia_mode = mode & ~current->fs->umask; + newattrs.ia_uid = current->fsuid; + newattrs.ia_gid = current->fsgid; + + if (whiteout_dentry->d_inode->i_size != 0) { + newattrs.ia_valid |= ATTR_SIZE; + newattrs.ia_size = 0; + } + + err = notify_change(whiteout_dentry, NULL, &newattrs); + + mutex_unlock(&whiteout_dentry->d_inode->i_mutex); + + if (err) + printk(KERN_WARNING + "unionfs: %s:%d: notify_change failed: %d, ignoring..\n", + __FILE__, __LINE__, err); + + new_hidden_dentry = dtohd(dentry); + DGET(new_hidden_dentry); + + hidden_dir_dentry = GET_PARENT(whiteout_dentry); + lock_rename(hidden_dir_dentry, hidden_dir_dentry); + + if (!(err = is_robranch_super(dentry->d_sb, bstart))) { + err = + vfs_rename(hidden_dir_dentry->d_inode, + whiteout_dentry, NULL, + hidden_dir_dentry->d_inode, + new_hidden_dentry, NULL); + } + if (!err) { + fist_copy_attr_timesizes(parent, + new_hidden_dentry->d_parent-> + d_inode); + parent->i_nlink = get_nlinks(parent); + } + + unlock_rename(hidden_dir_dentry, hidden_dir_dentry); + DPUT(hidden_dir_dentry); + + DPUT(new_hidden_dentry); + + if (err) { + /* exit if the error returned was NOT -EROFS */ + if (!IS_COPYUP_ERR(err)) + goto out; + /* We were not able to create the file in this branch, + * so, we try to create it in one branch to left + */ + bstart--; + } else { + /* reset the unionfs dentry to point to the .wh.foo entry. */ + + /* Discard any old reference. */ + DPUT(dtohd(dentry)); + + /* Trade one reference to another. */ + set_dtohd_index(dentry, bstart, whiteout_dentry); + whiteout_dentry = NULL; + + err = unionfs_interpose(dentry, parent->i_sb, 0); + goto out; + } + } + + for (bindex = bstart; bindex >= 0; bindex--) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) { + /* if hidden_dentry is NULL, create the entire + * dentry directory structure in branch 'bindex'. + * hidden_dentry will NOT be null when bindex == bstart + * because lookup passed as a negative unionfs dentry + * pointing to a lone negative underlying dentry */ + hidden_dentry = create_parents(parent, dentry, bindex); + if (!hidden_dentry || IS_ERR(hidden_dentry)) { + if (IS_ERR(hidden_dentry)) + err = PTR_ERR(hidden_dentry); + continue; + } + } + + checkinode(parent, "unionfs_create"); + + hidden_parent_dentry = lock_parent(hidden_dentry); + if (IS_ERR(hidden_parent_dentry)) { + err = PTR_ERR(hidden_parent_dentry); + goto out; + } + /* We shouldn't create things in a read-only branch. */ + if (!(err = is_robranch_super(dentry->d_sb, bindex))) { + //DQ: vfs_create has a different prototype in 2.6 + err = vfs_create(hidden_parent_dentry->d_inode, + hidden_dentry, mode, nd); + } + if (err || !hidden_dentry->d_inode) { + unlock_dir(hidden_parent_dentry); + + /* break out of for loop if the error wasn't -EROFS */ + if (!IS_COPYUP_ERR(err)) + break; + } else { + err = unionfs_interpose(dentry, parent->i_sb, 0); + if (!err) { + fist_copy_attr_timesizes(parent, + hidden_parent_dentry-> + d_inode); + /* update number of links on parent directory */ + parent->i_nlink = get_nlinks(parent); + } + unlock_dir(hidden_parent_dentry); + break; + } + } + + out: + DPUT(whiteout_dentry); + KFREE(name); + + print_dentry("OUT unionfs_create :", dentry); + unlock_dentry(dentry); + print_exit_status(err); + return err; +} + +struct dentry *unionfs_lookup(struct inode *parent, struct dentry *dentry, + struct nameidata *nd) +{ + struct nameidata lowernd; + + if(nd) + memcpy(&lowernd, nd, sizeof(struct nameidata)); + else + memset(&lowernd, 0, sizeof(struct nameidata)); + + /* The locking is done by unionfs_lookup_backend. */ + return unionfs_lookup_backend(dentry, &lowernd, INTERPOSE_LOOKUP); +} + +static int unionfs_link(struct dentry *old_dentry, struct inode *dir, + struct dentry *new_dentry) +{ + int err = 0; + struct dentry *hidden_old_dentry = NULL; + struct dentry *hidden_new_dentry = NULL; + struct dentry *hidden_dir_dentry = NULL; + struct dentry *whiteout_dentry; + char *name = NULL; + + print_entry_location(); + double_lock_dentry(new_dentry, old_dentry); + + hidden_new_dentry = dtohd(new_dentry); + + /* check if whiteout exists in the branch of new dentry, i.e. lookup + * .wh.foo first. If present, delete it */ + name = alloc_whname(new_dentry->d_name.name, new_dentry->d_name.len); + if (IS_ERR(name)) { + err = PTR_ERR(name); + goto out; + } + + whiteout_dentry = + LOOKUP_ONE_LEN(name, hidden_new_dentry->d_parent, + new_dentry->d_name.len + WHLEN); + if (IS_ERR(whiteout_dentry)) { + err = PTR_ERR(whiteout_dentry); + goto out; + } + + if (!whiteout_dentry->d_inode) { + DPUT(whiteout_dentry); + whiteout_dentry = NULL; + } else { + /* found a .wh.foo entry, unlink it and then call vfs_link() */ + hidden_dir_dentry = lock_parent(whiteout_dentry); + if (! + (err = + is_robranch_super(new_dentry->d_sb, + dbstart(new_dentry)))) { + err = + vfs_unlink(hidden_dir_dentry->d_inode, + whiteout_dentry, NULL); + } + fist_copy_attr_times(dir, hidden_dir_dentry->d_inode); + dir->i_nlink = get_nlinks(dir); + unlock_dir(hidden_dir_dentry); + hidden_dir_dentry = NULL; + DPUT(whiteout_dentry); + if (err) + goto out; + } + + if (dbstart(old_dentry) != dbstart(new_dentry)) { + hidden_new_dentry = + create_parents(dir, new_dentry, dbstart(old_dentry)); + err = PTR_ERR(hidden_new_dentry); + if (IS_COPYUP_ERR(err)) + goto docopyup; + if (!hidden_new_dentry || IS_ERR(hidden_new_dentry)) + goto out; + } + hidden_new_dentry = dtohd(new_dentry); + hidden_old_dentry = dtohd(old_dentry); + + BUG_ON(dbstart(old_dentry) != dbstart(new_dentry)); + hidden_dir_dentry = lock_parent(hidden_new_dentry); + if (!(err = is_robranch(old_dentry))) + err = + vfs_link(hidden_old_dentry, NULL, + hidden_dir_dentry->d_inode, + hidden_new_dentry, NULL); + unlock_dir(hidden_dir_dentry); + + docopyup: + if (IS_COPYUP_ERR(err)) { + int old_bstart = dbstart(old_dentry); + int bindex; + + for (bindex = old_bstart - 1; bindex >= 0; bindex--) { + err = + copyup_dentry(old_dentry->d_parent-> + d_inode, old_dentry, + old_bstart, bindex, NULL, + old_dentry->d_inode->i_size); + if (!err) { + hidden_new_dentry = + create_parents(dir, new_dentry, bindex); + hidden_old_dentry = dtohd(old_dentry); + hidden_dir_dentry = + lock_parent(hidden_new_dentry); + /* do vfs_link */ + err = vfs_link(hidden_old_dentry, NULL, + hidden_dir_dentry->d_inode, + hidden_new_dentry, NULL); + unlock_dir(hidden_dir_dentry); + goto check_link; + } + } + goto out; + } + check_link: + if (err || !hidden_new_dentry->d_inode) + goto out; + + /* Its a hard link, so use the same inode */ + new_dentry->d_inode = IGRAB(old_dentry->d_inode); + d_instantiate(new_dentry, new_dentry->d_inode); + fist_copy_attr_all(dir, hidden_new_dentry->d_parent->d_inode); + /* propagate number of hard-links */ + old_dentry->d_inode->i_nlink = get_nlinks(old_dentry->d_inode); + + out: + if (!new_dentry->d_inode) + d_drop(new_dentry); + + KFREE(name); + + unlock_dentry(new_dentry); + unlock_dentry(old_dentry); + + print_exit_status(err); + return err; +} + +static int unionfs_symlink(struct inode *dir, struct dentry *dentry, + const char *symname) +{ + int err = 0; + struct dentry *hidden_dentry = NULL; + struct dentry *whiteout_dentry = NULL; + struct dentry *hidden_dir_dentry = NULL; + umode_t mode; + int bindex = 0, bstart; + char *name = NULL; + + print_entry_location(); + lock_dentry(dentry); + print_dentry("IN unionfs_symlink", dentry); + + /* We start out in the leftmost branch. */ + bstart = dbstart(dentry); + + hidden_dentry = dtohd(dentry); + + /* check if whiteout exists in this branch, i.e. lookup .wh.foo first. If present, delete it */ + name = alloc_whname(dentry->d_name.name, dentry->d_name.len); + if (IS_ERR(name)) { + err = PTR_ERR(name); + goto out; + } + + whiteout_dentry = + LOOKUP_ONE_LEN(name, hidden_dentry->d_parent, + dentry->d_name.len + WHLEN); + if (IS_ERR(whiteout_dentry)) { + err = PTR_ERR(whiteout_dentry); + goto out; + } + + if (!whiteout_dentry->d_inode) { + DPUT(whiteout_dentry); + whiteout_dentry = NULL; + } else { + /* found a .wh.foo entry, unlink it and then call vfs_symlink() */ + hidden_dir_dentry = lock_parent(whiteout_dentry); + + print_dentry("HDD", hidden_dir_dentry); + print_dentry("WD", whiteout_dentry); + + if (!(err = is_robranch_super(dentry->d_sb, bstart))) { + err = + vfs_unlink(hidden_dir_dentry->d_inode, + whiteout_dentry, NULL); + } + DPUT(whiteout_dentry); + + fist_copy_attr_times(dir, hidden_dir_dentry->d_inode); + /* propagate number of hard-links */ + dir->i_nlink = get_nlinks(dir); + + unlock_dir(hidden_dir_dentry); + + if (err) { + /* exit if the error returned was NOT -EROFS */ + if (!IS_COPYUP_ERR(err)) + goto out; + /* should now try to create symlink in the another branch */ + bstart--; + } + } + + /* deleted whiteout if it was present, now do a normal vfs_symlink() with + possible recursive directory creation */ + for (bindex = bstart; bindex >= 0; bindex--) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) { + /* if hidden_dentry is NULL, create the entire + * dentry directory structure in branch 'bindex'. hidden_dentry will NOT be null when + * bindex == bstart because lookup passed as a negative unionfs dentry pointing to a + * lone negative underlying dentry */ + hidden_dentry = create_parents(dir, dentry, bindex); + if (!hidden_dentry || IS_ERR(hidden_dentry)) { + if (IS_ERR(hidden_dentry)) { + err = PTR_ERR(hidden_dentry); + } + dprint(PRINT_DEBUG, + "hidden dentry NULL (or error) for bindex = %d\n", + bindex); + continue; + } + } + + hidden_dir_dentry = lock_parent(hidden_dentry); + + if (!(err = is_robranch_super(dentry->d_sb, bindex))) { + mode = S_IALLUGO; + err = + vfs_symlink(hidden_dir_dentry->d_inode, + hidden_dentry, NULL, symname); + } + unlock_dir(hidden_dir_dentry); + + if (err || !hidden_dentry->d_inode) { + /* break out of for loop if error returned was NOT -EROFS */ + if (!IS_COPYUP_ERR(err)) + break; + } else { + err = unionfs_interpose(dentry, dir->i_sb, 0); + if (!err) { + fist_copy_attr_timesizes(dir, + hidden_dir_dentry-> + d_inode); + /* update number of links on parent directory */ + dir->i_nlink = get_nlinks(dir); + } + break; + } + } + + out: + if (!dentry->d_inode) + d_drop(dentry); + + KFREE(name); + print_dentry("OUT unionfs_symlink :", dentry); + unlock_dentry(dentry); + print_exit_status(err); + return err; +} + +static int unionfs_mkdir(struct inode *parent, struct dentry *dentry, int mode) +{ + int err = 0; + struct dentry *hidden_dentry = NULL, *whiteout_dentry = NULL; + struct dentry *hidden_parent_dentry = NULL; + int bindex = 0, bstart; + char *name = NULL; + int whiteout_unlinked = 0; + struct sioq_args args; + + print_entry_location(); + lock_dentry(dentry); + print_dentry("IN unionfs_mkdir", dentry); + bstart = dbstart(dentry); + + hidden_dentry = dtohd(dentry); + + // check if whiteout exists in this branch, i.e. lookup .wh.foo first + name = alloc_whname(dentry->d_name.name, dentry->d_name.len); + if (IS_ERR(name)) { + err = PTR_ERR(name); + goto out; + } + + whiteout_dentry = + LOOKUP_ONE_LEN(name, hidden_dentry->d_parent, + dentry->d_name.len + WHLEN); + if (IS_ERR(whiteout_dentry)) { + err = PTR_ERR(whiteout_dentry); + goto out; + } + + if (!whiteout_dentry->d_inode) { + DPUT(whiteout_dentry); + whiteout_dentry = NULL; + } else { + hidden_parent_dentry = lock_parent(whiteout_dentry); + + //found a.wh.foo entry, remove it then do vfs_mkdir + if (!(err = is_robranch_super(dentry->d_sb, bstart))) { + args.unlink.parent = hidden_parent_dentry->d_inode; + args.unlink.dentry = whiteout_dentry; + run_sioq(__unionfs_unlink, &args); + err = args.err; + } + DPUT(whiteout_dentry); + + unlock_dir(hidden_parent_dentry); + + if (err) { + /* exit if the error returned was NOT -EROFS */ + if (!IS_COPYUP_ERR(err)) + goto out; + bstart--; + } else { + whiteout_unlinked = 1; + } + } + + for (bindex = bstart; bindex >= 0; bindex--) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) { + hidden_dentry = create_parents(parent, dentry, bindex); + if (!hidden_dentry || IS_ERR(hidden_dentry)) { + dprint(PRINT_DEBUG, + "hidden dentry NULL for bindex = %d\n", + bindex); + continue; + } + } + + hidden_parent_dentry = lock_parent(hidden_dentry); + if (IS_ERR(hidden_parent_dentry)) { + err = PTR_ERR(hidden_parent_dentry); + goto out; + } + if (!(err = is_robranch_super(dentry->d_sb, bindex))) { + err = + vfs_mkdir(hidden_parent_dentry->d_inode, + hidden_dentry, NULL, mode); + } + unlock_dir(hidden_parent_dentry); + + /* XXX this could potentially return a negative hidden_dentry! */ + if (err || !hidden_dentry->d_inode) { + /* break out of for loop if error returned was NOT -EROFS */ + if (!IS_COPYUP_ERR(err)) + break; + } else { + int i; + int bend = dbend(dentry); + + for (i = bindex + 1; i < bend; i++) { + if (dtohd_index(dentry, i)) { + DPUT(dtohd_index(dentry, i)); + set_dtohd_index(dentry, i, NULL); + } + } + bend = bindex; + set_dbend(dentry, bend); + + err = unionfs_interpose(dentry, parent->i_sb, 0); + if (!err) { + fist_copy_attr_timesizes(parent, + hidden_parent_dentry-> + d_inode); + /* update number of links on parent directory */ + parent->i_nlink = get_nlinks(parent); + } + + err = make_dir_opaque(dentry, dbstart(dentry)); + if (err) { + dprint(PRINT_DEBUG, + "mkdir: error creating directory override entry: %d\n", + err); + goto out; + } + break; + } + } + + out: + if (!dentry->d_inode) + d_drop(dentry); + + KFREE(name); + + print_dentry("OUT unionfs_mkdir :", dentry); + unlock_dentry(dentry); + print_exit_status(err); + return err; +} + +static int unionfs_mknod(struct inode *dir, struct dentry *dentry, int mode, + dev_t dev) +{ + int err = 0; + struct dentry *hidden_dentry = NULL, *whiteout_dentry = NULL; + struct dentry *hidden_parent_dentry = NULL; + int bindex = 0, bstart; + char *name = NULL; + int whiteout_unlinked = 0; + + print_entry_location(); + lock_dentry(dentry); + print_dentry("IN unionfs_mknod", dentry); + bstart = dbstart(dentry); + + hidden_dentry = dtohd(dentry); + + // check if whiteout exists in this branch, i.e. lookup .wh.foo first + name = alloc_whname(dentry->d_name.name, dentry->d_name.len); + if (IS_ERR(name)) { + err = PTR_ERR(name); + goto out; + } + + whiteout_dentry = + LOOKUP_ONE_LEN(name, hidden_dentry->d_parent, + dentry->d_name.len + WHLEN); + if (IS_ERR(whiteout_dentry)) { + err = PTR_ERR(whiteout_dentry); + goto out; + } + + if (!whiteout_dentry->d_inode) { + DPUT(whiteout_dentry); + whiteout_dentry = NULL; + } else { + /* found .wh.foo, unlink it */ + hidden_parent_dentry = lock_parent(whiteout_dentry); + + //found a.wh.foo entry, remove it then do vfs_mkdir + if (!(err = is_robranch_super(dentry->d_sb, bstart))) + err = vfs_unlink(hidden_parent_dentry->d_inode, + whiteout_dentry, NULL); + DPUT(whiteout_dentry); + + unlock_dir(hidden_parent_dentry); + + if (err) { + if (!IS_COPYUP_ERR(err)) + goto out; + + bstart--; + } else { + whiteout_unlinked = 1; + } + } + + for (bindex = bstart; bindex >= 0; bindex--) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) { + hidden_dentry = create_parents(dir, dentry, bindex); + if (!hidden_dentry || IS_ERR(hidden_dentry)) { + dprint(PRINT_DEBUG, + "hidden dentry NULL for bindex = %d\n", + bindex); + continue; + } + } + + hidden_parent_dentry = lock_parent(hidden_dentry); + if (IS_ERR(hidden_parent_dentry)) { + err = PTR_ERR(hidden_parent_dentry); + goto out; + } + if (!(err = is_robranch_super(dentry->d_sb, bindex))) { + err = vfs_mknod(hidden_parent_dentry->d_inode, + hidden_dentry, NULL, mode, dev); + } + /* XXX this could potentially return a negative hidden_dentry! */ + if (err || !hidden_dentry->d_inode) { + unlock_dir(hidden_parent_dentry); + /* break out of for, if error was NOT -EROFS */ + if (!IS_COPYUP_ERR(err)) + break; + } else { + err = unionfs_interpose(dentry, dir->i_sb, 0); + if (!err) { + fist_copy_attr_timesizes(dir, + hidden_parent_dentry-> + d_inode); + /* update number of links on parent directory */ + dir->i_nlink = get_nlinks(dir); + } + unlock_dir(hidden_parent_dentry); + + break; + } + } + + out: + if (!dentry->d_inode) + d_drop(dentry); + + if (name) { + KFREE(name); + } + + print_dentry("OUT unionfs_mknod :", dentry); + unlock_dentry(dentry); + print_exit_status(err); + return err; +} + +int unionfs_readlink(struct dentry *dentry, char __user * buf, int bufsiz) +{ + int err; + struct dentry *hidden_dentry; + + print_entry_location(); + lock_dentry(dentry); + hidden_dentry = dtohd(dentry); + print_dentry("unionfs_readlink IN", dentry); + + if (!hidden_dentry->d_inode->i_op || + !hidden_dentry->d_inode->i_op->readlink) { + err = -EINVAL; + goto out; + } + + err = hidden_dentry->d_inode->i_op->readlink(hidden_dentry, + buf, bufsiz); + if (err > 0) + fist_copy_attr_atime(dentry->d_inode, hidden_dentry->d_inode); + + out: + unlock_dentry(dentry); + print_exit_status(err); + return err; +} + +/* We don't lock the dentry here, because readlink does the heavy lifting. */ +static void *unionfs_follow_link(struct dentry *dentry, struct nameidata *nd) +{ + char *buf; + int len = PAGE_SIZE, err; + mm_segment_t old_fs; + + print_entry_location(); + + /* This is freed by the put_link method assuming a successful call. */ + buf = (char *)KMALLOC(len, GFP_KERNEL); + if (!buf) { + err = -ENOMEM; + goto out; + } + + /* read the symlink, and then we will follow it */ + old_fs = get_fs(); + set_fs(KERNEL_DS); + err = dentry->d_inode->i_op->readlink(dentry, (char __user *)buf, len); + set_fs(old_fs); + if (err < 0) { + KFREE(buf); + buf = NULL; + goto out; + } + buf[err] = 0; + nd_set_link(nd, buf); + err = 0; + + out: + print_exit_status(err); + return ERR_PTR(err); +} + +void unionfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie) +{ + char *link; + print_entry_location(); + link = nd_get_link(nd); + KFREE(link); + print_exit_location(); +} + +/* Basically copied from the kernel vfs permission(), but we've changed + * the following: (1) the IS_RDONLY check is skipped, and (2) if you set + * the mount option `nfsperms=insceure', we assume that -EACCES means that + * the export is read-only and we should check standard Unix permissions. + * This means that NFS ACL checks (or other advanced permission features) + * are bypassed. + */ +static int unionfs_inode_permission(struct inode *inode, int mask, struct nameidata *nd, + int bindex) +{ + int retval, submask; + + if (mask & MAY_WRITE) { + /* The first branch is allowed to be really readonly. */ + if (bindex == 0) { + umode_t mode = inode->i_mode; + if (IS_RDONLY(inode) && (S_ISREG(mode) || S_ISDIR(mode) + || S_ISLNK(mode))) + return -EROFS; + } + /* + * Nobody gets write access to an immutable file. + */ + if (IS_IMMUTABLE(inode)) + return -EACCES; + } + + /* Ordinary permission routines do not understand MAY_APPEND. */ + submask = mask & ~MAY_APPEND; + if (inode->i_op && inode->i_op->permission) { + retval = inode->i_op->permission(inode, submask); + if ((retval == -EACCES) && (submask & MAY_WRITE) && + (!strcmp("nfs", (inode)->i_sb->s_type->name)) && + (nd) && (nd->path.mnt) && (nd->path.mnt->mnt_sb) && + (branchperms(nd->path.mnt->mnt_sb, bindex) & MAY_NFSRO)) { + retval = generic_permission(inode, submask, NULL); + } + } else { + retval = generic_permission(inode, submask, NULL); + } + + if (retval && retval != -EROFS) /* ignore EROFS */ + return retval; + + /* + * skip the LSM permission check. This means unionfs will wrongly + * copy up a LSM non-writable/non-readable file on a readonly branch + * to a read-write branch leading to odd behaviour. Until the mess + * of the LSM interface changes are resolved, there's nothing else + * that can be done. + * retval = security_inode_permission(inode, mask, nd); + */ + return ((retval == -EROFS) ? 0 : retval); /* ignore EROFS */ +} + +static int unionfs_permission(struct inode *inode, int mask) +{ + struct inode *hidden_inode = NULL; + int err = 0; + int bindex, bstart, bend; + const int is_file = !S_ISDIR(inode->i_mode); + const int write_mask = (mask & MAY_WRITE) && !(mask & MAY_READ); + + print_entry_location(); + + bstart = ibstart(inode); + bend = ibend(inode); + + print_inode("IN unionfs_permission", inode); + + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_inode = itohi_index(inode, bindex); + if (!hidden_inode) + continue; + + /* check the condition for D-F-D underlying files/directories, + * we dont have to check for files, if we are checking for + * directories. + */ + if (!is_file && !S_ISDIR(hidden_inode->i_mode)) + continue; + /* We use our own special version of permission, such that + * only the first branch returns -EROFS. */ + err = unionfs_inode_permission(hidden_inode, mask, NULL, bindex); + /* The permissions are an intersection of the overall directory + * permissions, so we fail if one fails. */ + if (err) + goto out; + /* only the leftmost file matters. */ + if (is_file || write_mask) { + if (is_file && write_mask) { + err = get_write_access(hidden_inode); + if (!err) + put_write_access(hidden_inode); + } + break; + } + } + + out: + print_exit_status(err); + return err; +} + +static int unionfs_setattr(struct dentry *dentry, struct iattr *ia) +{ + int err = 0; + struct dentry *hidden_dentry; + struct inode *inode = NULL; + struct inode *hidden_inode = NULL; + int bstart, bend, bindex; + int i; + int copyup = 0; + + print_entry_location(); + lock_dentry(dentry); + bstart = dbstart(dentry); + bend = dbend(dentry); + inode = dentry->d_inode; + + for (bindex = bstart; (bindex <= bend) || (bindex == bstart); bindex++) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) + continue; + BUG_ON(hidden_dentry->d_inode == NULL); + + /* If the file is on a read only branch */ + if (is_robranch_super(dentry->d_sb, bindex) + || IS_RDONLY(hidden_dentry->d_inode)) { + if (copyup || (bindex != bstart)) + continue; + /* Only if its the leftmost file, copyup the file */ + for (i = bstart - 1; i >= 0; i--) { + loff_t size = dentry->d_inode->i_size; + if (ia->ia_valid & ATTR_SIZE) + size = ia->ia_size; + err = copyup_dentry(dentry->d_parent->d_inode, + dentry, bstart, i, NULL, + size); + + if (!err) { + copyup = 1; + hidden_dentry = dtohd(dentry); + break; + } + /* if error is in the leftmost f/s, pass it up */ + if (i == 0) + goto out; + } + + } + /* + * mode change is for clearing setuid/setgid bits. Allow lower fs + * to interpret this in its own way. + */ + if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) + ia->ia_valid &= ~ATTR_MODE; + + err = notify_change(hidden_dentry, NULL, ia); + if (err) + goto out; + break; + } +#ifdef UNIONFS_MMAP + /* + * SP: notify_change will change the lower file's size, + * but we need to truncate the page tables, so need to call + * vmtruncate() + */ + + if (ia->ia_valid & ATTR_SIZE) { + if (ia->ia_size != i_size_read(inode)) { + err = vmtruncate(inode, ia->ia_size); + if (err) { + printk("unionfs_setattr: vmtruncate failed\n"); + } + } + } +#endif + /* get the size from the first hidden inode */ + hidden_inode = itohi(dentry->d_inode); + checkinode(inode, "unionfs_setattr"); + fist_copy_attr_all(inode, hidden_inode); + + out: + unlock_dentry(dentry); + checkinode(inode, "post unionfs_setattr"); + print_exit_status(err); + return err; +} + +struct inode_operations unionfs_symlink_iops = { + .readlink = unionfs_readlink, + .permission = unionfs_permission, + .follow_link = unionfs_follow_link, + .setattr = unionfs_setattr, + .put_link = unionfs_put_link, +}; + +struct inode_operations unionfs_dir_iops = { + .create = unionfs_create, + .lookup = unionfs_lookup, + .link = unionfs_link, + .unlink = unionfs_unlink, + .symlink = unionfs_symlink, + .mkdir = unionfs_mkdir, + .rmdir = unionfs_rmdir, + .mknod = unionfs_mknod, + .rename = unionfs_rename, + .permission = unionfs_permission, + .setattr = unionfs_setattr, + .setxattr = unionfs_setxattr, + .getxattr = unionfs_getxattr, + .removexattr = unionfs_removexattr, + .listxattr = unionfs_listxattr, +}; + +struct inode_operations unionfs_main_iops = { + .permission = unionfs_permission, + .setattr = unionfs_setattr, + .setxattr = unionfs_setxattr, + .getxattr = unionfs_getxattr, + .removexattr = unionfs_removexattr, + .listxattr = unionfs_listxattr, +}; + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/unionfs_debug.h +++ linux-2.6.28/ubuntu/unionfs/unionfs_debug.h @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef Sipek + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: unionfs_debug.h,v 1.3 2006/06/01 21:25:18 jsipek Exp $ + */ + +#ifndef __UNIONFS_H_ +#error This file should only be included from unionfs.h! +#endif + +#ifdef UNIONFS_DEBUG +#define DEFAULT_DEBUG_MASK 0 +#else +#define DEFAULT_DEBUG_MASK (~0) +#endif + +/* debug print levels */ +#define PRINT_NONE 0x0000 +#define PRINT_MAIN_ENTRY 0x0001 +#define PRINT_MAIN_EXIT 0x0002 +#define PRINT_UTILITY_ENTRY 0x0004 +#define PRINT_UTILITY_EXIT 0x0008 +#define PRINT_MISC_ENTRY 0x0010 +#define PRINT_MISC_EXIT 0x0020 +#define PRINT_DATA_DENTRY 0x0040 +#define PRINT_DATA_FILE 0x0080 +#define PRINT_DATA_INODE 0x0100 +#define PRINT_DATA_SB 0x0200 +#define PRINT_DEBUG 0x0400 +#define __PRINT_DEBUG_XATTR 0x0800 +#define PRINT_DEBUG_XATTR (PRINT_DEBUG | __PRINT_DEBUG_XATTR) +#define __PRINT_DEBUG_WHITEOUT 0x1000 +#define PRINT_DEBUG_WHITEOUT (PRINT_DEBUG | __PRINT_DEBUG_WHITEOUT) + +#define PRINT_MAX (0x2000 - 1) +#define PRINT_ALL (~PRINT_NONE) + +extern unsigned int get_debug_mask(void); +extern int set_debug_mask(int val); + +/* print inode */ +extern void unionfs_print_inode(const unsigned int req, const char *prefix, const struct inode *inode); + +/* check inode */ +extern void unionfs_checkinode(const unsigned int req, const struct inode *inode, const char *msg); + +/* prunt file */ +extern void unionfs_print_file(const unsigned int req, const char *prefix, const struct file *file); + +/* print dentry */ +extern void unionfs_print_dentry(const unsigned int req, const char *prefix, const struct dentry *dentry); + +extern void unionfs_print_dentry_nocheck(const unsigned int req, const char *prefix, const struct dentry *dentry); + +/* print superblock */ +extern void unionfs_print_sb(const unsigned int req, const char *prefix, const struct super_block *sb); + +/* print message */ +extern int unionfs_print(const unsigned int req, const char *fmt, ...); + +/* forced print-debugging functions */ +#define force_print_dentry(prefix, ptr) \ + unionfs_print_dentry(PRINT_ALL, (prefix), (ptr)) +#define force_print_dentry_nocheck(prefix, ptr) \ + unionfs_print_dentry_nocheck(PRINT_ALL, (prefix), (ptr)) +#define force_print_file(prefix, ptr) \ + unionfs_print_file(PRINT_ALL, (prefix), (ptr)) +#define force_print_inode(prefix, ptr) \ + unionfs_print_inode(PRINT_ALL, (prefix), (ptr)) +#define force_print_sb(prefix, ptr) \ + unionfs_print_sb(PRINT_ALL, (prefix), (ptr)) + +#ifdef UNIONFS_DEBUG +/* + * Full-fledged debugging enabled + */ + +#define print_dentry(prefix, ptr) \ + unionfs_print_dentry(PRINT_DATA_DENTRY, (prefix), (ptr)) +#define print_dentry_nocheck(prefix, ptr) \ + unionfs_print_dentry_nocheck(PRINT_DATA_DENTRY, (prefix), (ptr)) +#define print_file(prefix, ptr) \ + unionfs_print_file(PRINT_DATA_FILE, (prefix), (ptr)) +#define print_inode(prefix, ptr) \ + unionfs_print_inode(PRINT_DATA_INODE, (prefix), (ptr)) +#define print_sb(prefix, ptr) \ + unionfs_print_sb(PRINT_DATA_SB, (prefix), (ptr)) +#define dprint(req, fmt, args...) \ + unionfs_print(req, fmt, ## args) + +#define checkinode(ptr, msg) \ + unionfs_checkinode(PRINT_DEBUG, (ptr), (msg)) + +#define __print_entryexit(req, ee, fmt, args...) \ + unionfs_print((req), \ + ee " %s %s:%d" fmt "\n", \ + __FUNCTION__, \ + __FILE__, \ + __LINE__, \ + ##args) + +#define print_entry(fmt, args...) \ + __print_entryexit(PRINT_MAIN_ENTRY, \ + "IN: ", " " fmt, ##args) + +#define print_entry_location() \ + __print_entryexit(PRINT_MAIN_ENTRY, \ + "IN: ", "") + +#define print_exit_location() \ + __print_entryexit(PRINT_MAIN_EXIT, \ + "OUT:", "") + +#define print_exit_status(status) \ + __print_entryexit(PRINT_MAIN_EXIT, \ + "OUT:", ", STATUS: %d", status) + +static inline void __print_exit_pointer(unsigned int req, void *status) +{ + if (IS_ERR(status)) + __print_entryexit(req, "OUT:", ", STATUS: %ld", + PTR_ERR(status)); + else + __print_entryexit(req, "OUT:", ", STATUS: 0x%p", + status); +} +#define print_exit_pointer(status) \ + __print_exit_pointer(PRINT_MAIN_EXIT, status) + +#define print_util_entry(fmt, args...) \ + __print_entryexit(PRINT_UTILITY_ENTRY, \ + "IN: ", " " fmt, ##args) + +#define print_util_entry_location() \ + __print_entryexit(PRINT_UTILITY_ENTRY, \ + "IN: ", "") + +#define print_util_exit_location() \ + __print_entryexit(PRINT_UTILITY_EXIT, \ + "OUT:", "") + +#define print_util_exit_status(status) \ + __print_entryexit(PRINT_UTILITY_EXIT, \ + "OUT:", ", STATUS: %d", status) + +#define print_util_exit_pointer(status) \ + __print_exit_pointer(PRINT_UTILITY_EXIT, status) + +#else /* UNIONFS_DEBUG */ +/* + * Full-fledged debugging disabled + */ + +#define print_dentry(prefix, ptr) +#define print_dentry_nocheck(prefix, ptr) +#define print_file(prefix, ptr) +#define print_inode(prefix, ptr) +#define print_sb(prefix, ptr) +#define dprint(req, fmt, args...) + +#define checkinode(ptr, msg) + +#define print_entry(args...) +#define print_entry_location() +#define print_exit_location() +#define print_exit_status(status) +#define print_exit_pointer(status) +#define print_util_entry(args...) +#define print_util_entry_location() +#define print_util_exit_location() +#define print_util_exit_status(status) +#define print_util_exit_pointer(status) + +#endif /* ! UNIONFS_DEBUG */ + + --- linux-2.6.28.orig/ubuntu/unionfs/Makefile +++ linux-2.6.28/ubuntu/unionfs/Makefile @@ -0,0 +1,16 @@ +UNIONFS_VERSION = 1.4 +SUP_MAJOR= 2 +SUP_MINOR= 6 +SUP_PATCH= 18 + +EXTRA_CFLAGS+=-DUNIONFS_VERSION=\"${UNIONFS_VERSION}\" -DSUP_MAJOR=${SUP_MAJOR} -DSUP_MINOR=${SUP_MINOR} -DSUP_PATCH=${SUP_PATCH} -DUNIONFS_UNSUPPORTED + +# This will enable full debugging support +# EXTRA_CFLAGS+=-DUNIONFS_DEBUG + +obj-$(CONFIG_FS_UNIONFS) += unionfs.o + +unionfs-objs := subr.o dentry.o file.o inode.o main.o super.o \ + stale_inode.o branchman.o xattr.o rdstate.o copyup.o \ + dirhelper.o rename.o unlink.o lookup.o persistent_inode.o \ + commonfops.o dirfops.o print.o sioq.o --- linux-2.6.28.orig/ubuntu/unionfs/sioq.h +++ linux-2.6.28/ubuntu/unionfs/sioq.h @@ -0,0 +1,80 @@ +#ifndef _SIOQ_H +#define _SIOQ_H + +struct deletewh_args { + struct unionfs_dir_state *namelist; + struct dentry *dentry; + int bindex; +}; + +struct isopaque_args { + struct dentry *dentry; +}; + +struct create_args { + struct inode *parent; + struct dentry *dentry; + umode_t mode; + struct nameidata *nd; +}; + +struct mkdir_args { + struct inode *parent; + struct dentry *dentry; + umode_t mode; +}; + +struct mknod_args { + struct inode *parent; + struct dentry *dentry; + umode_t mode; + dev_t dev; +}; + +struct symlink_args { + struct inode *parent; + struct dentry *dentry; + char *symbuf; + umode_t mode; +}; + +struct unlink_args { + struct inode *parent; + struct dentry *dentry; +}; + + +struct sioq_args { + + struct completion comp; + struct work_struct wk; + int err; + void *ret; + + union { + struct deletewh_args deletewh; + struct isopaque_args isopaque; + struct create_args create; + struct mkdir_args mkdir; + struct mknod_args mknod; + struct symlink_args symlink; + struct unlink_args unlink; + }; //} u; +}; + +extern struct workqueue_struct *sioq; +int __init init_sioq(void); +extern void fin_sioq(void); +extern void run_sioq(work_func_t func, struct sioq_args *args); + +/* Extern definitions for our privledge escalation helpers */ +extern void __unionfs_create(struct work_struct *work); +extern void __unionfs_mkdir(struct work_struct *work); +extern void __unionfs_mknod(struct work_struct *work); +extern void __unionfs_symlink(struct work_struct *work); +extern void __unionfs_unlink(struct work_struct *work); +extern void __delete_whiteouts(struct work_struct *work); +extern void __is_opaque_dir(struct work_struct *work); + +#endif /* _SIOQ_H */ + --- linux-2.6.28.orig/ubuntu/unionfs/sioq.c +++ linux-2.6.28/ubuntu/unionfs/sioq.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2004-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ + +#include "unionfs.h" + +struct workqueue_struct *sioq; + +int __init init_sioq(void) +{ + int err; + + sioq = create_workqueue("unionfs_siod"); + if (!IS_ERR(sioq)) + return 0; + + err = PTR_ERR(sioq); + printk(KERN_ERR "create_workqueue failed %d\n", err); + sioq = NULL; + return err; +} + +void fin_sioq(void) +{ + if (sioq) + destroy_workqueue(sioq); +} + +void run_sioq(work_func_t func, struct sioq_args *args) +{ + INIT_WORK(&args->wk, func); + + init_completion(&args->comp); + while (!queue_work(sioq, &args->wk)) { + // TODO: do accounting if needed + schedule(); + } + wait_for_completion(&args->comp); +} + +void __unionfs_create(struct work_struct *work) +{ + struct sioq_args *args = container_of(work, struct sioq_args, wk); + struct create_args *c = &args->create; + args->err = vfs_create(c->parent, c->dentry, c->mode, c->nd); + complete(&args->comp); +} + +void __unionfs_mkdir(struct work_struct *work) +{ + struct sioq_args *args = container_of(work, struct sioq_args, wk); + struct mkdir_args *m = &args->mkdir; + args->err = vfs_mkdir(m->parent, m->dentry, NULL, m->mode); + complete(&args->comp); +} + +void __unionfs_mknod(struct work_struct *work) +{ + struct sioq_args *args = container_of(work, struct sioq_args, wk); + struct mknod_args *m = &args->mknod; + args->err = vfs_mknod(m->parent, m->dentry, NULL, m->mode, m->dev); + complete(&args->comp); +} +void __unionfs_symlink(struct work_struct *work) +{ + struct sioq_args *args = container_of(work, struct sioq_args, wk); + struct symlink_args *s = &args->symlink; + args->err = vfs_symlink(s->parent, s->dentry, NULL, s->symbuf); + complete(&args->comp); +} + +void __unionfs_unlink(struct work_struct *work) +{ + struct sioq_args *args = container_of(work, struct sioq_args, wk); + struct unlink_args *u = &args->unlink; + args->err = vfs_unlink(u->parent, u->dentry, NULL); + complete(&args->comp); +} + +void __delete_whiteouts(struct work_struct *work) { + struct sioq_args *args = container_of(work, struct sioq_args, wk); + struct deletewh_args *d = &args->deletewh; + args->err = delete_whiteouts(d->dentry, d->bindex, d->namelist); + complete(&args->comp); +} + +void __is_opaque_dir(struct work_struct *work) +{ + struct sioq_args *args = container_of(work, struct sioq_args, wk); + + args->ret = lookup_one_len(UNIONFS_DIR_OPAQUE, args->isopaque.dentry, + sizeof(UNIONFS_DIR_OPAQUE) - 1); + complete(&args->comp); +} --- linux-2.6.28.orig/ubuntu/unionfs/super.c +++ linux-2.6.28/ubuntu/unionfs/super.c @@ -0,0 +1,762 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: super.c,v 1.101 2006/11/04 22:27:51 jsipek Exp $ + */ + +#include "unionfs.h" + +/* The inode cache is used with alloc_inode for both our inode info and the + * vfs inode. */ +static struct kmem_cache *unionfs_inode_cachep; + +void unionfs_read_inode(struct inode *inode) +{ +#ifdef UNIONFS_MMAP + /* SP: use real address operations */ + extern struct address_space_operations unionfs_aops; +#else + static struct address_space_operations unionfs_empty_aops; +#endif + int size; + + print_entry_location(); + + if (!itopd(inode)) { + printk(KERN_ERR + "No kernel memory when allocating inode private data!\n"); + BUG(); + } + + memset(itopd(inode), 0, sizeof(struct unionfs_inode_info)); + itopd(inode)->b_start = -1; + itopd(inode)->b_end = -1; + atomic_set(&itopd(inode)->uii_generation, + atomic_read(&stopd(inode->i_sb)->usi_generation)); + itopd(inode)->uii_rdlock = SPIN_LOCK_UNLOCKED; + itopd(inode)->uii_rdcount = 1; + itopd(inode)->uii_hashsize = -1; + INIT_LIST_HEAD(&itopd(inode)->uii_readdircache); + + size = sbmax(inode->i_sb) * sizeof(struct inode *); + itohi_ptr(inode) = KZALLOC(size, GFP_KERNEL); + if (!itohi_ptr(inode)) { + printk(KERN_ERR + "No kernel memory when allocating lower-pointer array!\n"); + BUG(); + } + + inode->i_version++; + inode->i_op = &unionfs_main_iops; + inode->i_fop = &unionfs_main_fops; +#ifdef UNIONFS_MMAP + inode->i_mapping->a_ops = &unionfs_aops; +#else + /* I don't think ->a_ops is ever allowed to be NULL */ + inode->i_mapping->a_ops = &unionfs_empty_aops; + dprint(PRINT_DEBUG, "setting inode 0x%p a_ops to empty (0x%p)\n", + inode, inode->i_mapping->a_ops); +#endif + + print_exit_location(); +} + +#if 0 +static void unionfs_put_inode(struct inode *inode) +{ + print_entry_location(); + + dprint(PRINT_DEBUG, "%s i_count = %d, i_nlink = %d\n", __FUNCTION__, + atomic_read(&inode->i_count), inode->i_nlink); + + /* + * This is really funky stuff: + * Basically, if i_count == 1, iput will then decrement it and this + * inode will be destroyed. It is currently holding a reference to the + * hidden inode. Therefore, it needs to release that reference by + * calling iput on the hidden inode. iput() _will_ do it for us (by + * calling our clear_inode), but _only_ if i_nlink == 0. The problem + * is, NFS keeps i_nlink == 1 for silly_rename'd files. So we must for + * our i_nlink to 0 here to trick iput() into calling our clear_inode. + */ + + if (atomic_read(&inode->i_count) == 1) + inode->i_nlink = 0; + + print_exit_location(); +} +#endif + +/* + * we now define delete_inode, because there are two VFS paths that may + * destroy an inode: one of them calls clear inode before doing everything + * else that's needed, and the other is fine. This way we truncate the inode + * size (and its pages) and then clear our own inode, which will do an iput + * on our and the lower inode. + */ +static void unionfs_delete_inode(struct inode *inode) +{ + print_entry_location(); + + checkinode(inode, "unionfs_delete_inode IN"); + inode->i_size = 0; /* every f/s seems to do that */ + +#ifdef UNIONFS_MMAP + /* SP: if you try to clear_inode() when + * inode->i_data.nrpages != 0, you'll hit a BUG + * this is also what generic_delete_inode does */ + if (inode->i_data.nrpages) + truncate_inode_pages(&inode->i_data, 0); +#endif + clear_inode(inode); + + print_exit_location(); +} + +/* final actions when unmounting a file system */ +static void unionfs_put_super(struct super_block *sb) +{ + int bindex, bstart, bend; + struct unionfs_sb_info *spd; + + print_entry_location(); + + if ((spd = stopd(sb))) { +#ifdef UNIONFS_IMAP + /* XXX: Free persistent inode stuff. */ + cleanup_imap_data(sb); +#endif + bstart = sbstart(sb); + bend = sbend(sb); + for (bindex = bstart; bindex <= bend; bindex++) + mntput(stohiddenmnt_index(sb, bindex)); + + /* Make sure we have no leaks of branchget/branchput. */ + for (bindex = bstart; bindex <= bend; bindex++) + BUG_ON(branch_count(sb, bindex) != 0); + + KFREE(spd->usi_data); + KFREE(spd); + stopd_lhs(sb) = NULL; + } + dprint(PRINT_DEBUG, "unionfs: released super\n"); + + print_exit_location(); +} + +/* Since people use this to answer the "How big of a file can I write?" + * question, we report the size of the highest priority branch as the size of + * the union. + */ +static int unionfs_statfs(struct dentry *dentry, struct kstatfs *buf) +{ + int err = 0; + struct super_block *sb, *hidden_sb; + + sb = dentry->d_sb; + + hidden_sb = stohs_index(sb, sbstart(sb)); + err = vfs_statfs(hidden_sb->s_root, buf); + + buf->f_type = UNIONFS_SUPER_MAGIC; + buf->f_namelen -= WHLEN; + + memset(&buf->f_fsid, 0, sizeof(__kernel_fsid_t)); + memset(&buf->f_spare, 0, sizeof(buf->f_spare)); + + return err; +} + +static int do_binary_remount(struct super_block *sb, int *flags, char *data) +{ + unsigned long *uldata = (unsigned long *)data; + int err; + + uldata++; + + switch (*uldata) { + case UNIONFS_IOCTL_DELBRANCH: + err = unionfs_ioctl_delbranch(sb, *(uldata + 1)); + break; + default: + err = -ENOTTY; + } + + return err; +} + +/* We don't support a standard text remount, but we do have a magic remount + * for unionctl. The idea is that you can remove a branch without opening + * the union. Eventually it would be nice to support a full-on remount, so + * that you can have all of the directories change at once, but that would + * require some pretty complicated matching code. */ +static int unionfs_remount_fs(struct super_block *sb, int *flags, char *data) +{ + if (data && *((unsigned long *)data) == UNIONFS_REMOUNT_MAGIC) + return do_binary_remount(sb, flags, data); + printk("Warning! dirs delete and imap options to remount are ignored\n"); + return 0; +} + +/* + * Called by iput() when the inode reference count reached zero + * and the inode is not hashed anywhere. Used to clear anything + * that needs to be, before the inode is completely destroyed and put + * on the inode free list. + */ +static void unionfs_clear_inode(struct inode *inode) +{ + int bindex, bstart, bend; + struct inode *hidden_inode; + struct list_head *pos, *n; + struct unionfs_dir_state *rdstate; + + print_entry_location(); + + checkinode(inode, "unionfs_clear_inode IN"); + + list_for_each_safe(pos, n, &itopd(inode)->uii_readdircache) { + rdstate = list_entry(pos, struct unionfs_dir_state, uds_cache); + list_del(&rdstate->uds_cache); + free_rdstate(rdstate); + } + + /* Decrement a reference to a hidden_inode, which was incremented + * by our read_inode when it was created initially. */ + bstart = ibstart(inode); + bend = ibend(inode); + if (bstart >= 0) { + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_inode = itohi_index(inode, bindex); + if (!hidden_inode) + continue; + IPUT(hidden_inode); + } + } + // XXX: why this assertion fails? + // because it doesn't like us + // BUG_ON((inode->i_state & I_DIRTY) != 0); + KFREE(itohi_ptr(inode)); + itohi_ptr(inode) = NULL; + + print_exit_location(); +} + +static struct inode *unionfs_alloc_inode(struct super_block *sb) +{ + struct unionfs_inode_container *c; + + print_entry_location(); + + c = (struct unionfs_inode_container *) + kmem_cache_alloc(unionfs_inode_cachep, GFP_KERNEL); + if (!c) { + print_exit_pointer(NULL); + return NULL; + } + + memset(&c->info, 0, sizeof(c->info)); + + c->vfs_inode.i_version = 1; + print_exit_pointer(&c->vfs_inode); + return &c->vfs_inode; +} + +static void unionfs_destroy_inode(struct inode *inode) +{ + print_entry("inode = %p", inode); + kmem_cache_free(unionfs_inode_cachep, itopd(inode)); + print_exit_location(); +} + +static void init_once(void *v) +{ + struct unionfs_inode_container *c = (struct unionfs_inode_container *)v; + + print_entry_location(); + + inode_init_once(&c->vfs_inode); + + print_exit_location(); +} + +int init_inode_cache(void) +{ + int err = 0; + + print_entry_location(); + + unionfs_inode_cachep = + kmem_cache_create("unionfs_inode_cache", + sizeof(struct unionfs_inode_container), 0, + SLAB_RECLAIM_ACCOUNT, init_once); + if (!unionfs_inode_cachep) + err = -ENOMEM; + print_exit_status(err); + return err; +} + +void destroy_inode_cache(void) +{ + print_entry_location(); + if (!unionfs_inode_cachep) + goto out; + kmem_cache_destroy(unionfs_inode_cachep); + out: + print_exit_location(); + return; +} + +/* Called when we have a dirty inode, right here we only throw out + * parts of our readdir list that are too old. + */ +static int unionfs_write_inode(struct inode *inode, int sync) +{ + struct list_head *pos, *n; + struct unionfs_dir_state *rdstate; + + print_entry_location(); + + spin_lock(&itopd(inode)->uii_rdlock); + list_for_each_safe(pos, n, &itopd(inode)->uii_readdircache) { + rdstate = list_entry(pos, struct unionfs_dir_state, uds_cache); + /* We keep this list in LRU order. */ + if ((rdstate->uds_access + RDCACHE_JIFFIES) > jiffies) + break; + itopd(inode)->uii_rdcount--; + list_del(&rdstate->uds_cache); + free_rdstate(rdstate); + } + spin_unlock(&itopd(inode)->uii_rdlock); + + print_exit_location(); + return 0; +} + +/* + * Used only in nfs, to kill any pending RPC tasks, so that subsequent + * code can actually succeed and won't leave tasks that need handling. + * + * PS. I wonder if this is somehow useful to undo damage that was + * left in the kernel after a user level file server (such as amd) + * dies. + */ +static void unionfs_umount_begin(struct super_block *sb) +{ + struct super_block *hidden_sb; + int bindex, bstart, bend; + + print_entry_location(); +#if 0 + if (!(flags & MNT_FORCE)) + /* we are not being MNT_FORCEd, therefore we should emulate old + * behaviour + */ + goto out; +#endif + bstart = sbstart(sb); + bend = sbend(sb); + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_sb = stohs_index(sb, bindex); + + if (hidden_sb && hidden_sb->s_op && + hidden_sb->s_op->umount_begin) + hidden_sb->s_op->umount_begin(hidden_sb); + } + + print_exit_location(); +} + +static int unionfs_show_options(struct seq_file *m, struct vfsmount *mnt) +{ + struct super_block *sb = mnt->mnt_sb; + int ret = 0; + unsigned long tmp = 0; + char *hidden_path; + int bindex, bstart, bend; + int perms; + + lock_dentry(sb->s_root); + + tmp = __get_free_page(GFP_KERNEL); + if (!tmp) { + ret = -ENOMEM; + goto out; + } + + bindex = bstart = sbstart(sb); + bend = sbend(sb); + + seq_printf(m, ",dirs="); + for (bindex = bstart; bindex <= bend; bindex++) { + struct path tp; + tp.dentry = dtohd_index(sb->s_root, bindex); + tp.mnt = stohiddenmnt_index(sb, bindex); + + hidden_path = + d_path(&tp, (char *)tmp, PAGE_SIZE); + perms = branchperms(sb, bindex); + seq_printf(m, "%s=%s", hidden_path, + perms & MAY_WRITE ? "rw" : + perms & MAY_NFSRO ? "nfsro" : "ro"); + if (bindex != bend) { + seq_printf(m, ":"); + } + } + + seq_printf(m, ",debug=%u", get_debug_mask()); + +#ifdef UNIONFS_DELETE_ALL + if (IS_SET(sb, DELETE_ALL)) + seq_printf(m, ",delete=all"); + else +#endif + seq_printf(m, ",delete=whiteout"); + out: + if (tmp) + free_page(tmp); + unlock_dentry(sb->s_root); + return ret; +} + +#ifdef CONFIG_EXPORTFS +/* + * export operations. + * unionfs cannot handle disconnected dentry, since it has no hidden dentries. + */ +/* un-tested 64 bit environment (pointer and inode number) */ + +#define is_anon(d) ((d)->d_flags & DCACHE_DISCONNECTED) +extern struct export_operations export_op_default; + +static void prepend_path(char **path, const char *name, int len) +{ + *path -= len; + memcpy(*path, name, len); + (*path)--; + **path = '/'; +} + +struct filldir_arg { + int found, called; + char *path; + ino_t ino, parent_ino; +}; + +static int filldir(void *arg, const char *name, int len, loff_t pos, ino_t ino, + unsigned int d_type) +{ + struct filldir_arg *a = arg; + + a->called++; + if (len == 2 && !strncmp(name, "..", 2)) { + a->parent_ino = ino; + a->found++; + } else if (ino == a->ino) { + if (len != 1 || *name != '.') + prepend_path(&a->path, name, len); + a->found++; + } + return (a->found == 2) ? 1 : 0; +} + +static struct dentry *get_hidden_parent(struct super_block *hidden_sb, + ino_t hidden_parent_ino) +{ + __u32 fh[2]; + + if (hidden_sb->s_root->d_inode->i_ino == hidden_parent_ino) + return DGET(hidden_sb->s_root); + + fh[0] = hidden_parent_ino; + fh[1] = 0; + return export_op_default.get_dentry(hidden_sb, fh); +} + +static struct dentry *do_get_dentry(struct super_block *sb, ino_t ino, + __u32 gen, struct dentry *hidden_root, + ino_t hidden_ino, ino_t hidden_parent_ino) +{ + struct dentry *dentry, *hidden_parent, *parent; + char *path, *p; + struct filldir_arg arg = { + .ino = hidden_ino, + .parent_ino = hidden_parent_ino + }; + int open_flags, err, bindex, bend, found; + struct file *hidden_file; + struct super_block *hidden_sb; + + print_entry("hr%p, hi%lu, hpi%lu", + hidden_root, hidden_ino, hidden_parent_ino); + + dentry = ERR_PTR(-ENOMEM); + path = __getname(); + if (!path) + goto out; + arg.path = path + PATH_MAX - 1; + *arg.path = 0; + + open_flags = O_RDONLY | O_DIRECTORY /* | O_NOATIME */ ; + if (force_o_largefile()) + open_flags |= O_LARGEFILE; + + dentry = ERR_PTR(-ESTALE); + unionfs_read_lock(sb); + lock_dentry(sb->s_root); + bend = dbend(sb->s_root); + found = -1; + for (bindex = 0; found == -1 && bindex <= bend; bindex++) + if (hidden_root == dtohd_index(sb->s_root, bindex)) + found = bindex; + unlock_dentry(sb->s_root); + if (found == -1) + goto out_unlock; + + bindex = found; + hidden_sb = stohs_index(sb, bindex); + while (1) { + hidden_parent = get_hidden_parent(hidden_sb, hidden_parent_ino); + dentry = hidden_parent; + if (IS_ERR(hidden_parent)) + goto out_unlock; + + branchget(sb, bindex); + hidden_file = DENTRY_OPEN(DGET(hidden_parent), NULL, + open_flags); + if (IS_ERR(hidden_file)) { + dentry = (void *)hidden_file; + DPUT(hidden_parent); + branchput(sb, bindex); + goto out_unlock; + } + + arg.found = 0; + while (arg.found != 2) { + arg.called = 0; + err = vfs_readdir(hidden_file, filldir, &arg); + if (!arg.called || err < 0) + break; + } + fput(hidden_file); + branchput(sb, bindex); + if (arg.found != 2) { + dentry = ERR_PTR(-ESTALE); + DPUT(hidden_parent); + goto out_unlock; + } + + DPUT(hidden_parent); + if (hidden_parent_ino == hidden_root->d_inode->i_ino) + break; + arg.ino = hidden_parent_ino; + hidden_parent_ino = arg.parent_ino; + } + BUG_ON(arg.path < path); + + parent = DGET(sb->s_root); + p = strchr(++arg.path, '/'); + while (p) { + mutex_lock(&parent->d_inode->i_mutex); + dentry = LOOKUP_ONE_LEN(arg.path, parent, p - arg.path); + mutex_unlock(&parent->d_inode->i_mutex); + DPUT(parent); + if (IS_ERR(dentry)) + goto out_unlock; + if (!dentry->d_inode || !S_ISDIR(dentry->d_inode->i_mode)) { + DPUT(dentry); + dentry = ERR_PTR(-ESTALE); + goto out_unlock; + } + parent = dentry; + arg.path = p + 1; + p = strchr(arg.path, '/'); + } + mutex_lock(&parent->d_inode->i_mutex); + dentry = LOOKUP_ONE_LEN(arg.path, parent, strlen(arg.path)); + mutex_unlock(&parent->d_inode->i_mutex); + DPUT(parent); + if (!IS_ERR(dentry) + && (!dentry->d_inode + || dentry->d_inode->i_ino != ino + || dentry->d_inode->i_generation != gen)) { + DPUT(dentry); + dentry = ERR_PTR(-ESTALE); + } + + out_unlock: + unionfs_read_unlock(sb); + __putname(path); + out: + print_exit_pointer(dentry); + return dentry; +} + +enum { + FhHead = 4, FhHRoot1 = FhHead, FhHRoot2, + FhHIno1, FhHIno2, FhHPIno1, FhHPIno2, + FhTail +}; + +static void do_decode(__u32 * fh, struct dentry **hidden_root, + ino_t * hidden_ino, ino_t * hidden_parent_ino) +{ + unsigned long root; + + root = fh[FhHRoot2]; + *hidden_ino = fh[FhHIno2]; + *hidden_parent_ino = fh[FhHPIno2]; +#if BITS_PER_LONG == 64 + root |= ((unsigned long)fh[FhHRoot1]) << 32; + *hidden_ino |= ((unsigned long) fh[FhHIno1]) << 32; + *hidden_parent_ino |= ((unsigned long) fh[FhHPIno1]) << 32; +#elif BITS_PER_LONG == 32 + /* ok */ +#else +#error unknown size +#endif + + *hidden_root = (struct dentry*) root; +} + +static int unionfs_encode_fh(struct dentry *dentry, __u32 * fh, int *max_len, + int connectable) +{ + int type, len, bindex; + struct super_block *sb; + struct dentry *h_root; + ino_t h_ino, hp_ino; + static int warn; + + print_entry("dentry %p", dentry); + BUG_ON(is_anon(dentry) || !dentry->d_inode + || is_anon(dentry->d_parent)); + +#ifdef UNIONFS_IMAP + if (!warn && stopd(dentry->d_sb)->usi_persistent) + warn++; +#endif + if (!warn) { + printk(KERN_WARNING "Exporting Unionfs without imap" + " option may stop your NFS server or client"); + warn++; + } + + sb = dentry->d_sb; + unionfs_read_lock(sb); + lock_dentry(dentry); + + len = *max_len; + type = export_op_default.encode_fh(dentry, fh, max_len, connectable); + if (type == 255 || *max_len > FhHead || len < FhTail) { + type = 255; + goto out; + } + + *max_len = FhTail; + bindex = dbstart(dentry); + lock_dentry(sb->s_root); + h_root = dtohd_index(sb->s_root, bindex); + unlock_dentry(sb->s_root); + h_ino = itohi_index(dentry->d_inode, bindex)->i_ino; + hp_ino = parent_ino(dtohd(dentry)); + fh[FhHRoot2] = (unsigned long) h_root; + fh[FhHIno2] = h_ino; + fh[FhHPIno2] = hp_ino; +#if BITS_PER_LONG == 64 + fh[FhHRoot1] = ((unsigned long) h_root) >> 32; + fh[FhHIno1] = h_ino >> 32; + fh[FhHPIno1] = hp_ino >> 32; +#endif + + out: + unionfs_print(PRINT_MAIN_EXIT, "%d, fh{i%u, g%d, hr%x, hi%u, hpi%u}\n", + type, fh[0], fh[1], fh[FhHRoot2], fh[FhHIno2], + fh[FhHPIno2]); + unlock_dentry(dentry); + unionfs_read_unlock(sb); + return type; +} + +static struct dentry *unionfs_decode_fh(struct super_block *sb, __u32 * fh, + int fh_len, int fh_type, + int (*acceptable) (void *context, + struct dentry * de), + void *context) +{ + struct dentry *dentry, *hidden_root; + ino_t hidden_ino, hidden_parent_ino; + + print_entry("%d, fh{i%u, g%d, hr%x, hi%u, hpi%u}", + fh_type, fh[0], fh[1], fh[FhHRoot2], fh[FhHIno2], + fh[FhHPIno2]); + + dentry = export_op_default.get_dentry(sb, fh); + if (!dentry || IS_ERR(dentry) || (dentry->d_inode && !is_anon(dentry))) + return dentry; + + d_drop(dentry); + DPUT(dentry); + do_decode(fh, &hidden_root, &hidden_ino, &hidden_parent_ino); + dentry = do_get_dentry(sb, fh[0], fh[1], hidden_root, hidden_ino, + hidden_parent_ino); + if (!IS_ERR(dentry)) { + if (acceptable(context, dentry)) + return dentry; /* success */ + DPUT(dentry); + dentry = NULL; + } + return dentry; +} + +struct export_operations unionfs_export_ops = { + .decode_fh = unionfs_decode_fh, + .encode_fh = unionfs_encode_fh +}; +#endif + +struct super_operations unionfs_sops = { + //.put_inode = unionfs_put_inode, + .delete_inode = unionfs_delete_inode, + .put_super = unionfs_put_super, + .statfs = unionfs_statfs, + .remount_fs = unionfs_remount_fs, + .clear_inode = unionfs_clear_inode, + .umount_begin = unionfs_umount_begin, + .show_options = unionfs_show_options, + .write_inode = unionfs_write_inode, + .alloc_inode = unionfs_alloc_inode, + .destroy_inode = unionfs_destroy_inode, +}; + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/branchman.c +++ linux-2.6.28/ubuntu/unionfs/branchman.c @@ -0,0 +1,579 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: branchman.c,v 1.66 2006/10/31 00:05:22 yiannos Exp $ + */ + +#include "unionfs.h" + +struct dentry **alloc_new_dentries(int objs) +{ + if (!objs) + return NULL; + + return KZALLOC(sizeof(struct dentry *) * objs, GFP_KERNEL); +} + +struct unionfs_usi_data *alloc_new_data(int objs) +{ + if (!objs) + return NULL; + + return KZALLOC(sizeof(struct unionfs_usi_data) * objs, GFP_KERNEL); +} + +static void fixputmaps(struct super_block *sb) +{ + struct unionfs_sb_info *spd; + struct putmap *cur; + int gen; + int i; + + print_entry_location(); + + spd = stopd(sb); + cur = spd->usi_putmaps[spd->usi_lastputmap - spd->usi_firstputmap]; + + for (gen = 0; gen < spd->usi_lastputmap - spd->usi_firstputmap; gen++) { + if (!spd->usi_putmaps[gen]) + continue; + for (i = 0; i <= spd->usi_putmaps[gen]->bend; i++) + spd->usi_putmaps[gen]->map[i] = + cur->map[spd->usi_putmaps[gen]->map[i]]; + } + + print_exit_location(); +} + +static int newputmap(struct super_block *sb) +{ + struct unionfs_sb_info *spd; + struct putmap *newmap; + int count = 0; + int i; + + print_entry_location(); + + spd = stopd(sb); + + i = sizeof(int) * (sbend(sb) + 1); + newmap = KMALLOC(sizeof(struct putmap) + i, GFP_KERNEL); + if (!newmap) { + print_exit_status(-ENOMEM); + return -ENOMEM; + } + + if (!spd->usi_firstputmap) { + spd->usi_firstputmap = 1; + spd->usi_lastputmap = 1; + + spd->usi_putmaps = KMALLOC(sizeof(struct putmap *), GFP_KERNEL); + if (!spd->usi_putmaps) { + KFREE(newmap); + print_exit_status(-ENOMEM); + return -ENOMEM; + } + } else { + struct putmap **newlist; + int newfirst = spd->usi_firstputmap; + + while (!spd->usi_putmaps[newfirst - spd->usi_firstputmap] && + newfirst <= spd->usi_lastputmap) { + newfirst++; + } + + newlist = + KMALLOC(sizeof(struct putmap *) * + (1 + spd->usi_lastputmap - newfirst), GFP_KERNEL); + if (!newlist) { + KFREE(newmap); + print_exit_status(-ENOMEM); + return -ENOMEM; + } + + for (i = newfirst; i <= spd->usi_lastputmap; i++) { + newlist[i - newfirst] = + spd->usi_putmaps[i - spd->usi_firstputmap]; + } + + KFREE(spd->usi_putmaps); + spd->usi_putmaps = newlist; + spd->usi_firstputmap = newfirst; + spd->usi_lastputmap++; + } + + newmap->bend = sbend(sb); + for (i = 0; i <= sbend(sb); i++) { + count += branch_count(sb, i); + newmap->map[i] = i; + } + for (i = spd->usi_firstputmap; i < spd->usi_lastputmap; i++) { + struct putmap *cur; + cur = spd->usi_putmaps[i - spd->usi_firstputmap]; + if (!cur) + continue; + count -= atomic_read(&cur->count); + } + atomic_set(&newmap->count, count); + spd->usi_putmaps[spd->usi_lastputmap - spd->usi_firstputmap] = newmap; + + print_exit_status(0); + return 0; +} + +/* XXX: this function needs to go. There is no reason for this to be here */ +int unionfs_ioctl_branchcount(struct file *file, unsigned int cmd, + unsigned long arg) +{ + int err = 0; + int bstart, bend; + int i; + struct super_block *sb = file->f_dentry->d_sb; + + print_entry_location(); + + bstart = sbstart(sb); + bend = sbend(sb); + + err = bend + 1; + if (!arg) + goto out; + + for (i = bstart; i <= bend; i++) { + if (put_user(branch_count(sb, i), ((int __user *)arg) + i)) { + err = -EFAULT; + goto out; + } + } + + out: + print_exit_status(err); + return err; +} + +int unionfs_ioctl_incgen(struct file *file, unsigned int cmd, unsigned long arg) +{ + int err = 0; + struct super_block *sb; + + print_entry_location(); + + sb = file->f_dentry->d_sb; + + unionfs_write_lock(sb); + if ((err = newputmap(sb))) + goto out; + + atomic_inc(&stopd(sb)->usi_generation); + err = atomic_read(&stopd(sb)->usi_generation); + + atomic_set(&dtopd(sb->s_root)->udi_generation, err); + atomic_set(&itopd(sb->s_root->d_inode)->uii_generation, err); + + out: + unionfs_write_unlock(sb); + print_exit_status(err); + return err; +} + +int unionfs_ioctl_addbranch(struct inode *inode, unsigned int cmd, + unsigned long arg) +{ + int err; + struct unionfs_addbranch_args *addargs = NULL; + struct nameidata nd; + char *path = NULL; + int gen; + int i; + + int pobjects; + + struct unionfs_usi_data *new_data = NULL; + struct dentry **new_udi_dentry = NULL; + struct inode **new_uii_inode = NULL; + + struct dentry *root = NULL; + struct dentry *hidden_root = NULL; + + print_entry_location(); + +#ifdef UNIONFS_IMAP + if (stopd(sb)->usi_persistent) { + printk(KERN_ERR "Cannot manipulate branches if imap is used\n"); + err = -EPERM; + goto out; + } +#endif + + err = -ENOMEM; + addargs = KMALLOC(sizeof(struct unionfs_addbranch_args), GFP_KERNEL); + if (!addargs) + goto out; + + err = -EFAULT; + if (copy_from_user + (addargs, (const void __user *)arg, + sizeof(struct unionfs_addbranch_args))) + goto out; + + err = -EINVAL; + if (addargs->ab_perms & ~(MAY_READ | MAY_WRITE | MAY_NFSRO)) + goto out; + if (!(addargs->ab_perms & MAY_READ)) + goto out; + + err = -E2BIG; + if (sbend(inode->i_sb) > FD_SETSIZE) + goto out; + + err = -ENOMEM; + if (!(path = getname((const char __user *)addargs->ab_path))) + goto out; + + err = path_lookup(path, LOOKUP_FOLLOW, &nd); + + RECORD_PATH_LOOKUP(&nd); + if (err) + goto out; + if ((err = check_branch(&nd))) { + path_put(&nd.path); + RECORD_PATH_RELEASE(&nd); + goto out; + } + + unionfs_write_lock(inode->i_sb); + lock_dentry(inode->i_sb->s_root); + + root = inode->i_sb->s_root; + for (i = dbstart(inode->i_sb->s_root); i <= dbend(inode->i_sb->s_root); + i++) { + hidden_root = dtohd_index(root, i); + if (is_branch_overlap(hidden_root, nd.path.dentry)) { + err = -EINVAL; + goto out; + } + } + + err = -EINVAL; + if (addargs->ab_branch < 0 + || (addargs->ab_branch > (sbend(inode->i_sb) + 1))) + goto out; + + if ((err = newputmap(inode->i_sb))) + goto out; + + stopd(inode->i_sb)->b_end++; + dtopd(inode->i_sb->s_root)->udi_bcount++; + set_dbend(inode->i_sb->s_root, dbend(inode->i_sb->s_root) + 1); + itopd(inode->i_sb->s_root->d_inode)->b_end++; + + atomic_inc(&stopd(inode->i_sb)->usi_generation); + gen = atomic_read(&stopd(inode->i_sb)->usi_generation); + + pobjects = sbend(inode->i_sb) + 1; + + /* Reallocate the dynamic structures. */ + new_data = alloc_new_data(pobjects); + new_udi_dentry = alloc_new_dentries(pobjects); + new_uii_inode = KZALLOC(sizeof(struct inode *) * pobjects, GFP_KERNEL); + + if (!new_udi_dentry || !new_uii_inode || !new_data) { + err = -ENOMEM; + goto out; + } + + /* Copy the in-place values to our new structure. */ + for (i = 0; i < addargs->ab_branch; i++) { + atomic_set(&(new_data[i].sbcount), + branch_count(inode->i_sb, i)); + + new_data[i].branchperms = branchperms(inode->i_sb, i); + new_data[i].hidden_mnt = stohiddenmnt_index(inode->i_sb, i); + new_data[i].sb = stohs_index(inode->i_sb, i); + + new_udi_dentry[i] = dtohd_index(inode->i_sb->s_root, i); + new_uii_inode[i] = itohi_index(inode->i_sb->s_root->d_inode, i); + } + + /* Shift the ends to the right (only handle reallocated bits). */ + for (i = sbend(inode->i_sb) - 1; i >= (int)addargs->ab_branch; i--) { + int j = i + 1; + int pmindex; + + atomic_set(&new_data[j].sbcount, branch_count(inode->i_sb, i)); + + new_data[j].branchperms = branchperms(inode->i_sb, i); + new_data[j].hidden_mnt = stohiddenmnt_index(inode->i_sb, i); + new_data[j].sb = stohs_index(inode->i_sb, i); + new_udi_dentry[j] = dtohd_index(inode->i_sb->s_root, i); + new_uii_inode[j] = itohi_index(inode->i_sb->s_root->d_inode, i); + + /* Update the newest putmap, so it is correct for later. */ + pmindex = stopd(inode->i_sb)->usi_lastputmap; + pmindex -= stopd(inode->i_sb)->usi_firstputmap; + stopd(inode->i_sb)->usi_putmaps[pmindex]->map[i] = j; + + } + + /* Now we can free the old ones. */ + KFREE(dtopd(inode->i_sb->s_root)->udi_dentry); + KFREE(itopd(inode->i_sb->s_root->d_inode)->uii_inode); + KFREE(stopd(inode->i_sb)->usi_data); + + /* Update the real pointers. */ + dtohd_ptr(inode->i_sb->s_root) = new_udi_dentry; + itohi_ptr(inode->i_sb->s_root->d_inode) = new_uii_inode; + stopd(inode->i_sb)->usi_data = new_data; + + /* Re-NULL the new ones so we don't try to free them. */ + new_data = NULL; + new_udi_dentry = NULL; + new_uii_inode = NULL; + + /* Put the new dentry information into it's slot. */ + set_dtohd_index(inode->i_sb->s_root, addargs->ab_branch, nd.path.dentry); + set_itohi_index(inode->i_sb->s_root->d_inode, addargs->ab_branch, + IGRAB(nd.path.dentry->d_inode)); + set_branchperms(inode->i_sb, addargs->ab_branch, addargs->ab_perms); + set_branch_count(inode->i_sb, addargs->ab_branch, 0); + set_stohiddenmnt_index(inode->i_sb, addargs->ab_branch, nd.path.mnt); + set_stohs_index(inode->i_sb, addargs->ab_branch, nd.path.dentry->d_sb); + + atomic_set(&dtopd(inode->i_sb->s_root)->udi_generation, gen); + atomic_set(&itopd(inode->i_sb->s_root->d_inode)->uii_generation, gen); + + fixputmaps(inode->i_sb); + + out: + unlock_dentry(inode->i_sb->s_root); + unionfs_write_unlock(inode->i_sb); + + KFREE(new_udi_dentry); + KFREE(new_uii_inode); + KFREE(new_data); + KFREE(addargs); + if (path) + putname(path); + + print_exit_status(err); + + return err; +} + +/* This must be called with the super block already locked. */ +int unionfs_ioctl_delbranch(struct super_block *sb, unsigned long arg) +{ + struct dentry *hidden_dentry; + struct inode *hidden_inode; + struct vfsmount *hidden_mnt; + struct dentry *root_dentry; + struct inode *root_inode; + int err = 0; + int pmindex, i, gen; + + print_entry("branch = %lu ", arg); + lock_dentry(sb->s_root); + +#ifdef UNIONFS_IMAP + if (stopd(sb)->usi_persistent) { + printk(KERN_ERR "Cannot manipulate branches if imap is used\n"); + err = -EPERM; + goto out; + } +#endif + err = -EBUSY; + if (sbmax(sb) == 1) + goto out; + err = -EINVAL; + if (arg < 0 || arg > stopd(sb)->b_end) + goto out; + err = -EBUSY; + if (branch_count(sb, arg)) + goto out; + if ((err = newputmap(sb))) + goto out; + + pmindex = stopd(sb)->usi_lastputmap; + pmindex -= stopd(sb)->usi_firstputmap; + + atomic_inc(&stopd(sb)->usi_generation); + gen = atomic_read(&stopd(sb)->usi_generation); + + root_dentry = sb->s_root; + root_inode = sb->s_root->d_inode; + + hidden_dentry = dtohd_index(root_dentry, arg); + hidden_mnt = stohiddenmnt_index(sb, arg); + hidden_inode = itohi_index(root_inode, arg); + + DPUT(hidden_dentry); + IPUT(hidden_inode); + mntput(hidden_mnt); + + for (i = arg; i <= (sbend(sb) - 1); i++) { + set_branch_count(sb, i, branch_count(sb, i + 1)); + set_stohiddenmnt_index(sb, i, stohiddenmnt_index(sb, i + 1)); + set_stohs_index(sb, i, stohs_index(sb, i + 1)); + set_branchperms(sb, i, branchperms(sb, i + 1)); + set_dtohd_index(root_dentry, i, + dtohd_index(root_dentry, i + 1)); + set_itohi_index(root_inode, i, itohi_index(root_inode, i + 1)); + stopd(sb)->usi_putmaps[pmindex]->map[i + 1] = i; + } + + set_dtohd_index(root_dentry, sbend(sb), NULL); + set_itohi_index(root_inode, sbend(sb), NULL); + set_stohiddenmnt_index(sb, sbend(sb), NULL); + set_stohs_index(sb, sbend(sb), NULL); + + //XXX: Place check for inode maps and removal of branch here + + stopd(sb)->b_end--; + set_dbend(root_dentry, dbend(root_dentry) - 1); + dtopd(root_dentry)->udi_bcount--; + itopd(root_inode)->b_end--; + + atomic_set(&dtopd(root_dentry)->udi_generation, gen); + atomic_set(&itopd(root_inode)->uii_generation, gen); + + fixputmaps(sb); + + /* This doesn't open a file, so we might have to free the map here. */ + if (atomic_read(&stopd(sb)->usi_putmaps[pmindex]->count) == 0) { + KFREE(stopd(sb)->usi_putmaps[pmindex]); + stopd(sb)->usi_putmaps[pmindex] = NULL; + } + + out: + unlock_dentry(sb->s_root); + print_exit_status(err); + + return err; +} + +int unionfs_ioctl_rdwrbranch(struct inode *inode, unsigned int cmd, + unsigned long arg) +{ + int err; + struct unionfs_rdwrbranch_args *rdwrargs = NULL; + int gen; + + print_entry_location(); + + unionfs_write_lock(inode->i_sb); + lock_dentry(inode->i_sb->s_root); + + if ((err = newputmap(inode->i_sb))) + goto out; + + err = -ENOMEM; + rdwrargs = KMALLOC(sizeof(struct unionfs_rdwrbranch_args), GFP_KERNEL); + if (!rdwrargs) + goto out; + + err = -EFAULT; + if (copy_from_user + (rdwrargs, (const void __user *)arg, + sizeof(struct unionfs_rdwrbranch_args))) + goto out; + + err = -EINVAL; + if (rdwrargs->rwb_branch < 0 + || (rdwrargs->rwb_branch > (sbend(inode->i_sb) + 1))) + goto out; + if (rdwrargs->rwb_perms & ~(MAY_READ | MAY_WRITE | MAY_NFSRO)) + goto out; + if (!(rdwrargs->rwb_perms & MAY_READ)) + goto out; + + set_branchperms(inode->i_sb, rdwrargs->rwb_branch, rdwrargs->rwb_perms); + + atomic_inc(&stopd(inode->i_sb)->usi_generation); + gen = atomic_read(&stopd(inode->i_sb)->usi_generation); + atomic_set(&dtopd(inode->i_sb->s_root)->udi_generation, gen); + atomic_set(&itopd(inode->i_sb->s_root->d_inode)->uii_generation, gen); + + err = 0; + + out: + unlock_dentry(inode->i_sb->s_root); + unionfs_write_unlock(inode->i_sb); + KFREE(rdwrargs); + + print_exit_status(err); + + return err; +} + +int unionfs_ioctl_queryfile(struct file *file, unsigned int cmd, + unsigned long arg) +{ + int err = 0; + fd_set branchlist; + + int bstart = 0, bend = 0, bindex = 0; + struct dentry *dentry, *hidden_dentry; + + print_entry_location(); + + dentry = file->f_dentry; + lock_dentry(dentry); + if ((err = unionfs_partial_lookup(dentry))) + goto out; + bstart = dbstart(dentry); + bend = dbend(dentry); + + FD_ZERO(&branchlist); + + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) + continue; + if (hidden_dentry->d_inode) + FD_SET(bindex, &branchlist); + } + + err = copy_to_user((void __user *)arg, &branchlist, sizeof(fd_set)); + if (err) { + err = -EFAULT; + goto out; + } + + out: + unlock_dentry(dentry); + err = err < 0 ? err : bend; + print_exit_status(err); + return (err); +} + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/BOM +++ linux-2.6.28/ubuntu/unionfs/BOM @@ -0,0 +1,7 @@ +Downloaded from: http://www.filesystems.org/project-unionfs.html +Current Version: 1.4 + +Don't bother updating this code. No, we do not want 2.3.x. Yes, this is +heavily patched to account for upstream VFS API changes and AppArmor. + +DO NOT TOUCH :) --- linux-2.6.28.orig/ubuntu/unionfs/main.c +++ linux-2.6.28/ubuntu/unionfs/main.c @@ -0,0 +1,869 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: main.c,v 1.176 2006/10/10 07:28:13 jsipek Exp $ + */ + +#include "unionfs.h" +#include +#include + +/* declarations added for "sparse" */ +extern void unionfs_kill_block_super(struct super_block *sb); + +/* declarations added for malloc_debugging */ + +#ifdef FIST_MALLOC_DEBUG +extern atomic_t unionfs_malloc_counter; +extern atomic_t unionfs_mallocs_outstanding; +#endif + +extern void unionfs_read_inode(struct inode *inode); + +static struct inode *unionfs_iget(struct super_block *sb, ino_t ino) +{ + struct inode *inode; + + inode = iget_locked(sb, ino); + if (!inode) + return ERR_PTR(-ENOMEM); + if (inode->i_state & I_NEW) { + unionfs_read_inode(inode); + unlock_new_inode(inode); + } + return inode; +} + +/* sb we pass is unionfs's super_block */ +int unionfs_interpose(struct dentry *dentry, struct super_block *sb, int flag) +{ + struct inode *hidden_inode; + struct dentry *hidden_dentry; + int err = 0; + struct inode *inode; + int is_negative_dentry = 1; + int bindex, bstart, bend; + + print_entry("flag = %d", flag); + + verify_locked(dentry); + + print_dentry("In unionfs_interpose", dentry); + + bstart = dbstart(dentry); + bend = dbend(dentry); + + /* Make sure that we didn't get a negative dentry. */ + for (bindex = bstart; bindex <= bend; bindex++) { + if (dtohd_index(dentry, bindex) && + dtohd_index(dentry, bindex)->d_inode) { + is_negative_dentry = 0; + break; + } + } + BUG_ON(is_negative_dentry); + + /* We allocate our new inode below, by calling iget. + * iget will call our read_inode which will initialize some + * of the new inode's fields + */ + + /* On revalidate we've already got our own inode and just need + * to fix it up. */ + if (flag == INTERPOSE_REVAL) { + inode = dentry->d_inode; + itopd(inode)->b_start = -1; + itopd(inode)->b_end = -1; + atomic_set(&itopd(inode)->uii_generation, + atomic_read(&stopd(sb)->usi_generation)); + + itohi_ptr(inode) = + KZALLOC(sbmax(sb) * sizeof(struct inode *), GFP_KERNEL); + if (!itohi_ptr(inode)) { + err = -ENOMEM; + goto out; + } + mutex_lock(&inode->i_mutex); + } else { + ino_t ino; + /* get unique inode number for unionfs */ +#ifdef UNIONFS_IMAP + if (stopd(sb)->usi_persistent) { + err = read_uin(sb, bindex, + dtohd_index(dentry, + bindex)->d_inode->i_ino, + O_CREAT, &ino); + if (err) + goto out; + } else +#endif + ino = iunique(sb, UNIONFS_ROOT_INO); + + inode = unionfs_iget(sb, ino); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); + goto out; + } + + mutex_lock(&inode->i_mutex); + if (atomic_read(&inode->i_count) > 1) + goto skip; + } + + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) { + set_itohi_index(inode, bindex, NULL); + continue; + } + /* Initialize the hidden inode to the new hidden inode. */ + if (!hidden_dentry->d_inode) + continue; + set_itohi_index(inode, bindex, IGRAB(hidden_dentry->d_inode)); + } + + ibstart(inode) = dbstart(dentry); + ibend(inode) = dbend(dentry); + + /* Use attributes from the first branch. */ + hidden_inode = itohi(inode); + + /* Use different set of inode ops for symlinks & directories */ + if (S_ISLNK(hidden_inode->i_mode)) + inode->i_op = &unionfs_symlink_iops; + else if (S_ISDIR(hidden_inode->i_mode)) + inode->i_op = &unionfs_dir_iops; + + /* Use different set of file ops for directories */ + if (S_ISDIR(hidden_inode->i_mode)) + inode->i_fop = &unionfs_dir_fops; + + /* properly initialize special inodes */ + if (S_ISBLK(hidden_inode->i_mode) || S_ISCHR(hidden_inode->i_mode) || + S_ISFIFO(hidden_inode->i_mode) || S_ISSOCK(hidden_inode->i_mode)) + init_special_inode(inode, hidden_inode->i_mode, + hidden_inode->i_rdev); +#ifndef UNIONFS_MMAP + /* Fix our inode's address operations to that of the lower inode (Unionfs is FiST-Lite) */ + if (inode->i_mapping->a_ops != hidden_inode->i_mapping->a_ops) { + dprint(PRINT_DEBUG, "fixing inode 0x%p a_ops (0x%p -> 0x%p)\n", + inode, inode->i_mapping->a_ops, + hidden_inode->i_mapping->a_ops); + inode->i_mapping->a_ops = hidden_inode->i_mapping->a_ops; + } +#endif + /* all well, copy inode attributes */ + fist_copy_attr_all(inode, hidden_inode); + + skip: + /* only (our) lookup wants to do a d_add */ + switch (flag) { + case INTERPOSE_DEFAULT: + case INTERPOSE_REVAL_NEG: + d_instantiate(dentry, inode); + break; + case INTERPOSE_LOOKUP: + err = PTR_ERR(d_splice_alias(inode, dentry)); + break; + case INTERPOSE_REVAL: + /* Do nothing. */ + break; + default: + printk(KERN_ERR "Invalid interpose flag passed!"); + BUG(); + } + + print_dentry("Leaving unionfs_interpose", dentry); + print_inode("Leaving unionfs_interpose", inode); + mutex_unlock(&inode->i_mutex); + + out: + print_exit_status(err); + return err; +} + +void unionfs_reinterpose(struct dentry *dentry) +{ + struct dentry *hidden_dentry; + struct inode *inode; + int bindex, bstart, bend; + + print_entry_location(); + verify_locked(dentry); + print_dentry("IN: unionfs_reinterpose: ", dentry); + + /* This is pre-allocated inode */ + inode = dentry->d_inode; + + bstart = dbstart(dentry); + bend = dbend(dentry); + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) + continue; + + if (!hidden_dentry->d_inode) + continue; + if (itohi_index(inode, bindex)) + continue; + set_itohi_index(inode, bindex, IGRAB(hidden_dentry->d_inode)); + } + ibstart(inode) = dbstart(dentry); + ibend(inode) = dbend(dentry); + + print_dentry("OUT: unionfs_reinterpose: ", dentry); + print_inode("OUT: unionfs_reinterpose: ", inode); + + print_exit_location(); +} + +int check_branch(struct nameidata *nd) +{ + if (!strcmp(nd->path.dentry->d_sb->s_type->name, "unionfs")) + return -EINVAL; + if (!nd->path.dentry->d_inode) + return -ENOENT; + if (!S_ISDIR(nd->path.dentry->d_inode->i_mode)) + return -ENOTDIR; + return 0; +} + +/* checks if two hidden_dentries have overlapping branches */ +int is_branch_overlap(struct dentry *dent1, struct dentry *dent2) +{ + struct dentry *dent = NULL; + + dent = dent1; + while ((dent != dent2) && (dent->d_parent != dent)) { + dent = dent->d_parent; + } + if (dent == dent2) { + return 1; + } + + dent = dent2; + while ((dent != dent1) && (dent->d_parent != dent)) { + dent = dent->d_parent; + } + if (dent == dent1) { + return 1; + } + + return 0; +} +static int parse_branch_mode(char *name) +{ + int perms; + int l = strlen(name); + if (!strcmp(name + l - 3, "=ro")) { + perms = MAY_READ; + name[l - 3] = '\0'; + } else if (!strcmp(name + l - 6, "=nfsro")) { + perms = MAY_READ | MAY_NFSRO; + name[l - 6] = '\0'; + } else if (!strcmp(name + l - 3, "=rw")) { + perms = MAY_READ | MAY_WRITE; + name[l - 3] = '\0'; + } else { + perms = MAY_READ | MAY_WRITE; + } + + return perms; +} +static int get_separator_count(char *options, char *separator) +{ + char *token, *locopts, *locsep = NULL; + int count = 0; + /* + * We copy options so we dont destroy our pointer for parsing + */ + if (separator == NULL) { + locsep = KMALLOC(2, GFP_KERNEL); + if (!locsep) { + count = -ENOMEM; + goto out; + } + strcpy(locsep, ":"); + } else { + locsep = separator; + } + locopts = KMALLOC(strlen(options) + 1, GFP_KERNEL); + if (!locopts) { + count = -ENOMEM; + goto out; + } + strcpy(locopts, options); + while ((token = strsep(&locopts, locsep)) != NULL) + count++; + out: + KFREE(locopts); + return count; +} +static int parse_dirs_option(struct super_block *sb, struct unionfs_dentry_info + *hidden_root_info, char *options, char *separator) +{ + struct nameidata nd; + char *name, *locsep = NULL; + int err = 0; + int branches = 1; + int bindex = 0; + int i = 0; + int j = 0; + + struct dentry *dent1 = NULL; + struct dentry *dent2 = NULL; + + if (options[0] == '\0') { + printk(KERN_WARNING "unionfs: no branches specified\n"); + err = -EINVAL; + goto out; + } + /* + * Check to see if separator is specified otherwise use ':' + */ + if (separator == NULL) { + locsep = KMALLOC(2, GFP_KERNEL); + if (!locsep) { + err = -ENOMEM; + goto out; + } + strcpy(locsep, ":"); + } else { + locsep = separator; + } + branches = get_separator_count(options, separator); + /* allocate space for underlying pointers to hidden dentry */ + if (!(stopd(sb)->usi_data = alloc_new_data(branches))) { + err = -ENOMEM; + goto out; + } + + if (!(hidden_root_info->udi_dentry = alloc_new_dentries(branches))) { + err = -ENOMEM; + goto out; + } + + /* now parsing the string b1:b2=rw:b3=ro:b4 */ + branches = 0; + while ((name = strsep(&options, locsep)) != NULL) { + int perms; + + if (!*name) + continue; + branches++; + + /* strip off =rw or =ro if it is specified. */ + perms = parse_branch_mode(name); + if (!bindex && !(perms & MAY_WRITE)) { + err = -EINVAL; + goto out; + } + + dprint(PRINT_DEBUG, "using directory: %s (%c%c%c)\n", + name, perms & MAY_READ ? 'r' : '-', + perms & MAY_WRITE ? 'w' : '-', + perms & MAY_NFSRO ? 'n' : '-'); + + err = path_lookup(name, LOOKUP_FOLLOW, &nd); + RECORD_PATH_LOOKUP(&nd); + if (err) { + printk(KERN_WARNING "unionfs: error accessing " + "hidden directory '%s' (error %d)\n", name, err); + goto out; + } + + if ((err = check_branch(&nd))) { + printk(KERN_WARNING "unionfs: hidden directory " + "'%s' is not a valid branch\n", name); + path_put(&nd.path); + RECORD_PATH_RELEASE(&nd); + goto out; + } + + hidden_root_info->udi_dentry[bindex] = nd.path.dentry; + + set_stohiddenmnt_index(sb, bindex, nd.path.mnt); + set_branchperms(sb, bindex, perms); + set_branch_count(sb, bindex, 0); + + if (hidden_root_info->udi_bstart < 0) + hidden_root_info->udi_bstart = bindex; + hidden_root_info->udi_bend = bindex; + bindex++; + } + + if (branches == 0) { + printk(KERN_WARNING "unionfs: no branches specified\n"); + err = -EINVAL; + goto out; + } + + BUG_ON(branches != (hidden_root_info->udi_bend + 1)); + + /* ensure that no overlaps exist in the branches */ + for (i = 0; i < branches; i++) { + for (j = i + 1; j < branches; j++) { + dent1 = hidden_root_info->udi_dentry[i]; + dent2 = hidden_root_info->udi_dentry[j]; + + if (is_branch_overlap(dent1, dent2)) { + goto out_overlap; + } + } + } + + out_overlap: + + if (i != branches) { + printk(KERN_WARNING "unionfs: branches %d and %d overlap\n", i, + j); + err = -EINVAL; + goto out; + } + + out: + if (err) { + for (i = 0; i < branches; i++) { + if (hidden_root_info->udi_dentry[i]) + DPUT(hidden_root_info->udi_dentry[i]); + } + + KFREE(hidden_root_info->udi_dentry); + KFREE(stopd(sb)->usi_data); + + /* MUST clear the pointers to prevent potential double free if + * the caller dies later on + */ + hidden_root_info->udi_dentry = NULL; + stopd(sb)->usi_data = NULL; + } + if (!separator) + KFREE(locsep); + return err; +} + +/* + * Parse mount options. See the manual page for usage instructions. + * + * Returns the dentry object of the lower-level (hidden) directory; + * We want to mount our stackable file system on top of that hidden directory. + * + * Sets default debugging level to N, if any. + */ +static struct unionfs_dentry_info *unionfs_parse_options(struct super_block *sb, + char *options) +{ + struct unionfs_dentry_info *hidden_root_info; + char *optname, *separator = NULL; + int err = 0; + int bindex; + int sepfound = 0; + int dirsfound = 0; +#ifdef UNIONFS_IMAP + int imapfound = 0; +#endif + print_entry_location(); + + /* allocate private data area */ + err = -ENOMEM; + hidden_root_info = + KZALLOC(sizeof(struct unionfs_dentry_info), GFP_KERNEL); + if (!hidden_root_info) + goto out_error; + hidden_root_info->udi_bstart = -1; + hidden_root_info->udi_bend = -1; + hidden_root_info->udi_bopaque = -1; + + while ((optname = strsep(&options, ",")) != NULL) { + char *optarg; + char *endptr; + int intval; + + if (!*optname) { + continue; + } + + optarg = strchr(optname, '='); + if (optarg) { + *optarg++ = '\0'; + } + + /* All of our options take an argument now. Insert ones that + * don't, above this check. */ + if (!optarg) { + printk("unionfs: %s requires an argument.\n", optname); + err = -EINVAL; + goto out_error; + } + + if (!strcmp("dirs", optname)) { + if (++dirsfound > 1) { + printk(KERN_WARNING + "unionfs: multiple dirs specified\n"); + err = -EINVAL; + goto out_error; + } + err = + parse_dirs_option(sb, hidden_root_info, optarg, + separator); + if (err) + goto out_error; + continue; + } +#ifdef UNIONFS_IMAP + if (!strcmp("imap", optname)) { + if (++imapfound > 1) { + printk(KERN_WARNING + "unionfs: multiple imap specified\n"); + err = -EINVAL; + goto out_error; + } + err = parse_imap_option(sb, hidden_root_info, optarg); + if (err) + goto out_error; + continue; + } +#endif + if (!strcmp("delete", optname)) { + if (!strcmp("whiteout", optarg)) { + /* default */ +#ifdef UNIONFS_DELETE_ALL + } else if (!strcmp("all", optarg)) { + MOUNT_FLAG(sb) |= DELETE_ALL; +#endif + } else { + printk(KERN_WARNING + "unionfs: invalid delete option '%s'\n", + optarg); + err = -EINVAL; + goto out_error; + } + continue; + } + + if (!strcmp("separator", optname)) { + if (dirsfound) { + printk(KERN_WARNING + "unionfs: dirs= already parsed separator '%s' will have no effect\n", + optarg); + continue; + } + sepfound = 1; + separator = KMALLOC(strlen(optarg) + 1, GFP_KERNEL); + if (!separator) { + err = -ENOMEM; + goto out_error; + } + strcpy(separator, optarg); + continue; + } + /* All of these options require an integer argument. */ + intval = simple_strtoul(optarg, &endptr, 0); + if (*endptr) { + printk(KERN_WARNING + "unionfs: invalid %s option '%s'\n", + optname, optarg); + err = -EINVAL; + goto out_error; + } + + if (!strcmp("debug", optname)) { + set_debug_mask(intval); + continue; + } + + err = -EINVAL; + printk(KERN_WARNING + "unionfs: unrecognized option '%s'\n", optname); + goto out_error; + } + if (dirsfound != 1) { + printk(KERN_WARNING "unionfs: dirs option required\n"); + err = -EINVAL; + goto out_error; + } + goto out; + + out_error: + if (hidden_root_info && hidden_root_info->udi_dentry) { + for (bindex = hidden_root_info->udi_bstart; + bindex >= 0 && bindex <= hidden_root_info->udi_bend; + bindex++) { + struct dentry *d; + d = hidden_root_info->udi_dentry[bindex]; + DPUT(d); + if (stohiddenmnt_index(sb, bindex)) + mntput(stohiddenmnt_index(sb, bindex)); + } + } + + KFREE(hidden_root_info->udi_dentry); + KFREE(hidden_root_info); + + KFREE(stopd(sb)->usi_data); + stopd(sb)->usi_data = NULL; + + hidden_root_info = ERR_PTR(err); + KFREE(separator); + out: + print_exit_location(); + return hidden_root_info; +} + +static struct dentry *unionfs_d_alloc_root(struct super_block *sb) +{ + struct dentry *ret = NULL; + + if (sb) { + static const struct qstr name = {.name = "/",.len = 1 }; + + ret = d_alloc(NULL, &name); + if (ret) { + ret->d_op = &unionfs_dops; + ret->d_sb = sb; + ret->d_parent = ret; + } + } + return ret; +} + +static int unionfs_read_super(struct super_block *sb, void *raw_data, + int silent) +{ + int err = 0; + + struct unionfs_dentry_info *hidden_root_info = NULL; + int bindex, bstart, bend; + unsigned long long maxbytes; + + print_entry_location(); + + if (!raw_data) { + printk(KERN_WARNING + "unionfs_read_super: missing data argument\n"); + err = -EINVAL; + goto out; + } + + /* + * Allocate superblock private data + */ + stopd_lhs(sb) = KZALLOC(sizeof(struct unionfs_sb_info), GFP_KERNEL); + if (!stopd(sb)) { + printk(KERN_WARNING "%s: out of memory\n", __FUNCTION__); + err = -ENOMEM; + goto out; + } + stopd(sb)->b_end = -1; + atomic_set(&stopd(sb)->usi_generation, 1); + init_rwsem(&stopd(sb)->usi_rwsem); + + hidden_root_info = unionfs_parse_options(sb, raw_data); + if (IS_ERR(hidden_root_info)) { + printk(KERN_WARNING + "unionfs_read_super: error while parsing options (err = %ld)\n", + PTR_ERR(hidden_root_info)); + err = PTR_ERR(hidden_root_info); + hidden_root_info = NULL; + goto out_free; + } + if (hidden_root_info->udi_bstart == -1) { + err = -ENOENT; + goto out_free; + } + + /* set the hidden superblock field of upper superblock */ + bstart = hidden_root_info->udi_bstart; + BUG_ON(bstart != 0); + sbend(sb) = bend = hidden_root_info->udi_bend; + for (bindex = bstart; bindex <= bend; bindex++) { + struct dentry *d; + + d = hidden_root_info->udi_dentry[bindex]; + + set_stohs_index(sb, bindex, d->d_sb); + } + + /* Unionfs: Max Bytes is the maximum bytes from among all the branches */ + maxbytes = -1; + for (bindex = bstart; bindex <= bend; bindex++) + if (maxbytes < stohs_index(sb, bindex)->s_maxbytes) + maxbytes = stohs_index(sb, bindex)->s_maxbytes; + sb->s_maxbytes = maxbytes; + + sb->s_op = &unionfs_sops; +#ifdef CONFIG_EXPORTFS + sb->s_export_op = &unionfs_export_ops; +#endif + + /* + * we can't use d_alloc_root if we want to use + * our own interpose function unchanged, + * so we simply call our own "fake" d_alloc_root + */ + sb->s_root = unionfs_d_alloc_root(sb); + if (!sb->s_root) { + err = -ENOMEM; + goto out_dput; + } + + /* link the upper and lower dentries */ + dtopd_lhs(sb->s_root) = NULL; + if ((err = new_dentry_private_data(sb->s_root))) + goto out_freedpd; + + /* Set the hidden dentries for s_root */ + for (bindex = bstart; bindex <= bend; bindex++) { + struct dentry *d; + + d = hidden_root_info->udi_dentry[bindex]; + + set_dtohd_index(sb->s_root, bindex, d); + } + set_dbstart(sb->s_root, bstart); + set_dbend(sb->s_root, bend); + + /* Set the generation number to one, since this is for the mount. */ + atomic_set(&dtopd(sb->s_root)->udi_generation, 1); + + /* call interpose to create the upper level inode */ + if ((err = unionfs_interpose(sb->s_root, sb, 0))) + goto out_freedpd; + unlock_dentry(sb->s_root); + goto out; + + out_freedpd: + if (dtopd(sb->s_root)) { + KFREE(dtohd_ptr(sb->s_root)); + free_dentry_private_data(dtopd(sb->s_root)); + } + DPUT(sb->s_root); + out_dput: + if (hidden_root_info && !IS_ERR(hidden_root_info)) { + for (bindex = hidden_root_info->udi_bstart; + bindex <= hidden_root_info->udi_bend; bindex++) { + struct dentry *d; + + d = hidden_root_info->udi_dentry[bindex]; + + if (d) + DPUT(d); + + if (stopd(sb) && stohiddenmnt_index(sb, bindex)) + mntput(stohiddenmnt_index(sb, bindex)); + } + KFREE(hidden_root_info->udi_dentry); + KFREE(hidden_root_info); + hidden_root_info = NULL; + } + out_free: + KFREE(stopd(sb)->usi_data); + KFREE(stopd(sb)); + stopd_lhs(sb) = NULL; + out: + if (hidden_root_info && !IS_ERR(hidden_root_info)) { + KFREE(hidden_root_info->udi_dentry); + KFREE(hidden_root_info); + } + print_exit_status(err); + return err; +} + +static int unionfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, + void *raw_data, struct vfsmount *mnt) +{ + return get_sb_nodev(fs_type, flags, raw_data, unionfs_read_super, mnt); +} + +static struct file_system_type unionfs_fs_type = { + .owner = THIS_MODULE, + .name = "unionfs", + .get_sb = unionfs_get_sb, + .kill_sb = kill_anon_super, + .fs_flags = FS_REVAL_DOT, +}; + +static int init_debug = 0; +module_param_named(debug, init_debug, int, S_IRUGO); +MODULE_PARM_DESC(debug, "Initial Unionfs debug value."); + +static int __init init_unionfs_fs(void) +{ + int err; + printk("Registering unionfs " UNIONFS_VERSION "\n"); + + set_debug_mask(init_debug); + +#ifdef FIST_MALLOC_DEBUG + atomic_set(&unionfs_malloc_counter, 0); + atomic_set(&unionfs_mallocs_outstanding, 0); +#endif /* FIST_MALLOC_DEBUG */ + + if ((err = init_filldir_cache())) + goto out; + if ((err = init_inode_cache())) + goto out; + if ((err = init_dentry_cache())) + goto out; + if ((err = init_sioq())) + goto out; + err = register_filesystem(&unionfs_fs_type); + out: + if (err) { + fin_sioq(); + destroy_filldir_cache(); + destroy_inode_cache(); + destroy_dentry_cache(); + } + return err; +} +static void __exit exit_unionfs_fs(void) +{ + fin_sioq(); + destroy_filldir_cache(); + destroy_inode_cache(); + destroy_dentry_cache(); + unregister_filesystem(&unionfs_fs_type); + printk("Completed unionfs module unload.\n"); +} + +MODULE_AUTHOR + ("Filesystems and Storage Lab, Stony Brook University (http://www.fsl.cs.sunysb.edu/)"); +MODULE_DESCRIPTION("Unionfs " UNIONFS_VERSION + " (http://unionfs.filesystems.org/)"); +MODULE_LICENSE("GPL"); + +module_init(init_unionfs_fs); +module_exit(exit_unionfs_fs); +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/print.c +++ linux-2.6.28/ubuntu/unionfs/print.c @@ -0,0 +1,439 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef Sipek + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: print.c,v 1.77 2006/07/08 17:58:31 ezk Exp $ + */ + +/* Print debugging functions */ + +#include "unionfs.h" + +static unsigned int debug_mask = DEFAULT_DEBUG_MASK; + +/* get value of debugging variable */ +unsigned int get_debug_mask(void) +{ + return debug_mask; +} + +/* set debug level variable and return the previous value */ +int set_debug_mask(int val) +{ +#ifdef UNIONFS_DEBUG + int prev = debug_mask; + + debug_mask = val; + + printk(KERN_INFO UNIONFS_NAME ": debug mask set to %u\n", debug_mask); + + return prev; +#else /* UNIONFS_DEBUG */ + printk(KERN_WARNING UNIONFS_NAME ": debugging is not enabled\n"); + return -ENOTSUPP; +#endif /* ! UNIONFS_DEBUG */ +} + +static inline int should_print(const unsigned int req) +{ + return (req & debug_mask); +} + +static void unionfs_print_generic_inode(const char *prefix, + const char *prefix2, const struct inode *inode) +{ + if (!inode) { + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s%s: NULL INODE PASSED!\n", prefix, prefix2); + return; + } + + if (IS_ERR(inode)) { + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s%s: ERROR INODE PASSED: %ld\n", prefix, prefix2, + PTR_ERR(inode)); + return; + } + + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s%s: i_ino=%lu\n", + prefix, prefix2, inode->i_ino); + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s%s: i_count=%u\n", + prefix, prefix2, atomic_read(&inode->i_count)); + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s%s: i_nlink=%u\n", + prefix, prefix2, inode->i_nlink); + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s%s: i_mode=%o\n", + prefix, prefix2, inode->i_mode); + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s%s: i_size=%llu\n", + prefix, prefix2, inode->i_size); + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s%s: i_op=%p\n", + prefix, prefix2, inode->i_op); + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s%s: i_sb=%p (%s)\n", + prefix, prefix2, inode->i_sb, (inode->i_sb ? sbt(inode->i_sb) : "NullTypeSB")); +} + +void unionfs_print_inode(const unsigned int req, const char *prefix, const struct inode *inode) +{ + int bindex; + + if (!should_print(req)) + return; + + if (!inode) { + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s: NULL INODE PASSED!\n", prefix); + return; + } + if (IS_ERR(inode)) { + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s: ERROR INODE PASSED: %ld\n", prefix, PTR_ERR(inode)); + return; + } + + unionfs_print_generic_inode(prefix, "", inode); + + if (strcmp("unionfs", sbt(inode->i_sb))) { + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s: Not a " UNIONFS_NAME " inode.\n", prefix); + return; + } + + if (!itopd(inode)) + return; + + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s: ibstart=%d, ibend=%d\n", prefix, ibstart(inode), ibend(inode)); + + if (ibstart(inode) == -1) + return; + + for (bindex = ibstart(inode); bindex <= ibend(inode); bindex++) { + struct inode *hidden_inode = itohi_index(inode, bindex); + char newstr[10]; + if (!hidden_inode) { + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s: HI#%d: NULL\n", prefix, bindex); + continue; + } + snprintf(newstr, 10, ": HI%d", bindex); + unionfs_print_generic_inode(prefix, newstr, hidden_inode); + } +} + +static void unionfs_print_generic_file(const char *prefix, const char *prefix2, + const struct file *file) +{ + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s%s: f_dentry=0x%p\n", prefix, prefix2, file->f_dentry); + + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s%s: name=%s\n", prefix, prefix2, file->f_dentry->d_name.name); + if (file->f_dentry->d_inode) { + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s%s: f_dentry->d_inode->i_ino=%lu\n", prefix, prefix2, file->f_dentry->d_inode->i_ino); + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s%s: f_dentry->d_inode->i_mode=%o\n", prefix, prefix2, file->f_dentry->d_inode->i_mode); + } + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s%s: f_op=0x%p\n", prefix, prefix2, file->f_op); + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s%s: f_mode=0x%x\n", prefix, prefix2, file->f_mode); + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s%s: f_pos=0x%llu\n", prefix, prefix2, file->f_pos); + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s%s: f_count=%u\n", prefix, prefix2, atomic_read(&file->f_count)); + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s%s: f_flags=0x%x\n", prefix, prefix2, file->f_flags); + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s%s: f_version=%llu\n", prefix, prefix2, file->f_version); +} + +void unionfs_print_file(const unsigned int req, const char *prefix, const struct file *file) +{ + struct file *hidden_file; + + if (!should_print(req)) + return; + + if (!file) { + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s: NULL FILE PASSED!\n", prefix); + return; + } + + unionfs_print_generic_file(prefix, "", file); + + if (strcmp("unionfs", sbt(file->f_dentry->d_sb))) { + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s: Not a " UNIONFS_NAME " file.\n", prefix); + return; + } + + if (ftopd(file)) { + int bindex; + + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s: fbstart=%d, fbend=%d\n", prefix, fbstart(file), fbend(file)); + + for (bindex = fbstart(file); bindex <= fbend(file); bindex++) { + char newstr[10]; + hidden_file = ftohf_index(file, bindex); + if (!hidden_file) { + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s: HF#%d is NULL\n", prefix, bindex); + continue; + } + snprintf(newstr, 10, ": HF%d", bindex); + unionfs_print_generic_file(prefix, newstr, hidden_file); + } + } +} + +static char mode_to_type(mode_t mode) +{ + if (S_ISDIR(mode)) + return 'd'; + if (S_ISLNK(mode)) + return 'l'; + if (S_ISCHR(mode)) + return 'c'; + if (S_ISBLK(mode)) + return 'b'; + if (S_ISREG(mode)) + return 'f'; + return '?'; +} + +static void unionfs_print_generic_dentry(const char *prefix, const char *prefix2, const + struct dentry *dentry, int check) +{ + if (!dentry) { + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: NULL DENTRY PASSED!\n", prefix, prefix2); + return; + } + + if (IS_ERR(dentry)) { + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: ERROR DENTRY (%ld)!\n", prefix, prefix2, + PTR_ERR(dentry)); + return; + } + + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: dentry = %p\n", prefix, prefix2, dentry); + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: d_count=%d\n", prefix, prefix2, atomic_read(&dentry->d_count)); + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: d_flags=%x\n", prefix, prefix2, (int)dentry->d_flags); + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: d_name.name=\"%s\" (len = %d)\n", prefix, prefix2, dentry->d_name.name, dentry->d_name.len); + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: d_sb=%p (%s)\n", prefix, prefix2, dentry->d_sb, sbt(dentry->d_sb)); + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: d_inode=%p\n", prefix, prefix2, dentry->d_inode); + + if (dentry->d_inode) { + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: d_inode->i_ino=%ld (%s)\n", prefix, prefix2, + dentry->d_inode->i_ino, + sbt(dentry->d_inode->i_sb)); + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: dentry->d_inode->i_mode: %c%o\n", prefix, + prefix2, mode_to_type(dentry->d_inode->i_mode), + dentry->d_inode->i_mode); + } + + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: d_parent=%p (%s)\n", prefix, prefix2, + dentry->d_parent, + (dentry->d_parent ? sbt(dentry->d_parent->d_sb) : "nil")); + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: d_parent->d_name.name=\"%s\"\n", prefix, prefix2, + dentry->d_parent->d_name.name); + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: d_parent->d_count=%d\n", prefix, prefix2, + atomic_read(&dentry->d_parent->d_count)); + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: d_op=%p\n", prefix, prefix2, dentry->d_op); + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: d_fsdata=%p\n", prefix, prefix2, + dentry->d_fsdata); + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: hlist_unhashed(d_hash)=%d\n", prefix, prefix2, + hlist_unhashed(&((struct dentry *)dentry)->d_hash)); + + /* After we have printed it, we can assert something about it. */ + if (check) + BUG_ON(atomic_read(&dentry->d_count) <= 0); +} + +static void __unionfs_print_dentry(const char *prefix, const struct dentry *dentry, + int check) +{ + if (!dentry) { + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s: NULL DENTRY PASSED!\n", prefix); + return; + } + + if (IS_ERR(dentry)) { + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s: ERROR DENTRY (%ld)!\n", prefix, + PTR_ERR(dentry)); + return; + } + + unionfs_print_generic_dentry(prefix, "", dentry, check); + + if (strcmp("unionfs", sbt(dentry->d_sb))) { + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s: Not a " UNIONFS_NAME " dentry.\n", prefix); + return; + } + + if (!dtopd(dentry)) + return; + + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s: dbstart=%d, dbend=%d, dbopaque=%d\n", + prefix, dbstart(dentry), dbend(dentry), dbopaque(dentry)); + + if (dbstart(dentry) != -1) { + int bindex; + char newstr[10]; + struct dentry *hidden_dentry; + + for (bindex = dbstart(dentry); bindex <= dbend(dentry); + bindex++) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) { + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s: HD#%d: NULL\n", prefix, bindex); + continue; + } + snprintf(newstr, 10, ": HD%d", bindex); + unionfs_print_generic_dentry(prefix, newstr, hidden_dentry, check); + } + } +} + +void unionfs_print_dentry(const unsigned int req, const char *prefix, const struct dentry *dentry) +{ + if (!should_print(req)) + return; + + __unionfs_print_dentry(prefix, dentry, 1); +} + +void unionfs_print_dentry_nocheck(const unsigned int req, const char *prefix, const struct dentry *dentry) +{ + if (!should_print(req)) + return; + + __unionfs_print_dentry(prefix, dentry, 0); +} + +void unionfs_checkinode(const unsigned int req, const struct inode *inode, const char *msg) +{ + if (!should_print(req)) + return; + + if (!inode) { + printk(KERN_DEBUG UNIONFS_NAME ": unionfs_checkinode - inode is NULL! (%s)\n", + msg); + return; + } + + if (!itopd(inode)) { + printk(KERN_DEBUG UNIONFS_NAME ": unionfs_checkinode(%ld) - no private data (%s)\n", + inode->i_ino, msg); + return; + } + + if ((itopd(inode)->b_start < 0) || !itohi(inode)) { + printk(KERN_DEBUG UNIONFS_NAME + "unionfs_checkinode(%ld) - underlying is NULL! (%s)\n", + inode->i_ino, msg); + return; + } + + if (!inode->i_sb) { + printk(KERN_DEBUG UNIONFS_NAME + ": unionfs_checkinode(%ld) - inode->i_sb is NULL! (%s)\n", + inode->i_ino, msg); + return; + } + + printk(KERN_DEBUG UNIONFS_NAME ": inode->i_sb->s_type %p\n", inode->i_sb->s_type); + if (!inode->i_sb->s_type) { + printk(KERN_DEBUG UNIONFS_NAME + ": unionfs_checkinode(%ld) - inode->i_sb->s_type is NULL! (%s)\n", + inode->i_ino, msg); + return; + } + + printk(KERN_DEBUG UNIONFS_NAME + ": CI: %s: inode->i_count = %d, hidden_inode->i_count = %d, inode = %lu, sb = %s, hidden_sb = %s\n", + msg, atomic_read(&inode->i_count), + itopd(inode)->b_start >= + 0 ? atomic_read(&itohi(inode)->i_count) : -1, inode->i_ino, + inode->i_sb->s_type->name, + itopd(inode)->b_start >= + 0 ? itohi(inode)->i_sb->s_type->name : "(none)"); +} + +void unionfs_print_sb(const unsigned int req, const char *prefix, const struct super_block *sb) +{ + struct super_block *hidden_superblock; + + if (!should_print(req)) + return; + + if (!sb) { + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: NULL SB PASSED!\n", prefix); + return; + } + + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: s_blocksize=%lu\n", prefix, sb->s_blocksize); + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: s_blocksize_bits=%u\n", prefix, sb->s_blocksize_bits); + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: s_flags=0x%lx\n", prefix, sb->s_flags); + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: s_magic=0x%lx\n", prefix, sb->s_magic); + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: s_maxbytes=%llu\n", prefix, sb->s_maxbytes); + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: s_count=%d\n", prefix, sb->s_count); + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: s_active=%d\n", prefix, atomic_read(&sb->s_active)); + + if (stopd(sb)) + printk(KERN_DEBUG UNIONFS_NAME ": sbstart=%d, sbend=%d\n", sbstart(sb), + sbend(sb)); + + if (stopd(sb)) { + int bindex; + for (bindex = sbstart(sb); bindex <= sbend(sb); bindex++) { + hidden_superblock = stohs_index(sb, bindex); + if (!hidden_superblock) { + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: HS#%d is NULL", prefix, + bindex); + continue; + } + + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: HS#%d: s_blocksize=%lu\n", prefix, bindex, + hidden_superblock->s_blocksize); + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: HS#%d: s_blocksize_bits=%u\n", prefix, bindex, + hidden_superblock->s_blocksize_bits); + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: HS#%d: s_flags=0x%lx\n", prefix, bindex, + hidden_superblock->s_flags); + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: HS#%d: s_magic=0x%lx\n", prefix, bindex, + hidden_superblock->s_magic); + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: HS#%d: s_maxbytes=%llu\n", prefix, bindex, + hidden_superblock->s_maxbytes); + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: HS#%d: s_count=%d\n", prefix, bindex, + hidden_superblock->s_count); + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: HS#%d: s_active=%d\n", prefix, bindex, + atomic_read(&hidden_superblock->s_active)); + } + } +} + +int unionfs_print(const unsigned int req, const char *fmt, ...) +{ + va_list ap; + int r; + + if (!should_print(req)) + return 0; + + printk(KERN_DEBUG UNIONFS_NAME ": "); + va_start(ap, fmt); + r = vprintk(fmt, ap); + va_end(ap); + + return r; +} + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/unlink.c +++ linux-2.6.28/ubuntu/unionfs/unlink.c @@ -0,0 +1,380 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: unlink.c,v 1.44 2006/08/05 01:28:46 jro Exp $ + */ + +#include "unionfs.h" + +#ifdef UNIONFS_DELETE_ALL +static int unionfs_unlink_all(struct inode *dir, struct dentry *dentry) +{ + struct dentry *hidden_dentry; + struct dentry *hidden_dir_dentry; + int bstart, bend, bindex; + int err = 0; + int global_err = 0; + + print_entry_location(); + + if ((err = unionfs_partial_lookup(dentry))) + goto out; + + bstart = dbstart(dentry); + bend = dbend(dentry); + + for (bindex = bend; bindex >= bstart; bindex--) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) + continue; + + hidden_dir_dentry = lock_parent(hidden_dentry); + + /* avoid destroying the hidden inode if the file is in use */ + DGET(hidden_dentry); + if (!(err = is_robranch_super(dentry->d_sb, bindex))) + err = vfs_unlink(hidden_dir_dentry->d_inode, + hidden_dentry, NULL); + DPUT(hidden_dentry); + fist_copy_attr_times(dir, hidden_dir_dentry->d_inode); + unlock_dir(hidden_dir_dentry); + + if (err) { + /* passup the last error we got */ + if (!IS_COPYUP_ERR(err)) + goto out; + global_err = err; + } + } + + /* check if encountered error in the above loop */ + if (global_err) { + /* If we failed in the leftmost branch, then err will be set + * and we should move one over to create the whiteout. + * Otherwise, we should try in the leftmost branch. */ + if (err) { + if (dbstart(dentry) == 0) { + goto out; + } + err = create_whiteout(dentry, dbstart(dentry) - 1); + } else { + err = create_whiteout(dentry, dbstart(dentry)); + } + } else if (dbopaque(dentry) != -1) { + /* There is a hidden lower-priority file with the same name. */ + err = create_whiteout(dentry, dbopaque(dentry)); + } + out: + /* propagate number of hard-links */ + if (dentry->d_inode->i_nlink != 0) { + dentry->d_inode->i_nlink = get_nlinks(dentry->d_inode); + if (!err && global_err) + dentry->d_inode->i_nlink--; + } + /* We don't want to leave negative leftover dentries for revalidate. */ + if (!err && (global_err || dbopaque(dentry) != -1)) + update_bstart(dentry); + + print_exit_status(err); + return err; +} +#endif +static int unionfs_unlink_whiteout(struct inode *dir, struct dentry *dentry) +{ + struct dentry *hidden_dentry; + struct dentry *hidden_dir_dentry; + int bindex; + int err = 0; + + print_entry_location(); + + if ((err = unionfs_partial_lookup(dentry))) + goto out; + + bindex = dbstart(dentry); + + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) + goto out; + + hidden_dir_dentry = lock_parent(hidden_dentry); + + /* avoid destroying the hidden inode if the file is in use */ + DGET(hidden_dentry); + if (!(err = is_robranch_super(dentry->d_sb, bindex))) + err = vfs_unlink(hidden_dir_dentry->d_inode, hidden_dentry, + NULL); + DPUT(hidden_dentry); + fist_copy_attr_times(dir, hidden_dir_dentry->d_inode); + unlock_dir(hidden_dir_dentry); + + if (err && !IS_COPYUP_ERR(err)) + goto out; + + if (err) { + if (dbstart(dentry) == 0) + goto out; + + err = create_whiteout(dentry, dbstart(dentry) - 1); + } else if (dbopaque(dentry) != -1) { + /* There is a hidden lower-priority file with the same name. */ + err = create_whiteout(dentry, dbopaque(dentry)); + } else { + err = create_whiteout(dentry, dbstart(dentry)); + } + + out: + if (!err) + dentry->d_inode->i_nlink--; + + /* We don't want to leave negative leftover dentries for revalidate. */ + if (!err && (dbopaque(dentry) != -1)) + update_bstart(dentry); + + print_exit_status(err); + return err; + +} + +int unionfs_unlink(struct inode *dir, struct dentry *dentry) +{ + int err = 0; + + print_entry_location(); + lock_dentry(dentry); + print_dentry("IN unionfs_unlink", dentry); + +#ifdef UNIONFS_DELETE_ALL + if (IS_SET(dir->i_sb, DELETE_ALL)) + err = unionfs_unlink_all(dir, dentry); + else +#endif + err = unionfs_unlink_whiteout(dir, dentry); + /* call d_drop so the system "forgets" about us */ + if (!err) + d_drop(dentry); + + unlock_dentry(dentry); + print_exit_status(err); + return err; +} + +static int unionfs_rmdir_first(struct inode *dir, struct dentry *dentry, + struct unionfs_dir_state *namelist) +{ + int err; + struct dentry *hidden_dentry; + struct dentry *hidden_dir_dentry = NULL; + + print_entry_location(); + print_dentry("IN unionfs_rmdir_first: ", dentry); + + /* Here we need to remove whiteout entries. */ + err = delete_whiteouts(dentry, dbstart(dentry), namelist); + if (err) { + goto out; + } + + hidden_dentry = dtohd(dentry); + + hidden_dir_dentry = lock_parent(hidden_dentry); + + /* avoid destroying the hidden inode if the file is in use */ + DGET(hidden_dentry); + if (!(err = is_robranch(dentry))) { + err = vfs_rmdir(hidden_dir_dentry->d_inode, hidden_dentry, + NULL); + } + DPUT(hidden_dentry); + + fist_copy_attr_times(dir, hidden_dir_dentry->d_inode); + /* propagate number of hard-links */ + dentry->d_inode->i_nlink = get_nlinks(dentry->d_inode); + + out: + if (hidden_dir_dentry) { + unlock_dir(hidden_dir_dentry); + } + print_dentry("OUT unionfs_rmdir_first: ", dentry); + print_exit_status(err); + return err; +} + +#ifdef UNIONFS_DELETE_ALL +static int unionfs_rmdir_all(struct inode *dir, struct dentry *dentry, + struct unionfs_dir_state *namelist) +{ + struct dentry *hidden_dentry; + struct dentry *hidden_dir_dentry; + int bstart, bend, bindex; + int err = 0; + int global_err = 0; + + print_entry_location(); + print_dentry("IN unionfs_rmdir_all: ", dentry); + + bstart = dbstart(dentry); + bend = dbend(dentry); + + for (bindex = bend; bindex >= bstart; bindex--) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) + continue; + + hidden_dir_dentry = lock_parent(hidden_dentry); + if (S_ISDIR(hidden_dentry->d_inode->i_mode)) { + err = delete_whiteouts(dentry, bindex, namelist); + if (!err + && !(err = + is_robranch_super(dentry->d_sb, bindex))) { + err = + vfs_rmdir(hidden_dir_dentry->d_inode, + hidden_dentry, NULL); + } + } else { + err = -EISDIR; + } + + fist_copy_attr_times(dir, hidden_dir_dentry->d_inode); + unlock_dir(hidden_dir_dentry); + if (err) { + int local_err = + unionfs_refresh_hidden_dentry(dentry, bindex); + if (local_err) { + err = local_err; + goto out; + } + + if (!IS_COPYUP_ERR(err) && err != -ENOTEMPTY + && err != -EISDIR) + goto out; + + global_err = err; + } + } + + /* check if encountered error in the above loop */ + if (global_err) { + /* If we failed in the leftmost branch, then err will be set and we should + * move one over to create the whiteout. Otherwise, we should try in the + * leftmost branch. + */ + if (err) { + if (dbstart(dentry) == 0) { + goto out; + } + err = create_whiteout(dentry, dbstart(dentry) - 1); + } else { + err = create_whiteout(dentry, dbstart(dentry)); + } + } else { + err = create_whiteout(dentry, dbstart(dentry)); + } + + out: + /* propagate number of hard-links */ + dentry->d_inode->i_nlink = get_nlinks(dentry->d_inode); + + print_dentry("OUT unionfs_rmdir_all: ", dentry); + print_exit_status(err); + return err; +} +#endif +int unionfs_rmdir(struct inode *dir, struct dentry *dentry) +{ + int err = 0; + struct unionfs_dir_state *namelist = NULL; + + print_entry_location(); + lock_dentry(dentry); + print_dentry("IN unionfs_rmdir: ", dentry); + + /* check if this unionfs directory is empty or not */ + err = check_empty(dentry, &namelist); + if (err) { +#if 0 + /* vfs_rmdir(our caller) unhashed the dentry. This will recover + * the Unionfs inode number for the directory itself, but the + * children are already lost. It seems that tmpfs manages its + * way around this by upping the refcount on everything. + * + * Even if we do this, we still lose the inode numbers of the + * children. The best way to fix this is to fix the VFS (or + * use persistent inode maps). */ + if (d_unhashed(dentry)) + d_rehash(dentry); +#endif + goto out; + } +#ifdef UNIONFS_DELETE_ALL + if (IS_SET(dir->i_sb, DELETE_ALL)) { + /* delete all. */ + err = unionfs_rmdir_all(dir, dentry, namelist); + } else { /* Delete the first directory. */ +#endif + err = unionfs_rmdir_first(dir, dentry, namelist); + /* create whiteout */ + if (!err) { + err = create_whiteout(dentry, dbstart(dentry)); + } else { + int new_err; + + if (dbstart(dentry) == 0) + goto out; + + /* exit if the error returned was NOT -EROFS */ + if (!IS_COPYUP_ERR(err)) + goto out; + + new_err = create_whiteout(dentry, dbstart(dentry) - 1); + if (new_err != -EEXIST) + err = new_err; + } + +#ifdef UNIONFS_DELETE_ALL + } +#endif + out: + /* call d_drop so the system "forgets" about us */ + if (!err) + d_drop(dentry); + + if (namelist) + free_rdstate(namelist); + + unlock_dentry(dentry); + print_exit_status(err); + return err; +} + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/include/README +++ linux-2.6.28/ubuntu/include/README @@ -0,0 +1,4 @@ +Only use this directory for things which need to share their headers with +other parts of the kernel or other modules in ubuntu/ + +Otherwise, keep them local to the module directory. --- linux-2.6.28.orig/ubuntu/include/linux/squashfs_fs_sb.h +++ linux-2.6.28/ubuntu/include/linux/squashfs_fs_sb.h @@ -0,0 +1,76 @@ +#ifndef SQUASHFS_FS_SB +#define SQUASHFS_FS_SB +/* + * Squashfs + * + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 + * Phillip Lougher + * + * This program is free software; you can redistribute 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * squashfs_fs_sb.h + */ + +#include + +struct squashfs_cache { + long long block; + int length; + long long next_index; + char *data; +}; + +struct squashfs_fragment_cache { + long long block; + int length; + unsigned int locked; + char *data; +}; + +struct squashfs_sb_info { + struct squashfs_super_block sblk; + int devblksize; + int devblksize_log2; + int swap; + struct squashfs_cache *block_cache; + struct squashfs_fragment_cache *fragment; + int next_cache; + int next_fragment; + int next_meta_index; + unsigned int *uid; + unsigned int *guid; + long long *fragment_index; + unsigned int *fragment_index_2; + char *read_page; + struct mutex read_data_mutex; + struct mutex read_page_mutex; + struct mutex block_cache_mutex; + struct mutex fragment_mutex; + struct mutex meta_index_mutex; + wait_queue_head_t waitq; + wait_queue_head_t fragment_wait_queue; + struct meta_index *meta_index; + z_stream stream; + long long *inode_lookup_table; + int unused_cache_blks; + int unused_frag_blks; + int (*read_inode)(struct inode *i, squashfs_inode_t \ + inode); + long long (*read_blocklist)(struct inode *inode, int \ + index, int readahead_blks, char *block_list, \ + unsigned short **block_p, unsigned int *bsize); + int (*read_fragment_index_table)(struct super_block *s); +}; +#endif --- linux-2.6.28.orig/ubuntu/include/linux/aufs_types.h +++ linux-2.6.28/ubuntu/include/linux/aufs_types.h @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2005, 2006, 2007, 2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* $Id: aufs_type.h,v 1.110 2008/06/09 01:11:58 sfjro Exp $ */ + +#include + +#ifndef __AUFS_TYPE_H__ +#define __AUFS_TYPE_H__ + +#define AUFS_VERSION "20080609" + +/* move this to linux-2.6.19/include/magic.h */ +#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') + +/* ---------------------------------------------------------------------- */ + +#ifdef CONFIG_AUFS_BRANCH_MAX_127 +/* some environments treat 'char' as 'unsigned char' by default */ +typedef signed char aufs_bindex_t; +#define AUFS_BRANCH_MAX 127 +#else +typedef short aufs_bindex_t; +#ifdef CONFIG_AUFS_BRANCH_MAX_511 +#define AUFS_BRANCH_MAX 511 +#elif defined(CONFIG_AUFS_BRANCH_MAX_1023) +#define AUFS_BRANCH_MAX 1023 +#elif defined(CONFIG_AUFS_BRANCH_MAX_32767) +#define AUFS_BRANCH_MAX 32767 +#else +#error unknown CONFIG_AUFS_BRANCH_MAX value +#endif +#endif + +#define AUFS_NAME "aufs" +#define AUFS_FSTYPE AUFS_NAME + +#define AUFS_ROOT_INO 2 +#define AUFS_FIRST_INO 11 + +#define AUFS_WH_PFX ".wh." +#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1) +#define AUFS_XINO_FNAME "." AUFS_NAME ".xino" +#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME +#define AUFS_XINO_TRUNC_INIT 64 /* blocks */ +#define AUFS_XINO_TRUNC_STEP 4 /* blocks */ +#define AUFS_DIRWH_DEF 3 +#define AUFS_RDCACHE_DEF 10 /* seconds */ +#define AUFS_WKQ_NAME AUFS_NAME "d" +#define AUFS_NWKQ_DEF 4 +#define AUFS_MFS_SECOND_DEF 30 /* seconds */ +#define AUFS_PLINK_WARN 100 /* number of plinks */ + +#ifdef CONFIG_AUFS_COMPAT +#define AUFS_DIROPQ_NAME "__dir_opaque" +#else +#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */ +#endif +#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME + +/* will be whiteouted doubly */ +#define AUFS_WH_BASENAME AUFS_WH_PFX AUFS_NAME +#define AUFS_WH_PLINKDIR AUFS_WH_PFX "plink" + +/* ---------------------------------------------------------------------- */ + +/* ioctl */ +#if 0 /* reserved for future use */ +enum { + AuCtlErr, + AuCtlErr_Last +}; +enum { + AuCtl_REFRESH, AuCtl_REFRESHV, + AuCtl_FLUSH_PLINK, + AuCtl_CPUP, + AuCtl_CPDOWN, AuCtl_MVDOWN, + AuCtl_DIROPQ +}; + +struct aufs_ctl_cp { + int bsrc, bdst; + int err; +}; + +#define AuCtlType 'A' +#define AUFS_CTL_REFRESH _IO(AuCtlType, AuCtl_REFRESH) +#define AUFS_CTL_REFRESHV _IO(AuCtlType, AuCtl_REFRESHV) +#define AUFS_CTL_FLUSH_PLINK _IOR(AuCtlType, AuCtl_FLUSH_PLINK) +#define AUFS_CTL_CPUP _IOWR(AuCtlType, AuCtl_CPUP, struct aufs_ctl_cp) +#define AUFS_CTL_CPDOWN \ + _IOWR(AuCtlType, AuCtl_CPDOWN, struct aufs_ctl_cp) +#define AUFS_CTL_MVDOWN \ + _IOWR(AuCtlType, AuCtl_MVDOWN, struct aufs_ctl_cp) +#define AUFS_CTL_DIROPQ _IO(AuCtlType, AuCtl_DIROPQ) +#endif + +#endif /* __AUFS_TYPE_H__ */ --- linux-2.6.28.orig/ubuntu/include/linux/squashfs_fs_i.h +++ linux-2.6.28/ubuntu/include/linux/squashfs_fs_i.h @@ -0,0 +1,45 @@ +#ifndef SQUASHFS_FS_I +#define SQUASHFS_FS_I +/* + * Squashfs + * + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 + * Phillip Lougher + * + * This program is free software; you can redistribute 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * squashfs_fs_i.h + */ + +struct squashfs_inode_info { + long long start_block; + unsigned int offset; + union { + struct { + long long fragment_start_block; + unsigned int fragment_size; + unsigned int fragment_offset; + long long block_list_start; + } s1; + struct { + long long directory_index_start; + unsigned int directory_index_offset; + unsigned int directory_index_count; + unsigned int parent_inode; + } s2; + } u; + struct inode vfs_inode; +}; +#endif --- linux-2.6.28.orig/ubuntu/include/linux/squashfs_fs.h +++ linux-2.6.28/ubuntu/include/linux/squashfs_fs.h @@ -0,0 +1,935 @@ +#ifndef SQUASHFS_FS +#define SQUASHFS_FS + +/* + * Squashfs + * + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 + * Phillip Lougher + * + * This program is free software; you can redistribute 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * squashfs_fs.h + */ + +#ifndef CONFIG_SQUASHFS_2_0_COMPATIBILITY +#define CONFIG_SQUASHFS_2_0_COMPATIBILITY +#endif + +#define SQUASHFS_CACHED_FRAGMENTS CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE +#define SQUASHFS_MAJOR 3 +#define SQUASHFS_MINOR 1 +#define SQUASHFS_MAGIC 0x73717368 +#define SQUASHFS_MAGIC_SWAP 0x68737173 +#define SQUASHFS_START 0 + +/* size of metadata (inode and directory) blocks */ +#define SQUASHFS_METADATA_SIZE 8192 +#define SQUASHFS_METADATA_LOG 13 + +/* default size of data blocks */ +#define SQUASHFS_FILE_SIZE 131072 +#define SQUASHFS_FILE_LOG 17 + +#define SQUASHFS_FILE_MAX_SIZE 1048576 + +/* Max number of uids and gids */ +#define SQUASHFS_UIDS 256 +#define SQUASHFS_GUIDS 255 + +/* Max length of filename (not 255) */ +#define SQUASHFS_NAME_LEN 256 + +#define SQUASHFS_INVALID ((long long) 0xffffffffffff) +#define SQUASHFS_INVALID_FRAG ((unsigned int) 0xffffffff) +#define SQUASHFS_INVALID_BLK ((long long) -1) +#define SQUASHFS_USED_BLK ((long long) -2) + +/* Filesystem flags */ +#define SQUASHFS_NOI 0 +#define SQUASHFS_NOD 1 +#define SQUASHFS_CHECK 2 +#define SQUASHFS_NOF 3 +#define SQUASHFS_NO_FRAG 4 +#define SQUASHFS_ALWAYS_FRAG 5 +#define SQUASHFS_DUPLICATE 6 +#define SQUASHFS_EXPORT 7 + +#define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1) + +#define SQUASHFS_UNCOMPRESSED_INODES(flags) SQUASHFS_BIT(flags, \ + SQUASHFS_NOI) + +#define SQUASHFS_UNCOMPRESSED_DATA(flags) SQUASHFS_BIT(flags, \ + SQUASHFS_NOD) + +#define SQUASHFS_UNCOMPRESSED_FRAGMENTS(flags) SQUASHFS_BIT(flags, \ + SQUASHFS_NOF) + +#define SQUASHFS_NO_FRAGMENTS(flags) SQUASHFS_BIT(flags, \ + SQUASHFS_NO_FRAG) + +#define SQUASHFS_ALWAYS_FRAGMENTS(flags) SQUASHFS_BIT(flags, \ + SQUASHFS_ALWAYS_FRAG) + +#define SQUASHFS_DUPLICATES(flags) SQUASHFS_BIT(flags, \ + SQUASHFS_DUPLICATE) + +#define SQUASHFS_EXPORTABLE(flags) SQUASHFS_BIT(flags, \ + SQUASHFS_EXPORT) + +#define SQUASHFS_CHECK_DATA(flags) SQUASHFS_BIT(flags, \ + SQUASHFS_CHECK) + +#define SQUASHFS_MKFLAGS(noi, nod, check_data, nof, no_frag, always_frag, \ + duplicate_checking, exportable) (noi | (nod << 1) | (check_data << 2) \ + | (nof << 3) | (no_frag << 4) | (always_frag << 5) | \ + (duplicate_checking << 6) | (exportable << 7)) + +/* Max number of types and file types */ +#define SQUASHFS_DIR_TYPE 1 +#define SQUASHFS_FILE_TYPE 2 +#define SQUASHFS_SYMLINK_TYPE 3 +#define SQUASHFS_BLKDEV_TYPE 4 +#define SQUASHFS_CHRDEV_TYPE 5 +#define SQUASHFS_FIFO_TYPE 6 +#define SQUASHFS_SOCKET_TYPE 7 +#define SQUASHFS_LDIR_TYPE 8 +#define SQUASHFS_LREG_TYPE 9 + +/* 1.0 filesystem type definitions */ +#define SQUASHFS_TYPES 5 +#define SQUASHFS_IPC_TYPE 0 + +/* Flag whether block is compressed or uncompressed, bit is set if block is + * uncompressed */ +#define SQUASHFS_COMPRESSED_BIT (1 << 15) + +#define SQUASHFS_COMPRESSED_SIZE(B) (((B) & ~SQUASHFS_COMPRESSED_BIT) ? \ + (B) & ~SQUASHFS_COMPRESSED_BIT : SQUASHFS_COMPRESSED_BIT) + +#define SQUASHFS_COMPRESSED(B) (!((B) & SQUASHFS_COMPRESSED_BIT)) + +#define SQUASHFS_COMPRESSED_BIT_BLOCK (1 << 24) + +#define SQUASHFS_COMPRESSED_SIZE_BLOCK(B) ((B) & \ + ~SQUASHFS_COMPRESSED_BIT_BLOCK) + +#define SQUASHFS_COMPRESSED_BLOCK(B) (!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK)) + +/* + * Inode number ops. Inodes consist of a compressed block number, and an + * uncompressed offset within that block + */ +#define SQUASHFS_INODE_BLK(a) ((unsigned int) ((a) >> 16)) + +#define SQUASHFS_INODE_OFFSET(a) ((unsigned int) ((a) & 0xffff)) + +#define SQUASHFS_MKINODE(A, B) ((squashfs_inode_t)(((squashfs_inode_t) (A)\ + << 16) + (B))) + +/* Compute 32 bit VFS inode number from squashfs inode number */ +#define SQUASHFS_MK_VFS_INODE(a, b) ((unsigned int) (((a) << 8) + \ + ((b) >> 2) + 1)) +/* XXX */ + +/* Translate between VFS mode and squashfs mode */ +#define SQUASHFS_MODE(a) ((a) & 0xfff) + +/* fragment and fragment table defines */ +#define SQUASHFS_FRAGMENT_BYTES(A) ((A) * sizeof(struct squashfs_fragment_entry)) + +#define SQUASHFS_FRAGMENT_INDEX(A) (SQUASHFS_FRAGMENT_BYTES(A) / \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_FRAGMENT_INDEX_OFFSET(A) (SQUASHFS_FRAGMENT_BYTES(A) % \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_FRAGMENT_INDEXES(A) ((SQUASHFS_FRAGMENT_BYTES(A) + \ + SQUASHFS_METADATA_SIZE - 1) / \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_FRAGMENT_INDEX_BYTES(A) (SQUASHFS_FRAGMENT_INDEXES(A) *\ + sizeof(long long)) + +/* inode lookup table defines */ +#define SQUASHFS_LOOKUP_BYTES(A) ((A) * sizeof(squashfs_inode_t)) + +#define SQUASHFS_LOOKUP_BLOCK(A) (SQUASHFS_LOOKUP_BYTES(A) / \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_LOOKUP_BLOCK_OFFSET(A) (SQUASHFS_LOOKUP_BYTES(A) % \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_LOOKUP_BLOCKS(A) ((SQUASHFS_LOOKUP_BYTES(A) + \ + SQUASHFS_METADATA_SIZE - 1) / \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_LOOKUP_BLOCK_BYTES(A) (SQUASHFS_LOOKUP_BLOCKS(A) *\ + sizeof(long long)) + +/* cached data constants for filesystem */ +#define SQUASHFS_CACHED_BLKS 8 + +#define SQUASHFS_MAX_FILE_SIZE_LOG 64 + +#define SQUASHFS_MAX_FILE_SIZE ((long long) 1 << \ + (SQUASHFS_MAX_FILE_SIZE_LOG - 2)) + +#define SQUASHFS_MARKER_BYTE 0xff + +/* meta index cache */ +#define SQUASHFS_META_INDEXES (SQUASHFS_METADATA_SIZE / sizeof(unsigned int)) +#define SQUASHFS_META_ENTRIES 31 +#define SQUASHFS_META_NUMBER 8 +#define SQUASHFS_SLOTS 4 + +struct meta_entry { + long long data_block; + unsigned int index_block; + unsigned short offset; + unsigned short pad; +}; + +struct meta_index { + unsigned int inode_number; + unsigned int offset; + unsigned short entries; + unsigned short skip; + unsigned short locked; + unsigned short pad; + struct meta_entry meta_entry[SQUASHFS_META_ENTRIES]; +}; + + +/* + * definitions for structures on disk + */ + +typedef long long squashfs_block_t; +typedef long long squashfs_inode_t; + +struct squashfs_super_block { + unsigned int s_magic; + unsigned int inodes; + unsigned int bytes_used_2; + unsigned int uid_start_2; + unsigned int guid_start_2; + unsigned int inode_table_start_2; + unsigned int directory_table_start_2; + unsigned int s_major:16; + unsigned int s_minor:16; + unsigned int block_size_1:16; + unsigned int block_log:16; + unsigned int flags:8; + unsigned int no_uids:8; + unsigned int no_guids:8; + unsigned int mkfs_time /* time of filesystem creation */; + squashfs_inode_t root_inode; + unsigned int block_size; + unsigned int fragments; + unsigned int fragment_table_start_2; + long long bytes_used; + long long uid_start; + long long guid_start; + long long inode_table_start; + long long directory_table_start; + long long fragment_table_start; + long long lookup_table_start; +} __attribute__ ((packed)); + +struct squashfs_dir_index { + unsigned int index; + unsigned int start_block; + unsigned char size; + unsigned char name[0]; +} __attribute__ ((packed)); + +#define SQUASHFS_BASE_INODE_HEADER \ + unsigned int inode_type:4; \ + unsigned int mode:12; \ + unsigned int uid:8; \ + unsigned int guid:8; \ + unsigned int mtime; \ + unsigned int inode_number; + +struct squashfs_base_inode_header { + SQUASHFS_BASE_INODE_HEADER; +} __attribute__ ((packed)); + +struct squashfs_ipc_inode_header { + SQUASHFS_BASE_INODE_HEADER; + unsigned int nlink; +} __attribute__ ((packed)); + +struct squashfs_dev_inode_header { + SQUASHFS_BASE_INODE_HEADER; + unsigned int nlink; + unsigned short rdev; +} __attribute__ ((packed)); + +struct squashfs_symlink_inode_header { + SQUASHFS_BASE_INODE_HEADER; + unsigned int nlink; + unsigned short symlink_size; + char symlink[0]; +} __attribute__ ((packed)); + +struct squashfs_reg_inode_header { + SQUASHFS_BASE_INODE_HEADER; + squashfs_block_t start_block; + unsigned int fragment; + unsigned int offset; + unsigned int file_size; + unsigned short block_list[0]; +} __attribute__ ((packed)); + +struct squashfs_lreg_inode_header { + SQUASHFS_BASE_INODE_HEADER; + unsigned int nlink; + squashfs_block_t start_block; + unsigned int fragment; + unsigned int offset; + long long file_size; + unsigned short block_list[0]; +} __attribute__ ((packed)); + +struct squashfs_dir_inode_header { + SQUASHFS_BASE_INODE_HEADER; + unsigned int nlink; + unsigned int file_size:19; + unsigned int offset:13; + unsigned int start_block; + unsigned int parent_inode; +} __attribute__ ((packed)); + +struct squashfs_ldir_inode_header { + SQUASHFS_BASE_INODE_HEADER; + unsigned int nlink; + unsigned int file_size:27; + unsigned int offset:13; + unsigned int start_block; + unsigned int i_count:16; + unsigned int parent_inode; + struct squashfs_dir_index index[0]; +} __attribute__ ((packed)); + +union squashfs_inode_header { + struct squashfs_base_inode_header base; + struct squashfs_dev_inode_header dev; + struct squashfs_symlink_inode_header symlink; + struct squashfs_reg_inode_header reg; + struct squashfs_lreg_inode_header lreg; + struct squashfs_dir_inode_header dir; + struct squashfs_ldir_inode_header ldir; + struct squashfs_ipc_inode_header ipc; +}; + +struct squashfs_dir_entry { + unsigned int offset:13; + unsigned int type:3; + unsigned int size:8; + int inode_number:16; + char name[0]; +} __attribute__ ((packed)); + +struct squashfs_dir_header { + unsigned int count:8; + unsigned int start_block; + unsigned int inode_number; +} __attribute__ ((packed)); + +struct squashfs_fragment_entry { + long long start_block; + unsigned int size; + unsigned int pending; +} __attribute__ ((packed)); + +extern int squashfs_uncompress_block(void *d, int dstlen, void *s, int srclen); +extern int squashfs_uncompress_init(void); +extern int squashfs_uncompress_exit(void); + +/* + * macros to convert each packed bitfield structure from little endian to big + * endian and vice versa. These are needed when creating or using a filesystem + * on a machine with different byte ordering to the target architecture. + * + */ + +#define SQUASHFS_SWAP_START \ + int bits;\ + int b_pos;\ + unsigned long long val;\ + unsigned char *s;\ + unsigned char *d; + +#define SQUASHFS_SWAP_SUPER_BLOCK(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_super_block));\ + SQUASHFS_SWAP((s)->s_magic, d, 0, 32);\ + SQUASHFS_SWAP((s)->inodes, d, 32, 32);\ + SQUASHFS_SWAP((s)->bytes_used_2, d, 64, 32);\ + SQUASHFS_SWAP((s)->uid_start_2, d, 96, 32);\ + SQUASHFS_SWAP((s)->guid_start_2, d, 128, 32);\ + SQUASHFS_SWAP((s)->inode_table_start_2, d, 160, 32);\ + SQUASHFS_SWAP((s)->directory_table_start_2, d, 192, 32);\ + SQUASHFS_SWAP((s)->s_major, d, 224, 16);\ + SQUASHFS_SWAP((s)->s_minor, d, 240, 16);\ + SQUASHFS_SWAP((s)->block_size_1, d, 256, 16);\ + SQUASHFS_SWAP((s)->block_log, d, 272, 16);\ + SQUASHFS_SWAP((s)->flags, d, 288, 8);\ + SQUASHFS_SWAP((s)->no_uids, d, 296, 8);\ + SQUASHFS_SWAP((s)->no_guids, d, 304, 8);\ + SQUASHFS_SWAP((s)->mkfs_time, d, 312, 32);\ + SQUASHFS_SWAP((s)->root_inode, d, 344, 64);\ + SQUASHFS_SWAP((s)->block_size, d, 408, 32);\ + SQUASHFS_SWAP((s)->fragments, d, 440, 32);\ + SQUASHFS_SWAP((s)->fragment_table_start_2, d, 472, 32);\ + SQUASHFS_SWAP((s)->bytes_used, d, 504, 64);\ + SQUASHFS_SWAP((s)->uid_start, d, 568, 64);\ + SQUASHFS_SWAP((s)->guid_start, d, 632, 64);\ + SQUASHFS_SWAP((s)->inode_table_start, d, 696, 64);\ + SQUASHFS_SWAP((s)->directory_table_start, d, 760, 64);\ + SQUASHFS_SWAP((s)->fragment_table_start, d, 824, 64);\ + SQUASHFS_SWAP((s)->lookup_table_start, d, 888, 64);\ +} + +#define SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\ + SQUASHFS_MEMSET(s, d, n);\ + SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\ + SQUASHFS_SWAP((s)->mode, d, 4, 12);\ + SQUASHFS_SWAP((s)->uid, d, 16, 8);\ + SQUASHFS_SWAP((s)->guid, d, 24, 8);\ + SQUASHFS_SWAP((s)->mtime, d, 32, 32);\ + SQUASHFS_SWAP((s)->inode_number, d, 64, 32); + +#define SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, n) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\ +} + +#define SQUASHFS_SWAP_IPC_INODE_HEADER(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ + sizeof(struct squashfs_ipc_inode_header))\ + SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ +} + +#define SQUASHFS_SWAP_DEV_INODE_HEADER(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ + sizeof(struct squashfs_dev_inode_header)); \ + SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ + SQUASHFS_SWAP((s)->rdev, d, 128, 16);\ +} + +#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ + sizeof(struct squashfs_symlink_inode_header));\ + SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ + SQUASHFS_SWAP((s)->symlink_size, d, 128, 16);\ +} + +#define SQUASHFS_SWAP_REG_INODE_HEADER(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ + sizeof(struct squashfs_reg_inode_header));\ + SQUASHFS_SWAP((s)->start_block, d, 96, 64);\ + SQUASHFS_SWAP((s)->fragment, d, 160, 32);\ + SQUASHFS_SWAP((s)->offset, d, 192, 32);\ + SQUASHFS_SWAP((s)->file_size, d, 224, 32);\ +} + +#define SQUASHFS_SWAP_LREG_INODE_HEADER(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ + sizeof(struct squashfs_lreg_inode_header));\ + SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ + SQUASHFS_SWAP((s)->start_block, d, 128, 64);\ + SQUASHFS_SWAP((s)->fragment, d, 192, 32);\ + SQUASHFS_SWAP((s)->offset, d, 224, 32);\ + SQUASHFS_SWAP((s)->file_size, d, 256, 64);\ +} + +#define SQUASHFS_SWAP_DIR_INODE_HEADER(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ + sizeof(struct squashfs_dir_inode_header));\ + SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ + SQUASHFS_SWAP((s)->file_size, d, 128, 19);\ + SQUASHFS_SWAP((s)->offset, d, 147, 13);\ + SQUASHFS_SWAP((s)->start_block, d, 160, 32);\ + SQUASHFS_SWAP((s)->parent_inode, d, 192, 32);\ +} + +#define SQUASHFS_SWAP_LDIR_INODE_HEADER(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ + sizeof(struct squashfs_ldir_inode_header));\ + SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ + SQUASHFS_SWAP((s)->file_size, d, 128, 27);\ + SQUASHFS_SWAP((s)->offset, d, 155, 13);\ + SQUASHFS_SWAP((s)->start_block, d, 168, 32);\ + SQUASHFS_SWAP((s)->i_count, d, 200, 16);\ + SQUASHFS_SWAP((s)->parent_inode, d, 216, 32);\ +} + +#define SQUASHFS_SWAP_DIR_INDEX(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index));\ + SQUASHFS_SWAP((s)->index, d, 0, 32);\ + SQUASHFS_SWAP((s)->start_block, d, 32, 32);\ + SQUASHFS_SWAP((s)->size, d, 64, 8);\ +} + +#define SQUASHFS_SWAP_DIR_HEADER(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header));\ + SQUASHFS_SWAP((s)->count, d, 0, 8);\ + SQUASHFS_SWAP((s)->start_block, d, 8, 32);\ + SQUASHFS_SWAP((s)->inode_number, d, 40, 32);\ +} + +#define SQUASHFS_SWAP_DIR_ENTRY(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry));\ + SQUASHFS_SWAP((s)->offset, d, 0, 13);\ + SQUASHFS_SWAP((s)->type, d, 13, 3);\ + SQUASHFS_SWAP((s)->size, d, 16, 8);\ + SQUASHFS_SWAP((s)->inode_number, d, 24, 16);\ +} + +#define SQUASHFS_SWAP_FRAGMENT_ENTRY(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry));\ + SQUASHFS_SWAP((s)->start_block, d, 0, 64);\ + SQUASHFS_SWAP((s)->size, d, 64, 32);\ +} + +#define SQUASHFS_SWAP_INODE_T(s, d) SQUASHFS_SWAP_LONG_LONGS(s, d, 1) + +#define SQUASHFS_SWAP_SHORTS(s, d, n) {\ + int entry;\ + int bit_position;\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, n * 2);\ + for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ + 16)\ + SQUASHFS_SWAP(s[entry], d, bit_position, 16);\ +} + +#define SQUASHFS_SWAP_INTS(s, d, n) {\ + int entry;\ + int bit_position;\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, n * 4);\ + for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ + 32)\ + SQUASHFS_SWAP(s[entry], d, bit_position, 32);\ +} + +#define SQUASHFS_SWAP_LONG_LONGS(s, d, n) {\ + int entry;\ + int bit_position;\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, n * 8);\ + for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ + 64)\ + SQUASHFS_SWAP(s[entry], d, bit_position, 64);\ +} + +#define SQUASHFS_SWAP_DATA(s, d, n, bits) {\ + int entry;\ + int bit_position;\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, n * bits / 8);\ + for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ + bits)\ + SQUASHFS_SWAP(s[entry], d, bit_position, bits);\ +} + +#define SQUASHFS_SWAP_FRAGMENT_INDEXES(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n) +#define SQUASHFS_SWAP_LOOKUP_BLOCKS(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n) + +#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY + +struct squashfs_base_inode_header_1 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:4; /* index into uid table */ + unsigned int guid:4; /* index into guid table */ +} __attribute__ ((packed)); + +struct squashfs_ipc_inode_header_1 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:4; /* index into uid table */ + unsigned int guid:4; /* index into guid table */ + unsigned int type:4; + unsigned int offset:4; +} __attribute__ ((packed)); + +struct squashfs_dev_inode_header_1 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:4; /* index into uid table */ + unsigned int guid:4; /* index into guid table */ + unsigned short rdev; +} __attribute__ ((packed)); + +struct squashfs_symlink_inode_header_1 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:4; /* index into uid table */ + unsigned int guid:4; /* index into guid table */ + unsigned short symlink_size; + char symlink[0]; +} __attribute__ ((packed)); + +struct squashfs_reg_inode_header_1 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:4; /* index into uid table */ + unsigned int guid:4; /* index into guid table */ + unsigned int mtime; + unsigned int start_block; + unsigned int file_size:32; + unsigned short block_list[0]; +} __attribute__ ((packed)); + +struct squashfs_dir_inode_header_1 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:4; /* index into uid table */ + unsigned int guid:4; /* index into guid table */ + unsigned int file_size:19; + unsigned int offset:13; + unsigned int mtime; + unsigned int start_block:24; +} __attribute__ ((packed)); + +union squashfs_inode_header_1 { + struct squashfs_base_inode_header_1 base; + struct squashfs_dev_inode_header_1 dev; + struct squashfs_symlink_inode_header_1 symlink; + struct squashfs_reg_inode_header_1 reg; + struct squashfs_dir_inode_header_1 dir; + struct squashfs_ipc_inode_header_1 ipc; +}; + +#define SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n) \ + SQUASHFS_MEMSET(s, d, n);\ + SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\ + SQUASHFS_SWAP((s)->mode, d, 4, 12);\ + SQUASHFS_SWAP((s)->uid, d, 16, 4);\ + SQUASHFS_SWAP((s)->guid, d, 20, 4); + +#define SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, n) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n)\ +} + +#define SQUASHFS_SWAP_IPC_INODE_HEADER_1(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ + sizeof(struct squashfs_ipc_inode_header_1));\ + SQUASHFS_SWAP((s)->type, d, 24, 4);\ + SQUASHFS_SWAP((s)->offset, d, 28, 4);\ +} + +#define SQUASHFS_SWAP_DEV_INODE_HEADER_1(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ + sizeof(struct squashfs_dev_inode_header_1));\ + SQUASHFS_SWAP((s)->rdev, d, 24, 16);\ +} + +#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_1(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ + sizeof(struct squashfs_symlink_inode_header_1));\ + SQUASHFS_SWAP((s)->symlink_size, d, 24, 16);\ +} + +#define SQUASHFS_SWAP_REG_INODE_HEADER_1(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ + sizeof(struct squashfs_reg_inode_header_1));\ + SQUASHFS_SWAP((s)->mtime, d, 24, 32);\ + SQUASHFS_SWAP((s)->start_block, d, 56, 32);\ + SQUASHFS_SWAP((s)->file_size, d, 88, 32);\ +} + +#define SQUASHFS_SWAP_DIR_INODE_HEADER_1(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ + sizeof(struct squashfs_dir_inode_header_1));\ + SQUASHFS_SWAP((s)->file_size, d, 24, 19);\ + SQUASHFS_SWAP((s)->offset, d, 43, 13);\ + SQUASHFS_SWAP((s)->mtime, d, 56, 32);\ + SQUASHFS_SWAP((s)->start_block, d, 88, 24);\ +} + +#endif + +#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY + +struct squashfs_dir_index_2 { + unsigned int index:27; + unsigned int start_block:29; + unsigned char size; + unsigned char name[0]; +} __attribute__ ((packed)); + +struct squashfs_base_inode_header_2 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:8; /* index into uid table */ + unsigned int guid:8; /* index into guid table */ +} __attribute__ ((packed)); + +struct squashfs_ipc_inode_header_2 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:8; /* index into uid table */ + unsigned int guid:8; /* index into guid table */ +} __attribute__ ((packed)); + +struct squashfs_dev_inode_header_2 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:8; /* index into uid table */ + unsigned int guid:8; /* index into guid table */ + unsigned short rdev; +} __attribute__ ((packed)); + +struct squashfs_symlink_inode_header_2 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:8; /* index into uid table */ + unsigned int guid:8; /* index into guid table */ + unsigned short symlink_size; + char symlink[0]; +} __attribute__ ((packed)); + +struct squashfs_reg_inode_header_2 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:8; /* index into uid table */ + unsigned int guid:8; /* index into guid table */ + unsigned int mtime; + unsigned int start_block; + unsigned int fragment; + unsigned int offset; + unsigned int file_size:32; + unsigned short block_list[0]; +} __attribute__ ((packed)); + +struct squashfs_dir_inode_header_2 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:8; /* index into uid table */ + unsigned int guid:8; /* index into guid table */ + unsigned int file_size:19; + unsigned int offset:13; + unsigned int mtime; + unsigned int start_block:24; +} __attribute__ ((packed)); + +struct squashfs_ldir_inode_header_2 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:8; /* index into uid table */ + unsigned int guid:8; /* index into guid table */ + unsigned int file_size:27; + unsigned int offset:13; + unsigned int mtime; + unsigned int start_block:24; + unsigned int i_count:16; + struct squashfs_dir_index_2 index[0]; +} __attribute__ ((packed)); + +union squashfs_inode_header_2 { + struct squashfs_base_inode_header_2 base; + struct squashfs_dev_inode_header_2 dev; + struct squashfs_symlink_inode_header_2 symlink; + struct squashfs_reg_inode_header_2 reg; + struct squashfs_dir_inode_header_2 dir; + struct squashfs_ldir_inode_header_2 ldir; + struct squashfs_ipc_inode_header_2 ipc; +}; + +struct squashfs_dir_header_2 { + unsigned int count:8; + unsigned int start_block:24; +} __attribute__ ((packed)); + +struct squashfs_dir_entry_2 { + unsigned int offset:13; + unsigned int type:3; + unsigned int size:8; + char name[0]; +} __attribute__ ((packed)); + +struct squashfs_fragment_entry_2 { + unsigned int start_block; + unsigned int size; +} __attribute__ ((packed)); + +#define SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\ + SQUASHFS_MEMSET(s, d, n);\ + SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\ + SQUASHFS_SWAP((s)->mode, d, 4, 12);\ + SQUASHFS_SWAP((s)->uid, d, 16, 8);\ + SQUASHFS_SWAP((s)->guid, d, 24, 8);\ + +#define SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, n) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\ +} + +#define SQUASHFS_SWAP_IPC_INODE_HEADER_2(s, d) \ + SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, sizeof(struct squashfs_ipc_inode_header_2)) + +#define SQUASHFS_SWAP_DEV_INODE_HEADER_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ + sizeof(struct squashfs_dev_inode_header_2)); \ + SQUASHFS_SWAP((s)->rdev, d, 32, 16);\ +} + +#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ + sizeof(struct squashfs_symlink_inode_header_2));\ + SQUASHFS_SWAP((s)->symlink_size, d, 32, 16);\ +} + +#define SQUASHFS_SWAP_REG_INODE_HEADER_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ + sizeof(struct squashfs_reg_inode_header_2));\ + SQUASHFS_SWAP((s)->mtime, d, 32, 32);\ + SQUASHFS_SWAP((s)->start_block, d, 64, 32);\ + SQUASHFS_SWAP((s)->fragment, d, 96, 32);\ + SQUASHFS_SWAP((s)->offset, d, 128, 32);\ + SQUASHFS_SWAP((s)->file_size, d, 160, 32);\ +} + +#define SQUASHFS_SWAP_DIR_INODE_HEADER_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ + sizeof(struct squashfs_dir_inode_header_2));\ + SQUASHFS_SWAP((s)->file_size, d, 32, 19);\ + SQUASHFS_SWAP((s)->offset, d, 51, 13);\ + SQUASHFS_SWAP((s)->mtime, d, 64, 32);\ + SQUASHFS_SWAP((s)->start_block, d, 96, 24);\ +} + +#define SQUASHFS_SWAP_LDIR_INODE_HEADER_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ + sizeof(struct squashfs_ldir_inode_header_2));\ + SQUASHFS_SWAP((s)->file_size, d, 32, 27);\ + SQUASHFS_SWAP((s)->offset, d, 59, 13);\ + SQUASHFS_SWAP((s)->mtime, d, 72, 32);\ + SQUASHFS_SWAP((s)->start_block, d, 104, 24);\ + SQUASHFS_SWAP((s)->i_count, d, 128, 16);\ +} + +#define SQUASHFS_SWAP_DIR_INDEX_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index_2));\ + SQUASHFS_SWAP((s)->index, d, 0, 27);\ + SQUASHFS_SWAP((s)->start_block, d, 27, 29);\ + SQUASHFS_SWAP((s)->size, d, 56, 8);\ +} +#define SQUASHFS_SWAP_DIR_HEADER_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header_2));\ + SQUASHFS_SWAP((s)->count, d, 0, 8);\ + SQUASHFS_SWAP((s)->start_block, d, 8, 24);\ +} + +#define SQUASHFS_SWAP_DIR_ENTRY_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry_2));\ + SQUASHFS_SWAP((s)->offset, d, 0, 13);\ + SQUASHFS_SWAP((s)->type, d, 13, 3);\ + SQUASHFS_SWAP((s)->size, d, 16, 8);\ +} + +#define SQUASHFS_SWAP_FRAGMENT_ENTRY_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry_2));\ + SQUASHFS_SWAP((s)->start_block, d, 0, 32);\ + SQUASHFS_SWAP((s)->size, d, 32, 32);\ +} + +#define SQUASHFS_SWAP_FRAGMENT_INDEXES_2(s, d, n) SQUASHFS_SWAP_INTS(s, d, n) + +/* fragment and fragment table defines */ +#define SQUASHFS_FRAGMENT_BYTES_2(A) (A * sizeof(struct squashfs_fragment_entry_2)) + +#define SQUASHFS_FRAGMENT_INDEX_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) / \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_FRAGMENT_INDEX_OFFSET_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) % \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_FRAGMENT_INDEXES_2(A) ((SQUASHFS_FRAGMENT_BYTES_2(A) + \ + SQUASHFS_METADATA_SIZE - 1) / \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_FRAGMENT_INDEX_BYTES_2(A) (SQUASHFS_FRAGMENT_INDEXES_2(A) *\ + sizeof(int)) + +#endif + +#ifdef __KERNEL__ + +/* + * macros used to swap each structure entry, taking into account + * bitfields and different bitfield placing conventions on differing + * architectures + */ + +#include + +#ifdef __BIG_ENDIAN + /* convert from little endian to big endian */ +#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \ + tbits, b_pos) +#else + /* convert from big endian to little endian */ +#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \ + tbits, 64 - tbits - b_pos) +#endif + +#define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\ + b_pos = pos % 8;\ + val = 0;\ + s = (unsigned char *)p + (pos / 8);\ + d = ((unsigned char *) &val) + 7;\ + for(bits = 0; bits < (tbits + b_pos); bits += 8) \ + *d-- = *s++;\ + value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\ +} + +#define SQUASHFS_MEMSET(s, d, n) memset(s, 0, n); + +#endif +#endif --- linux-2.6.28.orig/ubuntu/include/linux/tlsf.h +++ linux-2.6.28/ubuntu/include/linux/tlsf.h @@ -0,0 +1,93 @@ +/* + * Two Levels Segregate Fit memory allocator (TLSF) + * Version 2.3.2 + * + * Written by Miguel Masmano Tello + * + * Thanks to Ismael Ripoll for his suggestions and reviews + * + * Copyright (C) 2007, 2006, 2005, 2004 + * + * This code is released using a dual license strategy: GPL/LGPL + * You can choose the licence that better fits your requirements. + * + * Released under the terms of the GNU General Public License Version 2.0 + * Released under the terms of the GNU Lesser General Public License Version 2.1 + * + * This is kernel port of TLSF allocator. + * Original code can be found at: http://rtportal.upv.es/rtmalloc/ + * - Nitin Gupta (nitingupta910@gmail.com) + */ + +#ifndef _TLSF_H_ +#define _TLSF_H_ + +typedef void* (get_memory)(size_t bytes); +typedef void (put_memory)(void *ptr); + +/** + * tlsf_create_memory_pool - create dynamic memory pool + * @name: name of the pool + * @get_mem: callback function used to expand pool + * @put_mem: callback function used to shrink pool + * @init_size: inital pool size (in bytes) + * @max_size: maximum pool size (in bytes) - set this as 0 for no limit + * @grow_size: amount of memory (in bytes) added to pool whenever required + * + * All size values are rounded up to next page boundary. + */ +extern void *tlsf_create_memory_pool(const char *name, + get_memory get_mem, + put_memory put_mem, + size_t init_size, + size_t max_size, + size_t grow_size); +/** + * tlsf_destory_memory_pool - cleanup given pool + * @mem_pool: Pool to be destroyed + * + * Data structures associated with pool are freed. + * All memory allocated from pool must be freed before + * destorying it. + */ +extern void tlsf_destroy_memory_pool(void *mem_pool); + +/** + * tlsf_malloc - allocate memory from given pool + * @size: no. of bytes + * @mem_pool: pool to allocate from + */ +extern void *tlsf_malloc(size_t size, void *mem_pool); + +/** + * tlsf_calloc - allocate and zero-out memory from given pool + * @size: no. of bytes + * @mem_pool: pool to allocate from + */ +extern void *tlsf_calloc(size_t nelem, size_t elem_size, void *mem_pool); + +/** + * tlsf_free - free memory from given pool + * @ptr: address of memory to be freed + * @mem_pool: pool to free from + */ +extern void tlsf_free(void *ptr, void *mem_pool); + +/** + * tlsf_get_used_size - get memory currently used by given pool + * + * Used memory includes stored data + metadata + internal fragmentation + */ +extern size_t tlsf_get_used_size(void *mem_pool); + +/** + * tlsf_get_total_size - get total memory currently allocated for given pool + * + * This is the total memory currently allocated for this pool which includes + * used size + free size. + * + * (Total - Used) is good indicator of memory efficiency of allocator. + */ +extern size_t tlsf_get_total_size(void *mem_pool); + +#endif --- linux-2.6.28.orig/ubuntu/rfkill/av5100.c +++ linux-2.6.28/ubuntu/rfkill/av5100.c @@ -0,0 +1,174 @@ +/******************************************************************************* + + Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. + + 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. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., 59 + Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + The full GNU General Public License is included in this distribution in the + file called LICENSE. + + Contact Information: + James P. Ketrenos + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +*******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define DRV_NAME "av5100" +#define DRV_VERSION "1.3" +#define DRV_DESCRIPTION "SW RF kill switch for Averatec 5100P" +#define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation" + +static int radio = 1; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) + +MODULE_PARM(radio, "i"); + +#else /* LINUX_VERSION_CODE < 2.6.0 */ + +#include +module_param(radio, int, 1); + +#endif /* LINUX_VERSION_CODE < 2.6.0 */ + +MODULE_PARM_DESC(radio, "controls state of radio (1=on, 0=off)"); + +MODULE_DESCRIPTION(DRV_DESCRIPTION); +MODULE_AUTHOR(DRV_COPYRIGHT); +MODULE_LICENSE("GPL"); + +#define AV5100_RADIO_ON (0xe0) +#define AV5100_RADIO_OFF (0xe1) + +static int av5100_radio = AV5100_RADIO_OFF; + +static void av5100_set_radio(int state) +{ + printk(KERN_INFO DRV_NAME ": Radio being turned %s\n", + (state == AV5100_RADIO_ON) ? "ON" : "OFF"); + outl(0x80020800, 0xcf8); + outb(0x6f, 0x0072); + outl(0x1800ffff, 0x1184); + outb(state, 0x00b2); + av5100_radio = state; +} + + +/* + * proc stuff + */ +static struct proc_dir_entry *dir_base = NULL; + +static int proc_set_radio(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + av5100_set_radio(buffer[0] == '0' ? AV5100_RADIO_OFF : AV5100_RADIO_ON); + + return count; +} + +static int proc_get_radio(char *page, char **start, off_t offset, + int count, int *eof, void *data) +{ + int len = 0; + + len += snprintf(page, count, DRV_NAME ": %d\n", + av5100_radio == AV5100_RADIO_OFF ? 0 : 1); + + *eof = 1; + return len; +} + + +static void av5100_proc_cleanup(void) +{ + if (dir_base) { + remove_proc_entry("radio", dir_base); + remove_proc_entry(DRV_NAME, NULL); + dir_base = NULL; + } +} + + +static int av5100_proc_init(void) +{ + struct proc_dir_entry *ent; + int err = 0; + + dir_base = create_proc_entry(DRV_NAME, S_IFDIR, NULL); + if (dir_base == NULL) { + printk(KERN_ERR DRV_NAME ": Unable to initialise /proc/" + DRV_NAME "\n"); + err = -ENOMEM; + goto fail; + } + + + ent = create_proc_entry("radio", S_IFREG | S_IRUGO | S_IWUSR, + dir_base); + if (ent) { + ent->read_proc = proc_get_radio; + ent->write_proc = proc_set_radio; + } else { + printk(KERN_ERR + "Unable to initialize /proc/" DRV_NAME "/radio\n"); + err = -ENOMEM; + goto fail; + } + + return 0; + + fail: + av5100_proc_cleanup(); + return err; +} + +/* + * module stuff + */ +static int __init av5100_init(void) +{ + av5100_proc_init(); + + av5100_set_radio((radio == 1) ? AV5100_RADIO_ON : AV5100_RADIO_OFF); + + return 0; +} + +static void __exit av5100_exit(void) +{ + av5100_set_radio(AV5100_RADIO_OFF); + + av5100_proc_cleanup(); +} + +module_init(av5100_init); +module_exit(av5100_exit); + +/* + 1 2 3 4 5 6 7 +12345678901234567890123456789012345678901234567890123456789012345678901234567890 +*/ --- linux-2.6.28.orig/ubuntu/rfkill/pbe5.c +++ linux-2.6.28/ubuntu/rfkill/pbe5.c @@ -0,0 +1,205 @@ +/******************************************************************************* + + 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. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., 59 + Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + The full GNU General Public License is included in this distribution in the + file called LICENSE. + + Author: + Pedro Ramalhais + + Based on: + av5100.c from http://ipw2100.sourceforge.net/ + +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "pbe5" +#define DRV_VERSION "1.3" +#define DRV_DESCRIPTION "SW RF kill switch for Packard Bell EasyNote E5" +#define DRV_AUTHOR "Pedro Ramalhais" +#define DRV_LICENSE "GPL" + +static int radio = 1; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) + +MODULE_PARM(radio, "i"); + +#else /* LINUX_VERSION_CODE < 2.6.0 */ + +#include +module_param(radio, int, 1); + +#endif /* LINUX_VERSION_CODE < 2.6.0 */ + +MODULE_PARM_DESC(radio, "controls state of radio (1=on, 0=off)"); + +MODULE_DESCRIPTION(DRV_DESCRIPTION); +MODULE_AUTHOR(DRV_AUTHOR); +MODULE_LICENSE(DRV_LICENSE); + +/* + * NOTE: These values were obtained from disassembling the Icon.exe program + * installed in the Packard Bell EasyNote E5 laptop. The names were guessed, + * so don't rely on them. + */ +#define PBE5_PORT_TOGGLE 0x0b3 +#define PBE5_VALUE_TOGGLE_ON 0x01 +#define PBE5_VALUE_TOGGLE_OFF 0x00 +#define PBE5_PORT_APPLY 0x0b2 +#define PBE5_VALUE_APPLY 0xef + +// Some "booleans" =;-) +#define PBE5_RADIO_OFF 0 +#define PBE5_RADIO_ON 1 + +static int pbe5_radio_status = PBE5_RADIO_ON; + +unsigned char pbe5_get_radio(void) +{ + unsigned char val = 0x00; + + val = inb(PBE5_PORT_TOGGLE); + + return val; +} + +static void pbe5_set_radio(int state_set) +{ + pbe5_radio_status = pbe5_get_radio(); + + if (pbe5_radio_status != state_set) { + // Set the radio toggle register + outb(PBE5_VALUE_TOGGLE_ON, PBE5_PORT_TOGGLE); + // Commit the radio toggle register value + outb(PBE5_VALUE_APPLY, PBE5_PORT_APPLY); + // Update the radio status + pbe5_radio_status = pbe5_get_radio(); + + printk(KERN_INFO DRV_NAME ": Radio turned %s\n", + (state_set == PBE5_RADIO_ON) ? "ON" : "OFF"); + } else { + printk(KERN_INFO DRV_NAME ": Radio already %s\n", + (state_set == PBE5_RADIO_ON) ? "ON" : "OFF"); + } +} + + +/* + * proc stuff + */ +static struct proc_dir_entry *dir_base = NULL; + +static int proc_set_radio(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + pbe5_set_radio(buffer[0] == '0' ? PBE5_RADIO_OFF : PBE5_RADIO_ON); + + return count; +} + +static int proc_get_radio(char *page, char **start, off_t offset, + int count, int *eof, void *data) +{ + int len = 0; + + len += snprintf(page, count, DRV_NAME ": %d\n", + pbe5_radio_status == PBE5_RADIO_OFF ? 0 : 1); + + *eof = 1; + return len; +} + + +static void pbe5_proc_cleanup(void) +{ + if (dir_base) { + remove_proc_entry("radio", dir_base); + remove_proc_entry(DRV_NAME, NULL); + dir_base = NULL; + } +} + + +static int pbe5_proc_init(void) +{ + struct proc_dir_entry *ent; + int err = 0; + + dir_base = create_proc_entry(DRV_NAME, S_IFDIR, NULL); + if (dir_base == NULL) { + printk(KERN_ERR DRV_NAME ": Unable to initialise /proc/" + DRV_NAME "\n"); + err = -ENOMEM; + goto fail; + } + + + ent = create_proc_entry("radio", S_IFREG | S_IRUGO | S_IWUSR, + dir_base); + if (ent) { + ent->read_proc = proc_get_radio; + ent->write_proc = proc_set_radio; + } else { + printk(KERN_ERR + "Unable to initialize /proc/" DRV_NAME "/radio\n"); + err = -ENOMEM; + goto fail; + } + + return 0; + + fail: + pbe5_proc_cleanup(); + return err; +} + +/* + * module stuff + */ +static int __init pbe5_init(void) +{ + pbe5_proc_init(); + + pbe5_set_radio((radio == 1) ? PBE5_RADIO_ON : PBE5_RADIO_OFF); + + return 0; +} + +static void __exit pbe5_exit(void) +{ + pbe5_set_radio(PBE5_RADIO_OFF); + + pbe5_proc_cleanup(); +} + +module_init(pbe5_init); +module_exit(pbe5_exit); + +/* + 1 2 3 4 5 6 7 +12345678901234567890123456789012345678901234567890123456789012345678901234567890 +*/ --- linux-2.6.28.orig/ubuntu/rfkill/Kconfig +++ linux-2.6.28/ubuntu/rfkill/Kconfig @@ -0,0 +1,7 @@ +config AVERATEC_5100P + tristate "Software kill switch for Averatec 5100P" + default m + +config PACKARDBELL_E5 + tristate "Software kill switch for Packard Bell EasyNote E5" + default m --- linux-2.6.28.orig/ubuntu/rfkill/Makefile +++ linux-2.6.28/ubuntu/rfkill/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for Ubuntu additional drivers +# + +obj-$(CONFIG_AVERATEC_5100P) += av5100.o +obj-$(CONFIG_PACKARDBELL_E5) += pbe5.o --- linux-2.6.28.orig/ubuntu/rfkill/BOM +++ linux-2.6.28/ubuntu/rfkill/BOM @@ -0,0 +1,6 @@ +Downloaded from: http://sourceforge.net/project/showfiles.php?group_id=108766 +Current Version: 1.3 +Comments: + +Had to change &proc_root to NULL due to changes in create/remove proc +entry usage. --- linux-2.6.28.orig/ubuntu/dm-raid4-5/dm-region_hash.h +++ linux-2.6.28/ubuntu/dm-raid4-5/dm-region_hash.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2003 Sistina Software Limited. + * Copyright (C) 2004-2007 Red Hat Inc. + * + * This file is released under the GPL. + */ + +#ifndef DM_RH_H +#define DM_RH_H + +#include "dm.h" +#include +#include "dm-bio-list.h" + +/*----------------------------------------------------------------- + * Region hash + *----------------------------------------------------------------*/ + +/* + * States a region can have. + */ +enum { + RH_CLEAN = 0x01, /* No writes in flight. */ + RH_DIRTY = 0x02, /* Writes in flight. */ + RH_NOSYNC = 0x04, /* Out of sync. */ + RH_RECOVERING = 0x08, /* Under resynchronization. */ + RH_ERROR = 0x10, /* Error recovering region */ +}; + +/* + * Conversion fns + */ +region_t rh_bio_to_region(void *rh, struct bio *bio); +region_t rh_sector_to_region(void *rh, sector_t sector); +sector_t rh_region_to_sector(void *rh, region_t region); + + +/* + * Functions to set a caller context in a region. + */ +void *rh_reg_get_context(void *reg); +void rh_reg_set_context(void *reg, void *context); + +/* + * Reagion hash and region parameters. + */ +region_t rh_get_region_size(void *rh); +sector_t rh_get_region_key(void *reg); + +int rh_init(void **rh, + unsigned int max_recovery, + void (*dispatch)(void *dispatch_context, struct bio_list *bios), + void *dispatch_context, + void (*wake)(void *wake_context), + void *wake_context, + struct dm_dirty_log *log, uint32_t region_size, region_t nr_regions); +void rh_exit(void *rh); + +int rh_state(void *rh, region_t region, int may_block); +void rh_update_states(void *rh); +void rh_flush(void *rh); + +void rh_inc(void *rh, region_t region); +void rh_inc_pending(void *rh, struct bio_list *bios); +void rh_dec(void *rh, region_t region); +void rh_delay(void *rh, struct bio *bio); +void rh_delay_by_region(void *rh, struct bio *bio, region_t region); + +int rh_recovery_prepare(void *rh); +void *rh_recovery_start(void *rh); +void rh_recovery_end(void *reg, int error); +void rh_stop_recovery(void *rh); +void rh_start_recovery(void *rh); + +#endif --- linux-2.6.28.orig/ubuntu/dm-raid4-5/dm-raid4-5.h +++ linux-2.6.28/ubuntu/dm-raid4-5/dm-raid4-5.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2006 Red Hat GmbH + * + * Module Author: Heinz Mauelshagen (Mauelshagen@RedHat.com) + * + * This file is released under the GPL. + * + */ + +#ifndef _DM_RAID45_H +#define _DM_RAID45_H + +/* Factor out to dm.h! */ +#define STR_LEN(ptr, str) ptr, str, strlen(ptr) + +enum lock_type { RAID45_EX, RAID45_SHARED }; + +struct dmraid45_locking_type { + /* Request a lock on a stripe. */ + void* (*lock)(sector_t key, enum lock_type type); + + /* Release a lock on a stripe. */ + void (*unlock)(void *lock_handle); + +}; + +#endif --- linux-2.6.28.orig/ubuntu/dm-raid4-5/dm-message.h +++ linux-2.6.28/ubuntu/dm-raid4-5/dm-message.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2007 Red Hat GmbH + * + * Module Author: Heinz Mauelshagen + * + * This file is released under the GPL. + * + */ + +#ifndef DM_MESSAGE_H +#define DM_MESSAGE_H + +/* Factor out to dm.h. */ +/* Reference to array end. */ +#define ARRAY_END(a) ((a) + ARRAY_SIZE(a)) + +/* Message return bits. */ +enum dm_message_return { + dm_msg_ret_ambiguous, /* Action ambiguous. */ + dm_msg_ret_inval, /* Action invalid. */ + dm_msg_ret_undef, /* Action undefined. */ + + dm_msg_ret_option, /* Option error. */ + dm_msg_ret_arg, /* Argument error. */ + dm_msg_ret_argcount, /* Argument count error. */ +}; + +/* Message argument type conversions. */ +enum dm_message_argument_type { + dm_msg_base_t, /* Basename string. */ + dm_msg_str_t, /* String. */ + dm_msg_int_t, /* Signed int. */ + dm_msg_uint_t, /* Unsigned int. */ + dm_msg_uint64_t, /* Unsigned int 64. */ +}; + +/* A message option. */ +struct dm_message_option { + unsigned num_options; + char **options; + unsigned long *actions; +}; + +/* Message arguments and types. */ +struct dm_message_argument { + unsigned num_args; + unsigned long **ptr; + enum dm_message_argument_type types[]; +}; + +/* Client message. */ +struct dm_msg { + unsigned long action; /* Identified action. */ + unsigned long ret; /* Return bits. */ + unsigned num_specs; /* # of sepcifications listed. */ + struct dm_msg_spec *specs; /* Specification list. */ + struct dm_msg_spec *spec; /* Specification selected. */ +}; + +/* Secification of the message. */ +struct dm_msg_spec { + const char *cmd; /* Name of the command (i.e. 'bandwidth'). */ + unsigned long action; + struct dm_message_option *options; + struct dm_message_argument *args; + unsigned long parm; /* Parameter to pass through to callback. */ + /* Function to process for action. */ + int (*f) (struct dm_msg *msg, void *context); +}; + +/* Parameter access macros. */ +#define DM_MSG_PARM(msg) ((msg)->spec->parm) + +#define DM_MSG_STR_ARGS(msg, idx) ((char*) *(msg)->spec->args->ptr[idx]) +#define DM_MSG_INT_ARGS(msg, idx) ((int) *(msg)->spec->args->ptr[idx]) +#define DM_MSG_UINT_ARGS(msg, idx) ((unsigned) DM_MSG_INT_ARG(msg, idx)) +#define DM_MSG_UINT64_ARGS(msg, idx) ((uint64_t) *(msg)->spec->args->ptr[idx]) + +#define DM_MSG_STR_ARG(msg) DM_MSG_STR_ARGS(msg, 0) +#define DM_MSG_INT_ARG(msg) DM_MSG_INT_ARGS(msg, 0) +#define DM_MSG_UINT_ARG(msg) DM_MSG_UINT_ARGS(msg, 0) +#define DM_MSG_UINT64_ARG(msg) DM_MSG_UINT64_ARGS(msg, 0) + + +/* Parse a message and its options and optionally call a function back. */ +int dm_message_parse(const char *caller, struct dm_msg *msg, void *context, + int argc, char **argv); + +#endif --- linux-2.6.28.orig/ubuntu/dm-raid4-5/dm-mem-cache.c +++ linux-2.6.28/ubuntu/dm-raid4-5/dm-mem-cache.c @@ -0,0 +1,292 @@ +/* + * Copyright (C) 2006,2007 Red Hat GmbH + * + * Module Author: Heinz Mauelshagen + * + * Allocate/free total_pages to a per client page pool. + * Allocate/free memory objects with chunks (1..n) of pages_per_chunk pages + * hanging off. + * + * This file is released under the GPL. + */ + +#define DM_MEM_CACHE_VERSION "0.2" + +#include "dm.h" +#include +#include "dm-mem-cache.h" + +struct dm_mem_cache_client { + spinlock_t lock; + mempool_t *objs_pool; + struct page_list *free_list; + unsigned objects; + unsigned chunks; + unsigned free_pages; + unsigned total_pages; +}; + +/* + * Free pages and page_list elements of client. + */ +static void free_cache_pages(struct page_list *list) +{ + while (list) { + struct page_list *pl = list; + + list = pl->next; + BUG_ON(!pl->page); + __free_page(pl->page); + kfree(pl); + } +} + +/* + * Alloc number of pages and page_list elements as required by client. + */ +static struct page_list *alloc_cache_pages(unsigned pages) +{ + struct page_list *pl, *ret = NULL; + struct page *page; + + while (pages--) { + page = alloc_page(GFP_NOIO); + if (!page) + goto err; + + pl = kmalloc(sizeof(*pl), GFP_NOIO); + if (!pl) { + __free_page(page); + goto err; + } + + pl->page = page; + pl->next = ret; + ret = pl; + } + + return ret; + + err: + free_cache_pages(ret); + return NULL; +} + +/* + * Allocate page_list elements from the pool to chunks of the mem object + */ +static void alloc_chunks(struct dm_mem_cache_client *cl, + struct dm_mem_cache_object *obj, + unsigned pages_per_chunk) +{ + unsigned chunks = cl->chunks; + unsigned long flags; + + local_irq_save(flags); + local_irq_disable(); + while (chunks--) { + unsigned p = pages_per_chunk; + + obj[chunks].pl = NULL; + + while (p--) { + struct page_list *pl; + + /* Take next element from free list */ + spin_lock(&cl->lock); + pl = cl->free_list; + BUG_ON(!pl); + cl->free_list = pl->next; + spin_unlock(&cl->lock); + + pl->next = obj[chunks].pl; + obj[chunks].pl = pl; + } + } + + local_irq_restore(flags); +} + +/* + * Free page_list elements putting them back onto free list + */ +static void free_chunks(struct dm_mem_cache_client *cl, + struct dm_mem_cache_object *obj) +{ + unsigned chunks = cl->chunks; + unsigned long flags; + struct page_list *next, *pl; + + local_irq_save(flags); + local_irq_disable(); + while (chunks--) { + for (pl = obj[chunks].pl; pl; pl = next) { + next = pl->next; + + spin_lock(&cl->lock); + pl->next = cl->free_list; + cl->free_list = pl; + cl->free_pages++; + spin_unlock(&cl->lock); + } + } + + local_irq_restore(flags); +} + +/* + * Create/destroy dm memory cache client resources. + */ +struct dm_mem_cache_client * +dm_mem_cache_client_create(unsigned total_pages, unsigned objects, + unsigned chunks) +{ + struct dm_mem_cache_client *client; + + client = kzalloc(sizeof(*client), GFP_KERNEL); + if (!client) + return ERR_PTR(-ENOMEM); + + client->objs_pool = mempool_create_kmalloc_pool(objects, chunks * sizeof(struct dm_mem_cache_object)); + if (!client->objs_pool) + goto err; + + client->free_list = alloc_cache_pages(total_pages); + if (!client->free_list) + goto err1; + + spin_lock_init(&client->lock); + client->objects = objects; + client->chunks = chunks; + client->free_pages = client->total_pages = total_pages; + return client; + + err1: + mempool_destroy(client->objs_pool); + err: + kfree(client); + return ERR_PTR(-ENOMEM); +} + +void dm_mem_cache_client_destroy(struct dm_mem_cache_client *cl) +{ + BUG_ON(cl->free_pages != cl->total_pages); + free_cache_pages(cl->free_list); + mempool_destroy(cl->objs_pool); + kfree(cl); +} + +/* + * Grow a clients cache by an amount of pages. + * + * Don't call from interrupt context! + */ +int dm_mem_cache_grow(struct dm_mem_cache_client *cl, + unsigned pages_per_chunk) +{ + unsigned pages = cl->chunks * pages_per_chunk; + struct page_list *pl = alloc_cache_pages(pages), *last = pl; + + if (!pl) + return -ENOMEM; + + while (last->next) + last = last->next; + + spin_lock_irq(&cl->lock); + last->next = cl->free_list; + cl->free_list = pl; + cl->free_pages += pages; + cl->total_pages += pages; + cl->objects++; + spin_unlock_irq(&cl->lock); + + mempool_resize(cl->objs_pool, cl->objects, GFP_NOIO); + return 0; +} + +/* Shrink a clients cache by an amount of pages */ +int dm_mem_cache_shrink(struct dm_mem_cache_client *cl, + unsigned pages_per_chunk) +{ + int r = 0; + unsigned pages = cl->chunks * pages_per_chunk, p = pages; + unsigned long flags; + struct page_list *last = NULL, *pl, *pos; + + spin_lock_irqsave(&cl->lock, flags); + pl = pos = cl->free_list; + while (p-- && pos->next) { + last = pos; + pos = pos->next; + } + + if (++p) + r = -ENOMEM; + else { + cl->free_list = pos; + cl->free_pages -= pages; + cl->total_pages -= pages; + cl->objects--; + last->next = NULL; + } + spin_unlock_irqrestore(&cl->lock, flags); + + if (!r) { + free_cache_pages(pl); + mempool_resize(cl->objs_pool, cl->objects, GFP_NOIO); + } + + return r; +} + +/* + * Allocate/free a memory object + * + * Can be called from interrupt context + */ +struct dm_mem_cache_object *dm_mem_cache_alloc(struct dm_mem_cache_client *cl, + unsigned pages_per_chunk) +{ + int r = 0; + unsigned pages = cl->chunks * pages_per_chunk; + unsigned long flags; + struct dm_mem_cache_object *obj; + + obj = mempool_alloc(cl->objs_pool, GFP_NOIO); + if (!obj) + return ERR_PTR(-ENOMEM); + + spin_lock_irqsave(&cl->lock, flags); + if (pages > cl->free_pages) + r = -ENOMEM; + else + cl->free_pages -= pages; + spin_unlock_irqrestore(&cl->lock, flags); + + if (r) { + mempool_free(obj, cl->objs_pool); + return ERR_PTR(r); + } + + alloc_chunks(cl, obj, pages_per_chunk); + return obj; +} + +void dm_mem_cache_free(struct dm_mem_cache_client *cl, + struct dm_mem_cache_object *obj) +{ + free_chunks(cl, obj); + mempool_free(obj, cl->objs_pool); +} + +EXPORT_SYMBOL(dm_mem_cache_client_create); +EXPORT_SYMBOL(dm_mem_cache_client_destroy); +EXPORT_SYMBOL(dm_mem_cache_alloc); +EXPORT_SYMBOL(dm_mem_cache_free); +EXPORT_SYMBOL(dm_mem_cache_grow); +EXPORT_SYMBOL(dm_mem_cache_shrink); + +MODULE_DESCRIPTION(DM_NAME " dm memory cache"); +MODULE_AUTHOR("Heinz Mauelshagen "); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/ubuntu/dm-raid4-5/Kconfig +++ linux-2.6.28/ubuntu/dm-raid4-5/Kconfig @@ -0,0 +1,6 @@ +config DM_RAID45 + tristate "RAID 4/5 target (EXPERIMENTAL)" + depends on BLK_DEV_DM && EXPERIMENTAL + default m + ---help--- + A target that supports RAID4 and RAID5 mappings. --- linux-2.6.28.orig/ubuntu/dm-raid4-5/Makefile +++ linux-2.6.28/ubuntu/dm-raid4-5/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS += -I$(srctree)/drivers/md + +obj-$(CONFIG_DM_RAID45) += dm-raid4-5.o dm-mem-cache.o dm-region_hash.o dm-message.o --- linux-2.6.28.orig/ubuntu/dm-raid4-5/dm-region_hash.c +++ linux-2.6.28/ubuntu/dm-raid4-5/dm-region_hash.c @@ -0,0 +1,643 @@ +/* + * Copyright (C) 2003 Sistina Software Limited. + * Copyright (C) 2004-2007 Red Hat Inc. + * + * This file is released under the GPL. + */ + +#include "dm.h" +#include +#include "dm-region_hash.h" + +#include +#include +#include +#include + +#define DM_MSG_PREFIX "region hash" + +/*----------------------------------------------------------------- + * Region hash + * + * The set splits itself up into discrete regions. + * Each region can be in one of three states: + * + * o clean + * o dirty, + * o nosync. + * + * There is no need to put clean regions in the hash. + * + * + * In addition to being present in the hash table a region _may_ + * be present on one of three lists. + * + * clean_regions: Regions on this list have no io pending to + * them, they are in sync, we are no longer interested in them, + * they are dull. rh_update_states() will remove them from the + * hash table. + * + * quiesced_regions: These regions have been spun down, ready + * for recovery. rh_recovery_start() will remove regions from + * this list and hand them to kmirrord, which will schedule the + * recovery io with kcopyd. + * + * recovered_regions: Regions that kcopyd has successfully + * recovered. rh_update_states() will now schedule any delayed + * io, up the recovery_count, and remove the region from the hash. + * + * There are 2 locks: + * A rw spin lock 'hash_lock' protects just the hash table, + * this is never held in write mode from interrupt context, + * which I believe means that we only have to disable irqs when + * doing a write lock. + * + * An ordinary spin lock 'region_lock' that protects the three + * lists in the region_hash, with the 'state', 'list' and + * 'delayed_bios' fields of the regions. This is used from irq + * context, so all other uses will have to suspend local irqs. + *---------------------------------------------------------------*/ +enum region_hash_flags { + RECOVERY, +}; + +struct region_hash { + unsigned int max_recovery; /* Max # of regions to recover in parallel */ + unsigned long flags; + + /* Callback function to dispatch queued writes on recovered regions. */ + void (*dispatch)(void *context, struct bio_list *bios); + void *dispatch_context; + + /* Callback function to wakeup callers worker thread. */ + void (*wake)(void *context); + void *wake_context; + + uint32_t region_size; + unsigned int region_shift; + + /* holds persistent region state */ + struct dm_dirty_log *log; + + /* hash table */ + rwlock_t hash_lock; + mempool_t *region_pool; + unsigned int mask; + unsigned int nr_buckets; + unsigned int prime; + unsigned int shift; + struct list_head *buckets; + + spinlock_t region_lock; + struct semaphore recovery_count; + struct list_head clean_regions; + struct list_head quiesced_regions; + struct list_head recovered_regions; +}; + +struct region { + struct region_hash *rh; /* FIXME: can we get rid of this ? */ + region_t key; + int state; + void *context; /* Caller context. */ + + struct list_head hash_list; + struct list_head list; + + atomic_t pending; + struct bio_list delayed_bios; +}; + +/* + * Conversion fns + */ +region_t rh_sector_to_region(void *rh, sector_t sector) +{ + return sector >> ((struct region_hash*) rh)->region_shift; +} + +region_t rh_bio_to_region(void *rh, struct bio *bio) +{ + return rh_sector_to_region(rh, bio->bi_sector); +} + +sector_t rh_region_to_sector(void *rh, region_t region) +{ + return region << ((struct region_hash*) rh)->region_shift; +} + +/* + * Retrival fns. + */ +region_t rh_get_region_key(void *reg) +{ + return ((struct region *)reg)->key; +} + +sector_t rh_get_region_size(void *rh) +{ + return ((struct region_hash *)rh)->region_size; +} + +/* Squirrel a context with a region. */ +void *rh_reg_get_context(void *reg) +{ + return ((struct region*) reg)->context; +} + +void rh_reg_set_context(void *reg, void *context) +{ + ((struct region*) reg)->context = context; +} + +/* + * Region struct allocation/free. + */ +static void *region_alloc(unsigned int gfp_mask, void *pool_data) +{ + return kmalloc(sizeof(struct region), gfp_mask); +} + +static void region_free(void *element, void *pool_data) +{ + kfree(element); +} + +#define MIN_REGIONS 64 +int rh_init(void **region_hash, + unsigned int max_recovery, + + void (*dispatch)(void *dispatch_context, struct bio_list *bios), + void *dispatch_context, + void (*wake)(void *wake_context), + void *wake_context, + struct dm_dirty_log *log, uint32_t region_size, region_t nr_regions) +{ + unsigned int nr_buckets, max_buckets; + unsigned hash_primes[] = { + /* Table of primes for rh_hash/table size optimization. */ + 3, 7, 13, 27, 53, 97, 193, 389, 769, + 1543, 3079, 6151, 12289, 24593, + }; + size_t i; + struct region_hash *rh; + + if (region_size & (region_size - 1)) { + DMERR("region size must be 2^^n"); + return -EINVAL; + } + + rh = kmalloc(sizeof(*rh), GFP_KERNEL); + if (!rh) { + DMERR("unable to allocate region hash memory"); + return -ENOMEM; + } + + rh->max_recovery = max_recovery; + rh->dispatch = dispatch; + rh->dispatch_context = dispatch_context; + rh->wake = wake; + rh->wake_context = wake_context; + rh->log = log; + rh->region_size = region_size; + rh->region_shift = ffs(region_size) - 1; + rwlock_init(&rh->hash_lock); + + /* Calculate a suitable number of buckets for our hash table. */ + max_buckets = nr_regions >> 6; + for (nr_buckets = 128u; nr_buckets < max_buckets; nr_buckets <<= 1); + nr_buckets >>= 1; + rh->mask = rh->nr_buckets = nr_buckets; + rh->mask--; + rh->shift = ffs(nr_buckets); + rh->prime = hash_primes[rh->shift - 1]; + if (rh->prime > ARRAY_SIZE(hash_primes) - 2) + rh->prime = ARRAY_SIZE(hash_primes) - 1; + + rh->buckets = vmalloc(nr_buckets * sizeof(*rh->buckets)); + if (!rh->buckets) { + DMERR("unable to allocate region hash bucket memory"); + vfree(rh); + return -ENOMEM; + } + + for (i = 0; i < nr_buckets; i++) + INIT_LIST_HEAD(rh->buckets + i); + + spin_lock_init(&rh->region_lock); + sema_init(&rh->recovery_count, 0); + INIT_LIST_HEAD(&rh->clean_regions); + INIT_LIST_HEAD(&rh->quiesced_regions); + INIT_LIST_HEAD(&rh->recovered_regions); + + rh->region_pool = mempool_create(MIN_REGIONS, region_alloc, + region_free, NULL); + if (!rh->region_pool) { + vfree(rh->buckets); + vfree(rh); + return -ENOMEM; + } + + *region_hash = rh; + + return 0; +} + +void rh_exit(void *v) +{ + unsigned int h; + struct region *reg, *tmp; + struct region_hash *rh = v; + + BUG_ON(!list_empty(&rh->quiesced_regions)); + + for (h = 0; h < rh->nr_buckets; h++) { + list_for_each_entry_safe(reg, tmp, rh->buckets + h, hash_list) { + BUG_ON(atomic_read(®->pending)); + mempool_free(reg, rh->region_pool); + } + } + + dm_dirty_log_destroy(rh->log); + + if (rh->region_pool) + mempool_destroy(rh->region_pool); + + vfree(rh->buckets); + kfree(rh); +} + +static inline unsigned int rh_hash(struct region_hash *rh, region_t region) +{ + return (unsigned int) ((region * rh->prime) >> rh->shift) & rh->mask; +} + +static struct region *__rh_lookup(struct region_hash *rh, region_t region) +{ + struct region *reg; + struct list_head *bucket = rh->buckets + rh_hash(rh, region); + + list_for_each_entry(reg, bucket, hash_list) { + if (reg->key == region) + return reg; + } + + return NULL; +} + +static void __rh_insert(struct region_hash *rh, struct region *reg) +{ + unsigned int h = rh_hash(rh, reg->key); + list_add(®->hash_list, rh->buckets + h); +} + +static struct region *__rh_alloc(struct region_hash *rh, region_t region) +{ + struct region *reg, *nreg; + + read_unlock(&rh->hash_lock); + + nreg = mempool_alloc(rh->region_pool, GFP_NOIO); + nreg->state = rh->log->type->in_sync(rh->log, region, 1) ? + RH_CLEAN : RH_NOSYNC; + nreg->rh = rh; + nreg->key = region; + + INIT_LIST_HEAD(&nreg->list); + + atomic_set(&nreg->pending, 0); + bio_list_init(&nreg->delayed_bios); + + write_lock_irq(&rh->hash_lock); + + reg = __rh_lookup(rh, region); + if (reg) + /* we lost the race */ + mempool_free(nreg, rh->region_pool); + else { + __rh_insert(rh, nreg); + if (nreg->state == RH_CLEAN) { + spin_lock(&rh->region_lock); + list_add(&nreg->list, &rh->clean_regions); + spin_unlock(&rh->region_lock); + } + reg = nreg; + } + + write_unlock_irq(&rh->hash_lock); + read_lock(&rh->hash_lock); + + return reg; +} + +static inline struct region *__rh_find(struct region_hash *rh, region_t region) +{ + struct region *reg; + + reg = __rh_lookup(rh, region); + if (!reg) + reg = __rh_alloc(rh, region); + + return reg; +} + +int rh_state(void *v, region_t region, int may_block) +{ + int r = 0; + struct region *reg; + struct region_hash *rh = v; + + read_lock(&rh->hash_lock); + reg = __rh_lookup(rh, region); + if (reg) + r = reg->state; + read_unlock(&rh->hash_lock); + + if (r) + return r; + + /* + * The region wasn't in the hash, so we fall back to the dirty log. + */ + r = rh->log->type->in_sync(rh->log, region, may_block); + + /* + * Any error from the dirty log (eg. -EWOULDBLOCK) gets + * taken as a RH_NOSYNC + */ + return r == 1 ? RH_CLEAN : RH_NOSYNC; +} + +void rh_update_states(void *v) +{ + struct region *reg, *next; + struct region_hash *rh = v; + LIST_HEAD(clean); + LIST_HEAD(recovered); + + /* + * Quickly grab the lists. + */ + write_lock_irq(&rh->hash_lock); + spin_lock(&rh->region_lock); + if (!list_empty(&rh->clean_regions)) { + list_splice(&rh->clean_regions, &clean); + INIT_LIST_HEAD(&rh->clean_regions); + + list_for_each_entry(reg, &clean, list) + list_del(®->hash_list); + } + + if (!list_empty(&rh->recovered_regions)) { + list_splice(&rh->recovered_regions, &recovered); + INIT_LIST_HEAD(&rh->recovered_regions); + + list_for_each_entry(reg, &recovered, list) + list_del(®->hash_list); + } + + spin_unlock(&rh->region_lock); + write_unlock_irq(&rh->hash_lock); + + /* + * All the regions on the recovered and clean lists have + * now been pulled out of the system, so no need to do + * any more locking. + */ + list_for_each_entry_safe (reg, next, &recovered, list) { + if (reg->state != RH_ERROR) + rh->log->type->clear_region(rh->log, reg->key); + + rh->log->type->set_region_sync(rh->log, reg->key, + reg->state != RH_ERROR); + up(&rh->recovery_count); + if (reg->delayed_bios.head) + rh->dispatch(rh->dispatch_context, ®->delayed_bios); + + mempool_free(reg, rh->region_pool); + } + + list_for_each_entry_safe(reg, next, &clean, list) { + rh->log->type->clear_region(rh->log, reg->key); + mempool_free(reg, rh->region_pool); + } + + rh_flush(rh); +} + +void rh_inc(void *v, region_t region) +{ + struct region *reg; + struct region_hash *rh = v; + + read_lock(&rh->hash_lock); + reg = __rh_find(rh, region); + if (reg->state == RH_CLEAN) { + rh->log->type->mark_region(rh->log, reg->key); + + spin_lock_irq(&rh->region_lock); + reg->state = RH_DIRTY; + list_del_init(®->list); /* Take off the clean list. */ + spin_unlock_irq(&rh->region_lock); + } + + atomic_inc(®->pending); + read_unlock(&rh->hash_lock); +} + +void rh_inc_pending(void *v, struct bio_list *bios) +{ + struct bio *bio; + struct region_hash *rh = v; + + for (bio = bios->head; bio; bio = bio->bi_next) + rh_inc(rh, rh_bio_to_region(rh, bio)); +} + +void rh_dec(void *v, region_t region) +{ + unsigned long flags; + struct region *reg; + struct region_hash *rh = v; + + read_lock(&rh->hash_lock); + reg = __rh_lookup(rh, region); + read_unlock(&rh->hash_lock); + + BUG_ON(!reg); + + if (atomic_dec_and_test(®->pending)) { + spin_lock_irqsave(&rh->region_lock, flags); + if (reg->state == RH_RECOVERING) { + list_add_tail(®->list, &rh->quiesced_regions); + } else { + reg->state = RH_CLEAN; + list_add(®->list, &rh->clean_regions); + } + spin_unlock_irqrestore(&rh->region_lock, flags); + } +} + +/* + * Starts quiescing a region in preparation for recovery. + */ +static int __rh_recovery_prepare(struct region_hash *rh) +{ + int r; + struct region *reg; + region_t region; + + /* + * Ask the dirty log what's next. + */ + r = rh->log->type->get_resync_work(rh->log, ®ion); + if (r <= 0) + return r; + + /* + * Get this region, and start it quiescing + * by setting the recovering flag. + */ + read_lock(&rh->hash_lock); + reg = __rh_find(rh, region); + read_unlock(&rh->hash_lock); + + spin_lock_irq(&rh->region_lock); + + reg->state = RH_RECOVERING; + + /* Already quiesced ? */ + list_del_init(®->list); + if (!atomic_read(®->pending)) + list_add(®->list, &rh->quiesced_regions); + + spin_unlock_irq(&rh->region_lock); + + return 1; +} + +int rh_recovery_prepare(void *v) +{ + struct region_hash *rh = v; + + if (test_bit(RECOVERY, &rh->flags)) { + while (!down_trylock(&rh->recovery_count)) { + if (__rh_recovery_prepare(rh) <= 0) { + up(&rh->recovery_count); + return -ENOENT; + } + } + } + + return 0; +} + +/* + * Returns any quiesced regions. + */ +void *rh_recovery_start(void *v) +{ + struct region *reg = NULL; + struct region_hash *rh = v; + + spin_lock_irq(&rh->region_lock); + if (!list_empty(&rh->quiesced_regions)) { + reg = list_entry(rh->quiesced_regions.next, + struct region, list); + list_del_init(®->list); /* Remove from the quiesced list. */ + } + spin_unlock_irq(&rh->region_lock); + + return (void*) reg; +} + +/* + * Put region on list of recovered ones. + */ +void rh_recovery_end(void *v, int error) +{ + struct region *reg = v; + struct region_hash *rh = reg->rh; + + if (error) + reg->state = RH_ERROR; + + spin_lock_irq(&rh->region_lock); + list_add(®->list, &rh->recovered_regions); + spin_unlock_irq(&rh->region_lock); +} + +void rh_flush(void *v) +{ + struct region_hash *rh = v; + + rh->log->type->flush(rh->log); +} + +void rh_delay_by_region(void *v, struct bio *bio, region_t region) +{ + struct region_hash *rh = v; + struct region *reg; + + read_lock(&rh->hash_lock); + reg = __rh_find(rh, region); + bio_list_add(®->delayed_bios, bio); + read_unlock(&rh->hash_lock); +} + +void rh_delay(void *v, struct bio *bio) +{ + return rh_delay_by_region(v, bio, rh_bio_to_region(v, bio)); +} + +void rh_stop_recovery(void *v) +{ + int i; + struct region_hash *rh = v; + + clear_bit(RECOVERY, &rh->flags); + rh->wake(rh->wake_context); + + /* wait for any recovering regions */ + for (i = 0; i < rh->max_recovery; i++) + down(&rh->recovery_count); +} + +void rh_start_recovery(void *v) +{ + int i; + struct region_hash *rh = v; + + set_bit(RECOVERY, &rh->flags); + for (i = 0; i < rh->max_recovery; i++) + up(&rh->recovery_count); + + rh->wake(rh->wake_context); +} + +EXPORT_SYMBOL(rh_bio_to_region); +EXPORT_SYMBOL(rh_sector_to_region); +EXPORT_SYMBOL(rh_region_to_sector); +EXPORT_SYMBOL(rh_init); +EXPORT_SYMBOL(rh_exit); +EXPORT_SYMBOL(rh_state); +EXPORT_SYMBOL(rh_update_states); +EXPORT_SYMBOL(rh_flush); +EXPORT_SYMBOL(rh_inc); +EXPORT_SYMBOL(rh_inc_pending); +EXPORT_SYMBOL(rh_dec); +EXPORT_SYMBOL(rh_delay); +EXPORT_SYMBOL(rh_delay_by_region); +EXPORT_SYMBOL(rh_recovery_prepare); +EXPORT_SYMBOL(rh_recovery_start); +EXPORT_SYMBOL(rh_recovery_end); +EXPORT_SYMBOL(rh_stop_recovery); +EXPORT_SYMBOL(rh_start_recovery); +EXPORT_SYMBOL(rh_reg_get_context); +EXPORT_SYMBOL(rh_reg_set_context); +EXPORT_SYMBOL(rh_get_region_key); +EXPORT_SYMBOL(rh_get_region_size); + +MODULE_DESCRIPTION(DM_NAME " region hash"); +MODULE_AUTHOR("Heinz Mauelshagen "); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/ubuntu/dm-raid4-5/dm-mem-cache.h +++ linux-2.6.28/ubuntu/dm-raid4-5/dm-mem-cache.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2006,2007 Red Hat GmbH + * + * Module Author: Heinz Mauelshagen + * + * Allocate/free total_pages to a per client page pool. + * Allocate/free memory objects with chunks (1..n) of pages_per_chunk pages + * hanging off. + * + * This file is released under the GPL. + */ + +#ifndef _DM_MEM_CACHE_H +#define _DM_MEM_CACHE_H + +#define DM_MEM_CACHE_H_VERSION "0.1" + +#include "dm.h" + +static inline struct page_list *pl_elem(struct page_list *pl, unsigned int p) +{ + while (pl && p--) + pl = pl->next; + + return pl; +} + +struct dm_mem_cache_object { + struct page_list *pl; /* Dynamically allocated array */ + void *private; /* Caller context reference */ +}; + +struct dm_mem_cache_client; + +/* + * Create/destroy dm memory cache client resources. + */ +struct dm_mem_cache_client *dm_mem_cache_client_create( + unsigned int total_pages, unsigned int objects, unsigned int chunks); +void dm_mem_cache_client_destroy(struct dm_mem_cache_client *client); + +/* + * Grow/shrink a dm memory cache client resources. + */ +int dm_mem_cache_grow(struct dm_mem_cache_client *client, unsigned int pages); +int dm_mem_cache_shrink(struct dm_mem_cache_client *client, unsigned int pages); + +/* + * Allocate/free a memory object + */ +struct dm_mem_cache_object * +dm_mem_cache_alloc(struct dm_mem_cache_client *client, + unsigned int pages_per_chunk); +void dm_mem_cache_free(struct dm_mem_cache_client *client, + struct dm_mem_cache_object *object); + +#endif --- linux-2.6.28.orig/ubuntu/dm-raid4-5/dm-raid4-5.c +++ linux-2.6.28/ubuntu/dm-raid4-5/dm-raid4-5.c @@ -0,0 +1,4425 @@ +/* + * Copyright (C) 2005-2008 Red Hat GmbH + * + * Module Author: Heinz Mauelshagen + * + * This file is released under the GPL. + * + * WARNING: this is Alpha software wich can corrupt your data! + * + * + * Linux 2.6 Device Mapper RAID4 and RAID5 target. + * + * Supports: + * o RAID4 with dedicated and selectable parity device + * o RAID5 with rotating parity (left+right, symmetric+asymmetric) + * + * + * Thanks to MD for: + * o the raid address calculation algorithm + * o the base of the biovec <-> page list copier. + * + * + * Uses region hash to keep track of how many writes are in flight to + * regions in order to use dirty log to keep state of regions to recover: + * + * o clean regions (those which are synchronized + * and don't have write io in flight) + * o dirty regions (those with write io in flight) + * + * + * On startup, any dirty regions are migrated to the 'nosync' state + * and are subject to recovery by the daemon. + * + * See raid_ctr() for table definition. + * + * + * FIXME: + * o add virtual interface for locking + * o remove instrumentation (REMOVEME:) + * + */ + +static const char *version = "v0.2427"; + +#include "dm.h" +#include "dm-bio-list.h" +#include +#include +#include "dm-mem-cache.h" +#include "dm-message.h" +#include "dm-region_hash.h" +#include "dm-raid4-5.h" +#include +#include + +#define STR_LEN(ptr, str) ptr, str, strlen(ptr) +/* + * Configurable parameters + */ +#define INLINE + +/* Default # of stripes if not set in constructor. */ +#define STRIPES 64 + +/* Minimum/maximum # of selectable stripes. */ +#define STRIPES_MIN 8 +#define STRIPES_MAX 16384 + +/* Default chunk size in sectors if not set in constructor. */ +#define CHUNK_SIZE 64 + +/* Default io size in sectors if not set in constructor. */ +#define IO_SIZE_MIN SECTORS_PER_PAGE +#define IO_SIZE IO_SIZE_MIN + +/* Maximum setable chunk size in sectors. */ +#define CHUNK_SIZE_MAX 16384 + +/* Recover io size default in sectors. */ +#define RECOVER_IO_SIZE_MIN 64 +#define RECOVER_IO_SIZE 256 + +/* Default percentage recover io bandwidth. */ +#define BANDWIDTH 10 +#define BANDWIDTH_MIN 1 +#define BANDWIDTH_MAX 100 +/* + * END Configurable parameters + */ + +#define TARGET "dm-raid45" +#define DAEMON "kraid45d" +#define DM_MSG_PREFIX TARGET + +#define SECTORS_PER_PAGE (PAGE_SIZE >> SECTOR_SHIFT) + +/* Amount/size for __xor(). */ +#define SECTORS_PER_XOR SECTORS_PER_PAGE +#define XOR_SIZE PAGE_SIZE + +/* Derive raid_set from stripe_cache pointer. */ +#define RS(x) container_of(x, struct raid_set, sc) + +/* Check value in range. */ +#define range_ok(i, min, max) (i >= min && i <= max) + +/* Page reference. */ +#define PAGE(stripe, p) ((stripe)->obj[p].pl->page) + +/* Bio list reference. */ +#define BL(stripe, p, rw) (stripe->ss[p].bl + rw) + +/* Page list reference. */ +#define PL(stripe, p) (stripe->obj[p].pl) + +/* Check argument is power of 2. */ +#define POWER_OF_2(a) (!(a & (a - 1))) + +/* xor optimization. */ +typedef unsigned long xor_t; + +/* Factor out to dm-bio-list.h */ +static inline void bio_list_push(struct bio_list *bl, struct bio *bio) +{ + bio->bi_next = bl->head; + bl->head = bio; + + if (!bl->tail) + bl->tail = bio; +} + +/* Factor out to dm.h */ +#define TI_ERR_RET(str, ret) \ + do { ti->error = DM_MSG_PREFIX ": " str; return ret; } while(0); +#define TI_ERR(str) TI_ERR_RET(str, -EINVAL) + +/*----------------------------------------------------------------- + * Stripe cache + * + * Cache for all reads and writes to raid sets (operational or degraded) + * + * We need to run all data to and from a RAID set through this cache, + * because parity chunks need to get calculated from data chunks + * or, in the degraded/resynchronization case, missing chunks need + * to be reconstructed using the other chunks of the stripe. + *---------------------------------------------------------------*/ +/* Protect kmem cache # counter. */ +static atomic_t _stripe_sc_nr = ATOMIC_INIT(-1); /* kmem cache # counter. */ + +/* A stripe set (holds bios hanging off). */ +struct stripe_set { + struct stripe *stripe; /* Backpointer to stripe for endio(). */ + struct bio_list bl[3]; /* Reads, writes, and writes merged. */ +#define WRITE_MERGED 2 +}; + +#if READ != 0 || WRITE != 1 +#error dm-raid45: READ/WRITE != 0/1 used as index!!! +#endif + +/* + * Stripe linked list indexes. Keep order, because the stripe + * and the stripe cache rely on the first 3! + */ +enum list_types { + LIST_IO = 0, /* Stripes with io pending. */ + LIST_ENDIO, /* Stripes to endio. */ + LIST_LRU, /* Least recently used stripes. */ + LIST_HASH, /* Hashed stripes. */ + NR_LISTS, /* To size array in struct stripe. */ +}; + +enum lock_types { + LOCK_ENDIO = 0, /* Protect endio list. */ + LOCK_LRU, /* Protect lru list. */ + NR_LOCKS, /* To size array in struct stripe_cache. */ +}; + +/* A stripe: the io object to handle all reads and writes to a RAID set. */ +struct stripe { + struct stripe_cache *sc; /* Backpointer to stripe cache. */ + + sector_t key; /* Hash key. */ + sector_t region; /* Region stripe is mapped to. */ + + /* Reference count. */ + atomic_t cnt; + + struct { + unsigned long flags; /* flags (see below). */ + + /* + * Pending ios in flight: + * + * used as a 'lock' to control move of stripe to endio list + */ + atomic_t pending; /* Pending ios in flight. */ + + /* Sectors to read and write for multi page stripe sets. */ + unsigned size; + } io; + + /* Lock on stripe (for clustering). */ + void *lock; + + /* + * 4 linked lists: + * o io list to flush io + * o endio list + * o LRU list to put stripes w/o reference count on + * o stripe cache hash + */ + struct list_head lists[NR_LISTS]; + + struct { + unsigned short parity; /* Parity chunk index. */ + short recover; /* Recovery chunk index. */ + } idx; + + /* This sets memory cache object (dm-mem-cache). */ + struct dm_mem_cache_object *obj; + + /* Array of stripe sets (dynamically allocated). */ + struct stripe_set ss[0]; +}; + +/* States stripes can be in (flags field). */ +enum stripe_states { + STRIPE_ACTIVE, /* Active io on stripe. */ + STRIPE_ERROR, /* io error on stripe. */ + STRIPE_MERGED, /* Writes got merged. */ + STRIPE_READ, /* Read. */ + STRIPE_RBW, /* Read-before-write. */ + STRIPE_RECONSTRUCT, /* reconstruct of a missing chunk required. */ + STRIPE_RECOVER, /* Stripe used for RAID set recovery. */ +}; + +/* ... and macros to access them. */ +#define BITOPS(name, what, var, flag) \ +static inline int TestClear ## name ## what(struct var *v) \ +{ return test_and_clear_bit(flag, &v->io.flags); } \ +static inline int TestSet ## name ## what(struct var *v) \ +{ return test_and_set_bit(flag, &v->io.flags); } \ +static inline void Clear ## name ## what(struct var *v) \ +{ clear_bit(flag, &v->io.flags); } \ +static inline void Set ## name ## what(struct var *v) \ +{ set_bit(flag, &v->io.flags); } \ +static inline int name ## what(struct var *v) \ +{ return test_bit(flag, &v->io.flags); } + + +BITOPS(Stripe, Active, stripe, STRIPE_ACTIVE) +BITOPS(Stripe, Merged, stripe, STRIPE_MERGED) +BITOPS(Stripe, Error, stripe, STRIPE_ERROR) +BITOPS(Stripe, Read, stripe, STRIPE_READ) +BITOPS(Stripe, RBW, stripe, STRIPE_RBW) +BITOPS(Stripe, Reconstruct, stripe, STRIPE_RECONSTRUCT) +BITOPS(Stripe, Recover, stripe, STRIPE_RECOVER) + +/* A stripe hash. */ +struct stripe_hash { + struct list_head *hash; + unsigned buckets; + unsigned mask; + unsigned prime; + unsigned shift; +}; + +/* A stripe cache. */ +struct stripe_cache { + /* Stripe hash. */ + struct stripe_hash hash; + + /* Stripes with io to flush, stripes to endio and LRU lists. */ + struct list_head lists[3]; + + /* Locks to protect endio and lru lists. */ + spinlock_t locks[NR_LOCKS]; + + /* Slab cache to allocate stripes from. */ + struct { + struct kmem_cache *cache; /* Cache itself. */ + char name[32]; /* Unique name. */ + } kc; + + struct dm_io_client *dm_io_client; /* dm-io client resource context. */ + + /* dm-mem-cache client resource context. */ + struct dm_mem_cache_client *dm_mem_cache_client; + + int stripes_parm; /* # stripes parameter from constructor. */ + atomic_t stripes; /* actual # of stripes in cache. */ + atomic_t stripes_to_shrink; /* # of stripes to shrink cache by. */ + atomic_t stripes_last; /* last # of stripes in cache. */ + atomic_t active_stripes; /* actual # of active stripes in cache. */ + + /* REMOVEME: */ + atomic_t max_active_stripes; /* actual # of active stripes in cache. */ +}; + +/* Flag specs for raid_dev */ ; +enum raid_dev_flags { DEVICE_FAILED, IO_QUEUED }; + +/* The raid device in a set. */ +struct raid_dev { + struct dm_dev *dev; + unsigned long flags; /* raid_dev_flags. */ + sector_t start; /* offset to map to. */ +}; + +/* Flags spec for raid_set. */ +enum raid_set_flags { + RS_CHECK_OVERWRITE, /* Check for chunk overwrites. */ + RS_DEAD, /* RAID set inoperational. */ + RS_DEVEL_STATS, /* REMOVEME: display status information. */ + RS_IO_ERROR, /* io error on set. */ + RS_RECOVER, /* Do recovery. */ + RS_RECOVERY_BANDWIDTH, /* Allow recovery bandwidth (delayed bios). */ + RS_REGION_GET, /* get a region to recover. */ + RS_SC_BUSY, /* stripe cache busy -> send an event. */ + RS_SUSPENDED, /* RAID set suspendedn. */ +}; + +/* REMOVEME: devel stats counters. */ +enum stats_types { + S_BIOS_READ, + S_BIOS_ADDED_READ, + S_BIOS_ENDIO_READ, + S_BIOS_WRITE, + S_BIOS_ADDED_WRITE, + S_BIOS_ENDIO_WRITE, + S_CAN_MERGE, + S_CANT_MERGE, + S_CONGESTED, + S_DM_IO_READ, + S_DM_IO_WRITE, + S_ACTIVE_READS, + S_BANDWIDTH, + S_BARRIER, + S_BIO_COPY_PL_NEXT, + S_DEGRADED, + S_DELAYED_BIOS, + S_EVICT, + S_FLUSHS, + S_HITS_1ST, + S_IOS_POST, + S_INSCACHE, + S_MAX_LOOKUP, + S_MERGE_PAGE_LOCKED, + S_NO_BANDWIDTH, + S_NOT_CONGESTED, + S_NO_RW, + S_NOSYNC, + S_PROHIBITPAGEIO, + S_RECONSTRUCT_EI, + S_RECONSTRUCT_DEV, + S_REDO, + S_REQUEUE, + S_STRIPE_ERROR, + S_SUM_DELAYED_BIOS, + S_XORS, + S_NR_STATS, /* # of stats counters. */ +}; + +/* Status type -> string mappings. */ +struct stats_map { + const enum stats_types type; + const char *str; +}; + +static struct stats_map stats_map[] = { + { S_BIOS_READ, "r=" }, + { S_BIOS_ADDED_READ, "/" }, + { S_BIOS_ENDIO_READ, "/" }, + { S_BIOS_WRITE, " w=" }, + { S_BIOS_ADDED_WRITE, "/" }, + { S_BIOS_ENDIO_WRITE, "/" }, + { S_DM_IO_READ, " rc=" }, + { S_DM_IO_WRITE, " wc=" }, + { S_ACTIVE_READS, " active_reads=" }, + { S_BANDWIDTH, " bandwidth=" }, + { S_NO_BANDWIDTH, " no_bandwidth=" }, + { S_BARRIER, " barrier=" }, + { S_BIO_COPY_PL_NEXT, " bio_copy_pl_next=" }, + { S_CAN_MERGE, " can_merge=" }, + { S_MERGE_PAGE_LOCKED, "/page_locked=" }, + { S_CANT_MERGE, "/cant_merge=" }, + { S_CONGESTED, " congested=" }, + { S_NOT_CONGESTED, "/not_congested=" }, + { S_DEGRADED, " degraded=" }, + { S_DELAYED_BIOS, " delayed_bios=" }, + { S_SUM_DELAYED_BIOS, "/sum_delayed_bios=" }, + { S_EVICT, " evict=" }, + { S_FLUSHS, " flushs=" }, + { S_HITS_1ST, " hits_1st=" }, + { S_IOS_POST, " ios_post=" }, + { S_INSCACHE, " inscache=" }, + { S_MAX_LOOKUP, " max_lookup=" }, + { S_NO_RW, " no_rw=" }, + { S_NOSYNC, " nosync=" }, + { S_PROHIBITPAGEIO, " ProhibitPageIO=" }, + { S_RECONSTRUCT_EI, " reconstruct_ei=" }, + { S_RECONSTRUCT_DEV, " reconstruct_dev=" }, + { S_REDO, " redo=" }, + { S_REQUEUE, " requeue=" }, + { S_STRIPE_ERROR, " stripe_error=" }, + { S_XORS, " xors=" }, +}; + +/* + * A RAID set. + */ +typedef void (*xor_function_t)(unsigned count, xor_t **data); +struct raid_set { + struct dm_target *ti; /* Target pointer. */ + + struct { + unsigned long flags; /* State flags. */ + spinlock_t in_lock; /* Protects central input list below. */ + struct bio_list in; /* Pending ios (central input list). */ + struct bio_list work; /* ios work set. */ + wait_queue_head_t suspendq; /* suspend synchronization. */ + atomic_t in_process; /* counter of queued bios (suspendq). */ + atomic_t in_process_max;/* counter of queued bios max. */ + + /* io work. */ + struct workqueue_struct *wq; + struct delayed_work dws; + } io; + + /* External locking. */ + struct dmraid45_locking_type *locking; + + struct stripe_cache sc; /* Stripe cache for this set. */ + + /* Xor optimization. */ + struct { + struct xor_func *f; + unsigned chunks; + unsigned speed; + } xor; + + /* Recovery parameters. */ + struct recover { + struct dm_dirty_log *dl; /* Dirty log. */ + void *rh; /* Region hash. */ + + region_t nr_regions; + region_t nr_regions_to_recover; + region_t nr_regions_recovered; + unsigned long start_jiffies; + unsigned long end_jiffies; + + unsigned bandwidth; /* Recovery bandwidth [%]. */ + unsigned bandwidth_work; /* Recovery bandwidth [factor]. */ + unsigned bandwidth_parm; /* " constructor parm. */ + unsigned io_size; /* io size <= chunk size. */ + unsigned io_size_parm; /* io size ctr parameter. */ + + /* recovery io throttling. */ + atomic_t io_count[2]; /* counter recover/regular io. */ + unsigned long last_jiffies; + + void *reg; /* Actual region to recover. */ + struct stripe *stripe; /* Stripe used for recovery. */ + sector_t pos; /* Position within region to recover. */ + sector_t end; /* End of region to recover. */ + } recover; + + /* RAID set parameters. */ + struct { + struct raid_type *raid_type; /* RAID type (eg, RAID4). */ + unsigned raid_parms; /* # variable raid parameters. */ + + unsigned chunk_size; /* Sectors per chunk. */ + unsigned chunk_size_parm; + unsigned chunk_mask; /* Mask for amount. */ + unsigned chunk_shift; /* rsector chunk size shift. */ + + unsigned io_size; /* Sectors per io. */ + unsigned io_size_parm; + unsigned io_mask; /* Mask for amount. */ + unsigned io_shift_mask; /* Mask for raid_address(). */ + unsigned io_shift; /* rsector io size shift. */ + unsigned pages_per_io; /* Pages per io. */ + + sector_t sectors_per_dev; /* Sectors per device. */ + + atomic_t failed_devs; /* Amount of devices failed. */ + + /* Index of device to initialize. */ + int dev_to_init; + int dev_to_init_parm; + + /* Raid devices dynamically allocated. */ + unsigned raid_devs; /* # of RAID devices below. */ + unsigned data_devs; /* # of RAID data devices. */ + + int ei; /* index of failed RAID device. */ + + /* index of dedicated parity device (i.e. RAID4). */ + int pi; + int pi_parm; /* constructor parm for status output. */ + } set; + + /* REMOVEME: devel stats counters. */ + atomic_t stats[S_NR_STATS]; + + /* Dynamically allocated temporary pointers for xor(). */ + xor_t **data; + + /* Dynamically allocated RAID devices. Alignment? */ + struct raid_dev dev[0]; +}; + + +BITOPS(RS, Bandwidth, raid_set, RS_RECOVERY_BANDWIDTH) +BITOPS(RS, CheckOverwrite, raid_set, RS_CHECK_OVERWRITE) +BITOPS(RS, Dead, raid_set, RS_DEAD) +BITOPS(RS, DevelStats, raid_set, RS_DEVEL_STATS) +BITOPS(RS, IoError, raid_set, RS_IO_ERROR) +BITOPS(RS, Recover, raid_set, RS_RECOVER) +BITOPS(RS, RegionGet, raid_set, RS_REGION_GET) +BITOPS(RS, ScBusy, raid_set, RS_SC_BUSY) +BITOPS(RS, Suspended, raid_set, RS_SUSPENDED) +#undef BITOPS + +#define PageIO(page) PageChecked(page) +#define AllowPageIO(page) SetPageChecked(page) +#define ProhibitPageIO(page) ClearPageChecked(page) + +/*----------------------------------------------------------------- + * Raid-4/5 set structures. + *---------------------------------------------------------------*/ +/* RAID level definitions. */ +enum raid_level { + raid4, + raid5, +}; + +/* Symmetric/Asymmetric, Left/Right parity rotating algorithms. */ +enum raid_algorithm { + none, + left_asym, + right_asym, + left_sym, + right_sym, +}; + +struct raid_type { + const char *name; /* RAID algorithm. */ + const char *descr; /* Descriptor text for logging. */ + const unsigned parity_devs; /* # of parity devices. */ + const unsigned minimal_devs; /* minimal # of devices in set. */ + const enum raid_level level; /* RAID level. */ + const enum raid_algorithm algorithm; /* RAID algorithm. */ +}; + +/* Supported raid types and properties. */ +static struct raid_type raid_types[] = { + {"raid4", "RAID4 (dedicated parity disk)", 1, 3, raid4, none}, + {"raid5_la", "RAID5 (left asymmetric)", 1, 3, raid5, left_asym}, + {"raid5_ra", "RAID5 (right asymmetric)", 1, 3, raid5, right_asym}, + {"raid5_ls", "RAID5 (left symmetric)", 1, 3, raid5, left_sym}, + {"raid5_rs", "RAID5 (right symmetric)", 1, 3, raid5, right_sym}, +}; + +/* Address as calculated by raid_address(). */ +struct address { + sector_t key; /* Hash key (start address of stripe). */ + unsigned di, pi; /* Data and parity disks index. */ +}; + +static inline void set_page_locked(struct page *page) { set_bit(PG_locked, &page->flags); } +static inline void clear_page_locked(struct page *page) { clear_bit(PG_locked, &page->flags); } + +/* REMOVEME: reset statistics counters. */ +static void stats_reset(struct raid_set *rs) +{ + unsigned s = S_NR_STATS; + + while (s--) + atomic_set(rs->stats + s, 0); +} + +/*---------------------------------------------------------------- + * RAID set management routines. + *--------------------------------------------------------------*/ +/* + * Begin small helper functions. + */ +/* Queue (optionally delayed) io work. */ +static void wake_do_raid_delayed(struct raid_set *rs, unsigned long delay) +{ + struct delayed_work *dws = &rs->io.dws; + + cancel_delayed_work(dws); + queue_delayed_work(rs->io.wq, dws, delay); +} + +/* Queue io work immediately (called from region hash too). */ +static INLINE void wake_do_raid(void *context) +{ + wake_do_raid_delayed(context, 0); +} + +/* Wait until all io has been processed. */ +static INLINE void wait_ios(struct raid_set *rs) +{ + wait_event(rs->io.suspendq, !atomic_read(&rs->io.in_process)); +} + +/* Declare io queued to device. */ +static INLINE void io_dev_queued(struct raid_dev *dev) +{ + set_bit(IO_QUEUED, &dev->flags); +} + +/* Io on device and reset ? */ +static inline int io_dev_clear(struct raid_dev *dev) +{ + return test_and_clear_bit(IO_QUEUED, &dev->flags); +} + +/* Get an io reference. */ +static INLINE void io_get(struct raid_set *rs) +{ + int p = atomic_inc_return(&rs->io.in_process); + + if (p > atomic_read(&rs->io.in_process_max)) + atomic_set(&rs->io.in_process_max, p); /* REMOVEME: max. */ +} + +/* Put the io reference and conditionally wake io waiters. */ +static INLINE void io_put(struct raid_set *rs) +{ + if (atomic_dec_and_test(&rs->io.in_process)) + wake_up(&rs->io.suspendq); +} + +/* Calculate device sector offset. */ +static INLINE sector_t _sector(struct raid_set *rs, struct bio *bio) +{ + sector_t sector = bio->bi_sector; + + sector_div(sector, rs->set.data_devs); + return sector; +} + +/* Test device operational. */ +static INLINE int dev_operational(struct raid_set *rs, unsigned p) +{ + return !test_bit(DEVICE_FAILED, &rs->dev[p].flags); +} + +/* Return # of active stripes in stripe cache. */ +static INLINE int sc_active(struct stripe_cache *sc) +{ + return atomic_read(&sc->active_stripes); +} + +/* Test io pending on stripe. */ +static INLINE int stripe_io(struct stripe *stripe) +{ + return atomic_read(&stripe->io.pending); +} + +static INLINE void stripe_io_inc(struct stripe *stripe) +{ + atomic_inc(&stripe->io.pending); +} + +static INLINE void stripe_io_dec(struct stripe *stripe) +{ + atomic_dec(&stripe->io.pending); +} + +/* Wrapper needed by for_each_io_dev(). */ +static void _stripe_io_inc(struct stripe *stripe, unsigned p) +{ + stripe_io_inc(stripe); +} + +/* Error a stripe. */ +static INLINE void stripe_error(struct stripe *stripe, struct page *page) +{ + SetStripeError(stripe); + SetPageError(page); + atomic_inc(RS(stripe->sc)->stats + S_STRIPE_ERROR); +} + +/* Page IOed ok. */ +enum dirty_type { CLEAN, DIRTY }; +static INLINE void page_set(struct page *page, enum dirty_type type) +{ + switch (type) { + case DIRTY: + SetPageDirty(page); + AllowPageIO(page); + break; + + case CLEAN: + ClearPageDirty(page); + break; + + default: + BUG(); + } + + SetPageUptodate(page); + ClearPageError(page); +} + +/* Return region state for a sector. */ +static INLINE int +region_state(struct raid_set *rs, sector_t sector, unsigned long state) +{ + void *rh = rs->recover.rh; + + if (unlikely(RSRecover(rs))) + return rh_state(rh, rh_sector_to_region(rh, sector), 1) & state; + else + return 0; +} + +/* Check maximum devices which may fail in a raid set. */ +static inline int raid_set_degraded(struct raid_set *rs) +{ + return RSIoError(rs); +} + +/* Check # of devices which may fail in a raid set. */ +static INLINE int raid_set_operational(struct raid_set *rs) +{ + /* Too many failed devices -> BAD. */ + return atomic_read(&rs->set.failed_devs) <= + rs->set.raid_type->parity_devs; +} + +/* + * Return true in case a page_list should be read/written + * + * Conditions to read/write: + * o 1st page in list not uptodate + * o 1st page in list dirty + * o if we optimized io away, we flag it using the pages checked bit. + */ +static INLINE unsigned page_io(struct page *page) +{ + /* Optimization: page was flagged to need io during first run. */ + if (PagePrivate(page)) { + ClearPagePrivate(page); + return 1; + } + + /* Avoid io if prohibited or a locked page. */ + if (!PageIO(page) || PageLocked(page)) + return 0; + + if (!PageUptodate(page) || PageDirty(page)) { + /* Flag page needs io for second run optimization. */ + SetPagePrivate(page); + return 1; + } + + return 0; +} + +/* Call a function on each page list needing io. */ +static INLINE unsigned +for_each_io_dev(struct raid_set *rs, struct stripe *stripe, + void (*f_io)(struct stripe *stripe, unsigned p)) +{ + unsigned p = rs->set.raid_devs, r = 0; + + while (p--) { + if (page_io(PAGE(stripe, p))) { + f_io(stripe, p); + r++; + } + } + + return r; +} + +/* Reconstruct a particular device ?. */ +static INLINE int dev_to_init(struct raid_set *rs) +{ + return rs->set.dev_to_init > -1; +} + +/* Index of device to calculate parity on. */ +static INLINE unsigned dev_for_parity(struct stripe *stripe) +{ + struct raid_set *rs = RS(stripe->sc); + + return dev_to_init(rs) ? rs->set.dev_to_init : stripe->idx.parity; +} + +/* Return the index of the device to be recovered. */ +static int idx_get(struct raid_set *rs) +{ + /* Avoid to read in the pages to be reconstructed anyway. */ + if (dev_to_init(rs)) + return rs->set.dev_to_init; + else if (rs->set.raid_type->level == raid4) + return rs->set.pi; + + return -1; +} + +/* RAID set congested function. */ +static int raid_set_congested(void *congested_data, int bdi_bits) +{ + struct raid_set *rs = congested_data; + int r = 0; /* Assume uncongested. */ + unsigned p = rs->set.raid_devs; + + /* If any of our component devices are overloaded. */ + while (p--) + r |= bdi_congested(&bdev_get_queue(rs->dev[p].dev->bdev)->backing_dev_info, bdi_bits); + + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + (r ? S_CONGESTED : S_NOT_CONGESTED)); + return r; +} + +/* Display RAID set dead message once. */ +static void raid_set_dead(struct raid_set *rs) +{ + if (!TestSetRSDead(rs)) { + unsigned p; + char buf[BDEVNAME_SIZE]; + + DMERR("FATAL: too many devices failed -> RAID set dead"); + + for (p = 0; p < rs->set.raid_devs; p++) { + if (!dev_operational(rs, p)) + DMERR("device /dev/%s failed", + bdevname(rs->dev[p].dev->bdev, buf)); + } + } +} + +/* RAID set degrade check. */ +static INLINE int +raid_set_check_and_degrade(struct raid_set *rs, + struct stripe *stripe, unsigned p) +{ + if (test_and_set_bit(DEVICE_FAILED, &rs->dev[p].flags)) + return -EPERM; + + /* Through an event in case of member device errors. */ + dm_table_event(rs->ti->table); + atomic_inc(&rs->set.failed_devs); + + /* Only log the first member error. */ + if (!TestSetRSIoError(rs)) { + char buf[BDEVNAME_SIZE]; + + /* Store index for recovery. */ + mb(); + rs->set.ei = p; + mb(); + + DMERR("CRITICAL: %sio error on device /dev/%s " + "in region=%llu; DEGRADING RAID set", + stripe ? "" : "FAKED ", + bdevname(rs->dev[p].dev->bdev, buf), + (unsigned long long) (stripe ? stripe->key : 0)); + DMERR("further device error messages suppressed"); + } + + return 0; +} + +static void +raid_set_check_degrade(struct raid_set *rs, struct stripe *stripe) +{ + unsigned p = rs->set.raid_devs; + + while (p--) { + struct page *page = PAGE(stripe, p); + + if (PageError(page)) { + ClearPageError(page); + raid_set_check_and_degrade(rs, stripe, p); + } + } +} + +/* RAID set upgrade check. */ +static int raid_set_check_and_upgrade(struct raid_set *rs, unsigned p) +{ + if (!test_and_clear_bit(DEVICE_FAILED, &rs->dev[p].flags)) + return -EPERM; + + if (atomic_dec_and_test(&rs->set.failed_devs)) { + ClearRSIoError(rs); + rs->set.ei = -1; + } + + return 0; +} + +/* Lookup a RAID device by name or by major:minor number. */ +union dev_lookup { + const char *dev_name; + struct raid_dev *dev; +}; +enum lookup_type { byname, bymajmin, bynumber }; +static int raid_dev_lookup(struct raid_set *rs, enum lookup_type by, + union dev_lookup *dl) +{ + unsigned p; + + /* + * Must be an incremental loop, because the device array + * can have empty slots still on calls from raid_ctr() + */ + for (p = 0; p < rs->set.raid_devs; p++) { + char buf[BDEVNAME_SIZE]; + struct raid_dev *dev = rs->dev + p; + + if (!dev->dev) + break; + + /* Format dev string appropriately if necessary. */ + if (by == byname) + bdevname(dev->dev->bdev, buf); + else if (by == bymajmin) + format_dev_t(buf, dev->dev->bdev->bd_dev); + + /* Do the actual check. */ + if (by == bynumber) { + if (dl->dev->dev->bdev->bd_dev == + dev->dev->bdev->bd_dev) + return p; + } else if (!strcmp(dl->dev_name, buf)) + return p; + } + + return -ENODEV; +} + +/* End io wrapper. */ +static INLINE void +_bio_endio(struct raid_set *rs, struct bio *bio, int error) +{ + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + (bio_data_dir(bio) == WRITE ? + S_BIOS_ENDIO_WRITE : S_BIOS_ENDIO_READ)); + bio_endio(bio, error); + io_put(rs); /* Wake any suspend waiters. */ +} + +/* + * End small helper functions. + */ + + +/* + * Stripe hash functions + */ +/* Initialize/destroy stripe hash. */ +static int hash_init(struct stripe_hash *hash, unsigned stripes) +{ + unsigned buckets = 1, max_buckets = stripes / 4; + unsigned hash_primes[] = { + /* Table of primes for hash_fn/table size optimization. */ + 3, 7, 13, 27, 53, 97, 193, 389, 769, + 1543, 3079, 6151, 12289, 24593, + }; + + /* Calculate number of buckets (2^^n <= stripes / 4). */ + while ((buckets <<= 1) < max_buckets); + + /* Allocate stripe hash. */ + hash->hash = vmalloc(buckets * sizeof(*hash->hash)); + if (!hash->hash) + return -ENOMEM; + + hash->buckets = buckets; + hash->mask = buckets - 1; + hash->shift = ffs(buckets); + if (hash->shift > ARRAY_SIZE(hash_primes) + 1) + hash->shift = ARRAY_SIZE(hash_primes) + 1; + + BUG_ON(hash->shift - 2 > ARRAY_SIZE(hash_primes) + 1); + hash->prime = hash_primes[hash->shift - 2]; + + /* Initialize buckets. */ + while (buckets--) + INIT_LIST_HEAD(hash->hash + buckets); + + return 0; +} + +static INLINE void hash_exit(struct stripe_hash *hash) +{ + if (hash->hash) { + vfree(hash->hash); + hash->hash = NULL; + } +} + +/* List add (head/tail/locked/unlocked) inlines. */ +enum list_lock_type { LIST_LOCKED, LIST_UNLOCKED }; +#define LIST_DEL(name, list) \ +static void stripe_ ## name ## _del(struct stripe *stripe, \ + enum list_lock_type lock) { \ + struct list_head *lh = stripe->lists + (list); \ + spinlock_t *l = NULL; \ +\ + if (lock == LIST_LOCKED) { \ + l = stripe->sc->locks + LOCK_LRU; \ + spin_lock_irq(l); \ + } \ +\ +\ + if (!list_empty(lh)) \ + list_del_init(lh); \ +\ + if (lock == LIST_LOCKED) \ + spin_unlock_irq(l); \ +} + +LIST_DEL(hash, LIST_HASH) +LIST_DEL(lru, LIST_LRU) +#undef LIST_DEL + +enum list_pos_type { POS_HEAD, POS_TAIL }; +#define LIST_ADD(name, list) \ +static void stripe_ ## name ## _add(struct stripe *stripe, \ + enum list_pos_type pos, \ + enum list_lock_type lock) { \ + struct list_head *lh = stripe->lists + (list); \ + struct stripe_cache *sc = stripe->sc; \ + spinlock_t *l = NULL; \ +\ + if (lock == LIST_LOCKED) { \ + l = sc->locks + LOCK_LRU; \ + spin_lock_irq(l); \ + } \ +\ + if (list_empty(lh)) { \ + if (pos == POS_HEAD) \ + list_add(lh, sc->lists + (list)); \ + else \ + list_add_tail(lh, sc->lists + (list)); \ + } \ +\ + if (lock == LIST_LOCKED) \ + spin_unlock_irq(l); \ +} + +LIST_ADD(endio, LIST_ENDIO) +LIST_ADD(io, LIST_IO) +LIST_ADD(lru, LIST_LRU) +#undef LIST_ADD + +#define POP(list) \ + if (list_empty(sc->lists + list)) \ + stripe = NULL; \ + else { \ + stripe = list_entry(sc->lists[list].next, struct stripe, \ + lists[list]); \ + list_del_init(&stripe->lists[list]); \ + } + +/* Pop an available stripe off the lru list. */ +static struct stripe *stripe_lru_pop(struct stripe_cache *sc) +{ + struct stripe *stripe; + spinlock_t *lock = sc->locks + LOCK_LRU; + + spin_lock_irq(lock); + POP(LIST_LRU); + spin_unlock_irq(lock); + + if (stripe) + /* Remove from hash before reuse. */ + stripe_hash_del(stripe, LIST_UNLOCKED); + + return stripe; +} + +static inline unsigned hash_fn(struct stripe_hash *hash, sector_t key) +{ + return (unsigned) (((key * hash->prime) >> hash->shift) & hash->mask); +} + +static inline struct list_head * +hash_bucket(struct stripe_hash *hash, sector_t key) +{ + return hash->hash + hash_fn(hash, key); +} + +/* Insert an entry into a hash. */ +static inline void hash_insert(struct stripe_hash *hash, struct stripe *stripe) +{ + list_add(stripe->lists + LIST_HASH, hash_bucket(hash, stripe->key)); +} + +/* Insert an entry into the stripe hash. */ +static inline void +sc_insert(struct stripe_cache *sc, struct stripe *stripe) +{ + hash_insert(&sc->hash, stripe); +} + +/* Lookup an entry in the stripe hash. */ +static inline struct stripe * +stripe_lookup(struct stripe_cache *sc, sector_t key) +{ + unsigned c = 0; + struct stripe *stripe; + struct list_head *bucket = hash_bucket(&sc->hash, key); + + list_for_each_entry(stripe, bucket, lists[LIST_HASH]) { + /* REMOVEME: statisics. */ + if (++c > atomic_read(RS(sc)->stats + S_MAX_LOOKUP)) + atomic_set(RS(sc)->stats + S_MAX_LOOKUP, c); + + if (stripe->key == key) + return stripe; + } + + return NULL; +} + +/* Resize the stripe cache hash on size changes. */ +static int hash_resize(struct stripe_cache *sc) +{ + /* Resize threshold reached? */ + if (atomic_read(&sc->stripes) > 2 * atomic_read(&sc->stripes_last) + || atomic_read(&sc->stripes) < atomic_read(&sc->stripes_last) / 4) { + int r; + struct stripe_hash hash, hash_tmp; + spinlock_t *lock; + + r = hash_init(&hash, atomic_read(&sc->stripes)); + if (r) + return r; + + lock = sc->locks + LOCK_LRU; + spin_lock_irq(lock); + if (sc->hash.hash) { + unsigned b = sc->hash.buckets; + struct list_head *pos, *tmp; + + /* Walk old buckets and insert into new. */ + while (b--) { + list_for_each_safe(pos, tmp, sc->hash.hash + b) + hash_insert(&hash, + list_entry(pos, struct stripe, + lists[LIST_HASH])); + } + + } + + memcpy(&hash_tmp, &sc->hash, sizeof(hash_tmp)); + memcpy(&sc->hash, &hash, sizeof(sc->hash)); + atomic_set(&sc->stripes_last, atomic_read(&sc->stripes)); + spin_unlock_irq(lock); + + hash_exit(&hash_tmp); + } + + return 0; +} + +/* + * Stripe cache locking functions + */ +/* Dummy lock function for local RAID4+5. */ +static void *no_lock(sector_t key, enum lock_type type) +{ + return &no_lock; +} + +/* Dummy unlock function for local RAID4+5. */ +static void no_unlock(void *lock_handle) +{ +} + +/* No locking (for local RAID 4+5). */ +static struct dmraid45_locking_type locking_none = { + .lock = no_lock, + .unlock = no_unlock, +}; + +/* Clustered RAID 4+5. */ +/* FIXME: code this. */ +static struct dmraid45_locking_type locking_cluster = { + .lock = no_lock, + .unlock = no_unlock, +}; + +/* Lock a stripe (for clustering). */ +static int +stripe_lock(struct raid_set *rs, struct stripe *stripe, int rw, sector_t key) +{ + stripe->lock = rs->locking->lock(key, rw == READ ? RAID45_SHARED : + RAID45_EX); + return stripe->lock ? 0 : -EPERM; +} + +/* Unlock a stripe (for clustering). */ +static void stripe_unlock(struct raid_set *rs, struct stripe *stripe) +{ + rs->locking->unlock(stripe->lock); + stripe->lock = NULL; +} + +/* + * Stripe cache functions. + */ +/* + * Invalidate all page lists pages of a stripe. + * + * I only keep state for the whole list in the first page. + */ +static INLINE void +stripe_pages_invalidate(struct stripe *stripe) +{ + unsigned p = RS(stripe->sc)->set.raid_devs; + + while (p--) { + struct page *page = PAGE(stripe, p); + + ProhibitPageIO(page); + ClearPageChecked(page); + ClearPageDirty(page); + ClearPageError(page); + clear_page_locked(page); + ClearPagePrivate(page); + ClearPageUptodate(page); + } +} + +/* Prepare stripe for (re)use. */ +static INLINE void stripe_invalidate(struct stripe *stripe) +{ + stripe->io.flags = 0; + stripe_pages_invalidate(stripe); +} + +/* Allow io on all chunks of a stripe. */ +static INLINE void stripe_allow_io(struct stripe *stripe) +{ + unsigned p = RS(stripe->sc)->set.raid_devs; + + while (p--) + AllowPageIO(PAGE(stripe, p)); +} + +/* Initialize a stripe. */ +static void +stripe_init(struct stripe_cache *sc, struct stripe *stripe, unsigned io_size) +{ + unsigned p = RS(sc)->set.raid_devs; + unsigned i; + + /* Work all io chunks. */ + while (p--) { + struct stripe_set *ss = stripe->ss + p; + + stripe->obj[p].private = ss; + ss->stripe = stripe; + + i = ARRAY_SIZE(ss->bl); + while (i--) + bio_list_init(ss->bl + i); + } + + stripe->sc = sc; + + i = ARRAY_SIZE(stripe->lists); + while (i--) + INIT_LIST_HEAD(&stripe->lists[i]); + + stripe->io.size = io_size; + atomic_set(&stripe->cnt, 0); + atomic_set(&stripe->io.pending, 0); + + stripe_invalidate(stripe); +} + +/* Number of pages per chunk. */ +static inline unsigned chunk_pages(unsigned io_size) +{ + return dm_div_up(io_size, SECTORS_PER_PAGE); +} + +/* Number of pages per stripe. */ +static inline unsigned stripe_pages(struct raid_set *rs, unsigned io_size) +{ + return chunk_pages(io_size) * rs->set.raid_devs; +} + +/* Initialize part of page_list (recovery). */ +static INLINE void stripe_zero_pl_part(struct stripe *stripe, unsigned p, + unsigned start, unsigned count) +{ + unsigned pages = chunk_pages(count); + /* Get offset into the page_list. */ + struct page_list *pl = pl_elem(PL(stripe, p), start / SECTORS_PER_PAGE); + + BUG_ON(!pl); + while (pl && pages--) { + BUG_ON(!pl->page); + memset(page_address(pl->page), 0, PAGE_SIZE); + pl = pl->next; + } +} + +/* Initialize parity chunk of stripe. */ +static INLINE void stripe_zero_chunk(struct stripe *stripe, unsigned p) +{ + stripe_zero_pl_part(stripe, p, 0, stripe->io.size); +} + +/* Return dynamic stripe structure size. */ +static INLINE size_t stripe_size(struct raid_set *rs) +{ + return sizeof(struct stripe) + + rs->set.raid_devs * sizeof(struct stripe_set); +} + +/* Allocate a stripe and its memory object. */ +enum grow { grow, keep }; +static struct stripe *stripe_alloc(struct stripe_cache *sc, + unsigned io_size, enum grow grow) +{ + int r; + unsigned pages_per_chunk = chunk_pages(io_size); + struct stripe *stripe; + + stripe = kmem_cache_alloc(sc->kc.cache, GFP_KERNEL); + if (stripe) { + memset(stripe, 0, stripe_size(RS(sc))); + + /* Grow the dm-mem-cache on request. */ + if (grow == grow) { + r = dm_mem_cache_grow(sc->dm_mem_cache_client, + pages_per_chunk); + if (r) + goto err_free; + } + + stripe->obj = dm_mem_cache_alloc(sc->dm_mem_cache_client, + pages_per_chunk); + if (!stripe->obj) + goto err_shrink; + + stripe_init(sc, stripe, io_size); + } + + return stripe; + + err_shrink: + if (grow == grow) + dm_mem_cache_shrink(sc->dm_mem_cache_client, pages_per_chunk); + err_free: + kmem_cache_free(sc->kc.cache, stripe); + return NULL; +} + +/* + * Free a stripes memory object, shrink the + * memory cache and free the stripe itself + */ +static void stripe_free(struct stripe *stripe) +{ + dm_mem_cache_free(stripe->sc->dm_mem_cache_client, stripe->obj); + dm_mem_cache_shrink(stripe->sc->dm_mem_cache_client, + chunk_pages(stripe->io.size)); + kmem_cache_free(stripe->sc->kc.cache, stripe); +} + +/* Free the recovery stripe. */ +static void stripe_recover_free(struct raid_set *rs) +{ + if (rs->recover.stripe) { + ClearRSRecover(rs); + stripe_free(rs->recover.stripe); + rs->recover.stripe = NULL; + } +} + +/* Push a stripe safely onto the endio list to be handled by do_endios(). */ +static INLINE void stripe_endio_push(struct stripe *stripe) +{ + int wake; + unsigned long flags; + struct stripe_cache *sc = stripe->sc; + spinlock_t *lock = sc->locks + LOCK_ENDIO; + + spin_lock_irqsave(lock, flags); + wake = list_empty(sc->lists + LIST_ENDIO); + stripe_endio_add(stripe, POS_HEAD, LIST_UNLOCKED); + spin_unlock_irqrestore(lock, flags); + + if (wake) + wake_do_raid(RS(sc)); +} + +/* Protected check for stripe cache endio list empty. */ +static INLINE int stripe_endio_empty(struct stripe_cache *sc) +{ + int r; + spinlock_t *lock = sc->locks + LOCK_ENDIO; + + spin_lock_irq(lock); + r = list_empty(sc->lists + LIST_ENDIO); + spin_unlock_irq(lock); + + return r; +} + +/* Pop a stripe off safely off the endio list. */ +static struct stripe *stripe_endio_pop(struct stripe_cache *sc) +{ + struct stripe *stripe; + spinlock_t *lock = sc->locks + LOCK_ENDIO; + + /* This runs in parallel with endio(). */ + spin_lock_irq(lock); + POP(LIST_ENDIO) + spin_unlock_irq(lock); + return stripe; +} + +#undef POP + +/* Evict stripe from cache. */ +static void stripe_evict(struct stripe *stripe) +{ + struct raid_set *rs = RS(stripe->sc); + stripe_hash_del(stripe, LIST_UNLOCKED); /* Take off hash. */ + + if (list_empty(stripe->lists + LIST_LRU)) { + stripe_lru_add(stripe, POS_TAIL, LIST_LOCKED); + atomic_inc(rs->stats + S_EVICT); /* REMOVEME: statistics. */ + } +} + +/* Grow stripe cache. */ +static int +sc_grow(struct stripe_cache *sc, unsigned stripes, enum grow grow) +{ + int r = 0; + struct raid_set *rs = RS(sc); + + /* Try to allocate this many (additional) stripes. */ + while (stripes--) { + struct stripe *stripe = stripe_alloc(sc, rs->set.io_size, grow); + + if (likely(stripe)) { + stripe_lru_add(stripe, POS_TAIL, LIST_LOCKED); + atomic_inc(&sc->stripes); + } else { + r = -ENOMEM; + break; + } + } + + ClearRSScBusy(rs); + return r ? r : hash_resize(sc); +} + +/* Shrink stripe cache. */ +static int sc_shrink(struct stripe_cache *sc, unsigned stripes) +{ + int r = 0; + + /* Try to get unused stripe from LRU list. */ + while (stripes--) { + struct stripe *stripe; + + stripe = stripe_lru_pop(sc); + if (stripe) { + /* An lru stripe may never have ios pending!. */ + BUG_ON(stripe_io(stripe)); + stripe_free(stripe); + atomic_dec(&sc->stripes); + } else { + r = -ENOENT; + break; + } + } + + /* Check if stats are still sane. */ + if (atomic_read(&sc->max_active_stripes) > + atomic_read(&sc->stripes)) + atomic_set(&sc->max_active_stripes, 0); + + if (r) + return r; + + ClearRSScBusy(RS(sc)); + return hash_resize(sc); +} + +/* Create stripe cache. */ +static int sc_init(struct raid_set *rs, unsigned stripes) +{ + unsigned i, nr; + struct stripe_cache *sc = &rs->sc; + struct stripe *stripe; + + /* Initialize lists and locks. */ + i = ARRAY_SIZE(sc->lists); + while (i--) + INIT_LIST_HEAD(sc->lists + i); + + i = NR_LOCKS; + while (i--) + spin_lock_init(sc->locks + i); + + /* Initialize atomic variables. */ + atomic_set(&sc->stripes, 0); + atomic_set(&sc->stripes_last, 0); + atomic_set(&sc->stripes_to_shrink, 0); + atomic_set(&sc->active_stripes, 0); + atomic_set(&sc->max_active_stripes, 0); /* REMOVEME: */ + + /* + * We need a runtime unique # to suffix the kmem cache name + * because we'll have one for each active RAID set. + */ + nr = atomic_inc_return(&_stripe_sc_nr); + sprintf(sc->kc.name, "%s_%d", TARGET, nr); + sc->kc.cache = kmem_cache_create(sc->kc.name, stripe_size(rs), + 0, 0, NULL); + if (!sc->kc.cache) + return -ENOMEM; + + /* Create memory cache client context and Allocate memory objects. */ + sc->dm_mem_cache_client = dm_mem_cache_client_create( + stripes * stripe_pages(rs, rs->set.io_size) + + 2 * stripe_pages(rs, rs->recover.io_size), + stripes + 2, rs->set.raid_devs); + if (IS_ERR(sc->dm_mem_cache_client)) + return PTR_ERR(sc->dm_mem_cache_client); + + /* Allocate stripe for set recovery. */ + stripe = stripe_alloc(sc, rs->recover.io_size, keep); + if (!stripe) + return -ENOMEM; + + SetStripeRecover(stripe); + rs->recover.stripe = stripe; + return sc_grow(sc, stripes, keep); /* Grow the cache. */ +} + +/* Destroy the stripe cache. */ +static void sc_exit(struct stripe_cache *sc) +{ + if (sc->hash.hash) { + if (sc->kc.cache) { + BUG_ON(sc_shrink(sc, atomic_read(&sc->stripes))); + kmem_cache_destroy(sc->kc.cache); + } + + if (sc->dm_mem_cache_client) + dm_mem_cache_client_destroy(sc->dm_mem_cache_client); + + hash_exit(&sc->hash); + } +} + +/* + * Calculate RAID address + * + * Delivers tuple with the index of the data disk holding the chunk + * in the set, the parity disks index and the start of the stripe + * within the address space of the set (used as the stripe cache hash key). + */ +/* thx MD. */ +static struct address * +raid_address(struct raid_set *rs, sector_t sector, struct address *addr) +{ + unsigned data_devs = rs->set.data_devs, di, pi, + raid_devs = rs->set.raid_devs; + sector_t stripe, tmp; + + /* + * chunk_number = sector / chunk_size + * stripe = chunk_number / data_devs + * di = stripe % data_devs; + */ + stripe = sector >> rs->set.chunk_shift; + di = sector_div(stripe, data_devs); + + switch (rs->set.raid_type->level) { + case raid5: + tmp = stripe; + pi = sector_div(tmp, raid_devs); + + switch (rs->set.raid_type->algorithm) { + case left_asym: /* Left asymmetric. */ + pi = data_devs - pi; + case right_asym: /* Right asymmetric. */ + if (di >= pi) + di++; + break; + + case left_sym: /* Left symmetric. */ + pi = data_devs - pi; + case right_sym: /* Right symmetric. */ + di = (pi + di + 1) % raid_devs; + break; + + default: + DMERR("Unknown RAID algorithm %d", + rs->set.raid_type->algorithm); + goto out; + } + + break; + + case raid4: + pi = rs->set.pi; + if (di >= pi) + di++; + break; + + default: + DMERR("Unknown RAID level %d", rs->set.raid_type->level); + goto out; + } + + /* + * Hash key = start offset on any single device of the RAID set; + * adjusted in case io size differs from chunk size. + */ + addr->key = (stripe << rs->set.chunk_shift) + + (sector & rs->set.io_shift_mask); + addr->di = di; + addr->pi = pi; + + out: + return addr; +} + +/* + * Copy data across between stripe pages and bio vectors. + * + * Pay attention to data alignment in stripe and bio pages. + */ +static void +bio_copy_page_list(int rw, struct stripe *stripe, + struct page_list *pl, struct bio *bio) +{ + unsigned i, page_offset; + void *page_addr; + struct raid_set *rs = RS(stripe->sc); + struct bio_vec *bv; + + /* Get start page in page list for this sector. */ + i = (bio->bi_sector & rs->set.io_mask) / SECTORS_PER_PAGE; + pl = pl_elem(pl, i); + + page_addr = page_address(pl->page); + page_offset = to_bytes(bio->bi_sector & (SECTORS_PER_PAGE - 1)); + + /* Walk all segments and copy data across between bio_vecs and pages. */ + bio_for_each_segment(bv, bio, i) { + int len = bv->bv_len, size; + unsigned bio_offset = 0; + void *bio_addr = __bio_kmap_atomic(bio, i, KM_USER0); + redo: + size = (page_offset + len > PAGE_SIZE) ? + PAGE_SIZE - page_offset : len; + + if (rw == READ) + memcpy(bio_addr + bio_offset, + page_addr + page_offset, size); + else + memcpy(page_addr + page_offset, + bio_addr + bio_offset, size); + + page_offset += size; + if (page_offset == PAGE_SIZE) { + /* + * We reached the end of the chunk page -> + * need refer to the next one to copy more data. + */ + len -= size; + if (len) { + /* Get next page. */ + pl = pl->next; + BUG_ON(!pl); + page_addr = page_address(pl->page); + page_offset = 0; + bio_offset += size; + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + S_BIO_COPY_PL_NEXT); + goto redo; + } + } + + __bio_kunmap_atomic(bio_addr, KM_USER0); + } +} + +/* + * Xor optimization macros. + */ +/* Xor data pointer declaration and initialization macros. */ +#define DECLARE_2 xor_t *d0 = data[0], *d1 = data[1] +#define DECLARE_3 DECLARE_2, *d2 = data[2] +#define DECLARE_4 DECLARE_3, *d3 = data[3] +#define DECLARE_5 DECLARE_4, *d4 = data[4] +#define DECLARE_6 DECLARE_5, *d5 = data[5] +#define DECLARE_7 DECLARE_6, *d6 = data[6] +#define DECLARE_8 DECLARE_7, *d7 = data[7] + +/* Xor unrole macros. */ +#define D2(n) d0[n] = d0[n] ^ d1[n] +#define D3(n) D2(n) ^ d2[n] +#define D4(n) D3(n) ^ d3[n] +#define D5(n) D4(n) ^ d4[n] +#define D6(n) D5(n) ^ d5[n] +#define D7(n) D6(n) ^ d6[n] +#define D8(n) D7(n) ^ d7[n] + +#define X_2(macro, offset) macro(offset); macro(offset + 1); +#define X_4(macro, offset) X_2(macro, offset); X_2(macro, offset + 2); +#define X_8(macro, offset) X_4(macro, offset); X_4(macro, offset + 4); +#define X_16(macro, offset) X_8(macro, offset); X_8(macro, offset + 8); +#define X_32(macro, offset) X_16(macro, offset); X_16(macro, offset + 16); +#define X_64(macro, offset) X_32(macro, offset); X_32(macro, offset + 32); + +/* Define a _xor_#chunks_#xors_per_run() function. */ +#define _XOR(chunks, xors_per_run) \ +static void _xor ## chunks ## _ ## xors_per_run(xor_t **data) \ +{ \ + unsigned end = XOR_SIZE / sizeof(data[0]), i; \ + DECLARE_ ## chunks; \ +\ + for (i = 0; i < end; i += xors_per_run) { \ + X_ ## xors_per_run(D ## chunks, i); \ + } \ +} + +/* Define xor functions for 2 - 8 chunks. */ +#define MAKE_XOR_PER_RUN(xors_per_run) \ + _XOR(2, xors_per_run); _XOR(3, xors_per_run); \ + _XOR(4, xors_per_run); _XOR(5, xors_per_run); \ + _XOR(6, xors_per_run); _XOR(7, xors_per_run); \ + _XOR(8, xors_per_run); + +MAKE_XOR_PER_RUN(8) /* Define _xor_*_8() functions. */ +MAKE_XOR_PER_RUN(16) /* Define _xor_*_16() functions. */ +MAKE_XOR_PER_RUN(32) /* Define _xor_*_32() functions. */ +MAKE_XOR_PER_RUN(64) /* Define _xor_*_64() functions. */ + +#define MAKE_XOR(xors_per_run) \ +struct { \ + void (*f)(xor_t**); \ +} static xor_funcs ## xors_per_run[] = { \ + { NULL }, \ + { NULL }, \ + { _xor2_ ## xors_per_run }, \ + { _xor3_ ## xors_per_run }, \ + { _xor4_ ## xors_per_run }, \ + { _xor5_ ## xors_per_run }, \ + { _xor6_ ## xors_per_run }, \ + { _xor7_ ## xors_per_run }, \ + { _xor8_ ## xors_per_run }, \ +}; \ +\ +static void xor_ ## xors_per_run(unsigned n, xor_t **data) \ +{ \ + /* Call respective function for amount of chunks. */ \ + xor_funcs ## xors_per_run[n].f(data); \ +} + +/* Define xor_8() - xor_64 functions. */ +MAKE_XOR(8) +MAKE_XOR(16) +MAKE_XOR(32) +MAKE_XOR(64) + +/* Maximum number of chunks, which can be xor'ed in one go. */ +#define XOR_CHUNKS_MAX (ARRAY_SIZE(xor_funcs8) - 1) + +struct xor_func { + xor_function_t f; + const char *name; +} static xor_funcs[] = { + {xor_8, "xor_8"}, + {xor_16, "xor_16"}, + {xor_32, "xor_32"}, + {xor_64, "xor_64"}, +}; + +/* + * Calculate crc. + * + * This indexes into the page list of the stripe. + * + * All chunks will be xored into the parity chunk + * in maximum groups of xor.chunks. + * + * FIXME: try mapping the pages on discontiguous memory. + */ +static void xor(struct stripe *stripe, unsigned pi, unsigned sector) +{ + struct raid_set *rs = RS(stripe->sc); + unsigned max_chunks = rs->xor.chunks, n, p; + unsigned o = sector / SECTORS_PER_PAGE; /* Offset into the page_list. */ + xor_t **d = rs->data; + xor_function_t xor_f = rs->xor.f->f; + + /* Address of parity page to xor into. */ + d[0] = page_address(pl_elem(PL(stripe, pi), o)->page); + + /* Preset pointers to data pages. */ + for (n = 1, p = rs->set.raid_devs; p--; ) { + if (p != pi && PageIO(PAGE(stripe, p))) + d[n++] = page_address(pl_elem(PL(stripe, p), o)->page); + + /* If max chunks -> xor .*/ + if (n == max_chunks) { + xor_f(n, d); + n = 1; + } + } + + /* If chunks -> xor. */ + if (n > 1) + xor_f(n, d); + + /* Set parity page uptodate and clean. */ + page_set(PAGE(stripe, pi), CLEAN); +} + +/* Common xor loop through all stripe page lists. */ +static void common_xor(struct stripe *stripe, sector_t count, + unsigned off, unsigned p) +{ + unsigned sector; + + for (sector = off; sector < count; sector += SECTORS_PER_XOR) + xor(stripe, p, sector); + + atomic_inc(RS(stripe->sc)->stats + S_XORS); /* REMOVEME: statistics. */ +} + +/* + * Calculate parity sectors on intact stripes. + * + * Need to calculate raid address for recover stripe, because its + * chunk sizes differs and is typically larger than io chunk size. + */ +static void parity_xor(struct stripe *stripe) +{ + struct raid_set *rs = RS(stripe->sc); + unsigned chunk_size = rs->set.chunk_size, + io_size = stripe->io.size, + xor_size = chunk_size > io_size ? io_size : chunk_size; + sector_t off; + + + /* This can be the recover stripe with a larger io size. */ + for (off = 0; off < io_size; off += xor_size) { + unsigned pi; + + /* + * Recover stripe likely is bigger than regular io + * ones and has no precalculated parity disk index -> + * need to calculate RAID address. + */ + if (unlikely(StripeRecover(stripe))) { + struct address addr; + + raid_address(rs, + (stripe->key + off) * rs->set.data_devs, + &addr); + pi = addr.pi; + stripe_zero_pl_part(stripe, pi, off, + rs->set.chunk_size); + } else + pi = stripe->idx.parity; + + common_xor(stripe, xor_size, off, pi); + page_set(PAGE(stripe, pi), DIRTY); + } +} + +/* Reconstruct missing chunk. */ +static void reconstruct_xor(struct stripe *stripe) +{ + struct raid_set *rs = RS(stripe->sc); + int p = stripe->idx.recover; + + BUG_ON(p < 0); + + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + (raid_set_degraded(rs) ? + S_RECONSTRUCT_EI : S_RECONSTRUCT_DEV)); + + /* Zero chunk to be reconstructed. */ + stripe_zero_chunk(stripe, p); + common_xor(stripe, stripe->io.size, 0, p); +} + +/* + * Try getting a stripe either from the hash or from the lru list + */ +static inline void _stripe_get(struct stripe *stripe) +{ + atomic_inc(&stripe->cnt); +} + +static struct stripe *stripe_get(struct raid_set *rs, struct address *addr) +{ + struct stripe_cache *sc = &rs->sc; + struct stripe *stripe; + + + stripe = stripe_lookup(sc, addr->key); + if (stripe) { + _stripe_get(stripe); + /* Remove from the lru list if on. */ + stripe_lru_del(stripe, LIST_LOCKED); + atomic_inc(rs->stats + S_HITS_1ST); /* REMOVEME: statistics. */ + } else { + /* Second try to get an LRU stripe. */ + stripe = stripe_lru_pop(sc); + if (stripe) { + _stripe_get(stripe); + /* Invalidate before reinserting with changed key. */ + stripe_invalidate(stripe); + stripe->key = addr->key; + stripe->region = rh_sector_to_region(rs->recover.rh, + addr->key); + stripe->idx.parity = addr->pi; + sc_insert(sc, stripe); + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + S_INSCACHE); + } + } + + return stripe; +} + +/* + * Decrement reference count on a stripe. + * + * Move it to list of LRU stripes if zero. + */ +static void stripe_put(struct stripe *stripe) +{ + if (atomic_dec_and_test(&stripe->cnt)) { + if (TestClearStripeActive(stripe)) + atomic_dec(&stripe->sc->active_stripes); + + /* Put stripe onto the LRU list. */ + stripe_lru_add(stripe, POS_TAIL, LIST_LOCKED); + } + + BUG_ON(atomic_read(&stripe->cnt) < 0); +} + +/* + * Process end io + * + * I need to do it here because I can't in interrupt + * + * Read and write functions are split in order to avoid + * conditionals in the main loop for performamce reasons. + */ +typedef void(*endio_helper_function)(struct stripe *, struct page_list *, + struct bio *); + +/* Helper read bios on a page list. */ +static void _bio_copy_page_list(struct stripe *stripe, struct page_list *pl, + struct bio *bio) +{ + bio_copy_page_list(READ, stripe, pl, bio); +} + +/* Helper write bios on a page list. */ +static void _rh_dec(struct stripe *stripe, struct page_list *pl, + struct bio *bio) +{ + rh_dec(RS(stripe->sc)->recover.rh, stripe->region); +} + +/* End io all bios on a page list. */ +static inline int +page_list_endio(int rw, struct stripe *stripe, unsigned p, unsigned *count) +{ + int r = 0; + struct bio_list *bl = BL(stripe, p, rw); + + if (!bio_list_empty(bl)) { + struct page_list *pl = PL(stripe, p); + struct page *page = pl->page; + + if (PageLocked(page)) + r = -EBUSY; + else if (PageUptodate(page)) { + struct bio *bio; + struct raid_set *rs = RS(stripe->sc); + endio_helper_function h_f = + rw == READ ? _bio_copy_page_list : _rh_dec; + + while ((bio = bio_list_pop(bl))) { + h_f(stripe, pl, bio); + _bio_endio(rs, bio, 0); + stripe_put(stripe); + if (count) + (*count)++; + } + } else + r = -EAGAIN; + } + + return r; +} + +/* + * End io all reads/writes on a stripe copying + * read date accross from stripe to bios. + */ +static int stripe_end_io(int rw, struct stripe *stripe, unsigned *count) +{ + int r = 0; + unsigned p = RS(stripe->sc)->set.raid_devs; + + while (p--) { + int rr = page_list_endio(rw, stripe, p, count); + + if (rr && r != -EIO) + r = rr; + } + + return r; +} + +/* Fail all ios on a bio list and return # of bios. */ +static unsigned +bio_list_fail(struct raid_set *rs, struct stripe *stripe, struct bio_list *bl) +{ + unsigned r; + struct bio *bio; + + raid_set_dead(rs); + + /* Update region counters. */ + if (stripe) { + void *rh = rs->recover.rh; + + bio_list_for_each(bio, bl) { + if (bio_data_dir(bio) == WRITE) + rh_dec(rh, stripe->region); + } + } + + /* Error end io all bios. */ + for (r = 0; (bio = bio_list_pop(bl)); r++) + _bio_endio(rs, bio, -EIO); + + return r; +} + +/* Fail all ios of a bio list of a stripe and drop io pending count. */ +static void +stripe_bio_list_fail(struct raid_set *rs, struct stripe *stripe, + struct bio_list *bl) +{ + unsigned put = bio_list_fail(rs, stripe, bl); + + while (put--) + stripe_put(stripe); +} + +/* Fail all ios hanging off all bio lists of a stripe. */ +static void stripe_fail_io(struct stripe *stripe) +{ + struct raid_set *rs = RS(stripe->sc); + unsigned p = rs->set.raid_devs; + + stripe_evict(stripe); + + while (p--) { + struct stripe_set *ss = stripe->ss + p; + int i = ARRAY_SIZE(ss->bl); + + while (i--) + stripe_bio_list_fail(rs, stripe, ss->bl + i); + } +} + +/* + * Handle all stripes by handing them to the daemon, because we can't + * map their pages to copy the data in interrupt context. + * + * We don't want to handle them here either, while interrupts are disabled. + */ + +/* Read/write endio function for dm-io (interrupt context). */ +static void endio(unsigned long error, void *context) +{ + struct dm_mem_cache_object *obj = context; + struct stripe_set *ss = obj->private; + struct stripe *stripe = ss->stripe; + struct page *page = obj->pl->page; + + if (unlikely(error)) + stripe_error(stripe, page); + else + page_set(page, CLEAN); + + clear_page_locked(page); + stripe_io_dec(stripe); + + /* Add stripe to endio list and wake daemon. */ + stripe_endio_push(stripe); +} + +/* + * Recovery io throttling + */ +/* Conditionally reset io counters. */ +enum count_type { IO_WORK = 0, IO_RECOVER }; +static int recover_io_reset(struct raid_set *rs) +{ + unsigned long j = jiffies; + + /* Pay attention to jiffies overflows. */ + if (j > rs->recover.last_jiffies + HZ + || j < rs->recover.last_jiffies) { + rs->recover.last_jiffies = j; + atomic_set(rs->recover.io_count + IO_WORK, 0); + atomic_set(rs->recover.io_count + IO_RECOVER, 0); + return 1; + } + + return 0; +} + +/* Count ios. */ +static INLINE void +recover_io_count(struct raid_set *rs, struct stripe *stripe) +{ + if (RSRecover(rs)) { + recover_io_reset(rs); + atomic_inc(rs->recover.io_count + + (stripe == rs->recover.stripe ? + IO_RECOVER : IO_WORK)); + } +} + +/* Read/Write a page_list asynchronously. */ +static void page_list_rw(struct stripe *stripe, unsigned p) +{ + struct stripe_cache *sc = stripe->sc; + struct raid_set *rs = RS(sc); + struct dm_mem_cache_object *obj = stripe->obj + p; + struct page_list *pl = obj->pl; + struct page *page = pl->page; + struct raid_dev *dev = rs->dev + p; + struct dm_io_region io = { + .bdev = dev->dev->bdev, + .sector = stripe->key, + .count = stripe->io.size, + }; + struct dm_io_request control = { + .bi_rw = PageDirty(page) ? WRITE : READ, + .mem.type = DM_IO_PAGE_LIST, + .mem.ptr.pl = pl, + .mem.offset = 0, + .notify.fn = endio, + .notify.context = obj, + .client = sc->dm_io_client, + }; + + BUG_ON(PageLocked(page)); + + /* + * Don't rw past end of device, which can happen, because + * typically sectors_per_dev isn't divisable by io_size. + */ + if (unlikely(io.sector + io.count > rs->set.sectors_per_dev)) + io.count = rs->set.sectors_per_dev - io.sector; + + io.sector += dev->start; /* Add . */ + recover_io_count(rs, stripe); /* Recovery io accounting. */ + + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + (PageDirty(page) ? S_DM_IO_WRITE: S_DM_IO_READ)); + + ClearPageError(page); + set_page_locked(page); + io_dev_queued(dev); + BUG_ON(dm_io(&control, 1, &io, NULL)); +} + +/* + * Write dirty / read not uptodate page lists of a stripe. + */ +static unsigned stripe_page_lists_rw(struct raid_set *rs, struct stripe *stripe) +{ + unsigned r; + + /* + * Increment the pending count on the stripe + * first, so that we don't race in endio(). + * + * An inc (IO) is needed for any page: + * + * o not uptodate + * o dirtied by writes merged + * o dirtied by parity calculations + */ + r = for_each_io_dev(rs, stripe, _stripe_io_inc); + if (r) { + /* io needed: chunks are not uptodate/dirty. */ + int max; /* REMOVEME: */ + struct stripe_cache *sc = &rs->sc; + + if (!TestSetStripeActive(stripe)) + atomic_inc(&sc->active_stripes); + + /* Take off the lru list in case it got added there. */ + stripe_lru_del(stripe, LIST_LOCKED); + + /* Submit actual io. */ + for_each_io_dev(rs, stripe, page_list_rw); + + /* REMOVEME: statistics */ + max = sc_active(sc); + if (atomic_read(&sc->max_active_stripes) < max) + atomic_set(&sc->max_active_stripes, max); + + atomic_inc(rs->stats + S_FLUSHS); + /* END REMOVEME: statistics */ + } + + return r; +} + +/* Work in all pending writes. */ +static INLINE void _writes_merge(struct stripe *stripe, unsigned p) +{ + struct bio_list *write = BL(stripe, p, WRITE); + + if (!bio_list_empty(write)) { + struct page_list *pl = stripe->obj[p].pl; + struct bio *bio; + struct bio_list *write_merged = BL(stripe, p, WRITE_MERGED); + + /* + * We can play with the lists without holding a lock, + * because it is just us accessing them anyway. + */ + bio_list_for_each(bio, write) + bio_copy_page_list(WRITE, stripe, pl, bio); + + bio_list_merge(write_merged, write); + bio_list_init(write); + page_set(pl->page, DIRTY); + } +} + +/* Merge in all writes hence dirtying respective pages. */ +static INLINE void writes_merge(struct stripe *stripe) +{ + unsigned p = RS(stripe->sc)->set.raid_devs; + + while (p--) + _writes_merge(stripe, p); +} + +/* Check, if a chunk gets completely overwritten. */ +static INLINE int stripe_check_overwrite(struct stripe *stripe, unsigned p) +{ + unsigned sectors = 0; + struct bio *bio; + struct bio_list *bl = BL(stripe, p, WRITE); + + bio_list_for_each(bio, bl) + sectors += bio_sectors(bio); + + return sectors == RS(stripe->sc)->set.io_size; +} + +/* + * Prepare stripe to avoid io on broken/reconstructed + * drive to be reconstructed on endio. + */ +enum prepare_type { IO_ALLOW, IO_PROHIBIT }; +static void stripe_prepare(struct stripe *stripe, unsigned p, + enum prepare_type type) +{ + struct page *page = PAGE(stripe, p); + + switch (type) { + case IO_PROHIBIT: + /* REMOVEME: statistics. */ + atomic_inc(RS(stripe->sc)->stats + S_PROHIBITPAGEIO); + ProhibitPageIO(page); + stripe->idx.recover = p; + SetStripeReconstruct(stripe); + break; + + case IO_ALLOW: + AllowPageIO(page); + stripe->idx.recover = -1; + ClearStripeReconstruct(stripe); + break; + + default: + BUG(); + } +} + +/* + * Degraded/reconstruction mode. + * + * Check stripe state to figure which chunks don't need IO. + */ +static INLINE void stripe_check_reconstruct(struct stripe *stripe, + int prohibited) +{ + struct raid_set *rs = RS(stripe->sc); + + /* + * Degraded mode (device(s) failed) -> + * avoid io on the failed device. + */ + if (unlikely(raid_set_degraded(rs))) { + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + S_DEGRADED); + stripe_prepare(stripe, rs->set.ei, IO_PROHIBIT); + return; + } else { + /* + * Reconstruction mode (ie. a particular device or + * some (rotating) parity chunk is being resynchronized) -> + * o make sure all needed pages are read in + * o writes are allowed to go through + */ + int r = region_state(rs, stripe->key, RH_NOSYNC); + + if (r) { + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + S_NOSYNC); + stripe_prepare(stripe, dev_for_parity(stripe), + IO_PROHIBIT); + return; + } + } + + /* + * All disks good. Avoid reading parity chunk and reconstruct it + * unless we have prohibited io to chunk(s). + */ + if (!prohibited) { + if (StripeMerged(stripe)) + stripe_prepare(stripe, stripe->idx.parity, IO_ALLOW); + else { + stripe_prepare(stripe, stripe->idx.parity, IO_PROHIBIT); + ClearStripeReconstruct(stripe); + } + } +} + +/* Check, if stripe is ready to merge writes. */ +static INLINE int stripe_check_merge(struct stripe *stripe) +{ + struct raid_set *rs = RS(stripe->sc); + int prohibited = 0; + unsigned chunks = 0, p = rs->set.raid_devs; + + /* Walk all chunks. */ + while (p--) { + struct page *page = PAGE(stripe, p); + + /* Can't merge active chunks. */ + if (PageLocked(page)) { + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + S_MERGE_PAGE_LOCKED); + break; + } + + /* Can merge uptodate chunks and have to count parity chunk. */ + if (PageUptodate(page) || p == stripe->idx.parity) { + chunks++; + continue; + } + + /* Read before write ordering. */ + if (RSCheckOverwrite(rs) && + bio_list_empty(BL(stripe, p, READ))) { + int r = stripe_check_overwrite(stripe, p); + + if (r) { + chunks++; + /* REMOVEME: statistics. */ + atomic_inc(RS(stripe->sc)->stats + + S_PROHIBITPAGEIO); + ProhibitPageIO(page); + prohibited = 1; + } + } + } + + if (chunks == rs->set.raid_devs) { + /* All pages are uptodate or get written over or mixture. */ + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + S_CAN_MERGE); + return 0; + } else + /* REMOVEME: statistics.*/ + atomic_inc(rs->stats + S_CANT_MERGE); + + return prohibited ? 1 : -EPERM; +} + +/* Check, if stripe is ready to merge writes. */ +static INLINE int stripe_check_read(struct stripe *stripe) +{ + int r = 0; + unsigned p = RS(stripe->sc)->set.raid_devs; + + /* Walk all chunks. */ + while (p--) { + struct page *page = PAGE(stripe, p); + + if (!PageLocked(page) && + bio_list_empty(BL(stripe, p, READ))) { + ProhibitPageIO(page); + r = 1; + } + } + + return r; +} + +/* + * Read/write a stripe. + * + * States to cover: + * o stripe to read and/or write + * o stripe with error to reconstruct + */ +static int stripe_rw(struct stripe *stripe) +{ + struct raid_set *rs = RS(stripe->sc); + int prohibited = 0, r; + + /* + * Check the state of the RAID set and if degraded (or + * resynchronizing for reads), read in all other chunks but + * the one on the dead/resynchronizing device in order to be + * able to reconstruct the missing one. + * + * Merge all writes hanging off uptodate pages of the stripe. + */ + + /* Initially allow io on all chunks and prohibit below, if necessary. */ + stripe_allow_io(stripe); + + if (StripeRBW(stripe)) { + r = stripe_check_merge(stripe); + if (!r) { + /* + * If I could rely on valid parity (which would only + * be sure in case of a full synchronization), + * I could xor a fraction of chunks out of + * parity and back in. + * + * For the time being, I got to redo parity... + */ + // parity_xor(stripe); /* Xor chunks out. */ + stripe_zero_chunk(stripe, stripe->idx.parity); + writes_merge(stripe); /* Merge writes in. */ + parity_xor(stripe); /* Update parity. */ + ClearStripeRBW(stripe); /* Disable RBW. */ + SetStripeMerged(stripe); /* Writes merged. */ + } + + if (r > 0) + prohibited = 1; + } else if (!raid_set_degraded(rs)) + prohibited = stripe_check_read(stripe); + + /* + * Check, if io needs to be allowed/prohibeted on certain chunks + * because of a degraded set or reconstruction on a region. + */ + stripe_check_reconstruct(stripe, prohibited); + + /* Now submit any reads/writes. */ + r = stripe_page_lists_rw(rs, stripe); + if (!r) { + /* + * No io submitted because of chunk io prohibited or + * locked pages -> push to end io list for processing. + */ + atomic_inc(rs->stats + S_NO_RW); /* REMOVEME: statistics. */ + stripe_endio_push(stripe); + wake_do_raid(rs); /* Wake myself. */ + } + + return 0; +} + +/* Flush stripe either via flush list or imeediately. */ +enum flush_type { FLUSH_DELAY, FLUSH_NOW }; +static int stripe_flush(struct stripe *stripe, enum flush_type type) +{ + int r = 0; + + stripe_lru_del(stripe, LIST_LOCKED); + + /* Delay flush by putting it on io list for later processing. */ + if (type == FLUSH_DELAY) + stripe_io_add(stripe, POS_TAIL, LIST_UNLOCKED); + + /* Immediately flush. */ + else if (type == FLUSH_NOW) { + if (likely(raid_set_operational(RS(stripe->sc)))) + r = stripe_rw(stripe); /* Read/write stripe. */ + else + /* Optimization: Fail early on failed sets. */ + stripe_fail_io(stripe); + } else + BUG(); + + return r; +} + +/* + * Queue reads and writes to a stripe by hanging + * their bios off the stripsets read/write lists. + * + * Endio reads on uptodate chunks. + */ +static INLINE int stripe_queue_bio(struct raid_set *rs, struct bio *bio, + struct bio_list *reject) +{ + int r = 0; + struct address addr; + struct stripe *stripe = + stripe_get(rs, raid_address(rs, bio->bi_sector, &addr)); + + if (stripe) { + int rr, rw = bio_data_dir(bio); + + rr = stripe_lock(rs, stripe, rw, addr.key); /* Lock stripe */ + if (rr) { + stripe_put(stripe); + goto out; + } + + /* Distinguish read and write cases. */ + bio_list_add(BL(stripe, addr.di, rw), bio); + + /* REMOVEME: statistics */ + atomic_inc(rs->stats + (rw == WRITE ? + S_BIOS_ADDED_WRITE : S_BIOS_ADDED_READ)); + + if (rw == READ) + SetStripeRead(stripe); + else { + SetStripeRBW(stripe); + + /* Inrement pending write count on region. */ + rh_inc(rs->recover.rh, stripe->region); + r = 1; /* Region hash needs a flush. */ + } + + /* + * Optimize stripe flushing: + * + * o directly start io for read stripes. + * + * o put stripe onto stripe caches io_list for RBW, + * so that do_flush() can belabour it after we put + * more bios to the stripe for overwrite optimization. + */ + stripe_flush(stripe, + StripeRead(stripe) ? FLUSH_NOW : FLUSH_DELAY); + + /* Got no stripe from cache -> reject bio. */ + } else { + out: + bio_list_add(reject, bio); + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + S_IOS_POST); + } + + return r; +} + +/* + * Recovery functions + */ +/* Read a stripe off a raid set for recovery. */ +static int recover_read(struct raid_set *rs, struct stripe *stripe, int idx) +{ + /* Invalidate all pages so that they get read in. */ + stripe_pages_invalidate(stripe); + + /* Allow io on all recovery chunks. */ + stripe_allow_io(stripe); + + if (idx > -1) + ProhibitPageIO(PAGE(stripe, idx)); + + stripe->key = rs->recover.pos; + return stripe_page_lists_rw(rs, stripe); +} + +/* Write a stripe to a raid set for recovery. */ +static int recover_write(struct raid_set *rs, struct stripe *stripe, int idx) +{ + /* + * If this is a reconstruct of a particular device, then + * reconstruct the respective page(s), else create parity page(s). + */ + if (idx > -1) { + struct page *page = PAGE(stripe, idx); + + AllowPageIO(page); + stripe_zero_chunk(stripe, idx); + common_xor(stripe, stripe->io.size, 0, idx); + page_set(page, DIRTY); + } else + parity_xor(stripe); + + return stripe_page_lists_rw(rs, stripe); +} + +/* Recover bandwidth available ?. */ +static int recover_bandwidth(struct raid_set *rs) +{ + int r, work; + + /* On reset -> allow recovery. */ + r = recover_io_reset(rs); + if (r || RSBandwidth(rs)) + goto out; + + work = atomic_read(rs->recover.io_count + IO_WORK); + if (work) { + /* Pay attention to larger recover stripe size. */ + int recover = + atomic_read(rs->recover.io_count + IO_RECOVER) * + rs->recover.stripe->io.size / + rs->set.io_size; + + /* + * Don't use more than given bandwidth of + * the work io for recovery. + */ + if (recover > work / rs->recover.bandwidth_work) { + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + S_NO_BANDWIDTH); + return 0; + } + } + + out: + atomic_inc(rs->stats + S_BANDWIDTH); /* REMOVEME: statistics. */ + return 1; +} + +/* Try to get a region to recover. */ +static int recover_get_region(struct raid_set *rs) +{ + struct recover *rec = &rs->recover; + void *rh = rec->rh; + + /* Start quiescing some regions. */ + if (!RSRegionGet(rs)) { + int r = recover_bandwidth(rs); /* Enough bandwidth ?. */ + + if (r) { + if (rh_recovery_prepare(rh) < 0) { + DMINFO("No %sregions to recover", + rec->nr_regions_to_recover ? + "more " : ""); + return -ENOENT; + } + } else + return -EAGAIN; + + SetRSRegionGet(rs); + } + + if (!rec->reg) { + rec->reg = rh_recovery_start(rh); + if (rec->reg) { + /* + * A reference for the the region I'll + * keep till I've completely synced it. + */ + io_get(rs); + rec->pos = + rh_region_to_sector(rh, + rh_get_region_key(rec->reg)); + rec->end = rec->pos + rh_get_region_size(rh); + return 1; + } else + return -EAGAIN; + } + + return 0; +} + +/* Read/write a recovery stripe. */ +static INLINE int recover_stripe_rw(struct raid_set *rs, struct stripe *stripe) +{ + /* Read/write flip-flop. */ + if (TestClearStripeRBW(stripe)) { + SetStripeRead(stripe); + return recover_read(rs, stripe, idx_get(rs)); + } else if (TestClearStripeRead(stripe)) + return recover_write(rs, stripe, idx_get(rs)); + + return 0; +} + +/* Reset recovery variables. */ +static void recovery_region_reset(struct raid_set *rs) +{ + rs->recover.reg = NULL; + ClearRSRegionGet(rs); +} + +/* Update region hash state. */ +static void recover_rh_update(struct raid_set *rs, int error) +{ + struct recover *rec = &rs->recover; + void *rh = rec->rh; + void *reg = rec->reg; + + if (reg) { + rh_recovery_end(reg, error); + if (!error) + rec->nr_regions_recovered++; + + recovery_region_reset(rs); + } + + rh_update_states(rh); + rh_flush(rh); + io_put(rs); /* Release the io reference for the region. */ +} + +/* Called by main io daemon to recover regions. */ +static INLINE void do_recovery(struct raid_set *rs) +{ + if (RSRecover(rs)) { + int r; + struct recover *rec = &rs->recover; + struct stripe *stripe = rec->stripe; + + /* If recovery is active -> return. */ + if (StripeActive(stripe)) + return; + + /* io error is fatal for recovery -> stop it. */ + if (unlikely(StripeError(stripe))) + goto err; + + /* Get a region to recover. */ + r = recover_get_region(rs); + switch (r) { + case 1: /* Got a new region. */ + /* Flag read before write. */ + ClearStripeRead(stripe); + SetStripeRBW(stripe); + break; + + case 0: + /* Got a region in the works. */ + r = recover_bandwidth(rs); + if (r) /* Got enough bandwidth. */ + break; + + case -EAGAIN: + /* No bandwidth/quiesced region yet, try later. */ + wake_do_raid_delayed(rs, HZ / 10); + return; + + case -ENOENT: /* No more regions. */ + goto free; + } + + /* Read/write a recover stripe. */ + r = recover_stripe_rw(rs, stripe); + if (r) { + /* Io initiated, get another reference for the IO. */ + io_get(rs); + return; + } + + /* Update recovery position within region. */ + rec->pos += stripe->io.size; + + /* If we're at end of region, update region hash. */ + if (rec->pos >= rec->end || + rec->pos >= rs->set.sectors_per_dev) + recover_rh_update(rs, 0); + else + SetStripeRBW(stripe); + + /* Schedule myself for another round... */ + wake_do_raid(rs); + return; + + err: + raid_set_check_degrade(rs, stripe); + + { + char buf[BDEVNAME_SIZE]; + + DMERR("stopping recovery due to " + "ERROR on /dev/%s, stripe at offset %llu", + bdevname(rs->dev[rs->set.ei].dev->bdev, buf), + (unsigned long long) stripe->key); + + } + + /* Make sure, that all quiesced regions get released. */ + do { + if (rec->reg) + rh_recovery_end(rec->reg, -EIO); + + rec->reg = rh_recovery_start(rec->rh); + } while (rec->reg); + + recover_rh_update(rs, -EIO); + free: + stripe_recover_free(rs); + rs->set.dev_to_init = -1; + rs->recover.end_jiffies = jiffies; + /* Check for jiffies overrun. */ + if (rs->recover.end_jiffies < rs->recover.start_jiffies) + rs->recover.end_jiffies = ~0; + } +} + +/* + * END recovery functions + */ + +/* End io process all stripes handed in by endio() callback. */ +static void do_endios(struct raid_set *rs) +{ + struct stripe_cache *sc = &rs->sc; + struct stripe *stripe; + + while ((stripe = stripe_endio_pop(sc))) { + unsigned count; + + /* Recovery stripe special case. */ + if (unlikely(StripeRecover(stripe))) { + if (stripe_io(stripe)) + continue; + + io_put(rs); /* Release region io reference. */ + ClearStripeActive(stripe); + atomic_dec(&sc->active_stripes); /* REMOVEME: */ + continue; + } + + /* Early end io all reads on any uptodate chunks. */ + stripe_end_io(READ, stripe, (count = 0, &count)); + if (stripe_io(stripe)) { + if (count) /* REMOVEME: statistics. */ + atomic_inc(rs->stats + S_ACTIVE_READS); + + continue; + } + + /* Set stripe inactive after all io got processed. */ + if (TestClearStripeActive(stripe)) + atomic_dec(&sc->active_stripes); + + /* Unlock stripe (for clustering). */ + stripe_unlock(rs, stripe); + + /* + * If an io error on a stripe occured and the RAID set + * is still operational, requeue the stripe for io. + */ + if (TestClearStripeError(stripe)) { + raid_set_check_degrade(rs, stripe); + ClearStripeReconstruct(stripe); + + if (!StripeMerged(stripe) && + raid_set_operational(rs)) { + stripe_pages_invalidate(stripe); + stripe_flush(stripe, FLUSH_DELAY); + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + S_REQUEUE); + continue; + } + } + + /* Check if the RAID set is inoperational to error ios. */ + if (!raid_set_operational(rs)) { + ClearStripeReconstruct(stripe); + stripe_fail_io(stripe); + BUG_ON(atomic_read(&stripe->cnt)); + continue; + } + + /* Got to reconstruct a missing chunk. */ + if (TestClearStripeReconstruct(stripe)) + reconstruct_xor(stripe); + + /* + * Now that we've got a complete stripe, we can + * process the rest of the end ios on reads. + */ + BUG_ON(stripe_end_io(READ, stripe, NULL)); + ClearStripeRead(stripe); + + /* + * Read-before-write stripes need to be flushed again in + * order to work the write data into the pages *after* + * they were read in. + */ + if (TestClearStripeMerged(stripe)) + /* End io all bios which got merged already. */ + BUG_ON(stripe_end_io(WRITE_MERGED, stripe, NULL)); + + /* Got to put on flush list because of new writes. */ + if (StripeRBW(stripe)) + stripe_flush(stripe, FLUSH_DELAY); + } +} + +/* + * Stripe cache shrinking. + */ +static INLINE void do_sc_shrink(struct raid_set *rs) +{ + unsigned shrink = atomic_read(&rs->sc.stripes_to_shrink); + + if (shrink) { + unsigned cur = atomic_read(&rs->sc.stripes); + + sc_shrink(&rs->sc, shrink); + shrink -= cur - atomic_read(&rs->sc.stripes); + atomic_set(&rs->sc.stripes_to_shrink, shrink); + + /* + * Wake myself up in case we failed to shrink the + * requested amount in order to try again later. + */ + if (shrink) + wake_do_raid(rs); + } +} + + +/* + * Process all ios + * + * We do different things with the io depending on the + * state of the region that it's in: + * + * o reads: hang off stripe cache or postpone if full + * + * o writes: + * + * CLEAN/DIRTY/NOSYNC: increment pending and hang io off stripe's stripe set. + * In case stripe cache is full or busy, postpone the io. + * + * RECOVERING: delay the io until recovery of the region completes. + * + */ +static INLINE void do_ios(struct raid_set *rs, struct bio_list *ios) +{ + int r; + unsigned flush = 0; + void *rh = rs->recover.rh; + struct bio *bio; + struct bio_list delay, reject; + + bio_list_init(&delay); + bio_list_init(&reject); + + /* + * Classify each io: + * o delay to recovering regions + * o queue to all other regions + */ + while ((bio = bio_list_pop(ios))) { + /* + * In case we get a barrier bio, push it back onto + * the input queue unless all work queues are empty + * and the stripe cache is inactive. + */ + if (unlikely(bio_barrier(bio))) { + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + S_BARRIER); + if (!list_empty(rs->sc.lists + LIST_IO) || + !bio_list_empty(&delay) || + !bio_list_empty(&reject) || + sc_active(&rs->sc)) { + bio_list_push(ios, bio); + break; + } + } + + r = region_state(rs, _sector(rs, bio), RH_RECOVERING); + if (unlikely(r)) { + /* Got to wait for recovering regions. */ + bio_list_add(&delay, bio); + SetRSBandwidth(rs); + } else { + /* + * Process ios to non-recovering regions by queueing + * them to stripes (does rh_inc()) for writes). + */ + flush += stripe_queue_bio(rs, bio, &reject); + } + } + + if (flush) + rh_flush(rh); /* Writes got queued -> flush dirty log. */ + + /* Delay ios to regions which are recovering. */ + while ((bio = bio_list_pop(&delay))) { + /* REMOVEME: statistics.*/ + atomic_inc(rs->stats + S_DELAYED_BIOS); + atomic_inc(rs->stats + S_SUM_DELAYED_BIOS); + rh_delay_by_region(rh, bio, + rh_sector_to_region(rh, _sector(rs, bio))); + } + + /* Merge any rejected bios back to the head of the input list. */ + bio_list_merge_head(ios, &reject); +} + +/* Flush any stripes on the io list. */ +static INLINE void do_flush(struct raid_set *rs) +{ + struct list_head *list = rs->sc.lists + LIST_IO, *pos, *tmp; + + list_for_each_safe(pos, tmp, list) { + int r = stripe_flush(list_entry(pos, struct stripe, + lists[LIST_IO]), FLUSH_NOW); + + /* Remove from the list only if the stripe got processed. */ + if (!r) + list_del_init(pos); + } +} + +/* Send an event in case we're getting too busy. */ +static INLINE void do_busy_event(struct raid_set *rs) +{ + if ((sc_active(&rs->sc) > atomic_read(&rs->sc.stripes) * 4 / 5)) { + if (!TestSetRSScBusy(rs)) + dm_table_event(rs->ti->table); + } else + ClearRSScBusy(rs); +} + +/* Unplug: let the io role on the sets devices. */ +static INLINE void do_unplug(struct raid_set *rs) +{ + struct raid_dev *dev = rs->dev + rs->set.raid_devs; + + while (dev-- > rs->dev) { + /* Only call any device unplug function, if io got queued. */ + if (io_dev_clear(dev)) { + struct request_queue *q = + bdev_get_queue(dev->dev->bdev); + + if (q->unplug_fn) + q->unplug_fn(q); + } + } +} + +/*----------------------------------------------------------------- + * RAID daemon + *---------------------------------------------------------------*/ +/* + * o belabour all end ios + * o optionally shrink the stripe cache + * o update the region hash states + * o optionally do recovery + * o grab the input queue + * o work an all requeued or new ios and perform stripe cache flushs + * unless the RAID set is inoperational (when we error ios) + * o check, if the stripe cache gets too busy and throw an event if so + * o unplug any component raid devices with queued bios + */ +static void do_raid(struct work_struct *ws) +{ + struct raid_set *rs = container_of(ws, struct raid_set, io.dws.work); + struct bio_list *ios = &rs->io.work, *ios_in = &rs->io.in; + spinlock_t *lock = &rs->io.in_lock; + + /* + * We always need to end io, so that ios + * can get errored in case the set failed + * and the region counters get decremented + * before we update the region hash states. + */ + redo: + do_endios(rs); + + /* + * Now that we've end io'd, which may have put stripes on + * the LRU list, we shrink the stripe cache if requested. + */ + do_sc_shrink(rs); + + /* Update region hash states before we go any further. */ + rh_update_states(rs->recover.rh); + + /* Try to recover regions. */ + do_recovery(rs); + + /* More endios -> process. */ + if (!stripe_endio_empty(&rs->sc)) { + atomic_inc(rs->stats + S_REDO); + goto redo; + } + + /* Quickly grab all new ios queued and add them to the work list. */ + spin_lock_irq(lock); + bio_list_merge(ios, ios_in); + bio_list_init(ios_in); + spin_unlock_irq(lock); + + /* Let's assume we're operational most of the time ;-). */ + if (likely(raid_set_operational(rs))) { + /* If we got ios, work them into the cache. */ + if (!bio_list_empty(ios)) { + do_ios(rs, ios); + do_unplug(rs); /* Unplug the sets device queues. */ + } + + do_flush(rs); /* Flush any stripes on io list. */ + do_unplug(rs); /* Unplug the sets device queues. */ + do_busy_event(rs); /* Check if we got too busy. */ + + /* More endios -> process. */ + if (!stripe_endio_empty(&rs->sc)) { + atomic_inc(rs->stats + S_REDO); + goto redo; + } + } else + /* No way to reconstruct data with too many devices failed. */ + bio_list_fail(rs, NULL, ios); +} + +/* + * Callback for region hash to dispatch + * delayed bios queued to recovered regions + * (Gets called via rh_update_states()). + */ +static void dispatch_delayed_bios(void *context, struct bio_list *bl) +{ + struct raid_set *rs = context; + struct bio *bio; + + /* REMOVEME: decrement pending delayed bios counter. */ + bio_list_for_each(bio, bl) + atomic_dec(rs->stats + S_DELAYED_BIOS); + + /* Merge region hash private list to work list. */ + bio_list_merge_head(&rs->io.work, bl); + bio_list_init(bl); + ClearRSBandwidth(rs); +} + +/************************************************************* + * Constructor helpers + *************************************************************/ +#define XOR_SPEED_SIZE rs->recover.io_size + +/* Calculate MB/sec. */ +static INLINE unsigned mbpers(struct raid_set *rs, unsigned speed) +{ + return to_bytes(speed * rs->set.data_devs * + XOR_SPEED_SIZE * HZ >> 10) >> 10; +} + +/* + * Discover fastest xor algorithm and # of chunks combination. + */ +/* Calculate speed for algorithm and # of chunks. */ +static INLINE unsigned xor_speed(struct raid_set *rs) +{ + unsigned r = 0; + unsigned long j; + + for (j = jiffies; j == jiffies;); /* Wait for next tick. */ + + /* Do xors for a full tick. */ + for (j = jiffies; j == jiffies;) { + mb(); + common_xor(rs->recover.stripe, XOR_SPEED_SIZE, 0, 0); + mb(); + r++; + mb(); + } + + return r; +} + +/* Optimize xor algorithm for this RAID set. */ +static unsigned xor_optimize(struct raid_set *rs) +{ + unsigned chunks_max = 2, speed_max = 0; + struct xor_func *f = ARRAY_END(xor_funcs), *f_max = NULL; + + /* + * Got to allow io on all chunks, so that + * xor() will actually work on them. + */ + stripe_allow_io(rs->recover.stripe); + + /* Try all xor functions. */ + while (f-- > xor_funcs) { + unsigned speed; + + /* Set actual xor function for common_xor(). */ + rs->xor.f = f; + rs->xor.chunks = XOR_CHUNKS_MAX + 1; + + while (rs->xor.chunks-- > 2) { + speed = xor_speed(rs); + if (speed > speed_max) { + speed_max = speed; + chunks_max = rs->xor.chunks; + f_max = f; + } + } + } + + /* Memorize optimum parameters. */ + rs->xor.f = f_max; + rs->xor.chunks = chunks_max; + return speed_max; +} + +/* + * Allocate a RAID context (a RAID set) + */ +static int +context_alloc(struct raid_set **raid_set, struct raid_type *raid_type, + unsigned stripes, unsigned chunk_size, unsigned io_size, + unsigned recover_io_size, unsigned raid_devs, + sector_t sectors_per_dev, + struct dm_target *ti, unsigned dl_parms, char **argv) +{ + int r; + unsigned p; + size_t len; + sector_t region_size, ti_len; + struct raid_set *rs = NULL; + struct dm_dirty_log *dl; + + /* + * Create the dirty log + * + * We need to change length for the dirty log constructor, + * because we want an amount of regions for all stripes derived + * from the single device size, so that we can keep region + * size = 2^^n independant of the number of devices + */ + ti_len = ti->len; + ti->len = sectors_per_dev; + dl = dm_dirty_log_create(argv[0], ti, dl_parms, argv + 2); + ti->len = ti_len; + if (!dl) + goto bad_dirty_log; + + /* Chunk size *must* be smaller than region size. */ + region_size = dl->type->get_region_size(dl); + if (chunk_size > region_size) + goto bad_chunk_size; + + /* Recover io size *must* be smaller than region size as well. */ + if (recover_io_size > region_size) + goto bad_recover_io_size; + + /* Size and allocate the RAID set structure. */ + len = sizeof(*rs->data) + sizeof(*rs->dev); + if (dm_array_too_big(sizeof(*rs), len, raid_devs)) + goto bad_array; + + len = sizeof(*rs) + raid_devs * len; + rs = kzalloc(len, GFP_KERNEL); + if (!rs) + goto bad_alloc; + + atomic_set(&rs->io.in_process, 0); + atomic_set(&rs->io.in_process_max, 0); + rs->recover.io_size = recover_io_size; + + /* Pointer to data array. */ + rs->data = (xor_t **) ((void *) rs->dev + raid_devs * sizeof(*rs->dev)); + rs->recover.dl = dl; + rs->set.raid_devs = p = raid_devs; + rs->set.data_devs = raid_devs - raid_type->parity_devs; + rs->set.raid_type = raid_type; + + /* + * Set chunk and io size and respective shifts + * (used to avoid divisions) + */ + rs->set.chunk_size = chunk_size; + rs->set.chunk_mask = chunk_size - 1; + rs->set.chunk_shift = ffs(chunk_size) - 1; + + rs->set.io_size = io_size; + rs->set.io_mask = io_size - 1; + rs->set.io_shift = ffs(io_size) - 1; + rs->set.io_shift_mask = rs->set.chunk_mask & ~rs->set.io_mask; + + rs->set.pages_per_io = chunk_pages(io_size); + rs->set.sectors_per_dev = sectors_per_dev; + + rs->set.ei = -1; /* Indicate no failed device. */ + atomic_set(&rs->set.failed_devs, 0); + + rs->ti = ti; + + atomic_set(rs->recover.io_count + IO_WORK, 0); + atomic_set(rs->recover.io_count + IO_RECOVER, 0); + + /* Initialize io lock and queues. */ + spin_lock_init(&rs->io.in_lock); + bio_list_init(&rs->io.in); + bio_list_init(&rs->io.work); + + init_waitqueue_head(&rs->io.suspendq); /* Suspend waiters (dm-io). */ + + rs->recover.nr_regions = dm_sector_div_up(sectors_per_dev, region_size); + r = rh_init(&rs->recover.rh, 1, dispatch_delayed_bios, rs, + wake_do_raid, rs, dl, region_size, + rs->recover.nr_regions); + if (r) + goto bad_rh; + + /* Initialize stripe cache. */ + r = sc_init(rs, stripes); + if (r) + goto bad_sc; + + /* Create dm-io client context. */ + rs->sc.dm_io_client = dm_io_client_create(rs->set.raid_devs * + rs->set.pages_per_io); + if (IS_ERR(rs->sc.dm_io_client)) + goto bad_dm_io_client; + + /* REMOVEME: statistics. */ + stats_reset(rs); + ClearRSDevelStats(rs); /* Disnable development status. */ + + *raid_set = rs; + return 0; + + bad_dirty_log: + TI_ERR_RET("Error creating dirty log", -ENOMEM); + + + bad_chunk_size: + dm_dirty_log_destroy(dl); + TI_ERR("Chunk size larger than region size"); + + bad_recover_io_size: + dm_dirty_log_destroy(dl); + TI_ERR("Recover stripe io size larger than region size"); + + bad_array: + dm_dirty_log_destroy(dl); + TI_ERR("Arry too big"); + + bad_alloc: + dm_dirty_log_destroy(dl); + TI_ERR_RET("Cannot allocate raid context", -ENOMEM); + + bad_rh: + dm_dirty_log_destroy(dl); + ti->error = DM_MSG_PREFIX "Error creating dirty region hash"; + goto free_rs; + + bad_sc: + ti->error = DM_MSG_PREFIX "Error creating stripe cache"; + goto free; + + bad_dm_io_client: + ti->error = DM_MSG_PREFIX "Error allocating dm-io resources"; + free: + sc_exit(&rs->sc); + rh_exit(rs->recover.rh); + free_rs: + kfree(rs); + return -ENOMEM; +} + +/* Free a RAID context (a RAID set). */ +static void +context_free(struct raid_set *rs, struct dm_target *ti, unsigned r) +{ + while (r--) + dm_put_device(ti, rs->dev[r].dev); + + dm_io_client_destroy(rs->sc.dm_io_client); + stripe_recover_free(rs); + sc_exit(&rs->sc); + rh_exit(rs->recover.rh); /* Destroys dirty log as well. */ + kfree(rs); +} + +/* Create work queue and initialize work. */ +static int rs_workqueue_init(struct raid_set *rs) +{ + struct dm_target *ti = rs->ti; + + rs->io.wq = create_singlethread_workqueue(DAEMON); + if (!rs->io.wq) + TI_ERR_RET("failed to create " DAEMON, -ENOMEM); + + INIT_DELAYED_WORK(&rs->io.dws, do_raid); + return 0; +} + +/* Return pointer to raid_type structure for raid name. */ +static struct raid_type *get_raid_type(char *name) +{ + struct raid_type *r = ARRAY_END(raid_types); + + while (r-- > raid_types) { + if (!strnicmp(STR_LEN(r->name, name))) + return r; + } + + return NULL; +} + +/* FIXME: factor out to dm core. */ +static int multiple(sector_t a, sector_t b, sector_t *n) +{ + sector_t r = a; + + sector_div(r, b); + *n = r; + return a == r * b; +} + +/* Log RAID set information to kernel log. */ +static void raid_set_log(struct raid_set *rs, unsigned speed) +{ + unsigned p; + char buf[BDEVNAME_SIZE]; + + for (p = 0; p < rs->set.raid_devs; p++) + DMINFO("/dev/%s is raid disk %u", + bdevname(rs->dev[p].dev->bdev, buf), p); + + DMINFO("%d/%d/%d sectors chunk/io/recovery size, %u stripes", + rs->set.chunk_size, rs->set.io_size, rs->recover.io_size, + atomic_read(&rs->sc.stripes)); + DMINFO("algorithm \"%s\", %u chunks with %uMB/s", rs->xor.f->name, + rs->xor.chunks, mbpers(rs, speed)); + DMINFO("%s set with net %u/%u devices", rs->set.raid_type->descr, + rs->set.data_devs, rs->set.raid_devs); +} + +/* Get all devices and offsets. */ +static int +dev_parms(struct dm_target *ti, struct raid_set *rs, + char **argv, int *p) +{ + for (*p = 0; *p < rs->set.raid_devs; (*p)++, argv += 2) { + int r; + unsigned long long tmp; + struct raid_dev *dev = rs->dev + *p; + union dev_lookup dl = {.dev = dev }; + + /* Get offset and device. */ + r = sscanf(argv[1], "%llu", &tmp); + if (r != 1) + TI_ERR("Invalid RAID device offset parameter"); + + dev->start = tmp; + r = dm_get_device(ti, argv[0], dev->start, + rs->set.sectors_per_dev, + dm_table_get_mode(ti->table), &dev->dev); + if (r) + TI_ERR_RET("RAID device lookup failure", r); + + r = raid_dev_lookup(rs, bynumber, &dl); + if (r != -ENODEV && r < *p) { + (*p)++; /* Ensure dm_put_device() on actual device. */ + TI_ERR_RET("Duplicate RAID device", -ENXIO); + } + } + + return 0; +} + +/* Set recovery bandwidth. */ +static INLINE void +recover_set_bandwidth(struct raid_set *rs, unsigned bandwidth) +{ + rs->recover.bandwidth = bandwidth; + rs->recover.bandwidth_work = 100 / bandwidth; +} + +/* Handle variable number of RAID parameters. */ +static int +raid_variable_parms(struct dm_target *ti, char **argv, + unsigned i, int *raid_parms, + int *chunk_size, int *chunk_size_parm, + int *stripes, int *stripes_parm, + int *io_size, int *io_size_parm, + int *recover_io_size, int *recover_io_size_parm, + int *bandwidth, int *bandwidth_parm) +{ + /* Fetch # of variable raid parameters. */ + if (sscanf(argv[i++], "%d", raid_parms) != 1 || + !range_ok(*raid_parms, 0, 5)) + TI_ERR("Bad variable raid parameters number"); + + if (*raid_parms) { + /* + * If we've got variable RAID parameters, + * chunk size is the first one + */ + if (sscanf(argv[i++], "%d", chunk_size) != 1 || + (*chunk_size != -1 && + (!POWER_OF_2(*chunk_size) || + !range_ok(*chunk_size, IO_SIZE_MIN, CHUNK_SIZE_MAX)))) + TI_ERR ("Invalid chunk size; " + "must be 2^^n and <= 16384"); + + *chunk_size_parm = *chunk_size; + if (*chunk_size == -1) + *chunk_size = CHUNK_SIZE; + + /* + * In case we've got 2 or more variable raid + * parameters, the number of stripes is the second one + */ + if (*raid_parms > 1) { + if (sscanf(argv[i++], "%d", stripes) != 1 || + (*stripes != -1 && + !range_ok(*stripes, STRIPES_MIN, + STRIPES_MAX))) + TI_ERR("Invalid number of stripes: must " + "be >= 8 and <= 8192"); + } + + *stripes_parm = *stripes; + if (*stripes == -1) + *stripes = STRIPES; + + /* + * In case we've got 3 or more variable raid + * parameters, the io size is the third one. + */ + if (*raid_parms > 2) { + if (sscanf(argv[i++], "%d", io_size) != 1 || + (*io_size != -1 && + (!POWER_OF_2(*io_size) || + !range_ok(*io_size, IO_SIZE_MIN, + min(BIO_MAX_SECTORS / 2, + *chunk_size))))) + TI_ERR("Invalid io size; must " + "be 2^^n and less equal " + "min(BIO_MAX_SECTORS/2, chunk size)"); + } else + *io_size = *chunk_size; + + *io_size_parm = *io_size; + if (*io_size == -1) + *io_size = *chunk_size; + + /* + * In case we've got 4 variable raid parameters, + * the recovery stripe io_size is the fourth one + */ + if (*raid_parms > 3) { + if (sscanf(argv[i++], "%d", recover_io_size) != 1 || + (*recover_io_size != -1 && + (!POWER_OF_2(*recover_io_size) || + !range_ok(*recover_io_size, RECOVER_IO_SIZE_MIN, + BIO_MAX_SECTORS / 2)))) + TI_ERR("Invalid recovery io size; must be " + "2^^n and less equal BIO_MAX_SECTORS/2"); + } + + *recover_io_size_parm = *recover_io_size; + if (*recover_io_size == -1) + *recover_io_size = RECOVER_IO_SIZE; + + /* + * In case we've got 5 variable raid parameters, + * the recovery io bandwidth is the fifth one + */ + if (*raid_parms > 4) { + if (sscanf(argv[i++], "%d", bandwidth) != 1 || + (*bandwidth != -1 && + !range_ok(*bandwidth, BANDWIDTH_MIN, + BANDWIDTH_MAX))) + TI_ERR("Invalid recovery bandwidth " + "percentage; must be > 0 and <= 100"); + } + + *bandwidth_parm = *bandwidth; + if (*bandwidth == -1) + *bandwidth = BANDWIDTH; + } + + return 0; +} + +/* Parse optional locking parameters. */ +static int +raid_locking_parms(struct dm_target *ti, char **argv, + unsigned i, int *locking_parms, + struct dmraid45_locking_type **locking_type) +{ + *locking_parms = 0; + *locking_type = &locking_none; + + if (!strnicmp(argv[i], "none", strlen(argv[i]))) + *locking_parms = 1; + else if (!strnicmp(argv[i + 1], "locking", strlen(argv[i + 1]))) { + *locking_type = &locking_none; + *locking_parms = 2; + } else if (!strnicmp(argv[i + 1], "cluster", strlen(argv[i + 1]))) { + *locking_type = &locking_cluster; + /* FIXME: namespace. */ + *locking_parms = 3; + } + + return *locking_parms == 1 ? -EINVAL : 0; +} + +/* Set backing device information properties of RAID set. */ +static void rs_set_bdi(struct raid_set *rs, unsigned stripes, unsigned chunks) +{ + unsigned p, ra_pages; + struct mapped_device *md = dm_table_get_md(rs->ti->table); + struct backing_dev_info *bdi = &dm_disk(md)->queue->backing_dev_info; + + /* Set read-ahead for the RAID set and the component devices. */ + bdi->ra_pages = stripes * stripe_pages(rs, rs->set.io_size); + ra_pages = chunks * chunk_pages(rs->set.io_size); + for (p = rs->set.raid_devs; p--; ) + bdev_get_queue(rs->dev[p].dev->bdev)->backing_dev_info.ra_pages = ra_pages; + + /* Set congested function and data. */ + bdi->congested_fn = raid_set_congested; + bdi->congested_data = rs; + + dm_put(md); +} + +/* Get backing device information properties of RAID set. */ +static void rs_get_ra(struct raid_set *rs, unsigned *stripes, unsigned *chunks) +{ + struct mapped_device *md = dm_table_get_md(rs->ti->table); + + *stripes = dm_disk(md)->queue->backing_dev_info.ra_pages + / stripe_pages(rs, rs->set.io_size); + *chunks = bdev_get_queue(rs->dev->dev->bdev)->backing_dev_info.ra_pages + / chunk_pages(rs->set.io_size); + + dm_put(md); +} + +/* + * Construct a RAID4/5 mapping: + * + * log_type #log_params \ + * raid_type [#parity_dev] #raid_variable_params \ + * [locking "none"/"cluster"] + * #raid_devs #dev_to_initialize [ ]{3,} + * + * log_type = "core"/"disk", + * #log_params = 1-3 (1-2 for core dirty log type, 3 for disk dirty log only) + * log_params = [dirty_log_path] region_size [[no]sync]) + * + * raid_type = "raid4", "raid5_la", "raid5_ra", "raid5_ls", "raid5_rs" + * + * #parity_dev = N if raid_type = "raid4" + * o N = -1: pick default = last device + * o N >= 0 and < #raid_devs: parity device index + * + * #raid_variable_params = 0-5; raid_params (-1 = default): + * [chunk_size [#stripes [io_size [recover_io_size [%recovery_bandwidth]]]]] + * o chunk_size (unit to calculate drive addresses; must be 2^^n, > 8 + * and <= CHUNK_SIZE_MAX) + * o #stripes is number of stripes allocated to stripe cache + * (must be > 1 and < STRIPES_MAX) + * o io_size (io unit size per device in sectors; must be 2^^n and > 8) + * o recover_io_size (io unit size per device for recovery in sectors; + must be 2^^n, > SECTORS_PER_PAGE and <= region_size) + * o %recovery_bandwith is the maximum amount spend for recovery during + * application io (1-100%) + * If raid_variable_params = 0, defaults will be used. + * Any raid_variable_param can be set to -1 to apply a default + * + * #raid_devs = N (N >= 3) + * + * #dev_to_initialize = N + * -1: initialize parity on all devices + * >= 0 and < #raid_devs: initialize raid_path; used to force reconstruction + * of a failed devices content after replacement + * + * = device_path (eg, /dev/sdd1) + * = begin at offset on + * + */ +#define MIN_PARMS 13 +static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv) +{ + int bandwidth = BANDWIDTH, bandwidth_parm = -1, + chunk_size = CHUNK_SIZE, chunk_size_parm = -1, + dev_to_init, dl_parms, locking_parms, parity_parm, pi = -1, + i, io_size = IO_SIZE, io_size_parm = -1, + r, raid_devs, raid_parms, + recover_io_size = RECOVER_IO_SIZE, recover_io_size_parm = -1, + stripes = STRIPES, stripes_parm = -1; + unsigned speed; + sector_t tmp, sectors_per_dev; + struct dmraid45_locking_type *locking; + struct raid_set *rs; + struct raid_type *raid_type; + + /* Ensure minimum number of parameters. */ + if (argc < MIN_PARMS) + TI_ERR("Not enough parameters"); + + /* Fetch # of dirty log parameters. */ + if (sscanf(argv[1], "%d", &dl_parms) != 1 + || !range_ok(dl_parms, 1, 4711)) + TI_ERR("Bad dirty log parameters number"); + + /* Check raid_type. */ + raid_type = get_raid_type(argv[dl_parms + 2]); + if (!raid_type) + TI_ERR("Bad raid type"); + + /* In case of RAID4, parity drive is selectable. */ + parity_parm = !!(raid_type->level == raid4); + + /* Handle variable number of RAID parameters. */ + r = raid_variable_parms(ti, argv, dl_parms + parity_parm + 3, + &raid_parms, + &chunk_size, &chunk_size_parm, + &stripes, &stripes_parm, + &io_size, &io_size_parm, + &recover_io_size, &recover_io_size_parm, + &bandwidth, &bandwidth_parm); + if (r) + return r; + + r = raid_locking_parms(ti, argv, + dl_parms + parity_parm + raid_parms + 4, + &locking_parms, &locking); + if (r) + return r; + + /* # of raid devices. */ + if (sscanf(argv[dl_parms + parity_parm + raid_parms + locking_parms +4], + "%d", &raid_devs) != 1 || raid_devs < raid_type->minimal_devs) + TI_ERR("Invalid number of raid devices"); + + /* In case of RAID4, check parity drive index is in limits. */ + if (raid_type->level == raid4) { + /* Fetch index of parity device. */ + if (sscanf(argv[dl_parms + 3], "%d", &pi) != 1 || + !range_ok(pi, 0, raid_devs - 1)) + TI_ERR("Invalid RAID4 parity device index"); + } + + /* + * Index of device to initialize starts at 0 + * + * o -1 -> don't initialize a particular device, + * o 0..raid_devs-1 -> initialize respective device + * (used for reconstruction of a replaced device) + */ + if (sscanf + (argv[dl_parms + parity_parm + raid_parms + locking_parms + 5], + "%d", &dev_to_init) != 1 + || !range_ok(dev_to_init, -1, raid_devs - 1)) + TI_ERR("Invalid number for raid device to initialize"); + + /* Check # of raid device arguments. */ + if (argc - dl_parms - parity_parm - raid_parms - 6 != + 2 * raid_devs) + TI_ERR("Wrong number of raid device/offset arguments"); + + /* + * Check that the table length is devisable + * w/o rest by (raid_devs - parity_devs) + */ + if (!multiple(ti->len, raid_devs - raid_type->parity_devs, + §ors_per_dev)) + TI_ERR + ("Target length not divisable by number of data devices"); + + /* + * Check that the device size is + * devisable w/o rest by chunk size + */ + if (!multiple(sectors_per_dev, chunk_size, &tmp)) + TI_ERR("Device length not divisable by chunk_size"); + + /**************************************************************** + * Now that we checked the constructor arguments -> + * let's allocate the RAID set + ****************************************************************/ + r = context_alloc(&rs, raid_type, stripes, chunk_size, io_size, + recover_io_size, raid_devs, sectors_per_dev, + ti, dl_parms, argv); + if (r) + return r; + + /* + * Set these here in order to avoid passing + * too many arguments to context_alloc() + */ + rs->set.dev_to_init_parm = dev_to_init; + rs->set.dev_to_init = dev_to_init; + rs->set.pi_parm = pi; + rs->set.pi = (pi == -1) ? rs->set.data_devs : pi; + rs->set.raid_parms = raid_parms; + rs->set.chunk_size_parm = chunk_size_parm; + rs->set.io_size_parm = io_size_parm; + rs->sc.stripes_parm = stripes_parm; + rs->recover.io_size_parm = recover_io_size_parm; + rs->recover.bandwidth_parm = bandwidth_parm; + recover_set_bandwidth(rs, bandwidth); + + /* Use locking type to lock stripe access. */ + rs->locking = locking; + + /* Get the device/offset tupels. */ + argv += dl_parms + 6 + parity_parm + raid_parms; + r = dev_parms(ti, rs, argv, &i); + if (r) + goto err; + + /* Initialize recovery. */ + rs->recover.start_jiffies = jiffies; + rs->recover.end_jiffies = 0; + recovery_region_reset(rs); + SetRSRecover(rs); + + /* Set backing device information (eg. read ahead). */ + rs_set_bdi(rs, chunk_size * 2, io_size * 4); + SetRSCheckOverwrite(rs); /* Allow chunk overwrite checks. */ + + speed = xor_optimize(rs); /* Select best xor algorithm. */ + + /* Initialize work queue to handle this RAID set's io. */ + r = rs_workqueue_init(rs); + if (r) + goto err; + + raid_set_log(rs, speed); /* Log information about RAID set. */ + + /* + * Make sure that dm core only hands maximum io size + * length down and pays attention to io boundaries. + */ + ti->split_io = rs->set.io_size; + ti->private = rs; + return 0; + + err: + context_free(rs, ti, i); + return r; +} + +/* + * Destruct a raid mapping + */ +static void raid_dtr(struct dm_target *ti) +{ + struct raid_set *rs = ti->private; + + /* Indicate recovery end. */ + ClearRSRecover(rs); + wake_do_raid(rs); /* Wake daemon. */ + wait_ios(rs); /* Wait for any io still being processed. */ + destroy_workqueue(rs->io.wq); + context_free(rs, ti, rs->set.raid_devs); +} + +/* Queues ios to RAID sets. */ +static inline void queue_bio(struct raid_set *rs, struct bio *bio) +{ + int wake; + struct bio_list *in = &rs->io.in; + spinlock_t *in_lock = &rs->io.in_lock; + + spin_lock_irq(in_lock); + wake = bio_list_empty(in); + bio_list_add(in, bio); + spin_unlock_irq(in_lock); + + /* Wake daemon if input list was empty. */ + if (wake) + wake_do_raid(rs); +} + +/* Raid mapping function. */ +static int raid_map(struct dm_target *ti, struct bio *bio, + union map_info *map_context) +{ + /* I don't want to waste stripe cache capacity. */ + if (bio_rw(bio) == READA) + return -EIO; + else { + struct raid_set *rs = ti->private; + + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + + (bio_data_dir(bio) == WRITE ? + S_BIOS_WRITE : S_BIOS_READ)); + + /* + * Get io reference to be waiting for to drop + * to zero on device suspension/destruction. + */ + io_get(rs); + bio->bi_sector -= ti->begin; /* Remap sector. */ + queue_bio(rs, bio); /* Queue to the daemon. */ + return DM_MAPIO_SUBMITTED; /* Handle later. */ + } +} + +/* Device suspend. */ +static void raid_postsuspend(struct dm_target *ti) +{ + struct raid_set *rs = ti->private; + struct dm_dirty_log *dl = rs->recover.dl; + + SetRSSuspended(rs); + + if (RSRecover(rs)) + rh_stop_recovery(rs->recover.rh); /* Wakes do_raid(). */ + else + wake_do_raid(rs); + + wait_ios(rs); /* Wait for completion of all ios being processed. */ + if (dl->type->postsuspend && dl->type->postsuspend(dl)) + /* Suspend dirty log. */ + /* FIXME: need better error handling. */ + DMWARN("log suspend failed"); +} + +/* Device resume. */ +static void raid_resume(struct dm_target *ti) +{ + struct raid_set *rs = ti->private; + struct dm_dirty_log *dl = rs->recover.dl; + + if (dl->type->resume && dl->type->resume(dl)) + /* Resume dirty log. */ + /* FIXME: need better error handling. */ + DMWARN("log resume failed"); + + rs->recover.nr_regions_to_recover = + rs->recover.nr_regions - dl->type->get_sync_count(dl); + + ClearRSSuspended(rs); + + /* Reset any unfinished recovery. */ + if (RSRecover(rs)) { + recovery_region_reset(rs); + rh_start_recovery(rs->recover.rh); /* Calls wake_do_raid(). */ + } else + wake_do_raid(rs); +} + +static INLINE unsigned sc_size(struct raid_set *rs) +{ + return to_sector(atomic_read(&rs->sc.stripes) * + (sizeof(struct stripe) + + (sizeof(struct stripe_set) + + (sizeof(struct page_list) + + to_bytes(rs->set.io_size) * + rs->set.raid_devs)) + + (rs->recover. + end_jiffies ? 0 : to_bytes(rs->set.raid_devs * + rs->recover. + io_size)))); +} + +/* REMOVEME: status output for development. */ +static void +raid_devel_stats(struct dm_target *ti, char *result, + unsigned *size, unsigned maxlen) +{ + unsigned chunks, stripes, sz = *size; + unsigned long j; + char buf[BDEVNAME_SIZE], *p; + struct stats_map *sm, *sm_end = ARRAY_END(stats_map); + struct raid_set *rs = ti->private; + struct recover *rec = &rs->recover; + struct timespec ts; + + DMEMIT("%s ", version); + DMEMIT("io_inprocess=%d ", atomic_read(&rs->io.in_process)); + DMEMIT("io_inprocess_max=%d ", atomic_read(&rs->io.in_process_max)); + + for (sm = stats_map; sm < sm_end; sm++) + DMEMIT("%s%d", sm->str, atomic_read(rs->stats + sm->type)); + + DMEMIT(" overwrite=%s ", RSCheckOverwrite(rs) ? "on" : "off"); + DMEMIT("sc=%u/%u/%u/%u/%u ", rs->set.chunk_size, rs->set.io_size, + atomic_read(&rs->sc.stripes), rs->sc.hash.buckets, + sc_size(rs)); + + j = (rec->end_jiffies ? rec->end_jiffies : jiffies) - + rec->start_jiffies; + jiffies_to_timespec(j, &ts); + sprintf(buf, "%ld.%ld", ts.tv_sec, ts.tv_nsec); + p = strchr(buf, '.'); + p[3] = 0; + + DMEMIT("rg=%llu%s/%llu/%llu/%u %s ", + (unsigned long long) rec->nr_regions_recovered, + RSRegionGet(rs) ? "+" : "", + (unsigned long long) rec->nr_regions_to_recover, + (unsigned long long) rec->nr_regions, rec->bandwidth, buf); + + rs_get_ra(rs, &stripes, &chunks); + DMEMIT("ra=%u/%u ", stripes, chunks); + + *size = sz; +} + +static int +raid_status(struct dm_target *ti, status_type_t type, + char *result, unsigned maxlen) +{ + unsigned i, sz = 0; + char buf[BDEVNAME_SIZE]; + struct raid_set *rs = ti->private; + + switch (type) { + case STATUSTYPE_INFO: + /* REMOVEME: statistics. */ + if (RSDevelStats(rs)) + raid_devel_stats(ti, result, &sz, maxlen); + + DMEMIT("%u ", rs->set.raid_devs); + + for (i = 0; i < rs->set.raid_devs; i++) + DMEMIT("%s ", + format_dev_t(buf, rs->dev[i].dev->bdev->bd_dev)); + + DMEMIT("1 "); + for (i = 0; i < rs->set.raid_devs; i++) { + DMEMIT("%c", + dev_operational(rs, i) ? 'A' : 'D'); + + if (rs->set.raid_type->level == raid4 && + i == rs->set.pi) + DMEMIT("p"); + + if (rs->set.dev_to_init == i) + DMEMIT("i"); + } + + break; + + case STATUSTYPE_TABLE: + sz = rs->recover.dl->type->status(rs->recover.dl, type, + result, maxlen); + DMEMIT("%s %u ", rs->set.raid_type->name, + rs->set.raid_parms); + + if (rs->set.raid_type->level == raid4) + DMEMIT("%d ", rs->set.pi_parm); + + if (rs->set.raid_parms) + DMEMIT("%d ", rs->set.chunk_size_parm); + + if (rs->set.raid_parms > 1) + DMEMIT("%d ", rs->sc.stripes_parm); + + if (rs->set.raid_parms > 2) + DMEMIT("%d ", rs->set.io_size_parm); + + if (rs->set.raid_parms > 3) + DMEMIT("%d ", rs->recover.io_size_parm); + + if (rs->set.raid_parms > 4) + DMEMIT("%d ", rs->recover.bandwidth_parm); + + DMEMIT("%u %d ", rs->set.raid_devs, rs->set.dev_to_init); + + for (i = 0; i < rs->set.raid_devs; i++) + DMEMIT("%s %llu ", + format_dev_t(buf, + rs->dev[i].dev->bdev->bd_dev), + (unsigned long long) rs->dev[i].start); + } + + return 0; +} + +/* + * Message interface + */ +enum raid_msg_actions { + act_bw, /* Recovery bandwidth switch. */ + act_dev, /* Device failure switch. */ + act_overwrite, /* Stripe overwrite check. */ + act_read_ahead, /* Set read ahead. */ + act_stats, /* Development statistics switch. */ + act_sc, /* Stripe cache switch. */ + + act_on, /* Set entity on. */ + act_off, /* Set entity off. */ + act_reset, /* Reset entity. */ + + act_set = act_on, /* Set # absolute. */ + act_grow = act_off, /* Grow # by an amount. */ + act_shrink = act_reset, /* Shrink # by an amount. */ +}; + +/* Turn a delta to absolute. */ +static int _absolute(unsigned long action, int act, int r) +{ + /* Make delta absolute. */ + if (test_bit(act_set, &action)); + else if (test_bit(act_grow, &action)) + r += act; + else if (test_bit(act_shrink, &action)) + r = act - r; + else + r = -EINVAL; + + return r; +} + + /* Change recovery io bandwidth. */ +static int bandwidth_change(struct dm_msg *msg, void *context) +{ + struct raid_set *rs = context; + int act = rs->recover.bandwidth; + int bandwidth = DM_MSG_INT_ARG(msg); + + if (range_ok(bandwidth, BANDWIDTH_MIN, BANDWIDTH_MAX)) { + /* Make delta bandwidth absolute. */ + bandwidth = _absolute(msg->action, act, bandwidth); + + /* Check range. */ + if (range_ok(bandwidth, BANDWIDTH_MIN, BANDWIDTH_MAX)) { + recover_set_bandwidth(rs, bandwidth); + return 0; + } + } + + set_bit(dm_msg_ret_arg, &msg->ret); + set_bit(dm_msg_ret_inval, &msg->ret); + return -EINVAL; +} + +/* Change state of a device (running/offline). */ +/* FIXME: this only works while recovering!. */ +static int device_state(struct dm_msg *msg, void *context) +{ + int r; + const char *str = "is already "; + union dev_lookup dl = { .dev_name = DM_MSG_STR_ARG(msg) }; + struct raid_set *rs = context; + + r = raid_dev_lookup(rs, strchr(dl.dev_name, ':') ? + bymajmin : byname, &dl); + if (r == -ENODEV) { + DMERR("device %s is no member of this set", dl.dev_name); + return r; + } + + if (test_bit(act_off, &msg->action)) { + if (dev_operational(rs, r)) + str = ""; + } else if (!dev_operational(rs, r)) + str = ""; + + DMINFO("/dev/%s %s%s", dl.dev_name, str, + test_bit(act_off, &msg->action) ? "offline" : "running"); + + return test_bit(act_off, &msg->action) ? + raid_set_check_and_degrade(rs, NULL, r) : + raid_set_check_and_upgrade(rs, r); +} + +/* Set/reset development feature flags. */ +static int devel_flags(struct dm_msg *msg, void *context) +{ + struct raid_set *rs = context; + + if (test_bit(act_on, &msg->action)) + return test_and_set_bit(msg->spec->parm, + &rs->io.flags) ? -EPERM : 0; + else if (test_bit(act_off, &msg->action)) + return test_and_clear_bit(msg->spec->parm, + &rs->io.flags) ? 0 : -EPERM; + else if (test_bit(act_reset, &msg->action)) { + if (test_bit(act_stats, &msg->action)) { + stats_reset(rs); + goto on; + } else if (test_bit(act_overwrite, &msg->action)) { + on: + set_bit(msg->spec->parm, &rs->io.flags); + return 0; + } + } + + return -EINVAL; +} + + /* Set stripe and chunk read ahead pages. */ +static int read_ahead_set(struct dm_msg *msg, void *context) +{ + int stripes = DM_MSG_INT_ARGS(msg, 0); + int chunks = DM_MSG_INT_ARGS(msg, 1); + + if (range_ok(stripes, 1, 512) && + range_ok(chunks, 1, 512)) { + rs_set_bdi(context, stripes, chunks); + return 0; + } + + set_bit(dm_msg_ret_arg, &msg->ret); + set_bit(dm_msg_ret_inval, &msg->ret); + return -EINVAL; +} + +/* Resize the stripe cache. */ +static int stripecache_resize(struct dm_msg *msg, void *context) +{ + int act, stripes; + struct raid_set *rs = context; + + /* Deny permission in case the daemon is still shrinking!. */ + if (atomic_read(&rs->sc.stripes_to_shrink)) + return -EPERM; + + stripes = DM_MSG_INT_ARG(msg); + if (stripes > 0) { + act = atomic_read(&rs->sc.stripes); + + /* Make delta stripes absolute. */ + stripes = _absolute(msg->action, act, stripes); + + /* + * Check range and that the # of stripes changes. + * We can grow from gere but need to leave any + * shrinking to the worker for synchronization. + */ + if (range_ok(stripes, STRIPES_MIN, STRIPES_MAX)) { + if (stripes > act) + return sc_grow(&rs->sc, stripes - act, grow); + else if (stripes < act) { + atomic_set(&rs->sc.stripes_to_shrink, + act - stripes); + wake_do_raid(rs); + } + + return 0; + } + } + + set_bit(dm_msg_ret_arg, &msg->ret); + set_bit(dm_msg_ret_inval, &msg->ret); + return -EINVAL; +} + +/* Parse the RAID message action. */ +/* + * 'ba[ndwidth] {se[t],g[row],sh[rink]} #' # e.g 'ba se 50' + * 'de{vice] o[ffline]/r[unning] DevName/maj:min' # e.g 'device o /dev/sda' + * "o[verwrite] {on,of[f],r[eset]}' # e.g. 'o of' + * "r[ead_ahead] set #stripes #chunks # e.g. 'r se 3 2' + * 'sta[tistics] {on,of[f],r[eset]}' # e.g. 'stat of' + * 'str[ipecache] {se[t],g[row],sh[rink]} #' # e.g. 'stripe set 1024' + * + */ +static int +raid_message(struct dm_target *ti, unsigned argc, char **argv) +{ + /* Variables to store the parsed parameters im. */ + static int i[2]; + static unsigned long *i_arg[] = { + (unsigned long *) i + 0, + (unsigned long *) i + 1, + }; + static char *p; + static unsigned long *p_arg[] = { (unsigned long *) &p }; + + /* Declare all message option strings. */ + static char *str_sgs[] = { "set", "grow", "shrink" }; + static char *str_dev[] = { "running", "offline" }; + static char *str_oor[] = { "on", "off", "reset" }; + + /* Declare all actions. */ + static unsigned long act_sgs[] = { act_set, act_grow, act_shrink }; + static unsigned long act_oor[] = { act_on, act_off, act_reset }; + + /* Bandwidth option. */ + static struct dm_message_option bw_opt = { 3, str_sgs, act_sgs }; + static struct dm_message_argument bw_args = + { 1, i_arg, { dm_msg_int_t } }; + + /* Device option. */ + static struct dm_message_option dev_opt = { 2, str_dev, act_oor }; + static struct dm_message_argument dev_args = + { 1, p_arg, { dm_msg_base_t } }; + + /* Read ahead option. */ + static struct dm_message_option ra_opt = { 1, str_sgs, act_sgs }; + static struct dm_message_argument ra_args = + { 2, i_arg, { dm_msg_int_t, dm_msg_int_t } }; + + static struct dm_message_argument null_args = + { 0, NULL, { dm_msg_int_t } }; + + /* Overwrite and statistics option. */ + static struct dm_message_option ovr_stats_opt = { 3, str_oor, act_oor }; + + /* Sripecache option. */ + static struct dm_message_option stripe_opt = { 3, str_sgs, act_sgs }; + + /* Declare messages. */ + static struct dm_msg_spec specs[] = { + { "bandwidth", act_bw, &bw_opt, &bw_args, + 0, bandwidth_change }, + { "device", act_dev, &dev_opt, &dev_args, + 0, device_state }, + { "overwrite", act_overwrite, &ovr_stats_opt, &null_args, + RS_CHECK_OVERWRITE, devel_flags }, + { "read_ahead", act_read_ahead, &ra_opt, &ra_args, + 0, read_ahead_set }, + { "statistics", act_stats, &ovr_stats_opt, &null_args, + RS_DEVEL_STATS, devel_flags }, + { "stripecache", act_sc, &stripe_opt, &bw_args, + 0, stripecache_resize }, + }; + + /* The message for the parser. */ + struct dm_msg msg = { + .num_specs = ARRAY_SIZE(specs), + .specs = specs, + }; + + return dm_message_parse(TARGET, &msg, ti->private, argc, argv); +} +/* + * END message interface + */ + +static struct target_type raid_target = { + .name = "raid45", + .version = {1, 0, 0}, + .module = THIS_MODULE, + .ctr = raid_ctr, + .dtr = raid_dtr, + .map = raid_map, + .postsuspend = raid_postsuspend, + .resume = raid_resume, + .status = raid_status, + .message = raid_message, +}; + +static void init_exit(const char *bad_msg, const char *good_msg, int r) +{ + if (r) + DMERR("Failed to %sregister target [%d]", bad_msg, r); + else + DMINFO("%s %s", good_msg, version); +} + +static int __init dm_raid_init(void) +{ + int r; + + r = dm_register_target(&raid_target); + init_exit("", "initialized", r); + return r; +} + +static void __exit dm_raid_exit(void) +{ + int r; + + r = dm_unregister_target(&raid_target); + init_exit("un", "exit", r); +} + +/* Module hooks. */ +module_init(dm_raid_init); +module_exit(dm_raid_exit); + +MODULE_DESCRIPTION(DM_NAME " raid4/5 target"); +MODULE_AUTHOR("Heinz Mauelshagen "); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/ubuntu/dm-raid4-5/BOM +++ linux-2.6.28/ubuntu/dm-raid4-5/BOM @@ -0,0 +1,3 @@ +Downloaded from: http://people.redhat.com/~heinzm/sw/dm/dm-raid45/ +Current Version: 20080221 +Comments: All of the patches to dmraid1/dm-log, etc are upstream. --- linux-2.6.28.orig/ubuntu/dm-raid4-5/dm-message.c +++ linux-2.6.28/ubuntu/dm-raid4-5/dm-message.c @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2007 Red Hat GmbH + * + * Module Author: Heinz Mauelshagen + * + * This file is released under the GPL. + * + * device-mapper message parser. + * + */ + +#include "dm.h" +#include "dm-message.h" +#include + +#define DM_MSG_PREFIX "dm_message" + +/* Basename of a path. */ +static inline char * +basename(char *s) +{ + char *p = strrchr(s, '/'); + + return p ? p + 1 : s; +} + +/* Get an argument depending on type. */ +static void +message_arguments(struct dm_msg *msg, int argc, char **argv) +{ + + if (argc) { + int i; + struct dm_message_argument *args = msg->spec->args; + + for (i = 0; i < args->num_args; i++) { + int r; + unsigned long **ptr = args->ptr; + enum dm_message_argument_type type = args->types[i]; + + switch (type) { + case dm_msg_base_t: + ((char **) ptr)[i] = basename(argv[i]); + break; + + case dm_msg_str_t: + ((char **) ptr)[i] = argv[i]; + break; + + case dm_msg_int_t: + r = sscanf(argv[i], "%d", ((int **) ptr)[i]); + goto check; + + case dm_msg_uint_t: + r = sscanf(argv[i], "%u", + ((unsigned **) ptr)[i]); + goto check; + + case dm_msg_uint64_t: + r = sscanf(argv[i], "%llu", + ((unsigned long long **) ptr)[i]); + + check: + if (r != 1) { + set_bit(dm_msg_ret_undef, &msg->ret); + set_bit(dm_msg_ret_arg, &msg->ret); + } + } + } + } +} + +/* Parse message options. */ +static void +message_options_parse(struct dm_msg *msg, int argc, char **argv) +{ + int hit = 0; + unsigned long *action; + size_t l1 = strlen(*argv), l_hit = 0; + struct dm_message_option *o = msg->spec->options; + char **option, **option_end = o->options + o->num_options; + + for (option = o->options, action = o->actions; + option < option_end; option++, action++) { + size_t l2 = strlen(*option); + + if (!strnicmp(*argv, *option, min(l1, l2))) { + hit++; + l_hit = l2; + set_bit(*action, &msg->action); + } + } + + /* Assume error. */ + msg->ret = 0; + set_bit(dm_msg_ret_option, &msg->ret); + if (!hit || l1 > l_hit) + set_bit(dm_msg_ret_undef, &msg->ret); /* Undefined option. */ + else if (hit > 1) + set_bit(dm_msg_ret_ambiguous, &msg->ret); /* Ambiguous option.*/ + else { + clear_bit(dm_msg_ret_option, &msg->ret); /* Option OK. */ + message_arguments(msg, --argc, ++argv); + } +} + +static inline void +print_ret(const char *caller, unsigned long ret) +{ + struct { + unsigned long err; + const char *err_str; + } static err_msg[] = { + { dm_msg_ret_ambiguous, "message ambiguous" }, + { dm_msg_ret_inval, "message invalid" }, + { dm_msg_ret_undef, "message undefined" }, + { dm_msg_ret_arg, "message argument" }, + { dm_msg_ret_argcount, "message argument count" }, + { dm_msg_ret_option, "option" }, + }, *e = ARRAY_END(err_msg); + + while (e-- > err_msg) { + if (test_bit(e->err, &ret)) + DMERR("%s %s", caller, e->err_str); + } +} + +/* Parse a message action. */ +int +dm_message_parse(const char *caller, struct dm_msg *msg, void *context, + int argc, char **argv) +{ + int hit = 0; + size_t l1 = strlen(*argv), l_hit = 0; + struct dm_msg_spec *s, *s_hit = NULL, + *s_end = msg->specs + msg->num_specs; + + if (argc < 2) + return -EINVAL; + + for (s = msg->specs; s < s_end; s++) { + size_t l2 = strlen(s->cmd); + + if (!strnicmp(*argv, s->cmd, min(l1, l2))) { + hit++; + l_hit = l2; + s_hit = s; + } + } + + msg->ret = 0; + if (!hit || l1 > l_hit) /* No hit or message string too long. */ + set_bit(dm_msg_ret_undef, &msg->ret); + else if (hit > 1) /* Ambiguous message. */ + set_bit(dm_msg_ret_ambiguous, &msg->ret); + else if (argc - 2 != s_hit->args->num_args) { + set_bit(dm_msg_ret_undef, &msg->ret); + set_bit(dm_msg_ret_argcount, &msg->ret); + } + + if (msg->ret) + goto bad; + + msg->action = 0; + msg->spec = s_hit; + set_bit(s_hit->action, &msg->action); + message_options_parse(msg, --argc, ++argv); + + if (!msg->ret) + return msg->spec->f(msg, context); + + bad: + print_ret(caller, msg->ret); + return -EINVAL; +} +EXPORT_SYMBOL(dm_message_parse); + +MODULE_DESCRIPTION(DM_NAME " device-mapper target message parser"); +MODULE_AUTHOR("Heinz Mauelshagen "); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/ubuntu/compcache/compcache.txt +++ linux-2.6.28/ubuntu/compcache/compcache.txt @@ -0,0 +1,29 @@ + +compcache: Compressed RAM based swap device +------------------------------------------- + +Project home: http://code.google.com/p/compcache + +* Introduction +This is a RAM based block device which acts as swap disk. +Pages swapped to this device are compressed and stored in +memory itself. + +It uses these components: + - TLSF: memory allocator + - LZO: de/compressor + +* Usage + - modprobe compcache compcache_size_kbytes= + (If no size is specified, default size of 25% of RAM is taken). + - swapon /dev/ramzswap0 + +* Notes + - Allocator and compcache statistics are exported via /proc interface: + (if stats are enabled for corresponding modules) + - /proc/tlsfinfo (from tlsf.ko) + - /proc/compcache (from compcache.ko) + + +Nitin Gupta +(nitingupta910@gmail.com) --- linux-2.6.28.orig/ubuntu/compcache/Kconfig +++ linux-2.6.28/ubuntu/compcache/Kconfig @@ -0,0 +1,61 @@ +menu "Compcache options" + +config BLK_DEV_COMPCACHE + tristate "Compressed RAM based swap device" + default m + select TLSF + select LZO_COMPRESS + select LZO_DECOMPRESS + help + This creates RAM based block device which acts as swap disk. Pages + swapped to this disk are compressed and stored in memory itself. + Project Home: http://code.google.com/p/compcache/ + +config BLK_DEV_COMPCACHE_DEBUG + default n + depends on BLK_DEV_COMPCACHE + bool "Enable debugging" + help + This causes negligible performance loss and size increase. + If unsure, say Y. + +config BLK_DEV_COMPCACHE_STATS + default n + depends on BLK_DEV_COMPCACHE + bool "Enable statistics" + help + Creates /proc/compcache to export various statistics. + This adds about 4K to size with negligible performance loss. + If unsure, say Y. +endmenu + +menu "Two Level Segregate Fit Allocator" + +config TLSF + tristate "TLSF Allocator" + default m + help + Two Level Segregate Fit Allocator. Its fast and gives low + fragmentation. See: + http://rtportal.upv.es/rtmalloc/ + http://code.google.com/p/compcache/wiki/TLSFAllocator + for more information. + +config TLSF_DEBUG + default n + depends on TLSF + bool "Enable TLSF allocator debugging" + help + Enable TLSF debugging. + This causes negligible performance loss and size increase. + If unusure, say Y. + +config TLSF_STATS + default n + depends on TLSF + bool "Collect TLSF statistics" + help + Creates /proc/tlsfinfo to export various tlsf statistics. + This adds about 30K to size with significant performance loss. + If unsure, say N. +endmenu --- linux-2.6.28.orig/ubuntu/compcache/compcache.h +++ linux-2.6.28/ubuntu/compcache/compcache.h @@ -0,0 +1,96 @@ +/* + * Compressed RAM based swap device + * + * (C) 2008 Nitin Gupta + * + * This RAM based block device acts as swap disk. + * Pages swapped to this device are compressed and + * stored in memory. + * + * Released under the terms of the GNU General Public + * License (version 2). See linux/COPYING for more information. + * + * Project home: http://code.google.com/p/compcache + */ + +#ifndef _COMPCACHE_H_ +#define _COMPCACHE_H_ + +#define SECTOR_SHIFT 9 +#define SECTOR_SIZE (1 << SECTOR_SHIFT) +#define SECTORS_PER_PAGE_SHIFT (PAGE_SHIFT - SECTOR_SHIFT) +#define SECTORS_PER_PAGE (1 << SECTORS_PER_PAGE_SHIFT) + +/*-- Configurable parameters */ +/* Default compcache size: 25% of total RAM */ +#define DEFAULT_COMPCACHE_PERCENT 25 +#define INIT_SIZE_BYTES (16 * 1024) +#define GROW_SIZE_BYTES INIT_SIZE_BYTES +/*-- */ + +/* Message prefix */ +#define C "compcache: " + +/* Debugging and Stats */ +#define NOP do { } while(0) + +#if defined(CONFIG_BLK_DEV_COMPCACHE_DEBUG) +#define DEBUG +#endif + +#if defined(CONFIG_BLK_DEV_COMPCACHE_STATS) +#define STATS +#endif + +#if defined(STATS) +#define stat_inc(stat) (stat++) +#define stat_dec(stat) (stat--) +#define stat_set(stat, val) (stat = val) +#define stat_setmax(stat, curr) (stat = (curr) > stat ? (curr) : stat) +#define stat_inc_if_less(stat, val1, val2) \ + (stat += ((val1) < (val2) ? 1 : 0)) +#else /* STATS */ +#define stat_inc(x) NOP +#define stat_dec(x) NOP +#define stat_set(x, v) NOP +#define stat_setmax(x, v) NOP +#define stat_inc_if_less(x, v1, v2) NOP +#endif /* STATS */ + +/*-- Data structures */ +/* Indexed by page no. */ +struct table { + void *addr; + unsigned long len; +}; + +struct compcache { + void *mem_pool; + void *compress_workmem; + void *compress_buffer; + struct table *table; + struct mutex lock; + struct gendisk *disk; + size_t size; /* In sectors */ +}; + +#if defined(STATS) +struct compcache_stats { + u32 num_reads; /* failed + successful */ + u32 num_writes; /* --do-- */ + u32 failed_reads; /* can happen when memory is tooo low */ + u32 failed_writes; /* should NEVER! happen */ + u32 invalid_io; /* non-swap I/O requests */ + u32 good_compress; /* no. of pages with compression + * ratio <= 50%. TODO: export full + * compressed page size histogram */ + u32 pages_expand; /* no. of incompressible pages */ + u32 notify_free; /* count of swap entry free notifications */ + size_t curr_pages; /* current no. of compressed pages */ + size_t curr_mem; /* current total size of compressed pages */ + size_t peak_mem; +}; +#endif +/*-- */ + +#endif --- linux-2.6.28.orig/ubuntu/compcache/Makefile +++ linux-2.6.28/ubuntu/compcache/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_BLK_DEV_COMPCACHE) += compcache.o +obj-$(CONFIG_TLSF) += tlsf.o --- linux-2.6.28.orig/ubuntu/compcache/tlsf.c +++ linux-2.6.28/ubuntu/compcache/tlsf.c @@ -0,0 +1,676 @@ +/* + * Two Levels Segregate Fit memory allocator (TLSF) + * Version 2.3.2 + * + * Written by Miguel Masmano Tello + * + * Thanks to Ismael Ripoll for his suggestions and reviews + * + * Copyright (C) 2007, 2006, 2005, 2004 + * + * This code is released using a dual license strategy: GPL/LGPL + * You can choose the licence that better fits your requirements. + * + * Released under the terms of the GNU General Public License Version 2.0 + * Released under the terms of the GNU Lesser General Public License Version 2.1 + * + * This is kernel port of TLSF allocator. + * Original code can be found at: http://rtportal.upv.es/rtmalloc/ + * - Nitin Gupta (nitingupta910@gmail.com) + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "tlsf_int.h" + +static spinlock_t pool_list_lock; +static struct list_head pool_list_head; + +#if defined(CONFIG_TLSF_STATS) +static struct proc_dir_entry *proc; + +/* Print in format similar to /proc/slabinfo -- easy to awk */ +static void print_tlsfinfo_header(struct seq_file *tlsf) +{ + seq_puts(tlsf, "# Size in kB\n"); + seq_puts(tlsf, "# name " + " "); +#if defined(CONFIG_TLSF_STATS) + seq_puts(tlsf, " " + " " + " "); +#endif +#if defined(CONFIG_TLSF_DEBUG) + seq_puts(tlsf, " "); +#endif + + seq_putc(tlsf, '\n'); +} + +/* Get pool no. (*pos) from pool list */ +static void *tlsf_start(struct seq_file *tlsf, loff_t *pos) +{ + struct list_head *lp; + loff_t p = *pos; + + spin_lock(&pool_list_lock); + if (!p) + return SEQ_START_TOKEN; + + list_for_each(lp, &pool_list_head) { + if (!--p) + return lp; + } + + return NULL; +} + +/* Get pool next to the one given by tlsf_start()/previous tlsf_next() */ +static void *tlsf_next(struct seq_file *tlsf, void *v, loff_t *pos) +{ + struct list_head *lp; + + if (v == SEQ_START_TOKEN) + lp = &pool_list_head; + else + lp = v; + + lp = lp->next; + if (lp == &pool_list_head) + return NULL; + + ++*pos; + return lp; +} + +static void tlsf_stop(struct seq_file *tlsf, void *v) +{ + spin_unlock(&pool_list_lock); +} + +/* Display stats for pool given by tlsf_next() */ +static int tlsf_show(struct seq_file *tlsf, void *v) +{ + struct pool *pool; + size_t used, total; + if (v == SEQ_START_TOKEN) { + print_tlsfinfo_header(tlsf); + return 0; + } + + pool = list_entry(v, struct pool, list); + used = tlsf_get_used_size(pool); + total = tlsf_get_total_size(pool); +#define K(x) ((x) >> 10) + seq_printf(tlsf, "%-16s %6zu %6zu %6zu %6zu %6zu %6zu", + pool->name, + K(pool->init_size), + K(pool->max_size), + K(pool->grow_size), + K(used), + K(total), + K(total - used)); + +#if defined(CONFIG_TLSF_STATS) + seq_printf(tlsf, " %6zu %6zu %6zu %6zu %6zu %6zu %6zu %6zu", + K(pool->peak_used), + K(pool->peak_total), + K(pool->peak_extra), + pool->count_alloc, + pool->count_free, + pool->count_region_alloc, + pool->count_region_free, + pool->count_failed_alloc); +#endif + +#if defined(CONFIG_TLSF_DEBUG) + seq_printf(tlsf, " %u", pool->valid); +#endif + + seq_putc(tlsf, '\n'); + return 0; +} + +static struct seq_operations tlsfinfo_op = { + .start = tlsf_start, + .next = tlsf_next, + .stop = tlsf_stop, + .show = tlsf_show, +}; + +static int tlsfinfo_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &tlsfinfo_op); +} + +static const struct file_operations proc_tlsfinfo_operations = { + .open = tlsfinfo_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; +#endif /* CONFIG_TLSF_STATS */ + +/* + * Helping functions + */ + +/** + * Returns indexes (fl, sl) of the list used to serve request of size r + */ +static inline void MAPPING_SEARCH(size_t *r, int *fl, int *sl) +{ + int t; + + if (*r < SMALL_BLOCK) { + *fl = 0; + *sl = *r / (SMALL_BLOCK / MAX_SLI); + } else { + t = (1 << (fls(*r) - 1 - MAX_LOG2_SLI)) - 1; + *r = *r + t; + *fl = fls(*r) - 1; + *sl = (*r >> (*fl - MAX_LOG2_SLI)) - MAX_SLI; + *fl -= FLI_OFFSET; + /*if ((*fl -= FLI_OFFSET) < 0) // FL will be always >0! + *fl = *sl = 0; + */ + *r &= ~t; + } +} + +/** + * Returns indexes (fl, sl) which is used as starting point to search + * for a block of size r. It also rounds up requested size(r) to the + * next list. + */ +static inline void MAPPING_INSERT(size_t r, int *fl, int *sl) +{ + if (r < SMALL_BLOCK) { + *fl = 0; + *sl = r / (SMALL_BLOCK / MAX_SLI); + } else { + *fl = fls(r) - 1; + *sl = (r >> (*fl - MAX_LOG2_SLI)) - MAX_SLI; + *fl -= FLI_OFFSET; + } +} + +/** + * Returns first block from a list that hold blocks larger than or + * equal to the one pointed by the indexes (fl, sl) + */ +static inline struct bhdr *FIND_SUITABLE_BLOCK(struct pool *p, int *fl, + int *sl) +{ + u32 tmp = p->sl_bitmap[*fl] & (~0 << *sl); + struct bhdr *b = NULL; + + if (tmp) { + *sl = ffs(tmp) - 1; + b = p->matrix[*fl][*sl]; + } else { + *fl = ffs(p->fl_bitmap & (~0 << (*fl + 1))) - 1; + if (*fl > 0) { /* likely */ + *sl = ffs(p->sl_bitmap[*fl]) - 1; + b = p->matrix[*fl][*sl]; + } + } + return b; +} + +/** + * Remove first free block(b) from free list with indexes (fl, sl). + */ +static inline void EXTRACT_BLOCK_HDR(struct bhdr *b, struct pool *p, int fl, + int sl) +{ + p->matrix[fl][sl] = b->ptr.free_ptr.next; + if (p->matrix[fl][sl]) + p->matrix[fl][sl]->ptr.free_ptr.prev = NULL; + else { + clear_bit(sl, (void *)&p->sl_bitmap[fl]); + if(!p->sl_bitmap[fl]) + clear_bit (fl, (void *)&p->fl_bitmap); + } + b->ptr.free_ptr = (struct free_ptr) {NULL, NULL}; +} + +/** + * Removes block(b) from free list with indexes (fl, sl) + */ +static inline void EXTRACT_BLOCK(struct bhdr *b, struct pool *p, int fl, + int sl) +{ + if (b->ptr.free_ptr.next) + b->ptr.free_ptr.next->ptr.free_ptr.prev = + b->ptr.free_ptr.prev; + if (b->ptr.free_ptr.prev) + b->ptr.free_ptr.prev->ptr.free_ptr.next = + b->ptr.free_ptr.next; + if (p->matrix[fl][sl] == b) { + p->matrix[fl][sl] = b->ptr.free_ptr.next; + if (!p->matrix[fl][sl]) { + clear_bit(sl, (void *)&p->sl_bitmap[fl]); + if (!p->sl_bitmap[fl]) + clear_bit (fl, (void *)&p->fl_bitmap); + } + } + b->ptr.free_ptr = (struct free_ptr) {NULL, NULL}; +} + +/** + * Insert block(b) in free list with indexes (fl, sl) + */ +static inline void INSERT_BLOCK(struct bhdr *b, struct pool *p, int fl, int sl) +{ + b->ptr.free_ptr = (struct free_ptr) {NULL, p->matrix[fl][sl]}; + if (p->matrix[fl][sl]) + p->matrix[fl][sl]->ptr.free_ptr.prev = b; + p->matrix[fl][sl] = b; + set_bit(sl, (void *)&p->sl_bitmap[fl]); + set_bit(fl, (void *)&p->fl_bitmap); +} + +/** + * Region is a virtually contiguous memory region and Pool is + * collection of such regions + */ +static inline void ADD_REGION(void *region, size_t region_size, + struct pool *pool) +{ + int fl, sl; + struct bhdr *b, *lb; + + b = (struct bhdr *)(region); + b->prev_hdr = NULL; + b->size = ROUNDDOWN_SIZE(region_size - 2 * BHDR_OVERHEAD) + | FREE_BLOCK | PREV_USED; + MAPPING_INSERT(b->size & BLOCK_SIZE_MASK, &fl, &sl); + INSERT_BLOCK(b, pool, fl, sl); + /* The sentinel block: allows us to know when we're in the last block */ + lb = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE_MASK); + lb->prev_hdr = b; + lb->size = 0 | USED_BLOCK | PREV_FREE; + pool->used_size += BHDR_OVERHEAD; /* only sentinel block is "used" */ + pool->num_regions++; + stat_inc(pool->count_region_alloc); +} + +/* + * Allocator code start + */ + +/** + * tlsf_create_memory_pool - create dynamic memory pool + * @name: name of the pool + * @get_mem: callback function used to expand pool + * @put_mem: callback function used to shrink pool + * @init_size: inital pool size (in bytes) + * @max_size: maximum pool size (in bytes) - set this as 0 for no limit + * @grow_size: amount of memory (in bytes) added to pool whenever required + * + * All size values are rounded up to next page boundary. + */ +void *tlsf_create_memory_pool(const char *name, + get_memory get_mem, + put_memory put_mem, + size_t init_size, + size_t max_size, + size_t grow_size) +{ + struct pool *pool; + void *region; +#if defined(CONFIG_TLSF_STATS) + size_t used, total; +#endif + + if (max_size) + BUG_ON(max_size < init_size); + + pool = get_mem(ROUNDUP_SIZE(sizeof(*pool))); + if (pool == NULL) + goto out; + memset(pool, 0, ROUNDUP_SIZE(sizeof(*pool))); + + /* Round to next page boundary */ + init_size = ROUNDUP_PAGE(init_size); + max_size = ROUNDUP_PAGE(max_size); + grow_size = ROUNDUP_PAGE(grow_size); + pr_info(T "pool: %p, init_size=%zu, max_size=%zu, grow_size=%zu\n", + pool, init_size, max_size, grow_size); + + /* pool global overhead not included in used size */ + pool->used_size = 0; + + pool->init_size = init_size; + pool->max_size = max_size; + pool->grow_size = grow_size; + pool->get_mem = get_mem; + pool->put_mem = put_mem; + strncpy(pool->name, name, MAX_POOL_NAME_LEN); + pool->name[MAX_POOL_NAME_LEN - 1] = '\0'; +#if defined(CONFIG_TLSF_DEBUG) + pool->valid = 1; +#endif + region = get_mem(init_size); + if (region == NULL) + goto out_region; + ADD_REGION(region, init_size, pool); + pool->init_region = region; + + spin_lock_init(&pool->lock); + + spin_lock(&pool_list_lock); + list_add_tail(&pool->list, &pool_list_head); + spin_unlock(&pool_list_lock); + + /* Pool created: update stats */ + stat_set(used, tlsf_get_used_size(pool)); + stat_set(total, tlsf_get_total_size(pool)); + stat_inc(pool->count_alloc); + stat_setmax(pool->peak_extra, total - used); + stat_setmax(pool->peak_used, used); + stat_setmax(pool->peak_total, total); + + return pool; + +out_region: + put_mem(pool); + +out: + return NULL; +} +EXPORT_SYMBOL_GPL(tlsf_create_memory_pool); + +/** + * tlsf_get_used_size - get memory currently used by given pool + * + * Used memory includes stored data + metadata + internal fragmentation + */ +size_t tlsf_get_used_size(void *mem_pool) +{ + struct pool *pool = (struct pool *)mem_pool; + return pool->used_size; +} +EXPORT_SYMBOL_GPL(tlsf_get_used_size); + +/** + * tlsf_get_total_size - get total memory currently allocated for given pool + * + * This is the total memory currently allocated for this pool which includes + * used size + free size. + * + * (Total - Used) is good indicator of memory efficiency of allocator. + */ +size_t tlsf_get_total_size(void *mem_pool) +{ + size_t total; + struct pool *pool = (struct pool *)mem_pool; + total = ROUNDUP_SIZE(sizeof(*pool)) + + pool->init_size + + (pool->num_regions - 1) * pool->grow_size; + return total; +} +EXPORT_SYMBOL_GPL(tlsf_get_total_size); + +/** + * tlsf_destory_memory_pool - cleanup given pool + * @mem_pool: Pool to be destroyed + * + * Data structures associated with pool are freed. + * All memory allocated from pool must be freed before + * destorying it. + */ +void tlsf_destroy_memory_pool(void *mem_pool) +{ + struct pool *pool; + + if (mem_pool == NULL) + return; + + pool = (struct pool *)mem_pool; + + /* User is destorying without ever allocating from this pool */ + if (tlsf_get_used_size(pool) == BHDR_OVERHEAD) { + pool->put_mem(pool->init_region); + pool->used_size -= BHDR_OVERHEAD; + stat_inc(pool->count_region_free); + } + + /* Check for memory leaks in this pool */ + if (tlsf_get_used_size(pool)) { + pr_warning(T "memory leak in pool: %s (%p). " + "%zu bytes still in use.\n", + pool->name, pool, tlsf_get_used_size(pool)); + +#if defined(CONFIG_TLSF_DEBUG) + pool->valid = 0; + /* Invalid pools stay in list for debugging purpose */ + return; +#endif + } + spin_lock(&pool_list_lock); + list_del_init(&pool->list); + spin_unlock(&pool_list_lock); + pool->put_mem(pool); +} +EXPORT_SYMBOL_GPL(tlsf_destroy_memory_pool); + +/** + * tlsf_malloc - allocate memory from given pool + * @size: no. of bytes + * @mem_pool: pool to allocate from + */ +void *tlsf_malloc(size_t size, void *mem_pool) +{ + struct pool *pool = (struct pool *)mem_pool; + struct bhdr *b, *b2, *next_b, *region; + int fl, sl; + size_t tmp_size; +#if defined(CONFIG_TLSF_STATS) + size_t used, total; +#endif + +#if defined(CONFIG_TLSF_DEBUG) + unsigned int retries = 0; +#endif + + size = (size < MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : ROUNDUP_SIZE(size); + /* Rounding up the requested size and calculating fl and sl */ + + spin_lock(&pool->lock); +retry_find: + MAPPING_SEARCH(&size, &fl, &sl); + + /* Searching a free block */ + if (!(b = FIND_SUITABLE_BLOCK(pool, &fl, &sl))) { +#if defined(CONFIG_TLSF_DEBUG) + /* + * This can happen if there are too many users + * allocating from this pool simultaneously. + */ + if (unlikely(retries == MAX_RETRY_EXPAND)) + goto out_locked; + retries++; +#endif + /* Not found */ + if (size > (pool->grow_size - 2 * BHDR_OVERHEAD)) + goto out_locked; + if (pool->max_size && (pool->init_size + + pool->num_regions * pool->grow_size + > pool->max_size)) + goto out_locked; + spin_unlock(&pool->lock); + if ((region = pool->get_mem(pool->grow_size)) == NULL) + goto out; + spin_lock(&pool->lock); + ADD_REGION(region, pool->grow_size, pool); + goto retry_find; + } + EXTRACT_BLOCK_HDR(b, pool, fl, sl); + + /*-- found: */ + next_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE_MASK); + /* Should the block be split? */ + tmp_size = (b->size & BLOCK_SIZE_MASK) - size; + if (tmp_size >= sizeof(struct bhdr) ) { + tmp_size -= BHDR_OVERHEAD; + b2 = GET_NEXT_BLOCK(b->ptr.buffer, size); + + b2->size = tmp_size | FREE_BLOCK | PREV_USED; + b2->prev_hdr = b; + + next_b->prev_hdr = b2; + + MAPPING_INSERT(tmp_size, &fl, &sl); + INSERT_BLOCK(b2, pool, fl, sl); + + b->size = size | (b->size & PREV_STATE); + } else { + next_b->size &= (~PREV_FREE); + b->size &= (~FREE_BLOCK); /* Now it's used */ + } + + pool->used_size += (b->size & BLOCK_SIZE_MASK) + BHDR_OVERHEAD; + + /* Successful alloc: update stats. */ + stat_set(used, tlsf_get_used_size(pool)); + stat_set(total, tlsf_get_total_size(pool)); + stat_inc(pool->count_alloc); + stat_setmax(pool->peak_extra, total - used); + stat_setmax(pool->peak_used, used); + stat_setmax(pool->peak_total, total); + + spin_unlock(&pool->lock); + return (void *)b->ptr.buffer; + + /* Failed alloc */ +out_locked: + spin_unlock(&pool->lock); + +out: + stat_inc(pool->count_failed_alloc); + return NULL; +} +EXPORT_SYMBOL_GPL(tlsf_malloc); + +/** + * tlsf_free - free memory from given pool + * @ptr: address of memory to be freed + * @mem_pool: pool to free from + */ +void tlsf_free(void *ptr, void *mem_pool) +{ + struct pool *pool = (struct pool *)mem_pool; + struct bhdr *b, *tmp_b; + int fl = 0, sl = 0; +#if defined(CONFIG_TLSF_STATS) + size_t used, total; +#endif + if (unlikely(ptr == NULL)) + return; + + b = (struct bhdr *) ((char *) ptr - BHDR_OVERHEAD); + + spin_lock(&pool->lock); + b->size |= FREE_BLOCK; + pool->used_size -= (b->size & BLOCK_SIZE_MASK) + BHDR_OVERHEAD; + b->ptr.free_ptr = (struct free_ptr) { NULL, NULL}; + tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE_MASK); + if (tmp_b->size & FREE_BLOCK) { + MAPPING_INSERT(tmp_b->size & BLOCK_SIZE_MASK, &fl, &sl); + EXTRACT_BLOCK(tmp_b, pool, fl, sl); + b->size += (tmp_b->size & BLOCK_SIZE_MASK) + BHDR_OVERHEAD; + } + if (b->size & PREV_FREE) { + tmp_b = b->prev_hdr; + MAPPING_INSERT(tmp_b->size & BLOCK_SIZE_MASK, &fl, &sl); + EXTRACT_BLOCK(tmp_b, pool, fl, sl); + tmp_b->size += (b->size & BLOCK_SIZE_MASK) + BHDR_OVERHEAD; + b = tmp_b; + } + tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE_MASK); + tmp_b->prev_hdr = b; + + MAPPING_INSERT(b->size & BLOCK_SIZE_MASK, &fl, &sl); + + if ((b->prev_hdr == NULL) && ((tmp_b->size & BLOCK_SIZE_MASK) == 0)) { + pool->put_mem(b); + pool->num_regions--; + pool->used_size -= BHDR_OVERHEAD; /* sentinel block header */ + stat_inc(pool->count_region_free); + goto out; + } + + INSERT_BLOCK(b, pool, fl, sl); + + tmp_b->size |= PREV_FREE; + tmp_b->prev_hdr = b; +out: + /* Update stats */ + stat_set(used, tlsf_get_used_size(pool)); + stat_set(total, tlsf_get_total_size(pool)); + stat_inc(pool->count_free); + stat_setmax(pool->peak_extra, total - used); + stat_setmax(pool->peak_used, used); + stat_setmax(pool->peak_total, total); + + spin_unlock(&pool->lock); +} +EXPORT_SYMBOL_GPL(tlsf_free); + +/** + * tlsf_calloc - allocate and zero-out memory from given pool + * @size: no. of bytes + * @mem_pool: pool to allocate from + */ +void *tlsf_calloc(size_t nelem, size_t elem_size, void *mem_pool) +{ + void *ptr; + + if (nelem == 0 || elem_size == 0) + return NULL; + + if ((ptr = tlsf_malloc(nelem * elem_size, mem_pool)) == NULL) + return NULL; + memset(ptr, 0, nelem * elem_size); + + return ptr; +} +EXPORT_SYMBOL_GPL(tlsf_calloc); + +static int __init tlsf_init(void) +{ + INIT_LIST_HEAD(&pool_list_head); + spin_lock_init(&pool_list_lock); +#if defined(CONFIG_TLSF_STATS) + proc = create_proc_entry("tlsfinfo", S_IRUGO, NULL); + if (proc) + proc->proc_fops = &proc_tlsfinfo_operations; + else + pr_warning(T "error creating proc entry\n"); +#endif + return 0; +} + +static void __exit tlsf_exit(void) +{ +#if defined(CONFIG_TLSF_STATS) + if (proc) + remove_proc_entry("tlsfinfo", proc->parent); +#endif + return; +} + +module_init(tlsf_init); +module_exit(tlsf_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Nitin Gupta "); +MODULE_DESCRIPTION("TLSF Memory Allocator"); --- linux-2.6.28.orig/ubuntu/compcache/compcache.c +++ linux-2.6.28/ubuntu/compcache/compcache.c @@ -0,0 +1,480 @@ +/* + * Compressed RAM based swap device + * + * (C) 2008 Nitin Gupta + * + * This RAM based block device acts as swap disk. + * Pages swapped to this device are compressed and + * stored in memory. + * + * Released under the terms of the GNU General Public + * License (version 2). See linux/COPYING for more information. + * + * Project home: http://code.google.com/p/compcache + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "compcache.h" + +static struct block_device_operations compcache_devops = { + .owner = THIS_MODULE, +}; + +static unsigned int init_done; +static struct compcache compcache; +static unsigned long compcache_size_kbytes; +#if defined(STATS) +static struct compcache_stats stats; +#endif + +#if defined(STATS) +static struct proc_dir_entry *proc; + +static int proc_compcache_read(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len; +#if defined(STATS) + size_t succ_writes; + unsigned int good_compress_perc = 0, no_compress_perc = 0; +#endif + + if (off > 0) { + *eof = 1; + return 0; + } + + len = sprintf(page, + "DiskSize: %8zu kB\n", + compcache.size >> (10 - SECTOR_SHIFT)); +#if defined(STATS) + succ_writes = stats.num_writes - stats.failed_writes; + if (succ_writes) { + good_compress_perc = stats.good_compress * 100 / succ_writes; + no_compress_perc = stats.pages_expand * 100 / succ_writes; + } + +#define K(x) ((x) >> 10) + len += sprintf(page + len, + "NumReads: %8u\n" + "NumWrites: %8u\n" + "FailedReads: %8u\n" + "FailedWrites: %8u\n" + "InvalidIO: %8u\n" + "GoodCompress: %8u %%\n" + "NoCompress: %8u %%\n" + "NotifyFree: %8u\n" + "CurrentPages: %8zu\n" + "CurrentMem: %8zu kB\n" + "PeakMem: %8zu kB\n", + stats.num_reads, + stats.num_writes, + stats.failed_reads, + stats.failed_writes, + stats.invalid_io, + good_compress_perc, + no_compress_perc, + stats.notify_free, + stats.curr_pages, + K(stats.curr_mem), + K(stats.peak_mem)); +#endif + return len; +} +#endif /* STATS */ + +/* + * callback function called when swap_map[offset] == 0 + * i.e page at this swap offset is no longer used + */ +static void notify_swap_entry_free(unsigned long offset) +{ + stat_inc(stats.notify_free); + + /* + * + * This callback happened due to some page being + * freed from swap-cache. This page was not written + * to swap disk. + */ + if (compcache.table[offset].addr == NULL) + return; + + tlsf_free(compcache.table[offset].addr, compcache.mem_pool); + stat_dec(stats.curr_pages); + stat_set(stats.curr_mem, stats.curr_mem - + compcache.table[offset].len); + compcache.table[offset].addr = NULL; + compcache.table[offset].len = 0; +} + +/* Check if request is within bounds and page aligned */ +static inline int valid_swap_request(struct bio *bio) +{ + if (unlikely((bio->bi_sector >= compcache.size) || + (bio->bi_sector & (SECTORS_PER_PAGE - 1)) || + (bio->bi_vcnt != 1) || + (bio->bi_size != PAGE_SIZE) || + (bio->bi_io_vec[0].bv_offset != 0))) + return 0; + return 1; +} + +static int compcache_make_request(struct request_queue *queue, struct bio *bio) +{ + int ret; + size_t clen, page_no; + void *user_mem; + struct page *page; + + if (!valid_swap_request(bio)) { + stat_inc(stats.invalid_io); + goto out_nomap; + } + + page = bio->bi_io_vec[0].bv_page; + page_no = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT; + + if (unlikely(!init_done) && PageSwapCache(page)) { + swp_entry_t entry = { .val = page_private(page) }; + set_notify_swap_entry_free(swp_type(entry), + notify_swap_entry_free); + init_done = 1; + } + + user_mem = kmap(page); + + if (bio_data_dir(bio) == READ) { + stat_inc(stats.num_reads); + /* + * This is attempt to read before any previous write + * to this location. This happens due to readahead when + * swap device is read from user-space (e.g. during swapon) + */ + if (unlikely(compcache.table[page_no].addr == NULL)) { + pr_debug("Read before write on swap device: " + "sector=%lu, size=%u, offset=%u\n", + (ulong)(bio->bi_sector), + bio->bi_size, + bio->bi_io_vec[0].bv_offset); + memset(user_mem, 0, PAGE_SIZE); + kunmap(page); + set_bit(BIO_UPTODATE, &bio->bi_flags); + bio_endio(bio, 0); + return 0; + } + + /* Page is stored uncompressed since its incompressible */ + if (unlikely(compcache.table[page_no].len == PAGE_SIZE)) { + memcpy(user_mem, compcache.table[page_no].addr, + PAGE_SIZE); + kunmap(page); + set_bit(BIO_UPTODATE, &bio->bi_flags); + bio_endio(bio, 0); + return 0; + } + + clen = PAGE_SIZE; + ret = lzo1x_decompress_safe( + compcache.table[page_no].addr, + compcache.table[page_no].len, + user_mem, + &clen); + + /* should NEVER happen */ + if (unlikely(ret != LZO_E_OK)) { + pr_err(C "Decompression failed! " + "err=%d, page=%zu, len=%lu\n", ret, page_no, + compcache.table[page_no].len); + stat_inc(stats.failed_reads); + goto out; + } + + kunmap(page); + set_bit(BIO_UPTODATE, &bio->bi_flags); + bio_endio(bio, 0); + return 0; + } else { /* Write */ + unsigned char *src = compcache.compress_buffer; + stat_inc(stats.num_writes); + /* + * System swaps to same sector again when the stored page + * is no longer referenced by any process. So, its now safe + * to free the memory that was allocated for this page. + */ + if (compcache.table[page_no].addr) { + tlsf_free(compcache.table[page_no].addr, + compcache.mem_pool); + stat_dec(stats.curr_pages); + stat_set(stats.curr_mem, stats.curr_mem - + compcache.table[page_no].len); + compcache.table[page_no].addr = NULL; + compcache.table[page_no].len = 0; + } + + mutex_lock(&compcache.lock); + ret = lzo1x_1_compress(user_mem, PAGE_SIZE, + src, &clen, compcache.compress_workmem); + if (unlikely(ret != LZO_E_OK)) { + mutex_unlock(&compcache.lock); + pr_err(C "Compression failed! err=%d\n", ret); + compcache.table[page_no].addr = NULL; + compcache.table[page_no].len = 0; + stat_inc(stats.failed_writes); + goto out; + } + + /* Page is incompressible - store it as is */ + if (clen >= PAGE_SIZE) { + pr_debug("Page expand on compression: " + "page=%zu, size=%zu\n", page_no, clen); + clen = PAGE_SIZE; + src = user_mem; + } + + if ((compcache.table[page_no].addr = tlsf_malloc(clen, + compcache.mem_pool)) == NULL) { + mutex_unlock(&compcache.lock); + pr_err(C "Error allocating memory for compressed " + "page: %zu, size=%zu \n", page_no, clen); + compcache.table[page_no].len = 0; + stat_inc(stats.failed_writes); + goto out; + } + + memcpy(compcache.table[page_no].addr, src, clen); + + /* Update stats */ + stat_inc(stats.curr_pages); + stat_set(stats.curr_mem, stats.curr_mem + clen); + stat_setmax(stats.peak_mem, stats.curr_mem); + stat_inc_if_less(stats.pages_expand, PAGE_SIZE - 1, clen); + stat_inc_if_less(stats.good_compress, clen, + PAGE_SIZE / 2 + 1); + mutex_unlock(&compcache.lock); + + compcache.table[page_no].len = clen; + + kunmap(page); + set_bit(BIO_UPTODATE, &bio->bi_flags); + bio_endio(bio, 0); + return 0; + } +out: + kunmap(page); +out_nomap: + bio_io_error(bio); + return 0; +} + +static void setup_swap_header(union swap_header *s) +{ + s->info.version = 1; + s->info.last_page = compcache.size >> SECTORS_PER_PAGE_SHIFT; + s->info.nr_badpages = 0; + memcpy(s->magic.magic, "SWAPSPACE2", 10); +} + +static void *get_mem(size_t size) +{ + return __vmalloc(size, GFP_NOIO, PAGE_KERNEL); +} + +static void put_mem(void *ptr) +{ + vfree(ptr); +} + +static int __init compcache_init(void) +{ + int ret; + size_t num_pages; + struct sysinfo i; + + mutex_init(&compcache.lock); + + if (compcache_size_kbytes == 0) { + pr_info(C "compcache size not provided." + " Using default: (%u%% of Total RAM).\n" + "Use compcache_size_kbytes module param to specify" + " custom size\n", DEFAULT_COMPCACHE_PERCENT); + si_meminfo(&i); + compcache_size_kbytes = ((DEFAULT_COMPCACHE_PERCENT * + i.totalram) / 100) << (PAGE_SHIFT - 10); + } + + compcache.size = compcache_size_kbytes << 10; + compcache.size = (compcache.size + PAGE_SIZE - 1) & PAGE_MASK; + pr_info(C "Compressed swap size set to: %zu KB\n", compcache.size >> 10); + compcache.size >>= SECTOR_SHIFT; + + compcache.compress_workmem = kmalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL); + if (compcache.compress_workmem == NULL) { + pr_err(C "Error allocating compressor working memory\n"); + ret = -ENOMEM; + goto fail; + } + + compcache.compress_buffer = kmalloc(2 * PAGE_SIZE, GFP_KERNEL); + if (compcache.compress_buffer == NULL) { + pr_err(C "Error allocating compressor buffer space\n"); + ret = -ENOMEM; + goto fail; + } + + num_pages = compcache.size >> SECTORS_PER_PAGE_SHIFT; + compcache.table = vmalloc(num_pages * sizeof(*compcache.table)); + if (compcache.table == NULL) { + pr_err(C "Error allocating compcache address table\n"); + ret = -ENOMEM; + goto fail; + } + memset(compcache.table, 0, num_pages * sizeof(*compcache.table)); + + compcache.table[0].addr = (void *)get_zeroed_page(GFP_KERNEL); + if (compcache.table[0].addr == NULL) { + pr_err(C "Error allocating swap header page\n"); + ret = -ENOMEM; + goto fail; + } + compcache.table[0].len = PAGE_SIZE; + setup_swap_header((union swap_header *)(compcache.table[0].addr)); + + compcache.disk = alloc_disk(1); + if (compcache.disk == NULL) { + pr_err(C "Error allocating disk structure\n"); + ret = -ENOMEM; + goto fail; + } + + compcache.disk->first_minor = 0; + compcache.disk->fops = &compcache_devops; + /* + * It is named like this to prevent distro installers + * from offering compcache as installation target. They + * seem to ignore all devices beginning with 'ram' + */ + strcpy(compcache.disk->disk_name, "ramzswap0"); + + compcache.disk->major = register_blkdev(0, compcache.disk->disk_name); + if (compcache.disk->major < 0) { + pr_err(C "Cannot register block device\n"); + ret = -EFAULT; + goto fail; + } + + compcache.disk->queue = blk_alloc_queue(GFP_KERNEL); + if (compcache.disk->queue == NULL) { + pr_err(C "Cannot register disk queue\n"); + ret = -EFAULT; + goto fail; + } + + set_capacity(compcache.disk, compcache.size); + blk_queue_make_request(compcache.disk->queue, compcache_make_request); + blk_queue_hardsect_size(compcache.disk->queue, PAGE_SIZE); + add_disk(compcache.disk); + + compcache.mem_pool = tlsf_create_memory_pool("compcache", + get_mem, put_mem, + INIT_SIZE_BYTES, 0, GROW_SIZE_BYTES); + if (compcache.mem_pool == NULL) { + pr_err(C "Error creating memory pool\n"); + ret = -ENOMEM; + goto fail; + } + +#if defined(STATS) + proc = create_proc_entry("compcache", S_IRUGO, NULL); + if (proc) + proc->read_proc = &proc_compcache_read; + else { + ret = -ENOMEM; + pr_warning(C "Error creating proc entry\n"); + goto fail; + } +#endif + + pr_debug(C "Initialization done!\n"); + return 0; + +fail: + if (compcache.disk != NULL) { + if (compcache.disk->major > 0) + unregister_blkdev(compcache.disk->major, + compcache.disk->disk_name); + del_gendisk(compcache.disk); + } + + free_page((unsigned long)compcache.table[0].addr); + kfree(compcache.compress_workmem); + kfree(compcache.compress_buffer); + vfree(compcache.table); + tlsf_destroy_memory_pool(compcache.mem_pool); +#if defined(STATS) + if (proc) + remove_proc_entry("compcache", proc->parent); +#endif + pr_err(C "Initialization failed: err=%d\n", ret); + return ret; +} + +static void __exit compcache_exit(void) +{ + size_t i, num_pages; + num_pages = compcache.size >> SECTORS_PER_PAGE_SHIFT; + + unregister_blkdev(compcache.disk->major, compcache.disk->disk_name); + del_gendisk(compcache.disk); + free_page((unsigned long)compcache.table[0].addr); + kfree(compcache.compress_workmem); + kfree(compcache.compress_buffer); + + /* Free all pages that are still in compcache */ + for (i = 1; i < num_pages; i++) + if (compcache.table[i].addr) + tlsf_free(compcache.table[i].addr, compcache.mem_pool); + vfree(compcache.table); + tlsf_destroy_memory_pool(compcache.mem_pool); + +#if defined(STATS) + remove_proc_entry("compcache", proc->parent); +#endif + pr_debug("cleanup done!\n"); +} + +#ifndef MODULE +static int __init compcache_size_setup(char *str) +{ + if (str) + compcache_size_kbytes = strtoul(str, NULL, 10); + return 1; +} + +__setup("compcache_size_kbytes=", compcache_size_setup); +#endif + +module_param(compcache_size_kbytes, ulong, 0); +MODULE_PARM_DESC(compcache_size_kbytes, "compcache device size (in KB)"); + +module_init(compcache_init); +module_exit(compcache_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Nitin Gupta "); +MODULE_DESCRIPTION("Compressed RAM Based Swap Device"); --- linux-2.6.28.orig/ubuntu/compcache/tlsf_int.h +++ linux-2.6.28/ubuntu/compcache/tlsf_int.h @@ -0,0 +1,145 @@ +/* + * To be used internally by TLSF allocator. + */ + +#ifndef _TLSF_INT_H_ +#define _TLSF_INT_H_ + +#include +#include + +/* Debugging and Stats */ +#define NOP do { } while(0) + +#if defined(CONFIG_TLSF_STATS) +#define stat_inc(stat) (stat++) +#define stat_set(stat, val) (stat = val) +#define stat_setmax(stat, curr) (stat = (curr) > stat ? (curr) : stat) + +#else /* STATS */ +#define stat_inc(x) NOP +#define stat_dec(x) NOP +#define stat_set(x, v) NOP +#define stat_setmax(x, v) NOP +#endif /* STATS */ + +/* Messsage prefix */ +#define T "TLSF: " + +#define MAX_POOL_NAME_LEN 16 + +/*-- TLSF structures */ + +/* Some IMPORTANT TLSF parameters */ +#define MEM_ALIGN (sizeof(void *) * 2) +#define MEM_ALIGN_MASK (~(MEM_ALIGN - 1)) + +#define MAX_FLI (30) +#define MAX_LOG2_SLI (5) +#define MAX_SLI (1 << MAX_LOG2_SLI) + +#define FLI_OFFSET (6) +/* tlsf structure just will manage blocks bigger than 128 bytes */ +#define SMALL_BLOCK (128) +#define REAL_FLI (MAX_FLI - FLI_OFFSET) +#define MIN_BLOCK_SIZE (sizeof(struct free_ptr)) +#define BHDR_OVERHEAD (sizeof(struct bhdr) - MIN_BLOCK_SIZE) + +#define PTR_MASK (sizeof(void *) - 1) +#define BLOCK_SIZE_MASK (0xFFFFFFFF - PTR_MASK) + +#define GET_NEXT_BLOCK(addr, r) ((struct bhdr *) \ + ((char *)(addr) + (r))) +#define ROUNDUP_SIZE(r) (((r) + MEM_ALIGN - 1) & MEM_ALIGN_MASK) +#define ROUNDDOWN_SIZE(r) ((r) & MEM_ALIGN_MASK) +#define ROUNDUP_PAGE(r) (((r) + PAGE_SIZE - 1) & PAGE_MASK) + +#define BLOCK_STATE (0x1) +#define PREV_STATE (0x2) + +/* bit 0 of the block size */ +#define FREE_BLOCK (0x1) +#define USED_BLOCK (0x0) + +/* bit 1 of the block size */ +#define PREV_FREE (0x2) +#define PREV_USED (0x0) + +#if defined(CONFIG_TLSF_DEBUG) +#define MAX_RETRY_EXPAND 10 +#endif + +struct free_ptr { + struct bhdr *prev; + struct bhdr *next; +}; + +struct bhdr { + /* All blocks in a region are linked in order of physical address */ + struct bhdr *prev_hdr; + /* + * The size is stored in bytes + * bit 0: block is free, if set + * bit 1: previous block is free, if set + */ + u32 size; + /* Free blocks in individual freelists are linked */ + union { + struct free_ptr free_ptr; + u8 buffer[sizeof(struct free_ptr)]; + } ptr; +}; + +struct pool { + /* First level bitmap (REAL_FLI bits) */ + u32 fl_bitmap; + + /* Second level bitmap */ + u32 sl_bitmap[REAL_FLI]; + + /* Free lists */ + struct bhdr *matrix[REAL_FLI][MAX_SLI]; + + spinlock_t lock; + + size_t init_size; + size_t max_size; + size_t grow_size; + + /* Basic stats */ + size_t used_size; + size_t num_regions; + + /* User provided functions for expanding/shrinking pool */ + get_memory *get_mem; + put_memory *put_mem; + + struct list_head list; + +#if defined(CONFIG_TLSF_STATS) + /* Extra stats */ + size_t peak_used; + size_t peak_total; + size_t peak_extra; /* MAX(Total - Used) */ + size_t count_alloc; + size_t count_free; + size_t count_region_alloc; + size_t count_region_free; + size_t count_failed_alloc; +#endif + +#if defined(CONFIG_TLSF_DEBUG) + /* + * Pool used size must be 0 when its destroyed. + * When non-empty pool is destroyed, it suggests + * memory leak. Such pools are marked invalid + * and kept in pool list for later debugging. + */ + unsigned int valid; +#endif + void *init_region; + char name[MAX_POOL_NAME_LEN]; +}; +/*-- TLSF structures end */ + +#endif --- linux-2.6.28.orig/ubuntu/compcache/BOM +++ linux-2.6.28/ubuntu/compcache/BOM @@ -0,0 +1,5 @@ +Downloaded from: http://code.google.com/p/compcache/ +Current Version: Patch for 2.6.26.rc6 + +Moved compcache and tlsf modules to ubuntu/. Only touches swap subsystem +for free page callback. --- linux-2.6.28.orig/ubuntu/dm-loop/dm-loop.c +++ linux-2.6.28/ubuntu/dm-loop/dm-loop.c @@ -0,0 +1,1036 @@ +/* + * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved. + * + * This file is part of device-mapper. + * + * Extent mapping implementation heavily influenced by mm/swapfile.c + * Bryn Reeves + * + * File mapping and block lookup algorithms support by + * Heinz Mauelshagen . + * + * This file is released under the GPL. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dm.h" +#include "dm-bio-list.h" + +#define DM_LOOP_DAEMON "kloopd" +#define DM_MSG_PREFIX "loop" + +enum flags { DM_LOOP_BMAP, DM_LOOP_FSIO }; + +/*-------------------------------------------------------------------- + * Loop context + *--------------------------------------------------------------------*/ + +struct loop_c { + unsigned long flags; + + /* Backing store */ + + struct file *filp; + char *path; + loff_t offset; + struct block_device *bdev; + unsigned blkbits; /* file system block size shift bits */ + + loff_t size; /* size of entire file in bytes */ + loff_t blocks; /* blocks allocated to loop file */ + sector_t mapped_sectors; /* size of mapped area in sectors */ + + int (*map_fn)(struct dm_target *, struct bio *); + void *map_data; +}; + +/* + * Block map extent + */ +struct dm_loop_extent { + sector_t start; /* start sector in mapped device */ + sector_t to; /* start sector on target device */ + sector_t len; /* length in sectors */ +}; + +/* + * Temporary extent list + */ +struct extent_list { + struct dm_loop_extent *extent; + struct list_head list; +}; + +static struct kmem_cache *dm_loop_extent_cache; + +/* + * Block map private context + */ +struct block_map_c { + int nr_extents; /* number of extents in map */ + struct dm_loop_extent **map; /* linear map of extent pointers */ + struct dm_loop_extent **mru; /* pointer to mru entry */ + spinlock_t mru_lock; /* protects mru */ +}; + +/* + * File map private context + */ +struct file_map_c { + spinlock_t lock; /* protects in */ + struct bio_list in; /* new bios for processing */ + struct bio_list work; /* bios queued for processing */ + struct workqueue_struct *wq; /* workqueue */ + struct work_struct ws; /* loop work */ + struct loop_c *loop; /* for filp & offset */ +}; + +/*-------------------------------------------------------------------- + * Generic helpers + *--------------------------------------------------------------------*/ + +static sector_t blk2sect(struct loop_c *lc, blkcnt_t block) +{ + return block << (lc->blkbits - SECTOR_SHIFT); +} + +static blkcnt_t sec2blk(struct loop_c *lc, sector_t sector) +{ + return sector >> (lc->blkbits - SECTOR_SHIFT); +} + +/*-------------------------------------------------------------------- + * File I/O helpers + *--------------------------------------------------------------------*/ + +/* + * transfer data to/from file using the read/write file_operations. + */ +static int fs_io(int rw, struct file *filp, loff_t *pos, struct bio_vec *bv) +{ + ssize_t r; + void __user *ptr = (void __user __force *) kmap(bv->bv_page) + bv->bv_offset; + mm_segment_t old_fs = get_fs(); + + set_fs(get_ds()); + r = (rw == READ) ? filp->f_op->read(filp, ptr, bv->bv_len, pos) : + filp->f_op->write(filp, ptr, bv->bv_len, pos); + set_fs(old_fs); + kunmap(bv->bv_page); + + return (r == bv->bv_len) ? 0 : -EIO; +} + +/* + * Handle I/O for one bio + */ +static void do_one_bio(struct file_map_c *fc, struct bio *bio) +{ + int r = 0, rw = bio_data_dir(bio); + loff_t start = (bio->bi_sector << 9) + fc->loop->offset, pos = start; + struct bio_vec *bv, *bv_end = bio->bi_io_vec + bio->bi_vcnt; + + for (bv = bio->bi_io_vec; bv < bv_end; bv++) { + r = fs_io(rw, fc->loop->filp, &pos, bv); + if (r) { + DMERR("%s error %d", rw ? "write" : "read", r); + break; + } + } + + bio_endio(bio, r); +} + +/* + * Worker thread for a 'file' type loop device + */ +static void do_loop_work(struct work_struct *ws) +{ + struct file_map_c *fc = container_of(ws, struct file_map_c, ws); + struct bio *bio; + + /* quickly grab all new bios queued and add them to the work list */ + spin_lock_irq(&fc->lock); + bio_list_merge(&fc->work, &fc->in); + bio_list_init(&fc->in); + spin_unlock_irq(&fc->lock); + + /* work the list and do file I/O on all bios */ + while ((bio = bio_list_pop(&fc->work))) + do_one_bio(fc, bio); +} + +/* + * Create work queue and initialize work + */ +static int loop_work_init(struct loop_c *lc) +{ + struct file_map_c *fc = lc->map_data; + + fc->wq = create_singlethread_workqueue(DM_LOOP_DAEMON); + if (!fc->wq) + return -ENOMEM; + + return 0; +} + +/* + * Destroy work queue + */ +static void loop_work_exit(struct loop_c *lc) +{ + struct file_map_c *fc = lc->map_data; + + if (fc->wq) + destroy_workqueue(fc->wq); +} + +/* + * DM_LOOP_FSIO map_fn. Mapping just queues bios to the file map + * context and lets the daemon deal with them. + */ +static int loop_file_map(struct dm_target *ti, struct bio *bio) +{ + int wake; + struct loop_c *lc = ti->private; + struct file_map_c *fc = lc->map_data; + + spin_lock_irq(&fc->lock); + wake = bio_list_empty(&fc->in); + bio_list_add(&fc->in, bio); + spin_unlock_irq(&fc->lock); + + /* + * Only call queue_work() if necessary to avoid + * superfluous preempt_{disable/enable}() overhead. + */ + if (wake) + queue_work(fc->wq, &fc->ws); + + /* Handling bio - will submit later. */ + return 0; +} + +/* + * Shutdown the workqueue and free a file mapping + */ +static void destroy_file_map(struct loop_c *lc) +{ + loop_work_exit(lc); + kfree(lc->map_data); +} + +/* + * Set up a file map context and workqueue + */ +static int setup_file_map(struct loop_c *lc) +{ + struct file_map_c *fc = kzalloc(sizeof(*fc), GFP_KERNEL); + + if (!fc) + return -ENOMEM; + + spin_lock_init(&fc->lock); + bio_list_init(&fc->in); + bio_list_init(&fc->work); + INIT_WORK(&fc->ws, do_loop_work); + fc->loop = lc; + + lc->map_data = fc; + lc->map_fn = loop_file_map; + + return loop_work_init(lc); +} + +/*-------------------------------------------------------------------- + * Block I/O helpers + *--------------------------------------------------------------------*/ + +static int contains_sector(struct dm_loop_extent *e, sector_t s) +{ + if (likely(e)) + return s < (e->start + (e->len)) && s >= e->start; + + return 0; +} + +/* + * Walk over a linked list of extent_list structures, freeing them as + * we go. Does not free el->extent. + */ +static void destroy_extent_list(struct list_head *head) +{ + struct list_head *curr, *n; + struct extent_list *el; + + if (list_empty(head)) + return; + + list_for_each_safe(curr, n, head) { + el = list_entry(curr, struct extent_list, list); + list_del(curr); + kfree(el); + } +} + +/* + * Add a new extent to the tail of the list at *head with + * start/to/len parameters. Allocates from the extent cache. + */ +static int list_add_extent(struct list_head *head, sector_t start, + sector_t to, sector_t len) +{ + struct dm_loop_extent *extent; + struct extent_list *list; + + extent = kmem_cache_alloc(dm_loop_extent_cache, GFP_KERNEL); + if (!extent) + goto out; + + list = kmalloc(sizeof(*list), GFP_KERNEL); + if (!list) + goto out; + + extent->start = start; + extent->to = to; + extent->len = len; + + list->extent = extent; + list_add_tail(&list->list, head); + + return 0; +out: + if (extent) + kmem_cache_free(dm_loop_extent_cache, extent); + return -ENOMEM; +} + +/* + * Return an extent range (i.e. beginning and ending physical block numbers). + */ +static int extent_range(struct inode *inode, + blkcnt_t logical_blk, blkcnt_t last_blk, + blkcnt_t *begin_blk, blkcnt_t *end_blk) +{ + sector_t dist = 0, phys_blk, probe_blk = logical_blk; + + /* Find beginning physical block of extent starting at logical_blk. */ + *begin_blk = phys_blk = bmap(inode, probe_blk); + if (!phys_blk) + return -ENXIO; + + for (; phys_blk == *begin_blk + dist; dist++) { + *end_blk = phys_blk; + if (++probe_blk > last_blk) + break; + + phys_blk = bmap(inode, probe_blk); + if (unlikely(!phys_blk)) + return -ENXIO; + } + + return 0; +} + +/* + * Create a sequential list of extents from an inode and return + * it in *head. On success return the number of extents found or + * -ERRNO on failure. + */ +static int loop_extents(struct loop_c *lc, struct inode *inode, + struct list_head *head) +{ + sector_t start = 0; + int r, nr_extents = 0; + blkcnt_t nr_blks = 0, begin_blk = 0, end_blk = 0; + blkcnt_t after_last_blk = sec2blk(lc, + (lc->mapped_sectors + (lc->offset >> 9))); + blkcnt_t logical_blk = sec2blk(lc, (lc->offset >> 9)); + + /* for each block in the mapped region */ + while (logical_blk < after_last_blk) { + r = extent_range(inode, logical_blk, after_last_blk - 1, + &begin_blk, &end_blk); + + /* sparse file fallback */ + if (unlikely(r)) { + DMWARN("%s has a hole; sparse file detected - " + "switching to filesystem I/O", lc->path); + clear_bit(DM_LOOP_BMAP, &lc->flags); + set_bit(DM_LOOP_FSIO, &lc->flags); + return r; + } + + nr_blks = 1 + end_blk - begin_blk; + + if (unlikely(!nr_blks)) + continue; + + r = list_add_extent(head, start, blk2sect(lc, begin_blk), + blk2sect(lc, nr_blks)); + if (unlikely(r)) + return r; + + /* advance to next extent */ + nr_extents++; + start += blk2sect(lc, nr_blks); + logical_blk += nr_blks; + } + + return nr_extents; +} + +/* + * Walk over the extents in a block_map_c, returning them to the cache and + * freeing bc->map and bc. + */ +static void destroy_block_map(struct block_map_c *bc) +{ + unsigned i; + + if (!bc) + return; + + for (i = 0; i < bc->nr_extents; i++) + kmem_cache_free(dm_loop_extent_cache, bc->map[i]); + + DMDEBUG("destroying block map of %d entries", i); + + vfree(bc->map); + kfree(bc); +} + +/* + * Find an extent in *bc using binary search. Returns a pointer into the + * extent map. Calculate index as (extent - bc->map). + */ +static struct dm_loop_extent **extent_binary_lookup(struct block_map_c *bc, + struct dm_loop_extent **extent_mru, sector_t sector) +{ + unsigned nr_extents = bc->nr_extents; + unsigned delta, dist, prev_dist = 0; + struct dm_loop_extent **eptr; + + /* Optimize lookup range based on MRU extent. */ + dist = extent_mru - bc->map; + if ((*extent_mru)->start >= sector) + delta = dist = dist / 2; + else { + delta = (nr_extents - dist) / 2; + dist += delta; + } + + eptr = bc->map + dist; + while (*eptr && !contains_sector(*eptr, sector)) { + if (sector >= (*eptr)->start + (*eptr)->len) { + prev_dist = dist; + if (delta > 1) + delta /= 2; + dist += delta; + } else { + delta = (dist - prev_dist) / 2; + if (!delta) + delta = 1; + dist -= delta; + } + eptr = bc->map + dist; + } + + return eptr; +} + +/* + * Lookup an extent for a sector using the mru cache and binary search. + */ +static struct dm_loop_extent *extent_lookup(struct block_map_c *bc, sector_t sector) +{ + struct dm_loop_extent **eptr; + + spin_lock_irq(&bc->mru_lock); + eptr = bc->mru; + spin_unlock_irq(&bc->mru_lock); + + if (contains_sector(*eptr, sector)) + return *eptr; + + eptr = extent_binary_lookup(bc, eptr, sector); + if (!eptr) + return NULL; + + spin_lock_irq(&bc->mru_lock); + bc->mru = eptr; + spin_unlock_irq(&bc->mru_lock); + + return *eptr; +} + +/* + * DM_LOOP_BMAP map_fn. Looks up the sector in the extent map and + * rewrites the bio device and bi_sector fields. + */ +static int loop_block_map(struct dm_target *ti, struct bio *bio) +{ + struct loop_c *lc = ti->private; + struct dm_loop_extent *extent = extent_lookup(lc->map_data, bio->bi_sector); + + if (likely(extent)) { + bio->bi_bdev = lc->bdev; + bio->bi_sector = extent->to + (bio->bi_sector - extent->start); + return 1; /* Done with bio -> submit */ + } + + DMERR("no matching extent in map for sector %llu", + (unsigned long long) bio->bi_sector + ti->begin); + BUG(); + + return -EIO; +} + +/* + * Turn an extent_list into a linear pointer map of nr_extents + 1 entries + * and set the final entry to NULL. + */ +static struct dm_loop_extent **build_extent_map(struct list_head *head, int nr_extents, + unsigned long *flags) +{ + unsigned map_size, cache_size; + struct dm_loop_extent **map, **curr; + struct list_head *pos; + struct extent_list *el; + + map_size = 1 + (sizeof(*map) * nr_extents); + cache_size = kmem_cache_size(dm_loop_extent_cache) * nr_extents; + + map = vmalloc(map_size); + curr = map; + + DMDEBUG("allocated extent map of %u %s for %d extents (%u %s)", + (map_size < 8192) ? map_size : map_size >> 10, + (map_size < 8192) ? "bytes" : "kilobytes", nr_extents, + (cache_size < 8192) ? cache_size : cache_size >> 10, + (cache_size < 8192) ? "bytes" : "kilobytes"); + + list_for_each(pos, head) { + el = list_entry(pos, struct extent_list, list); + *(curr++) = el->extent; + } + *curr = NULL; + + return map; +} + +/* + * Set up a block map context and extent map + */ +static int setup_block_map(struct loop_c *lc, struct inode *inode) +{ + int r, nr_extents; + struct block_map_c *bc; + LIST_HEAD(head); + + if (!inode || !inode->i_sb || !inode->i_sb->s_bdev) + return -ENXIO; + + /* build a linked list of extents in linear order */ + r = nr_extents = loop_extents(lc, inode, &head); + if (nr_extents < 1) + goto out; + + r = -ENOMEM; + bc = kzalloc(sizeof(*bc), GFP_KERNEL); + if (!bc) + goto out; + + /* create a linear map of pointers into the extent cache */ + bc->map = build_extent_map(&head, nr_extents, &lc->flags); + destroy_extent_list(&head); + + if (IS_ERR(bc->map)) { + r = PTR_ERR(bc->map); + goto out; + } + + spin_lock_init(&bc->mru_lock); + bc->mru = bc->map; + bc->nr_extents = nr_extents; + lc->bdev = inode->i_sb->s_bdev; + lc->map_data = bc; + lc->map_fn = loop_block_map; + + return 0; + +out: + return r; +} + +/*-------------------------------------------------------------------- + * Generic helpers + *--------------------------------------------------------------------*/ + +/* + * Invalidate all unlocked loop file pages + */ +static int loop_invalidate_file(struct file *filp) +{ + int r; + + /* Same as generic_file_direct_IO() */ + unmap_mapping_range(filp->f_mapping, 0, ~0UL, 0); + + r = filemap_write_and_wait(filp->f_mapping); + if (r) + return r; + + /* + * This will remove all pages except dirty ones. + * If there are dirty pages at this point, it means that the user + * is writing to the file and the coherency is lost anyway. + * If the user was writing to the file simultaneously, this + * returns non-zero, but we ignore that. + */ + invalidate_inode_pages2_range(filp->f_mapping, 0, ~0UL); + + return 0; +} + +/* + * Acquire or release a "no-truncate" lock on *filp. + * We overload the S_SWAPFILE flag for loop targets because + * it provides the same no-truncate semantics we require, and + * holding onto i_sem is no longer an option. + */ +static void file_truncate_lock(struct file *filp) +{ + struct inode *inode = filp->f_mapping->host; + + mutex_lock(&inode->i_mutex); + inode->i_flags |= S_SWAPFILE; + mutex_unlock(&inode->i_mutex); +} + +static void file_truncate_unlock(struct file *filp) +{ + struct inode *inode = filp->f_mapping->host; + + mutex_lock(&inode->i_mutex); + inode->i_flags &= ~S_SWAPFILE; + mutex_unlock(&inode->i_mutex); +} + +/* + * Fill out split_io for taget backing store + */ +static void set_split_io(struct dm_target *ti) +{ + struct loop_c *lc = ti->private; + + if (test_bit(DM_LOOP_BMAP, &lc->flags)) + /* Split I/O at block boundaries */ + ti->split_io = 1 << (lc->blkbits - SECTOR_SHIFT); + else + ti->split_io = 64; + + DMDEBUG("splitting io at %llu sector boundaries", + (unsigned long long) ti->split_io); +} + +/* + * Check that the loop file is regular and available. + */ +static int loop_check_file(struct dm_target *ti) +{ + struct loop_c *lc = ti->private; + struct file *filp = lc->filp; + struct inode *inode = filp->f_mapping->host; + + if (!inode) + return -ENXIO; + + ti->error = "backing file must be a regular file"; + if (!S_ISREG(inode->i_mode)) + return -EINVAL; + + ti->error = "backing file is mapped into userspace for writing"; + if (mapping_writably_mapped(filp->f_mapping)) + return -EBUSY; + + if (mapping_mapped(filp->f_mapping)) + DMWARN("%s is mapped into userspace", lc->path); + + if (!inode->i_sb || !inode->i_sb->s_bdev) { + DMWARN("%s has no blockdevice - switching to filesystem I/O", + lc->path); + clear_bit(DM_LOOP_BMAP, &lc->flags); + set_bit(DM_LOOP_FSIO, &lc->flags); + } + + ti->error = "backing file already in use"; + if (IS_SWAPFILE(inode)) + return -EBUSY; + + return 0; +} + +/* + * Check loop file size and store it in the loop context + */ +static int loop_setup_size(struct dm_target *ti) +{ + struct loop_c *lc = ti->private; + struct inode *inode = lc->filp->f_mapping->host; + int r = -EINVAL; + + lc->size = i_size_read(inode); + lc->blkbits = inode->i_blkbits; + + ti->error = "backing file is empty"; + if (!lc->size) + goto out; + + DMDEBUG("set backing file size to %llu", (unsigned long long) lc->size); + + ti->error = "backing file cannot be less than one block in size"; + if (lc->size < (blk2sect(lc, 1) << 9)) + goto out; + + ti->error = "loop file offset must be a multiple of fs blocksize"; + if (lc->offset & ((1 << lc->blkbits) - 1)) + goto out; + + ti->error = "loop file offset too large"; + if (lc->offset > (lc->size - (1 << 9))) + goto out; + + lc->mapped_sectors = (lc->size - lc->offset) >> 9; + DMDEBUG("set mapped sectors to %llu (%llu bytes)", + (unsigned long long) lc->mapped_sectors, + (lc->size - lc->offset)); + + if ((lc->offset + (lc->mapped_sectors << 9)) < lc->size) + DMWARN("not using %llu bytes in incomplete block at EOF", + lc->size - (lc->offset + (lc->mapped_sectors << 9))); + + ti->error = "mapped region cannot be smaller than target size"; + if (lc->size - lc->offset < (ti->len << 9)) + goto out; + + r = 0; + +out: + return r; +} + +/* + * release a loop file + */ +static void loop_put_file(struct file *filp) +{ + if (!filp) + return; + + file_truncate_unlock(filp); + filp_close(filp, NULL); +} + +/* + * Open loop file and perform type, availability and size checks. + */ +static int loop_get_file(struct dm_target *ti) +{ + int flags = ((dm_table_get_mode(ti->table) & FMODE_WRITE) ? + O_RDWR : O_RDONLY) | O_LARGEFILE; + struct loop_c *lc = ti->private; + struct file *filp; + int r = 0; + + ti->error = "could not open backing file"; + filp = filp_open(lc->path, flags, 0); + if (IS_ERR(filp)) + return PTR_ERR(filp); + lc->filp = filp; + r = loop_check_file(ti); + if (r) + goto err; + + r = loop_setup_size(ti); + if (r) + goto err; + + file_truncate_lock(filp); + return 0; + +err: + fput(filp); + return r; +} + +/* + * invalidate mapped pages belonging to the loop file + */ +static void loop_flush(struct dm_target *ti) +{ + struct loop_c *lc = ti->private; + + loop_invalidate_file(lc->filp); +} + +/*-------------------------------------------------------------------- + * Device-mapper target methods + *--------------------------------------------------------------------*/ + +/* + * Generic loop map function. Re-base I/O to target begin and submit + */ +static int loop_map(struct dm_target *ti, struct bio *bio, + union map_info *context) +{ + struct loop_c *lc = ti->private; + + if (unlikely(bio_barrier(bio))) + return -EOPNOTSUPP; + + bio->bi_sector -= ti->begin; + + if (lc->map_fn) + return lc->map_fn(ti, bio); + + return -EIO; +} + +/* + * Block status helper + */ +static ssize_t loop_file_status(struct loop_c *lc, char *result, + unsigned maxlen) +{ + ssize_t sz = 0; + struct file_map_c *fc = lc->map_data; + int qlen; + + spin_lock_irq(&fc->lock); + qlen = bio_list_size(&fc->work); + qlen += bio_list_size(&fc->in); + spin_unlock_irq(&fc->lock); + + DMEMIT("file %d", qlen); + + return sz; +} + +/* + * File status helper + */ +static ssize_t loop_block_status(struct loop_c *lc, char *result, + unsigned maxlen) +{ + ssize_t sz = 0; + struct block_map_c *bc = lc->map_data; + int mru; + + spin_lock_irq(&bc->mru_lock); + mru = bc->mru - bc->map; + spin_unlock_irq(&bc->mru_lock); + + DMEMIT("block %d %d", bc->nr_extents, mru); + + return sz; +} + +/* + * This needs some thought on handling unlinked backing files. some parts of + * the kernel return a cached name (now invalid), while others return a dcache + * "/path/to/foo (deleted)" name (never was/is valid). Which is "better" is + * debatable. + * + * On the one hand, using a cached name gives table output which is directly + * usable assuming the user re-creates the unlinked image file, on the other + * it is more consistent with e.g. swap to use the dcache name. + * +*/ +static int loop_status(struct dm_target *ti, status_type_t type, char *result, + unsigned maxlen) +{ + struct loop_c *lc = ti->private; + ssize_t sz = 0; + + switch (type) { + case STATUSTYPE_INFO: + if (test_bit(DM_LOOP_BMAP, &lc->flags)) + sz += loop_block_status(lc, result, maxlen - sz); + else if (test_bit(DM_LOOP_FSIO, &lc->flags)) + sz += loop_file_status(lc, result, maxlen - sz); + break; + + case STATUSTYPE_TABLE: + DMEMIT("%s %llu", lc->path, lc->offset); + break; + } + return 0; +} + +/* + * Destroy a loopback mapping + */ +static void loop_dtr(struct dm_target *ti) +{ + struct loop_c *lc = ti->private; + + if ((dm_table_get_mode(ti->table) & FMODE_WRITE)) + loop_invalidate_file(lc->filp); + + if (test_bit(DM_LOOP_BMAP, &lc->flags) && lc->map_data) + destroy_block_map((struct block_map_c *)lc->map_data); + if (test_bit(DM_LOOP_FSIO, &lc->flags) && lc->map_data) + destroy_file_map(lc); + + loop_put_file(lc->filp); + DMINFO("released file %s", lc->path); + + kfree(lc); +} + +/* + * Construct a loopback mapping: + */ +static int loop_ctr(struct dm_target *ti, unsigned argc, char **argv) +{ + struct loop_c *lc = NULL; + int r = -EINVAL; + + ti->error = "invalid argument count"; + if (argc != 2) + goto err; + + r = -ENOMEM; + ti->error = "cannot allocate loop context"; + lc = kzalloc(sizeof(*lc), GFP_KERNEL); + if (!lc) + goto err; + + /* default */ + set_bit(DM_LOOP_BMAP, &lc->flags); + ti->error = "cannot allocate loop path"; + lc->path = kstrdup(argv[0], GFP_KERNEL); + if (!lc->path) + goto err; + + ti->private = lc; + + r = -EINVAL; + ti->error = "invalid file offset"; + if (sscanf(argv[1], "%lld", &lc->offset) != 1) + goto err; + + if (lc->offset) + DMDEBUG("setting file offset to %lld", lc->offset); + + /* open & check file and set size parameters */ + r = loop_get_file(ti); + + /* ti->error has been set by loop_get_file */ + if (r) + goto err; + + ti->error = "could not create loop mapping"; + if (test_bit(DM_LOOP_BMAP, &lc->flags)) + r = setup_block_map(lc, lc->filp->f_mapping->host); + if (test_bit(DM_LOOP_FSIO, &lc->flags)) + r = setup_file_map(lc); + + if (r) + goto err_putf; + + loop_invalidate_file(lc->filp); + + set_split_io(ti); + if (lc->bdev) + dm_set_device_limits(ti, lc->bdev); + + DMDEBUG("constructed loop target on %s " + "(%lldk, %llu sectors)", lc->path, + (lc->size >> 10), (unsigned long long)lc->mapped_sectors); + ti->error = NULL; + + return 0; + +err_putf: + loop_put_file(lc->filp); +err: + if (lc) + kfree(lc); + return r; +} + +static struct target_type loop_target = { + .name = "loop", + .version = {0, 0, 2}, + .module = THIS_MODULE, + .ctr = loop_ctr, + .dtr = loop_dtr, + .map = loop_map, + .presuspend = loop_flush, + .flush = loop_flush, + .status = loop_status, +}; + +/*-------------------------------------------------------------------- + * Module bits + *--------------------------------------------------------------------*/ +static int __init dm_loop_init(void) +{ + int r; + + r = dm_register_target(&loop_target); + if (r < 0) { + DMERR("register failed %d", r); + goto err; + } + + r = -ENOMEM; + dm_loop_extent_cache = KMEM_CACHE(dm_loop_extent, SLAB_HWCACHE_ALIGN); + if (!dm_loop_extent_cache) + goto err; + + DMINFO("version %u.%u.%u loaded", + loop_target.version[0], loop_target.version[1], + loop_target.version[2]); + + return 0; + +err: + if (dm_loop_extent_cache) + kmem_cache_destroy(dm_loop_extent_cache); + + return r; +} + +static void __exit dm_loop_exit(void) +{ + int r; + + r = dm_unregister_target(&loop_target); + kmem_cache_destroy(dm_loop_extent_cache); + + if (r < 0) + DMERR("target unregister failed %d", r); + else + DMINFO("version %u.%u.%u unloaded", + loop_target.version[0], loop_target.version[1], + loop_target.version[2]); +} + +module_init(dm_loop_init); +module_exit(dm_loop_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Bryn Reeves "); +MODULE_DESCRIPTION("device-mapper loop target"); --- linux-2.6.28.orig/ubuntu/dm-loop/Kconfig +++ linux-2.6.28/ubuntu/dm-loop/Kconfig @@ -0,0 +1,9 @@ +config DM_LOOP + tristate "Loop target (EXPERIMENTAL)" + depends on BLK_DEV_DM && EXPERIMENTAL + ---help--- + This device-mapper target allows you to treat a regular file as + a block device. + + If unsure, say N. + --- linux-2.6.28.orig/ubuntu/dm-loop/Makefile +++ linux-2.6.28/ubuntu/dm-loop/Makefile @@ -0,0 +1,5 @@ +EXTRA_CFLAGS += -I$(srctree)/drivers/md + +obj-$(CONFIG_DM_LOOP) += dm-loop.o + + --- linux-2.6.28.orig/ubuntu/dm-loop/BOM +++ linux-2.6.28/ubuntu/dm-loop/BOM @@ -0,0 +1,4 @@ +Downloaded from: http://sources.redhat.com/lvm2/wiki/DMLoop +Current Version: Tues, 10 Jun 2008 09:10:03 -0000 +Comments: Fairly easy to integrate in + --- linux-2.6.28.orig/ubuntu/et131x/ET1310_pm.h +++ linux-2.6.28/ubuntu/et131x/ET1310_pm.h @@ -0,0 +1,216 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_pm.h - Defines, structs, enums, prototypes, etc. pertaining to power + * management. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/08/01 19:35:11 $ + $Revision: 1.5 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef _ET1310_PM_H_ +#define _ET1310_PM_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/****************************************************************************** + INCLUDES + *****************************************************************************/ +#include "ET1310_common.h" + + + + +/****************************************************************************** + CONSTANTS FOR POWER MANAGEMENT + *****************************************************************************/ +#define MAX_WOL_PACKET_SIZE 0x80 +#define MAX_WOL_MASK_SIZE ( MAX_WOL_PACKET_SIZE / 8 ) +#define NUM_WOL_PATTERNS 0x5 +#define CRC16_POLY 0x1021 + + + + +/****************************************************************************** + Definition of NDIS_DEVICE_POWER_STATE + *****************************************************************************/ +typedef enum +{ + NdisDeviceStateUnspecified = 0, + NdisDeviceStateD0, + NdisDeviceStateD1, + NdisDeviceStateD2, + NdisDeviceStateD3 +} NDIS_DEVICE_POWER_STATE; + + + + +/****************************************************************************** + Structure for Power Management Info + *****************************************************************************/ +typedef struct _MP_PM_CONFIG_SPACE_INFO_t +{ + UCHAR capId; + UCHAR nextItemPtr; + UINT16 pmcr; + UINT16 pmcsr; + UCHAR pmscr_bse; + UCHAR pm_data_regs; +} +MP_PM_CONFIG_SPACE_INFO_t, *pMP_PM_CONFIG_SPACE_INFO_t; + + + + +typedef struct _MP_POWER_MGMT +{ + /************************************************************************** + variable putting the phy into coma mode when boot up with no cable + plugged in after 5 seconds + *************************************************************************/ + UCHAR TransPhyComaModeOnBoot; + + + /************************************************************************** + Array holding the five CRC values that the device is currently using + for WOL. This will be queried when a pattern is to be removed. + *************************************************************************/ + UINT32 localWolAndCrc0; + UINT16 WOLPatternList[ NUM_WOL_PATTERNS ]; + UCHAR WOLMaskList[ NUM_WOL_PATTERNS ][ MAX_WOL_MASK_SIZE ]; + UINT32 WOLMaskSize[ NUM_WOL_PATTERNS ]; + + + /************************************************************************** + IP address + *************************************************************************/ + union + { + UINT32 u32; + UCHAR u8[4]; + } IPAddress; + + + /************************************************************************** + Current Power state of the adapter. + *************************************************************************/ + NDIS_DEVICE_POWER_STATE PowerState; + BOOL_t WOLState; + BOOL_t WOLEnabled; + BOOL_t Failed10Half; + BOOL_t bFailedStateTransition; + + /************************************************************************** + Next two used to save power information at power down. + This information will be used during power up to set up parts of Power + Management in JAGCore + *************************************************************************/ + UINT32 tx_en; + UINT32 rx_en; + UINT16 PowerDownSpeed; + UCHAR PowerDownDuplex; + + MP_PM_CONFIG_SPACE_INFO_t pmConfigRegs; +} MP_POWER_MGMT, *PMP_POWER_MGMT; + + + + +/****************************************************************************** + Forward declaration of the private adapter structure + ( IS THERE A WAY TO DO THIS WITH A TYPEDEF??? ) + *****************************************************************************/ +struct et131x_adapter; + + + + +/****************************************************************************** + PROTOTYPES for ET1310_pm.c + *****************************************************************************/ +UINT16 CalculateCCITCRC16( PUCHAR Pattern, PUCHAR Mask, UINT32 MaskSize ); + +void EnablePhyComa( struct et131x_adapter *pAdapter ); + +void DisablePhyComa( struct et131x_adapter *pAdapter ); + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ET1310_PM_H_ */ --- linux-2.6.28.orig/ubuntu/et131x/et131x_supp.h +++ linux-2.6.28/ubuntu/et131x/et131x_supp.h @@ -0,0 +1,133 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_supp.h - Misc. defines, structs, enums, prototypes, etc. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/08/01 19:35:13 $ + $Revision: 1.5 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + +#ifndef __ET131X_SUPP_H__ +#define __ET131X_SUPP_H__ + + + + +/****************************************************************************** + Enum for use with netif_indicate_status + *****************************************************************************/ +typedef enum netif_status +{ + NETIF_STATUS_INVALID = 0, + NETIF_STATUS_MEDIA_CONNECT, + NETIF_STATUS_MEDIA_DISCONNECT, + NETIF_STATUS_MAX +} NETIF_STATUS; + + + + +/****************************************************************************** + Definitions to maintain compatibility with older versions of the kernel + *****************************************************************************/ +#ifndef netdev_priv +#define netdev_priv(x) (ET131X_ADAPTER *)netdev->priv +#endif + +#ifndef SET_NETDEV_DEV +#define SET_NETDEV_DEV(net, pdev) +#endif + +#ifndef free_netdev +#define free_netdev(x) kfree(x) +#endif + +#ifndef if_mii +#define if_mii(x) (struct mii_ioctl_data *)&x->ifr_ifru +#endif + + + + +/****************************************************************************** + PROTOTYPES + *****************************************************************************/ +void et131x_init_enet_crc_calc( void ); + +UINT32 et131x_calc_enet_crc( PUCHAR Message, UINT32 MessageSize ); + +UINT32 pci_slot_information_read( struct pci_dev *pdev, UINT32 where, + UINT8 *buf, UINT32 len ); + +UINT32 pci_slot_information_write( struct pci_dev *pdev, UINT32 where, + UINT8 *buf, UINT32 len ); + +void netif_indicate_status( struct net_device *netdev, NETIF_STATUS status ); + + + + +#endif /* __ET131X_SUPP_H__ */ --- linux-2.6.28.orig/ubuntu/et131x/et131x_version.h +++ linux-2.6.28/ubuntu/et131x/et131x_version.h @@ -0,0 +1,124 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_version.h - This file provides system and device version information. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2006/01/31 20:58:43 $ + $Revision: 1.16 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET131X_VERSION_H__ +#define __ET131X_VERSION_H__ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include +#include + + + + +/****************************************************************************** + Constant Definitions + *****************************************************************************/ +#define DRIVER_AUTHOR "Victor Soriano (vjsoriano@agere.com)" +#define DRIVER_LICENSE "BSD" +#define DRIVER_DEVICE_STRING "ET1310" +#define DRIVER_NAME "et131x" +#define DRIVER_MAJOR_VERSION 1 +#define DRIVER_MINOR_VERSION 2 +#define DRIVER_PATCH_VERSION 3 +#define DRIVER_VERSION_STRING "1.2.3" +#define DRIVER_VENDOR "Agere Systems, http://www.agere.com" +#define DRIVER_BUILD_DATE "01/31/2006 15:40:00" +#define DRIVER_DESC "10/100/1000 Base-T Ethernet Driver" + +#define STRUCT_MODULE "net" // blux: missed by the kernel + +#define DRIVER_INFO DRIVER_DESC " for the "\ + DRIVER_DEVICE_STRING ", v" \ + DRIVER_VERSION_STRING " " \ + DRIVER_BUILD_DATE " by " \ + DRIVER_VENDOR + + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#define DRIVER_NAME_EXT "et131x.o" +#else +#define DRIVER_NAME_EXT "et131x.ko" +#endif + + + + +#endif /* __ET131X_VERSION_H__ */ --- linux-2.6.28.orig/ubuntu/et131x/et131x_defs.h +++ linux-2.6.28/ubuntu/et131x/et131x_defs.h @@ -0,0 +1,223 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_defs.h - Defines, structs, enums, prototypes, etc. to assist with OS + * compatibility + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/10/28 18:43:46 $ + $Revision: 1.8 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET131X_DEFS_H__ +#define __ET131X_DEFS_H__ + + + + +/****************************************************************************** + Define a boolean type + *****************************************************************************/ +typedef enum { FALSE, TRUE } __attribute__ ((packed)) BOOL_t; + + + + +/****************************************************************************** + Packet and header sizes + *****************************************************************************/ +#define NIC_MIN_PACKET_SIZE 60 +#define NIC_HEADER_SIZE ETH_HLEN //14 + + + + +/****************************************************************************** + Multicast list size + *****************************************************************************/ +#define NIC_MAX_MCAST_LIST 128 + + + + +/****************************************************************************** + Supported Filters + *****************************************************************************/ +#define ET131X_PACKET_TYPE_DIRECTED 0x0001 +#define ET131X_PACKET_TYPE_MULTICAST 0x0002 +#define ET131X_PACKET_TYPE_BROADCAST 0x0004 +#define ET131X_PACKET_TYPE_PROMISCUOUS 0x0008 +#define ET131X_PACKET_TYPE_ALL_MULTICAST 0x0010 + + + + +/****************************************************************************** + Tx Timeout + *****************************************************************************/ +#define ET131X_TX_TIMEOUT (1 * HZ) +#define NIC_SEND_HANG_THRESHOLD 0 + + + + +/****************************************************************************** + MP_TCB flags + *****************************************************************************/ +#define fMP_DEST_MULTI 0x00000001 +#define fMP_DEST_BROAD 0x00000002 + + + + +/****************************************************************************** + MP_ADAPTER flags + *****************************************************************************/ +#define fMP_ADAPTER_RECV_LOOKASIDE 0x00000004 +#define fMP_ADAPTER_INTERRUPT_IN_USE 0x00000008 +#define fMP_ADAPTER_SECONDARY 0x00000010 + + + + +/****************************************************************************** + MP_SHARED flags + *****************************************************************************/ +#define fMP_ADAPTER_SHUTDOWN 0x00100000 +#define fMP_ADAPTER_LOWER_POWER 0x00200000 + +#define fMP_ADAPTER_NON_RECOVER_ERROR 0x00800000 +#define fMP_ADAPTER_RESET_IN_PROGRESS 0x01000000 +#define fMP_ADAPTER_NO_CABLE 0x02000000 +#define fMP_ADAPTER_HARDWARE_ERROR 0x04000000 +#define fMP_ADAPTER_REMOVE_IN_PROGRESS 0x08000000 +#define fMP_ADAPTER_HALT_IN_PROGRESS 0x10000000 +#define fMP_ADAPTER_LINK_DETECTION 0x20000000 + +#define fMP_ADAPTER_FAIL_SEND_MASK 0x3ff00000 +#define fMP_ADAPTER_NOT_READY_MASK 0x3ff00000 + + + + +/****************************************************************************** + Some offsets in PCI config space that are actually used. + *****************************************************************************/ +#define ET1310_PCI_PM_CAPABILITY (UINT32)0x40 +#define ET1310_PCI_PM_CSR (UINT32)0x44 +#define ET1310_PCI_MAX_PYLD (UINT32)0x4C +#define ET1310_PCI_DEV_CTRL (UINT32)0x50 +#define ET1310_PCI_DEV_STAT (UINT32)0x52 +#define ET1310_NMI_DISABLE (UINT32)0x61 +#define ET1310_PCI_MAC_ADDRESS (UINT32)0xA4 +#define ET1310_PCI_EEPROM_STATUS (UINT32)0xB2 +#define ET1310_PCI_PHY_INDEX_REG (UINT32)0xB4 +#define ET1310_PCI_ACK_NACK (UINT32)0xC0 +#define ET1310_PCI_REPLAY (UINT32)0xC2 +#define ET1310_PCI_L0L1LATENCY (UINT32)0xCF +#define ET1310_PCI_SEL_PHY_CTRL (UINT32)0xE4 +#define ET1310_PCI_ADVANCED_ERR (UINT32)0x100 + + + + +/****************************************************************************** + PCI Vendor/Product IDs + *****************************************************************************/ +#define ET131X_PCI_VENDOR_ID 0x11C1 // Agere Systems +#define ET131X_PCI_DEVICE_ID_GIG 0xED00 // ET1310 1000 Base-T +#define ET131X_PCI_DEVICE_ID_FAST 0xED01 // ET1310 100 Base-T + + + + +/****************************************************************************** + Define FIELD_OFFSET macro + *****************************************************************************/ +#define FIELD_OFFSET(type,field) ((int)(&((type *)0)->field)) + + + + +/****************************************************************************** + Handle name change of some regsiter bits + *****************************************************************************/ +#define phy_sw_coma pm_phy_sw_coma + + + + +/****************************************************************************** + Define order of magnitude converter + *****************************************************************************/ +#define NANO_IN_A_MICRO 1000 + + + + +#endif /* __ET131X_DEFS_H__ */ --- linux-2.6.28.orig/ubuntu/et131x/et131x_isr.h +++ linux-2.6.28/ubuntu/et131x/et131x_isr.h @@ -0,0 +1,95 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_isr.h - Defines, structs, enums, prototypes, etc. pertaining to the + * ISR processing code. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/08/01 19:35:13 $ + $Revision: 1.3 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET131X_ISR_H__ +#define __ET131X_ISR_H__ + + + + +/****************************************************************************** + Function Prototypes + *****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +void et131x_isr( int irq, void *dev_id, struct pt_regs *regs ); +#else +irqreturn_t et131x_isr( int irq, void *dev_id ); +#endif + +void et131x_isr_handler( struct work_struct *work ); + + +#endif /* __ET131X_ISR_H__ */ --- linux-2.6.28.orig/ubuntu/et131x/et131x_config.h +++ linux-2.6.28/ubuntu/et131x/et131x_config.h @@ -0,0 +1,99 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_config.h - Defines, structs, enums, prototypes, etc. to support + * et131x_config.c + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/08/01 19:35:12 $ + $Revision: 1.4 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET131X_CONFIG_H__ +#define __ET131X_CONFIG_H__ + + + + +/****************************************************************************** + Forward declaration of the private adapter structure + *****************************************************************************/ +struct et131x_adapter; + + + + +/****************************************************************************** + PROTOTYPES for et131x_config.c + *****************************************************************************/ +void et131x_config_parse( struct et131x_adapter *pAdapter ); + + + + +#endif /* __ET131X_CONFIG_H__ */ --- linux-2.6.28.orig/ubuntu/et131x/et131x_main.c +++ linux-2.6.28/ubuntu/et131x/et131x_main.c @@ -0,0 +1,258 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_main.c - This file contains the driver's main Linux entry points. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/08/01 19:35:13 $ + $Revision: 1.6 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" +#include "et131x_initpci.h" + + + + +/****************************************************************************** + Modinfo parameters (filled out using defines from et131x_version.h) + *****************************************************************************/ +MODULE_AUTHOR( DRIVER_AUTHOR ); +MODULE_DESCRIPTION( DRIVER_INFO ); +MODULE_LICENSE( DRIVER_LICENSE ); + + + + +/****************************************************************************** + Module Parameters and related data for debugging facilities + *****************************************************************************/ +#ifdef ET131X_DBG + +static u32 et131x_debug_level = DBG_LVL; +static u32 et131x_debug_flags = DBG_DEFAULTS; + +module_param( et131x_debug_level, uint, 0 ); +module_param( et131x_debug_flags, uint, 0 ); + +MODULE_PARM_DESC( et131x_debug_level, + "Level of debugging desired (0-7)" ); + +dbg_info_t et131x_info = { DRIVER_NAME_EXT, 0, 0 }; +dbg_info_t *et131x_dbginfo = &et131x_info; + +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + ROUTINE : et131x_init_module + ****************************************************************************** + + DESCRIPTION : The "main" entry point called on driver initialization + + PARAMETERS : N/A + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_init_module( void ) +{ + int result; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_init_module" ); + + +#ifdef ET131X_DBG + /************************************************************************** + Set the level of debug messages displayed using the module parameter + *************************************************************************/ + et131x_dbginfo->dbgFlags = et131x_debug_flags; + + switch( et131x_debug_level ) + { + case 7: + et131x_dbginfo->dbgFlags |= ( DBG_RX_ON | DBG_TX_ON ); + + case 6: + et131x_dbginfo->dbgFlags |= DBG_PARAM_ON; + + case 5: + et131x_dbginfo->dbgFlags |= DBG_VERBOSE_ON; + + case 4: + et131x_dbginfo->dbgFlags |= DBG_TRACE_ON; + + case 3: + et131x_dbginfo->dbgFlags |= DBG_NOTICE_ON; + + case 2: + case 1: + case 0: + default: + break; + } +#endif /* ET131X_DBG */ + + DBG_ENTER( et131x_dbginfo ); + DBG_PRINT( "%s\n", DRIVER_INFO ); + + + result = et131x_pci_register( ); + + + DBG_LEAVE( et131x_dbginfo ); + return result; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_cleanup_module + ****************************************************************************** + + DESCRIPTION : The entry point called on driver cleanup + + PARAMETERS : N/A + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_cleanup_module( void ) +{ + DBG_FUNC( "et131x_cleanup_module" ); + DBG_ENTER( et131x_dbginfo ); + + + et131x_pci_unregister( ); + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + These macros map the driver-specific init_module() and cleanup_module() + routines so they can be called by the kernel. + *****************************************************************************/ +module_init(et131x_init_module); +module_exit(et131x_cleanup_module); --- linux-2.6.28.orig/ubuntu/et131x/et131x_adapter.h +++ linux-2.6.28/ubuntu/et131x/et131x_adapter.h @@ -0,0 +1,508 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_adapter.h - Header which includes the private adapter structure, along + * with related support structures, macros, definitions, etc. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2006/01/25 20:48:56 $ + $Revision: 1.15 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET131X_ADAPTER_H__ +#define __ET131X_ADAPTER_H__ + + + + +#include "ET1310_address_map.h" +#include "ET1310_tx.h" +#include "ET1310_rx.h" + + + + +/****************************************************************************** + Do not change these values: if changed, then change also in respective + TXdma and Rxdma engines + *****************************************************************************/ +#define NUM_DESC_PER_RING_TX 512 // TX Do not change these values +#define NUM_TCB 64 + + + + +/****************************************************************************** + These values are all superseded by registry entries to facilitate tuning. + Once the desired performance has been achieved, the optimal registry values + should be re-populated to these #defines: + *****************************************************************************/ +#define NUM_TRAFFIC_CLASSES 1 + + + + +/****************************************************************************** + There are three ways of counting errors - if there are more than X errors + in Y packets (represented by the "SAMPLE" macros), if there are more than + N errors in a S mSec time period (the "PERIOD" macros), or if there are + consecutive packets with errors (CONSEC_ERRORED_THRESH). This last covers + for "Bursty" errors, and the errored packets may well not be contiguous, + but several errors where the packet counter has changed by less than a + small amount will cause this count to increment. + *****************************************************************************/ +#define TX_PACKETS_IN_SAMPLE 10000 +#define TX_MAX_ERRORS_IN_SAMPLE 50 + +#define TX_ERROR_PERIOD 1000 +#define TX_MAX_ERRORS_IN_PERIOD 10 + +#define LINK_DETECTION_TIMER 5000 + +#define TX_CONSEC_RANGE 5 +#define TX_CONSEC_ERRORED_THRESH 10 + +#define LO_MARK_PERCENT_FOR_PSR 15 +#define LO_MARK_PERCENT_FOR_RX 15 + + + + +/****************************************************************************** + Macros for flag and ref count operations + *****************************************************************************/ +#define MP_SET_FLAG(_M, _F) ((_M)->Flags |= (_F)) +#define MP_CLEAR_FLAG(_M, _F) ((_M)->Flags &= ~(_F)) +#define MP_CLEAR_FLAGS(_M) ((_M)->Flags = 0) +#define MP_TEST_FLAG(_M, _F) (((_M)->Flags & (_F)) != 0) +#define MP_TEST_FLAGS(_M, _F) (((_M)->Flags & (_F)) == (_F)) +#define MP_IS_FLAG_CLEAR(_M, _F) (((_M)->Flags & (_F)) == 0) + +#define MP_INC_RCV_REF(_A) atomic_inc(&(_A)->RcvRefCount) +#define MP_DEC_RCV_REF(_A) atomic_dec(&(_A)->RcvRefCount) +#define MP_GET_RCV_REF(_A) atomic_read(&(_A)->RcvRefCount) + + + + +/****************************************************************************** + Macros specific to the private adapter structure + *****************************************************************************/ +#define MP_TCB_RESOURCES_AVAILABLE(_M) ((_M)->TxRing.nBusySend < NUM_TCB) +#define MP_TCB_RESOURCES_NOT_AVAILABLE(_M) ((_M)->TxRing.nBusySend >= NUM_TCB) + +#define MP_SHOULD_FAIL_SEND(_M) ((_M)->Flags & fMP_ADAPTER_FAIL_SEND_MASK) +#define MP_IS_NOT_READY(_M) ((_M)->Flags & fMP_ADAPTER_NOT_READY_MASK) +#define MP_IS_READY(_M) !((_M)->Flags & fMP_ADAPTER_NOT_READY_MASK) + +#define MP_HAS_CABLE(_M) !((_M)->Flags & fMP_ADAPTER_NO_CABLE) +#define MP_LINK_DETECTED(_M) !((_M)->Flags & fMP_ADAPTER_LINK_DETECTION) + + + + +/****************************************************************************** + Counters for error rate monitoring + *****************************************************************************/ +typedef struct _MP_ERR_COUNTERS +{ + UINT32 PktCountTxPackets; + UINT32 PktCountTxErrors; + UINT32 TimerBasedTxErrors; + UINT32 PktCountLastError; + UINT32 ErredConsecPackets; +} MP_ERR_COUNTERS, *PMP_ERR_COUNTERS; + + + + +/****************************************************************************** + RFD (Receive Frame Descriptor) + *****************************************************************************/ +typedef struct _MP_RFD +{ + struct list_head list_node; + struct sk_buff *Packet; + UINT32 PacketSize; // total size of receive frame + UINT16 iBufferIndex; + UINT8 iRingIndex; +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) + BOOL_t bHasVLANTag; + UINT16 VLANTag; +#endif +} MP_RFD, *PMP_RFD; + + + + +/****************************************************************************** + Enum for Flow Control + *****************************************************************************/ +typedef enum _eflow_control_t { + Both = 0, + TxOnly = 1, + RxOnly = 2, + None = 3 +} eFLOW_CONTROL_t, *PeFLOW_CONTROL_t; + + + + +/****************************************************************************** + Struct to define some device statistics + *****************************************************************************/ +typedef struct _ce_stats_t +{ + /************************************************************************** + Link Input/Output stats + *************************************************************************/ + UINT64 ipackets; // # of in packets + UINT64 opackets; // # of out packets + + + /************************************************************************** + MIB II variables + *************************************************************************/ + /************************************************************************** + NOTE - atomic_t types are only guaranteed to store 24-bits; if we MUST + have 32, then we'll need another way to perform atomic operations + *************************************************************************/ + UINT32 unircv; // # multicast packets received + atomic_t unixmt; // # multicast packets for Tx + UINT32 multircv; // # multicast packets received + atomic_t multixmt; // # multicast packets for Tx + UINT32 brdcstrcv; // # broadcast packets received + atomic_t brdcstxmt; // # broadcast packets for Tx + UINT32 norcvbuf; // # Rx packets discarded + UINT32 noxmtbuf; // # Tx packets discarded + + + /************************************************************************** + Transciever state informations. + *************************************************************************/ + UINT32 xcvr_addr; + UINT32 xcvr_id; + + + /************************************************************************** + Tx Statistics. + *************************************************************************/ + UINT32 tx_uflo; //Tx Underruns + + UINT32 collisions; + UINT32 excessive_collisions; + UINT32 first_collision; + UINT32 late_collisions; + UINT32 max_pkt_error; + UINT32 tx_deferred; + + + /************************************************************************** + Rx Statistics. + *************************************************************************/ + UINT32 rx_ov_flow; //Rx Over Flow + + UINT32 length_err; + UINT32 alignment_err; + UINT32 crc_err; + UINT32 code_violations; + UINT32 other_errors; + +#ifdef ET131X_DBG + UINT32 UnhandledInterruptsPerSec; + UINT32 RxDmaInterruptsPerSec; + UINT32 TxDmaInterruptsPerSec; + UINT32 WatchDogInterruptsPerSec; +#endif /* ET131X_DBG */ + + UINT32 SynchrounousIterations; + INT_STATUS_t InterruptStatus; +} +CE_STATS_t, *PCE_STATS_t; + + + + +/****************************************************************************** + The private adapter structure + *****************************************************************************/ +typedef struct et131x_adapter +{ + struct net_device *netdev; + struct pci_dev *pdev; + + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) + struct tq_struct task; +#else + struct work_struct task; +#endif + + + /************************************************************************** + Flags that indicate current state of the adapter + *************************************************************************/ + UINT32 Flags; + UINT32 HwErrCount; + + + /************************************************************************** + Configuration + *************************************************************************/ + UCHAR PermanentAddress[ETH_ALEN]; + UCHAR CurrentAddress[ETH_ALEN]; + BOOL_t bOverrideAddress; + BOOL_t bEepromPresent; + UCHAR eepromData[2]; + + + /************************************************************************** + Spinlocks + *************************************************************************/ + spinlock_t Lock; + + spinlock_t TCBSendQLock; + spinlock_t TCBReadyQLock; + spinlock_t SendHWLock; + spinlock_t SendWaitLock; + + spinlock_t RcvLock; + spinlock_t RcvPendLock; + spinlock_t FbrLock; + + spinlock_t PHYLock; + + + /************************************************************************** + Packet Filter and look ahead size + *************************************************************************/ + UINT32 PacketFilter; + UINT32 ulLookAhead; + UINT32 uiLinkSpeed; + UINT32 uiDuplexMode; + UINT32 uiAutoNegStatus; + UCHAR ucLinkStatus; + + + /************************************************************************** + multicast list + *************************************************************************/ + UINT32 MCAddressCount; + UCHAR MCList[NIC_MAX_MCAST_LIST][ETH_ALEN]; + + + /************************************************************************** + MAC test + *************************************************************************/ + TXMAC_TXTEST_t TxMacTest; + + + /************************************************************************** + Pointer to the device's PCI register space + *************************************************************************/ + ADDRESS_MAP_t *CSRAddress; + + + /************************************************************************** + PCI config space info, for debug purposes only. + *************************************************************************/ + UCHAR RevisionID; + UINT16 VendorID; + UINT16 DeviceID; + UINT16 SubVendorID; + UINT16 SubSystemID; + UINT32 CacheFillSize; + UINT16 PciXDevCtl; + UCHAR pci_lat_timer; + UCHAR pci_hdr_type; + UCHAR pci_bist; + UINT32 pci_cfg_state[64 / sizeof(u32)]; + + + /************************************************************************** + Registry parameters + *************************************************************************/ + UCHAR SpeedDuplex; // speed/duplex + eFLOW_CONTROL_t RegistryFlowControl; // for 802.3x flow control + UCHAR RegistryWOLMatch; // Enable WOL pattern-matching + UCHAR RegistryWOLLink; // Link state change is independant + UCHAR RegistryPhyComa; // Phy Coma mode enable/disable + + UINT32 RegistryRxMemEnd; // Size of internal rx memory + UCHAR RegistryMACStat; // If set, read MACSTAT, else don't + UINT32 RegistryVlanTag; // 802.1q Vlan TAG + UINT32 RegistryJumboPacket; // Max supported ethernet packet size + + UINT32 RegistryTxNumBuffers; + UINT32 RegistryTxTimeInterval; + + UINT32 RegistryRxNumBuffers; + UINT32 RegistryRxTimeInterval; + + + /************************************************************************** + Validation helpers + *************************************************************************/ + UCHAR RegistryPMWOL; + UCHAR RegistryNMIDisable; + UINT32 RegistryDMACache; + UINT32 RegistrySCGain; + UCHAR RegistryPhyLoopbk; // Enable Phy loopback + + + /************************************************************************** + Derived from the registry: + *************************************************************************/ + UCHAR AiForceDpx; // duplex setting + UINT16 AiForceSpeed; // 'Speed', user over-ride of line speed + eFLOW_CONTROL_t FlowControl; // flow control validated by the far-end + NETIF_STATUS MediaState; + UCHAR DriverNoPhyAccess; + + + /************************************************************************** + Minimize init-time + *************************************************************************/ + BOOL_t bQueryPending; + BOOL_t bSetPending; + BOOL_t bResetPending; + struct timer_list ErrorTimer; + BOOL_t bLinkTimerActive; + MP_POWER_MGMT PoMgmt; + INT_MASK_t CachedMaskValue; + + atomic_t RcvRefCount; // Num packets not yet returned + + + /************************************************************************** + Xcvr status at last poll + *************************************************************************/ + MI_BMSR_t Bmsr; + + + /************************************************************************** + Tx Memory Variables + *************************************************************************/ + TX_RING_t TxRing; + + + /************************************************************************** + Rx Memory Variables + *************************************************************************/ + RX_RING_t RxRing; + + + /************************************************************************** + ET1310 register Access + *************************************************************************/ + JAGCORE_ACCESS_REGS JagCoreRegs; + PCI_CFG_SPACE_REGS PciCfgRegs; + + + /************************************************************************** + Loopback specifics + *************************************************************************/ + UCHAR ReplicaPhyLoopbk; // Replica Enable + UCHAR ReplicaPhyLoopbkPF; // Replica Enable Pass/Fail + + + /************************************************************************** + Stats + *************************************************************************/ + CE_STATS_t Stats; + + struct net_device_stats net_stats; + struct net_device_stats net_stats_prev; + + + /************************************************************************** + VLAN + *************************************************************************/ +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) + struct vlan_group *vlgrp; +#endif + + /************************************************************************** + Data to support workaround for bad config space addresses; see + et131x_pci_setup() for more information + *************************************************************************/ + BOOL_t pci_bar_workaround; + unsigned long pci_bar_addr_orig; +} ET131X_ADAPTER, *PET131X_ADAPTER; + + + + +#define MPSendPacketsHandler MPSendPackets +#define MP_FREE_SEND_PACKET_FUN(Adapter, pMpTcb) et131x_free_send_packet(Adapter, pMpTcb) +#define MpSendPacketFun(Adapter,Packet) MpSendPacket(Adapter, Packet) + + + + +#endif /* __ET131X_ADAPTER_H__ */ --- linux-2.6.28.orig/ubuntu/et131x/Kconfig +++ linux-2.6.28/ubuntu/et131x/Kconfig @@ -0,0 +1,3 @@ +config NET_ET131X + tristate "Agere Systems 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs" + depends on PCI && NET --- linux-2.6.28.orig/ubuntu/et131x/ET1310_eeprom.h +++ linux-2.6.28/ubuntu/et131x/ET1310_eeprom.h @@ -0,0 +1,127 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_eeprom.h - Defines, structs, enums, prototypes, etc. used for EEPROM + * access routines + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/08/01 19:35:10 $ + $Revision: 1.4 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET1310_EEPROM_H__ +#define __ET1310_EEPROM_H__ + + + + +/****************************************************************************** + INCLUDES + *****************************************************************************/ +#include "ET1310_common.h" + + +#ifndef SUCCESS + #define SUCCESS 0 + #define FAILURE 1 +#endif + +#ifndef READ + #define READ 0 + #define WRITE 1 +#endif + +#ifndef SINGLE_BYTE + #define SINGLE_BYTE 0 + #define DUAL_BYTE 1 +#endif + + + + +/****************************************************************************** + Forward declaration of the private adapter structure + *****************************************************************************/ +struct et131x_adapter; + + + + +UINT32 EEPROM_access( struct et131x_adapter *pAdapter, UCHAR bAccessFlag, + UINT32 unOffset, UCHAR bWidth, void *pData ); + +INT32 EepromWriteByte( struct et131x_adapter *pAdapter, UINT32 unAddress, + UCHAR bData, UINT32 unEepromId, UINT32 unAddressingMode ); + +INT32 EepromReadByte( struct et131x_adapter *pAdapter, UINT32 unAddress, + PUCHAR pbData, UINT32 unEepromId, UINT32 unAddressingMode ); + + + + +#endif /* _ET1310_EEPROM_H_ */ --- linux-2.6.28.orig/ubuntu/et131x/et131x_netdev.h +++ linux-2.6.28/ubuntu/et131x/et131x_netdev.h @@ -0,0 +1,91 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_netdev.h - Defines, structs, enums, prototypes, etc. related to the + * driver's net_device support. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/08/01 19:35:13 $ + $Revision: 1.3 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET131X_NETDEV_H__ +#define __ET131X_NETDEV_H__ + + + + +struct net_device * et131x_device_alloc( void ); + +void et131x_device_free( struct net_device *netdev ); + + + + +#endif /* __ET131X_NETDEV_H__ */ + --- linux-2.6.28.orig/ubuntu/et131x/ET1310_rx.h +++ linux-2.6.28/ubuntu/et131x/ET1310_rx.h @@ -0,0 +1,488 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_rx.h - Defines, structs, enums, prototypes, etc. pertaining to data + * reception. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/10/28 18:43:45 $ + $Revision: 1.10 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET1310_RX_H__ +#define __ET1310_RX_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/****************************************************************************** + INCLUDES + *****************************************************************************/ +#include "ET1310_common.h" + +#define USE_FBR0 TRUE + +#ifdef USE_FBR0 +//#define FBR0_BUFFER_SIZE 256 +#endif + +//#define FBR1_BUFFER_SIZE 2048 + +#define FBR_CHUNKS 32 + +#define MAX_DESC_PER_RING_RX 1024 + + + + +/****************************************************************************** + number of RFDs - default and min + *****************************************************************************/ +#ifdef USE_FBR0 + #define RFD_LOW_WATER_MARK 40 + #define NIC_MIN_NUM_RFD 64 + #define NIC_DEFAULT_NUM_RFD 1024 +#else + #define RFD_LOW_WATER_MARK 20 + #define NIC_MIN_NUM_RFD 64 + #define NIC_DEFAULT_NUM_RFD 256 +#endif + +#define NUM_PACKETS_HANDLED 256 + +#define ALCATEL_BAD_STATUS 0xe47f0000 +#define ALCATEL_MULTICAST_PKT 0x01000000 +#define ALCATEL_BROADCAST_PKT 0x02000000 + + + + +/****************************************************************************** + typedefs for Free Buffer Descriptors + *****************************************************************************/ +typedef union _FBR_WORD2_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved:22; //bits 10-31 + UINT32 bi:10; //bits 0-9(Buffer Index) + #else + UINT32 bi:10; //bits 0-9(Buffer Index) + UINT32 reserved:22; //bit 10-31 + #endif + } bits; +} +FBR_WORD2_t, *PFBR_WORD2_t; + +typedef struct _FBR_DESC_t +{ + UINT32 addr_lo; + UINT32 addr_hi; + FBR_WORD2_t word2; +} +FBR_DESC_t, *PFBR_DESC_t; +/*===========================================================================*/ + + + + +/****************************************************************************** + Typedefs for Packet Status Ring Descriptors + *****************************************************************************/ +typedef union _PKT_STAT_DESC_WORD0_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + // top 16 bits are from the Alcatel Status Word as enumerated in + // PE-MCXMAC Data Sheet IPD DS54 0210-1 (also IPD-DS80 0205-2) +#if 0 + UINT32 asw_trunc:1; //bit 31(Rx frame truncated) +#endif + UINT32 asw_long_evt:1; //bit 31(Rx long event) + UINT32 asw_VLAN_tag:1; //bit 30(VLAN tag detected) + UINT32 asw_unsupported_op:1; //bit 29(unsupported OP code) + UINT32 asw_pause_frame:1; //bit 28(is a pause frame) + UINT32 asw_control_frame:1; //bit 27(is a control frame) + UINT32 asw_dribble_nibble:1; //bit 26(spurious bits after EOP) + UINT32 asw_broadcast:1; //bit 25(has a broadcast address) + UINT32 asw_multicast:1; //bit 24(has a multicast address) + UINT32 asw_OK:1; //bit 23(valid CRC + no code error) + UINT32 asw_too_long:1; //bit 22(frame length > 1518 bytes) + UINT32 asw_len_chk_err:1; //bit 21(frame length field incorrect) + UINT32 asw_CRC_err:1; //bit 20(CRC error) + UINT32 asw_code_err:1; //bit 19(one or more nibbles signalled as errors) + UINT32 asw_false_carrier_event:1; //bit 18(bad carrier since last good packet) + UINT32 asw_RX_DV_event:1; //bit 17(short receive event detected) + UINT32 asw_prev_pkt_dropped:1; //bit 16(e.g. IFG too small on previous) + UINT32 unused:5; //bits 11-15 + UINT32 vp:1; //bit 10(VLAN Packet) + UINT32 jp:1; //bit 9(Jumbo Packet) + UINT32 ft:1; //bit 8(Frame Truncated) + UINT32 drop:1; //bit 7(Drop packet) + UINT32 rxmac_error:1; //bit 6(RXMAC Error Indicator) + UINT32 wol:1; //bit 5(WOL Event) + UINT32 tcpp:1; //bit 4(TCP checksum pass) + UINT32 tcpa:1; //bit 3(TCP checksum assist) + UINT32 ipp:1; //bit 2(IP checksum pass) + UINT32 ipa:1; //bit 1(IP checksum assist) + UINT32 hp:1; //bit 0(hash pass) + #else + UINT32 hp:1; //bit 0(hash pass) + UINT32 ipa:1; //bit 1(IP checksum assist) + UINT32 ipp:1; //bit 2(IP checksum pass) + UINT32 tcpa:1; //bit 3(TCP checksum assist) + UINT32 tcpp:1; //bit 4(TCP checksum pass) + UINT32 wol:1; //bit 5(WOL Event) + UINT32 rxmac_error:1; //bit 6(RXMAC Error Indicator) + UINT32 drop:1; //bit 7(Drop packet) + UINT32 ft:1; //bit 8(Frame Truncated) + UINT32 jp:1; //bit 9(Jumbo Packet) + UINT32 vp:1; //bit 10(VLAN Packet) + UINT32 unused:5; //bits 11-15 + UINT32 asw_prev_pkt_dropped:1; //bit 16(e.g. IFG too small on previous) + UINT32 asw_RX_DV_event:1; //bit 17(short receive event detected) + UINT32 asw_false_carrier_event:1; //bit 18(bad carrier since last good packet) + UINT32 asw_code_err:1; //bit 19(one or more nibbles signalled as errors) + UINT32 asw_CRC_err:1; //bit 20(CRC error) + UINT32 asw_len_chk_err:1; //bit 21(frame length field incorrect) + UINT32 asw_too_long:1; //bit 22(frame length > 1518 bytes) + UINT32 asw_OK:1; //bit 23(valid CRC + no code error) + UINT32 asw_multicast:1; //bit 24(has a multicast address) + UINT32 asw_broadcast:1; //bit 25(has a broadcast address) + UINT32 asw_dribble_nibble:1; //bit 26(spurious bits after EOP) + UINT32 asw_control_frame:1; //bit 27(is a control frame) + UINT32 asw_pause_frame:1; //bit 28(is a pause frame) + UINT32 asw_unsupported_op:1; //bit 29(unsupported OP code) + UINT32 asw_VLAN_tag:1; //bit 30(VLAN tag detected) + UINT32 asw_long_evt:1; //bit 31(Rx long event) +#if 0 + UINT32 asw_trunc:1; //bit 31(Rx frame truncated) +#endif + #endif + } bits; +} +PKT_STAT_DESC_WORD0_t, *PPKT_STAT_WORD0_t; + +typedef union _PKT_STAT_DESC_WORD1_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:4; //bits 28-31 + UINT32 ri:2; //bits 26-27(Ring Index) + UINT32 bi:10; //bits 16-25(Buffer Index) + UINT32 length:16; //bit 0-15(length in bytes) + #else + UINT32 length:16; //bit 0-15(length in bytes) + UINT32 bi:10; //bits 16-25(Buffer Index) + UINT32 ri:2; //bits 26-27(Ring Index) + UINT32 unused:4; //bits 28-31 + #endif + } bits; +} +PKT_STAT_DESC_WORD1_t, *PPKT_STAT_WORD1_t; + +typedef struct _PKT_STAT_DESC_t +{ + PKT_STAT_DESC_WORD0_t word0; + PKT_STAT_DESC_WORD1_t word1; +} +PKT_STAT_DESC_t, *PPKT_STAT_DESC_t; +/*===========================================================================*/ + + + + +/****************************************************************************** + Typedefs for the RX DMA status word + *****************************************************************************/ +/****************************************************************************** + RXSTAT_WORD0_t structure holds part of the status bits of the Rx DMA engine + that get copied out to memory by the ET-1310. Word 0 is a 32 bit word which + contains Free Buffer ring 0 and 1 available offset. + *****************************************************************************/ +typedef union _rxstat_word0_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 FBR1unused:5; //bits 27-31 + UINT32 FBR1wrap:1; //bit 26 + UINT32 FBR1offset:10; //bits 16-25 + UINT32 FBR0unused:5; //bits 11-15 + UINT32 FBR0wrap:1; //bit 10 + UINT32 FBR0offset:10; //bits 0-9 + #else + UINT32 FBR0offset:10; //bits 0-9 + UINT32 FBR0wrap:1; //bit 10 + UINT32 FBR0unused:5; //bits 11-15 + UINT32 FBR1offset:10; //bits 16-25 + UINT32 FBR1wrap:1; //bit 26 + UINT32 FBR1unused:5; //bits 27-31 + #endif + } bits; +}RXSTAT_WORD0_t, *PRXSTAT_WORD0_t; + + + + +/****************************************************************************** + RXSTAT_WORD1_t structure holds part of the status bits of the Rx DMA engine + that get copied out to memory by the ET-1310. Word 3 is a 32 bit word which + contains the Packet Status Ring available offset. + *****************************************************************************/ +typedef union _rxstat_word1_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 PSRunused:3; //bits 29-31 + UINT32 PSRwrap:1; //bit 28 + UINT32 PSRoffset:12; //bits 16-27 + UINT32 reserved:16; //bits 0-15 + #else + UINT32 reserved:16; //bits 0-15 + UINT32 PSRoffset:12; //bits 16-27 + UINT32 PSRwrap:1; //bit 28 + UINT32 PSRunused:3; //bits 29-31 + #endif + } bits; +}RXSTAT_WORD1_t, *PRXSTAT_WORD1_t; + + + + +/****************************************************************************** + RX_STATUS_BLOCK_t is sructure representing the status of the Rx DMA engine + it sits in free memory, and is pointed to by 0x101c / 0x1020 + *****************************************************************************/ + +typedef struct _rx_status_block_t +{ + RXSTAT_WORD0_t Word0; + RXSTAT_WORD1_t Word1; +} +RX_STATUS_BLOCK_t, *PRX_STATUS_BLOCK_t; + + + + +/****************************************************************************** + Structure for look-up table holding free buffer ring pointers + *****************************************************************************/ +typedef struct _FbrLookupTable +{ + void *Va [MAX_DESC_PER_RING_RX]; + void *Buffer1 [MAX_DESC_PER_RING_RX]; + void *Buffer2 [MAX_DESC_PER_RING_RX]; + UINT32 PAHigh [MAX_DESC_PER_RING_RX]; + UINT32 PALow [MAX_DESC_PER_RING_RX]; +} FBRLOOKUPTABLE, *PFBRLOOKUPTABLE; + +typedef enum { + ONE_PACKET_INTERRUPT, + FOUR_PACKET_INTERRUPT +} +eRX_INTERRUPT_STATE_t, *PeRX_INTERRUPT_STATE_t; + + + + +/****************************************************************************** + Structure to hold the skb's in a list + *****************************************************************************/ +typedef struct rx_skb_list_elem +{ + struct list_head skb_list_elem; + dma_addr_t dma_addr; + struct sk_buff *skb; +} RX_SKB_LIST_ELEM, *PRX_SKB_LIST_ELEM; + + + + +/****************************************************************************** + RX_RING_t is sructure representing the adaptor's local reference(s) to the + rings + *****************************************************************************/ +typedef struct _rx_ring_t +{ +#ifdef USE_FBR0 + void *pFbr0RingVa; + dma_addr_t pFbr0RingPa; + void *Fbr0MemVa[ MAX_DESC_PER_RING_RX / FBR_CHUNKS ]; + dma_addr_t Fbr0MemPa[ MAX_DESC_PER_RING_RX / FBR_CHUNKS ]; + UINT64 Fbr0Realpa; + UINT64 Fbr0offset; + RXDMA_FBR_FULL_OFFSET_t local_Fbr0_full; + UINT32 Fbr0NumEntries; + UINT32 Fbr0BufferSize; +#endif + void *pFbr1RingVa; + dma_addr_t pFbr1RingPa; + void *Fbr1MemVa[ MAX_DESC_PER_RING_RX / FBR_CHUNKS ]; + dma_addr_t Fbr1MemPa[ MAX_DESC_PER_RING_RX / FBR_CHUNKS ]; + UINT64 Fbr1Realpa; + UINT64 Fbr1offset; + FBRLOOKUPTABLE *Fbr[2]; + RXDMA_FBR_FULL_OFFSET_t local_Fbr1_full; + UINT32 Fbr1NumEntries; + UINT32 Fbr1BufferSize; + + void *pPSRingVa; + dma_addr_t pPSRingPa; + UINT64 pPSRingRealPa; + UINT64 pPSRingOffset; + RXDMA_PSR_FULL_OFFSET_t local_psr_full; + UINT32 PsrNumEntries; + + void *pRxStatusVa; + dma_addr_t pRxStatusPa; + UINT64 RxStatusRealPA; + UINT64 RxStatusOffset; + + struct list_head RecvBufferPool; + + + /************************************************************************** + RECV + *************************************************************************/ + struct list_head RecvList; + struct list_head RecvPendingList; + UINT32 nReadyRecv; + + UINT32 NumRfd; + + BOOL_t UnfinishedReceives; + + struct list_head RecvPacketPool; + + + /************************************************************************** + lookaside lists + *************************************************************************/ + struct kmem_cache *RecvLookaside; +} +RX_RING_t, *PRX_RING_t; + + + + +/****************************************************************************** + Forward reference of RFD + *****************************************************************************/ +struct _MP_RFD; + + + + +/****************************************************************************** + Forward declaration of the private adapter structure + *****************************************************************************/ +struct et131x_adapter; + + + + +/****************************************************************************** + PROTOTYPES for Initialization + *****************************************************************************/ +int et131x_rx_dma_memory_alloc( struct et131x_adapter *adapter ); +void et131x_rx_dma_memory_free( struct et131x_adapter *adapter ); +int et131x_rfd_resources_alloc( struct et131x_adapter *adapter, struct _MP_RFD *pMpRfd ); +void et131x_rfd_resources_free( struct et131x_adapter *adapter, struct _MP_RFD *pMpRfd ); +int et131x_init_recv( struct et131x_adapter *adapter ); + +void ConfigRxDmaRegs( struct et131x_adapter *pAdapter ); +void SetRxDmaTimer( struct et131x_adapter *pAdapter ); +void et131x_rx_dma_disable( struct et131x_adapter *pAdapter ); +void et131x_rx_dma_enable( struct et131x_adapter *pAdapter ); + +void et131x_reset_recv( struct et131x_adapter *pAdapter ); + +void et131x_handle_recv_interrupt( struct et131x_adapter *pAdapter ); + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __ET1310_RX_H__ */ --- linux-2.6.28.orig/ubuntu/et131x/et131x_initpci.c +++ linux-2.6.28/ubuntu/et131x/et131x_initpci.c @@ -0,0 +1,1839 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_initpci.c - Routines and data used to register the driver with the + * PCI (and PCI Express) subsystem, as well as basic driver + * init and startup. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2006/01/25 20:48:56 $ + $Revision: 1.22 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +#include +#endif + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" +#include "et131x_netdev.h" +#include "et131x_config.h" +#include "et131x_isr.h" + +#include "ET1310_address_map.h" +#include "ET1310_jagcore.h" +#include "ET1310_tx.h" +#include "ET1310_rx.h" +#include "ET1310_mac.h" +#include "ET1310_eeprom.h" + + + + +/****************************************************************************** + Data for debugging facilities + *****************************************************************************/ +#ifdef ET131X_DBG +extern dbg_info_t *et131x_dbginfo; +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + Prototypes for functions with local scope + *****************************************************************************/ +int __devinit et131x_pci_probe( struct pci_dev *pdev, + const struct pci_device_id *ent ); + +void __devexit et131x_pci_remove( struct pci_dev *pdev ); + +int et131x_pci_setup( struct pci_dev *pdev ); + + + + +/****************************************************************************** + Data for PCI registration + *****************************************************************************/ +enum et131x_pci_versions +{ + Agere_Systems_PCI_V1 = 0, +}; + + +static struct pci_device_id et131x_pci_table[] __devinitdata = +{ + { ET131X_PCI_VENDOR_ID, ET131X_PCI_DEVICE_ID_GIG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { ET131X_PCI_VENDOR_ID, ET131X_PCI_DEVICE_ID_FAST, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0, } +}; + +MODULE_DEVICE_TABLE( pci, et131x_pci_table ); + + +static struct pci_driver et131x_driver = +{ + name: DRIVER_NAME, + id_table: et131x_pci_table, + probe: et131x_pci_probe, + remove: __devexit_p( et131x_pci_remove ), + suspend: NULL, //et131x_pci_suspend, + resume: NULL, //et131x_pci_resume, +}; + + + + +/****************************************************************************** + ROUTINE : et131x_find_adapter + ****************************************************************************** + + DESCRIPTION : Find the adapter and get all the assigned resources + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_find_adapter( ET131X_ADAPTER *adapter, struct pci_dev *pdev ) +{ + int result; + UCHAR eepromStat = 0; + UCHAR maxPayload = 0; + UCHAR latencyTimers = 0; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_find_adapter" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Allow disabling of Non-Maskable Interrupts in I/O space, to + support validation. + *************************************************************************/ + if( adapter->RegistryNMIDisable ) + { + UCHAR RegisterVal; + + RegisterVal = inb( ET1310_NMI_DISABLE ); + RegisterVal &= 0xf3; + + if( adapter->RegistryNMIDisable == 2 ) + { + RegisterVal |= 0xc; + } + + outb( ET1310_NMI_DISABLE, RegisterVal ); + } + + + /************************************************************************** + We first need to check the EEPROM Status code located at offset 0xB2 + of config space + *************************************************************************/ + + result = pci_slot_information_read( pdev, + ET1310_PCI_EEPROM_STATUS, + &eepromStat, + sizeof( UCHAR )); + /************************************************************************* + THIS IS A WORKAROUND: + * I need to call this function twice to get my card in a + LG M1 Express Dual running. I tried also a msleep before this + function, because I thougth there could be some time condidions + but it didn't work. Call the whole function twice also work. + *************************************************************************/ + result = pci_slot_information_read( pdev, + ET1310_PCI_EEPROM_STATUS, + &eepromStat, + sizeof( UCHAR )); + + if( result != sizeof( UCHAR )) + { + DBG_ERROR( et131x_dbginfo, "Could not read PCI config space for " + "EEPROM Status\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + + + /************************************************************************** + Determine if the error(s) we care about are present. If they are + present, we need to fail. + *************************************************************************/ + if( eepromStat & 0x4C ) + { + result = pci_slot_information_read( pdev, + PCI_REVISION_ID, + &adapter->RevisionID, + sizeof( UCHAR )); + if( result != sizeof( UCHAR )) + { + DBG_ERROR( et131x_dbginfo, + "Could not read PCI config space for " + "Revision ID\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + else if( adapter->RevisionID == 0x01 ) + { + INT32 nLoop; + UCHAR ucTemp[4] = {0xFE, 0x13, 0x10, 0xFF}; + + /****************************************************************** + Re-write the first 4 bytes if we have an eeprom present and + the revision id is 1, this fixes the corruption seen with + 1310 B Silicon + *****************************************************************/ + for( nLoop = 0; nLoop < 3; nLoop++ ) + { + EepromWriteByte( adapter, nLoop, ucTemp[nLoop], 0, SINGLE_BYTE ); + } + } + + DBG_ERROR( et131x_dbginfo, "Fatal EEPROM Status Error - 0x%04x\n", + eepromStat ); + + /********************************************************************** + This error could mean that there was an error reading the eeprom + or that the eeprom doesn't exist. We will treat each case the + same and not try to gather additional information that normally + would come from the eeprom, like MAC Address + *********************************************************************/ + adapter->bEepromPresent = FALSE; + + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + else + { + DBG_TRACE( et131x_dbginfo, "EEPROM Status Code - 0x%04x\n", eepromStat ); + adapter->bEepromPresent = TRUE; + } + + + /************************************************************************** + Read the EEPROM for information regarding LED behavior. Refer to + ET1310_phy.c, et131x_xcvr_init(), for its use. + *************************************************************************/ + EepromReadByte( adapter, 0x70, &adapter->eepromData [0], 0, SINGLE_BYTE ); + EepromReadByte( adapter, 0x71, &adapter->eepromData [1], 0, SINGLE_BYTE ); + + if( adapter->eepromData[0] != 0xcd ) + { + adapter->eepromData[1] = 0x00; // Disable all optional features + } + + + /************************************************************************** + Let's set up the PORT LOGIC Register. First we need to know what the + max_payload_size is + *************************************************************************/ + result = pci_slot_information_read( pdev, + ET1310_PCI_MAX_PYLD, + &maxPayload, + sizeof( UCHAR )); + + if( result != sizeof( UCHAR )) + { + DBG_ERROR( et131x_dbginfo, "Could not read PCI config space for " + "Max Payload Size\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + else + { + UINT16 AckNak [2] = {0x76, 0xD0}; + UINT16 Replay [2] = {0x1E0, 0x2ED}; + + + /********************************************************************** + Program the Ack/Nak latency and replay timers + *********************************************************************/ + maxPayload &= 0x07; // Only the lower 3 bits are valid + + if( maxPayload < 2 ) + { + result = pci_slot_information_write( pdev, + ET1310_PCI_ACK_NACK, + (UINT8 *)&AckNak[maxPayload], + sizeof( UINT16 )); + if( result != sizeof( UINT16 )) + { + DBG_ERROR( et131x_dbginfo, "Could not write PCI config space " + "for ACK/NAK\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + + result = pci_slot_information_write( pdev, + ET1310_PCI_REPLAY, + (UINT8 *)&Replay[maxPayload], + sizeof( UINT16 )); + if( result != sizeof( UINT16 )) + { + DBG_ERROR( et131x_dbginfo, "Could not write PCI config space " + "for Replay Timer\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + } + } + + + /************************************************************************** + l0s and l1 latency timers. We are using default values. + *************************************************************************/ + latencyTimers = 0x11; // Representing 001 for L0s and 010 for L1 + + result = pci_slot_information_write( pdev, + ET1310_PCI_L0L1LATENCY, + (UINT8 *)&latencyTimers, + sizeof( UCHAR )); + if( result != sizeof( UCHAR )) + { + DBG_ERROR( et131x_dbginfo, "Could not write PCI config space for " + "Latency Timers\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + + + /************************************************************************** + Archive Power management capability values for later use + *************************************************************************/ + result = pci_slot_information_read( pdev, + ET1310_PCI_PM_CAPABILITY, + (UINT8 *)&adapter->PoMgmt.pmConfigRegs, + sizeof( MP_PM_CONFIG_SPACE_INFO_t )); + if( result != sizeof( MP_PM_CONFIG_SPACE_INFO_t )) + { + DBG_ERROR( et131x_dbginfo, + "Could not read PCI config space for PM Capability\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + else + { + UCHAR read_size_reg; + + /****************************************************************** + Change the max read size to 2k + *****************************************************************/ + result = pci_slot_information_read( pdev, + 0x51, + (void *)&read_size_reg, + sizeof( UCHAR )); + + if( result != sizeof( UCHAR )) + { + DBG_ERROR( et131x_dbginfo, + "Could not read PCI config space for Max read size\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + + read_size_reg &= 0x8f; + read_size_reg |= 0x40; + + result = pci_slot_information_write( pdev, + 0x51, + &read_size_reg, + sizeof( UCHAR )); + if( result != sizeof( UCHAR )) + { + DBG_ERROR( et131x_dbginfo, + "Could not write PCI config space for Max read size\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + } + + + /************************************************************************** + PCI Express Configuration registers 0x48-0x5B (Device Control) + *************************************************************************/ + result = pci_slot_information_read( pdev, + ET1310_PCI_DEV_CTRL, + (UINT8 *)&adapter->PciXDevCtl, + sizeof( UINT16 )); + + if( result != sizeof( UINT16 )) + { + DBG_ERROR( et131x_dbginfo, + "Could not read PCI config space for PCI Express Dev Ctl\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + + + /************************************************************************** + Get MAC address from config space if an eeprom exists, otherwise the + MAC address there will not be valid + *************************************************************************/ + if( adapter->bEepromPresent ) + { + result = pci_slot_information_read( pdev, + ET1310_PCI_MAC_ADDRESS, + (UINT8 *)adapter->PermanentAddress, + ETH_ALEN ); + if( result != ETH_ALEN ) + { + DBG_ERROR( et131x_dbginfo, + "Could not read PCI config space for MAC address\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + } + + + DBG_LEAVE( et131x_dbginfo ); + return 0; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_error_timer_handler + ****************************************************************************** + + DESCRIPTION : The routine called when the error timer expires, to + track the number of recurring errors. + + PARAMETERS : data - a timer-specific variable; in this case, a + pointer to our private adapter structure + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_error_timer_handler( unsigned long data ) +{ + ET131X_ADAPTER *pAdapter = (ET131X_ADAPTER *)data; + PM_CSR_t pm_csr; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_error_timer_handler" ); + + + pm_csr = pAdapter->CSRAddress->global.pm_csr; + + if( pm_csr.bits.pm_phy_sw_coma == 0 ) + { + if( pAdapter->RegistryMACStat ) + { + UpdateMacStatHostCounters( pAdapter ); + } + } + else + { + DBG_VERBOSE( et131x_dbginfo, + "No interrupts, in PHY coma, pm_csr = 0x%x\n", + pm_csr.value ); + } + + + if( !pAdapter->Bmsr.bits.link_status && + pAdapter->RegistryPhyComa && + pAdapter->PoMgmt.TransPhyComaModeOnBoot < 11 ) + { + pAdapter->PoMgmt.TransPhyComaModeOnBoot++; + } + + if( pAdapter->PoMgmt.TransPhyComaModeOnBoot == 10 ) + { + if( !pAdapter->Bmsr.bits.link_status && pAdapter->RegistryPhyComa ) + { + if( pAdapter->CSRAddress->global.pm_csr.bits.phy_sw_coma == 0 ) + { + // NOTE - This was originally a 'sync with interrupt'. How + // to do that under Linux? + et131x_enable_interrupts( pAdapter ); + EnablePhyComa( pAdapter ); + } + } + } + + + /************************************************************************** + This is a periodic timer, so reschedule + *************************************************************************/ + add_timer( &pAdapter->ErrorTimer ); + + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_link_detection_handler + ****************************************************************************** + DESCRIPTION: + Timer function for handling link up at driver load time + + PARAMETERS : + SystemSpecific1 Not used + FunctionContext Pointer to our adapter + SystemSpecific2 Not used + SystemSpecific3 Not used + + RETURNS : + NONE + + *****************************************************************************/ +void et131x_link_detection_handler( unsigned long data ) +{ + ET131X_ADAPTER *pAdapter = (ET131X_ADAPTER *)data; + unsigned long lockflags; + /*-----------------------------------------------------------------------*/ + + + /************************************************************************** + Let everyone know that we have run + *************************************************************************/ + pAdapter->bLinkTimerActive = FALSE; + + if( pAdapter->MediaState == 0 ) + { + spin_lock_irqsave( &pAdapter->Lock, lockflags ); + + pAdapter->MediaState = NETIF_STATUS_MEDIA_DISCONNECT; + MP_CLEAR_FLAG( pAdapter, fMP_ADAPTER_LINK_DETECTION ); + + spin_unlock_irqrestore( &pAdapter->Lock, lockflags ); + + netif_indicate_status( pAdapter->netdev, pAdapter->MediaState ); + + if( pAdapter->bSetPending ) + { + pAdapter->bSetPending = FALSE; + } + } + + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_adapter_setup + ****************************************************************************** + + DESCRIPTION : Used to set the adapter up as per cassini+ documentation + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_adapter_setup( ET131X_ADAPTER *pAdapter ) +{ + int status = 0; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_adapter_setup" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Configure the JAGCore + *************************************************************************/ + ConfigGlobalRegs( pAdapter ); + + ConfigMACRegs1( pAdapter ); + ConfigMMCRegs( pAdapter ); + + ConfigRxMacRegs( pAdapter ); + ConfigTxMacRegs( pAdapter ); + + ConfigRxDmaRegs( pAdapter ); + ConfigTxDmaRegs( pAdapter ); + + ConfigMacStatRegs( pAdapter ); + + + /************************************************************************** + Move the following code to Timer function?? + *************************************************************************/ + status = et131x_xcvr_find( pAdapter ); + + if( status != 0 ) + { + DBG_WARNING( et131x_dbginfo, "Could not find the xcvr\n" ); + } + + + /********************************************************************** + Prepare the TRUEPHY library. + *********************************************************************/ + ET1310_PhyInit( pAdapter ); + + + /************************************************************************** + Reset the phy now so changes take place + *************************************************************************/ + ET1310_PhyReset( pAdapter ); + + + /************************************************************************** + Power down PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 1 ); + + + /************************************************************************** + We need to turn off 1000 base half dulplex, the mac does not + support it + For the 10/100 part, turn off all gig advertisement + *************************************************************************/ + if( pAdapter->DeviceID != ET131X_PCI_DEVICE_ID_FAST ) + { + ET1310_PhyAdvertise1000BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_FULL ); + } + else + { + ET1310_PhyAdvertise1000BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + } + + + /************************************************************************** + Power up PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 0 ); + + et131x_setphy_normal( pAdapter ); + + + DBG_LEAVE( et131x_dbginfo ); + return status; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_setup_hardware_properties + ****************************************************************************** + + DESCRIPTION : Used to set up the MAC Address on the ET1310 + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_setup_hardware_properties( ET131X_ADAPTER *adapter ) +{ + DBG_FUNC( "et131x_setup_hardware_properties" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + If have our default mac from registry and no mac address from EEPROM + then we need to generate the last octet and set it on the device + *************************************************************************/ + if( !adapter->bOverrideAddress ) + { + if (adapter->PermanentAddress[0] == 0x00 && + adapter->PermanentAddress[1] == 0x00 && + adapter->PermanentAddress[2] == 0x00 && + adapter->PermanentAddress[3] == 0x00 && + adapter->PermanentAddress[4] == 0x00 && + adapter->PermanentAddress[5] == 0x00 ) + { + /****************************************************************** + We need to randomly generate the last octet so we decrease our + chances of setting the mac address to same as another one of + our cards in the system + *****************************************************************/ + get_random_bytes( &adapter->CurrentAddress[5], 1 ); + + + /****************************************************************** + We have the default value in the register we are working with + so we need to copy the current address into the permanent + address + *****************************************************************/ + memcpy( adapter->PermanentAddress, + adapter->CurrentAddress, + ETH_ALEN ); + } + else + { + /****************************************************************** + We do not have an override address, so set the current address + to the permanent address and add it to the device + *****************************************************************/ + memcpy( adapter->CurrentAddress, + adapter->PermanentAddress, + ETH_ALEN ); + } + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_soft_reset + ****************************************************************************** + + DESCRIPTION : Issue a soft reset to the hardware, complete for ET1310. + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_soft_reset( ET131X_ADAPTER *adapter ) +{ + DBG_FUNC( "et131x_soft_reset" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Disable MAC Core + *************************************************************************/ + adapter->CSRAddress->mac.cfg1.value = 0xc00f0000; + + + /************************************************************************** + Set everything to a reset value + *************************************************************************/ + adapter->CSRAddress->global.sw_reset.value = 0x7F; + adapter->CSRAddress->mac.cfg1.value = 0x000f0000; + adapter->CSRAddress->mac.cfg1.value = 0x00000000; + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_align_allocated_memory + ****************************************************************************** + + DESCRIPTION : Align an allocated block of memory on a given boundary + + PARAMETERS : adapter - pointer to our adapter structure + phys_addr - pointer to Physical address + offset - pointer to the offset variable + mask - correct mask + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_align_allocated_memory( ET131X_ADAPTER *adapter, + UINT64 *phys_addr, + UINT64 *offset, + UINT64 mask ) +{ + UINT64 new_addr; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_align_allocated_memory" ); + DBG_ENTER( et131x_dbginfo ); + + + *offset = 0; + + new_addr = *phys_addr & ~mask; + + if( new_addr != *phys_addr ) + { + new_addr += mask+1; // Move to next aligned block + *offset = new_addr - *phys_addr; // Return offset for adjusting virt addr + *phys_addr = new_addr; // Return new physical address + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_adapter_memory_alloc + ****************************************************************************** + + DESCRIPTION : Allocate all the memory blocks for send, receive and + others. + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_adapter_memory_alloc( ET131X_ADAPTER *adapter ) +{ + int status = 0; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_adapter_memory_alloc" ); + DBG_ENTER( et131x_dbginfo ); + + do + { + /********************************************************************** + Allocate memory for the Tx Ring + *********************************************************************/ + status = et131x_tx_dma_memory_alloc( adapter ); + if( status != 0 ) + { + DBG_ERROR( et131x_dbginfo, "et131x_tx_dma_memory_alloc FAILED\n" ); + break; + } + + + /********************************************************************** + Receive buffer memory allocation + *********************************************************************/ + status = et131x_rx_dma_memory_alloc( adapter ); + if( status != 0 ) + { + DBG_ERROR( et131x_dbginfo, "et131x_rx_dma_memory_alloc FAILED\n" ); + et131x_tx_dma_memory_free( adapter ); + break; + } + + + /********************************************************************** + Init receive data structures + *********************************************************************/ + status = et131x_init_recv( adapter ); + if( status != 0 ) + { + DBG_ERROR( et131x_dbginfo, "et131x_init_recv FAILED\n" ); + et131x_tx_dma_memory_free( adapter ); + et131x_rx_dma_memory_free( adapter ); + break; + } + } while( 0 ); + + + DBG_LEAVE( et131x_dbginfo ); + return status; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_adapter_memory_free + ****************************************************************************** + + DESCRIPTION : Free all memory allocated for use by Tx & Rx code + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_adapter_memory_free( ET131X_ADAPTER *adapter ) +{ + DBG_FUNC( "et131x_adapter_memory_free" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Free DMA memory + *************************************************************************/ + et131x_tx_dma_memory_free( adapter ); + et131x_rx_dma_memory_free( adapter ); + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_pci_register + ****************************************************************************** + + DESCRIPTION : This function uses the above data to regsiter the PCI + function table and PCI Vendor/Product ID(s) with the PCI + subsystem to match corresponding devices to this driver. + + PARAMETERS : N/A + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_pci_register( void ) +{ + int result; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_pci_register" ); + DBG_ENTER( et131x_dbginfo ); + + + result = pci_register_driver( &et131x_driver ); + DBG_TRACE( et131x_dbginfo, + " pci_register_driver( ) returns %d \n", + result ); + + + DBG_LEAVE( et131x_dbginfo ); + return result; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_pci_cleanup + ****************************************************************************** + + DESCRIPTION : This function deregisters the PCI function table and + related PCI Vendor/Product ID(s) with the PCI subsytem. + + PARAMETERS : N/A + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_pci_unregister( void ) +{ + DBG_FUNC( "et131x_pci_unregister" ); + DBG_ENTER( et131x_dbginfo ); + + + pci_unregister_driver( &et131x_driver ); + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_pci_probe + ****************************************************************************** + + DESCRIPTION : Registered in the pci_driver structure, this function is + called when the PCI subsystem finds a new PCI device + which matches the information contained in the + pci_device_id table. This routine is the equivalent to + a device insertion routine. + + PARAMETERS : pdev - a pointer to the device's pci_dev structure + ent - this device's entry in the pci_device_id table + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int __devinit et131x_pci_probe( struct pci_dev *pdev, + const struct pci_device_id *ent ) +{ + int result; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_pci_probe" ); + DBG_ENTER( et131x_dbginfo ); + + + result = et131x_pci_setup( pdev ); + + + DBG_LEAVE( et131x_dbginfo ); + return 0; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_pci_remove + ****************************************************************************** + + DESCRIPTION : Registered in the pci_driver structure, this function is + called when the PCI subsystem detects that a PCI device + which matches the information contained in the + pci_device_id table has been removed. + + PARAMETERS : pdev - a pointer to the device's pci_dev structure + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void __devexit et131x_pci_remove( struct pci_dev *pdev ) +{ + struct net_device *netdev = NULL; + ET131X_ADAPTER *adapter = NULL; + BOOL_t bar_workaround; + unsigned long bar_addr_orig = 0; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_pci_remove" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Make sure the pci_dev pointer is valid + *************************************************************************/ + if( pdev == NULL ) + { + DBG_ERROR( et131x_dbginfo, + "PCI subsys passed in an invalid pci_dev pointer\n" ); + DBG_LEAVE( et131x_dbginfo ); + return; + } + + + /************************************************************************** + Retrieve the net_device pointer from the pci_dev struct, as well as the + private adapter struct + *************************************************************************/ + netdev = (struct net_device *)pci_get_drvdata( pdev ); + if( netdev == NULL ) + { + DBG_ERROR( et131x_dbginfo, + "Could not retrieve net_device struct\n" ); + DBG_LEAVE( et131x_dbginfo ); + return; + } + + adapter = netdev_priv( netdev ); + if( adapter == NULL ) + { + DBG_ERROR( et131x_dbginfo, + "Could not retrieve private adapter struct\n" ); + DBG_LEAVE( et131x_dbginfo ); + return; + } + + + /************************************************************************** + Retrieve config space workaround info before deleting the private + adapter struct + *************************************************************************/ + bar_workaround = adapter->pci_bar_workaround; + bar_addr_orig = adapter->pci_bar_addr_orig; + + + /************************************************************************** + Perform device cleanup + *************************************************************************/ + unregister_netdev( netdev ); + et131x_adapter_memory_free( adapter ); + iounmap( (void *)adapter->CSRAddress ); + et131x_device_free( netdev ); + + if( bar_workaround == FALSE ) + { + pci_release_regions( pdev ); + } + else + { + pdev->resource[0].start = bar_addr_orig; + } + + pci_disable_device( pdev ); + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_pci_setup + ****************************************************************************** + + DESCRIPTION : Called by et131x_pci_probe() to perform device + initialization. + + PARAMETERS : pdev - a pointer to the device's pci_dev structure + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_pci_setup( struct pci_dev *pdev ) +{ + int result = 0; + int pm_cap; + BOOL_t pci_using_dac; + unsigned long et131x_reg_base; + unsigned long et131x_reg_len; + struct net_device *netdev = NULL; + ET131X_ADAPTER *adapter = NULL; + BOOL_t bar_workaround = FALSE; + unsigned long bar_addr_orig = 0; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_pci_setup" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Make sure the device pointer is valid + *************************************************************************/ + if( pdev == NULL ) + { + DBG_ERROR( et131x_dbginfo, + "PCI subsys passed in an invalid pci_dev pointer\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -ENODEV; + } + + + /************************************************************************** + On some systems, the base address for a PCI device's config space which + is stored in the pci_dev structure is incorrect and different from + what's actually in the config space. If they're different, workaround + the issue by correcting the address. + *************************************************************************/ + pci_read_config_dword( pdev, PCI_BASE_ADDRESS_0, (u32 *)&et131x_reg_base ); + et131x_reg_base &= ~0x07; + + if( (u32)pdev->resource[0].start != (u32)et131x_reg_base ) + { + DBG_WARNING( et131x_dbginfo, "PCI CONFIG SPACE WORKAROUND REQUIRED\n" ); + DBG_WARNING( et131x_dbginfo, "pdev->resource[0].start : 0x%08x\n", + (unsigned int)pdev->resource[0].start ); + DBG_WARNING( et131x_dbginfo, "et131x_reg_base : 0x%08x\n", + (unsigned int)et131x_reg_base ); + bar_workaround = TRUE; + bar_addr_orig = pdev->resource[0].start; + pdev->resource[0].start = et131x_reg_base; + } + + + /************************************************************************** + Enable the device via the PCI subsystem + *************************************************************************/ + result = pci_enable_device( pdev ); + if( result != 0 ) + { + if( bar_workaround ) + { + pdev->resource[0].start = bar_addr_orig; + } + + DBG_ERROR( et131x_dbginfo, "pci_enable_device() failed\n" ); + DBG_LEAVE( et131x_dbginfo ); + return result; + } + + + /************************************************************************** + Perform some basic PCI checks + *************************************************************************/ + if( !( pci_resource_flags( pdev, 0 ) & IORESOURCE_MEM )) + { + if( bar_workaround ) + { + pdev->resource[0].start = bar_addr_orig; + } + + DBG_ERROR( et131x_dbginfo, + "Can't find PCI device's base address\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -ENODEV; + } + + if( bar_workaround == FALSE ) + { + result = pci_request_regions( pdev, DRIVER_NAME ); + if( result != 0 ) + { + DBG_ERROR( et131x_dbginfo, + "Can't get PCI resources\n" ); + + pci_disable_device( pdev ); + + DBG_LEAVE( et131x_dbginfo ); + return result; + } + } + + + /************************************************************************** + Enable PCI bus mastering + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Setting PCI Bus Mastering...\n" ); + pci_set_master( pdev ); + + + /************************************************************************** + Query PCI for Power Mgmt Capabilities + + NOTE: Now reading PowerMgmt in another location; is this still needed? + *************************************************************************/ + pm_cap = pci_find_capability( pdev, PCI_CAP_ID_PM ); + if( pm_cap == 0 ) + { + DBG_ERROR( et131x_dbginfo, + "Cannot find Power Management capabilities\n" ); + + if( bar_workaround == FALSE ) + { + pci_release_regions( pdev ); + } + else + { + pdev->resource[0].start = bar_addr_orig; + } + + pci_disable_device( pdev ); + + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + + + /************************************************************************** + Check the DMA addressing support of this device + *************************************************************************/ + if( !pci_set_dma_mask( pdev, 0xffffffffffffffffULL )) + { + DBG_TRACE( et131x_dbginfo, + "64-bit DMA addressing supported\n" ); + pci_using_dac = TRUE; + +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION( 2,6,0 )) + result = pci_set_consistent_dma_mask( pdev, 0xffffffffffffffffULL ); + if( result != 0 ) + { + DBG_ERROR( et131x_dbginfo, + "Unable to obtain 64 bit DMA for consistent allocations\n" ); + if( bar_workaround == FALSE ) + { + pci_release_regions( pdev ); + } + else + { + pdev->resource[0].start = bar_addr_orig; + } + + pci_disable_device( pdev ); + + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } +#endif + } + else if( !pci_set_dma_mask( pdev, 0xffffffffULL )) + { + DBG_TRACE( et131x_dbginfo, + "64-bit DMA addressing NOT supported\n" ); + DBG_TRACE( et131x_dbginfo, + "32-bit DMA addressing will be used\n" ); + pci_using_dac = FALSE; + } + else + { + DBG_ERROR( et131x_dbginfo, "No usable DMA addressing method\n" ); + + if( bar_workaround == FALSE ) + { + pci_release_regions( pdev ); + } + else + { + pdev->resource[0].start = bar_addr_orig; + } + + pci_disable_device( pdev ); + + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + + + /************************************************************************** + Allocate netdev and private adapter structs + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Allocate netdev and private adapter structs...\n" ); + netdev = et131x_device_alloc( ); + + if( netdev == NULL ) + { + DBG_ERROR( et131x_dbginfo, "Couldn't alloc netdev struct\n" ); + + if( bar_workaround == FALSE ) + { + pci_release_regions( pdev ); + } + else + { + pdev->resource[0].start = bar_addr_orig; + } + + pci_disable_device( pdev ); + + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + + /************************************************************************** + Setup the fundamental net_device and private adapter structure elements + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Setting fundamental net_device info...\n" ); + + #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + SET_MODULE_OWNER( netdev ); + #endif + #if ( LINUX_VERSION_CODE > KERNEL_VERSION(2,6,20)) + SET_NETDEV_DEV( netdev, &pdev->dev ); + #endif + if( pci_using_dac ) + { + //netdev->features |= NETIF_F_HIGHDMA; + } + + + /************************************************************************** + NOTE - Turn this on when we're ready to deal with SG-DMA + + NOTE: According to "Linux Device Drivers", 3rd ed, Rubini et al, if + checksumming is not performed in HW, then the kernel will not use SG. + From pp 510-511: + + "Note that the kernel does not perform scatter/gather I/O to your device + if it does not also provide some form of checksumming as well. The + reason is that, if the kernel has to make a pass over a fragmented + ("nonlinear") packet to calculate the checksum, it might as well copy + the data and coalesce the packet at the same time." + + This has been verified by setting the flags below and still not + receiving a scattered buffer from the network stack, so leave it off + until checksums are calculated in HW. + *************************************************************************/ + //netdev->features |= NETIF_F_SG; + //netdev->features |= NETIF_F_NO_CSUM; + +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION( 2,6,0 )) + //netdev->features |= NETIF_F_LLTX; +#endif + +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) + /************************************************************************** + The ET1310 does not perform VLAN tagging in hardware, so these flags are + not set. + *************************************************************************/ + /* + netdev->features |= NETIF_F_HW_VLAN_TX | + NETIF_F_HW_VLAN_RX | + NETIF_F_HW_VLAN_FILTER; + */ +#endif + + /************************************************************************** + Allocate private adapter struct and copy in relevant information + *************************************************************************/ + adapter = netdev_priv( netdev ); + adapter->pdev = pdev; + adapter->netdev = netdev; + adapter->VendorID = pdev->vendor; + adapter->DeviceID = pdev->device; + + adapter->pci_bar_workaround = bar_workaround; + adapter->pci_bar_addr_orig = bar_addr_orig; + + + /************************************************************************** + Do the same for the netdev struct + *************************************************************************/ + netdev->irq = pdev->irq; + netdev->base_addr = pdev->resource[0].start; + + + /************************************************************************** + Initialize spinlocks here + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Initialize spinlocks...\n" ); + + spin_lock_init( &adapter->Lock ); + spin_lock_init( &adapter->TCBSendQLock ); + spin_lock_init( &adapter->TCBReadyQLock ); + spin_lock_init( &adapter->SendHWLock ); + spin_lock_init( &adapter->SendWaitLock ); + spin_lock_init( &adapter->RcvLock ); + spin_lock_init( &adapter->RcvPendLock ); + spin_lock_init( &adapter->FbrLock ); + spin_lock_init( &adapter->PHYLock ); + + + /************************************************************************** + Parse configuration parameters into the private adapter struct + *************************************************************************/ + et131x_config_parse( adapter ); + + + /************************************************************************** + Find the physical adapter + + NOTE: This is the equivalent of the MpFindAdapter() routine; can we + lump it's init with the device specific init below into a single + init function? + *************************************************************************/ + //while(et131x_find_adapter( adapter, pdev ) != 0); + et131x_find_adapter( adapter, pdev ); + + /************************************************************************** + Map the bus-relative registers to system virtual memory + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Mapping bus-relative registers to virtual memory...\n" ); + + if( bar_workaround == FALSE ) + { + et131x_reg_base = pci_resource_start( pdev, 0 ); + et131x_reg_len = pci_resource_len( pdev, 0 ); + } + else + { + et131x_reg_len = 0x00200000; + } + + adapter->CSRAddress = (ADDRESS_MAP_t *)ioremap_nocache( et131x_reg_base, + et131x_reg_len ); + if( adapter->CSRAddress == NULL ) + { + DBG_ERROR( et131x_dbginfo, "Cannot map device registers\n" ); + + et131x_device_free( netdev ); + + if( bar_workaround == FALSE ) + { + pci_release_regions( pdev ); + } + else + { + pdev->resource[0].start = bar_addr_orig; + } + + pci_disable_device( pdev ); + + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + + /************************************************************************** + Perform device-specific initialization here (See code below) + *************************************************************************/ + + /************************************************************************** + If Phy COMA mode was enabled when we went down, disable it here. + *************************************************************************/ + { + PM_CSR_t GlobalPmCSR = {0}; + + GlobalPmCSR.bits.pm_sysclk_gate = 1; + GlobalPmCSR.bits.pm_txclk_gate = 1; + GlobalPmCSR.bits.pm_rxclk_gate = 1; + + adapter->CSRAddress->global.pm_csr = GlobalPmCSR; + } + + + /************************************************************************** + Issue a global reset to the et1310 + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Issuing soft reset...\n" ); + et131x_soft_reset( adapter ); + + + /************************************************************************** + Disable all interrupts (paranoid) + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Disable device interrupts...\n" ); + et131x_disable_interrupts( adapter ); + + + /************************************************************************** + Allocate DMA memory + *************************************************************************/ + result = et131x_adapter_memory_alloc( adapter ); + if( result != 0 ) + { + DBG_ERROR( et131x_dbginfo, + "Could not alloc adapater memory (DMA)\n" ); + + iounmap( (void *)adapter->CSRAddress ); + + et131x_device_free( netdev ); + + if( bar_workaround == FALSE ) + { + pci_release_regions( pdev ); + } + else + { + pdev->resource[0].start = bar_addr_orig; + } + + pci_disable_device( pdev ); + + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + + /************************************************************************** + Init send data structures + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Init send data structures...\n" ); + et131x_init_send( adapter ); + + adapter->PoMgmt.PowerState = NdisDeviceStateD0; + + + /************************************************************************** + Register the interrupt + + NOTE - This is being done in the open routine, where most other Linux + drivers setup IRQ handlers. Make sure device interrupts are not + turned on before the IRQ is registered!!!! + + What we will do here is setup the task structure for the ISR's + deferred handler + *************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) + adapter->task.routine = (void (*)(void *))et131x_isr_handler; + adapter->task.data = adapter; +#else + INIT_WORK( &adapter->task, et131x_isr_handler ); +#endif + + + /************************************************************************** + Determine MAC Address, and copy into the net_device struct + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Retrieve MAC address...\n" ); + et131x_setup_hardware_properties( adapter ); + + memcpy( netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN ); + + + /************************************************************************** + Setup up our lookup table for CRC Calculations + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Setup CRC lookup table...\n" ); + et131x_init_enet_crc_calc( ); + + + /************************************************************************** + Setup et1310 as per the documentation + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Setup the adapter...\n" ); + et131x_adapter_setup( adapter ); + + + /************************************************************************** + Create a timer to count errors received by the NIC + *************************************************************************/ + init_timer( &adapter->ErrorTimer ); + + adapter->ErrorTimer.expires = jiffies + TX_ERROR_PERIOD * HZ / 1000; + adapter->ErrorTimer.function = et131x_error_timer_handler; + adapter->ErrorTimer.data = (unsigned long)adapter; + + + /************************************************************************** + Initialize link state + *************************************************************************/ + et131x_link_detection_handler( (unsigned long)adapter ); + + + /************************************************************************** + Intialize variable for counting how long we do not have link status + *************************************************************************/ + adapter->PoMgmt.TransPhyComaModeOnBoot = 0; + + + /************************************************************************** + We can enable interrupts now + + NOTE - Because registration of interrupt handler is done in the device's + open(), defer enabling device interrupts to that point + *************************************************************************/ + + + /************************************************************************** + Register the net_device struct with the Linux network layer + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Registering net_device...\n" ); + + + if(( result = register_netdev( netdev )) != 0 ) + { + DBG_ERROR( et131x_dbginfo, "register_netdev() failed\n" ); + + et131x_adapter_memory_free( adapter ); + + iounmap( (void *)adapter->CSRAddress ); + + et131x_device_free( netdev ); + + if( bar_workaround == FALSE ) + { + pci_release_regions( pdev ); + } + else + { + pdev->resource[0].start = bar_addr_orig; + } + + pci_disable_device( pdev ); + + DBG_LEAVE( et131x_dbginfo ); + return result; + } + + + /************************************************************************** + Register the net_device struct with the PCI subsystem. Save a copy + of the PCI config space for this device now that the device has been + initialized, just in case it needs to be quickly restored. + *************************************************************************/ + pci_set_drvdata( pdev, netdev ); + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,10 )) + pci_save_state( adapter->pdev, adapter->pci_cfg_state); +#else + pci_save_state( adapter->pdev ); +#endif + + + /************************************************************************** + Print out some information about this device + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, + "DEVICE FOUND\n" ); + DBG_TRACE( et131x_dbginfo, + "------------------------------\n" ); + DBG_TRACE( et131x_dbginfo, + "Device Vendor ID : 0x%04x\n", + pdev->vendor ); + DBG_TRACE( et131x_dbginfo, + "Device Product ID : 0x%04x\n", + pdev->device ); + DBG_TRACE( et131x_dbginfo, + "Device SubVendor ID : 0x%04x\n", + pdev->subsystem_vendor ); + DBG_TRACE( et131x_dbginfo, + "Device SubProduct ID : 0x%04x\n", + pdev->subsystem_device ); + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) + DBG_TRACE( et131x_dbginfo, + "Device Name : %s\n", + pdev->name ); +#endif + + DBG_TRACE( et131x_dbginfo, + "Device on Bus # : %d\n", + pdev->bus->number ); + DBG_TRACE( et131x_dbginfo, + " Bus Name : %s\n", + pdev->bus->name ); + DBG_TRACE( et131x_dbginfo, + "Device in Slot # : %d\n", + PCI_SLOT( pdev->devfn )); + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,11 )) + DBG_TRACE( et131x_dbginfo, + " Slot Name : %s\n", + pdev->slot_name ); +#endif + + DBG_TRACE( et131x_dbginfo, + "Device Base Address : 0x%#03lx\n", + netdev->base_addr ); + DBG_TRACE( et131x_dbginfo, + "Device IRQ : %d\n", + netdev->irq ); + DBG_TRACE( et131x_dbginfo, + "Device MAC Address : %02x:%02x:%02x:%02x:%02x:%02x\n", + adapter->CurrentAddress[0], adapter->CurrentAddress[1], + adapter->CurrentAddress[2], adapter->CurrentAddress[3], + adapter->CurrentAddress[4], adapter->CurrentAddress[5] ); + + + DBG_LEAVE( et131x_dbginfo ); + return 0; +} +/*===========================================================================*/ --- linux-2.6.28.orig/ubuntu/et131x/et131x_debug.c +++ linux-2.6.28/ubuntu/et131x/et131x_debug.c @@ -0,0 +1,328 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_debug.c - Routines used for debugging. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/08/01 19:35:12 $ + $Revision: 1.6 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifdef ET131X_DBG + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" +#include "et131x_netdev.h" +#include "et131x_config.h" +#include "et131x_isr.h" + +#include "ET1310_address_map.h" +#include "ET1310_jagcore.h" +#include "ET1310_tx.h" +#include "ET1310_rx.h" +#include "ET1310_mac.h" + + + + +/****************************************************************************** + Data for debugging facilities + *****************************************************************************/ +extern dbg_info_t *et131x_dbginfo; + + + + +/****************************************************************************** + ROUTINE: DumpTxQueueContents + ****************************************************************************** + DESCRIPTION: + Used to dump out hte tx queue and the shadow pointers + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void DumpTxQueueContents( int dbgLvl, ET131X_ADAPTER *pAdapter ) +{ + UINT32 TxQueueAddr; + /*-----------------------------------------------------------------------*/ + + + if( DBG_FLAGS( et131x_dbginfo ) & dbgLvl ) + { + + for( TxQueueAddr = 0x200; TxQueueAddr< 0x3ff; TxQueueAddr++ ) + { + pAdapter->CSRAddress->mmc.sram_access.bits.req_addr = TxQueueAddr; + pAdapter->CSRAddress->mmc.sram_access.bits.req_access = 1; + + + DBG_PRINT( "Addr 0x%x, Access 0x%08x\t" + "Value 1 0x%08x, Value 2 0x%08x, " + "Value 3 0x%08x, Value 4 0x%08x, \n", + TxQueueAddr, + pAdapter->CSRAddress->mmc.sram_access.value, + pAdapter->CSRAddress->mmc.sram_word1.data, + pAdapter->CSRAddress->mmc.sram_word2.data, + pAdapter->CSRAddress->mmc.sram_word3.data, + pAdapter->CSRAddress->mmc.sram_word4.data ); + + } + + DBG_PRINT( "Shadow Pointers 0x%08x\n", + pAdapter->CSRAddress->txmac.shadow_ptr.value ); + } + + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: DumpDeviceBlock + ****************************************************************************** + + DESCRIPTION: + Dumps the first 64 regs of each block of the et-1310 (each block is + mapped to a new page, each page is 4096 bytes). + + PARAMETERS : + pAdapter - pointer to our adapter + + RETURN : + VOID + *****************************************************************************/ +#define NUM_BLOCKS 8 +void DumpDeviceBlock( int dbgLvl, ET131X_ADAPTER *pAdapter, UINT32 Block ) +{ + UINT32 Address1, Address2; + UINT32 *BigDevicePointer = (UINT32 *)pAdapter->CSRAddress; + /*-----------------------------------------------------------------------*/ + + + char* BlockNames[NUM_BLOCKS] = + {"Global", "Tx DMA", "Rx DMA", "Tx MAC", + "Rx MAC", "MAC", "MAC Stat", "MMC" }; + /*-----------------------------------------------------------------------*/ + + + /************************************************************************** + Output the debug counters to the debug terminal + *************************************************************************/ + if( DBG_FLAGS( et131x_dbginfo ) & dbgLvl ) + { + DBG_PRINT( "%s block\n", BlockNames[Block] ); + + for( Address1 = 0; Address1 < 8; Address1++ ) + { + for( Address2 = 0; Address2 < 8; Address2++ ) + { + if( Block == 0 ) + { + if((( Address1 * 8 ) + Address2 ) == 6 ) + { + DBG_PRINT( " ISR , " ); + } + else + { + DBG_PRINT( "0x%08x, ", + BigDevicePointer[( Block * 1024 ) + + ( Address1 * 8 ) + Address2] ); + + } + } + else + { + DBG_PRINT( "0x%08x, ", + BigDevicePointer[( Block * 1024 ) + + ( Address1 * 8 ) + Address2] ); + } + } + + DBG_PRINT( "\n" ); + } + + DBG_PRINT( "\n" ); + } + + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: DumpDeviceReg + ****************************************************************************** + + DESCRIPTION: + Dumps the first 64 regs of each block of the et-1310 (each block is + mapped to a new page, each page is 4096 bytes). + + PARAMETERS : + pAdapter - pointer to our adapter + + RETURN : + VOID + *****************************************************************************/ +void DumpDeviceReg( int dbgLvl, ET131X_ADAPTER *pAdapter ) +{ + UINT32 Address1, Address2; + UINT32 Block; + UINT32 *BigDevicePointer = (UINT32 *)pAdapter->CSRAddress; + + char* BlockNames[NUM_BLOCKS] = + {"Global", "Tx DMA", "Rx DMA", "Tx MAC", + "Rx MAC", "MAC", "MAC Stat", "MMC" }; + /*-----------------------------------------------------------------------*/ + + + /************************************************************************** + Output the debug counters to the debug terminal + *************************************************************************/ + if( DBG_FLAGS( et131x_dbginfo ) & dbgLvl ) + { + for( Block = 0; Block < NUM_BLOCKS; Block++ ) + { + DBG_PRINT( "%s block\n", BlockNames[Block] ); + + for( Address1 = 0; Address1 < 8; Address1++ ) + { + for( Address2 = 0; Address2 < 8; Address2++ ) + { + DBG_PRINT( "0x%08x, ", + BigDevicePointer[( Block * 1024 ) + + ( Address1 * 8 ) + Address2] ); + } + + DBG_PRINT( "\n" ); + } + + DBG_PRINT( "\n" ); + } + } + + return; +} +/*==========================================================================*/ + + + + +#endif // ET131X_DBG --- linux-2.6.28.orig/ubuntu/et131x/et131x_initpci.h +++ linux-2.6.28/ubuntu/et131x/et131x_initpci.h @@ -0,0 +1,103 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_initpci.h - Header which includes common data and function prototypes + * related to the driver's PCI (and PCI Express) information. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/10/28 17:31:23 $ + $Revision: 1.4 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET131X_INITPCI_H__ +#define __ET131X_INITPCI_H__ + + + + +/****************************************************************************** + Function Prototypes + *****************************************************************************/ +int et131x_pci_register( void ); +void et131x_pci_unregister( void ); + +void et131x_align_allocated_memory( ET131X_ADAPTER *adapter, + UINT64 *phys_addr, + UINT64 *offset, + UINT64 mask ); + + + + +int et131x_adapter_setup( ET131X_ADAPTER *pAdapter ); +int et131x_adapter_memory_alloc( ET131X_ADAPTER *adapter ); +void et131x_adapter_memory_free( ET131X_ADAPTER *adapter ); +void et131x_setup_hardware_properties( ET131X_ADAPTER *adapter ); +void et131x_soft_reset( ET131X_ADAPTER *adapter ); + +#endif /* __ET131X_INITPCI_H__ */ --- linux-2.6.28.orig/ubuntu/et131x/ET1310_jagcore.c +++ linux-2.6.28/ubuntu/et131x/ET1310_jagcore.c @@ -0,0 +1,642 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_jagcore.c - All code pertaining to the ET1301/ET131x's JAGcore + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/10/28 18:43:44 $ + $Revision: 1.9 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" +#include "et131x_initpci.h" + + + + +/****************************************************************************** + Data for debugging facilities + *****************************************************************************/ +#ifdef ET131X_DBG +extern dbg_info_t *et131x_dbginfo; +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + ROUTINE: ConfigGlobalRegs + ****************************************************************************** + + DESCRIPTION: + Used to configure the global registers on the JAGCore + + PARAMETERS : + pAdpater - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void ConfigGlobalRegs( ET131X_ADAPTER *pAdapter ) +{ + PGLOBAL_t pGbl; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "ConfigGlobalRegs" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Map a local pointer to the global section of the JAGCore + *************************************************************************/ + pGbl = &pAdapter->CSRAddress->global; + + if( pAdapter->RegistryPhyLoopbk == FALSE ) + { + if( pAdapter->RegistryJumboPacket < 2048 ) + { + /****************************************************************** + Tx / RxDMA and Tx/Rx MAC interfaces have a 1k word block of RAM + that the driver can split between Tx and Rx as it desires. Our + default is to split it 50/50: + *****************************************************************/ + pGbl->rxq_start_addr.value = 0; + pGbl->rxq_end_addr.value = pAdapter->RegistryRxMemEnd; + pGbl->txq_start_addr.value = pGbl->rxq_end_addr.bits.rxq_end_addr + 1; + pGbl->txq_end_addr.value = INTERNAL_MEM_SIZE - 1; + } + else if( pAdapter->RegistryJumboPacket < 8192 ) + { + /****************************************************************** + For jumbo packets > 2k in length, but < 8k, split 50-50. + *****************************************************************/ + pGbl->rxq_start_addr.value = 0; + pGbl->rxq_end_addr.value = INTERNAL_MEM_RX_OFFSET; + pGbl->txq_start_addr.value = INTERNAL_MEM_RX_OFFSET + 1; + pGbl->txq_end_addr.value = INTERNAL_MEM_SIZE - 1; + } + else + { + /****************************************************************** + 9216 is the only packet size greater than 8k that is available. + The Tx buffer has to be big enough for one whole packet on the + Tx side. We'll make the Tx 9408, and give the rest to Rx + *****************************************************************/ + pGbl->rxq_start_addr.value = 0x0000; + pGbl->rxq_end_addr.value = 0x01b3; + pGbl->txq_start_addr.value = 0x01b4; + pGbl->txq_end_addr.value = INTERNAL_MEM_SIZE - 1; + } + + /********************************************************************** + Initialize the loopback register. Disable all loopbacks. + *********************************************************************/ + pGbl->loopback.value = 0x0; + } + else + { + /************************************************************************** + For PHY Line loopback, the memory is configured as if Tx and Rx both + have all the memory. This is because the RxMAC will write data into + the space, and the TxMAC will read it out. + *************************************************************************/ + pGbl->rxq_start_addr.value = 0; + pGbl->rxq_end_addr.value = INTERNAL_MEM_SIZE - 1; + pGbl->txq_start_addr.value = 0; + pGbl->txq_end_addr.value = INTERNAL_MEM_SIZE - 1; + + /************************************************************************** + Initialize the loopback register (MAC loopback). + *************************************************************************/ + pGbl->loopback.value = 0x1; + } + + /************************************************************************** + MSI Register + *************************************************************************/ + pGbl->msi_config.value = 0x0; + + + /************************************************************************** + By default, disable the watchdog timer. It will be enabled when + a packet is queued. + *************************************************************************/ + pGbl->watchdog_timer = 0; + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: ConfigMMCRegs + ****************************************************************************** + + DESCRIPTION: + Used to configure the main memory registers in the JAGCore + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void ConfigMMCRegs( ET131X_ADAPTER *pAdapter ) +{ + MMC_CTRL_t mmc_ctrl = {0}; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "ConfigMMCRegs" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + All we need to do is initialize the Memory Control Register + *************************************************************************/ + mmc_ctrl.bits.force_ce = 0x0; + mmc_ctrl.bits.rxdma_disable = 0x0; + mmc_ctrl.bits.txdma_disable = 0x0; + mmc_ctrl.bits.txmac_disable = 0x0; + mmc_ctrl.bits.rxmac_disable = 0x0; + mmc_ctrl.bits.arb_disable = 0x0; + mmc_ctrl.bits.mmc_enable = 0x1; + + pAdapter->CSRAddress->mmc.mmc_ctrl.value = mmc_ctrl.value; + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_enable_interrupts + ****************************************************************************** + + DESCRIPTION : Enable interupts on the ET131x + + PARAMETERS : adapter - a pointer to our private adapter structure + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_enable_interrupts( ET131X_ADAPTER *adapter ) +{ + UINT32 MaskValue; + + + /************************************************************************** + Enable all global interrupts + *************************************************************************/ + if(( adapter->FlowControl == TxOnly ) || + ( adapter->FlowControl == Both )) + { + MaskValue = INT_MASK_ENABLE; + } + else + { + MaskValue = INT_MASK_ENABLE_NO_FLOW; + } + + if( adapter->DriverNoPhyAccess ) + { + MaskValue |= 0x10000; + } + + adapter->CachedMaskValue.value = MaskValue; + adapter->CSRAddress->global.int_mask.value = MaskValue; + + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_disable_interrupts + ****************************************************************************** + + DESCRIPTION : Enable interrupts on the ET131x + + PARAMETERS : adapter - a pointer to our private adapter structure + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ + +void et131x_disable_interrupts( ET131X_ADAPTER *adapter ) +{ + /************************************************************************** + Disable all global interrupts + *************************************************************************/ + adapter->CachedMaskValue.value = INT_MASK_DISABLE; + adapter->CSRAddress->global.int_mask.value = INT_MASK_DISABLE; + + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: NICGetRegs + ****************************************************************************** + + DESCRIPTION: + function used to get register data + + PARAMETERS : + pAdapter - pointer to our adapter structure + InfoBuf - pointer to data struct containing registers to get + ulBytesAvailable - + ulInfoLen - + + RETURN : + NONE + + *****************************************************************************/ +void * et131x_get_regs( ET131X_ADAPTER *pAdapter, void *InfoBuf, + PUINT32 ulBytesAvailable, PUINT32 ulInfoLen ) +{ + INT32 nRegCount; + PINT8 pJCBase; + INT32 x; + PUINT32 pReg; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_get_regs" ); + DBG_ENTER( et131x_dbginfo ); + + + memset( (void *)&pAdapter->JagCoreRegs, 0, sizeof( JAGCORE_ACCESS_REGS )); + + + /************************************************************************** + Get the user supplied data + *************************************************************************/ + pAdapter->JagCoreRegs = *(PJAGCORE_ACCESS_REGS)InfoBuf; + nRegCount = pAdapter->JagCoreRegs.nRegCount; + + pJCBase = (PINT8)&pAdapter->CSRAddress->global; + + for( x = 0; x < nRegCount; x++ ) + { + pReg = (PUINT32)( pJCBase+pAdapter->JagCoreRegs.nOffsets[x] ); + + pAdapter->JagCoreRegs.nData[x] = *pReg; + } + + *ulBytesAvailable = sizeof( JAGCORE_ACCESS_REGS ); + *ulInfoLen = sizeof( JAGCORE_ACCESS_REGS ); + + + DBG_LEAVE( et131x_dbginfo ); + return( (void *)&pAdapter->JagCoreRegs ); +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_set_regs + ****************************************************************************** + + DESCRIPTION: + function used to set register data + + PARAMETERS : + pAdapter - pointer to our adapter structure + InfoBuf - pointer to data struct containing register offset and data + to set + RETURN : + N/A + + *****************************************************************************/ +void et131x_set_regs( ET131X_ADAPTER *pAdapter, void *InfoBuf ) +{ + INT32 nRegCount; + PINT8 pJCBase; + INT32 x; + PUINT32 pReg; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_set_regs" ); + DBG_ENTER( et131x_dbginfo ); + + + memset( (void *)&pAdapter->JagCoreRegs, 0, sizeof( JAGCORE_ACCESS_REGS )); + + + /************************************************************************** + Get the user supplied data + *************************************************************************/ + pAdapter->JagCoreRegs = *(PJAGCORE_ACCESS_REGS)InfoBuf; + + nRegCount = pAdapter->JagCoreRegs.nRegCount; + + pJCBase = (PINT8)&pAdapter->CSRAddress->global; + + for( x = 0; x < nRegCount; x++ ) + { + pReg = (PUINT32)(pJCBase+pAdapter->JagCoreRegs.nOffsets[x]); + *pReg = pAdapter->JagCoreRegs.nData[x]; + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: GetPciCfgRegs + ****************************************************************************** + + DESCRIPTION: + function used to get register data + + PARAMETERS : + pAdapter - pointer to our adapter structure + InfoBuf - pointer to data struct containing registers to get + ulBytesAvailable - + ulInfoLen - + + RETURN : + NONE + + *****************************************************************************/ +void * GetPciCfgRegs( ET131X_ADAPTER *pAdapter, void * InfoBuf, + PUINT32 ulBytesAvailable, PUINT32 ulInfoLen ) +{ + INT32 nRegCount; + UINT32 ByteLength = 0; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "GetPciCfgRegs" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Get the user supplied data + *************************************************************************/ + pAdapter->PciCfgRegs = *(PPCI_CFG_SPACE_REGS)InfoBuf; + nRegCount = pAdapter->PciCfgRegs.nRegCount; + + + /************************************************************************** + Support for 8,16,32 bit widths + *************************************************************************/ + ByteLength = pAdapter->PciCfgRegs.nDataWidth/8; + + pci_slot_information_read( pAdapter->pdev, + pAdapter->PciCfgRegs.nOffsets[0], + (UINT8 *)&pAdapter->PciCfgRegs.nData, + ByteLength * nRegCount ); + + *ulBytesAvailable = sizeof( PCI_CFG_SPACE_REGS ); + *ulInfoLen = sizeof( PCI_CFG_SPACE_REGS ); + + + DBG_LEAVE( et131x_dbginfo ); + return( (void *)&pAdapter->PciCfgRegs ); +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: SetPciCfgRegs + ****************************************************************************** + + DESCRIPTION: + function used to set register data + + PARAMETERS : + pAdapter - pointer to our adapter structure + InfoBuf - pointer to data struct containing register offset and data + to set + RETURN : + N/A + + *****************************************************************************/ +void SetPciCfgRegs( ET131X_ADAPTER *pAdapter, void * InfoBuf ) +{ + INT32 nRegCount; + INT32 x; + UINT32 ByteLength = 0; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "SetPciCfgRegs" ); + DBG_ENTER( et131x_dbginfo ); + + + memset( (void *)&pAdapter->PciCfgRegs, 0, sizeof( PCI_CFG_SPACE_REGS )); + + + /************************************************************************** + Get the user supplied data + *************************************************************************/ + pAdapter->PciCfgRegs = *(PPCI_CFG_SPACE_REGS)InfoBuf; + + nRegCount = pAdapter->PciCfgRegs.nRegCount; + ByteLength = pAdapter->PciCfgRegs.nDataWidth/8; + + for( x = 0; x < nRegCount; x++ ) + { + pci_slot_information_write( pAdapter->pdev, + pAdapter->PciCfgRegs.nOffsets[x], + (UINT8 *)&pAdapter->PciCfgRegs.nData[x * ByteLength], + ByteLength ); + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: MemTest + ****************************************************************************** + + DESCRIPTION: + function used to test rx/tx queue memory at 0x0 and 0x200 + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURN : + TRUE or FALSE + + *****************************************************************************/ +BOOL_t MemTest( ET131X_ADAPTER *pAdapter, UINT32 addr ) +{ + UINT32 data; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "MemTest" ); + DBG_ENTER( et131x_dbginfo ); + + + // Read initial value + pAdapter->CSRAddress->mmc.sram_access.value = 1; + data = pAdapter->CSRAddress->mmc.sram_word1.data; + + + // Write test value + pAdapter->CSRAddress->mmc.sram_word1.data = 0xdeadbeef; + pAdapter->CSRAddress->mmc.sram_access.value = 0xf003; + + + // Read back test value + pAdapter->CSRAddress->mmc.sram_access.bits.req_access = 1; + if ( pAdapter->CSRAddress->mmc.sram_word1.data != 0xdeadbeef ) + { + DBG_LEAVE( et131x_dbginfo ); + return FALSE; + } + + // Restore initial value + pAdapter->CSRAddress->mmc.sram_word1.data = data; + pAdapter->CSRAddress->mmc.sram_access.value = 0xf003; + + + DBG_LEAVE( et131x_dbginfo ); + return TRUE; +} +/*===========================================================================*/ --- linux-2.6.28.orig/ubuntu/et131x/Makefile +++ linux-2.6.28/ubuntu/et131x/Makefile @@ -0,0 +1,6 @@ +obj-$(CONFIG_NET_ET131X) += et131x.o + +et131x-objs += et131x_main.o et131x_initpci.o et131x_isr.o et131x_netdev.o \ + et131x_supp.o et131x_config.o et131x_debug.o ET1310_jagcore.o \ + ET1310_tx.o ET1310_rx.o ET1310_phy.o ET1310_mac.o ET1310_pm.o \ + ET1310_eeprom.o --- linux-2.6.28.orig/ubuntu/et131x/et131x_debug.h +++ linux-2.6.28/ubuntu/et131x/et131x_debug.h @@ -0,0 +1,267 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_debug.h - Defines, structs, enums, prototypes, etc. used for + * outputting debug messages to the system logging facility + * (ksyslogd) + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/08/01 19:35:12 $ + $Revision: 1.10 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET131X_DBG_H__ +#define __ET131X_DBG_H__ + + + + +/****************************************************************************** + Define Masks for debugging types/levels + *****************************************************************************/ +#define DBG_ERROR_ON 0x00000001L +#define DBG_WARNING_ON 0x00000002L +#define DBG_NOTICE_ON 0x00000004L +#define DBG_TRACE_ON 0x00000008L +#define DBG_VERBOSE_ON 0x00000010L +#define DBG_PARAM_ON 0x00000020L +#define DBG_BREAK_ON 0x00000040L +#define DBG_RX_ON 0x00000100L +#define DBG_TX_ON 0x00000200L + + + + +#ifdef ET131X_DBG + + +/****************************************************************************** + Set the level of debugging if not done with a preprocessor define. See + et131x_main.c, function et131x_init_module() for how the debug level + translates into the types of messages displayed. + *****************************************************************************/ +#ifndef DBG_LVL +#define DBG_LVL 3 +#endif /* DBG_LVL */ + + +#define DBG_DEFAULTS (DBG_ERROR_ON | DBG_WARNING_ON | DBG_BREAK_ON ) + +#define DBG_FLAGS(A) (A)->dbgFlags +#define DBG_NAME(A) (A)->dbgName +#define DBG_LEVEL(A) (A)->dbgLevel + + +#ifndef PRINTK +# define PRINTK(S...) printk(S) +#endif /* PRINTK */ + + +#ifndef DBG_PRINT +# define DBG_PRINT(S...) PRINTK(KERN_DEBUG S) +#endif /* DBG_PRINT */ + + +#ifndef DBG_PRINTC +# define DBG_PRINTC(S...) PRINTK(S) +#endif /* DBG_PRINTC */ + + +#ifndef DBG_TRAP +# define DBG_TRAP {} //BUG() +#endif /* DBG_TRAP */ + + +#define _ENTER_STR ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" +#define _LEAVE_STR "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" + + +#define _DBG_ENTER(A) DBG_PRINT("%s:%.*s:%s\n",DBG_NAME(A),++DBG_LEVEL(A),_ENTER_STR,__FUNC__) +#define _DBG_LEAVE(A) DBG_PRINT("%s:%.*s:%s\n",DBG_NAME(A),DBG_LEVEL(A)--,_LEAVE_STR,__FUNC__) + + +#define DBG_FUNC(F) static const char __FUNC__[] = F; + + +#define DBG_ENTER(A) {if (DBG_FLAGS(A) & DBG_TRACE_ON) \ + _DBG_ENTER(A);} + + +#define DBG_LEAVE(A) {if (DBG_FLAGS(A) & DBG_TRACE_ON) \ + _DBG_LEAVE(A);} + + +#define DBG_PARAM(A,N,F,S...) {if (DBG_FLAGS(A) & DBG_PARAM_ON) \ + DBG_PRINT(" %s -- "F"\n",N,S);} + + +#define DBG_ERROR(A,S...) {if (DBG_FLAGS(A) & DBG_ERROR_ON) \ + {DBG_PRINT("%s:ERROR:%s ",DBG_NAME(A),__FUNC__);DBG_PRINTC(S);DBG_TRAP;}} + + +#define DBG_WARNING(A,S...) {if (DBG_FLAGS(A) & DBG_WARNING_ON) \ + {DBG_PRINT("%s:WARNING:%s ",DBG_NAME(A),__FUNC__);DBG_PRINTC(S);}} + + +#define DBG_NOTICE(A,S...) {if (DBG_FLAGS(A) & DBG_NOTICE_ON) \ + {DBG_PRINT("%s:NOTICE:%s ",DBG_NAME(A),__FUNC__);DBG_PRINTC(S);}} + + +#define DBG_TRACE(A,S...) {if (DBG_FLAGS(A) & DBG_TRACE_ON) \ + {DBG_PRINT("%s:TRACE:%s ",DBG_NAME(A),__FUNC__);DBG_PRINTC(S);}} + +#define DBG_VERBOSE(A,S...) {if (DBG_FLAGS(A) & DBG_VERBOSE_ON) \ + {DBG_PRINT("%s:VERBOSE:%s ",DBG_NAME(A),__FUNC__);DBG_PRINTC(S);}} + + +#define DBG_RX(A,S...) {if (DBG_FLAGS(A) & DBG_RX_ON) \ + {DBG_PRINT(S);}} + +#define DBG_RX_ENTER(A) {if (DBG_FLAGS(A) & DBG_RX_ON) \ + _DBG_ENTER(A);} + +#define DBG_RX_LEAVE(A) {if (DBG_FLAGS(A) & DBG_RX_ON) \ + _DBG_LEAVE(A);} + +#define DBG_TX(A,S...) {if (DBG_FLAGS(A) & DBG_TX_ON) \ + {DBG_PRINT(S);}} + +#define DBG_TX_ENTER(A) {if (DBG_FLAGS(A) & DBG_TX_ON) \ + _DBG_ENTER(A);} + +#define DBG_TX_LEAVE(A) {if (DBG_FLAGS(A) & DBG_TX_ON) \ + _DBG_LEAVE(A);} + + +#define DBG_ASSERT(C) {if (!(C)) \ + {DBG_PRINT("ASSERT(%s) -- %s#%d (%s)\n", \ + #C,__FILE__,__LINE__,__FUNC__); \ + DBG_TRAP;}} +#define STATIC + + +typedef struct +{ + char *dbgName; + int dbgLevel; + unsigned long dbgFlags; +} dbg_info_t; + + + + +#else /* ET131X_DBG */ + + + + +#define DBG_DEFN +#define DBG_TRAP +#define DBG_FUNC(F) +#define DBG_PRINT(S...) +#define DBG_ENTER(A) +#define DBG_LEAVE(A) +#define DBG_PARAM(A,N,F,S...) +#define DBG_ERROR(A,S...) +#define DBG_WARNING(A,S...) +#define DBG_NOTICE(A,S...) +#define DBG_TRACE(A,S...) +#define DBG_VERBOSE(A,S...) +#define DBG_RX(A,S...) +#define DBG_RX_ENTER(A) +#define DBG_RX_LEAVE(A) +#define DBG_TX(A,S...) +#define DBG_TX_ENTER(A) +#define DBG_TX_LEAVE(A) +#define DBG_ASSERT(C) +#define STATIC static + +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + Forward declaration of the private adapter structure + *****************************************************************************/ +struct et131x_adapter; + + + + +/****************************************************************************** + PROTOTYPES for et131x_debug.c + *****************************************************************************/ +void DumpTxQueueContents( int dbgLvl, struct et131x_adapter *pAdapter ); +void DumpDeviceBlock( int dbgLvl, struct et131x_adapter *pAdapter, unsigned int Block ); +void DumpDeviceReg( int dbgLvl, struct et131x_adapter *pAdapter ); + + + + +#endif /* __ET131X_DBG_H__ */ --- linux-2.6.28.orig/ubuntu/et131x/et131x_isr.c +++ linux-2.6.28/ubuntu/et131x/et131x_isr.c @@ -0,0 +1,656 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_isr.c - File which contains the ISR, ISR handler, and related routines + * for processing interrupts from the device. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2006/01/31 20:58:43 $ + $Revision: 1.13 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" +#include "ET1310_mac.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" + + + + +/****************************************************************************** + Data for debugging facilities + *****************************************************************************/ +#ifdef ET131X_DBG +extern dbg_info_t *et131x_dbginfo; +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + Prototypes for functions with local scope + *****************************************************************************/ + + + + +/****************************************************************************** + Defines for 2.4 compatibility with the new 2.6 IRQ handler return values + *****************************************************************************/ +#ifndef IRQ_RETVAL + +typedef void irqreturn_t; +#define IRQ_NONE +#define IRQ_HANDLED +#define IRQ_RETVAL(x) + +#endif /* IRQ_RETVAL */ + + + + +/****************************************************************************** + ROUTINE : et131x_isr + ****************************************************************************** + + DESCRIPTION : The Interrupt Service Routine for the driver. + + PARAMETERS : irq - the IRQ on which the interrupt was received. + dev_id - a buffer containing device-specific info (in + this case, a pointer to a net_device struct) + regs - + + RETURNS : For 2.4.x kernels - N/A + For 2.6.x kernels - A value indicating if the interrupt + was handled. + + REUSE INFORMATION : + + *****************************************************************************/ +irqreturn_t et131x_isr( int irq, void *dev_id ) +{ + BOOL_t handled = TRUE; + struct net_device *netdev = (struct net_device *)dev_id; + ET131X_ADAPTER *adapter = NULL; + INT_STATUS_t status; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_isr" ); + + + do + { + if(( netdev == NULL ) || ( !netif_device_present( netdev ))) + { + DBG_WARNING( et131x_dbginfo, + "No net_device struct or device not present\n" ); + handled = FALSE; + break; + } + + adapter = netdev_priv( netdev ); + + + /********************************************************************** + If the adapter is in low power state, then it should not recognize + any interrupt + + NOTE + *********************************************************************/ + + + /********************************************************************** + Disable Device Interrupts + *********************************************************************/ + et131x_disable_interrupts( adapter ); + + + /********************************************************************** + Get a copy of the value in the interrupt status register so we can + process the interrupting section + *********************************************************************/ + status.value = adapter->CSRAddress->global.int_status.value; + + if(( adapter->FlowControl == TxOnly ) || + ( adapter->FlowControl == Both )) + { + status.value &= ~INT_MASK_ENABLE; + } + else + { + status.value &= ~INT_MASK_ENABLE_NO_FLOW; + } + + + /********************************************************************** + Make sure this is our interrupt + *********************************************************************/ + if( !status.value ) + { +#ifdef ET131X_DBG + adapter->Stats.UnhandledInterruptsPerSec++; +#endif + handled = FALSE; + DBG_VERBOSE( et131x_dbginfo, "NOT OUR INTERRUPT\n" ); + et131x_enable_interrupts( adapter ); + break; + } + + /********************************************************************** + This is our interrupt, so process accordingly + *********************************************************************/ +#ifdef ET131X_DBG + if( status.bits.rxdma_xfr_done ) + { + adapter->Stats.RxDmaInterruptsPerSec++; + } + + if( status.bits.txdma_isr ) + { + adapter->Stats.TxDmaInterruptsPerSec++; + } +#endif + + if( status.bits.watchdog_interrupt ) + { + PMP_TCB pMpTcb = adapter->TxRing.CurrSendHead; + + if( pMpTcb ) + { + if( ++pMpTcb->PacketStaleCount > 1 ) + { + status.bits.txdma_isr = 1; + } + } + + if( adapter->RxRing.UnfinishedReceives ) + { + status.bits.rxdma_xfr_done = 1; + } + else if( pMpTcb == 0 ) + { + adapter->CSRAddress->global.watchdog_timer = 0; + } + + status.bits.watchdog_interrupt = 0; +#ifdef ET131X_DBG + adapter->Stats.WatchDogInterruptsPerSec++; +#endif + } + + if( status.value == 0 ) + { + /****************************************************************** + This interrupt has in some way been "handled" by the ISR. Either + it was a spurious Rx interrupt, or it was a Tx interrupt that + has been filtered by the ISR. + *****************************************************************/ + et131x_enable_interrupts( adapter ); + break; + } + + /********************************************************************** + We need to save the interrupt status value for use in our DPC. We + will clear the software copy of that in that routine. + *********************************************************************/ + adapter->Stats.InterruptStatus = status; + + + /********************************************************************** + Schedule the ISR handler as a bottom-half task in the kernel's + tq_immediate queue, and mark the queue for execution + *********************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) + schedule_task( &adapter->task ); +#else + schedule_work( &adapter->task ); +#endif + + } while( 0 ); + + return IRQ_RETVAL( handled ); +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_isr_handler + ****************************************************************************** + + DESCRIPTION : The ISR handler, scheduled to run in a deferred context + by the ISR. This is where the ISR's work actually gets + done. + + PARAMETERS : p_adapter - a pointer to the device's private adapter + structure + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_isr_handler( struct work_struct *work ) +{ + ET131X_ADAPTER *pAdapter = container_of( work, ET131X_ADAPTER, task ); + + INT_STATUS_t GlobStatus = pAdapter->Stats.InterruptStatus; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_isr_handler" ); + + + /************************************************************************** + These first two are by far the most common. Once handled, we clear + their two bits in the status word. If the word is now zero, we exit. + *************************************************************************/ + /************************************************************************** + Handle all the completed Transmit interrupts + *************************************************************************/ + if( GlobStatus.bits.txdma_isr ) + { + DBG_TX( et131x_dbginfo, "TXDMA_ISR interrupt\n" ); + et131x_handle_send_interrupt( pAdapter ); + } + + + /************************************************************************** + Handle all the completed Receives interrupts + *************************************************************************/ + if( GlobStatus.bits.rxdma_xfr_done ) + { + DBG_RX( et131x_dbginfo, "RXDMA_XFR_DONE interrupt\n" ); + et131x_handle_recv_interrupt( pAdapter ); + } + + GlobStatus.value &= 0xffffffd7; + + if( GlobStatus.value ) + { + + /********************************************************************** + Handle the TXDMA Error interrupt + *********************************************************************/ + if( GlobStatus.bits.txdma_err ) + { + TXDMA_ERROR_t TxDmaErr; + + + /****************************************************************** + Following read also clears the register (COR register) + *****************************************************************/ + TxDmaErr.value = pAdapter->CSRAddress->txdma.TxDmaError.value; + + DBG_WARNING( et131x_dbginfo, "TXDMA_ERR interrupt, error = %d\n", + TxDmaErr.value ); + } + + + /********************************************************************** + Handle Free Buffer Ring 0 and 1 Low interrupt + *********************************************************************/ + if( GlobStatus.bits.rxdma_fb_ring0_low || + GlobStatus.bits.rxdma_fb_ring1_low ) + { + /****************************************************************** + This indicates the number of unused buffers in RXDMA free buffer + ring 0 is <= the limit you programmed. Free buffer resources + need to be returned. Free buffers are consumed as packets are + passed from the network to the host. The host becomes aware of + the packets from the contents of the packet status ring. This + ring is queried when the packet done interrupt occurs. Packets + are then passed to the OS. When the OS is done with the packets + the resources can be returned to the ET1310 for re-use. This + interrupt is one method of returning resources. + *****************************************************************/ + DBG_WARNING( et131x_dbginfo, + "RXDMA_FB_RING0_LOW or " + "RXDMA_FB_RING1_LOW interrupt\n" ); + + + /****************************************************************** + If the user has flow control on, then we will send a pause + packet, otherwise just exit + *****************************************************************/ + if(( pAdapter->FlowControl == TxOnly ) || + ( pAdapter->FlowControl == Both )) + { + /************************************************************** + Tell the device to send a pause packet via the back pressure + register + *************************************************************/ + if( pAdapter->CSRAddress->global.pm_csr.bits.pm_phy_sw_coma == 0 ) + { + TXMAC_BP_CTRL_t bp_ctrl; + + bp_ctrl.bits.bp_req = 1; + bp_ctrl.bits.bp_xonxoff = 1; + + pAdapter->CSRAddress->txmac.bp_ctrl.value = bp_ctrl.value; + } + } + } + + + /********************************************************************** + Handle Packet Status Ring Low Interrupt + *********************************************************************/ + if( GlobStatus.bits.rxdma_pkt_stat_ring_low ) + { + DBG_WARNING( et131x_dbginfo, + "RXDMA_PKT_STAT_RING_LOW interrupt\n" ); + + + /****************************************************************** + Same idea as with the two Free Buffer Rings. Packets going from + the network to the host each consume a free buffer resource and + a packet status resource. These resoures are passed to the OS. + When the OS is done with the resources, they need to be returned + to the ET1310. This is one method of returning the resources. + *****************************************************************/ + } + + + /********************************************************************** + Handle RXDMA Error Interrupt + *********************************************************************/ + if( GlobStatus.bits.rxdma_err ) + { + /****************************************************************** + The rxdma_error interrupt is sent when a time-out on a request + issued by the JAGCore has occurred or a completion is returned + with an un-successful status. In both cases the request is + considered complete. The JAGCore will automatically re-try the + request in question. Normally information on events like these + are sent to the host using the "Advanced Error Reporting" + capability. This interrupt is another way of getting similar + information. The only thing required is to clear the interrupt + by reading the ISR in the global resources. The JAGCore will do + a re-try on the request. Normally you should never see this + interrupt. If you start to see this interrupt occurring + frequently then something bad has occurred. + A reset might be the thing to do. + *****************************************************************/ + // TRAP(); + + pAdapter->TxMacTest = pAdapter->CSRAddress->txmac.tx_test; + DBG_WARNING( et131x_dbginfo, + "RxDMA_ERR interrupt, error %x\n", + pAdapter->TxMacTest.value ); + } + + + /********************************************************************** + Handle the Wake on LAN Event + *********************************************************************/ + if( GlobStatus.bits.wake_on_lan ) + { + /****************************************************************** + This is a secondary interrupt for wake on LAN. The driver + should never see this, if it does, something serious is wrong. + We will TRAP the message when we are in DBG mode, otherwise we + will ignore it. + *****************************************************************/ + DBG_ERROR( et131x_dbginfo, "WAKE_ON_LAN interrupt\n" ); + } + + + /********************************************************************** + Handle the PHY interrupt + *********************************************************************/ + if( GlobStatus.bits.phy_interrupt ) + { + MI_BMSR_t BmsrInts, BmsrData; + MI_ISR_t myIsr; + + DBG_VERBOSE( et131x_dbginfo, "PHY interrupt\n" ); + + /****************************************************************** + If we are in coma mode when we get this interrupt, we need to + disable it. + *****************************************************************/ + if( pAdapter->CSRAddress->global.pm_csr.bits.phy_sw_coma == 1 ) + { + /************************************************************** + Check to see if we are in coma mode and if so, disable it + because we will not be able to read PHY values until we are + out. + *************************************************************/ + DBG_VERBOSE( et131x_dbginfo, "Device is in COMA mode, " + "need to wake up\n" ); + DisablePhyComa( pAdapter ); + } + + + /****************************************************************** + Read the PHY ISR to clear the reason for the interrupt. + *****************************************************************/ + MiRead( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + (UINT8)FIELD_OFFSET( MI_REGS_t, isr ), &myIsr.value ); + + if( !pAdapter->ReplicaPhyLoopbk ) + { + MiRead( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + (UINT8)FIELD_OFFSET( MI_REGS_t, bmsr ), &BmsrData.value ); + + BmsrInts.value = pAdapter->Bmsr.value ^ BmsrData.value; + pAdapter->Bmsr.value = BmsrData.value; + + DBG_VERBOSE( et131x_dbginfo, + "Bmsr.value = 0x%04x," + "Bmsr_ints.value = 0x%04x\n", + BmsrData.value, + BmsrInts.value ); + + + /************************************************************** + Do all the cable in / cable out stuff + *************************************************************/ + et131x_Mii_check( pAdapter, BmsrData, BmsrInts ); + } + } + + + /********************************************************************** + Let's move on to the TxMac + *********************************************************************/ + if( GlobStatus.bits.txmac_interrupt ) + { + pAdapter->TxRing.TxMacErr.value = pAdapter->CSRAddress->txmac.err.value; + + /****************************************************************** + When any of the errors occur and TXMAC generates an interrupt to + report these errors, it usually means that TXMAC has detected an + error in the data stream retrieved from the on-chip Tx Q. All of + these errors are catastrophic and TXMAC won’t be able to recover + data when these errors occur. In a nutshell, the whole Tx path + will have to be reset and re-configured afterwards. + *****************************************************************/ + DBG_WARNING( et131x_dbginfo, + "TXMAC interrupt, error 0x%08x\n", + pAdapter->TxRing.TxMacErr.value ); + + + /******************************************************************* + If we are debugging, we want to see this error, otherwise we just + want the device to be reset and continue + *****************************************************************/ + //DBG_TRAP(); + + } + + /********************************************************************** + Handle RXMAC Interrupt + *********************************************************************/ + if( GlobStatus.bits.rxmac_interrupt ) + { + /****************************************************************** + These interrupts are catastrophic to the device, what we need to + do is disable the interrupts and set the flag to cause us to + reset so we can solve this issue. + ******************************************************************/ + // MP_SET_FLAG( pAdapter, fMP_ADAPTER_HARDWARE_ERROR ); + + DBG_WARNING( et131x_dbginfo, + "RXMAC interrupt, error 0x%08x. Requesting reset\n", + pAdapter->CSRAddress->rxmac.err_reg.value ); + + DBG_WARNING( et131x_dbginfo, + "Enable 0x%08x, Diag 0x%p\n", + pAdapter->CSRAddress->rxmac.ctrl.value, + &pAdapter->CSRAddress->rxmac.rxq_diag ); + + + /******************************************************************* + If we are debugging, we want to see this error, otherwise we just + want the device to be reset and continue + *****************************************************************/ + // TRAP(); + } + + /********************************************************************** + Handle MAC_STAT Interrupt + *********************************************************************/ + if( GlobStatus.bits.mac_stat_interrupt ) + { + /****************************************************************** + This means at least one of the un-masked counters in the MAC_STAT + block has rolled over. Use this to maintain the top, software + managed bits of the counter(s). + *****************************************************************/ + DBG_VERBOSE( et131x_dbginfo, "MAC_STAT interrupt\n" ); + HandleMacStatInterrupt( pAdapter ); + } + + + /********************************************************************** + Handle SLV Timeout Interrupt + *********************************************************************/ + if( GlobStatus.bits.slv_timeout ) + { + /****************************************************************** + This means a timeout has occured on a read or write request to + one of the JAGCore registers. The Global Resources block has + terminated the request and on a read request, returned a "fake" + value. The most likely reasons are: Bad Address or the + addressed module is in a power-down state and can't respond. + *****************************************************************/ + DBG_VERBOSE( et131x_dbginfo, "SLV_TIMEOUT interrupt\n" ); + } + } + + + if( pAdapter->PoMgmt.PowerState == NdisDeviceStateD0 ) + { + et131x_enable_interrupts( pAdapter ); + } + + return; +} +/*===========================================================================*/ --- linux-2.6.28.orig/ubuntu/et131x/et131x_supp.c +++ linux-2.6.28/ubuntu/et131x/et131x_supp.c @@ -0,0 +1,440 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_supp.c - Misc. support routines. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/08/01 19:35:13 $ + $Revision: 1.6 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" +#include "ET1310_mac.h" + +#include "et131x_supp.h" + + + + +/****************************************************************************** + Data for debugging facilities + *****************************************************************************/ +#ifdef ET131X_DBG +extern dbg_info_t *et131x_dbginfo; +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + Global look-up table used to calculate CRC. Preset with the appropriate + XORs from the 256 possible byte values that might be in the message. + *****************************************************************************/ +static UINT32 SynDrome [256]; + + + + +/****************************************************************************** + Prototypes for functions with local scope + *****************************************************************************/ +static UINT32 crc32byte( UINT32 remainder, UCHAR data ); + + + + +/****************************************************************************** + ROUTINE : et131x_init_enet_crc_calc + ****************************************************************************** + + DESCRIPTION : Initializes the look-up table (syndrome) for CRC + calculation. + + PARAMETERS : N/A + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_init_enet_crc_calc( void ) +{ + UINT32 EthernetKey = 0x04c11db7; + UINT32 i; + UINT32 j; + UINT32 reg; + BOOL_t topBit; + /*-----------------------------------------------------------------------*/ + + + for( i = 0; i < 256; i++ ) + { + reg = i << 24; + + for( j = 0; j < 8; j++ ) + { + topBit = ( reg & 0x80000000 ) != 0; + + reg <<= 1; + + if( topBit ) + { + reg ^= EthernetKey; + } + } + SynDrome[i] = reg; + } + + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : crc32byte + ****************************************************************************** + + DESCRIPTION : + + PARAMETERS : + + RETURNS : + + REUSE INFORMATION : + + *****************************************************************************/ +#define CRC32_POLY 0x4C11DB7 + +static UINT32 crc32byte( UINT32 remainder, UCHAR data ) +{ + int index; + UINT32 remndr, hitbit; + /*-----------------------------------------------------------------------*/ + + + remndr = remainder; + + for( index = 0; index < 8; index++ ) + { + hitbit = (remndr >> 31) ^ (data & 0x01); + + data = data >> 1; // get the next data bit + remndr = remndr << 1; // get the next remainder bit + + if( hitbit ) + { + remndr = remndr ^ CRC32_POLY; + } + } + + return remndr; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_calc_enet_crc + ****************************************************************************** + + DESCRIPTION : Used to calculate the CRC of an ethernet message. Used + in the device's filtering of multi-cast packets. + + PARAMETERS : Message - A pointer to the Ethernet bytes to be encoded + MessageSize - The number of bytes in the message + + RETURNS : The computed CRC + + REUSE INFORMATION : + + *****************************************************************************/ +UINT32 et131x_calc_enet_crc( PUCHAR Message, UINT32 MessageSize ) +{ + UINT32 Result = 0xFFFFFFFF; + UINT32 i; + /*-----------------------------------------------------------------------*/ + + for( i = 0; i < MessageSize; i++ ) + { + Result = crc32byte( Result, *Message ); + Message++; + } + + return Result; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : pci_slot_information_read + ****************************************************************************** + + DESCRIPTION : Reads a segment of the PCI configuration space for a + device. + + This is a port of the NDIS function + NdisReadPciSlotInformation + + This function does not begin with 'et131x_' in order to + remain consistent with other system pci_xxx() calls. + + PARAMETERS : pdev - pointer to a pci_dev structure for the device + whose PCI config space is to be read + where - the offset to read + buf - a pointer to a buffer in which the data will be + returned + len - the length of the above buffer + + RETURNS : The length of the buffer read + + REUSE INFORMATION : + + *****************************************************************************/ +UINT32 pci_slot_information_read( struct pci_dev *pdev, UINT32 where, + UINT8 *buf, UINT32 len ) +{ + int i; + int status; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "pci_slot_information_read" ); + + + for( i = 0; i < len; i++ ) + { + status = pci_read_config_byte( pdev, where+i, &buf[i] ); + + if( status != 0 ) + { + DBG_ERROR( et131x_dbginfo, "Cannot Read PCI config space...\n" ); + break; + } + } + + return len; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : pci_slot_information_write + ****************************************************************************** + + DESCRIPTION : Writes a segment of the PCI configuration space for a + device. + + This is a port of the NDIS function + NdisWritePciSlotInformation + + This function does not begin with 'et131x_' in order to + remain consistent with other system pci_xxx() calls. + + PARAMETERS : pdev - pointer to a pci_dev structure for the device + whose PCI config space is to be written + where - the offset to write + buf - a pointer to a buffer containing the data to be + written + len - the length of the above buffer + + RETURNS : The length of the buffer written + + REUSE INFORMATION : + + *****************************************************************************/ +UINT32 pci_slot_information_write( struct pci_dev *pdev, UINT32 where, + UINT8 *buf, UINT32 len ) +{ + int i; + int status; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "pci_slot_information_write" ); + + + for( i = 0; i < len; i++ ) + { + status = pci_write_config_byte( pdev, where+i, buf[i] ); + + if( status != 0 ) + { + DBG_ERROR( et131x_dbginfo, "Cannot Write PCI config space...\n" ); + break; + } + } + + return len; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : netif_indicate_status + ****************************************************************************** + + DESCRIPTION : Provides the network stack with link status for the + given device. + + This is a port of the NDIS function + NdisMIndicateStatus. Unlike NDIS, there is no + corresponding status completion function. + + This function does not begin with 'et131x_' in order to + remain consistent with other system netif_xxx() calls. + + PARAMETERS : netdev - a pointer to the net_device struct representing + the device whose status we wosh to indicate. + status - the link status + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void netif_indicate_status( struct net_device *netdev, NETIF_STATUS status ) +{ + DBG_FUNC( "netif_indicate_status" ); + + + if( netdev != NULL ) + { + switch( status ) + { + case NETIF_STATUS_MEDIA_CONNECT: + DBG_VERBOSE( et131x_dbginfo, "Indicating Link UP\n" ); + netif_carrier_on( netdev ); + break; + + case NETIF_STATUS_MEDIA_DISCONNECT: + DBG_VERBOSE( et131x_dbginfo, "Indicating Link DOWN\n" ); + netif_carrier_off( netdev ); + break; + + default: + DBG_WARNING( et131x_dbginfo, + "Unknown link status code: %d\n", + status ); + break; + } + } + else + { + DBG_WARNING( et131x_dbginfo, "net_device pointer is NULL\n" ); + } + + return; +} +/*===========================================================================*/ --- linux-2.6.28.orig/ubuntu/et131x/ET1310_tx.c +++ linux-2.6.28/ubuntu/et131x/ET1310_tx.c @@ -0,0 +1,2084 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_tx.c - Routines used to perform data transmission. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2006/01/20 21:29:44 $ + $Revision: 1.24 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +#include +#endif + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" +#include "et131x_initpci.h" +#include "et131x_isr.h" + +#include "ET1310_tx.h" + + + + +/****************************************************************************** + Data for debugging facilities + *****************************************************************************/ +#ifdef ET131X_DBG +extern dbg_info_t *et131x_dbginfo; +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + Prototypes for functions local to this module + *****************************************************************************/ +void et131x_update_tcb_list( ET131X_ADAPTER *pAdapter ); +void et131x_check_send_wait_list( ET131X_ADAPTER *pAdapter ); +__inline void et131x_free_send_packet( ET131X_ADAPTER *pAdapter, PMP_TCB pMpTcb ); + +int et131x_send_packet( struct sk_buff *skb, ET131X_ADAPTER *pAdapter ); +int nic_send_packet( ET131X_ADAPTER *pAdapter, PMP_TCB pMpTcb ); + + + + +/****************************************************************************** + ROUTINE : et131x_tx_dma_memory_alloc + ****************************************************************************** + + DESCRIPTION : Allocates memory that will be visible both to the device + and to the CPU. The OS will pass us packets, pointers to + which we will insert in the Tx Descriptor queue. The + device will read this queue to find the packets in + memory. The device will update the "status" in memory + each time it xmits a packet. + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_tx_dma_memory_alloc( ET131X_ADAPTER *adapter ) +{ + int desc_size = 0; + TX_RING_t *tx_ring; + MP_TCB *tcb; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_tx_dma_memory_alloc" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Allocate memory for the TCB's (Transmit Control Block) + *************************************************************************/ + adapter->TxRing.MpTcbMem = kmalloc( NUM_TCB * sizeof( MP_TCB ), + GFP_ATOMIC | GFP_DMA ); + if( !adapter->TxRing.MpTcbMem ) + { + DBG_ERROR( et131x_dbginfo, "Cannot alloc memory for TCBs\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + memset( adapter->TxRing.MpTcbMem, 0, ( NUM_TCB * sizeof( MP_TCB ))); + + + /************************************************************************** + Setup some convenience pointers + *************************************************************************/ + tx_ring = (TX_RING_t *)&adapter->TxRing; + tcb = (MP_TCB *)adapter->TxRing.MpTcbMem; + + + /************************************************************************** + Allocate enough memory for the Tx descriptor ring, and allocate some + extra so that the ring can be aligned on a 4k boundary. + *************************************************************************/ + desc_size = ( sizeof( TX_DESC_ENTRY_t ) * NUM_DESC_PER_RING_TX ) + 4096 - 1; + tx_ring->pTxDescRingVa = (PTX_DESC_ENTRY_t)pci_alloc_consistent( adapter->pdev, + desc_size, + &tx_ring->pTxDescRingPa ); + if( !adapter->TxRing.pTxDescRingVa ) + { + DBG_ERROR( et131x_dbginfo, "Cannot alloc memory for Tx Ring\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + + /************************************************************************** + Save physical address + + NOTE : pci_alloc_consistent(), used above to alloc DMA regions, ALWAYS + returns SAC (32-bit) addresses. If DAC (64-bit) addresses are + ever returned, make sure the high part is retrieved here before + storing the adjusted address. + *************************************************************************/ + tx_ring->pTxDescRingAdjustedPa = tx_ring->pTxDescRingPa; + + + /************************************************************************** + Align Tx Descriptor Ring on a 4k (0x1000) byte boundary + *************************************************************************/ + et131x_align_allocated_memory( adapter, + &tx_ring->pTxDescRingAdjustedPa, + &tx_ring->TxDescOffset, + 0x0FFF ); + + tx_ring->pTxDescRingVa += tx_ring->TxDescOffset; + + + /************************************************************************** + Allocate memory for the Tx status block + *************************************************************************/ + tx_ring->pTxStatusVa = pci_alloc_consistent( adapter->pdev, + sizeof( TX_STATUS_BLOCK_t ), + &tx_ring->pTxStatusPa ); + if( !adapter->TxRing.pTxStatusPa ) + { + DBG_ERROR( et131x_dbginfo, "Cannot alloc memory for Tx status block\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + + /************************************************************************** + Allocate memory for a dummy buffer + *************************************************************************/ + tx_ring->pTxDummyBlkVa = pci_alloc_consistent( adapter->pdev, + NIC_MIN_PACKET_SIZE, + &tx_ring->pTxDummyBlkPa ); + if( !adapter->TxRing.pTxDummyBlkPa ) + { + DBG_ERROR( et131x_dbginfo, "Cannot alloc memory for Tx dummy buffer\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + + DBG_LEAVE( et131x_dbginfo ); + return 0; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_tx_dma_memory_free + ****************************************************************************** + + DESCRIPTION : Free all memory allocated within this module + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_tx_dma_memory_free( ET131X_ADAPTER *adapter ) +{ + int desc_size = 0; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_tx_dma_memory_free" ); + DBG_ENTER( et131x_dbginfo ); + + + if( adapter->TxRing.pTxDescRingVa ) + { + /********************************************************************** + Free memory relating to Tx rings here + *********************************************************************/ + adapter->TxRing.pTxDescRingVa -= adapter->TxRing.TxDescOffset; + + desc_size = ( sizeof( TX_DESC_ENTRY_t ) * NUM_DESC_PER_RING_TX ) + 4096 - 1; + + pci_free_consistent( adapter->pdev, + desc_size, + adapter->TxRing.pTxDescRingVa, + adapter->TxRing.pTxDescRingPa ); + + adapter->TxRing.pTxDescRingVa = NULL ; + } + + + /************************************************************************** + Free memory for the Tx status block + *************************************************************************/ + if( adapter->TxRing.pTxStatusVa ) + { + pci_free_consistent( adapter->pdev, + sizeof( TX_STATUS_BLOCK_t ), + adapter->TxRing.pTxStatusVa, + adapter->TxRing.pTxStatusPa ); + + adapter->TxRing.pTxStatusVa = NULL ; + } + + + /************************************************************************** + Free memory for the dummy buffer + *************************************************************************/ + if( adapter->TxRing.pTxDummyBlkVa ) + { + pci_free_consistent( adapter->pdev, + NIC_MIN_PACKET_SIZE, + adapter->TxRing.pTxDummyBlkVa, + adapter->TxRing.pTxDummyBlkPa ); + + adapter->TxRing.pTxDummyBlkVa = NULL ; + } + + + /************************************************************************** + Free the memory for MP_TCB structures + *************************************************************************/ + if( adapter->TxRing.MpTcbMem ) + { + kfree( adapter->TxRing.MpTcbMem ); + adapter->TxRing.MpTcbMem = NULL; + } + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : ConfigTxDmaRegs + ****************************************************************************** + + DESCRIPTION : Used to set up the tx dma section of the JAGCore. + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void ConfigTxDmaRegs( ET131X_ADAPTER *pAdapter ) +{ + PTXDMA_t pTxDma; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "ConfigTxDmaRegs" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + First lets get a copy of the pointer + *************************************************************************/ + pTxDma = &pAdapter->CSRAddress->txdma; + + + /************************************************************************** + Load the hardware with the start of the transmit descriptor ring. + *************************************************************************/ + pTxDma->pr_base_hi.addr_hi = + (UINT32)( pAdapter->TxRing.pTxDescRingAdjustedPa >> 32 ); + pTxDma->pr_base_lo.addr_lo = + (UINT32)( pAdapter->TxRing.pTxDescRingAdjustedPa ); + + + /************************************************************************** + Initialise the transmit DMA engine + *************************************************************************/ + pTxDma->pr_num_des.value = NUM_DESC_PER_RING_TX - 1; + + + /************************************************************************** + Load the completion writeback physical address + + NOTE : pci_alloc_consistent(), used above to alloc DMA regions, ALWAYS + returns SAC (32-bit) addresses. If DAC (64-bit) addresses are + ever returned, make sure the high part is retrieved here before + storing the adjusted address. + *************************************************************************/ + pTxDma->dma_wb_base_hi.addr_hi = 0x0; + pTxDma->dma_wb_base_lo.addr_lo = pAdapter->TxRing.pTxStatusPa; + + memset( pAdapter->TxRing.pTxStatusVa, 0, sizeof( TX_STATUS_BLOCK_t )); + + + pTxDma->service_request.value = 0x0; + pAdapter->TxRing.txDmaReadyToSend.value = 0x0; + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_tx_dma_disable + ****************************************************************************** + DESCRIPTION: + Stop OF Tx_DMA on the ET1310 + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + N/A + + *****************************************************************************/ +void et131x_tx_dma_disable( ET131X_ADAPTER *pAdapter ) +{ + DBG_FUNC( "et131x_tx_dma_disable" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Setup the tramsmit dma configuration register + *************************************************************************/ + pAdapter->CSRAddress->txdma.csr.value = 0x101; + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_tx_dma_enable + ****************************************************************************** + DESCRIPTION: + re-start OF Tx_DMA on the ET1310. Mainly used after a return to the + D0 (full-power) state from a lower state. + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + N/A + + *****************************************************************************/ +void et131x_tx_dma_enable( ET131X_ADAPTER *pAdapter ) +{ + TXDMA_CSR_t csr = {0}; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_tx_dma_enable" ); + DBG_ENTER( et131x_dbginfo ); + + + if( pAdapter->RegistryPhyLoopbk ) + { + /********************************************************************** + TxDMA is disabled for loopback operation. + *********************************************************************/ + pAdapter->CSRAddress->txdma.csr.value = 0x101; + + } + else + { + /********************************************************************** + Setup the transmit dma configuration register for normal operation + *********************************************************************/ + csr.bits.sngl_epkt_mode = 1; + csr.bits.halt = 0; + csr.bits.cache_thrshld = pAdapter->RegistryDMACache; + + pAdapter->CSRAddress->txdma.csr.value = csr.value; + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_init_send + ****************************************************************************** + + DESCRIPTION : Initialize send data structures + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_init_send( ET131X_ADAPTER *adapter ) +{ + PMP_TCB pMpTcb; + UINT32 TcbCount; + TX_RING_t *tx_ring; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_init_send" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Setup some convenience pointers + *************************************************************************/ + tx_ring = (TX_RING_t *)&adapter->TxRing; + pMpTcb = (PMP_TCB)adapter->TxRing.MpTcbMem; + + + tx_ring->TCBReadyQueueHead = pMpTcb; + + + /************************************************************************** + Go through and set up each TCB + *************************************************************************/ + for( TcbCount = 0; TcbCount < NUM_TCB; TcbCount++ ) + { + memset( pMpTcb, 0, sizeof( MP_TCB )); + + + /********************************************************************** + Set the link pointer in HW TCB to the next TCB in the chain. If + this is the last TCB in the chain, also set the tail pointer. + *********************************************************************/ + if( TcbCount < NUM_TCB - 1 ) + { + pMpTcb->Next = pMpTcb + 1; + } + else + { + tx_ring->TCBReadyQueueTail = pMpTcb; + pMpTcb->Next = (PMP_TCB)NULL; + } + + pMpTcb++; + } + + /************************************************************************** + Curr send queue should now be empty + *************************************************************************/ + tx_ring->CurrSendHead = (PMP_TCB)NULL; + tx_ring->CurrSendTail = (PMP_TCB)NULL; + + INIT_LIST_HEAD( &adapter->TxRing.SendWaitQueue ); + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_send_packets + ****************************************************************************** + + DESCRIPTION: + This function is called by the OS to send packets + + PARAMETERS : + skb - the packet(s) to send + netdev - the net_device struct corresponding to the device on which to + TX the above packet(s) + + RETURN : + 0 in almost all cases + non-zero value in extreme hard failure only + + *****************************************************************************/ +int et131x_send_packets( struct sk_buff *skb, struct net_device *netdev ) +{ + int status = 0; + ET131X_ADAPTER *pAdapter = NULL; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_send_packets" ); + DBG_TX_ENTER( et131x_dbginfo ); + + + pAdapter = netdev_priv( netdev ); + + + /************************************************************************** + Send these packets + + NOTE: The Linux Tx entry point is only given one packet at a time + to Tx, so the PacketCount and it's array used makes no sense here + *************************************************************************/ + + /************************************************************************** + Queue is not empty or TCB is not available + *************************************************************************/ + if( !list_empty( &pAdapter->TxRing.SendWaitQueue ) || + MP_TCB_RESOURCES_NOT_AVAILABLE( pAdapter )) + { + /********************************************************************** + NOTE - If there's an error on send, no need to queue the + packet under Linux; if we just send an error up to the netif + layer, it will resend the skb to us. + *********************************************************************/ + DBG_VERBOSE( et131x_dbginfo, + "TCB Resources Not Available\n" ); + status = -ENOMEM; + } + else + { + /********************************************************************** + We need to see if the link is up; if it's not, make the netif layer + think we're good and drop the packet + *********************************************************************/ + //if( MP_SHOULD_FAIL_SEND( pAdapter ) || pAdapter->DriverNoPhyAccess ) + if( MP_SHOULD_FAIL_SEND( pAdapter ) || pAdapter->DriverNoPhyAccess || + !netif_carrier_ok( netdev )) + { + DBG_VERBOSE( et131x_dbginfo, + "Can't Tx, Link is DOWN; drop the packet\n" ); + + dev_kfree_skb_any( skb ); + skb = NULL; + + pAdapter->net_stats.tx_dropped++; + } + else + { + status = et131x_send_packet( skb, pAdapter ); + + if( status == -ENOMEM ) + { + + /************************************************************** + NOTE - If there's an error on send, no need to queue the + packet under Linux; if we just send an error up to the netif + layer, it will resend the skb to us. + *************************************************************/ + DBG_WARNING( et131x_dbginfo, + "Resources problem, Queue tx packet\n" ); + } + else if( status != 0 ) + { + /************************************************************** + On any other error, make netif think we're OK and drop the + packet + *************************************************************/ + DBG_WARNING( et131x_dbginfo, + "General error, drop packet\n" ); + + dev_kfree_skb_any( skb ); + skb = NULL; + + pAdapter->net_stats.tx_dropped++; + } + } + } + + + DBG_TX_LEAVE( et131x_dbginfo ); + return status; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_send_packet + ****************************************************************************** + DESCRIPTION: + Do the work to send a packet + + Assumption: Send spinlock has been acquired + + PARAMETERS : + skb - the packet(s) to send + pAdapter - a pointer to the device's private adapter structure + + RETURN : + 0 in almost all cases + non-zero value in extreme hard failure only + + *****************************************************************************/ +int et131x_send_packet( struct sk_buff *skb, ET131X_ADAPTER *pAdapter ) +{ + int status = 0; + PMP_TCB pMpTcb = NULL; + PUINT16 pShBufVa; + unsigned long lockflags; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_send_packet" ); + DBG_TX_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Is our buffer scattered, or continuous? + *************************************************************************/ + if( skb_shinfo( skb )->nr_frags == 0 ) + { + DBG_TX( et131x_dbginfo, "Scattered buffer: NO\n" ); + } + else + { + DBG_TX( et131x_dbginfo, "Scattered buffer: YES, Num Frags: %d\n", + skb_shinfo( skb )->nr_frags ); + } + + + /************************************************************************** + All packets must have at least a MAC address and a protocol type + *************************************************************************/ + if( skb->len < ETH_HLEN ) + { + DBG_ERROR( et131x_dbginfo, "Packet size < ETH_HLEN (14 bytes)\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + + + /************************************************************************** + Is this packet VLAN tagged? If so, is it a tag previously registered? + If not, drop the packet + + NOTE - We need not worry about the above note for now, as VLAN is handled + by the linux kernel (for the most part). + *************************************************************************/ +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +#if defined __vlan_get_tag + { + unsigned short vlan_tag; + + if( __vlan_get_tag( skb, &vlan_tag ) == -EINVAL ) + { + DBG_TX( et131x_dbginfo, + "VLAN: No TX packet tag\n" ); + } + else + { + DBG_TX( et131x_dbginfo, + "VLAN: TX packet tag: %d\n", vlan_tag ); + } + } +#endif +#endif + + + /************************************************************************** + Get a TCB for this packet + *************************************************************************/ + spin_lock_irqsave( &pAdapter->TCBReadyQLock, lockflags ); + + pMpTcb = pAdapter->TxRing.TCBReadyQueueHead; + + if( pMpTcb == NULL ) + { + spin_unlock_irqrestore( &pAdapter->TCBReadyQLock, lockflags ); + + DBG_WARNING( et131x_dbginfo, "Can't obtain a TCB\n" ); + DBG_TX_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + pAdapter->TxRing.TCBReadyQueueHead = pMpTcb->Next; + + if( pAdapter->TxRing.TCBReadyQueueHead == NULL ) + { + pAdapter->TxRing.TCBReadyQueueTail = NULL; + } + + spin_unlock_irqrestore( &pAdapter->TCBReadyQLock, lockflags ); + + pMpTcb->PacketLength = skb->len; + pMpTcb->Packet = skb; + + if(( skb->data != NULL ) && (( skb->len - skb->data_len ) >= 6 )) + { + pShBufVa = (PUINT16)skb->data; + + if(( pShBufVa [0] == 0xffff ) && + ( pShBufVa [1] == 0xffff ) && + ( pShBufVa [2] == 0xffff )) + { + MP_SET_FLAG( pMpTcb, fMP_DEST_BROAD ); + } + else if(( pShBufVa [0] & 0x3 ) == 0x0001 ) + { + MP_SET_FLAG( pMpTcb, fMP_DEST_MULTI ); + } + } + + pMpTcb->Next = NULL; + + + /************************************************************************** + Call the NIC specific send handler. + *************************************************************************/ + if( status == 0 ) + { + status = nic_send_packet( pAdapter, pMpTcb ); + } + + if( status != 0 ) + { + spin_lock_irqsave( &pAdapter->TCBReadyQLock, lockflags ); + + if( pAdapter->TxRing.TCBReadyQueueTail ) + { + pAdapter->TxRing.TCBReadyQueueTail->Next = pMpTcb; + } + else + { + /****************************************************************** + Apparently ready Q is empty. + *****************************************************************/ + pAdapter->TxRing.TCBReadyQueueHead = pMpTcb; + } + + pAdapter->TxRing.TCBReadyQueueTail = pMpTcb; + + spin_unlock_irqrestore( &pAdapter->TCBReadyQLock, lockflags ); + + DBG_TX_LEAVE( et131x_dbginfo ); + return status ; + } + + DBG_ASSERT( pAdapter->TxRing.nBusySend <= NUM_TCB ); + + + DBG_TX_LEAVE( et131x_dbginfo ); + return 0; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: nic_send_packet + ****************************************************************************** + DESCRIPTION: + NIC specific send handler. This version of the send routine is designed + for version B silicon. + + PARAMETERS : + pAdapter - pointer to our adapter + pMpTcb - pointer to MP_TCB + + RETURNS : + 0 or errno + + *****************************************************************************/ +int nic_send_packet( ET131X_ADAPTER *pAdapter, PMP_TCB pMpTcb ) +{ + UINT32 loopIndex; + TX_DESC_ENTRY_t CurDesc[24]; + UINT32 FragmentNumber = 0; + UINT32 iThisCopy, iRemainder; + struct sk_buff *pPacket = pMpTcb->Packet; + UINT32 FragListCount = skb_shinfo( pPacket )->nr_frags + 1; + struct skb_frag_struct *pFragList = &skb_shinfo( pPacket )->frags[0]; + unsigned long lockflags1, lockflags2; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "nic_send_packet" ); + DBG_TX_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Part of the optimizations of this send routine restrict us to + sending 24 fragments at a pass. In practice we should never see more + than 5 fragments. + + NOTE: The older version of this function (below) can handle any number + of fragments. If needed, we can call this function, although it is less + efficient. + *************************************************************************/ + if( FragListCount > 23 ) + { + DBG_TX_LEAVE( et131x_dbginfo ); + return -EIO; + } + + memset( CurDesc, 0, sizeof( TX_DESC_ENTRY_t ) * ( FragListCount + 1 )); + + for( loopIndex = 0; loopIndex < FragListCount; loopIndex++ ) + { + /********************************************************************** + If there is something in this element, lets get a descriptor from + the ring and get the necessary data + *********************************************************************/ + if( loopIndex == 0 ) + { + /****************************************************************** + If the fragments are smaller than a standard MTU, then map them + to a single descriptor in the Tx Desc ring. However, if they're + larger, as is possible with support for jumbo packets, then + split them each across 2 descriptors. + + This will work until we determine why the hardware doesn't seem + to like large fragments. + *****************************************************************/ + if(( pPacket->len - pPacket->data_len ) <= 1514 ) + { + DBG_TX( et131x_dbginfo, + "Got packet of length %d, " + "filling desc entry %d, " + "TCB: 0x%p\n", + ( pPacket->len - pPacket->data_len ), + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req, + pMpTcb ); + + CurDesc[FragmentNumber].DataBufferPtrHigh = 0; + + CurDesc[FragmentNumber].word2.bits.length_in_bytes = + pPacket->len - pPacket->data_len; + + /****************************************************************** + NOTE - Here, the dma_addr_t returned from pci_map_single() is + implicitly cast as a UINT32. Although dma_addr_t can be 64-bit, + the address returned by pci_map_single() is always 32-bit + addressable (as defined by the pci/dma subsystem) + ******************************************************************/ + CurDesc[FragmentNumber++].DataBufferPtrLow = pci_map_single( pAdapter->pdev, + pPacket->data, + pPacket->len - pPacket->data_len, + PCI_DMA_TODEVICE ); + } + else + { + DBG_TX( et131x_dbginfo, + "Got packet of length %d, " + "filling desc entry %d, " + "TCB: 0x%p\n", + ( pPacket->len - pPacket->data_len ), + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req, + pMpTcb ); + + CurDesc[FragmentNumber].DataBufferPtrHigh = 0; + + CurDesc[FragmentNumber].word2.bits.length_in_bytes = + (( pPacket->len - pPacket->data_len ) / 2 ); + + /****************************************************************** + NOTE - Here, the dma_addr_t returned from pci_map_single() is + implicitly cast as a UINT32. Although dma_addr_t can be 64-bit, + the address returned by pci_map_single() is always 32-bit + addressable (as defined by the pci/dma subsystem) + ******************************************************************/ + CurDesc[FragmentNumber++].DataBufferPtrLow = pci_map_single( pAdapter->pdev, + pPacket->data, + (( pPacket->len - pPacket->data_len ) / 2 ), + PCI_DMA_TODEVICE ); + CurDesc[FragmentNumber].DataBufferPtrHigh = 0; + + CurDesc[FragmentNumber].word2.bits.length_in_bytes = + (( pPacket->len - pPacket->data_len ) / 2 ); + + /****************************************************************** + NOTE - Here, the dma_addr_t returned from pci_map_single() is + implicitly cast as a UINT32. Although dma_addr_t can be 64-bit, + the address returned by pci_map_single() is always 32-bit + addressable (as defined by the pci/dma subsystem) + ******************************************************************/ + CurDesc[FragmentNumber++].DataBufferPtrLow = pci_map_single( pAdapter->pdev, + pPacket->data + (( pPacket->len - pPacket->data_len ) / 2 ), + (( pPacket->len - pPacket->data_len ) / 2 ), + PCI_DMA_TODEVICE ); + } + } + else + { + DBG_TX( et131x_dbginfo, + "Got packet of length %d," + "filling desc entry %d\n" + "TCB: 0x%p\n", + pFragList[loopIndex].size, + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req, + pMpTcb ); + + CurDesc[FragmentNumber].DataBufferPtrHigh = 0; + + + CurDesc[FragmentNumber].word2.bits.length_in_bytes = + pFragList[loopIndex - 1].size; + + /****************************************************************** + NOTE - Here, the dma_addr_t returned from pci_map_page() is + implicitly cast as a UINT32. Although dma_addr_t can be 64-bit, + the address returned by pci_map_page() is always 32-bit + addressable (as defined by the pci/dma subsystem) + ******************************************************************/ + CurDesc[FragmentNumber++].DataBufferPtrLow = pci_map_page( pAdapter->pdev, + pFragList[loopIndex - 1].page, + pFragList[loopIndex - 1].page_offset, + pFragList[loopIndex - 1].size, + PCI_DMA_TODEVICE ); + } + } + + if( FragmentNumber == 0 ) + { + DBG_WARNING( et131x_dbginfo, "No. frags is 0\n" ); + return -EIO; + } + + if( pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS ) + { + if( ++pAdapter->TxRing.TxPacketsSinceLastinterrupt == + pAdapter->RegistryTxNumBuffers ) + { + CurDesc[FragmentNumber - 1].word3.value = 0x5; + pAdapter->TxRing.TxPacketsSinceLastinterrupt = 0; + } + else + { + CurDesc[FragmentNumber - 1].word3.value = 0x1; + } + } + else + { + CurDesc[FragmentNumber - 1].word3.value = 0x5; + } + + CurDesc[0].word3.bits.f = 1; + + pMpTcb->WrIndexStart = pAdapter->TxRing.txDmaReadyToSend; + + pMpTcb->PacketStaleCount = 0; + + spin_lock_irqsave( &pAdapter->SendHWLock, lockflags1 ); + + iThisCopy = NUM_DESC_PER_RING_TX - pAdapter->TxRing.txDmaReadyToSend.bits.serv_req; + + if( iThisCopy >= FragmentNumber ) + { + iRemainder = 0; + iThisCopy = FragmentNumber; + } + else + { + iRemainder = FragmentNumber - iThisCopy; + } + + memcpy( pAdapter->TxRing.pTxDescRingVa + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req, + CurDesc, + sizeof( TX_DESC_ENTRY_t ) * iThisCopy ); + + + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req += iThisCopy; + + if(( pAdapter->TxRing.txDmaReadyToSend.bits.serv_req == 0 ) || + ( pAdapter->TxRing.txDmaReadyToSend.bits.serv_req == NUM_DESC_PER_RING_TX)) + { + if( pAdapter->TxRing.txDmaReadyToSend.bits.serv_req_wrap ) + { + pAdapter->TxRing.txDmaReadyToSend.value = 0; + } + else + { + pAdapter->TxRing.txDmaReadyToSend.value = 0x400; + } + } + + if( iRemainder ) + { + memcpy( pAdapter->TxRing.pTxDescRingVa, + CurDesc + iThisCopy, + sizeof( TX_DESC_ENTRY_t ) * iRemainder ); + + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req += iRemainder; + } + + if( pAdapter->TxRing.txDmaReadyToSend.bits.serv_req == 0 ) + { + if( pAdapter->TxRing.txDmaReadyToSend.value ) + { + pMpTcb->WrIndex.value = NUM_DESC_PER_RING_TX - 1; + } + else + { + pMpTcb->WrIndex.value = 0x400 | ( NUM_DESC_PER_RING_TX - 1 ); + } + } + else + { + pMpTcb->WrIndex.value = pAdapter->TxRing.txDmaReadyToSend.value - 1; + } + + spin_lock_irqsave( &pAdapter->TCBSendQLock, lockflags2 ); + + if( pAdapter->TxRing.CurrSendTail ) + { + pAdapter->TxRing.CurrSendTail->Next = pMpTcb; + } + else + { + pAdapter->TxRing.CurrSendHead = pMpTcb; + } + + pAdapter->TxRing.CurrSendTail = pMpTcb; + + DBG_ASSERT( pMpTcb->Next == NULL ); + + pAdapter->TxRing.nBusySend++; + + spin_unlock_irqrestore( &pAdapter->TCBSendQLock, lockflags2 ); + + + /************************************************************************** + Write the new write pointer back to the device. + *************************************************************************/ + pAdapter->CSRAddress->txdma.service_request.value = + pAdapter->TxRing.txDmaReadyToSend.value; + + + /************************************************************************** + For Gig only, we use Tx Interrupt coalescing. Enable the software + timer to wake us up if this packet isn't followed by N more. + *************************************************************************/ + if( pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS ) + { + pAdapter->CSRAddress->global.watchdog_timer = + pAdapter->RegistryTxTimeInterval * NANO_IN_A_MICRO; + } + + spin_unlock_irqrestore( &pAdapter->SendHWLock, lockflags1 ); + + + DBG_TX_LEAVE( et131x_dbginfo ); + return 0; +} +/*===========================================================================*/ + + + + +/* NOTE - For now, keep this older version of NICSendPacket around for + reference, even though it's not used */ +#if 0 + +/****************************************************************************** + ROUTINE: NICSendPacket + ****************************************************************************** + DESCRIPTION: + NIC specific send handler. This version of the send routine is designed + for version A silicon. + + Assumption: Send spinlock has been acquired + + PARAMETERS : + pAdapter - pointer to our adapter + pMpTcb - pointer to MP_TCB + pFragList - pointer to the frag list to be filled + + RETURNS : + 0 on succes, errno on failure + + *****************************************************************************/ +int nic_send_packet( ET131X_ADAPTER *pAdapter, PMP_TCB pMpTcb ) +{ + UINT32 loopIndex, fragIndex, loopEnd; + UINT32 iSplitFirstElement = 0; + UINT32 SegmentSize = 0; + TX_DESC_ENTRY_t CurDesc; + TX_DESC_ENTRY_t *CurDescPostCopy = NULL; + UINT32 SlotsAvailable; + TXDMA_SERVICE_COMPLETE_t ServiceComplete = pAdapter->CSRAddress->txdma.NewServiceComplete; + unsigned int lockflags1, lockflags2; + struct sk_buff *pPacket = pMpTcb->Packet; + UINT32 FragListCount = skb_shinfo( pPacket )->nr_frags + 1; + struct skb_frag_struct *pFragList = &skb_shinfo( pPacket )->frags[0]; + PGLOBAL_t pGbl; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "nic_send_packet" ); + DBG_TX_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Attempt to fix TWO hardware bugs: + 1) NEVER write an odd number of descriptors. + 2) If packet length is less than NIC_MIN_PACKET_SIZE, then pad the + packet to NIC_MIN_PACKET_SIZE bytes by adding a new last + descriptor IN HALF DUPLEX MODE ONLY + NOTE that (2) interacts with (1). If the packet is less than + NIC_MIN_PACKET_SIZE bytes then we will append a descriptor. Therefore + if it is even now, it will eventually end up odd, and so will need + adjusting. + + VLAN tags get involved since VLAN tags add another one or two + segments. + *************************************************************************/ + DBG_TX( et131x_dbginfo, + "pMpTcb->PacketLength: %d\n", pMpTcb->PacketLength ); + + if(( pAdapter->uiDuplexMode == 0 ) && ( pMpTcb->PacketLength < NIC_MIN_PACKET_SIZE )) + { + DBG_TX( et131x_dbginfo, + "HALF DUPLEX mode AND len < MIN_PKT_SIZE\n" ); + if(( FragListCount & 0x1 ) == 0 ) + { + DBG_TX( et131x_dbginfo, + "Even number of descs, split 1st elem\n" ); + iSplitFirstElement = 1; + //SegmentSize = pFragList[0].size / 2; + SegmentSize = ( pPacket->len - pPacket->data_len ) / 2; + } + } + else if( FragListCount & 0x1 ) + { + DBG_TX( et131x_dbginfo, + "Odd number of descs, split 1st elem\n" ); + + iSplitFirstElement = 1; + //SegmentSize = pFragList[0].size / 2; + SegmentSize = ( pPacket->len - pPacket->data_len ) / 2; + } + + spin_lock_irqsave( &pAdapter->SendHWLock, lockflags1 ); + + if( pAdapter->TxRing.txDmaReadyToSend.bits.serv_req_wrap == + ServiceComplete.bits.serv_cpl_wrap ) + { + /********************************************************************** + The ring hasn't wrapped. Slots available should be (RING_SIZE) - + the difference between the two pointers. + *********************************************************************/ + SlotsAvailable = NUM_DESC_PER_RING_TX - + ( pAdapter->TxRing.txDmaReadyToSend.bits.serv_req - ServiceComplete.bits.serv_cpl); + } + else + { + /********************************************************************** + The ring has wrapped. Slots available should be the difference + between the two pointers. + *********************************************************************/ + SlotsAvailable = ServiceComplete.bits.serv_cpl - + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req; + } + + if(( FragListCount + iSplitFirstElement ) > SlotsAvailable ) + { + DBG_WARNING( et131x_dbginfo, "Not Enough Space in Tx Desc Ring\n" ); + spin_unlock_irqrestore( &pAdapter->SendHWLock, lockflags1 ); + return -ENOMEM; + } + + loopEnd = ( FragListCount ) + iSplitFirstElement; + fragIndex = 0; + + DBG_TX( et131x_dbginfo, + "TCB : 0x%p\n", pMpTcb ); + DBG_TX( et131x_dbginfo, + "Packet (SKB) : 0x%p\t Packet->len: %d\t Packet->data_len: %d\n", + pPacket, pPacket->len, pPacket->data_len ); + + DBG_TX( et131x_dbginfo, + "FragListCount : %d\t iSplitFirstElement: %d\t loopEnd:%d\n", + FragListCount, iSplitFirstElement, loopEnd ); + + for( loopIndex = 0; loopIndex < loopEnd; loopIndex++ ) + { + if( loopIndex > iSplitFirstElement ) + { + fragIndex++; + } + + DBG_TX( et131x_dbginfo, "In loop, loopIndex: %d\t fragIndex: %d\n", + loopIndex, fragIndex ); + + + /********************************************************************** + If there is something in this element, let's get a descriptor from + the ring and get the necessary data + *********************************************************************/ + DBG_TX( et131x_dbginfo, + "Packet Length %d," + "filling desc entry %d\n", + pPacket->len, + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req ); + + // NOTE - Should we do a paranoia check here to make sure the fragment + // actually has a length? It's HIGHLY unlikely the fragment would + // contain no data... + if( 1 ) + { + // NOTE - Currently always getting 32-bit addrs, and dma_addr_t is + // only 32-bit, so leave "high" ptr value out for now + CurDesc.DataBufferPtrHigh = 0; + + CurDesc.word2.value = 0; + CurDesc.word3.value = 0; + + + if( fragIndex == 0 ) + { + if( iSplitFirstElement ) + { + DBG_TX( et131x_dbginfo, "Split first element: YES\n" ); + + if( loopIndex == 0 ) + { + DBG_TX( et131x_dbginfo, + "Got fragment of length %d, fragIndex: %d\n", + pPacket->len - pPacket->data_len, + fragIndex ); + DBG_TX( et131x_dbginfo, + "SegmentSize: %d\n", SegmentSize ); + + + CurDesc.word2.bits.length_in_bytes = SegmentSize; + CurDesc.DataBufferPtrLow = pci_map_single( pAdapter->pdev, + pPacket->data, + SegmentSize, + PCI_DMA_TODEVICE ); + DBG_TX( et131x_dbginfo, "pci_map_single() returns: 0x%08x\n", + CurDesc.DataBufferPtrLow ); + } + else + { + DBG_TX( et131x_dbginfo, + "Got fragment of length %d, fragIndex: %d\n", + pPacket->len - pPacket->data_len, + fragIndex ); + DBG_TX( et131x_dbginfo, + "Leftover Size: %d\n", + ( pPacket->len - pPacket->data_len - SegmentSize )); + + CurDesc.word2.bits.length_in_bytes = (( pPacket->len - pPacket->data_len ) - + SegmentSize ); + CurDesc.DataBufferPtrLow = pci_map_single( pAdapter->pdev, + ( pPacket->data + SegmentSize ), + ( pPacket->len - pPacket->data_len - + SegmentSize ), + PCI_DMA_TODEVICE ); + DBG_TX( et131x_dbginfo, "pci_map_single() returns: 0x%08x\n", + CurDesc.DataBufferPtrLow ); + } + } + else + { + DBG_TX( et131x_dbginfo, "Split first element: NO\n" ); + + CurDesc.word2.bits.length_in_bytes = pPacket->len - + pPacket->data_len; + + CurDesc.DataBufferPtrLow = pci_map_single( pAdapter->pdev, + pPacket->data, + ( pPacket->len - + pPacket->data_len ), + PCI_DMA_TODEVICE ); + DBG_TX( et131x_dbginfo, "pci_map_single() returns: 0x%08x\n", + CurDesc.DataBufferPtrLow ); + } + } + else + { + + CurDesc.word2.bits.length_in_bytes = pFragList[fragIndex - 1].size; + CurDesc.DataBufferPtrLow = pci_map_page( pAdapter->pdev, + pFragList[fragIndex - 1].page, + pFragList[fragIndex - 1].page_offset, + pFragList[fragIndex - 1].size, + PCI_DMA_TODEVICE ); + DBG_TX( et131x_dbginfo, "pci_map_page() returns: 0x%08x\n", + CurDesc.DataBufferPtrLow ); + } + + if( loopIndex == 0 ) + { + /************************************************************** + This is the first descriptor of the packet + *************************************************************/ + /************************************************************** + Set the "f" bit to indicate this is the first descriptor in + the packet. + *************************************************************/ + DBG_TX( et131x_dbginfo, "This is our FIRST descriptor\n" ); + CurDesc.word3.bits.f = 1; + + pMpTcb->WrIndexStart = pAdapter->TxRing.txDmaReadyToSend; + } + + if(( loopIndex == (loopEnd - 1 )) && + ( pAdapter->uiDuplexMode || + ( pMpTcb->PacketLength >= NIC_MIN_PACKET_SIZE ))) + { + /************************************************************** + This is the Last descriptor of the packet + *************************************************************/ + DBG_TX( et131x_dbginfo, "THIS is our LAST descriptor\n" ); + + if( pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS ) + { + if( ++pAdapter->TxRing.TxPacketsSinceLastinterrupt >= pAdapter->RegistryTxNumBuffers ) + { + CurDesc.word3.value = 0x5; + pAdapter->TxRing.TxPacketsSinceLastinterrupt = 0; + } + else + { + CurDesc.word3.value = 0x1; + } + } + else + { + CurDesc.word3.value = 0x5; + } + + + /************************************************************** + Following index will be used during freeing of packet + *************************************************************/ + pMpTcb->WrIndex = pAdapter->TxRing.txDmaReadyToSend; + pMpTcb->PacketStaleCount = 0; + } + + /****************************************************************** + Copy the descriptor (filled above) into the descriptor ring + at the next free entry. Advance the "next free entry" variable + *****************************************************************/ + memcpy( pAdapter->TxRing.pTxDescRingVa + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req, + &CurDesc, + sizeof( TX_DESC_ENTRY_t )); + + CurDescPostCopy = pAdapter->TxRing.pTxDescRingVa + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req; + + DBG_TX( et131x_dbginfo, "CURRENT DESCRIPTOR\n" ); + DBG_TX( et131x_dbginfo, "\tAddress : 0x%p\n", CurDescPostCopy ); + DBG_TX( et131x_dbginfo, "\tDataBufferPtrHigh : 0x%08x\n", CurDescPostCopy->DataBufferPtrHigh ); + DBG_TX( et131x_dbginfo, "\tDataBufferPtrLow : 0x%08x\n", CurDescPostCopy->DataBufferPtrLow ); + DBG_TX( et131x_dbginfo, "\tword2 : 0x%08x\n", CurDescPostCopy->word2.value ); + DBG_TX( et131x_dbginfo, "\tword3 : 0x%08x\n", CurDescPostCopy->word3.value ); + + + if( ++pAdapter->TxRing.txDmaReadyToSend.bits.serv_req >= NUM_DESC_PER_RING_TX ) + { + if( pAdapter->TxRing.txDmaReadyToSend.bits.serv_req_wrap ) + { + pAdapter->TxRing.txDmaReadyToSend.value = 0; + } + else + { + pAdapter->TxRing.txDmaReadyToSend.value = 0x400; + } + } + } + } + + + if(( pAdapter->uiDuplexMode == 0 ) && ( pMpTcb->PacketLength < NIC_MIN_PACKET_SIZE )) + { + // NOTE - Same 32/64-bit issue as above... + CurDesc.DataBufferPtrHigh = 0x0; + CurDesc.DataBufferPtrLow = pAdapter->TxRing.pTxDummyBlkPa; + CurDesc.word2.value = 0; + + if( pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS ) + { + if( ++pAdapter->TxRing.TxPacketsSinceLastinterrupt >= pAdapter->RegistryTxNumBuffers ) + { + CurDesc.word3.value = 0x5; + pAdapter->TxRing.TxPacketsSinceLastinterrupt = 0; + } + else + { + CurDesc.word3.value = 0x1; + } + } + else + { + CurDesc.word3.value = 0x5; + } + + CurDesc.word2.bits.length_in_bytes = NIC_MIN_PACKET_SIZE - pMpTcb->PacketLength; + + pMpTcb->WrIndex = pAdapter->TxRing.txDmaReadyToSend; + + memcpy( pAdapter->TxRing.pTxDescRingVa + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req, + &CurDesc, + sizeof( TX_DESC_ENTRY_t )); + + CurDescPostCopy = pAdapter->TxRing.pTxDescRingVa + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req; + + DBG_TX( et131x_dbginfo, "CURRENT DESCRIPTOR\n" ); + DBG_TX( et131x_dbginfo, "\tAddress : 0x%p\n", CurDescPostCopy ); + DBG_TX( et131x_dbginfo, "\tDataBufferPtrHigh : 0x%08x\n", CurDescPostCopy->DataBufferPtrHigh ); + DBG_TX( et131x_dbginfo, "\tDataBufferPtrLow : 0x%08x\n", CurDescPostCopy->DataBufferPtrLow ); + DBG_TX( et131x_dbginfo, "\tword2 : 0x%08x\n", CurDescPostCopy->word2.value ); + DBG_TX( et131x_dbginfo, "\tword3 : 0x%08x\n", CurDescPostCopy->word3.value ); + + + if( ++pAdapter->TxRing.txDmaReadyToSend.bits.serv_req >= NUM_DESC_PER_RING_TX ) + { + if( pAdapter->TxRing.txDmaReadyToSend.bits.serv_req_wrap ) + { + pAdapter->TxRing.txDmaReadyToSend.value = 0; + } + else + { + pAdapter->TxRing.txDmaReadyToSend.value = 0x400; + } + } + + DBG_TX( et131x_dbginfo, "Padding descriptor %d by %d bytes\n", + //pAdapter->TxRing.txDmaReadyToSend.value, + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req, + NIC_MIN_PACKET_SIZE - pMpTcb->PacketLength ); + } + + spin_lock_irqsave( &pAdapter->TCBSendQLock, lockflags2 ); + + if( pAdapter->TxRing.CurrSendTail ) + { + pAdapter->TxRing.CurrSendTail->Next = pMpTcb; + } + else + { + pAdapter->TxRing.CurrSendHead = pMpTcb; + } + + pAdapter->TxRing.CurrSendTail = pMpTcb; + + DBG_ASSERT( pMpTcb->Next == NULL ); + + pAdapter->TxRing.nBusySend++; + + spin_unlock_irqrestore( &pAdapter->TCBSendQLock, lockflags2 ); + + + /************************************************************************** + Write the new write pointer back to the device. + *************************************************************************/ + pAdapter->CSRAddress->txdma.service_request.value = pAdapter->TxRing.txDmaReadyToSend.value; + +#if ( ET131X_DBG == 1 ) + DumpDeviceBlock( DBG_TX_ON, pAdapter, 1 ); +#endif + + + /************************************************************************** + Map a local pointer to the global section of the JAGCore + *************************************************************************/ + pGbl = &pAdapter->CSRAddress->global; + + + /************************************************************************** + For Gig only, we use Tx Interrupt coalescing. Enable the software + timer to wake us up if this packet isn't followed by N more. + *************************************************************************/ + if( pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS ) + { + pAdapter->CSRAddress->global.watchdog_timer = + pAdapter->RegistryTxTimeInterval * NANO_IN_A_MICRO; + } + + spin_unlock_irqrestore( &pAdapter->SendHWLock, lockflags1 ); + + + DBG_TX_LEAVE( et131x_dbginfo ); + return 0; +} +/*===========================================================================*/ +#endif + + + + +/****************************************************************************** + ROUTINE: et131x_free_send_packet + ****************************************************************************** + DESCRIPTION: + Recycle a MP_TCB and complete the packet if necessary + + Assumption: Send spinlock has been acquired + + PARAMETERS : + pAdapter - pointer to our adapter + pMpTcb - pointer to MP_TCB + + RETURNS : + NONE + + *****************************************************************************/ +__inline void et131x_free_send_packet( ET131X_ADAPTER *pAdapter, PMP_TCB pMpTcb ) +{ + unsigned long lockflags; + TX_DESC_ENTRY_t *desc = NULL; + struct net_device_stats *stats = &pAdapter->net_stats; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_free_send_packet" ); + + + if( MP_TEST_FLAG( pMpTcb, fMP_DEST_BROAD ) ) + { + atomic_inc( &pAdapter->Stats.brdcstxmt ); + } + else if( MP_TEST_FLAG( pMpTcb, fMP_DEST_MULTI )) + { + atomic_inc( &pAdapter->Stats.multixmt ); + } + else + { + atomic_inc( &pAdapter->Stats.unixmt ); + } + + if( pMpTcb->Packet ) + { + stats->tx_bytes += pMpTcb->Packet->len; + + + /********************************************************************** + Iterate through the TX descriptors on the ring corresponding to this + packet and umap the fragments they point to + *********************************************************************/ + DBG_TX( et131x_dbginfo, "Unmap descriptors Here\n" ); + + DBG_TX( et131x_dbginfo, + "TCB : 0x%p\n", pMpTcb ); + + DBG_TX( et131x_dbginfo, + "TCB Next : 0x%p\n", pMpTcb->Next ); + + DBG_TX( et131x_dbginfo, + "TCB PacketLength : %d\n", pMpTcb->PacketLength ); + + DBG_TX( et131x_dbginfo, + "TCB WrIndex.value : 0x%08x\n", pMpTcb->WrIndexStart.value ); + DBG_TX( et131x_dbginfo, + "TCB WrIndex.serv_req : %d\n", pMpTcb->WrIndexStart.bits.serv_req ); + + DBG_TX( et131x_dbginfo, + "TCB WrIndex.value : 0x%08x\n", pMpTcb->WrIndex.value ); + DBG_TX( et131x_dbginfo, + "TCB WrIndex.serv_req : %d\n", pMpTcb->WrIndex.bits.serv_req ); + + do + { + desc = (TX_DESC_ENTRY_t *)( pAdapter->TxRing.pTxDescRingVa + + pMpTcb->WrIndexStart.bits.serv_req ); + + DBG_TX( et131x_dbginfo, "CURRENT DESCRIPTOR\n" ); + DBG_TX( et131x_dbginfo, "\tAddress : 0x%p\n", desc ); + DBG_TX( et131x_dbginfo, "\tDataBufferPtrHigh : 0x%08x\n", desc->DataBufferPtrHigh ); + DBG_TX( et131x_dbginfo, "\tDataBufferPtrLow : 0x%08x\n", desc->DataBufferPtrLow ); + DBG_TX( et131x_dbginfo, "\tword2 : 0x%08x\n", desc->word2.value ); + DBG_TX( et131x_dbginfo, "\tword3 : 0x%08x\n", desc->word3.value ); + + pci_unmap_single( pAdapter->pdev, + desc->DataBufferPtrLow, + desc->word2.value, + PCI_DMA_TODEVICE ); + + if( ++pMpTcb->WrIndexStart.bits.serv_req >= NUM_DESC_PER_RING_TX ) + { + if( pMpTcb->WrIndexStart.bits.serv_req_wrap ) + { + pMpTcb->WrIndexStart.value = 0; + } + else + { + pMpTcb->WrIndexStart.value = 0x400; + } + } + } + while( desc != ( pAdapter->TxRing.pTxDescRingVa + + pMpTcb->WrIndex.bits.serv_req )); + + DBG_TX( et131x_dbginfo, + "Free Packet (SKB) : 0x%p\n", pMpTcb->Packet ); + + dev_kfree_skb_any( pMpTcb->Packet ); + } + + memset( pMpTcb, 0, sizeof( MP_TCB )); + + + /************************************************************************** + Add the TCB to the Ready Q + *************************************************************************/ + spin_lock_irqsave( &pAdapter->TCBReadyQLock, lockflags ); + + pAdapter->Stats.opackets++; + + if( pAdapter->TxRing.TCBReadyQueueTail ) + { + pAdapter->TxRing.TCBReadyQueueTail->Next = pMpTcb; + } + else + { + /********************************************************************** + Apparently ready Q is empty. + *********************************************************************/ + pAdapter->TxRing.TCBReadyQueueHead = pMpTcb; + } + + pAdapter->TxRing.TCBReadyQueueTail = pMpTcb; + + spin_unlock_irqrestore( &pAdapter->TCBReadyQLock, lockflags ); + + + DBG_ASSERT( pAdapter->TxRing.nBusySend >= 0 ); + + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_free_busy_send_packets + ****************************************************************************** + DESCRIPTION: + Free and complete the stopped active sends + + Assumption: Send spinlock has been acquired + + PARAMETERS : + pAdapter - pointer to our adapter + + RETURNS : + NONE + + *****************************************************************************/ +void et131x_free_busy_send_packets( ET131X_ADAPTER *pAdapter ) +{ + PMP_TCB pMpTcb; + struct list_head *pEntry; + struct sk_buff *pPacket = NULL; + unsigned long lockflags; + UINT32 FreeCounter = 0; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_free_busy_send_packets" ); + DBG_ENTER( et131x_dbginfo ); + + + while( !list_empty( &pAdapter->TxRing.SendWaitQueue )) + { + spin_lock_irqsave( &pAdapter->SendWaitLock, lockflags ); + + pAdapter->TxRing.nWaitSend--; + spin_unlock_irqrestore( &pAdapter->SendWaitLock, lockflags ); + + pEntry = pAdapter->TxRing.SendWaitQueue.next; + + pPacket = NULL; + } + + pAdapter->TxRing.nWaitSend = 0; + + + /************************************************************************** + Any packets being sent? Check the first TCB on the send list + *************************************************************************/ + spin_lock_irqsave( &pAdapter->TCBSendQLock, lockflags ); + + pMpTcb = pAdapter->TxRing.CurrSendHead; + + while(( pMpTcb != NULL ) && ( FreeCounter < NUM_TCB )) + { + PMP_TCB pNext = pMpTcb->Next; + + pAdapter->TxRing.CurrSendHead = pNext; + + if( pNext == NULL ) + { + pAdapter->TxRing.CurrSendTail = NULL; + } + + pAdapter->TxRing.nBusySend--; + + spin_unlock_irqrestore( &pAdapter->TCBSendQLock, lockflags ); + + DBG_VERBOSE( et131x_dbginfo, + "pMpTcb = 0x%p\n", + pMpTcb ); + + FreeCounter++; + MP_FREE_SEND_PACKET_FUN( pAdapter, pMpTcb ); + + spin_lock_irqsave( &pAdapter->TCBSendQLock, lockflags ); + + pMpTcb = pAdapter->TxRing.CurrSendHead; + } + + if( FreeCounter == NUM_TCB ) + { + DBG_ERROR( et131x_dbginfo, + "MpFreeBusySendPackets exitted loop for a bad reason\n" ); + BUG(); + } + + spin_unlock_irqrestore( &pAdapter->TCBSendQLock, lockflags ); + + pAdapter->TxRing.nBusySend = 0; + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_handle_send_interrupt + ****************************************************************************** + DESCRIPTION: + Interrupt handler for sending processing + Re-claim the send resources, complete sends and get more to send from + the send wait queue + + Assumption: Send spinlock has been acquired + + PARAMETERS : + pAdapter - pointer to our adapter + + RETURNS : + Nothing + + *****************************************************************************/ +void et131x_handle_send_interrupt( ET131X_ADAPTER *pAdapter ) +{ + DBG_FUNC( "et131x_handle_send_interrupt" ); + DBG_TX_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Mark as completed any packets which have been sent by the device. + *************************************************************************/ + et131x_update_tcb_list( pAdapter ); + + + /************************************************************************** + If we queued any transmits because we didn't have any TCBs earlier, + dequeue and send those packets now, as long as we have free TCBs. + *************************************************************************/ + et131x_check_send_wait_list( pAdapter ); + + + DBG_TX_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_update_tcb_list + ****************************************************************************** + DESCRIPTION: + Helper routine for Send Interrupt handler. Re-claims the send + resources and completes sends. Can also be called as part of the NIC + send routine when the "ServiceComplete" indication has wrapped. + + Assumption: + + PARAMETERS : + pAdapter - pointer to our adapter + + RETURNS : + Nothing + + *****************************************************************************/ +void et131x_update_tcb_list( ET131X_ADAPTER *pAdapter ) +{ + unsigned long lockflags; + TXDMA_SERVICE_COMPLETE_t ServiceComplete = pAdapter->CSRAddress->txdma.NewServiceComplete; + PMP_TCB pMpTcb; + /*-----------------------------------------------------------------------*/ + + + /************************************************************************** + Has the ring wrapped? Process any descriptors that do not have + the same "wrap" indicator as the current completion indicator + *************************************************************************/ + spin_lock_irqsave( &pAdapter->TCBSendQLock, lockflags ); + + pMpTcb = pAdapter->TxRing.CurrSendHead; + + if( ServiceComplete.bits.serv_cpl_wrap ) + { + while( pMpTcb && + !pMpTcb->WrIndex.bits.serv_req_wrap && + ( pMpTcb->WrIndex.bits.serv_req > ServiceComplete.bits.serv_cpl )) + { + PMP_TCB pNext = pMpTcb->Next; + + pAdapter->TxRing.CurrSendHead = pNext; + + if( pNext == NULL ) + { + pAdapter->TxRing.CurrSendTail = NULL; + } + + pAdapter->TxRing.nBusySend--; + + spin_unlock_irqrestore( &pAdapter->TCBSendQLock, lockflags ); + MP_FREE_SEND_PACKET_FUN( pAdapter, pMpTcb ); + spin_lock_irqsave( &pAdapter->TCBSendQLock, lockflags ); + + + /****************************************************************** + Goto the next packet + *****************************************************************/ + pMpTcb = pAdapter->TxRing.CurrSendHead; + } + } + else + { + while( pMpTcb && + pMpTcb->WrIndex.bits.serv_req_wrap && + ( pMpTcb->WrIndex.bits.serv_req > ServiceComplete.bits.serv_cpl )) + { + PMP_TCB pNext = pMpTcb->Next; + + pAdapter->TxRing.CurrSendHead = pNext; + + if( pNext == NULL ) + { + pAdapter->TxRing.CurrSendTail = NULL; + } + + pAdapter->TxRing.nBusySend--; + + spin_unlock_irqrestore( &pAdapter->TCBSendQLock, lockflags ); + MP_FREE_SEND_PACKET_FUN( pAdapter, pMpTcb ); + spin_lock_irqsave( &pAdapter->TCBSendQLock, lockflags ); + + + /****************************************************************** + Goto the next packet + *****************************************************************/ + pMpTcb = pAdapter->TxRing.CurrSendHead; + } + } + + while( pMpTcb && + ( ServiceComplete.bits.serv_cpl_wrap == pMpTcb->WrIndex.bits.serv_req_wrap ) && + ( ServiceComplete.bits.serv_cpl > pMpTcb->WrIndex.bits.serv_req )) + { + PMP_TCB pNext = pMpTcb->Next; + + pAdapter->TxRing.CurrSendHead = pNext; + + if( pNext == NULL ) + { + pAdapter->TxRing.CurrSendTail = NULL; + } + + pAdapter->TxRing.nBusySend--; + + spin_unlock_irqrestore( &pAdapter->TCBSendQLock, lockflags ); + MP_FREE_SEND_PACKET_FUN( pAdapter, pMpTcb ); + spin_lock_irqsave( &pAdapter->TCBSendQLock, lockflags ); + + + /********************************************************************** + Goto the next packet + *********************************************************************/ + pMpTcb = pAdapter->TxRing.CurrSendHead; + } + + + /* Wake up the queue when we hit a low-water mark */ + if( pAdapter->TxRing.nBusySend <= ( NUM_TCB / 3 )) + { + netif_wake_queue( pAdapter->netdev ); + } + + spin_unlock_irqrestore( &pAdapter->TCBSendQLock, lockflags ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_check_send_wait_list + ****************************************************************************** + DESCRIPTION: + Helper routine for the interrupt handler. Takes packets from the send + wait queue and posts them to the device (if room available). + + Assumption: + + PARAMETERS : + pAdapter - pointer to our adapter + + RETURNS : + Nothing + + *****************************************************************************/ +void et131x_check_send_wait_list( ET131X_ADAPTER *pAdapter ) +{ + unsigned long lockflags; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_check_send_wait_list" ); + + + spin_lock_irqsave( &pAdapter->SendWaitLock, lockflags ); + + while( !list_empty( &pAdapter->TxRing.SendWaitQueue ) && + MP_TCB_RESOURCES_AVAILABLE( pAdapter )) + { + struct list_head *pEntry; + + DBG_VERBOSE( et131x_dbginfo, + "Tx packets on the wait queue\n" ); + + pEntry = pAdapter->TxRing.SendWaitQueue.next; + + pAdapter->TxRing.nWaitSend--; + + DBG_WARNING( et131x_dbginfo, + "MpHandleSendInterrupt - sent a queued pkt. Waiting %d\n", + pAdapter->TxRing.nWaitSend ); + } + + spin_unlock_irqrestore( &pAdapter->SendWaitLock, lockflags ); + + return; +} +/*===========================================================================*/ + --- linux-2.6.28.orig/ubuntu/et131x/ET1310_phy.h +++ linux-2.6.28/ubuntu/et131x/ET1310_phy.h @@ -0,0 +1,1228 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_phy.h - Defines, structs, enums, prototypes, etc. pertaining to the + * PHY. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2006/01/18 22:18:33 $ + $Revision: 1.10 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef _ET1310_PHY_H_ +#define _ET1310_PHY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/****************************************************************************** + INCLUDES + *****************************************************************************/ +#include "ET1310_common.h" + + + + +#define TRUEPHY_SUCCESS 0 +#define TRUEPHY_FAILURE 1 +typedef void *TRUEPHY_HANDLE; +typedef void *TRUEPHY_PLATFORM_HANDLE; +typedef void *TRUEPHY_OSAL_HANDLE; + + + + +/****************************************************************************** + CONSTANTS for PHY Register + *****************************************************************************/ +/* MI Register Addresses */ +#define MI_CONTROL_REG 0 +#define MI_STATUS_REG 1 +#define MI_PHY_IDENTIFIER_1_REG 2 +#define MI_PHY_IDENTIFIER_2_REG 3 +#define MI_AUTONEG_ADVERTISEMENT_REG 4 +#define MI_AUTONEG_LINK_PARTNER_ABILITY_REG 5 +#define MI_AUTONEG_EXPANSION_REG 6 +#define MI_AUTONEG_NEXT_PAGE_TRANSMIT_REG 7 +#define MI_LINK_PARTNER_NEXT_PAGE_REG 8 +#define MI_1000BASET_CONTROL_REG 9 +#define MI_1000BASET_STATUS_REG 10 +#define MI_RESERVED11_REG 11 +#define MI_RESERVED12_REG 12 +#define MI_RESERVED13_REG 13 +#define MI_RESERVED14_REG 14 +#define MI_EXTENDED_STATUS_REG 15 + +/* VMI Register Addresses */ +#define VMI_RESERVED16_REG 16 +#define VMI_RESERVED17_REG 17 +#define VMI_RESERVED18_REG 18 +#define VMI_LOOPBACK_CONTROL_REG 19 +#define VMI_RESERVED20_REG 20 +#define VMI_MI_CONTROL_REG 21 +#define VMI_PHY_CONFIGURATION_REG 22 +#define VMI_PHY_CONTROL_REG 23 +#define VMI_INTERRUPT_MASK_REG 24 +#define VMI_INTERRUPT_STATUS_REG 25 +#define VMI_PHY_STATUS_REG 26 +#define VMI_LED_CONTROL_1_REG 27 +#define VMI_LED_CONTROL_2_REG 28 +#define VMI_RESERVED29_REG 29 +#define VMI_RESERVED30_REG 30 +#define VMI_RESERVED31_REG 31 + + + + +/****************************************************************************** + PHY Register Mapping(MI) Management Interface Regs + *****************************************************************************/ +typedef struct _MI_REGS_t +{ + UCHAR bmcr; // Basic mode control reg(Reg 0x00) + UCHAR bmsr; // Basic mode status reg(Reg 0x01) + UCHAR idr1; // Phy identifier reg 1(Reg 0x02) + UCHAR idr2; // Phy identifier reg 2(Reg 0x03) + UCHAR anar; // Auto-Negotiation advertisement(Reg 0x04) + UCHAR anlpar; // Auto-Negotiation link Partner Ability(Reg 0x05) + UCHAR aner; // Auto-Negotiation expansion reg(Reg 0x06) + UCHAR annptr; // Auto-Negotiation next page transmit reg(Reg 0x07) + UCHAR lpnpr; // link partner next page reg(Reg 0x08) + UCHAR gcr; // Gigabit basic mode control reg(Reg 0x09) + UCHAR gsr; // Gigabit basic mode status reg(Reg 0x0A) + UCHAR mi_res1[4]; // Future use by MI working group(Reg 0x0B - 0x0E) + UCHAR esr; // Extended status reg(Reg 0x0F) + UCHAR mi_res2[3]; // Future use by MI working group(Reg 0x10 - 0x12) + UCHAR loop_ctl; // Loopback Control Reg(Reg 0x13) + UCHAR mi_res3; // Future use by MI working group(Reg 0x14) + UCHAR mcr; // MI Control Reg(Reg 0x15) + UCHAR pcr; // Configuration Reg(Reg 0x16) + UCHAR phy_ctl; // PHY Control Reg(Reg 0x17) + UCHAR imr; // Interrupt Mask Reg(Reg 0x18) + UCHAR isr; // Interrupt Status Reg(Reg 0x19) + UCHAR psr; // PHY Status Reg(Reg 0x1A) + UCHAR lcr1; // LED Control 1 Reg(Reg 0x1B) + UCHAR lcr2; // LED Control 2 Reg(Reg 0x1C) + UCHAR mi_res4[3]; // Future use by MI working group(Reg 0x1D - 0x1F) +} +MI_REGS_t, *PMI_REGS_t; + + + + +/****************************************************************************** + MI Register 0: Basic mode control register + *****************************************************************************/ +typedef union _MI_BMCR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 reset:1; //bit 15 + UINT16 loopback:1; //bit 14 + UINT16 speed_sel:1; //bit 13 + UINT16 enable_autoneg:1; //bit 12 + UINT16 power_down:1; //bit 11 + UINT16 isolate:1; //bit 10 + UINT16 restart_autoneg:1; //bit 9 + UINT16 duplex_mode:1; //bit 8 + UINT16 col_test:1; //bit 7 + UINT16 speed_1000_sel:1; //bit 6 + UINT16 res1:6; //bits 0-5 + #else + UINT16 res1:6; //bits 0-5 + UINT16 speed_1000_sel:1; //bit 6 + UINT16 col_test:1; //bit 7 + UINT16 duplex_mode:1; //bit 8 + UINT16 restart_autoneg:1; //bit 9 + UINT16 isolate:1; //bit 10 + UINT16 power_down:1; //bit 11 + UINT16 enable_autoneg:1; //bit 12 + UINT16 speed_sel:1; //bit 13 + UINT16 loopback:1; //bit 14 + UINT16 reset:1; //bit 15 + #endif + } bits; +} +MI_BMCR_t, *PMI_BMCR_t; + + + + +/****************************************************************************** + MI Register 1: Basic mode status register + *****************************************************************************/ +typedef union _MI_BMSR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 link_100T4:1; //bit 15 + UINT16 link_100fdx:1; //bit 14 + UINT16 link_100hdx:1; //bit 13 + UINT16 link_10fdx:1; //bit 12 + UINT16 link_10hdx:1; //bit 11 + UINT16 link_100T2fdx:1; //bit 10 + UINT16 link_100T2hdx:1; //bit 9 + UINT16 extend_status:1; //bit 8 + UINT16 res1:1; //bit 7 + UINT16 preamble_supress:1; //bit 6 + UINT16 auto_neg_complete:1; //bit 5 + UINT16 remote_fault:1; //bit 4 + UINT16 auto_neg_able:1; //bit 3 + UINT16 link_status:1; //bit 2 + UINT16 jabber_detect:1; //bit 1 + UINT16 ext_cap:1; //bit 0 + #else + UINT16 ext_cap:1; //bit 0 + UINT16 jabber_detect:1; //bit 1 + UINT16 link_status:1; //bit 2 + UINT16 auto_neg_able:1; //bit 3 + UINT16 remote_fault:1; //bit 4 + UINT16 auto_neg_complete:1; //bit 5 + UINT16 preamble_supress:1; //bit 6 + UINT16 res1:1; //bit 7 + UINT16 extend_status:1; //bit 8 + UINT16 link_100T2hdx:1; //bit 9 + UINT16 link_100T2fdx:1; //bit 10 + UINT16 link_10hdx:1; //bit 11 + UINT16 link_10fdx:1; //bit 12 + UINT16 link_100hdx:1; //bit 13 + UINT16 link_100fdx:1; //bit 14 + UINT16 link_100T4:1; //bit 15 + #endif + } bits; +} +MI_BMSR_t, *PMI_BMSR_t; + + + + +/****************************************************************************** + MI Register 2: Physical Identifier 1 + *****************************************************************************/ +typedef union _MI_IDR1_t +{ + UINT16 value; + struct + { + UINT16 ieee_address:16; //0x0282 default(bits 0-15) + } bits; +} +MI_IDR1_t, *PMI_IDR1_t; + + + + +/****************************************************************************** + MI Register 3: Physical Identifier 2 + *****************************************************************************/ +typedef union _MI_IDR2_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 ieee_address:6; //111100 default(bits 10-15) + UINT16 model_no:6; //000001 default(bits 4-9) + UINT16 rev_no:4; //0010 default(bits 0-3) + #else + UINT16 rev_no:4; //0010 default(bits 0-3) + UINT16 model_no:6; //000001 default(bits 4-9) + UINT16 ieee_address:6; //111100 default(bits 10-15) + #endif + } bits; +} +MI_IDR2_t, *PMI_IDR2_t; + + + + +/****************************************************************************** + MI Register 4: Auto-negotiation advertisement register + *****************************************************************************/ +typedef union _MI_ANAR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 np_indication:1; //bit 15 + UINT16 res2:1; //bit 14 + UINT16 remote_fault:1; //bit 13 + UINT16 res1:1; //bit 12 + UINT16 cap_asmpause:1; //bit 11 + UINT16 cap_pause:1; //bit 10 + UINT16 cap_100T4:1; //bit 9 + UINT16 cap_100fdx:1; //bit 8 + UINT16 cap_100hdx:1; //bit 7 + UINT16 cap_10fdx:1; //bit 6 + UINT16 cap_10hdx:1; //bit 5 + UINT16 selector:5; //bits 0-4 + #else + UINT16 selector:5; //bits 0-4 + UINT16 cap_10hdx:1; //bit 5 + UINT16 cap_10fdx:1; //bit 6 + UINT16 cap_100hdx:1; //bit 7 + UINT16 cap_100fdx:1; //bit 8 + UINT16 cap_100T4:1; //bit 9 + UINT16 cap_pause:1; //bit 10 + UINT16 cap_asmpause:1; //bit 11 + UINT16 res1:1; //bit 12 + UINT16 remote_fault:1; //bit 13 + UINT16 res2:1; //bit 14 + UINT16 np_indication:1; //bit 15 + #endif + } bits; +} +MI_ANAR_t, *PMI_ANAR_t; + + + + +/****************************************************************************** + MI Register 5: Auto-negotiation link partner advertisement register + *****************************************************************************/ +typedef struct _MI_ANLPAR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 np_indication:1; //bit 15 + UINT16 acknowledge:1; //bit 14 + UINT16 remote_fault:1; //bit 13 + UINT16 res1:1; //bit 12 + UINT16 cap_asmpause:1; //bit 11 + UINT16 cap_pause:1; //bit 10 + UINT16 cap_100T4:1; //bit 9 + UINT16 cap_100fdx:1; //bit 8 + UINT16 cap_100hdx:1; //bit 7 + UINT16 cap_10fdx:1; //bit 6 + UINT16 cap_10hdx:1; //bit 5 + UINT16 selector:5; //bits 0-4 + #else + UINT16 selector:5; //bits 0-4 + UINT16 cap_10hdx:1; //bit 5 + UINT16 cap_10fdx:1; //bit 6 + UINT16 cap_100hdx:1; //bit 7 + UINT16 cap_100fdx:1; //bit 8 + UINT16 cap_100T4:1; //bit 9 + UINT16 cap_pause:1; //bit 10 + UINT16 cap_asmpause:1; //bit 11 + UINT16 res1:1; //bit 12 + UINT16 remote_fault:1; //bit 13 + UINT16 acknowledge:1; //bit 14 + UINT16 np_indication:1; //bit 15 + #endif + } bits; +} +MI_ANLPAR_t, *PMI_ANLPAR_t; + + + + +/****************************************************************************** + MI Register 6: Auto-negotiation expansion register + *****************************************************************************/ +typedef union _MI_ANER_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 res:11; //bits 5-15 + UINT16 pdf:1; //bit 4 + UINT16 lp_np_able:1; //bit 3 + UINT16 np_able:1; //bit 2 + UINT16 page_rx:1; //bit 1 + UINT16 lp_an_able:1; //bit 0 + #else + UINT16 lp_an_able:1; //bit 0 + UINT16 page_rx:1; //bit 1 + UINT16 np_able:1; //bit 2 + UINT16 lp_np_able:1; //bit 3 + UINT16 pdf:1; //bit 4 + UINT16 res:11; //bits 5-15 + #endif + } bits; +} +MI_ANER_t, *PMI_ANER_t; + + + + +/****************************************************************************** + MI Register 7: Auto-negotiation next page transmit reg(0x07) + *****************************************************************************/ +typedef union _MI_ANNPTR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 np:1; //bit 15 + UINT16 res1:1; //bit 14 + UINT16 msg_page:1; //bit 13 + UINT16 ack2:1; //bit 12 + UINT16 toggle:1; //bit 11 + UINT16 msg:11; //bits 0-10 + #else + UINT16 msg:11; //bits 0-10 + UINT16 toggle:1; //bit 11 + UINT16 ack2:1; //bit 12 + UINT16 msg_page:1; //bit 13 + UINT16 res1:1; //bit 14 + UINT16 np:1; //bit 15 + #endif + } bits; +} +MI_ANNPTR_t, *PMI_ANNPTR_t; + + + + +/****************************************************************************** + MI Register 8: Link Partner Next Page Reg(0x08) + *****************************************************************************/ +typedef union _MI_LPNPR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 np:1; //bit 15 + UINT16 ack:1; //bit 14 + UINT16 msg_page:1; //bit 13 + UINT16 ack2:1; //bit 12 + UINT16 toggle:1; //bit 11 + UINT16 msg:11; //bits 0-10 + #else + UINT16 msg:11; //bits 0-10 + UINT16 toggle:1; //bit 11 + UINT16 ack2:1; //bit 12 + UINT16 msg_page:1; //bit 13 + UINT16 ack:1; //bit 14 + UINT16 np:1; //bit 15 + #endif + } bits; +} +MI_LPNPR_t, *PMI_LPNPR_t; + + + + +/****************************************************************************** + MI Register 9: 1000BaseT Control Reg(0x09) + *****************************************************************************/ +typedef union _MI_GCR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 test_mode:3; //bits 13-15 + UINT16 ms_config_en:1; //bit 12 + UINT16 ms_value:1; //bit 11 + UINT16 port_type:1; //bit 10 + UINT16 link_1000fdx:1; //bit 9 + UINT16 link_1000hdx:1; //bit 8 + UINT16 res:8; //bit 0-7 + #else + UINT16 res:8; //bit 0-7 + UINT16 link_1000hdx:1; //bit 8 + UINT16 link_1000fdx:1; //bit 9 + UINT16 port_type:1; //bit 10 + UINT16 ms_value:1; //bit 11 + UINT16 ms_config_en:1; //bit 12 + UINT16 test_mode:3; //bits 13-15 + #endif + } bits; +} +MI_GCR_t, *PMI_GCR_t; + + + + +/****************************************************************************** + MI Register 10: 1000BaseT Status Reg(0x0A) + *****************************************************************************/ +typedef union _MI_GSR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 ms_config_fault:1; //bit 15 + UINT16 ms_resolve:1; //bit 14 + UINT16 local_rx_status:1; //bit 13 + UINT16 remote_rx_status:1; //bit 12 + UINT16 link_1000fdx:1; //bit 11 + UINT16 link_1000hdx:1; //bit 10 + UINT16 res:2; //bits 8-9 + UINT16 idle_err_cnt:8; //bits 0-7 + #else + UINT16 idle_err_cnt:8; //bits 0-7 + UINT16 res:2; //bits 8-9 + UINT16 link_1000hdx:1; //bit 10 + UINT16 link_1000fdx:1; //bit 11 + UINT16 remote_rx_status:1; //bit 12 + UINT16 local_rx_status:1; //bit 13 + UINT16 ms_resolve:1; //bit 14 + UINT16 ms_config_fault:1; //bit 15 + #endif + } bits; +} +MI_GSR_t, *PMI_GSR_t; + + + + +/****************************************************************************** + MI Register 11 - 14: Reserved Regs(0x0B - 0x0E) + *****************************************************************************/ +typedef union _MI_RES_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 res15:1; //bit 15 + UINT16 res14:1; //bit 14 + UINT16 res13:1; //bit 13 + UINT16 res12:1; //bit 12 + UINT16 res11:1; //bit 11 + UINT16 res10:1; //bit 10 + UINT16 res9:1; //bit 9 + UINT16 res8:1; //bit 8 + UINT16 res7:1; //bit 7 + UINT16 res6:1; //bit 6 + UINT16 res5:1; //bit 5 + UINT16 res4:1; //bit 4 + UINT16 res3:1; //bit 3 + UINT16 res2:1; //bit 2 + UINT16 res1:1; //bit 1 + UINT16 res0:1; //bit 0 + #else + UINT16 res0:1; //bit 0 + UINT16 res1:1; //bit 1 + UINT16 res2:1; //bit 2 + UINT16 res3:1; //bit 3 + UINT16 res4:1; //bit 4 + UINT16 res5:1; //bit 5 + UINT16 res6:1; //bit 6 + UINT16 res7:1; //bit 7 + UINT16 res8:1; //bit 8 + UINT16 res9:1; //bit 9 + UINT16 res10:1; //bit 10 + UINT16 res11:1; //bit 11 + UINT16 res12:1; //bit 12 + UINT16 res13:1; //bit 13 + UINT16 res14:1; //bit 14 + UINT16 res15:1; //bit 15 + #endif + } bits; +} +MI_RES_t, *PMI_RES_t; + + + + +/****************************************************************************** + MI Register 15: Extended status Reg(0x0F) + *****************************************************************************/ +typedef union _MI_ESR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 link_1000Xfdx:1; //bit 15 + UINT16 link_1000Xhdx:1; //bit 14 + UINT16 link_1000fdx:1; //bit 13 + UINT16 link_1000hdx:1; //bit 12 + UINT16 res:12; //bit 0-11 + #else + UINT16 res:12; //bit 0-11 + UINT16 link_1000hdx:1; //bit 12 + UINT16 link_1000fdx:1; //bit 13 + UINT16 link_1000Xhdx:1; //bit 14 + UINT16 link_1000Xfdx:1; //bit 15 + #endif + } bits; +} +MI_ESR_t, *PMI_ESR_t; + + + + +/****************************************************************************** + MI Register 16 - 18: Reserved Reg(0x10-0x12) + *****************************************************************************/ + + + + +/****************************************************************************** + MI Register 19: Loopback Control Reg(0x13) + *****************************************************************************/ +typedef union _MI_LCR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 mii_en:1; //bit 15 + UINT16 pcs_en:1; //bit 14 + UINT16 pmd_en:1; //bit 13 + UINT16 all_digital_en:1; //bit 12 + UINT16 replica_en:1; //bit 11 + UINT16 line_driver_en:1; //bit 10 + UINT16 res:10; //bit 0-9 + #else + UINT16 res:10; //bit 0-9 + UINT16 line_driver_en:1; //bit 10 + UINT16 replica_en:1; //bit 11 + UINT16 all_digital_en:1; //bit 12 + UINT16 pmd_en:1; //bit 13 + UINT16 pcs_en:1; //bit 14 + UINT16 mii_en:1; //bit 15 + #endif + } bits; +} +MI_LCR_t, *PMI_LCR_t; + + + + +/****************************************************************************** + MI Register 20: Reserved Reg(0x14) + *****************************************************************************/ + + + + +/****************************************************************************** + MI Register 21: Management Interface Control Reg(0x15) + *****************************************************************************/ +typedef union _MI_MICR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 res1:5; //bits 11-15 + UINT16 mi_error_count:7; //bits 4-10 + UINT16 res2:1; //bit 3 + UINT16 ignore_10g_fr:1; //bit 2 + UINT16 res3:1; //bit 1 + UINT16 preamble_supress_en:1; //bit 0 + #else + UINT16 preamble_supress_en:1; //bit 0 + UINT16 res3:1; //bit 1 + UINT16 ignore_10g_fr:1; //bit 2 + UINT16 res2:1; //bit 3 + UINT16 mi_error_count:7; //bits 4-10 + UINT16 res1:5; //bits 11-15 + #endif + } bits; +} +MI_MICR_t, *PMI_MICR_t; + + + + +/****************************************************************************** + MI Register 22: PHY Configuration Reg(0x16) + *****************************************************************************/ +typedef union _MI_PHY_CONFIG_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 crs_tx_en:1; //bit 15 + UINT16 res1:1; //bit 14 + UINT16 tx_fifo_depth:2; //bits 12-13 + UINT16 speed_downshift:2; //bits 10-11 + UINT16 pbi_detect:1; //bit 9 + UINT16 tbi_rate:1; //bit 8 + UINT16 alternate_np:1; //bit 7 + UINT16 group_mdio_en:1; //bit 6 + UINT16 tx_clock_en:1; //bit 5 + UINT16 sys_clock_en:1; //bit 4 + UINT16 res2:1; //bit 3 + UINT16 mac_if_mode:3; //bits 0-2 + #else + UINT16 mac_if_mode:3; //bits 0-2 + UINT16 res2:1; //bit 3 + UINT16 sys_clock_en:1; //bit 4 + UINT16 tx_clock_en:1; //bit 5 + UINT16 group_mdio_en:1; //bit 6 + UINT16 alternate_np:1; //bit 7 + UINT16 tbi_rate:1; //bit 8 + UINT16 pbi_detect:1; //bit 9 + UINT16 speed_downshift:2; //bits 10-11 + UINT16 tx_fifo_depth:2; //bits 12-13 + UINT16 res1:1; //bit 14 + UINT16 crs_tx_en:1; //bit 15 + #endif + } bits; +} +MI_PHY_CONFIG_t, *PMI_PHY_CONFIG_t; + + + + +/****************************************************************************** + MI Register 23: PHY CONTROL Reg(0x17) + *****************************************************************************/ +typedef union _MI_PHY_CONTROL_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 res1:1; //bit 15 + UINT16 tdr_en:1; //bit 14 + UINT16 res2:1; //bit 13 + UINT16 downshift_attempts:2; //bits 11-12 + UINT16 res3:5; //bit 6-10 + UINT16 jabber_10baseT:1; //bit 5 + UINT16 sqe_10baseT:1; //bit 4 + UINT16 tp_loopback_10baseT:1; //bit 3 + UINT16 preamble_gen_en:1; //bit 2 + UINT16 res4:1; //bit 1 + UINT16 force_int:1; //bit 0 + #else + UINT16 force_int:1; //bit 0 + UINT16 res4:1; //bit 1 + UINT16 preamble_gen_en:1; //bit 2 + UINT16 tp_loopback_10baseT:1; //bit 3 + UINT16 sqe_10baseT:1; //bit 4 + UINT16 jabber_10baseT:1; //bit 5 + UINT16 res3:5; //bit 6-10 + UINT16 downshift_attempts:2; //bits 11-12 + UINT16 res2:1; //bit 13 + UINT16 tdr_en:1; //bit 14 + UINT16 res1:1; //bit 15 + #endif + } bits; +} +MI_PHY_CONTROL_t, *PMI_PHY_CONTROL_t; + + + + +/****************************************************************************** + MI Register 24: Interrupt Mask Reg(0x18) + *****************************************************************************/ +typedef union _MI_IMR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 res1:6; //bits 10-15 + UINT16 mdio_sync_lost:1; //bit 9 + UINT16 autoneg_status:1; //bit 8 + UINT16 hi_bit_err:1; //bit 7 + UINT16 np_rx:1; //bit 6 + UINT16 err_counter_full:1; //bit 5 + UINT16 fifo_over_underflow:1; //bit 4 + UINT16 rx_status:1; //bit 3 + UINT16 link_status:1; //bit 2 + UINT16 automatic_speed:1; //bit 1 + UINT16 int_en:1; //bit 0 + #else + UINT16 int_en:1; //bit 0 + UINT16 automatic_speed:1; //bit 1 + UINT16 link_status:1; //bit 2 + UINT16 rx_status:1; //bit 3 + UINT16 fifo_over_underflow:1; //bit 4 + UINT16 err_counter_full:1; //bit 5 + UINT16 np_rx:1; //bit 6 + UINT16 hi_bit_err:1; //bit 7 + UINT16 autoneg_status:1; //bit 8 + UINT16 mdio_sync_lost:1; //bit 9 + UINT16 res1:6; //bits 10-15 + #endif + } bits; +} +MI_IMR_t, *PMI_IMR_t; + + + + +/****************************************************************************** + MI Register 25: Interrupt Status Reg(0x19) + *****************************************************************************/ +typedef union _MI_ISR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 res1:6; //bits 10-15 + UINT16 mdio_sync_lost:1; //bit 9 + UINT16 autoneg_status:1; //bit 8 + UINT16 hi_bit_err:1; //bit 7 + UINT16 np_rx:1; //bit 6 + UINT16 err_counter_full:1; //bit 5 + UINT16 fifo_over_underflow:1; //bit 4 + UINT16 rx_status:1; //bit 3 + UINT16 link_status:1; //bit 2 + UINT16 automatic_speed:1; //bit 1 + UINT16 int_en:1; //bit 0 + #else + UINT16 int_en:1; //bit 0 + UINT16 automatic_speed:1; //bit 1 + UINT16 link_status:1; //bit 2 + UINT16 rx_status:1; //bit 3 + UINT16 fifo_over_underflow:1; //bit 4 + UINT16 err_counter_full:1; //bit 5 + UINT16 np_rx:1; //bit 6 + UINT16 hi_bit_err:1; //bit 7 + UINT16 autoneg_status:1; //bit 8 + UINT16 mdio_sync_lost:1; //bit 9 + UINT16 res1:6; //bits 10-15 + #endif + } bits; +} +MI_ISR_t, *PMI_ISR_t; + + + + +/****************************************************************************** + MI Register 26: PHY Status Reg(0x1A) + *****************************************************************************/ +typedef union _MI_PSR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 res1:1; //bit 15 + UINT16 autoneg_fault:2; //bit 13-14 + UINT16 autoneg_status:1; //bit 12 + UINT16 mdi_x_status:1; //bit 11 + UINT16 polarity_status:1; //bit 10 + UINT16 speed_status:2; //bits 8-9 + UINT16 duplex_status:1; //bit 7 + UINT16 link_status:1; //bit 6 + UINT16 tx_status:1; //bit 5 + UINT16 rx_status:1; //bit 4 + UINT16 collision_status:1; //bit 3 + UINT16 autoneg_en:1; //bit 2 + UINT16 pause_en:1; //bit 1 + UINT16 asymmetric_dir:1; //bit 0 + #else + UINT16 asymmetric_dir:1; //bit 0 + UINT16 pause_en:1; //bit 1 + UINT16 autoneg_en:1; //bit 2 + UINT16 collision_status:1; //bit 3 + UINT16 rx_status:1; //bit 4 + UINT16 tx_status:1; //bit 5 + UINT16 link_status:1; //bit 6 + UINT16 duplex_status:1; //bit 7 + UINT16 speed_status:2; //bits 8-9 + UINT16 polarity_status:1; //bit 10 + UINT16 mdi_x_status:1; //bit 11 + UINT16 autoneg_status:1; //bit 12 + UINT16 autoneg_fault:2; //bit 13-14 + UINT16 res1:1; //bit 15 + #endif + } bits; +} +MI_PSR_t, *PMI_PSR_t; + + + + +/****************************************************************************** + MI Register 27: LED Control Reg 1(0x1B) + *****************************************************************************/ +typedef union _MI_LCR1_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 res1:2; //bits 14-15 + UINT16 led_dup_indicate:2; //bits 12-13 + UINT16 led_10baseT:2; //bits 10-11 + UINT16 led_collision:2; //bits 8-9 + UINT16 res2:2; //bits 6-7 + UINT16 res3:2; //bits 4-5 + UINT16 pulse_dur:2; //bits 2-3 + UINT16 pulse_stretch1:1; //bit 1 + UINT16 pulse_stretch0:1; //bit 0 + #else + UINT16 pulse_stretch0:1; //bit 0 + UINT16 pulse_stretch1:1; //bit 1 + UINT16 pulse_dur:2; //bits 2-3 + UINT16 res3:2; //bits 4-5 + UINT16 res2:2; //bits 6-7 + UINT16 led_collision:2; //bits 8-9 + UINT16 led_10baseT:2; //bits 10-11 + UINT16 led_dup_indicate:2; //bits 12-13 + UINT16 res1:2; //bits 14-15 + #endif + } bits; +} +MI_LCR1_t, *PMI_LCR1_t; + + + + +/****************************************************************************** + MI Register 28: LED Control Reg 2(0x1C) + *****************************************************************************/ +typedef union _MI_LCR2_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 led_link:4; //bits 12-15 + UINT16 led_tx_rx:4; //bits 8-11 + UINT16 led_100BaseTX:4; //bits 4-7 + UINT16 led_1000BaseT:4; //bits 0-3 + #else + UINT16 led_1000BaseT:4; //bits 0-3 + UINT16 led_100BaseTX:4; //bits 4-7 + UINT16 led_tx_rx:4; //bits 8-11 + UINT16 led_link:4; //bits 12-15 + #endif + } bits; +} +MI_LCR2_t, *PMI_LCR2_t; + + + + +/****************************************************************************** + MI Register 29 - 31: Reserved Reg(0x1D - 0x1E) + *****************************************************************************/ + + + + +/****************************************************************************** + TruePHY headers + *****************************************************************************/ +typedef struct _TRUEPHY_ACCESS_MI_REGS_ +{ + TRUEPHY_HANDLE hTruePhy; + INT32 nPhyId; + UCHAR bReadWrite; + PUCHAR pbyRegs; + PUCHAR pwData; + INT32 nRegCount; +} +TRUEPHY_ACCESS_MI_REGS, *PTRUEPHY_ACCESS_MI_REGS; + + + + +/****************************************************************************** + TruePHY headers + *****************************************************************************/ +typedef struct _TAG_TPAL_ACCESS_MI_REGS_ +{ + UINT32 nPhyId; + UCHAR bReadWrite; + UINT32 nRegCount; + UINT16 Data[4096]; + UCHAR Regs[4096]; +} TPAL_ACCESS_MI_REGS, *PTPAL_ACCESS_MI_REGS; + + + + +/****************************************************************************** + Required TruePHY PROTOTYPES + *****************************************************************************/ +/****************************************************************************** + TYPE DEFINITIONS + *****************************************************************************/ +typedef TRUEPHY_HANDLE TPAL_HANDLE; + + +/****************************************************************************** + Forward declaration of the private adapter structure + *****************************************************************************/ +struct et131x_adapter; + + +/////////////////////////////////////////////////////////////////////////////// +//// TruePHY Platform Specific Functions //// +/////////////////////////////////////////////////////////////////////////////// +//TRUEPHY_HANDLE TPAL_PlatformInit( void * pPlatformInfo, +// PTRUEPHY_PLATFORM_FUNCTIONS pPlatFunctions ); + +INT32 TPAL_MiAccessRegs( TPAL_HANDLE hPlatform, + INT32 nPhyId, + PUCHAR pbyAccessFlags, + PUCHAR pbyRegisters, + PUINT16 pwData, + PUINT16 pwAndMasks, + PUINT16 pwOrMasks, + INT32 nRegCount ); + +void TPAL_PlatformExit( TRUEPHY_PLATFORM_HANDLE hPlatform ); + + + + +/////////////////////////////////////////////////////////////////////////////// +//// OS Specific Functions //// +/////////////////////////////////////////////////////////////////////////////// +void *TPAL_AllocMem( TRUEPHY_PLATFORM_HANDLE hPlatform, u_long ulNumBytes ); +void TPAL_FreeMem( TRUEPHY_PLATFORM_HANDLE hPlatform, void *pMemBlock ); +void TPAL_Sleep( TRUEPHY_PLATFORM_HANDLE hPlatform, u_long ulMsec ); +u_long TPAL_GetSystemUpTime( TRUEPHY_PLATFORM_HANDLE hPlatform ); +void TPAL_GetLinkStatusInfo( struct et131x_adapter *adapter ); + +INT32 TPAL_SetPhy10HalfDuplex( struct et131x_adapter *adapter ); +INT32 TPAL_SetPhy10FullDuplex( struct et131x_adapter *adapter ); +void TPAL_SetPhy10Force( struct et131x_adapter * pAdapter ); +INT32 TPAL_SetPhy100HalfDuplex( struct et131x_adapter *adapter ); +INT32 TPAL_SetPhy100FullDuplex( struct et131x_adapter *adapter ); +void TPAL_SetPhy100Force( struct et131x_adapter * pAdapter ); +INT32 TPAL_SetPhy1000FullDuplex( struct et131x_adapter *adapter); +INT32 TPAL_SetPhyAutoNeg( struct et131x_adapter *adapter ); + + + + +/****************************************************************************** + PROTOTYPES for ET1310_phy.c + *****************************************************************************/ +int et131x_xcvr_find( struct et131x_adapter *adapter ); + +int et131x_setphy_normal( struct et131x_adapter *adapter ); +INT32 et131x_xcvr_init( struct et131x_adapter *adapter ); + +INT32 MiRead( struct et131x_adapter *adapter, + UINT8 xcvrAddr, + UINT8 xcvrReg, + UINT16 *value ); + +INT32 MiWrite( struct et131x_adapter *adapter, + UINT8 xcvrAddr, + UINT8 xcvReg, + UINT16 value ); + +void et131x_Mii_check( struct et131x_adapter *pAdapter, + MI_BMSR_t bmsr, + MI_BMSR_t bmsr_ints ); + + + + +/****************************************************************************** + This last is not strictly required (the driver could call the TPAL + version instead), but this sets the adapter up correctly, and calls the + access routine indirectly. This protects the driver from changes in TPAL. + *****************************************************************************/ +void SetPhy_10BaseTHalfDuplex( struct et131x_adapter *adapter ); + + + + +/****************************************************************************** + Defines for PHY access routines + *****************************************************************************/ +// Define bit operation flags +#define TRUEPHY_BIT_CLEAR 0 +#define TRUEPHY_BIT_SET 1 +#define TRUEPHY_BIT_READ 2 + +// Define read/write operation flags +#ifndef TRUEPHY_READ +#define TRUEPHY_READ 0 +#define TRUEPHY_WRITE 1 +#define TRUEPHY_MASK 2 +#endif + +// Define speeds +#define TRUEPHY_SPEED_10MBPS 0 +#define TRUEPHY_SPEED_100MBPS 1 +#define TRUEPHY_SPEED_1000MBPS 2 + +// Define duplex modes +#define TRUEPHY_DUPLEX_HALF 0 +#define TRUEPHY_DUPLEX_FULL 1 + +// Define master/slave configuration values +#define TRUEPHY_CFG_SLAVE 0 +#define TRUEPHY_CFG_MASTER 1 + +// Define MDI/MDI-X settings +#define TRUEPHY_MDI 0 +#define TRUEPHY_MDIX 1 +#define TRUEPHY_AUTO_MDI_MDIX 2 + +// Define 10Base-T link polarities +#define TRUEPHY_POLARITY_NORMAL 0 +#define TRUEPHY_POLARITY_INVERTED 1 + +// Define auto-negotiation results +#define TRUEPHY_ANEG_NOT_COMPLETE 0 +#define TRUEPHY_ANEG_COMPLETE 1 +#define TRUEPHY_ANEG_DISABLED 2 + +/* Define duplex advertisment flags */ +#define TRUEPHY_ADV_DUPLEX_NONE 0x00 +#define TRUEPHY_ADV_DUPLEX_FULL 0x01 +#define TRUEPHY_ADV_DUPLEX_HALF 0x02 +#define TRUEPHY_ADV_DUPLEX_BOTH \ + (TRUEPHY_ADV_DUPLEX_FULL | TRUEPHY_ADV_DUPLEX_HALF) + +#define PHY_CONTROL 0x00 //#define TRU_MI_CONTROL_REGISTER 0 +#define PHY_STATUS 0x01 //#define TRU_MI_STATUS_REGISTER 1 +#define PHY_ID_1 0x02 //#define TRU_MI_PHY_IDENTIFIER_1_REGISTER 2 +#define PHY_ID_2 0x03 //#define TRU_MI_PHY_IDENTIFIER_2_REGISTER 3 +#define PHY_AUTO_ADVERTISEMENT 0x04 //#define TRU_MI_ADVERTISEMENT_REGISTER 4 +#define PHY_AUTO_LINK_PARTNER 0x05 //#define TRU_MI_LINK_PARTNER_ABILITY_REGISTER 5 +#define PHY_AUTO_EXPANSION 0x06 //#define TRU_MI_EXPANSION_REGISTER 6 +#define PHY_AUTO_NEXT_PAGE_TX 0x07 //#define TRU_MI_NEXT_PAGE_TRANSMIT_REGISTER 7 +#define PHY_LINK_PARTNER_NEXT_PAGE 0x08 //#define TRU_MI_LINK_PARTNER_NEXT_PAGE_REGISTER 8 +#define PHY_1000_CONTROL 0x09 //#define TRU_MI_1000BASET_CONTROL_REGISTER 9 +#define PHY_1000_STATUS 0x0A //#define TRU_MI_1000BASET_STATUS_REGISTER 10 + + +#define PHY_EXTENDED_STATUS 0x0F //#define TRU_MI_EXTENDED_STATUS_REGISTER 15 + +// some defines for modem registers that seem to be 'reserved' +#define PHY_INDEX_REG 0x10 +#define PHY_DATA_REG 0x11 + +#define PHY_MPHY_CONTROL_REG 0x12 //#define TRU_VMI_MPHY_CONTROL_REGISTER 18 + +#define PHY_LOOPBACK_CONTROL 0x13 //#define TRU_VMI_LOOPBACK_CONTROL_1_REGISTER 19 + //#define TRU_VMI_LOOPBACK_CONTROL_2_REGISTER 20 +#define PHY_REGISTER_MGMT_CONTROL 0x15 //#define TRU_VMI_MI_SEQ_CONTROL_REGISTER 21 +#define PHY_CONFIG 0x16 //#define TRU_VMI_CONFIGURATION_REGISTER 22 +#define PHY_PHY_CONTROL 0x17 //#define TRU_VMI_PHY_CONTROL_REGISTER 23 +#define PHY_INTERRUPT_MASK 0x18 //#define TRU_VMI_INTERRUPT_MASK_REGISTER 24 +#define PHY_INTERRUPT_STATUS 0x19 //#define TRU_VMI_INTERRUPT_STATUS_REGISTER 25 +#define PHY_PHY_STATUS 0x1A //#define TRU_VMI_PHY_STATUS_REGISTER 26 +#define PHY_LED_1 0x1B //#define TRU_VMI_LED_CONTROL_1_REGISTER 27 +#define PHY_LED_2 0x1C //#define TRU_VMI_LED_CONTROL_2_REGISTER 28 + //#define TRU_VMI_LINK_CONTROL_REGISTER 29 + //#define TRU_VMI_TIMING_CONTROL_REGISTER + + + + +/****************************************************************************** + Prototypes for PHY access routines + *****************************************************************************/ +void ET1310_PhyInit( struct et131x_adapter *pAdapter ); +void ET1310_PhyReset( struct et131x_adapter *pAdapter ); +void ET1310_PhyPowerDown( struct et131x_adapter *pAdapter, BOOL_t down ); +void ET1310_PhyAutoNeg( struct et131x_adapter *pAdapter, BOOL_t enable ); +void ET1310_PhyDuplexMode( struct et131x_adapter *pAdapter, UINT16 duplex ); +void ET1310_PhySpeedSelect( struct et131x_adapter *pAdapter, UINT16 speed ); +void ET1310_PhyAdvertise1000BaseT( struct et131x_adapter *pAdapter, UINT16 duplex ); +void ET1310_PhyAdvertise100BaseT( struct et131x_adapter *pAdapter, UINT16 duplex ); +void ET1310_PhyAdvertise10BaseT( struct et131x_adapter *pAdapter, UINT16 duplex ); +void ET1310_PhyLinkStatus( struct et131x_adapter *pAdapter, + UCHAR *ucLinkStatus, + UINT32 *uiAutoNeg, + UINT32 *uiLinkSpeed, + UINT32 *uiDuplexMode, + UINT32 *uiMdiMdix, + UINT32 *uiMasterSlave, + UINT32 *uiPolarity ); +void ET1310_PhyAndOrReg( struct et131x_adapter *pAdapter, + UINT16 regnum, + UINT16 andMask, + UINT16 orMask ); +void ET1310_PhyAccessMiBit( struct et131x_adapter *pAdapter, + UINT16 action, + UINT16 regnum, + UINT16 bitnum, + UINT8 *value ); + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ET1310_PHY_H_ */ --- linux-2.6.28.orig/ubuntu/et131x/et131x_config.c +++ linux-2.6.28/ubuntu/et131x/et131x_config.c @@ -0,0 +1,383 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_config.c - Handles parsing of configuration data during + * initialization. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/10/28 18:43:46 $ + $Revision: 1.8 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" +#include "et131x_initpci.h" + +#include "ET1310_tx.h" + + + +/****************************************************************************** + Data for debugging facilities + *****************************************************************************/ +#ifdef ET131X_DBG +extern dbg_info_t *et131x_dbginfo; +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + Defines for Parameter Default/Min/Max vaules + *****************************************************************************/ +#define PARM_SPEED_DUPLEX_DEF 0 +#define PARM_SPEED_DUPLEX_MIN 0 +#define PARM_SPEED_DUPLEX_MAX 5 + +#define PARM_VLAN_TAG_DEF 0 +#define PARM_VLAN_TAG_MIN 0 +#define PARM_VLAN_TAG_MAX 4095 + +#define PARM_FLOW_CTL_DEF 0 +#define PARM_FLOW_CTL_MIN 0 +#define PARM_FLOW_CTL_MAX 3 + +#define PARM_WOL_LINK_DEF 3 +#define PARM_WOL_LINK_MIN 0 +#define PARM_WOL_LINK_MAX 3 + +#define PARM_WOL_MATCH_DEF 7 +#define PARM_WOL_MATCH_MIN 0 +#define PARM_WOL_MATCH_MAX 7 + +#define PARM_JUMBO_PKT_DEF 1514 +#define PARM_JUMBO_PKT_MIN 1514 +#define PARM_JUMBO_PKT_MAX 9216 + +#define PARM_PHY_COMA_DEF 0 +#define PARM_PHY_COMA_MIN 0 +#define PARM_PHY_COMA_MAX 1 + +#define PARM_RX_NUM_BUFS_DEF 4 +#define PARM_RX_NUM_BUFS_MIN 1 +#define PARM_RX_NUM_BUFS_MAX 64 + +#define PARM_RX_TIME_INT_DEF 10 +#define PARM_RX_TIME_INT_MIN 2 +#define PARM_RX_TIME_INT_MAX 320 + +#define PARM_TX_NUM_BUFS_DEF 4 +#define PARM_TX_NUM_BUFS_MIN 1 +#define PARM_TX_NUM_BUFS_MAX 40 + +#define PARM_TX_TIME_INT_DEF 40 +#define PARM_TX_TIME_INT_MIN 1 +#define PARM_TX_TIME_INT_MAX 140 + +#define PARM_RX_MEM_END_DEF 0x2bc +#define PARM_RX_MEM_END_MIN 0 +#define PARM_RX_MEM_END_MAX 0x3ff + +#define PARM_MAC_STAT_DEF 1 +#define PARM_MAC_STAT_MIN 0 +#define PARM_MAC_STAT_MAX 1 + +#define PARM_SC_GAIN_DEF 7 +#define PARM_SC_GAIN_MIN 0 +#define PARM_SC_GAIN_MAX 7 + +#define PARM_PM_WOL_DEF 0 +#define PARM_PM_WOL_MIN 0 +#define PARM_PM_WOL_MAX 1 + +#define PARM_NMI_DISABLE_DEF 0 +#define PARM_NMI_DISABLE_MIN 0 +#define PARM_NMI_DISABLE_MAX 2 + +#define PARM_DMA_CACHE_DEF 0 +#define PARM_DMA_CACHE_MIN 0 +#define PARM_DMA_CACHE_MAX 15 + +#define PARM_PHY_LOOPBK_DEF 0 +#define PARM_PHY_LOOPBK_MIN 0 +#define PARM_PHY_LOOPBK_MAX 1 + + +#define PARM_MAC_ADDRESS_DEF { 0x00, 0x05, 0x3d, 0x00, 0x02, 0x00 } + + + + +/****************************************************************************** + Module parameter for disabling NMI + *****************************************************************************/ +static u32 et131x_nmi_disable = PARM_NMI_DISABLE_DEF; + +module_param ( et131x_nmi_disable, uint, 0 ); +MODULE_PARM_DESC( et131x_nmi_disable, "Disable NMI (0-2) [0]" ); + + +/***************************************************************************** + Module parameter for manual speed setting + ****************************************************************************/ +static u32 et131x_speed_set = PARM_SPEED_DUPLEX_DEF; +module_param (et131x_speed_set, uint, 0); +MODULE_PARM_DESC( et131x_speed_set, "Set Link speed and dublex manually (0-5) [0] \n 1 : 10Mb Half-Duplex \n 2 : 10Mb Full-Duplex \n 3 : 100Mb Half-Duplex \n 4 : 100Mb Full-Duplex \n 5 : 1000Mb Full-Duplex \n 0 : Auto Speed Auto Dublex"); + + +/****************************************************************************** + ROUTINE : et131x_config_parse + ****************************************************************************** + + DESCRIPTION : Parses a configuration from some location (module + parameters, for example) into the private adapter struct + + PARAMETERS : pAdapter - pointer to the private adapter struct + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_config_parse( ET131X_ADAPTER *pAdapter ) +{ + UINT8 macAddrDef[] = PARM_MAC_ADDRESS_DEF; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_config_parse" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + The NDIS driver uses the registry to store persistent per-device + configuration, and reads this configuration into the appropriate + elements of the private adapter structure on initialization. Because + Linux has no analog to the registry, use this function to initialize the + private adapter structure with a default configuration. + + One other possibility is to use a series of module parameters which can + be passed in by the caller when the module is initialized. However, this + implementation does not allow for seperate configurations in the event + multiple devices are present, and hence will not suffice. + + If another method is derived which addresses this problem, this is where + it should be implemented. + *************************************************************************/ + + /************************************************************************** + Set the private adapter struct with default values for the corresponding + parameters + *************************************************************************/ + if( et131x_speed_set != PARM_SPEED_DUPLEX_DEF ) + { + DBG_VERBOSE( et131x_dbginfo, "Speed set manually to : %d \n",et131x_speed_set ); + pAdapter->SpeedDuplex = et131x_speed_set; + } + else + { + pAdapter->SpeedDuplex = PARM_SPEED_DUPLEX_DEF; + } + + // pAdapter->SpeedDuplex = PARM_SPEED_DUPLEX_DEF; + + pAdapter->RegistryVlanTag = PARM_VLAN_TAG_DEF; + pAdapter->RegistryFlowControl = PARM_FLOW_CTL_DEF; + pAdapter->RegistryWOLLink = PARM_WOL_LINK_DEF; + pAdapter->RegistryWOLMatch = PARM_WOL_MATCH_DEF; + pAdapter->RegistryJumboPacket = PARM_JUMBO_PKT_DEF; + pAdapter->RegistryPhyComa = PARM_PHY_COMA_DEF; + pAdapter->RegistryRxNumBuffers = PARM_RX_NUM_BUFS_DEF; + pAdapter->RegistryRxTimeInterval = PARM_RX_TIME_INT_DEF; + pAdapter->RegistryTxNumBuffers = PARM_TX_NUM_BUFS_DEF; + pAdapter->RegistryTxTimeInterval = PARM_TX_TIME_INT_DEF; + pAdapter->RegistryRxMemEnd = PARM_RX_MEM_END_DEF; + pAdapter->RegistryMACStat = PARM_MAC_STAT_DEF; + pAdapter->RegistrySCGain = PARM_SC_GAIN_DEF; + pAdapter->RegistryPMWOL = PARM_PM_WOL_DEF; + + if( et131x_nmi_disable != PARM_NMI_DISABLE_DEF ) + { + pAdapter->RegistryNMIDisable = et131x_nmi_disable; + } + else + { + pAdapter->RegistryNMIDisable = PARM_NMI_DISABLE_DEF; + } + + pAdapter->RegistryDMACache = PARM_DMA_CACHE_DEF; + pAdapter->RegistryPhyLoopbk = PARM_PHY_LOOPBK_DEF; + + + /************************************************************************** + Set the MAC address to a default + *************************************************************************/ + memcpy( pAdapter->CurrentAddress, macAddrDef, ETH_ALEN ); + pAdapter->bOverrideAddress = FALSE; + + DBG_TRACE( et131x_dbginfo, + "Default MAC Address : %02x:%02x:%02x:%02x:%02x:%02x\n", + pAdapter->CurrentAddress[0], pAdapter->CurrentAddress[1], + pAdapter->CurrentAddress[2], pAdapter->CurrentAddress[3], + pAdapter->CurrentAddress[4], pAdapter->CurrentAddress[5] ); + + + /************************************************************************** + Decode SpeedDuplex + + Set up as if we are auto negotiating always and then change if we go + into force mode + *************************************************************************/ + pAdapter->AiForceSpeed = 0; // Auto speed + pAdapter->AiForceDpx = 0; // Auto FDX + + + /************************************************************************** + If we are the 10/100 device, and gigabit is somehow requested then + knock it down to 100 full. + *************************************************************************/ + if(( pAdapter->DeviceID == ET131X_PCI_DEVICE_ID_FAST ) && + ( pAdapter->SpeedDuplex == 5 )) + { + pAdapter->SpeedDuplex = 4; + } + + + switch( pAdapter->SpeedDuplex ) + { + case 1: // 10Mb Half-Duplex + pAdapter->AiForceSpeed = 10; + pAdapter->AiForceDpx = 1; + break; + + case 2: // 10Mb Full-Duplex + pAdapter->AiForceSpeed = 10; + pAdapter->AiForceDpx = 2; + break; + + case 3: // 100Mb Half-Duplex + pAdapter->AiForceSpeed = 100; + pAdapter->AiForceDpx = 1; + break; + + case 4: // 100Mb Full-Duplex + pAdapter->AiForceSpeed = 100; + pAdapter->AiForceDpx = 2; + break; + + case 5: // 1000Mb Full-Duplex + pAdapter->AiForceSpeed = 1000; + pAdapter->AiForceDpx = 2; + break; + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + --- linux-2.6.28.orig/ubuntu/et131x/ET1310_tx.h +++ linux-2.6.28/ubuntu/et131x/ET1310_tx.h @@ -0,0 +1,354 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_tx.h - Defines, structs, enums, prototypes, etc. pertaining to data + * transmission. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/10/07 21:26:45 $ + $Revision: 1.9 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET1310_TX_H__ +#define __ET1310_TX_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/****************************************************************************** + Typedefs for Tx Descriptor Ring + *****************************************************************************/ +/****************************************************************************** + TXDESC_WORD2_t structure holds part of the control bits in the Tx Descriptor + ring for the ET-1310 + *****************************************************************************/ +typedef union _txdesc_word2_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 vlan_prio:3; //bits 29-31(VLAN priority) + UINT32 vlan_cfi:1; //bit 28(cfi) + UINT32 vlan_tag:12; //bits 16-27(VLAN tag) + UINT32 length_in_bytes:16; //bits 0-15(packet length) + #else + UINT32 length_in_bytes:16; //bits 0-15(packet length) + UINT32 vlan_tag:12; //bits 16-27(VLAN tag) + UINT32 vlan_cfi:1; //bit 28(cfi) + UINT32 vlan_prio:3; //bits 29-31(VLAN priority) + #endif /* _BIT_FIELDS_HTOL */ + } bits; +}TXDESC_WORD2_t, *PTXDESC_WORD2_t; + + + + +/****************************************************************************** + TXDESC_WORD3_t structure holds part of the control bits in the Tx Descriptor + ring for the ET-1310 + *****************************************************************************/ +typedef union _txdesc_word3_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:17; //bits 15-31 + UINT32 udpa:1; //bit 14(UDP checksum assist) + UINT32 tcpa:1; //bit 13(TCP checksum assist) + UINT32 ipa:1; //bit 12(IP checksum assist) + UINT32 vlan:1; //bit 11(append VLAN tag) + UINT32 hp:1; //bit 10(Packet is a Huge packet) + UINT32 pp:1; //bit 9(pad packet) + UINT32 mac:1; //bit 8(MAC override) + UINT32 crc:1; //bit 7(append CRC) + UINT32 e:1; //bit 6(Tx frame has error) + UINT32 pf:1; //bit 5(send pause frame) + UINT32 bp:1; //bit 4(Issue half-duplex backpressure (XON/XOFF) + UINT32 cw:1; //bit 3(Control word - no packet data) + UINT32 ir:1; //bit 2(interrupt the processor when this pkt sent) + UINT32 f:1; //bit 1(first packet in the sequence) + UINT32 l:1; //bit 0(last packet in the sequence) + #else + UINT32 l:1; //bit 0(last packet in the sequence) + UINT32 f:1; //bit 1(first packet in the sequence) + UINT32 ir:1; //bit 2(interrupt the processor when this pkt sent) + UINT32 cw:1; //bit 3(Control word - no packet data) + UINT32 bp:1; //bit 4(Issue half-duplex backpressure (XON/XOFF) + UINT32 pf:1; //bit 5(send pause frame) + UINT32 e:1; //bit 6(Tx frame has error) + UINT32 crc:1; //bit 7(append CRC) + UINT32 mac:1; //bit 8(MAC override) + UINT32 pp:1; //bit 9(pad packet) + UINT32 hp:1; //bit 10(Packet is a Huge packet) + UINT32 vlan:1; //bit 11(append VLAN tag) + UINT32 ipa:1; //bit 12(IP checksum assist) + UINT32 tcpa:1; //bit 13(TCP checksum assist) + UINT32 udpa:1; //bit 14(UDP checksum assist) + UINT32 unused:17; //bits 15-31 + #endif /* _BIT_FIELDS_HTOL */ + } bits; +}TXDESC_WORD3_t, *PTXDESC_WORD3_t; + + + + +/****************************************************************************** + TX_DESC_ENTRY_t is sructure representing each descriptor on the ring + *****************************************************************************/ +typedef struct _tx_desc_entry_t +{ + UINT32 DataBufferPtrHigh; + UINT32 DataBufferPtrLow; + TXDESC_WORD2_t word2; // control words how to xmit the + TXDESC_WORD3_t word3; // data (detailed above) +} +TX_DESC_ENTRY_t, *PTX_DESC_ENTRY_t; +/*===========================================================================*/ + + + + +/****************************************************************************** + Typedefs for Tx DMA engine status writeback + *****************************************************************************/ +/****************************************************************************** + TX_STATUS_BLOCK_t is sructure representing the status of the Tx DMA engine + it sits in free memory, and is pointed to by 0x101c / 0x1020 + *****************************************************************************/ + +typedef union _tx_status_block_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:21; //bits 11-31 + UINT32 serv_cpl_wrap:1; //bit 10 + UINT32 serv_cpl:10; //bits 0-9 + #else + UINT32 serv_cpl:10; //bits 0-9 + UINT32 serv_cpl_wrap:1; //bit 10 + UINT32 unused:21; //bits 11-31 + #endif + } bits; +} +TX_STATUS_BLOCK_t, *PTX_STATUS_BLOCK_t; +/*===========================================================================*/ + + + + +/****************************************************************************** + TCB (Transmit Control Block) + *****************************************************************************/ +typedef struct _MP_TCB +{ + struct _MP_TCB *Next; + UINT32 Flags; + UINT32 Count; + UINT32 PacketStaleCount; + struct sk_buff *Packet; + UINT32 PacketLength; + TXDMA_SERVICE_REQUEST_t WrIndex; + TXDMA_SERVICE_REQUEST_t WrIndexStart; +} MP_TCB, *PMP_TCB; + + + + +/****************************************************************************** + Structure to hold the skb's in a list + *****************************************************************************/ +typedef struct tx_skb_list_elem +{ + struct list_head skb_list_elem; + struct sk_buff *skb; +} TX_SKB_LIST_ELEM, *PTX_SKB_LIST_ELEM; + + + + +/****************************************************************************** + TX_RING_t is sructure representing our local reference(s) to the ring + *****************************************************************************/ +typedef struct _tx_ring_t +{ + /************************************************************************** + TCB (Transmit Control Block) memory and lists + *************************************************************************/ + PUCHAR MpTcbMem; + + + /************************************************************************** + List of TCBs that are ready to be used + *************************************************************************/ + PMP_TCB TCBReadyQueueHead; + PMP_TCB TCBReadyQueueTail; + + + /************************************************************************** + list of TCBs that are currently being sent. NOTE that access to all + three of these (including nBusySend) are controlled via the + TCBSendQLock. This lock should be secured prior to incementing / + decrementing nBusySend, or any queue manipulation on CurrSendHead / Tail + *************************************************************************/ + PMP_TCB CurrSendHead; + PMP_TCB CurrSendTail; + INT32 nBusySend; + + + /************************************************************************** + List of packets (not TCBs) that were queued for lack of resources + *************************************************************************/ + struct list_head SendWaitQueue; + INT32 nWaitSend; + + + /************************************************************************** + The actual descriptor ring + *************************************************************************/ + PTX_DESC_ENTRY_t pTxDescRingVa; + dma_addr_t pTxDescRingPa; + UINT64 pTxDescRingAdjustedPa; + UINT64 TxDescOffset; + + + /************************************************************************** + ReadyToSend indicates where we last wrote to in the descriptor ring. + *************************************************************************/ + TXDMA_SERVICE_REQUEST_t txDmaReadyToSend; + + + /************************************************************************** + The location of the write-back status block + *************************************************************************/ + PTX_STATUS_BLOCK_t pTxStatusVa; + dma_addr_t pTxStatusPa; + + + /************************************************************************** + A Block of zeroes, used to pad packets that are less than 60 bytes. + *************************************************************************/ + void *pTxDummyBlkVa; + dma_addr_t pTxDummyBlkPa; + + TXMAC_ERR_t TxMacErr; + + + /************************************************************************** + Variables to track the Tx interrupt coalescing features + *************************************************************************/ + INT32 TxPacketsSinceLastinterrupt; +} +TX_RING_t, *PTX_RING_t; + + + + +/****************************************************************************** + Forward declaration of the frag-list for the following prototypes + *****************************************************************************/ +typedef struct _MP_FRAG_LIST MP_FRAG_LIST, *PMP_FRAG_LIST; + + + + +/****************************************************************************** + Forward declaration of the private adapter structure + *****************************************************************************/ +struct et131x_adapter; + + + + +/****************************************************************************** + PROTOTYPES for et1310_tx.c + *****************************************************************************/ +int et131x_tx_dma_memory_alloc( struct et131x_adapter *adapter ); +void et131x_tx_dma_memory_free( struct et131x_adapter *adapter ); +void ConfigTxDmaRegs( struct et131x_adapter *pAdapter ); +void et131x_init_send( struct et131x_adapter *adapter ); +void et131x_tx_dma_disable( struct et131x_adapter *pAdapter ); +void et131x_tx_dma_enable( struct et131x_adapter *pAdapter ); +void et131x_handle_send_interrupt( struct et131x_adapter *pAdapter ); +void et131x_free_busy_send_packets( struct et131x_adapter *pAdapter ); +int et131x_send_packets( struct sk_buff *skb, struct net_device *netdev ); + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __ET1310_TX_H__ */ --- linux-2.6.28.orig/ubuntu/et131x/ET1310_mac.c +++ linux-2.6.28/ubuntu/et131x/ET1310_mac.c @@ -0,0 +1,1247 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_mac.c - All code and routines pertaining to the MAC + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/10/28 18:43:44 $ + $Revision: 1.11 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" +#include "ET1310_mac.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" +#include "et131x_initpci.h" +#include "et131x_supp.h" + + + + +/****************************************************************************** + Data for debugging facilities + *****************************************************************************/ +#ifdef ET131X_DBG +extern dbg_info_t *et131x_dbginfo; +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + ROUTINE: ConfigMacRegs1 + ****************************************************************************** + + DESCRIPTION: + Used to configure the first part of MAC regs to a known initialized + state + + PARAMETERS : + pAdpater - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void ConfigMACRegs1( ET131X_ADAPTER *pAdapter ) +{ + PMAC_t pMac; + MAC_STATION_ADDR1_t station1; + MAC_STATION_ADDR2_t station2; + MAC_IPG_t ipg; + MAC_HFDP_t hfdp; + MII_MGMT_CFG_t mii_mgmt_cfg; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "ConfigMACRegs1" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Let's get our pointer to the MAC regs + *************************************************************************/ + pMac = &pAdapter->CSRAddress->mac; + + + /************************************************************************** + First we need to reset everything. Write to MAC configuration register + 1 to perform reset. + *************************************************************************/ + pMac->cfg1.value = 0xC00F0000; + + + /************************************************************************** + Next lets configure the MAC Inter-packet gap register + *************************************************************************/ + ipg.bits.non_B2B_ipg_1 = 0x38; //58d + ipg.bits.non_B2B_ipg_2 = 0x58; //88d + ipg.bits.min_ifg_enforce = 0x50; //80d + ipg.bits.B2B_ipg = 0x60; //96d + + pMac->ipg.value = ipg.value; + + + /************************************************************************** + Next lets configure the MAC Half Duplex register + *************************************************************************/ + hfdp.bits.alt_beb_trunc = 0xA; + hfdp.bits.alt_beb_enable = 0x0; + hfdp.bits.bp_no_backoff = 0x0; + hfdp.bits.no_backoff = 0x0; + hfdp.bits.excess_defer = 0x1; + hfdp.bits.rexmit_max = 0xF; + hfdp.bits.coll_window = 0x37; //55d + + pMac->hfdp.value = hfdp.value; + + + /************************************************************************** + Next lets configure the MAC Interface Control register + *************************************************************************/ + pMac->if_ctrl.value = 0x0; + + + /************************************************************************** + Let's move on to setting up the mii managment configuration + *************************************************************************/ + mii_mgmt_cfg.bits.reset_mii_mgmt = 0; + mii_mgmt_cfg.bits.scan_auto_incremt = 0; + mii_mgmt_cfg.bits.preamble_suppress = 0; + mii_mgmt_cfg.bits.mgmt_clk_reset = 0x7; + + pMac->mii_mgmt_cfg.value = mii_mgmt_cfg.value; + + + /************************************************************************** + Next lets configure the MAC Station Address register. These values are + read from the EEPROM during initialization and stored in the adapter + structure. We write what is stored in the adapter structure to the MAC + Station Address registers high and low. This station address is used + for generating and checking pause control packets. + *************************************************************************/ + station2.bits.Octet1 = pAdapter->CurrentAddress[0]; + station2.bits.Octet2 = pAdapter->CurrentAddress[1]; + station1.bits.Octet3 = pAdapter->CurrentAddress[2]; + station1.bits.Octet4 = pAdapter->CurrentAddress[3]; + station1.bits.Octet5 = pAdapter->CurrentAddress[4]; + station1.bits.Octet6 = pAdapter->CurrentAddress[5]; + + pMac->station_addr_1.value = station1.value; + pMac->station_addr_2.value = station2.value; + + + /************************************************************************** + Max ethernet packet in bytes that will passed by the mac without being + truncated. Allow the MAC to pass 8 more than our max packet size. This + is 4 for the Ethernet CRC and 4 for the VLAN ID. + + Packets larger than (RegistryJumboPacket) that do not contain a VLAN + ID will be dropped by the Rx function. + *************************************************************************/ +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) + pMac->max_fm_len.value = pAdapter->RegistryJumboPacket + 8; +#else + pMac->max_fm_len.value = pAdapter->RegistryJumboPacket + 4; +#endif + + + /************************************************************************** + clear out MAC config reset + *************************************************************************/ + pAdapter->CSRAddress->mac.cfg1.value = 0x0; + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: ConfigMacRegs2 + ****************************************************************************** + + DESCRIPTION: + Used to configure the second part of MAC regs to a known initialized + state + + PARAMETERS : + pAdpater - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void ConfigMACRegs2( ET131X_ADAPTER *pAdapter ) +{ + INT32 delay = 0; + PMAC_t pMac; + MAC_CFG1_t cfg1; + MAC_CFG2_t cfg2; + MAC_IF_CTRL_t ifctrl; + TXMAC_CTL_t ctl = pAdapter->CSRAddress->txmac.ctl; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "ConfigMACRegs2" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Let's get our pointer to the MAC regs + *************************************************************************/ + pMac = &pAdapter->CSRAddress->mac; + + cfg1.value = pMac->cfg1.value; + cfg2.value = pMac->cfg2.value; + ifctrl.value = pMac->if_ctrl.value; + + if( pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS ) + { + cfg2.bits.if_mode = 0x2; + ifctrl.bits.phy_mode = 0x0; + } + else + { + cfg2.bits.if_mode = 0x1; + ifctrl.bits.phy_mode = 0x1; + } + + + /************************************************************************** + We need to enable Rx/Tx + *************************************************************************/ + cfg1.bits.rx_enable = 0x1; + cfg1.bits.tx_enable = 0x1; + + + /************************************************************************** + Set up flow control + *************************************************************************/ + cfg1.bits.tx_flow = 0x1; + + if( ( pAdapter->FlowControl == RxOnly ) || + ( pAdapter->FlowControl == Both )) + { + cfg1.bits.rx_flow = 0x1; + } + else + { + cfg1.bits.rx_flow = 0x0; + } + + + /************************************************************************** + Initialize loop back to off + *************************************************************************/ + cfg1.bits.loop_back = 0; + + pAdapter->CSRAddress->mac.cfg1.value = cfg1.value; + + + /************************************************************************** + Now we need to initialize the MAC Configuration 2 register + *************************************************************************/ + cfg2.bits.preamble_len = 0x7; + cfg2.bits.huge_frame = 0x0; + /* LENGTH FIELD CHECKING bit4: Set this bit to cause the MAC to check the + * frame’s length field to ensure it matches the actual data field length. Clear this bit if no + * length field checking is desired. Its default is ‘0’. + */ + cfg2.bits.len_check = 0x1; + + if ( pAdapter->RegistryPhyLoopbk == FALSE ) + { + cfg2.bits.pad_crc = 0x1; + cfg2.bits.crc_enable = 0x1; + } + else + { + cfg2.bits.pad_crc = 0; + cfg2.bits.crc_enable = 0; + } + + + /************************************************************************** + 1 – full duplex, 0 – half-duplex + *************************************************************************/ + cfg2.bits.full_duplex = pAdapter->uiDuplexMode; + ifctrl.bits.ghd_mode = !pAdapter->uiDuplexMode; + + pAdapter->CSRAddress->mac.if_ctrl = ifctrl; + pAdapter->CSRAddress->mac.cfg2.value = cfg2.value; + + do + { + udelay( 10 ); + delay++; + } while(( !pAdapter->CSRAddress->mac.cfg1.bits.syncd_rx_en || + !pAdapter->CSRAddress->mac.cfg1.bits.syncd_tx_en ) && + ( delay < 100 )); + + if( delay == 100 ) + { + DBG_ERROR( et131x_dbginfo, + "Syncd bits did not respond correctly cfg1 word 0x%08x\n", + pAdapter->CSRAddress->mac.cfg1.value ); + } + + DBG_TRACE( et131x_dbginfo, + "Speed %d, Dup %d, CFG1 0x%08x, CFG2 0x%08x, if_ctrl 0x%08x\n", + pAdapter->uiLinkSpeed, pAdapter->uiDuplexMode, + pAdapter->CSRAddress->mac.cfg1.value, + pAdapter->CSRAddress->mac.cfg2.value, + pAdapter->CSRAddress->mac.if_ctrl.value ); + + + /************************************************************************** + Enable TXMAC + *************************************************************************/ + ctl.bits.txmac_en = 0x1; + ctl.bits.fc_disable = 0x1; + pAdapter->CSRAddress->txmac.ctl = ctl; + + + /************************************************************************** + Ready to start the RXDMA/TXDMA engine + *************************************************************************/ + if( !MP_TEST_FLAG( pAdapter, fMP_ADAPTER_LOWER_POWER )) + { + et131x_rx_dma_enable( pAdapter ); + et131x_tx_dma_enable( pAdapter ); + } + else + { + DBG_WARNING( et131x_dbginfo, + "Didn't enable Rx/Tx due to low-power mode\n" ); + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: ConfigRxMacRegs + ****************************************************************************** + + DESCRIPTION: + Used to configure the RX MAC registers in the JAGCore + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void ConfigRxMacRegs( ET131X_ADAPTER *pAdapter ) +{ + PRXMAC_t pRxMac; + RXMAC_WOL_SA_LO_t sa_lo; + RXMAC_WOL_SA_HI_t sa_hi; + RXMAC_PF_CTRL_t pf_ctrl = {0}; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "ConfigRxMacRegs" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Let's get a local pointer to the RX MAC Registers + *************************************************************************/ + pRxMac = &pAdapter->CSRAddress->rxmac; + + + /************************************************************************** + Disable the MAC while it is being configured (also disable WOL) + *************************************************************************/ + pRxMac->ctrl.value = 0x8; + + + /************************************************************************** + Initialize WOL to disabled. + *************************************************************************/ + + pRxMac->crc0.value = 0x0; + pRxMac->crc12.value = 0x0000; + pRxMac->crc34.value = 0x0000; + + + /************************************************************************** + We need to set the WOL mask0 – mask4 next. We initialize it to its + default Values of 0x00000000 because there are not WOL masks as of + this time. + *************************************************************************/ + pRxMac->mask0_word0.mask = 0x00000000; + pRxMac->mask0_word1.mask = 0x00000000; + pRxMac->mask0_word2.mask = 0x00000000; + pRxMac->mask0_word3.mask = 0x00000000; + + pRxMac->mask1_word0.mask = 0x00000000; + pRxMac->mask1_word1.mask = 0x00000000; + pRxMac->mask1_word2.mask = 0x00000000; + pRxMac->mask1_word3.mask = 0x00000000; + + pRxMac->mask2_word0.mask = 0x00000000; + pRxMac->mask2_word1.mask = 0x00000000; + pRxMac->mask2_word2.mask = 0x00000000; + pRxMac->mask2_word3.mask = 0x00000000; + + pRxMac->mask3_word0.mask = 0x00000000; + pRxMac->mask3_word1.mask = 0x00000000; + pRxMac->mask3_word2.mask = 0x00000000; + pRxMac->mask3_word3.mask = 0x00000000; + + pRxMac->mask4_word0.mask = 0x00000000; + pRxMac->mask4_word1.mask = 0x00000000; + pRxMac->mask4_word2.mask = 0x00000000; + pRxMac->mask4_word3.mask = 0x00000000; + + + /************************************************************************** + Lets setup the WOL Source Address + *************************************************************************/ + sa_lo.bits.sa3 = pAdapter->CurrentAddress[2]; + sa_lo.bits.sa4 = pAdapter->CurrentAddress[3]; + sa_lo.bits.sa5 = pAdapter->CurrentAddress[4]; + sa_lo.bits.sa6 = pAdapter->CurrentAddress[5]; + pRxMac->sa_lo.value = sa_lo.value; + + sa_hi.bits.sa1 = pAdapter->CurrentAddress[0]; + sa_hi.bits.sa2 = pAdapter->CurrentAddress[1]; + pRxMac->sa_hi.value = sa_hi.value; + + + /************************************************************************** + Disable all Packet Filtering + *************************************************************************/ + pRxMac->pf_ctrl.value = 0; + + + /************************************************************************** + Let's initialize the Unicast Packet filtering address + *************************************************************************/ + if( pAdapter->PacketFilter & ET131X_PACKET_TYPE_DIRECTED ) + { + SetupDeviceForUnicast( pAdapter ); + pf_ctrl.bits.filter_uni_en = 1; + } + else + { + pRxMac->uni_pf_addr1.value = 0x00000000; + pRxMac->uni_pf_addr2.value = 0x00000000; + pRxMac->uni_pf_addr3.value = 0x00000000; + } + + + /************************************************************************** + Let's initialize the Multicast hash + *************************************************************************/ + if( pAdapter->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST ) + { + pf_ctrl.bits.filter_multi_en = 0; + } + else + { + pf_ctrl.bits.filter_multi_en = 1; + SetupDeviceForMulticast( pAdapter ); + } + + + /************************************************************************** + Runt packet filtering. Didn't work in version A silicon. + *************************************************************************/ + pf_ctrl.bits.min_pkt_size = NIC_MIN_PACKET_SIZE + 4; + pf_ctrl.bits.filter_frag_en = 1; + + if( pAdapter->RegistryJumboPacket > 8192 ) + { + RXMAC_MCIF_CTRL_MAX_SEG_t mcif_ctrl_max_seg; + + + /********************************************************************** + In order to transmit jumbo packets greater than 8k, the FIFO + between RxMAC and RxDMA needs to be reduced in size to (16k - + Jumbo packet size). In order to implement this, we must use + "cut through" mode in the RxMAC, which chops packets down into + segments which are (max_size * 16). In this case we selected + 256 bytes, since this is the size of the PCI-Express TLP's that + the 1310 uses. + *********************************************************************/ + mcif_ctrl_max_seg.bits.seg_en = 0x1; + mcif_ctrl_max_seg.bits.fc_en = 0x0; + mcif_ctrl_max_seg.bits.max_size = 0x10; + + pRxMac->mcif_ctrl_max_seg.value = mcif_ctrl_max_seg.value; + } + else + { + pRxMac->mcif_ctrl_max_seg.value = 0x0; + } + + + /************************************************************************** + Initialize the MCIF water marks + *************************************************************************/ + pRxMac->mcif_water_mark.value = 0x0; + + + /************************************************************************** + Initialize the MIF control + *************************************************************************/ + pRxMac->mif_ctrl.value = 0x0; + + + /************************************************************************** + Initialize the Space Available Register + *************************************************************************/ + pRxMac->space_avail.value = 0x0; + + /* Initialize the the mif_ctrl register + * bit 3 - Receive code error. One or more nibbles were signaled as errors + during the reception of the packet. Clear this bit in Gigabit, + set it in 100Mbit. This was derived experimentally at UNH. + * bit 4 - Receive CRC error. The packet’s CRC did not match the + internally generated CRC. + * bit 5 - Receive length check error. Indicates that frame length field + value in the packet does not match the actual data byte length + and is not a type field. + * bit 16 - Receive frame truncated. + * bit 17 - Drop packet enable + */ + if( pAdapter->uiLinkSpeed == TRUEPHY_SPEED_100MBPS ) + { + pRxMac->mif_ctrl.value = 0x30038; + } + else + { + pRxMac->mif_ctrl.value = 0x30030; + } + + + /************************************************************************** + Finally we initialize RxMac to be enabled & WOL disabled. Packet filter + is always enabled since it is where the runt packets are supposed to be + dropped. For version A silicon, runt packet dropping doesn't work, so + it is disabled in the pf_ctrl register, but we still leave the packet + filter on. + *************************************************************************/ + pRxMac->pf_ctrl = pf_ctrl; + pRxMac->ctrl.value = 0x9; + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: ConfigTxMacRegs + ****************************************************************************** + + DESCRIPTION: + used to configure the TX MAC registers of the JAGCore + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void ConfigTxMacRegs( ET131X_ADAPTER *pAdapter ) +{ + PTXMAC_t pTxMac; + TXMAC_CF_PARAM_t Local; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "ConfigTxMacRegs" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Let's get the pointer to tx mac section of regs + *************************************************************************/ + pTxMac = &pAdapter->CSRAddress->txmac; + + + /************************************************************************** + We need to update the Control Frame Parameters + cfpt - control frame pause timer set to 64 (0x40) + cfep - control frame extended pause timer set to 0x0 + *************************************************************************/ + if( pAdapter->FlowControl == None ) + { + pTxMac->cf_param.value = 0x0; + } + else + { + Local.bits.cfpt = 0x40; + Local.bits.cfep = 0x0; + pTxMac->cf_param.value = Local.value; + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: ConfigMacStatRegs + ****************************************************************************** + + DESCRIPTION: + Used to configure the MAC STAT section of the JAGCore + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void ConfigMacStatRegs( ET131X_ADAPTER *pAdapter ) +{ + PMAC_STAT_t pDevMacStat; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "ConfigMacStatRegs" ); + DBG_ENTER( et131x_dbginfo ); + + + pDevMacStat = &pAdapter->CSRAddress->macStat; + + + /************************************************************************** + Next we need to initialize all the MAC_STAT registers to zero on the + device. + *************************************************************************/ + pDevMacStat->RFcs = 0x0; + pDevMacStat->RAln = 0x0; + pDevMacStat->RFlr = 0x0; + pDevMacStat->RDrp = 0x0; + pDevMacStat->RCde = 0x0; + pDevMacStat->ROvr = 0x0; + pDevMacStat->RFrg = 0x0; + + pDevMacStat->TScl = 0x0; + pDevMacStat->TDfr = 0x0; + pDevMacStat->TMcl = 0x0; + pDevMacStat->TLcl = 0x0; + pDevMacStat->TNcl = 0x0; + pDevMacStat->TOvr = 0x0; + pDevMacStat->TUnd = 0x0; + + + /*************************************************************************** + Unmask any counters that we want to track the overflow of. Initially + this will be all counters. It may become clear later that we do not + need to track all counters. + **************************************************************************/ + { + MAC_STAT_REG_1_t Carry1M = {0xffffffff}; + + Carry1M.bits.rdrp = 0x0; + Carry1M.bits.rjbr = 0x1; + Carry1M.bits.rfrg = 0x0; + Carry1M.bits.rovr = 0x0; + Carry1M.bits.rund = 0x1; + Carry1M.bits.rcse = 0x1; + Carry1M.bits.rcde = 0x0; + Carry1M.bits.rflr = 0x0; + Carry1M.bits.raln = 0x0; + Carry1M.bits.rxuo = 0x1; + Carry1M.bits.rxpf = 0x1; + Carry1M.bits.rxcf = 0x1; + Carry1M.bits.rbca = 0x1; + Carry1M.bits.rmca = 0x1; + Carry1M.bits.rfcs = 0x0; + Carry1M.bits.rpkt = 0x1; + Carry1M.bits.rbyt = 0x1; + Carry1M.bits.trmgv = 0x1; + Carry1M.bits.trmax = 0x1; + Carry1M.bits.tr1k = 0x1; + Carry1M.bits.tr511 = 0x1; + Carry1M.bits.tr255 = 0x1; + Carry1M.bits.tr127 = 0x1; + Carry1M.bits.tr64 = 0x1; + + pDevMacStat->Carry1M = Carry1M; + } + + { + MAC_STAT_REG_2_t Carry2M = {0xffffffff}; + + Carry2M.bits.tdrp = 0x1; + Carry2M.bits.tpfh = 0x1; + Carry2M.bits.tncl = 0x0; + Carry2M.bits.txcl = 0x1; + Carry2M.bits.tlcl = 0x0; + Carry2M.bits.tmcl = 0x0; + Carry2M.bits.tscl = 0x0; + Carry2M.bits.tedf = 0x1; + Carry2M.bits.tdfr = 0x0; + Carry2M.bits.txpf = 0x1; + Carry2M.bits.tbca = 0x1; + Carry2M.bits.tmca = 0x1; + Carry2M.bits.tpkt = 0x1; + Carry2M.bits.tbyt = 0x1; + Carry2M.bits.tfrg = 0x1; + Carry2M.bits.tund = 0x0; + Carry2M.bits.tovr = 0x0; + Carry2M.bits.txcf = 0x1; + Carry2M.bits.tfcs = 0x1; + Carry2M.bits.tjbr = 0x1; + + pDevMacStat->Carry2M = Carry2M; + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: ConfigFlowControl + ****************************************************************************** + + DESCRIPTION: + Used to configure the MAC STAT section of the JAGCore + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void ConfigFlowControl( ET131X_ADAPTER *pAdapter ) +{ + if( pAdapter->uiDuplexMode == 0 ) + { + pAdapter->FlowControl = None; + } + else + { + char RemotePause, RemoteAsyncPause; + + ET1310_PhyAccessMiBit( pAdapter, + TRUEPHY_BIT_READ, 5, 10, &RemotePause ); + ET1310_PhyAccessMiBit( pAdapter, + TRUEPHY_BIT_READ, 5, 11, &RemoteAsyncPause ); + + if(( RemotePause == TRUEPHY_BIT_SET ) && + ( RemoteAsyncPause == TRUEPHY_BIT_SET )) + { + pAdapter->FlowControl = pAdapter->RegistryFlowControl; + } + else if(( RemotePause == TRUEPHY_BIT_SET ) && + ( RemoteAsyncPause == TRUEPHY_BIT_CLEAR )) + { + if( pAdapter->RegistryFlowControl == Both ) + { + pAdapter->FlowControl = Both; + } + else + { + pAdapter->FlowControl = None; + } + } + else if(( RemotePause == TRUEPHY_BIT_CLEAR ) && + ( RemoteAsyncPause == TRUEPHY_BIT_CLEAR )) + { + pAdapter->FlowControl = None; + } + else /* if (( RemotePause == TRUEPHY_CLEAR_BIT ) && + ( RemoteAsyncPause == TRUEPHY_SET_BIT )) */ + { + if( pAdapter->RegistryFlowControl == Both ) + { + pAdapter->FlowControl = RxOnly; + } + else + { + pAdapter->FlowControl = None; + } + } + } +} +/*===========================================================================*/ + + + + + + +/****************************************************************************** + ROUTINE: UpdateMacStatHostCounters + ****************************************************************************** + + DESCRIPTION: + used to update the local copy of the statistics held in the adapter + structure + + PARAMETERS : + pAdapter - pointer to the adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void UpdateMacStatHostCounters( ET131X_ADAPTER *pAdapter ) +{ + PMAC_STAT_t pDevMacStat; + /*-----------------------------------------------------------------------*/ + + + /************************************************************************** + Get a local pointer to the adapter macstat regs and update stats + *************************************************************************/ + pDevMacStat = &pAdapter->CSRAddress->macStat; + + pAdapter->Stats.collisions += pDevMacStat->TNcl; + pAdapter->Stats.first_collision += pDevMacStat->TScl; + pAdapter->Stats.tx_deferred += pDevMacStat->TDfr; + pAdapter->Stats.excessive_collisions += pDevMacStat->TMcl; + pAdapter->Stats.late_collisions += pDevMacStat->TLcl; + pAdapter->Stats.tx_uflo += pDevMacStat->TUnd; + pAdapter->Stats.max_pkt_error += pDevMacStat->TOvr; + + pAdapter->Stats.alignment_err += pDevMacStat->RAln; + pAdapter->Stats.crc_err += pDevMacStat->RCde; + pAdapter->Stats.norcvbuf += pDevMacStat->RDrp; + pAdapter->Stats.rx_ov_flow += pDevMacStat->ROvr; + pAdapter->Stats.code_violations += pDevMacStat->RFcs; + pAdapter->Stats.length_err += pDevMacStat->RFlr; + + pAdapter->Stats.other_errors += pDevMacStat->RFrg; + + return; +} +/*===========================================================================*/ + + + + + +/****************************************************************************** + ROUTINE: HandleMacStatInterrupt + ****************************************************************************** + + DESCRIPTION: + One of the MACSTAT counters has wrapped. Update the local copy of + the statistics held in the adapter structure, checking the "wrap" + bit for each counter. + + PARAMETERS : + pAdapter - pointer to the adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void HandleMacStatInterrupt( ET131X_ADAPTER *pAdapter ) +{ + MAC_STAT_REG_1_t Carry1; + MAC_STAT_REG_2_t Carry2; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "HandleMacStatInterrupt" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Read the interrupt bits from the register(s). These are Clear On Write. + *************************************************************************/ + Carry1 = pAdapter->CSRAddress->macStat.Carry1; + Carry2 = pAdapter->CSRAddress->macStat.Carry2; + + pAdapter->CSRAddress->macStat.Carry1 = Carry1; + pAdapter->CSRAddress->macStat.Carry2 = Carry2; + + + /************************************************************************** + We need to do update the host copy of all the MAC_STAT counters. For + each counter, check it's overflow bit. If the overflow bit is set, then + increment the host version of the count by one complete revolution of the + counter. This routine is called when the counter block indicates that + one of the counters has wrapped. + *************************************************************************/ + if( Carry1.bits.rfcs ) + { + pAdapter->Stats.code_violations += COUNTER_WRAP_16_BIT; + } + + if( Carry1.bits.raln ) + { + pAdapter->Stats.alignment_err += COUNTER_WRAP_12_BIT; + } + + if( Carry1.bits.rflr ) + { + pAdapter->Stats.length_err += COUNTER_WRAP_16_BIT; + } + + if( Carry1.bits.rfrg ) + { + pAdapter->Stats.other_errors += COUNTER_WRAP_16_BIT; + } + + if( Carry1.bits.rcde ) + { + pAdapter->Stats.crc_err += COUNTER_WRAP_16_BIT; + } + + if( Carry1.bits.rovr ) + { + pAdapter->Stats.rx_ov_flow += COUNTER_WRAP_16_BIT; + } + + if( Carry1.bits.rdrp ) + { + pAdapter->Stats.norcvbuf += COUNTER_WRAP_16_BIT; + } + + if( Carry2.bits.tovr ) + { + pAdapter->Stats.max_pkt_error += COUNTER_WRAP_12_BIT; + } + + if( Carry2.bits.tund ) + { + pAdapter->Stats.tx_uflo += COUNTER_WRAP_12_BIT; + } + + if( Carry2.bits.tscl ) + { + pAdapter->Stats.first_collision += COUNTER_WRAP_12_BIT; + } + + if( Carry2.bits.tdfr ) + { + pAdapter->Stats.tx_deferred += COUNTER_WRAP_12_BIT; + } + + if( Carry2.bits.tmcl ) + { + pAdapter->Stats.excessive_collisions += COUNTER_WRAP_12_BIT; + } + + if( Carry2.bits.tlcl ) + { + pAdapter->Stats.late_collisions += COUNTER_WRAP_12_BIT; + } + + if( Carry2.bits.tncl ) + { + pAdapter->Stats.collisions += COUNTER_WRAP_12_BIT; + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : SetupDeviceForMulticast + ****************************************************************************** + + DESCRIPTION : + Use to set the ET1310 to do multicast filtering + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + REUSE INFORMATION : + NONE + + *****************************************************************************/ +void SetupDeviceForMulticast( ET131X_ADAPTER *pAdapter ) +{ + UINT32 nIndex; + UINT32 result; + RXMAC_MULTI_HASH_t hash1 = {0}; + RXMAC_MULTI_HASH_t hash2 = {0}; + RXMAC_MULTI_HASH_t hash3 = {0}; + RXMAC_MULTI_HASH_t hash4 = {0}; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "SetupDeviceForMulticast" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + If ET131X_PACKET_TYPE_MULTICAST is specified, then we provision the + multi-cast LIST. If it is NOT specified, (and "ALL" is not specified) + then we should pass NO multi-cast addresses to the driver. + *************************************************************************/ + if( pAdapter->PacketFilter & ET131X_PACKET_TYPE_MULTICAST ) + { + DBG_VERBOSE( et131x_dbginfo, "MULTICAST flag is set, MCCount: %d\n", + pAdapter->MCAddressCount ); + + + /********************************************************************** + Loop through our multicast array and set up the device + **********************************************************************/ + for( nIndex = 0; nIndex < pAdapter->MCAddressCount; nIndex++ ) + { + DBG_VERBOSE( et131x_dbginfo, + "MCList[%d]: %02x:%02x:%02x:%02x:%02x:%02x\n", + nIndex, + pAdapter->MCList[nIndex][0], + pAdapter->MCList[nIndex][1], + pAdapter->MCList[nIndex][2], + pAdapter->MCList[nIndex][3], + pAdapter->MCList[nIndex][4], + pAdapter->MCList[nIndex][5] ); + + result = et131x_calc_enet_crc( pAdapter->MCList[nIndex], 6 ); + + result = ( result & 0x3F800000 ) >> 23; + + if( result < 32 ) + { + hash1.hash |= ( 1 << result ); + } + else if(( 31 < result ) && ( result < 64 )) + { + result -= 32; + hash2.hash |= ( 1 << result ); + } + else if(( 63 < result ) && ( result < 96 )) + { + result -= 64; + hash3.hash |= ( 1 << result ); + } + else + { + result -= 96; + hash4.hash |= ( 1 << result ); + } + } + } + + + /************************************************************************** + Write out the new hash to the device + *************************************************************************/ + if( pAdapter->CSRAddress->global.pm_csr.bits.pm_phy_sw_coma == 0 ) + { + pAdapter->CSRAddress->rxmac.multi_hash1.hash = hash1.hash; + pAdapter->CSRAddress->rxmac.multi_hash2.hash = hash2.hash; + pAdapter->CSRAddress->rxmac.multi_hash3.hash = hash3.hash; + pAdapter->CSRAddress->rxmac.multi_hash4.hash = hash4.hash; + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : SetupDeviceForUnicast + ****************************************************************************** + + DESCRIPTION : + Use to set the ET1310 to do unicast filtering + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + REUSE INFORMATION : + NONE + + *****************************************************************************/ +void SetupDeviceForUnicast( ET131X_ADAPTER *pAdapter ) +{ + RXMAC_UNI_PF_ADDR1_t uni_pf1; + RXMAC_UNI_PF_ADDR2_t uni_pf2; + RXMAC_UNI_PF_ADDR3_t uni_pf3; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "SetupDeviceForUnicast" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Set up unicast packet filter reg 3 to be the first two octets of the + MAC address for both address + *************************************************************************/ + /************************************************************************** + Set up unicast packet filter reg 2 to be the octets 2 - 5 of the + MAC address for second address + *************************************************************************/ + /************************************************************************** + Set up unicast packet filter reg 3 to be the octets 2 - 5 of the + MAC address for first address + *************************************************************************/ + uni_pf3.bits.addr1_1 = pAdapter->CurrentAddress[0]; + uni_pf3.bits.addr1_2 = pAdapter->CurrentAddress[1]; + uni_pf3.bits.addr2_1 = pAdapter->CurrentAddress[0]; + uni_pf3.bits.addr2_2 = pAdapter->CurrentAddress[1]; + + uni_pf2.bits.addr2_3 = pAdapter->CurrentAddress[2]; + uni_pf2.bits.addr2_4 = pAdapter->CurrentAddress[3]; + uni_pf2.bits.addr2_5 = pAdapter->CurrentAddress[4]; + uni_pf2.bits.addr2_6 = pAdapter->CurrentAddress[5]; + + uni_pf1.bits.addr1_3 = pAdapter->CurrentAddress[2]; + uni_pf1.bits.addr1_4 = pAdapter->CurrentAddress[3]; + uni_pf1.bits.addr1_5 = pAdapter->CurrentAddress[4]; + uni_pf1.bits.addr1_6 = pAdapter->CurrentAddress[5]; + + if( pAdapter->CSRAddress->global.pm_csr.bits.pm_phy_sw_coma == 0 ) + { + pAdapter->CSRAddress->rxmac.uni_pf_addr1 = uni_pf1; + pAdapter->CSRAddress->rxmac.uni_pf_addr2 = uni_pf2; + pAdapter->CSRAddress->rxmac.uni_pf_addr3 = uni_pf3; + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ --- linux-2.6.28.orig/ubuntu/et131x/ET1310_pm.c +++ linux-2.6.28/ubuntu/et131x/ET1310_pm.c @@ -0,0 +1,1723 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_pm.c - All power management related code (not completely implemented) + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2006/01/20 21:29:44 $ + $Revision: 1.8 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" +#include "ET1310_mac.h" +#include "ET1310_rx.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" +#include "et131x_initpci.h" + + + + +/****************************************************************************** + Data for debugging facilities + *****************************************************************************/ +#ifdef ET131X_DBG +extern dbg_info_t *et131x_dbginfo; +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + ROUTINE: CalculateCCITCRC16 + ****************************************************************************** + DESCRIPTION: + This routine calculates the CCIT CRC-16 value required for power + management. + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +UINT16 CalculateCCITCRC16( PUCHAR Pattern, PUCHAR Mask, UINT32 MaskSize ) +{ + UINT32 i, j, k, HitBit; + UINT16 RemainderCRC = 0xFFFF; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "CalculateCCITCRC16" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + There is one bit in the mask for every byte in the pattern. Therefore, + this first loop (the "i" loop) iterates over every byte in the mask, + the inner "j" loop iterates over every bit in each byte. If that bit + in the mask is clear, then we skip over this byte of packet date (the + "continue"). + *************************************************************************/ + for( i = 0; i < MaskSize; i++ ) + { + for( j = 0; j < 8; j++ ) + { + if(( Mask[i] & ( 1 << j )) == 0 ) + { + continue; + } + + /****************************************************************** + Following 10 lines iterates over every bit in this byte of the + pattern, and applies the CRC-16 calculation as defined by CCIT. + It could be optimized using a look-up-table, but this function + will be called infrequently, so the memory overhead of + optimization can be avoided. + *****************************************************************/ + for( k = 0; k < 8; k++ ) + { + HitBit = (( RemainderCRC >> 15 ) & 1 ); + HitBit ^= ( Pattern[(i*8)+j] >> k ) & 1; + + RemainderCRC <<= 1; + + if( HitBit ) + { + RemainderCRC ^= CRC16_POLY; + } + } + } + } + + DBG_LEAVE( et131x_dbginfo ); + return( RemainderCRC ); +} + +/*===========================================================================*/ + + + +#if 0 +/****************************************************************************** + ROUTINE: MPSetPowerD0 + ****************************************************************************** + DESCRIPTION: + Used to set the power state to D0, Updated for the ET1310 + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +VOID MPSetPowerD0( IN PMP_ADAPTER pAdapter ) +{ + UINT32 uPmCsr; + NDIS_DEVICE_POWER_STATE ComingBackFrom; + PM_CSR_t pm_csr = pAdapter->CSRAddress->global.pm_csr; + RXMAC_CTRL_t ctrl; + MI_ISR_t isr; + MI_BMSR_t Bmsr, BmsrInts; + UINT32 delay = 0; + + /*-----------------------------------------------------------------------*/ + + DBGPRINT( MP_TRACE, ( "----> MPSetPowerD0\n" )); + + /************************************************************************** + Archive the power-state we are returning from, and then set the + "current" power state back to fully operational + *************************************************************************/ + ComingBackFrom = pAdapter->PoMgmt.PowerState; + pAdapter->PoMgmt.PowerState = NdisDeviceStateD0; + + + /********************************************************************** + Allow disabling of Non-Maskable Interrupts in I/O space, to + support validation. + *********************************************************************/ + if( pAdapter->RegistryNMIDisable ) + { + UCHAR RegisterVal; + + NdisRawReadPortUchar( ET1310_NMI_DISABLE, &RegisterVal ); + + RegisterVal &= 0xf3; + + if( pAdapter->RegistryNMIDisable == 2 ) + { + RegisterVal |= 0xc; + } + + NdisRawWritePortUchar( ET1310_NMI_DISABLE, RegisterVal ); + } + + { + UCHAR read_size_reg; + + /****************************************************************** + Change the max read size to 2k + *****************************************************************/ + NdisReadPciSlotInformation( pAdapter->AdapterHandle, + 0, // not used + 0x51, + (PVOID)&read_size_reg, + sizeof( UCHAR )); + + read_size_reg &= 0x8f; + read_size_reg |= 0x40; + + NdisWritePciSlotInformation( pAdapter->AdapterHandle, + 0, + 0x51, + &read_size_reg, + sizeof( UCHAR )); + } + + + /************************************************************************** + Sample read of pmcsr to aid validation. Will be catured by PCI-e + analyzer + *************************************************************************/ + NdisReadPciSlotInformation( pAdapter->AdapterHandle, + 0, // Slot no. Reserved. Ndis ignores. + ET1310_PCI_PM_CSR, + (PVOID)&uPmCsr, + sizeof( UINT32 )); + + /************************************************************************** + we now need to set the JAGCore gating control registers for this power + state. Bypass this for nonwake device since in that case the JAGCore + and gigE PHY have been reset + + This is only supposeto be for wake mode, when in non-wake mode, the + device enters L1 which causes a reset of the jagcore which basically + clears the PM_STATE. But due to issue with system not staying in L1 the + hardware reset is not happening. So we take care of it here. + *************************************************************************/ + if( TRUE ) //pAdapter->PoMgmt.WOLEnabled ) + { + pm_csr.bits.pm_gigephy_en = 0; + pm_csr.bits.pm_jagcore_rx_en = 0; + pm_csr.bits.pm_jagcore_tx_en = 0; + pm_csr.bits.pm_phy_lped_en = 0; + pm_csr.bits.pm_phy_sw_coma = 0; + + /********************************************************************** + enable clock first + *********************************************************************/ + pm_csr.bits.pm_sysclk_gate = 1; + pm_csr.bits.pm_txclk_gate = 1; + pm_csr.bits.pm_rxclk_gate = 1; + + /********************************************************************** + tx_en and rx_en should remain the same as in power down + *********************************************************************/ + pAdapter->CSRAddress->global.pm_csr = pm_csr; + + /********************************************************************** + poll the PMSTATE until JAGCore is in normal state + *********************************************************************/ + while(( pAdapter->CSRAddress->global.pm_csr.bits.pm_jagcore_rx_rdy != 0 ) && + ( pAdapter->CSRAddress->global.pm_csr.bits.pm_jagcore_tx_rdy != 0 ) && + ( delay < 100 )) + { + NdisStallExecution( 10 ); + delay++; + } + + if( delay >= 100 ) + { + pm_csr = pAdapter->CSRAddress->global.pm_csr; + + pm_csr.bits.pm_jagcore_rx_en = 0; + pm_csr.bits.pm_jagcore_tx_en = 0; + pAdapter->CSRAddress->global.pm_csr.value = pm_csr.value; + } + } + + /************************************************************************** + now lets set up JAGcore pm control for D0 + *************************************************************************/ + pm_csr.bits.pm_gigephy_en = 0; + + pm_csr.bits.pm_jagcore_rx_en = pAdapter->PoMgmt.rx_en; + pm_csr.bits.pm_jagcore_tx_en = pAdapter->PoMgmt.tx_en; + + pAdapter->CSRAddress->global.pm_csr = pm_csr; + + /************************************************************************** + we also need to read and clear the phy_interrupt register in case of + wakeup on link status change + *************************************************************************/ + MiRead( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + (UINT8)FIELD_OFFSET( MI_REGS_t, isr ), &isr.value ); + + /************************************************************************** + disable WOL + *************************************************************************/ + ctrl = pAdapter->CSRAddress->rxmac.ctrl; + + ctrl.bits.wol_disable = 1; + ctrl.bits.mif_disable = 0; + ctrl.bits.async_disable = 0; + + pAdapter->CSRAddress->rxmac.ctrl = ctrl; + + /************************************************************************** + Set the power state to 0 (d0), and flip the PME status pin. Clear the + PME Enable pin, if it were set. + *************************************************************************/ + uPmCsr = 0x00008000; + NdisWritePciSlotInformation( pAdapter->AdapterHandle, + 0, // Slot no. Reserved. Ndis ignores. + ET1310_PCI_PM_CSR, + &uPmCsr, + sizeof( UINT32 )); + + /************************************************************************** + When the adapter is placed in D3 wake, it is set in 10 Base-T + half-duplex mode. However, we archived the speed and duplex settings + that were current prior to that, so restore them now and then tell + the phy to do it's thing. + *************************************************************************/ + if(( ComingBackFrom == NdisDeviceStateD3 ) || + ( ComingBackFrom == NdisDeviceStateD1 && !pAdapter->PoMgmt.WOLEnabledByCurrentState )) + { + pAdapter->AiForceSpeed = pAdapter->PoMgmt.PowerDownSpeed; + pAdapter->AiForceDpx = pAdapter->PoMgmt.PowerDownDuplex; + + /********************************************************************** + Re-initialize the send structures + **********************************************************************/ + MPInitSend( pAdapter ); + + /********************************************************************** + Reset the RFD list and re-start RU + *********************************************************************/ + NICResetRecv( pAdapter ); + + /********************************************************************** + Bring the device back to the state it was during init prior + to autonegotiation being complete. This way, when we get the + auto-neg complete interrupt, we can complete init by calling + ConfigMacREGS2. + *********************************************************************/ + HwSoftwareReset( pAdapter ); + + /********************************************************************** + setup et1310 as per the documentation + *********************************************************************/ + NICSetAdapterUp( pAdapter ); + } + + /************************************************************************** + Allow Tx to restart + *************************************************************************/ + MP_CLEAR_FLAG( pAdapter, fMP_ADAPTER_LOWER_POWER ); + + /************************************************************************** + Check to see if the link status bit is set in the BMSR register, if it + is not, this means we had a cable pull when at a lower power state and + need to indicate that we are disconnected to NDIS + *************************************************************************/ + MiRead( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + (UINT8)FIELD_OFFSET( MI_REGS_t, bmsr ), &Bmsr.value ); + + if( !Bmsr.bits.link_status ) + { + + pAdapter->Bmsr.value = Bmsr.value; + + NdisAcquireSpinLock( &pAdapter->Lock ); + MP_SET_FLAG( pAdapter, fMP_ADAPTER_LINK_DETECTION ); + pAdapter->MediaState = 0; + + NdisReleaseSpinLock( &pAdapter->Lock ); + + // get timer going again... + NdisMSetPeriodicTimer( &pAdapter->PeriodicTimer, + TX_ERROR_PERIOD ); + + // setup for possible disconnect + NdisMSetTimer( &pAdapter->LinkDetectionTimer, + LINK_DETECTION_TIMER ); + + pAdapter->bLinkTimerActive = TRUE; + + if( pAdapter->RegistryPhyComa ) + { + MPSetPhyComa( pAdapter ); + } + /********************************************************************** + In the case of link-in before sleep, link-out after sleep, we need + to re-start the start-of-day timer so that we eventually flop + into PhyComa. In this case, the above state change gets overwritten + since we get a PHY interrupt almost straight away, and PHY interrupt + handling pulls us out of PHY coma mode. + *********************************************************************/ + pAdapter->PoMgmt.TransPhyComaModeOnBoot = 0; + } + + /************************************************************************** + we need to enable interrupts + *************************************************************************/ + NdisMSynchronizeWithInterrupt( &pAdapter->Interrupt, + (PVOID)NICEnableInterrupts, + pAdapter ); + + DBGPRINT( MP_TRACE, ( "<---- MPSetPowerD0\n" )); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: MPSetLowPower + ****************************************************************************** + DESCRIPTION: + This routine is called when the adapter receives a SetPower to any + state other than d0. Most of the common stuff for setting to a lower + power state should be handled in here. + + PARAMETERS : + pAdapter - pointer to our adapter structure + PowerState - NewPowerState + + RETURNS : + NONE + + *****************************************************************************/ +VOID MPSetLowPower( IN PMP_ADAPTER pAdapter, + IN NDIS_DEVICE_POWER_STATE PowerState ) +{ + PM_CSR_t GlobalPmCSR; + RXMAC_CTRL_t ctrl; + MI_ISR_t isr; + MI_BMSR_t lBmsr; + BOOLEAN bDummy; + /*-----------------------------------------------------------------------*/ + + /************************************************************************** + if we are in coma mode when we get this request, we need to disable it + *************************************************************************/ + if( pAdapter->CSRAddress->global.pm_csr.bits.pm_phy_sw_coma == 1 ) + { + /********************************************************************** + check to see if we are in coma mode and if so, disable it because + we will not be able to read phy values until we are out. + *********************************************************************/ + MPDisablePhyComa( pAdapter ); + } + + /************************************************************************** + interrupts will be queued until after this routine completes. May as + well disable them now, since we do not want any of the queued interrupts. + *************************************************************************/ + NdisMSynchronizeWithInterrupt( &pAdapter->Interrupt, + (PVOID)NICDisableInterrupts, + pAdapter ); + + /************************************************************************** + Set the adapter power state to requested, lower state + *************************************************************************/ + pAdapter->PoMgmt.PowerState = PowerState; + + /************************************************************************** + Cancel timers - start them again when power restored + *************************************************************************/ + NdisMCancelTimer( &pAdapter->PeriodicTimer, &bDummy ); + + if( pAdapter->bLinkTimerActive == TRUE ){ + NdisMCancelTimer( &pAdapter->LinkDetectionTimer, &bDummy ); + } + + /************************************************************************** + Save the GbE PHY speed and duplex modes + + Need to restore this for: D1 nonwake, D3 wake and nonwake modes + *************************************************************************/ + pAdapter->PoMgmt.PowerDownSpeed = pAdapter->AiForceSpeed; + pAdapter->PoMgmt.PowerDownDuplex = pAdapter->AiForceDpx; + + NdisAcquireSpinLock( &pAdapter->SendHWLock ); + + /************************************************************************** + Stop sending packets. + *************************************************************************/ + MP_SET_FLAG( pAdapter, fMP_ADAPTER_LOWER_POWER ); + + NdisReleaseSpinLock( &pAdapter->SendHWLock ); + + /************************************************************************** + Free the packets being actively sent & stopped + **************************************************************************/ + MpFreeBusySendPackets( pAdapter ); + + /************************************************************************** + Save Rx/Tx enable condition. Used during restore to D0 state. + *************************************************************************/ + pAdapter->PoMgmt.tx_en = pAdapter->CSRAddress->global.pm_csr.bits.pm_jagcore_tx_en; + pAdapter->PoMgmt.rx_en = pAdapter->CSRAddress->global.pm_csr.bits.pm_jagcore_rx_en; + + /************************************************************************** + set the JAGCore gating control registers for this power state + *************************************************************************/ + GlobalPmCSR = pAdapter->CSRAddress->global.pm_csr; + + if( pAdapter->PoMgmt.WOLEnabledByCurrentState ) + { + GlobalPmCSR.bits.pm_gigephy_en = 0; + } + else + { + GlobalPmCSR.bits.pm_gigephy_en = 1; + } + + /************************************************************************** + only exercise the PM state machine when the link is up + *************************************************************************/ + if( pAdapter->Bmsr.bits.link_status ) + { + GlobalPmCSR.bits.pm_jagcore_tx_en = 1; + GlobalPmCSR.bits.pm_jagcore_rx_en = 1; + + } + pAdapter->CSRAddress->global.pm_csr = GlobalPmCSR; + + ctrl = pAdapter->CSRAddress->rxmac.ctrl; + + /************************************************************************** + only exercise the PM state machine when the link is up + *************************************************************************/ + if( pAdapter->Bmsr.bits.link_status ) + { + /********************************************************************** + disable MIF so power state can transition + *********************************************************************/ + ctrl.bits.mif_disable = 1; + pAdapter->CSRAddress->rxmac.ctrl = ctrl; + + while(( pAdapter->CSRAddress->global.pm_csr.bits.pm_jagcore_rx_rdy != 1 ) + && ( pAdapter->CSRAddress->global.pm_csr.bits.pm_jagcore_tx_rdy != 1 )) + { + NdisStallExecution( 10 ); + } + } + + /************************************************************************** + Stop hardware from receiving packets - Set the RU to idle + *************************************************************************/ + NICRxDmaDisable( pAdapter ); + + /************************************************************************** + Wait for outstanding Receive packets + *************************************************************************/ + while( MP_GET_RCV_REF( pAdapter ) != 0 ) + { + /********************************************************************** + Sleep for 2 Ms; + *********************************************************************/ + NdisStallExecution( 2000 ); + } + + /************************************************************************** + D3Wake only - set the MAC and Phy to 10BaseT half-duplex operation. + Archive the current settings in the pAdapter structure so we can + restore them when done. + *************************************************************************/ + if(( PowerState == NdisDeviceStateD3 ) && pAdapter->PoMgmt.WOLEnabledByCurrentState && + pAdapter->Bmsr.bits.link_status ) + { + /********************************************************************** + initialize variable for testing if we failed to go to specific link + *********************************************************************/ + pAdapter->PoMgmt.Failed10Half = FALSE; + + /********************************************************************** + set the phy properly + *********************************************************************/ + pAdapter->AiForceSpeed = 10; + pAdapter->AiForceDpx = 1; + + TPAL_SetPhy10HalfDuplex( pAdapter ); + + /********************************************************************** + get the link status here, we need to wait until the link comes back + after reconfiguring it. + *********************************************************************/ + TPAL_GetLinkStatusInfo( pAdapter ); + + if( pAdapter->PoMgmt.Failed10Half ) + { + /****************************************************************** + re-initialize variable for testing if we failed to go to + specific link speed + *****************************************************************/ + pAdapter->PoMgmt.Failed10Half = FALSE; + + /****************************************************************** + set the phy properly + *****************************************************************/ + pAdapter->AiForceSpeed = 100; + pAdapter->AiForceDpx = 1; + + TPAL_SetPhy100HalfDuplex( pAdapter ); + + /****************************************************************** + get the link status here, we need to wait until the link comes + back after reconfiguring it. + *****************************************************************/ + TPAL_GetLinkStatusInfo( pAdapter ); + } + + // SetRxDmaTimer( pAdapter ); + ConfigMACRegs2( pAdapter ); + } + + if( pAdapter->PoMgmt.WOLEnabledByCurrentState ) + { + RXMAC_WOL_CTL_CRC0_t rxmac_ctl_crc0 = pAdapter->CSRAddress->rxmac.crc0; + RXMAC_WOL_CRC12_t crc12; + RXMAC_WOL_CRC34_t crc34; + ULONG ulResult; + UINT32 SerdesPhyControl; + UINT mask; + + ulResult = NdisReadPciSlotInformation( pAdapter->AdapterHandle, + 0, // not used + ET1310_PCI_PHY_INDEX_REG, + (PVOID)&SerdesPhyControl, + sizeof( UINT32 )); + + if( pAdapter->RegistryPMWOL ) + { + SerdesPhyControl |= 0x00010000; + } + else + { + SerdesPhyControl &= 0xfffeffff; + } + + ulResult = NdisWritePciSlotInformation( + pAdapter->AdapterHandle, + 0, + ET1310_PCI_PHY_INDEX_REG, + (PVOID)&SerdesPhyControl, + sizeof( UINT32 )); + + if( pAdapter->Bmsr.bits.link_status ) + { + /********************************************************************** + need to do this for all wake devices + make sure all ignore bits are set + *********************************************************************/ + rxmac_ctl_crc0.bits.ignore_broad = 1; + rxmac_ctl_crc0.bits.ignore_multi = 1; + rxmac_ctl_crc0.bits.ignore_uni = 1; + + if( pAdapter->RegistryWOLMatch & 0x1 ) + { + rxmac_ctl_crc0.bits.ignore_mp = 0; + } + else + { + rxmac_ctl_crc0.bits.ignore_mp = 1; + } + + if( pAdapter->RegistryWOLMatch & 0x2 ) + { + rxmac_ctl_crc0.bits.ignore_pp = 0; + } + else + { + rxmac_ctl_crc0.bits.ignore_pp = 1; + } + + if( pAdapter->RegistryWOLLink & 0x1 ) + { + rxmac_ctl_crc0.bits.ignore_link_chg = 0; + } + else + { + rxmac_ctl_crc0.bits.ignore_link_chg = 1; + } + + /****************************************************************** + Clear the pattern match validity bits - i.e. make all patterns + invalid + *****************************************************************/ + rxmac_ctl_crc0.value &= ~0x1f; + + if(( pAdapter->RegistryWOLMatch & 0x2 ) && + ( pAdapter->PoMgmt.localWolAndCrc0 & 0x1f )) + { + /************************************************************** + set the validity bits based on what has been enabled in + the adapter + *************************************************************/ + rxmac_ctl_crc0.value |= (pAdapter->PoMgmt.localWolAndCrc0 & 0x1f); + + /************************************************************** + Copy the five CRCs from the adapter + *************************************************************/ + rxmac_ctl_crc0.bits.crc0 = pAdapter->PoMgmt.WOLPatternList [0]; + crc12.bits.crc1 = pAdapter->PoMgmt.WOLPatternList [1]; + crc12.bits.crc2 = pAdapter->PoMgmt.WOLPatternList [2]; + crc34.bits.crc3 = pAdapter->PoMgmt.WOLPatternList [3]; + crc34.bits.crc4 = pAdapter->PoMgmt.WOLPatternList [4]; + + for( mask = 0; mask < 5; mask++) + { + UINT i; + PUINT32 pDevicePatternMask = (PUINT32) + (&pAdapter->CSRAddress->rxmac.mask0_word0) + + (mask * MAX_WOL_MASK_SIZE / 4); + if(( pAdapter->PoMgmt.localWolAndCrc0 >> mask ) & 0x1 ) + { + UINT32 Temp[ MAX_WOL_MASK_SIZE / 4 ]; + PUCHAR pNdisPatternMask; + + pNdisPatternMask = (PUCHAR)&pAdapter->PoMgmt.WOLMaskList[ mask ][ 0 ]; + + NdisZeroMemory( Temp, sizeof( Temp )); + NdisMoveMemory( Temp, pNdisPatternMask, + pAdapter->PoMgmt.WOLMaskSize[ mask ] ); + + /************************************************************** + Write the mask to the device using the pointer calculated + above. + *************************************************************/ + for( i=0; i<( MAX_WOL_MASK_SIZE / 4 ); i++ ) + { + pDevicePatternMask[ i ] = Temp[ i ]; + } + } + } + } + + pAdapter->CSRAddress->rxmac.crc0 = rxmac_ctl_crc0; + pAdapter->CSRAddress->rxmac.crc12 = crc12; + pAdapter->CSRAddress->rxmac.crc34 = crc34; + + /****************************************************************** + we also need to read and clear the phy_interrupt register in + case of wakeup on link status change + *****************************************************************/ + MiRead( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + (UINT8)FIELD_OFFSET( MI_REGS_t, isr ), &isr.value ); + + MiRead( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + (UINT8)FIELD_OFFSET( MI_REGS_t, bmsr ), &lBmsr.value ); + + /****************************************************************** + disable mif and async + *****************************************************************/ + ctrl.bits.mif_disable = 1; + ctrl.bits.async_disable = 1; + ctrl.bits.wol_disable = 0; + pAdapter->CSRAddress->rxmac.ctrl = ctrl; + + rxmac_ctl_crc0.bits.clr_intr = 1; + pAdapter->CSRAddress->rxmac.crc0.value = rxmac_ctl_crc0.value; + + DBGPRINT( MP_SPEC, ("Going down - ctrl 0x%x, crc0_ctl 0x%x\n", + pAdapter->CSRAddress->rxmac.ctrl.value, + pAdapter->CSRAddress->rxmac.crc0.value )); + + pAdapter->Stats.InterruptStatus.value = pAdapter->CSRAddress->global.int_status.value; + + DBGPRINT( MP_SPEC, ("Going down - int stat was 0x%x, now 0x%x\n", + pAdapter->Stats.InterruptStatus.value, + pAdapter->CSRAddress->global.int_status.value )); + } + else if( pAdapter->RegistryWOLLink & 0x1 ) + { + GlobalPmCSR = pAdapter->CSRAddress->global.pm_csr; + + /************************************************************************** + Gate off JAGCore 3 clock domains + *************************************************************************/ + GlobalPmCSR.bits.pm_sysclk_gate = 0; + GlobalPmCSR.bits.pm_txclk_gate = 0; + GlobalPmCSR.bits.pm_rxclk_gate = 0; + pAdapter->CSRAddress->global.pm_csr = GlobalPmCSR; + + /************************************************************************** + Program gigE PHY in to Coma mode + *************************************************************************/ + GlobalPmCSR.bits.pm_phy_sw_coma = 1; + GlobalPmCSR.bits.pm_phy_lped_en = 1; + + pAdapter->CSRAddress->global.pm_csr = GlobalPmCSR; + } + } +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: MPSetPowerD1Wake + ****************************************************************************** + DESCRIPTION: + This routine is called when the adapter receives a SetPower to + D1 PowerState, and there is a set of wake-up patterns programmed + in the adapter. The set could consist of a single wake-up pattern. + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +VOID MPSetPowerD1Wake( PMP_ADAPTER pAdapter ) +{ + UINT32 uPmCsr; + PM_CSR_t pm_csr; + /*-----------------------------------------------------------------------*/ + + DBGPRINT( MP_TRACE, ( "----> MPSetPowerD1Wake\n" )); + + /************************************************************************** + common power down functionality; disable Tx & Rx, disable wol while + it is being provisioned, archive Tx and Rx enable, and do some of the + gating into jagcore. + *************************************************************************/ + MPSetLowPower( pAdapter, NdisDeviceStateD1 ); + + if((( pAdapter->RegistryWOLLink & 0x1) == 0 ) || ( pAdapter->Bmsr.bits.link_status )) + { + /********************************************************************** + gate off paths we do not want active and leave ones we do + *********************************************************************/ + pm_csr = pAdapter->CSRAddress->global.pm_csr; + + pm_csr.bits.pm_sysclk_gate = 0; + pm_csr.bits.pm_txclk_gate = 0; + pm_csr.bits.pm_rxclk_gate = 1; + + pAdapter->CSRAddress->global.pm_csr = pm_csr; + } + + /************************************************************************** + Set the power state to 1 (d1), and blip the PME status pin. Set the + PME Enable pin, which indicates wake state to PCI. + *************************************************************************/ + uPmCsr = 0x00008100; + NdisWritePciSlotInformation( pAdapter->AdapterHandle, + 0, // Slot no. Reserved. Ndis ignores. + ET1310_PCI_PM_CSR, + &uPmCsr, + sizeof( UINT32 )); + + DBGPRINT( MP_TRACE, ( "<---- MPSetPowerD1Wake\n" )); + return; +} +/*===========================================================================*/ + + + + + +/****************************************************************************** + ROUTINE: MPSetPowerD1NonWake + ****************************************************************************** + DESCRIPTION: + This routine is called when the adapter receives a SetPower to + D1 PowerState, and there are no wake-up patterns programmed + in the adapter. + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +VOID MPSetPowerD1NonWake( PMP_ADAPTER pAdapter ) +{ + UINT32 uPmCsr; + PM_CSR_t pm_csr; + /*-----------------------------------------------------------------------*/ + + DBGPRINT( MP_TRACE, ( "----> MPSetPowerD1NonWake\n" )); + + /************************************************************************** + common power down functionality; disable Tx & Rx, disable wol, + archive Tx and Rx enable, and do some of the gating into jagcore. + *************************************************************************/ + MPSetLowPower( pAdapter, NdisDeviceStateD1 ); + + /************************************************************************** + gate off paths we do not want active and leave ones we do + *************************************************************************/ + pm_csr = pAdapter->CSRAddress->global.pm_csr; + + pm_csr.bits.pm_sysclk_gate = 1; + pm_csr.bits.pm_txclk_gate = 1; + pm_csr.bits.pm_rxclk_gate = 1; + + pAdapter->CSRAddress->global.pm_csr = pm_csr; + + /************************************************************************** + Set the power state to 1 (d1), and blip the PME status pin. Leave the + PME Enable pin clear, which indicates non-wake state to PCI. + *************************************************************************/ + uPmCsr = 0x00008000; + NdisWritePciSlotInformation( pAdapter->AdapterHandle, + 0, // Slot no. Reserved. Ndis ignores. + ET1310_PCI_PM_CSR, + &uPmCsr, + sizeof( UINT32 )); + + DBGPRINT( MP_TRACE, ( "<---- MPSetPowerD1NonWake\n" )); + return; +} +/*===========================================================================*/ + + + + + +/****************************************************************************** + ROUTINE: MPSetPowerD3Wake + ****************************************************************************** + DESCRIPTION: + This routine is called when the adapter receives a SetPower to + D3 PowerState, and there is a set of wake-up patterns programmed + in the adapter. The set could consist of a single wake-up pattern. + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +VOID MPSetPowerD3Wake( PMP_ADAPTER pAdapter ) +{ + UINT32 uPmCsr; + PM_CSR_t pm_csr; + /*-----------------------------------------------------------------------*/ + + DBGPRINT( MP_TRACE, ( "----> MPSetPowerD3Wake\n" )); + + /************************************************************************** + common power down functionality; disable Tx & Rx, disable wol while + it is being provisioned, archive Tx and Rx enable, and do some of the + gating into jagcore. + *************************************************************************/ + MPSetLowPower( pAdapter, NdisDeviceStateD3 ); + + if((( pAdapter->RegistryWOLLink & 0x1) == 0 ) || ( pAdapter->Bmsr.bits.link_status )) + { + /********************************************************************** + gate off paths we do not want active and leave ones we do + *********************************************************************/ + pm_csr = pAdapter->CSRAddress->global.pm_csr; + + pm_csr.bits.pm_sysclk_gate = 0; + pm_csr.bits.pm_txclk_gate = 0; + pm_csr.bits.pm_rxclk_gate = 1; + + pAdapter->CSRAddress->global.pm_csr = pm_csr; + } + + /************************************************************************** + Set the power state to 3 (d3), and blip the PME status pin. Set the + PME Enable pin, which indicates wake state to PCI. + *************************************************************************/ + uPmCsr = 0x00008100; + NdisWritePciSlotInformation( pAdapter->AdapterHandle, + 0, // Slot no. Reserved. Ndis ignores. + ET1310_PCI_PM_CSR, + &uPmCsr, + sizeof( UINT32 )); + + DBGPRINT( MP_TRACE, ( "<---- MPSetPowerD3Wake\n" )); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: MPSetPowerD3NonWake + ****************************************************************************** + DESCRIPTION: + This routine is called when the adapter receives a SetPower to + D3 PowerState, and there are no wake-up patterns programmed + in the adapter. + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +VOID MPSetPowerD3NonWake( PMP_ADAPTER pAdapter ) +{ + UINT32 uPmCsr; + PM_CSR_t pm_csr; + /*-----------------------------------------------------------------------*/ + + DBGPRINT( MP_TRACE, ( "----> MPSetPowerD3NonWake\n" )); + + /************************************************************************** + common power down functionality; disable Tx & Rx, disable wol, + archive Tx and Rx enable, and do some of the gating into jagcore. + *************************************************************************/ + MPSetLowPower( pAdapter, NdisDeviceStateD3 ); + + /************************************************************************** + gate off paths we do not want active and leave ones we do + *************************************************************************/ + pm_csr = pAdapter->CSRAddress->global.pm_csr; + pm_csr.bits.pm_sysclk_gate = 1; + pm_csr.bits.pm_txclk_gate = 1; + pm_csr.bits.pm_rxclk_gate = 1; + + pAdapter->CSRAddress->global.pm_csr = pm_csr; + + /************************************************************************** + Set the power state to 3 (d3), and blip the PME status pin. Leave the + PME Enable pin clear, which indicates non-wake state to PCI. + *************************************************************************/ + uPmCsr = 0x00008000; + NdisWritePciSlotInformation( pAdapter->AdapterHandle, + 0, // Slot no. Reserved. Ndis ignores. + ET1310_PCI_PM_CSR, + &uPmCsr, + sizeof( UINT32 )); + + DBGPRINT( MP_TRACE, ( "<---- MPSetPowerD3NonWake\n" )); + + return; +} +/*===========================================================================*/ + +#endif + + +/****************************************************************************** + ROUTINE: EnablePhyComa + ****************************************************************************** + DESCRIPTION: + This routine is called when network cable is unplugged -- driver + receive an phy status change interrupt while in D0 and check that + phy_status is down. + + -- gate off JAGCore; + -- set gigE PHY in Coma mode + -- wake on phy_interrupt; Perform software reset JAGCore, + re-initialize jagcore and gigE PHY + + Add D0-ASPM-PhyLinkDown Support: + -- while in D0, when there is a phy_interrupt indicating phy link + down status, call the MPSetPhyComa routine to enter this active + state power saving mode + -- while in D0-ASPM-PhyLinkDown mode, when there is a phy_interrupt + indicating linkup status, call the MPDisablePhyComa routine to + restore JAGCore and gigE PHY + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void EnablePhyComa( ET131X_ADAPTER *pAdapter ) +{ + unsigned long lockflags; + PM_CSR_t GlobalPmCSR = pAdapter->CSRAddress->global.pm_csr; + INT32 LoopCounter = 10; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "EnablePhyComa" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Save the GbE PHY speed and duplex modes + Need to restore this when cable is plugged back in + *************************************************************************/ + pAdapter->PoMgmt.PowerDownSpeed = pAdapter->AiForceSpeed; + pAdapter->PoMgmt.PowerDownDuplex = pAdapter->AiForceDpx; + + + /************************************************************************** + Stop sending packets. + *************************************************************************/ + spin_lock_irqsave( &pAdapter->SendHWLock, lockflags ); + + MP_SET_FLAG( pAdapter, fMP_ADAPTER_LOWER_POWER ); + + spin_unlock_irqrestore( &pAdapter->SendHWLock, lockflags ); + + + /************************************************************************** + Wait for outstanding Receive packets + *************************************************************************/ + while(( MP_GET_RCV_REF( pAdapter ) != 0 ) && ( LoopCounter-- > 0 )) + { + /********************************************************************** + Sleep for 2 Ms; + *********************************************************************/ + mdelay( 2 ); + } + + + /************************************************************************** + Gate off JAGCore 3 clock domains + *************************************************************************/ + GlobalPmCSR.bits.pm_sysclk_gate = 0; + GlobalPmCSR.bits.pm_txclk_gate = 0; + GlobalPmCSR.bits.pm_rxclk_gate = 0; + pAdapter->CSRAddress->global.pm_csr = GlobalPmCSR; + + + /************************************************************************** + Program gigE PHY in to Coma mode + *************************************************************************/ + GlobalPmCSR.bits.pm_phy_sw_coma = 1; + + pAdapter->CSRAddress->global.pm_csr = GlobalPmCSR; + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: DisablePhyComa + ****************************************************************************** + DESCRIPTION: + This routine is used to disable the Phy Coma Mode + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void DisablePhyComa( ET131X_ADAPTER *pAdapter ) +{ + PM_CSR_t GlobalPmCSR = pAdapter->CSRAddress->global.pm_csr; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "DisablePhyComa" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************* + Disable phy_sw_coma register and re-enable JAGCore clocks + ************************************************************************/ + GlobalPmCSR.bits.pm_sysclk_gate = 1; + GlobalPmCSR.bits.pm_txclk_gate = 1; + GlobalPmCSR.bits.pm_rxclk_gate = 1; + GlobalPmCSR.bits.pm_phy_sw_coma = 0; + + pAdapter->CSRAddress->global.pm_csr = GlobalPmCSR; + + + /************************************************************************** + Restore the GbE PHY speed and duplex modes; + Reset JAGCore; re-configure and initialize JAGCore and gigE PHY + *************************************************************************/ + pAdapter->AiForceSpeed = pAdapter->PoMgmt.PowerDownSpeed; + pAdapter->AiForceDpx = pAdapter->PoMgmt.PowerDownDuplex; + + + /************************************************************************** + Re-initialize the send structures + *************************************************************************/ + et131x_init_send( pAdapter ); + + + /************************************************************************** + Reset the RFD list and re-start RU + *************************************************************************/ + et131x_reset_recv( pAdapter ); + + + /************************************************************************** + Bring the device back to the state it was during init prior to + autonegotiation being complete. This way, when we get the auto-neg + complete interrupt, we can complete init by calling ConfigMacREGS2. + *************************************************************************/ + et131x_soft_reset( pAdapter ); + + + /************************************************************************** + setup et1310 as per the documentation ?? + *************************************************************************/ + et131x_adapter_setup( pAdapter ); + + + /************************************************************************** + Allow Tx to restart + *************************************************************************/ + MP_CLEAR_FLAG( pAdapter, fMP_ADAPTER_LOWER_POWER ); + + + /************************************************************************** + Need to re-enable Rx. + *************************************************************************/ + et131x_rx_dma_enable( pAdapter ); + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + +#if 0 +/****************************************************************************** + ROUTINE: MPSetPower + ****************************************************************************** + + DESCRIPTION: + This routine is called when the adapter receives a SetPower + request. It redirects the call to an appropriate routine to + Set the New PowerState + + PARAMETERS : + pAdapter - pointer to the adapter structure + PowerState - NewPowerState + + RETURN : + NONE + + *****************************************************************************/ +VOID MPSetPower( IN PMP_ADAPTER pAdapter, + IN NDIS_DEVICE_POWER_STATE PowerState ) +{ + DBGPRINT( MP_TRACE, ( "====> MPSetPower()\n" )); + + /************************************************************************** + determine what power state we are going to and go there + *************************************************************************/ + pAdapter->PoMgmt.WOLEnabledByCurrentState = TRUE; + + if( !pAdapter->PoMgmt.WOLEnabledByNdis ) + { + pAdapter->PoMgmt.WOLEnabledByCurrentState = FALSE; + } + + if(( pAdapter->RegistryWOLMatch == 0 ) && ( pAdapter->RegistryWOLLink == 0 )) + { + pAdapter->PoMgmt.WOLEnabledByCurrentState = FALSE; + } + + if(( pAdapter->PoMgmt.localWolAndCrc0 & 0x1f ) == 0 ) + { + /********************************************************************** + There are no wake patterns programmed. + *********************************************************************/ + if( pAdapter->RegistryWOLLink == 0 ) + { + pAdapter->PoMgmt.WOLEnabledByCurrentState = FALSE; + } + } + + /************************************************************************** + If the link is pulled, then the only wake event that will wake us + up is wake on link state change. If this change is disabled (0), go + to a non-wake state. + *************************************************************************/ + if( !pAdapter->ucLinkStatus && ( pAdapter->RegistryWOLLink == 0 )) + { + pAdapter->PoMgmt.WOLEnabledByCurrentState = 0; + } + + if( PowerState == NdisDeviceStateD0 ) + { + MPSetPowerD0( pAdapter ); + } + else if( PowerState == NdisDeviceStateD1 ) + { + if( pAdapter->PoMgmt.WOLEnabledByCurrentState ) + { + MPSetPowerD1Wake( pAdapter ); + } + else + { + MPSetPowerD1NonWake( pAdapter ); + } + } + else if( PowerState == NdisDeviceStateD3 ) + { + if( pAdapter->PoMgmt.WOLEnabledByCurrentState ) + { + MPSetPowerD3Wake( pAdapter ); + } + else + { + MPSetPowerD3NonWake( pAdapter ); + } + } + + DBGPRINT( MP_TRACE, ( "<==== MPSetPower()\n" )); +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: MPFillPoMgmtCaps + ****************************************************************************** + + DESCRIPTION: + Fills in the Power Managment structure depending the capabilities of + the software driver and the card. MGS CURRENTLY NOT SUPPORTED + + + PARAMETERS : + pAdapter - pointer to the adapter structure + pPowManageCaps - power management struct as defined in the DDK, + pStatus - status to be returned by the request, + pulInfoLen - length of the pPowerManagmentCapabilites + + RETURN : + Success or failure + + NOTE: + If the driver returns NDIS_STATUS_SUCCESS in response to a query of + this OID, NDIS treats a miniport driver as power management-aware. + If the driver returns NDIS_STATUS_NOT_SUPPORTED, NDIS treats the + miniport driver as a legacy driver that is not power + management-aware. + + The Bus driver is the power policy owner here so we do not have to + perform our mapping of System States to Device states, that is + accomplished by NDIS, we need to worry more about our wake-up + capabilities + + *****************************************************************************/ +VOID MPFillPoMgmtCaps( IN PMP_ADAPTER pAdapter, + IN OUT PNDIS_PNP_CAPABILITIES pPowMgmtCaps, + IN OUT PNDIS_STATUS pStatus, + IN OUT PULONG pulInfoLen ) +{ + BOOLEAN bIsPoMgmtSupported = TRUE; + /*-----------------------------------------------------------------------*/ + + bIsPoMgmtSupported = MPIsPoMgmtSupported( pAdapter ); + + if( bIsPoMgmtSupported ) + { + /********************************************************************** + NDIS_DEVICE_WAKE_UP_ENABLE; + *********************************************************************/ + pPowMgmtCaps->Flags = 0; + + /********************************************************************** + Magic Packet wakeups + *********************************************************************/ + pPowMgmtCaps->WakeUpCapabilities.MinMagicPacketWakeUp = + NdisDeviceStateD3; + + /********************************************************************** + NdisDeviceStateD3; + *********************************************************************/ + pPowMgmtCaps->WakeUpCapabilities.MinPatternWakeUp = + NdisDeviceStateD3; + pPowMgmtCaps->WakeUpCapabilities.MinLinkChangeWakeUp = + NdisDeviceStateD3; + + *pulInfoLen = sizeof( *pPowMgmtCaps ); + *pStatus = NDIS_STATUS_SUCCESS; + } + else + { + NdisZeroMemory( pPowMgmtCaps, sizeof( *pPowMgmtCaps )); + + *pStatus = NDIS_STATUS_NOT_SUPPORTED; + *pulInfoLen = 0; + } +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: MPAddWakeUpPattern + ****************************************************************************** + + DESCRIPTION: + This routine will allocate a local memory structure, copy the pattern, + insert the pattern into a linked list and return success + + We are gauranteed that we wll get only one request at a time, so this + is implemented without locks. + + PARAMETERS : + pAdapter - pointer to the adapter structure + InformationBuffer - Wake up Pattern + InformationBufferLength - Wake Up Pattern Length + + RETURN : + Success - if successful + NDIS_STATUS_FAILURE - if memory allocation fails + + *****************************************************************************/ +NDIS_STATUS MPAddWakeUpPattern( IN PMP_ADAPTER pAdapter, + IN PVOID InfoBuf, + IN UINT InfoBufLen ) +{ + NDIS_STATUS Status; + PNDIS_PM_PACKET_PATTERN pPmPattern = NULL; + UINT Slot = 0, FreeSlot = 0xff; + PUCHAR pNdisPatternMask; + PUINT32 pDevicePatternMask; + UINT16 DevMagicNumber; + UINT i; + + PUCHAR TempBuf; + ULONG offset; + + /*-----------------------------------------------------------------------*/ + + pPmPattern = (PNDIS_PM_PACKET_PATTERN)InfoBuf; + + /************************************************************************** + Check that the wake-up pattern is not too large for us. Also, not + sure how to deal with a pattern whose mask is smaller than the pattern + *************************************************************************/ + if(( pPmPattern->MaskSize < (( pPmPattern->PatternSize / 8) + 1)) || + ( pPmPattern->PatternSize > MAX_WOL_PACKET_SIZE)) + { + return( NDIS_STATUS_RESOURCES ); + } + + NdisAcquireSpinLock( &pAdapter->Lock ); + + /************************************************************************** + Check to see if there is an empty slot on the device to store this + pattern. Store the slot number for later use. + *************************************************************************/ + while ((FreeSlot == 0xff) && (Slot < NUM_WOL_PATTERNS)) + { + if (!((pAdapter->PoMgmt.localWolAndCrc0 >> Slot) & 0x1)) + { + FreeSlot = Slot; + } + else + { + Slot++; + } + } + + if( FreeSlot == 0xff ) + { + /********************************************************************** + Failed to find a free slot. + *********************************************************************/ + NdisReleaseSpinLock( &pAdapter->Lock ); + return( NDIS_STATUS_RESOURCES ); + } + + pNdisPatternMask = (PUCHAR)InfoBuf + sizeof( NDIS_PM_PACKET_PATTERN ); + + /************************************************************************** + Make a copy of what Ndis sent us + *************************************************************************/ + for( i=0; iMaskSize; i++ ) + { + pAdapter->PoMgmt.WOLMaskList[ FreeSlot ][ i ] = pNdisPatternMask[ i ]; + } + + /************************************************************************** + Calculate the CRC that will be used by the device to identify this + packet + *************************************************************************/ + offset = 0; + TempBuf = (PUCHAR)( InfoBuf ) + pPmPattern->PatternOffset; + + DevMagicNumber = MPCalculateCCITCRC16( TempBuf, + (PUCHAR )( InfoBuf ) + + sizeof( NDIS_PM_PACKET_PATTERN ), + pPmPattern->MaskSize ); + + DBGPRINT( MP_SPEC, ( "DevMagicNumber 0x%08x\n", DevMagicNumber )); + DBGPRINT( MP_SPEC, ( "Pattern Size : 0x%08x, MaskSize : 0x%08x\n", + pPmPattern->PatternSize, pPmPattern->MaskSize )); + + pAdapter->PoMgmt.localWolAndCrc0 |= ( 1 << FreeSlot ); + + /************************************************************************** + Now handle storing the pattern in our adapter. Only store what makes + the pattern unique to our device. (the CRC, the mask and the mask + size. The pattern is irrelevant, since it is not stored in the + device). The mask is stored above. + *************************************************************************/ + pAdapter->PoMgmt.WOLPatternList[ FreeSlot ] = DevMagicNumber; + pAdapter->PoMgmt.WOLMaskSize[ FreeSlot ] = pPmPattern->MaskSize; + + NdisReleaseSpinLock( &pAdapter->Lock ); + return( NDIS_STATUS_SUCCESS ); +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: MPRemoveWakeUpPattern + ****************************************************************************** + + DESCRIPTION: + This routine will scan the array of wake up patterns and attempt to + match the wake up pattern. If it finds a copy , it will remove that + WakeUpPattern + + PARAMETERS: + pAdapter - pointer to the Adapter structure + InformationBuffer - Wake up Pattern + InformationBufferLength - Wake Up Pattern Length + + RETURN: + Success - if successful. + NDIS_STATUS_FAILURE - if memory allocation fails. + + *****************************************************************************/ +NDIS_STATUS MPRemoveWakeUpPattern( IN PMP_ADAPTER pAdapter, + IN PVOID InformationBuffer, + IN UINT InformationBufferLength ) +{ + + PNDIS_PM_PACKET_PATTERN pPmPattern = NULL; + UINT Slot = 0, FoundSlot = 0xff; + UINT16 DevMagicNumber; + /*-----------------------------------------------------------------------*/ + + pPmPattern = (PNDIS_PM_PACKET_PATTERN)InformationBuffer; + + /************************************************************************** + Check that the wake-up pattern is not too large for us. Also, not + sure how to deal with a pattern whose mask is not the same size + as the pattern. + *************************************************************************/ + if(( pPmPattern->MaskSize < (( pPmPattern->PatternSize / 8) + 1)) || + ( pPmPattern->PatternSize > MAX_WOL_PACKET_SIZE)) + { + return NDIS_STATUS_FAILURE; + } + + /************************************************************************** + Calculate the CRC that will be used by the device to identify this + packet + *************************************************************************/ + DevMagicNumber = MPCalculateCCITCRC16( (PUCHAR )( InformationBuffer ) + + pPmPattern->PatternOffset , + (PUCHAR )( InformationBuffer ) + + sizeof( NDIS_PM_PACKET_PATTERN ), + pPmPattern->MaskSize ); + + NdisAcquireSpinLock( &pAdapter->Lock ); + + while ((FoundSlot == 0xff) && (Slot < NUM_WOL_PATTERNS)) + { + if(( pAdapter->PoMgmt.WOLPatternList[ Slot ] == DevMagicNumber ) && + ( pAdapter->PoMgmt.WOLMaskSize[ Slot ] == pPmPattern->MaskSize ) && + (( pAdapter->PoMgmt.localWolAndCrc0 >> Slot ) & 0x1) ) + { + UINT i; + PUCHAR pIncomingMask = (PUCHAR)( InformationBuffer ) + + sizeof( NDIS_PM_PACKET_PATTERN ); + + for( i=0; iMaskSize; i++ ) + { + if( pAdapter->PoMgmt.WOLMaskList[ Slot ][ i ] != + pIncomingMask[ i ] ) + { + break; + } + } + if( i >= pPmPattern->MaskSize ) + { + FoundSlot = Slot; + } + } + + Slot++; + } + + if( FoundSlot == 0xff ) + { + /********************************************************************** + Failed to find this packet in the list coinciding with a valid + entry in the device. + *********************************************************************/ + NdisReleaseSpinLock( &pAdapter->Lock ); + return( NDIS_STATUS_FAILURE ); + } + + pAdapter->PoMgmt.localWolAndCrc0 &= ~( 1 << FoundSlot ); + + NdisReleaseSpinLock( &pAdapter->Lock ); + + return( NDIS_STATUS_SUCCESS ); +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: MPRemoveAllWakeUpPatterns + ****************************************************************************** + + DESCRIPTION: + This routine disables all wake-up on the device. Probably not + required. + + PARAMETERS: + pAdapter - pointer to the adapter structure + + RETURN: + Nothing + + *****************************************************************************/ +VOID MPRemoveAllWakeUpPatterns( IN PMP_ADAPTER pAdapter ) +{ + RXMAC_WOL_CTL_CRC0_t crc0; + /*-----------------------------------------------------------------------*/ + + if( pAdapter ) + { + NdisAcquireSpinLock( &pAdapter->Lock ); + + pAdapter->PoMgmt.localWolAndCrc0 = 0; + + NdisReleaseSpinLock( &pAdapter->Lock ); + } +} +/*===========================================================================*/ + +#endif --- linux-2.6.28.orig/ubuntu/et131x/ET1310_eeprom.c +++ linux-2.6.28/ubuntu/et131x/ET1310_eeprom.c @@ -0,0 +1,710 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_eeprom.c - Code used to access the device's EEPROM + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2006/01/18 22:18:33 $ + $Revision: 1.6 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" +#include "ET1310_eeprom.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" +#include "et131x_initpci.h" +#include "et131x_isr.h" + +#include "ET1310_tx.h" + + + + +/****************************************************************************** + EEPROM Defines + *****************************************************************************/ +/* LBCIF Register Groups (addressed via 32-bit offsets) */ +#define LBCIF_DWORD0_GROUP_OFFSET 0xAC +#define LBCIF_DWORD1_GROUP_OFFSET 0xB0 + +/* LBCIF Registers (addressed via 8-bit offsets) */ +#define LBCIF_ADDRESS_REGISTER_OFFSET 0xAC +#define LBCIF_DATA_REGISTER_OFFSET 0xB0 +#define LBCIF_CONTROL_REGISTER_OFFSET 0xB1 +#define LBCIF_STATUS_REGISTER_OFFSET 0xB2 + +/* LBCIF Control Register Bits */ +#define LBCIF_CONTROL_SEQUENTIAL_READ 0x01 +#define LBCIF_CONTROL_PAGE_WRITE 0x02 +#define LBCIF_CONTROL_UNUSED1 0x04 +#define LBCIF_CONTROL_EEPROM_RELOAD 0x08 +#define LBCIF_CONTROL_UNUSED2 0x10 +#define LBCIF_CONTROL_TWO_BYTE_ADDR 0x20 +#define LBCIF_CONTROL_I2C_WRITE 0x40 +#define LBCIF_CONTROL_LBCIF_ENABLE 0x80 + +/* LBCIF Status Register Bits */ +#define LBCIF_STATUS_PHY_QUEUE_AVAIL 0x01 +#define LBCIF_STATUS_I2C_IDLE 0x02 +#define LBCIF_STATUS_ACK_ERROR 0x04 +#define LBCIF_STATUS_GENERAL_ERROR 0x08 +#define LBCIF_STATUS_UNUSED 0x30 +#define LBCIF_STATUS_CHECKSUM_ERROR 0x40 +#define LBCIF_STATUS_EEPROM_PRESENT 0x80 + +/* Miscellaneous Constraints */ +#define MAX_NUM_REGISTER_POLLS 1000 +#define MAX_NUM_WRITE_RETRIES 2 + + + + +/****************************************************************************** + Define macros that allow individual register values to be extracted from a + DWORD1 register grouping + *****************************************************************************/ +#define EXTRACT_DATA_REGISTER(x) (UCHAR)(x & 0xFF) +#define EXTRACT_STATUS_REGISTER(x) (UCHAR)((x >> 16) & 0xFF) +#define EXTRACT_CONTROL_REG(x) (UCHAR)((x >> 8) & 0xFF) + + + + +static INT32 LbcifWriteByte( ET131X_ADAPTER *pAdapter, UINT32 unOffset, UCHAR bByte ) +{ + return EEPROM_access( pAdapter, WRITE, unOffset, 8, &bByte ); +} + + +static INT32 LbcifReadDword( ET131X_ADAPTER *pAdapter, UINT32 unOffset, PUINT32 punData ) +{ + return EEPROM_access( pAdapter, READ, unOffset, 32, punData ); +} + + +static INT32 LbcifWriteDword( ET131X_ADAPTER *pAdapter,UINT32 unOffset, UINT32 unData ) +{ + return EEPROM_access( pAdapter, WRITE, unOffset, 32, &unData ); +} + + + + +/****************************************************************************** + ROUTINE : EepromWriteByte + ****************************************************************************** + + DESCRIPTION : Write a byte to the ET1310's EEPROM + + PARAMETERS : pAdapter - pointer to our private adapter structure + unAddress - the address to write + bData - the value to write + unEepronId - the ID of the EEPROM + unAddressingMode - how the EEPROM is to be accessed + + RETURNS : SUCCESS or FAILURE + + REUSE INFORMATION : + + *****************************************************************************/ +INT32 EepromWriteByte( ET131X_ADAPTER *pAdapter, UINT32 unAddress, UCHAR bData, + UINT32 unEepromId, UINT32 unAddressingMode ) +{ + INT32 nIndex; + INT32 nRetries; + INT32 nError = FALSE; + INT32 nI2CWriteActive = 0; + INT32 nWriteSuccessful = 0; + UCHAR bControl; + UCHAR bStatus = 0; + UINT32 unDword1 = 0; + + UINT32 unData = 0; + /*-----------------------------------------------------------------------*/ + + + /************************************************************************** + The following excerpt is from "Serial EEPROM HW Design Specification" + Version 0.92 (9/20/2004): + + Single Byte Writes + + For an EEPROM, an I2C single byte write is defined as a START + condition followed by the device address, EEPROM address, one byte + of data and a STOP condition. The STOP condition will trigger the + EEPROM's internally timed write cycle to the nonvolatile memory. + All inputs are disabled during this write cycle and the EEPROM will + not respond to any access until the internal write is complete. + The steps to execute a single byte write are as follows: + + 1. Check LBCIF Status Register for bits 6 & 3:2 all equal to 0 and + bits 7,1:0 both equal to 1, at least once after reset. Subsequent + operations need only to check that bits 1:0 are equal to 1 prior + to starting a single byte write. + + 2. Write to the LBCIF Control Register: bit 7=1, bit 6=1, bit 3=0, + and bits 1:0 both =0. Bit 5 should be set according to the type + of EEPROM being accessed (1=two byte addressing, 0=one byte + addressing). + + 3. Write the address to the LBCIF Address Register. + + 4. Write the data to the LBCIF Data Register (the I2C write will + begin). + + 5. Monitor bit 1:0 of the LBCIF Status Register. When bits 1:0 are + both equal to 1, the I2C write has completed and the internal + write cycle of the EEPROM is about to start. (bits 1:0 = 01 is a + legal state while waiting from both equal to 1, but bits 1:0 = 10 + is invalid and implies that something is broken). + + 6. Check bit 3 of the LBCIF Status Register. If equal to 1, an + error has occurred. + + 7. Check bit 2 of the LBCIF Status Register. If equal to 1 an ACK + error has occurred on the address phase of the write. This could + be due to an actual hardware failure or the EEPROM may still be in + its internal write cycle from a previous write. This write oper- + ation was ignored and must be repeated later. + + 8. Set bit 6 of the LBCIF Control Register = 0. If another write is + required, go to step 1. + *************************************************************************/ + + + /************************************************************************** + Step 1: + *************************************************************************/ + for( nIndex = 0; nIndex < MAX_NUM_REGISTER_POLLS; nIndex++) + { + /********************************************************************** + Read registers grouped in DWORD1 + *********************************************************************/ + if( LbcifReadDword( pAdapter, LBCIF_DWORD1_GROUP_OFFSET, &unDword1 )) + { + nError = 1; + break; + } + + bStatus = EXTRACT_STATUS_REGISTER( unDword1 ); + + if( bStatus & LBCIF_STATUS_PHY_QUEUE_AVAIL && + bStatus & LBCIF_STATUS_I2C_IDLE ) + { + /****************************************************************** + bits 1:0 are equal to 1 + *****************************************************************/ + break; + } + } + + if( nError || ( nIndex >= MAX_NUM_REGISTER_POLLS )) + { + return( FAILURE ); + } + + + /************************************************************************** + Step 2: + *************************************************************************/ + bControl = 0; + bControl |= LBCIF_CONTROL_LBCIF_ENABLE | LBCIF_CONTROL_I2C_WRITE; + + if( unAddressingMode == DUAL_BYTE ) + { + bControl |= LBCIF_CONTROL_TWO_BYTE_ADDR; + } + + if( LbcifWriteByte( pAdapter, LBCIF_CONTROL_REGISTER_OFFSET, bControl )) + { + return( FAILURE ); + } + + nI2CWriteActive = 1; + + + /************************************************************************** + Prepare EEPROM address for Step 3 + *************************************************************************/ + unAddress |= ( unAddressingMode == DUAL_BYTE ) ? + ( unEepromId << 16 ) : ( unEepromId << 8 ); + + for( nRetries = 0; nRetries < MAX_NUM_WRITE_RETRIES; nRetries++ ) + { + /********************************************************************** + Step 3: + *********************************************************************/ + if( LbcifWriteDword( pAdapter, LBCIF_ADDRESS_REGISTER_OFFSET, unAddress )) + { + break; + } + + /********************************************************************** + Step 4: + *********************************************************************/ + if( LbcifWriteByte( pAdapter, LBCIF_DATA_REGISTER_OFFSET, bData )) + { + break; + } + + /********************************************************************** + Step 5: + *********************************************************************/ + for( nIndex = 0; nIndex < MAX_NUM_REGISTER_POLLS; nIndex++ ) + { + /****************************************************************** + Read registers grouped in DWORD1 + *****************************************************************/ + if( LbcifReadDword( pAdapter, LBCIF_DWORD1_GROUP_OFFSET, + &unDword1 )) + { + nError = 1; + break; + } + + bStatus = EXTRACT_STATUS_REGISTER( unDword1 ); + + if( bStatus & LBCIF_STATUS_PHY_QUEUE_AVAIL && + bStatus & LBCIF_STATUS_I2C_IDLE ) + { + /************************************************************** + I2C write complete + *************************************************************/ + break; + } + } + + if( nError || ( nIndex >= MAX_NUM_REGISTER_POLLS )) + { + break; + } + + + /********************************************************************** + Step 6: Don't break here if we are revision 1, this is so we do a + blind write for load bug. + *********************************************************************/ + if( bStatus & LBCIF_STATUS_GENERAL_ERROR && pAdapter->RevisionID == 0 ) + { + break; + } + + + /********************************************************************** + Step 7: + *********************************************************************/ + if( bStatus & LBCIF_STATUS_ACK_ERROR ) + { + /****************************************************************** + This could be due to an actual hardware failure or the EEPROM + may still be in its internal write cycle from a previous write. + This write operation was ignored and must be repeated later. + *****************************************************************/ + udelay( 10 ); + continue; + } + + nWriteSuccessful = 1; + break; + } + + + /************************************************************************** + Step 8: + *************************************************************************/ + udelay( 10 ); + nIndex = 0; + while( nI2CWriteActive ) + { + bControl &= ~LBCIF_CONTROL_I2C_WRITE; + + if( LbcifWriteByte( pAdapter, LBCIF_CONTROL_REGISTER_OFFSET, bControl )) + { + nWriteSuccessful = 0; + } + + /* Do read until internal ACK_ERROR goes away meaning write completed */ + for( ;; ) + { + /* unAddress */ + LbcifWriteDword( pAdapter, LBCIF_ADDRESS_REGISTER_OFFSET, unAddress ); + + for( ;; ) + { + LbcifReadDword( pAdapter, LBCIF_DATA_REGISTER_OFFSET, &unData ); + + if( unData & 0x00010000 ) + { + break; + } + } + + if(( unData & 0x00040000 ) == 0x0 ) + { + break; + } + } + + bControl = EXTRACT_CONTROL_REG( unData ); + + if( bControl != 0xC0 || nIndex == 10000 ) + { + break; + } + + nIndex++; + } + + return(( nWriteSuccessful ) ? SUCCESS : FAILURE ); +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : EepromReadByte + ****************************************************************************** + + DESCRIPTION : Read a byte from the ET1310's EEPROM + + PARAMETERS : pAdapter - pointer to our private adapter structure + unAddress - the address from which to read + pbData - a pointer to a byte in which to store the + value of the read + unEepronId - the ID of the EEPROM + unAddressingMode - how the EEPROM is to be accessed + + RETURNS : SUCCESS or FAILURE + + REUSE INFORMATION : + + *****************************************************************************/ +INT32 EepromReadByte( ET131X_ADAPTER *pAdapter, UINT32 unAddress, PUCHAR pbData, + UINT32 unEepromId, UINT32 unAddressingMode ) +{ + INT32 nIndex; + INT32 nError = 0; + INT32 nReadSuccessful = 0; + UCHAR bControl; + UCHAR bStatus = 0; + UINT32 unDword1 = 0; + /*-----------------------------------------------------------------------*/ + + + /************************************************************************** + The following excerpt is from "Serial EEPROM HW Design Specification" + Version 0.92 (9/20/2004): + + Single Byte Reads + + A single byte read is similar to the single byte write, with the + exception of the data flow: + + 1. Check LBCIF Status Register for bits 6 & 3:2 all equal to 0 and + bits 7,1:0 both equal to 1, at least once after reset. Subsequent + operations need only to check that bits 1:0 are equal to 1 prior + to starting a single byte read. + + 2. Write to the LBCIF Control Register: bit 7=1, bit 6=0, bit 3=0, + and bits 1:0 both =0. Bit 5 should be set according to the type + of EEPROM being accessed (1=two byte addressing, 0=one byte addr- + essing). + + 3. Write the address to the LBCIF Address Register (I2C read will + begin). + + 4. Monitor bit 0 of the LBCIF Status Register. When =1, I2C read is + complete. (if bit 1 =1 and bit 0 stays =0, a hardware failure has + occurred). + + 5. Check bit 2 of the LBCIF Status Register. If =1, then an error has + occurred. The data that has been returned from the PHY may be + invalid. + + 6. Regardless of error status, read data byte from LBCIF Data Register. + If another byte is required, go to step 1. + *************************************************************************/ + + + /************************************************************************** + Step 1: + *************************************************************************/ + for( nIndex = 0; nIndex < MAX_NUM_REGISTER_POLLS; nIndex++) + { + /********************************************************************** + Read registers grouped in DWORD1 + *********************************************************************/ + if( LbcifReadDword( pAdapter, LBCIF_DWORD1_GROUP_OFFSET, &unDword1 )) + { + nError = 1; + break; + } + + bStatus = EXTRACT_STATUS_REGISTER( unDword1 ); + + if( bStatus & LBCIF_STATUS_PHY_QUEUE_AVAIL && + bStatus & LBCIF_STATUS_I2C_IDLE ) + { + /****************************************************************** + bits 1:0 are equal to 1 + *****************************************************************/ + break; + } + } + + if( nError || ( nIndex >= MAX_NUM_REGISTER_POLLS )) + { + return( FAILURE ); + } + + + /************************************************************************** + Step 2: + *************************************************************************/ + bControl = 0; + bControl |= LBCIF_CONTROL_LBCIF_ENABLE; + + if( unAddressingMode == DUAL_BYTE ) + { + bControl |= LBCIF_CONTROL_TWO_BYTE_ADDR; + } + + if( LbcifWriteByte( pAdapter, LBCIF_CONTROL_REGISTER_OFFSET, bControl )) + { + return( FAILURE ); + } + + + /************************************************************************** + Step 3: + *************************************************************************/ + unAddress |= ( unAddressingMode == DUAL_BYTE ) ? + ( unEepromId << 16 ) : ( unEepromId << 8 ); + + if( LbcifWriteDword( pAdapter, LBCIF_ADDRESS_REGISTER_OFFSET, unAddress )) + { + return( FAILURE ); + } + + + /************************************************************************** + Step 4: + *************************************************************************/ + for( nIndex = 0; nIndex < MAX_NUM_REGISTER_POLLS; nIndex++ ) + { + /********************************************************************** + Read registers grouped in DWORD1 + *********************************************************************/ + if( LbcifReadDword( pAdapter, LBCIF_DWORD1_GROUP_OFFSET, &unDword1 )) + { + nError = 1; + break; + } + + bStatus = EXTRACT_STATUS_REGISTER( unDword1 ); + + if( bStatus & LBCIF_STATUS_PHY_QUEUE_AVAIL + && bStatus & LBCIF_STATUS_I2C_IDLE ) + { + /****************************************************************** + I2C read complete + *****************************************************************/ + break; + } + } + + if( nError || ( nIndex >= MAX_NUM_REGISTER_POLLS )) + { + return( FAILURE ); + } + + + /************************************************************************** + Step 5: + *************************************************************************/ + nReadSuccessful = ( bStatus & LBCIF_STATUS_ACK_ERROR ) ? 0 : 1; + + + /************************************************************************** + Step 6: + *************************************************************************/ + *pbData = EXTRACT_DATA_REGISTER( unDword1 ); + + return( nReadSuccessful ) ? SUCCESS : FAILURE; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : EEPROM_access + ****************************************************************************** + + DESCRIPTION : + Performs a read or write of a given data width at a specified offset + from EEPROM + + PARAMETERS : + pAdapter - [in] pointer to the adapter structure + bAccessFlag - [in] A flag indicating what type of transaction + READ/WRITE + unOffset - [in] Specifies the offset within the EEPROM + bWidth - [in] Defines the width (in bits) of the requested + access. Valid values are 8 or 32. + pData - [in/out] Pointer to a buffer that contains the data + requested by or resulting from the transaction + specified by 'bAccessFlag'. + Method in which this parameter is processed + (de-referenced) is determined by the value of + 'bWidth', i.e. 8-bit or 32-bit read/write + accesses. + + RETURNS : + result from PCI Config space access + + REUSE INFORMATION : + YES + + *****************************************************************************/ +UINT32 EEPROM_access( ET131X_ADAPTER *pAdapter, UCHAR bAccessFlag, + UINT32 unOffset, UCHAR bWidth, void *pData ) +{ + UINT32 ulResult; + /*-----------------------------------------------------------------------*/ + + if( bAccessFlag == WRITE ) + { + /********************************************************************** + we are doing a write + *********************************************************************/ + ulResult = pci_slot_information_write( pAdapter->pdev, + unOffset, + pData, + ( bWidth / 8 )); + } + else + { + /********************************************************************** + do the read read + *********************************************************************/ + ulResult = pci_slot_information_read( pAdapter->pdev, + unOffset, + pData, + ( bWidth / 8 )); + } + if( ulResult != 0 ) + { + return( 0 ); + } + else + { + return( ulResult ); + } +} +/*===========================================================================*/ --- linux-2.6.28.orig/ubuntu/et131x/ET1310_jagcore.h +++ linux-2.6.28/ubuntu/et131x/ET1310_jagcore.h @@ -0,0 +1,180 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_jagcore.h - Defines, structs, enums, prototypes, etc. pertaining to + * the JAGCore + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/10/28 18:43:44 $ + $Revision: 1.7 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET1310_JAGCORE_H__ +#define __ET1310_JAGCORE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/****************************************************************************** + INCLUDES + *****************************************************************************/ +#include "ET1310_common.h" + + + + +/****************************************************************************** + CONSTANTS FOR JAGCORE + *****************************************************************************/ +#define INTERNAL_MEM_SIZE 0x400 //1024 of internal memory +#define INTERNAL_MEM_RX_OFFSET 0x1FF //50% Tx, 50% Rx + +#define REGS_MAX_ARRAY 4096 + + + + +/****************************************************************************** + For interrupts, normal running is: + rxdma_xfr_done, phy_interrupt, mac_stat_interrupt, + watchdog_interrupt & txdma_xfer_done + + In both cases, when flow control is enabled for either Tx or bi-direction, + we additional enable rx_fbr0_low and rx_fbr1_low, so we know when the + buffer rings are running low. + *****************************************************************************/ +#define INT_MASK_DISABLE 0xffffffff + +// NOTE: Masking out MAC_STAT Interrupt for now... +//#define INT_MASK_ENABLE 0xfff6bf17 +//#define INT_MASK_ENABLE_NO_FLOW 0xfff6bfd7 +#define INT_MASK_ENABLE 0xfffebf17 +#define INT_MASK_ENABLE_NO_FLOW 0xfffebfd7 + + + + +/****************************************************************************** + DATA STRUCTURES FOR DIRECT REGISTER ACCESS + *****************************************************************************/ +typedef struct +{ + u8 bReadWrite; + u32 nRegCount; + u32 nData [REGS_MAX_ARRAY]; + u32 nOffsets [REGS_MAX_ARRAY]; +} JAGCORE_ACCESS_REGS, *PJAGCORE_ACCESS_REGS; + + +typedef struct +{ + u8 bReadWrite; + u32 nDataWidth; + u32 nRegCount; + u32 nOffsets [REGS_MAX_ARRAY]; + u32 nData [REGS_MAX_ARRAY]; +} PCI_CFG_SPACE_REGS, *PPCI_CFG_SPACE_REGS; + + + + +/****************************************************************************** + Forward declaration of the private adapter structure + *****************************************************************************/ +struct et131x_adapter; + + + + +/****************************************************************************** + PROTOTYPES + *****************************************************************************/ +void ConfigGlobalRegs(struct et131x_adapter *pAdapter ); + +void ConfigMMCRegs( struct et131x_adapter *pAdapter ); + +void et131x_enable_interrupts( struct et131x_adapter *adapter ); + +void et131x_disable_interrupts( struct et131x_adapter *adapter ); + +void * et131x_get_regs( struct et131x_adapter *pAdapter, void *InfoBuf, + PUINT32 ulBytesAvailable, PUINT32 ulInfoLen ); + +void et131x_set_regs( struct et131x_adapter *pAdapter, void *InfoBuf ); + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __ET1310_JAGCORE_H__ */ --- linux-2.6.28.orig/ubuntu/et131x/ET1310_address_map.h +++ linux-2.6.28/ubuntu/et131x/ET1310_address_map.h @@ -0,0 +1,3216 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_address_map.h - Contains the register mapping for the ET1310 + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/10/28 18:43:43 $ + $Revision: 1.8 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef _ET1310_ADDRESS_MAP_H_ +#define _ET1310_ADDRESS_MAP_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + some typedefs for compiler + *****************************************************************************/ +typedef s8 INT8, *PINT8; +typedef s16 INT16, *PINT16; +typedef s32 INT32, *PINT32; +typedef s64 INT64, *PINT64; + +typedef u8 UINT8, *PUINT8; +typedef u16 UINT16, *PUINT16; +typedef u32 UINT32, *PUINT32; +typedef u64 UINT64, *PUINT64; + +typedef u8 UCHAR, *PUCHAR; + + + + +/*===========================================================================*/ +/*===========================================================================*/ +/*=== START OF GLOBAL REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ +/****************************************************************************** + structure for tx queue start address reg in global address map + located at address 0x0000 + *****************************************************************************/ +typedef union _TXQ_START_ADDR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:22; //bits 10-31 + UINT32 txq_start:10; //bits 0-9 + #else + UINT32 txq_start:10; //bits 0-9 + UINT32 unused:22; //bits 10-31 + #endif + } bits; +} +TXQ_START_ADDR_t, *PTXQ_START_ADDR_t; + + +/****************************************************************************** + structure for tx queue end address reg in global address map + located at address 0x0004 + *****************************************************************************/ +typedef union _TXQ_END_ADDR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:22; //bits 10-31 + UINT32 txq_end:10; //bits 0-9 + #else + UINT32 txq_end:10; //bits 0-9 + UINT32 unused:22; //bits 10-31 + #endif + } bits; +} +TXQ_END_ADDR_t, *PTXQ_END_ADDR_t; + + +/****************************************************************************** + structure for rx queue start address reg in global address map + located at address 0x0008 + *****************************************************************************/ +typedef union _RXQ_START_ADDR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:22; //bits 10-31 + UINT32 rxq_start_addr:10; //bits 0-9 + #else + UINT32 rxq_start_addr:10; //bits 0-9 + UINT32 unused:22; //bits 10-31 + #endif + } bits; +} +RXQ_START_ADDR_t, *PRXQ_START_ADDR_t; + + +/****************************************************************************** + structure for rx queue end address reg in global address map + located at address 0x000C + *****************************************************************************/ +typedef union _RXQ_END_ADDR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:22; //bits 10-31 + UINT32 rxq_end_addr:10; //bits 0-9 + #else + UINT32 rxq_end_addr:10; //bits 0-9 + UINT32 unused:22; //bits 10-31 + #endif + } bits; +} +RXQ_END_ADDR_t, *PRXQ_END_ADDR_t; + + +/****************************************************************************** + structure for power management control status reg in global address map + located at address 0x0010 + *****************************************************************************/ +typedef union _PM_CSR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:22; //bits 10-31 + UINT32 pm_jagcore_rx_rdy:1; //bit 9 + UINT32 pm_jagcore_tx_rdy:1; //bit 8 + UINT32 pm_phy_lped_en:1; //bit 7 + UINT32 pm_phy_sw_coma:1; //bit 6 + UINT32 pm_rxclk_gate:1; //bit 5 + UINT32 pm_txclk_gate:1; //bit 4 + UINT32 pm_sysclk_gate:1; //bit 3 + UINT32 pm_jagcore_rx_en:1; //bit 2 + UINT32 pm_jagcore_tx_en:1; //bit 1 + UINT32 pm_gigephy_en:1; //bit 0 + #else + UINT32 pm_gigephy_en:1; //bit 0 + UINT32 pm_jagcore_tx_en:1; //bit 1 + UINT32 pm_jagcore_rx_en:1; //bit 2 + UINT32 pm_sysclk_gate:1; //bit 3 + UINT32 pm_txclk_gate:1; //bit 4 + UINT32 pm_rxclk_gate:1; //bit 5 + UINT32 pm_phy_sw_coma:1; //bit 6 + UINT32 pm_phy_lped_en:1; //bit 7 + UINT32 pm_jagcore_tx_rdy:1; //bit 8 + UINT32 pm_jagcore_rx_rdy:1; //bit 9 + UINT32 unused:22; //bits 10-31 + #endif + } bits; +} +PM_CSR_t, *PPM_CSR_t; + + +/****************************************************************************** + structure for interrupt status reg in global address map + located at address 0x0018 + *****************************************************************************/ +typedef union _INT_STATUS_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused5:11; //bits 21-31 + UINT32 slv_timeout:1; //bit 20 + UINT32 mac_stat_interrupt:1; //bit 19 + UINT32 rxmac_interrupt:1; //bit 18 + UINT32 txmac_interrupt:1; //bit 17 + UINT32 phy_interrupt:1; //bit 16 + UINT32 wake_on_lan:1; //bit 15 + UINT32 watchdog_interrupt:1; //bit 14 + UINT32 unused4:4; //bits 10-13 + UINT32 rxdma_err:1; //bit 9 + UINT32 rxdma_pkt_stat_ring_low:1; //bit 8 + UINT32 rxdma_fb_ring1_low:1; //bit 7 + UINT32 rxdma_fb_ring0_low:1; //bit 6 + UINT32 rxdma_xfr_done:1; //bit 5 + UINT32 txdma_err:1; //bit 4 + UINT32 txdma_isr:1; //bit 3 + UINT32 unused3:1; //bit 2 + UINT32 unused2:1; //bit 1 + UINT32 unused1:1; //bit 0 + #else + UINT32 unused1:1; //bit 0 + UINT32 unused2:1; //bit 1 + UINT32 unused3:1; //bit 2 + UINT32 txdma_isr:1; //bit 3 + UINT32 txdma_err:1; //bit 4 + UINT32 rxdma_xfr_done:1; //bit 5 + UINT32 rxdma_fb_ring0_low:1; //bit 6 + UINT32 rxdma_fb_ring1_low:1; //bit 7 + UINT32 rxdma_pkt_stat_ring_low:1; //bit 8 + UINT32 rxdma_err:1; //bit 9 + UINT32 unused4:4; //bits 10-13 + UINT32 watchdog_interrupt:1; //bit 14 + UINT32 wake_on_lan:1; //bit 15 + UINT32 phy_interrupt:1; //bit 16 + UINT32 txmac_interrupt:1; //bit 17 + UINT32 rxmac_interrupt:1; //bit 18 + UINT32 mac_stat_interrupt:1; //bit 19 + UINT32 slv_timeout:1; //bit 20 + UINT32 unused5:11; //bits 21-31 + #endif + } bits; +} +INT_STATUS_t, *PINT_STATUS_t; + + +/****************************************************************************** + structure for interrupt mask reg in global address map + located at address 0x001C + *****************************************************************************/ +typedef union _INT_MASK_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused5:11; //bits 21-31 + UINT32 slv_timeout:1; //bit 20 + UINT32 mac_stat_interrupt:1; //bit 19 + UINT32 rxmac_interrupt:1; //bit 18 + UINT32 txmac_interrupt:1; //bit 17 + UINT32 phy_interrupt:1; //bit 16 + UINT32 wake_on_lan:1; //bit 15 + UINT32 unused4:5; //bits 10-14 + UINT32 rxdma_err:1; //bit 9 + UINT32 rxdma_pkt_stat_ring_low:1; //bit 8 + UINT32 rxdma_fb_ring1_low:1; //bit 7 + UINT32 rxdma_fb_ring0_low:1; //bit 6 + UINT32 rxdma_xfr_done:1; //bit 5 + UINT32 txdma_err:1; //bit 4 + UINT32 txdma_isr:1; //bit 3 + UINT32 unused3:1; //bit 2 + UINT32 unused2:1; //bit 1 + UINT32 unused1:1; //bit 0 + #else + UINT32 unused1:1; //bit 0 + UINT32 unused2:1; //bit 1 + UINT32 unused3:1; //bit 2 + UINT32 txdma_isr:1; //bit 3 + UINT32 txdma_err:1; //bit 4 + UINT32 rxdma_xfr_done:1; //bit 5 + UINT32 rxdma_fb_ring0_low:1; //bit 6 + UINT32 rxdma_fb_ring1_low:1; //bit 7 + UINT32 rxdma_pkt_stat_ring_low:1; //bit 8 + UINT32 rxdma_err:1; //bit 9 + UINT32 unused4:5; //bits 10-14 + UINT32 wake_on_lan:1; //bit 15 + UINT32 phy_interrupt:1; //bit 16 + UINT32 txmac_interrupt:1; //bit 17 + UINT32 rxmac_interrupt:1; //bit 18 + UINT32 mac_stat_interrupt:1; //bit 19 + UINT32 slv_timeout:1; //bit 20 + UINT32 unused5:11; //bits 21-31 + #endif + } bits; +} +INT_MASK_t, *PINT_MASK_t; + + +/****************************************************************************** + structure for interrupt alias clear mask reg in global address map + located at address 0x0020 + *****************************************************************************/ +typedef union _INT_ALIAS_CLR_EN_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused5:11; //bits 21-31 + UINT32 slv_timeout:1; //bit 20 + UINT32 mac_stat_interrupt:1; //bit 19 + UINT32 rxmac_interrupt:1; //bit 18 + UINT32 txmac_interrupt:1; //bit 17 + UINT32 phy_interrupt:1; //bit 16 + UINT32 wake_on_lan:1; //bit 15 + UINT32 watchdog_interrupt:1; //bit 14 + UINT32 unused4:4; //bits 10-13 + UINT32 rxdma_err:1; //bit 9 + UINT32 rxdma_pkt_stat_ring_low:1; //bit 8 + UINT32 rxdma_fb_ring1_low:1; //bit 7 + UINT32 rxdma_fb_ring0_low:1; //bit 6 + UINT32 rxdma_xfr_done:1; //bit 5 + UINT32 txdma_err:1; //bit 4 + UINT32 txdma_isr:1; //bit 3 + UINT32 unused3:1; //bit 2 + UINT32 unused2:1; //bit 1 + UINT32 unused1:1; //bit 0 + #else + UINT32 unused1:1; //bit 0 + UINT32 unused2:1; //bit 1 + UINT32 unused3:1; //bit 2 + UINT32 txdma_isr:1; //bit 3 + UINT32 txdma_err:1; //bit 4 + UINT32 rxdma_xfr_done:1; //bit 5 + UINT32 rxdma_fb_ring0_low:1; //bit 6 + UINT32 rxdma_fb_ring1_low:1; //bit 7 + UINT32 rxdma_pkt_stat_ring_low:1; //bit 8 + UINT32 rxdma_err:1; //bit 9 + UINT32 unused4:4; //bits 10-13 + UINT32 watchdog_interrupt:1; //bit 14 + UINT32 wake_on_lan:1; //bit 15 + UINT32 phy_interrupt:1; //bit 16 + UINT32 txmac_interrupt:1; //bit 17 + UINT32 rxmac_interrupt:1; //bit 18 + UINT32 mac_stat_interrupt:1; //bit 19 + UINT32 slv_timeout:1; //bit 20 + UINT32 unused5:11; //bits 21-31 + #endif + } bits; +} +INT_ALIAS_CLR_EN_t, *PINT_ALIAS_CLR_EN_t; + + +/****************************************************************************** + structure for interrupt status alias reg in global address map + located at address 0x0024 + *****************************************************************************/ +typedef union _INT_STATUS_ALIAS_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused5:11; //bits 21-31 + UINT32 slv_timeout:1; //bit 20 + UINT32 mac_stat_interrupt:1; //bit 19 + UINT32 rxmac_interrupt:1; //bit 18 + UINT32 txmac_interrupt:1; //bit 17 + UINT32 phy_interrupt:1; //bit 16 + UINT32 wake_on_lan:1; //bit 15 + UINT32 watchdog_interrupt:1; //bit 14 + UINT32 unused4:4; //bits 10-13 + UINT32 rxdma_err:1; //bit 9 + UINT32 rxdma_pkt_stat_ring_low:1; //bit 8 + UINT32 rxdma_fb_ring1_low:1; //bit 7 + UINT32 rxdma_fb_ring0_low:1; //bit 6 + UINT32 rxdma_xfr_done:1; //bit 5 + UINT32 txdma_err:1; //bit 4 + UINT32 txdma_isr:1; //bit 3 + UINT32 unused3:1; //bit 2 + UINT32 unused2:1; //bit 1 + UINT32 unused1:1; //bit 0 + #else + UINT32 unused1:1; //bit 0 + UINT32 unused2:1; //bit 1 + UINT32 unused3:1; //bit 2 + UINT32 txdma_isr:1; //bit 3 + UINT32 txdma_err:1; //bit 4 + UINT32 rxdma_xfr_done:1; //bit 5 + UINT32 rxdma_fb_ring0_low:1; //bit 6 + UINT32 rxdma_fb_ring1_low:1; //bit 7 + UINT32 rxdma_pkt_stat_ring_low:1; //bit 8 + UINT32 rxdma_err:1; //bit 9 + UINT32 unused4:4; //bits 10-13 + UINT32 watchdog_interrupt:1; //bit 14 + UINT32 wake_on_lan:1; //bit 15 + UINT32 phy_interrupt:1; //bit 16 + UINT32 txmac_interrupt:1; //bit 17 + UINT32 rxmac_interrupt:1; //bit 18 + UINT32 mac_stat_interrupt:1; //bit 19 + UINT32 slv_timeout:1; //bit 20 + UINT32 unused5:11; //bits 21-31 + #endif + } bits; +} +INT_STATUS_ALIAS_t, *PINT_STATUS_ALIAS_t; + + +/****************************************************************************** + structure for software reset reg in global address map + located at address 0x0028 + *****************************************************************************/ +typedef union _SW_RESET_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 selfclr_disable:1; //bit 31 + UINT32 unused:24; //bits 7-30 + UINT32 mmc_sw_reset:1; //bit 6 + UINT32 mac_stat_sw_reset:1; //bit 5 + UINT32 mac_sw_reset:1; //bit 4 + UINT32 rxmac_sw_reset:1; //bit 3 + UINT32 txmac_sw_reset:1; //bit 2 + UINT32 rxdma_sw_reset:1; //bit 1 + UINT32 txdma_sw_reset:1; //bit 0 + #else + UINT32 txdma_sw_reset:1; //bit 0 + UINT32 rxdma_sw_reset:1; //bit 1 + UINT32 txmac_sw_reset:1; //bit 2 + UINT32 rxmac_sw_reset:1; //bit 3 + UINT32 mac_sw_reset:1; //bit 4 + UINT32 mac_stat_sw_reset:1; //bit 5 + UINT32 mmc_sw_reset:1; //bit 6 + UINT32 unused:24; //bits 7-30 + UINT32 selfclr_disable:1; //bit 31 + #endif + } bits; +} +SW_RESET_t, *PSW_RESET_t; + + +/****************************************************************************** + structure for SLV Timer reg in global address map + located at address 0x002C + *****************************************************************************/ +typedef union _SLV_TIMER_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:8; //bits 24-31 + UINT32 timer_ini:24; //bits 0-23 + #else + UINT32 timer_ini:24; //bits 0-23 + UINT32 unused:8; //bits 24-31 + #endif + } bits; +} +SLV_TIMER_t, *PSLV_TIMER_t; + + +/****************************************************************************** + structure for MSI Configuration reg in global address map + located at address 0x0030 + *****************************************************************************/ +typedef union _MSI_CONFIG_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused1:13; //bits 19-31 + UINT32 msi_tc:3; //bits 16-18 + UINT32 unused2:11; //bits 5-15 + UINT32 msi_vector:5; //bits 0-4 + #else + UINT32 msi_vector:5; //bits 0-4 + UINT32 unused2:11; //bits 5-15 + UINT32 msi_tc:3; //bits 16-18 + UINT32 unused1:13; //bits 19-31 + #endif + } bits; +} +MSI_CONFIG_t, *PMSI_CONFIG_t; + + +/****************************************************************************** + structure for Loopback reg in global address map + located at address 0x0034 + *****************************************************************************/ +typedef union _LOOPBACK_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:30; //bits 2-31 + UINT32 dma_loopback:1; //bit 1 + UINT32 mac_loopback:1; //bit 0 + #else + UINT32 mac_loopback:1; //bit 0 + UINT32 dma_loopback:1; //bit 1 + UINT32 unused:30; //bits 2-31 + #endif + } bits; +} +LOOPBACK_t, *PLOOPBACK_t; + + +/****************************************************************************** + GLOBAL Module of JAGCore Address Mapping + Located at address 0x0000 + *****************************************************************************/ +typedef struct _GLOBAL_t +{ //Location: + TXQ_START_ADDR_t txq_start_addr; // 0x0000 + TXQ_END_ADDR_t txq_end_addr; // 0x0004 + RXQ_START_ADDR_t rxq_start_addr; // 0x0008 + RXQ_END_ADDR_t rxq_end_addr; // 0x000C + PM_CSR_t pm_csr; // 0x0010 + UINT32 unused; // 0x0014 + INT_STATUS_t int_status; // 0x0018 + INT_MASK_t int_mask; // 0x001C + INT_ALIAS_CLR_EN_t int_alias_clr_en; // 0x0020 + INT_STATUS_ALIAS_t int_status_alias; // 0x0024 + SW_RESET_t sw_reset; // 0x0028 + SLV_TIMER_t slv_timer; // 0x002C + MSI_CONFIG_t msi_config; // 0x0030 + LOOPBACK_t loopback; // 0x0034 + UINT32 watchdog_timer; // 0x0038 +} +GLOBAL_t, *PGLOBAL_t; +/*===========================================================================*/ +/*===========================================================================*/ +/*=== END OF GLOBAL REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ + + + + +/*===========================================================================*/ +/*===========================================================================*/ +/*=== START OF TXDMA REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ +/****************************************************************************** + structure for txdma control status reg in txdma address map + located at address 0x1000 + *****************************************************************************/ +typedef union _TXDMA_CSR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused2:19; //bits 13-31 + UINT32 traffic_class:4; //bits 9-12 + UINT32 sngl_epkt_mode:1; //bit 8 + UINT32 cache_thrshld:4; //bits 4-7 + UINT32 unused1:2; //bits 2-3 + UINT32 drop_TLP_disable:1; //bit 1 + UINT32 halt:1; //bit 0 + #else + UINT32 halt:1; //bit 0 + UINT32 drop_TLP_disable:1; //bit 1 + UINT32 unused1:2; //bits 2-3 + UINT32 cache_thrshld:4; //bits 4-7 + UINT32 sngl_epkt_mode:1; //bit 8 + UINT32 traffic_class:4; //bits 9-12 + UINT32 unused2:19; //bits 13-31 + #endif + } bits; +} +TXDMA_CSR_t, *PTXDMA_CSR_t; + + +/****************************************************************************** + structure for txdma packet ring base address hi reg in txdma address map + located at address 0x1004 + *****************************************************************************/ +typedef struct _TXDMA_PR_BASE_HI_t +{ + UINT32 addr_hi; //bits 0-31 +} +TXDMA_PR_BASE_HI_t, *PTXDMA_PR_BASE_HI_t; + + +/****************************************************************************** + structure for txdma packet ring base address low reg in txdma address map + located at address 0x1008 + *****************************************************************************/ +typedef struct _TXDMA_PR_BASE_LO_t +{ + UINT32 addr_lo; //bits 0-31 +} +TXDMA_PR_BASE_LO_t, *PTXDMA_PR_BASE_LO_t; + + +/****************************************************************************** + structure for txdma packet ring number of descriptor reg in txdma address + map. Located at address 0x100C + *****************************************************************************/ +typedef union _TXDMA_PR_NUM_DES_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:22; //bits 10-31 + UINT32 pr_ndes:10; //bits 0-9 + #else + UINT32 pr_ndes:10; //bits 0-9 + UINT32 unused:22; //bits 10-31 + #endif + } bits; +} +TXDMA_PR_NUM_DES_t, *PTXDMA_PR_NUM_DES_t; + + +/****************************************************************************** + structure for txdma tx queue write address reg in txdma address map + located at address 0x1010 + *****************************************************************************/ +typedef union _TXDMA_TXQ_WR_ADDR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:21; //bits 11-31 + UINT32 txq_wr_wrap:1; //bit 10 + UINT32 txq_wr:10; //bits 0-9 + #else + UINT32 txq_wr:10; //bits 0-9 + UINT32 txq_wr_wrap:1; //bit 10 + UINT32 unused:21; //bits 11-31 + #endif + } bits; +} +TXDMA_TXQ_WR_ADDR_t, *PTXDMA_TXQ_WR_ADDR_t; + + +/****************************************************************************** + structure for txdma tx queue write address external reg in txdma address map + located at address 0x1014 + *****************************************************************************/ +typedef union _TXDMA_TXQ_WR_ADDR_EXT_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:21; //bits 11-31 + UINT32 txq_wr_ext_wrap:1; //bit 10 + UINT32 txq_wr_ext:10; //bits 0-9 + #else + UINT32 txq_wr_ext:10; //bits 0-9 + UINT32 txq_wr_ext_wrap:1; //bit 10 + UINT32 unused:21; //bits 11-31 + #endif + } bits; +} +TXDMA_TXQ_WR_ADDR_EXT_t, *PTXDMA_TXQ_WR_ADDR_EXT_t; + + +/****************************************************************************** + structure for txdma tx queue read address reg in txdma address map + located at address 0x1018 + *****************************************************************************/ +typedef union _TXDMA_TXQ_RD_ADDR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:21; //bits 11-31 + UINT32 txq_rd_wrap:1; //bit 10 + UINT32 txq_rd:10; //bits 0-9 + #else + UINT32 txq_rd:10; //bits 0-9 + UINT32 txq_rd_wrap:1; //bit 10 + UINT32 unused:21; //bits 11-31 + #endif + } bits; +} +TXDMA_TXQ_RD_ADDR_t, *PTXDMA_TXQ_RD_ADDR_t; + + +/****************************************************************************** + structure for txdma status writeback address hi reg in txdma address map + located at address 0x101C + *****************************************************************************/ +typedef struct _TXDMA_DMA_WB_ADDR_HI_t +{ + UINT32 addr_hi; //bits 0-31 +} +TXDMA_DMA_WB_ADDR_HI_t, *PTXDMA_DMA_WB_ADDR_HI_t; + + +/****************************************************************************** + structure for txdma status writeback address lo reg in txdma address map + located at address 0x1020 + *****************************************************************************/ +typedef struct _TXDMA_DMA_WB_ADDR_LO_t +{ + UINT32 addr_lo; //bits 0-31 +} +TXDMA_DMA_WB_ADDR_LO_t, *PTXDMA_DMA_WB_ADDR_LO_t; + + +/****************************************************************************** + structure for txdma service request reg in txdma address map + located at address 0x1024 + *****************************************************************************/ +typedef union _TXDMA_SERVICE_REQUEST_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:21; //bits 11-31 + UINT32 serv_req_wrap:1; //bit 10 + UINT32 serv_req:10; //bits 0-9 + #else + UINT32 serv_req:10; //bits 0-9 + UINT32 serv_req_wrap:1; //bit 10 + UINT32 unused:21; //bits 11-31 + #endif + } bits; +} +TXDMA_SERVICE_REQUEST_t, *PTXDMA_SERVICE_REQUEST_t; + + +/****************************************************************************** + structure for txdma service complete reg in txdma address map + located at address 0x1028 + *****************************************************************************/ +typedef union _TXDMA_SERVICE_COMPLETE_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:21; //bits 11-31 + UINT32 serv_cpl_wrap:1; //bit 10 + UINT32 serv_cpl:10; //bits 0-9 + #else + UINT32 serv_cpl:10; //bits 0-9 + UINT32 serv_cpl_wrap:1; //bit 10 + UINT32 unused:21; //bits 11-31 + #endif + } bits; +} +TXDMA_SERVICE_COMPLETE_t, *PTXDMA_SERVICE_COMPLETE_t; + + +/****************************************************************************** + structure for txdma tx descriptor cache read index reg in txdma address map + located at address 0x102C + *****************************************************************************/ +typedef union _TXDMA_CACHE_RD_INDEX_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:27; //bits 5-31 + UINT32 rdi_wrap:1; //bit 4 + UINT32 rdi:4; //bit 0-3 + #else + UINT32 rdi:4; //bits 0-3 + UINT32 rdi_wrap:1; //bit 4 + UINT32 unused:27; //bits 5-31 + #endif + } bits; +} +TXDMA_CACHE_RD_INDEX_t, *PTXDMA_CACHE_RD_INDEX_t; + + +/****************************************************************************** + structure for txdma tx descriptor cache write index reg in txdma address map + located at address 0x1030 + *****************************************************************************/ +typedef union _TXDMA_CACHE_WR_INDEX_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:27; //bits 5-31 + UINT32 wri_wrap:1; //bit 4 + UINT32 wri:4; //bit 0-3 + #else + UINT32 wri:4; //bits 0-3 + UINT32 wri_wrap:1; //bit 4 + UINT32 unused:27; //bits 5-31 + #endif + } bits; +} +TXDMA_CACHE_WR_INDEX_t, *PTXDMA_CACHE_WR_INDEX_t; + + +/****************************************************************************** + structure for txdma error reg in txdma address map + located at address 0x1034 + *****************************************************************************/ +typedef union _TXDMA_ERROR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused3:22; //bits 10-31 + UINT32 WrbkRewind:1; //bit 9 + UINT32 WrbkResend:1; //bit 8 + UINT32 unused2:2; //bits 6-7 + UINT32 DescrRewind:1; //bit 5 + UINT32 DescrResend:1; //bit 4 + UINT32 unused1:2; //bits 2-3 + UINT32 PyldRewind:1; //bit 1 + UINT32 PyldResend:1; //bit 0 + #else + UINT32 PyldResend:1; //bit 0 + UINT32 PyldRewind:1; //bit 1 + UINT32 unused1:2; //bits 2-3 + UINT32 DescrResend:1; //bit 4 + UINT32 DescrRewind:1; //bit 5 + UINT32 unused2:2; //bits 6-7 + UINT32 WrbkResend:1; //bit 8 + UINT32 WrbkRewind:1; //bit 9 + UINT32 unused3:22; //bits 10-31 + #endif + } bits; +} +TXDMA_ERROR_t, *PTXDMA_ERROR_t; + + +/****************************************************************************** + Tx DMA Module of JAGCore Address Mapping + Located at address 0x1000 + *****************************************************************************/ +typedef struct _TXDMA_t +{ //Location: + TXDMA_CSR_t csr; // 0x1000 + TXDMA_PR_BASE_HI_t pr_base_hi; // 0x1004 + TXDMA_PR_BASE_LO_t pr_base_lo; // 0x1008 + TXDMA_PR_NUM_DES_t pr_num_des; // 0x100C + TXDMA_TXQ_WR_ADDR_t txq_wr_addr; // 0x1010 + TXDMA_TXQ_WR_ADDR_EXT_t txq_wr_addr_ext; // 0x1014 + TXDMA_TXQ_RD_ADDR_t txq_rd_addr; // 0x1018 + TXDMA_DMA_WB_ADDR_HI_t dma_wb_base_hi; // 0x101C + TXDMA_DMA_WB_ADDR_LO_t dma_wb_base_lo; // 0x1020 + TXDMA_SERVICE_REQUEST_t service_request; // 0x1024 + TXDMA_SERVICE_COMPLETE_t service_complete; // 0x1028 + TXDMA_CACHE_RD_INDEX_t cache_rd_index; // 0x102C + TXDMA_CACHE_WR_INDEX_t cache_wr_index; // 0x1030 + TXDMA_ERROR_t TxDmaError; // 0x1034 + UINT32 DescAbortCount; // 0x1038 + UINT32 PayloadAbortCnt; // 0x103c + UINT32 WriteBackAbortCnt; // 0x1040 + UINT32 DescTimeoutCnt; // 0x1044 + UINT32 PayloadTimeoutCnt; // 0x1048 + UINT32 WriteBackTimeoutCnt;// 0x104c + UINT32 DescErrorCount; // 0x1050 + UINT32 PayloadErrorCnt; // 0x1054 + UINT32 WriteBackErrorCnt; // 0x1058 + UINT32 DroppedTLPCount; // 0x105c + TXDMA_SERVICE_COMPLETE_t NewServiceComplete; // 0x1060 + UINT32 EthernetPacketCount;// 0x1064 +} +TXDMA_t, *PTXDMA_t; +/*===========================================================================*/ +/*===========================================================================*/ +/*=== END OF TXDMA REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ + + + +/*===========================================================================*/ +/*===========================================================================*/ +/*=== START OF RXDMA REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ +/****************************************************************************** + structure for control status reg in rxdma address map + Located at address 0x2000 + *****************************************************************************/ +typedef union _RXDMA_CSR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused2:14; //bits 18-31 + UINT32 halt_status:1; //bit 17 + UINT32 pkt_done_flush:1; //bit 16 + UINT32 pkt_drop_disable:1; //bit 15 + UINT32 unused1:1; //bit 14 + UINT32 fbr1_enable:1; //bit 13 + UINT32 fbr1_size:2; //bits 11-12 + UINT32 fbr0_enable:1; //bit 10 + UINT32 fbr0_size:2; //bits 8-9 + UINT32 dma_big_endian:1; //bit 7 + UINT32 pkt_big_endian:1; //bit 6 + UINT32 psr_big_endian:1; //bit 5 + UINT32 fbr_big_endian:1; //bit 4 + UINT32 tc:3; //bits 1-3 + UINT32 halt:1; //bit 0 + #else + UINT32 halt:1; //bit 0 + UINT32 tc:3; //bits 1-3 + UINT32 fbr_big_endian:1; //bit 4 + UINT32 psr_big_endian:1; //bit 5 + UINT32 pkt_big_endian:1; //bit 6 + UINT32 dma_big_endian:1; //bit 7 + UINT32 fbr0_size:2; //bits 8-9 + UINT32 fbr0_enable:1; //bit 10 + UINT32 fbr1_size:2; //bits 11-12 + UINT32 fbr1_enable:1; //bit 13 + UINT32 unused1:1; //bit 14 + UINT32 pkt_drop_disable:1; //bit 15 + UINT32 pkt_done_flush:1; //bit 16 + UINT32 halt_status:1; //bit 17 + UINT32 unused2:14; //bits 18-31 + #endif + } bits; +} +RXDMA_CSR_t, *PRXDMA_CSR_t; + + +/****************************************************************************** + structure for dma writeback lo reg in rxdma address map + located at address 0x2004 + *****************************************************************************/ +typedef struct _RXDMA_DMA_WB_BASE_LO_t +{ + UINT32 addr_lo; //bits 0-31 +} +RXDMA_DMA_WB_BASE_LO_t, *PRXDMA_DMA_WB_BASE_LO_t; + + +/****************************************************************************** + structure for dma writeback hi reg in rxdma address map + located at address 0x2008 + *****************************************************************************/ +typedef struct _RXDMA_DMA_WB_BASE_HI_t +{ + UINT32 addr_hi; //bits 0-31 +} +RXDMA_DMA_WB_BASE_HI_t, *PRXDMA_DMA_WB_BASE_HI_t; + + +/****************************************************************************** + structure for number of packets done reg in rxdma address map + located at address 0x200C + *****************************************************************************/ +typedef union _RXDMA_NUM_PKT_DONE_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:24; //bits 8-31 + UINT32 num_done:8; //bits 0-7 + #else + UINT32 num_done:8; //bits 0-7 + UINT32 unused:24; //bits 8-31 + #endif + } bits; +} +RXDMA_NUM_PKT_DONE_t, *PRXDMA_NUM_PKT_DONE_t; + + +/****************************************************************************** + structure for max packet time reg in rxdma address map + located at address 0x2010 + *****************************************************************************/ +typedef union _RXDMA_MAX_PKT_TIME_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:14; //bits 18-31 + UINT32 time_done:18; //bits 0-17 + #else + UINT32 time_done:18; //bits 0-17 + UINT32 unused:14; //bits 18-31 + #endif + } bits; +} +RXDMA_MAX_PKT_TIME_t, *PRXDMA_MAX_PKT_TIME_t; + + +/****************************************************************************** + structure for rx queue read address reg in rxdma address map + located at address 0x2014 + *****************************************************************************/ +typedef union _RXDMA_RXQ_RD_ADDR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:21; //bits 11-31 + UINT32 rxq_rd_wrap:1; //bit 10 + UINT32 rxq_rd:10; //bits 0-9 + #else + UINT32 rxq_rd:10; //bits 0-9 + UINT32 rxq_rd_wrap:1; //bit 10 + UINT32 unused:21; //bits 11-31 + #endif + } bits; +} +RXDMA_RXQ_RD_ADDR_t, *PRXDMA_RXQ_RD_ADDR_t; + + +/****************************************************************************** + structure for rx queue read address external reg in rxdma address map + located at address 0x2018 + *****************************************************************************/ +typedef union _RXDMA_RXQ_RD_ADDR_EXT_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:21; //bits 11-31 + UINT32 rxq_rd_ext_wrap:1; //bit 10 + UINT32 rxq_rd_ext:10; //bits 0-9 + #else + UINT32 rxq_rd_ext:10; //bits 0-9 + UINT32 rxq_rd_ext_wrap:1; //bit 10 + UINT32 unused:21; //bits 11-31 + #endif + } bits; +} +RXDMA_RXQ_RD_ADDR_EXT_t, *PRXDMA_RXQ_RD_ADDR_EXT_t; + + +/****************************************************************************** + structure for rx queue write address reg in rxdma address map + located at address 0x201C + *****************************************************************************/ +typedef union _RXDMA_RXQ_WR_ADDR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:21; //bits 11-31 + UINT32 rxq_wr_wrap:1; //bit 10 + UINT32 rxq_wr:10; //bits 0-9 + #else + UINT32 rxq_wr:10; //bits 0-9 + UINT32 rxq_wr_wrap:1; //bit 10 + UINT32 unused:21; //bits 11-31 + #endif + } bits; +} +RXDMA_RXQ_WR_ADDR_t, *PRXDMA_RXQ_WR_ADDR_t; + + +/****************************************************************************** + structure for packet status ring base address lo reg in rxdma address map + located at address 0x2020 + *****************************************************************************/ +typedef struct _RXDMA_PSR_BASE_LO_t +{ + UINT32 addr_lo; //bits 0-31 +} +RXDMA_PSR_BASE_LO_t, *PRXDMA_PSR_BASE_LO_t; + + +/****************************************************************************** + structure for packet status ring base address hi reg in rxdma address map + located at address 0x2024 + *****************************************************************************/ +typedef struct _RXDMA_PSR_BASE_HI_t +{ + UINT32 addr_hi; //bits 0-31 +} +RXDMA_PSR_BASE_HI_t, *PRXDMA_PSR_BASE_HI_t; + + +/****************************************************************************** + structure for packet status ring number of descriptors reg in rxdma address + map. Located at address 0x2028 + *****************************************************************************/ +typedef union _RXDMA_PSR_NUM_DES_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:20; //bits 12-31 + UINT32 psr_ndes:12; //bit 0-11 + #else + UINT32 psr_ndes:12; //bit 0-11 + UINT32 unused:20; //bits 12-31 + #endif + } bits; +} +RXDMA_PSR_NUM_DES_t, *PRXDMA_PSR_NUM_DES_t; + + +/****************************************************************************** + structure for packet status ring available offset reg in rxdma address map + located at address 0x202C + *****************************************************************************/ +typedef union _RXDMA_PSR_AVAIL_OFFSET_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:19; //bits 13-31 + UINT32 psr_avail_wrap:1; //bit 12 + UINT32 psr_avail:12; //bit 0-11 + #else + UINT32 psr_avail:12; //bit 0-11 + UINT32 psr_avail_wrap:1; //bit 12 + UINT32 unused:19; //bits 13-31 + #endif + } bits; +} +RXDMA_PSR_AVAIL_OFFSET_t, *PRXDMA_PSR_AVAIL_OFFSET_t; + + +/****************************************************************************** + structure for packet status ring full offset reg in rxdma address map + located at address 0x2030 + *****************************************************************************/ +typedef union _RXDMA_PSR_FULL_OFFSET_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:19; //bits 13-31 + UINT32 psr_full_wrap:1; //bit 12 + UINT32 psr_full:12; //bit 0-11 + #else + UINT32 psr_full:12; //bit 0-11 + UINT32 psr_full_wrap:1; //bit 12 + UINT32 unused:19; //bits 13-31 + #endif + } bits; +} +RXDMA_PSR_FULL_OFFSET_t, *PRXDMA_PSR_FULL_OFFSET_t; + + +/****************************************************************************** + structure for packet status ring access index reg in rxdma address map + located at address 0x2034 + *****************************************************************************/ +typedef union _RXDMA_PSR_ACCESS_INDEX_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:27; //bits 5-31 + UINT32 psr_ai:5; //bits 0-4 + #else + UINT32 psr_ai:5; //bits 0-4 + UINT32 unused:27; //bits 5-31 + #endif + } bits; +} +RXDMA_PSR_ACCESS_INDEX_t, *PRXDMA_PSR_ACCESS_INDEX_t; + + +/****************************************************************************** + structure for packet status ring minimum descriptors reg in rxdma address + map. Located at address 0x2038 + *****************************************************************************/ +typedef union _RXDMA_PSR_MIN_DES_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:20; //bits 12-31 + UINT32 psr_min:12; //bits 0-11 + #else + UINT32 psr_min:12; //bits 0-11 + UINT32 unused:20; //bits 12-31 + #endif + } bits; +} +RXDMA_PSR_MIN_DES_t, *PRXDMA_PSR_MIN_DES_t; + + +/****************************************************************************** + structure for free buffer ring base lo address reg in rxdma address map + located at address 0x203C + *****************************************************************************/ +typedef struct _RXDMA_FBR_BASE_LO_t +{ + UINT32 addr_lo; //bits 0-31 +} +RXDMA_FBR_BASE_LO_t, *PRXDMA_FBR_BASE_LO_t; + + +/****************************************************************************** + structure for free buffer ring base hi address reg in rxdma address map + located at address 0x2040 + *****************************************************************************/ +typedef struct _RXDMA_FBR_BASE_HI_t +{ + UINT32 addr_hi; //bits 0-31 +} +RXDMA_FBR_BASE_HI_t, *PRXDMA_FBR_BASE_HI_t; + + +/****************************************************************************** + structure for free buffer ring number of descriptors reg in rxdma address + map. Located at address 0x2044 + *****************************************************************************/ +typedef union _RXDMA_FBR_NUM_DES_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:22; //bits 10-31 + UINT32 fbr_ndesc:10; //bits 0-9 + #else + UINT32 fbr_ndesc:10; //bits 0-9 + UINT32 unused:22; //bits 10-31 + #endif + } bits; +} +RXDMA_FBR_NUM_DES_t, *PRXDMA_FBR_NUM_DES_t; + + +/****************************************************************************** + structure for free buffer ring 0 available offset reg in rxdma address map + located at address 0x2048 + *****************************************************************************/ +typedef union _RXDMA_FBR_AVAIL_OFFSET_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:21; //bits 11-31 + UINT32 fbr_avail_wrap:1; //bit 10 + UINT32 fbr_avail:10; //bit 0-9 + #else + UINT32 fbr_avail:10; //bit 0-9 + UINT32 fbr_avail_wrap:1; //bit 10 + UINT32 unused:21; //bits 11-31 + #endif + } bits; +} +RXDMA_FBR_AVAIL_OFFSET_t, *PRXDMA_FBR_AVAIL_OFFSET_t; + + +/****************************************************************************** + structure for free buffer ring 0 full offset reg in rxdma address map + located at address 0x204C + *****************************************************************************/ +typedef union _RXDMA_FBR_FULL_OFFSET_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:21; //bits 11-31 + UINT32 fbr_full_wrap:1; //bit 10 + UINT32 fbr_full:10; //bit 0-9 + #else + UINT32 fbr_full:10; //bit 0-9 + UINT32 fbr_full_wrap:1; //bit 10 + UINT32 unused:21; //bits 11-31 + #endif + } bits; +} +RXDMA_FBR_FULL_OFFSET_t, *PRXDMA_FBR_FULL_OFFSET_t; + + +/****************************************************************************** + structure for free buffer cache 0 full offset reg in rxdma address map + located at address 0x2050 + *****************************************************************************/ +typedef union _RXDMA_FBC_RD_INDEX_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:27; //bits 5-31 + UINT32 fbc_rdi:5; //bit 0-4 + #else + UINT32 fbc_rdi:5; //bit 0-4 + UINT32 unused:27; //bits 5-31 + #endif + } bits; +} +RXDMA_FBC_RD_INDEX_t, *PRXDMA_FBC_RD_INDEX_t; + + +/****************************************************************************** + structure for free buffer ring 0 minimum descriptor reg in rxdma address map + located at address 0x2054 + *****************************************************************************/ +typedef union _RXDMA_FBR_MIN_DES_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:22; //bits 10-31 + UINT32 fbr_min:10; //bits 0-9 + #else + UINT32 fbr_min:10; //bits 0-9 + UINT32 unused:22; //bits 10-31 + #endif + } bits; +} +RXDMA_FBR_MIN_DES_t, *PRXDMA_FBR_MIN_DES_t; + + +/****************************************************************************** + structure for free buffer ring 1 base address lo reg in rxdma address map + located at address 0x2058 - 0x205C + Defined earlier (RXDMA_FBR_BASE_LO_t and RXDMA_FBR_BASE_HI_t) + *****************************************************************************/ + +/****************************************************************************** + structure for free buffer ring 1 number of descriptors reg in rxdma address + map. Located at address 0x2060 + Defined earlier (RXDMA_FBR_NUM_DES_t) + *****************************************************************************/ + +/****************************************************************************** + structure for free buffer ring 1 available offset reg in rxdma address map + located at address 0x2064 + Defined Earlier (RXDMA_FBR_AVAIL_OFFSET_t) + *****************************************************************************/ + +/****************************************************************************** + structure for free buffer ring 1 full offset reg in rxdma address map + located at address 0x2068 + Defined Earlier (RXDMA_FBR_FULL_OFFSET_t) + *****************************************************************************/ + +/****************************************************************************** + structure for free buffer cache 1 read index reg in rxdma address map + located at address 0x206C + Defined Earlier (RXDMA_FBC_RD_INDEX_t) + *****************************************************************************/ + +/****************************************************************************** + structure for free buffer ring 1 minimum descriptor reg in rxdma address map + located at address 0x2070 + Defined Earlier (RXDMA_FBR_MIN_DES_t) + *****************************************************************************/ + + +/****************************************************************************** + Rx DMA Module of JAGCore Address Mapping + Located at address 0x2000 + *****************************************************************************/ +typedef struct _RXDMA_t +{ //Location: + RXDMA_CSR_t csr; // 0x2000 + RXDMA_DMA_WB_BASE_LO_t dma_wb_base_lo; // 0x2004 + RXDMA_DMA_WB_BASE_HI_t dma_wb_base_hi; // 0x2008 + RXDMA_NUM_PKT_DONE_t num_pkt_done; // 0x200C + RXDMA_MAX_PKT_TIME_t max_pkt_time; // 0x2010 + RXDMA_RXQ_RD_ADDR_t rxq_rd_addr; // 0x2014 + RXDMA_RXQ_RD_ADDR_EXT_t rxq_rd_addr_ext; // 0x2018 + RXDMA_RXQ_WR_ADDR_t rxq_wr_addr; // 0x201C + RXDMA_PSR_BASE_LO_t psr_base_lo; // 0x2020 + RXDMA_PSR_BASE_HI_t psr_base_hi; // 0x2024 + RXDMA_PSR_NUM_DES_t psr_num_des; // 0x2028 + RXDMA_PSR_AVAIL_OFFSET_t psr_avail_offset; // 0x202C + RXDMA_PSR_FULL_OFFSET_t psr_full_offset; // 0x2030 + RXDMA_PSR_ACCESS_INDEX_t psr_access_index; // 0x2034 + RXDMA_PSR_MIN_DES_t psr_min_des; // 0x2038 + RXDMA_FBR_BASE_LO_t fbr0_base_lo; // 0x203C + RXDMA_FBR_BASE_HI_t fbr0_base_hi; // 0x2040 + RXDMA_FBR_NUM_DES_t fbr0_num_des; // 0x2044 + RXDMA_FBR_AVAIL_OFFSET_t fbr0_avail_offset; // 0x2048 + RXDMA_FBR_FULL_OFFSET_t fbr0_full_offset; // 0x204C + RXDMA_FBC_RD_INDEX_t fbr0_rd_index; // 0x2050 + RXDMA_FBR_MIN_DES_t fbr0_min_des; // 0x2054 + RXDMA_FBR_BASE_LO_t fbr1_base_lo; // 0x2058 + RXDMA_FBR_BASE_HI_t fbr1_base_hi; // 0x205C + RXDMA_FBR_NUM_DES_t fbr1_num_des; // 0x2060 + RXDMA_FBR_AVAIL_OFFSET_t fbr1_avail_offset; // 0x2064 + RXDMA_FBR_FULL_OFFSET_t fbr1_full_offset; // 0x2068 + RXDMA_FBC_RD_INDEX_t fbr1_rd_index; // 0x206C + RXDMA_FBR_MIN_DES_t fbr1_min_des; // 0x2070 +} +RXDMA_t, *PRXDMA_t; +/*===========================================================================*/ +/*===========================================================================*/ +/*=== END OF RXDMA REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ + + + +/*===========================================================================*/ +/*===========================================================================*/ +/*=== START OF TXMAC REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ +/****************************************************************************** + structure for control reg in txmac address map + located at address 0x3000 + *****************************************************************************/ +typedef union _TXMAC_CTL_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:24; //bits 8-31 + UINT32 cklseg_diable:1; //bit 7 + UINT32 ckbcnt_disable:1; //bit 6 + UINT32 cksegnum:1; //bit 5 + UINT32 async_disable:1; //bit 4 + UINT32 fc_disable:1; //bit 3 + UINT32 mcif_disable:1; //bit 2 + UINT32 mif_disable:1; //bit 1 + UINT32 txmac_en:1; //bit 0 + #else + UINT32 txmac_en:1; //bit 0 + UINT32 mif_disable:1; //bit 1 mac interface + UINT32 mcif_disable:1; //bit 2 memory controller interface + UINT32 fc_disable:1; //bit 3 + UINT32 async_disable:1; //bit 4 + UINT32 cksegnum:1; //bit 5 + UINT32 ckbcnt_disable:1; //bit 6 + UINT32 cklseg_diable:1; //bit 7 + UINT32 unused:24; //bits 8-31 + #endif + } bits; +} +TXMAC_CTL_t, *PTXMAC_CTL_t; + + +/****************************************************************************** + structure for shadow pointer reg in txmac address map + located at address 0x3004 + *****************************************************************************/ +typedef union _TXMAC_SHADOW_PTR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved2:5; //bits 27-31 + UINT32 txq_rd_ptr:11; //bits 16-26 + UINT32 reserved:5; //bits 11-15 + UINT32 txq_wr_ptr:11; //bits 0-10 + #else + UINT32 txq_wr_ptr:11; //bits 0-10 + UINT32 reserved:5; //bits 11-15 + UINT32 txq_rd_ptr:11; //bits 16-26 + UINT32 reserved2:5; //bits 27-31 + #endif + } bits; +} +TXMAC_SHADOW_PTR_t, *PTXMAC_SHADOW_PTR_t; + + +/****************************************************************************** + structure for error count reg in txmac address map + located at address 0x3008 + *****************************************************************************/ +typedef union _TXMAC_ERR_CNT_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:20; //bits 12-31 + UINT32 reserved:4; //bits 8-11 + UINT32 txq_underrun:4; //bits 4-7 + UINT32 fifo_underrun:4; //bits 0-3 + #else + UINT32 fifo_underrun:4; //bits 0-3 + UINT32 txq_underrun:4; //bits 4-7 + UINT32 reserved:4; //bits 8-11 + UINT32 unused:20; //bits 12-31 + #endif + } bits; +} TXMAC_ERR_CNT_t, *PTXMAC_ERR_CNT_t; + + +/****************************************************************************** + structure for max fill reg in txmac address map + located at address 0x300C + *****************************************************************************/ +typedef union _TXMAC_MAX_FILL_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:20; //bits 12-31 + UINT32 max_fill:12; //bits 0-11 + #else + UINT32 max_fill:12; //bits 0-11 + UINT32 unused:20; //bits 12-31 + #endif + } bits; +} +TXMAC_MAX_FILL_t, *PTXMAC_MAX_FILL_t; + + +/****************************************************************************** + structure for cf parameter reg in txmac address map + located at address 0x3010 + *****************************************************************************/ +typedef union _TXMAC_CF_PARAM_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 cfep:16; //bits 16-31 + UINT32 cfpt:16; //bits 0-15 + #else + UINT32 cfpt:16; //bits 0-15 + UINT32 cfep:16; //bits 16-31 + #endif + } bits; +} +TXMAC_CF_PARAM_t, *PTXMAC_CF_PARAM_t; + + +/****************************************************************************** + structure for tx test reg in txmac address map + located at address 0x3014 + *****************************************************************************/ +typedef union _TXMAC_TXTEST_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused2:15; //bits 17-31 + UINT32 reserved1:1; //bit 16 + UINT32 txtest_en:1; //bit 15 + UINT32 unused1:4; //bits 11-14 + UINT32 txqtest_ptr:11; //bits 0-11 + #else + UINT32 txqtest_ptr:11; //bits 0-10 + UINT32 unused1:4; //bits 11-14 + UINT32 txtest_en:1; //bit 15 + UINT32 reserved1:1; //bit 16 + UINT32 unused2:15; //bits 17-31 + #endif + } bits; +} +TXMAC_TXTEST_t, *PTXMAC_TXTEST_t; + + +/****************************************************************************** + structure for error reg in txmac address map + located at address 0x3018 + *****************************************************************************/ +typedef union _TXMAC_ERR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused2:23; //bits 9-31 + UINT32 fifo_underrun:1; //bit 8 + UINT32 unused1:2; //bits 6-7 + UINT32 ctrl2_err:1; //bit 5 + UINT32 txq_underrun:1; //bit 4 + UINT32 bcnt_err:1; //bit 3 + UINT32 lseg_err:1; //bit 2 + UINT32 segnum_err:1; //bit 1 + UINT32 seg0_err:1; //bit 0 + #else + UINT32 seg0_err:1; //bit 0 + UINT32 segnum_err:1; //bit 1 + UINT32 lseg_err:1; //bit 2 + UINT32 bcnt_err:1; //bit 3 + UINT32 txq_underrun:1; //bit 4 + UINT32 ctrl2_err:1; //bit 5 + UINT32 unused1:2; //bits 6-7 + UINT32 fifo_underrun:1; //bit 8 + UINT32 unused2:23; //bits 9-31 + #endif + } bits; +} +TXMAC_ERR_t, *PTXMAC_ERR_t; + + +/****************************************************************************** + structure for error interrupt reg in txmac address map + located at address 0x301C + *****************************************************************************/ +typedef union _TXMAC_ERR_INT_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused2:23; //bits 9-31 + UINT32 fifo_underrun:1; //bit 8 + UINT32 unused1:2; //bits 6-7 + UINT32 ctrl2_err:1; //bit 5 + UINT32 txq_underrun:1; //bit 4 + UINT32 bcnt_err:1; //bit 3 + UINT32 lseg_err:1; //bit 2 + UINT32 segnum_err:1; //bit 1 + UINT32 seg0_err:1; //bit 0 + #else + UINT32 seg0_err:1; //bit 0 + UINT32 segnum_err:1; //bit 1 + UINT32 lseg_err:1; //bit 2 + UINT32 bcnt_err:1; //bit 3 + UINT32 txq_underrun:1; //bit 4 + UINT32 ctrl2_err:1; //bit 5 + UINT32 unused1:2; //bits 6-7 + UINT32 fifo_underrun:1; //bit 8 + UINT32 unused2:23; //bits 9-31 + #endif + } bits; +} +TXMAC_ERR_INT_t, *PTXMAC_ERR_INT_t; + + +/****************************************************************************** + structure for error interrupt reg in txmac address map + located at address 0x3020 + *****************************************************************************/ +typedef union _TXMAC_CP_CTRL_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:30; //bits 2-31 + UINT32 bp_req:1; //bit 1 + UINT32 bp_xonxoff:1; //bit 0 + #else + UINT32 bp_xonxoff:1; //bit 0 + UINT32 bp_req:1; //bit 1 + UINT32 unused:30; //bits 2-31 + #endif + } bits; +} +TXMAC_BP_CTRL_t, *PTXMAC_BP_CTRL_t; + + +/****************************************************************************** + Tx MAC Module of JAGCore Address Mapping + *****************************************************************************/ +typedef struct _TXMAC_t +{ //Location: + TXMAC_CTL_t ctl; // 0x3000 + TXMAC_SHADOW_PTR_t shadow_ptr; // 0x3004 + TXMAC_ERR_CNT_t err_cnt; // 0x3008 + TXMAC_MAX_FILL_t max_fill; // 0x300C + TXMAC_CF_PARAM_t cf_param; // 0x3010 + TXMAC_TXTEST_t tx_test; // 0x3014 + TXMAC_ERR_t err; // 0x3018 + TXMAC_ERR_INT_t err_int; // 0x301C + TXMAC_BP_CTRL_t bp_ctrl; // 0x3020 +} +TXMAC_t, *PTXMAC_t; +/*===========================================================================*/ +/*===========================================================================*/ +/*=== END OF TXMAC REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ + + + +/*===========================================================================*/ +/*===========================================================================*/ +/*=== START OF RXMAC REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ +/****************************************************************************** + structure for rxmac control reg in rxmac address map + located at address 0x4000 + *****************************************************************************/ +typedef union _RXMAC_CTRL_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved:25; //bits 7-31 + UINT32 rxmac_int_disable:1; //bit 6 + UINT32 async_disable:1; //bit 5 + UINT32 mif_disable:1; //bit 4 + UINT32 wol_disable:1; //bit 3 + UINT32 pkt_filter_disable:1; //bit 2 + UINT32 mcif_disable:1; //bit 1 + UINT32 rxmac_en:1; //bit 0 + #else + UINT32 rxmac_en:1; //bit 0 + UINT32 mcif_disable:1; //bit 1 + UINT32 pkt_filter_disable:1; //bit 2 + UINT32 wol_disable:1; //bit 3 + UINT32 mif_disable:1; //bit 4 + UINT32 async_disable:1; //bit 5 + UINT32 rxmac_int_disable:1; //bit 6 + UINT32 reserved:25; //bits 7-31 + #endif + } bits; +} +RXMAC_CTRL_t, *PRXMAC_CTRL_t; + + +/****************************************************************************** + structure for Wake On Lan Control and CRC 0 reg in rxmac address map + located at address 0x4004 + *****************************************************************************/ +typedef union _RXMAC_WOL_CTL_CRC0_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 crc0:16; //bits 16-31 + UINT32 reserve:4; //bits 12-15 + UINT32 ignore_pp:1; //bit 11 + UINT32 ignore_mp:1; //bit 10 + UINT32 clr_intr:1; //bit 9 + UINT32 ignore_link_chg:1; //bit 8 + UINT32 ignore_uni:1; //bit 7 + UINT32 ignore_multi:1; //bit 6 + UINT32 ignore_broad:1; //bit 5 + UINT32 valid_crc4:1; //bit 4 + UINT32 valid_crc3:1; //bit 3 + UINT32 valid_crc2:1; //bit 2 + UINT32 valid_crc1:1; //bit 1 + UINT32 valid_crc0:1; //bit 0 + #else + UINT32 valid_crc0:1; //bit 0 + UINT32 valid_crc1:1; //bit 1 + UINT32 valid_crc2:1; //bit 2 + UINT32 valid_crc3:1; //bit 3 + UINT32 valid_crc4:1; //bit 4 + UINT32 ignore_broad:1; //bit 5 + UINT32 ignore_multi:1; //bit 6 + UINT32 ignore_uni:1; //bit 7 + UINT32 ignore_link_chg:1; //bit 8 + UINT32 clr_intr:1; //bit 9 + UINT32 ignore_mp:1; //bit 10 + UINT32 ignore_pp:1; //bit 11 + UINT32 reserve:4; //bits 12-15 + UINT32 crc0:16; //bits 16-31 + #endif + } bits; +} +RXMAC_WOL_CTL_CRC0_t, *PRXMAC_WOL_CTL_CRC0_t; + + +/****************************************************************************** + structure for CRC 1 and CRC 2 reg in rxmac address map + located at address 0x4008 + *****************************************************************************/ +typedef union _RXMAC_WOL_CRC12_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 crc2:16; //bits 16-31 + UINT32 crc1:16; //bits 0-15 + #else + UINT32 crc1:16; //bits 0-15 + UINT32 crc2:16; //bits 16-31 + #endif + } bits; +} +RXMAC_WOL_CRC12_t, *PRXMAC_WOL_CRC12_t; + + +/****************************************************************************** + structure for CRC 3 and CRC 4 reg in rxmac address map + located at address 0x400C + *****************************************************************************/ +typedef union _RXMAC_WOL_CRC34_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 crc4:16; //bits 16-31 + UINT32 crc3:16; //bits 0-15 + #else + UINT32 crc3:16; //bits 0-15 + UINT32 crc4:16; //bits 16-31 + #endif + } bits; +} +RXMAC_WOL_CRC34_t, *PRXMAC_WOL_CRC34_t; + + +/****************************************************************************** + structure for Wake On Lan Source Address Lo reg in rxmac address map + located at address 0x4010 + *****************************************************************************/ +typedef union _RXMAC_WOL_SA_LO_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 sa3:8; //bits 24-31 + UINT32 sa4:8; //bits 16-23 + UINT32 sa5:8; //bits 8-15 + UINT32 sa6:8; //bits 0-7 + #else + UINT32 sa6:8; //bits 0-7 + UINT32 sa5:8; //bits 8-15 + UINT32 sa4:8; //bits 16-23 + UINT32 sa3:8; //bits 24-31 + #endif + } bits; +} +RXMAC_WOL_SA_LO_t, *PRXMAC_WOL_SA_LO_t; + + +/****************************************************************************** + structure for Wake On Lan Source Address Hi reg in rxmac address map + located at address 0x4014 + *****************************************************************************/ +typedef union _RXMAC_WOL_SA_HI_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved:16; //bits 16-31 + UINT32 sa1:8; //bits 8-15 + UINT32 sa2:8; //bits 0-7 + #else + UINT32 sa2:8; //bits 0-7 + UINT32 sa1:8; //bits 8-15 + UINT32 reserved:16; //bits 16-31 + #endif + } bits; +} +RXMAC_WOL_SA_HI_t, *PRXMAC_WOL_SA_HI_t; + + +/****************************************************************************** + structure for Wake On Lan mask reg in rxmac address map + located at address 0x4018 - 0x4064 + *****************************************************************************/ +typedef struct _RXMAC_WOL_MASK_t +{ + UINT32 mask; //bits 0-31 +} +RXMAC_WOL_MASK_t, *PRXMAC_WOL_MASK_t; + + +/****************************************************************************** + structure for Unicast Paket Filter Address 1 reg in rxmac address map + located at address 0x4068 + *****************************************************************************/ +typedef union _RXMAC_UNI_PF_ADDR1_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 addr1_3:8; //bits 24-31 + UINT32 addr1_4:8; //bits 16-23 + UINT32 addr1_5:8; //bits 8-15 + UINT32 addr1_6:8; //bits 0-7 + #else + UINT32 addr1_6:8; //bits 0-7 + UINT32 addr1_5:8; //bits 8-15 + UINT32 addr1_4:8; //bits 16-23 + UINT32 addr1_3:8; //bits 24-31 + #endif + } bits; +} +RXMAC_UNI_PF_ADDR1_t, *PRXMAC_UNI_PF_ADDR1_t; + + +/****************************************************************************** + structure for Unicast Paket Filter Address 2 reg in rxmac address map + located at address 0x406C + *****************************************************************************/ +typedef union _RXMAC_UNI_PF_ADDR2_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 addr2_3:8; //bits 24-31 + UINT32 addr2_4:8; //bits 16-23 + UINT32 addr2_5:8; //bits 8-15 + UINT32 addr2_6:8; //bits 0-7 + #else + UINT32 addr2_6:8; //bits 0-7 + UINT32 addr2_5:8; //bits 8-15 + UINT32 addr2_4:8; //bits 16-23 + UINT32 addr2_3:8; //bits 24-31 + #endif + } bits; +} +RXMAC_UNI_PF_ADDR2_t, *PRXMAC_UNI_PF_ADDR2_t; + + +/****************************************************************************** + structure for Unicast Paket Filter Address 1 & 2 reg in rxmac address map + located at address 0x4070 + *****************************************************************************/ +typedef union _RXMAC_UNI_PF_ADDR3_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 addr2_1:8; //bits 24-31 + UINT32 addr2_2:8; //bits 16-23 + UINT32 addr1_1:8; //bits 8-15 + UINT32 addr1_2:8; //bits 0-7 + #else + UINT32 addr1_2:8; //bits 0-7 + UINT32 addr1_1:8; //bits 8-15 + UINT32 addr2_2:8; //bits 16-23 + UINT32 addr2_1:8; //bits 24-31 + #endif + } bits; +} +RXMAC_UNI_PF_ADDR3_t, *PRXMAC_UNI_PF_ADDR3_t; + + +/****************************************************************************** + structure for Multicast Hash reg in rxmac address map + located at address 0x4074 - 0x4080 + *****************************************************************************/ +typedef struct _RXMAC_MULTI_HASH_t +{ + UINT32 hash; //bits 0-31 +} +RXMAC_MULTI_HASH_t, *PRXMAC_MULTI_HASH_t; + + +/****************************************************************************** + structure for Packet Filter Control reg in rxmac address map + located at address 0x4084 + *****************************************************************************/ +typedef union _RXMAC_PF_CTRL_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused2:9; //bits 23-31 + UINT32 min_pkt_size:7; //bits 16-22 + UINT32 unused1:12; //bits 4-15 + UINT32 filter_frag_en:1; //bit 3 + UINT32 filter_uni_en:1; //bit 2 + UINT32 filter_multi_en:1; //bit 1 + UINT32 filter_broad_en:1; //bit 0 + #else + UINT32 filter_broad_en:1; //bit 0 + UINT32 filter_multi_en:1; //bit 1 + UINT32 filter_uni_en:1; //bit 2 + UINT32 filter_frag_en:1; //bit 3 + UINT32 unused1:12; //bits 4-15 + UINT32 min_pkt_size:7; //bits 16-22 + UINT32 unused2:9; //bits 23-31 + #endif + } bits; +} +RXMAC_PF_CTRL_t, *PRXMAC_PF_CTRL_t; + + +/****************************************************************************** + structure for Memory Controller Interface Control Max Segment reg in rxmac + address map. Located at address 0x4088 + *****************************************************************************/ +typedef union _RXMAC_MCIF_CTRL_MAX_SEG_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved:22; //bits 10-31 + UINT32 max_size:8; //bits 2-9 + UINT32 fc_en:1; //bit 1 + UINT32 seg_en:1; //bit 0 + #else + UINT32 seg_en:1; //bit 0 + UINT32 fc_en:1; //bit 1 + UINT32 max_size:8; //bits 2-9 + UINT32 reserved:22; //bits 10-31 + #endif + } bits; +} +RXMAC_MCIF_CTRL_MAX_SEG_t, *PRXMAC_MCIF_CTRL_MAX_SEG_t; + + +/****************************************************************************** + structure for Memory Controller Interface Water Mark reg in rxmac address + map. Located at address 0x408C + *****************************************************************************/ +typedef union _RXMAC_MCIF_WATER_MARK_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved2:6; //bits 26-31 + UINT32 mark_hi:10; //bits 16-25 + UINT32 reserved1:6; //bits 10-15 + UINT32 mark_lo:10; //bits 0-9 + #else + UINT32 mark_lo:10; //bits 0-9 + UINT32 reserved1:6; //bits 10-15 + UINT32 mark_hi:10; //bits 16-25 + UINT32 reserved2:6; //bits 26-31 + #endif + } bits; +} +RXMAC_MCIF_WATER_MARK_t, *PRXMAC_MCIF_WATER_MARK_t; + + +/****************************************************************************** + structure for Rx Queue Dialog reg in rxmac address map. + located at address 0x4090 + *****************************************************************************/ +typedef union _RXMAC_RXQ_DIAG_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved2:6; //bits 26-31 + UINT32 rd_ptr:10; //bits 16-25 + UINT32 reserved1:6; //bits 10-15 + UINT32 wr_ptr:10; //bits 0-9 + #else + UINT32 wr_ptr:10; //bits 0-9 + UINT32 reserved1:6; //bits 10-15 + UINT32 rd_ptr:10; //bits 16-25 + UINT32 reserved2:6; //bits 26-31 + #endif + } bits; +} +RXMAC_RXQ_DIAG_t, *PRXMAC_RXQ_DIAG_t; + + +/****************************************************************************** + structure for space availiable reg in rxmac address map. + located at address 0x4094 + *****************************************************************************/ +typedef union _RXMAC_SPACE_AVAIL_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved2:15; //bits 17-31 + UINT32 space_avail_en:1; //bit 16 + UINT32 reserved1:6; //bits 10-15 + UINT32 space_avail:10; //bits 0-9 + #else + UINT32 space_avail:10; //bits 0-9 + UINT32 reserved1:6; //bits 10-15 + UINT32 space_avail_en:1; //bit 16 + UINT32 reserved2:15; //bits 17-31 + #endif + } bits; +} +RXMAC_SPACE_AVAIL_t, *PRXMAC_SPACE_AVAIL_t; + + +/****************************************************************************** + structure for management interface reg in rxmac address map. + located at address 0x4098 + *****************************************************************************/ +typedef union _RXMAC_MIF_CTL_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserve:14; //bits 18-31 + UINT32 drop_pkt_en:1; //bit 17 + UINT32 drop_pkt_mask:17; //bits 0-16 + #else + UINT32 drop_pkt_mask:17; //bits 0-16 + UINT32 drop_pkt_en:1; //bit 17 + UINT32 reserve:14; //bits 18-31 + #endif + } bits; +} +RXMAC_MIF_CTL_t, *PRXMAC_MIF_CTL_t; + + +/****************************************************************************** + structure for Error reg in rxmac address map. + located at address 0x409C + *****************************************************************************/ +typedef union _RXMAC_ERROR_REG_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserve:28; //bits 4-31 + UINT32 mif:1; //bit 3 + UINT32 async:1; //bit 2 + UINT32 pkt_filter:1; //bit 1 + UINT32 mcif:1; //bit 0 + #else + UINT32 mcif:1; //bit 0 + UINT32 pkt_filter:1; //bit 1 + UINT32 async:1; //bit 2 + UINT32 mif:1; //bit 3 + UINT32 reserve:28; //bits 4-31 + #endif + } bits; +} +RXMAC_ERROR_REG_t, *PRXMAC_ERROR_REG_t; + + +/****************************************************************************** + Rx MAC Module of JAGCore Address Mapping + *****************************************************************************/ +typedef struct _RXMAC_t +{ //Location: + RXMAC_CTRL_t ctrl; // 0x4000 + RXMAC_WOL_CTL_CRC0_t crc0; // 0x4004 + RXMAC_WOL_CRC12_t crc12; // 0x4008 + RXMAC_WOL_CRC34_t crc34; // 0x400C + RXMAC_WOL_SA_LO_t sa_lo; // 0x4010 + RXMAC_WOL_SA_HI_t sa_hi; // 0x4014 + RXMAC_WOL_MASK_t mask0_word0; // 0x4018 + RXMAC_WOL_MASK_t mask0_word1; // 0x401C + RXMAC_WOL_MASK_t mask0_word2; // 0x4020 + RXMAC_WOL_MASK_t mask0_word3; // 0x4024 + RXMAC_WOL_MASK_t mask1_word0; // 0x4028 + RXMAC_WOL_MASK_t mask1_word1; // 0x402C + RXMAC_WOL_MASK_t mask1_word2; // 0x4030 + RXMAC_WOL_MASK_t mask1_word3; // 0x4034 + RXMAC_WOL_MASK_t mask2_word0; // 0x4038 + RXMAC_WOL_MASK_t mask2_word1; // 0x403C + RXMAC_WOL_MASK_t mask2_word2; // 0x4040 + RXMAC_WOL_MASK_t mask2_word3; // 0x4044 + RXMAC_WOL_MASK_t mask3_word0; // 0x4048 + RXMAC_WOL_MASK_t mask3_word1; // 0x404C + RXMAC_WOL_MASK_t mask3_word2; // 0x4050 + RXMAC_WOL_MASK_t mask3_word3; // 0x4054 + RXMAC_WOL_MASK_t mask4_word0; // 0x4058 + RXMAC_WOL_MASK_t mask4_word1; // 0x405C + RXMAC_WOL_MASK_t mask4_word2; // 0x4060 + RXMAC_WOL_MASK_t mask4_word3; // 0x4064 + RXMAC_UNI_PF_ADDR1_t uni_pf_addr1; // 0x4068 + RXMAC_UNI_PF_ADDR2_t uni_pf_addr2; // 0x406C + RXMAC_UNI_PF_ADDR3_t uni_pf_addr3; // 0x4070 + RXMAC_MULTI_HASH_t multi_hash1; // 0x4074 + RXMAC_MULTI_HASH_t multi_hash2; // 0x4078 + RXMAC_MULTI_HASH_t multi_hash3; // 0x407C + RXMAC_MULTI_HASH_t multi_hash4; // 0x4080 + RXMAC_PF_CTRL_t pf_ctrl; // 0x4084 + RXMAC_MCIF_CTRL_MAX_SEG_t mcif_ctrl_max_seg; // 0x4088 + RXMAC_MCIF_WATER_MARK_t mcif_water_mark; // 0x408C + RXMAC_RXQ_DIAG_t rxq_diag; // 0x4090 + RXMAC_SPACE_AVAIL_t space_avail; // 0x4094 + + RXMAC_MIF_CTL_t mif_ctrl; // 0x4098 + RXMAC_ERROR_REG_t err_reg; // 0x409C +} +RXMAC_t, *PRXMAC_t; +/*===========================================================================*/ +/*===========================================================================*/ +/*=== END OF TXMAC REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ + + + +/*===========================================================================*/ +/*===========================================================================*/ +/*=== START OF MAC REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ +/****************************************************************************** + structure for configuration #1 reg in mac address map. + located at address 0x5000 + *****************************************************************************/ +typedef union _MAC_CFG1_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 soft_reset:1; //bit 31 + UINT32 sim_reset:1; //bit 30 + UINT32 reserved3:10; //bits 20-29 + UINT32 reset_rx_mc:1; //bit 19 + UINT32 reset_tx_mc:1; //bit 18 + UINT32 reset_rx_fun:1; //bit 17 + UINT32 reset_tx_fun:1; //bit 16 + UINT32 reserved2:7; //bits 9-15 + UINT32 loop_back:1; //bit 8 + UINT32 reserved1:2; //bits 6-7 + UINT32 rx_flow:1; //bit 5 + UINT32 tx_flow:1; //bit 4 + UINT32 syncd_rx_en:1; //bit 3 + UINT32 rx_enable:1; //bit 2 + UINT32 syncd_tx_en:1; //bit 1 + UINT32 tx_enable:1; //bit 0 + #else + UINT32 tx_enable:1; //bit 0 + UINT32 syncd_tx_en:1; //bit 1 + UINT32 rx_enable:1; //bit 2 + UINT32 syncd_rx_en:1; //bit 3 + UINT32 tx_flow:1; //bit 4 + UINT32 rx_flow:1; //bit 5 + UINT32 reserved1:2; //bits 6-7 + UINT32 loop_back:1; //bit 8 + UINT32 reserved2:7; //bits 9-15 + UINT32 reset_tx_fun:1; //bit 16 + UINT32 reset_rx_fun:1; //bit 17 + UINT32 reset_tx_mc:1; //bit 18 + UINT32 reset_rx_mc:1; //bit 19 + UINT32 reserved3:10; //bits 20-29 + UINT32 sim_reset:1; //bit 30 + UINT32 soft_reset:1; //bit 31 + #endif + } bits; +} +MAC_CFG1_t, *PMAC_CFG1_t; + + +/****************************************************************************** + structure for configuration #2 reg in mac address map. + located at address 0x5004 + *****************************************************************************/ +typedef union _MAC_CFG2_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved3:16; //bits 16-31 + UINT32 preamble_len:4; //bits 12-15 + UINT32 reserved2:2; //bits 10-11 + UINT32 if_mode:2; //bits 8-9 + UINT32 reserved1:2; //bits 6-7 + UINT32 huge_frame:1; //bit 5 + UINT32 len_check:1; //bit 4 + UINT32 undefined:1; //bit 3 + UINT32 pad_crc:1; //bit 2 + UINT32 crc_enable:1; //bit 1 + UINT32 full_duplex:1; //bit 0 + #else + UINT32 full_duplex:1; //bit 0 + UINT32 crc_enable:1; //bit 1 + UINT32 pad_crc:1; //bit 2 + UINT32 undefined:1; //bit 3 + UINT32 len_check:1; //bit 4 + UINT32 huge_frame:1; //bit 5 + UINT32 reserved1:2; //bits 6-7 + UINT32 if_mode:2; //bits 8-9 + UINT32 reserved2:2; //bits 10-11 + UINT32 preamble_len:4; //bits 12-15 + UINT32 reserved3:16; //bits 16-31 + #endif + } bits; +} +MAC_CFG2_t, *PMAC_CFG2_t; + + +/****************************************************************************** + structure for Interpacket gap reg in mac address map. + located at address 0x5008 + *****************************************************************************/ +typedef union _MAC_IPG_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved:1; //bit 31 + UINT32 non_B2B_ipg_1:7; //bits 24-30 + UINT32 undefined2:1; //bit 23 + UINT32 non_B2B_ipg_2:7; //bits 16-22 + UINT32 min_ifg_enforce:8; //bits 8-15 + UINT32 undefined1:1; //bit 7 + UINT32 B2B_ipg:7; //bits 0-6 + #else + UINT32 B2B_ipg:7; //bits 0-6 + UINT32 undefined1:1; //bit 7 + UINT32 min_ifg_enforce:8; //bits 8-15 + UINT32 non_B2B_ipg_2:7; //bits 16-22 + UINT32 undefined2:1; //bit 23 + UINT32 non_B2B_ipg_1:7; //bits 24-30 + UINT32 reserved:1; //bit 31 + #endif + } bits; +} +MAC_IPG_t, *PMAC_IPG_t; + + +/****************************************************************************** + structure for half duplex reg in mac address map. + located at address 0x500C + *****************************************************************************/ +typedef union _MAC_HFDP_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved2:8; //bits 24-31 + UINT32 alt_beb_trunc:4; //bits 23-20 + UINT32 alt_beb_enable:1; //bit 19 + UINT32 bp_no_backoff:1; //bit 18 + UINT32 no_backoff:1; //bit 17 + UINT32 excess_defer:1; //bit 16 + UINT32 rexmit_max:4; //bits 12-15 + UINT32 reserved1:2; //bits 10-11 + UINT32 coll_window:10; //bits 0-9 + #else + UINT32 coll_window:10; //bits 0-9 + UINT32 reserved1:2; //bits 10-11 + UINT32 rexmit_max:4; //bits 12-15 + UINT32 excess_defer:1; //bit 16 + UINT32 no_backoff:1; //bit 17 + UINT32 bp_no_backoff:1; //bit 18 + UINT32 alt_beb_enable:1; //bit 19 + UINT32 alt_beb_trunc:4; //bits 23-20 + UINT32 reserved2:8; //bits 24-31 + #endif + } bits; +} +MAC_HFDP_t, *PMAC_HFDP_t; + + +/****************************************************************************** + structure for Maximum Frame Length reg in mac address map. + located at address 0x5010 + *****************************************************************************/ +typedef union _MAC_MAX_FM_LEN_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved:16; //bits 16-31 + UINT32 max_len:16; //bits 0-15 + #else + UINT32 max_len:16; //bits 0-15 + UINT32 reserved:16; //bits 16-31 + #endif + } bits; +} +MAC_MAX_FM_LEN_t, *PMAC_MAX_FM_LEN_t; + + +/****************************************************************************** + structure for Reserve 1 reg in mac address map. + located at address 0x5014 - 0x5018 + *****************************************************************************/ +typedef struct _MAC_RSV_t +{ + UINT32 value; //bits 0-31 +} +MAC_RSV_t, *PMAC_RSV_t; + + +/****************************************************************************** + structure for Test reg in mac address map. + located at address 0x501C + *****************************************************************************/ +typedef union _MAC_TEST_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:29; //bits 3-31 + UINT32 mac_test:3; //bits 0-2 + #else + UINT32 mac_test:3; //bits 0-2 + UINT32 unused:29; //bits 3-31 + #endif + } bits; +} +MAC_TEST_t, *PMAC_TEST_t; + + +/****************************************************************************** + structure for MII Management Configuration reg in mac address map. + located at address 0x5020 + *****************************************************************************/ +typedef union _MII_MGMT_CFG_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reset_mii_mgmt:1; //bit 31 + UINT32 reserved:25; //bits 6-30 + UINT32 scan_auto_incremt:1; //bit 5 + UINT32 preamble_suppress:1; //bit 4 + UINT32 undefined:1; //bit 3 + UINT32 mgmt_clk_reset:3; //bits 0-2 + #else + UINT32 mgmt_clk_reset:3; //bits 0-2 + UINT32 undefined:1; //bit 3 + UINT32 preamble_suppress:1; //bit 4 + UINT32 scan_auto_incremt:1; //bit 5 + UINT32 reserved:25; //bits 6-30 + UINT32 reset_mii_mgmt:1; //bit 31 + #endif + } bits; +} +MII_MGMT_CFG_t, *PMII_MGMT_CFG_t; + + +/****************************************************************************** + structure for MII Management Command reg in mac address map. + located at address 0x5024 + *****************************************************************************/ +typedef union _MII_MGMT_CMD_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved:30; //bits 2-31 + UINT32 scan_cycle:1; //bit 1 + UINT32 read_cycle:1; //bit 0 + #else + UINT32 read_cycle:1; //bit 0 + UINT32 scan_cycle:1; //bit 1 + UINT32 reserved:30; //bits 2-31 + #endif + } bits; +} +MII_MGMT_CMD_t, *PMII_MGMT_CMD_t; + + +/****************************************************************************** + structure for MII Management Address reg in mac address map. + located at address 0x5028 + *****************************************************************************/ +typedef union _MII_MGMT_ADDR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved2:19; //bit 13-31 + UINT32 phy_addr:5; //bits 8-12 + UINT32 reserved1:3; //bits 5-7 + UINT32 reg_addr:5; //bits 0-4 + #else + UINT32 reg_addr:5; //bits 0-4 + UINT32 reserved1:3; //bits 5-7 + UINT32 phy_addr:5; //bits 8-12 + UINT32 reserved2:19; //bit 13-31 + #endif + } bits; +} +MII_MGMT_ADDR_t, *PMII_MGMT_ADDR_t; + + +/****************************************************************************** + structure for MII Management Control reg in mac address map. + located at address 0x502C + *****************************************************************************/ +typedef union _MII_MGMT_CTRL_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved:16; //bits 16-31 + UINT32 phy_ctrl:16; //bits 0-15 + #else + UINT32 phy_ctrl:16; //bits 0-15 + UINT32 reserved:16; //bits 16-31 + #endif + } bits; +} +MII_MGMT_CTRL_t, *PMII_MGMT_CTRL_t; + + +/****************************************************************************** + structure for MII Management Status reg in mac address map. + located at address 0x5030 + *****************************************************************************/ +typedef union _MII_MGMT_STAT_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved:16; //bits 16-31 + UINT32 phy_stat:16; //bits 0-15 + #else + UINT32 phy_stat:16; //bits 0-15 + UINT32 reserved:16; //bits 16-31 + #endif + } bits; +} +MII_MGMT_STAT_t, *PMII_MGMT_STAT_t; + + +/****************************************************************************** + structure for MII Management Indicators reg in mac address map. + located at address 0x5034 + *****************************************************************************/ +typedef union _MII_MGMT_INDICATOR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved:29; //bits 3-31 + UINT32 not_valid:1; //bit 2 + UINT32 scanning:1; //bit 1 + UINT32 busy:1; //bit 0 + #else + UINT32 busy:1; //bit 0 + UINT32 scanning:1; //bit 1 + UINT32 not_valid:1; //bit 2 + UINT32 reserved:29; //bits 3-31 + #endif + } bits; +} +MII_MGMT_INDICATOR_t, *PMII_MGMT_INDICATOR_t; + + +/****************************************************************************** + structure for Interface Control reg in mac address map. + located at address 0x5038 + *****************************************************************************/ +typedef union _MAC_IF_CTRL_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reset_if_module:1; //bit 31 + UINT32 reserved4:3; //bit 28-30 + UINT32 tbi_mode:1; //bit 27 + UINT32 ghd_mode:1; //bit 26 + UINT32 lhd_mode:1; //bit 25 + UINT32 phy_mode:1; //bit 24 + UINT32 reset_per_mii:1; //bit 23 + UINT32 reserved3:6; //bits 17-22 + UINT32 speed:1; //bit 16 + UINT32 reset_pe100x:1; //bit 15 + UINT32 reserved2:4; //bits 11-14 + UINT32 force_quiet:1; //bit 10 + UINT32 no_cipher:1; //bit 9 + UINT32 disable_link_fail:1; //bit 8 + UINT32 reset_gpsi:1; //bit 7 + UINT32 reserved1:6; //bits 1-6 + UINT32 enab_jab_protect:1; //bit 0 + #else + UINT32 enab_jab_protect:1; //bit 0 + UINT32 reserved1:6; //bits 1-6 + UINT32 reset_gpsi:1; //bit 7 + UINT32 disable_link_fail:1; //bit 8 + UINT32 no_cipher:1; //bit 9 + UINT32 force_quiet:1; //bit 10 + UINT32 reserved2:4; //bits 11-14 + UINT32 reset_pe100x:1; //bit 15 + UINT32 speed:1; //bit 16 + UINT32 reserved3:6; //bits 17-22 + UINT32 reset_per_mii:1; //bit 23 + UINT32 phy_mode:1; //bit 24 + UINT32 lhd_mode:1; //bit 25 + UINT32 ghd_mode:1; //bit 26 + UINT32 tbi_mode:1; //bit 27 + UINT32 reserved4:3; //bit 28-30 + UINT32 reset_if_module:1; //bit 31 + #endif + } bits; +} +MAC_IF_CTRL_t, *PMAC_IF_CTRL_t; + + +/****************************************************************************** + structure for Interface Status reg in mac address map. + located at address 0x503C + *****************************************************************************/ +typedef union _MAC_IF_STAT_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved:22; //bits 10-31 + UINT32 excess_defer:1; //bit 9 + UINT32 clash:1; //bit 8 + UINT32 phy_jabber:1; //bit 7 + UINT32 phy_link_ok:1; //bit 6 + UINT32 phy_full_duplex:1; //bit 5 + UINT32 phy_speed:1; //bit 4 + UINT32 pe100x_link_fail:1; //bit 3 + UINT32 pe10t_loss_carrie:1; //bit 2 + UINT32 pe10t_sqe_error:1; //bit 1 + UINT32 pe10t_jabber:1; //bit 0 + #else + UINT32 pe10t_jabber:1; //bit 0 + UINT32 pe10t_sqe_error:1; //bit 1 + UINT32 pe10t_loss_carrie:1; //bit 2 + UINT32 pe100x_link_fail:1; //bit 3 + UINT32 phy_speed:1; //bit 4 + UINT32 phy_full_duplex:1; //bit 5 + UINT32 phy_link_ok:1; //bit 6 + UINT32 phy_jabber:1; //bit 7 + UINT32 clash:1; //bit 8 + UINT32 excess_defer:1; //bit 9 + UINT32 reserved:22; //bits 10-31 + #endif + } bits; +} +MAC_IF_STAT_t, *PMAC_IF_STAT_t; + + +/****************************************************************************** + structure for Mac Station Address, Part 1 reg in mac address map. + located at address 0x5040 + *****************************************************************************/ +typedef union _MAC_STATION_ADDR1_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 Octet6:8; //bits 24-31 + UINT32 Octet5:8; //bits 16-23 + UINT32 Octet4:8; //bits 8-15 + UINT32 Octet3:8; //bits 0-7 + #else + UINT32 Octet3:8; //bits 0-7 + UINT32 Octet4:8; //bits 8-15 + UINT32 Octet5:8; //bits 16-23 + UINT32 Octet6:8; //bits 24-31 + #endif + } bits; +} +MAC_STATION_ADDR1_t, *PMAC_STATION_ADDR1_t; + + +/****************************************************************************** + structure for Mac Station Address, Part 2 reg in mac address map. + located at address 0x5044 + *****************************************************************************/ +typedef union _MAC_STATION_ADDR2_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 Octet2:8; //bits 24-31 + UINT32 Octet1:8; //bits 16-23 + UINT32 reserved:16; //bits 0-15 + #else + UINT32 reserved:16; //bit 0-15 + UINT32 Octet1:8; //bits 16-23 + UINT32 Octet2:8; //bits 24-31 + #endif + } bits; +} +MAC_STATION_ADDR2_t, *PMAC_STATION_ADDR2_t; + + +/****************************************************************************** + MAC Module of JAGCore Address Mapping + *****************************************************************************/ +typedef struct _MAC_t +{ //Location: + MAC_CFG1_t cfg1; // 0x5000 + MAC_CFG2_t cfg2; // 0x5004 + MAC_IPG_t ipg; // 0x5008 + MAC_HFDP_t hfdp; // 0x500C + MAC_MAX_FM_LEN_t max_fm_len; // 0x5010 + MAC_RSV_t rsv1; // 0x5014 + MAC_RSV_t rsv2; // 0x5018 + MAC_TEST_t mac_test; // 0x501C + MII_MGMT_CFG_t mii_mgmt_cfg; // 0x5020 + MII_MGMT_CMD_t mii_mgmt_cmd; // 0x5024 + MII_MGMT_ADDR_t mii_mgmt_addr; // 0x5028 + MII_MGMT_CTRL_t mii_mgmt_ctrl; // 0x502C + MII_MGMT_STAT_t mii_mgmt_stat; // 0x5030 + MII_MGMT_INDICATOR_t mii_mgmt_indicator; // 0x5034 + MAC_IF_CTRL_t if_ctrl; // 0x5038 + MAC_IF_STAT_t if_stat; // 0x503C + MAC_STATION_ADDR1_t station_addr_1; // 0x5040 + MAC_STATION_ADDR2_t station_addr_2; // 0x5044 +} +MAC_t, *PMAC_t; +/*===========================================================================*/ +/*===========================================================================*/ +/*=== END OF MAC REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ + + + +/*===========================================================================*/ +/*===========================================================================*/ +/*=== START OF MAC STAT REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ +/****************************************************************************** + structure for Carry Register One and it's Mask Register reg located in mac + stat address map address 0x6130 and 0x6138. + *****************************************************************************/ +typedef union _MAC_STAT_REG_1_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 tr64:1; //bit 31 + UINT32 tr127:1; //bit 30 + UINT32 tr255:1; //bit 29 + UINT32 tr511:1; //bit 28 + UINT32 tr1k:1; //bit 27 + UINT32 trmax:1; //bit 26 + UINT32 trmgv:1; //bit 25 + UINT32 unused:8; //bits 17-24 + UINT32 rbyt:1; //bit 16 + UINT32 rpkt:1; //bit 15 + UINT32 rfcs:1; //bit 14 + UINT32 rmca:1; //bit 13 + UINT32 rbca:1; //bit 12 + UINT32 rxcf:1; //bit 11 + UINT32 rxpf:1; //bit 10 + UINT32 rxuo:1; //bit 9 + UINT32 raln:1; //bit 8 + UINT32 rflr:1; //bit 7 + UINT32 rcde:1; //bit 6 + UINT32 rcse:1; //bit 5 + UINT32 rund:1; //bit 4 + UINT32 rovr:1; //bit 3 + UINT32 rfrg:1; //bit 2 + UINT32 rjbr:1; //bit 1 + UINT32 rdrp:1; //bit 0 + #else + UINT32 rdrp:1; //bit 0 + UINT32 rjbr:1; //bit 1 + UINT32 rfrg:1; //bit 2 + UINT32 rovr:1; //bit 3 + UINT32 rund:1; //bit 4 + UINT32 rcse:1; //bit 5 + UINT32 rcde:1; //bit 6 + UINT32 rflr:1; //bit 7 + UINT32 raln:1; //bit 8 + UINT32 rxuo:1; //bit 9 + UINT32 rxpf:1; //bit 10 + UINT32 rxcf:1; //bit 11 + UINT32 rbca:1; //bit 12 + UINT32 rmca:1; //bit 13 + UINT32 rfcs:1; //bit 14 + UINT32 rpkt:1; //bit 15 + UINT32 rbyt:1; //bit 16 + UINT32 unused:8; //bits 17-24 + UINT32 trmgv:1; //bit 25 + UINT32 trmax:1; //bit 26 + UINT32 tr1k:1; //bit 27 + UINT32 tr511:1; //bit 28 + UINT32 tr255:1; //bit 29 + UINT32 tr127:1; //bit 30 + UINT32 tr64:1; //bit 31 + #endif + } bits; +} +MAC_STAT_REG_1_t, *PMAC_STAT_REG_1_t; + + +/****************************************************************************** + structure for Carry Register Two Mask Register reg in mac stat address map. + located at address 0x613C + *****************************************************************************/ +typedef union _MAC_STAT_REG_2_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:12; //bit 20-31 + UINT32 tjbr:1; //bit 19 + UINT32 tfcs:1; //bit 18 + UINT32 txcf:1; //bit 17 + UINT32 tovr:1; //bit 16 + UINT32 tund:1; //bit 15 + UINT32 tfrg:1; //bit 14 + UINT32 tbyt:1; //bit 13 + UINT32 tpkt:1; //bit 12 + UINT32 tmca:1; //bit 11 + UINT32 tbca:1; //bit 10 + UINT32 txpf:1; //bit 9 + UINT32 tdfr:1; //bit 8 + UINT32 tedf:1; //bit 7 + UINT32 tscl:1; //bit 6 + UINT32 tmcl:1; //bit 5 + UINT32 tlcl:1; //bit 4 + UINT32 txcl:1; //bit 3 + UINT32 tncl:1; //bit 2 + UINT32 tpfh:1; //bit 1 + UINT32 tdrp:1; //bit 0 + #else + UINT32 tdrp:1; //bit 0 + UINT32 tpfh:1; //bit 1 + UINT32 tncl:1; //bit 2 + UINT32 txcl:1; //bit 3 + UINT32 tlcl:1; //bit 4 + UINT32 tmcl:1; //bit 5 + UINT32 tscl:1; //bit 6 + UINT32 tedf:1; //bit 7 + UINT32 tdfr:1; //bit 8 + UINT32 txpf:1; //bit 9 + UINT32 tbca:1; //bit 10 + UINT32 tmca:1; //bit 11 + UINT32 tpkt:1; //bit 12 + UINT32 tbyt:1; //bit 13 + UINT32 tfrg:1; //bit 14 + UINT32 tund:1; //bit 15 + UINT32 tovr:1; //bit 16 + UINT32 txcf:1; //bit 17 + UINT32 tfcs:1; //bit 18 + UINT32 tjbr:1; //bit 19 + UINT32 unused:12; //bit 20-31 + #endif + } bits; +} +MAC_STAT_REG_2_t, *PMAC_STAT_REG_2_t; + + + + +/****************************************************************************** + MAC STATS Module of JAGCore Address Mapping + *****************************************************************************/ +typedef struct _MAC_STAT_t +{ //Location: + UINT32 pad[32]; // 0x6000 - 607C + + //Tx/Rx 0-64 Byte Frame Counter + UINT32 TR64; // 0x6080 + + //Tx/Rx 65-127 Byte Frame Counter + UINT32 TR127; // 0x6084 + + //Tx/Rx 128-255 Byte Frame Counter + UINT32 TR255; // 0x6088 + + //Tx/Rx 256-511 Byte Frame Counter + UINT32 TR511; // 0x608C + + //Tx/Rx 512-1023 Byte Frame Counter + UINT32 TR1K; // 0x6090 + + //Tx/Rx 1024-1518 Byte Frame Counter + UINT32 TRMax; // 0x6094 + + //Tx/Rx 1519-1522 Byte Good VLAN Frame Count + UINT32 TRMgv; // 0x6098 + + //Rx Byte Counter + UINT32 RByt; // 0x609C + + //Rx Packet Counter + UINT32 RPkt; // 0x60A0 + + //Rx FCS Error Counter + UINT32 RFcs; // 0x60A4 + + //Rx Multicast Packet Counter + UINT32 RMca; // 0x60A8 + + //Rx Broadcast Packet Counter + UINT32 RBca; // 0x60AC + + //Rx Control Frame Packet Counter + UINT32 RxCf; // 0x60B0 + + //Rx Pause Frame Packet Counter + UINT32 RxPf; // 0x60B4 + + //Rx Unknown OP Code Counter + UINT32 RxUo; // 0x60B8 + + //Rx Alignment Error Counter + UINT32 RAln; // 0x60BC + + //Rx Frame Length Error Counter + UINT32 RFlr; // 0x60C0 + + //Rx Code Error Counter + UINT32 RCde; // 0x60C4 + + //Rx Carrier Sense Error Counter + UINT32 RCse; // 0x60C8 + + //Rx Undersize Packet Counter + UINT32 RUnd; // 0x60CC + + //Rx Oversize Packet Counter + UINT32 ROvr; // 0x60D0 + + //Rx Fragment Counter + UINT32 RFrg; // 0x60D4 + + //Rx Jabber Counter + UINT32 RJbr; // 0x60D8 + + //Rx Drop + UINT32 RDrp; // 0x60DC + + //Tx Byte Counter + UINT32 TByt; // 0x60E0 + + //Tx Packet Counter + UINT32 TPkt; // 0x60E4 + + //Tx Multicast Packet Counter + UINT32 TMca; // 0x60E8 + + //Tx Broadcast Packet Counter + UINT32 TBca; // 0x60EC + + //Tx Pause Control Frame Counter + UINT32 TxPf; // 0x60F0 + + //Tx Deferral Packet Counter + UINT32 TDfr; // 0x60F4 + + //Tx Excessive Deferral Packet Counter + UINT32 TEdf; // 0x60F8 + + //Tx Single Collision Packet Counter + UINT32 TScl; // 0x60FC + + //Tx Multiple Collision Packet Counter + UINT32 TMcl; // 0x6100 + + //Tx Late Collision Packet Counter + UINT32 TLcl; // 0x6104 + + //Tx Excessive Collision Packet Counter + UINT32 TXcl; // 0x6108 + + //Tx Total Collision Packet Counter + UINT32 TNcl; // 0x610C + + //Tx Pause Frame Honored Counter + UINT32 TPfh; // 0x6110 + + //Tx Drop Frame Counter + UINT32 TDrp; // 0x6114 + + //Tx Jabber Frame Counter + UINT32 TJbr; // 0x6118 + + //Tx FCS Error Counter + UINT32 TFcs; // 0x611C + + //Tx Control Frame Counter + UINT32 TxCf; // 0x6120 + + //Tx Oversize Frame Counter + UINT32 TOvr; // 0x6124 + + //Tx Undersize Frame Counter + UINT32 TUnd; // 0x6128 + + //Tx Fragments Frame Counter + UINT32 TFrg; // 0x612C + + //Carry Register One Register + MAC_STAT_REG_1_t Carry1; // 0x6130 + + //Carry Register Two Register + MAC_STAT_REG_2_t Carry2; // 0x6134 + + //Carry Register One Mask Register + MAC_STAT_REG_1_t Carry1M; // 0x6138 + + //Carry Register Two Mask Register + MAC_STAT_REG_2_t Carry2M; // 0x613C +} +MAC_STAT_t, *PMAC_STAT_t; +/*===========================================================================*/ +/*===========================================================================*/ +/*=== END OF MAC STAT REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ + + + +/*===========================================================================*/ +/*===========================================================================*/ +/*=== START OF MMC REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ +/****************************************************************************** + structure for Main Memory Controller Control reg in mmc address map. + located at address 0x7000 + *****************************************************************************/ +typedef union _MMC_CTRL_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved:25; //bits 7-31 + UINT32 force_ce:1; //bit 6 + UINT32 rxdma_disable:1; //bit 5 + UINT32 txdma_disable:1; //bit 4 + UINT32 txmac_disable:1; //bit 3 + UINT32 rxmac_disable:1; //bit 2 + UINT32 arb_disable:1; //bit 1 + UINT32 mmc_enable:1; //bit 0 + #else + UINT32 mmc_enable:1; //bit 0 + UINT32 arb_disable:1; //bit 1 + UINT32 rxmac_disable:1; //bit 2 + UINT32 txmac_disable:1; //bit 3 + UINT32 txdma_disable:1; //bit 4 + UINT32 rxdma_disable:1; //bit 5 + UINT32 force_ce:1; //bit 6 + UINT32 reserved:25; //bits 7-31 + #endif + } bits; +} +MMC_CTRL_t, *PMMC_CTRL_t; + + +/****************************************************************************** + structure for Main Memory Controller Host Memory Access Address reg in mmc + address map. Located at address 0x7004 + *****************************************************************************/ +typedef union _MMC_SRAM_ACCESS_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 byte_enable:16; //bits 16-31 + UINT32 reserved2:2; //bits 14-15 + UINT32 req_addr:10; //bits 4-13 + UINT32 reserved1:1; //bit 3 + UINT32 is_ctrl_word:1; //bit 2 + UINT32 wr_access:1; //bit 1 + UINT32 req_access:1; //bit 0 + #else + UINT32 req_access:1; //bit 0 + UINT32 wr_access:1; //bit 1 + UINT32 is_ctrl_word:1; //bit 2 + UINT32 reserved1:1; //bit 3 + UINT32 req_addr:10; //bits 4-13 + UINT32 reserved2:2; //bits 14-15 + UINT32 byte_enable:16; //bits 16-31 + #endif + } bits; +} +MMC_SRAM_ACCESS_t, *PMMC_SRAM_ACCESS_t; + + +/****************************************************************************** + structure for Main Memory Controller Host Memory Access Data reg in mmc + address map. Located at address 0x7008 - 0x7014 + *****************************************************************************/ +typedef struct _MMC_SRAM_WORD_t +{ + UINT32 data; //bits 0-31 +} MMC_SRAM_WORD_t, *PMMC_SRAM_WORD_t; + + +/****************************************************************************** + Memory Control Module of JAGCore Address Mapping + *****************************************************************************/ +typedef struct _MMC_t +{ //Location: + MMC_CTRL_t mmc_ctrl; // 0x7000 + MMC_SRAM_ACCESS_t sram_access; // 0x7004 + MMC_SRAM_WORD_t sram_word1; // 0x7008 + MMC_SRAM_WORD_t sram_word2; // 0x700C + MMC_SRAM_WORD_t sram_word3; // 0x7010 + MMC_SRAM_WORD_t sram_word4; // 0x7014 +} +MMC_t, *PMMC_t; +/*===========================================================================*/ +/*===========================================================================*/ +/*=== END OF MMC REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ + + + +/*===========================================================================*/ +/*===========================================================================*/ +/*=== START OF EXP ROM REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ +/****************************************************************************** + Expansion ROM Module of JAGCore Address Mapping + *****************************************************************************/ + +/* Take this out until it is not empty */ +#if 0 +typedef struct _EXP_ROM_t +{ + +} +EXP_ROM_t, *PEXP_ROM_t; +#endif +/*===========================================================================*/ +/*===========================================================================*/ +/*=== END OF EXP ROM REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ + + + + +/****************************************************************************** + JAGCore Address Mapping + *****************************************************************************/ +typedef struct _ADDRESS_MAP_t +{ + GLOBAL_t global; + UCHAR unused_global[4096 - sizeof (GLOBAL_t)]; //unused section of global address map + TXDMA_t txdma; + UCHAR unused_txdma[4096 - sizeof (TXDMA_t)]; //unused section of txdma address map + RXDMA_t rxdma; + UCHAR unused_rxdma[4096 - sizeof (RXDMA_t)]; //unused section of rxdma address map + TXMAC_t txmac; + UCHAR unused_txmac[4096 - sizeof (TXMAC_t)]; //unused section of txmac address map + RXMAC_t rxmac; + UCHAR unused_rxmac[4096 - sizeof (RXMAC_t)]; //unused section of rxmac address map + MAC_t mac; + UCHAR unused_mac[4096 - sizeof (MAC_t)]; //unused section of mac address map + MAC_STAT_t macStat; + UCHAR unused_mac_stat[4096 - sizeof (MAC_STAT_t)]; //unused section of mac stat address map + MMC_t mmc; + UCHAR unused_mmc[4096 - sizeof (MMC_t)]; //unused section of mmc address map + UCHAR unused_[1015808]; //unused section of address map + +/* Take this out until it is not empty */ +#if 0 + EXP_ROM_t exp_rom; +#endif + + UCHAR unused_exp_rom[4096]; //MGS-size TBD + UCHAR unused__[524288]; //unused section of address map +} +ADDRESS_MAP_t, *PADDRESS_MAP_t; +/*===========================================================================*/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ET1310_ADDRESS_MAP_H_ */ --- linux-2.6.28.orig/ubuntu/et131x/ET1310_phy.c +++ linux-2.6.28/ubuntu/et131x/ET1310_phy.c @@ -0,0 +1,2728 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_phy.c - Routines for configuring and accessing the PHY + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2006/01/20 21:29:44 $ + $Revision: 1.13 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" +#include "et131x_netdev.h" +#include "et131x_initpci.h" + +#include "ET1310_address_map.h" +#include "ET1310_jagcore.h" +#include "ET1310_tx.h" +#include "ET1310_rx.h" +#include "ET1310_mac.h" + + + + +/****************************************************************************** + Data for debugging facilities + *****************************************************************************/ +#ifdef ET131X_DBG +extern dbg_info_t *et131x_dbginfo; +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + Prototypes for functions with local scope + *****************************************************************************/ +int et131x_xcvr_init( ET131X_ADAPTER *adapter ); + + + + +/****************************************************************************** + ROUTINE : MiRead + ****************************************************************************** + + DESCRIPTION : Used to read from the PHY through the MII Interface on + the MAC. + + PARAMETERS : adapter - pointer to our private adapter structure + xcvrAddr - the address of the transciever + xcvrReg - the register to read + value - pointer to a 16-bit value in which the value + will be stored. + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int MiRead( ET131X_ADAPTER *adapter, UINT8 xcvrAddr, UINT8 xcvrReg, UINT16 *value ) +{ + int status = 0; + UINT32 delay; + MII_MGMT_ADDR_t miiAddr; + MII_MGMT_CMD_t miiCmd; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "MiRead" ); + + + /************************************************************************** + Save a local copy of the registers we are dealing with so we can set + them back + *************************************************************************/ + miiAddr.value = adapter->CSRAddress->mac.mii_mgmt_addr.value; + miiCmd.value = adapter->CSRAddress->mac.mii_mgmt_cmd.value; + + + /************************************************************************** + Stop the current operation + *************************************************************************/ + adapter->CSRAddress->mac.mii_mgmt_cmd.value = 0x0; + + + /************************************************************************** + Set up the register we need to read from on the correct PHY + *************************************************************************/ + { + MII_MGMT_ADDR_t mii_mgmt_addr = {0}; + + mii_mgmt_addr.bits.phy_addr = xcvrAddr; + mii_mgmt_addr.bits.reg_addr = xcvrReg; + + adapter->CSRAddress->mac.mii_mgmt_addr = mii_mgmt_addr; + } + + + /************************************************************************** + Kick the read cycle off + *************************************************************************/ + delay = 0; + + adapter->CSRAddress->mac.mii_mgmt_cmd.value = 0x1; + + do + { + udelay( 50 ); + delay++; + } while(( adapter->CSRAddress->mac.mii_mgmt_indicator.bits.not_valid || + adapter->CSRAddress->mac.mii_mgmt_indicator.bits.busy ) && + ( delay < 50 )); + + + /************************************************************************** + If we hit the max delay, we could not read the register + *************************************************************************/ + if( delay >= 50 ) + { + DBG_WARNING( et131x_dbginfo, "xcvrReg 0x%08x could not be read\n", xcvrReg ); + DBG_WARNING( et131x_dbginfo, "status is 0x%08x\n", + adapter->CSRAddress->mac.mii_mgmt_indicator.value ); + + status = -EIO; + } + + + /************************************************************************** + If we hit here we were able to read the register and we need to return + the value to the caller + *************************************************************************/ + *value = (UINT16)adapter->CSRAddress->mac.mii_mgmt_stat.bits.phy_stat; + + + /************************************************************************** + Stop the read operation + *************************************************************************/ + adapter->CSRAddress->mac.mii_mgmt_cmd.value = 0x0; + + DBG_VERBOSE( et131x_dbginfo, " xcvr_addr = 0x%02x, " + "xcvr_reg = 0x%02x, " + "value = 0x%04x.\n", + xcvrAddr, xcvrReg, *value ); + + + /************************************************************************** + set the registers we touched back to the state at which we entered + this function + *************************************************************************/ + adapter->CSRAddress->mac.mii_mgmt_addr.value = miiAddr.value; + adapter->CSRAddress->mac.mii_mgmt_cmd.value = miiCmd.value; + + + return status; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : MiWrite + ****************************************************************************** + + DESCRIPTION : Used to write to a PHY register through the MII + interface of the MAC. Updated for the ET1310. + + PARAMETERS : adapter - pointer to our private adapter structure + xcvrAddr - the address of the transciever + xcvrReg - the register to read + value - 16-bit value to write + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int MiWrite( ET131X_ADAPTER *adapter, UINT8 xcvrAddr, UINT8 xcvrReg, UINT16 value ) +{ + int status = 0; + UINT32 delay; + MII_MGMT_ADDR_t miiAddr; + MII_MGMT_CMD_t miiCmd; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "MiWrite" ); + + + /************************************************************************** + Save a local copy of the registers we are dealing with so we can set + them back + *************************************************************************/ + miiAddr.value = adapter->CSRAddress->mac.mii_mgmt_addr.value; + miiCmd.value = adapter->CSRAddress->mac.mii_mgmt_cmd.value; + + + /************************************************************************** + Stop the current operation + *************************************************************************/ + adapter->CSRAddress->mac.mii_mgmt_cmd.value = 0x0; + + + /************************************************************************** + Set up the register we need to write to on the correct PHY + *************************************************************************/ + { + MII_MGMT_ADDR_t mii_mgmt_addr = {0}; + + mii_mgmt_addr.bits.phy_addr = xcvrAddr; + mii_mgmt_addr.bits.reg_addr = xcvrReg; + + adapter->CSRAddress->mac.mii_mgmt_addr = mii_mgmt_addr; + } + + + /************************************************************************** + Add the value to write to the registers to the mac + *************************************************************************/ + adapter->CSRAddress->mac.mii_mgmt_ctrl.value = value; + delay = 0; + + do + { + udelay( 50 ); + delay++; + } while(( adapter->CSRAddress->mac.mii_mgmt_indicator.bits.busy ) && + ( delay < 100 )); + + + /************************************************************************** + If we hit the max delay, we could not write the register + *************************************************************************/ + if( delay == 100 ) + { + UINT16 TempValue; + + DBG_WARNING( et131x_dbginfo, "xcvrReg 0x%08x could not be written", + xcvrReg ); + DBG_WARNING( et131x_dbginfo, "status is 0x%08x\n", + adapter->CSRAddress->mac.mii_mgmt_indicator.value ); + DBG_WARNING( et131x_dbginfo, "command is 0x%08x\n", + adapter->CSRAddress->mac.mii_mgmt_cmd.value ); + + MiRead( adapter, xcvrAddr, xcvrReg, &TempValue ); + + status = -EIO; + } + + + /************************************************************************** + Stop the write operation + *************************************************************************/ + adapter->CSRAddress->mac.mii_mgmt_cmd.value = 0x0; + + + /************************************************************************** + set the registers we touched back to the state at which we entered + this function + *************************************************************************/ + adapter->CSRAddress->mac.mii_mgmt_addr.value = miiAddr.value; + adapter->CSRAddress->mac.mii_mgmt_cmd.value = miiCmd.value; + + + DBG_VERBOSE( et131x_dbginfo, " xcvr_addr = 0x%02x, " + "xcvr_reg = 0x%02x, " + "value = 0x%04x.\n", + xcvrAddr, xcvrReg, value ); + + return status; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_xcvr_find + ****************************************************************************** + + DESCRIPTION : Used to find the PHY ID + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_xcvr_find( ET131X_ADAPTER *adapter ) +{ + int status = -ENODEV; + UINT8 xcvr_addr; + MI_IDR1_t idr1; + MI_IDR2_t idr2; + UINT32 xcvr_id; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_xcvr_find" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + We need to get xcvr id and address we just get the first one + *************************************************************************/ + for( xcvr_addr = 0; xcvr_addr < 32; xcvr_addr++ ) + { + /********************************************************************** + Read the ID from the PHY + *********************************************************************/ + MiRead( adapter, xcvr_addr, (UINT8)FIELD_OFFSET(MI_REGS_t, idr1), &idr1.value ); + MiRead( adapter, xcvr_addr, (UINT8)FIELD_OFFSET(MI_REGS_t, idr2), &idr2.value ); + + xcvr_id = (UINT32)(( idr1.value << 16 ) | idr2.value ); + + if(( idr1.value != 0) && ( idr1.value != 0xffff )) + { + DBG_TRACE( et131x_dbginfo, "Xcvr addr: 0x%02x\tXcvr_id: 0x%08x\n", + xcvr_addr, xcvr_id ); + + adapter->Stats.xcvr_id = xcvr_id; + adapter->Stats.xcvr_addr = (UINT32)xcvr_addr; + + status = 0; + break; + } + } + + + DBG_LEAVE( et131x_dbginfo ); + return status; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_setphy_normal + ****************************************************************************** + + DESCRIPTION : Used by Power Management to force the PHY into 10 Base T + half-duplex mode, when going to D3 in WOL mode. Also + used during initialization to set the PHY for normal + operation. + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_setphy_normal( ET131X_ADAPTER *adapter ) +{ + int status; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_setphy_normal" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Make sure the PHY is powered up + *************************************************************************/ + ET1310_PhyPowerDown( adapter, 0 ); + status = et131x_xcvr_init( adapter ); + + + DBG_LEAVE( et131x_dbginfo ); + return status; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_xcvr_init + ****************************************************************************** + + DESCRIPTION : Used to init the phy if we are setting it into force mode + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_xcvr_init( ET131X_ADAPTER *adapter ) +{ + int status = 0; + MI_IMR_t imr; + MI_ISR_t isr; + MI_LCR2_t lcr2; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_xcvr_init" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Zero out the adapter structure variable representing BMSR + *************************************************************************/ + adapter->Bmsr.value = 0; + + MiRead( adapter, (UINT8)adapter->Stats.xcvr_addr, + (UINT8)FIELD_OFFSET( MI_REGS_t, isr ), &isr.value ); + + MiRead( adapter, (UINT8)adapter->Stats.xcvr_addr, + (UINT8)FIELD_OFFSET( MI_REGS_t, imr ), &imr.value ); + + + /************************************************************************** + Set the link status interrupt only. Bad behavior when link status and + auto neg are set, we run into a nested interrupt problem + *************************************************************************/ + imr.bits.int_en = 0x1; + imr.bits.link_status = 0x1; + imr.bits.autoneg_status = 0x1; + + MiWrite( adapter, (UINT8)adapter->Stats.xcvr_addr, + (UINT8)FIELD_OFFSET( MI_REGS_t, imr ), imr.value ); + + + /************************************************************************** + Set the LED behavior such that LED 1 indicates speed (off = 10Mbits, + blink = 100Mbits, on = 1000Mbits) and LED 2 indicates link and + activity (on for link, blink off for activity). + + NOTE: Some customizations have been added here for specific vendors; + The LED behavior is now determined by vendor data in the EEPROM. However, + the above description is the default. + *************************************************************************/ + if(( adapter->eepromData[1] & 0x4 ) == 0 ) + { + MiRead( adapter, (UINT8)adapter->Stats.xcvr_addr, + (UINT8)FIELD_OFFSET( MI_REGS_t, lcr2 ), &lcr2.value ); + + if(( adapter->eepromData[1] & 0x8 ) == 0 ) + { + lcr2.bits.led_tx_rx = 0x3; + } + else + { + lcr2.bits.led_tx_rx = 0x4; + } + + lcr2.bits.led_link = 0xa; + + MiWrite( adapter, (UINT8)adapter->Stats.xcvr_addr, + (UINT8)FIELD_OFFSET( MI_REGS_t, lcr2 ), lcr2.value ); + } + + + /************************************************************************** + Determine if we need to go into a force mode and set it + *************************************************************************/ + if( adapter->AiForceSpeed == 0 && adapter->AiForceDpx == 0 ) + { + if(( adapter->RegistryFlowControl == TxOnly ) || + ( adapter->RegistryFlowControl == Both )) + { + ET1310_PhyAccessMiBit( adapter, + TRUEPHY_BIT_SET, 4, 11, NULL ); + } + else + { + ET1310_PhyAccessMiBit( adapter, + TRUEPHY_BIT_CLEAR, 4, 11, NULL ); + } + + if( adapter->RegistryFlowControl == Both ) + { + ET1310_PhyAccessMiBit( adapter, + TRUEPHY_BIT_SET, 4, 10, NULL ); + } + else + { + ET1310_PhyAccessMiBit( adapter, + TRUEPHY_BIT_CLEAR, 4, 10, NULL ); + } + + + /********************************************************************** + Set the phy to autonegotiation + *********************************************************************/ + ET1310_PhyAutoNeg( adapter, TRUE ); + + + /* NOTE - Do we need this? */ + ET1310_PhyAccessMiBit( adapter, + TRUEPHY_BIT_SET, 0, 9, NULL ); + + DBG_LEAVE( et131x_dbginfo ); + return status; + } + else + { + ET1310_PhyAutoNeg( adapter, FALSE ); + + /********************************************************************** + Set to the correct force mode. + *********************************************************************/ + if( adapter->AiForceDpx != 1 ) + { + if(( adapter->RegistryFlowControl == TxOnly ) || + ( adapter->RegistryFlowControl == Both )) + { + ET1310_PhyAccessMiBit( adapter, + TRUEPHY_BIT_SET, 4, 11, NULL ); + } + else + { + ET1310_PhyAccessMiBit( adapter, + TRUEPHY_BIT_CLEAR, 4, 11, NULL ); + } + + if( adapter->RegistryFlowControl == Both ) + { + ET1310_PhyAccessMiBit( adapter, + TRUEPHY_BIT_SET, 4, 10, NULL ); + } + else + { + ET1310_PhyAccessMiBit( adapter, + TRUEPHY_BIT_CLEAR, 4, 10, NULL ); + } + } + else + { + ET1310_PhyAccessMiBit( adapter, + TRUEPHY_BIT_CLEAR, 4, 10, NULL ); + ET1310_PhyAccessMiBit( adapter, + TRUEPHY_BIT_CLEAR, 4, 11, NULL ); + } + + switch( adapter->AiForceSpeed ) + { + case 10: + if( adapter->AiForceDpx == 1 ) + { + TPAL_SetPhy10HalfDuplex( adapter ); + } + else if( adapter->AiForceDpx == 2 ) + { + TPAL_SetPhy10FullDuplex( adapter ); + } + else + { + TPAL_SetPhy10Force( adapter ); + } + break; + + case 100: + if( adapter->AiForceDpx == 1 ) + { + TPAL_SetPhy100HalfDuplex( adapter ); + } + else if( adapter->AiForceDpx == 2 ) + { + TPAL_SetPhy100FullDuplex( adapter ); + } + else + { + TPAL_SetPhy100Force( adapter ); + } + break; + + case 1000: + TPAL_SetPhy1000FullDuplex( adapter ); + break; + } + + + DBG_LEAVE( et131x_dbginfo ); + return status; + } +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_Mii_check + ****************************************************************************** + + DESCRIPTION: + used to + + PARAMETERS : + pAdapter - pointer to our adapter + bmsr - + + RETURNS : + Nothing + + *****************************************************************************/ +void et131x_Mii_check( ET131X_ADAPTER *pAdapter, + MI_BMSR_t bmsr, + MI_BMSR_t bmsr_ints ) +{ + UCHAR ucLinkStatus; + INT32 nAutoNegStatus; + INT32 nSpeed; + INT32 nDuplex; + INT32 nMdiMdix; + INT32 nMasterSlave; + INT32 nPolarity; + unsigned long lockflags; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_Mii_check" ); + DBG_ENTER( et131x_dbginfo ); + + + if( bmsr_ints.bits.link_status ) + { + if( bmsr.bits.link_status ) + { + pAdapter->PoMgmt.TransPhyComaModeOnBoot = 20; + + + /****************************************************************** + Update our state variables and indicate the connected state + *****************************************************************/ + spin_lock_irqsave( &pAdapter->Lock, lockflags ); + + pAdapter->MediaState = NETIF_STATUS_MEDIA_CONNECT; + MP_CLEAR_FLAG( pAdapter, fMP_ADAPTER_LINK_DETECTION ); + + spin_unlock_irqrestore( &pAdapter->Lock, lockflags ); + + if( pAdapter->RegistryPhyLoopbk == FALSE ) + { + /************************************************************** + Don't indicate state if we're in loopback mode + *************************************************************/ + netif_indicate_status( pAdapter->netdev, pAdapter->MediaState ); + } + } + else + { + DBG_WARNING( et131x_dbginfo, "Link down cable problem\n" ); + + if( pAdapter->uiLinkSpeed == TRUEPHY_SPEED_10MBPS ) + { + // NOTE - Is there a way to query this without TruePHY? + //if( TRU_QueryCoreType ( pAdapter->hTruePhy, 0 ) == EMI_TRUEPHY_A13O ) + { + UINT16 Register18; + + MiRead( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + 0x12, &Register18 ); + MiWrite( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + 0x12, Register18 | 0x4 ); + MiWrite( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + 0x10, Register18 | 0x8402 ); + MiWrite( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + 0x11, Register18 | 511 ); + MiWrite( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + 0x12, Register18 ); + } + } + + /****************************************************************** + For the first N seconds of life, we are in "link detection" + When we are in this state, we should only report "connected". + When the LinkDetection Timer expires, we can report + disconnected (handled in the LinkDetectionDPC). + *****************************************************************/ + if(( MP_IS_FLAG_CLEAR( pAdapter, fMP_ADAPTER_LINK_DETECTION )) || + ( pAdapter->MediaState == NETIF_STATUS_MEDIA_DISCONNECT )) + { + spin_lock_irqsave( &pAdapter->Lock, lockflags ); + pAdapter->MediaState = NETIF_STATUS_MEDIA_DISCONNECT; + spin_unlock_irqrestore( &pAdapter->Lock, lockflags ); + + /************************************************************** + Only indicate state if we're in loopback mode + *************************************************************/ + if( pAdapter->RegistryPhyLoopbk == FALSE ) + { + netif_indicate_status( pAdapter->netdev, pAdapter->MediaState ); + } + } + + pAdapter->uiLinkSpeed = 0; + pAdapter->uiDuplexMode = 0; + + + /****************************************************************** + Free the packets being actively sent & stopped + *****************************************************************/ + et131x_free_busy_send_packets( pAdapter ); + + + /****************************************************************** + Re-initialize the send structures + *****************************************************************/ + et131x_init_send( pAdapter ); + + + /****************************************************************** + Reset the RFD list and re-start RU + *****************************************************************/ + et131x_reset_recv( pAdapter ); + + + /****************************************************************** + Bring the device back to the state it was during init prior + to autonegotiation being complete. This way, when we get the + auto-neg complete interrupt, we can complete init by calling + ConfigMacREGS2. + *****************************************************************/ + et131x_soft_reset( pAdapter ); + + + /****************************************************************** + Setup ET1310 as per the documentation + *****************************************************************/ + et131x_adapter_setup( pAdapter ); + + + /****************************************************************** + Setup the PHY into coma mode until the cable is plugged back in + *****************************************************************/ + if( pAdapter->RegistryPhyComa == 1 ) + { + EnablePhyComa( pAdapter ); + } + } + } + + if( bmsr_ints.bits.auto_neg_complete || + (( pAdapter->AiForceDpx == 3 ) && ( bmsr_ints.bits.link_status ))) + { + if( bmsr.bits.auto_neg_complete || + ( pAdapter->AiForceDpx == 3 )) + { + ET1310_PhyLinkStatus( pAdapter, + &ucLinkStatus, + &nAutoNegStatus, + &nSpeed, + &nDuplex, + &nMdiMdix, + &nMasterSlave, + &nPolarity ); + + + pAdapter->uiLinkSpeed = nSpeed; + pAdapter->uiDuplexMode = nDuplex; + + DBG_TRACE( et131x_dbginfo, + "pAdapter->uiLinkSpeed 0x%04x, pAdapter->uiDuplex 0x%08x\n", + pAdapter->uiLinkSpeed, pAdapter->uiDuplexMode ); + + pAdapter->PoMgmt.TransPhyComaModeOnBoot = 20; + + if( pAdapter->uiLinkSpeed == TRUEPHY_SPEED_10MBPS ) + { + // NOTE - Is there a way to query this without TruePHY? + //if( TRU_QueryCoreType ( pAdapter->hTruePhy, 0 ) == EMI_TRUEPHY_A13O ) + { + UINT16 Register18; + + MiRead( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + 0x12, &Register18 ); + MiWrite( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + 0x12, Register18 | 0x4 ); + MiWrite( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + 0x10, Register18 | 0x8402 ); + MiWrite( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + 0x11, Register18 | 511 ); + MiWrite( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + 0x12, Register18 ); + } + } + + ConfigFlowControl( pAdapter ); + + + if(( pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS ) && + ( pAdapter->RegistryJumboPacket > 2048 )) + + { + ET1310_PhyAndOrReg( pAdapter, 0x16, 0xcfff, 0x2000 ); + } + + SetRxDmaTimer( pAdapter ); + ConfigMACRegs2( pAdapter ); + } + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : TPAL_MiAccessRegs + ****************************************************************************** + + DESCRIPTION : Used to perform a single or series of MI Register + transactions on the specified PHY + + PARAMETERS : hPlatform - handle to platform resources + nPhyId - logical PHY ID (if >= 0) or + logical PHY group ID (if <0) + pbyAccessFlags - Pointer to a list of flags, which + specify the transaction type associated + with each register contained in the + 'pbyRegisters' array. Valid values: + TRUEPHY_READ + TRUEPHY_WRITE + TRUEPHY_MASK + If a logical PHY Group ID is specified + in 'nPhyId', the value of these flags + must be TRUEPHY_WRITE + pbyRegisters - Pointer to a list of MI registers + addressess (0-31), one of each register + specified by 'nRegCount' + pwData - Pointer to a buffer that contains the + data required by or resulting from each + transaction, the contents of which are + dependent upon the 'pbyAccessFlags' + parameter. Specifically: + + If 'pbyAccessFlags[i]' is TRUEPHY_READ, + the contents of the register specified + by 'pbyRegisters[i]' is read and stored + in 'pwData[i]'. + + If 'pbyAccessFlags[i]' is TRUEPHY_WRITE, + the contents of 'pwData[i]' is written + to the register specified by + 'pbyRegisters[i]'. + + If 'pbyAccessFlags[i]' is TRUEPHY_MASK, + the contents of the register specified + by 'pbyRegisters[i]' is read and stored + in 'pwData [i]', which is then + logically AND'ed with the contents of + 'pwAndMasks[i]' and logically OR'ed + with the contents of 'pwOrMasks[i]' + before it is written back to the + register specified by 'pbyRegisters[i]' + + This allows the calling function to + interleave a register read, logical + and/or, and write operation within a + single transaction. + + pwAndMasks - Pointer to buffer containing AND masks, + which is required if the corresponding + transaction type is TRUEPHY_MASK; + otherwise, this parameter is ignored. + pwOrMasks - Pointer to buffer containing OR masks, + which is required if the corresponding + transaction type is TRUEPHY_MASK; + otherwise, this parameter is ignored. + nRegCount - Specifies the number of register + transactions to be performed. + + RETURNS : TRUEPHY_SUCCESS + TRUEPHY_FAILURE + + REUSE INFORMATION : + + *****************************************************************************/ +INT32 TPAL_MiAccessRegs( TPAL_HANDLE hPlatform, + INT32 nPhyId, + PUCHAR pbyAccessFlags, + PUCHAR pbyRegisters, + PUINT16 pwData, + PUINT16 pwAndMasks, + PUINT16 pwOrMasks, + INT32 nRegCount ) +{ + INT32 nStatus = TRUEPHY_FAILURE; + INT32 index; + INT16 wTemp; + UINT8 xcvrAddr; + ET131X_ADAPTER *pAdapter = hPlatform; + unsigned long lockflags; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "TPAL_MiAccessRegs" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Validate Input parameters. We are not worried about nPhyId because we + can only access the one we control + *************************************************************************/ + if( pbyAccessFlags != NULL && pwData != NULL ) + { + /********************************************************************** + Convert nPhyId into a PHY physical address(nPhyAddress) + *********************************************************************/ + + + /********************************************************************** + Convert nPhyId into a MI bus address (nBusAddress). + + NOTE: This is only needed for platforms that support multiple MI + buses + *********************************************************************/ + + + /********************************************************************** + Get the xcvr addr for all transactions to go to + *********************************************************************/ + xcvrAddr = (UINT8)pAdapter->Stats.xcvr_addr; + + + /********************************************************************** + Go through all registers performing specific transaction indicated + in the corresponding pbyAccessFlags array. + *********************************************************************/ + for( index = 0; index < nRegCount; index++ ) + { + /****************************************************************** + Validate MI register + *****************************************************************/ + if( pbyRegisters[index] > 31 ) + { + break; + } + + + /****************************************************************** + Is this a read? + *****************************************************************/ + if( pbyAccessFlags[index] == TRUEPHY_READ ) + { + /************************************************************** + Group reads are not allowed + *************************************************************/ + if( nPhyId < 0 ) + { + break; + } + + + /************************************************************** + Make sure we acquire the spin lock + *************************************************************/ + spin_lock_irqsave( &pAdapter->PHYLock, lockflags ); + + + /************************************************************** + Let's perform the read operation + *************************************************************/ + MiRead( pAdapter, xcvrAddr, pbyRegisters[index], + (PUINT16)&pwData[index] ); + + spin_unlock_irqrestore( &pAdapter->PHYLock, lockflags ); + + } + else if( pbyAccessFlags[index] == TRUEPHY_WRITE ) + { + /************************************************************** + Make sure we acquire the spin lock + *************************************************************/ + spin_lock_irqsave( &pAdapter->PHYLock, lockflags ); + + + /************************************************************** + Let's perform the write operation + *************************************************************/ + MiWrite( pAdapter, xcvrAddr, pbyRegisters[index], + (UINT16)pwData[index] ); + + spin_unlock_irqrestore( &pAdapter->PHYLock, lockflags ); + } + else if( pbyAccessFlags[index] == TRUEPHY_MASK ) + { + /************************************************************** + Group masks are not allowed + *************************************************************/ + if( nPhyId < 0 ) + { + break; + } + + /************************************************************** + Pointer to AND and OR masks must not be NULL + *************************************************************/ + if(( pwOrMasks == NULL ) || ( pwAndMasks == NULL )) + { + break; + } + + /************************************************************** + Make sure we acquire the spin lock + *************************************************************/ + spin_lock_irqsave( &pAdapter->PHYLock, lockflags ); + + + /************************************************************** + Perform read + *************************************************************/ + MiRead( pAdapter, xcvrAddr, pbyRegisters[index], + (PUINT16)&pwData[index] ); + + + /************************************************************** + Perform and/or masks and write it back + *************************************************************/ + wTemp = (( pwData[index] & pwAndMasks[index] ) | + pwOrMasks[index] ); + + MiWrite( pAdapter, xcvrAddr, pbyRegisters[index], + (UINT16)wTemp ); + + spin_unlock_irqrestore( &pAdapter->PHYLock, lockflags ); + } + else + { + /************************************************************** + Invalid transaction type, just break out of the loop + *************************************************************/ + break; + } + }//end for loop + + /********************************************************************** + If we completed all the transactions, indicate success + *********************************************************************/ + if( index == nRegCount ) + { + nStatus = TRUEPHY_SUCCESS; + } + }//end if + + + DBG_LEAVE( et131x_dbginfo ); + return nStatus; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : TPAL_PlatformExit + ****************************************************************************** + + DESCRIPTION : Used to exit the TRUEPHY library which will de-allocate + any system resources allocated. + + PARAMETERS : hPlatform - handle to the platform resources + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ + +void TPAL_PlatformExit( TRUEPHY_OSAL_HANDLE hPlatform ) +{ + DBG_FUNC( "TPAL_PlatformExit" ); + DBG_ENTER( et131x_dbginfo ); + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + +/////////////////////////////////////////////////////////////////////////////// +//// OS Specific Functions //// +/////////////////////////////////////////////////////////////////////////////// +/****************************************************************************** + ROUTINE : TPAL_AllocMem + ****************************************************************************** + + DESCRIPTION : Used so the TRUEPHY library can allocate memory + + PARAMETERS : ulNumBytes - number of bytes to allocate + + RETURNS : pointer to allocated memory block on success, or + NULL on failure + + REUSE INFORMATION : + + *****************************************************************************/ +void * TPAL_AllocMem( TRUEPHY_OSAL_HANDLE hPlatform, u_long ulNumBytes ) +{ + void *pBuffer = NULL; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "TPAL_AllocMem" ); + DBG_ENTER( et131x_dbginfo ); + + + pBuffer = kmalloc( ulNumBytes, GFP_ATOMIC ); + + + DBG_LEAVE( et131x_dbginfo ); + return pBuffer; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : TPAL_FreeMem + ****************************************************************************** + + DESCRIPTION : Used to free a previously allocated block of memory + + PARAMETERS : pMemBlock - the pointer to the buffer to free + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void TPAL_FreeMem( TRUEPHY_OSAL_HANDLE hPlatform, void *pMemBlock ) +{ + DBG_FUNC( "TPAL_FreeMem" ); + DBG_ENTER( et131x_dbginfo ); + + + kfree( pMemBlock ); + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: TPAL_Sleep + ****************************************************************************** + + DESCRIPTION: + Used to delay execution for a specified number of milliseconds + + PARAMETERS : + ulMsec - Number of milliseconds to delay. This parameter can be zero + + RETURNS : + NONE + + *****************************************************************************/ +void TPAL_Sleep( TRUEPHY_OSAL_HANDLE hPlatform, u_long ulMsec ) +{ + DBG_FUNC( "TPAL_Sleep" ); + DBG_ENTER( et131x_dbginfo ); + + + mdelay( ulMsec ); + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: TPAL_GetSystemUpTime + ****************************************************************************** + + DESCRIPTION: + Used to get the numberr of milliseconds that have elapsed since the + system was started + + PARAMETERS : + NONE + + RETURNS : + number of milliseconds since system was started + + *****************************************************************************/ +u_long TPAL_GetSystemUpTime( TRUEPHY_OSAL_HANDLE hPlatform ) +{ + UINT32 uptime; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "TPAL_GetSystemUpTime" ); + DBG_ENTER( et131x_dbginfo ); + + + uptime = 10 * jiffies / HZ; + + + DBG_LEAVE( et131x_dbginfo ); + return uptime; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: TPAL_GetLinkStatusInfo + ****************************************************************************** + + DESCRIPTION: + used to determine what link speed and duplex the phy is set to + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void TPAL_GetLinkStatusInfo( ET131X_ADAPTER *pAdapter ) +{ + UINT32 index = 0; + INT32 MdiMdix; + INT32 MasterSlave; + INT32 Polarity; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "TPAL_GetLinkStatusInfo" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Get the link status information from the phy. Loop until the + autonegstatus is complete or link status is up. + + If looping for 50 uSec, break out, we have a problem + *************************************************************************/ + do + { + ET1310_PhyLinkStatus( pAdapter, + &pAdapter->ucLinkStatus, + &pAdapter->uiAutoNegStatus, + &pAdapter->uiLinkSpeed, + &pAdapter->uiDuplexMode, + &MdiMdix, + &MasterSlave, + &Polarity ); + + DBG_VERBOSE( et131x_dbginfo, + "uiAutoNegStatus 0x%08x ucLinkStatus 0x%04x\n " + "uiLinkSpeed 0x%04x, uiDuplexMode 0x%08x\n", + pAdapter->uiAutoNegStatus, + pAdapter->ucLinkStatus, + pAdapter->uiLinkSpeed, + pAdapter->uiDuplexMode ); + + udelay( 100 ); + index++; + + if( index == 10000 ) + { + /****************************************************************** + We hit our limit, we need to set a variable so during power + management we know to try 100/half + *****************************************************************/ + pAdapter->PoMgmt.Failed10Half = TRUE; + break; + } + } while( pAdapter->uiAutoNegStatus != TRUEPHY_ANEG_COMPLETE || + pAdapter->ucLinkStatus == 0 ); + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: TPAL_SetPhy10HalfDuplex + ****************************************************************************** + + DESCRIPTION: + Used to force the phy into 10 Base T Half Duplex mode. Also sets the + MAC so it is syncd up properly + + PARAMETERS : + pAdapter - pointer to the adapter structure + + RETURNS : + TRUEPHY_SUCCESS - if everything goes according to plan + TRUEPHY_FALIURE -if something goes wrong + + *****************************************************************************/ +INT32 TPAL_SetPhy10HalfDuplex( ET131X_ADAPTER *pAdapter ) +{ + INT32 returnValue = TRUEPHY_SUCCESS; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "TPAL_SetPhy10HalfDuplex" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Power down PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 1 ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not power down the PHY\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + /************************************************************************** + First we need to turn off all other advertisement + *************************************************************************/ + ET1310_PhyAdvertise1000BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not turn off advertisement of 1000 BaseT\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + ET1310_PhyAdvertise100BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not turn off advertisement of 100 BaseT " + "for forcing 10 BaseT Half Duplex\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + Set our advertise values accordingly + *************************************************************************/ + ET1310_PhyAdvertise10BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_HALF ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not set Advertise of 10 Half\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + /************************************************************************** + Power up PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 0 ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not power up the PHY\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + DBG_LEAVE( et131x_dbginfo ); + return returnValue ; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: TPAL_SetPhy10FullDuplex + ****************************************************************************** + + DESCRIPTION: + Used to force the phy into 10 Base T Full Duplex mode. Also sets the + MAC so it is syncd up properly + + PARAMETERS : + pAdapter - pointer to the adapter structure + + RETURNS : + TRUEPHY_SUCCESS - if everything goes according to plan + TRUEPHY_FALIURE -if somethign goes wrong during the procedures + + *****************************************************************************/ +INT32 TPAL_SetPhy10FullDuplex( ET131X_ADAPTER *pAdapter ) +{ + INT32 returnValue = TRUEPHY_SUCCESS; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "TPAL_SetPhy10FullDuplex" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Power down PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 1 ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not power down the PHY\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + First we need to turn off all other advertisement + *************************************************************************/ + ET1310_PhyAdvertise1000BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not turn off advertisement of 1000 BaseT " + "for Forcing 10 BaseT Full Duplex\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + ET1310_PhyAdvertise100BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not turn off advertisement of 100 BaseT " + "for Forcing 10 BaseT Full Duplex\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + Set our advertise values accordingly + *************************************************************************/ + ET1310_PhyAdvertise10BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_FULL ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not set Advertise of 10 Full\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + Power up PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 0 ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not power up the phy\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + DBG_LEAVE( et131x_dbginfo ); + return returnValue; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: TPAL_SetPhy10Force + ****************************************************************************** + + DESCRIPTION: + Used to force the phy into 10 Base T Full Duplex mode WITHOUT using + autonegotiation. + + PARAMETERS : + pAdapter - pointer to the adapter structure + + RETURNS : + + *****************************************************************************/ +void TPAL_SetPhy10Force( ET131X_ADAPTER *pAdapter ) +{ + DBG_FUNC( "TPAL_SetPhy10Force" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Power down PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 1 ); + + + /************************************************************************** + Disable autoneg + *************************************************************************/ + ET1310_PhyAutoNeg( pAdapter, FALSE ); + + + /************************************************************************** + Disable all advertisement + *************************************************************************/ + ET1310_PhyAdvertise1000BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + ET1310_PhyAdvertise10BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + ET1310_PhyAdvertise100BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + + /************************************************************************** + Force 10 Mbps + *************************************************************************/ + ET1310_PhySpeedSelect( pAdapter, TRUEPHY_SPEED_10MBPS ); + + + /************************************************************************** + Force Full duplex + *************************************************************************/ + ET1310_PhyDuplexMode( pAdapter, TRUEPHY_DUPLEX_FULL ); + + + /************************************************************************** + Power up PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 0 ); + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: TPAL_SetPhy100HalfDuplex + ****************************************************************************** + + DESCRIPTION: + Used to force the phy into 100 Base T Half Duplex mode. Also sets the + MAC so it is syncd up properly + + PARAMETERS : + pAdapter - pointer to the adapter structure + + RETURNS : + TRUEPHY_SUCCESS - if everything goes according to plan + TRUEPHY_FALIURE -if somethign goes wrong during the procedures + + *****************************************************************************/ +INT32 TPAL_SetPhy100HalfDuplex( ET131X_ADAPTER *pAdapter ) +{ + INT32 returnValue = TRUEPHY_SUCCESS; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "TPAL_SetPhy100HalfDuplex" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Power down PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 1 ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + + DBG_ERROR( et131x_dbginfo, "Could not power down the PHY\n" ); + DBG_LEAVE( et131x_dbginfo ); + return( returnValue ); + } + + + /************************************************************************** + first we need to turn off all other advertisement + *************************************************************************/ + ET1310_PhyAdvertise1000BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not turn off advertisement of 1000 BaseT " + "for Forcing 100 BaseT Half Duplex\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + ET1310_PhyAdvertise10BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not turn off advertisement of 10 BaseT " + "for Forcing 100 BaseT Half Duplex\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + Set our advertise values accordingly + *************************************************************************/ + ET1310_PhyAdvertise100BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_HALF ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not set Advertise of 100 Half\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /* Set speed */ + ET1310_PhySpeedSelect( pAdapter, TRUEPHY_SPEED_100MBPS ); + + + /************************************************************************** + Power up PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 0 ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not power up the PHY\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + DBG_LEAVE( et131x_dbginfo ); + return returnValue; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: TPAL_SetPhy100FullDuplex + ****************************************************************************** + + DESCRIPTION: + Used to force the phy into 100 Base T Full Duplex mode. Also sets the + MAC so it is syncd up properly + + PARAMETERS : + pAdapter - pointer to the adapter structure + + RETURNS : + TRUEPHY_SUCCESS - if everything goes according to plan + TRUEPHY_FALIURE -if somethign goes wrong during the procedures + + *****************************************************************************/ +INT32 TPAL_SetPhy100FullDuplex( ET131X_ADAPTER *pAdapter ) +{ + INT32 returnValue = TRUEPHY_SUCCESS; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "TPAL_SetPhy100FullDuplex" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Power down PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 1 ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not power down PHY\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + First we need to turn off all other advertisement + *************************************************************************/ + ET1310_PhyAdvertise1000BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not turn off advertisement of 1000 BaseT " + "for Forcing 100 BaseT Full Duplex\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + ET1310_PhyAdvertise10BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not turn off advertisement of 10 BaseT " + "for Forcing 100 BaseT Full Duplex\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + Set our advertise values accordingly + *************************************************************************/ + ET1310_PhyAdvertise100BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_FULL ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not set Advertise of 100 Full\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + Power up PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 0 ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not power up PHY\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + DBG_LEAVE( et131x_dbginfo ); + return returnValue; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: TPAL_SetPhy100Force + ****************************************************************************** + + DESCRIPTION: + Used to force the phy into 100 Base T Full Duplex mode WITHOUT using + autonegotiation. + + PARAMETERS : + pAdapter - pointer to the adapter structure + + RETURNS : + + *****************************************************************************/ +void TPAL_SetPhy100Force( ET131X_ADAPTER *pAdapter ) +{ + DBG_FUNC( "TPAL_SetPhy100Force" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Power down PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 1 ); + + + /************************************************************************** + Disable autoneg + *************************************************************************/ + ET1310_PhyAutoNeg( pAdapter, FALSE ); + + + /************************************************************************** + Disable all advertisement + *************************************************************************/ + ET1310_PhyAdvertise1000BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + + ET1310_PhyAdvertise10BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + + ET1310_PhyAdvertise100BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + + /************************************************************************** + Force 100 Mbps + *************************************************************************/ + ET1310_PhySpeedSelect( pAdapter, TRUEPHY_SPEED_100MBPS ); + + + /************************************************************************** + Force Full duplex + *************************************************************************/ + ET1310_PhyDuplexMode( pAdapter, TRUEPHY_DUPLEX_FULL ); + + + /************************************************************************** + Power up PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 0 ); + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: TPAL_SetPhy1000FullDuplex + ****************************************************************************** + + DESCRIPTION: + Used to force the phy into 1000 Base T Full Duplex mode. Also sets the + MAC so it is syncd up properly + + PARAMETERS : + pAdapter - pointer to the adapter structure + + RETURNS : + TRUEPHY_SUCCESS - if everything goes according to plan + TRUEPHY_FALIURE -if somethign goes wrong during the procedures + + *****************************************************************************/ +INT32 TPAL_SetPhy1000FullDuplex( ET131X_ADAPTER *pAdapter ) +{ + INT32 returnValue = TRUEPHY_SUCCESS; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "TPAL_SetPhy1000FullDuplex" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Power down PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 1 ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not power down phy\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + first we need to turn off all other advertisement + *************************************************************************/ + ET1310_PhyAdvertise100BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not turn off advertisement of 100 BaseT " + "for Forcing 1000 BaseT Full Duplex\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + ET1310_PhyAdvertise10BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not turn off advertisement of 10 BaseT " + "for Forcing 1000 BaseT Full Duplex\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + set our advertise values accordingly + *************************************************************************/ + ET1310_PhyAdvertise1000BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_FULL ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not set Advertise of 1000 Full\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + power up PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 0 ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not power up PHY\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + DBG_LEAVE( et131x_dbginfo ); + return returnValue; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: TPAL_SetPhyAutoNeg + ****************************************************************************** + + DESCRIPTION: + Used to set phy to autonegotiation mode. + + PARAMETERS : + pAdapter - pointer to the adapter structure + + RETURNS : + TRUEPHY_SUCCESS - if everything goes according to plan + TRUEPHY_FALIURE -if somethign goes wrong during the procedures + + *****************************************************************************/ +INT32 TPAL_SetPhyAutoNeg( ET131X_ADAPTER *pAdapter ) +{ + INT32 returnValue = TRUEPHY_SUCCESS; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "TPAL_SetPhyAutoNeg" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Power down PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 1 ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not power down phy\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + Turn on advertisement of all capabilities + *************************************************************************/ + ET1310_PhyAdvertise10BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_BOTH ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not Turn on Advertisement of 10 BaseT " + "from Setting to Auto Negotiation\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + ET1310_PhyAdvertise100BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_BOTH ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not Turn on Advertisement of 100 BaseT " + "from Setting to Auto Negotiation\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + if( pAdapter->DeviceID != ET131X_PCI_DEVICE_ID_FAST ) + { + ET1310_PhyAdvertise1000BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_FULL ); + } + else + { + ET1310_PhyAdvertise1000BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + } + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not Turn on Advertisement of 1000 BaseT " + "from Setting to Auto Negotiation\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + Make sure auto-neg is ON (it is disabled in FORCE modes) + *************************************************************************/ + ET1310_PhyAutoNeg( pAdapter, TRUE ); + + + /************************************************************************** + Power up PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 0 ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not power up phy\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + DBG_LEAVE( et131x_dbginfo ); + return returnValue; +} +/*===========================================================================*/ + + + + +/****************************************************************************** +******************************************************************************* + + The routines which follow provide low-level access to the PHY, and are used + primarily by the routines above (although there are a few places elsewhere in + the driver where this level of access is required). + +******************************************************************************* +******************************************************************************/ + +static UINT16 ConfigPhy[25][2] = +{ + /* Reg Value Register */ + /* Addr */ + {0x880B, 0x0926}, /* AfeIfCreg4B1000Msbs */ + {0x880C, 0x0926}, /* AfeIfCreg4B100Msbs */ + {0x880D, 0x0926}, /* AfeIfCreg4B10Msbs */ + + {0x880E, 0xB4D3}, /* AfeIfCreg4B1000Lsbs */ + {0x880F, 0xB4D3}, /* AfeIfCreg4B100Lsbs */ + {0x8810, 0xB4D3}, /* AfeIfCreg4B10Lsbs */ + + {0x8805, 0xB03E}, /* AfeIfCreg3B1000Msbs */ + {0x8806, 0xB03E}, /* AfeIfCreg3B100Msbs */ + {0x8807, 0xFF00}, /* AfeIfCreg3B10Msbs */ + + {0x8808, 0xE090}, /* AfeIfCreg3B1000Lsbs */ + {0x8809, 0xE110}, /* AfeIfCreg3B100Lsbs */ + {0x880A, 0x0000}, /* AfeIfCreg3B10Lsbs */ + + {0x300D, 1 }, /* DisableNorm */ + + {0x280C, 0x0180}, /* LinkHoldEnd */ + + {0x1C21, 0x0002}, /* AlphaM */ + + {0x3821, 6 }, /* FfeLkgTx0 */ + {0x381D, 1 }, /* FfeLkg1g4 */ + {0x381E, 1 }, /* FfeLkg1g5 */ + {0x381F, 1 }, /* FfeLkg1g6 */ + {0x3820, 1 }, /* FfeLkg1g7 */ + + {0x8402, 0x01F0}, /* Btinact */ + {0x800E, 20 }, /* LftrainTime */ + {0x800F, 24 }, /* DvguardTime */ + {0x8010, 46 }, /* IdlguardTime */ + + {0, 0 } + +}; +// +// condensed version of the phy initialization routine +// +void ET1310_PhyInit( ET131X_ADAPTER *pAdapter ) +{ + UINT16 usData, usIndex; + + + if( pAdapter == NULL ) + { + return; + } + + + // get the identity (again ?) + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_ID_1, &usData ); + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_ID_2, &usData ); + + // what does this do/achieve ? + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_MPHY_CONTROL_REG, &usData ); // should read 0002 + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_MPHY_CONTROL_REG, 0x0006 ); + + // read modem register 0402, should I do something with the return data ? + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_INDEX_REG, 0x0402 ); + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_DATA_REG, &usData ); + + // what does this do/achieve ? + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_MPHY_CONTROL_REG, 0x0002 ); + + // get the identity (again ?) + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_ID_1, &usData ); + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_ID_2, &usData ); + + // what does this achieve ? + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_MPHY_CONTROL_REG, &usData ); // should read 0002 + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_MPHY_CONTROL_REG, 0x0006 ); + + // read modem register 0402, should I do something with the return data ? + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_INDEX_REG, 0x0402 ); + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_DATA_REG, &usData ); + + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_MPHY_CONTROL_REG, 0x0002 ); + + // what does this achieve (should return 0x1040) + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, &usData ); + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_MPHY_CONTROL_REG, &usData ); // should read 0002 + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, 0x1840 ); + + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_MPHY_CONTROL_REG, 0x0007 ); + + // here the writing of the array starts.... + usIndex = 0; + while( ConfigPhy[usIndex][0] != 0x0000 ) + { + // write value + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_INDEX_REG, ConfigPhy[usIndex][0] ); + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_DATA_REG, ConfigPhy[usIndex][1] ); + + // read it back + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_INDEX_REG, ConfigPhy[usIndex][0] ); + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_DATA_REG, &usData ); + + // do a check on the value read back ? + usIndex++; + } + // here the writing of the array ends... + + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, &usData ); // 0x1840 + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_MPHY_CONTROL_REG, &usData ); // should read 0007 + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, 0x1040 ); + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_MPHY_CONTROL_REG, 0x0002 ); + + return; + +} + + + + +void ET1310_PhyReset( ET131X_ADAPTER *pAdapter ) +{ + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, 0x8000 ); + return; +} + + + + +void ET1310_PhyPowerDown( ET131X_ADAPTER *pAdapter, BOOL_t down ) +{ + UINT16 usData; + + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, &usData ); + + if( down == FALSE ) + { + // Power UP + usData &= ~0x0800; + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, usData ); + } + else + { + // Power DOWN + usData |= 0x0800; + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, usData ); + } + + return; +} + + +void ET1310_PhyAutoNeg( ET131X_ADAPTER *pAdapter, BOOL_t enable ) +{ + UINT16 usData; + + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, &usData ); + + if( enable == TRUE ) + { + // Autonegotiation ON + usData |= 0x1000; + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, usData ); + } + else + { + // Autonegotiation OFF + usData &= ~0x1000; + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, usData ); + } + + return; +} + +void ET1310_PhyDuplexMode( ET131X_ADAPTER *pAdapter, UINT16 duplex ) +{ + UINT16 usData; + + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, &usData ); + + if( duplex == TRUEPHY_DUPLEX_FULL ) + { + // Set Full Duplex + usData |= 0x100; + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, usData ); + } + else + { + // Set Half Duplex + usData &= ~0x100; + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, usData ); + } + + return; +} + + +void ET1310_PhySpeedSelect( ET131X_ADAPTER *pAdapter, UINT16 speed ) +{ + UINT16 usData; + + // Read the PHY control register + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, &usData ); + + // Clear all Speed settings (Bits 6, 13) + usData &= ~0x2040; + + // Reset the speed bits based on user selection + switch( speed ) + { + case TRUEPHY_SPEED_10MBPS: + // Bits already cleared above, do nothing + break; + + case TRUEPHY_SPEED_100MBPS: + // 100M == Set bit 13 + usData |= 0x2000; + break; + + case TRUEPHY_SPEED_1000MBPS: + default: + usData |= 0x0040; + break; + } + + // Write back the new speed + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, usData ); + + return; +} + + +void ET1310_PhyAdvertise1000BaseT( ET131X_ADAPTER *pAdapter, UINT16 duplex ) +{ + UINT16 usData; + + // Read the PHY 1000 Base-T Control Register + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_1000_CONTROL, &usData ); + + // Clear Bits 8,9 + usData &= ~0x0300; + + switch( duplex ) + { + case TRUEPHY_ADV_DUPLEX_NONE: + // Duplex already cleared, do nothing + break; + + case TRUEPHY_ADV_DUPLEX_FULL: + // Set Bit 9 + usData |= 0x0200; + break; + + case TRUEPHY_ADV_DUPLEX_HALF: + // Set Bit 8 + usData |= 0x0100; + break; + + case TRUEPHY_ADV_DUPLEX_BOTH: + default: + usData |= 0x0300; + break; + } + + // Write back advertisement + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_1000_CONTROL, usData ); + + return; +} + + +void ET1310_PhyAdvertise100BaseT( ET131X_ADAPTER *pAdapter, UINT16 duplex ) +{ + UINT16 usData; + + // Read the Autonegotiation Register (10/100) + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_AUTO_ADVERTISEMENT, &usData ); + + // Clear bits 7,8 + usData &= ~0x0180; + + switch( duplex ) + { + case TRUEPHY_ADV_DUPLEX_NONE: + // Duplex already cleared, do nothing + break; + + case TRUEPHY_ADV_DUPLEX_FULL: + // Set Bit 8 + usData |= 0x0100; + break; + + case TRUEPHY_ADV_DUPLEX_HALF: + // Set Bit 7 + usData |= 0x0080; + break; + + case TRUEPHY_ADV_DUPLEX_BOTH: + default: + // Set Bits 7,8 + usData |= 0x0180; + break; + } + + // Write back advertisement + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_AUTO_ADVERTISEMENT, usData ); + + return; +} + + +void ET1310_PhyAdvertise10BaseT( ET131X_ADAPTER *pAdapter, UINT16 duplex ) +{ + UINT16 usData; + + // Read the Autonegotiation Register (10/100) + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_AUTO_ADVERTISEMENT, &usData ); + + // Clear bits 5,6 + usData &= ~0x0060; + + switch( duplex ) + { + case TRUEPHY_ADV_DUPLEX_NONE: + // Duplex already cleared, do nothing + break; + + case TRUEPHY_ADV_DUPLEX_FULL: + // Set Bit 6 + usData |= 0x0040; + break; + + case TRUEPHY_ADV_DUPLEX_HALF: + // Set Bit 5 + usData |= 0x0020; + break; + + case TRUEPHY_ADV_DUPLEX_BOTH: + default: + // Set Bits 5,6 + usData |= 0x0060; + break; + } + + // Write back advertisement + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_AUTO_ADVERTISEMENT, usData ); + + return; +} + + + + +void ET1310_PhyLinkStatus( ET131X_ADAPTER *pAdapter, + UCHAR *ucLinkStatus, + UINT32 *uiAutoNeg, + UINT32 *uiLinkSpeed, + UINT32 *uiDuplexMode, + UINT32 *uiMdiMdix, + UINT32 *uiMasterSlave, + UINT32 *uiPolarity ) +{ + UINT16 usMiStatus = 0; + UINT16 us1000BaseT = 0; + UINT16 usVmiPhyStatus = 0; + UINT16 usControl = 0; + + + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_STATUS, &usMiStatus ); + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_1000_STATUS, &us1000BaseT ); + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_PHY_STATUS, &usVmiPhyStatus ); + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, &usControl ); + + if( ucLinkStatus ) + { + *ucLinkStatus = (unsigned char)(( usVmiPhyStatus & 0x0040 ) ? 1 : 0 ); + } + + if( uiAutoNeg ) + { + *uiAutoNeg = ( usControl & 0x1000 ) ? (( usVmiPhyStatus & 0x0020 ) ? TRUEPHY_ANEG_COMPLETE : TRUEPHY_ANEG_NOT_COMPLETE ) : TRUEPHY_ANEG_DISABLED; + } + + if( uiLinkSpeed ) + { + *uiLinkSpeed = ( usVmiPhyStatus & 0x0300 ) >> 8; + } + + if( uiDuplexMode ) + { + *uiDuplexMode = ( usVmiPhyStatus & 0x0080 ) >> 7; + } + + if( uiMdiMdix ) + { + /* NOTE: Need to complete this */ + *uiMdiMdix = 0; + } + + if( uiMasterSlave ) + { + *uiMasterSlave = ( us1000BaseT & 0x4000 ) ? TRUEPHY_CFG_MASTER : TRUEPHY_CFG_SLAVE; + } + + if( uiPolarity ) + { + *uiPolarity = ( usVmiPhyStatus & 0x0400 ) ? TRUEPHY_POLARITY_INVERTED : TRUEPHY_POLARITY_NORMAL; + } + + return; +} + + +void ET1310_PhyAndOrReg( ET131X_ADAPTER *pAdapter, + UINT16 regnum, + UINT16 andMask, + UINT16 orMask ) +{ + UINT16 reg; + + // Read the requested register + MiRead( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + regnum, ® ); + + // Apply the AND mask + reg &= andMask; + + // Apply the OR mask + reg |= orMask; + + // Write the value back to the register + MiWrite( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + regnum, reg ); + + return; +} + + +void ET1310_PhyAccessMiBit( ET131X_ADAPTER *pAdapter, + UINT16 action, + UINT16 regnum, + UINT16 bitnum, + UINT8 *value ) +{ + UINT16 reg; + UINT16 mask = 0; + + // Create a mask to isolate the requested bit + mask = 0x0001 << bitnum; + + // Read the requested register + MiRead( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + regnum, ® ); + + switch( action ) + { + case TRUEPHY_BIT_READ: + if( value != NULL ) + { + *value = ( reg & mask ) >> bitnum; + } + + break; + + case TRUEPHY_BIT_SET: + reg |= mask; + MiWrite( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, regnum, reg ); + break; + + case TRUEPHY_BIT_CLEAR: + reg &= ~mask; + MiWrite( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, regnum, reg ); + break; + + default: + break; + } + + return; +} + --- linux-2.6.28.orig/ubuntu/et131x/ET1310_rx.c +++ linux-2.6.28/ubuntu/et131x/ET1310_rx.c @@ -0,0 +1,2056 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_rx.c - Routines used to perform data reception + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2006/01/20 21:29:44 $ + $Revision: 1.21 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +#include +#endif + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" +#include "et131x_initpci.h" + +#include "ET1310_rx.h" + + + + +/****************************************************************************** + Data for debugging facilities + *****************************************************************************/ +#ifdef ET131X_DBG +extern dbg_info_t *et131x_dbginfo; +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + Prototypes for functions local to this module + *****************************************************************************/ +void nic_return_rfd( ET131X_ADAPTER *pAdapter, PMP_RFD pMpRfd ); + + + + +/****************************************************************************** + ROUTINE : et131x_rx_dma_memory_alloc + ****************************************************************************** + + DESCRIPTION : Allocates Free buffer ring 1 for sure, free buffer ring + 0 if required, and the Packet Status Ring + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_rx_dma_memory_alloc( ET131X_ADAPTER *adapter ) +{ + UINT32 OuterLoop, InnerLoop; + UINT32 bufsize; + UINT32 pktStatRingSize, FBRChunkSize; + RX_RING_t *rx_ring; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_rx_dma_memory_alloc" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Setup some convenience pointers + *************************************************************************/ + rx_ring = (RX_RING_t *)&adapter->RxRing; + + + /************************************************************************** + Alloc memory for the lookup table + *************************************************************************/ +#ifdef USE_FBR0 + rx_ring->Fbr[0] = kmalloc( sizeof( FBRLOOKUPTABLE ), GFP_KERNEL ); +#endif + + rx_ring->Fbr[1] = kmalloc( sizeof( FBRLOOKUPTABLE ), GFP_KERNEL ); + + + /************************************************************************** + The first thing we will do is configure the sizes of the buffer rings. + These will change based on jumbo packet support. Larger jumbo packets + increases the size of each entry in FBR0, and the number of entries in + FBR0, while at the same time decreasing the number of entries in FBR1. + + FBR1 holds "large" frames, FBR0 holds "small" frames. If FBR1 entries + are huge in order to accomodate a "jumbo" frame, then it will have less + entries. Conversely, FBR1 will now be relied upon to carry more + "normal" frames, thus it's entry size also increases and the number + of entries goes up too (since it now carries "small" + "regular" + packets. + + In this scheme, we try to maintain 512 entries between the two rings. + Also, FBR1 remains a constant size - when it's size doubles the + number of entries halves. FBR0 increases in size, however. + *************************************************************************/ + + if( adapter->RegistryJumboPacket < 2048 ) + { +#ifdef USE_FBR0 + rx_ring->Fbr0BufferSize = 256; + rx_ring->Fbr0NumEntries = 512; +#endif + rx_ring->Fbr1BufferSize = 2048; + rx_ring->Fbr1NumEntries = 512; + } + else if( adapter->RegistryJumboPacket < 4096 ) + { +#ifdef USE_FBR0 + rx_ring->Fbr0BufferSize = 512; + rx_ring->Fbr0NumEntries = 1024; +#endif + rx_ring->Fbr1BufferSize = 4096; + rx_ring->Fbr1NumEntries = 512; + } + else + { +#ifdef USE_FBR0 + rx_ring->Fbr0BufferSize = 1024; + rx_ring->Fbr0NumEntries = 768; +#endif + rx_ring->Fbr1BufferSize = 16384; + rx_ring->Fbr1NumEntries = 128; + } + +#ifdef USE_FBR0 + adapter->RxRing.PsrNumEntries = adapter->RxRing.Fbr0NumEntries + + adapter->RxRing.Fbr1NumEntries; +#else + adapter->RxRing.PsrNumEntries = adapter->RxRing.Fbr1NumEntries; +#endif + + + /************************************************************************** + Allocate an area of memory for Free Buffer Ring 1 + *************************************************************************/ + bufsize = ( sizeof( FBR_DESC_t ) * rx_ring->Fbr1NumEntries) + 0xfff; + rx_ring->pFbr1RingVa = pci_alloc_consistent( adapter->pdev, + bufsize, + &rx_ring->pFbr1RingPa ); + if( !rx_ring->pFbr1RingVa ) + { + DBG_ERROR( et131x_dbginfo, "Cannot alloc memory for Free Buffer Ring 1\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + + /************************************************************************** + Save physical address + + NOTE : pci_alloc_consistent(), used above to alloc DMA regions, ALWAYS + returns SAC (32-bit) addresses. If DAC (64-bit) addresses are + ever returned, make sure the high part is retrieved here before + storing the adjusted address. + *************************************************************************/ + rx_ring->Fbr1Realpa = rx_ring->pFbr1RingPa; + + + /************************************************************************** + Align Free Buffer Ring 1 on a 4K boundary + *************************************************************************/ + et131x_align_allocated_memory( adapter, + &rx_ring->Fbr1Realpa, + &rx_ring->Fbr1offset, + 0x0FFF ); + + rx_ring->pFbr1RingVa = (void *)( (PUCHAR)rx_ring->pFbr1RingVa + + rx_ring->Fbr1offset ); + + +#ifdef USE_FBR0 + /************************************************************************** + Allocate an area of memory for Free Buffer Ring 0 + *************************************************************************/ + bufsize = ( sizeof( FBR_DESC_t ) * rx_ring->Fbr0NumEntries ) + 0xfff; + rx_ring->pFbr0RingVa = pci_alloc_consistent( adapter->pdev, + bufsize, + &rx_ring->pFbr0RingPa ); + if( !rx_ring->pFbr0RingVa ) + { + DBG_ERROR( et131x_dbginfo, "Cannot alloc memory for Free Buffer Ring 0\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + + /************************************************************************** + Save physical address + + NOTE : pci_alloc_consistent(), used above to alloc DMA regions, ALWAYS + returns SAC (32-bit) addresses. If DAC (64-bit) addresses are + ever returned, make sure the high part is retrieved here before + storing the adjusted address. + *************************************************************************/ + rx_ring->Fbr0Realpa = rx_ring->pFbr0RingPa; + + + /************************************************************************** + Align Free Buffer Ring 0 on a 4K boundary + *************************************************************************/ + et131x_align_allocated_memory( adapter, + &rx_ring->Fbr0Realpa, + &rx_ring->Fbr0offset, + 0x0FFF ); + + rx_ring->pFbr0RingVa = (void *)( (PUCHAR)rx_ring->pFbr0RingVa + + rx_ring->Fbr0offset ); + +#endif + + + for( OuterLoop = 0; OuterLoop < (rx_ring->Fbr1NumEntries / FBR_CHUNKS); OuterLoop++ ) + { + UINT64 Fbr1Offset; + UINT64 Fbr1TempPa; + UINT32 Fbr1Align; + + /********************************************************************** + This code allocates an area of memory big enough for N free + buffers + (buffer_size - 1) so that the buffers can be aligned + on 4k boundaries. If each buffer were aligned + to a buffer_size boundary, the effect would be to double the size + of FBR0. By allocating N buffers at once, we reduce this overhead. + *********************************************************************/ + if( rx_ring->Fbr1BufferSize > 4096 ) + { + Fbr1Align = 4096; + } + else + { + Fbr1Align = rx_ring->Fbr1BufferSize; + } + + FBRChunkSize = ( FBR_CHUNKS * rx_ring->Fbr1BufferSize ) + Fbr1Align - 1; + rx_ring->Fbr1MemVa[OuterLoop] = pci_alloc_consistent( adapter->pdev, + FBRChunkSize, + &rx_ring->Fbr1MemPa[OuterLoop] ); + + if( !rx_ring->Fbr1MemVa[OuterLoop] ) + { + DBG_ERROR( et131x_dbginfo, "Could not alloc memory\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + + /********************************************************************** + See NOTE in "Save Physical Address" comment above + *********************************************************************/ + Fbr1TempPa = rx_ring->Fbr1MemPa[OuterLoop]; + + et131x_align_allocated_memory( adapter, + &Fbr1TempPa, + &Fbr1Offset, + (Fbr1Align - 1)); + + + for( InnerLoop = 0; InnerLoop < FBR_CHUNKS; InnerLoop++ ) + { + UINT32 index = (OuterLoop * FBR_CHUNKS) + InnerLoop; + + + /****************************************************************** + Save the Virtual address of this index for quick access later + *****************************************************************/ + rx_ring->Fbr[1]->Va[index] = (PUCHAR)rx_ring->Fbr1MemVa[OuterLoop] + + ( InnerLoop * rx_ring->Fbr1BufferSize ) + + Fbr1Offset; + + + /****************************************************************** + now store the physical address in the descriptor so the device + can access it + *****************************************************************/ + rx_ring->Fbr[1]->PAHigh[index] = (UINT32)(Fbr1TempPa >> 32); + rx_ring->Fbr[1]->PALow[index] = (UINT32) Fbr1TempPa; + + Fbr1TempPa += rx_ring->Fbr1BufferSize; + + rx_ring->Fbr[1]->Buffer1[index] = rx_ring->Fbr[1]->Va[index]; + rx_ring->Fbr[1]->Buffer2[index] = rx_ring->Fbr[1]->Va[index] - 4; + } + } + +#ifdef USE_FBR0 + /************************************************************************** + Same for FBR0 (if in use) + *************************************************************************/ + for( OuterLoop = 0; OuterLoop < (rx_ring->Fbr0NumEntries / FBR_CHUNKS); OuterLoop++ ) + { + UINT64 Fbr0Offset; + UINT64 Fbr0TempPa; + + FBRChunkSize = (( FBR_CHUNKS + 1 ) * rx_ring->Fbr0BufferSize ) - 1; + rx_ring->Fbr0MemVa[OuterLoop] = pci_alloc_consistent( adapter->pdev, + FBRChunkSize, + &rx_ring->Fbr0MemPa[OuterLoop] ); + + if( !rx_ring->Fbr0MemVa[OuterLoop] ) + { + DBG_ERROR( et131x_dbginfo, "Could not alloc memory\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + + /********************************************************************** + See NOTE in "Save Physical Address" comment above + *********************************************************************/ + Fbr0TempPa = rx_ring->Fbr0MemPa[OuterLoop]; + + et131x_align_allocated_memory( adapter, + &Fbr0TempPa, + &Fbr0Offset, + rx_ring->Fbr0BufferSize - 1 ); + + + for( InnerLoop = 0; InnerLoop < FBR_CHUNKS; InnerLoop++ ) + { + UINT32 index = (OuterLoop * FBR_CHUNKS) + InnerLoop; + + rx_ring->Fbr[0]->Va[index] = (PUCHAR)rx_ring->Fbr0MemVa[OuterLoop] + + ( InnerLoop * rx_ring->Fbr0BufferSize ) + + Fbr0Offset; + + rx_ring->Fbr[0]->PAHigh[index] = (UINT32)(Fbr0TempPa >> 32); + rx_ring->Fbr[0]->PALow[index] = (UINT32) Fbr0TempPa; + + Fbr0TempPa += rx_ring->Fbr0BufferSize; + + rx_ring->Fbr[0]->Buffer1[index] = rx_ring->Fbr[0]->Va[index]; + rx_ring->Fbr[0]->Buffer2[index] = rx_ring->Fbr[0]->Va[index] - 4; + } + } +#endif + + /************************************************************************** + Allocate an area of memory for the FIFO of Packet Status ring entries + *************************************************************************/ + pktStatRingSize = sizeof( PKT_STAT_DESC_t ) * adapter->RxRing.PsrNumEntries; + + rx_ring->pPSRingVa = pci_alloc_consistent( adapter->pdev, + pktStatRingSize + 0x0fff, + &rx_ring->pPSRingPa ); + + if( !rx_ring->pPSRingVa ) + { + DBG_ERROR( et131x_dbginfo, "Cannot alloc memory for Packet Status Ring\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + + /************************************************************************** + Save physical address + + NOTE : pci_alloc_consistent(), used above to alloc DMA regions, ALWAYS + returns SAC (32-bit) addresses. If DAC (64-bit) addresses are + ever returned, make sure the high part is retrieved here before + storing the adjusted address. + *************************************************************************/ + rx_ring->pPSRingRealPa = rx_ring->pPSRingPa; + + + /************************************************************************** + Align Packet Status Ring on a 4K boundary + *************************************************************************/ + et131x_align_allocated_memory( adapter, + &rx_ring->pPSRingRealPa, + &rx_ring->pPSRingOffset, + 0x0FFF ); + + rx_ring->pPSRingVa = (void *)( (PUCHAR)rx_ring->pPSRingVa + + rx_ring->pPSRingOffset ); + + + /************************************************************************** + Allocate an area of memory for the writeback of status information + *************************************************************************/ + rx_ring->pRxStatusVa = pci_alloc_consistent( adapter->pdev, + sizeof( RX_STATUS_BLOCK_t ) + 0x7, + &rx_ring->pRxStatusPa ); + if( !rx_ring->pRxStatusVa ) + { + DBG_ERROR( et131x_dbginfo, "Cannot alloc memory for Status Block\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + + /************************************************************************** + Save physical address + *************************************************************************/ + rx_ring->RxStatusRealPA = rx_ring->pRxStatusPa; + + + /************************************************************************** + Align write back on an 8 byte boundary + *************************************************************************/ + et131x_align_allocated_memory( adapter, + &rx_ring->RxStatusRealPA, + &rx_ring->RxStatusOffset, + 0x07 ); + + rx_ring->pRxStatusVa = (void *)( (PUCHAR)rx_ring->pRxStatusVa + + rx_ring->RxStatusOffset ); + rx_ring->NumRfd = NIC_DEFAULT_NUM_RFD; + + + /************************************************************************** + Recv + pci_pool_create initializes a lookaside list. + After successful creation, nonpaged fixed-size blocks can be + allocated from and freed to the lookaside list. + + RFDs will be allocated from this pool. + *************************************************************************/ + rx_ring->RecvLookaside = + #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) + kmem_cache_create( adapter->netdev->name, + sizeof( MP_RFD ), + 0, + SLAB_CACHE_DMA | + SLAB_HWCACHE_ALIGN, + NULL, + NULL ); + #endif + #if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)) + kmem_cache_create( adapter->netdev->name, + sizeof( MP_RFD ), + 0, + SLAB_CACHE_DMA | + SLAB_HWCACHE_ALIGN, + NULL); + #endif + + MP_SET_FLAG( adapter, fMP_ADAPTER_RECV_LOOKASIDE ); + + + /************************************************************************** + The RFDs are going to be put on lists later on, so initialize the lists + now. + *************************************************************************/ + INIT_LIST_HEAD( &rx_ring->RecvList ); + INIT_LIST_HEAD( &rx_ring->RecvPendingList ); + + + DBG_LEAVE( et131x_dbginfo ); + return 0; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_rx_dma_memory_free + ****************************************************************************** + + DESCRIPTION : Should basically free all memory allocated within this + module. + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_rx_dma_memory_free( ET131X_ADAPTER *adapter ) +{ + UINT32 index; + UINT32 bufsize; + UINT32 pktStatRingSize; + PMP_RFD pMpRfd; + RX_RING_t *rx_ring; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_rx_dma_memory_free" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Setup some convenience pointers + *************************************************************************/ + rx_ring = (RX_RING_t *)&adapter->RxRing; + + + /************************************************************************** + Free RFDs and associated packet descriptors + *************************************************************************/ + DBG_ASSERT( rx_ring->nReadyRecv == rx_ring->NumRfd ); + + while( !list_empty( &rx_ring->RecvList )) + { + pMpRfd = (MP_RFD *)list_entry( rx_ring->RecvList.next, + MP_RFD, + list_node ); + + list_del( &pMpRfd->list_node ); + et131x_rfd_resources_free( adapter, pMpRfd ); + } + + while( !list_empty( &rx_ring->RecvPendingList )) + { + pMpRfd = (MP_RFD *)list_entry( rx_ring->RecvPendingList.next, + MP_RFD, + list_node ); + list_del( &pMpRfd->list_node ); + et131x_rfd_resources_free( adapter, pMpRfd ); + } + + + /************************************************************************** + Free Free Buffer Ring 1 + *************************************************************************/ + if( rx_ring->pFbr1RingVa ) + { + /********************************************************************** + First the packet memory + *********************************************************************/ + for( index = 0; index < + (rx_ring->Fbr1NumEntries / FBR_CHUNKS); index++ ) + { + if( rx_ring->Fbr1MemVa[index] ) + { + UINT32 Fbr1Align; + + if( rx_ring->Fbr1BufferSize > 4096 ) + { + Fbr1Align = 4096; + } + else + { + Fbr1Align = rx_ring->Fbr1BufferSize; + } + + bufsize = ( rx_ring->Fbr1BufferSize * FBR_CHUNKS ) + + Fbr1Align - 1; + + pci_free_consistent( adapter->pdev, + bufsize, + rx_ring->Fbr1MemVa[index], + rx_ring->Fbr1MemPa[index] ); + + rx_ring->Fbr1MemVa[index] = 0; + } + } + + + /********************************************************************** + Now the FIFO itself + *********************************************************************/ + rx_ring->pFbr1RingVa = (void *)( (PUCHAR)rx_ring->pFbr1RingVa - + rx_ring->Fbr1offset ); + + bufsize = ( sizeof( FBR_DESC_t ) * rx_ring->Fbr1NumEntries ) + 0xfff; + + pci_free_consistent( adapter->pdev, + bufsize, + rx_ring->pFbr1RingVa, + rx_ring->pFbr1RingPa ); + + rx_ring->pFbr1RingVa = NULL; + } + + +#ifdef USE_FBR0 + /********************************************************************** + Now the same for Free Buffer Ring 0 + *********************************************************************/ + if( rx_ring->pFbr0RingVa ) + { + /********************************************************************** + First the packet memory + *********************************************************************/ + for( index = 0; index < + (rx_ring->Fbr0NumEntries / FBR_CHUNKS); index++ ) + { + if( rx_ring->Fbr0MemVa[index] ) + { + bufsize = ( rx_ring->Fbr0BufferSize * ( FBR_CHUNKS + 1 )) - 1; + + pci_free_consistent( adapter->pdev, + bufsize, + rx_ring->Fbr0MemVa[index], + rx_ring->Fbr0MemPa[index] ); + + rx_ring->Fbr0MemVa[index] = 0; + } + } + + + /********************************************************************** + Now the FIFO itself + *********************************************************************/ + rx_ring->pFbr0RingVa = (void *)( (PUCHAR)rx_ring->pFbr0RingVa - + rx_ring->Fbr0offset ); + + bufsize = ( sizeof( FBR_DESC_t ) * rx_ring->Fbr0NumEntries ) + 0xfff; + + pci_free_consistent( adapter->pdev, + bufsize, + rx_ring->pFbr0RingVa, + rx_ring->pFbr0RingPa ); + + rx_ring->pFbr0RingVa = NULL; + } +#endif + + + /************************************************************************** + Free Packet Status Ring + *************************************************************************/ + if( rx_ring->pPSRingVa ) + { + rx_ring->pPSRingVa = (void *)( (PUCHAR)rx_ring->pPSRingVa - + rx_ring->pPSRingOffset ); + + pktStatRingSize = sizeof( PKT_STAT_DESC_t ) * adapter->RxRing.PsrNumEntries; + + pci_free_consistent( adapter->pdev, + pktStatRingSize + 0x0fff, + rx_ring->pPSRingVa, + rx_ring->pPSRingPa ); + + rx_ring->pPSRingVa = NULL; + } + + + /********************************************************************** + Free area of memory for the writeback of status information + *********************************************************************/ + if( rx_ring->pRxStatusVa ) + { + rx_ring->pRxStatusVa = (void *)( (PUCHAR)rx_ring->pRxStatusVa - + rx_ring->RxStatusOffset ); + + pci_free_consistent( adapter->pdev, + sizeof( RX_STATUS_BLOCK_t ) + 0x7, + rx_ring->pRxStatusVa, + rx_ring->pRxStatusPa ); + + rx_ring->pRxStatusVa = NULL; + } + + + /************************************************************************** + Free receive buffer pool + *************************************************************************/ + + + /************************************************************************** + Free receive packet pool + *************************************************************************/ + + + /************************************************************************** + Destroy the lookaside (RFD) pool + *************************************************************************/ + if( MP_TEST_FLAG( adapter, fMP_ADAPTER_RECV_LOOKASIDE )) + { + kmem_cache_destroy( rx_ring->RecvLookaside ); + MP_CLEAR_FLAG( adapter, fMP_ADAPTER_RECV_LOOKASIDE ); + } + + + /************************************************************************** + Free the FBR Lookup Table + *************************************************************************/ +#ifdef USE_FBR0 + kfree( rx_ring->Fbr[0] ); +#endif + + kfree( rx_ring->Fbr[1] ); + + + /************************************************************************** + Reset Counters + *************************************************************************/ + rx_ring->nReadyRecv = 0; + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_init_recv + ****************************************************************************** + + DESCRIPTION : Initialize receive data structures. + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_init_recv( ET131X_ADAPTER *adapter ) +{ + int status = -ENOMEM; + PMP_RFD pMpRfd = NULL; + UINT32 RfdCount; + UINT32 TotalNumRfd = 0; + RX_RING_t *rx_ring = NULL; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_init_recv" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Setup some convenience pointers + *************************************************************************/ + rx_ring = (RX_RING_t *)&adapter->RxRing; + + + /************************************************************************** + Setup each RFD + *************************************************************************/ + for( RfdCount = 0; RfdCount < rx_ring->NumRfd; RfdCount++ ) + { + pMpRfd = ( MP_RFD * )kmem_cache_alloc( rx_ring->RecvLookaside, + GFP_ATOMIC | GFP_DMA ); + + if( !pMpRfd ) + { + DBG_ERROR( et131x_dbginfo, "Couldn't alloc RFD out of kmem_cache\n" ); + + status = -ENOMEM; + continue; + } + + status = et131x_rfd_resources_alloc( adapter,pMpRfd ); + if( status != 0 ) + { + DBG_ERROR( et131x_dbginfo, "Couldn't alloc packet for RFD\n" ); + kmem_cache_free( rx_ring->RecvLookaside, pMpRfd ); + continue; + } + + + /********************************************************************** + Add this RFD to the RecvList + *********************************************************************/ + list_add_tail( &pMpRfd->list_node, &rx_ring->RecvList ); + + + /********************************************************************** + Increment both the available RFD's, and the total RFD's. + *********************************************************************/ + rx_ring->nReadyRecv++; + TotalNumRfd++; + } + + if( TotalNumRfd > NIC_MIN_NUM_RFD ) + { + status = 0; + } + + rx_ring->NumRfd = TotalNumRfd; + + if( status != 0 ) + { + kmem_cache_free( rx_ring->RecvLookaside, pMpRfd ); + DBG_ERROR( et131x_dbginfo, "Allocation problems in et131x_init_recv\n" ); + } + + + DBG_LEAVE( et131x_dbginfo ); + return status; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_rfd_resources_alloc + ****************************************************************************** + + DESCRIPTION : + + PARAMETERS : adapter - pointer to our private adapter structure + pMpRfd - pointer to a RFD + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_rfd_resources_alloc( ET131X_ADAPTER *adapter, MP_RFD *pMpRfd ) +{ + pMpRfd->Packet = NULL; + + return 0; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_rfd_resources_free + ****************************************************************************** + + DESCRIPTION : Free the packet allocated for the given RFD + + PARAMETERS : adapter - pointer to our private adapter structure + pMpRfd - pointer to a RFD + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_rfd_resources_free( ET131X_ADAPTER *adapter, MP_RFD *pMpRfd ) +{ + pMpRfd->Packet = NULL; + kmem_cache_free( adapter->RxRing.RecvLookaside, pMpRfd ); + + return; +} +/*===========================================================================*/ + + + + + +/****************************************************************************** + ROUTINE: ConfigRxDmaRegs + ****************************************************************************** + DESCRIPTION: + START OF Rx_DMA INIT SEQUENCE + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + + + *****************************************************************************/ +void ConfigRxDmaRegs( ET131X_ADAPTER *pAdapter ) +{ + PRXDMA_t pRxDma; + PFBR_DESC_t pFbrEntry; + UINT32 iEntry; + unsigned long lockflags; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "ConfigRxDmaRegs" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Let's get our pointer to the RxDma section of regs + *************************************************************************/ + pRxDma = &pAdapter->CSRAddress->rxdma; + + + /************************************************************************** + Halt RXDMA to perform the reconfigure. + *************************************************************************/ + et131x_rx_dma_disable( pAdapter ); + + + /************************************************************************** + Load the completion writeback physical address + + NOTE : pci_alloc_consistent(), used above to alloc DMA regions, ALWAYS + returns SAC (32-bit) addresses. If DAC (64-bit) addresses are + ever returned, make sure the high part is retrieved here before + storing the adjusted address. + *************************************************************************/ + pRxDma->dma_wb_base_hi.addr_hi = (UINT32)( pAdapter->RxRing.RxStatusRealPA >> 32 ); + pRxDma->dma_wb_base_lo.addr_lo = (UINT32)( pAdapter->RxRing.RxStatusRealPA ); + + memset( pAdapter->RxRing.pRxStatusVa, 0, sizeof( RX_STATUS_BLOCK_t )); + + + /************************************************************************** + Set the address and parameters of the packet status ring into the 1310's + registers + *************************************************************************/ + pRxDma->psr_base_hi.addr_hi = (UINT32)( pAdapter->RxRing.pPSRingRealPa >> 32 ); + pRxDma->psr_base_lo.addr_lo = (UINT32)( pAdapter->RxRing.pPSRingRealPa ); + + pRxDma->psr_num_des.value = pAdapter->RxRing.PsrNumEntries - 1; + + pRxDma->psr_full_offset.value = 0; + + pRxDma->psr_min_des.value = + ( pRxDma->psr_num_des.bits.psr_ndes * LO_MARK_PERCENT_FOR_PSR ) / 100; + + spin_lock_irqsave( &pAdapter->RcvLock, lockflags ); + + + /************************************************************************** + These local variables track the PSR in the adapter structure + *************************************************************************/ + pAdapter->RxRing.local_psr_full.bits.psr_full = 0; + pAdapter->RxRing.local_psr_full.bits.psr_full_wrap = 0; + + + /************************************************************************** + Now's the best time to initialize FBR1 contents + *************************************************************************/ + pFbrEntry = (PFBR_DESC_t) pAdapter->RxRing.pFbr1RingVa; + + for (iEntry=0; iEntry < pAdapter->RxRing.Fbr1NumEntries; iEntry++) + { + pFbrEntry->addr_hi = pAdapter->RxRing.Fbr[1]->PAHigh[ iEntry ]; + pFbrEntry->addr_lo = pAdapter->RxRing.Fbr[1]->PALow [ iEntry ]; + pFbrEntry->word2.bits.bi = iEntry; + pFbrEntry++; + } + + + /************************************************************************** + Set the address and parameters of Free buffer ring 1 (and 0 if required) + into the 1310's registers + *************************************************************************/ + pRxDma->fbr1_base_hi.addr_hi = (UINT32)( pAdapter->RxRing.Fbr1Realpa >> 32 ); + pRxDma->fbr1_base_lo.addr_lo = (UINT32)( pAdapter->RxRing.Fbr1Realpa ); + + pRxDma->fbr1_num_des.value = pAdapter->RxRing.Fbr1NumEntries - 1; + + { + RXDMA_FBR_FULL_OFFSET_t fbr1_full; + + fbr1_full.bits.fbr_full = 0; + fbr1_full.bits.fbr_full_wrap = 1; + + pRxDma->fbr1_full_offset = fbr1_full; + } + + + /************************************************************************** + This variable tracks the free buffer ring 1 full position, so it has to + match the above. + *************************************************************************/ + pAdapter->RxRing.local_Fbr1_full.bits.fbr_full = 0; + pAdapter->RxRing.local_Fbr1_full.bits.fbr_full_wrap = 1; + + pRxDma->fbr1_min_des.bits.fbr_min = + (( pAdapter->RxRing.Fbr1NumEntries * LO_MARK_PERCENT_FOR_RX ) / 100) - 1; + + +#ifdef USE_FBR0 + /************************************************************************** + Now's the best time to initialize FBR0 contents + *************************************************************************/ + pFbrEntry = (PFBR_DESC_t) pAdapter->RxRing.pFbr0RingVa; + + for (iEntry=0; iEntry < pAdapter->RxRing.Fbr0NumEntries; iEntry++) + { + pFbrEntry->addr_hi = pAdapter->RxRing.Fbr[0]->PAHigh[iEntry]; + pFbrEntry->addr_lo = pAdapter->RxRing.Fbr[0]->PALow [iEntry]; + pFbrEntry->word2.bits.bi = iEntry; + pFbrEntry++; + } + + pRxDma->fbr0_base_hi.addr_hi = (UINT32)( pAdapter->RxRing.Fbr0Realpa >> 32 ); + pRxDma->fbr0_base_lo.addr_lo = (UINT32)( pAdapter->RxRing.Fbr0Realpa ); + + pRxDma->fbr0_num_des.bits.fbr_ndesc = pAdapter->RxRing.Fbr0NumEntries - 1; + + { + RXDMA_FBR_FULL_OFFSET_t fbr0_full; + + fbr0_full.bits.fbr_full = 0; + fbr0_full.bits.fbr_full_wrap = 1; + + pRxDma->fbr0_full_offset = fbr0_full; + } + + + /************************************************************************** + This variable tracks the free buffer ring 0 full position, so it has to + match the above. + *************************************************************************/ + pAdapter->RxRing.local_Fbr0_full.bits.fbr_full = 0; + pAdapter->RxRing.local_Fbr0_full.bits.fbr_full_wrap = 1; + + pRxDma->fbr0_min_des.bits.fbr_min = + (( pAdapter->RxRing.Fbr0NumEntries * LO_MARK_PERCENT_FOR_RX ) / 100) - 1; +#endif + + + /************************************************************************** + Program the number of packets we will receive before generating an + interrupt. + + For version B silicon, this value gets updated once autoneg is complete. + *************************************************************************/ + pRxDma->num_pkt_done.value = pAdapter->RegistryRxNumBuffers; + + + /************************************************************************** + The "time_done" is not working correctly to coalesce interrupts after + a given time period, but rather is giving us an interrupt regardless + of whether we have received packets. + + This value gets updated once autoneg is complete. + *************************************************************************/ + pRxDma->max_pkt_time.value = pAdapter->RegistryRxTimeInterval; + + spin_unlock_irqrestore( &pAdapter->RcvLock, lockflags ); + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: SetRxDmaTimer + ****************************************************************************** + DESCRIPTION: + SET the heartbeat timer according to line rate. + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + N/A + + *****************************************************************************/ +void SetRxDmaTimer( ET131X_ADAPTER *pAdapter ) +{ + /************************************************************************** + For version B silicon, we do not use the RxDMA timer for 10 and 100 + Mbits/s line rates. We do not enable and RxDMA interrupt coalescing. + *************************************************************************/ + if(( pAdapter->uiLinkSpeed == TRUEPHY_SPEED_100MBPS ) || + ( pAdapter->uiLinkSpeed == TRUEPHY_SPEED_10MBPS )) + { + pAdapter->CSRAddress->rxdma.max_pkt_time.value = 0; + pAdapter->CSRAddress->rxdma.num_pkt_done.value = 1; + } + + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_rx_dma_disable + ****************************************************************************** + DESCRIPTION: + Stop OF Rx_DMA on the ET1310 + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + + + *****************************************************************************/ +void et131x_rx_dma_disable( ET131X_ADAPTER *pAdapter ) +{ + DBG_FUNC( "et131x_rx_dma_disable" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Setup the receive dma configuration register + *************************************************************************/ + pAdapter->CSRAddress->rxdma.csr.value = 0x00002001; + + if( pAdapter->CSRAddress->rxdma.csr.bits.halt_status != 1 ) + { + udelay( 5 ); + if( pAdapter->CSRAddress->rxdma.csr.bits.halt_status != 1 ) + { + DBG_ERROR( et131x_dbginfo, + "RX Dma failed to enter halt state. CSR 0x%08x\n", + pAdapter->CSRAddress->rxdma.csr.value ); + } + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_rx_dma_enable + ****************************************************************************** + DESCRIPTION: + re-start OF Rx_DMA on the ET1310. + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + + + *****************************************************************************/ +void et131x_rx_dma_enable( ET131X_ADAPTER *pAdapter ) +{ + DBG_FUNC( "et131x_rx_dma_enable" ); + DBG_RX_ENTER( et131x_dbginfo ); + + + if( pAdapter->RegistryPhyLoopbk ) + { + /********************************************************************** + RxDMA is disabled for loopback operation. + *********************************************************************/ + pAdapter->CSRAddress->rxdma.csr.value = 0x1; + } + else + { + /********************************************************************** + Setup the receive dma configuration register for normal operation. + *********************************************************************/ + { + RXDMA_CSR_t csr = {0}; + + csr.bits.fbr1_enable = 1; + + if( pAdapter->RxRing.Fbr1BufferSize == 4096 ) + { + csr.bits.fbr1_size = 1; + } + else if( pAdapter->RxRing.Fbr1BufferSize == 8192 ) + { + csr.bits.fbr1_size = 2; + } + else if( pAdapter->RxRing.Fbr1BufferSize == 16384 ) + { + csr.bits.fbr1_size = 3; + } +#ifdef USE_FBR0 + csr.bits.fbr0_enable = 1; + + if( pAdapter->RxRing.Fbr0BufferSize == 256 ) + { + csr.bits.fbr0_size = 1; + } + else if( pAdapter->RxRing.Fbr0BufferSize == 512 ) + { + csr.bits.fbr0_size = 2; + } + else if( pAdapter->RxRing.Fbr0BufferSize == 1024 ) + { + csr.bits.fbr0_size = 3; + } +#endif + pAdapter->CSRAddress->rxdma.csr = csr; + } + + if( pAdapter->CSRAddress->rxdma.csr.bits.halt_status != 0 ) + { + udelay( 5 ); + if( pAdapter->CSRAddress->rxdma.csr.bits.halt_status != 0 ) + { + DBG_ERROR( et131x_dbginfo, + "RX Dma failed to exit halt state. CSR 0x%08x\n", + pAdapter->CSRAddress->rxdma.csr.value ); + } + } + } + + + DBG_RX_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: nic_rx_pkts + ****************************************************************************** + DESCRIPTION: + Checks the hardware for available packets, using completion ring + If packets are available, it gets an RFD from the RecvList, attaches + the packet to it, puts the RFD in the RecvPendList, and also returns + the pointer to the RFD. + + PARAMETERS : + pAdapter - pointer to our adapter + + RETURNS : + pMpRfd - pointer to our MPRFD + + *****************************************************************************/ +PMP_RFD nic_rx_pkts( ET131X_ADAPTER *pAdapter ) +{ + PRX_STATUS_BLOCK_t pRxStatusBlock; + PPKT_STAT_DESC_t pPSREntry; + PMP_RFD pMpRfd; + UINT32 nIndex; + PUCHAR pBufVa; + PUINT16 pShBufVa; + unsigned long lockflags; + struct list_head *element; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "nic_rx_pkts" ); + DBG_RX_ENTER( et131x_dbginfo ); + + + /************************************************************************** + RX Status block is written by the DMA engine prior to every interrupt. + It contains the next to be used entry in the Packet Status Ring, and + also the two Free Buffer rings. + *************************************************************************/ + pRxStatusBlock = (PRX_STATUS_BLOCK_t)pAdapter->RxRing.pRxStatusVa; + + if(( pRxStatusBlock->Word1.bits.PSRoffset != + pAdapter->RxRing.local_psr_full.bits.psr_full ) || + ( pRxStatusBlock->Word1.bits.PSRwrap != + pAdapter->RxRing.local_psr_full.bits.psr_full_wrap )) + { + UINT8 ringIndex; + UINT16 bufferIndex; + UINT32 localLen; + PKT_STAT_DESC_WORD0_t Word0; + + + /********************************************************************** + The packet status ring indicates that data is available. + *********************************************************************/ + pPSREntry = (PPKT_STAT_DESC_t)( pAdapter->RxRing.pPSRingVa ) + + pAdapter->RxRing.local_psr_full.bits.psr_full; + + + /********************************************************************** + Grab any information that is required once the PSR is advanced, + since we can no longer rely on the memory being accurate + *********************************************************************/ + localLen = pPSREntry->word1.bits.length; + ringIndex = (UINT8)pPSREntry->word1.bits.ri; + bufferIndex = (UINT16)pPSREntry->word1.bits.bi; + Word0 = pPSREntry->word0; + + DBG_RX( et131x_dbginfo, "RX PACKET STATUS\n" ); + DBG_RX( et131x_dbginfo, "\tlength : %d\n", localLen ); + DBG_RX( et131x_dbginfo, "\tringIndex : %d\n", ringIndex ); + DBG_RX( et131x_dbginfo, "\tbufferIndex : %d\n", bufferIndex ); + DBG_RX( et131x_dbginfo, "\tword0 : 0x%08x\n", Word0.value ); + + +#if 0 + /********************************************************************** + Check the Status Word that the MAC has appended to the PSR entry in + case the MAC has detected errors. + *********************************************************************/ + if( Word0.value & ALCATEL_BAD_STATUS ) + { + DBG_ERROR( et131x_dbginfo, + "NICRxPkts >> Alcatel Status Word error." + "Value 0x%08x\n", + pPSREntry->word0.value ); + } +#endif + + + /********************************************************************** + Indicate that we have used this PSR entry. + *********************************************************************/ + if( ++pAdapter->RxRing.local_psr_full.bits.psr_full > + ( pAdapter->RxRing.PsrNumEntries - 1 )) + { + pAdapter->RxRing.local_psr_full.bits.psr_full = 0; + pAdapter->RxRing.local_psr_full.bits.psr_full_wrap ^= 1; + } + + pAdapter->CSRAddress->rxdma.psr_full_offset = + pAdapter->RxRing.local_psr_full; + +#ifndef USE_FBR0 + if( ringIndex != 1 ) + { + DBG_ERROR( et131x_dbginfo, + "NICRxPkts PSR Entry %d indicates " + "Buffer Ring 0 in use\n", + pAdapter->RxRing.local_psr_full.bits.psr_full ); + + DBG_RX_LEAVE( et131x_dbginfo ); + return NULL; + } +#endif + +#ifdef USE_FBR0 + if(( ringIndex > 1 ) || + (( ringIndex == 0 ) && ( bufferIndex > ( pAdapter->RxRing.Fbr0NumEntries - 1 ))) || + (( ringIndex == 1 ) && ( bufferIndex > ( pAdapter->RxRing.Fbr1NumEntries - 1 )))) +#else + if(( ringIndex != 1 ) || ( bufferIndex > ( pAdapter->RxRing.Fbr1NumEntries - 1 ))) +#endif + { + /****************************************************************** + Illegal buffer or ring index cannot be used by the S/W + *****************************************************************/ + DBG_ERROR( et131x_dbginfo, + "NICRxPkts PSR Entry %d indicates " + "length of %d and/or bad bi(%d)\n", + pAdapter->RxRing.local_psr_full.bits.psr_full, + localLen, + bufferIndex ); + + DBG_RX_LEAVE( et131x_dbginfo ); + return NULL; + } + + + /********************************************************************** + Get and fill the RFD. + *********************************************************************/ + spin_lock_irqsave( &pAdapter->RcvLock, lockflags ); + + pMpRfd = NULL; + element = pAdapter->RxRing.RecvList.next; + pMpRfd = (PMP_RFD)list_entry( element, MP_RFD, list_node ); + + if( pMpRfd == NULL ) + { + DBG_RX( et131x_dbginfo, + "NULL RFD returned from RecvList via list_entry()\n" ); + DBG_RX_LEAVE( et131x_dbginfo ); + return NULL; + } + + list_del( &pMpRfd->list_node ); + pAdapter->RxRing.nReadyRecv--; + + spin_unlock_irqrestore( &pAdapter->RcvLock, lockflags ); + + pMpRfd->iBufferIndex = bufferIndex; + pMpRfd->iRingIndex = ringIndex; + + + /********************************************************************** + In V1 silicon, there is a bug which screws up filtering of runt + packets. Therefore runt packet filtering is disabled in the MAC + and the packets are dropped here. They are also counted here. + *********************************************************************/ + if( localLen < ( NIC_MIN_PACKET_SIZE + 4 )) + { + pAdapter->Stats.other_errors++; + localLen = 0; + } + + +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) + if( localLen ) + { + pShBufVa = pAdapter->RxRing.Fbr[ringIndex]->Va[bufferIndex]; + + pMpRfd->bHasVLANTag = FALSE; + + + /****************************************************************** + The protocol value of 0x8100 means there is a VLAN tag in the + packet. Also the original protocol value will be present four + bytes further on. + *****************************************************************/ + if( pShBufVa[6] == 0x0081 ) + { + UINT16 LocalShort = (( pShBufVa[7] & 0xff00 ) >> 8 ) + + (( pShBufVa[7] & 0x00ff ) << 8 ); + UINT16 vlan_tag = LocalShort & 0x0fff; + + pMpRfd->bHasVLANTag = TRUE; + + DBG_RX( et131x_dbginfo, + "VLAN: RX packet Tag: %d\n", vlan_tag ); + + + /************************************************************** + The rules are: + - if our VLAN tag is zero we can pass anything up + - if our VLAN tag matches the incoming we can pass it + - If the packet is a protocol 802.3ad we pass it + regardless (802.3ad had protocol val of 0x8809. + proto val is now in ShBuf [8]) + - If the packet is a GARP VLAN Registration Protocol + (GVRP) packet, we pass it regardless. + 01:80:c2:00:00:21 is the GVRP address. + + NOTE: Because the ET1310 doesn't perform VLAN tagging + (it's done in the kernel) always pass packets up. + We'll leave this code in, however, just in case it's + needed in the future. + *************************************************************/ + if(( 1 ) || + ( pShBufVa[8] == 0x0988 ) || + (( pShBufVa[0] == 0x8001 ) && + ( pShBufVa[1] == 0x00c2 ) && + ( pShBufVa[2] == 0x2100 ))) + { + DBG_RX( et131x_dbginfo, + "VLAN: Passed test, send pkt up\n" ); + pMpRfd->VLANTag = vlan_tag; + } + else + { + /********************************************************* + Our VLAN tag is non-zero, AND the incoming tag does + not match it. Drop the packet. + ********************************************************/ + DBG_RX( et131x_dbginfo, + "VLAN: no match, drop pkt\n" ); + localLen = 0; + } + } + else if(( pShBufVa[6] == 0x0988 ) || + (( pShBufVa[0] == 0x8001 ) && + ( pShBufVa[1] == 0x00c2 ) && + ( pShBufVa[2] == 0x2100 ))) + { + /****************************************************************** + The protocol type (ethertype) of 0x8809 corresponds to 802.3ad + The MAC address of 01:80:c2:00:00:21 is the GARP VLAN + registration protocol (GVRP) address. + + Both of these message types should be passed up regardless + of their VLAN tagging. + *****************************************************************/ + DBG_RX( et131x_dbginfo, + "VLAN: No tag, but 802.3ad/GVRP, send pkt up\n" ); + } + else + { + /****************************************************************** + Our VLAN tag is non-zero. no VLAN header on incoming. + Packet is not GVRP or 802.3ad. Drop the packet. + *****************************************************************/ + DBG_RX( et131x_dbginfo, + "VLAN: No RX packet tag\n" ); + // NOTE: Same as the note above; never drop a packet for now. + // localLen = 0; + } + } +#endif + + if( localLen ) + { + if ( pAdapter->ReplicaPhyLoopbk == 1 ) + { + pBufVa = pAdapter->RxRing.Fbr[ringIndex]->Va[bufferIndex]; + + if( memcmp( &pBufVa[6], &pAdapter->CurrentAddress[0], ETH_ALEN ) == 0 ) + { + if( memcmp( &pBufVa[42], "Replica packet", ETH_HLEN )) + { + pAdapter->ReplicaPhyLoopbkPF = 1; + } + } + DBG_WARNING( et131x_dbginfo, + "pBufVa:\t%02x:%02x:%02x:%02x:%02x:%02x\n", + pBufVa[6], + pBufVa[7], + pBufVa[8], + pBufVa[9], + pBufVa[10], + pBufVa[11] ); + + DBG_WARNING( et131x_dbginfo, + "CurrentAddr:\t%02x:%02x:%02x:%02x:%02x:%02x\n", + pAdapter->CurrentAddress[0], + pAdapter->CurrentAddress[1], + pAdapter->CurrentAddress[2], + pAdapter->CurrentAddress[3], + pAdapter->CurrentAddress[4], + pAdapter->CurrentAddress[5] ); + } + + /****************************************************************** + Determine if this is a multicast packet coming in + *****************************************************************/ + if(( Word0.value & ALCATEL_MULTICAST_PKT ) && + !( Word0.value & ALCATEL_BROADCAST_PKT )) + { + /************************************************************** + Promiscuous mode and Multicast mode are not mutually + exclusive as was first thought. I guess Promiscuous is + just considered a super-set of the other filters. + Generally filter is 0x2b when in promiscuous mode. + *************************************************************/ + if(( pAdapter->PacketFilter & ET131X_PACKET_TYPE_MULTICAST ) && + !( pAdapter->PacketFilter & ET131X_PACKET_TYPE_PROMISCUOUS ) && + !( pAdapter->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST )) + { + pBufVa = pAdapter->RxRing.Fbr[ringIndex]->Va[bufferIndex]; + + /********************************************************** + Loop through our list to see if the destination address + of this packet matches one in our list. + *********************************************************/ + for( nIndex = 0; nIndex < pAdapter->MCAddressCount; nIndex++ ) + { + if( pBufVa[0] == pAdapter->MCList[nIndex][0] && + pBufVa[1] == pAdapter->MCList[nIndex][1] && + pBufVa[2] == pAdapter->MCList[nIndex][2] && + pBufVa[3] == pAdapter->MCList[nIndex][3] && + pBufVa[4] == pAdapter->MCList[nIndex][4] && + pBufVa[5] == pAdapter->MCList[nIndex][5] ) + { + break; + } + } + + /********************************************************** + If our index is equal to the number of Multicast + address we have, then this means we did not find this + packet's matching address in our list. Set the + PacketSize to zero, so we free our RFD when we return + from this function. + *********************************************************/ + if( nIndex == pAdapter->MCAddressCount ) + { + localLen = 0; + } + } + + if( localLen > 0 ) + { + pAdapter->Stats.multircv++; + } + } + else if( Word0.value & ALCATEL_BROADCAST_PKT ) + { + pAdapter->Stats.brdcstrcv++; + } + else + { + /************************************************************** + Not sure what this counter measures in promiscuous mode. + Perhaps we should check the MAC address to see if it is + directed to us in promiscuous mode. + *************************************************************/ + pAdapter->Stats.unircv++; + } + } + + if( localLen > 0 ) + { + struct sk_buff *skb = NULL; + +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +#ifdef __vlan_get_tag + unsigned short vlan_tag = 0; +#endif +#endif + + //vlan_tag = 0; + + //pMpRfd->PacketSize = localLen - 4; + pMpRfd->PacketSize = localLen; + + skb = dev_alloc_skb( pMpRfd->PacketSize + 2 ); + if( !skb ) + { + DBG_ERROR( et131x_dbginfo, "Couldn't alloc an SKB for Rx\n" ); + DBG_RX_LEAVE( et131x_dbginfo ); + return NULL; + } + + pAdapter->net_stats.rx_bytes += pMpRfd->PacketSize; + + memcpy( skb_put( skb, pMpRfd->PacketSize ), + pAdapter->RxRing.Fbr[ringIndex]->Va[bufferIndex], + pMpRfd->PacketSize ); + + skb->dev = pAdapter->netdev; + skb->protocol = eth_type_trans( skb, pAdapter->netdev ); + skb->ip_summed = CHECKSUM_NONE; + + +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +#if defined __vlan_get_tag + if( __vlan_get_tag( skb, &vlan_tag ) == -EINVAL ) + { + DBG_RX( et131x_dbginfo, + "VLAN: No Rx packet tag\n" ); + } + else + { + DBG_RX( et131x_dbginfo, + "VLAN: Rx packet tag: %d\n", vlan_tag ); + } +#endif +#endif + + netif_rx( skb ); + } + else + { + pMpRfd->PacketSize = 0; + } + + nic_return_rfd( pAdapter, pMpRfd ); + + + DBG_RX( et131x_dbginfo, "(1)\n" ); + DBG_RX_LEAVE( et131x_dbginfo ); + return pMpRfd; + } + else + { + /********************************************************************** + Looks like this ring is not updated yet + *********************************************************************/ + DBG_RX( et131x_dbginfo, "(0)\n" ); + DBG_RX_LEAVE( et131x_dbginfo ); + return NULL; + } +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_reset_recv + ****************************************************************************** + DESCRIPTION: + Reset the receive list + + Assumption: Rcv spinlock has been acquired + + PARAMETERS : + pAdapter - pointer to our adapter + + RETURNS : + NONE + + *****************************************************************************/ +void et131x_reset_recv( ET131X_ADAPTER *pAdapter ) +{ + PMP_RFD pMpRfd; + struct list_head *element; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_reset_recv" ); + DBG_ENTER( et131x_dbginfo ); + + + DBG_ASSERT( !list_empty( &pAdapter->RxRing.RecvList )); + + + /************************************************************************** + Take all the RFD's from the pending list, and stick them on the + RecvList. + *************************************************************************/ + while( !list_empty( &pAdapter->RxRing.RecvPendingList ) ) + { + element = pAdapter->RxRing.RecvPendingList.next; + + pMpRfd = (PMP_RFD)list_entry( element, MP_RFD, list_node ); + + list_del( &pMpRfd->list_node ); + list_add_tail( &pMpRfd->list_node, &pAdapter->RxRing.RecvList ); + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_handle_recv_interrupt + ****************************************************************************** + DESCRIPTION: + Interrupt handler for receive processing + + Assumption: Rcv spinlock has been acquired + + PARAMETERS : + pAdapter - pointer to our adapter + + RETURNS : + NONE + + *****************************************************************************/ +void et131x_handle_recv_interrupt( ET131X_ADAPTER *pAdapter ) +{ + PMP_RFD pMpRfd = NULL; + struct sk_buff *PacketArray [NUM_PACKETS_HANDLED]; + PMP_RFD RFDFreeArray[NUM_PACKETS_HANDLED]; + UINT32 PacketArrayCount = 0; + UINT32 PacketsToHandle; + UINT32 PacketFreeCount = 0; + BOOL_t TempUnfinishedRec = FALSE; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_handle_recv_interrupt" ); + DBG_RX_ENTER( et131x_dbginfo ); + + + PacketsToHandle = NUM_PACKETS_HANDLED; + + + /************************************************************************** + Process up to available RFD's + *************************************************************************/ + while( PacketArrayCount < PacketsToHandle ) + { + if( list_empty( &pAdapter->RxRing.RecvList )) + { + DBG_ASSERT( pAdapter->RxRing.nReadyRecv == 0 ); + DBG_ERROR( et131x_dbginfo, "NO RFD's !!!!!!!!!!!!!\n" ); + TempUnfinishedRec = TRUE; + break; + } + + pMpRfd = nic_rx_pkts( pAdapter ); + + if( pMpRfd == NULL) + { + break; + } + + + /********************************************************************** + Do not receive any packets until a filter has been set. + Do not receive any packets until we are at D0. + Do not receive any packets until we have link. + If length is zero, return the RFD in order to advance the Free + buffer ring. + *********************************************************************/ + if(( !pAdapter->PacketFilter ) || + ( pAdapter->PoMgmt.PowerState != NdisDeviceStateD0 ) || + ( !MP_LINK_DETECTED( pAdapter )) || + ( pMpRfd->PacketSize == 0 )) + { + continue; + } + + + /********************************************************************** + Increment the number of packets we received + *********************************************************************/ + pAdapter->Stats.ipackets++; + + + /********************************************************************** + Set the status on the packet, either resources or success + *********************************************************************/ + if( pAdapter->RxRing.nReadyRecv >= RFD_LOW_WATER_MARK ) + { + /****************************************************************** + Put this RFD on the pending list + + NOTE - nic_rx_pkts() above is already returning the RFD to the + RecvList, so don't additionally do that here. + + Besides, we don't really need (at this point) the pending list + anyway. + *****************************************************************/ + //spin_lock_irqsave( &pAdapter->RcvPendLock, lockflags ); + //list_add_tail( &pMpRfd->list_node, &pAdapter->RxRing.RecvPendingList ); + //spin_unlock_irqrestore( &pAdapter->RcvPendLock, lockflags ); + + + /****************************************************************** + Update the number of outstanding Recvs + *****************************************************************/ + //MP_INC_RCV_REF( pAdapter ); + } + else + { + RFDFreeArray[PacketFreeCount] = pMpRfd; + PacketFreeCount++; + + DBG_WARNING( et131x_dbginfo, "RFD's are running out !!!!!!!!!!!!!\n" ); + } + + PacketArray[PacketArrayCount] = pMpRfd->Packet; + PacketArrayCount++; + } + + + if(( PacketArrayCount == NUM_PACKETS_HANDLED ) || TempUnfinishedRec ) + { + pAdapter->RxRing.UnfinishedReceives = TRUE; + pAdapter->CSRAddress->global.watchdog_timer = + pAdapter->RegistryTxTimeInterval * NANO_IN_A_MICRO; + } + else + { + /********************************************************************** + Watchdog timer will disable itself if appropriate. + *********************************************************************/ + pAdapter->RxRing.UnfinishedReceives = FALSE; + } + + + DBG_RX_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: NICReturnRFD + ****************************************************************************** + DESCRIPTION: + Recycle a RFD and put it back onto the receive list + + PARAMETERS : + pAdapter - pointer to our adapter + pMpRfd - pointer to the RFD + + RETURNS : + NONE + + *****************************************************************************/ +void nic_return_rfd( ET131X_ADAPTER *pAdapter, PMP_RFD pMpRfd ) +{ + UINT16 ReturnedBI = pMpRfd->iBufferIndex; + UINT8 ReturnedRI = pMpRfd->iRingIndex; + unsigned long lockflags; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "nic_return_rfd" ); + DBG_RX_ENTER( et131x_dbginfo ); + + + /************************************************************************** + We don't use any of the OOB data besides status + Otherwise, we need to clean up OOB data + *************************************************************************/ + if( +#ifdef USE_FBR0 + (( ReturnedRI == 0 ) && ( ReturnedBI < pAdapter->RxRing.Fbr0NumEntries )) || +#endif + (( ReturnedRI == 1 ) && ( ReturnedBI < pAdapter->RxRing.Fbr1NumEntries ))) + { + spin_lock_irqsave( &pAdapter->FbrLock, lockflags ); + + if( ReturnedRI == 1 ) + { + PFBR_DESC_t pNextDesc = (PFBR_DESC_t)(pAdapter->RxRing.pFbr1RingVa) + + pAdapter->RxRing.local_Fbr1_full.bits.fbr_full; + + /****************************************************************** + Handle the Free Buffer Ring advancement here. Write the + PA / Buffer Index for the returned buffer into the oldest + (next to be freed)FBR entry + *****************************************************************/ + pNextDesc->addr_hi = pAdapter->RxRing.Fbr[1]->PAHigh[ReturnedBI]; + pNextDesc->addr_lo = pAdapter->RxRing.Fbr[1]->PALow[ReturnedBI]; + pNextDesc->word2.value = ReturnedBI; + + if( ++pAdapter->RxRing.local_Fbr1_full.bits.fbr_full > + ( pAdapter->RxRing.Fbr1NumEntries - 1 )) + { + pAdapter->RxRing.local_Fbr1_full.bits.fbr_full = 0; + pAdapter->RxRing.local_Fbr1_full.bits.fbr_full_wrap ^= 1; + } + + pAdapter->CSRAddress->rxdma.fbr1_full_offset = + pAdapter->RxRing.local_Fbr1_full; + } +#ifdef USE_FBR0 + else + { + PFBR_DESC_t pNextDesc = (PFBR_DESC_t)(pAdapter->RxRing.pFbr0RingVa) + + pAdapter->RxRing.local_Fbr0_full.bits.fbr_full; + + /****************************************************************** + Handle the Free Buffer Ring advancement here. Write the + PA / Buffer Index for the returned buffer into the oldest + (next to be freed) FBR entry + *****************************************************************/ + pNextDesc->addr_hi = pAdapter->RxRing.Fbr[0]->PAHigh[ReturnedBI]; + pNextDesc->addr_lo = pAdapter->RxRing.Fbr[0]->PALow[ReturnedBI]; + pNextDesc->word2.value = ReturnedBI; + + if( ++pAdapter->RxRing.local_Fbr0_full.bits.fbr_full > + (pAdapter->RxRing.Fbr0NumEntries - 1)) + { + pAdapter->RxRing.local_Fbr0_full.bits.fbr_full = 0; + pAdapter->RxRing.local_Fbr0_full.bits.fbr_full_wrap ^= 1; + } + + pAdapter->CSRAddress->rxdma.fbr0_full_offset = + pAdapter->RxRing.local_Fbr0_full; + } +#endif + spin_unlock_irqrestore( &pAdapter->FbrLock, lockflags ); + } + else + { + DBG_ERROR( et131x_dbginfo, + "NICReturnRFD illegal Buffer Index returned\n" ); + } + + + /************************************************************************** + The processing on this RFD is done, so put it back on the tail of + our list + *************************************************************************/ + spin_lock_irqsave( &pAdapter->RcvLock, lockflags ); + + list_add_tail( &pMpRfd->list_node, &pAdapter->RxRing.RecvList ); + pAdapter->RxRing.nReadyRecv++; + + spin_unlock_irqrestore( &pAdapter->RcvLock, lockflags ); + + DBG_ASSERT( pAdapter->RxRing.nReadyRecv <= pAdapter->RxRing.NumRfd ); + + + DBG_RX_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ --- linux-2.6.28.orig/ubuntu/et131x/et131x_netdev.c +++ linux-2.6.28/ubuntu/et131x/et131x_netdev.c @@ -0,0 +1,1624 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_netdev.c - Routines and data required by all Linux network devices. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2007/01/22 23:13:56 $ + $Revision: 1.21 $ + $Name: T_20060131_v1-2-3 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/******************************************************************************* + Includes + ******************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +#include +#endif + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" +#include "ET1310_mac.h" +#include "ET1310_tx.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" +#include "et131x_isr.h" +#include "et131x_initpci.h" + + + + +/****************************************************************************** + Data for debugging facilities + *****************************************************************************/ +#ifdef ET131X_DBG +extern dbg_info_t *et131x_dbginfo; +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + Prototypes for functions with local scope + *****************************************************************************/ +int et131x_init( struct net_device *netdev ); + +int et131x_config( struct net_device *netdev, struct ifmap *map ); + +struct net_device_stats *et131x_stats( struct net_device *netdev ); + +int et131x_open( struct net_device *netdev ); + +int et131x_close( struct net_device *netdev ); + +int et131x_ioctl( struct net_device *netdev, struct ifreq *reqbuf, int cmd ); + +void et131x_multicast( struct net_device *netdev ); + +int et131x_tx( struct sk_buff *skb, struct net_device *netdev ); + +void et131x_tx_timeout( struct net_device *netdev ); + +int et131x_change_mtu( struct net_device *netdev, int new_mtu ); + +int et131x_set_mac_addr( struct net_device *netdev, void *new_mac ); + +void et131x_vlan_rx_register( struct net_device *netdev, struct vlan_group *grp ); + +void et131x_vlan_rx_add_vid( struct net_device *netdev, UINT16 vid ); + +void et131x_vlan_rx_kill_vid( struct net_device *netdev, UINT16 vid ); + + + + +/****************************************************************************** + ROUTINE : et131x_device_alloc() + ****************************************************************************** + + DESCRIPTION : Create instances of net_device and wl_private for the + new adapter and register the device's entry points in + the net_device structure. + + PARAMETERS : N/A + + RETURNS : pointer to the allocated and initialized net_device + struct for this device. + + REUSE INFORMATION : + + *****************************************************************************/ +struct net_device * et131x_device_alloc( void ) +{ + struct net_device *netdev = NULL; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_device_alloc" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Alloc net_device and adapter structs + *************************************************************************/ + netdev = alloc_etherdev( sizeof( ET131X_ADAPTER )); + + if( netdev == NULL ) + { + DBG_ERROR( et131x_dbginfo, + "Alloc of net_device struct failed\n" ); + DBG_LEAVE( et131x_dbginfo ); + return NULL; + } + + + /************************************************************************** + Setup the function registration table (and other data) for a net_device + *************************************************************************/ + //netdev->init = &et131x_init; + netdev->set_config = &et131x_config; + netdev->get_stats = &et131x_stats; + netdev->open = &et131x_open; + netdev->stop = &et131x_close; + netdev->do_ioctl = &et131x_ioctl; + netdev->set_multicast_list = &et131x_multicast; + netdev->hard_start_xmit = &et131x_tx; + netdev->tx_timeout = &et131x_tx_timeout; + netdev->watchdog_timeo = ET131X_TX_TIMEOUT; + netdev->change_mtu = &et131x_change_mtu; + netdev->set_mac_address = &et131x_set_mac_addr; + +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) + netdev->vlan_rx_register = &et131x_vlan_rx_register; + netdev->vlan_rx_add_vid = &et131x_vlan_rx_add_vid; + netdev->vlan_rx_kill_vid = &et131x_vlan_rx_kill_vid; +#endif + + //netdev->ethtool_ops = &et131x_ethtool_ops; + + // Poll? + //netdev->poll = &et131x_poll; + //netdev->poll_controller = &et131x_poll_controller; + + + DBG_LEAVE( et131x_dbginfo ); + return netdev; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_device_free() + ****************************************************************************** + + DESCRIPTION : Free the net_device and adapter private resources for + an adapter and perform basic cleanup. + + PARAMETERS : netdev - a pointer to the net_device structure + representing the device whose resources should + be freed. + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_device_free( struct net_device *netdev ) +{ + + DBG_FUNC( "et131x_device_free" ); + DBG_ENTER( et131x_dbginfo ); + + if( netdev == NULL ) + { + DBG_WARNING( et131x_dbginfo, "Pointer to net_device == NULL\n" ); + DBG_LEAVE( et131x_dbginfo ); + return; + } + else + { + free_netdev( netdev ); + } + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_init + ****************************************************************************** + + DESCRIPTION : This function is called by the kernel to initialize a + device + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device to be initialized. + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : At the moment, this routine does nothing, as most init + processing needs to be performed before this point. + + *****************************************************************************/ +int et131x_init( struct net_device *netdev ) +{ + + DBG_FUNC( "et131x_init" ); + DBG_ENTER( et131x_dbginfo ); + + + DBG_LEAVE( et131x_dbginfo ); + return 0; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_config + ****************************************************************************** + + DESCRIPTION : Implement the SIOCSIFMAP interface. + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device to be configured. + map - a pointer to an ifmap struct + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_config( struct net_device *netdev, struct ifmap *map ) +{ + DBG_FUNC( "et131x_config" ); + DBG_ENTER( et131x_dbginfo ); + + + DBG_LEAVE( et131x_dbginfo ); + return 0; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_stats + ****************************************************************************** + + DESCRIPTION : Return the current device statistics. + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device whose stats are being queried. + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +struct net_device_stats *et131x_stats( struct net_device *netdev ) +{ + ET131X_ADAPTER *adapter = netdev_priv(netdev); + struct net_device_stats *stats = &adapter->net_stats; + CE_STATS_t *devstat = &adapter->Stats; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_stats" ); + DBG_ENTER( et131x_dbginfo ); + + + stats->rx_packets = devstat->ipackets; + stats->tx_packets = devstat->opackets; + stats->rx_errors = devstat->length_err + devstat->alignment_err + + devstat->crc_err + devstat->code_violations + + devstat->other_errors; + stats->tx_errors = devstat->max_pkt_error; + stats->multicast = devstat->multircv; + stats->collisions = devstat->collisions; + + stats->rx_length_errors = devstat->length_err; + stats->rx_over_errors = devstat->rx_ov_flow; + stats->rx_crc_errors = devstat->crc_err; + + // NOTE: These stats don't have corresponding values in CE_STATS, so we're + // going to have to update these directly from within the TX/RX code + //stats->rx_bytes = 20; //devstat->; + //stats->tx_bytes = 20; //devstat->; + //stats->rx_dropped = devstat->; + //stats->tx_dropped = devstat->; + + // NOTE: Not used, can't find analogous statistics + //stats->rx_frame_errors = devstat->; + //stats->rx_fifo_errors = devstat->; + //stats->rx_missed_errors = devstat->; + + //stats->tx_aborted_errors = devstat->; + //stats->tx_carrier_errors = devstat->; + //stats->tx_fifo_errors = devstat->; + //stats->tx_heartbeat_errors = devstat->; + //stats->tx_window_errors = devstat->; + + + DBG_LEAVE( et131x_dbginfo ); + return stats; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_open + ****************************************************************************** + + DESCRIPTION : Open the device for use. + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device to be opened. + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_open( struct net_device *netdev ) +{ + int result = 0; + ET131X_ADAPTER *adapter = NULL; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_open" ); + DBG_ENTER( et131x_dbginfo ); + + + adapter = netdev_priv( netdev ); + + + /************************************************************************** + Start the timer to track NIC errors + *************************************************************************/ + add_timer( &adapter->ErrorTimer ); + + + /************************************************************************** + Register our ISR + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Registering ISR...\n" ); + + result = request_irq( netdev->irq, et131x_isr, IRQF_SHARED, netdev->name, netdev ); + if( result ) + { + DBG_ERROR( et131x_dbginfo, "Could not register ISR\n" ); + DBG_LEAVE( et131x_dbginfo ); + return result; + } + + + /************************************************************************** + Enable the Tx and Rx DMA engines (if not already enabled) + *************************************************************************/ + et131x_rx_dma_enable( adapter ); + et131x_tx_dma_enable( adapter ); + + + /************************************************************************** + Enable device interrupts + *************************************************************************/ + et131x_enable_interrupts( adapter ); + + MP_SET_FLAG( adapter, fMP_ADAPTER_INTERRUPT_IN_USE ); + + + /************************************************************************** + We're ready to move some data, so start the queue + *************************************************************************/ + netif_start_queue( netdev ); + + + DBG_LEAVE( et131x_dbginfo ); + return result; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_close + ****************************************************************************** + + DESCRIPTION : Close the device. + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device to be opened. + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_close( struct net_device *netdev ) +{ + ET131X_ADAPTER *adapter = NULL; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_close" ); + DBG_ENTER( et131x_dbginfo ); + + + adapter = netdev_priv( netdev ); + + + /************************************************************************** + First thing is to stop the queue + *************************************************************************/ + netif_stop_queue( netdev ); + + + /************************************************************************** + Stop the Tx and Rx DMA engines + *************************************************************************/ + et131x_rx_dma_disable( adapter ); + et131x_tx_dma_disable( adapter ); + + + /************************************************************************** + Disable device interrupts + *************************************************************************/ + et131x_disable_interrupts( adapter ); + + + /************************************************************************** + Deregistering ISR + *************************************************************************/ + MP_CLEAR_FLAG( adapter, fMP_ADAPTER_INTERRUPT_IN_USE ); + + DBG_TRACE( et131x_dbginfo, "Deregistering ISR...\n" ); + free_irq( netdev->irq, netdev ); + + + /************************************************************************** + Stop the error timer + *************************************************************************/ + del_timer_sync( &adapter->ErrorTimer ); + + + DBG_LEAVE( et131x_dbginfo ); + return 0; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_ioctl_mii + ****************************************************************************** + + DESCRIPTION : The function which handles MII IOCTLs + + PARAMETERS : netdev - the net_device struct corresponding to the + device on which the query is being made + reqbuf - the request-specific data buffer + cmd - the command request code + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_ioctl_mii( struct net_device *netdev, struct ifreq *reqbuf, int cmd ) +{ + int status = 0; + ET131X_ADAPTER *pAdapter = netdev_priv(netdev); + struct mii_ioctl_data *data = if_mii( reqbuf ); + UINT16 mii_reg; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_ioctl_mii" ); + DBG_ENTER( et131x_dbginfo ); + + + switch( cmd ) + { + case SIOCGMIIPHY: + DBG_VERBOSE( et131x_dbginfo, "SIOCGMIIPHY\n" ); + data->phy_id = pAdapter->Stats.xcvr_addr; + break; + + + case SIOCGMIIREG: + DBG_VERBOSE( et131x_dbginfo, "SIOCGMIIREG\n" ); + if( !capable( CAP_NET_ADMIN )) + { + status = -EPERM; + } + else + { + status = MiRead( pAdapter, + pAdapter->Stats.xcvr_addr, + data->reg_num, + &data->val_out ); + } + + break; + + + case SIOCSMIIREG: + DBG_VERBOSE( et131x_dbginfo, "SIOCSMIIREG\n" ); + if( !capable( CAP_NET_ADMIN )) + { + status = -EPERM; + } + else + { + mii_reg = data->val_in; + + status = MiWrite( pAdapter, + pAdapter->Stats.xcvr_addr, + data->reg_num, + mii_reg ); + } + + break; + + + default: + status = -EOPNOTSUPP; + } + + + DBG_LEAVE( et131x_dbginfo ); + return status; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_ioctl + ****************************************************************************** + + DESCRIPTION : The I/O Control handler for the driver. + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device on which the control request is + being made. + reqbuf - a pointer to the IOCTL request buffer. + cmd - the IOCTL command code. + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_ioctl( struct net_device *netdev, struct ifreq *reqbuf, int cmd ) +{ + int status = 0; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_ioctl" ); + DBG_ENTER( et131x_dbginfo ); + + + switch( cmd ) + { + case SIOCGMIIPHY: + case SIOCGMIIREG: + case SIOCSMIIREG: + status = et131x_ioctl_mii( netdev, reqbuf, cmd ); + break; + + default: +/* DBG_WARNING( et131x_dbginfo, "Unhandled IOCTL Code: 0x%04x\n", cmd );*/ + status = -EOPNOTSUPP; + } + + + DBG_LEAVE( et131x_dbginfo ); + return status; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_set_packet_filter + ****************************************************************************** + + DESCRIPTION : Configures the Rx Packet filtering on the device + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : 0 on success, errno on failure + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_set_packet_filter( ET131X_ADAPTER *adapter ) +{ + int status = 0; + UINT32 filter = adapter->PacketFilter; + RXMAC_CTRL_t ctrl = adapter->CSRAddress->rxmac.ctrl; + RXMAC_PF_CTRL_t pf_ctrl = adapter->CSRAddress->rxmac.pf_ctrl; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_set_packet_filter" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Default to disabled packet filtering. Enable it in the individual case + statements that require the device to filter something + *************************************************************************/ + ctrl.bits.pkt_filter_disable = 1; + + + /************************************************************************** + Set us to be in promiscuous mode so we receive everything, + this is also true when we get a packet filter of 0 + *************************************************************************/ + if(( filter & ET131X_PACKET_TYPE_PROMISCUOUS ) || filter == 0 ) + { + pf_ctrl.bits.filter_broad_en = 0; + pf_ctrl.bits.filter_multi_en = 0; + pf_ctrl.bits.filter_uni_en = 0; + } + else + { + /********************************************************************** + Set us up with Multicast packet filtering. Three cases are + possible - (1) we have a multi-cast list, (2) we receive ALL + multicast entries or (3) we receive none. + *********************************************************************/ + if( filter & ET131X_PACKET_TYPE_ALL_MULTICAST ) + { + DBG_VERBOSE( et131x_dbginfo, + "Multicast filtering OFF (Rx ALL MULTICAST)\n" ); + pf_ctrl.bits.filter_multi_en = 0; + } + else + { + DBG_VERBOSE( et131x_dbginfo, "Multicast filtering ON\n" ); + SetupDeviceForMulticast( adapter ); + pf_ctrl.bits.filter_multi_en = 1; + ctrl.bits.pkt_filter_disable = 0; + } + + + /********************************************************************** + Set us up with Unicast packet filtering + *********************************************************************/ + if( filter & ET131X_PACKET_TYPE_DIRECTED ) + { + DBG_VERBOSE( et131x_dbginfo, "Unicast Filtering ON\n" ); + SetupDeviceForUnicast( adapter ); + pf_ctrl.bits.filter_uni_en = 1; + ctrl.bits.pkt_filter_disable = 0; + } + + + /********************************************************************** + Set us up with Broadcast packet filtering + *********************************************************************/ + if( filter & ET131X_PACKET_TYPE_BROADCAST ) + { + DBG_VERBOSE( et131x_dbginfo, "Broadcast Filtering ON\n" ); + pf_ctrl.bits.filter_broad_en = 1; + ctrl.bits.pkt_filter_disable = 0; + } + else + { + DBG_VERBOSE( et131x_dbginfo, "Broadcast Filtering OFF\n" ); + pf_ctrl.bits.filter_broad_en = 0; + } + + + /********************************************************************** + Setup the receive mac configuration registers - Packet Filter + control + the enable / disable for packet filter in the control + reg. + *********************************************************************/ + adapter->CSRAddress->rxmac.pf_ctrl.value = pf_ctrl.value; + adapter->CSRAddress->rxmac.ctrl = ctrl; + } + + DBG_LEAVE( et131x_dbginfo ); + return status; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_multicast + ****************************************************************************** + + DESCRIPTION : The handler to configure multicasting on the interface. + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device. + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_multicast( struct net_device *netdev ) +{ + ET131X_ADAPTER *adapter = NULL; + UINT32 PacketFilter = 0; + UINT32 count; + unsigned long lockflags; + struct dev_mc_list *mclist = netdev->mc_list; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_multicast" ); + DBG_ENTER( et131x_dbginfo ); + + + adapter = netdev_priv( netdev ); + + + spin_lock_irqsave( &adapter->Lock, lockflags ); + + + /************************************************************************** + Before we modify the platform-independent filter flags, store them + locally. This allows us to determine if anything's changed and if we + even need to bother the hardware + *************************************************************************/ + PacketFilter = adapter->PacketFilter; + + + /************************************************************************** + Clear the 'multicast' flag locally; becuase we only have a single flag + to check multicast, and multiple multicast addresses can be set, this is + the easiest way to determine if more than one multicast address is being + set. + *************************************************************************/ + PacketFilter &= ~ET131X_PACKET_TYPE_MULTICAST; + + + /************************************************************************** + Check the net_device flags and set the device independent flags + accordingly + *************************************************************************/ + DBG_VERBOSE( et131x_dbginfo, + "MULTICAST ADDR COUNT: %d\n", + netdev->mc_count ); + + if( netdev->flags & IFF_PROMISC ) + { + DBG_VERBOSE( et131x_dbginfo, "Request: PROMISCUOUS MODE ON\n" ); + adapter->PacketFilter |= ET131X_PACKET_TYPE_PROMISCUOUS; + } + else + { + DBG_VERBOSE( et131x_dbginfo, "Request: PROMISCUOUS MODE OFF\n" ); + adapter->PacketFilter &= ~ET131X_PACKET_TYPE_PROMISCUOUS; + } + + + if( netdev->flags & IFF_ALLMULTI ) + { + DBG_VERBOSE( et131x_dbginfo, "Request: ACCEPT ALL MULTICAST\n" ); + adapter->PacketFilter |= ET131X_PACKET_TYPE_ALL_MULTICAST; + } + + + if( netdev->mc_count > NIC_MAX_MCAST_LIST ) + { + DBG_WARNING( et131x_dbginfo, + "ACCEPT ALL MULTICAST for now, as there's more Multicast " + "addresses than the HW supports\n" ); + + adapter->PacketFilter |= ET131X_PACKET_TYPE_ALL_MULTICAST; + } + + + if( netdev->mc_count < 1 ) + { + DBG_VERBOSE( et131x_dbginfo, "Request: REJECT ALL MULTICAST\n" ); + adapter->PacketFilter &= ~ET131X_PACKET_TYPE_ALL_MULTICAST; + adapter->PacketFilter &= ~ET131X_PACKET_TYPE_MULTICAST; + } + else + { + DBG_VERBOSE( et131x_dbginfo, "Request: SET MULTICAST FILTER(S)\n" ); + adapter->PacketFilter |= ET131X_PACKET_TYPE_MULTICAST; + } + + + /************************************************************************** + Set values in the private adapter struct + *************************************************************************/ + adapter->MCAddressCount = netdev->mc_count; + + if( netdev->mc_count ) + { + if( mclist->dmi_addrlen != ETH_ALEN ) + { + DBG_WARNING( et131x_dbginfo, "Multicast addrs are not ETH_ALEN in size\n" ); + } + else + { + count = netdev->mc_count - 1; + memcpy( adapter->MCList[count], mclist->dmi_addr, ETH_ALEN ); + } + } + + + /************************************************************************** + Are the new flags different from the previous ones? If not, then no + action is required + + NOTE - This block will always update the MCList with the hardware, even + if the addresses aren't the same. + *************************************************************************/ + if( PacketFilter != adapter->PacketFilter ) + { + /********************************************************************** + Call the device's filter function + *********************************************************************/ + DBG_VERBOSE( et131x_dbginfo, + "UPDATE REQUIRED, FLAGS changed\n" ); + + et131x_set_packet_filter( adapter ); + } + else + { + DBG_VERBOSE( et131x_dbginfo, + "NO UPDATE REQUIRED, FLAGS didn't change\n" ); + } + + + spin_unlock_irqrestore( &adapter->Lock, lockflags ); + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_tx + ****************************************************************************** + + DESCRIPTION : The handler called when the Linux network layer wants + to a Tx a packet on the device. + + PARAMETERS : skb - a pointer to the sk_buff structure which + represents the data to be Tx'd. + netdev - a pointer to a net_device struct representing + the device on which data is to be Tx'd. + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_tx( struct sk_buff *skb, struct net_device *netdev ) +{ + int status = 0; + ET131X_ADAPTER *adapter; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_tx" ); + DBG_TX_ENTER( et131x_dbginfo ); + + + adapter = netdev_priv( netdev ); + + + /************************************************************************** + Save the timestamp for the TX timeout watchdog + *************************************************************************/ + netdev->trans_start = jiffies; + + + /************************************************************************** + Call the device-specific data Tx routine + *************************************************************************/ + status = et131x_send_packets( skb, netdev ); + + + /************************************************************************** + Check status and manage the netif queue if necessary + *************************************************************************/ + if( status != 0 ) + { + if( status == -ENOMEM ) + { + DBG_VERBOSE( et131x_dbginfo, "OUT OF TCBs; STOP NETIF QUEUE\n" ); + + /* Put the queue to sleep until resources are available */ + netif_stop_queue( netdev ); + status = 1; + } + else + { + DBG_WARNING( et131x_dbginfo, "Misc error; drop packet\n" ); + status = 0; + } + } + + DBG_TX_LEAVE( et131x_dbginfo ); + return status; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_tx_timeout + ****************************************************************************** + + DESCRIPTION : The handler called when a Tx request times out. The + timeout period is specified by the 'tx_timeo" element in + the net_device structure (see et131x_alloc_device() to + see how this value is set). + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device. + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_tx_timeout( struct net_device *netdev ) +{ + ET131X_ADAPTER *pAdapter = netdev_priv( netdev ); + PMP_TCB pMpTcb; + unsigned long lockflags; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_tx_timeout" ); + DBG_WARNING( et131x_dbginfo, "TX TIMEOUT\n" ); + + + /************************************************************************** + Just skip this part if the adapter is doing link detection + *************************************************************************/ + if( MP_TEST_FLAG( pAdapter, fMP_ADAPTER_LINK_DETECTION )) + { + DBG_ERROR( et131x_dbginfo, "Still doing link detection\n" ); + return; + } + + + /************************************************************************** + Any nonrecoverable hardware error? + Checks adapter->flags for any failure in phy reading + *************************************************************************/ + if( MP_TEST_FLAG( pAdapter, fMP_ADAPTER_NON_RECOVER_ERROR )) + { + DBG_WARNING( et131x_dbginfo, "Non recoverable error - remove\n" ); + return; + } + + + /************************************************************************** + Hardware failure? + *************************************************************************/ + if( MP_TEST_FLAG( pAdapter, fMP_ADAPTER_HARDWARE_ERROR )) + { + DBG_WARNING( et131x_dbginfo, "hardware error - reset\n" ); + return; + } + + /************************************************************************** + Is send stuck? + *************************************************************************/ + spin_lock_irqsave( &pAdapter->TCBSendQLock, lockflags ); + + pMpTcb = pAdapter->TxRing.CurrSendHead; + + if( pMpTcb != NULL ) + { + pMpTcb->Count++; + + if( pMpTcb->Count > NIC_SEND_HANG_THRESHOLD ) + { +#ifdef ET131X_DBG + TX_STATUS_BLOCK_t txDmaComplete = *( pAdapter->TxRing.pTxStatusVa ); + PTX_DESC_ENTRY_t pDesc = pAdapter->TxRing.pTxDescRingVa + + pMpTcb->WrIndex.bits.serv_req; +#endif + TX_DESC_ENTRY_t StuckDescriptors[10]; + + if( pMpTcb->WrIndex.bits.serv_req > 7 ) + { + memcpy( StuckDescriptors, + pAdapter->TxRing.pTxDescRingVa + pMpTcb->WrIndex.bits.serv_req - 6, + sizeof( TX_DESC_ENTRY_t ) * 10 ); + } + + spin_unlock_irqrestore( &pAdapter->TCBSendQLock, lockflags ); + + DBG_WARNING( et131x_dbginfo, + "Send stuck - reset. pMpTcb->WrIndex %x, Flags 0x%08x\n", + pMpTcb->WrIndex.bits.serv_req, pMpTcb->Flags ); + + DBG_WARNING( et131x_dbginfo, + "pDesc 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", + pDesc->DataBufferPtrHigh, pDesc->DataBufferPtrLow, + pDesc->word2.value, pDesc->word3.value ); + + DBG_WARNING( et131x_dbginfo, + "WbStatus 0x%08x\n", + txDmaComplete.value ); + +#ifdef ET131X_DBG + DumpDeviceBlock( DBG_WARNING_ON, pAdapter, 0 ); + DumpDeviceBlock( DBG_WARNING_ON, pAdapter, 1 ); + DumpDeviceBlock( DBG_WARNING_ON, pAdapter, 3 ); + DumpDeviceBlock( DBG_WARNING_ON, pAdapter, 5 ); +#endif + et131x_close( netdev ); + et131x_open( netdev ); + + return; + } + } + + spin_unlock_irqrestore( &pAdapter->TCBSendQLock, lockflags ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_change_mtu + ****************************************************************************** + + DESCRIPTION : The handler called to change the MTU for the device. + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device whose MTU is to be changed. + + new_mtu - the desired MTU. + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_change_mtu( struct net_device *netdev, int new_mtu ) +{ + int result = 0; + ET131X_ADAPTER *adapter = NULL; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_change_mtu" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Get the private adapter structure + *************************************************************************/ + adapter = netdev_priv( netdev ); + + if( adapter == NULL ) + { + DBG_LEAVE( et131x_dbginfo ); + return -ENODEV; + } + + + /************************************************************************** + Make sure the requested MTU is valid + *************************************************************************/ + if( new_mtu == 0 || new_mtu > 9216 ) + { + DBG_LEAVE( et131x_dbginfo ); + return -EINVAL; + } + + + /************************************************************************** + Stop the netif queue + *************************************************************************/ + netif_stop_queue( netdev ); + + + /************************************************************************** + Stop the Tx and Rx DMA engines + *************************************************************************/ + et131x_rx_dma_disable( adapter ); + et131x_tx_dma_disable( adapter ); + + + /************************************************************************** + Disable device interrupts + *************************************************************************/ + et131x_disable_interrupts( adapter ); + et131x_handle_send_interrupt( adapter ); + et131x_handle_recv_interrupt( adapter ); + + + /************************************************************************** + Set the new MTU + *************************************************************************/ + netdev->mtu = new_mtu; + + + /************************************************************************** + Free Rx DMA memory + *************************************************************************/ + et131x_adapter_memory_free( adapter ); + + + /************************************************************************** + Set the config parameter for Jumbo Packet support + *************************************************************************/ + adapter->RegistryJumboPacket = new_mtu + 14; + et131x_soft_reset( adapter ); + + + /************************************************************************** + Alloc and init Rx DMA memory + *************************************************************************/ + result = et131x_adapter_memory_alloc( adapter ); + if( result != 0 ) + { + DBG_WARNING( et131x_dbginfo, + "Change MTU failed; couldn't re-alloc DMA memory\n" ); + return result; + } + + et131x_init_send( adapter ); + + + et131x_setup_hardware_properties( adapter ); + memcpy( netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN ); + et131x_init_enet_crc_calc( ); + + + /************************************************************************** + Init the device with the new settings + *************************************************************************/ + et131x_adapter_setup( adapter ); + + + /************************************************************************** + Enable interrupts + *************************************************************************/ + if( MP_TEST_FLAG( adapter, fMP_ADAPTER_INTERRUPT_IN_USE )) + { + et131x_enable_interrupts( adapter ); + } + + + /************************************************************************** + Restart the Tx and Rx DMA engines + *************************************************************************/ + et131x_rx_dma_enable( adapter ); + et131x_tx_dma_enable( adapter ); + + + /************************************************************************** + Restart the netif queue + *************************************************************************/ + netif_wake_queue( netdev ); + + + DBG_LEAVE( et131x_dbginfo ); + return result; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_set_mac_addr + ****************************************************************************** + + DESCRIPTION : The handler called to change the MAC address for the + device. + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device whose MAC is to be changed. + + new_mac - a buffer containing a sock_addr struct in which + the desired MAC address is stored. + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + IMPLEMENTED BY : blux http://berndlux.de 22.01.2007 21:14 + + *****************************************************************************/ +int et131x_set_mac_addr( struct net_device *netdev, void *new_mac ) +{ + int result = 0; + ET131X_ADAPTER *adapter = NULL; + struct sockaddr *address = new_mac; + + DBG_FUNC( "et131x_set_mac_addr" ); + DBG_ENTER( et131x_dbginfo ); + // begin blux + // DBG_VERBOSE( et131x_dbginfo, "Function not implemented!!\n" ); + + /*-----------------------------------------------------------------------*/ + + + /************************************************************************** + Get the private adapter structure + *************************************************************************/ + adapter = netdev_priv( netdev ); + + if( adapter == NULL ) + { + DBG_LEAVE( et131x_dbginfo ); + return -ENODEV; + } + + + /************************************************************************** + Make sure the requested MAC is valid + *************************************************************************/ + if (!is_valid_ether_addr(address->sa_data)) + { + DBG_LEAVE( et131x_dbginfo ); + return -EINVAL; + } + + + /************************************************************************** + Stop the netif queue + *************************************************************************/ + netif_stop_queue( netdev ); + + + /************************************************************************** + Stop the Tx and Rx DMA engines + *************************************************************************/ + et131x_rx_dma_disable( adapter ); + et131x_tx_dma_disable( adapter ); + + + /************************************************************************** + Disable device interrupts + *************************************************************************/ + et131x_disable_interrupts( adapter ); + et131x_handle_send_interrupt( adapter ); + et131x_handle_recv_interrupt( adapter ); + + + /************************************************************************** + Set the new MAC + *************************************************************************/ + // netdev->set_mac_address = &new_mac; + // netdev->mtu = new_mtu; + + + memcpy(netdev->dev_addr, address->sa_data, netdev->addr_len); + + printk("%s: Setting MAC address to %02x:%02x:%02x:%02x:%02x:%02x\n", netdev->name, + netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2], + netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]); + + + /************************************************************************** + Free Rx DMA memory + *************************************************************************/ + et131x_adapter_memory_free( adapter ); + + + /************************************************************************** + Set the config parameter for Jumbo Packet support + *************************************************************************/ + //adapter->RegistryJumboPacket = new_mtu + 14; + // blux: not needet here, w'll change the MAC + + et131x_soft_reset( adapter ); + + + /************************************************************************** + Alloc and init Rx DMA memory + *************************************************************************/ + result = et131x_adapter_memory_alloc( adapter ); + if( result != 0 ) + { + DBG_WARNING( et131x_dbginfo, + "Change MAC failed; couldn't re-alloc DMA memory\n" ); + return result; + } + + et131x_init_send( adapter ); + + + et131x_setup_hardware_properties( adapter ); + // memcpy( netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN ); + // blux: no, do not override our nice address + et131x_init_enet_crc_calc( ); + + + /************************************************************************** + Init the device with the new settings + *************************************************************************/ + et131x_adapter_setup( adapter ); + + + /************************************************************************** + Enable interrupts + *************************************************************************/ + if( MP_TEST_FLAG( adapter, fMP_ADAPTER_INTERRUPT_IN_USE )) + { + et131x_enable_interrupts( adapter ); + } + + + /************************************************************************** + Restart the Tx and Rx DMA engines + *************************************************************************/ + et131x_rx_dma_enable( adapter ); + et131x_tx_dma_enable( adapter ); + + + /************************************************************************** + Restart the netif queue + *************************************************************************/ + netif_wake_queue( netdev ); + + + + DBG_LEAVE( et131x_dbginfo ); + return result; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + NOTE: The ET1310 doesn't support hardware VLAN tagging, so these functions + are currently not used; they are in place to eventually support the + feature if needed. + *****************************************************************************/ + +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) + +/****************************************************************************** + ROUTINE : et131x_vlan_rx_register + ****************************************************************************** + + DESCRIPTION : The handler called to enable or disable VLAN support on + the device. + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device on which VLAN should be enabled or + disabled. + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_vlan_rx_register( struct net_device *netdev, struct vlan_group *grp ) +{ + ET131X_ADAPTER *pAdapter = netdev_priv( netdev ); + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_vlan_rx_register" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Track the vlan_group struct in the adapter private structure; if this + element is NULL, then VLAN is disabled; otherwise, it is enabled. + *************************************************************************/ + if( grp ) + { + DBG_VERBOSE( et131x_dbginfo, "VLAN: Enable, 0x%p\n", grp ); + } + else + { + DBG_VERBOSE( et131x_dbginfo, "VLAN: Disable\n" ); + } + + pAdapter->vlgrp = grp; + + + /************************************************************************** + This is where any interfacing with the hardware to enable or disable + VLAN would be done. Since the ET1310 doesn't handle this in hardware, + nothing else needs to be done. + *************************************************************************/ + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_vlan_rx_add_vid + ****************************************************************************** + + DESCRIPTION : The handler called to register a VLAN tag. + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device on which a VLAN tag should be added. + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_vlan_rx_add_vid( struct net_device *netdev, UINT16 vid ) +{ + DBG_FUNC( "et131x_vlan_rx_add_vid" ); + DBG_ENTER( et131x_dbginfo ); + + + DBG_VERBOSE( et131x_dbginfo, "VLAN, Add VID: %d\n", vid ); + + + /************************************************************************** + This is where any interfacing with the hardware to register VLAN IDs + would take place. Since the ET1310 doesn't handle this in hardware, + nothing else needs to be done here; the vlan_group structure's + vlan_devices element can be used in the TX/RX routines to determine if + a VLAN tag has been 'registered' with the device. + *************************************************************************/ + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_vlan_rx_kill_vid + ****************************************************************************** + + DESCRIPTION : The handler called to deregister a VLAN tag. + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device on which a VLAN tag should be + removed. + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_vlan_rx_kill_vid( struct net_device *netdev, UINT16 vid ) +{ + ET131X_ADAPTER *pAdapter = netdev_priv( netdev ); + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_vlan_rx_kill_vid" ); + DBG_ENTER( et131x_dbginfo ); + + + DBG_VERBOSE( et131x_dbginfo, "VLAN, Remove VID: %d\n", vid ); + + if( pAdapter->vlgrp ) + { + pAdapter->vlgrp->vlan_devices_arrays[vid] = NULL; + } + + + /************************************************************************** + This is where any interfacing with the hardware to deregister VLAN IDs + would take place. Since the ET1310 doesn't handle this in hardware, + nothing else needs to be done here. + *************************************************************************/ + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + +#endif --- linux-2.6.28.orig/ubuntu/et131x/BOM +++ linux-2.6.28/ubuntu/et131x/BOM @@ -0,0 +1,2 @@ +Downloaded from: http://sourceforge.net/project/platformdownload.php?group_id=179406 +Current Version: 1.2.3-3 --- linux-2.6.28.orig/ubuntu/et131x/ET1310_mac.h +++ linux-2.6.28/ubuntu/et131x/ET1310_mac.h @@ -0,0 +1,140 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_mac.h - Defines, structs, enums, prototypes, etc. pertaining to the + * MAC. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/08/01 19:35:11 $ + $Revision: 1.5 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef _ET1310_MAC_H_ +#define _ET1310_MAC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/****************************************************************************** + INCLUDES + *****************************************************************************/ +#include "ET1310_common.h" + + + + +/****************************************************************************** + MACSTAT #defines + *****************************************************************************/ +#define COUNTER_WRAP_28_BIT 0x10000000 +#define COUNTER_WRAP_22_BIT 0x400000 +#define COUNTER_WRAP_16_BIT 0x10000 +#define COUNTER_WRAP_12_BIT 0x1000 + +#define COUNTER_MASK_28_BIT (COUNTER_WRAP_28_BIT - 1) +#define COUNTER_MASK_22_BIT (COUNTER_WRAP_22_BIT - 1) +#define COUNTER_MASK_16_BIT (COUNTER_WRAP_16_BIT - 1) +#define COUNTER_MASK_12_BIT (COUNTER_WRAP_12_BIT - 1) + +#define UPDATE_COUNTER(HostCnt,DevCnt) \ + HostCnt = HostCnt + DevCnt; + + + + +/****************************************************************************** + Forward declaration of the private adapter structure + *****************************************************************************/ +struct et131x_adapter; + + +/****************************************************************************** + PROTOTYPES + *****************************************************************************/ +void ConfigMACRegs1( struct et131x_adapter *pAdapter ); +void ConfigMACRegs2( struct et131x_adapter *pAdapter ); +void ConfigRxMacRegs( struct et131x_adapter *pAdapter ); +void ConfigTxMacRegs( struct et131x_adapter *pAdapter ); +void ConfigMacStatRegs( struct et131x_adapter *pAdapter ); +void ConfigFlowControl( struct et131x_adapter *pAdapter ); +void UpdateMacStatHostCounters( struct et131x_adapter *pAdapter ); +void HandleMacStatInterrupt( struct et131x_adapter *pAdapter ); +void SetupDeviceForMulticast( struct et131x_adapter *pAdapter ); +void SetupDeviceForUnicast( struct et131x_adapter *pAdapter ); + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ET1310_MAC_H_ */ --- linux-2.6.28.orig/ubuntu/et131x/ET1310_common.h +++ linux-2.6.28/ubuntu/et131x/ET1310_common.h @@ -0,0 +1,97 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310.h - Common defines, structs, enums, prototypes, etc. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, 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 as comments in the code as + * well as 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. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS 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, INCLUDING, BUT NOT LIMITED TO, 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. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/08/01 19:35:10 $ + $Revision: 1.5 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET1310_COMMON_H__ +#define __ET1310_COMMON_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/****************************************************************************** + INCLUDES + *****************************************************************************/ +#include "ET1310_address_map.h" + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __ET1310_COMMON_H__ */ --- linux-2.6.28.orig/ubuntu/misc/tp_smapi.c +++ linux-2.6.28/ubuntu/misc/tp_smapi.c @@ -0,0 +1,1477 @@ +/* + * tp_smapi.c - ThinkPad SMAPI support + * + * This driver exposes some features of the System Management Application + * Program Interface (SMAPI) BIOS found on ThinkPad laptops. It works on + * models in which the SMAPI BIOS runs in SMM and is invoked by writing + * to the APM control port 0xB2. Older models use a different interface; + * for those, try the out-of-tree "thinkpad" module from "tpctl". + * It also exposes battery status information, obtained from the ThinkPad + * embedded controller (via the thinkpad_ec module). + * + * Many of the battery status values obtained from the EC simply mirror + * values provided by the battery's Smart Battery System (SBS) interface, so + * their meaning is defined by the Smart Battery Data Specification. + * References to this SBS spec are given in the code where relevant. + * + * Copyright (C) 2006 Shem Multinymous . + * SMAPI access code based on the mwave driver by Mike Sullivan. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 /* CMOS defines */ +#include +#include +#include "thinkpad_ec.h" +#include +#include +#include + +#define TP_VERSION "0.37" +#define TP_DESC "ThinkPad SMAPI Support" +#define TP_DIR "smapi" + +MODULE_AUTHOR("Shem Multinymous"); +MODULE_DESCRIPTION(TP_DESC); +MODULE_VERSION(TP_VERSION); +MODULE_LICENSE("GPL"); + +static struct platform_device *pdev; + +static int tp_debug; +module_param_named(debug, tp_debug, int, 0600); +MODULE_PARM_DESC(debug, "Debug level (0=off, 1=on)"); + +/* A few macros for printk()ing: */ +#define TPRINTK(level, fmt, args...) \ + dev_printk(level, &(pdev->dev), "%s: " fmt "\n", __func__, ## args) +#define DPRINTK(fmt, args...) \ + do { if (tp_debug) TPRINTK(KERN_DEBUG, fmt, ## args); } while (0) + +/********************************************************************* + * SMAPI interface + */ + +/* SMAPI functions (register BX when making the SMM call). */ +#define SMAPI_GET_INHIBIT_CHARGE 0x2114 +#define SMAPI_SET_INHIBIT_CHARGE 0x2115 +#define SMAPI_GET_THRESH_START 0x2116 +#define SMAPI_SET_THRESH_START 0x2117 +#define SMAPI_GET_FORCE_DISCHARGE 0x2118 +#define SMAPI_SET_FORCE_DISCHARGE 0x2119 +#define SMAPI_GET_THRESH_STOP 0x211a +#define SMAPI_SET_THRESH_STOP 0x211b + +/* SMAPI error codes (see ThinkPad 770 Technical Reference Manual p.83 at + http://www-307.ibm.com/pc/support/site.wss/document.do?lndocid=PFAN-3TUQQD */ +#define SMAPI_RETCODE_EOF 0xff +static struct { u8 rc; char *msg; int ret; } smapi_retcode[] = +{ + {0x00, "OK", 0}, + {0x53, "SMAPI fuction is not available", -ENXIO}, + {0x81, "Invalid parameter", -EINVAL}, + {0x86, "Function is not supported by SMAPI BIOS", -EOPNOTSUPP}, + {0x90, "System error", -EIO}, + {0x91, "System is invalid", -EIO}, + {0x92, "System is busy, -EBUSY"}, + {0xa0, "Device error (disk read error)", -EIO}, + {0xa1, "Device is busy", -EBUSY}, + {0xa2, "Device is not attached", -ENXIO}, + {0xa3, "Device is disbled", -EIO}, + {0xa4, "Request parameter is out of range", -EINVAL}, + {0xa5, "Request parameter is not accepted", -EINVAL}, + {0xa6, "Transient error", -EBUSY}, /* ? */ + {SMAPI_RETCODE_EOF, "Unknown error code", -EIO} +}; + + +#define SMAPI_MAX_RETRIES 10 +#define SMAPI_PORT2 0x4F /* fixed port, meaning unclear */ +static unsigned short smapi_port; /* APM control port, normally 0xB2 */ + +static DECLARE_MUTEX(smapi_mutex); + +/** + * find_smapi_port - read SMAPI port from NVRAM + */ +static int __init find_smapi_port(void) +{ + u16 smapi_id = 0; + unsigned short port = 0; + unsigned long flags; + + spin_lock_irqsave(&rtc_lock, flags); + smapi_id = CMOS_READ(0x7C); + smapi_id |= (CMOS_READ(0x7D) << 8); + spin_unlock_irqrestore(&rtc_lock, flags); + + if (smapi_id != 0x5349) { + printk(KERN_ERR "SMAPI not supported (ID=0x%x)\n", smapi_id); + return -ENXIO; + } + spin_lock_irqsave(&rtc_lock, flags); + port = CMOS_READ(0x7E); + port |= (CMOS_READ(0x7F) << 8); + spin_unlock_irqrestore(&rtc_lock, flags); + if (port == 0) { + printk(KERN_ERR "unable to read SMAPI port number\n"); + return -ENXIO; + } + return port; +} + +/** + * smapi_request - make a SMAPI call + * @inEBX, @inECX, @inEDI, @inESI: input registers + * @outEBX, @outECX, @outEDX, @outEDI, @outESI: outputs registers + * @msg: textual error message + * Invokes the SMAPI SMBIOS with the given input and outpu args. + * All outputs are optional (can be %NULL). + * Returns 0 when successful, and a negative errno constant + * (see smapi_retcode above) upon failure. + */ +static int smapi_request(u32 inEBX, u32 inECX, + u32 inEDI, u32 inESI, + u32 *outEBX, u32 *outECX, u32 *outEDX, + u32 *outEDI, u32 *outESI, const char **msg) +{ + int ret = 0; + int i; + int retries; + u8 rc; + /* Must use local vars for output regs, due to reg pressure. */ + u32 tmpEAX, tmpEBX, tmpECX, tmpEDX, tmpEDI, tmpESI; + + for (retries = 0; retries < SMAPI_MAX_RETRIES; ++retries) { + DPRINTK("req_in: BX=%x CX=%x DI=%x SI=%x", + inEBX, inECX, inEDI, inESI); + + /* SMAPI's SMBIOS call and thinkpad_ec end up using use + * different interfaces to the same chip, so play it safe. */ + ret = thinkpad_ec_lock(); + if (ret) + return ret; + + __asm__ __volatile__( + "movl $0x00005380,%%eax\n\t" + "movl %6,%%ebx\n\t" + "movl %7,%%ecx\n\t" + "movl %8,%%edi\n\t" + "movl %9,%%esi\n\t" + "xorl %%edx,%%edx\n\t" + "movw %10,%%dx\n\t" + "out %%al,%%dx\n\t" /* trigger SMI to SMBIOS */ + "out %%al,$0x4F\n\t" + "movl %%eax,%0\n\t" + "movl %%ebx,%1\n\t" + "movl %%ecx,%2\n\t" + "movl %%edx,%3\n\t" + "movl %%edi,%4\n\t" + "movl %%esi,%5\n\t" + :"=m"(tmpEAX), + "=m"(tmpEBX), + "=m"(tmpECX), + "=m"(tmpEDX), + "=m"(tmpEDI), + "=m"(tmpESI) + :"m"(inEBX), "m"(inECX), "m"(inEDI), "m"(inESI), + "m"((u16)smapi_port) + :"%eax", "%ebx", "%ecx", "%edx", "%edi", + "%esi"); + + thinkpad_ec_invalidate(); + thinkpad_ec_unlock(); + + /* Don't let the next SMAPI access happen too quickly, + * may case problems. (We're hold smapi_mutex). */ + msleep(50); + + if (outEBX) *outEBX = tmpEBX; + if (outECX) *outECX = tmpECX; + if (outEDX) *outEDX = tmpEDX; + if (outESI) *outESI = tmpESI; + if (outEDI) *outEDI = tmpEDI; + + /* Look up error code */ + rc = (tmpEAX>>8)&0xFF; + for (i = 0; smapi_retcode[i].rc != SMAPI_RETCODE_EOF && + smapi_retcode[i].rc != rc; ++i) {} + ret = smapi_retcode[i].ret; + if (msg) + *msg = smapi_retcode[i].msg; + + DPRINTK("req_out: AX=%x BX=%x CX=%x DX=%x DI=%x SI=%x r=%d", + tmpEAX, tmpEBX, tmpECX, tmpEDX, tmpEDI, tmpESI, ret); + if (ret) + TPRINTK(KERN_NOTICE, "SMAPI error: %s (func=%x)", + smapi_retcode[i].msg, inEBX); + + if (ret != -EBUSY) + return ret; + } + return ret; +} + +/* Convenience wrapper: discard output arguments */ +static int smapi_write(u32 inEBX, u32 inECX, + u32 inEDI, u32 inESI, const char **msg) +{ + return smapi_request(inEBX, inECX, inEDI, inESI, + NULL, NULL, NULL, NULL, NULL, msg); +} + + +/********************************************************************* + * Specific SMAPI services + * All of these functions return 0 upon success, and a negative errno + * constant (see smapi_retcode) on failure. + */ + +enum thresh_type { + THRESH_STOP = 0, /* the code assumes this is 0 for brevity */ + THRESH_START +}; +#define THRESH_NAME(which) ((which == THRESH_START) ? "start" : "stop") + +/** + * __get_real_thresh - read battery charge start/stop threshold from SMAPI + * @bat: battery number (0 or 1) + * @which: THRESH_START or THRESH_STOP + * @thresh: 1..99, 0=default 1..99, 0=default (pass this as-is to SMAPI) + * @outEDI: some additional state that needs to be preserved, meaning unknown + * @outESI: some additional state that needs to be preserved, meaning unknown + */ +static int __get_real_thresh(int bat, enum thresh_type which, int *thresh, + u32 *outEDI, u32 *outESI) +{ + u32 ebx = (which == THRESH_START) ? SMAPI_GET_THRESH_START + : SMAPI_GET_THRESH_STOP; + u32 ecx = (bat+1)<<8; + const char *msg; + int ret = smapi_request(ebx, ecx, 0, 0, NULL, + &ecx, NULL, outEDI, outESI, &msg); + if (ret) { + TPRINTK(KERN_NOTICE, "cannot get %s_thresh of bat=%d: %s", + THRESH_NAME(which), bat, msg); + return ret; + } + if (!(ecx&0x00000100)) { + TPRINTK(KERN_NOTICE, "cannot get %s_thresh of bat=%d: ecx=0%x", + THRESH_NAME(which), bat, ecx); + return -EIO; + } + if (thresh) + *thresh = ecx&0xFF; + return 0; +} + +/** + * get_real_thresh - read battery charge start/stop threshold from SMAPI + * @bat: battery number (0 or 1) + * @which: THRESH_START or THRESH_STOP + * @thresh: 1..99, 0=default (passes as-is to SMAPI) + */ +static int get_real_thresh(int bat, enum thresh_type which, int *thresh) +{ + return __get_real_thresh(bat, which, thresh, NULL, NULL); +} + +/** + * set_real_thresh - write battery start/top charge threshold to SMAPI + * @bat: battery number (0 or 1) + * @which: THRESH_START or THRESH_STOP + * @thresh: 1..99, 0=default (passes as-is to SMAPI) + */ +static int set_real_thresh(int bat, enum thresh_type which, int thresh) +{ + u32 ebx = (which == THRESH_START) ? SMAPI_SET_THRESH_START + : SMAPI_SET_THRESH_STOP; + u32 ecx = ((bat+1)<<8) + thresh; + u32 getDI, getSI; + const char *msg; + int ret; + + /* verify read before writing */ + ret = __get_real_thresh(bat, which, NULL, &getDI, &getSI); + if (ret) + return ret; + + ret = smapi_write(ebx, ecx, getDI, getSI, &msg); + if (ret) + TPRINTK(KERN_NOTICE, "set %s to %d for bat=%d failed: %s", + THRESH_NAME(which), thresh, bat, msg); + else + TPRINTK(KERN_INFO, "set %s to %d for bat=%d", + THRESH_NAME(which), thresh, bat); + return ret; +} + +/** + * __get_inhibit_charge_minutes - get inhibit charge period from SMAPI + * @bat: battery number (0 or 1) + * @minutes: period in minutes (1..65535 minutes, 0=disabled) + * @outECX: some additional state that needs to be preserved, meaning unknown + * Note that @minutes is the originally set value, it does not count down. + */ +static int __get_inhibit_charge_minutes(int bat, int *minutes, u32 *outECX) +{ + u32 ecx = (bat+1)<<8; + u32 esi; + const char *msg; + int ret = smapi_request(SMAPI_GET_INHIBIT_CHARGE, ecx, 0, 0, + NULL, &ecx, NULL, NULL, &esi, &msg); + if (ret) { + TPRINTK(KERN_NOTICE, "failed for bat=%d: %s", bat, msg); + return ret; + } + if (!(ecx&0x0100)) { + TPRINTK(KERN_NOTICE, "bad ecx=0x%x for bat=%d", ecx, bat); + return -EIO; + } + if (minutes) + *minutes = (ecx&0x0001)?esi:0; + if (outECX) + *outECX = ecx; + return 0; +} + +/** + * get_inhibit_charge_minutes - get inhibit charge period from SMAPI + * @bat: battery number (0 or 1) + * @minutes: period in minutes (1..65535 minutes, 0=disabled) + * Note that @minutes is the originally set value, it does not count down. + */ +static int get_inhibit_charge_minutes(int bat, int *minutes) +{ + return __get_inhibit_charge_minutes(bat, minutes, NULL); +} + +/** + * set_inhibit_charge_minutes - write inhibit charge period to SMAPI + * @bat: battery number (0 or 1) + * @minutes: period in minutes (1..65535 minutes, 0=disabled) + */ +static int set_inhibit_charge_minutes(int bat, int minutes) +{ + u32 ecx; + const char *msg; + int ret; + + /* verify read before writing */ + ret = __get_inhibit_charge_minutes(bat, NULL, &ecx); + if (ret) + return ret; + + ecx = ((bat+1)<<8) | (ecx&0x00FE) | (minutes > 0 ? 0x0001 : 0x0000); + if (minutes > 0xFFFF) + minutes = 0xFFFF; + ret = smapi_write(SMAPI_SET_INHIBIT_CHARGE, ecx, 0, minutes, &msg); + if (ret) + TPRINTK(KERN_NOTICE, + "set to %d failed for bat=%d: %s", minutes, bat, msg); + else + TPRINTK(KERN_INFO, "set to %d for bat=%d\n", minutes, bat); + return ret; +} + + +/** + * get_force_discharge - get status of forced discharging from SMAPI + * @bat: battery number (0 or 1) + * @enabled: 1 if forced discharged is enabled, 0 if not + */ +static int get_force_discharge(int bat, int *enabled) +{ + u32 ecx = (bat+1)<<8; + const char *msg; + int ret = smapi_request(SMAPI_GET_FORCE_DISCHARGE, ecx, 0, 0, + NULL, &ecx, NULL, NULL, NULL, &msg); + if (ret) { + TPRINTK(KERN_NOTICE, "failed for bat=%d: %s", bat, msg); + return ret; + } + *enabled = (!(ecx&0x00000100) && (ecx&0x00000001))?1:0; + return 0; +} + +/** + * set_force_discharge - write status of forced discharging to SMAPI + * @bat: battery number (0 or 1) + * @enabled: 1 if forced discharged is enabled, 0 if not + */ +static int set_force_discharge(int bat, int enabled) +{ + u32 ecx = (bat+1)<<8; + const char *msg; + int ret = smapi_request(SMAPI_GET_FORCE_DISCHARGE, ecx, 0, 0, + NULL, &ecx, NULL, NULL, NULL, &msg); + if (ret) { + TPRINTK(KERN_NOTICE, "get failed for bat=%d: %s", bat, msg); + return ret; + } + if (ecx&0x00000100) { + TPRINTK(KERN_NOTICE, "cannot force discharge bat=%d", bat); + return -EIO; + } + + ecx = ((bat+1)<<8) | (ecx&0x000000FA) | (enabled?0x00000001:0); + ret = smapi_write(SMAPI_SET_FORCE_DISCHARGE, ecx, 0, 0, &msg); + if (ret) + TPRINTK(KERN_NOTICE, "set to %d failed for bat=%d: %s", + enabled, bat, msg); + else + TPRINTK(KERN_INFO, "set to %d for bat=%d", enabled, bat); + return ret; +} + + +/********************************************************************* + * Wrappers to threshold-related SMAPI functions, which handle default + * thresholds and related quirks. + */ + +/* Minimum, default and minimum difference for battery charging thresholds: */ +#define MIN_THRESH_DELTA 4 /* Min delta between start and stop thresh */ +#define MIN_THRESH_START 2 +#define MAX_THRESH_START (100-MIN_THRESH_DELTA) +#define MIN_THRESH_STOP (MIN_THRESH_START + MIN_THRESH_DELTA) +#define MAX_THRESH_STOP 100 +#define DEFAULT_THRESH_START MAX_THRESH_START +#define DEFAULT_THRESH_STOP MAX_THRESH_STOP + +/* The GUI of IBM's Battery Maximizer seems to show a start threshold that + * is 1 more than the value we set/get via SMAPI. Since the threshold is + * maintained across reboot, this can be confusing. So we kludge our + * interface for interoperability: */ +#define BATMAX_FIX 1 + +/* Get charge start/stop threshold (1..100), + * substituting default values if needed and applying BATMAT_FIX. */ +static int get_thresh(int bat, enum thresh_type which, int *thresh) +{ + int ret = get_real_thresh(bat, which, thresh); + if (ret) + return ret; + if (*thresh == 0) + *thresh = (which == THRESH_START) ? DEFAULT_THRESH_START + : DEFAULT_THRESH_STOP; + else if (which == THRESH_START) + *thresh += BATMAX_FIX; + return 0; +} + + +/* Set charge start/stop threshold (1..100), + * substituting default values if needed and applying BATMAT_FIX. */ +static int set_thresh(int bat, enum thresh_type which, int thresh) +{ + if (which == THRESH_STOP && thresh == DEFAULT_THRESH_STOP) + thresh = 0; /* 100 is out of range, but default means 100 */ + if (which == THRESH_START) + thresh -= BATMAX_FIX; + return set_real_thresh(bat, which, thresh); +} + +/********************************************************************* + * ThinkPad embedded controller readout and basic functions + */ + +/** + * read_tp_ec_row - read data row from the ThinkPad embedded controller + * @arg0: EC command code + * @bat: battery number, 0 or 1 + * @j: the byte value to be used for "junk" (unused) input/outputs + * @dataval: result vector + */ +static int read_tp_ec_row(u8 arg0, int bat, u8 j, u8 *dataval) +{ + int ret; + const struct thinkpad_ec_row args = { .mask = 0xFFFF, + .val = {arg0, j,j,j,j,j,j,j,j,j,j,j,j,j,j, (u8)bat} }; + struct thinkpad_ec_row data = { .mask = 0xFFFF }; + + ret = thinkpad_ec_lock(); + if (ret) + return ret; + ret = thinkpad_ec_read_row(&args, &data); + thinkpad_ec_unlock(); + memcpy(dataval, &data.val, TP_CONTROLLER_ROW_LEN); + return ret; +} + +/** + * power_device_present - check for presence of battery or AC power + * @bat: 0 for battery 0, 1 for battery 1, otherwise AC power + * Returns 1 if present, 0 if not present, negative if error. + */ +static int power_device_present(int bat) +{ + u8 row[TP_CONTROLLER_ROW_LEN]; + u8 test; + int ret = read_tp_ec_row(1, bat, 0, row); + if (ret) + return ret; + switch (bat) { + case 0: test = 0x40; break; /* battery 0 */ + case 1: test = 0x20; break; /* battery 1 */ + default: test = 0x80; /* AC power */ + } + return (row[0] & test) ? 1 : 0; +} + +/** + * bat_has_status - check if battery can report detailed status + * @bat: 0 for battery 0, 1 for battery 1 + * Returns 1 if yes, 0 if no, negative if error. + */ +static int bat_has_status(int bat) +{ + u8 row[TP_CONTROLLER_ROW_LEN]; + int ret = read_tp_ec_row(1, bat, 0, row); + if (ret) + return ret; + if ((row[0] & (bat?0x20:0x40)) == 0) /* no battery */ + return 0; + if ((row[1] & (0x60)) == 0) /* no status */ + return 0; + return 1; +} + +/** + * get_tp_ec_bat_16 - read a 16-bit value from EC battery status data + * @arg0: first argument to EC + * @off: offset in row returned from EC + * @bat: battery (0 or 1) + * @val: the 16-bit value obtained + * Returns nonzero on error. + */ +static int get_tp_ec_bat_16(u8 arg0, int offset, int bat, u16 *val) +{ + u8 row[TP_CONTROLLER_ROW_LEN]; + int ret; + if (bat_has_status(bat) != 1) + return -ENXIO; + ret = read_tp_ec_row(arg0, bat, 0, row); + if (ret) + return ret; + *val = *(u16 *)(row+offset); + return 0; +} + +/********************************************************************* + * sysfs attributes for batteries - + * definitions and helper functions + */ + +/* A custom device attribute struct which holds a battery number */ +struct bat_device_attribute { + struct device_attribute dev_attr; + int bat; +}; + +/** + * attr_get_bat - get the battery to which the attribute belongs + */ +static int attr_get_bat(struct device_attribute *attr) +{ + return container_of(attr, struct bat_device_attribute, dev_attr)->bat; +} + +/** + * show_tp_ec_bat_u16 - show an unsigned 16-bit battery attribute + * @arg0: specified 1st argument of EC raw to read + * @offset: byte offset in EC raw data + * @mul: correction factor to multiply by + * @na_msg: string to output is value not available (0xFFFFFFFF) + * @attr: battery attribute + * @buf: output buffer + * The 16-bit value is read from the EC, treated as unsigned, + * transformed as x->mul*x, and printed to the buffer. + * If the value is 0xFFFFFFFF and na_msg!=%NULL, na_msg is printed instead. + */ +static ssize_t show_tp_ec_bat_u16(u8 arg0, int offset, int mul, + const char *na_msg, + struct device_attribute *attr, char *buf) +{ + u16 val; + int ret = get_tp_ec_bat_16(arg0, offset, attr_get_bat(attr), &val); + if (ret) + return ret; + if (na_msg && val == 0xFFFF) + return sprintf(buf, "%s\n", na_msg); + else + return sprintf(buf, "%u\n", mul*(unsigned int)val); +} + +/** + * show_tp_ec_bat_s16 - show an signed 16-bit battery attribute + * @arg0: specified 1st argument of EC raw to read + * @offset: byte offset in EC raw data + * @mul: correction factor to multiply by + * @add: correction term to add after multiplication + * @attr: battery attribute + * @buf: output buffer + * The 16-bit value is read from the EC, treated as signed, + * transformed as x->mul*x+add, and printed to the buffer. + */ +static ssize_t show_tp_ec_bat_s16(u8 arg0, int offset, int mul, int add, + struct device_attribute *attr, char *buf) +{ + u16 val; + int ret = get_tp_ec_bat_16(arg0, offset, attr_get_bat(attr), &val); + if (ret) + return ret; + return sprintf(buf, "%d\n", mul*(s16)val+add); +} + +/** + * show_tp_ec_bat_str - show a string from EC battery status data + * @arg0: specified 1st argument of EC raw to read + * @offset: byte offset in EC raw data + * @maxlen: maximum string length + * @attr: battery attribute + * @buf: output buffer + */ +static ssize_t show_tp_ec_bat_str(u8 arg0, int offset, int maxlen, + struct device_attribute *attr, char *buf) +{ + int bat = attr_get_bat(attr); + u8 row[TP_CONTROLLER_ROW_LEN]; + int ret; + if (bat_has_status(bat) != 1) + return -ENXIO; + ret = read_tp_ec_row(arg0, bat, 0, row); + if (ret) + return ret; + strncpy(buf, (char *)row+offset, maxlen); + buf[maxlen] = 0; + strcat(buf, "\n"); + return strlen(buf); +} + +/** + * show_tp_ec_bat_power - show a power readout from EC battery status data + * @arg0: specified 1st argument of EC raw to read + * @offV: byte offset of voltage in EC raw data + * @offI: byte offset of current in EC raw data + * @attr: battery attribute + * @buf: output buffer + * Computes the power as current*voltage from the two given readout offsets. + */ +static ssize_t show_tp_ec_bat_power(u8 arg0, int offV, int offI, + struct device_attribute *attr, char *buf) +{ + u8 row[TP_CONTROLLER_ROW_LEN]; + int milliamp, millivolt, ret; + int bat = attr_get_bat(attr); + if (bat_has_status(bat) != 1) + return -ENXIO; + ret = read_tp_ec_row(1, bat, 0, row); + if (ret) + return ret; + millivolt = *(u16 *)(row+offV); + milliamp = *(s16 *)(row+offI); + return sprintf(buf, "%d\n", milliamp*millivolt/1000); /* units: mW */ +} + +/** + * show_tp_ec_bat_date - decode and show a date from EC battery status data + * @arg0: specified 1st argument of EC raw to read + * @offset: byte offset in EC raw data + * @attr: battery attribute + * @buf: output buffer + */ +static ssize_t show_tp_ec_bat_date(u8 arg0, int offset, + struct device_attribute *attr, char *buf) +{ + u8 row[TP_CONTROLLER_ROW_LEN]; + u16 v; + int ret; + int day, month, year; + int bat = attr_get_bat(attr); + if (bat_has_status(bat) != 1) + return -ENXIO; + ret = read_tp_ec_row(arg0, bat, 0, row); + if (ret) + return ret; + + /* Decode bit-packed: v = day | (month<<5) | ((year-1980)<<9) */ + v = *(u16 *)(row+offset); + day = v & 0x1F; + month = (v >> 5) & 0xF; + year = (v >> 9) + 1980; + + return sprintf(buf, "%04d-%02d-%02d\n", year, month, day); +} + + +/********************************************************************* + * sysfs attribute I/O for batteries - + * the actual attribute show/store functions + */ + +static ssize_t show_battery_start_charge_thresh(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int thresh; + int bat = attr_get_bat(attr); + int ret = get_thresh(bat, THRESH_START, &thresh); + if (ret) + return ret; + return sprintf(buf, "%d\n", thresh); /* units: percent */ +} + +static ssize_t show_battery_stop_charge_thresh(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int thresh; + int bat = attr_get_bat(attr); + int ret = get_thresh(bat, THRESH_STOP, &thresh); + if (ret) + return ret; + return sprintf(buf, "%d\n", thresh); /* units: percent */ +} + +/** + * store_battery_start_charge_thresh - store battery_start_charge_thresh attr + * Since this is a kernel<->user interface, we ensure a valid state for + * the hardware. We do this by clamping the requested threshold to the + * valid range and, if necessary, moving the other threshold so that + * it's MIN_THRESH_DELTA away from this one. + */ +static ssize_t store_battery_start_charge_thresh(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int thresh, other_thresh, ret; + int bat = attr_get_bat(attr); + + if (sscanf(buf, "%d", &thresh) != 1 || thresh < 1 || thresh > 100) + return -EINVAL; + + if (thresh < MIN_THRESH_START) /* clamp up to MIN_THRESH_START */ + thresh = MIN_THRESH_START; + if (thresh > MAX_THRESH_START) /* clamp down to MAX_THRESH_START */ + thresh = MAX_THRESH_START; + + down(&smapi_mutex); + ret = get_thresh(bat, THRESH_STOP, &other_thresh); + if (ret != -EOPNOTSUPP) { + if (ret) /* other threshold is set? */ + goto out; + ret = get_real_thresh(bat, THRESH_START, NULL); + if (ret) /* this threshold is set? */ + goto out; + if (other_thresh < thresh+MIN_THRESH_DELTA) { + /* move other thresh to keep it above this one */ + ret = set_thresh(bat, THRESH_STOP, + thresh+MIN_THRESH_DELTA); + if (ret) + goto out; + } + } + ret = set_thresh(bat, THRESH_START, thresh); +out: + up(&smapi_mutex); + return count; + +} + +/** + * store_battery_stop_charge_thresh - store battery_stop_charge_thresh attr + * Since this is a kernel<->user interface, we ensure a valid state for + * the hardware. We do this by clamping the requested threshold to the + * valid range and, if necessary, moving the other threshold so that + * it's MIN_THRESH_DELTA away from this one. + */ +static ssize_t store_battery_stop_charge_thresh(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int thresh, other_thresh, ret; + int bat = attr_get_bat(attr); + + if (sscanf(buf, "%d", &thresh) != 1 || thresh < 1 || thresh > 100) + return -EINVAL; + + if (thresh < MIN_THRESH_STOP) /* clamp up to MIN_THRESH_STOP */ + thresh = MIN_THRESH_STOP; + + down(&smapi_mutex); + ret = get_thresh(bat, THRESH_START, &other_thresh); + if (ret != -EOPNOTSUPP) { /* other threshold exists? */ + if (ret) + goto out; + /* this threshold exists? */ + ret = get_real_thresh(bat, THRESH_STOP, NULL); + if (ret) + goto out; + if (other_thresh >= thresh-MIN_THRESH_DELTA) { + /* move other thresh to be below this one */ + ret = set_thresh(bat, THRESH_START, + thresh-MIN_THRESH_DELTA); + if (ret) + goto out; + } + } + ret = set_thresh(bat, THRESH_STOP, thresh); +out: + up(&smapi_mutex); + return count; +} + +static ssize_t show_battery_inhibit_charge_minutes(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int minutes; + int bat = attr_get_bat(attr); + int ret = get_inhibit_charge_minutes(bat, &minutes); + if (ret) + return ret; + return sprintf(buf, "%d\n", minutes); /* units: minutes */ +} + +static ssize_t store_battery_inhibit_charge_minutes(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + int minutes; + int bat = attr_get_bat(attr); + if (sscanf(buf, "%d", &minutes) != 1 || minutes < 0) { + TPRINTK(KERN_ERR, "inhibit_charge_minutes: " + "must be a non-negative integer"); + return -EINVAL; + } + ret = set_inhibit_charge_minutes(bat, minutes); + if (ret) + return ret; + return count; +} + +static ssize_t show_battery_force_discharge(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int enabled; + int bat = attr_get_bat(attr); + int ret = get_force_discharge(bat, &enabled); + if (ret) + return ret; + return sprintf(buf, "%d\n", enabled); /* type: boolean */ +} + +static ssize_t store_battery_force_discharge(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int ret; + int enabled; + int bat = attr_get_bat(attr); + if (sscanf(buf, "%d", &enabled) != 1 || enabled < 0 || enabled > 1) + return -EINVAL; + ret = set_force_discharge(bat, enabled); + if (ret) + return ret; + return count; +} + +static ssize_t show_battery_installed( + struct device *dev, struct device_attribute *attr, char *buf) +{ + int bat = attr_get_bat(attr); + int ret = power_device_present(bat); + if (ret < 0) + return ret; + return sprintf(buf, "%d\n", ret); /* type: boolean */ +} + +static ssize_t show_battery_state( + struct device *dev, struct device_attribute *attr, char *buf) +{ + u8 row[TP_CONTROLLER_ROW_LEN]; + const char *txt; + int ret; + int bat = attr_get_bat(attr); + if (bat_has_status(bat) != 1) + return sprintf(buf, "none\n"); + ret = read_tp_ec_row(1, bat, 0, row); + if (ret) + return ret; + switch (row[1] & 0xf0) { + case 0xc0: txt = "idle"; break; + case 0xd0: txt = "discharging"; break; + case 0xe0: txt = "charging"; break; + default: return sprintf(buf, "unknown (0x%x)\n", row[1]); + } + return sprintf(buf, "%s\n", txt); /* type: string from fixed set */ +} + +static ssize_t show_battery_manufacturer( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* type: string. SBS spec v1.1 p34: ManufacturerName() */ + return show_tp_ec_bat_str(4, 2, TP_CONTROLLER_ROW_LEN-2, attr, buf); +} + +static ssize_t show_battery_model( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* type: string. SBS spec v1.1 p34: DeviceName() */ + return show_tp_ec_bat_str(5, 2, TP_CONTROLLER_ROW_LEN-2, attr, buf); +} + +static ssize_t show_battery_barcoding( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* type: string */ + return show_tp_ec_bat_str(7, 2, TP_CONTROLLER_ROW_LEN-2, attr, buf); +} + +static ssize_t show_battery_chemistry( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* type: string. SBS spec v1.1 p34-35: DeviceChemistry() */ + return show_tp_ec_bat_str(6, 2, 5, attr, buf); +} + +static ssize_t show_battery_voltage( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mV. SBS spec v1.1 p24: Voltage() */ + return show_tp_ec_bat_u16(1, 6, 1, NULL, attr, buf); +} + +static ssize_t show_battery_design_voltage( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mV. SBS spec v1.1 p32: DesignVoltage() */ + return show_tp_ec_bat_u16(3, 4, 1, NULL, attr, buf); +} + +static ssize_t show_battery_charging_max_voltage( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mV. SBS spec v1.1 p37,39: ChargingVoltage() */ + return show_tp_ec_bat_u16(9, 8, 1, NULL, attr, buf); +} + +static ssize_t show_battery_group0_voltage( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mV */ + return show_tp_ec_bat_u16(0xA, 12, 1, NULL, attr, buf); +} + +static ssize_t show_battery_group1_voltage( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mV */ + return show_tp_ec_bat_u16(0xA, 10, 1, NULL, attr, buf); +} + +static ssize_t show_battery_group2_voltage( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mV */ + return show_tp_ec_bat_u16(0xA, 8, 1, NULL, attr, buf); +} + +static ssize_t show_battery_group3_voltage( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mV */ + return show_tp_ec_bat_u16(0xA, 6, 1, NULL, attr, buf); +} + +static ssize_t show_battery_current_now( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mA. SBS spec v1.1 p24: Current() */ + return show_tp_ec_bat_s16(1, 8, 1, 0, attr, buf); +} + +static ssize_t show_battery_current_avg( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mA. SBS spec v1.1 p24: AverageCurrent() */ + return show_tp_ec_bat_s16(1, 10, 1, 0, attr, buf); +} + +static ssize_t show_battery_charging_max_current( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mA. SBS spec v1.1 p36,38: ChargingCurrent() */ + return show_tp_ec_bat_s16(9, 6, 1, 0, attr, buf); +} + +static ssize_t show_battery_power_now( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mW. SBS spec v1.1: Voltage()*Current() */ + return show_tp_ec_bat_power(1, 6, 8, attr, buf); +} + +static ssize_t show_battery_power_avg( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mW. SBS spec v1.1: Voltage()*AverageCurrent() */ + return show_tp_ec_bat_power(1, 6, 10, attr, buf); +} + +static ssize_t show_battery_remaining_percent( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: percent. SBS spec v1.1 p25: RelativeStateOfCharge() */ + return show_tp_ec_bat_u16(1, 12, 1, NULL, attr, buf); +} + +static ssize_t show_battery_remaining_charging_time( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: minutes. SBS spec v1.1 p27: AverageTimeToFull() */ + return show_tp_ec_bat_u16(2, 8, 1, "not_charging", attr, buf); +} + +static ssize_t show_battery_remaining_running_time( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: minutes. SBS spec v1.1 p27: RunTimeToEmpty() */ + return show_tp_ec_bat_u16(2, 6, 1, "not_discharging", attr, buf); +} + +static ssize_t show_battery_remaining_running_time_now( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: minutes. SBS spec v1.1 p27: RunTimeToEmpty() */ + return show_tp_ec_bat_u16(2, 4, 1, "not_discharging", attr, buf); +} + +static ssize_t show_battery_remaining_capacity( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mWh. SBS spec v1.1 p26. */ + return show_tp_ec_bat_u16(1, 14, 10, "", attr, buf); +} + +static ssize_t show_battery_last_full_capacity( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mWh. SBS spec v1.1 p26: FullChargeCapacity() */ + return show_tp_ec_bat_u16(2, 2, 10, "", attr, buf); +} + +static ssize_t show_battery_design_capacity( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mWh. SBS spec v1.1 p32: DesignCapacity() */ + return show_tp_ec_bat_u16(3, 2, 10, "", attr, buf); +} + +static ssize_t show_battery_cycle_count( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: ordinal. SBS spec v1.1 p32: CycleCount() */ + return show_tp_ec_bat_u16(2, 12, 1, "", attr, buf); +} + +static ssize_t show_battery_temperature( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: millicelsius. SBS spec v1.1: Temperature()*10 */ + return show_tp_ec_bat_s16(1, 4, 100, -273100, attr, buf); +} + +static ssize_t show_battery_serial( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* type: int. SBS spec v1.1 p34: SerialNumber() */ + return show_tp_ec_bat_u16(3, 10, 1, "", attr, buf); +} + +static ssize_t show_battery_manufacture_date( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* type: YYYY-MM-DD. SBS spec v1.1 p34: ManufactureDate() */ + return show_tp_ec_bat_date(3, 8, attr, buf); +} + +static ssize_t show_battery_first_use_date( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* type: YYYY-MM-DD */ + return show_tp_ec_bat_date(8, 2, attr, buf); +} + +/** + * show_battery_dump - show the battery's dump attribute + * The dump attribute gives a hex dump of all EC readouts related to a + * battery. Some of the enumerated values don't really exist (i.e., the + * EC function just leaves them untouched); we use a kludge to detect and + * denote these. + */ +#define MIN_DUMP_ARG0 0x00 +#define MAX_DUMP_ARG0 0x0a /* 0x0b is useful too but hangs old EC firmware */ +static ssize_t show_battery_dump( + struct device *dev, struct device_attribute *attr, char *buf) +{ + int i; + char *p = buf; + int bat = attr_get_bat(attr); + u8 arg0; /* first argument to EC */ + u8 rowa[TP_CONTROLLER_ROW_LEN], + rowb[TP_CONTROLLER_ROW_LEN]; + const u8 junka = 0xAA, + junkb = 0x55; /* junk values for testing changes */ + int ret; + + for (arg0 = MIN_DUMP_ARG0; arg0 <= MAX_DUMP_ARG0; ++arg0) { + if ((p-buf) > PAGE_SIZE-TP_CONTROLLER_ROW_LEN*5) + return -ENOMEM; /* don't overflow sysfs buf */ + /* Read raw twice with different junk values, + * to detect unused output bytes which are left unchaged: */ + ret = read_tp_ec_row(arg0, bat, junka, rowa); + if (ret) + return ret; + ret = read_tp_ec_row(arg0, bat, junkb, rowb); + if (ret) + return ret; + for (i = 0; i < TP_CONTROLLER_ROW_LEN; i++) { + if (rowa[i] == junka && rowb[i] == junkb) + p += sprintf(p, "-- "); /* unused by EC */ + else + p += sprintf(p, "%02x ", rowa[i]); + } + p += sprintf(p, "\n"); + } + return p-buf; +} + + +/********************************************************************* + * sysfs attribute I/O, other than batteries + */ + +static ssize_t show_ac_connected( + struct device *dev, struct device_attribute *attr, char *buf) +{ + int ret = power_device_present(0xFF); + if (ret < 0) + return ret; + return sprintf(buf, "%d\n", ret); /* type: boolean */ +} + +/********************************************************************* + * The the "smapi_request" sysfs attribute executes a raw SMAPI call. + * You write to make a request and read to get the result. The state + * is saved globally rather than per fd (sysfs limitation), so + * simultaenous requests may get each other's results! So this is for + * development and debugging only. + */ +#define MAX_SMAPI_ATTR_ANSWER_LEN 128 +static char smapi_attr_answer[MAX_SMAPI_ATTR_ANSWER_LEN] = ""; + +static ssize_t show_smapi_request(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret = snprintf(buf, PAGE_SIZE, "%s", smapi_attr_answer); + smapi_attr_answer[0] = '\0'; + return ret; +} + +static ssize_t store_smapi_request(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned int inEBX, inECX, inEDI, inESI; + u32 outEBX, outECX, outEDX, outEDI, outESI; + const char *msg; + int ret; + if (sscanf(buf, "%x %x %x %x", &inEBX, &inECX, &inEDI, &inESI) != 4) { + smapi_attr_answer[0] = '\0'; + return -EINVAL; + } + ret = smapi_request( + inEBX, inECX, inEDI, inESI, + &outEBX, &outECX, &outEDX, &outEDI, &outESI, &msg); + snprintf(smapi_attr_answer, MAX_SMAPI_ATTR_ANSWER_LEN, + "%x %x %x %x %x %d '%s'\n", + (unsigned int)outEBX, (unsigned int)outECX, + (unsigned int)outEDX, (unsigned int)outEDI, + (unsigned int)outESI, ret, msg); + if (ret) + return ret; + else + return count; +} + +/********************************************************************* + * Power management: the embedded controller forgets the battery + * thresholds when the system is suspended to disk and unplugged from + * AC and battery, so we restore it upon resume. + */ + +static int saved_threshs[4] = {-1, -1, -1, -1}; /* -1 = don't know */ + +static int tp_suspend(struct platform_device *dev, pm_message_t state) +{ + if (get_real_thresh(0, THRESH_STOP , &saved_threshs[0])) + saved_threshs[0] = -1; + if (get_real_thresh(0, THRESH_START, &saved_threshs[1])) + saved_threshs[1] = -1; + if (get_real_thresh(1, THRESH_STOP , &saved_threshs[2])) + saved_threshs[2] = -1; + if (get_real_thresh(1, THRESH_START, &saved_threshs[3])) + saved_threshs[3] = -1; + DPRINTK("suspend saved: %d %d %d %d", saved_threshs[0], + saved_threshs[1], saved_threshs[2], saved_threshs[3]); + return 0; +} + +static int tp_resume(struct platform_device *dev) +{ + DPRINTK("resume restoring: %d %d %d %d", saved_threshs[0], + saved_threshs[1], saved_threshs[2], saved_threshs[3]); + if (saved_threshs[0] >= 0) + set_real_thresh(0, THRESH_STOP , saved_threshs[0]); + if (saved_threshs[1] >= 0) + set_real_thresh(0, THRESH_START, saved_threshs[1]); + if (saved_threshs[2] >= 0) + set_real_thresh(1, THRESH_STOP , saved_threshs[2]); + if (saved_threshs[3] >= 0) + set_real_thresh(1, THRESH_START, saved_threshs[3]); + return 0; +} + + +/********************************************************************* + * Driver model + */ + +static struct platform_driver tp_driver = { + .suspend = tp_suspend, + .resume = tp_resume, + .driver = { + .name = "smapi", + .owner = THIS_MODULE + }, +}; + + +/********************************************************************* + * Sysfs device model + */ + +/* Attributes in /sys/devices/platform/smapi/ */ + +static DEVICE_ATTR(ac_connected, 0444, show_ac_connected, NULL); +static DEVICE_ATTR(smapi_request, 0600, show_smapi_request, + store_smapi_request); + +static struct attribute *tp_root_attributes[] = { + &dev_attr_ac_connected.attr, + &dev_attr_smapi_request.attr, + NULL +}; +static struct attribute_group tp_root_attribute_group = { + .attrs = tp_root_attributes +}; + +/* Attributes under /sys/devices/platform/smapi/BAT{0,1}/ : + * Every attribute needs to be defined (i.e., statically allocated) for + * each battery, and then referenced in the attribute list of each battery. + * We use preprocessor voodoo to avoid duplicating the list of attributes 4 + * times. The preprocessor output is just normal sysfs attributes code. + */ + +/** + * FOREACH_BAT_ATTR - invoke the given macros on all our battery attributes + * @_BAT: battery number (0 or 1) + * @_ATTR_RW: macro to invoke for each read/write attribute + * @_ATTR_R: macro to invoke for each read-only attribute + */ +#define FOREACH_BAT_ATTR(_BAT, _ATTR_RW, _ATTR_R) \ + _ATTR_RW(_BAT, start_charge_thresh) \ + _ATTR_RW(_BAT, stop_charge_thresh) \ + _ATTR_RW(_BAT, inhibit_charge_minutes) \ + _ATTR_RW(_BAT, force_discharge) \ + _ATTR_R(_BAT, installed) \ + _ATTR_R(_BAT, state) \ + _ATTR_R(_BAT, manufacturer) \ + _ATTR_R(_BAT, model) \ + _ATTR_R(_BAT, barcoding) \ + _ATTR_R(_BAT, chemistry) \ + _ATTR_R(_BAT, voltage) \ + _ATTR_R(_BAT, group0_voltage) \ + _ATTR_R(_BAT, group1_voltage) \ + _ATTR_R(_BAT, group2_voltage) \ + _ATTR_R(_BAT, group3_voltage) \ + _ATTR_R(_BAT, current_now) \ + _ATTR_R(_BAT, current_avg) \ + _ATTR_R(_BAT, charging_max_current) \ + _ATTR_R(_BAT, power_now) \ + _ATTR_R(_BAT, power_avg) \ + _ATTR_R(_BAT, remaining_percent) \ + _ATTR_R(_BAT, remaining_charging_time) \ + _ATTR_R(_BAT, remaining_running_time) \ + _ATTR_R(_BAT, remaining_running_time_now) \ + _ATTR_R(_BAT, remaining_capacity) \ + _ATTR_R(_BAT, last_full_capacity) \ + _ATTR_R(_BAT, design_voltage) \ + _ATTR_R(_BAT, charging_max_voltage) \ + _ATTR_R(_BAT, design_capacity) \ + _ATTR_R(_BAT, cycle_count) \ + _ATTR_R(_BAT, temperature) \ + _ATTR_R(_BAT, serial) \ + _ATTR_R(_BAT, manufacture_date) \ + _ATTR_R(_BAT, first_use_date) \ + _ATTR_R(_BAT, dump) + +/* Define several macros we will feed into FOREACH_BAT_ATTR: */ + +#define DEFINE_BAT_ATTR_RW(_BAT,_NAME) \ + static struct bat_device_attribute dev_attr_##_NAME##_##_BAT = { \ + .dev_attr = __ATTR(_NAME, 0644, show_battery_##_NAME, \ + store_battery_##_NAME), \ + .bat = _BAT \ + }; + +#define DEFINE_BAT_ATTR_R(_BAT,_NAME) \ + static struct bat_device_attribute dev_attr_##_NAME##_##_BAT = { \ + .dev_attr = __ATTR(_NAME, 0644, show_battery_##_NAME, 0), \ + .bat = _BAT \ + }; + +#define REF_BAT_ATTR(_BAT,_NAME) \ + &dev_attr_##_NAME##_##_BAT.dev_attr.attr, + +/* This provide all attributes for one battery: */ + +#define PROVIDE_BAT_ATTRS(_BAT) \ + FOREACH_BAT_ATTR(_BAT, DEFINE_BAT_ATTR_RW, DEFINE_BAT_ATTR_R) \ + static struct attribute *tp_bat##_BAT##_attributes[] = { \ + FOREACH_BAT_ATTR(_BAT, REF_BAT_ATTR, REF_BAT_ATTR) \ + NULL \ + }; \ + static struct attribute_group tp_bat##_BAT##_attribute_group = { \ + .name = "BAT" #_BAT, \ + .attrs = tp_bat##_BAT##_attributes \ + }; + +/* Finally genereate the attributes: */ + +PROVIDE_BAT_ATTRS(0) +PROVIDE_BAT_ATTRS(1) + +/* List of attribute groups */ + +static struct attribute_group *attr_groups[] = { + &tp_root_attribute_group, + &tp_bat0_attribute_group, + &tp_bat1_attribute_group, + NULL +}; + + +/********************************************************************* + * Init and cleanup + */ + +static struct attribute_group **next_attr_group; /* next to register */ + +static int __init tp_init(void) +{ + int ret; + printk(KERN_INFO "tp_smapi " TP_VERSION " loading...\n"); + + ret = find_smapi_port(); + if (ret < 0) + goto err; + else + smapi_port = ret; + + if (!request_region(smapi_port, 1, "smapi")) { + printk(KERN_ERR "tp_smapi cannot claim port 0x%x\n", + smapi_port); + ret = -ENXIO; + goto err; + } + + if (!request_region(SMAPI_PORT2, 1, "smapi")) { + printk(KERN_ERR "tp_smapi cannot claim port 0x%x\n", + SMAPI_PORT2); + ret = -ENXIO; + goto err_port1; + } + + ret = platform_driver_register(&tp_driver); + if (ret) + goto err_port2; + + pdev = platform_device_alloc("smapi", -1); + if (!pdev) { + ret = -ENOMEM; + goto err_driver; + } + + ret = platform_device_add(pdev); + if (ret) + goto err_device_free; + + for (next_attr_group = attr_groups; *next_attr_group; + ++next_attr_group) { + ret = sysfs_create_group(&pdev->dev.kobj, *next_attr_group); + if (ret) + goto err_attr; + } + + printk(KERN_INFO "tp_smapi successfully loaded (smapi_port=0x%x).\n", + smapi_port); + return 0; + +err_attr: + while (--next_attr_group >= attr_groups) + sysfs_remove_group(&pdev->dev.kobj, *next_attr_group); + platform_device_unregister(pdev); +err_device_free: + platform_device_put(pdev); +err_driver: + platform_driver_unregister(&tp_driver); +err_port2: + release_region(SMAPI_PORT2, 1); +err_port1: + release_region(smapi_port, 1); +err: + printk(KERN_ERR "tp_smapi init failed (ret=%d)!\n", ret); + return ret; +} + +static void __exit tp_exit(void) +{ + while (next_attr_group && --next_attr_group >= attr_groups) + sysfs_remove_group(&pdev->dev.kobj, *next_attr_group); + platform_device_unregister(pdev); + platform_driver_unregister(&tp_driver); + release_region(SMAPI_PORT2, 1); + if (smapi_port) + release_region(smapi_port, 1); + + printk(KERN_INFO "tp_smapi unloaded.\n"); +} + +module_init(tp_init); +module_exit(tp_exit); --- linux-2.6.28.orig/ubuntu/misc/fsam7400.c +++ linux-2.6.28/ubuntu/misc/fsam7400.c @@ -0,0 +1,373 @@ +/******************************************************************************* + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., 59 + Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + The full GNU General Public License is included in this distribution in the + file called LICENSE. + + Author: + Marcel Naziri + + Based on: + pbe5.c by Pedro Ramalhais + + Many thanks to: + Pedro Ramalhais for spending several nights with me on IRC disassembling + the structure of the windows driver files... :) + +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "fsam7400" +#define DRV_VERSION "0.4.0" +#define DRV_DESCRIPTION "SW RF kill switch for Fujitsu Siemens Amilo M 7400" +#define DRV_COPYRIGHT "Copyright(c) 2004 zwobbl ;)" +#define DRV_AUTHOR "Marcel Naziri" +#define DRV_LICENSE "GPL" + +MODULE_DESCRIPTION(DRV_DESCRIPTION); +MODULE_AUTHOR(DRV_AUTHOR); +MODULE_LICENSE(DRV_LICENSE); + +#define RADIO_NONE 0xFFFFFFFF +#define RADIO_OFF 0x00000000 +#define RADIO_ON 0x00000010 + +static int radio = RADIO_NONE; +module_param(radio, uint, 0400); +MODULE_PARM_DESC(radio, "desired radio state when loading module"); + +static int autooff = 1; +module_param(autooff, uint, 0400); +MODULE_PARM_DESC(autooff, "turns radio off when unloading module " + "(default)"); + +static int uid = 0; +module_param(uid, uint, 0400); +MODULE_PARM_DESC(uid, "user ID for proc entry"); + +static int gid = 0; +module_param(gid, uint, 0400); +MODULE_PARM_DESC(gid, "group ID for proc entry"); + +/* some more or less useful macros */ +#ifdef CONFIG_IPW2100_DEBUG +#define DEBUG_OUT0(a) printk(KERN_INFO DRV_NAME ": " a) +#define DEBUG_OUT1(a,b) printk(KERN_INFO DRV_NAME ": " a,b) +#define DEBUG_OUT2(a,b,c) printk(KERN_INFO DRV_NAME ": " a,b,c) +#define DEBUG_OUT3(a,b,c,d) printk(KERN_INFO DRV_NAME ": " a,b,c,d) +#else +#define DEBUG_OUT0(a) +#define DEBUG_OUT1(a,b) +#define DEBUG_OUT2(a,b,c) +#define DEBUG_OUT3(a,b,c,d) +#endif + +#define ONOFF(x) (x) ? "ON" : "OFF" +#define RADIO_ONOFF(x) (x) == RADIO_ON ? "ON" : "OFF" +#define TOUL(x) (unsigned long) (x) + +/* + * NOTE: These values were obtained from disassembling the wbutton.sys driver + * installed in the Fujitsu Siemens Amilo M 7400 laptop. The names were guessed, + * so don't rely on them. + */ + +/*** hardware dependant stuff ***/ + +#define BIOS_CODE_ADDR 0x000F0000 +#define BIOS_CODE_ALT_MASK 0xFFFFC000 + +#define BIOS_CODE_MAPSIZE 0x010000 +#define BIOS_CODE_ALT_MAPSIZE 0x004000 + +#define BIOS_MAGIC_COMMAND 0x9610 +#define BIOS_MAGIC_OFF 0x0035 +#define BIOS_MAGIC_ON 0x0135 +#define BIOS_MAGIC_CHECK 0x0235 + +#define PTR_POSITION 5 +#define ALLIGNED_STEP 0x10 + +#define BIOS_SIGN_SIZE 4 +static const char bios_sign[] = { + 0x42, 0x21, 0x55, 0x30 +}; + +#define WLAN_DISABLED_IN_BIOS 0x01 +#define WLAN_ENABLED_IN_BIOS 0x03 + +static unsigned long bios_code = 0; + +static int fsam_bios_routine(int eax, int ebx) +{ + __asm__ __volatile__( + "call *%3 \t\n" + : "=a"(eax) + : "a"(eax), "b"(ebx), "c"(bios_code) + ); + return (eax & 0xFF); +} + +static int fsam_call_bios(int value) +{ + if (bios_code) { + int command = BIOS_MAGIC_COMMAND; + + DEBUG_OUT2("bios routine gets parameter eax=%X and ebx=%X\n", + command, value); + + value = fsam_bios_routine(command, value); + + DEBUG_OUT1("bios routine results %X\n", value); + return value; + } + return ~0; +} + +/* pointer to mapped memory*/ +static void *mem_code = NULL; + +static inline void fsam_unmap_memory(void) +{ + bios_code = 0; + if (mem_code) { + iounmap(mem_code); + } +} + +static inline int fsam_map_memory(void) +{ + const unsigned long max_offset = BIOS_CODE_MAPSIZE - BIOS_SIGN_SIZE - PTR_POSITION; + unsigned long offset; + unsigned int addr; + + mem_code = ioremap(BIOS_CODE_ADDR, BIOS_CODE_MAPSIZE); + if (!mem_code) + goto fail; + + DEBUG_OUT3("physical memory %x-%x mapped to virtual address %p\n", + BIOS_CODE_ADDR, BIOS_CODE_ADDR+BIOS_CODE_MAPSIZE, mem_code); + + for ( offset = 0; offset < max_offset; offset += ALLIGNED_STEP ) + if (check_signature(mem_code + offset, bios_sign, BIOS_SIGN_SIZE)) + break; + + if (offset >= max_offset) + goto fail; + + DEBUG_OUT1("bios signature found at offset %lx\n", offset); + + addr = readl(mem_code + offset + PTR_POSITION); + + if (addr < BIOS_CODE_ADDR) + { + DEBUG_OUT0("bios routine out of memory range, " + "doing some new memory mapping...\n"); + iounmap(mem_code); + mem_code = NULL; + + addr &= BIOS_CODE_ALT_MASK; + + mem_code = ioremap(addr, BIOS_CODE_ALT_MAPSIZE); + if (!mem_code) + goto fail; + + DEBUG_OUT3("physical memory %x-%x mapped to virtual address %p\n", + addr, addr+BIOS_CODE_ALT_MAPSIZE, mem_code); + + addr &= 0x3FFF; + } + else + addr &= 0xFFFF; + + bios_code = addr + TOUL(mem_code); + DEBUG_OUT1("supposed address of bios routine is %lx\n", bios_code); + + return 1; + + fail: + fsam_unmap_memory(); + return 0; +} + +/*** interface stuff ***/ + +static void rfkill_set_radio(int value) +{ + radio = value == RADIO_ON ? fsam_call_bios(BIOS_MAGIC_ON) : + fsam_call_bios(BIOS_MAGIC_OFF); +} + +static inline int rfkill_get_radio(void) +{ + return radio; +} + +static inline int rfkill_supported(void) +{ + return bios_code != 0; +} + +static inline void rfkill_initialize(void) { + fsam_map_memory(); + + if (rfkill_supported()) { + radio = radio != RADIO_NONE + ? ( radio ? RADIO_ON : RADIO_OFF ) /*module parameter*/ + : ( fsam_call_bios(BIOS_MAGIC_CHECK) == WLAN_ENABLED_IN_BIOS + ? RADIO_ON : RADIO_OFF ); + } +} + +static inline void rfkill_uninitialize(void) { + fsam_unmap_memory(); +} + +/*** proc stuff ***/ + +static inline int common_proc_set_radio(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + unsigned long len = 4; + char newstate[len]; + + len = count < len ? count : len; + + if ( copy_from_user(newstate, buffer, len) != 0 ) + return -EFAULT; + + if ( (*newstate == '1' || *newstate == '0') && + (count == 1 || isspace(newstate[1])) ) + rfkill_set_radio(*newstate == '1' ? RADIO_ON : RADIO_OFF); + else + if ( !strncmp(newstate, "on", 2) && + (count == 2 || isspace(newstate[2])) ) + rfkill_set_radio(RADIO_ON); + else + if ( !strncmp(newstate, "off", 3) && + (count == 3 || isspace(newstate[3])) ) + rfkill_set_radio(RADIO_OFF); + + return count; +} + +static inline int common_proc_get_radio(char *page, char **start, off_t offset, + int count, int *eof, void *data) +{ + int len = snprintf(page, count, DRV_DESCRIPTION ", v" DRV_VERSION "\n" + " auto-off is %s\n", + ONOFF(autooff)); + len += snprintf(page+len, count-len, " radio state is %s\n", + RADIO_ONOFF(rfkill_get_radio())); + *eof = 1; + + return len; +} + +#define PROC_DIR "driver/wireless" +#define PROC_RADIO "radio" + +static struct proc_dir_entry *dir_base = NULL; + +static inline void common_proc_cleanup(void) +{ + if (dir_base) { + remove_proc_entry(PROC_RADIO, dir_base); + remove_proc_entry(PROC_DIR, NULL); + dir_base = NULL; + } +} + +static inline int common_proc_init(void) +{ + struct proc_dir_entry *ent; + int err = 0; + + dir_base = proc_mkdir(PROC_DIR, NULL); + if (dir_base == NULL) { + printk(KERN_ERR DRV_NAME ": Unable to initialize /proc/" PROC_DIR "\n"); + err = -ENOMEM; + goto fail; + } + + ent = create_proc_entry(PROC_RADIO, + S_IFREG | S_IRUGO | S_IWUSR | S_IWGRP, + dir_base); + ent->uid = uid; + ent->gid = gid; + if (ent) { + ent->read_proc = common_proc_get_radio; + ent->write_proc = common_proc_set_radio; + } else { + printk(KERN_ERR DRV_NAME ": Unable to initialize /proc/" + PROC_DIR "/" PROC_RADIO "\n"); + err = -ENOMEM; + goto fail; + } + return 0; + + fail: + common_proc_cleanup(); + return err; +} + +/*** module stuff ***/ + +static int __init common_init(void) +{ + printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", v" DRV_VERSION "\n"); + printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n"); + + rfkill_initialize(); + + if (rfkill_supported()) { + common_proc_init(); + if (radio != RADIO_NONE) + rfkill_set_radio(radio); + } else + printk(KERN_INFO DRV_NAME ": no supported wireless hardware found\n"); + + return 0; +} + +static void __exit common_exit(void) +{ + if (rfkill_supported() && autooff) + rfkill_set_radio(RADIO_OFF); + + common_proc_cleanup(); + rfkill_uninitialize(); + + printk(KERN_INFO DRV_NAME ": module removed successfully\n"); +} + +module_init(common_init); +module_exit(common_exit); + +/* + 1 2 3 4 5 6 7 +12345678901234567890123456789012345678901234567890123456789012345678901234567890 +*/ --- linux-2.6.28.orig/ubuntu/misc/Kconfig +++ linux-2.6.28/ubuntu/misc/Kconfig @@ -0,0 +1,36 @@ +config USB_APPLEIR + tristate "Apple USB Infrared Receiver" + default m + depends on USB + +config BLK_DEV_DM_BBR + tristate "Bad-block-relocation target for device-mapper" + default m + depends on BLK_DEV_DM + +config INPUT_ACERHK + tristate "Acer Travelmate laptop special key support" + default m + depends on X86_32 + +config FSAM7400 + tristate "SW RF kill switch for Fujitsu Siemens Amilo M 7400" + default m + select CHECK_SIGNATURE + +config LMPCM_USB + tristate "USB Logitech MediaPlay Cordless Mouse driver" + default m + depends on USB + +config TP_SMAPI + tristate "ThinkPad SMAPI Support" + default m + +config TP_SMAPI_EC + tristate "ThinkPad embedded controller LPC3 functions" + default m + +source "ubuntu/misc/media/Kconfig" + +source "ubuntu/misc/wireless/Kconfig" --- linux-2.6.28.orig/ubuntu/misc/acerhk.c +++ linux-2.6.28/ubuntu/misc/acerhk.c @@ -0,0 +1,3001 @@ +/********************************************************************* + * Filename: acerhk.c + * Version: 0.5 + * + * Copyright (C) 2002-2006, Olaf Tauber (olaf-tauber@versanet.de) + * + * Description: kernel driver for Acer Travelmate and similar + * laptops special keys + * Author: Olaf Tauber + * Created at: Mon Apr 29 22:16:42 2002 + * Modified at: Tue Feb 28 21:38:41 2006 + * Modified by: Olaf Tauber + * Modified at: Thu Nov 24 13:03:01 2005 + * Modified by: Antonio Cuni + * Modified at: Wed Oct 27 19:47:11 CEST 2004 + * Modified by: Joachim Fenkes + * + * This program is free software; you can redistribute + * it and/or modify it under the terms of the GNU General + * Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, + * Suite 330, Boston, MA 02111-1307 USA + * + * + */ + +/* This driver is heavily dependent on the architecture, don't let anyone + * without an X86 machine use it. I doubt that there are laptops out there + * which would need this driver and are not X86, so it doesn't matter anyway. + */ +#ifdef CONFIG_X86 + +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +#define KERNEL26 +#include +#else +#include +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) +#define STATIC_INPUT_DEV +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "acerhk.h" + +/* #define ACERDEBUG */ +/* #define DUMMYHW */ + +#define ACERHK_VERSION "0.5.34" +#define MODULE_NAME "acerhk" + +/* maximum number of polling loops, adjust it if needed to values between + * 1 and 32 + */ +#define MAX_POLLING_LOOPS 16U + +/* maximum length for model string */ +#define ACERHK_MODEL_STRLEN 16 +/* size of mapped areas */ +#define AREA_SIZE 0xffff +/* needed for colussi algorithm */ +#define XSIZE 20 + +/* Module parameters */ +static int poll=1; +static int autowlan; +static int usedritek=1; +static int wlan_state=-1; +static int bluetooth_state=-1; +static int verbose; +static unsigned int force_series; +#ifdef KERNEL26 +module_param(poll, int, 0444); +module_param(autowlan, int, 0444); +module_param(usedritek, int, 0444); +module_param(verbose, int, 0444); +module_param(wlan_state, int, 0444); +module_param(bluetooth_state, int, 0444); +module_param(force_series, uint, 0444); +#else +MODULE_PARM(poll, "i"); +MODULE_PARM(autowlan, "i"); +MODULE_PARM(wlan_state, "i"); +MODULE_PARM(bluetooth_state, "i"); +MODULE_PARM(usedritek, "i"); +MODULE_PARM(verbose, "i"); +MODULE_PARM(force_series, "i"); +#endif +MODULE_PARM_DESC(poll, "start polling timer"); +MODULE_PARM_DESC(autowlan, "automatic switching of wlan hardware"); +MODULE_PARM_DESC(wlan_state, "(assumed) initial state of WLAN LED/hardware"); +MODULE_PARM_DESC(bluetooth_state, "(assumed) initial state of Bluetooth LED/hardware"); +MODULE_PARM_DESC(usedritek, "enable dritek keyboard extension"); +MODULE_PARM_DESC(verbose, "output additional information"); +MODULE_PARM_DESC(force_series, "force laptop series, skip autodetection"); + +/* input device */ +static struct input_dev *acerhk_input_dev_ptr; +#ifdef STATIC_INPUT_DEV +static struct input_dev acerhk_input_dev; +#endif + +/* mapped IO area from 0xf0000 */ +static void *reg1; +/* mapped IO area from 0xe0000 */ +static void *reg2; +/* Pointer to mapped area at 0x400 on 520 series */ +static void *preg400; +/* location of IO routine in mapped area */ +static unsigned int bios_routine; +/* index of CMOS port to get key event */ +static unsigned int cmos_index; +/* function for bios call */ +static bios_call call_bios; +/* address of model string */ +static char *acerhk_model_addr; +/* copied string, maximum length 16 ('TravelMate xxx') */ +static char acerhk_model_string[ACERHK_MODEL_STRLEN]; +/* type of hardware access */ +static t_acer_type acerhk_type; +/* travelmate series */ +static unsigned int acerhk_series; +/* supported features for this model */ +static unsigned int acerhk_model_features; +/* map of acer key codes to acer key names */ +static unsigned char acerhk_key2name[0xff]; +/* map of acer key names to key events */ +static t_map_name2event acerhk_name2event; +/* timer for polling key presses */ +static struct timer_list acerhk_timer_poll; +/* polling active */ +static int acerhk_polling_state; +/* polling delay */ +static unsigned acerhk_polling_delay = HZ/5; +/* wlan hardware toggle */ +static int acerhk_wlan_state; +/* bluetooth hardware toggle */ +static int acerhk_bluetooth_state; + +/* bluetooth blinking state; added by Antonio Cuni + possible values: + -1: blinking disabled (default) + 0: blinking enabled, led currently off + 1: blinking enabled, led currently on +*/ +static int acerhk_blueled_blinking = -1; +/* delay between two changes of state, in jiffies */ +static unsigned acerhk_blueled_blinking_delay; +/* timer for blinking */ +static struct timer_list acerhk_timer_blinking; + +/* function prototypes */ +static void start_polling(void); +static void stop_polling(void); + +/* Added by Antonio Cuni */ +static void start_blinking(void); +static void stop_blinking(void); + +/* {{{ Experimental use of dritek keyboard extension */ + +#define EC_STATUS_REG 0x66 /* Status register of EC (R) */ +#define EC_CNTL_REG 0x66 /* Controller command register of EC (W) */ +#define EC_DATA_REG 0x62 /* EC data register (R/W) */ + +#ifdef KERNEL26 + +#include + +#define KBD_STATUS_REG 0x64 /* Status register (R) */ +#define KBD_CNTL_REG 0x64 /* Controller command register (W) */ +#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */ + +#else + +#ifndef KEY_MEDIA +#define KEY_MEDIA 226 +#endif + +#define preempt_disable() do { } while (0) +#define preempt_enable_no_resched() do { } while (0) +#define preempt_enable() do { } while (0) +#define preempt_check_resched() do { } while (0) +#include + +#endif + +static inline int my_i8042_read_status(void) +{ + return inb(KBD_STATUS_REG); +} +static int my_i8042_wait_write(void) +{ + int i = 0; + while ((my_i8042_read_status() & 0x02) && (i < 10000)) { + udelay(50); + i++; + } + return -(i == 10000); +} +static void send_kbd_cmd(unsigned char cmd, unsigned char val) +{ + if (usedritek) { + preempt_disable(); + if (!my_i8042_wait_write()) + outb(cmd, KBD_CNTL_REG); + if (!my_i8042_wait_write()) + outb(val, KBD_DATA_REG); + preempt_enable_no_resched(); + } else { + printk(KERN_INFO"acerhk: request for accessing EC ignored\n" + KERN_INFO"acerhk: Use of dritek keyboard extension not enabled, use module\n" + KERN_INFO"acerhk: parameter usedritek=1 to do that (possibly dangerous)\n"); + } +} +#ifdef ACERDEBUG +static inline int my_i8042_read_ecstatus(void) +{ + return inb(EC_STATUS_REG); +} +static int my_i8042_wait_ecwrite(void) +{ + int i = 0; + while ((my_i8042_read_ecstatus() & 0x02) && (i < 10000)) { + udelay(50); + i++; + } + return -(i == 10000); +} +static void send_ec_cmd(unsigned char cmd, unsigned char val) +{ + if (usedritek) { + preempt_disable(); + if (!my_i8042_wait_ecwrite()) + outb(cmd, EC_CNTL_REG); + if (!my_i8042_wait_ecwrite()) + outb(val, EC_DATA_REG); + preempt_enable_no_resched(); + } else { + printk(KERN_INFO"acerhk: request for accessing EC ignored\n" + KERN_INFO"acerhk: Use of dritek keyboard extension not enabled, use module\n" + KERN_INFO"acerhk: parameter usedritek=1 to do that (possibly dangerous)\n"); + } +} +#endif +#ifdef ACERDEBUG +static void enable_mute_led_ec(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: enabling mute led via EC\n"); + send_kbd_cmd(0x59, 0x94); +} +static void disable_mute_led_ec(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: disabling mute led via EC\n"); + send_kbd_cmd(0x59, 0x95); +} +static void enable_dmm_function(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: enabling WLAN via EC variant 2\n"); + send_kbd_cmd(0x45, 0xd3); +} +#endif +static void enable_wlan_ec_1(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: enabling WLAN via EC variant 1\n"); + send_kbd_cmd(0xe7, 0x01); + acerhk_wlan_state = 1; +} +static void disable_wlan_ec_1(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: disabling WLAN via EC variant 1\n"); + send_kbd_cmd(0xe7, 0x00); + acerhk_wlan_state = 0; +} +static void enable_bluetooth_ec_1(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: enabling Bluetooth via EC variant 1\n"); + send_kbd_cmd(0xe7, 0x03); + acerhk_bluetooth_state = 1; +} +static void disable_bluetooth_ec_1(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: disabling Bluetooth via EC variant 1\n"); + send_kbd_cmd(0xe7, 0x02); + acerhk_bluetooth_state = 0; +} +static void enable_wlan_ec_2(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: enabling WLAN via EC variant 2\n"); + send_kbd_cmd(0x45, acerhk_bluetooth_state ? 0xa2 : 0xa0); + acerhk_wlan_state = 1; +} +static void disable_wlan_ec_2(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: disabling WLAN via EC variant 2\n"); + send_kbd_cmd(0x45, acerhk_bluetooth_state ? 0xa1 : 0xa3); + acerhk_wlan_state = 0; +} +static void enable_bluetooth_ec_2(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: enabling Bluetooth via EC variant 2\n"); + send_kbd_cmd(0x45, acerhk_wlan_state ? 0xa2 : 0xa1); + acerhk_bluetooth_state = 1; +} +static void disable_bluetooth_ec_2(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: disabling Bluetooth via EC variant 2\n"); + send_kbd_cmd(0x45, acerhk_wlan_state ? 0xa0 : 0xa3); + acerhk_bluetooth_state = 0; +} +#ifdef ACERDEBUG +static void enable_wireless_ec(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: enabling wireless hardware\n"); + if (usedritek) { + preempt_disable(); + if (!my_i8042_wait_ecwrite()) + outb(0x4d, EC_CNTL_REG); + if (!my_i8042_wait_ecwrite()) + outb(0xd2, EC_DATA_REG); + if (!my_i8042_wait_ecwrite()) + outb(0x01, EC_DATA_REG); + preempt_enable_no_resched(); + } + acerhk_wlan_state = 1; +} +static void disable_wireless_ec(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: disabling wireless hardware\n"); + if (usedritek) { + preempt_disable(); + if (!my_i8042_wait_ecwrite()) + outb(0x4d, EC_CNTL_REG); + if (!my_i8042_wait_ecwrite()) + outb(0xd2, EC_DATA_REG); + if (!my_i8042_wait_ecwrite()) + outb(0x00, EC_DATA_REG); + preempt_enable_no_resched(); + } + acerhk_wlan_state = 0; +} +#endif +static void enable_dritek_keyboard(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: enabling dritek keyboard extension\n"); + send_kbd_cmd(0x59, 0x90); +} +static void disable_dritek_keyboard(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: disabling dritek keyboard extension\n"); + send_kbd_cmd(0x59, 0x91); +} +static void enable_mail_led_ec_1(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: enabling mail led via EC variant 1\n"); + send_kbd_cmd(0xe8, 0x01); +} +static void disable_mail_led_ec_1(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: disabling mail led via EC variant 1\n"); + send_kbd_cmd(0xe8, 0x00); +} + +static void enable_mail_led_ec_2(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: enabling mail led via EC variant 2\n"); + send_kbd_cmd(0x59, 0x92); +} +static void disable_mail_led_ec_2(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: disabling mail led via EC variant 2\n"); + send_kbd_cmd(0x59, 0x93); +} +static void enable_mail_led_ec_3(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: enabling mail led via EC variant 3\n"); + if (usedritek) { + preempt_disable(); + if (!my_i8042_wait_write()) + outl(0x80008894, 0xCF8); + if (!my_i8042_wait_write()) + outw(0xC061, 0xCFC); + preempt_enable_no_resched(); + } +} +static void disable_mail_led_ec_3(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: disabling mail led via EC variant 3\n"); + if (usedritek) { + preempt_disable(); + if (!my_i8042_wait_write()) + outl(0x80008894, 0xCF8); + if (!my_i8042_wait_write()) + outw(0xC060, 0xCFC); + preempt_enable_no_resched(); + } +} + +/* }}} */ + +/* {{{ string search functions */ + +/* This is the Colussi algorithm, the code is taken from + http://www-igm.univ-mlv.fr/~lecroq/string +*/ +int preColussi(char *x, int m, int *h, int *next, int *shift) +{ + int i, k, nd, q, r, s; + int hmax[XSIZE], kmin[XSIZE], nhd0[XSIZE], rmin[XSIZE]; + /* Computation of hmax */ + i = k = 1; + do { + while (x[i] == x[i - k]) + i++; + hmax[k] = i; + q = k + 1; + while (hmax[q - k] + k < i) { + hmax[q] = hmax[q - k] + k; + q++; + } + k = q; + if (k == i + 1) + i = k; + } while (k <= m); /* Computation of kmin */ + memset(kmin, 0, m*sizeof(int)); + r = 0; + for (i = m; i >= 1; --i) + if (hmax[i] < m) + kmin[hmax[i]] = i; /* Computation of rmin */ + for (i = m - 1; i >= 0; --i) { + if (hmax[i + 1] == m) + r = i + 1; + if (kmin[i] == 0) + rmin[i] = r; + else + rmin[i] = 0; + } /* Computation of h */ + s = -1; + r = m; + for (i = 0; i < m; ++i) + if (kmin[i] == 0) + h[--r] = i; + else + h[++s] = i; + nd = s; /* Computation of shift */ + for (i = 0; i <= nd; ++i) + shift[i] = kmin[h[i]]; + for (i = nd + 1; i < m; ++i) + shift[i] = rmin[h[i]]; + shift[m] = rmin[0]; /* Computation of nhd0 */ + s = 0; + for (i = 0; i < m; ++i) { + nhd0[i] = s; + if (kmin[i] > 0) + ++s; + } /* Computation of next */ + for (i = 0; i <= nd; ++i) + next[i] = nhd0[h[i] - kmin[h[i]]]; + for (i = nd + 1; i < m; ++i) + next[i] = nhd0[m - rmin[h[i]]]; + next[m] = nhd0[m - rmin[h[m - 1]]]; return(nd); +} + +int COLUSSI(char *x, int m, char *y, int n) { + int i, j, last, nd, + h[XSIZE], next[XSIZE], shift[XSIZE]; /* Processing */ + int match_pos; /* position of first match */ + nd = preColussi(x, m, h, next, shift); /* Searching */ + i = j = 0; + last = -1; + match_pos = -1; + while ( (match_pos == -1) + && (j <= n - m) ) { + while (i < m && last < j + h[i] && + x[h[i]] == y[j + h[i]]) + i++; + if (i >= m || last >= j + h[i]) { + /* Match found, bail out */ + match_pos = j; + i = m; + } + if (i > nd) + last = j + m - 1; + j += shift[i]; + i = next[i]; + } + return match_pos; +} + +/* }}} */ + +/* {{{ hardware access functions */ + +/* call_bios_ + * + * call request handler in mapped system rom + * + * the request is handed over via all 6 general purpose registers, results are + * taken from them and copied back to buf + */ +static asmlinkage void call_bios_6xx(struct register_buffer *buf) +{ + if (bios_routine) { + local_irq_disable(); + __asm__ __volatile__( + "movl %1,%%edx\n\t" + "pusha\n\t" + "movl %%edx,%%ebp\n\t" + "movl (%%ebp),%%eax\n\t" + "movl 4(%%ebp),%%ebx\n\t" + "movl 8(%%ebp),%%ecx\n\t" + "movl 12(%%ebp),%%edx\n\t" + "movl 16(%%ebp),%%edi\n\t" + "movl 20(%%ebp),%%esi\n\t" + "pushl %%ebp\n\t" + "call *%0\n\t" + "popl %%ebp\n\t" + "movl %%eax, (%%ebp)\n\t" + "movl %%ebx, 4(%%ebp)\n\t" + "movl %%ecx, 8(%%ebp)\n\t" + "movl %%edx, 12(%%ebp)\n\t" + "movl %%edi, 16(%%ebp)\n\t" + "movl %%esi, 20(%%ebp)\n\t" + "popa\n\t" + : + :"m" (bios_routine), "m" (buf) + :"%eax", "%ebx", "%ecx", "%edx", "%edi", "%esi"//, "%ebp" + ); + local_irq_enable(); + } +} + +static asmlinkage void call_bios_52x(struct register_buffer *buf) +{ + if (bios_routine) { + local_irq_disable(); + __asm__ __volatile__( + "movl %2,%%edx\n\t" + "pusha\n\t" + "movl %%edx,%%ebp\n\t" + "movl (%%ebp),%%eax\n\t" + "movl 4(%%ebp),%%ebx\n\t" + "movl 8(%%ebp),%%ecx\n\t" + "movl 12(%%ebp),%%edx\n\t" + "movl 16(%%ebp),%%edi\n\t" + "movl 20(%%ebp),%%esi\n\t" + "pushl %%ebp\n\t" + "movl %1, %%ebp\n\t" + "call *%0\n\t" + "popl %%ebp\n\t" + "movl %%eax, (%%ebp)\n\t" + "movl %%ebx, 4(%%ebp)\n\t" + "movl %%ecx, 8(%%ebp)\n\t" + "movl %%edx, 12(%%ebp)\n\t" + "movl %%edi, 16(%%ebp)\n\t" + "movl %%esi, 20(%%ebp)\n\t" + "popa\n\t" + : + :"m" (bios_routine), "m" (preg400), "m" (buf) + :"%eax", "%ebx", "%ecx", "%edx", "%edi", "%esi"//, "%ebp" + ); + local_irq_enable(); + } +} + +#define PRINT_BUFFER(x) \ + printk(KERN_INFO"acerhk: eax=0x%x ebx=0x%x ecx=0x%x edx=0x%x\n" \ + "acerhk: edi=0x%x esi=0x%x ebp=0x%x\n", \ + x.eax, x.ebx, x.ecx, x.edx, x.edi, x.esi, x.ebp); + +/* get_fnkey_event + * + * gets the first (oldest) key id from the queue of events + * + * return value: id of key + */ +static int get_fnkey_event(void) +{ + struct register_buffer regs; + regs.eax = 0x9610; + regs.ebx = 0x61C; + /* clear other registers, some models need this */ + regs.ecx = 0; + regs.edx = 0; + preempt_disable(); + call_bios(®s); + preempt_enable_no_resched(); + return regs.eax & 0xffff; +} + +/* get_thermal_event + * + * does what? + * + * return value: event ? + */ +static int get_thermal_event(void) +{ + struct register_buffer regs; + if (acerhk_model_features & TM_F_THERMAL) { + regs.eax = 0x9612; + regs.ebx = 0x12e; + preempt_disable(); + call_bios(®s); + preempt_enable_no_resched(); + if (verbose > 3) + printk(KERN_INFO"acerhk: thermal event = 0x%x\n", regs.eax); + } else { + regs.eax = 0x00; + if (verbose > 3) + printk(KERN_INFO"acerhk: thermal event not supported\n"); + } + return regs.eax & 0xffff; +} + +#ifdef ACERDEBUG +/* pbutton_fct + * + * does what? + * + * return value: ? + */ +static int pbutton_fct(void) +{ + struct register_buffer regs; + if (acerhk_model_features & TM_F_PBUTTON) { + regs.eax = 0x9612; + regs.ebx = 0x10b; + regs.ecx = 0x2; + preempt_disable(); + call_bios(®s); + preempt_enable_no_resched(); + if (verbose > 3) + printk(KERN_INFO"acerhk: pbutton = 0x%x\n", regs.eax); + } else { + if (verbose > 3) + printk(KERN_INFO"acerhk: pbutton function not supported\n"); + regs.eax = 0x00; + } + return regs.eax & 0xffff; +} +#endif + +/* wbutton_fct_1 + * + * turn on installed Bluetooth hardware together with the corresponding LED + * + * val: 0 turns off the LED + * 1 turns the LED to green/blue + * + * return value: ? + */ +static int wbutton_fct_1(int val) +{ + struct register_buffer regs; + if (acerhk_model_features & TM_F_WBUTTON) { + acerhk_bluetooth_state = val; + regs.eax = 0x9610; + regs.ebx = ((val & 0xff) << 8) | 0x34; + preempt_disable(); + call_bios(®s); + preempt_enable_no_resched(); + if (verbose > 3) + printk(KERN_INFO"acerhk: wbutton1 = 0x%x\n", regs.eax); + } else { + if (verbose > 3) + printk(KERN_INFO"acerhk: wbutton function 1 not supported\n"); + regs.eax = 0x00; + } + return regs.eax & 0xffff; +} + +/* wbutton_fct_2 + * + * turn on installed WLAN hardware together with the corresponding LED + * + * val: 0 turns off the LED + * 1 turns the LED to orange + * + * return value: ? + */ +static int wbutton_fct_2(int val) +{ + struct register_buffer regs; + if (acerhk_model_features & TM_F_WBUTTON) { + acerhk_wlan_state = val; + regs.eax = 0x9610; + regs.ebx = ((val & 0xff) << 8) | 0x35; + preempt_disable(); + call_bios(®s); + preempt_enable_no_resched(); + if (verbose > 3) + printk(KERN_INFO"acerhk: wbutton2 = 0x%x\n", regs.eax); + } else { + if (verbose > 3) + printk(KERN_INFO"acerhk: wbutton function 2 not supported\n"); + regs.eax = 0x00; + } + return regs.eax & 0xffff; +} + +/* get_cmos_index + * + * gets index of CMOS port from ROM. The number of events is monitored + * in this port. + * + * return value: index of CMOS port + */ +static int get_cmos_index(void) +{ + struct register_buffer regs; + regs.eax = 0x9610; + regs.ebx = 0x51C; + preempt_disable(); + call_bios(®s); + preempt_enable_no_resched(); + cmos_index = regs.ecx & 0xff; + if (verbose) + printk(KERN_INFO"acerhk: cmos index set to 0x%x\n", cmos_index); + return cmos_index; +} + +/* get_nr_events + * + * gets the number of cached events (keys pressed) in queue. Up to 31 events + * are cached. + * + * return value: number of events in queue + */ +static int get_nr_events(void) +{ + unsigned long flags; + unsigned char c = 0; + + spin_lock_irqsave (&rtc_lock, flags); +#ifndef DUMMYHW + if (cmos_index) + c = CMOS_READ(cmos_index); + else if (verbose > 3) + printk(KERN_INFO"acerhk: get_nr_events - no valid cmos index set\n"); +#endif + spin_unlock_irqrestore (&rtc_lock, flags); + return c; +} + +/* set_mail_led + * + * change state of mail led + * + * val: 0 - switch led off + * 1 - switch led on (blinking) + * + * return value: 1 - action succesfull (val valid) + * 0 - no action taken (val invalid) + */ +static int set_mail_led(int val) +{ + struct register_buffer regs; + if (acerhk_model_features & TM_F_MAIL_LED) { + regs.eax = 0x9610; + regs.ebx = ((val & 0xff) << 8) | 0x31; + preempt_disable(); + call_bios(®s); + preempt_enable_no_resched(); + if (verbose > 3) + printk(KERN_INFO"acerhk: mail led set to = 0x%x\n", val); + } else if (acerhk_model_features & TM_F_MAIL_LED_EC) { + if (val == 1) + enable_mail_led_ec_1(); + else if (val == 0) + disable_mail_led_ec_1(); + } else if (acerhk_model_features & TM_F_MAIL_LED_EC2) { + if (val == 1) + enable_mail_led_ec_2(); + else if (val == 0) + disable_mail_led_ec_2(); + } else if (acerhk_model_features & TM_F_MAIL_LED_EC3) { + if (val == 1) + enable_mail_led_ec_3(); + else if (val == 0) + disable_mail_led_ec_3(); + } else { + if (verbose > 3) + printk(KERN_INFO"acerhk: mail led not supported\n"); + regs.eax = 0x00; + } + return regs.eax & 0xffff; +} + +/* launch_connect + * + * does what? + * val: 1 - only known value from windows driver + */ +static int launch_connect(int val) +{ + struct register_buffer regs; + if (acerhk_model_features & TM_F_CONNECT) { + regs.eax = 0x9610; + regs.ebx = ((val & 0xff) << 8) | 0x2e; + preempt_disable(); + call_bios(®s); + preempt_enable_no_resched(); + if (verbose > 3) + printk(KERN_INFO"acerhk: connect(%d) = 0x%x\n", val, regs.eax); + } else { + if (verbose > 3) + printk(KERN_INFO"acerhk: connect not supported\n"); + regs.eax = 0x00; + } + return regs.eax & 0xffff; +} + +/* }}} */ + +/* {{{ hardware probing */ + +static struct proc_dir_entry *proc_acer_dir; + +static unsigned int __init find_hk_area(void) +{ + int offset, sig; + unsigned int fkt; + fkt = 0; + sig = -1; /* offset to signature in io area */ + /* Look for signature, start at 0xf0000, search until 0xffff0 */ + for (offset = 0;offset < 0xfffd; offset += 16) { + if (readl(reg1 + offset) == 0x30552142) { + sig = offset; + offset = 0xffff; + } + } + if (sig < 0) + printk(KERN_WARNING"acerhk: could not find request handler, possibly not all functions available\n"); + else { + /* compute location of bios routine */ + fkt = readl(reg1 + sig + 5); + /* adjust fkt to address of mapped IO area */ + if (fkt >= 0xf0000) + fkt = (unsigned int)reg1 + fkt - 0xf0000; + else if (fkt >= 0xe0000) + fkt = (unsigned int)reg1 + fkt - 0xe0000; + else + fkt = 0; + } + return fkt; +} + +static void print_features(void) +{ + int i; + printk(KERN_INFO"acerhk: supported keys:"); + for (i = 0; i < 255; i++) { + switch (acerhk_key2name[i]) { + case k_help: printk(" help"); break; + case k_setup: printk(" setup"); break; + case k_p1: printk(" p1"); break; + case k_p2: printk(" p2"); break; + case k_p3: printk(" p3"); break; + case k_www: printk(" www"); break; + case k_mail: printk(" mail"); break; + case k_wireless: printk(" wireless"); break; + case k_power: printk(" power"); break; + case k_mute: printk(" mute"); break; + case k_volup: printk(" volup"); break; + case k_voldn: printk(" voldn"); break; + case k_res: printk(" res"); break; + case k_close: printk(" close"); break; + case k_open: printk(" open"); break; + case k_wireless2: printk(" wireless2"); break; + case k_play: printk(" play"); break; + case k_stop: printk(" stop"); break; + case k_prev: printk(" prev"); break; + case k_next: printk(" next"); break; + case k_display: printk(" display"); break; + default: break; + } + } + printk("\n"); + if (acerhk_model_features & TM_F_MUTE_LED_EC) + printk(KERN_INFO"acerhk: mute led is supported\n"); + if (acerhk_model_features & TM_F_MAIL_LED) + printk(KERN_INFO"acerhk: mail led is supported\n"); + else if (acerhk_model_features & TM_F_MAIL_LED_EC) + printk(KERN_INFO"acerhk: mail led (EC) is supported\n"); + else if (acerhk_model_features & TM_F_MAIL_LED_EC2) + printk(KERN_INFO"acerhk: mail led (EC2) is supported\n"); + else if (acerhk_model_features & TM_F_MAIL_LED_EC3) + printk(KERN_INFO"acerhk: mail led (EC3) is supported\n"); + printk(KERN_INFO"acerhk: supported functions:"); + if (acerhk_model_features & TM_F_CONNECT) + printk(" connect"); + if (acerhk_model_features & TM_F_THERMAL) + printk(" thermal"); + if (acerhk_model_features & TM_F_PBUTTON) + printk(" pbutton"); + if (acerhk_model_features & TM_F_WBUTTON) + printk(" wbutton"); + printk("\n"); +} + +static void __init setup_keymap_model(unsigned int series) +{ + /* clear mapping keycode -> keyname, */ + memset(&acerhk_key2name[0], k_none, sizeof(acerhk_key2name)); + /* first set the common keys, namely FnF1 and FnF2, */ + acerhk_key2name[1] = k_help; + acerhk_key2name[2] = k_setup; + /* then set known keycodes according to model */ + switch (series) { + case 110: + acerhk_key2name[48] = k_wireless; + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + acerhk_key2name[54] = k_www; + acerhk_key2name[49] = k_mail; + acerhk_key2name[3] = k_power; + acerhk_key2name[8] = k_mute; + acerhk_key2name[32] = k_volup; + acerhk_key2name[33] = k_voldn; + /* C110 generates 2 extra codes when opening/closing the lid */ + acerhk_key2name[74] = k_close; + acerhk_key2name[75] = k_open; + break; + case 300: /* treat C300 like C100 with Bluetooth button */ + acerhk_key2name[68] = k_wireless2; + case 100: + acerhk_key2name[48] = k_wireless; + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + acerhk_key2name[49] = k_www; + acerhk_key2name[54] = k_mail; + acerhk_key2name[3] = k_power; + acerhk_key2name[8] = k_mute; + acerhk_key2name[32] = k_volup; + acerhk_key2name[33] = k_voldn; + break; + default: + /* only the two common keys are supported */ + break; + case 210: + acerhk_key2name[19] = k_p1; + acerhk_key2name[20] = k_p2; + acerhk_key2name[17] = k_www; + acerhk_key2name[18] = k_mail; + break; + case 220: + case 260: /* 260 with same keys? */ + acerhk_key2name[49] = k_p1; + acerhk_key2name[19] = k_p2; + acerhk_key2name[18] = k_www; + acerhk_key2name[17] = k_mail; + break; + case 230: + case 280: /* 280 with same keys? */ + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + acerhk_key2name[49] = k_mail; + acerhk_key2name[54] = k_www; + break; + case 1500: + acerhk_key2name[0x49] = k_setup; + acerhk_key2name[0x36] = k_www; + acerhk_key2name[0x31] = k_mail; + acerhk_key2name[0x11] = k_p1; + acerhk_key2name[0x12] = k_p2; + acerhk_key2name[0x30] = k_wireless; + acerhk_key2name[0x44] = k_wireless2; + acerhk_key2name[0x03] = k_power; + break; + case 240: + acerhk_key2name[0x31] = k_www; + acerhk_key2name[0x36] = k_mail; + acerhk_key2name[0x11] = k_p1; + acerhk_key2name[0x12] = k_p2; + acerhk_key2name[0x44] = k_wireless; + acerhk_key2name[0x30] = k_wireless2; + acerhk_key2name[0x03] = k_power; + acerhk_key2name[0x08] = k_mute; + // acerhk_key2name[] = k_volup; + // acerhk_key2name[] = k_voldn; + break; + case 2900: + acerhk_key2name[0x31] = k_mail; /* with led */ + acerhk_key2name[0x36] = k_www; + acerhk_key2name[0x11] = k_p1; + acerhk_key2name[0x12] = k_p2; + acerhk_key2name[0x30] = k_wireless; /* wireless, with led, related with autowlan=1 */ + break; + case 250: /* enriqueg@altern.org */ + /* TravelMate 254LMi_DT manual common for 240/250 series, but key order + differ from 240 already present on acerhk driver */ + /* TravelMate 254LMi_DT: 6 buttons: left to right: mail, www, p1, p2, bluetooth, wireless */ + acerhk_key2name[0x31] = k_mail; /* with led */ + acerhk_key2name[0x36] = k_www; + acerhk_key2name[0x11] = k_p1; + acerhk_key2name[0x12] = k_p2; + acerhk_key2name[0x44] = k_wireless2; /* bluetooth, hw optional */ + acerhk_key2name[0x30] = k_wireless; /* wireless, with led, related with autowlan=1 */ + acerhk_key2name[0x03] = k_power; /* Fn+F3 */ + acerhk_key2name[0x08] = k_mute; /* Fn+F8 */ + break; + case 380: + /* TM 380 has same codes as TM 370, with an additional one */ + acerhk_key2name[0x03] = k_power; + case 370: + acerhk_key2name[0x30] = k_wireless; + acerhk_key2name[0x11] = k_p1; + acerhk_key2name[0x12] = k_p2; + acerhk_key2name[0x13] = k_p3; + acerhk_key2name[0x36] = k_www; + acerhk_key2name[0x31] = k_mail; + break; + case 360: + /* 360 series has the same layout as 350, with an + additional wireless key */ + acerhk_key2name[64] = k_wireless; + case 350: + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + acerhk_key2name[20] = k_p3; + acerhk_key2name[21] = k_www; + acerhk_key2name[19] = k_mail; + break; + case 520: + acerhk_key2name[19] = k_p1; + acerhk_key2name[20] = k_p2; + acerhk_key2name[17] = k_www; + acerhk_key2name[18] = k_mail; + break; + case 610: + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + acerhk_key2name[19] = k_p3; + acerhk_key2name[21] = k_www; + acerhk_key2name[20] = k_mail; + acerhk_key2name[64] = k_wireless; + break; + case 630: + /* 630 has all keys of 620 plus one */ + acerhk_key2name[8] = k_mute; + case 620: + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + acerhk_key2name[19] = k_p3; + acerhk_key2name[54] = k_www; + acerhk_key2name[49] = k_mail; + acerhk_key2name[48] = k_wireless; + acerhk_key2name[3] = k_power; + acerhk_key2name[32] = k_volup; + acerhk_key2name[33] = k_voldn; + break; + case 290: + case 420: + case 430: + case 530: + case 540: + case 650: + case 660: + case 800: + case 1450: + case 2300: + case 2350: + case 4000: + case 4050: + case 6000: + case 8000: + case 4100: + case 4150: + case 4500: + case 4600: + case 4650: + case 1680: + case 1690: + /* keys are handled by dritek EC */ + acerhk_key2name[1] = k_none; + acerhk_key2name[2] = k_none; + break; + case 1300: + case 1310: + case 1350: + case 1360: + case 1400: + case 1700: + case 1800: + case 2000: + case 2010: + case 2020: + /* Aspire 13xx series laptops use dritek hardware, no + acerhk-mapping needed + VolUp and VolDown are managed as normal keys + 1300/1310 series should have P1, P2, Mail, WWW, Mute buttons + 1353 has bluetooth, wifi, p1, p2, www, mail, help, setup, power + and mute + Aspire 1400/1450/Ferrari use dritek EC, too + 1450 should have bluetooth, wifi, p1, p2, www, mail, help, + setup, power and mute + Aspire 1700 uses dritek EC, too + 1700 should have bluetooth, wifi, p1, p2, www, mail, help, + setup, power and mute + need the MM-buttons Activation? (forward, shuffle, ...) + 2000 hast lots of MM buttons + 2010 should have bluetooth, wifi, p1, p2, www, mail, help, + setup, power and mute + */ + acerhk_key2name[1] = k_none; + acerhk_key2name[2] = k_none; + break; + case 1600: + /* Aspire 1600 has acer keycode 0x49 for FnF2 */ + acerhk_key2name[73] = k_setup; + acerhk_key2name[48] = k_wireless; + acerhk_key2name[49] = k_mail; + acerhk_key2name[54] = k_www; + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + acerhk_key2name[19] = k_p3; + acerhk_key2name[3] = k_power; + acerhk_key2name[8] = k_mute; + /* VolUp and VolDown keys doesn't seem to be managed as special keys + but as normal keys ! */ + break; + case 5020: /* Aspire 5020 has 0x6a for Fn+F2 */ + acerhk_key2name[2] = k_none; + acerhk_key2name[106] = k_setup; + acerhk_key2name[3] = k_power; + acerhk_key2name[5] = k_display; + acerhk_key2name[49] = k_mail; + acerhk_key2name[54] = k_www; + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + acerhk_key2name[48] = k_wireless; + acerhk_key2name[68] = k_wireless2; + break; + case 2410: /* TM 2410 is very similar to Aspire 5020, but has 0x6s for Fn-F3 */ + acerhk_key2name[2] = k_none; + acerhk_key2name[106] = k_setup; + acerhk_key2name[109] = k_power; + acerhk_key2name[49] = k_mail; + acerhk_key2name[54] = k_www; + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + acerhk_key2name[48] = k_wireless; + acerhk_key2name[68] = k_wireless2; + break; + case 40100: + /* Medion MD40100, 4 keys */ + acerhk_key2name[54] = k_www; + acerhk_key2name[49] = k_mail; + acerhk_key2name[48] = k_wireless; + acerhk_key2name[55] = k_res; + break; + case 96500: + case 95400: + /* Medion MD95400, many keys */ + acerhk_key2name[49] = k_mail; /* 1 */ + acerhk_key2name[54] = k_www; /* 2 */ + acerhk_key2name[48] = k_wireless; /* 3 */ + acerhk_key2name[68] = k_wireless2; /* 4 (Bluetooth) */ + + acerhk_key2name[17] = k_p1; /* 5 */ + acerhk_key2name[18] = k_p2; /* 6 */ + acerhk_key2name[36] = k_play; /* 7 */ + acerhk_key2name[37] = k_stop; /* 8 */ + acerhk_key2name[34] = k_prev; /* 9 */ + acerhk_key2name[35] = k_next; /* 10 */ + acerhk_key2name[33] = k_voldn; /* 11 */ + acerhk_key2name[32] = k_volup; /* 12 */ + acerhk_key2name[38] = k_p3; /* 13 */ + acerhk_key2name[8] = k_mute; /* 14 */ + + acerhk_key2name[1] = k_help; /* FN+F1 (Help) */ + acerhk_key2name[5] = k_display; /* FN+F3 (Display switch) */ + acerhk_key2name[6] = k_res; /* FN+F4 (Display ein/ausschalten) */ + break; + case 42200: + /* Medion MD42200, 7 keys, no setup */ + acerhk_key2name[2] = k_none; + acerhk_key2name[5] = k_display; + acerhk_key2name[54] = k_www; + acerhk_key2name[48] = k_wireless; + acerhk_key2name[49] = k_mail; + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + break; + case 9783: + /* Medion MD9783, 6 keys + info, no setup */ + acerhk_key2name[2] = k_none; + acerhk_key2name[54] = k_www; + acerhk_key2name[49] = k_mail; + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + acerhk_key2name[19] = k_p3; + acerhk_key2name[8] = k_mute; + break; + case 7400: + /* Amilo Pro V2000 does not have Help and Setup key (?) + Amilo M 7400 has Help key, disabling only setup + */ + acerhk_key2name[2] = k_none; + acerhk_key2name[48] = k_wireless; + acerhk_key2name[49] = k_mail; + acerhk_key2name[54] = k_www; + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + break; + case 1559: + acerhk_key2name[6] = k_display; /* FN+F4 (Display ein/ausschalten) */ + case 1555: + /* AOpen (Ahtec Signal 1555M) is similar to FS Amilo M */ + acerhk_key2name[2] = k_none; + acerhk_key2name[48] = k_wireless; + acerhk_key2name[49] = k_mail; + acerhk_key2name[54] = k_www; + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + acerhk_key2name[34] = k_prev; + acerhk_key2name[35] = k_next; + acerhk_key2name[36] = k_play; + acerhk_key2name[37] = k_stop; + break; + case 6800: + case 7820: + /* Amilo D does not have Setup key */ + acerhk_key2name[2] = k_none; + acerhk_key2name[49] = k_mail; + acerhk_key2name[54] = k_www; + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + acerhk_key2name[19] = k_p3; + acerhk_key2name[8] = k_mute; + break; + case 6805: /* Added by damagedspline@aim.com */ + /* Amilo A1xxx does not have Setup key nor a mail key */ + acerhk_key2name[2] = k_none; + acerhk_key2name[54] = k_www; + acerhk_key2name[5] = k_display; + acerhk_key2name[110] = k_setup; //This is the Fancy Fan (cool-n'-quiet) key on A1650g + acerhk_key2name[48] = k_wireless; + break; + } +} + +static void __init setup_model_features(unsigned int series) +{ + switch (series) { + case 200: + case 210: + case 520: + /* nothing special */ + acerhk_model_features = 0; + acerhk_type = TM_old; + break; + case 220: + case 230: + case 260: + case 280: + case 360: + case 40100: /* Medion MD40100 */ + case 95400: /* Medion MD95400 */ + case 96500: /* Medion MD96500 */ + /* all special functions, no mail led */ + acerhk_model_features = 0x00f00000; + acerhk_type = TM_new; + break; + case 42200: /* Medion MD42200 */ + /* has WLAN button, should call connect() */ + acerhk_model_features = TM_F_WBUTTON | TM_F_CONNECT; + acerhk_type = TM_old; + break; + case 9783: /* Medion MD9783 */ + /* only email led */ + acerhk_model_features = TM_F_MAIL_LED; + acerhk_type = TM_new; + break; + case 1600: + acerhk_type = TM_new; + /* Do Aspire 1600 series have special functions or not ? I enable + them, perhaps it helps with problems Francois Valenduc has */ + acerhk_model_features = 0x00f00000; + break; + case 300: + case 100: + case 110: + case 240: + case 350: + case 610: + case 620: + case 630: + /* all special functions, mail led */ + acerhk_model_features = TM_F_MAIL_LED | 0x00f00000; + acerhk_type = TM_new; + break; + case 370: + case 380: + case 2410: + case 2900: /* Medion MD2900 */ + case 2100: /* TM 2100 uses same driver as 5020 */ + case 5020: /* Aspire 5020 is still old hardware */ + acerhk_model_features = TM_F_MAIL_LED | TM_F_CONNECT| TM_F_WBUTTON; + acerhk_type = TM_new; + break; + case 7400: + case 1555: + case 1559: + /* all special functions for Fujitsu-Siemens Amilo M7400, Pro V2000; AOpen */ + acerhk_model_features = 0x00f00000; + acerhk_type = TM_new; + break; + case 6805: /* Added by damagedspline@aim.com */ + /* Amilo A1xxx does not have a mail led */ + acerhk_model_features = 0x00f00000; + acerhk_type = TM_new; + break; + case 6800: + case 7820: + /* mail led and all special functions for FS Amilo D */ + acerhk_model_features = TM_F_MAIL_LED | 0x00f00000; + acerhk_type = TM_new; + break; + case 2350: + case 4050: + acerhk_wlan_state = 1; // Default state is on + case 290: + /* no special functions, wireless hardware controlled by EC */ + acerhk_model_features = TM_F_WLAN_EC2 | TM_F_BLUE_EC2; + acerhk_type = TM_dritek; + break; + case 650: + case 1300: + case 1310: + case 1400: + case 1700: + /* all special functions, wireless hardware can be controlled */ + acerhk_model_features = 0x00f00000; + acerhk_type = TM_dritek; + break; + case 4100: + case 4600: + case 1680: + case 1690: /* Aspire 1680/1690 should be similar to TM 4100/4600 */ + /* mail led, wireless and bluetooth controlled the old way, but keys are + controlled by normal keyboard controller, so mark as dritek and + deactivate dritek use */ + acerhk_model_features = TM_F_MAIL_LED | TM_F_WBUTTON; + acerhk_type = TM_dritek; + usedritek=0; + break; + case 660: + case 800: + /* all special functions, mail led */ + acerhk_model_features = TM_F_MAIL_LED | 0x00f00000; + acerhk_type = TM_dritek; + break; + case 1350: + case 1360: + /* mail led, handled by EC, wireless HW is not (yet) controllable ? */ + acerhk_model_features = TM_F_MAIL_LED_EC|TM_F_WLAN_EC1; + acerhk_type = TM_dritek; + break; + case 1450: + /* Bluetooth/Wlan led, Mail led handled by EC (variant 3) */ + acerhk_model_features = TM_F_MAIL_LED_EC3|TM_F_WBUTTON; + acerhk_type = TM_dritek; + break; + case 1500: + /* Bluetooth/Wlan led */ + acerhk_model_features = TM_F_WBUTTON; + acerhk_type = TM_new; + break; + case 420: + case 430: + /* all functions and dritek EC, mail LED is handled by EC, second + variant. An additional led is available, mute. (really?) + */ + acerhk_type = TM_dritek; + acerhk_model_features = TM_F_MUTE_LED_EC|TM_F_MAIL_LED_EC2; + break; + case 2300: + case 4000: + case 4500: + /* wireless hardware, hopefully under control of my driver */ + acerhk_type = TM_dritek; + acerhk_model_features = TM_F_BLUE_EC1|TM_F_WLAN_EC1; + break; + case 3200: + /* test, if this model uses old style wlan control */ + acerhk_model_features = TM_F_WBUTTON; + acerhk_type = TM_dritek; + break; + case 6000: + case 8000: + /* 6000 and 8000 have wireless hardware, but I don't know how to handle, + so I choose no features */ + acerhk_type = TM_dritek; + break; + case 530: + case 540: + case 2000: + /* No features (?) dritek EC, mail LED is handled by EC but + different from other Aspire series */ + acerhk_type = TM_dritek; + acerhk_model_features = TM_F_MAIL_LED_EC2; + break; + case 4150: + case 4650: + /* Dritek EC, bluetooth, wifi, mail */ + /* According to Andreas Stumpfl his TM 4652LMi does also work as series + 3200, which might mean that the BIOS function accesses the EC */ + acerhk_type = TM_dritek; + acerhk_model_features = TM_F_MAIL_LED_EC2 | TM_F_WLAN_EC2 | TM_F_BLUE_EC2; + break; + case 1800: + case 2010: + case 2020: + /* Dritek EC, bluetooth, wifi, mail */ + acerhk_type = TM_dritek; + acerhk_model_features = TM_F_MAIL_LED_EC2 | TM_F_WLAN_EC2 | TM_F_BLUE_EC2; + acerhk_wlan_state = 1; // Default state is on + break; + case 250: /* enriqueg@altern.org */ + /* TravelMate254LMi_DT : mail led, bluetooth (button present, hw optional), wifi (with led) */ + acerhk_model_features = TM_F_MAIL_LED| + TM_F_WBUTTON ; + acerhk_type = TM_new; + acerhk_wlan_state = 0; //Initial state is off on 254LMi_DT + break; + default: + /* nothing special */ + acerhk_model_features = 0; + acerhk_type = TM_unknown; + break; + } + /* set the correct bios call function according to type */ + if ((acerhk_type == TM_new) || (acerhk_type == TM_dritek)) { + call_bios = call_bios_6xx; + if (verbose > 2) + printk(KERN_INFO"acerhk: using call_bios_6xx mode\n"); + } else { + call_bios = call_bios_52x; + if (verbose > 2) + printk(KERN_INFO"acerhk: using call_bios_52x mode\n"); + } + /* remove key file on dritek hardware */ + if (acerhk_type == TM_dritek) { + remove_proc_entry("key", proc_acer_dir); + } + /* setup available keys */ + setup_keymap_model(acerhk_series); + if (verbose > 1) + print_features(); +} + +static unsigned int __init determine_laptop_series(char * str) +{ + /* 0 means unknown series, handled like TM 200 */ + unsigned int series = 0; + if (strncmp(str, "TravelMate ", 11) == 0) { + switch (str[11]) { + case 'C': + if (str[12] == '1') { + if (str[13] == '0') { + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates TM C100 series\n"); + series = 100; + } else if (str[13] == '1') { + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates TM C110 series\n"); + series = 110; + } + } else if (str[12] == '3') { + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates TM C300 series\n"); + series = 300; + } + break; + case 'F': + if (str[12] == '4') { + series = 230; + } + break; + case '2': + if (str[14] == '0') { + /* newer Travelmate 2xxx series */ + switch (str[12]) { + case '0': + case '5': + series = 2000; // 2000 and 2500 are the same + break; + case '1': + if (str[13] == '0') + series = 2100; + break; + case '2': + case '7': + series = 2200; // 2200 and 2700 are the same + break; + case '3': + if (str[13] == '0') + series = 4000; // 2300 is the same as 4000 + else if (str[13] == '5') + series = 4050; // 2350 is the same as 4050 + break; + case '4': + if (str[13] == '1') + series = 2410; + break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM 2xxx series\n"); + break; + } + } else { + /* older Travelmate 2xx series */ + switch (str[12]) { + case '0': series = 200; break; + case '1': series = 210; break; + case '2': series = 220; break; + case '4': series = 240; break; + case '5': series = 250; break; /* enriqueg@altern.org */ + case '6': series = 260; break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM 2xx series\n"); + break; + } + } + break; + case '3': + switch (str[12]) { + case '0': series = 3200; break; /* TM 3000 works like TM 3200 */ + /* Travelmate 3xx series */ + case '5': series = 350; break; + case '6': series = 360; break; + case '7': series = 370; break; + case '8': series = 380; break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM 3xx series\n"); + break; + } + break; + case '4': + if ( (strnlen(str, ACERHK_MODEL_STRLEN-1) == 15) && + (str[14] == '0') ) { /* Travelmate 4xxx series */ + switch (str[12]) { + case '0': /* 4000 and 4500 are the same */ + case '5': + series = 4000; + break; + case '1': + case '6': /* 4100 and 4600 are the same */ + series = 4100; + break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM 4xxx series\n"); + break; + } + } else { /* Travelmate 4xx series */ + switch (str[12]) { + case '2': series = 420; break; + case '3': series = 430; break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM 4xx series\n"); + break; + } + } + break; + case '5': /* Travelmate 5xx series */ + if (str[12] == '2') + series = 520; + else if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM 5xx series\n"); + break; + case '6': /* older Travelmate 6xx series */ + switch (str[12]) { + case '1': series = 610; break; + case '2': series = 620; break; + case '3': series = 630; break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM 6xx series\n"); + break; + } + break; + default: + printk(KERN_INFO"acerhk: model string indicates unknown TM xxx series\n"); + break; + } + if (series && verbose > 1) + printk(KERN_INFO"acerhk: model string indicates TM %d series\n", series); + } + /* newer Travelmate series do not have a space after 'TravelMate' */ + else if (strncmp(str, "TravelMate", 10) == 0) { + switch (str[10]) { + case '2': + if (str[11] == '9') { + series = 290; + } else { + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM2xx series\n"); + } + break; + case '3': + if (str[11] == '2' && str[14] == '3') { + // TM 3200 uses "TravelMate32003" + series = 3200; + } else { + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM3xxx series\n"); + } + break; + case '4': + switch (str[11]) { + case '3': series = 430; break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM4xx series\n"); + break; + } + break; + case '5': + switch (str[11]) { + case '3': series = 530; break; + case '4': series = 540; break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM5xx series\n"); + break; + } + break; + case '6': + switch (str[11]) { + case '5': series = 650; break; + case '6': series = 660; break; + case '0': + if (strncmp(str, "TravelMate60003", 15) == 0) { + series = 6000; break; + } + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM6xx series\n"); + break; + } + break; + case '8': + if (strncmp(str, "TravelMate80003", 15) == 0) { + series = 8000; + } else if (str[11] == '0') { + series = 800; + } else { + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM8xx series\n"); + } + break; + default: + printk(KERN_INFO"acerhk: model string indicates unknown TMxxx series\n"); + break; + } + if (series && verbose > 1) + printk(KERN_INFO"acerhk: model string indicates TM%d series\n", series); + } + else if (strncmp(str, "Aspire ", 7) == 0) { + switch(str[7]) { + case '1': /* Aspire 1xxx series */ + switch(str[8]) { + case '3': /* Aspire 13xx series */ + switch (str[9]) { + case '0': series = 1300; break; + case '1': series = 1310; break; + case '5': series = 1350; break; + case '6': series = 1360; break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown Aspire 13xx series\n"); + break; + } + break; + case '4': /* Aspire 14xx series */ + switch (str[9]) { + case '0': series = 1400; break; + case '5': series = 1450; break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown Aspire 14xx series\n"); + break; + } + break; + case '5': series = 1500; break; + case '6': /* Aspire 14xx series */ + switch (str[9]) { + case '0': series = 1600; break; + case '8': + case '9': series = 1680; break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown Aspire 16xx series\n"); + break; + } + break; + case '7': series = 1700; break; + case '8': series = 1800; break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown Aspire 1xxx series\n"); + break; + } + break; + case '2': /* Aspire 2xxx series */ + if (str[8] == '0') { + switch (str[9]) { + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown Aspire 20xx series\n"); + break; + case '0': series = 2000; break; + case '1': series = 2010; break; + case '2': series = 2020; break; + } + } else { + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown Aspire 2xxx series\n"); + } + break; + case '3': /* Aspire 3xxx series */ + if (str[8] == '0') { + switch (str[9]) { + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown Aspire 30xx series\n"); + break; + case '2': series = 5020; break; /* Aspire 3020/5020 are identical */ + } + } else { + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown Aspire 3xxx series\n"); + } + break; + case '5': /* Aspire 5xxx series */ + if (str[8] == '0') { + switch (str[9]) { + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown Aspire 50xx series\n"); + break; + case '2': series = 5020; break; + } + } else { + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown Aspire 5xxx series\n"); + } + break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown Aspire series\n"); + break; + } + if (series && verbose > 1) + printk(KERN_INFO"acerhk: model string indicates Aspire %d series\n", series); + } + else if (strncmp(str, "Extensa ", 8) == 0) { + /* Extensa series */ + switch (str[8]) { + case '3': + switch (str[9]) { + case '0': + series = 3000; break; + default: break; + } + break; + default: break; + } + if (series && verbose > 1) + printk(KERN_INFO"acerhk: model string indicates Extensa %d series\n", series); + else if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown Extensa series\n"); + } + else if (strncmp(str, "Amilo ", 6) == 0) { + switch (str[6]) { + case 'D': /* complete string is "Amilo D-Series", there seems to be no model number */ + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates FS Amilo D series\n"); + /* this is the model number of my Amilo */ + series = 7820; + break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown FS Amilo XX series\n"); + series = 7820; + } + } + else if (strncmp(str, "AMILO ", 6) == 0) { + switch (str[6]) { + case 'D': /* AMILO D 6800 P4-2000 */ + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates FS AMILO D series\n"); + series = 6800; + break; + case 'M': + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates FS AMILO M(7400) series\n"); + series = 7400; + break; + case 'P': + /* it is assumed, that 'AMILO P' appears only on Amilo Pro Series */ + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates FS AMILO Pro (V2000) series\n"); + series = 7400; + break; + case 'A': /* AMILO Axxxx - added by damagedspline@aim.com */ + switch (str[7]) { + case '1': /* AMILO A1xxx */ + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates FS AMILO A1xxx series\n"); + series = 6805; + break; + } + break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown FS AMILO XX series\n"); + series = 6800; + } + } + else if (strncmp(str, "MEDIONPC", 8) == 0) { + uint medionmodel; + if ((medionmodel = COLUSSI("WIM 2040", 4, reg1, AREA_SIZE)) >= 0) { + printk(KERN_INFO"acerhk: found Medion model string:'%s'\n", (char*)reg1+medionmodel); + series = 96500; + } else { + if ((medionmodel = COLUSSI("MD 9", 4, reg1, AREA_SIZE)) >= 0) { + printk(KERN_INFO"acerhk: found Medion model string:'%s'\n", (char*)reg1+medionmodel); + } + series = 95400; + } + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates a medion MD %d\n", series); + } + else if (strncmp(str, "MEDIONNB", 8) == 0) { + /* Search for the Product string of the MD9783. */ + if (COLUSSI("MD 42200", 8, reg1, AREA_SIZE) >= 0) { + if (verbose>1) + printk(KERN_INFO"acerhk: model string indicates a Medion MD 42200\n"); + series = 42200; + } else if (COLUSSI("MD 9783", 7, reg1, AREA_SIZE) >= 0){ + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates a medion MD 9783\n"); + series = 9783; + } else if (COLUSSI("WIM 2000", 7, reg1, AREA_SIZE) >= 0){ + if (verbose>1) + printk(KERN_INFO"acerhk: model string indicates a Medion MD 2900\n"); + series = 2900; + } else { + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates a medion MD40100\n"); + series = 40100; + } + } else if (strncmp(str, "AOpen", 5) == 0) { + if (strncmp(str, "AOpen*EzRestore", 15) == 0) { + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates a AOpen 1559\n"); + series = 1559; + } else { + /* Unless I know of other models no further differentiation, + although there is a second part of the model string */ + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates a AOpen\n"); + series = 1555; + } + } else if (strncmp(str, "CL56", 4) == 0) { + /* Unless I know of other models no further differentiation, + although there are strings with more numbers ("CL561" on a Compal + CL56/Zepto 4200, reported by Stian B. Barmen) + It has the same functions as Acer Aspire 2010 + */ + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates a Compal CL56 (or similar)\n"); + series = 2010; + } else { + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates no supported hardware\n"); + } + return (series); +} + +static void __init probe_model(void) { + int offset; /* offset from beginning of reg1 to Model string */ + if (verbose) + printk(KERN_INFO"acerhk: start search for model string at %p\n", reg1); + /* first we look for Travelmate, if it isn't one we try to identify other + laptops, such as Medion or Aspire */ + offset = COLUSSI("Travel", 6, reg1, AREA_SIZE); + /* Try to detect Aspire laptops */ + if (offset < 0) + offset = COLUSSI("Aspire", 6, reg1, AREA_SIZE); + /* Try to detect Extensa laptops */ + if (offset < 0) + offset = COLUSSI("Extensa", 7, reg1, AREA_SIZE); + /* Try to detect Medion laptops */ + if (offset < 0) + offset = COLUSSI("MEDION", 6, reg1, AREA_SIZE); + /* Try to detect AOpen laptops */ + if (offset < 0) + offset = COLUSSI("AOpen", 5, reg1, AREA_SIZE); + /* Try to detect Fujitsu Siemens Amilo laptops */ + if (offset < 0) + offset = COLUSSI("Amilo", 5, reg1, AREA_SIZE); + if (offset < 0) + offset = COLUSSI("AMILO", 5, reg1, AREA_SIZE); + /* Try to detect Compal */ + if (offset < 0) + offset = COLUSSI("CL56", 4, reg1, AREA_SIZE); + if (offset >= 0) { + acerhk_model_addr = reg1 + offset; + /* copy the string, but not more than 15 characters */ + strncpy(acerhk_model_string, acerhk_model_addr, ACERHK_MODEL_STRLEN-1); + if (verbose) + printk(KERN_INFO"acerhk: found model string '%s' at %p\n", + acerhk_model_string, acerhk_model_addr); + if (bios_routine && verbose > 2) + printk(KERN_INFO"acerhk: offset from model string to function address: 0x%lx\n", + bios_routine - (unsigned long)acerhk_model_addr); + acerhk_series = determine_laptop_series(acerhk_model_string); + } else { + printk(KERN_WARNING"acerhk: Could not find model string, will assume type 200 series\n"); + acerhk_series = 200; + } +} + +/* }}} */ + +/* {{{ key polling and translation */ + +static void print_mapping(void) +{ + printk(KERN_INFO"acerhk: key mapping:\n"); + printk("acerhk: help 0x%x\n", acerhk_name2event[k_help]); + printk("acerhk: setup 0x%x\n", acerhk_name2event[k_setup]); + printk("acerhk: p1 0x%x\n", acerhk_name2event[k_p1]); + printk("acerhk: p2 0x%x\n", acerhk_name2event[k_p2]); + printk("acerhk: p3 0x%x\n", acerhk_name2event[k_p3]); + printk("acerhk: www 0x%x\n", acerhk_name2event[k_www]); + printk("acerhk: mail 0x%x\n", acerhk_name2event[k_mail]); + printk("acerhk: wireless 0x%x\n", acerhk_name2event[k_wireless]); + printk("acerhk: power 0x%x\n", acerhk_name2event[k_power]); + printk("acerhk: mute 0x%x\n", acerhk_name2event[k_mute]); + printk("acerhk: volup 0x%x\n", acerhk_name2event[k_volup]); + printk("acerhk: voldn 0x%x\n", acerhk_name2event[k_voldn]); + printk("acerhk: res 0x%x\n", acerhk_name2event[k_res]); + printk("acerhk: close 0x%x\n", acerhk_name2event[k_close]); + printk("acerhk: open 0x%x\n", acerhk_name2event[k_open]); + printk("acerhk: wireless2 0x%x\n", acerhk_name2event[k_wireless2]); + printk("acerhk: play 0x%x\n", acerhk_name2event[k_play]); + printk("acerhk: stop 0x%x\n", acerhk_name2event[k_stop]); + printk("acerhk: prev 0x%x\n", acerhk_name2event[k_prev]); + printk("acerhk: next 0x%x\n", acerhk_name2event[k_next]); + printk("acerhk: display 0x%x\n", acerhk_name2event[k_display]); +} + +static void set_keymap_name(t_key_names name, unsigned int key) +{ + acerhk_name2event[name] = key; +} + +static void init_keymap_input(void) +{ + /* these values for input keys are chosen to match the key names on the + actual Acer laptop */ + set_keymap_name(k_none, KEY_RESERVED); + set_keymap_name(k_help, KEY_HELP); + set_keymap_name(k_setup, KEY_CONFIG); + set_keymap_name(k_p1, KEY_PROG1); + set_keymap_name(k_p2, KEY_PROG2); + set_keymap_name(k_p3, KEY_PROG3); + set_keymap_name(k_www, KEY_WWW); + set_keymap_name(k_mail, KEY_MAIL); + set_keymap_name(k_wireless, KEY_XFER); + set_keymap_name(k_power, KEY_POWER); + set_keymap_name(k_mute, KEY_MUTE); + set_keymap_name(k_volup, KEY_VOLUMEUP); + set_keymap_name(k_voldn, KEY_VOLUMEDOWN); + set_keymap_name(k_res, KEY_CONFIG); + set_keymap_name(k_close, KEY_CLOSE); + set_keymap_name(k_open, KEY_OPEN); + /* I am not really happy with the selections for wireless and wireless2, + but coffee looks good. Michal Veselenyi proposed this value */ + set_keymap_name(k_wireless2, KEY_COFFEE); + set_keymap_name(k_play, KEY_PLAYPAUSE); + set_keymap_name(k_stop, KEY_STOPCD); + set_keymap_name(k_prev, KEY_PREVIOUSSONG); + set_keymap_name(k_next, KEY_NEXTSONG); + set_keymap_name(k_display, KEY_MEDIA); /* also not happy with this */ + if (verbose > 1) + print_mapping(); +} + +static int filter_idle_value(int keycode) +{ + int validkey = 0; + if (keycode != 0x0 && + keycode != 0x9610 && + keycode != 0xc100 && /* Francois Valenduc, Aspire 1601 LC */ + keycode != 0x8610 && + keycode != 0x861 && + keycode != 0x8650 && + keycode != 0x865) + validkey = keycode; + if (verbose > 4 && !validkey) + printk(KERN_INFO"acerhk: throw away idle value 0x%x\n", keycode); + return validkey; +} + +static void send_key_event(t_key_names key) +{ + unsigned int input_key; + if (key != k_none) { + /* convert key name to kernel keycode */ + input_key = acerhk_name2event[key]; + if (verbose > 2) + printk(KERN_INFO"acerhk: translated acer key name 0x%x to input key 0x%x\n", + key, input_key); + /* send press and release together, as there is no such event from acer as 'release' */ + input_report_key(acerhk_input_dev_ptr, input_key, 1); + input_report_key(acerhk_input_dev_ptr, input_key, 0); + } +} + +static t_key_names transl8_key_code(int keycode) +{ + t_key_names keyname = k_none; + /* first filter out idle values */ + if ( (keycode = filter_idle_value(keycode)) ) { + if (verbose > 3) + printk(KERN_INFO"acerhk: received key code 0x%x\n", keycode); + /* translate keycode to key name */ + if (keycode >= 0 && keycode <= 255) + keyname = acerhk_key2name[keycode]; + else { + if (verbose > 3) + printk(KERN_INFO"acerhk: keycode 0x%x too big, will use only 8 bits\n", keycode); + /* use only lower 8 bits of value to distinguish keys */ + keyname = acerhk_key2name[keycode&0xff]; + } + /* produce some log information for higher verbosity levels */ + if (keyname != k_none && verbose > 2) + printk(KERN_INFO"acerhk: translated acer key code 0x%x to key name 0x%x\n", + keycode, keyname); + else if (keyname == k_none && verbose > 3) + printk(KERN_INFO"acerhk: translated acer key code 0x%x to no key\n", + keycode); + if (autowlan) { + /* if automatic switching of wlan hardware is enabled, do it here + on wireless key press */ + if (keyname == k_wireless2) { + if (acerhk_bluetooth_state) + wbutton_fct_1(0); + else + wbutton_fct_1(1); + } + if (keyname == k_wireless) { + if (acerhk_wlan_state) + wbutton_fct_2(0); + else + wbutton_fct_2(1); + } + } + } + return keyname; +} + +/* polling timer handler */ +static void acerhk_poll_event(unsigned long save_size) +{ +#ifndef DUMMYHW + unsigned int max = MAX_POLLING_LOOPS; + /* make sure not to loop more then 32 times */ + if (!max || max > 32) + max = 32; + if (acerhk_type != TM_dritek) { + while (get_nr_events() && max--) { + send_key_event(transl8_key_code(get_fnkey_event())); + } + } else { + send_key_event(transl8_key_code(get_fnkey_event())); + } +#endif + acerhk_timer_poll.expires = jiffies + acerhk_polling_delay; + add_timer(&acerhk_timer_poll); +} + +/* blinking timer handler; added by Antonio Cuni */ +static void acerhk_blink_event(unsigned long not_used) +{ + if (acerhk_blueled_blinking != -1) { + acerhk_blueled_blinking = !acerhk_blueled_blinking; +#ifndef DUMMYHW + wbutton_fct_1(acerhk_blueled_blinking); +#endif + acerhk_timer_blinking.expires = jiffies + acerhk_blueled_blinking_delay; + add_timer(&acerhk_timer_blinking); + } + else + printk(KERN_WARNING "acerhk: blinking event called, but blinking not active\n"); +} + +static void init_input(void) +{ + int i; + +#ifndef KERNEL26 + /* request keyboard input module */ + request_module("keybdev"); + if (verbose > 3) + printk(KERN_INFO"requested keyboard input driver\n"); +#endif + +#ifndef STATIC_INPUT_DEV + /* allocate acerhk input device */ + acerhk_input_dev_ptr=input_allocate_device(); + /* enter some name */ + acerhk_input_dev_ptr->name = "Acer hotkey driver"; +#else + acerhk_input_dev_ptr=&acerhk_input_dev; +#endif + + /* some laptops have a mail led, should I announce it here? */ + acerhk_input_dev_ptr->evbit[0] = BIT(EV_KEY); + /* announce keys to input system + * the generated keys can be changed on runtime, + * but to publish those changes the device needs to + * get reconnected (I dont't know any other way) + * Therefore I enable all possible keys */ + for (i = KEY_RESERVED; i < BTN_MISC; i++) + set_bit(i, acerhk_input_dev_ptr->keybit); + /* set mapping keyname -> input event */ + init_keymap_input(); + if (verbose) + printk(KERN_INFO"acerhk: registered input device\n"); + input_register_device(acerhk_input_dev_ptr); + init_timer(&acerhk_timer_poll); + acerhk_polling_state = 0; +} + +static void stop_polling(void) +{ + if (acerhk_polling_state == 1) { + del_timer(&acerhk_timer_poll); + if (verbose) + printk(KERN_INFO"acerhk: key polling stopped\n"); + acerhk_polling_state = 0; + } else + if (verbose) + printk(KERN_INFO"acerhk: key polling not active\n"); +} + +static void start_polling(void) +{ + if (acerhk_polling_state != 1) { + acerhk_timer_poll.function = acerhk_poll_event; + acerhk_timer_poll.expires = jiffies + acerhk_polling_delay; + acerhk_timer_poll.data = get_nr_events(); + add_timer(&acerhk_timer_poll); + acerhk_polling_state = 1; + if (acerhk_type == TM_dritek) { + printk(KERN_INFO"acerhk: Your hardware does not need polling enabled for hotkeys to work, " + "you can safely disable polling by using the module parameter poll=0 (unless you " + "want to play around with the driver and see if there are buttons which need polling).\n"); + } + if (verbose) + printk(KERN_INFO"acerhk: starting key polling, every %d ms\n", acerhk_polling_delay); + } else + if (verbose) + printk(KERN_INFO"acerhk: key polling already active\n"); +} + +/* addedd by Antonio Cuni */ +static void start_blinking(void) +{ + if (acerhk_blueled_blinking == -1) { + // blinking was disabled... enable it! + acerhk_timer_blinking.function = acerhk_blink_event; + acerhk_timer_blinking.expires = jiffies + acerhk_blueled_blinking_delay; + acerhk_timer_blinking.data = 0; // not used + add_timer(&acerhk_timer_blinking); + acerhk_blueled_blinking = 0; + if (verbose) + printk(KERN_INFO "acerhk: starting blueled blinking\n"); + } else + if (verbose) + printk(KERN_INFO "acerhk: blueled already blinking\n"); +} + +/* Added by Antonio Cuni */ +static void stop_blinking(void) +{ + if (acerhk_blueled_blinking != -1) { + del_timer(&acerhk_timer_blinking); + if (verbose) + printk(KERN_INFO "acerhk: blueled blinking stopped\n"); + acerhk_blueled_blinking = -1; + } +} + +static void release_input(void) +{ + stop_polling(); + input_unregister_device(acerhk_input_dev_ptr); +} + +/* }}} */ + +/* {{{ procfs functions */ + +#ifndef CONFIG_PROC_FS + +static int acerhk_proc_init(void) +{ + return 1; +} +#else + +/* This macro frees the machine specific function from bounds checking and + * things like that... */ +#define PRINT_PROC(fmt,args...) \ + do { \ + *len += sprintf( buffer+*len, fmt, ##args ); \ + if (*begin + *len > offset + size) \ + return( 0 ); \ + if (*begin + *len < offset) { \ + *begin += *len; \ + *len = 0; \ + } \ + } while(0) + +static int pc_proc_infos( char *buffer, int *len, + off_t *begin, off_t offset, int size ) +{ + PRINT_PROC( "Acer hotkeys version %s\n", ACERHK_VERSION); + PRINT_PROC( "Model(Type)\t: %s(", acerhk_model_string); + switch(acerhk_type) { + default: + PRINT_PROC( "unknown)\n"); + break; + case TM_old: + PRINT_PROC( "old)\n"); + break; + case TM_new: + PRINT_PROC( "new)\n"); + break; + case TM_dritek: + PRINT_PROC( "Dritek)\n"); + break; + } + if (bios_routine != 0) { + PRINT_PROC( "request handler\t: 0x%x\n", bios_routine); + if (cmos_index) { + PRINT_PROC( "CMOS index\t: 0x%x\n", cmos_index); + PRINT_PROC( "events pending\t: %u\n", get_nr_events()); + } else { + PRINT_PROC( "CMOS index\t: not available\n"); + } + if (acerhk_polling_state == 1) + PRINT_PROC( "kernel polling\t: active\n"); + else + PRINT_PROC( "kernel polling\t: inactive\n"); + PRINT_PROC( "autoswitch wlan\t: "); + if (autowlan == 1) + PRINT_PROC( "enabled\n"); + else + PRINT_PROC( "disabled\n"); + } else { + PRINT_PROC( "request handler\t: not found\n"); + PRINT_PROC( "kernel polling\t: not possible\n"); + } + /* model specific infos */ + if (acerhk_type == TM_dritek) { + PRINT_PROC( "use of Dritek EC: "); + if (usedritek) + PRINT_PROC( "enabled\n"); + else + PRINT_PROC( "disabled\n"); + } + if (acerhk_type == TM_old) + PRINT_PROC( "preg400\t\t: 0x%p\n", preg400); + return (1); +} + +static int acerhk_proc_info( char *buffer, char **start, off_t offset, + int size, int *eof, void *data ) +{ + int len = 0; + off_t begin = 0; + + *eof = pc_proc_infos( buffer, &len, &begin, offset, size ); + + if (offset >= begin + len) + return( 0 ); + *start = buffer + (offset - begin); + return( size < begin + len - offset ? size : begin + len - offset ); + +} + +static int acerhk_proc_key( char *buffer, char **start, off_t offset, + int size, int *eof, void *data ) +{ + if (size >= 5 && offset == 0) { + if (acerhk_type == TM_dritek || acerhk_polling_state == 1) { + snprintf(buffer+offset, size, "n/a\n"); + } else { + snprintf(buffer+offset, size, "0x%02x\n", filter_idle_value(get_fnkey_event())); + } + *eof = 1; + return 5; + } + *eof = 1; + return 0; +} + +static int acerhk_proc_led(struct file* file, const char* buffer, + unsigned long count, void* data) +{ + char str[4]; + int len; + if (count > 4) + len = 4; + else + len = count; + if (copy_from_user(str, buffer, len)) + return -EFAULT; + str[3] = '\0'; + if ( ( (len >= 2) && (!strncmp(str, "on", 2) || !strncmp(str, "an", 2)) ) + || str[0] == '1') + set_mail_led(1); + else + set_mail_led(0); + return len; +} + +static int acerhk_proc_wirelessled(struct file* file, const char* buffer, + unsigned long count, void* data) +{ + char str[4]; + int len; + if (count > 4) + len = 4; + else + len = count; + if (copy_from_user(str, buffer, len)) + return -EFAULT; + str[3] = '\0'; + if ( ( (len >= 2) && (!strncmp(str, "on", 2) || !strncmp(str, "an", 2)) ) + || str[0] == '1') { + if (acerhk_model_features & TM_F_WLAN_EC1) + enable_wlan_ec_1(); + else if (acerhk_model_features & TM_F_WLAN_EC2) + enable_wlan_ec_2(); + else + wbutton_fct_2(1); + } + else { + if (acerhk_model_features & TM_F_WLAN_EC1) + disable_wlan_ec_1(); + else if (acerhk_model_features & TM_F_WLAN_EC2) + disable_wlan_ec_2(); + else + wbutton_fct_2(0); + } + return len; +} + + +/* Modified by Antonio Cuni: added support for blinking + possible values: + - off, 0: led always off + - on, an, 1: led alway on + - n (a number): led blinking; n is the delay between + two changes of state, in jiffies; n must + be > 50, to prevent the user from overloading + the kernel. + + */ +static int acerhk_proc_blueled(struct file* file, const char* buffer, + unsigned long count, void* data) +{ + const int MAXLEN=11; + char str[MAXLEN]; + int len; + int isNumber; + + if (count > MAXLEN) + len = MAXLEN; + else + len = count; + if (copy_from_user(str, buffer, len)) + return -EFAULT; + str[MAXLEN - 1] = '\0'; + + /* try to parse a number */ + isNumber = sscanf(str, "%u", &acerhk_blueled_blinking_delay); + /* if the delay is 0, turn off the led */ + if (isNumber && acerhk_blueled_blinking_delay != 0 && acerhk_blueled_blinking_delay != 1) { + if (acerhk_blueled_blinking_delay < 50) + printk(KERN_INFO"acerhk: blinking request rejected. The delay must be > 50.\n"); + else { + if (verbose) + printk(KERN_INFO"acerhk: blinking delay set to %u.\n", acerhk_blueled_blinking_delay); + start_blinking(); + } + } else if (acerhk_blueled_blinking_delay == 1 || !strncmp(str, "on", 2) || !strncmp(str, "an", 2)) { + stop_blinking(); + if (acerhk_model_features & TM_F_BLUE_EC1) + enable_bluetooth_ec_1(); + else if (acerhk_model_features & TM_F_BLUE_EC2) + enable_bluetooth_ec_2(); + else + wbutton_fct_1(1); + } else { + /* it's 0 or everything else */ + stop_blinking(); + if (acerhk_model_features & TM_F_BLUE_EC1) + disable_bluetooth_ec_1(); + else if (acerhk_model_features & TM_F_BLUE_EC2) + disable_bluetooth_ec_2(); + else + wbutton_fct_1(0); + } + return len; +} + +#ifdef ACERDEBUG +static void do_debug(const char* buffer, unsigned long len) +{ + unsigned int h, i; + switch (buffer[0]) { + case 'b': + /* test WLAN on TM 4001 */ + switch (buffer[1]) { + case '0': + disable_wlan_ec_1(); + break; + case '1': + default: + enable_wlan_ec_1(); + } + break; + case 'B': + /* test BLUETOOTH on TM 4001 */ + switch (buffer[1]) { + case '0': + disable_bluetooth_ec_1(); + break; + case '1': + default: + enable_bluetooth_ec_1(); + } + break; + case 'D': + /* test "DMM Function Enabled" entry of TM 4150/4650 */ + enable_dmm_function(); + break; + case 'i': + case '1': +#ifndef KERNEL26 + MOD_INC_USE_COUNT; +#endif + break; + case 'e': + switch (buffer[1]) { + case '1': + start_polling(); + break; + default: + stop_polling(); + } + break; + case 'k': + for (i = 0; i <= 255;i++) { + input_report_key(acerhk_input_dev_ptr, i, 1); + input_report_key(acerhk_input_dev_ptr, i, 0); + } + break; + case 'm': + /* set mapping key names -> input events */ + sscanf(&buffer[2],"%x", &i); + h = buffer[1] - '0' + 1; + printk("acerhk: key name %x maps to %x\n", h, i); + acerhk_name2event[h] = i; + break; + case 'M': + /* test mute LED on dritek hardware */ + switch (buffer[1]) { + case '0': + disable_mute_led_ec(); + break; + case '1': + default: + enable_mute_led_ec(); + } + break; + case 'p': + printk("acerhk: pbutton = 0x%x\n", pbutton_fct()); + break; + case 's': + /* send key event to test the key translation in input system */ + sscanf(&buffer[1],"%x", &h); + printk("acerhk: sending key event 0x%x\n", h); + input_report_key(acerhk_input_dev_ptr, h, 1); + input_report_key(acerhk_input_dev_ptr, h, 0); + break; + case 'S': + /* simulate key codes to test the key translation in acerhk */ + sscanf(&buffer[1],"%x", &h); + send_key_event(transl8_key_code(h)); + break; + case 't': + printk("acerhk: thermal event = 0x%x\n", get_thermal_event()); + break; + case 'w': + /* test the wbutton functions, someone really needs to have another look + at the windows driver */ + switch (buffer[1]) { + case '2': + printk("acerhk: wbutton_2(%d) = 0x%x\n", buffer[2]-'0', wbutton_fct_2(buffer[2]-'0')); + break; + case '1': + default: + printk("acerhk: wbutton_1(%d) = 0x%x\n", buffer[2]-'0', wbutton_fct_1(buffer[2]-'0')); + } + break; + case 'W': + /* test wireless HW/LED on some models using dritek hardware */ + switch (buffer[1]) { + case '0': + disable_wireless_ec(); + break; + case '1': + default: + enable_wireless_ec(); + } + break; + case 'v': + verbose = buffer[1]-'0'; + printk("acerhk: verbosity level changed to %d\n", verbose); + break; + case 'd': + case '0': + default: +#ifndef KERNEL26 + MOD_DEC_USE_COUNT; +#endif + break; + } +} + +static int acerhk_proc_debug(struct file* file, const char* buffer, + unsigned long count, void* data) +{ + char str[5]; + int len; + if (count > 5) + len = 5; + else + len = count; + if (copy_from_user(str, buffer, len)) + return -EFAULT; + str[4] = '\0'; + do_debug(str, len); + return len; +} +#endif + +static int acerhk_proc_init(void) +{ + int retval; + struct proc_dir_entry *entry; + /* create own directory */ + proc_acer_dir = proc_mkdir("driver/acerhk", NULL); + if (proc_acer_dir == NULL) { + retval = 0; + printk(KERN_INFO"acerhk: could not create /proc/driver/acerhk\n"); + } + else { + proc_acer_dir->owner = THIS_MODULE; + /* now create several files, first general info ... */ + entry = create_proc_read_entry("info", + 0444, proc_acer_dir, acerhk_proc_info, NULL); + if (entry == NULL) { + printk(KERN_INFO"acerhk: cannot create info file\n"); + remove_proc_entry("driver/acerhk", NULL); + retval = 0; + } else { + entry->owner = THIS_MODULE; + /* ... last pressed key ... */ + entry = create_proc_read_entry("key", + 0444, proc_acer_dir, acerhk_proc_key, NULL); + if (entry == NULL) { + printk(KERN_INFO"acerhk: cannot create key file\n"); + remove_proc_entry("info", proc_acer_dir); + remove_proc_entry("driver/acerhk", NULL); + retval = 0; + } else { + entry->owner = THIS_MODULE; + /* ... and led control file */ + entry = create_proc_entry("led", 0222, proc_acer_dir); + if (entry == NULL) { + printk(KERN_INFO"acerhk: cannot create LED file\n"); + remove_proc_entry("info", proc_acer_dir); + remove_proc_entry("key", proc_acer_dir); + remove_proc_entry("driver/acerhk", NULL); + retval = 0; + } + else { + entry->write_proc = acerhk_proc_led; + entry->owner = THIS_MODULE; + /* ... and wireless led controll file */ + entry = create_proc_entry("wirelessled", 0222, proc_acer_dir); + if (entry == NULL) { + printk(KERN_INFO"acerhk: cannot create wirelessled file\n"); + remove_proc_entry("info", proc_acer_dir); + remove_proc_entry("key", proc_acer_dir); + remove_proc_entry("led", proc_acer_dir); + remove_proc_entry("driver/acerhk", NULL); + retval = 0; + } + else { + entry->write_proc = acerhk_proc_wirelessled; + entry->owner = THIS_MODULE; + /* ... and bluetooth led controll file */ + entry = create_proc_entry("blueled", 0222, proc_acer_dir); + if (entry == NULL) { + printk(KERN_INFO"acerhk: cannot create blueled file\n"); + remove_proc_entry("info", proc_acer_dir); + remove_proc_entry("key", proc_acer_dir); + remove_proc_entry("led", proc_acer_dir); + remove_proc_entry("wirelessled", proc_acer_dir); + remove_proc_entry("driver/acerhk", NULL); + retval = 0; + } else { + entry->write_proc = acerhk_proc_blueled; + entry->owner = THIS_MODULE; + retval = 1; +#ifdef ACERDEBUG + /* add extra file for debugging purposes */ + entry = create_proc_entry("debug", 0222, proc_acer_dir); + if (entry == NULL) { + printk(KERN_INFO"acerhk: cannot create debug file\n"); + remove_proc_entry("info", proc_acer_dir); + remove_proc_entry("key", proc_acer_dir); + remove_proc_entry("led", proc_acer_dir); + remove_proc_entry("wirelessled", proc_acer_dir); + remove_proc_entry("blueled", proc_acer_dir); + remove_proc_entry("driver/acerhk", NULL); + retval = 0; + } + else { + entry->write_proc = acerhk_proc_debug; + entry->owner = THIS_MODULE; + retval = 1; + } +#endif + } + } + } + } + } + } + return retval; +} + +static void acerhk_proc_cleanup(void) +{ + if (proc_acer_dir) { + remove_proc_entry("info", proc_acer_dir); + /* On dritek type hardware key file is already removed */ + if (acerhk_type != TM_dritek) + remove_proc_entry("key", proc_acer_dir); + remove_proc_entry("led", proc_acer_dir); + remove_proc_entry("wirelessled", proc_acer_dir); + remove_proc_entry("blueled", proc_acer_dir); +#ifdef ACERDEBUG + remove_proc_entry("debug", proc_acer_dir); +#endif + remove_proc_entry("driver/acerhk", NULL); + proc_acer_dir = NULL; + } +} + +#endif /* CONFIG_PROC_FS */ + +/* }}} */ + +/* {{{ file operations */ + +static int acerhk_ioctl( struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg ) +{ + int retval; + switch( cmd ) { + case ACERHK_GET_KEYCOUNT: + { + char nr; + nr = get_nr_events(); + put_user(nr, (char*)arg); + retval = 0; + break; + } + case ACERHK_GET_KEYID: + { + char id; + id = get_fnkey_event(); + put_user(id, (char*)arg); + retval = 0; + break; + } + case ACERHK_CONNECT: + launch_connect(1); + retval = 0; + break; + case ACERHK_START_POLLING: + start_polling(); + retval = 0; + break; + case ACERHK_STOP_POLLING: + stop_polling(); + retval = 0; + break; + case ACERHK_DISCONNECT: + launch_connect(0); + retval = 0; + break; + case ACERHK_GET_THERMAL_EVENT: + { + short event; + event = get_thermal_event(); + put_user(event, (short*)arg); + retval = 0; + break; + } + case ACERHK_MAIL_LED_OFF: + set_mail_led(0); + retval = 0; + break; + case ACERHK_MAIL_LED_ON: + set_mail_led(1); + retval = 0; + break; + case ACERHK_GET_KEY_MAP: + if (copy_to_user((t_map_name2event*)arg, &acerhk_name2event, sizeof(acerhk_name2event))) + retval = -EFAULT; + else + retval = 0; + break; + case ACERHK_SET_KEY_MAP: + if (copy_from_user(&acerhk_name2event, (t_map_name2event*)arg, sizeof(acerhk_name2event))) + retval = -EFAULT; + else { + if (verbose) { + printk(KERN_INFO"acerhk: changed key mapping\n"); + print_mapping(); + } + retval = 0; + } + break; + default: + retval = -EINVAL; + } + return retval; +} + +#ifdef ACERDEBUG +static ssize_t acerhk_write (struct file* file, const char* buffer, size_t length, loff_t* offset) +{ + if (length) + do_debug(buffer, length); + return length; +} +#endif + +static int acerhk_open( struct inode *inode, struct file *file ) +{ + return 0; +} + +static int acerhk_release( struct inode *inode, struct file *file ) +{ + return 0; +} + +static struct file_operations acerhk_fops = { + owner: THIS_MODULE, + ioctl: acerhk_ioctl, + open: acerhk_open, +#ifdef ACERDEBUG + write: acerhk_write, +#endif + release: acerhk_release, +}; + +static struct miscdevice acerhk_dev = { + MISC_DYNAMIC_MINOR, + "acerhk", + &acerhk_fops +}; + +/* }}} */ + +static void __init model_init(void) +{ + /* set callroutine, features and keymap for model */ + setup_model_features(acerhk_series); + /* override initial state of wireless hardware if specified by module options */ + if (wlan_state >= 0) acerhk_wlan_state = wlan_state; + if (bluetooth_state >= 0) acerhk_bluetooth_state = bluetooth_state; + /* Launch connect only if available */ + if (acerhk_model_features & TM_F_CONNECT) { + if (verbose) + printk(KERN_INFO"acerhk: Model type %d, calling launch_connect(1)\n", + acerhk_type); + launch_connect(1); + } + if ( acerhk_type != TM_dritek ) { + get_cmos_index(); + } + if ( acerhk_type == TM_dritek ) { + enable_dritek_keyboard(); + } + /* added by Antonio Cuni */ + init_timer(&acerhk_timer_blinking); +} + + +static void __exit acerhk_cleanup_module (void); +static int __init acerhk_init(void) +{ + int ret; + + ret = misc_register( &acerhk_dev ); + if (ret) { + printk(KERN_ERR "acerhk: can't misc_register on minor=%d\n", ACERHK_MINOR); + ret = -EAGAIN; + } + else if (!acerhk_proc_init()) { + printk(KERN_ERR "acerhk: can't create procfs entries\n"); + ret = -ENOMEM; + misc_deregister( &acerhk_dev ); + } + else { + reg1 = ioremap(0xf0000, 0xffff); + if (verbose > 1) + printk(KERN_INFO"acerhk: area from 0xf000 to 0xffff mapped to %p\n", reg1); + reg2 = ioremap(0xe0000, 0xffff); + if (verbose > 1) + printk(KERN_INFO"acerhk: area from 0xe000 to 0xffff mapped to %p\n", reg2); + /* the area 0x400 is used as data area by earlier (520) series */ + preg400 = ioremap(0x400, 0xfff); + if (verbose > 1) + printk(KERN_INFO"acerhk: area from 0x400 to 0x13ff mapped to %p\n", preg400); + /* attach to input system */ + init_input(); + memset(acerhk_model_string, 0x00, ACERHK_MODEL_STRLEN); +#ifdef DUMMYHW + acerhk_model_addr = (void*)0x12345678; + /* copy the string, but not more than 15 characters */ + strncpy(acerhk_model_string, "TravelmateDummy", ACERHK_MODEL_STRLEN-1); + /* set callroutine for model */ + if (force_series) + acerhk_series = force_series; + else + acerhk_series = 2000; + setup_model_features(acerhk_series); + printk(KERN_INFO "Acer Travelmate hotkey driver v" ACERHK_VERSION " dummy\n"); + if ( acerhk_type == TM_dritek ) + enable_dritek_keyboard(); + if (poll) + start_polling(); + init_timer(&acerhk_timer_blinking); +#else + bios_routine = find_hk_area(); + if (!force_series) + probe_model(); + else { + if (verbose) + printk(KERN_INFO"acerhk: forced laptop series to %d\n", force_series); + acerhk_series = force_series; + } + /* do model specific initialization */ + model_init(); + /* Without a bios routine we cannot do anything except on dritek + type HW, unload on other types */ + if (bios_routine || (acerhk_type == TM_dritek)) { + ret = 0; + if (verbose && bios_routine) + printk(KERN_INFO"acerhk: bios routine found at 0x%x\n", bios_routine); + printk(KERN_INFO "Acer Travelmate hotkey driver v" ACERHK_VERSION "\n"); + /* If automatic switching of wlan is wanted but polling is disabled, + automatically enable it */ + if (!poll && autowlan) { + printk(KERN_INFO "Automatic switching of wireless hardware needs polling, enabling it\n"); + poll = 1; + } + /* start automatic polling of key presses if wanted and bios routine found */ + if (poll && bios_routine) + start_polling(); + } else { + printk(KERN_ERR "acerhk: can't find bios routine, cannot do anything for you, sorry!\n"); + ret = -ENOMEM; + acerhk_cleanup_module(); + } +#endif + } + return ret; +} + +static void __exit acerhk_cleanup_module (void) +{ + acerhk_proc_cleanup(); + stop_blinking(); + if (reg1) + iounmap(reg1); + if (reg2) + iounmap(reg2); + if (preg400) + iounmap(preg400); + release_input(); + misc_deregister( &acerhk_dev ); + if ( acerhk_type == TM_dritek ) { + disable_dritek_keyboard(); + } + if (verbose > 2) + printk(KERN_INFO "acerhk: unloaded\n"); +} + +module_init(acerhk_init); +module_exit(acerhk_cleanup_module); + +MODULE_AUTHOR("Olaf Tauber"); +MODULE_DESCRIPTION("AcerHotkeys extra buttons keyboard driver"); +MODULE_LICENSE("GPL"); + +#ifndef KERNEL26 +EXPORT_NO_SYMBOLS; +#endif + +#else +#error This driver is only available for X86 architecture +#endif +/* + * Local variables: + * c-indent-level: 4 + * tab-width: 4 + * End: + */ + --- linux-2.6.28.orig/ubuntu/misc/lmpcm_usb.c +++ linux-2.6.28/ubuntu/misc/lmpcm_usb.c @@ -0,0 +1,469 @@ +/* + * Copyright (c) 2004-2005 David Oliveira + * + * USB Logitech MediaPlay Cordless Mouse driver + * + */ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * If you need to contact me, you can do it by e-mail, sending a mail + * message to + */ + +#include +#include +#include +#include +#include +#include + +#ifdef BIT +#undef BIT +#endif +#define BIT(x) (1UL<<((x)%BITS_PER_LONG)) +#define LONG(x) ((x)/BITS_PER_LONG) + +#define DRIVER_VERSION "v0.5.5" +#define DRIVER_AUTHOR "David Oliveira " +#define DRIVER_DESC "USB Logitech MediaPlay Cordless Mouse driver" +#define DRIVER_LICENSE "GPL" + +#define GETBIT(v,n) ((v>>(n))&0x01) +#define SETBIT(v,n) (v |= (0x01<<(n))) + +#ifdef SLAB_ATOMIC +# define ATOMIC SLAB_ATOMIC +#else +# define ATOMIC GFP_ATOMIC +#endif + + +/* Module properties */ + +MODULE_AUTHOR ( DRIVER_AUTHOR ); +MODULE_DESCRIPTION ( DRIVER_DESC ); +MODULE_LICENSE ( DRIVER_LICENSE ); + + +/* Own type */ + +typedef struct usb_lmpcm { + + // Device name + + char name[128]; + + // USB interrupt data + + signed char *data; + + char phys[64]; + + dma_addr_t data_dma; + + // USB device + + struct usb_device *usbdev; + + // Input device + + struct input_dev *inputdev; + + // USB Request block + + struct urb *urb; + + // Number of openned times + + int open; + +} lmpcm_t; + + +// Initialize lmpcm structure + +void lmpcm_init ( lmpcm_t *lmpcm ) { + + memset(lmpcm, 0, sizeof(lmpcm_t)); + lmpcm->inputdev = NULL; + lmpcm->urb = NULL; + lmpcm->data = NULL; + +} + + +// Free lmpcm buffers + +void lmpcm_free ( lmpcm_t *lmpcm ) { + + if ( lmpcm->urb ) + usb_free_urb(lmpcm->urb); + + if ( lmpcm->data ) + usb_buffer_free(lmpcm->usbdev,8,lmpcm->data,lmpcm->data_dma); + + kfree(lmpcm); + +} + + +// Create new lmpcm (buffer allocation + +lmpcm_t *lmpcm_new ( struct usb_device *dev ) { + + lmpcm_t *lmpcm; + + // Create object + + if (!(lmpcm = kmalloc(sizeof(lmpcm_t), GFP_KERNEL))) + return NULL; + + // Initialize + + lmpcm_init(lmpcm); + + + // Input device + + if ( (lmpcm->inputdev = input_allocate_device()) == NULL ) { + lmpcm_free(lmpcm); + return NULL; + } + + + // Create urb handler + + if (!(lmpcm->urb = usb_alloc_urb(0, GFP_KERNEL))) { + lmpcm_free(lmpcm); + return NULL; + } + + + // Create data required for urb transfer + + if (!(lmpcm->data = usb_buffer_alloc(dev,8,ATOMIC,&lmpcm->data_dma))) { + lmpcm_free(lmpcm); + return NULL; + } + + + // Set lmpcm usb device + + lmpcm->usbdev = dev; + + + return lmpcm; + +} + + + + + +// Get data from urb and send to input API + +void input_send_data ( struct input_dev *dev, char *data ) { + + char + btn = data[0], // Basic buttons (left, right, middle, side and extra) + mbtn = data[6], // Media buttons + x = data[1], // X movement + y = data[2], // Y movement + w = data[3]; // Wheel movement + + + input_report_key(dev, BTN_LEFT, GETBIT(btn,0)); + input_report_key(dev, BTN_RIGHT, GETBIT(btn,1)); + input_report_key(dev, BTN_MIDDLE, GETBIT(btn,2)); + input_report_key(dev, BTN_SIDE, GETBIT(btn,3)); + input_report_key(dev, BTN_EXTRA, GETBIT(btn,4)); + input_report_key(dev, KEY_PLAYCD, GETBIT(btn,5)); + input_report_key(dev, KEY_BACK, GETBIT(btn,6)); + input_report_key(dev, KEY_FORWARD, GETBIT(btn,7)); + + input_report_key(dev, KEY_VOLUMEUP, GETBIT(mbtn,0)); + input_report_key(dev, KEY_VOLUMEDOWN, GETBIT(mbtn,1)); + input_report_key(dev, KEY_NEXTSONG, GETBIT(mbtn,2)); + input_report_key(dev, KEY_PREVIOUSSONG, GETBIT(mbtn,3)); + input_report_key(dev, KEY_PLAYPAUSE, GETBIT(mbtn,4)); + + input_report_rel(dev, REL_X, x); + input_report_rel(dev, REL_Y, y); + input_report_rel(dev, REL_WHEEL, w); + +} + +static void usb_lmpcm_handle(struct urb *urb) { + + lmpcm_t *mouse = urb->context; + signed char *data = mouse->data; + struct input_dev *inputdev = mouse->inputdev; + + + // Check returned status + + if (urb->status) return ; + + + // Send data to input interface + + input_send_data(inputdev,data); + + input_sync(inputdev); + usb_submit_urb(urb,ATOMIC); + +} + +static int usb_lmpcm_open(struct input_dev *dev) { + + lmpcm_t *mouse = (lmpcm_t *)input_get_drvdata(dev); + + if (mouse->open++) + return 0; + + mouse->urb->dev = mouse->usbdev; + + if (usb_submit_urb(mouse->urb, GFP_KERNEL)) { + mouse->open--; + return -EIO; + } + + return 0; + +} + +static void usb_lmpcm_close(struct input_dev *dev) { + + lmpcm_t *mouse = (lmpcm_t *)input_get_drvdata(dev); + + if (!--mouse->open) + usb_kill_urb(mouse->urb); + +} + +static void input_device_init ( struct input_dev *inputdev, struct usb_interface *intf, void *private, struct usb_device *dev ) { + + char path[64]; + + lmpcm_t *mouse = (lmpcm_t *) private; + + int + x, + keys[] = { KEY_PLAYPAUSE, KEY_BACK, KEY_FORWARD, KEY_PLAYCD, KEY_VOLUMEUP, KEY_VOLUMEDOWN, + KEY_NEXTSONG, KEY_PREVIOUSSONG, 0 }; + + + // Events + + inputdev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + + // Add special keys + + for ( x = 0 ; keys[x] ; x++ ) + set_bit(keys[x],inputdev->keybit); + + // Add basic buttons + + inputdev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | + BIT(BTN_SIDE) | BIT(BTN_EXTRA); + + // Add move mouse movement (X/Y) + + inputdev->relbit[0] = BIT(REL_X) | BIT(REL_Y); + + // Add wheel + + inputdev->relbit[0] |= BIT(REL_WHEEL); + + + // Private data structure + + input_set_drvdata(inputdev, mouse); + + // Input file operations + + inputdev->open = usb_lmpcm_open; + inputdev->close = usb_lmpcm_close; + + // Device + + inputdev->name = mouse->name; + + usb_make_path(dev,path,64); + snprintf(mouse->phys,64,"%s/input0",path); + + inputdev->phys = mouse->phys; + inputdev->id.bustype = BUS_USB; + inputdev->id.vendor = dev->descriptor.idVendor; + inputdev->id.product = dev->descriptor.idProduct; + inputdev->id.version = dev->descriptor.bcdDevice; + +} + +static int usb_lmpcm_probe(struct usb_interface *intf, const struct usb_device_id *id) { + + struct usb_device *dev = interface_to_usbdev(intf); + struct usb_host_interface *interface; + + + struct usb_endpoint_descriptor *endpoint; + lmpcm_t *mouse; + int pipe, maxp; + char *buf; + + + // Get mouse endpoint + + interface = intf->cur_altsetting; + + if ( interface->desc.bNumEndpoints != 1 ) return -ENODEV; + endpoint = &interface->endpoint[0].desc; + + + // Check endpoint + + if (!(endpoint->bEndpointAddress & USB_DIR_IN)) + return -ENODEV; + + if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) + return -ENODEV; + + + // Create endpoint pipe + + pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); + maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); + + + // Create lmpcm object + + if (!(mouse = lmpcm_new(dev))) + return -ENOMEM; + + // Initialize input device + + input_device_init(mouse->inputdev,intf,mouse,dev); + + + // Set device name + + if (!(buf = kmalloc(63, GFP_KERNEL))) { + lmpcm_free(mouse); + return -ENOMEM; + } + + + if (dev->descriptor.iManufacturer && + usb_string(dev, dev->descriptor.iManufacturer, buf, 63) > 0) + strcat(mouse->name, buf); + + if (dev->descriptor.iProduct && + usb_string(dev, dev->descriptor.iProduct, buf, 63) > 0) + sprintf(mouse->name, "%s %s", mouse->name, buf); + + if (!strlen(mouse->name)) + sprintf(mouse->name, "lmpcm_usb.c: Logitech MediaPlay Mouse on usb%04x:%04x", + mouse->inputdev->id.vendor, mouse->inputdev->id.product); + + kfree(buf); + + + // Initialize interrupt transfer + + usb_fill_int_urb(mouse->urb,dev,pipe,mouse->data,((maxp > 8)?8:maxp),usb_lmpcm_handle,mouse,endpoint->bInterval); + mouse->urb->transfer_dma = mouse->data_dma; + mouse->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + + // Register input device + + input_register_device(mouse->inputdev); + + + printk(KERN_INFO "lmpcm_usb.c: Detected device: %s\n", mouse->name); + + // Set usb handler interface data + + usb_set_intfdata(intf,mouse); + + + return 0; + +} + + +static void usb_lmpcm_disconnect(struct usb_interface *intf) { + + lmpcm_t *mouse = usb_get_intfdata(intf); + + usb_set_intfdata(intf,NULL); + if (mouse) { + usb_kill_urb(mouse->urb); + input_unregister_device(mouse->inputdev); + lmpcm_free(mouse); + } + +} + + + + +/* Module structures */ + +static struct usb_device_id usb_lmpcm_id_table [] = { + { USB_DEVICE(0x46d, 0xc50e) }, + { } +}; + +MODULE_DEVICE_TABLE (usb, usb_lmpcm_id_table); + +static struct usb_driver usb_lmpcm_driver = { + + .name = "lmpcm_usb", + .probe = usb_lmpcm_probe, + .disconnect = usb_lmpcm_disconnect, + .id_table = usb_lmpcm_id_table + +}; + + + +/* Module main functions */ + +static int __init usb_lmpcm_init(void) { + + int rv; + + // Register usb driver + + rv = usb_register(&usb_lmpcm_driver); + + info(DRIVER_VERSION ":" DRIVER_DESC); + + return rv; +} + +static void __exit usb_lmpcm_exit(void) { + + usb_deregister(&usb_lmpcm_driver); + +} + +// Set + +module_init(usb_lmpcm_init); +module_exit(usb_lmpcm_exit); --- linux-2.6.28.orig/ubuntu/misc/thinkpad_ec.c +++ linux-2.6.28/ubuntu/misc/thinkpad_ec.c @@ -0,0 +1,489 @@ +/* + * thinkpad_ec.c - ThinkPad embedded controller LPC3 functions + * + * The embedded controller on ThinkPad laptops has a non-standard interface, + * where LPC channel 3 of the H8S EC chip is hooked up to IO ports + * 0x1600-0x161F and implements (a special case of) the H8S LPC protocol. + * The EC LPC interface provides various system management services (currently + * known: battery information and accelerometer readouts). This driver + * provides access and mutual exclusion for the EC interface. +* + * The LPC protocol and terminology is documented here: + * "H8S/2104B Group Hardware Manual", + * http://documentation.renesas.com/eng/products/mpumcu/rej09b0300_2140bhm.pdf + * + * Copyright (C) 2006-2007 Shem Multinymous + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 "thinkpad_ec.h" +#include +#include +#include + +#define TP_VERSION "0.37" + +MODULE_AUTHOR("Shem Multinymous"); +MODULE_DESCRIPTION("ThinkPad embedded controller hardware access"); +MODULE_VERSION(TP_VERSION); +MODULE_LICENSE("GPL"); + +/* IO ports used by embedded controller LPC channel 3: */ +#define TPC_BASE_PORT 0x1600 +#define TPC_NUM_PORTS 0x20 +#define TPC_STR3_PORT 0x1604 /* Reads H8S EC register STR3 */ +#define TPC_TWR0_PORT 0x1610 /* Mapped to H8S EC register TWR0MW/SW */ +#define TPC_TWR15_PORT 0x161F /* Mapped to H8S EC register TWR15. */ + /* (and port TPC_TWR0_PORT+i is mapped to H8S reg TWRi for 00x%02x", \ + msg, args->val[0x0], args->val[0xF], code) + +/* State of request prefetching: */ +static u8 prefetch_arg0, prefetch_argF; /* Args of last prefetch */ +static u64 prefetch_jiffies; /* time of prefetch, or: */ +#define TPC_PREFETCH_NONE INITIAL_JIFFIES /* No prefetch */ +#define TPC_PREFETCH_JUNK (INITIAL_JIFFIES+1) /* Ignore prefetch */ + +/* Locking: */ + +static DECLARE_MUTEX(thinkpad_ec_mutex); + +/** + * thinkpad_ec_lock - get lock on the ThinkPad EC + * + * Get exclusive lock for accesing the ThinkPad embedded controller LPC3 + * interface. Returns 0 iff lock acquired. + */ +int thinkpad_ec_lock(void) +{ + int ret; + ret = down_interruptible(&thinkpad_ec_mutex); + return ret; +} +EXPORT_SYMBOL_GPL(thinkpad_ec_lock); + +/** + * thinkpad_ec_try_lock - try getting lock on the ThinkPad EC + * + * Try getting an exclusive lock for accesing the ThinkPad embedded + * controller LPC3. Returns immediately if lock is not available; neither + * blocks nor sleeps. Returns 0 iff lock acquired . + */ +int thinkpad_ec_try_lock(void) +{ + return down_trylock(&thinkpad_ec_mutex); +} +EXPORT_SYMBOL_GPL(thinkpad_ec_try_lock); + +/** + * thinkpad_ec_unlock - release lock on ThinkPad EC + * + * Release a previously acquired exclusive lock on the ThinkPad ebmedded + * controller LPC3 interface. + */ +void thinkpad_ec_unlock(void) +{ + up(&thinkpad_ec_mutex); +} +EXPORT_SYMBOL_GPL(thinkpad_ec_unlock); + +/** + * thinkpad_ec_request_row - tell embedded controller to prepare a row + * @args Input register arguments + * + * Requests a data row by writing to H8S LPC registers TRW0 through TWR15 (or + * a subset thereof) following the protocol prescribed by the "H8S/2104B Group + * Hardware Manual". Does sanity checks via status register STR3. + */ +static int thinkpad_ec_request_row(const struct thinkpad_ec_row *args) +{ + u8 str3; + int i; + + /* EC protocol requires write to TWR0 (function code): */ + if (!(args->mask & 0x0001)) { + printk(KERN_ERR MSG_FMT("bad args->mask=0x%02x", args->mask)); + return -EINVAL; + } + + /* Check initial STR3 status: */ + str3 = inb(TPC_STR3_PORT) & H8S_STR3_MASK; + if (str3 & H8S_STR3_OBF3B) { /* data already pending */ + inb(TPC_TWR15_PORT); /* marks end of previous transaction */ + if (prefetch_jiffies == TPC_PREFETCH_NONE) + printk(KERN_WARNING REQ_FMT( + "EC has result from unrequested transaction", + str3)); + return -EBUSY; /* EC will be ready in a few usecs */ + } else if (str3 == H8S_STR3_SWMF) { /* busy with previous request */ + if (prefetch_jiffies == TPC_PREFETCH_NONE) + printk(KERN_WARNING REQ_FMT( + "EC is busy with unrequested transaction", + str3)); + return -EBUSY; /* data will be pending in a few usecs */ + } else if (str3 != 0x00) { /* unexpected status? */ + printk(KERN_WARNING REQ_FMT("unexpected initial STR3", str3)); + return -EIO; + } + + /* Send TWR0MW: */ + outb(args->val[0], TPC_TWR0_PORT); + str3 = inb(TPC_STR3_PORT) & H8S_STR3_MASK; + if (str3 != H8S_STR3_MWMF) { /* not accepted? */ + printk(KERN_WARNING REQ_FMT("arg0 rejected", str3)); + return -EIO; + } + + /* Send TWR1 through TWR14: */ + for (i = 1; i < TP_CONTROLLER_ROW_LEN-1; i++) + if ((args->mask>>i)&1) + outb(args->val[i], TPC_TWR0_PORT+i); + + /* Send TWR15 (default to 0x01). This marks end of command. */ + outb((args->mask & 0x8000) ? args->val[0xF] : 0x01, TPC_TWR15_PORT); + + /* Wait until EC starts writing its reply (~60ns on average). + * Releasing locks before this happens may cause an EC hang + * due to firmware bug! + */ + for (i = 0; i < TPC_REQUEST_RETRIES; i++) { + str3 = inb(TPC_STR3_PORT) & H8S_STR3_MASK; + if (str3 & H8S_STR3_SWMF) /* EC started replying */ + return 0; + else if (!(str3 & ~(H8S_STR3_IBF3B|H8S_STR3_MWMF))) + /* Normal progress (the EC hasn't seen the request + * yet, or is processing it). Wait it out. */ + ndelay(TPC_REQUEST_NDELAY); + else { /* weird EC status */ + printk(KERN_WARNING + REQ_FMT("bad end STR3", str3)); + return -EIO; + } + } + printk(KERN_WARNING REQ_FMT("EC is mysteriously silent", str3)); + return -EIO; +} + +/** + * thinkpad_ec_read_data - read pre-requested row-data from EC + * @args Input register arguments of pre-requested rows + * @data Output register values + * + * Reads current row data from the controller, assuming it's already + * requested. Follows the H8S spec for register access and status checks. + */ +static int thinkpad_ec_read_data(const struct thinkpad_ec_row *args, + struct thinkpad_ec_row *data) +{ + int i; + u8 str3 = inb(TPC_STR3_PORT) & H8S_STR3_MASK; + /* Once we make a request, STR3 assumes the sequence of values listed + * in the following 'if' as it reads the request and writes its data. + * It takes about a few dozen nanosecs total, with very high variance. + */ + if (str3 == (H8S_STR3_IBF3B|H8S_STR3_MWMF) || + str3 == 0x00 || /* the 0x00 is indistinguishable from idle EC! */ + str3 == H8S_STR3_SWMF) + return -EBUSY; /* not ready yet */ + /* Finally, the EC signals output buffer full: */ + if (str3 != (H8S_STR3_OBF3B|H8S_STR3_SWMF)) { + printk(KERN_WARNING + REQ_FMT("bad initial STR3", str3)); + return -EIO; + } + + /* Read first byte (signals start of read transactions): */ + data->val[0] = inb(TPC_TWR0_PORT); + /* Optionally read 14 more bytes: */ + for (i = 1; i < TP_CONTROLLER_ROW_LEN-1; i++) + if ((data->mask >> i)&1) + data->val[i] = inb(TPC_TWR0_PORT+i); + /* Read last byte from 0x161F (signals end of read transaction): */ + data->val[0xF] = inb(TPC_TWR15_PORT); + + /* Readout still pending? */ + str3 = inb(TPC_STR3_PORT) & H8S_STR3_MASK; + if (str3 & H8S_STR3_OBF3B) + printk(KERN_WARNING + REQ_FMT("OBF3B=1 after read", str3)); + /* If port 0x161F returns 0x80 too often, the EC may lock up. Warn: */ + if (data->val[0xF] == 0x80) + printk(KERN_WARNING + REQ_FMT("0x161F reports error", data->val[0xF])); + return 0; +} + +/** + * thinkpad_ec_is_row_fetched - is the given row currently prefetched? + * + * To keep things simple we compare only the first and last args; + * this suffices for all known cases. + */ +static int thinkpad_ec_is_row_fetched(const struct thinkpad_ec_row *args) +{ + return (prefetch_jiffies != TPC_PREFETCH_NONE) && + (prefetch_jiffies != TPC_PREFETCH_JUNK) && + (prefetch_arg0 == args->val[0]) && + (prefetch_argF == args->val[0xF]) && + (get_jiffies_64() < prefetch_jiffies + TPC_PREFETCH_TIMEOUT); +} + +/** + * thinkpad_ec_read_row - request and read data from ThinkPad EC + * @args Input register arguments + * @data Output register values + * + * Read a data row from the ThinkPad embedded controller LPC3 interface. + * Does fetching and retrying if needed. The row is specified by an + * array of 16 bytes, some of which may be undefined (but the first is + * mandatory). These bytes are given in @args->val[], where @args->val[i] is + * used iff (@args->mask>>i)&1). The resulting row data is stored in + * @data->val[], but is only guaranteed to be valid for indices corresponding + * to set bit in @data->mask. That is, if @data->mask&(1<val[i] is undefined. + * + * Returns -EBUSY on transient error and -EIO on abnormal condition. + * Caller must hold controller lock. + */ +int thinkpad_ec_read_row(const struct thinkpad_ec_row *args, + struct thinkpad_ec_row *data) +{ + int retries, ret; + + if (thinkpad_ec_is_row_fetched(args)) + goto read_row; /* already requested */ + + /* Request the row */ + for (retries = 0; retries < TPC_READ_RETRIES; ++retries) { + ret = thinkpad_ec_request_row(args); + if (!ret) + goto read_row; + if (ret != -EBUSY) + break; + ndelay(TPC_READ_NDELAY); + } + printk(KERN_ERR REQ_FMT("failed requesting row", ret)); + goto out; + +read_row: + /* Read the row's data */ + for (retries = 0; retries < TPC_READ_RETRIES; ++retries) { + ret = thinkpad_ec_read_data(args, data); + if (!ret) + goto out; + if (ret != -EBUSY) + break; + ndelay(TPC_READ_NDELAY); + } + + printk(KERN_ERR REQ_FMT("failed waiting for data", ret)); + +out: + prefetch_jiffies = TPC_PREFETCH_JUNK; + return ret; +} +EXPORT_SYMBOL_GPL(thinkpad_ec_read_row); + +/** + * thinkpad_ec_try_read_row - try reading prefetched data from ThinkPad EC + * @args Input register arguments + * @data Output register values + * + * Try reading a data row from the ThinkPad embedded controller LPC3 + * interface, if this raw was recently prefetched using + * thinkpad_ec_prefetch_row(). Does not fetch, retry or block. + * The parameters have the same meaning as in thinkpad_ec_read_row(). + * + * Returns -EBUSY is data not ready and -ENODATA if row not prefetched. + * Caller must hold controller lock. + */ +int thinkpad_ec_try_read_row(const struct thinkpad_ec_row *args, + struct thinkpad_ec_row *data) +{ + int ret; + if (!thinkpad_ec_is_row_fetched(args)) { + ret = -ENODATA; + } else { + ret = thinkpad_ec_read_data(args, data); + if (!ret) + prefetch_jiffies = TPC_PREFETCH_NONE; /* eaten up */ + } + return ret; +} +EXPORT_SYMBOL_GPL(thinkpad_ec_try_read_row); + +/** + * thinkpad_ec_prefetch_row - prefetch data from ThinkPad EC + * @args Input register arguments + * + * Prefetch a data row from the ThinkPad embedded controller LCP3 + * interface. A subsequent call to thinkpad_ec_read_row() with the + * same arguments will be faster, and a subsequent call to + * thinkpad_ec_try_read_row() stands a good chance of succeeding if + * done neither too soon nor too late. See + * thinkpad_ec_read_row() for the meaning of @args. + * + * Returns -EBUSY on transient error and -EIO on abnormal condition. + * Caller must hold controller lock. + */ +int thinkpad_ec_prefetch_row(const struct thinkpad_ec_row *args) +{ + int ret; + ret = thinkpad_ec_request_row(args); + if (ret) { + prefetch_jiffies = TPC_PREFETCH_JUNK; + } else { + prefetch_jiffies = get_jiffies_64(); + prefetch_arg0 = args->val[0x0]; + prefetch_argF = args->val[0xF]; + } + return ret; +} +EXPORT_SYMBOL_GPL(thinkpad_ec_prefetch_row); + +/** + * thinkpad_ec_invalidate - invalidate prefetched ThinkPad EC data + * + * Invalidate the data prefetched via thinkpad_ec_prefetch_row() from the + * ThinkPad embedded controller LPC3 interface. + * Must be called before unlocking by any code that accesses the controller + * ports directly. + */ +void thinkpad_ec_invalidate(void) +{ + prefetch_jiffies = TPC_PREFETCH_JUNK; +} +EXPORT_SYMBOL_GPL(thinkpad_ec_invalidate); + + +/*** Checking for EC hardware ***/ + +/** + * thinkpad_ec_test - verify the EC is present and follows protocol + * + * Ensure the EC LPC3 channel really works on this machine by making + * an EC request and seeing if the EC follows the documented H8S protocol. + * The requested row just reads battery status, so it should be harmless to + * access it (on a correct EC). + * This test writes to IO ports, so execute only after checking DMI. + */ +static int __init thinkpad_ec_test(void) +{ + int ret; + const struct thinkpad_ec_row args = /* battery 0 basic status */ + { .mask = 0x8001, .val = {0x01,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x00} }; + struct thinkpad_ec_row data = { .mask = 0x0000 }; + ret = thinkpad_ec_lock(); + if (ret) + return ret; + ret = thinkpad_ec_read_row(&args, &data); + thinkpad_ec_unlock(); + return ret; +} + +/* Search all DMI device names of a given type for a substring */ +static int __init dmi_find_substring(int type, const char *substr) +{ + const struct dmi_device *dev = NULL; + while ((dev = dmi_find_device(type, NULL, dev))) { + if (strstr(dev->name, substr)) + return 1; + } + return 0; +} + +#define TP_DMI_MATCH(vendor,model) { \ + .ident = vendor " " model, \ + .matches = { \ + DMI_MATCH(DMI_BOARD_VENDOR, vendor), \ + DMI_MATCH(DMI_PRODUCT_VERSION, model) \ + } \ +} + +/* Check DMI for existence of ThinkPad embedded controller */ +static int __init check_dmi_for_ec(void) +{ + /* A few old models that have a good EC but don't report it in DMI */ + struct dmi_system_id tp_whitelist[] = { + TP_DMI_MATCH("IBM", "ThinkPad A30"), + TP_DMI_MATCH("IBM", "ThinkPad T23"), + TP_DMI_MATCH("IBM", "ThinkPad X24"), + { .ident = NULL } + }; + return dmi_find_substring(DMI_DEV_TYPE_OEM_STRING, + "IBM ThinkPad Embedded Controller") || + dmi_check_system(tp_whitelist); +} + +/*** Init and cleanup ***/ + +static int __init thinkpad_ec_init(void) +{ + if (!check_dmi_for_ec()) { + printk(KERN_WARNING + "thinkpad_ec: no ThinkPad embedded controller!\n"); + return -ENODEV; + } + + if (!request_region(TPC_BASE_PORT, TPC_NUM_PORTS, + "thinkpad_ec")) { + printk(KERN_ERR "thinkpad_ec: cannot claim io ports %#x-%#x\n", + TPC_BASE_PORT, + TPC_BASE_PORT + TPC_NUM_PORTS - 1); + return -ENXIO; + } + prefetch_jiffies = TPC_PREFETCH_JUNK; + if (thinkpad_ec_test()) { + printk(KERN_ERR "thinkpad_ec: initial ec test failed\n"); + release_region(TPC_BASE_PORT, TPC_NUM_PORTS); + return -ENXIO; + } + printk(KERN_INFO "thinkpad_ec: thinkpad_ec " TP_VERSION " loaded.\n"); + return 0; +} + +static void __exit thinkpad_ec_exit(void) +{ + release_region(TPC_BASE_PORT, TPC_NUM_PORTS); + printk(KERN_INFO "thinkpad_ec: unloaded.\n"); +} + +module_init(thinkpad_ec_init); +module_exit(thinkpad_ec_exit); --- linux-2.6.28.orig/ubuntu/misc/Makefile +++ linux-2.6.28/ubuntu/misc/Makefile @@ -0,0 +1,15 @@ +# +# Makefile for Ubuntu additional drivers +# + +obj-$(CONFIG_USB_APPLEIR) += appleir.o +obj-$(CONFIG_BLK_DEV_DM_BBR) += dm-bbr.o +obj-$(CONFIG_INPUT_ACERHK) += acerhk.o +obj-$(CONFIG_LMPCM_USB) += lmpcm_usb.o +obj-$(CONFIG_TP_SMAPI) += tp_smapi.o +obj-$(CONFIG_TP_SMAPI_EC) += thinkpad_ec.o +obj-$(CONFIG_FSAM7400) += fsam7400.o + +obj-m += media/ wireless/ + +CFLAGS_dm-bbr.o += -I$(srctree)/drivers/md --- linux-2.6.28.orig/ubuntu/misc/thinkpad_ec.h +++ linux-2.6.28/ubuntu/misc/thinkpad_ec.h @@ -0,0 +1,47 @@ +/* + * thinkpad_ec.h - interface to ThinkPad embedded controller LPC3 functions + * + * Copyright (C) 2005 Shem Multinymous + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 _THINKPAD_EC_H +#define _THINKPAD_EC_H + +#ifdef __KERNEL__ + +#define TP_CONTROLLER_ROW_LEN 16 + +/* EC transactions input and output (possibly partial) vectors of 16 bytes. */ +struct thinkpad_ec_row { + u16 mask; /* bitmap of which entries of val[] are meaningful */ + u8 val[TP_CONTROLLER_ROW_LEN]; +}; + +extern int __must_check thinkpad_ec_lock(void); +extern int __must_check thinkpad_ec_try_lock(void); +extern void thinkpad_ec_unlock(void); + +extern int thinkpad_ec_read_row(const struct thinkpad_ec_row *args, + struct thinkpad_ec_row *data); +extern int thinkpad_ec_try_read_row(const struct thinkpad_ec_row *args, + struct thinkpad_ec_row *mask); +extern int thinkpad_ec_prefetch_row(const struct thinkpad_ec_row *args); +extern void thinkpad_ec_invalidate(void); + + +#endif /* __KERNEL */ +#endif /* _THINKPAD_EC_H */ --- linux-2.6.28.orig/ubuntu/misc/dm-bbr.c +++ linux-2.6.28/ubuntu/misc/dm-bbr.c @@ -0,0 +1,1012 @@ +/* + * (C) Copyright IBM Corp. 2002, 2004 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + * + * linux/drivers/md/dm-bbr.c + * + * Bad-block-relocation (BBR) target for device-mapper. + * + * The BBR target is designed to remap I/O write failures to another safe + * location on disk. Note that most disk drives have BBR built into them, + * this means that our software BBR will be only activated when all hardware + * BBR replacement sectors have been used. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dm-bio-record.h" +#include "dm.h" +#include "dm-bbr.h" + +#define DM_MSG_PREFIX "bbr" +#define SECTOR_SIZE (1 << SECTOR_SHIFT) + +static struct workqueue_struct *dm_bbr_wq = NULL; +static void bbr_remap_handler(struct work_struct *work); +static struct kmem_cache *bbr_remap_cache; +static struct kmem_cache *bbr_io_cache; +static mempool_t *bbr_io_pool; + +/** + * bbr_binary_tree_destroy + * + * Destroy the binary tree. + **/ +static void bbr_binary_tree_destroy(struct bbr_runtime_remap *root) +{ + struct bbr_runtime_remap **link = NULL; + struct bbr_runtime_remap *node = root; + + while (node) { + if (node->left) { + link = &node->left; + node = node->left; + continue; + } + if (node->right) { + link = &node->right; + node = node->right; + continue; + } + + kmem_cache_free(bbr_remap_cache, node); + if (node == root) { + /* If root is deleted, we're done. */ + break; + } + + /* Back to root. */ + node = root; + *link = NULL; + } +} + +static void bbr_free_remap(struct bbr_private *bbr_id) +{ + spin_lock_irq(&bbr_id->remap_root_lock); + bbr_binary_tree_destroy(bbr_id->remap_root); + bbr_id->remap_root = NULL; + spin_unlock_irq(&bbr_id->remap_root_lock); +} + +static struct bbr_private *bbr_alloc_private(void) +{ + struct bbr_private *bbr_id; + + bbr_id = kzalloc(sizeof(*bbr_id), GFP_KERNEL); + if (bbr_id == NULL) + return NULL; + + INIT_WORK(&bbr_id->remap_work, bbr_remap_handler); + spin_lock_init(&bbr_id->remap_root_lock); + spin_lock_init(&bbr_id->remap_ios_lock); + bbr_id->in_use_replacement_blks = (atomic_t) ATOMIC_INIT(0); + + return bbr_id; +} + +static void bbr_free_private(struct bbr_private *bbr_id) +{ + vfree(bbr_id->bbr_table); + bbr_free_remap(bbr_id); + kfree(bbr_id); +} + +static u32 crc_table[256]; +static u32 crc_table_built = 0; + +static void build_crc_table(void) +{ + u32 i, j, crc; + + for (i = 0; i <= 255; i++) { + crc = i; + for (j = 8; j > 0; j--) { + if (crc & 1) + crc = (crc >> 1) ^ CRC_POLYNOMIAL; + else + crc >>= 1; + } + crc_table[i] = crc; + } + crc_table_built = 1; +} + +static u32 calculate_crc(u32 crc, void *buffer, u32 buffersize) +{ + unsigned char *current_byte; + u32 temp1, temp2, i; + + current_byte = (unsigned char *) buffer; + /* Make sure the crc table is available */ + if (!crc_table_built) + build_crc_table(); + /* Process each byte in the buffer. */ + for (i = 0; i < buffersize; i++) { + temp1 = (crc >> 8) & 0x00FFFFFF; + temp2 = crc_table[(crc ^ (u32) * current_byte) & + (u32) 0xff]; + current_byte++; + crc = temp1 ^ temp2; + } + return crc; +} + +/** + * le_bbr_table_sector_to_cpu + * + * Convert bbr meta data from on-disk (LE) format + * to the native cpu endian format. + **/ +static void le_bbr_table_sector_to_cpu(struct bbr_table *p) +{ + int i; + p->signature = le32_to_cpup(&p->signature); + p->crc = le32_to_cpup(&p->crc); + p->sequence_number = le32_to_cpup(&p->sequence_number); + p->in_use_cnt = le32_to_cpup(&p->in_use_cnt); + for (i = 0; i < BBR_ENTRIES_PER_SECT; i++) { + p->entries[i].bad_sect = + le64_to_cpup(&p->entries[i].bad_sect); + p->entries[i].replacement_sect = + le64_to_cpup(&p->entries[i].replacement_sect); + } +} + +/** + * cpu_bbr_table_sector_to_le + * + * Convert bbr meta data from cpu endian format to on-disk (LE) format + **/ +static void cpu_bbr_table_sector_to_le(struct bbr_table *p, + struct bbr_table *le) +{ + int i; + le->signature = cpu_to_le32p(&p->signature); + le->crc = cpu_to_le32p(&p->crc); + le->sequence_number = cpu_to_le32p(&p->sequence_number); + le->in_use_cnt = cpu_to_le32p(&p->in_use_cnt); + for (i = 0; i < BBR_ENTRIES_PER_SECT; i++) { + le->entries[i].bad_sect = + cpu_to_le64p(&p->entries[i].bad_sect); + le->entries[i].replacement_sect = + cpu_to_le64p(&p->entries[i].replacement_sect); + } +} + +/** + * validate_bbr_table_sector + * + * Check the specified BBR table sector for a valid signature and CRC. If it's + * valid, endian-convert the table sector. + **/ +static int validate_bbr_table_sector(struct bbr_table *p) +{ + int org_crc, final_crc; + + if (le32_to_cpup(&p->signature) != BBR_TABLE_SIGNATURE) { + DMERR("BBR table signature doesn't match!"); + DMERR("Found 0x%x. Expecting 0x%x", + le32_to_cpup(&p->signature), BBR_TABLE_SIGNATURE); + return -EINVAL; + } + + if (!p->crc) { + DMERR("BBR table sector has no CRC!"); + return -EINVAL; + } + + org_crc = le32_to_cpup(&p->crc); + p->crc = 0; + final_crc = calculate_crc(INITIAL_CRC, (void *)p, sizeof(*p)); + if (final_crc != org_crc) { + DMERR("CRC failed!"); + DMERR("Found 0x%x. Expecting 0x%x", + org_crc, final_crc); + return -EINVAL; + } + + p->crc = cpu_to_le32p(&org_crc); + le_bbr_table_sector_to_cpu(p); + + return 0; +} + +/** + * bbr_binary_tree_insert + * + * Insert a node into the binary tree. + **/ +static void bbr_binary_tree_insert(struct bbr_runtime_remap **root, + struct bbr_runtime_remap *newnode) +{ + struct bbr_runtime_remap **node = root; + while (node && *node) { + node = (newnode->remap.bad_sect > (*node)->remap.bad_sect) ? + &(*node)->right : &(*node)->left; + } + + newnode->left = newnode->right = NULL; + *node = newnode; +} + +/** + * bbr_binary_search + * + * Search for a node that contains bad_sect == lsn. + **/ +static struct bbr_runtime_remap *bbr_binary_search( + struct bbr_runtime_remap *root, + u64 lsn) +{ + struct bbr_runtime_remap *node = root; + while (node) { + if (node->remap.bad_sect == lsn) + break; + + node = (lsn > node->remap.bad_sect) ? node->right : node->left; + } + return node; +} + +/** + * bbr_insert_remap_entry + * + * Create a new remap entry and add it to the binary tree for this node. + **/ +static int bbr_insert_remap_entry(struct bbr_private *bbr_id, + struct bbr_table_entry *new_bbr_entry) +{ + struct bbr_runtime_remap *newnode; + + newnode = kmem_cache_alloc(bbr_remap_cache, GFP_NOIO); + if (!newnode) { + DMERR("Could not allocate from remap cache!"); + return -ENOMEM; + } + newnode->remap.bad_sect = new_bbr_entry->bad_sect; + newnode->remap.replacement_sect = new_bbr_entry->replacement_sect; + spin_lock_irq(&bbr_id->remap_root_lock); + bbr_binary_tree_insert(&bbr_id->remap_root, newnode); + spin_unlock_irq(&bbr_id->remap_root_lock); + return 0; +} + +/** + * bbr_table_to_remap_list + * + * The on-disk bbr table is sorted by the replacement sector LBA. In order to + * improve run time performance, the in memory remap list must be sorted by + * the bad sector LBA. This function is called at discovery time to initialize + * the remap list. This function assumes that at least one copy of meta data + * is valid. + **/ +static u32 bbr_table_to_remap_list(struct bbr_private *bbr_id) +{ + u32 in_use_blks = 0; + int i, j; + struct bbr_table *p; + + for (i = 0, p = bbr_id->bbr_table; + i < bbr_id->nr_sects_bbr_table; + i++, p++) { + if (!p->in_use_cnt) + break; + + in_use_blks += p->in_use_cnt; + for (j = 0; j < p->in_use_cnt; j++) + bbr_insert_remap_entry(bbr_id, &p->entries[j]); + } + if (in_use_blks) { + char b[32]; + DMWARN("There are %u BBR entries for device %s", + in_use_blks, format_dev_t(b, bbr_id->dev->bdev->bd_dev)); + } + + return in_use_blks; +} + +/** + * bbr_search_remap_entry + * + * Search remap entry for the specified sector. If found, return a pointer to + * the table entry. Otherwise, return NULL. + **/ +static struct bbr_table_entry *bbr_search_remap_entry( + struct bbr_private *bbr_id, + u64 lsn) +{ + struct bbr_runtime_remap *p; + + spin_lock_irq(&bbr_id->remap_root_lock); + p = bbr_binary_search(bbr_id->remap_root, lsn); + spin_unlock_irq(&bbr_id->remap_root_lock); + return (p) ? &p->remap : NULL; +} + +/** + * bbr_remap + * + * If *lsn is in the remap table, return TRUE and modify *lsn, + * else, return FALSE. + **/ +static int bbr_remap(struct bbr_private *bbr_id, + u64 *lsn) +{ + struct bbr_table_entry *e; + + if (atomic_read(&bbr_id->in_use_replacement_blks)) { + e = bbr_search_remap_entry(bbr_id, *lsn); + if (e) { + *lsn = e->replacement_sect; + return 1; + } + } + return 0; +} + +/** + * bbr_remap_probe + * + * If any of the sectors in the range [lsn, lsn+nr_sects] are in the remap + * table return TRUE, Else, return FALSE. + **/ +static int bbr_remap_probe(struct bbr_private *bbr_id, + u64 lsn, u64 nr_sects) +{ + u64 tmp, cnt; + + if (atomic_read(&bbr_id->in_use_replacement_blks)) { + for (cnt = 0, tmp = lsn; + cnt < nr_sects; + cnt += bbr_id->blksize_in_sects, tmp = lsn + cnt) { + if (bbr_remap(bbr_id,&tmp)) + return 1; + } + } + return 0; +} + +static int rw_table(struct bbr_private *bbr_id, void *vma, + struct dm_io_region *ptr, int rw) +{ + bbr_id->vma_io_req.bi_rw = rw; + bbr_id->vma_io_req.mem.ptr.vma = vma; + bbr_id->vma_io_req.notify.fn = NULL; + + return dm_io(&bbr_id->vma_io_req, 1, ptr, NULL); +} + +static int io_sync(struct bbr_private *bbr_id, struct page_list *pl, + unsigned offset, struct dm_io_region *ptr, int rw) +{ + bbr_id->page_io_req.bi_rw = rw; + bbr_id->page_io_req.mem.ptr.pl = pl; + bbr_id->page_io_req.mem.offset = offset; + bbr_id->page_io_req.notify.fn = NULL; + + return dm_io(&bbr_id->page_io_req, 1, ptr, NULL); +} + +/** + * bbr_setup + * + * Read the remap tables from disk and set up the initial remap tree. + **/ +static int bbr_setup(struct bbr_private *bbr_id) +{ + struct bbr_table *table = bbr_id->bbr_table; + struct dm_io_region job; + int i, rc = 0; + + job.bdev = bbr_id->dev->bdev; + job.count = 1; + + /* Read and verify each BBR table sector individually. */ + for (i = 0; i < bbr_id->nr_sects_bbr_table; i++, table++) { + job.sector = bbr_id->lba_table1 + i; + rc = rw_table(bbr_id, table, &job, READ); + if (rc && bbr_id->lba_table2) { + job.sector = bbr_id->lba_table2 + i; + rc = rw_table(bbr_id, table, &job, READ); + } + if (rc) { + goto out; + } + + rc = validate_bbr_table_sector(table); + if (rc) { + goto out; + } + } + atomic_set(&bbr_id->in_use_replacement_blks, + bbr_table_to_remap_list(bbr_id)); + +out: + if (rc) + DMERR("error during device setup: %d", rc); + return rc; +} + +/** + * bbr_io_remap_error + * @bbr_id: Private data for the BBR node. + * @rw: READ or WRITE. + * @starting_lsn: Starting sector of request to remap. + * @count: Number of sectors in the request. + * @page: Page containing the data for the request. + * @offset: Byte-offset of the data within the page. + * + * For the requested range, try to write each sector individually. For each + * sector that fails, find the next available remap location and write the + * data to that new location. Then update the table and write both copies + * of the table to disk. Finally, update the in-memory mapping and do any + * other necessary bookkeeping. + **/ +static int bbr_io_remap_error(struct bbr_private *bbr_id, + int rw, + u64 starting_lsn, + u64 count, + struct page *page, + unsigned int offset) +{ + struct bbr_table *bbr_table; + struct dm_io_region job; + struct page_list pl; + unsigned long table_sector_index; + unsigned long table_sector_offset; + unsigned long index; + u64 lsn, new_lsn; + char b[32]; + int rc; + + job.bdev = bbr_id->dev->bdev; + job.count = 1; + pl.page = page; + pl.next = NULL; + + /* For each sector in the request. */ + for (lsn = 0; lsn < count; lsn++, offset += SECTOR_SIZE) { + job.sector = starting_lsn + lsn; + rc = io_sync(bbr_id, &pl, offset, &job, rw); + while (rc) { + /* Find the next available relocation sector. */ + new_lsn = atomic_read(&bbr_id->in_use_replacement_blks); + if (new_lsn >= bbr_id->nr_replacement_blks) { + /* No more replacement sectors available. */ + return -EIO; + } + new_lsn += bbr_id->start_replacement_sect; + + /* Write the data to its new location. */ + DMWARN("device %s: Trying to remap bad sector "PFU64" to sector "PFU64, + format_dev_t(b, bbr_id->dev->bdev->bd_dev), + starting_lsn + lsn, new_lsn); + job.sector = new_lsn; + rc = io_sync(bbr_id, &pl, offset, &job, rw); + if (rc) { + /* This replacement sector is bad. + * Try the next one. + */ + DMERR("device %s: replacement sector "PFU64" is bad. Skipping.", + format_dev_t(b, bbr_id->dev->bdev->bd_dev), new_lsn); + atomic_inc(&bbr_id->in_use_replacement_blks); + continue; + } + + /* Add this new entry to the on-disk table. */ + table_sector_index = new_lsn - + bbr_id->start_replacement_sect; + table_sector_offset = table_sector_index / + BBR_ENTRIES_PER_SECT; + index = table_sector_index % BBR_ENTRIES_PER_SECT; + + bbr_table = &bbr_id->bbr_table[table_sector_offset]; + bbr_table->entries[index].bad_sect = starting_lsn + lsn; + bbr_table->entries[index].replacement_sect = new_lsn; + bbr_table->in_use_cnt++; + bbr_table->sequence_number++; + bbr_table->crc = 0; + bbr_table->crc = calculate_crc(INITIAL_CRC, + bbr_table, + sizeof(struct bbr_table)); + + /* Write the table to disk. */ + cpu_bbr_table_sector_to_le(bbr_table, bbr_table); + if (bbr_id->lba_table1) { + job.sector = bbr_id->lba_table1 + table_sector_offset; + rc = rw_table(bbr_id, bbr_table, &job, WRITE); + } + if (bbr_id->lba_table2) { + job.sector = bbr_id->lba_table2 + table_sector_offset; + rc |= rw_table(bbr_id, bbr_table, &job, WRITE); + } + le_bbr_table_sector_to_cpu(bbr_table); + + if (rc) { + /* Error writing one of the tables to disk. */ + DMERR("device %s: error updating BBR tables on disk.", + format_dev_t(b, bbr_id->dev->bdev->bd_dev)); + return rc; + } + + /* Insert a new entry in the remapping binary-tree. */ + rc = bbr_insert_remap_entry(bbr_id, + &bbr_table->entries[index]); + if (rc) { + DMERR("device %s: error adding new entry to remap tree.", + format_dev_t(b, bbr_id->dev->bdev->bd_dev)); + return rc; + } + + atomic_inc(&bbr_id->in_use_replacement_blks); + } + } + + return 0; +} + +/** + * bbr_io_process_request + * + * For each sector in this request, check if the sector has already + * been remapped. If so, process all previous sectors in the request, + * followed by the remapped sector. Then reset the starting lsn and + * count, and keep going with the rest of the request as if it were + * a whole new request. If any of the sync_io's return an error, + * call the remapper to relocate the bad sector(s). + * + * 2.5 Note: When switching over to bio's for the I/O path, we have made + * the assumption that the I/O request described by the bio is one + * virtually contiguous piece of memory (even though the bio vector + * describes it using a series of physical page addresses). + **/ +static int bbr_io_process_request(struct bbr_private *bbr_id, + struct bio *bio) +{ + struct dm_io_region job; + u64 starting_lsn = bio->bi_sector; + u64 count, lsn, remapped_lsn; + struct page_list pl; + unsigned int offset; + int i, rw = bio_data_dir(bio); + int rc = 0; + + job.bdev = bbr_id->dev->bdev; + pl.next = NULL; + + /* Each bio can contain multiple vectors, each with a different page. + * Treat each vector as a separate request. + */ + /* KMC: Is this the right way to walk the bvec list? */ + for (i = 0; + i < bio->bi_vcnt; + i++, bio->bi_idx++, starting_lsn += count) { + + /* Bvec info: number of sectors, page, + * and byte-offset within page. + */ + count = bio_iovec(bio)->bv_len >> SECTOR_SHIFT; + pl.page = bio_iovec(bio)->bv_page; + offset = bio_iovec(bio)->bv_offset; + + /* For each sector in this bvec, check if the sector has + * already been remapped. If so, process all previous sectors + * in this request, followed by the remapped sector. Then reset + * the starting lsn and count and keep going with the rest of + * the request as if it were a whole new request. + */ + for (lsn = 0; lsn < count; lsn++) { + remapped_lsn = starting_lsn + lsn; + rc = bbr_remap(bbr_id, &remapped_lsn); + if (!rc) { + /* This sector is fine. */ + continue; + } + + /* Process all sectors in the request up to this one. */ + if (lsn > 0) { + job.sector = starting_lsn; + job.count = lsn; + rc = io_sync(bbr_id, &pl, offset, &job, rw); + if (rc) { + /* If this I/O failed, then one of the + * sectors in this request needs to be + * relocated. + */ + rc = bbr_io_remap_error(bbr_id, rw, + starting_lsn, + lsn, pl.page, + offset); + if (rc) { + /* KMC: Return? Or continue to next bvec? */ + return rc; + } + } + offset += (lsn << SECTOR_SHIFT); + } + + /* Process the remapped sector. */ + job.sector = remapped_lsn; + job.count = 1; + rc = io_sync(bbr_id, &pl, offset, &job, rw); + if (rc) { + /* BUGBUG - Need more processing if this caused + * an error. If this I/O failed, then the + * existing remap is now bad, and we need to + * find a new remap. Can't use + * bbr_io_remap_error(), because the existing + * map entry needs to be changed, not added + * again, and the original table entry also + * needs to be changed. + */ + return rc; + } + + starting_lsn += (lsn + 1); + count -= (lsn + 1); + lsn = -1; + offset += SECTOR_SIZE; + } + + /* Check for any remaining sectors after the last split. This + * could potentially be the whole request, but that should be a + * rare case because requests should only be processed by the + * thread if we know an error occurred or they contained one or + * more remapped sectors. + */ + if (count) { + job.sector = starting_lsn; + job.count = count; + rc = io_sync(bbr_id, &pl, offset, &job, rw); + if (rc) { + /* If this I/O failed, then one of the sectors + * in this request needs to be relocated. + */ + rc = bbr_io_remap_error(bbr_id, rw, starting_lsn, + count, pl.page, offset); + if (rc) { + /* KMC: Return? Or continue to next bvec? */ + return rc; + } + } + } + } + + return 0; +} + +static void bbr_io_process_requests(struct bbr_private *bbr_id, + struct bio *bio) +{ + struct bio *next; + int rc; + + while (bio) { + next = bio->bi_next; + bio->bi_next = NULL; + + rc = bbr_io_process_request(bbr_id, bio); + + bio_endio(bio, rc); + + bio = next; + } +} + +/** + * bbr_remap_handler + * + * This is the handler for the bbr work-queue. + * + * I/O requests should only be sent to this handler if we know that: + * a) the request contains at least one remapped sector. + * or + * b) the request caused an error on the normal I/O path. + * + * This function uses synchronous I/O, so sending a request to this + * thread that doesn't need special processing will cause severe + * performance degredation. + **/ +static void bbr_remap_handler(struct work_struct *work) +{ + struct bbr_private *bbr_id = + container_of(work, struct bbr_private, remap_work); + struct bio *bio; + unsigned long flags; + + spin_lock_irqsave(&bbr_id->remap_ios_lock, flags); + bio = bio_list_get(&bbr_id->remap_ios); + spin_unlock_irqrestore(&bbr_id->remap_ios_lock, flags); + + bbr_io_process_requests(bbr_id, bio); +} + +/** + * bbr_endio + * + * This is the callback for normal write requests. Check for an error + * during the I/O, and send to the thread for processing if necessary. + **/ +static int bbr_endio(struct dm_target *ti, struct bio *bio, + int error, union map_info *map_context) +{ + struct bbr_private *bbr_id = ti->private; + struct dm_bio_details *bbr_io = map_context->ptr; + + if (error && bbr_io) { + unsigned long flags; + char b[32]; + + dm_bio_restore(bbr_io, bio); + map_context->ptr = NULL; + + DMERR("device %s: I/O failure on sector %lu. " + "Scheduling for retry.", + format_dev_t(b, bbr_id->dev->bdev->bd_dev), + (unsigned long)bio->bi_sector); + + spin_lock_irqsave(&bbr_id->remap_ios_lock, flags); + bio_list_add(&bbr_id->remap_ios, bio); + spin_unlock_irqrestore(&bbr_id->remap_ios_lock, flags); + + queue_work(dm_bbr_wq, &bbr_id->remap_work); + + error = 1; + } + + if (bbr_io) + mempool_free(bbr_io, bbr_io_pool); + + return error; +} + +/** + * Construct a bbr mapping + **/ +static int bbr_ctr(struct dm_target *ti, unsigned int argc, char **argv) +{ + struct bbr_private *bbr_id; + unsigned long block_size; + char *end; + int rc = -EINVAL; + + if (argc != 8) { + ti->error = "dm-bbr requires exactly 8 arguments: " + "device offset table1_lsn table2_lsn table_size start_replacement nr_replacement_blks block_size"; + goto out1; + } + + bbr_id = bbr_alloc_private(); + if (!bbr_id) { + ti->error = "dm-bbr: Error allocating bbr private data."; + goto out1; + } + + bbr_id->offset = simple_strtoull(argv[1], &end, 10); + bbr_id->lba_table1 = simple_strtoull(argv[2], &end, 10); + bbr_id->lba_table2 = simple_strtoull(argv[3], &end, 10); + bbr_id->nr_sects_bbr_table = simple_strtoull(argv[4], &end, 10); + bbr_id->start_replacement_sect = simple_strtoull(argv[5], &end, 10); + bbr_id->nr_replacement_blks = simple_strtoull(argv[6], &end, 10); + block_size = simple_strtoul(argv[7], &end, 10); + bbr_id->blksize_in_sects = (block_size >> SECTOR_SHIFT); + + bbr_id->vma_io_req.mem.type = DM_IO_VMA; + bbr_id->vma_io_req.client = dm_io_client_create(1); + if (IS_ERR(bbr_id->vma_io_req.client)) { + rc = PTR_ERR(bbr_id->vma_io_req.client); + DMWARN("couldn't allocate disk VMA io client"); + goto out2; + } + + bbr_id->page_io_req.mem.type = DM_IO_PAGE_LIST; + bbr_id->page_io_req.client = dm_io_client_create(1); + if (IS_ERR(bbr_id->page_io_req.client)) { + rc = PTR_ERR(bbr_id->page_io_req.client); + DMWARN("couldn't allocate pagelist io client"); + goto out3; + } + + bbr_id->bbr_table = vmalloc(bbr_id->nr_sects_bbr_table << SECTOR_SHIFT); + if (!bbr_id->bbr_table) { + ti->error = "dm-bbr: Error allocating bbr table."; + goto out4; + } + + if (dm_get_device(ti, argv[0], 0, ti->len, + dm_table_get_mode(ti->table), &bbr_id->dev)) { + ti->error = "dm-bbr: Device lookup failed"; + goto out4; + } + + rc = bbr_setup(bbr_id); + if (rc) { + ti->error = "dm-bbr: Device setup failed"; + goto out5; + } + + ti->private = bbr_id; + return 0; + +out5: + dm_put_device(ti, bbr_id->dev); +out4: + dm_io_client_destroy(bbr_id->page_io_req.client); +out3: + dm_io_client_destroy(bbr_id->vma_io_req.client); +out2: + bbr_free_private(bbr_id); +out1: + return rc; +} + +static void bbr_dtr(struct dm_target *ti) +{ + struct bbr_private *bbr_id = ti->private; + + dm_put_device(ti, bbr_id->dev); + dm_io_client_destroy(bbr_id->page_io_req.client); + dm_io_client_destroy(bbr_id->vma_io_req.client); + bbr_free_private(bbr_id); +} + +static int bbr_map(struct dm_target *ti, struct bio *bio, + union map_info *map_context) +{ + struct bbr_private *bbr_id = ti->private; + struct dm_bio_details *bbr_io; + unsigned long flags; + int rc = 1; + + bio->bi_sector += bbr_id->offset; + + if (atomic_read(&bbr_id->in_use_replacement_blks) == 0 || + !bbr_remap_probe(bbr_id, bio->bi_sector, bio_sectors(bio))) { + /* No existing remaps or this request doesn't + * contain any remapped sectors. + */ + bio->bi_bdev = bbr_id->dev->bdev; + + bbr_io = mempool_alloc(bbr_io_pool, GFP_NOIO); + dm_bio_record(bbr_io, bio); + map_context->ptr = bbr_io; + } else { + /* This request has at least one remapped sector. + * Give it to the work-queue for processing. + */ + map_context->ptr = NULL; + spin_lock_irqsave(&bbr_id->remap_ios_lock, flags); + bio_list_add(&bbr_id->remap_ios, bio); + spin_unlock_irqrestore(&bbr_id->remap_ios_lock, flags); + + queue_work(dm_bbr_wq, &bbr_id->remap_work); + rc = 0; + } + + return rc; +} + +static int bbr_status(struct dm_target *ti, status_type_t type, + char *result, unsigned int maxlen) +{ + struct bbr_private *bbr_id = ti->private; + char b[BDEVNAME_SIZE]; + + switch (type) { + case STATUSTYPE_INFO: + result[0] = '\0'; + break; + + case STATUSTYPE_TABLE: + snprintf(result, maxlen, "%s "PFU64" "PFU64" "PFU64" "PFU64" "PFU64" "PFU64" %u", + format_dev_t(b, bbr_id->dev->bdev->bd_dev), + bbr_id->offset, bbr_id->lba_table1, bbr_id->lba_table2, + bbr_id->nr_sects_bbr_table, + bbr_id->start_replacement_sect, + bbr_id->nr_replacement_blks, + bbr_id->blksize_in_sects << SECTOR_SHIFT); + break; + } + return 0; +} + +static struct target_type bbr_target = { + .name = "bbr", + .version= {1, 0, 1}, + .module = THIS_MODULE, + .ctr = bbr_ctr, + .dtr = bbr_dtr, + .map = bbr_map, + .end_io = bbr_endio, + .status = bbr_status, +}; + +int __init dm_bbr_init(void) +{ + int rc; + + rc = dm_register_target(&bbr_target); + if (rc) { + DMERR("error registering target."); + goto err1; + } + + bbr_remap_cache = kmem_cache_create("bbr-remap", + sizeof(struct bbr_runtime_remap), + 0, SLAB_HWCACHE_ALIGN, NULL); + if (!bbr_remap_cache) { + DMERR("error creating remap cache."); + rc = ENOMEM; + goto err2; + } + + bbr_io_cache = kmem_cache_create("bbr-io", sizeof(struct dm_bio_details), + 0, SLAB_HWCACHE_ALIGN, NULL); + if (!bbr_io_cache) { + DMERR("error creating io cache."); + rc = ENOMEM; + goto err3; + } + + bbr_io_pool = mempool_create(256, mempool_alloc_slab, + mempool_free_slab, bbr_io_cache); + if (!bbr_io_pool) { + DMERR("error creating io mempool."); + rc = ENOMEM; + goto err4; + } + + dm_bbr_wq = create_workqueue("dm-bbr"); + if (!dm_bbr_wq) { + DMERR("error creating work-queue."); + rc = ENOMEM; + goto err5; + } + + return 0; + +err5: + mempool_destroy(bbr_io_pool); +err4: + kmem_cache_destroy(bbr_io_cache); +err3: + kmem_cache_destroy(bbr_remap_cache); +err2: + dm_unregister_target(&bbr_target); +err1: + return rc; +} + +void __exit dm_bbr_exit(void) +{ + destroy_workqueue(dm_bbr_wq); + mempool_destroy(bbr_io_pool); + kmem_cache_destroy(bbr_io_cache); + kmem_cache_destroy(bbr_remap_cache); + dm_unregister_target(&bbr_target); +} + +module_init(dm_bbr_init); +module_exit(dm_bbr_exit); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/ubuntu/misc/dm-bbr.h +++ linux-2.6.28/ubuntu/misc/dm-bbr.h @@ -0,0 +1,132 @@ +/* + * (C) Copyright IBM Corp. 2002, 2004 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + * + * linux/drivers/md/dm-bbr.h + * + * Bad-block-relocation (BBR) target for device-mapper. + * + * The BBR target is designed to remap I/O write failures to another safe + * location on disk. Note that most disk drives have BBR built into them, + * this means that our software BBR will be only activated when all hardware + * BBR replacement sectors have been used. + */ + +#include +#include +#include + +#define BBR_TABLE_SIGNATURE 0x42627254 /* BbrT */ +#define BBR_ENTRIES_PER_SECT 31 +#define INITIAL_CRC 0xFFFFFFFF +#define CRC_POLYNOMIAL 0xEDB88320L + +/** + * Macros to cleanly print 64-bit numbers on both 32-bit and 64-bit machines. + * Use these in place of %Ld, %Lu, and %Lx. + **/ +#if BITS_PER_LONG > 32 +#define PFU64 "%lu" +#else +#define PFU64 "%Lu" +#endif + +/** + * struct bbr_table_entry + * @bad_sect: LBA of bad location. + * @replacement_sect: LBA of new location. + * + * Structure to describe one BBR remap. + **/ +struct bbr_table_entry { + u64 bad_sect; + u64 replacement_sect; +}; + +/** + * struct bbr_table + * @signature: Signature on each BBR table sector. + * @crc: CRC for this table sector. + * @sequence_number: Used to resolve conflicts when primary and secondary + * tables do not match. + * @in_use_cnt: Number of in-use table entries. + * @entries: Actual table of remaps. + * + * Structure to describe each sector of the metadata table. Each sector in this + * table can describe 31 remapped sectors. + **/ +struct bbr_table { + u32 signature; + u32 crc; + u32 sequence_number; + u32 in_use_cnt; + struct bbr_table_entry entries[BBR_ENTRIES_PER_SECT]; +}; + +/** + * struct bbr_runtime_remap + * + * Node in the binary tree used to keep track of remaps. + **/ +struct bbr_runtime_remap { + struct bbr_table_entry remap; + struct bbr_runtime_remap *left; + struct bbr_runtime_remap *right; +}; + +/** + * struct bbr_private + * @dev: Info about underlying device. + * @bbr_table: Copy of metadata table. + * @remap_root: Binary tree containing all remaps. + * @remap_root_lock: Lock for the binary tree. + * @remap_work: For adding work items to the work-queue. + * @remap_ios: List of I/Os for the work-queue to handle. + * @remap_ios_lock: Lock for the remap_ios list. + * @offset: LBA of data area. + * @lba_table1: LBA of primary BBR table. + * @lba_table2: LBA of secondary BBR table. + * @nr_sects_bbr_table: Size of each BBR table. + * @nr_replacement_blks: Number of replacement blocks. + * @start_replacement_sect: LBA of start of replacement blocks. + * @blksize_in_sects: Size of each block. + * @in_use_replacement_blks: Current number of remapped blocks. + * + * Private data for each BBR target. + **/ +struct bbr_private { + struct dm_dev *dev; + struct bbr_table *bbr_table; + struct bbr_runtime_remap *remap_root; + spinlock_t remap_root_lock; + + struct dm_io_request vma_io_req; + struct dm_io_request page_io_req; + + struct work_struct remap_work; + struct bio_list remap_ios; + spinlock_t remap_ios_lock; + + u64 offset; + u64 lba_table1; + u64 lba_table2; + u64 nr_sects_bbr_table; + u64 start_replacement_sect; + u64 nr_replacement_blks; + u32 blksize_in_sects; + atomic_t in_use_replacement_blks; +}; + --- linux-2.6.28.orig/ubuntu/misc/appleir.c +++ linux-2.6.28/ubuntu/misc/appleir.c @@ -0,0 +1,401 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Version Information + * + */ + +#if 0 +#define DUMP_PACKETS +#else +#undef DUMP_PACKETS +#endif + +#define DRIVER_VERSION "v1.1" +#define DRIVER_AUTHOR "James McKenzie" +#define DRIVER_DESC "USB Apple MacMini IR Receiver driver" +#define DRIVER_LICENSE "GPL" + +MODULE_AUTHOR (DRIVER_AUTHOR); +MODULE_DESCRIPTION (DRIVER_DESC); +MODULE_LICENSE (DRIVER_LICENSE); + +#ifndef USB_VENDOR_ID_APPLE +#define USB_VENDOR_ID_APPLE 0x05ac +#endif +#ifndef USB_DEVICE_ID_APPLE_IR +#define USB_DEVICE_ID_APPLE_IR 0x8240 +#endif +#ifndef USB_DEVICE_ID_APPLE_IR2 +#define USB_DEVICE_ID_APPLE_IR2 0x8242 +#endif + +#define URB_SIZE 32 + +#define MAX_KEYS 8 +#define MAX_KEYS_MASK (MAX_KEYS - 1 ) + +struct appleir +{ + struct input_dev *dev; + uint8_t *data; + dma_addr_t dma_buf; + struct usb_device *usbdev; + struct urb *urb; + int timer_initted; + struct timer_list key_up_timer; + int current_key; + char phys[32]; +}; + + +static struct usb_device_id appleir_ids[] = { + {USB_DEVICE (USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IR),.driver_info = 0}, + {USB_DEVICE (USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IR2),.driver_info = 0}, + {} +}; + +MODULE_DEVICE_TABLE (usb, appleir_ids); + + +/* I have two devices both of which report the following */ +/* 25 87 ee 83 0a + */ +/* 25 87 ee 83 0c - */ +/* 25 87 ee 83 09 << */ +/* 25 87 ee 83 06 >> */ +/* 25 87 ee 83 05 >" */ +/* 25 87 ee 83 03 menu */ +/* 26 00 00 00 00 for key repeat*/ + +/* Thomas Glanzmann reports the following responses */ +/* 25 87 ee ca 0b + */ +/* 25 87 ee ca 0d - */ +/* 25 87 ee ca 08 << */ +/* 25 87 ee ca 07 >> */ +/* 25 87 ee ca 04 >" */ +/* 25 87 ee ca 02 menu */ +/* 26 00 00 00 00 for key repeat*/ +/* He also observes the following event sometimes */ +/* sent after a key is release, which I interpret */ +/* as a flat battery message */ +/* 25 87 e0 ca 06 flat battery */ + +/* Alexandre Karpenko reports the following responses for Device ID 0x8242 */ +/* 25 87 ee 47 0b + */ +/* 25 87 ee 47 0d - */ +/* 25 87 ee 47 08 << */ +/* 25 87 ee 47 07 >> */ +/* 25 87 ee 47 04 >" */ +/* 25 87 ee 47 02 menu */ +/* 26 87 ee 47 ** for key repeat (** is the code of the key being held) */ + + +static int keymap[MAX_KEYS] = { + KEY_RESERVED, KEY_MENU, + KEY_PLAYPAUSE, KEY_FORWARD, + KEY_BACK, KEY_VOLUMEUP, + KEY_VOLUMEDOWN, KEY_RESERVED +}; + +static void +dump_packet (struct appleir *appleir, char *msg, uint8_t * data, int len) +{ + int i; + + printk (KERN_ERR "appleir: %s (%d bytes)", msg, len); + + for (i = 0; i < len; ++i) + { + printk (" %02x", data[i]); + } + + printk ("\n"); +} + + +static void +key_up (struct appleir *appleir, int key) +{ + //printk (KERN_ERR "key %d up\n", key); + input_report_key (appleir->dev, key, 0); + input_sync (appleir->dev); +} + +static void +key_down (struct appleir *appleir, int key) +{ + //printk (KERN_ERR "key %d down\n", key); + input_report_key (appleir->dev, key, 1); + input_sync (appleir->dev); +} + +static void +battery_flat (struct appleir *appleir) +{ + printk (KERN_ERR "appleir: possible flat battery?\n"); +} + +static void +key_up_tick (unsigned long data) +{ + struct appleir *appleir = (struct appleir *) data; + + if (appleir->current_key) + { + key_up (appleir, appleir->current_key); + appleir->current_key = 0; + } +} + +static void +new_data (struct appleir *appleir, uint8_t * data, int len) +{ + static const uint8_t keydown[] = { 0x25, 0x87, 0xee }; + static const uint8_t keyrepeat[] = { 0x26 }; + static const uint8_t flatbattery[] = { 0x25, 0x87, 0xe0 }; + +#ifdef DUMP_PACKETS + dump_packet (appleir, "received", data, len); +#endif + + if (len != 5) + return; + + if (!memcmp (data, keydown, sizeof (keydown))) + { + /*If we already have a key down, take it up before marking */ + /*this one down */ + if (appleir->current_key) + key_up (appleir, appleir->current_key); + appleir->current_key = keymap[(data[4] >> 1) & MAX_KEYS_MASK]; + + key_down (appleir, appleir->current_key); + /*remote doesn't do key up, either pull them up, in the test */ + /*above, or here set a timer which pulls them up after 1/8 s */ + mod_timer (&appleir->key_up_timer, jiffies + HZ / 8); + + return; + } + + if (!memcmp (data, keyrepeat, sizeof (keyrepeat))) + { + key_down (appleir, appleir->current_key); + /*remote doesn't do key up, either pull them up, in the test */ + /*above, or here set a timer which pulls them up after 1/8 s */ + mod_timer (&appleir->key_up_timer, jiffies + HZ / 8); + return; + } + + if (!memcmp (data, flatbattery, sizeof (flatbattery))) + { + battery_flat (appleir); + /*Fall through */ + } + + dump_packet (appleir, "unknown packet", data, len); +} + +static void +appleir_urb (struct urb *urb) +{ + struct appleir *appleir = urb->context; + int retval; + + switch (urb->status) + { + case 0: + new_data (appleir, urb->transfer_buffer, urb->actual_length); + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* this urb is terminated, clean up */ + dbg ("%s - urb shutting down with status: %d", __FUNCTION__, + urb->status); + return; + default: + dbg ("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); + } + + retval = usb_submit_urb (urb, GFP_ATOMIC); + if (retval) + err ("%s - usb_submit_urb failed with result %d", __FUNCTION__, retval); +} + + +static int +appleir_open (struct input_dev *dev) +{ + struct appleir *appleir = (struct appleir *)input_get_drvdata(dev); + + if (usb_submit_urb (appleir->urb, GFP_KERNEL)) + return -EIO; + + return 0; +} + +static void +appleir_close (struct input_dev *dev) +{ + struct appleir *appleir = (struct appleir *)input_get_drvdata(dev); + usb_kill_urb (appleir->urb); + del_timer_sync (&appleir->key_up_timer); +} + + + + +static int +appleir_probe (struct usb_interface *intf, const struct usb_device_id *id) +{ + struct usb_device *dev = interface_to_usbdev (intf); + struct usb_endpoint_descriptor *endpoint; + struct appleir *appleir = NULL; + struct input_dev *input_dev; + int i; + + appleir = kzalloc (sizeof (struct appleir), GFP_KERNEL); + if (!appleir) + goto fail; + + memset (appleir, 0, sizeof (struct appleir)); + + + appleir->data = + usb_buffer_alloc (dev, URB_SIZE, GFP_KERNEL, &appleir->dma_buf); + if (!appleir->data) + goto fail; + + appleir->urb = usb_alloc_urb (0, GFP_KERNEL); + if (!appleir->urb) + goto fail; + + appleir->usbdev = dev; + + input_dev = input_allocate_device (); + if (!input_dev) + goto fail; + + appleir->dev = input_dev; + + + usb_make_path (dev, appleir->phys, sizeof (appleir->phys)); + strlcpy (appleir->phys, "/input0", sizeof (appleir->phys)); + + input_dev->name = "Apple Mac mini infrared remote control driver"; + input_dev->phys = appleir->phys; + usb_to_input_id (dev, &input_dev->id); + input_dev->dev.parent = &intf->dev; + input_set_drvdata(input_dev, appleir); + + input_dev->evbit[0] = BIT (EV_KEY) | BIT (EV_REP); + input_dev->ledbit[0] = 0; + + for (i = 0; i < MAX_KEYS; i++) + { + set_bit (keymap[i], input_dev->keybit); + } + + clear_bit (0, input_dev->keybit); + + input_dev->open = appleir_open; + input_dev->close = appleir_close; + + endpoint = &intf->cur_altsetting->endpoint[0].desc; + + usb_fill_int_urb (appleir->urb, dev, + usb_rcvintpipe (dev, endpoint->bEndpointAddress), + appleir->data, 8, + appleir_urb, appleir, endpoint->bInterval); + + appleir->urb->transfer_dma = appleir->dma_buf; + appleir->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + usb_set_intfdata (intf, appleir); + + init_timer (&appleir->key_up_timer); + + appleir->key_up_timer.function = key_up_tick; + appleir->key_up_timer.data = (unsigned long) appleir; + + appleir->timer_initted++; + + input_register_device (appleir->dev); + + return 0; + +fail: + + if (appleir) + { + + + if (appleir->data) + usb_buffer_free (dev, URB_SIZE, appleir->data, appleir->dma_buf); + + if (appleir->timer_initted) + del_timer_sync (&appleir->key_up_timer); + + if (appleir->dev) + input_free_device (appleir->dev); + + kfree (appleir); + } + + return -ENOMEM; +} + +static void +appleir_disconnect (struct usb_interface *intf) +{ + struct appleir *appleir = usb_get_intfdata (intf); + + usb_set_intfdata (intf, NULL); + if (appleir) + { + input_unregister_device (appleir->dev); + if (appleir->timer_initted) + del_timer_sync (&appleir->key_up_timer); + usb_kill_urb (appleir->urb); + usb_free_urb (appleir->urb); + usb_buffer_free (interface_to_usbdev (intf), URB_SIZE, appleir->data, + appleir->dma_buf); + kfree (appleir); + } +} + +static struct usb_driver appleir_driver = { + .name = "appleir", + .probe = appleir_probe, + .disconnect = appleir_disconnect, + .id_table = appleir_ids, +}; + +static int __init +appleir_init (void) +{ + int retval; + retval = usb_register (&appleir_driver); + if (retval) + goto out; + info (DRIVER_VERSION ":" DRIVER_DESC); +out: + return retval; +} + +static void __exit +appleir_exit (void) +{ + usb_deregister (&appleir_driver); +} + +module_init (appleir_init); +module_exit (appleir_exit); --- linux-2.6.28.orig/ubuntu/misc/BOM +++ linux-2.6.28/ubuntu/misc/BOM @@ -0,0 +1,3 @@ +Module: dm-bbr +Downloaded from: http://dev.gentoo.org/~dsd/gentoo-sources/patches-2.6.25-2.htm +Comments: Changes in md headers for 2.6.26 required some munging. --- linux-2.6.28.orig/ubuntu/misc/acerhk.h +++ linux-2.6.28/ubuntu/misc/acerhk.h @@ -0,0 +1,91 @@ +#ifndef __ACERHK_H__ +#define __ACERHK_H__ + +#include + +#define ACERHK_MINOR MISC_DYNAMIC_MINOR + +#define ACERHK_GET_KEYCOUNT _IOR('p', 0x01, char) /* Get number of cached key presses */ +#define ACERHK_GET_KEYID _IOR('p', 0x02, char) /* Get first key in queue */ +#define ACERHK_CONNECT _IO('p', 0x03) /* ? */ +#define ACERHK_DISCONNECT _IO('p', 0x04) /* ? */ +#define ACERHK_GET_THERMAL_EVENT _IOR('p', 0x05, short) /* ? */ +#define ACERHK_MAIL_LED_OFF _IO('p', 0x10) /* switch mail LED off */ +#define ACERHK_MAIL_LED_ON _IO('p', 0x11) /* switch mail LED on (blinking) */ +#define ACERHK_START_POLLING _IO('p', 0x12) /* poll keys in kernel, send real key events */ +#define ACERHK_STOP_POLLING _IO('p', 0x13) /* stop key polling in kernel */ +#define ACERHK_GET_KEY_MAP _IOR('p', 0x20, int) /* Get mapping of key names to key events, */ +#define ACERHK_SET_KEY_MAP _IOW('p', 0x21, int) /* Set mapping of key names to key events */ + +/* all possible keys (known to me) */ +typedef enum e_key_names { + k_none = 0, + k_help = 1, /* Fn+F1 */ + k_setup = 2, /* Fn+F2 */ + k_p1 = 3, + k_p2 = 4, + k_p3 = 5, + k_www = 6, + k_mail = 7, + k_wireless = 8, + k_power = 9, /* Fn+F3 */ + k_mute = 10, /* Fn+F8 */ + k_volup = 11, /* Fn+Up */ + k_voldn = 12, /* Fn+Down */ + k_res = 13, /* resolution change on Medion MD 40100 */ + k_close = 14, /* if lid is closed in tablet mode */ + k_open = 15, /* if lid is opend in tablet mode */ + k_wireless2 = 16, /* second wireless button on TM 243LC */ + k_play = 17, /* Play/Pause found on AOpen */ + k_stop = 18, /* Stop/Eject found on AOpen */ + k_prev = 19, /* Prev found on AOpen */ + k_next = 20, /* Next found on AOpen */ + k_display = 21 /* Change internal/external display on MD 42200 */ +} t_key_names; +#define NR_KEY_NAMES 22 +typedef unsigned int t_map_name2event[NR_KEY_NAMES]; + +#ifdef __KERNEL__ + +/* available features */ +#define TM_F_WLAN_EC1 0x00000010 +#define TM_F_BLUE_EC1 0x00000020 +#define TM_F_WLAN_EC2 0x00000040 +#define TM_F_BLUE_EC2 0x00000080 +#define TM_F_MUTE_LED_EC 0x00001000 +#define TM_F_MAIL_LED 0x00010000 +#define TM_F_MAIL_LED_EC 0x00020000 +#define TM_F_MAIL_LED_EC2 0x00040000 +#define TM_F_MAIL_LED_EC3 0x00080000 + +#define TM_F_CONNECT 0x00100000 +#define TM_F_THERMAL 0x00200000 +#define TM_F_PBUTTON 0x00400000 +#define TM_F_WBUTTON 0x00800000 + +typedef enum acer_type { + TM_unknown, + /* 200, 210, 520, 600 and 730 series, Medion MD42200 */ + TM_old, + /* C100, C110, 220, 230, 240, 260, 350, 360, 610, 620, 630, 740 series + Medion MD40100, Aspire 1600, FS Amilo */ + TM_new, + /* Aspire 13xx, 14xx, 1700, TM 290, 650, 660, 800 */ + TM_dritek +} t_acer_type; + +struct register_buffer { + unsigned int eax; + unsigned int ebx; + unsigned int ecx; + unsigned int edx; + unsigned int edi; + unsigned int esi; + unsigned int ebp; +}; + +typedef asmlinkage void (*bios_call) (struct register_buffer *); + +#endif + +#endif --- linux-2.6.28.orig/ubuntu/misc/media/snd-bt-sco.c +++ linux-2.6.28/ubuntu/misc/media/snd-bt-sco.c @@ -0,0 +1,1231 @@ +/* + * Bluetooth SCO soundcard + * Copyright (c) 2003, 2004 by Jonathan Paisley + * + * Based on dummy.c which is + * Copyright (c) by Jaroslav Kysela + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + * + */ + + +/* note: defining these two independently is not tested, + * thus not recommended + */ + +/* enable dynamic compression */ +#define DYNAMIC_COMPRESSION +/* enable automatic endianness fixup */ +#define AUTO_FIXUP_BYTESHIFT + + +#ifdef DYNAMIC_COMPRESSION +/* Autoadjust mic at most this often in 1/8000s */ +#define GRABSAMPLES 400 +/* Maximum push for the mike 16= 1:1 - default 20:1 = 320 */ +#define COMPRESSION_MAX_16 320 +/* Minimum push for the mike 1= 1:16 */ +#define COMPRESSION_MIN_16 1 +#endif + +#define chip_t snd_card_bt_sco_t + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// this was ostensibly for newer kernels but fails on 2.6.19.2 +#if 0 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) +#include +#endif +#endif +#include +#include +#include +#include +#include +#define SNDRV_GET_ID +#include + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15) +#include +#else +#define mutex semaphore +#define mutex_init init_MUTEX +#define mutex_lock down +#define mutex_unlock up +#endif + +#ifndef SNDRV_HWDEP_IFACE_BLUETOOTH +#define SNDRV_HWDEP_IFACE_BLUETOOTH (SNDRV_HWDEP_IFACE_EMUX_WAVETABLE + 1) +#endif + +#ifndef SNDRV_HWDEP_IFACE_BT_SCO +#define SNDRV_HWDEP_IFACE_BT_SCO (SNDRV_HWDEP_IFACE_BLUETOOTH + 1) +#endif + +#define SNDRV_BT_SCO_IOCTL_SET_SCO_SOCKET _IOW ('H', 0x10, int) +#define SNDRV_BT_SCO_IOCTL_REQ_INFO _IO ('H', 0x11) + +static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */ + +#define MOD_REVISION "$Revision: 1.19 $"; +static char *mod_revision = MOD_REVISION; + +MODULE_AUTHOR("Jonathan Paisley "); +MODULE_DESCRIPTION("Bluetooth SCO Headset Soundcard"); +MODULE_VERSION(MOD_REVISION); +MODULE_LICENSE("GPL"); +MODULE_SUPPORTED_DEVICE("{{ALSA,Bluetooth SCO Soundcard}}"); + +module_param_array(index, int, NULL, 0444); +MODULE_PARM_DESC(index, "Index value for Bluetooth SCO Headset Soundcard."); + +#undef dprintk +#if 1 +#define dprintk(fmt...) printk(KERN_INFO "snd-bt-sco: " fmt) +#else +#define dprintk(fmt...) do {} while(0) +#endif + +#define MAX_BUFFER_SIZE (32*1024) + +#define MIXER_ADDR_MASTER 0 +#define MIXER_ADDR_MIC 1 +#define MIXER_ADDR_LAST 1 + +#define MIXER_MASK_MASTER 1 +#define MIXER_MASK_MIC 2 + +#define MIXER_MIN_VOLUME 1 +#define MIXER_MAX_VOLUME 15 + +struct snd_card_bt_sco_pcm; + +typedef struct snd_card_bt_sco_info { + int mixer_volume[MIXER_ADDR_LAST + 1]; + int playback_count, capture_count; +} snd_card_bt_sco_info_t; + +typedef struct snd_card_bt_sco { + struct snd_card *card; + spinlock_t mixer_lock; + int mixer_volume[MIXER_ADDR_LAST + 1]; +#ifdef DYNAMIC_COMPRESSION + struct snd_kcontrol *mixer_controls[MIXER_ADDR_LAST + 2 + 1]; /* also loopback and agc */ +#else + struct snd_kcontrol *mixer_controls[MIXER_ADDR_LAST + 2 ]; /* also loopback */ +#endif + volatile int loopback; +#ifdef DYNAMIC_COMPRESSION + volatile int agc; +#endif + atomic_t playback_count, capture_count; + volatile int count_changed; + spinlock_t count_changed_lock; + + spinlock_t mixer_changed_lock; + volatile int mixer_changed; + wait_queue_head_t hwdep_wait; + + struct task_struct *thread; + + struct mutex thread_sem; + + volatile struct socket *sco_sock; + struct mutex sock_sem; + wait_queue_head_t wait; + + struct mutex playback_sem; + struct snd_card_bt_sco_pcm *playback; + struct mutex capture_sem; + struct snd_card_bt_sco_pcm *capture; +} snd_card_bt_sco_t; + +typedef struct snd_card_bt_sco_pcm { + snd_card_bt_sco_t *bt_sco; + spinlock_t lock; + unsigned int pcm_size; + unsigned int pcm_count; + unsigned int pcm_bps; /* bytes per second */ + unsigned int pcm_irq_pos; /* IRQ position */ + unsigned int pcm_buf_pos; /* position in buffer */ + struct snd_pcm_substream *substream; +} snd_card_bt_sco_pcm_t; + +static struct snd_card *snd_bt_sco_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; + +static int snd_card_bt_sco_playback_trigger(struct snd_pcm_substream * + substream, int cmd) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + snd_card_bt_sco_pcm_t *bspcm = runtime->private_data; + snd_card_bt_sco_t *bt_sco = snd_pcm_substream_chip(substream); + + dprintk("playback_trigger %d\n", cmd); + + if (cmd == SNDRV_PCM_TRIGGER_START) { + bt_sco->playback = bspcm; + dprintk("setting playback to bspcm\n"); + } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { + bt_sco->playback = NULL; + dprintk("setting playback to NULL\n"); + } else { + return -EINVAL; + } + return 0; +} + +static int snd_card_bt_sco_capture_trigger(struct snd_pcm_substream * + substream, int cmd) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + snd_card_bt_sco_pcm_t *bspcm = runtime->private_data; + snd_card_bt_sco_t *bt_sco = snd_pcm_substream_chip(substream); + + dprintk("capture_trigger %d\n", cmd); + + if (cmd == SNDRV_PCM_TRIGGER_START) { + bt_sco->capture = bspcm; + dprintk("setting capture to bspcm\n"); + } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { + bt_sco->capture = NULL; + dprintk("setting capture to NULL\n"); + } else { + return -EINVAL; + } + return 0; +} + +static int snd_card_bt_sco_pcm_prepare(struct snd_pcm_substream * substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + snd_card_bt_sco_pcm_t *bspcm = runtime->private_data; + unsigned int bps; + + bps = runtime->rate * runtime->channels; + bps *= snd_pcm_format_width(runtime->format); + bps /= 8; + if (bps <= 0) + return -EINVAL; + bspcm->pcm_bps = bps; + bspcm->pcm_size = snd_pcm_lib_buffer_bytes(substream); + bspcm->pcm_count = snd_pcm_lib_period_bytes(substream); + bspcm->pcm_irq_pos = 0; + bspcm->pcm_buf_pos = 0; + dprintk("prepare ok bps: %d size: %d count: %d\n", + bspcm->pcm_bps, bspcm->pcm_size, bspcm->pcm_count); + return 0; +} + +static int snd_card_bt_sco_playback_prepare(struct snd_pcm_substream * substream) +{ + return snd_card_bt_sco_pcm_prepare(substream); +} + +static int snd_card_bt_sco_capture_prepare(struct snd_pcm_substream * substream) +{ + dprintk("capture_prepare\n"); + return snd_card_bt_sco_pcm_prepare(substream); +} + +static void snd_card_bt_sco_pcm_receive(snd_card_bt_sco_pcm_t * bspcm, + unsigned char *data, unsigned int len) +{ + unsigned long flags; + unsigned int oldptr; + + spin_lock_irqsave(&bspcm->lock, flags); + oldptr = bspcm->pcm_buf_pos; + bspcm->pcm_irq_pos += len; + bspcm->pcm_buf_pos += len; + bspcm->pcm_buf_pos %= bspcm->pcm_size; + spin_unlock_irqrestore(&bspcm->lock, flags); + /* copy a data chunk */ + if (oldptr + len > bspcm->pcm_size) { + unsigned int cnt = bspcm->pcm_size - oldptr; + memcpy(bspcm->substream->runtime->dma_area + oldptr, data, cnt); + memcpy(bspcm->substream->runtime->dma_area, data + cnt, + len - cnt); + } else { + memcpy(bspcm->substream->runtime->dma_area + oldptr, data, len); + } + /* update the pointer, call callback if necessary */ + spin_lock_irqsave(&bspcm->lock, flags); + if (bspcm->pcm_irq_pos >= bspcm->pcm_count) { + bspcm->pcm_irq_pos %= bspcm->pcm_count; + spin_unlock_irqrestore(&bspcm->lock, flags); + snd_pcm_period_elapsed(bspcm->substream); + } else + spin_unlock_irqrestore(&bspcm->lock, flags); + +} + +static void snd_card_bt_sco_pcm_send(snd_card_bt_sco_pcm_t * bspcm, + unsigned char *data, unsigned int len) +{ + unsigned long flags; + unsigned int oldptr; + + spin_lock_irqsave(&bspcm->lock, flags); + oldptr = bspcm->pcm_buf_pos; + bspcm->pcm_irq_pos += len; + bspcm->pcm_buf_pos += len; + bspcm->pcm_buf_pos %= bspcm->pcm_size; + spin_unlock_irqrestore(&bspcm->lock, flags); + /* copy a data chunk */ + if (oldptr + len > bspcm->pcm_size) { + unsigned int cnt = bspcm->pcm_size - oldptr; + memcpy(data, bspcm->substream->runtime->dma_area + oldptr, cnt); + memcpy(data + cnt, bspcm->substream->runtime->dma_area, + len - cnt); + } else { + memcpy(data, bspcm->substream->runtime->dma_area + oldptr, len); + } + /* update the pointer, call callback if necessary */ + spin_lock_irqsave(&bspcm->lock, flags); + if (bspcm->pcm_irq_pos >= bspcm->pcm_count) { + bspcm->pcm_irq_pos %= bspcm->pcm_count; + spin_unlock_irqrestore(&bspcm->lock, flags); + snd_pcm_period_elapsed(bspcm->substream); + } else + spin_unlock_irqrestore(&bspcm->lock, flags); +} + +static snd_pcm_uframes_t +snd_card_bt_sco_playback_pointer(struct snd_pcm_substream * substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + snd_card_bt_sco_pcm_t *bspcm = runtime->private_data; + + return bytes_to_frames(runtime, bspcm->pcm_buf_pos); +} + +static snd_pcm_uframes_t +snd_card_bt_sco_capture_pointer(struct snd_pcm_substream * substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + snd_card_bt_sco_pcm_t *bspcm = runtime->private_data; + + return bytes_to_frames(runtime, bspcm->pcm_buf_pos); +} + +static struct snd_pcm_hardware snd_card_bt_sco_playback = { + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP_VALID), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = SNDRV_PCM_RATE_8000, + .rate_min = 8000, + .rate_max = 8000, + .channels_min = 1, + .channels_max = 1, + .buffer_bytes_max = MAX_BUFFER_SIZE, + .period_bytes_min = 24, + .period_bytes_max = MAX_BUFFER_SIZE, + .periods_min = 1, + .periods_max = 4 * 8000 / 24, + .fifo_size = 0, +}; + +static struct snd_pcm_hardware snd_card_bt_sco_capture = { + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP_VALID), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = SNDRV_PCM_RATE_8000, + .rate_min = 8000, + .rate_max = 8000, + .channels_min = 1, + .channels_max = 1, + .buffer_bytes_max = MAX_BUFFER_SIZE, + .period_bytes_min = 24, + .period_bytes_max = MAX_BUFFER_SIZE, + .periods_min = 1, + .periods_max = 4 * 8000 / 24, + .fifo_size = 0, +}; + +static void snd_card_bt_sco_runtime_free(struct snd_pcm_runtime * runtime) +{ + snd_card_bt_sco_pcm_t *bspcm = runtime->private_data; + kfree(bspcm); +} + +static int snd_card_bt_sco_playback_open(struct snd_pcm_substream * substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + snd_card_bt_sco_pcm_t *bspcm; + snd_card_bt_sco_t *bt_sco = snd_pcm_substream_chip(substream); + + dprintk("playback_open\n"); + + bspcm = kmalloc(sizeof(*bspcm), GFP_KERNEL); + if (bspcm == NULL) + return -ENOMEM; + memset(bspcm, 0, sizeof(*bspcm)); + if ((runtime->dma_area = + snd_malloc_pages(MAX_BUFFER_SIZE, GFP_KERNEL)) == NULL) { + kfree(bspcm); + return -ENOMEM; + } + runtime->dma_bytes = MAX_BUFFER_SIZE; + spin_lock_init(&bspcm->lock); + bspcm->substream = substream; + runtime->private_data = bspcm; + runtime->private_free = snd_card_bt_sco_runtime_free; + runtime->hw = snd_card_bt_sco_playback; + + atomic_inc(&bt_sco->playback_count); + spin_lock_irq(&bt_sco->count_changed_lock); + bt_sco->count_changed = 1; + spin_unlock_irq(&bt_sco->count_changed_lock); + wake_up(&bt_sco->hwdep_wait); + + return 0; +} + +static int snd_card_bt_sco_capture_open(struct snd_pcm_substream * substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + snd_card_bt_sco_pcm_t *bspcm; + snd_card_bt_sco_t *bt_sco = snd_pcm_substream_chip(substream); + + dprintk("capture_open\n"); + + bspcm = kmalloc(sizeof(*bspcm), GFP_KERNEL); + if (bspcm == NULL) + return -ENOMEM; + memset(bspcm, 0, sizeof(*bspcm)); + if ((runtime->dma_area = + snd_malloc_pages(MAX_BUFFER_SIZE, GFP_KERNEL)) == NULL) { + kfree(bspcm); + return -ENOMEM; + } + runtime->dma_bytes = MAX_BUFFER_SIZE; + memset(runtime->dma_area, 0, runtime->dma_bytes); + spin_lock_init(&bspcm->lock); + bspcm->substream = substream; + runtime->private_data = bspcm; + runtime->private_free = snd_card_bt_sco_runtime_free; + runtime->hw = snd_card_bt_sco_capture; + + atomic_inc(&bt_sco->capture_count); + spin_lock_irq(&bt_sco->count_changed_lock); + bt_sco->count_changed = 1; + spin_unlock_irq(&bt_sco->count_changed_lock); + wake_up(&bt_sco->hwdep_wait); + + return 0; +} + +static int snd_card_bt_sco_playback_close(struct snd_pcm_substream * substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + snd_card_bt_sco_t *bt_sco = snd_pcm_substream_chip(substream); + + snd_assert(bt_sco->playback == NULL,; + ); + + /* Ensure any references to this in our thread have finished */ + mutex_lock(&bt_sco->playback_sem); + mutex_unlock(&bt_sco->playback_sem); + + atomic_dec(&bt_sco->playback_count); + spin_lock_irq(&bt_sco->count_changed_lock); + bt_sco->count_changed = 1; + spin_unlock_irq(&bt_sco->count_changed_lock); + wake_up(&bt_sco->hwdep_wait); + + snd_free_pages(runtime->dma_area, runtime->dma_bytes); + return 0; +} + +static int snd_card_bt_sco_capture_close(struct snd_pcm_substream * substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_card_bt_sco *bt_sco = + (struct snd_card_bt_sco *)substream->private_data; + + snd_assert(bt_sco->capture == NULL,; + ); + + /* Ensure any references to this in our thread have finished */ + mutex_lock(&bt_sco->capture_sem); + mutex_unlock(&bt_sco->capture_sem); + + atomic_dec(&bt_sco->capture_count); + spin_lock_irq(&bt_sco->count_changed_lock); + bt_sco->count_changed = 1; + spin_unlock_irq(&bt_sco->count_changed_lock); + wake_up(&bt_sco->hwdep_wait); + + snd_free_pages(runtime->dma_area, runtime->dma_bytes); + return 0; +} + +static struct snd_pcm_ops snd_card_bt_sco_playback_ops = { + .open = snd_card_bt_sco_playback_open, + .close = snd_card_bt_sco_playback_close, + .ioctl = snd_pcm_lib_ioctl, + .prepare = snd_card_bt_sco_playback_prepare, + .trigger = snd_card_bt_sco_playback_trigger, + .pointer = snd_card_bt_sco_playback_pointer, +}; + +static struct snd_pcm_ops snd_card_bt_sco_capture_ops = { + .open = snd_card_bt_sco_capture_open, + .close = snd_card_bt_sco_capture_close, + .ioctl = snd_pcm_lib_ioctl, + .prepare = snd_card_bt_sco_capture_prepare, + .trigger = snd_card_bt_sco_capture_trigger, + .pointer = snd_card_bt_sco_capture_pointer, +}; + +static int __init snd_card_bt_sco_pcm(snd_card_bt_sco_t * bt_sco) +{ + struct snd_pcm *pcm; + int err; + + if ((err = + snd_pcm_new(bt_sco->card, "Bluetooth SCO PCM", 0, 1, 1, &pcm)) < 0) + return err; + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, + &snd_card_bt_sco_playback_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, + &snd_card_bt_sco_capture_ops); + pcm->private_data = bt_sco; + pcm->info_flags = 0; + strcpy(pcm->name, "BT SCO PCM"); + return 0; +} + +#define BT_SCO_VOLUME(xname, xindex, addr) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ + .info = snd_bt_sco_volume_info, \ + .get = snd_bt_sco_volume_get, .put = snd_bt_sco_volume_put, \ + .private_value = addr } + +static int snd_bt_sco_volume_info(struct snd_kcontrol * kcontrol, + struct snd_ctl_elem_info * uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = MIXER_MIN_VOLUME; + uinfo->value.integer.max = MIXER_MAX_VOLUME; + return 0; +} + +static int snd_bt_sco_volume_get(struct snd_kcontrol * kcontrol, + struct snd_ctl_elem_value * ucontrol) +{ + snd_card_bt_sco_t *bt_sco = snd_kcontrol_chip(kcontrol); + unsigned long flags; + int addr = kcontrol->private_value; + + spin_lock_irqsave(&bt_sco->mixer_lock, flags); + ucontrol->value.integer.value[0] = bt_sco->mixer_volume[addr]; + spin_unlock_irqrestore(&bt_sco->mixer_lock, flags); + return 0; +} + +static int snd_bt_sco_volume_put(struct snd_kcontrol * kcontrol, + struct snd_ctl_elem_value * ucontrol) +{ + snd_card_bt_sco_t *bt_sco = snd_kcontrol_chip(kcontrol); + unsigned long flags; + int changed, addr = kcontrol->private_value; + int vol; + + vol = ucontrol->value.integer.value[0]; + if (vol < MIXER_MIN_VOLUME) + vol = MIXER_MIN_VOLUME; + if (vol > MIXER_MAX_VOLUME) + vol = MIXER_MAX_VOLUME; + spin_lock_irqsave(&bt_sco->mixer_lock, flags); + changed = bt_sco->mixer_volume[addr] != vol; + bt_sco->mixer_volume[addr] = vol; + spin_unlock_irqrestore(&bt_sco->mixer_lock, flags); + if (changed) { + spin_lock_irqsave(&bt_sco->mixer_changed_lock, flags); + bt_sco->mixer_changed = 1; + spin_unlock_irqrestore(&bt_sco->mixer_changed_lock, flags); + wake_up(&bt_sco->hwdep_wait); + } + return changed; +} + +static int snd_bt_sco_boolean_info(struct snd_kcontrol * kcontrol, + struct snd_ctl_elem_info * uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +static int snd_bt_sco_loopback_get(struct snd_kcontrol * kcontrol, + struct snd_ctl_elem_value * ucontrol) +{ + snd_card_bt_sco_t *bt_sco = snd_kcontrol_chip(kcontrol); + unsigned long flags; + + spin_lock_irqsave(&bt_sco->mixer_lock, flags); + ucontrol->value.integer.value[0] = bt_sco->loopback; + spin_unlock_irqrestore(&bt_sco->mixer_lock, flags); + return 0; +} + +static int snd_bt_sco_loopback_put(struct snd_kcontrol * kcontrol, + struct snd_ctl_elem_value * ucontrol) +{ + snd_card_bt_sco_t *bt_sco = snd_kcontrol_chip(kcontrol); + unsigned long flags; + int changed; + int loopback; + + loopback = !!ucontrol->value.integer.value[0]; + + spin_lock_irqsave(&bt_sco->mixer_lock, flags); + changed = bt_sco->loopback != loopback; + bt_sco->loopback = loopback; + spin_unlock_irqrestore(&bt_sco->mixer_lock, flags); + return changed; +} + +#ifdef DYNAMIC_COMPRESSION +static int snd_bt_sco_agc_get(struct snd_kcontrol * kcontrol, + struct snd_ctl_elem_value * ucontrol) +{ + snd_card_bt_sco_t *bt_sco = snd_kcontrol_chip(kcontrol); + unsigned long flags; + + spin_lock_irqsave(&bt_sco->mixer_lock, flags); + ucontrol->value.integer.value[0] = bt_sco->agc; + spin_unlock_irqrestore(&bt_sco->mixer_lock, flags); + return 0; +} + +static int snd_bt_sco_agc_put(struct snd_kcontrol * kcontrol, + struct snd_ctl_elem_value * ucontrol) +{ + snd_card_bt_sco_t *bt_sco = snd_kcontrol_chip(kcontrol); + unsigned long flags; + int changed; + int agc; + + agc = !!ucontrol->value.integer.value[0]; + + spin_lock_irqsave(&bt_sco->mixer_lock, flags); + changed = bt_sco->agc != agc; + bt_sco->agc = agc; + spin_unlock_irqrestore(&bt_sco->mixer_lock, flags); + return changed; +} +#endif + +#define BT_SCO_CONTROLS (sizeof(snd_bt_sco_controls)/sizeof(struct snd_kcontrol_new)) + +static struct snd_kcontrol_new snd_bt_sco_controls[] = { + BT_SCO_VOLUME("Master Volume", 0, MIXER_ADDR_MASTER), + BT_SCO_VOLUME("Mic Volume", 0, MIXER_ADDR_MIC), + {.iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Loopback Switch", + .index = 0, + .info = snd_bt_sco_boolean_info, + .get = snd_bt_sco_loopback_get, + .put = snd_bt_sco_loopback_put, + } +#ifdef DYNAMIC_COMPRESSION + , + {.iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "AGC Switch", + .index = 0, + .info = snd_bt_sco_boolean_info, + .get = snd_bt_sco_agc_get, + .put = snd_bt_sco_agc_put, + } +#endif +}; + +int __init snd_card_bt_sco_new_mixer(snd_card_bt_sco_t * bt_sco) +{ + struct snd_card *card = bt_sco->card; + + unsigned int idx; + int err; + + snd_assert(bt_sco != NULL, return -EINVAL); + spin_lock_init(&bt_sco->mixer_lock); + strcpy(card->mixername, "BT Headset Mixer"); + + for (idx = 0; idx < BT_SCO_CONTROLS; idx++) { + bt_sco->mixer_controls[idx] = + snd_ctl_new1(&snd_bt_sco_controls[idx], bt_sco); + + if ((err = snd_ctl_add(card, bt_sco->mixer_controls[idx])) < 0) + return err; + } + return 0; +} + +static int snd_card_bt_open(struct snd_hwdep * hw, struct file *file) +{ + return 0; +} + +static int snd_card_bt_release(struct snd_hwdep * hw, struct file *file) +{ + return 0; +} + +static int snd_card_bt_ioctl(struct snd_hwdep * hw, struct file *file, + unsigned int cmd, unsigned long arg) +{ + snd_card_bt_sco_t *bt_sco = hw->card->private_data; + struct socket *sock; + int err = -ENOTTY; + int fd = arg; + + switch (cmd) { + case SNDRV_BT_SCO_IOCTL_SET_SCO_SOCKET: + err = 0; + /* Interrupt any socket operations, so that we may + * change the socket */ + mutex_lock(&bt_sco->sock_sem); + kthread_stop(bt_sco->thread); + if (bt_sco->sco_sock) { + dprintk("Disposing of previous socket count %d\n", + file_count(bt_sco->sco_sock->file)); + /* Extra brackets needed here since sockfd_put is a poorly implemented macro */ + sockfd_put(((struct socket *)bt_sco->sco_sock)); + + bt_sco->sco_sock = NULL; + } + + if (fd >= 0) { + err = -EINVAL; + sock = sockfd_lookup(fd, &err); + if (sock) { + if (sock->sk->sk_family == PF_BLUETOOTH && + sock->sk->sk_protocol == BTPROTO_SCO) { + bt_sco->sco_sock = sock; + wake_up(&bt_sco->wait); + err = 0; + } else { + dprintk + ("Not a bluetooth SCO socket %d:%d\n", + sock->sk->sk_family, + sock->sk->sk_protocol); + sockfd_put(sock); + } + } + } + mutex_unlock(&bt_sco->sock_sem); + break; + case SNDRV_BT_SCO_IOCTL_REQ_INFO: + spin_lock_irq(&bt_sco->count_changed_lock); + bt_sco->count_changed = 1; + spin_unlock_irq(&bt_sco->count_changed_lock); + wake_up(&bt_sco->hwdep_wait); + break; + } + return err; +} + +static long snd_card_bt_write(struct snd_hwdep * hw, const char *buf, long count, + loff_t * offset) +{ + snd_card_bt_sco_t *bt_sco = hw->card->private_data; + int mixer_volume[MIXER_ADDR_LAST + 1]; + int retval; + int i; + + if (count != sizeof(mixer_volume)) + return -EINVAL; + + if (copy_from_user(mixer_volume, buf, sizeof(mixer_volume))) + return -EFAULT; + + retval = sizeof(mixer_volume); + + spin_lock_irq(&bt_sco->mixer_lock); + for (i = 0; i <= MIXER_ADDR_LAST; i++) { + int vol = mixer_volume[i]; + if (vol > MIXER_MAX_VOLUME) + vol = MIXER_MAX_VOLUME; + if (vol < MIXER_MIN_VOLUME) + vol = MIXER_MIN_VOLUME; + if (bt_sco->mixer_volume[i] != vol) { + bt_sco->mixer_volume[i] = vol; + snd_ctl_notify(bt_sco->card, + SNDRV_CTL_EVENT_MASK_VALUE, + &bt_sco->mixer_controls[i]->id); + } + } + spin_unlock_irq(&bt_sco->mixer_lock); + + return retval; +} + +static long snd_card_bt_read(struct snd_hwdep * hw, char *buf, long count, + loff_t * offset) +{ + snd_card_bt_sco_t *bt_sco = hw->card->private_data; + DECLARE_WAITQUEUE(wait, current); + ssize_t retval; + int changed; + snd_card_bt_sco_info_t infobuf; + + if (count < sizeof(bt_sco->mixer_volume)) + return -EINVAL; + + add_wait_queue(&bt_sco->hwdep_wait, &wait); + current->state = TASK_INTERRUPTIBLE; + do { + changed = 0; + spin_lock_irq(&bt_sco->mixer_changed_lock); + if(bt_sco->mixer_changed) + changed = 1; + bt_sco->mixer_changed = 0; + spin_unlock_irq(&bt_sco->mixer_changed_lock); + + spin_lock_irq(&bt_sco->count_changed_lock); + if(bt_sco->count_changed) + changed = 1; + bt_sco->count_changed = 0; + spin_unlock_irq(&bt_sco->count_changed_lock); + + if (changed != 0) + break; + + if (signal_pending(current)) { + retval = -ERESTARTSYS; + goto out; + } + schedule(); + } while (1); + + memcpy(infobuf.mixer_volume, bt_sco->mixer_volume, sizeof(infobuf.mixer_volume)); + infobuf.playback_count = atomic_read(&bt_sco->playback_count); + infobuf.capture_count = atomic_read(&bt_sco->capture_count); + + if (copy_to_user + (buf, &infobuf, sizeof(infobuf))) + retval = -EFAULT; + else + retval = sizeof(infobuf); + + out: + current->state = TASK_RUNNING; + remove_wait_queue(&bt_sco->hwdep_wait, &wait); + return retval; +} + +static unsigned int snd_card_bt_poll(struct snd_hwdep * hw, + struct file *file, poll_table * wait) +{ + snd_card_bt_sco_t *bt_sco = hw->card->private_data; + int ret; + + poll_wait(file, &bt_sco->hwdep_wait, wait); + + ret = 0; + spin_lock_irq(&bt_sco->mixer_changed_lock); + if(bt_sco->mixer_changed) + ret |= POLLIN | POLLRDNORM; + spin_unlock_irq(&bt_sco->mixer_changed_lock); + + spin_lock_irq(&bt_sco->count_changed_lock); + if(bt_sco->count_changed) + ret |= POLLIN | POLLRDNORM; + spin_unlock_irq(&bt_sco->count_changed_lock); + + return ret; +} + +static int snd_card_bt_sco_thread(void *data) +{ + struct snd_card *card = (struct snd_card *) data; + snd_card_bt_sco_t *bt_sco = card->private_data; + struct socket *sock; + int len; +#define BUF_SIZE 256 + unsigned char buf[BUF_SIZE]; + struct msghdr msg; + struct iovec iov; +#if defined(DYNAMIC_COMPRESSION) || defined(AUTO_FIXUP_BYTESHIFT) + int i; +#endif +#ifdef DYNAMIC_COMPRESSION + static int factor=16; + static int maxvalsmoothed=0; + static int maxvalgrablen=GRABSAMPLES; /* adjust volume at most 4 times/second */ +#endif +#ifdef AUTO_FIXUP_BYTESHIFT + static int shift=0; + static unsigned char lastbyte; +#endif + + set_freezable(); + + dprintk("snd-bt-scod thread starting\n"); + mutex_unlock(&bt_sco->thread_sem); + + do { + /* This may be woken up by a wake_up() when + * a new socket is installed, or by a signal. + * Signals are sent to terminate the thread, + * in which case thread_exit is set, and to force + * recvmesg() to wake up (from the ioctl handler) + */ + wait_event_freezable(bt_sco->wait, bt_sco->sco_sock || kthread_should_stop()); + + mutex_lock(&bt_sco->sock_sem); + sock = (struct socket *)bt_sco->sco_sock; + if (sock) + get_file(sock->file); + mutex_unlock(&bt_sco->sock_sem); + + if (!sock) + continue; + + /* We have a socket, let's read from it and write to it... */ + + memset(&msg, 0, sizeof(msg)); + msg.msg_iov = &iov; + iov.iov_base = buf; + iov.iov_len = BUF_SIZE; + + /* This will block until we receive data or a signal */ + len = sock_recvmsg(sock, &msg, BUF_SIZE, 0); + if (len > 0) { + +#if defined (AUTO_FIXUP_BYTESHIFT) || defined (DYNAMIC_COMPRESSION) + +#ifdef AUTO_FIXUP_BYTESHIFT + int lostatcnt=0; +#endif + if (len&1) dprintk("odd len %d\n",len); +#ifdef AUTO_FIXUP_BYTESHIFT + if (shift) { + unsigned char newlastbyte; + newlastbyte=buf[len-1]; + memmove(buf+1,buf,len-1); + buf[0]=lastbyte; + lastbyte=newlastbyte; + } +#endif + for(i=0;i0x7fff) { + k=0x7fff; + if (bt_sco->agc&&factor>COMPRESSION_MIN_16) factor--; + } else if (k<-0x8000) { + k=0x8000; + if (bt_sco->agc&&factor>COMPRESSION_MIN_16) factor--; + } + buf[i+1]=(k>>8)&0xff; + buf[i ]=k&0xff; + + /* find the highest absolute value in a + * GRABSAMPLES long interval. + */ + if (k<0) k=-j; + if (k>maxvalsmoothed) maxvalsmoothed=k; + /* if the interval is over, recalculate + * the compression factor. Move it slowly. + */ + if (maxvalgrablen--<=0) { + maxvalgrablen=GRABSAMPLES; + /* If the noise goes up over 1000, we stop + * pushing the software gain + */ + if (maxvalsmoothed<1000&&factoragc) factor=16; + maxvalsmoothed=0; + } +#endif + } +#ifdef AUTO_FIXUP_BYTESHIFT + if (lostatcnt==len/2&&len>32) { + shift=!shift; + //dprintk("Shift problem detected! Fixing to %d.\n",shift); + } +#endif +#endif /* any of them */ + mutex_lock(&bt_sco->capture_sem); + if (bt_sco->capture) { + snd_card_bt_sco_pcm_receive + (bt_sco->capture, buf, len); + } + mutex_unlock(&bt_sco->capture_sem); + + mutex_lock(&bt_sco->playback_sem); + + if (bt_sco->playback || !bt_sco->loopback) { + memset(buf, 0, len); +#if 0 + /* fill with tone instead of silence */ + int i; + + for (i = 0; i < len / 2; i++) { + buf[i] = 0; + } + for (i = len / 2; i < len; i++) { + buf[i] = 127; + } +#endif + } + if (bt_sco->playback) { + int i, notzero = -1; + + snd_card_bt_sco_pcm_send + (bt_sco->playback, buf, len); + + /* Strangely, when the device is open but no audio is + being written by the app, there's an occasional glitch + in the silence data. This hack eliminates it. */ + + for (i = 0; i < len; i++) { + if (buf[i] != 0) { + if (notzero >= 0) + break; + notzero = i; + } + } + if (notzero >= 0 && i >= len) { + buf[notzero] = 0; + } + } + mutex_unlock(&bt_sco->playback_sem); + +#if 0 + /* This chunk of code lets us record (using arecord) + what data alsa is sending out. + + e.g., when idle, we'd expect something like: + + 8080 8080 8080 8080 8483 8281 8182 8384 + 8080 8080 8080 8080 8080 8080 8080 8080 + 8080 8080 8080 8080 8483 8281 8182 8384 + 8080 8080 8080 8080 8080 8080 8080 8080 + + (this is from 'xxd' of a wav file, that data in + which is unsigned, whereas we are dealing with signed). + */ + + mutex_lock(&bt_sco->capture_sem); + if (bt_sco->capture) { + snd_card_bt_sco_pcm_receive + (bt_sco->capture, "\001\002\003\004", 4); + snd_card_bt_sco_pcm_receive + (bt_sco->capture, buf, len); + snd_card_bt_sco_pcm_receive + (bt_sco->capture, "\004\003\002\001", 4); + } + mutex_unlock(&bt_sco->capture_sem); +#endif + msg.msg_flags = 0; + msg.msg_iov = &iov; + iov.iov_base = buf; + iov.iov_len = BUF_SIZE; + sock_sendmsg(sock, &msg, len); + } + + /* Expect this to be 3 because we (this thead) have a copy, + the driver process keeps one, and the app has the socket open. + */ + if (file_count(sock->file) != 3) { + dprintk("file_count is %d (expected 3)\n", + file_count(sock->file)); + } + fput(sock->file); + + schedule(); + } while (!kthread_should_stop() || bt_sco->sco_sock); + + dprintk("thread exiting\n"); + + return 0; +} + +static void snd_card_bt_private_free(struct snd_card * card) +{ + snd_card_bt_sco_t *bt_sco = card->private_data; + + dprintk("private_free, killing thread\n"); + kthread_stop(bt_sco->thread); + dprintk("private_free, thread exited\n"); + + if (bt_sco->sco_sock) { + dprintk("shutdown: freeing socket count %d\n", + file_count(bt_sco->sco_sock->file)); + + sockfd_put(((struct socket *)bt_sco->sco_sock)); + } + + kfree(bt_sco); +} + +static int __init snd_card_bt_sco_probe(int dev) +{ + struct snd_card *card; + snd_card_bt_sco_t *bt_sco; + int err; + struct snd_hwdep *hw; + + card = + snd_card_new(index[dev], SNDRV_DEFAULT_STR1, + THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; + + bt_sco = kmalloc(sizeof(*bt_sco), GFP_KERNEL); + if(bt_sco == NULL) + return -ENOMEM; + memset(bt_sco, 0, sizeof(*bt_sco)); + card->private_data = bt_sco; + card->private_free = snd_card_bt_private_free; + + bt_sco->card = card; + + mutex_init(&bt_sco->thread_sem); + mutex_lock(&bt_sco->thread_sem); + mutex_init(&bt_sco->sock_sem); + mutex_init(&bt_sco->capture_sem); + mutex_init(&bt_sco->playback_sem); + init_waitqueue_head(&bt_sco->wait); + init_waitqueue_head(&bt_sco->hwdep_wait); + spin_lock_init(&bt_sco->mixer_changed_lock); + spin_lock_init(&bt_sco->count_changed_lock); + + /* These clone flags copied from some other driver. + Not sure that they're really correct... */ + bt_sco->thread = + kthread_run(snd_card_bt_sco_thread, card, "snd-bt-scod"); + if (IS_ERR(bt_sco->thread)) { + err = PTR_ERR(bt_sco->thread); + goto __nodev; + } + + mutex_lock(&bt_sco->thread_sem); + + if ((err = snd_card_bt_sco_pcm(bt_sco)) < 0) + goto __nodev; + if ((err = snd_card_bt_sco_new_mixer(bt_sco)) < 0) + goto __nodev; + strcpy(card->driver, "Bluetooth SCO"); + strcpy(card->shortname, "BT Headset"); + sprintf(card->longname, "BT Headset %i", dev + 1); + + err = snd_hwdep_new(card, "BTSCO", 0, &hw); + if (err < 0) + goto __nodev; + + sprintf(hw->name, "BTSCO"); + hw->iface = SNDRV_HWDEP_IFACE_BT_SCO; + hw->ops.open = snd_card_bt_open; + hw->ops.ioctl = snd_card_bt_ioctl; + hw->ops.release = snd_card_bt_release; + hw->ops.read = snd_card_bt_read; + hw->ops.write = snd_card_bt_write; + hw->ops.poll = snd_card_bt_poll; + + if ((err = snd_card_register(card)) == 0) { + snd_bt_sco_cards[dev] = card; + return 0; + } + __nodev: + snd_card_free(card); + return err; +} + +static int __init alsa_card_bt_sco_init(void) +{ + printk(KERN_INFO "snd-bt-sco revision %s\n", mod_revision + 11); + + if (snd_card_bt_sco_probe(0) < 0) { +#ifdef MODULE + printk(KERN_ERR + "Bluetooth SCO soundcard not found or device busy\n"); +#endif + return -ENODEV; + } + return 0; +} + +static void __exit alsa_card_bt_sco_exit(void) +{ + int idx; + + for (idx = 0; idx < SNDRV_CARDS; idx++) + snd_card_free(snd_bt_sco_cards[idx]); +} + +module_init(alsa_card_bt_sco_init) + module_exit(alsa_card_bt_sco_exit) +#ifndef MODULE +static int __init alsa_card_bt_sco_setup(char *str) +{ + static unsigned __initdata nr_dev = 0; + + if (nr_dev >= SNDRV_CARDS) + return 0; + nr_dev++; + return 1; +} + +__setup("snd-bt-sco=", alsa_card_bt_sco_setup); + +#endif /* ifndef MODULE */ --- linux-2.6.28.orig/ubuntu/misc/media/Kconfig +++ linux-2.6.28/ubuntu/misc/media/Kconfig @@ -0,0 +1,13 @@ +menu "Media related drivers" + +config SND_BTSCO + tristate "Bluetooth SCO Sound driver" + default m + depends on SND && BT + +config USB_OV511_NEW + tristate "OmniVision OV511 Camera-to-USB Bridge Driver" + default m + depends on USB && VIDEO_V4L2 + +endmenu --- linux-2.6.28.orig/ubuntu/misc/media/Makefile +++ linux-2.6.28/ubuntu/misc/media/Makefile @@ -0,0 +1,4 @@ +# + +#obj-$(CONFIG_SND_BTSCO) += snd-bt-sco.o +obj-$(CONFIG_USB_OV511_NEW) += ov511/ --- linux-2.6.28.orig/ubuntu/misc/media/ov511/ov511.c +++ linux-2.6.28/ubuntu/misc/media/ov511/ov511.c @@ -0,0 +1,6123 @@ +/* + * OmniVision OV511 Camera-to-USB Bridge Driver + * + * Copyright (c) 1999-2003 Mark W. McClelland + * Original decompression code Copyright 1998-2000 OmniVision Technologies + * Many improvements by Bret Wallach + * Color fixes by by Orion Sky Lawlor (2/26/2000) + * Snapshot code by Kevin Moore + * OV7620 fixes by Charl P. Botha + * Changes by Claudio Matsuoka + * Original SAA7111A code by Dave Perks + * URB error messages from pwc driver by Nemosoft + * generic_ioctl() code from videodev.c by Gerd Knorr and Alan Cox + * Memory management (rvmalloc) code from bttv driver, by Gerd Knorr and others + * + * Based on the Linux CPiA driver written by Peter Pregler, + * Scott J. Bertin and Johannes Erdfelt. + * + * Please see the file: Documentation/usb/ov511.txt + * and the website at: http://alpha.dyndns.org/ov511 + * for more info. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the 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 + +#if defined (__i386__) + #include +#endif + +#include "ov511.h" + +/* + * Version Information + */ +#define DRIVER_VERSION "v1.64 for Linux 2.5" +#define EMAIL "mark@alpha.dyndns.org" +#define DRIVER_AUTHOR "Mark McClelland & Bret Wallach \ + & Orion Sky Lawlor & Kevin Moore & Charl P. Botha \ + & Claudio Matsuoka " +#define DRIVER_DESC "ov511 USB Camera Driver" + +#define OV511_I2C_RETRIES 3 +#define ENABLE_Y_QUANTABLE 1 +#define ENABLE_UV_QUANTABLE 1 + +#define OV511_MAX_UNIT_VIDEO 16 + +/* Pixel count * bytes per YUV420 pixel (1.5) */ +#define MAX_FRAME_SIZE(w, h) ((w) * (h) * 3 / 2) + +#define MAX_DATA_SIZE(w, h) (MAX_FRAME_SIZE(w, h) + sizeof(struct timeval)) + +/* Max size * bytes per YUV420 pixel (1.5) + one extra isoc frame for safety */ +#define MAX_RAW_DATA_SIZE(w, h) ((w) * (h) * 3 / 2 + 1024) + +#define FATAL_ERROR(rc) ((rc) < 0 && (rc) != -EPERM) + +/********************************************************************** + * Module Parameters + * (See ov511.txt for detailed descriptions of these) + **********************************************************************/ + +/* These variables (and all static globals) default to zero */ +static int autobright = 1; +static int autogain = 1; +static int autoexp = 1; +static int debug; +static int snapshot; +static int cams = 1; +static int compress; +static int testpat; +static int dumppix; +static int led = 1; +static int dump_bridge; +static int dump_sensor; +static int printph; +static int phy = 0x1f; +static int phuv = 0x05; +static int pvy = 0x06; +static int pvuv = 0x06; +static int qhy = 0x14; +static int qhuv = 0x03; +static int qvy = 0x04; +static int qvuv = 0x04; +static int lightfreq; +static int bandingfilter; +static int clockdiv = -1; +static int packetsize = -1; +static int framedrop = -1; +static int fastset; +static int force_palette; +static int backlight; +static int unit_video[OV511_MAX_UNIT_VIDEO]; +static int remove_zeros; +static int mirror; +static int ov518_color; + +module_param(autobright, int, 0); +MODULE_PARM_DESC(autobright, "Sensor automatically changes brightness"); +module_param(autogain, int, 0); +MODULE_PARM_DESC(autogain, "Sensor automatically changes gain"); +module_param(autoexp, int, 0); +MODULE_PARM_DESC(autoexp, "Sensor automatically changes exposure"); +module_param(debug, int, 0); +MODULE_PARM_DESC(debug, + "Debug level: 0=none, 1=inits, 2=warning, 3=config, 4=functions, 5=max"); +module_param(snapshot, int, 0); +MODULE_PARM_DESC(snapshot, "Enable snapshot mode"); +module_param(cams, int, 0); +MODULE_PARM_DESC(cams, "Number of simultaneous cameras"); +module_param(compress, int, 0); +MODULE_PARM_DESC(compress, "Turn on compression"); +module_param(testpat, int, 0); +MODULE_PARM_DESC(testpat, + "Replace image with vertical bar testpattern (only partially working)"); +module_param(dumppix, int, 0); +MODULE_PARM_DESC(dumppix, "Dump raw pixel data"); +module_param(led, int, 0); +MODULE_PARM_DESC(led, + "LED policy (OV511+ or later). 0=off, 1=on (default), 2=auto (on when open)"); +module_param(dump_bridge, int, 0); +MODULE_PARM_DESC(dump_bridge, "Dump the bridge registers"); +module_param(dump_sensor, int, 0); +MODULE_PARM_DESC(dump_sensor, "Dump the sensor registers"); +module_param(printph, int, 0); +MODULE_PARM_DESC(printph, "Print frame start/end headers"); +module_param(phy, int, 0); +MODULE_PARM_DESC(phy, "Prediction range (horiz. Y)"); +module_param(phuv, int, 0); +MODULE_PARM_DESC(phuv, "Prediction range (horiz. UV)"); +module_param(pvy, int, 0); +MODULE_PARM_DESC(pvy, "Prediction range (vert. Y)"); +module_param(pvuv, int, 0); +MODULE_PARM_DESC(pvuv, "Prediction range (vert. UV)"); +module_param(qhy, int, 0); +MODULE_PARM_DESC(qhy, "Quantization threshold (horiz. Y)"); +module_param(qhuv, int, 0); +MODULE_PARM_DESC(qhuv, "Quantization threshold (horiz. UV)"); +module_param(qvy, int, 0); +MODULE_PARM_DESC(qvy, "Quantization threshold (vert. Y)"); +module_param(qvuv, int, 0); +MODULE_PARM_DESC(qvuv, "Quantization threshold (vert. UV)"); +module_param(lightfreq, int, 0); +MODULE_PARM_DESC(lightfreq, + "Light frequency. Set to 50 or 60 Hz, or zero for default settings"); +module_param(bandingfilter, int, 0); +MODULE_PARM_DESC(bandingfilter, + "Enable banding filter (to reduce effects of fluorescent lighting)"); +module_param(clockdiv, int, 0); +MODULE_PARM_DESC(clockdiv, "Force pixel clock divisor to a specific value"); +module_param(packetsize, int, 0); +MODULE_PARM_DESC(packetsize, "Force a specific isoc packet size"); +module_param(framedrop, int, 0); +MODULE_PARM_DESC(framedrop, "Force a specific frame drop register setting"); +module_param(fastset, int, 0); +MODULE_PARM_DESC(fastset, "Allows picture settings to take effect immediately"); +module_param(force_palette, int, 0); +MODULE_PARM_DESC(force_palette, "Force the palette to a specific value"); +module_param(backlight, int, 0); +MODULE_PARM_DESC(backlight, "For objects that are lit from behind"); +static int num_uv; +module_param_array(unit_video, int, &num_uv, 0); +MODULE_PARM_DESC(unit_video, + "Force use of specific minor number(s). 0 is not allowed."); +module_param(remove_zeros, int, 0); +MODULE_PARM_DESC(remove_zeros, + "Remove zero-padding from uncompressed incoming data"); +module_param(mirror, int, 0); +MODULE_PARM_DESC(mirror, "Reverse image horizontally"); +module_param(ov518_color, int, 0); +MODULE_PARM_DESC(ov518_color, "Enable OV518 color (experimental)"); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); + +/********************************************************************** + * Miscellaneous Globals + **********************************************************************/ + +static struct usb_driver ov511_driver; + +static struct ov51x_decomp_ops *ov511_decomp_ops; +static struct ov51x_decomp_ops *ov511_mmx_decomp_ops; +static struct ov51x_decomp_ops *ov518_decomp_ops; +static struct ov51x_decomp_ops *ov518_mmx_decomp_ops; + +/* Number of times to retry a failed I2C transaction. Increase this if you + * are getting "Failed to read sensor ID..." */ +static int i2c_detect_tries = 5; + +/* MMX support is present in kernel and CPU. Checked upon decomp module load. */ +#if defined(__i386__) || defined(__x86_64__) +#define ov51x_mmx_available (cpu_has_mmx) +#else +#define ov51x_mmx_available (0) +#endif + +static struct usb_device_id device_table [] = { + { USB_DEVICE(VEND_OMNIVISION, PROD_OV511) }, + { USB_DEVICE(VEND_OMNIVISION, PROD_OV511PLUS) }, + { USB_DEVICE(VEND_OMNIVISION, PROD_OV518) }, + { USB_DEVICE(VEND_OMNIVISION, PROD_OV518PLUS) }, + { USB_DEVICE(VEND_MATTEL, PROD_ME2CAM) }, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, device_table); + +static unsigned char yQuanTable511[] = OV511_YQUANTABLE; +static unsigned char uvQuanTable511[] = OV511_UVQUANTABLE; +static unsigned char yQuanTable518[] = OV518_YQUANTABLE; +static unsigned char uvQuanTable518[] = OV518_UVQUANTABLE; + +/********************************************************************** + * Symbolic Names + **********************************************************************/ + +/* Known OV511-based cameras */ +static struct symbolic_list camlist[] = { + { 0, "Generic Camera (no ID)" }, + { 1, "Mustek WCam 3X" }, + { 3, "D-Link DSB-C300" }, + { 4, "Generic OV511/OV7610" }, + { 5, "Puretek PT-6007" }, + { 6, "Lifeview USB Life TV (NTSC)" }, + { 21, "Creative Labs WebCam 3" }, + { 22, "Lifeview USB Life TV (PAL D/K+B/G)" }, + { 36, "Koala-Cam" }, + { 38, "Lifeview USB Life TV (PAL)" }, + { 41, "Samsung Anycam MPC-M10" }, + { 43, "Mtekvision Zeca MV402" }, + { 46, "Suma eON" }, + { 70, "Lifeview USB Life TV (PAL/SECAM)" }, + { 100, "Lifeview RoboCam" }, + { 102, "AverMedia InterCam Elite" }, + { 112, "MediaForte MV300" }, /* or OV7110 evaluation kit */ + { 134, "Ezonics EZCam II" }, + { 192, "Webeye 2000B" }, + { 253, "Alpha Vision Tech. AlphaCam SE" }, + { -1, NULL } +}; + +/* Video4Linux1 Palettes */ +static struct symbolic_list v4l1_plist[] = { + { VIDEO_PALETTE_GREY, "GREY" }, + { VIDEO_PALETTE_HI240, "HI240" }, + { VIDEO_PALETTE_RGB565, "RGB565" }, + { VIDEO_PALETTE_RGB24, "RGB24" }, + { VIDEO_PALETTE_RGB32, "RGB32" }, + { VIDEO_PALETTE_RGB555, "RGB555" }, + { VIDEO_PALETTE_YUV422, "YUV422" }, + { VIDEO_PALETTE_YUYV, "YUYV" }, + { VIDEO_PALETTE_UYVY, "UYVY" }, + { VIDEO_PALETTE_YUV420, "YUV420" }, + { VIDEO_PALETTE_YUV411, "YUV411" }, + { VIDEO_PALETTE_RAW, "RAW" }, + { VIDEO_PALETTE_YUV422P,"YUV422P" }, + { VIDEO_PALETTE_YUV411P,"YUV411P" }, + { VIDEO_PALETTE_YUV420P,"YUV420P" }, + { VIDEO_PALETTE_YUV410P,"YUV410P" }, + { -1, NULL } +}; + +static struct symbolic_list brglist[] = { + { BRG_OV511, "OV511" }, + { BRG_OV511PLUS, "OV511+" }, + { BRG_OV518, "OV518" }, + { BRG_OV518PLUS, "OV518+" }, + { -1, NULL } +}; + +static struct symbolic_list senlist[] = { + { SEN_OV76BE, "OV76BE" }, + { SEN_OV7610, "OV7610" }, + { SEN_OV7620, "OV7620" }, + { SEN_OV7620AE, "OV7620AE" }, + { SEN_OV6620, "OV6620" }, + { SEN_OV6630, "OV6630" }, + { SEN_OV6630AE, "OV6630AE" }, + { SEN_OV6630AF, "OV6630AF" }, + { SEN_OV8600, "OV8600" }, + { SEN_KS0127, "KS0127" }, + { SEN_KS0127B, "KS0127B" }, + { SEN_SAA7111A, "SAA7111A" }, + { -1, NULL } +}; + +/* URB error codes: */ +static struct symbolic_list urb_errlist[] = { + { -ENOSR, "Buffer error (overrun)" }, + { -EPIPE, "Stalled (device not responding)" }, + { -EOVERFLOW, "Babble (bad cable?)" }, + { -EPROTO, "Bit-stuff error (bad cable?)" }, + { -EILSEQ, "CRC/Timeout" }, + { -ETIMEDOUT, "NAK (device does not respond)" }, + { -1, NULL } +}; + +/********************************************************************** + * Memory management + **********************************************************************/ +static void * +rvmalloc(unsigned long size) +{ + void *mem; + unsigned long adr; + + size = PAGE_ALIGN(size); + mem = vmalloc_32(size); + if (!mem) + return NULL; + + memset(mem, 0, size); /* Clear the ram out, no junk to the user */ + adr = (unsigned long) mem; + while (size > 0) { + SetPageReserved(vmalloc_to_page((void *)adr)); + adr += PAGE_SIZE; + size -= PAGE_SIZE; + } + + return mem; +} + +static void +rvfree(void *mem, unsigned long size) +{ + unsigned long adr; + + if (!mem) + return; + + adr = (unsigned long) mem; + while ((long) size > 0) { + ClearPageReserved(vmalloc_to_page((void *)adr)); + adr += PAGE_SIZE; + size -= PAGE_SIZE; + } + vfree(mem); +} + +/********************************************************************** + * + * Register I/O + * + **********************************************************************/ + +/* Write an OV51x register */ +static int +reg_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value) +{ + int rc; + + PDEBUG(5, "0x%02X:0x%02X", reg, value); + + down(&ov->cbuf_lock); + ov->cbuf[0] = value; + rc = usb_control_msg(ov->dev, + usb_sndctrlpipe(ov->dev, 0), + (ov->bclass == BCL_OV518)?1:2 /* REG_IO */, + USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, (__u16)reg, &ov->cbuf[0], 1, 1000); + up(&ov->cbuf_lock); + + if (rc < 0) + err("reg write: error %d: %s", rc, symbolic(urb_errlist, rc)); + + return rc; +} + +/* Read from an OV51x register */ +/* returns: negative is error, pos or zero is data */ +static int +reg_r(struct usb_ov511 *ov, unsigned char reg) +{ + int rc; + + down(&ov->cbuf_lock); + rc = usb_control_msg(ov->dev, + usb_rcvctrlpipe(ov->dev, 0), + (ov->bclass == BCL_OV518)?1:3 /* REG_IO */, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, (__u16)reg, &ov->cbuf[0], 1, 1000); + + if (rc < 0) { + err("reg read: error %d: %s", rc, symbolic(urb_errlist, rc)); + } else { + rc = ov->cbuf[0]; + PDEBUG(5, "0x%02X:0x%02X", reg, ov->cbuf[0]); + } + + up(&ov->cbuf_lock); + + return rc; +} + +/* + * Writes bits at positions specified by mask to an OV51x reg. Bits that are in + * the same position as 1's in "mask" are cleared and set to "value". Bits + * that are in the same position as 0's in "mask" are preserved, regardless + * of their respective state in "value". + */ +static int +reg_w_mask(struct usb_ov511 *ov, + unsigned char reg, + unsigned char value, + unsigned char mask) +{ + int ret; + unsigned char oldval, newval; + + ret = reg_r(ov, reg); + if (ret < 0) + return ret; + + oldval = (unsigned char) ret; + oldval &= (~mask); /* Clear the masked bits */ + value &= mask; /* Enforce mask on value */ + newval = oldval | value; /* Set the desired bits */ + + return (reg_w(ov, reg, newval)); +} + +/* + * Writes multiple (n) byte value to a single register. Only valid with certain + * registers (0x30 and 0xc4 - 0xce). + */ +static int +ov518_reg_w32(struct usb_ov511 *ov, unsigned char reg, u32 val, int n) +{ + int rc; + + PDEBUG(5, "0x%02X:%7d, n=%d", reg, val, n); + + down(&ov->cbuf_lock); + + *((__le32 *)ov->cbuf) = __cpu_to_le32(val); + + rc = usb_control_msg(ov->dev, + usb_sndctrlpipe(ov->dev, 0), + 1 /* REG_IO */, + USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, (__u16)reg, ov->cbuf, n, 1000); + up(&ov->cbuf_lock); + + if (rc < 0) + err("reg write multiple: error %d: %s", rc, + symbolic(urb_errlist, rc)); + + return rc; +} + +static int +ov511_upload_quan_tables(struct usb_ov511 *ov) +{ + unsigned char *pYTable = yQuanTable511; + unsigned char *pUVTable = uvQuanTable511; + unsigned char val0, val1; + int i, rc, reg = R511_COMP_LUT_BEGIN; + + PDEBUG(4, "Uploading quantization tables"); + + for (i = 0; i < OV511_QUANTABLESIZE / 2; i++) { + if (ENABLE_Y_QUANTABLE) { + val0 = *pYTable++; + val1 = *pYTable++; + val0 &= 0x0f; + val1 &= 0x0f; + val0 |= val1 << 4; + rc = reg_w(ov, reg, val0); + if (rc < 0) + return rc; + } + + if (ENABLE_UV_QUANTABLE) { + val0 = *pUVTable++; + val1 = *pUVTable++; + val0 &= 0x0f; + val1 &= 0x0f; + val0 |= val1 << 4; + rc = reg_w(ov, reg + OV511_QUANTABLESIZE/2, val0); + if (rc < 0) + return rc; + } + + reg++; + } + + return 0; +} + +/* OV518 quantization tables are 8x4 (instead of 8x8) */ +static int +ov518_upload_quan_tables(struct usb_ov511 *ov) +{ + unsigned char *pYTable = yQuanTable518; + unsigned char *pUVTable = uvQuanTable518; + unsigned char val0, val1; + int i, rc, reg = R511_COMP_LUT_BEGIN; + + PDEBUG(4, "Uploading quantization tables"); + + for (i = 0; i < OV518_QUANTABLESIZE / 2; i++) { + if (ENABLE_Y_QUANTABLE) { + val0 = *pYTable++; + val1 = *pYTable++; + val0 &= 0x0f; + val1 &= 0x0f; + val0 |= val1 << 4; + rc = reg_w(ov, reg, val0); + if (rc < 0) + return rc; + } + + if (ENABLE_UV_QUANTABLE) { + val0 = *pUVTable++; + val1 = *pUVTable++; + val0 &= 0x0f; + val1 &= 0x0f; + val0 |= val1 << 4; + rc = reg_w(ov, reg + OV518_QUANTABLESIZE/2, val0); + if (rc < 0) + return rc; + } + + reg++; + } + + return 0; +} + +static int +ov51x_reset(struct usb_ov511 *ov, unsigned char reset_type) +{ + int rc; + + /* Setting bit 0 not allowed on 518/518Plus */ + if (ov->bclass == BCL_OV518) + reset_type &= 0xfe; + + PDEBUG(4, "Reset: type=0x%02X", reset_type); + + rc = reg_w(ov, R51x_SYS_RESET, reset_type); + rc = reg_w(ov, R51x_SYS_RESET, 0); + + if (rc < 0) + err("reset: command failed"); + + return rc; +} + +/********************************************************************** + * + * Low-level I2C I/O functions + * + **********************************************************************/ + +/* NOTE: Do not call this function directly! + * The OV518 I2C I/O procedure is different, hence, this function. + * This is normally only called from i2c_w(). Note that this function + * always succeeds regardless of whether the sensor is present and working. + */ +static int +ov518_i2c_write_internal(struct usb_ov511 *ov, + unsigned char reg, + unsigned char value) +{ + int rc; + + PDEBUG(5, "0x%02X:0x%02X", reg, value); + + /* Select camera register */ + rc = reg_w(ov, R51x_I2C_SADDR_3, reg); + if (rc < 0) + return rc; + + /* Write "value" to I2C data port of OV511 */ + rc = reg_w(ov, R51x_I2C_DATA, value); + if (rc < 0) + return rc; + + /* Initiate 3-byte write cycle */ + rc = reg_w(ov, R518_I2C_CTL, 0x01); + if (rc < 0) + return rc; + + return 0; +} + +/* NOTE: Do not call this function directly! */ +static int +ov511_i2c_write_internal(struct usb_ov511 *ov, + unsigned char reg, + unsigned char value) +{ + int rc, retries; + + PDEBUG(5, "0x%02X:0x%02X", reg, value); + + /* Three byte write cycle */ + for (retries = OV511_I2C_RETRIES; ; ) { + /* Select camera register */ + rc = reg_w(ov, R51x_I2C_SADDR_3, reg); + if (rc < 0) + break; + + /* Write "value" to I2C data port of OV511 */ + rc = reg_w(ov, R51x_I2C_DATA, value); + if (rc < 0) + break; + + /* Initiate 3-byte write cycle */ + rc = reg_w(ov, R511_I2C_CTL, 0x01); + if (rc < 0) + break; + + /* Retry until idle */ + do + rc = reg_r(ov, R511_I2C_CTL); + while (rc > 0 && ((rc&1) == 0)); + if (rc < 0) + break; + + /* Ack? */ + if ((rc&2) == 0) { + rc = 0; + break; + } +#if 0 + /* I2C abort */ + reg_w(ov, R511_I2C_CTL, 0x10); +#endif + if (--retries < 0) { + err("i2c write retries exhausted"); + rc = -1; + break; + } + } + + return rc; +} + +/* NOTE: Do not call this function directly! + * The OV518 I2C I/O procedure is different, hence, this function. + * This is normally only called from i2c_r(). Note that this function + * always succeeds regardless of whether the sensor is present and working. + */ +static int +ov518_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg) +{ + int rc, value; + + /* Select camera register */ + rc = reg_w(ov, R51x_I2C_SADDR_2, reg); + if (rc < 0) + return rc; + + /* Initiate 2-byte write cycle */ + rc = reg_w(ov, R518_I2C_CTL, 0x03); + if (rc < 0) + return rc; + + /* Initiate 2-byte read cycle */ + rc = reg_w(ov, R518_I2C_CTL, 0x05); + if (rc < 0) + return rc; + + value = reg_r(ov, R51x_I2C_DATA); + + PDEBUG(5, "0x%02X:0x%02X", reg, value); + + return value; +} + +/* NOTE: Do not call this function directly! + * returns: negative is error, pos or zero is data */ +static int +ov511_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg) +{ + int rc, value, retries; + + /* Two byte write cycle */ + for (retries = OV511_I2C_RETRIES; ; ) { + /* Select camera register */ + rc = reg_w(ov, R51x_I2C_SADDR_2, reg); + if (rc < 0) + return rc; + + /* Initiate 2-byte write cycle */ + rc = reg_w(ov, R511_I2C_CTL, 0x03); + if (rc < 0) + return rc; + + /* Retry until idle */ + do + rc = reg_r(ov, R511_I2C_CTL); + while (rc > 0 && ((rc&1) == 0)); + if (rc < 0) + return rc; + + if ((rc&2) == 0) /* Ack? */ + break; + + /* I2C abort */ + reg_w(ov, R511_I2C_CTL, 0x10); + + if (--retries < 0) { + err("i2c write retries exhausted"); + return -1; + } + } + + /* Two byte read cycle */ + for (retries = OV511_I2C_RETRIES; ; ) { + /* Initiate 2-byte read cycle */ + rc = reg_w(ov, R511_I2C_CTL, 0x05); + if (rc < 0) + return rc; + + /* Retry until idle */ + do + rc = reg_r(ov, R511_I2C_CTL); + while (rc > 0 && ((rc&1) == 0)); + if (rc < 0) + return rc; + + if ((rc&2) == 0) /* Ack? */ + break; + + /* I2C abort */ + rc = reg_w(ov, R511_I2C_CTL, 0x10); + if (rc < 0) + return rc; + + if (--retries < 0) { + err("i2c read retries exhausted"); + return -1; + } + } + + value = reg_r(ov, R51x_I2C_DATA); + + PDEBUG(5, "0x%02X:0x%02X", reg, value); + + /* This is needed to make i2c_w() work */ + rc = reg_w(ov, R511_I2C_CTL, 0x05); + if (rc < 0) + return rc; + + return value; +} + +/* returns: negative is error, pos or zero is data */ +static int +i2c_r(struct usb_ov511 *ov, unsigned char reg) +{ + int rc; + + down(&ov->i2c_lock); + + if (ov->bclass == BCL_OV518) + rc = ov518_i2c_read_internal(ov, reg); + else + rc = ov511_i2c_read_internal(ov, reg); + + up(&ov->i2c_lock); + + return rc; +} + +static int +i2c_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value) +{ + int rc; + + down(&ov->i2c_lock); + + if (ov->bclass == BCL_OV518) + rc = ov518_i2c_write_internal(ov, reg, value); + else + rc = ov511_i2c_write_internal(ov, reg, value); + + up(&ov->i2c_lock); + + return rc; +} + +/* Do not call this function directly! */ +static int +ov51x_i2c_write_mask_internal(struct usb_ov511 *ov, + unsigned char reg, + unsigned char value, + unsigned char mask) +{ + int rc; + unsigned char oldval, newval; + + if (mask == 0xff) { + newval = value; + } else { + if (ov->bclass == BCL_OV518) + rc = ov518_i2c_read_internal(ov, reg); + else + rc = ov511_i2c_read_internal(ov, reg); + if (rc < 0) + return rc; + + oldval = (unsigned char) rc; + oldval &= (~mask); /* Clear the masked bits */ + value &= mask; /* Enforce mask on value */ + newval = oldval | value; /* Set the desired bits */ + } + + if (ov->bclass == BCL_OV518) + return (ov518_i2c_write_internal(ov, reg, newval)); + else + return (ov511_i2c_write_internal(ov, reg, newval)); +} + +/* Writes bits at positions specified by mask to an I2C reg. Bits that are in + * the same position as 1's in "mask" are cleared and set to "value". Bits + * that are in the same position as 0's in "mask" are preserved, regardless + * of their respective state in "value". + */ +static int +i2c_w_mask(struct usb_ov511 *ov, + unsigned char reg, + unsigned char value, + unsigned char mask) +{ + int rc; + + down(&ov->i2c_lock); + rc = ov51x_i2c_write_mask_internal(ov, reg, value, mask); + up(&ov->i2c_lock); + + return rc; +} + +/* Set the read and write slave IDs. The "slave" argument is the write slave, + * and the read slave will be set to (slave + 1). ov->i2c_lock should be held + * when calling this. This should not be called from outside the i2c I/O + * functions. + */ +static int +i2c_set_slave_internal(struct usb_ov511 *ov, unsigned char slave) +{ + int rc; + + rc = reg_w(ov, R51x_I2C_W_SID, slave); + if (rc < 0) + return rc; + + rc = reg_w(ov, R51x_I2C_R_SID, slave + 1); + if (rc < 0) + return rc; + + return 0; +} + +/* Write to a specific I2C slave ID and register, using the specified mask */ +static int +i2c_w_slave(struct usb_ov511 *ov, + unsigned char slave, + unsigned char reg, + unsigned char value, + unsigned char mask) +{ + int rc = 0; + + down(&ov->i2c_lock); + + /* Set new slave IDs */ + rc = i2c_set_slave_internal(ov, slave); + if (rc < 0) + goto out; + + rc = ov51x_i2c_write_mask_internal(ov, reg, value, mask); + +out: + /* Restore primary IDs */ + if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0) + err("Couldn't restore primary I2C slave"); + + up(&ov->i2c_lock); + return rc; +} + +/* Read from a specific I2C slave ID and register */ +static int +i2c_r_slave(struct usb_ov511 *ov, + unsigned char slave, + unsigned char reg) +{ + int rc; + + down(&ov->i2c_lock); + + /* Set new slave IDs */ + rc = i2c_set_slave_internal(ov, slave); + if (rc < 0) + goto out; + + if (ov->bclass == BCL_OV518) + rc = ov518_i2c_read_internal(ov, reg); + else + rc = ov511_i2c_read_internal(ov, reg); + +out: + /* Restore primary IDs */ + if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0) + err("Couldn't restore primary I2C slave"); + + up(&ov->i2c_lock); + return rc; +} + +/* Sets I2C read and write slave IDs. Returns <0 for error */ +static int +ov51x_set_slave_ids(struct usb_ov511 *ov, unsigned char sid) +{ + int rc; + + down(&ov->i2c_lock); + + rc = i2c_set_slave_internal(ov, sid); + if (rc < 0) + goto out; + + // FIXME: Is this actually necessary? + rc = ov51x_reset(ov, OV511_RESET_NOREGS); +out: + up(&ov->i2c_lock); + return rc; +} + +static int +write_regvals(struct usb_ov511 *ov, struct ov511_regvals * pRegvals) +{ + int rc; + + while (pRegvals->bus != OV511_DONE_BUS) { + if (pRegvals->bus == OV511_REG_BUS) { + if ((rc = reg_w(ov, pRegvals->reg, pRegvals->val)) < 0) + return rc; + } else if (pRegvals->bus == OV511_I2C_BUS) { + if ((rc = i2c_w(ov, pRegvals->reg, pRegvals->val)) < 0) + return rc; + } else { + err("Bad regval array"); + return -1; + } + pRegvals++; + } + return 0; +} + +#ifdef OV511_DEBUG +static void +dump_i2c_range(struct usb_ov511 *ov, int reg1, int regn) +{ + int i, rc; + + for (i = reg1; i <= regn; i++) { + rc = i2c_r(ov, i); + info("Sensor[0x%02X] = 0x%02X", i, rc); + } +} + +static void +dump_i2c_regs(struct usb_ov511 *ov) +{ + info("I2C REGS"); + dump_i2c_range(ov, 0x00, 0x7C); +} + +static void +dump_reg_range(struct usb_ov511 *ov, int reg1, int regn) +{ + int i, rc; + + for (i = reg1; i <= regn; i++) { + rc = reg_r(ov, i); + info("OV511[0x%02X] = 0x%02X", i, rc); + } +} + +static void +ov511_dump_regs(struct usb_ov511 *ov) +{ + info("CAMERA INTERFACE REGS"); + dump_reg_range(ov, 0x10, 0x1f); + info("DRAM INTERFACE REGS"); + dump_reg_range(ov, 0x20, 0x23); + info("ISO FIFO REGS"); + dump_reg_range(ov, 0x30, 0x31); + info("PIO REGS"); + dump_reg_range(ov, 0x38, 0x39); + dump_reg_range(ov, 0x3e, 0x3e); + info("I2C REGS"); + dump_reg_range(ov, 0x40, 0x49); + info("SYSTEM CONTROL REGS"); + dump_reg_range(ov, 0x50, 0x55); + dump_reg_range(ov, 0x5e, 0x5f); + info("OmniCE REGS"); + dump_reg_range(ov, 0x70, 0x79); + /* NOTE: Quantization tables are not readable. You will get the value + * in reg. 0x79 for every table register */ + dump_reg_range(ov, 0x80, 0x9f); + dump_reg_range(ov, 0xa0, 0xbf); + +} + +static void +ov518_dump_regs(struct usb_ov511 *ov) +{ + info("VIDEO MODE REGS"); + dump_reg_range(ov, 0x20, 0x2f); + info("DATA PUMP AND SNAPSHOT REGS"); + dump_reg_range(ov, 0x30, 0x3f); + info("I2C REGS"); + dump_reg_range(ov, 0x40, 0x4f); + info("SYSTEM CONTROL AND VENDOR REGS"); + dump_reg_range(ov, 0x50, 0x5f); + info("60 - 6F"); + dump_reg_range(ov, 0x60, 0x6f); + info("70 - 7F"); + dump_reg_range(ov, 0x70, 0x7f); + info("Y QUANTIZATION TABLE"); + dump_reg_range(ov, 0x80, 0x8f); + info("UV QUANTIZATION TABLE"); + dump_reg_range(ov, 0x90, 0x9f); + info("A0 - BF"); + dump_reg_range(ov, 0xa0, 0xbf); + info("CBR"); + dump_reg_range(ov, 0xc0, 0xcf); +} +#endif + +/*****************************************************************************/ + +/* Temporarily stops OV511 from functioning. Must do this before changing + * registers while the camera is streaming */ +static inline int +ov51x_stop(struct usb_ov511 *ov) +{ + PDEBUG(4, "stopping"); + ov->stopped = 1; + if (ov->bclass == BCL_OV518) + return (reg_w_mask(ov, R51x_SYS_RESET, 0x3a, 0x3a)); + else + return (reg_w(ov, R51x_SYS_RESET, 0x3d)); +} + +/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not + * actually stopped (for performance). */ +static inline int +ov51x_restart(struct usb_ov511 *ov) +{ + if (ov->stopped) { + PDEBUG(4, "restarting"); + ov->stopped = 0; + + /* Reinitialize the stream */ + if (ov->bclass == BCL_OV518) + reg_w(ov, 0x2f, 0x80); + + return (reg_w(ov, R51x_SYS_RESET, 0x00)); + } + + return 0; +} + +/* Sleeps until no frames are active. Returns !0 if got signal */ +static int +ov51x_wait_frames_inactive(struct usb_ov511 *ov) +{ + return wait_event_interruptible(ov->wq, ov->curframe < 0); +} + +/* Resets the hardware snapshot button */ +static void +ov51x_clear_snapshot(struct usb_ov511 *ov) +{ + if (ov->bclass == BCL_OV511) { + reg_w(ov, R51x_SYS_SNAP, 0x00); + reg_w(ov, R51x_SYS_SNAP, 0x02); + reg_w(ov, R51x_SYS_SNAP, 0x00); + } else if (ov->bclass == BCL_OV518) { + warn("snapshot reset not supported yet on OV518(+)"); + } else { + err("clear snap: invalid bridge type"); + } +} + +#if 0 +/* Checks the status of the snapshot button. Returns 1 if it was pressed since + * it was last cleared, and zero in all other cases (including errors) */ +static int +ov51x_check_snapshot(struct usb_ov511 *ov) +{ + int ret, status = 0; + + if (ov->bclass == BCL_OV511) { + ret = reg_r(ov, R51x_SYS_SNAP); + if (ret < 0) { + err("Error checking snspshot status (%d)", ret); + } else if (ret & 0x08) { + status = 1; + } + } else if (ov->bclass == BCL_OV518) { + warn("snapshot check not supported yet on OV518(+)"); + } else { + err("check snap: invalid bridge type"); + } + + return status; +} +#endif + +/* This does an initial reset of an OmniVision sensor and ensures that I2C + * is synchronized. Returns <0 for failure. + */ +static int +init_ov_sensor(struct usb_ov511 *ov) +{ + int i, success; + + /* Reset the sensor */ + if (i2c_w(ov, 0x12, 0x80) < 0) + return -EIO; + + /* Wait for it to initialize */ + msleep(150); + + for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) { + if ((i2c_r(ov, OV7610_REG_ID_HIGH) == 0x7F) && + (i2c_r(ov, OV7610_REG_ID_LOW) == 0xA2)) { + success = 1; + continue; + } + + /* Reset the sensor */ + if (i2c_w(ov, 0x12, 0x80) < 0) + return -EIO; + /* Wait for it to initialize */ + msleep(150); + /* Dummy read to sync I2C */ + if (i2c_r(ov, 0x00) < 0) + return -EIO; + } + + if (!success) + return -EIO; + + PDEBUG(1, "I2C synced in %d attempt(s)", i); + + return 0; +} + +static int +ov511_set_packet_size(struct usb_ov511 *ov, int size) +{ + int alt, mult; + + if (ov51x_stop(ov) < 0) + return -EIO; + + mult = size >> 5; + + if (ov->bridge == BRG_OV511) { + if (size == 0) + alt = OV511_ALT_SIZE_0; + else if (size == 257) + alt = OV511_ALT_SIZE_257; + else if (size == 513) + alt = OV511_ALT_SIZE_513; + else if (size == 769) + alt = OV511_ALT_SIZE_769; + else if (size == 993) + alt = OV511_ALT_SIZE_993; + else { + err("Set packet size: invalid size (%d)", size); + return -EINVAL; + } + } else if (ov->bridge == BRG_OV511PLUS) { + if (size == 0) + alt = OV511PLUS_ALT_SIZE_0; + else if (size == 33) + alt = OV511PLUS_ALT_SIZE_33; + else if (size == 129) + alt = OV511PLUS_ALT_SIZE_129; + else if (size == 257) + alt = OV511PLUS_ALT_SIZE_257; + else if (size == 385) + alt = OV511PLUS_ALT_SIZE_385; + else if (size == 513) + alt = OV511PLUS_ALT_SIZE_513; + else if (size == 769) + alt = OV511PLUS_ALT_SIZE_769; + else if (size == 961) + alt = OV511PLUS_ALT_SIZE_961; + else { + err("Set packet size: invalid size (%d)", size); + return -EINVAL; + } + } else { + err("Set packet size: Invalid bridge type"); + return -EINVAL; + } + + PDEBUG(3, "%d, mult=%d, alt=%d", size, mult, alt); + + if (reg_w(ov, R51x_FIFO_PSIZE, mult) < 0) + return -EIO; + + if (usb_set_interface(ov->dev, ov->iface, alt) < 0) { + err("Set packet size: set interface error"); + return -EBUSY; + } + + if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0) + return -EIO; + + ov->packet_size = size; + + if (ov51x_restart(ov) < 0) + return -EIO; + + return 0; +} + +/* Note: Unlike the OV511/OV511+, the size argument does NOT include the + * optional packet number byte. The actual size *is* stored in ov->packet_size, + * though. */ +static int +ov518_set_packet_size(struct usb_ov511 *ov, int size) +{ + int alt; + + if (ov51x_stop(ov) < 0) + return -EIO; + + if (ov->bclass == BCL_OV518) { + if (size == 0) + alt = OV518_ALT_SIZE_0; + else if (size == 128) + alt = OV518_ALT_SIZE_128; + else if (size == 256) + alt = OV518_ALT_SIZE_256; + else if (size == 384) + alt = OV518_ALT_SIZE_384; + else if (size == 512) + alt = OV518_ALT_SIZE_512; + else if (size == 640) + alt = OV518_ALT_SIZE_640; + else if (size == 768) + alt = OV518_ALT_SIZE_768; + else if (size == 896) + alt = OV518_ALT_SIZE_896; + else { + err("Set packet size: invalid size (%d)", size); + return -EINVAL; + } + } else { + err("Set packet size: Invalid bridge type"); + return -EINVAL; + } + + PDEBUG(3, "%d, alt=%d", size, alt); + + ov->packet_size = size; + if (size > 0) { + /* Program ISO FIFO size reg (packet number isn't included) */ + ov518_reg_w32(ov, 0x30, size, 2); + + if (ov->packet_numbering) + ++ov->packet_size; + } + + if (usb_set_interface(ov->dev, ov->iface, alt) < 0) { + err("Set packet size: set interface error"); + return -EBUSY; + } + + /* Initialize the stream */ + if (reg_w(ov, 0x2f, 0x80) < 0) + return -EIO; + + if (ov51x_restart(ov) < 0) + return -EIO; + + if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0) + return -EIO; + + return 0; +} + +/* Upload compression params and quantization tables. Returns 0 for success. */ +static int +ov511_init_compression(struct usb_ov511 *ov) +{ + int rc = 0; + + if (!ov->compress_inited) { + reg_w(ov, 0x70, phy); + reg_w(ov, 0x71, phuv); + reg_w(ov, 0x72, pvy); + reg_w(ov, 0x73, pvuv); + reg_w(ov, 0x74, qhy); + reg_w(ov, 0x75, qhuv); + reg_w(ov, 0x76, qvy); + reg_w(ov, 0x77, qvuv); + + if (ov511_upload_quan_tables(ov) < 0) { + err("Error uploading quantization tables"); + rc = -EIO; + goto out; + } + } + + ov->compress_inited = 1; +out: + return rc; +} + +/* Upload compression params and quantization tables. Returns 0 for success. */ +static int +ov518_init_compression(struct usb_ov511 *ov) +{ + int rc = 0; + + if (!ov->compress_inited) { + if (ov518_upload_quan_tables(ov) < 0) { + err("Error uploading quantization tables"); + rc = -EIO; + goto out; + } + } + + ov->compress_inited = 1; +out: + return rc; +} + +/* -------------------------------------------------------------------------- */ + +/* Sets sensor's contrast setting to "val" */ +static int +sensor_set_contrast(struct usb_ov511 *ov, unsigned short val) +{ + int rc; + + PDEBUG(3, "%d", val); + + if (ov->stop_during_set) + if (ov51x_stop(ov) < 0) + return -EIO; + + switch (ov->sensor) { + case SEN_OV7610: + case SEN_OV6620: + { + rc = i2c_w(ov, OV7610_REG_CNT, val >> 8); + if (rc < 0) + goto out; + break; + } + case SEN_OV6630: + { + rc = i2c_w_mask(ov, OV7610_REG_CNT, val >> 12, 0x0f); + if (rc < 0) + goto out; + break; + } + case SEN_OV7620: + { + unsigned char ctab[] = { + 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57, + 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff + }; + + /* Use Y gamma control instead. Bit 0 enables it. */ + rc = i2c_w(ov, 0x64, ctab[val>>12]); + if (rc < 0) + goto out; + break; + } + case SEN_SAA7111A: + { + rc = i2c_w(ov, 0x0b, val >> 9); + if (rc < 0) + goto out; + break; + } + default: + { + PDEBUG(3, "Unsupported with this sensor"); + rc = -EPERM; + goto out; + } + } + + rc = 0; /* Success */ + ov->contrast = val; +out: + if (ov51x_restart(ov) < 0) + return -EIO; + + return rc; +} + +/* Gets sensor's contrast setting */ +static int +sensor_get_contrast(struct usb_ov511 *ov, unsigned short *val) +{ + int rc; + + switch (ov->sensor) { + case SEN_OV7610: + case SEN_OV6620: + rc = i2c_r(ov, OV7610_REG_CNT); + if (rc < 0) + return rc; + else + *val = rc << 8; + break; + case SEN_OV6630: + rc = i2c_r(ov, OV7610_REG_CNT); + if (rc < 0) + return rc; + else + *val = rc << 12; + break; + case SEN_OV7620: + /* Use Y gamma reg instead. Bit 0 is the enable bit. */ + rc = i2c_r(ov, 0x64); + if (rc < 0) + return rc; + else + *val = (rc & 0xfe) << 8; + break; + case SEN_SAA7111A: + *val = ov->contrast; + break; + default: + PDEBUG(3, "Unsupported with this sensor"); + return -EPERM; + } + + PDEBUG(3, "%d", *val); + ov->contrast = *val; + + return 0; +} + +/* -------------------------------------------------------------------------- */ + +/* Sets sensor's brightness setting to "val" */ +static int +sensor_set_brightness(struct usb_ov511 *ov, unsigned short val) +{ + int rc; + + PDEBUG(4, "%d", val); + + if (ov->stop_during_set) + if (ov51x_stop(ov) < 0) + return -EIO; + + switch (ov->sensor) { + case SEN_OV7610: + case SEN_OV76BE: + case SEN_OV6620: + case SEN_OV6630: + rc = i2c_w(ov, OV7610_REG_BRT, val >> 8); + if (rc < 0) + goto out; + break; + case SEN_OV7620: + /* 7620 doesn't like manual changes when in auto mode */ + if (!ov->auto_brt) { + rc = i2c_w(ov, OV7610_REG_BRT, val >> 8); + if (rc < 0) + goto out; + } + break; + case SEN_SAA7111A: + rc = i2c_w(ov, 0x0a, val >> 8); + if (rc < 0) + goto out; + break; + default: + PDEBUG(3, "Unsupported with this sensor"); + rc = -EPERM; + goto out; + } + + rc = 0; /* Success */ + ov->brightness = val; +out: + if (ov51x_restart(ov) < 0) + return -EIO; + + return rc; +} + +/* Gets sensor's brightness setting */ +static int +sensor_get_brightness(struct usb_ov511 *ov, unsigned short *val) +{ + int rc; + + switch (ov->sensor) { + case SEN_OV7610: + case SEN_OV76BE: + case SEN_OV7620: + case SEN_OV6620: + case SEN_OV6630: + rc = i2c_r(ov, OV7610_REG_BRT); + if (rc < 0) + return rc; + else + *val = rc << 8; + break; + case SEN_SAA7111A: + *val = ov->brightness; + break; + default: + PDEBUG(3, "Unsupported with this sensor"); + return -EPERM; + } + + PDEBUG(3, "%d", *val); + ov->brightness = *val; + + return 0; +} + +/* -------------------------------------------------------------------------- */ + +/* Sets sensor's saturation (color intensity) setting to "val" */ +static int +sensor_set_saturation(struct usb_ov511 *ov, unsigned short val) +{ + int rc; + + PDEBUG(3, "%d", val); + + if (ov->stop_during_set) + if (ov51x_stop(ov) < 0) + return -EIO; + + switch (ov->sensor) { + case SEN_OV7610: + case SEN_OV76BE: + case SEN_OV6620: + case SEN_OV6630: + rc = i2c_w(ov, OV7610_REG_SAT, val >> 8); + if (rc < 0) + goto out; + break; + case SEN_OV7620: +// /* Use UV gamma control instead. Bits 0 & 7 are reserved. */ +// rc = ov_i2c_write(ov->dev, 0x62, (val >> 9) & 0x7e); +// if (rc < 0) +// goto out; + rc = i2c_w(ov, OV7610_REG_SAT, val >> 8); + if (rc < 0) + goto out; + break; + case SEN_SAA7111A: + rc = i2c_w(ov, 0x0c, val >> 9); + if (rc < 0) + goto out; + break; + default: + PDEBUG(3, "Unsupported with this sensor"); + rc = -EPERM; + goto out; + } + + rc = 0; /* Success */ + ov->colour = val; +out: + if (ov51x_restart(ov) < 0) + return -EIO; + + return rc; +} + +/* Gets sensor's saturation (color intensity) setting */ +static int +sensor_get_saturation(struct usb_ov511 *ov, unsigned short *val) +{ + int rc; + + switch (ov->sensor) { + case SEN_OV7610: + case SEN_OV76BE: + case SEN_OV6620: + case SEN_OV6630: + rc = i2c_r(ov, OV7610_REG_SAT); + if (rc < 0) + return rc; + else + *val = rc << 8; + break; + case SEN_OV7620: +// /* Use UV gamma reg instead. Bits 0 & 7 are reserved. */ +// rc = i2c_r(ov, 0x62); +// if (rc < 0) +// return rc; +// else +// *val = (rc & 0x7e) << 9; + rc = i2c_r(ov, OV7610_REG_SAT); + if (rc < 0) + return rc; + else + *val = rc << 8; + break; + case SEN_SAA7111A: + *val = ov->colour; + break; + default: + PDEBUG(3, "Unsupported with this sensor"); + return -EPERM; + } + + PDEBUG(3, "%d", *val); + ov->colour = *val; + + return 0; +} + +/* -------------------------------------------------------------------------- */ + +/* Sets sensor's hue (red/blue balance) setting to "val" */ +static int +sensor_set_hue(struct usb_ov511 *ov, unsigned short val) +{ + int rc; + + PDEBUG(3, "%d", val); + + if (ov->stop_during_set) + if (ov51x_stop(ov) < 0) + return -EIO; + + switch (ov->sensor) { + case SEN_OV7610: + case SEN_OV6620: + case SEN_OV6630: + rc = i2c_w(ov, OV7610_REG_RED, 0xFF - (val >> 8)); + if (rc < 0) + goto out; + + rc = i2c_w(ov, OV7610_REG_BLUE, val >> 8); + if (rc < 0) + goto out; + break; + case SEN_OV7620: +// Hue control is causing problems. I will enable it once it's fixed. +#if 0 + rc = i2c_w(ov, 0x7a, (unsigned char)(val >> 8) + 0xb); + if (rc < 0) + goto out; + + rc = i2c_w(ov, 0x79, (unsigned char)(val >> 8) + 0xb); + if (rc < 0) + goto out; +#endif + break; + case SEN_SAA7111A: + rc = i2c_w(ov, 0x0d, (val + 32768) >> 8); + if (rc < 0) + goto out; + break; + default: + PDEBUG(3, "Unsupported with this sensor"); + rc = -EPERM; + goto out; + } + + rc = 0; /* Success */ + ov->hue = val; +out: + if (ov51x_restart(ov) < 0) + return -EIO; + + return rc; +} + +/* Gets sensor's hue (red/blue balance) setting */ +static int +sensor_get_hue(struct usb_ov511 *ov, unsigned short *val) +{ + int rc; + + switch (ov->sensor) { + case SEN_OV7610: + case SEN_OV6620: + case SEN_OV6630: + rc = i2c_r(ov, OV7610_REG_BLUE); + if (rc < 0) + return rc; + else + *val = rc << 8; + break; + case SEN_OV7620: + rc = i2c_r(ov, 0x7a); + if (rc < 0) + return rc; + else + *val = rc << 8; + break; + case SEN_SAA7111A: + *val = ov->hue; + break; + default: + PDEBUG(3, "Unsupported with this sensor"); + return -EPERM; + } + + PDEBUG(3, "%d", *val); + ov->hue = *val; + + return 0; +} + +/* -------------------------------------------------------------------------- */ + +static int +sensor_set_picture(struct usb_ov511 *ov, struct video_picture *p) +{ + int rc; + + PDEBUG(4, "sensor_set_picture"); + + ov->whiteness = p->whiteness; + + /* Don't return error if a setting is unsupported, or rest of settings + * will not be performed */ + + rc = sensor_set_contrast(ov, p->contrast); + if (FATAL_ERROR(rc)) + return rc; + + rc = sensor_set_brightness(ov, p->brightness); + if (FATAL_ERROR(rc)) + return rc; + + rc = sensor_set_saturation(ov, p->colour); + if (FATAL_ERROR(rc)) + return rc; + + rc = sensor_set_hue(ov, p->hue); + if (FATAL_ERROR(rc)) + return rc; + + return 0; +} + +static int +sensor_get_picture(struct usb_ov511 *ov, struct video_picture *p) +{ + int rc; + + PDEBUG(4, "sensor_get_picture"); + + /* Don't return error if a setting is unsupported, or rest of settings + * will not be performed */ + + rc = sensor_get_contrast(ov, &(p->contrast)); + if (FATAL_ERROR(rc)) + return rc; + + rc = sensor_get_brightness(ov, &(p->brightness)); + if (FATAL_ERROR(rc)) + return rc; + + rc = sensor_get_saturation(ov, &(p->colour)); + if (FATAL_ERROR(rc)) + return rc; + + rc = sensor_get_hue(ov, &(p->hue)); + if (FATAL_ERROR(rc)) + return rc; + + p->whiteness = 105 << 8; + + return 0; +} + +#if 0 +// FIXME: Exposure range is only 0x00-0x7f in interlace mode +/* Sets current exposure for sensor. This only has an effect if auto-exposure + * is off */ +static inline int +sensor_set_exposure(struct usb_ov511 *ov, unsigned char val) +{ + int rc; + + PDEBUG(3, "%d", val); + + if (ov->stop_during_set) + if (ov51x_stop(ov) < 0) + return -EIO; + + switch (ov->sensor) { + case SEN_OV6620: + case SEN_OV6630: + case SEN_OV7610: + case SEN_OV7620: + case SEN_OV76BE: + case SEN_OV8600: + rc = i2c_w(ov, 0x10, val); + if (rc < 0) + goto out; + + break; + case SEN_KS0127: + case SEN_KS0127B: + case SEN_SAA7111A: + PDEBUG(3, "Unsupported with this sensor"); + return -EPERM; + default: + err("Sensor not supported for set_exposure"); + return -EINVAL; + } + + rc = 0; /* Success */ + ov->exposure = val; +out: + if (ov51x_restart(ov) < 0) + return -EIO; + + return rc; +} +#endif + +/* Gets current exposure level from sensor, regardless of whether it is under + * manual control. */ +static int +sensor_get_exposure(struct usb_ov511 *ov, unsigned char *val) +{ + int rc; + + switch (ov->sensor) { + case SEN_OV7610: + case SEN_OV6620: + case SEN_OV6630: + case SEN_OV7620: + case SEN_OV76BE: + case SEN_OV8600: + rc = i2c_r(ov, 0x10); + if (rc < 0) + return rc; + else + *val = rc; + break; + case SEN_KS0127: + case SEN_KS0127B: + case SEN_SAA7111A: + val = NULL; + PDEBUG(3, "Unsupported with this sensor"); + return -EPERM; + default: + err("Sensor not supported for get_exposure"); + return -EINVAL; + } + + PDEBUG(3, "%d", *val); + ov->exposure = *val; + + return 0; +} + +/* Turns on or off the LED. Only has an effect with OV511+/OV518(+) */ +static void +ov51x_led_control(struct usb_ov511 *ov, int enable) +{ + PDEBUG(4, " (%s)", enable ? "turn on" : "turn off"); + + if (ov->bridge == BRG_OV511PLUS) + reg_w(ov, R511_SYS_LED_CTL, enable ? 1 : 0); + else if (ov->bclass == BCL_OV518) + reg_w_mask(ov, R518_GPIO_OUT, enable ? 0x02 : 0x00, 0x02); + + return; +} + +/* Matches the sensor's internal frame rate to the lighting frequency. + * Valid frequencies are: + * 50 - 50Hz, for European and Asian lighting + * 60 - 60Hz, for American lighting + * + * Tested with: OV7610, OV7620, OV76BE, OV6620 + * Unsupported: KS0127, KS0127B, SAA7111A + * Returns: 0 for success + */ +static int +sensor_set_light_freq(struct usb_ov511 *ov, int freq) +{ + int sixty; + + PDEBUG(4, "%d Hz", freq); + + if (freq == 60) + sixty = 1; + else if (freq == 50) + sixty = 0; + else { + err("Invalid light freq (%d Hz)", freq); + return -EINVAL; + } + + switch (ov->sensor) { + case SEN_OV7610: + i2c_w_mask(ov, 0x2a, sixty?0x00:0x80, 0x80); + i2c_w(ov, 0x2b, sixty?0x00:0xac); + i2c_w_mask(ov, 0x13, 0x10, 0x10); + i2c_w_mask(ov, 0x13, 0x00, 0x10); + break; + case SEN_OV7620: + case SEN_OV76BE: + case SEN_OV8600: + i2c_w_mask(ov, 0x2a, sixty?0x00:0x80, 0x80); + i2c_w(ov, 0x2b, sixty?0x00:0xac); + i2c_w_mask(ov, 0x76, 0x01, 0x01); + break; + case SEN_OV6620: + case SEN_OV6630: + i2c_w(ov, 0x2b, sixty?0xa8:0x28); + i2c_w(ov, 0x2a, sixty?0x84:0xa4); + break; + case SEN_KS0127: + case SEN_KS0127B: + case SEN_SAA7111A: + PDEBUG(5, "Unsupported with this sensor"); + return -EPERM; + default: + err("Sensor not supported for set_light_freq"); + return -EINVAL; + } + + ov->lightfreq = freq; + + return 0; +} + +/* If enable is true, turn on the sensor's banding filter, otherwise turn it + * off. This filter tries to reduce the pattern of horizontal light/dark bands + * caused by some (usually fluorescent) lighting. The light frequency must be + * set either before or after enabling it with ov51x_set_light_freq(). + * + * Tested with: OV7610, OV7620, OV76BE, OV6620. + * Unsupported: KS0127, KS0127B, SAA7111A + * Returns: 0 for success + */ +static int +sensor_set_banding_filter(struct usb_ov511 *ov, int enable) +{ + int rc; + + PDEBUG(4, " (%s)", enable ? "turn on" : "turn off"); + + if (ov->sensor == SEN_KS0127 || ov->sensor == SEN_KS0127B + || ov->sensor == SEN_SAA7111A) { + PDEBUG(5, "Unsupported with this sensor"); + return -EPERM; + } + + rc = i2c_w_mask(ov, 0x2d, enable?0x04:0x00, 0x04); + if (rc < 0) + return rc; + + ov->bandfilt = enable; + + return 0; +} + +/* If enable is true, turn on the sensor's auto brightness control, otherwise + * turn it off. + * + * Unsupported: KS0127, KS0127B, SAA7111A + * Returns: 0 for success + */ +static int +sensor_set_auto_brightness(struct usb_ov511 *ov, int enable) +{ + int rc; + + PDEBUG(4, " (%s)", enable ? "turn on" : "turn off"); + + if (ov->sensor == SEN_KS0127 || ov->sensor == SEN_KS0127B + || ov->sensor == SEN_SAA7111A) { + PDEBUG(5, "Unsupported with this sensor"); + return -EPERM; + } + + rc = i2c_w_mask(ov, 0x2d, enable?0x10:0x00, 0x10); + if (rc < 0) + return rc; + + ov->auto_brt = enable; + + return 0; +} + +/* If enable is true, turn on the sensor's auto exposure control, otherwise + * turn it off. + * + * Unsupported: KS0127, KS0127B, SAA7111A + * Returns: 0 for success + */ +static int +sensor_set_auto_exposure(struct usb_ov511 *ov, int enable) +{ + PDEBUG(4, " (%s)", enable ? "turn on" : "turn off"); + + switch (ov->sensor) { + case SEN_OV7610: + i2c_w_mask(ov, 0x29, enable?0x00:0x80, 0x80); + break; + case SEN_OV6620: + case SEN_OV7620: + case SEN_OV76BE: + case SEN_OV8600: + i2c_w_mask(ov, 0x13, enable?0x01:0x00, 0x01); + break; + case SEN_OV6630: + i2c_w_mask(ov, 0x28, enable?0x00:0x10, 0x10); + break; + case SEN_KS0127: + case SEN_KS0127B: + case SEN_SAA7111A: + PDEBUG(5, "Unsupported with this sensor"); + return -EPERM; + default: + err("Sensor not supported for set_auto_exposure"); + return -EINVAL; + } + + ov->auto_exp = enable; + + return 0; +} + +/* Modifies the sensor's exposure algorithm to allow proper exposure of objects + * that are illuminated from behind. + * + * Tested with: OV6620, OV7620 + * Unsupported: OV7610, OV76BE, KS0127, KS0127B, SAA7111A + * Returns: 0 for success + */ +static int +sensor_set_backlight(struct usb_ov511 *ov, int enable) +{ + PDEBUG(4, " (%s)", enable ? "turn on" : "turn off"); + + switch (ov->sensor) { + case SEN_OV7620: + case SEN_OV8600: + i2c_w_mask(ov, 0x68, enable?0xe0:0xc0, 0xe0); + i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08); + i2c_w_mask(ov, 0x28, enable?0x02:0x00, 0x02); + break; + case SEN_OV6620: + i2c_w_mask(ov, 0x4e, enable?0xe0:0xc0, 0xe0); + i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08); + i2c_w_mask(ov, 0x0e, enable?0x80:0x00, 0x80); + break; + case SEN_OV6630: + i2c_w_mask(ov, 0x4e, enable?0x80:0x60, 0xe0); + i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08); + i2c_w_mask(ov, 0x28, enable?0x02:0x00, 0x02); + break; + case SEN_OV7610: + case SEN_OV76BE: + case SEN_KS0127: + case SEN_KS0127B: + case SEN_SAA7111A: + PDEBUG(5, "Unsupported with this sensor"); + return -EPERM; + default: + err("Sensor not supported for set_backlight"); + return -EINVAL; + } + + ov->backlight = enable; + + return 0; +} + +static int +sensor_set_mirror(struct usb_ov511 *ov, int enable) +{ + PDEBUG(4, " (%s)", enable ? "turn on" : "turn off"); + + switch (ov->sensor) { + case SEN_OV6620: + case SEN_OV6630: + case SEN_OV7610: + case SEN_OV7620: + case SEN_OV76BE: + case SEN_OV8600: + i2c_w_mask(ov, 0x12, enable?0x40:0x00, 0x40); + break; + case SEN_KS0127: + case SEN_KS0127B: + case SEN_SAA7111A: + PDEBUG(5, "Unsupported with this sensor"); + return -EPERM; + default: + err("Sensor not supported for set_mirror"); + return -EINVAL; + } + + ov->mirror = enable; + + return 0; +} + +/* Returns number of bits per pixel (regardless of where they are located; + * planar or not), or zero for unsupported format. + */ +static inline int +get_depth(int palette) +{ + switch (palette) { + case VIDEO_PALETTE_GREY: return 8; + case VIDEO_PALETTE_YUV420: return 12; + case VIDEO_PALETTE_YUV420P: return 12; /* Planar */ + default: return 0; /* Invalid format */ + } +} + +/* Bytes per frame. Used by read(). Return of 0 indicates error */ +static inline long int +get_frame_length(struct ov511_frame *frame) +{ + if (!frame) + return 0; + else + return ((frame->width * frame->height + * get_depth(frame->format)) >> 3); +} + +static int +mode_init_ov_sensor_regs(struct usb_ov511 *ov, int width, int height, + int mode, int sub_flag, int qvga) +{ + int clock; + + /******** Mode (VGA/QVGA) and sensor specific regs ********/ + + switch (ov->sensor) { + case SEN_OV7610: + i2c_w(ov, 0x14, qvga?0x24:0x04); +// FIXME: Does this improve the image quality or frame rate? +#if 0 + i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20); + i2c_w(ov, 0x24, 0x10); + i2c_w(ov, 0x25, qvga?0x40:0x8a); + i2c_w(ov, 0x2f, qvga?0x30:0xb0); + i2c_w(ov, 0x35, qvga?0x1c:0x9c); +#endif + break; + case SEN_OV7620: +// i2c_w(ov, 0x2b, 0x00); + i2c_w(ov, 0x14, qvga?0xa4:0x84); + i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20); + i2c_w(ov, 0x24, qvga?0x20:0x3a); + i2c_w(ov, 0x25, qvga?0x30:0x60); + i2c_w_mask(ov, 0x2d, qvga?0x40:0x00, 0x40); + i2c_w_mask(ov, 0x67, qvga?0xf0:0x90, 0xf0); + i2c_w_mask(ov, 0x74, qvga?0x20:0x00, 0x20); + break; + case SEN_OV76BE: +// i2c_w(ov, 0x2b, 0x00); + i2c_w(ov, 0x14, qvga?0xa4:0x84); +// FIXME: Enable this once 7620AE uses 7620 initial settings +#if 0 + i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20); + i2c_w(ov, 0x24, qvga?0x20:0x3a); + i2c_w(ov, 0x25, qvga?0x30:0x60); + i2c_w_mask(ov, 0x2d, qvga?0x40:0x00, 0x40); + i2c_w_mask(ov, 0x67, qvga?0xb0:0x90, 0xf0); + i2c_w_mask(ov, 0x74, qvga?0x20:0x00, 0x20); +#endif + break; + case SEN_OV6620: + i2c_w(ov, 0x14, qvga?0x24:0x04); + break; + case SEN_OV6630: + i2c_w(ov, 0x14, qvga?0xa0:0x80); + break; + default: + err("Invalid sensor"); + return -EINVAL; + } + + /******** Palette-specific regs ********/ + + if (mode == VIDEO_PALETTE_GREY) { + if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV76BE) { + /* these aren't valid on the OV6620/OV7620/6630? */ + i2c_w_mask(ov, 0x0e, 0x40, 0x40); + } + + if (ov->sensor == SEN_OV6630 && ov->bridge == BRG_OV518 + && ov518_color) { + i2c_w_mask(ov, 0x12, 0x00, 0x10); + i2c_w_mask(ov, 0x13, 0x00, 0x20); + } else { + i2c_w_mask(ov, 0x13, 0x20, 0x20); + } + } else { + if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV76BE) { + /* not valid on the OV6620/OV7620/6630? */ + i2c_w_mask(ov, 0x0e, 0x00, 0x40); + } + + /* The OV518 needs special treatment. Although both the OV518 + * and the OV6630 support a 16-bit video bus, only the 8 bit Y + * bus is actually used. The UV bus is tied to ground. + * Therefore, the OV6630 needs to be in 8-bit multiplexed + * output mode */ + + if (ov->sensor == SEN_OV6630 && ov->bridge == BRG_OV518 + && ov518_color) { + i2c_w_mask(ov, 0x12, 0x10, 0x10); + i2c_w_mask(ov, 0x13, 0x20, 0x20); + } else { + i2c_w_mask(ov, 0x13, 0x00, 0x20); + } + } + + /******** Clock programming ********/ + + /* The OV6620 needs special handling. This prevents the + * severe banding that normally occurs */ + if (ov->sensor == SEN_OV6620 || ov->sensor == SEN_OV6630) + { + /* Clock down */ + + i2c_w(ov, 0x2a, 0x04); + + if (ov->compress) { +// clock = 0; /* This ensures the highest frame rate */ + clock = 3; + } else if (clockdiv == -1) { /* If user didn't override it */ + clock = 3; /* Gives better exposure time */ + } else { + clock = clockdiv; + } + + PDEBUG(4, "Setting clock divisor to %d", clock); + + i2c_w(ov, 0x11, clock); + + i2c_w(ov, 0x2a, 0x84); + /* This next setting is critical. It seems to improve + * the gain or the contrast. The "reserved" bits seem + * to have some effect in this case. */ + i2c_w(ov, 0x2d, 0x85); + } + else + { + if (ov->compress) { + clock = 1; /* This ensures the highest frame rate */ + } else if (clockdiv == -1) { /* If user didn't override it */ + /* Calculate and set the clock divisor */ + clock = ((sub_flag ? ov->subw * ov->subh + : width * height) + * (mode == VIDEO_PALETTE_GREY ? 2 : 3) / 2) + / 66000; + } else { + clock = clockdiv; + } + + PDEBUG(4, "Setting clock divisor to %d", clock); + + i2c_w(ov, 0x11, clock); + } + + /******** Special Features ********/ + + if (framedrop >= 0) + i2c_w(ov, 0x16, framedrop); + + /* Test Pattern */ + i2c_w_mask(ov, 0x12, (testpat?0x02:0x00), 0x02); + + /* Enable auto white balance */ + i2c_w_mask(ov, 0x12, 0x04, 0x04); + + // This will go away as soon as ov51x_mode_init_sensor_regs() + // is fully tested. + /* 7620/6620/6630? don't have register 0x35, so play it safe */ + if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV76BE) { + if (width == 640 && height == 480) + i2c_w(ov, 0x35, 0x9e); + else + i2c_w(ov, 0x35, 0x1e); + } + + return 0; +} + +static int +set_ov_sensor_window(struct usb_ov511 *ov, int width, int height, int mode, + int sub_flag) +{ + int ret; + int hwsbase, hwebase, vwsbase, vwebase, hwsize, vwsize; + int hoffset, voffset, hwscale = 0, vwscale = 0; + + /* The different sensor ICs handle setting up of window differently. + * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!!! */ + switch (ov->sensor) { + case SEN_OV7610: + case SEN_OV76BE: + hwsbase = 0x38; + hwebase = 0x3a; + vwsbase = vwebase = 0x05; + break; + case SEN_OV6620: + case SEN_OV6630: + hwsbase = 0x38; + hwebase = 0x3a; + vwsbase = 0x05; + vwebase = 0x06; + break; + case SEN_OV7620: + hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */ + hwebase = 0x2f; + vwsbase = vwebase = 0x05; + break; + default: + err("Invalid sensor"); + return -EINVAL; + } + + if (ov->sensor == SEN_OV6620 || ov->sensor == SEN_OV6630) { + /* Note: OV518(+) does downsample on its own) */ + if ((width > 176 && height > 144) + || ov->bclass == BCL_OV518) { /* CIF */ + ret = mode_init_ov_sensor_regs(ov, width, height, + mode, sub_flag, 0); + if (ret < 0) + return ret; + hwscale = 1; + vwscale = 1; /* The datasheet says 0; it's wrong */ + hwsize = 352; + vwsize = 288; + } else if (width > 176 || height > 144) { + err("Illegal dimensions"); + return -EINVAL; + } else { /* QCIF */ + ret = mode_init_ov_sensor_regs(ov, width, height, + mode, sub_flag, 1); + if (ret < 0) + return ret; + hwsize = 176; + vwsize = 144; + } + } else { + if (width > 320 && height > 240) { /* VGA */ + ret = mode_init_ov_sensor_regs(ov, width, height, + mode, sub_flag, 0); + if (ret < 0) + return ret; + hwscale = 2; + vwscale = 1; + hwsize = 640; + vwsize = 480; + } else if (width > 320 || height > 240) { + err("Illegal dimensions"); + return -EINVAL; + } else { /* QVGA */ + ret = mode_init_ov_sensor_regs(ov, width, height, + mode, sub_flag, 1); + if (ret < 0) + return ret; + hwscale = 1; + hwsize = 320; + vwsize = 240; + } + } + + /* Center the window */ + hoffset = ((hwsize - width) / 2) >> hwscale; + voffset = ((vwsize - height) / 2) >> vwscale; + + /* FIXME! - This needs to be changed to support 160x120 and 6620!!! */ + if (sub_flag) { + i2c_w(ov, 0x17, hwsbase+(ov->subx>>hwscale)); + i2c_w(ov, 0x18, hwebase+((ov->subx+ov->subw)>>hwscale)); + i2c_w(ov, 0x19, vwsbase+(ov->suby>>vwscale)); + i2c_w(ov, 0x1a, vwebase+((ov->suby+ov->subh)>>vwscale)); + } else { + i2c_w(ov, 0x17, hwsbase + hoffset); + i2c_w(ov, 0x18, hwebase + hoffset + (hwsize>>hwscale)); + i2c_w(ov, 0x19, vwsbase + voffset); + i2c_w(ov, 0x1a, vwebase + voffset + (vwsize>>vwscale)); + } + +#ifdef OV511_DEBUG + if (dump_sensor) + dump_i2c_regs(ov); +#endif + + return 0; +} + +/* Set up the OV511/OV511+ with the given image parameters. + * + * Do not put any sensor-specific code in here (including I2C I/O functions) + */ +static int +ov511_mode_init_regs(struct usb_ov511 *ov, + int width, int height, int mode, int sub_flag) +{ + int hsegs, vsegs; + + if (sub_flag) { + width = ov->subw; + height = ov->subh; + } + + PDEBUG(3, "width:%d, height:%d, mode:%d, sub:%d", + width, height, mode, sub_flag); + + // FIXME: This should be moved to a 7111a-specific function once + // subcapture is dealt with properly + if (ov->sensor == SEN_SAA7111A) { + if (width == 320 && height == 240) { + /* No need to do anything special */ + } else if (width == 640 && height == 480) { + /* Set the OV511 up as 320x480, but keep the + * V4L resolution as 640x480 */ + width = 320; + } else { + err("SAA7111A only allows 320x240 or 640x480"); + return -EINVAL; + } + } + + /* Make sure width and height are a multiple of 8 */ + if (width % 8 || height % 8) { + err("Invalid size (%d, %d) (mode = %d)", width, height, mode); + return -EINVAL; + } + + if (width < ov->minwidth || height < ov->minheight) { + err("Requested dimensions are too small"); + return -EINVAL; + } + + if (ov51x_stop(ov) < 0) + return -EIO; + + if (mode == VIDEO_PALETTE_GREY) { + reg_w(ov, R511_CAM_UV_EN, 0x00); + reg_w(ov, R511_SNAP_UV_EN, 0x00); + reg_w(ov, R511_SNAP_OPTS, 0x01); + } else { + reg_w(ov, R511_CAM_UV_EN, 0x01); + reg_w(ov, R511_SNAP_UV_EN, 0x01); + reg_w(ov, R511_SNAP_OPTS, 0x03); + } + + /* Here I'm assuming that snapshot size == image size. + * I hope that's always true. --claudio + */ + hsegs = (width >> 3) - 1; + vsegs = (height >> 3) - 1; + + reg_w(ov, R511_CAM_PXCNT, hsegs); + reg_w(ov, R511_CAM_LNCNT, vsegs); + reg_w(ov, R511_CAM_PXDIV, 0x00); + reg_w(ov, R511_CAM_LNDIV, 0x00); + + /* YUV420, low pass filter on */ + reg_w(ov, R511_CAM_OPTS, 0x03); + + /* Snapshot additions */ + reg_w(ov, R511_SNAP_PXCNT, hsegs); + reg_w(ov, R511_SNAP_LNCNT, vsegs); + reg_w(ov, R511_SNAP_PXDIV, 0x00); + reg_w(ov, R511_SNAP_LNDIV, 0x00); + + if (ov->compress) { + /* Enable Y and UV quantization and compression */ + reg_w(ov, R511_COMP_EN, 0x07); + reg_w(ov, R511_COMP_LUT_EN, 0x03); + ov51x_reset(ov, OV511_RESET_OMNICE); + } + + if (ov51x_restart(ov) < 0) + return -EIO; + + return 0; +} + +/* Sets up the OV518/OV518+ with the given image parameters + * + * OV518 needs a completely different approach, until we can figure out what + * the individual registers do. Also, only 15 FPS is supported now. + * + * Do not put any sensor-specific code in here (including I2C I/O functions) + */ +static int +ov518_mode_init_regs(struct usb_ov511 *ov, + int width, int height, int mode, int sub_flag) +{ + int hsegs, vsegs, hi_res; + + if (sub_flag) { + width = ov->subw; + height = ov->subh; + } + + PDEBUG(3, "width:%d, height:%d, mode:%d, sub:%d", + width, height, mode, sub_flag); + + if (width % 16 || height % 8) { + err("Invalid size (%d, %d)", width, height); + return -EINVAL; + } + + if (width < ov->minwidth || height < ov->minheight) { + err("Requested dimensions are too small"); + return -EINVAL; + } + + if (width >= 320 && height >= 240) { + hi_res = 1; + } else if (width >= 320 || height >= 240) { + err("Invalid width/height combination (%d, %d)", width, height); + return -EINVAL; + } else { + hi_res = 0; + } + + if (ov51x_stop(ov) < 0) + return -EIO; + + /******** Set the mode ********/ + + reg_w(ov, 0x2b, 0); + reg_w(ov, 0x2c, 0); + reg_w(ov, 0x2d, 0); + reg_w(ov, 0x2e, 0); + reg_w(ov, 0x3b, 0); + reg_w(ov, 0x3c, 0); + reg_w(ov, 0x3d, 0); + reg_w(ov, 0x3e, 0); + + if (ov->bridge == BRG_OV518 && ov518_color) { + /* OV518 needs U and V swapped */ + i2c_w_mask(ov, 0x15, 0x00, 0x01); + + if (mode == VIDEO_PALETTE_GREY) { + /* Set 16-bit input format (UV data are ignored) */ + reg_w_mask(ov, 0x20, 0x00, 0x08); + + /* Set 8-bit (4:0:0) output format */ + reg_w_mask(ov, 0x28, 0x00, 0xf0); + reg_w_mask(ov, 0x38, 0x00, 0xf0); + } else { + /* Set 8-bit (YVYU) input format */ + reg_w_mask(ov, 0x20, 0x08, 0x08); + + /* Set 12-bit (4:2:0) output format */ + reg_w_mask(ov, 0x28, 0x80, 0xf0); + reg_w_mask(ov, 0x38, 0x80, 0xf0); + } + } else { + reg_w(ov, 0x28, (mode == VIDEO_PALETTE_GREY) ? 0x00:0x80); + reg_w(ov, 0x38, (mode == VIDEO_PALETTE_GREY) ? 0x00:0x80); + } + + hsegs = width / 16; + vsegs = height / 4; + + reg_w(ov, 0x29, hsegs); + reg_w(ov, 0x2a, vsegs); + + reg_w(ov, 0x39, hsegs); + reg_w(ov, 0x3a, vsegs); + + /* Windows driver does this here; who knows why */ + reg_w(ov, 0x2f, 0x80); + + /******** Set the framerate (to 15 FPS) ********/ + + /* Mode independent, but framerate dependent, regs */ + reg_w(ov, 0x51, 0x02); /* Clock divider; lower==faster */ + reg_w(ov, 0x22, 0x18); + reg_w(ov, 0x23, 0xff); + + if (ov->bridge == BRG_OV518PLUS) + reg_w(ov, 0x21, 0x19); + else + reg_w(ov, 0x71, 0x19); /* Compression-related? */ + + // FIXME: Sensor-specific + /* Bit 5 is what matters here. Of course, it is "reserved" */ + i2c_w(ov, 0x54, 0x23); + + reg_w(ov, 0x2f, 0x80); + + if (ov->bridge == BRG_OV518PLUS) { + reg_w(ov, 0x24, 0x94); + reg_w(ov, 0x25, 0x90); + ov518_reg_w32(ov, 0xc4, 400, 2); /* 190h */ + ov518_reg_w32(ov, 0xc6, 540, 2); /* 21ch */ + ov518_reg_w32(ov, 0xc7, 540, 2); /* 21ch */ + ov518_reg_w32(ov, 0xc8, 108, 2); /* 6ch */ + ov518_reg_w32(ov, 0xca, 131098, 3); /* 2001ah */ + ov518_reg_w32(ov, 0xcb, 532, 2); /* 214h */ + ov518_reg_w32(ov, 0xcc, 2400, 2); /* 960h */ + ov518_reg_w32(ov, 0xcd, 32, 2); /* 20h */ + ov518_reg_w32(ov, 0xce, 608, 2); /* 260h */ + } else { + reg_w(ov, 0x24, 0x9f); + reg_w(ov, 0x25, 0x90); + ov518_reg_w32(ov, 0xc4, 400, 2); /* 190h */ + ov518_reg_w32(ov, 0xc6, 500, 2); /* 1f4h */ + ov518_reg_w32(ov, 0xc7, 500, 2); /* 1f4h */ + ov518_reg_w32(ov, 0xc8, 142, 2); /* 8eh */ + ov518_reg_w32(ov, 0xca, 131098, 3); /* 2001ah */ + ov518_reg_w32(ov, 0xcb, 532, 2); /* 214h */ + ov518_reg_w32(ov, 0xcc, 2000, 2); /* 7d0h */ + ov518_reg_w32(ov, 0xcd, 32, 2); /* 20h */ + ov518_reg_w32(ov, 0xce, 608, 2); /* 260h */ + } + + reg_w(ov, 0x2f, 0x80); + + if (ov51x_restart(ov) < 0) + return -EIO; + + /* Reset it just for good measure */ + if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0) + return -EIO; + + return 0; +} + +/* This is a wrapper around the OV511, OV518, and sensor specific functions */ +static int +mode_init_regs(struct usb_ov511 *ov, + int width, int height, int mode, int sub_flag) +{ + int rc = 0; + + if (!ov || !ov->dev) + return -EFAULT; + + if (ov->bclass == BCL_OV518) { + rc = ov518_mode_init_regs(ov, width, height, mode, sub_flag); + } else { + rc = ov511_mode_init_regs(ov, width, height, mode, sub_flag); + } + + if (FATAL_ERROR(rc)) + return rc; + + switch (ov->sensor) { + case SEN_OV7610: + case SEN_OV7620: + case SEN_OV76BE: + case SEN_OV8600: + case SEN_OV6620: + case SEN_OV6630: + rc = set_ov_sensor_window(ov, width, height, mode, sub_flag); + break; + case SEN_KS0127: + case SEN_KS0127B: + err("KS0127-series decoders not supported yet"); + rc = -EINVAL; + break; + case SEN_SAA7111A: +// rc = mode_init_saa_sensor_regs(ov, width, height, mode, +// sub_flag); + + PDEBUG(1, "SAA status = 0x%02X", i2c_r(ov, 0x1f)); + break; + default: + err("Unknown sensor"); + rc = -EINVAL; + } + + if (FATAL_ERROR(rc)) + return rc; + + /* Sensor-independent settings */ + rc = sensor_set_auto_brightness(ov, ov->auto_brt); + if (FATAL_ERROR(rc)) + return rc; + + rc = sensor_set_auto_exposure(ov, ov->auto_exp); + if (FATAL_ERROR(rc)) + return rc; + + rc = sensor_set_banding_filter(ov, bandingfilter); + if (FATAL_ERROR(rc)) + return rc; + + if (ov->lightfreq) { + rc = sensor_set_light_freq(ov, lightfreq); + if (FATAL_ERROR(rc)) + return rc; + } + + rc = sensor_set_backlight(ov, ov->backlight); + if (FATAL_ERROR(rc)) + return rc; + + rc = sensor_set_mirror(ov, ov->mirror); + if (FATAL_ERROR(rc)) + return rc; + + return 0; +} + +/* This sets the default image parameters. This is useful for apps that use + * read() and do not set these. + */ +static int +ov51x_set_default_params(struct usb_ov511 *ov) +{ + int i; + + /* Set default sizes in case IOCTL (VIDIOCMCAPTURE) is not used + * (using read() instead). */ + for (i = 0; i < OV511_NUMFRAMES; i++) { + ov->frame[i].width = ov->maxwidth; + ov->frame[i].height = ov->maxheight; + ov->frame[i].bytes_read = 0; + if (force_palette) + ov->frame[i].format = force_palette; + else + ov->frame[i].format = VIDEO_PALETTE_YUV420; + + ov->frame[i].depth = get_depth(ov->frame[i].format); + } + + PDEBUG(3, "%dx%d, %s", ov->maxwidth, ov->maxheight, + symbolic(v4l1_plist, ov->frame[0].format)); + + /* Initialize to max width/height, YUV420 or RGB24 (if supported) */ + if (mode_init_regs(ov, ov->maxwidth, ov->maxheight, + ov->frame[0].format, 0) < 0) + return -EINVAL; + + return 0; +} + +/********************************************************************** + * + * Video decoder stuff + * + **********************************************************************/ + +/* Set analog input port of decoder */ +static int +decoder_set_input(struct usb_ov511 *ov, int input) +{ + PDEBUG(4, "port %d", input); + + switch (ov->sensor) { + case SEN_SAA7111A: + { + /* Select mode */ + i2c_w_mask(ov, 0x02, input, 0x07); + /* Bypass chrominance trap for modes 4..7 */ + i2c_w_mask(ov, 0x09, (input > 3) ? 0x80:0x00, 0x80); + break; + } + default: + return -EINVAL; + } + + return 0; +} + +/* Get ASCII name of video input */ +static int +decoder_get_input_name(struct usb_ov511 *ov, int input, char *name) +{ + switch (ov->sensor) { + case SEN_SAA7111A: + { + if (input < 0 || input > 7) + return -EINVAL; + else if (input < 4) + sprintf(name, "CVBS-%d", input); + else // if (input < 8) + sprintf(name, "S-Video-%d", input - 4); + break; + } + default: + sprintf(name, "%s", "Camera"); + } + + return 0; +} + +/* Set norm (NTSC, PAL, SECAM, AUTO) */ +static int +decoder_set_norm(struct usb_ov511 *ov, int norm) +{ + PDEBUG(4, "%d", norm); + + switch (ov->sensor) { + case SEN_SAA7111A: + { + int reg_8, reg_e; + + if (norm == VIDEO_MODE_NTSC) { + reg_8 = 0x40; /* 60 Hz */ + reg_e = 0x00; /* NTSC M / PAL BGHI */ + } else if (norm == VIDEO_MODE_PAL) { + reg_8 = 0x00; /* 50 Hz */ + reg_e = 0x00; /* NTSC M / PAL BGHI */ + } else if (norm == VIDEO_MODE_AUTO) { + reg_8 = 0x80; /* Auto field detect */ + reg_e = 0x00; /* NTSC M / PAL BGHI */ + } else if (norm == VIDEO_MODE_SECAM) { + reg_8 = 0x00; /* 50 Hz */ + reg_e = 0x50; /* SECAM / PAL 4.43 */ + } else { + return -EINVAL; + } + + i2c_w_mask(ov, 0x08, reg_8, 0xc0); + i2c_w_mask(ov, 0x0e, reg_e, 0x70); + break; + } + default: + return -EINVAL; + } + + return 0; +} + +/********************************************************************** + * + * Raw data parsing + * + **********************************************************************/ + +/* Copies a 64-byte segment at pIn to an 8x8 block at pOut. The width of the + * image at pOut is specified by w. + */ +static inline void +make_8x8(unsigned char *pIn, unsigned char *pOut, int w) +{ + unsigned char *pOut1 = pOut; + int x, y; + + for (y = 0; y < 8; y++) { + pOut1 = pOut; + for (x = 0; x < 8; x++) { + *pOut1++ = *pIn++; + } + pOut += w; + } +} + +/* + * For RAW BW (YUV 4:0:0) images, data show up in 256 byte segments. + * The segments represent 4 squares of 8x8 pixels as follows: + * + * 0 1 ... 7 64 65 ... 71 ... 192 193 ... 199 + * 8 9 ... 15 72 73 ... 79 200 201 ... 207 + * ... ... ... + * 56 57 ... 63 120 121 ... 127 248 249 ... 255 + * + */ +static void +yuv400raw_to_yuv400p(struct ov511_frame *frame, + unsigned char *pIn0, unsigned char *pOut0) +{ + int x, y; + unsigned char *pIn, *pOut, *pOutLine; + + /* Copy Y */ + pIn = pIn0; + pOutLine = pOut0; + for (y = 0; y < frame->rawheight - 1; y += 8) { + pOut = pOutLine; + for (x = 0; x < frame->rawwidth - 1; x += 8) { + make_8x8(pIn, pOut, frame->rawwidth); + pIn += 64; + pOut += 8; + } + pOutLine += 8 * frame->rawwidth; + } +} + +/* + * For YUV 4:2:0 images, the data show up in 384 byte segments. + * The first 64 bytes of each segment are U, the next 64 are V. The U and + * V are arranged as follows: + * + * 0 1 ... 7 + * 8 9 ... 15 + * ... + * 56 57 ... 63 + * + * U and V are shipped at half resolution (1 U,V sample -> one 2x2 block). + * + * The next 256 bytes are full resolution Y data and represent 4 squares + * of 8x8 pixels as follows: + * + * 0 1 ... 7 64 65 ... 71 ... 192 193 ... 199 + * 8 9 ... 15 72 73 ... 79 200 201 ... 207 + * ... ... ... + * 56 57 ... 63 120 121 ... 127 ... 248 249 ... 255 + * + * Note that the U and V data in one segment represent a 16 x 16 pixel + * area, but the Y data represent a 32 x 8 pixel area. If the width is not an + * even multiple of 32, the extra 8x8 blocks within a 32x8 block belong to the + * next horizontal stripe. + * + * If dumppix module param is set, _parse_data just dumps the incoming segments, + * verbatim, in order, into the frame. When used with vidcat -f ppm -s 640x480 + * this puts the data on the standard output and can be analyzed with the + * parseppm.c utility I wrote. That's a much faster way for figuring out how + * these data are scrambled. + */ + +/* Converts from raw, uncompressed segments at pIn0 to a YUV420P frame at pOut0. + * + * FIXME: Currently only handles width and height that are multiples of 16 + */ +static void +yuv420raw_to_yuv420p(struct ov511_frame *frame, + unsigned char *pIn0, unsigned char *pOut0) +{ + int k, x, y; + unsigned char *pIn, *pOut, *pOutLine; + const unsigned int a = frame->rawwidth * frame->rawheight; + const unsigned int w = frame->rawwidth / 2; + + /* Copy U and V */ + pIn = pIn0; + pOutLine = pOut0 + a; + for (y = 0; y < frame->rawheight - 1; y += 16) { + pOut = pOutLine; + for (x = 0; x < frame->rawwidth - 1; x += 16) { + make_8x8(pIn, pOut, w); + make_8x8(pIn + 64, pOut + a/4, w); + pIn += 384; + pOut += 8; + } + pOutLine += 8 * w; + } + + /* Copy Y */ + pIn = pIn0 + 128; + pOutLine = pOut0; + k = 0; + for (y = 0; y < frame->rawheight - 1; y += 8) { + pOut = pOutLine; + for (x = 0; x < frame->rawwidth - 1; x += 8) { + make_8x8(pIn, pOut, frame->rawwidth); + pIn += 64; + pOut += 8; + if ((++k) > 3) { + k = 0; + pIn += 128; + } + } + pOutLine += 8 * frame->rawwidth; + } +} + +/********************************************************************** + * + * Decompression + * + **********************************************************************/ + +/* Chooses a decompression module, locks it, and sets ov->decomp_ops + * accordingly. Returns -ENXIO if decompressor is not available, otherwise + * returns 0 if no other error. + */ +static int +request_decompressor(struct usb_ov511 *ov) +{ + if (!ov) + return -ENODEV; + + if (ov->decomp_ops) { + err("ERROR: Decompressor already requested!"); + return -EINVAL; + } + + lock_kernel(); + + /* Try to get MMX, and fall back on no-MMX if necessary */ + if (ov->bclass == BCL_OV511) { + if (ov511_mmx_decomp_ops) { + PDEBUG(3, "Using OV511 MMX decompressor"); + ov->decomp_ops = ov511_mmx_decomp_ops; + } else if (ov511_decomp_ops) { + PDEBUG(3, "Using OV511 decompressor"); + ov->decomp_ops = ov511_decomp_ops; + } else { + err("No decompressor available"); + } + } else if (ov->bclass == BCL_OV518) { + if (ov518_mmx_decomp_ops) { + PDEBUG(3, "Using OV518 MMX decompressor"); + ov->decomp_ops = ov518_mmx_decomp_ops; + } else if (ov518_decomp_ops) { + PDEBUG(3, "Using OV518 decompressor"); + ov->decomp_ops = ov518_decomp_ops; + } else { + err("No decompressor available"); + } + } else { + err("Unknown bridge"); + } + + if (!ov->decomp_ops) + goto nosys; + + if (!ov->decomp_ops->owner) { + ov->decomp_ops = NULL; + goto nosys; + } + + if (!try_module_get(ov->decomp_ops->owner)) + goto nosys; + + unlock_kernel(); + return 0; + + nosys: + unlock_kernel(); + return -ENOSYS; +} + +/* Unlocks decompression module and nulls ov->decomp_ops. Safe to call even + * if ov->decomp_ops is NULL. + */ +static void +release_decompressor(struct usb_ov511 *ov) +{ + int released = 0; /* Did we actually do anything? */ + + if (!ov) + return; + + lock_kernel(); + + if (ov->decomp_ops) { + module_put(ov->decomp_ops->owner); + released = 1; + } + + ov->decomp_ops = NULL; + + unlock_kernel(); + + if (released) + PDEBUG(3, "Decompressor released"); +} + +static void +decompress(struct usb_ov511 *ov, struct ov511_frame *frame, + unsigned char *pIn0, unsigned char *pOut0) +{ + if (!ov->decomp_ops) + if (request_decompressor(ov)) + return; + + PDEBUG(4, "Decompressing %d bytes", frame->bytes_recvd); + + if (frame->format == VIDEO_PALETTE_GREY + && ov->decomp_ops->decomp_400) { + int ret = ov->decomp_ops->decomp_400( + pIn0, + pOut0, + frame->compbuf, + frame->rawwidth, + frame->rawheight, + frame->bytes_recvd); + PDEBUG(4, "DEBUG: decomp_400 returned %d", ret); + } else if (frame->format != VIDEO_PALETTE_GREY + && ov->decomp_ops->decomp_420) { + int ret = ov->decomp_ops->decomp_420( + pIn0, + pOut0, + frame->compbuf, + frame->rawwidth, + frame->rawheight, + frame->bytes_recvd); + PDEBUG(4, "DEBUG: decomp_420 returned %d", ret); + } else { + err("Decompressor does not support this format"); + } +} + +/********************************************************************** + * + * Format conversion + * + **********************************************************************/ + +/* Fuses even and odd fields together, and doubles width. + * INPUT: an odd field followed by an even field at pIn0, in YUV planar format + * OUTPUT: a normal YUV planar image, with correct aspect ratio + */ +static void +deinterlace(struct ov511_frame *frame, int rawformat, + unsigned char *pIn0, unsigned char *pOut0) +{ + const int fieldheight = frame->rawheight / 2; + const int fieldpix = fieldheight * frame->rawwidth; + const int w = frame->width; + int x, y; + unsigned char *pInEven, *pInOdd, *pOut; + + PDEBUG(5, "fieldheight=%d", fieldheight); + + if (frame->rawheight != frame->height) { + err("invalid height"); + return; + } + + if ((frame->rawwidth * 2) != frame->width) { + err("invalid width"); + return; + } + + /* Y */ + pInOdd = pIn0; + pInEven = pInOdd + fieldpix; + pOut = pOut0; + for (y = 0; y < fieldheight; y++) { + for (x = 0; x < frame->rawwidth; x++) { + *pOut = *pInEven; + *(pOut+1) = *pInEven++; + *(pOut+w) = *pInOdd; + *(pOut+w+1) = *pInOdd++; + pOut += 2; + } + pOut += w; + } + + if (rawformat == RAWFMT_YUV420) { + /* U */ + pInOdd = pIn0 + fieldpix * 2; + pInEven = pInOdd + fieldpix / 4; + for (y = 0; y < fieldheight / 2; y++) { + for (x = 0; x < frame->rawwidth / 2; x++) { + *pOut = *pInEven; + *(pOut+1) = *pInEven++; + *(pOut+w/2) = *pInOdd; + *(pOut+w/2+1) = *pInOdd++; + pOut += 2; + } + pOut += w/2; + } + /* V */ + pInOdd = pIn0 + fieldpix * 2 + fieldpix / 2; + pInEven = pInOdd + fieldpix / 4; + for (y = 0; y < fieldheight / 2; y++) { + for (x = 0; x < frame->rawwidth / 2; x++) { + *pOut = *pInEven; + *(pOut+1) = *pInEven++; + *(pOut+w/2) = *pInOdd; + *(pOut+w/2+1) = *pInOdd++; + pOut += 2; + } + pOut += w/2; + } + } +} + +static void +ov51x_postprocess_grey(struct usb_ov511 *ov, struct ov511_frame *frame) +{ + /* Deinterlace frame, if necessary */ + if (ov->sensor == SEN_SAA7111A && frame->rawheight >= 480) { + if (frame->compressed) + decompress(ov, frame, frame->rawdata, + frame->tempdata); + else + yuv400raw_to_yuv400p(frame, frame->rawdata, + frame->tempdata); + + deinterlace(frame, RAWFMT_YUV400, frame->tempdata, + frame->data); + } else { + if (frame->compressed) + decompress(ov, frame, frame->rawdata, + frame->data); + else + yuv400raw_to_yuv400p(frame, frame->rawdata, + frame->data); + } +} + +/* Process raw YUV420 data into standard YUV420P */ +static void +ov51x_postprocess_yuv420(struct usb_ov511 *ov, struct ov511_frame *frame) +{ + /* Deinterlace frame, if necessary */ + if (ov->sensor == SEN_SAA7111A && frame->rawheight >= 480) { + if (frame->compressed) + decompress(ov, frame, frame->rawdata, frame->tempdata); + else + yuv420raw_to_yuv420p(frame, frame->rawdata, + frame->tempdata); + + deinterlace(frame, RAWFMT_YUV420, frame->tempdata, + frame->data); + } else { + if (frame->compressed) + decompress(ov, frame, frame->rawdata, frame->data); + else + yuv420raw_to_yuv420p(frame, frame->rawdata, + frame->data); + } +} + +/* Post-processes the specified frame. This consists of: + * 1. Decompress frame, if necessary + * 2. Deinterlace frame and scale to proper size, if necessary + * 3. Convert from YUV planar to destination format, if necessary + * 4. Fix the RGB offset, if necessary + */ +static void +ov51x_postprocess(struct usb_ov511 *ov, struct ov511_frame *frame) +{ + if (dumppix) { + memset(frame->data, 0, + MAX_DATA_SIZE(ov->maxwidth, ov->maxheight)); + PDEBUG(4, "Dumping %d bytes", frame->bytes_recvd); + memcpy(frame->data, frame->rawdata, frame->bytes_recvd); + } else { + switch (frame->format) { + case VIDEO_PALETTE_GREY: + ov51x_postprocess_grey(ov, frame); + break; + case VIDEO_PALETTE_YUV420: + case VIDEO_PALETTE_YUV420P: + ov51x_postprocess_yuv420(ov, frame); + break; + default: + err("Cannot convert data to %s", + symbolic(v4l1_plist, frame->format)); + } + } +} + +/********************************************************************** + * + * OV51x data transfer, IRQ handler + * + **********************************************************************/ + +static inline void +ov511_move_data(struct usb_ov511 *ov, unsigned char *in, int n) +{ + int num, offset; + int pnum = in[ov->packet_size - 1]; /* Get packet number */ + int max_raw = MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight); + struct ov511_frame *frame = &ov->frame[ov->curframe]; + struct timeval *ts; + + /* SOF/EOF packets have 1st to 8th bytes zeroed and the 9th + * byte non-zero. The EOF packet has image width/height in the + * 10th and 11th bytes. The 9th byte is given as follows: + * + * bit 7: EOF + * 6: compression enabled + * 5: 422/420/400 modes + * 4: 422/420/400 modes + * 3: 1 + * 2: snapshot button on + * 1: snapshot frame + * 0: even/odd field + */ + + if (printph) { + info("ph(%3d): %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x", + pnum, in[0], in[1], in[2], in[3], in[4], in[5], in[6], + in[7], in[8], in[9], in[10], in[11]); + } + + /* Check for SOF/EOF packet */ + if ((in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) || + (~in[8] & 0x08)) + goto check_middle; + + /* Frame end */ + if (in[8] & 0x80) { + ts = (struct timeval *)(frame->data + + MAX_FRAME_SIZE(ov->maxwidth, ov->maxheight)); + do_gettimeofday(ts); + + /* Get the actual frame size from the EOF header */ + frame->rawwidth = ((int)(in[9]) + 1) * 8; + frame->rawheight = ((int)(in[10]) + 1) * 8; + + PDEBUG(4, "Frame end, frame=%d, pnum=%d, w=%d, h=%d, recvd=%d", + ov->curframe, pnum, frame->rawwidth, frame->rawheight, + frame->bytes_recvd); + + /* Validate the header data */ + RESTRICT_TO_RANGE(frame->rawwidth, ov->minwidth, ov->maxwidth); + RESTRICT_TO_RANGE(frame->rawheight, ov->minheight, + ov->maxheight); + + /* Don't allow byte count to exceed buffer size */ + RESTRICT_TO_RANGE(frame->bytes_recvd, 8, max_raw); + + if (frame->scanstate == STATE_LINES) { + int nextf; + + frame->grabstate = FRAME_DONE; + wake_up_interruptible(&frame->wq); + + /* If next frame is ready or grabbing, + * point to it */ + nextf = (ov->curframe + 1) % OV511_NUMFRAMES; + if (ov->frame[nextf].grabstate == FRAME_READY + || ov->frame[nextf].grabstate == FRAME_GRABBING) { + ov->curframe = nextf; + ov->frame[nextf].scanstate = STATE_SCANNING; + } else { + if (frame->grabstate == FRAME_DONE) { + PDEBUG(4, "** Frame done **"); + } else { + PDEBUG(4, "Frame not ready? state = %d", + ov->frame[nextf].grabstate); + } + + ov->curframe = -1; + } + } else { + PDEBUG(5, "Frame done, but not scanning"); + } + /* Image corruption caused by misplaced frame->segment = 0 + * fixed by carlosf@conectiva.com.br + */ + } else { + /* Frame start */ + PDEBUG(4, "Frame start, framenum = %d", ov->curframe); + + /* Check to see if it's a snapshot frame */ + /* FIXME?? Should the snapshot reset go here? Performance? */ + if (in[8] & 0x02) { + frame->snapshot = 1; + PDEBUG(3, "snapshot detected"); + } + + frame->scanstate = STATE_LINES; + frame->bytes_recvd = 0; + frame->compressed = in[8] & 0x40; + } + +check_middle: + /* Are we in a frame? */ + if (frame->scanstate != STATE_LINES) { + PDEBUG(5, "Not in a frame; packet skipped"); + return; + } + + /* If frame start, skip header */ + if (frame->bytes_recvd == 0) + offset = 9; + else + offset = 0; + + num = n - offset - 1; + + /* Dump all data exactly as received */ + if (dumppix == 2) { + frame->bytes_recvd += n - 1; + if (frame->bytes_recvd <= max_raw) + memcpy(frame->rawdata + frame->bytes_recvd - (n - 1), + in, n - 1); + else + PDEBUG(3, "Raw data buffer overrun!! (%d)", + frame->bytes_recvd - max_raw); + } else if (!frame->compressed && !remove_zeros) { + frame->bytes_recvd += num; + if (frame->bytes_recvd <= max_raw) + memcpy(frame->rawdata + frame->bytes_recvd - num, + in + offset, num); + else + PDEBUG(3, "Raw data buffer overrun!! (%d)", + frame->bytes_recvd - max_raw); + } else { /* Remove all-zero FIFO lines (aligned 32-byte blocks) */ + int b, read = 0, allzero, copied = 0; + if (offset) { + frame->bytes_recvd += 32 - offset; // Bytes out + memcpy(frame->rawdata, in + offset, 32 - offset); + read += 32; + } + + while (read < n - 1) { + allzero = 1; + for (b = 0; b < 32; b++) { + if (in[read + b]) { + allzero = 0; + break; + } + } + + if (allzero) { + /* Don't copy it */ + } else { + if (frame->bytes_recvd + copied + 32 <= max_raw) + { + memcpy(frame->rawdata + + frame->bytes_recvd + copied, + in + read, 32); + copied += 32; + } else { + PDEBUG(3, "Raw data buffer overrun!!"); + } + } + read += 32; + } + + frame->bytes_recvd += copied; + } +} + +static inline void +ov518_move_data(struct usb_ov511 *ov, unsigned char *in, int n) +{ + int max_raw = MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight); + struct ov511_frame *frame = &ov->frame[ov->curframe]; + struct timeval *ts; + + /* Don't copy the packet number byte */ + if (ov->packet_numbering) + --n; + + /* A false positive here is likely, until OVT gives me + * the definitive SOF/EOF format */ + if ((!(in[0] | in[1] | in[2] | in[3] | in[5])) && in[6]) { + if (printph) { + info("ph: %2x %2x %2x %2x %2x %2x %2x %2x", in[0], + in[1], in[2], in[3], in[4], in[5], in[6], in[7]); + } + + if (frame->scanstate == STATE_LINES) { + PDEBUG(4, "Detected frame end/start"); + goto eof; + } else { //scanstate == STATE_SCANNING + /* Frame start */ + PDEBUG(4, "Frame start, framenum = %d", ov->curframe); + goto sof; + } + } else { + goto check_middle; + } + +eof: + ts = (struct timeval *)(frame->data + + MAX_FRAME_SIZE(ov->maxwidth, ov->maxheight)); + do_gettimeofday(ts); + + PDEBUG(4, "Frame end, curframe = %d, hw=%d, vw=%d, recvd=%d", + ov->curframe, + (int)(in[9]), (int)(in[10]), frame->bytes_recvd); + + // FIXME: Since we don't know the header formats yet, + // there is no way to know what the actual image size is + frame->rawwidth = frame->width; + frame->rawheight = frame->height; + + /* Validate the header data */ + RESTRICT_TO_RANGE(frame->rawwidth, ov->minwidth, ov->maxwidth); + RESTRICT_TO_RANGE(frame->rawheight, ov->minheight, ov->maxheight); + + /* Don't allow byte count to exceed buffer size */ + RESTRICT_TO_RANGE(frame->bytes_recvd, 8, max_raw); + + if (frame->scanstate == STATE_LINES) { + int nextf; + + frame->grabstate = FRAME_DONE; + wake_up_interruptible(&frame->wq); + + /* If next frame is ready or grabbing, + * point to it */ + nextf = (ov->curframe + 1) % OV511_NUMFRAMES; + if (ov->frame[nextf].grabstate == FRAME_READY + || ov->frame[nextf].grabstate == FRAME_GRABBING) { + ov->curframe = nextf; + ov->frame[nextf].scanstate = STATE_SCANNING; + frame = &ov->frame[nextf]; + } else { + if (frame->grabstate == FRAME_DONE) { + PDEBUG(4, "** Frame done **"); + } else { + PDEBUG(4, "Frame not ready? state = %d", + ov->frame[nextf].grabstate); + } + + ov->curframe = -1; + PDEBUG(4, "SOF dropped (no active frame)"); + return; /* Nowhere to store this frame */ + } + } +sof: + PDEBUG(4, "Starting capture on frame %d", frame->framenum); + +// Snapshot not reverse-engineered yet. +#if 0 + /* Check to see if it's a snapshot frame */ + /* FIXME?? Should the snapshot reset go here? Performance? */ + if (in[8] & 0x02) { + frame->snapshot = 1; + PDEBUG(3, "snapshot detected"); + } +#endif + frame->scanstate = STATE_LINES; + frame->bytes_recvd = 0; + frame->compressed = 1; + +check_middle: + /* Are we in a frame? */ + if (frame->scanstate != STATE_LINES) { + PDEBUG(4, "scanstate: no SOF yet"); + return; + } + + /* Dump all data exactly as received */ + if (dumppix == 2) { + frame->bytes_recvd += n; + if (frame->bytes_recvd <= max_raw) + memcpy(frame->rawdata + frame->bytes_recvd - n, in, n); + else + PDEBUG(3, "Raw data buffer overrun!! (%d)", + frame->bytes_recvd - max_raw); + } else { + /* All incoming data are divided into 8-byte segments. If the + * segment contains all zero bytes, it must be skipped. These + * zero-segments allow the OV518 to mainain a constant data rate + * regardless of the effectiveness of the compression. Segments + * are aligned relative to the beginning of each isochronous + * packet. The first segment in each image is a header (the + * decompressor skips it later). + */ + + int b, read = 0, allzero, copied = 0; + + while (read < n) { + allzero = 1; + for (b = 0; b < 8; b++) { + if (in[read + b]) { + allzero = 0; + break; + } + } + + if (allzero) { + /* Don't copy it */ + } else { + if (frame->bytes_recvd + copied + 8 <= max_raw) + { + memcpy(frame->rawdata + + frame->bytes_recvd + copied, + in + read, 8); + copied += 8; + } else { + PDEBUG(3, "Raw data buffer overrun!!"); + } + } + read += 8; + } + frame->bytes_recvd += copied; + } +} + +static void +ov51x_isoc_irq(struct urb *urb) +{ + int i; + struct usb_ov511 *ov; + struct ov511_sbuf *sbuf; + + if (!urb->context) { + PDEBUG(4, "no context"); + return; + } + + sbuf = urb->context; + ov = sbuf->ov; + + if (!ov || !ov->dev || !ov->user) { + PDEBUG(4, "no device, or not open"); + return; + } + + if (!ov->streaming) { + PDEBUG(4, "hmmm... not streaming, but got interrupt"); + return; + } + + if (urb->status == -ENOENT || urb->status == -ECONNRESET) { + PDEBUG(4, "URB unlinked"); + return; + } + + if (urb->status != -EINPROGRESS && urb->status != 0) { + err("ERROR: urb->status=%d: %s", urb->status, + symbolic(urb_errlist, urb->status)); + } + + /* Copy the data received into our frame buffer */ + PDEBUG(5, "sbuf[%d]: Moving %d packets", sbuf->n, + urb->number_of_packets); + for (i = 0; i < urb->number_of_packets; i++) { + /* Warning: Don't call *_move_data() if no frame active! */ + if (ov->curframe >= 0) { + int n = urb->iso_frame_desc[i].actual_length; + int st = urb->iso_frame_desc[i].status; + unsigned char *cdata; + + urb->iso_frame_desc[i].actual_length = 0; + urb->iso_frame_desc[i].status = 0; + + cdata = urb->transfer_buffer + + urb->iso_frame_desc[i].offset; + + if (!n) { + PDEBUG(4, "Zero-length packet"); + continue; + } + + if (st) + PDEBUG(2, "data error: [%d] len=%d, status=%d", + i, n, st); + + if (ov->bclass == BCL_OV511) + ov511_move_data(ov, cdata, n); + else if (ov->bclass == BCL_OV518) + ov518_move_data(ov, cdata, n); + else + err("Unknown bridge device (%d)", ov->bridge); + + } else if (waitqueue_active(&ov->wq)) { + wake_up_interruptible(&ov->wq); + } + } + + /* Resubmit this URB */ + urb->dev = ov->dev; + if ((i = usb_submit_urb(urb, GFP_ATOMIC)) != 0) + err("usb_submit_urb() ret %d", i); + + return; +} + +/**************************************************************************** + * + * Stream initialization and termination + * + ***************************************************************************/ + +static int +ov51x_init_isoc(struct usb_ov511 *ov) +{ + struct urb *urb; + int fx, err, n, size; + + PDEBUG(3, "*** Initializing capture ***"); + + ov->curframe = -1; + + if (ov->bridge == BRG_OV511) { + if (cams == 1) + size = 993; + else if (cams == 2) + size = 513; + else if (cams == 3 || cams == 4) + size = 257; + else { + err("\"cams\" parameter too high!"); + return -1; + } + } else if (ov->bridge == BRG_OV511PLUS) { + if (cams == 1) + size = 961; + else if (cams == 2) + size = 513; + else if (cams == 3 || cams == 4) + size = 257; + else if (cams >= 5 && cams <= 8) + size = 129; + else if (cams >= 9 && cams <= 31) + size = 33; + else { + err("\"cams\" parameter too high!"); + return -1; + } + } else if (ov->bclass == BCL_OV518) { + if (cams == 1) + size = 896; + else if (cams == 2) + size = 512; + else if (cams == 3 || cams == 4) + size = 256; + else if (cams >= 5 && cams <= 8) + size = 128; + else { + err("\"cams\" parameter too high!"); + return -1; + } + } else { + err("invalid bridge type"); + return -1; + } + + // FIXME: OV518 is hardcoded to 15 FPS (alternate 5) for now + if (ov->bclass == BCL_OV518) { + if (packetsize == -1) { + ov518_set_packet_size(ov, 640); + } else { + info("Forcing packet size to %d", packetsize); + ov518_set_packet_size(ov, packetsize); + } + } else { + if (packetsize == -1) { + ov511_set_packet_size(ov, size); + } else { + info("Forcing packet size to %d", packetsize); + ov511_set_packet_size(ov, packetsize); + } + } + + for (n = 0; n < OV511_NUMSBUF; n++) { + urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL); + if (!urb) { + err("init isoc: usb_alloc_urb ret. NULL"); + return -ENOMEM; + } + ov->sbuf[n].urb = urb; + urb->dev = ov->dev; + urb->context = &ov->sbuf[n]; + urb->pipe = usb_rcvisocpipe(ov->dev, OV511_ENDPOINT_ADDRESS); + urb->transfer_flags = URB_ISO_ASAP; + urb->transfer_buffer = ov->sbuf[n].data; + urb->complete = ov51x_isoc_irq; + urb->number_of_packets = FRAMES_PER_DESC; + urb->transfer_buffer_length = ov->packet_size * FRAMES_PER_DESC; + urb->interval = 1; + for (fx = 0; fx < FRAMES_PER_DESC; fx++) { + urb->iso_frame_desc[fx].offset = ov->packet_size * fx; + urb->iso_frame_desc[fx].length = ov->packet_size; + } + } + + ov->streaming = 1; + + for (n = 0; n < OV511_NUMSBUF; n++) { + ov->sbuf[n].urb->dev = ov->dev; + err = usb_submit_urb(ov->sbuf[n].urb, GFP_KERNEL); + if (err) { + err("init isoc: usb_submit_urb(%d) ret %d", n, err); + return err; + } + } + + return 0; +} + +static void +ov51x_unlink_isoc(struct usb_ov511 *ov) +{ + int n; + + /* Unschedule all of the iso td's */ + for (n = OV511_NUMSBUF - 1; n >= 0; n--) { + if (ov->sbuf[n].urb) { + usb_kill_urb(ov->sbuf[n].urb); + usb_free_urb(ov->sbuf[n].urb); + ov->sbuf[n].urb = NULL; + } + } +} + +static void +ov51x_stop_isoc(struct usb_ov511 *ov) +{ + if (!ov->streaming || !ov->dev) + return; + + PDEBUG(3, "*** Stopping capture ***"); + + if (ov->bclass == BCL_OV518) + ov518_set_packet_size(ov, 0); + else + ov511_set_packet_size(ov, 0); + + ov->streaming = 0; + + ov51x_unlink_isoc(ov); +} + +static int +ov51x_new_frame(struct usb_ov511 *ov, int framenum) +{ + struct ov511_frame *frame; + int newnum; + + PDEBUG(4, "ov->curframe = %d, framenum = %d", ov->curframe, framenum); + + if (!ov->dev) + return -1; + + /* If we're not grabbing a frame right now and the other frame is */ + /* ready to be grabbed into, then use it instead */ + if (ov->curframe == -1) { + newnum = (framenum - 1 + OV511_NUMFRAMES) % OV511_NUMFRAMES; + if (ov->frame[newnum].grabstate == FRAME_READY) + framenum = newnum; + } else + return 0; + + frame = &ov->frame[framenum]; + + PDEBUG(4, "framenum = %d, width = %d, height = %d", framenum, + frame->width, frame->height); + + frame->grabstate = FRAME_GRABBING; + frame->scanstate = STATE_SCANNING; + frame->snapshot = 0; + + ov->curframe = framenum; + + /* Make sure it's not too big */ + if (frame->width > ov->maxwidth) + frame->width = ov->maxwidth; + + frame->width &= ~7L; /* Multiple of 8 */ + + if (frame->height > ov->maxheight) + frame->height = ov->maxheight; + + frame->height &= ~3L; /* Multiple of 4 */ + + return 0; +} + +/**************************************************************************** + * + * Buffer management + * + ***************************************************************************/ + +/* + * - You must acquire buf_lock before entering this function. + * - Because this code will free any non-null pointer, you must be sure to null + * them if you explicitly free them somewhere else! + */ +static void +ov51x_do_dealloc(struct usb_ov511 *ov) +{ + int i; + PDEBUG(4, "entered"); + + if (ov->fbuf) { + rvfree(ov->fbuf, OV511_NUMFRAMES + * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight)); + ov->fbuf = NULL; + } + + vfree(ov->rawfbuf); + ov->rawfbuf = NULL; + + vfree(ov->tempfbuf); + ov->tempfbuf = NULL; + + for (i = 0; i < OV511_NUMSBUF; i++) { + kfree(ov->sbuf[i].data); + ov->sbuf[i].data = NULL; + } + + for (i = 0; i < OV511_NUMFRAMES; i++) { + ov->frame[i].data = NULL; + ov->frame[i].rawdata = NULL; + ov->frame[i].tempdata = NULL; + if (ov->frame[i].compbuf) { + free_page((unsigned long) ov->frame[i].compbuf); + ov->frame[i].compbuf = NULL; + } + } + + PDEBUG(4, "buffer memory deallocated"); + ov->buf_state = BUF_NOT_ALLOCATED; + PDEBUG(4, "leaving"); +} + +static int +ov51x_alloc(struct usb_ov511 *ov) +{ + int i; + const int w = ov->maxwidth; + const int h = ov->maxheight; + const int data_bufsize = OV511_NUMFRAMES * MAX_DATA_SIZE(w, h); + const int raw_bufsize = OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h); + + PDEBUG(4, "entered"); + down(&ov->buf_lock); + + if (ov->buf_state == BUF_ALLOCATED) + goto out; + + ov->fbuf = rvmalloc(data_bufsize); + if (!ov->fbuf) + goto error; + + ov->rawfbuf = vmalloc(raw_bufsize); + if (!ov->rawfbuf) + goto error; + + memset(ov->rawfbuf, 0, raw_bufsize); + + ov->tempfbuf = vmalloc(raw_bufsize); + if (!ov->tempfbuf) + goto error; + + memset(ov->tempfbuf, 0, raw_bufsize); + + for (i = 0; i < OV511_NUMSBUF; i++) { + ov->sbuf[i].data = kmalloc(FRAMES_PER_DESC * + MAX_FRAME_SIZE_PER_DESC, GFP_KERNEL); + if (!ov->sbuf[i].data) + goto error; + + PDEBUG(4, "sbuf[%d] @ %p", i, ov->sbuf[i].data); + } + + for (i = 0; i < OV511_NUMFRAMES; i++) { + ov->frame[i].data = ov->fbuf + i * MAX_DATA_SIZE(w, h); + ov->frame[i].rawdata = ov->rawfbuf + + i * MAX_RAW_DATA_SIZE(w, h); + ov->frame[i].tempdata = ov->tempfbuf + + i * MAX_RAW_DATA_SIZE(w, h); + + ov->frame[i].compbuf = + (unsigned char *) __get_free_page(GFP_KERNEL); + if (!ov->frame[i].compbuf) + goto error; + + PDEBUG(4, "frame[%d] @ %p", i, ov->frame[i].data); + } + + ov->buf_state = BUF_ALLOCATED; +out: + up(&ov->buf_lock); + PDEBUG(4, "leaving"); + return 0; +error: + ov51x_do_dealloc(ov); + up(&ov->buf_lock); + PDEBUG(4, "errored"); + return -ENOMEM; +} + +static void +ov51x_dealloc(struct usb_ov511 *ov) +{ + PDEBUG(4, "entered"); + down(&ov->buf_lock); + ov51x_do_dealloc(ov); + up(&ov->buf_lock); + PDEBUG(4, "leaving"); +} + +/**************************************************************************** + * + * V4L 1 API + * + ***************************************************************************/ + +static int +ov51x_v4l1_open(struct inode *inode, struct file *file) +{ + struct video_device *vdev = video_devdata(file); + struct usb_ov511 *ov = video_get_drvdata(vdev); + int err, i; + + PDEBUG(4, "opening"); + + down(&ov->lock); + + err = -EBUSY; + if (ov->user) + goto out; + + ov->sub_flag = 0; + + /* In case app doesn't set them... */ + err = ov51x_set_default_params(ov); + if (err < 0) + goto out; + + /* Make sure frames are reset */ + for (i = 0; i < OV511_NUMFRAMES; i++) { + ov->frame[i].grabstate = FRAME_UNUSED; + ov->frame[i].bytes_read = 0; + } + + /* If compression is on, make sure now that a + * decompressor can be loaded */ + if (ov->compress && !ov->decomp_ops) { + err = request_decompressor(ov); + if (err && !dumppix) + goto out; + } + + err = ov51x_alloc(ov); + if (err < 0) + goto out; + + err = ov51x_init_isoc(ov); + if (err) { + ov51x_dealloc(ov); + goto out; + } + + ov->user++; + file->private_data = vdev; + + if (ov->led_policy == LED_AUTO) + ov51x_led_control(ov, 1); + +out: + up(&ov->lock); + return err; +} + +static int +ov51x_v4l1_close(struct inode *inode, struct file *file) +{ + struct video_device *vdev = file->private_data; + struct usb_ov511 *ov = video_get_drvdata(vdev); + + PDEBUG(4, "ov511_close"); + + down(&ov->lock); + + ov->user--; + ov51x_stop_isoc(ov); + + release_decompressor(ov); + + if (ov->led_policy == LED_AUTO) + ov51x_led_control(ov, 0); + + if (ov->dev) + ov51x_dealloc(ov); + + up(&ov->lock); + + /* Device unplugged while open. Only a minimum of unregistration is done + * here; the disconnect callback already did the rest. */ + if (!ov->dev) { + down(&ov->cbuf_lock); + kfree(ov->cbuf); + ov->cbuf = NULL; + up(&ov->cbuf_lock); + + ov51x_dealloc(ov); + kfree(ov); + ov = NULL; + } + + file->private_data = NULL; + return 0; +} + +/* Do not call this function directly! */ +static int +ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file, + unsigned int cmd, void *arg) +{ + struct video_device *vdev = file->private_data; + struct usb_ov511 *ov = video_get_drvdata(vdev); + PDEBUG(5, "IOCtl: 0x%X", cmd); + + if (!ov->dev) + return -EIO; + + switch (cmd) { + case VIDIOCGCAP: + { + struct video_capability *b = arg; + + PDEBUG(4, "VIDIOCGCAP"); + + memset(b, 0, sizeof(struct video_capability)); + sprintf(b->name, "%s USB Camera", + symbolic(brglist, ov->bridge)); + b->type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE; + b->channels = ov->num_inputs; + b->audios = 0; + b->maxwidth = ov->maxwidth; + b->maxheight = ov->maxheight; + b->minwidth = ov->minwidth; + b->minheight = ov->minheight; + + return 0; + } + case VIDIOCGCHAN: + { + struct video_channel *v = arg; + + PDEBUG(4, "VIDIOCGCHAN"); + + if ((unsigned)(v->channel) >= ov->num_inputs) { + err("Invalid channel (%d)", v->channel); + return -EINVAL; + } + + v->norm = ov->norm; + v->type = VIDEO_TYPE_CAMERA; + v->flags = 0; +// v->flags |= (ov->has_decoder) ? VIDEO_VC_NORM : 0; + v->tuners = 0; + decoder_get_input_name(ov, v->channel, v->name); + + return 0; + } + case VIDIOCSCHAN: + { + struct video_channel *v = arg; + int err; + + PDEBUG(4, "VIDIOCSCHAN"); + + /* Make sure it's not a camera */ + if (!ov->has_decoder) { + if (v->channel == 0) + return 0; + else + return -EINVAL; + } + + if (v->norm != VIDEO_MODE_PAL && + v->norm != VIDEO_MODE_NTSC && + v->norm != VIDEO_MODE_SECAM && + v->norm != VIDEO_MODE_AUTO) { + err("Invalid norm (%d)", v->norm); + return -EINVAL; + } + + if ((unsigned)(v->channel) >= ov->num_inputs) { + err("Invalid channel (%d)", v->channel); + return -EINVAL; + } + + err = decoder_set_input(ov, v->channel); + if (err) + return err; + + err = decoder_set_norm(ov, v->norm); + if (err) + return err; + + return 0; + } + case VIDIOCGPICT: + { + struct video_picture *p = arg; + + PDEBUG(4, "VIDIOCGPICT"); + + memset(p, 0, sizeof(struct video_picture)); + if (sensor_get_picture(ov, p)) + return -EIO; + + /* Can we get these from frame[0]? -claudio? */ + p->depth = ov->frame[0].depth; + p->palette = ov->frame[0].format; + + return 0; + } + case VIDIOCSPICT: + { + struct video_picture *p = arg; + int i, rc; + + PDEBUG(4, "VIDIOCSPICT"); + + if (!get_depth(p->palette)) + return -EINVAL; + + if (sensor_set_picture(ov, p)) + return -EIO; + + if (force_palette && p->palette != force_palette) { + info("Palette rejected (%s)", + symbolic(v4l1_plist, p->palette)); + return -EINVAL; + } + + // FIXME: Format should be independent of frames + if (p->palette != ov->frame[0].format) { + PDEBUG(4, "Detected format change"); + + rc = ov51x_wait_frames_inactive(ov); + if (rc) + return rc; + + mode_init_regs(ov, ov->frame[0].width, + ov->frame[0].height, p->palette, ov->sub_flag); + } + + PDEBUG(4, "Setting depth=%d, palette=%s", + p->depth, symbolic(v4l1_plist, p->palette)); + + for (i = 0; i < OV511_NUMFRAMES; i++) { + ov->frame[i].depth = p->depth; + ov->frame[i].format = p->palette; + } + + return 0; + } + case VIDIOCGCAPTURE: + { + int *vf = arg; + + PDEBUG(4, "VIDIOCGCAPTURE"); + + ov->sub_flag = *vf; + return 0; + } + case VIDIOCSCAPTURE: + { + struct video_capture *vc = arg; + + PDEBUG(4, "VIDIOCSCAPTURE"); + + if (vc->flags) + return -EINVAL; + if (vc->decimation) + return -EINVAL; + + vc->x &= ~3L; + vc->y &= ~1L; + vc->y &= ~31L; + + if (vc->width == 0) + vc->width = 32; + + vc->height /= 16; + vc->height *= 16; + if (vc->height == 0) + vc->height = 16; + + ov->subx = vc->x; + ov->suby = vc->y; + ov->subw = vc->width; + ov->subh = vc->height; + + return 0; + } + case VIDIOCSWIN: + { + struct video_window *vw = arg; + int i, rc; + + PDEBUG(4, "VIDIOCSWIN: %dx%d", vw->width, vw->height); + +#if 0 + if (vw->flags) + return -EINVAL; + if (vw->clipcount) + return -EINVAL; + if (vw->height != ov->maxheight) + return -EINVAL; + if (vw->width != ov->maxwidth) + return -EINVAL; +#endif + + rc = ov51x_wait_frames_inactive(ov); + if (rc) + return rc; + + rc = mode_init_regs(ov, vw->width, vw->height, + ov->frame[0].format, ov->sub_flag); + if (rc < 0) + return rc; + + for (i = 0; i < OV511_NUMFRAMES; i++) { + ov->frame[i].width = vw->width; + ov->frame[i].height = vw->height; + } + + return 0; + } + case VIDIOCGWIN: + { + struct video_window *vw = arg; + + memset(vw, 0, sizeof(struct video_window)); + vw->x = 0; /* FIXME */ + vw->y = 0; + vw->width = ov->frame[0].width; + vw->height = ov->frame[0].height; + vw->flags = 30; + + PDEBUG(4, "VIDIOCGWIN: %dx%d", vw->width, vw->height); + + return 0; + } + case VIDIOCGMBUF: + { + struct video_mbuf *vm = arg; + int i; + + PDEBUG(4, "VIDIOCGMBUF"); + + memset(vm, 0, sizeof(struct video_mbuf)); + vm->size = OV511_NUMFRAMES + * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight); + vm->frames = OV511_NUMFRAMES; + + vm->offsets[0] = 0; + for (i = 1; i < OV511_NUMFRAMES; i++) { + vm->offsets[i] = vm->offsets[i-1] + + MAX_DATA_SIZE(ov->maxwidth, ov->maxheight); + } + + return 0; + } + case VIDIOCMCAPTURE: + { + struct video_mmap *vm = arg; + int rc, depth; + unsigned int f = vm->frame; + + PDEBUG(4, "VIDIOCMCAPTURE: frame: %d, %dx%d, %s", f, vm->width, + vm->height, symbolic(v4l1_plist, vm->format)); + + depth = get_depth(vm->format); + if (!depth) { + PDEBUG(2, "VIDIOCMCAPTURE: invalid format (%s)", + symbolic(v4l1_plist, vm->format)); + return -EINVAL; + } + + if (f >= OV511_NUMFRAMES) { + err("VIDIOCMCAPTURE: invalid frame (%d)", f); + return -EINVAL; + } + + if (vm->width > ov->maxwidth + || vm->height > ov->maxheight) { + err("VIDIOCMCAPTURE: requested dimensions too big"); + return -EINVAL; + } + + if (ov->frame[f].grabstate == FRAME_GRABBING) { + PDEBUG(4, "VIDIOCMCAPTURE: already grabbing"); + return -EBUSY; + } + + if (force_palette && (vm->format != force_palette)) { + PDEBUG(2, "palette rejected (%s)", + symbolic(v4l1_plist, vm->format)); + return -EINVAL; + } + + if ((ov->frame[f].width != vm->width) || + (ov->frame[f].height != vm->height) || + (ov->frame[f].format != vm->format) || + (ov->frame[f].sub_flag != ov->sub_flag) || + (ov->frame[f].depth != depth)) { + PDEBUG(4, "VIDIOCMCAPTURE: change in image parameters"); + + rc = ov51x_wait_frames_inactive(ov); + if (rc) + return rc; + + rc = mode_init_regs(ov, vm->width, vm->height, + vm->format, ov->sub_flag); +#if 0 + if (rc < 0) { + PDEBUG(1, "Got error while initializing regs "); + return ret; + } +#endif + ov->frame[f].width = vm->width; + ov->frame[f].height = vm->height; + ov->frame[f].format = vm->format; + ov->frame[f].sub_flag = ov->sub_flag; + ov->frame[f].depth = depth; + } + + /* Mark it as ready */ + ov->frame[f].grabstate = FRAME_READY; + + PDEBUG(4, "VIDIOCMCAPTURE: renewing frame %d", f); + + return ov51x_new_frame(ov, f); + } + case VIDIOCSYNC: + { + unsigned int fnum = *((unsigned int *) arg); + struct ov511_frame *frame; + int rc; + + if (fnum >= OV511_NUMFRAMES) { + err("VIDIOCSYNC: invalid frame (%d)", fnum); + return -EINVAL; + } + + frame = &ov->frame[fnum]; + + PDEBUG(4, "syncing to frame %d, grabstate = %d", fnum, + frame->grabstate); + + switch (frame->grabstate) { + case FRAME_UNUSED: + return -EINVAL; + case FRAME_READY: + case FRAME_GRABBING: + case FRAME_ERROR: +redo: + if (!ov->dev) + return -EIO; + + rc = wait_event_interruptible(frame->wq, + (frame->grabstate == FRAME_DONE) + || (frame->grabstate == FRAME_ERROR)); + + if (rc) + return rc; + + if (frame->grabstate == FRAME_ERROR) { + if ((rc = ov51x_new_frame(ov, fnum)) < 0) + return rc; + goto redo; + } + /* Fall through */ + case FRAME_DONE: + if (ov->snap_enabled && !frame->snapshot) { + if ((rc = ov51x_new_frame(ov, fnum)) < 0) + return rc; + goto redo; + } + + frame->grabstate = FRAME_UNUSED; + + /* Reset the hardware snapshot button */ + /* FIXME - Is this the best place for this? */ + if ((ov->snap_enabled) && (frame->snapshot)) { + frame->snapshot = 0; + ov51x_clear_snapshot(ov); + } + + /* Decompression, format conversion, etc... */ + ov51x_postprocess(ov, frame); + + break; + } /* end switch */ + + return 0; + } + case VIDIOCGFBUF: + { + struct video_buffer *vb = arg; + + PDEBUG(4, "VIDIOCGFBUF"); + + memset(vb, 0, sizeof(struct video_buffer)); + + return 0; + } + case VIDIOCGUNIT: + { + struct video_unit *vu = arg; + + PDEBUG(4, "VIDIOCGUNIT"); + + memset(vu, 0, sizeof(struct video_unit)); + + vu->video = ov->vdev->minor; + vu->vbi = VIDEO_NO_UNIT; + vu->radio = VIDEO_NO_UNIT; + vu->audio = VIDEO_NO_UNIT; + vu->teletext = VIDEO_NO_UNIT; + + return 0; + } + case OV511IOC_WI2C: + { + struct ov511_i2c_struct *w = arg; + + return i2c_w_slave(ov, w->slave, w->reg, w->value, w->mask); + } + case OV511IOC_RI2C: + { + struct ov511_i2c_struct *r = arg; + int rc; + + rc = i2c_r_slave(ov, r->slave, r->reg); + if (rc < 0) + return rc; + + r->value = rc; + return 0; + } + default: + PDEBUG(3, "Unsupported IOCtl: 0x%X", cmd); + return -ENOIOCTLCMD; + } /* end switch */ + + return 0; +} + +static int +ov51x_v4l1_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct video_device *vdev = file->private_data; + struct usb_ov511 *ov = video_get_drvdata(vdev); + int rc; + + if (down_interruptible(&ov->lock)) + return -EINTR; + + rc = video_usercopy(inode, file, cmd, arg, ov51x_v4l1_ioctl_internal); + + up(&ov->lock); + return rc; +} + +static ssize_t +ov51x_v4l1_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos) +{ + struct video_device *vdev = file->private_data; + int noblock = file->f_flags&O_NONBLOCK; + unsigned long count = cnt; + struct usb_ov511 *ov = video_get_drvdata(vdev); + int i, rc = 0, frmx = -1; + struct ov511_frame *frame; + + if (down_interruptible(&ov->lock)) + return -EINTR; + + PDEBUG(4, "%ld bytes, noblock=%d", count, noblock); + + if (!vdev || !buf) { + rc = -EFAULT; + goto error; + } + + if (!ov->dev) { + rc = -EIO; + goto error; + } + +// FIXME: Only supports two frames + /* See if a frame is completed, then use it. */ + if (ov->frame[0].grabstate >= FRAME_DONE) /* _DONE or _ERROR */ + frmx = 0; + else if (ov->frame[1].grabstate >= FRAME_DONE)/* _DONE or _ERROR */ + frmx = 1; + + /* If nonblocking we return immediately */ + if (noblock && (frmx == -1)) { + rc = -EAGAIN; + goto error; + } + + /* If no FRAME_DONE, look for a FRAME_GRABBING state. */ + /* See if a frame is in process (grabbing), then use it. */ + if (frmx == -1) { + if (ov->frame[0].grabstate == FRAME_GRABBING) + frmx = 0; + else if (ov->frame[1].grabstate == FRAME_GRABBING) + frmx = 1; + } + + /* If no frame is active, start one. */ + if (frmx == -1) { + if ((rc = ov51x_new_frame(ov, frmx = 0))) { + err("read: ov51x_new_frame error"); + goto error; + } + } + + frame = &ov->frame[frmx]; + +restart: + if (!ov->dev) { + rc = -EIO; + goto error; + } + + /* Wait while we're grabbing the image */ + PDEBUG(4, "Waiting image grabbing"); + rc = wait_event_interruptible(frame->wq, + (frame->grabstate == FRAME_DONE) + || (frame->grabstate == FRAME_ERROR)); + + if (rc) + goto error; + + PDEBUG(4, "Got image, frame->grabstate = %d", frame->grabstate); + PDEBUG(4, "bytes_recvd = %d", frame->bytes_recvd); + + if (frame->grabstate == FRAME_ERROR) { + frame->bytes_read = 0; + err("** ick! ** Errored frame %d", ov->curframe); + if (ov51x_new_frame(ov, frmx)) { + err("read: ov51x_new_frame error"); + goto error; + } + goto restart; + } + + + /* Repeat until we get a snapshot frame */ + if (ov->snap_enabled) + PDEBUG(4, "Waiting snapshot frame"); + if (ov->snap_enabled && !frame->snapshot) { + frame->bytes_read = 0; + if ((rc = ov51x_new_frame(ov, frmx))) { + err("read: ov51x_new_frame error"); + goto error; + } + goto restart; + } + + /* Clear the snapshot */ + if (ov->snap_enabled && frame->snapshot) { + frame->snapshot = 0; + ov51x_clear_snapshot(ov); + } + + /* Decompression, format conversion, etc... */ + ov51x_postprocess(ov, frame); + + PDEBUG(4, "frmx=%d, bytes_read=%ld, length=%ld", frmx, + frame->bytes_read, + get_frame_length(frame)); + + /* copy bytes to user space; we allow for partials reads */ +// if ((count + frame->bytes_read) +// > get_frame_length((struct ov511_frame *)frame)) +// count = frame->scanlength - frame->bytes_read; + + /* FIXME - count hardwired to be one frame... */ + count = get_frame_length(frame); + + PDEBUG(4, "Copy to user space: %ld bytes", count); + if ((i = copy_to_user(buf, frame->data + frame->bytes_read, count))) { + PDEBUG(4, "Copy failed! %d bytes not copied", i); + rc = -EFAULT; + goto error; + } + + frame->bytes_read += count; + PDEBUG(4, "{copy} count used=%ld, new bytes_read=%ld", + count, frame->bytes_read); + + /* If all data have been read... */ + if (frame->bytes_read + >= get_frame_length(frame)) { + frame->bytes_read = 0; + +// FIXME: Only supports two frames + /* Mark it as available to be used again. */ + ov->frame[frmx].grabstate = FRAME_UNUSED; + if ((rc = ov51x_new_frame(ov, !frmx))) { + err("ov51x_new_frame returned error"); + goto error; + } + } + + PDEBUG(4, "read finished, returning %ld (sweet)", count); + + up(&ov->lock); + return count; + +error: + up(&ov->lock); + return rc; +} + +static int +ov51x_v4l1_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct video_device *vdev = file->private_data; + unsigned long start = vma->vm_start; + unsigned long size = vma->vm_end - vma->vm_start; + struct usb_ov511 *ov = video_get_drvdata(vdev); + unsigned long page, pos; + + if (ov->dev == NULL) + return -EIO; + + PDEBUG(4, "mmap: %ld (%lX) bytes", size, size); + + if (size > (((OV511_NUMFRAMES + * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight) + + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))) + return -EINVAL; + + if (down_interruptible(&ov->lock)) + return -EINTR; + + pos = (unsigned long)ov->fbuf; + while (size > 0) { + page = vmalloc_to_pfn((void *)pos); + if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) { + up(&ov->lock); + return -EAGAIN; + } + start += PAGE_SIZE; + pos += PAGE_SIZE; + if (size > PAGE_SIZE) + size -= PAGE_SIZE; + else + size = 0; + } + + up(&ov->lock); + return 0; +} + +static struct file_operations ov511_fops = { + .owner = THIS_MODULE, + .open = ov51x_v4l1_open, + .release = ov51x_v4l1_close, + .read = ov51x_v4l1_read, + .mmap = ov51x_v4l1_mmap, + .ioctl = ov51x_v4l1_ioctl, + .llseek = no_llseek, +}; + +static struct video_device vdev_template = { + .name = "OV511 USB Camera", + .fops = &ov511_fops, + .release = video_device_release, + .minor = -1, +}; + +/**************************************************************************** + * + * OV511 and sensor configuration + * + ***************************************************************************/ + +/* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses + * the same register settings as the OV7610, since they are very similar. + */ +static int +ov7xx0_configure(struct usb_ov511 *ov) +{ + int i, success; + int rc; + + /* Lawrence Glaister reports: + * + * Register 0x0f in the 7610 has the following effects: + * + * 0x85 (AEC method 1): Best overall, good contrast range + * 0x45 (AEC method 2): Very overexposed + * 0xa5 (spec sheet default): Ok, but the black level is + * shifted resulting in loss of contrast + * 0x05 (old driver setting): very overexposed, too much + * contrast + */ + static struct ov511_regvals aRegvalsNorm7610[] = { + { OV511_I2C_BUS, 0x10, 0xff }, + { OV511_I2C_BUS, 0x16, 0x06 }, + { OV511_I2C_BUS, 0x28, 0x24 }, + { OV511_I2C_BUS, 0x2b, 0xac }, + { OV511_I2C_BUS, 0x12, 0x00 }, + { OV511_I2C_BUS, 0x38, 0x81 }, + { OV511_I2C_BUS, 0x28, 0x24 }, /* 0c */ + { OV511_I2C_BUS, 0x0f, 0x85 }, /* lg's setting */ + { OV511_I2C_BUS, 0x15, 0x01 }, + { OV511_I2C_BUS, 0x20, 0x1c }, + { OV511_I2C_BUS, 0x23, 0x2a }, + { OV511_I2C_BUS, 0x24, 0x10 }, + { OV511_I2C_BUS, 0x25, 0x8a }, + { OV511_I2C_BUS, 0x26, 0xa2 }, + { OV511_I2C_BUS, 0x27, 0xc2 }, + { OV511_I2C_BUS, 0x2a, 0x04 }, + { OV511_I2C_BUS, 0x2c, 0xfe }, + { OV511_I2C_BUS, 0x2d, 0x93 }, + { OV511_I2C_BUS, 0x30, 0x71 }, + { OV511_I2C_BUS, 0x31, 0x60 }, + { OV511_I2C_BUS, 0x32, 0x26 }, + { OV511_I2C_BUS, 0x33, 0x20 }, + { OV511_I2C_BUS, 0x34, 0x48 }, + { OV511_I2C_BUS, 0x12, 0x24 }, + { OV511_I2C_BUS, 0x11, 0x01 }, + { OV511_I2C_BUS, 0x0c, 0x24 }, + { OV511_I2C_BUS, 0x0d, 0x24 }, + { OV511_DONE_BUS, 0x0, 0x00 }, + }; + + static struct ov511_regvals aRegvalsNorm7620[] = { + { OV511_I2C_BUS, 0x00, 0x00 }, + { OV511_I2C_BUS, 0x01, 0x80 }, + { OV511_I2C_BUS, 0x02, 0x80 }, + { OV511_I2C_BUS, 0x03, 0xc0 }, + { OV511_I2C_BUS, 0x06, 0x60 }, + { OV511_I2C_BUS, 0x07, 0x00 }, + { OV511_I2C_BUS, 0x0c, 0x24 }, + { OV511_I2C_BUS, 0x0c, 0x24 }, + { OV511_I2C_BUS, 0x0d, 0x24 }, + { OV511_I2C_BUS, 0x11, 0x01 }, + { OV511_I2C_BUS, 0x12, 0x24 }, + { OV511_I2C_BUS, 0x13, 0x01 }, + { OV511_I2C_BUS, 0x14, 0x84 }, + { OV511_I2C_BUS, 0x15, 0x01 }, + { OV511_I2C_BUS, 0x16, 0x03 }, + { OV511_I2C_BUS, 0x17, 0x2f }, + { OV511_I2C_BUS, 0x18, 0xcf }, + { OV511_I2C_BUS, 0x19, 0x06 }, + { OV511_I2C_BUS, 0x1a, 0xf5 }, + { OV511_I2C_BUS, 0x1b, 0x00 }, + { OV511_I2C_BUS, 0x20, 0x18 }, + { OV511_I2C_BUS, 0x21, 0x80 }, + { OV511_I2C_BUS, 0x22, 0x80 }, + { OV511_I2C_BUS, 0x23, 0x00 }, + { OV511_I2C_BUS, 0x26, 0xa2 }, + { OV511_I2C_BUS, 0x27, 0xea }, + { OV511_I2C_BUS, 0x28, 0x20 }, + { OV511_I2C_BUS, 0x29, 0x00 }, + { OV511_I2C_BUS, 0x2a, 0x10 }, + { OV511_I2C_BUS, 0x2b, 0x00 }, + { OV511_I2C_BUS, 0x2c, 0x88 }, + { OV511_I2C_BUS, 0x2d, 0x91 }, + { OV511_I2C_BUS, 0x2e, 0x80 }, + { OV511_I2C_BUS, 0x2f, 0x44 }, + { OV511_I2C_BUS, 0x60, 0x27 }, + { OV511_I2C_BUS, 0x61, 0x02 }, + { OV511_I2C_BUS, 0x62, 0x5f }, + { OV511_I2C_BUS, 0x63, 0xd5 }, + { OV511_I2C_BUS, 0x64, 0x57 }, + { OV511_I2C_BUS, 0x65, 0x83 }, + { OV511_I2C_BUS, 0x66, 0x55 }, + { OV511_I2C_BUS, 0x67, 0x92 }, + { OV511_I2C_BUS, 0x68, 0xcf }, + { OV511_I2C_BUS, 0x69, 0x76 }, + { OV511_I2C_BUS, 0x6a, 0x22 }, + { OV511_I2C_BUS, 0x6b, 0x00 }, + { OV511_I2C_BUS, 0x6c, 0x02 }, + { OV511_I2C_BUS, 0x6d, 0x44 }, + { OV511_I2C_BUS, 0x6e, 0x80 }, + { OV511_I2C_BUS, 0x6f, 0x1d }, + { OV511_I2C_BUS, 0x70, 0x8b }, + { OV511_I2C_BUS, 0x71, 0x00 }, + { OV511_I2C_BUS, 0x72, 0x14 }, + { OV511_I2C_BUS, 0x73, 0x54 }, + { OV511_I2C_BUS, 0x74, 0x00 }, + { OV511_I2C_BUS, 0x75, 0x8e }, + { OV511_I2C_BUS, 0x76, 0x00 }, + { OV511_I2C_BUS, 0x77, 0xff }, + { OV511_I2C_BUS, 0x78, 0x80 }, + { OV511_I2C_BUS, 0x79, 0x80 }, + { OV511_I2C_BUS, 0x7a, 0x80 }, + { OV511_I2C_BUS, 0x7b, 0xe2 }, + { OV511_I2C_BUS, 0x7c, 0x00 }, + { OV511_DONE_BUS, 0x0, 0x00 }, + }; + + PDEBUG(4, "starting configuration"); + + /* This looks redundant, but is necessary for WebCam 3 */ + ov->primary_i2c_slave = OV7xx0_SID; + if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0) + return -1; + + if (init_ov_sensor(ov) >= 0) { + PDEBUG(1, "OV7xx0 sensor initalized (method 1)"); + } else { + /* Reset the 76xx */ + if (i2c_w(ov, 0x12, 0x80) < 0) + return -1; + + /* Wait for it to initialize */ + msleep(150); + + i = 0; + success = 0; + while (i <= i2c_detect_tries) { + if ((i2c_r(ov, OV7610_REG_ID_HIGH) == 0x7F) && + (i2c_r(ov, OV7610_REG_ID_LOW) == 0xA2)) { + success = 1; + break; + } else { + i++; + } + } + +// Was (i == i2c_detect_tries) previously. This obviously used to always report +// success. Whether anyone actually depended on that bug is unknown + if ((i >= i2c_detect_tries) && (success == 0)) { + err("Failed to read sensor ID. You might not have an"); + err("OV7610/20, or it may be not responding. Report"); + err("this to " EMAIL); + err("This is only a warning. You can attempt to use"); + err("your camera anyway"); +// Only issue a warning for now +// return -1; + } else { + PDEBUG(1, "OV7xx0 initialized (method 2, %dx)", i+1); + } + } + + /* Detect sensor (sub)type */ + rc = i2c_r(ov, OV7610_REG_COM_I); + + if (rc < 0) { + err("Error detecting sensor type"); + return -1; + } else if ((rc & 3) == 3) { + info("Sensor is an OV7610"); + ov->sensor = SEN_OV7610; + } else if ((rc & 3) == 1) { + /* I don't know what's different about the 76BE yet. */ + if (i2c_r(ov, 0x15) & 1) + info("Sensor is an OV7620AE"); + else + info("Sensor is an OV76BE"); + + /* OV511+ will return all zero isoc data unless we + * configure the sensor as a 7620. Someone needs to + * find the exact reg. setting that causes this. */ + if (ov->bridge == BRG_OV511PLUS) { + info("Enabling 511+/7620AE workaround"); + ov->sensor = SEN_OV7620; + } else { + ov->sensor = SEN_OV76BE; + } + } else if ((rc & 3) == 0) { + info("Sensor is an OV7620"); + ov->sensor = SEN_OV7620; + } else { + err("Unknown image sensor version: %d", rc & 3); + return -1; + } + + if (ov->sensor == SEN_OV7620) { + PDEBUG(4, "Writing 7620 registers"); + if (write_regvals(ov, aRegvalsNorm7620)) + return -1; + } else { + PDEBUG(4, "Writing 7610 registers"); + if (write_regvals(ov, aRegvalsNorm7610)) + return -1; + } + + /* Set sensor-specific vars */ + ov->maxwidth = 640; + ov->maxheight = 480; + ov->minwidth = 64; + ov->minheight = 48; + + // FIXME: These do not match the actual settings yet + ov->brightness = 0x80 << 8; + ov->contrast = 0x80 << 8; + ov->colour = 0x80 << 8; + ov->hue = 0x80 << 8; + + return 0; +} + +/* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */ +static int +ov6xx0_configure(struct usb_ov511 *ov) +{ + int rc; + + static struct ov511_regvals aRegvalsNorm6x20[] = { + { OV511_I2C_BUS, 0x12, 0x80 }, /* reset */ + { OV511_I2C_BUS, 0x11, 0x01 }, + { OV511_I2C_BUS, 0x03, 0x60 }, + { OV511_I2C_BUS, 0x05, 0x7f }, /* For when autoadjust is off */ + { OV511_I2C_BUS, 0x07, 0xa8 }, + /* The ratio of 0x0c and 0x0d controls the white point */ + { OV511_I2C_BUS, 0x0c, 0x24 }, + { OV511_I2C_BUS, 0x0d, 0x24 }, + { OV511_I2C_BUS, 0x0f, 0x15 }, /* COMS */ + { OV511_I2C_BUS, 0x10, 0x75 }, /* AEC Exposure time */ + { OV511_I2C_BUS, 0x12, 0x24 }, /* Enable AGC */ + { OV511_I2C_BUS, 0x14, 0x04 }, + /* 0x16: 0x06 helps frame stability with moving objects */ + { OV511_I2C_BUS, 0x16, 0x06 }, +// { OV511_I2C_BUS, 0x20, 0x30 }, /* Aperture correction enable */ + { OV511_I2C_BUS, 0x26, 0xb2 }, /* BLC enable */ + /* 0x28: 0x05 Selects RGB format if RGB on */ + { OV511_I2C_BUS, 0x28, 0x05 }, + { OV511_I2C_BUS, 0x2a, 0x04 }, /* Disable framerate adjust */ +// { OV511_I2C_BUS, 0x2b, 0xac }, /* Framerate; Set 2a[7] first */ + { OV511_I2C_BUS, 0x2d, 0x99 }, + { OV511_I2C_BUS, 0x33, 0xa0 }, /* Color Processing Parameter */ + { OV511_I2C_BUS, 0x34, 0xd2 }, /* Max A/D range */ + { OV511_I2C_BUS, 0x38, 0x8b }, + { OV511_I2C_BUS, 0x39, 0x40 }, + + { OV511_I2C_BUS, 0x3c, 0x39 }, /* Enable AEC mode changing */ + { OV511_I2C_BUS, 0x3c, 0x3c }, /* Change AEC mode */ + { OV511_I2C_BUS, 0x3c, 0x24 }, /* Disable AEC mode changing */ + + { OV511_I2C_BUS, 0x3d, 0x80 }, + /* These next two registers (0x4a, 0x4b) are undocumented. They + * control the color balance */ + { OV511_I2C_BUS, 0x4a, 0x80 }, + { OV511_I2C_BUS, 0x4b, 0x80 }, + { OV511_I2C_BUS, 0x4d, 0xd2 }, /* This reduces noise a bit */ + { OV511_I2C_BUS, 0x4e, 0xc1 }, + { OV511_I2C_BUS, 0x4f, 0x04 }, +// Do 50-53 have any effect? +// Toggle 0x12[2] off and on here? + { OV511_DONE_BUS, 0x0, 0x00 }, /* END MARKER */ + }; + + static struct ov511_regvals aRegvalsNorm6x30[] = { + /*OK*/ { OV511_I2C_BUS, 0x12, 0x80 }, /* reset */ + { OV511_I2C_BUS, 0x11, 0x00 }, + /*OK*/ { OV511_I2C_BUS, 0x03, 0x60 }, + /*0A?*/ { OV511_I2C_BUS, 0x05, 0x7f }, /* For when autoadjust is off */ + { OV511_I2C_BUS, 0x07, 0xa8 }, + /* The ratio of 0x0c and 0x0d controls the white point */ + /*OK*/ { OV511_I2C_BUS, 0x0c, 0x24 }, + /*OK*/ { OV511_I2C_BUS, 0x0d, 0x24 }, + /*A*/ { OV511_I2C_BUS, 0x0e, 0x20 }, +// /*04?*/ { OV511_I2C_BUS, 0x14, 0x80 }, + { OV511_I2C_BUS, 0x16, 0x03 }, +// /*OK*/ { OV511_I2C_BUS, 0x20, 0x30 }, /* Aperture correction enable */ + // 21 & 22? The suggested values look wrong. Go with default + /*A*/ { OV511_I2C_BUS, 0x23, 0xc0 }, + /*A*/ { OV511_I2C_BUS, 0x25, 0x9a }, // Check this against default +// /*OK*/ { OV511_I2C_BUS, 0x26, 0xb2 }, /* BLC enable */ + + /* 0x28: 0x05 Selects RGB format if RGB on */ +// /*04?*/ { OV511_I2C_BUS, 0x28, 0x05 }, +// /*04?*/ { OV511_I2C_BUS, 0x28, 0x45 }, // DEBUG: Tristate UV bus + + /*OK*/ { OV511_I2C_BUS, 0x2a, 0x04 }, /* Disable framerate adjust */ +// /*OK*/ { OV511_I2C_BUS, 0x2b, 0xac }, /* Framerate; Set 2a[7] first */ + { OV511_I2C_BUS, 0x2d, 0x99 }, +// /*A*/ { OV511_I2C_BUS, 0x33, 0x26 }, // Reserved bits on 6620 +// /*d2?*/ { OV511_I2C_BUS, 0x34, 0x03 }, /* Max A/D range */ +// /*8b?*/ { OV511_I2C_BUS, 0x38, 0x83 }, +// /*40?*/ { OV511_I2C_BUS, 0x39, 0xc0 }, // 6630 adds bit 7 +// { OV511_I2C_BUS, 0x3c, 0x39 }, /* Enable AEC mode changing */ +// { OV511_I2C_BUS, 0x3c, 0x3c }, /* Change AEC mode */ +// { OV511_I2C_BUS, 0x3c, 0x24 }, /* Disable AEC mode changing */ + { OV511_I2C_BUS, 0x3d, 0x80 }, +// /*A*/ { OV511_I2C_BUS, 0x3f, 0x0e }, + + /* These next two registers (0x4a, 0x4b) are undocumented. They + * control the color balance */ +// /*OK?*/ { OV511_I2C_BUS, 0x4a, 0x80 }, // Check these +// /*OK?*/ { OV511_I2C_BUS, 0x4b, 0x80 }, + { OV511_I2C_BUS, 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */ + /*c1?*/ { OV511_I2C_BUS, 0x4e, 0x40 }, + + /* UV average mode, color killer: strongest */ + { OV511_I2C_BUS, 0x4f, 0x07 }, + + { OV511_I2C_BUS, 0x54, 0x23 }, /* Max AGC gain: 18dB */ + { OV511_I2C_BUS, 0x57, 0x81 }, /* (default) */ + { OV511_I2C_BUS, 0x59, 0x01 }, /* AGC dark current comp: +1 */ + { OV511_I2C_BUS, 0x5a, 0x2c }, /* (undocumented) */ + { OV511_I2C_BUS, 0x5b, 0x0f }, /* AWB chrominance levels */ +// { OV511_I2C_BUS, 0x5c, 0x10 }, + { OV511_DONE_BUS, 0x0, 0x00 }, /* END MARKER */ + }; + + PDEBUG(4, "starting sensor configuration"); + + if (init_ov_sensor(ov) < 0) { + err("Failed to read sensor ID. You might not have an OV6xx0,"); + err("or it may be not responding. Report this to " EMAIL); + return -1; + } else { + PDEBUG(1, "OV6xx0 sensor detected"); + } + + /* Detect sensor (sub)type */ + rc = i2c_r(ov, OV7610_REG_COM_I); + + if (rc < 0) { + err("Error detecting sensor type"); + return -1; + } + + if ((rc & 3) == 0) { + ov->sensor = SEN_OV6630; + info("Sensor is an OV6630"); + } else if ((rc & 3) == 1) { + ov->sensor = SEN_OV6620; + info("Sensor is an OV6620"); + } else if ((rc & 3) == 2) { + ov->sensor = SEN_OV6630; + info("Sensor is an OV6630AE"); + } else if ((rc & 3) == 3) { + ov->sensor = SEN_OV6630; + info("Sensor is an OV6630AF"); + } + + /* Set sensor-specific vars */ + ov->maxwidth = 352; + ov->maxheight = 288; + ov->minwidth = 64; + ov->minheight = 48; + + // FIXME: These do not match the actual settings yet + ov->brightness = 0x80 << 8; + ov->contrast = 0x80 << 8; + ov->colour = 0x80 << 8; + ov->hue = 0x80 << 8; + + if (ov->sensor == SEN_OV6620) { + PDEBUG(4, "Writing 6x20 registers"); + if (write_regvals(ov, aRegvalsNorm6x20)) + return -1; + } else { + PDEBUG(4, "Writing 6x30 registers"); + if (write_regvals(ov, aRegvalsNorm6x30)) + return -1; + } + + return 0; +} + +/* This initializes the KS0127 and KS0127B video decoders. */ +static int +ks0127_configure(struct usb_ov511 *ov) +{ + int rc; + +// FIXME: I don't know how to sync or reset it yet +#if 0 + if (ov51x_init_ks_sensor(ov) < 0) { + err("Failed to initialize the KS0127"); + return -1; + } else { + PDEBUG(1, "KS012x(B) sensor detected"); + } +#endif + + /* Detect decoder subtype */ + rc = i2c_r(ov, 0x00); + if (rc < 0) { + err("Error detecting sensor type"); + return -1; + } else if (rc & 0x08) { + rc = i2c_r(ov, 0x3d); + if (rc < 0) { + err("Error detecting sensor type"); + return -1; + } else if ((rc & 0x0f) == 0) { + info("Sensor is a KS0127"); + ov->sensor = SEN_KS0127; + } else if ((rc & 0x0f) == 9) { + info("Sensor is a KS0127B Rev. A"); + ov->sensor = SEN_KS0127B; + } + } else { + err("Error: Sensor is an unsupported KS0122"); + return -1; + } + + /* Set sensor-specific vars */ + ov->maxwidth = 640; + ov->maxheight = 480; + ov->minwidth = 64; + ov->minheight = 48; + + // FIXME: These do not match the actual settings yet + ov->brightness = 0x80 << 8; + ov->contrast = 0x80 << 8; + ov->colour = 0x80 << 8; + ov->hue = 0x80 << 8; + + /* This device is not supported yet. Bail out now... */ + err("This sensor is not supported yet."); + return -1; + + return 0; +} + +/* This initializes the SAA7111A video decoder. */ +static int +saa7111a_configure(struct usb_ov511 *ov) +{ + int rc; + + /* Since there is no register reset command, all registers must be + * written, otherwise gives erratic results */ + static struct ov511_regvals aRegvalsNormSAA7111A[] = { + { OV511_I2C_BUS, 0x06, 0xce }, + { OV511_I2C_BUS, 0x07, 0x00 }, + { OV511_I2C_BUS, 0x10, 0x44 }, /* YUV422, 240/286 lines */ + { OV511_I2C_BUS, 0x0e, 0x01 }, /* NTSC M or PAL BGHI */ + { OV511_I2C_BUS, 0x00, 0x00 }, + { OV511_I2C_BUS, 0x01, 0x00 }, + { OV511_I2C_BUS, 0x03, 0x23 }, + { OV511_I2C_BUS, 0x04, 0x00 }, + { OV511_I2C_BUS, 0x05, 0x00 }, + { OV511_I2C_BUS, 0x08, 0xc8 }, /* Auto field freq */ + { OV511_I2C_BUS, 0x09, 0x01 }, /* Chrom. trap off, APER=0.25 */ + { OV511_I2C_BUS, 0x0a, 0x80 }, /* BRIG=128 */ + { OV511_I2C_BUS, 0x0b, 0x40 }, /* CONT=1.0 */ + { OV511_I2C_BUS, 0x0c, 0x40 }, /* SATN=1.0 */ + { OV511_I2C_BUS, 0x0d, 0x00 }, /* HUE=0 */ + { OV511_I2C_BUS, 0x0f, 0x00 }, + { OV511_I2C_BUS, 0x11, 0x0c }, + { OV511_I2C_BUS, 0x12, 0x00 }, + { OV511_I2C_BUS, 0x13, 0x00 }, + { OV511_I2C_BUS, 0x14, 0x00 }, + { OV511_I2C_BUS, 0x15, 0x00 }, + { OV511_I2C_BUS, 0x16, 0x00 }, + { OV511_I2C_BUS, 0x17, 0x00 }, + { OV511_I2C_BUS, 0x02, 0xc0 }, /* Composite input 0 */ + { OV511_DONE_BUS, 0x0, 0x00 }, + }; + +// FIXME: I don't know how to sync or reset it yet +#if 0 + if (ov51x_init_saa_sensor(ov) < 0) { + err("Failed to initialize the SAA7111A"); + return -1; + } else { + PDEBUG(1, "SAA7111A sensor detected"); + } +#endif + + /* 640x480 not supported with PAL */ + if (ov->pal) { + ov->maxwidth = 320; + ov->maxheight = 240; /* Even field only */ + } else { + ov->maxwidth = 640; + ov->maxheight = 480; /* Even/Odd fields */ + } + + ov->minwidth = 320; + ov->minheight = 240; /* Even field only */ + + ov->has_decoder = 1; + ov->num_inputs = 8; + ov->norm = VIDEO_MODE_AUTO; + ov->stop_during_set = 0; /* Decoder guarantees stable image */ + + /* Decoder doesn't change these values, so we use these instead of + * acutally reading the registers (which doesn't work) */ + ov->brightness = 0x80 << 8; + ov->contrast = 0x40 << 9; + ov->colour = 0x40 << 9; + ov->hue = 32768; + + PDEBUG(4, "Writing SAA7111A registers"); + if (write_regvals(ov, aRegvalsNormSAA7111A)) + return -1; + + /* Detect version of decoder. This must be done after writing the + * initial regs or the decoder will lock up. */ + rc = i2c_r(ov, 0x00); + + if (rc < 0) { + err("Error detecting sensor version"); + return -1; + } else { + info("Sensor is an SAA7111A (version 0x%x)", rc); + ov->sensor = SEN_SAA7111A; + } + + // FIXME: Fix this for OV518(+) + /* Latch to negative edge of clock. Otherwise, we get incorrect + * colors and jitter in the digital signal. */ + if (ov->bclass == BCL_OV511) + reg_w(ov, 0x11, 0x00); + else + warn("SAA7111A not yet supported with OV518/OV518+"); + + return 0; +} + +/* This initializes the OV511/OV511+ and the sensor */ +static int +ov511_configure(struct usb_ov511 *ov) +{ + static struct ov511_regvals aRegvalsInit511[] = { + { OV511_REG_BUS, R51x_SYS_RESET, 0x7f }, + { OV511_REG_BUS, R51x_SYS_INIT, 0x01 }, + { OV511_REG_BUS, R51x_SYS_RESET, 0x7f }, + { OV511_REG_BUS, R51x_SYS_INIT, 0x01 }, + { OV511_REG_BUS, R51x_SYS_RESET, 0x3f }, + { OV511_REG_BUS, R51x_SYS_INIT, 0x01 }, + { OV511_REG_BUS, R51x_SYS_RESET, 0x3d }, + { OV511_DONE_BUS, 0x0, 0x00}, + }; + + static struct ov511_regvals aRegvalsNorm511[] = { + { OV511_REG_BUS, R511_DRAM_FLOW_CTL, 0x01 }, + { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 }, + { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 }, + { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 }, + { OV511_REG_BUS, R511_FIFO_OPTS, 0x1f }, + { OV511_REG_BUS, R511_COMP_EN, 0x00 }, + { OV511_REG_BUS, R511_COMP_LUT_EN, 0x03 }, + { OV511_DONE_BUS, 0x0, 0x00 }, + }; + + static struct ov511_regvals aRegvalsNorm511Plus[] = { + { OV511_REG_BUS, R511_DRAM_FLOW_CTL, 0xff }, + { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 }, + { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 }, + { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 }, + { OV511_REG_BUS, R511_FIFO_OPTS, 0xff }, + { OV511_REG_BUS, R511_COMP_EN, 0x00 }, + { OV511_REG_BUS, R511_COMP_LUT_EN, 0x03 }, + { OV511_DONE_BUS, 0x0, 0x00 }, + }; + + PDEBUG(4, ""); + + ov->customid = reg_r(ov, R511_SYS_CUST_ID); + if (ov->customid < 0) { + err("Unable to read camera bridge registers"); + goto error; + } + + PDEBUG (1, "CustomID = %d", ov->customid); + ov->desc = symbolic(camlist, ov->customid); + info("model: %s", ov->desc); + + if (0 == strcmp(ov->desc, NOT_DEFINED_STR)) { + err("Camera type (%d) not recognized", ov->customid); + err("Please notify " EMAIL " of the name,"); + err("manufacturer, model, and this number of your camera."); + err("Also include the output of the detection process."); + } + + if (ov->customid == 70) /* USB Life TV (PAL/SECAM) */ + ov->pal = 1; + + if (write_regvals(ov, aRegvalsInit511)) + goto error; + + if (ov->led_policy == LED_OFF || ov->led_policy == LED_AUTO) + ov51x_led_control(ov, 0); + + /* The OV511+ has undocumented bits in the flow control register. + * Setting it to 0xff fixes the corruption with moving objects. */ + if (ov->bridge == BRG_OV511) { + if (write_regvals(ov, aRegvalsNorm511)) + goto error; + } else if (ov->bridge == BRG_OV511PLUS) { + if (write_regvals(ov, aRegvalsNorm511Plus)) + goto error; + } else { + err("Invalid bridge"); + } + + if (ov511_init_compression(ov)) + goto error; + + ov->packet_numbering = 1; + ov511_set_packet_size(ov, 0); + + ov->snap_enabled = snapshot; + + /* Test for 7xx0 */ + PDEBUG(3, "Testing for 0V7xx0"); + ov->primary_i2c_slave = OV7xx0_SID; + if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0) + goto error; + + if (i2c_w(ov, 0x12, 0x80) < 0) { + /* Test for 6xx0 */ + PDEBUG(3, "Testing for 0V6xx0"); + ov->primary_i2c_slave = OV6xx0_SID; + if (ov51x_set_slave_ids(ov, OV6xx0_SID) < 0) + goto error; + + if (i2c_w(ov, 0x12, 0x80) < 0) { + /* Test for 8xx0 */ + PDEBUG(3, "Testing for 0V8xx0"); + ov->primary_i2c_slave = OV8xx0_SID; + if (ov51x_set_slave_ids(ov, OV8xx0_SID) < 0) + goto error; + + if (i2c_w(ov, 0x12, 0x80) < 0) { + /* Test for SAA7111A */ + PDEBUG(3, "Testing for SAA7111A"); + ov->primary_i2c_slave = SAA7111A_SID; + if (ov51x_set_slave_ids(ov, SAA7111A_SID) < 0) + goto error; + + if (i2c_w(ov, 0x0d, 0x00) < 0) { + /* Test for KS0127 */ + PDEBUG(3, "Testing for KS0127"); + ov->primary_i2c_slave = KS0127_SID; + if (ov51x_set_slave_ids(ov, KS0127_SID) < 0) + goto error; + + if (i2c_w(ov, 0x10, 0x00) < 0) { + err("Can't determine sensor slave IDs"); + goto error; + } else { + if (ks0127_configure(ov) < 0) { + err("Failed to configure KS0127"); + goto error; + } + } + } else { + if (saa7111a_configure(ov) < 0) { + err("Failed to configure SAA7111A"); + goto error; + } + } + } else { + err("Detected unsupported OV8xx0 sensor"); + goto error; + } + } else { + if (ov6xx0_configure(ov) < 0) { + err("Failed to configure OV6xx0"); + goto error; + } + } + } else { + if (ov7xx0_configure(ov) < 0) { + err("Failed to configure OV7xx0"); + goto error; + } + } + + return 0; + +error: + err("OV511 Config failed"); + + return -EBUSY; +} + +/* This initializes the OV518/OV518+ and the sensor */ +static int +ov518_configure(struct usb_ov511 *ov) +{ + /* For 518 and 518+ */ + static struct ov511_regvals aRegvalsInit518[] = { + { OV511_REG_BUS, R51x_SYS_RESET, 0x40 }, + { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 }, + { OV511_REG_BUS, R51x_SYS_RESET, 0x3e }, + { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 }, + { OV511_REG_BUS, R51x_SYS_RESET, 0x00 }, + { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 }, + { OV511_REG_BUS, 0x46, 0x00 }, + { OV511_REG_BUS, 0x5d, 0x03 }, + { OV511_DONE_BUS, 0x0, 0x00}, + }; + + static struct ov511_regvals aRegvalsNorm518[] = { + { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 }, /* Reset */ + { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 }, /* Enable */ + { OV511_REG_BUS, 0x31, 0x0f }, + { OV511_REG_BUS, 0x5d, 0x03 }, + { OV511_REG_BUS, 0x24, 0x9f }, + { OV511_REG_BUS, 0x25, 0x90 }, + { OV511_REG_BUS, 0x20, 0x00 }, + { OV511_REG_BUS, 0x51, 0x04 }, + { OV511_REG_BUS, 0x71, 0x19 }, + { OV511_DONE_BUS, 0x0, 0x00 }, + }; + + static struct ov511_regvals aRegvalsNorm518Plus[] = { + { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 }, /* Reset */ + { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 }, /* Enable */ + { OV511_REG_BUS, 0x31, 0x0f }, + { OV511_REG_BUS, 0x5d, 0x03 }, + { OV511_REG_BUS, 0x24, 0x9f }, + { OV511_REG_BUS, 0x25, 0x90 }, + { OV511_REG_BUS, 0x20, 0x60 }, + { OV511_REG_BUS, 0x51, 0x02 }, + { OV511_REG_BUS, 0x71, 0x19 }, + { OV511_REG_BUS, 0x40, 0xff }, + { OV511_REG_BUS, 0x41, 0x42 }, + { OV511_REG_BUS, 0x46, 0x00 }, + { OV511_REG_BUS, 0x33, 0x04 }, + { OV511_REG_BUS, 0x21, 0x19 }, + { OV511_REG_BUS, 0x3f, 0x10 }, + { OV511_DONE_BUS, 0x0, 0x00 }, + }; + + PDEBUG(4, ""); + + /* First 5 bits of custom ID reg are a revision ID on OV518 */ + info("Device revision %d", 0x1F & reg_r(ov, R511_SYS_CUST_ID)); + + /* Give it the default description */ + ov->desc = symbolic(camlist, 0); + + if (write_regvals(ov, aRegvalsInit518)) + goto error; + + /* Set LED GPIO pin to output mode */ + if (reg_w_mask(ov, 0x57, 0x00, 0x02) < 0) + goto error; + + /* LED is off by default with OV518; have to explicitly turn it on */ + if (ov->led_policy == LED_OFF || ov->led_policy == LED_AUTO) + ov51x_led_control(ov, 0); + else + ov51x_led_control(ov, 1); + + /* Don't require compression if dumppix is enabled; otherwise it's + * required. OV518 has no uncompressed mode, to save RAM. */ + if (!dumppix && !ov->compress) { + ov->compress = 1; + warn("Compression required with OV518...enabling"); + } + + if (ov->bridge == BRG_OV518) { + if (write_regvals(ov, aRegvalsNorm518)) + goto error; + } else if (ov->bridge == BRG_OV518PLUS) { + if (write_regvals(ov, aRegvalsNorm518Plus)) + goto error; + } else { + err("Invalid bridge"); + } + + if (reg_w(ov, 0x2f, 0x80) < 0) + goto error; + + if (ov518_init_compression(ov)) + goto error; + + if (ov->bridge == BRG_OV518) + { + struct usb_interface *ifp; + struct usb_host_interface *alt; + __u16 mxps = 0; + + ifp = usb_ifnum_to_if(ov->dev, 0); + if (ifp) { + alt = usb_altnum_to_altsetting(ifp, 7); + if (alt) + mxps = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); + } + + /* Some OV518s have packet numbering by default, some don't */ + if (mxps == 897) + ov->packet_numbering = 1; + else + ov->packet_numbering = 0; + } else { + /* OV518+ has packet numbering turned on by default */ + ov->packet_numbering = 1; + } + + ov518_set_packet_size(ov, 0); + + ov->snap_enabled = snapshot; + + /* Test for 76xx */ + ov->primary_i2c_slave = OV7xx0_SID; + if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0) + goto error; + + /* The OV518 must be more aggressive about sensor detection since + * I2C write will never fail if the sensor is not present. We have + * to try to initialize the sensor to detect its presence */ + + if (init_ov_sensor(ov) < 0) { + /* Test for 6xx0 */ + ov->primary_i2c_slave = OV6xx0_SID; + if (ov51x_set_slave_ids(ov, OV6xx0_SID) < 0) + goto error; + + if (init_ov_sensor(ov) < 0) { + /* Test for 8xx0 */ + ov->primary_i2c_slave = OV8xx0_SID; + if (ov51x_set_slave_ids(ov, OV8xx0_SID) < 0) + goto error; + + if (init_ov_sensor(ov) < 0) { + err("Can't determine sensor slave IDs"); + goto error; + } else { + err("Detected unsupported OV8xx0 sensor"); + goto error; + } + } else { + if (ov6xx0_configure(ov) < 0) { + err("Failed to configure OV6xx0"); + goto error; + } + } + } else { + if (ov7xx0_configure(ov) < 0) { + err("Failed to configure OV7xx0"); + goto error; + } + } + + ov->maxwidth = 352; + ov->maxheight = 288; + + // The OV518 cannot go as low as the sensor can + ov->minwidth = 160; + ov->minheight = 120; + + return 0; + +error: + err("OV518 Config failed"); + + return -EBUSY; +} + +/**************************************************************************** + * sysfs + ***************************************************************************/ + +static inline struct usb_ov511 *cd_to_ov(struct device *cd) +{ + struct video_device *vdev = to_video_device(cd); + return video_get_drvdata(vdev); +} + +static ssize_t show_custom_id(struct device *cd, struct device_attribute *attr, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + return sprintf(buf, "%d\n", ov->customid); +} +static DEVICE_ATTR(custom_id, S_IRUGO, show_custom_id, NULL); + +static ssize_t show_model(struct device *cd, struct device_attribute *attr, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + return sprintf(buf, "%s\n", ov->desc); +} +static DEVICE_ATTR(model, S_IRUGO, show_model, NULL); + +static ssize_t show_bridge(struct device *cd, struct device_attribute *attr, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + return sprintf(buf, "%s\n", symbolic(brglist, ov->bridge)); +} +static DEVICE_ATTR(bridge, S_IRUGO, show_bridge, NULL); + +static ssize_t show_sensor(struct device *cd, struct device_attribute *attr, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + return sprintf(buf, "%s\n", symbolic(senlist, ov->sensor)); +} +static DEVICE_ATTR(sensor, S_IRUGO, show_sensor, NULL); + +static ssize_t show_brightness(struct device *cd, struct device_attribute *attr, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + unsigned short x; + + if (!ov->dev) + return -ENODEV; + sensor_get_brightness(ov, &x); + return sprintf(buf, "%d\n", x >> 8); +} +static DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL); + +static ssize_t show_saturation(struct device *cd, struct device_attribute *attr, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + unsigned short x; + + if (!ov->dev) + return -ENODEV; + sensor_get_saturation(ov, &x); + return sprintf(buf, "%d\n", x >> 8); +} +static DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL); + +static ssize_t show_contrast(struct device *cd, struct device_attribute *attr, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + unsigned short x; + + if (!ov->dev) + return -ENODEV; + sensor_get_contrast(ov, &x); + return sprintf(buf, "%d\n", x >> 8); +} +static DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL); + +static ssize_t show_hue(struct device *cd, struct device_attribute *attr, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + unsigned short x; + + if (!ov->dev) + return -ENODEV; + sensor_get_hue(ov, &x); + return sprintf(buf, "%d\n", x >> 8); +} +static DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL); + +static ssize_t show_exposure(struct device *cd, struct device_attribute *attr, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + unsigned char exp = 0; + + if (!ov->dev) + return -ENODEV; + sensor_get_exposure(ov, &exp); + return sprintf(buf, "%d\n", exp >> 8); +} +static DEVICE_ATTR(exposure, S_IRUGO, show_exposure, NULL); + +static void ov_create_sysfs(struct device *dev) +{ + device_create_file(dev, &dev_attr_custom_id); + device_create_file(dev, &dev_attr_model); + device_create_file(dev, &dev_attr_bridge); + device_create_file(dev, &dev_attr_sensor); + device_create_file(dev, &dev_attr_brightness); + device_create_file(dev, &dev_attr_saturation); + device_create_file(dev, &dev_attr_contrast); + device_create_file(dev, &dev_attr_hue); + device_create_file(dev, &dev_attr_exposure); +} + +/**************************************************************************** + * USB routines + ***************************************************************************/ + +static int +ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + struct usb_device *dev = interface_to_usbdev(intf); + struct usb_interface_descriptor *idesc; + struct usb_ov511 *ov; + int i; + + PDEBUG(1, "probing for device..."); + + /* We don't handle multi-config cameras */ + if (dev->descriptor.bNumConfigurations != 1) + return -ENODEV; + + idesc = &intf->cur_altsetting->desc; + + if (idesc->bInterfaceClass != 0xFF) + return -ENODEV; + if (idesc->bInterfaceSubClass != 0x00) + return -ENODEV; + + if ((ov = kmalloc(sizeof(*ov), GFP_KERNEL)) == NULL) { + err("couldn't kmalloc ov struct"); + goto error_out; + } + + memset(ov, 0, sizeof(*ov)); + + ov->dev = dev; + ov->iface = idesc->bInterfaceNumber; + ov->led_policy = led; + ov->compress = compress; + ov->lightfreq = lightfreq; + ov->num_inputs = 1; /* Video decoder init functs. change this */ + ov->stop_during_set = !fastset; + ov->backlight = backlight; + ov->mirror = mirror; + ov->auto_brt = autobright; + ov->auto_gain = autogain; + ov->auto_exp = autoexp; + + switch (le16_to_cpu(dev->descriptor.idProduct)) { + case PROD_OV511: + ov->bridge = BRG_OV511; + ov->bclass = BCL_OV511; + break; + case PROD_OV511PLUS: + ov->bridge = BRG_OV511PLUS; + ov->bclass = BCL_OV511; + break; + case PROD_OV518: + ov->bridge = BRG_OV518; + ov->bclass = BCL_OV518; + break; + case PROD_OV518PLUS: + ov->bridge = BRG_OV518PLUS; + ov->bclass = BCL_OV518; + break; + case PROD_ME2CAM: + if (le16_to_cpu(dev->descriptor.idVendor) != VEND_MATTEL) + goto error; + ov->bridge = BRG_OV511PLUS; + ov->bclass = BCL_OV511; + break; + default: + err("Unknown product ID 0x%04x", le16_to_cpu(dev->descriptor.idProduct)); + goto error; + } + + info("USB %s video device found", symbolic(brglist, ov->bridge)); + + init_waitqueue_head(&ov->wq); + + init_MUTEX(&ov->lock); /* to 1 == available */ + init_MUTEX(&ov->buf_lock); + init_MUTEX(&ov->param_lock); + init_MUTEX(&ov->i2c_lock); + init_MUTEX(&ov->cbuf_lock); + + ov->buf_state = BUF_NOT_ALLOCATED; + + if (usb_make_path(dev, ov->usb_path, OV511_USB_PATH_LEN) < 0) { + err("usb_make_path error"); + goto error; + } + + /* Allocate control transfer buffer. */ + /* Must be kmalloc()'ed, for DMA compatibility */ + ov->cbuf = kmalloc(OV511_CBUF_SIZE, GFP_KERNEL); + if (!ov->cbuf) + goto error; + + if (ov->bclass == BCL_OV518) { + if (ov518_configure(ov) < 0) + goto error; + } else { + if (ov511_configure(ov) < 0) + goto error; + } + + for (i = 0; i < OV511_NUMFRAMES; i++) { + ov->frame[i].framenum = i; + init_waitqueue_head(&ov->frame[i].wq); + } + + for (i = 0; i < OV511_NUMSBUF; i++) { + ov->sbuf[i].ov = ov; + spin_lock_init(&ov->sbuf[i].lock); + ov->sbuf[i].n = i; + } + + /* Unnecessary? (This is done on open(). Need to make sure variables + * are properly initialized without this before removing it, though). */ + if (ov51x_set_default_params(ov) < 0) + goto error; + +#ifdef OV511_DEBUG + if (dump_bridge) { + if (ov->bclass == BCL_OV511) + ov511_dump_regs(ov); + else + ov518_dump_regs(ov); + } +#endif + + ov->vdev = video_device_alloc(); + if (!ov->vdev) + goto error; + + memcpy(ov->vdev, &vdev_template, sizeof(*ov->vdev)); +// ov->vdev->dev = &dev->dev; + video_set_drvdata(ov->vdev, ov); + + for (i = 0; i < OV511_MAX_UNIT_VIDEO; i++) { + /* Minor 0 cannot be specified; assume user wants autodetect */ + if (unit_video[i] == 0) + break; + + if (video_register_device(ov->vdev, VFL_TYPE_GRABBER, + unit_video[i]) >= 0) { + break; + } + } + + /* Use the next available one */ + if ((ov->vdev->minor == -1) && + video_register_device(ov->vdev, VFL_TYPE_GRABBER, -1) < 0) { + err("video_register_device failed"); + goto error; + } + + info("Device at %s registered to minor %d", ov->usb_path, + ov->vdev->minor); + + usb_set_intfdata(intf, ov); + ov_create_sysfs(&ov->dev->dev); + return 0; + +error: + if (ov->vdev) { + if (-1 == ov->vdev->minor) + video_device_release(ov->vdev); + else + video_unregister_device(ov->vdev); + ov->vdev = NULL; + } + + if (ov->cbuf) { + down(&ov->cbuf_lock); + kfree(ov->cbuf); + ov->cbuf = NULL; + up(&ov->cbuf_lock); + } + + kfree(ov); + ov = NULL; + +error_out: + err("Camera initialization failed"); + return -EIO; +} + +static void +ov51x_disconnect(struct usb_interface *intf) +{ + struct usb_ov511 *ov = usb_get_intfdata(intf); + int n; + + PDEBUG(3, ""); + + usb_set_intfdata (intf, NULL); + + if (!ov) + return; + + if (ov->vdev) + video_unregister_device(ov->vdev); + + for (n = 0; n < OV511_NUMFRAMES; n++) + ov->frame[n].grabstate = FRAME_ERROR; + + ov->curframe = -1; + + /* This will cause the process to request another frame */ + for (n = 0; n < OV511_NUMFRAMES; n++) + wake_up_interruptible(&ov->frame[n].wq); + + wake_up_interruptible(&ov->wq); + + ov->streaming = 0; + ov51x_unlink_isoc(ov); + + ov->dev = NULL; + + /* Free the memory */ + if (ov && !ov->user) { + down(&ov->cbuf_lock); + kfree(ov->cbuf); + ov->cbuf = NULL; + up(&ov->cbuf_lock); + + ov51x_dealloc(ov); + kfree(ov); + ov = NULL; + } + + PDEBUG(3, "Disconnect complete"); +} + +static struct usb_driver ov511_driver = { + .name = "ov511", + .id_table = device_table, + .probe = ov51x_probe, + .disconnect = ov51x_disconnect +}; + +/**************************************************************************** + * + * Module routines + * + ***************************************************************************/ + +/* Returns 0 for success */ +int +ov511_register_decomp_module(int ver, struct ov51x_decomp_ops *ops, int ov518, + int mmx) +{ + if (ver != DECOMP_INTERFACE_VER) { + err("Decompression module has incompatible"); + err("interface version %d", ver); + err("Interface version %d is required", DECOMP_INTERFACE_VER); + return -EINVAL; + } + + if (!ops) + return -EFAULT; + + if (mmx && !ov51x_mmx_available) { + err("MMX not available on this system or kernel"); + return -EINVAL; + } + + lock_kernel(); + + if (ov518) { + if (mmx) { + if (ov518_mmx_decomp_ops) + goto err_in_use; + else + ov518_mmx_decomp_ops = ops; + } else { + if (ov518_decomp_ops) + goto err_in_use; + else + ov518_decomp_ops = ops; + } + } else { + if (mmx) { + if (ov511_mmx_decomp_ops) + goto err_in_use; + else + ov511_mmx_decomp_ops = ops; + } else { + if (ov511_decomp_ops) + goto err_in_use; + else + ov511_decomp_ops = ops; + } + } + + unlock_kernel(); + return 0; + +err_in_use: + unlock_kernel(); + return -EBUSY; +} + +void +ov511_deregister_decomp_module(int ov518, int mmx) +{ + lock_kernel(); + + if (ov518) { + if (mmx) + ov518_mmx_decomp_ops = NULL; + else + ov518_decomp_ops = NULL; + } else { + if (mmx) + ov511_mmx_decomp_ops = NULL; + else + ov511_decomp_ops = NULL; + } + + unlock_kernel(); +} + +static int __init +usb_ov511_init(void) +{ + int retval; + + retval = usb_register(&ov511_driver); + if (retval) + goto out; + + info(DRIVER_VERSION " : " DRIVER_DESC); + +out: + return retval; +} + +static void __exit +usb_ov511_exit(void) +{ + usb_deregister(&ov511_driver); + info("driver deregistered"); + +} + +module_init(usb_ov511_init); +module_exit(usb_ov511_exit); + +EXPORT_SYMBOL(ov511_register_decomp_module); +EXPORT_SYMBOL(ov511_deregister_decomp_module); --- linux-2.6.28.orig/ubuntu/misc/media/ov511/ov511_decomp.c +++ linux-2.6.28/ubuntu/misc/media/ov511/ov511_decomp.c @@ -0,0 +1,581 @@ +/* OV511 Decompression Support Module + * + * Copyright (c) 1999-2003 Mark W. McClelland. All rights reserved. + * http://alpha.dyndns.org/ov511/ + * + * Original decompression code Copyright 1998-2000 OmniVision Technologies + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; version 2 of the License. + */ + + +#if defined(OUTSIDE_KERNEL) + #if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS) + #define MODVERSIONS + #endif + + #include + + #ifdef MODVERSIONS + #include + #endif +#else + #include +#endif + +#include +#include + +#include "ov511.h" + +/****************************************************************************** + * Version Information + ******************************************************************************/ + +#define DRIVER_VERSION "v1.6" +#define DRIVER_AUTHOR "Mark McClelland , OmniVision \ +Technologies " +#define DRIVER_DESC "OV511 Decompression Module" + +/****************************************************************************** + * Prototypes + ******************************************************************************/ + +extern int ov511_register_decomp_module(int ver, struct ov51x_decomp_ops *ops, + int ov518, int mmx); +extern void ov511_deregister_decomp_module(int ov518, int mmx); + +/****************************************************************************** + * Decompression Module Interface Constants + ******************************************************************************/ + +static const int interface_ver = DECOMP_INTERFACE_VER; +static const int ov518 = 0; +static const int mmx = 0; + +/****************************************************************************** + * Module Features + ******************************************************************************/ + +static int debug; + +module_param(debug, uint, 0400); +MODULE_PARM_DESC(debug, + "Debug level: 0=none, 1=inits, 2=warning, 3=config, 4=functions, 5=max"); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +#if defined(MODULE_LICENSE) /* Introduced in ~2.4.10 */ +MODULE_LICENSE("GPL"); +#endif + +/****************************************************************************** + * Decompression Functions + ******************************************************************************/ + +static void +DecompressYHI(unsigned char *pIn, + unsigned char *pOut, + int *iIn, /* in/out */ + int *iOut, /* in/out */ + const int w, + const int YUVFlag) +{ + short ZigZag[64]; + int temp[64]; + int Zcnt_Flag = 0; + int Num8_Flag = 0; + int in_pos = *iIn; + int out_pos = *iOut; + int tmp, tmp1, tmp2, tmp3; + unsigned char header, ZTable[64]; + short tmpl, tmph, half_byte, idx, count; + unsigned long ZigZag_length = 0, ZT_length, i, j; + short DeZigZag[64]; + + const short a = 11584; + const short b = 16068; + const short c = 15136; + const short d = 13624; + const short e = 9104; + const short f = 6270; + const short g = 3196; + + int out_idx; + + /* Take off every 'Zig' */ + for (i = 0; i < 64; i++) { + ZigZag[i] = 0; + } + + /***************************** + * Read in the Y header byte * + *****************************/ + + header = pIn[in_pos]; + in_pos++; + + ZigZag_length = header & 0x3f; + ZigZag_length = ZigZag_length + 1; + + Num8_Flag = header & 0x40; + Zcnt_Flag = header & 0x80; + + /************************* + * Read in the Y content * + *************************/ + + if (Zcnt_Flag == 0) { /* Without Zero Table read contents directly */ + /* Read in ZigZag[0] */ + ZigZag[0] = pIn[in_pos++]; + tmpl = pIn[in_pos++]; + tmph = tmpl<<8; + ZigZag[0] = ZigZag[0] | tmph; + ZigZag[0] = ZigZag[0]<<4; + ZigZag[0] = ZigZag[0]>>4; + + if (Num8_Flag) { /* 8 Bits */ + for (i = 1; i < ZigZag_length; i++) { + ZigZag[i] = pIn[in_pos++]; + ZigZag[i] = ZigZag[i]<<8; + ZigZag[i] = ZigZag[i]>>8; + } + } else { /* 12 bits and has no Zero Table */ + idx = 1; + half_byte = 0; + for (i = 1; i < ZigZag_length; i++) { + if (half_byte == 0) { + ZigZag[i] = pIn[in_pos++]; + tmpl = pIn[in_pos++]; + tmph = tmpl<<8; + tmph = tmph&0x0f00; + ZigZag[i] = ZigZag[i] | tmph; + ZigZag[i] = ZigZag[i]<<4; + ZigZag[i] = ZigZag[i]>>4; + half_byte = 1; + } else { + ZigZag[i] = pIn[in_pos++]; + ZigZag[i] = ZigZag[i]<<8; + tmpl = tmpl & 0x00f0; + ZigZag[i] = ZigZag[i] | tmpl; + ZigZag[i] = ZigZag[i]>>4; + half_byte = 0; + } + } + } + } else { /* Has Zero Table */ + /* Calculate Z-Table length */ + ZT_length = ZigZag_length/8; + tmp = ZigZag_length%8; + + if (tmp > 0) { + ZT_length = ZT_length + 1; + } + + /* Read in Zero Table */ + for (j = 0; j < ZT_length; j++) { + ZTable[j] = pIn[in_pos++]; + } + + /* Read in ZigZag[0] */ + ZigZag[0] = pIn[in_pos++]; + tmpl = pIn[in_pos++]; + tmph = tmpl<<8; + ZigZag[0] = ZigZag[0] | tmph; + ZigZag[0] = ZigZag[0]<<4; + ZigZag[0] = ZigZag[0]>>4; + + /* Decode ZigZag */ + idx = 0; + ZTable[idx] = ZTable[idx]<<1; + count = 7; + + if (Num8_Flag) { /* 8 Bits and has zero table */ + for (i = 1; i < ZigZag_length; i++) { + if ((ZTable[idx]&0x80)) { + ZigZag[i] = pIn[in_pos++]; + ZigZag[i] = ZigZag[i]<<8; + ZigZag[i] = ZigZag[i]>>8; + } + + ZTable[idx]=ZTable[idx]<<1; + count--; + if (count == 0) { + count = 8; + idx++; + } + } + } else { /* 12 bits and has Zero Table */ + half_byte = 0; + for (i = 1; i < ZigZag_length; i++) { + if (ZTable[idx]&0x80) { + if (half_byte == 0) { + ZigZag[i] = pIn[in_pos++]; + tmpl = pIn[in_pos++]; + tmph = tmpl <<8; + tmph = tmph & 0x0f00; + ZigZag[i] = ZigZag[i] | tmph; + ZigZag[i] = ZigZag[i]<<4; + ZigZag[i] = ZigZag[i]>>4; + half_byte = 1; + } else { + ZigZag[i] = pIn[in_pos++]; + ZigZag[i] = ZigZag[i]<<8; + tmpl = tmpl & 0x00f0; + ZigZag[i] = ZigZag[i] | tmpl; + ZigZag[i] = ZigZag[i]>>4; + half_byte = 0; + } + } + + ZTable[idx] = ZTable[idx]<<1; + count--; + if (count == 0) { + count = 8; + idx++; + } + } + } + } + + /************* + * De-ZigZag * + *************/ + + for (j = 0; j < 64; j++) { + DeZigZag[j] = 0; + } + + if (YUVFlag == 1) { + DeZigZag[0] = ZigZag[0]; + DeZigZag[1] = ZigZag[1]<<1; + DeZigZag[2] = ZigZag[5]<<1; + DeZigZag[3] = ZigZag[6]<<2; + + DeZigZag[8] = ZigZag[2]<<1; + DeZigZag[9] = ZigZag[4]<<1; + DeZigZag[10] = ZigZag[7]<<1; + DeZigZag[11] = ZigZag[13]<<2; + + DeZigZag[16] = ZigZag[3]<<1; + DeZigZag[17] = ZigZag[8]<<1; + DeZigZag[18] = ZigZag[12]<<2; + DeZigZag[19] = ZigZag[17]<<2; + + DeZigZag[24] = ZigZag[9]<<2; + DeZigZag[25] = ZigZag[11]<<2; + DeZigZag[26] = ZigZag[18]<<2; + DeZigZag[27] = ZigZag[24]<<3; + } else { + DeZigZag[0] = ZigZag[0]; + DeZigZag[1] = ZigZag[1]<<2; + DeZigZag[2] = ZigZag[5]<<2; + DeZigZag[3] = ZigZag[6]<<3; + + DeZigZag[8] = ZigZag[2]<<2; + DeZigZag[9] = ZigZag[4]<<2; + DeZigZag[10] = ZigZag[7]<<2; + DeZigZag[11] = ZigZag[13]<<4; + + DeZigZag[16] = ZigZag[3]<<2; + DeZigZag[17] = ZigZag[8]<<2; + DeZigZag[18] = ZigZag[12]<<3; + DeZigZag[19] = ZigZag[17]<<4; + + DeZigZag[24] = ZigZag[9]<<3; + DeZigZag[25] = ZigZag[11]<<4; + DeZigZag[26] = ZigZag[18]<<4; + DeZigZag[27] = ZigZag[24]<<4; + } + + /***************** + **** IDCT 1D **** + *****************/ + +#define IDCT_1D(c0, c1, c2, c3, in) \ + do { \ + tmp1=((c0)*DeZigZag[in])+((c2)*DeZigZag[(in)+2]); \ + tmp2=(c1)*DeZigZag[(in)+1]; \ + tmp3=(c3)*DeZigZag[(in)+3]; \ + } while (0) + +#define COMPOSE_1(out1, out2) \ + do { \ + tmp=tmp1+tmp2+tmp3; \ + temp[out1] = tmp>>15; \ + tmp=tmp1-tmp2-tmp3; \ + temp[out2] = tmp>>15; \ + } while (0) + +#define COMPOSE_2(out1, out2) \ + do { \ + tmp=tmp1+tmp2-tmp3; \ + temp[out1] = tmp>>15; \ + tmp=tmp1-tmp2+tmp3; \ + temp[out2] = tmp>>15; \ + } while (0) + + /* j = 0 */ + IDCT_1D(a, b, c, d, 0); COMPOSE_1( 0, 56); + IDCT_1D(a, b, c, d, 8); COMPOSE_1( 1, 57); + IDCT_1D(a, b, c, d, 16); COMPOSE_1( 2, 58); + IDCT_1D(a, b, c, d, 24); COMPOSE_1( 3, 59); + + /* j = 1 */ + IDCT_1D(a, d, f, g, 0); COMPOSE_2( 8, 48); + IDCT_1D(a, d, f, g, 8); COMPOSE_2( 9, 49); + IDCT_1D(a, d, f, g, 16); COMPOSE_2(10, 50); + IDCT_1D(a, d, f, g, 24); COMPOSE_2(11, 51); + + /* j = 2 */ + IDCT_1D(a, e, -f, b, 0); COMPOSE_2(16, 40); + IDCT_1D(a, e, -f, b, 8); COMPOSE_2(17, 41); + IDCT_1D(a, e, -f, b, 16); COMPOSE_2(18, 42); + IDCT_1D(a, e, -f, b, 24); COMPOSE_2(19, 43); + + /* j = 3 */ + IDCT_1D(a, g, -c, e, 0); COMPOSE_2(24, 32); + IDCT_1D(a, g, -c, e, 8); COMPOSE_2(25, 33); + IDCT_1D(a, g, -c, e, 16); COMPOSE_2(26, 34); + IDCT_1D(a, g, -c, e, 24); COMPOSE_2(27, 35); + +#undef IDCT_1D +#undef COMPOSE_1 +#undef COMPOSE_2 + + /***************** + **** IDCT 2D **** + *****************/ + +#define IDCT_2D(c0, c1, c2, c3, in) \ + do { \ + tmp = temp[in]*(c0) + temp[(in)+1]*(c1) \ + + temp[(in)+2]*(c2) + temp[(in)+3]*(c3); \ + } while (0) + +#define STORE(i) \ + do { \ + tmp = tmp >> 15; \ + tmp = tmp + 128; \ + if (tmp > 255) tmp = 255; \ + if (tmp < 0) tmp = 0; \ + pOut[i] = (unsigned char) tmp; \ + } while (0) + +#define IDCT_2D_ROW(in) \ + do { \ + IDCT_2D(a, b, c, d, in); STORE(0+out_idx); \ + IDCT_2D(a, d, f, -g, in); STORE(1+out_idx); \ + IDCT_2D(a, e, -f, -b, in); STORE(2+out_idx); \ + IDCT_2D(a, g, -c, -e, in); STORE(3+out_idx); \ + IDCT_2D(a, -g, -c, e, in); STORE(4+out_idx); \ + IDCT_2D(a, -e, -f, b, in); STORE(5+out_idx); \ + IDCT_2D(a, -d, f, g, in); STORE(6+out_idx); \ + IDCT_2D(a, -b, c, -d, in); STORE(7+out_idx); \ + } while (0) + + +#define IDCT_2D_FAST(c0, c1, c2, c3, in) \ + do { \ + tmp1=((c0)*temp[in])+((c2)*temp[(in)+2]); \ + tmp2=(c1)*temp[(in)+1]; \ + tmp3=(c3)*temp[(in)+3]; \ + } while (0) + +#define STORE_FAST_1(out1, out2) \ + do { \ + tmp=tmp1+tmp2+tmp3; \ + STORE((out1)+out_idx); \ + tmp=tmp1-tmp2-tmp3; \ + STORE((out2)+out_idx); \ + } while (0) + +#define STORE_FAST_2(out1, out2) \ + do { \ + tmp=tmp1+tmp2-tmp3; \ + STORE((out1)+out_idx); \ + tmp=tmp1-tmp2+tmp3; \ + STORE((out2)+out_idx); \ + } while (0) + +#define IDCT_2D_FAST_ROW(in) \ + do { \ + IDCT_2D_FAST(a, b, c, d, in); STORE_FAST_1(0, 7); \ + IDCT_2D_FAST(a, d, f, g, in); STORE_FAST_2(1, 6); \ + IDCT_2D_FAST(a, e, -f, b, in); STORE_FAST_2(2, 5); \ + IDCT_2D_FAST(a, g, -c, e, in); STORE_FAST_2(3, 4); \ + } while (0) + + out_idx = out_pos; + + IDCT_2D_ROW(0); out_idx += w; + IDCT_2D_ROW(8); out_idx += w; + IDCT_2D_ROW(16); out_idx += w; + IDCT_2D_ROW(24); out_idx += w; + IDCT_2D_ROW(32); out_idx += w; + IDCT_2D_ROW(40); out_idx += w; + IDCT_2D_FAST_ROW(48); out_idx += w; + IDCT_2D_FAST_ROW(56); + + *iIn = in_pos; + *iOut = out_pos + 8; +} + +#define DECOMP_Y() DecompressYHI(pIn, pY, &iIn, &iY, w, 1) +#define DECOMP_U() DecompressYHI(pIn, pU, &iIn, &iU, w/2, 2) +#define DECOMP_V() DecompressYHI(pIn, pV, &iIn, &iV, w/2, 2) + +inline static int +Decompress400HiNoMMX(unsigned char *pIn, + unsigned char *pOut, + const int w, + const int h, + const int inSize) +{ + unsigned char *pY = pOut; + int x, y, iIn, iY; + + iIn = 0; + for (y = 0; y < h; y += 8) { + iY = w*y; + + for (x = 0; x < w; x += 8) + DECOMP_Y(); + } + + return 0; +} + +inline static int +Decompress420HiNoMMX(unsigned char *pIn, + unsigned char *pOut, + const int w, + const int h, + const int inSize) +{ + unsigned char *pY = pOut; + unsigned char *pU = pY + w*h; + unsigned char *pV = pU + w*h/4; + int xY, xUV, iY, iU, iV, iIn, count; + const int nBlocks = (w*h) / (32*8); + + iIn = 0; + iY = iU = iV = 0; + xY = xUV = 0; + + for (count = 0; count < nBlocks; count++) { + DECOMP_U(); + DECOMP_V(); xUV += 16; + if (xUV >= w) { + iU += (w*7)/2; + iV += (w*7)/2; + xUV = 0; + } + + DECOMP_Y(); xY += 8; + DECOMP_Y(); xY += 8; + if (xY >= w) { + iY += w*7; + xY = 0; + } + DECOMP_Y(); xY += 8; + DECOMP_Y(); xY += 8; + if (xY >= w) { + iY += w*7; + xY = 0; + } + } + + return 0; +} + +/* Input format is raw isoc. data (with header and packet + * number stripped, and all-zero blocks removed). + * Output format is YUV400 + * Returns uncompressed data length if success, or zero if error + */ +static int +Decompress400(unsigned char *pIn, + unsigned char *pOut, + unsigned char *pTmp, + int w, + int h, + int inSize) +{ + int numpix = w * h; + int rc; + + PDEBUG(4, "%dx%d pIn=%p pOut=%p inSize=%d", w, h, pIn, pOut, inSize); + + rc = Decompress400HiNoMMX(pIn, pOut, w, h, inSize); + + if (rc) + return 0; + + return numpix; +} + +/* Input format is raw isoc. data (with header and packet + * number stripped, and all-zero blocks removed). + * Output format is planar YUV420 + * Returns uncompressed data length if success, or zero if error + */ +static int +Decompress420(unsigned char *pIn, + unsigned char *pOut, + unsigned char *pTmp, + int w, + int h, + int inSize) +{ + int numpix = w * h; + int rc; + + PDEBUG(4, "%dx%d pIn=%p pOut=%p inSize=%d", w, h, pIn, pOut, inSize); + + rc = Decompress420HiNoMMX(pIn, pOut, w, h, inSize); + + if (rc) + return 0; + + return (numpix * 3 / 2); +} + +/****************************************************************************** + * Module Functions + ******************************************************************************/ + +static struct ov51x_decomp_ops decomp_ops = { + .decomp_400 = Decompress400, + .decomp_420 = Decompress420, + .owner = THIS_MODULE, +}; + +static int __init +decomp_init(void) +{ + int rc; + + rc = ov511_register_decomp_module(DECOMP_INTERFACE_VER, &decomp_ops, + ov518, mmx); + if (rc) { + err("Could not register with ov511 (rc=%d)", rc); + return -1; + } + + info(DRIVER_VERSION " : " DRIVER_DESC); + + return 0; +} + +static void __exit +decomp_exit(void) +{ + ov511_deregister_decomp_module(ov518, mmx); + info("deregistered\n"); +} + +module_init(decomp_init); +module_exit(decomp_exit); --- linux-2.6.28.orig/ubuntu/misc/media/ov511/Makefile +++ linux-2.6.28/ubuntu/misc/media/ov511/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_USB_OV511_NEW) += ov511.o ov511_decomp.o ov518_decomp.o --- linux-2.6.28.orig/ubuntu/misc/media/ov511/ov518_decomp.c +++ linux-2.6.28/ubuntu/misc/media/ov511/ov518_decomp.c @@ -0,0 +1,1566 @@ +/* OV518 Decompression Support Module (No-MMX version) + * + * Copyright (c) 2002-2003 Mark W. McClelland. All rights reserved. + * http://alpha.dyndns.org/ov511/ + * + * Fast integer iDCT by Yuri van Oers + * Original OV511 decompression code Copyright 1998-2000 OmniVision Technologies + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; version 2 of the License. + */ + + +#if defined(OUTSIDE_KERNEL) + #if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS) + #define MODVERSIONS + #endif + + #include + + #ifdef MODVERSIONS + #include + #endif +#else + #include +#endif + +#include +#include + +#include "ov511.h" + +/****************************************************************************** + * Compile-time Options + ******************************************************************************/ + +/* Defining APPROXIMATE_MUL_BY_SHIFT increases performance by approximation + * the multiplications by shifts. I think there's no change in the + * calculated picture, but I'm not sure, so the choice is still in here. */ +#undef APPROXIMATE_MUL_BY_SHIFT + +/* Allows printing the dynamic quantization tables (only if debug >= 5) */ +#define PRINT_QT + +/****************************************************************************** + * Version Information + ******************************************************************************/ + +#define DRIVER_VERSION "v1.3" +#define DRIVER_AUTHOR "Mark McClelland , \ +Yuri van Oers , OmniVision Technologies \ +" +#define DRIVER_DESC "OV518 Decompression Module" + +/****************************************************************************** + * Decompression Module Interface Constants + ******************************************************************************/ + +static const int interface_ver = DECOMP_INTERFACE_VER; +static const int ov518 = 1; +static const int mmx = 0; + +/****************************************************************************** + * Module Features + ******************************************************************************/ + +static int debug = 0; + +/* Static quantization. This uses a fixed quantization table versus the one + * that is normally embedded in the data. Define this if you see very bad + * contrast or "blockiness" in the decompressed output. */ +static int staticquant = 0; + +module_param(debug, uint, 0400); +MODULE_PARM_DESC(debug, + "Debug level: 0=none, 1=inits, 2=warning, 3=config, 4=functions, 5=max"); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +#if defined(MODULE_LICENSE) /* Introduced in ~2.4.10 */ +MODULE_LICENSE("GPL"); +#endif + +/****************************************************************************** + * Prototypes + ******************************************************************************/ + +extern int ov511_register_decomp_module(int ver, struct ov51x_decomp_ops *ops, + int ov518, int mmx); +extern void ov511_deregister_decomp_module(int ov518, int mmx); + +/****************************************************************************** + * Local Data Types + ******************************************************************************/ + +/* Make sure this remains naturally aligned and 2^n bytes in size */ +struct tree_node { + short left; /* Pointer to left child node */ + short right; /* Pointer to right child node */ + signed char depth; /* Depth (starting at 1) if leaf, else -1 */ + signed char coeffbits; /* Size of coefficient data, or zero if none */ + signed char skip; /* Number of zero coefficients. Unused w/ DC */ + char padding; /* Pad out to 8 bytes */ +}; + +struct comp_info { + int bytes; /* Number of processed input bytes */ + int bits; /* Number of unprocessed input bits */ + int rawLen; /* Total number of bytes in input buffer */ + unsigned char *qt; /* Current quantization table */ +}; + +/****************************************************************************** + * Constant Data Definitions + ******************************************************************************/ + +/* Zig-Zag Table */ +static const unsigned char ZigZag518[] = { + 0x00, 0x02, 0x03, 0x09, + 0x01, 0x04, 0x08, 0x0a, + 0x05, 0x07, 0x0b, 0x11, + 0x06, 0x0c, 0x10, 0x12, + 0x0d, 0x0f, 0x13, 0x19, + 0x0e, 0x14, 0x18, 0x1a, + 0x15, 0x17, 0x1b, 0x1e, + 0x16, 0x1c, 0x1d, 0x1f +}; + +/* Huffman trees */ + +static const struct tree_node treeYAC[] = { + { 1, 4, -1, 0, -1}, { 2, 3, -1, 0, -1}, + { -1, -1, 2, 1, 0}, { -1, -1, 2, 2, 0}, + { 5, 9, -1, 0, -1}, { 6, 7, -1, 0, -1}, + { -1, -1, 3, 3, 0}, {323, 8, -1, 0, -1}, + { -1, -1, 4, 4, 0}, { 10, 13, -1, 0, -1}, + { 38, 11, -1, 0, -1}, { 12, 39, -1, 0, -1}, + { -1, -1, 5, 5, 0}, { 59, 14, -1, 0, -1}, + { 15, 18, -1, 0, -1}, { 16, 113, -1, 0, -1}, + { 17, 40, -1, 0, -1}, { -1, -1, 7, 6, 0}, + { 19, 22, -1, 0, -1}, { 20, 41, -1, 0, -1}, + { 21, 61, -1, 0, -1}, { -1, -1, 8, 7, 0}, + { 23, 27, -1, 0, -1}, {169, 24, -1, 0, -1}, + {208, 25, -1, 0, -1}, { 26, 62, -1, 0, -1}, + { -1, -1, 10, 8, 0}, { 44, 28, -1, 0, -1}, + { 63, 29, -1, 0, -1}, { 30, 191, -1, 0, -1}, + { 31, 119, -1, 0, -1}, { 32, 82, -1, 0, -1}, + { 33, 55, -1, 0, -1}, { 34, 48, -1, 0, -1}, + {171, 35, -1, 0, -1}, { 36, 37, -1, 0, -1}, + { -1, -1, 16, 9, 0}, { -1, -1, 16, 10, 0}, + { -1, -1, 4, 1, 1}, { -1, -1, 5, 2, 1}, + { -1, -1, 7, 3, 1}, {151, 42, -1, 0, -1}, + { 43, 79, -1, 0, -1}, { -1, -1, 9, 4, 1}, + { 96, 45, -1, 0, -1}, {246, 46, -1, 0, -1}, + { 47, 115, -1, 0, -1}, { -1, -1, 11, 5, 1}, + { 49, 52, -1, 0, -1}, { 50, 51, -1, 0, -1}, + { -1, -1, 16, 6, 1}, { -1, -1, 16, 7, 1}, + { 53, 54, -1, 0, -1}, { -1, -1, 16, 8, 1}, + { -1, -1, 16, 9, 1}, { 56, 71, -1, 0, -1}, + { 57, 68, -1, 0, -1}, { 58, 67, -1, 0, -1}, + { -1, -1, 16, 10, 1}, { 60, 77, -1, 0, -1}, + { -1, -1, 5, 1, 2}, { -1, -1, 8, 2, 2}, + { -1, -1, 10, 3, 2}, {265, 64, -1, 0, -1}, + { 65, 134, -1, 0, -1}, { 66, 80, -1, 0, -1}, + { -1, -1, 12, 4, 2}, { -1, -1, 16, 5, 2}, + { 69, 70, -1, 0, -1}, { -1, -1, 16, 6, 2}, + { -1, -1, 16, 7, 2}, { 72, 75, -1, 0, -1}, + { 73, 74, -1, 0, -1}, { -1, -1, 16, 8, 2}, + { -1, -1, 16, 9, 2}, { 76, 81, -1, 0, -1}, + { -1, -1, 16, 10, 2}, { 78, 95, -1, 0, -1}, + { -1, -1, 6, 1, 3}, { -1, -1, 9, 2, 3}, + { -1, -1, 12, 3, 3}, { -1, -1, 16, 4, 3}, + { 83, 101, -1, 0, -1}, { 84, 91, -1, 0, -1}, + { 85, 88, -1, 0, -1}, { 86, 87, -1, 0, -1}, + { -1, -1, 16, 5, 3}, { -1, -1, 16, 6, 3}, + { 89, 90, -1, 0, -1}, { -1, -1, 16, 7, 3}, + { -1, -1, 16, 8, 3}, { 92, 98, -1, 0, -1}, + { 93, 94, -1, 0, -1}, { -1, -1, 16, 9, 3}, + { -1, -1, 16, 10, 3}, { -1, -1, 6, 1, 4}, + { 97, 225, -1, 0, -1}, { -1, -1, 10, 2, 4}, + { 99, 100, -1, 0, -1}, { -1, -1, 16, 3, 4}, + { -1, -1, 16, 4, 4}, {102, 109, -1, 0, -1}, + {103, 106, -1, 0, -1}, {104, 105, -1, 0, -1}, + { -1, -1, 16, 5, 4}, { -1, -1, 16, 6, 4}, + {107, 108, -1, 0, -1}, { -1, -1, 16, 7, 4}, + { -1, -1, 16, 8, 4}, {110, 116, -1, 0, -1}, + {111, 112, -1, 0, -1}, { -1, -1, 16, 9, 4}, + { -1, -1, 16, 10, 4}, {114, 133, -1, 0, -1}, + { -1, -1, 7, 1, 5}, { -1, -1, 11, 2, 5}, + {117, 118, -1, 0, -1}, { -1, -1, 16, 3, 5}, + { -1, -1, 16, 4, 5}, {120, 156, -1, 0, -1}, + {121, 139, -1, 0, -1}, {122, 129, -1, 0, -1}, + {123, 126, -1, 0, -1}, {124, 125, -1, 0, -1}, + { -1, -1, 16, 5, 5}, { -1, -1, 16, 6, 5}, + {127, 128, -1, 0, -1}, { -1, -1, 16, 7, 5}, + { -1, -1, 16, 8, 5}, {130, 136, -1, 0, -1}, + {131, 132, -1, 0, -1}, { -1, -1, 16, 9, 5}, + { -1, -1, 16, 10, 5}, { -1, -1, 7, 1, 6}, + {135, 152, -1, 0, -1}, { -1, -1, 12, 2, 6}, + {137, 138, -1, 0, -1}, { -1, -1, 16, 3, 6}, + { -1, -1, 16, 4, 6}, {140, 147, -1, 0, -1}, + {141, 144, -1, 0, -1}, {142, 143, -1, 0, -1}, + { -1, -1, 16, 5, 6}, { -1, -1, 16, 6, 6}, + {145, 146, -1, 0, -1}, { -1, -1, 16, 7, 6}, + { -1, -1, 16, 8, 6}, {148, 153, -1, 0, -1}, + {149, 150, -1, 0, -1}, { -1, -1, 16, 9, 6}, + { -1, -1, 16, 10, 6}, { -1, -1, 8, 1, 7}, + { -1, -1, 12, 2, 7}, {154, 155, -1, 0, -1}, + { -1, -1, 16, 3, 7}, { -1, -1, 16, 4, 7}, + {157, 175, -1, 0, -1}, {158, 165, -1, 0, -1}, + {159, 162, -1, 0, -1}, {160, 161, -1, 0, -1}, + { -1, -1, 16, 5, 7}, { -1, -1, 16, 6, 7}, + {163, 164, -1, 0, -1}, { -1, -1, 16, 7, 7}, + { -1, -1, 16, 8, 7}, {166, 172, -1, 0, -1}, + {167, 168, -1, 0, -1}, { -1, -1, 16, 9, 7}, + { -1, -1, 16, 10, 7}, {170, 187, -1, 0, -1}, + { -1, -1, 9, 1, 8}, { -1, -1, 15, 2, 8}, + {173, 174, -1, 0, -1}, { -1, -1, 16, 3, 8}, + { -1, -1, 16, 4, 8}, {176, 183, -1, 0, -1}, + {177, 180, -1, 0, -1}, {178, 179, -1, 0, -1}, + { -1, -1, 16, 5, 8}, { -1, -1, 16, 6, 8}, + {181, 182, -1, 0, -1}, { -1, -1, 16, 7, 8}, + { -1, -1, 16, 8, 8}, {184, 188, -1, 0, -1}, + {185, 186, -1, 0, -1}, { -1, -1, 16, 9, 8}, + { -1, -1, 16, 10, 8}, { -1, -1, 9, 1, 9}, + {189, 190, -1, 0, -1}, { -1, -1, 16, 2, 9}, + { -1, -1, 16, 3, 9}, {192, 258, -1, 0, -1}, + {193, 226, -1, 0, -1}, {194, 210, -1, 0, -1}, + {195, 202, -1, 0, -1}, {196, 199, -1, 0, -1}, + {197, 198, -1, 0, -1}, { -1, -1, 16, 4, 9}, + { -1, -1, 16, 5, 9}, {200, 201, -1, 0, -1}, + { -1, -1, 16, 6, 9}, { -1, -1, 16, 7, 9}, + {203, 206, -1, 0, -1}, {204, 205, -1, 0, -1}, + { -1, -1, 16, 8, 9}, { -1, -1, 16, 9, 9}, + {207, 209, -1, 0, -1}, { -1, -1, 16, 10, 9}, + { -1, -1, 9, 1, 10}, { -1, -1, 16, 2, 10}, + {211, 218, -1, 0, -1}, {212, 215, -1, 0, -1}, + {213, 214, -1, 0, -1}, { -1, -1, 16, 3, 10}, + { -1, -1, 16, 4, 10}, {216, 217, -1, 0, -1}, + { -1, -1, 16, 5, 10}, { -1, -1, 16, 6, 10}, + {219, 222, -1, 0, -1}, {220, 221, -1, 0, -1}, + { -1, -1, 16, 7, 10}, { -1, -1, 16, 8, 10}, + {223, 224, -1, 0, -1}, { -1, -1, 16, 9, 10}, + { -1, -1, 16, 10, 10}, { -1, -1, 10, 1, 11}, + {227, 242, -1, 0, -1}, {228, 235, -1, 0, -1}, + {229, 232, -1, 0, -1}, {230, 231, -1, 0, -1}, + { -1, -1, 16, 2, 11}, { -1, -1, 16, 3, 11}, + {233, 234, -1, 0, -1}, { -1, -1, 16, 4, 11}, + { -1, -1, 16, 5, 11}, {236, 239, -1, 0, -1}, + {237, 238, -1, 0, -1}, { -1, -1, 16, 6, 11}, + { -1, -1, 16, 7, 11}, {240, 241, -1, 0, -1}, + { -1, -1, 16, 8, 11}, { -1, -1, 16, 9, 11}, + {243, 251, -1, 0, -1}, {244, 248, -1, 0, -1}, + {245, 247, -1, 0, -1}, { -1, -1, 16, 10, 11}, + { -1, -1, 10, 1, 12}, { -1, -1, 16, 2, 12}, + {249, 250, -1, 0, -1}, { -1, -1, 16, 3, 12}, + { -1, -1, 16, 4, 12}, {252, 255, -1, 0, -1}, + {253, 254, -1, 0, -1}, { -1, -1, 16, 5, 12}, + { -1, -1, 16, 6, 12}, {256, 257, -1, 0, -1}, + { -1, -1, 16, 7, 12}, { -1, -1, 16, 8, 12}, + {259, 292, -1, 0, -1}, {260, 277, -1, 0, -1}, + {261, 270, -1, 0, -1}, {262, 267, -1, 0, -1}, + {263, 264, -1, 0, -1}, { -1, -1, 16, 9, 12}, + { -1, -1, 16, 10, 12}, {266, 322, -1, 0, -1}, + { -1, -1, 11, 1, 13}, {268, 269, -1, 0, -1}, + { -1, -1, 16, 2, 13}, { -1, -1, 16, 3, 13}, + {271, 274, -1, 0, -1}, {272, 273, -1, 0, -1}, + { -1, -1, 16, 4, 13}, { -1, -1, 16, 5, 13}, + {275, 276, -1, 0, -1}, { -1, -1, 16, 6, 13}, + { -1, -1, 16, 7, 13}, {278, 285, -1, 0, -1}, + {279, 282, -1, 0, -1}, {280, 281, -1, 0, -1}, + { -1, -1, 16, 8, 13}, { -1, -1, 16, 9, 13}, + {283, 284, -1, 0, -1}, { -1, -1, 16, 10, 13}, + { -1, -1, 16, 1, 14}, {286, 289, -1, 0, -1}, + {287, 288, -1, 0, -1}, { -1, -1, 16, 2, 14}, + { -1, -1, 16, 3, 14}, {290, 291, -1, 0, -1}, + { -1, -1, 16, 4, 14}, { -1, -1, 16, 5, 14}, + {293, 308, -1, 0, -1}, {294, 301, -1, 0, -1}, + {295, 298, -1, 0, -1}, {296, 297, -1, 0, -1}, + { -1, -1, 16, 6, 14}, { -1, -1, 16, 7, 14}, + {299, 300, -1, 0, -1}, { -1, -1, 16, 8, 14}, + { -1, -1, 16, 9, 14}, {302, 305, -1, 0, -1}, + {303, 304, -1, 0, -1}, { -1, -1, 16, 10, 14}, + { -1, -1, 16, 1, 15}, {306, 307, -1, 0, -1}, + { -1, -1, 16, 2, 15}, { -1, -1, 16, 3, 15}, + {309, 316, -1, 0, -1}, {310, 313, -1, 0, -1}, + {311, 312, -1, 0, -1}, { -1, -1, 16, 4, 15}, + { -1, -1, 16, 5, 15}, {314, 315, -1, 0, -1}, + { -1, -1, 16, 6, 15}, { -1, -1, 16, 7, 15}, + {317, 320, -1, 0, -1}, {318, 319, -1, 0, -1}, + { -1, -1, 16, 8, 15}, { -1, -1, 16, 9, 15}, + {321, -1, -1, 0, -1}, { -1, -1, 16, 10, 15}, + { -1, -1, 11, 0, 16}, { -1, -1, 4, 0, -1}, +}; + +static const struct tree_node treeUVAC[] = { + { 1, 3, -1, 0, -1}, {323, 2, -1, 0, -1}, + { -1, -1, 2, 1, 0}, { 4, 8, -1, 0, -1}, + { 5, 6, -1, 0, -1}, { -1, -1, 3, 2, 0}, + { 7, 37, -1, 0, -1}, { -1, -1, 4, 3, 0}, + { 9, 13, -1, 0, -1}, { 10, 60, -1, 0, -1}, + { 11, 12, -1, 0, -1}, { -1, -1, 5, 4, 0}, + { -1, -1, 5, 5, 0}, { 14, 17, -1, 0, -1}, + { 15, 97, -1, 0, -1}, { 16, 38, -1, 0, -1}, + { -1, -1, 6, 6, 0}, { 18, 21, -1, 0, -1}, + { 19, 39, -1, 0, -1}, { 20, 135, -1, 0, -1}, + { -1, -1, 7, 7, 0}, { 22, 26, -1, 0, -1}, + { 82, 23, -1, 0, -1}, { 24, 99, -1, 0, -1}, + { 25, 42, -1, 0, -1}, { -1, -1, 9, 8, 0}, + { 27, 31, -1, 0, -1}, {211, 28, -1, 0, -1}, + {248, 29, -1, 0, -1}, { 30, 63, -1, 0, -1}, + { -1, -1, 10, 9, 0}, { 43, 32, -1, 0, -1}, + { 33, 48, -1, 0, -1}, {153, 34, -1, 0, -1}, + { 35, 64, -1, 0, -1}, { 36, 47, -1, 0, -1}, + { -1, -1, 12, 10, 0}, { -1, -1, 4, 1, 1}, + { -1, -1, 6, 2, 1}, {152, 40, -1, 0, -1}, + { 41, 62, -1, 0, -1}, { -1, -1, 8, 3, 1}, + { -1, -1, 9, 4, 1}, { 84, 44, -1, 0, -1}, + {322, 45, -1, 0, -1}, { 46, 136, -1, 0, -1}, + { -1, -1, 11, 5, 1}, { -1, -1, 12, 6, 1}, + { 49, 189, -1, 0, -1}, { 50, 119, -1, 0, -1}, + { 51, 76, -1, 0, -1}, { 66, 52, -1, 0, -1}, + { 53, 69, -1, 0, -1}, { 54, 57, -1, 0, -1}, + { 55, 56, -1, 0, -1}, { -1, -1, 16, 7, 1}, + { -1, -1, 16, 8, 1}, { 58, 59, -1, 0, -1}, + { -1, -1, 16, 9, 1}, { -1, -1, 16, 10, 1}, + { 61, 81, -1, 0, -1}, { -1, -1, 5, 1, 2}, + { -1, -1, 8, 2, 2}, { -1, -1, 10, 3, 2}, + { 65, 86, -1, 0, -1}, { -1, -1, 12, 4, 2}, + {286, 67, -1, 0, -1}, { 68, 304, -1, 0, -1}, + { -1, -1, 15, 5, 2}, { 70, 73, -1, 0, -1}, + { 71, 72, -1, 0, -1}, { -1, -1, 16, 6, 2}, + { -1, -1, 16, 7, 2}, { 74, 75, -1, 0, -1}, + { -1, -1, 16, 8, 2}, { -1, -1, 16, 9, 2}, + { 77, 102, -1, 0, -1}, { 78, 91, -1, 0, -1}, + { 79, 88, -1, 0, -1}, { 80, 87, -1, 0, -1}, + { -1, -1, 16, 10, 2}, { -1, -1, 5, 1, 3}, + { 83, 171, -1, 0, -1}, { -1, -1, 8, 2, 3}, + { 85, 117, -1, 0, -1}, { -1, -1, 10, 3, 3}, + { -1, -1, 12, 4, 3}, { -1, -1, 16, 5, 3}, + { 89, 90, -1, 0, -1}, { -1, -1, 16, 6, 3}, + { -1, -1, 16, 7, 3}, { 92, 95, -1, 0, -1}, + { 93, 94, -1, 0, -1}, { -1, -1, 16, 8, 3}, + { -1, -1, 16, 9, 3}, { 96, 101, -1, 0, -1}, + { -1, -1, 16, 10, 3}, { 98, 116, -1, 0, -1}, + { -1, -1, 6, 1, 4}, {100, 188, -1, 0, -1}, + { -1, -1, 9, 2, 4}, { -1, -1, 16, 3, 4}, + {103, 110, -1, 0, -1}, {104, 107, -1, 0, -1}, + {105, 106, -1, 0, -1}, { -1, -1, 16, 4, 4}, + { -1, -1, 16, 5, 4}, {108, 109, -1, 0, -1}, + { -1, -1, 16, 6, 4}, { -1, -1, 16, 7, 4}, + {111, 114, -1, 0, -1}, {112, 113, -1, 0, -1}, + { -1, -1, 16, 8, 4}, { -1, -1, 16, 9, 4}, + {115, 118, -1, 0, -1}, { -1, -1, 16, 10, 4}, + { -1, -1, 6, 1, 5}, { -1, -1, 10, 2, 5}, + { -1, -1, 16, 3, 5}, {120, 156, -1, 0, -1}, + {121, 138, -1, 0, -1}, {122, 129, -1, 0, -1}, + {123, 126, -1, 0, -1}, {124, 125, -1, 0, -1}, + { -1, -1, 16, 4, 5}, { -1, -1, 16, 5, 5}, + {127, 128, -1, 0, -1}, { -1, -1, 16, 6, 5}, + { -1, -1, 16, 7, 5}, {130, 133, -1, 0, -1}, + {131, 132, -1, 0, -1}, { -1, -1, 16, 8, 5}, + { -1, -1, 16, 9, 5}, {134, 137, -1, 0, -1}, + { -1, -1, 16, 10, 5}, { -1, -1, 7, 1, 6}, + { -1, -1, 11, 2, 6}, { -1, -1, 16, 3, 6}, + {139, 146, -1, 0, -1}, {140, 143, -1, 0, -1}, + {141, 142, -1, 0, -1}, { -1, -1, 16, 4, 6}, + { -1, -1, 16, 5, 6}, {144, 145, -1, 0, -1}, + { -1, -1, 16, 6, 6}, { -1, -1, 16, 7, 6}, + {147, 150, -1, 0, -1}, {148, 149, -1, 0, -1}, + { -1, -1, 16, 8, 6}, { -1, -1, 16, 9, 6}, + {151, 155, -1, 0, -1}, { -1, -1, 16, 10, 6}, + { -1, -1, 7, 1, 7}, {154, 267, -1, 0, -1}, + { -1, -1, 11, 2, 7}, { -1, -1, 16, 3, 7}, + {157, 173, -1, 0, -1}, {158, 165, -1, 0, -1}, + {159, 162, -1, 0, -1}, {160, 161, -1, 0, -1}, + { -1, -1, 16, 4, 7}, { -1, -1, 16, 5, 7}, + {163, 164, -1, 0, -1}, { -1, -1, 16, 6, 7}, + { -1, -1, 16, 7, 7}, {166, 169, -1, 0, -1}, + {167, 168, -1, 0, -1}, { -1, -1, 16, 8, 7}, + { -1, -1, 16, 9, 7}, {170, 172, -1, 0, -1}, + { -1, -1, 16, 10, 7}, { -1, -1, 8, 1, 8}, + { -1, -1, 16, 2, 8}, {174, 181, -1, 0, -1}, + {175, 178, -1, 0, -1}, {176, 177, -1, 0, -1}, + { -1, -1, 16, 3, 8}, { -1, -1, 16, 4, 8}, + {179, 180, -1, 0, -1}, { -1, -1, 16, 5, 8}, + { -1, -1, 16, 6, 8}, {182, 185, -1, 0, -1}, + {183, 184, -1, 0, -1}, { -1, -1, 16, 7, 8}, + { -1, -1, 16, 8, 8}, {186, 187, -1, 0, -1}, + { -1, -1, 16, 9, 8}, { -1, -1, 16, 10, 8}, + { -1, -1, 9, 1, 9}, {190, 257, -1, 0, -1}, + {191, 224, -1, 0, -1}, {192, 207, -1, 0, -1}, + {193, 200, -1, 0, -1}, {194, 197, -1, 0, -1}, + {195, 196, -1, 0, -1}, { -1, -1, 16, 2, 9}, + { -1, -1, 16, 3, 9}, {198, 199, -1, 0, -1}, + { -1, -1, 16, 4, 9}, { -1, -1, 16, 5, 9}, + {201, 204, -1, 0, -1}, {202, 203, -1, 0, -1}, + { -1, -1, 16, 6, 9}, { -1, -1, 16, 7, 9}, + {205, 206, -1, 0, -1}, { -1, -1, 16, 8, 9}, + { -1, -1, 16, 9, 9}, {208, 217, -1, 0, -1}, + {209, 214, -1, 0, -1}, {210, 213, -1, 0, -1}, + { -1, -1, 16, 10, 9}, {212, 230, -1, 0, -1}, + { -1, -1, 9, 1, 10}, { -1, -1, 16, 2, 10}, + {215, 216, -1, 0, -1}, { -1, -1, 16, 3, 10}, + { -1, -1, 16, 4, 10}, {218, 221, -1, 0, -1}, + {219, 220, -1, 0, -1}, { -1, -1, 16, 5, 10}, + { -1, -1, 16, 6, 10}, {222, 223, -1, 0, -1}, + { -1, -1, 16, 7, 10}, { -1, -1, 16, 8, 10}, + {225, 241, -1, 0, -1}, {226, 234, -1, 0, -1}, + {227, 231, -1, 0, -1}, {228, 229, -1, 0, -1}, + { -1, -1, 16, 9, 10}, { -1, -1, 16, 10, 10}, + { -1, -1, 9, 1, 11}, {232, 233, -1, 0, -1}, + { -1, -1, 16, 2, 11}, { -1, -1, 16, 3, 11}, + {235, 238, -1, 0, -1}, {236, 237, -1, 0, -1}, + { -1, -1, 16, 4, 11}, { -1, -1, 16, 5, 11}, + {239, 240, -1, 0, -1}, { -1, -1, 16, 6, 11}, + { -1, -1, 16, 7, 11}, {242, 250, -1, 0, -1}, + {243, 246, -1, 0, -1}, {244, 245, -1, 0, -1}, + { -1, -1, 16, 8, 11}, { -1, -1, 16, 9, 11}, + {247, 249, -1, 0, -1}, { -1, -1, 16, 10, 11}, + { -1, -1, 9, 1, 12}, { -1, -1, 16, 2, 12}, + {251, 254, -1, 0, -1}, {252, 253, -1, 0, -1}, + { -1, -1, 16, 3, 12}, { -1, -1, 16, 4, 12}, + {255, 256, -1, 0, -1}, { -1, -1, 16, 5, 12}, + { -1, -1, 16, 6, 12}, {258, 291, -1, 0, -1}, + {259, 275, -1, 0, -1}, {260, 268, -1, 0, -1}, + {261, 264, -1, 0, -1}, {262, 263, -1, 0, -1}, + { -1, -1, 16, 7, 12}, { -1, -1, 16, 8, 12}, + {265, 266, -1, 0, -1}, { -1, -1, 16, 9, 12}, + { -1, -1, 16, 10, 12}, { -1, -1, 11, 1, 13}, + {269, 272, -1, 0, -1}, {270, 271, -1, 0, -1}, + { -1, -1, 16, 2, 13}, { -1, -1, 16, 3, 13}, + {273, 274, -1, 0, -1}, { -1, -1, 16, 4, 13}, + { -1, -1, 16, 5, 13}, {276, 283, -1, 0, -1}, + {277, 280, -1, 0, -1}, {278, 279, -1, 0, -1}, + { -1, -1, 16, 6, 13}, { -1, -1, 16, 7, 13}, + {281, 282, -1, 0, -1}, { -1, -1, 16, 8, 13}, + { -1, -1, 16, 9, 13}, {284, 288, -1, 0, -1}, + {285, 287, -1, 0, -1}, { -1, -1, 16, 10, 13}, + { -1, -1, 14, 1, 14}, { -1, -1, 16, 2, 14}, + {289, 290, -1, 0, -1}, { -1, -1, 16, 3, 14}, + { -1, -1, 16, 4, 14}, {292, 308, -1, 0, -1}, + {293, 300, -1, 0, -1}, {294, 297, -1, 0, -1}, + {295, 296, -1, 0, -1}, { -1, -1, 16, 5, 14}, + { -1, -1, 16, 6, 14}, {298, 299, -1, 0, -1}, + { -1, -1, 16, 7, 14}, { -1, -1, 16, 8, 14}, + {301, 305, -1, 0, -1}, {302, 303, -1, 0, -1}, + { -1, -1, 16, 9, 14}, { -1, -1, 16, 10, 14}, + { -1, -1, 15, 1, 15}, {306, 307, -1, 0, -1}, + { -1, -1, 16, 2, 15}, { -1, -1, 16, 3, 15}, + {309, 316, -1, 0, -1}, {310, 313, -1, 0, -1}, + {311, 312, -1, 0, -1}, { -1, -1, 16, 4, 15}, + { -1, -1, 16, 5, 15}, {314, 315, -1, 0, -1}, + { -1, -1, 16, 6, 15}, { -1, -1, 16, 7, 15}, + {317, 320, -1, 0, -1}, {318, 319, -1, 0, -1}, + { -1, -1, 16, 8, 15}, { -1, -1, 16, 9, 15}, + {321, -1, -1, 0, -1}, { -1, -1, 16, 10, 15}, + { -1, -1, 10, 0, 16}, { -1, -1, 2, 0, -1}, +}; + +static const struct tree_node treeYDC[] = { + { 1, 6, -1, 0}, { 2, 3, -1, 0}, + { -1, -1, 2, 0}, { 4, 5, -1, 0}, + { -1, -1, 3, 1}, { -1, -1, 3, 2}, + { 7, 10, -1, 0}, { 8, 9, -1, 0}, + { -1, -1, 3, 3}, { -1, -1, 3, 4}, + { 11, 12, -1, 0}, { -1, -1, 3, 5}, + { 13, 14, -1, 0}, { -1, -1, 4, 6}, + { 15, 16, -1, 0}, { -1, -1, 5, 7}, + { 17, 18, -1, 0}, { -1, -1, 6, 8}, + { 19, 20, -1, 0}, { -1, -1, 7, 9}, + { 21, 22, -1, 0}, { -1, -1, 8, 10}, + { 23, -1, -1, 0}, { -1, -1, 9, 11}, +}; + +static const struct tree_node treeUVDC[] = { + { 1, 4, -1, 0}, { 2, 3, -1, 0}, + { -1, -1, 2, 0}, { -1, -1, 2, 1}, + { 5, 6, -1, 0}, { -1, -1, 2, 2}, + { 7, 8, -1, 0}, { -1, -1, 3, 3}, + { 9, 10, -1, 0}, { -1, -1, 4, 4}, + { 11, 12, -1, 0}, { -1, -1, 5, 5}, + { 13, 14, -1, 0}, { -1, -1, 6, 6}, + { 15, 16, -1, 0}, { -1, -1, 7, 7}, + { 17, 18, -1, 0}, { -1, -1, 8, 8}, + { 19, 20, -1, 0}, { -1, -1, 9, 9}, + { 21, 22, -1, 0}, { -1, -1, 10, 10}, + { 23, -1, -1, 0}, { -1, -1, 11, 11}, +}; + +/****************************************************************************** + * Debugging + ******************************************************************************/ + +#ifdef PRINT_QT +#define PRN_QT_ROW(a, i) PDEBUG(5, "%02x %02x %02x %02x %02x %02x %02x %02x", \ + (a)[(i)], (a)[(i)+1], (a)[(i)+2], (a)[(i)+3], (a)[(i)+4], (a)[(i)+5], \ + (a)[(i)+6], (a)[(i)+7]) + +static inline void +print_qt(unsigned char *qt) +{ + PDEBUG(5, "Y Quantization table:"); + PRN_QT_ROW(qt, 0); + PRN_QT_ROW(qt, 8); + PRN_QT_ROW(qt, 16); + PRN_QT_ROW(qt, 24); + PDEBUG(5, "UV Quantization table:"); + PRN_QT_ROW(qt, 32); + PRN_QT_ROW(qt, 40); + PRN_QT_ROW(qt, 48); + PRN_QT_ROW(qt, 56); +} +#else +static inline void +print_qt(unsigned char *qt) { } +#endif /* PRINT_QT */ + +/****************************************************************************** + * Huffman Decoder + ******************************************************************************/ + +/* Note: There is no penalty for passing the tree as an argument, since dummy + * args are passed anyway (to maintain 16-byte stack alignment), and since the + * address is loaded into a register either way. */ + +/* If no node is found, coeffbits and skip will not be modified */ +/* Return: Depth of node found, or -1 if invalid input code */ +static int +getNodeAC(unsigned int in, signed char *coeffbits, signed char *skip, + const struct tree_node *tree) +{ + int node = 0; + int i = 0; + int depth; + + do { + if ((in & 0x80000000) == 0) + node = tree[node].left; + else + node = tree[node].right; + + if (node == -1) + break; + + depth = tree[node].depth; + + /* Is it a leaf? If not, branch downward */ + if (depth != -1) { + *coeffbits = tree[node].coeffbits; + *skip = tree[node].skip; + return depth; + } + + in <<= 1; + ++i; + } while (i <= 15); + + return -1; +} + +/* If no node is found, coeffbits will not be modified */ +/* Return: Depth of node found, or -1 if invalid input code */ +static int +getNodeDC(unsigned int in, signed char *coeffbits, const struct tree_node *tree) +{ + int node = 0; + int i = 0; + int depth; + + do { + if ((in & 0x80000000) == 0) + node = tree[node].left; + else + node = tree[node].right; + + if (node == -1) + break; + + depth = tree[node].depth; + + /* Is it a leaf? If not, branch downward */ + if (depth != -1) { + *coeffbits = tree[node].coeffbits; + return depth; + } + + in <<= 1; + ++i; + } while (i <= 15); + + return -1; +} + +static inline unsigned int +getBytes(int *rawData, struct comp_info *cinfo) +{ + int bufLen = cinfo->rawLen; + int bits = cinfo->bits; + int bytes = cinfo->bytes; + unsigned char *in = bytes + (unsigned char *) rawData; + unsigned char b1, b2, b3, b4, b5; + unsigned int packedIn; + + /* Pull 5 bytes out of raw data */ + if (bytes < bufLen - 4) { + b1 = in[0]; + b2 = in[1]; + b3 = in[2]; + b4 = in[3]; + b5 = in[4]; + } else { + if (bytes < bufLen - 3) { + b1 = in[0]; + b2 = in[1]; + b3 = in[2]; + b4 = in[3]; + } else { + if (bytes < bufLen - 2) { + b1 = in[0]; + b2 = in[1]; + b3 = in[2]; + } else { + if (bytes < bufLen - 1) { + b1 = in[0]; + b2 = in[1]; + } else { + if (bytes <= bufLen) { + b1 = in[0]; + } else { + b1 = 0; + } + b2 = 0; + } + b3 = 0; + } + b4 = 0; + } + b5 = 0; + } + + /* Pack the bytes */ + packedIn = b1 << 24; + packedIn += b2 << 16; + packedIn += b3 << 8; + packedIn += b4; + + if (bits != 0) { + packedIn = packedIn << bits; + packedIn += b5 >> (8 - bits); + } + + return packedIn; +} + +static int +getACCoefficient(int *rawData, int *coeff, struct comp_info *cinfo, + const struct tree_node *tree) +{ + int input, bits, bytes, tmp_c; + signed char coeffbits = 0; + signed char skip = 0; + + input = getBytes(rawData, cinfo); + bits = getNodeAC(input, &coeffbits, &skip, tree); + + if (coeffbits) { + input = input << (bits - 1); + input &= 0x7fffffff; + if (! (input & 0x40000000)) + input |= 0x80000000; + + tmp_c = input >> (31 - coeffbits); + if (tmp_c < 0) + tmp_c++; + *coeff = tmp_c; + + bits += coeffbits; + } + + bytes = (bits + cinfo->bits) >> 3; + cinfo->bytes += bytes; + cinfo->bits += bits - (bytes << 3); + + return skip; +} + +static void +getDCCoefficient(int *rawData, int *coeff, struct comp_info *cinfo, + const struct tree_node *tree) +{ + int input, bits, bytes, tmp_c; + signed char coeffbits = 0; + + input = getBytes(rawData, cinfo); + bits = getNodeDC(input, &coeffbits, tree); + + if (bits == -1) { + bits = 1; /* Try to re-sync at the next bit */ + *coeff = 0; /* Indicates no change from last DC */ + } else { + + input = input << (bits - 1); + input &= 0x7fffffff; + if (! (input & 0x40000000)) + input |= 0x80000000; + + tmp_c = input >> (31 - coeffbits); + if (tmp_c < 0) + tmp_c++; + *coeff = tmp_c; + + bits += coeffbits; + } + + bytes = (bits + cinfo->bits) >> 3; + cinfo->bytes += bytes; + cinfo->bits += bits - (bytes << 3); +} + +/* For AC coefficients, here is what the "skip" value means: + * -1: Either the 8x4 block has ended, or the decoding failed. + * 0: Use the returned coeff. Don't skip anything. + * 1-15: The next coeffs are zero. The returned coeff is used. + * 16: The next 16 coeffs are zero. The returned coeff is ignored. + * + * You must ensure that the C[] array not be overrun, or stack corruption will + * result. + */ +static void +huffmanDecoderY(int *C, int *pIn, struct comp_info *cinfo) +{ + int coeff = 0; + int i = 1; + int k, skip; + + getDCCoefficient(pIn, C, cinfo, treeYDC); + + i = 1; + do { + skip = getACCoefficient(pIn, &coeff, cinfo, treeYAC); + + if (skip == -1) { + break; + } else if (skip == 0) { + C[i++] = coeff; + } else if (skip == 16) { + k = 16; + if (i > 16) + k = 32 - i; + + while (k--) + C[i++] = 0; + } else { + k = skip; + if (skip > 31 - i) + k = 31 - i; + + while (k--) + C[i++] = 0; + + C[i++] = coeff; + } + } while (i <= 31); + + if (skip == -1) + while (i <= 31) C[i++] = 0; + else + getACCoefficient(pIn, &coeff, cinfo, treeYAC); +} + +/* Same as huffmanDecoderY, except for the tables used */ +static void +huffmanDecoderUV(int *C, int *pIn, struct comp_info *cinfo) +{ + int coeff = 0; + int i = 1; + int k, skip; + + getDCCoefficient(pIn, C, cinfo, treeUVDC); + + i = 1; + do { + skip = getACCoefficient(pIn, &coeff, cinfo, treeUVAC); + + if (skip == -1) { + break; + } else if (skip == 0) { + C[i++] = coeff; + } else if (skip == 16) { + k = 16; + if (i > 16) + k = 32 - i; + + while (k--) + C[i++] = 0; + } else { + k = skip; + if (skip > 31 - i) + k = 31 - i; + + while (k--) + C[i++] = 0; + + C[i++] = coeff; + } + } while (i <= 31); + + if (skip == -1) + while (i <= 31) C[i++] = 0; + else + getACCoefficient(pIn, &coeff, cinfo, treeUVAC); +} + +/****************************************************************************** + * iDCT Functions + ******************************************************************************/ + +#ifndef APPROXIMATE_MUL_BY_SHIFT + +#define IDCT_MESSAGE "iDCT with multiply" + +#define TIMES_16382(u) ((u)? 16382 * (u):0) +#define TIMES_23168(u) ((u)? 23168 * (u):0) +#define TIMES_30270(u) ((u)? 30270 * (u):0) +#define TIMES_41986(u) ((u)? 41986 * (u):0) +#define TIMES_35594(u) ((u)? 35594 * (u):0) +#define TIMES_23783(u) ((u)? 23783 * (u):0) +#define TIMES_8351(u) ((u)? 8351 * (u):0) +#define TIMES_17391(u) ((u)? 17391 * (u):0) +#define TIMES_14743(u) ((u)? 14743 * (u):0) +#define TIMES_9851(u) ((u)? 9851 * (u):0) +#define TIMES_3459(u) ((u)? 3459 * (u):0) +#define TIMES_32134(u) ((u)? 32134 * (u):0) +#define TIMES_27242(u) ((u)? 27242 * (u):0) +#define TIMES_18202(u) ((u)? 18202 * (u):0) +#define TIMES_6392(u) ((u)? 6392 * (u):0) +#define TIMES_39550(u) ((u)? 39550 * (u):0) +#define TIMES_6785(u) ((u)? 6785 * (u):0) +#define TIMES_12538(u) ((u)? 12538 * (u):0) + +#else + +#define IDCT_MESSAGE "iDCT with shift" + +#define TIMES_16382(u) ( (u)? x=(u) , (x<<14) - (x<<1) :0 ) +#define TIMES_23168(u) ( (u)? x=(u) , (x<<14) + (x<<12) + (x<<11) + (x<<9) :0 ) +#define TIMES_30270(u) ( (u)? x=(u) , (x<<15) - (x<<11) :0 ) +#define TIMES_41986(u) ( (u)? x=(u) , (x<<15) + (x<<13) + (x<<10) :0 ) +#define TIMES_35594(u) ( (u)? x=(u) , (x<<15) + (x<<11) + (x<<9) + (x<<8) :0 ) +#define TIMES_23783(u) ( (u)? x=(u) , (x<<14) + (x<<13) - (x<<9) - (x<<8) :0 ) +#define TIMES_8351(u) ( (u)? x=(u) , (x<<13) :0 ) +#define TIMES_17391(u) ( (u)? x=(u) , (x<<14) + (x<<10) :0 ) +#define TIMES_14743(u) ( (u)? x=(u) , (x<<14) - (x<<10) - (x<<9) :0 ) +#define TIMES_9851(u) ( (u)? x=(u) , (x<<13) + (x<<10) + (x<<9) :0 ) +#define TIMES_3459(u) ( (u)? x=(u) , (x<<12) - (x<<9) :0 ) +#define TIMES_32134(u) ( (u)? x=(u) , (x<<15) - (x<<9) :0 ) +#define TIMES_27242(u) ( (u)? x=(u) , (x<<14) + (x<<13) + (x<<11) + (x<<9) :0 ) +#define TIMES_18202(u) ( (u)? x=(u) , (x<<14) + (x<<11) - (x<<8) :0 ) +#define TIMES_6392(u) ( (u)? x=(u) , (x<<13) - (x<<11) + (x<<8) :0 ) +#define TIMES_39550(u) ( (u)? x=(u) , (x<<15) + (x<<12) + (x<<11) + (x<<9) :0 ) +#define TIMES_6785(u) ( (u)? x=(u) , (x<<12) + (x<<11) + (x<<9) :0 ) +#define TIMES_12538(u) ( (u)? x=(u) , (x<<13) + (x<<12) + (x<<8) :0 ) + +/* + * The variables C0, C4, C16 and C20 can also be removed from the algorithm + * if APPROXIMATE_MUL_BY_SHIFTS is defined. They store correction values + * and can be considered insignificant. + */ + +#endif + +static void +DCT_8x4(int *coeff, unsigned char *out) +/* pre: coeff == coefficients + post: coeff != coefficients + ** DO NOT ASSUME coeff TO BE THE SAME BEFORE AND AFTER CALLING THIS FUNCTION! +*/ +{ + register int base,val1,val2,val3; + int tmp1,tmp2; + int C0,C4,C16,C20; + int C2_18,C6_22,C1_17,C3_19,C5_21,C7_23; + register int t; +#ifdef APPROXIMATE_MUL_BY_SHIFT + register int x; +#endif + + C0=coeff[0]; + C4=coeff[4]; + C16=coeff[16]; + C20=coeff[20]; + + coeff[0]=TIMES_23168(coeff[0]); + coeff[4]=TIMES_23168(coeff[4]); + coeff[16]=TIMES_23168(coeff[16]); + coeff[20]=TIMES_23168(coeff[20]); + + C2_18 = coeff[2]+coeff[18]; + C6_22 = coeff[6]+coeff[22]; + C1_17 = coeff[1]+coeff[17]; + C3_19 = coeff[3]+coeff[19]; + C5_21 = coeff[5]+coeff[21]; + C7_23 = coeff[7]+coeff[23]; + +// 0,7,25,32 + + base = 0x1000000; + base += coeff[0]+coeff[4]+coeff[16]+coeff[20]; + base += TIMES_30270(C2_18); + base += TIMES_12538(C6_22); + + val1 = TIMES_41986(coeff[9]); + val1 += TIMES_35594(coeff[11]); + val1 += TIMES_23783(coeff[13]); + val1 += TIMES_8351(coeff[15]); + val1 += TIMES_17391(coeff[25]); + val1 += TIMES_14743(coeff[27]); + val1 += TIMES_9851(coeff[29]); + val1 += TIMES_3459(coeff[31]); + + val2 = TIMES_32134(C1_17); + val2 += TIMES_27242(C3_19); + val2 += TIMES_18202(C5_21); + val2 += TIMES_6392(C7_23); + + val3 = TIMES_39550(coeff[10]); + val3 += TIMES_16382(coeff[14]+coeff[26]); + val3 += TIMES_6785(coeff[30]); + val3 += TIMES_30270(coeff[8]+coeff[12]); + val3 += TIMES_12538(coeff[24]+coeff[28]); + + t=(base + val1 + val2 + val3) >> 17; + out[0]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 - val2 + val3 - C4 - C20) >> 17; + out[7]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 + val2 - val3 - C16- C20) >> 17; + out[24]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base + val1 - val2 - val3 - C4 - C16 - C20) >> 17; + out[31]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + +//1,6,25,30 + + base = 0x1000000; + base += coeff[0]-coeff[4]+coeff[16]-coeff[20]; + base += TIMES_12538(C2_18); + base -= TIMES_30270(C6_22); + + val1 = TIMES_35594(coeff[9]); + val1 -= TIMES_8351(coeff[11]); + val1 -= TIMES_41986(coeff[13]); + val1 -= TIMES_23783(coeff[15]); + val1 -= TIMES_14743(coeff[25]); + val1 -= TIMES_3459(coeff[27]); + val1 -= TIMES_17391(coeff[29]); + val1 -= TIMES_9851(coeff[31]); + + val2 = TIMES_27242(C1_17); + val2 -= TIMES_6392(C3_19); + val2 -= TIMES_32134(C5_21); + val2 -= TIMES_18202(C7_23); + + val3 = TIMES_16382(coeff[10]-coeff[30]); + val3 -= TIMES_39550(coeff[14]); + val3 += TIMES_6785(coeff[26]); + val3 += TIMES_12538(coeff[24]-coeff[28]); + val3 += TIMES_30270(coeff[8]-coeff[12]); + + t=(base + val1 + val2 + val3 + C4 + C20) >> 17; + out[1]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 - val2 + val3) >> 17; + out[6]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 + val2 - val3 + C4 - C16 + C20) >> 17; + out[25]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base + val1 - val2 - val3 + C20) >> 17; + out[30]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + +//2,5,26,29 + + base = 0x1000000; + base += coeff[0] - coeff[4] + coeff[16] - coeff[20]; + base -= TIMES_12538(C2_18); + base += TIMES_30270(C6_22); + + val1 = TIMES_23783(coeff[9]); + val1 -= TIMES_41986(coeff[11]); + val1 += TIMES_8351(coeff[13]); + val1 += TIMES_35594(coeff[15]); + val1 += TIMES_9851(coeff[25]); + val1 -= TIMES_17391(coeff[27]); + val1 += TIMES_3459(coeff[29]); + val1 += TIMES_14743(coeff[31]); + + val2 = TIMES_18202(C1_17); + val2 -= TIMES_32134(C3_19); + val2 += TIMES_6392(C5_21); + val2 += TIMES_27242(C7_23); + + val3 = -TIMES_16382(coeff[10] - coeff[30]); + val3 += TIMES_39550(coeff[14]); + val3 -= TIMES_6785(coeff[26]); + val3 += TIMES_12538(coeff[24] - coeff[28]); + val3 += TIMES_30270(coeff[8] - coeff[12]); + + t=(base + val1 + val2 + val3) >> 17; + out[2]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 - val2 + val3) >> 17; + out[5]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 + val2 - val3 - C16) >> 17; + out[26]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base + val1 - val2 - val3 + C4 - C16 + C20) >> 17; + out[29]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + +//3,4,27,28 + + base = 0x1000000; + base += coeff[0] + coeff[4] + coeff[16] + coeff[20]; + base -= TIMES_30270(C2_18); + base -= TIMES_12538(C6_22); + + val1 = TIMES_8351(coeff[9]); + val1 -= TIMES_23783(coeff[11]); + val1 += TIMES_35594(coeff[13]); + val1 += TIMES_3459(coeff[25]); + val1 -= TIMES_9851(coeff[27]); + val1 += TIMES_14743(coeff[29]); + + val2 = TIMES_6392(C1_17); + val2 -= TIMES_18202(C3_19); + val2 += TIMES_27242(C5_21); + + val3 = -TIMES_39550(coeff[10]); + val3 += TIMES_16382(coeff[14] + coeff[26]); + val3 -= TIMES_6785(coeff[30]); + val3 += TIMES_30270(coeff[8] + coeff[12]); + val3 += TIMES_12538(coeff[24] + coeff[28]); + + tmp1 = TIMES_32134(C7_23); + tmp2 = TIMES_41986(coeff[15]) + TIMES_17391(coeff[31]); + + t=(base + val1 + val2 + val3 - tmp1 - tmp2 - C4 - C20) >> 17; + out[3]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 - val2 + val3) >> 17; + out[4]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 + val2 - val3 - tmp1 + tmp2) >> 17; + out[27]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base + val1 - val2 - val3 - C16 - C20) >> 17; + out[28]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + +// Second half + C2_18 = coeff[2] - coeff[18]; + C6_22 = coeff[6] - coeff[22]; + C1_17 = coeff[1] - coeff[17]; + C3_19 = coeff[3] - coeff[19]; + C5_21 = coeff[5] - coeff[21]; + C7_23 = coeff[7] - coeff[23]; + +// 8,15,16,23 + + base = 0x1000000; + base += coeff[0] + coeff[4] - coeff[16] - coeff[20]; + base +=TIMES_30270(C2_18); + base +=TIMES_12538(C6_22); + + val1 = TIMES_17391(coeff[9]); + val1 += TIMES_14743(coeff[11]); + val1 += TIMES_9851(coeff[13]); + val1 += TIMES_3459(coeff[15]); + val1 -= TIMES_41986(coeff[25]); + val1 -= TIMES_35594(coeff[27]); + val1 -= TIMES_23783(coeff[29]); + val1 -= TIMES_8351(coeff[31]); + + val2 = TIMES_32134(C1_17); + val2 += TIMES_27242(C3_19); + val2 += TIMES_18202(C5_21); + val2 += TIMES_6392(C7_23); + + val3 = TIMES_16382(coeff[10] - coeff[30]); + val3 += TIMES_6785(coeff[14]); + val3 -= TIMES_39550(coeff[26]); + val3 -=TIMES_30270(coeff[24] + coeff[28]); + val3 +=TIMES_12538(coeff[8] + coeff[12]); + + t=(base + val1 + val2 + val3) >> 17; + out[8]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 - val2 + val3 - C4 + C16 + C20) >> 17; + out[15]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 + val2 - val3) >> 17; + out[16]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base + val1 - val2 - val3 - C4 + C20) >> 17; + out[23]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + +//9,14,17,22 + + base = 0x1000000; + base += coeff[0] - coeff[4] - coeff[16] + coeff[20]; + base += TIMES_12538(C2_18); + base -= TIMES_30270(C6_22); + + val1 = TIMES_14743(coeff[9]); + val1 -= TIMES_3459(coeff[11]); + val1 -= TIMES_17391(coeff[13]); + val1 -= TIMES_9851(coeff[15]); + val1 -= TIMES_35594(coeff[25]); + val1 += TIMES_8351(coeff[27]); + val1 += TIMES_41986(coeff[29]); + val1 += TIMES_23783(coeff[31]); + + val2 = TIMES_27242(C1_17); + val2 -= TIMES_6392(C3_19); + val2 -= TIMES_32134(C5_21); + val2 -= TIMES_18202(C7_23); + + val3 = TIMES_6785(coeff[10]); + val3 -= TIMES_16382(coeff[14] + coeff[26]); + val3 += TIMES_39550(coeff[30]); + val3 += TIMES_12538(coeff[8] - coeff[12]); + val3 -= TIMES_30270(coeff[24] - coeff[28]); + + t=(base + val1 + val2 + val3 + C4 + C16 - C20) >> 17; + out[9]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 - val2 + val3 + C16) >> 17; + out[14]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 + val2 - val3 + C4) >> 17; + out[17]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base + val1 - val2 - val3) >> 17; + out[22]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + +//10,13,18,21 + + base = 0x1000000; + base += coeff[0] - coeff[4] - coeff[16] + coeff[20]; + base -= TIMES_12538(C2_18); + base += TIMES_30270(C6_22); + + val1 = TIMES_9851(coeff[9]); + val1 -= TIMES_17391(coeff[11]); + val1 += TIMES_3459(coeff[13]); + val1 += TIMES_14743(coeff[15]); + val1 -= TIMES_23783(coeff[25]); + val1 += TIMES_41986(coeff[27]); + val1 -= TIMES_8351(coeff[29]); + val1 -= TIMES_35594(coeff[31]); + + val2 = TIMES_18202(C1_17); + val2 -= TIMES_32134(C3_19); + val2 += TIMES_6392(C5_21); + val2 += TIMES_27242(C7_23); + + val3 = -TIMES_6785(coeff[10]); + val3 += TIMES_16382(coeff[14]+coeff[26]); + val3 -= TIMES_39550(coeff[30]); + val3 += TIMES_12538(coeff[8]-coeff[12]); + val3 -= TIMES_30270(coeff[24]-coeff[28]); + + t=(base + val1 + val2 + val3) >> 17; + out[10]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 - val2 + val3 + C4 + C16 - C20) >> 17; + out[13]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 + val2 - val3) >> 17; + out[18]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base + val1 - val2 - val3 + C4) >> 17; + out[21]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + +// 11,12,19,20 + + base = 0x1000000; + base += coeff[0]+coeff[4]-coeff[16]-coeff[20]; + base -= TIMES_30270(C2_18); + base -= TIMES_12538(C6_22); + + val1 = TIMES_3459(coeff[9]); + val1 -= TIMES_9851(coeff[11]); + val1 += TIMES_14743(coeff[13]); + val1 -= TIMES_8351(coeff[25]); + val1 += TIMES_23783(coeff[27]); + val1 -= TIMES_35594(coeff[29]); + + val2 = TIMES_6392(C1_17); + val2 -= TIMES_18202(C3_19); + val2 += TIMES_27242(C5_21); + + val3 = -TIMES_16382(coeff[10] - coeff[30]); + val3 -= TIMES_6785(coeff[14]); + val3 += TIMES_39550(coeff[26]); + val3 -= TIMES_30270(coeff[24]+coeff[28]); + val3 += TIMES_12538(coeff[8]+coeff[12]); + + tmp1 = TIMES_32134(C7_23); + tmp2 = -TIMES_17391(coeff[15]) + TIMES_41986(coeff[31]); + + t=(base + val1 + val2 + val3 - tmp1 + tmp2 + C16 + C20) >> 17; + out[11]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 - val2 + val3 + C16 + C20) >> 17; + out[12]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 + val2 - val3 - tmp1 - tmp2 - C4 + C20) >> 17; + out[19]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base + val1 - val2 - val3) >> 17; + out[20]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; +} + +#undef TIMES_16382 +#undef TIMES_23168 +#undef TIMES_30270 +#undef TIMES_41986 +#undef TIMES_35594 +#undef TIMES_23783 +#undef TIMES_8351 +#undef TIMES_17391 +#undef TIMES_14743 +#undef TIMES_9851 +#undef TIMES_3459 +#undef TIMES_32134 +#undef TIMES_27242 +#undef TIMES_18202 +#undef TIMES_6392 +#undef TIMES_39550 +#undef TIMES_6785 +#undef TIMES_12538 + +/****************************************************************************** + * Main Decoder Functions + ******************************************************************************/ + +/* This function handles the decompression of a single 8x4 block. It is + * independent of the palette (YUV422, YUV420, YUV400, GBR422...). cinfo->bytes + * determines the positin in the input buffer. + */ +static int +decompress8x4(unsigned char *pOut, + unsigned char *pIn, + int *lastDC, + int uvFlag, + struct comp_info *cinfo) +{ + int i, x, y, dc; + int coeffs[32]; + int deZigZag[32]; + int *dest; + int *src; + unsigned char *qt = cinfo->qt; + + if (! uvFlag) { + huffmanDecoderY(coeffs, (int*) pIn, cinfo); + + /* iDPCM and dequantize first coefficient */ + dc = (*lastDC) + coeffs[0]; + coeffs[0] = dc * (qt[0] + 1); + *lastDC = dc; + + /* ...and the second coefficient */ + coeffs[1] = ((qt[1] + 1) * coeffs[1]) >> 1; + + /* Dequantize, starting at 3rd element */ + for (i = 2; i < 32; i++) + coeffs[i] = (qt[i] + 1) * coeffs[i]; + } else { + huffmanDecoderUV(coeffs, (int*) pIn, cinfo); + + /* iDPCM */ + dc = (*lastDC) + coeffs[0]; + coeffs[0] = dc; + *lastDC = dc; + + /* Dequantize */ + for (i = 0; i < 32; i++) + coeffs[i] = (qt[32 + i] + 1) * coeffs[i]; + } + + /* Dezigzag */ + for (i = 0; i < 32; i++) + deZigZag[i] = coeffs[ZigZag518[i]]; + + /* Transpose the dezigzagged coefficient matrix */ + src = deZigZag; + dest = coeffs; + for (y = 0; y <= 3; ++y) { + for (x = 0; x <= 7; ++x) { + dest[x] = src[x * 4]; + } + src += 1; + dest += 8; + } + + /* Do the inverse DCT transform */ + DCT_8x4(coeffs, pOut); + + return 0; /* Always returns 0 */ +} + +static inline void +copyBlock(unsigned char *src, unsigned char *dest, int destInc) +{ + int i; + unsigned int *pSrc, *pDest; + + for (i = 0; i <= 3; i++) { + pSrc = (unsigned int *) src; + pDest = (unsigned int *) dest; + pDest[0] = pSrc[0]; + pDest[1] = pSrc[1]; + src += 8; + dest += destInc; + } +} + +static inline int +decompress400NoMMXOV518(unsigned char *pIn, + unsigned char *pOut, + unsigned char *pTmp, + const int w, + const int h, + const int numpix, + struct comp_info *cinfo) +{ + int iOutY, x, y; + int lastYDC = 0; + + /* Start Y loop */ + y = 0; + do { + iOutY = w * y; + x = 0; + do { + decompress8x4(pTmp, pIn, &lastYDC, 0, cinfo); + copyBlock(pTmp, pOut + iOutY, w); + iOutY += 8; + x += 8; + } while (x < w); + y += 4; + } while (y < h); + + /* Did we decode too much? */ + if (cinfo->bytes > cinfo->rawLen + 897) + return 1; + + /* Did we decode enough? */ + if (cinfo->bytes >= cinfo->rawLen - 897) + return 0; + else + return 1; +} + +static inline int +decompress420NoMMXOV518(unsigned char *pIn, + unsigned char *pOut, + unsigned char *pTmp, + const int w, + const int h, + const int numpix, + struct comp_info *cinfo) +{ + unsigned char *pOutU = pOut + numpix; + unsigned char *pOutV = pOutU + numpix / 4; + int iOutY, iOutU, iOutV, x, y; + int lastYDC = 0; + int lastUDC = 0; + int lastVDC = 0; + + /* Start Y loop */ + y = 0; + do { + iOutY = w * y; + iOutV = iOutU = iOutY / 4; + + x = 0; + do { + decompress8x4(pTmp, pIn, &lastYDC, 0, cinfo); + copyBlock(pTmp, pOut + iOutY, w); + iOutY += 8; + x += 8; + } while (x < w); + + + + iOutY = w * (y + 4); + x = 0; + do { + decompress8x4(pTmp, pIn, &lastUDC, 1, cinfo); + copyBlock(pTmp, pOutU + iOutU, w/2); + iOutU += 8; + + decompress8x4(pTmp, pIn, &lastVDC, 1, cinfo); + copyBlock(pTmp, pOutV + iOutV, w/2); + iOutV += 8; + + decompress8x4(pTmp, pIn, &lastYDC, 0, cinfo); + copyBlock(pTmp, pOut + iOutY, w); + iOutY += 8; + + decompress8x4(pTmp, pIn, &lastYDC, 0, cinfo); + copyBlock(pTmp, pOut + iOutY, w); + iOutY += 8; + + x += 16; + } while (x < w); + + y += 8; + } while (y < h); + + /* Did we decode too much? */ + if (cinfo->bytes > cinfo->rawLen + 897) + return 1; + + /* Did we decode enough? */ + if (cinfo->bytes >= cinfo->rawLen - 897) + return 0; + else + return 1; +} + +/* Get quantization tables from static arrays + * Returns: <0 if error, or >=0 otherwise */ +static int +get_qt_static(struct comp_info *cinfo) +{ + unsigned char qtY[] = OV518_YQUANTABLE; + unsigned char qtUV[] = OV518_UVQUANTABLE; + unsigned char qt[64]; + + memcpy(qt, qtY, 32); + memcpy(qt + 32, qtUV, 32); + cinfo->qt = qt; + + return 0; +} + + +/* Get quantization tables from input + * Returns: <0 if error, or >=0 otherwise */ +static int +get_qt_dynamic(unsigned char *pIn, struct comp_info *cinfo) +{ + int rawLen = cinfo->rawLen; + + /* Make sure input is actually big enough to hold trailer */ + if (rawLen < 72) { + PDEBUG(1, "Not enough input to decompress"); + return -EINVAL; + } + + cinfo->qt = pIn + rawLen - 64; + + print_qt(cinfo->qt); + + return 0; +} + +/* Input format is raw isoc. data (with intact SOF header, packet numbers + * stripped, and all-zero blocks removed). + * Output format is planar YUV400 + * Returns uncompressed data length if success, or zero if error + */ +static int +Decompress400(unsigned char *pIn, + unsigned char *pOut, + unsigned char *pTmp, + int w, + int h, + int inSize) +{ + struct comp_info cinfo; + int numpix = w * h; + + PDEBUG(4, "%dx%d pIn=%p pOut=%p pTmp=%p inSize=%d", w, h, pIn, pOut, + pTmp, inSize); + + cinfo.bytes = 0; + cinfo.bits = 0; + cinfo.rawLen = inSize; + + if (staticquant) { + if (get_qt_static(&cinfo) < 0) + return 0; + } else { + if (get_qt_dynamic(pIn, &cinfo) < 0) + return 0; + } + + /* Decompress, skipping the 8-byte SOF header */ + if (decompress400NoMMXOV518(pIn + 8, pOut, pTmp, w, h, numpix, &cinfo)) +// return 0; + ; /* Don't return error yet */ + + return (numpix); +} + +/* Input format is raw isoc. data (with intact SOF header, packet numbers + * stripped, and all-zero blocks removed). + * Output format is planar YUV420 + * Returns uncompressed data length if success, or zero if error + */ +static int +Decompress420(unsigned char *pIn, + unsigned char *pOut, + unsigned char *pTmp, + int w, + int h, + int inSize) +{ + struct comp_info cinfo; + int numpix = w * h; + + PDEBUG(4, "%dx%d pIn=%p pOut=%p pTmp=%p inSize=%d", w, h, pIn, pOut, + pTmp, inSize); + + cinfo.bytes = 0; + cinfo.bits = 0; + cinfo.rawLen = inSize; + + if (staticquant) { + if (get_qt_static(&cinfo) < 0) + return 0; + } else { + if (get_qt_dynamic(pIn, &cinfo) < 0) + return 0; + } + + /* Decompress, skipping the 8-byte SOF header */ + if (decompress420NoMMXOV518(pIn + 8, pOut, pTmp, w, h, numpix, &cinfo)) +// return 0; + ; /* Don't return error yet */ + + return (numpix * 3 / 2); +} + +/****************************************************************************** + * Module Functions + ******************************************************************************/ + +static struct ov51x_decomp_ops decomp_ops = { + .decomp_400 = Decompress400, + .decomp_420 = Decompress420, + .owner = THIS_MODULE, +}; + +static int __init +decomp_init(void) +{ + int rc; + + rc = ov511_register_decomp_module(DECOMP_INTERFACE_VER, &decomp_ops, + ov518, mmx); + if (rc) { + err("Could not register with ov511 (rc=%d)", rc); + return -1; + } + + info(DRIVER_VERSION " : " DRIVER_DESC); + PDEBUG(1, "Using %s, %s quantization", IDCT_MESSAGE, + staticquant ? "static" : "dynamic"); + + return 0; +} + +static void __exit +decomp_exit(void) +{ + ov511_deregister_decomp_module(ov518, mmx); + info("deregistered"); +} + +module_init(decomp_init); +module_exit(decomp_exit); --- linux-2.6.28.orig/ubuntu/misc/media/ov511/ov511.h +++ linux-2.6.28/ubuntu/misc/media/ov511/ov511.h @@ -0,0 +1,570 @@ +#ifndef __LINUX_OV511_H +#define __LINUX_OV511_H + +#include +#include +#include +#include +#include + +#define OV511_DEBUG /* Turn on debug messages */ + +#ifdef OV511_DEBUG + #define PDEBUG(level, fmt, args...) \ + if (debug >= (level)) info("[%s:%d] " fmt, \ + __FUNCTION__, __LINE__ , ## args) +#else + #define PDEBUG(level, fmt, args...) do {} while(0) +#endif + +/* This macro restricts an int variable to an inclusive range */ +#define RESTRICT_TO_RANGE(v,mi,ma) { \ + if ((v) < (mi)) (v) = (mi); \ + else if ((v) > (ma)) (v) = (ma); \ +} + +/* --------------------------------- */ +/* DEFINES FOR OV511 AND OTHER CHIPS */ +/* --------------------------------- */ + +/* USB IDs */ +#define VEND_OMNIVISION 0x05A9 +#define PROD_OV511 0x0511 +#define PROD_OV511PLUS 0xA511 +#define PROD_OV518 0x0518 +#define PROD_OV518PLUS 0xA518 + +#define VEND_MATTEL 0x0813 +#define PROD_ME2CAM 0x0002 + +/* --------------------------------- */ +/* OV51x REGISTER MNEMONICS */ +/* --------------------------------- */ + +/* Camera interface register numbers */ +#define R511_CAM_DELAY 0x10 +#define R511_CAM_EDGE 0x11 +#define R511_CAM_PXCNT 0x12 +#define R511_CAM_LNCNT 0x13 +#define R511_CAM_PXDIV 0x14 +#define R511_CAM_LNDIV 0x15 +#define R511_CAM_UV_EN 0x16 +#define R511_CAM_LINE_MODE 0x17 +#define R511_CAM_OPTS 0x18 + +/* Snapshot mode camera interface register numbers */ +#define R511_SNAP_FRAME 0x19 +#define R511_SNAP_PXCNT 0x1A +#define R511_SNAP_LNCNT 0x1B +#define R511_SNAP_PXDIV 0x1C +#define R511_SNAP_LNDIV 0x1D +#define R511_SNAP_UV_EN 0x1E +#define R511_SNAP_OPTS 0x1F + +/* DRAM register numbers */ +#define R511_DRAM_FLOW_CTL 0x20 +#define R511_DRAM_ARCP 0x21 +#define R511_DRAM_MRC 0x22 +#define R511_DRAM_RFC 0x23 + +/* ISO FIFO register numbers */ +#define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */ +#define R511_FIFO_OPTS 0x31 + +/* Parallel IO register numbers */ +#define R511_PIO_OPTS 0x38 +#define R511_PIO_DATA 0x39 +#define R511_PIO_BIST 0x3E +#define R518_GPIO_IN 0x55 /* OV518(+) only */ +#define R518_GPIO_OUT 0x56 /* OV518(+) only */ +#define R518_GPIO_CTL 0x57 /* OV518(+) only */ +#define R518_GPIO_PULSE_IN 0x58 /* OV518(+) only */ +#define R518_GPIO_PULSE_CLEAR 0x59 /* OV518(+) only */ +#define R518_GPIO_PULSE_POL 0x5a /* OV518(+) only */ +#define R518_GPIO_PULSE_EN 0x5b /* OV518(+) only */ +#define R518_GPIO_RESET 0x5c /* OV518(+) only */ + +/* I2C registers */ +#define R511_I2C_CTL 0x40 +#define R518_I2C_CTL 0x47 /* OV518(+) only */ +#define R51x_I2C_W_SID 0x41 +#define R51x_I2C_SADDR_3 0x42 +#define R51x_I2C_SADDR_2 0x43 +#define R51x_I2C_R_SID 0x44 +#define R51x_I2C_DATA 0x45 +#define R51x_I2C_CLOCK 0x46 +#define R51x_I2C_TIMEOUT 0x47 + +/* I2C snapshot registers */ +#define R511_SI2C_SADDR_3 0x48 +#define R511_SI2C_DATA 0x49 + +/* System control registers */ +#define R51x_SYS_RESET 0x50 + /* Reset type definitions */ +#define OV511_RESET_UDC 0x01 +#define OV511_RESET_I2C 0x02 +#define OV511_RESET_FIFO 0x04 +#define OV511_RESET_OMNICE 0x08 +#define OV511_RESET_DRAM 0x10 +#define OV511_RESET_CAM_INT 0x20 +#define OV511_RESET_OV511 0x40 +#define OV511_RESET_NOREGS 0x3F /* All but OV511 & regs */ +#define OV511_RESET_ALL 0x7F + +#define R511_SYS_CLOCK_DIV 0x51 +#define R51x_SYS_SNAP 0x52 +#define R51x_SYS_INIT 0x53 +#define R511_SYS_PWR_CLK 0x54 /* OV511+/OV518(+) only */ +#define R511_SYS_LED_CTL 0x55 /* OV511+ only */ +#define R511_SYS_USER 0x5E +#define R511_SYS_CUST_ID 0x5F + +/* OmniCE (compression) registers */ +#define R511_COMP_PHY 0x70 +#define R511_COMP_PHUV 0x71 +#define R511_COMP_PVY 0x72 +#define R511_COMP_PVUV 0x73 +#define R511_COMP_QHY 0x74 +#define R511_COMP_QHUV 0x75 +#define R511_COMP_QVY 0x76 +#define R511_COMP_QVUV 0x77 +#define R511_COMP_EN 0x78 +#define R511_COMP_LUT_EN 0x79 +#define R511_COMP_LUT_BEGIN 0x80 + +/* --------------------------------- */ +/* ALTERNATE NUMBERS */ +/* --------------------------------- */ + +/* Alternate numbers for various max packet sizes (OV511 only) */ +#define OV511_ALT_SIZE_992 0 +#define OV511_ALT_SIZE_993 1 +#define OV511_ALT_SIZE_768 2 +#define OV511_ALT_SIZE_769 3 +#define OV511_ALT_SIZE_512 4 +#define OV511_ALT_SIZE_513 5 +#define OV511_ALT_SIZE_257 6 +#define OV511_ALT_SIZE_0 7 + +/* Alternate numbers for various max packet sizes (OV511+ only) */ +#define OV511PLUS_ALT_SIZE_0 0 +#define OV511PLUS_ALT_SIZE_33 1 +#define OV511PLUS_ALT_SIZE_129 2 +#define OV511PLUS_ALT_SIZE_257 3 +#define OV511PLUS_ALT_SIZE_385 4 +#define OV511PLUS_ALT_SIZE_513 5 +#define OV511PLUS_ALT_SIZE_769 6 +#define OV511PLUS_ALT_SIZE_961 7 + +/* Alternate numbers for various max packet sizes (OV518(+) only) */ +#define OV518_ALT_SIZE_0 0 +#define OV518_ALT_SIZE_128 1 +#define OV518_ALT_SIZE_256 2 +#define OV518_ALT_SIZE_384 3 +#define OV518_ALT_SIZE_512 4 +#define OV518_ALT_SIZE_640 5 +#define OV518_ALT_SIZE_768 6 +#define OV518_ALT_SIZE_896 7 + +/* --------------------------------- */ +/* OV7610 REGISTER MNEMONICS */ +/* --------------------------------- */ + +/* OV7610 registers */ +#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */ +#define OV7610_REG_BLUE 0x01 /* blue channel balance */ +#define OV7610_REG_RED 0x02 /* red channel balance */ +#define OV7610_REG_SAT 0x03 /* saturation */ + /* 04 reserved */ +#define OV7610_REG_CNT 0x05 /* Y contrast */ +#define OV7610_REG_BRT 0x06 /* Y brightness */ + /* 08-0b reserved */ +#define OV7610_REG_BLUE_BIAS 0x0C /* blue channel bias (5:0) */ +#define OV7610_REG_RED_BIAS 0x0D /* read channel bias (5:0) */ +#define OV7610_REG_GAMMA_COEFF 0x0E /* gamma settings */ +#define OV7610_REG_WB_RANGE 0x0F /* AEC/ALC/S-AWB settings */ +#define OV7610_REG_EXP 0x10 /* manual exposure setting */ +#define OV7610_REG_CLOCK 0x11 /* polarity/clock prescaler */ +#define OV7610_REG_COM_A 0x12 /* misc common regs */ +#define OV7610_REG_COM_B 0x13 /* misc common regs */ +#define OV7610_REG_COM_C 0x14 /* misc common regs */ +#define OV7610_REG_COM_D 0x15 /* misc common regs */ +#define OV7610_REG_FIELD_DIVIDE 0x16 /* field interval/mode settings */ +#define OV7610_REG_HWIN_START 0x17 /* horizontal window start */ +#define OV7610_REG_HWIN_END 0x18 /* horizontal window end */ +#define OV7610_REG_VWIN_START 0x19 /* vertical window start */ +#define OV7610_REG_VWIN_END 0x1A /* vertical window end */ +#define OV7610_REG_PIXEL_SHIFT 0x1B /* pixel shift */ +#define OV7610_REG_ID_HIGH 0x1C /* manufacturer ID MSB */ +#define OV7610_REG_ID_LOW 0x1D /* manufacturer ID LSB */ + /* 0e-0f reserved */ +#define OV7610_REG_COM_E 0x20 /* misc common regs */ +#define OV7610_REG_YOFFSET 0x21 /* Y channel offset */ +#define OV7610_REG_UOFFSET 0x22 /* U channel offset */ + /* 23 reserved */ +#define OV7610_REG_ECW 0x24 /* Exposure white level for AEC */ +#define OV7610_REG_ECB 0x25 /* Exposure black level for AEC */ +#define OV7610_REG_COM_F 0x26 /* misc settings */ +#define OV7610_REG_COM_G 0x27 /* misc settings */ +#define OV7610_REG_COM_H 0x28 /* misc settings */ +#define OV7610_REG_COM_I 0x29 /* misc settings */ +#define OV7610_REG_FRAMERATE_H 0x2A /* frame rate MSB + misc */ +#define OV7610_REG_FRAMERATE_L 0x2B /* frame rate LSB */ +#define OV7610_REG_ALC 0x2C /* Auto Level Control settings */ +#define OV7610_REG_COM_J 0x2D /* misc settings */ +#define OV7610_REG_VOFFSET 0x2E /* V channel offset adjustment */ +#define OV7610_REG_ARRAY_BIAS 0x2F /* Array bias -- don't change */ + /* 30-32 reserved */ +#define OV7610_REG_YGAMMA 0x33 /* misc gamma settings (7:6) */ +#define OV7610_REG_BIAS_ADJUST 0x34 /* misc bias settings */ +#define OV7610_REG_COM_L 0x35 /* misc settings */ + /* 36-37 reserved */ +#define OV7610_REG_COM_K 0x38 /* misc registers */ + +/* --------------------------------- */ +/* I2C ADDRESSES */ +/* --------------------------------- */ + +#define OV7xx0_SID 0x42 +#define OV6xx0_SID 0xC0 +#define OV8xx0_SID 0xA0 +#define KS0127_SID 0xD8 +#define SAA7111A_SID 0x48 + +/* --------------------------------- */ +/* MISCELLANEOUS DEFINES */ +/* --------------------------------- */ + +#define I2C_CLOCK_PRESCALER 0x03 + +#define FRAMES_PER_DESC 10 /* FIXME - What should this be? */ +#define MAX_FRAME_SIZE_PER_DESC 993 /* For statically allocated stuff */ +#define PIXELS_PER_SEG 256 /* Pixels per segment */ + +#define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */ + +#define OV511_NUMFRAMES 2 +#if OV511_NUMFRAMES > VIDEO_MAX_FRAME + #error "OV511_NUMFRAMES is too high" +#endif + +#define OV511_NUMSBUF 2 + +/* Control transfers use up to 4 bytes */ +#define OV511_CBUF_SIZE 4 + +/* Size of usb_make_path() buffer */ +#define OV511_USB_PATH_LEN 64 + +/* Bridge types */ +enum { + BRG_UNKNOWN, + BRG_OV511, + BRG_OV511PLUS, + BRG_OV518, + BRG_OV518PLUS, +}; + +/* Bridge classes */ +enum { + BCL_UNKNOWN, + BCL_OV511, + BCL_OV518, +}; + +/* Sensor types */ +enum { + SEN_UNKNOWN, + SEN_OV76BE, + SEN_OV7610, + SEN_OV7620, + SEN_OV7620AE, + SEN_OV6620, + SEN_OV6630, + SEN_OV6630AE, + SEN_OV6630AF, + SEN_OV8600, + SEN_KS0127, + SEN_KS0127B, + SEN_SAA7111A, +}; + +enum { + STATE_SCANNING, /* Scanning for start */ + STATE_HEADER, /* Parsing header */ + STATE_LINES, /* Parsing lines */ +}; + +/* Buffer states */ +enum { + BUF_NOT_ALLOCATED, + BUF_ALLOCATED, +}; + +/* --------- Definition of ioctl interface --------- */ + +#define OV511_INTERFACE_VER 101 + +/* LED options */ +enum { + LED_OFF, + LED_ON, + LED_AUTO, +}; + +/* Raw frame formats */ +enum { + RAWFMT_INVALID, + RAWFMT_YUV400, + RAWFMT_YUV420, + RAWFMT_YUV422, + RAWFMT_GBR422, +}; + +struct ov511_i2c_struct { + unsigned char slave; /* Write slave ID (read ID - 1) */ + unsigned char reg; /* Index of register */ + unsigned char value; /* User sets this w/ write, driver does w/ read */ + unsigned char mask; /* Bits to be changed. Not used with read ops */ +}; + +/* ioctls */ +#define OV511IOC_WI2C _IOW('v', BASE_VIDIOCPRIVATE + 5, \ + struct ov511_i2c_struct) +#define OV511IOC_RI2C _IOWR('v', BASE_VIDIOCPRIVATE + 6, \ + struct ov511_i2c_struct) +/* ------------- End IOCTL interface -------------- */ + +struct usb_ov511; /* Forward declaration */ + +struct ov511_sbuf { + struct usb_ov511 *ov; + unsigned char *data; + struct urb *urb; + spinlock_t lock; + int n; +}; + +enum { + FRAME_UNUSED, /* Unused (no MCAPTURE) */ + FRAME_READY, /* Ready to start grabbing */ + FRAME_GRABBING, /* In the process of being grabbed into */ + FRAME_DONE, /* Finished grabbing, but not been synced yet */ + FRAME_ERROR, /* Something bad happened while processing */ +}; + +struct ov511_regvals { + enum { + OV511_DONE_BUS, + OV511_REG_BUS, + OV511_I2C_BUS, + } bus; + unsigned char reg; + unsigned char val; +}; + +struct ov511_frame { + int framenum; /* Index of this frame */ + unsigned char *data; /* Frame buffer */ + unsigned char *tempdata; /* Temp buffer for multi-stage conversions */ + unsigned char *rawdata; /* Raw camera data buffer */ + unsigned char *compbuf; /* Temp buffer for decompressor */ + + int depth; /* Bytes per pixel */ + int width; /* Width application is expecting */ + int height; /* Height application is expecting */ + + int rawwidth; /* Actual width of frame sent from camera */ + int rawheight; /* Actual height of frame sent from camera */ + + int sub_flag; /* Sub-capture mode for this frame? */ + unsigned int format; /* Format for this frame */ + int compressed; /* Is frame compressed? */ + + volatile int grabstate; /* State of grabbing */ + int scanstate; /* State of scanning */ + + int bytes_recvd; /* Number of image bytes received from camera */ + + long bytes_read; /* Amount that has been read() */ + + wait_queue_head_t wq; /* Processes waiting */ + + int snapshot; /* True if frame was a snapshot */ +}; + +#define DECOMP_INTERFACE_VER 4 + +/* Compression module operations */ +struct ov51x_decomp_ops { + int (*decomp_400)(unsigned char *, unsigned char *, unsigned char *, + int, int, int); + int (*decomp_420)(unsigned char *, unsigned char *, unsigned char *, + int, int, int); + int (*decomp_422)(unsigned char *, unsigned char *, unsigned char *, + int, int, int); + struct module *owner; +}; + +struct usb_ov511 { + struct video_device *vdev; + struct usb_device *dev; + + int customid; + char *desc; + unsigned char iface; + char usb_path[OV511_USB_PATH_LEN]; + + /* Determined by sensor type */ + int maxwidth; + int maxheight; + int minwidth; + int minheight; + + int brightness; + int colour; + int contrast; + int hue; + int whiteness; + int exposure; + int auto_brt; /* Auto brightness enabled flag */ + int auto_gain; /* Auto gain control enabled flag */ + int auto_exp; /* Auto exposure enabled flag */ + int backlight; /* Backlight exposure algorithm flag */ + int mirror; /* Image is reversed horizontally */ + + int led_policy; /* LED: off|on|auto; OV511+ only */ + + struct semaphore lock; /* Serializes user-accessible operations */ + int user; /* user count for exclusive use */ + + int streaming; /* Are we streaming Isochronous? */ + int grabbing; /* Are we grabbing? */ + + int compress; /* Should the next frame be compressed? */ + int compress_inited; /* Are compression params uploaded? */ + + int lightfreq; /* Power (lighting) frequency */ + int bandfilt; /* Banding filter enabled flag */ + + unsigned char *fbuf; /* Videodev buffer area */ + unsigned char *tempfbuf; /* Temporary (intermediate) buffer area */ + unsigned char *rawfbuf; /* Raw camera data buffer area */ + + int sub_flag; /* Pix Array subcapture on flag */ + int subx; /* Pix Array subcapture x offset */ + int suby; /* Pix Array subcapture y offset */ + int subw; /* Pix Array subcapture width */ + int subh; /* Pix Array subcapture height */ + + int curframe; /* Current receiving sbuf */ + struct ov511_frame frame[OV511_NUMFRAMES]; + + struct ov511_sbuf sbuf[OV511_NUMSBUF]; + + wait_queue_head_t wq; /* Processes waiting */ + + int snap_enabled; /* Snapshot mode enabled */ + + int bridge; /* Type of bridge (BRG_*) */ + int bclass; /* Class of bridge (BCL_*) */ + int sensor; /* Type of image sensor chip (SEN_*) */ + + int packet_size; /* Frame size per isoc desc */ + int packet_numbering; /* Is ISO frame numbering enabled? */ + + struct semaphore param_lock; /* params lock for this camera */ + + /* Framebuffer/sbuf management */ + int buf_state; + struct semaphore buf_lock; + + struct ov51x_decomp_ops *decomp_ops; + + /* Stop streaming while changing picture settings */ + int stop_during_set; + + int stopped; /* Streaming is temporarily paused */ + + /* Video decoder stuff */ + int input; /* Composite, S-VIDEO, etc... */ + int num_inputs; /* Number of inputs */ + int norm; /* NTSC / PAL / SECAM */ + int has_decoder; /* Device has a video decoder */ + int pal; /* Device is designed for PAL resolution */ + + /* I2C interface */ + struct semaphore i2c_lock; /* Protect I2C controller regs */ + unsigned char primary_i2c_slave; /* I2C write id of sensor */ + + /* Control transaction stuff */ + unsigned char *cbuf; /* Buffer for payload */ + struct semaphore cbuf_lock; +}; + +/* Used to represent a list of values and their respective symbolic names */ +struct symbolic_list { + int num; + char *name; +}; + +#define NOT_DEFINED_STR "Unknown" + +/* Returns the name of the matching element in the symbolic_list array. The + * end of the list must be marked with an element that has a NULL name. + */ +static inline char * +symbolic(struct symbolic_list list[], int num) +{ + int i; + + for (i = 0; list[i].name != NULL; i++) + if (list[i].num == num) + return (list[i].name); + + return (NOT_DEFINED_STR); +} + +/* Compression stuff */ + +#define OV511_QUANTABLESIZE 64 +#define OV518_QUANTABLESIZE 32 + +#define OV511_YQUANTABLE { \ + 0, 1, 1, 2, 2, 3, 3, 4, \ + 1, 1, 1, 2, 2, 3, 4, 4, \ + 1, 1, 2, 2, 3, 4, 4, 4, \ + 2, 2, 2, 3, 4, 4, 4, 4, \ + 2, 2, 3, 4, 4, 5, 5, 5, \ + 3, 3, 4, 4, 5, 5, 5, 5, \ + 3, 4, 4, 4, 5, 5, 5, 5, \ + 4, 4, 4, 4, 5, 5, 5, 5 \ +} + +#define OV511_UVQUANTABLE { \ + 0, 2, 2, 3, 4, 4, 4, 4, \ + 2, 2, 2, 4, 4, 4, 4, 4, \ + 2, 2, 3, 4, 4, 4, 4, 4, \ + 3, 4, 4, 4, 4, 4, 4, 4, \ + 4, 4, 4, 4, 4, 4, 4, 4, \ + 4, 4, 4, 4, 4, 4, 4, 4, \ + 4, 4, 4, 4, 4, 4, 4, 4, \ + 4, 4, 4, 4, 4, 4, 4, 4 \ +} + +#define OV518_YQUANTABLE { \ + 5, 4, 5, 6, 6, 7, 7, 7, \ + 5, 5, 5, 5, 6, 7, 7, 7, \ + 6, 6, 6, 6, 7, 7, 7, 8, \ + 7, 7, 6, 7, 7, 7, 8, 8 \ +} + +#define OV518_UVQUANTABLE { \ + 6, 6, 6, 7, 7, 7, 7, 7, \ + 6, 6, 6, 7, 7, 7, 7, 7, \ + 6, 6, 6, 7, 7, 7, 7, 8, \ + 7, 7, 7, 7, 7, 7, 8, 8 \ +} + +#endif --- linux-2.6.28.orig/ubuntu/misc/wireless/Kconfig +++ linux-2.6.28/ubuntu/misc/wireless/Kconfig @@ -0,0 +1,19 @@ +menu "Wireless Drivers" + +config WIRELESS_ACX + tristate "TI ACX1xx based wireless cards (CardBus/PCI/USB)" + default m + depends on NET && IEEE80211 + +config P80211 + tristate + default n + depends on NET + +config PRISM2_USB + tristate "Prism2 based USB devices" + default m + depends on NET + select P80211 + +endmenu --- linux-2.6.28.orig/ubuntu/misc/wireless/Makefile +++ linux-2.6.28/ubuntu/misc/wireless/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for Ubuntu additional drivers +# + +obj-$(CONFIG_WIRELESS_ACX) += acx/ +obj-$(CONFIG_P80211) += p80211/ +obj-$(CONFIG_PRISM2_USB) += prism2_usb/ --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/p80211mod.c +++ linux-2.6.28/ubuntu/misc/wireless/p80211/p80211mod.c @@ -0,0 +1,219 @@ +/* src/p80211/p80211mod.c +* +* Module entry and exit for p80211 +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file contains the p80211.o entry and exit points defined for linux +* kernel modules. +* +* Notes: +* - all module parameters for p80211.o should be defined here. +* +* -------------------------------------------------------------------- +*/ + +/*================================================================*/ +/* System Includes */ + + +#include + +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,25)) +#include +#endif + +#include +#include +#include +#include +#include + +#include +#include + +/*================================================================*/ +/* Project Includes */ + +#include +#include +#include +#include +#include +#include +#include + +/*================================================================*/ +/* Local Constants */ + + +/*================================================================*/ +/* Local Macros */ + + +/*================================================================*/ +/* Local Types */ + + +/*================================================================*/ +/* Local Static Definitions */ + +static char *version = "p80211.o: " WLAN_RELEASE; + + +/*----------------------------------------------------------------*/ +/* --Module Parameters */ + +int wlan_watchdog = 5000; +module_param(wlan_watchdog, int, 0644); +MODULE_PARM_DESC(wlan_watchdog, "transmit timeout in milliseconds"); + +int wlan_wext_write = 1; +#if WIRELESS_EXT > 12 +module_param(wlan_wext_write, int, 0644); +MODULE_PARM_DESC(wlan_wext_write, "enable write wireless extensions"); +#endif + +#ifdef WLAN_INCLUDE_DEBUG +int wlan_debug=0; +module_param(wlan_debug, int, 0644); +MODULE_PARM_DESC(wlan_debug, "p80211 debug level"); +#endif + +MODULE_LICENSE("Dual MPL/GPL"); + +/*================================================================*/ +/* Local Function Declarations */ + +int init_module(void); +void cleanup_module(void); + +/*================================================================*/ +/* Function Definitions */ + +/*---------------------------------------------------------------- +* init_module +* +* Module initialization routine, called once at module load time. +* +* Arguments: +* none +* +* Returns: +* 0 - success +* ~0 - failure, module is unloaded. +* +* Side effects: +* TODO: define +* +* Call context: +* process thread (insmod or modprobe) +----------------------------------------------------------------*/ +int init_module(void) +{ + DBFENTER; + +#if 0 + printk(KERN_NOTICE "%s (%s) Loaded\n", version, WLAN_BUILD_DATE); +#endif + + p80211netdev_startup(); +#ifdef CONFIG_HOTPLUG + p80211_run_sbin_hotplug(NULL, WLAN_HOTPLUG_STARTUP); +#endif + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* cleanup_module +* +* Called at module unload time. This is our last chance to +* clean up after ourselves. +* +* Arguments: +* none +* +* Returns: +* nothing +* +* Side effects: +* TODO: define +* +* Call context: +* process thread +* +----------------------------------------------------------------*/ +void cleanup_module(void) +{ + DBFENTER; + +#ifdef CONFIG_HOTPLUG + p80211_run_sbin_hotplug(NULL, WLAN_HOTPLUG_SHUTDOWN); +#endif + p80211netdev_shutdown(); + printk(KERN_NOTICE "%s Unloaded\n", version); + + DBFEXIT; + return; +} + +EXPORT_SYMBOL(p80211netdev_hwremoved); +EXPORT_SYMBOL(register_wlandev); +EXPORT_SYMBOL(p80211netdev_rx); +EXPORT_SYMBOL(unregister_wlandev); +EXPORT_SYMBOL(wlan_setup); +EXPORT_SYMBOL(wlan_unsetup); +EXPORT_SYMBOL(p80211_suspend); +EXPORT_SYMBOL(p80211_resume); + +EXPORT_SYMBOL(p80211skb_free); +EXPORT_SYMBOL(p80211skb_rxmeta_attach); + +EXPORT_SYMBOL(p80211wext_event_associated); + +EXPORT_SYMBOL(wlan_wext_write); +EXPORT_SYMBOL(p80211_allow_ioctls); --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/p80211wext.c +++ linux-2.6.28/ubuntu/misc/wireless/p80211/p80211wext.c @@ -0,0 +1,2174 @@ +/* src/p80211/p80211wext.c +* +* Glue code to make linux-wlan-ng a happy wireless extension camper. +* +* original author: Reyk Floeter +* Completely re-written by Solomon Peachy +* +* Copyright (C) 2002 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +*/ + +/*================================================================*/ +/* System Includes */ + + +#include + +#include +#include +#include +#include +#include +#include +#include +#if WIRELESS_EXT > 12 +#include +#endif +#include +#include +#include +#include + +/*================================================================*/ +/* Project Includes */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int p80211wext_giwrate(netdevice_t *dev, + struct iw_request_info *info, + struct iw_param *rrq, char *extra); +static int p80211wext_giwessid(netdevice_t *dev, + struct iw_request_info *info, + struct iw_point *data, char *essid); +/* compatibility to wireless extensions */ +#ifdef WIRELESS_EXT + +static UINT8 p80211_mhz_to_channel(UINT16 mhz) +{ + if (mhz >= 5000) { + return ((mhz - 5000) / 5); + } + + if (mhz == 2482) + return 14; + + if (mhz >= 2407) { + return ((mhz - 2407) / 5); + } + + return 0; +} + +static UINT16 p80211_channel_to_mhz(UINT8 ch, int dot11a) +{ + + if (ch == 0) + return 0; + if (ch > 200) + return 0; + + /* 5G */ + + if (dot11a) { + return (5000 + (5 * ch)); + } + + /* 2.4G */ + + if (ch == 14) + return 2484; + + if ((ch < 14) && (ch > 0)) { + return (2407 + (5 * ch)); + } + + return 0; +} + +/* taken from orinoco.c ;-) */ +static const long p80211wext_channel_freq[] = { + 2412, 2417, 2422, 2427, 2432, 2437, 2442, + 2447, 2452, 2457, 2462, 2467, 2472, 2484 +}; +#define NUM_CHANNELS (sizeof(p80211wext_channel_freq) / sizeof(p80211wext_channel_freq[0])) + +/* steal a spare bit to store the shared/opensystems state. should default to open if not set */ +#define HOSTWEP_SHAREDKEY BIT3 + + +/** function declarations =============== */ + +static int qual_as_percent(int snr ) { + if ( snr <= 0 ) + return 0; + if ( snr <= 40 ) + return snr*5/2; + return 100; +} + +static inline int invalid_state(wlandevice_t *wlandev ) { + return wlandev->msdstate != WLAN_MSD_RUNNING; +} + +static int p80211wext_dorequest(wlandevice_t *wlandev, UINT32 did, UINT32 data) +{ + p80211msg_dot11req_mibset_t msg; + p80211item_uint32_t mibitem; + int result; + + DBFENTER; + + msg.msgcode = DIDmsg_dot11req_mibset; + mibitem.did = did; + mibitem.data = data; + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + DBFEXIT; + return result; +} + +static int p80211wext_autojoin(wlandevice_t *wlandev) +{ + p80211msg_lnxreq_autojoin_t msg; + struct iw_point data; + char ssid[IW_ESSID_MAX_SIZE]; + + int result; + int err = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + + /* Get ESSID */ + result = p80211wext_giwessid(wlandev->netdev, NULL, &data, ssid); + + if (result) { + err = -EFAULT; + goto exit; + } + + if ( wlandev->hostwep & HOSTWEP_SHAREDKEY ) + msg.authtype.data = P80211ENUM_authalg_sharedkey; + else + msg.authtype.data = P80211ENUM_authalg_opensystem; + + msg.msgcode = DIDmsg_lnxreq_autojoin; + + /* Trim the last '\0' to fit the SSID format */ + + if (data.length && ssid[data.length-1] == '\0') { + data.length = data.length - 1; + } + + memcpy(msg.ssid.data.data, ssid, data.length); + msg.ssid.data.len = data.length; + + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + +exit: + + DBFEXIT; + return err; + +} + +/* called by /proc/net/wireless */ +struct iw_statistics* p80211wext_get_wireless_stats (netdevice_t *dev) +{ + p80211msg_lnxreq_commsquality_t quality; + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + struct iw_statistics* wstats = &wlandev->wstats; + int retval; + + DBFENTER; + /* Check */ + if ( (wlandev == NULL) || (wlandev->msdstate != WLAN_MSD_RUNNING) ) + return NULL; + + /* XXX Only valid in station mode */ + wstats->status = 0; + + /* build request message */ + quality.msgcode = DIDmsg_lnxreq_commsquality; + quality.dbm.data = P80211ENUM_truth_true; + quality.dbm.status = P80211ENUM_msgitem_status_data_ok; + + /* send message to nsd */ + if ( wlandev->mlmerequest == NULL ) + return NULL; + + retval = wlandev->mlmerequest(wlandev, (p80211msg_t*) &quality); + + wstats->qual.qual = qual_as_percent(quality.link.data); /* overall link quality */ + wstats->qual.level = quality.level.data; /* instant signal level */ + wstats->qual.noise = quality.noise.data; /* instant noise level */ + +#if WIRELESS_EXT > 18 + wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; +#else + wstats->qual.updated = 7; +#endif + wstats->discard.code = wlandev->rx.decrypt_err; + wstats->discard.nwid = 0; + wstats->discard.misc = 0; + +#if WIRELESS_EXT > 11 + wstats->discard.fragment = 0; // incomplete fragments + wstats->discard.retries = 0; // tx retries. + wstats->miss.beacon = 0; +#endif + + DBFEXIT; + + return wstats; +} + +static int p80211wext_giwname(netdevice_t *dev, + struct iw_request_info *info, + char *name, char *extra) +{ + struct iw_param rate; + int result; + int err = 0; + + DBFENTER; + + result = p80211wext_giwrate(dev, NULL, &rate, NULL); + + if (result) { + err = -EFAULT; + goto exit; + } + + switch (rate.value) { + case 1000000: + case 2000000: + strcpy(name, "IEEE 802.11-DS"); + break; + case 5500000: + case 11000000: + strcpy(name, "IEEE 802.11-b"); + break; + } +exit: + DBFEXIT; + return err; +} + +static int p80211wext_giwfreq(netdevice_t *dev, + struct iw_request_info *info, + struct iw_freq *freq, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211item_uint32_t mibitem; + p80211msg_dot11req_mibset_t msg; + int result; + int err = 0; + + DBFENTER; + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + + + msg.msgcode = DIDmsg_dot11req_mibget; + mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel; + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + + memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem)); + + if (mibitem.data > NUM_CHANNELS) { + err = -EFAULT; + goto exit; + } + + /* convert into frequency instead of a channel */ + freq->e = 1; + freq->m = p80211_channel_to_mhz(mibitem.data, 0) * 100000; + + exit: + DBFEXIT; + return err; +} + +static int p80211wext_siwfreq(netdevice_t *dev, + struct iw_request_info *info, + struct iw_freq *freq, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211item_uint32_t mibitem; + p80211msg_dot11req_mibset_t msg; + int result; + int err = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + + if (!wlan_wext_write) { + err = (-EOPNOTSUPP); + goto exit; + } + + msg.msgcode = DIDmsg_dot11req_mibset; + mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel; + mibitem.status = P80211ENUM_msgitem_status_data_ok; + + if ( (freq->e == 0) && (freq->m <= 1000) ) + mibitem.data = freq->m; + else + mibitem.data = p80211_mhz_to_channel(freq->m); + + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + + exit: + DBFEXIT; + return err; +} + +#if WIRELESS_EXT > 8 + +static int p80211wext_giwmode(netdevice_t *dev, + struct iw_request_info *info, + __u32 *mode, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + + DBFENTER; + + switch (wlandev->macmode) { + case WLAN_MACMODE_IBSS_STA: + *mode = IW_MODE_ADHOC; + break; + case WLAN_MACMODE_ESS_STA: + *mode = IW_MODE_INFRA; + break; + case WLAN_MACMODE_ESS_AP: + *mode = IW_MODE_MASTER; + break; + default: + /* Not set yet. */ + *mode = IW_MODE_AUTO; + } + + DBFEXIT; + return 0; +} + +static int p80211wext_siwmode(netdevice_t *dev, + struct iw_request_info *info, + __u32 *mode, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211item_uint32_t mibitem; + p80211msg_dot11req_mibset_t msg; + int result; + int err = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + if (!wlan_wext_write) { + err = (-EOPNOTSUPP); + goto exit; + } + + if (*mode != IW_MODE_ADHOC && *mode != IW_MODE_INFRA && + *mode != IW_MODE_MASTER) { + err = (-EOPNOTSUPP); + goto exit; + } + + /* Operation mode is the same with current mode */ + if (*mode == wlandev->macmode) + goto exit; + + switch (*mode) { + case IW_MODE_ADHOC: + wlandev->macmode = WLAN_MACMODE_IBSS_STA; + break; + case IW_MODE_INFRA: + wlandev->macmode = WLAN_MACMODE_ESS_STA; + break; + case IW_MODE_MASTER: + wlandev->macmode = WLAN_MACMODE_ESS_AP; + break; + default: + /* Not set yet. */ + WLAN_LOG_INFO("Operation mode: %d not support\n", *mode); + return -EOPNOTSUPP; + } + + /* Set Operation mode to the PORT TYPE RID */ + +#warning "get rid of p2mib here" + + msg.msgcode = DIDmsg_dot11req_mibset; + mibitem.did = DIDmib_p2_p2Static_p2CnfPortType; + mibitem.data = (*mode == IW_MODE_ADHOC) ? 0 : 1; + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) + err = -EFAULT; + + exit: + DBFEXIT; + + return err; +} + + +static int p80211wext_giwrange(netdevice_t *dev, + struct iw_request_info *info, + struct iw_point *data, char *extra) +{ + struct iw_range *range = (struct iw_range *) extra; + int i, val; + + DBFENTER; + + // for backward compatability set size & zero everything we don't understand + data->length = sizeof(*range); + memset(range,0,sizeof(*range)); + +#if WIRELESS_EXT > 9 + range->txpower_capa = IW_TXPOW_DBM; + // XXX what about min/max_pmp, min/max_pmt, etc. +#endif + +#if WIRELESS_EXT > 10 + range->we_version_compiled = WIRELESS_EXT; + range->we_version_source = 13; + + range->retry_capa = IW_RETRY_LIMIT; + range->retry_flags = IW_RETRY_LIMIT; + range->min_retry = 0; + range->max_retry = 255; +#endif /* WIRELESS_EXT > 10 */ + +#if WIRELESS_EXT > 16 + range->event_capa[0] = (IW_EVENT_CAPA_K_0 | //mode/freq/ssid + IW_EVENT_CAPA_MASK(SIOCGIWAP) | + IW_EVENT_CAPA_MASK(SIOCGIWSCAN)); + range->event_capa[1] = IW_EVENT_CAPA_K_1; //encode + range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVQUAL) | + IW_EVENT_CAPA_MASK(IWEVCUSTOM) ); +#endif + + range->num_channels = NUM_CHANNELS; + + /* XXX need to filter against the regulatory domain &| active set */ + val = 0; + for (i = 0; i < NUM_CHANNELS ; i++) { + range->freq[val].i = i + 1; + range->freq[val].m = p80211wext_channel_freq[i] * 100000; + range->freq[val].e = 1; + val++; + } + + range->num_frequency = val; + + /* Max of /proc/net/wireless */ + range->max_qual.qual = 100; + range->max_qual.level = 0; + range->max_qual.noise = 0; + range->sensitivity = 3; + // XXX these need to be nsd-specific! + + range->min_rts = 0; + range->max_rts = 2347; + range->min_frag = 256; + range->max_frag = 2346; + + range->max_encoding_tokens = NUM_WEPKEYS; + range->num_encoding_sizes = 2; + range->encoding_size[0] = 5; + range->encoding_size[1] = 13; + + // XXX what about num_bitrates/throughput? + range->num_bitrates = 0; + + /* estimated max throughput */ + // XXX need to cap it if we're running at ~2Mbps.. + range->throughput = 5500000; + + DBFEXIT; + return 0; +} +#endif + +static int p80211wext_giwap(netdevice_t *dev, + struct iw_request_info *info, + struct sockaddr *ap_addr, char *extra) +{ + + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + + DBFENTER; + + memcpy(ap_addr->sa_data, wlandev->bssid, WLAN_BSSID_LEN); + ap_addr->sa_family = ARPHRD_ETHER; + + DBFEXIT; + return 0; +} + +#if WIRELESS_EXT > 8 +static int p80211wext_giwencode(netdevice_t *dev, + struct iw_request_info *info, + struct iw_point *erq, char *key) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + int err = 0; + int i; + + DBFENTER; + + i = (erq->flags & IW_ENCODE_INDEX) - 1; + erq->flags = 0; + + if (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) + erq->flags |= IW_ENCODE_ENABLED; + else + erq->flags |= IW_ENCODE_DISABLED; + + if (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED) + erq->flags |= IW_ENCODE_RESTRICTED; + else + erq->flags |= IW_ENCODE_OPEN; + + if (i == -1) + i = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK; + + if ((i < 0) || (i >= NUM_WEPKEYS)) { + err = -EINVAL; + goto exit; + } + + erq->flags |= i + 1; + + /* copy the key from the driver cache as the keys are read-only MIBs */ + erq->length = wlandev->wep_keylens[i]; + memcpy(key, wlandev->wep_keys[i], erq->length); + + exit: + DBFEXIT; + return err; +} + +static int p80211wext_siwencode(netdevice_t *dev, + struct iw_request_info *info, + struct iw_point *erq, char *key) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211msg_dot11req_mibset_t msg; + p80211item_pstr32_t pstr; + + int err = 0; + int result = 0; + int i; + + DBFENTER; + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + + if (!wlan_wext_write) { + err = (-EOPNOTSUPP); + goto exit; + } + + /* Check the Key index first. */ + if((i = (erq->flags & IW_ENCODE_INDEX))) { + + if ((i < 1) || (i > NUM_WEPKEYS)) { + err = -EINVAL; + goto exit; + } else { + i--; + } + + /* Set current key number only if no keys are given */ + if (erq->flags & IW_ENCODE_NOKEY) { + result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID, i); + + if (result) { + err = -EFAULT; + goto exit; + } + } + + } else { + // Use defaultkey if no Key Index + i = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK; + } + + /* Check if there is no key information in the iwconfig request */ + if((erq->flags & IW_ENCODE_NOKEY) == 0 ) { + + /*------------------------------------------------------------ + * If there is WEP Key for setting, check the Key Information + * and then set it to the firmware. + -------------------------------------------------------------*/ + + if (erq->length > 0) { + + /* copy the key from the driver cache as the keys are read-only MIBs */ + wlandev->wep_keylens[i] = erq->length; + memcpy(wlandev->wep_keys[i], key, erq->length); + + /* Prepare data struture for p80211req_dorequest. */ + memcpy(pstr.data.data, key, erq->length); + pstr.data.len = erq->length; + + switch(i) + { + case 0: + pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0; + break; + + case 1: + pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1; + break; + + case 2: + pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2; + break; + + case 3: + pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3; + break; + + default: + err = -EINVAL; + goto exit; + } + + msg.msgcode = DIDmsg_dot11req_mibset; + memcpy(&msg.mibattribute.data, &pstr, sizeof(pstr)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + } + + } + + /* Check the PrivacyInvoked flag */ + if (erq->flags & IW_ENCODE_DISABLED) { + result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_false); + } else { + result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_true); + } + + if (result) { + err = -EFAULT; + goto exit; + } + + /* The security mode may be open or restricted, and its meaning + depends on the card used. With most cards, in open mode no + authentication is used and the card may also accept non- + encrypted sessions, whereas in restricted mode only encrypted + sessions are accepted and the card will use authentication if + available. + */ + if (erq->flags & IW_ENCODE_RESTRICTED) { + result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_true); + // wlandev->hostwep |= HOSTWEP_SHAREDKEY; + } else if (erq->flags & IW_ENCODE_OPEN) { + result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_false); + // wlandev->hostwep &= ~HOSTWEP_SHAREDKEY; + } + + if (result) { + err = -EFAULT; + goto exit; + } + + exit: + + DBFEXIT; + return err; +} + +static int p80211wext_giwessid(netdevice_t *dev, + struct iw_request_info *info, + struct iw_point *data, char *essid) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + + DBFENTER; + + if (wlandev->ssid.len) { + data->length = wlandev->ssid.len; + data->flags = 1; + memcpy(essid, wlandev->ssid.data, data->length); + essid[data->length] = 0; +#if (WIRELESS_EXT < 21) + data->length++; +#endif + } else { + memset(essid, 0, sizeof(wlandev->ssid.data)); + data->length = 0; + data->flags = 0; + } + + DBFEXIT; + return 0; +} + +static int p80211wext_siwessid(netdevice_t *dev, + struct iw_request_info *info, + struct iw_point *data, char *essid) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211msg_lnxreq_autojoin_t msg; + + int result; + int err = 0; + int length = data->length; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + if (!wlan_wext_write) { + err = (-EOPNOTSUPP); + goto exit; + } + + + if ( wlandev->hostwep & HOSTWEP_SHAREDKEY ) + msg.authtype.data = P80211ENUM_authalg_sharedkey; + else + msg.authtype.data = P80211ENUM_authalg_opensystem; + + msg.msgcode = DIDmsg_lnxreq_autojoin; + +#if (WIRELESS_EXT < 21) + if (length) length--; +#endif + + /* Trim the last '\0' to fit the SSID format */ + + if (length && essid[length-1] == '\0') { + length--; + } + + memcpy(msg.ssid.data.data, essid, length); + msg.ssid.data.len = length; + + WLAN_LOG_DEBUG(1,"autojoin_ssid for %s \n",essid); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + WLAN_LOG_DEBUG(1,"autojoin_ssid %d\n",result); + + if (result) { + err = -EFAULT; + goto exit; + } + + exit: + DBFEXIT; + return err; +} + + +static int p80211wext_siwcommit(netdevice_t *dev, + struct iw_request_info *info, + struct iw_point *data, char *essid) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + int err = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + if (!wlan_wext_write) { + err = (-EOPNOTSUPP); + goto exit; + } + + /* Auto Join */ + err = p80211wext_autojoin(wlandev); + + exit: + DBFEXIT; + return err; +} + + +static int p80211wext_giwrate(netdevice_t *dev, + struct iw_request_info *info, + struct iw_param *rrq, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211item_uint32_t mibitem; + p80211msg_dot11req_mibset_t msg; + int result; + int err = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + msg.msgcode = DIDmsg_dot11req_mibget; + mibitem.did = DIDmib_p2_p2MAC_p2CurrentTxRate; + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + + memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem)); + + rrq->fixed = 0; /* can it change? */ + rrq->disabled = 0; + rrq->value = 0; + +#define HFA384x_RATEBIT_1 ((UINT16)1) +#define HFA384x_RATEBIT_2 ((UINT16)2) +#define HFA384x_RATEBIT_5dot5 ((UINT16)4) +#define HFA384x_RATEBIT_11 ((UINT16)8) + + switch (mibitem.data) { + case HFA384x_RATEBIT_1: + rrq->value = 1000000; + break; + case HFA384x_RATEBIT_2: + rrq->value = 2000000; + break; + case HFA384x_RATEBIT_5dot5: + rrq->value = 5500000; + break; + case HFA384x_RATEBIT_11: + rrq->value = 11000000; + break; + default: + err = -EINVAL; + } + exit: + DBFEXIT; + return err; +} + +static int p80211wext_giwrts(netdevice_t *dev, + struct iw_request_info *info, + struct iw_param *rts, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211item_uint32_t mibitem; + p80211msg_dot11req_mibset_t msg; + int result; + int err = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + msg.msgcode = DIDmsg_dot11req_mibget; + mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold; + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + + memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem)); + + rts->value = mibitem.data; + rts->disabled = (rts->value == 2347); + rts->fixed = 1; + + exit: + DBFEXIT; + return err; +} + + +static int p80211wext_siwrts(netdevice_t *dev, + struct iw_request_info *info, + struct iw_param *rts, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211item_uint32_t mibitem; + p80211msg_dot11req_mibset_t msg; + int result; + int err = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + if (!wlan_wext_write) { + err = (-EOPNOTSUPP); + goto exit; + } + + msg.msgcode = DIDmsg_dot11req_mibget; + mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold; + if (rts->disabled) + mibitem.data = 2347; + else + mibitem.data = rts->value; + + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + + exit: + DBFEXIT; + return err; +} + +static int p80211wext_giwfrag(netdevice_t *dev, + struct iw_request_info *info, + struct iw_param *frag, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211item_uint32_t mibitem; + p80211msg_dot11req_mibset_t msg; + int result; + int err = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + msg.msgcode = DIDmsg_dot11req_mibget; + mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold; + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + + memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem)); + + frag->value = mibitem.data; + frag->disabled = (frag->value == 2346); + frag->fixed = 1; + + exit: + DBFEXIT; + return err; +} + +static int p80211wext_siwfrag(netdevice_t *dev, + struct iw_request_info *info, + struct iw_param *frag, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211item_uint32_t mibitem; + p80211msg_dot11req_mibset_t msg; + int result; + int err = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + if (!wlan_wext_write) { + err = (-EOPNOTSUPP); + goto exit; + } + + msg.msgcode = DIDmsg_dot11req_mibset; + mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold; + + if (frag->disabled) + mibitem.data = 2346; + else + mibitem.data = frag->value; + + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + + exit: + DBFEXIT; + return err; +} + +#endif /* WIRELESS_EXT > 8 */ + +#if WIRELESS_EXT > 10 + +#ifndef IW_RETRY_LONG +#define IW_RETRY_LONG IW_RETRY_MAX +#endif + +#ifndef IW_RETRY_SHORT +#define IW_RETRY_SHORT IW_RETRY_MIN +#endif + +static int p80211wext_giwretry(netdevice_t *dev, + struct iw_request_info *info, + struct iw_param *rrq, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211item_uint32_t mibitem; + p80211msg_dot11req_mibset_t msg; + int result; + int err = 0; + UINT16 shortretry, longretry, lifetime; + + DBFENTER; + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + + msg.msgcode = DIDmsg_dot11req_mibget; + mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit; + + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + + memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem)); + + shortretry = mibitem.data; + + mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit; + + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + + memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem)); + + longretry = mibitem.data; + + mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime; + + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + + memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem)); + + lifetime = mibitem.data; + + rrq->disabled = 0; + + if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { + rrq->flags = IW_RETRY_LIFETIME; + rrq->value = lifetime * 1024; + } else { + if (rrq->flags & IW_RETRY_LONG) { + rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG; + rrq->value = longretry; + } else { + rrq->flags = IW_RETRY_LIMIT; + rrq->value = shortretry; + if (shortretry != longretry) + rrq->flags |= IW_RETRY_SHORT; + } + } + + exit: + DBFEXIT; + return err; + +} + +static int p80211wext_siwretry(netdevice_t *dev, + struct iw_request_info *info, + struct iw_param *rrq, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211item_uint32_t mibitem; + p80211msg_dot11req_mibset_t msg; + int result; + int err = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + if (!wlan_wext_write) { + err = (-EOPNOTSUPP); + goto exit; + } + + if (rrq->disabled) { + err = -EINVAL; + goto exit; + } + + msg.msgcode = DIDmsg_dot11req_mibset; + + if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { + mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime; + mibitem.data = rrq->value /= 1024; + + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + } else { + if (rrq->flags & IW_RETRY_LONG) { + mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit; + mibitem.data = rrq->value; + + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + } + + if (rrq->flags & IW_RETRY_SHORT) { + mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit; + mibitem.data = rrq->value; + + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + } + } + + exit: + DBFEXIT; + return err; + +} + +#endif /* WIRELESS_EXT > 10 */ + +#if WIRELESS_EXT > 9 +static int p80211wext_siwtxpow(netdevice_t *dev, + struct iw_request_info *info, + struct iw_param *rrq, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211item_uint32_t mibitem; + p80211msg_dot11req_mibset_t msg; + int result; + int err = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + if (!wlan_wext_write) { + err = (-EOPNOTSUPP); + goto exit; + } + + msg.msgcode = DIDmsg_dot11req_mibset; + + switch (rrq->value) { + + case 1 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel1; break; + case 2 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel2; break; + case 3 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel3; break; + case 4 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel4; break; + case 5 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel5; break; + case 6 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel6; break; + case 7 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel7; break; + case 8 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel8; break; + default: mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel8; break; + } + + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + + exit: + DBFEXIT; + return err; +} + +static int p80211wext_giwtxpow(netdevice_t *dev, + struct iw_request_info *info, + struct iw_param *rrq, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211item_uint32_t mibitem; + p80211msg_dot11req_mibset_t msg; + int result; + int err = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + msg.msgcode = DIDmsg_dot11req_mibget; + mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel; + + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + + memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem)); + + // XXX handle OFF by setting disabled = 1; + + rrq->flags = 0; // IW_TXPOW_DBM; + rrq->disabled = 0; + rrq->fixed = 0; + rrq->value = mibitem.data; + + exit: + DBFEXIT; + return err; +} +#endif /* WIRELESS_EXT > 9 */ + +static int p80211wext_siwspy(netdevice_t *dev, + struct iw_request_info *info, + struct iw_point *srq, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + struct sockaddr address[IW_MAX_SPY]; + int number = srq->length; + int i; + + DBFENTER; + + /* Copy the data from the input buffer */ + memcpy(address, extra, sizeof(struct sockaddr)*number); + + wlandev->spy_number = 0; + + if (number > 0) { + + /* extract the addresses */ + for (i = 0; i < number; i++) { + + memcpy(wlandev->spy_address[i], address[i].sa_data, ETH_ALEN); + } + + /* reset stats */ + memset(wlandev->spy_stat, 0, sizeof(struct iw_quality) * IW_MAX_SPY); + + /* set number of addresses */ + wlandev->spy_number = number; + } + + DBFEXIT; + return 0; +} + +/* jkriegl: from orinoco, modified */ +static int p80211wext_giwspy(netdevice_t *dev, + struct iw_request_info *info, + struct iw_point *srq, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + + struct sockaddr address[IW_MAX_SPY]; + struct iw_quality spy_stat[IW_MAX_SPY]; + int number; + int i; + + DBFENTER; + + number = wlandev->spy_number; + + if (number > 0) { + + /* populate address and spy struct's */ + for (i = 0; i < number; i++) { + memcpy(address[i].sa_data, wlandev->spy_address[i], ETH_ALEN); + address[i].sa_family = AF_UNIX; + memcpy(&spy_stat[i], &wlandev->spy_stat[i], sizeof(struct iw_quality)); + } + + /* reset update flag */ + for (i=0; i < number; i++) + wlandev->spy_stat[i].updated = 0; + } + + /* push stuff to user space */ + srq->length = number; + memcpy(extra, address, sizeof(struct sockaddr)*number); + memcpy(extra+sizeof(struct sockaddr)*number, spy_stat, sizeof(struct iw_quality)*number); + + DBFEXIT; + return 0; +} + +static int prism2_result2err (int prism2_result) +{ + int err = 0; + + switch (prism2_result) { + case P80211ENUM_resultcode_invalid_parameters: + err = -EINVAL; + break; + case P80211ENUM_resultcode_implementation_failure: + err = -EIO; + break; + case P80211ENUM_resultcode_not_supported: + err = -EOPNOTSUPP; + break; + default: + err = 0; + break; + } + + return err; +} + +#if WIRELESS_EXT > 13 +static int p80211wext_siwscan(netdevice_t *dev, + struct iw_request_info *info, + struct iw_point *srq, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211msg_dot11req_scan_t msg; + int result; + int err = 0; + int i = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + if (wlandev->macmode == WLAN_MACMODE_ESS_AP) { + WLAN_LOG_ERROR("Can't scan in AP mode\n"); + err = (-EOPNOTSUPP); + goto exit; + } + + memset(&msg, 0x00, sizeof(p80211msg_dot11req_scan_t)); + msg.msgcode = DIDmsg_dot11req_scan; + msg.bsstype.data = P80211ENUM_bsstype_any; + + memset(&(msg.bssid.data), 0xFF, sizeof (p80211item_pstr6_t)); + msg.bssid.data.len = 6; + + msg.scantype.data = P80211ENUM_scantype_active; + msg.probedelay.data = 0; + + for (i = 1; i <= 14; i++) + msg.channellist.data.data[i-1] = i; + msg.channellist.data.len = 14; + + msg.maxchanneltime.data = 250; + msg.minchanneltime.data = 200; + + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + if (result) + err = prism2_result2err (msg.resultcode.data); + + exit: + DBFEXIT; + return err; +} + + +/* Helper to translate scan into Wireless Extensions scan results. + * Inspired by the prism54 code, which was in turn inspired by the + * airo driver code. + */ +static char * +wext_translate_bss(char *current_ev, char *end_buf, p80211msg_dot11req_scan_results_t *bss, + struct iw_request_info *info) +{ + struct iw_event iwe; /* Temporary buffer */ + + /* The first entry must be the MAC address */ + memcpy(iwe.u.ap_addr.sa_data, bss->bssid.data.data, WLAN_BSSID_LEN); + iwe.u.ap_addr.sa_family = ARPHRD_ETHER; + iwe.cmd = SIOCGIWAP; + current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); + + /* The following entries will be displayed in the same order we give them */ + + /* The ESSID. */ + if (bss->ssid.data.len > 0) { + char essid[IW_ESSID_MAX_SIZE + 1]; + int size; + + size = wlan_min(IW_ESSID_MAX_SIZE, bss->ssid.data.len); + memset(&essid, 0, sizeof (essid)); + memcpy(&essid, bss->ssid.data.data, size); + WLAN_LOG_DEBUG(1, " essid size = %d\n", size); + iwe.u.data.length = size; + iwe.u.data.flags = 1; + iwe.cmd = SIOCGIWESSID; + current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, &essid[0]); + WLAN_LOG_DEBUG(1, " essid size OK.\n"); + } + + switch (bss->bsstype.data) { + case P80211ENUM_bsstype_infrastructure: + iwe.u.mode = IW_MODE_MASTER; + break; + + case P80211ENUM_bsstype_independent: + iwe.u.mode = IW_MODE_ADHOC; + break; + + default: + iwe.u.mode = 0; + break; + } + iwe.cmd = SIOCGIWMODE; + if (iwe.u.mode) + current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN); + + /* Encryption capability */ + if (bss->privacy.data == P80211ENUM_truth_true) + iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; + else + iwe.u.data.flags = IW_ENCODE_DISABLED; + iwe.u.data.length = 0; + iwe.cmd = SIOCGIWENCODE; + current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, NULL); + + /* Add frequency. (short) bss->channel is the frequency in MHz */ + iwe.u.freq.m = bss->dschannel.data; + iwe.u.freq.e = 0; + iwe.cmd = SIOCGIWFREQ; + current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); + + /* Add quality statistics */ + iwe.u.qual.level = bss->signal.data; + iwe.u.qual.noise = bss->noise.data; + /* do a simple SNR for quality */ + iwe.u.qual.qual = qual_as_percent(bss->signal.data - bss->noise.data); + iwe.cmd = IWEVQUAL; + current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); + + return current_ev; +} + + +static int p80211wext_giwscan(netdevice_t *dev, + struct iw_request_info *info, + struct iw_point *srq, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211msg_dot11req_scan_results_t msg; + int result = 0; + int err = 0; + int i = 0; + int scan_good = 0; + char *current_ev = extra; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + + /* Since wireless tools doesn't really have a way of passing how + * many scan results results there were back here, keep grabbing them + * until we fail. + */ + do { + memset(&msg, 0, sizeof(msg)); + msg.msgcode = DIDmsg_dot11req_scan_results; + msg.bssindex.data = i; + + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + if ((result != 0) || + (msg.resultcode.data != P80211ENUM_resultcode_success)) { + break; + } + + current_ev = wext_translate_bss(current_ev, extra + IW_SCAN_MAX_DATA, &msg, info); + scan_good = 1; + i++; + } while (i < IW_MAX_AP); + + srq->length = (current_ev - extra); + srq->flags = 0; /* todo */ + + if (result && !scan_good) + err = prism2_result2err (msg.resultcode.data); + exit: + DBFEXIT; + return err; +} +#endif + +/*****************************************************/ +//extra wireless extensions stuff to support NetworkManager (I hope) + +#if WIRELESS_EXT > 17 +/* SIOCSIWENCODEEXT */ +static int p80211wext_set_encodeext(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; + p80211msg_dot11req_mibset_t msg; + p80211item_pstr32_t *pstr; + + int result = 0; + struct iw_point *encoding = &wrqu->encoding; + int idx = encoding->flags & IW_ENCODE_INDEX; + + DBFENTER; + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + result = -EBUSY; + goto exit; + } + + WLAN_LOG_DEBUG(1,"set_encode_ext flags[%d] alg[%d] keylen[%d]\n",ext->ext_flags,(int)ext->alg,(int)ext->key_len); + + + if ( ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY ) { + // set default key ? I'm not sure if this the the correct thing to do here + + if ( idx ) { + if (idx < 1 || idx > NUM_WEPKEYS) { + return -EINVAL; + } else + idx--; + } + WLAN_LOG_DEBUG(1,"setting default key (%d)\n",idx); + result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID, idx); + if ( result ) + return -EFAULT; + } + + + if ( ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY ) { + if ( ! ext->alg & IW_ENCODE_ALG_WEP) { + WLAN_LOG_DEBUG(1,"asked to set a non wep key :("); + return -EINVAL; + } + if (idx) { + if (idx <1 || idx > NUM_WEPKEYS) + return -EINVAL; + else + idx--; + } + WLAN_LOG_DEBUG(1,"Set WEP key (%d)\n",idx); + wlandev->wep_keylens[idx] = ext->key_len; + memcpy(wlandev->wep_keys[idx], ext->key, ext->key_len); + + memset( &msg,0,sizeof(msg)); + pstr = (p80211item_pstr32_t*)&msg.mibattribute.data; + memcpy(pstr->data.data, ext->key,ext->key_len); + pstr->data.len = ext->key_len; + switch (idx) { + case 0: + pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0; + break; + case 1: + pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1; + break; + case 2: + pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2; + break; + case 3: + pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3; + break; + default: + break; + } + msg.msgcode = DIDmsg_dot11req_mibset; + result = p80211req_dorequest(wlandev,(UINT8*)&msg); + WLAN_LOG_DEBUG(1,"result (%d)\n",result); + } + exit: + DBFEXIT; + return result; +} + +/* SIOCGIWENCODEEXT */ +static int p80211wext_get_encodeext(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) + +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; + + struct iw_point *encoding = &wrqu->encoding; + int result = 0; + int max_len; + int idx; + + DBFENTER; + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + result = -EBUSY; + goto exit; + } + + + WLAN_LOG_DEBUG(1,"get_encode_ext flags[%d] alg[%d] keylen[%d]\n",ext->ext_flags,(int)ext->alg,(int)ext->key_len); + + + max_len = encoding->length - sizeof(*ext); + if ( max_len <= 0) { + WLAN_LOG_DEBUG(1,"get_encodeext max_len [%d] invalid\n",max_len); + result = -EINVAL; + goto exit; + } + idx = encoding->flags & IW_ENCODE_INDEX; + + WLAN_LOG_DEBUG(1,"get_encode_ext index [%d]\n",idx); + + if (idx) { + if (idx < 1 || idx > NUM_WEPKEYS ) { + WLAN_LOG_DEBUG(1,"get_encode_ext invalid key index [%d]\n",idx); + result = -EINVAL; + goto exit; + } + idx--; + } else { + /* default key ? not sure what to do */ + /* will just use key[0] for now ! FIX ME */ + } + + encoding->flags = idx + 1; + memset(ext,0,sizeof(*ext)); + + ext->alg = IW_ENCODE_ALG_WEP; + ext->key_len = wlandev->wep_keylens[idx]; + memcpy( ext->key, wlandev->wep_keys[idx] , ext->key_len ); + + encoding->flags |= IW_ENCODE_ENABLED; +exit: + DBFEXIT; + + return result; +} + + +/* SIOCSIWAUTH */ +static int p80211_wext_set_iwauth (struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + struct iw_param *param = &wrqu->param; + int result =0; + + DBFENTER; + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + result = -EBUSY; + goto exit; + } + + + WLAN_LOG_DEBUG(1,"set_iwauth flags[%d]\n",(int)param->flags & IW_AUTH_INDEX ); + + switch (param->flags & IW_AUTH_INDEX) { + case IW_AUTH_DROP_UNENCRYPTED: + WLAN_LOG_DEBUG(1,"drop_unencrypted %d\n",param->value); + if (param->value) + result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_true); + else + result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_false); + break; + + case IW_AUTH_PRIVACY_INVOKED: + WLAN_LOG_DEBUG(1,"privacy invoked %d\n",param->value); + if ( param->value) + result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_true); + else + result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_false); + + break; + + case IW_AUTH_80211_AUTH_ALG: + if ( param->value & IW_AUTH_ALG_OPEN_SYSTEM ) { + WLAN_LOG_DEBUG(1,"set open_system\n"); + wlandev->hostwep &= ~HOSTWEP_SHAREDKEY; + } else if ( param->value & IW_AUTH_ALG_SHARED_KEY) { + WLAN_LOG_DEBUG(1,"set shared key\n"); + wlandev->hostwep |= HOSTWEP_SHAREDKEY; + } else { + /* don't know what to do know :( */ + WLAN_LOG_DEBUG(1,"unknown AUTH_ALG (%d)\n",param->value); + result = -EINVAL; + } + break; + + default: + break; + } + + exit: + DBFEXIT; + return result; +} + +/* SIOCSIWAUTH */ +static int p80211_wext_get_iwauth (struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + struct iw_param *param = &wrqu->param; + int result =0; + + DBFENTER; + WLAN_LOG_DEBUG(1,"get_iwauth flags[%d]\n",(int)param->flags & IW_AUTH_INDEX ); + + switch (param->flags & IW_AUTH_INDEX) { + case IW_AUTH_DROP_UNENCRYPTED: + param->value = wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED?1:0; + break; + + case IW_AUTH_PRIVACY_INVOKED: + param->value = wlandev->hostwep & HOSTWEP_PRIVACYINVOKED?1:0; + break; + + case IW_AUTH_80211_AUTH_ALG: + param->value = wlandev->hostwep & HOSTWEP_SHAREDKEY?IW_AUTH_ALG_SHARED_KEY:IW_AUTH_ALG_OPEN_SYSTEM; + break; + + + default: + break; + } + + DBFEXIT; + + return result; +} + + +#endif + + + + + + +/*****************************************************/ + + + + + +/* +typedef int (*iw_handler)(netdevice_t *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); +*/ + +#if WIRELESS_EXT > 12 +static iw_handler p80211wext_handlers[] = { + (iw_handler) p80211wext_siwcommit, /* SIOCSIWCOMMIT */ + (iw_handler) p80211wext_giwname, /* SIOCGIWNAME */ + (iw_handler) NULL, /* SIOCSIWNWID */ + (iw_handler) NULL, /* SIOCGIWNWID */ + (iw_handler) p80211wext_siwfreq, /* SIOCSIWFREQ */ + (iw_handler) p80211wext_giwfreq, /* SIOCGIWFREQ */ + (iw_handler) p80211wext_siwmode, /* SIOCSIWMODE */ + (iw_handler) p80211wext_giwmode, /* SIOCGIWMODE */ + (iw_handler) NULL, /* SIOCSIWSENS */ + (iw_handler) NULL, /* SIOCGIWSENS */ + (iw_handler) NULL, /* not used */ /* SIOCSIWRANGE */ + (iw_handler) p80211wext_giwrange, /* SIOCGIWRANGE */ + (iw_handler) NULL, /* not used */ /* SIOCSIWPRIV */ + (iw_handler) NULL, /* kernel code */ /* SIOCGIWPRIV */ + (iw_handler) NULL, /* not used */ /* SIOCSIWSTATS */ + (iw_handler) NULL, /* kernel code */ /* SIOCGIWSTATS */ + (iw_handler) p80211wext_siwspy, /* SIOCSIWSPY */ + (iw_handler) p80211wext_giwspy, /* SIOCGIWSPY */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* SIOCSIWAP */ + (iw_handler) p80211wext_giwap, /* SIOCGIWAP */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* SIOCGIWAPLIST */ +#if WIRELESS_EXT > 13 + (iw_handler) p80211wext_siwscan, /* SIOCSIWSCAN */ + (iw_handler) p80211wext_giwscan, /* SIOCGIWSCAN */ +#else /* WIRELESS_EXT > 13 */ + (iw_handler) NULL, /* null */ /* SIOCSIWSCAN */ + (iw_handler) NULL, /* null */ /* SIOCGIWSCAN */ +#endif /* WIRELESS_EXT > 13 */ + (iw_handler) p80211wext_siwessid, /* SIOCSIWESSID */ + (iw_handler) p80211wext_giwessid, /* SIOCGIWESSID */ + (iw_handler) NULL, /* SIOCSIWNICKN */ + (iw_handler) p80211wext_giwessid, /* SIOCGIWNICKN */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* SIOCSIWRATE */ + (iw_handler) p80211wext_giwrate, /* SIOCGIWRATE */ + (iw_handler) p80211wext_siwrts, /* SIOCSIWRTS */ + (iw_handler) p80211wext_giwrts, /* SIOCGIWRTS */ + (iw_handler) p80211wext_siwfrag, /* SIOCSIWFRAG */ + (iw_handler) p80211wext_giwfrag, /* SIOCGIWFRAG */ + (iw_handler) p80211wext_siwtxpow, /* SIOCSIWTXPOW */ + (iw_handler) p80211wext_giwtxpow, /* SIOCGIWTXPOW */ + (iw_handler) p80211wext_siwretry, /* SIOCSIWRETRY */ + (iw_handler) p80211wext_giwretry, /* SIOCGIWRETRY */ + (iw_handler) p80211wext_siwencode, /* SIOCSIWENCODE */ + (iw_handler) p80211wext_giwencode, /* SIOCGIWENCODE */ + (iw_handler) NULL, /* SIOCSIWPOWER */ + (iw_handler) NULL, /* SIOCGIWPOWER */ +#if WIRELESS_EXT > 17 +/* WPA operations */ + + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* SIOCSIWGENIE set generic IE */ + (iw_handler) NULL, /* SIOCGIWGENIE get generic IE */ + (iw_handler) p80211_wext_set_iwauth, /* SIOCSIWAUTH set authentication mode params */ + (iw_handler) p80211_wext_get_iwauth, /* SIOCGIWAUTH get authentication mode params */ + + (iw_handler) p80211wext_set_encodeext, /* SIOCSIWENCODEEXT set encoding token & mode */ + (iw_handler) p80211wext_get_encodeext, /* SIOCGIWENCODEEXT get encoding token & mode */ + (iw_handler) NULL, /* SIOCSIWPMKSA PMKSA cache operation */ +#endif +}; + +struct iw_handler_def p80211wext_handler_def = { + .num_standard = sizeof(p80211wext_handlers) / sizeof(iw_handler), + .num_private = 0, + .num_private_args = 0, + .standard = p80211wext_handlers, + .private = NULL, + .private_args = NULL, +#if WIRELESS_EXT > 16 + .get_wireless_stats = p80211wext_get_wireless_stats +#endif +}; + +#endif + +/* wireless extensions' ioctls */ +int p80211wext_support_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + +#if WIRELESS_EXT < 13 + struct iwreq *iwr = (struct iwreq*)ifr; +#endif + + p80211item_uint32_t mibitem; + int err = 0; + + DBFENTER; + + mibitem.status = P80211ENUM_msgitem_status_data_ok; + + if ( wlandev->msdstate != WLAN_MSD_RUNNING ) { + err = -ENODEV; + goto exit; + } + + WLAN_LOG_DEBUG(1, "Received wireless extension ioctl #%d.\n", cmd); + + switch (cmd) { +#if WIRELESS_EXT < 13 + case SIOCSIWNAME: /* unused */ + err = (-EOPNOTSUPP); + break; + case SIOCGIWNAME: /* get name == wireless protocol */ + err = p80211wext_giwname(dev, NULL, (char *) &iwr->u, NULL); + break; + case SIOCSIWNWID: + case SIOCGIWNWID: + err = (-EOPNOTSUPP); + break; + case SIOCSIWFREQ: /* set channel */ + err = p80211wext_siwfreq(dev, NULL, &(iwr->u.freq), NULL); + break; + case SIOCGIWFREQ: /* get channel */ + err = p80211wext_giwfreq(dev, NULL, &(iwr->u.freq), NULL); + break; + case SIOCSIWRANGE: + case SIOCSIWPRIV: + case SIOCSIWAP: /* set access point MAC addresses (BSSID) */ + err = (-EOPNOTSUPP); + break; + + case SIOCGIWAP: /* get access point MAC addresses (BSSID) */ + err = p80211wext_giwap(dev, NULL, &(iwr->u.ap_addr), NULL); + break; + +#if WIRELESS_EXT > 8 + case SIOCSIWMODE: /* set operation mode */ + case SIOCSIWESSID: /* set SSID (network name) */ + case SIOCSIWRATE: /* set default bit rate (bps) */ + err = (-EOPNOTSUPP); + break; + + case SIOCGIWMODE: /* get operation mode */ + err = p80211wext_giwmode(dev, NULL, &iwr->u.mode, NULL); + + break; + case SIOCGIWNICKN: /* get node name/nickname */ + case SIOCGIWESSID: /* get SSID */ + if(iwr->u.essid.pointer) { + char ssid[IW_ESSID_MAX_SIZE+1]; + memset(ssid, 0, sizeof(ssid)); + + err = p80211wext_giwessid(dev, NULL, &iwr->u.essid, ssid); + if(copy_to_user(iwr->u.essid.pointer, ssid, sizeof(ssid))) + err = (-EFAULT); + } + break; + case SIOCGIWRATE: + err = p80211wext_giwrate(dev, NULL, &iwr->u.bitrate, NULL); + break; + case SIOCGIWRTS: + err = p80211wext_giwrts(dev, NULL, &iwr->u.rts, NULL); + break; + case SIOCGIWFRAG: + err = p80211wext_giwfrag(dev, NULL, &iwr->u.rts, NULL); + break; + case SIOCGIWENCODE: + if (!capable(CAP_NET_ADMIN)) + err = -EPERM; + else if (iwr->u.encoding.pointer) { + char keybuf[MAX_KEYLEN]; + err = p80211wext_giwencode(dev, NULL, + &iwr->u.encoding, keybuf); + if (copy_to_user(iwr->u.encoding.pointer, keybuf, + iwr->u.encoding.length)) + err = -EFAULT; + } + break; + case SIOCGIWAPLIST: + case SIOCSIWRTS: + case SIOCSIWFRAG: + case SIOCSIWSENS: + case SIOCGIWSENS: + case SIOCSIWNICKN: /* set node name/nickname */ + case SIOCSIWENCODE: /* set encoding token & mode */ + case SIOCSIWSPY: + case SIOCGIWSPY: + case SIOCSIWPOWER: + case SIOCGIWPOWER: + case SIOCGIWPRIV: + err = (-EOPNOTSUPP); + break; + case SIOCGIWRANGE: + if(iwr->u.data.pointer != NULL) { + struct iw_range range; + err = p80211wext_giwrange(dev, NULL, &iwr->u.data, + (char *) &range); + /* Push that up to the caller */ + if (copy_to_user(iwr->u.data.pointer, &range, sizeof(range))) + err = -EFAULT; + } + break; +#endif /* WIRELESS_EXT > 8 */ +#if WIRELESS_EXT > 9 + case SIOCSIWTXPOW: + err = (-EOPNOTSUPP); + break; + case SIOCGIWTXPOW: + err = p80211wext_giwtxpow(dev, NULL, &iwr->u.txpower, NULL); + break; +#endif /* WIRELESS_EXT > 9 */ +#if WIRELESS_EXT > 10 + case SIOCSIWRETRY: + err = (-EOPNOTSUPP); + break; + case SIOCGIWRETRY: + err = p80211wext_giwretry(dev, NULL, &iwr->u.retry, NULL); + break; +#endif /* WIRELESS_EXT > 10 */ + +#endif /* WIRELESS_EXT <= 12 */ + + default: + err = (-EOPNOTSUPP); + break; + } + + exit: + DBFEXIT; + return (err); +} + +int p80211wext_event_associated(wlandevice_t *wlandev, int assoc) +{ + union iwreq_data data; + + DBFENTER; + +#if WIRELESS_EXT > 13 + /* Send the association state first */ + data.ap_addr.sa_family = ARPHRD_ETHER; + if (assoc) { + memcpy(data.ap_addr.sa_data, wlandev->bssid, WLAN_ADDR_LEN); + } else { + memset(data.ap_addr.sa_data, 0, WLAN_ADDR_LEN); + } + + if (wlan_wext_write) + wireless_send_event(wlandev->netdev, SIOCGIWAP, &data, NULL); + + if (!assoc) goto done; + + // XXX send association data, like IEs, etc etc. +#endif + done: + DBFEXIT; + return 0; +} + + +#endif /* compatibility to wireless extensions */ + + + + --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/p80211netdev.c +++ linux-2.6.28/ubuntu/misc/wireless/p80211/p80211netdev.c @@ -0,0 +1,1558 @@ +/* src/p80211/p80211knetdev.c +* +* Linux Kernel net device interface +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* The functions required for a Linux network device are defined here. +* +* -------------------------------------------------------------------- +*/ + + +/*================================================================*/ +/* System Includes */ + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef SIOCETHTOOL +#include +#endif + +#if WIRELESS_EXT > 12 +#include +#endif + +/*================================================================*/ +/* Project Includes */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*================================================================*/ +/* Local Constants */ + +/*================================================================*/ +/* Local Macros */ + + +/*================================================================*/ +/* Local Types */ + +/*================================================================*/ +/* Local Static Definitions */ + +#define __NO_VERSION__ /* prevent the static definition */ + +#ifdef CONFIG_PROC_FS +static struct proc_dir_entry *proc_p80211; +#endif + +/*================================================================*/ +/* Local Function Declarations */ + +/* Support functions */ +static void p80211netdev_rx_bh(unsigned long arg); + +/* netdevice method functions */ +static int p80211knetdev_init( netdevice_t *netdev); +static struct net_device_stats* p80211knetdev_get_stats(netdevice_t *netdev); +static int p80211knetdev_open( netdevice_t *netdev); +static int p80211knetdev_stop( netdevice_t *netdev ); +static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netdev); +static void p80211knetdev_set_multicast_list(netdevice_t *dev); +static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd); +static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr); +static void p80211knetdev_tx_timeout(netdevice_t *netdev); +static int p80211_rx_typedrop( wlandevice_t *wlandev, UINT16 fc); + +#ifdef CONFIG_PROC_FS +static int +p80211netdev_proc_read( + char *page, + char **start, + off_t offset, + int count, + int *eof, + void *data); +#endif + +/*================================================================*/ +/* Function Definitions */ + +/*---------------------------------------------------------------- +* p80211knetdev_startup +* +* Initialize the wlandevice/netdevice part of 802.11 services at +* load time. +* +* Arguments: +* none +* +* Returns: +* nothing +----------------------------------------------------------------*/ +void p80211netdev_startup(void) +{ + DBFENTER; + +#ifdef CONFIG_PROC_FS + if (PROC_NET != NULL) { + proc_p80211 = create_proc_entry( + "p80211", + (S_IFDIR|S_IRUGO|S_IXUGO), + PROC_NET); + } +#endif + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* p80211knetdev_shutdown +* +* Shutdown the wlandevice/netdevice part of 802.11 services at +* unload time. +* +* Arguments: +* none +* +* Returns: +* nothing +----------------------------------------------------------------*/ +void +p80211netdev_shutdown(void) +{ + DBFENTER; +#ifdef CONFIG_PROC_FS + if (proc_p80211 != NULL) { + remove_proc_entry("p80211", PROC_NET); + } +#endif + DBFEXIT; +} + +/*---------------------------------------------------------------- +* p80211knetdev_init +* +* Init method for a Linux netdevice. Called in response to +* register_netdev. +* +* Arguments: +* none +* +* Returns: +* nothing +----------------------------------------------------------------*/ +static int p80211knetdev_init( netdevice_t *netdev) +{ + DBFENTER; + /* Called in response to register_netdev */ + /* This is usually the probe function, but the probe has */ + /* already been done by the MSD and the create_kdev */ + /* function. All we do here is return success */ + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* p80211knetdev_get_stats +* +* Statistics retrieval for linux netdevices. Here we're reporting +* the Linux i/f level statistics. Hence, for the primary numbers, +* we don't want to report the numbers from the MIB. Eventually, +* it might be useful to collect some of the error counters though. +* +* Arguments: +* netdev Linux netdevice +* +* Returns: +* the address of the statistics structure +----------------------------------------------------------------*/ +static struct net_device_stats* +p80211knetdev_get_stats(netdevice_t *netdev) +{ + wlandevice_t *wlandev = (wlandevice_t*)netdev->priv; + DBFENTER; + + /* TODO: review the MIB stats for items that correspond to + linux stats */ + + DBFEXIT; + return &(wlandev->linux_stats); +} + + +/*---------------------------------------------------------------- +* p80211knetdev_open +* +* Linux netdevice open method. Following a successful call here, +* the device is supposed to be ready for tx and rx. In our +* situation that may not be entirely true due to the state of the +* MAC below. +* +* Arguments: +* netdev Linux network device structure +* +* Returns: +* zero on success, non-zero otherwise +----------------------------------------------------------------*/ +static int p80211knetdev_open( netdevice_t *netdev ) +{ + int result = 0; /* success */ + wlandevice_t *wlandev = (wlandevice_t*)(netdev->priv); + + DBFENTER; + + /* Check to make sure the MSD is running */ + if ( wlandev->msdstate != WLAN_MSD_RUNNING ) { + return -ENODEV; + } + + /* Tell the MSD to open */ + if ( wlandev->open != NULL) { + result = wlandev->open(wlandev); + if ( result == 0 ) { +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43) ) + netdev->interrupt = 0; +#endif + p80211netdev_start_queue(wlandev); + wlandev->state = WLAN_DEVICE_OPEN; + } + } else { + result = -EAGAIN; + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* p80211knetdev_stop +* +* Linux netdevice stop (close) method. Following this call, +* no frames should go up or down through this interface. +* +* Arguments: +* netdev Linux network device structure +* +* Returns: +* zero on success, non-zero otherwise +----------------------------------------------------------------*/ +static int p80211knetdev_stop( netdevice_t *netdev ) +{ + int result = 0; + wlandevice_t *wlandev = (wlandevice_t*)(netdev->priv); + + DBFENTER; + + if ( wlandev->close != NULL ) { + result = wlandev->close(wlandev); + } + + p80211netdev_stop_queue(wlandev); + wlandev->state = WLAN_DEVICE_CLOSED; + + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* p80211netdev_rx +* +* Frame receive function called by the mac specific driver. +* +* Arguments: +* wlandev WLAN network device structure +* skb skbuff containing a full 802.11 frame. +* Returns: +* nothing +* Side effects: +* +----------------------------------------------------------------*/ +void +p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb ) +{ + DBFENTER; + + /* Enqueue for post-irq processing */ + skb_queue_tail(&wlandev->nsd_rxq, skb); + + tasklet_schedule(&wlandev->rx_bh); + + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* p80211netdev_rx_bh +* +* Deferred processing of all received frames. +* +* Arguments: +* wlandev WLAN network device structure +* skb skbuff containing a full 802.11 frame. +* Returns: +* nothing +* Side effects: +* +----------------------------------------------------------------*/ +static void p80211netdev_rx_bh(unsigned long arg) +{ + wlandevice_t *wlandev = (wlandevice_t *) arg; + struct sk_buff *skb = NULL; + netdevice_t *dev = wlandev->netdev; + p80211_hdr_a3_t *hdr; + UINT16 fc; + + DBFENTER; + + /* Let's empty our our queue */ + while ( (skb = skb_dequeue(&wlandev->nsd_rxq)) ) { + if (wlandev->state == WLAN_DEVICE_OPEN) { + + if (dev->type != ARPHRD_ETHER) { + /* RAW frame; we shouldn't convert it */ + // XXX Append the Prism Header here instead. + + /* set up various data fields */ + skb->dev = dev; + skb_reset_mac_header(skb); + + skb->ip_summed = CHECKSUM_NONE; + skb->pkt_type = PACKET_OTHERHOST; + skb->protocol = htons(ETH_P_80211_RAW); + dev->last_rx = jiffies; + + wlandev->linux_stats.rx_packets++; + wlandev->linux_stats.rx_bytes += skb->len; + netif_rx_ni(skb); + continue; + } else { + hdr = (p80211_hdr_a3_t *)skb->data; + fc = ieee2host16(hdr->fc); + if (p80211_rx_typedrop(wlandev, fc)) { + dev_kfree_skb(skb); + continue; + } + + /* perform mcast filtering */ + if (wlandev->netdev->flags & IFF_ALLMULTI) { + /* allow my local address through */ + if (memcmp(hdr->a1, wlandev->netdev->dev_addr, WLAN_ADDR_LEN) != 0) { + /* but reject anything else that isn't multicast */ + if (!(hdr->a1[0] & 0x01)) { + dev_kfree_skb(skb); + continue; + } + } + } + + if ( skb_p80211_to_ether(wlandev, wlandev->ethconv, skb) == 0 ) { + skb->dev->last_rx = jiffies; + wlandev->linux_stats.rx_packets++; + wlandev->linux_stats.rx_bytes += skb->len; + netif_rx_ni(skb); + continue; + } + WLAN_LOG_DEBUG(1, "p80211_to_ether failed.\n"); + } + } + dev_kfree_skb(skb); + } + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* p80211knetdev_hard_start_xmit +* +* Linux netdevice method for transmitting a frame. +* +* Arguments: +* skb Linux sk_buff containing the frame. +* netdev Linux netdevice. +* +* Side effects: +* If the lower layers report that buffers are full. netdev->tbusy +* will be set to prevent higher layers from sending more traffic. +* +* Note: If this function returns non-zero, higher layers retain +* ownership of the skb. +* +* Returns: +* zero on success, non-zero on failure. +----------------------------------------------------------------*/ +static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netdev) +{ + int result = 0; + int txresult = -1; + wlandevice_t *wlandev = (wlandevice_t*)netdev->priv; + p80211_hdr_t p80211_hdr; + p80211_metawep_t p80211_wep; + + DBFENTER; + + if (skb == NULL) { + return 0; + } + + if (wlandev->state != WLAN_DEVICE_OPEN) { + result = 1; + goto failed; + } + + memset(&p80211_hdr, 0, sizeof(p80211_hdr_t)); + memset(&p80211_wep, 0, sizeof(p80211_metawep_t)); + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) ) + if ( test_and_set_bit(0, (void*)&(netdev->tbusy)) != 0 ) { + /* We've been called w/ tbusy set, has the tx */ + /* path stalled? */ + WLAN_LOG_DEBUG(1, "called when tbusy set\n"); + result = 1; + goto failed; + } +#else + if ( netif_queue_stopped(netdev) ) { + WLAN_LOG_DEBUG(1, "called when queue stopped.\n"); + result = 1; + goto failed; + } + + netif_stop_queue(netdev); + + /* No timeout handling here, 2.3.38+ kernels call the + * timeout function directly. + * TODO: Add timeout handling. + */ +#endif + + /* Check to see that a valid mode is set */ + switch( wlandev->macmode ) { + case WLAN_MACMODE_IBSS_STA: + case WLAN_MACMODE_ESS_STA: + case WLAN_MACMODE_ESS_AP: + break; + default: + /* Mode isn't set yet, just drop the frame + * and return success . + * TODO: we need a saner way to handle this + */ + if(skb->protocol != ETH_P_80211_RAW) { + p80211netdev_start_queue(wlandev); + WLAN_LOG_NOTICE( + "Tx attempt prior to association, frame dropped.\n"); + wlandev->linux_stats.tx_dropped++; + result = 0; + goto failed; + } + break; + } + + /* Check for raw transmits */ + if(skb->protocol == ETH_P_80211_RAW) { + if (!capable(CAP_NET_ADMIN)) { + result = 1; + goto failed; + } + /* move the header over */ + memcpy(&p80211_hdr, skb->data, sizeof(p80211_hdr_t)); + skb_pull(skb, sizeof(p80211_hdr_t)); + } else { + if ( skb_ether_to_p80211(wlandev, wlandev->ethconv, skb, &p80211_hdr, &p80211_wep) != 0 ) { + /* convert failed */ + WLAN_LOG_DEBUG(1, "ether_to_80211(%d) failed.\n", + wlandev->ethconv); + result = 1; + goto failed; + } + } + if ( wlandev->txframe == NULL ) { + result = 1; + goto failed; + } + + netdev->trans_start = jiffies; + + wlandev->linux_stats.tx_packets++; + /* count only the packet payload */ + wlandev->linux_stats.tx_bytes += skb->len; + + txresult = wlandev->txframe(wlandev, skb, &p80211_hdr, &p80211_wep); + + if ( txresult == 0) { + /* success and more buf */ + /* avail, re: hw_txdata */ + p80211netdev_wake_queue(wlandev); + result = 0; + } else if ( txresult == 1 ) { + /* success, no more avail */ + WLAN_LOG_DEBUG(3, "txframe success, no more bufs\n"); + /* netdev->tbusy = 1; don't set here, irqhdlr */ + /* may have already cleared it */ + result = 0; + } else if ( txresult == 2 ) { + /* alloc failure, drop frame */ + WLAN_LOG_DEBUG(3, "txframe returned alloc_fail\n"); + result = 1; + } else { + /* buffer full or queue busy, drop frame. */ + WLAN_LOG_DEBUG(3, "txframe returned full or busy\n"); + result = 1; + } + + failed: + /* Free up the WEP buffer if it's not the same as the skb */ + if ((p80211_wep.data) && (p80211_wep.data != skb->data)) + kfree(p80211_wep.data); + + /* we always free the skb here, never in a lower level. */ + if (!result) + dev_kfree_skb(skb); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* p80211knetdev_set_multicast_list +* +* Called from higher lavers whenever there's a need to set/clear +* promiscuous mode or rewrite the multicast list. +* +* Arguments: +* none +* +* Returns: +* nothing +----------------------------------------------------------------*/ +static void p80211knetdev_set_multicast_list(netdevice_t *dev) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + + DBFENTER; + + /* TODO: real multicast support as well */ + + if (wlandev->set_multicast_list) + wlandev->set_multicast_list(wlandev, dev); + + DBFEXIT; +} + +#ifdef SIOCETHTOOL + +static int p80211netdev_ethtool(wlandevice_t *wlandev, void __user *useraddr) +{ + UINT32 ethcmd; + struct ethtool_drvinfo info; + struct ethtool_value edata; + + memset(&info, 0, sizeof(info)); + memset(&edata, 0, sizeof(edata)); + + if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) + return -EFAULT; + + switch (ethcmd) { + case ETHTOOL_GDRVINFO: + info.cmd = ethcmd; + snprintf(info.driver, sizeof(info.driver), "p80211_%s", + wlandev->nsdname); + snprintf(info.version, sizeof(info.version), "%s", + WLAN_RELEASE); + + // info.fw_version + // info.bus_info + + if (copy_to_user(useraddr, &info, sizeof(info))) + return -EFAULT; + return 0; +#ifdef ETHTOOL_GLINK + case ETHTOOL_GLINK: + edata.cmd = ethcmd; + + if (wlandev->linkstatus && + (wlandev->macmode != WLAN_MACMODE_NONE)) { + edata.data = 1; + } else { + edata.data = 0; + } + + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } +#endif + + return -EOPNOTSUPP; +} + +#endif + +/*---------------------------------------------------------------- +* p80211knetdev_do_ioctl +* +* Handle an ioctl call on one of our devices. Everything Linux +* ioctl specific is done here. Then we pass the contents of the +* ifr->data to the request message handler. +* +* Arguments: +* dev Linux kernel netdevice +* ifr Our private ioctl request structure, typed for the +* generic struct ifreq so we can use ptr to func +* w/o cast. +* +* Returns: +* zero on success, a negative errno on failure. Possible values: +* -ENETDOWN Device isn't up. +* -EBUSY cmd already in progress +* -ETIME p80211 cmd timed out (MSD may have its own timers) +* -EFAULT memory fault copying msg from user buffer +* -ENOMEM unable to allocate kernel msg buffer +* -ENOSYS bad magic, it the cmd really for us? +* -EINTR sleeping on cmd, awakened by signal, cmd cancelled. +* +* Call Context: +* Process thread (ioctl caller). TODO: SMP support may require +* locks. +----------------------------------------------------------------*/ +static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd) +{ + int result = 0; + p80211ioctl_req_t *req = (p80211ioctl_req_t*)ifr; + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + UINT8 *msgbuf; + DBFENTER; + + WLAN_LOG_DEBUG(2, "rx'd ioctl, cmd=%d, len=%d\n", cmd, req->len); + + mutex_lock(&wlandev->ioctl_lock); +#if WIRELESS_EXT < 13 + /* Is this a wireless extensions ioctl? */ + if ((cmd >= SIOCIWFIRST) && (cmd <= SIOCIWLAST)) { + if ((result = p80211wext_support_ioctl(dev, ifr, cmd)) + != (-EOPNOTSUPP)) { + goto bail; + } + } +#endif + +#ifdef SIOCETHTOOL + if (cmd == SIOCETHTOOL) { + result = p80211netdev_ethtool(wlandev, (void __user *) ifr->ifr_data); + goto bail; + } +#endif + + /* Test the magic, assume ifr is good if it's there */ + if ( req->magic != P80211_IOCTL_MAGIC ) { + result = -ENOSYS; + goto bail; + } + + if ( cmd == P80211_IFTEST ) { + result = 0; + goto bail; + } else if ( cmd != P80211_IFREQ ) { + result = -ENOSYS; + goto bail; + } + + /* Allocate a buf of size req->len */ + if ((msgbuf = kmalloc( req->len, GFP_KERNEL))) { + if ( copy_from_user( msgbuf, (void __user *) req->data, req->len) ) { + result = -EFAULT; + } else { + result = p80211req_dorequest( wlandev, msgbuf); + } + + if ( result == 0 ) { + if ( copy_to_user( (void __user *) req->data, msgbuf, req->len)) { + result = -EFAULT; + } + } + kfree(msgbuf); + } else { + result = -ENOMEM; + } +bail: + mutex_unlock(&wlandev->ioctl_lock); + + DBFEXIT; + + return result; /* If allocate,copyfrom or copyto fails, return errno */ +} + +/*---------------------------------------------------------------- +* p80211knetdev_set_mac_address +* +* Handles the ioctl for changing the MACAddress of a netdevice +* +* references: linux/netdevice.h and drivers/net/net_init.c +* +* NOTE: [MSM] We only prevent address changes when the netdev is +* up. We don't control anything based on dot11 state. If the +* address is changed on a STA that's currently associated, you +* will probably lose the ability to send and receive data frames. +* Just be aware. Therefore, this should usually only be done +* prior to scan/join/auth/assoc. +* +* Arguments: +* dev netdevice struct +* addr the new MACAddress (a struct) +* +* Returns: +* zero on success, a negative errno on failure. Possible values: +* -EBUSY device is bussy (cmd not possible) +* -and errors returned by: p80211req_dorequest(..) +* +* by: Collin R. Mulliner +----------------------------------------------------------------*/ +static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr) +{ + struct sockaddr *new_addr = addr; + p80211msg_dot11req_mibset_t dot11req; + p80211item_unk392_t *mibattr; + p80211item_pstr6_t *macaddr; + p80211item_uint32_t *resultcode; + int result = 0; + + DBFENTER; + /* If we're running, we don't allow MAC address changes */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) ) + if ( dev->start) { + return -EBUSY; + } +#else + if (netif_running(dev)) { + return -EBUSY; + } +#endif + + /* Set up some convenience pointers. */ + mibattr = &dot11req.mibattribute; + macaddr = (p80211item_pstr6_t*)&mibattr->data; + resultcode = &dot11req.resultcode; + + /* Set up a dot11req_mibset */ + memset(&dot11req, 0, sizeof(p80211msg_dot11req_mibset_t)); + dot11req.msgcode = DIDmsg_dot11req_mibset; + dot11req.msglen = sizeof(p80211msg_dot11req_mibset_t); + memcpy(dot11req.devname, + ((wlandevice_t*)(dev->priv))->name, + WLAN_DEVNAMELEN_MAX - 1); + + /* Set up the mibattribute argument */ + mibattr->did = DIDmsg_dot11req_mibset_mibattribute; + mibattr->status = P80211ENUM_msgitem_status_data_ok; + mibattr->len = sizeof(mibattr->data); + + macaddr->did = DIDmib_dot11mac_dot11OperationTable_dot11MACAddress; + macaddr->status = P80211ENUM_msgitem_status_data_ok; + macaddr->len = sizeof(macaddr->data); + macaddr->data.len = WLAN_ADDR_LEN; + memcpy(&macaddr->data.data, new_addr->sa_data, WLAN_ADDR_LEN); + + /* Set up the resultcode argument */ + resultcode->did = DIDmsg_dot11req_mibset_resultcode; + resultcode->status = P80211ENUM_msgitem_status_no_value; + resultcode->len = sizeof(resultcode->data); + resultcode->data = 0; + + /* now fire the request */ + result = p80211req_dorequest(dev->priv, (UINT8*)&dot11req); + + /* If the request wasn't successful, report an error and don't + * change the netdev address + */ + if ( result != 0 || resultcode->data != P80211ENUM_resultcode_success) { + WLAN_LOG_ERROR( + "Low-level driver failed dot11req_mibset(dot11MACAddress).\n"); + result = -EADDRNOTAVAIL; + } else { + /* everything's ok, change the addr in netdev */ + memcpy(dev->dev_addr, new_addr->sa_data, dev->addr_len); + } + + DBFEXIT; + return result; +} + +static int wlan_change_mtu(netdevice_t *dev, int new_mtu) +{ + DBFENTER; + // 2312 is max 802.11 payload, 20 is overhead, (ether + llc +snap) + // and another 8 for wep. + if ( (new_mtu < 68) || (new_mtu > (2312 - 20 - 8))) + return -EINVAL; + + dev->mtu = new_mtu; + + DBFEXIT; + + return 0; +} + +/*--------------------------------------------------------- + * wlan_alloc_netdev + * + * create a netdev properly over different kernel versions + * this should work with kernels earlier than 2.6.26, and if + * anyone cares they can change it +----------------------------------------------------------*/ + +static inline netdevice_t * wlan_alloc_netdev() { + netdevice_t *dev; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) ) + dev = alloc_netdev(0,"wlan%d",ether_setup); +#else + dev = kmalloc(sizeof(netdevice_t), GFP_ATOMIC); + if ( dev ) { + memset( dev, 0, sizeof(netdevice_t)); + ether_setup(dev); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) ) + dev->nd_net = &init_net; +#endif + } +#endif + return dev; +} + + +/*---------------------------------------------------------------- +* wlan_setup +* +* Roughly matches the functionality of ether_setup. Here +* we set up any members of the wlandevice structure that are common +* to all devices. Additionally, we allocate a linux 'struct device' +* and perform the same setup as ether_setup. +* +* Note: It's important that the caller have setup the wlandev->name +* ptr prior to calling this function. +* +* Arguments: +* wlandev ptr to the wlandev structure for the +* interface. +* Returns: +* zero on success, non-zero otherwise. +* Call Context: +* Should be process thread. We'll assume it might be +* interrupt though. When we add support for statically +* compiled drivers, this function will be called in the +* context of the kernel startup code. +----------------------------------------------------------------*/ +int wlan_setup(wlandevice_t *wlandev) +{ + int result = 0; + netdevice_t *dev; + + DBFENTER; + + /* Set up the wlandev */ + wlandev->state = WLAN_DEVICE_CLOSED; + wlandev->ethconv = WLAN_ETHCONV_8021h; + wlandev->macmode = WLAN_MACMODE_NONE; + + /* Set up the rx queue */ + skb_queue_head_init(&wlandev->nsd_rxq); + tasklet_init(&wlandev->rx_bh, + p80211netdev_rx_bh, + (unsigned long)wlandev); + + /* Allocate and initialize the struct net device */ + dev = wlan_alloc_netdev(); + if ( dev == NULL ) { + WLAN_LOG_ERROR("Failed to alloc netdev.\n"); + result = 1; + } else { + wlandev->netdev = dev; + dev->priv = wlandev; + dev->hard_start_xmit = p80211knetdev_hard_start_xmit; + dev->get_stats = p80211knetdev_get_stats; + + mutex_init(&wlandev->ioctl_lock); + /* block ioctls until fully initialised. Don't forget to call allow_ioctls at some point!*/ + mutex_lock(&wlandev->ioctl_lock); + +#ifdef HAVE_PRIVATE_IOCTL + dev->do_ioctl = p80211knetdev_do_ioctl; +#endif +#ifdef HAVE_MULTICAST + dev->set_multicast_list = p80211knetdev_set_multicast_list; +#endif + dev->init = p80211knetdev_init; + dev->open = p80211knetdev_open; + dev->stop = p80211knetdev_stop; + +#if defined(CONFIG_NET_WIRELESS) || defined(WIRELESS_EXT) +#if (WIRELESS_EXT < 17) + dev->get_wireless_stats = p80211wext_get_wireless_stats; +#endif +#if WIRELESS_EXT > 12 + dev->wireless_handlers = &p80211wext_handler_def; +#endif +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) ) + dev->tbusy = 1; + dev->start = 0; +#else + netif_stop_queue(dev); +#endif +#ifdef HAVE_CHANGE_MTU + dev->change_mtu = wlan_change_mtu; +#endif +#ifdef HAVE_SET_MAC_ADDR + dev->set_mac_address = p80211knetdev_set_mac_address; +#endif +#ifdef HAVE_TX_TIMEOUT + dev->tx_timeout = &p80211knetdev_tx_timeout; + dev->watchdog_timeo = (wlan_watchdog * HZ) / 1000; +#endif + netif_carrier_off(dev); + } + + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* wlan_unsetup +* +* This function is paired with the wlan_setup routine. It should +* be called after unregister_wlandev. Basically, all it does is +* free the 'struct device' that's associated with the wlandev. +* We do it here because the 'struct device' isn't allocated +* explicitly in the driver code, it's done in wlan_setup. To +* do the free in the driver might seem like 'magic'. +* +* Arguments: +* wlandev ptr to the wlandev structure for the +* interface. +* Returns: +* zero on success, non-zero otherwise. +* Call Context: +* Should be process thread. We'll assume it might be +* interrupt though. When we add support for statically +* compiled drivers, this function will be called in the +* context of the kernel startup code. +----------------------------------------------------------------*/ +int wlan_unsetup(wlandevice_t *wlandev) +{ + int result = 0; + + DBFENTER; + + tasklet_kill(&wlandev->rx_bh); + + if (wlandev->netdev == NULL ) { + WLAN_LOG_ERROR("called without wlandev->netdev set.\n"); + result = 1; + } else { + free_netdev(wlandev->netdev); + wlandev->netdev = NULL; + } + + DBFEXIT; + return 0; +} + + + +/*---------------------------------------------------------------- +* register_wlandev +* +* Roughly matches the functionality of register_netdev. This function +* is called after the driver has successfully probed and set up the +* resources for the device. It's now ready to become a named device +* in the Linux system. +* +* First we allocate a name for the device (if not already set), then +* we call the Linux function register_netdevice. +* +* Arguments: +* wlandev ptr to the wlandev structure for the +* interface. +* Returns: +* zero on success, non-zero otherwise. +* Call Context: +* Can be either interrupt or not. +----------------------------------------------------------------*/ +int register_wlandev(wlandevice_t *wlandev) +{ + int i = 0; + netdevice_t *dev = wlandev->netdev; + + DBFENTER; +/* alloc_netdev already sets up the name */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) ) + i = register_netdev(dev); + if (i) + return i; +#else + i = dev_alloc_name(wlandev->netdev, "wlan%d"); + if (i >= 0) { + i = register_netdev(wlandev->netdev); + } + if (i != 0) { + return -EIO; + } + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) ) + dev->name = wlandev->name; +#else + strcpy(wlandev->name, dev->name); +#endif +#endif + + +#ifdef CONFIG_PROC_FS + if (proc_p80211) { + wlandev->procdir = proc_mkdir(wlandev->name, proc_p80211); + if ( wlandev->procdir ) + wlandev->procwlandev = + create_proc_read_entry("wlandev", 0, + wlandev->procdir, + p80211netdev_proc_read, + wlandev); + if (wlandev->nsd_proc_read) + create_proc_read_entry("nsd", 0, + wlandev->procdir, + wlandev->nsd_proc_read, + wlandev); + } +#endif + + if (wlan_wext_write) { +/* + // fake out a call to ifstate_enable! + p80211msg_lnxreq_ifstate_t msg; + memset(&msg, 0, sizeof(msg)); + msg.msgcode = DIDmsg_lnxreq_ifstate; + msg.msglen = sizeof(msg); + msg.ifstate.status = P80211ENUM_msgitem_status_data_ok; + msg.ifstate.data = P80211ENUM_ifstate_enable; + + p80211req_dorequest(wlandev, &msg); +*/ + } else { +#ifdef CONFIG_HOTPLUG + p80211_run_sbin_hotplug(wlandev, WLAN_HOTPLUG_REGISTER); +#endif + } + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* unregister_wlandev +* +* Roughly matches the functionality of unregister_netdev. This +* function is called to remove a named device from the system. +* +* First we tell linux that the device should no longer exist. +* Then we remove it from the list of known wlan devices. +* +* Arguments: +* wlandev ptr to the wlandev structure for the +* interface. +* Returns: +* zero on success, non-zero otherwise. +* Call Context: +* Can be either interrupt or not. +----------------------------------------------------------------*/ +int unregister_wlandev(wlandevice_t *wlandev) +{ + struct sk_buff *skb; + + DBFENTER; + +#ifdef CONFIG_HOTPLUG + p80211_run_sbin_hotplug(wlandev, WLAN_HOTPLUG_REMOVE); +#endif + +#ifdef CONFIG_PROC_FS + if ( wlandev->procwlandev ) { + remove_proc_entry("wlandev", wlandev->procdir); + } + if ( wlandev->nsd_proc_read ) { + remove_proc_entry("nsd", wlandev->procdir); + } + if (wlandev->procdir) { + remove_proc_entry(wlandev->name, proc_p80211); + } +#endif + + unregister_netdev(wlandev->netdev); + + /* Now to clean out the rx queue */ + while ( (skb = skb_dequeue(&wlandev->nsd_rxq)) ) { + dev_kfree_skb(skb); + } + + DBFEXIT; + return 0; +} + +#ifdef CONFIG_PROC_FS +/*---------------------------------------------------------------- +* proc_read +* +* Read function for /proc/net/p80211//wlandev +* +* Arguments: +* buf +* start +* offset +* count +* eof +* data +* Returns: +* zero on success, non-zero otherwise. +* Call Context: +* Can be either interrupt or not. +----------------------------------------------------------------*/ +static int +p80211netdev_proc_read( + char *page, + char **start, + off_t offset, + int count, + int *eof, + void *data) +{ + char *p = page; + wlandevice_t *wlandev = (wlandevice_t *) data; + + DBFENTER; + if (offset != 0) { + *eof = 1; + goto exit; + } + + p += sprintf(p, "p80211 version: %s (%s)\n\n", + WLAN_RELEASE, WLAN_BUILD_DATE); + p += sprintf(p, "name : %s\n", wlandev->name); + p += sprintf(p, "nsd name : %s\n", wlandev->nsdname); + p += sprintf(p, "address : %02x:%02x:%02x:%02x:%02x:%02x\n", + wlandev->netdev->dev_addr[0], wlandev->netdev->dev_addr[1], wlandev->netdev->dev_addr[2], + wlandev->netdev->dev_addr[3], wlandev->netdev->dev_addr[4], wlandev->netdev->dev_addr[5]); + p += sprintf(p, "nsd caps : %s%s%s%s%s%s%s%s%s%s\n", + (wlandev->nsdcaps & P80211_NSDCAP_HARDWAREWEP) ? "wep_hw " : "", + (wlandev->nsdcaps & P80211_NSDCAP_TIEDWEP) ? "wep_tied " : "", + (wlandev->nsdcaps & P80211_NSDCAP_NOHOSTWEP) ? "wep_hw_only " : "", + (wlandev->nsdcaps & P80211_NSDCAP_PBCC) ? "pbcc " : "", + (wlandev->nsdcaps & P80211_NSDCAP_SHORT_PREAMBLE) ? "short_preamble " : "", + (wlandev->nsdcaps & P80211_NSDCAP_AGILITY) ? "agility " : "", + (wlandev->nsdcaps & P80211_NSDCAP_AP_RETRANSMIT) ? "ap_retransmit " : "", + (wlandev->nsdcaps & P80211_NSDCAP_HWFRAGMENT) ? "hw_frag " : "", + (wlandev->nsdcaps & P80211_NSDCAP_AUTOJOIN) ? "autojoin " : "", + (wlandev->nsdcaps & P80211_NSDCAP_NOSCAN) ? "" : "scan "); + + + p += sprintf(p, "bssid : %02x:%02x:%02x:%02x:%02x:%02x\n", + wlandev->bssid[0], wlandev->bssid[1], wlandev->bssid[2], + wlandev->bssid[3], wlandev->bssid[4], wlandev->bssid[5]); + + p += sprintf(p, "Enabled : %s%s\n", + (wlandev->shortpreamble) ? "short_preamble " : "", + (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) ? "privacy" : ""); + p += sprintf(p, "msdstate=%d\n", wlandev->msdstate); + + + exit: + DBFEXIT; + return (p - page); +} +#endif + +/*---------------------------------------------------------------- +* p80211netdev_hwremoved +* +* Hardware removed notification. This function should be called +* immediately after an MSD has detected that the underlying hardware +* has been yanked out from under us. The primary things we need +* to do are: +* - Mark the wlandev +* - Prevent any further traffic from the knetdev i/f +* - Prevent any further requests from mgmt i/f +* - If there are any waitq'd mgmt requests or mgmt-frame exchanges, +* shut them down. +* - Call the MSD hwremoved function. +* +* The remainder of the cleanup will be handled by unregister(). +* Our primary goal here is to prevent as much tickling of the MSD +* as possible since the MSD is already in a 'wounded' state. +* +* TODO: As new features are added, this function should be +* updated. +* +* Arguments: +* wlandev WLAN network device structure +* Returns: +* nothing +* Side effects: +* +* Call context: +* Usually interrupt. +----------------------------------------------------------------*/ +void p80211netdev_hwremoved(wlandevice_t *wlandev) +{ + DBFENTER; + wlandev->hwremoved = 1; + if ( wlandev->state == WLAN_DEVICE_OPEN) { + p80211netdev_stop_queue(wlandev); + } + + netif_device_detach(wlandev->netdev); + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* p80211_rx_typedrop +* +* Classifies the frame, increments the appropriate counter, and +* returns 0|1|2 indicating whether the driver should handle, ignore, or +* drop the frame +* +* Arguments: +* wlandev wlan device structure +* fc frame control field +* +* Returns: +* zero if the frame should be handled by the driver, +* one if the frame should be ignored +* anything else means we drop it. +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static int p80211_rx_typedrop( wlandevice_t *wlandev, UINT16 fc) +{ + UINT16 ftype; + UINT16 fstype; + int drop = 0; + /* Classify frame, increment counter */ + ftype = WLAN_GET_FC_FTYPE(fc); + fstype = WLAN_GET_FC_FSTYPE(fc); +#if 0 + WLAN_LOG_DEBUG(4, + "rx_typedrop : ftype=%d fstype=%d.\n", ftype, fstype); +#endif + switch ( ftype ) { + case WLAN_FTYPE_MGMT: + if ((wlandev->netdev->flags & IFF_PROMISC) || + (wlandev->netdev->flags & IFF_ALLMULTI)) { + drop = 1; + break; + } + WLAN_LOG_DEBUG(3, "rx'd mgmt:\n"); + wlandev->rx.mgmt++; + switch( fstype ) { + case WLAN_FSTYPE_ASSOCREQ: + /* printk("assocreq"); */ + wlandev->rx.assocreq++; + break; + case WLAN_FSTYPE_ASSOCRESP: + /* printk("assocresp"); */ + wlandev->rx.assocresp++; + break; + case WLAN_FSTYPE_REASSOCREQ: + /* printk("reassocreq"); */ + wlandev->rx.reassocreq++; + break; + case WLAN_FSTYPE_REASSOCRESP: + /* printk("reassocresp"); */ + wlandev->rx.reassocresp++; + break; + case WLAN_FSTYPE_PROBEREQ: + /* printk("probereq"); */ + wlandev->rx.probereq++; + break; + case WLAN_FSTYPE_PROBERESP: + /* printk("proberesp"); */ + wlandev->rx.proberesp++; + break; + case WLAN_FSTYPE_BEACON: + /* printk("beacon"); */ + wlandev->rx.beacon++; + break; + case WLAN_FSTYPE_ATIM: + /* printk("atim"); */ + wlandev->rx.atim++; + break; + case WLAN_FSTYPE_DISASSOC: + /* printk("disassoc"); */ + wlandev->rx.disassoc++; + break; + case WLAN_FSTYPE_AUTHEN: + /* printk("authen"); */ + wlandev->rx.authen++; + break; + case WLAN_FSTYPE_DEAUTHEN: + /* printk("deauthen"); */ + wlandev->rx.deauthen++; + break; + default: + /* printk("unknown"); */ + wlandev->rx.mgmt_unknown++; + break; + } + /* printk("\n"); */ + drop = 2; + break; + + case WLAN_FTYPE_CTL: + if ((wlandev->netdev->flags & IFF_PROMISC) || + (wlandev->netdev->flags & IFF_ALLMULTI)) { + drop = 1; + break; + } + WLAN_LOG_DEBUG(3, "rx'd ctl:\n"); + wlandev->rx.ctl++; + switch( fstype ) { + case WLAN_FSTYPE_PSPOLL: + /* printk("pspoll"); */ + wlandev->rx.pspoll++; + break; + case WLAN_FSTYPE_RTS: + /* printk("rts"); */ + wlandev->rx.rts++; + break; + case WLAN_FSTYPE_CTS: + /* printk("cts"); */ + wlandev->rx.cts++; + break; + case WLAN_FSTYPE_ACK: + /* printk("ack"); */ + wlandev->rx.ack++; + break; + case WLAN_FSTYPE_CFEND: + /* printk("cfend"); */ + wlandev->rx.cfend++; + break; + case WLAN_FSTYPE_CFENDCFACK: + /* printk("cfendcfack"); */ + wlandev->rx.cfendcfack++; + break; + default: + /* printk("unknown"); */ + wlandev->rx.ctl_unknown++; + break; + } + /* printk("\n"); */ + drop = 2; + break; + + case WLAN_FTYPE_DATA: + wlandev->rx.data++; + switch( fstype ) { + case WLAN_FSTYPE_DATAONLY: + wlandev->rx.dataonly++; + break; + case WLAN_FSTYPE_DATA_CFACK: + wlandev->rx.data_cfack++; + break; + case WLAN_FSTYPE_DATA_CFPOLL: + wlandev->rx.data_cfpoll++; + break; + case WLAN_FSTYPE_DATA_CFACK_CFPOLL: + wlandev->rx.data__cfack_cfpoll++; + break; + case WLAN_FSTYPE_NULL: + WLAN_LOG_DEBUG(3, "rx'd data:null\n"); + wlandev->rx.null++; + break; + case WLAN_FSTYPE_CFACK: + WLAN_LOG_DEBUG(3, "rx'd data:cfack\n"); + wlandev->rx.cfack++; + break; + case WLAN_FSTYPE_CFPOLL: + WLAN_LOG_DEBUG(3, "rx'd data:cfpoll\n"); + wlandev->rx.cfpoll++; + break; + case WLAN_FSTYPE_CFACK_CFPOLL: + WLAN_LOG_DEBUG(3, "rx'd data:cfack_cfpoll\n"); + wlandev->rx.cfack_cfpoll++; + break; + default: + /* printk("unknown"); */ + wlandev->rx.data_unknown++; + break; + } + + break; + } + return drop; +} + +#ifdef CONFIG_HOTPLUG +/* Notify userspace when a netdevice event occurs, + * by running '/sbin/hotplug net' with certain + * environment variables set. + */ +int p80211_run_sbin_hotplug(wlandevice_t *wlandev, char *action) +{ + char *argv[3], *envp[7], ifname[12 + IFNAMSIZ], action_str[32]; + char nsdname[32], wlan_wext[32]; + int i; + + if (wlandev) { + sprintf(ifname, "INTERFACE=%s", wlandev->name); + sprintf(nsdname, "NSDNAME=%s", wlandev->nsdname); + } else { + sprintf(ifname, "INTERFACE=null"); + sprintf(nsdname, "NSDNAME=null"); + } + + sprintf(wlan_wext, "WLAN_WEXT=%s", wlan_wext_write ? "y" : ""); + sprintf(action_str, "ACTION=%s", action); + + i = 0; + argv[i++] = hotplug_path; + argv[i++] = "wlan"; + argv[i] = NULL; + + i = 0; + /* minimal command environment */ + envp [i++] = "HOME=/"; + envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; + envp [i++] = ifname; + envp [i++] = action_str; + envp [i++] = nsdname; + envp [i++] = wlan_wext; + envp [i] = NULL; + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,62)) + return call_usermodehelper(argv [0], argv, envp); +#else + return call_usermodehelper(argv [0], argv, envp, 0); +#endif +} + +#endif + + +void p80211_suspend(wlandevice_t *wlandev) +{ + DBFENTER; + +#ifdef CONFIG_HOTPLUG + p80211_run_sbin_hotplug(wlandev, WLAN_HOTPLUG_SUSPEND); +#endif + + DBFEXIT; +} + +void p80211_resume(wlandevice_t *wlandev) +{ + DBFENTER; + +#ifdef CONFIG_HOTPLUG + p80211_run_sbin_hotplug(wlandev, WLAN_HOTPLUG_RESUME); +#endif + + DBFEXIT; +} + +static void p80211knetdev_tx_timeout( netdevice_t *netdev) +{ + wlandevice_t *wlandev = (wlandevice_t*)netdev->priv; + DBFENTER; + + if (wlandev->tx_timeout) { + wlandev->tx_timeout(wlandev); + } else { + WLAN_LOG_WARNING("Implement tx_timeout for %s\n", + wlandev->nsdname); + p80211netdev_wake_queue(wlandev); + } + + DBFEXIT; +} + +void p80211_allow_ioctls(wlandevice_t *wlandev) { + mutex_unlock(&wlandev->ioctl_lock); +} --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/Makefile +++ linux-2.6.28/ubuntu/misc/wireless/p80211/Makefile @@ -0,0 +1,11 @@ +obj-$(CONFIG_P80211) := p80211.o + +p80211-objs := p80211mod.o \ + p80211conv.o \ + p80211req.o \ + p80211wep.o \ + p80211wext.o \ + p80211netdev.o + +EXTRA_CFLAGS += -DWLAN_TXMGMT_MINBRATE -DRSN_INTERNAL_ROAM \ + -DWLAN_HOSTIF=WLAN_NONE -I$(src) --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/p80211wep.c +++ linux-2.6.28/ubuntu/misc/wireless/p80211/p80211wep.c @@ -0,0 +1,317 @@ +/* src/p80211/p80211wep.c +* +* WEP encode/decode for P80211. +* +* Copyright (C) 2002 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +*/ + +/*================================================================*/ +/* System Includes */ + + +#include + +#include +#include +#include +#include + +#include +#include + +// #define WEP_DEBUG + +/*================================================================*/ +/* Project Includes */ + +#include +#include +#include +#include +#include +#include + +/*================================================================*/ +/* Local Constants */ + +#define SSWAP(a,b) {UINT8 tmp = s[a]; s[a] = s[b]; s[b] = tmp;} +#define WEP_KEY(x) (((x) & 0xC0) >> 6) + +/*================================================================*/ +/* Local Macros */ + + +/*================================================================*/ +/* Local Types */ + + +/*================================================================*/ +/* Local Static Definitions */ + +static const UINT32 wep_crc32_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; + +/*================================================================*/ +/* Local Function Declarations */ + +/*================================================================*/ +/* Function Definitions */ + +/* keylen in bytes! */ + +int wep_change_key(wlandevice_t *wlandev, int keynum, UINT8* key, int keylen) +{ + if (keylen < 0) return -1; + if (keylen >= MAX_KEYLEN) return -1; + if (key == NULL) return -1; + if (keynum < 0) return -1; + if (keynum >= NUM_WEPKEYS) return -1; + + +#ifdef WEP_DEBUG + printk(KERN_DEBUG "WEP key %d len %d = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", keynum, keylen, key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7]); +#endif + + wlandev->wep_keylens[keynum] = keylen; + memcpy(wlandev->wep_keys[keynum], key, keylen); + + return 0; +} + +/* + 4-byte IV at start of buffer, 4-byte ICV at end of buffer. + if successful, buf start is payload begin, length -= 8; + */ +int wep_decrypt(wlandevice_t *wlandev, UINT8 *buf, UINT32 len, int key_override, UINT8 *iv, UINT8 *icv) +{ + UINT32 i, j, k, crc, keylen; + UINT8 s[256], key[64], c_crc[4]; + UINT8 keyidx; + + /* Needs to be at least 8 bytes of payload */ + if (len <= 0) return -1; + + /* initialize the first bytes of the key from the IV */ + key[0] = iv[0]; + key[1] = iv[1]; + key[2] = iv[2]; + keyidx = WEP_KEY(iv[3]); + + if (key_override >= 0) + keyidx = key_override; + + if (keyidx >= NUM_WEPKEYS) return -2; + + keylen = wlandev->wep_keylens[keyidx]; + + if (keylen == 0) return -3; + + /* copy the rest of the key over from the designated key */ + memcpy(key+3, wlandev->wep_keys[keyidx], keylen); + + keylen+=3; /* add in IV bytes */ + +#ifdef WEP_DEBUG + printk(KERN_DEBUG "D %d: %02x %02x %02x (%d %d) %02x:%02x:%02x:%02x:%02x\n", len, key[0], key[1], key[2], keyidx, keylen, key[3], key[4], key[5], key[6], key[7]); +#endif + + /* set up the RC4 state */ + for (i = 0; i < 256; i++) + s[i] = i; + j = 0; + for (i = 0; i < 256; i++) { + j = (j + s[i] + key[i % keylen]) & 0xff; + SSWAP(i,j); + } + + /* Apply the RC4 to the data, update the CRC32 */ + crc = ~0; + i = j = 0; + for (k = 0; k < len; k++) { + i = (i+1) & 0xff; + j = (j+s[i]) & 0xff; + SSWAP(i,j); + buf[k] ^= s[(s[i] + s[j]) & 0xff]; + crc = wep_crc32_table[(crc ^ buf[k]) & 0xff] ^ (crc >> 8); + } + crc = ~crc; + + /* now let's check the crc */ + c_crc[0] = crc; + c_crc[1] = crc >> 8; + c_crc[2] = crc >> 16; + c_crc[3] = crc >> 24; + + for (k = 0; k < 4; k++) { + i = (i + 1) & 0xff; + j = (j+s[i]) & 0xff; + SSWAP(i,j); + if ((c_crc[k] ^ s[(s[i] + s[j]) & 0xff]) != icv[k]) + return -(4 | (k << 4)) ; /* ICV mismatch */ + } + + return 0; +} + +/* encrypts in-place. */ +int wep_encrypt(wlandevice_t *wlandev, UINT8 *buf, UINT8 *dst, UINT32 len, int keynum, UINT8 *iv, UINT8 *icv) +{ + UINT32 i, j, k, crc, keylen; + UINT8 s[256], key[64]; + + /* no point in WEPping an empty frame */ + if (len <= 0) return -1; + + /* we need to have a real key.. */ + if (keynum >= NUM_WEPKEYS) return -2; + keylen = wlandev->wep_keylens[keynum]; + if (keylen <= 0) return -3; + + /* use a random IV. And skip known weak ones. */ + get_random_bytes(iv, 3); + while ((iv[1] == 0xff) && (iv[0] >= 3) && (iv[0] < keylen)) + get_random_bytes(iv, 3); + + iv[3] = (keynum & 0x03) << 6; + + key[0] = iv[0]; + key[1] = iv[1]; + key[2] = iv[2]; + + /* copy the rest of the key over from the designated key */ + memcpy(key+3, wlandev->wep_keys[keynum], keylen); + + keylen+=3; /* add in IV bytes */ + +#ifdef WEP_DEBUG + printk(KERN_DEBUG "E %d (%d/%d %d) %02x %02x %02x %02x:%02x:%02x:%02x:%02x\n", len, iv[3], keynum, keylen, key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7]); +#endif + + /* set up the RC4 state */ + for (i = 0; i < 256; i++) + s[i] = i; + j = 0; + for (i = 0; i < 256; i++) { + j = (j + s[i] + key[i % keylen]) & 0xff; + SSWAP(i,j); + } + + /* Update CRC32 then apply RC4 to the data */ + crc = ~0; + i = j = 0; + for (k = 0; k < len; k++) { + crc = wep_crc32_table[(crc ^ buf[k]) & 0xff] ^ (crc >> 8); + i = (i+1) & 0xff; + j = (j+s[i]) & 0xff; + SSWAP(i,j); + dst[k] = buf[k] ^ s[(s[i] + s[j]) & 0xff]; + } + crc = ~crc; + + /* now let's encrypt the crc */ + icv[0] = crc; + icv[1] = crc >> 8; + icv[2] = crc >> 16; + icv[3] = crc >> 24; + + for (k = 0; k < 4; k++) { + i = (i + 1) & 0xff; + j = (j+s[i]) & 0xff; + SSWAP(i,j); + icv[k] ^= s[(s[i] + s[j]) & 0xff]; + } + + return 0; +} --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/p80211req.c +++ linux-2.6.28/ubuntu/misc/wireless/p80211/p80211req.c @@ -0,0 +1,329 @@ +/* src/p80211/p80211req.c +* +* Request/Indication/MacMgmt interface handling functions +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file contains the functions, types, and macros to support the +* MLME request interface that's implemented via the device ioctls. +* +* -------------------------------------------------------------------- +*/ + +/*================================================================*/ +/* System Includes */ + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/*================================================================*/ +/* Project Includes */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*================================================================*/ +/* Local Constants */ + +/* Maximum amount of time we'll wait for a request to complete */ +#define P80211REQ_MAXTIME 3*HZ /* 3 seconds */ + +/*================================================================*/ +/* Local Macros */ + +/*================================================================*/ +/* Local Types */ + +/*================================================================*/ +/* Local Static Definitions */ + +/*================================================================*/ +/* Local Function Declarations */ + +static void p80211req_handlemsg( wlandevice_t *wlandev, p80211msg_t *msg); +static int p80211req_mibset_mibget(wlandevice_t *wlandev, p80211msg_dot11req_mibget_t *mib_msg, int isget); + +/*================================================================*/ +/* Function Definitions */ + + +/*---------------------------------------------------------------- +* p80211req_dorequest +* +* Handles an MLME reqest/confirm message. +* +* Arguments: +* wlandev WLAN device struct +* msgbuf Buffer containing a request message +* +* Returns: +* 0 on success, an errno otherwise +* +* Call context: +* Potentially blocks the caller, so it's a good idea to +* not call this function from an interrupt context. +----------------------------------------------------------------*/ +int p80211req_dorequest( wlandevice_t *wlandev, UINT8 *msgbuf) +{ + int result = 0; + p80211msg_t *msg = (p80211msg_t*)msgbuf; + + DBFENTER; + + /* Check to make sure the MSD is running */ + if ( + !((wlandev->msdstate == WLAN_MSD_HWPRESENT && + msg->msgcode == DIDmsg_lnxreq_ifstate) || + wlandev->msdstate == WLAN_MSD_RUNNING || + wlandev->msdstate == WLAN_MSD_FWLOAD) ) { + return -ENODEV; + } + + /* Check Permissions */ + if (!capable(CAP_NET_ADMIN) && + (msg->msgcode != DIDmsg_dot11req_mibget)) { + WLAN_LOG_ERROR("%s: only dot11req_mibget allowed for non-root.\n", wlandev->name); + return -EPERM; + } + + /* Check for busy status */ + if ( test_and_set_bit(1, &(wlandev->request_pending))) { + return -EBUSY; + } + + /* Allow p80211 to look at msg and handle if desired. */ + /* So far, all p80211 msgs are immediate, no waitq/timer necessary */ + /* This may change. */ + p80211req_handlemsg(wlandev, msg); + + /* Pass it down to wlandev via wlandev->mlmerequest */ + if ( wlandev->mlmerequest != NULL ) + wlandev->mlmerequest(wlandev, msg); + + clear_bit( 1, &(wlandev->request_pending)); + DBFEXIT; + return result; /* if result==0, msg->status still may contain an err */ +} + +/*---------------------------------------------------------------- +* p80211req_handlemsg +* +* p80211 message handler. Primarily looks for messages that +* belong to p80211 and then dispatches the appropriate response. +* TODO: we don't do anything yet. Once the linuxMIB is better +* defined we'll need a get/set handler. +* +* Arguments: +* wlandev WLAN device struct +* msg message structure +* +* Returns: +* nothing (any results are set in the status field of the msg) +* +* Call context: +* Process thread +----------------------------------------------------------------*/ +static void p80211req_handlemsg( wlandevice_t *wlandev, p80211msg_t *msg) +{ + DBFENTER; + + switch (msg->msgcode) { + + case DIDmsg_lnxreq_hostwep: { + p80211msg_lnxreq_hostwep_t *req = (p80211msg_lnxreq_hostwep_t*) msg; + wlandev->hostwep &= ~(HOSTWEP_DECRYPT|HOSTWEP_ENCRYPT); + if (req->decrypt.data == P80211ENUM_truth_true) + wlandev->hostwep |= HOSTWEP_DECRYPT; + if (req->encrypt.data == P80211ENUM_truth_true) + wlandev->hostwep |= HOSTWEP_ENCRYPT; + + break; + } + case DIDmsg_dot11req_mibget: + case DIDmsg_dot11req_mibset: { + int isget = (msg->msgcode == DIDmsg_dot11req_mibget); + p80211msg_dot11req_mibget_t *mib_msg = (p80211msg_dot11req_mibget_t *) msg; + p80211req_mibset_mibget (wlandev, mib_msg, isget); + } + default: + // XXX do nothing! + ; + } /* switch msg->msgcode */ + + DBFEXIT; + + return; +} + +static int p80211req_mibset_mibget(wlandevice_t *wlandev, + p80211msg_dot11req_mibget_t *mib_msg, + int isget) +{ + p80211itemd_t *mibitem = (p80211itemd_t *) mib_msg->mibattribute.data; + p80211pstrd_t *pstr = (p80211pstrd_t*) mibitem->data; + UINT8 *key = mibitem->data + sizeof(p80211pstrd_t); + + DBFENTER; + + switch (mibitem->did) { + case DIDmib_dot11smt_p80211Table_p80211_ifstate: { + UINT32 *data = (UINT32 *) mibitem->data; + if (isget) + switch (wlandev->msdstate) { + case WLAN_MSD_HWPRESENT: + *data = P80211ENUM_ifstate_disable; + break; + case WLAN_MSD_FWLOAD: + *data = P80211ENUM_ifstate_fwload; + break; + case WLAN_MSD_RUNNING: + *data = P80211ENUM_ifstate_enable; + break; + default: + *data = P80211ENUM_ifstate_enable; + } + break; + } + case DIDmib_dot11phy_dot11PhyOperationTable_dot11ShortPreambleEnabled: { + UINT32 *data = (UINT32 *) mibitem->data; + + if (isget) + *data = wlandev->shortpreamble; + else + wlandev->shortpreamble = *data; + break; + } + case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0: { + if (!isget) + wep_change_key(wlandev, 0, key, pstr->len); + break; + } + case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1: { + if (!isget) + wep_change_key(wlandev, 1, key, pstr->len); + break; + } + case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2: { + if (!isget) + wep_change_key(wlandev, 2, key, pstr->len); + break; + } + case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3: { + if (!isget) + wep_change_key(wlandev, 3, key, pstr->len); + break; + } + case DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID: { + UINT32 *data = (UINT32 *) mibitem->data; + + if (isget) { + *data = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK; + } else { + wlandev->hostwep &= ~(HOSTWEP_DEFAULTKEY_MASK); + + wlandev->hostwep |= (*data & HOSTWEP_DEFAULTKEY_MASK); + } + break; + } + case DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked: { + UINT32 *data = (UINT32 *) mibitem->data; + + if (isget) { + if (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) + *data = P80211ENUM_truth_true; + else + *data = P80211ENUM_truth_false; + } else { + wlandev->hostwep &= ~(HOSTWEP_PRIVACYINVOKED); + if (*data == P80211ENUM_truth_true) + wlandev->hostwep |= HOSTWEP_PRIVACYINVOKED; + } + break; + } + case DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted: { + UINT32 *data = (UINT32 *) mibitem->data; + + if (isget) { + if (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED) + *data = P80211ENUM_truth_true; + else + *data = P80211ENUM_truth_false; + } else { + wlandev->hostwep &= ~(HOSTWEP_EXCLUDEUNENCRYPTED); + if (*data == P80211ENUM_truth_true) + wlandev->hostwep |= HOSTWEP_EXCLUDEUNENCRYPTED; + } + break; + } + default: + // XXXX do nothing! + ; + } + + DBFEXIT; + return 0; +} + --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/p80211conv.c +++ linux-2.6.28/ubuntu/misc/wireless/p80211/p80211conv.c @@ -0,0 +1,691 @@ +/* src/p80211/p80211conv.c +* +* Ether/802.11 conversions and packet buffer routines +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file defines the functions that perform Ethernet to/from +* 802.11 frame conversions. +* +* -------------------------------------------------------------------- +*/ +/*================================================================*/ +/* System Includes */ + +#define __NO_VERSION__ /* prevent the static definition */ + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +/*================================================================*/ +/* Project Includes */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +/*================================================================*/ +/* Local Constants */ + +/*================================================================*/ +/* Local Macros */ + + +/*================================================================*/ +/* Local Types */ + + +/*================================================================*/ +/* Local Static Definitions */ + +static UINT8 oui_rfc1042[] = {0x00, 0x00, 0x00}; +static UINT8 oui_8021h[] = {0x00, 0x00, 0xf8}; + +/*================================================================*/ +/* Local Function Declarations */ + + +/*================================================================*/ +/* Function Definitions */ + +/*---------------------------------------------------------------- +* p80211pb_ether_to_80211 +* +* Uses the contents of the ether frame and the etherconv setting +* to build the elements of the 802.11 frame. +* +* We don't actually set +* up the frame header here. That's the MAC's job. We're only handling +* conversion of DIXII or 802.3+LLC frames to something that works +* with 802.11. +* +* Note -- 802.11 header is NOT part of the skb. Likewise, the 802.11 +* FCS is also not present and will need to be added elsewhere. +* +* Arguments: +* ethconv Conversion type to perform +* skb skbuff containing the ether frame +* p80211_hdr 802.11 header +* +* Returns: +* 0 on success, non-zero otherwise +* +* Call context: +* May be called in interrupt or non-interrupt context +----------------------------------------------------------------*/ +int skb_ether_to_p80211( wlandevice_t *wlandev, UINT32 ethconv, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep) +{ + + UINT16 fc; + UINT16 proto; + wlan_ethhdr_t e_hdr; + wlan_llc_t *e_llc; + wlan_snap_t *e_snap; + int foo; + + DBFENTER; + memcpy(&e_hdr, skb->data, sizeof(e_hdr)); + + if (skb->len <= 0) { + WLAN_LOG_DEBUG(1, "zero-length skb!\n"); + return 1; + } + + if ( ethconv == WLAN_ETHCONV_ENCAP ) { /* simplest case */ + WLAN_LOG_DEBUG(3, "ENCAP len: %d\n", skb->len); + /* here, we don't care what kind of ether frm. Just stick it */ + /* in the 80211 payload */ + /* which is to say, leave the skb alone. */ + } else { + /* step 1: classify ether frame, DIX or 802.3? */ + proto = ntohs(e_hdr.type); + if ( proto <= 1500 ) { + WLAN_LOG_DEBUG(3, "802.3 len: %d\n", skb->len); + /* codes <= 1500 reserved for 802.3 lengths */ + /* it's 802.3, pass ether payload unchanged, */ + + /* trim off ethernet header */ + skb_pull(skb, WLAN_ETHHDR_LEN); + + /* leave off any PAD octets. */ + skb_trim(skb, proto); + } else { + WLAN_LOG_DEBUG(3, "DIXII len: %d\n", skb->len); + /* it's DIXII, time for some conversion */ + + /* trim off ethernet header */ + skb_pull(skb, WLAN_ETHHDR_LEN); + + /* tack on SNAP */ + e_snap = (wlan_snap_t *) skb_push(skb, sizeof(wlan_snap_t)); + e_snap->type = htons(proto); + if ( ethconv == WLAN_ETHCONV_8021h && p80211_stt_findproto(proto) ) { + memcpy( e_snap->oui, oui_8021h, WLAN_IEEE_OUI_LEN); + } else { + memcpy( e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN); + } + + /* tack on llc */ + e_llc = (wlan_llc_t *) skb_push(skb, sizeof(wlan_llc_t)); + e_llc->dsap = 0xAA; /* SNAP, see IEEE 802 */ + e_llc->ssap = 0xAA; + e_llc->ctl = 0x03; + + } + } + + /* Set up the 802.11 header */ + /* It's a data frame */ + fc = host2ieee16( WLAN_SET_FC_FTYPE(WLAN_FTYPE_DATA) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DATAONLY)); + + switch ( wlandev->macmode ) { + case WLAN_MACMODE_IBSS_STA: + memcpy(p80211_hdr->a3.a1, &e_hdr.daddr, WLAN_ADDR_LEN); + memcpy(p80211_hdr->a3.a2, wlandev->netdev->dev_addr, WLAN_ADDR_LEN); + memcpy(p80211_hdr->a3.a3, wlandev->bssid, WLAN_ADDR_LEN); + break; + case WLAN_MACMODE_ESS_STA: + fc |= host2ieee16(WLAN_SET_FC_TODS(1)); + memcpy(p80211_hdr->a3.a1, wlandev->bssid, WLAN_ADDR_LEN); + memcpy(p80211_hdr->a3.a2, wlandev->netdev->dev_addr, WLAN_ADDR_LEN); + memcpy(p80211_hdr->a3.a3, &e_hdr.daddr, WLAN_ADDR_LEN); + break; + case WLAN_MACMODE_ESS_AP: + fc |= host2ieee16(WLAN_SET_FC_FROMDS(1)); + memcpy(p80211_hdr->a3.a1, &e_hdr.daddr, WLAN_ADDR_LEN); + memcpy(p80211_hdr->a3.a2, wlandev->bssid, WLAN_ADDR_LEN); + memcpy(p80211_hdr->a3.a3, &e_hdr.saddr, WLAN_ADDR_LEN); + break; + default: + WLAN_LOG_ERROR("Error: Converting eth to wlan in unknown mode.\n"); + return 1; + break; + } + + p80211_wep->data = NULL; + + if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) && (wlandev->hostwep & HOSTWEP_ENCRYPT)) { + // XXXX need to pick keynum other than default? + +#if 1 + p80211_wep->data = kmalloc(skb->len, GFP_ATOMIC); +#else + p80211_wep->data = skb->data; +#endif + + if ((foo = wep_encrypt(wlandev, skb->data, p80211_wep->data, + skb->len, + (wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK), + p80211_wep->iv, p80211_wep->icv))) { + WLAN_LOG_WARNING("Host en-WEP failed, dropping frame (%d).\n", foo); + return 2; + } + fc |= host2ieee16(WLAN_SET_FC_ISWEP(1)); + } + + + // skb->nh.raw = skb->data; + + p80211_hdr->a3.fc = fc; + p80211_hdr->a3.dur = 0; + p80211_hdr->a3.seq = 0; + + DBFEXIT; + return 0; +} + +/* jkriegl: from orinoco, modified */ +static void orinoco_spy_gather(wlandevice_t *wlandev, char *mac, + p80211_rxmeta_t *rxmeta) +{ + int i; + + /* Gather wireless spy statistics: for each packet, compare the + * source address with out list, and if match, get the stats... */ + + for (i = 0; i < wlandev->spy_number; i++) { + + if (!memcmp(wlandev->spy_address[i], mac, ETH_ALEN)) { + memcpy(wlandev->spy_address[i], mac, ETH_ALEN); + wlandev->spy_stat[i].level = rxmeta->signal; + wlandev->spy_stat[i].noise = rxmeta->noise; + wlandev->spy_stat[i].qual = (rxmeta->signal > rxmeta->noise) ? \ + (rxmeta->signal - rxmeta->noise) : 0; + wlandev->spy_stat[i].updated = 0x7; + } + } +} + +/*---------------------------------------------------------------- +* p80211pb_80211_to_ether +* +* Uses the contents of a received 802.11 frame and the etherconv +* setting to build an ether frame. +* +* This function extracts the src and dest address from the 802.11 +* frame to use in the construction of the eth frame. +* +* Arguments: +* ethconv Conversion type to perform +* skb Packet buffer containing the 802.11 frame +* +* Returns: +* 0 on success, non-zero otherwise +* +* Call context: +* May be called in interrupt or non-interrupt context +----------------------------------------------------------------*/ +int skb_p80211_to_ether( wlandevice_t *wlandev, UINT32 ethconv, struct sk_buff *skb) +{ + netdevice_t *netdev = wlandev->netdev; + UINT16 fc; + UINT payload_length; + UINT payload_offset; + UINT8 daddr[WLAN_ETHADDR_LEN]; + UINT8 saddr[WLAN_ETHADDR_LEN]; + p80211_hdr_t *w_hdr; + wlan_ethhdr_t *e_hdr; + wlan_llc_t *e_llc; + wlan_snap_t *e_snap; + + int foo; + + DBFENTER; + + payload_length = skb->len - WLAN_HDR_A3_LEN - WLAN_CRC_LEN; + payload_offset = WLAN_HDR_A3_LEN; + + w_hdr = (p80211_hdr_t *) skb->data; + + /* setup some vars for convenience */ + fc = ieee2host16(w_hdr->a3.fc); + if ( (WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 0) ) { + memcpy(daddr, w_hdr->a3.a1, WLAN_ETHADDR_LEN); + memcpy(saddr, w_hdr->a3.a2, WLAN_ETHADDR_LEN); + } else if( (WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 1) ) { + memcpy(daddr, w_hdr->a3.a1, WLAN_ETHADDR_LEN); + memcpy(saddr, w_hdr->a3.a3, WLAN_ETHADDR_LEN); + } else if( (WLAN_GET_FC_TODS(fc) == 1) && (WLAN_GET_FC_FROMDS(fc) == 0) ) { + memcpy(daddr, w_hdr->a3.a3, WLAN_ETHADDR_LEN); + memcpy(saddr, w_hdr->a3.a2, WLAN_ETHADDR_LEN); + } else { + payload_offset = WLAN_HDR_A4_LEN; + payload_length -= ( WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN ); + if (payload_length < 0 ) { + WLAN_LOG_ERROR("A4 frame too short!\n"); + return 1; + } + memcpy(daddr, w_hdr->a4.a3, WLAN_ETHADDR_LEN); + memcpy(saddr, w_hdr->a4.a4, WLAN_ETHADDR_LEN); + } + + /* perform de-wep if necessary.. */ + if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) && WLAN_GET_FC_ISWEP(fc) && (wlandev->hostwep & HOSTWEP_DECRYPT)) { + if (payload_length <= 8) { + WLAN_LOG_ERROR("WEP frame too short (%u).\n", + skb->len); + return 1; + } + if ((foo = wep_decrypt(wlandev, skb->data + payload_offset + 4, + payload_length - 8, -1, + skb->data + payload_offset, + skb->data + payload_offset + payload_length - 4))) { + /* de-wep failed, drop skb. */ + WLAN_LOG_DEBUG(1, "Host de-WEP failed, dropping frame (%d).\n", foo); + wlandev->rx.decrypt_err++; + return 2; + } + + /* subtract the IV+ICV length off the payload */ + payload_length -= 8; + /* chop off the IV */ + skb_pull(skb, 4); + /* chop off the ICV. */ + skb_trim(skb, skb->len - 4); + + wlandev->rx.decrypt++; + } + + e_hdr = (wlan_ethhdr_t *) (skb->data + payload_offset); + + e_llc = (wlan_llc_t *) (skb->data + payload_offset); + e_snap = (wlan_snap_t *) (skb->data + payload_offset + sizeof(wlan_llc_t)); + + /* Test for the various encodings */ + if ( (payload_length >= sizeof(wlan_ethhdr_t)) && + ( e_llc->dsap != 0xaa || e_llc->ssap != 0xaa ) && + ((memcmp(daddr, e_hdr->daddr, WLAN_ETHADDR_LEN) == 0) || + (memcmp(saddr, e_hdr->saddr, WLAN_ETHADDR_LEN) == 0))) { + WLAN_LOG_DEBUG(3, "802.3 ENCAP len: %d\n", payload_length); + /* 802.3 Encapsulated */ + /* Test for an overlength frame */ + if ( payload_length > (netdev->mtu + WLAN_ETHHDR_LEN)) { + /* A bogus length ethfrm has been encap'd. */ + /* Is someone trying an oflow attack? */ + WLAN_LOG_ERROR("ENCAP frame too large (%d > %d)\n", + payload_length, netdev->mtu + WLAN_ETHHDR_LEN); + return 1; + } + + /* Chop off the 802.11 header. it's already sane. */ + skb_pull(skb, payload_offset); + /* chop off the 802.11 CRC */ + skb_trim(skb, skb->len - WLAN_CRC_LEN); + + } else if ((payload_length >= sizeof(wlan_llc_t) + sizeof(wlan_snap_t)) && + (e_llc->dsap == 0xaa) && + (e_llc->ssap == 0xaa) && + (e_llc->ctl == 0x03) && + (((memcmp( e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN)==0) && + (ethconv == WLAN_ETHCONV_8021h) && + (p80211_stt_findproto(ieee2host16(e_snap->type)))) || + (memcmp( e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN)!=0))) + { + WLAN_LOG_DEBUG(3, "SNAP+RFC1042 len: %d\n", payload_length); + /* it's a SNAP + RFC1042 frame && protocol is in STT */ + /* build 802.3 + RFC1042 */ + + /* Test for an overlength frame */ + if ( payload_length > netdev->mtu ) { + /* A bogus length ethfrm has been sent. */ + /* Is someone trying an oflow attack? */ + WLAN_LOG_ERROR("SNAP frame too large (%d > %d)\n", + payload_length, netdev->mtu); + return 1; + } + + /* chop 802.11 header from skb. */ + skb_pull(skb, payload_offset); + + /* create 802.3 header at beginning of skb. */ + e_hdr = (wlan_ethhdr_t *) skb_push(skb, WLAN_ETHHDR_LEN); + memcpy(e_hdr->daddr, daddr, WLAN_ETHADDR_LEN); + memcpy(e_hdr->saddr, saddr, WLAN_ETHADDR_LEN); + e_hdr->type = htons(payload_length); + + /* chop off the 802.11 CRC */ + skb_trim(skb, skb->len - WLAN_CRC_LEN); + + } else if ((payload_length >= sizeof(wlan_llc_t) + sizeof(wlan_snap_t)) && + (e_llc->dsap == 0xaa) && + (e_llc->ssap == 0xaa) && + (e_llc->ctl == 0x03) ) { + WLAN_LOG_DEBUG(3, "802.1h/RFC1042 len: %d\n", payload_length); + /* it's an 802.1h frame || (an RFC1042 && protocol is not in STT) */ + /* build a DIXII + RFC894 */ + + /* Test for an overlength frame */ + if ((payload_length - sizeof(wlan_llc_t) - sizeof(wlan_snap_t)) + > netdev->mtu) { + /* A bogus length ethfrm has been sent. */ + /* Is someone trying an oflow attack? */ + WLAN_LOG_ERROR("DIXII frame too large (%ld > %d)\n", + (long int) (payload_length - sizeof(wlan_llc_t) - + sizeof(wlan_snap_t)), + netdev->mtu); + return 1; + } + + /* chop 802.11 header from skb. */ + skb_pull(skb, payload_offset); + + /* chop llc header from skb. */ + skb_pull(skb, sizeof(wlan_llc_t)); + + /* chop snap header from skb. */ + skb_pull(skb, sizeof(wlan_snap_t)); + + /* create 802.3 header at beginning of skb. */ + e_hdr = (wlan_ethhdr_t *) skb_push(skb, WLAN_ETHHDR_LEN); + e_hdr->type = e_snap->type; + memcpy(e_hdr->daddr, daddr, WLAN_ETHADDR_LEN); + memcpy(e_hdr->saddr, saddr, WLAN_ETHADDR_LEN); + + /* chop off the 802.11 CRC */ + skb_trim(skb, skb->len - WLAN_CRC_LEN); + } else { + WLAN_LOG_DEBUG(3, "NON-ENCAP len: %d\n", payload_length); + /* any NON-ENCAP */ + /* it's a generic 80211+LLC or IPX 'Raw 802.3' */ + /* build an 802.3 frame */ + /* allocate space and setup hostbuf */ + + /* Test for an overlength frame */ + if ( payload_length > netdev->mtu ) { + /* A bogus length ethfrm has been sent. */ + /* Is someone trying an oflow attack? */ + WLAN_LOG_ERROR("OTHER frame too large (%d > %d)\n", + payload_length, + netdev->mtu); + return 1; + } + + /* Chop off the 802.11 header. */ + skb_pull(skb, payload_offset); + + /* create 802.3 header at beginning of skb. */ + e_hdr = (wlan_ethhdr_t *) skb_push(skb, WLAN_ETHHDR_LEN); + memcpy(e_hdr->daddr, daddr, WLAN_ETHADDR_LEN); + memcpy(e_hdr->saddr, saddr, WLAN_ETHADDR_LEN); + e_hdr->type = htons(payload_length); + + /* chop off the 802.11 CRC */ + skb_trim(skb, skb->len - WLAN_CRC_LEN); + + } + + /* + * Note that eth_type_trans() expects an skb w/ skb->data pointing + * at the MAC header, it then sets the following skb members: + * skb->mac_header, + * skb->data, and + * skb->pkt_type. + * It then _returns_ the value that _we're_ supposed to stuff in + * skb->protocol. This is nuts. + */ + skb->protocol = eth_type_trans(skb, netdev); + + /* jkriegl: process signal and noise as set in hfa384x_int_rx() */ + /* jkriegl: only process signal/noise if requested by iwspy */ + if (wlandev->spy_number) + orinoco_spy_gather(wlandev, eth_hdr(skb)->h_source, P80211SKB_RXMETA(skb)); + + /* Free the metadata */ + p80211skb_rxmeta_detach(skb); + + DBFEXIT; + return 0; +} + +/*---------------------------------------------------------------- +* p80211_stt_findproto +* +* Searches the 802.1h Selective Translation Table for a given +* protocol. +* +* Arguments: +* proto protocl number (in host order) to search for. +* +* Returns: +* 1 - if the table is empty or a match is found. +* 0 - if the table is non-empty and a match is not found. +* +* Call context: +* May be called in interrupt or non-interrupt context +----------------------------------------------------------------*/ +int p80211_stt_findproto(UINT16 proto) +{ + /* Always return found for now. This is the behavior used by the */ + /* Zoom Win95 driver when 802.1h mode is selected */ + /* TODO: If necessary, add an actual search we'll probably + need this to match the CMAC's way of doing things. + Need to do some testing to confirm. + */ + + if (proto == 0x80f3) /* APPLETALK */ + return 1; + + return 0; +} + +/*---------------------------------------------------------------- +* p80211skb_rxmeta_detach +* +* Disconnects the frmmeta and rxmeta from an skb. +* +* Arguments: +* wlandev The wlandev this skb belongs to. +* skb The skb we're attaching to. +* +* Returns: +* 0 on success, non-zero otherwise +* +* Call context: +* May be called in interrupt or non-interrupt context +----------------------------------------------------------------*/ +void +p80211skb_rxmeta_detach(struct sk_buff *skb) +{ + p80211_rxmeta_t *rxmeta; + p80211_frmmeta_t *frmmeta; + + DBFENTER; + /* Sanity checks */ + if ( skb==NULL ) { /* bad skb */ + WLAN_LOG_DEBUG(1, "Called w/ null skb.\n"); + goto exit; + } + frmmeta = P80211SKB_FRMMETA(skb); + if ( frmmeta == NULL ) { /* no magic */ + WLAN_LOG_DEBUG(1, "Called w/ bad frmmeta magic.\n"); + goto exit; + } + rxmeta = frmmeta->rx; + if ( rxmeta == NULL ) { /* bad meta ptr */ + WLAN_LOG_DEBUG(1, "Called w/ bad rxmeta ptr.\n"); + goto exit; + } + + /* Free rxmeta */ + kfree(rxmeta); + + /* Clear skb->cb */ + memset(skb->cb, 0, sizeof(skb->cb)); +exit: + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* p80211skb_rxmeta_attach +* +* Allocates a p80211rxmeta structure, initializes it, and attaches +* it to an skb. +* +* Arguments: +* wlandev The wlandev this skb belongs to. +* skb The skb we're attaching to. +* +* Returns: +* 0 on success, non-zero otherwise +* +* Call context: +* May be called in interrupt or non-interrupt context +----------------------------------------------------------------*/ +int +p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb) +{ + int result = 0; + p80211_rxmeta_t *rxmeta; + p80211_frmmeta_t *frmmeta; + + DBFENTER; + + /* If these already have metadata, we error out! */ + if (P80211SKB_RXMETA(skb) != NULL) { + WLAN_LOG_ERROR("%s: RXmeta already attached!\n", + wlandev->name); + result = 0; + goto exit; + } + + /* Allocate the rxmeta */ + rxmeta = kmalloc(sizeof(p80211_rxmeta_t), GFP_ATOMIC); + + if ( rxmeta == NULL ) { + WLAN_LOG_ERROR("%s: Failed to allocate rxmeta.\n", + wlandev->name); + result = 1; + goto exit; + } + + /* Initialize the rxmeta */ + memset(rxmeta, 0, sizeof(p80211_rxmeta_t)); + rxmeta->wlandev = wlandev; + rxmeta->hosttime = jiffies; + + /* Overlay a frmmeta_t onto skb->cb */ + memset(skb->cb, 0, sizeof(p80211_frmmeta_t)); + frmmeta = (p80211_frmmeta_t*)(skb->cb); + frmmeta->magic = P80211_FRMMETA_MAGIC; + frmmeta->rx = rxmeta; +exit: + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* p80211skb_free +* +* Frees an entire p80211skb by checking and freeing the meta struct +* and then freeing the skb. +* +* Arguments: +* wlandev The wlandev this skb belongs to. +* skb The skb we're attaching to. +* +* Returns: +* 0 on success, non-zero otherwise +* +* Call context: +* May be called in interrupt or non-interrupt context +----------------------------------------------------------------*/ +void +p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb) +{ + p80211_frmmeta_t *meta; + DBFENTER; + meta = P80211SKB_FRMMETA(skb); + if ( meta && meta->rx) { + p80211skb_rxmeta_detach(skb); + } else { + WLAN_LOG_ERROR("Freeing an skb (%p) w/ no frmmeta.\n", skb); + } + + dev_kfree_skb(skb); + DBFEXIT; + return; +} --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211ioctl.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211ioctl.h @@ -0,0 +1,123 @@ +/* src/include/wlan/p80211ioctl.h +* +* Declares constants and types for the p80211 ioctls +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* While this file is called 'ioctl' is purpose goes a little beyond +* that. This file defines the types and contants used to implement +* the p80211 request/confirm/indicate interfaces on Linux. The +* request/confirm interface is, in fact, normally implemented as an +* ioctl. The indicate interface on the other hand, is implemented +* using the Linux 'netlink' interface. +* +* The reason I say that request/confirm is 'normally' implemented +* via ioctl is that we're reserving the right to be able to send +* request commands via the netlink interface. This will be necessary +* if we ever need to send request messages when there aren't any +* wlan network devices present (i.e. sending a message that only p80211 +* cares about. +* -------------------------------------------------------------------- +*/ + + +#ifndef _P80211IOCTL_H +#define _P80211IOCTL_H + +/*================================================================*/ +/* Constants */ + +/*----------------------------------------------------------------*/ +/* p80211 ioctl "request" codes. See argument 2 of ioctl(2). */ + +#define P80211_IFTEST (SIOCDEVPRIVATE + 0) +#define P80211_IFREQ (SIOCDEVPRIVATE + 1) + +/*----------------------------------------------------------------*/ +/* Magic number, a quick test to see we're getting the desired struct */ + +#define P80211_IOCTL_MAGIC (0x4a2d464dUL) + +/*----------------------------------------------------------------*/ +/* Netlink protocol numbers for the indication interface */ + +#define P80211_NL_SOCK_IND NETLINK_USERSOCK + +/*----------------------------------------------------------------*/ +/* Netlink multicast bits for different types of messages */ + +#define P80211_NL_MCAST_GRP_MLME BIT0 /* Local station messages */ +#define P80211_NL_MCAST_GRP_SNIFF BIT1 /* Sniffer messages */ +#define P80211_NL_MCAST_GRP_DIST BIT2 /* Distribution system messages */ + +/*================================================================*/ +/* Macros */ + + +/*================================================================*/ +/* Types */ + +/*----------------------------------------------------------------*/ +/* A ptr to the following structure type is passed as the third */ +/* argument to the ioctl system call when issuing a request to */ +/* the p80211 module. */ + +typedef struct p80211ioctl_req +{ + char name[WLAN_DEVNAMELEN_MAX]; + caddr_t data; + UINT32 magic; + UINT16 len; + UINT32 result; +} __WLAN_ATTRIB_PACK__ p80211ioctl_req_t; + + +/*================================================================*/ +/* Extern Declarations */ + + +/*================================================================*/ +/* Function Declarations */ + + +#endif /* _P80211IOCTL_H */ --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211msg.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211msg.h @@ -0,0 +1,102 @@ +/* src/include/wlan/p80211msg.h +* +* Macros, constants, types, and funcs for req and ind messages +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +*/ + +#ifndef _P80211MSG_H +#define _P80211MSG_H + +/*================================================================*/ +/* System Includes */ + +/*================================================================*/ +/* Project Includes */ + +#ifndef _WLAN_COMPAT_H +#include +#endif + +/*================================================================*/ +/* Constants */ + +#define MSG_BUFF_LEN 4000 +#define WLAN_DEVNAMELEN_MAX 16 + +/*================================================================*/ +/* Macros */ + +/*================================================================*/ +/* Types */ + +/*--------------------------------------------------------------------*/ +/*----- Message Structure Types --------------------------------------*/ + +/*--------------------------------------------------------------------*/ +/* Prototype msg type */ + +typedef struct p80211msg +{ + UINT32 msgcode; + UINT32 msglen; + UINT8 devname[WLAN_DEVNAMELEN_MAX]; +} __WLAN_ATTRIB_PACK__ p80211msg_t; + +typedef struct p80211msgd +{ + UINT32 msgcode; + UINT32 msglen; + UINT8 devname[WLAN_DEVNAMELEN_MAX]; + UINT8 args[0]; +} __WLAN_ATTRIB_PACK__ p80211msgd_t; + +/*================================================================*/ +/* Extern Declarations */ + + +/*================================================================*/ +/* Function Declarations */ + +#endif /* _P80211MSG_H */ + --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211req.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211req.h @@ -0,0 +1,68 @@ +/* src/include/wlan/p80211req.h +* +* Request handling functions +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +*/ + +#ifndef _LINUX_P80211REQ_H +#define _LINUX_P80211REQ_H + +/*================================================================*/ +/* Constants */ + +/*================================================================*/ +/* Macros */ + +/*================================================================*/ +/* Types */ + +/*================================================================*/ +/* Externs */ + +/*================================================================*/ +/* Function Declarations */ + +int p80211req_dorequest(wlandevice_t *wlandev, UINT8 *msgbuf); + +#endif --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211metastruct.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211metastruct.h @@ -0,0 +1,644 @@ +/* This file is GENERATED AUTOMATICALLY. DO NOT EDIT OR MODIFY. +* -------------------------------------------------------------------- +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +*/ + +#ifndef _P80211MKMETASTRUCT_H +#define _P80211MKMETASTRUCT_H + + +typedef struct p80211msg_dot11req_mibget +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_unk392_t mibattribute ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_mibget_t; + +typedef struct p80211msg_dot11req_mibset +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_unk392_t mibattribute ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_mibset_t; + +typedef struct p80211msg_dot11req_powermgmt +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t powermgmtmode ; + p80211item_uint32_t wakeup ; + p80211item_uint32_t receivedtims ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_powermgmt_t; + +typedef struct p80211msg_dot11req_scan +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t bsstype ; + p80211item_pstr6_t bssid ; + UINT8 pad_0C[1] ; + p80211item_pstr32_t ssid ; + UINT8 pad_1D[3] ; + p80211item_uint32_t scantype ; + p80211item_uint32_t probedelay ; + p80211item_pstr14_t channellist ; + UINT8 pad_2C[1] ; + p80211item_uint32_t minchanneltime ; + p80211item_uint32_t maxchanneltime ; + p80211item_uint32_t resultcode ; + p80211item_uint32_t numbss ; + p80211item_uint32_t append ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_scan_t; + +typedef struct p80211msg_dot11req_scan_results +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t bssindex ; + p80211item_uint32_t resultcode ; + p80211item_uint32_t signal ; + p80211item_uint32_t noise ; + p80211item_pstr6_t bssid ; + UINT8 pad_3C[1] ; + p80211item_pstr32_t ssid ; + UINT8 pad_4D[3] ; + p80211item_uint32_t bsstype ; + p80211item_uint32_t beaconperiod ; + p80211item_uint32_t dtimperiod ; + p80211item_uint32_t timestamp ; + p80211item_uint32_t localtime ; + p80211item_uint32_t fhdwelltime ; + p80211item_uint32_t fhhopset ; + p80211item_uint32_t fhhoppattern ; + p80211item_uint32_t fhhopindex ; + p80211item_uint32_t dschannel ; + p80211item_uint32_t cfpcount ; + p80211item_uint32_t cfpperiod ; + p80211item_uint32_t cfpmaxduration ; + p80211item_uint32_t cfpdurremaining ; + p80211item_uint32_t ibssatimwindow ; + p80211item_uint32_t cfpollable ; + p80211item_uint32_t cfpollreq ; + p80211item_uint32_t privacy ; + p80211item_uint32_t basicrate1 ; + p80211item_uint32_t basicrate2 ; + p80211item_uint32_t basicrate3 ; + p80211item_uint32_t basicrate4 ; + p80211item_uint32_t basicrate5 ; + p80211item_uint32_t basicrate6 ; + p80211item_uint32_t basicrate7 ; + p80211item_uint32_t basicrate8 ; + p80211item_uint32_t supprate1 ; + p80211item_uint32_t supprate2 ; + p80211item_uint32_t supprate3 ; + p80211item_uint32_t supprate4 ; + p80211item_uint32_t supprate5 ; + p80211item_uint32_t supprate6 ; + p80211item_uint32_t supprate7 ; + p80211item_uint32_t supprate8 ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_scan_results_t; + +typedef struct p80211msg_dot11req_join +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr6_t bssid ; + UINT8 pad_5C[1] ; + p80211item_uint32_t joinfailuretimeout ; + p80211item_uint32_t basicrate1 ; + p80211item_uint32_t basicrate2 ; + p80211item_uint32_t basicrate3 ; + p80211item_uint32_t basicrate4 ; + p80211item_uint32_t basicrate5 ; + p80211item_uint32_t basicrate6 ; + p80211item_uint32_t basicrate7 ; + p80211item_uint32_t basicrate8 ; + p80211item_uint32_t operationalrate1 ; + p80211item_uint32_t operationalrate2 ; + p80211item_uint32_t operationalrate3 ; + p80211item_uint32_t operationalrate4 ; + p80211item_uint32_t operationalrate5 ; + p80211item_uint32_t operationalrate6 ; + p80211item_uint32_t operationalrate7 ; + p80211item_uint32_t operationalrate8 ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_join_t; + +typedef struct p80211msg_dot11req_authenticate +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr6_t peerstaaddress ; + UINT8 pad_6C[1] ; + p80211item_uint32_t authenticationtype ; + p80211item_uint32_t authenticationfailuretimeout ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_authenticate_t; + +typedef struct p80211msg_dot11req_deauthenticate +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr6_t peerstaaddress ; + UINT8 pad_7C[1] ; + p80211item_uint32_t reasoncode ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_deauthenticate_t; + +typedef struct p80211msg_dot11req_associate +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr6_t peerstaaddress ; + UINT8 pad_8C[1] ; + p80211item_uint32_t associatefailuretimeout ; + p80211item_uint32_t cfpollable ; + p80211item_uint32_t cfpollreq ; + p80211item_uint32_t privacy ; + p80211item_uint32_t listeninterval ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_associate_t; + +typedef struct p80211msg_dot11req_reassociate +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr6_t newapaddress ; + UINT8 pad_9C[1] ; + p80211item_uint32_t reassociatefailuretimeout ; + p80211item_uint32_t cfpollable ; + p80211item_uint32_t cfpollreq ; + p80211item_uint32_t privacy ; + p80211item_uint32_t listeninterval ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_reassociate_t; + +typedef struct p80211msg_dot11req_disassociate +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr6_t peerstaaddress ; + UINT8 pad_10C[1] ; + p80211item_uint32_t reasoncode ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_disassociate_t; + +typedef struct p80211msg_dot11req_reset +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t setdefaultmib ; + p80211item_pstr6_t macaddress ; + UINT8 pad_11C[1] ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_reset_t; + +typedef struct p80211msg_dot11req_start +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr32_t ssid ; + UINT8 pad_12D[3] ; + p80211item_uint32_t bsstype ; + p80211item_uint32_t beaconperiod ; + p80211item_uint32_t dtimperiod ; + p80211item_uint32_t cfpperiod ; + p80211item_uint32_t cfpmaxduration ; + p80211item_uint32_t fhdwelltime ; + p80211item_uint32_t fhhopset ; + p80211item_uint32_t fhhoppattern ; + p80211item_uint32_t dschannel ; + p80211item_uint32_t ibssatimwindow ; + p80211item_uint32_t probedelay ; + p80211item_uint32_t cfpollable ; + p80211item_uint32_t cfpollreq ; + p80211item_uint32_t basicrate1 ; + p80211item_uint32_t basicrate2 ; + p80211item_uint32_t basicrate3 ; + p80211item_uint32_t basicrate4 ; + p80211item_uint32_t basicrate5 ; + p80211item_uint32_t basicrate6 ; + p80211item_uint32_t basicrate7 ; + p80211item_uint32_t basicrate8 ; + p80211item_uint32_t operationalrate1 ; + p80211item_uint32_t operationalrate2 ; + p80211item_uint32_t operationalrate3 ; + p80211item_uint32_t operationalrate4 ; + p80211item_uint32_t operationalrate5 ; + p80211item_uint32_t operationalrate6 ; + p80211item_uint32_t operationalrate7 ; + p80211item_uint32_t operationalrate8 ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_start_t; + +typedef struct p80211msg_dot11ind_authenticate +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr6_t peerstaaddress ; + UINT8 pad_13C[1] ; + p80211item_uint32_t authenticationtype ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11ind_authenticate_t; + +typedef struct p80211msg_dot11ind_deauthenticate +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr6_t peerstaaddress ; + UINT8 pad_14C[1] ; + p80211item_uint32_t reasoncode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11ind_deauthenticate_t; + +typedef struct p80211msg_dot11ind_associate +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr6_t peerstaaddress ; + UINT8 pad_15C[1] ; + p80211item_uint32_t aid ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11ind_associate_t; + +typedef struct p80211msg_dot11ind_reassociate +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr6_t peerstaaddress ; + UINT8 pad_16C[1] ; + p80211item_uint32_t aid ; + p80211item_pstr6_t oldapaddress ; + UINT8 pad_17C[1] ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11ind_reassociate_t; + +typedef struct p80211msg_dot11ind_disassociate +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr6_t peerstaaddress ; + UINT8 pad_18C[1] ; + p80211item_uint32_t reasoncode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11ind_disassociate_t; + +typedef struct p80211msg_lnxreq_ifstate +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t ifstate ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_ifstate_t; + +typedef struct p80211msg_lnxreq_wlansniff +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t enable ; + p80211item_uint32_t channel ; + p80211item_uint32_t prismheader ; + p80211item_uint32_t wlanheader ; + p80211item_uint32_t keepwepflags ; + p80211item_uint32_t stripfcs ; + p80211item_uint32_t packet_trunc ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_wlansniff_t; + +typedef struct p80211msg_lnxreq_hostwep +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t resultcode ; + p80211item_uint32_t decrypt ; + p80211item_uint32_t encrypt ; +} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_hostwep_t; + +typedef struct p80211msg_lnxreq_commsquality +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t resultcode ; + p80211item_uint32_t dbm ; + p80211item_uint32_t link ; + p80211item_uint32_t level ; + p80211item_uint32_t noise ; +} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_commsquality_t; + +typedef struct p80211msg_lnxreq_autojoin +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr32_t ssid ; + UINT8 pad_19D[3] ; + p80211item_uint32_t authtype ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_autojoin_t; + +typedef struct p80211msg_lnxind_wlansniffrm +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t hosttime ; + p80211item_uint32_t mactime ; + p80211item_uint32_t channel ; + p80211item_uint32_t rssi ; + p80211item_uint32_t sq ; + p80211item_uint32_t signal ; + p80211item_uint32_t noise ; + p80211item_uint32_t rate ; + p80211item_uint32_t istx ; + p80211item_uint32_t frmlen ; +} __WLAN_ATTRIB_PACK__ p80211msg_lnxind_wlansniffrm_t; + +typedef struct p80211msg_lnxind_roam +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t reason ; +} __WLAN_ATTRIB_PACK__ p80211msg_lnxind_roam_t; + +typedef struct p80211msg_p2req_join +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr6_t bssid ; + UINT8 pad_20C[1] ; + p80211item_uint32_t basicrate1 ; + p80211item_uint32_t basicrate2 ; + p80211item_uint32_t basicrate3 ; + p80211item_uint32_t basicrate4 ; + p80211item_uint32_t basicrate5 ; + p80211item_uint32_t basicrate6 ; + p80211item_uint32_t basicrate7 ; + p80211item_uint32_t basicrate8 ; + p80211item_uint32_t operationalrate1 ; + p80211item_uint32_t operationalrate2 ; + p80211item_uint32_t operationalrate3 ; + p80211item_uint32_t operationalrate4 ; + p80211item_uint32_t operationalrate5 ; + p80211item_uint32_t operationalrate6 ; + p80211item_uint32_t operationalrate7 ; + p80211item_uint32_t operationalrate8 ; + p80211item_pstr32_t ssid ; + UINT8 pad_21D[3] ; + p80211item_uint32_t channel ; + p80211item_uint32_t authtype ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_join_t; + +typedef struct p80211msg_p2req_readpda +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_unk1024_t pda ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_readpda_t; + +typedef struct p80211msg_p2req_readcis +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_unk1024_t cis ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_readcis_t; + +typedef struct p80211msg_p2req_auxport_state +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t enable ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_auxport_state_t; + +typedef struct p80211msg_p2req_auxport_read +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t addr ; + p80211item_uint32_t len ; + p80211item_unk1024_t data ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_auxport_read_t; + +typedef struct p80211msg_p2req_auxport_write +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t addr ; + p80211item_uint32_t len ; + p80211item_unk1024_t data ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_auxport_write_t; + +typedef struct p80211msg_p2req_low_level +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t command ; + p80211item_uint32_t param0 ; + p80211item_uint32_t param1 ; + p80211item_uint32_t param2 ; + p80211item_uint32_t resp0 ; + p80211item_uint32_t resp1 ; + p80211item_uint32_t resp2 ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_low_level_t; + +typedef struct p80211msg_p2req_test_command +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t testcode ; + p80211item_uint32_t testparam ; + p80211item_uint32_t resultcode ; + p80211item_uint32_t status ; + p80211item_uint32_t resp0 ; + p80211item_uint32_t resp1 ; + p80211item_uint32_t resp2 ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_test_command_t; + +typedef struct p80211msg_p2req_mmi_read +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t addr ; + p80211item_uint32_t value ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_mmi_read_t; + +typedef struct p80211msg_p2req_mmi_write +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t addr ; + p80211item_uint32_t data ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_mmi_write_t; + +typedef struct p80211msg_p2req_ramdl_state +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t enable ; + p80211item_uint32_t exeaddr ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_ramdl_state_t; + +typedef struct p80211msg_p2req_ramdl_write +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t addr ; + p80211item_uint32_t len ; + p80211item_unk4096_t data ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_ramdl_write_t; + +typedef struct p80211msg_p2req_flashdl_state +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t enable ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_flashdl_state_t; + +typedef struct p80211msg_p2req_flashdl_write +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t addr ; + p80211item_uint32_t len ; + p80211item_unk4096_t data ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_flashdl_write_t; + +typedef struct p80211msg_p2req_mm_state +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t enable ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_mm_state_t; + +typedef struct p80211msg_p2req_dump_state +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t level ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_dump_state_t; + +typedef struct p80211msg_p2req_channel_info +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t channellist ; + p80211item_uint32_t channeldwelltime ; + p80211item_uint32_t resultcode ; + p80211item_uint32_t numchinfo ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_channel_info_t; + +typedef struct p80211msg_p2req_channel_info_results +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t channel ; + p80211item_uint32_t resultcode ; + p80211item_uint32_t avgnoiselevel ; + p80211item_uint32_t peaknoiselevel ; + p80211item_uint32_t bssactive ; + p80211item_uint32_t pcfactive ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_channel_info_results_t; + +typedef struct p80211msg_p2req_enable +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_enable_t; + +#endif --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211metamib.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211metamib.h @@ -0,0 +1,105 @@ +/* src/include/wlan/p80211metamib.h +* +* Macros, const, types, and funcs for p80211 mib metadata +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file declares some of the constants and types used in various +* parts of the linux-wlan system. +* +* Notes: +* - Constant values are always in HOST byte order. +* +* All functions and statics declared here are implemented in p80211types.c +* -------------------------------------------------------------------- +*/ + +#ifndef _P80211METAMIB_H +#define _P80211METAMIB_H + +/*================================================================*/ +/* System Includes */ + +/*================================================================*/ +/* Project Includes */ + +#ifndef _WLAN_COMPAT_H +#include +#endif + +/*================================================================*/ +/* Constants */ + +/*----------------------------------------------------------------*/ +/* */ + +/*================================================================*/ +/* Macros */ + +/*----------------------------------------------------------------*/ +/* */ + +/*================================================================*/ +/* Types */ + +/*----------------------------------------------------------------*/ +/* */ + +/*================================================================*/ +/* Extern Declarations */ + +/*----------------------------------------------------------------*/ +/* The following is the external declaration for the mib */ +/* category metadata list */ + +extern catlistitem_t mib_catlist[]; +extern UINT32 mib_catlist_size; + + +/*================================================================*/ +/* Function Declarations */ + +/*----------------------------------------------------------------*/ +/* */ + +#endif /* _P80211METAMIB_H */ --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211mgmt.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211mgmt.h @@ -0,0 +1,575 @@ +/* src/include/wlan/p80211mgmt.h +* +* Macros, types, and functions to handle 802.11 mgmt frames +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file declares the constants and types used in the interface +* between a wlan driver and the user mode utilities. +* +* Notes: +* - Constant values are always in HOST byte order. To assign +* values to multi-byte fields they _must_ be converted to +* ieee byte order. To retrieve multi-byte values from incoming +* frames, they must be converted to host order. +* +* - The len member of the frame structure does NOT!!! include +* the MAC CRC. Therefore, the len field on rx'd frames should +* have 4 subtracted from it. +* +* All functions declared here are implemented in p80211.c +* +* The types, macros, and functions defined here are primarily +* used for encoding and decoding management frames. They are +* designed to follow these patterns of use: +* +* DECODE: +* 1) a frame of length len is received into buffer b +* 2) using the hdr structure and macros, we determine the type +* 3) an appropriate mgmt frame structure, mf, is allocated and zeroed +* 4) mf.hdr = b +* mf.buf = b +* mf.len = len +* 5) call mgmt_decode( mf ) +* 6) the frame field pointers in mf are now set. Note that any +* multi-byte frame field values accessed using the frame field +* pointers are in ieee byte order and will have to be converted +* to host order. +* +* ENCODE: +* 1) Library client allocates buffer space for maximum length +* frame of the desired type +* 2) Library client allocates a mgmt frame structure, called mf, +* of the desired type +* 3) Set the following: +* mf.type = +* mf.buf = +* 4) call mgmt_encode( mf ) +* 5) all of the fixed field pointers and fixed length information element +* pointers in mf are now set to their respective locations in the +* allocated space (fortunately, all variable length information elements +* fall at the end of their respective frames). +* 5a) The length field is set to include the last of the fixed and fixed +* length fields. It may have to be updated for optional or variable +* length information elements. +* 6) Optional and variable length information elements are special cases +* and must be handled individually by the client code. +* -------------------------------------------------------------------- +*/ + +#ifndef _P80211MGMT_H +#define _P80211MGMT_H + +/*================================================================*/ +/* System Includes */ + +/*================================================================*/ +/* Project Includes */ + +#ifndef _WLAN_COMPAT_H +#include +#endif + +#ifndef _P80211HDR_H +#include +#endif + + +/*================================================================*/ +/* Constants */ + +/*-- Information Element IDs --------------------*/ +#define WLAN_EID_SSID 0 +#define WLAN_EID_SUPP_RATES 1 +#define WLAN_EID_FH_PARMS 2 +#define WLAN_EID_DS_PARMS 3 +#define WLAN_EID_CF_PARMS 4 +#define WLAN_EID_TIM 5 +#define WLAN_EID_IBSS_PARMS 6 +/*-- values 7-15 reserved --*/ +#define WLAN_EID_CHALLENGE 16 +/*-- values 17-31 reserved for challenge text extension --*/ +/*-- values 32-255 reserved --*/ + +/*-- Reason Codes -------------------------------*/ +#define WLAN_MGMT_REASON_RSVD 0 +#define WLAN_MGMT_REASON_UNSPEC 1 +#define WLAN_MGMT_REASON_PRIOR_AUTH_INVALID 2 +#define WLAN_MGMT_REASON_DEAUTH_LEAVING 3 +#define WLAN_MGMT_REASON_DISASSOC_INACTIVE 4 +#define WLAN_MGMT_REASON_DISASSOC_AP_BUSY 5 +#define WLAN_MGMT_REASON_CLASS2_NONAUTH 6 +#define WLAN_MGMT_REASON_CLASS3_NONASSOC 7 +#define WLAN_MGMT_REASON_DISASSOC_STA_HASLEFT 8 +#define WLAN_MGMT_REASON_CANT_ASSOC_NONAUTH 9 + +/*-- Status Codes -------------------------------*/ +#define WLAN_MGMT_STATUS_SUCCESS 0 +#define WLAN_MGMT_STATUS_UNSPEC_FAILURE 1 +#define WLAN_MGMT_STATUS_CAPS_UNSUPPORTED 10 +#define WLAN_MGMT_STATUS_REASSOC_NO_ASSOC 11 +#define WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC 12 +#define WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG 13 +#define WLAN_MGMT_STATUS_RX_AUTH_NOSEQ 14 +#define WLAN_MGMT_STATUS_CHALLENGE_FAIL 15 +#define WLAN_MGMT_STATUS_AUTH_TIMEOUT 16 +#define WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY 17 +#define WLAN_MGMT_STATUS_ASSOC_DENIED_RATES 18 + /* p80211b additions */ +#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOSHORT 19 +#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOPBCC 20 +#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOAGILITY 21 + + + +/*-- Auth Algorithm Field ---------------------------*/ +#define WLAN_AUTH_ALG_OPENSYSTEM 0 +#define WLAN_AUTH_ALG_SHAREDKEY 1 + +/*-- Management Frame Field Offsets -------------*/ +/* Note: Not all fields are listed because of variable lengths, */ +/* see the code in p80211.c to see how we search for fields */ +/* Note: These offsets are from the start of the frame data */ + +#define WLAN_BEACON_OFF_TS 0 +#define WLAN_BEACON_OFF_BCN_INT 8 +#define WLAN_BEACON_OFF_CAPINFO 10 +#define WLAN_BEACON_OFF_SSID 12 + +#define WLAN_DISASSOC_OFF_REASON 0 + +#define WLAN_ASSOCREQ_OFF_CAP_INFO 0 +#define WLAN_ASSOCREQ_OFF_LISTEN_INT 2 +#define WLAN_ASSOCREQ_OFF_SSID 4 + +#define WLAN_ASSOCRESP_OFF_CAP_INFO 0 +#define WLAN_ASSOCRESP_OFF_STATUS 2 +#define WLAN_ASSOCRESP_OFF_AID 4 +#define WLAN_ASSOCRESP_OFF_SUPP_RATES 6 + +#define WLAN_REASSOCREQ_OFF_CAP_INFO 0 +#define WLAN_REASSOCREQ_OFF_LISTEN_INT 2 +#define WLAN_REASSOCREQ_OFF_CURR_AP 4 +#define WLAN_REASSOCREQ_OFF_SSID 10 + +#define WLAN_REASSOCRESP_OFF_CAP_INFO 0 +#define WLAN_REASSOCRESP_OFF_STATUS 2 +#define WLAN_REASSOCRESP_OFF_AID 4 +#define WLAN_REASSOCRESP_OFF_SUPP_RATES 6 + +#define WLAN_PROBEREQ_OFF_SSID 0 + +#define WLAN_PROBERESP_OFF_TS 0 +#define WLAN_PROBERESP_OFF_BCN_INT 8 +#define WLAN_PROBERESP_OFF_CAP_INFO 10 +#define WLAN_PROBERESP_OFF_SSID 12 + +#define WLAN_AUTHEN_OFF_AUTH_ALG 0 +#define WLAN_AUTHEN_OFF_AUTH_SEQ 2 +#define WLAN_AUTHEN_OFF_STATUS 4 +#define WLAN_AUTHEN_OFF_CHALLENGE 6 + +#define WLAN_DEAUTHEN_OFF_REASON 0 + + +/*================================================================*/ +/* Macros */ + +/*-- Capability Field ---------------------------*/ +#define WLAN_GET_MGMT_CAP_INFO_ESS(n) ((n) & BIT0) +#define WLAN_GET_MGMT_CAP_INFO_IBSS(n) (((n) & BIT1) >> 1) +#define WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(n) (((n) & BIT2) >> 2) +#define WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(n) (((n) & BIT3) >> 3) +#define WLAN_GET_MGMT_CAP_INFO_PRIVACY(n) (((n) & BIT4) >> 4) + /* p80211b additions */ +#define WLAN_GET_MGMT_CAP_INFO_SHORT(n) (((n) & BIT5) >> 5) +#define WLAN_GET_MGMT_CAP_INFO_PBCC(n) (((n) & BIT6) >> 6) +#define WLAN_GET_MGMT_CAP_INFO_AGILITY(n) (((n) & BIT7) >> 7) + +#define WLAN_SET_MGMT_CAP_INFO_ESS(n) (n) +#define WLAN_SET_MGMT_CAP_INFO_IBSS(n) ((n) << 1) +#define WLAN_SET_MGMT_CAP_INFO_CFPOLLABLE(n) ((n) << 2) +#define WLAN_SET_MGMT_CAP_INFO_CFPOLLREQ(n) ((n) << 3) +#define WLAN_SET_MGMT_CAP_INFO_PRIVACY(n) ((n) << 4) + /* p80211b additions */ +#define WLAN_SET_MGMT_CAP_INFO_SHORT(n) ((n) << 5) +#define WLAN_SET_MGMT_CAP_INFO_PBCC(n) ((n) << 6) +#define WLAN_SET_MGMT_CAP_INFO_AGILITY(n) ((n) << 7) + + +/*================================================================*/ +/* Types */ + +/*-- Information Element Types --------------------*/ +/* prototype structure, all IEs start with these members */ + +typedef struct wlan_ie +{ + UINT8 eid; + UINT8 len; +} __WLAN_ATTRIB_PACK__ wlan_ie_t; + +/*-- Service Set Identity (SSID) -----------------*/ +typedef struct wlan_ie_ssid +{ + UINT8 eid; + UINT8 len; + UINT8 ssid[1]; /* may be zero, ptrs may overlap */ +} __WLAN_ATTRIB_PACK__ wlan_ie_ssid_t; + +/*-- Supported Rates -----------------------------*/ +typedef struct wlan_ie_supp_rates +{ + UINT8 eid; + UINT8 len; + UINT8 rates[1]; /* had better be at LEAST one! */ +} __WLAN_ATTRIB_PACK__ wlan_ie_supp_rates_t; + +/*-- FH Parameter Set ----------------------------*/ +typedef struct wlan_ie_fh_parms +{ + UINT8 eid; + UINT8 len; + UINT16 dwell; + UINT8 hopset; + UINT8 hoppattern; + UINT8 hopindex; +} __WLAN_ATTRIB_PACK__ wlan_ie_fh_parms_t; + +/*-- DS Parameter Set ----------------------------*/ +typedef struct wlan_ie_ds_parms +{ + UINT8 eid; + UINT8 len; + UINT8 curr_ch; +} __WLAN_ATTRIB_PACK__ wlan_ie_ds_parms_t; + +/*-- CF Parameter Set ----------------------------*/ + +typedef struct wlan_ie_cf_parms +{ + UINT8 eid; + UINT8 len; + UINT8 cfp_cnt; + UINT8 cfp_period; + UINT16 cfp_maxdur; + UINT16 cfp_durremaining; +} __WLAN_ATTRIB_PACK__ wlan_ie_cf_parms_t; + +/*-- TIM ------------------------------------------*/ +typedef struct wlan_ie_tim +{ + UINT8 eid; + UINT8 len; + UINT8 dtim_cnt; + UINT8 dtim_period; + UINT8 bitmap_ctl; + UINT8 virt_bm[1]; +} __WLAN_ATTRIB_PACK__ wlan_ie_tim_t; + +/*-- IBSS Parameter Set ---------------------------*/ +typedef struct wlan_ie_ibss_parms +{ + UINT8 eid; + UINT8 len; + UINT16 atim_win; +} __WLAN_ATTRIB_PACK__ wlan_ie_ibss_parms_t; + +/*-- Challenge Text ------------------------------*/ +typedef struct wlan_ie_challenge +{ + UINT8 eid; + UINT8 len; + UINT8 challenge[1]; +} __WLAN_ATTRIB_PACK__ wlan_ie_challenge_t; + +/*-------------------------------------------------*/ +/* Frame Types */ + +/* prototype structure, all mgmt frame types will start with these members */ +typedef struct wlan_fr_mgmt +{ + UINT16 type; + UINT16 len; /* DOES NOT include CRC !!!!*/ + UINT8 *buf; + p80211_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + void *priv; + /*-- fixed fields -----------*/ + /*-- info elements ----------*/ +} wlan_fr_mgmt_t; + +/*-- Beacon ---------------------------------------*/ +typedef struct wlan_fr_beacon +{ + UINT16 type; + UINT16 len; + UINT8 *buf; + p80211_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + void *priv; + /*-- fixed fields -----------*/ + UINT64 *ts; + UINT16 *bcn_int; + UINT16 *cap_info; + /*-- info elements ----------*/ + wlan_ie_ssid_t *ssid; + wlan_ie_supp_rates_t *supp_rates; + wlan_ie_fh_parms_t *fh_parms; + wlan_ie_ds_parms_t *ds_parms; + wlan_ie_cf_parms_t *cf_parms; + wlan_ie_ibss_parms_t *ibss_parms; + wlan_ie_tim_t *tim; + +} wlan_fr_beacon_t; + + +/*-- IBSS ATIM ------------------------------------*/ +typedef struct wlan_fr_ibssatim +{ + UINT16 type; + UINT16 len; + UINT8* buf; + p80211_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + void *priv; + + /*-- fixed fields -----------*/ + /*-- info elements ----------*/ + + /* this frame type has a null body */ + +} wlan_fr_ibssatim_t; + +/*-- Disassociation -------------------------------*/ +typedef struct wlan_fr_disassoc +{ + UINT16 type; + UINT16 len; + UINT8 *buf; + p80211_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + void *priv; + /*-- fixed fields -----------*/ + UINT16 *reason; + + /*-- info elements ----------*/ + +} wlan_fr_disassoc_t; + +/*-- Association Request --------------------------*/ +typedef struct wlan_fr_assocreq +{ + UINT16 type; + UINT16 len; + UINT8* buf; + p80211_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + void *priv; + /*-- fixed fields -----------*/ + UINT16 *cap_info; + UINT16 *listen_int; + /*-- info elements ----------*/ + wlan_ie_ssid_t *ssid; + wlan_ie_supp_rates_t *supp_rates; + +} wlan_fr_assocreq_t; + +/*-- Association Response -------------------------*/ +typedef struct wlan_fr_assocresp +{ + UINT16 type; + UINT16 len; + UINT8 *buf; + p80211_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + void *priv; + /*-- fixed fields -----------*/ + UINT16 *cap_info; + UINT16 *status; + UINT16 *aid; + /*-- info elements ----------*/ + wlan_ie_supp_rates_t *supp_rates; + +} wlan_fr_assocresp_t; + +/*-- Reassociation Request ------------------------*/ +typedef struct wlan_fr_reassocreq +{ + UINT16 type; + UINT16 len; + UINT8 *buf; + p80211_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + void *priv; + /*-- fixed fields -----------*/ + UINT16 *cap_info; + UINT16 *listen_int; + UINT8 *curr_ap; + /*-- info elements ----------*/ + wlan_ie_ssid_t *ssid; + wlan_ie_supp_rates_t *supp_rates; + +} wlan_fr_reassocreq_t; + +/*-- Reassociation Response -----------------------*/ +typedef struct wlan_fr_reassocresp +{ + UINT16 type; + UINT16 len; + UINT8 *buf; + p80211_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + void *priv; + /*-- fixed fields -----------*/ + UINT16 *cap_info; + UINT16 *status; + UINT16 *aid; + /*-- info elements ----------*/ + wlan_ie_supp_rates_t *supp_rates; + +} wlan_fr_reassocresp_t; + +/*-- Probe Request --------------------------------*/ +typedef struct wlan_fr_probereq +{ + UINT16 type; + UINT16 len; + UINT8 *buf; + p80211_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + void *priv; + /*-- fixed fields -----------*/ + /*-- info elements ----------*/ + wlan_ie_ssid_t *ssid; + wlan_ie_supp_rates_t *supp_rates; + +} wlan_fr_probereq_t; + +/*-- Probe Response -------------------------------*/ +typedef struct wlan_fr_proberesp +{ + UINT16 type; + UINT16 len; + UINT8 *buf; + p80211_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + void *priv; + /*-- fixed fields -----------*/ + UINT64 *ts; + UINT16 *bcn_int; + UINT16 *cap_info; + /*-- info elements ----------*/ + wlan_ie_ssid_t *ssid; + wlan_ie_supp_rates_t *supp_rates; + wlan_ie_fh_parms_t *fh_parms; + wlan_ie_ds_parms_t *ds_parms; + wlan_ie_cf_parms_t *cf_parms; + wlan_ie_ibss_parms_t *ibss_parms; +} wlan_fr_proberesp_t; + +/*-- Authentication -------------------------------*/ +typedef struct wlan_fr_authen +{ + UINT16 type; + UINT16 len; + UINT8 *buf; + p80211_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + void *priv; + /*-- fixed fields -----------*/ + UINT16 *auth_alg; + UINT16 *auth_seq; + UINT16 *status; + /*-- info elements ----------*/ + wlan_ie_challenge_t *challenge; + +} wlan_fr_authen_t; + +/*-- Deauthenication -----------------------------*/ +typedef struct wlan_fr_deauthen +{ + UINT16 type; + UINT16 len; + UINT8 *buf; + p80211_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + void *priv; + /*-- fixed fields -----------*/ + UINT16 *reason; + + /*-- info elements ----------*/ + +} wlan_fr_deauthen_t; + + +/*================================================================*/ +/* Extern Declarations */ + + +/*================================================================*/ +/* Function Declarations */ + +void wlan_mgmt_encode_beacon( wlan_fr_beacon_t *f ); +void wlan_mgmt_decode_beacon( wlan_fr_beacon_t *f ); +void wlan_mgmt_encode_disassoc( wlan_fr_disassoc_t *f ); +void wlan_mgmt_decode_disassoc( wlan_fr_disassoc_t *f ); +void wlan_mgmt_encode_assocreq( wlan_fr_assocreq_t *f ); +void wlan_mgmt_decode_assocreq( wlan_fr_assocreq_t *f ); +void wlan_mgmt_encode_assocresp( wlan_fr_assocresp_t *f ); +void wlan_mgmt_decode_assocresp( wlan_fr_assocresp_t *f ); +void wlan_mgmt_encode_reassocreq( wlan_fr_reassocreq_t *f ); +void wlan_mgmt_decode_reassocreq( wlan_fr_reassocreq_t *f ); +void wlan_mgmt_encode_reassocresp( wlan_fr_reassocresp_t *f ); +void wlan_mgmt_decode_reassocresp( wlan_fr_reassocresp_t *f ); +void wlan_mgmt_encode_probereq( wlan_fr_probereq_t *f ); +void wlan_mgmt_decode_probereq( wlan_fr_probereq_t *f ); +void wlan_mgmt_encode_proberesp( wlan_fr_proberesp_t *f ); +void wlan_mgmt_decode_proberesp( wlan_fr_proberesp_t *f ); +void wlan_mgmt_encode_authen( wlan_fr_authen_t *f ); +void wlan_mgmt_decode_authen( wlan_fr_authen_t *f ); +void wlan_mgmt_encode_deauthen( wlan_fr_deauthen_t *f ); +void wlan_mgmt_decode_deauthen( wlan_fr_deauthen_t *f ); + + +#endif /* _P80211MGMT_H */ --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211meta.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211meta.h @@ -0,0 +1,169 @@ +/* src/include/wlan/p80211meta.h +* +* Macros, constants, types, and funcs for p80211 metadata +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file declares some of the constants and types used in various +* parts of the linux-wlan system. +* +* Notes: +* - Constant values are always in HOST byte order. +* +* All functions and statics declared here are implemented in p80211types.c +* -------------------------------------------------------------------- +*/ + +#ifndef _P80211META_H +#define _P80211META_H + +/*================================================================*/ +/* System Includes */ + +/*================================================================*/ +/* Project Includes */ + +#ifndef _WLAN_COMPAT_H +#include +#endif + +/*================================================================*/ +/* Constants */ + +/*----------------------------------------------------------------*/ +/* */ + +/*================================================================*/ +/* Macros */ + +/*----------------------------------------------------------------*/ +/* The following macros are used to ensure consistent naming */ +/* conventions for all the different metadata lists. */ + +#define MKREQMETANAME(name) p80211meta_ ## req ## _ ## name +#define MKINDMETANAME(name) p80211meta_ ## ind ## _ ## name +#define MKMIBMETANAME(name) p80211meta_ ## mib ## _ ## name +#define MKGRPMETANAME(name) p80211meta_ ## grp ## _ ## name + +#define MKREQMETASIZE(name) p80211meta_ ## req ## _ ## name ## _ ## size +#define MKINDMETASIZE(name) p80211meta_ ## ind ## _ ## name ## _ ## size +#define MKMIBMETASIZE(name) p80211meta_ ## mib ## _ ## name ## _ ## size +#define MKGRPMETASIZE(name) p80211meta_ ## grp ## _ ## name ## _ ## size + +#define GETMETASIZE(aptr) (**((UINT32**)(aptr))) + +/*----------------------------------------------------------------*/ +/* The following ifdef depends on the following defines: */ +/* P80211_NOINCLUDESTRINGS - if defined, all metadata name fields */ +/* are empty strings */ + +#ifdef P80211_NOINCLUDESTRINGS + #define MKITEMNAME(s) ("") +#else + #define MKITEMNAME(s) (s) +#endif + +/*================================================================*/ +/* Types */ + +/*----------------------------------------------------------------*/ +/* The following structure types are used for the metadata */ +/* representation of category list metadata, group list metadata, */ +/* and data item metadata for both Mib and Messages. */ + +typedef struct p80211meta +{ + char *name; /* data item name */ + UINT32 did; /* partial did */ + UINT32 flags; /* set of various flag bits */ + UINT32 min; /* min value of a BOUNDEDINT */ + UINT32 max; /* max value of a BOUNDEDINT */ + + UINT32 maxlen; /* maxlen of a OCTETSTR or DISPLAYSTR */ + UINT32 minlen; /* minlen of a OCTETSTR or DISPLAYSTR */ + p80211enum_t *enumptr; /* ptr to the enum type for ENUMINT */ + p80211_totext_t totextptr; /* ptr to totext conversion function */ + p80211_fromtext_t fromtextptr; /* ptr to totext conversion function */ + p80211_valid_t validfunptr; /* ptr to totext conversion function */ +} p80211meta_t; + +typedef struct grplistitem +{ + char *name; + p80211meta_t *itemlist; +} grplistitem_t; + +typedef struct catlistitem +{ + char *name; + grplistitem_t *grplist; +} catlistitem_t; + +/*================================================================*/ +/* Extern Declarations */ + +/*----------------------------------------------------------------*/ +/* */ + +/*================================================================*/ +/* Function Declarations */ + +/*----------------------------------------------------------------*/ +/* */ +UINT32 p80211_text2did(catlistitem_t *catlist, char *catname, char *grpname, char *itemname); +UINT32 p80211_text2catdid(catlistitem_t *list, char *name ); +UINT32 p80211_text2grpdid(grplistitem_t *list, char *name ); +UINT32 p80211_text2itemdid(p80211meta_t *list, char *name ); +UINT32 p80211_isvalid_did( catlistitem_t *catlist, UINT32 did ); +UINT32 p80211_isvalid_catdid( catlistitem_t *catlist, UINT32 did ); +UINT32 p80211_isvalid_grpdid( catlistitem_t *catlist, UINT32 did ); +UINT32 p80211_isvalid_itemdid( catlistitem_t *catlist, UINT32 did ); +catlistitem_t *p80211_did2cat( catlistitem_t *catlist, UINT32 did ); +grplistitem_t *p80211_did2grp( catlistitem_t *catlist, UINT32 did ); +p80211meta_t *p80211_did2item( catlistitem_t *catlist, UINT32 did ); +UINT32 p80211item_maxdatalen( struct catlistitem *metalist, UINT32 did ); +UINT32 p80211_metaname2did(struct catlistitem *metalist, char *itemname); +UINT32 p80211item_getoffset( struct catlistitem *metalist, UINT32 did ); +int p80211item_gettype(p80211meta_t *meta); + +#endif /* _P80211META_H */ --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211netdev.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211netdev.h @@ -0,0 +1,339 @@ +/* src/include/wlan/p80211netdev.h +* +* WLAN net device structure and functions +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file declares the structure type that represents each wlan +* interface. +* +* -------------------------------------------------------------------- +*/ + +#ifndef _LINUX_P80211NETDEV_H +#define _LINUX_P80211NETDEV_H + +#include +#include + +/*================================================================*/ +/* Constants */ + +#define WLAN_DEVICE_CLOSED 0 +#define WLAN_DEVICE_OPEN 1 + +#define WLAN_MACMODE_NONE 0 +#define WLAN_MACMODE_IBSS_STA 1 +#define WLAN_MACMODE_ESS_STA 2 +#define WLAN_MACMODE_ESS_AP 3 + +/* MSD States */ +#define WLAN_MSD_START -1 +#define WLAN_MSD_DRIVERLOADED 0 +#define WLAN_MSD_HWPRESENT_PENDING 1 +#define WLAN_MSD_HWFAIL 2 +#define WLAN_MSD_HWPRESENT 3 +#define WLAN_MSD_FWLOAD_PENDING 4 +#define WLAN_MSD_FWLOAD 5 +#define WLAN_MSD_RUNNING_PENDING 6 +#define WLAN_MSD_RUNNING 7 + +#ifndef ETH_P_ECONET +#define ETH_P_ECONET 0x0018 /* needed for 2.2.x kernels */ +#endif + +#define ETH_P_80211_RAW (ETH_P_ECONET + 1) + +#ifndef ARPHRD_IEEE80211 +#define ARPHRD_IEEE80211 801 /* kernel 2.4.6 */ +#endif + +#ifndef ARPHRD_IEEE80211_PRISM /* kernel 2.4.18 */ +#define ARPHRD_IEEE80211_PRISM 802 +#endif + +/*--- NSD Capabilities Flags ------------------------------*/ +#define P80211_NSDCAP_HARDWAREWEP 0x01 /* hardware wep engine */ +#define P80211_NSDCAP_TIEDWEP 0x02 /* can't decouple en/de */ +#define P80211_NSDCAP_NOHOSTWEP 0x04 /* must use hardware wep */ +#define P80211_NSDCAP_PBCC 0x08 /* hardware supports PBCC */ +#define P80211_NSDCAP_SHORT_PREAMBLE 0x10 /* hardware supports */ +#define P80211_NSDCAP_AGILITY 0x20 /* hardware supports */ +#define P80211_NSDCAP_AP_RETRANSMIT 0x40 /* nsd handles retransmits */ +#define P80211_NSDCAP_HWFRAGMENT 0x80 /* nsd handles frag/defrag */ +#define P80211_NSDCAP_AUTOJOIN 0x100 /* nsd does autojoin */ +#define P80211_NSDCAP_NOSCAN 0x200 /* nsd can scan */ + +/*================================================================*/ +/* Macros */ + +/*================================================================*/ +/* Types */ + +/* Received frame statistics */ +typedef struct p80211_frmrx_t +{ + UINT32 mgmt; + UINT32 assocreq; + UINT32 assocresp; + UINT32 reassocreq; + UINT32 reassocresp; + UINT32 probereq; + UINT32 proberesp; + UINT32 beacon; + UINT32 atim; + UINT32 disassoc; + UINT32 authen; + UINT32 deauthen; + UINT32 mgmt_unknown; + UINT32 ctl; + UINT32 pspoll; + UINT32 rts; + UINT32 cts; + UINT32 ack; + UINT32 cfend; + UINT32 cfendcfack; + UINT32 ctl_unknown; + UINT32 data; + UINT32 dataonly; + UINT32 data_cfack; + UINT32 data_cfpoll; + UINT32 data__cfack_cfpoll; + UINT32 null; + UINT32 cfack; + UINT32 cfpoll; + UINT32 cfack_cfpoll; + UINT32 data_unknown; + UINT32 decrypt; + UINT32 decrypt_err; +} p80211_frmrx_t; + +#ifdef WIRELESS_EXT +/* called by /proc/net/wireless */ +struct iw_statistics* p80211wext_get_wireless_stats(netdevice_t *dev); +/* wireless extensions' ioctls */ +int p80211wext_support_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd); +#if WIRELESS_EXT > 12 +extern struct iw_handler_def p80211wext_handler_def; +#endif + +int p80211wext_event_associated(struct wlandevice *wlandev, int assoc); + +#endif /* wireless extensions */ + +/* WEP stuff */ +#define NUM_WEPKEYS 4 +#define MAX_KEYLEN 32 + +#define HOSTWEP_DEFAULTKEY_MASK (BIT1|BIT0) +#define HOSTWEP_DECRYPT BIT4 +#define HOSTWEP_ENCRYPT BIT5 +#define HOSTWEP_PRIVACYINVOKED BIT6 +#define HOSTWEP_EXCLUDEUNENCRYPTED BIT7 + +extern int wlan_watchdog; +extern int wlan_wext_write; + +/* WLAN device type */ +typedef struct wlandevice +{ + struct wlandevice *next; /* link for list of devices */ + void *priv; /* private data for MSD */ + + /* Subsystem State */ + char name[WLAN_DEVNAMELEN_MAX]; /* Dev name, from register_wlandev()*/ + char *nsdname; + + UINT32 state; /* Device I/F state (open/closed) */ + UINT32 msdstate; /* state of underlying driver */ + UINT32 hwremoved; /* Has the hw been yanked out? */ + + /* Hardware config */ + UINT irq; + UINT iobase; + UINT membase; + UINT32 nsdcaps; /* NSD Capabilities flags */ + + /* Config vars */ + UINT ethconv; + + /* device methods (init by MSD, used by p80211 */ + int (*open)(struct wlandevice *wlandev); + int (*close)(struct wlandevice *wlandev); + void (*reset)(struct wlandevice *wlandev ); + int (*txframe)(struct wlandevice *wlandev, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep); + int (*mlmerequest)(struct wlandevice *wlandev, p80211msg_t *msg); + int (*set_multicast_list)(struct wlandevice *wlandev, + netdevice_t *dev); + void (*tx_timeout)(struct wlandevice *wlandev); + +#ifdef CONFIG_PROC_FS + int (*nsd_proc_read)(char *page, char **start, off_t offset, int count, int *eof, void *data); +#endif + + /* 802.11 State */ + UINT8 bssid[WLAN_BSSID_LEN]; + p80211pstr32_t ssid; + UINT32 macmode; + int linkstatus; + int shortpreamble; /* C bool */ + + /* WEP State */ + UINT8 wep_keys[NUM_WEPKEYS][MAX_KEYLEN]; + UINT8 wep_keylens[NUM_WEPKEYS]; + int hostwep; + + /* Request/Confirm i/f state (used by p80211) */ + unsigned long request_pending; /* flag, access atomically */ + + /* netlink socket */ + /* queue for indications waiting for cmd completion */ + /* Linux netdevice and support */ + netdevice_t *netdev; /* ptr to linux netdevice */ + struct net_device_stats linux_stats; + +#ifdef CONFIG_PROC_FS + /* Procfs support */ + struct proc_dir_entry *procdir; + struct proc_dir_entry *procwlandev; +#endif + + /* Rx bottom half */ + struct tasklet_struct rx_bh; + + struct sk_buff_head nsd_rxq; + + /* 802.11 device statistics */ + struct p80211_frmrx_t rx; + +/* compatibility to wireless extensions */ +#ifdef WIRELESS_EXT + struct iw_statistics wstats; + + /* jkriegl: iwspy fields */ + UINT8 spy_number; + char spy_address[IW_MAX_SPY][ETH_ALEN]; + struct iw_quality spy_stat[IW_MAX_SPY]; + +#endif + + struct mutex ioctl_lock; +} wlandevice_t; + +/* WEP stuff */ +int wep_change_key(wlandevice_t *wlandev, int keynum, UINT8* key, int keylen); +int wep_decrypt(wlandevice_t *wlandev, UINT8 *buf, UINT32 len, int key_override, UINT8 *iv, UINT8 *icv); +int wep_encrypt(wlandevice_t *wlandev, UINT8 *buf, UINT8 *dst, UINT32 len, int keynum, UINT8 *iv, UINT8 *icv); + +/*================================================================*/ +/* Externs */ + +/*================================================================*/ +/* Function Declarations */ + +void p80211netdev_startup(void); +void p80211netdev_shutdown(void); +int wlan_setup(wlandevice_t *wlandev); +int wlan_unsetup(wlandevice_t *wlandev); +int register_wlandev(wlandevice_t *wlandev); +int unregister_wlandev(wlandevice_t *wlandev); +void p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb); +void p80211netdev_hwremoved(wlandevice_t *wlandev); +void p80211_suspend(wlandevice_t *wlandev); +void p80211_resume(wlandevice_t *wlandev); + +void p80211_allow_ioctls(wlandevice_t *wlandev); + +/*================================================================*/ +/* Function Definitions */ + +static inline void +p80211netdev_stop_queue(wlandevice_t *wlandev) +{ + if ( !wlandev ) return; + if ( !wlandev->netdev ) return; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) ) + wlandev->netdev->tbusy = 1; + wlandev->netdev->start = 0; +#else + netif_stop_queue(wlandev->netdev); +#endif +} + +static inline void +p80211netdev_start_queue(wlandevice_t *wlandev) +{ + if ( !wlandev ) return; + if ( !wlandev->netdev ) return; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) ) + wlandev->netdev->tbusy = 0; + wlandev->netdev->start = 1; +#else + netif_start_queue(wlandev->netdev); +#endif +} + +static inline void +p80211netdev_wake_queue(wlandevice_t *wlandev) +{ + if ( !wlandev ) return; + if ( !wlandev->netdev ) return; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) ) + wlandev->netdev->tbusy = 0; + mark_bh(NET_BH); +#else + netif_wake_queue(wlandev->netdev); +#endif +} + +#ifdef CONFIG_HOTPLUG +#define WLAN_HOTPLUG_REGISTER "register" +#define WLAN_HOTPLUG_REMOVE "remove" +#define WLAN_HOTPLUG_STARTUP "startup" +#define WLAN_HOTPLUG_SHUTDOWN "shutdown" +#define WLAN_HOTPLUG_SUSPEND "suspend" +#define WLAN_HOTPLUG_RESUME "resume" +int p80211_run_sbin_hotplug(wlandevice_t *wlandev, char *action); +#endif + +#endif --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211conv.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211conv.h @@ -0,0 +1,186 @@ +/* src/include/wlan/p80211conv.h +* +* Ether/802.11 conversions and packet buffer routines +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file declares the functions, types and macros that perform +* Ethernet to/from 802.11 frame conversions. +* +* -------------------------------------------------------------------- +*/ + +#ifndef _LINUX_P80211CONV_H +#define _LINUX_P80211CONV_H + +/*================================================================*/ +/* Constants */ + +#define WLAN_ETHADDR_LEN 6 +#define WLAN_IEEE_OUI_LEN 3 + +#define WLAN_ETHCONV_ENCAP 1 +#define WLAN_ETHCONV_RFC1042 2 +#define WLAN_ETHCONV_8021h 3 + +#define WLAN_MIN_ETHFRM_LEN 60 +#define WLAN_MAX_ETHFRM_LEN 1514 +#define WLAN_ETHHDR_LEN 14 + +#define P80211CAPTURE_VERSION 0x80211001 + +/*================================================================*/ +/* Macros */ + +#define P80211_FRMMETA_MAGIC 0x802110 + +#define P80211SKB_FRMMETA(s) \ + (((((p80211_frmmeta_t*)((s)->cb))->magic)==P80211_FRMMETA_MAGIC) ? \ + ((p80211_frmmeta_t*)((s)->cb)) : \ + (NULL)) + +#define P80211SKB_RXMETA(s) \ + (P80211SKB_FRMMETA((s)) ? P80211SKB_FRMMETA((s))->rx : ((p80211_rxmeta_t*)(NULL))) + +typedef struct p80211_rxmeta +{ + struct wlandevice *wlandev; + + UINT64 mactime; /* Hi-rez MAC-supplied time value */ + UINT64 hosttime; /* Best-rez host supplied time value */ + + UINT rxrate; /* Receive data rate in 100kbps */ + UINT priority; /* 0-15, 0=contention, 6=CF */ + INT signal; /* An SSI, see p80211netdev.h */ + INT noise; /* An SSI, see p80211netdev.h */ + UINT channel; /* Receive channel (mostly for snifs) */ + UINT preamble; /* P80211ENUM_preambletype_* */ + UINT encoding; /* P80211ENUM_encoding_* */ + +} p80211_rxmeta_t; + +typedef struct p80211_frmmeta +{ + UINT magic; + p80211_rxmeta_t *rx; +} p80211_frmmeta_t; + +void p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb); +int p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb); +void p80211skb_rxmeta_detach(struct sk_buff *skb); + +/*================================================================*/ +/* Types */ + +/* + * Frame capture header. (See doc/capturefrm.txt) + */ +typedef struct p80211_caphdr +{ + UINT32 version; + UINT32 length; + UINT64 mactime; + UINT64 hosttime; + UINT32 phytype; + UINT32 channel; + UINT32 datarate; + UINT32 antenna; + UINT32 priority; + UINT32 ssi_type; + INT32 ssi_signal; + INT32 ssi_noise; + UINT32 preamble; + UINT32 encoding; +} p80211_caphdr_t; + +/* buffer free method pointer type */ +typedef void (* freebuf_method_t)(void *buf, int size); + +typedef struct p80211_metawep { + void *data; + UINT8 iv[4]; + UINT8 icv[4]; +} p80211_metawep_t; + +/* local ether header type */ +typedef struct wlan_ethhdr +{ + UINT8 daddr[WLAN_ETHADDR_LEN]; + UINT8 saddr[WLAN_ETHADDR_LEN]; + UINT16 type; +} __WLAN_ATTRIB_PACK__ wlan_ethhdr_t; + +/* local llc header type */ +typedef struct wlan_llc +{ + UINT8 dsap; + UINT8 ssap; + UINT8 ctl; +} __WLAN_ATTRIB_PACK__ wlan_llc_t; + +/* local snap header type */ +typedef struct wlan_snap +{ + UINT8 oui[WLAN_IEEE_OUI_LEN]; + UINT16 type; +} __WLAN_ATTRIB_PACK__ wlan_snap_t; + +/* Circular include trick */ +struct wlandevice; + +/*================================================================*/ +/* Externs */ + +/*================================================================*/ +/*Function Declarations */ + +int skb_p80211_to_ether( struct wlandevice *wlandev, UINT32 ethconv, + struct sk_buff *skb); +int skb_ether_to_p80211( struct wlandevice *wlandev, UINT32 ethconv, + struct sk_buff *skb, p80211_hdr_t *p80211_hdr, + p80211_metawep_t *p80211_wep ); + +int p80211_stt_findproto(UINT16 proto); +int p80211_stt_addproto(UINT16 proto); + +#endif --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211hdr.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211hdr.h @@ -0,0 +1,299 @@ +/* src/include/wlan/p80211hdr.h +* +* Macros, types, and functions for handling 802.11 MAC headers +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file declares the constants and types used in the interface +* between a wlan driver and the user mode utilities. +* +* Note: +* - Constant values are always in HOST byte order. To assign +* values to multi-byte fields they _must_ be converted to +* ieee byte order. To retrieve multi-byte values from incoming +* frames, they must be converted to host order. +* +* All functions declared here are implemented in p80211.c +* -------------------------------------------------------------------- +*/ + +#ifndef _P80211HDR_H +#define _P80211HDR_H + +/*================================================================*/ +/* System Includes */ + +/*================================================================*/ +/* Project Includes */ + +#ifndef _WLAN_COMPAT_H +#include +#endif + + +/*================================================================*/ +/* Constants */ + +/*--- Sizes -----------------------------------------------*/ +#define WLAN_ADDR_LEN 6 +#define WLAN_CRC_LEN 4 +#define WLAN_BSSID_LEN 6 +#define WLAN_BSS_TS_LEN 8 +#define WLAN_HDR_A3_LEN 24 +#define WLAN_HDR_A4_LEN 30 +#define WLAN_SSID_MAXLEN 32 +#define WLAN_DATA_MAXLEN 2312 +#define WLAN_A3FR_MAXLEN (WLAN_HDR_A3_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN) +#define WLAN_A4FR_MAXLEN (WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN) +#define WLAN_BEACON_FR_MAXLEN (WLAN_HDR_A3_LEN + 334) +#define WLAN_ATIM_FR_MAXLEN (WLAN_HDR_A3_LEN + 0) +#define WLAN_DISASSOC_FR_MAXLEN (WLAN_HDR_A3_LEN + 2) +#define WLAN_ASSOCREQ_FR_MAXLEN (WLAN_HDR_A3_LEN + 48) +#define WLAN_ASSOCRESP_FR_MAXLEN (WLAN_HDR_A3_LEN + 16) +#define WLAN_REASSOCREQ_FR_MAXLEN (WLAN_HDR_A3_LEN + 54) +#define WLAN_REASSOCRESP_FR_MAXLEN (WLAN_HDR_A3_LEN + 16) +#define WLAN_PROBEREQ_FR_MAXLEN (WLAN_HDR_A3_LEN + 44) +#define WLAN_PROBERESP_FR_MAXLEN (WLAN_HDR_A3_LEN + 78) +#define WLAN_AUTHEN_FR_MAXLEN (WLAN_HDR_A3_LEN + 261) +#define WLAN_DEAUTHEN_FR_MAXLEN (WLAN_HDR_A3_LEN + 2) +#define WLAN_WEP_NKEYS 4 +#define WLAN_WEP_MAXKEYLEN 13 +#define WLAN_CHALLENGE_IE_LEN 130 +#define WLAN_CHALLENGE_LEN 128 +#define WLAN_WEP_IV_LEN 4 +#define WLAN_WEP_ICV_LEN 4 + +/*--- Frame Control Field -------------------------------------*/ +/* Frame Types */ +#define WLAN_FTYPE_MGMT 0x00 +#define WLAN_FTYPE_CTL 0x01 +#define WLAN_FTYPE_DATA 0x02 + +/* Frame subtypes */ +/* Management */ +#define WLAN_FSTYPE_ASSOCREQ 0x00 +#define WLAN_FSTYPE_ASSOCRESP 0x01 +#define WLAN_FSTYPE_REASSOCREQ 0x02 +#define WLAN_FSTYPE_REASSOCRESP 0x03 +#define WLAN_FSTYPE_PROBEREQ 0x04 +#define WLAN_FSTYPE_PROBERESP 0x05 +#define WLAN_FSTYPE_BEACON 0x08 +#define WLAN_FSTYPE_ATIM 0x09 +#define WLAN_FSTYPE_DISASSOC 0x0a +#define WLAN_FSTYPE_AUTHEN 0x0b +#define WLAN_FSTYPE_DEAUTHEN 0x0c + +/* Control */ +#define WLAN_FSTYPE_BLOCKACKREQ 0x8 +#define WLAN_FSTYPE_BLOCKACK 0x9 +#define WLAN_FSTYPE_PSPOLL 0x0a +#define WLAN_FSTYPE_RTS 0x0b +#define WLAN_FSTYPE_CTS 0x0c +#define WLAN_FSTYPE_ACK 0x0d +#define WLAN_FSTYPE_CFEND 0x0e +#define WLAN_FSTYPE_CFENDCFACK 0x0f + +/* Data */ +#define WLAN_FSTYPE_DATAONLY 0x00 +#define WLAN_FSTYPE_DATA_CFACK 0x01 +#define WLAN_FSTYPE_DATA_CFPOLL 0x02 +#define WLAN_FSTYPE_DATA_CFACK_CFPOLL 0x03 +#define WLAN_FSTYPE_NULL 0x04 +#define WLAN_FSTYPE_CFACK 0x05 +#define WLAN_FSTYPE_CFPOLL 0x06 +#define WLAN_FSTYPE_CFACK_CFPOLL 0x07 + + +/*================================================================*/ +/* Macros */ + +/*--- FC Macros ----------------------------------------------*/ +/* Macros to get/set the bitfields of the Frame Control Field */ +/* GET_FC_??? - takes the host byte-order value of an FC */ +/* and retrieves the value of one of the */ +/* bitfields and moves that value so its lsb is */ +/* in bit 0. */ +/* SET_FC_??? - takes a host order value for one of the FC */ +/* bitfields and moves it to the proper bit */ +/* location for ORing into a host order FC. */ +/* To send the FC produced from SET_FC_???, */ +/* one must put the bytes in IEEE order. */ +/* e.g. */ +/* printf("the frame subtype is %x", */ +/* GET_FC_FTYPE( ieee2host( rx.fc ))) */ +/* */ +/* tx.fc = host2ieee( SET_FC_FTYPE(WLAN_FTYP_CTL) | */ +/* SET_FC_FSTYPE(WLAN_FSTYPE_RTS) ); */ +/*------------------------------------------------------------*/ + +#define WLAN_GET_FC_PVER(n) (((UINT16)(n)) & (BIT0 | BIT1)) +#define WLAN_GET_FC_FTYPE(n) ((((UINT16)(n)) & (BIT2 | BIT3)) >> 2) +#define WLAN_GET_FC_FSTYPE(n) ((((UINT16)(n)) & (BIT4|BIT5|BIT6|BIT7)) >> 4) +#define WLAN_GET_FC_TODS(n) ((((UINT16)(n)) & (BIT8)) >> 8) +#define WLAN_GET_FC_FROMDS(n) ((((UINT16)(n)) & (BIT9)) >> 9) +#define WLAN_GET_FC_MOREFRAG(n) ((((UINT16)(n)) & (BIT10)) >> 10) +#define WLAN_GET_FC_RETRY(n) ((((UINT16)(n)) & (BIT11)) >> 11) +#define WLAN_GET_FC_PWRMGT(n) ((((UINT16)(n)) & (BIT12)) >> 12) +#define WLAN_GET_FC_MOREDATA(n) ((((UINT16)(n)) & (BIT13)) >> 13) +#define WLAN_GET_FC_ISWEP(n) ((((UINT16)(n)) & (BIT14)) >> 14) +#define WLAN_GET_FC_ORDER(n) ((((UINT16)(n)) & (BIT15)) >> 15) + +#define WLAN_SET_FC_PVER(n) ((UINT16)(n)) +#define WLAN_SET_FC_FTYPE(n) (((UINT16)(n)) << 2) +#define WLAN_SET_FC_FSTYPE(n) (((UINT16)(n)) << 4) +#define WLAN_SET_FC_TODS(n) (((UINT16)(n)) << 8) +#define WLAN_SET_FC_FROMDS(n) (((UINT16)(n)) << 9) +#define WLAN_SET_FC_MOREFRAG(n) (((UINT16)(n)) << 10) +#define WLAN_SET_FC_RETRY(n) (((UINT16)(n)) << 11) +#define WLAN_SET_FC_PWRMGT(n) (((UINT16)(n)) << 12) +#define WLAN_SET_FC_MOREDATA(n) (((UINT16)(n)) << 13) +#define WLAN_SET_FC_ISWEP(n) (((UINT16)(n)) << 14) +#define WLAN_SET_FC_ORDER(n) (((UINT16)(n)) << 15) + +/*--- Duration Macros ----------------------------------------*/ +/* Macros to get/set the bitfields of the Duration Field */ +/* - the duration value is only valid when bit15 is zero */ +/* - the firmware handles these values, so I'm not going */ +/* these macros right now. */ +/*------------------------------------------------------------*/ + +/*--- Sequence Control Macros -------------------------------*/ +/* Macros to get/set the bitfields of the Sequence Control */ +/* Field. */ +/*------------------------------------------------------------*/ +#define WLAN_GET_SEQ_FRGNUM(n) (((UINT16)(n)) & (BIT0|BIT1|BIT2|BIT3)) +#define WLAN_GET_SEQ_SEQNUM(n) ((((UINT16)(n)) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4) + +/*--- Data ptr macro -----------------------------------------*/ +/* Creates a UINT8* to the data portion of a frame */ +/* Assumes you're passing in a ptr to the beginning of the hdr*/ +/*------------------------------------------------------------*/ +#define WLAN_HDR_A3_DATAP(p) (((UINT8*)(p)) + WLAN_HDR_A3_LEN) +#define WLAN_HDR_A4_DATAP(p) (((UINT8*)(p)) + WLAN_HDR_A4_LEN) + +#define DOT11_RATE5_ISBASIC_GET(r) (((UINT8)(r)) & BIT7) + +/*================================================================*/ +/* Types */ + +/* BSS Timestamp */ +typedef UINT8 wlan_bss_ts_t[WLAN_BSS_TS_LEN]; + +/* Generic 802.11 Header types */ + +typedef struct p80211_hdr_a3 +{ + UINT16 fc; + UINT16 dur; + UINT8 a1[WLAN_ADDR_LEN]; + UINT8 a2[WLAN_ADDR_LEN]; + UINT8 a3[WLAN_ADDR_LEN]; + UINT16 seq; +} __WLAN_ATTRIB_PACK__ p80211_hdr_a3_t; + +typedef struct p80211_hdr_a4 +{ + UINT16 fc; + UINT16 dur; + UINT8 a1[WLAN_ADDR_LEN]; + UINT8 a2[WLAN_ADDR_LEN]; + UINT8 a3[WLAN_ADDR_LEN]; + UINT16 seq; + UINT8 a4[WLAN_ADDR_LEN]; +} __WLAN_ATTRIB_PACK__ p80211_hdr_a4_t; + +typedef union p80211_hdr +{ + p80211_hdr_a3_t a3; + p80211_hdr_a4_t a4; +} __WLAN_ATTRIB_PACK__ p80211_hdr_t; + + +/*================================================================*/ +/* Extern Declarations */ + + +/*================================================================*/ +/* Function Declarations */ + +/* Frame and header lenght macros */ + +#define WLAN_CTL_FRAMELEN(fstype) (\ + (fstype) == WLAN_FSTYPE_BLOCKACKREQ ? 24 : \ + (fstype) == WLAN_FSTYPE_BLOCKACK ? 152 : \ + (fstype) == WLAN_FSTYPE_PSPOLL ? 20 : \ + (fstype) == WLAN_FSTYPE_RTS ? 20 : \ + (fstype) == WLAN_FSTYPE_CTS ? 14 : \ + (fstype) == WLAN_FSTYPE_ACK ? 14 : \ + (fstype) == WLAN_FSTYPE_CFEND ? 20 : \ + (fstype) == WLAN_FSTYPE_CFENDCFACK ? 20 : 4) + +#define WLAN_FCS_LEN 4 + +/* ftcl in HOST order */ +inline static UINT16 p80211_headerlen(UINT16 fctl) +{ + UINT16 hdrlen = 0; + + switch ( WLAN_GET_FC_FTYPE(fctl) ) { + case WLAN_FTYPE_MGMT: + hdrlen = WLAN_HDR_A3_LEN; + break; + case WLAN_FTYPE_DATA: + hdrlen = WLAN_HDR_A3_LEN; + if ( WLAN_GET_FC_TODS(fctl) && WLAN_GET_FC_FROMDS(fctl) ) { + hdrlen += WLAN_ADDR_LEN; + } + break; + case WLAN_FTYPE_CTL: + hdrlen = WLAN_CTL_FRAMELEN(WLAN_GET_FC_FSTYPE(fctl)) - + WLAN_FCS_LEN; + break; + default: + hdrlen = WLAN_HDR_A3_LEN; + } + + return hdrlen; +} + +#endif /* _P80211HDR_H */ --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/version.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/version.h @@ -0,0 +1,64 @@ +/* src/include/wlan/version.h +* +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +*/ +#ifndef _WLAN_VERSION_H +#define _WLAN_VERSION_H +#ifndef KERNEL_VERSION +#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +#endif + +/* WLAN_HOSTIF (generally set on the command line, not detected) */ +#define WLAN_NONE 0 +#define WLAN_PCMCIA 1 +#define WLAN_ISA 2 +#define WLAN_PCI 3 +#define WLAN_USB 4 +#define WLAN_PLX 5 +#define WLAN_SLAVE 6 +#define WLAN_RELEASE "0.2.9" +#define WLAN_RELEASE_CODE 0x000209 +#define WLAN_BUILD_DATE "Sun Jul 27 23:23:32 CEST 2008" + +#endif --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211metamsg.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211metamsg.h @@ -0,0 +1,105 @@ +/* src/include/wlan/p80211metamsg.h +* +* Macros, const, types, and funcs for p80211 msg metadata +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file declares some of the constants and types used in various +* parts of the linux-wlan system. +* +* Notes: +* - Constant values are always in HOST byte order. +* +* All functions and statics declared here are implemented in p80211types.c +* -------------------------------------------------------------------- +*/ + +#ifndef _P80211METAMSG_H +#define _P80211METAMSG_H + +/*================================================================*/ +/* System Includes */ + +/*================================================================*/ +/* Project Includes */ + +#ifndef _WLAN_COMPAT_H +#include +#endif + +/*================================================================*/ +/* Constants */ + +/*----------------------------------------------------------------*/ +/* */ + +/*================================================================*/ +/* Macros */ + +/*----------------------------------------------------------------*/ +/* */ + +/*================================================================*/ +/* Types */ + +/*----------------------------------------------------------------*/ +/* */ + +/*================================================================*/ +/* Extern Declarations */ + +/*----------------------------------------------------------------*/ +/* The following is the external declaration for the message */ +/* category metadata list */ + +extern catlistitem_t msg_catlist[]; +extern UINT32 msg_catlist_size; + + +/*================================================================*/ +/* Function Declarations */ + +/*----------------------------------------------------------------*/ +/* */ + +#endif /* _P80211METAMSG_H */ --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211types.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211types.h @@ -0,0 +1,675 @@ +/* src/include/wlan/p80211types.h +* +* Macros, constants, types, and funcs for p80211 data types +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file declares some of the constants and types used in various +* parts of the linux-wlan system. +* +* Notes: +* - Constant values are always in HOST byte order. +* +* All functions and statics declared here are implemented in p80211types.c +* -------------------------------------------------------------------- +*/ + +#ifndef _P80211TYPES_H +#define _P80211TYPES_H + +/*================================================================*/ +/* System Includes */ +/*================================================================*/ + +/*================================================================*/ +/* Project Includes */ +/*================================================================*/ + +#ifndef _WLAN_COMPAT_H +#include +#endif + +/*================================================================*/ +/* Constants */ +/*================================================================*/ + +/*----------------------------------------------------------------*/ +/* p80211 data type codes used for MIB items and message */ +/* arguments. The various metadata structures provide additional */ +/* information about these types. */ + +#define P80211_TYPE_OCTETSTR 1 /* pascal array of bytes */ +#define P80211_TYPE_DISPLAYSTR 2 /* pascal array of bytes containing ascii */ +#define P80211_TYPE_INT 4 /* UINT32 min and max limited by 32 bits */ +#define P80211_TYPE_ENUMINT 5 /* UINT32 holding a numeric + code that can be mapped + to a textual name */ +#define P80211_TYPE_UNKDATA 6 /* Data item containing an + unknown data type */ +#define P80211_TYPE_INTARRAY 7 /* Array of 32-bit integers. */ +#define P80211_TYPE_BITARRAY 8 /* Array of bits. */ +#define P80211_TYPE_MACARRAY 9 /* Array of MAC addresses. */ + +/*----------------------------------------------------------------*/ +/* The following constants are indexes into the Mib Category List */ +/* and the Message Category List */ + +/* Mib Category List */ +#define P80211_MIB_CAT_DOT11SMT 1 +#define P80211_MIB_CAT_DOT11MAC 2 +#define P80211_MIB_CAT_DOT11PHY 3 + +#define P80211SEC_DOT11SMT P80211_MIB_CAT_DOT11SMT +#define P80211SEC_DOT11MAC P80211_MIB_CAT_DOT11MAC +#define P80211SEC_DOT11PHY P80211_MIB_CAT_DOT11PHY + +/* Message Category List */ +#define P80211_MSG_CAT_DOT11REQ 1 +#define P80211_MSG_CAT_DOT11IND 2 +/* #define P80211_MSG_CAT_DOT11CFM 3 (doesn't exist at this time) */ + +#define P80211SEC_DOT11REQ P80211_MSG_CAT_DOT11REQ +#define P80211SEC_DOT11IND P80211_MSG_CAT_DOT11IND +/* #define P80211SEC_DOT11CFM P80211_MSG_CAT_DOT11CFM (doesn't exist at this time */ + + + +/*----------------------------------------------------------------*/ +/* p80211 DID field codes that represent access type and */ +/* is_table status. */ + +#define P80211DID_ACCESS_READ 0x10000000 +#define P80211DID_ACCESS_WRITE 0x08000000 +#define P80211DID_WRITEONLY 0x00000001 +#define P80211DID_READONLY 0x00000002 +#define P80211DID_READWRITE 0x00000003 +#define P80211DID_ISTABLE_FALSE 0 +#define P80211DID_ISTABLE_TRUE 1 + +/*----------------------------------------------------------------*/ +/* p80211 enumeration constants. The value to text mappings for */ +/* these is in p80211types.c. These defines were generated */ +/* from the mappings. */ + +/* error codes for lookups */ +#define P80211ENUM_BAD 0xffffffffUL +#define P80211ENUM_BADSTR "P80211ENUM_BAD" + +#define P80211ENUM_truth_false 0 +#define P80211ENUM_truth_true 1 +#define P80211ENUM_ifstate_disable 0 +#define P80211ENUM_ifstate_fwload 1 +#define P80211ENUM_ifstate_enable 2 +#define P80211ENUM_powermgmt_active 1 +#define P80211ENUM_powermgmt_powersave 2 +#define P80211ENUM_bsstype_infrastructure 1 +#define P80211ENUM_bsstype_independent 2 +#define P80211ENUM_bsstype_any 3 +#define P80211ENUM_authalg_opensystem 1 +#define P80211ENUM_authalg_sharedkey 2 +#define P80211ENUM_phytype_fhss 1 +#define P80211ENUM_phytype_dsss 2 +#define P80211ENUM_phytype_irbaseband 3 +#define P80211ENUM_temptype_commercial 1 +#define P80211ENUM_temptype_industrial 2 +#define P80211ENUM_regdomain_fcc 16 +#define P80211ENUM_regdomain_doc 32 +#define P80211ENUM_regdomain_etsi 48 +#define P80211ENUM_regdomain_spain 49 +#define P80211ENUM_regdomain_france 50 +#define P80211ENUM_regdomain_mkk 64 +#define P80211ENUM_ccamode_edonly 1 +#define P80211ENUM_ccamode_csonly 2 +#define P80211ENUM_ccamode_edandcs 4 +#define P80211ENUM_ccamode_cswithtimer 8 +#define P80211ENUM_ccamode_hrcsanded 16 +#define P80211ENUM_diversity_fixedlist 1 +#define P80211ENUM_diversity_notsupported 2 +#define P80211ENUM_diversity_dynamic 3 +#define P80211ENUM_scantype_active 1 +#define P80211ENUM_scantype_passive 2 +#define P80211ENUM_scantype_both 3 +#define P80211ENUM_resultcode_success 1 +#define P80211ENUM_resultcode_invalid_parameters 2 +#define P80211ENUM_resultcode_not_supported 3 +#define P80211ENUM_resultcode_timeout 4 +#define P80211ENUM_resultcode_too_many_req 5 +#define P80211ENUM_resultcode_refused 6 +#define P80211ENUM_resultcode_bss_already 7 +#define P80211ENUM_resultcode_invalid_access 8 +#define P80211ENUM_resultcode_invalid_mibattribute 9 +#define P80211ENUM_resultcode_cant_set_readonly_mib 10 +#define P80211ENUM_resultcode_implementation_failure 11 +#define P80211ENUM_resultcode_cant_get_writeonly_mib 12 +#define P80211ENUM_reason_unspec_reason 1 +#define P80211ENUM_reason_auth_not_valid 2 +#define P80211ENUM_reason_deauth_lv_ss 3 +#define P80211ENUM_reason_inactivity 4 +#define P80211ENUM_reason_ap_overload 5 +#define P80211ENUM_reason_class23_err 6 +#define P80211ENUM_reason_class3_err 7 +#define P80211ENUM_reason_disas_lv_ss 8 +#define P80211ENUM_reason_asoc_not_auth 9 +#define P80211ENUM_status_successful 0 +#define P80211ENUM_status_unspec_failure 1 +#define P80211ENUM_status_unsup_cap 10 +#define P80211ENUM_status_reasoc_no_asoc 11 +#define P80211ENUM_status_fail_other 12 +#define P80211ENUM_status_unspt_alg 13 +#define P80211ENUM_status_auth_seq_fail 14 +#define P80211ENUM_status_chlng_fail 15 +#define P80211ENUM_status_auth_timeout 16 +#define P80211ENUM_status_ap_full 17 +#define P80211ENUM_status_unsup_rate 18 +#define P80211ENUM_status_unsup_shortpreamble 19 +#define P80211ENUM_status_unsup_pbcc 20 +#define P80211ENUM_status_unsup_agility 21 +#define P80211ENUM_msgitem_status_data_ok 0 +#define P80211ENUM_msgitem_status_no_value 1 +#define P80211ENUM_msgitem_status_invalid_itemname 2 +#define P80211ENUM_msgitem_status_invalid_itemdata 3 +#define P80211ENUM_msgitem_status_missing_itemdata 4 +#define P80211ENUM_msgitem_status_incomplete_itemdata 5 +#define P80211ENUM_msgitem_status_invalid_msg_did 6 +#define P80211ENUM_msgitem_status_invalid_mib_did 7 +#define P80211ENUM_msgitem_status_missing_conv_func 8 +#define P80211ENUM_msgitem_status_string_too_long 9 +#define P80211ENUM_msgitem_status_data_out_of_range 10 +#define P80211ENUM_msgitem_status_string_too_short 11 +#define P80211ENUM_msgitem_status_missing_valid_func 12 +#define P80211ENUM_msgitem_status_unknown 13 +#define P80211ENUM_msgitem_status_invalid_did 14 +#define P80211ENUM_msgitem_status_missing_print_func 15 + +#define P80211ENUM_lnxroam_reason_unknown 0 +#define P80211ENUM_lnxroam_reason_beacon 1 +#define P80211ENUM_lnxroam_reason_signal 2 +#define P80211ENUM_lnxroam_reason_txretry 3 +#define P80211ENUM_lnxroam_reason_notjoined 4 + +#define P80211ENUM_p2preamble_long 0 +#define P80211ENUM_p2preamble_short 2 +#define P80211ENUM_p2preamble_mixed 3 + +/*----------------------------------------------------------------*/ +/* p80211 max length constants for the different pascal strings. */ + +#define MAXLEN_PSTR6 (6) /* pascal array of 6 bytes */ +#define MAXLEN_PSTR14 (14) /* pascal array of 14 bytes */ +#define MAXLEN_PSTR32 (32) /* pascal array of 32 bytes */ +#define MAXLEN_PSTR255 (255) /* pascal array of 255 bytes */ +#define MAXLEN_MIBATTRIBUTE (392) /* maximum mibattribute */ + /* where the size of the DATA itself */ + /* is a DID-LEN-DATA triple */ + /* with a max size of 4+4+384 */ + +#define P80211_SET_INT(item, value) do { \ + (item).data = (value); \ + (item).status = P80211ENUM_msgitem_status_data_ok; \ + } while(0) +/*----------------------------------------------------------------*/ +/* string constants */ + +#define NOT_SET "NOT_SET" +#define NOT_SUPPORTED "NOT_SUPPORTED" +#define UNKNOWN_DATA "UNKNOWN_DATA" + + +/*--------------------------------------------------------------------*/ +/* Metadata flags */ + +/* MSM: Do these belong in p80211meta.h? I'm not sure. */ + +#define ISREQUIRED (0x80000000UL) +#define ISREQUEST (0x40000000UL) +#define ISCONFIRM (0x20000000UL) + + +/*================================================================*/ +/* Macros */ + +/*--------------------------------------------------------------------*/ +/* The following macros are used to manipulate the 'flags' field in */ +/* the metadata. These are only used when the metadata is for */ +/* command arguments to determine if the data item is required, and */ +/* whether the metadata item is for a request command, confirm */ +/* command or both. */ +/*--------------------------------------------------------------------*/ +/* MSM: Do these belong in p80211meta.h? I'm not sure */ + +#define P80211ITEM_SETFLAGS(q, r, c) ( q | r | c ) + +#define P80211ITEM_ISREQUIRED(flags) (((UINT32)(flags & ISREQUIRED)) >> 31 ) +#define P80211ITEM_ISREQUEST(flags) (((UINT32)(flags & ISREQUEST)) >> 30 ) +#define P80211ITEM_ISCONFIRM(flags) (((UINT32)(flags & ISCONFIRM)) >> 29 ) + +/*----------------------------------------------------------------*/ +/* The following macro creates a name for an enum */ + +#define MKENUMNAME(name) p80211enum_ ## name + +/*---------------------------------------------------------------- +* The following constants and macros are used to construct and +* deconstruct the Data ID codes. The coding is as follows: +* +* ...rwtnnnnnnnniiiiiiggggggssssss s - Section +* g - Group +* i - Item +* n - Index +* t - Table flag +* w - Write flag +* r - Read flag +* . - Unused +*/ + +#define P80211DID_INVALID 0xffffffffUL +#define P80211DID_VALID 0x00000000UL + +#define P80211DID_LSB_SECTION (0) +#define P80211DID_LSB_GROUP (6) +#define P80211DID_LSB_ITEM (12) +#define P80211DID_LSB_INDEX (18) +#define P80211DID_LSB_ISTABLE (26) +#define P80211DID_LSB_ACCESS (27) + +#define P80211DID_MASK_SECTION (0x0000003fUL) +#define P80211DID_MASK_GROUP (0x0000003fUL) +#define P80211DID_MASK_ITEM (0x0000003fUL) +#define P80211DID_MASK_INDEX (0x000000ffUL) +#define P80211DID_MASK_ISTABLE (0x00000001UL) +#define P80211DID_MASK_ACCESS (0x00000003UL) + + +#define P80211DID_MK(a,m,l) ((((UINT32)(a)) & (m)) << (l)) + +#define P80211DID_MKSECTION(a) P80211DID_MK(a, \ + P80211DID_MASK_SECTION, \ + P80211DID_LSB_SECTION ) +#define P80211DID_MKGROUP(a) P80211DID_MK(a, \ + P80211DID_MASK_GROUP, \ + P80211DID_LSB_GROUP ) +#define P80211DID_MKITEM(a) P80211DID_MK(a, \ + P80211DID_MASK_ITEM, \ + P80211DID_LSB_ITEM ) +#define P80211DID_MKINDEX(a) P80211DID_MK(a, \ + P80211DID_MASK_INDEX, \ + P80211DID_LSB_INDEX ) +#define P80211DID_MKISTABLE(a) P80211DID_MK(a, \ + P80211DID_MASK_ISTABLE, \ + P80211DID_LSB_ISTABLE ) + + +#define P80211DID_MKID(s,g,i,n,t,a) (P80211DID_MKSECTION(s) | \ + P80211DID_MKGROUP(g) | \ + P80211DID_MKITEM(i) | \ + P80211DID_MKINDEX(n) | \ + P80211DID_MKISTABLE(t) | \ + (a) ) + + +#define P80211DID_GET(a,m,l) ((((UINT32)(a)) >> (l)) & (m)) + +#define P80211DID_SECTION(a) P80211DID_GET(a, \ + P80211DID_MASK_SECTION, \ + P80211DID_LSB_SECTION) +#define P80211DID_GROUP(a) P80211DID_GET(a, \ + P80211DID_MASK_GROUP, \ + P80211DID_LSB_GROUP) +#define P80211DID_ITEM(a) P80211DID_GET(a, \ + P80211DID_MASK_ITEM, \ + P80211DID_LSB_ITEM) +#define P80211DID_INDEX(a) P80211DID_GET(a, \ + P80211DID_MASK_INDEX, \ + P80211DID_LSB_INDEX) +#define P80211DID_ISTABLE(a) P80211DID_GET(a, \ + P80211DID_MASK_ISTABLE, \ + P80211DID_LSB_ISTABLE) +#define P80211DID_ACCESS(a) P80211DID_GET(a, \ + P80211DID_MASK_ACCESS, \ + P80211DID_LSB_ACCESS) + +/*================================================================*/ +/* Types */ + +/*----------------------------------------------------------------*/ +/* The following structure types are used for the represenation */ +/* of ENUMINT type metadata. */ + +typedef struct p80211enumpair +{ + UINT32 val; + char *name; +} p80211enumpair_t; + +typedef struct p80211enum +{ + INT nitems; + p80211enumpair_t *list; +} p80211enum_t; + +/*----------------------------------------------------------------*/ +/* The following structure types are used to store data items in */ +/* messages. */ + +/* Template pascal string */ +typedef struct p80211pstr +{ + UINT8 len; +} __WLAN_ATTRIB_PACK__ p80211pstr_t; + +typedef struct p80211pstrd +{ + UINT8 len; + UINT8 data[0]; +} __WLAN_ATTRIB_PACK__ p80211pstrd_t; + +/* Maximum pascal string */ +typedef struct p80211pstr255 +{ + UINT8 len; + UINT8 data[MAXLEN_PSTR255]; +} __WLAN_ATTRIB_PACK__ p80211pstr255_t; + +/* pascal string for macaddress and bssid */ +typedef struct p80211pstr6 +{ + UINT8 len; + UINT8 data[MAXLEN_PSTR6]; +} __WLAN_ATTRIB_PACK__ p80211pstr6_t; + +/* pascal string for channel list */ +typedef struct p80211pstr14 +{ + UINT8 len; + UINT8 data[MAXLEN_PSTR14]; +} __WLAN_ATTRIB_PACK__ p80211pstr14_t; + +/* pascal string for ssid */ +typedef struct p80211pstr32 +{ + UINT8 len; + UINT8 data[MAXLEN_PSTR32]; +} __WLAN_ATTRIB_PACK__ p80211pstr32_t; + +/* MAC address array */ +typedef struct p80211macarray +{ + UINT32 cnt; + UINT8 data[1][MAXLEN_PSTR6]; +} __WLAN_ATTRIB_PACK__ p80211macarray_t; + +/* prototype template */ +typedef struct p80211item +{ + UINT32 did; + UINT16 status; + UINT16 len; +} __WLAN_ATTRIB_PACK__ p80211item_t; + +/* prototype template w/ data item */ +typedef struct p80211itemd +{ + UINT32 did; + UINT16 status; + UINT16 len; + UINT8 data[0]; +} __WLAN_ATTRIB_PACK__ p80211itemd_t; + +/* message data item for INT, BOUNDEDINT, ENUMINT */ +typedef struct p80211item_uint32 +{ + UINT32 did; + UINT16 status; + UINT16 len; + UINT32 data; +} __WLAN_ATTRIB_PACK__ p80211item_uint32_t; + +/* message data item for OCTETSTR, DISPLAYSTR */ +typedef struct p80211item_pstr6 +{ + UINT32 did; + UINT16 status; + UINT16 len; + p80211pstr6_t data; +} __WLAN_ATTRIB_PACK__ p80211item_pstr6_t; + +/* message data item for OCTETSTR, DISPLAYSTR */ +typedef struct p80211item_pstr14 +{ + UINT32 did; + UINT16 status; + UINT16 len; + p80211pstr14_t data; +} __WLAN_ATTRIB_PACK__ p80211item_pstr14_t; + +/* message data item for OCTETSTR, DISPLAYSTR */ +typedef struct p80211item_pstr32 +{ + UINT32 did; + UINT16 status; + UINT16 len; + p80211pstr32_t data; +} __WLAN_ATTRIB_PACK__ p80211item_pstr32_t; + +/* message data item for OCTETSTR, DISPLAYSTR */ +typedef struct p80211item_pstr255 +{ + UINT32 did; + UINT16 status; + UINT16 len; + p80211pstr255_t data; +} __WLAN_ATTRIB_PACK__ p80211item_pstr255_t; + +/* message data item for UNK 392, namely mib items */ +typedef struct p80211item_unk392 +{ + UINT32 did; + UINT16 status; + UINT16 len; + UINT8 data[MAXLEN_MIBATTRIBUTE]; +} __WLAN_ATTRIB_PACK__ p80211item_unk392_t; + +/* message data item for UNK 1025, namely p2 pdas */ +typedef struct p80211item_unk1024 +{ + UINT32 did; + UINT16 status; + UINT16 len; + UINT8 data[1024]; +} __WLAN_ATTRIB_PACK__ p80211item_unk1024_t; + +/* message data item for UNK 4096, namely p2 download chunks */ +typedef struct p80211item_unk4096 +{ + UINT32 did; + UINT16 status; + UINT16 len; + UINT8 data[4096]; +} __WLAN_ATTRIB_PACK__ p80211item_unk4096_t; + +struct catlistitem; + +/*----------------------------------------------------------------*/ +/* The following structure type is used to represent all of the */ +/* metadata items. Some components may choose to use more, */ +/* less or different metadata items. */ + +typedef void (*p80211_totext_t)( struct catlistitem *, UINT32 did, UINT8* itembuf, char *textbuf); +typedef void (*p80211_fromtext_t)( struct catlistitem *, UINT32 did, UINT8* itembuf, char *textbuf); +typedef UINT32 (*p80211_valid_t)( struct catlistitem *, UINT32 did, UINT8* itembuf); + + +/*================================================================*/ +/* Extern Declarations */ + +/*----------------------------------------------------------------*/ +/* Enumeration Lists */ +/* The following are the external declarations */ +/* for all enumerations */ + +extern p80211enum_t MKENUMNAME(truth); +extern p80211enum_t MKENUMNAME(ifstate); +extern p80211enum_t MKENUMNAME(powermgmt); +extern p80211enum_t MKENUMNAME(bsstype); +extern p80211enum_t MKENUMNAME(authalg); +extern p80211enum_t MKENUMNAME(phytype); +extern p80211enum_t MKENUMNAME(temptype); +extern p80211enum_t MKENUMNAME(regdomain); +extern p80211enum_t MKENUMNAME(ccamode); +extern p80211enum_t MKENUMNAME(diversity); +extern p80211enum_t MKENUMNAME(scantype); +extern p80211enum_t MKENUMNAME(resultcode); +extern p80211enum_t MKENUMNAME(reason); +extern p80211enum_t MKENUMNAME(status); +extern p80211enum_t MKENUMNAME(msgcode); +extern p80211enum_t MKENUMNAME(msgitem_status); + +extern p80211enum_t MKENUMNAME(lnxroam_reason); + +extern p80211enum_t MKENUMNAME(p2preamble); + +/*================================================================*/ +/* Function Declarations */ + +/*----------------------------------------------------------------*/ +/* The following declare some utility functions for use with the */ +/* p80211enum_t type. */ + +UINT32 p80211enum_text2int(p80211enum_t *ep, char *text); +UINT32 p80211enum_int2text(p80211enum_t *ep, UINT32 val, char *text); +void p80211_error2text(int err_code, char *err_str); + +/*----------------------------------------------------------------*/ +/* The following declare some utility functions for use with the */ +/* p80211item_t and p80211meta_t types. */ + +/*----------------------------------------------------------------*/ +/* The following declare functions that perform validation and */ +/* text to binary conversions based on the metadata for interface */ +/* and MIB data items. */ +/*----------------------------------------------------------------*/ + +/*-- DISPLAYSTR ------------------------------------------------------*/ +/* pstr ==> cstr */ +void p80211_totext_displaystr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* cstr ==> pstr */ +void p80211_fromtext_displaystr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* function that checks validity of a displaystr binary value */ +UINT32 p80211_isvalid_displaystr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf ); + +/*-- OCTETSTR --------------------------------------------------------*/ +/* pstr ==> "xx:xx:...." */ +void p80211_totext_octetstr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* "xx:xx:...." ==> pstr */ +void p80211_fromtext_octetstr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* function that checks validity of an octetstr binary value */ +UINT32 p80211_isvalid_octetstr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf ); + +/*-- INT -------------------------------------------------------------*/ +/* UINT32 ==> %d */ +void p80211_totext_int( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* %d ==> UINT32 */ +void p80211_fromtext_int( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* function that checks validity of an int's binary value (always successful) */ +UINT32 p80211_isvalid_int( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf ); + +/*-- ENUMINT ---------------------------------------------------------*/ +/* UINT32 ==> */ +void p80211_totext_enumint( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* ==> UINT32 */ +void p80211_fromtext_enumint( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* function that checks validity of an enum's binary value */ +UINT32 p80211_isvalid_enumint( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf ); + +/*-- INTARRAY --------------------------------------------------------*/ +/* UINT32[] => %d,%d,%d,... */ +void p80211_totext_intarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* %d,%d,%d,... ==> UINT32[] */ +void p80211_fromtext_intarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* function that checks validity of an integer array's value */ +UINT32 p80211_isvalid_intarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf ); + +/*-- BITARRAY --------------------------------------------------------*/ +/* UINT32 ==> %d,%d,%d,... */ +void p80211_totext_bitarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* %d,%d,%d,... ==> UINT32 */ +void p80211_fromtext_bitarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* function that checks validity of a bit array's value */ +UINT32 p80211_isvalid_bitarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf ); + +/*-- MACARRAY --------------------------------------------------------*/ +void p80211_totext_macarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +void p80211_fromtext_macarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* function that checks validity of a MAC address array's value */ +UINT32 p80211_isvalid_macarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf ); + +/*-- MIBATTRIUBTE ------------------------------------------------------*/ +/* ==> */ +void p80211_totext_getmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); +void p80211_totext_setmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + + +/* ==> */ +void p80211_fromtext_getmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); +void p80211_fromtext_setmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* function that checks validity of a mibitem's binary value */ +UINT32 p80211_isvalid_getmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf ); +UINT32 p80211_isvalid_setmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf ); + +#endif /* _P80211TYPES_H */ + --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211metadef.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211metadef.h @@ -0,0 +1,2524 @@ +/* This file is GENERATED AUTOMATICALLY. DO NOT EDIT OR MODIFY. +* -------------------------------------------------------------------- +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +*/ + +#ifndef _P80211MKMETADEF_H +#define _P80211MKMETADEF_H + + +#define DIDmsg_cat_dot11req \ + P80211DID_MKSECTION(1) +#define DIDmsg_dot11req_mibget \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(1)) +#define DIDmsg_dot11req_mibget_mibattribute \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_mibget_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_mibset \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2)) +#define DIDmsg_dot11req_mibset_mibattribute \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_mibset_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_powermgmt \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3)) +#define DIDmsg_dot11req_powermgmt_powermgmtmode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_powermgmt_wakeup \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_powermgmt_receivedtims \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_dot11req_powermgmt_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_dot11req_scan \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4)) +#define DIDmsg_dot11req_scan_bsstype \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_scan_bssid \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_scan_ssid \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_dot11req_scan_scantype \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_dot11req_scan_probedelay \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_dot11req_scan_channellist \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(6) | 0x00000000) +#define DIDmsg_dot11req_scan_minchanneltime \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(7) | 0x00000000) +#define DIDmsg_dot11req_scan_maxchanneltime \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(8) | 0x00000000) +#define DIDmsg_dot11req_scan_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(9) | 0x00000000) +#define DIDmsg_dot11req_scan_numbss \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(10) | 0x00000000) +#define DIDmsg_dot11req_scan_append \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(11) | 0x00000000) +#define DIDmsg_dot11req_scan_results \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5)) +#define DIDmsg_dot11req_scan_results_bssindex \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_scan_results_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_scan_results_signal \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_dot11req_scan_results_noise \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_dot11req_scan_results_bssid \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_dot11req_scan_results_ssid \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(6) | 0x00000000) +#define DIDmsg_dot11req_scan_results_bsstype \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(7) | 0x00000000) +#define DIDmsg_dot11req_scan_results_beaconperiod \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(8) | 0x00000000) +#define DIDmsg_dot11req_scan_results_dtimperiod \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(9) | 0x00000000) +#define DIDmsg_dot11req_scan_results_timestamp \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(10) | 0x00000000) +#define DIDmsg_dot11req_scan_results_localtime \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(11) | 0x00000000) +#define DIDmsg_dot11req_scan_results_fhdwelltime \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(12) | 0x00000000) +#define DIDmsg_dot11req_scan_results_fhhopset \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(13) | 0x00000000) +#define DIDmsg_dot11req_scan_results_fhhoppattern \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(14) | 0x00000000) +#define DIDmsg_dot11req_scan_results_fhhopindex \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(15) | 0x00000000) +#define DIDmsg_dot11req_scan_results_dschannel \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(16) | 0x00000000) +#define DIDmsg_dot11req_scan_results_cfpcount \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(17) | 0x00000000) +#define DIDmsg_dot11req_scan_results_cfpperiod \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(18) | 0x00000000) +#define DIDmsg_dot11req_scan_results_cfpmaxduration \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(19) | 0x00000000) +#define DIDmsg_dot11req_scan_results_cfpdurremaining \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(20) | 0x00000000) +#define DIDmsg_dot11req_scan_results_ibssatimwindow \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(21) | 0x00000000) +#define DIDmsg_dot11req_scan_results_cfpollable \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(22) | 0x00000000) +#define DIDmsg_dot11req_scan_results_cfpollreq \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(23) | 0x00000000) +#define DIDmsg_dot11req_scan_results_privacy \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(24) | 0x00000000) +#define DIDmsg_dot11req_scan_results_basicrate1 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(25) | 0x00000000) +#define DIDmsg_dot11req_scan_results_basicrate2 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(26) | 0x00000000) +#define DIDmsg_dot11req_scan_results_basicrate3 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(27) | 0x00000000) +#define DIDmsg_dot11req_scan_results_basicrate4 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(28) | 0x00000000) +#define DIDmsg_dot11req_scan_results_basicrate5 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(29) | 0x00000000) +#define DIDmsg_dot11req_scan_results_basicrate6 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(30) | 0x00000000) +#define DIDmsg_dot11req_scan_results_basicrate7 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(31) | 0x00000000) +#define DIDmsg_dot11req_scan_results_basicrate8 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(32) | 0x00000000) +#define DIDmsg_dot11req_scan_results_supprate1 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(33) | 0x00000000) +#define DIDmsg_dot11req_scan_results_supprate2 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(34) | 0x00000000) +#define DIDmsg_dot11req_scan_results_supprate3 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(35) | 0x00000000) +#define DIDmsg_dot11req_scan_results_supprate4 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(36) | 0x00000000) +#define DIDmsg_dot11req_scan_results_supprate5 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(37) | 0x00000000) +#define DIDmsg_dot11req_scan_results_supprate6 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(38) | 0x00000000) +#define DIDmsg_dot11req_scan_results_supprate7 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(39) | 0x00000000) +#define DIDmsg_dot11req_scan_results_supprate8 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(40) | 0x00000000) +#define DIDmsg_dot11req_join \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6)) +#define DIDmsg_dot11req_join_bssid \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_join_joinfailuretimeout \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_join_basicrate1 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_dot11req_join_basicrate2 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_dot11req_join_basicrate3 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_dot11req_join_basicrate4 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(6) | 0x00000000) +#define DIDmsg_dot11req_join_basicrate5 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(7) | 0x00000000) +#define DIDmsg_dot11req_join_basicrate6 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(8) | 0x00000000) +#define DIDmsg_dot11req_join_basicrate7 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(9) | 0x00000000) +#define DIDmsg_dot11req_join_basicrate8 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(10) | 0x00000000) +#define DIDmsg_dot11req_join_operationalrate1 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(11) | 0x00000000) +#define DIDmsg_dot11req_join_operationalrate2 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(12) | 0x00000000) +#define DIDmsg_dot11req_join_operationalrate3 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(13) | 0x00000000) +#define DIDmsg_dot11req_join_operationalrate4 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(14) | 0x00000000) +#define DIDmsg_dot11req_join_operationalrate5 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(15) | 0x00000000) +#define DIDmsg_dot11req_join_operationalrate6 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(16) | 0x00000000) +#define DIDmsg_dot11req_join_operationalrate7 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(17) | 0x00000000) +#define DIDmsg_dot11req_join_operationalrate8 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(18) | 0x00000000) +#define DIDmsg_dot11req_join_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(19) | 0x00000000) +#define DIDmsg_dot11req_authenticate \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(7)) +#define DIDmsg_dot11req_authenticate_peerstaaddress \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_authenticate_authenticationtype \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_authenticate_authenticationfailuretimeout \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_dot11req_authenticate_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_dot11req_deauthenticate \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(8)) +#define DIDmsg_dot11req_deauthenticate_peerstaaddress \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_deauthenticate_reasoncode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_deauthenticate_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_dot11req_associate \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(9)) +#define DIDmsg_dot11req_associate_peerstaaddress \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(9) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_associate_associatefailuretimeout \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(9) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_associate_cfpollable \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(9) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_dot11req_associate_cfpollreq \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(9) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_dot11req_associate_privacy \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(9) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_dot11req_associate_listeninterval \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(9) | \ + P80211DID_MKITEM(6) | 0x00000000) +#define DIDmsg_dot11req_associate_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(9) | \ + P80211DID_MKITEM(7) | 0x00000000) +#define DIDmsg_dot11req_reassociate \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(10)) +#define DIDmsg_dot11req_reassociate_newapaddress \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(10) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_reassociate_reassociatefailuretimeout \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(10) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_reassociate_cfpollable \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(10) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_dot11req_reassociate_cfpollreq \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(10) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_dot11req_reassociate_privacy \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(10) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_dot11req_reassociate_listeninterval \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(10) | \ + P80211DID_MKITEM(6) | 0x00000000) +#define DIDmsg_dot11req_reassociate_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(10) | \ + P80211DID_MKITEM(7) | 0x00000000) +#define DIDmsg_dot11req_disassociate \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(11)) +#define DIDmsg_dot11req_disassociate_peerstaaddress \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(11) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_disassociate_reasoncode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(11) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_disassociate_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(11) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_dot11req_reset \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(12)) +#define DIDmsg_dot11req_reset_setdefaultmib \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(12) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_reset_macaddress \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(12) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_reset_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(12) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_dot11req_start \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13)) +#define DIDmsg_dot11req_start_ssid \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_start_bsstype \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_start_beaconperiod \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_dot11req_start_dtimperiod \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_dot11req_start_cfpperiod \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_dot11req_start_cfpmaxduration \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(6) | 0x00000000) +#define DIDmsg_dot11req_start_fhdwelltime \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(7) | 0x00000000) +#define DIDmsg_dot11req_start_fhhopset \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(8) | 0x00000000) +#define DIDmsg_dot11req_start_fhhoppattern \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(9) | 0x00000000) +#define DIDmsg_dot11req_start_dschannel \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(10) | 0x00000000) +#define DIDmsg_dot11req_start_ibssatimwindow \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(11) | 0x00000000) +#define DIDmsg_dot11req_start_probedelay \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(12) | 0x00000000) +#define DIDmsg_dot11req_start_cfpollable \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(13) | 0x00000000) +#define DIDmsg_dot11req_start_cfpollreq \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(14) | 0x00000000) +#define DIDmsg_dot11req_start_basicrate1 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(15) | 0x00000000) +#define DIDmsg_dot11req_start_basicrate2 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(16) | 0x00000000) +#define DIDmsg_dot11req_start_basicrate3 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(17) | 0x00000000) +#define DIDmsg_dot11req_start_basicrate4 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(18) | 0x00000000) +#define DIDmsg_dot11req_start_basicrate5 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(19) | 0x00000000) +#define DIDmsg_dot11req_start_basicrate6 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(20) | 0x00000000) +#define DIDmsg_dot11req_start_basicrate7 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(21) | 0x00000000) +#define DIDmsg_dot11req_start_basicrate8 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(22) | 0x00000000) +#define DIDmsg_dot11req_start_operationalrate1 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(23) | 0x00000000) +#define DIDmsg_dot11req_start_operationalrate2 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(24) | 0x00000000) +#define DIDmsg_dot11req_start_operationalrate3 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(25) | 0x00000000) +#define DIDmsg_dot11req_start_operationalrate4 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(26) | 0x00000000) +#define DIDmsg_dot11req_start_operationalrate5 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(27) | 0x00000000) +#define DIDmsg_dot11req_start_operationalrate6 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(28) | 0x00000000) +#define DIDmsg_dot11req_start_operationalrate7 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(29) | 0x00000000) +#define DIDmsg_dot11req_start_operationalrate8 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(30) | 0x00000000) +#define DIDmsg_dot11req_start_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(31) | 0x00000000) +#define DIDmsg_cat_dot11ind \ + P80211DID_MKSECTION(2) +#define DIDmsg_dot11ind_authenticate \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1)) +#define DIDmsg_dot11ind_authenticate_peerstaaddress \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11ind_authenticate_authenticationtype \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11ind_deauthenticate \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2)) +#define DIDmsg_dot11ind_deauthenticate_peerstaaddress \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11ind_deauthenticate_reasoncode \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11ind_associate \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3)) +#define DIDmsg_dot11ind_associate_peerstaaddress \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11ind_associate_aid \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11ind_reassociate \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(4)) +#define DIDmsg_dot11ind_reassociate_peerstaaddress \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11ind_reassociate_aid \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11ind_reassociate_oldapaddress \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_dot11ind_disassociate \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(5)) +#define DIDmsg_dot11ind_disassociate_peerstaaddress \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11ind_disassociate_reasoncode \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_cat_lnxreq \ + P80211DID_MKSECTION(3) +#define DIDmsg_lnxreq_ifstate \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(1)) +#define DIDmsg_lnxreq_ifstate_ifstate \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_lnxreq_ifstate_resultcode \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_lnxreq_wlansniff \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2)) +#define DIDmsg_lnxreq_wlansniff_enable \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_lnxreq_wlansniff_channel \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_lnxreq_wlansniff_prismheader \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_lnxreq_wlansniff_wlanheader \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_lnxreq_wlansniff_keepwepflags \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_lnxreq_wlansniff_stripfcs \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(6) | 0x00000000) +#define DIDmsg_lnxreq_wlansniff_packet_trunc \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(7) | 0x00000000) +#define DIDmsg_lnxreq_wlansniff_resultcode \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(8) | 0x00000000) +#define DIDmsg_lnxreq_hostwep \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3)) +#define DIDmsg_lnxreq_hostwep_resultcode \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_lnxreq_hostwep_decrypt \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_lnxreq_hostwep_encrypt \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_lnxreq_commsquality \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4)) +#define DIDmsg_lnxreq_commsquality_resultcode \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_lnxreq_commsquality_dbm \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_lnxreq_commsquality_link \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_lnxreq_commsquality_level \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_lnxreq_commsquality_noise \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_lnxreq_autojoin \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(5)) +#define DIDmsg_lnxreq_autojoin_ssid \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_lnxreq_autojoin_authtype \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_lnxreq_autojoin_resultcode \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_cat_lnxind \ + P80211DID_MKSECTION(4) +#define DIDmsg_lnxind_wlansniffrm \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1)) +#define DIDmsg_lnxind_wlansniffrm_hosttime \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_lnxind_wlansniffrm_mactime \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_lnxind_wlansniffrm_channel \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_lnxind_wlansniffrm_rssi \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_lnxind_wlansniffrm_sq \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_lnxind_wlansniffrm_signal \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(6) | 0x00000000) +#define DIDmsg_lnxind_wlansniffrm_noise \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(7) | 0x00000000) +#define DIDmsg_lnxind_wlansniffrm_rate \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(8) | 0x00000000) +#define DIDmsg_lnxind_wlansniffrm_istx \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(9) | 0x00000000) +#define DIDmsg_lnxind_wlansniffrm_frmlen \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(10) | 0x00000000) +#define DIDmsg_lnxind_roam \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(2)) +#define DIDmsg_lnxind_roam_reason \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_cat_p2req \ + P80211DID_MKSECTION(5) +#define DIDmsg_p2req_join \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1)) +#define DIDmsg_p2req_join_bssid \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_join_basicrate1 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_join_basicrate2 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_p2req_join_basicrate3 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_p2req_join_basicrate4 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_p2req_join_basicrate5 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(6) | 0x00000000) +#define DIDmsg_p2req_join_basicrate6 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(7) | 0x00000000) +#define DIDmsg_p2req_join_basicrate7 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(8) | 0x00000000) +#define DIDmsg_p2req_join_basicrate8 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(9) | 0x00000000) +#define DIDmsg_p2req_join_operationalrate1 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(10) | 0x00000000) +#define DIDmsg_p2req_join_operationalrate2 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(11) | 0x00000000) +#define DIDmsg_p2req_join_operationalrate3 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(12) | 0x00000000) +#define DIDmsg_p2req_join_operationalrate4 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(13) | 0x00000000) +#define DIDmsg_p2req_join_operationalrate5 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(14) | 0x00000000) +#define DIDmsg_p2req_join_operationalrate6 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(15) | 0x00000000) +#define DIDmsg_p2req_join_operationalrate7 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(16) | 0x00000000) +#define DIDmsg_p2req_join_operationalrate8 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(17) | 0x00000000) +#define DIDmsg_p2req_join_ssid \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(18) | 0x00000000) +#define DIDmsg_p2req_join_channel \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(19) | 0x00000000) +#define DIDmsg_p2req_join_authtype \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(20) | 0x00000000) +#define DIDmsg_p2req_join_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(21) | 0x00000000) +#define DIDmsg_p2req_readpda \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2)) +#define DIDmsg_p2req_readpda_pda \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_readpda_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_readcis \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3)) +#define DIDmsg_p2req_readcis_cis \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_readcis_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_auxport_state \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(4)) +#define DIDmsg_p2req_auxport_state_enable \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_auxport_state_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_auxport_read \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5)) +#define DIDmsg_p2req_auxport_read_addr \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_auxport_read_len \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_auxport_read_data \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_p2req_auxport_read_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_p2req_auxport_write \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6)) +#define DIDmsg_p2req_auxport_write_addr \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_auxport_write_len \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_auxport_write_data \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_p2req_auxport_write_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_p2req_low_level \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7)) +#define DIDmsg_p2req_low_level_command \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_low_level_param0 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_low_level_param1 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_p2req_low_level_param2 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_p2req_low_level_resp0 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_p2req_low_level_resp1 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(6) | 0x00000000) +#define DIDmsg_p2req_low_level_resp2 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(7) | 0x00000000) +#define DIDmsg_p2req_low_level_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(8) | 0x00000000) +#define DIDmsg_p2req_test_command \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(8)) +#define DIDmsg_p2req_test_command_testcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_test_command_testparam \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_test_command_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_p2req_test_command_status \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_p2req_test_command_resp0 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_p2req_test_command_resp1 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(6) | 0x00000000) +#define DIDmsg_p2req_test_command_resp2 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(7) | 0x00000000) +#define DIDmsg_p2req_mmi_read \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(9)) +#define DIDmsg_p2req_mmi_read_addr \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(9) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_mmi_read_value \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(9) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_mmi_read_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(9) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_p2req_mmi_write \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(10)) +#define DIDmsg_p2req_mmi_write_addr \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(10) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_mmi_write_data \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(10) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_mmi_write_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(10) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_p2req_ramdl_state \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(11)) +#define DIDmsg_p2req_ramdl_state_enable \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(11) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_ramdl_state_exeaddr \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(11) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_ramdl_state_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(11) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_p2req_ramdl_write \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(12)) +#define DIDmsg_p2req_ramdl_write_addr \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(12) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_ramdl_write_len \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(12) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_ramdl_write_data \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(12) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_p2req_ramdl_write_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(12) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_p2req_flashdl_state \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(13)) +#define DIDmsg_p2req_flashdl_state_enable \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_flashdl_state_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_flashdl_write \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(14)) +#define DIDmsg_p2req_flashdl_write_addr \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(14) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_flashdl_write_len \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(14) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_flashdl_write_data \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(14) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_p2req_flashdl_write_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(14) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_p2req_mm_state \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(15)) +#define DIDmsg_p2req_mm_state_enable \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(15) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_mm_state_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(15) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_dump_state \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(16)) +#define DIDmsg_p2req_dump_state_level \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(16) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_dump_state_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(16) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_channel_info \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(17)) +#define DIDmsg_p2req_channel_info_channellist \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(17) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_channel_info_channeldwelltime \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(17) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_channel_info_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(17) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_p2req_channel_info_numchinfo \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(17) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_p2req_channel_info_results \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(18)) +#define DIDmsg_p2req_channel_info_results_channel \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(18) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_channel_info_results_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(18) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_channel_info_results_avgnoiselevel \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(18) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_p2req_channel_info_results_peaknoiselevel \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(18) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_p2req_channel_info_results_bssactive \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(18) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_p2req_channel_info_results_pcfactive \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(18) | \ + P80211DID_MKITEM(6) | 0x00000000) +#define DIDmsg_p2req_enable \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(19)) +#define DIDmsg_p2req_enable_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(19) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmib_cat_dot11smt \ + P80211DID_MKSECTION(1) +#define DIDmib_dot11smt_p80211Table \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(1)) +#define DIDmib_dot11smt_p80211Table_p80211_ifstate \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(1) | 0x10000000) +#define DIDmib_dot11smt_dot11StationConfigTable \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2)) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11StationID \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(1) | 0x18000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11MediumOccupancyLimit \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(2) | 0x18000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11CFPollable \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(3) | 0x10000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11CFPPeriod \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(4) | 0x18000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11CFPMaxDuration \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(5) | 0x18000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11AuthenticationResponseTimeOut \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(6) | 0x18000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11PrivacyOptionImplemented \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(7) | 0x10000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11PowerManagementMode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(8) | 0x18000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11DesiredSSID \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(9) | 0x18000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11DesiredBSSType \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(10) | 0x18000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11OperationalRateSet \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(11) | 0x18000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11BeaconPeriod \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(12) | 0x18000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11DTIMPeriod \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(13) | 0x18000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11AssociationResponseTimeOut \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(14) | 0x10000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11DisassociateReason \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(15) | 0x10000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11DisassociateStation \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(16) | 0x10000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11DeauthenticateReason \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(17) | 0x10000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11DeauthenticateStation \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(18) | 0x10000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11AuthenticateFailStatus \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(19) | 0x10000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11AuthenticateFailStation \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(20) | 0x10000000) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3)) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm1 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(1) | 0x14000000) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable1 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(2) | 0x1c000000) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm2 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(3) | 0x14000000) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable2 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(4) | 0x1c000000) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm3 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(5) | 0x14000000) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable3 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(6) | 0x1c000000) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm4 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(7) | 0x14000000) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable4 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(8) | 0x1c000000) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm5 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(9) | 0x14000000) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable5 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(10) | 0x1c000000) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm6 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(11) | 0x14000000) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable6 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(12) | 0x1c000000) +#define DIDmib_dot11smt_dot11WEPDefaultKeysTable \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4)) +#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(1) | 0x0c000000) +#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(2) | 0x0c000000) +#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(3) | 0x0c000000) +#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(4) | 0x0c000000) +#define DIDmib_dot11smt_dot11WEPKeyMappingsTable \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5)) +#define DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingIndex \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(1) | 0x1c000000) +#define DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingAddress \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(2) | 0x1c000000) +#define DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingWEPOn \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(3) | 0x1c000000) +#define DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingValue \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(4) | 0x1c000000) +#define DIDmib_dot11smt_dot11PrivacyTable \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6)) +#define DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(1) | 0x18000000) +#define DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(2) | 0x18000000) +#define DIDmib_dot11smt_dot11PrivacyTable_dot11WEPKeyMappingLength \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(3) | 0x18000000) +#define DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(4) | 0x18000000) +#define DIDmib_dot11smt_dot11PrivacyTable_dot11WEPICVErrorCount \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(5) | 0x10000000) +#define DIDmib_dot11smt_dot11PrivacyTable_dot11WEPExcludedCount \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(6) | 0x10000000) +#define DIDmib_cat_dot11mac \ + P80211DID_MKSECTION(2) +#define DIDmib_dot11mac_dot11OperationTable \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1)) +#define DIDmib_dot11mac_dot11OperationTable_dot11MACAddress \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(1) | 0x18000000) +#define DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(2) | 0x18000000) +#define DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(3) | 0x10000000) +#define DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(4) | 0x10000000) +#define DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(5) | 0x18000000) +#define DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(6) | 0x10000000) +#define DIDmib_dot11mac_dot11OperationTable_dot11MaxReceiveLifetime \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(7) | 0x10000000) +#define DIDmib_dot11mac_dot11OperationTable_dot11ManufacturerID \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(8) | 0x10000000) +#define DIDmib_dot11mac_dot11OperationTable_dot11ProductID \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(9) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2)) +#define DIDmib_dot11mac_dot11CountersTable_dot11TransmittedFragmentCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(1) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11MulticastTransmittedFrameCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(2) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11FailedCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(3) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11RetryCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(4) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11MultipleRetryCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(5) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11FrameDuplicateCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(6) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11RTSSuccessCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(7) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11RTSFailureCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(8) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11ACKFailureCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(9) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11ReceivedFragmentCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(10) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11MulticastReceivedFrameCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(11) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11FCSErrorCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(12) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11TransmittedFrameCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(13) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11WEPUndecryptableCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(14) | 0x10000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3)) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address1 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(1) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address2 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(2) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address3 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(3) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address4 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(4) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address5 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(5) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address6 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(6) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address7 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(7) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address8 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(8) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address9 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(9) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address10 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(10) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address11 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(11) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address12 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(12) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address13 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(13) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address14 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(14) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address15 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(15) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address16 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(16) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address17 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(17) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address18 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(18) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address19 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(19) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address20 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(20) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address21 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(21) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address22 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(22) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address23 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(23) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address24 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(24) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address25 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(25) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address26 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(26) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address27 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(27) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address28 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(28) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address29 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(29) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address30 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(30) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address31 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(31) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address32 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(32) | 0x1c000000) +#define DIDmib_cat_dot11phy \ + P80211DID_MKSECTION(3) +#define DIDmib_dot11phy_dot11PhyOperationTable \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(1)) +#define DIDmib_dot11phy_dot11PhyOperationTable_dot11PHYType \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(1) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyOperationTable_dot11CurrentRegDomain \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(2) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyOperationTable_dot11TempType \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(3) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyOperationTable_dot11ChannelAgilityPresent \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(4) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyOperationTable_dot11ChannelAgilityEnabled \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(5) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyOperationTable_dot11ShortPreambleEnabled \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(6) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyAntennaTable \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2)) +#define DIDmib_dot11phy_dot11PhyAntennaTable_dot11CurrentTxAntenna \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(1) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyAntennaTable_dot11DiversitySupport \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(2) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyAntennaTable_dot11CurrentRxAntenna \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(3) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyTxPowerTable \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3)) +#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11NumberSupportedPowerLevels \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(1) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel1 \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(2) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel2 \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(3) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel3 \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(4) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel4 \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(5) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel5 \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(6) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel6 \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(7) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel7 \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(8) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel8 \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(9) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(10) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyFHSSTable \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4)) +#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11HopTime \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(1) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentChannelNumber \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(2) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11MaxDwellTime \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(3) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentDwellTime \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(4) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentSet \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(5) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentPattern \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(6) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentIndex \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(7) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyDSSSTable \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(5)) +#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(1) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11CCAModeSupported \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(2) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentCCAMode \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(3) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11EDThreshold \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(4) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11ShortPreambleOptionImplemented \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(5) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11PBCCOptionImplemented \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(6) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyIRTable \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(6)) +#define DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogTimerMax \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(1) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogCountMax \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(2) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogTimerMin \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(3) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogCountMin \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(4) | 0x18000000) +#define DIDmib_dot11phy_dot11RegDomainsSupportedTable \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(7)) +#define DIDmib_dot11phy_dot11RegDomainsSupportedTable_dot11RegDomainsSupportIndex \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(1) | 0x1c000000) +#define DIDmib_dot11phy_dot11RegDomainsSupportedTable_dot11RegDomainsSupportValue \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(2) | 0x14000000) +#define DIDmib_dot11phy_dot11AntennasListTable \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(8)) +#define DIDmib_dot11phy_dot11AntennasListTable_dot11AntennaListIndex \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(1) | 0x1c000000) +#define DIDmib_dot11phy_dot11AntennasListTable_dot11SupportedTxAntenna \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(2) | 0x1c000000) +#define DIDmib_dot11phy_dot11AntennasListTable_dot11SupportedRxAntenna \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(3) | 0x1c000000) +#define DIDmib_dot11phy_dot11AntennasListTable_dot11DiversitySelectionRx \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(4) | 0x1c000000) +#define DIDmib_dot11phy_dot11SupportedDataRatesTxTable \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(9)) +#define DIDmib_dot11phy_dot11SupportedDataRatesTxTable_dot11SupportedDataRatesTxIndex \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(9) | \ + P80211DID_MKITEM(1) | 0x1c000000) +#define DIDmib_dot11phy_dot11SupportedDataRatesTxTable_dot11SupportedDataRatesTxValue \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(9) | \ + P80211DID_MKITEM(2) | 0x14000000) +#define DIDmib_dot11phy_dot11SupportedDataRatesRxTable \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(10)) +#define DIDmib_dot11phy_dot11SupportedDataRatesRxTable_dot11SupportedDataRatesRxIndex \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(10) | \ + P80211DID_MKITEM(1) | 0x1c000000) +#define DIDmib_dot11phy_dot11SupportedDataRatesRxTable_dot11SupportedDataRatesRxValue \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(10) | \ + P80211DID_MKITEM(2) | 0x14000000) +#define DIDmib_cat_lnx \ + P80211DID_MKSECTION(4) +#define DIDmib_lnx_lnxConfigTable \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1)) +#define DIDmib_lnx_lnxConfigTable_lnxRSNAIE \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(1) | 0x18000000) +#define DIDmib_cat_p2 \ + P80211DID_MKSECTION(5) +#define DIDmib_p2_p2Table \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1)) +#define DIDmib_p2_p2Table_p2MMTx \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(1) | 0x18000000) +#define DIDmib_p2_p2Table_p2EarlyBeacon \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(2) | 0x18000000) +#define DIDmib_p2_p2Table_p2ReceivedFrameStatistics \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(3) | 0x10000000) +#define DIDmib_p2_p2Table_p2CommunicationTallies \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(4) | 0x10000000) +#define DIDmib_p2_p2Table_p2Authenticated \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(5) | 0x10000000) +#define DIDmib_p2_p2Table_p2Associated \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(6) | 0x10000000) +#define DIDmib_p2_p2Table_p2PowerSaveUserCount \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(7) | 0x10000000) +#define DIDmib_p2_p2Table_p2Comment \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(8) | 0x18000000) +#define DIDmib_p2_p2Table_p2AccessMode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(9) | 0x18000000) +#define DIDmib_p2_p2Table_p2AccessAllow \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(10) | 0x18000000) +#define DIDmib_p2_p2Table_p2AccessDeny \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(11) | 0x18000000) +#define DIDmib_p2_p2Table_p2ChannelInfoResults \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(12) | 0x10000000) +#define DIDmib_p2_p2Static \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2)) +#define DIDmib_p2_p2Static_p2CnfPortType \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(1) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfOwnMACAddress \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(2) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfDesiredSSID \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(3) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfOwnChannel \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(4) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfOwnSSID \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(5) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfOwnATIMWindow \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(6) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfSystemScale \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(7) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfMaxDataLength \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(8) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfWDSAddress \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(9) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfPMEnabled \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(10) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfPMEPS \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(11) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfMulticastReceive \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(12) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfMaxSleepDuration \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(13) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfPMHoldoverDuration \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(14) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfOwnName \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(15) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfOwnDTIMPeriod \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(16) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfWDSAddress1 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(17) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfWDSAddress2 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(18) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfWDSAddress3 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(19) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfWDSAddress4 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(20) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfWDSAddress5 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(21) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfWDSAddress6 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(22) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfMulticastPMBuffering \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(23) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfWEPDefaultKeyID \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(24) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfWEPDefaultKey0 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(25) | 0x08000000) +#define DIDmib_p2_p2Static_p2CnfWEPDefaultKey1 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(26) | 0x08000000) +#define DIDmib_p2_p2Static_p2CnfWEPDefaultKey2 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(27) | 0x08000000) +#define DIDmib_p2_p2Static_p2CnfWEPDefaultKey3 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(28) | 0x08000000) +#define DIDmib_p2_p2Static_p2CnfWEPFlags \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(29) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfAuthentication \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(30) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfMaxAssociatedStations \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(31) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfTxControl \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(32) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfRoamingMode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(33) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfHostAuthentication \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(34) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfRcvCrcError \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(35) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfAltRetryCount \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(36) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfBeaconInterval \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(37) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfMediumOccupancyLimit \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(38) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfCFPPeriod \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(39) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfCFPMaxDuration \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(40) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfCFPFlags \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(41) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfSTAPCFInfo \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(42) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfPriorityQUsage \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(43) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfTIMCtrl \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(44) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfThirty2Tally \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(45) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfEnhSecurity \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(46) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfShortPreamble \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(47) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfExcludeLongPreamble \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(48) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfAuthenticationRspTO \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(49) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfBasicRates \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(50) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfSupportedRates \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(51) | 0x18000000) +#define DIDmib_p2_p2Dynamic \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3)) +#define DIDmib_p2_p2Dynamic_p2CreateIBSS \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(1) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(2) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2RTSThreshold \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(3) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2TxRateControl \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(4) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2PromiscuousMode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(5) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold0 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(6) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold1 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(7) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold2 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(8) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold3 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(9) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold4 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(10) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold5 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(11) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold6 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(12) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2RTSThreshold0 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(13) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2RTSThreshold1 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(14) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2RTSThreshold2 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(15) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2RTSThreshold3 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(16) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2RTSThreshold4 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(17) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2RTSThreshold5 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(18) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2RTSThreshold6 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(19) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2TxRateControl0 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(20) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2TxRateControl1 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(21) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2TxRateControl2 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(22) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2TxRateControl3 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(23) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2TxRateControl4 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(24) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2TxRateControl5 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(25) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2TxRateControl6 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(26) | 0x18000000) +#define DIDmib_p2_p2Behavior \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(4)) +#define DIDmib_p2_p2Behavior_p2TickTime \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(1) | 0x18000000) +#define DIDmib_p2_p2NIC \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5)) +#define DIDmib_p2_p2NIC_p2MaxLoadTime \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(1) | 0x10000000) +#define DIDmib_p2_p2NIC_p2DLBufferPage \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(2) | 0x10000000) +#define DIDmib_p2_p2NIC_p2DLBufferOffset \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(3) | 0x10000000) +#define DIDmib_p2_p2NIC_p2DLBufferLength \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(4) | 0x10000000) +#define DIDmib_p2_p2NIC_p2PRIIdentity \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(5) | 0x10000000) +#define DIDmib_p2_p2NIC_p2PRISupRange \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(6) | 0x10000000) +#define DIDmib_p2_p2NIC_p2CFIActRanges \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(7) | 0x10000000) +#define DIDmib_p2_p2NIC_p2NICSerialNumber \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(8) | 0x10000000) +#define DIDmib_p2_p2NIC_p2NICIdentity \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(9) | 0x10000000) +#define DIDmib_p2_p2NIC_p2MFISupRange \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(10) | 0x10000000) +#define DIDmib_p2_p2NIC_p2CFISupRange \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(11) | 0x10000000) +#define DIDmib_p2_p2NIC_p2ChannelList \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(12) | 0x10000000) +#define DIDmib_p2_p2NIC_p2RegulatoryDomains \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(13) | 0x10000000) +#define DIDmib_p2_p2NIC_p2TempType \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(14) | 0x10000000) +#define DIDmib_p2_p2NIC_p2STAIdentity \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(15) | 0x10000000) +#define DIDmib_p2_p2NIC_p2STASupRange \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(16) | 0x10000000) +#define DIDmib_p2_p2NIC_p2MFIActRanges \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(17) | 0x10000000) +#define DIDmib_p2_p2NIC_p2STACFIActRanges \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(18) | 0x10000000) +#define DIDmib_p2_p2NIC_p2BuildSequence \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(19) | 0x10000000) +#define DIDmib_p2_p2NIC_p2PrimaryFWID \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(20) | 0x10000000) +#define DIDmib_p2_p2NIC_p2SecondaryFWID \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(21) | 0x10000000) +#define DIDmib_p2_p2NIC_p2TertiaryFWID \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(22) | 0x10000000) +#define DIDmib_p2_p2MAC \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6)) +#define DIDmib_p2_p2MAC_p2PortStatus \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(1) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CurrentSSID \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(2) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CurrentBSSID \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(3) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CommsQuality \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(4) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CommsQualityCQ \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(5) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CommsQualityASL \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(6) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CommsQualityANL \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(7) | 0x10000000) +#define DIDmib_p2_p2MAC_p2dbmCommsQuality \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(8) | 0x10000000) +#define DIDmib_p2_p2MAC_p2dbmCommsQualityCQ \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(9) | 0x10000000) +#define DIDmib_p2_p2MAC_p2dbmCommsQualityASL \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(10) | 0x10000000) +#define DIDmib_p2_p2MAC_p2dbmCommsQualityANL \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(11) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CurrentTxRate \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(12) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CurrentBeaconInterval \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(13) | 0x10000000) +#define DIDmib_p2_p2MAC_p2StaCurrentScaleThresholds \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(14) | 0x10000000) +#define DIDmib_p2_p2MAC_p2APCurrentScaleThresholds \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(15) | 0x10000000) +#define DIDmib_p2_p2MAC_p2ProtocolRspTime \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(16) | 0x10000000) +#define DIDmib_p2_p2MAC_p2ShortRetryLimit \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(17) | 0x10000000) +#define DIDmib_p2_p2MAC_p2LongRetryLimit \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(18) | 0x10000000) +#define DIDmib_p2_p2MAC_p2MaxTransmitLifetime \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(19) | 0x10000000) +#define DIDmib_p2_p2MAC_p2MaxReceiveLifetime \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(20) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CFPollable \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(21) | 0x10000000) +#define DIDmib_p2_p2MAC_p2AuthenticationAlgorithms \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(22) | 0x10000000) +#define DIDmib_p2_p2MAC_p2PrivacyOptionImplemented \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(23) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CurrentTxRate1 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(24) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CurrentTxRate2 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(25) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CurrentTxRate3 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(26) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CurrentTxRate4 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(27) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CurrentTxRate5 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(28) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CurrentTxRate6 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(29) | 0x10000000) +#define DIDmib_p2_p2MAC_p2OwnMACAddress \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(30) | 0x10000000) +#define DIDmib_p2_p2Modem \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7)) +#define DIDmib_p2_p2Modem_p2PHYType \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(1) | 0x10000000) +#define DIDmib_p2_p2Modem_p2CurrentChannel \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(2) | 0x10000000) +#define DIDmib_p2_p2Modem_p2CurrentPowerState \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(3) | 0x10000000) +#define DIDmib_p2_p2Modem_p2CCAMode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(4) | 0x10000000) +#define DIDmib_p2_p2Modem_p2SupportedDataRates \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(5) | 0x10000000) +#define DIDmib_p2_p2Modem_p2TxPowerMax \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(6) | 0x18000000) +#endif --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/wlan_compat.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/wlan_compat.h @@ -0,0 +1,784 @@ +/* src/include/wlan/wlan_compat.h +* +* Types and macros to aid in portability +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +*/ + +#ifndef _WLAN_COMPAT_H +#define _WLAN_COMPAT_H + +/*=============================================================*/ +/*------ Establish Platform Identity --------------------------*/ +/*=============================================================*/ +/* Key macros: */ +/* WLAN_CPU_FAMILY */ + #define WLAN_Ix86 1 + #define WLAN_PPC 2 + #define WLAN_Ix96 3 + #define WLAN_ARM 4 + #define WLAN_ALPHA 5 + #define WLAN_MIPS 6 + #define WLAN_HPPA 7 + #define WLAN_SPARC 8 + #define WLAN_SH 9 + #define WLAN_x86_64 10 +/* WLAN_SYSARCH */ + #define WLAN_PCAT 1 + #define WLAN_MBX 2 + #define WLAN_RPX 3 + #define WLAN_LWARCH 4 + #define WLAN_PMAC 5 + #define WLAN_SKIFF 6 + #define WLAN_BITSY 7 + #define WLAN_ALPHAARCH 7 + #define WLAN_MIPSARCH 9 + #define WLAN_HPPAARCH 10 + #define WLAN_SPARCARCH 11 + #define WLAN_SHARCH 12 + +/* Note: the PLX HOSTIF above refers to some vendors implementations for */ +/* PCI. It's a PLX chip that is a PCI to PCMCIA adapter, but it */ +/* isn't a real PCMCIA host interface adapter providing all the */ +/* card&socket services. */ + +#if (defined(CONFIG_PPC) || defined(CONFIG_8xx) || defined(__powerpc__)) +#ifndef __ppc__ +#define __ppc__ +#endif +#endif + +#if defined(__KERNEL__) + +#ifndef AUTOCONF_INCLUDED +#include +#endif + +#if defined(__x86_64__) + #define WLAN_CPU_FAMILY WLAN_x86_64 + #define WLAN_SYSARCH WLAN_PCAT +#elif defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) + #define WLAN_CPU_FAMILY WLAN_Ix86 + #define WLAN_SYSARCH WLAN_PCAT +#elif defined(__ppc__) + #define WLAN_CPU_FAMILY WLAN_PPC + #if defined(CONFIG_MBX) + #define WLAN_SYSARCH WLAN_MBX + #elif defined(CONFIG_RPXLITE) + #define WLAN_SYSARCH WLAN_RPX + #elif defined(CONFIG_RPXCLASSIC) + #define WLAN_SYSARCH WLAN_RPX + #else + #define WLAN_SYSARCH WLAN_PMAC + #endif +#elif defined(__arm__) + #define WLAN_CPU_FAMILY WLAN_ARM + #define WLAN_SYSARCH WLAN_SKIFF +#elif defined(__alpha__) + #define WLAN_CPU_FAMILY WLAN_ALPHA + #define WLAN_SYSARCH WLAN_ALPHAARCH +#elif defined(__mips__) + #define WLAN_CPU_FAMILY WLAN_MIPS + #define WLAN_SYSARCH WLAN_MIPSARCH +#elif defined(__hppa__) + #define WLAN_CPU_FAMILY WLAN_HPPA + #define WLAN_SYSARCH WLAN_HPPAARCH +#elif defined(__sparc__) + #define WLAN_CPU_FAMILY WLAN_SPARC + #define WLAN_SYSARCH WLAN_SPARC +#elif defined(__sh__) + #define WLAN_CPU_FAMILY WLAN_SH + #define WLAN_SYSARCH WLAN_SHARCH + #ifndef __LITTLE_ENDIAN__ + #define __LITTLE_ENDIAN__ + #endif +#else + #error "No CPU identified!" +#endif +#endif /* __KERNEL__ */ + +/* + Some big endian machines implicitly do all I/O in little endian mode. + + In particular: + Linux/PPC on PowerMacs (PCI) + Arm/Intel Xscale (PCI) + + This may also affect PLX boards and other BE &| PPC platforms; + as new ones are discovered, add them below. +*/ + +#if defined(WLAN_HOSTIF) +#if ((WLAN_HOSTIF == WLAN_PCI) || (WLAN_HOSTIF == WLAN_PLX)) +#if ((WLAN_SYSARCH == WLAN_SKIFF) || (WLAN_SYSARCH == WLAN_PMAC) || (WLAN_SYSARCH == WLAN_SPARC)) +#define REVERSE_ENDIAN +#endif +#endif +#endif + +/*=============================================================*/ +/*------ Bit settings -----------------------------------------*/ +/*=============================================================*/ + +#define BIT0 0x00000001 +#define BIT1 0x00000002 +#define BIT2 0x00000004 +#define BIT3 0x00000008 +#define BIT4 0x00000010 +#define BIT5 0x00000020 +#define BIT6 0x00000040 +#define BIT7 0x00000080 +#define BIT8 0x00000100 +#define BIT9 0x00000200 +#define BIT10 0x00000400 +#define BIT11 0x00000800 +#define BIT12 0x00001000 +#define BIT13 0x00002000 +#define BIT14 0x00004000 +#define BIT15 0x00008000 +#define BIT16 0x00010000 +#define BIT17 0x00020000 +#define BIT18 0x00040000 +#define BIT19 0x00080000 +#define BIT20 0x00100000 +#define BIT21 0x00200000 +#define BIT22 0x00400000 +#define BIT23 0x00800000 +#define BIT24 0x01000000 +#define BIT25 0x02000000 +#define BIT26 0x04000000 +#define BIT27 0x08000000 +#define BIT28 0x10000000 +#define BIT29 0x20000000 +#define BIT30 0x40000000 +#define BIT31 0x80000000 + +#include + +typedef u_int8_t UINT8; +typedef u_int16_t UINT16; +typedef u_int32_t UINT32; + +typedef int8_t INT8; +typedef int16_t INT16; +typedef int32_t INT32; + +typedef unsigned int UINT; +typedef signed int INT; + +typedef u_int64_t UINT64; +typedef int64_t INT64; + +#define UINT8_MAX (0xffUL) +#define UINT16_MAX (0xffffUL) +#define UINT32_MAX (0xffffffffUL) + +#define INT8_MAX (0x7fL) +#define INT16_MAX (0x7fffL) +#define INT32_MAX (0x7fffffffL) + +/*=============================================================*/ +/*------ Compiler Portability Macros --------------------------*/ +/*=============================================================*/ +#define __WLAN_ATTRIB_PACK__ __attribute__ ((packed)) + +/*=============================================================*/ +/*------ OS Portability Macros --------------------------------*/ +/*=============================================================*/ + +#ifndef WLAN_DBVAR +#define WLAN_DBVAR wlan_debug +#endif + +#ifndef KERNEL_VERSION +#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) +# if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)) +# include +# else +# include +# endif +#elif defined(__KERNEL__) +# define PREEMPT_MASK (0x000000FFUL) +# define preempt_count() (0UL) +#endif + +#define WLAN_LOG_ERROR(x,args...) printk(KERN_ERR "%s: " x , __FUNCTION__ , ##args); + +#define WLAN_LOG_WARNING(x,args...) printk(KERN_WARNING "%s: " x , __FUNCTION__ , ##args); + +#define WLAN_LOG_NOTICE(x,args...) printk(KERN_NOTICE "%s: " x , __FUNCTION__ , ##args); + +#define WLAN_LOG_INFO(args... ) printk(KERN_INFO args) + +#if defined(WLAN_INCLUDE_DEBUG) + #define WLAN_ASSERT(c) if ((!(c)) && WLAN_DBVAR >= 1) { \ + WLAN_LOG_DEBUG(1, "Assertion failure!\n"); } + #define WLAN_HEX_DUMP( l, x, p, n) if( WLAN_DBVAR >= (l) ){ \ + int __i__; \ + printk(KERN_DEBUG x ":"); \ + for( __i__=0; __i__ < (n); __i__++) \ + printk( " %02x", ((UINT8*)(p))[__i__]); \ + printk("\n"); } + #define DBFENTER { if ( WLAN_DBVAR >= 5 ){ WLAN_LOG_DEBUG(3,"---->\n"); } } + #define DBFEXIT { if ( WLAN_DBVAR >= 5 ){ WLAN_LOG_DEBUG(3,"<----\n"); } } + + #define WLAN_LOG_DEBUG(l,x,args...) if ( WLAN_DBVAR >= (l)) printk(KERN_DEBUG "%s(%lu): " x , __FUNCTION__, (preempt_count() & PREEMPT_MASK), ##args ); +#else + #define WLAN_ASSERT(c) + #define WLAN_HEX_DUMP( l, s, p, n) + #define DBFENTER + #define DBFEXIT + + #define WLAN_LOG_DEBUG(l, s, args...) +#endif + +#ifdef CONFIG_SMP +#define __SMP__ 1 +#endif + +#if defined(__KERNEL__) + +#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19))) +#define URB_ONLY_CALLBACK +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) +#define PT_REGS , struct pt_regs *regs +#else +#define PT_REGS +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)) +# define del_singleshot_timer_sync(a) del_timer_sync(a) +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,17)) +#define CONFIG_NETLINK 1 +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)) +#define kfree_s(a, b) kfree((a)) +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)) +#ifndef init_waitqueue_head +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,0,16)) +#define init_waitqueue_head(p) (*(p) = NULL) +#else +#define init_waitqueue_head(p) init_waitqueue(p) +#endif +typedef struct wait_queue *wait_queue_head_t; +typedef struct wait_queue wait_queue_t; +#define set_current_state(b) { current->state = (b); mb(); } +#define init_waitqueue_entry(a, b) { (a)->task = current; } +#endif +#endif + +#ifndef wait_event_interruptible_timeout +// retval == 0; signal met; we're good. +// retval < 0; interrupted by signal. +// retval > 0; timed out. + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)) // fixme? + +#define __wait_event_interruptible_timeout(wq, condition, ret) \ +do { \ + wait_queue_t __wait; \ + init_waitqueue_entry(&__wait, current); \ + \ + add_wait_queue(&wq, &__wait); \ + for (;;) { \ + set_current_state(TASK_INTERRUPTIBLE); \ + if (condition) \ + break; \ + if (!signal_pending(current)) { \ + ret = schedule_timeout(ret) ; \ + if (!ret) \ + break; \ + continue; \ + } \ + ret = -ERESTARTSYS; \ + break; \ + } \ + set_current_state(TASK_RUNNING); \ + remove_wait_queue(&wq, &__wait); \ +} while (0) + +#else // 2.2 + + +#define __wait_event_interruptible_timeout(wq, condition, ret) \ +do { \ + struct wait_queue __wait; \ + \ + __wait.task = current; \ + add_wait_queue(&wq, &__wait); \ + for (;;) { \ + current->state = TASK_INTERRUPTIBLE; \ + if (condition) \ + break; \ + if (!signal_pending(current)) { \ + ret = schedule_timeout(ret); \ + if (!ret) \ + break; \ + continue; \ + } \ + ret = -ERESTARTSYS; \ + break; \ + } \ + current->state = TASK_RUNNING; \ + remove_wait_queue(&wq, &__wait); \ +} while (0) + +#endif // version >= 2.4 + +#define wait_event_interruptible_timeout(wq, condition, timeout) \ +({ \ + long __ret = timeout; \ + if (!(condition)) \ + __wait_event_interruptible_timeout(wq, condition, __ret); \ + __ret; \ +}) + +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20)) +#ifdef _LINUX_LIST_H + +static inline void list_move_tail(struct list_head *list, + struct list_head *head) +{ + __list_del(list->prev, list->next); + list_add_tail(list, head); +} + +static inline void __list_splice(struct list_head *list, + struct list_head *head) +{ + struct list_head *first = list->next; + struct list_head *last = list->prev; + struct list_head *at = head->next; + + first->prev = head; + head->next = first; + + last->next = at; + at->prev = last; +} + +static inline void list_move(struct list_head *list, struct list_head *head) +{ + __list_del(list->prev, list->next); + list_add(list, head); +} + +static inline void list_splice_init(struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) { + __list_splice(list, head); + INIT_LIST_HEAD(list); + } +} + + +#endif // LIST_H +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) +#define SET_MODULE_OWNER(x) do { } while (0) +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,90)) +#define spin_lock(l) do { } while (0) +#define spin_unlock(l) do { } while (0) +#define spin_lock_irqsave(l,f) do { save_flags(f); cli(); } while (0) +#define spin_unlock_irqrestore(l,f) do { restore_flags(f); } while (0) +#define spin_lock_init(s) do { } while (0) +#define spin_trylock(l) (1) +typedef int spinlock_t; +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) // XXX ??? +#define spin_lock_bh spin_lock +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) +#ifdef CONFIG_SMP +#define spin_is_locked(x) (*(volatile char *)(&(x)->lock) <= 0) +#else +#define spin_is_locked(l) (0) +#endif +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,28)) +#define __user +#define __iomem +#endif + +#ifdef _LINUX_PROC_FS_H + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) +#define PROC_NET proc_net +#else +#define PROC_NET init_net.proc_net +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,25)) + +extern inline struct proc_dir_entry * +create_proc_read_entry(const char *name, mode_t mode, + struct proc_dir_entry *base, + read_proc_t *read_proc, void *data) +{ + struct proc_dir_entry *res = create_proc_entry(name, mode, base); + if (res) { + res->read_proc = read_proc; + res->data = data; + } + return res; +} +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,29)) +#ifndef proc_mkdir +#define proc_mkdir(name, root) create_proc_entry(name, S_IFDIR, root) +#endif +#endif +#endif /* _LINUX_PROC_FS_H */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) +#define skb_reset_mac_header(__a) (__a)->mac.raw = (__a)->data +#define SKB_MAC_HEADER(__a) (__a)->mac.raw +#else +#define SKB_MAC_HEADER(__a) (__a)->mac_header +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) +#define IRQF_DISABLED SA_INTERRUPT +#define IRQF_SHARED SA_SHIRQ +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +#ifndef INIT_TQUEUE +#define PREPARE_TQUEUE(_tq, _routine, _data) \ + do { \ + (_tq)->routine = _routine; \ + (_tq)->data = _data; \ + } while (0) +#define INIT_TQUEUE(_tq, _routine, _data) \ + do { \ + INIT_LIST_HEAD(&(_tq)->list); \ + (_tq)->sync = 0; \ + PREPARE_TQUEUE((_tq), (_routine), (_data)); \ + } while (0) +#endif + +#ifndef container_of +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) +#endif + +#ifndef INIT_WORK +#define work_struct tq_struct + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) +#define schedule_work(a) queue_task(a, &tq_scheduler) +#else +#define schedule_work(a) schedule_task(a) +#endif + +#define flush_scheduled_work flush_scheduled_tasks +#define INIT_WORK2(_wq, _routine) INIT_TQUEUE(_wq, (void (*)(void *))_routine, _wq) +#endif + +#else // >= 2.5 kernel + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +#define INIT_WORK2(_wq, _routine) INIT_WORK(_wq, (void (*)(void *))_routine, _wq) +#else +#define INIT_WORK2(_wq, _routine) INIT_WORK(_wq, _routine) +#endif + +#endif // >= 2.5 kernel + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38)) +typedef struct device netdevice_t; +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4)) +typedef struct net_device netdevice_t; +#else +#undef netdevice_t +typedef struct net_device netdevice_t; +#endif + +#ifdef WIRELESS_EXT +#if (WIRELESS_EXT < 13) +struct iw_request_info +{ + __u16 cmd; /* Wireless Extension command */ + __u16 flags; /* More to come ;-) */ +}; +#endif +#endif + + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,18)) +#define MODULE_PARM(a,b) extern int __bogus_decl +#define MODULE_AUTHOR(a) extern int __bogus_decl +#define MODULE_DESCRIPTION(a) extern int __bogus_decl +#define MODULE_SUPPORTED_DEVICE(a) extern int __bogus_decl +#undef GET_USE_COUNT +#define GET_USE_COUNT(m) mod_use_count_ +#endif + +#ifndef MODULE_OWNER +#define MODULE_OWNER(a) extern int __bogus_decl +#define ANCIENT_MODULE_CODE +#endif + +#ifndef MODULE_LICENSE +#define MODULE_LICENSE(m) extern int __bogus_decl +#endif + +/* TODO: Do we care about this? */ +#ifndef MODULE_DEVICE_TABLE +#define MODULE_DEVICE_TABLE(foo,bar) +#endif + +#define wlan_minutes2ticks(a) ((a)*(wlan_ticks_per_sec * 60)) +#define wlan_seconds2ticks(a) ((a)*(wlan_ticks_per_sec)) + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,47)) +#define NEW_MODULE_CODE +#ifdef ANCIENT_MODULE_CODE +#undef ANCIENT_MODULE_CODE +#endif +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,25)) +#define module_param(name, type, perm) \ + static inline void *__check_existence_##name(void) { return &name; } \ + MODULE_PARM(name, _MODULE_PARM_STRING_ ## type) + +#define _MODULE_PARM_STRING_byte "b" +#define _MODULE_PARM_STRING_short "h" +#define _MODULE_PARM_STRING_ushort "h" +#define _MODULE_PARM_STRING_int "i" +#define _MODULE_PARM_STRING_uint "i" +#define _MODULE_PARM_STRING_long "l" +#define _MODULE_PARM_STRING_ulong "l" +#define _MODULE_PARM_STRING_bool "i" +#endif + +/* linux < 2.5.69 */ +#ifndef IRQ_NONE +typedef void irqreturn_t; +#define IRQ_NONE +#define IRQ_HANDLED +#define IRQ_RETVAL(x) +#endif + +#ifndef in_atomic +#define in_atomic() 0 +#endif + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)) +#define URB_ASYNC_UNLINK 0 +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)) +#define URB_ASYNC_UNLINK USB_ASYNC_UNLINK +#define usb_fill_bulk_urb FILL_BULK_URB +#define usb_kill_urb usb_unlink_urb +#else +#define USB_QUEUE_BULK 0 +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)) +typedef u32 pm_message_t; +#endif + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9)) +#define hotplug_path "/etc/hotplug/wlan.agent" +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) +#define free_netdev(x) kfree(x) +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)) +#define eth_hdr(x) (x)->mac.ethernet +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) +#define del_timer_sync(a) del_timer(a) +#endif + +#ifndef might_sleep +#define might_sleep(a) do { } while (0) +#endif + +/* Apparently 2.4.2 ethtool is quite different, maybe newer too? */ +#if (defined(SIOETHTOOL) && !defined(ETHTOOL_GDRVINFO)) +#undef SIOETHTOOL +#endif + +// pcmcia-cs stuff +#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68)) && \ + !defined(pcmcia_access_configuration_register)) +#define pcmcia_access_configuration_register(handle, reg) \ + CardServices(AccessConfigurationRegister, handle, reg) +#define pcmcia_register_client(handle, reg) \ + CardServices(RegisterClient, handle, reg) +#define pcmcia_deregister_client(handle) \ + CardServices(DeregisterClient, handle) +#define pcmcia_get_first_tuple(handle, tuple) \ + CardServices(GetFirstTuple, handle, tuple) +#define pcmcia_get_next_tuple(handle, tuple) \ + CardServices(GetNextTuple, handle, tuple) +#define pcmcia_get_tuple_data(handle, tuple) \ + CardServices(GetTupleData, handle, tuple) +#define pcmcia_parse_tuple(handle, tuple, parse) \ + CardServices(ParseTuple, handle, tuple, parse) +#define pcmcia_get_configuration_info(handle, config) \ + CardServices(GetConfigurationInfo, handle, config) +#define pcmcia_request_io(handle, req) \ + CardServices(RequestIO, handle, req) +#define pcmcia_request_irq(handle, req) \ + CardServices(RequestIRQ, handle, req) +#define pcmcia_request_configuration(handle, req) \ + CardServices(RequestConfiguration, handle, req) +#define pcmcia_release_configuration(handle) \ + CardServices(ReleaseConfiguration, handle) +#define pcmcia_release_io(handle, req) \ + CardServices(ReleaseIO, handle, req) +#define pcmcia_release_irq(handle, req) \ + CardServices(ReleaseIRQ, handle, req) +#define pcmcia_release_window(win) \ + CardServices(ReleaseWindow, win) +#define pcmcia_get_card_services_info(info) \ + CardServices(GetCardServicesInfo, info) +#define pcmcia_report_error(handle, err) \ + CardServices(ReportError, handle, err) +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) +#define round_jiffies(a) (a) +#endif + +#endif /* __KERNEL__ */ + +/*=============================================================*/ +/*------ Hardware Portability Macros --------------------------*/ +/*=============================================================*/ + +#define ieee2host16(n) __le16_to_cpu(n) +#define ieee2host32(n) __le32_to_cpu(n) +#define host2ieee16(n) __cpu_to_le16(n) +#define host2ieee32(n) __cpu_to_le32(n) + +#if (WLAN_CPU_FAMILY != WLAN_MIPS) +typedef UINT32 phys_t; +#endif + +#if (WLAN_CPU_FAMILY == WLAN_PPC) + #define wlan_inw(a) in_be16((unsigned short *)((a)+_IO_BASE)) + #define wlan_inw_le16_to_cpu(a) inw((a)) + #define wlan_outw(v,a) out_be16((unsigned short *)((a)+_IO_BASE), (v)) + #define wlan_outw_cpu_to_le16(v,a) outw((v),(a)) +#else + #define wlan_inw(a) inw((a)) + #define wlan_inw_le16_to_cpu(a) __cpu_to_le16(inw((a))) + #define wlan_outw(v,a) outw((v),(a)) + #define wlan_outw_cpu_to_le16(v,a) outw(__cpu_to_le16((v)),(a)) +#endif + +/*=============================================================*/ +/*--- General Macros ------------------------------------------*/ +/*=============================================================*/ + +#define wlan_max(a, b) (((a) > (b)) ? (a) : (b)) +#define wlan_min(a, b) (((a) < (b)) ? (a) : (b)) + +#define wlan_isprint(c) (((c) > (0x19)) && ((c) < (0x7f))) + +#define wlan_hexchar(x) (((x) < 0x0a) ? ('0' + (x)) : ('a' + ((x) - 0x0a))) + +/* Create a string of printable chars from something that might not be */ +/* It's recommended that the str be 4*len + 1 bytes long */ +#define wlan_mkprintstr(buf, buflen, str, strlen) \ +{ \ + int i = 0; \ + int j = 0; \ + memset(str, 0, (strlen)); \ + for (i = 0; i < (buflen); i++) { \ + if ( wlan_isprint((buf)[i]) ) { \ + (str)[j] = (buf)[i]; \ + j++; \ + } else { \ + (str)[j] = '\\'; \ + (str)[j+1] = 'x'; \ + (str)[j+2] = wlan_hexchar(((buf)[i] & 0xf0) >> 4); \ + (str)[j+3] = wlan_hexchar(((buf)[i] & 0x0f)); \ + j += 4; \ + } \ + } \ +} + +/*=============================================================*/ +/*--- Variables -----------------------------------------------*/ +/*=============================================================*/ + +#ifdef WLAN_INCLUDE_DEBUG +extern int wlan_debug; +#endif + +extern int wlan_ethconv; /* What's the default ethconv? */ + +/*=============================================================*/ +/*--- Functions -----------------------------------------------*/ +/*=============================================================*/ +#endif /* _WLAN_COMPAT_H */ + --- linux-2.6.28.orig/ubuntu/misc/wireless/prism2_usb/hfa384x_usb.c +++ linux-2.6.28/ubuntu/misc/wireless/prism2_usb/hfa384x_usb.c @@ -0,0 +1,5068 @@ +/* src/prism2/driver/hfa384x_usb.c +* +* Functions that talk to the USB variantof the Intersil hfa384x MAC +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file implements functions that correspond to the prism2/hfa384x +* 802.11 MAC hardware and firmware host interface. +* +* The functions can be considered to represent several levels of +* abstraction. The lowest level functions are simply C-callable wrappers +* around the register accesses. The next higher level represents C-callable +* prism2 API functions that match the Intersil documentation as closely +* as is reasonable. The next higher layer implements common sequences +* of invokations of the API layer (e.g. write to bap, followed by cmd). +* +* Common sequences: +* hfa384x_drvr_xxx Highest level abstractions provided by the +* hfa384x code. They are driver defined wrappers +* for common sequences. These functions generally +* use the services of the lower levels. +* +* hfa384x_drvr_xxxconfig An example of the drvr level abstraction. These +* functions are wrappers for the RID get/set +* sequence. They call copy_[to|from]_bap() and +* cmd_access(). These functions operate on the +* RIDs and buffers without validation. The caller +* is responsible for that. +* +* API wrapper functions: +* hfa384x_cmd_xxx functions that provide access to the f/w commands. +* The function arguments correspond to each command +* argument, even command arguments that get packed +* into single registers. These functions _just_ +* issue the command by setting the cmd/parm regs +* & reading the status/resp regs. Additional +* activities required to fully use a command +* (read/write from/to bap, get/set int status etc.) +* are implemented separately. Think of these as +* C-callable prism2 commands. +* +* Lowest Layer Functions: +* hfa384x_docmd_xxx These functions implement the sequence required +* to issue any prism2 command. Primarily used by the +* hfa384x_cmd_xxx functions. +* +* hfa384x_bap_xxx BAP read/write access functions. +* Note: we usually use BAP0 for non-interrupt context +* and BAP1 for interrupt context. +* +* hfa384x_dl_xxx download related functions. +* +* Driver State Issues: +* Note that there are two pairs of functions that manage the +* 'initialized' and 'running' states of the hw/MAC combo. The four +* functions are create(), destroy(), start(), and stop(). create() +* sets up the data structures required to support the hfa384x_* +* functions and destroy() cleans them up. The start() function gets +* the actual hardware running and enables the interrupts. The stop() +* function shuts the hardware down. The sequence should be: +* create() +* start() +* . +* . Do interesting things w/ the hardware +* . +* stop() +* destroy() +* +* Note that destroy() can be called without calling stop() first. +* -------------------------------------------------------------------- +*/ + +/*================================================================*/ +/* System Includes */ +#define WLAN_DBVAR prism2_debug + +#include + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#if (WLAN_HOSTIF != WLAN_USB) +#error "This file is specific to USB" +#endif + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) +static int +wait_for_completion_interruptible(struct completion *x) +{ + int ret = 0; + + might_sleep(); + + spin_lock_irq(&x->wait.lock); + if (!x->done) { + DECLARE_WAITQUEUE(wait, current); + + wait.flags |= WQ_FLAG_EXCLUSIVE; + __add_wait_queue_tail(&x->wait, &wait); + do { + if (signal_pending(current)) { + ret = -ERESTARTSYS; + __remove_wait_queue(&x->wait, &wait); + goto out; + } + __set_current_state(TASK_INTERRUPTIBLE); + spin_unlock_irq(&x->wait.lock); + schedule(); + spin_lock_irq(&x->wait.lock); + } while (!x->done); + __remove_wait_queue(&x->wait, &wait); + } + x->done--; +out: + spin_unlock_irq(&x->wait.lock); + + return ret; +} +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69) +static void +usb_init_urb(struct urb *urb) +{ + memset(urb, 0, sizeof(*urb)); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) /* tune me! */ + urb->count = (atomic_t)ATOMIC_INIT(1); +#endif + spin_lock_init(&urb->lock); +} +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) /* tune me! */ +# define SUBMIT_URB(u,f) usb_submit_urb(u,f) +#else +# define SUBMIT_URB(u,f) usb_submit_urb(u) +#endif + +/*================================================================*/ +/* Project Includes */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*================================================================*/ +/* Local Constants */ + +enum cmd_mode +{ + DOWAIT = 0, + DOASYNC +}; +typedef enum cmd_mode CMD_MODE; + +#define THROTTLE_JIFFIES (HZ/8) + +/*================================================================*/ +/* Local Macros */ + +#define ROUNDUP64(a) (((a)+63)&~63) + +/*================================================================*/ +/* Local Types */ + +/*================================================================*/ +/* Local Static Definitions */ +extern int prism2_debug; + +/*================================================================*/ +/* Local Function Declarations */ + +#ifdef DEBUG_USB +static void +dbprint_urb(struct urb* urb); +#endif + +static void +hfa384x_int_rxmonitor( + wlandevice_t *wlandev, + hfa384x_usb_rxfrm_t *rxfrm); + +static void +hfa384x_usb_defer(struct work_struct *data); + +static int +submit_rx_urb(hfa384x_t *hw, gfp_t flags); + +static int +submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t flags); + +/*---------------------------------------------------*/ +/* Callbacks */ +#ifdef URB_ONLY_CALLBACK +static void +hfa384x_usbout_callback(struct urb *urb); +static void +hfa384x_ctlxout_callback(struct urb *urb); +static void +hfa384x_usbin_callback(struct urb *urb); +#else +static void +hfa384x_usbout_callback(struct urb *urb, struct pt_regs *regs); +static void +hfa384x_ctlxout_callback(struct urb *urb, struct pt_regs *regs); +static void +hfa384x_usbin_callback(struct urb *urb, struct pt_regs *regs); +#endif + +static void +hfa384x_usbin_txcompl(wlandevice_t *wlandev, hfa384x_usbin_t *usbin); + +static void +hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb); + +static void +hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin); + +static void +hfa384x_usbout_tx(wlandevice_t *wlandev, hfa384x_usbout_t *usbout); + +static void hfa384x_usbin_ctlx(hfa384x_t *hw, hfa384x_usbin_t *usbin, + int urb_status); + +/*---------------------------------------------------*/ +/* Functions to support the prism2 usb command queue */ + +static void +hfa384x_usbctlxq_run(hfa384x_t *hw); + +static void +hfa384x_usbctlx_reqtimerfn(unsigned long data); + +static void +hfa384x_usbctlx_resptimerfn(unsigned long data); + +static void +hfa384x_usb_throttlefn(unsigned long data); + +static void +hfa384x_usbctlx_completion_task(unsigned long data); + +static void +hfa384x_usbctlx_reaper_task(unsigned long data); + +static int +hfa384x_usbctlx_submit(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx); + +static void +unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx); + +struct usbctlx_completor +{ + int (*complete)(struct usbctlx_completor*); +}; +typedef struct usbctlx_completor usbctlx_completor_t; + +static int +hfa384x_usbctlx_complete_sync(hfa384x_t *hw, + hfa384x_usbctlx_t *ctlx, + usbctlx_completor_t *completor); + +static int +unlocked_usbctlx_cancel_async(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx); + +static void +hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx); + +static void +hfa384x_cb_rrid(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx); + +static int +usbctlx_get_status(const hfa384x_usb_cmdresp_t *cmdresp, + hfa384x_cmdresult_t *result); + +static void +usbctlx_get_rridresult(const hfa384x_usb_rridresp_t *rridresp, + hfa384x_rridresult_t *result); + +/*---------------------------------------------------*/ +/* Low level req/resp CTLX formatters and submitters */ +static int +hfa384x_docmd( + hfa384x_t *hw, + CMD_MODE mode, + hfa384x_metacmd_t *cmd, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data); + +static int +hfa384x_dorrid( + hfa384x_t *hw, + CMD_MODE mode, + UINT16 rid, + void *riddata, + UINT riddatalen, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data); + +static int +hfa384x_dowrid( + hfa384x_t *hw, + CMD_MODE mode, + UINT16 rid, + void *riddata, + UINT riddatalen, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data); + +static int +hfa384x_dormem( + hfa384x_t *hw, + CMD_MODE mode, + UINT16 page, + UINT16 offset, + void *data, + UINT len, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data); + +static int +hfa384x_dowmem( + hfa384x_t *hw, + CMD_MODE mode, + UINT16 page, + UINT16 offset, + void *data, + UINT len, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data); + +static int +hfa384x_isgood_pdrcode(UINT16 pdrcode); + +/*================================================================*/ +/* Function Definitions */ +static inline const char* ctlxstr(CTLX_STATE s) +{ + static const char* ctlx_str[] = { + "Initial state", + "Complete", + "Request failed", + "Request pending", + "Request packet submitted", + "Request packet completed", + "Response packet completed" + }; + + return ctlx_str[s]; +}; + + +static inline hfa384x_usbctlx_t* +get_active_ctlx(hfa384x_t *hw) +{ + return list_entry(hw->ctlxq.active.next, hfa384x_usbctlx_t, list); +} + + +#ifdef DEBUG_USB +void +dbprint_urb(struct urb* urb) +{ + WLAN_LOG_DEBUG(3,"urb->pipe=0x%08x\n", urb->pipe); + WLAN_LOG_DEBUG(3,"urb->status=0x%08x\n", urb->status); + WLAN_LOG_DEBUG(3,"urb->transfer_flags=0x%08x\n", urb->transfer_flags); + WLAN_LOG_DEBUG(3,"urb->transfer_buffer=0x%08x\n", (UINT)urb->transfer_buffer); + WLAN_LOG_DEBUG(3,"urb->transfer_buffer_length=0x%08x\n", urb->transfer_buffer_length); + WLAN_LOG_DEBUG(3,"urb->actual_length=0x%08x\n", urb->actual_length); + WLAN_LOG_DEBUG(3,"urb->bandwidth=0x%08x\n", urb->bandwidth); + WLAN_LOG_DEBUG(3,"urb->setup_packet(ctl)=0x%08x\n", (UINT)urb->setup_packet); + WLAN_LOG_DEBUG(3,"urb->start_frame(iso/irq)=0x%08x\n", urb->start_frame); + WLAN_LOG_DEBUG(3,"urb->interval(irq)=0x%08x\n", urb->interval); + WLAN_LOG_DEBUG(3,"urb->error_count(iso)=0x%08x\n", urb->error_count); + WLAN_LOG_DEBUG(3,"urb->timeout=0x%08x\n", urb->timeout); + WLAN_LOG_DEBUG(3,"urb->context=0x%08x\n", (UINT)urb->context); + WLAN_LOG_DEBUG(3,"urb->complete=0x%08x\n", (UINT)urb->complete); +} +#endif + + +/*---------------------------------------------------------------- +* submit_rx_urb +* +* Listen for input data on the BULK-IN pipe. If the pipe has +* stalled then schedule it to be reset. +* +* Arguments: +* hw device struct +* memflags memory allocation flags +* +* Returns: +* error code from submission +* +* Call context: +* Any +----------------------------------------------------------------*/ +static int +submit_rx_urb(hfa384x_t *hw, gfp_t memflags) +{ + struct sk_buff *skb; + int result; + + DBFENTER; + + skb = dev_alloc_skb(sizeof(hfa384x_usbin_t)); + if (skb == NULL) { + result = -ENOMEM; + goto done; + } + + /* Post the IN urb */ + usb_fill_bulk_urb(&hw->rx_urb, hw->usb, + hw->endp_in, + skb->data, sizeof(hfa384x_usbin_t), + hfa384x_usbin_callback, hw->wlandev); + + hw->rx_urb_skb = skb; + + result = -ENOLINK; + if ( !hw->wlandev->hwremoved && !test_bit(WORK_RX_HALT, &hw->usb_flags)) { + result = SUBMIT_URB(&hw->rx_urb, memflags); + + /* Check whether we need to reset the RX pipe */ + if (result == -EPIPE) { + WLAN_LOG_WARNING("%s rx pipe stalled: requesting reset\n", + hw->wlandev->netdev->name); + if ( !test_and_set_bit(WORK_RX_HALT, &hw->usb_flags) ) + schedule_work(&hw->usb_work); + } + } + + /* Don't leak memory if anything should go wrong */ + if (result != 0) { + dev_kfree_skb(skb); + hw->rx_urb_skb = NULL; + } + + done: + + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* submit_tx_urb +* +* Prepares and submits the URB of transmitted data. If the +* submission fails then it will schedule the output pipe to +* be reset. +* +* Arguments: +* hw device struct +* tx_urb URB of data for tranmission +* memflags memory allocation flags +* +* Returns: +* error code from submission +* +* Call context: +* Any +----------------------------------------------------------------*/ +static int +submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t memflags) +{ + struct net_device *netdev = hw->wlandev->netdev; + int result; + + DBFENTER; + + result = -ENOLINK; + if ( netif_running(netdev) ) { + + if ( !hw->wlandev->hwremoved && !test_bit(WORK_TX_HALT, &hw->usb_flags) ) { + result = SUBMIT_URB(tx_urb, memflags); + + /* Test whether we need to reset the TX pipe */ + if (result == -EPIPE) { + WLAN_LOG_WARNING("%s tx pipe stalled: requesting reset\n", + netdev->name); + set_bit(WORK_TX_HALT, &hw->usb_flags); + schedule_work(&hw->usb_work); + } else if (result == 0) { + netif_stop_queue(netdev); + } + } + } + + DBFEXIT; + + return result; +} + +/*---------------------------------------------------------------- +* hfa394x_usb_defer +* +* There are some things that the USB stack cannot do while +* in interrupt context, so we arrange this function to run +* in process context. +* +* Arguments: +* hw device structure +* +* Returns: +* nothing +* +* Call context: +* process (by design) +----------------------------------------------------------------*/ +static void +hfa384x_usb_defer(struct work_struct *data) +{ + hfa384x_t *hw = container_of(data, struct hfa384x, usb_work); + struct net_device *netdev = hw->wlandev->netdev; + + DBFENTER; + + /* Don't bother trying to reset anything if the plug + * has been pulled ... + */ + if ( hw->wlandev->hwremoved ) { + DBFEXIT; + return; + } + + /* Reception has stopped: try to reset the input pipe */ + if (test_bit(WORK_RX_HALT, &hw->usb_flags)) { + int ret; + + usb_kill_urb(&hw->rx_urb); /* Cannot be holding spinlock! */ + + ret = usb_clear_halt(hw->usb, hw->endp_in); + if (ret != 0) { + printk(KERN_ERR + "Failed to clear rx pipe for %s: err=%d\n", + netdev->name, ret); + } else { + printk(KERN_INFO "%s rx pipe reset complete.\n", + netdev->name); + clear_bit(WORK_RX_HALT, &hw->usb_flags); + set_bit(WORK_RX_RESUME, &hw->usb_flags); + } + } + + /* Resume receiving data back from the device. */ + if ( test_bit(WORK_RX_RESUME, &hw->usb_flags) ) { + int ret; + + ret = submit_rx_urb(hw, GFP_KERNEL); + if (ret != 0) { + printk(KERN_ERR + "Failed to resume %s rx pipe.\n", netdev->name); + } else { + clear_bit(WORK_RX_RESUME, &hw->usb_flags); + } + } + + /* Transmission has stopped: try to reset the output pipe */ + if (test_bit(WORK_TX_HALT, &hw->usb_flags)) { + int ret; + + usb_kill_urb(&hw->tx_urb); + ret = usb_clear_halt(hw->usb, hw->endp_out); + if (ret != 0) { + printk(KERN_ERR + "Failed to clear tx pipe for %s: err=%d\n", + netdev->name, ret); + } else { + printk(KERN_INFO "%s tx pipe reset complete.\n", + netdev->name); + clear_bit(WORK_TX_HALT, &hw->usb_flags); + set_bit(WORK_TX_RESUME, &hw->usb_flags); + + /* Stopping the BULK-OUT pipe also blocked + * us from sending any more CTLX URBs, so + * we need to re-run our queue ... + */ + hfa384x_usbctlxq_run(hw); + } + } + + /* Resume transmitting. */ + if ( test_and_clear_bit(WORK_TX_RESUME, &hw->usb_flags) ) { + p80211netdev_wake_queue(hw->wlandev); + } + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_create +* +* Sets up the hfa384x_t data structure for use. Note this +* does _not_ intialize the actual hardware, just the data structures +* we use to keep track of its state. +* +* Arguments: +* hw device structure +* irq device irq number +* iobase i/o base address for register access +* membase memory base address for register access +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +void +hfa384x_create( hfa384x_t *hw, struct usb_device *usb) +{ + DBFENTER; + + memset(hw, 0, sizeof(hfa384x_t)); + hw->usb = usb; + + /* set up the endpoints */ + hw->endp_in = usb_rcvbulkpipe(usb, 1); + hw->endp_out = usb_sndbulkpipe(usb, 2); + + /* Set up the waitq */ + init_waitqueue_head(&hw->cmdq); + + /* Initialize the command queue */ + spin_lock_init(&hw->ctlxq.lock); + INIT_LIST_HEAD(&hw->ctlxq.pending); + INIT_LIST_HEAD(&hw->ctlxq.active); + INIT_LIST_HEAD(&hw->ctlxq.completing); + INIT_LIST_HEAD(&hw->ctlxq.reapable); + + /* Initialize the authentication queue */ + skb_queue_head_init(&hw->authq); + + tasklet_init(&hw->reaper_bh, + hfa384x_usbctlx_reaper_task, + (unsigned long)hw); + tasklet_init(&hw->completion_bh, + hfa384x_usbctlx_completion_task, + (unsigned long)hw); + INIT_WORK2(&hw->link_bh, prism2sta_processing_defer); + INIT_WORK2(&hw->usb_work, hfa384x_usb_defer); + + init_timer(&hw->throttle); + hw->throttle.function = hfa384x_usb_throttlefn; + hw->throttle.data = (unsigned long)hw; + + init_timer(&hw->resptimer); + hw->resptimer.function = hfa384x_usbctlx_resptimerfn; + hw->resptimer.data = (unsigned long)hw; + + init_timer(&hw->reqtimer); + hw->reqtimer.function = hfa384x_usbctlx_reqtimerfn; + hw->reqtimer.data = (unsigned long)hw; + + usb_init_urb(&hw->rx_urb); + usb_init_urb(&hw->tx_urb); + usb_init_urb(&hw->ctlx_urb); + + hw->link_status = HFA384x_LINK_NOTCONNECTED; + hw->state = HFA384x_STATE_INIT; + + INIT_WORK2(&hw->commsqual_bh, prism2sta_commsqual_defer); + init_timer(&hw->commsqual_timer); + hw->commsqual_timer.data = (unsigned long) hw; + hw->commsqual_timer.function = prism2sta_commsqual_timer; + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_destroy +* +* Partner to hfa384x_create(). This function cleans up the hw +* structure so that it can be freed by the caller using a simple +* kfree. Currently, this function is just a placeholder. If, at some +* point in the future, an hw in the 'shutdown' state requires a 'deep' +* kfree, this is where it should be done. Note that if this function +* is called on a _running_ hw structure, the drvr_stop() function is +* called. +* +* Arguments: +* hw device structure +* +* Returns: +* nothing, this function is not allowed to fail. +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +void +hfa384x_destroy( hfa384x_t *hw) +{ + struct sk_buff *skb; + + DBFENTER; + + if ( hw->state == HFA384x_STATE_RUNNING ) { + hfa384x_drvr_stop(hw); + } + hw->state = HFA384x_STATE_PREINIT; + + if (hw->scanresults) { + kfree(hw->scanresults); + hw->scanresults = NULL; + } + + /* Now to clean out the auth queue */ + while ( (skb = skb_dequeue(&hw->authq)) ) { + dev_kfree_skb(skb); + } + + DBFEXIT; +} + + +/*---------------------------------------------------------------- + */ +static hfa384x_usbctlx_t* usbctlx_alloc(void) +{ + hfa384x_usbctlx_t *ctlx; + + ctlx = kmalloc(sizeof(*ctlx), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); + if (ctlx != NULL) + { + memset(ctlx, 0, sizeof(*ctlx)); + init_completion(&ctlx->done); + } + + return ctlx; +} + + +/*---------------------------------------------------------------- + * +----------------------------------------------------------------*/ +static int +usbctlx_get_status(const hfa384x_usb_cmdresp_t *cmdresp, + hfa384x_cmdresult_t *result) +{ + DBFENTER; + + result->status = hfa384x2host_16(cmdresp->status); + result->resp0 = hfa384x2host_16(cmdresp->resp0); + result->resp1 = hfa384x2host_16(cmdresp->resp1); + result->resp2 = hfa384x2host_16(cmdresp->resp2); + + WLAN_LOG_DEBUG(4, "cmdresult:status=0x%04x " + "resp0=0x%04x resp1=0x%04x resp2=0x%04x\n", + result->status, + result->resp0, + result->resp1, + result->resp2); + + DBFEXIT; + return (result->status & HFA384x_STATUS_RESULT); +} + +static void +usbctlx_get_rridresult(const hfa384x_usb_rridresp_t *rridresp, + hfa384x_rridresult_t *result) +{ + DBFENTER; + + result->rid = hfa384x2host_16(rridresp->rid); + result->riddata = rridresp->data; + result->riddata_len = ((hfa384x2host_16(rridresp->frmlen) - 1) * 2); + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* Completor object: +* This completor must be passed to hfa384x_usbctlx_complete_sync() +* when processing a CTLX that returns a hfa384x_cmdresult_t structure. +----------------------------------------------------------------*/ +struct usbctlx_cmd_completor +{ + usbctlx_completor_t head; + + const hfa384x_usb_cmdresp_t *cmdresp; + hfa384x_cmdresult_t *result; +}; +typedef struct usbctlx_cmd_completor usbctlx_cmd_completor_t; + +static int usbctlx_cmd_completor_fn(usbctlx_completor_t *head) +{ + usbctlx_cmd_completor_t *complete = (usbctlx_cmd_completor_t*)head; + return usbctlx_get_status(complete->cmdresp, complete->result); +} + +static inline usbctlx_completor_t* +init_cmd_completor(usbctlx_cmd_completor_t *completor, + const hfa384x_usb_cmdresp_t *cmdresp, + hfa384x_cmdresult_t *result) +{ + completor->head.complete = usbctlx_cmd_completor_fn; + completor->cmdresp = cmdresp; + completor->result = result; + return &(completor->head); +} + +/*---------------------------------------------------------------- +* Completor object: +* This completor must be passed to hfa384x_usbctlx_complete_sync() +* when processing a CTLX that reads a RID. +----------------------------------------------------------------*/ +struct usbctlx_rrid_completor +{ + usbctlx_completor_t head; + + const hfa384x_usb_rridresp_t *rridresp; + void *riddata; + UINT riddatalen; +}; +typedef struct usbctlx_rrid_completor usbctlx_rrid_completor_t; + +static int usbctlx_rrid_completor_fn(usbctlx_completor_t *head) +{ + usbctlx_rrid_completor_t *complete = (usbctlx_rrid_completor_t*)head; + hfa384x_rridresult_t rridresult; + + usbctlx_get_rridresult(complete->rridresp, &rridresult); + + /* Validate the length, note body len calculation in bytes */ + if ( rridresult.riddata_len != complete->riddatalen ) { + WLAN_LOG_WARNING( + "RID len mismatch, rid=0x%04x hlen=%d fwlen=%d\n", + rridresult.rid, + complete->riddatalen, + rridresult.riddata_len); + return -ENODATA; + } + + memcpy(complete->riddata, + rridresult.riddata, + complete->riddatalen); + return 0; +} + +static inline usbctlx_completor_t* +init_rrid_completor(usbctlx_rrid_completor_t *completor, + const hfa384x_usb_rridresp_t *rridresp, + void *riddata, + UINT riddatalen) +{ + completor->head.complete = usbctlx_rrid_completor_fn; + completor->rridresp = rridresp; + completor->riddata = riddata; + completor->riddatalen = riddatalen; + return &(completor->head); +} + +/*---------------------------------------------------------------- +* Completor object: +* Interprets the results of a synchronous RID-write +----------------------------------------------------------------*/ +typedef usbctlx_cmd_completor_t usbctlx_wrid_completor_t; +#define init_wrid_completor init_cmd_completor + +/*---------------------------------------------------------------- +* Completor object: +* Interprets the results of a synchronous memory-write +----------------------------------------------------------------*/ +typedef usbctlx_cmd_completor_t usbctlx_wmem_completor_t; +#define init_wmem_completor init_cmd_completor + +/*---------------------------------------------------------------- +* Completor object: +* Interprets the results of a synchronous memory-read +----------------------------------------------------------------*/ +struct usbctlx_rmem_completor +{ + usbctlx_completor_t head; + + const hfa384x_usb_rmemresp_t *rmemresp; + void *data; + UINT len; +}; +typedef struct usbctlx_rmem_completor usbctlx_rmem_completor_t; + +static int usbctlx_rmem_completor_fn(usbctlx_completor_t *head) +{ + usbctlx_rmem_completor_t *complete = (usbctlx_rmem_completor_t*)head; + + WLAN_LOG_DEBUG(4,"rmemresp:len=%d\n", complete->rmemresp->frmlen); + memcpy(complete->data, complete->rmemresp->data, complete->len); + return 0; +} + +static inline usbctlx_completor_t* +init_rmem_completor(usbctlx_rmem_completor_t *completor, + hfa384x_usb_rmemresp_t *rmemresp, + void *data, + UINT len) +{ + completor->head.complete = usbctlx_rmem_completor_fn; + completor->rmemresp = rmemresp; + completor->data = data; + completor->len = len; + return &(completor->head); +} + +/*---------------------------------------------------------------- +* hfa384x_cb_status +* +* Ctlx_complete handler for async CMD type control exchanges. +* mark the hw struct as such. +* +* Note: If the handling is changed here, it should probably be +* changed in docmd as well. +* +* Arguments: +* hw hw struct +* ctlx completed CTLX +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void +hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx) +{ + DBFENTER; + + if ( ctlx->usercb != NULL ) { + hfa384x_cmdresult_t cmdresult; + + if (ctlx->state != CTLX_COMPLETE) { + memset(&cmdresult, 0, sizeof(cmdresult)); + cmdresult.status = HFA384x_STATUS_RESULT_SET(HFA384x_CMD_ERR); + } else { + usbctlx_get_status(&ctlx->inbuf.cmdresp, &cmdresult); + } + + ctlx->usercb(hw, &cmdresult, ctlx->usercb_data); + } + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_cb_rrid +* +* CTLX completion handler for async RRID type control exchanges. +* +* Note: If the handling is changed here, it should probably be +* changed in dorrid as well. +* +* Arguments: +* hw hw struct +* ctlx completed CTLX +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void +hfa384x_cb_rrid(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx) +{ + DBFENTER; + + if ( ctlx->usercb != NULL ) { + hfa384x_rridresult_t rridresult; + + if (ctlx->state != CTLX_COMPLETE) { + memset(&rridresult, 0, sizeof(rridresult)); + rridresult.rid = hfa384x2host_16(ctlx->outbuf.rridreq.rid); + } else { + usbctlx_get_rridresult(&ctlx->inbuf.rridresp, &rridresult); + } + + ctlx->usercb(hw, &rridresult, ctlx->usercb_data); + } + + DBFEXIT; +} + +static inline int +hfa384x_docmd_wait(hfa384x_t *hw, hfa384x_metacmd_t *cmd) +{ + return hfa384x_docmd(hw, DOWAIT, cmd, NULL, NULL, NULL); +} + +static inline int +hfa384x_docmd_async(hfa384x_t *hw, + hfa384x_metacmd_t *cmd, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data) +{ + return hfa384x_docmd(hw, DOASYNC, cmd, + cmdcb, usercb, usercb_data); +} + +static inline int +hfa384x_dorrid_wait(hfa384x_t *hw, UINT16 rid, void *riddata, UINT riddatalen) +{ + return hfa384x_dorrid(hw, DOWAIT, + rid, riddata, riddatalen, + NULL, NULL, NULL); +} + +static inline int +hfa384x_dorrid_async(hfa384x_t *hw, + UINT16 rid, void *riddata, UINT riddatalen, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data) +{ + return hfa384x_dorrid(hw, DOASYNC, + rid, riddata, riddatalen, + cmdcb, usercb, usercb_data); +} + +static inline int +hfa384x_dowrid_wait(hfa384x_t *hw, UINT16 rid, void *riddata, UINT riddatalen) +{ + return hfa384x_dowrid(hw, DOWAIT, + rid, riddata, riddatalen, + NULL, NULL, NULL); +} + +static inline int +hfa384x_dowrid_async(hfa384x_t *hw, + UINT16 rid, void *riddata, UINT riddatalen, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data) +{ + return hfa384x_dowrid(hw, DOASYNC, + rid, riddata, riddatalen, + cmdcb, usercb, usercb_data); +} + +static inline int +hfa384x_dormem_wait(hfa384x_t *hw, + UINT16 page, UINT16 offset, void *data, UINT len) +{ + return hfa384x_dormem(hw, DOWAIT, + page, offset, data, len, + NULL, NULL, NULL); +} + +static inline int +hfa384x_dormem_async(hfa384x_t *hw, + UINT16 page, UINT16 offset, void *data, UINT len, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data) +{ + return hfa384x_dormem(hw, DOASYNC, + page, offset, data, len, + cmdcb, usercb, usercb_data); +} + +static inline int +hfa384x_dowmem_wait( + hfa384x_t *hw, + UINT16 page, + UINT16 offset, + void *data, + UINT len) +{ + return hfa384x_dowmem(hw, DOWAIT, + page, offset, data, len, + NULL, NULL, NULL); +} + +static inline int +hfa384x_dowmem_async( + hfa384x_t *hw, + UINT16 page, + UINT16 offset, + void *data, + UINT len, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data) +{ + return hfa384x_dowmem(hw, DOASYNC, + page, offset, data, len, + cmdcb, usercb, usercb_data); +} + +/*---------------------------------------------------------------- +* hfa384x_cmd_initialize +* +* Issues the initialize command and sets the hw->state based +* on the result. +* +* Arguments: +* hw device structure +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int +hfa384x_cmd_initialize(hfa384x_t *hw) +{ + int result = 0; + int i; + hfa384x_metacmd_t cmd; + + DBFENTER; + + + cmd.cmd = HFA384x_CMDCODE_INIT; + cmd.parm0 = 0; + cmd.parm1 = 0; + cmd.parm2 = 0; + + result = hfa384x_docmd_wait(hw, &cmd); + + + WLAN_LOG_DEBUG(3,"cmdresp.init: " + "status=0x%04x, resp0=0x%04x, " + "resp1=0x%04x, resp2=0x%04x\n", + cmd.result.status, + cmd.result.resp0, + cmd.result.resp1, + cmd.result.resp2); + if ( result == 0 ) { + for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) { + hw->port_enabled[i] = 0; + } + } + + hw->link_status = HFA384x_LINK_NOTCONNECTED; + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_disable +* +* Issues the disable command to stop communications on one of +* the MACs 'ports'. +* +* Arguments: +* hw device structure +* macport MAC port number (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_cmd_disable(hfa384x_t *hw, UINT16 macport) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DISABLE) | + HFA384x_CMD_MACPORT_SET(macport); + cmd.parm0 = 0; + cmd.parm1 = 0; + cmd.parm2 = 0; + + result = hfa384x_docmd_wait(hw, &cmd); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_enable +* +* Issues the enable command to enable communications on one of +* the MACs 'ports'. +* +* Arguments: +* hw device structure +* macport MAC port number +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_cmd_enable(hfa384x_t *hw, UINT16 macport) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ENABLE) | + HFA384x_CMD_MACPORT_SET(macport); + cmd.parm0 = 0; + cmd.parm1 = 0; + cmd.parm2 = 0; + + result = hfa384x_docmd_wait(hw, &cmd); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_notify +* +* Sends an info frame to the firmware to alter the behavior +* of the f/w asynch processes. Can only be called when the MAC +* is in the enabled state. +* +* Arguments: +* hw device structure +* reclaim [0|1] indicates whether the given FID will +* be handed back (via Alloc event) for reuse. +* (host order) +* fid FID of buffer containing the frame that was +* previously copied to MAC memory via the bap. +* (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* hw->resp0 will contain the FID being used by async notify +* process. If reclaim==0, resp0 will be the same as the fid +* argument. If reclaim==1, resp0 will be the different. +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_cmd_notify(hfa384x_t *hw, UINT16 reclaim, UINT16 fid, + void *buf, UINT16 len) +{ +#if 0 + int result = 0; + UINT16 cmd; + DBFENTER; + cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_NOTIFY) | + HFA384x_CMD_RECL_SET(reclaim); + result = hfa384x_docmd_wait(hw, cmd); + + DBFEXIT; + return result; +#endif +return 0; +} + + +#if 0 +/*---------------------------------------------------------------- +* hfa384x_cmd_inquiry +* +* Requests an info frame from the firmware. The info frame will +* be delivered asynchronously via the Info event. +* +* Arguments: +* hw device structure +* fid FID of the info frame requested. (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_cmd_inquiry(hfa384x_t *hw, UINT16 fid) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_INQ); + cmd.parm0 = 0; + cmd.parm1 = 0; + cmd.parm2 = 0; + + result = hfa384x_docmd_wait(hw, &cmd); + + DBFEXIT; + return result; +} +#endif + + +/*---------------------------------------------------------------- +* hfa384x_cmd_monitor +* +* Enables the 'monitor mode' of the MAC. Here's the description of +* monitor mode that I've received thus far: +* +* "The "monitor mode" of operation is that the MAC passes all +* frames for which the PLCP checks are correct. All received +* MPDUs are passed to the host with MAC Port = 7, with a +* receive status of good, FCS error, or undecryptable. Passing +* certain MPDUs is a violation of the 802.11 standard, but useful +* for a debugging tool." Normal communication is not possible +* while monitor mode is enabled. +* +* Arguments: +* hw device structure +* enable a code (0x0b|0x0f) that enables/disables +* monitor mode. (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_cmd_monitor(hfa384x_t *hw, UINT16 enable) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR) | + HFA384x_CMD_AINFO_SET(enable); + cmd.parm0 = 0; + cmd.parm1 = 0; + cmd.parm2 = 0; + + result = hfa384x_docmd_wait(hw, &cmd); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_download +* +* Sets the controls for the MAC controller code/data download +* process. The arguments set the mode and address associated +* with a download. Note that the aux registers should be enabled +* prior to setting one of the download enable modes. +* +* Arguments: +* hw device structure +* mode 0 - Disable programming and begin code exec +* 1 - Enable volatile mem programming +* 2 - Enable non-volatile mem programming +* 3 - Program non-volatile section from NV download +* buffer. +* (host order) +* lowaddr +* highaddr For mode 1, sets the high & low order bits of +* the "destination address". This address will be +* the execution start address when download is +* subsequently disabled. +* For mode 2, sets the high & low order bits of +* the destination in NV ram. +* For modes 0 & 3, should be zero. (host order) +* NOTE: these are CMD format. +* codelen Length of the data to write in mode 2, +* zero otherwise. (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_cmd_download(hfa384x_t *hw, UINT16 mode, UINT16 lowaddr, + UINT16 highaddr, UINT16 codelen) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + WLAN_LOG_DEBUG(5, + "mode=%d, lowaddr=0x%04x, highaddr=0x%04x, codelen=%d\n", + mode, lowaddr, highaddr, codelen); + + cmd.cmd = (HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DOWNLD) | + HFA384x_CMD_PROGMODE_SET(mode)); + + cmd.parm0 = lowaddr; + cmd.parm1 = highaddr; + cmd.parm2 = codelen; + + result = hfa384x_docmd_wait(hw, &cmd); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_copy_from_aux +* +* Copies a collection of bytes from the controller memory. The +* Auxiliary port MUST be enabled prior to calling this function. +* We _might_ be in a download state. +* +* Arguments: +* hw device structure +* cardaddr address in hfa384x data space to read +* auxctl address space select +* buf ptr to destination host buffer +* len length of data to transfer (in bytes) +* +* Returns: +* nothing +* +* Side effects: +* buf contains the data copied +* +* Call context: +* process +* interrupt +----------------------------------------------------------------*/ +void +hfa384x_copy_from_aux( + hfa384x_t *hw, UINT32 cardaddr, UINT32 auxctl, void *buf, UINT len) +{ + DBFENTER; + WLAN_LOG_ERROR("not used in USB.\n"); + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_copy_to_aux +* +* Copies a collection of bytes to the controller memory. The +* Auxiliary port MUST be enabled prior to calling this function. +* We _might_ be in a download state. +* +* Arguments: +* hw device structure +* cardaddr address in hfa384x data space to read +* auxctl address space select +* buf ptr to destination host buffer +* len length of data to transfer (in bytes) +* +* Returns: +* nothing +* +* Side effects: +* Controller memory now contains a copy of buf +* +* Call context: +* process +* interrupt +----------------------------------------------------------------*/ +void +hfa384x_copy_to_aux( + hfa384x_t *hw, UINT32 cardaddr, UINT32 auxctl, void *buf, UINT len) +{ + DBFENTER; + WLAN_LOG_ERROR("not used in USB.\n"); + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_corereset +* +* Perform a reset of the hfa38xx MAC core. We assume that the hw +* structure is in its "created" state. That is, it is initialized +* with proper values. Note that if a reset is done after the +* device has been active for awhile, the caller might have to clean +* up some leftover cruft in the hw structure. +* +* Arguments: +* hw device structure +* holdtime how long (in ms) to hold the reset +* settletime how long (in ms) to wait after releasing +* the reset +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis) +{ +#if 0 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + struct usb_device *parent = hw->usb->parent; + int i; + int port = -1; +#endif +#endif + int result = 0; + + +#define P2_USB_RT_PORT (USB_TYPE_CLASS | USB_RECIP_OTHER) +#define P2_USB_FEAT_RESET 4 +#define P2_USB_FEAT_C_RESET 20 + + DBFENTER; + +#if 0 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + /* Find the hub port */ + for ( i = 0; i < parent->maxchild; i++) { + if (parent->children[i] == hw->usb) { + port = i; + break; + } + } + if (port < 0) return -ENOENT; + + /* Set and clear the reset */ + usb_control_msg(parent, usb_sndctrlpipe(parent, 0), + USB_REQ_SET_FEATURE, P2_USB_RT_PORT, P2_USB_FEAT_RESET, + port+1, NULL, 0, 1*HZ); + wait_ms(holdtime); + usb_control_msg(parent, usb_sndctrlpipe(parent, 0), + USB_REQ_CLEAR_FEATURE, P2_USB_RT_PORT, P2_USB_FEAT_C_RESET, + port+1, NULL, 0, 1*HZ); + wait_ms(settletime); + + /* Set the device address */ + result=usb_set_address(hw->usb); + if (result < 0) { + WLAN_LOG_ERROR("reset_usbdev: Dev not accepting address, " + "result=%d\n", result); + clear_bit(hw->usb->devnum, &hw->usb->bus->devmap.devicemap); + hw->usb->devnum = -1; + goto done; + } + /* Let the address settle */ + wait_ms(20); + + /* Assume we're reusing the original descriptor data */ + + /* Set the configuration. */ + WLAN_LOG_DEBUG(3, "Setting Configuration %d\n", + hw->usb->config[0].bConfigurationValue); + result=usb_set_configuration(hw->usb, hw->usb->config[0].bConfigurationValue); + if ( result ) { + WLAN_LOG_ERROR("usb_set_configuration() failed, result=%d.\n", + result); + goto done; + } + /* Let the configuration settle */ + wait_ms(20); + + done: +#else + result=usb_reset_device(hw->usb); + if(result<0) { + WLAN_LOG_ERROR("usb_reset_device() failed, result=%d.\n",result); + } +#endif +#endif + + result=usb_reset_device(hw->usb); + if(result<0) { + WLAN_LOG_ERROR("usb_reset_device() failed, result=%d.\n",result); + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_usbctlx_complete_sync +* +* Waits for a synchronous CTLX object to complete, +* and then handles the response. +* +* Arguments: +* hw device structure +* ctlx CTLX ptr +* completor functor object to decide what to +* do with the CTLX's result. +* +* Returns: +* 0 Success +* -ERESTARTSYS Interrupted by a signal +* -EIO CTLX failed +* -ENODEV Adapter was unplugged +* ??? Result from completor +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +static int hfa384x_usbctlx_complete_sync(hfa384x_t *hw, + hfa384x_usbctlx_t *ctlx, + usbctlx_completor_t *completor) +{ + unsigned long flags; + int result; + + DBFENTER; + + result = wait_for_completion_interruptible(&ctlx->done); + + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + /* + * We can only handle the CTLX if the USB disconnect + * function has not run yet ... + */ + cleanup: + if ( hw->wlandev->hwremoved ) + { + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + result = -ENODEV; + } + else if ( result != 0 ) + { + int runqueue = 0; + + /* + * We were probably interrupted, so delete + * this CTLX asynchronously, kill the timers + * and the URB, and then start the next + * pending CTLX. + * + * NOTE: We can only delete the timers and + * the URB if this CTLX is active. + */ + if (ctlx == get_active_ctlx(hw)) + { + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + + del_singleshot_timer_sync(&hw->reqtimer); + del_singleshot_timer_sync(&hw->resptimer); + hw->req_timer_done = 1; + hw->resp_timer_done = 1; + usb_kill_urb(&hw->ctlx_urb); + + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + runqueue = 1; + + /* + * This scenario is so unlikely that I'm + * happy with a grubby "goto" solution ... + */ + if ( hw->wlandev->hwremoved ) + goto cleanup; + } + + /* + * The completion task will send this CTLX + * to the reaper the next time it runs. We + * are no longer in a hurry. + */ + ctlx->reapable = 1; + ctlx->state = CTLX_REQ_FAILED; + list_move_tail(&ctlx->list, &hw->ctlxq.completing); + + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + + if (runqueue) + hfa384x_usbctlxq_run(hw); + } else { + if (ctlx->state == CTLX_COMPLETE) { + result = completor->complete(completor); + } else { + WLAN_LOG_WARNING("CTLX[%d] error: state(%s)\n", + hfa384x2host_16(ctlx->outbuf.type), + ctlxstr(ctlx->state)); + result = -EIO; + } + + list_del(&ctlx->list); + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + kfree(ctlx); + } + + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* hfa384x_docmd +* +* Constructs a command CTLX and submits it. +* +* NOTE: Any changes to the 'post-submit' code in this function +* need to be carried over to hfa384x_cbcmd() since the handling +* is virtually identical. +* +* Arguments: +* hw device structure +* mode DOWAIT or DOASYNC +* cmd cmd structure. Includes all arguments and result +* data points. All in host order. in host order +* cmdcb command-specific callback +* usercb user callback for async calls, NULL for DOWAIT calls +* usercb_data user supplied data pointer for async calls, NULL +* for DOASYNC calls +* +* Returns: +* 0 success +* -EIO CTLX failure +* -ERESTARTSYS Awakened on signal +* >0 command indicated error, Status and Resp0-2 are +* in hw structure. +* +* Side effects: +* +* +* Call context: +* process +----------------------------------------------------------------*/ +static int +hfa384x_docmd( + hfa384x_t *hw, + CMD_MODE mode, + hfa384x_metacmd_t *cmd, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data) +{ + int result; + hfa384x_usbctlx_t *ctlx; + + DBFENTER; + ctlx = usbctlx_alloc(); + if ( ctlx == NULL ) { + result = -ENOMEM; + goto done; + } + + /* Initialize the command */ + ctlx->outbuf.cmdreq.type = host2hfa384x_16(HFA384x_USB_CMDREQ); + ctlx->outbuf.cmdreq.cmd = host2hfa384x_16(cmd->cmd); + ctlx->outbuf.cmdreq.parm0 = host2hfa384x_16(cmd->parm0); + ctlx->outbuf.cmdreq.parm1 = host2hfa384x_16(cmd->parm1); + ctlx->outbuf.cmdreq.parm2 = host2hfa384x_16(cmd->parm2); + + ctlx->outbufsize = sizeof(ctlx->outbuf.cmdreq); + + WLAN_LOG_DEBUG(4, "cmdreq: cmd=0x%04x " + "parm0=0x%04x parm1=0x%04x parm2=0x%04x\n", + cmd->cmd, + cmd->parm0, + cmd->parm1, + cmd->parm2); + + ctlx->reapable = mode; + ctlx->cmdcb = cmdcb; + ctlx->usercb = usercb; + ctlx->usercb_data = usercb_data; + + result = hfa384x_usbctlx_submit(hw, ctlx); + if (result != 0) { + kfree(ctlx); + } else if (mode == DOWAIT) { + usbctlx_cmd_completor_t completor; + + result = hfa384x_usbctlx_complete_sync( + hw, ctlx, init_cmd_completor(&completor, + &ctlx->inbuf.cmdresp, + &cmd->result) ); + } + +done: + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_dorrid +* +* Constructs a read rid CTLX and issues it. +* +* NOTE: Any changes to the 'post-submit' code in this function +* need to be carried over to hfa384x_cbrrid() since the handling +* is virtually identical. +* +* Arguments: +* hw device structure +* mode DOWAIT or DOASYNC +* rid Read RID number (host order) +* riddata Caller supplied buffer that MAC formatted RID.data +* record will be written to for DOWAIT calls. Should +* be NULL for DOASYNC calls. +* riddatalen Buffer length for DOWAIT calls. Zero for DOASYNC calls. +* cmdcb command callback for async calls, NULL for DOWAIT calls +* usercb user callback for async calls, NULL for DOWAIT calls +* usercb_data user supplied data pointer for async calls, NULL +* for DOWAIT calls +* +* Returns: +* 0 success +* -EIO CTLX failure +* -ERESTARTSYS Awakened on signal +* -ENODATA riddatalen != macdatalen +* >0 command indicated error, Status and Resp0-2 are +* in hw structure. +* +* Side effects: +* +* Call context: +* interrupt (DOASYNC) +* process (DOWAIT or DOASYNC) +----------------------------------------------------------------*/ +static int +hfa384x_dorrid( + hfa384x_t *hw, + CMD_MODE mode, + UINT16 rid, + void *riddata, + UINT riddatalen, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data) +{ + int result; + hfa384x_usbctlx_t *ctlx; + + DBFENTER; + ctlx = usbctlx_alloc(); + if ( ctlx == NULL ) { + result = -ENOMEM; + goto done; + } + + /* Initialize the command */ + ctlx->outbuf.rridreq.type = host2hfa384x_16(HFA384x_USB_RRIDREQ); + ctlx->outbuf.rridreq.frmlen = + host2hfa384x_16(sizeof(ctlx->outbuf.rridreq.rid)); + ctlx->outbuf.rridreq.rid = host2hfa384x_16(rid); + + ctlx->outbufsize = sizeof(ctlx->outbuf.rridreq); + + ctlx->reapable = mode; + ctlx->cmdcb = cmdcb; + ctlx->usercb = usercb; + ctlx->usercb_data = usercb_data; + + /* Submit the CTLX */ + result = hfa384x_usbctlx_submit(hw, ctlx); + if (result != 0) { + kfree(ctlx); + } else if (mode == DOWAIT) { + usbctlx_rrid_completor_t completor; + + result = hfa384x_usbctlx_complete_sync( + hw, ctlx, init_rrid_completor(&completor, + &ctlx->inbuf.rridresp, + riddata, + riddatalen) ); + } + +done: + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_dowrid +* +* Constructs a write rid CTLX and issues it. +* +* NOTE: Any changes to the 'post-submit' code in this function +* need to be carried over to hfa384x_cbwrid() since the handling +* is virtually identical. +* +* Arguments: +* hw device structure +* CMD_MODE DOWAIT or DOASYNC +* rid RID code +* riddata Data portion of RID formatted for MAC +* riddatalen Length of the data portion in bytes +* cmdcb command callback for async calls, NULL for DOWAIT calls +* usercb user callback for async calls, NULL for DOWAIT calls +* usercb_data user supplied data pointer for async calls +* +* Returns: +* 0 success +* -ETIMEDOUT timed out waiting for register ready or +* command completion +* >0 command indicated error, Status and Resp0-2 are +* in hw structure. +* +* Side effects: +* +* Call context: +* interrupt (DOASYNC) +* process (DOWAIT or DOASYNC) +----------------------------------------------------------------*/ +static int +hfa384x_dowrid( + hfa384x_t *hw, + CMD_MODE mode, + UINT16 rid, + void *riddata, + UINT riddatalen, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data) +{ + int result; + hfa384x_usbctlx_t *ctlx; + + DBFENTER; + ctlx = usbctlx_alloc(); + if ( ctlx == NULL ) { + result = -ENOMEM; + goto done; + } + + /* Initialize the command */ + ctlx->outbuf.wridreq.type = host2hfa384x_16(HFA384x_USB_WRIDREQ); + ctlx->outbuf.wridreq.frmlen = host2hfa384x_16( + (sizeof(ctlx->outbuf.wridreq.rid) + + riddatalen + 1) / 2); + ctlx->outbuf.wridreq.rid = host2hfa384x_16(rid); + memcpy(ctlx->outbuf.wridreq.data, riddata, riddatalen); + + ctlx->outbufsize = sizeof(ctlx->outbuf.wridreq.type) + + sizeof(ctlx->outbuf.wridreq.frmlen) + + sizeof(ctlx->outbuf.wridreq.rid) + + riddatalen; + + ctlx->reapable = mode; + ctlx->cmdcb = cmdcb; + ctlx->usercb = usercb; + ctlx->usercb_data = usercb_data; + + /* Submit the CTLX */ + result = hfa384x_usbctlx_submit(hw, ctlx); + if (result != 0) { + kfree(ctlx); + } else if (mode == DOWAIT) { + usbctlx_wrid_completor_t completor; + hfa384x_cmdresult_t wridresult; + + result = hfa384x_usbctlx_complete_sync( + hw, + ctlx, + init_wrid_completor(&completor, + &ctlx->inbuf.wridresp, + &wridresult) ); + } + +done: + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* hfa384x_dormem +* +* Constructs a readmem CTLX and issues it. +* +* NOTE: Any changes to the 'post-submit' code in this function +* need to be carried over to hfa384x_cbrmem() since the handling +* is virtually identical. +* +* Arguments: +* hw device structure +* mode DOWAIT or DOASYNC +* page MAC address space page (CMD format) +* offset MAC address space offset +* data Ptr to data buffer to receive read +* len Length of the data to read (max == 2048) +* cmdcb command callback for async calls, NULL for DOWAIT calls +* usercb user callback for async calls, NULL for DOWAIT calls +* usercb_data user supplied data pointer for async calls +* +* Returns: +* 0 success +* -ETIMEDOUT timed out waiting for register ready or +* command completion +* >0 command indicated error, Status and Resp0-2 are +* in hw structure. +* +* Side effects: +* +* Call context: +* interrupt (DOASYNC) +* process (DOWAIT or DOASYNC) +----------------------------------------------------------------*/ +static int +hfa384x_dormem( + hfa384x_t *hw, + CMD_MODE mode, + UINT16 page, + UINT16 offset, + void *data, + UINT len, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data) +{ + int result; + hfa384x_usbctlx_t *ctlx; + + DBFENTER; + ctlx = usbctlx_alloc(); + if ( ctlx == NULL ) { + result = -ENOMEM; + goto done; + } + + /* Initialize the command */ + ctlx->outbuf.rmemreq.type = host2hfa384x_16(HFA384x_USB_RMEMREQ); + ctlx->outbuf.rmemreq.frmlen = host2hfa384x_16( + sizeof(ctlx->outbuf.rmemreq.offset) + + sizeof(ctlx->outbuf.rmemreq.page) + + len); + ctlx->outbuf.rmemreq.offset = host2hfa384x_16(offset); + ctlx->outbuf.rmemreq.page = host2hfa384x_16(page); + + ctlx->outbufsize = sizeof(ctlx->outbuf.rmemreq); + + WLAN_LOG_DEBUG(4, + "type=0x%04x frmlen=%d offset=0x%04x page=0x%04x\n", + ctlx->outbuf.rmemreq.type, + ctlx->outbuf.rmemreq.frmlen, + ctlx->outbuf.rmemreq.offset, + ctlx->outbuf.rmemreq.page); + + WLAN_LOG_DEBUG(4,"pktsize=%zd\n", + ROUNDUP64(sizeof(ctlx->outbuf.rmemreq))); + + ctlx->reapable = mode; + ctlx->cmdcb = cmdcb; + ctlx->usercb = usercb; + ctlx->usercb_data = usercb_data; + + result = hfa384x_usbctlx_submit(hw, ctlx); + if (result != 0) { + kfree(ctlx); + } else if ( mode == DOWAIT ) { + usbctlx_rmem_completor_t completor; + + result = hfa384x_usbctlx_complete_sync( + hw, ctlx, init_rmem_completor(&completor, + &ctlx->inbuf.rmemresp, + data, + len) ); + } + +done: + DBFEXIT; + return result; +} + + + +/*---------------------------------------------------------------- +* hfa384x_dowmem +* +* Constructs a writemem CTLX and issues it. +* +* NOTE: Any changes to the 'post-submit' code in this function +* need to be carried over to hfa384x_cbwmem() since the handling +* is virtually identical. +* +* Arguments: +* hw device structure +* mode DOWAIT or DOASYNC +* page MAC address space page (CMD format) +* offset MAC address space offset +* data Ptr to data buffer containing write data +* len Length of the data to read (max == 2048) +* cmdcb command callback for async calls, NULL for DOWAIT calls +* usercb user callback for async calls, NULL for DOWAIT calls +* usercb_data user supplied data pointer for async calls. +* +* Returns: +* 0 success +* -ETIMEDOUT timed out waiting for register ready or +* command completion +* >0 command indicated error, Status and Resp0-2 are +* in hw structure. +* +* Side effects: +* +* Call context: +* interrupt (DOWAIT) +* process (DOWAIT or DOASYNC) +----------------------------------------------------------------*/ +static int +hfa384x_dowmem( + hfa384x_t *hw, + CMD_MODE mode, + UINT16 page, + UINT16 offset, + void *data, + UINT len, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data) +{ + int result; + hfa384x_usbctlx_t *ctlx; + + DBFENTER; + WLAN_LOG_DEBUG(5, "page=0x%04x offset=0x%04x len=%d\n", + page,offset,len); + + ctlx = usbctlx_alloc(); + if ( ctlx == NULL ) { + result = -ENOMEM; + goto done; + } + + /* Initialize the command */ + ctlx->outbuf.wmemreq.type = host2hfa384x_16(HFA384x_USB_WMEMREQ); + ctlx->outbuf.wmemreq.frmlen = host2hfa384x_16( + sizeof(ctlx->outbuf.wmemreq.offset) + + sizeof(ctlx->outbuf.wmemreq.page) + + len); + ctlx->outbuf.wmemreq.offset = host2hfa384x_16(offset); + ctlx->outbuf.wmemreq.page = host2hfa384x_16(page); + memcpy(ctlx->outbuf.wmemreq.data, data, len); + + ctlx->outbufsize = sizeof(ctlx->outbuf.wmemreq.type) + + sizeof(ctlx->outbuf.wmemreq.frmlen) + + sizeof(ctlx->outbuf.wmemreq.offset) + + sizeof(ctlx->outbuf.wmemreq.page) + + len; + + ctlx->reapable = mode; + ctlx->cmdcb = cmdcb; + ctlx->usercb = usercb; + ctlx->usercb_data = usercb_data; + + result = hfa384x_usbctlx_submit(hw, ctlx); + if (result != 0) { + kfree(ctlx); + } else if ( mode == DOWAIT ) { + usbctlx_wmem_completor_t completor; + hfa384x_cmdresult_t wmemresult; + + result = hfa384x_usbctlx_complete_sync( + hw, + ctlx, + init_wmem_completor(&completor, + &ctlx->inbuf.wmemresp, + &wmemresult) ); + } + +done: + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_commtallies +* +* Send a commtallies inquiry to the MAC. Note that this is an async +* call that will result in an info frame arriving sometime later. +* +* Arguments: +* hw device structure +* +* Returns: +* zero success. +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_drvr_commtallies( hfa384x_t *hw ) +{ + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = HFA384x_CMDCODE_INQ; + cmd.parm0 = HFA384x_IT_COMMTALLIES; + cmd.parm1 = 0; + cmd.parm2 = 0; + + hfa384x_docmd_async(hw, &cmd, NULL, NULL, NULL); + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_disable +* +* Issues the disable command to stop communications on one of +* the MACs 'ports'. Only macport 0 is valid for stations. +* APs may also disable macports 1-6. Only ports that have been +* previously enabled may be disabled. +* +* Arguments: +* hw device structure +* macport MAC port number (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_drvr_disable(hfa384x_t *hw, UINT16 macport) +{ + int result = 0; + + DBFENTER; + if ((!hw->isap && macport != 0) || + (hw->isap && !(macport <= HFA384x_PORTID_MAX)) || + !(hw->port_enabled[macport]) ){ + result = -EINVAL; + } else { + result = hfa384x_cmd_disable(hw, macport); + if ( result == 0 ) { + hw->port_enabled[macport] = 0; + } + } + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_enable +* +* Issues the enable command to enable communications on one of +* the MACs 'ports'. Only macport 0 is valid for stations. +* APs may also enable macports 1-6. Only ports that are currently +* disabled may be enabled. +* +* Arguments: +* hw device structure +* macport MAC port number +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_drvr_enable(hfa384x_t *hw, UINT16 macport) +{ + int result = 0; + + DBFENTER; + if ((!hw->isap && macport != 0) || + (hw->isap && !(macport <= HFA384x_PORTID_MAX)) || + (hw->port_enabled[macport]) ){ + result = -EINVAL; + } else { + result = hfa384x_cmd_enable(hw, macport); + if ( result == 0 ) { + hw->port_enabled[macport] = 1; + } + } + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_flashdl_enable +* +* Begins the flash download state. Checks to see that we're not +* already in a download state and that a port isn't enabled. +* Sets the download state and retrieves the flash download +* buffer location, buffer size, and timeout length. +* +* Arguments: +* hw device structure +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_drvr_flashdl_enable(hfa384x_t *hw) +{ + int result = 0; + int i; + + DBFENTER; + /* Check that a port isn't active */ + for ( i = 0; i < HFA384x_PORTID_MAX; i++) { + if ( hw->port_enabled[i] ) { + WLAN_LOG_DEBUG(1,"called when port enabled.\n"); + return -EINVAL; + } + } + + /* Check that we're not already in a download state */ + if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) { + return -EINVAL; + } + + /* Retrieve the buffer loc&size and timeout */ + if ( (result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER, + &(hw->bufinfo), sizeof(hw->bufinfo))) ) { + return result; + } + hw->bufinfo.page = hfa384x2host_16(hw->bufinfo.page); + hw->bufinfo.offset = hfa384x2host_16(hw->bufinfo.offset); + hw->bufinfo.len = hfa384x2host_16(hw->bufinfo.len); + if ( (result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME, + &(hw->dltimeout))) ) { + return result; + } + hw->dltimeout = hfa384x2host_16(hw->dltimeout); + + WLAN_LOG_DEBUG(1,"flashdl_enable\n"); + + hw->dlstate = HFA384x_DLSTATE_FLASHENABLED; + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_flashdl_disable +* +* Ends the flash download state. Note that this will cause the MAC +* firmware to restart. +* +* Arguments: +* hw device structure +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_drvr_flashdl_disable(hfa384x_t *hw) +{ + DBFENTER; + /* Check that we're already in the download state */ + if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) { + return -EINVAL; + } + + WLAN_LOG_DEBUG(1,"flashdl_enable\n"); + + /* There isn't much we can do at this point, so I don't */ + /* bother w/ the return value */ + hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0); + hw->dlstate = HFA384x_DLSTATE_DISABLED; + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_flashdl_write +* +* Performs a FLASH download of a chunk of data. First checks to see +* that we're in the FLASH download state, then sets the download +* mode, uses the aux functions to 1) copy the data to the flash +* buffer, 2) sets the download 'write flash' mode, 3) readback and +* compare. Lather rinse, repeat as many times an necessary to get +* all the given data into flash. +* When all data has been written using this function (possibly +* repeatedly), call drvr_flashdl_disable() to end the download state +* and restart the MAC. +* +* Arguments: +* hw device structure +* daddr Card address to write to. (host order) +* buf Ptr to data to write. +* len Length of data (host order). +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int +hfa384x_drvr_flashdl_write( + hfa384x_t *hw, + UINT32 daddr, + void *buf, + UINT32 len) +{ + int result = 0; + UINT32 dlbufaddr; + int nburns; + UINT32 burnlen; + UINT32 burndaddr; + UINT16 burnlo; + UINT16 burnhi; + int nwrites; + UINT8 *writebuf; + UINT16 writepage; + UINT16 writeoffset; + UINT32 writelen; + int i; + int j; + + DBFENTER; + WLAN_LOG_DEBUG(5,"daddr=0x%08x len=%d\n", daddr, len); + + /* Check that we're in the flash download state */ + if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) { + return -EINVAL; + } + + WLAN_LOG_INFO("Download %d bytes to flash @0x%06x\n", len, daddr); + + /* Convert to flat address for arithmetic */ + /* NOTE: dlbuffer RID stores the address in AUX format */ + dlbufaddr = HFA384x_ADDR_AUX_MKFLAT( + hw->bufinfo.page, hw->bufinfo.offset); + WLAN_LOG_DEBUG(5, + "dlbuf.page=0x%04x dlbuf.offset=0x%04x dlbufaddr=0x%08x\n", + hw->bufinfo.page, hw->bufinfo.offset, dlbufaddr); + +#if 0 +WLAN_LOG_WARNING("dlbuf@0x%06lx len=%d to=%d\n", dlbufaddr, hw->bufinfo.len, hw->dltimeout); +#endif + /* Calculations to determine how many fills of the dlbuffer to do + * and how many USB wmemreq's to do for each fill. At this point + * in time, the dlbuffer size and the wmemreq size are the same. + * Therefore, nwrites should always be 1. The extra complexity + * here is a hedge against future changes. + */ + + /* Figure out how many times to do the flash programming */ + nburns = len / hw->bufinfo.len; + nburns += (len % hw->bufinfo.len) ? 1 : 0; + + /* For each flash program cycle, how many USB wmemreq's are needed? */ + nwrites = hw->bufinfo.len / HFA384x_USB_RWMEM_MAXLEN; + nwrites += (hw->bufinfo.len % HFA384x_USB_RWMEM_MAXLEN) ? 1 : 0; + + /* For each burn */ + for ( i = 0; i < nburns; i++) { + /* Get the dest address and len */ + burnlen = (len - (hw->bufinfo.len * i)) > hw->bufinfo.len ? + hw->bufinfo.len : + (len - (hw->bufinfo.len * i)); + burndaddr = daddr + (hw->bufinfo.len * i); + burnlo = HFA384x_ADDR_CMD_MKOFF(burndaddr); + burnhi = HFA384x_ADDR_CMD_MKPAGE(burndaddr); + + WLAN_LOG_INFO("Writing %d bytes to flash @0x%06x\n", + burnlen, burndaddr); + + /* Set the download mode */ + result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NV, + burnlo, burnhi, burnlen); + if ( result ) { + WLAN_LOG_ERROR("download(NV,lo=%x,hi=%x,len=%x) " + "cmd failed, result=%d. Aborting d/l\n", + burnlo, burnhi, burnlen, result); + goto exit_proc; + } + + /* copy the data to the flash download buffer */ + for ( j=0; j < nwrites; j++) { + writebuf = buf + + (i*hw->bufinfo.len) + + (j*HFA384x_USB_RWMEM_MAXLEN); + + writepage = HFA384x_ADDR_CMD_MKPAGE( + dlbufaddr + + (j*HFA384x_USB_RWMEM_MAXLEN)); + writeoffset = HFA384x_ADDR_CMD_MKOFF( + dlbufaddr + + (j*HFA384x_USB_RWMEM_MAXLEN)); + + writelen = burnlen-(j*HFA384x_USB_RWMEM_MAXLEN); + writelen = writelen > HFA384x_USB_RWMEM_MAXLEN ? + HFA384x_USB_RWMEM_MAXLEN : + writelen; + + result = hfa384x_dowmem_wait( hw, + writepage, + writeoffset, + writebuf, + writelen ); +#if 0 + +Comment out for debugging, assume the write was successful. + if (result) { + WLAN_LOG_ERROR( + "Write to dl buffer failed, " + "result=0x%04x. Aborting.\n", + result); + goto exit_proc; + } +#endif + + } + + /* set the download 'write flash' mode */ + result = hfa384x_cmd_download(hw, + HFA384x_PROGMODE_NVWRITE, + 0,0,0); + if ( result ) { + WLAN_LOG_ERROR( + "download(NVWRITE,lo=%x,hi=%x,len=%x) " + "cmd failed, result=%d. Aborting d/l\n", + burnlo, burnhi, burnlen, result); + goto exit_proc; + } + + /* TODO: We really should do a readback and compare. */ + } + +exit_proc: + + /* Leave the firmware in the 'post-prog' mode. flashdl_disable will */ + /* actually disable programming mode. Remember, that will cause the */ + /* the firmware to effectively reset itself. */ + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_getconfig +* +* Performs the sequence necessary to read a config/info item. +* +* Arguments: +* hw device structure +* rid config/info record id (host order) +* buf host side record buffer. Upon return it will +* contain the body portion of the record (minus the +* RID and len). +* len buffer length (in bytes, should match record length) +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* -ENODATA length mismatch between argument and retrieved +* record. +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_drvr_getconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len) +{ + int result; + DBFENTER; + + result = hfa384x_dorrid_wait(hw, rid, buf, len); + + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- + * hfa384x_drvr_getconfig_async + * + * Performs the sequence necessary to perform an async read of + * of a config/info item. + * + * Arguments: + * hw device structure + * rid config/info record id (host order) + * buf host side record buffer. Upon return it will + * contain the body portion of the record (minus the + * RID and len). + * len buffer length (in bytes, should match record length) + * cbfn caller supplied callback, called when the command + * is done (successful or not). + * cbfndata pointer to some caller supplied data that will be + * passed in as an argument to the cbfn. + * + * Returns: + * nothing the cbfn gets a status argument identifying if + * any errors occur. + * Side effects: + * Queues an hfa384x_usbcmd_t for subsequent execution. + * + * Call context: + * Any + ----------------------------------------------------------------*/ +int +hfa384x_drvr_getconfig_async( + hfa384x_t *hw, + UINT16 rid, + ctlx_usercb_t usercb, + void *usercb_data) +{ + return hfa384x_dorrid_async(hw, rid, NULL, 0, + hfa384x_cb_rrid, usercb, usercb_data); +} + +/*---------------------------------------------------------------- + * hfa384x_drvr_setconfig_async + * + * Performs the sequence necessary to write a config/info item. + * + * Arguments: + * hw device structure + * rid config/info record id (in host order) + * buf host side record buffer + * len buffer length (in bytes) + * usercb completion callback + * usercb_data completion callback argument + * + * Returns: + * 0 success + * >0 f/w reported error - f/w status code + * <0 driver reported error + * + * Side effects: + * + * Call context: + * process + ----------------------------------------------------------------*/ +int +hfa384x_drvr_setconfig_async( + hfa384x_t *hw, + UINT16 rid, + void *buf, + UINT16 len, + ctlx_usercb_t usercb, + void *usercb_data) +{ + return hfa384x_dowrid_async(hw, rid, buf, len, + hfa384x_cb_status, usercb, usercb_data); +} + +/*---------------------------------------------------------------- +* hfa384x_drvr_handover +* +* Sends a handover notification to the MAC. +* +* Arguments: +* hw device structure +* addr address of station that's left +* +* Returns: +* zero success. +* -ERESTARTSYS received signal while waiting for semaphore. +* -EIO failed to write to bap, or failed in cmd. +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_drvr_handover( hfa384x_t *hw, UINT8 *addr) +{ + DBFENTER; + WLAN_LOG_ERROR("Not currently supported in USB!\n"); + DBFEXIT; + return -EIO; +} + +/*---------------------------------------------------------------- +* hfa384x_drvr_low_level +* +* Write test commands to the card. Some test commands don't make +* sense without prior set-up. For example, continous TX isn't very +* useful until you set the channel. That functionality should be +* +* Side effects: +* +* Call context: +* process thread +* -----------------------------------------------------------------*/ +int hfa384x_drvr_low_level(hfa384x_t *hw, hfa384x_metacmd_t *cmd) +{ + int result; + DBFENTER; + + /* Do i need a host2hfa... conversion ? */ + + result = hfa384x_docmd_wait(hw, cmd); + + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* hfa384x_drvr_mmi_read +* +* Read mmi registers. mmi is intersil-speak for the baseband +* processor registers. +* +* Arguments: +* hw device structure +* register The test register to be accessed (must be even #). +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_drvr_mmi_read(hfa384x_t *hw, UINT32 addr, UINT32 *resp) +{ +#if 0 + int result = 0; + UINT16 cmd_code = (UINT16) 0x30; + UINT16 param = (UINT16) addr; + DBFENTER; + + /* Do i need a host2hfa... conversion ? */ + result = hfa384x_docmd_wait(hw, cmd_code); + + DBFEXIT; + return result; +#endif +return 0; +} + +/*---------------------------------------------------------------- +* hfa384x_drvr_mmi_write +* +* Read mmi registers. mmi is intersil-speak for the baseband +* processor registers. +* +* Arguments: +* hw device structure +* addr The test register to be accessed (must be even #). +* data The data value to write to the register. +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ + +int +hfa384x_drvr_mmi_write(hfa384x_t *hw, UINT32 addr, UINT32 data) +{ +#if 0 + int result = 0; + UINT16 cmd_code = (UINT16) 0x31; + UINT16 param0 = (UINT16) addr; + UINT16 param1 = (UINT16) data; + DBFENTER; + + WLAN_LOG_DEBUG(1,"mmi write : addr = 0x%08lx\n", addr); + WLAN_LOG_DEBUG(1,"mmi write : data = 0x%08lx\n", data); + + /* Do i need a host2hfa... conversion ? */ + result = hfa384x_docmd_wait(hw, cmd_code); + + DBFEXIT; + return result; +#endif +return 0; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_ramdl_disable +* +* Ends the ram download state. +* +* Arguments: +* hw device structure +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int +hfa384x_drvr_ramdl_disable(hfa384x_t *hw) +{ + DBFENTER; + /* Check that we're already in the download state */ + if ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) { + return -EINVAL; + } + + WLAN_LOG_DEBUG(3,"ramdl_disable()\n"); + + /* There isn't much we can do at this point, so I don't */ + /* bother w/ the return value */ + hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0); + hw->dlstate = HFA384x_DLSTATE_DISABLED; + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_ramdl_enable +* +* Begins the ram download state. Checks to see that we're not +* already in a download state and that a port isn't enabled. +* Sets the download state and calls cmd_download with the +* ENABLE_VOLATILE subcommand and the exeaddr argument. +* +* Arguments: +* hw device structure +* exeaddr the card execution address that will be +* jumped to when ramdl_disable() is called +* (host order). +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int +hfa384x_drvr_ramdl_enable(hfa384x_t *hw, UINT32 exeaddr) +{ + int result = 0; + UINT16 lowaddr; + UINT16 hiaddr; + int i; + DBFENTER; + /* Check that a port isn't active */ + for ( i = 0; i < HFA384x_PORTID_MAX; i++) { + if ( hw->port_enabled[i] ) { + WLAN_LOG_ERROR( + "Can't download with a macport enabled.\n"); + return -EINVAL; + } + } + + /* Check that we're not already in a download state */ + if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) { + WLAN_LOG_ERROR( + "Download state not disabled.\n"); + return -EINVAL; + } + + WLAN_LOG_DEBUG(3,"ramdl_enable, exeaddr=0x%08x\n", exeaddr); + + /* Call the download(1,addr) function */ + lowaddr = HFA384x_ADDR_CMD_MKOFF(exeaddr); + hiaddr = HFA384x_ADDR_CMD_MKPAGE(exeaddr); + + result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_RAM, + lowaddr, hiaddr, 0); + + if ( result == 0) { + /* Set the download state */ + hw->dlstate = HFA384x_DLSTATE_RAMENABLED; + } else { + WLAN_LOG_DEBUG(1, + "cmd_download(0x%04x, 0x%04x) failed, result=%d.\n", + lowaddr, + hiaddr, + result); + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_ramdl_write +* +* Performs a RAM download of a chunk of data. First checks to see +* that we're in the RAM download state, then uses the [read|write]mem USB +* commands to 1) copy the data, 2) readback and compare. The download +* state is unaffected. When all data has been written using +* this function, call drvr_ramdl_disable() to end the download state +* and restart the MAC. +* +* Arguments: +* hw device structure +* daddr Card address to write to. (host order) +* buf Ptr to data to write. +* len Length of data (host order). +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int +hfa384x_drvr_ramdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len) +{ + int result = 0; + int nwrites; + UINT8 *data = buf; + int i; + UINT32 curraddr; + UINT16 currpage; + UINT16 curroffset; + UINT16 currlen; + DBFENTER; + /* Check that we're in the ram download state */ + if ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) { + return -EINVAL; + } + + WLAN_LOG_INFO("Writing %d bytes to ram @0x%06x\n", len, daddr); + + /* How many dowmem calls? */ + nwrites = len / HFA384x_USB_RWMEM_MAXLEN; + nwrites += len % HFA384x_USB_RWMEM_MAXLEN ? 1 : 0; + + /* Do blocking wmem's */ + for(i=0; i < nwrites; i++) { + /* make address args */ + curraddr = daddr + (i * HFA384x_USB_RWMEM_MAXLEN); + currpage = HFA384x_ADDR_CMD_MKPAGE(curraddr); + curroffset = HFA384x_ADDR_CMD_MKOFF(curraddr); + currlen = len - (i * HFA384x_USB_RWMEM_MAXLEN); + if ( currlen > HFA384x_USB_RWMEM_MAXLEN) { + currlen = HFA384x_USB_RWMEM_MAXLEN; + } + + /* Do blocking ctlx */ + result = hfa384x_dowmem_wait( hw, + currpage, + curroffset, + data + (i*HFA384x_USB_RWMEM_MAXLEN), + currlen ); + + if (result) break; + + /* TODO: We really should have a readback. */ + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_readpda +* +* Performs the sequence to read the PDA space. Note there is no +* drvr_writepda() function. Writing a PDA is +* generally implemented by a calling component via calls to +* cmd_download and writing to the flash download buffer via the +* aux regs. +* +* Arguments: +* hw device structure +* buf buffer to store PDA in +* len buffer length +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* -ETIMEOUT timout waiting for the cmd regs to become +* available, or waiting for the control reg +* to indicate the Aux port is enabled. +* -ENODATA the buffer does NOT contain a valid PDA. +* Either the card PDA is bad, or the auxdata +* reads are giving us garbage. + +* +* Side effects: +* +* Call context: +* process or non-card interrupt. +----------------------------------------------------------------*/ +int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, UINT len) +{ + int result = 0; + UINT16 *pda = buf; + int pdaok = 0; + int morepdrs = 1; + int currpdr = 0; /* word offset of the current pdr */ + size_t i; + UINT16 pdrlen; /* pdr length in bytes, host order */ + UINT16 pdrcode; /* pdr code, host order */ + UINT16 currpage; + UINT16 curroffset; + struct pdaloc { + UINT32 cardaddr; + UINT16 auxctl; + } pdaloc[] = + { + { HFA3842_PDA_BASE, 0}, + { HFA3841_PDA_BASE, 0}, + { HFA3841_PDA_BOGUS_BASE, 0} + }; + + DBFENTER; + + /* Read the pda from each known address. */ + for ( i = 0; i < ARRAY_SIZE(pdaloc); i++) { + /* Make address */ + currpage = HFA384x_ADDR_CMD_MKPAGE(pdaloc[i].cardaddr); + curroffset = HFA384x_ADDR_CMD_MKOFF(pdaloc[i].cardaddr); + + result = hfa384x_dormem_wait(hw, + currpage, + curroffset, + buf, + len); /* units of bytes */ + + if (result) { + WLAN_LOG_WARNING( + "Read from index %zd failed, continuing\n", + i ); + continue; + } + + /* Test for garbage */ + pdaok = 1; /* initially assume good */ + morepdrs = 1; + while ( pdaok && morepdrs ) { + pdrlen = hfa384x2host_16(pda[currpdr]) * 2; + pdrcode = hfa384x2host_16(pda[currpdr+1]); + /* Test the record length */ + if ( pdrlen > HFA384x_PDR_LEN_MAX || pdrlen == 0) { + WLAN_LOG_ERROR("pdrlen invalid=%d\n", + pdrlen); + pdaok = 0; + break; + } + /* Test the code */ + if ( !hfa384x_isgood_pdrcode(pdrcode) ) { + WLAN_LOG_ERROR("pdrcode invalid=%d\n", + pdrcode); + pdaok = 0; + break; + } + /* Test for completion */ + if ( pdrcode == HFA384x_PDR_END_OF_PDA) { + morepdrs = 0; + } + + /* Move to the next pdr (if necessary) */ + if ( morepdrs ) { + /* note the access to pda[], need words here */ + currpdr += hfa384x2host_16(pda[currpdr]) + 1; + } + } + if ( pdaok ) { + WLAN_LOG_INFO( + "PDA Read from 0x%08x in %s space.\n", + pdaloc[i].cardaddr, + pdaloc[i].auxctl == 0 ? "EXTDS" : + pdaloc[i].auxctl == 1 ? "NV" : + pdaloc[i].auxctl == 2 ? "PHY" : + pdaloc[i].auxctl == 3 ? "ICSRAM" : + ""); + break; + } + } + result = pdaok ? 0 : -ENODATA; + + if ( result ) { + WLAN_LOG_DEBUG(3,"Failure: pda is not okay\n"); + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_setconfig +* +* Performs the sequence necessary to write a config/info item. +* +* Arguments: +* hw device structure +* rid config/info record id (in host order) +* buf host side record buffer +* len buffer length (in bytes) +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_drvr_setconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len) +{ + return hfa384x_dowrid_wait(hw, rid, buf, len); +} + +/*---------------------------------------------------------------- +* hfa384x_drvr_start +* +* Issues the MAC initialize command, sets up some data structures, +* and enables the interrupts. After this function completes, the +* low-level stuff should be ready for any/all commands. +* +* Arguments: +* hw device structure +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_drvr_start(hfa384x_t *hw) +{ + int result, result1, result2; + u16 status; + DBFENTER; + + might_sleep(); + + /* Clear endpoint stalls - but only do this if the endpoint + * is showing a stall status. Some prism2 cards seem to behave + * badly if a clear_halt is called when the endpoint is already + * ok + */ + result = usb_get_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_in, &status); + if (result < 0) { + WLAN_LOG_ERROR( + "Cannot get bulk in endpoint status.\n"); + goto done; + } + if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_in)) { + WLAN_LOG_ERROR( + "Failed to reset bulk in endpoint.\n"); + } + + result = usb_get_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_out, &status); + if (result < 0) { + WLAN_LOG_ERROR( + "Cannot get bulk out endpoint status.\n"); + goto done; + } + if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_out)) { + WLAN_LOG_ERROR( + "Failed to reset bulk out endpoint.\n"); + } + + /* Synchronous unlink, in case we're trying to restart the driver */ + usb_kill_urb(&hw->rx_urb); + + /* Post the IN urb */ + result = submit_rx_urb(hw, GFP_KERNEL); + if (result != 0) { + WLAN_LOG_ERROR( + "Fatal, failed to submit RX URB, result=%d\n", + result); + goto done; + } + + /* Call initialize twice, with a 1 second sleep in between. + * This is a nasty work-around since many prism2 cards seem to + * need time to settle after an init from cold. The second + * call to initialize in theory is not necessary - but we call + * it anyway as a double insurance policy: + * 1) If the first init should fail, the second may well succeed + * and the card can still be used + * 2) It helps ensures all is well with the card after the first + * init and settle time. + */ + result1 = hfa384x_cmd_initialize(hw); + msleep(1000); + result = result2 = hfa384x_cmd_initialize(hw); + if (result1 != 0) { + if (result2 != 0) { + WLAN_LOG_ERROR( + "cmd_initialize() failed on two attempts, results %d and %d\n", + result1, result2); + usb_kill_urb(&hw->rx_urb); + goto done; + } else { + WLAN_LOG_DEBUG(0, "First cmd_initialize() failed (result %d),\n", + result1); + WLAN_LOG_DEBUG(0, "but second attempt succeeded. All should be ok\n"); + } + } else if (result2 != 0) { + WLAN_LOG_WARNING( + "First cmd_initialize() succeeded, but second attempt failed (result=%d)\n", + result2); + WLAN_LOG_WARNING("Most likely the card will be functional\n"); + goto done; + } + + hw->state = HFA384x_STATE_RUNNING; + +done: + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_stop +* +* Shuts down the MAC to the point where it is safe to unload the +* driver. Any subsystem that may be holding a data or function +* ptr into the driver must be cleared/deinitialized. +* +* Arguments: +* hw device structure +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int +hfa384x_drvr_stop(hfa384x_t *hw) +{ + int result = 0; + int i; + DBFENTER; + + might_sleep(); + + /* There's no need for spinlocks here. The USB "disconnect" + * function sets this "removed" flag and then calls us. + */ + if ( !hw->wlandev->hwremoved ) { + /* Call initialize to leave the MAC in its 'reset' state */ + hfa384x_cmd_initialize(hw); + + /* Cancel the rxurb */ + usb_kill_urb(&hw->rx_urb); + } + + hw->link_status = HFA384x_LINK_NOTCONNECTED; + hw->state = HFA384x_STATE_INIT; + + del_timer_sync(&hw->commsqual_timer); + + /* Clear all the port status */ + for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) { + hw->port_enabled[i] = 0; + } + + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* hfa384x_drvr_txframe +* +* Takes a frame from prism2sta and queues it for transmission. +* +* Arguments: +* hw device structure +* skb packet buffer struct. Contains an 802.11 +* data frame. +* p80211_hdr points to the 802.11 header for the packet. +* Returns: +* 0 Success and more buffs available +* 1 Success but no more buffs +* 2 Allocation failure +* 4 Buffer full or queue busy +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep) + +{ + int usbpktlen = sizeof(hfa384x_tx_frame_t); + int result; + int ret; + char *ptr; + + DBFENTER; + + if (hw->tx_urb.status == -EINPROGRESS) { + WLAN_LOG_WARNING("TX URB already in use\n"); + result = 3; + goto exit; + } + + /* Build Tx frame structure */ + /* Set up the control field */ + memset(&hw->txbuff.txfrm.desc, 0, sizeof(hw->txbuff.txfrm.desc)); + + /* Setup the usb type field */ + hw->txbuff.type = host2hfa384x_16(HFA384x_USB_TXFRM); + + /* Set up the sw_support field to identify this frame */ + hw->txbuff.txfrm.desc.sw_support = 0x0123; + +/* Tx complete and Tx exception disable per dleach. Might be causing + * buf depletion + */ +//#define DOEXC SLP -- doboth breaks horribly under load, doexc less so. +#if defined(DOBOTH) + hw->txbuff.txfrm.desc.tx_control = + HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) | + HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(1); +#elif defined(DOEXC) + hw->txbuff.txfrm.desc.tx_control = + HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) | + HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(0); +#else + hw->txbuff.txfrm.desc.tx_control = + HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) | + HFA384x_TX_TXEX_SET(0) | HFA384x_TX_TXOK_SET(0); +#endif + hw->txbuff.txfrm.desc.tx_control = + host2hfa384x_16(hw->txbuff.txfrm.desc.tx_control); + + /* copy the header over to the txdesc */ + memcpy(&(hw->txbuff.txfrm.desc.frame_control), p80211_hdr, sizeof(p80211_hdr_t)); + + /* if we're using host WEP, increase size by IV+ICV */ + if (p80211_wep->data) { + hw->txbuff.txfrm.desc.data_len = host2hfa384x_16(skb->len+8); + // hw->txbuff.txfrm.desc.tx_control |= HFA384x_TX_NOENCRYPT_SET(1); + usbpktlen+=8; + } else { + hw->txbuff.txfrm.desc.data_len = host2hfa384x_16(skb->len); + } + + usbpktlen += skb->len; + + /* copy over the WEP IV if we are using host WEP */ + ptr = hw->txbuff.txfrm.data; + if (p80211_wep->data) { + memcpy(ptr, p80211_wep->iv, sizeof(p80211_wep->iv)); + ptr+= sizeof(p80211_wep->iv); + memcpy(ptr, p80211_wep->data, skb->len); + } else { + memcpy(ptr, skb->data, skb->len); + } + /* copy over the packet data */ + ptr+= skb->len; + + /* copy over the WEP ICV if we are using host WEP */ + if (p80211_wep->data) { + memcpy(ptr, p80211_wep->icv, sizeof(p80211_wep->icv)); + } + + /* Send the USB packet */ + usb_fill_bulk_urb( &(hw->tx_urb), hw->usb, + hw->endp_out, + &(hw->txbuff), ROUNDUP64(usbpktlen), + hfa384x_usbout_callback, hw->wlandev ); + hw->tx_urb.transfer_flags |= USB_QUEUE_BULK; + + result = 1; + ret = submit_tx_urb(hw, &hw->tx_urb, GFP_ATOMIC); + if ( ret != 0 ) { + WLAN_LOG_ERROR( + "submit_tx_urb() failed, error=%d\n", ret); + result = 3; + } + + exit: + DBFEXIT; + return result; +} + +void hfa384x_tx_timeout(wlandevice_t *wlandev) +{ + hfa384x_t *hw = wlandev->priv; + unsigned long flags; + + DBFENTER; + + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + if ( !hw->wlandev->hwremoved && + /* Note the bitwise OR, not the logical OR. */ + ( !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags) | + !test_and_set_bit(WORK_RX_HALT, &hw->usb_flags) ) ) + { + schedule_work(&hw->usb_work); + } + + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + + DBFEXIT; +} + +/*---------------------------------------------------------------- +* hfa384x_usbctlx_reaper_task +* +* Tasklet to delete dead CTLX objects +* +* Arguments: +* data ptr to a hfa384x_t +* +* Returns: +* +* Call context: +* Interrupt +----------------------------------------------------------------*/ +static void hfa384x_usbctlx_reaper_task(unsigned long data) +{ + hfa384x_t *hw = (hfa384x_t*)data; + struct list_head *entry; + struct list_head *temp; + unsigned long flags; + + DBFENTER; + + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + /* This list is guaranteed to be empty if someone + * has unplugged the adapter. + */ + list_for_each_safe(entry, temp, &hw->ctlxq.reapable) { + hfa384x_usbctlx_t *ctlx; + + ctlx = list_entry(entry, hfa384x_usbctlx_t, list); + list_del(&ctlx->list); + kfree(ctlx); + } + + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + + DBFEXIT; +} + +/*---------------------------------------------------------------- +* hfa384x_usbctlx_completion_task +* +* Tasklet to call completion handlers for returned CTLXs +* +* Arguments: +* data ptr to hfa384x_t +* +* Returns: +* Nothing +* +* Call context: +* Interrupt +----------------------------------------------------------------*/ +static void hfa384x_usbctlx_completion_task(unsigned long data) +{ + hfa384x_t *hw = (hfa384x_t*)data; + struct list_head *entry; + struct list_head *temp; + unsigned long flags; + + int reap = 0; + + DBFENTER; + + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + /* This list is guaranteed to be empty if someone + * has unplugged the adapter ... + */ + list_for_each_safe(entry, temp, &hw->ctlxq.completing) { + hfa384x_usbctlx_t *ctlx; + + ctlx = list_entry(entry, hfa384x_usbctlx_t, list); + + /* Call the completion function that this + * command was assigned, assuming it has one. + */ + if ( ctlx->cmdcb != NULL ) { + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + ctlx->cmdcb(hw, ctlx); + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + /* Make sure we don't try and complete + * this CTLX more than once! + */ + ctlx->cmdcb = NULL; + + /* Did someone yank the adapter out + * while our list was (briefly) unlocked? + */ + if ( hw->wlandev->hwremoved ) + { + reap = 0; + break; + } + } + + /* + * "Reapable" CTLXs are ones which don't have any + * threads waiting for them to die. Hence they must + * be delivered to The Reaper! + */ + if ( ctlx->reapable ) { + /* Move the CTLX off the "completing" list (hopefully) + * on to the "reapable" list where the reaper task + * can find it. And "reapable" means that this CTLX + * isn't sitting on a wait-queue somewhere. + */ + list_move_tail(&ctlx->list, &hw->ctlxq.reapable); + reap = 1; + } + + complete(&ctlx->done); + } + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + + if (reap) + tasklet_schedule(&hw->reaper_bh); + + DBFEXIT; +} + +/*---------------------------------------------------------------- +* unlocked_usbctlx_cancel_async +* +* Mark the CTLX dead asynchronously, and ensure that the +* next command on the queue is run afterwards. +* +* Arguments: +* hw ptr to the hfa384x_t structure +* ctlx ptr to a CTLX structure +* +* Returns: +* 0 the CTLX's URB is inactive +* -EINPROGRESS the URB is currently being unlinked +* +* Call context: +* Either process or interrupt, but presumably interrupt +----------------------------------------------------------------*/ +static int unlocked_usbctlx_cancel_async(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx) +{ + int ret; + + DBFENTER; + + /* + * Try to delete the URB containing our request packet. + * If we succeed, then its completion handler will be + * called with a status of -ECONNRESET. + */ + hw->ctlx_urb.transfer_flags |= URB_ASYNC_UNLINK; + ret = usb_unlink_urb(&hw->ctlx_urb); + + if (ret != -EINPROGRESS) { + /* + * The OUT URB had either already completed + * or was still in the pending queue, so the + * URB's completion function will not be called. + * We will have to complete the CTLX ourselves. + */ + ctlx->state = CTLX_REQ_FAILED; + unlocked_usbctlx_complete(hw, ctlx); + ret = 0; + } + + DBFEXIT; + + return ret; +} + +/*---------------------------------------------------------------- +* unlocked_usbctlx_complete +* +* A CTLX has completed. It may have been successful, it may not +* have been. At this point, the CTLX should be quiescent. The URBs +* aren't active and the timers should have been stopped. +* +* The CTLX is migrated to the "completing" queue, and the completing +* tasklet is scheduled. +* +* Arguments: +* hw ptr to a hfa384x_t structure +* ctlx ptr to a ctlx structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* Either, assume interrupt +----------------------------------------------------------------*/ +static void unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx) +{ + DBFENTER; + + /* Timers have been stopped, and ctlx should be in + * a terminal state. Retire it from the "active" + * queue. + */ + list_move_tail(&ctlx->list, &hw->ctlxq.completing); + tasklet_schedule(&hw->completion_bh); + + switch (ctlx->state) { + case CTLX_COMPLETE: + case CTLX_REQ_FAILED: + /* This are the correct terminating states. */ + break; + + default: + WLAN_LOG_ERROR("CTLX[%d] not in a terminating state(%s)\n", + hfa384x2host_16(ctlx->outbuf.type), + ctlxstr(ctlx->state)); + break; + } /* switch */ + + DBFEXIT; +} + +/*---------------------------------------------------------------- +* hfa384x_usbctlxq_run +* +* Checks to see if the head item is running. If not, starts it. +* +* Arguments: +* hw ptr to hfa384x_t +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* any +----------------------------------------------------------------*/ +static void +hfa384x_usbctlxq_run(hfa384x_t *hw) +{ + unsigned long flags; + DBFENTER; + + /* acquire lock */ + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + /* Only one active CTLX at any one time, because there's no + * other (reliable) way to match the response URB to the + * correct CTLX. + * + * Don't touch any of these CTLXs if the hardware + * has been removed or the USB subsystem is stalled. + */ + if ( !list_empty(&hw->ctlxq.active) || + test_bit(WORK_TX_HALT, &hw->usb_flags) || + hw->wlandev->hwremoved ) + goto unlock; + + while ( !list_empty(&hw->ctlxq.pending) ) { + hfa384x_usbctlx_t *head; + int result; + + /* This is the first pending command */ + head = list_entry(hw->ctlxq.pending.next, + hfa384x_usbctlx_t, + list); + + /* We need to split this off to avoid a race condition */ + list_move_tail(&head->list, &hw->ctlxq.active); + + /* Fill the out packet */ + usb_fill_bulk_urb( &(hw->ctlx_urb), hw->usb, + hw->endp_out, + &(head->outbuf), ROUNDUP64(head->outbufsize), + hfa384x_ctlxout_callback, hw); + hw->ctlx_urb.transfer_flags |= USB_QUEUE_BULK; + + /* Now submit the URB and update the CTLX's state + */ + if ((result = SUBMIT_URB(&hw->ctlx_urb, GFP_ATOMIC)) == 0) { + /* This CTLX is now running on the active queue */ + head->state = CTLX_REQ_SUBMITTED; + + /* Start the OUT wait timer */ + hw->req_timer_done = 0; + hw->reqtimer.expires = jiffies + HZ; + add_timer(&hw->reqtimer); + + /* Start the IN wait timer */ + hw->resp_timer_done = 0; + hw->resptimer.expires = jiffies + 2*HZ; + add_timer(&hw->resptimer); + + break; + } + + if (result == -EPIPE) { + /* The OUT pipe needs resetting, so put + * this CTLX back in the "pending" queue + * and schedule a reset ... + */ + WLAN_LOG_WARNING("%s tx pipe stalled: requesting reset\n", + hw->wlandev->netdev->name); + list_move(&head->list, &hw->ctlxq.pending); + set_bit(WORK_TX_HALT, &hw->usb_flags); + schedule_work(&hw->usb_work); + break; + } + + if (result == -ESHUTDOWN) { + WLAN_LOG_WARNING("%s urb shutdown!\n", + hw->wlandev->netdev->name); + break; + } + + WLAN_LOG_ERROR("Failed to submit CTLX[%d]: error=%d\n", + hfa384x2host_16(head->outbuf.type), result); + unlocked_usbctlx_complete(hw, head); + } /* while */ + + unlock: + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_usbin_callback +* +* Callback for URBs on the BULKIN endpoint. +* +* Arguments: +* urb ptr to the completed urb +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +#ifdef URB_ONLY_CALLBACK +static void hfa384x_usbin_callback(struct urb *urb) +#else +static void hfa384x_usbin_callback(struct urb *urb, struct pt_regs *regs) +#endif +{ + wlandevice_t *wlandev = urb->context; + hfa384x_t *hw; + hfa384x_usbin_t *usbin = (hfa384x_usbin_t *) urb->transfer_buffer; + struct sk_buff *skb = NULL; + int result; + int urb_status; + UINT16 type; + + enum USBIN_ACTION { + HANDLE, + RESUBMIT, + ABORT + } action; + + DBFENTER; + + if ( !wlandev || + !wlandev->netdev || + wlandev->hwremoved ) + goto exit; + + hw = wlandev->priv; + if (!hw) + goto exit; + + skb = hw->rx_urb_skb; + if (!skb || (skb->data != urb->transfer_buffer)) { + BUG(); + } + hw->rx_urb_skb = NULL; + + /* Check for error conditions within the URB */ + switch (urb->status) { + case 0: + action = HANDLE; + + /* Check for short packet */ + if ( urb->actual_length == 0 ) { + ++(wlandev->linux_stats.rx_errors); + ++(wlandev->linux_stats.rx_length_errors); + action = RESUBMIT; + } + break; + + case -EPIPE: + WLAN_LOG_WARNING("%s rx pipe stalled: requesting reset\n", + wlandev->netdev->name); + if ( !test_and_set_bit(WORK_RX_HALT, &hw->usb_flags) ) + schedule_work(&hw->usb_work); + ++(wlandev->linux_stats.rx_errors); + action = ABORT; + break; + + case -EILSEQ: + case -ETIMEDOUT: + case -EPROTO: + if ( !test_and_set_bit(THROTTLE_RX, &hw->usb_flags) && + !timer_pending(&hw->throttle) ) { + mod_timer(&hw->throttle, jiffies + THROTTLE_JIFFIES); + } + ++(wlandev->linux_stats.rx_errors); + action = ABORT; + break; + + case -EOVERFLOW: + ++(wlandev->linux_stats.rx_over_errors); + action = RESUBMIT; + break; + + case -ENODEV: + case -ESHUTDOWN: + WLAN_LOG_DEBUG(3,"status=%d, device removed.\n", urb->status); + action = ABORT; + break; + + case -ENOENT: + case -ECONNRESET: + WLAN_LOG_DEBUG(3,"status=%d, urb explicitly unlinked.\n", urb->status); + action = ABORT; + break; + + default: + WLAN_LOG_DEBUG(3,"urb status=%d, transfer flags=0x%x\n", + urb->status, urb->transfer_flags); + ++(wlandev->linux_stats.rx_errors); + action = RESUBMIT; + break; + } + + urb_status = urb->status; + + if (action != ABORT) { + /* Repost the RX URB */ + result = submit_rx_urb(hw, GFP_ATOMIC); + + if (result != 0) { + WLAN_LOG_ERROR( + "Fatal, failed to resubmit rx_urb. error=%d\n", + result); + } + } + + /* Handle any USB-IN packet */ + /* Note: the check of the sw_support field, the type field doesn't + * have bit 12 set like the docs suggest. + */ + type = hfa384x2host_16(usbin->type); + if (HFA384x_USB_ISRXFRM(type)) { + if (action == HANDLE) { + if (usbin->txfrm.desc.sw_support == 0x0123) { + hfa384x_usbin_txcompl(wlandev, usbin); + } else { + skb_put(skb, sizeof(*usbin)); + hfa384x_usbin_rx(wlandev, skb); + skb = NULL; + } + } + goto exit; + } + if (HFA384x_USB_ISTXFRM(type)) { + if (action == HANDLE) + hfa384x_usbin_txcompl(wlandev, usbin); + goto exit; + } + switch (type) { + case HFA384x_USB_INFOFRM: + if (action == ABORT) + goto exit; + if (action == HANDLE) + hfa384x_usbin_info(wlandev, usbin); + break; + + case HFA384x_USB_CMDRESP: + case HFA384x_USB_WRIDRESP: + case HFA384x_USB_RRIDRESP: + case HFA384x_USB_WMEMRESP: + case HFA384x_USB_RMEMRESP: + /* ALWAYS, ALWAYS, ALWAYS handle this CTLX!!!! */ + hfa384x_usbin_ctlx(hw, usbin, urb_status); + break; + + case HFA384x_USB_BUFAVAIL: + WLAN_LOG_DEBUG(3,"Received BUFAVAIL packet, frmlen=%d\n", + usbin->bufavail.frmlen); + break; + + case HFA384x_USB_ERROR: + WLAN_LOG_DEBUG(3,"Received USB_ERROR packet, errortype=%d\n", + usbin->usberror.errortype); + break; + + default: + WLAN_LOG_DEBUG(3,"Unrecognized USBIN packet, type=%x, status=%d\n", + usbin->type, urb_status); + break; + } /* switch */ + +exit: + + if (skb) + dev_kfree_skb(skb); + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_usbin_ctlx +* +* We've received a URB containing a Prism2 "response" message. +* This message needs to be matched up with a CTLX on the active +* queue and our state updated accordingly. +* +* Arguments: +* hw ptr to hfa384x_t +* usbin ptr to USB IN packet +* urb_status status of this Bulk-In URB +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void hfa384x_usbin_ctlx(hfa384x_t *hw, hfa384x_usbin_t *usbin, + int urb_status) +{ + hfa384x_usbctlx_t *ctlx; + int run_queue = 0; + unsigned long flags; + + DBFENTER; + +retry: + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + /* There can be only one CTLX on the active queue + * at any one time, and this is the CTLX that the + * timers are waiting for. + */ + if ( list_empty(&hw->ctlxq.active) ) { + goto unlock; + } + + /* Remove the "response timeout". It's possible that + * we are already too late, and that the timeout is + * already running. And that's just too bad for us, + * because we could lose our CTLX from the active + * queue here ... + */ + if (del_timer(&hw->resptimer) == 0) { + if (hw->resp_timer_done == 0) { + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + goto retry; + } + } + else { + hw->resp_timer_done = 1; + } + + ctlx = get_active_ctlx(hw); + + if (urb_status != 0) { + /* + * Bad CTLX, so get rid of it. But we only + * remove it from the active queue if we're no + * longer expecting the OUT URB to complete. + */ + if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0) + run_queue = 1; + } else { + const UINT16 intype = (usbin->type&~host2hfa384x_16(0x8000)); + + /* + * Check that our message is what we're expecting ... + */ + if (ctlx->outbuf.type != intype) { + WLAN_LOG_WARNING("Expected IN[%d], received IN[%d] - ignored.\n", + hfa384x2host_16(ctlx->outbuf.type), + hfa384x2host_16(intype)); + goto unlock; + } + + /* This URB has succeeded, so grab the data ... */ + memcpy(&ctlx->inbuf, usbin, sizeof(ctlx->inbuf)); + + switch (ctlx->state) { + case CTLX_REQ_SUBMITTED: + /* + * We have received our response URB before + * our request has been acknowledged. Odd, + * but our OUT URB is still alive... + */ + WLAN_LOG_DEBUG(0, "Causality violation: please reboot Universe, or email linux-wlan-devel@lists.linux-wlan.com\n"); + ctlx->state = CTLX_RESP_COMPLETE; + break; + + case CTLX_REQ_COMPLETE: + /* + * This is the usual path: our request + * has already been acknowledged, and + * now we have received the reply too. + */ + ctlx->state = CTLX_COMPLETE; + unlocked_usbctlx_complete(hw, ctlx); + run_queue = 1; + break; + + default: + /* + * Throw this CTLX away ... + */ + WLAN_LOG_ERROR("Matched IN URB, CTLX[%d] in invalid state(%s)." + " Discarded.\n", + hfa384x2host_16(ctlx->outbuf.type), + ctlxstr(ctlx->state)); + if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0) + run_queue = 1; + break; + } /* switch */ + } + +unlock: + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + + if (run_queue) + hfa384x_usbctlxq_run(hw); + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_usbin_txcompl +* +* At this point we have the results of a previous transmit. +* +* Arguments: +* wlandev wlan device +* usbin ptr to the usb transfer buffer +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void hfa384x_usbin_txcompl(wlandevice_t *wlandev, hfa384x_usbin_t *usbin) +{ + UINT16 status; + DBFENTER; + + status = hfa384x2host_16(usbin->type); /* yeah I know it says type...*/ + + /* Was there an error? */ + if (HFA384x_TXSTATUS_ISERROR(status)) { + prism2sta_ev_txexc(wlandev, status); + } else { + prism2sta_ev_tx(wlandev, status); + } + // prism2sta_ev_alloc(wlandev); + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_usbin_rx +* +* At this point we have a successful received a rx frame packet. +* +* Arguments: +* wlandev wlan device +* usbin ptr to the usb transfer buffer +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb) +{ + hfa384x_usbin_t *usbin = (hfa384x_usbin_t *) skb->data; + hfa384x_t *hw = wlandev->priv; + int hdrlen; + p80211_rxmeta_t *rxmeta; + UINT16 data_len; + UINT16 fc; + + DBFENTER; + + /* Byte order convert once up front. */ + usbin->rxfrm.desc.status = + hfa384x2host_16(usbin->rxfrm.desc.status); + usbin->rxfrm.desc.time = + hfa384x2host_32(usbin->rxfrm.desc.time); + + /* Now handle frame based on port# */ + switch( HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status) ) + { + case 0: + fc = ieee2host16(usbin->rxfrm.desc.frame_control); + + /* If exclude and we receive an unencrypted, drop it */ + if ( (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED) && + !WLAN_GET_FC_ISWEP(fc)){ + goto done; + } + + data_len = hfa384x2host_16(usbin->rxfrm.desc.data_len); + + /* How much header data do we have? */ + hdrlen = p80211_headerlen(fc); + + /* Pull off the descriptor */ + skb_pull(skb, sizeof(hfa384x_rx_frame_t)); + + /* Now shunt the header block up against the data block + * with an "overlapping" copy + */ + memmove(skb_push(skb, hdrlen), + &usbin->rxfrm.desc.frame_control, + hdrlen); + + skb->dev = wlandev->netdev; + skb->dev->last_rx = jiffies; + + /* And set the frame length properly */ + skb_trim(skb, data_len + hdrlen); + + /* The prism2 series does not return the CRC */ + memset(skb_put(skb, WLAN_CRC_LEN), 0xff, WLAN_CRC_LEN); + + skb_reset_mac_header(skb); + + /* Attach the rxmeta, set some stuff */ + p80211skb_rxmeta_attach(wlandev, skb); + rxmeta = P80211SKB_RXMETA(skb); + rxmeta->mactime = usbin->rxfrm.desc.time; + rxmeta->rxrate = usbin->rxfrm.desc.rate; + rxmeta->signal = usbin->rxfrm.desc.signal - hw->dbmadjust; + rxmeta->noise = usbin->rxfrm.desc.silence - hw->dbmadjust; + + prism2sta_ev_rx(wlandev, skb); + + break; + + case 7: + if ( ! HFA384x_RXSTATUS_ISFCSERR(usbin->rxfrm.desc.status) ) { + /* Copy to wlansnif skb */ + hfa384x_int_rxmonitor( wlandev, &usbin->rxfrm); + dev_kfree_skb(skb); + } else { + WLAN_LOG_DEBUG(3,"Received monitor frame: FCSerr set\n"); + } + break; + + default: + WLAN_LOG_WARNING("Received frame on unsupported port=%d\n", + HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status) ); + goto done; + break; + } + +done: + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* hfa384x_int_rxmonitor +* +* Helper function for int_rx. Handles monitor frames. +* Note that this function allocates space for the FCS and sets it +* to 0xffffffff. The hfa384x doesn't give us the FCS value but the +* higher layers expect it. 0xffffffff is used as a flag to indicate +* the FCS is bogus. +* +* Arguments: +* wlandev wlan device structure +* rxfrm rx descriptor read from card in int_rx +* +* Returns: +* nothing +* +* Side effects: +* Allocates an skb and passes it up via the PF_PACKET interface. +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void hfa384x_int_rxmonitor( wlandevice_t *wlandev, hfa384x_usb_rxfrm_t *rxfrm) +{ + hfa384x_rx_frame_t *rxdesc = &(rxfrm->desc); + UINT hdrlen = 0; + UINT datalen = 0; + UINT skblen = 0; + p80211msg_lnxind_wlansniffrm_t *msg; + UINT8 *datap; + UINT16 fc; + struct sk_buff *skb; + hfa384x_t *hw = wlandev->priv; + + + DBFENTER; + /* Don't forget the status, time, and data_len fields are in host order */ + /* Figure out how big the frame is */ + fc = ieee2host16(rxdesc->frame_control); + hdrlen = p80211_headerlen(fc); + datalen = hfa384x2host_16(rxdesc->data_len); + + /* Allocate an ind message+framesize skb */ + skblen = sizeof(p80211msg_lnxind_wlansniffrm_t) + + hdrlen + datalen + WLAN_CRC_LEN; + + /* sanity check the length */ + if ( skblen > + (sizeof(p80211msg_lnxind_wlansniffrm_t) + + WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN) ) { + WLAN_LOG_DEBUG(1, "overlen frm: len=%zd\n", + skblen - sizeof(p80211msg_lnxind_wlansniffrm_t)); + } + + if ( (skb = dev_alloc_skb(skblen)) == NULL ) { + WLAN_LOG_ERROR("alloc_skb failed trying to allocate %d bytes\n", skblen); + return; + } + + /* only prepend the prism header if in the right mode */ + if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) && + (hw->sniffhdr == 0)) { + datap = skb_put(skb, sizeof(p80211msg_lnxind_wlansniffrm_t)); + msg = (p80211msg_lnxind_wlansniffrm_t*) datap; + + /* Initialize the message members */ + msg->msgcode = DIDmsg_lnxind_wlansniffrm; + msg->msglen = sizeof(p80211msg_lnxind_wlansniffrm_t); + strcpy(msg->devname, wlandev->name); + + msg->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime; + msg->hosttime.status = 0; + msg->hosttime.len = 4; + msg->hosttime.data = jiffies; + + msg->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime; + msg->mactime.status = 0; + msg->mactime.len = 4; + msg->mactime.data = rxdesc->time; + + msg->channel.did = DIDmsg_lnxind_wlansniffrm_channel; + msg->channel.status = 0; + msg->channel.len = 4; + msg->channel.data = hw->sniff_channel; + + msg->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi; + msg->rssi.status = P80211ENUM_msgitem_status_no_value; + msg->rssi.len = 4; + msg->rssi.data = 0; + + msg->sq.did = DIDmsg_lnxind_wlansniffrm_sq; + msg->sq.status = P80211ENUM_msgitem_status_no_value; + msg->sq.len = 4; + msg->sq.data = 0; + + msg->signal.did = DIDmsg_lnxind_wlansniffrm_signal; + msg->signal.status = 0; + msg->signal.len = 4; + msg->signal.data = rxdesc->signal; + + msg->noise.did = DIDmsg_lnxind_wlansniffrm_noise; + msg->noise.status = 0; + msg->noise.len = 4; + msg->noise.data = rxdesc->silence; + + msg->rate.did = DIDmsg_lnxind_wlansniffrm_rate; + msg->rate.status = 0; + msg->rate.len = 4; + msg->rate.data = rxdesc->rate / 5; /* set to 802.11 units */ + + msg->istx.did = DIDmsg_lnxind_wlansniffrm_istx; + msg->istx.status = 0; + msg->istx.len = 4; + msg->istx.data = P80211ENUM_truth_false; + + msg->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen; + msg->frmlen.status = 0; + msg->frmlen.len = 4; + msg->frmlen.data = hdrlen + datalen + WLAN_CRC_LEN; + } else if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) && + (hw->sniffhdr != 0)) { + p80211_caphdr_t *caphdr; + /* The NEW header format! */ + datap = skb_put(skb, sizeof(p80211_caphdr_t)); + caphdr = (p80211_caphdr_t*) datap; + + caphdr->version = htonl(P80211CAPTURE_VERSION); + caphdr->length = htonl(sizeof(p80211_caphdr_t)); + caphdr->mactime = __cpu_to_be64(rxdesc->time) * 1000; + caphdr->hosttime = __cpu_to_be64(jiffies); + caphdr->phytype = htonl(4); /* dss_dot11_b */ + caphdr->channel = htonl(hw->sniff_channel); + caphdr->datarate = htonl(rxdesc->rate); + caphdr->antenna = htonl(0); /* unknown */ + caphdr->priority = htonl(0); /* unknown */ + caphdr->ssi_type = htonl(3); /* rssi_raw */ + caphdr->ssi_signal = htonl(rxdesc->signal); + caphdr->ssi_noise = htonl(rxdesc->silence); + caphdr->preamble = htonl(0); /* unknown */ + caphdr->encoding = htonl(1); /* cck */ + } + + /* Copy the 802.11 header to the skb (ctl frames may be less than a full header) */ + datap = skb_put(skb, hdrlen); + memcpy( datap, &(rxdesc->frame_control), hdrlen); + + /* If any, copy the data from the card to the skb */ + if ( datalen > 0 ) + { + datap = skb_put(skb, datalen); + memcpy(datap, rxfrm->data, datalen); + + /* check for unencrypted stuff if WEP bit set. */ + if (*(datap - hdrlen + 1) & 0x40) // wep set + if ((*(datap) == 0xaa) && (*(datap+1) == 0xaa)) + *(datap - hdrlen + 1) &= 0xbf; // clear wep; it's the 802.2 header! + } + + if (hw->sniff_fcs) { + /* Set the FCS */ + datap = skb_put(skb, WLAN_CRC_LEN); + memset( datap, 0xff, WLAN_CRC_LEN); + } + + /* pass it back up */ + prism2sta_ev_rx(wlandev, skb); + + DBFEXIT; + return; +} + + + +/*---------------------------------------------------------------- +* hfa384x_usbin_info +* +* At this point we have a successful received a Prism2 info frame. +* +* Arguments: +* wlandev wlan device +* usbin ptr to the usb transfer buffer +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin) +{ + DBFENTER; + + usbin->infofrm.info.framelen = hfa384x2host_16(usbin->infofrm.info.framelen); + prism2sta_ev_info(wlandev, &usbin->infofrm.info); + + DBFEXIT; +} + + + +/*---------------------------------------------------------------- +* hfa384x_usbout_callback +* +* Callback for URBs on the BULKOUT endpoint. +* +* Arguments: +* urb ptr to the completed urb +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +#ifdef URB_ONLY_CALLBACK +static void hfa384x_usbout_callback(struct urb *urb) +#else +static void hfa384x_usbout_callback(struct urb *urb, struct pt_regs *regs) +#endif +{ + wlandevice_t *wlandev = urb->context; + hfa384x_usbout_t *usbout = urb->transfer_buffer; + DBFENTER; + +#ifdef DEBUG_USB + dbprint_urb(urb); +#endif + + if ( wlandev && + wlandev->netdev ) { + + switch(urb->status) { + case 0: + hfa384x_usbout_tx(wlandev, usbout); + break; + + case -EPIPE: + { + hfa384x_t *hw = wlandev->priv; + WLAN_LOG_WARNING("%s tx pipe stalled: requesting reset\n", + wlandev->netdev->name); + if ( !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags) ) + schedule_work(&hw->usb_work); + ++(wlandev->linux_stats.tx_errors); + break; + } + + case -EPROTO: + case -ETIMEDOUT: + case -EILSEQ: + { + hfa384x_t *hw = wlandev->priv; + + if ( !test_and_set_bit(THROTTLE_TX, &hw->usb_flags) + && !timer_pending(&hw->throttle) ) { + mod_timer(&hw->throttle, + jiffies + THROTTLE_JIFFIES); + } + ++(wlandev->linux_stats.tx_errors); + netif_stop_queue(wlandev->netdev); + break; + } + + case -ENOENT: + case -ESHUTDOWN: + /* Ignorable errors */ + break; + + default: + WLAN_LOG_INFO("unknown urb->status=%d\n", urb->status); + ++(wlandev->linux_stats.tx_errors); + break; + } /* switch */ + } + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_ctlxout_callback +* +* Callback for control data on the BULKOUT endpoint. +* +* Arguments: +* urb ptr to the completed urb +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +#ifdef URB_ONLY_CALLBACK +static void hfa384x_ctlxout_callback(struct urb *urb) +#else +static void hfa384x_ctlxout_callback(struct urb *urb, struct pt_regs *regs) +#endif +{ + hfa384x_t *hw = urb->context; + int delete_resptimer = 0; + int timer_ok = 1; + int run_queue = 0; + hfa384x_usbctlx_t *ctlx; + unsigned long flags; + + DBFENTER; + + WLAN_LOG_DEBUG(3,"urb->status=%d\n", urb->status); +#ifdef DEBUG_USB + dbprint_urb(urb); +#endif + if ( (urb->status == -ESHUTDOWN) || + (urb->status == -ENODEV) || + (hw == NULL) ) + goto done; + +retry: + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + /* + * Only one CTLX at a time on the "active" list, and + * none at all if we are unplugged. However, we can + * rely on the disconnect function to clean everything + * up if someone unplugged the adapter. + */ + if ( list_empty(&hw->ctlxq.active) ) { + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + goto done; + } + + /* + * Having something on the "active" queue means + * that we have timers to worry about ... + */ + if (del_timer(&hw->reqtimer) == 0) { + if (hw->req_timer_done == 0) { + /* + * This timer was actually running while we + * were trying to delete it. Let it terminate + * gracefully instead. + */ + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + goto retry; + } + } + else { + hw->req_timer_done = 1; + } + + ctlx = get_active_ctlx(hw); + + if ( urb->status == 0 ) { + /* Request portion of a CTLX is successful */ + switch ( ctlx->state ) { + case CTLX_REQ_SUBMITTED: + /* This OUT-ACK received before IN */ + ctlx->state = CTLX_REQ_COMPLETE; + break; + + case CTLX_RESP_COMPLETE: + /* IN already received before this OUT-ACK, + * so this command must now be complete. + */ + ctlx->state = CTLX_COMPLETE; + unlocked_usbctlx_complete(hw, ctlx); + run_queue = 1; + break; + + default: + /* This is NOT a valid CTLX "success" state! */ + WLAN_LOG_ERROR( + "Illegal CTLX[%d] success state(%s, %d) in OUT URB\n", + hfa384x2host_16(ctlx->outbuf.type), + ctlxstr(ctlx->state), urb->status); + break; + } /* switch */ + } else { + /* If the pipe has stalled then we need to reset it */ + if ( (urb->status == -EPIPE) && + !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags) ) { + WLAN_LOG_WARNING("%s tx pipe stalled: requesting reset\n", + hw->wlandev->netdev->name); + schedule_work(&hw->usb_work); + } + + /* If someone cancels the OUT URB then its status + * should be either -ECONNRESET or -ENOENT. + */ + ctlx->state = CTLX_REQ_FAILED; + unlocked_usbctlx_complete(hw, ctlx); + delete_resptimer = 1; + run_queue = 1; + } + + delresp: + if (delete_resptimer) { + if ((timer_ok = del_timer(&hw->resptimer)) != 0) { + hw->resp_timer_done = 1; + } + } + + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + + if ( !timer_ok && (hw->resp_timer_done == 0) ) { + spin_lock_irqsave(&hw->ctlxq.lock, flags); + goto delresp; + } + + if (run_queue) + hfa384x_usbctlxq_run(hw); + + done: + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_usbctlx_reqtimerfn +* +* Timer response function for CTLX request timeouts. If this +* function is called, it means that the callback for the OUT +* URB containing a Prism2.x XXX_Request was never called. +* +* Arguments: +* data a ptr to the hfa384x_t +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void +hfa384x_usbctlx_reqtimerfn(unsigned long data) +{ + hfa384x_t *hw = (hfa384x_t*)data; + unsigned long flags; + DBFENTER; + + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + hw->req_timer_done = 1; + + /* Removing the hardware automatically empties + * the active list ... + */ + if ( !list_empty(&hw->ctlxq.active) ) + { + /* + * We must ensure that our URB is removed from + * the system, if it hasn't already expired. + */ + hw->ctlx_urb.transfer_flags |= URB_ASYNC_UNLINK; + if (usb_unlink_urb(&hw->ctlx_urb) == -EINPROGRESS) + { + hfa384x_usbctlx_t *ctlx = get_active_ctlx(hw); + + ctlx->state = CTLX_REQ_FAILED; + + /* This URB was active, but has now been + * cancelled. It will now have a status of + * -ECONNRESET in the callback function. + * + * We are cancelling this CTLX, so we're + * not going to need to wait for a response. + * The URB's callback function will check + * that this timer is truly dead. + */ + if (del_timer(&hw->resptimer) != 0) + hw->resp_timer_done = 1; + } + } + + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_usbctlx_resptimerfn +* +* Timer response function for CTLX response timeouts. If this +* function is called, it means that the callback for the IN +* URB containing a Prism2.x XXX_Response was never called. +* +* Arguments: +* data a ptr to the hfa384x_t +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void +hfa384x_usbctlx_resptimerfn(unsigned long data) +{ + hfa384x_t *hw = (hfa384x_t*)data; + unsigned long flags; + + DBFENTER; + + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + hw->resp_timer_done = 1; + + /* The active list will be empty if the + * adapter has been unplugged ... + */ + if ( !list_empty(&hw->ctlxq.active) ) + { + hfa384x_usbctlx_t *ctlx = get_active_ctlx(hw); + + if ( unlocked_usbctlx_cancel_async(hw, ctlx) == 0 ) + { + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + hfa384x_usbctlxq_run(hw); + goto done; + } + } + + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + + done: + DBFEXIT; +} + +/*---------------------------------------------------------------- +* hfa384x_usb_throttlefn +* +* +* Arguments: +* data ptr to hw +* +* Returns: +* Nothing +* +* Side effects: +* +* Call context: +* Interrupt +----------------------------------------------------------------*/ +static void +hfa384x_usb_throttlefn(unsigned long data) +{ + hfa384x_t *hw = (hfa384x_t*)data; + unsigned long flags; + + DBFENTER; + + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + /* + * We need to check BOTH the RX and the TX throttle controls, + * so we use the bitwise OR instead of the logical OR. + */ + WLAN_LOG_DEBUG(3, "flags=0x%lx\n", hw->usb_flags); + if ( !hw->wlandev->hwremoved && + ( + (test_and_clear_bit(THROTTLE_RX, &hw->usb_flags) && + !test_and_set_bit(WORK_RX_RESUME, &hw->usb_flags)) + | + (test_and_clear_bit(THROTTLE_TX, &hw->usb_flags) && + !test_and_set_bit(WORK_TX_RESUME, &hw->usb_flags)) + ) ) + { + schedule_work(&hw->usb_work); + } + + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_usbctlx_submit +* +* Called from the doxxx functions to submit a CTLX to the queue +* +* Arguments: +* hw ptr to the hw struct +* ctlx ctlx structure to enqueue +* +* Returns: +* -ENODEV if the adapter is unplugged +* 0 +* +* Side effects: +* +* Call context: +* process or interrupt +----------------------------------------------------------------*/ +static int +hfa384x_usbctlx_submit( + hfa384x_t *hw, + hfa384x_usbctlx_t *ctlx) +{ + unsigned long flags; + int ret; + + DBFENTER; + + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + if (hw->wlandev->hwremoved) { + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + ret = -ENODEV; + } else { + ctlx->state = CTLX_PENDING; + list_add_tail(&ctlx->list, &hw->ctlxq.pending); + + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + hfa384x_usbctlxq_run(hw); + ret = 0; + } + + DBFEXIT; + return ret; +} + + +/*---------------------------------------------------------------- +* hfa384x_usbout_tx +* +* At this point we have finished a send of a frame. Mark the URB +* as available and call ev_alloc to notify higher layers we're +* ready for more. +* +* Arguments: +* wlandev wlan device +* usbout ptr to the usb transfer buffer +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void hfa384x_usbout_tx(wlandevice_t *wlandev, hfa384x_usbout_t *usbout) +{ + DBFENTER; + + prism2sta_ev_alloc(wlandev); + + DBFEXIT; +} + +/*---------------------------------------------------------------- +* hfa384x_isgood_pdrcore +* +* Quick check of PDR codes. +* +* Arguments: +* pdrcode PDR code number (host order) +* +* Returns: +* zero not good. +* one is good. +* +* Side effects: +* +* Call context: +----------------------------------------------------------------*/ +static int +hfa384x_isgood_pdrcode(UINT16 pdrcode) +{ + switch(pdrcode) { + case HFA384x_PDR_END_OF_PDA: + case HFA384x_PDR_PCB_PARTNUM: + case HFA384x_PDR_PDAVER: + case HFA384x_PDR_NIC_SERIAL: + case HFA384x_PDR_MKK_MEASUREMENTS: + case HFA384x_PDR_NIC_RAMSIZE: + case HFA384x_PDR_MFISUPRANGE: + case HFA384x_PDR_CFISUPRANGE: + case HFA384x_PDR_NICID: + case HFA384x_PDR_MAC_ADDRESS: + case HFA384x_PDR_REGDOMAIN: + case HFA384x_PDR_ALLOWED_CHANNEL: + case HFA384x_PDR_DEFAULT_CHANNEL: + case HFA384x_PDR_TEMPTYPE: + case HFA384x_PDR_IFR_SETTING: + case HFA384x_PDR_RFR_SETTING: + case HFA384x_PDR_HFA3861_BASELINE: + case HFA384x_PDR_HFA3861_SHADOW: + case HFA384x_PDR_HFA3861_IFRF: + case HFA384x_PDR_HFA3861_CHCALSP: + case HFA384x_PDR_HFA3861_CHCALI: + case HFA384x_PDR_3842_NIC_CONFIG: + case HFA384x_PDR_USB_ID: + case HFA384x_PDR_PCI_ID: + case HFA384x_PDR_PCI_IFCONF: + case HFA384x_PDR_PCI_PMCONF: + case HFA384x_PDR_RFENRGY: + case HFA384x_PDR_HFA3861_MANF_TESTSP: + case HFA384x_PDR_HFA3861_MANF_TESTI: + /* code is OK */ + return 1; + break; + default: + if ( pdrcode < 0x1000 ) { + /* code is OK, but we don't know exactly what it is */ + WLAN_LOG_DEBUG(3, + "Encountered unknown PDR#=0x%04x, " + "assuming it's ok.\n", + pdrcode); + return 1; + } else { + /* bad code */ + WLAN_LOG_DEBUG(3, + "Encountered unknown PDR#=0x%04x, " + "(>=0x1000), assuming it's bad.\n", + pdrcode); + return 0; + } + break; + } + return 0; /* avoid compiler warnings */ +} + --- linux-2.6.28.orig/ubuntu/misc/wireless/prism2_usb/prism2mib.c +++ linux-2.6.28/ubuntu/misc/wireless/prism2_usb/prism2mib.c @@ -0,0 +1,3794 @@ +/* src/prism2/driver/prism2mib.c +* +* Management request for mibset/mibget +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* The functions in this file handle the mibset/mibget management +* functions. +* +* -------------------------------------------------------------------- +*/ + +/*================================================================*/ +/* System Includes */ +#define WLAN_DBVAR prism2_debug + +#include + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#if (WLAN_HOSTIF == WLAN_PCMCIA) +#include +#include +#include +#include +#include +#include +#endif + +#if ((WLAN_HOSTIF == WLAN_PLX) || (WLAN_HOSTIF == WLAN_PCI)) +#include +#include +#endif + +#if (WLAN_HOSTIF == WLAN_USB) +#include +#endif + +#include + +/*================================================================*/ +/* Project Includes */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*================================================================*/ +/* Local Constants */ + +#define MIB_TMP_MAXLEN 200 /* Max length of RID record (in bytes). */ + +/*================================================================*/ +/* Local Types */ + +#define F_AP 0x1 /* MIB is supported on Access Points. */ +#define F_STA 0x2 /* MIB is supported on stations. */ +#define F_READ 0x4 /* MIB may be read. */ +#define F_WRITE 0x8 /* MIB may be written. */ + +typedef struct mibrec +{ + UINT32 did; + UINT16 flag; + UINT16 parm1; + UINT16 parm2; + UINT16 parm3; + int (*func)(struct mibrec *mib, + int isget, + wlandevice_t *wlandev, + hfa384x_t *hw, + p80211msg_dot11req_mibset_t *msg, + void *data); +} mibrec_t; + +/*================================================================*/ +/* Local Function Declarations */ + +static int prism2mib_bytestr2pstr( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_bytearea2pstr( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_uint32( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_uint32array( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_uint32offset( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_truth( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_preamble( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_flag( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_appcfinfoflag( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_regulatorydomains( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_wepdefaultkey( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_powermanagement( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_privacyinvoked( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_excludeunencrypted( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_fragmentationthreshold( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_operationalrateset( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_groupaddress( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_fwid( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_authalg( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_authalgenable( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_priv( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static void prism2mib_priv_authlist( +hfa384x_t *hw, +prism2sta_authlist_t *list); + +static void prism2mib_priv_accessmode( +hfa384x_t *hw, +UINT32 mode); + +static void prism2mib_priv_accessallow( +hfa384x_t *hw, +p80211macarray_t *macarray); + +static void prism2mib_priv_accessdeny( +hfa384x_t *hw, +p80211macarray_t *macarray); + +static void prism2mib_priv_deauthenticate( +hfa384x_t *hw, +UINT8 *addr); + +/*================================================================*/ +/* Local Static Definitions */ + +static mibrec_t mibtab[] = { + + /* dot11smt MIB's */ + + { DIDmib_dot11smt_dot11StationConfigTable_dot11StationID, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFOWNMACADDR, HFA384x_RID_CNFOWNMACADDR_LEN, 0, + prism2mib_bytearea2pstr }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11MediumOccupancyLimit, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 0, + prism2mib_uint32offset }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11CFPollable, + F_STA | F_READ, + HFA384x_RID_CFPOLLABLE, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11CFPPeriod, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 1, + prism2mib_uint32offset }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11CFPMaxDuration, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 2, + prism2mib_uint32offset }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11AuthenticationResponseTimeOut, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFAUTHRSPTIMEOUT, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11PrivacyOptionImplemented, + F_AP | F_STA | F_READ, + HFA384x_RID_PRIVACYOPTIMP, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11PowerManagementMode, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFPMENABLED, 0, 0, + prism2mib_powermanagement }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11DesiredSSID, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFDESIREDSSID, HFA384x_RID_CNFDESIREDSSID_LEN, 0, + prism2mib_bytestr2pstr }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11DesiredBSSType, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_priv }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11OperationalRateSet, + F_STA | F_READ | F_WRITE, + HFA384x_RID_TXRATECNTL, 0, 0, + prism2mib_operationalrateset }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11OperationalRateSet, + F_AP | F_READ | F_WRITE, + HFA384x_RID_TXRATECNTL0, 0, 0, + prism2mib_operationalrateset }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11BeaconPeriod, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFAPBCNINT, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11DTIMPeriod, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFOWNDTIMPER, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11AssociationResponseTimeOut, + F_AP | F_STA | F_READ, + HFA384x_RID_PROTOCOLRSPTIME, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm1, + F_AP | F_STA | F_READ, + 1, 0, 0, + prism2mib_authalg }, + { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm2, + F_AP | F_STA | F_READ, + 2, 0, 0, + prism2mib_authalg }, + { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm3, + F_AP | F_STA | F_READ, + 3, 0, 0, + prism2mib_authalg }, + { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm4, + F_AP | F_STA | F_READ, + 4, 0, 0, + prism2mib_authalg }, + { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm5, + F_AP | F_STA | F_READ, + 5, 0, 0, + prism2mib_authalg }, + { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm6, + F_AP | F_STA | F_READ, + 6, 0, 0, + prism2mib_authalg }, + { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable1, + F_AP | F_STA | F_READ | F_WRITE, + 1, 0, 0, + prism2mib_authalgenable }, + { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable2, + F_AP | F_STA | F_READ | F_WRITE, + 2, 0, 0, + prism2mib_authalgenable }, + { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable3, + F_AP | F_STA | F_READ | F_WRITE, + 3, 0, 0, + prism2mib_authalgenable }, + { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable4, + F_AP | F_STA | F_READ | F_WRITE, + 4, 0, 0, + prism2mib_authalgenable }, + { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable5, + F_AP | F_STA | F_READ | F_WRITE, + 5, 0, 0, + prism2mib_authalgenable }, + { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable6, + F_AP | F_STA | F_READ | F_WRITE, + 6, 0, 0, + prism2mib_authalgenable }, + { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0, + F_AP | F_STA | F_WRITE, + HFA384x_RID_CNFWEPDEFAULTKEY0, 0, 0, + prism2mib_wepdefaultkey }, + { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1, + F_AP | F_STA | F_WRITE, + HFA384x_RID_CNFWEPDEFAULTKEY1, 0, 0, + prism2mib_wepdefaultkey }, + { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2, + F_AP | F_STA | F_WRITE, + HFA384x_RID_CNFWEPDEFAULTKEY2, 0, 0, + prism2mib_wepdefaultkey }, + { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3, + F_AP | F_STA | F_WRITE, + HFA384x_RID_CNFWEPDEFAULTKEY3, 0, 0, + prism2mib_wepdefaultkey }, + { DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_PRIVINVOKED, 0, + prism2mib_privacyinvoked }, + { DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFWEPDEFAULTKEYID, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_EXCLUDE, 0, + prism2mib_excludeunencrypted }, + { DIDmib_dot11phy_dot11PhyOperationTable_dot11ShortPreambleEnabled, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFSHORTPREAMBLE, 0, 0, + prism2mib_preamble }, + + /* dot11mac MIB's */ + + { DIDmib_dot11mac_dot11OperationTable_dot11MACAddress, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFOWNMACADDR, HFA384x_RID_CNFOWNMACADDR_LEN, 0, + prism2mib_bytearea2pstr }, + { DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold, + F_STA | F_READ | F_WRITE, + HFA384x_RID_RTSTHRESH, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold, + F_AP | F_READ | F_WRITE, + HFA384x_RID_RTSTHRESH0, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit, + F_AP | F_STA | F_READ, + HFA384x_RID_SHORTRETRYLIMIT, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit, + F_AP | F_STA | F_READ, + HFA384x_RID_LONGRETRYLIMIT, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold, + F_STA | F_READ | F_WRITE, + HFA384x_RID_FRAGTHRESH, 0, 0, + prism2mib_fragmentationthreshold }, + { DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold, + F_AP | F_READ | F_WRITE, + HFA384x_RID_FRAGTHRESH0, 0, 0, + prism2mib_fragmentationthreshold }, + { DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime, + F_AP | F_STA | F_READ, + HFA384x_RID_MAXTXLIFETIME, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11mac_dot11OperationTable_dot11MaxReceiveLifetime, + F_AP | F_STA | F_READ, + HFA384x_RID_MAXRXLIFETIME, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address1, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address2, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address3, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address4, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address5, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address6, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address7, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address8, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address9, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address10, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address11, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address12, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address13, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address14, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address15, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address16, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address17, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address18, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address19, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address20, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address21, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address22, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address23, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address24, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address25, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address26, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address27, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address28, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address29, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address30, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address31, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address32, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + + /* dot11phy MIB's */ + + { DIDmib_dot11phy_dot11PhyOperationTable_dot11PHYType, + F_AP | F_STA | F_READ, + HFA384x_RID_PHYTYPE, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11phy_dot11PhyOperationTable_dot11TempType, + F_AP | F_STA | F_READ, + HFA384x_RID_TEMPTYPE, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel, + F_STA | F_READ, + HFA384x_RID_CURRENTCHANNEL, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel, + F_AP | F_READ, + HFA384x_RID_CNFOWNCHANNEL, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentCCAMode, + F_AP | F_STA | F_READ, + HFA384x_RID_CCAMODE, 0, 0, + prism2mib_uint32 }, + + /* p2Table MIB's */ + + { DIDmib_p2_p2Table_p2MMTx, + F_AP | F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_priv }, + { DIDmib_p2_p2Table_p2EarlyBeacon, + F_AP | F_READ | F_WRITE, + BIT7, 0, 0, + prism2mib_appcfinfoflag }, + { DIDmib_p2_p2Table_p2ReceivedFrameStatistics, + F_AP | F_STA | F_READ, + 0, 0, 0, + prism2mib_priv }, + { DIDmib_p2_p2Table_p2CommunicationTallies, + F_AP | F_STA | F_READ, + 0, 0, 0, + prism2mib_priv }, + { DIDmib_p2_p2Table_p2Authenticated, + F_AP | F_READ, + 0, 0, 0, + prism2mib_priv }, + { DIDmib_p2_p2Table_p2Associated, + F_AP | F_READ, + 0, 0, 0, + prism2mib_priv }, + { DIDmib_p2_p2Table_p2PowerSaveUserCount, + F_AP | F_READ, + 0, 0, 0, + prism2mib_priv }, + { DIDmib_p2_p2Table_p2Comment, + F_AP | F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_priv }, + { DIDmib_p2_p2Table_p2AccessMode, + F_AP | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_priv }, + { DIDmib_p2_p2Table_p2AccessAllow, + F_AP | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_priv }, + { DIDmib_p2_p2Table_p2AccessDeny, + F_AP | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_priv }, + { DIDmib_p2_p2Table_p2ChannelInfoResults, + F_AP | F_READ, + 0, 0, 0, + prism2mib_priv }, + + /* p2Static MIB's */ + + { DIDmib_p2_p2Static_p2CnfPortType, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFPORTTYPE, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfOwnMACAddress, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFOWNMACADDR, HFA384x_RID_CNFOWNMACADDR_LEN, 0, + prism2mib_bytearea2pstr }, + { DIDmib_p2_p2Static_p2CnfDesiredSSID, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFDESIREDSSID, HFA384x_RID_CNFDESIREDSSID_LEN, 0, + prism2mib_bytestr2pstr }, + { DIDmib_p2_p2Static_p2CnfOwnChannel, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFOWNCHANNEL, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfOwnSSID, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFOWNSSID, HFA384x_RID_CNFOWNSSID_LEN, 0, + prism2mib_bytestr2pstr }, + { DIDmib_p2_p2Static_p2CnfOwnATIMWindow, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFOWNATIMWIN, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfSystemScale, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFSYSSCALE, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfMaxDataLength, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFMAXDATALEN, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfWDSAddress, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFWDSADDR, HFA384x_RID_CNFWDSADDR_LEN, 0, + prism2mib_bytearea2pstr }, + { DIDmib_p2_p2Static_p2CnfPMEnabled, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFPMENABLED, 0, 0, + prism2mib_truth }, + { DIDmib_p2_p2Static_p2CnfPMEPS, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFPMEPS, 0, 0, + prism2mib_truth }, + { DIDmib_p2_p2Static_p2CnfMulticastReceive, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFMULTICASTRX, 0, 0, + prism2mib_truth }, + { DIDmib_p2_p2Static_p2CnfMaxSleepDuration, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFMAXSLEEPDUR, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfPMHoldoverDuration, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFPMHOLDDUR, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfOwnName, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFOWNNAME, HFA384x_RID_CNFOWNNAME_LEN, 0, + prism2mib_bytestr2pstr }, + { DIDmib_p2_p2Static_p2CnfOwnDTIMPeriod, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFOWNDTIMPER, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfWDSAddress1, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFWDSADDR1, HFA384x_RID_CNFWDSADDR1_LEN, 0, + prism2mib_bytearea2pstr }, + { DIDmib_p2_p2Static_p2CnfWDSAddress2, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFWDSADDR2, HFA384x_RID_CNFWDSADDR2_LEN, 0, + prism2mib_bytearea2pstr }, + { DIDmib_p2_p2Static_p2CnfWDSAddress3, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFWDSADDR3, HFA384x_RID_CNFWDSADDR3_LEN, 0, + prism2mib_bytearea2pstr }, + { DIDmib_p2_p2Static_p2CnfWDSAddress4, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFWDSADDR4, HFA384x_RID_CNFWDSADDR4_LEN, 0, + prism2mib_bytearea2pstr }, + { DIDmib_p2_p2Static_p2CnfWDSAddress5, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFWDSADDR5, HFA384x_RID_CNFWDSADDR5_LEN, 0, + prism2mib_bytearea2pstr }, + { DIDmib_p2_p2Static_p2CnfWDSAddress6, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFWDSADDR6, HFA384x_RID_CNFWDSADDR6_LEN, 0, + prism2mib_bytearea2pstr }, + { DIDmib_p2_p2Static_p2CnfMulticastPMBuffering, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFMCASTPMBUFF, 0, 0, + prism2mib_truth }, + { DIDmib_p2_p2Static_p2CnfWEPDefaultKeyID, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFWEPDEFAULTKEYID, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfWEPDefaultKey0, + F_AP | F_STA | F_WRITE, + HFA384x_RID_CNFWEPDEFAULTKEY0, 0, 0, + prism2mib_wepdefaultkey }, + { DIDmib_p2_p2Static_p2CnfWEPDefaultKey1, + F_AP | F_STA | F_WRITE, + HFA384x_RID_CNFWEPDEFAULTKEY1, 0, 0, + prism2mib_wepdefaultkey }, + { DIDmib_p2_p2Static_p2CnfWEPDefaultKey2, + F_AP | F_STA | F_WRITE, + HFA384x_RID_CNFWEPDEFAULTKEY2, 0, 0, + prism2mib_wepdefaultkey }, + { DIDmib_p2_p2Static_p2CnfWEPDefaultKey3, + F_AP | F_STA | F_WRITE, + HFA384x_RID_CNFWEPDEFAULTKEY3, 0, 0, + prism2mib_wepdefaultkey }, + { DIDmib_p2_p2Static_p2CnfWEPFlags, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFWEPFLAGS, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfAuthentication, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFAUTHENTICATION, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfMaxAssociatedStations, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFMAXASSOCSTATIONS, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfTxControl, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFTXCONTROL, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfRoamingMode, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFROAMINGMODE, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfHostAuthentication, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFHOSTAUTHASSOC, 0, 0, + prism2mib_truth }, + { DIDmib_p2_p2Static_p2CnfRcvCrcError, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFRCVCRCERROR, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfAltRetryCount, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFALTRETRYCNT, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfBeaconInterval, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFAPBCNINT, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfMediumOccupancyLimit, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 0, + prism2mib_uint32offset }, + { DIDmib_p2_p2Static_p2CnfCFPPeriod, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 1, + prism2mib_uint32offset }, + { DIDmib_p2_p2Static_p2CnfCFPMaxDuration, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 2, + prism2mib_uint32offset }, + { DIDmib_p2_p2Static_p2CnfCFPFlags, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 3, + prism2mib_uint32offset }, + { DIDmib_p2_p2Static_p2CnfSTAPCFInfo, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFSTAPCFINFO, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfPriorityQUsage, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFPRIORITYQUSAGE, HFA384x_RID_CNFPRIOQUSAGE_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2Static_p2CnfTIMCtrl, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFTIMCTRL, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfThirty2Tally, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFTHIRTY2TALLY, 0, 0, + prism2mib_truth }, + { DIDmib_p2_p2Static_p2CnfEnhSecurity, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFENHSECURITY, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfShortPreamble, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFSHORTPREAMBLE, 0, 0, + prism2mib_preamble }, + { DIDmib_p2_p2Static_p2CnfExcludeLongPreamble, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFEXCLONGPREAMBLE, 0, 0, + prism2mib_truth }, + { DIDmib_p2_p2Static_p2CnfAuthenticationRspTO, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFAUTHRSPTIMEOUT, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfBasicRates, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFBASICRATES, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfSupportedRates, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFSUPPRATES, 0, 0, + prism2mib_uint32 }, + + /* p2Dynamic MIB's */ + + { DIDmib_p2_p2Dynamic_p2CreateIBSS, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CREATEIBSS, 0, 0, + prism2mib_truth }, + { DIDmib_p2_p2Dynamic_p2FragmentationThreshold, + F_STA | F_READ | F_WRITE, + HFA384x_RID_FRAGTHRESH, 0, 0, + prism2mib_fragmentationthreshold }, + { DIDmib_p2_p2Dynamic_p2RTSThreshold, + F_STA | F_READ | F_WRITE, + HFA384x_RID_RTSTHRESH, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2TxRateControl, + F_STA | F_READ | F_WRITE, + HFA384x_RID_TXRATECNTL, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2PromiscuousMode, + F_STA | F_READ | F_WRITE, + HFA384x_RID_PROMISCMODE, 0, 0, + prism2mib_truth }, + { DIDmib_p2_p2Dynamic_p2FragmentationThreshold0, + F_AP | F_READ | F_WRITE, + HFA384x_RID_FRAGTHRESH0, 0, 0, + prism2mib_fragmentationthreshold }, + { DIDmib_p2_p2Dynamic_p2FragmentationThreshold1, + F_AP | F_READ | F_WRITE, + HFA384x_RID_FRAGTHRESH1, 0, 0, + prism2mib_fragmentationthreshold }, + { DIDmib_p2_p2Dynamic_p2FragmentationThreshold2, + F_AP | F_READ | F_WRITE, + HFA384x_RID_FRAGTHRESH2, 0, 0, + prism2mib_fragmentationthreshold }, + { DIDmib_p2_p2Dynamic_p2FragmentationThreshold3, + F_AP | F_READ | F_WRITE, + HFA384x_RID_FRAGTHRESH3, 0, 0, + prism2mib_fragmentationthreshold }, + { DIDmib_p2_p2Dynamic_p2FragmentationThreshold4, + F_AP | F_READ | F_WRITE, + HFA384x_RID_FRAGTHRESH4, 0, 0, + prism2mib_fragmentationthreshold }, + { DIDmib_p2_p2Dynamic_p2FragmentationThreshold5, + F_AP | F_READ | F_WRITE, + HFA384x_RID_FRAGTHRESH5, 0, 0, + prism2mib_fragmentationthreshold }, + { DIDmib_p2_p2Dynamic_p2FragmentationThreshold6, + F_AP | F_READ | F_WRITE, + HFA384x_RID_FRAGTHRESH6, 0, 0, + prism2mib_fragmentationthreshold }, + { DIDmib_p2_p2Dynamic_p2RTSThreshold0, + F_AP | F_READ | F_WRITE, + HFA384x_RID_RTSTHRESH0, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2RTSThreshold1, + F_AP | F_READ | F_WRITE, + HFA384x_RID_RTSTHRESH1, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2RTSThreshold2, + F_AP | F_READ | F_WRITE, + HFA384x_RID_RTSTHRESH2, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2RTSThreshold3, + F_AP | F_READ | F_WRITE, + HFA384x_RID_RTSTHRESH3, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2RTSThreshold4, + F_AP | F_READ | F_WRITE, + HFA384x_RID_RTSTHRESH4, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2RTSThreshold5, + F_AP | F_READ | F_WRITE, + HFA384x_RID_RTSTHRESH5, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2RTSThreshold6, + F_AP | F_READ | F_WRITE, + HFA384x_RID_RTSTHRESH6, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2TxRateControl0, + F_AP | F_READ | F_WRITE, + HFA384x_RID_TXRATECNTL0, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2TxRateControl1, + F_AP | F_READ | F_WRITE, + HFA384x_RID_TXRATECNTL1, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2TxRateControl2, + F_AP | F_READ | F_WRITE, + HFA384x_RID_TXRATECNTL2, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2TxRateControl3, + F_AP | F_READ | F_WRITE, + HFA384x_RID_TXRATECNTL3, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2TxRateControl4, + F_AP | F_READ | F_WRITE, + HFA384x_RID_TXRATECNTL4, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2TxRateControl5, + F_AP | F_READ | F_WRITE, + HFA384x_RID_TXRATECNTL5, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2TxRateControl6, + F_AP | F_READ | F_WRITE, + HFA384x_RID_TXRATECNTL6, 0, 0, + prism2mib_uint32 }, + + /* p2Behavior MIB's */ + + { DIDmib_p2_p2Behavior_p2TickTime, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_ITICKTIME, 0, 0, + prism2mib_uint32 }, + + /* p2NIC MIB's */ + + { DIDmib_p2_p2NIC_p2MaxLoadTime, + F_AP | F_STA | F_READ, + HFA384x_RID_MAXLOADTIME, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2NIC_p2DLBufferPage, + F_AP | F_STA | F_READ, + HFA384x_RID_DOWNLOADBUFFER, HFA384x_RID_DOWNLOADBUFFER_LEN, 0, + prism2mib_uint32offset }, + { DIDmib_p2_p2NIC_p2DLBufferOffset, + F_AP | F_STA | F_READ, + HFA384x_RID_DOWNLOADBUFFER, HFA384x_RID_DOWNLOADBUFFER_LEN, 1, + prism2mib_uint32offset }, + { DIDmib_p2_p2NIC_p2DLBufferLength, + F_AP | F_STA | F_READ, + HFA384x_RID_DOWNLOADBUFFER, HFA384x_RID_DOWNLOADBUFFER_LEN, 2, + prism2mib_uint32offset }, + { DIDmib_p2_p2NIC_p2PRIIdentity, + F_AP | F_STA | F_READ, + HFA384x_RID_PRIIDENTITY, HFA384x_RID_PRIIDENTITY_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2NIC_p2PRISupRange, + F_AP | F_STA | F_READ, + HFA384x_RID_PRISUPRANGE, HFA384x_RID_PRISUPRANGE_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2NIC_p2CFIActRanges, + F_AP | F_STA | F_READ, + HFA384x_RID_PRI_CFIACTRANGES, HFA384x_RID_CFIACTRANGES_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2NIC_p2BuildSequence, + F_AP | F_STA | F_READ, + HFA384x_RID_BUILDSEQ, HFA384x_RID_BUILDSEQ_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2NIC_p2PrimaryFWID, + F_AP | F_STA | F_READ, + 0, 0, 0, + prism2mib_fwid }, + { DIDmib_p2_p2NIC_p2SecondaryFWID, + F_AP | F_STA | F_READ, + 0, 0, 0, + prism2mib_fwid }, + { DIDmib_p2_p2NIC_p2TertiaryFWID, + F_AP | F_READ, + 0, 0, 0, + prism2mib_fwid }, + { DIDmib_p2_p2NIC_p2NICSerialNumber, + F_AP | F_STA | F_READ, + HFA384x_RID_NICSERIALNUMBER, HFA384x_RID_NICSERIALNUMBER_LEN, 0, + prism2mib_bytearea2pstr }, + { DIDmib_p2_p2NIC_p2NICIdentity, + F_AP | F_STA | F_READ, + HFA384x_RID_NICIDENTITY, HFA384x_RID_NICIDENTITY_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2NIC_p2MFISupRange, + F_AP | F_STA | F_READ, + HFA384x_RID_MFISUPRANGE, HFA384x_RID_MFISUPRANGE_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2NIC_p2CFISupRange, + F_AP | F_STA | F_READ, + HFA384x_RID_CFISUPRANGE, HFA384x_RID_CFISUPRANGE_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2NIC_p2ChannelList, + F_AP | F_STA | F_READ, + HFA384x_RID_CHANNELLIST, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2NIC_p2RegulatoryDomains, + F_AP | F_STA | F_READ, + HFA384x_RID_REGULATORYDOMAINS, HFA384x_RID_REGULATORYDOMAINS_LEN, 0, + prism2mib_regulatorydomains }, + { DIDmib_p2_p2NIC_p2TempType, + F_AP | F_STA | F_READ, + HFA384x_RID_TEMPTYPE, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2NIC_p2STAIdentity, + F_AP | F_STA | F_READ, + HFA384x_RID_STAIDENTITY, HFA384x_RID_STAIDENTITY_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2NIC_p2STASupRange, + F_AP | F_STA | F_READ, + HFA384x_RID_STASUPRANGE, HFA384x_RID_STASUPRANGE_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2NIC_p2MFIActRanges, + F_AP | F_STA | F_READ, + HFA384x_RID_STA_MFIACTRANGES, HFA384x_RID_MFIACTRANGES_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2NIC_p2STACFIActRanges, + F_AP | F_STA | F_READ, + HFA384x_RID_STA_CFIACTRANGES, HFA384x_RID_CFIACTRANGES2_LEN, 0, + prism2mib_uint32array }, + + /* p2MAC MIB's */ + + { DIDmib_p2_p2MAC_p2PortStatus, + F_STA | F_READ, + HFA384x_RID_PORTSTATUS, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2CurrentSSID, + F_STA | F_READ, + HFA384x_RID_CURRENTSSID, HFA384x_RID_CURRENTSSID_LEN, 0, + prism2mib_bytestr2pstr }, + { DIDmib_p2_p2MAC_p2CurrentBSSID, + F_STA | F_READ, + HFA384x_RID_CURRENTBSSID, HFA384x_RID_CURRENTBSSID_LEN, 0, + prism2mib_bytearea2pstr }, + { DIDmib_p2_p2MAC_p2CommsQuality, + F_STA | F_READ, + HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2MAC_p2CommsQualityCQ, + F_STA | F_READ, + HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 0, + prism2mib_uint32offset }, + { DIDmib_p2_p2MAC_p2CommsQualityASL, + F_STA | F_READ, + HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 1, + prism2mib_uint32offset }, + { DIDmib_p2_p2MAC_p2CommsQualityANL, + F_STA | F_READ, + HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 2, + prism2mib_uint32offset }, + { DIDmib_p2_p2MAC_p2dbmCommsQuality, + F_STA | F_READ, + HFA384x_RID_DBMCOMMSQUALITY, HFA384x_RID_DBMCOMMSQUALITY_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2MAC_p2dbmCommsQualityCQ, + F_STA | F_READ, + HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 0, + prism2mib_uint32offset }, + { DIDmib_p2_p2MAC_p2dbmCommsQualityASL, + F_STA | F_READ, + HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 1, + prism2mib_uint32offset }, + { DIDmib_p2_p2MAC_p2dbmCommsQualityANL, + F_STA | F_READ, + HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 2, + prism2mib_uint32offset }, + { DIDmib_p2_p2MAC_p2CurrentTxRate, + F_STA | F_READ, + HFA384x_RID_CURRENTTXRATE, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2CurrentBeaconInterval, + F_AP | F_STA | F_READ, + HFA384x_RID_CURRENTBCNINT, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2StaCurrentScaleThresholds, + F_STA | F_READ, + HFA384x_RID_CURRENTSCALETHRESH, HFA384x_RID_STACURSCALETHRESH_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2MAC_p2APCurrentScaleThresholds, + F_AP | F_READ, + HFA384x_RID_CURRENTSCALETHRESH, HFA384x_RID_APCURSCALETHRESH_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2MAC_p2ProtocolRspTime, + F_AP | F_STA | F_READ, + HFA384x_RID_PROTOCOLRSPTIME, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2ShortRetryLimit, + F_AP | F_STA | F_READ, + HFA384x_RID_SHORTRETRYLIMIT, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2LongRetryLimit, + F_AP | F_STA | F_READ, + HFA384x_RID_LONGRETRYLIMIT, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2MaxTransmitLifetime, + F_AP | F_STA | F_READ, + HFA384x_RID_MAXTXLIFETIME, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2MaxReceiveLifetime, + F_AP | F_STA | F_READ, + HFA384x_RID_MAXRXLIFETIME, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2CFPollable, + F_STA | F_READ, + HFA384x_RID_CFPOLLABLE, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2AuthenticationAlgorithms, + F_AP | F_STA | F_READ, + HFA384x_RID_AUTHALGORITHMS, HFA384x_RID_AUTHALGORITHMS_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2MAC_p2PrivacyOptionImplemented, + F_AP | F_STA | F_READ, + HFA384x_RID_PRIVACYOPTIMP, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2CurrentTxRate1, + F_AP | F_READ, + HFA384x_RID_CURRENTTXRATE1, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2CurrentTxRate2, + F_AP | F_READ, + HFA384x_RID_CURRENTTXRATE2, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2CurrentTxRate3, + F_AP | F_READ, + HFA384x_RID_CURRENTTXRATE3, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2CurrentTxRate4, + F_AP | F_READ, + HFA384x_RID_CURRENTTXRATE4, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2CurrentTxRate5, + F_AP | F_READ, + HFA384x_RID_CURRENTTXRATE5, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2CurrentTxRate6, + F_AP | F_READ, + HFA384x_RID_CURRENTTXRATE6, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2OwnMACAddress, + F_AP | F_READ, + HFA384x_RID_OWNMACADDRESS, HFA384x_RID_OWNMACADDRESS_LEN, 0, + prism2mib_bytearea2pstr }, + + /* p2Modem MIB's */ + + { DIDmib_p2_p2Modem_p2PHYType, + F_AP | F_STA | F_READ, + HFA384x_RID_PHYTYPE, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Modem_p2CurrentChannel, + F_AP | F_STA | F_READ, + HFA384x_RID_CURRENTCHANNEL, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Modem_p2CurrentPowerState, + F_AP | F_STA | F_READ, + HFA384x_RID_CURRENTPOWERSTATE, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Modem_p2CCAMode, + F_AP | F_STA | F_READ, + HFA384x_RID_CCAMODE, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Modem_p2TxPowerMax, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_TXPOWERMAX, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_TXPOWERMAX, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Modem_p2SupportedDataRates, + F_AP | F_STA | F_READ, + HFA384x_RID_SUPPORTEDDATARATES, HFA384x_RID_SUPPORTEDDATARATES_LEN, 0, + prism2mib_bytestr2pstr }, + + /* And finally, lnx mibs */ + { DIDmib_lnx_lnxConfigTable_lnxRSNAIE, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFWPADATA, 0, 0, + prism2mib_priv }, + { 0, 0, 0, 0, 0, NULL}}; + +/*---------------------------------------------------------------- +These MIB's are not supported at this time: + +DIDmib_dot11phy_dot11PhyOperationTable_dot11ChannelAgilityPresent +DIDmib_dot11phy_dot11PhyOperationTable_dot11ChannelAgilityEnabled +DIDmib_dot11phy_dot11PhyDSSSTable_dot11PBCCOptionImplemented +DIDmib_dot11phy_dot11RegDomainsSupportedTable_dot11RegDomainsSupportIndex +DIDmib_dot11phy_dot11SupportedDataRatesTxTable_dot11SupportedDataRatesTxIndex +DIDmib_dot11phy_dot11SupportedDataRatesTxTable_dot11SupportedDataRatesTxValue +DIDmib_dot11phy_dot11SupportedDataRatesRxTable_dot11SupportedDataRatesRxIndex +DIDmib_dot11phy_dot11SupportedDataRatesRxTable_dot11SupportedDataRatesRxValue + +DIDmib_dot11phy_dot11RegDomainsSupportedTable_dot11RegDomainsSupportValue +TODO: need to investigate why wlan has this as enumerated and Prism2 has this + as btye str. + +DIDmib_dot11phy_dot11PhyDSSSTable_dot11ShortPreambleOptionImplemented +TODO: Find out the firmware version number(s) for identifying + whether the firmware is capable of short preamble. TRUE or FALSE + will be returned based on the version of the firmware. + +WEP Key mappings aren't supported in the f/w. +DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingIndex +DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingAddress +DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingWEPOn +DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingValue +DIDmib_dot11smt_dot11PrivacyTable_dot11WEPKeyMappingLength + +TODO: implement counters. +DIDmib_dot11smt_dot11PrivacyTable_dot11WEPICVErrorCount +DIDmib_dot11smt_dot11PrivacyTable_dot11WEPExcludedCount +DIDmib_dot11mac_dot11CountersTable_dot11TransmittedFragmentCount +DIDmib_dot11mac_dot11CountersTable_dot11MulticastTransmittedFrameCount +DIDmib_dot11mac_dot11CountersTable_dot11FailedCount +DIDmib_dot11mac_dot11CountersTable_dot11RetryCount +DIDmib_dot11mac_dot11CountersTable_dot11MultipleRetryCount +DIDmib_dot11mac_dot11CountersTable_dot11FrameDuplicateCount +DIDmib_dot11mac_dot11CountersTable_dot11RTSSuccessCount +DIDmib_dot11mac_dot11CountersTable_dot11RTSFailureCount +DIDmib_dot11mac_dot11CountersTable_dot11ACKFailureCount +DIDmib_dot11mac_dot11CountersTable_dot11ReceivedFragmentCount +DIDmib_dot11mac_dot11CountersTable_dot11MulticastReceivedFrameCount +DIDmib_dot11mac_dot11CountersTable_dot11FCSErrorCount +DIDmib_dot11mac_dot11CountersTable_dot11TransmittedFrameCount +DIDmib_dot11mac_dot11CountersTable_dot11WEPUndecryptableCount + +TODO: implement sane values for these. +DIDmib_dot11mac_dot11OperationTable_dot11ManufacturerID +DIDmib_dot11mac_dot11OperationTable_dot11ProductID + +Not too worried about these at the moment. +DIDmib_dot11phy_dot11PhyAntennaTable_dot11CurrentTxAntenna +DIDmib_dot11phy_dot11PhyAntennaTable_dot11DiversitySupport +DIDmib_dot11phy_dot11PhyAntennaTable_dot11CurrentRxAntenna +DIDmib_dot11phy_dot11PhyTxPowerTable_dot11NumberSupportedPowerLevels +DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel1 +DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel2 +DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel3 +DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel4 +DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel5 +DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel6 +DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel7 +DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel8 +DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel + +Ummm, FH and IR don't apply +DIDmib_dot11phy_dot11PhyFHSSTable_dot11HopTime +DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentChannelNumber +DIDmib_dot11phy_dot11PhyFHSSTable_dot11MaxDwellTime +DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentDwellTime +DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentSet +DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentPattern +DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentIndex +DIDmib_dot11phy_dot11PhyDSSSTable_dot11CCAModeSupported +DIDmib_dot11phy_dot11PhyDSSSTable_dot11EDThreshold +DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogTimerMax +DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogCountMax +DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogTimerMin +DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogCountMin + +We just don't have enough antennas right now to worry about this. +DIDmib_dot11phy_dot11AntennasListTable_dot11AntennaListIndex +DIDmib_dot11phy_dot11AntennasListTable_dot11SupportedTxAntenna +DIDmib_dot11phy_dot11AntennasListTable_dot11SupportedRxAntenna +DIDmib_dot11phy_dot11AntennasListTable_dot11DiversitySelectionRx + +------------------------------------------------------------------*/ + +/*================================================================*/ +/* Function Definitions */ + +/*---------------------------------------------------------------- +* prism2mgmt_mibset_mibget +* +* Set the value of a mib item. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ + +int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp) +{ + hfa384x_t *hw = wlandev->priv; + int result, isget; + mibrec_t *mib; + UINT16 which; + + p80211msg_dot11req_mibset_t *msg = msgp; + p80211itemd_t *mibitem; + + DBFENTER; + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_success; + + /* + ** Determine if this is an Access Point or a station. + */ + + which = hw->ap ? F_AP : F_STA; + + /* + ** Find the MIB in the MIB table. Note that a MIB may be in the + ** table twice...once for an AP and once for a station. Make sure + ** to get the correct one. Note that DID=0 marks the end of the + ** MIB table. + */ + + mibitem = (p80211itemd_t *) msg->mibattribute.data; + + for (mib = mibtab; mib->did != 0; mib++) + if (mib->did == mibitem->did && (mib->flag & which)) + break; + + if (mib->did == 0) { + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + goto done; + } + + /* + ** Determine if this is a "mibget" or a "mibset". If this is a + ** "mibget", then make sure that the MIB may be read. Otherwise, + ** this is a "mibset" so make make sure that the MIB may be written. + */ + + isget = (msg->msgcode == DIDmsg_dot11req_mibget); + + if (isget) { + if (!(mib->flag & F_READ)) { + msg->resultcode.data = + P80211ENUM_resultcode_cant_get_writeonly_mib; + goto done; + } + } else { + if (!(mib->flag & F_WRITE)) { + msg->resultcode.data = + P80211ENUM_resultcode_cant_set_readonly_mib; + goto done; + } + } + + /* + ** Execute the MIB function. If things worked okay, then make + ** sure that the MIB function also worked okay. If so, and this + ** is a "mibget", then the status value must be set for both the + ** "mibattribute" parameter and the mib item within the data + ** portion of the "mibattribute". + */ + + result = mib->func(mib, isget, wlandev, hw, msg, + (void *) mibitem->data); + + if (msg->resultcode.data == P80211ENUM_resultcode_success) { + if (result != 0) { + WLAN_LOG_DEBUG(1, "get/set failure, result=%d\n", + result); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + } else { + if (isget) { + msg->mibattribute.status = + P80211ENUM_msgitem_status_data_ok; + mibitem->status = + P80211ENUM_msgitem_status_data_ok; + } + } + } + +done: + DBFEXIT; + + return(0); +} + +/*---------------------------------------------------------------- +* prism2mib_bytestr2pstr +* +* Get/set pstr data to/from a byte string. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Number of bytes of RID data. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_bytestr2pstr( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + p80211pstrd_t *pstr = (p80211pstrd_t*) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t*) bytebuf; + + DBFENTER; + + if (isget) { + result = hfa384x_drvr_getconfig(hw, mib->parm1, bytebuf, mib->parm2); + prism2mgmt_bytestr2pstr(p2bytestr, pstr); + } else { + memset(bytebuf, 0, mib->parm2); + prism2mgmt_pstr2bytestr(p2bytestr, pstr); + result = hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, mib->parm2); + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_bytearea2pstr +* +* Get/set pstr data to/from a byte area. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Number of bytes of RID data. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_bytearea2pstr( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + p80211pstrd_t *pstr = (p80211pstrd_t*) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + + DBFENTER; + + if (isget) { + result = hfa384x_drvr_getconfig(hw, mib->parm1, bytebuf, mib->parm2); + prism2mgmt_bytearea2pstr(bytebuf, pstr, mib->parm2); + } else { + memset(bytebuf, 0, mib->parm2); + prism2mgmt_pstr2bytearea(bytebuf, pstr); + result = hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, mib->parm2); + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_uint32 +* +* Get/set uint32 data. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Not used. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_uint32( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + UINT32 *uint32 = (UINT32*) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + UINT16 *wordbuf = (UINT16*) bytebuf; + + DBFENTER; + + if (isget) { + result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf); + *uint32 = *wordbuf; + /* [MSM] Removed, getconfig16 returns the value in host order. + * prism2mgmt_prism2int2p80211int(wordbuf, uint32); + */ + } else { + /* [MSM] Removed, setconfig16 expects host order. + * prism2mgmt_p80211int2prism2int(wordbuf, uint32); + */ + *wordbuf = *uint32; + result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf); + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_uint32array +* +* Get/set an array of uint32 data. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Number of bytes of RID data. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_uint32array( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + UINT32 *uint32 = (UINT32 *) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + UINT16 *wordbuf = (UINT16*) bytebuf; + int i, cnt; + + DBFENTER; + + cnt = mib->parm2 / sizeof(UINT16); + + if (isget) { + result = hfa384x_drvr_getconfig(hw, mib->parm1, wordbuf, mib->parm2); + for (i = 0; i < cnt; i++) + prism2mgmt_prism2int2p80211int(wordbuf+i, uint32+i); + } else { + for (i = 0; i < cnt; i++) + prism2mgmt_p80211int2prism2int(wordbuf+i, uint32+i); + result = hfa384x_drvr_setconfig(hw, mib->parm1, wordbuf, mib->parm2); + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_uint32offset +* +* Get/set a single element in an array of uint32 data. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Number of bytes of RID data. +* parm3 Element index. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_uint32offset( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + UINT32 *uint32 = (UINT32*) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + UINT16 *wordbuf = (UINT16*) bytebuf; + UINT16 cnt; + + DBFENTER; + + cnt = mib->parm2 / sizeof(UINT16); + + result = hfa384x_drvr_getconfig(hw, mib->parm1, wordbuf, mib->parm2); + if (result == 0) { + if (isget) { + if (mib->parm3 < cnt) + prism2mgmt_prism2int2p80211int(wordbuf+mib->parm3, uint32); + else + *uint32 = 0; + } else { + if (mib->parm3 < cnt) { + prism2mgmt_p80211int2prism2int(wordbuf+mib->parm3, uint32); + result = hfa384x_drvr_setconfig(hw, mib->parm1, wordbuf, mib->parm2); + } + } + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_truth +* +* Get/set truth data. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Not used. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_truth( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + UINT32 *uint32 = (UINT32*) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + UINT16 *wordbuf = (UINT16*) bytebuf; + + DBFENTER; + + if (isget) { + result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf); + *uint32 = (*wordbuf) ? + P80211ENUM_truth_true : P80211ENUM_truth_false; + } else { + *wordbuf = ((*uint32) == P80211ENUM_truth_true) ? 1 : 0; + result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf); + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_flag +* +* Get/set a flag. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Bit to get/set. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_flag( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + UINT32 *uint32 = (UINT32*) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + UINT16 *wordbuf = (UINT16*) bytebuf; + UINT32 flags; + + DBFENTER; + + result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf); + if (result == 0) { + /* [MSM] Removed, getconfig16 returns the value in host order. + * prism2mgmt_prism2int2p80211int(wordbuf, &flags); + */ + flags = *wordbuf; + if (isget) { + *uint32 = (flags & mib->parm2) ? + P80211ENUM_truth_true : P80211ENUM_truth_false; + } else { + if ((*uint32) == P80211ENUM_truth_true) + flags |= mib->parm2; + else + flags &= ~mib->parm2; + /* [MSM] Removed, setconfig16 expects host order. + * prism2mgmt_p80211int2prism2int(wordbuf, &flags); + */ + *wordbuf = flags; + result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf); + } + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_appcfinfoflag +* +* Get/set a single flag in the APPCFINFO record. +* +* MIB record parameters: +* parm1 Bit to get/set. +* parm2 Not used. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_appcfinfoflag( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + UINT32 *uint32 = (UINT32*) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + UINT16 *wordbuf = (UINT16*) bytebuf; + UINT16 word; + + DBFENTER; + + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CNFAPPCFINFO, + bytebuf, HFA384x_RID_CNFAPPCFINFO_LEN); + if (result == 0) { + if (isget) { + *uint32 = (hfa384x2host_16(wordbuf[3]) & mib->parm1) ? + P80211ENUM_truth_true : P80211ENUM_truth_false; + } else { + word = hfa384x2host_16(wordbuf[3]); + word = ((*uint32) == P80211ENUM_truth_true) ? + (word | mib->parm1) : (word & ~mib->parm1); + wordbuf[3] = host2hfa384x_16(word); + result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFAPPCFINFO, + bytebuf, HFA384x_RID_CNFAPPCFINFO_LEN); + } + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_regulatorydomains +* +* Get regulatory domain data. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Number of bytes of RID data. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_regulatorydomains( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + UINT32 cnt; + p80211pstrd_t *pstr = (p80211pstrd_t*) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + UINT16 *wordbuf = (UINT16*) bytebuf; + + DBFENTER; + + result = 0; + + if (isget) { + result = hfa384x_drvr_getconfig(hw, mib->parm1, wordbuf, mib->parm2); + prism2mgmt_prism2int2p80211int(wordbuf, &cnt); + pstr->len = (UINT8) cnt; + memcpy(pstr->data, &wordbuf[1], pstr->len); + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_wepdefaultkey +* +* Get/set WEP default keys. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Number of bytes of RID data. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_wepdefaultkey( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + p80211pstrd_t *pstr = (p80211pstrd_t*) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + UINT16 len; + + DBFENTER; + + if (isget) { + result = 0; /* Should never happen. */ + } else { + len = (pstr->len > 5) ? HFA384x_RID_CNFWEP128DEFAULTKEY_LEN : + HFA384x_RID_CNFWEPDEFAULTKEY_LEN; + memset(bytebuf, 0, len); + prism2mgmt_pstr2bytearea(bytebuf, pstr); + result = hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, len); + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_powermanagement +* +* Get/set 802.11 power management value. Note that this is defined differently +* by 802.11 and Prism2: +* +* Meaning 802.11 Prism2 +* active 1 false +* powersave 2 true +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Not used. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_powermanagement( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + UINT32 *uint32 = (UINT32*) data; + UINT32 value; + + DBFENTER; + + if (isget) { + result = prism2mib_uint32(mib, isget, wlandev, hw, msg, &value); + *uint32 = (value == 0) ? 1 : 2; + } else { + value = ((*uint32) == 1) ? 0 : 1; + result = prism2mib_uint32(mib, isget, wlandev, hw, msg, &value); + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_preamble +* +* Get/set Prism2 short preamble +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Not used. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_preamble( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + UINT32 *uint32 = (UINT32*) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + UINT16 *wordbuf = (UINT16*) bytebuf; + + DBFENTER; + + if (isget) { + result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf); + *uint32 = *wordbuf; + } else { + *wordbuf = *uint32; + result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf); + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_privacyinvoked +* +* Get/set the dot11PrivacyInvoked value. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Bit value for PrivacyInvoked flag. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_privacyinvoked( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + + DBFENTER; + + if (wlandev->hostwep & HOSTWEP_DECRYPT) { + if (wlandev->hostwep & HOSTWEP_DECRYPT) + mib->parm2 |= HFA384x_WEPFLAGS_DISABLE_RXCRYPT; + if (wlandev->hostwep & HOSTWEP_ENCRYPT) + mib->parm2 |= HFA384x_WEPFLAGS_DISABLE_TXCRYPT; + } + + result = prism2mib_flag(mib, isget, wlandev, hw, msg, data); + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_excludeunencrypted +* +* Get/set the dot11ExcludeUnencrypted value. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Bit value for ExcludeUnencrypted flag. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_excludeunencrypted( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + + DBFENTER; + + result = prism2mib_flag(mib, isget, wlandev, hw, msg, data); + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_fragmentationthreshold +* +* Get/set the fragmentation threshold. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Not used. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_fragmentationthreshold( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + UINT32 *uint32 = (UINT32*) data; + + DBFENTER; + + if (!isget) + if ((*uint32) % 2) { + WLAN_LOG_WARNING("Attempt to set odd number " + "FragmentationThreshold\n"); + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + return(0); + } + + result = prism2mib_uint32(mib, isget, wlandev, hw, msg, data); + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_operationalrateset +* +* Get/set the operational rate set. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Not used. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_operationalrateset( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + p80211pstrd_t *pstr = (p80211pstrd_t *) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + UINT16 *wordbuf = (UINT16*) bytebuf; + + DBFENTER; + + if (isget) { + result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf); + prism2mgmt_get_oprateset(wordbuf, pstr); + } else { + prism2mgmt_set_oprateset(wordbuf, pstr); + result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf); + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, *wordbuf); + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_groupaddress +* +* Get/set the dot11GroupAddressesTable. +* +* MIB record parameters: +* parm1 Not used. +* parm2 Not used. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_groupaddress( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + p80211pstrd_t *pstr = (p80211pstrd_t *) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + UINT16 len; + + DBFENTER; + + /* TODO: fix this. f/w doesn't support mcast filters */ + + if (isget) { + prism2mgmt_get_grpaddr(mib->did, pstr, hw); + return(0); + } + + result = prism2mgmt_set_grpaddr(mib->did, bytebuf, pstr, hw); + if (result != 0) { + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + return(result); + } + + if (hw->dot11_grpcnt <= MAX_PRISM2_GRP_ADDR) { + len = hw->dot11_grpcnt * WLAN_ADDR_LEN; + memcpy(bytebuf, hw->dot11_grp_addr[0], len); + result = hfa384x_drvr_setconfig(hw, HFA384x_RID_GROUPADDR, bytebuf, len); + + /* + ** Turn off promiscuous mode if count is equal to MAX. We may + ** have been at a higher count in promiscuous mode and need to + ** turn it off. + */ + + /* but only if we're not already in promisc mode. :) */ + if ((hw->dot11_grpcnt == MAX_PRISM2_GRP_ADDR) && + !( wlandev->netdev->flags & IFF_PROMISC)) { + result = hfa384x_drvr_setconfig16(hw, + HFA384x_RID_PROMISCMODE, 0); + } + } else { + + /* + ** Clear group addresses in card and set to promiscuous mode. + */ + + memset(bytebuf, 0, sizeof(bytebuf)); + result = hfa384x_drvr_setconfig(hw, HFA384x_RID_GROUPADDR, + bytebuf, 0); + if (result == 0) { + result = hfa384x_drvr_setconfig16(hw, + HFA384x_RID_PROMISCMODE, 1); + } + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_fwid +* +* Get the firmware ID. +* +* MIB record parameters: +* parm1 Not used. +* parm2 Not used. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_fwid( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + p80211pstrd_t *pstr = (p80211pstrd_t *) data; + hfa384x_FWID_t fwid; + + DBFENTER; + + if (isget) { + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_FWID, + &fwid, HFA384x_RID_FWID_LEN); + if (mib->did == DIDmib_p2_p2NIC_p2PrimaryFWID) { + fwid.primary[HFA384x_FWID_LEN - 1] = '\0'; + pstr->len = strlen(fwid.primary); + memcpy(pstr->data, fwid.primary, pstr->len); + } else { + fwid.secondary[HFA384x_FWID_LEN - 1] = '\0'; + pstr->len = strlen(fwid.secondary); + memcpy(pstr->data, fwid.secondary, pstr->len); + } + } else + result = 0; /* Should never happen. */ + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_authalg +* +* Get values from the AuhtenticationAlgorithmsTable. +* +* MIB record parameters: +* parm1 Table index (1-6). +* parm2 Not used. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_authalg( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + UINT32 *uint32 = (UINT32*) data; + + DBFENTER; + + /* MSM: pkx supplied code that code queries RID FD4D....but the f/w's + * results are bogus. Therefore, we have to simulate the appropriate + * results here in the driver based on our knowledge of existing MAC + * features. That's the whole point behind this ugly function. + */ + + if (isget) { + msg->resultcode.data = P80211ENUM_resultcode_success; + switch (mib->parm1) { + case 1: /* Open System */ + *uint32 = P80211ENUM_authalg_opensystem; + break; + case 2: /* SharedKey */ + *uint32 = P80211ENUM_authalg_sharedkey; + break; + default: + *uint32 = 0; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + break; + } + } + + DBFEXIT; + return(0); +} + +/*---------------------------------------------------------------- +* prism2mib_authalgenable +* +* Get/set the enable values from the AuhtenticationAlgorithmsTable. +* +* MIB record parameters: +* parm1 Table index (1-6). +* parm2 Not used. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_authalgenable( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + UINT32 *uint32 = (UINT32*) data; + + int index; + UINT16 cnf_auth; + UINT16 mask; + + DBFENTER; + + index = mib->parm1 - 1; + + result = hfa384x_drvr_getconfig16( hw, + HFA384x_RID_CNFAUTHENTICATION, &cnf_auth); + WLAN_LOG_DEBUG(2,"cnfAuthentication0=%d, index=%d\n", cnf_auth, index); + + if (isget) { + if ( index == 0 || index == 1 ) { + *uint32 = (cnf_auth & (1<resultcode.data = P80211ENUM_resultcode_not_supported; + } + } else { + if ( index == 0 || index == 1 ) { + mask = 1 << index; + if (*uint32==P80211ENUM_truth_true ) { + cnf_auth |= mask; + } else { + cnf_auth &= ~mask; + } + result = hfa384x_drvr_setconfig16( hw, + HFA384x_RID_CNFAUTHENTICATION, cnf_auth); + WLAN_LOG_DEBUG(2,"cnfAuthentication:=%d\n", cnf_auth); + if ( result ) { + WLAN_LOG_DEBUG(1,"Unable to set p2cnfAuthentication to %d\n", cnf_auth); + msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; + } + } else { + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_priv +* +* Get/set values in the "priv" data structure. +* +* MIB record parameters: +* parm1 Not used. +* parm2 Not used. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_priv( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + UINT32 *uint32 = (UINT32*) data; + p80211pstrd_t *pstr = (p80211pstrd_t*) data; + p80211macarray_t *macarray = (p80211macarray_t *) data; + + int i, cnt, result, done; + + DBFENTER; + + switch (mib->did) { + case DIDmib_p2_p2Table_p2ReceivedFrameStatistics: + + /* + ** Note: The values in this record are changed by the + ** interrupt handler and therefore cannot be guaranteed + ** to be stable while they are being copied. However, + ** the interrupt handler will take priority over this + ** code. Hence, if the same values are copied twice, + ** then we are ensured that the values have not been + ** changed. If they have, then just try again. Don't + ** try more than 10 times...if we still haven't got it, + ** then the values we do have are probably good enough. + ** This scheme for copying values is used in order to + ** prevent having to block the interrupt handler while + ** we copy the values. + */ + + if (isget) { + UINT8 test[sizeof(wlandev->rx)]; + for (i = 0; i < 10; i++) { + memcpy(data, &wlandev->rx, sizeof(wlandev->rx)); + memcpy(test, &wlandev->rx, sizeof(wlandev->rx)); + if (memcmp(data, test, sizeof(wlandev->rx)) == 0) break; + } + } + break; + + case DIDmib_p2_p2Table_p2CommunicationTallies: + + /* + ** Note: The values in this record are changed by the + ** interrupt handler and therefore cannot be guaranteed + ** to be stable while they are being copied. See the + ** note above about copying values. + */ + + if (isget) { + UINT8 test[sizeof(hw->tallies)]; + result = hfa384x_drvr_commtallies(hw); + + /* ?????? We need to wait a bit here for the */ + /* tallies to get updated. ?????? */ + /* MSM: TODO: The right way to do this is to + * add a "commtallie" wait queue to the + * priv structure that gets run every time + * we receive a commtally info frame. + * This process would sleep on that + * queue and get awakened when the + * the requested info frame arrives. + * Don't have time to do and test this + * right now. + */ + + /* Ugh, this is nasty. */ + for (i = 0; i < 10; i++) { + memcpy(data, + &hw->tallies, + sizeof(hw->tallies)); + memcpy(test, + &hw->tallies, + sizeof(hw->tallies)); + if ( memcmp(data, + test, + sizeof(hw->tallies)) == 0) + break; + } + } + + break; + + case DIDmib_p2_p2Table_p2Authenticated: + + if (isget) { + prism2sta_authlist_t old; + prism2mib_priv_authlist(hw, &old); + + macarray->cnt = 0; + for (i = 0; i < old.cnt; i++) { + if (!old.assoc[i]) { + memcpy(macarray->data[macarray->cnt], old.addr[i], WLAN_ADDR_LEN); + macarray->cnt++; + } + } + } + + break; + + case DIDmib_p2_p2Table_p2Associated: + + if (isget) { + prism2sta_authlist_t old; + prism2mib_priv_authlist(hw, &old); + + macarray->cnt = 0; + for (i = 0; i < old.cnt; i++) { + if (old.assoc[i]) { + memcpy(macarray->data[macarray->cnt], old.addr[i], WLAN_ADDR_LEN); + macarray->cnt++; + } + } + } + + break; + + case DIDmib_p2_p2Table_p2PowerSaveUserCount: + + if (isget) + *uint32 = hw->psusercount; + + break; + + case DIDmib_p2_p2Table_p2Comment: + + if (isget) { + pstr->len = strlen(hw->comment); + memcpy(pstr->data, hw->comment, pstr->len); + } else { + cnt = pstr->len; + if (cnt < 0) cnt = 0; + if (cnt >= sizeof(hw->comment)) + cnt = sizeof(hw->comment)-1; + memcpy(hw->comment, pstr->data, cnt); + pstr->data[cnt] = '\0'; + } + + break; + + case DIDmib_p2_p2Table_p2AccessMode: + + if (isget) + *uint32 = hw->accessmode; + else + prism2mib_priv_accessmode(hw, *uint32); + + break; + + case DIDmib_p2_p2Table_p2AccessAllow: + + if (isget) { + macarray->cnt = hw->allow.cnt; + memcpy(macarray->data, hw->allow.addr, + macarray->cnt*WLAN_ADDR_LEN); + } else { + prism2mib_priv_accessallow(hw, macarray); + } + + break; + + case DIDmib_p2_p2Table_p2AccessDeny: + + if (isget) { + macarray->cnt = hw->deny.cnt; + memcpy(macarray->data, hw->deny.addr, + macarray->cnt*WLAN_ADDR_LEN); + } else { + prism2mib_priv_accessdeny(hw, macarray); + } + + break; + + case DIDmib_p2_p2Table_p2ChannelInfoResults: + + if (isget) { + done = atomic_read(&hw->channel_info.done); + if (done == 0) { + msg->resultcode.status = P80211ENUM_msgitem_status_no_value; + break; + } + if (done == 1) { + msg->resultcode.status = P80211ENUM_msgitem_status_incomplete_itemdata; + break; + } + + for (i = 0; i < 14; i++, uint32 += 5) { + uint32[0] = i+1; + uint32[1] = hw->channel_info.results.result[i].anl; + uint32[2] = hw->channel_info.results.result[i].pnl; + uint32[3] = (hw->channel_info.results.result[i].active & HFA384x_CHINFORESULT_BSSACTIVE) ? 1 : 0; + uint32[4] = (hw->channel_info.results.result[i].active & HFA384x_CHINFORESULT_PCFACTIVE) ? 1 : 0; + } + } + + break; + + case DIDmib_dot11smt_dot11StationConfigTable_dot11DesiredBSSType: + + if (isget) + *uint32 = hw->dot11_desired_bss_type; + else + hw->dot11_desired_bss_type = *uint32; + + break; + + case DIDmib_lnx_lnxConfigTable_lnxRSNAIE: { + hfa384x_WPAData_t wpa; + if (isget) { + hfa384x_drvr_getconfig( hw, HFA384x_RID_CNFWPADATA, + (UINT8 *) &wpa, sizeof(wpa)); + pstr->len = hfa384x2host_16(wpa.datalen); + memcpy(pstr->data, wpa.data, pstr->len); + } else { + wpa.datalen = host2hfa384x_16(pstr->len); + memcpy(wpa.data, pstr->data, pstr->len); + + result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFWPADATA, + (UINT8 *) &wpa, sizeof(wpa)); + } + break; + } + default: + WLAN_LOG_ERROR("Unhandled DID 0x%08x\n", mib->did); + } + + DBFEXIT; + return(0); +} + +/*---------------------------------------------------------------- +* prism2mib_priv_authlist +* +* Get a copy of the list of authenticated stations. +* +* Arguments: +* priv "priv" structure. +* list List of authenticated stations. +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ + +static void prism2mib_priv_authlist( +hfa384x_t *hw, +prism2sta_authlist_t *list) +{ + prism2sta_authlist_t test; + int i; + + DBFENTER; + + /* + ** Note: The values in this record are changed by the interrupt + ** handler and therefore cannot be guaranteed to be stable while + ** they are being copied. However, the interrupt handler will + ** take priority over this code. Hence, if the same values are + ** copied twice, then we are ensured that the values have not + ** been changed. If they have, then just try again. Don't try + ** more than 10 times...the list of authenticated stations is + ** unlikely to be changing frequently enough that we can't get + ** a snapshot in 10 tries. Don't try more than this so that we + ** don't risk locking-up for long periods of time. If we still + ** haven't got the snapshot, then generate an error message and + ** return an empty list (since this is the only valid list that + ** we can guarentee). This scheme for copying values is used in + ** order to prevent having to block the interrupt handler while + ** we copy the values. + */ + + for (i = 0; i < 10; i++) { + memcpy(list, &hw->authlist, sizeof(prism2sta_authlist_t)); + memcpy(&test, &hw->authlist, sizeof(prism2sta_authlist_t)); + if (memcmp(list, &test, sizeof(prism2sta_authlist_t)) == 0) + break; + } + + if (i >= 10) { + list->cnt = 0; + WLAN_LOG_ERROR("Could not obtain snapshot of authenticated stations.\n"); + } + + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* prism2mib_priv_accessmode +* +* Set the Access Mode. +* +* Arguments: +* priv "priv" structure. +* hw "hw" structure. +* mode New access mode. +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ + +static void prism2mib_priv_accessmode( +hfa384x_t *hw, +UINT32 mode) +{ + prism2sta_authlist_t old; + int i, j, deauth; + UINT8 *addr; + + DBFENTER; + + /* + ** If the mode is not changing or it is changing to "All", then it's + ** okay to go ahead without a lot of messing around. Otherwise, the + ** access mode is changing in a way that may leave some stations + ** authenticated which should not be authenticated. It will be + ** necessary to de-authenticate these stations. + */ + + if (mode == WLAN_ACCESS_ALL || mode == hw->accessmode) { + hw->accessmode = mode; + return; + } + + /* + ** Switch to the new access mode. Once this is done, then the interrupt + ** handler (which uses this value) will be prevented from authenticating + ** ADDITIONAL stations which should not be authenticated. Then get a + ** copy of the current list of authenticated stations. + */ + + hw->accessmode = mode; + + prism2mib_priv_authlist(hw, &old); + + /* + ** Now go through the list of previously authenticated stations (some + ** of which might de-authenticate themselves while we are processing it + ** but that is okay). Any station which no longer matches the access + ** mode, must be de-authenticated. + */ + + for (i = 0; i < old.cnt; i++) { + addr = old.addr[i]; + + if (mode == WLAN_ACCESS_NONE) + deauth = 1; + else { + if (mode == WLAN_ACCESS_ALLOW) { + for (j = 0; j < hw->allow.cnt; j++) + if (memcmp(addr, hw->allow.addr[j], + WLAN_ADDR_LEN) == 0) + break; + deauth = (j >= hw->allow.cnt); + } else { + for (j = 0; j < hw->deny.cnt; j++) + if (memcmp(addr, hw->deny.addr[j], + WLAN_ADDR_LEN) == 0) + break; + deauth = (j < hw->deny.cnt); + } + } + + if (deauth) prism2mib_priv_deauthenticate(hw, addr); + } + + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* prism2mib_priv_accessallow +* +* Change the list of allowed MAC addresses. +* +* Arguments: +* priv "priv" structure. +* hw "hw" structure. +* macarray New array of MAC addresses. +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ + +static void prism2mib_priv_accessallow( +hfa384x_t *hw, +p80211macarray_t *macarray) +{ + prism2sta_authlist_t old; + int i, j; + + DBFENTER; + + /* + ** Change the access list. Note that the interrupt handler may be in + ** the middle of using the access list!!! Since the interrupt handler + ** will always have priority over this process and this is the only + ** process that will modify the list, this problem can be handled as + ** follows: + ** + ** 1. Set the "modify" flag. + ** 2. Change the first copy of the list. + ** 3. Clear the "modify" flag. + ** 4. Change the backup copy of the list. + ** + ** The interrupt handler will check the "modify" flag. If NOT set, then + ** the first copy of the list is valid and may be used. Otherwise, the + ** first copy is being changed but the backup copy is valid and may be + ** used. Doing things this way prevents having to have the interrupt + ** handler block while the list is being updated. + */ + + hw->allow.modify = 1; + + hw->allow.cnt = macarray->cnt; + memcpy(hw->allow.addr, macarray->data, macarray->cnt*WLAN_ADDR_LEN); + + hw->allow.modify = 0; + + hw->allow.cnt1 = macarray->cnt; + memcpy(hw->allow.addr1, macarray->data, macarray->cnt*WLAN_ADDR_LEN); + + /* + ** If the current access mode is "Allow", then changing the access + ** list may leave some stations authenticated which should not be + ** authenticated. It will be necessary to de-authenticate these + ** stations. Otherwise, the list can be changed without a lot of fuss. + */ + + if (hw->accessmode == WLAN_ACCESS_ALLOW) { + + /* + ** Go through the list of authenticated stations (some of + ** which might de-authenticate themselves while we are + ** processing it but that is okay). Any station which is + ** no longer in the list of allowed stations, must be + ** de-authenticated. + */ + + prism2mib_priv_authlist(hw, &old); + + for (i = 0; i < old.cnt; i++) { + for (j = 0; j < hw->allow.cnt; j++) + if (memcmp(old.addr[i], hw->allow.addr[j], + WLAN_ADDR_LEN) == 0) + break; + if (j >= hw->allow.cnt) + prism2mib_priv_deauthenticate(hw, old.addr[i]); + } + } + + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* prism2mib_priv_accessdeny +* +* Change the list of denied MAC addresses. +* +* Arguments: +* priv "priv" structure. +* hw "hw" structure. +* macarray New array of MAC addresses. +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ + +static void prism2mib_priv_accessdeny( +hfa384x_t *hw, +p80211macarray_t *macarray) +{ + prism2sta_authlist_t old; + int i, j; + + DBFENTER; + + /* + ** Change the access list. Note that the interrupt handler may be in + ** the middle of using the access list!!! Since the interrupt handler + ** will always have priority over this process and this is the only + ** process that will modify the list, this problem can be handled as + ** follows: + ** + ** 1. Set the "modify" flag. + ** 2. Change the first copy of the list. + ** 3. Clear the "modify" flag. + ** 4. Change the backup copy of the list. + ** + ** The interrupt handler will check the "modify" flag. If NOT set, then + ** the first copy of the list is valid and may be used. Otherwise, the + ** first copy is being changed but the backup copy is valid and may be + ** used. Doing things this way prevents having to have the interrupt + ** handler block while the list is being updated. + */ + + hw->deny.modify = 1; + + hw->deny.cnt = macarray->cnt; + memcpy(hw->deny.addr, macarray->data, macarray->cnt*WLAN_ADDR_LEN); + + hw->deny.modify = 0; + + hw->deny.cnt1 = macarray->cnt; + memcpy(hw->deny.addr1, macarray->data, macarray->cnt*WLAN_ADDR_LEN); + + /* + ** If the current access mode is "Deny", then changing the access + ** list may leave some stations authenticated which should not be + ** authenticated. It will be necessary to de-authenticate these + ** stations. Otherwise, the list can be changed without a lot of fuss. + */ + + if (hw->accessmode == WLAN_ACCESS_DENY) { + + /* + ** Go through the list of authenticated stations (some of + ** which might de-authenticate themselves while we are + ** processing it but that is okay). Any station which is + ** now in the list of denied stations, must be de-authenticated. + */ + + prism2mib_priv_authlist(hw, &old); + + for (i = 0; i < old.cnt; i++) + for (j = 0; j < hw->deny.cnt; j++) + if (memcmp(old.addr[i], hw->deny.addr[j], + WLAN_ADDR_LEN) == 0) { + prism2mib_priv_deauthenticate(hw, old.addr[i]); + break; + } + } + + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* prism2mib_priv_deauthenticate +* +* De-authenticate a station. This is done by sending a HandoverAddress +* information frame to the firmware. This should work, according to +* Intersil. +* +* Arguments: +* priv "priv" structure. +* hw "hw" structure. +* addr MAC address of station to be de-authenticated. +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ + +static void prism2mib_priv_deauthenticate( +hfa384x_t *hw, +UINT8 *addr) +{ + DBFENTER; + hfa384x_drvr_handover(hw, addr); + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_pstr2bytestr +* +* Convert the pstr data in the WLAN message structure into an hfa384x +* byte string format. +* +* Arguments: +* bytestr hfa384x byte string data type +* pstr wlan message data +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ + +void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr) +{ + DBFENTER; + + bytestr->len = host2hfa384x_16((UINT16)(pstr->len)); + memcpy(bytestr->data, pstr->data, pstr->len); + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_pstr2bytearea +* +* Convert the pstr data in the WLAN message structure into an hfa384x +* byte area format. +* +* Arguments: +* bytearea hfa384x byte area data type +* pstr wlan message data +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ + +void prism2mgmt_pstr2bytearea(UINT8 *bytearea, p80211pstrd_t *pstr) +{ + DBFENTER; + + memcpy(bytearea, pstr->data, pstr->len); + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_bytestr2pstr +* +* Convert the data in an hfa384x byte string format into a +* pstr in the WLAN message. +* +* Arguments: +* bytestr hfa384x byte string data type +* msg wlan message +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ + +void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr) +{ + DBFENTER; + + pstr->len = (UINT8)(hfa384x2host_16((UINT16)(bytestr->len))); + memcpy(pstr->data, bytestr->data, pstr->len); + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_bytearea2pstr +* +* Convert the data in an hfa384x byte area format into a pstr +* in the WLAN message. +* +* Arguments: +* bytearea hfa384x byte area data type +* msg wlan message +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ + +void prism2mgmt_bytearea2pstr(UINT8 *bytearea, p80211pstrd_t *pstr, int len) +{ + DBFENTER; + + pstr->len = (UINT8)len; + memcpy(pstr->data, bytearea, len); + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_prism2int2p80211int +* +* Convert an hfa384x integer into a wlan integer +* +* Arguments: +* prism2enum pointer to hfa384x integer +* wlanenum pointer to p80211 integer +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ + +void prism2mgmt_prism2int2p80211int(UINT16 *prism2int, UINT32 *wlanint) +{ + DBFENTER; + + *wlanint = (UINT32)hfa384x2host_16(*prism2int); + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_p80211int2prism2int +* +* Convert a wlan integer into an hfa384x integer +* +* Arguments: +* prism2enum pointer to hfa384x integer +* wlanenum pointer to p80211 integer +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ + +void prism2mgmt_p80211int2prism2int(UINT16 *prism2int, UINT32 *wlanint) +{ + DBFENTER; + + *prism2int = host2hfa384x_16((UINT16)(*wlanint)); + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_prism2enum2p80211enum +* +* Convert the hfa384x enumerated int into a p80211 enumerated int +* +* Arguments: +* prism2enum pointer to hfa384x integer +* wlanenum pointer to p80211 integer +* rid hfa384x record id +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ +void prism2mgmt_prism2enum2p80211enum(UINT16 *prism2enum, UINT32 *wlanenum, UINT16 rid) +{ + DBFENTER; + + /* At the moment, the need for this functionality hasn't + presented itself. All the wlan enumerated values are + a 1-to-1 match against the Prism2 enumerated values*/ + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_p80211enum2prism2enum +* +* Convert the p80211 enumerated int into an hfa384x enumerated int +* +* Arguments: +* prism2enum pointer to hfa384x integer +* wlanenum pointer to p80211 integer +* rid hfa384x record id +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ +void prism2mgmt_p80211enum2prism2enum(UINT16 *prism2enum, UINT32 *wlanenum, UINT16 rid) +{ + DBFENTER; + + /* At the moment, the need for this functionality hasn't + presented itself. All the wlan enumerated values are + a 1-to-1 match against the Prism2 enumerated values*/ + DBFEXIT; + return; +} + + + +/*---------------------------------------------------------------- +* prism2mgmt_get_oprateset +* +* Convert the hfa384x bit area into a wlan octet string. +* +* Arguments: +* rate Prism2 bit area +* pstr wlan octet string +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ +void prism2mgmt_get_oprateset(UINT16 *rate, p80211pstrd_t *pstr) +{ + UINT8 len; + UINT8 *datarate; + + DBFENTER; + + len = 0; + datarate = pstr->data; + + /* 1 Mbps */ + if ( BIT0 & (*rate) ) { + len += (UINT8)1; + *datarate = (UINT8)2; + datarate++; + } + + /* 2 Mbps */ + if ( BIT1 & (*rate) ) { + len += (UINT8)1; + *datarate = (UINT8)4; + datarate++; + } + + /* 5.5 Mbps */ + if ( BIT2 & (*rate) ) { + len += (UINT8)1; + *datarate = (UINT8)11; + datarate++; + } + + /* 11 Mbps */ + if ( BIT3 & (*rate) ) { + len += (UINT8)1; + *datarate = (UINT8)22; + datarate++; + } + + pstr->len = len; + + DBFEXIT; + return; +} + + + +/*---------------------------------------------------------------- +* prism2mgmt_set_oprateset +* +* Convert the wlan octet string into an hfa384x bit area. +* +* Arguments: +* rate Prism2 bit area +* pstr wlan octet string +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ +void prism2mgmt_set_oprateset(UINT16 *rate, p80211pstrd_t *pstr) +{ + UINT8 *datarate; + int i; + + DBFENTER; + + *rate = 0; + + datarate = pstr->data; + + for ( i=0; i < pstr->len; i++, datarate++ ) { + switch (*datarate) { + case 2: /* 1 Mbps */ + *rate |= BIT0; + break; + case 4: /* 2 Mbps */ + *rate |= BIT1; + break; + case 11: /* 5.5 Mbps */ + *rate |= BIT2; + break; + case 22: /* 11 Mbps */ + *rate |= BIT3; + break; + default: + WLAN_LOG_DEBUG(1, "Unrecoginzed Rate of %d\n", + *datarate); + break; + } + } + + DBFEXIT; + return; +} + + + +/*---------------------------------------------------------------- +* prism2mgmt_get_grpaddr +* +* Retrieves a particular group address from the list of +* group addresses. +* +* Arguments: +* did mibitem did +* pstr wlan octet string +* priv prism2 driver private data structure +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ +void prism2mgmt_get_grpaddr(UINT32 did, p80211pstrd_t *pstr, + hfa384x_t *hw ) +{ + int index; + + DBFENTER; + + index = prism2mgmt_get_grpaddr_index(did); + + if ( index >= 0 ) { + pstr->len = WLAN_ADDR_LEN; + memcpy(pstr->data, hw->dot11_grp_addr[index], + WLAN_ADDR_LEN); + } + + DBFEXIT; + return; +} + + + +/*---------------------------------------------------------------- +* prism2mgmt_set_grpaddr +* +* Convert the wlan octet string into an hfa384x bit area. +* +* Arguments: +* did mibitem did +* buf +* groups +* +* Returns: +* 0 Success +* !0 Error +* +----------------------------------------------------------------*/ +int prism2mgmt_set_grpaddr(UINT32 did, UINT8 *prism2buf, + p80211pstrd_t *pstr, hfa384x_t *hw ) +{ + UINT8 no_addr[WLAN_ADDR_LEN]; + int index; + + DBFENTER; + + memset(no_addr, 0, WLAN_ADDR_LEN); + if (memcmp(no_addr, pstr->data, WLAN_ADDR_LEN) != 0) { + + /* + ** The address is NOT 0 so we are "adding" an address to the + ** group address list. Check to make sure we aren't trying + ** to add more than the maximum allowed number of group + ** addresses in the list. The new address is added to the + ** end of the list regardless of the DID used to add the + ** address. + */ + + if (hw->dot11_grpcnt >= MAX_GRP_ADDR) return(-1); + + memcpy(hw->dot11_grp_addr[hw->dot11_grpcnt], pstr->data, + WLAN_ADDR_LEN); + hw->dot11_grpcnt += 1; + } else { + + /* + ** The address is 0. Interpret this as "deleting" an address + ** from the group address list. Get the address index from + ** the DID. If this is within the range of used addresses, + ** then delete the specified address by shifting all following + ** addresses down. Then clear the last address (which should + ** now be unused). If the address index is NOT within the + ** range of used addresses, then just ignore the address. + */ + + index = prism2mgmt_get_grpaddr_index(did); + if (index >= 0 && index < hw->dot11_grpcnt) { + hw->dot11_grpcnt -= 1; + memmove(hw->dot11_grp_addr[index], + hw->dot11_grp_addr[index + 1], + ((hw->dot11_grpcnt)-index) * WLAN_ADDR_LEN); + memset(hw->dot11_grp_addr[hw->dot11_grpcnt], 0, + WLAN_ADDR_LEN); + } + } + + DBFEXIT; + return(0); +} + + +/*---------------------------------------------------------------- +* prism2mgmt_get_grpaddr_index +* +* Gets the index in the group address list based on the did. +* +* Arguments: +* did mibitem did +* +* Returns: +* >= 0 If valid did +* < 0 If not valid did +* +----------------------------------------------------------------*/ +int prism2mgmt_get_grpaddr_index( UINT32 did ) +{ + int index; + + DBFENTER; + + index = -1; + + switch (did) { + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address1: + index = 0; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address2: + index = 1; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address3: + index = 2; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address4: + index = 3; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address5: + index = 4; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address6: + index = 5; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address7: + index = 6; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address8: + index = 7; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address9: + index = 8; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address10: + index = 9; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address11: + index = 10; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address12: + index = 11; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address13: + index = 12; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address14: + index = 13; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address15: + index = 14; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address16: + index = 15; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address17: + index = 16; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address18: + index = 17; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address19: + index = 18; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address20: + index = 19; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address21: + index = 20; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address22: + index = 21; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address23: + index = 22; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address24: + index = 23; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address25: + index = 24; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address26: + index = 25; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address27: + index = 26; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address28: + index = 27; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address29: + index = 28; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address30: + index = 29; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address31: + index = 30; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address32: + index = 31; + break; + } + + DBFEXIT; + return index; +} --- linux-2.6.28.orig/ubuntu/misc/wireless/prism2_usb/hfa384x.c +++ linux-2.6.28/ubuntu/misc/wireless/prism2_usb/hfa384x.c @@ -0,0 +1,4018 @@ +/* src/prism2/driver/hfa384x.c +* +* Implements the functions of the Intersil hfa384x MAC +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file implements functions that correspond to the prism2/hfa384x +* 802.11 MAC hardware and firmware host interface. +* +* The functions can be considered to represent several levels of +* abstraction. The lowest level functions are simply C-callable wrappers +* around the register accesses. The next higher level represents C-callable +* prism2 API functions that match the Intersil documentation as closely +* as is reasonable. The next higher layer implements common sequences +* of invokations of the API layer (e.g. write to bap, followed by cmd). +* +* Common sequences: +* hfa384x_drvr_xxx Highest level abstractions provided by the +* hfa384x code. They are driver defined wrappers +* for common sequences. These functions generally +* use the services of the lower levels. +* +* hfa384x_drvr_xxxconfig An example of the drvr level abstraction. These +* functions are wrappers for the RID get/set +* sequence. They call copy_[to|from]_bap() and +* cmd_access(). These functions operate on the +* RIDs and buffers without validation. The caller +* is responsible for that. +* +* API wrapper functions: +* hfa384x_cmd_xxx functions that provide access to the f/w commands. +* The function arguments correspond to each command +* argument, even command arguments that get packed +* into single registers. These functions _just_ +* issue the command by setting the cmd/parm regs +* & reading the status/resp regs. Additional +* activities required to fully use a command +* (read/write from/to bap, get/set int status etc.) +* are implemented separately. Think of these as +* C-callable prism2 commands. +* +* Lowest Layer Functions: +* hfa384x_docmd_xxx These functions implement the sequence required +* to issue any prism2 command. Primarily used by the +* hfa384x_cmd_xxx functions. +* +* hfa384x_bap_xxx BAP read/write access functions. +* Note: we usually use BAP0 for non-interrupt context +* and BAP1 for interrupt context. +* +* hfa384x_dl_xxx download related functions. +* +* Driver State Issues: +* Note that there are two pairs of functions that manage the +* 'initialized' and 'running' states of the hw/MAC combo. The four +* functions are create(), destroy(), start(), and stop(). create() +* sets up the data structures required to support the hfa384x_* +* functions and destroy() cleans them up. The start() function gets +* the actual hardware running and enables the interrupts. The stop() +* function shuts the hardware down. The sequence should be: +* create() +* . +* . Self contained test routines can run here, particularly +* . corereset() and test_hostif(). +* . +* start() +* . +* . Do interesting things w/ the hardware +* . +* stop() +* destroy() +* +* Note that destroy() can be called without calling stop() first. +* -------------------------------------------------------------------- +*/ + +/*================================================================*/ + +/* System Includes */ +#define WLAN_DBVAR prism2_debug +#include + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +#include +#else +#include +#endif + +#if (WLAN_HOSTIF == WLAN_PCMCIA) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) ) +#include +#endif +#include +#include +#include +#include +#include +#endif + +#if ((WLAN_HOSTIF == WLAN_PLX) || (WLAN_HOSTIF == WLAN_PCI)) +#include +#include +#endif + +#include + +// XXXX #define CMD_IRQ + +/*================================================================*/ +/* Project Includes */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*================================================================*/ +/* Local Constants */ + +static const UINT16 crc16tab[256] = +{ + 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, + 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, + 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, + 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, + 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, + 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, + 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, + 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, + 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, + 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, + 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, + 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, + 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, + 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40, + 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, + 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, + 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, + 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, + 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, + 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, + 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, + 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, + 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, + 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, + 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, + 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, + 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, + 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, + 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, + 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, + 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, + 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040 +}; + +/*================================================================*/ +/* Local Macros */ + +/*================================================================*/ +/* Local Types */ + +/*================================================================*/ +/* Local Static Definitions */ +extern int prism2_debug; + +/*================================================================*/ +/* Local Function Declarations */ + +static void hfa384x_int_dtim(wlandevice_t *wlandev); +static void hfa384x_int_infdrop(wlandevice_t *wlandev); + +static void hfa384x_bap_tasklet(unsigned long data); + +static void hfa384x_int_info(wlandevice_t *wlandev); +static void hfa384x_int_txexc(wlandevice_t *wlandev); +static void hfa384x_int_tx(wlandevice_t *wlandev); +static void hfa384x_int_rx(wlandevice_t *wlandev); + +#ifdef CMD_IRQ +static void hfa384x_int_cmd(wlandevice_t *wlandev); +#endif +static void hfa384x_int_rxmonitor( wlandevice_t *wlandev, + UINT16 rxfid, hfa384x_rx_frame_t *rxdesc); +static void hfa384x_int_alloc(wlandevice_t *wlandev); + +static int hfa384x_docmd_wait( hfa384x_t *hw, hfa384x_metacmd_t *cmd); + +static int hfa384x_dl_docmd_wait( hfa384x_t *hw, hfa384x_metacmd_t *cmd); + +static UINT16 +hfa384x_mkcrc16(UINT8 *p, int len); + +int hfa384x_copy_to_bap4(hfa384x_t *hw, UINT16 bap, UINT16 id, UINT16 offset, + void *buf, UINT len, void* buf2, UINT len2, + void *buf3, UINT len3, void* buf4, UINT len4); + +/*================================================================*/ +/* Function Definitions */ + +static UINT16 +txfid_queue_empty(hfa384x_t *hw) +{ + return (hw->txfid_head == hw->txfid_tail) ? 1 : 0; +} + +static UINT16 +txfid_queue_remove(hfa384x_t *hw) +{ + UINT16 result= 0; + + if (txfid_queue_empty(hw)) { + WLAN_LOG_DEBUG(3,"queue empty.\n"); + } else { + result = hw->txfid_queue[hw->txfid_head]; + hw->txfid_head = (hw->txfid_head + 1) % hw->txfid_N; + } + + return (UINT16)result; +} + +static INT16 +txfid_queue_add(hfa384x_t *hw, UINT16 val) +{ + INT16 result = 0; + + if (hw->txfid_head == ((hw->txfid_tail + 1) % hw->txfid_N)) { + result = -1; + WLAN_LOG_DEBUG(3,"queue full.\n"); + } else { + hw->txfid_queue[hw->txfid_tail] = val; + result = hw->txfid_tail; + hw->txfid_tail = (hw->txfid_tail + 1) % hw->txfid_N; + } + + return result; +} + +/*---------------------------------------------------------------- +* hfa384x_create +* +* Initializes the hfa384x_t data structure for use. Note this +* does _not_ intialize the actual hardware, just the data structures +* we use to keep track of its state. +* +* Arguments: +* hw device structure +* irq device irq number +* iobase [pcmcia] i/o base address for register access +* [pci] zero +* [plx] i/o base address for register access +* membase [pcmcia] pcmcia_cs "link" pointer +* [pci] memory base address for register access +* [plx] memory base address for card attribute memory +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +void hfa384x_create(hfa384x_t *hw, UINT irq, UINT32 iobase, + UINT8 __iomem *membase) +{ + DBFENTER; + memset(hw, 0, sizeof(hfa384x_t)); + hw->irq = irq; + hw->iobase = iobase; + hw->membase = membase; + spin_lock_init(&(hw->cmdlock)); + + /* BAP setup */ + spin_lock_init(&(hw->baplock)); + tasklet_init(&hw->bap_tasklet, + hfa384x_bap_tasklet, + (unsigned long) hw); + + init_waitqueue_head(&hw->cmdq); + sema_init(&hw->infofid_sem, 1); + + hw->txfid_head = 0; + hw->txfid_tail = 0; + hw->txfid_N = HFA384x_DRVR_FIDSTACKLEN_MAX; + memset(hw->txfid_queue, 0, sizeof(hw->txfid_queue)); + + hw->isram16 = 1; + + /* Init the auth queue head */ + skb_queue_head_init(&hw->authq); + + INIT_WORK2(&hw->link_bh, prism2sta_processing_defer); + + INIT_WORK2(&hw->commsqual_bh, prism2sta_commsqual_defer); + + init_timer(&hw->commsqual_timer); + hw->commsqual_timer.data = (unsigned long) hw; + hw->commsqual_timer.function = prism2sta_commsqual_timer; + + hw->link_status = HFA384x_LINK_NOTCONNECTED; + hw->state = HFA384x_STATE_INIT; + + DBFEXIT; +} + +/*---------------------------------------------------------------- +* hfa384x_destroy +* +* Partner to hfa384x_create(). This function cleans up the hw +* structure so that it can be freed by the caller using a simple +* kfree. Currently, this function is just a placeholder. If, at some +* point in the future, an hw in the 'shutdown' state requires a 'deep' +* kfree, this is where it should be done. Note that if this function +* is called on a _running_ hw structure, the drvr_stop() function is +* called. +* +* Arguments: +* hw device structure +* +* Returns: +* nothing, this function is not allowed to fail. +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +void +hfa384x_destroy( hfa384x_t *hw) +{ + struct sk_buff *skb; + + DBFENTER; + + if ( hw->state == HFA384x_STATE_RUNNING ) { + hfa384x_drvr_stop(hw); + } + hw->state = HFA384x_STATE_PREINIT; + + if (hw->scanresults) { + kfree(hw->scanresults); + hw->scanresults = NULL; + } + + /* Now to clean out the auth queue */ + while ( (skb = skb_dequeue(&hw->authq)) ) { + dev_kfree_skb(skb); + } + + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* hfa384x_drvr_getconfig +* +* Performs the sequence necessary to read a config/info item. +* +* Arguments: +* hw device structure +* rid config/info record id (host order) +* buf host side record buffer. Upon return it will +* contain the body portion of the record (minus the +* RID and len). +* len buffer length (in bytes, should match record length) +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* -ENODATA length mismatch between argument and retrieved +* record. +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_getconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len) +{ + int result = 0; + DBFENTER; + + result = hfa384x_cmd_access( hw, 0, rid, buf, len); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_setconfig +* +* Performs the sequence necessary to write a config/info item. +* +* Arguments: +* hw device structure +* rid config/info record id (in host order) +* buf host side record buffer +* len buffer length (in bytes) +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_setconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len) +{ + int result = 0; + DBFENTER; + + result = hfa384x_cmd_access( hw, 1, rid, buf, len); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_readpda +* +* Performs the sequence to read the PDA space. Note there is no +* drvr_writepda() function. Writing a PDA is +* generally implemented by a calling component via calls to +* cmd_download and writing to the flash download buffer via the +* aux regs. +* +* Arguments: +* hw device structure +* buf buffer to store PDA in +* len buffer length +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* -ETIMEOUT timout waiting for the cmd regs to become +* available, or waiting for the control reg +* to indicate the Aux port is enabled. +* -ENODATA the buffer does NOT contain a valid PDA. +* Either the card PDA is bad, or the auxdata +* reads are giving us garbage. + +* +* Side effects: +* +* Call context: +* process thread or non-card interrupt. +----------------------------------------------------------------*/ +int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, UINT len) +{ + int result = 0; + UINT16 *pda = buf; + int pdaok = 0; + int morepdrs = 1; + int currpdr = 0; /* word offset of the current pdr */ + int i; + UINT16 pdrlen; /* pdr length in bytes, host order */ + UINT16 pdrcode; /* pdr code, host order */ + UINT16 crc; + UINT16 pdacrc; + struct pdaloc { + UINT32 cardaddr; + UINT16 auxctl; + } pdaloc[] = + { + { HFA3842_PDA_BASE, HFA384x_AUX_CTL_NV}, + { HFA3842_PDA_BASE, HFA384x_AUX_CTL_EXTDS}, + { HFA3841_PDA_BASE, HFA384x_AUX_CTL_NV}, + { HFA3841_PDA_BASE, HFA384x_AUX_CTL_EXTDS}, + { HFA3841_PDA_BOGUS_BASE, HFA384x_AUX_CTL_NV} + }; + + DBFENTER; + /* Check for aux available */ + result = hfa384x_cmd_aux_enable(hw, 0); + if ( result ) { + WLAN_LOG_DEBUG(1,"aux_enable() failed. result=%d\n", result); + goto failed; + } + + /* Read the pda from each known address. */ + for ( i = 0; i < (sizeof(pdaloc)/sizeof(pdaloc[0])); i++) { + WLAN_LOG_DEBUG( 3, "Checking PDA@(0x%08x,%s)\n", + pdaloc[i].cardaddr, + pdaloc[i].auxctl == HFA384x_AUX_CTL_NV ? + "CTL_NV" : "CTL_EXTDS"); + + /* Copy bufsize bytes from our current pdaloc */ + hfa384x_copy_from_aux(hw, + pdaloc[i].cardaddr, + pdaloc[i].auxctl, + buf, + len); + + /* Test for garbage */ + /* Traverse the PDR list Looking for PDA-END */ + pdaok = 1; /* intially assume good */ + morepdrs = 1; + currpdr = 0; + while ( pdaok && morepdrs ) { + pdrlen = hfa384x2host_16(pda[currpdr]) * 2; + pdrcode = hfa384x2host_16(pda[currpdr+1]); + + /* Test for completion at END record */ + if ( pdrcode == HFA384x_PDR_END_OF_PDA ) { + if ( pdrlen == 4 ) { + morepdrs = 0; + /* Calculate CRC-16 and compare to PDA + * value. Note the addition of 2 words + * for ENDREC.len and ENDREC.code + * fields. + */ + crc = hfa384x_mkcrc16( (UINT8*)pda, + (currpdr + 2) * sizeof(UINT16)); + pdacrc =hfa384x2host_16(pda[currpdr+2]); + if ( crc != pdacrc ) { + WLAN_LOG_DEBUG(3, + "PDA crc failed:" + "calc_crc=0x%04x," + "pdr_crc=0x%04x.\n", + crc, pdacrc); + pdaok = 0; + } + } else { + WLAN_LOG_DEBUG(3, + "END record detected w/ " + "len(%d) != 2, assuming bad PDA\n", + pdrlen); + pdaok = 0; + + } + break; + } + + /* Test the record length */ + if ( pdrlen > HFA384x_PDR_LEN_MAX || pdrlen == 0) { + WLAN_LOG_DEBUG(3, + "pdrlen for address #%d " + "at %#x:%#x:%d\n", + i, pdaloc[i].cardaddr, + pdaloc[i].auxctl, pdrlen); + WLAN_LOG_DEBUG(3,"pdrlen invalid=%d\n", + pdrlen); + pdaok = 0; + break; + } + + /* Move to the next pdr */ + if ( morepdrs ) { + /* note the access to pda[], we need words */ + currpdr += hfa384x2host_16(pda[currpdr]) + 1; + if (currpdr*sizeof(UINT16) > len) { + WLAN_LOG_DEBUG(3, + "Didn't find PDA_END in buffer, " + "trying next location.\n"); + pdaok = 0; + break; + } + } + } + if ( pdaok ) { + WLAN_LOG_INFO( + "PDA Read from 0x%08x in %s space.\n", + pdaloc[i].cardaddr, + pdaloc[i].auxctl == 0 ? "EXTDS" : + pdaloc[i].auxctl == 1 ? "NV" : + pdaloc[i].auxctl == 2 ? "PHY" : + pdaloc[i].auxctl == 3 ? "ICSRAM" : + ""); + break; + } + } + result = pdaok ? 0 : -ENODATA; + + if ( result ) { + WLAN_LOG_DEBUG(3,"Failure: pda is not okay\n"); + } + + hfa384x_cmd_aux_disable(hw); +failed: + DBFEXIT; + return result; +} + + + +/*---------------------------------------------------------------- +* mkpda_crc +* +* Calculates the CRC16 for the given PDA and inserts the value +* into the end record. +* +* Arguments: +* pda ptr to the PDA data structure. +* +* Returns: +* 0 - success +* ~0 - failure (probably an errno) +----------------------------------------------------------------*/ +static UINT16 +hfa384x_mkcrc16(UINT8 *p, int len) +{ + UINT16 crc = 0; + UINT8 *lim = p + len; + + while (p < lim) { + crc = (crc >> 8 ) ^ crc16tab[(crc & 0xff) ^ *p++]; + } + + return crc; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_ramdl_enable +* +* Begins the ram download state. Checks to see that we're not +* already in a download state and that a port isn't enabled. +* Sets the download state and calls cmd_download with the +* ENABLE_VOLATILE subcommand and the exeaddr argument. +* +* Arguments: +* hw device structure +* exeaddr the card execution address that will be +* jumped to when ramdl_disable() is called +* (host order). +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_ramdl_enable(hfa384x_t *hw, UINT32 exeaddr) +{ + int result = 0; + UINT16 lowaddr; + UINT16 hiaddr; + int i; + DBFENTER; + /* Check that a port isn't active */ + for ( i = 0; i < HFA384x_PORTID_MAX; i++) { + if ( hw->port_enabled[i] ) { + WLAN_LOG_DEBUG(1,"Can't download with a port enabled.\n"); + result = -EINVAL; + goto done; + } + } + + /* Check that we're not already in a download state */ + if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) { + WLAN_LOG_DEBUG(1,"Download state not disabled.\n"); + result = -EINVAL; + goto done; + } + + /* Are we supposed to go into genesis mode? */ + if (exeaddr == 0x3f0000) { + UINT16 initseq[2] = { 0xe100, 0xffa1 }; + UINT16 readbuf[2]; + UINT8 hcr = 0x0f; /* Default to x16 SRAM */ + hw->isram16 = 1; + + WLAN_LOG_DEBUG(1, "Dropping into Genesis mode\n"); + + /* Issue card reset and enable aux port */ + hfa384x_corereset(hw, prism2_reset_holdtime, + prism2_reset_settletime, 0); + hfa384x_cmd_aux_enable(hw, 1); + + /* Genesis set */ + hfa384x_copy_to_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS, + initseq, sizeof(initseq)); + + hfa384x_corereset(hw, prism2_reset_holdtime, + prism2_reset_settletime, hcr); + + /* Validate memory config */ + hfa384x_copy_to_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS, + initseq, sizeof(initseq)); + hfa384x_copy_from_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS, + readbuf, sizeof(initseq)); + WLAN_HEX_DUMP(3, "readback", readbuf, sizeof(readbuf)); + + if (memcmp(initseq, readbuf, sizeof(readbuf))) { + hcr = 0x1f; /* x8 SRAM */ + hw->isram16 = 0; + + hfa384x_copy_to_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS, + initseq, sizeof(initseq)); + hfa384x_corereset(hw, prism2_reset_holdtime, + prism2_reset_settletime, hcr); + + hfa384x_copy_to_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS, + initseq, sizeof(initseq)); + hfa384x_copy_from_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS, + readbuf, sizeof(initseq)); + WLAN_HEX_DUMP(2, "readback", readbuf, sizeof(readbuf)); + + if (memcmp(initseq, readbuf, sizeof(readbuf))) { + WLAN_LOG_ERROR("Genesis mode failed\n"); + result = -1; + goto done; + } + } + + /* Now we're in genesis mode */ + hw->dlstate = HFA384x_DLSTATE_GENESIS; + goto done; + } + + /* Retrieve the buffer loc&size and timeout */ + if ( (result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER, + &(hw->bufinfo), sizeof(hw->bufinfo))) ) { + goto done; + } + hw->bufinfo.page = hfa384x2host_16(hw->bufinfo.page); + hw->bufinfo.offset = hfa384x2host_16(hw->bufinfo.offset); + hw->bufinfo.len = hfa384x2host_16(hw->bufinfo.len); + if ( (result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME, + &(hw->dltimeout))) ) { + goto done; + } + hw->dltimeout = hfa384x2host_16(hw->dltimeout); + + /* Enable the aux port */ + if ( (result = hfa384x_cmd_aux_enable(hw, 0)) ) { + WLAN_LOG_DEBUG(1,"Aux enable failed, result=%d.\n", result); + goto done; + } + + /* Call the download(1,addr) function */ + lowaddr = HFA384x_ADDR_CMD_MKOFF(exeaddr); + hiaddr = HFA384x_ADDR_CMD_MKPAGE(exeaddr); + + result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_RAM, + lowaddr, hiaddr, 0); + if ( result == 0) { + /* Set the download state */ + hw->dlstate = HFA384x_DLSTATE_RAMENABLED; + } else { + WLAN_LOG_DEBUG(1,"cmd_download(0x%04x, 0x%04x) failed, result=%d.\n", + lowaddr,hiaddr, result); + /* Disable the aux port */ + hfa384x_cmd_aux_disable(hw); + } + + done: + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_ramdl_disable +* +* Ends the ram download state. +* +* Arguments: +* hw device structure +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_ramdl_disable(hfa384x_t *hw) +{ + DBFENTER; + /* Check that we're already in the download state */ + if ( ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) && + ( hw->dlstate != HFA384x_DLSTATE_GENESIS ) ) { + return -EINVAL; + } + + if (hw->dlstate == HFA384x_DLSTATE_GENESIS) { + hfa384x_corereset(hw, prism2_reset_holdtime, + prism2_reset_settletime, + hw->isram16 ? 0x07: 0x17); + goto done; + } + + /* Disable the aux port */ + hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0); + + done: + hw->dlstate = HFA384x_DLSTATE_DISABLED; + hfa384x_cmd_aux_disable(hw); + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_ramdl_write +* +* Performs a RAM download of a chunk of data. First checks to see +* that we're in the RAM download state, then uses the aux functions +* to 1) copy the data, 2) readback and compare. The download +* state is unaffected. When all data has been written using +* this function, call drvr_ramdl_disable() to end the download state +* and restart the MAC. +* +* Arguments: +* hw device structure +* daddr Card address to write to. (host order) +* buf Ptr to data to write. +* len Length of data (host order). +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_ramdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len) +{ + int result = 0; + UINT8 *verbuf; + DBFENTER; + /* Check that we're in the ram download state */ + if ( ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) && + ( hw->dlstate != HFA384x_DLSTATE_GENESIS ) ) { + return -EINVAL; + } + + WLAN_LOG_INFO("Writing %d bytes to ram @0x%06x\n", len, daddr); +#if 0 +WLAN_HEX_DUMP(1, "dldata", buf, len); +#endif + /* Copy the data via the aux port */ + hfa384x_copy_to_aux(hw, daddr, HFA384x_AUX_CTL_EXTDS, buf, len); + + /* Create a buffer for the verify */ + verbuf = kmalloc(len, GFP_KERNEL); + if (verbuf == NULL ) return 1; + + /* Read back and compare */ + hfa384x_copy_from_aux(hw, daddr, HFA384x_AUX_CTL_EXTDS, verbuf, len); + + if ( memcmp(buf, verbuf, len) ) { + WLAN_LOG_DEBUG(1,"ramdl verify failed!\n"); + result = -EINVAL; + } + + kfree_s(verbuf, len); + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_flashdl_enable +* +* Begins the flash download state. Checks to see that we're not +* already in a download state and that a port isn't enabled. +* Sets the download state and retrieves the flash download +* buffer location, buffer size, and timeout length. +* +* Arguments: +* hw device structure +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_flashdl_enable(hfa384x_t *hw) +{ + int result = 0; + int i; + + DBFENTER; + /* Check that a port isn't active */ + for ( i = 0; i < HFA384x_PORTID_MAX; i++) { + if ( hw->port_enabled[i] ) { + WLAN_LOG_DEBUG(1,"called when port enabled.\n"); + return -EINVAL; + } + } + + /* Check that we're not already in a download state */ + if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) { + return -EINVAL; + } + + /* Retrieve the buffer loc&size and timeout */ + if ( (result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER, + &(hw->bufinfo), sizeof(hw->bufinfo))) ) { + return result; + } + hw->bufinfo.page = hfa384x2host_16(hw->bufinfo.page); + hw->bufinfo.offset = hfa384x2host_16(hw->bufinfo.offset); + hw->bufinfo.len = hfa384x2host_16(hw->bufinfo.len); + if ( (result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME, + &(hw->dltimeout))) ) { + return result; + } + hw->dltimeout = hfa384x2host_16(hw->dltimeout); + + /* Enable the aux port */ + if ( (result = hfa384x_cmd_aux_enable(hw, 0)) ) { + return result; + } + + hw->dlstate = HFA384x_DLSTATE_FLASHENABLED; + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_flashdl_disable +* +* Ends the flash download state. Note that this will cause the MAC +* firmware to restart. +* +* Arguments: +* hw device structure +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_flashdl_disable(hfa384x_t *hw) +{ + DBFENTER; + /* Check that we're already in the download state */ + if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) { + return -EINVAL; + } + + /* There isn't much we can do at this point, so I don't */ + /* bother w/ the return value */ + hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0); + hw->dlstate = HFA384x_DLSTATE_DISABLED; + + /* Disable the aux port */ + hfa384x_cmd_aux_disable(hw); + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_flashdl_write +* +* Performs a FLASH download of a chunk of data. First checks to see +* that we're in the FLASH download state, then sets the download +* mode, uses the aux functions to 1) copy the data to the flash +* buffer, 2) sets the download 'write flash' mode, 3) readback and +* compare. Lather rinse, repeat as many times an necessary to get +* all the given data into flash. +* When all data has been written using this function (possibly +* repeatedly), call drvr_flashdl_disable() to end the download state +* and restart the MAC. +* +* Arguments: +* hw device structure +* daddr Card address to write to. (host order) +* buf Ptr to data to write. +* len Length of data (host order). +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_flashdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len) +{ + int result = 0; + UINT8 *verbuf; + UINT32 dlbufaddr; + UINT32 currlen; + UINT32 currdaddr; + UINT16 destlo; + UINT16 desthi; + int nwrites; + int i; + + DBFENTER; + /* Check that we're in the flash download state */ + if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) { + return -EINVAL; + } + + WLAN_LOG_INFO("Download %d bytes to flash @0x%06x\n", len, daddr); + + /* Need a flat address for arithmetic */ + dlbufaddr = HFA384x_ADDR_AUX_MKFLAT( + hw->bufinfo.page, + hw->bufinfo.offset); + verbuf = kmalloc(hw->bufinfo.len, GFP_KERNEL); + +#if 0 +WLAN_LOG_WARNING("dlbuf@0x%06lx len=%d to=%d\n", dlbufaddr, hw->bufinfo.len, hw->dltimeout); +#endif + /* Figure out how many times to to the flash prog */ + nwrites = len / hw->bufinfo.len; + nwrites += (len % hw->bufinfo.len) ? 1 : 0; + + if ( verbuf == NULL ) { + WLAN_LOG_ERROR("Failed to allocate flash verify buffer\n"); + return 1; + } + /* For each */ + for ( i = 0; i < nwrites; i++) { + /* Get the dest address and len */ + currlen = (len - (hw->bufinfo.len * i)) > hw->bufinfo.len ? + hw->bufinfo.len : + (len - (hw->bufinfo.len * i)); + currdaddr = daddr + (hw->bufinfo.len * i); + destlo = HFA384x_ADDR_CMD_MKOFF(currdaddr); + desthi = HFA384x_ADDR_CMD_MKPAGE(currdaddr); + WLAN_LOG_INFO("Writing %d bytes to flash @0x%06x\n", currlen, currdaddr); +#if 0 +WLAN_HEX_DUMP(1, "dldata", buf+(hw->bufinfo.len*i), currlen); +#endif + /* Set the download mode */ + result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NV, + destlo, desthi, currlen); + if ( result ) { + WLAN_LOG_ERROR("download(NV,lo=%x,hi=%x,len=%x) " + "cmd failed, result=%d. Aborting d/l\n", + destlo, desthi, currlen, result); + goto exit_proc; + } + /* copy the data to the flash buffer */ + hfa384x_copy_to_aux(hw, dlbufaddr, HFA384x_AUX_CTL_EXTDS, + buf+(hw->bufinfo.len*i), currlen); + /* set the download 'write flash' mode */ + result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NVWRITE, 0,0,0); + if ( result ) { + WLAN_LOG_ERROR( + "download(NVWRITE,lo=%x,hi=%x,len=%x) " + "cmd failed, result=%d. Aborting d/l\n", + destlo, desthi, currlen, result); + goto exit_proc; + } + /* readback and compare, if fail...bail */ + hfa384x_copy_from_aux(hw, + currdaddr, HFA384x_AUX_CTL_NV, + verbuf, currlen); + + if ( memcmp(buf+(hw->bufinfo.len*i), verbuf, currlen) ) { + return -EINVAL; + } + } + +exit_proc: + /* DOH! This kfree's for you Mark :-) My forehead hurts... */ + kfree(verbuf); + + /* Leave the firmware in the 'post-prog' mode. flashdl_disable will */ + /* actually disable programming mode. Remember, that will cause the */ + /* the firmware to effectively reset itself. */ + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_initialize +* +* Issues the initialize command and sets the hw->state based +* on the result. +* +* Arguments: +* hw device structure +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_cmd_initialize(hfa384x_t *hw) +{ + int result = 0; + int i; + hfa384x_metacmd_t cmd; + + DBFENTER; + + /* we don't want to be interrupted during the reset */ + hfa384x_setreg(hw, 0, HFA384x_INTEN); + hfa384x_setreg(hw, 0xffff, HFA384x_EVACK); + + cmd.cmd = HFA384x_CMDCODE_INIT; + cmd.parm0 = 0; + cmd.parm1 = 0; + cmd.parm2 = 0; + + spin_lock_bh(&hw->cmdlock); + result = hfa384x_docmd_wait(hw, &cmd); + spin_unlock_bh(&hw->cmdlock); + + if ( result == 0 ) { + for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) { + hw->port_enabled[i] = 0; + } + } + + hw->link_status = HFA384x_LINK_NOTCONNECTED; + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_commtallies +* +* Send a commtallies inquiry to the MAC. Note that this is an async +* call that will result in an info frame arriving sometime later. +* +* Arguments: +* hw device structure +* +* Returns: +* zero success. +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_drvr_commtallies( hfa384x_t *hw ) +{ + hfa384x_metacmd_t cmd; + int result; + + DBFENTER; + + cmd.cmd = HFA384x_CMDCODE_INQ; + cmd.parm0 = HFA384x_IT_COMMTALLIES; + cmd.parm1 = 0; + cmd.parm2 = 0; + + spin_lock_bh(&hw->cmdlock); + result = hfa384x_docmd_wait(hw, &cmd); + spin_unlock_bh(&hw->cmdlock); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_enable +* +* Issues the enable command to enable communications on one of +* the MACs 'ports'. Only macport 0 is valid for stations. +* APs may also enable macports 1-6. Only ports that are currently +* disabled may be enabled. +* +* Arguments: +* hw device structure +* macport MAC port number +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_enable(hfa384x_t *hw, UINT16 macport) +{ + int result = 0; + + DBFENTER; + if ((!hw->isap && macport != 0) || + (hw->isap && !(macport <= HFA384x_PORTID_MAX)) || + (hw->port_enabled[macport]) ){ + result = -EINVAL; + } else { + result = hfa384x_cmd_enable(hw, macport); + if ( result == 0 ) { + hw->port_enabled[macport] = 1; + } + } + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_enable +* +* Issues the the enable command to enable communications on one of the +* MACs 'ports'. +* +* Arguments: +* hw device structure +* macport MAC port number +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_cmd_enable(hfa384x_t *hw, UINT16 macport) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ENABLE) | + HFA384x_CMD_MACPORT_SET(macport); + cmd.parm0 = 0; + cmd.parm1 = 0; + cmd.parm2 = 0; + + spin_lock_bh(&hw->cmdlock); + result = hfa384x_docmd_wait(hw, &cmd); + spin_unlock_bh(&hw->cmdlock); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_disable +* +* Issues the disable command to stop communications on one of +* the MACs 'ports'. Only macport 0 is valid for stations. +* APs may also disable macports 1-6. Only ports that have been +* previously enabled may be disabled. +* +* Arguments: +* hw device structure +* macport MAC port number (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_disable(hfa384x_t *hw, UINT16 macport) +{ + int result = 0; + + DBFENTER; + if ((!hw->isap && macport != 0) || + (hw->isap && !(macport <= HFA384x_PORTID_MAX)) || + !(hw->port_enabled[macport]) ){ + result = -EINVAL; + } else { + result = hfa384x_cmd_disable(hw, macport); + if ( result == 0 ) { + hw->port_enabled[macport] = 0; + } + } + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_disable +* +* Issues the command to disable a port. +* +* Arguments: +* hw device structure +* macport MAC port number (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_cmd_disable(hfa384x_t *hw, UINT16 macport) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DISABLE) | + HFA384x_CMD_MACPORT_SET(macport); + cmd.parm0 = 0; + cmd.parm1 = 0; + cmd.parm2 = 0; + + spin_lock_bh(&hw->cmdlock); + result = hfa384x_docmd_wait(hw, &cmd); + spin_unlock_bh(&hw->cmdlock); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_diagnose +* +* Issues the diagnose command to test the: register interface, +* MAC controller (including loopback), External RAM, Non-volatile +* memory integrity, and synthesizers. Following execution of this +* command, MAC/firmware are in the 'initial state'. Therefore, +* the Initialize command should be issued after successful +* completion of this command. This function may only be called +* when the MAC is in the 'communication disabled' state. +* +* Arguments: +* hw device structure +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +#define DIAG_PATTERNA ((UINT16)0xaaaa) +#define DIAG_PATTERNB ((UINT16)0x5555) + +int hfa384x_cmd_diagnose(hfa384x_t *hw) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DIAG); + cmd.parm0 = DIAG_PATTERNA; + cmd.parm1 = DIAG_PATTERNB; + cmd.parm2 = 0; + + spin_lock_bh(&hw->cmdlock); + result = hfa384x_docmd_wait(hw, &cmd); + spin_unlock_bh(&hw->cmdlock); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_allocate +* +* Issues the allocate command instructing the firmware to allocate +* a 'frame structure buffer' in MAC controller RAM. This command +* does not provide the result, it only initiates one of the f/w's +* asynchronous processes to construct the buffer. When the +* allocation is complete, it will be indicated via the Alloc +* bit in the EvStat register and the FID identifying the allocated +* space will be available from the AllocFID register. Some care +* should be taken when waiting for the Alloc event. If a Tx or +* Notify command w/ Reclaim has been previously executed, it's +* possible the first Alloc event after execution of this command +* will be for the reclaimed buffer and not the one you asked for. +* This case must be handled in the Alloc event handler. +* +* Arguments: +* hw device structure +* len allocation length, must be an even value +* in the range [4-2400]. (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_cmd_allocate(hfa384x_t *hw, UINT16 len) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + + if ( (len % 2) || + len < HFA384x_CMD_ALLOC_LEN_MIN || + len > HFA384x_CMD_ALLOC_LEN_MAX ) { + result = -EINVAL; + } else { + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ALLOC); + cmd.parm0 = len; + cmd.parm1 = 0; + cmd.parm2 = 0; + + spin_lock_bh(&hw->cmdlock); + result = hfa384x_docmd_wait(hw, &cmd); + spin_unlock_bh(&hw->cmdlock); + } + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_transmit +* +* Instructs the firmware to transmit a frame previously copied +* to a given buffer. This function returns immediately, the Tx +* results are available via the Tx or TxExc events (if the frame +* control bits are set). The reclaim argument specifies if the +* FID passed will be used by the f/w tx process or returned for +* use w/ another transmit command. If reclaim is set, expect an +* Alloc event signalling the availibility of the FID for reuse. +* +* NOTE: hw->cmdlock MUST BE HELD before calling this function! +* +* Arguments: +* hw device structure +* reclaim [0|1] indicates whether the given FID will +* be handed back (via Alloc event) for reuse. +* (host order) +* qos [0-3] Value to put in the QoS field of the +* tx command, identifies a queue to place the +* outgoing frame in. +* (host order) +* fid FID of buffer containing the frame that was +* previously copied to MAC memory via the bap. +* (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* hw->resp0 will contain the FID being used by async tx +* process. If reclaim==0, resp0 will be the same as the fid +* argument. If reclaim==1, resp0 will be the different and +* is the value to watch for in the Tx|TxExc to indicate completion +* of the frame passed in fid. +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_cmd_transmit(hfa384x_t *hw, UINT16 reclaim, UINT16 qos, UINT16 fid) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_TX) | + HFA384x_CMD_RECL_SET(reclaim) | + HFA384x_CMD_QOS_SET(qos); + cmd.parm0 = fid; + cmd.parm1 = 0; + cmd.parm2 = 0; + + result = hfa384x_docmd_wait(hw, &cmd); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_clearpersist +* +* Instructs the firmware to clear the persistence bit in a given +* FID. This has the effect of telling the firmware to drop the +* persistent frame. The FID must be one that was previously used +* to transmit a PRST frame. +* +* Arguments: +* hw device structure +* fid FID of the persistent frame (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_cmd_clearpersist(hfa384x_t *hw, UINT16 fid) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_CLRPRST); + cmd.parm0 = fid; + cmd.parm1 = 0; + cmd.parm2 = 0; + + spin_lock_bh(&hw->cmdlock); + result = hfa384x_docmd_wait(hw, &cmd); + spin_unlock_bh(&hw->cmdlock); + + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* hfa384x_cmd_notify +* +* Sends an info frame to the firmware to alter the behavior +* of the f/w asynch processes. Can only be called when the MAC +* is in the enabled state. +* +* Arguments: +* hw device structure +* reclaim [0|1] indicates whether the given FID will +* be handed back (via Alloc event) for reuse. +* (host order) +* fid FID of buffer containing the frame that was +* previously copied to MAC memory via the bap. +* (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* hw->resp0 will contain the FID being used by async notify +* process. If reclaim==0, resp0 will be the same as the fid +* argument. If reclaim==1, resp0 will be the different. +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_cmd_notify(hfa384x_t *hw, UINT16 reclaim, UINT16 fid, + void *buf, UINT16 len) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_NOTIFY) | + HFA384x_CMD_RECL_SET(reclaim); + cmd.parm0 = fid; + cmd.parm1 = 0; + cmd.parm2 = 0; + + spin_lock_bh(&hw->cmdlock); + + /* Copy the record to FID */ + result = hfa384x_copy_to_bap(hw, HFA384x_BAP_PROC, hw->infofid, 0, buf, len); + if ( result ) { + WLAN_LOG_DEBUG(1, + "copy_to_bap(%04x, 0, %d) failed, result=0x%x\n", + hw->infofid, len, result); + result = -EIO; + goto failed; + } + + result = hfa384x_docmd_wait(hw, &cmd); + + failed: + spin_unlock_bh(&hw->cmdlock); + + DBFEXIT; + return result; +} + + +#if 0 +/*---------------------------------------------------------------- +* hfa384x_cmd_inquiry +* +* Requests an info frame from the firmware. The info frame will +* be delivered asynchronously via the Info event. +* +* Arguments: +* hw device structure +* fid FID of the info frame requested. (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +static int hfa384x_cmd_inquiry(hfa384x_t *hw, UINT16 fid) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_INQ); + cmd.parm0 = fid; + cmd.parm1 = 0; + cmd.parm2 = 0; + + spin_lock_bh(&hw->cmdlock); + result = hfa384x_docmd_wait(hw, &cmd); + spin_unlock_bh(&hw->cmdlock); + + DBFEXIT; + return result; +} +#endif + + +/*---------------------------------------------------------------- +* hfa384x_cmd_access +* +* Requests that a given record be copied to/from the record +* buffer. If we're writing from the record buffer, the contents +* must previously have been written to the record buffer via the +* bap. If we're reading into the record buffer, the record can +* be read out of the record buffer after this call. +* +* Arguments: +* hw device structure +* write [0|1] copy the record buffer to the given +* configuration record. (host order) +* rid RID of the record to read/write. (host order) +* buf host side record buffer. Upon return it will +* contain the body portion of the record (minus the +* RID and len). +* len buffer length (in bytes, should match record length) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_cmd_access(hfa384x_t *hw, UINT16 write, UINT16 rid, + void* buf, UINT16 len) +{ + int result = 0; + hfa384x_metacmd_t cmd; + hfa384x_rec_t rec; + + DBFENTER; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)) + /* This should NOT be called in interrupt context! */ + if (in_irq()) { + WLAN_LOG_ERROR("Krap, in Interrupt context!"); +#ifdef WLAN_INCLUDE_DEBUG + BUG(); +#endif + } +#endif + spin_lock_bh(&hw->cmdlock); + + if (write) { + rec.rid = host2hfa384x_16(rid); + rec.reclen = host2hfa384x_16((len/2) + 1); /* note conversion to words, +1 for rid field */ + /* write the record */ + result = hfa384x_copy_to_bap4( hw, HFA384x_BAP_PROC, rid, 0, + &rec, sizeof(rec), + buf, len, + NULL, 0, NULL, 0); + if ( result ) { + WLAN_LOG_DEBUG(3,"Failure writing record header+data\n"); + goto fail; + } + + } + + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ACCESS) | + HFA384x_CMD_WRITE_SET(write); + cmd.parm0 = rid; + cmd.parm1 = 0; + cmd.parm2 = 0; + + result = hfa384x_docmd_wait(hw, &cmd); + if ( result ) { + WLAN_LOG_ERROR("Call to hfa384x_docmd_wait failed (%d %d)\n", + result, cmd.result.resp0); + goto fail; + } + + if (!write) { + result = hfa384x_copy_from_bap( hw, HFA384x_BAP_PROC, rid, 0, &rec, sizeof(rec)); + if ( result ) { + WLAN_LOG_DEBUG(3,"Call to hfa384x_copy_from_bap failed\n"); + goto fail; + } + + /* Validate the record length */ + if ( ((hfa384x2host_16(rec.reclen)-1)*2) != len ) { /* note body len calculation in bytes */ + WLAN_LOG_DEBUG(1, "RID len mismatch, rid=0x%04x hlen=%d fwlen=%d\n", + rid, len, (hfa384x2host_16(rec.reclen)-1)*2); + result = -ENODATA; + goto fail; + } + + result = hfa384x_copy_from_bap( hw, HFA384x_BAP_PROC, rid, sizeof(rec), buf, len); + + } + + fail: + spin_unlock_bh(&hw->cmdlock); + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_monitor +* +* Enables the 'monitor mode' of the MAC. Here's the description of +* monitor mode that I've received thus far: +* +* "The "monitor mode" of operation is that the MAC passes all +* frames for which the PLCP checks are correct. All received +* MPDUs are passed to the host with MAC Port = 7, with a +* receive status of good, FCS error, or undecryptable. Passing +* certain MPDUs is a violation of the 802.11 standard, but useful +* for a debugging tool." Normal communication is not possible +* while monitor mode is enabled. +* +* Arguments: +* hw device structure +* enable a code (0x0b|0x0f) that enables/disables +* monitor mode. (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_cmd_monitor(hfa384x_t *hw, UINT16 enable) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR) | + HFA384x_CMD_AINFO_SET(enable); + cmd.parm0 = 0; + cmd.parm1 = 0; + cmd.parm2 = 0; + + spin_lock_bh(&hw->cmdlock); + result = hfa384x_docmd_wait(hw, &cmd); + spin_unlock_bh(&hw->cmdlock); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_download +* +* Sets the controls for the MAC controller code/data download +* process. The arguments set the mode and address associated +* with a download. Note that the aux registers should be enabled +* prior to setting one of the download enable modes. +* +* Arguments: +* hw device structure +* mode 0 - Disable programming and begin code exec +* 1 - Enable volatile mem programming +* 2 - Enable non-volatile mem programming +* 3 - Program non-volatile section from NV download +* buffer. +* (host order) +* lowaddr +* highaddr For mode 1, sets the high & low order bits of +* the "destination address". This address will be +* the execution start address when download is +* subsequently disabled. +* For mode 2, sets the high & low order bits of +* the destination in NV ram. +* For modes 0 & 3, should be zero. (host order) +* NOTE: these address args are in CMD format +* codelen Length of the data to write in mode 2, +* zero otherwise. (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_cmd_download(hfa384x_t *hw, UINT16 mode, UINT16 lowaddr, + UINT16 highaddr, UINT16 codelen) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DOWNLD) | + HFA384x_CMD_PROGMODE_SET(mode); + cmd.parm0 = lowaddr; + cmd.parm1 = highaddr; + cmd.parm2 = codelen; + + spin_lock_bh(&hw->cmdlock); + result = hfa384x_dl_docmd_wait(hw, &cmd); + spin_unlock_bh(&hw->cmdlock); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_aux_enable +* +* Goes through the process of enabling the auxilary port. This +* is necessary prior to raw reads/writes to card data space. +* Direct access to the card data space is only used for downloading +* code and debugging. +* Note that a call to this function is required before attempting +* a download. +* +* Arguments: +* hw device structure +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_cmd_aux_enable(hfa384x_t *hw, int force) +{ + int result = -ETIMEDOUT; + unsigned long flags; + UINT32 retries_remaining; + UINT16 reg; + UINT auxen_mirror = hw->auxen; + + DBFENTER; + + /* Check for existing enable */ + if ( hw->auxen ) { + hw->auxen++; + return 0; + } + + /* acquire the lock */ + spin_lock_irqsave( &(hw->cmdlock), flags); + /* wait for cmd register busy bit to clear */ + retries_remaining = 100000; + do { + reg = hfa384x_getreg(hw, HFA384x_CMD); + udelay(10); + } + while (HFA384x_CMD_ISBUSY(reg) && --retries_remaining); + if (retries_remaining != 0) { + /* busy bit clear, it's OK to write to ParamX regs */ + hfa384x_setreg(hw, HFA384x_AUXPW0, + HFA384x_PARAM0); + hfa384x_setreg(hw, HFA384x_AUXPW1, + HFA384x_PARAM1); + hfa384x_setreg(hw, HFA384x_AUXPW2, + HFA384x_PARAM2); + + /* Set the aux enable in the Control register */ + hfa384x_setreg(hw, HFA384x_CONTROL_AUX_DOENABLE, + HFA384x_CONTROL); + + /* Now wait for completion */ + retries_remaining = 100000; + do { + reg = hfa384x_getreg(hw, HFA384x_CONTROL); + udelay(10); + } + while ( ((reg & (BIT14|BIT15)) != HFA384x_CONTROL_AUX_ISENABLED) && + --retries_remaining ); + if (retries_remaining != 0) { + result = 0; + hw->auxen++; + } + } + + /* Force it enabled even if the command failed, if told.. */ + if ((hw->auxen == auxen_mirror) && force) + hw->auxen++; + + spin_unlock_irqrestore( &(hw->cmdlock), flags); + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_aux_disable +* +* Goes through the process of disabling the auxilary port +* enabled with aux_enable(). +* +* Arguments: +* hw device structure +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_cmd_aux_disable(hfa384x_t *hw) +{ + int result = -ETIMEDOUT; + unsigned long timeout; + UINT16 reg = 0; + + DBFENTER; + + /* See if there's more than one enable */ + if (hw->auxen) hw->auxen--; + if (hw->auxen) return 0; + + /* Clear the aux enable in the Control register */ + hfa384x_setreg(hw, 0, HFA384x_PARAM0); + hfa384x_setreg(hw, 0, HFA384x_PARAM1); + hfa384x_setreg(hw, 0, HFA384x_PARAM2); + hfa384x_setreg(hw, HFA384x_CONTROL_AUX_DODISABLE, + HFA384x_CONTROL); + + /* Now wait for completion */ + timeout = jiffies + 1*HZ; + reg = hfa384x_getreg(hw, HFA384x_CONTROL); + while ( ((reg & (BIT14|BIT15)) != HFA384x_CONTROL_AUX_ISDISABLED) && + time_before(jiffies,timeout) ){ + udelay(10); + reg = hfa384x_getreg(hw, HFA384x_CONTROL); + } + if ((reg & (BIT14|BIT15)) == HFA384x_CONTROL_AUX_ISDISABLED ) { + result = 0; + } + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* hfa384x_drvr_low_level +* +* Write test commands to the card. Some test commands don't make +* sense without prior set-up. For example, continous TX isn't very +* useful until you set the channel. That functionality should be +* +* Side effects: +* +* Call context: +* process thread +* -----------------------------------------------------------------*/ +int hfa384x_drvr_low_level(hfa384x_t *hw, hfa384x_metacmd_t *cmd) +{ + int result = 0; + DBFENTER; + + /* Do i need a host2hfa... conversion ? */ +#if 0 + printk(KERN_INFO "%#x %#x %#x %#x\n", cmd->cmd, cmd->parm0, cmd->parm1, cmd->parm2); +#endif + spin_lock_bh(&hw->cmdlock); + result = hfa384x_docmd_wait(hw, cmd); + spin_unlock_bh(&hw->cmdlock); + + DBFEXIT; + return result; +} + + +/* TODO: determine if these will ever be needed */ +#if 0 +int hfa384x_cmd_readmif(hfa384x_t *hw) +{ + DBFENTER; + DBFEXIT; + return 0; +} + + +int hfa384x_cmd_writemif(hfa384x_t *hw) +{ + DBFENTER; + DBFEXIT; + return 0; +} +#endif + +/*---------------------------------------------------------------- +* hfa384x_drvr_mmi_read +* +* Read mmi registers. mmi is intersil-speak for the baseband +* processor registers. +* +* Arguments: +* hw device structure +* register The test register to be accessed (must be even #). +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_mmi_read(hfa384x_t *hw, UINT32 addr, UINT32 *resp) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + cmd.cmd = (UINT16) 0x30; + cmd.parm0 = (UINT16) addr; + cmd.parm1 = 0; + cmd.parm2 = 0; + + /* Do i need a host2hfa... conversion ? */ + spin_lock_bh(&hw->cmdlock); + result = hfa384x_docmd_wait(hw, &cmd); + spin_unlock_bh(&hw->cmdlock); + + *resp = (UINT32) cmd.result.resp0; + + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* hfa384x_drvr_mmi_write +* +* Read mmi registers. mmi is intersil-speak for the baseband +* processor registers. +* +* Arguments: +* hw device structure +* addr The test register to be accessed (must be even #). +* data The data value to write to the register. +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ + +int +hfa384x_drvr_mmi_write(hfa384x_t *hw, UINT32 addr, UINT32 data) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + cmd.cmd = (UINT16) 0x31; + cmd.parm0 = (UINT16) addr; + cmd.parm1 = (UINT16) data; + cmd.parm2 = 0; + + WLAN_LOG_DEBUG(1,"mmi write : addr = 0x%08x\n", addr); + WLAN_LOG_DEBUG(1,"mmi write : data = 0x%08x\n", data); + + /* Do i need a host2hfa... conversion ? */ + spin_lock_bh(&hw->cmdlock); + result = hfa384x_docmd_wait(hw, &cmd); + spin_unlock_bh(&hw->cmdlock); + + DBFEXIT; + return result; +} + + +/* TODO: determine if these will ever be needed */ +#if 0 +int hfa384x_cmd_readmif(hfa384x_t *hw) +{ + DBFENTER; + DBFEXIT; + return 0; +} + + +int hfa384x_cmd_writemif(hfa384x_t *hw) +{ + DBFENTER; + DBFEXIT; + return 0; +} +#endif + + + +/*---------------------------------------------------------------- +* hfa384x_copy_from_bap +* +* Copies a collection of bytes from the MAC controller memory via +* one set of BAP registers. +* +* Arguments: +* hw device structure +* bap [0|1] which BAP to use +* id FID or RID, destined for the select register (host order) +* offset An _even_ offset into the buffer for the given +* FID/RID. We haven't the means to validate this, +* so be careful. (host order) +* buf ptr to array of bytes +* len length of data to transfer in bytes +* +* Returns: +* 0 success +* >0 f/w reported failure - value of offset reg. +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +* interrupt +----------------------------------------------------------------*/ +int hfa384x_copy_from_bap(hfa384x_t *hw, UINT16 bap, UINT16 id, UINT16 offset, + void *buf, UINT len) +{ + int result = 0; + unsigned long flags = 0; + UINT8 *d = (UINT8*)buf; + UINT selectreg; + UINT offsetreg; + UINT datareg; + UINT i; + UINT16 reg = 0; + + DBFENTER; + + /* Validate bap, offset, buf, and len */ + if ( (bap > 1) || + (offset > HFA384x_BAP_OFFSET_MAX) || + (offset % 2) || + (buf == NULL) || + (len > HFA384x_BAP_DATALEN_MAX) ){ + result = -EINVAL; + } else { + selectreg = (bap == 1) ? HFA384x_SELECT1 : HFA384x_SELECT0 ; + offsetreg = (bap == 1) ? HFA384x_OFFSET1 : HFA384x_OFFSET0 ; + datareg = (bap == 1) ? HFA384x_DATA1 : HFA384x_DATA0 ; + + /* Obtain lock */ + spin_lock_irqsave( &(hw->baplock), flags); + + /* Write id to select reg */ + hfa384x_setreg(hw, id, selectreg); + /* Write offset to offset reg */ + hfa384x_setreg(hw, offset, offsetreg); + /* Wait for offset[busy] to clear (see BAP_TIMEOUT) */ + i = 0; + do { + reg = hfa384x_getreg(hw, offsetreg); + if ( i > 0 ) udelay(10); + i++; + } while ( i < prism2_bap_timeout && HFA384x_OFFSET_ISBUSY(reg)); +#if (WLAN_HOSTIF != WLAN_PCI) + /* Release lock */ + spin_unlock_irqrestore( &(hw->baplock), flags); +#endif + + if ( HFA384x_OFFSET_ISBUSY(reg) ){ + /* If timeout, return -ETIMEDOUT */ + result = reg; + } else if ( HFA384x_OFFSET_ISERR(reg) ){ + /* If offset[err] == 1, return -EINVAL */ + result = reg; + } else { + /* Read even(len) buf contents from data reg */ + for ( i = 0; i < (len & 0xfffe); i+=2 ) { + *(UINT16*)(&(d[i])) = + hfa384x_getreg_noswap(hw, datareg); + } + /* If len odd, handle last byte */ + if ( len % 2 ){ + reg = hfa384x_getreg_noswap(hw, datareg); + d[len-1] = ((UINT8*)(®))[0]; + } + } + + /* According to Intersil errata dated 9/16/02: + + "In PRISM PCI MAC host interface, if both BAPs are concurrently + requesing memory access, both will accept the Ack. There is no + firmware workaround possible. To prevent BAP access failures or + hang conditions the host MUST NOT access both BAPs in sucession + unless at least 5us elapses between accesses. The safest choice + is to USE ONLY ONE BAP for all data movement operations." + + What this means: + + We have to serialize ALL BAP accesses, and furthermore, add a 5us + delay after access if we're using a PCI platform. + + Unfortunately, this means we have to lock out interrupts througout + the entire BAP copy. + + It remains to be seen if "BAP access" means "BAP setup" or the more + literal definition of "copying data back and forth" I'm erring for + the latter, safer definition. -- SLP. + + */ + +#if (WLAN_HOSTIF == WLAN_PCI) + udelay(5); + /* Release lock */ + spin_unlock_irqrestore( &(hw->baplock), flags); +#endif + + } + + if (result) { + WLAN_LOG_DEBUG(1, + "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n", + reg, len, result); + } + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_copy_to_bap +* +* Copies a collection of bytes to the MAC controller memory via +* one set of BAP registers. +* +* Arguments: +* hw device structure +* bap [0|1] which BAP to use +* id FID or RID, destined for the select register (host order) +* offset An _even_ offset into the buffer for the given +* FID/RID. We haven't the means to validate this, +* so be careful. (host order) +* buf ptr to array of bytes +* len length of data to transfer (in bytes) +* +* Returns: +* 0 success +* >0 f/w reported failure - value of offset reg. +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +* interrupt +----------------------------------------------------------------*/ +int hfa384x_copy_to_bap(hfa384x_t *hw, UINT16 bap, UINT16 id, UINT16 offset, + void *buf, UINT len) +{ + return hfa384x_copy_to_bap4(hw, bap, id, offset, buf, len, NULL, 0, NULL, 0, NULL, 0); +} + +int hfa384x_copy_to_bap4(hfa384x_t *hw, UINT16 bap, UINT16 id, UINT16 offset, + void *buf, UINT len1, void* buf2, UINT len2, + void *buf3, UINT len3, void *buf4, UINT len4) +{ + int result = 0; + unsigned long flags = 0; + UINT8 *d; + UINT selectreg; + UINT offsetreg; + UINT datareg; + UINT i; + UINT16 reg; + + DBFENTER; + +// printk(KERN_DEBUG "ctb1 %d id %04x o %d %d %d %d %d\n", bap, id, offset, len1, len2, len3, len4); + + /* Validate bap, offset, buf, and len */ + if ( (bap > 1) || + (offset > HFA384x_BAP_OFFSET_MAX) || + (offset % 2) || + (buf == NULL) || + (len1+len2+len3+len4 > HFA384x_BAP_DATALEN_MAX) ){ + result = -EINVAL; + } else { + selectreg = (bap == 1) ? HFA384x_SELECT1 : HFA384x_SELECT0; + offsetreg = (bap == 1) ? HFA384x_OFFSET1 : HFA384x_OFFSET0; + datareg = (bap == 1) ? HFA384x_DATA1 : HFA384x_DATA0; + /* Obtain lock */ + spin_lock_irqsave( &(hw->baplock), flags); + + /* Write id to select reg */ + hfa384x_setreg(hw, id, selectreg); + udelay(10); + /* Write offset to offset reg */ + hfa384x_setreg(hw, offset, offsetreg); + /* Wait for offset[busy] to clear (see BAP_TIMEOUT) */ + i = 0; + do { + reg = hfa384x_getreg(hw, offsetreg); + if ( i > 0 ) udelay(10); + i++; + } while ( i < prism2_bap_timeout && HFA384x_OFFSET_ISBUSY(reg)); + +#if (WLAN_HOSTIF != WLAN_PCI) + /* Release lock */ + spin_unlock_irqrestore( &(hw->baplock), flags); +#endif + + if ( HFA384x_OFFSET_ISBUSY(reg) ){ + /* If timeout, return reg */ + result = reg; + } else if ( HFA384x_OFFSET_ISERR(reg) ){ + /* If offset[err] == 1, return reg */ + result = reg; + } else { + d = (UINT8*)buf; + /* Write even(len1) buf contents to data reg */ + for ( i = 0; i < (len1 & 0xfffe); i+=2 ) { + hfa384x_setreg_noswap(hw, + *(UINT16*)(&(d[i])), datareg); + } + if (len1 & 1) { + UINT16 data; + UINT8 *b = (UINT8 *) &data; + b[0] = d[len1-1]; + if (buf2 != NULL) { + d = (UINT8*)buf2; + b[1] = d[0]; + len2--; + buf2++; + } + hfa384x_setreg_noswap(hw, data, datareg); + } + if ((buf2 != NULL) && (len2 > 0)) { + /* Write even(len2) buf contents to data reg */ + d = (UINT8*)buf2; + for ( i = 0; i < (len2 & 0xfffe); i+=2 ) { + hfa384x_setreg_noswap(hw, *(UINT16*)(&(d[i])), datareg); + } + if (len2 & 1) { + UINT16 data; + UINT8 *b = (UINT8 *) &data; + b[0] = d[len2-1]; + if (buf3 != NULL) { + d = (UINT8*)buf3; + b[1] = d[0]; + len3--; + buf3++; + } + hfa384x_setreg_noswap(hw, data, datareg); + } + } + + if ((buf3 != NULL) && (len3 > 0)) { + /* Write even(len3) buf contents to data reg */ + d = (UINT8*)buf3; + for ( i = 0; i < (len3 & 0xfffe); i+=2 ) { + hfa384x_setreg_noswap(hw, *(UINT16*)(&(d[i])), datareg); + } + if (len3 & 1) { + UINT16 data; + UINT8 *b = (UINT8 *) &data; + b[0] = d[len3-1]; + if (buf4 != NULL) { + d = (UINT8*)buf4; + b[1] = d[0]; + len4--; + buf4++; + } + hfa384x_setreg_noswap(hw, data, datareg); + } + } + if ((buf4 != NULL) && (len4 > 0)) { + /* Write even(len4) buf contents to data reg */ + d = (UINT8*)buf4; + for ( i = 0; i < (len4 & 0xfffe); i+=2 ) { + hfa384x_setreg_noswap(hw, *(UINT16*)(&(d[i])), datareg); + } + if (len4 & 1) { + UINT16 data; + UINT8 *b = (UINT8 *) &data; + b[0] = d[len4-1]; + b[1] = 0; + + hfa384x_setreg_noswap(hw, data, datareg); + } + } +// printk(KERN_DEBUG "ctb2 %d id %04x o %d %d %d %d %d\n", bap, id, offset, len1, len2, len3, len4); + + } + +#if (WLAN_HOSTIF == WLAN_PCI) + udelay(5); + /* Release lock */ + spin_unlock_irqrestore( &(hw->baplock), flags); +#endif + + } + + if (result) + WLAN_LOG_ERROR("copy_to_bap() failed.\n"); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_copy_from_aux +* +* Copies a collection of bytes from the controller memory. The +* Auxiliary port MUST be enabled prior to calling this function. +* We _might_ be in a download state. +* +* Arguments: +* hw device structure +* cardaddr address in hfa384x data space to read +* auxctl address space select +* buf ptr to destination host buffer +* len length of data to transfer (in bytes) +* +* Returns: +* nothing +* +* Side effects: +* buf contains the data copied +* +* Call context: +* process thread +* interrupt +----------------------------------------------------------------*/ +void +hfa384x_copy_from_aux( + hfa384x_t *hw, UINT32 cardaddr, UINT32 auxctl, void *buf, UINT len) +{ + UINT16 currpage; + UINT16 curroffset; + UINT i = 0; + + DBFENTER; + + if ( !(hw->auxen) ) { + WLAN_LOG_DEBUG(1, + "Attempt to read 0x%04x when aux not enabled\n", + cardaddr); + return; + + } + /* Build appropriate aux page and offset */ + currpage = HFA384x_AUX_MKPAGE(cardaddr); + curroffset = HFA384x_AUX_MKOFF(cardaddr, auxctl); + hfa384x_setreg(hw, currpage, HFA384x_AUXPAGE); + hfa384x_setreg(hw, curroffset, HFA384x_AUXOFFSET); + udelay(5); /* beat */ + + /* read the data */ + while ( i < len) { + *((UINT16*)(buf+i)) = hfa384x_getreg_noswap(hw, HFA384x_AUXDATA); + i+=2; + curroffset+=2; + if ( (curroffset&HFA384x_ADDR_AUX_OFF_MASK) > + HFA384x_ADDR_AUX_OFF_MAX ) { + currpage++; + curroffset = 0; + curroffset = HFA384x_AUX_MKOFF(curroffset, auxctl); + hfa384x_setreg(hw, currpage, HFA384x_AUXPAGE); + hfa384x_setreg(hw, curroffset, HFA384x_AUXOFFSET); + udelay(5); /* beat */ + } + } + /* Make sure the auxctl bits are clear */ + hfa384x_setreg(hw, 0, HFA384x_AUXOFFSET); + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_copy_to_aux +* +* Copies a collection of bytes to the controller memory. The +* Auxiliary port MUST be enabled prior to calling this function. +* We _might_ be in a download state. +* +* Arguments: +* hw device structure +* cardaddr address in hfa384x data space to read +* auxctl address space select +* buf ptr to destination host buffer +* len length of data to transfer (in bytes) +* +* Returns: +* nothing +* +* Side effects: +* Controller memory now contains a copy of buf +* +* Call context: +* process thread +* interrupt +----------------------------------------------------------------*/ +void +hfa384x_copy_to_aux( + hfa384x_t *hw, UINT32 cardaddr, UINT32 auxctl, void *buf, UINT len) +{ + UINT16 currpage; + UINT16 curroffset; + UINT i = 0; + + DBFENTER; + + if ( !(hw->auxen) ) { + WLAN_LOG_DEBUG(1, + "Attempt to read 0x%04x when aux not enabled\n", + cardaddr); + return; + + } + /* Build appropriate aux page and offset */ + currpage = HFA384x_AUX_MKPAGE(cardaddr); + curroffset = HFA384x_AUX_MKOFF(cardaddr, auxctl); + hfa384x_setreg(hw, currpage, HFA384x_AUXPAGE); + hfa384x_setreg(hw, curroffset, HFA384x_AUXOFFSET); + udelay(5); /* beat */ + + /* write the data */ + while ( i < len) { + hfa384x_setreg_noswap(hw, + *((UINT16*)(buf+i)), HFA384x_AUXDATA); + i+=2; + curroffset+=2; + if ( curroffset > HFA384x_ADDR_AUX_OFF_MAX ) { + currpage++; + curroffset = 0; + hfa384x_setreg(hw, currpage, HFA384x_AUXPAGE); + hfa384x_setreg(hw, curroffset, HFA384x_AUXOFFSET); + udelay(5); /* beat */ + } + } + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_wait +* +* Waits for availability of the Command register, then +* issues the given command. Then polls the Evstat register +* waiting for command completion. Timeouts shouldn't be +* possible since we're preventing overlapping commands and all +* commands should be cleared and acknowledged. +* +* Arguments: +* wlandev device structure +* cmd cmd structure. Includes all arguments and result +* data points. All in host order. +* +* Returns: +* 0 success +* -ETIMEDOUT timed out waiting for register ready or +* command completion +* >0 command indicated error, Status and Resp0-2 are +* in hw structure. +* +* Side effects: +* +* +* Call context: +* process thread +----------------------------------------------------------------*/ +static int hfa384x_docmd_wait( hfa384x_t *hw, hfa384x_metacmd_t *cmd) +{ + int result = -ETIMEDOUT; + UINT16 reg = 0; + UINT16 counter; + + DBFENTER; + + hw->cmdflag = 0; + hw->cmddata = cmd; + + /* wait for the busy bit to clear */ + counter = 0; + reg = hfa384x_getreg(hw, HFA384x_CMD); + while ( HFA384x_CMD_ISBUSY(reg) && + (counter < 10)) { + reg = hfa384x_getreg(hw, HFA384x_CMD); + counter++; + udelay(10); + } + + if (HFA384x_CMD_ISBUSY(reg)) { + WLAN_LOG_ERROR("hfa384x_cmd timeout(1), reg=0x%0hx.\n", reg); + goto failed; + } + if (!HFA384x_CMD_ISBUSY(reg)) { + /* busy bit clear, write command */ + hfa384x_setreg(hw, cmd->parm0, HFA384x_PARAM0); + hfa384x_setreg(hw, cmd->parm1, HFA384x_PARAM1); + hfa384x_setreg(hw, cmd->parm2, HFA384x_PARAM2); + hfa384x_setreg(hw, cmd->cmd, HFA384x_CMD); + +#ifdef CMD_IRQ + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,2,0)) + while (! hw->cmdflag) + interruptible_sleep_on(&hw->cmdq); +#else + wait_event_interruptible(hw->cmdq, hw->cmdflag); +#endif + result = HFA384x_STATUS_RESULT_GET(cmd->status); +#else // CMD_IRQ + /* Now wait for completion */ + counter = 0; + reg = hfa384x_getreg(hw, HFA384x_EVSTAT); + /* Initialization is the problem. It takes about + 100ms. "normal" commands are typically is about + 200-400 us (I've never seen less than 200). Longer + is better so that we're not hammering the bus. */ + while ( !HFA384x_EVSTAT_ISCMD(reg) && + (counter < 5000)) { + reg = hfa384x_getreg(hw, HFA384x_EVSTAT); + counter++; + udelay(200); + } + + if ( HFA384x_EVSTAT_ISCMD(reg) ) { + result = 0; + cmd->result.status = hfa384x_getreg(hw, HFA384x_STATUS); + cmd->result.resp0 = hfa384x_getreg(hw, HFA384x_RESP0); + cmd->result.resp1 = hfa384x_getreg(hw, HFA384x_RESP1); + cmd->result.resp2 = hfa384x_getreg(hw, HFA384x_RESP2); + hfa384x_setreg(hw, HFA384x_EVACK_CMD, + HFA384x_EVACK); + result = HFA384x_STATUS_RESULT_GET(cmd->result.status); + } else { + WLAN_LOG_ERROR("hfa384x_cmd timeout(2), reg=0x%0hx.\n", reg); + } +#endif /* CMD_IRQ */ + } + + failed: + hw->cmdflag = 0; + hw->cmddata = NULL; + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_dl_docmd_wait +* +* Waits for availability of the Command register, then +* issues the given command. Then polls the Evstat register +* waiting for command completion. Timeouts shouldn't be +* possible since we're preventing overlapping commands and all +* commands should be cleared and acknowledged. +* +* This routine is only used for downloads. Since it doesn't lock out +* interrupts the system response is much better. +* +* Arguments: +* wlandev device structure +* cmd cmd structure. Includes all arguments and result +* data points. All in host order. +* +* Returns: +* 0 success +* -ETIMEDOUT timed out waiting for register ready or +* command completion +* >0 command indicated error, Status and Resp0-2 are +* in hw structure. +* +* Side effects: +* +* +* Call context: +* process thread +----------------------------------------------------------------*/ +static int hfa384x_dl_docmd_wait( hfa384x_t *hw, hfa384x_metacmd_t *cmd) +{ + int result = -ETIMEDOUT; + unsigned long timeout; + UINT16 reg = 0; + + DBFENTER; + /* wait for the busy bit to clear */ + timeout = jiffies + 1*HZ; + reg = hfa384x_getreg(hw, HFA384x_CMD); + while ( HFA384x_CMD_ISBUSY(reg) && time_before( jiffies, timeout) ) { + reg = hfa384x_getreg(hw, HFA384x_CMD); + udelay(10); + } + if (HFA384x_CMD_ISBUSY(reg)) { + WLAN_LOG_WARNING("Timed out waiting for cmd register.\n"); + goto failed; + } + + if (!HFA384x_CMD_ISBUSY(reg)) { + /* busy bit clear, write command */ + hfa384x_setreg(hw, cmd->parm0, HFA384x_PARAM0); + hfa384x_setreg(hw, cmd->parm1, HFA384x_PARAM1); + hfa384x_setreg(hw, cmd->parm2, HFA384x_PARAM2); + hfa384x_setreg(hw, cmd->cmd, HFA384x_CMD); + + /* Now wait for completion */ + if ( (HFA384x_CMD_CMDCODE_GET(cmd->cmd) == HFA384x_CMDCODE_DOWNLD) ) { + /* dltimeout is in ms */ + timeout = (((UINT32)hw->dltimeout) / 1000UL) * HZ; + if ( timeout > 0 ) { + timeout += jiffies; + } else { + timeout = jiffies + 1*HZ; + } + } else { + timeout = jiffies + 1*HZ; + } + reg = hfa384x_getreg(hw, HFA384x_EVSTAT); + while ( !HFA384x_EVSTAT_ISCMD(reg) && time_before(jiffies,timeout) ) { + udelay(100); + reg = hfa384x_getreg(hw, HFA384x_EVSTAT); + } + if ( HFA384x_EVSTAT_ISCMD(reg) ) { + result = 0; + cmd->result.status = hfa384x_getreg(hw, HFA384x_STATUS); + cmd->result.resp0 = hfa384x_getreg(hw, HFA384x_RESP0); + cmd->result.resp1 = hfa384x_getreg(hw, HFA384x_RESP1); + cmd->result.resp2 = hfa384x_getreg(hw, HFA384x_RESP2); + hfa384x_setreg(hw, HFA384x_EVACK_CMD, HFA384x_EVACK); + result = HFA384x_STATUS_RESULT_GET(cmd->result.status); + } + } + +failed: + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* hfa384x_drvr_start +* +* Issues the MAC initialize command, sets up some data structures, +* and enables the interrupts. After this function completes, the +* low-level stuff should be ready for any/all commands. +* +* Arguments: +* hw device structure +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_start(hfa384x_t *hw) +{ + int result = 0; + UINT16 reg; + int i; + int j; + DBFENTER; + + /* call initialize */ + result = hfa384x_cmd_initialize(hw); + if (result != 0) { + WLAN_LOG_ERROR("Initialize command failed.\n"); + goto failed; + } + + /* make sure interrupts are disabled and any layabout events cleared */ + hfa384x_setreg(hw, 0, HFA384x_INTEN); + hfa384x_setreg(hw, 0xffff, HFA384x_EVACK); + + hw->txfid_head = 0; + hw->txfid_tail = 0; + hw->txfid_N = HFA384x_DRVR_FIDSTACKLEN_MAX; + memset(hw->txfid_queue, 0, sizeof(hw->txfid_queue)); + + /* Allocate tx and notify FIDs */ + /* First, tx */ + for ( i = 0; i < HFA384x_DRVR_FIDSTACKLEN_MAX-1; i++) { + result = hfa384x_cmd_allocate(hw, HFA384x_DRVR_TXBUF_MAX); + if (result != 0) { + WLAN_LOG_ERROR("Allocate(tx) command failed.\n"); + goto failed; + } + j = 0; + do { + reg = hfa384x_getreg(hw, HFA384x_EVSTAT); + udelay(10); + j++; + } while ( !HFA384x_EVSTAT_ISALLOC(reg) && j < 50); /* 50 is timeout */ + if ( j >= 50 ) { + WLAN_LOG_ERROR("Timed out waiting for evalloc(tx).\n"); + result = -ETIMEDOUT; + goto failed; + } + reg = hfa384x_getreg(hw, HFA384x_ALLOCFID); + + txfid_queue_add(hw, reg); + + WLAN_LOG_DEBUG(4,"hw->txfid_queue[%d]=0x%04x\n",i,reg); + + reg = HFA384x_EVACK_ALLOC_SET(1); + hfa384x_setreg(hw, reg, HFA384x_EVACK); + + } + + /* Now, the info frame fid */ + result = hfa384x_cmd_allocate(hw, HFA384x_INFOFRM_MAXLEN); + if (result != 0) { + WLAN_LOG_ERROR("Allocate(tx) command failed.\n"); + goto failed; + } + i = 0; + do { + reg = hfa384x_getreg(hw, HFA384x_EVSTAT); + udelay(10); + i++; + } while ( !HFA384x_EVSTAT_ISALLOC(reg) && i < 50); /* 50 is timeout */ + if ( i >= 50 ) { + WLAN_LOG_ERROR("Timed out waiting for evalloc(info).\n"); + result = -ETIMEDOUT; + goto failed; + } + hw->infofid = hfa384x_getreg(hw, HFA384x_ALLOCFID); + reg = HFA384x_EVACK_ALLOC_SET(1); + hfa384x_setreg(hw, reg, HFA384x_EVACK); + WLAN_LOG_DEBUG(4,"hw->infofid=0x%04x\n", hw->infofid); + + /* Set swsupport regs to magic # for card presence detection */ + hfa384x_setreg(hw, HFA384x_DRVR_MAGIC, HFA384x_SWSUPPORT0); + + /* Now enable the interrupts and set the running state */ + hfa384x_setreg(hw, 0xffff, HFA384x_EVSTAT); + hfa384x_events_all(hw); + + hw->state = HFA384x_STATE_RUNNING; + + goto done; +failed: + WLAN_LOG_ERROR("Failed, result=%d\n", result); +done: + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_stop +* +* Issues the initialize command to leave us in the 'reset' state. +* +* Arguments: +* hw device structure +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_stop(hfa384x_t *hw) +{ + int result = 0; + int i; + DBFENTER; + + del_timer_sync(&hw->commsqual_timer); + + if ( hw->wlandev->hwremoved ) { + /* only flush when we're shutting down for good */ + flush_scheduled_work(); + } + + if (hw->state == HFA384x_STATE_RUNNING) { + /* + * Send the MAC initialize cmd. + */ + hfa384x_cmd_initialize(hw); + + /* + * Make absolutely sure interrupts are disabled and any + * layabout events cleared + */ + hfa384x_setreg(hw, 0, HFA384x_INTEN); + hfa384x_setreg(hw, 0xffff, HFA384x_EVACK); + } + + tasklet_kill(&hw->bap_tasklet); + + hw->link_status = HFA384x_LINK_NOTCONNECTED; + hw->state = HFA384x_STATE_INIT; + + /* Clear all the port status */ + for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) { + hw->port_enabled[i] = 0; + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_txframe +* +* Takes a frame from prism2sta and queues it for transmission. +* +* Arguments: +* hw device structure +* skb packet buffer struct. Contains an 802.11 +* data frame. +* p80211_hdr points to the 802.11 header for the packet. +* Returns: +* 0 Success and more buffs available +* 1 Success but no more buffs +* 2 Allocation failure +* 3 MAC Tx command failed +* 4 Buffer full or queue busy +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep) +{ + hfa384x_tx_frame_t txdesc; + UINT16 macq = 0; + UINT16 fid; + int result; + + DBFENTER; + + /* Build Tx frame structure */ + /* Set up the control field */ + memset(&txdesc, 0, sizeof(txdesc)); + +/* Tx complete and Tx exception disable per dleach. Might be causing + * buf depletion + */ +#define DOBOTH 1 +#if DOBOTH + txdesc.tx_control = + HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) | + HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(1); +#elif DOEXC + txdesc.tx_control = + HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) | + HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(0); +#else + txdesc.tx_control = + HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) | + HFA384x_TX_TXEX_SET(0) | HFA384x_TX_TXOK_SET(0); +#endif + + /* if we're using host WEP, increase size by IV+ICV */ + if (p80211_wep->data) { + txdesc.data_len = host2hfa384x_16(skb->len+8); + // txdesc.tx_control |= HFA384x_TX_NOENCRYPT_SET(1); + } else { + txdesc.data_len = host2hfa384x_16(skb->len); + } + + txdesc.tx_control = host2hfa384x_16(txdesc.tx_control); + /* copy the header over to the txdesc */ + memcpy(&(txdesc.frame_control), p80211_hdr, sizeof(p80211_hdr_t)); + + /* Since tbusy is set whenever the stack is empty, there should + * always be something on the stack if we get to this point. + * [MSM]: NOT TRUE!!!!! so I added the test of fid below. + */ + + /* Allocate FID */ + + fid = txfid_queue_remove(hw); + + if ( fid == 0 ) { /* stack or queue was empty */ + return 4; + } + + /* now let's get the cmdlock */ + spin_lock(&hw->cmdlock); + + /* Copy descriptor+payload to FID */ + if (p80211_wep->data) { + result = hfa384x_copy_to_bap4(hw, HFA384x_BAP_PROC, fid, 0, + &txdesc, sizeof(txdesc), + p80211_wep->iv, sizeof(p80211_wep->iv), + p80211_wep->data, skb->len, + p80211_wep->icv, sizeof(p80211_wep->icv)); + } else { + result = hfa384x_copy_to_bap4(hw, HFA384x_BAP_PROC, fid, 0, + &txdesc, sizeof(txdesc), + skb->data, skb->len, + NULL, 0, NULL, 0); + } + + if ( result ) { + WLAN_LOG_DEBUG(1, + "copy_to_bap(%04x, %d, %d) failed, result=0x%x\n", + fid, + sizeof(txdesc), + skb->len, + result); + + /* put the fid back in the queue */ + txfid_queue_add(hw, fid); + + result = 3; + goto failed; + } + + /* Issue Tx command */ + result = hfa384x_cmd_transmit(hw, HFA384x_TXCMD_RECL, macq, fid); + + if ( result != 0 ) { + txfid_queue_add(hw, fid); + + WLAN_LOG_DEBUG(1,"cmd_tx(%04x) failed, result=%d\n", + fid, result); + result = 3; + goto failed; + } + + /* indicate we haven't any buffers, int_alloc will clear */ + result = txfid_queue_empty(hw); +failed: + + spin_unlock(&hw->cmdlock); + + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* hfa384x_interrupt +* +* Driver interrupt handler. +* +* Arguments: +* irq irq number +* dev_id pointer to the device +* regs registers +* +* Returns: +* nothing +* +* Side effects: +* May result in a frame being passed up the stack or an info +* frame being handled. +* +* Call context: +* Ummm, could it be interrupt? +----------------------------------------------------------------*/ +irqreturn_t hfa384x_interrupt(int irq, void *dev_id PT_REGS) +{ + int reg; + wlandevice_t *wlandev = (wlandevice_t*)dev_id; + hfa384x_t *hw = wlandev->priv; + int ev_read = 0; + DBFENTER; + + if (!wlandev || wlandev->hwremoved) + return IRQ_NONE; /* Not much we can do w/o hardware */ +#if (WLAN_HOSTIF == WLAN_PCMCIA) + if (hw->iobase == 0) /* XXX FIXME Properly */ + return IRQ_NONE; +#endif + + for (;;ev_read++) { + if (ev_read >= prism2_irq_evread_max) + break; + + /* Check swsupport reg magic # for card presence */ + reg = hfa384x_getreg(hw, HFA384x_SWSUPPORT0); + if ( reg != HFA384x_DRVR_MAGIC) { + WLAN_LOG_DEBUG(2, "irq=%d, no magic. Card removed?.\n", irq); + break; + } + + /* read the EvStat register for interrupt enabled events */ + reg = hfa384x_getreg(hw, HFA384x_EVSTAT); + + /* AND with the enabled interrupts */ + reg &= hfa384x_getreg(hw, HFA384x_INTEN); + + /* Handle the events */ + if ( HFA384x_EVSTAT_ISWTERR(reg) ){ + WLAN_LOG_ERROR( + "Error: WTERR interrupt received (unhandled).\n"); + hfa384x_setreg(hw, HFA384x_EVACK_WTERR_SET(1), + HFA384x_EVACK); + } + + if ( HFA384x_EVSTAT_ISINFDROP(reg) ){ + hfa384x_int_infdrop(wlandev); + hfa384x_setreg(hw, HFA384x_EVACK_INFDROP_SET(1), + HFA384x_EVACK); + } + + if (HFA384x_EVSTAT_ISBAP_OP(reg)) { + /* Disable the BAP interrupts */ + hfa384x_events_nobap(hw); + tasklet_schedule(&hw->bap_tasklet); + } + + if ( HFA384x_EVSTAT_ISALLOC(reg) ){ + hfa384x_int_alloc(wlandev); + hfa384x_setreg(hw, HFA384x_EVACK_ALLOC_SET(1), + HFA384x_EVACK); + } + + if ( HFA384x_EVSTAT_ISDTIM(reg) ){ + hfa384x_int_dtim(wlandev); + hfa384x_setreg(hw, HFA384x_EVACK_DTIM_SET(1), + HFA384x_EVACK); + } +#ifdef CMD_IRQ + if ( HFA384x_EVSTAT_ISCMD(reg) ){ + hfa384x_int_cmd(wlandev); + hfa384x_setreg(hw, HFA384x_EVACK_CMD_SET(1), + HFA384x_EVACK); + } +#endif + + /* allow the evstat to be updated after the evack */ + udelay(20); + } + + DBFEXIT; + return IRQ_HANDLED; +} + +#ifdef CMD_IRQ +/*---------------------------------------------------------------- +* hfa384x_int_cmd +* +* Handles command completion event. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +void hfa384x_int_cmd(wlandevice_t *wlandev) +{ + hfa384x_t *hw = wlandev->priv; + DBFENTER; + + // check to make sure it's the right command? + if (hw->cmddata) { + hw->cmddata->status = hfa384x_getreg(hw, HFA384x_STATUS); + hw->cmddata->resp0 = hfa384x_getreg(hw, HFA384x_RESP0); + hw->cmddata->resp1 = hfa384x_getreg(hw, HFA384x_RESP1); + hw->cmddata->resp2 = hfa384x_getreg(hw, HFA384x_RESP2); + } + hw->cmdflag = 1; + + printk(KERN_INFO "um. int_cmd\n"); + + wake_up_interruptible(&hw->cmdq); + + // XXXX perform a bap copy too? + + DBFEXIT; + return; +} +#endif + +/*---------------------------------------------------------------- +* hfa384x_int_dtim +* +* Handles the DTIM early warning event. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void hfa384x_int_dtim(wlandevice_t *wlandev) +{ +#if 0 + hfa384x_t *hw = wlandev->priv; +#endif + DBFENTER; + prism2sta_ev_dtim(wlandev); + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* hfa384x_int_infdrop +* +* Handles the InfDrop event. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void hfa384x_int_infdrop(wlandevice_t *wlandev) +{ +#if 0 + hfa384x_t *hw = wlandev->priv; +#endif + DBFENTER; + prism2sta_ev_infdrop(wlandev); + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* hfa384x_int_info +* +* Handles the Info event. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* tasklet +----------------------------------------------------------------*/ +static void hfa384x_int_info(wlandevice_t *wlandev) +{ + hfa384x_t *hw = wlandev->priv; + UINT16 reg; + hfa384x_InfFrame_t inf; + int result; + DBFENTER; + /* Retrieve the FID */ + reg = hfa384x_getreg(hw, HFA384x_INFOFID); + + /* Retrieve the length */ + result = hfa384x_copy_from_bap( hw, + HFA384x_BAP_INT, reg, 0, &inf.framelen, sizeof(UINT16)); + if ( result ) { + WLAN_LOG_DEBUG(1, + "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n", + reg, sizeof(inf), result); + goto failed; + } + inf.framelen = hfa384x2host_16(inf.framelen); + + /* Retrieve the rest */ + result = hfa384x_copy_from_bap( hw, + HFA384x_BAP_INT, reg, sizeof(UINT16), + &(inf.infotype), inf.framelen * sizeof(UINT16)); + if ( result ) { + WLAN_LOG_DEBUG(1, + "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n", + reg, sizeof(inf), result); + goto failed; + } + + prism2sta_ev_info(wlandev, &inf); +failed: + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* hfa384x_int_txexc +* +* Handles the TxExc event. A Transmit Exception event indicates +* that the MAC's TX process was unsuccessful - so the packet did +* not get transmitted. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* tasklet +----------------------------------------------------------------*/ +static void hfa384x_int_txexc(wlandevice_t *wlandev) +{ + hfa384x_t *hw = wlandev->priv; + UINT16 status; + UINT16 fid; + int result = 0; + DBFENTER; + /* Collect the status and display */ + fid = hfa384x_getreg(hw, HFA384x_TXCOMPLFID); + result = hfa384x_copy_from_bap(hw, HFA384x_BAP_INT, fid, 0, &status, sizeof(status)); + if ( result ) { + WLAN_LOG_DEBUG(1, + "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n", + fid, sizeof(status), result); + goto failed; + } + status = hfa384x2host_16(status); + prism2sta_ev_txexc(wlandev, status); +failed: + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* hfa384x_int_tx +* +* Handles the Tx event. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* tasklet +----------------------------------------------------------------*/ +static void hfa384x_int_tx(wlandevice_t *wlandev) +{ + hfa384x_t *hw = wlandev->priv; + UINT16 fid; + UINT16 status; + int result = 0; + DBFENTER; + fid = hfa384x_getreg(hw, HFA384x_TXCOMPLFID); + result = hfa384x_copy_from_bap(hw, HFA384x_BAP_INT, fid, 0, &status, sizeof(status)); + if ( result ) { + WLAN_LOG_DEBUG(1, + "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n", + fid, sizeof(status), result); + goto failed; + } + status = hfa384x2host_16(status); + prism2sta_ev_tx(wlandev, status); +failed: + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* hfa384x_int_rx +* +* Handles the Rx event. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* tasklet +----------------------------------------------------------------*/ +static void hfa384x_int_rx(wlandevice_t *wlandev) +{ + hfa384x_t *hw = wlandev->priv; + UINT16 rxfid; + hfa384x_rx_frame_t rxdesc; + int result; + int hdrlen; + UINT16 fc; + p80211_rxmeta_t *rxmeta; + struct sk_buff *skb = NULL; + UINT8 *datap; + + DBFENTER; + + /* Get the FID */ + rxfid = hfa384x_getreg(hw, HFA384x_RXFID); + /* Get the descriptor (including headers) */ + result = hfa384x_copy_from_bap(hw, + HFA384x_BAP_INT, + rxfid, + 0, + &rxdesc, + sizeof(rxdesc)); + if ( result ) { + WLAN_LOG_DEBUG(1, + "copy_from_bap(0x%04x, %d, %d) failed, result=0x%x\n", + rxfid, + 0, + sizeof(rxdesc), + result); + goto done; + } + + /* Byte order convert once up front. */ + rxdesc.status = hfa384x2host_16(rxdesc.status); + rxdesc.time = hfa384x2host_32(rxdesc.time); + + /* drop errors and whatnot in promisc mode */ + if (( wlandev->netdev->flags & IFF_PROMISC ) && + (HFA384x_RXSTATUS_ISFCSERR(rxdesc.status) || + HFA384x_RXSTATUS_ISUNDECR(rxdesc.status))) + goto done; + + /* Now handle frame based on port# */ + switch( HFA384x_RXSTATUS_MACPORT_GET(rxdesc.status) ) + { + case 0: + + fc = ieee2host16(rxdesc.frame_control); + + /* If exclude and we receive an unencrypted, drop it */ + if ( (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED) && + !WLAN_GET_FC_ISWEP(fc)) { + goto done; + } + + hdrlen = p80211_headerlen(fc); + + /* Allocate the buffer, note CRC (aka FCS). pballoc */ + /* assumes there needs to be space for one */ + skb = dev_alloc_skb(hfa384x2host_16(rxdesc.data_len) + hdrlen + WLAN_CRC_LEN + 2); /* a little extra */ + + if ( ! skb ) { + WLAN_LOG_ERROR("alloc_skb failed.\n"); + goto done; + } + + skb->dev = wlandev->netdev; + + /* theoretically align the IP header on a 32-bit word. */ + if ( hdrlen == WLAN_HDR_A4_LEN ) + skb_reserve(skb, 2); + + /* Copy the 802.11 hdr to the buffer */ + datap = skb_put(skb, WLAN_HDR_A3_LEN); + memcpy(datap, &rxdesc.frame_control, WLAN_HDR_A3_LEN); + + /* Snag the A4 address if present */ + if (hdrlen == WLAN_HDR_A4_LEN) { + datap = skb_put(skb, WLAN_ADDR_LEN); + memcpy(datap, &rxdesc.address4, WLAN_HDR_A3_LEN); + } + + /* we can convert the data_len as we passed the original on */ + rxdesc.data_len = hfa384x2host_16(rxdesc.data_len); + + /* Copy the payload data to the buffer */ + if ( rxdesc.data_len > 0 ) { + datap = skb_put(skb, rxdesc.data_len); + result = hfa384x_copy_from_bap(hw, + HFA384x_BAP_INT, rxfid, HFA384x_RX_DATA_OFF, + datap, rxdesc.data_len); + if ( result ) { + WLAN_LOG_DEBUG(1, + "copy_from_bap(0x%04x, %d, %d) failed, result=0x%x\n", + rxfid, + HFA384x_RX_DATA_OFF, + rxdesc.data_len, + result); + goto failed; + } + } + /* the prism2 cards don't return the FCS */ + datap = skb_put(skb, WLAN_CRC_LEN); + memset (datap, 0xff, WLAN_CRC_LEN); + skb_reset_mac_header(skb); + + /* Attach the rxmeta, set some stuff */ + p80211skb_rxmeta_attach(wlandev, skb); + rxmeta = P80211SKB_RXMETA(skb); + rxmeta->mactime = rxdesc.time; + rxmeta->rxrate = rxdesc.rate; + rxmeta->signal = rxdesc.signal - hw->dbmadjust; + rxmeta->noise = rxdesc.silence - hw->dbmadjust; + + prism2sta_ev_rx(wlandev, skb); + goto done; + case 7: + + if ( ! HFA384x_RXSTATUS_ISFCSERR(rxdesc.status) ) { + hfa384x_int_rxmonitor( wlandev, rxfid, &rxdesc); + } else { + WLAN_LOG_DEBUG(3,"Received monitor frame: FCSerr set\n"); + } + goto done; + + default: + + WLAN_LOG_WARNING("Received frame on unsupported port=%d\n", + HFA384x_RXSTATUS_MACPORT_GET(rxdesc.status) ); + goto done; + } + + failed: + dev_kfree_skb(skb); + + done: + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* hfa384x_int_rxmonitor +* +* Helper function for int_rx. Handles monitor frames. +* Note that this function allocates space for the FCS and sets it +* to 0xffffffff. The hfa384x doesn't give us the FCS value but the +* higher layers expect it. 0xffffffff is used as a flag to indicate +* the FCS is bogus. +* +* Arguments: +* wlandev wlan device structure +* rxfid received FID +* rxdesc rx descriptor read from card in int_rx +* +* Returns: +* nothing +* +* Side effects: +* Allocates an skb and passes it up via the PF_PACKET interface. +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void hfa384x_int_rxmonitor( wlandevice_t *wlandev, UINT16 rxfid, + hfa384x_rx_frame_t *rxdesc) +{ + hfa384x_t *hw = wlandev->priv; + UINT hdrlen = 0; + UINT datalen = 0; + UINT skblen = 0; + UINT truncated = 0; + UINT8 *datap; + UINT16 fc; + struct sk_buff *skb; + + DBFENTER; + /* Don't forget the status, time, and data_len fields are in host order */ + /* Figure out how big the frame is */ + fc = ieee2host16(rxdesc->frame_control); + hdrlen = p80211_headerlen(fc); + datalen = hfa384x2host_16(rxdesc->data_len); + + /* Allocate an ind message+framesize skb */ + skblen = sizeof(p80211msg_lnxind_wlansniffrm_t) + + hdrlen + datalen + WLAN_CRC_LEN; + + /* sanity check the length */ + if ( skblen > + (sizeof(p80211msg_lnxind_wlansniffrm_t) + + WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN) ) { + WLAN_LOG_DEBUG(1, "overlen frm: len=%d\n", + skblen - sizeof(p80211msg_lnxind_wlansniffrm_t)); + } + + if ( (skb = dev_alloc_skb(skblen)) == NULL ) { + WLAN_LOG_ERROR("alloc_skb failed trying to allocate %d bytes\n", skblen); + return; + } + + /* only prepend the prism header if in the right mode */ + if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) && + (hw->sniffhdr == 0)) { + p80211msg_lnxind_wlansniffrm_t *msg; + datap = skb_put(skb, sizeof(p80211msg_lnxind_wlansniffrm_t)); + msg = (p80211msg_lnxind_wlansniffrm_t*) datap; + + /* Initialize the message members */ + msg->msgcode = DIDmsg_lnxind_wlansniffrm; + msg->msglen = sizeof(p80211msg_lnxind_wlansniffrm_t); + strcpy(msg->devname, wlandev->name); + + msg->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime; + msg->hosttime.status = 0; + msg->hosttime.len = 4; + msg->hosttime.data = jiffies; + + msg->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime; + msg->mactime.status = 0; + msg->mactime.len = 4; + msg->mactime.data = rxdesc->time * 1000; + + msg->channel.did = DIDmsg_lnxind_wlansniffrm_channel; + msg->channel.status = 0; + msg->channel.len = 4; + msg->channel.data = hw->sniff_channel; + + msg->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi; + msg->rssi.status = P80211ENUM_msgitem_status_no_value; + msg->rssi.len = 4; + msg->rssi.data = 0; + + msg->sq.did = DIDmsg_lnxind_wlansniffrm_sq; + msg->sq.status = P80211ENUM_msgitem_status_no_value; + msg->sq.len = 4; + msg->sq.data = 0; + + msg->signal.did = DIDmsg_lnxind_wlansniffrm_signal; + msg->signal.status = 0; + msg->signal.len = 4; + msg->signal.data = rxdesc->signal; + + msg->noise.did = DIDmsg_lnxind_wlansniffrm_noise; + msg->noise.status = 0; + msg->noise.len = 4; + msg->noise.data = rxdesc->silence; + + msg->rate.did = DIDmsg_lnxind_wlansniffrm_rate; + msg->rate.status = 0; + msg->rate.len = 4; + msg->rate.data = rxdesc->rate / 5; /* set to 802.11 units */ + + msg->istx.did = DIDmsg_lnxind_wlansniffrm_istx; + msg->istx.status = 0; + msg->istx.len = 4; + msg->istx.data = P80211ENUM_truth_false; + + msg->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen; + msg->frmlen.status = 0; + msg->frmlen.len = 4; + msg->frmlen.data = hdrlen + datalen + WLAN_CRC_LEN; + } else if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) && + (hw->sniffhdr != 0)) { + p80211_caphdr_t *caphdr; + /* The NEW header format! */ + datap = skb_put(skb, sizeof(p80211_caphdr_t)); + caphdr = (p80211_caphdr_t*) datap; + + caphdr->version = htonl(P80211CAPTURE_VERSION); + caphdr->length = htonl(sizeof(p80211_caphdr_t)); + caphdr->mactime = __cpu_to_be64(rxdesc->time); + caphdr->hosttime = __cpu_to_be64(jiffies); + caphdr->phytype = htonl(4); /* dss_dot11_b */ + caphdr->channel = htonl(hw->sniff_channel); + caphdr->datarate = htonl(rxdesc->rate); + caphdr->antenna = htonl(0); /* unknown */ + caphdr->priority = htonl(0); /* unknown */ + caphdr->ssi_type = htonl(3); /* rssi_raw */ + caphdr->ssi_signal = htonl(rxdesc->signal); + caphdr->ssi_noise = htonl(rxdesc->silence); + caphdr->preamble = htonl(0); /* unknown */ + caphdr->encoding = htonl(1); /* cck */ + } + /* Copy the 802.11 header to the skb (ctl frames may be less than a full header) */ + datap = skb_put(skb, hdrlen); + memcpy( datap, &(rxdesc->frame_control), hdrlen); + + /* If any, copy the data from the card to the skb */ + if ( datalen > 0 ) + { + /* Truncate the packet if the user wants us to */ + UINT dataread = datalen; + if(hw->sniff_truncate > 0 && dataread > hw->sniff_truncate) { + dataread = hw->sniff_truncate; + truncated = 1; + } + + datap = skb_put(skb, dataread); + hfa384x_copy_from_bap(hw, + HFA384x_BAP_INT, rxfid, HFA384x_RX_DATA_OFF, + datap, dataread); + + /* check for unencrypted stuff if WEP bit set. */ + if (*(datap - hdrlen + 1) & 0x40) // wep set + if ((*(datap) == 0xaa) && (*(datap+1) == 0xaa)) + *(datap - hdrlen + 1) &= 0xbf; // clear wep; it's the 802.2 header! + } + + if (!truncated && hw->sniff_fcs) { + /* Set the FCS */ + datap = skb_put(skb, WLAN_CRC_LEN); + memset( datap, 0xff, WLAN_CRC_LEN); + } + + /* pass it back up */ + prism2sta_ev_rx(wlandev, skb); + + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* hfa384x_int_alloc +* +* Handles the Alloc event. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void hfa384x_int_alloc(wlandevice_t *wlandev) +{ + hfa384x_t *hw = wlandev->priv; + UINT16 fid; + INT16 result; + + DBFENTER; + + /* Handle the reclaimed FID */ + /* collect the FID and push it onto the stack */ + fid = hfa384x_getreg(hw, HFA384x_ALLOCFID); + + if ( fid != hw->infofid ) { /* It's a transmit fid */ + WLAN_LOG_DEBUG(5, "int_alloc(%#x)\n", fid); + result = txfid_queue_add(hw, fid); + if (result != -1) { + prism2sta_ev_alloc(wlandev); + WLAN_LOG_DEBUG(5, "q_add.\n"); + } else { + WLAN_LOG_DEBUG(5, "q_full.\n"); + } + } else { + /* unlock the info fid */ + up(&hw->infofid_sem); + } + + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_handover +* +* Sends a handover notification to the MAC. +* +* Arguments: +* hw device structure +* addr address of station that's left +* +* Returns: +* zero success. +* -ERESTARTSYS received signal while waiting for semaphore. +* -EIO failed to write to bap, or failed in cmd. +* +* Side effects: +* +* Call context: +* process thread, NOTE: this call may block on a semaphore! +----------------------------------------------------------------*/ +int hfa384x_drvr_handover( hfa384x_t *hw, UINT8 *addr) +{ + int result = 0; + hfa384x_HandoverAddr_t rec; + UINT len; + DBFENTER; + + /* Acquire the infofid */ + if ( down_interruptible(&hw->infofid_sem) ) { + result = -ERESTARTSYS; + goto failed; + } + + /* Set up the record */ + len = sizeof(hfa384x_HandoverAddr_t); + rec.framelen = host2hfa384x_16(len/2 - 1); + rec.infotype = host2hfa384x_16(HFA384x_IT_HANDOVERADDR); + memcpy(rec.handover_addr, addr, sizeof(rec.handover_addr)); + + /* Issue the command */ + result = hfa384x_cmd_notify(hw, 1, hw->infofid, &rec, len); + + if ( result != 0 ) { + WLAN_LOG_DEBUG(1,"cmd_notify(%04x) failed, result=%d", + hw->infofid, result); + result = -EIO; + goto failed; + } + +failed: + DBFEXIT; + return result; +} + +void hfa384x_tx_timeout(wlandevice_t *wlandev) +{ + DBFENTER; + + WLAN_LOG_WARNING("Implement me.\n"); + + DBFEXIT; +} + +/* Handles all "rx" BAP operations */ +static void hfa384x_bap_tasklet(unsigned long data) +{ + hfa384x_t *hw = (hfa384x_t *) data; + wlandevice_t *wlandev = hw->wlandev; + int counter = prism2_irq_evread_max; + int reg; + + DBFENTER; + + while (counter-- > 0) { + /* Get interrupt register */ + reg = hfa384x_getreg(hw, HFA384x_EVSTAT); + + if ((reg == 0xffff) || + !(reg & HFA384x_INT_BAP_OP)) { + break; + } + + if ( HFA384x_EVSTAT_ISINFO(reg) ){ + hfa384x_int_info(wlandev); + hfa384x_setreg(hw, HFA384x_EVACK_INFO_SET(1), + HFA384x_EVACK); + } + if ( HFA384x_EVSTAT_ISTXEXC(reg) ){ + hfa384x_int_txexc(wlandev); + hfa384x_setreg(hw, HFA384x_EVACK_TXEXC_SET(1), + HFA384x_EVACK); + } + if ( HFA384x_EVSTAT_ISTX(reg) ){ + hfa384x_int_tx(wlandev); + hfa384x_setreg(hw, HFA384x_EVACK_TX_SET(1), + HFA384x_EVACK); + } + if ( HFA384x_EVSTAT_ISRX(reg) ){ + hfa384x_int_rx(wlandev); + hfa384x_setreg(hw, HFA384x_EVACK_RX_SET(1), + HFA384x_EVACK); + } + } + + /* re-enable interrupts */ + hfa384x_events_all(hw); + + DBFEXIT; +} --- linux-2.6.28.orig/ubuntu/misc/wireless/prism2_usb/prism2_usb.c +++ linux-2.6.28/ubuntu/misc/wireless/prism2_usb/prism2_usb.c @@ -0,0 +1,367 @@ +#define WLAN_HOSTIF WLAN_USB +#include "hfa384x_usb.c" +#include "prism2mgmt.c" +#include "prism2mib.c" +#include "prism2sta.c" + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) +#error "prism2_usb requires at least a 2.4.x kernel!" +#endif + +#define PRISM_USB_DEVICE(vid, pid, name) \ + USB_DEVICE(vid, pid), \ + .driver_info = (unsigned long) name + +static struct usb_device_id usb_prism_tbl[] = { + {PRISM_USB_DEVICE(0x0707, 0xee04, "Intersil Americas USB 802.11b WLAN DEVICE")}, + {PRISM_USB_DEVICE(0x04bb, 0x0922, "IOData AirPort WN-B11/USBS")}, + {PRISM_USB_DEVICE(0x07aa, 0x0012, "Corega Wireless LAN USB Stick-11")}, + {PRISM_USB_DEVICE(0x09aa, 0x3642, "Prism2.x 11Mbps WLAN USB Adapter")}, + {PRISM_USB_DEVICE(0x1668, 0x0408, "Actiontec Prism2.5 11Mbps WLAN USB Adapter")}, + {PRISM_USB_DEVICE(0x1668, 0x0421, "Actiontec Prism2.5 11Mbps WLAN USB Adapter")}, + {PRISM_USB_DEVICE(0x1915, 0x2236, "Linksys WUSB11v3.0 11Mbps WLAN USB Adapter")}, + {PRISM_USB_DEVICE(0x066b, 0x2212, "Linksys WUSB11v2.5 11Mbps WLAN USB Adapter")}, + {PRISM_USB_DEVICE(0x066b, 0x2213, "Linksys WUSB12v1.1 11Mbps WLAN USB Adapter")}, + {PRISM_USB_DEVICE(0x067c, 0x1022, "Siemens SpeedStream 1022 11Mbps WLAN USB Adapter")}, + {PRISM_USB_DEVICE(0x049f, 0x0033, "Compaq/Intel W100 PRO/Wireless 11Mbps multiport WLAN Adapter")}, + {PRISM_USB_DEVICE(0x0411, 0x0016, "Melco WLI-USB-S11 11Mbps WLAN Adapter")}, + {PRISM_USB_DEVICE(0x08de, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter")}, + {PRISM_USB_DEVICE(0x8086, 0x1111, "Intel PRO/Wireless 2011B LAN USB Adapter")}, + {PRISM_USB_DEVICE(0x0d8e, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter")}, + {PRISM_USB_DEVICE(0x045e, 0x006e, "Microsoft MN510 Wireless USB Adapter")}, + {PRISM_USB_DEVICE(0x0967, 0x0204, "Acer Warplink USB Adapter")}, + {PRISM_USB_DEVICE(0x0cde, 0x0002, "Z-Com 725/726 Prism2.5 USB/USB Integrated")}, + {PRISM_USB_DEVICE(0x0cde, 0x0005, "Z-Com Xl735 Wireless 802.11b USB Adapter")}, + {PRISM_USB_DEVICE(0x413c, 0x8100, "Dell TrueMobile 1180 Wireless USB Adapter")}, + {PRISM_USB_DEVICE(0x0b3b, 0x1601, "ALLNET 0193 11Mbps WLAN USB Adapter")}, + {PRISM_USB_DEVICE(0x0b3b, 0x1602, "ZyXEL ZyAIR B200 Wireless USB Adapter")}, + {PRISM_USB_DEVICE(0x0baf, 0x00eb, "USRobotics USR1120 Wireless USB Adapter")}, + {PRISM_USB_DEVICE(0x0411, 0x0027, "Melco WLI-USB-KS11G 11Mbps WLAN Adapter")}, + {PRISM_USB_DEVICE(0x04f1, 0x3009, "JVC MP-XP7250 Builtin USB WLAN Adapter")}, + {PRISM_USB_DEVICE(0x0846, 0x4110, "NetGear MA111")}, + {PRISM_USB_DEVICE(0x03f3, 0x0020, "Adaptec AWN-8020 USB WLAN Adapter")}, +// {PRISM_USB_DEVICE(0x0ace, 0x1201, "ZyDAS ZD1201 Wireless USB Adapter")}, + {PRISM_USB_DEVICE(0x2821, 0x3300, "ASUS-WL140 Wireless USB Adapter")}, + {PRISM_USB_DEVICE(0x2001, 0x3700, "DWL-122 Wireless USB Adapter")}, + {PRISM_USB_DEVICE(0x2001, 0x3702, "DWL-120 Rev F Wireless USB Adapter")}, + {PRISM_USB_DEVICE(0x50c2, 0x4013, "Averatec USB WLAN Adapter")}, + {PRISM_USB_DEVICE(0x2c02, 0x14ea, "Planex GW-US11H WLAN USB Adapter")}, + {PRISM_USB_DEVICE(0x124a, 0x168b, "Airvast PRISM3 WLAN USB Adapter")}, + {PRISM_USB_DEVICE(0x083a, 0x3503, "T-Sinus 111 USB WLAN Adapter")}, + {PRISM_USB_DEVICE(0x2821, 0x3300, "Hawking HighDB USB Adapter")}, + {PRISM_USB_DEVICE(0x0411, 0x0044, "Melco WLI-USB-KB11 11Mbps WLAN Adapter")}, + {PRISM_USB_DEVICE(0x1668, 0x6106, "ROPEX FreeLan 802.11b USB Adapter")}, + {PRISM_USB_DEVICE(0x124a, 0x4017, "Pheenet WL-503IA 802.11b USB Adapter")}, + {PRISM_USB_DEVICE(0x0bb2, 0x0302, "Ambit Microsystems Corp.")}, + {PRISM_USB_DEVICE(0x9016, 0x182d, "Sitecom WL-022 802.11b USB Adapter")}, + {PRISM_USB_DEVICE(0x0543, 0x0f01, "ViewSonic Airsync USB Adapter 11Mbps (Prism2.5)")}, + { /* terminator */ } +}; + +MODULE_DEVICE_TABLE(usb, usb_prism_tbl); + +/*---------------------------------------------------------------- +* prism2sta_probe_usb +* +* Probe routine called by the USB subsystem. +* +* Arguments: +* dev ptr to the usb_device struct +* ifnum interface number being offered +* +* Returns: +* NULL - we're not claiming the device+interface +* non-NULL - we are claiming the device+interface and +* this is a ptr to the data we want back +* when disconnect is called. +* +* Side effects: +* +* Call context: +* I'm not sure, assume it's interrupt. +* +----------------------------------------------------------------*/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +static void __devinit *prism2sta_probe_usb( + struct usb_device *dev, + unsigned int ifnum, + const struct usb_device_id *id) +#else +static int prism2sta_probe_usb( + struct usb_interface *interface, + const struct usb_device_id *id) +#endif +{ + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + struct usb_interface *interface; +#else + struct usb_device *dev; +#endif + + wlandevice_t *wlandev = NULL; + hfa384x_t *hw = NULL; + int result = 0; + + DBFENTER; + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + interface = &dev->actconfig->interface[ifnum]; +#else + dev = interface_to_usbdev(interface); +#endif + + + if ((wlandev = create_wlan()) == NULL) { + WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info); + result = -EIO; + goto failed; + } + hw = wlandev->priv; + + if ( wlan_setup(wlandev) != 0 ) { + WLAN_LOG_ERROR("%s: wlan_setup() failed.\n", dev_info); + result = -EIO; + goto failed; + } + + /* Initialize the hw data */ + hfa384x_create(hw, dev); + hw->wlandev = wlandev; + + SET_MODULE_OWNER(wlandev->netdev); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) + SET_NETDEV_DEV(wlandev->netdev, &(interface->dev)); +#endif + + /* Do a chip-level reset on the MAC */ + if (prism2_doreset) { + result = hfa384x_corereset(hw, + prism2_reset_holdtime, + prism2_reset_settletime, 0); + if (result != 0) { + hfa384x_destroy(hw); + result = -EIO; + WLAN_LOG_ERROR( + "%s: hfa384x_corereset() failed.\n", + dev_info); + goto failed; + } + } + +#ifndef NEW_MODULE_CODE + usb_inc_dev_use(dev); +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) + usb_get_dev(dev); +#endif + + wlandev->msdstate = WLAN_MSD_HWPRESENT; + + /* Register the wlandev, this gets us a name and registers the + * linux netdevice. + */ + if ( register_wlandev(wlandev) != 0 ) { + WLAN_LOG_ERROR("%s: register_wlandev() failed.\n", dev_info); + result = -EIO; + goto failed; + } + + if (wlan_wext_write) + prism2sta_ifstate(wlandev, P80211ENUM_ifstate_enable); + + goto done; + + failed: + if (wlandev) kfree(wlandev); + if (hw) kfree(hw); + wlandev = NULL; + + done: + DBFEXIT; + + p80211_allow_ioctls(wlandev); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + return wlandev; +#else + usb_set_intfdata(interface, wlandev); + return result; +#endif +} + + +/*---------------------------------------------------------------- +* prism2sta_disconnect_usb +* +* Called when a device previously claimed by probe is removed +* from the USB. +* +* Arguments: +* dev ptr to the usb_device struct +* ptr ptr returned by probe() when the device +* was claimed. +* +* Returns: +* Nothing +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +static void __devexit +prism2sta_disconnect_usb(struct usb_device *dev, void *ptr) +#else +static void +prism2sta_disconnect_usb(struct usb_interface *interface) +#endif +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + wlandevice_t *wlandev; +#else + wlandevice_t *wlandev = (wlandevice_t*)ptr; +#endif + + DBFENTER; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + wlandev = (wlandevice_t *) usb_get_intfdata(interface); +#endif + + if ( wlandev != NULL ) { + LIST_HEAD(cleanlist); + struct list_head *entry; + struct list_head *temp; + unsigned long flags; + + hfa384x_t *hw = wlandev->priv; + + if (!hw) + goto exit; + + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + p80211netdev_hwremoved(wlandev); + list_splice_init(&hw->ctlxq.reapable, &cleanlist); + list_splice_init(&hw->ctlxq.completing, &cleanlist); + list_splice_init(&hw->ctlxq.pending, &cleanlist); + list_splice_init(&hw->ctlxq.active, &cleanlist); + + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + + /* There's no hardware to shutdown, but the driver + * might have some tasks or tasklets that must be + * stopped before we can tear everything down. + */ + prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable); + + del_singleshot_timer_sync(&hw->throttle); + del_singleshot_timer_sync(&hw->reqtimer); + del_singleshot_timer_sync(&hw->resptimer); + + /* Unlink all the URBs. This "removes the wheels" + * from the entire CTLX handling mechanism. + */ + usb_kill_urb(&hw->rx_urb); + usb_kill_urb(&hw->tx_urb); + usb_kill_urb(&hw->ctlx_urb); + + tasklet_kill(&hw->completion_bh); + tasklet_kill(&hw->reaper_bh); + + flush_scheduled_work(); + + /* Now we complete any outstanding commands + * and tell everyone who is waiting for their + * responses that we have shut down. + */ + list_for_each(entry, &cleanlist) { + hfa384x_usbctlx_t *ctlx; + + ctlx = list_entry(entry, hfa384x_usbctlx_t, list); + complete(&ctlx->done); + } + + /* Give any outstanding synchronous commands + * a chance to complete. All they need to do + * is "wake up", so that's easy. + * (I'd like a better way to do this, really.) + */ + msleep(100); + + /* Now delete the CTLXs, because no-one else can now. */ + list_for_each_safe(entry, temp, &cleanlist) { + hfa384x_usbctlx_t *ctlx; + + ctlx = list_entry(entry, hfa384x_usbctlx_t, list); + kfree(ctlx); + } + + /* Unhook the wlandev */ + unregister_wlandev(wlandev); + wlan_unsetup(wlandev); + +#ifndef NEW_MODULE_CODE + usb_dec_dev_use(hw->usb); +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) + usb_put_dev(hw->usb); +#endif + + hfa384x_destroy(hw); + kfree(hw); + + kfree(wlandev); + } + + exit: + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + usb_set_intfdata(interface, NULL); +#endif + DBFEXIT; +} + + +static struct usb_driver prism2_usb_driver = { +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,19)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)) + .owner = THIS_MODULE, +#endif + .name = "prism2_usb", + .probe = prism2sta_probe_usb, + .disconnect = prism2sta_disconnect_usb, + .id_table = usb_prism_tbl, + /* fops, minor? */ +}; + +#ifdef MODULE + +static int __init prism2usb_init(void) +{ + DBFENTER; + + WLAN_LOG_NOTICE("%s Loaded\n", version); + WLAN_LOG_NOTICE("dev_info is: %s\n", dev_info); + + /* This call will result in calls to prism2sta_probe_usb. */ + return usb_register(&prism2_usb_driver); + + DBFEXIT; +}; + +static void __exit prism2usb_cleanup(void) +{ + DBFENTER; + + usb_deregister(&prism2_usb_driver); + + printk(KERN_NOTICE "%s Unloaded\n", version); + + DBFEXIT; +}; + +module_init(prism2usb_init); +module_exit(prism2usb_cleanup); + +#endif // module --- linux-2.6.28.orig/ubuntu/misc/wireless/prism2_usb/Makefile +++ linux-2.6.28/ubuntu/misc/wireless/prism2_usb/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_PRISM2_USB) += prism2_usb.o + +EXTRA_CFLAGS += -I$(src)/../p80211 -I$(src) --- linux-2.6.28.orig/ubuntu/misc/wireless/prism2_usb/prism2sta.c +++ linux-2.6.28/ubuntu/misc/wireless/prism2_usb/prism2sta.c @@ -0,0 +1,2502 @@ +/* src/prism2/driver/prism2sta.c +* +* Implements the station functionality for prism2 +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file implements the module and linux pcmcia routines for the +* prism2 driver. +* +* -------------------------------------------------------------------- +*/ + +/*================================================================*/ +/* System Includes */ +#define WLAN_DBVAR prism2_debug + +#include + + +#include + +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,25)) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +#include +#else +#include +#endif + +#include +#include +#include +#include + +#if (WLAN_HOSTIF == WLAN_PCMCIA) +#include +#include +#include +#include +#include +#include +#endif + +#include + +#if ((WLAN_HOSTIF == WLAN_PLX) || (WLAN_HOSTIF == WLAN_PCI)) +#include +#include +#endif + +/*================================================================*/ +/* Project Includes */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*================================================================*/ +/* Local Constants */ + +/*================================================================*/ +/* Local Macros */ + +/*================================================================*/ +/* Local Types */ + +/*================================================================*/ +/* Local Static Definitions */ + +#if (WLAN_HOSTIF == WLAN_PCMCIA) +#define DRIVER_SUFFIX "_cs" +#elif (WLAN_HOSTIF == WLAN_PLX) +#define DRIVER_SUFFIX "_plx" +typedef char* dev_info_t; +#elif (WLAN_HOSTIF == WLAN_PCI) +#define DRIVER_SUFFIX "_pci" +typedef char* dev_info_t; +#elif (WLAN_HOSTIF == WLAN_USB) +#define DRIVER_SUFFIX "_usb" +typedef char* dev_info_t; +#else +#error "HOSTIF unsupported or undefined!" +#endif + +static char *version = "prism2" DRIVER_SUFFIX ".o: " WLAN_RELEASE; +static dev_info_t dev_info = "prism2" DRIVER_SUFFIX; + +#if (WLAN_HOSTIF == WLAN_PLX || WLAN_HOSTIF == WLAN_PCI) +#ifdef CONFIG_PM +static int prism2sta_suspend_pci(struct pci_dev *pdev, pm_message_t state); +static int prism2sta_resume_pci(struct pci_dev *pdev); +#endif +#endif + +#if (WLAN_HOSTIF == WLAN_PCI) + +#endif /* WLAN_PCI */ + +static wlandevice_t *create_wlan(void); + +/*----------------------------------------------------------------*/ +/* --Module Parameters */ + +int prism2_reset_holdtime=30; /* Reset hold time in ms */ +int prism2_reset_settletime=100; /* Reset settle time in ms */ + +#if (WLAN_HOSTIF == WLAN_USB) +static int prism2_doreset=0; /* Do a reset at init? */ +#else +static int prism2_doreset=1; /* Do a reset at init? */ +int prism2_bap_timeout=1000; /* BAP timeout */ +int prism2_irq_evread_max=20; /* Maximum number of + * ev_reads (loops) + * in irq handler + */ +#endif + +#ifdef WLAN_INCLUDE_DEBUG +int prism2_debug=0; +module_param( prism2_debug, int, 0644); +MODULE_PARM_DESC(prism2_debug, "prism2 debugging"); +#endif + +module_param( prism2_doreset, int, 0644); +MODULE_PARM_DESC(prism2_doreset, "Issue a reset on initialization"); + +module_param( prism2_reset_holdtime, int, 0644); +MODULE_PARM_DESC( prism2_reset_holdtime, "reset hold time in ms"); +module_param( prism2_reset_settletime, int, 0644); +MODULE_PARM_DESC( prism2_reset_settletime, "reset settle time in ms"); + +#if (WLAN_HOSTIF != WLAN_USB) +module_param( prism2_bap_timeout, int, 0644); +MODULE_PARM_DESC(prism2_bap_timeout, "BufferAccessPath Timeout in 10*n us"); +module_param( prism2_irq_evread_max, int, 0644); +MODULE_PARM_DESC( prism2_irq_evread_max, "Maximim number of event reads in interrupt handler"); +#endif + +MODULE_LICENSE("Dual MPL/GPL"); + +/*================================================================*/ +/* Local Function Declarations */ + +static int prism2sta_open(wlandevice_t *wlandev); +static int prism2sta_close(wlandevice_t *wlandev); +static void prism2sta_reset(wlandevice_t *wlandev ); +static int prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep); +static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg); +static int prism2sta_getcardinfo(wlandevice_t *wlandev); +static int prism2sta_globalsetup(wlandevice_t *wlandev); +static int prism2sta_setmulticast(wlandevice_t *wlandev, + netdevice_t *dev); + +static void prism2sta_inf_handover( + wlandevice_t *wlandev, hfa384x_InfFrame_t *inf); +static void prism2sta_inf_tallies( + wlandevice_t *wlandev, hfa384x_InfFrame_t *inf); +static void prism2sta_inf_hostscanresults( + wlandevice_t *wlandev, hfa384x_InfFrame_t *inf); +static void prism2sta_inf_scanresults( + wlandevice_t *wlandev, hfa384x_InfFrame_t *inf); +static void prism2sta_inf_chinforesults( + wlandevice_t *wlandev, hfa384x_InfFrame_t *inf); +static void prism2sta_inf_linkstatus( + wlandevice_t *wlandev, hfa384x_InfFrame_t *inf); +static void prism2sta_inf_assocstatus( + wlandevice_t *wlandev, hfa384x_InfFrame_t *inf); +static void prism2sta_inf_authreq( + wlandevice_t *wlandev, hfa384x_InfFrame_t *inf); +static void prism2sta_inf_authreq_defer( + wlandevice_t *wlandev, hfa384x_InfFrame_t *inf); +static void prism2sta_inf_psusercnt( + wlandevice_t *wlandev, hfa384x_InfFrame_t *inf); + +#ifdef CONFIG_PROC_FS +static int +prism2sta_proc_read( + char *page, + char **start, + off_t offset, + int count, + int *eof, + void *data); +#endif + +/*================================================================*/ +/* Function Definitions */ + +/*---------------------------------------------------------------- +* dmpmem +* +* Debug utility function to dump memory to the kernel debug log. +* +* Arguments: +* buf ptr data we want dumped +* len length of data +* +* Returns: +* nothing +* Side effects: +* +* Call context: +* process thread +* interrupt +----------------------------------------------------------------*/ +inline void dmpmem(void *buf, int n) +{ + int c; + for ( c= 0; c < n; c++) { + if ( (c % 16) == 0 ) printk(KERN_DEBUG"dmp[%d]: ", c); + printk("%02x ", ((UINT8*)buf)[c]); + if ( (c % 16) == 15 ) printk("\n"); + } + if ( (c % 16) != 0 ) printk("\n"); +} + + +/*---------------------------------------------------------------- +* prism2sta_open +* +* WLAN device open method. Called from p80211netdev when kernel +* device open (start) method is called in response to the +* SIOCSIIFFLAGS ioctl changing the flags bit IFF_UP +* from clear to set. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* 0 success +* >0 f/w reported error +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +static int prism2sta_open(wlandevice_t *wlandev) +{ + DBFENTER; + +#ifdef ANCIENT_MODULE_CODE + MOD_INC_USE_COUNT; +#endif + + /* We don't currently have to do anything else. + * The setup of the MAC should be subsequently completed via + * the mlme commands. + * Higher layers know we're ready from dev->start==1 and + * dev->tbusy==0. Our rx path knows to pass up received/ + * frames because of dev->flags&IFF_UP is true. + */ + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* prism2sta_close +* +* WLAN device close method. Called from p80211netdev when kernel +* device close method is called in response to the +* SIOCSIIFFLAGS ioctl changing the flags bit IFF_UP +* from set to clear. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* 0 success +* >0 f/w reported error +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +static int prism2sta_close(wlandevice_t *wlandev) +{ + DBFENTER; + +#ifdef ANCIENT_MODULE_CODE + MOD_DEC_USE_COUNT; +#endif + + /* We don't currently have to do anything else. + * Higher layers know we're not ready from dev->start==0 and + * dev->tbusy==1. Our rx path knows to not pass up received + * frames because of dev->flags&IFF_UP is false. + */ + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* prism2sta_reset +* +* Not currently implented. +* +* Arguments: +* wlandev wlan device structure +* none +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +static void prism2sta_reset(wlandevice_t *wlandev ) +{ + DBFENTER; + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* prism2sta_txframe +* +* Takes a frame from p80211 and queues it for transmission. +* +* Arguments: +* wlandev wlan device structure +* pb packet buffer struct. Contains an 802.11 +* data frame. +* p80211_hdr points to the 802.11 header for the packet. +* Returns: +* 0 Success and more buffs available +* 1 Success but no more buffs +* 2 Allocation failure +* 4 Buffer full or queue busy +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +static int prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb, + p80211_hdr_t *p80211_hdr, + p80211_metawep_t *p80211_wep) +{ + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + int result; + DBFENTER; + + /* If necessary, set the 802.11 WEP bit */ + if ((wlandev->hostwep & (HOSTWEP_PRIVACYINVOKED | HOSTWEP_ENCRYPT)) == HOSTWEP_PRIVACYINVOKED) { + p80211_hdr->a3.fc |= host2ieee16(WLAN_SET_FC_ISWEP(1)); + } + + result = hfa384x_drvr_txframe(hw, skb, p80211_hdr, p80211_wep); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2sta_mlmerequest +* +* wlan command message handler. All we do here is pass the message +* over to the prism2sta_mgmt_handler. +* +* Arguments: +* wlandev wlan device structure +* msg wlan command message +* Returns: +* 0 success +* <0 successful acceptance of message, but we're +* waiting for an async process to finish before +* we're done with the msg. When the asynch +* process is done, we'll call the p80211 +* function p80211req_confirm() . +* >0 An error occurred while we were handling +* the message. +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg) +{ + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + + int result = 0; + DBFENTER; + + switch( msg->msgcode ) + { + case DIDmsg_dot11req_mibget : + WLAN_LOG_DEBUG(2,"Received mibget request\n"); + result = prism2mgmt_mibset_mibget(wlandev, msg); + break; + case DIDmsg_dot11req_mibset : + WLAN_LOG_DEBUG(2,"Received mibset request\n"); + result = prism2mgmt_mibset_mibget(wlandev, msg); + break; + case DIDmsg_dot11req_powermgmt : + WLAN_LOG_DEBUG(2,"Received powermgmt request\n"); + result = prism2mgmt_powermgmt(wlandev, msg); + break; + case DIDmsg_dot11req_scan : + WLAN_LOG_DEBUG(2,"Received scan request\n"); + result = prism2mgmt_scan(wlandev, msg); + break; + case DIDmsg_dot11req_scan_results : + WLAN_LOG_DEBUG(2,"Received scan_results request\n"); + result = prism2mgmt_scan_results(wlandev, msg); + break; + case DIDmsg_dot11req_join : + WLAN_LOG_DEBUG(2,"Received join request\n"); + result = prism2mgmt_join(wlandev, msg); + break; + case DIDmsg_dot11req_authenticate : + WLAN_LOG_DEBUG(2,"Received authenticate request\n"); + result = prism2mgmt_authenticate(wlandev, msg); + break; + case DIDmsg_dot11req_deauthenticate : + WLAN_LOG_DEBUG(2,"Received mlme deauthenticate request\n"); + result = prism2mgmt_deauthenticate(wlandev, msg); + break; + case DIDmsg_dot11req_associate : + WLAN_LOG_DEBUG(2,"Received mlme associate request\n"); + result = prism2mgmt_associate(wlandev, msg); + break; + case DIDmsg_dot11req_reassociate : + WLAN_LOG_DEBUG(2,"Received mlme reassociate request\n"); + result = prism2mgmt_reassociate(wlandev, msg); + break; + case DIDmsg_dot11req_disassociate : + WLAN_LOG_DEBUG(2,"Received mlme disassociate request\n"); + result = prism2mgmt_disassociate(wlandev, msg); + break; + case DIDmsg_dot11req_reset : + WLAN_LOG_DEBUG(2,"Received mlme reset request\n"); + result = prism2mgmt_reset(wlandev, msg); + break; + case DIDmsg_dot11req_start : + WLAN_LOG_DEBUG(2,"Received mlme start request\n"); + result = prism2mgmt_start(wlandev, msg); + break; + /* + * Prism2 specific messages + */ + case DIDmsg_p2req_join : + WLAN_LOG_DEBUG(2,"Received p2 join request\n"); + result = prism2mgmt_p2_join(wlandev, msg); + break; + case DIDmsg_p2req_readpda : + WLAN_LOG_DEBUG(2,"Received mlme readpda request\n"); + result = prism2mgmt_readpda(wlandev, msg); + break; + case DIDmsg_p2req_readcis : + WLAN_LOG_DEBUG(2,"Received mlme readcis request\n"); + result = prism2mgmt_readcis(wlandev, msg); + break; + case DIDmsg_p2req_auxport_state : + WLAN_LOG_DEBUG(2,"Received mlme auxport_state request\n"); + result = prism2mgmt_auxport_state(wlandev, msg); + break; + case DIDmsg_p2req_auxport_read : + WLAN_LOG_DEBUG(2,"Received mlme auxport_read request\n"); + result = prism2mgmt_auxport_read(wlandev, msg); + break; + case DIDmsg_p2req_auxport_write : + WLAN_LOG_DEBUG(2,"Received mlme auxport_write request\n"); + result = prism2mgmt_auxport_write(wlandev, msg); + break; + case DIDmsg_p2req_low_level : + WLAN_LOG_DEBUG(2,"Received mlme low_level request\n"); + result = prism2mgmt_low_level(wlandev, msg); + break; + case DIDmsg_p2req_test_command : + WLAN_LOG_DEBUG(2,"Received mlme test_command request\n"); + result = prism2mgmt_test_command(wlandev, msg); + break; + case DIDmsg_p2req_mmi_read : + WLAN_LOG_DEBUG(2,"Received mlme mmi_read request\n"); + result = prism2mgmt_mmi_read(wlandev, msg); + break; + case DIDmsg_p2req_mmi_write : + WLAN_LOG_DEBUG(2,"Received mlme mmi_write request\n"); + result = prism2mgmt_mmi_write(wlandev, msg); + break; + case DIDmsg_p2req_ramdl_state : + WLAN_LOG_DEBUG(2,"Received mlme ramdl_state request\n"); + result = prism2mgmt_ramdl_state(wlandev, msg); + break; + case DIDmsg_p2req_ramdl_write : + WLAN_LOG_DEBUG(2,"Received mlme ramdl_write request\n"); + result = prism2mgmt_ramdl_write(wlandev, msg); + break; + case DIDmsg_p2req_flashdl_state : + WLAN_LOG_DEBUG(2,"Received mlme flashdl_state request\n"); + result = prism2mgmt_flashdl_state(wlandev, msg); + break; + case DIDmsg_p2req_flashdl_write : + WLAN_LOG_DEBUG(2,"Received mlme flashdl_write request\n"); + result = prism2mgmt_flashdl_write(wlandev, msg); + break; + case DIDmsg_p2req_dump_state : + WLAN_LOG_DEBUG(2,"Received mlme dump_state request\n"); + result = prism2mgmt_dump_state(wlandev, msg); + break; + case DIDmsg_p2req_channel_info : + WLAN_LOG_DEBUG(2,"Received mlme channel_info request\n"); + result = prism2mgmt_channel_info(wlandev, msg); + break; + case DIDmsg_p2req_channel_info_results : + WLAN_LOG_DEBUG(2,"Received mlme channel_info_results request\n"); + result = prism2mgmt_channel_info_results(wlandev, msg); + break; + /* + * Linux specific messages + */ + case DIDmsg_lnxreq_hostwep : + break; // ignore me. + case DIDmsg_lnxreq_ifstate : + { + p80211msg_lnxreq_ifstate_t *ifstatemsg; + WLAN_LOG_DEBUG(2,"Received mlme ifstate request\n"); + ifstatemsg = (p80211msg_lnxreq_ifstate_t*)msg; + result = prism2sta_ifstate(wlandev, ifstatemsg->ifstate.data); + ifstatemsg->resultcode.status = + P80211ENUM_msgitem_status_data_ok; + ifstatemsg->resultcode.data = result; + result = 0; + } + break; + case DIDmsg_lnxreq_wlansniff : + WLAN_LOG_DEBUG(2,"Received mlme wlansniff request\n"); + result = prism2mgmt_wlansniff(wlandev, msg); + break; + case DIDmsg_lnxreq_autojoin : + WLAN_LOG_DEBUG(2,"Received mlme autojoin request\n"); + result = prism2mgmt_autojoin(wlandev, msg); + break; + case DIDmsg_p2req_enable : + WLAN_LOG_DEBUG(2,"Received mlme enable request\n"); + result = prism2mgmt_enable(wlandev, msg); + break; + case DIDmsg_lnxreq_commsquality: { + p80211msg_lnxreq_commsquality_t *qualmsg; + + WLAN_LOG_DEBUG(2,"Received commsquality request\n"); + + if (hw->ap) + break; + + qualmsg = (p80211msg_lnxreq_commsquality_t*) msg; + + qualmsg->link.status = P80211ENUM_msgitem_status_data_ok; + qualmsg->level.status = P80211ENUM_msgitem_status_data_ok; + qualmsg->noise.status = P80211ENUM_msgitem_status_data_ok; + + + qualmsg->link.data = hfa384x2host_16(hw->qual.CQ_currBSS); + qualmsg->level.data = hfa384x2host_16(hw->qual.ASL_currBSS); + qualmsg->noise.data = hfa384x2host_16(hw->qual.ANL_currFC); + + break; + } + default: + WLAN_LOG_WARNING("Unknown mgmt request message 0x%08x", msg->msgcode); + break; + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2sta_ifstate +* +* Interface state. This is the primary WLAN interface enable/disable +* handler. Following the driver/load/deviceprobe sequence, this +* function must be called with a state of "enable" before any other +* commands will be accepted. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* A p80211 message resultcode value. +* +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +UINT32 prism2sta_ifstate(wlandevice_t *wlandev, UINT32 ifstate) +{ + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + UINT32 result; + DBFENTER; + + result = P80211ENUM_resultcode_implementation_failure; + + WLAN_LOG_DEBUG(2, "Current MSD state(%d), requesting(%d)\n", + wlandev->msdstate, ifstate); + switch (ifstate) + { + case P80211ENUM_ifstate_fwload: + switch (wlandev->msdstate) { + case WLAN_MSD_HWPRESENT: + wlandev->msdstate = WLAN_MSD_FWLOAD_PENDING; + /* + * Initialize the device+driver sufficiently + * for firmware loading. + */ +#if (WLAN_HOSTIF != WLAN_USB) + result=hfa384x_cmd_initialize(hw); +#else + if ((result=hfa384x_drvr_start(hw))) { + WLAN_LOG_ERROR( + "hfa384x_drvr_start() failed," + "result=%d\n", (int)result); + result = + P80211ENUM_resultcode_implementation_failure; + wlandev->msdstate = WLAN_MSD_HWPRESENT; + break; + } +#endif + wlandev->msdstate = WLAN_MSD_FWLOAD; + result = P80211ENUM_resultcode_success; + break; + case WLAN_MSD_FWLOAD: + hfa384x_cmd_initialize(hw); + result = P80211ENUM_resultcode_success; + break; + case WLAN_MSD_RUNNING: + WLAN_LOG_WARNING( + "Cannot enter fwload state from enable state," + "you must disable first.\n"); + result = P80211ENUM_resultcode_invalid_parameters; + break; + case WLAN_MSD_HWFAIL: + default: + /* probe() had a problem or the msdstate contains + * an unrecognized value, there's nothing we can do. + */ + result = P80211ENUM_resultcode_implementation_failure; + break; + } + break; + case P80211ENUM_ifstate_enable: + switch (wlandev->msdstate) { + case WLAN_MSD_HWPRESENT: + case WLAN_MSD_FWLOAD: + wlandev->msdstate = WLAN_MSD_RUNNING_PENDING; + /* Initialize the device+driver for full + * operation. Note that this might me an FWLOAD to + * to RUNNING transition so we must not do a chip + * or board level reset. Note that on failure, + * the MSD state is set to HWPRESENT because we + * can't make any assumptions about the state + * of the hardware or a previous firmware load. + */ + if ((result=hfa384x_drvr_start(hw))) { + WLAN_LOG_ERROR( + "hfa384x_drvr_start() failed," + "result=%d\n", (int)result); + result = + P80211ENUM_resultcode_implementation_failure; + wlandev->msdstate = WLAN_MSD_HWPRESENT; + break; + } + + if ((result=prism2sta_getcardinfo(wlandev))) { + WLAN_LOG_ERROR( + "prism2sta_getcardinfo() failed," + "result=%d\n", (int)result); + result = + P80211ENUM_resultcode_implementation_failure; + hfa384x_drvr_stop(hw); + wlandev->msdstate = WLAN_MSD_HWPRESENT; + break; + } + if ((result=prism2sta_globalsetup(wlandev))) { + WLAN_LOG_ERROR( + "prism2sta_globalsetup() failed," + "result=%d\n", (int)result); + result = + P80211ENUM_resultcode_implementation_failure; + hfa384x_drvr_stop(hw); + wlandev->msdstate = WLAN_MSD_HWPRESENT; + break; + } + wlandev->msdstate = WLAN_MSD_RUNNING; + hw->join_ap = 0; + hw->join_retries = 60; + result = P80211ENUM_resultcode_success; + break; + case WLAN_MSD_RUNNING: + /* Do nothing, we're already in this state.*/ + result = P80211ENUM_resultcode_success; + break; + case WLAN_MSD_HWFAIL: + default: + /* probe() had a problem or the msdstate contains + * an unrecognized value, there's nothing we can do. + */ + result = P80211ENUM_resultcode_implementation_failure; + break; + } + break; + case P80211ENUM_ifstate_disable: + switch (wlandev->msdstate) { + case WLAN_MSD_HWPRESENT: + /* Do nothing, we're already in this state.*/ + result = P80211ENUM_resultcode_success; + break; + case WLAN_MSD_FWLOAD: + case WLAN_MSD_RUNNING: + wlandev->msdstate = WLAN_MSD_HWPRESENT_PENDING; + /* + * TODO: Shut down the MAC completely. Here a chip + * or board level reset is probably called for. + * After a "disable" _all_ results are lost, even + * those from a fwload. + */ + if (!wlandev->hwremoved) + netif_carrier_off(wlandev->netdev); + + hfa384x_drvr_stop(hw); + + wlandev->macmode = WLAN_MACMODE_NONE; + wlandev->msdstate = WLAN_MSD_HWPRESENT; + result = P80211ENUM_resultcode_success; + break; + case WLAN_MSD_HWFAIL: + default: + /* probe() had a problem or the msdstate contains + * an unrecognized value, there's nothing we can do. + */ + result = P80211ENUM_resultcode_implementation_failure; + break; + } + break; + default: + result = P80211ENUM_resultcode_invalid_parameters; + break; + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2sta_getcardinfo +* +* Collect the NICID, firmware version and any other identifiers +* we'd like to have in host-side data structures. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* 0 success +* >0 f/w reported error +* <0 driver reported error +* +* Side effects: +* +* Call context: +* Either. +----------------------------------------------------------------*/ +static int prism2sta_getcardinfo(wlandevice_t *wlandev) +{ + int result = 0; + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + UINT16 temp; + UINT8 snum[HFA384x_RID_NICSERIALNUMBER_LEN]; + char pstr[(HFA384x_RID_NICSERIALNUMBER_LEN * 4) + 1]; + + DBFENTER; + + /* Collect version and compatibility info */ + /* Some are critical, some are not */ + /* NIC identity */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICIDENTITY, + &hw->ident_nic, sizeof(hfa384x_compident_t)); + if ( result ) { + WLAN_LOG_ERROR("Failed to retrieve NICIDENTITY\n"); + goto failed; + } + + /* get all the nic id fields in host byte order */ + hw->ident_nic.id = hfa384x2host_16(hw->ident_nic.id); + hw->ident_nic.variant = hfa384x2host_16(hw->ident_nic.variant); + hw->ident_nic.major = hfa384x2host_16(hw->ident_nic.major); + hw->ident_nic.minor = hfa384x2host_16(hw->ident_nic.minor); + + WLAN_LOG_INFO( "ident: nic h/w: id=0x%02x %d.%d.%d\n", + hw->ident_nic.id, hw->ident_nic.major, + hw->ident_nic.minor, hw->ident_nic.variant); + + /* Primary f/w identity */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRIIDENTITY, + &hw->ident_pri_fw, sizeof(hfa384x_compident_t)); + if ( result ) { + WLAN_LOG_ERROR("Failed to retrieve PRIIDENTITY\n"); + goto failed; + } + + /* get all the private fw id fields in host byte order */ + hw->ident_pri_fw.id = hfa384x2host_16(hw->ident_pri_fw.id); + hw->ident_pri_fw.variant = hfa384x2host_16(hw->ident_pri_fw.variant); + hw->ident_pri_fw.major = hfa384x2host_16(hw->ident_pri_fw.major); + hw->ident_pri_fw.minor = hfa384x2host_16(hw->ident_pri_fw.minor); + + WLAN_LOG_INFO( "ident: pri f/w: id=0x%02x %d.%d.%d\n", + hw->ident_pri_fw.id, hw->ident_pri_fw.major, + hw->ident_pri_fw.minor, hw->ident_pri_fw.variant); + + /* Station (Secondary?) f/w identity */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STAIDENTITY, + &hw->ident_sta_fw, sizeof(hfa384x_compident_t)); + if ( result ) { + WLAN_LOG_ERROR("Failed to retrieve STAIDENTITY\n"); + goto failed; + } + + if (hw->ident_nic.id < 0x8000) { + WLAN_LOG_ERROR("FATAL: Card is not an Intersil Prism2/2.5/3\n"); + result = -1; + goto failed; + } + + /* get all the station fw id fields in host byte order */ + hw->ident_sta_fw.id = hfa384x2host_16(hw->ident_sta_fw.id); + hw->ident_sta_fw.variant = hfa384x2host_16(hw->ident_sta_fw.variant); + hw->ident_sta_fw.major = hfa384x2host_16(hw->ident_sta_fw.major); + hw->ident_sta_fw.minor = hfa384x2host_16(hw->ident_sta_fw.minor); + + /* strip out the 'special' variant bits */ + hw->mm_mods = hw->ident_sta_fw.variant & (BIT14 | BIT15); + hw->ident_sta_fw.variant &= ~((UINT16)(BIT14 | BIT15)); + + if ( hw->ident_sta_fw.id == 0x1f ) { + hw->ap = 0; + WLAN_LOG_INFO( + "ident: sta f/w: id=0x%02x %d.%d.%d\n", + hw->ident_sta_fw.id, hw->ident_sta_fw.major, + hw->ident_sta_fw.minor, hw->ident_sta_fw.variant); + } else { + hw->ap = 1; + WLAN_LOG_INFO( + "ident: ap f/w: id=0x%02x %d.%d.%d\n", + hw->ident_sta_fw.id, hw->ident_sta_fw.major, + hw->ident_sta_fw.minor, hw->ident_sta_fw.variant); + } + + /* Compatibility range, Modem supplier */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_MFISUPRANGE, + &hw->cap_sup_mfi, sizeof(hfa384x_caplevel_t)); + if ( result ) { + WLAN_LOG_ERROR("Failed to retrieve MFISUPRANGE\n"); + goto failed; + } + + /* get all the Compatibility range, modem interface supplier + fields in byte order */ + hw->cap_sup_mfi.role = hfa384x2host_16(hw->cap_sup_mfi.role); + hw->cap_sup_mfi.id = hfa384x2host_16(hw->cap_sup_mfi.id); + hw->cap_sup_mfi.variant = hfa384x2host_16(hw->cap_sup_mfi.variant); + hw->cap_sup_mfi.bottom = hfa384x2host_16(hw->cap_sup_mfi.bottom); + hw->cap_sup_mfi.top = hfa384x2host_16(hw->cap_sup_mfi.top); + + WLAN_LOG_INFO( + "MFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", + hw->cap_sup_mfi.role, hw->cap_sup_mfi.id, + hw->cap_sup_mfi.variant, hw->cap_sup_mfi.bottom, + hw->cap_sup_mfi.top); + + /* Compatibility range, Controller supplier */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CFISUPRANGE, + &hw->cap_sup_cfi, sizeof(hfa384x_caplevel_t)); + if ( result ) { + WLAN_LOG_ERROR("Failed to retrieve CFISUPRANGE\n"); + goto failed; + } + + /* get all the Compatibility range, controller interface supplier + fields in byte order */ + hw->cap_sup_cfi.role = hfa384x2host_16(hw->cap_sup_cfi.role); + hw->cap_sup_cfi.id = hfa384x2host_16(hw->cap_sup_cfi.id); + hw->cap_sup_cfi.variant = hfa384x2host_16(hw->cap_sup_cfi.variant); + hw->cap_sup_cfi.bottom = hfa384x2host_16(hw->cap_sup_cfi.bottom); + hw->cap_sup_cfi.top = hfa384x2host_16(hw->cap_sup_cfi.top); + + WLAN_LOG_INFO( + "CFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", + hw->cap_sup_cfi.role, hw->cap_sup_cfi.id, + hw->cap_sup_cfi.variant, hw->cap_sup_cfi.bottom, + hw->cap_sup_cfi.top); + + /* Compatibility range, Primary f/w supplier */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRISUPRANGE, + &hw->cap_sup_pri, sizeof(hfa384x_caplevel_t)); + if ( result ) { + WLAN_LOG_ERROR("Failed to retrieve PRISUPRANGE\n"); + goto failed; + } + + /* get all the Compatibility range, primary firmware supplier + fields in byte order */ + hw->cap_sup_pri.role = hfa384x2host_16(hw->cap_sup_pri.role); + hw->cap_sup_pri.id = hfa384x2host_16(hw->cap_sup_pri.id); + hw->cap_sup_pri.variant = hfa384x2host_16(hw->cap_sup_pri.variant); + hw->cap_sup_pri.bottom = hfa384x2host_16(hw->cap_sup_pri.bottom); + hw->cap_sup_pri.top = hfa384x2host_16(hw->cap_sup_pri.top); + + WLAN_LOG_INFO( + "PRI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", + hw->cap_sup_pri.role, hw->cap_sup_pri.id, + hw->cap_sup_pri.variant, hw->cap_sup_pri.bottom, + hw->cap_sup_pri.top); + + /* Compatibility range, Station f/w supplier */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STASUPRANGE, + &hw->cap_sup_sta, sizeof(hfa384x_caplevel_t)); + if ( result ) { + WLAN_LOG_ERROR("Failed to retrieve STASUPRANGE\n"); + goto failed; + } + + /* get all the Compatibility range, station firmware supplier + fields in byte order */ + hw->cap_sup_sta.role = hfa384x2host_16(hw->cap_sup_sta.role); + hw->cap_sup_sta.id = hfa384x2host_16(hw->cap_sup_sta.id); + hw->cap_sup_sta.variant = hfa384x2host_16(hw->cap_sup_sta.variant); + hw->cap_sup_sta.bottom = hfa384x2host_16(hw->cap_sup_sta.bottom); + hw->cap_sup_sta.top = hfa384x2host_16(hw->cap_sup_sta.top); + + if ( hw->cap_sup_sta.id == 0x04 ) { + WLAN_LOG_INFO( + "STA:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", + hw->cap_sup_sta.role, hw->cap_sup_sta.id, + hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom, + hw->cap_sup_sta.top); + } else { + WLAN_LOG_INFO( + "AP:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", + hw->cap_sup_sta.role, hw->cap_sup_sta.id, + hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom, + hw->cap_sup_sta.top); + } + + /* Compatibility range, primary f/w actor, CFI supplier */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRI_CFIACTRANGES, + &hw->cap_act_pri_cfi, sizeof(hfa384x_caplevel_t)); + if ( result ) { + WLAN_LOG_ERROR("Failed to retrieve PRI_CFIACTRANGES\n"); + goto failed; + } + + /* get all the Compatibility range, primary f/w actor, CFI supplier + fields in byte order */ + hw->cap_act_pri_cfi.role = hfa384x2host_16(hw->cap_act_pri_cfi.role); + hw->cap_act_pri_cfi.id = hfa384x2host_16(hw->cap_act_pri_cfi.id); + hw->cap_act_pri_cfi.variant = hfa384x2host_16(hw->cap_act_pri_cfi.variant); + hw->cap_act_pri_cfi.bottom = hfa384x2host_16(hw->cap_act_pri_cfi.bottom); + hw->cap_act_pri_cfi.top = hfa384x2host_16(hw->cap_act_pri_cfi.top); + + WLAN_LOG_INFO( + "PRI-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", + hw->cap_act_pri_cfi.role, hw->cap_act_pri_cfi.id, + hw->cap_act_pri_cfi.variant, hw->cap_act_pri_cfi.bottom, + hw->cap_act_pri_cfi.top); + + /* Compatibility range, sta f/w actor, CFI supplier */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STA_CFIACTRANGES, + &hw->cap_act_sta_cfi, sizeof(hfa384x_caplevel_t)); + if ( result ) { + WLAN_LOG_ERROR("Failed to retrieve STA_CFIACTRANGES\n"); + goto failed; + } + + /* get all the Compatibility range, station f/w actor, CFI supplier + fields in byte order */ + hw->cap_act_sta_cfi.role = hfa384x2host_16(hw->cap_act_sta_cfi.role); + hw->cap_act_sta_cfi.id = hfa384x2host_16(hw->cap_act_sta_cfi.id); + hw->cap_act_sta_cfi.variant = hfa384x2host_16(hw->cap_act_sta_cfi.variant); + hw->cap_act_sta_cfi.bottom = hfa384x2host_16(hw->cap_act_sta_cfi.bottom); + hw->cap_act_sta_cfi.top = hfa384x2host_16(hw->cap_act_sta_cfi.top); + + WLAN_LOG_INFO( + "STA-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", + hw->cap_act_sta_cfi.role, hw->cap_act_sta_cfi.id, + hw->cap_act_sta_cfi.variant, hw->cap_act_sta_cfi.bottom, + hw->cap_act_sta_cfi.top); + + /* Compatibility range, sta f/w actor, MFI supplier */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STA_MFIACTRANGES, + &hw->cap_act_sta_mfi, sizeof(hfa384x_caplevel_t)); + if ( result ) { + WLAN_LOG_ERROR("Failed to retrieve STA_MFIACTRANGES\n"); + goto failed; + } + + /* get all the Compatibility range, station f/w actor, MFI supplier + fields in byte order */ + hw->cap_act_sta_mfi.role = hfa384x2host_16(hw->cap_act_sta_mfi.role); + hw->cap_act_sta_mfi.id = hfa384x2host_16(hw->cap_act_sta_mfi.id); + hw->cap_act_sta_mfi.variant = hfa384x2host_16(hw->cap_act_sta_mfi.variant); + hw->cap_act_sta_mfi.bottom = hfa384x2host_16(hw->cap_act_sta_mfi.bottom); + hw->cap_act_sta_mfi.top = hfa384x2host_16(hw->cap_act_sta_mfi.top); + + WLAN_LOG_INFO( + "STA-MFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", + hw->cap_act_sta_mfi.role, hw->cap_act_sta_mfi.id, + hw->cap_act_sta_mfi.variant, hw->cap_act_sta_mfi.bottom, + hw->cap_act_sta_mfi.top); + + /* Serial Number */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICSERIALNUMBER, + snum, HFA384x_RID_NICSERIALNUMBER_LEN); + if ( !result ) { + wlan_mkprintstr(snum, HFA384x_RID_NICSERIALNUMBER_LEN, + pstr, sizeof(pstr)); + WLAN_LOG_INFO("Prism2 card SN: %s\n", pstr); + } else { + WLAN_LOG_ERROR("Failed to retrieve Prism2 Card SN\n"); + goto failed; + } + + /* Collect the MAC address */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CNFOWNMACADDR, + wlandev->netdev->dev_addr, WLAN_ADDR_LEN); + if ( result != 0 ) { + WLAN_LOG_ERROR("Failed to retrieve mac address\n"); + goto failed; + } + + /* short preamble is always implemented */ + wlandev->nsdcaps |= P80211_NSDCAP_SHORT_PREAMBLE; + + /* find out if hardware wep is implemented */ + hfa384x_drvr_getconfig16(hw, HFA384x_RID_PRIVACYOPTIMP, &temp); + if (temp) + wlandev->nsdcaps |= P80211_NSDCAP_HARDWAREWEP; + + /* get the dBm Scaling constant */ + hfa384x_drvr_getconfig16(hw, HFA384x_RID_CNFDBMADJUST, &temp); + hw->dbmadjust = temp; + + /* Only enable scan by default on newer firmware */ + if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major, + hw->ident_sta_fw.minor, + hw->ident_sta_fw.variant) < + HFA384x_FIRMWARE_VERSION(1,5,5)) { + wlandev->nsdcaps |= P80211_NSDCAP_NOSCAN; + } + + /* TODO: Set any internally managed config items */ + + goto done; +failed: + WLAN_LOG_ERROR("Failed, result=%d\n", result); +done: + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2sta_globalsetup +* +* Set any global RIDs that we want to set at device activation. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* 0 success +* >0 f/w reported error +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +static int prism2sta_globalsetup(wlandevice_t *wlandev) +{ + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + + /* Set the maximum frame size */ + return hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, + WLAN_DATA_MAXLEN); +} + +static int prism2sta_setmulticast(wlandevice_t *wlandev, netdevice_t *dev) +{ + int result = 0; + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + + UINT16 promisc; + + DBFENTER; + + /* If we're not ready, what's the point? */ + if ( hw->state != HFA384x_STATE_RUNNING ) + goto exit; + + /* If we're an AP, do nothing here */ + if (hw->ap) + goto exit; + + if ( (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0 ) + promisc = P80211ENUM_truth_true; + else + promisc = P80211ENUM_truth_false; + + result = hfa384x_drvr_setconfig16_async(hw, HFA384x_RID_PROMISCMODE, promisc); + + /* XXX TODO: configure the multicast list */ + // CLEAR_HW_MULTICAST_LIST + // struct dev_mc_list element = dev->mc_list; + // while (element != null) { + // HW_ADD_MULTICAST_ADDR(element->dmi_addr, dmi_addrlen) + // element = element->next; + // } + + exit: + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* prism2sta_inf_handover +* +* Handles the receipt of a Handover info frame. Should only be present +* in APs only. +* +* Arguments: +* wlandev wlan device structure +* inf ptr to info frame (contents in hfa384x order) +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void prism2sta_inf_handover(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf) +{ + DBFENTER; + WLAN_LOG_DEBUG(2,"received infoframe:HANDOVER (unhandled)\n"); + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* prism2sta_inf_tallies +* +* Handles the receipt of a CommTallies info frame. +* +* Arguments: +* wlandev wlan device structure +* inf ptr to info frame (contents in hfa384x order) +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void prism2sta_inf_tallies(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf) +{ + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + UINT16 *src16; + UINT32 *dst; + UINT32 *src32; + int i; + int cnt; + + DBFENTER; + + /* + ** Determine if these are 16-bit or 32-bit tallies, based on the + ** record length of the info record. + */ + + cnt = sizeof(hfa384x_CommTallies32_t) / sizeof(UINT32); + if (inf->framelen > 22) { + dst = (UINT32 *) &hw->tallies; + src32 = (UINT32 *) &inf->info.commtallies32; + for (i = 0; i < cnt; i++, dst++, src32++) + *dst += hfa384x2host_32(*src32); + } else { + dst = (UINT32 *) &hw->tallies; + src16 = (UINT16 *) &inf->info.commtallies16; + for (i = 0; i < cnt; i++, dst++, src16++) + *dst += hfa384x2host_16(*src16); + } + + DBFEXIT; + + return; +} + +/*---------------------------------------------------------------- +* prism2sta_inf_scanresults +* +* Handles the receipt of a Scan Results info frame. +* +* Arguments: +* wlandev wlan device structure +* inf ptr to info frame (contents in hfa384x order) +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void prism2sta_inf_scanresults(wlandevice_t *wlandev, + hfa384x_InfFrame_t *inf) +{ + + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + int nbss; + hfa384x_ScanResult_t *sr = &(inf->info.scanresult); + int i; + hfa384x_JoinRequest_data_t joinreq; + int result; + DBFENTER; + + /* Get the number of results, first in bytes, then in results */ + nbss = (inf->framelen * sizeof(UINT16)) - + sizeof(inf->infotype) - + sizeof(inf->info.scanresult.scanreason); + nbss /= sizeof(hfa384x_ScanResultSub_t); + + /* Print em */ + WLAN_LOG_DEBUG(1,"rx scanresults, reason=%d, nbss=%d:\n", + inf->info.scanresult.scanreason, nbss); + for ( i = 0; i < nbss; i++) { + WLAN_LOG_DEBUG(1, "chid=%d anl=%d sl=%d bcnint=%d\n", + sr->result[i].chid, + sr->result[i].anl, + sr->result[i].sl, + sr->result[i].bcnint); + WLAN_LOG_DEBUG(1, " capinfo=0x%04x proberesp_rate=%d\n", + sr->result[i].capinfo, + sr->result[i].proberesp_rate); + } + /* issue a join request */ + joinreq.channel = sr->result[0].chid; + memcpy( joinreq.bssid, sr->result[0].bssid, WLAN_BSSID_LEN); + result = hfa384x_drvr_setconfig( hw, + HFA384x_RID_JOINREQUEST, + &joinreq, HFA384x_RID_JOINREQUEST_LEN); + if (result) { + WLAN_LOG_ERROR("setconfig(joinreq) failed, result=%d\n", result); + } + + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* prism2sta_inf_hostscanresults +* +* Handles the receipt of a Scan Results info frame. +* +* Arguments: +* wlandev wlan device structure +* inf ptr to info frame (contents in hfa384x order) +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void prism2sta_inf_hostscanresults(wlandevice_t *wlandev, + hfa384x_InfFrame_t *inf) +{ + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + int nbss; + DBFENTER; + + nbss = (inf->framelen - 3) / 32; + WLAN_LOG_DEBUG(1, "Received %d hostscan results\n", nbss); + + if (nbss > 32) + nbss = 32; + + if (hw->scanresults) + kfree(hw->scanresults); + + hw->scanresults = kmalloc(sizeof(hfa384x_InfFrame_t), GFP_ATOMIC); + memcpy(hw->scanresults, inf, sizeof(hfa384x_InfFrame_t)); + + if (nbss == 0) + nbss = -1; + + /* Notify/wake the sleeping caller. */ + hw->scanflag = nbss; + wake_up_interruptible(&hw->cmdq); + + DBFEXIT; +}; + +/*---------------------------------------------------------------- +* prism2sta_inf_chinforesults +* +* Handles the receipt of a Channel Info Results info frame. +* +* Arguments: +* wlandev wlan device structure +* inf ptr to info frame (contents in hfa384x order) +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void prism2sta_inf_chinforesults(wlandevice_t *wlandev, + hfa384x_InfFrame_t *inf) +{ + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + unsigned int i, n; + + DBFENTER; + hw->channel_info.results.scanchannels = + hfa384x2host_16(inf->info.chinforesult.scanchannels); +#if 0 + memcpy(&inf->info.chinforesult, &hw->channel_info.results, sizeof(hfa384x_ChInfoResult_t)); +#endif + + for (i=0, n=0; ichannel_info.results.scanchannels & (1<info.chinforesult.result[n].chid)-1; + hfa384x_ChInfoResultSub_t *chinforesult=&hw->channel_info.results.result[channel]; + chinforesult->chid = channel; + chinforesult->anl = hfa384x2host_16(inf->info.chinforesult.result[n].anl); + chinforesult->pnl = hfa384x2host_16(inf->info.chinforesult.result[n].pnl); + chinforesult->active = hfa384x2host_16(inf->info.chinforesult.result[n].active); + WLAN_LOG_DEBUG(2, "chinfo: channel %d, %s level (avg/peak)=%d/%d dB, pcf %d\n", + channel+1, + chinforesult->active & + HFA384x_CHINFORESULT_BSSACTIVE ? "signal" : "noise", + chinforesult->anl, chinforesult->pnl, + chinforesult->active & HFA384x_CHINFORESULT_PCFACTIVE ? 1 : 0 + ); + n++; + } + } + atomic_set(&hw->channel_info.done, 2); + + hw->channel_info.count = n; + DBFEXIT; + return; +} + +void prism2sta_processing_defer(struct work_struct *data) +{ + hfa384x_t *hw = container_of(data, struct hfa384x, link_bh); + wlandevice_t *wlandev = hw->wlandev; + hfa384x_bytestr32_t ssid; + int result; + + DBFENTER; + /* First let's process the auth frames */ + { + struct sk_buff *skb; + hfa384x_InfFrame_t *inf; + + while ( (skb = skb_dequeue(&hw->authq)) ) { + inf = (hfa384x_InfFrame_t *) skb->data; + prism2sta_inf_authreq_defer(wlandev, inf); + } + + } + + /* Now let's handle the linkstatus stuff */ + if (hw->link_status == hw->link_status_new) + goto failed; + + hw->link_status = hw->link_status_new; + + switch(hw->link_status) { + case HFA384x_LINK_NOTCONNECTED: + /* I'm currently assuming that this is the initial link + * state. It should only be possible immediately + * following an Enable command. + * Response: + * Block Transmits, Ignore receives of data frames + */ + netif_carrier_off(wlandev->netdev); + + WLAN_LOG_INFO("linkstatus=NOTCONNECTED (unhandled)\n"); + break; + + case HFA384x_LINK_CONNECTED: + /* This one indicates a successful scan/join/auth/assoc. + * When we have the full MLME complement, this event will + * signify successful completion of both mlme_authenticate + * and mlme_associate. State management will get a little + * ugly here. + * Response: + * Indicate authentication and/or association + * Enable Transmits, Receives and pass up data frames + */ + + netif_carrier_on(wlandev->netdev); + + /* If we are joining a specific AP, set our state and reset retries */ + if(hw->join_ap == 1) + hw->join_ap = 2; + hw->join_retries = 60; + + /* Don't call this in monitor mode */ + if ( wlandev->netdev->type == ARPHRD_ETHER ) { + UINT16 portstatus; + + WLAN_LOG_INFO("linkstatus=CONNECTED\n"); + + /* For non-usb devices, we can use the sync versions */ + /* Collect the BSSID, and set state to allow tx */ + + result = hfa384x_drvr_getconfig(hw, + HFA384x_RID_CURRENTBSSID, + wlandev->bssid, WLAN_BSSID_LEN); + if ( result ) { + WLAN_LOG_DEBUG(1, + "getconfig(0x%02x) failed, result = %d\n", + HFA384x_RID_CURRENTBSSID, result); + goto failed; + } + + result = hfa384x_drvr_getconfig(hw, + HFA384x_RID_CURRENTSSID, + &ssid, sizeof(ssid)); + if ( result ) { + WLAN_LOG_DEBUG(1, + "getconfig(0x%02x) failed, result = %d\n", + HFA384x_RID_CURRENTSSID, result); + goto failed; + } + prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *)&ssid, + (p80211pstrd_t *) &wlandev->ssid); + + /* Collect the port status */ + result = hfa384x_drvr_getconfig16(hw, + HFA384x_RID_PORTSTATUS, &portstatus); + if ( result ) { + WLAN_LOG_DEBUG(1, + "getconfig(0x%02x) failed, result = %d\n", + HFA384x_RID_PORTSTATUS, result); + goto failed; + } + wlandev->macmode = + (portstatus == HFA384x_PSTATUS_CONN_IBSS) ? + WLAN_MACMODE_IBSS_STA : WLAN_MACMODE_ESS_STA; + + /* Get the ball rolling on the comms quality stuff */ + prism2sta_commsqual_defer(&hw->commsqual_bh); + } + break; + + case HFA384x_LINK_DISCONNECTED: + /* This one indicates that our association is gone. We've + * lost connection with the AP and/or been disassociated. + * This indicates that the MAC has completely cleared it's + * associated state. We * should send a deauth indication + * (implying disassoc) up * to the MLME. + * Response: + * Indicate Deauthentication + * Block Transmits, Ignore receives of data frames + */ + if(hw->join_ap == 2) + { + hfa384x_JoinRequest_data_t joinreq; + joinreq = hw->joinreq; + /* Send the join request */ + hfa384x_drvr_setconfig( hw, + HFA384x_RID_JOINREQUEST, + &joinreq, HFA384x_RID_JOINREQUEST_LEN); + WLAN_LOG_INFO("linkstatus=DISCONNECTED (re-submitting join)\n"); + } else { + if (wlandev->netdev->type == ARPHRD_ETHER) + WLAN_LOG_INFO("linkstatus=DISCONNECTED (unhandled)\n"); + } + wlandev->macmode = WLAN_MACMODE_NONE; + + netif_carrier_off(wlandev->netdev); + + break; + + case HFA384x_LINK_AP_CHANGE: + /* This one indicates that the MAC has decided to and + * successfully completed a change to another AP. We + * should probably implement a reassociation indication + * in response to this one. I'm thinking that the the + * p80211 layer needs to be notified in case of + * buffering/queueing issues. User mode also needs to be + * notified so that any BSS dependent elements can be + * updated. + * associated state. We * should send a deauth indication + * (implying disassoc) up * to the MLME. + * Response: + * Indicate Reassociation + * Enable Transmits, Receives and pass up data frames + */ + WLAN_LOG_INFO("linkstatus=AP_CHANGE\n"); + + result = hfa384x_drvr_getconfig(hw, + HFA384x_RID_CURRENTBSSID, + wlandev->bssid, WLAN_BSSID_LEN); + if ( result ) { + WLAN_LOG_DEBUG(1, + "getconfig(0x%02x) failed, result = %d\n", + HFA384x_RID_CURRENTBSSID, result); + goto failed; + } + + result = hfa384x_drvr_getconfig(hw, + HFA384x_RID_CURRENTSSID, + &ssid, sizeof(ssid)); + if ( result ) { + WLAN_LOG_DEBUG(1, + "getconfig(0x%02x) failed, result = %d\n", + HFA384x_RID_CURRENTSSID, result); + goto failed; + } + prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *)&ssid, + (p80211pstrd_t *) &wlandev->ssid); + + + hw->link_status = HFA384x_LINK_CONNECTED; + netif_carrier_on(wlandev->netdev); + + break; + + case HFA384x_LINK_AP_OUTOFRANGE: + /* This one indicates that the MAC has decided that the + * AP is out of range, but hasn't found a better candidate + * so the MAC maintains its "associated" state in case + * we get back in range. We should block transmits and + * receives in this state. Do we need an indication here? + * Probably not since a polling user-mode element would + * get this status from from p2PortStatus(FD40). What about + * p80211? + * Response: + * Block Transmits, Ignore receives of data frames + */ + WLAN_LOG_INFO("linkstatus=AP_OUTOFRANGE (unhandled)\n"); + + netif_carrier_off(wlandev->netdev); + + break; + + case HFA384x_LINK_AP_INRANGE: + /* This one indicates that the MAC has decided that the + * AP is back in range. We continue working with our + * existing association. + * Response: + * Enable Transmits, Receives and pass up data frames + */ + WLAN_LOG_INFO("linkstatus=AP_INRANGE\n"); + + hw->link_status = HFA384x_LINK_CONNECTED; + netif_carrier_on(wlandev->netdev); + + break; + + case HFA384x_LINK_ASSOCFAIL: + /* This one is actually a peer to CONNECTED. We've + * requested a join for a given SSID and optionally BSSID. + * We can use this one to indicate authentication and + * association failures. The trick is going to be + * 1) identifying the failure, and 2) state management. + * Response: + * Disable Transmits, Ignore receives of data frames + */ + if(hw->join_ap && --hw->join_retries > 0) + { + hfa384x_JoinRequest_data_t joinreq; + joinreq = hw->joinreq; + /* Send the join request */ + hfa384x_drvr_setconfig( hw, + HFA384x_RID_JOINREQUEST, + &joinreq, HFA384x_RID_JOINREQUEST_LEN); + WLAN_LOG_INFO("linkstatus=ASSOCFAIL (re-submitting join)\n"); + } else { + WLAN_LOG_INFO("linkstatus=ASSOCFAIL (unhandled)\n"); + } + + netif_carrier_off(wlandev->netdev); + + break; + + default: + /* This is bad, IO port problems? */ + WLAN_LOG_WARNING( + "unknown linkstatus=0x%02x\n", hw->link_status); + goto failed; + break; + } + + wlandev->linkstatus = (hw->link_status == HFA384x_LINK_CONNECTED); +#ifdef WIRELESS_EXT + p80211wext_event_associated(wlandev, wlandev->linkstatus); +#endif + + failed: + DBFEXIT; +} + +/*---------------------------------------------------------------- +* prism2sta_inf_linkstatus +* +* Handles the receipt of a Link Status info frame. +* +* Arguments: +* wlandev wlan device structure +* inf ptr to info frame (contents in hfa384x order) +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void prism2sta_inf_linkstatus(wlandevice_t *wlandev, + hfa384x_InfFrame_t *inf) +{ + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + + DBFENTER; + + hw->link_status_new = hfa384x2host_16(inf->info.linkstatus.linkstatus); + + schedule_work(&hw->link_bh); + + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* prism2sta_inf_assocstatus +* +* Handles the receipt of an Association Status info frame. Should +* be present in APs only. +* +* Arguments: +* wlandev wlan device structure +* inf ptr to info frame (contents in hfa384x order) +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void prism2sta_inf_assocstatus(wlandevice_t *wlandev, + hfa384x_InfFrame_t *inf) +{ + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + hfa384x_AssocStatus_t rec; + int i; + + DBFENTER; + + memcpy(&rec, &inf->info.assocstatus, sizeof(rec)); + rec.assocstatus = hfa384x2host_16(rec.assocstatus); + rec.reason = hfa384x2host_16(rec.reason); + + /* + ** Find the address in the list of authenticated stations. If it wasn't + ** found, then this address has not been previously authenticated and + ** something weird has happened if this is anything other than an + ** "authentication failed" message. If the address was found, then + ** set the "associated" flag for that station, based on whether the + ** station is associating or losing its association. Something weird + ** has also happened if we find the address in the list of authenticated + ** stations but we are getting an "authentication failed" message. + */ + + for (i = 0; i < hw->authlist.cnt; i++) + if (memcmp(rec.sta_addr, hw->authlist.addr[i], WLAN_ADDR_LEN) == 0) + break; + + if (i >= hw->authlist.cnt) { + if (rec.assocstatus != HFA384x_ASSOCSTATUS_AUTHFAIL) + WLAN_LOG_WARNING("assocstatus info frame received for non-authenticated station.\n"); + } else { + hw->authlist.assoc[i] = + (rec.assocstatus == HFA384x_ASSOCSTATUS_STAASSOC || + rec.assocstatus == HFA384x_ASSOCSTATUS_REASSOC); + + if (rec.assocstatus == HFA384x_ASSOCSTATUS_AUTHFAIL) + WLAN_LOG_WARNING("authfail assocstatus info frame received for authenticated station.\n"); + } + + DBFEXIT; + + return; +} + +/*---------------------------------------------------------------- +* prism2sta_inf_authreq +* +* Handles the receipt of an Authentication Request info frame. Should +* be present in APs only. +* +* Arguments: +* wlandev wlan device structure +* inf ptr to info frame (contents in hfa384x order) +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +* +----------------------------------------------------------------*/ +static void prism2sta_inf_authreq(wlandevice_t *wlandev, + hfa384x_InfFrame_t *inf) +{ + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + struct sk_buff *skb; + + DBFENTER; + + skb = dev_alloc_skb(sizeof(*inf)); + if (skb) { + skb_put(skb, sizeof(*inf)); + memcpy(skb->data, inf, sizeof(*inf)); + skb_queue_tail(&hw->authq, skb); + schedule_work(&hw->link_bh); + } + + DBFEXIT; +} + +static void prism2sta_inf_authreq_defer(wlandevice_t *wlandev, + hfa384x_InfFrame_t *inf) +{ + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + hfa384x_authenticateStation_data_t rec; + + int i, added, result, cnt; + UINT8 *addr; + + DBFENTER; + + /* + ** Build the AuthenticateStation record. Initialize it for denying + ** authentication. + */ + + memcpy(rec.address, inf->info.authreq.sta_addr, WLAN_ADDR_LEN); + rec.status = P80211ENUM_status_unspec_failure; + + /* + ** Authenticate based on the access mode. + */ + + switch (hw->accessmode) { + case WLAN_ACCESS_NONE: + + /* + ** Deny all new authentications. However, if a station + ** is ALREADY authenticated, then accept it. + */ + + for (i = 0; i < hw->authlist.cnt; i++) + if (memcmp(rec.address, hw->authlist.addr[i], + WLAN_ADDR_LEN) == 0) { + rec.status = P80211ENUM_status_successful; + break; + } + + break; + + case WLAN_ACCESS_ALL: + + /* + ** Allow all authentications. + */ + + rec.status = P80211ENUM_status_successful; + break; + + case WLAN_ACCESS_ALLOW: + + /* + ** Only allow the authentication if the MAC address + ** is in the list of allowed addresses. + ** + ** Since this is the interrupt handler, we may be here + ** while the access list is in the middle of being + ** updated. Choose the list which is currently okay. + ** See "prism2mib_priv_accessallow()" for details. + */ + + if (hw->allow.modify == 0) { + cnt = hw->allow.cnt; + addr = hw->allow.addr[0]; + } else { + cnt = hw->allow.cnt1; + addr = hw->allow.addr1[0]; + } + + for (i = 0; i < cnt; i++, addr += WLAN_ADDR_LEN) + if (memcmp(rec.address, addr, WLAN_ADDR_LEN) == 0) { + rec.status = P80211ENUM_status_successful; + break; + } + + break; + + case WLAN_ACCESS_DENY: + + /* + ** Allow the authentication UNLESS the MAC address is + ** in the list of denied addresses. + ** + ** Since this is the interrupt handler, we may be here + ** while the access list is in the middle of being + ** updated. Choose the list which is currently okay. + ** See "prism2mib_priv_accessdeny()" for details. + */ + + if (hw->deny.modify == 0) { + cnt = hw->deny.cnt; + addr = hw->deny.addr[0]; + } else { + cnt = hw->deny.cnt1; + addr = hw->deny.addr1[0]; + } + + rec.status = P80211ENUM_status_successful; + + for (i = 0; i < cnt; i++, addr += WLAN_ADDR_LEN) + if (memcmp(rec.address, addr, WLAN_ADDR_LEN) == 0) { + rec.status = P80211ENUM_status_unspec_failure; + break; + } + + break; + } + + /* + ** If the authentication is okay, then add the MAC address to the list + ** of authenticated stations. Don't add the address if it is already in + ** the list. (802.11b does not seem to disallow a station from issuing + ** an authentication request when the station is already authenticated. + ** Does this sort of thing ever happen? We might as well do the check + ** just in case.) + */ + + added = 0; + + if (rec.status == P80211ENUM_status_successful) { + for (i = 0; i < hw->authlist.cnt; i++) + if (memcmp(rec.address, hw->authlist.addr[i], WLAN_ADDR_LEN) == 0) + break; + + if (i >= hw->authlist.cnt) { + if (hw->authlist.cnt >= WLAN_AUTH_MAX) { + rec.status = P80211ENUM_status_ap_full; + } else { + memcpy(hw->authlist.addr[hw->authlist.cnt], + rec.address, WLAN_ADDR_LEN); + hw->authlist.cnt++; + added = 1; + } + } + } + + /* + ** Send back the results of the authentication. If this doesn't work, + ** then make sure to remove the address from the authenticated list if + ** it was added. + */ + + rec.status = host2hfa384x_16(rec.status); + rec.algorithm = inf->info.authreq.algorithm; + + result = hfa384x_drvr_setconfig(hw, HFA384x_RID_AUTHENTICATESTA, + &rec, sizeof(rec)); + if (result) { + if (added) hw->authlist.cnt--; + WLAN_LOG_ERROR("setconfig(authenticatestation) failed, result=%d\n", result); + } + + DBFEXIT; + + return; +} + + +/*---------------------------------------------------------------- +* prism2sta_inf_psusercnt +* +* Handles the receipt of a PowerSaveUserCount info frame. Should +* be present in APs only. +* +* Arguments: +* wlandev wlan device structure +* inf ptr to info frame (contents in hfa384x order) +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void prism2sta_inf_psusercnt(wlandevice_t *wlandev, + hfa384x_InfFrame_t *inf) +{ + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + + DBFENTER; + + hw->psusercount = hfa384x2host_16(inf->info.psusercnt.usercnt); + + DBFEXIT; + + return; +} + +/*---------------------------------------------------------------- +* prism2sta_ev_dtim +* +* Handles the DTIM early warning event. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +void prism2sta_ev_dtim(wlandevice_t *wlandev) +{ +#if 0 + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; +#endif + DBFENTER; + WLAN_LOG_DEBUG(3, "DTIM event, currently unhandled.\n"); + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* prism2sta_ev_infdrop +* +* Handles the InfDrop event. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +void prism2sta_ev_infdrop(wlandevice_t *wlandev) +{ +#if 0 + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; +#endif + DBFENTER; + WLAN_LOG_DEBUG(3, "Info frame dropped due to card mem low.\n"); + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* prism2sta_ev_info +* +* Handles the Info event. +* +* Arguments: +* wlandev wlan device structure +* inf ptr to a generic info frame +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +void prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf) +{ + DBFENTER; + inf->infotype = hfa384x2host_16(inf->infotype); + /* Dispatch */ + switch ( inf->infotype ) { + case HFA384x_IT_HANDOVERADDR: + prism2sta_inf_handover(wlandev, inf); + break; + case HFA384x_IT_COMMTALLIES: + prism2sta_inf_tallies(wlandev, inf); + break; + case HFA384x_IT_HOSTSCANRESULTS: + prism2sta_inf_hostscanresults(wlandev, inf); + break; + case HFA384x_IT_SCANRESULTS: + prism2sta_inf_scanresults(wlandev, inf); + break; + case HFA384x_IT_CHINFORESULTS: + prism2sta_inf_chinforesults(wlandev, inf); + break; + case HFA384x_IT_LINKSTATUS: + prism2sta_inf_linkstatus(wlandev, inf); + break; + case HFA384x_IT_ASSOCSTATUS: + prism2sta_inf_assocstatus(wlandev, inf); + break; + case HFA384x_IT_AUTHREQ: + prism2sta_inf_authreq(wlandev, inf); + break; + case HFA384x_IT_PSUSERCNT: + prism2sta_inf_psusercnt(wlandev, inf); + break; + case HFA384x_IT_KEYIDCHANGED: + WLAN_LOG_WARNING("Unhandled IT_KEYIDCHANGED\n"); + break; + case HFA384x_IT_ASSOCREQ: + WLAN_LOG_WARNING("Unhandled IT_ASSOCREQ\n"); + break; + case HFA384x_IT_MICFAILURE: + WLAN_LOG_WARNING("Unhandled IT_MICFAILURE\n"); + break; + default: + WLAN_LOG_WARNING( + "Unknown info type=0x%02x\n", inf->infotype); + break; + } + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* prism2sta_ev_txexc +* +* Handles the TxExc event. A Transmit Exception event indicates +* that the MAC's TX process was unsuccessful - so the packet did +* not get transmitted. +* +* Arguments: +* wlandev wlan device structure +* status tx frame status word +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +void prism2sta_ev_txexc(wlandevice_t *wlandev, UINT16 status) +{ + DBFENTER; + + WLAN_LOG_DEBUG(3, "TxExc status=0x%x.\n", status); + + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* prism2sta_ev_tx +* +* Handles the Tx event. +* +* Arguments: +* wlandev wlan device structure +* status tx frame status word +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +void prism2sta_ev_tx(wlandevice_t *wlandev, UINT16 status) +{ + DBFENTER; + WLAN_LOG_DEBUG(4, "Tx Complete, status=0x%04x\n", status); + /* update linux network stats */ + wlandev->linux_stats.tx_packets++; + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* prism2sta_ev_rx +* +* Handles the Rx event. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +void prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb) +{ + DBFENTER; + + p80211netdev_rx(wlandev, skb); + + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* prism2sta_ev_alloc +* +* Handles the Alloc event. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +void prism2sta_ev_alloc(wlandevice_t *wlandev) +{ + DBFENTER; + + p80211netdev_wake_queue(wlandev); + + DBFEXIT; + return; +} + +#if (WLAN_HOSTIF == WLAN_PLX || WLAN_HOSTIF == WLAN_PCI) +#ifdef CONFIG_PM +static int prism2sta_suspend_pci(struct pci_dev *pdev, pm_message_t state) +{ + wlandevice_t *wlandev; + + wlandev = (wlandevice_t *) pci_get_drvdata(pdev); + + /* reset hardware */ + if (wlandev) { + prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable); + p80211_suspend(wlandev); + } + + // call a netif_device_detach(wlandev->netdev) ? + + return 0; +} + +static int prism2sta_resume_pci (struct pci_dev *pdev) +{ + wlandevice_t *wlandev; + + wlandev = (wlandevice_t *) pci_get_drvdata(pdev); + + if (wlandev) { + p80211_resume(wlandev); + prism2sta_ifstate(wlandev, P80211ENUM_ifstate_enable); + } + + return 0; +} +#endif +#endif + +/*---------------------------------------------------------------- +* create_wlan +* +* Called at module init time. This creates the wlandevice_t structure +* and initializes it with relevant bits. +* +* Arguments: +* none +* +* Returns: +* the created wlandevice_t structure. +* +* Side effects: +* also allocates the priv/hw structures. +* +* Call context: +* process thread +* +----------------------------------------------------------------*/ +static wlandevice_t *create_wlan(void) +{ + wlandevice_t *wlandev = NULL; + hfa384x_t *hw = NULL; + + /* Alloc our structures */ + wlandev = kmalloc(sizeof(wlandevice_t), GFP_KERNEL); + hw = kmalloc(sizeof(hfa384x_t), GFP_KERNEL); + + if (!wlandev || !hw) { + WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info); + if (wlandev) kfree(wlandev); + if (hw) kfree(hw); + return NULL; + } + + /* Clear all the structs */ + memset(wlandev, 0, sizeof(wlandevice_t)); + memset(hw, 0, sizeof(hfa384x_t)); + + /* Initialize the network device object. */ + wlandev->nsdname = dev_info; + wlandev->msdstate = WLAN_MSD_HWPRESENT_PENDING; + wlandev->priv = hw; + wlandev->open = prism2sta_open; + wlandev->close = prism2sta_close; + wlandev->reset = prism2sta_reset; +#ifdef CONFIG_PROC_FS + wlandev->nsd_proc_read = prism2sta_proc_read; +#endif + wlandev->txframe = prism2sta_txframe; + wlandev->mlmerequest = prism2sta_mlmerequest; + wlandev->set_multicast_list = prism2sta_setmulticast; + wlandev->tx_timeout = hfa384x_tx_timeout; + + wlandev->nsdcaps = P80211_NSDCAP_HWFRAGMENT | + P80211_NSDCAP_AUTOJOIN; + + /* Initialize the device private data stucture. */ + hw->dot11_desired_bss_type = 1; + + return wlandev; +} + +#ifdef CONFIG_PROC_FS +static int +prism2sta_proc_read( + char *page, + char **start, + off_t offset, + int count, + int *eof, + void *data) +{ + char *p = page; + wlandevice_t *wlandev = (wlandevice_t *) data; + hfa384x_t *hw = (hfa384x_t *) wlandev->priv; + + UINT16 hwtype = 0; + + DBFENTER; + if (offset != 0) { + *eof = 1; + goto exit; + } + + // XXX 0x0001 for prism2.5/3, 0x0000 for prism2. + hwtype = BIT0; + +#if (WLAN_HOSTIF != WLAN_USB) + if (hw->isram16) + hwtype |= BIT1; +#endif + +#if (WLAN_HOSTIF == WLAN_PCI) + hwtype |= BIT2; +#endif + +#define PRISM2_CVS_ID "$Id: prism2sta.c 1858 2008-03-24 18:49:31Z pizza $" + + p += sprintf(p, "# %s version %s (%s) '%s'\n\n", + dev_info, + WLAN_RELEASE, WLAN_BUILD_DATE, PRISM2_CVS_ID); + + p += sprintf(p, "# nic h/w: id=0x%02x %d.%d.%d\n", + hw->ident_nic.id, hw->ident_nic.major, + hw->ident_nic.minor, hw->ident_nic.variant); + + p += sprintf(p, "# pri f/w: id=0x%02x %d.%d.%d\n", + hw->ident_pri_fw.id, hw->ident_pri_fw.major, + hw->ident_pri_fw.minor, hw->ident_pri_fw.variant); + + if (hw->ident_sta_fw.id == 0x1f) { + p += sprintf(p, "# sta f/w: id=0x%02x %d.%d.%d\n", + hw->ident_sta_fw.id, hw->ident_sta_fw.major, + hw->ident_sta_fw.minor, hw->ident_sta_fw.variant); + } else { + p += sprintf(p, "# ap f/w: id=0x%02x %d.%d.%d\n", + hw->ident_sta_fw.id, hw->ident_sta_fw.major, + hw->ident_sta_fw.minor, hw->ident_sta_fw.variant); + } + +#if (WLAN_HOSTIF != WLAN_USB) + p += sprintf(p, "# initial nic hw type, needed for SSF ramdl\n"); + p += sprintf(p, "initnichw=%04x\n", hwtype); +#endif + + exit: + DBFEXIT; + return (p - page); +} +#endif + +void prism2sta_commsqual_defer(struct work_struct *data) +{ + hfa384x_t *hw = container_of(data, struct hfa384x, commsqual_bh); + wlandevice_t *wlandev = hw->wlandev; + hfa384x_bytestr32_t ssid; + int result = 0; + + DBFENTER; + + if (hw->wlandev->hwremoved) + goto done; + + /* we don't care if we're in AP mode */ + if ((wlandev->macmode == WLAN_MACMODE_NONE) || + (wlandev->macmode == WLAN_MACMODE_ESS_AP)) { + goto done; + } + + /* It only makes sense to poll these in non-IBSS */ + if (wlandev->macmode != WLAN_MACMODE_IBSS_STA) { + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DBMCOMMSQUALITY, + &hw->qual, + HFA384x_RID_DBMCOMMSQUALITY_LEN); + + if (result) { + WLAN_LOG_ERROR("error fetching commsqual\n"); + goto done; + } + + // qual.CQ_currBSS; // link + // ASL_currBSS; // level + // qual.ANL_currFC; // noise + + WLAN_LOG_DEBUG(3, "commsqual %d %d %d\n", + hfa384x2host_16(hw->qual.CQ_currBSS), + hfa384x2host_16(hw->qual.ASL_currBSS), + hfa384x2host_16(hw->qual.ANL_currFC)); + } + + /* Lastly, we need to make sure the BSSID didn't change on us */ + result = hfa384x_drvr_getconfig(hw, + HFA384x_RID_CURRENTBSSID, + wlandev->bssid, WLAN_BSSID_LEN); + if ( result ) { + WLAN_LOG_DEBUG(1, + "getconfig(0x%02x) failed, result = %d\n", + HFA384x_RID_CURRENTBSSID, result); + goto done; + } + + result = hfa384x_drvr_getconfig(hw, + HFA384x_RID_CURRENTSSID, + &ssid, sizeof(ssid)); + if ( result ) { + WLAN_LOG_DEBUG(1, + "getconfig(0x%02x) failed, result = %d\n", + HFA384x_RID_CURRENTSSID, result); + goto done; + } + prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *)&ssid, + (p80211pstrd_t *) &wlandev->ssid); + + + /* Reschedule timer */ + mod_timer(&hw->commsqual_timer, round_jiffies(jiffies + HZ)); + + done: + DBFEXIT; +} + +void prism2sta_commsqual_timer(unsigned long data) +{ + hfa384x_t *hw = (hfa384x_t *) data; + + DBFENTER; + + schedule_work(&hw->commsqual_bh); + + DBFEXIT; +} --- linux-2.6.28.orig/ubuntu/misc/wireless/prism2_usb/prism2mgmt.c +++ linux-2.6.28/ubuntu/misc/wireless/prism2_usb/prism2mgmt.c @@ -0,0 +1,2956 @@ +/* src/prism2/driver/prism2mgmt.c +* +* Management request handler functions. +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* The functions in this file handle management requests sent from +* user mode. +* +* Most of these functions have two separate blocks of code that are +* conditional on whether this is a station or an AP. This is used +* to separate out the STA and AP responses to these management primitives. +* It's a choice (good, bad, indifferent?) to have the code in the same +* place so it's clear that the same primitive is implemented in both +* cases but has different behavior. +* +* -------------------------------------------------------------------- +*/ + +/*================================================================*/ +/* System Includes */ +#define WLAN_DBVAR prism2_debug + +#include + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if (WLAN_HOSTIF == WLAN_USB) +#include +#endif + +#if (WLAN_HOSTIF == WLAN_PCMCIA) +#include +#include +#include +#include +#include +#include +#endif + +#include + +/*================================================================*/ +/* Project Includes */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*================================================================*/ +/* Local Constants */ + + +/*================================================================*/ +/* Local Macros */ + +/* Converts 802.11 format rate specifications to prism2 */ +#define p80211rate_to_p2bit(n) ((((n)&~BIT7) == 2) ? BIT0 : \ + (((n)&~BIT7) == 4) ? BIT1 : \ + (((n)&~BIT7) == 11) ? BIT2 : \ + (((n)&~BIT7) == 22) ? BIT3 : 0) + +/*================================================================*/ +/* Local Types */ + + +/*================================================================*/ +/* Local Static Definitions */ + + +/*================================================================*/ +/* Local Function Declarations */ + + +/*================================================================*/ +/* Function Definitions */ + + +/*---------------------------------------------------------------- +* prism2mgmt_powermgmt +* +* Set the power management state of this station's MAC. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_powermgmt(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + hfa384x_t *hw = wlandev->priv; + p80211msg_dot11req_powermgmt_t *msg = msgp; + + DBFENTER; + + if (!hw->ap) { + + /*** STATION ***/ + + /* + * Set CNFPMENABLED (on or off) + * Set CNFMULTICASTRX (if PM on, otherwise clear) + * Spout a notice stating that SleepDuration and + * HoldoverDuration and PMEPS also have an impact. + */ + /* Powermgmt is currently unsupported for STA */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } else { + + /*** ACCESS POINT ***/ + + /* Powermgmt is never supported for AP */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_scan +* +* Initiate a scan for BSSs. +* +* This function corresponds to MLME-scan.request and part of +* MLME-scan.confirm. As far as I can tell in the standard, there +* are no restrictions on when a scan.request may be issued. We have +* to handle in whatever state the driver/MAC happen to be. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + hfa384x_t *hw = wlandev->priv; + p80211msg_dot11req_scan_t *msg = msgp; + UINT16 roamingmode, word; + int i, timeout; + int istmpenable = 0; + + hfa384x_HostScanRequest_data_t scanreq; + + DBFENTER; + + if (hw->ap) { + WLAN_LOG_ERROR("Prism2 in AP mode cannot perform scans.\n"); + result = 1; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + goto exit; + } + + /* gatekeeper check */ + if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major, + hw->ident_sta_fw.minor, + hw->ident_sta_fw.variant) < + HFA384x_FIRMWARE_VERSION(1,3,2)) { + WLAN_LOG_ERROR("HostScan not supported with current firmware (<1.3.2).\n"); + result = 1; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + goto exit; + } + + memset(&scanreq, 0, sizeof(scanreq)); + + /* save current roaming mode */ + result = hfa384x_drvr_getconfig16(hw, + HFA384x_RID_CNFROAMINGMODE, &roamingmode); + if ( result ) { + WLAN_LOG_ERROR("getconfig(ROAMMODE) failed. result=%d\n", + result); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + goto exit; + } + + /* drop into mode 3 for the scan */ + result = hfa384x_drvr_setconfig16(hw, + HFA384x_RID_CNFROAMINGMODE, + HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM); + if ( result ) { + WLAN_LOG_ERROR("setconfig(ROAMINGMODE) failed. result=%d\n", + result); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + goto exit; + } + + /* active or passive? */ + if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major, + hw->ident_sta_fw.minor, + hw->ident_sta_fw.variant) > + HFA384x_FIRMWARE_VERSION(1,5,0)) { + if (msg->scantype.data != P80211ENUM_scantype_active) { + word = host2hfa384x_16(msg->maxchanneltime.data); + } else { + word = 0; + } + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPASSIVESCANCTRL, word); + if ( result ) { + WLAN_LOG_WARNING("Passive scan not supported with " + "current firmware. (<1.5.1)\n"); + } + } + + /* set up the txrate to be 2MBPS. Should be fastest basicrate... */ + word = HFA384x_RATEBIT_2; + scanreq.txRate = host2hfa384x_16(word); + + /* set up the channel list */ + word = 0; + for (i = 0; i < msg->channellist.data.len; i++) { + UINT8 channel = msg->channellist.data.data[i]; + if (channel > 14) continue; + /* channel 1 is BIT0 ... channel 14 is BIT13 */ + word |= (1 << (channel-1)); + } + scanreq.channelList = host2hfa384x_16(word); + + /* set up the ssid, if present. */ + scanreq.ssid.len = host2hfa384x_16(msg->ssid.data.len); + memcpy(scanreq.ssid.data, msg->ssid.data.data, msg->ssid.data.len); + + /* Enable the MAC port if it's not already enabled */ + result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_PORTSTATUS, &word); + if ( result ) { + WLAN_LOG_ERROR("getconfig(PORTSTATUS) failed. " + "result=%d\n", result); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + goto exit; + } + if (word == HFA384x_PORTSTATUS_DISABLED) { + UINT16 wordbuf[17]; + + result = hfa384x_drvr_setconfig16(hw, + HFA384x_RID_CNFROAMINGMODE, + HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM); + if ( result ) { + WLAN_LOG_ERROR("setconfig(ROAMINGMODE) failed. result=%d\n", result); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + goto exit; + } + /* Construct a bogus SSID and assign it to OwnSSID and + * DesiredSSID + */ + wordbuf[0] = host2hfa384x_16(WLAN_SSID_MAXLEN); + get_random_bytes(&wordbuf[1], WLAN_SSID_MAXLEN); + result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFOWNSSID, + wordbuf, HFA384x_RID_CNFOWNSSID_LEN); + if ( result ) { + WLAN_LOG_ERROR("Failed to set OwnSSID.\n"); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + goto exit; + } + result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFDESIREDSSID, + wordbuf, HFA384x_RID_CNFDESIREDSSID_LEN); + if ( result ) { + WLAN_LOG_ERROR("Failed to set DesiredSSID.\n"); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + goto exit; + } + /* bsstype */ + result = hfa384x_drvr_setconfig16(hw, + HFA384x_RID_CNFPORTTYPE, + HFA384x_PORTTYPE_IBSS); + if ( result ) { + WLAN_LOG_ERROR("Failed to set CNFPORTTYPE.\n"); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + goto exit; + } + /* ibss options */ + result = hfa384x_drvr_setconfig16(hw, + HFA384x_RID_CREATEIBSS, + HFA384x_CREATEIBSS_JOINCREATEIBSS); + if ( result ) { + WLAN_LOG_ERROR("Failed to set CREATEIBSS.\n"); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + goto exit; + } + result = hfa384x_drvr_enable(hw, 0); + if ( result ) { + WLAN_LOG_ERROR("drvr_enable(0) failed. " + "result=%d\n", result); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + goto exit; + } + istmpenable = 1; + } + + /* Figure out our timeout first Kus, then HZ */ + timeout = msg->channellist.data.len * msg->maxchanneltime.data; + timeout = (timeout * HZ)/1000; + + /* Issue the scan request */ + hw->scanflag = 0; + + WLAN_HEX_DUMP(5,"hscanreq", &scanreq, sizeof(scanreq)); + + result = hfa384x_drvr_setconfig( hw, + HFA384x_RID_HOSTSCAN, &scanreq, + sizeof(hfa384x_HostScanRequest_data_t)); + if ( result ) { + WLAN_LOG_ERROR("setconfig(SCANREQUEST) failed. result=%d\n", + result); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + goto exit; + } + + /* sleep until info frame arrives */ + wait_event_interruptible_timeout(hw->cmdq, hw->scanflag, timeout); + + msg->numbss.status = P80211ENUM_msgitem_status_data_ok; + if (hw->scanflag == -1) + hw->scanflag = 0; + + msg->numbss.data = hw->scanflag; + + hw->scanflag = 0; + + /* Disable port if we temporarily enabled it. */ + if (istmpenable) { + result = hfa384x_drvr_disable(hw, 0); + if ( result ) { + WLAN_LOG_ERROR("drvr_disable(0) failed. " + "result=%d\n", result); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + goto exit; + } + } + + /* restore original roaming mode */ + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFROAMINGMODE, + roamingmode); + if ( result ) { + WLAN_LOG_ERROR("setconfig(ROAMMODE) failed. result=%d\n", + result); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + goto exit; + } + + result = 0; + msg->resultcode.data = P80211ENUM_resultcode_success; + + exit: + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_scan_results +* +* Retrieve the BSS description for one of the BSSs identified in +* a scan. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + p80211msg_dot11req_scan_results_t *req; + hfa384x_t *hw = wlandev->priv; + hfa384x_HScanResultSub_t *item = NULL; + + int count; + + DBFENTER; + + req = (p80211msg_dot11req_scan_results_t *) msgp; + + req->resultcode.status = P80211ENUM_msgitem_status_data_ok; + + if (hw->ap) { + result = 1; + req->resultcode.data = P80211ENUM_resultcode_not_supported; + goto exit; + } + + if (! hw->scanresults) { + WLAN_LOG_ERROR("dot11req_scan_results can only be used after a successful dot11req_scan.\n"); + result = 2; + req->resultcode.data = P80211ENUM_resultcode_invalid_parameters; + goto exit; + } + + count = (hw->scanresults->framelen - 3) / 32; + if (count > 32) count = 32; + + if (req->bssindex.data >= count) { + WLAN_LOG_DEBUG(0, "requested index (%d) out of range (%d)\n", + req->bssindex.data, count); + result = 2; + req->resultcode.data = P80211ENUM_resultcode_invalid_parameters; + goto exit; + } + + item = &(hw->scanresults->info.hscanresult.result[req->bssindex.data]); + /* signal and noise */ + req->signal.status = P80211ENUM_msgitem_status_data_ok; + req->noise.status = P80211ENUM_msgitem_status_data_ok; + req->signal.data = hfa384x2host_16(item->sl); + req->noise.data = hfa384x2host_16(item->anl); + + /* BSSID */ + req->bssid.status = P80211ENUM_msgitem_status_data_ok; + req->bssid.data.len = WLAN_BSSID_LEN; + memcpy(req->bssid.data.data, item->bssid, WLAN_BSSID_LEN); + + /* SSID */ + req->ssid.status = P80211ENUM_msgitem_status_data_ok; + req->ssid.data.len = hfa384x2host_16(item->ssid.len); + memcpy(req->ssid.data.data, item->ssid.data, req->ssid.data.len); + + /* supported rates */ + for (count = 0; count < 10 ; count++) + if (item->supprates[count] == 0) + break; + +#define REQBASICRATE(N) \ + if ((count >= N) && DOT11_RATE5_ISBASIC_GET(item->supprates[(N)-1])) { \ + req->basicrate ## N .data = item->supprates[(N)-1]; \ + req->basicrate ## N .status = P80211ENUM_msgitem_status_data_ok; \ + } + + REQBASICRATE(1); + REQBASICRATE(2); + REQBASICRATE(3); + REQBASICRATE(4); + REQBASICRATE(5); + REQBASICRATE(6); + REQBASICRATE(7); + REQBASICRATE(8); + +#define REQSUPPRATE(N) \ + if (count >= N) { \ + req->supprate ## N .data = item->supprates[(N)-1]; \ + req->supprate ## N .status = P80211ENUM_msgitem_status_data_ok; \ + } + + REQSUPPRATE(1); + REQSUPPRATE(2); + REQSUPPRATE(3); + REQSUPPRATE(4); + REQSUPPRATE(5); + REQSUPPRATE(6); + REQSUPPRATE(7); + REQSUPPRATE(8); + + /* beacon period */ + req->beaconperiod.status = P80211ENUM_msgitem_status_data_ok; + req->beaconperiod.data = hfa384x2host_16(item->bcnint); + + /* timestamps */ + req->timestamp.status = P80211ENUM_msgitem_status_data_ok; + req->timestamp.data = jiffies; + req->localtime.status = P80211ENUM_msgitem_status_data_ok; + req->localtime.data = jiffies; + + /* atim window */ + req->ibssatimwindow.status = P80211ENUM_msgitem_status_data_ok; + req->ibssatimwindow.data = hfa384x2host_16(item->atim); + + /* Channel */ + req->dschannel.status = P80211ENUM_msgitem_status_data_ok; + req->dschannel.data = hfa384x2host_16(item->chid); + + /* capinfo bits */ + count = hfa384x2host_16(item->capinfo); + + /* privacy flag */ + req->privacy.status = P80211ENUM_msgitem_status_data_ok; + req->privacy.data = WLAN_GET_MGMT_CAP_INFO_PRIVACY(count); + + /* cfpollable */ + req->cfpollable.status = P80211ENUM_msgitem_status_data_ok; + req->cfpollable.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(count); + + /* cfpollreq */ + req->cfpollreq.status = P80211ENUM_msgitem_status_data_ok; + req->cfpollreq.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(count); + + /* bsstype */ + req->bsstype.status = P80211ENUM_msgitem_status_data_ok; + req->bsstype.data = (WLAN_GET_MGMT_CAP_INFO_ESS(count)) ? + P80211ENUM_bsstype_infrastructure : + P80211ENUM_bsstype_independent; + + // item->proberesp_rate +/* + req->fhdwelltime + req->fhhopset + req->fhhoppattern + req->fhhopindex + req->cfpdurremaining +*/ + + result = 0; + req->resultcode.data = P80211ENUM_resultcode_success; + + exit: + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_join +* +* Join a BSS whose BSS description was previously obtained with +* a scan. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_join(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + hfa384x_t *hw = wlandev->priv; + p80211msg_dot11req_join_t *msg = msgp; + DBFENTER; + + if (!hw->ap) { + + /*** STATION ***/ + + /* TODO: Implement after scan */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } else { + + /*** ACCESS POINT ***/ + + /* Never supported by APs */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_p2_join +* +* Join a specific BSS +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_p2_join(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_join_t *msg = msgp; + UINT16 reg; + p80211pstrd_t *pstr; + UINT8 bytebuf[256]; + hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t*)bytebuf; + hfa384x_JoinRequest_data_t joinreq; + DBFENTER; + + if (!hw->ap) { + + wlandev->macmode = WLAN_MACMODE_NONE; + + /*** STATION ***/ + /* Set the PortType */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_success; + + /* ess port */ + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, 1); + if ( result ) { + WLAN_LOG_ERROR("Failed to set Port Type\n"); + goto failed; + } + + /* Set the auth type */ + if ( msg->authtype.data == P80211ENUM_authalg_sharedkey ) { + reg = HFA384x_CNFAUTHENTICATION_SHAREDKEY; + } else { + reg = HFA384x_CNFAUTHENTICATION_OPENSYSTEM; + } + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAUTHENTICATION, reg); + if ( result ) { + WLAN_LOG_ERROR("Failed to set Authentication\n"); + goto failed; + } + + /* Turn off all roaming */ + hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFROAMINGMODE, 3); + if ( result ) { + WLAN_LOG_ERROR("Failed to Turn off Roaming\n"); + goto failed; + } + + /* Basic rates */ + reg = 0; + if ( msg->basicrate1.status == P80211ENUM_msgitem_status_data_ok ) { + reg = p80211rate_to_p2bit(msg->basicrate1.data); + } + if ( msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->basicrate2.data); + } + if ( msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->basicrate3.data); + } + if ( msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->basicrate4.data); + } + if ( msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->basicrate5.data); + } + if ( msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->basicrate6.data); + } + if ( msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->basicrate7.data); + } + if ( msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->basicrate8.data); + } + if( reg == 0) + reg = 0x03; + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFBASICRATES, reg); + if ( result ) { + WLAN_LOG_ERROR("Failed to set basicrates=%d.\n", reg); + goto failed; + } + + /* Operational rates (supprates and txratecontrol) */ + reg = 0; + if ( msg->operationalrate1.status == P80211ENUM_msgitem_status_data_ok ) { + reg = p80211rate_to_p2bit(msg->operationalrate1.data); + } + if ( msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->operationalrate2.data); + } + if ( msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->operationalrate3.data); + } + if ( msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->operationalrate4.data); + } + if ( msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->operationalrate5.data); + } + if ( msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->operationalrate6.data); + } + if ( msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->operationalrate7.data); + } + if ( msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->operationalrate8.data); + } + if( reg == 0) + reg = 0x0f; + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, reg); + if ( result ) { + WLAN_LOG_ERROR("Failed to set supprates=%d.\n", reg); + goto failed; + } + + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, reg); + if ( result ) { + WLAN_LOG_ERROR("Failed to set txrates=%d.\n", reg); + goto failed; + } + + /* Set the ssid */ + memset(bytebuf, 0, 256); + pstr = (p80211pstrd_t*)&(msg->ssid.data); + prism2mgmt_pstr2bytestr(p2bytestr, pstr); + result = hfa384x_drvr_setconfig( + hw, HFA384x_RID_CNFDESIREDSSID, + bytebuf, HFA384x_RID_CNFDESIREDSSID_LEN); + if ( result ) { + WLAN_LOG_ERROR("Failed to set SSID\n"); + goto failed; + } + + /* Enable the Port */ + result = hfa384x_cmd_enable(hw, 0); + if ( result ) { + WLAN_LOG_ERROR("Enable macport failed, result=%d.\n", result); + goto failed; + } + + /* Fill in the join request */ + joinreq.channel = msg->channel.data; + memcpy( joinreq.bssid, ((unsigned char *) &msg->bssid.data) + 1, WLAN_BSSID_LEN); + hw->joinreq = joinreq; + hw->join_ap = 1; + + /* Send the join request */ + result = hfa384x_drvr_setconfig( hw, + HFA384x_RID_JOINREQUEST, + &joinreq, HFA384x_RID_JOINREQUEST_LEN); + if(result != 0) { + WLAN_LOG_ERROR("Join request failed, result=%d.\n", result); + goto failed; + } + + } else { + + /*** ACCESS POINT ***/ + + /* Never supported by APs */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } + + goto done; +failed: + WLAN_LOG_DEBUG(1, "Failed to set a config option, result=%d\n", result); + msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters; + +done: + result = 0; + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_authenticate +* +* Station should be begin an authentication exchange. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_authenticate(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + hfa384x_t *hw = wlandev->priv; + p80211msg_dot11req_authenticate_t *msg = msgp; + DBFENTER; + + if (!hw->ap) { + + /*** STATION ***/ + + /* TODO: Decide how we're going to handle this one w/ Prism2 */ + /* It could be entertaining since Prism2 doesn't have */ + /* an explicit way to control this */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } else { + + /*** ACCESS POINT ***/ + + /* Never supported by APs */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_deauthenticate +* +* Send a deauthenticate notification. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_deauthenticate(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + hfa384x_t *hw = wlandev->priv; + p80211msg_dot11req_deauthenticate_t *msg = msgp; + DBFENTER; + + if (!hw->ap) { + + /*** STATION ***/ + + /* TODO: Decide how we're going to handle this one w/ Prism2 */ + /* It could be entertaining since Prism2 doesn't have */ + /* an explicit way to control this */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } else { + + /*** ACCESS POINT ***/ + hfa384x_drvr_handover(hw, msg->peerstaaddress.data.data); + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_success; + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_associate +* +* Associate with an ESS. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_associate(wlandevice_t *wlandev, void *msgp) +{ + hfa384x_t *hw = wlandev->priv; + int result = 0; + p80211msg_dot11req_associate_t *msg = msgp; + DBFENTER; + + if (!hw->ap) { + + /*** STATION ***/ + +#if 0 + /* Set the TxRates */ + reg = 0x000f; + hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, reg); +#endif + + /* Set the PortType */ + /* ess port */ + hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, 1); + + /* Enable the Port */ + hfa384x_drvr_enable(hw, 0); + + /* Set the resultcode */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_success; + + } else { + + /*** ACCESS POINT ***/ + + /* Never supported on AP */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_reassociate +* +* Renew association because of a BSS change. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_reassociate(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + hfa384x_t *hw = wlandev->priv; + p80211msg_dot11req_reassociate_t *msg = msgp; + DBFENTER; + + if (!hw->ap) { + + /*** STATION ***/ + + /* TODO: Not supported yet...not sure how we're going to do it */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } else { + + /*** ACCESS POINT ***/ + + /* Never supported on AP */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_disassociate +* +* Send a disassociation notification. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_disassociate(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + hfa384x_t *hw = wlandev->priv; + p80211msg_dot11req_disassociate_t *msg = msgp; + DBFENTER; + + if (!hw->ap) { + + /*** STATION ***/ + + /* TODO: Not supported yet...not sure how to do it */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } else { + + /*** ACCESS POINT ***/ + hfa384x_drvr_handover(hw, msg->peerstaaddress.data.data); + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_success; + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_reset +* +* Reset the MAC and MSD. The p80211 layer has it's own handling +* that should be done before and after this function. +* Procedure: +* - disable system interrupts ?? +* - disable MAC interrupts +* - restore system interrupts +* - issue the MAC initialize command +* - clear any MSD level state (including timers, queued events, +* etc.). Note that if we're removing timer'd/queue events, we may +* need to have remained in the system interrupt disabled state. +* We should be left in the same state that we're in following +* driver initialization. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer, MAY BE NULL! for a driver local +* call. +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread, commonly wlanctl, but might be rmmod/pci_close. +----------------------------------------------------------------*/ +int prism2mgmt_reset(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + hfa384x_t *hw = wlandev->priv; + p80211msg_dot11req_reset_t *msg = msgp; + DBFENTER; + + /* + * This is supported on both AP and STA and it's not allowed + * to fail. + */ + if ( msgp ) { + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_success; + WLAN_LOG_INFO("dot11req_reset: the macaddress and " + "setdefaultmib arguments are currently unsupported.\n"); + } + + /* + * If we got this far, the MSD must be in the MSDRUNNING state + * therefore, we must stop and then restart the hw/MAC combo. + */ + hfa384x_drvr_stop(hw); + result = hfa384x_drvr_start(hw); + if (result != 0) { + WLAN_LOG_ERROR("dot11req_reset: Initialize command failed," + " bad things will happen from here.\n"); + return 0; + } + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_start +* +* Start a BSS. Any station can do this for IBSS, only AP for ESS. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_start(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + hfa384x_t *hw = wlandev->priv; + p80211msg_dot11req_start_t *msg = msgp; + + p80211pstrd_t *pstr; + UINT8 bytebuf[80]; + hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t*)bytebuf; + hfa384x_PCFInfo_data_t *pcfinfo = (hfa384x_PCFInfo_data_t*)bytebuf; + UINT16 word; + DBFENTER; + + wlandev->macmode = WLAN_MACMODE_NONE; + + /* Set the SSID */ + memcpy(&wlandev->ssid, &msg->ssid.data, sizeof(msg->ssid.data)); + + if (!hw->ap) { + /*** ADHOC IBSS ***/ + /* see if current f/w is less than 8c3 */ + if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major, + hw->ident_sta_fw.minor, + hw->ident_sta_fw.variant) < + HFA384x_FIRMWARE_VERSION(0,8,3)) { + /* Ad-Hoc not quite supported on Prism2 */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + goto done; + } + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + + /*** STATION ***/ + /* Set the REQUIRED config items */ + /* SSID */ + pstr = (p80211pstrd_t*)&(msg->ssid.data); + prism2mgmt_pstr2bytestr(p2bytestr, pstr); + result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFOWNSSID, + bytebuf, HFA384x_RID_CNFOWNSSID_LEN); + if ( result ) { + WLAN_LOG_ERROR("Failed to set CnfOwnSSID\n"); + goto failed; + } + result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFDESIREDSSID, + bytebuf, HFA384x_RID_CNFDESIREDSSID_LEN); + if ( result ) { + WLAN_LOG_ERROR("Failed to set CnfDesiredSSID\n"); + goto failed; + } + + /* bsstype - we use the default in the ap firmware */ + /* IBSS port */ + hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, 0); + + /* beacon period */ + word = msg->beaconperiod.data; + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAPBCNINT, word); + if ( result ) { + WLAN_LOG_ERROR("Failed to set beacon period=%d.\n", word); + goto failed; + } + + /* dschannel */ + word = msg->dschannel.data; + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFOWNCHANNEL, word); + if ( result ) { + WLAN_LOG_ERROR("Failed to set channel=%d.\n", word); + goto failed; + } + /* Basic rates */ + word = p80211rate_to_p2bit(msg->basicrate1.data); + if ( msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate2.data); + } + if ( msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate3.data); + } + if ( msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate4.data); + } + if ( msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate5.data); + } + if ( msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate6.data); + } + if ( msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate7.data); + } + if ( msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate8.data); + } + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFBASICRATES, word); + if ( result ) { + WLAN_LOG_ERROR("Failed to set basicrates=%d.\n", word); + goto failed; + } + + /* Operational rates (supprates and txratecontrol) */ + word = p80211rate_to_p2bit(msg->operationalrate1.data); + if ( msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate2.data); + } + if ( msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate3.data); + } + if ( msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate4.data); + } + if ( msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate5.data); + } + if ( msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate6.data); + } + if ( msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate7.data); + } + if ( msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate8.data); + } + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, word); + if ( result ) { + WLAN_LOG_ERROR("Failed to set supprates=%d.\n", word); + goto failed; + } + + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, word); + if ( result ) { + WLAN_LOG_ERROR("Failed to set txrates=%d.\n", word); + goto failed; + } + + /* Set the macmode so the frame setup code knows what to do */ + if ( msg->bsstype.data == P80211ENUM_bsstype_independent ) { + wlandev->macmode = WLAN_MACMODE_IBSS_STA; + /* lets extend the data length a bit */ + hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, 2304); + } + + /* Enable the Port */ + result = hfa384x_drvr_enable(hw, 0); + if ( result ) { + WLAN_LOG_ERROR("Enable macport failed, result=%d.\n", result); + goto failed; + } + + msg->resultcode.data = P80211ENUM_resultcode_success; + + goto done; + } + + /*** ACCESS POINT ***/ + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + + /* Validate the command, if BSStype=infra is the tertiary loaded? */ + if ( msg->bsstype.data == P80211ENUM_bsstype_independent ) { + WLAN_LOG_ERROR("AP driver cannot create IBSS.\n"); + goto failed; + } else if ( hw->cap_sup_sta.id != 5) { + WLAN_LOG_ERROR("AP driver failed to detect AP firmware.\n"); + goto failed; + } + + /* Set the REQUIRED config items */ + /* SSID */ + pstr = (p80211pstrd_t*)&(msg->ssid.data); + prism2mgmt_pstr2bytestr(p2bytestr, pstr); + result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFOWNSSID, + bytebuf, HFA384x_RID_CNFOWNSSID_LEN); + if ( result ) { + WLAN_LOG_ERROR("Failed to set SSID, result=0x%04x\n", result); + goto failed; + } + + /* bsstype - we use the default in the ap firmware */ + + /* beacon period */ + word = msg->beaconperiod.data; + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAPBCNINT, word); + if ( result ) { + WLAN_LOG_ERROR("Failed to set beacon period=%d.\n", word); + goto failed; + } + + /* dschannel */ + word = msg->dschannel.data; + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFOWNCHANNEL, word); + if ( result ) { + WLAN_LOG_ERROR("Failed to set channel=%d.\n", word); + goto failed; + } + /* Basic rates */ + word = p80211rate_to_p2bit(msg->basicrate1.data); + if ( msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate2.data); + } + if ( msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate3.data); + } + if ( msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate4.data); + } + if ( msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate5.data); + } + if ( msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate6.data); + } + if ( msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate7.data); + } + if ( msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate8.data); + } + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFBASICRATES, word); + if ( result ) { + WLAN_LOG_ERROR("Failed to set basicrates=%d.\n", word); + goto failed; + } + + /* Operational rates (supprates and txratecontrol) */ + word = p80211rate_to_p2bit(msg->operationalrate1.data); + if ( msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate2.data); + } + if ( msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate3.data); + } + if ( msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate4.data); + } + if ( msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate5.data); + } + if ( msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate6.data); + } + if ( msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate7.data); + } + if ( msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate8.data); + } + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, word); + if ( result ) { + WLAN_LOG_ERROR("Failed to set supprates=%d.\n", word); + goto failed; + } + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL0, word); + if ( result ) { + WLAN_LOG_ERROR("Failed to set txrates=%d.\n", word); + goto failed; + } + + /* ibssatimwindow */ + if (msg->ibssatimwindow.status == P80211ENUM_msgitem_status_data_ok) { + WLAN_LOG_INFO("prism2mgmt_start: atimwindow not used in " + "Infrastructure mode, ignored.\n"); + } + + /* DTIM period */ + word = msg->dtimperiod.data; + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFOWNDTIMPER, word); + if ( result ) { + WLAN_LOG_ERROR("Failed to set dtim period=%d.\n", word); + goto failed; + } + + /* probedelay */ + if (msg->probedelay.status == P80211ENUM_msgitem_status_data_ok) { + WLAN_LOG_INFO("prism2mgmt_start: probedelay not " + "supported in prism2, ignored.\n"); + } + + /* cfpollable, cfpollreq, cfpperiod, cfpmaxduration */ + if (msg->cfpollable.data == P80211ENUM_truth_true && + msg->cfpollreq.data == P80211ENUM_truth_true ) { + WLAN_LOG_ERROR("cfpollable=cfpollreq=true is illegal.\n"); + result = -1; + goto failed; + } + + /* read the PCFInfo and update */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CNFAPPCFINFO, + pcfinfo, HFA384x_RID_CNFAPPCFINFO_LEN); + if ( result ) { + WLAN_LOG_INFO("prism2mgmt_start: read(pcfinfo) failed, " + "assume it's " + "not supported, pcf settings ignored.\n"); + goto pcf_skip; + } + if ((msg->cfpollable.data == P80211ENUM_truth_false && + msg->cfpollreq.data == P80211ENUM_truth_false) ) { + pcfinfo->MediumOccupancyLimit = 0; + pcfinfo->CFPPeriod = 0; + pcfinfo->CFPMaxDuration = 0; + pcfinfo->CFPFlags &= host2hfa384x_16((UINT16)~BIT0); + + if ( msg->cfpperiod.status == P80211ENUM_msgitem_status_data_ok || + msg->cfpmaxduration.status == P80211ENUM_msgitem_status_data_ok ) { + WLAN_LOG_WARNING( + "Setting cfpperiod or cfpmaxduration when " + "cfpollable and cfreq are false is pointless.\n"); + } + } + if ((msg->cfpollable.data == P80211ENUM_truth_true || + msg->cfpollreq.data == P80211ENUM_truth_true) ) { + if ( msg->cfpollable.data == P80211ENUM_truth_true) { + pcfinfo->CFPFlags |= host2hfa384x_16((UINT16)BIT0); + } + + if ( msg->cfpperiod.status == P80211ENUM_msgitem_status_data_ok) { + pcfinfo->CFPPeriod = msg->cfpperiod.data; + pcfinfo->CFPPeriod = host2hfa384x_16(pcfinfo->CFPPeriod); + } + + if ( msg->cfpmaxduration.status == P80211ENUM_msgitem_status_data_ok) { + pcfinfo->CFPMaxDuration = msg->cfpmaxduration.data; + pcfinfo->CFPMaxDuration = host2hfa384x_16(pcfinfo->CFPMaxDuration); + pcfinfo->MediumOccupancyLimit = pcfinfo->CFPMaxDuration; + } + } + result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFAPPCFINFO, + pcfinfo, HFA384x_RID_CNFAPPCFINFO_LEN); + if ( result ) { + WLAN_LOG_ERROR("write(pcfinfo) failed.\n"); + goto failed; + } + +pcf_skip: + /* Set the macmode so the frame setup code knows what to do */ + if ( msg->bsstype.data == P80211ENUM_bsstype_infrastructure ) { + wlandev->macmode = WLAN_MACMODE_ESS_AP; + /* lets extend the data length a bit */ + hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, 2304); + } + + /* Set the BSSID to the same as our MAC */ + memcpy( wlandev->bssid, wlandev->netdev->dev_addr, WLAN_BSSID_LEN); + + /* Enable the Port */ + result = hfa384x_drvr_enable(hw, 0); + if ( result ) { + WLAN_LOG_ERROR("Enable macport failed, result=%d.\n", result); + goto failed; + } + + msg->resultcode.data = P80211ENUM_resultcode_success; + + goto done; +failed: + WLAN_LOG_DEBUG(1, "Failed to set a config option, result=%d\n", result); + msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters; + +done: + result = 0; + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_enable +* +* Start a BSS. Any station can do this for IBSS, only AP for ESS. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_enable(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_enable_t *msg = msgp; + DBFENTER; + + if (!hw->ap) { + + /*** STATION ***/ + + /* Ad-Hoc not quite supported on Prism2 */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + goto done; + } + + /*** ACCESS POINT ***/ + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + + /* Is the tertiary loaded? */ + if ( hw->cap_sup_sta.id != 5) { + WLAN_LOG_ERROR("AP driver failed to detect AP firmware.\n"); + goto failed; + } + + /* Set the macmode so the frame setup code knows what to do */ + wlandev->macmode = WLAN_MACMODE_ESS_AP; + + /* Set the BSSID to the same as our MAC */ + memcpy( wlandev->bssid, wlandev->netdev->dev_addr, WLAN_BSSID_LEN); + + /* Enable the Port */ + result = hfa384x_drvr_enable(hw, 0); + if ( result ) { + WLAN_LOG_ERROR("Enable macport failed, result=%d.\n", result); + goto failed; + } + + msg->resultcode.data = P80211ENUM_resultcode_success; + + goto done; +failed: + msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters; + +done: + result = 0; + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_readpda +* +* Collect the PDA data and put it in the message. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp) +{ + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_readpda_t *msg = msgp; + int result; + DBFENTER; + + /* We only support collecting the PDA when in the FWLOAD + * state. + */ + if (wlandev->msdstate != WLAN_MSD_FWLOAD) { + WLAN_LOG_ERROR( + "PDA may only be read " + "in the fwload state.\n"); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + } else { + /* Call drvr_readpda(), it handles the auxport enable + * and validating the returned PDA. + */ + result = hfa384x_drvr_readpda( + hw, + msg->pda.data, + HFA384x_PDA_LEN_MAX); + if (result) { + WLAN_LOG_ERROR( + "hfa384x_drvr_readpda() failed, " + "result=%d\n", + result); + + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + msg->resultcode.status = + P80211ENUM_msgitem_status_data_ok; + DBFEXIT; + return 0; + } + msg->pda.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_success; + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + } + + DBFEXIT; + return 0; +} + +/*---------------------------------------------------------------- +* prism2mgmt_readcis +* +* Collect the CIS data and put it in the message. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_readcis(wlandevice_t *wlandev, void *msgp) +{ + int result; + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_readcis_t *msg = msgp; + + DBFENTER; + + memset(msg->cis.data, 0, sizeof(msg->cis.data)); + + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CIS, + msg->cis.data, HFA384x_RID_CIS_LEN); + if ( result ) { + WLAN_LOG_INFO("prism2mgmt_readcis: read(cis) failed.\n"); + msg->cis.status = P80211ENUM_msgitem_status_no_value; + msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; + + } + else { + msg->cis.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_success; + } + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + + DBFEXIT; + return 0; +} + +/*---------------------------------------------------------------- +* prism2mgmt_auxport_state +* +* Enables/Disables the card's auxiliary port. Should be called +* before and after a sequence of auxport_read()/auxport_write() +* calls. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_auxport_state(wlandevice_t *wlandev, void *msgp) +{ + p80211msg_p2req_auxport_state_t *msg = msgp; + +#if (WLAN_HOSTIF != WLAN_USB) + hfa384x_t *hw = wlandev->priv; + DBFENTER; + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + if (msg->enable.data == P80211ENUM_truth_true) { + if ( hfa384x_cmd_aux_enable(hw, 0) ) { + msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; + } else { + msg->resultcode.data = P80211ENUM_resultcode_success; + } + } else { + hfa384x_cmd_aux_disable(hw); + msg->resultcode.data = P80211ENUM_resultcode_success; + } + +#else /* !USB */ + DBFENTER; + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + +#endif /* WLAN_HOSTIF != WLAN_USB */ + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_auxport_read +* +* Copies data from the card using the auxport. The auxport must +* have previously been enabled. Note: this is not the way to +* do downloads, see the [ram|flash]dl functions. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_auxport_read(wlandevice_t *wlandev, void *msgp) +{ +#if (WLAN_HOSTIF != WLAN_USB) + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_auxport_read_t *msg = msgp; + UINT32 addr; + UINT32 len; + UINT8* buf; + UINT32 maxlen = sizeof(msg->data.data); + DBFENTER; + + if ( hw->auxen ) { + addr = msg->addr.data; + len = msg->len.data; + buf = msg->data.data; + if ( len <= maxlen ) { /* max read/write size */ + hfa384x_copy_from_aux(hw, addr, HFA384x_AUX_CTL_EXTDS, buf, len); + msg->resultcode.data = P80211ENUM_resultcode_success; + } else { + WLAN_LOG_DEBUG(1,"Attempt to read > maxlen from auxport.\n"); + msg->resultcode.data = P80211ENUM_resultcode_refused; + } + + } else { + msg->resultcode.data = P80211ENUM_resultcode_refused; + } + msg->data.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + + DBFEXIT; + return 0; +#else + DBFENTER; + + WLAN_LOG_ERROR("prism2mgmt_auxport_read: Not supported on USB.\n"); + + DBFEXIT; + return 0; +#endif +} + + +/*---------------------------------------------------------------- +* prism2mgmt_auxport_write +* +* Copies data to the card using the auxport. The auxport must +* have previously been enabled. Note: this is not the way to +* do downloads, see the [ram|flash]dl functions. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_auxport_write(wlandevice_t *wlandev, void *msgp) +{ +#if (WLAN_HOSTIF != WLAN_USB) + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_auxport_write_t *msg = msgp; + UINT32 addr; + UINT32 len; + UINT8* buf; + UINT32 maxlen = sizeof(msg->data.data); + DBFENTER; + + if ( hw->auxen ) { + addr = msg->addr.data; + len = msg->len.data; + buf = msg->data.data; + if ( len <= maxlen ) { /* max read/write size */ + hfa384x_copy_to_aux(hw, addr, HFA384x_AUX_CTL_EXTDS, buf, len); + } else { + WLAN_LOG_DEBUG(1,"Attempt to write > maxlen from auxport.\n"); + msg->resultcode.data = P80211ENUM_resultcode_refused; + } + + } else { + msg->resultcode.data = P80211ENUM_resultcode_refused; + } + msg->data.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + + DBFEXIT; + return 0; +#else + DBFENTER; + WLAN_LOG_ERROR("prism2mgmt_auxport_read: Not supported on USB.\n"); + DBFEXIT; + return 0; +#endif +} + +/*---------------------------------------------------------------- +* prism2mgmt_low_level +* +* Puts the card into the desired test mode. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_low_level(wlandevice_t *wlandev, void *msgp) +{ + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_low_level_t *msg = msgp; + hfa384x_metacmd_t cmd; + DBFENTER; + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + + /* call some routine to execute the test command */ + cmd.cmd = (UINT16) msg->command.data; + cmd.parm0 = (UINT16) msg->param0.data; + cmd.parm1 = (UINT16) msg->param1.data; + cmd.parm2 = (UINT16) msg->param2.data; + + hfa384x_drvr_low_level(hw,&cmd); + + msg->resp0.data = (UINT32) cmd.result.resp0; + msg->resp1.data = (UINT32) cmd.result.resp1; + msg->resp2.data = (UINT32) cmd.result.resp2; + + msg->resultcode.data = P80211ENUM_resultcode_success; + + DBFEXIT; + return 0; +} + +/*---------------------------------------------------------------- +* prism2mgmt_test_command +* +* Puts the card into the desired test mode. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_test_command(wlandevice_t *wlandev, void *msgp) +{ + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_test_command_t *msg = msgp; + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = ((UINT16) msg->testcode.data) << 8 | 0x38; + cmd.parm0 = (UINT16) msg->testparam.data; + cmd.parm1 = 0; + cmd.parm2 = 0; + + /* call some routine to execute the test command */ + + hfa384x_drvr_low_level(hw,&cmd); + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_success; + + msg->status.status = P80211ENUM_msgitem_status_data_ok; + msg->status.data = cmd.result.status; + msg->resp0.status = P80211ENUM_msgitem_status_data_ok; + msg->resp0.data = cmd.result.resp0; + msg->resp1.status = P80211ENUM_msgitem_status_data_ok; + msg->resp1.data = cmd.result.resp1; + msg->resp2.status = P80211ENUM_msgitem_status_data_ok; + msg->resp2.data = cmd.result.resp2; + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_mmi_read +* +* Read from one of the MMI registers. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_mmi_read(wlandevice_t *wlandev, void *msgp) +{ + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_mmi_read_t *msg = msgp; + UINT32 resp = 0; + + DBFENTER; + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + + /* call some routine to execute the test command */ + + hfa384x_drvr_mmi_read(hw, msg->addr.data, &resp); + + /* I'm not sure if this is "architecturally" correct, but it + is expedient. */ + + msg->value.status = P80211ENUM_msgitem_status_data_ok; + msg->value.data = resp; + msg->resultcode.data = P80211ENUM_resultcode_success; + + DBFEXIT; + return 0; +} + +/*---------------------------------------------------------------- +* prism2mgmt_mmi_write +* +* Write a data value to one of the MMI registers. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_mmi_write(wlandevice_t *wlandev, void *msgp) +{ + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_mmi_write_t *msg = msgp; + DBFENTER; + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + + /* call some routine to execute the test command */ + + hfa384x_drvr_mmi_write(hw, msg->addr.data, msg->data.data); + + msg->resultcode.data = P80211ENUM_resultcode_success; + + DBFEXIT; + return 0; +} + +/*---------------------------------------------------------------- +* prism2mgmt_ramdl_state +* +* Establishes the beginning/end of a card RAM download session. +* +* It is expected that the ramdl_write() function will be called +* one or more times between the 'enable' and 'disable' calls to +* this function. +* +* Note: This function should not be called when a mac comm port +* is active. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp) +{ + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_ramdl_state_t *msg = msgp; + DBFENTER; + + if (wlandev->msdstate != WLAN_MSD_FWLOAD) { + WLAN_LOG_ERROR( + "ramdl_state(): may only be called " + "in the fwload state.\n"); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + DBFEXIT; + return 0; + } + + /* + ** Note: Interrupts are locked out if this is an AP and are NOT + ** locked out if this is a station. + */ + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + if ( msg->enable.data == P80211ENUM_truth_true ) { + if ( hfa384x_drvr_ramdl_enable(hw, msg->exeaddr.data) ) { + msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; + } else { + msg->resultcode.data = P80211ENUM_resultcode_success; + } + } else { + hfa384x_drvr_ramdl_disable(hw); + msg->resultcode.data = P80211ENUM_resultcode_success; + } + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_ramdl_write +* +* Writes a buffer to the card RAM using the download state. This +* is for writing code to card RAM. To just read or write raw data +* use the aux functions. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp) +{ + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_ramdl_write_t *msg = msgp; + UINT32 addr; + UINT32 len; + UINT8 *buf; + DBFENTER; + + if (wlandev->msdstate != WLAN_MSD_FWLOAD) { + WLAN_LOG_ERROR( + "ramdl_write(): may only be called " + "in the fwload state.\n"); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + DBFEXIT; + return 0; + } + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + /* first validate the length */ + if ( msg->len.data > sizeof(msg->data.data) ) { + msg->resultcode.status = P80211ENUM_resultcode_invalid_parameters; + return 0; + } + /* call the hfa384x function to do the write */ + addr = msg->addr.data; + len = msg->len.data; + buf = msg->data.data; + if ( hfa384x_drvr_ramdl_write(hw, addr, buf, len) ) { + msg->resultcode.data = P80211ENUM_resultcode_refused; + + } + msg->resultcode.data = P80211ENUM_resultcode_success; + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_flashdl_state +* +* Establishes the beginning/end of a card Flash download session. +* +* It is expected that the flashdl_write() function will be called +* one or more times between the 'enable' and 'disable' calls to +* this function. +* +* Note: This function should not be called when a mac comm port +* is active. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_flashdl_state_t *msg = msgp; + DBFENTER; + + if (wlandev->msdstate != WLAN_MSD_FWLOAD) { + WLAN_LOG_ERROR( + "flashdl_state(): may only be called " + "in the fwload state.\n"); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + DBFEXIT; + return 0; + } + + /* + ** Note: Interrupts are locked out if this is an AP and are NOT + ** locked out if this is a station. + */ + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + if ( msg->enable.data == P80211ENUM_truth_true ) { + if ( hfa384x_drvr_flashdl_enable(hw) ) { + msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; + } else { + msg->resultcode.data = P80211ENUM_resultcode_success; + } + } else { + hfa384x_drvr_flashdl_disable(hw); + msg->resultcode.data = P80211ENUM_resultcode_success; + /* NOTE: At this point, the MAC is in the post-reset + * state and the driver is in the fwload state. + * We need to get the MAC back into the fwload + * state. To do this, we set the nsdstate to HWPRESENT + * and then call the ifstate function to redo everything + * that got us into the fwload state. + */ + wlandev->msdstate = WLAN_MSD_HWPRESENT; + result = prism2sta_ifstate(wlandev, P80211ENUM_ifstate_fwload); + if (result != P80211ENUM_resultcode_success) { + WLAN_LOG_ERROR("prism2sta_ifstate(fwload) failed," + "P80211ENUM_resultcode=%d\n", result); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + result = -1; + } + } + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_flashdl_write +* +* +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp) +{ + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_flashdl_write_t *msg = msgp; + UINT32 addr; + UINT32 len; + UINT8 *buf; + DBFENTER; + + if (wlandev->msdstate != WLAN_MSD_FWLOAD) { + WLAN_LOG_ERROR( + "flashdl_write(): may only be called " + "in the fwload state.\n"); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + DBFEXIT; + return 0; + } + + /* + ** Note: Interrupts are locked out if this is an AP and are NOT + ** locked out if this is a station. + */ + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + /* first validate the length */ + if ( msg->len.data > sizeof(msg->data.data) ) { + msg->resultcode.status = + P80211ENUM_resultcode_invalid_parameters; + return 0; + } + /* call the hfa384x function to do the write */ + addr = msg->addr.data; + len = msg->len.data; + buf = msg->data.data; + if ( hfa384x_drvr_flashdl_write(hw, addr, buf, len) ) { + msg->resultcode.data = P80211ENUM_resultcode_refused; + + } + msg->resultcode.data = P80211ENUM_resultcode_success; + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_dump_state +* +* Dumps the driver's and hardware's current state via the kernel +* log at KERN_NOTICE level. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_dump_state(wlandevice_t *wlandev, void *msgp) +{ + p80211msg_p2req_dump_state_t *msg = msgp; + int result = 0; + +#if (WLAN_HOSTIF != WLAN_USB) + hfa384x_t *hw = wlandev->priv; + UINT16 auxbuf[15]; + DBFENTER; + + WLAN_LOG_NOTICE("prism2 driver and hardware state:\n"); + if ( (result = hfa384x_cmd_aux_enable(hw, 0)) ) { + WLAN_LOG_ERROR("aux_enable failed, result=%d\n", result); + goto failed; + } + hfa384x_copy_from_aux(hw, + 0x01e2, + HFA384x_AUX_CTL_EXTDS, + auxbuf, + sizeof(auxbuf)); + hfa384x_cmd_aux_disable(hw); + WLAN_LOG_NOTICE(" cmac: FreeBlocks=%d\n", auxbuf[5]); + WLAN_LOG_NOTICE(" cmac: IntEn=0x%02x EvStat=0x%02x\n", + hfa384x_getreg(hw, HFA384x_INTEN), + hfa384x_getreg(hw, HFA384x_EVSTAT)); + + #ifdef USE_FID_STACK + WLAN_LOG_NOTICE(" drvr: txfid_top=%d stacksize=%d\n", + hw->txfid_top,HFA384x_DRVR_FIDSTACKLEN_MAX); + #else + WLAN_LOG_NOTICE(" drvr: txfid_head=%d txfid_tail=%d txfid_N=%d\n", + hw->txfid_head, hw->txfid_tail, hw->txfid_N); + #endif + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_success; + +#else /* (WLAN_HOSTIF == WLAN_USB) */ + + DBFENTER; + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + goto failed; + +#endif /* (WLAN_HOSTIF != WLAN_USB) */ + +failed: + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* prism2mgmt_channel_info +* +* Issues a ChannelInfoRequest. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_channel_info(wlandevice_t *wlandev, void *msgp) +{ + p80211msg_p2req_channel_info_t *msg=msgp; + hfa384x_t *hw = wlandev->priv; + int result, i, n=0; + UINT16 channel_mask=0; + hfa384x_ChannelInfoRequest_data_t chinforeq; + // unsigned long now; + + DBFENTER; + + if (!hw->ap) { + + /*** STATION ***/ + + /* Not supported in STA f/w */ + P80211_SET_INT(msg->resultcode, P80211ENUM_resultcode_not_supported); + goto done; + } + + /*** ACCESS POINT ***/ + +#define CHINFO_TIMEOUT 2 + + P80211_SET_INT(msg->resultcode, P80211ENUM_resultcode_success); + + /* setting default value for channellist = all channels */ + if (!msg->channellist.data) { + P80211_SET_INT(msg->channellist, 0x00007FFE); + } + /* setting default value for channeldwelltime = 100 ms */ + if (!msg->channeldwelltime.data) { + P80211_SET_INT(msg->channeldwelltime, 100); + } + channel_mask = (UINT16) (msg->channellist.data >> 1); + for (i=0, n=0; i < 14; i++) { + if (channel_mask & (1<numchinfo, n); + chinforeq.channelList = host2hfa384x_16(channel_mask); + chinforeq.channelDwellTime = host2hfa384x_16(msg->channeldwelltime.data); + + atomic_set(&hw->channel_info.done, 1); + + result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CHANNELINFOREQUEST, + &chinforeq, HFA384x_RID_CHANNELINFOREQUEST_LEN); + if ( result ) { + WLAN_LOG_ERROR("setconfig(CHANNELINFOREQUEST) failed. result=%d\n", + result); + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + goto done; + } + /* + now = jiffies; + while (atomic_read(&hw->channel_info.done) != 1) { + if ((jiffies - now) > CHINFO_TIMEOUT*HZ) { + WLAN_LOG_NOTICE("ChannelInfo results not received in %d seconds, aborting.\n", + CHINFO_TIMEOUT); + msg->resultcode.data = P80211ENUM_resultcode_timeout; + goto done; + } + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(HZ/4); + current->state = TASK_RUNNING; + } + */ + +done: + + DBFEXIT; + return 0; +} + +/*---------------------------------------------------------------- +* prism2mgmt_channel_info_results +* +* Returns required ChannelInfo result. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_channel_info_results(wlandevice_t *wlandev, void *msgp) +{ + hfa384x_t *hw = wlandev->priv; + + p80211msg_p2req_channel_info_results_t *msg=msgp; + int result=0; + int channel; + + DBFENTER; + + if (!hw->ap) { + + /*** STATION ***/ + + /* Not supported in STA f/w */ + P80211_SET_INT(msg->resultcode, P80211ENUM_resultcode_not_supported); + goto done; + } + + /*** ACCESS POINT ***/ + + switch (atomic_read(&hw->channel_info.done)) { + case 0: msg->resultcode.status = P80211ENUM_msgitem_status_no_value; + goto done; + case 1: msg->resultcode.status = P80211ENUM_msgitem_status_incomplete_itemdata; + goto done; + } + + P80211_SET_INT(msg->resultcode, P80211ENUM_resultcode_success); + channel=msg->channel.data-1; + + if (channel < 0 || ! (hw->channel_info.results.scanchannels & 1<resultcode.data = P80211ENUM_resultcode_invalid_parameters; + goto done; + } + WLAN_LOG_DEBUG(2, "chinfo_results: channel %d, avg/peak level=%d/%d dB, active=%d\n", + channel+1, + hw->channel_info.results.result[channel].anl, + hw->channel_info.results.result[channel].pnl, + hw->channel_info.results.result[channel].active + ); + P80211_SET_INT(msg->avgnoiselevel, hw->channel_info.results.result[channel].anl); + P80211_SET_INT(msg->peaknoiselevel, hw->channel_info.results.result[channel].pnl); + P80211_SET_INT(msg->bssactive, hw->channel_info.results.result[channel].active & + HFA384x_CHINFORESULT_BSSACTIVE + ? P80211ENUM_truth_true + : P80211ENUM_truth_false) ; + P80211_SET_INT(msg->pcfactive, hw->channel_info.results.result[channel].active & + HFA384x_CHINFORESULT_PCFACTIVE + ? P80211ENUM_truth_true + : P80211ENUM_truth_false) ; + +done: + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_autojoin +* +* Associate with an ESS. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp) +{ + hfa384x_t *hw = wlandev->priv; + int result = 0; + UINT16 reg; + UINT16 port_type; + p80211msg_lnxreq_autojoin_t *msg = msgp; + p80211pstrd_t *pstr; + UINT8 bytebuf[256]; + hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t*)bytebuf; + DBFENTER; + + wlandev->macmode = WLAN_MACMODE_NONE; + + /* Set the SSID */ + memcpy(&wlandev->ssid, &msg->ssid.data, sizeof(msg->ssid.data)); + + if (hw->ap) { + + /*** ACCESS POINT ***/ + + /* Never supported on AP */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + goto done; + } + + /* Disable the Port */ + hfa384x_drvr_disable(hw, 0); + + /*** STATION ***/ + /* Set the TxRates */ + hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, 0x000f); + + /* Set the auth type */ + if ( msg->authtype.data == P80211ENUM_authalg_sharedkey ) { + reg = HFA384x_CNFAUTHENTICATION_SHAREDKEY; + } else { + reg = HFA384x_CNFAUTHENTICATION_OPENSYSTEM; + } + hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAUTHENTICATION, reg); + + /* Set the ssid */ + memset(bytebuf, 0, 256); + pstr = (p80211pstrd_t*)&(msg->ssid.data); + prism2mgmt_pstr2bytestr(p2bytestr, pstr); + result = hfa384x_drvr_setconfig( + hw, HFA384x_RID_CNFDESIREDSSID, + bytebuf, HFA384x_RID_CNFDESIREDSSID_LEN); +#if 0 + /* we can use the new-fangled auto-unknown mode if the firmware + is 1.3.3 or newer */ + if (HFA384x_FIRMARE_VERSION(hw->ident_sta_fw.major, + hw->ident_sta_fw.minor, + hw->ident_sta_fw.variant) >= + HFA384x_FIRMWARE_VERSION(1,3,3)) { + /* Set up the IBSS options */ + reg = HFA384x_CREATEIBSS_JOINESS_JOINCREATEIBSS; + hfa384x_drvr_setconfig16(hw, HFA384x_RID_CREATEIBSS, reg); + + /* Set the PortType */ + port_type = HFA384x_PORTTYPE_IBSS; + } else { + port_type = HFA384x_PORTTYPE_BSS; + } +#else + port_type = HFA384x_PORTTYPE_BSS; +#endif + /* Set the PortType */ + hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, port_type); + + /* Enable the Port */ + hfa384x_drvr_enable(hw, 0); + + /* Set the resultcode */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_success; + +done: + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_wlansniff +* +* Start or stop sniffing. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + p80211msg_lnxreq_wlansniff_t *msg = msgp; + + hfa384x_t *hw = wlandev->priv; + UINT16 word; + + DBFENTER; + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + switch (msg->enable.data) + { + case P80211ENUM_truth_false: + /* Confirm that we're in monitor mode */ + if ( wlandev->netdev->type == ARPHRD_ETHER ) { + msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters; + result = 0; + goto exit; + } + /* Disable monitor mode */ + result = hfa384x_cmd_monitor(hw, HFA384x_MONITOR_DISABLE); + if ( result ) { + WLAN_LOG_DEBUG(1, + "failed to disable monitor mode, result=%d\n", + result); + goto failed; + } + /* Disable port 0 */ + result = hfa384x_drvr_disable(hw, 0); + if ( result ) { + WLAN_LOG_DEBUG(1, + "failed to disable port 0 after sniffing, result=%d\n", + result); + goto failed; + } + /* Clear the driver state */ + wlandev->netdev->type = ARPHRD_ETHER; + + /* Restore the wepflags */ + result = hfa384x_drvr_setconfig16(hw, + HFA384x_RID_CNFWEPFLAGS, + hw->presniff_wepflags); + if ( result ) { + WLAN_LOG_DEBUG(1, + "failed to restore wepflags=0x%04x, result=%d\n", + hw->presniff_wepflags, + result); + goto failed; + } + + /* Set the port to its prior type and enable (if necessary) */ + if (hw->presniff_port_type != 0 ) { + word = hw->presniff_port_type; + result = hfa384x_drvr_setconfig16(hw, + HFA384x_RID_CNFPORTTYPE, word); + if ( result ) { + WLAN_LOG_DEBUG(1, + "failed to restore porttype, result=%d\n", + result); + goto failed; + } + + /* Enable the port */ + result = hfa384x_drvr_enable(hw, 0); + if ( result ) { + WLAN_LOG_DEBUG(1, "failed to enable port to presniff setting, result=%d\n", result); + goto failed; + } + } else { + result = hfa384x_drvr_disable(hw, 0); + + } + + WLAN_LOG_INFO("monitor mode disabled\n"); + msg->resultcode.data = P80211ENUM_resultcode_success; + result = 0; + goto exit; + break; + case P80211ENUM_truth_true: + /* Disable the port (if enabled), only check Port 0 */ + if ( hw->port_enabled[0]) { + if (wlandev->netdev->type == ARPHRD_ETHER) { + /* Save macport 0 state */ + result = hfa384x_drvr_getconfig16(hw, + HFA384x_RID_CNFPORTTYPE, + &(hw->presniff_port_type)); + if ( result ) { + WLAN_LOG_DEBUG(1,"failed to read porttype, result=%d\n", result); + goto failed; + } + /* Save the wepflags state */ + result = hfa384x_drvr_getconfig16(hw, + HFA384x_RID_CNFWEPFLAGS, + &(hw->presniff_wepflags)); + if ( result ) { + WLAN_LOG_DEBUG(1,"failed to read wepflags, result=%d\n", result); + goto failed; + } + hfa384x_drvr_stop(hw); + result = hfa384x_drvr_start(hw); + if ( result ) { + WLAN_LOG_DEBUG(1, + "failed to restart the card for sniffing, result=%d\n", + result); + goto failed; + } + } else { + /* Disable the port */ + result = hfa384x_drvr_disable(hw, 0); + if ( result ) { + WLAN_LOG_DEBUG(1, + "failed to enable port for sniffing, result=%d\n", + result); + goto failed; + } + } + } else { + hw->presniff_port_type = 0; + } + + /* Set the channel we wish to sniff */ + word = msg->channel.data; + result = hfa384x_drvr_setconfig16(hw, + HFA384x_RID_CNFOWNCHANNEL, word); + hw->sniff_channel=word; + + if ( result ) { + WLAN_LOG_DEBUG(1, + "failed to set channel %d, result=%d\n", + word, + result); + goto failed; + } + + /* Now if we're already sniffing, we can skip the rest */ + if (wlandev->netdev->type != ARPHRD_ETHER) { + /* Set the port type to pIbss */ + word = HFA384x_PORTTYPE_PSUEDOIBSS; + result = hfa384x_drvr_setconfig16(hw, + HFA384x_RID_CNFPORTTYPE, word); + if ( result ) { + WLAN_LOG_DEBUG(1, + "failed to set porttype %d, result=%d\n", + word, + result); + goto failed; + } + if ((msg->keepwepflags.status == P80211ENUM_msgitem_status_data_ok) && (msg->keepwepflags.data != P80211ENUM_truth_true)) { + /* Set the wepflags for no decryption */ + word = HFA384x_WEPFLAGS_DISABLE_TXCRYPT | + HFA384x_WEPFLAGS_DISABLE_RXCRYPT; + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFWEPFLAGS, word); + } + + if ( result ) { + WLAN_LOG_DEBUG(1, + "failed to set wepflags=0x%04x, result=%d\n", + word, + result); + goto failed; + } + } + + /* Do we want to strip the FCS in monitor mode? */ + if ((msg->stripfcs.status == P80211ENUM_msgitem_status_data_ok) && (msg->stripfcs.data == P80211ENUM_truth_true)) { + hw->sniff_fcs = 0; + } else { + hw->sniff_fcs = 1; + } + + /* Do we want to truncate the packets? */ + if (msg->packet_trunc.status == P80211ENUM_msgitem_status_data_ok) { + hw->sniff_truncate = msg->packet_trunc.data; + } else { + hw->sniff_truncate = 0; + } + + /* Enable the port */ + result = hfa384x_drvr_enable(hw, 0); + if ( result ) { + WLAN_LOG_DEBUG(1, + "failed to enable port for sniffing, result=%d\n", + result); + goto failed; + } + /* Enable monitor mode */ + result = hfa384x_cmd_monitor(hw, HFA384x_MONITOR_ENABLE); + if ( result ) { + WLAN_LOG_DEBUG(1, + "failed to enable monitor mode, result=%d\n", + result); + goto failed; + } + + if (wlandev->netdev->type == ARPHRD_ETHER) { + WLAN_LOG_INFO("monitor mode enabled\n"); + } + + /* Set the driver state */ + /* Do we want the prism2 header? */ + if ((msg->prismheader.status == P80211ENUM_msgitem_status_data_ok) && (msg->prismheader.data == P80211ENUM_truth_true)) { + hw->sniffhdr = 0; + wlandev->netdev->type = ARPHRD_IEEE80211_PRISM; + } else if ((msg->wlanheader.status == P80211ENUM_msgitem_status_data_ok) && (msg->wlanheader.data == P80211ENUM_truth_true)) { + hw->sniffhdr = 1; + wlandev->netdev->type = ARPHRD_IEEE80211_PRISM; + } else { + wlandev->netdev->type = ARPHRD_IEEE80211; + } + + msg->resultcode.data = P80211ENUM_resultcode_success; + result = 0; + goto exit; + break; + default: + msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters; + result = 0; + goto exit; + break; + } + +failed: + msg->resultcode.data = P80211ENUM_resultcode_refused; + result = 0; +exit: + + DBFEXIT; + return result; +} --- linux-2.6.28.orig/ubuntu/misc/wireless/prism2_usb/BOM +++ linux-2.6.28/ubuntu/misc/wireless/prism2_usb/BOM @@ -0,0 +1,15 @@ +# Jul 29, 2008 +# Copied from the linux-wlan-ng 0.2.9+dfsg source package + +Run "make config" then "make" in src/mkmeta + +cp -a src/prism2/driver $KERNEL/ubuntu/misc/wireless/prism2_usb +cp -a src/p80211 $KERNEL/ubuntu/misc/wireless/ +cp -a src/include/wlan $KERNEL/ubuntu/misc/wireless/p80211/ +cp -a src/prism2/include/prism2 $KERNEL/ubuntu/misc/wireless/prism2_usb/ + +Strip down prism2_usb/Makefile and p80211/Makefile +rm prism2_usb/prism2_{cs,pci,plx} + +Use dev_net_set() for 2.6.26 in p80211/p80211netdev.c:wlan_setup() + --- linux-2.6.28.orig/ubuntu/misc/wireless/prism2_usb/prism2/hfa384x.h +++ linux-2.6.28/ubuntu/misc/wireless/prism2_usb/prism2/hfa384x.h @@ -0,0 +1,3067 @@ +/* src/prism2/include/prism2/hfa384x.h +* +* Defines the constants and data structures for the hfa384x +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* [Implementation and usage notes] +* +* [References] +* CW10 Programmer's Manual v1.5 +* IEEE 802.11 D10.0 +* +* -------------------------------------------------------------------- +*/ + +#ifndef _HFA384x_H +#define _HFA384x_H + +/*=============================================================*/ +#define HFA384x_FIRMWARE_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) + +#define HFA384x_LEVEL_TO_dBm(v) (0x100 + (v) * 100 / 255 - 100) + +/*------ Constants --------------------------------------------*/ +/*--- Mins & Maxs -----------------------------------*/ +#define HFA384x_CMD_ALLOC_LEN_MIN ((UINT16)4) +#define HFA384x_CMD_ALLOC_LEN_MAX ((UINT16)2400) +#define HFA384x_BAP_DATALEN_MAX ((UINT16)4096) +#define HFA384x_BAP_OFFSET_MAX ((UINT16)4096) +#define HFA384x_PORTID_MAX ((UINT16)7) +#define HFA384x_NUMPORTS_MAX ((UINT16)(HFA384x_PORTID_MAX+1)) +#define HFA384x_PDR_LEN_MAX ((UINT16)512) /* in bytes, from EK */ +#define HFA384x_PDA_RECS_MAX ((UINT16)200) /* a guess */ +#define HFA384x_PDA_LEN_MAX ((UINT16)1024) /* in bytes, from EK */ +#define HFA384x_SCANRESULT_MAX ((UINT16)31) +#define HFA384x_HSCANRESULT_MAX ((UINT16)31) +#define HFA384x_CHINFORESULT_MAX ((UINT16)16) +#define HFA384x_DRVR_FIDSTACKLEN_MAX (10) +#define HFA384x_DRVR_TXBUF_MAX (sizeof(hfa384x_tx_frame_t) + \ + WLAN_DATA_MAXLEN - \ + WLAN_WEP_IV_LEN - \ + WLAN_WEP_ICV_LEN + 2) +#define HFA384x_DRVR_MAGIC (0x4a2d) +#define HFA384x_INFODATA_MAXLEN (sizeof(hfa384x_infodata_t)) +#define HFA384x_INFOFRM_MAXLEN (sizeof(hfa384x_InfFrame_t)) +#define HFA384x_RID_GUESSING_MAXLEN 2048 /* I'm not really sure */ +#define HFA384x_RIDDATA_MAXLEN HFA384x_RID_GUESSING_MAXLEN +#define HFA384x_USB_RWMEM_MAXLEN 2048 + +/*--- Support Constants -----------------------------*/ +#define HFA384x_BAP_PROC ((UINT16)0) +#define HFA384x_BAP_INT ((UINT16)1) +#define HFA384x_PORTTYPE_IBSS ((UINT16)0) +#define HFA384x_PORTTYPE_BSS ((UINT16)1) +#define HFA384x_PORTTYPE_WDS ((UINT16)2) +#define HFA384x_PORTTYPE_PSUEDOIBSS ((UINT16)3) +#define HFA384x_PORTTYPE_HOSTAP ((UINT16)6) +#define HFA384x_WEPFLAGS_PRIVINVOKED ((UINT16)BIT0) +#define HFA384x_WEPFLAGS_EXCLUDE ((UINT16)BIT1) +#define HFA384x_WEPFLAGS_DISABLE_TXCRYPT ((UINT16)BIT4) +#define HFA384x_WEPFLAGS_DISABLE_RXCRYPT ((UINT16)BIT7) +#define HFA384x_WEPFLAGS_DISALLOW_MIXED ((UINT16)BIT11) +#define HFA384x_WEPFLAGS_IV_INTERVAL1 ((UINT16)0) +#define HFA384x_WEPFLAGS_IV_INTERVAL10 ((UINT16)BIT5) +#define HFA384x_WEPFLAGS_IV_INTERVAL50 ((UINT16)BIT6) +#define HFA384x_WEPFLAGS_IV_INTERVAL100 ((UINT16)(BIT5 | BIT6)) +#define HFA384x_WEPFLAGS_FIRMWARE_WPA ((UINT16)BIT8) +#define HFA384x_WEPFLAGS_HOST_MIC ((UINT16)BIT9) +#define HFA384x_ROAMMODE_FWSCAN_FWROAM ((UINT16)1) +#define HFA384x_ROAMMODE_FWSCAN_HOSTROAM ((UINT16)2) +#define HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM ((UINT16)3) +#define HFA384x_PORTSTATUS_DISABLED ((UINT16)1) +#define HFA384x_PORTSTATUS_INITSRCH ((UINT16)2) +#define HFA384x_PORTSTATUS_CONN_IBSS ((UINT16)3) +#define HFA384x_PORTSTATUS_CONN_ESS ((UINT16)4) +#define HFA384x_PORTSTATUS_OOR_ESS ((UINT16)5) +#define HFA384x_PORTSTATUS_CONN_WDS ((UINT16)6) +#define HFA384x_PORTSTATUS_HOSTAP ((UINT16)8) +#define HFA384x_RATEBIT_1 ((UINT16)1) +#define HFA384x_RATEBIT_2 ((UINT16)2) +#define HFA384x_RATEBIT_5dot5 ((UINT16)4) +#define HFA384x_RATEBIT_11 ((UINT16)8) + +/*--- Just some symbolic names for legibility -------*/ +#define HFA384x_TXCMD_NORECL ((UINT16)0) +#define HFA384x_TXCMD_RECL ((UINT16)1) + +/*--- MAC Internal memory constants and macros ------*/ +/* masks and macros used to manipulate MAC internal memory addresses. */ +/* MAC internal memory addresses are 23 bit quantities. The MAC uses + * a paged address space where the upper 16 bits are the page number + * and the lower 7 bits are the offset. There are various Host API + * elements that require two 16-bit quantities to specify a MAC + * internal memory address. Unfortunately, some of the API's use a + * page/offset format where the offset value is JUST the lower seven + * bits and the page is the remaining 16 bits. Some of the API's + * assume that the 23 bit address has been split at the 16th bit. We + * refer to these two formats as AUX format and CMD format. The + * macros below help handle some of this. + */ + +/* Handy constant */ +#define HFA384x_ADDR_AUX_OFF_MAX ((UINT16)0x007f) + +/* Mask bits for discarding unwanted pieces in a flat address */ +#define HFA384x_ADDR_FLAT_AUX_PAGE_MASK (0x007fff80) +#define HFA384x_ADDR_FLAT_AUX_OFF_MASK (0x0000007f) +#define HFA384x_ADDR_FLAT_CMD_PAGE_MASK (0xffff0000) +#define HFA384x_ADDR_FLAT_CMD_OFF_MASK (0x0000ffff) + +/* Mask bits for discarding unwanted pieces in AUX format 16-bit address parts */ +#define HFA384x_ADDR_AUX_PAGE_MASK (0xffff) +#define HFA384x_ADDR_AUX_OFF_MASK (0x007f) + +/* Mask bits for discarding unwanted pieces in CMD format 16-bit address parts */ +#define HFA384x_ADDR_CMD_PAGE_MASK (0x007f) +#define HFA384x_ADDR_CMD_OFF_MASK (0xffff) + +/* Make a 32-bit flat address from AUX format 16-bit page and offset */ +#define HFA384x_ADDR_AUX_MKFLAT(p,o) \ + (((UINT32)(((UINT16)(p))&HFA384x_ADDR_AUX_PAGE_MASK)) <<7) | \ + ((UINT32)(((UINT16)(o))&HFA384x_ADDR_AUX_OFF_MASK)) + +/* Make a 32-bit flat address from CMD format 16-bit page and offset */ +#define HFA384x_ADDR_CMD_MKFLAT(p,o) \ + (((UINT32)(((UINT16)(p))&HFA384x_ADDR_CMD_PAGE_MASK)) <<16) | \ + ((UINT32)(((UINT16)(o))&HFA384x_ADDR_CMD_OFF_MASK)) + +/* Make AUX format offset and page from a 32-bit flat address */ +#define HFA384x_ADDR_AUX_MKPAGE(f) \ + ((UINT16)((((UINT32)(f))&HFA384x_ADDR_FLAT_AUX_PAGE_MASK)>>7)) +#define HFA384x_ADDR_AUX_MKOFF(f) \ + ((UINT16)(((UINT32)(f))&HFA384x_ADDR_FLAT_AUX_OFF_MASK)) + +/* Make CMD format offset and page from a 32-bit flat address */ +#define HFA384x_ADDR_CMD_MKPAGE(f) \ + ((UINT16)((((UINT32)(f))&HFA384x_ADDR_FLAT_CMD_PAGE_MASK)>>16)) +#define HFA384x_ADDR_CMD_MKOFF(f) \ + ((UINT16)(((UINT32)(f))&HFA384x_ADDR_FLAT_CMD_OFF_MASK)) + +/*--- Aux register masks/tests ----------------------*/ +/* Some of the upper bits of the AUX offset register are used to */ +/* select address space. */ +#define HFA384x_AUX_CTL_EXTDS (0x00) +#define HFA384x_AUX_CTL_NV (0x01) +#define HFA384x_AUX_CTL_PHY (0x02) +#define HFA384x_AUX_CTL_ICSRAM (0x03) + +/* Make AUX register offset and page values from a flat address */ +#define HFA384x_AUX_MKOFF(f, c) \ + (HFA384x_ADDR_AUX_MKOFF(f) | (((UINT16)(c))<<12)) +#define HFA384x_AUX_MKPAGE(f) HFA384x_ADDR_AUX_MKPAGE(f) + + +/*--- Controller Memory addresses -------------------*/ +#define HFA3842_PDA_BASE (0x007f0000UL) +#define HFA3841_PDA_BASE (0x003f0000UL) +#define HFA3841_PDA_BOGUS_BASE (0x00390000UL) + +/*--- Driver Download states -----------------------*/ +#define HFA384x_DLSTATE_DISABLED 0 +#define HFA384x_DLSTATE_RAMENABLED 1 +#define HFA384x_DLSTATE_FLASHENABLED 2 +#define HFA384x_DLSTATE_FLASHWRITTEN 3 +#define HFA384x_DLSTATE_FLASHWRITEPENDING 4 +#define HFA384x_DLSTATE_GENESIS 5 + +/*--- Register I/O offsets --------------------------*/ +#if ((WLAN_HOSTIF == WLAN_PCMCIA) || (WLAN_HOSTIF == WLAN_PLX)) + +#define HFA384x_CMD_OFF (0x00) +#define HFA384x_PARAM0_OFF (0x02) +#define HFA384x_PARAM1_OFF (0x04) +#define HFA384x_PARAM2_OFF (0x06) +#define HFA384x_STATUS_OFF (0x08) +#define HFA384x_RESP0_OFF (0x0A) +#define HFA384x_RESP1_OFF (0x0C) +#define HFA384x_RESP2_OFF (0x0E) +#define HFA384x_INFOFID_OFF (0x10) +#define HFA384x_RXFID_OFF (0x20) +#define HFA384x_ALLOCFID_OFF (0x22) +#define HFA384x_TXCOMPLFID_OFF (0x24) +#define HFA384x_SELECT0_OFF (0x18) +#define HFA384x_OFFSET0_OFF (0x1C) +#define HFA384x_DATA0_OFF (0x36) +#define HFA384x_SELECT1_OFF (0x1A) +#define HFA384x_OFFSET1_OFF (0x1E) +#define HFA384x_DATA1_OFF (0x38) +#define HFA384x_EVSTAT_OFF (0x30) +#define HFA384x_INTEN_OFF (0x32) +#define HFA384x_EVACK_OFF (0x34) +#define HFA384x_CONTROL_OFF (0x14) +#define HFA384x_SWSUPPORT0_OFF (0x28) +#define HFA384x_SWSUPPORT1_OFF (0x2A) +#define HFA384x_SWSUPPORT2_OFF (0x2C) +#define HFA384x_AUXPAGE_OFF (0x3A) +#define HFA384x_AUXOFFSET_OFF (0x3C) +#define HFA384x_AUXDATA_OFF (0x3E) + +#elif (WLAN_HOSTIF == WLAN_PCI || WLAN_HOSTIF == WLAN_USB) + +#define HFA384x_CMD_OFF (0x00) +#define HFA384x_PARAM0_OFF (0x04) +#define HFA384x_PARAM1_OFF (0x08) +#define HFA384x_PARAM2_OFF (0x0c) +#define HFA384x_STATUS_OFF (0x10) +#define HFA384x_RESP0_OFF (0x14) +#define HFA384x_RESP1_OFF (0x18) +#define HFA384x_RESP2_OFF (0x1c) +#define HFA384x_INFOFID_OFF (0x20) +#define HFA384x_RXFID_OFF (0x40) +#define HFA384x_ALLOCFID_OFF (0x44) +#define HFA384x_TXCOMPLFID_OFF (0x48) +#define HFA384x_SELECT0_OFF (0x30) +#define HFA384x_OFFSET0_OFF (0x38) +#define HFA384x_DATA0_OFF (0x6c) +#define HFA384x_SELECT1_OFF (0x34) +#define HFA384x_OFFSET1_OFF (0x3c) +#define HFA384x_DATA1_OFF (0x70) +#define HFA384x_EVSTAT_OFF (0x60) +#define HFA384x_INTEN_OFF (0x64) +#define HFA384x_EVACK_OFF (0x68) +#define HFA384x_CONTROL_OFF (0x28) +#define HFA384x_SWSUPPORT0_OFF (0x50) +#define HFA384x_SWSUPPORT1_OFF (0x54) +#define HFA384x_SWSUPPORT2_OFF (0x58) +#define HFA384x_AUXPAGE_OFF (0x74) +#define HFA384x_AUXOFFSET_OFF (0x78) +#define HFA384x_AUXDATA_OFF (0x7c) +#define HFA384x_PCICOR_OFF (0x4c) +#define HFA384x_PCIHCR_OFF (0x5c) +#define HFA384x_PCI_M0_ADDRH_OFF (0x80) +#define HFA384x_PCI_M0_ADDRL_OFF (0x84) +#define HFA384x_PCI_M0_LEN_OFF (0x88) +#define HFA384x_PCI_M0_CTL_OFF (0x8c) +#define HFA384x_PCI_STATUS_OFF (0x98) +#define HFA384x_PCI_M1_ADDRH_OFF (0xa0) +#define HFA384x_PCI_M1_ADDRL_OFF (0xa4) +#define HFA384x_PCI_M1_LEN_OFF (0xa8) +#define HFA384x_PCI_M1_CTL_OFF (0xac) + +#endif + +/*--- Register Field Masks --------------------------*/ +#define HFA384x_CMD_BUSY ((UINT16)BIT15) +#define HFA384x_CMD_AINFO ((UINT16)(BIT14 | BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8)) +#define HFA384x_CMD_MACPORT ((UINT16)(BIT10 | BIT9 | BIT8)) +#define HFA384x_CMD_RECL ((UINT16)BIT8) +#define HFA384x_CMD_WRITE ((UINT16)BIT8) +#define HFA384x_CMD_PROGMODE ((UINT16)(BIT9 | BIT8)) +#define HFA384x_CMD_CMDCODE ((UINT16)(BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)) + +#define HFA384x_STATUS_RESULT ((UINT16)(BIT14 | BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8)) +#define HFA384x_STATUS_CMDCODE ((UINT16)(BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)) + +#define HFA384x_OFFSET_BUSY ((UINT16)BIT15) +#define HFA384x_OFFSET_ERR ((UINT16)BIT14) +#define HFA384x_OFFSET_DATAOFF ((UINT16)(BIT11 | BIT10 | BIT9 | BIT8 | BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1)) + +#define HFA384x_EVSTAT_TICK ((UINT16)BIT15) +#define HFA384x_EVSTAT_WTERR ((UINT16)BIT14) +#define HFA384x_EVSTAT_INFDROP ((UINT16)BIT13) +#define HFA384x_EVSTAT_INFO ((UINT16)BIT7) +#define HFA384x_EVSTAT_DTIM ((UINT16)BIT5) +#define HFA384x_EVSTAT_CMD ((UINT16)BIT4) +#define HFA384x_EVSTAT_ALLOC ((UINT16)BIT3) +#define HFA384x_EVSTAT_TXEXC ((UINT16)BIT2) +#define HFA384x_EVSTAT_TX ((UINT16)BIT1) +#define HFA384x_EVSTAT_RX ((UINT16)BIT0) + +#define HFA384x_INT_BAP_OP (HFA384x_EVSTAT_INFO|HFA384x_EVSTAT_RX|HFA384x_EVSTAT_TX|HFA384x_EVSTAT_TXEXC) + +#define HFA384x_INT_NORMAL (HFA384x_EVSTAT_INFO|HFA384x_EVSTAT_RX|HFA384x_EVSTAT_TX|HFA384x_EVSTAT_TXEXC|HFA384x_EVSTAT_INFDROP|HFA384x_EVSTAT_ALLOC|HFA384x_EVSTAT_DTIM) + +#define HFA384x_INTEN_TICK ((UINT16)BIT15) +#define HFA384x_INTEN_WTERR ((UINT16)BIT14) +#define HFA384x_INTEN_INFDROP ((UINT16)BIT13) +#define HFA384x_INTEN_INFO ((UINT16)BIT7) +#define HFA384x_INTEN_DTIM ((UINT16)BIT5) +#define HFA384x_INTEN_CMD ((UINT16)BIT4) +#define HFA384x_INTEN_ALLOC ((UINT16)BIT3) +#define HFA384x_INTEN_TXEXC ((UINT16)BIT2) +#define HFA384x_INTEN_TX ((UINT16)BIT1) +#define HFA384x_INTEN_RX ((UINT16)BIT0) + +#define HFA384x_EVACK_TICK ((UINT16)BIT15) +#define HFA384x_EVACK_WTERR ((UINT16)BIT14) +#define HFA384x_EVACK_INFDROP ((UINT16)BIT13) +#define HFA384x_EVACK_INFO ((UINT16)BIT7) +#define HFA384x_EVACK_DTIM ((UINT16)BIT5) +#define HFA384x_EVACK_CMD ((UINT16)BIT4) +#define HFA384x_EVACK_ALLOC ((UINT16)BIT3) +#define HFA384x_EVACK_TXEXC ((UINT16)BIT2) +#define HFA384x_EVACK_TX ((UINT16)BIT1) +#define HFA384x_EVACK_RX ((UINT16)BIT0) + +#define HFA384x_CONTROL_AUXEN ((UINT16)(BIT15 | BIT14)) + + +/*--- Command Code Constants --------------------------*/ +/*--- Controller Commands --------------------------*/ +#define HFA384x_CMDCODE_INIT ((UINT16)0x00) +#define HFA384x_CMDCODE_ENABLE ((UINT16)0x01) +#define HFA384x_CMDCODE_DISABLE ((UINT16)0x02) +#define HFA384x_CMDCODE_DIAG ((UINT16)0x03) + +/*--- Buffer Mgmt Commands --------------------------*/ +#define HFA384x_CMDCODE_ALLOC ((UINT16)0x0A) +#define HFA384x_CMDCODE_TX ((UINT16)0x0B) +#define HFA384x_CMDCODE_CLRPRST ((UINT16)0x12) + +/*--- Regulate Commands --------------------------*/ +#define HFA384x_CMDCODE_NOTIFY ((UINT16)0x10) +#define HFA384x_CMDCODE_INQ ((UINT16)0x11) + +/*--- Configure Commands --------------------------*/ +#define HFA384x_CMDCODE_ACCESS ((UINT16)0x21) +#define HFA384x_CMDCODE_DOWNLD ((UINT16)0x22) + +/*--- Debugging Commands -----------------------------*/ +#define HFA384x_CMDCODE_MONITOR ((UINT16)(0x38)) +#define HFA384x_MONITOR_ENABLE ((UINT16)(0x0b)) +#define HFA384x_MONITOR_DISABLE ((UINT16)(0x0f)) + +/*--- Result Codes --------------------------*/ +#define HFA384x_SUCCESS ((UINT16)(0x00)) +#define HFA384x_CARD_FAIL ((UINT16)(0x01)) +#define HFA384x_NO_BUFF ((UINT16)(0x05)) +#define HFA384x_CMD_ERR ((UINT16)(0x7F)) + +/*--- Programming Modes -------------------------- + MODE 0: Disable programming + MODE 1: Enable volatile memory programming + MODE 2: Enable non-volatile memory programming + MODE 3: Program non-volatile memory section +--------------------------------------------------*/ +#define HFA384x_PROGMODE_DISABLE ((UINT16)0x00) +#define HFA384x_PROGMODE_RAM ((UINT16)0x01) +#define HFA384x_PROGMODE_NV ((UINT16)0x02) +#define HFA384x_PROGMODE_NVWRITE ((UINT16)0x03) + +/*--- AUX register enable --------------------------*/ +#define HFA384x_AUXPW0 ((UINT16)0xfe01) +#define HFA384x_AUXPW1 ((UINT16)0xdc23) +#define HFA384x_AUXPW2 ((UINT16)0xba45) + +#define HFA384x_CONTROL_AUX_ISDISABLED ((UINT16)0x0000) +#define HFA384x_CONTROL_AUX_ISENABLED ((UINT16)0xc000) +#define HFA384x_CONTROL_AUX_DOENABLE ((UINT16)0x8000) +#define HFA384x_CONTROL_AUX_DODISABLE ((UINT16)0x4000) + +/*--- Record ID Constants --------------------------*/ +/*-------------------------------------------------------------------- +Configuration RIDs: Network Parameters, Static Configuration Entities +--------------------------------------------------------------------*/ +#define HFA384x_RID_CNFPORTTYPE ((UINT16)0xFC00) +#define HFA384x_RID_CNFOWNMACADDR ((UINT16)0xFC01) +#define HFA384x_RID_CNFDESIREDSSID ((UINT16)0xFC02) +#define HFA384x_RID_CNFOWNCHANNEL ((UINT16)0xFC03) +#define HFA384x_RID_CNFOWNSSID ((UINT16)0xFC04) +#define HFA384x_RID_CNFOWNATIMWIN ((UINT16)0xFC05) +#define HFA384x_RID_CNFSYSSCALE ((UINT16)0xFC06) +#define HFA384x_RID_CNFMAXDATALEN ((UINT16)0xFC07) +#define HFA384x_RID_CNFWDSADDR ((UINT16)0xFC08) +#define HFA384x_RID_CNFPMENABLED ((UINT16)0xFC09) +#define HFA384x_RID_CNFPMEPS ((UINT16)0xFC0A) +#define HFA384x_RID_CNFMULTICASTRX ((UINT16)0xFC0B) +#define HFA384x_RID_CNFMAXSLEEPDUR ((UINT16)0xFC0C) +#define HFA384x_RID_CNFPMHOLDDUR ((UINT16)0xFC0D) +#define HFA384x_RID_CNFOWNNAME ((UINT16)0xFC0E) +#define HFA384x_RID_CNFOWNDTIMPER ((UINT16)0xFC10) +#define HFA384x_RID_CNFWDSADDR1 ((UINT16)0xFC11) +#define HFA384x_RID_CNFWDSADDR2 ((UINT16)0xFC12) +#define HFA384x_RID_CNFWDSADDR3 ((UINT16)0xFC13) +#define HFA384x_RID_CNFWDSADDR4 ((UINT16)0xFC14) +#define HFA384x_RID_CNFWDSADDR5 ((UINT16)0xFC15) +#define HFA384x_RID_CNFWDSADDR6 ((UINT16)0xFC16) +#define HFA384x_RID_CNFMCASTPMBUFF ((UINT16)0xFC17) + +/*-------------------------------------------------------------------- +Configuration RID lengths: Network Params, Static Config Entities + This is the length of JUST the DATA part of the RID (does not + include the len or code fields) +--------------------------------------------------------------------*/ +/* TODO: fill in the rest of these */ +#define HFA384x_RID_CNFPORTTYPE_LEN ((UINT16)2) +#define HFA384x_RID_CNFOWNMACADDR_LEN ((UINT16)6) +#define HFA384x_RID_CNFDESIREDSSID_LEN ((UINT16)34) +#define HFA384x_RID_CNFOWNCHANNEL_LEN ((UINT16)2) +#define HFA384x_RID_CNFOWNSSID_LEN ((UINT16)34) +#define HFA384x_RID_CNFOWNATIMWIN_LEN ((UINT16)2) +#define HFA384x_RID_CNFSYSSCALE_LEN ((UINT16)0) +#define HFA384x_RID_CNFMAXDATALEN_LEN ((UINT16)0) +#define HFA384x_RID_CNFWDSADDR_LEN ((UINT16)6) +#define HFA384x_RID_CNFPMENABLED_LEN ((UINT16)0) +#define HFA384x_RID_CNFPMEPS_LEN ((UINT16)0) +#define HFA384x_RID_CNFMULTICASTRX_LEN ((UINT16)0) +#define HFA384x_RID_CNFMAXSLEEPDUR_LEN ((UINT16)0) +#define HFA384x_RID_CNFPMHOLDDUR_LEN ((UINT16)0) +#define HFA384x_RID_CNFOWNNAME_LEN ((UINT16)34) +#define HFA384x_RID_CNFOWNDTIMPER_LEN ((UINT16)0) +#define HFA384x_RID_CNFWDSADDR1_LEN ((UINT16)6) +#define HFA384x_RID_CNFWDSADDR2_LEN ((UINT16)6) +#define HFA384x_RID_CNFWDSADDR3_LEN ((UINT16)6) +#define HFA384x_RID_CNFWDSADDR4_LEN ((UINT16)6) +#define HFA384x_RID_CNFWDSADDR5_LEN ((UINT16)6) +#define HFA384x_RID_CNFWDSADDR6_LEN ((UINT16)6) +#define HFA384x_RID_CNFMCASTPMBUFF_LEN ((UINT16)0) +#define HFA384x_RID_CNFAUTHENTICATION_LEN ((UINT16)sizeof(UINT16)) +#define HFA384x_RID_CNFMAXSLEEPDUR_LEN ((UINT16)0) + +/*-------------------------------------------------------------------- +Configuration RIDs: Network Parameters, Dynamic Configuration Entities +--------------------------------------------------------------------*/ +#define HFA384x_RID_GROUPADDR ((UINT16)0xFC80) +#define HFA384x_RID_CREATEIBSS ((UINT16)0xFC81) +#define HFA384x_RID_FRAGTHRESH ((UINT16)0xFC82) +#define HFA384x_RID_RTSTHRESH ((UINT16)0xFC83) +#define HFA384x_RID_TXRATECNTL ((UINT16)0xFC84) +#define HFA384x_RID_PROMISCMODE ((UINT16)0xFC85) +#define HFA384x_RID_FRAGTHRESH0 ((UINT16)0xFC90) +#define HFA384x_RID_FRAGTHRESH1 ((UINT16)0xFC91) +#define HFA384x_RID_FRAGTHRESH2 ((UINT16)0xFC92) +#define HFA384x_RID_FRAGTHRESH3 ((UINT16)0xFC93) +#define HFA384x_RID_FRAGTHRESH4 ((UINT16)0xFC94) +#define HFA384x_RID_FRAGTHRESH5 ((UINT16)0xFC95) +#define HFA384x_RID_FRAGTHRESH6 ((UINT16)0xFC96) +#define HFA384x_RID_RTSTHRESH0 ((UINT16)0xFC97) +#define HFA384x_RID_RTSTHRESH1 ((UINT16)0xFC98) +#define HFA384x_RID_RTSTHRESH2 ((UINT16)0xFC99) +#define HFA384x_RID_RTSTHRESH3 ((UINT16)0xFC9A) +#define HFA384x_RID_RTSTHRESH4 ((UINT16)0xFC9B) +#define HFA384x_RID_RTSTHRESH5 ((UINT16)0xFC9C) +#define HFA384x_RID_RTSTHRESH6 ((UINT16)0xFC9D) +#define HFA384x_RID_TXRATECNTL0 ((UINT16)0xFC9E) +#define HFA384x_RID_TXRATECNTL1 ((UINT16)0xFC9F) +#define HFA384x_RID_TXRATECNTL2 ((UINT16)0xFCA0) +#define HFA384x_RID_TXRATECNTL3 ((UINT16)0xFCA1) +#define HFA384x_RID_TXRATECNTL4 ((UINT16)0xFCA2) +#define HFA384x_RID_TXRATECNTL5 ((UINT16)0xFCA3) +#define HFA384x_RID_TXRATECNTL6 ((UINT16)0xFCA4) + +/*-------------------------------------------------------------------- +Configuration RID Lengths: Network Param, Dynamic Config Entities + This is the length of JUST the DATA part of the RID (does not + include the len or code fields) +--------------------------------------------------------------------*/ +/* TODO: fill in the rest of these */ +#define HFA384x_RID_GROUPADDR_LEN ((UINT16)16 * WLAN_ADDR_LEN) +#define HFA384x_RID_CREATEIBSS_LEN ((UINT16)0) +#define HFA384x_RID_FRAGTHRESH_LEN ((UINT16)0) +#define HFA384x_RID_RTSTHRESH_LEN ((UINT16)0) +#define HFA384x_RID_TXRATECNTL_LEN ((UINT16)4) +#define HFA384x_RID_PROMISCMODE_LEN ((UINT16)2) +#define HFA384x_RID_FRAGTHRESH0_LEN ((UINT16)0) +#define HFA384x_RID_FRAGTHRESH1_LEN ((UINT16)0) +#define HFA384x_RID_FRAGTHRESH2_LEN ((UINT16)0) +#define HFA384x_RID_FRAGTHRESH3_LEN ((UINT16)0) +#define HFA384x_RID_FRAGTHRESH4_LEN ((UINT16)0) +#define HFA384x_RID_FRAGTHRESH5_LEN ((UINT16)0) +#define HFA384x_RID_FRAGTHRESH6_LEN ((UINT16)0) +#define HFA384x_RID_RTSTHRESH0_LEN ((UINT16)0) +#define HFA384x_RID_RTSTHRESH1_LEN ((UINT16)0) +#define HFA384x_RID_RTSTHRESH2_LEN ((UINT16)0) +#define HFA384x_RID_RTSTHRESH3_LEN ((UINT16)0) +#define HFA384x_RID_RTSTHRESH4_LEN ((UINT16)0) +#define HFA384x_RID_RTSTHRESH5_LEN ((UINT16)0) +#define HFA384x_RID_RTSTHRESH6_LEN ((UINT16)0) +#define HFA384x_RID_TXRATECNTL0_LEN ((UINT16)0) +#define HFA384x_RID_TXRATECNTL1_LEN ((UINT16)0) +#define HFA384x_RID_TXRATECNTL2_LEN ((UINT16)0) +#define HFA384x_RID_TXRATECNTL3_LEN ((UINT16)0) +#define HFA384x_RID_TXRATECNTL4_LEN ((UINT16)0) +#define HFA384x_RID_TXRATECNTL5_LEN ((UINT16)0) +#define HFA384x_RID_TXRATECNTL6_LEN ((UINT16)0) + +/*-------------------------------------------------------------------- +Configuration RIDs: Behavior Parameters +--------------------------------------------------------------------*/ +#define HFA384x_RID_ITICKTIME ((UINT16)0xFCE0) + +/*-------------------------------------------------------------------- +Configuration RID Lengths: Behavior Parameters + This is the length of JUST the DATA part of the RID (does not + include the len or code fields) +--------------------------------------------------------------------*/ +#define HFA384x_RID_ITICKTIME_LEN ((UINT16)2) + +/*---------------------------------------------------------------------- +Information RIDs: NIC Information +--------------------------------------------------------------------*/ +#define HFA384x_RID_MAXLOADTIME ((UINT16)0xFD00) +#define HFA384x_RID_DOWNLOADBUFFER ((UINT16)0xFD01) +#define HFA384x_RID_PRIIDENTITY ((UINT16)0xFD02) +#define HFA384x_RID_PRISUPRANGE ((UINT16)0xFD03) +#define HFA384x_RID_PRI_CFIACTRANGES ((UINT16)0xFD04) +#define HFA384x_RID_NICSERIALNUMBER ((UINT16)0xFD0A) +#define HFA384x_RID_NICIDENTITY ((UINT16)0xFD0B) +#define HFA384x_RID_MFISUPRANGE ((UINT16)0xFD0C) +#define HFA384x_RID_CFISUPRANGE ((UINT16)0xFD0D) +#define HFA384x_RID_CHANNELLIST ((UINT16)0xFD10) +#define HFA384x_RID_REGULATORYDOMAINS ((UINT16)0xFD11) +#define HFA384x_RID_TEMPTYPE ((UINT16)0xFD12) +#define HFA384x_RID_CIS ((UINT16)0xFD13) +#define HFA384x_RID_STAIDENTITY ((UINT16)0xFD20) +#define HFA384x_RID_STASUPRANGE ((UINT16)0xFD21) +#define HFA384x_RID_STA_MFIACTRANGES ((UINT16)0xFD22) +#define HFA384x_RID_STA_CFIACTRANGES ((UINT16)0xFD23) +#define HFA384x_RID_BUILDSEQ ((UINT16)0xFFFE) +#define HFA384x_RID_FWID ((UINT16)0xFFFF) + +/*---------------------------------------------------------------------- +Information RID Lengths: NIC Information + This is the length of JUST the DATA part of the RID (does not + include the len or code fields) +--------------------------------------------------------------------*/ +#define HFA384x_RID_MAXLOADTIME_LEN ((UINT16)0) +#define HFA384x_RID_DOWNLOADBUFFER_LEN ((UINT16)sizeof(hfa384x_downloadbuffer_t)) +#define HFA384x_RID_PRIIDENTITY_LEN ((UINT16)8) +#define HFA384x_RID_PRISUPRANGE_LEN ((UINT16)10) +#define HFA384x_RID_CFIACTRANGES_LEN ((UINT16)10) +#define HFA384x_RID_NICSERIALNUMBER_LEN ((UINT16)12) +#define HFA384x_RID_NICIDENTITY_LEN ((UINT16)8) +#define HFA384x_RID_MFISUPRANGE_LEN ((UINT16)10) +#define HFA384x_RID_CFISUPRANGE_LEN ((UINT16)10) +#define HFA384x_RID_CHANNELLIST_LEN ((UINT16)0) +#define HFA384x_RID_REGULATORYDOMAINS_LEN ((UINT16)12) +#define HFA384x_RID_TEMPTYPE_LEN ((UINT16)0) +#define HFA384x_RID_CIS_LEN ((UINT16)480) +#define HFA384x_RID_STAIDENTITY_LEN ((UINT16)8) +#define HFA384x_RID_STASUPRANGE_LEN ((UINT16)10) +#define HFA384x_RID_MFIACTRANGES_LEN ((UINT16)10) +#define HFA384x_RID_CFIACTRANGES2_LEN ((UINT16)10) +#define HFA384x_RID_BUILDSEQ_LEN ((UINT16)sizeof(hfa384x_BuildSeq_t)) +#define HFA384x_RID_FWID_LEN ((UINT16)sizeof(hfa384x_FWID_t)) + +/*-------------------------------------------------------------------- +Information RIDs: MAC Information +--------------------------------------------------------------------*/ +#define HFA384x_RID_PORTSTATUS ((UINT16)0xFD40) +#define HFA384x_RID_CURRENTSSID ((UINT16)0xFD41) +#define HFA384x_RID_CURRENTBSSID ((UINT16)0xFD42) +#define HFA384x_RID_COMMSQUALITY ((UINT16)0xFD43) +#define HFA384x_RID_CURRENTTXRATE ((UINT16)0xFD44) +#define HFA384x_RID_CURRENTBCNINT ((UINT16)0xFD45) +#define HFA384x_RID_CURRENTSCALETHRESH ((UINT16)0xFD46) +#define HFA384x_RID_PROTOCOLRSPTIME ((UINT16)0xFD47) +#define HFA384x_RID_SHORTRETRYLIMIT ((UINT16)0xFD48) +#define HFA384x_RID_LONGRETRYLIMIT ((UINT16)0xFD49) +#define HFA384x_RID_MAXTXLIFETIME ((UINT16)0xFD4A) +#define HFA384x_RID_MAXRXLIFETIME ((UINT16)0xFD4B) +#define HFA384x_RID_CFPOLLABLE ((UINT16)0xFD4C) +#define HFA384x_RID_AUTHALGORITHMS ((UINT16)0xFD4D) +#define HFA384x_RID_PRIVACYOPTIMP ((UINT16)0xFD4F) +#define HFA384x_RID_DBMCOMMSQUALITY ((UINT16)0xFD51) +#define HFA384x_RID_CURRENTTXRATE1 ((UINT16)0xFD80) +#define HFA384x_RID_CURRENTTXRATE2 ((UINT16)0xFD81) +#define HFA384x_RID_CURRENTTXRATE3 ((UINT16)0xFD82) +#define HFA384x_RID_CURRENTTXRATE4 ((UINT16)0xFD83) +#define HFA384x_RID_CURRENTTXRATE5 ((UINT16)0xFD84) +#define HFA384x_RID_CURRENTTXRATE6 ((UINT16)0xFD85) +#define HFA384x_RID_OWNMACADDRESS ((UINT16)0xFD86) +// #define HFA384x_RID_PCFINFO ((UINT16)0xFD87) +#define HFA384x_RID_SCANRESULTS ((UINT16)0xFD88) // NEW +#define HFA384x_RID_HOSTSCANRESULTS ((UINT16)0xFD89) // NEW +#define HFA384x_RID_AUTHENTICATIONUSED ((UINT16)0xFD8A) // NEW +#define HFA384x_RID_ASSOCIATEFAILURE ((UINT16)0xFD8D) // 1.8.0 + +/*-------------------------------------------------------------------- +Information RID Lengths: MAC Information + This is the length of JUST the DATA part of the RID (does not + include the len or code fields) +--------------------------------------------------------------------*/ +#define HFA384x_RID_PORTSTATUS_LEN ((UINT16)0) +#define HFA384x_RID_CURRENTSSID_LEN ((UINT16)34) +#define HFA384x_RID_CURRENTBSSID_LEN ((UINT16)WLAN_BSSID_LEN) +#define HFA384x_RID_COMMSQUALITY_LEN ((UINT16)sizeof(hfa384x_commsquality_t)) +#define HFA384x_RID_DBMCOMMSQUALITY_LEN ((UINT16)sizeof(hfa384x_dbmcommsquality_t)) +#define HFA384x_RID_CURRENTTXRATE_LEN ((UINT16)0) +#define HFA384x_RID_CURRENTBCNINT_LEN ((UINT16)0) +#define HFA384x_RID_STACURSCALETHRESH_LEN ((UINT16)12) +#define HFA384x_RID_APCURSCALETHRESH_LEN ((UINT16)6) +#define HFA384x_RID_PROTOCOLRSPTIME_LEN ((UINT16)0) +#define HFA384x_RID_SHORTRETRYLIMIT_LEN ((UINT16)0) +#define HFA384x_RID_LONGRETRYLIMIT_LEN ((UINT16)0) +#define HFA384x_RID_MAXTXLIFETIME_LEN ((UINT16)0) +#define HFA384x_RID_MAXRXLIFETIME_LEN ((UINT16)0) +#define HFA384x_RID_CFPOLLABLE_LEN ((UINT16)0) +#define HFA384x_RID_AUTHALGORITHMS_LEN ((UINT16)4) +#define HFA384x_RID_PRIVACYOPTIMP_LEN ((UINT16)0) +#define HFA384x_RID_CURRENTTXRATE1_LEN ((UINT16)0) +#define HFA384x_RID_CURRENTTXRATE2_LEN ((UINT16)0) +#define HFA384x_RID_CURRENTTXRATE3_LEN ((UINT16)0) +#define HFA384x_RID_CURRENTTXRATE4_LEN ((UINT16)0) +#define HFA384x_RID_CURRENTTXRATE5_LEN ((UINT16)0) +#define HFA384x_RID_CURRENTTXRATE6_LEN ((UINT16)0) +#define HFA384x_RID_OWNMACADDRESS_LEN ((UINT16)6) +#define HFA384x_RID_PCFINFO_LEN ((UINT16)6) +#define HFA384x_RID_CNFAPPCFINFO_LEN ((UINT16)sizeof(hfa384x_PCFInfo_data_t)) +#define HFA384x_RID_SCANREQUEST_LEN ((UINT16)sizeof(hfa384x_ScanRequest_data_t)) +#define HFA384x_RID_JOINREQUEST_LEN ((UINT16)sizeof(hfa384x_JoinRequest_data_t)) +#define HFA384x_RID_AUTHENTICATESTA_LEN ((UINT16)sizeof(hfa384x_authenticateStation_data_t)) +#define HFA384x_RID_CHANNELINFOREQUEST_LEN ((UINT16)sizeof(hfa384x_ChannelInfoRequest_data_t)) +/*-------------------------------------------------------------------- +Information RIDs: Modem Information +--------------------------------------------------------------------*/ +#define HFA384x_RID_PHYTYPE ((UINT16)0xFDC0) +#define HFA384x_RID_CURRENTCHANNEL ((UINT16)0xFDC1) +#define HFA384x_RID_CURRENTPOWERSTATE ((UINT16)0xFDC2) +#define HFA384x_RID_CCAMODE ((UINT16)0xFDC3) +#define HFA384x_RID_SUPPORTEDDATARATES ((UINT16)0xFDC6) +#define HFA384x_RID_LFOSTATUS ((UINT16)0xFDC7) // 1.7.1 + +/*-------------------------------------------------------------------- +Information RID Lengths: Modem Information + This is the length of JUST the DATA part of the RID (does not + include the len or code fields) +--------------------------------------------------------------------*/ +#define HFA384x_RID_PHYTYPE_LEN ((UINT16)0) +#define HFA384x_RID_CURRENTCHANNEL_LEN ((UINT16)0) +#define HFA384x_RID_CURRENTPOWERSTATE_LEN ((UINT16)0) +#define HFA384x_RID_CCAMODE_LEN ((UINT16)0) +#define HFA384x_RID_SUPPORTEDDATARATES_LEN ((UINT16)10) + +/*-------------------------------------------------------------------- +API ENHANCEMENTS (NOT ALREADY IMPLEMENTED) +--------------------------------------------------------------------*/ +#define HFA384x_RID_CNFWEPDEFAULTKEYID ((UINT16)0xFC23) +#define HFA384x_RID_CNFWEPDEFAULTKEY0 ((UINT16)0xFC24) +#define HFA384x_RID_CNFWEPDEFAULTKEY1 ((UINT16)0xFC25) +#define HFA384x_RID_CNFWEPDEFAULTKEY2 ((UINT16)0xFC26) +#define HFA384x_RID_CNFWEPDEFAULTKEY3 ((UINT16)0xFC27) +#define HFA384x_RID_CNFWEPFLAGS ((UINT16)0xFC28) +#define HFA384x_RID_CNFWEPKEYMAPTABLE ((UINT16)0xFC29) +#define HFA384x_RID_CNFAUTHENTICATION ((UINT16)0xFC2A) +#define HFA384x_RID_CNFMAXASSOCSTATIONS ((UINT16)0xFC2B) +#define HFA384x_RID_CNFTXCONTROL ((UINT16)0xFC2C) +#define HFA384x_RID_CNFROAMINGMODE ((UINT16)0xFC2D) +#define HFA384x_RID_CNFHOSTAUTHASSOC ((UINT16)0xFC2E) +#define HFA384x_RID_CNFRCVCRCERROR ((UINT16)0xFC30) +// #define HFA384x_RID_CNFMMLIFE ((UINT16)0xFC31) +#define HFA384x_RID_CNFALTRETRYCNT ((UINT16)0xFC32) +#define HFA384x_RID_CNFAPBCNINT ((UINT16)0xFC33) +#define HFA384x_RID_CNFAPPCFINFO ((UINT16)0xFC34) +#define HFA384x_RID_CNFSTAPCFINFO ((UINT16)0xFC35) +#define HFA384x_RID_CNFPRIORITYQUSAGE ((UINT16)0xFC37) +#define HFA384x_RID_CNFTIMCTRL ((UINT16)0xFC40) +#define HFA384x_RID_CNFTHIRTY2TALLY ((UINT16)0xFC42) +#define HFA384x_RID_CNFENHSECURITY ((UINT16)0xFC43) +#define HFA384x_RID_CNFDBMADJUST ((UINT16)0xFC46) // NEW +#define HFA384x_RID_CNFWPADATA ((UINT16)0xFC48) // 1.7.0 +#define HFA384x_RID_CNFPROPOGATIONDELAY ((UINT16)0xFC49) // 1.7.6 +#define HFA384x_RID_CNFSHORTPREAMBLE ((UINT16)0xFCB0) +#define HFA384x_RID_CNFEXCLONGPREAMBLE ((UINT16)0xFCB1) +#define HFA384x_RID_CNFAUTHRSPTIMEOUT ((UINT16)0xFCB2) +#define HFA384x_RID_CNFBASICRATES ((UINT16)0xFCB3) +#define HFA384x_RID_CNFSUPPRATES ((UINT16)0xFCB4) +#define HFA384x_RID_CNFFALLBACKCTRL ((UINT16)0xFCB5) // NEW +#define HFA384x_RID_WEPKEYSTATUS ((UINT16)0xFCB6) // NEW +#define HFA384x_RID_WEPKEYMAPINDEX ((UINT16)0xFCB7) // NEW +#define HFA384x_RID_BROADCASTKEYID ((UINT16)0xFCB8) // NEW +#define HFA384x_RID_ENTSECFLAGEYID ((UINT16)0xFCB9) // NEW +#define HFA384x_RID_CNFPASSIVESCANCTRL ((UINT16)0xFCBA) // NEW STA +#define HFA384x_RID_CNFWPAHANDLING ((UINT16)0xFCBB) // 1.7.0 +#define HFA384x_RID_MDCCONTROL ((UINT16)0xFCBC) // 1.7.0/1.4.0 +#define HFA384x_RID_MDCCOUNTRY ((UINT16)0xFCBD) // 1.7.0/1.4.0 +#define HFA384x_RID_TXPOWERMAX ((UINT16)0xFCBE) // 1.7.0/1.4.0 +#define HFA384x_RID_CNFLFOENBLED ((UINT16)0xFCBF) // 1.6.3 +#define HFA384x_RID_CAPINFO ((UINT16)0xFCC0) // 1.7.0/1.3.7 +#define HFA384x_RID_LISTENINTERVAL ((UINT16)0xFCC1) // 1.7.0/1.3.7 +#define HFA384x_RID_DIVERSITYENABLED ((UINT16)0xFCC2) // 1.7.0/1.3.7 +#define HFA384x_RID_LED_CONTROL ((UINT16)0xFCC4) // 1.7.6 +#define HFA384x_RID_HFO_DELAY ((UINT16)0xFCC5) // 1.7.6 +#define HFA384x_RID_DISSALOWEDBSSID ((UINT16)0xFCC6) // 1.8.0 +#define HFA384x_RID_SCANREQUEST ((UINT16)0xFCE1) +#define HFA384x_RID_JOINREQUEST ((UINT16)0xFCE2) +#define HFA384x_RID_AUTHENTICATESTA ((UINT16)0xFCE3) +#define HFA384x_RID_CHANNELINFOREQUEST ((UINT16)0xFCE4) +#define HFA384x_RID_HOSTSCAN ((UINT16)0xFCE5) // NEW STA +#define HFA384x_RID_ASSOCIATESTA ((UINT16)0xFCE6) + +#define HFA384x_RID_CNFWEPDEFAULTKEY_LEN ((UINT16)6) +#define HFA384x_RID_CNFWEP128DEFAULTKEY_LEN ((UINT16)14) +#define HFA384x_RID_CNFPRIOQUSAGE_LEN ((UINT16)4) +/*-------------------------------------------------------------------- +PD Record codes +--------------------------------------------------------------------*/ +#define HFA384x_PDR_PCB_PARTNUM ((UINT16)0x0001) +#define HFA384x_PDR_PDAVER ((UINT16)0x0002) +#define HFA384x_PDR_NIC_SERIAL ((UINT16)0x0003) +#define HFA384x_PDR_MKK_MEASUREMENTS ((UINT16)0x0004) +#define HFA384x_PDR_NIC_RAMSIZE ((UINT16)0x0005) +#define HFA384x_PDR_MFISUPRANGE ((UINT16)0x0006) +#define HFA384x_PDR_CFISUPRANGE ((UINT16)0x0007) +#define HFA384x_PDR_NICID ((UINT16)0x0008) +//#define HFA384x_PDR_REFDAC_MEASUREMENTS ((UINT16)0x0010) +//#define HFA384x_PDR_VGDAC_MEASUREMENTS ((UINT16)0x0020) +//#define HFA384x_PDR_LEVEL_COMP_MEASUREMENTS ((UINT16)0x0030) +//#define HFA384x_PDR_MODEM_TRIMDAC_MEASUREMENTS ((UINT16)0x0040) +//#define HFA384x_PDR_COREGA_HACK ((UINT16)0x00ff) +#define HFA384x_PDR_MAC_ADDRESS ((UINT16)0x0101) +//#define HFA384x_PDR_MKK_CALLNAME ((UINT16)0x0102) +#define HFA384x_PDR_REGDOMAIN ((UINT16)0x0103) +#define HFA384x_PDR_ALLOWED_CHANNEL ((UINT16)0x0104) +#define HFA384x_PDR_DEFAULT_CHANNEL ((UINT16)0x0105) +//#define HFA384x_PDR_PRIVACY_OPTION ((UINT16)0x0106) +#define HFA384x_PDR_TEMPTYPE ((UINT16)0x0107) +//#define HFA384x_PDR_REFDAC_SETUP ((UINT16)0x0110) +//#define HFA384x_PDR_VGDAC_SETUP ((UINT16)0x0120) +//#define HFA384x_PDR_LEVEL_COMP_SETUP ((UINT16)0x0130) +//#define HFA384x_PDR_TRIMDAC_SETUP ((UINT16)0x0140) +#define HFA384x_PDR_IFR_SETTING ((UINT16)0x0200) +#define HFA384x_PDR_RFR_SETTING ((UINT16)0x0201) +#define HFA384x_PDR_HFA3861_BASELINE ((UINT16)0x0202) +#define HFA384x_PDR_HFA3861_SHADOW ((UINT16)0x0203) +#define HFA384x_PDR_HFA3861_IFRF ((UINT16)0x0204) +#define HFA384x_PDR_HFA3861_CHCALSP ((UINT16)0x0300) +#define HFA384x_PDR_HFA3861_CHCALI ((UINT16)0x0301) +#define HFA384x_PDR_MAX_TX_POWER ((UINT16)0x0302) +#define HFA384x_PDR_MASTER_CHAN_LIST ((UINT16)0x0303) +#define HFA384x_PDR_3842_NIC_CONFIG ((UINT16)0x0400) +#define HFA384x_PDR_USB_ID ((UINT16)0x0401) +#define HFA384x_PDR_PCI_ID ((UINT16)0x0402) +#define HFA384x_PDR_PCI_IFCONF ((UINT16)0x0403) +#define HFA384x_PDR_PCI_PMCONF ((UINT16)0x0404) +#define HFA384x_PDR_RFENRGY ((UINT16)0x0406) +#define HFA384x_PDR_USB_POWER_TYPE ((UINT16)0x0407) +//#define HFA384x_PDR_UNKNOWN408 ((UINT16)0x0408) +#define HFA384x_PDR_USB_MAX_POWER ((UINT16)0x0409) +#define HFA384x_PDR_USB_MANUFACTURER ((UINT16)0x0410) +#define HFA384x_PDR_USB_PRODUCT ((UINT16)0x0411) +#define HFA384x_PDR_ANT_DIVERSITY ((UINT16)0x0412) +#define HFA384x_PDR_HFO_DELAY ((UINT16)0x0413) +#define HFA384x_PDR_SCALE_THRESH ((UINT16)0x0414) + +#define HFA384x_PDR_HFA3861_MANF_TESTSP ((UINT16)0x0900) +#define HFA384x_PDR_HFA3861_MANF_TESTI ((UINT16)0x0901) +#define HFA384x_PDR_END_OF_PDA ((UINT16)0x0000) + + +/*=============================================================*/ +/*------ Macros -----------------------------------------------*/ + +/*--- Register ID macros ------------------------*/ + +#define HFA384x_CMD HFA384x_CMD_OFF +#define HFA384x_PARAM0 HFA384x_PARAM0_OFF +#define HFA384x_PARAM1 HFA384x_PARAM1_OFF +#define HFA384x_PARAM2 HFA384x_PARAM2_OFF +#define HFA384x_STATUS HFA384x_STATUS_OFF +#define HFA384x_RESP0 HFA384x_RESP0_OFF +#define HFA384x_RESP1 HFA384x_RESP1_OFF +#define HFA384x_RESP2 HFA384x_RESP2_OFF +#define HFA384x_INFOFID HFA384x_INFOFID_OFF +#define HFA384x_RXFID HFA384x_RXFID_OFF +#define HFA384x_ALLOCFID HFA384x_ALLOCFID_OFF +#define HFA384x_TXCOMPLFID HFA384x_TXCOMPLFID_OFF +#define HFA384x_SELECT0 HFA384x_SELECT0_OFF +#define HFA384x_OFFSET0 HFA384x_OFFSET0_OFF +#define HFA384x_DATA0 HFA384x_DATA0_OFF +#define HFA384x_SELECT1 HFA384x_SELECT1_OFF +#define HFA384x_OFFSET1 HFA384x_OFFSET1_OFF +#define HFA384x_DATA1 HFA384x_DATA1_OFF +#define HFA384x_EVSTAT HFA384x_EVSTAT_OFF +#define HFA384x_INTEN HFA384x_INTEN_OFF +#define HFA384x_EVACK HFA384x_EVACK_OFF +#define HFA384x_CONTROL HFA384x_CONTROL_OFF +#define HFA384x_SWSUPPORT0 HFA384x_SWSUPPORT0_OFF +#define HFA384x_SWSUPPORT1 HFA384x_SWSUPPORT1_OFF +#define HFA384x_SWSUPPORT2 HFA384x_SWSUPPORT2_OFF +#define HFA384x_AUXPAGE HFA384x_AUXPAGE_OFF +#define HFA384x_AUXOFFSET HFA384x_AUXOFFSET_OFF +#define HFA384x_AUXDATA HFA384x_AUXDATA_OFF +#define HFA384x_PCICOR HFA384x_PCICOR_OFF +#define HFA384x_PCIHCR HFA384x_PCIHCR_OFF + + +/*--- Register Test/Get/Set Field macros ------------------------*/ + +#define HFA384x_CMD_ISBUSY(value) ((UINT16)(((UINT16)value) & HFA384x_CMD_BUSY)) +#define HFA384x_CMD_AINFO_GET(value) ((UINT16)(((UINT16)(value) & HFA384x_CMD_AINFO) >> 8)) +#define HFA384x_CMD_AINFO_SET(value) ((UINT16)((UINT16)(value) << 8)) +#define HFA384x_CMD_MACPORT_GET(value) ((UINT16)(HFA384x_CMD_AINFO_GET((UINT16)(value) & HFA384x_CMD_MACPORT))) +#define HFA384x_CMD_MACPORT_SET(value) ((UINT16)HFA384x_CMD_AINFO_SET(value)) +#define HFA384x_CMD_ISRECL(value) ((UINT16)(HFA384x_CMD_AINFO_GET((UINT16)(value) & HFA384x_CMD_RECL))) +#define HFA384x_CMD_RECL_SET(value) ((UINT16)HFA384x_CMD_AINFO_SET(value)) +#define HFA384x_CMD_QOS_GET(value) ((UINT16((((UINT16)(value))&((UINT16)0x3000)) >> 12)) +#define HFA384x_CMD_QOS_SET(value) ((UINT16)((((UINT16)(value)) << 12) & 0x3000)) +#define HFA384x_CMD_ISWRITE(value) ((UINT16)(HFA384x_CMD_AINFO_GET((UINT16)(value) & HFA384x_CMD_WRITE))) +#define HFA384x_CMD_WRITE_SET(value) ((UINT16)HFA384x_CMD_AINFO_SET((UINT16)value)) +#define HFA384x_CMD_PROGMODE_GET(value) ((UINT16)(HFA384x_CMD_AINFO_GET((UINT16)(value) & HFA384x_CMD_PROGMODE))) +#define HFA384x_CMD_PROGMODE_SET(value) ((UINT16)HFA384x_CMD_AINFO_SET((UINT16)value)) +#define HFA384x_CMD_CMDCODE_GET(value) ((UINT16)(((UINT16)(value)) & HFA384x_CMD_CMDCODE)) +#define HFA384x_CMD_CMDCODE_SET(value) ((UINT16)(value)) + +#define HFA384x_STATUS_RESULT_GET(value) ((UINT16)((((UINT16)(value)) & HFA384x_STATUS_RESULT) >> 8)) +#define HFA384x_STATUS_RESULT_SET(value) (((UINT16)(value)) << 8) +#define HFA384x_STATUS_CMDCODE_GET(value) (((UINT16)(value)) & HFA384x_STATUS_CMDCODE) +#define HFA384x_STATUS_CMDCODE_SET(value) ((UINT16)(value)) + +#define HFA384x_OFFSET_ISBUSY(value) ((UINT16)(((UINT16)(value)) & HFA384x_OFFSET_BUSY)) +#define HFA384x_OFFSET_ISERR(value) ((UINT16)(((UINT16)(value)) & HFA384x_OFFSET_ERR)) +#define HFA384x_OFFSET_DATAOFF_GET(value) ((UINT16)(((UINT16)(value)) & HFA384x_OFFSET_DATAOFF)) +#define HFA384x_OFFSET_DATAOFF_SET(value) ((UINT16)(value)) + +#define HFA384x_EVSTAT_ISTICK(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_TICK)) +#define HFA384x_EVSTAT_ISWTERR(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_WTERR)) +#define HFA384x_EVSTAT_ISINFDROP(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_INFDROP)) +#define HFA384x_EVSTAT_ISINFO(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_INFO)) +#define HFA384x_EVSTAT_ISDTIM(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_DTIM)) +#define HFA384x_EVSTAT_ISCMD(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_CMD)) +#define HFA384x_EVSTAT_ISALLOC(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_ALLOC)) +#define HFA384x_EVSTAT_ISTXEXC(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_TXEXC)) +#define HFA384x_EVSTAT_ISTX(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_TX)) +#define HFA384x_EVSTAT_ISRX(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_RX)) + +#define HFA384x_EVSTAT_ISBAP_OP(value) ((UINT16)(((UINT16)(value)) & HFA384x_INT_BAP_OP)) + +#define HFA384x_INTEN_ISTICK(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_TICK)) +#define HFA384x_INTEN_TICK_SET(value) ((UINT16)(((UINT16)(value)) << 15)) +#define HFA384x_INTEN_ISWTERR(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_WTERR)) +#define HFA384x_INTEN_WTERR_SET(value) ((UINT16)(((UINT16)(value)) << 14)) +#define HFA384x_INTEN_ISINFDROP(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_INFDROP)) +#define HFA384x_INTEN_INFDROP_SET(value) ((UINT16)(((UINT16)(value)) << 13)) +#define HFA384x_INTEN_ISINFO(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_INFO)) +#define HFA384x_INTEN_INFO_SET(value) ((UINT16)(((UINT16)(value)) << 7)) +#define HFA384x_INTEN_ISDTIM(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_DTIM)) +#define HFA384x_INTEN_DTIM_SET(value) ((UINT16)(((UINT16)(value)) << 5)) +#define HFA384x_INTEN_ISCMD(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_CMD)) +#define HFA384x_INTEN_CMD_SET(value) ((UINT16)(((UINT16)(value)) << 4)) +#define HFA384x_INTEN_ISALLOC(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_ALLOC)) +#define HFA384x_INTEN_ALLOC_SET(value) ((UINT16)(((UINT16)(value)) << 3)) +#define HFA384x_INTEN_ISTXEXC(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_TXEXC)) +#define HFA384x_INTEN_TXEXC_SET(value) ((UINT16)(((UINT16)(value)) << 2)) +#define HFA384x_INTEN_ISTX(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_TX)) +#define HFA384x_INTEN_TX_SET(value) ((UINT16)(((UINT16)(value)) << 1)) +#define HFA384x_INTEN_ISRX(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_RX)) +#define HFA384x_INTEN_RX_SET(value) ((UINT16)(((UINT16)(value)) << 0)) + +#define HFA384x_EVACK_ISTICK(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_TICK)) +#define HFA384x_EVACK_TICK_SET(value) ((UINT16)(((UINT16)(value)) << 15)) +#define HFA384x_EVACK_ISWTERR(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_WTERR)) +#define HFA384x_EVACK_WTERR_SET(value) ((UINT16)(((UINT16)(value)) << 14)) +#define HFA384x_EVACK_ISINFDROP(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_INFDROP)) +#define HFA384x_EVACK_INFDROP_SET(value) ((UINT16)(((UINT16)(value)) << 13)) +#define HFA384x_EVACK_ISINFO(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_INFO)) +#define HFA384x_EVACK_INFO_SET(value) ((UINT16)(((UINT16)(value)) << 7)) +#define HFA384x_EVACK_ISDTIM(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_DTIM)) +#define HFA384x_EVACK_DTIM_SET(value) ((UINT16)(((UINT16)(value)) << 5)) +#define HFA384x_EVACK_ISCMD(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_CMD)) +#define HFA384x_EVACK_CMD_SET(value) ((UINT16)(((UINT16)(value)) << 4)) +#define HFA384x_EVACK_ISALLOC(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_ALLOC)) +#define HFA384x_EVACK_ALLOC_SET(value) ((UINT16)(((UINT16)(value)) << 3)) +#define HFA384x_EVACK_ISTXEXC(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_TXEXC)) +#define HFA384x_EVACK_TXEXC_SET(value) ((UINT16)(((UINT16)(value)) << 2)) +#define HFA384x_EVACK_ISTX(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_TX)) +#define HFA384x_EVACK_TX_SET(value) ((UINT16)(((UINT16)(value)) << 1)) +#define HFA384x_EVACK_ISRX(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_RX)) +#define HFA384x_EVACK_RX_SET(value) ((UINT16)(((UINT16)(value)) << 0)) + +#define HFA384x_CONTROL_AUXEN_SET(value) ((UINT16)(((UINT16)(value)) << 14)) +#define HFA384x_CONTROL_AUXEN_GET(value) ((UINT16)(((UINT16)(value)) >> 14)) + +/* Byte Order */ +#ifdef __KERNEL__ +#define hfa384x2host_16(n) (__le16_to_cpu((UINT16)(n))) +#define hfa384x2host_32(n) (__le32_to_cpu((UINT32)(n))) +#define host2hfa384x_16(n) (__cpu_to_le16((UINT16)(n))) +#define host2hfa384x_32(n) (__cpu_to_le32((UINT32)(n))) +#endif + +/* Host Maintained State Info */ +#define HFA384x_STATE_PREINIT 0 +#define HFA384x_STATE_INIT 1 +#define HFA384x_STATE_RUNNING 2 + +/*=============================================================*/ +/*------ Types and their related constants --------------------*/ + +#define HFA384x_HOSTAUTHASSOC_HOSTAUTH BIT0 +#define HFA384x_HOSTAUTHASSOC_HOSTASSOC BIT1 + +#define HFA384x_WHAHANDLING_DISABLED 0 +#define HFA384x_WHAHANDLING_PASSTHROUGH BIT1 + +/*-------------------------------------------------------------*/ +/* Commonly used basic types */ +typedef struct hfa384x_bytestr +{ + UINT16 len; + UINT8 data[0]; +} __WLAN_ATTRIB_PACK__ hfa384x_bytestr_t; + +typedef struct hfa384x_bytestr32 +{ + UINT16 len; + UINT8 data[32]; +} __WLAN_ATTRIB_PACK__ hfa384x_bytestr32_t; + +/*-------------------------------------------------------------------- +Configuration Record Structures: + Network Parameters, Static Configuration Entities +--------------------------------------------------------------------*/ +/* Prototype structure: all configuration record structures start with +these members */ + +typedef struct hfa384x_record +{ + UINT16 reclen; + UINT16 rid; +} __WLAN_ATTRIB_PACK__ hfa384x_rec_t; + +typedef struct hfa384x_record16 +{ + UINT16 reclen; + UINT16 rid; + UINT16 val; +} __WLAN_ATTRIB_PACK__ hfa384x_rec16_t; + +typedef struct hfa384x_record32 +{ + UINT16 reclen; + UINT16 rid; + UINT32 val; +} __WLAN_ATTRIB_PACK__ hfa384x_rec32; + +/*-- Hardware/Firmware Component Information ----------*/ +typedef struct hfa384x_compident +{ + UINT16 id; + UINT16 variant; + UINT16 major; + UINT16 minor; +} __WLAN_ATTRIB_PACK__ hfa384x_compident_t; + +typedef struct hfa384x_caplevel +{ + UINT16 role; + UINT16 id; + UINT16 variant; + UINT16 bottom; + UINT16 top; +} __WLAN_ATTRIB_PACK__ hfa384x_caplevel_t; + +/*-- Configuration Record: cnfPortType --*/ +typedef struct hfa384x_cnfPortType +{ + UINT16 cnfPortType; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfPortType_t; + +/*-- Configuration Record: cnfOwnMACAddress --*/ +typedef struct hfa384x_cnfOwnMACAddress +{ + UINT8 cnfOwnMACAddress[6]; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnMACAddress_t; + +/*-- Configuration Record: cnfDesiredSSID --*/ +typedef struct hfa384x_cnfDesiredSSID +{ + UINT8 cnfDesiredSSID[34]; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfDesiredSSID_t; + +/*-- Configuration Record: cnfOwnChannel --*/ +typedef struct hfa384x_cnfOwnChannel +{ + UINT16 cnfOwnChannel; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnChannel_t; + +/*-- Configuration Record: cnfOwnSSID --*/ +typedef struct hfa384x_cnfOwnSSID +{ + UINT8 cnfOwnSSID[34]; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnSSID_t; + +/*-- Configuration Record: cnfOwnATIMWindow --*/ +typedef struct hfa384x_cnfOwnATIMWindow +{ + UINT16 cnfOwnATIMWindow; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnATIMWindow_t; + +/*-- Configuration Record: cnfSystemScale --*/ +typedef struct hfa384x_cnfSystemScale +{ + UINT16 cnfSystemScale; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfSystemScale_t; + +/*-- Configuration Record: cnfMaxDataLength --*/ +typedef struct hfa384x_cnfMaxDataLength +{ + UINT16 cnfMaxDataLength; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfMaxDataLength_t; + +/*-- Configuration Record: cnfWDSAddress --*/ +typedef struct hfa384x_cnfWDSAddress +{ + UINT8 cnfWDSAddress[6]; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfWDSAddress_t; + +/*-- Configuration Record: cnfPMEnabled --*/ +typedef struct hfa384x_cnfPMEnabled +{ + UINT16 cnfPMEnabled; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfPMEnabled_t; + +/*-- Configuration Record: cnfPMEPS --*/ +typedef struct hfa384x_cnfPMEPS +{ + UINT16 cnfPMEPS; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfPMEPS_t; + +/*-- Configuration Record: cnfMulticastReceive --*/ +typedef struct hfa384x_cnfMulticastReceive +{ + UINT16 cnfMulticastReceive; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfMulticastReceive_t; + +/*-- Configuration Record: cnfAuthentication --*/ +#define HFA384x_CNFAUTHENTICATION_OPENSYSTEM 0x0001 +#define HFA384x_CNFAUTHENTICATION_SHAREDKEY 0x0002 +#define HFA384x_CNFAUTHENTICATION_LEAP 0x0004 + +/*-- Configuration Record: cnfMaxSleepDuration --*/ +typedef struct hfa384x_cnfMaxSleepDuration +{ + UINT16 cnfMaxSleepDuration; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfMaxSleepDuration_t; + +/*-- Configuration Record: cnfPMHoldoverDuration --*/ +typedef struct hfa384x_cnfPMHoldoverDuration +{ + UINT16 cnfPMHoldoverDuration; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfPMHoldoverDuration_t; + +/*-- Configuration Record: cnfOwnName --*/ +typedef struct hfa384x_cnfOwnName +{ + UINT8 cnfOwnName[34]; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnName_t; + +/*-- Configuration Record: cnfOwnDTIMPeriod --*/ +typedef struct hfa384x_cnfOwnDTIMPeriod +{ + UINT16 cnfOwnDTIMPeriod; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnDTIMPeriod_t; + +/*-- Configuration Record: cnfWDSAddress --*/ +typedef struct hfa384x_cnfWDSAddressN +{ + UINT8 cnfWDSAddress[6]; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfWDSAddressN_t; + +/*-- Configuration Record: cnfMulticastPMBuffering --*/ +typedef struct hfa384x_cnfMulticastPMBuffering +{ + UINT16 cnfMulticastPMBuffering; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfMulticastPMBuffering_t; + +/*-------------------------------------------------------------------- +Configuration Record Structures: + Network Parameters, Dynamic Configuration Entities +--------------------------------------------------------------------*/ + +/*-- Configuration Record: GroupAddresses --*/ +typedef struct hfa384x_GroupAddresses +{ + UINT8 MACAddress[16][6]; +} __WLAN_ATTRIB_PACK__ hfa384x_GroupAddresses_t; + +/*-- Configuration Record: CreateIBSS --*/ +typedef struct hfa384x_CreateIBSS +{ + UINT16 CreateIBSS; +} __WLAN_ATTRIB_PACK__ hfa384x_CreateIBSS_t; + +#define HFA384x_CREATEIBSS_JOINCREATEIBSS 0 +#define HFA384x_CREATEIBSS_JOINESS_JOINCREATEIBSS 1 +#define HFA384x_CREATEIBSS_JOINIBSS 2 +#define HFA384x_CREATEIBSS_JOINESS_JOINIBSS 3 + +/*-- Configuration Record: FragmentationThreshold --*/ +typedef struct hfa384x_FragmentationThreshold +{ + UINT16 FragmentationThreshold; +} __WLAN_ATTRIB_PACK__ hfa384x_FragmentationThreshold_t; + +/*-- Configuration Record: RTSThreshold --*/ +typedef struct hfa384x_RTSThreshold +{ + UINT16 RTSThreshold; +} __WLAN_ATTRIB_PACK__ hfa384x_RTSThreshold_t; + +/*-- Configuration Record: TxRateControl --*/ +typedef struct hfa384x_TxRateControl +{ + UINT16 TxRateControl; +} __WLAN_ATTRIB_PACK__ hfa384x_TxRateControl_t; + +/*-- Configuration Record: PromiscuousMode --*/ +typedef struct hfa384x_PromiscuousMode +{ + UINT16 PromiscuousMode; +} __WLAN_ATTRIB_PACK__ hfa384x_PromiscuousMode_t; + +/*-- Configuration Record: ScanRequest (data portion only) --*/ +typedef struct hfa384x_ScanRequest_data +{ + UINT16 channelList; + UINT16 txRate; +} __WLAN_ATTRIB_PACK__ hfa384x_ScanRequest_data_t; + +/*-- Configuration Record: HostScanRequest (data portion only) --*/ +typedef struct hfa384x_HostScanRequest_data +{ + UINT16 channelList; + UINT16 txRate; + hfa384x_bytestr32_t ssid; +} __WLAN_ATTRIB_PACK__ hfa384x_HostScanRequest_data_t; + +/*-- Configuration Record: JoinRequest (data portion only) --*/ +typedef struct hfa384x_JoinRequest_data +{ + UINT8 bssid[WLAN_BSSID_LEN]; + UINT16 channel; +} __WLAN_ATTRIB_PACK__ hfa384x_JoinRequest_data_t; + +/*-- Configuration Record: authenticateStation (data portion only) --*/ +typedef struct hfa384x_authenticateStation_data +{ + UINT8 address[WLAN_ADDR_LEN]; + UINT16 status; + UINT16 algorithm; +} __WLAN_ATTRIB_PACK__ hfa384x_authenticateStation_data_t; + +/*-- Configuration Record: associateStation (data portion only) --*/ +typedef struct hfa384x_associateStation_data +{ + UINT8 address[WLAN_ADDR_LEN]; + UINT16 status; + UINT16 type; +} __WLAN_ATTRIB_PACK__ hfa384x_associateStation_data_t; + +/*-- Configuration Record: ChannelInfoRequest (data portion only) --*/ +typedef struct hfa384x_ChannelInfoRequest_data +{ + UINT16 channelList; + UINT16 channelDwellTime; +} __WLAN_ATTRIB_PACK__ hfa384x_ChannelInfoRequest_data_t; + +/*-- Configuration Record: WEPKeyMapping (data portion only) --*/ +typedef struct hfa384x_WEPKeyMapping +{ + UINT8 address[WLAN_ADDR_LEN]; + UINT16 key_index; + UINT8 key[16]; + UINT8 mic_transmit_key[4]; + UINT8 mic_receive_key[4]; +} __WLAN_ATTRIB_PACK__ hfa384x_WEPKeyMapping_t; + +/*-- Configuration Record: WPAData (data portion only) --*/ +typedef struct hfa384x_WPAData +{ + UINT16 datalen; + UINT8 data[0]; // max 80 +} __WLAN_ATTRIB_PACK__ hfa384x_WPAData_t; + +/*-------------------------------------------------------------------- +Configuration Record Structures: Behavior Parameters +--------------------------------------------------------------------*/ + +/*-- Configuration Record: TickTime --*/ +typedef struct hfa384x_TickTime +{ + UINT16 TickTime; +} __WLAN_ATTRIB_PACK__ hfa384x_TickTime_t; + +/*-------------------------------------------------------------------- +Information Record Structures: NIC Information +--------------------------------------------------------------------*/ + +/*-- Information Record: MaxLoadTime --*/ +typedef struct hfa384x_MaxLoadTime +{ + UINT16 MaxLoadTime; +} __WLAN_ATTRIB_PACK__ hfa384x_MaxLoadTime_t; + +/*-- Information Record: DownLoadBuffer --*/ +/* NOTE: The page and offset are in AUX format */ +typedef struct hfa384x_downloadbuffer +{ + UINT16 page; + UINT16 offset; + UINT16 len; +} __WLAN_ATTRIB_PACK__ hfa384x_downloadbuffer_t; + +/*-- Information Record: PRIIdentity --*/ +typedef struct hfa384x_PRIIdentity +{ + UINT16 PRICompID; + UINT16 PRIVariant; + UINT16 PRIMajorVersion; + UINT16 PRIMinorVersion; +} __WLAN_ATTRIB_PACK__ hfa384x_PRIIdentity_t; + +/*-- Information Record: PRISupRange --*/ +typedef struct hfa384x_PRISupRange +{ + UINT16 PRIRole; + UINT16 PRIID; + UINT16 PRIVariant; + UINT16 PRIBottom; + UINT16 PRITop; +} __WLAN_ATTRIB_PACK__ hfa384x_PRISupRange_t; + +/*-- Information Record: CFIActRanges --*/ +typedef struct hfa384x_CFIActRanges +{ + UINT16 CFIRole; + UINT16 CFIID; + UINT16 CFIVariant; + UINT16 CFIBottom; + UINT16 CFITop; +} __WLAN_ATTRIB_PACK__ hfa384x_CFIActRanges_t; + +/*-- Information Record: NICSerialNumber --*/ +typedef struct hfa384x_NICSerialNumber +{ + UINT8 NICSerialNumber[12]; +} __WLAN_ATTRIB_PACK__ hfa384x_NICSerialNumber_t; + +/*-- Information Record: NICIdentity --*/ +typedef struct hfa384x_NICIdentity +{ + UINT16 NICCompID; + UINT16 NICVariant; + UINT16 NICMajorVersion; + UINT16 NICMinorVersion; +} __WLAN_ATTRIB_PACK__ hfa384x_NICIdentity_t; + +/*-- Information Record: MFISupRange --*/ +typedef struct hfa384x_MFISupRange +{ + UINT16 MFIRole; + UINT16 MFIID; + UINT16 MFIVariant; + UINT16 MFIBottom; + UINT16 MFITop; +} __WLAN_ATTRIB_PACK__ hfa384x_MFISupRange_t; + +/*-- Information Record: CFISupRange --*/ +typedef struct hfa384x_CFISupRange +{ + UINT16 CFIRole; + UINT16 CFIID; + UINT16 CFIVariant; + UINT16 CFIBottom; + UINT16 CFITop; +} __WLAN_ATTRIB_PACK__ hfa384x_CFISupRange_t; + +/*-- Information Record: BUILDSEQ:BuildSeq --*/ +typedef struct hfa384x_BuildSeq { + UINT16 primary; + UINT16 secondary; +} __WLAN_ATTRIB_PACK__ hfa384x_BuildSeq_t; + +/*-- Information Record: FWID --*/ +#define HFA384x_FWID_LEN 14 +typedef struct hfa384x_FWID { + UINT8 primary[HFA384x_FWID_LEN]; + UINT8 secondary[HFA384x_FWID_LEN]; +} __WLAN_ATTRIB_PACK__ hfa384x_FWID_t; + +/*-- Information Record: ChannelList --*/ +typedef struct hfa384x_ChannelList +{ + UINT16 ChannelList; +} __WLAN_ATTRIB_PACK__ hfa384x_ChannelList_t; + +/*-- Information Record: RegulatoryDomains --*/ +typedef struct hfa384x_RegulatoryDomains +{ + UINT8 RegulatoryDomains[12]; +} __WLAN_ATTRIB_PACK__ hfa384x_RegulatoryDomains_t; + +/*-- Information Record: TempType --*/ +typedef struct hfa384x_TempType +{ + UINT16 TempType; +} __WLAN_ATTRIB_PACK__ hfa384x_TempType_t; + +/*-- Information Record: CIS --*/ +typedef struct hfa384x_CIS +{ + UINT8 CIS[480]; +} __WLAN_ATTRIB_PACK__ hfa384x_CIS_t; + +/*-- Information Record: STAIdentity --*/ +typedef struct hfa384x_STAIdentity +{ + UINT16 STACompID; + UINT16 STAVariant; + UINT16 STAMajorVersion; + UINT16 STAMinorVersion; +} __WLAN_ATTRIB_PACK__ hfa384x_STAIdentity_t; + +/*-- Information Record: STASupRange --*/ +typedef struct hfa384x_STASupRange +{ + UINT16 STARole; + UINT16 STAID; + UINT16 STAVariant; + UINT16 STABottom; + UINT16 STATop; +} __WLAN_ATTRIB_PACK__ hfa384x_STASupRange_t; + +/*-- Information Record: MFIActRanges --*/ +typedef struct hfa384x_MFIActRanges +{ + UINT16 MFIRole; + UINT16 MFIID; + UINT16 MFIVariant; + UINT16 MFIBottom; + UINT16 MFITop; +} __WLAN_ATTRIB_PACK__ hfa384x_MFIActRanges_t; + +/*-------------------------------------------------------------------- +Information Record Structures: NIC Information +--------------------------------------------------------------------*/ + +/*-- Information Record: PortStatus --*/ +typedef struct hfa384x_PortStatus +{ + UINT16 PortStatus; +} __WLAN_ATTRIB_PACK__ hfa384x_PortStatus_t; + +#define HFA384x_PSTATUS_DISABLED ((UINT16)1) +#define HFA384x_PSTATUS_SEARCHING ((UINT16)2) +#define HFA384x_PSTATUS_CONN_IBSS ((UINT16)3) +#define HFA384x_PSTATUS_CONN_ESS ((UINT16)4) +#define HFA384x_PSTATUS_OUTOFRANGE ((UINT16)5) +#define HFA384x_PSTATUS_CONN_WDS ((UINT16)6) + +/*-- Information Record: CurrentSSID --*/ +typedef struct hfa384x_CurrentSSID +{ + UINT8 CurrentSSID[34]; +} __WLAN_ATTRIB_PACK__ hfa384x_CurrentSSID_t; + +/*-- Information Record: CurrentBSSID --*/ +typedef struct hfa384x_CurrentBSSID +{ + UINT8 CurrentBSSID[6]; +} __WLAN_ATTRIB_PACK__ hfa384x_CurrentBSSID_t; + +/*-- Information Record: commsquality --*/ +typedef struct hfa384x_commsquality +{ + UINT16 CQ_currBSS; + UINT16 ASL_currBSS; + UINT16 ANL_currFC; +} __WLAN_ATTRIB_PACK__ hfa384x_commsquality_t; + +/*-- Information Record: dmbcommsquality --*/ +typedef struct hfa384x_dbmcommsquality +{ + UINT16 CQdbm_currBSS; + UINT16 ASLdbm_currBSS; + UINT16 ANLdbm_currFC; +} __WLAN_ATTRIB_PACK__ hfa384x_dbmcommsquality_t; + +/*-- Information Record: CurrentTxRate --*/ +typedef struct hfa384x_CurrentTxRate +{ + UINT16 CurrentTxRate; +} __WLAN_ATTRIB_PACK__ hfa384x_CurrentTxRate_t; + +/*-- Information Record: CurrentBeaconInterval --*/ +typedef struct hfa384x_CurrentBeaconInterval +{ + UINT16 CurrentBeaconInterval; +} __WLAN_ATTRIB_PACK__ hfa384x_CurrentBeaconInterval_t; + +/*-- Information Record: CurrentScaleThresholds --*/ +typedef struct hfa384x_CurrentScaleThresholds +{ + UINT16 EnergyDetectThreshold; + UINT16 CarrierDetectThreshold; + UINT16 DeferDetectThreshold; + UINT16 CellSearchThreshold; /* Stations only */ + UINT16 DeadSpotThreshold; /* Stations only */ +} __WLAN_ATTRIB_PACK__ hfa384x_CurrentScaleThresholds_t; + +/*-- Information Record: ProtocolRspTime --*/ +typedef struct hfa384x_ProtocolRspTime +{ + UINT16 ProtocolRspTime; +} __WLAN_ATTRIB_PACK__ hfa384x_ProtocolRspTime_t; + +/*-- Information Record: ShortRetryLimit --*/ +typedef struct hfa384x_ShortRetryLimit +{ + UINT16 ShortRetryLimit; +} __WLAN_ATTRIB_PACK__ hfa384x_ShortRetryLimit_t; + +/*-- Information Record: LongRetryLimit --*/ +typedef struct hfa384x_LongRetryLimit +{ + UINT16 LongRetryLimit; +} __WLAN_ATTRIB_PACK__ hfa384x_LongRetryLimit_t; + +/*-- Information Record: MaxTransmitLifetime --*/ +typedef struct hfa384x_MaxTransmitLifetime +{ + UINT16 MaxTransmitLifetime; +} __WLAN_ATTRIB_PACK__ hfa384x_MaxTransmitLifetime_t; + +/*-- Information Record: MaxReceiveLifetime --*/ +typedef struct hfa384x_MaxReceiveLifetime +{ + UINT16 MaxReceiveLifetime; +} __WLAN_ATTRIB_PACK__ hfa384x_MaxReceiveLifetime_t; + +/*-- Information Record: CFPollable --*/ +typedef struct hfa384x_CFPollable +{ + UINT16 CFPollable; +} __WLAN_ATTRIB_PACK__ hfa384x_CFPollable_t; + +/*-- Information Record: AuthenticationAlgorithms --*/ +typedef struct hfa384x_AuthenticationAlgorithms +{ + UINT16 AuthenticationType; + UINT16 TypeEnabled; +} __WLAN_ATTRIB_PACK__ hfa384x_AuthenticationAlgorithms_t; + +/*-- Information Record: AuthenticationAlgorithms +(data only --*/ +typedef struct hfa384x_AuthenticationAlgorithms_data +{ + UINT16 AuthenticationType; + UINT16 TypeEnabled; +} __WLAN_ATTRIB_PACK__ hfa384x_AuthenticationAlgorithms_data_t; + +/*-- Information Record: PrivacyOptionImplemented --*/ +typedef struct hfa384x_PrivacyOptionImplemented +{ + UINT16 PrivacyOptionImplemented; +} __WLAN_ATTRIB_PACK__ hfa384x_PrivacyOptionImplemented_t; + +/*-- Information Record: OwnMACAddress --*/ +typedef struct hfa384x_OwnMACAddress +{ + UINT8 OwnMACAddress[6]; +} __WLAN_ATTRIB_PACK__ hfa384x_OwnMACAddress_t; + +/*-- Information Record: PCFInfo --*/ +typedef struct hfa384x_PCFInfo +{ + UINT16 MediumOccupancyLimit; + UINT16 CFPPeriod; + UINT16 CFPMaxDuration; + UINT16 CFPFlags; +} __WLAN_ATTRIB_PACK__ hfa384x_PCFInfo_t; + +/*-- Information Record: PCFInfo (data portion only) --*/ +typedef struct hfa384x_PCFInfo_data +{ + UINT16 MediumOccupancyLimit; + UINT16 CFPPeriod; + UINT16 CFPMaxDuration; + UINT16 CFPFlags; +} __WLAN_ATTRIB_PACK__ hfa384x_PCFInfo_data_t; + +/*-------------------------------------------------------------------- +Information Record Structures: Modem Information Records +--------------------------------------------------------------------*/ + +/*-- Information Record: PHYType --*/ +typedef struct hfa384x_PHYType +{ + UINT16 PHYType; +} __WLAN_ATTRIB_PACK__ hfa384x_PHYType_t; + +/*-- Information Record: CurrentChannel --*/ +typedef struct hfa384x_CurrentChannel +{ + UINT16 CurrentChannel; +} __WLAN_ATTRIB_PACK__ hfa384x_CurrentChannel_t; + +/*-- Information Record: CurrentPowerState --*/ +typedef struct hfa384x_CurrentPowerState +{ + UINT16 CurrentPowerState; +} __WLAN_ATTRIB_PACK__ hfa384x_CurrentPowerState_t; + +/*-- Information Record: CCAMode --*/ +typedef struct hfa384x_CCAMode +{ + UINT16 CCAMode; +} __WLAN_ATTRIB_PACK__ hfa384x_CCAMode_t; + +/*-- Information Record: SupportedDataRates --*/ +typedef struct hfa384x_SupportedDataRates +{ + UINT8 SupportedDataRates[10]; +} __WLAN_ATTRIB_PACK__ hfa384x_SupportedDataRates_t; + +/*-- Information Record: LFOStatus --*/ +typedef struct hfa384x_LFOStatus +{ + UINT16 TestResults; + UINT16 LFOResult; + UINT16 VRHFOResult; +} __WLAN_ATTRIB_PACK__ hfa384x_LFOStatus_t; + +#define HFA384x_TESTRESULT_ALLPASSED BIT0 +#define HFA384x_TESTRESULT_LFO_FAIL BIT1 +#define HFA384x_TESTRESULT_VR_HF0_FAIL BIT2 +#define HFA384x_HOST_FIRM_COORDINATE BIT7 +#define HFA384x_TESTRESULT_COORDINATE BIT15 + +/*-- Information Record: LEDControl --*/ +typedef struct hfa384x_LEDControl +{ + UINT16 searching_on; + UINT16 searching_off; + UINT16 assoc_on; + UINT16 assoc_off; + UINT16 activity; +} __WLAN_ATTRIB_PACK__ hfa384x_LEDControl_t; + +/*-------------------------------------------------------------------- + FRAME DESCRIPTORS AND FRAME STRUCTURES + +FRAME DESCRIPTORS: Offsets + +---------------------------------------------------------------------- +Control Info (offset 44-51) +--------------------------------------------------------------------*/ +#define HFA384x_FD_STATUS_OFF ((UINT16)0x44) +#define HFA384x_FD_TIME_OFF ((UINT16)0x46) +#define HFA384x_FD_SWSUPPORT_OFF ((UINT16)0x4A) +#define HFA384x_FD_SILENCE_OFF ((UINT16)0x4A) +#define HFA384x_FD_SIGNAL_OFF ((UINT16)0x4B) +#define HFA384x_FD_RATE_OFF ((UINT16)0x4C) +#define HFA384x_FD_RXFLOW_OFF ((UINT16)0x4D) +#define HFA384x_FD_RESERVED_OFF ((UINT16)0x4E) +#define HFA384x_FD_TXCONTROL_OFF ((UINT16)0x50) +/*-------------------------------------------------------------------- +802.11 Header (offset 52-6B) +--------------------------------------------------------------------*/ +#define HFA384x_FD_FRAMECONTROL_OFF ((UINT16)0x52) +#define HFA384x_FD_DURATIONID_OFF ((UINT16)0x54) +#define HFA384x_FD_ADDRESS1_OFF ((UINT16)0x56) +#define HFA384x_FD_ADDRESS2_OFF ((UINT16)0x5C) +#define HFA384x_FD_ADDRESS3_OFF ((UINT16)0x62) +#define HFA384x_FD_SEQCONTROL_OFF ((UINT16)0x68) +#define HFA384x_FD_ADDRESS4_OFF ((UINT16)0x6A) +#define HFA384x_FD_DATALEN_OFF ((UINT16)0x70) +/*-------------------------------------------------------------------- +802.3 Header (offset 72-7F) +--------------------------------------------------------------------*/ +#define HFA384x_FD_DESTADDRESS_OFF ((UINT16)0x72) +#define HFA384x_FD_SRCADDRESS_OFF ((UINT16)0x78) +#define HFA384x_FD_DATALENGTH_OFF ((UINT16)0x7E) + +/*-------------------------------------------------------------------- +FRAME STRUCTURES: Communication Frames +---------------------------------------------------------------------- +Communication Frames: Transmit Frames +--------------------------------------------------------------------*/ +/*-- Communication Frame: Transmit Frame Structure --*/ +typedef struct hfa384x_tx_frame +{ + UINT16 status; + UINT16 reserved1; + UINT16 reserved2; + UINT32 sw_support; + UINT8 tx_retrycount; + UINT8 tx_rate; + UINT16 tx_control; + + /*-- 802.11 Header Information --*/ + + UINT16 frame_control; + UINT16 duration_id; + UINT8 address1[6]; + UINT8 address2[6]; + UINT8 address3[6]; + UINT16 sequence_control; + UINT8 address4[6]; + UINT16 data_len; /* little endian format */ + + /*-- 802.3 Header Information --*/ + + UINT8 dest_addr[6]; + UINT8 src_addr[6]; + UINT16 data_length; /* big endian format */ +} __WLAN_ATTRIB_PACK__ hfa384x_tx_frame_t; +/*-------------------------------------------------------------------- +Communication Frames: Field Masks for Transmit Frames +--------------------------------------------------------------------*/ +/*-- Status Field --*/ +#define HFA384x_TXSTATUS_ACKERR ((UINT16)BIT5) +#define HFA384x_TXSTATUS_FORMERR ((UINT16)BIT3) +#define HFA384x_TXSTATUS_DISCON ((UINT16)BIT2) +#define HFA384x_TXSTATUS_AGEDERR ((UINT16)BIT1) +#define HFA384x_TXSTATUS_RETRYERR ((UINT16)BIT0) +/*-- Transmit Control Field --*/ +#define HFA384x_TX_CFPOLL ((UINT16)BIT12) +#define HFA384x_TX_PRST ((UINT16)BIT11) +#define HFA384x_TX_MACPORT ((UINT16)(BIT10 | BIT9 | BIT8)) +#define HFA384x_TX_NOENCRYPT ((UINT16)BIT7) +#define HFA384x_TX_RETRYSTRAT ((UINT16)(BIT6 | BIT5)) +#define HFA384x_TX_STRUCTYPE ((UINT16)(BIT4 | BIT3)) +#define HFA384x_TX_TXEX ((UINT16)BIT2) +#define HFA384x_TX_TXOK ((UINT16)BIT1) +/*-------------------------------------------------------------------- +Communication Frames: Test/Get/Set Field Values for Transmit Frames +--------------------------------------------------------------------*/ +/*-- Status Field --*/ +#define HFA384x_TXSTATUS_ISERROR(v) \ + (((UINT16)(v))&\ + (HFA384x_TXSTATUS_ACKERR|HFA384x_TXSTATUS_FORMERR|\ + HFA384x_TXSTATUS_DISCON|HFA384x_TXSTATUS_AGEDERR|\ + HFA384x_TXSTATUS_RETRYERR)) + +#define HFA384x_TXSTATUS_ISACKERR(v) ((UINT16)(((UINT16)(v)) & HFA384x_TXSTATUS_ACKERR)) +#define HFA384x_TXSTATUS_ISFORMERR(v) ((UINT16)(((UINT16)(v)) & HFA384x_TXSTATUS_FORMERR)) +#define HFA384x_TXSTATUS_ISDISCON(v) ((UINT16)(((UINT16)(v)) & HFA384x_TXSTATUS_DISCON)) +#define HFA384x_TXSTATUS_ISAGEDERR(v) ((UINT16)(((UINT16)(v)) & HFA384x_TXSTATUS_AGEDERR)) +#define HFA384x_TXSTATUS_ISRETRYERR(v) ((UINT16)(((UINT16)(v)) & HFA384x_TXSTATUS_RETRYERR)) + +#define HFA384x_TX_GET(v,m,s) ((((UINT16)(v))&((UINT16)(m)))>>((UINT16)(s))) +#define HFA384x_TX_SET(v,m,s) ((((UINT16)(v))<<((UINT16)(s)))&((UINT16)(m))) + +#define HFA384x_TX_CFPOLL_GET(v) HFA384x_TX_GET(v, HFA384x_TX_CFPOLL,12) +#define HFA384x_TX_CFPOLL_SET(v) HFA384x_TX_SET(v, HFA384x_TX_CFPOLL,12) +#define HFA384x_TX_PRST_GET(v) HFA384x_TX_GET(v, HFA384x_TX_PRST,11) +#define HFA384x_TX_PRST_SET(v) HFA384x_TX_SET(v, HFA384x_TX_PRST,11) +#define HFA384x_TX_MACPORT_GET(v) HFA384x_TX_GET(v, HFA384x_TX_MACPORT, 8) +#define HFA384x_TX_MACPORT_SET(v) HFA384x_TX_SET(v, HFA384x_TX_MACPORT, 8) +#define HFA384x_TX_NOENCRYPT_GET(v) HFA384x_TX_GET(v, HFA384x_TX_NOENCRYPT, 7) +#define HFA384x_TX_NOENCRYPT_SET(v) HFA384x_TX_SET(v, HFA384x_TX_NOENCRYPT, 7) +#define HFA384x_TX_RETRYSTRAT_GET(v) HFA384x_TX_GET(v, HFA384x_TX_RETRYSTRAT, 5) +#define HFA384x_TX_RETRYSTRAT_SET(v) HFA384x_TX_SET(v, HFA384x_TX_RETRYSTRAT, 5) +#define HFA384x_TX_STRUCTYPE_GET(v) HFA384x_TX_GET(v, HFA384x_TX_STRUCTYPE, 3) +#define HFA384x_TX_STRUCTYPE_SET(v) HFA384x_TX_SET(v, HFA384x_TX_STRUCTYPE, 3) +#define HFA384x_TX_TXEX_GET(v) HFA384x_TX_GET(v, HFA384x_TX_TXEX, 2) +#define HFA384x_TX_TXEX_SET(v) HFA384x_TX_SET(v, HFA384x_TX_TXEX, 2) +#define HFA384x_TX_TXOK_GET(v) HFA384x_TX_GET(v, HFA384x_TX_TXOK, 1) +#define HFA384x_TX_TXOK_SET(v) HFA384x_TX_SET(v, HFA384x_TX_TXOK, 1) +/*-------------------------------------------------------------------- +Communication Frames: Receive Frames +--------------------------------------------------------------------*/ +/*-- Communication Frame: Receive Frame Structure --*/ +typedef struct hfa384x_rx_frame +{ + /*-- MAC rx descriptor (hfa384x byte order) --*/ + UINT16 status; + UINT32 time; + UINT8 silence; + UINT8 signal; + UINT8 rate; + UINT8 rx_flow; + UINT16 reserved1; + UINT16 reserved2; + + /*-- 802.11 Header Information (802.11 byte order) --*/ + UINT16 frame_control; + UINT16 duration_id; + UINT8 address1[6]; + UINT8 address2[6]; + UINT8 address3[6]; + UINT16 sequence_control; + UINT8 address4[6]; + UINT16 data_len; /* hfa384x (little endian) format */ + + /*-- 802.3 Header Information --*/ + UINT8 dest_addr[6]; + UINT8 src_addr[6]; + UINT16 data_length; /* IEEE? (big endian) format */ +} __WLAN_ATTRIB_PACK__ hfa384x_rx_frame_t; +/*-------------------------------------------------------------------- +Communication Frames: Field Masks for Receive Frames +--------------------------------------------------------------------*/ +/*-- Offsets --------*/ +#define HFA384x_RX_DATA_LEN_OFF ((UINT16)44) +#define HFA384x_RX_80211HDR_OFF ((UINT16)14) +#define HFA384x_RX_DATA_OFF ((UINT16)60) + +/*-- Status Fields --*/ +#define HFA384x_RXSTATUS_MSGTYPE ((UINT16)(BIT15 | BIT14 | BIT13)) +#define HFA384x_RXSTATUS_MACPORT ((UINT16)(BIT10 | BIT9 | BIT8)) +#define HFA384x_RXSTATUS_UNDECR ((UINT16)BIT1) +#define HFA384x_RXSTATUS_FCSERR ((UINT16)BIT0) +/*-------------------------------------------------------------------- +Communication Frames: Test/Get/Set Field Values for Receive Frames +--------------------------------------------------------------------*/ +#define HFA384x_RXSTATUS_MSGTYPE_GET(value) ((UINT16)((((UINT16)(value)) & HFA384x_RXSTATUS_MSGTYPE) >> 13)) +#define HFA384x_RXSTATUS_MSGTYPE_SET(value) ((UINT16)(((UINT16)(value)) << 13)) +#define HFA384x_RXSTATUS_MACPORT_GET(value) ((UINT16)((((UINT16)(value)) & HFA384x_RXSTATUS_MACPORT) >> 8)) +#define HFA384x_RXSTATUS_MACPORT_SET(value) ((UINT16)(((UINT16)(value)) << 8)) +#define HFA384x_RXSTATUS_ISUNDECR(value) ((UINT16)(((UINT16)(value)) & HFA384x_RXSTATUS_UNDECR)) +#define HFA384x_RXSTATUS_ISFCSERR(value) ((UINT16)(((UINT16)(value)) & HFA384x_RXSTATUS_FCSERR)) +/*-------------------------------------------------------------------- + FRAME STRUCTURES: Information Types and Information Frame Structures +---------------------------------------------------------------------- +Information Types +--------------------------------------------------------------------*/ +#define HFA384x_IT_HANDOVERADDR ((UINT16)0xF000UL) +#define HFA384x_IT_HANDOVERDEAUTHADDRESS ((UINT16)0xF001UL)//AP 1.3.7 +#define HFA384x_IT_COMMTALLIES ((UINT16)0xF100UL) +#define HFA384x_IT_SCANRESULTS ((UINT16)0xF101UL) +#define HFA384x_IT_CHINFORESULTS ((UINT16)0xF102UL) +#define HFA384x_IT_HOSTSCANRESULTS ((UINT16)0xF103UL) +#define HFA384x_IT_LINKSTATUS ((UINT16)0xF200UL) +#define HFA384x_IT_ASSOCSTATUS ((UINT16)0xF201UL) +#define HFA384x_IT_AUTHREQ ((UINT16)0xF202UL) +#define HFA384x_IT_PSUSERCNT ((UINT16)0xF203UL) +#define HFA384x_IT_KEYIDCHANGED ((UINT16)0xF204UL) +#define HFA384x_IT_ASSOCREQ ((UINT16)0xF205UL) +#define HFA384x_IT_MICFAILURE ((UINT16)0xF206UL) + +/*-------------------------------------------------------------------- +Information Frames Structures +---------------------------------------------------------------------- +Information Frames: Notification Frame Structures +--------------------------------------------------------------------*/ +/*-- Notification Frame,MAC Mgmt: Handover Address --*/ +typedef struct hfa384x_HandoverAddr +{ + UINT16 framelen; + UINT16 infotype; + UINT8 handover_addr[WLAN_BSSID_LEN]; +} __WLAN_ATTRIB_PACK__ hfa384x_HandoverAddr_t; + +/*-- Inquiry Frame, Diagnose: Communication Tallies --*/ +typedef struct hfa384x_CommTallies16 +{ + UINT16 txunicastframes; + UINT16 txmulticastframes; + UINT16 txfragments; + UINT16 txunicastoctets; + UINT16 txmulticastoctets; + UINT16 txdeferredtrans; + UINT16 txsingleretryframes; + UINT16 txmultipleretryframes; + UINT16 txretrylimitexceeded; + UINT16 txdiscards; + UINT16 rxunicastframes; + UINT16 rxmulticastframes; + UINT16 rxfragments; + UINT16 rxunicastoctets; + UINT16 rxmulticastoctets; + UINT16 rxfcserrors; + UINT16 rxdiscardsnobuffer; + UINT16 txdiscardswrongsa; + UINT16 rxdiscardswepundecr; + UINT16 rxmsginmsgfrag; + UINT16 rxmsginbadmsgfrag; +} __WLAN_ATTRIB_PACK__ hfa384x_CommTallies16_t; + +typedef struct hfa384x_CommTallies32 +{ + UINT32 txunicastframes; + UINT32 txmulticastframes; + UINT32 txfragments; + UINT32 txunicastoctets; + UINT32 txmulticastoctets; + UINT32 txdeferredtrans; + UINT32 txsingleretryframes; + UINT32 txmultipleretryframes; + UINT32 txretrylimitexceeded; + UINT32 txdiscards; + UINT32 rxunicastframes; + UINT32 rxmulticastframes; + UINT32 rxfragments; + UINT32 rxunicastoctets; + UINT32 rxmulticastoctets; + UINT32 rxfcserrors; + UINT32 rxdiscardsnobuffer; + UINT32 txdiscardswrongsa; + UINT32 rxdiscardswepundecr; + UINT32 rxmsginmsgfrag; + UINT32 rxmsginbadmsgfrag; +} __WLAN_ATTRIB_PACK__ hfa384x_CommTallies32_t; + +/*-- Inquiry Frame, Diagnose: Scan Results & Subfields--*/ +typedef struct hfa384x_ScanResultSub +{ + UINT16 chid; + UINT16 anl; + UINT16 sl; + UINT8 bssid[WLAN_BSSID_LEN]; + UINT16 bcnint; + UINT16 capinfo; + hfa384x_bytestr32_t ssid; + UINT8 supprates[10]; /* 802.11 info element */ + UINT16 proberesp_rate; +} __WLAN_ATTRIB_PACK__ hfa384x_ScanResultSub_t; + +typedef struct hfa384x_ScanResult +{ + UINT16 rsvd; + UINT16 scanreason; + hfa384x_ScanResultSub_t + result[HFA384x_SCANRESULT_MAX]; +} __WLAN_ATTRIB_PACK__ hfa384x_ScanResult_t; + +/*-- Inquiry Frame, Diagnose: ChInfo Results & Subfields--*/ +typedef struct hfa384x_ChInfoResultSub +{ + UINT16 chid; + UINT16 anl; + UINT16 pnl; + UINT16 active; +} __WLAN_ATTRIB_PACK__ hfa384x_ChInfoResultSub_t; + +#define HFA384x_CHINFORESULT_BSSACTIVE BIT0 +#define HFA384x_CHINFORESULT_PCFACTIVE BIT1 + +typedef struct hfa384x_ChInfoResult +{ + UINT16 scanchannels; + hfa384x_ChInfoResultSub_t + result[HFA384x_CHINFORESULT_MAX]; +} __WLAN_ATTRIB_PACK__ hfa384x_ChInfoResult_t; + +/*-- Inquiry Frame, Diagnose: Host Scan Results & Subfields--*/ +typedef struct hfa384x_HScanResultSub +{ + UINT16 chid; + UINT16 anl; + UINT16 sl; + UINT8 bssid[WLAN_BSSID_LEN]; + UINT16 bcnint; + UINT16 capinfo; + hfa384x_bytestr32_t ssid; + UINT8 supprates[10]; /* 802.11 info element */ + UINT16 proberesp_rate; + UINT16 atim; +} __WLAN_ATTRIB_PACK__ hfa384x_HScanResultSub_t; + +typedef struct hfa384x_HScanResult +{ + UINT16 nresult; + UINT16 rsvd; + hfa384x_HScanResultSub_t + result[HFA384x_HSCANRESULT_MAX]; +} __WLAN_ATTRIB_PACK__ hfa384x_HScanResult_t; + +/*-- Unsolicited Frame, MAC Mgmt: LinkStatus --*/ + +#define HFA384x_LINK_NOTCONNECTED ((UINT16)0) +#define HFA384x_LINK_CONNECTED ((UINT16)1) +#define HFA384x_LINK_DISCONNECTED ((UINT16)2) +#define HFA384x_LINK_AP_CHANGE ((UINT16)3) +#define HFA384x_LINK_AP_OUTOFRANGE ((UINT16)4) +#define HFA384x_LINK_AP_INRANGE ((UINT16)5) +#define HFA384x_LINK_ASSOCFAIL ((UINT16)6) + +typedef struct hfa384x_LinkStatus +{ + UINT16 linkstatus; +} __WLAN_ATTRIB_PACK__ hfa384x_LinkStatus_t; + + +/*-- Unsolicited Frame, MAC Mgmt: AssociationStatus (--*/ + +#define HFA384x_ASSOCSTATUS_STAASSOC ((UINT16)1) +#define HFA384x_ASSOCSTATUS_REASSOC ((UINT16)2) +#define HFA384x_ASSOCSTATUS_DISASSOC ((UINT16)3) +#define HFA384x_ASSOCSTATUS_ASSOCFAIL ((UINT16)4) +#define HFA384x_ASSOCSTATUS_AUTHFAIL ((UINT16)5) + +typedef struct hfa384x_AssocStatus +{ + UINT16 assocstatus; + UINT8 sta_addr[WLAN_ADDR_LEN]; + /* old_ap_addr is only valid if assocstatus == 2 */ + UINT8 old_ap_addr[WLAN_ADDR_LEN]; + UINT16 reason; + UINT16 reserved; +} __WLAN_ATTRIB_PACK__ hfa384x_AssocStatus_t; + +/*-- Unsolicited Frame, MAC Mgmt: AuthRequest (AP Only) --*/ + +typedef struct hfa384x_AuthRequest +{ + UINT8 sta_addr[WLAN_ADDR_LEN]; + UINT16 algorithm; +} __WLAN_ATTRIB_PACK__ hfa384x_AuthReq_t; + +/*-- Unsolicited Frame, MAC Mgmt: AssocRequest (AP Only) --*/ + +typedef struct hfa384x_AssocRequest +{ + UINT8 sta_addr[WLAN_ADDR_LEN]; + UINT16 type; + UINT8 wpa_data[80]; +} __WLAN_ATTRIB_PACK__ hfa384x_AssocReq_t; + + +#define HFA384x_ASSOCREQ_TYPE_ASSOC 0 +#define HFA384x_ASSOCREQ_TYPE_REASSOC 1 + +/*-- Unsolicited Frame, MAC Mgmt: MIC Failure (AP Only) --*/ + +typedef struct hfa384x_MicFailure +{ + UINT8 sender[WLAN_ADDR_LEN]; + UINT8 dest[WLAN_ADDR_LEN]; +} __WLAN_ATTRIB_PACK__ hfa384x_MicFailure_t; + +/*-- Unsolicited Frame, MAC Mgmt: PSUserCount (AP Only) --*/ + +typedef struct hfa384x_PSUserCount +{ + UINT16 usercnt; +} __WLAN_ATTRIB_PACK__ hfa384x_PSUserCount_t; + +typedef struct hfa384x_KeyIDChanged +{ + UINT8 sta_addr[WLAN_ADDR_LEN]; + UINT16 keyid; +} __WLAN_ATTRIB_PACK__ hfa384x_KeyIDChanged_t; + +/*-- Collection of all Inf frames ---------------*/ +typedef union hfa384x_infodata { + hfa384x_CommTallies16_t commtallies16; + hfa384x_CommTallies32_t commtallies32; + hfa384x_ScanResult_t scanresult; + hfa384x_ChInfoResult_t chinforesult; + hfa384x_HScanResult_t hscanresult; + hfa384x_LinkStatus_t linkstatus; + hfa384x_AssocStatus_t assocstatus; + hfa384x_AuthReq_t authreq; + hfa384x_PSUserCount_t psusercnt; + hfa384x_KeyIDChanged_t keyidchanged; +} __WLAN_ATTRIB_PACK__ hfa384x_infodata_t; + +typedef struct hfa384x_InfFrame +{ + UINT16 framelen; + UINT16 infotype; + hfa384x_infodata_t info; +} __WLAN_ATTRIB_PACK__ hfa384x_InfFrame_t; + +#if (WLAN_HOSTIF == WLAN_USB) +/*-------------------------------------------------------------------- +USB Packet structures and constants. +--------------------------------------------------------------------*/ + +/* Should be sent to the ctrlout endpoint */ +#define HFA384x_USB_ENBULKIN 6 + +/* Should be sent to the bulkout endpoint */ +#define HFA384x_USB_TXFRM 0 +#define HFA384x_USB_CMDREQ 1 +#define HFA384x_USB_WRIDREQ 2 +#define HFA384x_USB_RRIDREQ 3 +#define HFA384x_USB_WMEMREQ 4 +#define HFA384x_USB_RMEMREQ 5 + +/* Received from the bulkin endpoint */ +#define HFA384x_USB_ISFRM(a) (!((a) & 0x8000)) +#define HFA384x_USB_ISTXFRM(a) (((a) & 0x9000) == 0x1000) +#define HFA384x_USB_ISRXFRM(a) (!((a) & 0x9000)) +#define HFA384x_USB_INFOFRM 0x8000 +#define HFA384x_USB_CMDRESP 0x8001 +#define HFA384x_USB_WRIDRESP 0x8002 +#define HFA384x_USB_RRIDRESP 0x8003 +#define HFA384x_USB_WMEMRESP 0x8004 +#define HFA384x_USB_RMEMRESP 0x8005 +#define HFA384x_USB_BUFAVAIL 0x8006 +#define HFA384x_USB_ERROR 0x8007 + +/*------------------------------------*/ +/* Request (bulk OUT) packet contents */ + +typedef struct hfa384x_usb_txfrm { + hfa384x_tx_frame_t desc; + UINT8 data[WLAN_DATA_MAXLEN]; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_txfrm_t; + +typedef struct hfa384x_usb_cmdreq { + UINT16 type; + UINT16 cmd; + UINT16 parm0; + UINT16 parm1; + UINT16 parm2; + UINT8 pad[54]; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_cmdreq_t; + +typedef struct hfa384x_usb_wridreq { + UINT16 type; + UINT16 frmlen; + UINT16 rid; + UINT8 data[HFA384x_RIDDATA_MAXLEN]; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_wridreq_t; + +typedef struct hfa384x_usb_rridreq { + UINT16 type; + UINT16 frmlen; + UINT16 rid; + UINT8 pad[58]; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_rridreq_t; + +typedef struct hfa384x_usb_wmemreq { + UINT16 type; + UINT16 frmlen; + UINT16 offset; + UINT16 page; + UINT8 data[HFA384x_USB_RWMEM_MAXLEN]; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_wmemreq_t; + +typedef struct hfa384x_usb_rmemreq { + UINT16 type; + UINT16 frmlen; + UINT16 offset; + UINT16 page; + UINT8 pad[56]; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_rmemreq_t; + +/*------------------------------------*/ +/* Response (bulk IN) packet contents */ + +typedef struct hfa384x_usb_rxfrm { + hfa384x_rx_frame_t desc; + UINT8 data[WLAN_DATA_MAXLEN]; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_rxfrm_t; + +typedef struct hfa384x_usb_infofrm { + UINT16 type; + hfa384x_InfFrame_t info; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_infofrm_t; + +typedef struct hfa384x_usb_statusresp { + UINT16 type; + UINT16 status; + UINT16 resp0; + UINT16 resp1; + UINT16 resp2; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_cmdresp_t; + +typedef hfa384x_usb_cmdresp_t hfa384x_usb_wridresp_t; + +typedef struct hfa384x_usb_rridresp { + UINT16 type; + UINT16 frmlen; + UINT16 rid; + UINT8 data[HFA384x_RIDDATA_MAXLEN]; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_rridresp_t; + +typedef hfa384x_usb_cmdresp_t hfa384x_usb_wmemresp_t; + +typedef struct hfa384x_usb_rmemresp { + UINT16 type; + UINT16 frmlen; + UINT8 data[HFA384x_USB_RWMEM_MAXLEN]; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_rmemresp_t; + +typedef struct hfa384x_usb_bufavail { + UINT16 type; + UINT16 frmlen; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_bufavail_t; + +typedef struct hfa384x_usb_error { + UINT16 type; + UINT16 errortype; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_error_t; + +/*----------------------------------------------------------*/ +/* Unions for packaging all the known packet types together */ + +typedef union hfa384x_usbout { + UINT16 type; + hfa384x_usb_txfrm_t txfrm; + hfa384x_usb_cmdreq_t cmdreq; + hfa384x_usb_wridreq_t wridreq; + hfa384x_usb_rridreq_t rridreq; + hfa384x_usb_wmemreq_t wmemreq; + hfa384x_usb_rmemreq_t rmemreq; +} __WLAN_ATTRIB_PACK__ hfa384x_usbout_t; + +typedef union hfa384x_usbin { + UINT16 type; + hfa384x_usb_rxfrm_t rxfrm; + hfa384x_usb_txfrm_t txfrm; + hfa384x_usb_infofrm_t infofrm; + hfa384x_usb_cmdresp_t cmdresp; + hfa384x_usb_wridresp_t wridresp; + hfa384x_usb_rridresp_t rridresp; + hfa384x_usb_wmemresp_t wmemresp; + hfa384x_usb_rmemresp_t rmemresp; + hfa384x_usb_bufavail_t bufavail; + hfa384x_usb_error_t usberror; + UINT8 boguspad[3000]; +} __WLAN_ATTRIB_PACK__ hfa384x_usbin_t; + +#endif /* WLAN_USB */ + +/*-------------------------------------------------------------------- +PD record structures. +--------------------------------------------------------------------*/ + +typedef struct hfa384x_pdr_pcb_partnum +{ + UINT8 num[8]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_pcb_partnum_t; + +typedef struct hfa384x_pdr_pcb_tracenum +{ + UINT8 num[8]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_pcb_tracenum_t; + +typedef struct hfa384x_pdr_nic_serial +{ + UINT8 num[12]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nic_serial_t; + +typedef struct hfa384x_pdr_mkk_measurements +{ + double carrier_freq; + double occupied_band; + double power_density; + double tx_spur_f1; + double tx_spur_f2; + double tx_spur_f3; + double tx_spur_f4; + double tx_spur_l1; + double tx_spur_l2; + double tx_spur_l3; + double tx_spur_l4; + double rx_spur_f1; + double rx_spur_f2; + double rx_spur_l1; + double rx_spur_l2; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mkk_measurements_t; + +typedef struct hfa384x_pdr_nic_ramsize +{ + UINT8 size[12]; /* units of KB */ +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nic_ramsize_t; + +typedef struct hfa384x_pdr_mfisuprange +{ + UINT16 id; + UINT16 variant; + UINT16 bottom; + UINT16 top; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mfisuprange_t; + +typedef struct hfa384x_pdr_cfisuprange +{ + UINT16 id; + UINT16 variant; + UINT16 bottom; + UINT16 top; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_cfisuprange_t; + +typedef struct hfa384x_pdr_nicid +{ + UINT16 id; + UINT16 variant; + UINT16 major; + UINT16 minor; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nicid_t; + + +typedef struct hfa384x_pdr_refdac_measurements +{ + UINT16 value[0]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_refdac_measurements_t; + +typedef struct hfa384x_pdr_vgdac_measurements +{ + UINT16 value[0]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_vgdac_measurements_t; + +typedef struct hfa384x_pdr_level_comp_measurements +{ + UINT16 value[0]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_level_compc_measurements_t; + +typedef struct hfa384x_pdr_mac_address +{ + UINT8 addr[6]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mac_address_t; + +typedef struct hfa384x_pdr_mkk_callname +{ + UINT8 callname[8]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mkk_callname_t; + +typedef struct hfa384x_pdr_regdomain +{ + UINT16 numdomains; + UINT16 domain[5]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_regdomain_t; + +typedef struct hfa384x_pdr_allowed_channel +{ + UINT16 ch_bitmap; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_allowed_channel_t; + +typedef struct hfa384x_pdr_default_channel +{ + UINT16 channel; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_default_channel_t; + +typedef struct hfa384x_pdr_privacy_option +{ + UINT16 available; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_privacy_option_t; + +typedef struct hfa384x_pdr_temptype +{ + UINT16 type; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_temptype_t; + +typedef struct hfa384x_pdr_refdac_setup +{ + UINT16 ch_value[14]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_refdac_setup_t; + +typedef struct hfa384x_pdr_vgdac_setup +{ + UINT16 ch_value[14]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_vgdac_setup_t; + +typedef struct hfa384x_pdr_level_comp_setup +{ + UINT16 ch_value[14]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_level_comp_setup_t; + +typedef struct hfa384x_pdr_trimdac_setup +{ + UINT16 trimidac; + UINT16 trimqdac; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_trimdac_setup_t; + +typedef struct hfa384x_pdr_ifr_setting +{ + UINT16 value[3]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_ifr_setting_t; + +typedef struct hfa384x_pdr_rfr_setting +{ + UINT16 value[3]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_rfr_setting_t; + +typedef struct hfa384x_pdr_hfa3861_baseline +{ + UINT16 value[50]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_baseline_t; + +typedef struct hfa384x_pdr_hfa3861_shadow +{ + UINT32 value[32]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_shadow_t; + +typedef struct hfa384x_pdr_hfa3861_ifrf +{ + UINT32 value[20]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_ifrf_t; + +typedef struct hfa384x_pdr_hfa3861_chcalsp +{ + UINT16 value[14]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_chcalsp_t; + +typedef struct hfa384x_pdr_hfa3861_chcali +{ + UINT16 value[17]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_chcali_t; + +typedef struct hfa384x_pdr_hfa3861_nic_config +{ + UINT16 config_bitmap; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nic_config_t; + +typedef struct hfa384x_pdr_hfo_delay +{ + UINT8 hfo_delay; +} __WLAN_ATTRIB_PACK__ hfa384x_hfo_delay_t; + +typedef struct hfa384x_pdr_hfa3861_manf_testsp +{ + UINT16 value[30]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_manf_testsp_t; + +typedef struct hfa384x_pdr_hfa3861_manf_testi +{ + UINT16 value[30]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_manf_testi_t; + +typedef struct hfa384x_end_of_pda +{ + UINT16 crc; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_end_of_pda_t; + +typedef struct hfa384x_pdrec +{ + UINT16 len; /* in words */ + UINT16 code; + union pdr { + hfa384x_pdr_pcb_partnum_t pcb_partnum; + hfa384x_pdr_pcb_tracenum_t pcb_tracenum; + hfa384x_pdr_nic_serial_t nic_serial; + hfa384x_pdr_mkk_measurements_t mkk_measurements; + hfa384x_pdr_nic_ramsize_t nic_ramsize; + hfa384x_pdr_mfisuprange_t mfisuprange; + hfa384x_pdr_cfisuprange_t cfisuprange; + hfa384x_pdr_nicid_t nicid; + hfa384x_pdr_refdac_measurements_t refdac_measurements; + hfa384x_pdr_vgdac_measurements_t vgdac_measurements; + hfa384x_pdr_level_compc_measurements_t level_compc_measurements; + hfa384x_pdr_mac_address_t mac_address; + hfa384x_pdr_mkk_callname_t mkk_callname; + hfa384x_pdr_regdomain_t regdomain; + hfa384x_pdr_allowed_channel_t allowed_channel; + hfa384x_pdr_default_channel_t default_channel; + hfa384x_pdr_privacy_option_t privacy_option; + hfa384x_pdr_temptype_t temptype; + hfa384x_pdr_refdac_setup_t refdac_setup; + hfa384x_pdr_vgdac_setup_t vgdac_setup; + hfa384x_pdr_level_comp_setup_t level_comp_setup; + hfa384x_pdr_trimdac_setup_t trimdac_setup; + hfa384x_pdr_ifr_setting_t ifr_setting; + hfa384x_pdr_rfr_setting_t rfr_setting; + hfa384x_pdr_hfa3861_baseline_t hfa3861_baseline; + hfa384x_pdr_hfa3861_shadow_t hfa3861_shadow; + hfa384x_pdr_hfa3861_ifrf_t hfa3861_ifrf; + hfa384x_pdr_hfa3861_chcalsp_t hfa3861_chcalsp; + hfa384x_pdr_hfa3861_chcali_t hfa3861_chcali; + hfa384x_pdr_nic_config_t nic_config; + hfa384x_hfo_delay_t hfo_delay; + hfa384x_pdr_hfa3861_manf_testsp_t hfa3861_manf_testsp; + hfa384x_pdr_hfa3861_manf_testi_t hfa3861_manf_testi; + hfa384x_pdr_end_of_pda_t end_of_pda; + + } data; +} __WLAN_ATTRIB_PACK__ hfa384x_pdrec_t; + + +#ifdef __KERNEL__ +/*-------------------------------------------------------------------- +--- MAC state structure, argument to all functions -- +--- Also, a collection of support types -- +--------------------------------------------------------------------*/ +typedef struct hfa384x_statusresult +{ + UINT16 status; + UINT16 resp0; + UINT16 resp1; + UINT16 resp2; +} hfa384x_cmdresult_t; + +#if (WLAN_HOSTIF == WLAN_USB) + +/* USB Control Exchange (CTLX): + * A queue of the structure below is maintained for all of the + * Request/Response type USB packets supported by Prism2. + */ +/* The following hfa384x_* structures are arguments to + * the usercb() for the different CTLX types. + */ +typedef hfa384x_cmdresult_t hfa384x_wridresult_t; +typedef hfa384x_cmdresult_t hfa384x_wmemresult_t; + +typedef struct hfa384x_rridresult +{ + UINT16 rid; + const void *riddata; + UINT riddata_len; +} hfa384x_rridresult_t; + +enum ctlx_state { + CTLX_START = 0, /* Start state, not queued */ + + CTLX_COMPLETE, /* CTLX successfully completed */ + CTLX_REQ_FAILED, /* OUT URB completed w/ error */ + + CTLX_PENDING, /* Queued, data valid */ + CTLX_REQ_SUBMITTED, /* OUT URB submitted */ + CTLX_REQ_COMPLETE, /* OUT URB complete */ + CTLX_RESP_COMPLETE /* IN URB received */ +}; +typedef enum ctlx_state CTLX_STATE; + +struct hfa384x_usbctlx; +struct hfa384x; + +typedef void (*ctlx_cmdcb_t)( struct hfa384x*, const struct hfa384x_usbctlx* ); + +typedef void (*ctlx_usercb_t)( + struct hfa384x *hw, + void *ctlxresult, + void *usercb_data); + +typedef struct hfa384x_usbctlx +{ + struct list_head list; + + size_t outbufsize; + hfa384x_usbout_t outbuf; /* pkt buf for OUT */ + hfa384x_usbin_t inbuf; /* pkt buf for IN(a copy) */ + + CTLX_STATE state; /* Tracks running state */ + + struct completion done; + volatile int reapable; /* Food for the reaper task */ + + ctlx_cmdcb_t cmdcb; /* Async command callback */ + ctlx_usercb_t usercb; /* Async user callback, */ + void *usercb_data; /* at CTLX completion */ + + int variant; /* Identifies cmd variant */ +} hfa384x_usbctlx_t; + +typedef struct hfa384x_usbctlxq +{ + spinlock_t lock; + struct list_head pending; + struct list_head active; + struct list_head completing; + struct list_head reapable; +} hfa384x_usbctlxq_t; +#endif + +typedef struct hfa484x_metacmd +{ + UINT16 cmd; + + UINT16 parm0; + UINT16 parm1; + UINT16 parm2; + +#if 0 //XXX cmd irq stuff + UINT16 bulkid; /* what RID/FID to copy down. */ + int bulklen; /* how much to copy from BAP */ + char *bulkdata; /* And to where? */ +#endif + + hfa384x_cmdresult_t result; +} hfa384x_metacmd_t; + +#define MAX_PRISM2_GRP_ADDR 16 +#define MAX_GRP_ADDR 32 +#define WLAN_COMMENT_MAX 80 /* Max. length of user comment string. */ + +#define MM_SAT_PCF (BIT14) +#define MM_GCSD_PCF (BIT15) +#define MM_GCSD_PCF_EB (BIT14 | BIT15) + +#define WLAN_STATE_STOPPED 0 /* Network is not active. */ +#define WLAN_STATE_STARTED 1 /* Network has been started. */ + +#define WLAN_AUTH_MAX 60 /* Max. # of authenticated stations. */ +#define WLAN_ACCESS_MAX 60 /* Max. # of stations in an access list. */ +#define WLAN_ACCESS_NONE 0 /* No stations may be authenticated. */ +#define WLAN_ACCESS_ALL 1 /* All stations may be authenticated. */ +#define WLAN_ACCESS_ALLOW 2 /* Authenticate only "allowed" stations. */ +#define WLAN_ACCESS_DENY 3 /* Do not authenticate "denied" stations. */ + +/* XXX These are going away ASAP */ +typedef struct prism2sta_authlist +{ + UINT cnt; + UINT8 addr[WLAN_AUTH_MAX][WLAN_ADDR_LEN]; + UINT8 assoc[WLAN_AUTH_MAX]; +} prism2sta_authlist_t; + +typedef struct prism2sta_accesslist +{ + UINT modify; + UINT cnt; + UINT8 addr[WLAN_ACCESS_MAX][WLAN_ADDR_LEN]; + UINT cnt1; + UINT8 addr1[WLAN_ACCESS_MAX][WLAN_ADDR_LEN]; +} prism2sta_accesslist_t; + +typedef struct hfa384x +{ +#if (WLAN_HOSTIF != WLAN_USB) + /* Resource config */ + UINT32 iobase; + char __iomem *membase; + UINT32 irq; +#else + /* USB support data */ + struct usb_device *usb; + struct urb rx_urb; + struct sk_buff *rx_urb_skb; + struct urb tx_urb; + struct urb ctlx_urb; + hfa384x_usbout_t txbuff; + hfa384x_usbctlxq_t ctlxq; + struct timer_list reqtimer; + struct timer_list resptimer; + + struct timer_list throttle; + + struct tasklet_struct reaper_bh; + struct tasklet_struct completion_bh; + + struct work_struct usb_work; + + unsigned long usb_flags; +#define THROTTLE_RX 0 +#define THROTTLE_TX 1 +#define WORK_RX_HALT 2 +#define WORK_TX_HALT 3 +#define WORK_RX_RESUME 4 +#define WORK_TX_RESUME 5 + + unsigned short req_timer_done:1; + unsigned short resp_timer_done:1; + + int endp_in; + int endp_out; +#endif /* !USB */ + +#if (WLAN_HOSTIF == WLAN_PCMCIA) +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16) + struct pcmcia_device *pdev; +#else + dev_link_t *link; +#endif + dev_node_t node; +#endif + + int sniff_fcs; + int sniff_channel; + int sniff_truncate; + int sniffhdr; + + wait_queue_head_t cmdq; /* wait queue itself */ + + /* Controller state */ + UINT32 state; + UINT32 isap; + UINT8 port_enabled[HFA384x_NUMPORTS_MAX]; +#if (WLAN_HOSTIF != WLAN_USB) + UINT auxen; + UINT isram16; +#endif /* !USB */ + + /* Download support */ + UINT dlstate; + hfa384x_downloadbuffer_t bufinfo; + UINT16 dltimeout; + +#if (WLAN_HOSTIF != WLAN_USB) + spinlock_t cmdlock; + volatile int cmdflag; /* wait queue flag */ + hfa384x_metacmd_t *cmddata; /* for our async callback */ + + /* BAP support */ + spinlock_t baplock; + struct tasklet_struct bap_tasklet; + + /* MAC buffer ids */ + UINT16 txfid_head; + UINT16 txfid_tail; + UINT txfid_N; + UINT16 txfid_queue[HFA384x_DRVR_FIDSTACKLEN_MAX]; + UINT16 infofid; + struct semaphore infofid_sem; +#endif /* !USB */ + + int scanflag; /* to signal scan comlete */ + int join_ap; /* are we joined to a specific ap */ + int join_retries; /* number of join retries till we fail */ + hfa384x_JoinRequest_data_t joinreq; /* join request saved data */ + + wlandevice_t *wlandev; + /* Timer to allow for the deferred processing of linkstatus messages */ + struct work_struct link_bh; + + struct work_struct commsqual_bh; + hfa384x_commsquality_t qual; + struct timer_list commsqual_timer; + + UINT16 link_status; + UINT16 link_status_new; + struct sk_buff_head authq; + + /* And here we have stuff that used to be in priv */ + + /* State variables */ + UINT presniff_port_type; + UINT16 presniff_wepflags; + UINT32 dot11_desired_bss_type; + int ap; /* AP flag: 0 - Station, 1 - Access Point. */ + + int dbmadjust; + + /* Group Addresses - right now, there are up to a total + of MAX_GRP_ADDR group addresses */ + UINT8 dot11_grp_addr[MAX_GRP_ADDR][WLAN_ADDR_LEN]; + UINT dot11_grpcnt; + + /* Component Identities */ + hfa384x_compident_t ident_nic; + hfa384x_compident_t ident_pri_fw; + hfa384x_compident_t ident_sta_fw; + hfa384x_compident_t ident_ap_fw; + UINT16 mm_mods; + + /* Supplier compatibility ranges */ + hfa384x_caplevel_t cap_sup_mfi; + hfa384x_caplevel_t cap_sup_cfi; + hfa384x_caplevel_t cap_sup_pri; + hfa384x_caplevel_t cap_sup_sta; + hfa384x_caplevel_t cap_sup_ap; + + /* Actor compatibility ranges */ + hfa384x_caplevel_t cap_act_pri_cfi; /* pri f/w to controller interface */ + hfa384x_caplevel_t cap_act_sta_cfi; /* sta f/w to controller interface */ + hfa384x_caplevel_t cap_act_sta_mfi; /* sta f/w to modem interface */ + hfa384x_caplevel_t cap_act_ap_cfi; /* ap f/w to controller interface */ + hfa384x_caplevel_t cap_act_ap_mfi; /* ap f/w to modem interface */ + + UINT32 psusercount; /* Power save user count. */ + hfa384x_CommTallies32_t tallies; /* Communication tallies. */ + UINT8 comment[WLAN_COMMENT_MAX+1]; /* User comment */ + + /* Channel Info request results (AP only) */ + struct { + atomic_t done; + UINT8 count; + hfa384x_ChInfoResult_t results; + } channel_info; + + hfa384x_InfFrame_t *scanresults; + + + prism2sta_authlist_t authlist; /* Authenticated station list. */ + UINT accessmode; /* Access mode. */ + prism2sta_accesslist_t allow; /* Allowed station list. */ + prism2sta_accesslist_t deny; /* Denied station list. */ + +} hfa384x_t; + +/*=============================================================*/ +/*--- Function Declarations -----------------------------------*/ +/*=============================================================*/ +#if (WLAN_HOSTIF == WLAN_USB) +void +hfa384x_create( + hfa384x_t *hw, + struct usb_device *usb); +#else +void +hfa384x_create( + hfa384x_t *hw, + UINT irq, + UINT32 iobase, + UINT8 __iomem *membase); +#endif + +void hfa384x_destroy(hfa384x_t *hw); + +irqreturn_t +hfa384x_interrupt(int irq, void *dev_id PT_REGS); +int +hfa384x_corereset( hfa384x_t *hw, int holdtime, int settletime, int genesis); +int +hfa384x_drvr_chinforesults( hfa384x_t *hw); +int +hfa384x_drvr_commtallies( hfa384x_t *hw); +int +hfa384x_drvr_disable(hfa384x_t *hw, UINT16 macport); +int +hfa384x_drvr_enable(hfa384x_t *hw, UINT16 macport); +int +hfa384x_drvr_flashdl_enable(hfa384x_t *hw); +int +hfa384x_drvr_flashdl_disable(hfa384x_t *hw); +int +hfa384x_drvr_flashdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len); +int +hfa384x_drvr_getconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len); +int +hfa384x_drvr_handover( hfa384x_t *hw, UINT8 *addr); +int +hfa384x_drvr_hostscanresults( hfa384x_t *hw); +int +hfa384x_drvr_low_level(hfa384x_t *hw, hfa384x_metacmd_t *cmd); +int +hfa384x_drvr_mmi_read(hfa384x_t *hw, UINT32 address, UINT32 *result); +int +hfa384x_drvr_mmi_write(hfa384x_t *hw, UINT32 address, UINT32 data); +int +hfa384x_drvr_ramdl_enable(hfa384x_t *hw, UINT32 exeaddr); +int +hfa384x_drvr_ramdl_disable(hfa384x_t *hw); +int +hfa384x_drvr_ramdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len); +int +hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, UINT len); +int +hfa384x_drvr_scanresults( hfa384x_t *hw); + +int +hfa384x_drvr_setconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len); + +static inline int +hfa384x_drvr_getconfig16(hfa384x_t *hw, UINT16 rid, void *val) +{ + int result = 0; + result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(UINT16)); + if ( result == 0 ) { + *((UINT16*)val) = hfa384x2host_16(*((UINT16*)val)); + } + return result; +} + +static inline int +hfa384x_drvr_getconfig32(hfa384x_t *hw, UINT16 rid, void *val) +{ + int result = 0; + + result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(UINT32)); + if ( result == 0 ) { + *((UINT32*)val) = hfa384x2host_32(*((UINT32*)val)); + } + + return result; +} + +static inline int +hfa384x_drvr_setconfig16(hfa384x_t *hw, UINT16 rid, UINT16 val) +{ + UINT16 value = host2hfa384x_16(val); + return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(value)); +} + +static inline int +hfa384x_drvr_setconfig32(hfa384x_t *hw, UINT16 rid, UINT32 val) +{ + UINT32 value = host2hfa384x_32(val); + return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(value)); +} + +#if (WLAN_HOSTIF == WLAN_USB) +int +hfa384x_drvr_getconfig_async(hfa384x_t *hw, + UINT16 rid, + ctlx_usercb_t usercb, + void *usercb_data); + +int +hfa384x_drvr_setconfig_async(hfa384x_t *hw, + UINT16 rid, + void *buf, + UINT16 len, + ctlx_usercb_t usercb, + void *usercb_data); +#else +static inline int +hfa384x_drvr_setconfig_async(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len, + void *ptr1, void *ptr2) +{ + (void)ptr1; + (void)ptr2; + return hfa384x_drvr_setconfig(hw, rid, buf, len); +} +#endif + +static inline int +hfa384x_drvr_setconfig16_async(hfa384x_t *hw, UINT16 rid, UINT16 val) +{ + UINT16 value = host2hfa384x_16(val); + return hfa384x_drvr_setconfig_async(hw, rid, &value, sizeof(value), + NULL , NULL); +} + +static inline int +hfa384x_drvr_setconfig32_async(hfa384x_t *hw, UINT16 rid, UINT32 val) +{ + UINT32 value = host2hfa384x_32(val); + return hfa384x_drvr_setconfig_async(hw, rid, &value, sizeof(value), + NULL , NULL); +} + + +int +hfa384x_drvr_start(hfa384x_t *hw); +int +hfa384x_drvr_stop(hfa384x_t *hw); +int +hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep); +void +hfa384x_tx_timeout(wlandevice_t *wlandev); + +int +hfa384x_cmd_initialize(hfa384x_t *hw); +int +hfa384x_cmd_enable(hfa384x_t *hw, UINT16 macport); +int +hfa384x_cmd_disable(hfa384x_t *hw, UINT16 macport); +int +hfa384x_cmd_diagnose(hfa384x_t *hw); +int +hfa384x_cmd_allocate(hfa384x_t *hw, UINT16 len); +int +hfa384x_cmd_transmit(hfa384x_t *hw, UINT16 reclaim, UINT16 qos, UINT16 fid); +int +hfa384x_cmd_clearpersist(hfa384x_t *hw, UINT16 fid); +int +hfa384x_cmd_notify(hfa384x_t *hw, UINT16 reclaim, UINT16 fid, void *buf, UINT16 len); +int +hfa384x_cmd_inquire(hfa384x_t *hw, UINT16 fid); +int +hfa384x_cmd_access(hfa384x_t *hw, UINT16 write, UINT16 rid, void *buf, UINT16 len); +int +hfa384x_cmd_monitor(hfa384x_t *hw, UINT16 enable); +int +hfa384x_cmd_download( + hfa384x_t *hw, + UINT16 mode, + UINT16 lowaddr, + UINT16 highaddr, + UINT16 codelen); +int +hfa384x_cmd_aux_enable(hfa384x_t *hw, int force); +int +hfa384x_cmd_aux_disable(hfa384x_t *hw); +int +hfa384x_copy_from_bap( + hfa384x_t *hw, + UINT16 bap, + UINT16 id, + UINT16 offset, + void *buf, + UINT len); +int +hfa384x_copy_to_bap( + hfa384x_t *hw, + UINT16 bap, + UINT16 id, + UINT16 offset, + void *buf, + UINT len); +void +hfa384x_copy_from_aux( + hfa384x_t *hw, + UINT32 cardaddr, + UINT32 auxctl, + void *buf, + UINT len); +void +hfa384x_copy_to_aux( + hfa384x_t *hw, + UINT32 cardaddr, + UINT32 auxctl, + void *buf, + UINT len); + +#if (WLAN_HOSTIF != WLAN_USB) + +/* + HFA384x is a LITTLE ENDIAN part. + + the get/setreg functions implicitly byte-swap the data to LE. + the _noswap variants do not perform a byte-swap on the data. +*/ + +static inline UINT16 +__hfa384x_getreg(hfa384x_t *hw, UINT reg); + +static inline void +__hfa384x_setreg(hfa384x_t *hw, UINT16 val, UINT reg); + +static inline UINT16 +__hfa384x_getreg_noswap(hfa384x_t *hw, UINT reg); + +static inline void +__hfa384x_setreg_noswap(hfa384x_t *hw, UINT16 val, UINT reg); + +#ifdef REVERSE_ENDIAN +#define hfa384x_getreg __hfa384x_getreg_noswap +#define hfa384x_setreg __hfa384x_setreg_noswap +#define hfa384x_getreg_noswap __hfa384x_getreg +#define hfa384x_setreg_noswap __hfa384x_setreg +#else +#define hfa384x_getreg __hfa384x_getreg +#define hfa384x_setreg __hfa384x_setreg +#define hfa384x_getreg_noswap __hfa384x_getreg_noswap +#define hfa384x_setreg_noswap __hfa384x_setreg_noswap +#endif + +/*---------------------------------------------------------------- +* hfa384x_getreg +* +* Retrieve the value of one of the MAC registers. Done here +* because different PRISM2 MAC parts use different buses and such. +* NOTE: This function returns the value in HOST ORDER!!!!!! +* +* Arguments: +* hw MAC part structure +* reg Register identifier (offset for I/O based i/f) +* +* Returns: +* Value from the register in HOST ORDER!!!! +----------------------------------------------------------------*/ +static inline UINT16 +__hfa384x_getreg(hfa384x_t *hw, UINT reg) +{ +/* printk(KERN_DEBUG "Reading from 0x%0x\n", hw->membase + reg); */ +#if ((WLAN_HOSTIF == WLAN_PCMCIA) || (WLAN_HOSTIF == WLAN_PLX)) + return wlan_inw_le16_to_cpu(hw->iobase+reg); +#elif (WLAN_HOSTIF == WLAN_PCI) + return __le16_to_cpu(readw(hw->membase + reg)); +#endif +} + +/*---------------------------------------------------------------- +* hfa384x_setreg +* +* Set the value of one of the MAC registers. Done here +* because different PRISM2 MAC parts use different buses and such. +* NOTE: This function assumes the value is in HOST ORDER!!!!!! +* +* Arguments: +* hw MAC part structure +* val Value, in HOST ORDER!!, to put in the register +* reg Register identifier (offset for I/O based i/f) +* +* Returns: +* Nothing +----------------------------------------------------------------*/ +static inline void +__hfa384x_setreg(hfa384x_t *hw, UINT16 val, UINT reg) +{ +#if ((WLAN_HOSTIF == WLAN_PCMCIA) || (WLAN_HOSTIF == WLAN_PLX)) + wlan_outw_cpu_to_le16( val, hw->iobase + reg); + return; +#elif (WLAN_HOSTIF == WLAN_PCI) + writew(__cpu_to_le16(val), hw->membase + reg); + return; +#endif +} + + +/*---------------------------------------------------------------- +* hfa384x_getreg_noswap +* +* Retrieve the value of one of the MAC registers. Done here +* because different PRISM2 MAC parts use different buses and such. +* +* Arguments: +* hw MAC part structure +* reg Register identifier (offset for I/O based i/f) +* +* Returns: +* Value from the register. +----------------------------------------------------------------*/ +static inline UINT16 +__hfa384x_getreg_noswap(hfa384x_t *hw, UINT reg) +{ +#if ((WLAN_HOSTIF == WLAN_PCMCIA) || (WLAN_HOSTIF == WLAN_PLX)) + return wlan_inw(hw->iobase+reg); +#elif (WLAN_HOSTIF == WLAN_PCI) + return readw(hw->membase + reg); +#endif +} + + +/*---------------------------------------------------------------- +* hfa384x_setreg_noswap +* +* Set the value of one of the MAC registers. Done here +* because different PRISM2 MAC parts use different buses and such. +* +* Arguments: +* hw MAC part structure +* val Value to put in the register +* reg Register identifier (offset for I/O based i/f) +* +* Returns: +* Nothing +----------------------------------------------------------------*/ +static inline void +__hfa384x_setreg_noswap(hfa384x_t *hw, UINT16 val, UINT reg) +{ +#if ((WLAN_HOSTIF == WLAN_PCMCIA) || (WLAN_HOSTIF == WLAN_PLX)) + wlan_outw( val, hw->iobase + reg); + return; +#elif (WLAN_HOSTIF == WLAN_PCI) + writew(val, hw->membase + reg); + return; +#endif +} + + +static inline void hfa384x_events_all(hfa384x_t *hw) +{ + hfa384x_setreg(hw, + HFA384x_INT_NORMAL +#ifdef CMD_IRQ + | HFA384x_INTEN_CMD_SET(1) +#endif + , + HFA384x_INTEN); + +} + +static inline void hfa384x_events_nobap(hfa384x_t *hw) +{ + hfa384x_setreg(hw, + (HFA384x_INT_NORMAL & ~HFA384x_INT_BAP_OP) +#ifdef CMD_IRQ + | HFA384x_INTEN_CMD_SET(1) +#endif + , + HFA384x_INTEN); + +} + +#endif /* WLAN_HOSTIF != WLAN_USB */ +#endif /* __KERNEL__ */ + +#endif /* _HFA384x_H */ --- linux-2.6.28.orig/ubuntu/misc/wireless/prism2_usb/prism2/prism2mgmt.h +++ linux-2.6.28/ubuntu/misc/wireless/prism2_usb/prism2/prism2mgmt.h @@ -0,0 +1,182 @@ +/* src/prism2/include/prism2/prism2mgmt.h +* +* Declares the mgmt command handler functions +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file contains the constants and data structures for interaction +* with the hfa384x Wireless LAN (WLAN) Media Access Contoller (MAC). +* The hfa384x is a portion of the Harris PRISM(tm) WLAN chipset. +* +* [Implementation and usage notes] +* +* [References] +* CW10 Programmer's Manual v1.5 +* IEEE 802.11 D10.0 +* +* -------------------------------------------------------------------- +*/ + +#ifndef _PRISM2MGMT_H +#define _PRISM2MGMT_H + + +/*=============================================================*/ +/*------ Constants --------------------------------------------*/ + +/*=============================================================*/ +/*------ Macros -----------------------------------------------*/ + +/*=============================================================*/ +/*------ Types and their related constants --------------------*/ + +/*=============================================================*/ +/*------ Static variable externs ------------------------------*/ + +#if (WLAN_HOSTIF != WLAN_USB) +extern int prism2_bap_timeout; +extern int prism2_irq_evread_max; +#endif +extern int prism2_debug; +extern int prism2_reset_holdtime; +extern int prism2_reset_settletime; +/*=============================================================*/ +/*--- Function Declarations -----------------------------------*/ +/*=============================================================*/ + +UINT32 +prism2sta_ifstate(wlandevice_t *wlandev, UINT32 ifstate); + +void +prism2sta_ev_dtim(wlandevice_t *wlandev); +void +prism2sta_ev_infdrop(wlandevice_t *wlandev); +void +prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf); +void +prism2sta_ev_txexc(wlandevice_t *wlandev, UINT16 status); +void +prism2sta_ev_tx(wlandevice_t *wlandev, UINT16 status); +void +prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb); +void +prism2sta_ev_alloc(wlandevice_t *wlandev); + + +int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_powermgmt(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_join(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_p2_join(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_authenticate(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_deauthenticate(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_associate(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_reassociate(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_disassociate(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_reset(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_start(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_readcis(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_auxport_state(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_auxport_read(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_auxport_write(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_low_level(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_test_command(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_mmi_read(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_mmi_write(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_mm_state(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_dump_state(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_enable(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_channel_info(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_channel_info_results(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp); + +/*--------------------------------------------------------------- +* conversion functions going between wlan message data types and +* Prism2 data types +---------------------------------------------------------------*/ +/* byte area conversion functions*/ +void prism2mgmt_pstr2bytearea(UINT8 *bytearea, p80211pstrd_t *pstr); +void prism2mgmt_bytearea2pstr(UINT8 *bytearea, p80211pstrd_t *pstr, int len); + +/* byte string conversion functions*/ +void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr); +void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr); + +/* integer conversion functions */ +void prism2mgmt_prism2int2p80211int(UINT16 *prism2int, UINT32 *wlanint); +void prism2mgmt_p80211int2prism2int(UINT16 *prism2int, UINT32 *wlanint); + +/* enumerated integer conversion functions */ +void prism2mgmt_prism2enum2p80211enum(UINT16 *prism2enum, UINT32 *wlanenum, UINT16 rid); +void prism2mgmt_p80211enum2prism2enum(UINT16 *prism2enum, UINT32 *wlanenum, UINT16 rid); + +/* functions to convert a bit area to/from an Operational Rate Set */ +void prism2mgmt_get_oprateset(UINT16 *rate, p80211pstrd_t *pstr); +void prism2mgmt_set_oprateset(UINT16 *rate, p80211pstrd_t *pstr); + +/* functions to convert Group Addresses */ +void prism2mgmt_get_grpaddr(UINT32 did, + p80211pstrd_t *pstr, hfa384x_t *priv ); +int prism2mgmt_set_grpaddr(UINT32 did, + UINT8 *prism2buf, p80211pstrd_t *pstr, hfa384x_t *priv ); +int prism2mgmt_get_grpaddr_index( UINT32 did ); + +void prism2sta_processing_defer(struct work_struct *data); + +void prism2sta_commsqual_defer(struct work_struct *data); +void prism2sta_commsqual_timer(unsigned long data); + +/*=============================================================*/ +/*--- Inline Function Definitions (if supported) --------------*/ +/*=============================================================*/ + + + +#endif --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/wlan_hdr.h +++ linux-2.6.28/ubuntu/misc/wireless/acx/wlan_hdr.h @@ -0,0 +1,497 @@ +/*********************************************************************** +** Copyright (C) 2003 ACX100 Open Source Project +** +** The contents of this file are subject to the Mozilla Public +** License Version 1.1 (the "License"); you may not use this file +** except in compliance with the License. You may obtain a copy of +** the License at http://www.mozilla.org/MPL/ +** +** Software distributed under the License is distributed on an "AS +** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +** implied. See the License for the specific language governing +** rights and limitations under the License. +** +** Alternatively, the contents of this file may be used under the +** terms of the GNU Public License version 2 (the "GPL"), in which +** case the provisions of the GPL are applicable instead of the +** above. If you wish to allow the use of your version of this file +** only under the terms of the GPL and not to allow others to use +** your version of this file under the MPL, indicate your decision +** by deleting the provisions above and replace them with the notice +** and other provisions required by the GPL. If you do not delete +** the provisions above, a recipient may use your version of this +** file under either the MPL or the GPL. +** --------------------------------------------------------------------- +** Inquiries regarding the ACX100 Open Source Project can be +** made directly to: +** +** acx100-users@lists.sf.net +** http://acx100.sf.net +** --------------------------------------------------------------------- +*/ + +/*********************************************************************** +** This code is based on elements which are +** Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +** info@linux-wlan.com +** http://www.linux-wlan.com +*/ + +/* mini-doc + +Here are all 11b/11g/11a rates and modulations: + + 11b 11g 11a + --- --- --- + 1 |B |B | + 2 |Q |Q | + 5.5|Cp |C p| + 6 | |Od |O + 9 | |od |o +11 |Cp |C p| +12 | |Od |O +18 | |od |o +22 | | p| +24 | |Od |O +33 | | p| +36 | |od |o +48 | |od |o +54 | |od |o + +Mandatory: + B - DBPSK (Differential Binary Phase Shift Keying) + Q - DQPSK (Differential Quaternary Phase Shift Keying) + C - CCK (Complementary Code Keying, a form of DSSS + (Direct Sequence Spread Spectrum) modulation) + O - OFDM (Orthogonal Frequency Division Multiplexing) +Optional: + o - OFDM + d - CCK-OFDM (also known as DSSS-OFDM) + p - PBCC (Packet Binary Convolutional Coding) + +The term CCK-OFDM may be used interchangeably with DSSS-OFDM +(the IEEE 802.11g-2003 standard uses the latter terminology). +In the CCK-OFDM, the PLCP header of the frame uses the CCK form of DSSS, +while the PLCP payload (the MAC frame) is modulated using OFDM. + +Basically, you must use CCK-OFDM if you have mixed 11b/11g environment, +or else (pure OFDM) 11b equipment may not realize that AP +is sending a packet and start sending its own one. +Sadly, looks like acx111 does not support CCK-OFDM, only pure OFDM. + +Re PBCC: avoid using it. It makes sense only if you have +TI "11b+" hardware. You _must_ use PBCC in order to reach 22Mbps on it. + +Preambles: + +Long preamble (at 1Mbit rate, takes 144 us): + 16 bytes ones + 2 bytes 0xF3A0 (lsb sent first) +PLCP header follows (at 1Mbit also): + 1 byte Signal: speed, in 0.1Mbit units, except for: + 33Mbit: 33 (instead of 330 - doesn't fit in octet) + all CCK-OFDM rates: 30 + 1 byte Service + 0,1,4: reserved + 2: 1=locked clock + 3: 1=PBCC + 5: Length Extension (PBCC 22,33Mbit (11g only)) <- + 6: Length Extension (PBCC 22,33Mbit (11g only)) <- BLACK MAGIC HERE + 7: Length Extension <- + 2 bytes Length (time needed to tx this frame) + a) 5.5 Mbit/s CCK + Length = octets*8/5.5, rounded up to integer + b) 11 Mbit/s CCK + Length = octets*8/11, rounded up to integer + Service bit 7: + 0 = rounding took less than 8/11 + 1 = rounding took more than or equal to 8/11 + c) 5.5 Mbit/s PBCC + Length = (octets+1)*8/5.5, rounded up to integer + d) 11 Mbit/s PBCC + Length = (octets+1)*8/11, rounded up to integer + Service bit 7: + 0 = rounding took less than 8/11 + 1 = rounding took more than or equal to 8/11 + e) 22 Mbit/s PBCC + Length = (octets+1)*8/22, rounded up to integer + Service bits 6,7: + 00 = rounding took less than 8/22ths + 01 = rounding took 8/22...15/22ths + 10 = rounding took 16/22ths or more. + f) 33 Mbit/s PBCC + Length = (octets+1)*8/33, rounded up to integer + Service bits 5,6,7: + 000 rounding took less than 8/33 + 001 rounding took 8/33...15/33 + 010 rounding took 16/33...23/33 + 011 rounding took 24/33...31/33 + 100 rounding took 32/33 or more + 2 bytes CRC + +PSDU follows (up to 2346 bytes at selected rate) + +While Signal value alone is not enough to determine rate and modulation, +Signal+Service is always sufficient. + +Short preamble (at 1Mbit rate, takes 72 us): + 7 bytes zeroes + 2 bytes 0x05CF (lsb sent first) +PLCP header follows *at 2Mbit/s*. Format is the same as in long preamble. +PSDU follows (up to 2346 bytes at selected rate) + +OFDM preamble is completely different, uses OFDM +modulation from the start and thus easily identifiable. +Not shown here. +*/ + + +/*********************************************************************** +** Constants +*/ + +#define WLAN_HDR_A3_LEN 24 +#define WLAN_HDR_A4_LEN 30 +/* IV structure: +** 3 bytes: Initialization Vector (24 bits) +** 1 byte: 0..5: padding, must be 0; 6..7: key selector (0-3) +*/ +#define WLAN_WEP_IV_LEN 4 +/* 802.11 says 2312 but looks like 2312 is a max size of _WEPed data_ */ +#define WLAN_DATA_MAXLEN 2304 +#define WLAN_WEP_ICV_LEN 4 +#define WLAN_FCS_LEN 4 +#define WLAN_A3FR_MAXLEN (WLAN_HDR_A3_LEN + WLAN_DATA_MAXLEN) +#define WLAN_A4FR_MAXLEN (WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN) +#define WLAN_A3FR_MAXLEN_FCS (WLAN_HDR_A3_LEN + WLAN_DATA_MAXLEN + 4) +#define WLAN_A4FR_MAXLEN_FCS (WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + 4) +#define WLAN_A3FR_MAXLEN_WEP (WLAN_A3FR_MAXLEN + 8) +#define WLAN_A4FR_MAXLEN_WEP (WLAN_A4FR_MAXLEN + 8) +#define WLAN_A3FR_MAXLEN_WEP_FCS (WLAN_A3FR_MAXLEN_FCS + 8) +#define WLAN_A4FR_MAXLEN_WEP_FCS (WLAN_A4FR_MAXLEN_FCS + 8) + +#define WLAN_BSS_TS_LEN 8 +#define WLAN_SSID_MAXLEN 32 +#define WLAN_BEACON_FR_MAXLEN (WLAN_HDR_A3_LEN + 334) +#define WLAN_ATIM_FR_MAXLEN (WLAN_HDR_A3_LEN + 0) +#define WLAN_DISASSOC_FR_MAXLEN (WLAN_HDR_A3_LEN + 2) +#define WLAN_ASSOCREQ_FR_MAXLEN (WLAN_HDR_A3_LEN + 48) +#define WLAN_ASSOCRESP_FR_MAXLEN (WLAN_HDR_A3_LEN + 16) +#define WLAN_REASSOCREQ_FR_MAXLEN (WLAN_HDR_A3_LEN + 54) +#define WLAN_REASSOCRESP_FR_MAXLEN (WLAN_HDR_A3_LEN + 16) +#define WLAN_PROBEREQ_FR_MAXLEN (WLAN_HDR_A3_LEN + 44) +#define WLAN_PROBERESP_FR_MAXLEN (WLAN_HDR_A3_LEN + 78) +#define WLAN_AUTHEN_FR_MAXLEN (WLAN_HDR_A3_LEN + 261) +#define WLAN_DEAUTHEN_FR_MAXLEN (WLAN_HDR_A3_LEN + 2) +#define WLAN_CHALLENGE_IE_LEN 130 +#define WLAN_CHALLENGE_LEN 128 +#define WLAN_WEP_MAXKEYLEN 13 +#define WLAN_WEP_NKEYS 4 + +/*--- Frame Control Field -------------------------------------*/ +/* Frame Types */ +#define WLAN_FTYPE_MGMT 0x00 +#define WLAN_FTYPE_CTL 0x01 +#define WLAN_FTYPE_DATA 0x02 + +/* Frame subtypes */ +/* Management */ +#define WLAN_FSTYPE_ASSOCREQ 0x00 +#define WLAN_FSTYPE_ASSOCRESP 0x01 +#define WLAN_FSTYPE_REASSOCREQ 0x02 +#define WLAN_FSTYPE_REASSOCRESP 0x03 +#define WLAN_FSTYPE_PROBEREQ 0x04 +#define WLAN_FSTYPE_PROBERESP 0x05 +#define WLAN_FSTYPE_BEACON 0x08 +#define WLAN_FSTYPE_ATIM 0x09 +#define WLAN_FSTYPE_DISASSOC 0x0a +#define WLAN_FSTYPE_AUTHEN 0x0b +#define WLAN_FSTYPE_DEAUTHEN 0x0c + +/* Control */ +#define WLAN_FSTYPE_PSPOLL 0x0a +#define WLAN_FSTYPE_RTS 0x0b +#define WLAN_FSTYPE_CTS 0x0c +#define WLAN_FSTYPE_ACK 0x0d +#define WLAN_FSTYPE_CFEND 0x0e +#define WLAN_FSTYPE_CFENDCFACK 0x0f + +/* Data */ +#define WLAN_FSTYPE_DATAONLY 0x00 +#define WLAN_FSTYPE_DATA_CFACK 0x01 +#define WLAN_FSTYPE_DATA_CFPOLL 0x02 +#define WLAN_FSTYPE_DATA_CFACK_CFPOLL 0x03 +#define WLAN_FSTYPE_NULL 0x04 +#define WLAN_FSTYPE_CFACK 0x05 +#define WLAN_FSTYPE_CFPOLL 0x06 +#define WLAN_FSTYPE_CFACK_CFPOLL 0x07 + +/*--- FC Constants v. 2.0 ------------------------------------*/ +/* Each constant is defined twice: WF_CONST is in host */ +/* byteorder, WF_CONSTi is in ieee byteorder. */ +/* Usage: */ +/* printf("the frame subtype is %X", WF_FC_FTYPEi & rx.fc); */ +/* tx.fc = WF_FTYPE_CTLi | WF_FSTYPE_RTSi; */ +/*------------------------------------------------------------*/ + +enum { +/*--- Frame Control Field -------------------------------------*/ +/* Protocol version: always 0 for current 802.11 standards */ +IEEE16(WF_FC_PVER, 0x0003) +IEEE16(WF_FC_FTYPE, 0x000c) +IEEE16(WF_FC_FSTYPE, 0x00f0) +IEEE16(WF_FC_TODS, 0x0100) +IEEE16(WF_FC_FROMDS, 0x0200) +IEEE16(WF_FC_FROMTODS, 0x0300) +IEEE16(WF_FC_MOREFRAG, 0x0400) +IEEE16(WF_FC_RETRY, 0x0800) +/* Indicates PS mode in which STA will be after successful completion +** of current frame exchange sequence. Always 0 for AP frames */ +IEEE16(WF_FC_PWRMGT, 0x1000) +/* What MoreData=1 means: +** From AP to STA in PS mode: don't sleep yet, I have more frames for you +** From Contention-Free (CF) Pollable STA in response to a CF-Poll: +** STA has buffered frames for transmission in response to next CF-Poll +** Bcast/mcast frames transmitted from AP: +** when additional bcast/mcast frames remain to be transmitted by AP +** during this beacon interval +** In all other cases MoreData=0 */ +IEEE16(WF_FC_MOREDATA, 0x2000) +IEEE16(WF_FC_ISWEP, 0x4000) +IEEE16(WF_FC_ORDER, 0x8000) + +/* Frame Types */ +IEEE16(WF_FTYPE_MGMT, 0x00) +IEEE16(WF_FTYPE_CTL, 0x04) +IEEE16(WF_FTYPE_DATA, 0x08) + +/* Frame subtypes */ +/* Management */ +IEEE16(WF_FSTYPE_ASSOCREQ, 0x00) +IEEE16(WF_FSTYPE_ASSOCRESP, 0x10) +IEEE16(WF_FSTYPE_REASSOCREQ, 0x20) +IEEE16(WF_FSTYPE_REASSOCRESP, 0x30) +IEEE16(WF_FSTYPE_PROBEREQ, 0x40) +IEEE16(WF_FSTYPE_PROBERESP, 0x50) +IEEE16(WF_FSTYPE_BEACON, 0x80) +IEEE16(WF_FSTYPE_ATIM, 0x90) +IEEE16(WF_FSTYPE_DISASSOC, 0xa0) +IEEE16(WF_FSTYPE_AUTHEN, 0xb0) +IEEE16(WF_FSTYPE_DEAUTHEN, 0xc0) + +/* Control */ +IEEE16(WF_FSTYPE_PSPOLL, 0xa0) +IEEE16(WF_FSTYPE_RTS, 0xb0) +IEEE16(WF_FSTYPE_CTS, 0xc0) +IEEE16(WF_FSTYPE_ACK, 0xd0) +IEEE16(WF_FSTYPE_CFEND, 0xe0) +IEEE16(WF_FSTYPE_CFENDCFACK, 0xf0) + +/* Data */ +IEEE16(WF_FSTYPE_DATAONLY, 0x00) +IEEE16(WF_FSTYPE_DATA_CFACK, 0x10) +IEEE16(WF_FSTYPE_DATA_CFPOLL, 0x20) +IEEE16(WF_FSTYPE_DATA_CFACK_CFPOLL, 0x30) +IEEE16(WF_FSTYPE_NULL, 0x40) +IEEE16(WF_FSTYPE_CFACK, 0x50) +IEEE16(WF_FSTYPE_CFPOLL, 0x60) +IEEE16(WF_FSTYPE_CFACK_CFPOLL, 0x70) +}; + + +/*********************************************************************** +** Macros +*/ + +/*--- Duration Macros ----------------------------------------*/ +/* Macros to get/set the bitfields of the Duration Field */ +/* - the duration value is only valid when bit15 is zero */ +/* - the firmware handles these values, so I'm not going */ +/* to use these macros right now. */ +/*------------------------------------------------------------*/ + +/*--- Sequence Control Macros -------------------------------*/ +/* Macros to get/set the bitfields of the Sequence Control */ +/* Field. */ +/*------------------------------------------------------------*/ +#define WLAN_GET_SEQ_FRGNUM(n) ((u16)(n) & 0x000f) +#define WLAN_GET_SEQ_SEQNUM(n) (((u16)(n) & 0xfff0) >> 4) + +/*--- Data ptr macro -----------------------------------------*/ +/* Creates a u8* to the data portion of a frame */ +/* Assumes you're passing in a ptr to the beginning of the hdr*/ +/*------------------------------------------------------------*/ +#define WLAN_HDR_A3_DATAP(p) (((u8*)(p)) + WLAN_HDR_A3_LEN) +#define WLAN_HDR_A4_DATAP(p) (((u8*)(p)) + WLAN_HDR_A4_LEN) + + +/*********************************************************************** +** Types +*/ + +/* 802.11 header type +** +** Note the following: +** a1 *always* is receiver's mac or bcast/mcast +** a2 *always* is transmitter's mac, if a2 exists +** seq: [0:3] frag#, [4:15] seq# - used for dup detection +** (dups from retries have same seq#) */ +typedef struct wlan_hdr { + u16 fc; + u16 dur; + u8 a1[ETH_ALEN]; + u8 a2[ETH_ALEN]; + u8 a3[ETH_ALEN]; + u16 seq; + u8 a4[ETH_ALEN]; +} WLAN_PACKED wlan_hdr_t; + +/* Separate structs for use if frame type is known */ +typedef struct wlan_hdr_a3 { + u16 fc; + u16 dur; + u8 a1[ETH_ALEN]; + u8 a2[ETH_ALEN]; + u8 a3[ETH_ALEN]; + u16 seq; +} WLAN_PACKED wlan_hdr_a3_t; + +typedef struct wlan_hdr_mgmt { + u16 fc; + u16 dur; + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + u8 bssid[ETH_ALEN]; + u16 seq; +} WLAN_PACKED wlan_hdr_mgmt_t; + +#ifdef NOT_NEEDED_YET +typedef struct { /* ad-hoc peer->peer (to/from DS = 0/0) */ + u16 fc; + u16 dur; + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + u8 bssid[ETH_ALEN]; + u16 seq; +} WLAN_PACKED ibss; +typedef struct { /* ap->sta (to/from DS = 0/1) */ + u16 fc; + u16 dur; + u8 da[ETH_ALEN]; + u8 bssid[ETH_ALEN]; + u8 sa[ETH_ALEN]; + u16 seq; +} WLAN_PACKED fromap; +typedef struct { /* sta->ap (to/from DS = 1/0) */ + u16 fc; + u16 dur; + u8 bssid[ETH_ALEN]; + u8 sa[ETH_ALEN]; + u8 da[ETH_ALEN]; + u16 seq; +} WLAN_PACKED toap; +typedef struct { /* wds->wds (to/from DS = 1/1), the only 4addr pkt */ + u16 fc; + u16 dur; + u8 ra[ETH_ALEN]; + u8 ta[ETH_ALEN]; + u8 da[ETH_ALEN]; + u16 seq; + u8 sa[ETH_ALEN]; +} WLAN_PACKED wds; +typedef struct { /* all management packets */ + u16 fc; + u16 dur; + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + u8 bssid[ETH_ALEN]; + u16 seq; +} WLAN_PACKED mgmt; +typedef struct { /* has no body, just a FCS */ + u16 fc; + u16 dur; + u8 ra[ETH_ALEN]; + u8 ta[ETH_ALEN]; +} WLAN_PACKED rts; +typedef struct { /* has no body, just a FCS */ + u16 fc; + u16 dur; + u8 ra[ETH_ALEN]; +} WLAN_PACKED cts; +typedef struct { /* has no body, just a FCS */ + u16 fc; + u16 dur; + u8 ra[ETH_ALEN]; +} WLAN_PACKED ack; +typedef struct { /* has no body, just a FCS */ + u16 fc; + /* NB: this one holds Assoc ID in dur field: */ + u16 aid; + u8 bssid[ETH_ALEN]; + u8 ta[ETH_ALEN]; +} WLAN_PACKED pspoll; +typedef struct { /* has no body, just a FCS */ + u16 fc; + u16 dur; + u8 ra[ETH_ALEN]; + u8 bssid[ETH_ALEN]; +} WLAN_PACKED cfend; +typedef struct { /* has no body, just a FCS */ + u16 fc; + u16 dur; + u8 ra[ETH_ALEN]; + u8 bssid[ETH_ALEN]; +} WLAN_PACKED cfendcfack; +#endif + +/* Prism header emulation (monitor mode) */ +typedef struct wlanitem_u32 { + u32 did; + u16 status; + u16 len; + u32 data; +} WLAN_PACKED wlanitem_u32_t; +#define WLANITEM_STATUS_data_ok 0 +#define WLANITEM_STATUS_no_value 1 +#define WLANITEM_STATUS_invalid_itemname 2 +#define WLANITEM_STATUS_invalid_itemdata 3 +#define WLANITEM_STATUS_missing_itemdata 4 +#define WLANITEM_STATUS_incomplete_itemdata 5 +#define WLANITEM_STATUS_invalid_msg_did 6 +#define WLANITEM_STATUS_invalid_mib_did 7 +#define WLANITEM_STATUS_missing_conv_func 8 +#define WLANITEM_STATUS_string_too_long 9 +#define WLANITEM_STATUS_data_out_of_range 10 +#define WLANITEM_STATUS_string_too_short 11 +#define WLANITEM_STATUS_missing_valid_func 12 +#define WLANITEM_STATUS_unknown 13 +#define WLANITEM_STATUS_invalid_did 14 +#define WLANITEM_STATUS_missing_print_func 15 + +#define WLAN_DEVNAMELEN_MAX 16 +typedef struct wlansniffrm { + u32 msgcode; + u32 msglen; + u8 devname[WLAN_DEVNAMELEN_MAX]; + wlanitem_u32_t hosttime; + wlanitem_u32_t mactime; + wlanitem_u32_t channel; + wlanitem_u32_t rssi; + wlanitem_u32_t sq; + wlanitem_u32_t signal; + wlanitem_u32_t noise; + wlanitem_u32_t rate; + wlanitem_u32_t istx; /* tx? 0:no 1:yes */ + wlanitem_u32_t frmlen; +} WLAN_PACKED wlansniffrm_t; +#define WLANSNIFFFRM 0x0041 +#define WLANSNIFFFRM_hosttime 0x1041 +#define WLANSNIFFFRM_mactime 0x2041 +#define WLANSNIFFFRM_channel 0x3041 +#define WLANSNIFFFRM_rssi 0x4041 +#define WLANSNIFFFRM_sq 0x5041 +#define WLANSNIFFFRM_signal 0x6041 +#define WLANSNIFFFRM_noise 0x7041 +#define WLANSNIFFFRM_rate 0x8041 +#define WLANSNIFFFRM_istx 0x9041 +#define WLANSNIFFFRM_frmlen 0xA041 --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/usb.c +++ linux-2.6.28/ubuntu/misc/wireless/acx/usb.c @@ -0,0 +1,1725 @@ +/*********************************************************************** +** Copyright (C) 2003 ACX100 Open Source Project +** +** The contents of this file are subject to the Mozilla Public +** License Version 1.1 (the "License"); you may not use this file +** except in compliance with the License. You may obtain a copy of +** the License at http://www.mozilla.org/MPL/ +** +** Software distributed under the License is distributed on an "AS +** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +** implied. See the License for the specific language governing +** rights and limitations under the License. +** +** Alternatively, the contents of this file may be used under the +** terms of the GNU Public License version 2 (the "GPL"), in which +** case the provisions of the GPL are applicable instead of the +** above. If you wish to allow the use of your version of this file +** only under the terms of the GPL and not to allow others to use +** your version of this file under the MPL, indicate your decision +** by deleting the provisions above and replace them with the notice +** and other provisions required by the GPL. If you do not delete +** the provisions above, a recipient may use your version of this +** file under either the MPL or the GPL. +** --------------------------------------------------------------------- +** Inquiries regarding the ACX100 Open Source Project can be +** made directly to: +** +** acx100-users@lists.sf.net +** http://acx100.sf.net +** --------------------------------------------------------------------- +*/ + +/*********************************************************************** +** USB support for TI ACX100 based devices. Many parts are taken from +** the PCI driver. +** +** Authors: +** Martin Wawro +** Andreas Mohr +** +** LOCKING +** callback functions called by USB core are running in interrupt context +** and thus have names with _i_. +*/ +#define ACX_USB 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "acx.h" + + +/*********************************************************************** +*/ +/* number of endpoints of an interface */ +#define NUM_EP(intf) (intf)->altsetting[0].desc.bNumEndpoints +#define EP(intf, nr) (intf)->altsetting[0].endpoint[(nr)].desc +#define GET_DEV(udev) usb_get_dev((udev)) +#define PUT_DEV(udev) usb_put_dev((udev)) +#define SET_NETDEV_OWNER(ndev, owner) /* not needed anymore ??? */ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14) +/* removed in 2.6.14. We will use fake value for now */ +#define URB_ASYNC_UNLINK 0 +#endif + + +/*********************************************************************** +*/ +/* ACX100 (TNETW1100) USB device: D-Link DWL-120+ */ +#define ACX100_VENDOR_ID 0x2001 +#define ACX100_PRODUCT_ID_UNBOOTED 0x3B01 +#define ACX100_PRODUCT_ID_BOOTED 0x3B00 + +/* TNETW1450 USB devices */ +#define VENDOR_ID_DLINK 0x07b8 /* D-Link Corp. */ +#define PRODUCT_ID_WUG2400 0xb21a /* AboCom WUG2400 or SafeCom SWLUT-54125 */ +#define VENDOR_ID_AVM_GMBH 0x057c +#define PRODUCT_ID_AVM_WLAN_USB 0x5601 +#define PRODUCT_ID_AVM_WLAN_USB_si 0x6201 /* "self install" named Version: driver kills kernel on inbound scans from fritz box ??? */ +#define VENDOR_ID_ZCOM 0x0cde +#define PRODUCT_ID_ZCOM_XG750 0x0017 /* not tested yet */ +#define VENDOR_ID_TI 0x0451 +#define PRODUCT_ID_TI_UNKNOWN 0x60c5 /* not tested yet */ + +#define ACX_USB_CTRL_TIMEOUT 5500 /* steps in ms */ + +/* Buffer size for fw upload, same for both ACX100 USB and TNETW1450 */ +#define ACX_USB_RWMEM_MAXLEN 2048 + +/* The number of bulk URBs to use */ +#define ACX_TX_URB_CNT 8 +#define ACX_RX_URB_CNT 2 + +/* Should be sent to the bulkout endpoint */ +#define ACX_USB_REQ_UPLOAD_FW 0x10 +#define ACX_USB_REQ_ACK_CS 0x11 +#define ACX_USB_REQ_CMD 0x12 + +/*********************************************************************** +** Prototypes +*/ +static int acxusb_e_probe(struct usb_interface *, const struct usb_device_id *); +static void acxusb_e_disconnect(struct usb_interface *); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) +static void acxusb_i_complete_tx(struct urb *); +static void acxusb_i_complete_rx(struct urb *); +#else +static void acxusb_i_complete_tx(struct urb *, struct pt_regs *); +static void acxusb_i_complete_rx(struct urb *, struct pt_regs *); +#endif +static int acxusb_e_open(struct net_device *); +static int acxusb_e_close(struct net_device *); +static void acxusb_i_set_rx_mode(struct net_device *); +static int acxusb_boot(struct usb_device *); + +static void acxusb_l_poll_rx(acx_device_t *adev, usb_rx_t* rx); + +static void acxusb_i_tx_timeout(struct net_device *); + +/* static void dump_device(struct usb_device *); */ +/* static void dump_device_descriptor(struct usb_device_descriptor *); */ +/* static void dump_config_descriptor(struct usb_config_descriptor *); */ + +/*********************************************************************** +** Module Data +*/ +#define TXBUFSIZE sizeof(usb_txbuffer_t) +/* + * Now, this is just plain lying, but the device insists in giving us + * huge packets. We supply extra space after rxbuffer. Need to understand + * it better... + */ +#define RXBUFSIZE (sizeof(rxbuffer_t) + \ + (sizeof(usb_rx_t) - sizeof(struct usb_rx_plain))) + +static const struct usb_device_id +acxusb_ids[] = { + { USB_DEVICE(ACX100_VENDOR_ID, ACX100_PRODUCT_ID_BOOTED) }, + { USB_DEVICE(ACX100_VENDOR_ID, ACX100_PRODUCT_ID_UNBOOTED) }, + {} +}; +MODULE_DEVICE_TABLE(usb, acxusb_ids); + +/* USB driver data structure as required by the kernel's USB core */ +static struct usb_driver +acxusb_driver = { + .name = "acx_usb", + .probe = acxusb_e_probe, + .disconnect = acxusb_e_disconnect, + .id_table = acxusb_ids +}; + + +/*********************************************************************** +** USB helper +** +** ldd3 ch13 says: +** When the function is usb_kill_urb, the urb lifecycle is stopped. This +** function is usually used when the device is disconnected from the system, +** in the disconnect callback. For some drivers, the usb_unlink_urb function +** should be used to tell the USB core to stop an urb. This function does not +** wait for the urb to be fully stopped before returning to the caller. +** This is useful for stoppingthe urb while in an interrupt handler or when +** a spinlock is held, as waiting for a urb to fully stop requires the ability +** for the USB core to put the calling process to sleep. This function requires +** that the URB_ASYNC_UNLINK flag value be set in the urb that is being asked +** to be stopped in order to work properly. +** +** (URB_ASYNC_UNLINK is obsolete, usb_unlink_urb will always be +** asynchronous while usb_kill_urb is synchronous and should be called +** directly (drivers/usb/core/urb.c)) +** +** In light of this, timeout is just for paranoid reasons... +* +* Actually, it's useful for debugging. If we reach timeout, we're doing +* something wrong with the urbs. +*/ +static void +acxusb_unlink_urb(struct urb* urb) +{ + if (!urb) + return; + + if (urb->status == -EINPROGRESS) { + int timeout = 10; + + usb_unlink_urb(urb); + while (--timeout && urb->status == -EINPROGRESS) { + mdelay(1); + } + if (!timeout) { + printk("acx_usb: urb unlink timeout!\n"); + } + } +} + + +/*********************************************************************** +** EEPROM and PHY read/write helpers +*/ +/*********************************************************************** +** acxusb_s_read_phy_reg +*/ +int +acxusb_s_read_phy_reg(acx_device_t *adev, u32 reg, u8 *charbuf) +{ + /* mem_read_write_t mem; */ + + FN_ENTER; + + printk("%s doesn't seem to work yet, disabled.\n", __func__); + + /* + mem.addr = cpu_to_le16(reg); + mem.type = cpu_to_le16(0x82); + mem.len = cpu_to_le32(4); + acx_s_issue_cmd(adev, ACX1xx_CMD_MEM_READ, &mem, sizeof(mem)); + *charbuf = mem.data; + log(L_DEBUG, "read radio PHY[0x%04X]=0x%02X\n", reg, *charbuf); + */ + + FN_EXIT1(OK); + return OK; +} + + +/*********************************************************************** +*/ +int +acxusb_s_write_phy_reg(acx_device_t *adev, u32 reg, u8 value) +{ + mem_read_write_t mem; + + FN_ENTER; + + mem.addr = cpu_to_le16(reg); + mem.type = cpu_to_le16(0x82); + mem.len = cpu_to_le32(4); + mem.data = value; + acx_s_issue_cmd(adev, ACX1xx_CMD_MEM_WRITE, &mem, sizeof(mem)); + log(L_DEBUG, "write radio PHY[0x%04X]=0x%02X\n", reg, value); + + FN_EXIT1(OK); + return OK; +} + + +/*********************************************************************** +** acxusb_s_issue_cmd_timeo +** Excecutes a command in the command mailbox +** +** buffer = a pointer to the data. +** The data must not include 4 byte command header +*/ + +/* TODO: ideally we shall always know how much we need +** and this shall be 0 */ +#define BOGUS_SAFETY_PADDING 0x40 + +#undef FUNC +#define FUNC "issue_cmd" + +#if !ACX_DEBUG +int +acxusb_s_issue_cmd_timeo( + acx_device_t *adev, + unsigned cmd, + void *buffer, + unsigned buflen, + unsigned timeout) +{ +#else +int +acxusb_s_issue_cmd_timeo_debug( + acx_device_t *adev, + unsigned cmd, + void *buffer, + unsigned buflen, + unsigned timeout, + const char* cmdstr) +{ +#endif + /* USB ignores timeout param */ + + struct usb_device *usbdev; + struct { + u16 cmd; + u16 status; + u8 data[1]; + } ACX_PACKED *loc; + const char *devname; + int acklen, blocklen, inpipe, outpipe; + int cmd_status; + int result; + + FN_ENTER; + + devname = adev->ndev->name; + /* no "wlan%%d: ..." please */ + if (!devname || !devname[0] || devname[4]=='%') + devname = "acx"; + + log(L_CTL, FUNC"(cmd:%s,buflen:%u,type:0x%04X)\n", + cmdstr, buflen, + buffer ? le16_to_cpu(((acx_ie_generic_t *)buffer)->type) : -1); + + loc = kmalloc(buflen + 4 + BOGUS_SAFETY_PADDING, GFP_KERNEL); + if (!loc) { + printk("%s: "FUNC"(): no memory for data buffer\n", devname); + goto bad; + } + + /* get context from acx_device */ + usbdev = adev->usbdev; + + /* check which kind of command was issued */ + loc->cmd = cpu_to_le16(cmd); + loc->status = 0; + +/* NB: buflen == frmlen + 4 +** +** Interrogate: write 8 bytes: (cmd,status,rid,frmlen), then +** read (cmd,status,rid,frmlen,data[frmlen]) back +** +** Configure: write (cmd,status,rid,frmlen,data[frmlen]) +** +** Possibly bogus special handling of ACX1xx_IE_SCAN_STATUS removed +*/ + + /* now write the parameters of the command if needed */ + acklen = buflen + 4 + BOGUS_SAFETY_PADDING; + blocklen = buflen; + if (buffer && buflen) { + /* if it's an INTERROGATE command, just pass the length + * of parameters to read, as data */ + if (cmd == ACX1xx_CMD_INTERROGATE) { + blocklen = 4; + acklen = buflen + 4; + } + memcpy(loc->data, buffer, blocklen); + } + blocklen += 4; /* account for cmd,status */ + + /* obtain the I/O pipes */ + outpipe = usb_sndctrlpipe(usbdev, 0); + inpipe = usb_rcvctrlpipe(usbdev, 0); + log(L_CTL, "ctrl inpipe=0x%X outpipe=0x%X\n", inpipe, outpipe); + log(L_CTL, "sending USB control msg (out) (blocklen=%d)\n", blocklen); + if (acx_debug & L_DATA) + acx_dump_bytes(loc, blocklen); + + result = usb_control_msg(usbdev, outpipe, + ACX_USB_REQ_CMD, /* request */ + USB_TYPE_VENDOR|USB_DIR_OUT, /* requesttype */ + 0, /* value */ + 0, /* index */ + loc, /* dataptr */ + blocklen, /* size */ + ACX_USB_CTRL_TIMEOUT /* timeout in ms */ + ); + + if (result == -ENODEV) { + log(L_CTL, "no device present (unplug?)\n"); + goto good; + } + + log(L_CTL, "wrote %d bytes\n", result); + if (result < 0) { + goto bad; + } + + /* check for device acknowledge */ + log(L_CTL, "sending USB control msg (in) (acklen=%d)\n", acklen); + loc->status = 0; /* delete old status flag -> set to IDLE */ + /* shall we zero out the rest? */ + result = usb_control_msg(usbdev, inpipe, + ACX_USB_REQ_CMD, /* request */ + USB_TYPE_VENDOR|USB_DIR_IN, /* requesttype */ + 0, /* value */ + 0, /* index */ + loc, /* dataptr */ + acklen, /* size */ + ACX_USB_CTRL_TIMEOUT /* timeout in ms */ + ); + if (result < 0) { + printk("%s: "FUNC"(): USB read error %d\n", devname, result); + goto bad; + } + if (acx_debug & L_CTL) { + printk("read %d bytes: ", result); + acx_dump_bytes(loc, result); + } + +/* + check for result==buflen+4? Was seen: + +interrogate(type:ACX100_IE_DOT11_ED_THRESHOLD,len:4) +issue_cmd(cmd:ACX1xx_CMD_INTERROGATE,buflen:8,type:4111) +ctrl inpipe=0x80000280 outpipe=0x80000200 +sending USB control msg (out) (blocklen=8) +01 00 00 00 0F 10 04 00 +wrote 8 bytes +sending USB control msg (in) (acklen=12) sizeof(loc->data +read 4 bytes <==== MUST BE 12!! +*/ + + cmd_status = le16_to_cpu(loc->status); + if (cmd_status != 1) { + printk("%s: "FUNC"(): cmd_status is not SUCCESS: %d (%s)\n", + devname, cmd_status, acx_cmd_status_str(cmd_status)); + /* TODO: goto bad; ? */ + } + if ((cmd == ACX1xx_CMD_INTERROGATE) && buffer && buflen) { + memcpy(buffer, loc->data, buflen); + log(L_CTL, "response frame: cmd=0x%04X status=%d\n", + le16_to_cpu(loc->cmd), + cmd_status); + } +good: + kfree(loc); + FN_EXIT1(OK); + return OK; +bad: + /* Give enough info so that callers can avoid + ** printing their own diagnostic messages */ +#if ACX_DEBUG + printk("%s: "FUNC"(cmd:%s) FAILED\n", devname, cmdstr); +#else + printk("%s: "FUNC"(cmd:0x%04X) FAILED\n", devname, cmd); +#endif + dump_stack(); + kfree(loc); + FN_EXIT1(NOT_OK); + return NOT_OK; +} + + +/*********************************************************************** +** acxusb_boot() +** Inputs: +** usbdev -> Pointer to kernel's usb_device structure +** +** Returns: +** (int) Errorcode or 0 on success +** +** This function triggers the loading of the firmware image from harddisk +** and then uploads the firmware to the USB device. After uploading the +** firmware and transmitting the checksum, the device resets and appears +** as a new device on the USB bus (the device we can finally deal with) +*/ +static int +acxusb_boot(struct usb_device *usbdev) +{ + char filename[256]; + char *firmware = NULL; + char *usbbuf; + unsigned int offset; + unsigned int len, inpipe, outpipe; + u32 checksum; + u32 size; + int result; + + FN_ENTER; + + usbbuf = kmalloc(ACX_USB_RWMEM_MAXLEN, GFP_KERNEL); + if (!usbbuf) { + printk(KERN_ERR "acx: no memory for USB transfer buffer (" + STRING(ACX_USB_RWMEM_MAXLEN)" bytes)\n"); + result = -ENOMEM; + goto end; + } + + snprintf(filename, sizeof(filename), "acx/%s/tiacx100usb", firmware_ver); + firmware = (char *)acx_s_read_fw(&usbdev->dev, filename, &size); + if (!firmware) { + result = -EIO; + goto end; + } + log(L_INIT, "firmware size: %d bytes\n", size); + + /* Obtain the I/O pipes */ + outpipe = usb_sndctrlpipe(usbdev, 0); + inpipe = usb_rcvctrlpipe(usbdev, 0); + + /* now upload the firmware, slice the data into blocks */ + offset = 8; + while (offset < size) { + len = size - offset; + if (len >= ACX_USB_RWMEM_MAXLEN) { + len = ACX_USB_RWMEM_MAXLEN; + } + log(L_INIT, "uploading firmware (%d bytes, offset=%d)\n", + len, offset); + result = 0; + memcpy(usbbuf, firmware + offset, len); + result = usb_control_msg(usbdev, outpipe, + ACX_USB_REQ_UPLOAD_FW, + USB_TYPE_VENDOR|USB_DIR_OUT, + size - 8, /* value */ + 0, /* index */ + usbbuf, /* dataptr */ + len, /* size */ + 3000 /* timeout in ms */ + ); + offset += len; + if (result < 0) { + printk(KERN_ERR "acx: error %d during upload " + "of firmware, aborting\n", result); + goto end; + } + } + + /* finally, send the checksum and reboot the device */ + /* does this trigger the reboot? */ + checksum = le32_to_cpu(*(u32 *)firmware); + result = usb_control_msg(usbdev, outpipe, + ACX_USB_REQ_UPLOAD_FW, + USB_TYPE_VENDOR|USB_DIR_OUT, + checksum & 0xffff, /* value */ + checksum >> 16, /* index */ + NULL, /* dataptr */ + 0, /* size */ + 3000 /* timeout in ms */ + ); + if (result < 0) { + printk(KERN_ERR "acx: error %d during tx of checksum, " + "aborting\n", result); + goto end; + } + result = usb_control_msg(usbdev, inpipe, + ACX_USB_REQ_ACK_CS, + USB_TYPE_VENDOR|USB_DIR_IN, + checksum & 0xffff, /* value */ + checksum >> 16, /* index */ + usbbuf, /* dataptr */ + 8, /* size */ + 3000 /* timeout in ms */ + ); + if (result < 0) { + printk(KERN_ERR "acx: error %d during ACK of checksum, " + "aborting\n", result); + goto end; + } + if (*usbbuf != 0x10) { + kfree(usbbuf); + printk(KERN_ERR "acx: invalid checksum?\n"); + result = -EINVAL; + goto end; + } + result = 0; + +end: + vfree(firmware); + kfree(usbbuf); + + FN_EXIT1(result); + return result; +} + + +/* FIXME: maybe merge it with usual eeprom reading, into common code? */ +static void +acxusb_s_read_eeprom_version(acx_device_t *adev) +{ + u8 eeprom_ver[0x8]; + + memset(eeprom_ver, 0, sizeof(eeprom_ver)); + acx_s_interrogate(adev, &eeprom_ver, ACX1FF_IE_EEPROM_VER); + + /* FIXME: which one of those values to take? */ + adev->eeprom_version = eeprom_ver[5]; +} + + +/* + * temporary helper function to at least fill important cfgopt members with + * useful replacement values until we figure out how one manages to fetch + * the configoption struct in the USB device case... + */ +static int +acxusb_s_fill_configoption(acx_device_t *adev) +{ + adev->cfgopt_probe_delay = 200; + adev->cfgopt_dot11CCAModes = 4; + adev->cfgopt_dot11Diversity = 1; + adev->cfgopt_dot11ShortPreambleOption = 1; + adev->cfgopt_dot11PBCCOption = 1; + adev->cfgopt_dot11ChannelAgility = 0; + adev->cfgopt_dot11PhyType = 5; + adev->cfgopt_dot11TempType = 1; + return OK; +} + + +/*********************************************************************** +** acxusb_e_probe() +** +** This function is invoked by the kernel's USB core whenever a new device is +** attached to the system or the module is loaded. It is presented a usb_device +** structure from which information regarding the device is obtained and evaluated. +** In case this driver is able to handle one of the offered devices, it returns +** a non-null pointer to a driver context and thereby claims the device. +*/ + +static void +dummy_netdev_init(struct net_device *ndev) {} + +static int +acxusb_e_probe(struct usb_interface *intf, const struct usb_device_id *devID) +{ + struct usb_device *usbdev = interface_to_usbdev(intf); + acx_device_t *adev = NULL; + struct net_device *ndev = NULL; + struct usb_config_descriptor *config; + struct usb_endpoint_descriptor *epdesc; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) + struct usb_host_endpoint *ep; +#endif + struct usb_interface_descriptor *ifdesc; + const char* msg; + int numconfigs, numfaces, numep; + int result = OK; + int i; + + FN_ENTER; + + /* First check if this is the "unbooted" hardware */ + if ((usbdev->descriptor.idVendor == ACX100_VENDOR_ID) + && (usbdev->descriptor.idProduct == ACX100_PRODUCT_ID_UNBOOTED)) { + /* Boot the device (i.e. upload the firmware) */ + acxusb_boot(usbdev); + + /* OK, we are done with booting. Normally, the + ** ID for the unbooted device should disappear + ** and it will not need a driver anyway...so + ** return a NULL + */ + log(L_INIT, "finished booting, returning from probe()\n"); + result = OK; /* success */ + goto end; + } + + if ((usbdev->descriptor.idVendor != ACX100_VENDOR_ID) + || (usbdev->descriptor.idProduct != ACX100_PRODUCT_ID_BOOTED)) { + goto end_nodev; + } + +/* Ok, so it's our device and it has already booted */ + + /* Allocate memory for a network device */ + + ndev = alloc_netdev(sizeof(*adev), "wlan%d", dummy_netdev_init); + /* (NB: memsets to 0 entire area) */ + if (!ndev) { + msg = "acx: no memory for netdev\n"; + goto end_nomem; + } + + /* Register the callbacks for the network device functions */ + + ether_setup(ndev); + ndev->open = &acxusb_e_open; + ndev->stop = &acxusb_e_close; + ndev->hard_start_xmit = (void *)&acx_i_start_xmit; + ndev->get_stats = (void *)&acx_e_get_stats; + ndev->set_multicast_list = (void *)&acxusb_i_set_rx_mode; +#ifdef HAVE_TX_TIMEOUT + ndev->tx_timeout = &acxusb_i_tx_timeout; + ndev->watchdog_timeo = 4 * HZ; +#endif + ndev->change_mtu = &acx_e_change_mtu; + + /* Setup private driver context */ + + adev = netdev_priv(ndev); + adev->ndev = ndev; + + adev->dev_type = DEVTYPE_USB; + adev->chip_type = CHIPTYPE_ACX100; + + /* FIXME: should be read from register (via firmware) using standard ACX code */ + adev->radio_type = RADIO_MAXIM_0D; + + adev->usbdev = usbdev; + spin_lock_init(&adev->lock); /* initial state: unlocked */ + sema_init(&adev->sem, 1); /* initial state: 1 (upped) */ + + /* Check that this is really the hardware we know about. + ** If not sure, at least notify the user that he + ** may be in trouble... + */ + numconfigs = (int)usbdev->descriptor.bNumConfigurations; + if (numconfigs != 1) + printk("acx: number of configurations is %d, " + "this driver only knows how to handle 1, " + "be prepared for surprises\n", numconfigs); + + config = &usbdev->config->desc; + numfaces = config->bNumInterfaces; + if (numfaces != 1) + printk("acx: number of interfaces is %d, " + "this driver only knows how to handle 1, " + "be prepared for surprises\n", numfaces); + + ifdesc = &intf->altsetting->desc; + numep = ifdesc->bNumEndpoints; + log(L_DEBUG, "# of endpoints: %d\n", numep); + + /* obtain information about the endpoint + ** addresses, begin with some default values + */ + adev->bulkoutep = 1; + adev->bulkinep = 1; + for (i = 0; i < numep; i++) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) + ep = usbdev->ep_in[i]; + if (!ep) + continue; + epdesc = &ep->desc; +#else + epdesc = usb_epnum_to_ep_desc(usbdev, i); + if (!epdesc) + continue; +#endif + if (epdesc->bmAttributes & USB_ENDPOINT_XFER_BULK) { + if (epdesc->bEndpointAddress & 0x80) + adev->bulkinep = epdesc->bEndpointAddress & 0xF; + else + adev->bulkoutep = epdesc->bEndpointAddress & 0xF; + } + } + log(L_DEBUG, "bulkout ep: 0x%X\n", adev->bulkoutep); + log(L_DEBUG, "bulkin ep: 0x%X\n", adev->bulkinep); + + /* already done by memset: adev->rxtruncsize = 0; */ + log(L_DEBUG, "TXBUFSIZE=%d RXBUFSIZE=%d\n", + (int) TXBUFSIZE, (int) RXBUFSIZE); + + /* Allocate the RX/TX containers. */ + adev->usb_tx = kmalloc(sizeof(usb_tx_t) * ACX_TX_URB_CNT, GFP_KERNEL); + if (!adev->usb_tx) { + msg = "acx: no memory for tx container"; + goto end_nomem; + } + adev->usb_rx = kmalloc(sizeof(usb_rx_t) * ACX_RX_URB_CNT, GFP_KERNEL); + if (!adev->usb_rx) { + msg = "acx: no memory for rx container"; + goto end_nomem; + } + + /* Setup URBs for bulk-in/out messages */ + for (i = 0; i < ACX_RX_URB_CNT; i++) { + adev->usb_rx[i].urb = usb_alloc_urb(0, GFP_KERNEL); + if (!adev->usb_rx[i].urb) { + msg = "acx: no memory for input URB\n"; + goto end_nomem; + } + adev->usb_rx[i].urb->status = 0; + adev->usb_rx[i].adev = adev; + adev->usb_rx[i].busy = 0; + } + + for (i = 0; i< ACX_TX_URB_CNT; i++) { + adev->usb_tx[i].urb = usb_alloc_urb(0, GFP_KERNEL); + if (!adev->usb_tx[i].urb) { + msg = "acx: no memory for output URB\n"; + goto end_nomem; + } + adev->usb_tx[i].urb->status = 0; + adev->usb_tx[i].adev = adev; + adev->usb_tx[i].busy = 0; + } + adev->tx_free = ACX_TX_URB_CNT; + + usb_set_intfdata(intf, adev); + SET_NETDEV_DEV(ndev, &intf->dev); + + /* TODO: move all of fw cmds to open()? But then we won't know our MAC addr + until ifup (it's available via reading ACX1xx_IE_DOT11_STATION_ID)... */ + + /* put acx out of sleep mode and initialize it */ + acx_s_issue_cmd(adev, ACX1xx_CMD_WAKE, NULL, 0); + + result = acx_s_init_mac(adev); + if (result) + goto end; + + /* TODO: see similar code in pci.c */ + acxusb_s_read_eeprom_version(adev); + acxusb_s_fill_configoption(adev); + acx_s_set_defaults(adev); + acx_s_get_firmware_version(adev); + acx_display_hardware_details(adev); + + /* Register the network device */ + log(L_INIT, "registering network device\n"); + result = register_netdev(ndev); + if (result) { + msg = "acx: failed to register USB network device " + "(error %d)\n"; + goto end_nomem; + } + + acx_proc_register_entries(ndev); + + acx_stop_queue(ndev, "on probe"); + acx_carrier_off(ndev, "on probe"); + + printk("acx: USB module " ACX_RELEASE " loaded successfully\n"); + +#if CMD_DISCOVERY + great_inquisitor(adev); +#endif + + /* Everything went OK, we are happy now */ + result = OK; + goto end; + +end_nomem: + printk(msg, result); + + if (ndev) { + if (adev->usb_rx) { + for (i = 0; i < ACX_RX_URB_CNT; i++) + usb_free_urb(adev->usb_rx[i].urb); + kfree(adev->usb_rx); + } + if (adev->usb_tx) { + for (i = 0; i < ACX_TX_URB_CNT; i++) + usb_free_urb(adev->usb_tx[i].urb); + kfree(adev->usb_tx); + } + free_netdev(ndev); + } + + result = -ENOMEM; + goto end; + +end_nodev: + /* no device we could handle, return error. */ + result = -EIO; + +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acxusb_e_disconnect() +** +** This function is invoked whenever the user pulls the plug from the USB +** device or the module is removed from the kernel. In these cases, the +** network devices have to be taken down and all allocated memory has +** to be freed. +*/ +static void +acxusb_e_disconnect(struct usb_interface *intf) +{ + acx_device_t *adev = usb_get_intfdata(intf); + unsigned long flags; + int i; + + FN_ENTER; + + /* No WLAN device... no sense */ + if (!adev) + goto end; + + /* Unregister network device + * + * If the interface is up, unregister_netdev() will take + * care of calling our close() function, which takes + * care of unlinking the urbs, sending the device to + * sleep, etc... + * This can't be called with sem or lock held because + * _close() will try to grab it as well if it's called, + * deadlocking the machine. + */ + unregister_netdev(adev->ndev); + + acx_sem_lock(adev); + acx_lock(adev, flags); + /* This device exists no more */ + usb_set_intfdata(intf, NULL); + acx_proc_unregister_entries(adev->ndev); + + /* + * Here we only free them. _close() took care of + * unlinking them. + */ + for (i = 0; i < ACX_RX_URB_CNT; ++i) { + usb_free_urb(adev->usb_rx[i].urb); + } + for (i = 0; i< ACX_TX_URB_CNT; ++i) { + usb_free_urb(adev->usb_tx[i].urb); + } + + /* Freeing containers */ + kfree(adev->usb_rx); + kfree(adev->usb_tx); + + acx_unlock(adev, flags); + acx_sem_unlock(adev); + + free_netdev(adev->ndev); +end: + FN_EXIT0; +} + + +/*********************************************************************** +** acxusb_e_open() +** This function is called when the user sets up the network interface. +** It initializes a management timer, sets up the USB card and starts +** the network tx queue and USB receive. +*/ +static int +acxusb_e_open(struct net_device *ndev) +{ + acx_device_t *adev = ndev2adev(ndev); + unsigned long flags; + int i; + + FN_ENTER; + + acx_sem_lock(adev); + + /* put the ACX100 out of sleep mode */ + acx_s_issue_cmd(adev, ACX1xx_CMD_WAKE, NULL, 0); + + acx_init_task_scheduler(adev); + + init_timer(&adev->mgmt_timer); + adev->mgmt_timer.function = acx_i_timer; + adev->mgmt_timer.data = (unsigned long)adev; + + /* acx_s_start needs it */ + SET_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP); + acx_s_start(adev); + + /* don't acx_start_queue() here, we need to associate first */ + + acx_lock(adev, flags); + for (i = 0; i < ACX_RX_URB_CNT; i++) { + adev->usb_rx[i].urb->status = 0; + } + + acxusb_l_poll_rx(adev, &adev->usb_rx[0]); + + acx_unlock(adev, flags); + + acx_sem_unlock(adev); + + FN_EXIT0; + return 0; +} + + +/*********************************************************************** +** acxusb_e_close() +** +** This function stops the network functionality of the interface (invoked +** when the user calls ifconfig down). The tx queue is halted and +** the device is marked as down. In case there were any pending USB bulk +** transfers, these are unlinked (asynchronously). The module in-use count +** is also decreased in this function. +*/ +static int +acxusb_e_close(struct net_device *ndev) +{ + acx_device_t *adev = ndev2adev(ndev); + unsigned long flags; + int i; + + FN_ENTER; + +#ifdef WE_STILL_DONT_CARE_ABOUT_IT + /* Transmit a disassociate frame */ + lock + acx_l_transmit_disassoc(adev, &client); + unlock +#endif + + acx_sem_lock(adev); + + CLEAR_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP); + +/* Code below is remarkably similar to acxpci_s_down(). Maybe we can merge them? */ + + /* Make sure we don't get any more rx requests */ + acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0); + acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0); + + /* + * We must do FLUSH *without* holding sem to avoid a deadlock. + * See pci.c:acxpci_s_down() for deails. + */ + acx_sem_unlock(adev); + FLUSH_SCHEDULED_WORK(); + acx_sem_lock(adev); + + /* Power down the device */ + acx_s_issue_cmd(adev, ACX1xx_CMD_SLEEP, NULL, 0); + + /* Stop the transmit queue, mark the device as DOWN */ + acx_lock(adev, flags); + acx_stop_queue(ndev, "on ifdown"); + acx_set_status(adev, ACX_STATUS_0_STOPPED); + /* stop pending rx/tx urb transfers */ + for (i = 0; i < ACX_TX_URB_CNT; i++) { + acxusb_unlink_urb(adev->usb_tx[i].urb); + adev->usb_tx[i].busy = 0; + } + for (i = 0; i < ACX_RX_URB_CNT; i++) { + acxusb_unlink_urb(adev->usb_rx[i].urb); + adev->usb_rx[i].busy = 0; + } + adev->tx_free = ACX_TX_URB_CNT; + acx_unlock(adev, flags); + + /* Must do this outside of lock */ + del_timer_sync(&adev->mgmt_timer); + + acx_sem_unlock(adev); + + FN_EXIT0; + return 0; +} + + +/*********************************************************************** +** acxusb_l_poll_rx +** This function (re)initiates a bulk-in USB transfer on a given urb +*/ +static void +acxusb_l_poll_rx(acx_device_t *adev, usb_rx_t* rx) +{ + struct usb_device *usbdev; + struct urb *rxurb; + int errcode, rxnum; + unsigned int inpipe; + + FN_ENTER; + + rxurb = rx->urb; + usbdev = adev->usbdev; + + rxnum = rx - adev->usb_rx; + + inpipe = usb_rcvbulkpipe(usbdev, adev->bulkinep); + if (unlikely(rxurb->status == -EINPROGRESS)) { + printk(KERN_ERR "acx: error, rx triggered while rx urb in progress\n"); + /* FIXME: this is nasty, receive is being cancelled by this code + * on the other hand, this should not happen anyway... + */ + usb_unlink_urb(rxurb); + } else + if (unlikely(rxurb->status == -ECONNRESET)) { + log(L_USBRXTX, "acx_usb: _poll_rx: connection reset\n"); + goto end; + } + rxurb->actual_length = 0; + usb_fill_bulk_urb(rxurb, usbdev, inpipe, + &rx->bulkin, /* dataptr */ + RXBUFSIZE, /* size */ + acxusb_i_complete_rx, /* handler */ + rx /* handler param */ + ); + rxurb->transfer_flags = URB_ASYNC_UNLINK; + + /* ATOMIC: we may be called from complete_rx() usb callback */ + errcode = usb_submit_urb(rxurb, GFP_ATOMIC); + /* FIXME: evaluate the error code! */ + log(L_USBRXTX, "SUBMIT RX (%d) inpipe=0x%X size=%d errcode=%d\n", + rxnum, inpipe, (int) RXBUFSIZE, errcode); +end: + FN_EXIT0; +} + + +/*********************************************************************** +** acxusb_i_complete_rx() +** Inputs: +** urb -> pointer to USB request block +** regs -> pointer to register-buffer for syscalls (see asm/ptrace.h) +** +** This function is invoked by USB subsystem whenever a bulk receive +** request returns. +** The received data is then committed to the network stack and the next +** USB receive is triggered. +*/ +static void +acxusb_i_complete_rx(struct urb *urb) +{ + acx_device_t *adev; + rxbuffer_t *ptr; + rxbuffer_t *inbuf; + usb_rx_t *rx; + unsigned long flags; + int size, remsize, packetsize, rxnum; + + FN_ENTER; + + BUG_ON(!urb->context); + + rx = (usb_rx_t *)urb->context; + adev = rx->adev; + + acx_lock(adev, flags); + + /* + * Happens on disconnect or close. Don't play with the urb. + * Don't resubmit it. It will get unlinked by close() + */ + if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) { + log(L_USBRXTX, "rx: device is down, not doing anything\n"); + goto end_unlock; + } + + inbuf = &rx->bulkin; + size = urb->actual_length; + remsize = size; + rxnum = rx - adev->usb_rx; + + log(L_USBRXTX, "RETURN RX (%d) status=%d size=%d\n", + rxnum, urb->status, size); + + /* Send the URB that's waiting. */ + log(L_USBRXTX, "rxnum=%d, sending=%d\n", rxnum, rxnum^1); + acxusb_l_poll_rx(adev, &adev->usb_rx[rxnum^1]); + + if (unlikely(size > sizeof(rxbuffer_t))) + printk("acx_usb: rx too large: %d, please report\n", size); + + /* check if the transfer was aborted */ + switch (urb->status) { + case 0: /* No error */ + break; + case -EOVERFLOW: + printk(KERN_ERR "acx: rx data overrun\n"); + adev->rxtruncsize = 0; /* Not valid anymore. */ + goto end_unlock; + case -ECONNRESET: + adev->rxtruncsize = 0; + goto end_unlock; + case -ESHUTDOWN: /* rmmod */ + adev->rxtruncsize = 0; + goto end_unlock; + default: + adev->rxtruncsize = 0; + adev->stats.rx_errors++; + printk("acx: rx error (urb status=%d)\n", urb->status); + goto end_unlock; + } + + if (unlikely(!size)) + printk("acx: warning, encountered zerolength rx packet\n"); + + if (urb->transfer_buffer != inbuf) + goto end_unlock; + + /* check if previous frame was truncated + ** FIXME: this code can only handle truncation + ** of consecutive packets! + */ + ptr = inbuf; + if (adev->rxtruncsize) { + int tail_size; + + ptr = &adev->rxtruncbuf; + packetsize = RXBUF_BYTES_USED(ptr); + if (acx_debug & L_USBRXTX) { + printk("handling truncated frame (truncsize=%d size=%d " + "packetsize(from trunc)=%d)\n", + adev->rxtruncsize, size, packetsize); + acx_dump_bytes(ptr, RXBUF_HDRSIZE); + acx_dump_bytes(inbuf, RXBUF_HDRSIZE); + } + + /* bytes needed for rxtruncbuf completion: */ + tail_size = packetsize - adev->rxtruncsize; + + if (size < tail_size) { + /* there is not enough data to complete this packet, + ** simply append the stuff to the truncation buffer + */ + memcpy(((char *)ptr) + adev->rxtruncsize, inbuf, size); + adev->rxtruncsize += size; + remsize = 0; + } else { + /* ok, this data completes the previously + ** truncated packet. copy it into a descriptor + ** and give it to the rest of the stack */ + + /* append tail to previously truncated part + ** NB: adev->rxtruncbuf (pointed to by ptr) can't + ** overflow because this is already checked before + ** truncation buffer was filled. See below, + ** "if (packetsize > sizeof(rxbuffer_t))..." code */ + memcpy(((char *)ptr) + adev->rxtruncsize, inbuf, tail_size); + + if (acx_debug & L_USBRXTX) { + printk("full trailing packet + 12 bytes:\n"); + acx_dump_bytes(inbuf, tail_size + RXBUF_HDRSIZE); + } + acx_l_process_rxbuf(adev, ptr); + adev->rxtruncsize = 0; + ptr = (rxbuffer_t *) (((char *)inbuf) + tail_size); + remsize -= tail_size; + } + log(L_USBRXTX, "post-merge size=%d remsize=%d\n", + size, remsize); + } + + /* size = USB data block size + ** remsize = unprocessed USB bytes left + ** ptr = current pos in USB data block + */ + while (remsize) { + if (remsize < RXBUF_HDRSIZE) { + printk("acx: truncated rx header (%d bytes)!\n", + remsize); + if (ACX_DEBUG) + acx_dump_bytes(ptr, remsize); + break; + } + + packetsize = RXBUF_BYTES_USED(ptr); + log(L_USBRXTX, "packet with packetsize=%d\n", packetsize); + + if (RXBUF_IS_TXSTAT(ptr)) { + /* do rate handling */ + usb_txstatus_t *stat = (void*)ptr; + u16 client_no = (u16)stat->hostdata; + + log(L_USBRXTX, "tx: stat: mac_cnt_rcvd:%04X " + "queue_index:%02X mac_status:%02X hostdata:%08X " + "rate:%u ack_failures:%02X rts_failures:%02X " + "rts_ok:%02X\n", + stat->mac_cnt_rcvd, + stat->queue_index, stat->mac_status, stat->hostdata, + stat->rate, stat->ack_failures, stat->rts_failures, + stat->rts_ok); + + if (adev->rate_auto && client_no < VEC_SIZE(adev->sta_list)) { + client_t *clt = &adev->sta_list[client_no]; + u16 cur = stat->hostdata >> 16; + + if (clt && clt->rate_cur == cur) { + acx_l_handle_txrate_auto(adev, clt, + cur, /* intended rate */ + stat->rate, 0, /* actually used rate */ + stat->mac_status, /* error? */ + ACX_TX_URB_CNT - adev->tx_free); + } + } + goto next; + } + + if (packetsize > sizeof(rxbuffer_t)) { + printk("acx: packet exceeds max wlan " + "frame size (%d > %d). size=%d\n", + packetsize, (int) sizeof(rxbuffer_t), size); + if (ACX_DEBUG) + acx_dump_bytes(ptr, 16); + /* FIXME: put some real error-handling in here! */ + break; + } + + if (packetsize > remsize) { + /* frame truncation handling */ + if (acx_debug & L_USBRXTX) { + printk("need to truncate packet, " + "packetsize=%d remsize=%d " + "size=%d bytes:", + packetsize, remsize, size); + acx_dump_bytes(ptr, RXBUF_HDRSIZE); + } + memcpy(&adev->rxtruncbuf, ptr, remsize); + adev->rxtruncsize = remsize; + break; + } + + /* packetsize <= remsize */ + /* now handle the received data */ + acx_l_process_rxbuf(adev, ptr); +next: + ptr = (rxbuffer_t *)(((char *)ptr) + packetsize); + remsize -= packetsize; + if ((acx_debug & L_USBRXTX) && remsize) { + printk("more than one packet in buffer, " + "second packet hdr:"); + acx_dump_bytes(ptr, RXBUF_HDRSIZE); + } + } + +end_unlock: + acx_unlock(adev, flags); +/* end: */ + FN_EXIT0; +} + + +/*********************************************************************** +** acxusb_i_complete_tx() +** Inputs: +** urb -> pointer to USB request block +** regs -> pointer to register-buffer for syscalls (see asm/ptrace.h) +** +** This function is invoked upon termination of a USB transfer. +*/ +static void +acxusb_i_complete_tx(struct urb *urb) +{ + acx_device_t *adev; + usb_tx_t *tx; + unsigned long flags; + int txnum; + + FN_ENTER; + + BUG_ON(!urb->context); + + tx = (usb_tx_t *)urb->context; + adev = tx->adev; + + txnum = tx - adev->usb_tx; + + acx_lock(adev, flags); + + /* + * If the iface isn't up, we don't have any right + * to play with them. The urb may get unlinked. + */ + if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) { + log(L_USBRXTX, "tx: device is down, not doing anything\n"); + goto end_unlock; + } + + log(L_USBRXTX, "RETURN TX (%d): status=%d size=%d\n", + txnum, urb->status, urb->actual_length); + + /* handle USB transfer errors */ + switch (urb->status) { + case 0: /* No error */ + break; + case -ESHUTDOWN: + goto end_unlock; + break; + case -ECONNRESET: + goto end_unlock; + break; + /* FIXME: real error-handling code here please */ + default: + printk(KERN_ERR "acx: tx error, urb status=%d\n", urb->status); + /* FIXME: real error-handling code here please */ + } + + /* free the URB and check for more data */ + tx->busy = 0; + adev->tx_free++; + if ((adev->tx_free >= TX_START_QUEUE) + && (adev->status == ACX_STATUS_4_ASSOCIATED) + && (acx_queue_stopped(adev->ndev)) + ) { + log(L_BUF, "tx: wake queue (%u free txbufs)\n", + adev->tx_free); + acx_wake_queue(adev->ndev, NULL); + } + +end_unlock: + acx_unlock(adev, flags); +/* end: */ + FN_EXIT0; +} + + +/*************************************************************** +** acxusb_l_alloc_tx +** Actually returns a usb_tx_t* ptr +*/ +tx_t* +acxusb_l_alloc_tx(acx_device_t *adev) +{ + usb_tx_t *tx; + unsigned head; + + FN_ENTER; + + head = adev->tx_head; + do { + head = (head + 1) % ACX_TX_URB_CNT; + if (!adev->usb_tx[head].busy) { + log(L_USBRXTX, "allocated tx %d\n", head); + tx = &adev->usb_tx[head]; + tx->busy = 1; + adev->tx_free--; + /* Keep a few free descs between head and tail of tx ring. + ** It is not absolutely needed, just feels safer */ + if (adev->tx_free < TX_STOP_QUEUE) { + log(L_BUF, "tx: stop queue " + "(%u free txbufs)\n", adev->tx_free); + acx_stop_queue(adev->ndev, NULL); + } + goto end; + } + } while (likely(head!=adev->tx_head)); + tx = NULL; + printk_ratelimited("acx: tx buffers full\n"); +end: + adev->tx_head = head; + FN_EXIT0; + return (tx_t*)tx; +} + + +/*************************************************************** +** Used if alloc_tx()'ed buffer needs to be cancelled without doing tx +*/ +void +acxusb_l_dealloc_tx(tx_t *tx_opaque) +{ + usb_tx_t* tx = (usb_tx_t*)tx_opaque; + tx->busy = 0; +} + + +/*************************************************************** +*/ +void* +acxusb_l_get_txbuf(acx_device_t *adev, tx_t* tx_opaque) +{ + usb_tx_t* tx = (usb_tx_t*)tx_opaque; + return &tx->bulkout.data; +} + + +/*************************************************************** +** acxusb_l_tx_data +** +** Can be called from IRQ (rx -> (AP bridging or mgmt response) -> tx). +** Can be called from acx_i_start_xmit (data frames from net core). +*/ +void +acxusb_l_tx_data(acx_device_t *adev, tx_t* tx_opaque, int wlanpkt_len) +{ + struct usb_device *usbdev; + struct urb* txurb; + usb_tx_t* tx; + usb_txbuffer_t* txbuf; + client_t *clt; + wlan_hdr_t* whdr; + unsigned int outpipe; + int ucode, txnum; + + FN_ENTER; + + tx = ((usb_tx_t *)tx_opaque); + txurb = tx->urb; + txbuf = &tx->bulkout; + whdr = (wlan_hdr_t *)txbuf->data; + txnum = tx - adev->usb_tx; + + log(L_DEBUG, "using buf#%d free=%d len=%d\n", + txnum, adev->tx_free, wlanpkt_len); + + switch (adev->mode) { + case ACX_MODE_0_ADHOC: + case ACX_MODE_3_AP: + clt = acx_l_sta_list_get(adev, whdr->a1); + break; + case ACX_MODE_2_STA: + clt = adev->ap_client; + break; + default: /* ACX_MODE_OFF, ACX_MODE_MONITOR */ + clt = NULL; + break; + } + + if (unlikely(clt && !clt->rate_cur)) { + printk("acx: driver bug! bad ratemask\n"); + goto end; + } + + /* fill the USB transfer header */ + txbuf->desc = cpu_to_le16(USB_TXBUF_TXDESC); + txbuf->mpdu_len = cpu_to_le16(wlanpkt_len); + txbuf->queue_index = 1; + if (clt) { + txbuf->rate = clt->rate_100; + txbuf->hostdata = (clt - adev->sta_list) | (clt->rate_cur << 16); + } else { + txbuf->rate = adev->rate_bcast100; + txbuf->hostdata = ((u16)-1) | (adev->rate_bcast << 16); + } + txbuf->ctrl1 = DESC_CTL_FIRSTFRAG; + if (1 == adev->preamble_cur) + SET_BIT(txbuf->ctrl1, DESC_CTL_SHORT_PREAMBLE); + txbuf->ctrl2 = 0; + txbuf->data_len = cpu_to_le16(wlanpkt_len); + + if (unlikely(acx_debug & L_DATA)) { + printk("dump of bulk out urb:\n"); + acx_dump_bytes(txbuf, wlanpkt_len + USB_TXBUF_HDRSIZE); + } + + if (unlikely(txurb->status == -EINPROGRESS)) { + printk("acx: trying to submit tx urb while already in progress\n"); + } + + /* now schedule the USB transfer */ + usbdev = adev->usbdev; + outpipe = usb_sndbulkpipe(usbdev, adev->bulkoutep); + + usb_fill_bulk_urb(txurb, usbdev, outpipe, + txbuf, /* dataptr */ + wlanpkt_len + USB_TXBUF_HDRSIZE, /* size */ + acxusb_i_complete_tx, /* handler */ + tx /* handler param */ + ); + + txurb->transfer_flags = URB_ASYNC_UNLINK|URB_ZERO_PACKET; + ucode = usb_submit_urb(txurb, GFP_ATOMIC); + log(L_USBRXTX, "SUBMIT TX (%d): outpipe=0x%X buf=%p txsize=%d " + "rate=%u errcode=%d\n", txnum, outpipe, txbuf, + wlanpkt_len + USB_TXBUF_HDRSIZE, txbuf->rate, ucode); + + if (unlikely(ucode)) { + printk(KERN_ERR "acx: submit_urb() error=%d txsize=%d\n", + ucode, wlanpkt_len + USB_TXBUF_HDRSIZE); + + /* on error, just mark the frame as done and update + ** the statistics + */ + adev->stats.tx_errors++; + tx->busy = 0; + adev->tx_free++; + /* needed? if (adev->tx_free > TX_START_QUEUE) acx_wake_queue(...) */ + } +end: + FN_EXIT0; +} + + +/*********************************************************************** +*/ +static void +acxusb_i_set_rx_mode(struct net_device *ndev) +{ +} + + +/*********************************************************************** +*/ +#ifdef HAVE_TX_TIMEOUT +static void +acxusb_i_tx_timeout(struct net_device *ndev) +{ + acx_device_t *adev = ndev2adev(ndev); + unsigned long flags; + int i; + + FN_ENTER; + + acx_lock(adev, flags); + /* unlink the URBs */ + for (i = 0; i < ACX_TX_URB_CNT; i++) { + acxusb_unlink_urb(adev->usb_tx[i].urb); + adev->usb_tx[i].busy = 0; + } + adev->tx_free = ACX_TX_URB_CNT; + /* TODO: stats update */ + acx_unlock(adev, flags); + + FN_EXIT0; +} +#endif + + +/*********************************************************************** +** init_module() +** +** This function is invoked upon loading of the kernel module. +** It registers itself at the kernel's USB subsystem. +** +** Returns: Errorcode on failure, 0 on success +*/ +int __init +acxusb_e_init_module(void) +{ + log(L_INIT, "USB module " ACX_RELEASE " initialized, " + "probing for devices...\n"); + return usb_register(&acxusb_driver); +} + + + +/*********************************************************************** +** cleanup_module() +** +** This function is invoked as last step of the module unloading. It simply +** deregisters this module at the kernel's USB subsystem. +*/ +void __exit +acxusb_e_cleanup_module() +{ + usb_deregister(&acxusb_driver); +} + + +/*********************************************************************** +** DEBUG STUFF +*/ +#if ACX_DEBUG + +#ifdef UNUSED +static void +dump_device(struct usb_device *usbdev) +{ + int i; + struct usb_config_descriptor *cd; + + printk("acx device dump:\n"); + printk(" devnum: %d\n", usbdev->devnum); + printk(" speed: %d\n", usbdev->speed); + printk(" tt: 0x%X\n", (unsigned int)(usbdev->tt)); + printk(" ttport: %d\n", (unsigned int)(usbdev->ttport)); + printk(" toggle[0]: 0x%X toggle[1]: 0x%X\n", (unsigned int)(usbdev->toggle[0]), (unsigned int)(usbdev->toggle[1])); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) + /* This saw a change after 2.6.10 */ + printk(" ep_in wMaxPacketSize: "); + for (i = 0; i < 16; ++i) + if (usbdev->ep_in[i] != NULL) + printk("%d:%d ", i, usbdev->ep_in[i]->desc.wMaxPacketSize); + printk("\n"); + printk(" ep_out wMaxPacketSize: "); + for (i = 0; i < VEC_SIZE(usbdev->ep_out); ++i) + if (usbdev->ep_out[i] != NULL) + printk("%d:%d ", i, usbdev->ep_out[i]->desc.wMaxPacketSize); + printk("\n"); +#else + printk(" epmaxpacketin: "); + for (i = 0; i < 16; i++) + printk("%d ", usbdev->epmaxpacketin[i]); + printk("\n"); + printk(" epmaxpacketout: "); + for (i = 0; i < 16; i++) + printk("%d ", usbdev->epmaxpacketout[i]); + printk("\n"); +#endif + printk(" parent: 0x%X\n", (unsigned int)usbdev->parent); + printk(" bus: 0x%X\n", (unsigned int)usbdev->bus); +#ifdef NO_DATATYPE + printk(" configs: "); + for (i = 0; i < usbdev->descriptor.bNumConfigurations; i++) + printk("0x%X ", usbdev->config[i]); + printk("\n"); +#endif + printk(" actconfig: %p\n", usbdev->actconfig); + dump_device_descriptor(&usbdev->descriptor); + + cd = &usbdev->config->desc; + dump_config_descriptor(cd); +} + + +/*********************************************************************** +*/ +static void +dump_config_descriptor(struct usb_config_descriptor *cd) +{ + printk("Configuration Descriptor:\n"); + if (!cd) { + printk("NULL\n"); + return; + } + printk(" bLength: %d (0x%X)\n", cd->bLength, cd->bLength); + printk(" bDescriptorType: %d (0x%X)\n", cd->bDescriptorType, cd->bDescriptorType); + printk(" bNumInterfaces: %d (0x%X)\n", cd->bNumInterfaces, cd->bNumInterfaces); + printk(" bConfigurationValue: %d (0x%X)\n", cd->bConfigurationValue, cd->bConfigurationValue); + printk(" iConfiguration: %d (0x%X)\n", cd->iConfiguration, cd->iConfiguration); + printk(" bmAttributes: %d (0x%X)\n", cd->bmAttributes, cd->bmAttributes); + /* printk(" MaxPower: %d (0x%X)\n", cd->bMaxPower, cd->bMaxPower); */ +} + + +static void +dump_device_descriptor(struct usb_device_descriptor *dd) +{ + printk("Device Descriptor:\n"); + if (!dd) { + printk("NULL\n"); + return; + } + printk(" bLength: %d (0x%X)\n", dd->bLength, dd->bLength); + printk(" bDescriptortype: %d (0x%X)\n", dd->bDescriptorType, dd->bDescriptorType); + printk(" bcdUSB: %d (0x%X)\n", dd->bcdUSB, dd->bcdUSB); + printk(" bDeviceClass: %d (0x%X)\n", dd->bDeviceClass, dd->bDeviceClass); + printk(" bDeviceSubClass: %d (0x%X)\n", dd->bDeviceSubClass, dd->bDeviceSubClass); + printk(" bDeviceProtocol: %d (0x%X)\n", dd->bDeviceProtocol, dd->bDeviceProtocol); + printk(" bMaxPacketSize0: %d (0x%X)\n", dd->bMaxPacketSize0, dd->bMaxPacketSize0); + printk(" idVendor: %d (0x%X)\n", dd->idVendor, dd->idVendor); + printk(" idProduct: %d (0x%X)\n", dd->idProduct, dd->idProduct); + printk(" bcdDevice: %d (0x%X)\n", dd->bcdDevice, dd->bcdDevice); + printk(" iManufacturer: %d (0x%X)\n", dd->iManufacturer, dd->iManufacturer); + printk(" iProduct: %d (0x%X)\n", dd->iProduct, dd->iProduct); + printk(" iSerialNumber: %d (0x%X)\n", dd->iSerialNumber, dd->iSerialNumber); + printk(" bNumConfigurations: %d (0x%X)\n", dd->bNumConfigurations, dd->bNumConfigurations); +} +#endif /* UNUSED */ + +#endif /* ACX_DEBUG */ --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/pci.c +++ linux-2.6.28/ubuntu/misc/wireless/acx/pci.c @@ -0,0 +1,4260 @@ +/*********************************************************************** +** Copyright (C) 2003 ACX100 Open Source Project +** +** The contents of this file are subject to the Mozilla Public +** License Version 1.1 (the "License"); you may not use this file +** except in compliance with the License. You may obtain a copy of +** the License at http://www.mozilla.org/MPL/ +** +** Software distributed under the License is distributed on an "AS +** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +** implied. See the License for the specific language governing +** rights and limitations under the License. +** +** Alternatively, the contents of this file may be used under the +** terms of the GNU Public License version 2 (the "GPL"), in which +** case the provisions of the GPL are applicable instead of the +** above. If you wish to allow the use of your version of this file +** only under the terms of the GPL and not to allow others to use +** your version of this file under the MPL, indicate your decision +** by deleting the provisions above and replace them with the notice +** and other provisions required by the GPL. If you do not delete +** the provisions above, a recipient may use your version of this +** file under either the MPL or the GPL. +** --------------------------------------------------------------------- +** Inquiries regarding the ACX100 Open Source Project can be +** made directly to: +** +** acx100-users@lists.sf.net +** http://acx100.sf.net +** --------------------------------------------------------------------- +*/ +#define ACX_PCI 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "acx.h" + + +/*********************************************************************** +*/ +#define PCI_TYPE (PCI_USES_MEM | PCI_ADDR0 | PCI_NO_ACPI_WAKE) +#define PCI_ACX100_REGION1 0x01 +#define PCI_ACX100_REGION1_SIZE 0x1000 /* Memory size - 4K bytes */ +#define PCI_ACX100_REGION2 0x02 +#define PCI_ACX100_REGION2_SIZE 0x10000 /* Memory size - 64K bytes */ + +#define PCI_ACX111_REGION1 0x00 +#define PCI_ACX111_REGION1_SIZE 0x2000 /* Memory size - 8K bytes */ +#define PCI_ACX111_REGION2 0x01 +#define PCI_ACX111_REGION2_SIZE 0x20000 /* Memory size - 128K bytes */ + +/* Texas Instruments Vendor ID */ +#define PCI_VENDOR_ID_TI 0x104c + +/* ACX100 22Mb/s WLAN controller */ +#define PCI_DEVICE_ID_TI_TNETW1100A 0x8400 +#define PCI_DEVICE_ID_TI_TNETW1100B 0x8401 + +/* ACX111 54Mb/s WLAN controller */ +#define PCI_DEVICE_ID_TI_TNETW1130 0x9066 + +/* PCI Class & Sub-Class code, Network-'Other controller' */ +#define PCI_CLASS_NETWORK_OTHERS 0x0280 + +#define CARD_EEPROM_ID_SIZE 6 + +#ifndef PCI_D0 +/* From include/linux/pci.h */ +#define PCI_D0 0 +#define PCI_D1 1 +#define PCI_D2 2 +#define PCI_D3hot 3 +#define PCI_D3cold 4 +#define PCI_UNKNOWN 5 +#define PCI_POWER_ERROR -1 +#endif + + +/*********************************************************************** +*/ +static void acxpci_i_tx_timeout(struct net_device *ndev); +static irqreturn_t acxpci_i_interrupt(int irq, void *dev_id); +static void acxpci_i_set_multicast_list(struct net_device *ndev); + +static int acxpci_e_open(struct net_device *ndev); +static int acxpci_e_close(struct net_device *ndev); +static void acxpci_s_up(struct net_device *ndev); +static void acxpci_s_down(struct net_device *ndev); + + +/*********************************************************************** +** Register access +*/ + +/* Pick one */ +/* #define INLINE_IO static */ +#define INLINE_IO static inline + +INLINE_IO u32 +read_reg32(acx_device_t *adev, unsigned int offset) +{ +#if ACX_IO_WIDTH == 32 + return readl((u8 *)adev->iobase + adev->io[offset]); +#else + return readw((u8 *)adev->iobase + adev->io[offset]) + + (readw((u8 *)adev->iobase + adev->io[offset] + 2) << 16); +#endif +} + +INLINE_IO u16 +read_reg16(acx_device_t *adev, unsigned int offset) +{ + return readw((u8 *)adev->iobase + adev->io[offset]); +} + +INLINE_IO u8 +read_reg8(acx_device_t *adev, unsigned int offset) +{ + return readb((u8 *)adev->iobase + adev->io[offset]); +} + +INLINE_IO void +write_reg32(acx_device_t *adev, unsigned int offset, u32 val) +{ +#if ACX_IO_WIDTH == 32 + writel(val, (u8 *)adev->iobase + adev->io[offset]); +#else + writew(val & 0xffff, (u8 *)adev->iobase + adev->io[offset]); + writew(val >> 16, (u8 *)adev->iobase + adev->io[offset] + 2); +#endif +} + +INLINE_IO void +write_reg16(acx_device_t *adev, unsigned int offset, u16 val) +{ + writew(val, (u8 *)adev->iobase + adev->io[offset]); +} + +INLINE_IO void +write_reg8(acx_device_t *adev, unsigned int offset, u8 val) +{ + writeb(val, (u8 *)adev->iobase + adev->io[offset]); +} + +/* Handle PCI posting properly: + * Make sure that writes reach the adapter in case they require to be executed + * *before* the next write, by reading a random (and safely accessible) register. + * This call has to be made if there is no read following (which would flush the data + * to the adapter), yet the written data has to reach the adapter immediately. */ +INLINE_IO void +write_flush(acx_device_t *adev) +{ + /* readb(adev->iobase + adev->io[IO_ACX_INFO_MAILBOX_OFFS]); */ + /* faster version (accesses the first register, IO_ACX_SOFT_RESET, + * which should also be safe): */ + readb(adev->iobase); +} + +INLINE_IO int +adev_present(acx_device_t *adev) +{ + /* fast version (accesses the first register, IO_ACX_SOFT_RESET, + * which should be safe): */ + return readl(adev->iobase) != 0xffffffff; +} + + +/*********************************************************************** +*/ +static inline txdesc_t* +get_txdesc(acx_device_t *adev, int index) +{ + return (txdesc_t*) (((u8*)adev->txdesc_start) + index * adev->txdesc_size); +} + +static inline txdesc_t* +advance_txdesc(acx_device_t *adev, txdesc_t* txdesc, int inc) +{ + return (txdesc_t*) (((u8*)txdesc) + inc * adev->txdesc_size); +} + +static txhostdesc_t* +get_txhostdesc(acx_device_t *adev, txdesc_t* txdesc) +{ + int index = (u8*)txdesc - (u8*)adev->txdesc_start; + if (unlikely(ACX_DEBUG && (index % adev->txdesc_size))) { + printk("bad txdesc ptr %p\n", txdesc); + return NULL; + } + index /= adev->txdesc_size; + if (unlikely(ACX_DEBUG && (index >= TX_CNT))) { + printk("bad txdesc ptr %p\n", txdesc); + return NULL; + } + return &adev->txhostdesc_start[index*2]; +} + +static inline client_t* +get_txc(acx_device_t *adev, txdesc_t* txdesc) +{ + int index = (u8*)txdesc - (u8*)adev->txdesc_start; + if (unlikely(ACX_DEBUG && (index % adev->txdesc_size))) { + printk("bad txdesc ptr %p\n", txdesc); + return NULL; + } + index /= adev->txdesc_size; + if (unlikely(ACX_DEBUG && (index >= TX_CNT))) { + printk("bad txdesc ptr %p\n", txdesc); + return NULL; + } + return adev->txc[index]; +} + +static inline u16 +get_txr(acx_device_t *adev, txdesc_t* txdesc) +{ + int index = (u8*)txdesc - (u8*)adev->txdesc_start; + index /= adev->txdesc_size; + return adev->txr[index]; +} + +static inline void +put_txcr(acx_device_t *adev, txdesc_t* txdesc, client_t* c, u16 r111) +{ + int index = (u8*)txdesc - (u8*)adev->txdesc_start; + if (unlikely(ACX_DEBUG && (index % adev->txdesc_size))) { + printk("bad txdesc ptr %p\n", txdesc); + return; + } + index /= adev->txdesc_size; + if (unlikely(ACX_DEBUG && (index >= TX_CNT))) { + printk("bad txdesc ptr %p\n", txdesc); + return; + } + adev->txc[index] = c; + adev->txr[index] = r111; +} + + +/*********************************************************************** +** EEPROM and PHY read/write helpers +*/ +/*********************************************************************** +** acxpci_read_eeprom_byte +** +** Function called to read an octet in the EEPROM. +** +** This function is used by acxpci_e_probe to check if the +** connected card is a legal one or not. +** +** Arguments: +** adev ptr to acx_device structure +** addr address to read in the EEPROM +** charbuf ptr to a char. This is where the read octet +** will be stored +*/ +int +acxpci_read_eeprom_byte(acx_device_t *adev, u32 addr, u8 *charbuf) +{ + int result; + int count; + + write_reg32(adev, IO_ACX_EEPROM_CFG, 0); + write_reg32(adev, IO_ACX_EEPROM_ADDR, addr); + write_flush(adev); + write_reg32(adev, IO_ACX_EEPROM_CTL, 2); + + count = 0xffff; + while (read_reg16(adev, IO_ACX_EEPROM_CTL)) { + /* scheduling away instead of CPU burning loop + * doesn't seem to work here at all: + * awful delay, sometimes also failure. + * Doesn't matter anyway (only small delay). */ + if (unlikely(!--count)) { + printk("%s: timeout waiting for EEPROM read\n", + adev->ndev->name); + result = NOT_OK; + goto fail; + } + cpu_relax(); + } + + *charbuf = read_reg8(adev, IO_ACX_EEPROM_DATA); + log(L_DEBUG, "EEPROM at 0x%04X = 0x%02X\n", addr, *charbuf); + result = OK; + +fail: + return result; +} + + +/*********************************************************************** +** We don't lock hw accesses here since we never r/w eeprom in IRQ +** Note: this function sleeps only because of GFP_KERNEL alloc +*/ +#ifdef UNUSED +int +acxpci_s_write_eeprom(acx_device_t *adev, u32 addr, u32 len, const u8 *charbuf) +{ + u8 *data_verify = NULL; + unsigned long flags; + int count, i; + int result = NOT_OK; + u16 gpio_orig; + + printk("acx: WARNING! I would write to EEPROM now. " + "Since I really DON'T want to unless you know " + "what you're doing (THIS CODE WILL PROBABLY " + "NOT WORK YET!), I will abort that now. And " + "definitely make sure to make a " + "/proc/driver/acx_wlan0_eeprom backup copy first!!! " + "(the EEPROM content includes the PCI config header!! " + "If you kill important stuff, then you WILL " + "get in trouble and people DID get in trouble already)\n"); + return OK; + + FN_ENTER; + + data_verify = kmalloc(len, GFP_KERNEL); + if (!data_verify) { + goto end; + } + + /* first we need to enable the OE (EEPROM Output Enable) GPIO line + * to be able to write to the EEPROM. + * NOTE: an EEPROM writing success has been reported, + * but you probably have to modify GPIO_OUT, too, + * and you probably need to activate a different GPIO + * line instead! */ + gpio_orig = read_reg16(adev, IO_ACX_GPIO_OE); + write_reg16(adev, IO_ACX_GPIO_OE, gpio_orig & ~1); + write_flush(adev); + + /* ok, now start writing the data out */ + for (i = 0; i < len; i++) { + write_reg32(adev, IO_ACX_EEPROM_CFG, 0); + write_reg32(adev, IO_ACX_EEPROM_ADDR, addr + i); + write_reg32(adev, IO_ACX_EEPROM_DATA, *(charbuf + i)); + write_flush(adev); + write_reg32(adev, IO_ACX_EEPROM_CTL, 1); + + count = 0xffff; + while (read_reg16(adev, IO_ACX_EEPROM_CTL)) { + if (unlikely(!--count)) { + printk("WARNING, DANGER!!! " + "Timeout waiting for EEPROM write\n"); + goto end; + } + cpu_relax(); + } + } + + /* disable EEPROM writing */ + write_reg16(adev, IO_ACX_GPIO_OE, gpio_orig); + write_flush(adev); + + /* now start a verification run */ + for (i = 0; i < len; i++) { + write_reg32(adev, IO_ACX_EEPROM_CFG, 0); + write_reg32(adev, IO_ACX_EEPROM_ADDR, addr + i); + write_flush(adev); + write_reg32(adev, IO_ACX_EEPROM_CTL, 2); + + count = 0xffff; + while (read_reg16(adev, IO_ACX_EEPROM_CTL)) { + if (unlikely(!--count)) { + printk("timeout waiting for EEPROM read\n"); + goto end; + } + cpu_relax(); + } + + data_verify[i] = read_reg16(adev, IO_ACX_EEPROM_DATA); + } + + if (0 == memcmp(charbuf, data_verify, len)) + result = OK; /* read data matches, success */ + +end: + kfree(data_verify); + FN_EXIT1(result); + return result; +} +#endif /* UNUSED */ + + +/*********************************************************************** +** acxpci_s_read_phy_reg +** +** Messing with rx/tx disabling and enabling here +** (write_reg32(adev, IO_ACX_ENABLE, 0b000000xx)) kills traffic +*/ +int +acxpci_s_read_phy_reg(acx_device_t *adev, u32 reg, u8 *charbuf) +{ + int result = NOT_OK; + int count; + + FN_ENTER; + + write_reg32(adev, IO_ACX_PHY_ADDR, reg); + write_flush(adev); + write_reg32(adev, IO_ACX_PHY_CTL, 2); + + count = 0xffff; + while (read_reg32(adev, IO_ACX_PHY_CTL)) { + /* scheduling away instead of CPU burning loop + * doesn't seem to work here at all: + * awful delay, sometimes also failure. + * Doesn't matter anyway (only small delay). */ + if (unlikely(!--count)) { + printk("%s: timeout waiting for phy read\n", + adev->ndev->name); + *charbuf = 0; + goto fail; + } + cpu_relax(); + } + + log(L_DEBUG, "count was %u\n", count); + *charbuf = read_reg8(adev, IO_ACX_PHY_DATA); + + log(L_DEBUG, "radio PHY at 0x%04X = 0x%02X\n", *charbuf, reg); + result = OK; + goto fail; /* silence compiler warning */ +fail: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +*/ +int +acxpci_s_write_phy_reg(acx_device_t *adev, u32 reg, u8 value) +{ + FN_ENTER; + + /* mprusko said that 32bit accesses result in distorted sensitivity + * on his card. Unconfirmed, looks like it's not true (most likely since we + * now properly flush writes). */ + write_reg32(adev, IO_ACX_PHY_DATA, value); + write_reg32(adev, IO_ACX_PHY_ADDR, reg); + write_flush(adev); + write_reg32(adev, IO_ACX_PHY_CTL, 1); + write_flush(adev); + log(L_DEBUG, "radio PHY write 0x%02X at 0x%04X\n", value, reg); + + FN_EXIT1(OK); + return OK; +} + + +#define NO_AUTO_INCREMENT 1 + +/*********************************************************************** +** acxpci_s_write_fw +** +** Write the firmware image into the card. +** +** Arguments: +** adev wlan device structure +** fw_image firmware image. +** +** Returns: +** 1 firmware image corrupted +** 0 success +*/ +static int +acxpci_s_write_fw(acx_device_t *adev, const firmware_image_t *fw_image, u32 offset) +{ + int len, size; + u32 sum, v32; + /* we skip the first four bytes which contain the control sum */ + const u8 *p = (u8*)fw_image + 4; + + /* start the image checksum by adding the image size value */ + sum = p[0]+p[1]+p[2]+p[3]; + p += 4; + + write_reg32(adev, IO_ACX_SLV_END_CTL, 0); + +#if NO_AUTO_INCREMENT + write_reg32(adev, IO_ACX_SLV_MEM_CTL, 0); /* use basic mode */ +#else + write_reg32(adev, IO_ACX_SLV_MEM_CTL, 1); /* use autoincrement mode */ + write_reg32(adev, IO_ACX_SLV_MEM_ADDR, offset); /* configure start address */ + write_flush(adev); +#endif + + len = 0; + size = le32_to_cpu(fw_image->size) & (~3); + + while (likely(len < size)) { + v32 = be32_to_cpu(*(u32*)p); + sum += p[0]+p[1]+p[2]+p[3]; + p += 4; + len += 4; + +#if NO_AUTO_INCREMENT + write_reg32(adev, IO_ACX_SLV_MEM_ADDR, offset + len - 4); + write_flush(adev); +#endif + write_reg32(adev, IO_ACX_SLV_MEM_DATA, v32); + } + + log(L_DEBUG, "firmware written, size:%d sum1:%x sum2:%x\n", + size, sum, le32_to_cpu(fw_image->chksum)); + + /* compare our checksum with the stored image checksum */ + return (sum != le32_to_cpu(fw_image->chksum)); +} + + +/*********************************************************************** +** acxpci_s_validate_fw +** +** Compare the firmware image given with +** the firmware image written into the card. +** +** Arguments: +** adev wlan device structure +** fw_image firmware image. +** +** Returns: +** NOT_OK firmware image corrupted or not correctly written +** OK success +*/ +static int +acxpci_s_validate_fw(acx_device_t *adev, const firmware_image_t *fw_image, + u32 offset) +{ + u32 sum, v32, w32; + int len, size; + int result = OK; + /* we skip the first four bytes which contain the control sum */ + const u8 *p = (u8*)fw_image + 4; + + /* start the image checksum by adding the image size value */ + sum = p[0]+p[1]+p[2]+p[3]; + p += 4; + + write_reg32(adev, IO_ACX_SLV_END_CTL, 0); + +#if NO_AUTO_INCREMENT + write_reg32(adev, IO_ACX_SLV_MEM_CTL, 0); /* use basic mode */ +#else + write_reg32(adev, IO_ACX_SLV_MEM_CTL, 1); /* use autoincrement mode */ + write_reg32(adev, IO_ACX_SLV_MEM_ADDR, offset); /* configure start address */ +#endif + + len = 0; + size = le32_to_cpu(fw_image->size) & (~3); + + while (likely(len < size)) { + v32 = be32_to_cpu(*(u32*)p); + p += 4; + len += 4; + +#if NO_AUTO_INCREMENT + write_reg32(adev, IO_ACX_SLV_MEM_ADDR, offset + len - 4); +#endif + w32 = read_reg32(adev, IO_ACX_SLV_MEM_DATA); + + if (unlikely(w32 != v32)) { + printk("acx: FATAL: firmware upload: " + "data parts at offset %d don't match (0x%08X vs. 0x%08X)! " + "I/O timing issues or defective memory, with DWL-xx0+? " + "ACX_IO_WIDTH=16 may help. Please report\n", + len, v32, w32); + result = NOT_OK; + break; + } + + sum += (u8)w32 + (u8)(w32>>8) + (u8)(w32>>16) + (u8)(w32>>24); + } + + /* sum control verification */ + if (result != NOT_OK) { + if (sum != le32_to_cpu(fw_image->chksum)) { + printk("acx: FATAL: firmware upload: " + "checksums don't match!\n"); + result = NOT_OK; + } + } + + return result; +} + +struct fw_match { + unsigned short vendor; + unsigned short device; + unsigned short subvendor; + unsigned short subdevice; + const char *verstr; + int announced; +}; + +/* NOTE: This is NOT the module device table. We're just abusing the + * pci_device_id struct for our own purposes */ +static struct fw_match fw_ver_table[] = { + { /* Abocom WG24500, reported by Franz Pletz */ + .vendor = PCI_VENDOR_ID_TI, + .device = PCI_DEVICE_ID_TI_TNETW1130, + .subvendor = 0x13d1, + .subdevice = 0xab80, + .verstr = "1.2.0.30", + }, + { /* Texas Instruments ACX 111 54Mbps Wireless Interface */ + .vendor = PCI_VENDOR_ID_TI, + .device = PCI_DEVICE_ID_TI_TNETW1130, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .verstr = "1.2.1.34", + }, + { 0 } +}; + +#define PCI_MATCH(a,b) (a == b || a == (unsigned short)PCI_ANY_ID) + +/* Returns an alternate version of the firmware for specific devices. The + * above table will _always_ be overriden by module param. */ +static const char *get_firmware_ver(struct pci_dev *dev) +{ + struct fw_match *dev_match; + + if (!dev || strcmp(firmware_ver, "default")) + goto use_default; + + for (dev_match = fw_ver_table; dev_match->vendor; dev_match++) { + if (PCI_MATCH(dev_match->vendor, dev->vendor) && + PCI_MATCH(dev_match->device, dev->device) && + PCI_MATCH(dev_match->subvendor, dev->subsystem_vendor) && + PCI_MATCH(dev_match->subdevice, dev->subsystem_device)) + return dev_match->verstr; + } + +use_default: + return firmware_ver; +} + + +/*********************************************************************** +** acxpci_s_upload_fw +** +** Called from acx_reset_dev +*/ +static int +acxpci_s_upload_fw(acx_device_t *adev) +{ + firmware_image_t *fw_image = NULL; + int res = NOT_OK; + int try; + u32 file_size; + char filename[256]; + + FN_ENTER; + + printk(KERN_INFO "acx: loading firmware for acx1%02d chipset with radio" + " ID %02X\n", IS_ACX111(adev)*111, adev->radio_type); + + /* Try combined, then main image */ + adev->need_radio_fw = 0; + snprintf(filename, sizeof(filename), "acx/%s/tiacx1%02dc%02X", + get_firmware_ver(adev->pdev), + IS_ACX111(adev)*11, adev->radio_type); + + fw_image = acx_s_read_fw(&adev->pdev->dev, filename, &file_size); + if (!fw_image) { + adev->need_radio_fw = 1; + filename[strlen(filename) - 3] = '\0'; + fw_image = acx_s_read_fw(&adev->pdev->dev, filename, &file_size); + if (!fw_image) { + FN_EXIT1(NOT_OK); + return NOT_OK; + } + } + + for (try = 1; try <= 5; try++) { + res = acxpci_s_write_fw(adev, fw_image, 0); + log(L_DEBUG|L_INIT, "acx_write_fw (main/combined): %d\n", res); + if (OK == res) { + res = acxpci_s_validate_fw(adev, fw_image, 0); + log(L_DEBUG|L_INIT, "acx_validate_fw " + "(main/combined): %d\n", res); + } + + if (OK == res) { + SET_BIT(adev->dev_state_mask, ACX_STATE_FW_LOADED); + break; + } + printk("acx: firmware upload attempt #%d FAILED, " + "retrying...\n", try); + acx_s_msleep(1000); /* better wait for a while... */ + } + + vfree(fw_image); + + FN_EXIT1(res); + return res; +} + + +/*********************************************************************** +** acxpci_s_upload_radio +** +** Uploads the appropriate radio module firmware into the card. +*/ +int +acxpci_s_upload_radio(acx_device_t *adev) +{ + acx_ie_memmap_t mm; + firmware_image_t *radio_image; + acx_cmd_radioinit_t radioinit; + int res = NOT_OK; + int try; + u32 offset; + u32 size; + char filename[256]; + + if (!adev->need_radio_fw) return OK; + + FN_ENTER; + + printk(KERN_INFO "acx: loading radio image for radio %02X\n", + adev->radio_type); + + acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP); + offset = le32_to_cpu(mm.CodeEnd); + + snprintf(filename, sizeof(filename), "acx/%s/tiacx1%02dr%02X", + get_firmware_ver(adev->pdev), IS_ACX111(adev)*11, + adev->radio_type); + radio_image = acx_s_read_fw(&adev->pdev->dev, filename, &size); + if (!radio_image) { + printk("acx: can't load radio module '%s'\n", filename); + goto fail; + } + + acx_s_issue_cmd(adev, ACX1xx_CMD_SLEEP, NULL, 0); + + for (try = 1; try <= 5; try++) { + res = acxpci_s_write_fw(adev, radio_image, offset); + log(L_DEBUG|L_INIT, "acx_write_fw (radio): %d\n", res); + if (OK == res) { + res = acxpci_s_validate_fw(adev, radio_image, offset); + log(L_DEBUG|L_INIT, "acx_validate_fw (radio): %d\n", res); + } + + if (OK == res) + break; + printk("acx: radio firmware upload attempt #%d FAILED, " + "retrying...\n", try); + acx_s_msleep(1000); /* better wait for a while... */ + } + + acx_s_issue_cmd(adev, ACX1xx_CMD_WAKE, NULL, 0); + radioinit.offset = cpu_to_le32(offset); + /* no endian conversion needed, remains in card CPU area: */ + radioinit.len = radio_image->size; + + vfree(radio_image); + + if (OK != res) + goto fail; + + /* will take a moment so let's have a big timeout */ + acx_s_issue_cmd_timeo(adev, ACX1xx_CMD_RADIOINIT, + &radioinit, sizeof(radioinit), CMD_TIMEOUT_MS(1000)); + + res = acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP); +fail: + FN_EXIT1(res); + return res; +} + + +/*********************************************************************** +** acxpci_l_reset_mac +** +** MAC will be reset +** Call context: reset_dev +*/ +static void +acxpci_l_reset_mac(acx_device_t *adev) +{ + u16 temp; + + FN_ENTER; + + /* halt eCPU */ + temp = read_reg16(adev, IO_ACX_ECPU_CTRL) | 0x1; + write_reg16(adev, IO_ACX_ECPU_CTRL, temp); + + /* now do soft reset of eCPU, set bit */ + temp = read_reg16(adev, IO_ACX_SOFT_RESET) | 0x1; + log(L_DEBUG, "%s: enable soft reset...\n", __func__); + write_reg16(adev, IO_ACX_SOFT_RESET, temp); + write_flush(adev); + + /* now clear bit again: deassert eCPU reset */ + log(L_DEBUG, "%s: disable soft reset and go to init mode...\n", __func__); + write_reg16(adev, IO_ACX_SOFT_RESET, temp & ~0x1); + + /* now start a burst read from initial EEPROM */ + temp = read_reg16(adev, IO_ACX_EE_START) | 0x1; + write_reg16(adev, IO_ACX_EE_START, temp); + write_flush(adev); + + FN_EXIT0; +} + + +/*********************************************************************** +** acxpci_s_verify_init +*/ +static int +acxpci_s_verify_init(acx_device_t *adev) +{ + int result = NOT_OK; + unsigned long timeout; + + FN_ENTER; + + timeout = jiffies + 2*HZ; + for (;;) { + u16 irqstat = read_reg16(adev, IO_ACX_IRQ_STATUS_NON_DES); + if (irqstat & HOST_INT_FCS_THRESHOLD) { + result = OK; + write_reg16(adev, IO_ACX_IRQ_ACK, HOST_INT_FCS_THRESHOLD); + break; + } + if (time_after(jiffies, timeout)) + break; + /* Init may take up to ~0.5 sec total */ + acx_s_msleep(50); + } + + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** A few low-level helpers +** +** Note: these functions are not protected by lock +** and thus are never allowed to be called from IRQ. +** Also they must not race with fw upload which uses same hw regs +*/ + +/*********************************************************************** +** acxpci_write_cmd_type_status +*/ + +static inline void +acxpci_write_cmd_type_status(acx_device_t *adev, u16 type, u16 status) +{ + writel(type | (status << 16), adev->cmd_area); + write_flush(adev); +} + + +/*********************************************************************** +** acxpci_read_cmd_type_status +*/ +static u32 +acxpci_read_cmd_type_status(acx_device_t *adev) +{ + u32 cmd_type, cmd_status; + + cmd_type = readl(adev->cmd_area); + cmd_status = (cmd_type >> 16); + cmd_type = (u16)cmd_type; + + log(L_CTL, "cmd_type:%04X cmd_status:%04X [%s]\n", + cmd_type, cmd_status, + acx_cmd_status_str(cmd_status)); + + return cmd_status; +} + + +/*********************************************************************** +** acxpci_s_reset_dev +** +** Arguments: +** netdevice that contains the adev variable +** Returns: +** NOT_OK on fail +** OK on success +** Side effects: +** device is hard reset +** Call context: +** acxpci_e_probe +** Comment: +** This resets the device using low level hardware calls +** as well as uploads and verifies the firmware to the card +*/ + +static inline void +init_mboxes(acx_device_t *adev) +{ + u32 cmd_offs, info_offs; + + cmd_offs = read_reg32(adev, IO_ACX_CMD_MAILBOX_OFFS); + info_offs = read_reg32(adev, IO_ACX_INFO_MAILBOX_OFFS); + adev->cmd_area = (u8 *)adev->iobase2 + cmd_offs; + adev->info_area = (u8 *)adev->iobase2 + info_offs; + log(L_DEBUG, "iobase2=%p\n" + "cmd_mbox_offset=%X cmd_area=%p\n" + "info_mbox_offset=%X info_area=%p\n", + adev->iobase2, + cmd_offs, adev->cmd_area, + info_offs, adev->info_area); +} + + +static inline void +read_eeprom_area(acx_device_t *adev) +{ +#if ACX_DEBUG > 1 + int offs; + u8 tmp; + + for (offs = 0x8c; offs < 0xb9; offs++) + acxpci_read_eeprom_byte(adev, offs, &tmp); +#endif +} + + +static int +acxpci_s_reset_dev(acx_device_t *adev) +{ + const char* msg = ""; + unsigned long flags; + int result = NOT_OK; + u16 hardware_info; + u16 ecpu_ctrl; + int count; + + FN_ENTER; + + /* reset the device to make sure the eCPU is stopped + * to upload the firmware correctly */ + + acx_lock(adev, flags); + + acxpci_l_reset_mac(adev); + + ecpu_ctrl = read_reg16(adev, IO_ACX_ECPU_CTRL) & 1; + if (!ecpu_ctrl) { + msg = "eCPU is already running. "; + goto end_unlock; + } + +#ifdef WE_DONT_NEED_THAT_DO_WE + if (read_reg16(adev, IO_ACX_SOR_CFG) & 2) { + /* eCPU most likely means "embedded CPU" */ + msg = "eCPU did not start after boot from flash. "; + goto end_unlock; + } + + /* check sense on reset flags */ + if (read_reg16(adev, IO_ACX_SOR_CFG) & 0x10) { + printk("%s: eCPU did not start after boot (SOR), " + "is this fatal?\n", adev->ndev->name); + } +#endif + /* scan, if any, is stopped now, setting corresponding IRQ bit */ + adev->irq_status |= HOST_INT_SCAN_COMPLETE; + + acx_unlock(adev, flags); + + /* need to know radio type before fw load */ + /* Need to wait for arrival of this information in a loop, + * most probably since eCPU runs some init code from EEPROM + * (started burst read in reset_mac()) which also + * sets the radio type ID */ + + count = 0xffff; + do { + hardware_info = read_reg16(adev, IO_ACX_EEPROM_INFORMATION); + if (!--count) { + msg = "eCPU didn't indicate radio type"; + goto end_fail; + } + cpu_relax(); + } while (!(hardware_info & 0xff00)); /* radio type still zero? */ + + /* printk("DEBUG: count %d\n", count); */ + adev->form_factor = hardware_info & 0xff; + adev->radio_type = hardware_info >> 8; + + /* load the firmware */ + if (OK != acxpci_s_upload_fw(adev)) + goto end_fail; + + /* acx_s_msleep(10); this one really shouldn't be required */ + + /* now start eCPU by clearing bit */ + write_reg16(adev, IO_ACX_ECPU_CTRL, ecpu_ctrl & ~0x1); + log(L_DEBUG, "booted eCPU up and waiting for completion...\n"); + + /* wait for eCPU bootup */ + if (OK != acxpci_s_verify_init(adev)) { + msg = "timeout waiting for eCPU. "; + goto end_fail; + } + log(L_DEBUG, "eCPU has woken up, card is ready to be configured\n"); + + init_mboxes(adev); + acxpci_write_cmd_type_status(adev, 0, 0); + + /* test that EEPROM is readable */ + read_eeprom_area(adev); + + result = OK; + goto end; + +/* Finish error message. Indicate which function failed */ +end_unlock: + acx_unlock(adev, flags); +end_fail: + printk("acx: %sreset_dev() FAILED\n", msg); +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acxpci_s_issue_cmd_timeo +** +** Sends command to fw, extract result +** +** NB: we do _not_ take lock inside, so be sure to not touch anything +** which may interfere with IRQ handler operation +** +** TODO: busy wait is a bit silly, so: +** 1) stop doing many iters - go to sleep after first +** 2) go to waitqueue based approach: wait, not poll! +*/ +#undef FUNC +#define FUNC "issue_cmd" + +#if !ACX_DEBUG +int +acxpci_s_issue_cmd_timeo( + acx_device_t *adev, + unsigned int cmd, + void *buffer, + unsigned buflen, + unsigned cmd_timeout) +{ +#else +int +acxpci_s_issue_cmd_timeo_debug( + acx_device_t *adev, + unsigned cmd, + void *buffer, + unsigned buflen, + unsigned cmd_timeout, + const char* cmdstr) +{ + unsigned long start = jiffies; +#endif + const char *devname; + unsigned counter; + u16 irqtype; + u16 cmd_status; + unsigned long timeout; + + FN_ENTER; + + devname = adev->ndev->name; + if (!devname || !devname[0] || devname[4]=='%') + devname = "acx"; + + log(L_CTL, FUNC"(cmd:%s,buflen:%u,timeout:%ums,type:0x%04X)\n", + cmdstr, buflen, cmd_timeout, + buffer ? le16_to_cpu(((acx_ie_generic_t *)buffer)->type) : -1); + + if (!(adev->dev_state_mask & ACX_STATE_FW_LOADED)) { + printk("%s: "FUNC"(): firmware is not loaded yet, " + "cannot execute commands!\n", devname); + goto bad; + } + + if ((acx_debug & L_DEBUG) && (cmd != ACX1xx_CMD_INTERROGATE)) { + printk("input buffer (len=%u):\n", buflen); + acx_dump_bytes(buffer, buflen); + } + + /* wait for firmware to become idle for our command submission */ + timeout = HZ/5; + counter = (timeout * 1000 / HZ) - 1; /* in ms */ + timeout += jiffies; + do { + cmd_status = acxpci_read_cmd_type_status(adev); + /* Test for IDLE state */ + if (!cmd_status) + break; + if (counter % 8 == 0) { + if (time_after(jiffies, timeout)) { + counter = 0; + break; + } + /* we waited 8 iterations, no luck. Sleep 8 ms */ + acx_s_msleep(8); + } + } while (likely(--counter)); + + if (!counter) { + /* the card doesn't get idle, we're in trouble */ + printk("%s: "FUNC"(): cmd_status is not IDLE: 0x%04X!=0\n", + devname, cmd_status); + goto bad; + } else if (counter < 190) { /* if waited >10ms... */ + log(L_CTL|L_DEBUG, FUNC"(): waited for IDLE %dms. " + "Please report\n", 199 - counter); + } + + /* now write the parameters of the command if needed */ + if (buffer && buflen) { + /* if it's an INTERROGATE command, just pass the length + * of parameters to read, as data */ +#if CMD_DISCOVERY + if (cmd == ACX1xx_CMD_INTERROGATE) + memset_io(adev->cmd_area + 4, 0xAA, buflen); +#endif + /* adev->cmd_area points to PCI device's memory, not to RAM! */ + memcpy_toio(adev->cmd_area + 4, buffer, + (cmd == ACX1xx_CMD_INTERROGATE) ? 4 : buflen); + } + /* now write the actual command type */ + acxpci_write_cmd_type_status(adev, cmd, 0); + /* execute command */ + write_reg16(adev, IO_ACX_INT_TRIG, INT_TRIG_CMD); + write_flush(adev); + + /* wait for firmware to process command */ + + /* Ensure nonzero and not too large timeout. + ** Also converts e.g. 100->99, 200->199 + ** which is nice but not essential */ + cmd_timeout = (cmd_timeout-1) | 1; + if (unlikely(cmd_timeout > 1199)) + cmd_timeout = 1199; + /* clear CMD_COMPLETE bit. can be set only by IRQ handler: */ + adev->irq_status &= ~HOST_INT_CMD_COMPLETE; + + /* we schedule away sometimes (timeout can be large) */ + counter = cmd_timeout; + timeout = jiffies + cmd_timeout * HZ / 1000; + do { + if (!adev->irqs_active) { /* IRQ disabled: poll */ + irqtype = read_reg16(adev, IO_ACX_IRQ_STATUS_NON_DES); + if (irqtype & HOST_INT_CMD_COMPLETE) { + write_reg16(adev, IO_ACX_IRQ_ACK, + HOST_INT_CMD_COMPLETE); + break; + } + } else { /* Wait when IRQ will set the bit */ + irqtype = adev->irq_status; + if (irqtype & HOST_INT_CMD_COMPLETE) + break; + } + + if (counter % 8 == 0) { + if (time_after(jiffies, timeout)) { + counter = 0; + break; + } + /* we waited 8 iterations, no luck. Sleep 8 ms */ + acx_s_msleep(8); + } + } while (likely(--counter)); + + /* save state for debugging */ + cmd_status = acxpci_read_cmd_type_status(adev); + + /* put the card in IDLE state */ + acxpci_write_cmd_type_status(adev, 0, 0); + + if (!counter) { /* timed out! */ + printk("%s: "FUNC"(): timed out %s for CMD_COMPLETE. " + "irq bits:0x%04X irq_status:0x%04X timeout:%dms " + "cmd_status:%d (%s)\n", + devname, (adev->irqs_active) ? "waiting" : "polling", + irqtype, adev->irq_status, cmd_timeout, + cmd_status, acx_cmd_status_str(cmd_status)); + goto bad; + } else if (cmd_timeout - counter > 30) { /* if waited >30ms... */ + log(L_CTL|L_DEBUG, FUNC"(): %s for CMD_COMPLETE %dms. " + "count:%d. Please report\n", + (adev->irqs_active) ? "waited" : "polled", + cmd_timeout - counter, counter); + } + + if (1 != cmd_status) { /* it is not a 'Success' */ + printk("%s: "FUNC"(): cmd_status is not SUCCESS: %d (%s). " + "Took %dms of %d\n", + devname, cmd_status, acx_cmd_status_str(cmd_status), + cmd_timeout - counter, cmd_timeout); + /* zero out result buffer + * WARNING: this will trash stack in case of illegally large input + * length! */ + if (buffer && buflen) + memset(buffer, 0, buflen); + goto bad; + } + + /* read in result parameters if needed */ + if (buffer && buflen && (cmd == ACX1xx_CMD_INTERROGATE)) { + /* adev->cmd_area points to PCI device's memory, not to RAM! */ + memcpy_fromio(buffer, adev->cmd_area + 4, buflen); + if (acx_debug & L_DEBUG) { + printk("output buffer (len=%u): ", buflen); + acx_dump_bytes(buffer, buflen); + } + } +/* ok: */ + log(L_CTL, FUNC"(%s): took %ld jiffies to complete\n", + cmdstr, jiffies - start); + FN_EXIT1(OK); + return OK; + +bad: + /* Give enough info so that callers can avoid + ** printing their own diagnostic messages */ +#if ACX_DEBUG + printk("%s: "FUNC"(cmd:%s) FAILED\n", devname, cmdstr); +#else + printk("%s: "FUNC"(cmd:0x%04X) FAILED\n", devname, cmd); +#endif + dump_stack(); + FN_EXIT1(NOT_OK); + return NOT_OK; +} + + +/*********************************************************************** +*/ +#ifdef NONESSENTIAL_FEATURES +typedef struct device_id { + unsigned char id[6]; + char *descr; + char *type; +} device_id_t; + +static const device_id_t +device_ids[] = +{ + { + {'G', 'l', 'o', 'b', 'a', 'l'}, + NULL, + NULL, + }, + { + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + "uninitialized", + "SpeedStream SS1021 or Gigafast WF721-AEX" + }, + { + {0x80, 0x81, 0x82, 0x83, 0x84, 0x85}, + "non-standard", + "DrayTek Vigor 520" + }, + { + {'?', '?', '?', '?', '?', '?'}, + "non-standard", + "Level One WPC-0200" + }, + { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + "empty", + "DWL-650+ variant" + } +}; + +static void +acx_show_card_eeprom_id(acx_device_t *adev) +{ + unsigned char buffer[CARD_EEPROM_ID_SIZE]; + int i; + + memset(&buffer, 0, CARD_EEPROM_ID_SIZE); + /* use direct EEPROM access */ + for (i = 0; i < CARD_EEPROM_ID_SIZE; i++) { + if (OK != acxpci_read_eeprom_byte(adev, + ACX100_EEPROM_ID_OFFSET + i, + &buffer[i])) { + printk("acx: reading EEPROM FAILED\n"); + break; + } + } + + for (i = 0; i < VEC_SIZE(device_ids); i++) { + if (!memcmp(&buffer, device_ids[i].id, CARD_EEPROM_ID_SIZE)) { + if (device_ids[i].descr) { + printk("acx: EEPROM card ID string check " + "found %s card ID: is this %s?\n", + device_ids[i].descr, device_ids[i].type); + } + break; + } + } + if (i == VEC_SIZE(device_ids)) { + printk("acx: EEPROM card ID string check found " + "unknown card: expected 'Global', got '%.*s\'. " + "Please report\n", CARD_EEPROM_ID_SIZE, buffer); + } +} +#endif /* NONESSENTIAL_FEATURES */ + + +/*********************************************************************** +** acxpci_free_desc_queues +** +** Releases the queues that have been allocated, the +** others have been initialised to NULL so this +** function can be used if only part of the queues were allocated. +*/ + +static inline void +free_coherent(struct pci_dev *hwdev, size_t size, + void *vaddr, dma_addr_t dma_handle) +{ + dma_free_coherent(hwdev == NULL ? NULL : &hwdev->dev, + size, vaddr, dma_handle); +} + +void +acxpci_free_desc_queues(acx_device_t *adev) +{ +#define ACX_FREE_QUEUE(size, ptr, phyaddr) \ + if (ptr) { \ + free_coherent(0, size, ptr, phyaddr); \ + ptr = NULL; \ + size = 0; \ + } + + FN_ENTER; + + ACX_FREE_QUEUE(adev->txhostdesc_area_size, adev->txhostdesc_start, adev->txhostdesc_startphy); + ACX_FREE_QUEUE(adev->txbuf_area_size, adev->txbuf_start, adev->txbuf_startphy); + + adev->txdesc_start = NULL; + + ACX_FREE_QUEUE(adev->rxhostdesc_area_size, adev->rxhostdesc_start, adev->rxhostdesc_startphy); + ACX_FREE_QUEUE(adev->rxbuf_area_size, adev->rxbuf_start, adev->rxbuf_startphy); + + adev->rxdesc_start = NULL; + + FN_EXIT0; +} + + +/*********************************************************************** +** acxpci_s_delete_dma_regions +*/ +static void +acxpci_s_delete_dma_regions(acx_device_t *adev) +{ + unsigned long flags; + + FN_ENTER; + /* disable radio Tx/Rx. Shouldn't we use the firmware commands + * here instead? Or are we that much down the road that it's no + * longer possible here? */ + write_reg16(adev, IO_ACX_ENABLE, 0); + + acx_s_msleep(100); + + acx_lock(adev, flags); + acxpci_free_desc_queues(adev); + acx_unlock(adev, flags); + + FN_EXIT0; +} + + +/*********************************************************************** +** acxpci_e_probe +** +** Probe routine called when a PCI device w/ matching ID is found. +** Here's the sequence: +** - Allocate the PCI resources. +** - Read the PCMCIA attribute memory to make sure we have a WLAN card +** - Reset the MAC +** - Initialize the dev and wlan data +** - Initialize the MAC +** +** pdev - ptr to pci device structure containing info about pci configuration +** id - ptr to the device id entry that matched this device +*/ +static const u16 +IO_ACX100[] = +{ + 0x0000, /* IO_ACX_SOFT_RESET */ + + 0x0014, /* IO_ACX_SLV_MEM_ADDR */ + 0x0018, /* IO_ACX_SLV_MEM_DATA */ + 0x001c, /* IO_ACX_SLV_MEM_CTL */ + 0x0020, /* IO_ACX_SLV_END_CTL */ + + 0x0034, /* IO_ACX_FEMR */ + + 0x007c, /* IO_ACX_INT_TRIG */ + 0x0098, /* IO_ACX_IRQ_MASK */ + 0x00a4, /* IO_ACX_IRQ_STATUS_NON_DES */ + 0x00a8, /* IO_ACX_IRQ_STATUS_CLEAR */ + 0x00ac, /* IO_ACX_IRQ_ACK */ + 0x00b0, /* IO_ACX_HINT_TRIG */ + + 0x0104, /* IO_ACX_ENABLE */ + + 0x0250, /* IO_ACX_EEPROM_CTL */ + 0x0254, /* IO_ACX_EEPROM_ADDR */ + 0x0258, /* IO_ACX_EEPROM_DATA */ + 0x025c, /* IO_ACX_EEPROM_CFG */ + + 0x0268, /* IO_ACX_PHY_ADDR */ + 0x026c, /* IO_ACX_PHY_DATA */ + 0x0270, /* IO_ACX_PHY_CTL */ + + 0x0290, /* IO_ACX_GPIO_OE */ + + 0x0298, /* IO_ACX_GPIO_OUT */ + + 0x02a4, /* IO_ACX_CMD_MAILBOX_OFFS */ + 0x02a8, /* IO_ACX_INFO_MAILBOX_OFFS */ + 0x02ac, /* IO_ACX_EEPROM_INFORMATION */ + + 0x02d0, /* IO_ACX_EE_START */ + 0x02d4, /* IO_ACX_SOR_CFG */ + 0x02d8 /* IO_ACX_ECPU_CTRL */ +}; + +static const u16 +IO_ACX111[] = +{ + 0x0000, /* IO_ACX_SOFT_RESET */ + + 0x0014, /* IO_ACX_SLV_MEM_ADDR */ + 0x0018, /* IO_ACX_SLV_MEM_DATA */ + 0x001c, /* IO_ACX_SLV_MEM_CTL */ + 0x0020, /* IO_ACX_SLV_END_CTL */ + + 0x0034, /* IO_ACX_FEMR */ + + 0x00b4, /* IO_ACX_INT_TRIG */ + 0x00d4, /* IO_ACX_IRQ_MASK */ + /* we do mean NON_DES (0xf0), not NON_DES_MASK which is at 0xe0: */ + 0x00f0, /* IO_ACX_IRQ_STATUS_NON_DES */ + 0x00e4, /* IO_ACX_IRQ_STATUS_CLEAR */ + 0x00e8, /* IO_ACX_IRQ_ACK */ + 0x00ec, /* IO_ACX_HINT_TRIG */ + + 0x01d0, /* IO_ACX_ENABLE */ + + 0x0338, /* IO_ACX_EEPROM_CTL */ + 0x033c, /* IO_ACX_EEPROM_ADDR */ + 0x0340, /* IO_ACX_EEPROM_DATA */ + 0x0344, /* IO_ACX_EEPROM_CFG */ + + 0x0350, /* IO_ACX_PHY_ADDR */ + 0x0354, /* IO_ACX_PHY_DATA */ + 0x0358, /* IO_ACX_PHY_CTL */ + + 0x0374, /* IO_ACX_GPIO_OE */ + + 0x037c, /* IO_ACX_GPIO_OUT */ + + 0x0388, /* IO_ACX_CMD_MAILBOX_OFFS */ + 0x038c, /* IO_ACX_INFO_MAILBOX_OFFS */ + 0x0390, /* IO_ACX_EEPROM_INFORMATION */ + + 0x0100, /* IO_ACX_EE_START */ + 0x0104, /* IO_ACX_SOR_CFG */ + 0x0108, /* IO_ACX_ECPU_CTRL */ +}; + +static void +dummy_netdev_init(struct net_device *ndev) {} + +static int __devinit +acxpci_e_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + acx111_ie_configoption_t co; + unsigned long mem_region1 = 0; + unsigned long mem_region2 = 0; + unsigned long mem_region1_size; + unsigned long mem_region2_size; + unsigned long phymem1; + unsigned long phymem2; + void *mem1 = NULL; + void *mem2 = NULL; + acx_device_t *adev = NULL; + struct net_device *ndev = NULL; + const char *chip_name; + int result = -EIO; + int err; + u8 chip_type; + + FN_ENTER; + + /* Enable the PCI device */ + if (pci_enable_device(pdev)) { + printk("acx: pci_enable_device() FAILED\n"); + result = -ENODEV; + goto fail_pci_enable_device; + } + + /* enable busmastering (required for CardBus) */ + pci_set_master(pdev); + + /* FIXME: prism54 calls pci_set_mwi() here, + * should we do/support the same? */ + + /* chiptype is u8 but id->driver_data is ulong + ** Works for now (possible values are 1 and 2) */ + chip_type = (u8)id->driver_data; + /* acx100 and acx111 have different PCI memory regions */ + if (chip_type == CHIPTYPE_ACX100) { + chip_name = "ACX100"; + mem_region1 = PCI_ACX100_REGION1; + mem_region1_size = PCI_ACX100_REGION1_SIZE; + + mem_region2 = PCI_ACX100_REGION2; + mem_region2_size = PCI_ACX100_REGION2_SIZE; + } else if (chip_type == CHIPTYPE_ACX111) { + chip_name = "ACX111"; + mem_region1 = PCI_ACX111_REGION1; + mem_region1_size = PCI_ACX111_REGION1_SIZE; + + mem_region2 = PCI_ACX111_REGION2; + mem_region2_size = PCI_ACX111_REGION2_SIZE; + } else { + printk("acx: unknown chip type 0x%04X\n", chip_type); + goto fail_unknown_chiptype; + } + + /* Figure out our resources */ + phymem1 = pci_resource_start(pdev, mem_region1); + phymem2 = pci_resource_start(pdev, mem_region2); + if (!request_mem_region(phymem1, pci_resource_len(pdev, mem_region1), "acx_1")) { + printk("acx: cannot reserve PCI memory region 1 (are you sure " + "you have CardBus support in kernel?)\n"); + goto fail_request_mem_region1; + } + if (!request_mem_region(phymem2, pci_resource_len(pdev, mem_region2), "acx_2")) { + printk("acx: cannot reserve PCI memory region 2\n"); + goto fail_request_mem_region2; + } + + /* this used to be ioremap(), but ioremap_nocache() + * is much less risky, right? (and slower?) + * FIXME: we may want to go back to cached variant if it's + * certain that our code really properly handles + * cached operation (memory barriers, volatile?, ...) + * (but always keep this comment here regardless!) + * Possibly make this a driver config setting? */ + + mem1 = ioremap(phymem1, mem_region1_size); + if (!mem1) { + printk("acx: ioremap() FAILED\n"); + goto fail_ioremap1; + } + mem2 = ioremap(phymem2, mem_region2_size); + if (!mem2) { + printk("acx: ioremap() #2 FAILED\n"); + goto fail_ioremap2; + } + + printk("acx: found %s-based wireless network card at %s, irq:%d, " + "phymem1:0x%lX, phymem2:0x%lX, mem1:0x%p, mem1_size:%ld, " + "mem2:0x%p, mem2_size:%ld\n", + chip_name, pci_name(pdev), pdev->irq, phymem1, phymem2, + mem1, mem_region1_size, + mem2, mem_region2_size); + log(L_ANY, "initial debug setting is 0x%04X\n", acx_debug); + + if (0 == pdev->irq) { + printk("acx: can't use IRQ 0\n"); + goto fail_irq; + } + + ndev = alloc_netdev(sizeof(*adev), "wlan%d", dummy_netdev_init); + /* (NB: memsets to 0 entire area) */ + if (!ndev) { + printk("acx: no memory for netdevice struct\n"); + goto fail_alloc_netdev; + } + + ether_setup(ndev); + ndev->open = &acxpci_e_open; + ndev->stop = &acxpci_e_close; + ndev->hard_start_xmit = &acx_i_start_xmit; + ndev->get_stats = &acx_e_get_stats; +#if IW_HANDLER_VERSION <= 5 + ndev->get_wireless_stats = &acx_e_get_wireless_stats; +#endif + ndev->wireless_handlers = (struct iw_handler_def *)&acx_ioctl_handler_def; + ndev->set_multicast_list = &acxpci_i_set_multicast_list; + ndev->tx_timeout = &acxpci_i_tx_timeout; + ndev->change_mtu = &acx_e_change_mtu; + ndev->watchdog_timeo = 4 * HZ; + ndev->irq = pdev->irq; + ndev->base_addr = pci_resource_start(pdev, 0); + + adev = ndev2adev(ndev); + spin_lock_init(&adev->lock); /* initial state: unlocked */ + /* We do not start with downed sem: we want PARANOID_LOCKING to work */ + sema_init(&adev->sem, 1); /* initial state: 1 (upped) */ + /* since nobody can see new netdev yet, we can as well + ** just _presume_ that we're under sem (instead of actually taking it): */ + /* acx_sem_lock(adev); */ + adev->pdev = pdev; + adev->ndev = ndev; + adev->dev_type = DEVTYPE_PCI; + adev->chip_type = chip_type; + adev->chip_name = chip_name; + adev->io = (CHIPTYPE_ACX100 == chip_type) ? IO_ACX100 : IO_ACX111; + adev->membase = phymem1; + adev->iobase = mem1; + adev->membase2 = phymem2; + adev->iobase2 = mem2; + /* to find crashes due to weird driver access + * to unconfigured interface (ifup) */ + adev->mgmt_timer.function = (void (*)(unsigned long))0x0000dead; + +#ifdef NONESSENTIAL_FEATURES + acx_show_card_eeprom_id(adev); +#endif /* NONESSENTIAL_FEATURES */ + +#ifdef SET_MODULE_OWNER + SET_MODULE_OWNER(ndev); +#endif + SET_NETDEV_DEV(ndev, &pdev->dev); + + log(L_IRQ|L_INIT, "using IRQ %d\n", pdev->irq); + + /* need to be able to restore PCI state after a suspend */ + pci_save_state(pdev); + pci_set_drvdata(pdev, ndev); + + /* ok, pci setup is finished, now start initializing the card */ + + /* NB: read_reg() reads may return bogus data before reset_dev(), + * since the firmware which directly controls large parts of the I/O + * registers isn't initialized yet. + * acx100 seems to be more affected than acx111 */ + if (OK != acxpci_s_reset_dev(adev)) + goto fail_reset; + + if (IS_ACX100(adev)) { + /* ACX100: configopt struct in cmd mailbox - directly after reset */ + memcpy_fromio(&co, adev->cmd_area, sizeof(co)); + } + + if (OK != acx_s_init_mac(adev)) + goto fail_init_mac; + + if (IS_ACX111(adev)) { + /* ACX111: configopt struct needs to be queried after full init */ + acx_s_interrogate(adev, &co, ACX111_IE_CONFIG_OPTIONS); + } + +/* TODO: merge them into one function, they are called just once and are the same for pci & usb */ + if (OK != acxpci_read_eeprom_byte(adev, 0x05, &adev->eeprom_version)) + goto fail_read_eeprom_version; + + acx_s_parse_configoption(adev, &co); + acx_s_set_defaults(adev); + acx_s_get_firmware_version(adev); /* needs to be after acx_s_init_mac() */ + acx_display_hardware_details(adev); + + /* Register the card, AFTER everything else has been set up, + * since otherwise an ioctl could step on our feet due to + * firmware operations happening in parallel or uninitialized data */ + err = register_netdev(ndev); + if (OK != err) { + printk("acx: register_netdev() FAILED: %d\n", err); + goto fail_register_netdev; + } + + acx_proc_register_entries(ndev); + + /* Now we have our device, so make sure the kernel doesn't try + * to send packets even though we're not associated to a network yet */ + acx_stop_queue(ndev, "on probe"); + acx_carrier_off(ndev, "on probe"); + + /* after register_netdev() userspace may start working with dev + * (in particular, on other CPUs), we only need to up the sem */ + /* acx_sem_unlock(adev); */ + + printk("acx "ACX_RELEASE": net device %s, driver compiled " + "against wireless extensions %d and Linux %s\n", + ndev->name, WIRELESS_EXT, UTS_RELEASE); + +#if CMD_DISCOVERY + great_inquisitor(adev); +#endif + + result = OK; + goto done; + + /* error paths: undo everything in reverse order... */ + +fail_register_netdev: + + acxpci_s_delete_dma_regions(adev); + pci_set_drvdata(pdev, NULL); + +fail_init_mac: +fail_read_eeprom_version: +fail_reset: + + free_netdev(ndev); +fail_alloc_netdev: +fail_irq: + + iounmap(mem2); +fail_ioremap2: + + iounmap(mem1); +fail_ioremap1: + + release_mem_region(pci_resource_start(pdev, mem_region2), + pci_resource_len(pdev, mem_region2)); +fail_request_mem_region2: + + release_mem_region(pci_resource_start(pdev, mem_region1), + pci_resource_len(pdev, mem_region1)); +fail_request_mem_region1: +fail_unknown_chiptype: + + pci_disable_device(pdev); +fail_pci_enable_device: + + pci_set_power_state(pdev, PCI_D3hot); + +done: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acxpci_e_remove +** +** Shut device down (if not hot unplugged) +** and deallocate PCI resources for the acx chip. +** +** pdev - ptr to PCI device structure containing info about pci configuration +*/ +static void __devexit +acxpci_e_remove(struct pci_dev *pdev) +{ + struct net_device *ndev; + acx_device_t *adev; + unsigned long mem_region1, mem_region2; + unsigned long flags; + + FN_ENTER; + + ndev = (struct net_device*) pci_get_drvdata(pdev); + if (!ndev) { + log(L_DEBUG, "%s: card is unused. Skipping any release code\n", + __func__); + goto end; + } + + adev = ndev2adev(ndev); + + /* If device wasn't hot unplugged... */ + if (adev_present(adev)) { + + acx_sem_lock(adev); + + /* disable both Tx and Rx to shut radio down properly */ + acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0); + acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0); + +#ifdef REDUNDANT + /* put the eCPU to sleep to save power + * Halting is not possible currently, + * since not supported by all firmware versions */ + acx_s_issue_cmd(adev, ACX100_CMD_SLEEP, NULL, 0); +#endif + acx_lock(adev, flags); + /* disable power LED to save power :-) */ + log(L_INIT, "switching off power LED to save power\n"); + acxpci_l_power_led(adev, 0); + /* stop our eCPU */ + if (IS_ACX111(adev)) { + /* FIXME: does this actually keep halting the eCPU? + * I don't think so... + */ + acxpci_l_reset_mac(adev); + } else { + u16 temp; + /* halt eCPU */ + temp = read_reg16(adev, IO_ACX_ECPU_CTRL) | 0x1; + write_reg16(adev, IO_ACX_ECPU_CTRL, temp); + write_flush(adev); + } + acx_unlock(adev, flags); + + acx_sem_unlock(adev); + } + + /* unregister the device to not let the kernel + * (e.g. ioctls) access a half-deconfigured device + * NB: this will cause acxpci_e_close() to be called, + * thus we shouldn't call it under sem! */ + log(L_INIT, "removing device %s\n", ndev->name); + unregister_netdev(ndev); + + /* unregister_netdev ensures that no references to us left. + * For paranoid reasons we continue to follow the rules */ + acx_sem_lock(adev); + + if (adev->dev_state_mask & ACX_STATE_IFACE_UP) { + acxpci_s_down(ndev); + CLEAR_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP); + } + + acx_proc_unregister_entries(ndev); + + if (IS_ACX100(adev)) { + mem_region1 = PCI_ACX100_REGION1; + mem_region2 = PCI_ACX100_REGION2; + } else { + mem_region1 = PCI_ACX111_REGION1; + mem_region2 = PCI_ACX111_REGION2; + } + + /* finally, clean up PCI bus state */ + acxpci_s_delete_dma_regions(adev); + if (adev->iobase) iounmap(adev->iobase); + if (adev->iobase2) iounmap(adev->iobase2); + release_mem_region(pci_resource_start(pdev, mem_region1), + pci_resource_len(pdev, mem_region1)); + release_mem_region(pci_resource_start(pdev, mem_region2), + pci_resource_len(pdev, mem_region2)); + pci_disable_device(pdev); + + /* remove dev registration */ + pci_set_drvdata(pdev, NULL); + + acx_sem_unlock(adev); + + /* Free netdev (quite late, + * since otherwise we might get caught off-guard + * by a netdev timeout handler execution + * expecting to see a working dev...) */ + free_netdev(ndev); + + /* put device into ACPI D3 mode (shutdown) */ + pci_set_power_state(pdev, PCI_D3hot); + +end: + FN_EXIT0; +} + + +/*********************************************************************** +** TODO: PM code needs to be fixed / debugged / tested. +*/ +#ifdef CONFIG_PM +static int +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) +acxpci_e_suspend(struct pci_dev *pdev, pm_message_t state) +#else +acxpci_e_suspend(struct pci_dev *pdev, u32 state) +#endif +{ + struct net_device *ndev = pci_get_drvdata(pdev); + acx_device_t *adev; + + FN_ENTER; + printk("acx: suspend handler is experimental!\n"); + printk("sus: dev %p\n", ndev); + + if (!netif_running(ndev)) + goto end; + + adev = ndev2adev(ndev); + printk("sus: adev %p\n", adev); + + acx_sem_lock(adev); + + netif_device_detach(ndev); /* this one cannot sleep */ + acxpci_s_down(ndev); + /* down() does not set it to 0xffff, but here we really want that */ + write_reg16(adev, IO_ACX_IRQ_MASK, 0xffff); + write_reg16(adev, IO_ACX_FEMR, 0x0); + acxpci_s_delete_dma_regions(adev); + pci_save_state(pdev); + pci_set_power_state(pdev, PCI_D3hot); + + acx_sem_unlock(adev); +end: + FN_EXIT0; + return OK; +} + + +static int +acxpci_e_resume(struct pci_dev *pdev) +{ + struct net_device *ndev = pci_get_drvdata(pdev); + acx_device_t *adev; + + FN_ENTER; + + printk("acx: resume handler is experimental!\n"); + printk("rsm: got dev %p\n", ndev); + + if (!netif_running(ndev)) + goto end; + + adev = ndev2adev(ndev); + printk("rsm: got adev %p\n", adev); + + acx_sem_lock(adev); + + pci_set_power_state(pdev, PCI_D0); + printk("rsm: power state PCI_D0 set\n"); + pci_restore_state(pdev); + printk("rsm: PCI state restored\n"); + + if (OK != acxpci_s_reset_dev(adev)) + goto end_unlock; + printk("rsm: device reset done\n"); + if (OK != acx_s_init_mac(adev)) + goto end_unlock; + printk("rsm: init MAC done\n"); + + acxpci_s_up(ndev); + printk("rsm: acx up done\n"); + + /* now even reload all card parameters as they were before suspend, + * and possibly be back in the network again already :-) */ + if (ACX_STATE_IFACE_UP & adev->dev_state_mask) { + adev->set_mask = GETSET_ALL; + acx_s_update_card_settings(adev); + printk("rsm: settings updated\n"); + } + netif_device_attach(ndev); + printk("rsm: device attached\n"); + +end_unlock: + acx_sem_unlock(adev); +end: + /* we need to return OK here anyway, right? */ + FN_EXIT0; + return OK; +} +#endif /* CONFIG_PM */ + + +/*********************************************************************** +** acxpci_s_up +** +** This function is called by acxpci_e_open (when ifconfig sets the device as up) +** +** Side effects: +** - Enables on-card interrupt requests +** - calls acx_s_start +*/ + +static void +enable_acx_irq(acx_device_t *adev) +{ + FN_ENTER; + write_reg16(adev, IO_ACX_IRQ_MASK, adev->irq_mask); + write_reg16(adev, IO_ACX_FEMR, 0x8000); + adev->irqs_active = 1; + FN_EXIT0; +} + +static void +acxpci_s_up(struct net_device *ndev) +{ + acx_device_t *adev = ndev2adev(ndev); + unsigned long flags; + + FN_ENTER; + + acx_lock(adev, flags); + enable_acx_irq(adev); + acx_unlock(adev, flags); + + /* acx fw < 1.9.3.e has a hardware timer, and older drivers + ** used to use it. But we don't do that anymore, our OS + ** has reliable software timers */ + init_timer(&adev->mgmt_timer); + adev->mgmt_timer.function = acx_i_timer; + adev->mgmt_timer.data = (unsigned long)adev; + + /* Need to set ACX_STATE_IFACE_UP first, or else + ** timer won't be started by acx_set_status() */ + SET_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP); + switch (adev->mode) { + case ACX_MODE_0_ADHOC: + case ACX_MODE_2_STA: + /* actual scan cmd will happen in start() */ + acx_set_status(adev, ACX_STATUS_1_SCANNING); break; + case ACX_MODE_3_AP: + case ACX_MODE_MONITOR: + acx_set_status(adev, ACX_STATUS_4_ASSOCIATED); break; + } + + acx_s_start(adev); + + FN_EXIT0; +} + + +/*********************************************************************** +** acxpci_s_down +** +** NB: device may be already hot unplugged if called from acxpci_e_remove() +** +** Disables on-card interrupt request, stops softirq and timer, stops queue, +** sets status == STOPPED +*/ + +static void +disable_acx_irq(acx_device_t *adev) +{ + FN_ENTER; + + /* I guess mask is not 0xffff because acx100 won't signal + ** cmd completion then (needed for ifup). + ** Someone with acx100 please confirm */ + write_reg16(adev, IO_ACX_IRQ_MASK, adev->irq_mask_off); + write_reg16(adev, IO_ACX_FEMR, 0x0); + adev->irqs_active = 0; + FN_EXIT0; +} + +static void +acxpci_s_down(struct net_device *ndev) +{ + acx_device_t *adev = ndev2adev(ndev); + unsigned long flags; + + FN_ENTER; + + /* Disable IRQs first, so that IRQs cannot race with us */ + /* then wait until interrupts have finished executing on other CPUs */ + acx_lock(adev, flags); + disable_acx_irq(adev); + synchronize_irq(adev->pdev->irq); + acx_unlock(adev, flags); + + /* we really don't want to have an asynchronous tasklet disturb us + ** after something vital for its job has been shut down, so + ** end all remaining work now. + ** + ** NB: carrier_off (done by set_status below) would lead to + ** not yet fully understood deadlock in FLUSH_SCHEDULED_WORK(). + ** That's why we do FLUSH first. + ** + ** NB2: we have a bad locking bug here: FLUSH_SCHEDULED_WORK() + ** waits for acx_e_after_interrupt_task to complete if it is running + ** on another CPU, but acx_e_after_interrupt_task + ** will sleep on sem forever, because it is taken by us! + ** Work around that by temporary sem unlock. + ** This will fail miserably if we'll be hit by concurrent + ** iwconfig or something in between. TODO! */ + acx_sem_unlock(adev); + FLUSH_SCHEDULED_WORK(); + acx_sem_lock(adev); + + /* This is possible: + ** FLUSH_SCHEDULED_WORK -> acx_e_after_interrupt_task -> + ** -> set_status(ASSOCIATED) -> wake_queue() + ** That's why we stop queue _after_ FLUSH_SCHEDULED_WORK + ** lock/unlock is just paranoia, maybe not needed */ + acx_lock(adev, flags); + acx_stop_queue(ndev, "on ifdown"); + acx_set_status(adev, ACX_STATUS_0_STOPPED); + acx_unlock(adev, flags); + + /* kernel/timer.c says it's illegal to del_timer_sync() + ** a timer which restarts itself. We guarantee this cannot + ** ever happen because acx_i_timer() never does this if + ** status is ACX_STATUS_0_STOPPED */ + del_timer_sync(&adev->mgmt_timer); + + FN_EXIT0; +} + + +/*********************************************************************** +** acxpci_e_open +** +** Called as a result of SIOCSIFFLAGS ioctl changing the flags bit IFF_UP +** from clear to set. In other words: ifconfig up. +** +** Returns: +** 0 success +** >0 f/w reported error +** <0 driver reported error +*/ +static int +acxpci_e_open(struct net_device *ndev) +{ + acx_device_t *adev = ndev2adev(ndev); + int result = OK; + + FN_ENTER; + + acx_sem_lock(adev); + + acx_init_task_scheduler(adev); + +/* TODO: pci_set_power_state(pdev, PCI_D0); ? */ + + /* request shared IRQ handler */ + if (request_irq(ndev->irq, acxpci_i_interrupt, IRQF_SHARED, ndev->name, ndev)) { + printk("%s: request_irq FAILED\n", ndev->name); + result = -EAGAIN; + goto done; + } + log(L_DEBUG|L_IRQ, "request_irq %d successful\n", ndev->irq); + + /* ifup device */ + acxpci_s_up(ndev); + + /* We don't currently have to do anything else. + * The setup of the MAC should be subsequently completed via + * the mlme commands. + * Higher layers know we're ready from dev->start==1 and + * dev->tbusy==0. Our rx path knows to pass up received/ + * frames because of dev->flags&IFF_UP is true. + */ +done: + acx_sem_unlock(adev); + + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acxpci_e_close +** +** Called as a result of SIOCSIIFFLAGS ioctl changing the flags bit IFF_UP +** from set to clear. I.e. called by "ifconfig DEV down" +** +** Returns: +** 0 success +** >0 f/w reported error +** <0 driver reported error +*/ +static int +acxpci_e_close(struct net_device *ndev) +{ + acx_device_t *adev = ndev2adev(ndev); + + FN_ENTER; + + acx_sem_lock(adev); + + /* ifdown device */ + CLEAR_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP); + if (netif_device_present(ndev)) { + acxpci_s_down(ndev); + } + + /* disable all IRQs, release shared IRQ handler */ + write_reg16(adev, IO_ACX_IRQ_MASK, 0xffff); + write_reg16(adev, IO_ACX_FEMR, 0x0); + free_irq(ndev->irq, ndev); + +/* TODO: pci_set_power_state(pdev, PCI_D3hot); ? */ + + /* We currently don't have to do anything else. + * Higher layers know we're not ready from dev->start==0 and + * dev->tbusy==1. Our rx path knows to not pass up received + * frames because of dev->flags&IFF_UP is false. + */ + acx_sem_unlock(adev); + + log(L_INIT, "closed device\n"); + FN_EXIT0; + return OK; +} + + +/*********************************************************************** +** acxpci_i_tx_timeout +** +** Called from network core. Must not sleep! +*/ +static void +acxpci_i_tx_timeout(struct net_device *ndev) +{ + acx_device_t *adev = ndev2adev(ndev); + unsigned long flags; + unsigned int tx_num_cleaned; + + FN_ENTER; + + acx_lock(adev, flags); + + /* clean processed tx descs, they may have been completely full */ + tx_num_cleaned = acxpci_l_clean_txdesc(adev); + + /* nothing cleaned, yet (almost) no free buffers available? + * --> clean all tx descs, no matter which status!! + * Note that I strongly suspect that doing emergency cleaning + * may confuse the firmware. This is a last ditch effort to get + * ANYTHING to work again... + * + * TODO: it's best to simply reset & reinit hw from scratch... + */ + if ((adev->tx_free <= TX_EMERG_CLEAN) && (tx_num_cleaned == 0)) { + printk("%s: FAILED to free any of the many full tx buffers. " + "Switching to emergency freeing. " + "Please report!\n", ndev->name); + acxpci_l_clean_txdesc_emergency(adev); + } + + if (acx_queue_stopped(ndev) && (ACX_STATUS_4_ASSOCIATED == adev->status)) + acx_wake_queue(ndev, "after tx timeout"); + + /* stall may have happened due to radio drift, so recalib radio */ + acx_schedule_task(adev, ACX_AFTER_IRQ_CMD_RADIO_RECALIB); + + /* do unimportant work last */ + printk("%s: tx timeout!\n", ndev->name); + adev->stats.tx_errors++; + + acx_unlock(adev, flags); + + FN_EXIT0; +} + + +/*********************************************************************** +** acxpci_i_set_multicast_list +** FIXME: most likely needs refinement +*/ +static void +acxpci_i_set_multicast_list(struct net_device *ndev) +{ + acx_device_t *adev = ndev2adev(ndev); + unsigned long flags; + + FN_ENTER; + + acx_lock(adev, flags); + + /* firmwares don't have allmulti capability, + * so just use promiscuous mode instead in this case. */ + if (ndev->flags & (IFF_PROMISC|IFF_ALLMULTI)) { + SET_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS); + CLEAR_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI); + SET_BIT(adev->set_mask, SET_RXCONFIG); + /* let kernel know in case *we* needed to set promiscuous */ + ndev->flags |= (IFF_PROMISC|IFF_ALLMULTI); + } else { + CLEAR_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS); + SET_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI); + SET_BIT(adev->set_mask, SET_RXCONFIG); + ndev->flags &= ~(IFF_PROMISC|IFF_ALLMULTI); + } + + /* cannot update card settings directly here, atomic context */ + acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG); + + acx_unlock(adev, flags); + + FN_EXIT0; +} + + +/*************************************************************** +** acxpci_l_process_rxdesc +** +** Called directly and only from the IRQ handler +*/ + +#if !ACX_DEBUG +static inline void log_rxbuffer(const acx_device_t *adev) {} +#else +static void +log_rxbuffer(const acx_device_t *adev) +{ + register const struct rxhostdesc *rxhostdesc; + int i; + /* no FN_ENTER here, we don't want that */ + + rxhostdesc = adev->rxhostdesc_start; + if (unlikely(!rxhostdesc)) return; + for (i = 0; i < RX_CNT; i++) { + if ((rxhostdesc->Ctl_16 & cpu_to_le16(DESC_CTL_HOSTOWN)) + && (rxhostdesc->Status & cpu_to_le32(DESC_STATUS_FULL))) + printk("rx: buf %d full\n", i); + rxhostdesc++; + } +} +#endif + +static void +acxpci_l_process_rxdesc(acx_device_t *adev) +{ + register rxhostdesc_t *hostdesc; + unsigned count, tail; + + FN_ENTER; + + if (unlikely(acx_debug & L_BUFR)) + log_rxbuffer(adev); + + /* First, have a loop to determine the first descriptor that's + * full, just in case there's a mismatch between our current + * rx_tail and the full descriptor we're supposed to handle. */ + tail = adev->rx_tail; + count = RX_CNT; + while (1) { + hostdesc = &adev->rxhostdesc_start[tail]; + /* advance tail regardless of outcome of the below test */ + tail = (tail + 1) % RX_CNT; + + if ((hostdesc->Ctl_16 & cpu_to_le16(DESC_CTL_HOSTOWN)) + && (hostdesc->Status & cpu_to_le32(DESC_STATUS_FULL))) + break; /* found it! */ + + if (unlikely(!--count)) /* hmm, no luck: all descs empty, bail out */ + goto end; + } + + /* now process descriptors, starting with the first we figured out */ + while (1) { + log(L_BUFR, "rx: tail=%u Ctl_16=%04X Status=%08X\n", + tail, hostdesc->Ctl_16, hostdesc->Status); + + acx_l_process_rxbuf(adev, hostdesc->data); + + hostdesc->Status = 0; + /* flush all writes before adapter sees CTL_HOSTOWN change */ + wmb(); + /* Host no longer owns this, needs to be LAST */ + CLEAR_BIT(hostdesc->Ctl_16, cpu_to_le16(DESC_CTL_HOSTOWN)); + + /* ok, descriptor is handled, now check the next descriptor */ + hostdesc = &adev->rxhostdesc_start[tail]; + + /* if next descriptor is empty, then bail out */ + if (!(hostdesc->Ctl_16 & cpu_to_le16(DESC_CTL_HOSTOWN)) + || !(hostdesc->Status & cpu_to_le32(DESC_STATUS_FULL))) + break; + + tail = (tail + 1) % RX_CNT; + } +end: + adev->rx_tail = tail; + FN_EXIT0; +} + + +/*********************************************************************** +** acxpci_i_interrupt +** +** IRQ handler (atomic context, must not sleep, blah, blah) +*/ + +/* scan is complete. all frames now on the receive queue are valid */ +#define INFO_SCAN_COMPLETE 0x0001 +#define INFO_WEP_KEY_NOT_FOUND 0x0002 +/* hw has been reset as the result of a watchdog timer timeout */ +#define INFO_WATCH_DOG_RESET 0x0003 +/* failed to send out NULL frame from PS mode notification to AP */ +/* recommended action: try entering 802.11 PS mode again */ +#define INFO_PS_FAIL 0x0004 +/* encryption/decryption process on a packet failed */ +#define INFO_IV_ICV_FAILURE 0x0005 + +/* Info mailbox format: +2 bytes: type +2 bytes: status +more bytes may follow + rumors say about status: + 0x0000 info available (set by hw) + 0x0001 information received (must be set by host) + 0x1000 info available, mailbox overflowed (messages lost) (set by hw) + but in practice we've seen: + 0x9000 when we did not set status to 0x0001 on prev message + 0x1001 when we did set it + 0x0000 was never seen + conclusion: this is really a bitfield: + 0x1000 is 'info available' bit + 'mailbox overflowed' bit is 0x8000, not 0x1000 + value of 0x0000 probably means that there are no messages at all + P.S. I dunno how in hell hw is supposed to notice that messages are lost - + it does NOT clear bit 0x0001, and this bit will probably stay forever set + after we set it once. Let's hope this will be fixed in firmware someday +*/ + +static void +handle_info_irq(acx_device_t *adev) +{ +#if ACX_DEBUG + static const char * const info_type_msg[] = { + "(unknown)", + "scan complete", + "WEP key not found", + "internal watchdog reset was done", + "failed to send powersave (NULL frame) notification to AP", + "encrypt/decrypt on a packet has failed", + "TKIP tx keys disabled", + "TKIP rx keys disabled", + "TKIP rx: key ID not found", + "???", + "???", + "???", + "???", + "???", + "???", + "???", + "TKIP IV value exceeds thresh" + }; +#endif + u32 info_type, info_status; + + info_type = readl(adev->info_area); + info_status = (info_type >> 16); + info_type = (u16)info_type; + + /* inform fw that we have read this info message */ + writel(info_type | 0x00010000, adev->info_area); + write_reg16(adev, IO_ACX_INT_TRIG, INT_TRIG_INFOACK); + write_flush(adev); + + log(L_CTL, "info_type:%04X info_status:%04X\n", + info_type, info_status); + + log(L_IRQ, "got Info IRQ: status %04X type %04X: %s\n", + info_status, info_type, + info_type_msg[(info_type >= VEC_SIZE(info_type_msg)) ? + 0 : info_type] + ); +} + + +static void +log_unusual_irq(u16 irqtype) { + /* + if (!printk_ratelimit()) + return; + */ + + printk("acx: got"); + if (irqtype & HOST_INT_RX_DATA) { + printk(" Rx_Data"); + } + /* HOST_INT_TX_COMPLETE */ + if (irqtype & HOST_INT_TX_XFER) { + printk(" Tx_Xfer"); + } + /* HOST_INT_RX_COMPLETE */ + if (irqtype & HOST_INT_DTIM) { + printk(" DTIM"); + } + if (irqtype & HOST_INT_BEACON) { + printk(" Beacon"); + } + if (irqtype & HOST_INT_TIMER) { + log(L_IRQ, " Timer"); + } + if (irqtype & HOST_INT_KEY_NOT_FOUND) { + printk(" Key_Not_Found"); + } + if (irqtype & HOST_INT_IV_ICV_FAILURE) { + printk(" IV_ICV_Failure (crypto)"); + } + /* HOST_INT_CMD_COMPLETE */ + /* HOST_INT_INFO */ + if (irqtype & HOST_INT_OVERFLOW) { + printk(" Overflow"); + } + if (irqtype & HOST_INT_PROCESS_ERROR) { + printk(" Process_Error"); + } + /* HOST_INT_SCAN_COMPLETE */ + if (irqtype & HOST_INT_FCS_THRESHOLD) { + printk(" FCS_Threshold"); + } + if (irqtype & HOST_INT_UNKNOWN) { + printk(" Unknown"); + } + printk(" IRQ(s)\n"); +} + + +static void +update_link_quality_led(acx_device_t *adev) +{ + int qual; + + qual = acx_signal_determine_quality(adev->wstats.qual.level, adev->wstats.qual.noise); + if (qual > adev->brange_max_quality) + qual = adev->brange_max_quality; + + if (time_after(jiffies, adev->brange_time_last_state_change + + (HZ/2 - HZ/2 * (unsigned long)qual / adev->brange_max_quality ) )) { + acxpci_l_power_led(adev, (adev->brange_last_state == 0)); + adev->brange_last_state ^= 1; /* toggle */ + adev->brange_time_last_state_change = jiffies; + } +} + + +#define MAX_IRQLOOPS_PER_JIFFY (20000/HZ) /* a la orinoco.c */ + +static irqreturn_t +acxpci_i_interrupt(int irq, void *dev_id) +{ + acx_device_t *adev; + unsigned long flags; + unsigned int irqcount = MAX_IRQLOOPS_PER_JIFFY; + register u16 irqtype; + u16 unmasked; + + adev = ndev2adev((struct net_device*)dev_id); + + /* LOCKING: can just spin_lock() since IRQs are disabled anyway. + * I am paranoid */ + acx_lock(adev, flags); + + unmasked = read_reg16(adev, IO_ACX_IRQ_STATUS_CLEAR); + if (unlikely(0xffff == unmasked)) { + /* 0xffff value hints at missing hardware, + * so don't do anything. + * Not very clean, but other drivers do the same... */ + log(L_IRQ, "IRQ type:FFFF - device removed? IRQ_NONE\n"); + goto none; + } + + /* We will check only "interesting" IRQ types */ + irqtype = unmasked & ~adev->irq_mask; + if (!irqtype) { + /* We are on a shared IRQ line and it wasn't our IRQ */ + log(L_IRQ, "IRQ type:%04X, mask:%04X - all are masked, IRQ_NONE\n", + unmasked, adev->irq_mask); + goto none; + } + + /* Done here because IRQ_NONEs taking three lines of log + ** drive me crazy */ + FN_ENTER; + +#define IRQ_ITERATE 1 +#if IRQ_ITERATE +if (jiffies != adev->irq_last_jiffies) { + adev->irq_loops_this_jiffy = 0; + adev->irq_last_jiffies = jiffies; +} + +/* safety condition; we'll normally abort loop below + * in case no IRQ type occurred */ +while (likely(--irqcount)) { +#endif + /* ACK all IRQs ASAP */ + write_reg16(adev, IO_ACX_IRQ_ACK, 0xffff); + + log(L_IRQ, "IRQ type:%04X, mask:%04X, type & ~mask:%04X\n", + unmasked, adev->irq_mask, irqtype); + + /* Handle most important IRQ types first */ + if (irqtype & HOST_INT_RX_COMPLETE) { + log(L_IRQ, "got Rx_Complete IRQ\n"); + acxpci_l_process_rxdesc(adev); + } + if (irqtype & HOST_INT_TX_COMPLETE) { + log(L_IRQ, "got Tx_Complete IRQ\n"); + /* don't clean up on each Tx complete, wait a bit + * unless we're going towards full, in which case + * we do it immediately, too (otherwise we might lockup + * with a full Tx buffer if we go into + * acxpci_l_clean_txdesc() at a time when we won't wakeup + * the net queue in there for some reason...) */ + if (adev->tx_free <= TX_START_CLEAN) { +#if TX_CLEANUP_IN_SOFTIRQ + acx_schedule_task(adev, ACX_AFTER_IRQ_TX_CLEANUP); +#else + acxpci_l_clean_txdesc(adev); +#endif + } + } + + /* Less frequent ones */ + if (irqtype & (0 + | HOST_INT_CMD_COMPLETE + | HOST_INT_INFO + | HOST_INT_SCAN_COMPLETE + )) { + if (irqtype & HOST_INT_CMD_COMPLETE) { + log(L_IRQ, "got Command_Complete IRQ\n"); + /* save the state for the running issue_cmd() */ + SET_BIT(adev->irq_status, HOST_INT_CMD_COMPLETE); + } + if (irqtype & HOST_INT_INFO) { + handle_info_irq(adev); + } + if (irqtype & HOST_INT_SCAN_COMPLETE) { + log(L_IRQ, "got Scan_Complete IRQ\n"); + /* need to do that in process context */ + acx_schedule_task(adev, ACX_AFTER_IRQ_COMPLETE_SCAN); + /* remember that fw is not scanning anymore */ + SET_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE); + } + } + + /* These we just log, but either they happen rarely + * or we keep them masked out */ + if (irqtype & (0 + | HOST_INT_RX_DATA + /* | HOST_INT_TX_COMPLETE */ + | HOST_INT_TX_XFER + /* | HOST_INT_RX_COMPLETE */ + | HOST_INT_DTIM + | HOST_INT_BEACON + | HOST_INT_TIMER + | HOST_INT_KEY_NOT_FOUND + | HOST_INT_IV_ICV_FAILURE + /* | HOST_INT_CMD_COMPLETE */ + /* | HOST_INT_INFO */ + | HOST_INT_OVERFLOW + | HOST_INT_PROCESS_ERROR + /* | HOST_INT_SCAN_COMPLETE */ + | HOST_INT_FCS_THRESHOLD + | HOST_INT_UNKNOWN + )) { + log_unusual_irq(irqtype); + } + +#if IRQ_ITERATE + unmasked = read_reg16(adev, IO_ACX_IRQ_STATUS_CLEAR); + irqtype = unmasked & ~adev->irq_mask; + /* Bail out if no new IRQ bits or if all are masked out */ + if (!irqtype) + break; + + if (unlikely(++adev->irq_loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY)) { + printk(KERN_ERR "acx: too many interrupts per jiffy!\n"); + /* Looks like card floods us with IRQs! Try to stop that */ + write_reg16(adev, IO_ACX_IRQ_MASK, 0xffff); + /* This will short-circuit all future attempts to handle IRQ. + * We cant do much more... */ + adev->irq_mask = 0; + break; + } +} +#endif + /* Routine to perform blink with range */ + if (unlikely(adev->led_power == 2)) + update_link_quality_led(adev); + +/* handled: */ + /* write_flush(adev); - not needed, last op was read anyway */ + acx_unlock(adev, flags); + FN_EXIT0; + return IRQ_HANDLED; + +none: + acx_unlock(adev, flags); + return IRQ_NONE; +} + + +/*********************************************************************** +** acxpci_l_power_led +*/ +void +acxpci_l_power_led(acx_device_t *adev, int enable) +{ + u16 gpio_pled = IS_ACX111(adev) ? 0x0040 : 0x0800; + + /* A hack. Not moving message rate limiting to adev->xxx + * (it's only a debug message after all) */ + static int rate_limit = 0; + + if (rate_limit++ < 3) + log(L_IOCTL, "Please report in case toggling the power " + "LED doesn't work for your card!\n"); + if (enable) + write_reg16(adev, IO_ACX_GPIO_OUT, + read_reg16(adev, IO_ACX_GPIO_OUT) & ~gpio_pled); + else + write_reg16(adev, IO_ACX_GPIO_OUT, + read_reg16(adev, IO_ACX_GPIO_OUT) | gpio_pled); +} + + +/*********************************************************************** +** Ioctls +*/ + +/*********************************************************************** +*/ +int +acx111pci_ioctl_info( + struct net_device *ndev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra) +{ +#if ACX_DEBUG > 1 + acx_device_t *adev = ndev2adev(ndev); + rxdesc_t *rxdesc; + txdesc_t *txdesc; + rxhostdesc_t *rxhostdesc; + txhostdesc_t *txhostdesc; + struct acx111_ie_memoryconfig memconf; + struct acx111_ie_queueconfig queueconf; + unsigned long flags; + int i; + char memmap[0x34]; + char rxconfig[0x8]; + char fcserror[0x8]; + char ratefallback[0x5]; + + if ( !(acx_debug & (L_IOCTL|L_DEBUG)) ) + return OK; + /* using printk() since we checked debug flag already */ + + acx_sem_lock(adev); + + if (!IS_ACX111(adev)) { + printk("acx111-specific function called " + "with non-acx111 chip, aborting\n"); + goto end_ok; + } + + /* get Acx111 Memory Configuration */ + memset(&memconf, 0, sizeof(memconf)); + /* BTW, fails with 12 (Write only) error code. + ** Retained for easy testing of issue_cmd error handling :) */ + acx_s_interrogate(adev, &memconf, ACX1xx_IE_QUEUE_CONFIG); + + /* get Acx111 Queue Configuration */ + memset(&queueconf, 0, sizeof(queueconf)); + acx_s_interrogate(adev, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS); + + /* get Acx111 Memory Map */ + memset(memmap, 0, sizeof(memmap)); + acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP); + + /* get Acx111 Rx Config */ + memset(rxconfig, 0, sizeof(rxconfig)); + acx_s_interrogate(adev, &rxconfig, ACX1xx_IE_RXCONFIG); + + /* get Acx111 fcs error count */ + memset(fcserror, 0, sizeof(fcserror)); + acx_s_interrogate(adev, &fcserror, ACX1xx_IE_FCS_ERROR_COUNT); + + /* get Acx111 rate fallback */ + memset(ratefallback, 0, sizeof(ratefallback)); + acx_s_interrogate(adev, &ratefallback, ACX1xx_IE_RATE_FALLBACK); + + /* force occurrence of a beacon interrupt */ + /* TODO: comment why is this necessary */ + write_reg16(adev, IO_ACX_HINT_TRIG, HOST_INT_BEACON); + + /* dump Acx111 Mem Configuration */ + printk("dump mem config:\n" + "data read: %d, struct size: %d\n" + "Number of stations: %1X\n" + "Memory block size: %1X\n" + "tx/rx memory block allocation: %1X\n" + "count rx: %X / tx: %X queues\n" + "options %1X\n" + "fragmentation %1X\n" + "Rx Queue 1 Count Descriptors: %X\n" + "Rx Queue 1 Host Memory Start: %X\n" + "Tx Queue 1 Count Descriptors: %X\n" + "Tx Queue 1 Attributes: %X\n", + memconf.len, (int) sizeof(memconf), + memconf.no_of_stations, + memconf.memory_block_size, + memconf.tx_rx_memory_block_allocation, + memconf.count_rx_queues, memconf.count_tx_queues, + memconf.options, + memconf.fragmentation, + memconf.rx_queue1_count_descs, + acx2cpu(memconf.rx_queue1_host_rx_start), + memconf.tx_queue1_count_descs, + memconf.tx_queue1_attributes); + + /* dump Acx111 Queue Configuration */ + printk("dump queue head:\n" + "data read: %d, struct size: %d\n" + "tx_memory_block_address (from card): %X\n" + "rx_memory_block_address (from card): %X\n" + "rx1_queue address (from card): %X\n" + "tx1_queue address (from card): %X\n" + "tx1_queue attributes (from card): %X\n", + queueconf.len, (int) sizeof(queueconf), + queueconf.tx_memory_block_address, + queueconf.rx_memory_block_address, + queueconf.rx1_queue_address, + queueconf.tx1_queue_address, + queueconf.tx1_attributes); + + /* dump Acx111 Mem Map */ + printk("dump mem map:\n" + "data read: %d, struct size: %d\n" + "Code start: %X\n" + "Code end: %X\n" + "WEP default key start: %X\n" + "WEP default key end: %X\n" + "STA table start: %X\n" + "STA table end: %X\n" + "Packet template start: %X\n" + "Packet template end: %X\n" + "Queue memory start: %X\n" + "Queue memory end: %X\n" + "Packet memory pool start: %X\n" + "Packet memory pool end: %X\n" + "iobase: %p\n" + "iobase2: %p\n", + *((u16 *)&memmap[0x02]), (int) sizeof(memmap), + *((u32 *)&memmap[0x04]), + *((u32 *)&memmap[0x08]), + *((u32 *)&memmap[0x0C]), + *((u32 *)&memmap[0x10]), + *((u32 *)&memmap[0x14]), + *((u32 *)&memmap[0x18]), + *((u32 *)&memmap[0x1C]), + *((u32 *)&memmap[0x20]), + *((u32 *)&memmap[0x24]), + *((u32 *)&memmap[0x28]), + *((u32 *)&memmap[0x2C]), + *((u32 *)&memmap[0x30]), + adev->iobase, + adev->iobase2); + + /* dump Acx111 Rx Config */ + printk("dump rx config:\n" + "data read: %d, struct size: %d\n" + "rx config: %X\n" + "rx filter config: %X\n", + *((u16 *)&rxconfig[0x02]), (int) sizeof(rxconfig), + *((u16 *)&rxconfig[0x04]), + *((u16 *)&rxconfig[0x06])); + + /* dump Acx111 fcs error */ + printk("dump fcserror:\n" + "data read: %d, struct size: %d\n" + "fcserrors: %X\n", + *((u16 *)&fcserror[0x02]), (int) sizeof(fcserror), + *((u32 *)&fcserror[0x04])); + + /* dump Acx111 rate fallback */ + printk("dump rate fallback:\n" + "data read: %d, struct size: %d\n" + "ratefallback: %X\n", + *((u16 *)&ratefallback[0x02]), (int) sizeof(ratefallback), + *((u8 *)&ratefallback[0x04])); + + /* protect against IRQ */ + acx_lock(adev, flags); + + /* dump acx111 internal rx descriptor ring buffer */ + rxdesc = adev->rxdesc_start; + + /* loop over complete receive pool */ + if (rxdesc) for (i = 0; i < RX_CNT; i++) { + printk("\ndump internal rxdesc %d:\n" + "mem pos %p\n" + "next 0x%X\n" + "acx mem pointer (dynamic) 0x%X\n" + "CTL (dynamic) 0x%X\n" + "Rate (dynamic) 0x%X\n" + "RxStatus (dynamic) 0x%X\n" + "Mod/Pre (dynamic) 0x%X\n", + i, + rxdesc, + acx2cpu(rxdesc->pNextDesc), + acx2cpu(rxdesc->ACXMemPtr), + rxdesc->Ctl_8, + rxdesc->rate, + rxdesc->error, + rxdesc->SNR); + rxdesc++; + } + + /* dump host rx descriptor ring buffer */ + + rxhostdesc = adev->rxhostdesc_start; + + /* loop over complete receive pool */ + if (rxhostdesc) for (i = 0; i < RX_CNT; i++) { + printk("\ndump host rxdesc %d:\n" + "mem pos %p\n" + "buffer mem pos 0x%X\n" + "buffer mem offset 0x%X\n" + "CTL 0x%X\n" + "Length 0x%X\n" + "next 0x%X\n" + "Status 0x%X\n", + i, + rxhostdesc, + acx2cpu(rxhostdesc->data_phy), + rxhostdesc->data_offset, + le16_to_cpu(rxhostdesc->Ctl_16), + le16_to_cpu(rxhostdesc->length), + acx2cpu(rxhostdesc->desc_phy_next), + rxhostdesc->Status); + rxhostdesc++; + } + + /* dump acx111 internal tx descriptor ring buffer */ + txdesc = adev->txdesc_start; + + /* loop over complete transmit pool */ + if (txdesc) for (i = 0; i < TX_CNT; i++) { + printk("\ndump internal txdesc %d:\n" + "size 0x%X\n" + "mem pos %p\n" + "next 0x%X\n" + "acx mem pointer (dynamic) 0x%X\n" + "host mem pointer (dynamic) 0x%X\n" + "length (dynamic) 0x%X\n" + "CTL (dynamic) 0x%X\n" + "CTL2 (dynamic) 0x%X\n" + "Status (dynamic) 0x%X\n" + "Rate (dynamic) 0x%X\n", + i, + (int) sizeof(struct txdesc), + txdesc, + acx2cpu(txdesc->pNextDesc), + acx2cpu(txdesc->AcxMemPtr), + acx2cpu(txdesc->HostMemPtr), + le16_to_cpu(txdesc->total_length), + txdesc->Ctl_8, + txdesc->Ctl2_8, txdesc->error, + txdesc->u.r1.rate); + txdesc = advance_txdesc(adev, txdesc, 1); + } + + /* dump host tx descriptor ring buffer */ + + txhostdesc = adev->txhostdesc_start; + + /* loop over complete host send pool */ + if (txhostdesc) for (i = 0; i < TX_CNT * 2; i++) { + printk("\ndump host txdesc %d:\n" + "mem pos %p\n" + "buffer mem pos 0x%X\n" + "buffer mem offset 0x%X\n" + "CTL 0x%X\n" + "Length 0x%X\n" + "next 0x%X\n" + "Status 0x%X\n", + i, + txhostdesc, + acx2cpu(txhostdesc->data_phy), + txhostdesc->data_offset, + le16_to_cpu(txhostdesc->Ctl_16), + le16_to_cpu(txhostdesc->length), + acx2cpu(txhostdesc->desc_phy_next), + le32_to_cpu(txhostdesc->Status)); + txhostdesc++; + } + + /* write_reg16(adev, 0xb4, 0x4); */ + + acx_unlock(adev, flags); +end_ok: + + acx_sem_unlock(adev); +#endif /* ACX_DEBUG */ + return OK; +} + + +/*********************************************************************** +*/ +int +acx100pci_ioctl_set_phy_amp_bias( + struct net_device *ndev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + unsigned long flags; + u16 gpio_old; + + if (!IS_ACX100(adev)) { + /* WARNING!!! + * Removing this check *might* damage + * hardware, since we're tweaking GPIOs here after all!!! + * You've been warned... + * WARNING!!! */ + printk("acx: sorry, setting bias level for non-acx100 " + "is not supported yet\n"); + return OK; + } + + if (*extra > 7) { + printk("acx: invalid bias parameter, range is 0-7\n"); + return -EINVAL; + } + + acx_sem_lock(adev); + + /* Need to lock accesses to [IO_ACX_GPIO_OUT]: + * IRQ handler uses it to update LED */ + acx_lock(adev, flags); + gpio_old = read_reg16(adev, IO_ACX_GPIO_OUT); + write_reg16(adev, IO_ACX_GPIO_OUT, (gpio_old & 0xf8ff) | ((u16)*extra << 8)); + acx_unlock(adev, flags); + + log(L_DEBUG, "gpio_old: 0x%04X\n", gpio_old); + printk("%s: PHY power amplifier bias: old:%d, new:%d\n", + ndev->name, + (gpio_old & 0x0700) >> 8, (unsigned char)*extra); + + acx_sem_unlock(adev); + + return OK; +} + + +/*************************************************************** +** acxpci_l_alloc_tx +** Actually returns a txdesc_t* ptr +** +** FIXME: in case of fragments, should allocate multiple descrs +** after figuring out how many we need and whether we still have +** sufficiently many. +*/ +tx_t* +acxpci_l_alloc_tx(acx_device_t *adev) +{ + struct txdesc *txdesc; + unsigned head; + u8 ctl8; + + FN_ENTER; + + if (unlikely(!adev->tx_free)) { + printk("acx: BUG: no free txdesc left\n"); + txdesc = NULL; + goto end; + } + + head = adev->tx_head; + txdesc = get_txdesc(adev, head); + ctl8 = txdesc->Ctl_8; + + /* 2005-10-11: there were several bug reports on this happening + ** but now cause seems to be understood & fixed */ + if (unlikely(DESC_CTL_HOSTOWN != (ctl8 & DESC_CTL_ACXDONE_HOSTOWN))) { + /* whoops, descr at current index is not free, so probably + * ring buffer already full */ + printk("acx: BUG: tx_head:%d Ctl8:0x%02X - failed to find " + "free txdesc\n", head, ctl8); + txdesc = NULL; + goto end; + } + + /* Needed in case txdesc won't be eventually submitted for tx */ + txdesc->Ctl_8 = DESC_CTL_ACXDONE_HOSTOWN; + + adev->tx_free--; + log(L_BUFT, "tx: got desc %u, %u remain\n", + head, adev->tx_free); + /* Keep a few free descs between head and tail of tx ring. + ** It is not absolutely needed, just feels safer */ + if (adev->tx_free < TX_STOP_QUEUE) { + log(L_BUF, "stop queue (%u tx desc left)\n", + adev->tx_free); + acx_stop_queue(adev->ndev, NULL); + } + + /* returning current descriptor, so advance to next free one */ + adev->tx_head = (head + 1) % TX_CNT; +end: + FN_EXIT0; + + return (tx_t*)txdesc; +} + + +/*********************************************************************** +*/ +void* +acxpci_l_get_txbuf(acx_device_t *adev, tx_t* tx_opaque) +{ + return get_txhostdesc(adev, (txdesc_t*)tx_opaque)->data; +} + + +/*********************************************************************** +** acxpci_l_tx_data +** +** Can be called from IRQ (rx -> (AP bridging or mgmt response) -> tx). +** Can be called from acx_i_start_xmit (data frames from net core). +** +** FIXME: in case of fragments, should loop over the number of +** pre-allocated tx descrs, properly setting up transfer data and +** CTL_xxx flags according to fragment number. +*/ +void +acxpci_l_tx_data(acx_device_t *adev, tx_t* tx_opaque, int len) +{ + txdesc_t *txdesc = (txdesc_t*)tx_opaque; + txhostdesc_t *hostdesc1, *hostdesc2; + client_t *clt; + u16 rate_cur; + u8 Ctl_8, Ctl2_8; + + FN_ENTER; + + /* fw doesn't tx such packets anyhow */ + if (unlikely(len < WLAN_HDR_A3_LEN)) + goto end; + + hostdesc1 = get_txhostdesc(adev, txdesc); + /* modify flag status in separate variable to be able to write it back + * in one big swoop later (also in order to have less device memory + * accesses) */ + Ctl_8 = txdesc->Ctl_8; + Ctl2_8 = 0; /* really need to init it to 0, not txdesc->Ctl2_8, it seems */ + + hostdesc2 = hostdesc1 + 1; + + /* DON'T simply set Ctl field to 0 here globally, + * it needs to maintain a consistent flag status (those are state flags!!), + * otherwise it may lead to severe disruption. Only set or reset particular + * flags at the exact moment this is needed... */ + + /* let chip do RTS/CTS handshaking before sending + * in case packet size exceeds threshold */ + if (len > adev->rts_threshold) + SET_BIT(Ctl2_8, DESC_CTL2_RTS); + else + CLEAR_BIT(Ctl2_8, DESC_CTL2_RTS); + + switch (adev->mode) { + case ACX_MODE_0_ADHOC: + case ACX_MODE_3_AP: + clt = acx_l_sta_list_get(adev, ((wlan_hdr_t*)hostdesc1->data)->a1); + break; + case ACX_MODE_2_STA: + clt = adev->ap_client; + break; +#if 0 +/* testing was done on acx111: */ + case ACX_MODE_MONITOR: + SET_BIT(Ctl2_8, 0 +/* sends CTS to self before packet */ + + DESC_CTL2_SEQ /* don't increase sequence field */ +/* not working (looks like good fcs is still added) */ + + DESC_CTL2_FCS /* don't add the FCS */ +/* not tested */ + + DESC_CTL2_MORE_FRAG +/* not tested */ + + DESC_CTL2_RETRY /* don't increase retry field */ +/* not tested */ + + DESC_CTL2_POWER /* don't increase power mgmt. field */ +/* no effect */ + + DESC_CTL2_WEP /* encrypt this frame */ +/* not tested */ + + DESC_CTL2_DUR /* don't increase duration field */ + ); + /* fallthrough */ +#endif + default: /* ACX_MODE_OFF, ACX_MODE_MONITOR */ + clt = NULL; + break; + } + + rate_cur = clt ? clt->rate_cur : adev->rate_bcast; + if (unlikely(!rate_cur)) { + printk("acx: driver bug! bad ratemask\n"); + goto end; + } + + /* used in tx cleanup routine for auto rate and accounting: */ + put_txcr(adev, txdesc, clt, rate_cur); + + txdesc->total_length = cpu_to_le16(len); + hostdesc2->length = cpu_to_le16(len - WLAN_HDR_A3_LEN); + if (IS_ACX111(adev)) { + /* note that if !txdesc->do_auto, txrate->cur + ** has only one nonzero bit */ + txdesc->u.r2.rate111 = cpu_to_le16( + rate_cur + /* WARNING: I was never able to make it work with prism54 AP. + ** It was falling down to 1Mbit where shortpre is not applicable, + ** and not working at all at "5,11 basic rates only" setting. + ** I even didn't see tx packets in radio packet capture. + ** Disabled for now --vda */ + /*| ((clt->shortpre && clt->cur!=RATE111_1) ? RATE111_SHORTPRE : 0) */ + ); +#ifdef TODO_FIGURE_OUT_WHEN_TO_SET_THIS + /* should add this to rate111 above as necessary */ + | (clt->pbcc511 ? RATE111_PBCC511 : 0) +#endif + hostdesc1->length = cpu_to_le16(len); + } else { /* ACX100 */ + u8 rate_100 = clt ? clt->rate_100 : adev->rate_bcast100; + txdesc->u.r1.rate = rate_100; +#ifdef TODO_FIGURE_OUT_WHEN_TO_SET_THIS + if (clt->pbcc511) { + if (n == RATE100_5 || n == RATE100_11) + n |= RATE100_PBCC511; + } + + if (clt->shortpre && (clt->cur != RATE111_1)) + SET_BIT(Ctl_8, DESC_CTL_SHORT_PREAMBLE); /* set Short Preamble */ +#endif + /* set autodma and reclaim and 1st mpdu */ + SET_BIT(Ctl_8, DESC_CTL_AUTODMA | DESC_CTL_RECLAIM | DESC_CTL_FIRSTFRAG); +#if ACX_FRAGMENTATION + /* SET_BIT(Ctl2_8, DESC_CTL2_MORE_FRAG); cannot set it unconditionally, needs to be set for all non-last fragments */ +#endif + hostdesc1->length = cpu_to_le16(WLAN_HDR_A3_LEN); + } + /* don't need to clean ack/rts statistics here, already + * done on descr cleanup */ + + /* clears HOSTOWN and ACXDONE bits, thus telling that the descriptors + * are now owned by the acx100; do this as LAST operation */ + CLEAR_BIT(Ctl_8, DESC_CTL_ACXDONE_HOSTOWN); + /* flush writes before we release hostdesc to the adapter here */ + wmb(); + CLEAR_BIT(hostdesc1->Ctl_16, cpu_to_le16(DESC_CTL_HOSTOWN)); + CLEAR_BIT(hostdesc2->Ctl_16, cpu_to_le16(DESC_CTL_HOSTOWN)); + + /* write back modified flags */ + txdesc->Ctl2_8 = Ctl2_8; + txdesc->Ctl_8 = Ctl_8; + /* unused: txdesc->tx_time = cpu_to_le32(jiffies); */ + + /* flush writes before we tell the adapter that it's its turn now */ + mmiowb(); + write_reg16(adev, IO_ACX_INT_TRIG, INT_TRIG_TXPRC); + write_flush(adev); + + /* log the packet content AFTER sending it, + * in order to not delay sending any further than absolutely needed + * Do separate logs for acx100/111 to have human-readable rates */ + if (unlikely(acx_debug & (L_XFER|L_DATA))) { + u16 fc = ((wlan_hdr_t*)hostdesc1->data)->fc; + if (IS_ACX111(adev)) + printk("tx: pkt (%s): len %d " + "rate %04X%s status %u\n", + acx_get_packet_type_string(le16_to_cpu(fc)), len, + le16_to_cpu(txdesc->u.r2.rate111), + (le16_to_cpu(txdesc->u.r2.rate111) & RATE111_SHORTPRE) ? "(SPr)" : "", + adev->status); + else + printk("tx: pkt (%s): len %d rate %03u%s status %u\n", + acx_get_packet_type_string(fc), len, + txdesc->u.r1.rate, + (Ctl_8 & DESC_CTL_SHORT_PREAMBLE) ? "(SPr)" : "", + adev->status); + + if (acx_debug & L_DATA) { + printk("tx: 802.11 [%d]: ", len); + acx_dump_bytes(hostdesc1->data, len); + } + } +end: + FN_EXIT0; +} + + +/*********************************************************************** +** acxpci_l_clean_txdesc +** +** This function resets the txdescs' status when the ACX100 +** signals the TX done IRQ (txdescs have been processed), starting with +** the pool index of the descriptor which we would use next, +** in order to make sure that we can be as fast as possible +** in filling new txdescs. +** Everytime we get called we know where the next packet to be cleaned is. +*/ + +#if !ACX_DEBUG +static inline void log_txbuffer(const acx_device_t *adev) {} +#else +static void +log_txbuffer(acx_device_t *adev) +{ + txdesc_t *txdesc; + int i; + + /* no FN_ENTER here, we don't want that */ + /* no locks here, since it's entirely non-critical code */ + txdesc = adev->txdesc_start; + if (unlikely(!txdesc)) return; + printk("tx: desc->Ctl8's:"); + for (i = 0; i < TX_CNT; i++) { + printk(" %02X", txdesc->Ctl_8); + txdesc = advance_txdesc(adev, txdesc, 1); + } + printk("\n"); +} +#endif + + +static void +handle_tx_error(acx_device_t *adev, u8 error, unsigned int finger) +{ + const char *err = "unknown error"; + + /* hmm, should we handle this as a mask + * of *several* bits? + * For now I think only caring about + * individual bits is ok... */ + switch (error) { + case 0x01: + err = "no Tx due to error in other fragment"; + adev->wstats.discard.fragment++; + break; + case 0x02: + err = "Tx aborted"; + adev->stats.tx_aborted_errors++; + break; + case 0x04: + err = "Tx desc wrong parameters"; + adev->wstats.discard.misc++; + break; + case 0x08: + err = "WEP key not found"; + adev->wstats.discard.misc++; + break; + case 0x10: + err = "MSDU lifetime timeout? - try changing " + "'iwconfig retry lifetime XXX'"; + adev->wstats.discard.misc++; + break; + case 0x20: + err = "excessive Tx retries due to either distance " + "too high or unable to Tx or Tx frame error - " + "try changing 'iwconfig txpower XXX' or " + "'sens'itivity or 'retry'"; + adev->wstats.discard.retries++; + /* Tx error 0x20 also seems to occur on + * overheating, so I'm not sure whether we + * actually want to do aggressive radio recalibration, + * since people maybe won't notice then that their hardware + * is slowly getting cooked... + * Or is it still a safe long distance from utter + * radio non-functionality despite many radio recalibs + * to final destructive overheating of the hardware? + * In this case we really should do recalib here... + * I guess the only way to find out is to do a + * potentially fatal self-experiment :-\ + * Or maybe only recalib in case we're using Tx + * rate auto (on errors switching to lower speed + * --> less heat?) or 802.11 power save mode? + * + * ok, just do it. */ + if (++adev->retry_errors_msg_ratelimit % 4 == 0) { + if (adev->retry_errors_msg_ratelimit <= 20) { + printk("%s: several excessive Tx " + "retry errors occurred, attempting " + "to recalibrate radio. Radio " + "drift might be caused by increasing " + "card temperature, please check the card " + "before it's too late!\n", + adev->ndev->name); + if (adev->retry_errors_msg_ratelimit == 20) + printk("disabling above message\n"); + } + + acx_schedule_task(adev, ACX_AFTER_IRQ_CMD_RADIO_RECALIB); + } + break; + case 0x40: + err = "Tx buffer overflow"; + adev->stats.tx_fifo_errors++; + break; + case 0x80: + /* possibly ACPI C-state powersaving related!!! + * (DMA timeout due to excessively high wakeup + * latency after C-state activation!?) + * Disable C-State powersaving and try again, + * then PLEASE REPORT, I'm VERY interested in + * whether my theory is correct that this is + * actually the problem here. + * In that case, use new Linux idle wakeup latency + * requirements kernel API to prevent this issue. */ + err = "DMA error"; + adev->wstats.discard.misc++; + break; + } + adev->stats.tx_errors++; + if (adev->stats.tx_errors <= 20) + printk("%s: tx error 0x%02X, buf %02u! (%s)\n", + adev->ndev->name, error, finger, err); + else + printk("%s: tx error 0x%02X, buf %02u!\n", + adev->ndev->name, error, finger); +} + + +unsigned int +acxpci_l_clean_txdesc(acx_device_t *adev) +{ + txdesc_t *txdesc; + unsigned finger; + int num_cleaned; + u16 r111; + u8 error, ack_failures, rts_failures, rts_ok, r100; + + FN_ENTER; + + if (unlikely(acx_debug & L_DEBUG)) + log_txbuffer(adev); + + log(L_BUFT, "tx: cleaning up bufs from %u\n", adev->tx_tail); + + /* We know first descr which is not free yet. We advance it as far + ** as we see correct bits set in following descs (if next desc + ** is NOT free, we shouldn't advance at all). We know that in + ** front of tx_tail may be "holes" with isolated free descs. + ** We will catch up when all intermediate descs will be freed also */ + + finger = adev->tx_tail; + num_cleaned = 0; + while (likely(finger != adev->tx_head)) { + txdesc = get_txdesc(adev, finger); + + /* If we allocated txdesc on tx path but then decided + ** to NOT use it, then it will be left as a free "bubble" + ** in the "allocated for tx" part of the ring. + ** We may meet it on the next ring pass here. */ + + /* stop if not marked as "tx finished" and "host owned" */ + if ((txdesc->Ctl_8 & DESC_CTL_ACXDONE_HOSTOWN) + != DESC_CTL_ACXDONE_HOSTOWN) { + if (unlikely(!num_cleaned)) { /* maybe remove completely */ + log(L_BUFT, "clean_txdesc: tail isn't free. " + "tail:%d head:%d\n", + adev->tx_tail, adev->tx_head); + } + break; + } + + /* remember desc values... */ + error = txdesc->error; + ack_failures = txdesc->ack_failures; + rts_failures = txdesc->rts_failures; + rts_ok = txdesc->rts_ok; + r100 = txdesc->u.r1.rate; + r111 = le16_to_cpu(txdesc->u.r2.rate111); + + /* need to check for certain error conditions before we + * clean the descriptor: we still need valid descr data here */ + if (unlikely(0x30 & error)) { + /* only send IWEVTXDROP in case of retry or lifetime exceeded; + * all other errors mean we screwed up locally */ + union iwreq_data wrqu; + wlan_hdr_t *hdr; + txhostdesc_t *hostdesc; + + hostdesc = get_txhostdesc(adev, txdesc); + hdr = (wlan_hdr_t *)hostdesc->data; + MAC_COPY(wrqu.addr.sa_data, hdr->a1); + wireless_send_event(adev->ndev, IWEVTXDROP, &wrqu, NULL); + } + + /* ...and free the desc */ + txdesc->error = 0; + txdesc->ack_failures = 0; + txdesc->rts_failures = 0; + txdesc->rts_ok = 0; + /* signal host owning it LAST, since ACX already knows that this + ** descriptor is finished since it set Ctl_8 accordingly. */ + txdesc->Ctl_8 = DESC_CTL_HOSTOWN; + + adev->tx_free++; + num_cleaned++; + + if ((adev->tx_free >= TX_START_QUEUE) + && (adev->status == ACX_STATUS_4_ASSOCIATED) + && (acx_queue_stopped(adev->ndev)) + ) { + log(L_BUF, "tx: wake queue (avail. Tx desc %u)\n", + adev->tx_free); + acx_wake_queue(adev->ndev, NULL); + } + + /* do error checking, rate handling and logging + * AFTER having done the work, it's faster */ + + /* do rate handling */ + if (adev->rate_auto) { + struct client *clt = get_txc(adev, txdesc); + if (clt) { + u16 cur = get_txr(adev, txdesc); + if (clt->rate_cur == cur) { + acx_l_handle_txrate_auto(adev, clt, + cur, /* intended rate */ + r100, r111, /* actually used rate */ + (error & 0x30), /* was there an error? */ + TX_CNT + TX_CLEAN_BACKLOG - adev->tx_free); + } + } + } + + if (unlikely(error)) + handle_tx_error(adev, error, finger); + + if (IS_ACX111(adev)) + log(L_BUFT, "tx: cleaned %u: !ACK=%u !RTS=%u RTS=%u r111=%04X\n", + finger, ack_failures, rts_failures, rts_ok, r111); + else + log(L_BUFT, "tx: cleaned %u: !ACK=%u !RTS=%u RTS=%u rate=%u\n", + finger, ack_failures, rts_failures, rts_ok, r100); + + /* update pointer for descr to be cleaned next */ + finger = (finger + 1) % TX_CNT; + } + + /* remember last position */ + adev->tx_tail = finger; +/* end: */ + FN_EXIT1(num_cleaned); + return num_cleaned; +} + +/* clean *all* Tx descriptors, and regardless of their previous state. + * Used for brute-force reset handling. */ +void +acxpci_l_clean_txdesc_emergency(acx_device_t *adev) +{ + txdesc_t *txdesc; + int i; + + FN_ENTER; + + for (i = 0; i < TX_CNT; i++) { + txdesc = get_txdesc(adev, i); + + /* free it */ + txdesc->ack_failures = 0; + txdesc->rts_failures = 0; + txdesc->rts_ok = 0; + txdesc->error = 0; + txdesc->Ctl_8 = DESC_CTL_HOSTOWN; + } + + adev->tx_free = TX_CNT; + + FN_EXIT0; +} + + +/*********************************************************************** +** acxpci_s_create_tx_host_desc_queue +*/ + +static void* +allocate(acx_device_t *adev, size_t size, dma_addr_t *phy, const char *msg) +{ + void *ptr; + + ptr = dma_alloc_coherent(adev->pdev ? &adev->pdev->dev : NULL, + size, phy, GFP_KERNEL); + + if (ptr) { + log(L_DEBUG, "%s sz=%d adr=0x%p phy=0x%08llx\n", + msg, (int)size, ptr, (unsigned long long)*phy); + memset(ptr, 0, size); + return ptr; + } + printk(KERN_ERR "acx: %s allocation FAILED (%d bytes)\n", + msg, (int)size); + return NULL; +} + + +static int +acxpci_s_create_tx_host_desc_queue(acx_device_t *adev) +{ + txhostdesc_t *hostdesc; + u8 *txbuf; + dma_addr_t hostdesc_phy; + dma_addr_t txbuf_phy; + int i; + + FN_ENTER; + + /* allocate TX buffer */ + adev->txbuf_area_size = TX_CNT * WLAN_A4FR_MAXLEN_WEP_FCS; + adev->txbuf_start = allocate(adev, adev->txbuf_area_size, + &adev->txbuf_startphy, "txbuf_start"); + if (!adev->txbuf_start) + goto fail; + + /* allocate the TX host descriptor queue pool */ + adev->txhostdesc_area_size = TX_CNT * 2*sizeof(*hostdesc); + adev->txhostdesc_start = allocate(adev, adev->txhostdesc_area_size, + &adev->txhostdesc_startphy, "txhostdesc_start"); + if (!adev->txhostdesc_start) + goto fail; + /* check for proper alignment of TX host descriptor pool */ + if ((long) adev->txhostdesc_start & 3) { + printk("acx: driver bug: dma alloc returns unaligned address\n"); + goto fail; + } + + hostdesc = adev->txhostdesc_start; + hostdesc_phy = adev->txhostdesc_startphy; + txbuf = adev->txbuf_start; + txbuf_phy = adev->txbuf_startphy; + +#if 0 +/* Each tx buffer is accessed by hardware via +** txdesc -> txhostdesc(s) -> txbuffer(s). +** We use only one txhostdesc per txdesc, but it looks like +** acx111 is buggy: it accesses second txhostdesc +** (via hostdesc.desc_phy_next field) even if +** txdesc->length == hostdesc->length and thus +** entire packet was placed into first txhostdesc. +** Due to this bug acx111 hangs unless second txhostdesc +** has le16_to_cpu(hostdesc.length) = 3 (or larger) +** Storing NULL into hostdesc.desc_phy_next +** doesn't seem to help. +** +** Update: although it worked on Xterasys XN-2522g +** with len=3 trick, WG311v2 is even more bogus, doesn't work. +** Keeping this code (#ifdef'ed out) for documentational purposes. +*/ + for (i = 0; i < TX_CNT*2; i++) { + hostdesc_phy += sizeof(*hostdesc); + if (!(i & 1)) { + hostdesc->data_phy = cpu2acx(txbuf_phy); + /* hostdesc->data_offset = ... */ + /* hostdesc->reserved = ... */ + hostdesc->Ctl_16 = cpu_to_le16(DESC_CTL_HOSTOWN); + /* hostdesc->length = ... */ + hostdesc->desc_phy_next = cpu2acx(hostdesc_phy); + hostdesc->pNext = ptr2acx(NULL); + /* hostdesc->Status = ... */ + /* below: non-hardware fields */ + hostdesc->data = txbuf; + + txbuf += WLAN_A4FR_MAXLEN_WEP_FCS; + txbuf_phy += WLAN_A4FR_MAXLEN_WEP_FCS; + } else { + /* hostdesc->data_phy = ... */ + /* hostdesc->data_offset = ... */ + /* hostdesc->reserved = ... */ + /* hostdesc->Ctl_16 = ... */ + hostdesc->length = cpu_to_le16(3); /* bug workaround */ + /* hostdesc->desc_phy_next = ... */ + /* hostdesc->pNext = ... */ + /* hostdesc->Status = ... */ + /* below: non-hardware fields */ + /* hostdesc->data = ... */ + } + hostdesc++; + } +#endif +/* We initialize two hostdescs so that they point to adjacent +** memory areas. Thus txbuf is really just a contiguous memory area */ + for (i = 0; i < TX_CNT*2; i++) { + hostdesc_phy += sizeof(*hostdesc); + + hostdesc->data_phy = cpu2acx(txbuf_phy); + /* done by memset(0): hostdesc->data_offset = 0; */ + /* hostdesc->reserved = ... */ + hostdesc->Ctl_16 = cpu_to_le16(DESC_CTL_HOSTOWN); + /* hostdesc->length = ... */ + hostdesc->desc_phy_next = cpu2acx(hostdesc_phy); + /* done by memset(0): hostdesc->pNext = ptr2acx(NULL); */ + /* hostdesc->Status = ... */ + /* ->data is a non-hardware field: */ + hostdesc->data = txbuf; + + if (!(i & 1)) { + txbuf += WLAN_HDR_A3_LEN; + txbuf_phy += WLAN_HDR_A3_LEN; + } else { + txbuf += WLAN_A4FR_MAXLEN_WEP_FCS - WLAN_HDR_A3_LEN; + txbuf_phy += WLAN_A4FR_MAXLEN_WEP_FCS - WLAN_HDR_A3_LEN; + } + hostdesc++; + } + hostdesc--; + hostdesc->desc_phy_next = cpu2acx(adev->txhostdesc_startphy); + + FN_EXIT1(OK); + return OK; +fail: + printk("acx: create_tx_host_desc_queue FAILED\n"); + /* dealloc will be done by free function on error case */ + FN_EXIT1(NOT_OK); + return NOT_OK; +} + + +/*************************************************************** +** acxpci_s_create_rx_host_desc_queue +*/ +/* the whole size of a data buffer (header plus data body) + * plus 32 bytes safety offset at the end */ +#define RX_BUFFER_SIZE (sizeof(rxbuffer_t) + 32) + +static int +acxpci_s_create_rx_host_desc_queue(acx_device_t *adev) +{ + rxhostdesc_t *hostdesc; + rxbuffer_t *rxbuf; + dma_addr_t hostdesc_phy; + dma_addr_t rxbuf_phy; + int i; + + FN_ENTER; + + /* allocate the RX host descriptor queue pool */ + adev->rxhostdesc_area_size = RX_CNT * sizeof(*hostdesc); + adev->rxhostdesc_start = allocate(adev, adev->rxhostdesc_area_size, + &adev->rxhostdesc_startphy, "rxhostdesc_start"); + if (!adev->rxhostdesc_start) + goto fail; + /* check for proper alignment of RX host descriptor pool */ + if ((long) adev->rxhostdesc_start & 3) { + printk("acx: driver bug: dma alloc returns unaligned address\n"); + goto fail; + } + + /* allocate Rx buffer pool which will be used by the acx + * to store the whole content of the received frames in it */ + adev->rxbuf_area_size = RX_CNT * RX_BUFFER_SIZE; + adev->rxbuf_start = allocate(adev, adev->rxbuf_area_size, + &adev->rxbuf_startphy, "rxbuf_start"); + if (!adev->rxbuf_start) + goto fail; + + rxbuf = adev->rxbuf_start; + rxbuf_phy = adev->rxbuf_startphy; + hostdesc = adev->rxhostdesc_start; + hostdesc_phy = adev->rxhostdesc_startphy; + + /* don't make any popular C programming pointer arithmetic mistakes + * here, otherwise I'll kill you... + * (and don't dare asking me why I'm warning you about that...) */ + for (i = 0; i < RX_CNT; i++) { + hostdesc->data = rxbuf; + hostdesc->data_phy = cpu2acx(rxbuf_phy); + hostdesc->length = cpu_to_le16(RX_BUFFER_SIZE); + CLEAR_BIT(hostdesc->Ctl_16, cpu_to_le16(DESC_CTL_HOSTOWN)); + rxbuf++; + rxbuf_phy += sizeof(*rxbuf); + hostdesc_phy += sizeof(*hostdesc); + hostdesc->desc_phy_next = cpu2acx(hostdesc_phy); + hostdesc++; + } + hostdesc--; + hostdesc->desc_phy_next = cpu2acx(adev->rxhostdesc_startphy); + FN_EXIT1(OK); + return OK; +fail: + printk("acx: create_rx_host_desc_queue FAILED\n"); + /* dealloc will be done by free function on error case */ + FN_EXIT1(NOT_OK); + return NOT_OK; +} + + +/*************************************************************** +** acxpci_s_create_hostdesc_queues +*/ +int +acxpci_s_create_hostdesc_queues(acx_device_t *adev) +{ + int result; + result = acxpci_s_create_tx_host_desc_queue(adev); + if (OK != result) return result; + result = acxpci_s_create_rx_host_desc_queue(adev); + return result; +} + + +/*************************************************************** +** acxpci_create_tx_desc_queue +*/ +static void +acxpci_create_tx_desc_queue(acx_device_t *adev, u32 tx_queue_start) +{ + txdesc_t *txdesc; + txhostdesc_t *hostdesc; + dma_addr_t hostmemptr; + u32 mem_offs; + int i; + + FN_ENTER; + + if (IS_ACX100(adev)) + adev->txdesc_size = sizeof(*txdesc); + else + /* the acx111 txdesc is 4 bytes larger */ + adev->txdesc_size = sizeof(*txdesc) + 4; + + adev->txdesc_start = (txdesc_t *) (adev->iobase2 + tx_queue_start); + + log(L_DEBUG, "adev->iobase2=%p\n" + "tx_queue_start=%08X\n" + "adev->txdesc_start=%p\n", + adev->iobase2, + tx_queue_start, + adev->txdesc_start); + + adev->tx_free = TX_CNT; + /* done by memset: adev->tx_head = 0; */ + /* done by memset: adev->tx_tail = 0; */ + txdesc = adev->txdesc_start; + mem_offs = tx_queue_start; + hostmemptr = adev->txhostdesc_startphy; + hostdesc = adev->txhostdesc_start; + + if (IS_ACX111(adev)) { + /* ACX111 has a preinitialized Tx buffer! */ + /* loop over whole send pool */ + /* FIXME: do we have to do the hostmemptr stuff here?? */ + for (i = 0; i < TX_CNT; i++) { + txdesc->HostMemPtr = ptr2acx(hostmemptr); + txdesc->Ctl_8 = DESC_CTL_HOSTOWN; + /* reserve two (hdr desc and payload desc) */ + hostdesc += 2; + hostmemptr += 2 * sizeof(*hostdesc); + txdesc = advance_txdesc(adev, txdesc, 1); + } + } else { + /* ACX100 Tx buffer needs to be initialized by us */ + /* clear whole send pool. sizeof is safe here (we are acx100) */ + memset(adev->txdesc_start, 0, TX_CNT * sizeof(*txdesc)); + + /* loop over whole send pool */ + for (i = 0; i < TX_CNT; i++) { + log(L_DEBUG, "configure card tx descriptor: 0x%p, " + "size: 0x%X\n", txdesc, adev->txdesc_size); + + /* pointer to hostdesc memory */ + txdesc->HostMemPtr = ptr2acx(hostmemptr); + /* initialise ctl */ + txdesc->Ctl_8 = ( DESC_CTL_HOSTOWN | DESC_CTL_RECLAIM + | DESC_CTL_AUTODMA | DESC_CTL_FIRSTFRAG); + /* done by memset(0): txdesc->Ctl2_8 = 0; */ + /* point to next txdesc */ + txdesc->pNextDesc = cpu2acx(mem_offs + adev->txdesc_size); + /* reserve two (hdr desc and payload desc) */ + hostdesc += 2; + hostmemptr += 2 * sizeof(*hostdesc); + /* go to the next one */ + mem_offs += adev->txdesc_size; + /* ++ is safe here (we are acx100) */ + txdesc++; + } + /* go back to the last one */ + txdesc--; + /* and point to the first making it a ring buffer */ + txdesc->pNextDesc = cpu2acx(tx_queue_start); + } + FN_EXIT0; +} + + +/*************************************************************** +** acxpci_create_rx_desc_queue +*/ +static void +acxpci_create_rx_desc_queue(acx_device_t *adev, u32 rx_queue_start) +{ + rxdesc_t *rxdesc; + u32 mem_offs; + int i; + + FN_ENTER; + + /* done by memset: adev->rx_tail = 0; */ + + /* ACX111 doesn't need any further config: preconfigures itself. + * Simply print ring buffer for debugging */ + if (IS_ACX111(adev)) { + /* rxdesc_start already set here */ + + adev->rxdesc_start = (rxdesc_t *) ((u8 *)adev->iobase2 + rx_queue_start); + + rxdesc = adev->rxdesc_start; + for (i = 0; i < RX_CNT; i++) { + log(L_DEBUG, "rx descriptor %d @ 0x%p\n", i, rxdesc); + rxdesc = adev->rxdesc_start = (rxdesc_t *) + (adev->iobase2 + acx2cpu(rxdesc->pNextDesc)); + } + } else { + /* we didn't pre-calculate rxdesc_start in case of ACX100 */ + /* rxdesc_start should be right AFTER Tx pool */ + adev->rxdesc_start = (rxdesc_t *) + ((u8 *) adev->txdesc_start + (TX_CNT * sizeof(txdesc_t))); + /* NB: sizeof(txdesc_t) above is valid because we know + ** we are in if (acx100) block. Beware of cut-n-pasting elsewhere! + ** acx111's txdesc is larger! */ + + memset(adev->rxdesc_start, 0, RX_CNT * sizeof(*rxdesc)); + + /* loop over whole receive pool */ + rxdesc = adev->rxdesc_start; + mem_offs = rx_queue_start; + for (i = 0; i < RX_CNT; i++) { + log(L_DEBUG, "rx descriptor @ 0x%p\n", rxdesc); + rxdesc->Ctl_8 = DESC_CTL_RECLAIM | DESC_CTL_AUTODMA; + /* point to next rxdesc */ + rxdesc->pNextDesc = cpu2acx(mem_offs + sizeof(*rxdesc)); + /* go to the next one */ + mem_offs += sizeof(*rxdesc); + rxdesc++; + } + /* go to the last one */ + rxdesc--; + + /* and point to the first making it a ring buffer */ + rxdesc->pNextDesc = cpu2acx(rx_queue_start); + } + FN_EXIT0; +} + + +/*************************************************************** +** acxpci_create_desc_queues +*/ +void +acxpci_create_desc_queues(acx_device_t *adev, u32 tx_queue_start, u32 rx_queue_start) +{ + acxpci_create_tx_desc_queue(adev, tx_queue_start); + acxpci_create_rx_desc_queue(adev, rx_queue_start); +} + + +/*************************************************************** +** acxpci_s_proc_diag_output +*/ +char* +acxpci_s_proc_diag_output(char *p, acx_device_t *adev) +{ + const char *rtl, *thd, *ttl; + rxhostdesc_t *rxhostdesc; + txdesc_t *txdesc; + int i; + + FN_ENTER; + + p += sprintf(p, "** Rx buf **\n"); + rxhostdesc = adev->rxhostdesc_start; + if (rxhostdesc) for (i = 0; i < RX_CNT; i++) { + rtl = (i == adev->rx_tail) ? " [tail]" : ""; + if ((rxhostdesc->Ctl_16 & cpu_to_le16(DESC_CTL_HOSTOWN)) + && (rxhostdesc->Status & cpu_to_le32(DESC_STATUS_FULL)) ) + p += sprintf(p, "%02u FULL%s\n", i, rtl); + else + p += sprintf(p, "%02u empty%s\n", i, rtl); + rxhostdesc++; + } + p += sprintf(p, "** Tx buf (free %d, Linux netqueue %s) **\n", adev->tx_free, + acx_queue_stopped(adev->ndev) ? "STOPPED" : "running"); + txdesc = adev->txdesc_start; + if (txdesc) for (i = 0; i < TX_CNT; i++) { + thd = (i == adev->tx_head) ? " [head]" : ""; + ttl = (i == adev->tx_tail) ? " [tail]" : ""; + if (txdesc->Ctl_8 & DESC_CTL_ACXDONE) + p += sprintf(p, "%02u free (%02X)%s%s\n", i, txdesc->Ctl_8, thd, ttl); + else + p += sprintf(p, "%02u tx (%02X)%s%s\n", i, txdesc->Ctl_8, thd, ttl); + txdesc = advance_txdesc(adev, txdesc, 1); + } + p += sprintf(p, + "\n" + "** PCI data **\n" + "txbuf_start %p, txbuf_area_size %u, txbuf_startphy %08llx\n" + "txdesc_size %u, txdesc_start %p\n" + "txhostdesc_start %p, txhostdesc_area_size %u, txhostdesc_startphy %08llx\n" + "rxdesc_start %p\n" + "rxhostdesc_start %p, rxhostdesc_area_size %u, rxhostdesc_startphy %08llx\n" + "rxbuf_start %p, rxbuf_area_size %u, rxbuf_startphy %08llx\n", + adev->txbuf_start, adev->txbuf_area_size, + (unsigned long long)adev->txbuf_startphy, + adev->txdesc_size, adev->txdesc_start, + adev->txhostdesc_start, adev->txhostdesc_area_size, + (unsigned long long)adev->txhostdesc_startphy, + adev->rxdesc_start, + adev->rxhostdesc_start, adev->rxhostdesc_area_size, + (unsigned long long)adev->rxhostdesc_startphy, + adev->rxbuf_start, adev->rxbuf_area_size, + (unsigned long long)adev->rxbuf_startphy); + + FN_EXIT0; + return p; +} + + +/*********************************************************************** +*/ +int +acxpci_proc_eeprom_output(char *buf, acx_device_t *adev) +{ + char *p = buf; + int i; + + FN_ENTER; + + for (i = 0; i < 0x400; i++) { + acxpci_read_eeprom_byte(adev, i, p++); + } + + FN_EXIT1(p - buf); + return p - buf; +} + + +/*********************************************************************** +*/ +void +acxpci_set_interrupt_mask(acx_device_t *adev) +{ + if (IS_ACX111(adev)) { + adev->irq_mask = (u16) ~(0 + /* | HOST_INT_RX_DATA */ + | HOST_INT_TX_COMPLETE + /* | HOST_INT_TX_XFER */ + | HOST_INT_RX_COMPLETE + /* | HOST_INT_DTIM */ + /* | HOST_INT_BEACON */ + /* | HOST_INT_TIMER */ + /* | HOST_INT_KEY_NOT_FOUND */ + | HOST_INT_IV_ICV_FAILURE + | HOST_INT_CMD_COMPLETE + | HOST_INT_INFO + /* | HOST_INT_OVERFLOW */ + /* | HOST_INT_PROCESS_ERROR */ + | HOST_INT_SCAN_COMPLETE + | HOST_INT_FCS_THRESHOLD + /* | HOST_INT_UNKNOWN */ + ); + /* Or else acx100 won't signal cmd completion, right? */ + adev->irq_mask_off = (u16)~( HOST_INT_CMD_COMPLETE ); /* 0xfdff */ + } else { + adev->irq_mask = (u16) ~(0 + /* | HOST_INT_RX_DATA */ + | HOST_INT_TX_COMPLETE + /* | HOST_INT_TX_XFER */ + | HOST_INT_RX_COMPLETE + /* | HOST_INT_DTIM */ + /* | HOST_INT_BEACON */ + /* | HOST_INT_TIMER */ + /* | HOST_INT_KEY_NOT_FOUND */ + /* | HOST_INT_IV_ICV_FAILURE */ + | HOST_INT_CMD_COMPLETE + | HOST_INT_INFO + /* | HOST_INT_OVERFLOW */ + /* | HOST_INT_PROCESS_ERROR */ + | HOST_INT_SCAN_COMPLETE + /* | HOST_INT_FCS_THRESHOLD */ + /* | HOST_INT_UNKNOWN */ + ); + adev->irq_mask_off = (u16)~( HOST_INT_UNKNOWN ); /* 0x7fff */ + } +} + + +/*********************************************************************** +*/ +int +acx100pci_s_set_tx_level(acx_device_t *adev, u8 level_dbm) +{ + /* since it can be assumed that at least the Maxim radio has a + * maximum power output of 20dBm and since it also can be + * assumed that these values drive the DAC responsible for + * setting the linear Tx level, I'd guess that these values + * should be the corresponding linear values for a dBm value, + * in other words: calculate the values from that formula: + * Y [dBm] = 10 * log (X [mW]) + * then scale the 0..63 value range onto the 1..100mW range (0..20 dBm) + * and you're done... + * Hopefully that's ok, but you never know if we're actually + * right... (especially since Windows XP doesn't seem to show + * actual Tx dBm values :-P) */ + + /* NOTE: on Maxim, value 30 IS 30mW, and value 10 IS 10mW - so the + * values are EXACTLY mW!!! Not sure about RFMD and others, + * though... */ + static const u8 dbm2val_maxim[21] = { + 63, 63, 63, 62, + 61, 61, 60, 60, + 59, 58, 57, 55, + 53, 50, 47, 43, + 38, 31, 23, 13, + 0 + }; + static const u8 dbm2val_rfmd[21] = { + 0, 0, 0, 1, + 2, 2, 3, 3, + 4, 5, 6, 8, + 10, 13, 16, 20, + 25, 32, 41, 50, + 63 + }; + const u8 *table; + + switch (adev->radio_type) { + case RADIO_MAXIM_0D: + table = &dbm2val_maxim[0]; + break; + case RADIO_RFMD_11: + case RADIO_RALINK_15: + table = &dbm2val_rfmd[0]; + break; + default: + printk("%s: unknown/unsupported radio type, " + "cannot modify tx power level yet!\n", + adev->ndev->name); + return NOT_OK; + } + printk("%s: changing radio power level to %u dBm (%u)\n", + adev->ndev->name, level_dbm, table[level_dbm]); + acxpci_s_write_phy_reg(adev, 0x11, table[level_dbm]); + return OK; +} + + +/*********************************************************************** +** Data for init_module/cleanup_module +*/ +static DEFINE_PCI_DEVICE_TABLE(acxpci_id_tbl) = { + { + .vendor = PCI_VENDOR_ID_TI, + .device = PCI_DEVICE_ID_TI_TNETW1100A, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = CHIPTYPE_ACX100, + }, + { + .vendor = PCI_VENDOR_ID_TI, + .device = PCI_DEVICE_ID_TI_TNETW1100B, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = CHIPTYPE_ACX100, + }, + { + .vendor = PCI_VENDOR_ID_TI, + .device = PCI_DEVICE_ID_TI_TNETW1130, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = CHIPTYPE_ACX111, + }, + { + .vendor = 0, + .device = 0, + .subvendor = 0, + .subdevice = 0, + .driver_data = 0, + } +}; + +MODULE_DEVICE_TABLE(pci, acxpci_id_tbl); + +static struct pci_driver acxpci_driver = { + .name = "acx_pci", + .id_table = acxpci_id_tbl, + .probe = acxpci_e_probe, + .remove = __devexit_p(acxpci_e_remove), +#ifdef CONFIG_PM + .suspend = acxpci_e_suspend, + .resume = acxpci_e_resume +#endif /* CONFIG_PM */ +}; + + +/*********************************************************************** +** acxpci_e_init_module +** +** Module initialization routine, called once at module load time +*/ +int __init +acxpci_e_init_module(void) +{ + int res; + + FN_ENTER; + +#if (ACX_IO_WIDTH==32) + printk("acx: compiled to use 32bit I/O access. " + "I/O timing issues might occur, such as " + "non-working firmware upload. Report them\n"); +#else + printk("acx: compiled to use 16bit I/O access only " + "(compatibility mode)\n"); +#endif + +#ifdef __LITTLE_ENDIAN +#define ENDIANNESS_STRING "running on a little-endian CPU\n" +#else +#define ENDIANNESS_STRING "running on a BIG-ENDIAN CPU\n" +#endif + log(L_INIT, + ENDIANNESS_STRING + "PCI module " ACX_RELEASE " initialized, " + "waiting for cards to probe...\n" + ); + + res = pci_register_driver(&acxpci_driver); + FN_EXIT1(res); + return res; +} + + +/*********************************************************************** +** acxpci_e_cleanup_module +** +** Called at module unload time. This is our last chance to +** clean up after ourselves. +*/ +void __exit +acxpci_e_cleanup_module(void) +{ + FN_ENTER; + + pci_unregister_driver(&acxpci_driver); + + FN_EXIT0; +} --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/wlan.c +++ linux-2.6.28/ubuntu/misc/wireless/acx/wlan.c @@ -0,0 +1,421 @@ +/*********************************************************************** +** Copyright (C) 2003 ACX100 Open Source Project +** +** The contents of this file are subject to the Mozilla Public +** License Version 1.1 (the "License"); you may not use this file +** except in compliance with the License. You may obtain a copy of +** the License at http://www.mozilla.org/MPL/ +** +** Software distributed under the License is distributed on an "AS +** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +** implied. See the License for the specific language governing +** rights and limitations under the License. +** +** Alternatively, the contents of this file may be used under the +** terms of the GNU Public License version 2 (the "GPL"), in which +** case the provisions of the GPL are applicable instead of the +** above. If you wish to allow the use of your version of this file +** only under the terms of the GPL and not to allow others to use +** your version of this file under the MPL, indicate your decision +** by deleting the provisions above and replace them with the notice +** and other provisions required by the GPL. If you do not delete +** the provisions above, a recipient may use your version of this +** file under either the MPL or the GPL. +** --------------------------------------------------------------------- +** Inquiries regarding the ACX100 Open Source Project can be +** made directly to: +** +** acx100-users@lists.sf.net +** http://acx100.sf.net +** --------------------------------------------------------------------- +*/ + +/*********************************************************************** +** This code is based on elements which are +** Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +** info@linux-wlan.com +** http://www.linux-wlan.com +*/ + +#include +#include +#include +#include +#include + +#include "acx.h" + + +/*********************************************************************** +*/ +#define LOG_BAD_EID(hdr,len,ie_ptr) acx_log_bad_eid(hdr, len, ((wlan_ie_t*)ie_ptr)) + +#define IE_EID(ie_ptr) (((wlan_ie_t*)(ie_ptr))->eid) +#define IE_LEN(ie_ptr) (((wlan_ie_t*)(ie_ptr))->len) +#define OFFSET(hdr,off) (WLAN_HDR_A3_DATAP(hdr) + (off)) + + +/*********************************************************************** +** wlan_mgmt_decode_XXX +** +** Given a complete frame in f->hdr, sets the pointers in f to +** the areas that correspond to the parts of the frame. +** +** Assumptions: +** 1) f->len and f->hdr are already set +** 2) f->len is the length of the MAC header + data, the FCS +** is NOT included +** 3) all members except len and hdr are zero +** Arguments: +** f frame structure +** +** Returns: +** nothing +** +** Side effects: +** frame structure members are pointing at their +** respective portions of the frame buffer. +*/ +void +wlan_mgmt_decode_beacon(wlan_fr_beacon_t * f) +{ + u8 *ie_ptr; + u8 *end = (u8*)f->hdr + f->len; + + f->type = WLAN_FSTYPE_BEACON; + + /*-- Fixed Fields ----*/ + f->ts = (u64 *) OFFSET(f->hdr, WLAN_BEACON_OFF_TS); + f->bcn_int = (u16 *) OFFSET(f->hdr, WLAN_BEACON_OFF_BCN_INT); + f->cap_info = (u16 *) OFFSET(f->hdr, WLAN_BEACON_OFF_CAPINFO); + + /*-- Information elements */ + ie_ptr = OFFSET(f->hdr, WLAN_BEACON_OFF_SSID); + while (ie_ptr < end) { + switch (IE_EID(ie_ptr)) { + case WLAN_EID_SSID: + f->ssid = (wlan_ie_ssid_t *) ie_ptr; + break; + case WLAN_EID_SUPP_RATES: + f->supp_rates = (wlan_ie_supp_rates_t *) ie_ptr; + break; + case WLAN_EID_EXT_RATES: + f->ext_rates = (wlan_ie_supp_rates_t *) ie_ptr; + break; + case WLAN_EID_FH_PARMS: + f->fh_parms = (wlan_ie_fh_parms_t *) ie_ptr; + break; + case WLAN_EID_DS_PARMS: + f->ds_parms = (wlan_ie_ds_parms_t *) ie_ptr; + break; + case WLAN_EID_CF_PARMS: + f->cf_parms = (wlan_ie_cf_parms_t *) ie_ptr; + break; + case WLAN_EID_IBSS_PARMS: + f->ibss_parms = (wlan_ie_ibss_parms_t *) ie_ptr; + break; + case WLAN_EID_TIM: + f->tim = (wlan_ie_tim_t *) ie_ptr; + break; + case WLAN_EID_ERP_INFO: + f->erp = (wlan_ie_erp_t *) ie_ptr; + break; + + case WLAN_EID_COUNTRY: + /* was seen: 07 06 47 42 20 01 0D 14 */ + case WLAN_EID_PWR_CONSTRAINT: + /* was seen by Ashwin Mansinghka from + Atheros-based PCI card in AP mode using madwifi drivers: */ + /* 20 01 00 */ + case WLAN_EID_NONERP: + /* was seen from WRT54GS with OpenWrt: 2F 01 07 */ + case WLAN_EID_UNKNOWN128: + /* was seen by Jacek Jablonski from Orinoco AP */ + /* 80 06 00 60 1D 2C 3B 00 */ + case WLAN_EID_UNKNOWN133: + /* was seen by David Bronaugh from ???? */ + /* 85 1E 00 00 84 12 07 00 FF 00 11 00 61 70 63 31 */ + /* 63 73 72 30 34 32 00 00 00 00 00 00 00 00 00 25 */ + case WLAN_EID_UNKNOWN223: + /* was seen by Carlos Martin from ???? */ + /* DF 20 01 1E 04 00 00 00 06 63 09 02 FF 0F 30 30 */ + /* 30 42 36 42 33 34 30 39 46 31 00 00 00 00 00 00 00 00 */ + case WLAN_EID_GENERIC: + /* WPA: hostap code: + if (pos[1] >= 4 && + pos[2] == 0x00 && pos[3] == 0x50 && + pos[4] == 0xf2 && pos[5] == 1) { + wpa = pos; + wpa_len = pos[1] + 2; + } + TI x4 mode: seen DD 04 08 00 28 00 + (08 00 28 is TI's OUI) + last byte is probably 0/1 - disabled/enabled + */ + case WLAN_EID_RSN: + /* hostap does something with it: + rsn = pos; + rsn_len = pos[1] + 2; + */ + break; + + default: + LOG_BAD_EID(f->hdr, f->len, ie_ptr); + break; + } + ie_ptr = ie_ptr + 2 + IE_LEN(ie_ptr); + } +} + + +#ifdef UNUSED +void wlan_mgmt_decode_ibssatim(wlan_fr_ibssatim_t * f) +{ + f->type = WLAN_FSTYPE_ATIM; + /*-- Fixed Fields ----*/ + /*-- Information elements */ +} +#endif /* UNUSED */ + +void +wlan_mgmt_decode_disassoc(wlan_fr_disassoc_t * f) +{ + f->type = WLAN_FSTYPE_DISASSOC; + + /*-- Fixed Fields ----*/ + f->reason = (u16 *) OFFSET(f->hdr, WLAN_DISASSOC_OFF_REASON); + + /*-- Information elements */ +} + + +void +wlan_mgmt_decode_assocreq(wlan_fr_assocreq_t * f) +{ + u8 *ie_ptr; + u8 *end = (u8*)f->hdr + f->len; + + + f->type = WLAN_FSTYPE_ASSOCREQ; + + /*-- Fixed Fields ----*/ + f->cap_info = (u16 *) OFFSET(f->hdr, WLAN_ASSOCREQ_OFF_CAP_INFO); + f->listen_int = (u16 *) OFFSET(f->hdr, WLAN_ASSOCREQ_OFF_LISTEN_INT); + + /*-- Information elements */ + ie_ptr = OFFSET(f->hdr, WLAN_ASSOCREQ_OFF_SSID); + while (ie_ptr < end) { + switch (IE_EID(ie_ptr)) { + case WLAN_EID_SSID: + f->ssid = (wlan_ie_ssid_t *) ie_ptr; + break; + case WLAN_EID_SUPP_RATES: + f->supp_rates = (wlan_ie_supp_rates_t *) ie_ptr; + break; + case WLAN_EID_EXT_RATES: + f->ext_rates = (wlan_ie_supp_rates_t *) ie_ptr; + break; + default: + LOG_BAD_EID(f->hdr, f->len, ie_ptr); + break; + } + ie_ptr = ie_ptr + 2 + IE_LEN(ie_ptr); + } +} + + +void +wlan_mgmt_decode_assocresp(wlan_fr_assocresp_t * f) +{ + f->type = WLAN_FSTYPE_ASSOCRESP; + + /*-- Fixed Fields ----*/ + f->cap_info = (u16 *) OFFSET(f->hdr, WLAN_ASSOCRESP_OFF_CAP_INFO); + f->status = (u16 *) OFFSET(f->hdr, WLAN_ASSOCRESP_OFF_STATUS); + f->aid = (u16 *) OFFSET(f->hdr, WLAN_ASSOCRESP_OFF_AID); + + /*-- Information elements */ + f->supp_rates = (wlan_ie_supp_rates_t *) + OFFSET(f->hdr, WLAN_ASSOCRESP_OFF_SUPP_RATES); +} + + +#ifdef UNUSED +void +wlan_mgmt_decode_reassocreq(wlan_fr_reassocreq_t * f) +{ + u8 *ie_ptr; + u8 *end = (u8*)f->hdr + f->len; + + f->type = WLAN_FSTYPE_REASSOCREQ; + + /*-- Fixed Fields ----*/ + f->cap_info = (u16 *) OFFSET(f->hdr, WLAN_REASSOCREQ_OFF_CAP_INFO); + f->listen_int = (u16 *) OFFSET(f->hdr, WLAN_REASSOCREQ_OFF_LISTEN_INT); + f->curr_ap = (u8 *) OFFSET(f->hdr, WLAN_REASSOCREQ_OFF_CURR_AP); + + /*-- Information elements */ + ie_ptr = OFFSET(f->hdr, WLAN_REASSOCREQ_OFF_SSID); + while (ie_ptr < end) { + switch (IE_EID(ie_ptr)) { + case WLAN_EID_SSID: + f->ssid = (wlan_ie_ssid_t *) ie_ptr; + break; + case WLAN_EID_SUPP_RATES: + f->supp_rates = (wlan_ie_supp_rates_t *) ie_ptr; + break; + case WLAN_EID_EXT_RATES: + f->ext_rates = (wlan_ie_supp_rates_t *) ie_ptr; + break; + default: + LOG_BAD_EID(f->hdr, f->len, ie_ptr); + break; + } + ie_ptr = ie_ptr + 2 + IE_LEN(ie_ptr); + } +} + + +void +wlan_mgmt_decode_reassocresp(wlan_fr_reassocresp_t * f) +{ + f->type = WLAN_FSTYPE_REASSOCRESP; + + /*-- Fixed Fields ----*/ + f->cap_info = (u16 *) OFFSET(f->hdr, WLAN_REASSOCRESP_OFF_CAP_INFO); + f->status = (u16 *) OFFSET(f->hdr, WLAN_REASSOCRESP_OFF_STATUS); + f->aid = (u16 *) OFFSET(f->hdr, WLAN_REASSOCRESP_OFF_AID); + + /*-- Information elements */ + f->supp_rates = (wlan_ie_supp_rates_t *) + OFFSET(f->hdr, WLAN_REASSOCRESP_OFF_SUPP_RATES); +} + + +void +wlan_mgmt_decode_probereq(wlan_fr_probereq_t * f) +{ + u8 *ie_ptr; + u8 *end = (u8*)f->hdr + f->len; + + f->type = WLAN_FSTYPE_PROBEREQ; + + /*-- Fixed Fields ----*/ + + /*-- Information elements */ + ie_ptr = OFFSET(f->hdr, WLAN_PROBEREQ_OFF_SSID); + while (ie_ptr < end) { + switch (IE_EID(ie_ptr)) { + case WLAN_EID_SSID: + f->ssid = (wlan_ie_ssid_t *) ie_ptr; + break; + case WLAN_EID_SUPP_RATES: + f->supp_rates = (wlan_ie_supp_rates_t *) ie_ptr; + break; + case WLAN_EID_EXT_RATES: + f->ext_rates = (wlan_ie_supp_rates_t *) ie_ptr; + break; + default: + LOG_BAD_EID(f->hdr, f->len, ie_ptr); + break; + } + ie_ptr = ie_ptr + 2 + IE_LEN(ie_ptr); + } +} +#endif /* UNUSED */ + + +/* TODO: decoding of beacon and proberesp can be merged (similar structure) */ +void +wlan_mgmt_decode_proberesp(wlan_fr_proberesp_t * f) +{ + u8 *ie_ptr; + u8 *end = (u8*)f->hdr + f->len; + + f->type = WLAN_FSTYPE_PROBERESP; + + /*-- Fixed Fields ----*/ + f->ts = (u64 *) OFFSET(f->hdr, WLAN_PROBERESP_OFF_TS); + f->bcn_int = (u16 *) OFFSET(f->hdr, WLAN_PROBERESP_OFF_BCN_INT); + f->cap_info = (u16 *) OFFSET(f->hdr, WLAN_PROBERESP_OFF_CAP_INFO); + + /*-- Information elements */ + ie_ptr = OFFSET(f->hdr, WLAN_PROBERESP_OFF_SSID); + while (ie_ptr < end) { + switch (IE_EID(ie_ptr)) { + case WLAN_EID_SSID: + f->ssid = (wlan_ie_ssid_t *) ie_ptr; + break; + case WLAN_EID_SUPP_RATES: + f->supp_rates = (wlan_ie_supp_rates_t *) ie_ptr; + break; + case WLAN_EID_EXT_RATES: + f->ext_rates = (wlan_ie_supp_rates_t *) ie_ptr; + break; + case WLAN_EID_FH_PARMS: + f->fh_parms = (wlan_ie_fh_parms_t *) ie_ptr; + break; + case WLAN_EID_DS_PARMS: + f->ds_parms = (wlan_ie_ds_parms_t *) ie_ptr; + break; + case WLAN_EID_CF_PARMS: + f->cf_parms = (wlan_ie_cf_parms_t *) ie_ptr; + break; + case WLAN_EID_IBSS_PARMS: + f->ibss_parms = (wlan_ie_ibss_parms_t *) ie_ptr; + break; +#ifdef DONT_DO_IT_ADD_REAL_HANDLING_INSTEAD + case WLAN_EID_COUNTRY: + break; + ... +#endif +#ifdef SENT_HERE_BY_OPENWRT + /* should those be trapped or handled?? */ + case WLAN_EID_ERP_INFO: + break; + case WLAN_EID_NONERP: + break; + case WLAN_EID_GENERIC: + break; +#endif + default: + LOG_BAD_EID(f->hdr, f->len, ie_ptr); + break; + } + + ie_ptr = ie_ptr + 2 + IE_LEN(ie_ptr); + } +} + + +void +wlan_mgmt_decode_authen(wlan_fr_authen_t * f) +{ + u8 *ie_ptr; + u8 *end = (u8*)f->hdr + f->len; + + f->type = WLAN_FSTYPE_AUTHEN; + + /*-- Fixed Fields ----*/ + f->auth_alg = (u16 *) OFFSET(f->hdr, WLAN_AUTHEN_OFF_AUTH_ALG); + f->auth_seq = (u16 *) OFFSET(f->hdr, WLAN_AUTHEN_OFF_AUTH_SEQ); + f->status = (u16 *) OFFSET(f->hdr, WLAN_AUTHEN_OFF_STATUS); + + /*-- Information elements */ + ie_ptr = OFFSET(f->hdr, WLAN_AUTHEN_OFF_CHALLENGE); + if ((ie_ptr < end) && (IE_EID(ie_ptr) == WLAN_EID_CHALLENGE)) { + f->challenge = (wlan_ie_challenge_t *) ie_ptr; + } +} + + +void +wlan_mgmt_decode_deauthen(wlan_fr_deauthen_t * f) +{ + f->type = WLAN_FSTYPE_DEAUTHEN; + + /*-- Fixed Fields ----*/ + f->reason = (u16 *) OFFSET(f->hdr, WLAN_DEAUTHEN_OFF_REASON); + + /*-- Information elements */ +} --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/conv.c +++ linux-2.6.28/ubuntu/misc/wireless/acx/conv.c @@ -0,0 +1,504 @@ +/*********************************************************************** +** Copyright (C) 2003 ACX100 Open Source Project +** +** The contents of this file are subject to the Mozilla Public +** License Version 1.1 (the "License"); you may not use this file +** except in compliance with the License. You may obtain a copy of +** the License at http://www.mozilla.org/MPL/ +** +** Software distributed under the License is distributed on an "AS +** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +** implied. See the License for the specific language governing +** rights and limitations under the License. +** +** Alternatively, the contents of this file may be used under the +** terms of the GNU Public License version 2 (the "GPL"), in which +** case the provisions of the GPL are applicable instead of the +** above. If you wish to allow the use of your version of this file +** only under the terms of the GPL and not to allow others to use +** your version of this file under the MPL, indicate your decision +** by deleting the provisions above and replace them with the notice +** and other provisions required by the GPL. If you do not delete +** the provisions above, a recipient may use your version of this +** file under either the MPL or the GPL. +** --------------------------------------------------------------------- +** Inquiries regarding the ACX100 Open Source Project can be +** made directly to: +** +** acx100-users@lists.sf.net +** http://acx100.sf.net +** --------------------------------------------------------------------- +*/ + +#include +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) +#include +#endif +#include +#include +#include +#include +#include + +#include "acx.h" + + +/*********************************************************************** +** proto_is_stt +** +** Searches the 802.1h Selective Translation Table for a given +** protocol. +** +** prottype - protocol number (in host order) to search for. +** +** Returns: +** 1 - if the table is empty or a match is found. +** 0 - if the table is non-empty and a match is not found. +** +** Based largely on p80211conv.c of the linux-wlan-ng project +*/ +static inline int +proto_is_stt(unsigned int proto) +{ + /* Always return found for now. This is the behavior used by the */ + /* Zoom Win95 driver when 802.1h mode is selected */ + /* TODO: If necessary, add an actual search we'll probably + need this to match the CMAC's way of doing things. + Need to do some testing to confirm. + */ + + if (proto == 0x80f3) /* APPLETALK */ + return 1; + + return 0; +/* return ((prottype == ETH_P_AARP) || (prottype == ETH_P_IPX)); */ +} + +/* Helpers */ + +static inline void +store_llc_snap(struct wlan_llc *llc) +{ + llc->dsap = 0xaa; /* SNAP, see IEEE 802 */ + llc->ssap = 0xaa; + llc->ctl = 0x03; +} +static inline int +llc_is_snap(const struct wlan_llc *llc) +{ + return (llc->dsap == 0xaa) + && (llc->ssap == 0xaa) + && (llc->ctl == 0x03); +} +static inline void +store_oui_rfc1042(struct wlan_snap *snap) +{ + snap->oui[0] = 0; + snap->oui[1] = 0; + snap->oui[2] = 0; +} +static inline int +oui_is_rfc1042(const struct wlan_snap *snap) +{ + return (snap->oui[0] == 0) + && (snap->oui[1] == 0) + && (snap->oui[2] == 0); +} +static inline void +store_oui_8021h(struct wlan_snap *snap) +{ + snap->oui[0] = 0; + snap->oui[1] = 0; + snap->oui[2] = 0xf8; +} +static inline int +oui_is_8021h(const struct wlan_snap *snap) +{ + return (snap->oui[0] == 0) + && (snap->oui[1] == 0) + && (snap->oui[2] == 0xf8); +} + + +/*********************************************************************** +** acx_ether_to_txbuf +** +** Uses the contents of the ether frame to build the elements of +** the 802.11 frame. +** +** We don't actually set up the frame header here. That's the +** MAC's job. We're only handling conversion of DIXII or 802.3+LLC +** frames to something that works with 802.11. +** +** Based largely on p80211conv.c of the linux-wlan-ng project +*/ +int +acx_ether_to_txbuf(acx_device_t *adev, void *txbuf, const struct sk_buff *skb) +{ + struct wlan_hdr_a3 *w_hdr; + struct wlan_ethhdr *e_hdr; + struct wlan_llc *e_llc; + struct wlan_snap *e_snap; + const u8 *a1, *a3; + int header_len, payload_len = -1; + /* protocol type or data length, depending on whether + * DIX or 802.3 ethernet format */ + u16 proto; + u16 fc; + + FN_ENTER; + + if (unlikely(!skb->len)) { + log(L_DEBUG, "zero-length skb!\n"); + goto end; + } + + w_hdr = (struct wlan_hdr_a3*)txbuf; + + switch (adev->mode) { + case ACX_MODE_MONITOR: + /* NB: one day we might want to play with DESC_CTL2_FCS + ** Will need to stop doing "- WLAN_FCS_LEN" here then */ + if (unlikely(skb->len >= WLAN_A4FR_MAXLEN_WEP_FCS - WLAN_FCS_LEN)) { + printk("%s: can't tx oversized frame (%d bytes)\n", + adev->ndev->name, skb->len); + goto end; + } + memcpy(w_hdr, skb->data, skb->len); + payload_len = skb->len; + goto end; + } + + /* step 1: classify ether frame, DIX or 802.3? */ + e_hdr = (wlan_ethhdr_t *)skb->data; + proto = ntohs(e_hdr->type); + if (proto <= 1500) { + log(L_DEBUG, "tx: 802.3 len: %d\n", skb->len); + /* codes <= 1500 reserved for 802.3 lengths */ + /* it's 802.3, pass ether payload unchanged, */ + /* trim off ethernet header and copy payload to txdesc */ + header_len = WLAN_HDR_A3_LEN; + } else { + /* it's DIXII, time for some conversion */ + /* Create 802.11 packet. Header also contains llc and snap. */ + + log(L_DEBUG, "tx: DIXII len: %d\n", skb->len); + + /* size of header is 802.11 header + llc + snap */ + header_len = WLAN_HDR_A3_LEN + sizeof(wlan_llc_t) + sizeof(wlan_snap_t); + /* llc is located behind the 802.11 header */ + e_llc = (wlan_llc_t*)(w_hdr + 1); + /* snap is located behind the llc */ + e_snap = (wlan_snap_t*)(e_llc + 1); + + /* setup the LLC header */ + store_llc_snap(e_llc); + + /* setup the SNAP header */ + e_snap->type = htons(proto); + if (proto_is_stt(proto)) { + store_oui_8021h(e_snap); + } else { + store_oui_rfc1042(e_snap); + } + } + /* trim off ethernet header and copy payload to txbuf */ + payload_len = skb->len - sizeof(wlan_ethhdr_t); + /* TODO: can we just let acx DMA payload from skb instead? */ + memcpy((u8*)txbuf + header_len, skb->data + sizeof(wlan_ethhdr_t), payload_len); + payload_len += header_len; + + /* Set up the 802.11 header */ + switch (adev->mode) { + case ACX_MODE_0_ADHOC: + fc = (WF_FTYPE_DATAi | WF_FSTYPE_DATAONLYi); + a1 = e_hdr->daddr; + a3 = adev->bssid; + break; + case ACX_MODE_2_STA: + fc = (WF_FTYPE_DATAi | WF_FSTYPE_DATAONLYi | WF_FC_TODSi); + a1 = adev->bssid; + a3 = e_hdr->daddr; + break; + case ACX_MODE_3_AP: + fc = (WF_FTYPE_DATAi | WF_FSTYPE_DATAONLYi | WF_FC_FROMDSi); + a1 = e_hdr->daddr; + a3 = e_hdr->saddr; + break; + default: + printk("%s: error - converting eth to wlan in unknown mode\n", + adev->ndev->name); + payload_len = -1; + goto end; + } + if (adev->wep_enabled) + SET_BIT(fc, WF_FC_ISWEPi); + + w_hdr->fc = fc; + w_hdr->dur = 0; + MAC_COPY(w_hdr->a1, a1); + MAC_COPY(w_hdr->a2, adev->dev_addr); + MAC_COPY(w_hdr->a3, a3); + w_hdr->seq = 0; + +#ifdef DEBUG_CONVERT + if (acx_debug & L_DATA) { + printk("original eth frame [%d]: ", skb->len); + acx_dump_bytes(skb->data, skb->len); + printk("802.11 frame [%d]: ", payload_len); + acx_dump_bytes(w_hdr, payload_len); + } +#endif + +end: + FN_EXIT1(payload_len); + return payload_len; +} + + +/*********************************************************************** +** acx_rxbuf_to_ether +** +** Uses the contents of a received 802.11 frame to build an ether +** frame. +** +** This function extracts the src and dest address from the 802.11 +** frame to use in the construction of the eth frame. +** +** Based largely on p80211conv.c of the linux-wlan-ng project +*/ +struct sk_buff* +acx_rxbuf_to_ether(acx_device_t *adev, rxbuffer_t *rxbuf) +{ + struct wlan_hdr *w_hdr; + struct wlan_ethhdr *e_hdr; + struct wlan_llc *e_llc; + struct wlan_snap *e_snap; + struct sk_buff *skb; + const u8 *daddr; + const u8 *saddr; + const u8 *e_payload; + int buflen, payload_length; + unsigned int payload_offset, mtu; + u16 fc; + + FN_ENTER; + + /* This looks complex because it must handle possible + ** phy header in rxbuff */ + w_hdr = acx_get_wlan_hdr(adev, rxbuf); + payload_offset = WLAN_HDR_A3_LEN; /* it is relative to w_hdr */ + payload_length = RXBUF_BYTES_USED(rxbuf) /* entire rxbuff... */ + - ((u8*)w_hdr - (u8*)rxbuf) /* minus space before 802.11 frame */ + - WLAN_HDR_A3_LEN; /* minus 802.11 header */ + + /* setup some vars for convenience */ + fc = w_hdr->fc; + switch (WF_FC_FROMTODSi & fc) { + case 0: + daddr = w_hdr->a1; + saddr = w_hdr->a2; + break; + case WF_FC_FROMDSi: + daddr = w_hdr->a1; + saddr = w_hdr->a3; + break; + case WF_FC_TODSi: + daddr = w_hdr->a3; + saddr = w_hdr->a2; + break; + default: /* WF_FC_FROMTODSi */ + payload_offset += (WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN); + payload_length -= (WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN); + daddr = w_hdr->a3; + saddr = w_hdr->a4; + } + + if ((WF_FC_ISWEPi & fc) && IS_ACX100(adev)) { + /* chop off the IV+ICV WEP header and footer */ + log(L_DATA|L_DEBUG, "rx: WEP packet, " + "chopping off IV and ICV\n"); + payload_offset += WLAN_WEP_IV_LEN; + payload_length -= WLAN_WEP_IV_LEN + WLAN_WEP_ICV_LEN; + } + + if (unlikely(payload_length < 0)) { + printk("%s: rx frame too short, ignored\n", adev->ndev->name); + goto ret_null; + } + + e_hdr = (wlan_ethhdr_t*) ((u8*) w_hdr + payload_offset); + e_llc = (wlan_llc_t*) e_hdr; + e_snap = (wlan_snap_t*) (e_llc + 1); + mtu = adev->ndev->mtu; + e_payload = (u8*) (e_snap + 1); + + log(L_DATA, "rx: payload_offset %d, payload_length %d\n", + payload_offset, payload_length); + log(L_XFER|L_DATA, + "rx: frame info: llc=%02X%02X%02X " + "snap.oui=%02X%02X%02X snap.type=%04X\n", + e_llc->dsap, e_llc->ssap, e_llc->ctl, + e_snap->oui[0], e_snap->oui[1], e_snap->oui[2], + ntohs(e_snap->type)); + + /* Test for the various encodings */ + if ((payload_length >= sizeof(wlan_ethhdr_t)) + && ((e_llc->dsap != 0xaa) || (e_llc->ssap != 0xaa)) + && ( (mac_is_equal(daddr, e_hdr->daddr)) + || (mac_is_equal(saddr, e_hdr->saddr)) + ) + ) { + /* 802.3 Encapsulated: */ + /* wlan frame body contains complete eth frame (header+body) */ + log(L_DEBUG|L_DATA, "rx: 802.3 ENCAP len=%d\n", payload_length); + + if (unlikely(payload_length > (mtu + ETH_HLEN))) { + printk("%s: rx: ENCAP frame too large (%d > %d)\n", + adev->ndev->name, + payload_length, mtu + ETH_HLEN); + goto ret_null; + } + + /* allocate space and setup host buffer */ + buflen = payload_length; + /* Attempt to align IP header (14 bytes eth header + 2 = 16) */ + skb = dev_alloc_skb(buflen + 2); + if (unlikely(!skb)) + goto no_skb; + skb_reserve(skb, 2); + skb_put(skb, buflen); /* make room */ + + /* now copy the data from the 80211 frame */ + memcpy(skb->data, e_hdr, payload_length); + + } else if ( (payload_length >= sizeof(wlan_llc_t)+sizeof(wlan_snap_t)) + && llc_is_snap(e_llc) ) { + /* wlan frame body contains: AA AA 03 ... (it's a SNAP) */ + + if ( !oui_is_rfc1042(e_snap) + || (proto_is_stt(ieee2host16(e_snap->type)) /* && (ethconv == WLAN_ETHCONV_8021h) */)) { + log(L_DEBUG|L_DATA, "rx: SNAP+RFC1042 len=%d\n", payload_length); + /* wlan frame body contains: AA AA 03 !(00 00 00) ... -or- */ + /* wlan frame body contains: AA AA 03 00 00 00 0x80f3 ... */ + /* build eth hdr, type = len, copy AA AA 03... as eth body */ + /* it's a SNAP + RFC1042 frame && protocol is in STT */ + + if (unlikely(payload_length > mtu)) { + printk("%s: rx: SNAP frame too large (%d > %d)\n", + adev->ndev->name, + payload_length, mtu); + goto ret_null; + } + + /* allocate space and setup host buffer */ + buflen = payload_length + ETH_HLEN; + skb = dev_alloc_skb(buflen + 2); + if (unlikely(!skb)) + goto no_skb; + skb_reserve(skb, 2); + skb_put(skb, buflen); /* make room */ + + /* create 802.3 header */ + e_hdr = (wlan_ethhdr_t*) skb->data; + MAC_COPY(e_hdr->daddr, daddr); + MAC_COPY(e_hdr->saddr, saddr); + e_hdr->type = htons(payload_length); + + /* Now copy the data from the 80211 frame. + Make room in front for the eth header, and keep the + llc and snap from the 802.11 payload */ + memcpy(skb->data + ETH_HLEN, + e_llc, payload_length); + + } else { + /* wlan frame body contains: AA AA 03 00 00 00 [type] [tail] */ + /* build eth hdr, type=[type], copy [tail] as eth body */ + log(L_DEBUG|L_DATA, "rx: 802.1h/RFC1042 len=%d\n", + payload_length); + /* it's an 802.1h frame (an RFC1042 && protocol is not in STT) */ + /* build a DIXII + RFC894 */ + + payload_length -= sizeof(wlan_llc_t) + sizeof(wlan_snap_t); + if (unlikely(payload_length > mtu)) { + printk("%s: rx: DIXII frame too large (%d > %d)\n", + adev->ndev->name, + payload_length, mtu); + goto ret_null; + } + + /* allocate space and setup host buffer */ + buflen = payload_length + ETH_HLEN; + skb = dev_alloc_skb(buflen + 2); + if (unlikely(!skb)) + goto no_skb; + skb_reserve(skb, 2); + skb_put(skb, buflen); /* make room */ + + /* create 802.3 header */ + e_hdr = (wlan_ethhdr_t *) skb->data; + MAC_COPY(e_hdr->daddr, daddr); + MAC_COPY(e_hdr->saddr, saddr); + e_hdr->type = e_snap->type; + + /* Now copy the data from the 80211 frame. + Make room in front for the eth header, and cut off the + llc and snap from the 802.11 payload */ + memcpy(skb->data + ETH_HLEN, + e_payload, payload_length); + } + + } else { + log(L_DEBUG|L_DATA, "rx: NON-ENCAP len=%d\n", payload_length); + /* build eth hdr, type=len, copy wlan body as eth body */ + /* any NON-ENCAP */ + /* it's a generic 80211+LLC or IPX 'Raw 802.3' */ + /* build an 802.3 frame */ + + if (unlikely(payload_length > mtu)) { + printk("%s: rx: OTHER frame too large (%d > %d)\n", + adev->ndev->name, payload_length, mtu); + goto ret_null; + } + + /* allocate space and setup host buffer */ + buflen = payload_length + ETH_HLEN; + skb = dev_alloc_skb(buflen + 2); + if (unlikely(!skb)) + goto no_skb; + skb_reserve(skb, 2); + skb_put(skb, buflen); /* make room */ + + /* set up the 802.3 header */ + e_hdr = (wlan_ethhdr_t *) skb->data; + MAC_COPY(e_hdr->daddr, daddr); + MAC_COPY(e_hdr->saddr, saddr); + e_hdr->type = htons(payload_length); + + /* now copy the data from the 80211 frame */ + memcpy(skb->data + ETH_HLEN, e_llc, payload_length); + } + + skb->dev = adev->ndev; + skb->protocol = eth_type_trans(skb, adev->ndev); + +#ifdef DEBUG_CONVERT + if (acx_debug & L_DATA) { + int len = RXBUF_BYTES_RCVD(adev, rxbuf); + printk("p802.11 frame [%d]: ", len); + acx_dump_bytes(w_hdr, len); + printk("eth frame [%d]: ", skb->len); + acx_dump_bytes(skb->data, skb->len); + } +#endif + + FN_EXIT0; + return skb; + +no_skb: + printk("%s: rx: no memory for skb (%d bytes)\n", + adev->ndev->name, buflen + 2); +ret_null: + FN_EXIT1((int)NULL); + return NULL; +} --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/setrate.c +++ linux-2.6.28/ubuntu/misc/wireless/acx/setrate.c @@ -0,0 +1,213 @@ +/* TODO: stop #including, move into wireless.c + * until then, keep in sync copies in prism54/ and acx/ dirs + * code+data size: less than 1k */ + +enum { + DOT11_RATE_1, + DOT11_RATE_2, + DOT11_RATE_5, + DOT11_RATE_11, + DOT11_RATE_22, + DOT11_RATE_33, + DOT11_RATE_6, + DOT11_RATE_9, + DOT11_RATE_12, + DOT11_RATE_18, + DOT11_RATE_24, + DOT11_RATE_36, + DOT11_RATE_48, + DOT11_RATE_54 +}; +enum { + DOT11_MOD_DBPSK, + DOT11_MOD_DQPSK, + DOT11_MOD_CCK, + DOT11_MOD_OFDM, + DOT11_MOD_CCKOFDM, + DOT11_MOD_PBCC +}; +static const u8 ratelist[] = { 1,2,5,11,22,33,6,9,12,18,24,36,48,54 }; +static const u8 dot11ratebyte[] = { 1*2,2*2,11,11*2,22*2,33*2,6*2,9*2,12*2,18*2,24*2,36*2,48*2,54*2 }; +static const u8 default_modulation[] = { + DOT11_MOD_DBPSK, + DOT11_MOD_DQPSK, + DOT11_MOD_CCK, + DOT11_MOD_CCK, + DOT11_MOD_PBCC, + DOT11_MOD_PBCC, + DOT11_MOD_OFDM, + DOT11_MOD_OFDM, + DOT11_MOD_OFDM, + DOT11_MOD_OFDM, + DOT11_MOD_OFDM, + DOT11_MOD_OFDM, + DOT11_MOD_OFDM, + DOT11_MOD_OFDM +}; + +static /* TODO: remove 'static' when moved to wireless.c */ +int +rate_mbit2enum(int n) { + int i=0; + while(i=DOT11_RATE_6) return DOT11_MOD_OFDM; */ + return default_modulation[r_enum]; + } + if(suffix=='c') { + if(r_enumDOT11_RATE_11) return -EINVAL; + return DOT11_MOD_CCK; + } + if(suffix=='p') { + if(r_enumDOT11_RATE_33) return -EINVAL; + return DOT11_MOD_PBCC; + } + if(suffix=='o') { + if(r_enumINT_MAX) return -EINVAL; + + rate_enum = rate_mbit2enum(rate_mbit); + if(rate_enum<0) return rate_enum; + + c = *str; + mod = get_modulation(rate_enum, c); + if(mod<0) return mod; + + if(c>='a' && c<='z') c = *++str; + if(c!=',' && c!=' ' && c!='\0') return -EINVAL; + + if(supported) { + int r = supported(rate_mbit, mod, opaque); + if(r) return r; + } + + *vector++ = dot11ratebyte[rate_enum] | or_mask; + + size--; + str++; + } while(size>0 && c==','); + + if(size<1) return -E2BIG; + *vector=0; /* TODO: sort, remove dups? */ + + *pstr = str-1; + return 0; +} + +static /* TODO: remove 'static' when moved to wireless.c */ +int +fill_ratevectors(const char *str, u8 *brate, u8 *orate, int size, + int (*supported)(int mbit, int mod, void *opaque), void *opaque) +{ + int r; + + r = fill_ratevector(&str, brate, size, supported, opaque, 0x80); + if(r) return r; + + orate[0] = 0; + if(*str==' ') { + str++; + r = fill_ratevector(&str, orate, size, supported, opaque, 0); + if(r) return r; + /* TODO: sanitize, e.g. remove/error on rates already in basic rate set? */ + } + if(*str) + return -EINVAL; + + return 0; +} +#endif + +/* TODO: use u64 masks? */ + +static int +fill_ratemask(const char **pstr, u32* mask, + int (*supported)(int mbit, int mod,void *opaque), + u32 (*gen_mask)(int mbit, int mod,void *opaque), + void *opaque) +{ + unsigned long rate_mbit; + int rate_enum,mod; + u32 m = 0; + const char *str = *pstr; + char c; + + do { + rate_mbit = simple_strtoul(str, (char**)&str, 10); + if(rate_mbit>INT_MAX) return -EINVAL; + + rate_enum = rate_mbit2enum(rate_mbit); + if(rate_enum<0) return rate_enum; + + c = *str; + mod = get_modulation(rate_enum, c); + if(mod<0) return mod; + + if(c>='a' && c<='z') c = *++str; + if(c!=',' && c!=' ' && c!='\0') return -EINVAL; + + if(supported) { + int r = supported(rate_mbit, mod, opaque); + if(r) return r; + } + + m |= gen_mask(rate_mbit, mod, opaque); + str++; + } while(c==','); + + *pstr = str-1; + *mask |= m; + return 0; +} + +static /* TODO: remove 'static' when moved to wireless.c */ +int +fill_ratemasks(const char *str, u32 *bmask, u32 *omask, + int (*supported)(int mbit, int mod,void *opaque), + u32 (*gen_mask)(int mbit, int mod,void *opaque), + void *opaque) +{ + int r; + + r = fill_ratemask(&str, bmask, supported, gen_mask, opaque); + if(r) return r; + + if(*str==' ') { + str++; + r = fill_ratemask(&str, omask, supported, gen_mask, opaque); + if(r) return r; + } + if(*str) + return -EINVAL; + return 0; +} --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/acx_config.h +++ linux-2.6.28/ubuntu/misc/wireless/acx/acx_config.h @@ -0,0 +1,41 @@ +/* Driver version */ +#define ACX_RELEASE "v0.3.36" + +/* set to 0 if you don't want any debugging code to be compiled in */ +/* set to 1 if you want some debugging */ +/* set to 2 if you want extensive debug log */ +#define ACX_DEBUG 0 +#define ACX_DEFAULT_MSG (L_ASSOC|L_INIT) + +/* assume 32bit I/O width + * (16bit is also compatible with Compact Flash) */ +#define ACX_IO_WIDTH 32 + +/* Set this to 1 if you want monitor mode to use + * phy header. Currently it is not useful anyway since we + * don't know what useful info (if any) is in phy header. + * If you want faster/smaller code, say 0 here */ +#define WANT_PHY_HDR 0 + +/* whether to do Tx descriptor cleanup in softirq (i.e. not in IRQ + * handler) or not. Note that doing it later does slightly increase + * system load, so still do that stuff in the IRQ handler for now, + * even if that probably means worse latency */ +#define TX_CLEANUP_IN_SOFTIRQ 0 + +/* if you want very experimental 802.11 power save mode features */ +#define POWER_SAVE_80211 0 + +/* if you want very early packet fragmentation bits and pieces */ +#define ACX_FRAGMENTATION 0 + +/* Locking: */ +/* very talkative */ +/* #define PARANOID_LOCKING 1 */ +/* normal (use when bug-free) */ +#define DO_LOCKING 1 +/* else locking is disabled! */ + +/* 0 - normal mode */ +/* 1 - development/debug: probe for IEs on modprobe */ +#define CMD_DISCOVERY 0 --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/Makefile +++ linux-2.6.28/ubuntu/misc/wireless/acx/Makefile @@ -0,0 +1,5 @@ +EXTRA_CFLAGS = -DCONFIG_NET_ACX_PCI -DCONFIG_NET_ACX_USB + +obj-$(CONFIG_WIRELESS_ACX) += acx.o + +acx-objs := wlan.o conv.o ioctl.o common.o pci.o usb.o --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/ioctl.c +++ linux-2.6.28/ubuntu/misc/wireless/acx/ioctl.c @@ -0,0 +1,2745 @@ +/*********************************************************************** +** Copyright (C) 2003 ACX100 Open Source Project +** +** The contents of this file are subject to the Mozilla Public +** License Version 1.1 (the "License"); you may not use this file +** except in compliance with the License. You may obtain a copy of +** the License at http://www.mozilla.org/MPL/ +** +** Software distributed under the License is distributed on an "AS +** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +** implied. See the License for the specific language governing +** rights and limitations under the License. +** +** Alternatively, the contents of this file may be used under the +** terms of the GNU Public License version 2 (the "GPL"), in which +** case the provisions of the GPL are applicable instead of the +** above. If you wish to allow the use of your version of this file +** only under the terms of the GPL and not to allow others to use +** your version of this file under the MPL, indicate your decision +** by deleting the provisions above and replace them with the notice +** and other provisions required by the GPL. If you do not delete +** the provisions above, a recipient may use your version of this +** file under either the MPL or the GPL. +** --------------------------------------------------------------------- +** Inquiries regarding the ACX100 Open Source Project can be +** made directly to: +** +** acx100-users@lists.sf.net +** http://acx100.sf.net +** --------------------------------------------------------------------- +*/ + +#include +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) +#include +#endif +#include +#include +#include +/* #include */ /* required for 2.4.x kernels; verify_write() */ +#include +#include +#include + +#include "acx.h" + + +/*********************************************************************** +*/ + +/* channel frequencies + * TODO: Currently, every other 802.11 driver keeps its own copy of this. In + * the long run this should be integrated into ieee802_11.h or wireless.h or + * whatever IEEE802.11x framework evolves */ +static const u16 acx_channel_freq[] = { + 2412, 2417, 2422, 2427, 2432, 2437, 2442, + 2447, 2452, 2457, 2462, 2467, 2472, 2484, +}; + + +/*********************************************************************** +** acx_ioctl_commit +*/ +static int +acx_ioctl_commit(struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + + FN_ENTER; + + acx_sem_lock(adev); + if (ACX_STATE_IFACE_UP & adev->dev_state_mask) + acx_s_update_card_settings(adev); + acx_sem_unlock(adev); + + FN_EXIT0; + return OK; +} + + +/*********************************************************************** +*/ +static int +acx_ioctl_get_name( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + static const char * const names[] = { "IEEE 802.11b+/g+", "IEEE 802.11b+" }; + + strcpy(wrqu->name, names[IS_ACX111(adev) ? 0 : 1]); + + return OK; +} + + +/*********************************************************************** +** acx_ioctl_set_freq +*/ +static int +acx_ioctl_set_freq( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int channel = -1; + unsigned int mult = 1; + int result; + + FN_ENTER; + + if (wrqu->freq.e == 0 && wrqu->freq.m <= 1000) { + /* Setting by channel number */ + channel = wrqu->freq.m; + } else { + /* If setting by frequency, convert to a channel */ + int i; + + for (i = 0; i < (6 - wrqu->freq.e); i++) + mult *= 10; + + for (i = 1; i <= 14; i++) + if (wrqu->freq.m == acx_channel_freq[i - 1] * mult) + channel = i; + } + + if (channel > 14) { + result = -EINVAL; + goto end; + } + + acx_sem_lock(adev); + + adev->channel = channel; + /* hmm, the following code part is strange, but this is how + * it was being done before... */ + log(L_IOCTL, "Changing to channel %d\n", channel); + SET_BIT(adev->set_mask, GETSET_CHANNEL); + + result = -EINPROGRESS; /* need to call commit handler */ + + acx_sem_unlock(adev); +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +*/ +static inline int +acx_ioctl_get_freq( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + wrqu->freq.e = 0; + wrqu->freq.m = adev->channel; + return OK; +} + + +/*********************************************************************** +** acx_ioctl_set_mode +*/ +static int +acx_ioctl_set_mode( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int result; + + FN_ENTER; + + acx_sem_lock(adev); + + switch (wrqu->mode) { + case IW_MODE_AUTO: + adev->mode = ACX_MODE_OFF; + break; + case IW_MODE_MONITOR: + adev->mode = ACX_MODE_MONITOR; + break; + case IW_MODE_ADHOC: + adev->mode = ACX_MODE_0_ADHOC; + break; + case IW_MODE_INFRA: + adev->mode = ACX_MODE_2_STA; + break; + case IW_MODE_MASTER: + printk("acx: master mode (HostAP) is very, very " + "experimental! It might work partially, but " + "better get prepared for nasty surprises " + "at any time\n"); + adev->mode = ACX_MODE_3_AP; + break; + case IW_MODE_REPEAT: + case IW_MODE_SECOND: + default: + result = -EOPNOTSUPP; + goto end_unlock; + } + + log(L_ASSOC, "new adev->mode=%d\n", adev->mode); + SET_BIT(adev->set_mask, GETSET_MODE); + result = -EINPROGRESS; + +end_unlock: + acx_sem_unlock(adev); + + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +*/ +static int +acx_ioctl_get_mode( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int result = 0; + + switch (adev->mode) { + case ACX_MODE_OFF: + wrqu->mode = IW_MODE_AUTO; break; + case ACX_MODE_MONITOR: + wrqu->mode = IW_MODE_MONITOR; break; + case ACX_MODE_0_ADHOC: + wrqu->mode = IW_MODE_ADHOC; break; + case ACX_MODE_2_STA: + wrqu->mode = IW_MODE_INFRA; break; + case ACX_MODE_3_AP: + wrqu->mode = IW_MODE_MASTER; break; + default: + result = -EOPNOTSUPP; + } + return result; +} + + +/*********************************************************************** +*/ +static int +acx_ioctl_set_sens( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->sens; + acx_device_t *adev = ndev2adev(ndev); + + acx_sem_lock(adev); + + adev->sensitivity = (1 == vwrq->disabled) ? 0 : vwrq->value; + SET_BIT(adev->set_mask, GETSET_SENSITIVITY); + + acx_sem_unlock(adev); + + return -EINPROGRESS; +} + + +/*********************************************************************** +*/ +static int +acx_ioctl_get_sens( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->sens; + acx_device_t *adev = ndev2adev(ndev); + + if (IS_USB(adev)) + /* setting the PHY reg via fw cmd doesn't work yet */ + return -EOPNOTSUPP; + + /* acx_sem_lock(adev); */ + + vwrq->value = adev->sensitivity; + vwrq->disabled = (vwrq->value == 0); + vwrq->fixed = 1; + + /* acx_sem_unlock(adev); */ + + return OK; +} + + +/*********************************************************************** +** acx_ioctl_set_ap +** +** Sets the MAC address of the AP to associate with +*/ +static int +acx_ioctl_set_ap( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct sockaddr *awrq = &wrqu->ap_addr; + acx_device_t *adev = ndev2adev(ndev); + int result = 0; + const u8 *ap; + + FN_ENTER; + if (NULL == awrq) { + result = -EFAULT; + goto end; + } + if (ARPHRD_ETHER != awrq->sa_family) { + result = -EINVAL; + goto end; + } + + ap = awrq->sa_data; + acxlog_mac(L_IOCTL, "set AP=", ap, "\n"); + + MAC_COPY(adev->ap, ap); + + /* We want to start rescan in managed or ad-hoc mode, + ** otherwise just set adev->ap. + ** "iwconfig ap mode managed": we must be able + ** to set ap _first_ and _then_ set mode */ + switch (adev->mode) { + case ACX_MODE_0_ADHOC: + case ACX_MODE_2_STA: + /* FIXME: if there is a convention on what zero AP means, + ** please add a comment about that. I don't know of any --vda */ + if (mac_is_zero(ap)) { + /* "off" == 00:00:00:00:00:00 */ + MAC_BCAST(adev->ap); + log(L_IOCTL, "Not reassociating\n"); + } else { + log(L_IOCTL, "Forcing reassociation\n"); + SET_BIT(adev->set_mask, GETSET_RESCAN); + } + break; + } + result = -EINPROGRESS; +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +*/ +static int +acx_ioctl_get_ap( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct sockaddr *awrq = &wrqu->ap_addr; + acx_device_t *adev = ndev2adev(ndev); + + if (ACX_STATUS_4_ASSOCIATED == adev->status) { + /* as seen in Aironet driver, airo.c */ + MAC_COPY(awrq->sa_data, adev->bssid); + } else { + MAC_ZERO(awrq->sa_data); + } + awrq->sa_family = ARPHRD_ETHER; + return OK; +} + + +/*********************************************************************** +** acx_ioctl_get_aplist +** +** Deprecated in favor of iwscan. +** We simply return the list of currently available stations in range, +** don't do a new scan. +*/ +static int +acx_ioctl_get_aplist( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_point *dwrq = &wrqu->data; + acx_device_t *adev = ndev2adev(ndev); + struct sockaddr *address = (struct sockaddr *) extra; + struct iw_quality qual[IW_MAX_AP]; + int i, cur; + int result = OK; + + FN_ENTER; + + /* we have AP list only in STA mode */ + if (ACX_MODE_2_STA != adev->mode) { + result = -EOPNOTSUPP; + goto end; + } + + cur = 0; + for (i = 0; i < VEC_SIZE(adev->sta_list); i++) { + struct client *bss = &adev->sta_list[i]; + if (!bss->used) continue; + MAC_COPY(address[cur].sa_data, bss->bssid); + address[cur].sa_family = ARPHRD_ETHER; + qual[cur].level = bss->sir; + qual[cur].noise = bss->snr; +#ifndef OLD_QUALITY + qual[cur].qual = acx_signal_determine_quality(qual[cur].level, + qual[cur].noise); +#else + qual[cur].qual = (qual[cur].noise <= 100) ? + 100 - qual[cur].noise : 0; +#endif + /* no scan: level/noise/qual not updated: */ + qual[cur].updated = 0; + cur++; + } + if (cur) { + dwrq->flags = 1; + memcpy(extra + sizeof(struct sockaddr)*cur, &qual, + sizeof(struct iw_quality)*cur); + } + dwrq->length = cur; +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +*/ +static int +acx_ioctl_set_scan( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int result; + + FN_ENTER; + + acx_sem_lock(adev); + + /* don't start scan if device is not up yet */ + if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) { + result = -EAGAIN; + goto end_unlock; + } + + /* This is NOT a rescan for new AP! + ** Do not use SET_BIT(GETSET_RESCAN); */ + acx_s_cmd_start_scan(adev); + result = OK; + +end_unlock: + acx_sem_unlock(adev); +/* end: */ + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_s_scan_add_station +*/ +/* helper. not sure whether it's really a _s_leeping fn */ +static char* +acx_s_scan_add_station( + acx_device_t *adev, + char *ptr, + char *end_buf, + struct client *bss, + struct iw_request_info *info) +{ + struct iw_event iwe; + char *ptr_rate; + + FN_ENTER; + + /* MAC address has to be added first */ + iwe.cmd = SIOCGIWAP; + iwe.u.ap_addr.sa_family = ARPHRD_ETHER; + MAC_COPY(iwe.u.ap_addr.sa_data, bss->bssid); + acxlog_mac(L_IOCTL, "scan, station address: ", bss->bssid, "\n"); + ptr = iwe_stream_add_event(info, ptr, end_buf, &iwe, IW_EV_ADDR_LEN); + + /* Add ESSID */ + iwe.cmd = SIOCGIWESSID; + iwe.u.data.length = bss->essid_len; + iwe.u.data.flags = 1; + log(L_IOCTL, "scan, essid: %s\n", bss->essid); + ptr = iwe_stream_add_point(info, ptr, end_buf, &iwe, bss->essid); + + /* Add mode */ + iwe.cmd = SIOCGIWMODE; + if (bss->cap_info & (WF_MGMT_CAP_ESS | WF_MGMT_CAP_IBSS)) { + if (bss->cap_info & WF_MGMT_CAP_ESS) + iwe.u.mode = IW_MODE_MASTER; + else + iwe.u.mode = IW_MODE_ADHOC; + log(L_IOCTL, "scan, mode: %d\n", iwe.u.mode); + ptr = iwe_stream_add_event(info, ptr, end_buf, &iwe, IW_EV_UINT_LEN); + } + + /* Add frequency */ + iwe.cmd = SIOCGIWFREQ; + iwe.u.freq.m = acx_channel_freq[bss->channel - 1] * 100000; + iwe.u.freq.e = 1; + log(L_IOCTL, "scan, frequency: %d\n", iwe.u.freq.m); + ptr = iwe_stream_add_event(info, ptr, end_buf, &iwe, IW_EV_FREQ_LEN); + + /* Add link quality */ + iwe.cmd = IWEVQUAL; + /* FIXME: these values should be expressed in dBm, but we don't know + * how to calibrate it yet */ + iwe.u.qual.level = bss->sir; + iwe.u.qual.noise = bss->snr; +#ifndef OLD_QUALITY + iwe.u.qual.qual = acx_signal_determine_quality(iwe.u.qual.level, + iwe.u.qual.noise); +#else + iwe.u.qual.qual = (iwe.u.qual.noise <= 100) ? + 100 - iwe.u.qual.noise : 0; +#endif + iwe.u.qual.updated = 7; + log(L_IOCTL, "scan, link quality: %d/%d/%d\n", + iwe.u.qual.level, iwe.u.qual.noise, iwe.u.qual.qual); + ptr = iwe_stream_add_event(info, ptr, end_buf, &iwe, IW_EV_QUAL_LEN); + + /* Add encryption */ + iwe.cmd = SIOCGIWENCODE; + if (bss->cap_info & WF_MGMT_CAP_PRIVACY) + iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; + else + iwe.u.data.flags = IW_ENCODE_DISABLED; + iwe.u.data.length = 0; + log(L_IOCTL, "scan, encryption flags: %X\n", iwe.u.data.flags); + ptr = iwe_stream_add_point(info, ptr, end_buf, &iwe, bss->essid); + + /* add rates */ + iwe.cmd = SIOCGIWRATE; + iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; + ptr_rate = ptr + IW_EV_LCP_LEN; + + { + u16 rate = bss->rate_cap; + const u8* p = acx_bitpos2ratebyte; + while (rate) { + if (rate & 1) { + iwe.u.bitrate.value = *p * 500000; /* units of 500kb/s */ + log(L_IOCTL, "scan, rate: %d\n", iwe.u.bitrate.value); + ptr_rate = iwe_stream_add_value(info, ptr, ptr_rate, end_buf, + &iwe, IW_EV_PARAM_LEN); + } + rate >>= 1; + p++; + }} + + if ((ptr_rate - ptr) > (ptrdiff_t)IW_EV_LCP_LEN) + ptr = ptr_rate; + + /* drop remaining station data items for now */ + + FN_EXIT0; + return ptr; +} + + +/*********************************************************************** + * acx_ioctl_get_scan + */ +static int +acx_ioctl_get_scan( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_point *dwrq = &wrqu->data; + acx_device_t *adev = ndev2adev(ndev); + char *ptr = extra; + int i; + int result = OK; + + FN_ENTER; + + acx_sem_lock(adev); + + /* no scan available if device is not up yet */ + if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) { + log(L_IOCTL, "iface not up yet\n"); + result = -EAGAIN; + goto end_unlock; + } + +#ifdef ENODATA_TO_BE_USED_AFTER_SCAN_ERROR_ONLY + if (adev->bss_table_count == 0) { + /* no stations found */ + result = -ENODATA; + goto end_unlock; + } +#endif + + for (i = 0; i < VEC_SIZE(adev->sta_list); i++) { + struct client *bss = &adev->sta_list[i]; + if (!bss->used) continue; + ptr = acx_s_scan_add_station(adev, ptr, + extra + IW_SCAN_MAX_DATA, bss, info); + } + dwrq->length = ptr - extra; + dwrq->flags = 0; + +end_unlock: + acx_sem_unlock(adev); +/* end: */ + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_ioctl_set_essid +*/ +static int +acx_ioctl_set_essid( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_point *dwrq = &wrqu->essid; + acx_device_t *adev = ndev2adev(ndev); + int len = dwrq->length; + int result; + + FN_ENTER; + + if (len < 0) { + result = -EINVAL; + goto end; + } + + log(L_IOCTL, "set ESSID '%*s', length %d, flags 0x%04X\n", + len, extra, len, dwrq->flags); + +#if WIRELESS_EXT >= 21 + /* WE 21 gives real ESSID strlen, not +1 (trailing zero): + * see LKML "[patch] drivers/net/wireless: correct reported ssid lengths" */ + len += 1; +#endif + + acx_sem_lock(adev); + + /* ESSID disabled? */ + if (0 == dwrq->flags) { + adev->essid_active = 0; + + } else { + if (dwrq->length > IW_ESSID_MAX_SIZE+1) { + result = -E2BIG; + goto end_unlock; + } + + if (len > sizeof(adev->essid)) + len = sizeof(adev->essid); + memcpy(adev->essid, extra, len-1); + adev->essid[len-1] = '\0'; + /* Paranoia: just in case there is a '\0'... */ + adev->essid_len = strlen(adev->essid); + adev->essid_active = 1; + } + + SET_BIT(adev->set_mask, GETSET_RESCAN); + + result = -EINPROGRESS; + +end_unlock: + acx_sem_unlock(adev); +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +*/ +static int +acx_ioctl_get_essid( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_point *dwrq = &wrqu->essid; + acx_device_t *adev = ndev2adev(ndev); + + dwrq->flags = adev->essid_active; + if (adev->essid_active) { + memcpy(extra, adev->essid, adev->essid_len); + extra[adev->essid_len] = '\0'; + dwrq->length = adev->essid_len + 1; + dwrq->flags = 1; + } + return OK; +} + + +/*********************************************************************** +** acx_l_update_client_rates +*/ +static void +acx_l_update_client_rates(acx_device_t *adev, u16 rate) +{ + int i; + for (i = 0; i < VEC_SIZE(adev->sta_list); i++) { + client_t *clt = &adev->sta_list[i]; + if (!clt->used) continue; + clt->rate_cfg = (clt->rate_cap & rate); + if (!clt->rate_cfg) { + /* no compatible rates left: kick client */ + acxlog_mac(L_ASSOC, "client ",clt->address," kicked: " + "rates are not compatible anymore\n"); + acx_l_sta_list_del(adev, clt); + continue; + } + clt->rate_cur &= clt->rate_cfg; + if (!clt->rate_cur) { + /* current rate become invalid, choose a valid one */ + clt->rate_cur = 1 << lowest_bit(clt->rate_cfg); + } + if (IS_ACX100(adev)) + clt->rate_100 = acx_bitpos2rate100[highest_bit(clt->rate_cur)]; + clt->fallback_count = clt->stepup_count = 0; + clt->ignore_count = 16; + } + switch (adev->mode) { + case ACX_MODE_2_STA: + if (adev->ap_client && !adev->ap_client->used) { + /* Owwww... we kicked our AP!! :) */ + SET_BIT(adev->set_mask, GETSET_RESCAN); + } + } +} + + +/*********************************************************************** +*/ +/* maps bits from acx111 rate to rate in Mbits */ +static const unsigned int +acx111_rate_tbl[] = { + 1000000, /* 0 */ + 2000000, /* 1 */ + 5500000, /* 2 */ + 6000000, /* 3 */ + 9000000, /* 4 */ + 11000000, /* 5 */ + 12000000, /* 6 */ + 18000000, /* 7 */ + 22000000, /* 8 */ + 24000000, /* 9 */ + 36000000, /* 10 */ + 48000000, /* 11 */ + 54000000, /* 12 */ + 500000, /* 13, should not happen */ + 500000, /* 14, should not happen */ + 500000, /* 15, should not happen */ +}; + +/*********************************************************************** + * acx_ioctl_set_rate + */ +static int +acx_ioctl_set_rate( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->param; + acx_device_t *adev = ndev2adev(ndev); + u16 txrate_cfg = 1; + unsigned long flags; + int autorate; + int result = -EINVAL; + + FN_ENTER; + log(L_IOCTL, "rate %d fixed 0x%X disabled 0x%X flags 0x%X\n", + vwrq->value, vwrq->fixed, vwrq->disabled, vwrq->flags); + + if ((0 == vwrq->fixed) || (1 == vwrq->fixed)) { + int i = VEC_SIZE(acx111_rate_tbl)-1; + if (vwrq->value == -1) + /* "iwconfig rate auto" --> choose highest */ + vwrq->value = IS_ACX100(adev) ? 22000000 : 54000000; + while (i >= 0) { + if (vwrq->value == acx111_rate_tbl[i]) { + txrate_cfg <<= i; + i = 0; + break; + } + i--; + } + if (i == -1) { /* no matching rate */ + result = -EINVAL; + goto end; + } + } else { /* rate N, N<1000 (driver specific): we don't use this */ + result = -EOPNOTSUPP; + goto end; + } + /* now: only one bit is set in txrate_cfg, corresponding to + ** indicated rate */ + + autorate = (vwrq->fixed == 0) && (RATE111_1 != txrate_cfg); + if (autorate) { + /* convert 00100000 -> 00111111 */ + txrate_cfg = (txrate_cfg<<1)-1; + } + + if (IS_ACX100(adev)) { + txrate_cfg &= RATE111_ACX100_COMPAT; + if (!txrate_cfg) { + result = -ENOTSUPP; /* rate is not supported by acx100 */ + goto end; + } + } + + acx_sem_lock(adev); + acx_lock(adev, flags); + + adev->rate_auto = autorate; + adev->rate_oper = txrate_cfg; + adev->rate_basic = txrate_cfg; + /* only do that in auto mode, non-auto will be able to use + * one specific Tx rate only anyway */ + if (autorate) { + /* only use 802.11b base rates, for standard 802.11b H/W + * compatibility */ + adev->rate_basic &= RATE111_80211B_COMPAT; + } + adev->rate_bcast = 1 << lowest_bit(txrate_cfg); + if (IS_ACX100(adev)) + adev->rate_bcast100 = acx_rate111to100(adev->rate_bcast); + acx_l_update_ratevector(adev); + acx_l_update_client_rates(adev, txrate_cfg); + + /* Do/don't do tx rate fallback; beacon contents and rate */ + SET_BIT(adev->set_mask, SET_RATE_FALLBACK|SET_TEMPLATES); + result = -EINPROGRESS; + + acx_unlock(adev, flags); + acx_sem_unlock(adev); +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_ioctl_get_rate +*/ +static int +acx_ioctl_get_rate( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->param; + acx_device_t *adev = ndev2adev(ndev); + unsigned long flags; + u16 rate; + + acx_lock(adev, flags); + rate = adev->rate_oper; + if (adev->ap_client) + rate = adev->ap_client->rate_cur; + vwrq->value = acx111_rate_tbl[highest_bit(rate)]; + vwrq->fixed = !adev->rate_auto; + vwrq->disabled = 0; + acx_unlock(adev, flags); + + return OK; +} + +static int +acx_ioctl_set_rts( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->rts; + acx_device_t *adev = ndev2adev(ndev); + int val = vwrq->value; + + if (vwrq->disabled) + val = 2312; + if ((val < 0) || (val > 2312)) + return -EINVAL; + + adev->rts_threshold = val; + return OK; +} + +static inline int +acx_ioctl_get_rts( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->rts; + acx_device_t *adev = ndev2adev(ndev); + + vwrq->value = adev->rts_threshold; + vwrq->disabled = (vwrq->value >= 2312); + vwrq->fixed = 1; + return OK; +} + + +#if ACX_FRAGMENTATION +static int +acx_ioctl_set_frag( + struct net_device *ndev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int val = vwrq->value; + + if (vwrq->disabled) + val = 32767; + else + if ((val < 256) || (val > 2347)) + return -EINVAL; + + adev->frag_threshold = val; + return OK; +} + +static inline int +acx_ioctl_get_frag( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->frag; + acx_device_t *adev = ndev2adev(ndev); + + vwrq->value = adev->frag_threshold; + vwrq->disabled = (vwrq->value >= 2347); + vwrq->fixed = 1; + return OK; +} +#endif + + +/*********************************************************************** +** acx_ioctl_set_encode +*/ +static int +acx_ioctl_set_encode( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_point *dwrq = &wrqu->encoding; + acx_device_t *adev = ndev2adev(ndev); + int index; + int result; + + FN_ENTER; + + log(L_IOCTL, "set encoding flags=0x%04X, size=%d, key: %s\n", + dwrq->flags, dwrq->length, extra ? "set" : "No key"); + + acx_sem_lock(adev); + + index = (dwrq->flags & IW_ENCODE_INDEX) - 1; + + if (dwrq->length > 0) { + /* if index is 0 or invalid, use default key */ + if ((index < 0) || (index > 3)) + index = (int)adev->wep_current_index; + + if (0 == (dwrq->flags & IW_ENCODE_NOKEY)) { + if (dwrq->length > 29) + dwrq->length = 29; /* restrict it */ + + if (dwrq->length > 13) { + /* 29*8 == 232, WEP256 */ + adev->wep_keys[index].size = 29; + } else if (dwrq->length > 5) { + /* 13*8 == 104bit, WEP128 */ + adev->wep_keys[index].size = 13; + } else if (dwrq->length > 0) { + /* 5*8 == 40bit, WEP64 */ + adev->wep_keys[index].size = 5; + } else { + /* disable key */ + adev->wep_keys[index].size = 0; + } + + memset(adev->wep_keys[index].key, 0, + sizeof(adev->wep_keys[index].key)); + memcpy(adev->wep_keys[index].key, extra, dwrq->length); + } + } else { + /* set transmit key */ + if ((index >= 0) && (index <= 3)) + adev->wep_current_index = index; + else if (0 == (dwrq->flags & IW_ENCODE_MODE)) { + /* complain if we were not just setting + * the key mode */ + result = -EINVAL; + goto end_unlock; + } + } + + adev->wep_enabled = !(dwrq->flags & IW_ENCODE_DISABLED); + + if (dwrq->flags & IW_ENCODE_OPEN) { + adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM; + adev->wep_restricted = 0; + + } else if (dwrq->flags & IW_ENCODE_RESTRICTED) { + adev->auth_alg = WLAN_AUTH_ALG_SHAREDKEY; + adev->wep_restricted = 1; + } + + /* set flag to make sure the card WEP settings get updated */ + SET_BIT(adev->set_mask, GETSET_WEP); + + log(L_IOCTL, "len=%d, key at 0x%p, flags=0x%X\n", + dwrq->length, extra, dwrq->flags); + + for (index = 0; index <= 3; index++) { + if (adev->wep_keys[index].size) { + log(L_IOCTL, "index=%d, size=%d, key at 0x%p\n", + adev->wep_keys[index].index, + (int) adev->wep_keys[index].size, + adev->wep_keys[index].key); + } + } + result = -EINPROGRESS; + +end_unlock: + acx_sem_unlock(adev); + + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_ioctl_get_encode +*/ +static int +acx_ioctl_get_encode( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_point *dwrq = &wrqu->encoding; + acx_device_t *adev = ndev2adev(ndev); + int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; + + FN_ENTER; + + if (adev->wep_enabled == 0) { + dwrq->flags = IW_ENCODE_DISABLED; + } else { + if ((index < 0) || (index > 3)) + index = (int)adev->wep_current_index; + + dwrq->flags = (adev->wep_restricted == 1) ? + IW_ENCODE_RESTRICTED : IW_ENCODE_OPEN; + dwrq->length = adev->wep_keys[index].size; + + memcpy(extra, adev->wep_keys[index].key, + adev->wep_keys[index].size); + } + + /* set the current index */ + SET_BIT(dwrq->flags, index + 1); + + log(L_IOCTL, "len=%d, key=%p, flags=0x%X\n", + dwrq->length, dwrq->pointer, + dwrq->flags); + + FN_EXIT1(OK); + return OK; +} + + +/*********************************************************************** +*/ +static int +acx_ioctl_set_power( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->power; + acx_device_t *adev = ndev2adev(ndev); + int result = -EINPROGRESS; + + FN_ENTER; + + log(L_IOCTL, "set 802.11 powersave flags=0x%04X\n", vwrq->flags); + + acx_sem_lock(adev); + + if (vwrq->disabled) { + CLEAR_BIT(adev->ps_wakeup_cfg, PS_CFG_ENABLE); + SET_BIT(adev->set_mask, GETSET_POWER_80211); + goto end; + } + if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { + u16 ps_timeout = (vwrq->value * 1024) / 1000; + + if (ps_timeout > 255) + ps_timeout = 255; + log(L_IOCTL, "setting PS timeout value to %d time units " + "due to %dus\n", ps_timeout, vwrq->value); + adev->ps_hangover_period = ps_timeout; + } else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) { + u16 ps_periods = vwrq->value / 1000000; + + if (ps_periods > 255) + ps_periods = 255; + log(L_IOCTL, "setting PS period value to %d periods " + "due to %dus\n", ps_periods, vwrq->value); + adev->ps_listen_interval = ps_periods; + CLEAR_BIT(adev->ps_wakeup_cfg, PS_CFG_WAKEUP_MODE_MASK); + SET_BIT(adev->ps_wakeup_cfg, PS_CFG_WAKEUP_EACH_ITVL); + } + + switch (vwrq->flags & IW_POWER_MODE) { + /* FIXME: are we doing the right thing here? */ + case IW_POWER_UNICAST_R: + CLEAR_BIT(adev->ps_options, PS_OPT_STILL_RCV_BCASTS); + break; + case IW_POWER_MULTICAST_R: + SET_BIT(adev->ps_options, PS_OPT_STILL_RCV_BCASTS); + break; + case IW_POWER_ALL_R: + SET_BIT(adev->ps_options, PS_OPT_STILL_RCV_BCASTS); + break; + case IW_POWER_ON: + break; + default: + log(L_IOCTL, "unknown PS mode\n"); + result = -EINVAL; + goto end; + } + + SET_BIT(adev->ps_wakeup_cfg, PS_CFG_ENABLE); + SET_BIT(adev->set_mask, GETSET_POWER_80211); +end: + acx_sem_unlock(adev); + + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +*/ +static int +acx_ioctl_get_power( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->power; + acx_device_t *adev = ndev2adev(ndev); + + FN_ENTER; + + log(L_IOCTL, "Get 802.11 Power Save flags = 0x%04X\n", vwrq->flags); + vwrq->disabled = ((adev->ps_wakeup_cfg & PS_CFG_ENABLE) == 0); + if (vwrq->disabled) + goto end; + + if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { + vwrq->value = adev->ps_hangover_period * 1000 / 1024; + vwrq->flags = IW_POWER_TIMEOUT; + } else { + vwrq->value = adev->ps_listen_interval * 1000000; + vwrq->flags = IW_POWER_PERIOD|IW_POWER_RELATIVE; + } + if (adev->ps_options & PS_OPT_STILL_RCV_BCASTS) + SET_BIT(vwrq->flags, IW_POWER_ALL_R); + else + SET_BIT(vwrq->flags, IW_POWER_UNICAST_R); +end: + FN_EXIT1(OK); + return OK; +} + + +/*********************************************************************** +** acx_ioctl_get_txpow +*/ +static inline int +acx_ioctl_get_txpow( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->power; + acx_device_t *adev = ndev2adev(ndev); + + FN_ENTER; + + vwrq->flags = IW_TXPOW_DBM; + vwrq->disabled = 0; + vwrq->fixed = 1; + vwrq->value = adev->tx_level_dbm; + + log(L_IOCTL, "get txpower:%d dBm\n", adev->tx_level_dbm); + + FN_EXIT1(OK); + return OK; +} + + +/*********************************************************************** +** acx_ioctl_set_txpow +*/ +static int +acx_ioctl_set_txpow( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->power; + acx_device_t *adev = ndev2adev(ndev); + int result; + + FN_ENTER; + + log(L_IOCTL, "set txpower:%d, disabled:%d, flags:0x%04X\n", + vwrq->value, vwrq->disabled, vwrq->flags); + + acx_sem_lock(adev); + + if (vwrq->disabled != adev->tx_disabled) { + SET_BIT(adev->set_mask, GETSET_TX); + } + + adev->tx_disabled = vwrq->disabled; + if (vwrq->value == -1) { + if (vwrq->disabled) { + adev->tx_level_dbm = 0; + log(L_IOCTL, "disable radio tx\n"); + } else { + /* adev->tx_level_auto = 1; */ + log(L_IOCTL, "set tx power auto (NIY)\n"); + } + } else { + adev->tx_level_dbm = vwrq->value <= 20 ? vwrq->value : 20; + /* adev->tx_level_auto = 0; */ + log(L_IOCTL, "set txpower=%d dBm\n", adev->tx_level_dbm); + } + SET_BIT(adev->set_mask, GETSET_TXPOWER); + + result = -EINPROGRESS; + + acx_sem_unlock(adev); + + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_ioctl_get_range +*/ +static int +acx_ioctl_get_range( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_point *dwrq = &wrqu->data; + struct iw_range *range = (struct iw_range *)extra; + acx_device_t *adev = ndev2adev(ndev); + int i,n; + + FN_ENTER; + + if (!dwrq->pointer) + goto end; + + dwrq->length = sizeof(struct iw_range); + memset(range, 0, sizeof(struct iw_range)); + n = 0; + for (i = 1; i <= 14; i++) { + if (adev->reg_dom_chanmask & (1 << (i - 1))) { + range->freq[n].i = i; + range->freq[n].m = acx_channel_freq[i - 1] * 100000; + range->freq[n].e = 1; /* units are MHz */ + n++; + } + } + range->num_channels = n; + range->num_frequency = n; + + range->min_rts = 0; + range->max_rts = 2312; + +#if ACX_FRAGMENTATION + range->min_frag = 256; + range->max_frag = 2312; +#endif + + range->encoding_size[0] = 5; + range->encoding_size[1] = 13; + range->encoding_size[2] = 29; + range->num_encoding_sizes = 3; + range->max_encoding_tokens = 4; + + range->min_pmp = 0; + range->max_pmp = 5000000; + range->min_pmt = 0; + range->max_pmt = 65535 * 1000; + range->pmp_flags = IW_POWER_PERIOD; + range->pmt_flags = IW_POWER_TIMEOUT; + range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R; + + if (IS_ACX100(adev)) { /* ACX100 has direct radio programming - arbitrary levels, so offer a lot */ + for (i = 0; i <= IW_MAX_TXPOWER - 1; i++) + range->txpower[i] = 20 * i / (IW_MAX_TXPOWER - 1); + range->num_txpower = IW_MAX_TXPOWER; + range->txpower_capa = IW_TXPOW_DBM; + } + else { + int count = min(IW_MAX_TXPOWER, (int)adev->cfgopt_power_levels.len); + for (i = 0; i <= count; i++) + range->txpower[i] = adev->cfgopt_power_levels.list[i]; + range->num_txpower = count; + /* this list is given in mW */ + range->txpower_capa = IW_TXPOW_MWATT; + } + + range->we_version_compiled = WIRELESS_EXT; + range->we_version_source = 0x9; + + range->retry_capa = IW_RETRY_LIMIT; + range->retry_flags = IW_RETRY_LIMIT; + range->min_retry = 1; + range->max_retry = 255; + + range->r_time_flags = IW_RETRY_LIFETIME; + range->min_r_time = 0; + /* FIXME: lifetime ranges and orders of magnitude are strange?? */ + range->max_r_time = 65535; + + if (IS_USB(adev)) + range->sensitivity = 0; + else if (IS_ACX111(adev)) + range->sensitivity = 3; + else + range->sensitivity = 255; + + for (i=0; i < adev->rate_supported_len; i++) { + range->bitrate[i] = (adev->rate_supported[i] & ~0x80) * 500000; + /* never happens, but keep it, to be safe: */ + if (range->bitrate[i] == 0) + break; + } + range->num_bitrates = i; + + range->max_qual.qual = 100; + range->max_qual.level = 100; + range->max_qual.noise = 100; + /* TODO: better values */ + range->avg_qual.qual = 90; + range->avg_qual.level = 80; + range->avg_qual.noise = 2; + +end: + FN_EXIT1(OK); + return OK; +} + + +/*********************************************************************** +** Private functions +*/ + +/*********************************************************************** +** acx_ioctl_get_nick +*/ +static inline int +acx_ioctl_get_nick( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_point *dwrq = &wrqu->data; + acx_device_t *adev = ndev2adev(ndev); + + strcpy(extra, adev->nick); + dwrq->length = strlen(extra) + 1; + + return OK; +} + + +/*********************************************************************** +** acx_ioctl_set_nick +*/ +static int +acx_ioctl_set_nick( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_point *dwrq = &wrqu->data; + acx_device_t *adev = ndev2adev(ndev); + int result; + + FN_ENTER; + + acx_sem_lock(adev); + + if (dwrq->length > IW_ESSID_MAX_SIZE + 1) { + result = -E2BIG; + goto end_unlock; + } + + /* extra includes trailing \0, so it's ok */ + strcpy(adev->nick, extra); + result = OK; + +end_unlock: + acx_sem_unlock(adev); + + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_ioctl_get_retry +*/ +static int +acx_ioctl_get_retry( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->retry; + acx_device_t *adev = ndev2adev(ndev); + unsigned int type = vwrq->flags & IW_RETRY_TYPE; + unsigned int modifier = vwrq->flags & IW_RETRY_MODIFIER; + int result; + + FN_ENTER; + + acx_sem_lock(adev); + + /* return the short retry number by default */ + if (type == IW_RETRY_LIFETIME) { + vwrq->flags = IW_RETRY_LIFETIME; + vwrq->value = adev->msdu_lifetime; + } else if (modifier == IW_RETRY_MAX) { + vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; + vwrq->value = adev->long_retry; + } else { + vwrq->flags = IW_RETRY_LIMIT; + if (adev->long_retry != adev->short_retry) + SET_BIT(vwrq->flags, IW_RETRY_MIN); + vwrq->value = adev->short_retry; + } + + /* can't be disabled */ + vwrq->disabled = (u8)0; + result = OK; + + acx_sem_unlock(adev); + + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_ioctl_set_retry +*/ +static int +acx_ioctl_set_retry( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->retry; + acx_device_t *adev = ndev2adev(ndev); + int result; + + FN_ENTER; + + if (!vwrq) { + result = -EFAULT; + goto end; + } + if (vwrq->disabled) { + result = -EINVAL; + goto end; + } + + acx_sem_lock(adev); + + result = -EINVAL; + if (IW_RETRY_LIMIT == (vwrq->flags & IW_RETRY_TYPE)) { + printk("old retry limits: short %d long %d\n", + adev->short_retry, adev->long_retry); + if (vwrq->flags & IW_RETRY_MAX) { + adev->long_retry = vwrq->value; + } else if (vwrq->flags & IW_RETRY_MIN) { + adev->short_retry = vwrq->value; + } else { + /* no modifier: set both */ + adev->long_retry = vwrq->value; + adev->short_retry = vwrq->value; + } + printk("new retry limits: short %d long %d\n", + adev->short_retry, adev->long_retry); + SET_BIT(adev->set_mask, GETSET_RETRY); + result = -EINPROGRESS; + } + else if (vwrq->flags & IW_RETRY_LIFETIME) { + adev->msdu_lifetime = vwrq->value; + printk("new MSDU lifetime: %d\n", adev->msdu_lifetime); + SET_BIT(adev->set_mask, SET_MSDU_LIFETIME); + result = -EINPROGRESS; + } + + acx_sem_unlock(adev); +end: + FN_EXIT1(result); + return result; +} + + +/************************ private ioctls ******************************/ + + +/*********************************************************************** +** acx_ioctl_set_debug +*/ +#if ACX_DEBUG +static int +acx_ioctl_set_debug( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + unsigned int debug_new = *((unsigned int *)extra); + int result = -EINVAL; + + log(L_ANY, "setting debug from %04X to %04X\n", acx_debug, debug_new); + acx_debug = debug_new; + + result = OK; + return result; + +} +#endif + + +/*********************************************************************** +** acx_ioctl_list_reg_domain +*/ +static int +acx_ioctl_list_reg_domain( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int i = 1; + const char * const *entry = acx_reg_domain_strings; + + printk("dom# chan# domain/country\n"); + while (*entry) + printk("%4d %s\n", i++, *entry++); + return OK; +} + + +/*********************************************************************** +** acx_ioctl_set_reg_domain +*/ +static int +acx_ioctl_set_reg_domain( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int result; + + FN_ENTER; + + if ((*extra < 1) || ((size_t)*extra > acx_reg_domain_ids_len)) { + result = -EINVAL; + goto end; + } + + acx_sem_lock(adev); + + adev->reg_dom_id = acx_reg_domain_ids[*extra - 1]; + SET_BIT(adev->set_mask, GETSET_REG_DOMAIN); + + result = -EINPROGRESS; + + acx_sem_unlock(adev); +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_ioctl_get_reg_domain +*/ +static int +acx_ioctl_get_reg_domain( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int dom,i; + + /* no locking */ + dom = adev->reg_dom_id; + + for (i = 1; i <= acx_reg_domain_ids_len; i++) { + if (acx_reg_domain_ids[i-1] == dom) { + log(L_IOCTL, "regulatory domain is currently set " + "to %d (0x%X): %s\n", i, dom, + acx_reg_domain_strings[i-1]); + *extra = i; + break; + } + } + + return OK; +} + + +/*********************************************************************** +** acx_ioctl_set_short_preamble +*/ +static const char * const +preamble_modes[] = { + "off", + "on", + "auto (peer capability dependent)", + "unknown mode, error" +}; + +static int +acx_ioctl_set_short_preamble( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int i; + int result; + + FN_ENTER; + + if ((unsigned char)*extra > 2) { + result = -EINVAL; + goto end; + } + + acx_sem_lock(adev); + + adev->preamble_mode = (u8)*extra; + switch (adev->preamble_mode) { + case 0: /* long */ + adev->preamble_cur = 0; + break; + case 1: + /* short, kick incapable peers */ + adev->preamble_cur = 1; + for (i = 0; i < VEC_SIZE(adev->sta_list); i++) { + client_t *clt = &adev->sta_list[i]; + if (!clt->used) continue; + if (!(clt->cap_info & WF_MGMT_CAP_SHORT)) { + clt->used = CLIENT_EMPTY_SLOT_0; + } + } + switch (adev->mode) { + case ACX_MODE_2_STA: + if (adev->ap_client && !adev->ap_client->used) { + /* We kicked our AP :) */ + SET_BIT(adev->set_mask, GETSET_RESCAN); + } + } + break; + case 2: /* auto. short only if all peers are short-capable */ + adev->preamble_cur = 1; + for (i = 0; i < VEC_SIZE(adev->sta_list); i++) { + client_t *clt = &adev->sta_list[i]; + if (!clt->used) continue; + if (!(clt->cap_info & WF_MGMT_CAP_SHORT)) { + adev->preamble_cur = 0; + break; + } + } + break; + } + printk("new short preamble setting: configured %s, active %s\n", + preamble_modes[adev->preamble_mode], + preamble_modes[adev->preamble_cur]); + result = OK; + + acx_sem_unlock(adev); +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_ioctl_get_short_preamble +*/ +static int +acx_ioctl_get_short_preamble( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + + acx_sem_lock(adev); + + printk("current short preamble setting: configured %s, active %s\n", + preamble_modes[adev->preamble_mode], + preamble_modes[adev->preamble_cur]); + + *extra = (char)adev->preamble_mode; + + acx_sem_unlock(adev); + + return OK; +} + + +/*********************************************************************** +** acx_ioctl_set_antenna +** +** TX and RX antenna can be set separately but this function good +** for testing 0-4 bits +*/ +static int +acx_ioctl_set_antenna( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + + acx_sem_lock(adev); + + printk("old antenna value: 0x%02X (COMBINED bit mask)\n" + "Rx antenna selection:\n" + "0x00 ant. 1\n" + "0x40 ant. 2\n" + "0x80 full diversity\n" + "0xc0 partial diversity\n" + "0x0f dwell time mask (in units of us)\n" + "Tx antenna selection:\n" + "0x00 ant. 2\n" /* yep, those ARE reversed! */ + "0x20 ant. 1\n" + "new antenna value: 0x%02X\n", + adev->antenna, (u8)*extra); + + adev->antenna = (u8)*extra; + SET_BIT(adev->set_mask, GETSET_ANTENNA); + + acx_sem_unlock(adev); + + return -EINPROGRESS; +} + + +/*********************************************************************** +** acx_ioctl_get_antenna +*/ +static int +acx_ioctl_get_antenna( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + + /* no locking. it's pointless to lock a single load */ + printk("current antenna value: 0x%02X (COMBINED bit mask)\n" + "Rx antenna selection:\n" + "0x00 ant. 1\n" + "0x40 ant. 2\n" + "0x80 full diversity\n" + "0xc0 partial diversity\n" + "Tx antenna selection:\n" + "0x00 ant. 2\n" /* yep, those ARE reversed! */ + "0x20 ant. 1\n", adev->antenna); + + return 0; +} + + +/*********************************************************************** +** acx_ioctl_set_rx_antenna +** +** 0 = antenna1; 1 = antenna2; 2 = full diversity; 3 = partial diversity +** Could anybody test which antenna is the external one? +*/ +static int +acx_ioctl_set_rx_antenna( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int result; + + FN_ENTER; + + if (*extra > 3) { + result = -EINVAL; + goto end; + } + + printk("old antenna value: 0x%02X\n", adev->antenna); + + acx_sem_lock(adev); + + adev->antenna &= 0x3f; + SET_BIT(adev->antenna, (*extra << 6)); + SET_BIT(adev->set_mask, GETSET_ANTENNA); + printk("new antenna value: 0x%02X\n", adev->antenna); + result = -EINPROGRESS; + + acx_sem_unlock(adev); +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_ioctl_set_tx_antenna +** +** Arguments: 0 == antenna2; 1 == antenna1; +** Could anybody test which antenna is the external one? +*/ +static int +acx_ioctl_set_tx_antenna( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int result; + + FN_ENTER; + + if (*extra > 1) { + result = -EINVAL; + goto end; + } + + printk("old antenna value: 0x%02X\n", adev->antenna); + + acx_sem_lock(adev); + + adev->antenna &= ~0x30; + SET_BIT(adev->antenna, ((*extra & 0x01) << 5)); + SET_BIT(adev->set_mask, GETSET_ANTENNA); + printk("new antenna value: 0x%02X\n", adev->antenna); + result = -EINPROGRESS; + + acx_sem_unlock(adev); +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_ioctl_wlansniff +** +** can we just remove this in favor of monitor mode? --vda +*/ +static int +acx_ioctl_wlansniff( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + unsigned int *params = (unsigned int*)extra; + unsigned int enable = (unsigned int)(params[0] > 0); + int result; + + FN_ENTER; + + acx_sem_lock(adev); + + /* not using printk() here, since it distorts kismet display + * when printk messages activated */ + log(L_IOCTL, "setting monitor to: 0x%02X\n", params[0]); + + switch (params[0]) { + case 0: + /* no monitor mode. hmm, should we simply ignore it + * or go back to enabling adev->netdev->type ARPHRD_ETHER? */ + break; + case 1: + adev->monitor_type = ARPHRD_IEEE80211_PRISM; + break; + case 2: + adev->monitor_type = ARPHRD_IEEE80211; + break; + } + + if (params[0]) { + adev->mode = ACX_MODE_MONITOR; + SET_BIT(adev->set_mask, GETSET_MODE); + } + + if (enable) { + adev->channel = params[1]; + SET_BIT(adev->set_mask, GETSET_RX); + } + result = -EINPROGRESS; + + acx_sem_unlock(adev); + + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_ioctl_unknown11 +** FIXME: looks like some sort of "iwpriv kick_sta MAC" but it's broken +*/ +static int +acx_ioctl_unknown11( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ +#ifdef BROKEN + struct iw_param *vwrq = &wrqu->param; + acx_device_t *adev = ndev2adev(ndev); + unsigned long flags; + client_t client; + int result; + + acx_sem_lock(adev); + acx_lock(adev, flags); + + acx_l_transmit_disassoc(adev, &client); + result = OK; + + acx_unlock(adev, flags); + acx_sem_unlock(adev); + + return result; +#endif + return -EINVAL; +} + + +/*********************************************************************** +** debug helper function to be able to debug various issues relatively easily +*/ +static int +acx_ioctl_dbg_set_masks( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + const unsigned int *params = (unsigned int*)extra; + int result; + + acx_sem_lock(adev); + + log(L_IOCTL, "setting flags in settings mask: " + "get_mask %08X set_mask %08X\n" + "before: get_mask %08X set_mask %08X\n", + params[0], params[1], + adev->get_mask, adev->set_mask); + SET_BIT(adev->get_mask, params[0]); + SET_BIT(adev->set_mask, params[1]); + log(L_IOCTL, "after: get_mask %08X set_mask %08X\n", + adev->get_mask, adev->set_mask); + result = -EINPROGRESS; /* immediately call commit handler */ + + acx_sem_unlock(adev); + + return result; +} + + +/*********************************************************************** +* acx_ioctl_set_rates +* +* This ioctl takes string parameter. Examples: +* iwpriv wlan0 SetRates "1,2" +* use 1 and 2 Mbit rates, both are in basic rate set +* iwpriv wlan0 SetRates "1,2 5,11" +* use 1,2,5.5,11 Mbit rates. 1 and 2 are basic +* iwpriv wlan0 SetRates "1,2 5c,11c" +* same ('c' means 'CCK modulation' and it is a default for 5 and 11) +* iwpriv wlan0 SetRates "1,2 5p,11p" +* use 1,2,5.5,11 Mbit, 1,2 are basic. 5 and 11 are using PBCC +* iwpriv wlan0 SetRates "1,2,5,11 22p" +* use 1,2,5.5,11,22 Mbit. 1,2,5.5 and 11 are basic. 22 is using PBCC +* (this is the maximum acx100 can do (modulo x4 mode)) +* iwpriv wlan0 SetRates "1,2,5,11 22" +* same. 802.11 defines only PBCC modulation +* for 22 and 33 Mbit rates, so there is no ambiguity +* iwpriv wlan0 SetRates "1,2,5,11 6o,9o,12o,18o,24o,36o,48o,54o" +* 1,2,5.5 and 11 are basic. 11g OFDM rates are enabled but +* they are not in basic rate set. 22 Mbit is disabled. +* iwpriv wlan0 SetRates "1,2,5,11 6,9,12,18,24,36,48,54" +* same. OFDM is default for 11g rates except 22 and 33 Mbit, +* thus 'o' is optional +* iwpriv wlan0 SetRates "1,2,5,11 6d,9d,12d,18d,24d,36d,48d,54d" +* 1,2,5.5 and 11 are basic. 11g CCK-OFDM rates are enabled +* (acx111 does not support CCK-OFDM, driver will reject this cmd) +* iwpriv wlan0 SetRates "6,9,12 18,24,36,48,54" +* 6,9,12 are basic, rest of 11g rates is enabled. Using OFDM +*/ +#include "setrate.c" + +/* disallow: 33Mbit (unsupported by hw) */ +/* disallow: CCKOFDM (unsupported by hw) */ +static int +acx111_supported(int mbit, int modulation, void *opaque) +{ + if (mbit==33) return -ENOTSUPP; + if (modulation==DOT11_MOD_CCKOFDM) return -ENOTSUPP; + return OK; +} + +static const u16 +acx111mask[] = { + [DOT11_RATE_1 ] = RATE111_1 , + [DOT11_RATE_2 ] = RATE111_2 , + [DOT11_RATE_5 ] = RATE111_5 , + [DOT11_RATE_11] = RATE111_11, + [DOT11_RATE_22] = RATE111_22, + /* [DOT11_RATE_33] = */ + [DOT11_RATE_6 ] = RATE111_6 , + [DOT11_RATE_9 ] = RATE111_9 , + [DOT11_RATE_12] = RATE111_12, + [DOT11_RATE_18] = RATE111_18, + [DOT11_RATE_24] = RATE111_24, + [DOT11_RATE_36] = RATE111_36, + [DOT11_RATE_48] = RATE111_48, + [DOT11_RATE_54] = RATE111_54, +}; + +static u32 +acx111_gen_mask(int mbit, int modulation, void *opaque) +{ + /* lower 16 bits show selected 1, 2, CCK and OFDM rates */ + /* upper 16 bits show selected PBCC rates */ + u32 m = acx111mask[rate_mbit2enum(mbit)]; + if (modulation==DOT11_MOD_PBCC) + return m<<16; + return m; +} + +static int +verify_rate(u32 rate, int chip_type) +{ + /* never happens. be paranoid */ + if (!rate) return -EINVAL; + + /* disallow: mixing PBCC and CCK at 5 and 11Mbit + ** (can be supported, but needs complicated handling in tx code) */ + if (( rate & ((RATE111_11+RATE111_5)<<16) ) + && ( rate & (RATE111_11+RATE111_5) ) + ) { + return -ENOTSUPP; + } + if (CHIPTYPE_ACX100 == chip_type) { + if ( rate & ~(RATE111_ACX100_COMPAT+(RATE111_ACX100_COMPAT<<16)) ) + return -ENOTSUPP; + } + return 0; +} + +static int +acx_ioctl_set_rates(struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + unsigned long flags; + int result; + u32 brate = 0, orate = 0; /* basic, operational rate set */ + + FN_ENTER; + + log(L_IOCTL, "set_rates %s\n", extra); + result = fill_ratemasks(extra, &brate, &orate, + acx111_supported, acx111_gen_mask, 0); + if (result) goto end; + SET_BIT(orate, brate); + log(L_IOCTL, "brate %08X orate %08X\n", brate, orate); + + result = verify_rate(brate, adev->chip_type); + if (result) goto end; + result = verify_rate(orate, adev->chip_type); + if (result) goto end; + + acx_sem_lock(adev); + acx_lock(adev, flags); + + adev->rate_basic = brate; + adev->rate_oper = orate; + /* TODO: ideally, we shall monitor highest basic rate + ** which was successfully sent to every peer + ** (say, last we checked, everybody could hear 5.5 Mbits) + ** and use that for bcasts when we want to reach all peers. + ** For beacons, we probably shall use lowest basic rate + ** because we want to reach all *potential* new peers too */ + adev->rate_bcast = 1 << lowest_bit(brate); + if (IS_ACX100(adev)) + adev->rate_bcast100 = acx_rate111to100(adev->rate_bcast); + adev->rate_auto = !has_only_one_bit(orate); + acx_l_update_client_rates(adev, orate); + /* TODO: get rid of ratevector, build it only when needed */ + acx_l_update_ratevector(adev); + + /* Do/don't do tx rate fallback; beacon contents and rate */ + SET_BIT(adev->set_mask, SET_RATE_FALLBACK|SET_TEMPLATES); + result = -EINPROGRESS; + + acx_unlock(adev, flags); + acx_sem_unlock(adev); +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_ioctl_get_phy_chan_busy_percentage +*/ +static int +acx_ioctl_get_phy_chan_busy_percentage( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + struct { + u16 type; + u16 len; + u32 busytime; + u32 totaltime; + } ACX_PACKED usage; + int result; + + acx_sem_lock(adev); + + if (OK != acx_s_interrogate(adev, &usage, ACX1xx_IE_MEDIUM_USAGE)) { + result = NOT_OK; + goto end_unlock; + } + + usage.busytime = le32_to_cpu(usage.busytime); + usage.totaltime = le32_to_cpu(usage.totaltime); + + /* yes, this is supposed to be "Medium" (singular of media), + not "average"! OK, reword the message to make it obvious... */ + printk("%s: busy percentage of medium (since last invocation): %d%% " + "(%u of %u microseconds)\n", + ndev->name, + usage.busytime / ((usage.totaltime / 100) + 1), + usage.busytime, usage.totaltime); + + result = OK; + +end_unlock: + acx_sem_unlock(adev); + + return result; +} + + +/*********************************************************************** +** acx_ioctl_set_ed_threshold +*/ +static inline int +acx_ioctl_set_ed_threshold( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + + acx_sem_lock(adev); + + printk("old ED threshold value: %d\n", adev->ed_threshold); + adev->ed_threshold = (unsigned char)*extra; + printk("new ED threshold value: %d\n", (unsigned char)*extra); + SET_BIT(adev->set_mask, GETSET_ED_THRESH); + + acx_sem_unlock(adev); + + return -EINPROGRESS; +} + + +/*********************************************************************** +** acx_ioctl_set_cca +*/ +static inline int +acx_ioctl_set_cca( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int result; + + acx_sem_lock(adev); + + printk("old CCA value: 0x%02X\n", adev->cca); + adev->cca = (unsigned char)*extra; + printk("new CCA value: 0x%02X\n", (unsigned char)*extra); + SET_BIT(adev->set_mask, GETSET_CCA); + result = -EINPROGRESS; + + acx_sem_unlock(adev); + + return result; +} + + +/*********************************************************************** +*/ +static const char * const +scan_modes[] = { "active", "passive", "background" }; + +static void +acx_print_scan_params(acx_device_t *adev, const char* head) +{ + printk("%s: %smode %d (%s), min chan time %dTU, " + "max chan time %dTU, max scan rate byte: %d\n", + adev->ndev->name, head, + adev->scan_mode, scan_modes[adev->scan_mode], + adev->scan_probe_delay, adev->scan_duration, adev->scan_rate); +} + +static int +acx_ioctl_set_scan_params( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int result; + const int *params = (int *)extra; + + acx_sem_lock(adev); + + acx_print_scan_params(adev, "old scan parameters: "); + if ((params[0] != -1) && (params[0] >= 0) && (params[0] <= 2)) + adev->scan_mode = params[0]; + if (params[1] != -1) + adev->scan_probe_delay = params[1]; + if (params[2] != -1) + adev->scan_duration = params[2]; + if ((params[3] != -1) && (params[3] <= 255)) + adev->scan_rate = params[3]; + acx_print_scan_params(adev, "new scan parameters: "); + SET_BIT(adev->set_mask, GETSET_RESCAN); + result = -EINPROGRESS; + + acx_sem_unlock(adev); + + return result; +} + +static int +acx_ioctl_get_scan_params( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int result; + int *params = (int *)extra; + + acx_sem_lock(adev); + + acx_print_scan_params(adev, "current scan parameters: "); + params[0] = adev->scan_mode; + params[1] = adev->scan_probe_delay; + params[2] = adev->scan_duration; + params[3] = adev->scan_rate; + result = OK; + + acx_sem_unlock(adev); + + return result; +} + + +/*********************************************************************** +*/ +static int +acx100_ioctl_set_led_power( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + static const char * const led_modes[] = { "off", "on", "LinkQuality" }; + + acx_device_t *adev = ndev2adev(ndev); + int result; + + acx_sem_lock(adev); + + printk("%s: power LED status: old %d (%s), ", + ndev->name, + adev->led_power, + led_modes[adev->led_power]); + adev->led_power = extra[0]; + if (adev->led_power > 2) adev->led_power = 2; + printk("new %d (%s)\n", + adev->led_power, + led_modes[adev->led_power]); + + if (adev->led_power == 2) { + printk("%s: max link quality setting: old %d, ", + ndev->name, adev->brange_max_quality); + if (extra[1]) + adev->brange_max_quality = extra[1]; + printk("new %d\n", adev->brange_max_quality); + } + + SET_BIT(adev->set_mask, GETSET_LED_POWER); + + result = -EINPROGRESS; + + acx_sem_unlock(adev); + + return result; +} + + +/*********************************************************************** +*/ +static inline int +acx100_ioctl_get_led_power( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + + acx_sem_lock(adev); + + extra[0] = adev->led_power; + if (adev->led_power == 2) + extra[1] = adev->brange_max_quality; + else + extra[1] = -1; + + acx_sem_unlock(adev); + + return OK; +} + + +/*********************************************************************** +*/ +static int +acx111_ioctl_info( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->param; + if (!IS_PCI(ndev2adev(ndev))) + return OK; + return acx111pci_ioctl_info(ndev, info, vwrq, extra); +} + + +/*********************************************************************** +*/ +static int +acx100_ioctl_set_phy_amp_bias( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->param; + if (!IS_PCI(ndev2adev(ndev))) { + printk("acx: set_phy_amp_bias() is not supported on USB\n"); + return OK; + } + return acx100pci_ioctl_set_phy_amp_bias(ndev, info, vwrq, extra); +} + + +/*********************************************************************** +*/ +static const iw_handler acx_ioctl_handler[] = +{ + acx_ioctl_commit, /* SIOCSIWCOMMIT */ + acx_ioctl_get_name, /* SIOCGIWNAME */ + NULL, /* SIOCSIWNWID */ + NULL, /* SIOCGIWNWID */ + acx_ioctl_set_freq, /* SIOCSIWFREQ */ + acx_ioctl_get_freq, /* SIOCGIWFREQ */ + acx_ioctl_set_mode, /* SIOCSIWMODE */ + acx_ioctl_get_mode, /* SIOCGIWMODE */ + acx_ioctl_set_sens, /* SIOCSIWSENS */ + acx_ioctl_get_sens, /* SIOCGIWSENS */ + NULL, /* SIOCSIWRANGE */ + acx_ioctl_get_range, /* SIOCGIWRANGE */ + NULL, /* SIOCSIWPRIV */ + NULL, /* SIOCGIWPRIV */ + NULL, /* SIOCSIWSTATS */ + NULL, /* SIOCGIWSTATS */ +#if IW_HANDLER_VERSION > 4 + iw_handler_set_spy, /* SIOCSIWSPY */ + iw_handler_get_spy, /* SIOCGIWSPY */ + iw_handler_set_thrspy, /* SIOCSIWTHRSPY */ + iw_handler_get_thrspy, /* SIOCGIWTHRSPY */ +#else /* IW_HANDLER_VERSION > 4 */ +#ifdef WIRELESS_SPY + NULL /* acx_ioctl_set_spy FIXME */, /* SIOCSIWSPY */ + NULL /* acx_ioctl_get_spy */, /* SIOCGIWSPY */ +#else /* WSPY */ + NULL, /* SIOCSIWSPY */ + NULL, /* SIOCGIWSPY */ +#endif /* WSPY */ + NULL, /* [nothing] */ + NULL, /* [nothing] */ +#endif /* IW_HANDLER_VERSION > 4 */ + acx_ioctl_set_ap, /* SIOCSIWAP */ + acx_ioctl_get_ap, /* SIOCGIWAP */ + NULL, /* [nothing] */ + acx_ioctl_get_aplist, /* SIOCGIWAPLIST */ + acx_ioctl_set_scan, /* SIOCSIWSCAN */ + acx_ioctl_get_scan, /* SIOCGIWSCAN */ + acx_ioctl_set_essid, /* SIOCSIWESSID */ + acx_ioctl_get_essid, /* SIOCGIWESSID */ + acx_ioctl_set_nick, /* SIOCSIWNICKN */ + acx_ioctl_get_nick, /* SIOCGIWNICKN */ + NULL, /* [nothing] */ + NULL, /* [nothing] */ + acx_ioctl_set_rate, /* SIOCSIWRATE */ + acx_ioctl_get_rate, /* SIOCGIWRATE */ + acx_ioctl_set_rts, /* SIOCSIWRTS */ + acx_ioctl_get_rts, /* SIOCGIWRTS */ +#if ACX_FRAGMENTATION + acx_ioctl_set_frag, /* SIOCSIWFRAG */ + acx_ioctl_get_frag, /* SIOCGIWFRAG */ +#else + NULL, /* SIOCSIWFRAG */ + NULL, /* SIOCGIWFRAG */ +#endif + acx_ioctl_set_txpow, /* SIOCSIWTXPOW */ + acx_ioctl_get_txpow, /* SIOCGIWTXPOW */ + acx_ioctl_set_retry, /* SIOCSIWRETRY */ + acx_ioctl_get_retry, /* SIOCGIWRETRY */ + acx_ioctl_set_encode, /* SIOCSIWENCODE */ + acx_ioctl_get_encode, /* SIOCGIWENCODE */ + acx_ioctl_set_power, /* SIOCSIWPOWER */ + acx_ioctl_get_power, /* SIOCGIWPOWER */ +}; + + +/*********************************************************************** +*/ + +/* if you plan to reorder something, make sure to reorder all other places + * accordingly! */ +/* SET/GET convention: SETs must have even position, GETs odd */ +#define ACX100_IOCTL SIOCIWFIRSTPRIV +enum { + ACX100_IOCTL_DEBUG = ACX100_IOCTL, + ACX100_IOCTL_GET__________UNUSED1, + ACX100_IOCTL_SET_PLED, + ACX100_IOCTL_GET_PLED, + ACX100_IOCTL_SET_RATES, + ACX100_IOCTL_LIST_DOM, + ACX100_IOCTL_SET_DOM, + ACX100_IOCTL_GET_DOM, + ACX100_IOCTL_SET_SCAN_PARAMS, + ACX100_IOCTL_GET_SCAN_PARAMS, + ACX100_IOCTL_SET_PREAMB, + ACX100_IOCTL_GET_PREAMB, + ACX100_IOCTL_SET_ANT, + ACX100_IOCTL_GET_ANT, + ACX100_IOCTL_RX_ANT, + ACX100_IOCTL_TX_ANT, + ACX100_IOCTL_SET_PHY_AMP_BIAS, + ACX100_IOCTL_GET_PHY_CHAN_BUSY, + ACX100_IOCTL_SET_ED, + ACX100_IOCTL_GET__________UNUSED3, + ACX100_IOCTL_SET_CCA, + ACX100_IOCTL_GET__________UNUSED4, + ACX100_IOCTL_MONITOR, + ACX100_IOCTL_TEST, + ACX100_IOCTL_DBG_SET_MASKS, + ACX111_IOCTL_INFO, + ACX100_IOCTL_DBG_SET_IO, + ACX100_IOCTL_DBG_GET_IO +}; + + +static const iw_handler acx_ioctl_private_handler[] = +{ +#if ACX_DEBUG +[ACX100_IOCTL_DEBUG - ACX100_IOCTL] = acx_ioctl_set_debug, +#endif +[ACX100_IOCTL_SET_PLED - ACX100_IOCTL] = acx100_ioctl_set_led_power, +[ACX100_IOCTL_GET_PLED - ACX100_IOCTL] = acx100_ioctl_get_led_power, +[ACX100_IOCTL_SET_RATES - ACX100_IOCTL] = acx_ioctl_set_rates, +[ACX100_IOCTL_LIST_DOM - ACX100_IOCTL] = acx_ioctl_list_reg_domain, +[ACX100_IOCTL_SET_DOM - ACX100_IOCTL] = acx_ioctl_set_reg_domain, +[ACX100_IOCTL_GET_DOM - ACX100_IOCTL] = acx_ioctl_get_reg_domain, +[ACX100_IOCTL_SET_SCAN_PARAMS - ACX100_IOCTL] = acx_ioctl_set_scan_params, +[ACX100_IOCTL_GET_SCAN_PARAMS - ACX100_IOCTL] = acx_ioctl_get_scan_params, +[ACX100_IOCTL_SET_PREAMB - ACX100_IOCTL] = acx_ioctl_set_short_preamble, +[ACX100_IOCTL_GET_PREAMB - ACX100_IOCTL] = acx_ioctl_get_short_preamble, +[ACX100_IOCTL_SET_ANT - ACX100_IOCTL] = acx_ioctl_set_antenna, +[ACX100_IOCTL_GET_ANT - ACX100_IOCTL] = acx_ioctl_get_antenna, +[ACX100_IOCTL_RX_ANT - ACX100_IOCTL] = acx_ioctl_set_rx_antenna, +[ACX100_IOCTL_TX_ANT - ACX100_IOCTL] = acx_ioctl_set_tx_antenna, +[ACX100_IOCTL_SET_PHY_AMP_BIAS - ACX100_IOCTL] = acx100_ioctl_set_phy_amp_bias, +[ACX100_IOCTL_GET_PHY_CHAN_BUSY - ACX100_IOCTL] = acx_ioctl_get_phy_chan_busy_percentage, +[ACX100_IOCTL_SET_ED - ACX100_IOCTL] = acx_ioctl_set_ed_threshold, +[ACX100_IOCTL_SET_CCA - ACX100_IOCTL] = acx_ioctl_set_cca, +[ACX100_IOCTL_MONITOR - ACX100_IOCTL] = acx_ioctl_wlansniff, +[ACX100_IOCTL_TEST - ACX100_IOCTL] = acx_ioctl_unknown11, +[ACX100_IOCTL_DBG_SET_MASKS - ACX100_IOCTL] = acx_ioctl_dbg_set_masks, +[ACX111_IOCTL_INFO - ACX100_IOCTL] = acx111_ioctl_info, +}; + + +static const struct iw_priv_args acx_ioctl_private_args[] = { +#if ACX_DEBUG +{ cmd : ACX100_IOCTL_DEBUG, + set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetDebug" }, +#endif +{ cmd : ACX100_IOCTL_SET_PLED, + set_args : IW_PRIV_TYPE_BYTE | 2, + get_args : 0, + name : "SetLEDPower" }, +{ cmd : ACX100_IOCTL_GET_PLED, + set_args : 0, + get_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 2, + name : "GetLEDPower" }, +{ cmd : ACX100_IOCTL_SET_RATES, + set_args : IW_PRIV_TYPE_CHAR | 256, + get_args : 0, + name : "SetRates" }, +{ cmd : ACX100_IOCTL_LIST_DOM, + set_args : 0, + get_args : 0, + name : "ListRegDomain" }, +{ cmd : ACX100_IOCTL_SET_DOM, + set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetRegDomain" }, +{ cmd : ACX100_IOCTL_GET_DOM, + set_args : 0, + get_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + name : "GetRegDomain" }, +{ cmd : ACX100_IOCTL_SET_SCAN_PARAMS, + set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 4, + get_args : 0, + name : "SetScanParams" }, +{ cmd : ACX100_IOCTL_GET_SCAN_PARAMS, + set_args : 0, + get_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 4, + name : "GetScanParams" }, +{ cmd : ACX100_IOCTL_SET_PREAMB, + set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetSPreamble" }, +{ cmd : ACX100_IOCTL_GET_PREAMB, + set_args : 0, + get_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + name : "GetSPreamble" }, +{ cmd : ACX100_IOCTL_SET_ANT, + set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetAntenna" }, +{ cmd : ACX100_IOCTL_GET_ANT, + set_args : 0, + get_args : 0, + name : "GetAntenna" }, +{ cmd : ACX100_IOCTL_RX_ANT, + set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetRxAnt" }, +{ cmd : ACX100_IOCTL_TX_ANT, + set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetTxAnt" }, +{ cmd : ACX100_IOCTL_SET_PHY_AMP_BIAS, + set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetPhyAmpBias"}, +{ cmd : ACX100_IOCTL_GET_PHY_CHAN_BUSY, + set_args : 0, + get_args : 0, + name : "GetPhyChanBusy" }, +{ cmd : ACX100_IOCTL_SET_ED, + set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetED" }, +{ cmd : ACX100_IOCTL_SET_CCA, + set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetCCA" }, +{ cmd : ACX100_IOCTL_MONITOR, + set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, + get_args : 0, + name : "monitor" }, +{ cmd : ACX100_IOCTL_TEST, + set_args : 0, + get_args : 0, + name : "Test" }, +{ cmd : ACX100_IOCTL_DBG_SET_MASKS, + set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, + get_args : 0, + name : "DbgSetMasks" }, +{ cmd : ACX111_IOCTL_INFO, + set_args : 0, + get_args : 0, + name : "GetAcx111Info" }, +{ cmd : ACX100_IOCTL_DBG_SET_IO, + set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 4, + get_args : 0, + name : "DbgSetIO" }, +{ cmd : ACX100_IOCTL_DBG_GET_IO, + set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, + get_args : 0, + name : "DbgGetIO" }, +}; + + +const struct iw_handler_def acx_ioctl_handler_def = +{ + .num_standard = VEC_SIZE(acx_ioctl_handler), + .num_private = VEC_SIZE(acx_ioctl_private_handler), + .num_private_args = VEC_SIZE(acx_ioctl_private_args), + .standard = (iw_handler *) acx_ioctl_handler, + .private = (iw_handler *) acx_ioctl_private_handler, + .private_args = (struct iw_priv_args *) acx_ioctl_private_args, +#if IW_HANDLER_VERSION > 5 + .get_wireless_stats = acx_e_get_wireless_stats +#endif /* IW > 5 */ +}; --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/acx_func.h +++ linux-2.6.28/ubuntu/misc/wireless/acx/acx_func.h @@ -0,0 +1,651 @@ +/*********************************************************************** +** Copyright (C) 2003 ACX100 Open Source Project +** +** The contents of this file are subject to the Mozilla Public +** License Version 1.1 (the "License"); you may not use this file +** except in compliance with the License. You may obtain a copy of +** the License at http://www.mozilla.org/MPL/ +** +** Software distributed under the License is distributed on an "AS +** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +** implied. See the License for the specific language governing +** rights and limitations under the License. +** +** Alternatively, the contents of this file may be used under the +** terms of the GNU Public License version 2 (the "GPL"), in which +** case the provisions of the GPL are applicable instead of the +** above. If you wish to allow the use of your version of this file +** only under the terms of the GPL and not to allow others to use +** your version of this file under the MPL, indicate your decision +** by deleting the provisions above and replace them with the notice +** and other provisions required by the GPL. If you do not delete +** the provisions above, a recipient may use your version of this +** file under either the MPL or the GPL. +** --------------------------------------------------------------------- +** Inquiries regarding the ACX100 Open Source Project can be +** made directly to: +** +** acx100-users@lists.sf.net +** http://acx100.sf.net +** --------------------------------------------------------------------- +*/ + + +/*********************************************************************** +** LOGGING +** +** - Avoid SHOUTING needlessly. Avoid excessive verbosity. +** Gradually remove messages which are old debugging aids. +** +** - Use printk() for messages which are to be always logged. +** Supply either 'acx:' or ':' prefix so that user +** can figure out who's speaking among other kernel chatter. +** acx: is for general issues (e.g. "acx: no firmware image!") +** while : is related to a particular device +** (think about multi-card setup). Double check that message +** is not confusing to the average user. +** +** - use printk KERN_xxx level only if message is not a WARNING +** but is INFO, ERR etc. +** +** - Use printk_ratelimited() for messages which may flood +** (e.g. "rx DUP pkt!"). +** +** - Use log() for messages which may be omitted (and they +** _will_ be omitted in non-debug builds). Note that +** message levels may be disabled at compile-time selectively, +** thus select them wisely. Example: L_DEBUG is the lowest +** (most likely to be compiled out) -> use for less important stuff. +** +** - Do not print important stuff with log(), or else people +** will never build non-debug driver. +** +** Style: +** hex: capital letters, zero filled (e.g. 0x02AC) +** str: dont start from capitals, no trailing periods ("tx: queue is stopped") +*/ +#if ACX_DEBUG > 1 + +void log_fn_enter(const char *funcname); +void log_fn_exit(const char *funcname); +void log_fn_exit_v(const char *funcname, int v); + +#define FN_ENTER \ + do { \ + if (unlikely(acx_debug & L_FUNC)) { \ + log_fn_enter(__func__); \ + } \ + } while (0) + +#define FN_EXIT1(v) \ + do { \ + if (unlikely(acx_debug & L_FUNC)) { \ + log_fn_exit_v(__func__, v); \ + } \ + } while (0) +#define FN_EXIT0 \ + do { \ + if (unlikely(acx_debug & L_FUNC)) { \ + log_fn_exit(__func__); \ + } \ + } while (0) + +#else + +#define FN_ENTER +#define FN_EXIT1(v) +#define FN_EXIT0 + +#endif /* ACX_DEBUG > 1 */ + + +#if ACX_DEBUG + +#define log(chan, args...) \ + do { \ + if (acx_debug & (chan)) \ + printk(args); \ + } while (0) +#define printk_ratelimited(args...) printk(args) + +#else /* Non-debug build: */ + +#define log(chan, args...) +/* Standard way of log flood prevention */ +#define printk_ratelimited(args...) \ +do { \ + if (printk_ratelimit()) \ + printk(args); \ +} while (0) + +#endif /* ACX_DEBUG */ + +void acx_print_mac(const char *head, const u8 *mac, const char *tail); + +/* Optimized out to nothing in non-debug build */ +static inline void +acxlog_mac(int level, const char *head, const u8 *mac, const char *tail) +{ + if (acx_debug & level) { + acx_print_mac(head, mac, tail); + } +} + + +/*********************************************************************** +** MAC address helpers +*/ +static inline void +MAC_COPY(u8 *mac, const u8 *src) +{ + *(u32*)mac = *(u32*)src; + ((u16*)mac)[2] = ((u16*)src)[2]; + /* kernel's memcpy will do the same: memcpy(dst, src, ETH_ALEN); */ +} + +static inline void +MAC_FILL(u8 *mac, u8 val) +{ + memset(mac, val, ETH_ALEN); +} + +static inline void +MAC_BCAST(u8 *mac) +{ + ((u16*)mac)[2] = *(u32*)mac = -1; +} + +static inline void +MAC_ZERO(u8 *mac) +{ + ((u16*)mac)[2] = *(u32*)mac = 0; +} + +static inline int +mac_is_equal(const u8 *a, const u8 *b) +{ + /* can't beat this */ + return memcmp(a, b, ETH_ALEN) == 0; +} + +static inline int +mac_is_bcast(const u8 *mac) +{ + /* AND together 4 first bytes with sign-extended 2 last bytes + ** Only bcast address gives 0xffffffff. +1 gives 0 */ + return ( *(s32*)mac & ((s16*)mac)[2] ) + 1 == 0; +} + +static inline int +mac_is_zero(const u8 *mac) +{ + return ( *(u32*)mac | ((u16*)mac)[2] ) == 0; +} + +static inline int +mac_is_directed(const u8 *mac) +{ + return (mac[0] & 1)==0; +} + +static inline int +mac_is_mcast(const u8 *mac) +{ + return (mac[0] & 1) && !mac_is_bcast(mac); +} + +#define MACSTR "%02X:%02X:%02X:%02X:%02X:%02X" +#define MAC(bytevector) \ + ((unsigned char *)bytevector)[0], \ + ((unsigned char *)bytevector)[1], \ + ((unsigned char *)bytevector)[2], \ + ((unsigned char *)bytevector)[3], \ + ((unsigned char *)bytevector)[4], \ + ((unsigned char *)bytevector)[5] + + +/*********************************************************************** +** Random helpers +*/ +#define TO_STRING(x) #x +#define STRING(x) TO_STRING(x) + +#define CLEAR_BIT(val, mask) ((val) &= ~(mask)) +#define SET_BIT(val, mask) ((val) |= (mask)) + +/* undefined if v==0 */ +static inline unsigned int +lowest_bit(u16 v) +{ + unsigned int n = 0; + while (!(v & 0xf)) { v>>=4; n+=4; } + while (!(v & 1)) { v>>=1; n++; } + return n; +} + +/* undefined if v==0 */ +static inline unsigned int +highest_bit(u16 v) +{ + unsigned int n = 0; + while (v>0xf) { v>>=4; n+=4; } + while (v>1) { v>>=1; n++; } + return n; +} + +/* undefined if v==0 */ +static inline int +has_only_one_bit(u16 v) +{ + return ((v-1) ^ v) >= v; +} + + +static inline int +is_hidden_essid(char *essid) +{ + return (('\0' == essid[0]) || + ((' ' == essid[0]) && ('\0' == essid[1]))); +} + +/*********************************************************************** +** LOCKING +** We have adev->sem and adev->lock. +** +** We employ following naming convention in order to get locking right: +** +** acx_e_xxxx - external entry points called from process context. +** It is okay to sleep. adev->sem is to be taken on entry. +** acx_i_xxxx - external entry points possibly called from atomic context. +** Sleeping is not allowed (and thus down(sem) is not legal!) +** acx_s_xxxx - potentially sleeping functions. Do not ever call under lock! +** acx_l_xxxx - functions which expect lock to be already taken. +** rest - non-sleeping functions which do not require locking +** but may be run under lock +** +** A small number of local helpers do not have acx_[eisl]_ prefix. +** They are always close to caller and are to be reviewed locally. +** +** Theory of operation: +** +** All process-context entry points (_e_ functions) take sem +** immediately. IRQ handler and other 'atomic-context' entry points +** (_i_ functions) take lock immediately on entry, but dont take sem +** because that might sleep. +** +** Thus *all* code is either protected by sem or lock, or both. +** +** Code which must not run concurrently with IRQ takes lock. +** Such code is marked with _l_. +** +** This results in the following rules of thumb useful in code review: +** +** + If a function calls _s_ fn, it must be an _s_ itself. +** + You can call _l_ fn only (a) from another _l_ fn +** or (b) from _s_, _e_ or _i_ fn by taking lock, calling _l_, +** and dropping lock. +** + All IRQ code runs under lock. +** + Any _s_ fn is running under sem. +** + Code under sem can race only with IRQ code. +** + Code under sem+lock cannot race with anything. +*/ + +/* These functions *must* be inline or they will break horribly on SPARC, due + * to its weird semantics for save/restore flags */ + +#if defined(PARANOID_LOCKING) /* Lock debugging */ + +void acx_lock_debug(acx_device_t *adev, const char* where); +void acx_unlock_debug(acx_device_t *adev, const char* where); +void acx_down_debug(acx_device_t *adev, const char* where); +void acx_up_debug(acx_device_t *adev, const char* where); +void acx_lock_unhold(void); +void acx_sem_unhold(void); + +static inline void +acx_lock_helper(acx_device_t *adev, unsigned long *fp, const char* where) +{ + acx_lock_debug(adev, where); + spin_lock_irqsave(&adev->lock, *fp); +} +static inline void +acx_unlock_helper(acx_device_t *adev, unsigned long *fp, const char* where) +{ + acx_unlock_debug(adev, where); + spin_unlock_irqrestore(&adev->lock, *fp); +} +static inline void +acx_down_helper(acx_device_t *adev, const char* where) +{ + acx_down_debug(adev, where); +} +static inline void +acx_up_helper(acx_device_t *adev, const char* where) +{ + acx_up_debug(adev, where); +} +#define acx_lock(adev, flags) acx_lock_helper(adev, &(flags), __FILE__ ":" STRING(__LINE__)) +#define acx_unlock(adev, flags) acx_unlock_helper(adev, &(flags), __FILE__ ":" STRING(__LINE__)) +#define acx_sem_lock(adev) acx_down_helper(adev, __FILE__ ":" STRING(__LINE__)) +#define acx_sem_unlock(adev) acx_up_helper(adev, __FILE__ ":" STRING(__LINE__)) + +#elif defined(DO_LOCKING) + +#define acx_lock(adev, flags) spin_lock_irqsave(&adev->lock, flags) +#define acx_unlock(adev, flags) spin_unlock_irqrestore(&adev->lock, flags) +#define acx_sem_lock(adev) down(&adev->sem) +#define acx_sem_unlock(adev) up(&adev->sem) +#define acx_lock_unhold() ((void)0) +#define acx_sem_unhold() ((void)0) + +#else /* no locking! :( */ + +#define acx_lock(adev, flags) ((void)0) +#define acx_unlock(adev, flags) ((void)0) +#define acx_sem_lock(adev) ((void)0) +#define acx_sem_unlock(adev) ((void)0) +#define acx_lock_unhold() ((void)0) +#define acx_sem_unhold() ((void)0) + +#endif + + +/*********************************************************************** +*/ + +/* Can race with rx path (which is not protected by sem): +** rx -> process_[re]assocresp() -> set_status(ASSOCIATED) -> wake_queue() +** Can race with tx_complete IRQ: +** IRQ -> acxpci_l_clean_txdesc -> acx_wake_queue +** Review carefully all callsites */ +static inline void +acx_stop_queue(struct net_device *ndev, const char *msg) +{ + if (netif_queue_stopped(ndev)) + return; + + netif_stop_queue(ndev); + if (msg) + log(L_BUFT, "tx: stop queue %s\n", msg); +} + +static inline int +acx_queue_stopped(struct net_device *ndev) +{ + return netif_queue_stopped(ndev); +} + +/* +static inline void +acx_start_queue(struct net_device *ndev, const char *msg) +{ + netif_start_queue(ndev); + if (msg) + log(L_BUFT, "tx: start queue %s\n", msg); +} +*/ + +static inline void +acx_wake_queue(struct net_device *ndev, const char *msg) +{ + netif_wake_queue(ndev); + if (msg) + log(L_BUFT, "tx: wake queue %s\n", msg); +} + +static inline void +acx_carrier_off(struct net_device *ndev, const char *msg) +{ + netif_carrier_off(ndev); + if (msg) + log(L_BUFT, "tx: carrier off %s\n", msg); +} + +static inline void +acx_carrier_on(struct net_device *ndev, const char *msg) +{ + netif_carrier_on(ndev); + if (msg) + log(L_BUFT, "tx: carrier on %s\n", msg); +} + +/* This function does not need locking UNLESS you call it +** as acx_set_status(ACX_STATUS_4_ASSOCIATED), bacause this can +** wake queue. This can race with stop_queue elsewhere. */ +void acx_set_status(acx_device_t *adev, u16 status); + + +/*********************************************************************** +** Communication with firmware +*/ +#define CMD_TIMEOUT_MS(n) (n) +#define ACX_CMD_TIMEOUT_DEFAULT CMD_TIMEOUT_MS(50) + +#if ACX_DEBUG + +/* We want to log cmd names */ +int acxpci_s_issue_cmd_timeo_debug(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout, const char* cmdstr); +int acxusb_s_issue_cmd_timeo_debug(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout, const char* cmdstr); +static inline int +acx_s_issue_cmd_timeo_debug(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout, const char* cmdstr) +{ + if (IS_PCI(adev)) + return acxpci_s_issue_cmd_timeo_debug(adev, cmd, param, len, timeout, cmdstr); + return acxusb_s_issue_cmd_timeo_debug(adev, cmd, param, len, timeout, cmdstr); +} +#define acx_s_issue_cmd(adev,cmd,param,len) \ + acx_s_issue_cmd_timeo_debug(adev,cmd,param,len,ACX_CMD_TIMEOUT_DEFAULT,#cmd) +#define acx_s_issue_cmd_timeo(adev,cmd,param,len,timeo) \ + acx_s_issue_cmd_timeo_debug(adev,cmd,param,len,timeo,#cmd) +int acx_s_configure_debug(acx_device_t *adev, void *pdr, int type, const char* str); +#define acx_s_configure(adev,pdr,type) \ + acx_s_configure_debug(adev,pdr,type,#type) +int acx_s_interrogate_debug(acx_device_t *adev, void *pdr, int type, const char* str); +#define acx_s_interrogate(adev,pdr,type) \ + acx_s_interrogate_debug(adev,pdr,type,#type) + +#else + +int acxpci_s_issue_cmd_timeo(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout); +int acxusb_s_issue_cmd_timeo(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout); +static inline int +acx_s_issue_cmd_timeo(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout) +{ + if (IS_PCI(adev)) + return acxpci_s_issue_cmd_timeo(adev, cmd, param, len, timeout); + return acxusb_s_issue_cmd_timeo(adev, cmd, param, len, timeout); +} +static inline int +acx_s_issue_cmd(acx_device_t *adev, unsigned cmd, void *param, unsigned len) +{ + if (IS_PCI(adev)) + return acxpci_s_issue_cmd_timeo(adev, cmd, param, len, ACX_CMD_TIMEOUT_DEFAULT); + return acxusb_s_issue_cmd_timeo(adev, cmd, param, len, ACX_CMD_TIMEOUT_DEFAULT); +} +int acx_s_configure(acx_device_t *adev, void *pdr, int type); +int acx_s_interrogate(acx_device_t *adev, void *pdr, int type); + +#endif + +void acx_s_cmd_start_scan(acx_device_t *adev); + + +/*********************************************************************** +** Ioctls +*/ +int +acx111pci_ioctl_info( + struct net_device *ndev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra); +int +acx100pci_ioctl_set_phy_amp_bias( + struct net_device *ndev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra); + + +/*********************************************************************** +** /proc +*/ +#ifdef CONFIG_PROC_FS +int acx_proc_register_entries(const struct net_device *ndev); +int acx_proc_unregister_entries(const struct net_device *ndev); +#else +static inline int +acx_proc_register_entries(const struct net_device *ndev) { return OK; } +static inline int +acx_proc_unregister_entries(const struct net_device *ndev) { return OK; } +#endif + + +/*********************************************************************** +*/ +firmware_image_t *acx_s_read_fw(struct device *dev, const char *file, u32 *size); +int acxpci_s_upload_radio(acx_device_t *adev); + + +/*********************************************************************** +** Unsorted yet :) +*/ +int acxpci_s_read_phy_reg(acx_device_t *adev, u32 reg, u8 *charbuf); +int acxusb_s_read_phy_reg(acx_device_t *adev, u32 reg, u8 *charbuf); +static inline int +acx_s_read_phy_reg(acx_device_t *adev, u32 reg, u8 *charbuf) +{ + if (IS_PCI(adev)) + return acxpci_s_read_phy_reg(adev, reg, charbuf); + return acxusb_s_read_phy_reg(adev, reg, charbuf); +} + +int acxpci_s_write_phy_reg(acx_device_t *adev, u32 reg, u8 value); +int acxusb_s_write_phy_reg(acx_device_t *adev, u32 reg, u8 value); +static inline int +acx_s_write_phy_reg(acx_device_t *adev, u32 reg, u8 value) +{ + if (IS_PCI(adev)) + return acxpci_s_write_phy_reg(adev, reg, value); + return acxusb_s_write_phy_reg(adev, reg, value); +} + +tx_t* acxpci_l_alloc_tx(acx_device_t *adev); +tx_t* acxusb_l_alloc_tx(acx_device_t *adev); +static inline tx_t* +acx_l_alloc_tx(acx_device_t *adev) +{ + if (IS_PCI(adev)) + return acxpci_l_alloc_tx(adev); + return acxusb_l_alloc_tx(adev); +} + +void acxusb_l_dealloc_tx(tx_t *tx_opaque); +static inline void +acx_l_dealloc_tx(acx_device_t *adev, tx_t *tx_opaque) +{ + if (IS_USB(adev)) + acxusb_l_dealloc_tx(tx_opaque); +} + +void* acxpci_l_get_txbuf(acx_device_t *adev, tx_t *tx_opaque); +void* acxusb_l_get_txbuf(acx_device_t *adev, tx_t *tx_opaque); +static inline void* +acx_l_get_txbuf(acx_device_t *adev, tx_t *tx_opaque) +{ + if (IS_PCI(adev)) + return acxpci_l_get_txbuf(adev, tx_opaque); + return acxusb_l_get_txbuf(adev, tx_opaque); +} + +void acxpci_l_tx_data(acx_device_t *adev, tx_t *tx_opaque, int len); +void acxusb_l_tx_data(acx_device_t *adev, tx_t *tx_opaque, int len); +static inline void +acx_l_tx_data(acx_device_t *adev, tx_t *tx_opaque, int len) +{ + if (IS_PCI(adev)) + acxpci_l_tx_data(adev, tx_opaque, len); + else + acxusb_l_tx_data(adev, tx_opaque, len); +} + +static inline wlan_hdr_t* +acx_get_wlan_hdr(acx_device_t *adev, const rxbuffer_t *rxbuf) +{ + return (wlan_hdr_t*)((u8*)&rxbuf->hdr_a3 + adev->phy_header_len); +} + +void acxpci_l_power_led(acx_device_t *adev, int enable); +int acxpci_read_eeprom_byte(acx_device_t *adev, u32 addr, u8 *charbuf); +unsigned int acxpci_l_clean_txdesc(acx_device_t *adev); +void acxpci_l_clean_txdesc_emergency(acx_device_t *adev); +int acxpci_s_create_hostdesc_queues(acx_device_t *adev); +void acxpci_create_desc_queues(acx_device_t *adev, u32 tx_queue_start, u32 rx_queue_start); +void acxpci_free_desc_queues(acx_device_t *adev); +char* acxpci_s_proc_diag_output(char *p, acx_device_t *adev); +int acxpci_proc_eeprom_output(char *p, acx_device_t *adev); +void acxpci_set_interrupt_mask(acx_device_t *adev); +int acx100pci_s_set_tx_level(acx_device_t *adev, u8 level_dbm); + +void acx_s_msleep(int ms); +int acx_s_init_mac(acx_device_t *adev); +void acx_set_reg_domain(acx_device_t *adev, unsigned char reg_dom_id); +void acx_set_timer(acx_device_t *adev, int timeout_us); +void acx_update_capabilities(acx_device_t *adev); +void acx_s_start(acx_device_t *adev); + +void acx_s_update_card_settings(acx_device_t *adev); +void acx_s_parse_configoption(acx_device_t *adev, const acx111_ie_configoption_t *pcfg); +void acx_l_update_ratevector(acx_device_t *adev); + +void acx_init_task_scheduler(acx_device_t *adev); +void acx_schedule_task(acx_device_t *adev, unsigned int set_flag); + +int acx_e_ioctl_old(struct net_device *ndev, struct ifreq *ifr, int cmd); + +client_t *acx_l_sta_list_get(acx_device_t *adev, const u8 *address); +void acx_l_sta_list_del(acx_device_t *adev, client_t *clt); + +int acx_l_transmit_disassoc(acx_device_t *adev, client_t *clt); +void acx_i_timer(unsigned long a); +int acx_s_complete_scan(acx_device_t *adev); + +struct sk_buff *acx_rxbuf_to_ether(acx_device_t *adev, rxbuffer_t *rxbuf); +int acx_ether_to_txbuf(acx_device_t *adev, void *txbuf, const struct sk_buff *skb); + +u8 acx_signal_determine_quality(u8 signal, u8 noise); + +void acx_l_process_rxbuf(acx_device_t *adev, rxbuffer_t *rxbuf); +void acx_l_handle_txrate_auto(acx_device_t *adev, struct client *txc, + u16 intended_rate, u8 rate100, u16 rate111, u8 error, + int pkts_to_ignore); + +void acx_dump_bytes(const void *, int); +void acx_log_bad_eid(wlan_hdr_t* hdr, int len, wlan_ie_t* ie_ptr); + +u8 acx_rate111to100(u16); + +void acx_s_set_defaults(acx_device_t *adev); + +#if !ACX_DEBUG +static inline const char* acx_get_packet_type_string(u16 fc) { return ""; } +#else +const char* acx_get_packet_type_string(u16 fc); +#endif +const char* acx_cmd_status_str(unsigned int state); + +int acx_i_start_xmit(struct sk_buff *skb, struct net_device *ndev); + +void great_inquisitor(acx_device_t *adev); + +void acx_s_get_firmware_version(acx_device_t *adev); +void acx_display_hardware_details(acx_device_t *adev); + +int acx_e_change_mtu(struct net_device *ndev, int mtu); +struct net_device_stats* acx_e_get_stats(struct net_device *ndev); +struct iw_statistics* acx_e_get_wireless_stats(struct net_device *ndev); + +int __init acxpci_e_init_module(void); +int __init acxusb_e_init_module(void); +void __exit acxpci_e_cleanup_module(void); +void __exit acxusb_e_cleanup_module(void); --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/acx_struct.h +++ linux-2.6.28/ubuntu/misc/wireless/acx/acx_struct.h @@ -0,0 +1,2049 @@ +/*********************************************************************** +** Copyright (C) 2003 ACX100 Open Source Project +** +** The contents of this file are subject to the Mozilla Public +** License Version 1.1 (the "License"); you may not use this file +** except in compliance with the License. You may obtain a copy of +** the License at http://www.mozilla.org/MPL/ +** +** Software distributed under the License is distributed on an "AS +** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +** implied. See the License for the specific language governing +** rights and limitations under the License. +** +** Alternatively, the contents of this file may be used under the +** terms of the GNU Public License version 2 (the "GPL"), in which +** case the provisions of the GPL are applicable instead of the +** above. If you wish to allow the use of your version of this file +** only under the terms of the GPL and not to allow others to use +** your version of this file under the MPL, indicate your decision +** by deleting the provisions above and replace them with the notice +** and other provisions required by the GPL. If you do not delete +** the provisions above, a recipient may use your version of this +** file under either the MPL or the GPL. +** --------------------------------------------------------------------- +** Inquiries regarding the ACX100 Open Source Project can be +** made directly to: +** +** acx100-users@lists.sf.net +** http://acx100.sf.net +** --------------------------------------------------------------------- +*/ + +/*********************************************************************** +** Forward declarations of types +*/ +typedef struct tx tx_t; +typedef struct acx_device acx_device_t; +typedef struct client client_t; +typedef struct rxdesc rxdesc_t; +typedef struct txdesc txdesc_t; +typedef struct rxhostdesc rxhostdesc_t; +typedef struct txhostdesc txhostdesc_t; + + +/*********************************************************************** +** Debug / log functionality +*/ +enum { + L_LOCK = (ACX_DEBUG>1)*0x0001, /* locking debug log */ + L_INIT = (ACX_DEBUG>0)*0x0002, /* special card initialization logging */ + L_IRQ = (ACX_DEBUG>0)*0x0004, /* interrupt stuff */ + L_ASSOC = (ACX_DEBUG>0)*0x0008, /* assocation (network join) and station log */ + L_FUNC = (ACX_DEBUG>1)*0x0020, /* logging of function enter / leave */ + L_XFER = (ACX_DEBUG>1)*0x0080, /* logging of transfers and mgmt */ + L_DATA = (ACX_DEBUG>1)*0x0100, /* logging of transfer data */ + L_DEBUG = (ACX_DEBUG>1)*0x0200, /* log of debug info */ + L_IOCTL = (ACX_DEBUG>0)*0x0400, /* log ioctl calls */ + L_CTL = (ACX_DEBUG>1)*0x0800, /* log of low-level ctl commands */ + L_BUFR = (ACX_DEBUG>1)*0x1000, /* debug rx buffer mgmt (ring buffer etc.) */ + L_XFER_BEACON = (ACX_DEBUG>1)*0x2000, /* also log beacon packets */ + L_BUFT = (ACX_DEBUG>1)*0x4000, /* debug tx buffer mgmt (ring buffer etc.) */ + L_USBRXTX = (ACX_DEBUG>0)*0x8000, /* debug USB rx/tx operations */ + L_BUF = L_BUFR + L_BUFT, + L_ANY = 0xffff +}; + +#if ACX_DEBUG +extern unsigned int acx_debug; +#else +enum { acx_debug = 0 }; +#endif + +extern char firmware_ver[]; + + +/*********************************************************************** +** Random helpers +*/ +#define ACX_PACKED __attribute__ ((packed)) + +#define VEC_SIZE(a) (sizeof(a)/sizeof(a[0])) + +/* Use worker_queues for 2.5/2.6 kernels and queue tasks for 2.4 kernels + (used for the 'bottom half' of the interrupt routine) */ + +#include +#define USE_WORKER_TASKS +#define WORK_STRUCT struct work_struct +#define SCHEDULE_WORK schedule_work +#define FLUSH_SCHEDULED_WORK flush_scheduled_work + + +/*********************************************************************** +** Constants +*/ +#define OK 0 +#define NOT_OK 1 + +/* The supported chip models */ +#define CHIPTYPE_ACX100 1 +#define CHIPTYPE_ACX111 2 + +#define IS_ACX100(adev) ((adev)->chip_type == CHIPTYPE_ACX100) +#define IS_ACX111(adev) ((adev)->chip_type == CHIPTYPE_ACX111) + +/* Supported interfaces */ +#define DEVTYPE_PCI 0 +#define DEVTYPE_USB 1 + +#if defined(CONFIG_NET_ACX_PCI) + #if !defined(CONFIG_NET_ACX_USB) + #define IS_PCI(adev) 1 + #else + #define IS_PCI(adev) ((adev)->dev_type == DEVTYPE_PCI) + #endif +#else + #define IS_PCI(adev) 0 +#endif + +#if defined(CONFIG_NET_ACX_USB) + #if !defined(CONFIG_NET_ACX_PCI) + #define IS_USB(adev) 1 + #else + #define IS_USB(adev) ((adev)->dev_type == DEVTYPE_USB) + #endif +#else + #define IS_USB(adev) 0 +#endif + +/* Driver defaults */ +#define DEFAULT_DTIM_INTERVAL 10 +/* used to be 2048, but FreeBSD driver changed it to 4096 to work properly +** in noisy wlans */ +#define DEFAULT_MSDU_LIFETIME 4096 +#define DEFAULT_RTS_THRESHOLD 2312 /* max. size: disable RTS mechanism */ +#define DEFAULT_BEACON_INTERVAL 100 + +#define ACX100_BAP_DATALEN_MAX 4096 +#define ACX100_RID_GUESSING_MAXLEN 2048 /* I'm not really sure */ +#define ACX100_RIDDATA_MAXLEN ACX100_RID_GUESSING_MAXLEN + +/* Support Constants */ +/* Radio type names, found in Win98 driver's TIACXLN.INF */ +#define RADIO_MAXIM_0D 0x0d +#define RADIO_RFMD_11 0x11 +#define RADIO_RALINK_15 0x15 +/* used in ACX111 cards (WG311v2, WL-121, ...): */ +#define RADIO_RADIA_16 0x16 +/* most likely *sometimes* used in ACX111 cards: */ +#define RADIO_UNKNOWN_17 0x17 +/* FwRad19.bin was found in a Safecom driver; must be an ACX111 radio: */ +#define RADIO_UNKNOWN_19 0x19 +#define RADIO_UNKNOWN_1B 0x1b /* radio in SafeCom SWLUT-54125 USB adapter; entirely unknown!! */ + +/* Controller Commands */ +/* can be found in table cmdTable in firmware "Rev. 1.5.0" (FW150) */ +#define ACX1xx_CMD_RESET 0x00 +#define ACX1xx_CMD_INTERROGATE 0x01 +#define ACX1xx_CMD_CONFIGURE 0x02 +#define ACX1xx_CMD_ENABLE_RX 0x03 +#define ACX1xx_CMD_ENABLE_TX 0x04 +#define ACX1xx_CMD_DISABLE_RX 0x05 +#define ACX1xx_CMD_DISABLE_TX 0x06 +#define ACX1xx_CMD_FLUSH_QUEUE 0x07 +#define ACX1xx_CMD_SCAN 0x08 +#define ACX1xx_CMD_STOP_SCAN 0x09 +#define ACX1xx_CMD_CONFIG_TIM 0x0a +#define ACX1xx_CMD_JOIN 0x0b +#define ACX1xx_CMD_WEP_MGMT 0x0c +#ifdef OLD_FIRMWARE_VERSIONS +#define ACX100_CMD_HALT 0x0e /* mapped to unknownCMD in FW150 */ +#else +#define ACX1xx_CMD_MEM_READ 0x0d +#define ACX1xx_CMD_MEM_WRITE 0x0e +#endif +#define ACX1xx_CMD_SLEEP 0x0f +#define ACX1xx_CMD_WAKE 0x10 +#define ACX1xx_CMD_UNKNOWN_11 0x11 /* mapped to unknownCMD in FW150 */ +#define ACX100_CMD_INIT_MEMORY 0x12 +#define ACX1FF_CMD_DISABLE_RADIO 0x12 /* new firmware? TNETW1450? */ +#define ACX1xx_CMD_CONFIG_BEACON 0x13 +#define ACX1xx_CMD_CONFIG_PROBE_RESPONSE 0x14 +#define ACX1xx_CMD_CONFIG_NULL_DATA 0x15 +#define ACX1xx_CMD_CONFIG_PROBE_REQUEST 0x16 +#define ACX1xx_CMD_FCC_TEST 0x17 +#define ACX1xx_CMD_RADIOINIT 0x18 +#define ACX111_CMD_RADIOCALIB 0x19 +#define ACX1FF_CMD_NOISE_HISTOGRAM 0x1c /* new firmware? TNETW1450? */ +#define ACX1FF_CMD_RX_RESET 0x1d /* new firmware? TNETW1450? */ +#define ACX1FF_CMD_LNA_CONTROL 0x20 /* new firmware? TNETW1450? */ +#define ACX1FF_CMD_CONTROL_DBG_TRACE 0x21 /* new firmware? TNETW1450? */ + +/* 'After Interrupt' Commands */ +#define ACX_AFTER_IRQ_CMD_STOP_SCAN 0x01 +#define ACX_AFTER_IRQ_CMD_ASSOCIATE 0x02 +#define ACX_AFTER_IRQ_CMD_RADIO_RECALIB 0x04 +#define ACX_AFTER_IRQ_UPDATE_CARD_CFG 0x08 +#define ACX_AFTER_IRQ_TX_CLEANUP 0x10 +#define ACX_AFTER_IRQ_COMPLETE_SCAN 0x20 +#define ACX_AFTER_IRQ_RESTART_SCAN 0x40 + +/*********************************************************************** +** Tx/Rx buffer sizes and watermarks +** +** This will alloc and use DMAable buffers of +** WLAN_A4FR_MAXLEN_WEP_FCS * (RX_CNT + TX_CNT) bytes +** RX/TX_CNT=32 -> ~150k DMA buffers +** RX/TX_CNT=16 -> ~75k DMA buffers +** +** 2005-10-10: reduced memory usage by lowering both to 16 +*/ +#define RX_CNT 16 +#define TX_CNT 16 + +/* we clean up txdescs when we have N free txdesc: */ +#define TX_CLEAN_BACKLOG (TX_CNT/4) +#define TX_START_CLEAN (TX_CNT - TX_CLEAN_BACKLOG) +#define TX_EMERG_CLEAN 2 +/* we stop queue if we have < N free txbufs: */ +#define TX_STOP_QUEUE 3 +/* we start queue if we have >= N free txbufs: */ +#define TX_START_QUEUE 5 + +/*********************************************************************** +** Interrogate/Configure cmd constants +** +** NB: length includes JUST the data part of the IE +** (does not include size of the (type,len) pair) +** +** TODO: seems that acx100, acx100usb, acx111 have some differences, +** fix code with regard to this! +*/ + +#define DEF_IE(name, val, len) enum { ACX##name=val, ACX##name##_LEN=len } + +/* Information Elements: Network Parameters, Static Configuration Entities */ +/* these are handled by real_cfgtable in firmware "Rev 1.5.0" (FW150) */ +DEF_IE(1xx_IE_UNKNOWN_00 ,0x0000, -1); /* mapped to cfgInvalid in FW150 */ +DEF_IE(100_IE_ACX_TIMER ,0x0001, 0x10); +DEF_IE(1xx_IE_POWER_MGMT ,0x0002, 0x06); /* TNETW1450: length 0x18!! */ +DEF_IE(1xx_IE_QUEUE_CONFIG ,0x0003, 0x1c); +DEF_IE(100_IE_BLOCK_SIZE ,0x0004, 0x02); +DEF_IE(1FF_IE_SLOT_TIME ,0x0004, 0x08); /* later firmware versions only? */ +DEF_IE(1xx_IE_MEMORY_CONFIG_OPTIONS ,0x0005, 0x14); +DEF_IE(1FF_IE_QUEUE_HEAD ,0x0005, 0x14 /* FIXME: length? */); +DEF_IE(1xx_IE_RATE_FALLBACK ,0x0006, 0x01); /* TNETW1450: length 2 */ +DEF_IE(100_IE_WEP_OPTIONS ,0x0007, 0x03); +DEF_IE(111_IE_RADIO_BAND ,0x0007, -1); +DEF_IE(1FF_IE_TIMING_CFG ,0x0007, -1); /* later firmware versions; TNETW1450 only? */ +DEF_IE(100_IE_SSID ,0x0008, 0x20); /* huh? */ +DEF_IE(1xx_IE_MEMORY_MAP ,0x0008, 0x28); /* huh? TNETW1450 has length 0x40!! */ +DEF_IE(1xx_IE_SCAN_STATUS ,0x0009, 0x04); /* mapped to cfgInvalid in FW150 */ +DEF_IE(1xx_IE_ASSOC_ID ,0x000a, 0x02); +DEF_IE(1xx_IE_UNKNOWN_0B ,0x000b, -1); /* mapped to cfgInvalid in FW150 */ +DEF_IE(1FF_IE_TX_POWER_LEVEL_TABLE ,0x000b, 0x18); /* later firmware versions; TNETW1450 only? */ +DEF_IE(100_IE_UNKNOWN_0C ,0x000c, -1); /* very small implementation in FW150! */ +/* ACX100 has an equivalent struct in the cmd mailbox directly after reset. + * 0x14c seems extremely large, will trash stack on failure (memset!) + * in case of small input struct --> OOPS! */ +DEF_IE(111_IE_CONFIG_OPTIONS ,0x000c, 0x14c); +DEF_IE(1xx_IE_FWREV ,0x000d, 0x18); +DEF_IE(1xx_IE_FCS_ERROR_COUNT ,0x000e, 0x04); +DEF_IE(1xx_IE_MEDIUM_USAGE ,0x000f, 0x08); +DEF_IE(1xx_IE_RXCONFIG ,0x0010, 0x04); +DEF_IE(100_IE_UNKNOWN_11 ,0x0011, -1); /* NONBINARY: large implementation in FW150! link quality readings or so? */ +DEF_IE(111_IE_QUEUE_THRESH ,0x0011, -1); +DEF_IE(100_IE_UNKNOWN_12 ,0x0012, -1); /* NONBINARY: VERY large implementation in FW150!! */ +DEF_IE(111_IE_BSS_POWER_SAVE ,0x0012, /* -1 */ 2); +DEF_IE(1xx_IE_FIRMWARE_STATISTICS ,0x0013, 0x9c); /* TNETW1450: length 0x134!! */ +DEF_IE(1FF_IE_RX_INTR_CONFIG ,0x0014, 0x14); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1xx_IE_FEATURE_CONFIG ,0x0015, 0x08); +DEF_IE(111_IE_KEY_CHOOSE ,0x0016, 0x04); /* for rekeying. really len=4?? */ +DEF_IE(1FF_IE_MISC_CONFIG_TABLE ,0x0017, 0x04); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1FF_IE_WONE_CONFIG ,0x0018, -1); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1FF_IE_TID_CONFIG ,0x001a, 0x2c); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1FF_IE_CALIB_ASSESSMENT ,0x001e, 0x04); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1FF_IE_BEACON_FILTER_OPTIONS ,0x001f, 0x02); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1FF_IE_LOW_RSSI_THRESH_OPT ,0x0020, 0x04); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1FF_IE_NOISE_HISTOGRAM_RESULTS ,0x0021, 0x30); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1FF_IE_PACKET_DETECT_THRESH ,0x0023, 0x04); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1FF_IE_TX_CONFIG_OPTIONS ,0x0024, 0x04); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1FF_IE_CCA_THRESHOLD ,0x0025, 0x02); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1FF_IE_EVENT_MASK ,0x0026, 0x08); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1FF_IE_DTIM_PERIOD ,0x0027, 0x02); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1FF_IE_ACI_CONFIG_SET ,0x0029, 0x06); /* later firmware versions; maybe TNETW1450 only? */ +DEF_IE(1FF_IE_EEPROM_VER ,0x0030, 0x04); /* later firmware versions; maybe TNETW1450 only? */ +DEF_IE(1xx_IE_DOT11_STATION_ID ,0x1001, 0x06); +DEF_IE(100_IE_DOT11_UNKNOWN_1002 ,0x1002, -1); /* mapped to cfgInvalid in FW150 */ +DEF_IE(111_IE_DOT11_FRAG_THRESH ,0x1002, -1); /* mapped to cfgInvalid in FW150; TNETW1450 has length 2!! */ +DEF_IE(100_IE_DOT11_BEACON_PERIOD ,0x1003, 0x02); /* mapped to cfgInvalid in FW150 */ +DEF_IE(1xx_IE_DOT11_DTIM_PERIOD ,0x1004, -1); /* mapped to cfgInvalid in FW150 */ +DEF_IE(1FF_IE_DOT11_MAX_RX_LIFETIME ,0x1004, -1); /* later firmware versions; maybe TNETW1450 only? */ +DEF_IE(1xx_IE_DOT11_SHORT_RETRY_LIMIT ,0x1005, 0x01); /* TNETW1450: length 2 */ +DEF_IE(1xx_IE_DOT11_LONG_RETRY_LIMIT ,0x1006, 0x01); /* TNETW1450: length 2 */ +DEF_IE(100_IE_DOT11_WEP_DEFAULT_KEY_WRITE ,0x1007, 0x20); /* configure default keys; TNETW1450 has length 0x24!! */ +DEF_IE(1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME ,0x1008, 0x04); +DEF_IE(1xx_IE_DOT11_GROUP_ADDR ,0x1009, -1); +DEF_IE(1xx_IE_DOT11_CURRENT_REG_DOMAIN ,0x100a, 0x02); +/* It's harmless to have larger struct. Use USB case always. */ +DEF_IE(1xx_IE_DOT11_CURRENT_ANTENNA ,0x100b, 0x02); /* in fact len=1 for PCI */ +DEF_IE(1xx_IE_DOT11_UNKNOWN_100C ,0x100c, -1); /* mapped to cfgInvalid in FW150 */ +DEF_IE(1xx_IE_DOT11_TX_POWER_LEVEL ,0x100d, 0x01); /* TNETW1450 has length 2!! */ +DEF_IE(1xx_IE_DOT11_CURRENT_CCA_MODE ,0x100e, 0x02); /* in fact len=1 for PCI */ +/* USB doesn't return anything - len==0?! */ +DEF_IE(100_IE_DOT11_ED_THRESHOLD ,0x100f, 0x04); +DEF_IE(1xx_IE_DOT11_WEP_DEFAULT_KEY_SET ,0x1010, 0x01); /* set default key ID; TNETW1450: length 2 */ +DEF_IE(100_IE_DOT11_UNKNOWN_1011 ,0x1011, -1); /* mapped to cfgInvalid in FW150 */ +DEF_IE(1FF_IE_DOT11_CURR_5GHZ_REGDOM ,0x1011, -1); /* later firmware versions; maybe TNETW1450 only? */ +DEF_IE(100_IE_DOT11_UNKNOWN_1012 ,0x1012, -1); /* mapped to cfgInvalid in FW150 */ +DEF_IE(100_IE_DOT11_UNKNOWN_1013 ,0x1013, -1); /* mapped to cfgInvalid in FW150 */ + +#if 0 +/* Experimentally obtained on acx100, fw 1.9.8.b +** -1 means that fw returned 'invalid IE' +** 0200 FC00 nnnn... are test read contents: u16 type, u16 len, data +** (AA are poison bytes marking bytes not written by fw) +** +** Looks like acx100 fw does not update len field (thus len=256-4=FC here) +** A number of IEs seem to trash type,len fields +** IEs marked 'huge' return gobs of data (no poison bytes remain) +*/ +DEF_IE(100_IE_INVAL_00, 0x0000, -1); +DEF_IE(100_IE_INVAL_01, 0x0001, -1); /* IE_ACX_TIMER, len=16 on older fw */ +DEF_IE(100_IE_POWER_MGMT, 0x0002, 4); /* 0200FC00 00040000 AAAAAAAA */ +DEF_IE(100_IE_QUEUE_CONFIG, 0x0003, 28); /* 0300FC00 48060000 9CAD0000 0101AAAA DCB00000 E4B00000 9CAA0000 00AAAAAA */ +DEF_IE(100_IE_BLOCK_SIZE, 0x0004, 2); /* 0400FC00 0001AAAA AAAAAAAA AAAAAAAA */ +/* write only: */ +DEF_IE(100_IE_MEMORY_CONFIG_OPTIONS, 0x0005, 20); +DEF_IE(100_IE_RATE_FALLBACK, 0x0006, 1); /* 0600FC00 00AAAAAA AAAAAAAA AAAAAAAA */ +/* write only: */ +DEF_IE(100_IE_WEP_OPTIONS, 0x0007, 3); +DEF_IE(100_IE_MEMORY_MAP, 0x0008, 40); /* huge: 0800FC00 30000000 6CA20000 70A20000... */ +/* gives INVAL on read: */ +DEF_IE(100_IE_SCAN_STATUS, 0x0009, -1); +DEF_IE(100_IE_ASSOC_ID, 0x000a, 2); /* huge: 0A00FC00 00000000 01040800 00000000... */ +DEF_IE(100_IE_INVAL_0B, 0x000b, -1); +/* 'command rejected': */ +DEF_IE(100_IE_CONFIG_OPTIONS, 0x000c, -3); +DEF_IE(100_IE_FWREV, 0x000d, 24); /* 0D00FC00 52657620 312E392E 382E6200 AAAAAAAA AAAAAAAA 05050201 AAAAAAAA */ +DEF_IE(100_IE_FCS_ERROR_COUNT, 0x000e, 4); +DEF_IE(100_IE_MEDIUM_USAGE, 0x000f, 8); /* E41F0000 2D780300 FCC91300 AAAAAAAA */ +DEF_IE(100_IE_RXCONFIG, 0x0010, 4); /* 1000FC00 00280000 AAAAAAAA AAAAAAAA */ +DEF_IE(100_IE_QUEUE_THRESH, 0x0011, 12); /* 1100FC00 AAAAAAAA 00000000 00000000 */ +DEF_IE(100_IE_BSS_POWER_SAVE, 0x0012, 1); /* 1200FC00 00AAAAAA AAAAAAAA AAAAAAAA */ +/* read only, variable len */ +DEF_IE(100_IE_FIRMWARE_STATISTICS, 0x0013, 256); /* 0000AC00 00000000 ... */ +DEF_IE(100_IE_INT_CONFIG, 0x0014, 20); /* 00000000 00000000 00000000 00000000 5D74D105 00000000 AAAAAAAA AAAAAAAA */ +DEF_IE(100_IE_FEATURE_CONFIG, 0x0015, 8); /* 1500FC00 16000000 AAAAAAAA AAAAAAAA */ +/* returns 'invalid MAC': */ +DEF_IE(100_IE_KEY_CHOOSE, 0x0016, -4); +DEF_IE(100_IE_INVAL_17, 0x0017, -1); +DEF_IE(100_IE_UNKNOWN_18, 0x0018, 0); /* null len?! 1800FC00 AAAAAAAA AAAAAAAA AAAAAAAA */ +DEF_IE(100_IE_UNKNOWN_19, 0x0019, 256); /* huge: 1900FC00 9C1F00EA FEFFFFEA FEFFFFEA... */ +DEF_IE(100_IE_INVAL_1A, 0x001A, -1); + +DEF_IE(100_IE_DOT11_INVAL_1000, 0x1000, -1); +DEF_IE(100_IE_DOT11_STATION_ID, 0x1001, 6); /* huge: 0110FC00 58B10E2F 03000000 00000000... */ +DEF_IE(100_IE_DOT11_INVAL_1002, 0x1002, -1); +DEF_IE(100_IE_DOT11_INVAL_1003, 0x1003, -1); +DEF_IE(100_IE_DOT11_INVAL_1004, 0x1004, -1); +DEF_IE(100_IE_DOT11_SHORT_RETRY_LIMIT, 0x1005, 1); +DEF_IE(100_IE_DOT11_LONG_RETRY_LIMIT, 0x1006, 1); +/* write only: */ +DEF_IE(100_IE_DOT11_WEP_DEFAULT_KEY_WRITE, 0x1007, 32); +DEF_IE(100_IE_DOT11_MAX_XMIT_MSDU_LIFETIME, 0x1008, 4); /* huge: 0810FC00 00020000 F4010000 00000000... */ +/* undoc but returns something */ +DEF_IE(100_IE_DOT11_GROUP_ADDR, 0x1009, 12); /* huge: 0910FC00 00000000 00000000 00000000... */ +DEF_IE(100_IE_DOT11_CURRENT_REG_DOMAIN, 0x100a, 1); /* 0A10FC00 30AAAAAA AAAAAAAA AAAAAAAA */ +DEF_IE(100_IE_DOT11_CURRENT_ANTENNA, 0x100b, 1); /* 0B10FC00 8FAAAAAA AAAAAAAA AAAAAAAA */ +DEF_IE(100_IE_DOT11_INVAL_100C, 0x100c, -1); +DEF_IE(100_IE_DOT11_TX_POWER_LEVEL, 0x100d, 2); /* 00000000 0100AAAA AAAAAAAA AAAAAAAA */ +DEF_IE(100_IE_DOT11_CURRENT_CCA_MODE, 0x100e, 1); /* 0E10FC00 0DAAAAAA AAAAAAAA AAAAAAAA */ +DEF_IE(100_IE_DOT11_ED_THRESHOLD, 0x100f, 4); /* 0F10FC00 70000000 AAAAAAAA AAAAAAAA */ +/* set default key ID */ +DEF_IE(100_IE_DOT11_WEP_DEFAULT_KEY_SET, 0x1010, 1); /* 1010FC00 00AAAAAA AAAAAAAA AAAAAAAA */ +DEF_IE(100_IE_DOT11_INVAL_1011, 0x1011, -1); +DEF_IE(100_IE_DOT11_INVAL_1012, 0x1012, -1); +DEF_IE(100_IE_DOT11_INVAL_1013, 0x1013, -1); +DEF_IE(100_IE_DOT11_UNKNOWN_1014, 0x1014, 256); /* huge */ +DEF_IE(100_IE_DOT11_UNKNOWN_1015, 0x1015, 256); /* huge */ +DEF_IE(100_IE_DOT11_UNKNOWN_1016, 0x1016, 256); /* huge */ +DEF_IE(100_IE_DOT11_UNKNOWN_1017, 0x1017, 256); /* huge */ +DEF_IE(100_IE_DOT11_UNKNOWN_1018, 0x1018, 256); /* huge */ +DEF_IE(100_IE_DOT11_UNKNOWN_1019, 0x1019, 256); /* huge */ +#endif + +#if 0 +/* Experimentally obtained on PCI acx111 Xterasys XN-2522g, fw 1.2.1.34 +** -1 means that fw returned 'invalid IE' +** 0400 0800 nnnn... are test read contents: u16 type, u16 len, data +** (AA are poison bytes marking bytes not written by fw) +** +** Looks like acx111 fw reports real len! +*/ +DEF_IE(111_IE_INVAL_00, 0x0000, -1); +DEF_IE(111_IE_INVAL_01, 0x0001, -1); +DEF_IE(111_IE_POWER_MGMT, 0x0002, 12); +/* write only, variable len: 12 + rxqueue_cnt*8 + txqueue_cnt*4: */ +DEF_IE(111_IE_MEMORY_CONFIG, 0x0003, 24); +DEF_IE(111_IE_BLOCK_SIZE, 0x0004, 8); /* 04000800 AA00AAAA AAAAAAAA */ +/* variable len: 8 + rxqueue_cnt*8 + txqueue_cnt*8: */ +DEF_IE(111_IE_QUEUE_HEAD, 0x0005, 24); +DEF_IE(111_IE_RATE_FALLBACK, 0x0006, 1); +/* acx100 name:WEP_OPTIONS */ +/* said to have len:1 (not true, actually returns 12 bytes): */ +DEF_IE(111_IE_RADIO_BAND, 0x0007, 12); /* 07000C00 AAAA1F00 FF03AAAA AAAAAAAA */ +DEF_IE(111_IE_MEMORY_MAP, 0x0008, 48); +/* said to have len:4, but gives INVAL on read: */ +DEF_IE(111_IE_SCAN_STATUS, 0x0009, -1); +DEF_IE(111_IE_ASSOC_ID, 0x000a, 2); +/* write only, len is not known: */ +DEF_IE(111_IE_UNKNOWN_0B, 0x000b, 0); +/* read only, variable len. I see 67 byte reads: */ +DEF_IE(111_IE_CONFIG_OPTIONS, 0x000c, 67); /* 0C004300 01160500 ... */ +DEF_IE(111_IE_FWREV, 0x000d, 24); +DEF_IE(111_IE_FCS_ERROR_COUNT, 0x000e, 4); +DEF_IE(111_IE_MEDIUM_USAGE, 0x000f, 8); +DEF_IE(111_IE_RXCONFIG, 0x0010, 4); +DEF_IE(111_IE_QUEUE_THRESH, 0x0011, 12); +DEF_IE(111_IE_BSS_POWER_SAVE, 0x0012, 1); +/* read only, variable len. I see 240 byte reads: */ +DEF_IE(111_IE_FIRMWARE_STATISTICS, 0x0013, 240); /* 1300F000 00000000 ... */ +/* said to have len=17. looks like fw pads it to 20: */ +DEF_IE(111_IE_INT_CONFIG, 0x0014, 20); /* 14001400 00000000 00000000 00000000 00000000 00000000 */ +DEF_IE(111_IE_FEATURE_CONFIG, 0x0015, 8); +/* said to be name:KEY_INDICATOR, len:4, but gives INVAL on read: */ +DEF_IE(111_IE_KEY_CHOOSE, 0x0016, -1); +/* said to have len:4, but in fact returns 8: */ +DEF_IE(111_IE_MAX_USB_XFR, 0x0017, 8); /* 17000800 00014000 00000000 */ +DEF_IE(111_IE_INVAL_18, 0x0018, -1); +DEF_IE(111_IE_INVAL_19, 0x0019, -1); +/* undoc but returns something: */ +/* huh, fw indicates len=20 but uses 4 more bytes in buffer??? */ +DEF_IE(111_IE_UNKNOWN_1A, 0x001A, 20); /* 1A001400 AA00AAAA 0000020F FF030000 00020000 00000007 04000000 */ + +DEF_IE(111_IE_DOT11_INVAL_1000, 0x1000, -1); +DEF_IE(111_IE_DOT11_STATION_ID, 0x1001, 6); +DEF_IE(111_IE_DOT11_FRAG_THRESH, 0x1002, 2); +/* acx100 only? gives INVAL on read: */ +DEF_IE(111_IE_DOT11_BEACON_PERIOD, 0x1003, -1); +/* said to be MAX_RECV_MSDU_LIFETIME: */ +DEF_IE(111_IE_DOT11_DTIM_PERIOD, 0x1004, 4); +DEF_IE(111_IE_DOT11_SHORT_RETRY_LIMIT, 0x1005, 1); +DEF_IE(111_IE_DOT11_LONG_RETRY_LIMIT, 0x1006, 1); +/* acx100 only? gives INVAL on read: */ +DEF_IE(111_IE_DOT11_WEP_DEFAULT_KEY_WRITE, 0x1007, -1); +DEF_IE(111_IE_DOT11_MAX_XMIT_MSDU_LIFETIME, 0x1008, 4); +/* undoc but returns something. maybe it's 2 multicast MACs to listen to? */ +DEF_IE(111_IE_DOT11_GROUP_ADDR, 0x1009, 12); /* 09100C00 00000000 00000000 00000000 */ +DEF_IE(111_IE_DOT11_CURRENT_REG_DOMAIN, 0x100a, 1); +DEF_IE(111_IE_DOT11_CURRENT_ANTENNA, 0x100b, 2); +DEF_IE(111_IE_DOT11_INVAL_100C, 0x100c, -1); +DEF_IE(111_IE_DOT11_TX_POWER_LEVEL, 0x100d, 1); +/* said to have len=1 but gives INVAL on read: */ +DEF_IE(111_IE_DOT11_CURRENT_CCA_MODE, 0x100e, -1); +/* said to have len=4 but gives INVAL on read: */ +DEF_IE(111_IE_DOT11_ED_THRESHOLD, 0x100f, -1); +/* set default key ID. write only: */ +DEF_IE(111_IE_DOT11_WEP_DEFAULT_KEY_SET, 0x1010, 1); +/* undoc but returns something: */ +DEF_IE(111_IE_DOT11_UNKNOWN_1011, 0x1011, 1); /* 11100100 20 */ +DEF_IE(111_IE_DOT11_INVAL_1012, 0x1012, -1); +DEF_IE(111_IE_DOT11_INVAL_1013, 0x1013, -1); +#endif + + +/*********************************************************************** +**Information Frames Structures +*/ + +/* Used in beacon frames and the like */ +#define DOT11RATEBYTE_1 (1*2) +#define DOT11RATEBYTE_2 (2*2) +#define DOT11RATEBYTE_5_5 (5*2+1) +#define DOT11RATEBYTE_11 (11*2) +#define DOT11RATEBYTE_22 (22*2) +#define DOT11RATEBYTE_6_G (6*2) +#define DOT11RATEBYTE_9_G (9*2) +#define DOT11RATEBYTE_12_G (12*2) +#define DOT11RATEBYTE_18_G (18*2) +#define DOT11RATEBYTE_24_G (24*2) +#define DOT11RATEBYTE_36_G (36*2) +#define DOT11RATEBYTE_48_G (48*2) +#define DOT11RATEBYTE_54_G (54*2) +#define DOT11RATEBYTE_BASIC 0x80 /* flags rates included in basic rate set */ + + +/*********************************************************************** +** rxbuffer_t +** +** This is the format of rx data returned by acx +*/ + +/* I've hoped it's a 802.11 PHY header, but no... + * so far, I've seen on acx111: + * 0000 3a00 0000 0000 IBSS Beacons + * 0000 3c00 0000 0000 ESS Beacons + * 0000 2700 0000 0000 Probe requests + * --vda + */ +typedef struct phy_hdr { + u8 unknown[4]; + u8 acx111_unknown[4]; +} ACX_PACKED phy_hdr_t; + +/* seems to be a bit similar to hfa384x_rx_frame. + * These fields are still not quite obvious, though. + * Some seem to have different meanings... */ + +#define RXBUF_HDRSIZE 12 +#define RXBUF_BYTES_RCVD(adev, rxbuf) \ + ((le16_to_cpu((rxbuf)->mac_cnt_rcvd) & 0xfff) - (adev)->phy_header_len) +#define RXBUF_BYTES_USED(rxbuf) \ + ((le16_to_cpu((rxbuf)->mac_cnt_rcvd) & 0xfff) + RXBUF_HDRSIZE) +/* USBism */ +#define RXBUF_IS_TXSTAT(rxbuf) (le16_to_cpu((rxbuf)->mac_cnt_rcvd) & 0x8000) +/* +mac_cnt_rcvd: + 12 bits: length of frame from control field to first byte of FCS + 3 bits: reserved + 1 bit: 1 = it's a tx status info, not a rx packet (USB only) + +mac_cnt_mblks: + 6 bits: number of memory block used to store frame in adapter memory + 1 bit: Traffic Indicator bit in TIM of received Beacon was set + +mac_status: 1 byte (bitmap): + 7 Matching BSSID + 6 Matching SSID + 5 BDCST Address 1 field is a broadcast + 4 VBM received beacon frame has more than one set bit (?!) + 3 TIM Set bit representing this station is set in TIM of received beacon + 2 GROUP Address 1 is a multicast + 1 ADDR1 Address 1 matches our MAC + 0 FCSGD FSC is good + +phy_stat_baseband: 1 byte (bitmap): + 7 Preamble frame had a long preamble + 6 PLCP Error CRC16 error in PLCP header + 5 Unsup_Mod unsupported modulation + 4 Selected Antenna antenna 1 was used to receive this frame + 3 PBCC/CCK frame used: 1=PBCC, 0=CCK modulation + 2 OFDM frame used OFDM modulation + 1 TI Protection protection frame was detected + 0 Reserved + +phy_plcp_signal: 1 byte: + Receive PLCP Signal field from the Baseband Processor + +phy_level: 1 byte: + receive AGC gain level (can be used to measure receive signal strength) + +phy_snr: 1 byte: + estimated noise power of equalized receive signal + at input of FEC decoder (can be used to measure receive signal quality) + +time: 4 bytes: + timestamp sampled from either the Access Manager TSF counter + or free-running microsecond counter when the MAC receives + first byte of PLCP header. +*/ + +typedef struct rxbuffer { + u16 mac_cnt_rcvd; /* only 12 bits are len! (0xfff) */ + u8 mac_cnt_mblks; + u8 mac_status; + u8 phy_stat_baseband; /* bit 0x80: used LNA (Low-Noise Amplifier) */ + u8 phy_plcp_signal; + u8 phy_level; /* PHY stat */ + u8 phy_snr; /* PHY stat */ + u32 time; /* timestamp upon MAC rcv first byte */ +/* 4-byte (acx100) or 8-byte (acx111) phy header will be here +** if RX_CFG1_INCLUDE_PHY_HDR is in effect: +** phy_hdr_t phy */ + wlan_hdr_a3_t hdr_a3; + /* maximally sized data part of wlan packet */ + u8 data_a3[WLAN_A4FR_MAXLEN_WEP_FCS - WLAN_HDR_A3_LEN]; + /* can add hdr/data_a4 if needed */ +} ACX_PACKED rxbuffer_t; + + +/*--- Firmware statistics ----------------------------------------------------*/ + +/* define a random 100 bytes more to catch firmware versions which + * provide a bigger struct */ +#define FW_STATS_FUTURE_EXTENSION 100 + +typedef struct fw_stats_tx { + u32 tx_desc_of; +} ACX_PACKED fw_stats_tx_t; + +typedef struct fw_stats_rx { + u32 rx_oom; + u32 rx_hdr_of; + u32 rx_hw_stuck; /* old: u32 rx_hdr_use_next */ + u32 rx_dropped_frame; + u32 rx_frame_ptr_err; + u32 rx_xfr_hint_trig; + u32 rx_aci_events; /* later versions only */ + u32 rx_aci_resets; /* later versions only */ +} ACX_PACKED fw_stats_rx_t; + +typedef struct fw_stats_dma { + u32 rx_dma_req; + u32 rx_dma_err; + u32 tx_dma_req; + u32 tx_dma_err; +} ACX_PACKED fw_stats_dma_t; + +typedef struct fw_stats_irq { + u32 cmd_cplt; + u32 fiq; + u32 rx_hdrs; + u32 rx_cmplt; + u32 rx_mem_of; + u32 rx_rdys; + u32 irqs; + u32 tx_procs; + u32 decrypt_done; + u32 dma_0_done; + u32 dma_1_done; + u32 tx_exch_complet; + u32 commands; + u32 rx_procs; + u32 hw_pm_mode_changes; + u32 host_acks; + u32 pci_pm; + u32 acm_wakeups; +} ACX_PACKED fw_stats_irq_t; + +typedef struct fw_stats_wep { + u32 wep_key_count; + u32 wep_default_key_count; + u32 dot11_def_key_mib; + u32 wep_key_not_found; + u32 wep_decrypt_fail; + u32 wep_pkt_decrypt; + u32 wep_decrypt_irqs; +} ACX_PACKED fw_stats_wep_t; + +typedef struct fw_stats_pwr { + u32 tx_start_ctr; + u32 no_ps_tx_too_short; + u32 rx_start_ctr; + u32 no_ps_rx_too_short; + u32 lppd_started; + u32 no_lppd_too_noisy; + u32 no_lppd_too_short; + u32 no_lppd_matching_frame; +} ACX_PACKED fw_stats_pwr_t; + +typedef struct fw_stats_mic { + u32 mic_rx_pkts; + u32 mic_calc_fail; +} ACX_PACKED fw_stats_mic_t; + +typedef struct fw_stats_aes { + u32 aes_enc_fail; + u32 aes_dec_fail; + u32 aes_enc_pkts; + u32 aes_dec_pkts; + u32 aes_enc_irq; + u32 aes_dec_irq; +} ACX_PACKED fw_stats_aes_t; + +typedef struct fw_stats_event { + u32 heartbeat; + u32 calibration; + u32 rx_mismatch; + u32 rx_mem_empty; + u32 rx_pool; + u32 oom_late; + u32 phy_tx_err; + u32 tx_stuck; +} ACX_PACKED fw_stats_event_t; + +/* mainly for size calculation only */ +typedef struct fw_stats { + u16 type; + u16 len; + fw_stats_tx_t tx; + fw_stats_rx_t rx; + fw_stats_dma_t dma; + fw_stats_irq_t irq; + fw_stats_wep_t wep; + fw_stats_pwr_t pwr; + fw_stats_mic_t mic; + fw_stats_aes_t aes; + fw_stats_event_t evt; + u8 _padding[FW_STATS_FUTURE_EXTENSION]; +} fw_stats_t; + +/* Firmware version struct */ + +typedef struct fw_ver { + u16 cmd; + u16 size; + char fw_id[20]; + u32 hw_id; +} ACX_PACKED fw_ver_t; + +#define FW_ID_SIZE 20 + + +/*--- WEP stuff --------------------------------------------------------------*/ +#define DOT11_MAX_DEFAULT_WEP_KEYS 4 + +/* non-firmware struct, no packing necessary */ +typedef struct wep_key { + size_t size; /* most often used member first */ + u8 index; + u8 key[29]; + u16 strange_filler; +} wep_key_t; /* size = 264 bytes (33*8) */ +/* FIXME: We don't have size 264! Or is there 2 bytes beyond the key + * (strange_filler)? */ + +/* non-firmware struct, no packing necessary */ +typedef struct key_struct { + u8 addr[ETH_ALEN]; /* 0x00 */ + u16 filler1; /* 0x06 */ + u32 filler2; /* 0x08 */ + u32 index; /* 0x0c */ + u16 len; /* 0x10 */ + u8 key[29]; /* 0x12; is this long enough??? */ +} key_struct_t; /* size = 276. FIXME: where is the remaining space?? */ + + +/*--- Client (peer) info -----------------------------------------------------*/ +/* adev->sta_list[] is used for: +** accumulating and processing of scan results +** keeping client info in AP mode +** keeping AP info in STA mode (AP is the only one 'client') +** keeping peer info in ad-hoc mode +** non-firmware struct --> no packing necessary */ +enum { + CLIENT_EMPTY_SLOT_0 = 0, + CLIENT_EXIST_1 = 1, + CLIENT_AUTHENTICATED_2 = 2, + CLIENT_ASSOCIATED_3 = 3, + CLIENT_JOIN_CANDIDATE = 4 +}; +struct client { + /* most frequent access first */ + u8 used; /* misnamed, more like 'status' */ + struct client* next; + unsigned long mtime; /* last time we heard it, in jiffies */ + size_t essid_len; /* length of ESSID (without '\0') */ + u32 sir; /* Standard IR */ + u32 snr; /* Signal to Noise Ratio */ + u16 aid; /* association ID */ + u16 seq; /* from client's auth req */ + u16 auth_alg; /* from client's auth req */ + u16 cap_info; /* from client's assoc req */ + u16 rate_cap; /* what client supports (all rates) */ + u16 rate_bas; /* what client supports (basic rates) */ + u16 rate_cfg; /* what is allowed (by iwconfig etc) */ + u16 rate_cur; /* currently used rate mask */ + u8 rate_100; /* currently used rate byte (acx100 only) */ + u8 address[ETH_ALEN]; + u8 bssid[ETH_ALEN]; /* ad-hoc hosts can have bssid != mac */ + u8 channel; + u8 auth_step; + u8 ignore_count; + u8 fallback_count; + u8 stepup_count; + char essid[IW_ESSID_MAX_SIZE + 1]; /* ESSID and trailing '\0' */ +/* FIXME: this one is too damn big */ + char challenge_text[WLAN_CHALLENGE_LEN]; +}; + + +/*********************************************************************** +** Hardware structures +*/ + +/* An opaque typesafe helper type + * + * Some hardware fields are actually pointers, + * but they have to remain u32, since using ptr instead + * (8 bytes on 64bit systems!) would disrupt the fixed descriptor + * format the acx firmware expects in the non-user area. + * Since we cannot cram an 8 byte ptr into 4 bytes, we need to + * enforce that pointed to data remains in low memory + * (address value needs to fit in 4 bytes) on 64bit systems. + * + * This is easy to get wrong, thus we are using a small struct + * and special macros to access it. Macros will check for + * attempts to overflow an acx_ptr with value > 0xffffffff. + * + * Attempts to use acx_ptr without macros result in compile-time errors */ + +typedef struct { + u32 v; +} ACX_PACKED acx_ptr; + +#if ACX_DEBUG +#define CHECK32(n) BUG_ON(sizeof(n)>4 && (long)(n)>0xffffff00) +#else +#define CHECK32(n) ((void)0) +#endif + +/* acx_ptr <-> integer conversion */ +#define cpu2acx(n) ({ CHECK32(n); ((acx_ptr){ .v = cpu_to_le32(n) }); }) +#define acx2cpu(a) (le32_to_cpu(a.v)) + +/* acx_ptr <-> pointer conversion */ +#define ptr2acx(p) ({ CHECK32(p); ((acx_ptr){ .v = cpu_to_le32((u32)(long)(p)) }); }) +#define acx2ptr(a) ((void*)le32_to_cpu(a.v)) + +/* Values for rate field (acx100 only) */ +#define RATE100_1 10 +#define RATE100_2 20 +#define RATE100_5 55 +#define RATE100_11 110 +#define RATE100_22 220 +/* This bit denotes use of PBCC: +** (PBCC encoding is usable with 11 and 22 Mbps speeds only) */ +#define RATE100_PBCC511 0x80 + +/* Bit values for rate111 field */ +#define RATE111_1 0x0001 /* DBPSK */ +#define RATE111_2 0x0002 /* DQPSK */ +#define RATE111_5 0x0004 /* CCK or PBCC */ +#define RATE111_6 0x0008 /* CCK-OFDM or OFDM */ +#define RATE111_9 0x0010 /* CCK-OFDM or OFDM */ +#define RATE111_11 0x0020 /* CCK or PBCC */ +#define RATE111_12 0x0040 /* CCK-OFDM or OFDM */ +#define RATE111_18 0x0080 /* CCK-OFDM or OFDM */ +#define RATE111_22 0x0100 /* PBCC */ +#define RATE111_24 0x0200 /* CCK-OFDM or OFDM */ +#define RATE111_36 0x0400 /* CCK-OFDM or OFDM */ +#define RATE111_48 0x0800 /* CCK-OFDM or OFDM */ +#define RATE111_54 0x1000 /* CCK-OFDM or OFDM */ +#define RATE111_RESERVED 0x2000 +#define RATE111_PBCC511 0x4000 /* PBCC mod at 5.5 or 11Mbit (else CCK) */ +#define RATE111_SHORTPRE 0x8000 /* short preamble */ +/* Special 'try everything' value */ +#define RATE111_ALL 0x1fff +/* These bits denote acx100 compatible settings */ +#define RATE111_ACX100_COMPAT 0x0127 +/* These bits denote 802.11b compatible settings */ +#define RATE111_80211B_COMPAT 0x0027 + +/* Descriptor Ctl field bits + * init value is 0x8e, "idle" value is 0x82 (in idle tx descs) + */ +#define DESC_CTL_SHORT_PREAMBLE 0x01 /* preamble type: 0 = long; 1 = short */ +#define DESC_CTL_FIRSTFRAG 0x02 /* this is the 1st frag of the frame */ +#define DESC_CTL_AUTODMA 0x04 +#define DESC_CTL_RECLAIM 0x08 /* ready to reuse */ +#define DESC_CTL_HOSTDONE 0x20 /* host has finished processing */ +#define DESC_CTL_ACXDONE 0x40 /* acx has finished processing */ +/* host owns the desc [has to be released last, AFTER modifying all other desc fields!] */ +#define DESC_CTL_HOSTOWN 0x80 +#define DESC_CTL_ACXDONE_HOSTOWN (DESC_CTL_ACXDONE | DESC_CTL_HOSTOWN) + +/* Descriptor Status field + */ +#define DESC_STATUS_FULL (1 << 31) + +/* NB: some bits may be interesting for Monitor mode tx (aka Raw tx): */ +#define DESC_CTL2_SEQ 0x01 /* don't increase sequence field */ +#define DESC_CTL2_FCS 0x02 /* don't add the FCS */ +#define DESC_CTL2_MORE_FRAG 0x04 +#define DESC_CTL2_RETRY 0x08 /* don't increase retry field */ +#define DESC_CTL2_POWER 0x10 /* don't increase power mgmt. field */ +#define DESC_CTL2_RTS 0x20 /* do RTS/CTS magic before sending */ +#define DESC_CTL2_WEP 0x40 /* encrypt this frame */ +#define DESC_CTL2_DUR 0x80 /* don't increase duration field */ + +/*********************************************************************** +** PCI structures +*/ +/* IRQ Constants +** (outside of "#ifdef PCI" because USB (mis)uses HOST_INT_SCAN_COMPLETE) */ +#define HOST_INT_RX_DATA 0x0001 +#define HOST_INT_TX_COMPLETE 0x0002 +#define HOST_INT_TX_XFER 0x0004 +#define HOST_INT_RX_COMPLETE 0x0008 +#define HOST_INT_DTIM 0x0010 +#define HOST_INT_BEACON 0x0020 +#define HOST_INT_TIMER 0x0040 +#define HOST_INT_KEY_NOT_FOUND 0x0080 +#define HOST_INT_IV_ICV_FAILURE 0x0100 +#define HOST_INT_CMD_COMPLETE 0x0200 +#define HOST_INT_INFO 0x0400 +#define HOST_INT_OVERFLOW 0x0800 +#define HOST_INT_PROCESS_ERROR 0x1000 +#define HOST_INT_SCAN_COMPLETE 0x2000 +#define HOST_INT_FCS_THRESHOLD 0x4000 +#define HOST_INT_UNKNOWN 0x8000 + +/* Outside of "#ifdef PCI" because USB needs to know sizeof() +** of txdesc and rxdesc: */ +struct txdesc { + acx_ptr pNextDesc; /* pointer to next txdesc */ + acx_ptr HostMemPtr; /* 0x04 */ + acx_ptr AcxMemPtr; /* 0x08 */ + u32 tx_time; /* 0x0c */ + u16 total_length; /* 0x10 */ + u16 Reserved; /* 0x12 */ + +/* The following 16 bytes do not change when acx100 owns the descriptor */ +/* BUG: fw clears last byte of this area which is supposedly reserved +** for driver use. amd64 blew up. We dare not use it now */ + u32 dummy[4]; + + u8 Ctl_8; /* 0x24, 8bit value */ + u8 Ctl2_8; /* 0x25, 8bit value */ + u8 error; /* 0x26 */ + u8 ack_failures; /* 0x27 */ + u8 rts_failures; /* 0x28 */ + u8 rts_ok; /* 0x29 */ + union { + struct { + u8 rate; /* 0x2a */ + u8 queue_ctrl; /* 0x2b */ + } ACX_PACKED r1; + struct { + u16 rate111; /* 0x2a */ + } ACX_PACKED r2; + } ACX_PACKED u; + u32 queue_info; /* 0x2c (acx100, reserved on acx111) */ +} ACX_PACKED; /* size : 48 = 0x30 */ +/* NB: acx111 txdesc structure is 4 byte larger */ +/* All these 4 extra bytes are reserved. tx alloc code takes them into account */ + +struct rxdesc { + acx_ptr pNextDesc; /* 0x00 */ + acx_ptr HostMemPtr; /* 0x04 */ + acx_ptr ACXMemPtr; /* 0x08 */ + u32 rx_time; /* 0x0c */ + u16 total_length; /* 0x10 */ + u16 WEP_length; /* 0x12 */ + u32 WEP_ofs; /* 0x14 */ + +/* the following 16 bytes do not change when acx100 owns the descriptor */ + u8 driverWorkspace[16]; /* 0x18 */ + + u8 Ctl_8; + u8 rate; + u8 error; + u8 SNR; /* Signal-to-Noise Ratio */ + u8 RxLevel; + u8 queue_ctrl; + u16 unknown; + u32 unknown2; +} ACX_PACKED; /* size 52 = 0x34 */ + +#ifdef ACX_PCI + +/* Register I/O offsets */ +#define ACX100_EEPROM_ID_OFFSET 0x380 + +/* please add further ACX hardware register definitions only when + it turns out you need them in the driver, and please try to use + firmware functionality instead, since using direct I/O access instead + of letting the firmware do it might confuse the firmware's state + machine */ + +/* ***** ABSOLUTELY ALWAYS KEEP OFFSETS IN SYNC WITH THE INITIALIZATION +** OF THE I/O ARRAYS!!!! (grep for '^IO_ACX') ***** */ +enum { + IO_ACX_SOFT_RESET = 0, + + IO_ACX_SLV_MEM_ADDR, + IO_ACX_SLV_MEM_DATA, + IO_ACX_SLV_MEM_CTL, + IO_ACX_SLV_END_CTL, + + IO_ACX_FEMR, /* Function Event Mask */ + + IO_ACX_INT_TRIG, + IO_ACX_IRQ_MASK, + IO_ACX_IRQ_STATUS_NON_DES, + IO_ACX_IRQ_STATUS_CLEAR, /* CLEAR = clear on read */ + IO_ACX_IRQ_ACK, + IO_ACX_HINT_TRIG, + + IO_ACX_ENABLE, + + IO_ACX_EEPROM_CTL, + IO_ACX_EEPROM_ADDR, + IO_ACX_EEPROM_DATA, + IO_ACX_EEPROM_CFG, + + IO_ACX_PHY_ADDR, + IO_ACX_PHY_DATA, + IO_ACX_PHY_CTL, + + IO_ACX_GPIO_OE, + + IO_ACX_GPIO_OUT, + + IO_ACX_CMD_MAILBOX_OFFS, + IO_ACX_INFO_MAILBOX_OFFS, + IO_ACX_EEPROM_INFORMATION, + + IO_ACX_EE_START, + IO_ACX_SOR_CFG, + IO_ACX_ECPU_CTRL +}; +/* ***** ABSOLUTELY ALWAYS KEEP OFFSETS IN SYNC WITH THE INITIALIZATION +** OF THE I/O ARRAYS!!!! (grep for '^IO_ACX') ***** */ + +/* Values for IO_ACX_INT_TRIG register: */ +/* inform hw that rxdesc in queue needs processing */ +#define INT_TRIG_RXPRC 0x08 +/* inform hw that txdesc in queue needs processing */ +#define INT_TRIG_TXPRC 0x04 +/* ack that we received info from info mailbox */ +#define INT_TRIG_INFOACK 0x02 +/* inform hw that we have filled command mailbox */ +#define INT_TRIG_CMD 0x01 + +struct txhostdesc { + acx_ptr data_phy; /* 0x00 [u8 *] */ + u16 data_offset; /* 0x04 */ + u16 reserved; /* 0x06 */ + u16 Ctl_16; /* 16bit value, endianness!! */ + u16 length; /* 0x0a */ + acx_ptr desc_phy_next; /* 0x0c [txhostdesc *] */ + acx_ptr pNext; /* 0x10 [txhostdesc *] */ + u32 Status; /* 0x14, unused on Tx */ +/* From here on you can use this area as you want (variable length, too!) */ + u8 *data; +} ACX_PACKED; + +struct rxhostdesc { + acx_ptr data_phy; /* 0x00 [rxbuffer_t *] */ + u16 data_offset; /* 0x04 */ + u16 reserved; /* 0x06 */ + u16 Ctl_16; /* 0x08; 16bit value, endianness!! */ + u16 length; /* 0x0a */ + acx_ptr desc_phy_next; /* 0x0c [rxhostdesc_t *] */ + acx_ptr pNext; /* 0x10 [rxhostdesc_t *] */ + u32 Status; /* 0x14 */ +/* From here on you can use this area as you want (variable length, too!) */ + rxbuffer_t *data; +} ACX_PACKED; + +#endif /* ACX_PCI */ + +/*********************************************************************** +** USB structures and constants +*/ +#ifdef ACX_USB + +/* Used for usb_txbuffer.desc field */ +#define USB_TXBUF_TXDESC 0xA +/* Size of header (everything up to data[]) */ +#define USB_TXBUF_HDRSIZE 14 +typedef struct usb_txbuffer { + u16 desc; + u16 mpdu_len; + u8 queue_index; + u8 rate; + u32 hostdata; + u8 ctrl1; + u8 ctrl2; + u16 data_len; + /* wlan packet content is placed here: */ + u8 data[WLAN_A4FR_MAXLEN_WEP_FCS]; +} ACX_PACKED usb_txbuffer_t; + +/* USB returns either rx packets (see rxbuffer) or +** these "tx status" structs: */ +typedef struct usb_txstatus { + u16 mac_cnt_rcvd; /* only 12 bits are len! (0xfff) */ + u8 queue_index; + u8 mac_status; /* seen 0x20 on tx failure */ + u32 hostdata; + u8 rate; + u8 ack_failures; + u8 rts_failures; + u8 rts_ok; +} ACX_PACKED usb_txstatus_t; + +typedef struct usb_tx { + unsigned busy:1; + struct urb *urb; + acx_device_t *adev; + /* actual USB bulk output data block is here: */ + usb_txbuffer_t bulkout; +} usb_tx_t; + +struct usb_rx_plain { + unsigned busy:1; + struct urb *urb; + acx_device_t *adev; + rxbuffer_t bulkin; +}; + +typedef struct usb_rx { + unsigned busy:1; + struct urb *urb; + acx_device_t *adev; + rxbuffer_t bulkin; + /* Make entire structure 4k. Report if it breaks something. */ + u8 padding[4*1024 - sizeof(struct usb_rx_plain)]; +} usb_rx_t; +#endif /* ACX_USB */ + + +/* Config Option structs */ + +typedef struct co_antennas { + u8 type; + u8 len; + u8 list[2]; +} ACX_PACKED co_antennas_t; + +typedef struct co_powerlevels { + u8 type; + u8 len; + u16 list[8]; +} ACX_PACKED co_powerlevels_t; + +typedef struct co_datarates { + u8 type; + u8 len; + u8 list[8]; +} ACX_PACKED co_datarates_t; + +typedef struct co_domains { + u8 type; + u8 len; + u8 list[6]; +} ACX_PACKED co_domains_t; + +typedef struct co_product_id { + u8 type; + u8 len; + u8 list[128]; +} ACX_PACKED co_product_id_t; + +typedef struct co_manuf_id { + u8 type; + u8 len; + u8 list[128]; +} ACX_PACKED co_manuf_t; + +typedef struct co_fixed { + char NVSv[8]; +/* u16 NVS_vendor_offs; ACX111-only */ +/* u16 unknown; ACX111-only */ + u8 MAC[6]; /* ACX100-only */ + u16 probe_delay; /* ACX100-only */ + u32 eof_memory; + u8 dot11CCAModes; + u8 dot11Diversity; + u8 dot11ShortPreambleOption; + u8 dot11PBCCOption; + u8 dot11ChannelAgility; + u8 dot11PhyType; /* FIXME: does 802.11 call it "dot11PHYType"? */ + u8 dot11TempType; + u8 table_count; +} ACX_PACKED co_fixed_t; + +typedef struct acx111_ie_configoption { + u16 type; + u16 len; +/* Do not access below members directly, they are in fact variable length */ + co_fixed_t fixed; + co_antennas_t antennas; + co_powerlevels_t power_levels; + co_datarates_t data_rates; + co_domains_t domains; + co_product_id_t product_id; + co_manuf_t manufacturer; + u8 _padding[4]; +} ACX_PACKED acx111_ie_configoption_t; + + +/*********************************************************************** +** Main acx per-device data structure +*/ +#define ACX_STATE_FW_LOADED 0x01 +#define ACX_STATE_IFACE_UP 0x02 + +/* MAC mode (BSS type) defines + * Note that they shouldn't be redefined, since they are also used + * during communication with firmware */ +#define ACX_MODE_0_ADHOC 0 +#define ACX_MODE_1_UNUSED 1 +#define ACX_MODE_2_STA 2 +#define ACX_MODE_3_AP 3 +/* These are our own inventions. Sending these to firmware +** makes it stop emitting beacons, which is exactly what we want +** for these modes */ +#define ACX_MODE_MONITOR 0xfe +#define ACX_MODE_OFF 0xff +/* 'Submode': identifies exact status of ADHOC/STA host */ +#define ACX_STATUS_0_STOPPED 0 +#define ACX_STATUS_1_SCANNING 1 +#define ACX_STATUS_2_WAIT_AUTH 2 +#define ACX_STATUS_3_AUTHENTICATED 3 +#define ACX_STATUS_4_ASSOCIATED 4 + +/* FIXME: this should be named something like struct acx_priv (typedef'd to + * acx_priv_t) */ + +/* non-firmware struct, no packing necessary */ +struct acx_device { + /* most frequent accesses first (dereferencing and cache line!) */ + + /*** Locking ***/ + /* FIXME: try to convert semaphore to more efficient mutex according + to Ingo Molnar's docs (but not before driver is in mainline or + pre-mutex Linux 2.6.10 is very outdated). */ + struct semaphore sem; + spinlock_t lock; +#if defined(PARANOID_LOCKING) /* Lock debugging */ + const char *last_sem; + const char *last_lock; + unsigned long sem_time; + unsigned long lock_time; +#endif + + /*** Linux network device ***/ + struct net_device *ndev; /* pointer to linux netdevice */ + + /*** Device statistics ***/ + struct net_device_stats stats; /* net device statistics */ +#ifdef WIRELESS_EXT + struct iw_statistics wstats; /* wireless statistics */ +#endif + /*** Power managment ***/ + struct pm_dev *pm; /* PM crap */ + + /*** Management timer ***/ + struct timer_list mgmt_timer; + + /*** Hardware identification ***/ + const char *chip_name; + u8 dev_type; + u8 chip_type; + u8 form_factor; + u8 radio_type; + u8 eeprom_version; + + /*** Config retrieved from EEPROM ***/ + char cfgopt_NVSv[8]; + u16 cfgopt_NVS_vendor_offs; + u8 cfgopt_MAC[6]; + u16 cfgopt_probe_delay; + u32 cfgopt_eof_memory; + u8 cfgopt_dot11CCAModes; + u8 cfgopt_dot11Diversity; + u8 cfgopt_dot11ShortPreambleOption; + u8 cfgopt_dot11PBCCOption; + u8 cfgopt_dot11ChannelAgility; + u8 cfgopt_dot11PhyType; + u8 cfgopt_dot11TempType; + co_antennas_t cfgopt_antennas; + co_powerlevels_t cfgopt_power_levels; + co_datarates_t cfgopt_data_rates; + co_domains_t cfgopt_domains; + co_product_id_t cfgopt_product_id; + co_manuf_t cfgopt_manufacturer; + + /*** Firmware identification ***/ + char firmware_version[FW_ID_SIZE+1]; + u32 firmware_numver; + u32 firmware_id; + const u16 *ie_len; + const u16 *ie_len_dot11; + + /*** Device state ***/ + u16 dev_state_mask; + u8 led_power; /* power LED status */ + u32 get_mask; /* mask of settings to fetch from the card */ + u32 set_mask; /* mask of settings to write to the card */ + + /* Barely used in USB case */ + u16 irq_status; + + u8 after_interrupt_jobs; /* mini job list for doing actions after an interrupt occurred */ + WORK_STRUCT after_interrupt_task; /* our task for after interrupt actions */ + + /*** scanning ***/ + u16 scan_count; /* number of times to do channel scan */ + u8 scan_mode; /* 0 == active, 1 == passive, 2 == background */ + u8 scan_rate; + u16 scan_duration; + u16 scan_probe_delay; +#if WIRELESS_EXT > 15 + struct iw_spy_data spy_data; /* FIXME: needs to be implemented! */ +#endif + + /*** Wireless network settings ***/ + /* copy of the device address (ifconfig hw ether) that we actually use + ** for 802.11; copied over from the network device's MAC address + ** (ifconfig) when it makes sense only */ + u8 dev_addr[MAX_ADDR_LEN]; + u8 bssid[ETH_ALEN]; /* the BSSID after having joined */ + u8 ap[ETH_ALEN]; /* The AP we want, FF:FF:FF:FF:FF:FF is any */ + u16 aid; /* The Association ID sent from the AP / last used AID if we're an AP */ + u16 mode; /* mode from iwconfig */ + int monitor_type; /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_PRISM */ + u16 status; /* 802.11 association status */ + u8 essid_active; /* specific ESSID active, or select any? */ + u8 essid_len; /* to avoid dozens of strlen() */ + /* INCLUDES \0 termination for easy printf - but many places + ** simply want the string data memcpy'd plus a length indicator! + ** Keep that in mind... */ + char essid[IW_ESSID_MAX_SIZE+1]; + /* essid we are going to use for association, in case of "essid 'any'" + ** and in case of hidden ESSID (use configured ESSID then) */ + char essid_for_assoc[IW_ESSID_MAX_SIZE+1]; + char nick[IW_ESSID_MAX_SIZE+1]; /* see essid! */ + u8 channel; + u8 reg_dom_id; /* reg domain setting */ + u16 reg_dom_chanmask; + u16 auth_or_assoc_retries; + u16 scan_retries; + unsigned long scan_start; /* YES, jiffies is defined as "unsigned long" */ + + /* stations known to us (if we're an ap) */ + client_t sta_list[32]; /* tab is larger than list, so that */ + client_t *sta_hash_tab[64]; /* hash collisions are not likely */ + client_t *ap_client; /* this one is our AP (STA mode only) */ + + int dup_count; + int nondup_count; + unsigned long dup_msg_expiry; + u16 last_seq_ctrl; /* duplicate packet detection */ + + /* 802.11 power save mode */ + u8 ps_wakeup_cfg; + u8 ps_listen_interval; + u8 ps_options; + u8 ps_hangover_period; + u32 ps_enhanced_transition_time; + u32 ps_beacon_rx_time; + + /*** PHY settings ***/ + u8 fallback_threshold; + u8 stepup_threshold; + u16 rate_basic; + u16 rate_oper; + u16 rate_bcast; + u16 rate_bcast100; + u8 rate_auto; /* false if "iwconfig rate N" (WITHOUT 'auto'!) */ + u8 preamble_mode; /* 0 == Long Preamble, 1 == Short, 2 == Auto */ + u8 preamble_cur; + + u8 tx_disabled; + u8 tx_level_dbm; + /* u8 tx_level_val; */ + /* u8 tx_level_auto; whether to do automatic power adjustment */ + + unsigned long recalib_time_last_success; + unsigned long recalib_time_last_attempt; + int recalib_failure_count; + int recalib_msg_ratelimit; + int retry_errors_msg_ratelimit; + + unsigned long brange_time_last_state_change; /* time the power LED was last changed */ + u8 brange_last_state; /* last state of the LED */ + u8 brange_max_quality; /* maximum quality that equates to full speed */ + + u8 sensitivity; + u8 antenna; /* antenna settings */ + u8 ed_threshold; /* energy detect threshold */ + u8 cca; /* clear channel assessment */ + + u16 rts_threshold; + u16 frag_threshold; + u32 short_retry; + u32 long_retry; + u16 msdu_lifetime; + u16 listen_interval; /* given in units of beacon interval */ + u32 beacon_interval; + + u16 capabilities; + u8 rate_supported_len; + u8 rate_supported[13]; + + /*** Encryption settings (WEP) ***/ + u32 auth_alg; /* used in transmit_authen1 */ + u8 wep_enabled; + u8 wep_restricted; + u8 wep_current_index; + wep_key_t wep_keys[DOT11_MAX_DEFAULT_WEP_KEYS]; /* the default WEP keys */ + key_struct_t wep_key_struct[10]; + + /*** Unknown ***/ + u8 dtim_interval; + + /*** Card Rx/Tx management ***/ + u16 rx_config_1; + u16 rx_config_2; + u16 memblocksize; + unsigned int tx_free; + unsigned int tx_head; /* keep as close as possible to Tx stuff below (cache line) */ + u16 phy_header_len; + +/************************************************************************* + *** PCI/USB/... must be last or else hw agnostic code breaks horribly *** + *************************************************************************/ + + /* hack to let common code compile. FIXME */ + dma_addr_t rxhostdesc_startphy; + + /*** PCI stuff ***/ +#ifdef ACX_PCI + /* pointers to tx buffers, tx host descriptors (in host memory) + ** and tx descs in device memory */ + unsigned int tx_tail; + u8 *txbuf_start; + txhostdesc_t *txhostdesc_start; + txdesc_t *txdesc_start; /* points to PCI-mapped memory */ + dma_addr_t txbuf_startphy; + dma_addr_t txhostdesc_startphy; + /* sizes of above host memory areas */ + unsigned int txbuf_area_size; + unsigned int txhostdesc_area_size; + + unsigned int txdesc_size; /* size of txdesc; ACX111 = ACX100 + 4 */ + client_t *txc[TX_CNT]; + u16 txr[TX_CNT]; + + /* same for rx */ + unsigned int rx_tail; + rxbuffer_t *rxbuf_start; + rxhostdesc_t *rxhostdesc_start; + rxdesc_t *rxdesc_start; + /* physical addresses of above host memory areas */ + dma_addr_t rxbuf_startphy; + /* dma_addr_t rxhostdesc_startphy; */ + unsigned int rxbuf_area_size; + unsigned int rxhostdesc_area_size; + + u8 need_radio_fw; + u8 irqs_active; /* whether irq sending is activated */ + + const u16 *io; /* points to ACX100 or ACX111 PCI I/O register address set */ + + struct pci_dev *pdev; + + unsigned long membase; + unsigned long membase2; + void __iomem *iobase; + void __iomem *iobase2; + /* command interface */ + u8 __iomem *cmd_area; + u8 __iomem *info_area; + + u16 irq_mask; /* interrupt types to mask out (not wanted) with many IRQs activated */ + u16 irq_mask_off; /* interrupt types to mask out (not wanted) with IRQs off */ + unsigned int irq_loops_this_jiffy; + unsigned long irq_last_jiffies; +#endif + + /*** USB stuff ***/ +#ifdef ACX_USB + struct usb_device *usbdev; + + rxbuffer_t rxtruncbuf; + + usb_tx_t *usb_tx; + usb_rx_t *usb_rx; + + int bulkinep; /* bulk-in endpoint */ + int bulkoutep; /* bulk-out endpoint */ + int rxtruncsize; +#endif + +}; + +static inline acx_device_t* +ndev2adev(struct net_device *ndev) +{ + return netdev_priv(ndev); +} + + +/* For use with ACX1xx_IE_RXCONFIG */ +/* bit description + * 13 include additional header (length etc.) *required* + * struct is defined in 'struct rxbuffer' + * is this bit acx100 only? does acx111 always put the header, + * and bit setting is irrelevant? --vda + * 10 receive frames only with SSID used in last join cmd + * 9 discard broadcast + * 8 receive packets for multicast address 1 + * 7 receive packets for multicast address 0 + * 6 discard all multicast packets + * 5 discard frames from foreign BSSID + * 4 discard frames with foreign destination MAC address + * 3 promiscuous mode (receive ALL frames, disable filter) + * 2 include FCS + * 1 include phy header + * 0 ??? + */ +#define RX_CFG1_INCLUDE_RXBUF_HDR 0x2000 /* ACX100 only */ +#define RX_CFG1_FILTER_SSID 0x0400 +#define RX_CFG1_FILTER_BCAST 0x0200 +#define RX_CFG1_RCV_MC_ADDR1 0x0100 +#define RX_CFG1_RCV_MC_ADDR0 0x0080 +#define RX_CFG1_FILTER_ALL_MULTI 0x0040 +#define RX_CFG1_FILTER_BSSID 0x0020 +#define RX_CFG1_FILTER_MAC 0x0010 +#define RX_CFG1_RCV_PROMISCUOUS 0x0008 +#define RX_CFG1_INCLUDE_FCS 0x0004 +#define RX_CFG1_INCLUDE_PHY_HDR (WANT_PHY_HDR ? 0x0002 : 0) +/* bit description + * 11 receive association requests etc. + * 10 receive authentication frames + * 9 receive beacon frames + * 8 receive contention free packets + * 7 receive control frames + * 6 receive data frames + * 5 receive broken frames + * 4 receive management frames + * 3 receive probe requests + * 2 receive probe responses + * 1 receive RTS/CTS/ACK frames + * 0 receive other + */ +#define RX_CFG2_RCV_ASSOC_REQ 0x0800 +#define RX_CFG2_RCV_AUTH_FRAMES 0x0400 +#define RX_CFG2_RCV_BEACON_FRAMES 0x0200 +#define RX_CFG2_RCV_CONTENTION_FREE 0x0100 +#define RX_CFG2_RCV_CTRL_FRAMES 0x0080 +#define RX_CFG2_RCV_DATA_FRAMES 0x0040 +#define RX_CFG2_RCV_BROKEN_FRAMES 0x0020 +#define RX_CFG2_RCV_MGMT_FRAMES 0x0010 +#define RX_CFG2_RCV_PROBE_REQ 0x0008 +#define RX_CFG2_RCV_PROBE_RESP 0x0004 +#define RX_CFG2_RCV_ACK_FRAMES 0x0002 +#define RX_CFG2_RCV_OTHER 0x0001 + +/* For use with ACX1xx_IE_FEATURE_CONFIG */ +#define FEATURE1_80MHZ_CLOCK 0x00000040L +#define FEATURE1_4X 0x00000020L +#define FEATURE1_LOW_RX 0x00000008L +#define FEATURE1_EXTRA_LOW_RX 0x00000001L + +#define FEATURE2_SNIFFER 0x00000080L +#define FEATURE2_NO_TXCRYPT 0x00000001L + +/*-- get and set mask values --*/ +#define GETSET_LED_POWER 0x00000001L +#define GETSET_STATION_ID 0x00000002L +#define SET_TEMPLATES 0x00000004L +#define SET_STA_LIST 0x00000008L +#define GETSET_TX 0x00000010L +#define GETSET_RX 0x00000020L +#define SET_RXCONFIG 0x00000040L +#define GETSET_ANTENNA 0x00000080L +#define GETSET_SENSITIVITY 0x00000100L +#define GETSET_TXPOWER 0x00000200L +#define GETSET_ED_THRESH 0x00000400L +#define GETSET_CCA 0x00000800L +#define GETSET_POWER_80211 0x00001000L +#define GETSET_RETRY 0x00002000L +#define GETSET_REG_DOMAIN 0x00004000L +#define GETSET_CHANNEL 0x00008000L +/* Used when ESSID changes etc and we need to scan for AP anew */ +#define GETSET_RESCAN 0x00010000L +#define GETSET_MODE 0x00020000L +#define GETSET_WEP 0x00040000L +#define SET_WEP_OPTIONS 0x00080000L +#define SET_MSDU_LIFETIME 0x00100000L +#define SET_RATE_FALLBACK 0x00200000L + +/* keep in sync with the above */ +#define GETSET_ALL (0 \ +/* GETSET_LED_POWER */ | 0x00000001L \ +/* GETSET_STATION_ID */ | 0x00000002L \ +/* SET_TEMPLATES */ | 0x00000004L \ +/* SET_STA_LIST */ | 0x00000008L \ +/* GETSET_TX */ | 0x00000010L \ +/* GETSET_RX */ | 0x00000020L \ +/* SET_RXCONFIG */ | 0x00000040L \ +/* GETSET_ANTENNA */ | 0x00000080L \ +/* GETSET_SENSITIVITY */| 0x00000100L \ +/* GETSET_TXPOWER */ | 0x00000200L \ +/* GETSET_ED_THRESH */ | 0x00000400L \ +/* GETSET_CCA */ | 0x00000800L \ +/* GETSET_POWER_80211 */| 0x00001000L \ +/* GETSET_RETRY */ | 0x00002000L \ +/* GETSET_REG_DOMAIN */ | 0x00004000L \ +/* GETSET_CHANNEL */ | 0x00008000L \ +/* GETSET_RESCAN */ | 0x00010000L \ +/* GETSET_MODE */ | 0x00020000L \ +/* GETSET_WEP */ | 0x00040000L \ +/* SET_WEP_OPTIONS */ | 0x00080000L \ +/* SET_MSDU_LIFETIME */ | 0x00100000L \ +/* SET_RATE_FALLBACK */ | 0x00200000L \ + ) + + +/*********************************************************************** +** Firmware loading +*/ +#include /* request_firmware() */ +#include /* struct pci_device */ + + +/*********************************************************************** +*/ +typedef struct acx100_ie_memblocksize { + u16 type; + u16 len; + u16 size; +} ACX_PACKED acx100_ie_memblocksize_t; + +typedef struct acx100_ie_queueconfig { + u16 type; + u16 len; + u32 AreaSize; + u32 RxQueueStart; + u8 QueueOptions; + u8 NumTxQueues; + u8 NumRxDesc; /* for USB only */ + u8 pad1; + u32 QueueEnd; + u32 HostQueueEnd; /* QueueEnd2 */ + u32 TxQueueStart; + u8 TxQueuePri; + u8 NumTxDesc; + u16 pad2; +} ACX_PACKED acx100_ie_queueconfig_t; + +typedef struct acx111_ie_queueconfig { + u16 type; + u16 len; + u32 tx_memory_block_address; + u32 rx_memory_block_address; + u32 rx1_queue_address; + u32 reserved1; + u32 tx1_queue_address; + u8 tx1_attributes; + u16 reserved2; + u8 reserved3; +} ACX_PACKED acx111_ie_queueconfig_t; + +typedef struct acx100_ie_memconfigoption { + u16 type; + u16 len; + u32 DMA_config; + acx_ptr pRxHostDesc; + u32 rx_mem; + u32 tx_mem; + u16 RxBlockNum; + u16 TxBlockNum; +} ACX_PACKED acx100_ie_memconfigoption_t; + +typedef struct acx111_ie_memoryconfig { + u16 type; + u16 len; + u16 no_of_stations; + u16 memory_block_size; + u8 tx_rx_memory_block_allocation; + u8 count_rx_queues; + u8 count_tx_queues; + u8 options; + u8 fragmentation; + u16 reserved1; + u8 reserved2; + + /* start of rx1 block */ + u8 rx_queue1_count_descs; + u8 rx_queue1_reserved1; + u8 rx_queue1_type; /* must be set to 7 */ + u8 rx_queue1_prio; /* must be set to 0 */ + acx_ptr rx_queue1_host_rx_start; + /* end of rx1 block */ + + /* start of tx1 block */ + u8 tx_queue1_count_descs; + u8 tx_queue1_reserved1; + u8 tx_queue1_reserved2; + u8 tx_queue1_attributes; + /* end of tx1 block */ +} ACX_PACKED acx111_ie_memoryconfig_t; + +typedef struct acx_ie_memmap { + u16 type; + u16 len; + u32 CodeStart; + u32 CodeEnd; + u32 WEPCacheStart; + u32 WEPCacheEnd; + u32 PacketTemplateStart; + u32 PacketTemplateEnd; + u32 QueueStart; + u32 QueueEnd; + u32 PoolStart; + u32 PoolEnd; +} ACX_PACKED acx_ie_memmap_t; + +typedef struct acx111_ie_feature_config { + u16 type; + u16 len; + u32 feature_options; + u32 data_flow_options; +} ACX_PACKED acx111_ie_feature_config_t; + +typedef struct acx111_ie_tx_level { + u16 type; + u16 len; + u8 level; +} ACX_PACKED acx111_ie_tx_level_t; + +#define PS_CFG_ENABLE 0x80 +#define PS_CFG_PENDING 0x40 /* status flag when entering PS */ +#define PS_CFG_WAKEUP_MODE_MASK 0x07 +#define PS_CFG_WAKEUP_BY_HOST 0x03 +#define PS_CFG_WAKEUP_EACH_ITVL 0x02 +#define PS_CFG_WAKEUP_ON_DTIM 0x01 +#define PS_CFG_WAKEUP_ALL_BEAC 0x00 + +/* Enhanced PS mode: sleep until Rx Beacon w/ the STA's AID bit set +** in the TIM; newer firmwares only(?) */ +#define PS_OPT_ENA_ENHANCED_PS 0x04 +#define PS_OPT_TX_PSPOLL 0x02 /* send PSPoll frame to fetch waiting frames from AP (on frame with matching AID) */ +#define PS_OPT_STILL_RCV_BCASTS 0x01 + +typedef struct acx100_ie_powersave { + u16 type; + u16 len; + u8 wakeup_cfg; + u8 listen_interval; /* for EACH_ITVL: wake up every "beacon units" interval */ + u8 options; + u8 hangover_period; /* remaining wake time after Tx MPDU w/ PS bit, in values of 1/1024 seconds */ + u16 enhanced_ps_transition_time; /* rem. wake time for Enh. PS */ +} ACX_PACKED acx100_ie_powersave_t; + +typedef struct acx111_ie_powersave { + u16 type; + u16 len; + u8 wakeup_cfg; + u8 listen_interval; /* for EACH_ITVL: wake up every "beacon units" interval */ + u8 options; + u8 hangover_period; /* remaining wake time after Tx MPDU w/ PS bit, in values of 1/1024 seconds */ + u32 beacon_rx_time; + u32 enhanced_ps_transition_time; /* rem. wake time for Enh. PS */ +} ACX_PACKED acx111_ie_powersave_t; + + +/*********************************************************************** +** Commands and template structures +*/ + +/* +** SCAN command structure +** +** even though acx100 scan rates match RATE100 constants, +** acx111 ones do not match! Therefore we do not use RATE100 #defines */ +#define ACX_SCAN_RATE_1 10 +#define ACX_SCAN_RATE_2 20 +#define ACX_SCAN_RATE_5 55 +#define ACX_SCAN_RATE_11 110 +#define ACX_SCAN_RATE_22 220 +#define ACX_SCAN_RATE_PBCC 0x80 /* OR with this if needed */ +#define ACX_SCAN_OPT_ACTIVE 0x00 /* a bit mask */ +#define ACX_SCAN_OPT_PASSIVE 0x01 +/* Background scan: we go into Power Save mode (by transmitting +** NULL data frame to AP with the power mgmt bit set), do the scan, +** and then exit Power Save mode. A plus is that AP buffers frames +** for us while we do background scan. Thus we avoid frame losses. +** Background scan can be active or passive, just like normal one */ +#define ACX_SCAN_OPT_BACKGROUND 0x02 +typedef struct acx100_scan { + u16 count; /* number of scans to do, 0xffff == continuous */ + u16 start_chan; + u16 flags; /* channel list mask; 0x8000 == all channels? */ + u8 max_rate; /* max. probe rate */ + u8 options; /* bit mask, see defines above */ + u16 chan_duration; + u16 max_probe_delay; +} ACX_PACKED acx100_scan_t; /* length 0xc */ + +#define ACX111_SCAN_RATE_6 0x0B +#define ACX111_SCAN_RATE_9 0x0F +#define ACX111_SCAN_RATE_12 0x0A +#define ACX111_SCAN_RATE_18 0x0E +#define ACX111_SCAN_RATE_24 0x09 +#define ACX111_SCAN_RATE_36 0x0D +#define ACX111_SCAN_RATE_48 0x08 +#define ACX111_SCAN_RATE_54 0x0C +#define ACX111_SCAN_OPT_5GHZ 0x04 /* else 2.4GHZ */ +#define ACX111_SCAN_MOD_SHORTPRE 0x01 /* you can combine SHORTPRE and PBCC */ +#define ACX111_SCAN_MOD_PBCC 0x80 +#define ACX111_SCAN_MOD_OFDM 0x40 +typedef struct acx111_scan { + u16 count; /* number of scans to do */ + u8 channel_list_select; /* 0: scan all channels, 1: from chan_list only */ + u16 reserved1; + u8 reserved2; + u8 rate; /* rate for probe requests (if active scan) */ + u8 options; /* bit mask, see defines above */ + u16 chan_duration; /* min time to wait for reply on one channel (in TU) */ + /* (active scan only) (802.11 section 11.1.3.2.2) */ + u16 max_probe_delay; /* max time to wait for reply on one channel (active scan) */ + /* time to listen on a channel (passive scan) */ + u8 modulation; + u8 channel_list[26]; /* bits 7:0 first byte: channels 8:1 */ + /* bits 7:0 second byte: channels 16:9 */ + /* 26 bytes is enough to cover 802.11a */ +} ACX_PACKED acx111_scan_t; + + +/* +** Radio calibration command structure +*/ +typedef struct acx111_cmd_radiocalib { +/* 0x80000000 == automatic calibration by firmware, according to interval; + * bits 0..3: select calibration methods to go through: + * calib based on DC, AfeDC, Tx mismatch, Tx equilization */ + u32 methods; + u32 interval; +} ACX_PACKED acx111_cmd_radiocalib_t; + + +/* +** Packet template structures +** +** Packet templates store contents of Beacon, Probe response, Probe request, +** Null data frame, and TIM data frame. Firmware automatically transmits +** contents of template at appropriate time: +** - Beacon: when configured as AP or Ad-hoc +** - Probe response: when configured as AP or Ad-hoc, whenever +** a Probe request frame is received +** - Probe request: when host issues SCAN command (active) +** - Null data frame: when entering 802.11 power save mode +** - TIM data: at the end of Beacon frames (if no TIM template +** is configured, then transmits default TIM) +** NB: +** - size field must be set to size of actual template +** (NOT sizeof(struct) - templates are variable in length), +** size field is not itself counted. +** - members flagged with an asterisk must be initialized with host, +** rest must be zero filled. +** - variable length fields shown only in comments */ +typedef struct acx_template_tim { + u16 size; + u8 tim_eid; /* 00 1 TIM IE ID * */ + u8 len; /* 01 1 Length * */ + u8 dtim_cnt; /* 02 1 DTIM Count */ + u8 dtim_period; /* 03 1 DTIM Period */ + u8 bitmap_ctrl; /* 04 1 Bitmap Control * (except bit0) */ + /* 05 n Partial Virtual Bitmap * */ + u8 variable[0x100 - 1-1-1-1-1]; +} ACX_PACKED acx_template_tim_t; + +typedef struct acx_template_probereq { + u16 size; + u16 fc; /* 00 2 fc * */ + u16 dur; /* 02 2 Duration */ + u8 da[6]; /* 04 6 Destination Address * */ + u8 sa[6]; /* 0A 6 Source Address * */ + u8 bssid[6]; /* 10 6 BSSID * */ + u16 seq; /* 16 2 Sequence Control */ + /* 18 n SSID * */ + /* nn n Supported Rates * */ + u8 variable[0x44 - 2-2-6-6-6-2]; +} ACX_PACKED acx_template_probereq_t; + +typedef struct acx_template_proberesp { + u16 size; + u16 fc; /* 00 2 fc * (bits [15:12] and [10:8] per 802.11 section 7.1.3.1) */ + u16 dur; /* 02 2 Duration */ + u8 da[6]; /* 04 6 Destination Address */ + u8 sa[6]; /* 0A 6 Source Address */ + u8 bssid[6]; /* 10 6 BSSID */ + u16 seq; /* 16 2 Sequence Control */ + u8 timestamp[8];/* 18 8 Timestamp */ + u16 beacon_interval; /* 20 2 Beacon Interval * */ + u16 cap; /* 22 2 Capability Information * */ + /* 24 n SSID * */ + /* nn n Supported Rates * */ + /* nn 1 DS Parameter Set * */ + u8 variable[0x54 - 2-2-6-6-6-2-8-2-2]; +} ACX_PACKED acx_template_proberesp_t; +#define acx_template_beacon_t acx_template_proberesp_t +#define acx_template_beacon acx_template_proberesp + +typedef struct acx_template_nullframe { + u16 size; + struct wlan_hdr_a3 hdr; +} ACX_PACKED acx_template_nullframe_t; + + +/* +** JOIN command structure +** +** as opposed to acx100, acx111 dtim interval is AFTER rates_basic111. +** NOTE: took me about an hour to get !@#$%^& packing right --> struct packing is eeeeevil... */ +typedef struct acx_joinbss { + u8 bssid[ETH_ALEN]; + u16 beacon_interval; + union { + struct { + u8 dtim_interval; + u8 rates_basic; + u8 rates_supported; + } ACX_PACKED acx100; + struct { + u16 rates_basic; + u8 dtim_interval; + } ACX_PACKED acx111; + } ACX_PACKED u; + u8 genfrm_txrate; /* generated frame (bcn, proberesp, RTS, PSpoll) tx rate */ + u8 genfrm_mod_pre; /* generated frame modulation/preamble: + ** bit7: PBCC, bit6: OFDM (else CCK/DQPSK/DBPSK) + ** bit5: short pre */ + u8 macmode; /* BSS Type, must be one of ACX_MODE_xxx */ + u8 channel; + u8 essid_len; + char essid[IW_ESSID_MAX_SIZE]; +} ACX_PACKED acx_joinbss_t; + +#define JOINBSS_RATES_1 0x01 +#define JOINBSS_RATES_2 0x02 +#define JOINBSS_RATES_5 0x04 +#define JOINBSS_RATES_11 0x08 +#define JOINBSS_RATES_22 0x10 + +/* Looks like missing bits are used to indicate 11g rates! +** (it follows from the fact that constants below match 1:1 to RATE111_nn) +** This was actually seen! Look at that Assoc Request sent by acx111, +** it _does_ contain 11g rates in basic set: +01:30:20.070772 Beacon (xxx) [1.0* 2.0* 5.5* 11.0* 6.0* 9.0* 12.0* 18.0* 24.0* 36.0* 48.0* 54.0* Mbit] ESS CH: 1 +01:30:20.074425 Authentication (Open System)-1: Succesful +01:30:20.076539 Authentication (Open System)-2: +01:30:20.076620 Acknowledgment +01:30:20.088546 Assoc Request (xxx) [1.0* 2.0* 5.5* 6.0* 9.0* 11.0* 12.0* 18.0* 24.0* 36.0* 48.0* 54.0* Mbit] +01:30:20.122413 Assoc Response AID(1) :: Succesful +01:30:20.122679 Acknowledgment +01:30:20.173204 Beacon (xxx) [1.0* 2.0* 5.5* 11.0* 6.0* 9.0* 12.0* 18.0* 24.0* 36.0* 48.0* 54.0* Mbit] ESS CH: 1 +*/ +#define JOINBSS_RATES_BASIC111_1 0x0001 +#define JOINBSS_RATES_BASIC111_2 0x0002 +#define JOINBSS_RATES_BASIC111_5 0x0004 +#define JOINBSS_RATES_BASIC111_11 0x0020 +#define JOINBSS_RATES_BASIC111_22 0x0100 + + +/*********************************************************************** +*/ +typedef struct mem_read_write { + u16 addr; + u16 type; /* 0x0 int. RAM / 0xffff MAC reg. / 0x81 PHY RAM / 0x82 PHY reg.; or maybe it's actually 0x30 for MAC? Better verify it by writing and reading back and checking whether the value holds! */ + u32 len; + u32 data; +} ACX_PACKED mem_read_write_t; + +typedef struct firmware_image { + u32 chksum; + u32 size; + u8 data[1]; /* the byte array of the actual firmware... */ +} ACX_PACKED firmware_image_t; + +typedef struct acx_cmd_radioinit { + u32 offset; + u32 len; +} ACX_PACKED acx_cmd_radioinit_t; + +typedef struct acx100_ie_wep_options { + u16 type; + u16 len; + u16 NumKeys; /* max # of keys */ + u8 WEPOption; /* 0 == decrypt default key only, 1 == override decrypt */ + u8 Pad; /* used only for acx111 */ +} ACX_PACKED acx100_ie_wep_options_t; + +typedef struct ie_dot11WEPDefaultKey { + u16 type; + u16 len; + u8 action; + u8 keySize; + u8 defaultKeyNum; + u8 key[29]; /* check this! was Key[19] */ +} ACX_PACKED ie_dot11WEPDefaultKey_t; + +typedef struct acx111WEPDefaultKey { + u8 MacAddr[ETH_ALEN]; + u16 action; /* NOTE: this is a u16, NOT a u8!! */ + u16 reserved; + u8 keySize; + u8 type; + u8 index; + u8 defaultKeyNum; + u8 counter[6]; + u8 key[32]; /* up to 32 bytes (for TKIP!) */ +} ACX_PACKED acx111WEPDefaultKey_t; + +typedef struct ie_dot11WEPDefaultKeyID { + u16 type; + u16 len; + u8 KeyID; +} ACX_PACKED ie_dot11WEPDefaultKeyID_t; + +typedef struct acx100_cmd_wep_mgmt { + u8 MacAddr[ETH_ALEN]; + u16 Action; + u16 KeySize; + u8 Key[29]; /* 29*8 == 232bits == WEP256 */ +} ACX_PACKED acx100_cmd_wep_mgmt_t; + +typedef struct acx_ie_generic { + u16 type; + u16 len; + union { + /* Association ID IE: just a 16bit value: */ + u16 aid; + /* generic member for quick implementation of commands */ + u8 bytes[32]; + } ACX_PACKED m; +} ACX_PACKED acx_ie_generic_t; + +/*********************************************************************** +*/ +#define CHECK_SIZEOF(type,size) { \ + extern void BUG_bad_size_for_##type(void); \ + if (sizeof(type)!=(size)) BUG_bad_size_for_##type(); \ +} + +static inline void +acx_struct_size_check(void) +{ + CHECK_SIZEOF(txdesc_t, 0x30); + CHECK_SIZEOF(acx100_ie_memconfigoption_t, 24); + CHECK_SIZEOF(acx100_ie_queueconfig_t, 0x20); + CHECK_SIZEOF(acx_joinbss_t, 0x30); + /* IEs need 4 bytes for (type,len) tuple */ + CHECK_SIZEOF(acx111_ie_configoption_t, ACX111_IE_CONFIG_OPTIONS_LEN + 4); +} + + +/*********************************************************************** +** Global data +*/ +extern const u8 acx_bitpos2ratebyte[]; +extern const u8 acx_bitpos2rate100[]; + +extern const u8 acx_reg_domain_ids[]; +extern const char * const acx_reg_domain_strings[]; +enum { + acx_reg_domain_ids_len = 8 +}; + +extern const struct iw_handler_def acx_ioctl_handler_def; --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/wlan_mgmt.h +++ linux-2.6.28/ubuntu/misc/wireless/acx/wlan_mgmt.h @@ -0,0 +1,582 @@ +/*********************************************************************** +** Copyright (C) 2003 ACX100 Open Source Project +** +** The contents of this file are subject to the Mozilla Public +** License Version 1.1 (the "License"); you may not use this file +** except in compliance with the License. You may obtain a copy of +** the License at http://www.mozilla.org/MPL/ +** +** Software distributed under the License is distributed on an "AS +** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +** implied. See the License for the specific language governing +** rights and limitations under the License. +** +** Alternatively, the contents of this file may be used under the +** terms of the GNU Public License version 2 (the "GPL"), in which +** case the provisions of the GPL are applicable instead of the +** above. If you wish to allow the use of your version of this file +** only under the terms of the GPL and not to allow others to use +** your version of this file under the MPL, indicate your decision +** by deleting the provisions above and replace them with the notice +** and other provisions required by the GPL. If you do not delete +** the provisions above, a recipient may use your version of this +** file under either the MPL or the GPL. +** --------------------------------------------------------------------- +** Inquiries regarding the ACX100 Open Source Project can be +** made directly to: +** +** acx100-users@lists.sf.net +** http://acx100.sf.net +** --------------------------------------------------------------------- +*/ + +/*********************************************************************** +** This code is based on elements which are +** Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +** info@linux-wlan.com +** http://www.linux-wlan.com +*/ + +/*********************************************************************** +** Constants +*/ + +/*-- Information Element IDs --------------------*/ +#define WLAN_EID_SSID 0 +#define WLAN_EID_SUPP_RATES 1 +#define WLAN_EID_FH_PARMS 2 +#define WLAN_EID_DS_PARMS 3 +#define WLAN_EID_CF_PARMS 4 +#define WLAN_EID_TIM 5 +#define WLAN_EID_IBSS_PARMS 6 +#define WLAN_EID_COUNTRY 7 /* 802.11d */ +#define WLAN_EID_FH_HOP_PARMS 8 /* 802.11d */ +#define WLAN_EID_FH_TABLE 9 /* 802.11d */ +#define WLAN_EID_REQUEST 10 /* 802.11d */ +/*-- values 11-15 reserved --*/ +#define WLAN_EID_CHALLENGE 16 +/*-- values 17-31 reserved for challenge text extension --*/ +#define WLAN_EID_PWR_CONSTRAINT 32 /* 11h PowerConstraint */ +#define WLAN_EID_ERP_INFO 42 /* was seen from WRT54GS with OpenWrt */ +#define WLAN_EID_NONERP 47 /* was seen from WRT54GS with OpenWrt */ +#define WLAN_EID_RSN 48 +#define WLAN_EID_EXT_RATES 50 +#define WLAN_EID_UNKNOWN128 128 +#define WLAN_EID_UNKNOWN133 133 +#define WLAN_EID_GENERIC 221 /* was seen from WRT54GS with OpenWrt */ +#define WLAN_EID_UNKNOWN223 223 + +#if 0 +#define WLAN_EID_PWR_CAP 33 /* 11h PowerCapability */ +#define WLAN_EID_TPC_REQUEST 34 /* 11h TPC Request */ +#define WLAN_EID_TPC_REPORT 35 /* 11h TPC Report */ +#define WLAN_EID_SUPP_CHANNELS 36 /* 11h Supported Channels */ +#define WLAN_EID_CHANNEL_SWITCH 37 /* 11h ChannelSwitch */ +#define WLAN_EID_MEASURE_REQUEST 38 /* 11h MeasurementRequest */ +#define WLAN_EID_MEASURE_REPORT 39 /* 11h MeasurementReport */ +#define WLAN_EID_QUIET_ID 40 /* 11h Quiet */ +#define WLAN_EID_IBSS_DFS_ID 41 /* 11h IBSS_DFS */ +#endif + +/*-- Reason Codes -------------------------------*/ +#define WLAN_MGMT_REASON_RSVD 0 +#define WLAN_MGMT_REASON_UNSPEC 1 +#define WLAN_MGMT_REASON_PRIOR_AUTH_INVALID 2 +#define WLAN_MGMT_REASON_DEAUTH_LEAVING 3 +#define WLAN_MGMT_REASON_DISASSOC_INACTIVE 4 +#define WLAN_MGMT_REASON_DISASSOC_AP_BUSY 5 +#define WLAN_MGMT_REASON_CLASS2_NONAUTH 6 +#define WLAN_MGMT_REASON_CLASS3_NONASSOC 7 +#define WLAN_MGMT_REASON_DISASSOC_STA_HASLEFT 8 +#define WLAN_MGMT_REASON_CANT_ASSOC_NONAUTH 9 + +/*-- Status Codes -------------------------------*/ +#define WLAN_MGMT_STATUS_SUCCESS 0 +#define WLAN_MGMT_STATUS_UNSPEC_FAILURE 1 +#define WLAN_MGMT_STATUS_CAPS_UNSUPPORTED 10 +#define WLAN_MGMT_STATUS_REASSOC_NO_ASSOC 11 +#define WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC 12 +#define WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG 13 +#define WLAN_MGMT_STATUS_RX_AUTH_NOSEQ 14 +#define WLAN_MGMT_STATUS_CHALLENGE_FAIL 15 +#define WLAN_MGMT_STATUS_AUTH_TIMEOUT 16 +#define WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY 17 +#define WLAN_MGMT_STATUS_ASSOC_DENIED_RATES 18 +/* p80211b additions */ +#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOSHORT 19 +#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOPBCC 20 +#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOAGILITY 21 + +/*-- Auth Algorithm Field ---------------------------*/ +#define WLAN_AUTH_ALG_OPENSYSTEM 0 +#define WLAN_AUTH_ALG_SHAREDKEY 1 + +/*-- Management Frame Field Offsets -------------*/ +/* Note: Not all fields are listed because of variable lengths */ +/* Note: These offsets are from the start of the frame data */ + +#define WLAN_BEACON_OFF_TS 0 +#define WLAN_BEACON_OFF_BCN_INT 8 +#define WLAN_BEACON_OFF_CAPINFO 10 +#define WLAN_BEACON_OFF_SSID 12 + +#define WLAN_DISASSOC_OFF_REASON 0 + +#define WLAN_ASSOCREQ_OFF_CAP_INFO 0 +#define WLAN_ASSOCREQ_OFF_LISTEN_INT 2 +#define WLAN_ASSOCREQ_OFF_SSID 4 + +#define WLAN_ASSOCRESP_OFF_CAP_INFO 0 +#define WLAN_ASSOCRESP_OFF_STATUS 2 +#define WLAN_ASSOCRESP_OFF_AID 4 +#define WLAN_ASSOCRESP_OFF_SUPP_RATES 6 + +#define WLAN_REASSOCREQ_OFF_CAP_INFO 0 +#define WLAN_REASSOCREQ_OFF_LISTEN_INT 2 +#define WLAN_REASSOCREQ_OFF_CURR_AP 4 +#define WLAN_REASSOCREQ_OFF_SSID 10 + +#define WLAN_REASSOCRESP_OFF_CAP_INFO 0 +#define WLAN_REASSOCRESP_OFF_STATUS 2 +#define WLAN_REASSOCRESP_OFF_AID 4 +#define WLAN_REASSOCRESP_OFF_SUPP_RATES 6 + +#define WLAN_PROBEREQ_OFF_SSID 0 + +#define WLAN_PROBERESP_OFF_TS 0 +#define WLAN_PROBERESP_OFF_BCN_INT 8 +#define WLAN_PROBERESP_OFF_CAP_INFO 10 +#define WLAN_PROBERESP_OFF_SSID 12 + +#define WLAN_AUTHEN_OFF_AUTH_ALG 0 +#define WLAN_AUTHEN_OFF_AUTH_SEQ 2 +#define WLAN_AUTHEN_OFF_STATUS 4 +#define WLAN_AUTHEN_OFF_CHALLENGE 6 + +#define WLAN_DEAUTHEN_OFF_REASON 0 + +enum { +IEEE16(WF_MGMT_CAP_ESS, 0x0001) +IEEE16(WF_MGMT_CAP_IBSS, 0x0002) +/* In (re)assoc request frames by STA: +** Pollable=0, PollReq=0: STA is not CF-Pollable +** 0 1: STA is CF-Pollable, not requesting to be placed on the CF-Polling list +** 1 0: STA is CF-Pollable, requesting to be placed on the CF-Polling list +** 1 1: STA is CF-Pollable, requesting never to be polled +** In beacon, proberesp, (re)assoc resp frames by AP: +** 0 0: No point coordinator at AP +** 0 1: Point coordinator at AP for delivery only (no polling) +** 1 0: Point coordinator at AP for delivery and polling +** 1 1: Reserved */ +IEEE16(WF_MGMT_CAP_CFPOLLABLE, 0x0004) +IEEE16(WF_MGMT_CAP_CFPOLLREQ, 0x0008) +/* 1=non-WEP data frames are disallowed */ +IEEE16(WF_MGMT_CAP_PRIVACY, 0x0010) +/* In beacon, proberesp, (re)assocresp by AP/AdHoc: +** 1=use of shortpre is allowed ("I can receive shortpre") */ +IEEE16(WF_MGMT_CAP_SHORT, 0x0020) +IEEE16(WF_MGMT_CAP_PBCC, 0x0040) +IEEE16(WF_MGMT_CAP_AGILITY, 0x0080) +/* In (re)assoc request frames by STA: +** 1=short slot time implemented and enabled +** NB: AP shall use long slot time beginning at the next Beacon after assoc +** of STA with this bit set to 0 +** In beacon, proberesp, (re)assoc resp frames by AP: +** currently used slot time value: 0/1 - long/short */ +IEEE16(WF_MGMT_CAP_SHORTSLOT, 0x0400) +/* In (re)assoc request frames by STA: 1=CCK-OFDM is implemented and enabled +** In beacon, proberesp, (re)assoc resp frames by AP/AdHoc: +** 1=CCK-OFDM is allowed */ +IEEE16(WF_MGMT_CAP_CCKOFDM, 0x2000) +}; + + +/*********************************************************************** +** Types +*/ + +/* Information Element types */ + +/* prototype structure, all IEs start with these members */ +typedef struct wlan_ie { + u8 eid; + u8 len; +} WLAN_PACKED wlan_ie_t; + +/*-- Service Set Identity (SSID) -----------------*/ +typedef struct wlan_ie_ssid { + u8 eid; + u8 len; + u8 ssid[1]; /* may be zero */ +} WLAN_PACKED wlan_ie_ssid_t; + +/*-- Supported Rates -----------------------------*/ +typedef struct wlan_ie_supp_rates { + u8 eid; + u8 len; + u8 rates[1]; /* had better be at LEAST one! */ +} WLAN_PACKED wlan_ie_supp_rates_t; + +/*-- FH Parameter Set ----------------------------*/ +typedef struct wlan_ie_fh_parms { + u8 eid; + u8 len; + u16 dwell; + u8 hopset; + u8 hoppattern; + u8 hopindex; +} WLAN_PACKED wlan_ie_fh_parms_t; + +/*-- DS Parameter Set ----------------------------*/ +typedef struct wlan_ie_ds_parms { + u8 eid; + u8 len; + u8 curr_ch; +} WLAN_PACKED wlan_ie_ds_parms_t; + +/*-- CF Parameter Set ----------------------------*/ +typedef struct wlan_ie_cf_parms { + u8 eid; + u8 len; + u8 cfp_cnt; + u8 cfp_period; + u16 cfp_maxdur; + u16 cfp_durremaining; +} WLAN_PACKED wlan_ie_cf_parms_t; + +/*-- TIM ------------------------------------------*/ +typedef struct wlan_ie_tim { + u8 eid; + u8 len; + u8 dtim_cnt; + u8 dtim_period; + u8 bitmap_ctl; + u8 virt_bm[1]; +} WLAN_PACKED wlan_ie_tim_t; + +/*-- IBSS Parameter Set ---------------------------*/ +typedef struct wlan_ie_ibss_parms { + u8 eid; + u8 len; + u16 atim_win; +} WLAN_PACKED wlan_ie_ibss_parms_t; + +/*-- Challenge Text ------------------------------*/ +typedef struct wlan_ie_challenge { + u8 eid; + u8 len; + u8 challenge[1]; +} WLAN_PACKED wlan_ie_challenge_t; + +/*-- ERP (42) -------------------------------------*/ +typedef struct wlan_ie_erp { + u8 eid; + u8 len; + /* bit 0:Non ERP present + ** 1:Use Protection + ** 2:Barker Preamble mode + ** 3-7:reserved */ + u8 erp; +} WLAN_PACKED wlan_ie_erp_t; + +/* Types for parsing mgmt frames */ + +/* prototype structure, all mgmt frame types will start with these members */ +typedef struct wlan_fr_mgmt { + u16 type; + u16 len; /* DOES NOT include FCS */ + wlan_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + /*-- fixed fields -----------*/ + /*-- info elements ----------*/ +} WLAN_PACKED wlan_fr_mgmt_t; + +/*-- Beacon ---------------------------------------*/ +typedef struct wlan_fr_beacon { + u16 type; + u16 len; + wlan_hdr_t *hdr; + /*-- fixed fields -----------*/ + u64 *ts; + u16 *bcn_int; + u16 *cap_info; + /*-- info elements ----------*/ + wlan_ie_ssid_t *ssid; + wlan_ie_supp_rates_t *supp_rates; + wlan_ie_supp_rates_t *ext_rates; + wlan_ie_fh_parms_t *fh_parms; + wlan_ie_ds_parms_t *ds_parms; + wlan_ie_cf_parms_t *cf_parms; + wlan_ie_ibss_parms_t *ibss_parms; + wlan_ie_tim_t *tim; /* in beacon only, not proberesp */ + wlan_ie_erp_t *erp; /* in beacon only, not proberesp */ +} wlan_fr_beacon_t; +#define wlan_fr_proberesp wlan_fr_beacon +#define wlan_fr_proberesp_t wlan_fr_beacon_t + +/*-- IBSS ATIM ------------------------------------*/ +typedef struct wlan_fr_ibssatim { + u16 type; + u16 len; + wlan_hdr_t *hdr; + /*-- fixed fields -----------*/ + /*-- info elements ----------*/ + /* this frame type has a null body */ +} wlan_fr_ibssatim_t; + +/*-- Disassociation -------------------------------*/ +typedef struct wlan_fr_disassoc { + u16 type; + u16 len; + wlan_hdr_t *hdr; + /*-- fixed fields -----------*/ + u16 *reason; + /*-- info elements ----------*/ +} wlan_fr_disassoc_t; + +/*-- Association Request --------------------------*/ +typedef struct wlan_fr_assocreq { + u16 type; + u16 len; + wlan_hdr_t *hdr; + /*-- fixed fields -----------*/ + u16 *cap_info; + u16 *listen_int; + /*-- info elements ----------*/ + wlan_ie_ssid_t *ssid; + wlan_ie_supp_rates_t *supp_rates; + wlan_ie_supp_rates_t *ext_rates; +} wlan_fr_assocreq_t; + +/*-- Association Response -------------------------*/ +typedef struct wlan_fr_assocresp { + u16 type; + u16 len; + wlan_hdr_t *hdr; + /*-- fixed fields -----------*/ + u16 *cap_info; + u16 *status; + u16 *aid; + /*-- info elements ----------*/ + wlan_ie_supp_rates_t *supp_rates; + wlan_ie_supp_rates_t *ext_rates; +} wlan_fr_assocresp_t; + +/*-- Reassociation Request ------------------------*/ +typedef struct wlan_fr_reassocreq { + u16 type; + u16 len; + wlan_hdr_t *hdr; + /*-- fixed fields -----------*/ + u16 *cap_info; + u16 *listen_int; + u8 *curr_ap; + /*-- info elements ----------*/ + wlan_ie_ssid_t *ssid; + wlan_ie_supp_rates_t *supp_rates; + wlan_ie_supp_rates_t *ext_rates; +} wlan_fr_reassocreq_t; + +/*-- Reassociation Response -----------------------*/ +typedef struct wlan_fr_reassocresp { + u16 type; + u16 len; + wlan_hdr_t *hdr; + /*-- fixed fields -----------*/ + u16 *cap_info; + u16 *status; + u16 *aid; + /*-- info elements ----------*/ + wlan_ie_supp_rates_t *supp_rates; + wlan_ie_supp_rates_t *ext_rates; +} wlan_fr_reassocresp_t; + +/*-- Probe Request --------------------------------*/ +typedef struct wlan_fr_probereq { + u16 type; + u16 len; + wlan_hdr_t *hdr; + /*-- fixed fields -----------*/ + /*-- info elements ----------*/ + wlan_ie_ssid_t *ssid; + wlan_ie_supp_rates_t *supp_rates; + wlan_ie_supp_rates_t *ext_rates; +} wlan_fr_probereq_t; + +/*-- Authentication -------------------------------*/ +typedef struct wlan_fr_authen { + u16 type; + u16 len; + wlan_hdr_t *hdr; + /*-- fixed fields -----------*/ + u16 *auth_alg; + u16 *auth_seq; + u16 *status; + /*-- info elements ----------*/ + wlan_ie_challenge_t *challenge; +} wlan_fr_authen_t; + +/*-- Deauthenication -----------------------------*/ +typedef struct wlan_fr_deauthen { + u16 type; + u16 len; + wlan_hdr_t *hdr; + /*-- fixed fields -----------*/ + u16 *reason; + /*-- info elements ----------*/ +} wlan_fr_deauthen_t; + +/* Types for building mgmt frames */ + +/* Warning. Several types used in below structs are +** in fact variable length. Use structs with such fields with caution */ +typedef struct auth_frame_body { + u16 auth_alg; + u16 auth_seq; + u16 status; + wlan_ie_challenge_t challenge; +} WLAN_PACKED auth_frame_body_t; + +typedef struct assocresp_frame_body { + u16 cap_info; + u16 status; + u16 aid; + wlan_ie_supp_rates_t rates; +} WLAN_PACKED assocresp_frame_body_t; + +typedef struct reassocreq_frame_body { + u16 cap_info; + u16 listen_int; + u8 current_ap[ETH_ALEN]; + wlan_ie_ssid_t ssid; +/* access to this one is disabled since ssid_t is variable length: */ + /* wlan_ie_supp_rates_t rates; */ +} WLAN_PACKED reassocreq_frame_body_t; + +typedef struct reassocresp_frame_body { + u16 cap_info; + u16 status; + u16 aid; + wlan_ie_supp_rates_t rates; +} WLAN_PACKED reassocresp_frame_body_t; + +typedef struct deauthen_frame_body { + u16 reason; +} WLAN_PACKED deauthen_frame_body_t; + +typedef struct disassoc_frame_body { + u16 reason; +} WLAN_PACKED disassoc_frame_body_t; + +typedef struct probereq_frame_body { + wlan_ie_ssid_t ssid; + wlan_ie_supp_rates_t rates; +} WLAN_PACKED probereq_frame_body_t; + +typedef struct proberesp_frame_body { + u8 timestamp[8]; + u16 beacon_int; + u16 cap_info; + wlan_ie_ssid_t ssid; +/* access to these is disabled since ssid_t is variable length: */ + /* wlan_ie_supp_rates_t rates; */ + /* fhps_t fhps; */ + /* dsps_t dsps; */ + /* cfps_t cfps; */ +} WLAN_PACKED proberesp_frame_body_t; + + +/*********************************************************************** +** Functions +*/ + +/* Helpers for parsing mgmt frames */ +void wlan_mgmt_decode_ibssatim(wlan_fr_ibssatim_t *f); +void wlan_mgmt_decode_assocreq(wlan_fr_assocreq_t *f); +void wlan_mgmt_decode_assocresp(wlan_fr_assocresp_t *f); +void wlan_mgmt_decode_authen(wlan_fr_authen_t *f); +void wlan_mgmt_decode_beacon(wlan_fr_beacon_t *f); +void wlan_mgmt_decode_deauthen(wlan_fr_deauthen_t *f); +void wlan_mgmt_decode_disassoc(wlan_fr_disassoc_t *f); +void wlan_mgmt_decode_probereq(wlan_fr_probereq_t *f); +void wlan_mgmt_decode_proberesp(wlan_fr_proberesp_t *f); +void wlan_mgmt_decode_reassocreq(wlan_fr_reassocreq_t *f); +void wlan_mgmt_decode_reassocresp(wlan_fr_reassocresp_t *f); + +/* Helpers for building mgmt frames */ +static inline u8* +wlan_fill_ie_ssid(u8 *p, int len, const char *ssid) +{ + struct wlan_ie_ssid *ie = (void*)p; + ie->eid = WLAN_EID_SSID; + ie->len = len; + memcpy(ie->ssid, ssid, len); + return p + len + 2; +} +/* This controls whether we create 802.11g 'ext supported rates' IEs +** or just create overlong 'supported rates' IEs instead +** (non-11g compliant) */ +#define WE_OBEY_802_11G 1 +static inline u8* +wlan_fill_ie_rates(u8 *p, int len, const u8 *rates) +{ + struct wlan_ie_supp_rates *ie = (void*)p; +#if WE_OBEY_802_11G + if (len > 8 ) len = 8; +#endif + /* supported rates (1 to 8 octets) */ + ie->eid = WLAN_EID_SUPP_RATES; + ie->len = len; + memcpy(ie->rates, rates, len); + return p + len + 2; +} +/* This one wouldn't create an IE at all if not needed */ +static inline u8* +wlan_fill_ie_rates_ext(u8 *p, int len, const u8 *rates) +{ + struct wlan_ie_supp_rates *ie = (void*)p; +#if !WE_OBEY_802_11G + return p; +#endif + len -= 8; + if (len <= 0) return p; + /* ext supported rates */ + ie->eid = WLAN_EID_EXT_RATES; + ie->len = len; + memcpy(ie->rates, rates+8, len); + return p + len + 2; +} +static inline u8* +wlan_fill_ie_ds_parms(u8 *p, int channel) +{ + struct wlan_ie_ds_parms *ie = (void*)p; + ie->eid = WLAN_EID_DS_PARMS; + ie->len = 1; + ie->curr_ch = channel; + return p + sizeof(*ie); +} +static inline u8* +wlan_fill_ie_ibss_parms(u8 *p, int atim_win) +{ + struct wlan_ie_ibss_parms *ie = (void*)p; + ie->eid = WLAN_EID_IBSS_PARMS; + ie->len = 2; + ie->atim_win = atim_win; + return p + sizeof(*ie); +} +static inline u8* +wlan_fill_ie_tim(u8 *p, int rem, int period, int bcast, + int ofs, int len, const u8 *vbm) +{ + struct wlan_ie_tim *ie = (void*)p; + ie->eid = WLAN_EID_TIM; + ie->len = len + 3; + ie->dtim_cnt = rem; + ie->dtim_period = period; + ie->bitmap_ctl = ofs | (bcast!=0); + if (vbm) + memcpy(ie->virt_bm, vbm, len); /* min 1 byte */ + else + ie->virt_bm[0] = 0; + return p + len + 3 + 2; +} --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/acx.h +++ linux-2.6.28/ubuntu/misc/wireless/acx/acx.h @@ -0,0 +1,6 @@ +#include "acx_config.h" +#include "wlan_compat.h" +#include "wlan_hdr.h" +#include "wlan_mgmt.h" +#include "acx_struct.h" +#include "acx_func.h" --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/wlan_compat.h +++ linux-2.6.28/ubuntu/misc/wireless/acx/wlan_compat.h @@ -0,0 +1,264 @@ +/*********************************************************************** +** Copyright (C) 2003 ACX100 Open Source Project +** +** The contents of this file are subject to the Mozilla Public +** License Version 1.1 (the "License"); you may not use this file +** except in compliance with the License. You may obtain a copy of +** the License at http://www.mozilla.org/MPL/ +** +** Software distributed under the License is distributed on an "AS +** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +** implied. See the License for the specific language governing +** rights and limitations under the License. +** +** Alternatively, the contents of this file may be used under the +** terms of the GNU Public License version 2 (the "GPL"), in which +** case the provisions of the GPL are applicable instead of the +** above. If you wish to allow the use of your version of this file +** only under the terms of the GPL and not to allow others to use +** your version of this file under the MPL, indicate your decision +** by deleting the provisions above and replace them with the notice +** and other provisions required by the GPL. If you do not delete +** the provisions above, a recipient may use your version of this +** file under either the MPL or the GPL. +** --------------------------------------------------------------------- +** Inquiries regarding the ACX100 Open Source Project can be +** made directly to: +** +** acx100-users@lists.sf.net +** http://acx100.sf.net +** --------------------------------------------------------------------- +*/ + +/*********************************************************************** +** This code is based on elements which are +** Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +** info@linux-wlan.com +** http://www.linux-wlan.com +*/ + +/*=============================================================*/ +/*------ Establish Platform Identity --------------------------*/ +/*=============================================================*/ +/* Key macros: */ +/* WLAN_CPU_FAMILY */ +#define WLAN_Ix86 1 +#define WLAN_PPC 2 +#define WLAN_Ix96 3 +#define WLAN_ARM 4 +#define WLAN_ALPHA 5 +#define WLAN_MIPS 6 +#define WLAN_HPPA 7 +#define WLAN_SPARC 8 +#define WLAN_SH 9 +#define WLAN_x86_64 10 +#define WLAN_IA64 11 +/* WLAN_CPU_CORE */ +#define WLAN_I386CORE 1 +#define WLAN_PPCCORE 2 +#define WLAN_I296 3 +#define WLAN_ARMCORE 4 +#define WLAN_ALPHACORE 5 +#define WLAN_MIPSCORE 6 +#define WLAN_HPPACORE 7 +/* WLAN_CPU_PART */ +#define WLAN_I386PART 1 +#define WLAN_MPC860 2 +#define WLAN_MPC823 3 +#define WLAN_I296SA 4 +#define WLAN_PPCPART 5 +#define WLAN_ARMPART 6 +#define WLAN_ALPHAPART 7 +#define WLAN_MIPSPART 8 +#define WLAN_HPPAPART 9 +/* WLAN_SYSARCH */ +#define WLAN_PCAT 1 +#define WLAN_MBX 2 +#define WLAN_RPX 3 +#define WLAN_LWARCH 4 +#define WLAN_PMAC 5 +#define WLAN_SKIFF 6 +#define WLAN_BITSY 7 +#define WLAN_ALPHAARCH 7 +#define WLAN_MIPSARCH 9 +#define WLAN_HPPAARCH 10 +/* WLAN_HOSTIF (generally set on the command line, not detected) */ +#define WLAN_PCMCIA 1 +#define WLAN_ISA 2 +#define WLAN_PCI 3 +#define WLAN_USB 4 +#define WLAN_PLX 5 + +/* Note: the PLX HOSTIF above refers to some vendors implementations for */ +/* PCI. It's a PLX chip that is a PCI to PCMCIA adapter, but it */ +/* isn't a real PCMCIA host interface adapter providing all the */ +/* card&socket services. */ + +#ifdef __powerpc__ +#ifndef __ppc__ +#define __ppc__ +#endif +#endif + +#if (defined(CONFIG_PPC) || defined(CONFIG_8xx)) +#ifndef __ppc__ +#define __ppc__ +#endif +#endif + +#if defined(__x86_64__) + #define WLAN_CPU_FAMILY WLAN_x86_64 + #define WLAN_SYSARCH WLAN_PCAT +#elif defined (__ia64__) + #define WLAN_CPU_FAMILY WLAN_IA64 + #define WLAN_SYSARCH WLAN_PCAT +#elif defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) + #define WLAN_CPU_FAMILY WLAN_Ix86 + #define WLAN_CPU_CORE WLAN_I386CORE + #define WLAN_CPU_PART WLAN_I386PART + #define WLAN_SYSARCH WLAN_PCAT +#elif defined(__ppc__) + #define WLAN_CPU_FAMILY WLAN_PPC + #define WLAN_CPU_CORE WLAN_PPCCORE + #if defined(CONFIG_MBX) + #define WLAN_CPU_PART WLAN_MPC860 + #define WLAN_SYSARCH WLAN_MBX + #elif defined(CONFIG_RPXLITE) + #define WLAN_CPU_PART WLAN_MPC823 + #define WLAN_SYSARCH WLAN_RPX + #elif defined(CONFIG_RPXCLASSIC) + #define WLAN_CPU_PART WLAN_MPC860 + #define WLAN_SYSARCH WLAN_RPX + #else + #define WLAN_CPU_PART WLAN_PPCPART + #define WLAN_SYSARCH WLAN_PMAC + #endif +#elif defined(__arm__) + #define WLAN_CPU_FAMILY WLAN_ARM + #define WLAN_CPU_CORE WLAN_ARMCORE + #define WLAN_CPU_PART WLAN_ARM_PART + #define WLAN_SYSARCH WLAN_SKIFF +#elif defined(__alpha__) + #define WLAN_CPU_FAMILY WLAN_ALPHA + #define WLAN_CPU_CORE WLAN_ALPHACORE + #define WLAN_CPU_PART WLAN_ALPHAPART + #define WLAN_SYSARCH WLAN_ALPHAARCH +#elif defined(__mips__) + #define WLAN_CPU_FAMILY WLAN_MIPS + #define WLAN_CPU_CORE WLAN_MIPSCORE + #define WLAN_CPU_PART WLAN_MIPSPART + #define WLAN_SYSARCH WLAN_MIPSARCH +#elif defined(__hppa__) + #define WLAN_CPU_FAMILY WLAN_HPPA + #define WLAN_CPU_CORE WLAN_HPPACORE + #define WLAN_CPU_PART WLAN_HPPAPART + #define WLAN_SYSARCH WLAN_HPPAARCH +#elif defined(__sparc__) + #define WLAN_CPU_FAMILY WLAN_SPARC + #define WLAN_SYSARCH WLAN_SPARC +#elif defined(__sh__) + #define WLAN_CPU_FAMILY WLAN_SH + #define WLAN_SYSARCH WLAN_SHARCH + #ifndef __LITTLE_ENDIAN__ + #define __LITTLE_ENDIAN__ + #endif +#else + #error "No CPU identified!" +#endif + +/* + Some big endian machines implicitly do all I/O in little endian mode. + + In particular: + Linux/PPC on PowerMacs (PCI) + Arm/Intel Xscale (PCI) + + This may also affect PLX boards and other BE &| PPC platforms; + as new ones are discovered, add them below. +*/ + +#if ((WLAN_SYSARCH == WLAN_SKIFF) || (WLAN_SYSARCH == WLAN_PMAC)) +#define REVERSE_ENDIAN +#endif + +/*=============================================================*/ +/*------ Hardware Portability Macros --------------------------*/ +/*=============================================================*/ +#if (WLAN_CPU_FAMILY == WLAN_PPC) +#define wlan_inw(a) in_be16((unsigned short *)((a)+_IO_BASE)) +#define wlan_inw_le16_to_cpu(a) inw((a)) +#define wlan_outw(v,a) out_be16((unsigned short *)((a)+_IO_BASE), (v)) +#define wlan_outw_cpu_to_le16(v,a) outw((v),(a)) +#else +#define wlan_inw(a) inw((a)) +#define wlan_inw_le16_to_cpu(a) __cpu_to_le16(inw((a))) +#define wlan_outw(v,a) outw((v),(a)) +#define wlan_outw_cpu_to_le16(v,a) outw(__cpu_to_le16((v)),(a)) +#endif + +/*=============================================================*/ +/*------ Bit settings -----------------------------------------*/ +/*=============================================================*/ +#define ieee2host16(n) __le16_to_cpu(n) +#define ieee2host32(n) __le32_to_cpu(n) +#define host2ieee16(n) __cpu_to_le16(n) +#define host2ieee32(n) __cpu_to_le32(n) + +/* for constants */ +#ifdef __LITTLE_ENDIAN + #define IEEE16(a,n) a = n, a##i = n, +#else + #ifdef __BIG_ENDIAN + /* shifts would produce gcc warnings. Oh well... */ + #define IEEE16(a,n) a = n, a##i = ((n&0xff)*256 + ((n&0xff00)/256)), + #else + #error give me endianness or give me death + #endif +#endif + +/*=============================================================*/ +/*------ Compiler Portability Macros --------------------------*/ +/*=============================================================*/ +#define WLAN_PACKED __attribute__ ((packed)) + +/* Interrupt handler backwards compatibility stuff */ +#ifndef IRQ_NONE +#define IRQ_NONE +#define IRQ_HANDLED +typedef void irqreturn_t; +#endif + +#ifndef ARPHRD_IEEE80211_PRISM +#define ARPHRD_IEEE80211_PRISM 802 +#endif + +#define ETH_P_80211_RAW (ETH_P_ECONET + 1) + +/*============================================================================* + * Constants * + *============================================================================*/ +#define WLAN_IEEE_OUI_LEN 3 + +/*============================================================================* + * Types * + *============================================================================*/ + +/* local ether header type */ +typedef struct wlan_ethhdr { + u8 daddr[ETH_ALEN]; + u8 saddr[ETH_ALEN]; + u16 type; +} WLAN_PACKED wlan_ethhdr_t; + +/* local llc header type */ +typedef struct wlan_llc { + u8 dsap; + u8 ssap; + u8 ctl; +} WLAN_PACKED wlan_llc_t; + +/* local snap header type */ +typedef struct wlan_snap { + u8 oui[WLAN_IEEE_OUI_LEN]; + u16 type; +} WLAN_PACKED wlan_snap_t; --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/common.c +++ linux-2.6.28/ubuntu/misc/wireless/acx/common.c @@ -0,0 +1,7220 @@ +/*********************************************************************** +** Copyright (C) 2003 ACX100 Open Source Project +** +** The contents of this file are subject to the Mozilla Public +** License Version 1.1 (the "License"); you may not use this file +** except in compliance with the License. You may obtain a copy of +** the License at http://www.mozilla.org/MPL/ +** +** Software distributed under the License is distributed on an "AS +** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +** implied. See the License for the specific language governing +** rights and limitations under the License. +** +** Alternatively, the contents of this file may be used under the +** terms of the GNU Public License version 2 (the "GPL"), in which +** case the provisions of the GPL are applicable instead of the +** above. If you wish to allow the use of your version of this file +** only under the terms of the GPL and not to allow others to use +** your version of this file under the MPL, indicate your decision +** by deleting the provisions above and replace them with the notice +** and other provisions required by the GPL. If you do not delete +** the provisions above, a recipient may use your version of this +** file under either the MPL or the GPL. +** --------------------------------------------------------------------- +** Inquiries regarding the ACX100 Open Source Project can be +** made directly to: +** +** acx100-users@lists.sf.net +** http://acx100.sf.net +** --------------------------------------------------------------------- +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "acx.h" + + +/*********************************************************************** +*/ +static client_t *acx_l_sta_list_alloc(acx_device_t *adev); +static client_t *acx_l_sta_list_get_from_hash(acx_device_t *adev, const u8 *address); + +static int acx_l_process_data_frame_master(acx_device_t *adev, rxbuffer_t *rxbuf); +static int acx_l_process_data_frame_client(acx_device_t *adev, rxbuffer_t *rxbuf); +/* static int acx_l_process_NULL_frame(acx_device_t *adev, rxbuffer_t *rxbuf, int vala); */ +static int acx_l_process_mgmt_frame(acx_device_t *adev, rxbuffer_t *rxbuf); +static void acx_l_process_disassoc_from_sta(acx_device_t *adev, const wlan_fr_disassoc_t *req); +static void acx_l_process_disassoc_from_ap(acx_device_t *adev, const wlan_fr_disassoc_t *req); +static void acx_l_process_deauth_from_sta(acx_device_t *adev, const wlan_fr_deauthen_t *req); +static void acx_l_process_deauth_from_ap(acx_device_t *adev, const wlan_fr_deauthen_t *req); +static int acx_l_process_probe_response(acx_device_t *adev, wlan_fr_proberesp_t *req, const rxbuffer_t *rxbuf); +static int acx_l_process_assocresp(acx_device_t *adev, const wlan_fr_assocresp_t *req); +static int acx_l_process_reassocresp(acx_device_t *adev, const wlan_fr_reassocresp_t *req); +static int acx_l_process_authen(acx_device_t *adev, const wlan_fr_authen_t *req); +static int acx_l_transmit_assocresp(acx_device_t *adev, const wlan_fr_assocreq_t *req); +static int acx_l_transmit_reassocresp(acx_device_t *adev, const wlan_fr_reassocreq_t *req); +static int acx_l_transmit_deauthen(acx_device_t *adev, const u8 *addr, u16 reason); +static int acx_l_transmit_authen1(acx_device_t *adev); +static int acx_l_transmit_authen2(acx_device_t *adev, const wlan_fr_authen_t *req, client_t *clt); +static int acx_l_transmit_authen3(acx_device_t *adev, const wlan_fr_authen_t *req); +static int acx_l_transmit_authen4(acx_device_t *adev, const wlan_fr_authen_t *req); +static int acx_l_transmit_assoc_req(acx_device_t *adev); + + +/*********************************************************************** +*/ +#if ACX_DEBUG +unsigned int acx_debug = ACX_DEFAULT_MSG; +#endif + +char firmware_ver[33] = "default"; +module_param_string(firmware_ver, firmware_ver, sizeof(firmware_ver), 0444); +MODULE_PARM_DESC(firmware_ver, "Alternate firmware version."); + +#if ACX_DEBUG +module_param_named(debug, acx_debug, uint, 0); +#endif + +#if ACX_DEBUG +MODULE_PARM_DESC(debug, "Debug level mask (see L_xxx constants)"); +#endif + +#ifdef MODULE_LICENSE +MODULE_LICENSE("Dual MPL/GPL"); +#endif +/* USB had this: MODULE_AUTHOR("Martin Wawro "); */ +MODULE_AUTHOR("ACX100 Open Source Driver development team"); +MODULE_DESCRIPTION("Driver for TI ACX1xx based wireless cards (CardBus/PCI/USB)"); + + +/*********************************************************************** +*/ +/* Probably a number of acx's intermediate buffers for USB transfers, +** not to be confused with number of descriptors in tx/rx rings +** (which are not directly accessible to host in USB devices) */ +#define USB_RX_CNT 10 +#define USB_TX_CNT 10 + + +/*********************************************************************** +*/ + +/* minutes to wait until next radio recalibration: */ +#define RECALIB_PAUSE 5 + +/* Please keep acx_reg_domain_ids_len in sync... */ +const u8 acx_reg_domain_ids[acx_reg_domain_ids_len] = + { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40, 0x41, 0x51 }; +static const u16 reg_domain_channel_masks[acx_reg_domain_ids_len] = + { 0x07ff, 0x07ff, 0x1fff, 0x0600, 0x1e00, 0x2000, 0x3fff, 0x01fc }; +const char * const +acx_reg_domain_strings[] = { + /* 0 */ " 1-11 FCC (USA)", + /* 1 */ " 1-11 DOC/IC (Canada)", +/* BTW: WLAN use in ETSI is regulated by ETSI standard EN 300 328-2 V1.1.2 */ + /* 2 */ " 1-13 ETSI (Europe)", + /* 3 */ "10-11 Spain", + /* 4 */ "10-13 France", + /* 5 */ " 14 MKK (Japan)", + /* 6 */ " 1-14 MKK1", + /* 7 */ " 3-9 Israel (not all firmware versions)", + NULL /* needs to remain as last entry */ +}; + + + +/*********************************************************************** +** Debugging support +*/ +#ifdef PARANOID_LOCKING +static unsigned max_lock_time; +static unsigned max_sem_time; + +void +acx_lock_unhold() { max_lock_time = 0; } +void +acx_sem_unhold() { max_sem_time = 0; } + +static inline const char* +sanitize_str(const char *s) +{ + const char* t = strrchr(s, '/'); + if (t) return t + 1; + return s; +} + +void +acx_lock_debug(acx_device_t *adev, const char* where) +{ + unsigned int count = 100*1000*1000; + where = sanitize_str(where); + while (--count) { + if (!spin_is_locked(&adev->lock)) break; + cpu_relax(); + } + if (!count) { + printk(KERN_EMERG "LOCKUP: already taken at %s!\n", adev->last_lock); + BUG(); + } + adev->last_lock = where; + rdtscl(adev->lock_time); +} +void +acx_unlock_debug(acx_device_t *adev, const char* where) +{ +#ifdef SMP + if (!spin_is_locked(&adev->lock)) { + where = sanitize_str(where); + printk(KERN_EMERG "STRAY UNLOCK at %s!\n", where); + BUG(); + } +#endif + if (acx_debug & L_LOCK) { + unsigned long diff; + rdtscl(diff); + diff -= adev->lock_time; + if (diff > max_lock_time) { + where = sanitize_str(where); + printk("max lock hold time %ld CPU ticks from %s " + "to %s\n", diff, adev->last_lock, where); + max_lock_time = diff; + } + } +} +void +acx_down_debug(acx_device_t *adev, const char* where) +{ + int sem_count; + unsigned long timeout = jiffies + 5*HZ; + + where = sanitize_str(where); + + for (;;) { + sem_count = atomic_read(&adev->sem.count); + if (sem_count) break; + if (time_after(jiffies, timeout)) + break; + msleep(5); + } + if (!sem_count) { + printk(KERN_EMERG "D STATE at %s! last sem at %s\n", + where, adev->last_sem); + dump_stack(); + } + adev->last_sem = where; + adev->sem_time = jiffies; + down(&adev->sem); + if (acx_debug & L_LOCK) { + printk("%s: sem_down %d -> %d\n", + where, sem_count, atomic_read(&adev->sem.count)); + } +} +void +acx_up_debug(acx_device_t *adev, const char* where) +{ + int sem_count = atomic_read(&adev->sem.count); + if (sem_count) { + where = sanitize_str(where); + printk(KERN_EMERG "STRAY UP at %s! sem.count=%d\n", where, sem_count); + dump_stack(); + } + if (acx_debug & L_LOCK) { + unsigned long diff = jiffies - adev->sem_time; + if (diff > max_sem_time) { + where = sanitize_str(where); + printk("max sem hold time %ld jiffies from %s " + "to %s\n", diff, adev->last_sem, where); + max_sem_time = diff; + } + } + up(&adev->sem); + if (acx_debug & L_LOCK) { + where = sanitize_str(where); + printk("%s: sem_up %d -> %d\n", + where, sem_count, atomic_read(&adev->sem.count)); + } +} +#endif /* PARANOID_LOCKING */ + + +/*********************************************************************** +*/ +#if ACX_DEBUG > 1 + +static int acx_debug_func_indent; +#define DEBUG_TSC 0 +#define FUNC_INDENT_INCREMENT 2 + +#if DEBUG_TSC +#define TIMESTAMP(d) unsigned long d; rdtscl(d) +#else +#define TIMESTAMP(d) unsigned long d = jiffies +#endif + +static const char +spaces[] = " " " "; /* Nx10 spaces */ + +void +log_fn_enter(const char *funcname) +{ + int indent; + TIMESTAMP(d); + + indent = acx_debug_func_indent; + if (indent >= sizeof(spaces)) + indent = sizeof(spaces)-1; + + printk("%08ld %s==> %s\n", + d % 100000000, + spaces + (sizeof(spaces)-1) - indent, + funcname + ); + + acx_debug_func_indent += FUNC_INDENT_INCREMENT; +} +void +log_fn_exit(const char *funcname) +{ + int indent; + TIMESTAMP(d); + + acx_debug_func_indent -= FUNC_INDENT_INCREMENT; + + indent = acx_debug_func_indent; + if (indent >= sizeof(spaces)) + indent = sizeof(spaces)-1; + + printk("%08ld %s<== %s\n", + d % 100000000, + spaces + (sizeof(spaces)-1) - indent, + funcname + ); +} +void +log_fn_exit_v(const char *funcname, int v) +{ + int indent; + TIMESTAMP(d); + + acx_debug_func_indent -= FUNC_INDENT_INCREMENT; + + indent = acx_debug_func_indent; + if (indent >= sizeof(spaces)) + indent = sizeof(spaces)-1; + + printk("%08ld %s<== %s: %08X\n", + d % 100000000, + spaces + (sizeof(spaces)-1) - indent, + funcname, + v + ); +} +#endif /* ACX_DEBUG > 1 */ + + +/*********************************************************************** +** Basically a msleep with logging +*/ +void +acx_s_msleep(int ms) +{ + FN_ENTER; + msleep(ms); + FN_EXIT0; +} + + +/*********************************************************************** +** Not inlined: it's larger than it seems +*/ +void +acx_print_mac(const char *head, const u8 *mac, const char *tail) +{ + printk("%s"MACSTR"%s", head, MAC(mac), tail); +} + + +/*********************************************************************** +** acx_get_status_name +*/ +static const char* +acx_get_status_name(u16 status) +{ + static const char * const str[] = { + "STOPPED", "SCANNING", "WAIT_AUTH", + "AUTHENTICATED", "ASSOCIATED", "INVALID??" + }; + if (status > VEC_SIZE(str)-1) + status = VEC_SIZE(str)-1; + + return str[status]; +} + + +/*********************************************************************** +** acx_get_packet_type_string +*/ +#if ACX_DEBUG +const char* +acx_get_packet_type_string(u16 fc) +{ + static const char * const mgmt_arr[] = { + "MGMT/AssocReq", "MGMT/AssocResp", "MGMT/ReassocReq", + "MGMT/ReassocResp", "MGMT/ProbeReq", "MGMT/ProbeResp", + "MGMT/UNKNOWN", "MGMT/UNKNOWN", "MGMT/Beacon", "MGMT/ATIM", + "MGMT/Disassoc", "MGMT/Authen", "MGMT/Deauthen" + }; + static const char * const ctl_arr[] = { + "CTL/PSPoll", "CTL/RTS", "CTL/CTS", "CTL/Ack", "CTL/CFEnd", + "CTL/CFEndCFAck" + }; + static const char * const data_arr[] = { + "DATA/DataOnly", "DATA/Data CFAck", "DATA/Data CFPoll", + "DATA/Data CFAck/CFPoll", "DATA/Null", "DATA/CFAck", + "DATA/CFPoll", "DATA/CFAck/CFPoll" + }; + const char *str; + u8 fstype = (WF_FC_FSTYPE & fc) >> 4; + u8 ctl; + + switch (WF_FC_FTYPE & fc) { + case WF_FTYPE_MGMT: + if (fstype < VEC_SIZE(mgmt_arr)) + str = mgmt_arr[fstype]; + else + str = "MGMT/UNKNOWN"; + break; + case WF_FTYPE_CTL: + ctl = fstype - 0x0a; + if (ctl < VEC_SIZE(ctl_arr)) + str = ctl_arr[ctl]; + else + str = "CTL/UNKNOWN"; + break; + case WF_FTYPE_DATA: + if (fstype < VEC_SIZE(data_arr)) + str = data_arr[fstype]; + else + str = "DATA/UNKNOWN"; + break; + default: + str = "UNKNOWN"; + break; + } + return str; +} +#endif + + +/*********************************************************************** +** acx_wlan_reason_str +*/ +static inline const char* +acx_wlan_reason_str(u16 reason) +{ + static const char* const reason_str[] = { + /* 0 */ "?", + /* 1 */ "unspecified", + /* 2 */ "prev auth is not valid", + /* 3 */ "leaving BBS", + /* 4 */ "due to inactivity", + /* 5 */ "AP is busy", + /* 6 */ "got class 2 frame from non-auth'ed STA", + /* 7 */ "got class 3 frame from non-assoc'ed STA", + /* 8 */ "STA has left BSS", + /* 9 */ "assoc without auth is not allowed", + /* 10 */ "bad power setting (802.11h)", + /* 11 */ "bad channel (802.11i)", + /* 12 */ "?", + /* 13 */ "invalid IE", + /* 14 */ "MIC failure", + /* 15 */ "four-way handshake timeout", + /* 16 */ "group key handshake timeout", + /* 17 */ "IE is different", + /* 18 */ "invalid group cipher", + /* 19 */ "invalid pairwise cipher", + /* 20 */ "invalid AKMP", + /* 21 */ "unsupported RSN version", + /* 22 */ "invalid RSN IE cap", + /* 23 */ "802.1x failed", + /* 24 */ "cipher suite rejected" + }; + return reason < VEC_SIZE(reason_str) ? reason_str[reason] : "?"; +} + + +/*********************************************************************** +** acx_cmd_status_str +*/ +const char* +acx_cmd_status_str(unsigned int state) +{ + static const char * const cmd_error_strings[] = { + "Idle", + "Success", + "Unknown Command", + "Invalid Information Element", + "Channel rejected", + "Channel invalid in current regulatory domain", + "MAC invalid", + "Command rejected (read-only information element)", + "Command rejected", + "Already asleep", + "TX in progress", + "Already awake", + "Write only", + "RX in progress", + "Invalid parameter", + "Scan in progress", + "Failed" + }; + return state < VEC_SIZE(cmd_error_strings) ? + cmd_error_strings[state] : "?"; +} + + +/*********************************************************************** +** get_status_string +*/ +static inline const char* +get_status_string(unsigned int status) +{ + /* A bit shortened, but hopefully still understandable */ + static const char * const status_str[] = { + /* 0 */ "Successful", + /* 1 */ "Unspecified failure", + /* 2 */ "reserved", + /* 3 */ "reserved", + /* 4 */ "reserved", + /* 5 */ "reserved", + /* 6 */ "reserved", + /* 7 */ "reserved", + /* 8 */ "reserved", + /* 9 */ "reserved", + /*10 */ "Cannot support all requested capabilities in Capability Information field", + /*11 */ "Reassoc denied (reason outside of 802.11b scope)", + /*12 */ "Assoc denied (reason outside of 802.11b scope) -- maybe MAC filtering by peer?", + /*13 */ "Responding station doesnt support specified auth algorithm -- maybe WEP auth Open vs. Restricted?", + /*14 */ "Auth rejected: wrong transaction sequence number", + /*15 */ "Auth rejected: challenge failure", + /*16 */ "Auth rejected: timeout for next frame in sequence", + /*17 */ "Assoc denied: too many STAs on this AP", + /*18 */ "Assoc denied: requesting STA doesnt support all data rates in basic set", + /*19 */ "Assoc denied: requesting STA doesnt support Short Preamble", + /*20 */ "Assoc denied: requesting STA doesnt support PBCC Modulation", + /*21 */ "Assoc denied: requesting STA doesnt support Channel Agility" + /*22 */ "reserved", + /*23 */ "reserved", + /*24 */ "reserved", + /*25 */ "Assoc denied: requesting STA doesnt support Short Slot Time", + /*26 */ "Assoc denied: requesting STA doesnt support DSSS-OFDM" + }; + + return status_str[status < VEC_SIZE(status_str) ? status : 2]; +} + + +/*********************************************************************** +*/ +void +acx_log_bad_eid(wlan_hdr_t* hdr, int len, wlan_ie_t* ie_ptr) +{ + if (acx_debug & L_ASSOC) { + int offset = (u8*)ie_ptr - (u8*)hdr; + printk("acx: unknown EID %d in mgmt frame at offset %d. IE: ", + ie_ptr->eid, offset); + /* IE len can be bogus, IE can extend past packet end. Oh well... */ + acx_dump_bytes(ie_ptr, ie_ptr->len + 2); + if (acx_debug & L_DATA) { + printk("frame (%s): ", + acx_get_packet_type_string(le16_to_cpu(hdr->fc))); + acx_dump_bytes(hdr, len); + } + } +} + + +/*********************************************************************** +*/ +#if ACX_DEBUG +void +acx_dump_bytes(const void *data, int num) +{ + const u8* ptr = (const u8*)data; + + if (num <= 0) { + printk("\n"); + return; + } + + while (num >= 16) { + printk( "%02X %02X %02X %02X %02X %02X %02X %02X " + "%02X %02X %02X %02X %02X %02X %02X %02X\n", + ptr[0], ptr[1], ptr[2], ptr[3], + ptr[4], ptr[5], ptr[6], ptr[7], + ptr[8], ptr[9], ptr[10], ptr[11], + ptr[12], ptr[13], ptr[14], ptr[15]); + num -= 16; + ptr += 16; + } + if (num > 0) { + while (--num > 0) + printk("%02X ", *ptr++); + printk("%02X\n", *ptr); + } +} +#endif + + +/*********************************************************************** +** acx_s_get_firmware_version +*/ +void +acx_s_get_firmware_version(acx_device_t *adev) +{ + fw_ver_t fw; + u8 hexarr[4] = { 0, 0, 0, 0 }; + int hexidx = 0, val = 0; + const char *num; + char c; + + FN_ENTER; + + memset(fw.fw_id, 'E', FW_ID_SIZE); + acx_s_interrogate(adev, &fw, ACX1xx_IE_FWREV); + memcpy(adev->firmware_version, fw.fw_id, FW_ID_SIZE); + adev->firmware_version[FW_ID_SIZE] = '\0'; + + log(L_DEBUG, "fw_ver: fw_id='%s' hw_id=%08X\n", + adev->firmware_version, fw.hw_id); + + if (strncmp(fw.fw_id, "Rev ", 4) != 0) { + printk("acx: strange firmware version string " + "'%s', please report\n", adev->firmware_version); + adev->firmware_numver = 0x01090407; /* assume 1.9.4.7 */ + } else { + num = &fw.fw_id[4]; + while (1) { + c = *num++; + if ((c == '.') || (c == '\0')) { + hexarr[hexidx++] = val; + if ((hexidx > 3) || (c == '\0')) /* end? */ + break; + val = 0; + continue; + } + if ((c >= '0') && (c <= '9')) + c -= '0'; + else + c = c - 'a' + (char)10; + val = val*16 + c; + } + + adev->firmware_numver = (u32)( + (hexarr[0] << 24) | (hexarr[1] << 16) + | (hexarr[2] << 8) | hexarr[3]); + log(L_DEBUG, "firmware_numver 0x%08X\n", adev->firmware_numver); + } + if (IS_ACX111(adev)) { + if (adev->firmware_numver == 0x00010011) { + /* This one does not survive floodpinging */ + printk("acx: firmware '%s' is known to be buggy, " + "please upgrade\n", adev->firmware_version); + } + } + + adev->firmware_id = le32_to_cpu(fw.hw_id); + + /* we're able to find out more detailed chip names now */ + switch (adev->firmware_id & 0xffff0000) { + case 0x01010000: + case 0x01020000: + adev->chip_name = "TNETW1100A"; + break; + case 0x01030000: + adev->chip_name = "TNETW1100B"; + break; + case 0x03000000: + case 0x03010000: + adev->chip_name = "TNETW1130"; + break; + case 0x04030000: /* 0x04030101 is TNETW1450 */ + adev->chip_name = "TNETW1450"; + break; + default: + printk("acx: unknown chip ID 0x%08X, " + "please report\n", adev->firmware_id); + break; + } + + FN_EXIT0; +} + + +/*********************************************************************** +** acx_display_hardware_details +** +** Displays hw/fw version, radio type etc... +*/ +void +acx_display_hardware_details(acx_device_t *adev) +{ + const char *radio_str, *form_str; + + FN_ENTER; + + switch (adev->radio_type) { + case RADIO_MAXIM_0D: + radio_str = "Maxim"; + break; + case RADIO_RFMD_11: + radio_str = "RFMD"; + break; + case RADIO_RALINK_15: + radio_str = "Ralink"; + break; + case RADIO_RADIA_16: + radio_str = "Radia"; + break; + case RADIO_UNKNOWN_17: + /* TI seems to have a radio which is + * additionally 802.11a capable, too */ + radio_str = "802.11a/b/g radio?! Please report"; + break; + case RADIO_UNKNOWN_19: + radio_str = "A radio used by Safecom cards?! Please report"; + break; + case RADIO_UNKNOWN_1B: + radio_str = "An unknown radio used by TNETW1450 USB adapters"; + break; + default: + radio_str = "UNKNOWN, please report radio type name!"; + break; + } + + switch (adev->form_factor) { + case 0x00: + form_str = "unspecified"; + break; + case 0x01: + form_str = "(mini-)PCI / CardBus"; + break; + case 0x02: + form_str = "USB"; + break; + case 0x03: + form_str = "Compact Flash"; + break; + default: + form_str = "UNKNOWN, please report"; + break; + } + + printk("acx: === chipset %s, radio type 0x%02X (%s), " + "form factor 0x%02X (%s), EEPROM version 0x%02X: " + "uploaded firmware '%s' ===\n", + adev->chip_name, adev->radio_type, radio_str, + adev->form_factor, form_str, adev->eeprom_version, + adev->firmware_version); + + FN_EXIT0; +} + + +/*********************************************************************** +*/ +int +acx_e_change_mtu(struct net_device *ndev, int mtu) +{ + enum { + MIN_MTU = 256, + MAX_MTU = WLAN_DATA_MAXLEN - (ETH_HLEN) + }; + + if (mtu < MIN_MTU || mtu > MAX_MTU) + return -EINVAL; + + ndev->mtu = mtu; + return 0; +} + + +/*********************************************************************** +** acx_e_get_stats, acx_e_get_wireless_stats +*/ +struct net_device_stats* +acx_e_get_stats(struct net_device *ndev) +{ + acx_device_t *adev = ndev2adev(ndev); + return &adev->stats; +} + +struct iw_statistics* +acx_e_get_wireless_stats(struct net_device *ndev) +{ + acx_device_t *adev = ndev2adev(ndev); + return &adev->wstats; +} + + +/*********************************************************************** +** maps acx111 tx descr rate field to acx100 one +*/ +const u8 +acx_bitpos2rate100[] = { + RATE100_1 ,/* 0 */ + RATE100_2 ,/* 1 */ + RATE100_5 ,/* 2 */ + RATE100_2 ,/* 3, should not happen */ + RATE100_2 ,/* 4, should not happen */ + RATE100_11 ,/* 5 */ + RATE100_2 ,/* 6, should not happen */ + RATE100_2 ,/* 7, should not happen */ + RATE100_22 ,/* 8 */ + RATE100_2 ,/* 9, should not happen */ + RATE100_2 ,/* 10, should not happen */ + RATE100_2 ,/* 11, should not happen */ + RATE100_2 ,/* 12, should not happen */ + RATE100_2 ,/* 13, should not happen */ + RATE100_2 ,/* 14, should not happen */ + RATE100_2 ,/* 15, should not happen */ +}; + +u8 +acx_rate111to100(u16 r) { + return acx_bitpos2rate100[highest_bit(r)]; +} + + +/*********************************************************************** +** Calculate level like the feb 2003 windows driver seems to do +*/ +static u8 +acx_signal_to_winlevel(u8 rawlevel) +{ + /* u8 winlevel = (u8) (0.5 + 0.625 * rawlevel); */ + u8 winlevel = ((4 + (rawlevel * 5)) / 8); + + if (winlevel > 100) + winlevel = 100; + return winlevel; +} + +u8 +acx_signal_determine_quality(u8 signal, u8 noise) +{ + int qual; + + qual = (((signal - 30) * 100 / 70) + (100 - noise * 4)) / 2; + + if (qual > 100) + return 100; + if (qual < 0) + return 0; + return qual; +} + + +/*********************************************************************** +** Interrogate/configure commands +*/ + +/* FIXME: the lengths given here probably aren't always correct. + * They should be gradually replaced by proper "sizeof(acx1XX_ie_XXXX)-4", + * unless the firmware actually expects a different length than the struct length */ +static const u16 +acx100_ie_len[] = { + 0, + ACX100_IE_ACX_TIMER_LEN, + sizeof(acx100_ie_powersave_t)-4, /* is that 6 or 8??? */ + ACX1xx_IE_QUEUE_CONFIG_LEN, + ACX100_IE_BLOCK_SIZE_LEN, + ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN, + ACX1xx_IE_RATE_FALLBACK_LEN, + ACX100_IE_WEP_OPTIONS_LEN, + ACX1xx_IE_MEMORY_MAP_LEN, /* ACX1xx_IE_SSID_LEN, */ + 0, + ACX1xx_IE_ASSOC_ID_LEN, + 0, + ACX111_IE_CONFIG_OPTIONS_LEN, + ACX1xx_IE_FWREV_LEN, + ACX1xx_IE_FCS_ERROR_COUNT_LEN, + ACX1xx_IE_MEDIUM_USAGE_LEN, + ACX1xx_IE_RXCONFIG_LEN, + 0, + 0, + sizeof(fw_stats_t)-4, + 0, + ACX1xx_IE_FEATURE_CONFIG_LEN, + ACX111_IE_KEY_CHOOSE_LEN, + ACX1FF_IE_MISC_CONFIG_TABLE_LEN, + ACX1FF_IE_WONE_CONFIG_LEN, + 0, + ACX1FF_IE_TID_CONFIG_LEN, + 0, + 0, + 0, + ACX1FF_IE_CALIB_ASSESSMENT_LEN, + ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN, + ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN, + ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN, + 0, + ACX1FF_IE_PACKET_DETECT_THRESH_LEN, + ACX1FF_IE_TX_CONFIG_OPTIONS_LEN, + ACX1FF_IE_CCA_THRESHOLD_LEN, + ACX1FF_IE_EVENT_MASK_LEN, + ACX1FF_IE_DTIM_PERIOD_LEN, + 0, + ACX1FF_IE_ACI_CONFIG_SET_LEN, + 0, + 0, + 0, + 0, + 0, + 0, + ACX1FF_IE_EEPROM_VER_LEN, +}; + +static const u16 +acx100_ie_len_dot11[] = { + 0, + ACX1xx_IE_DOT11_STATION_ID_LEN, + 0, + ACX100_IE_DOT11_BEACON_PERIOD_LEN, + ACX1xx_IE_DOT11_DTIM_PERIOD_LEN, + ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN, + ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN, + ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN, + ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN, + 0, + ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN, + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN, + 0, + ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN, + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN, + ACX100_IE_DOT11_ED_THRESHOLD_LEN, + ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN, + 0, + 0, + 0, +}; + +static const u16 +acx111_ie_len[] = { + 0, + ACX100_IE_ACX_TIMER_LEN, + sizeof(acx111_ie_powersave_t)-4, + ACX1xx_IE_QUEUE_CONFIG_LEN, + ACX100_IE_BLOCK_SIZE_LEN, + ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN, + ACX1xx_IE_RATE_FALLBACK_LEN, + ACX100_IE_WEP_OPTIONS_LEN, + ACX1xx_IE_MEMORY_MAP_LEN, /* ACX1xx_IE_SSID_LEN, */ + 0, + ACX1xx_IE_ASSOC_ID_LEN, + 0, + ACX111_IE_CONFIG_OPTIONS_LEN, + ACX1xx_IE_FWREV_LEN, + ACX1xx_IE_FCS_ERROR_COUNT_LEN, + ACX1xx_IE_MEDIUM_USAGE_LEN, + ACX1xx_IE_RXCONFIG_LEN, + 0, + 0, + sizeof(fw_stats_t)-4, + 0, + ACX1xx_IE_FEATURE_CONFIG_LEN, + ACX111_IE_KEY_CHOOSE_LEN, + ACX1FF_IE_MISC_CONFIG_TABLE_LEN, + ACX1FF_IE_WONE_CONFIG_LEN, + 0, + ACX1FF_IE_TID_CONFIG_LEN, + 0, + 0, + 0, + ACX1FF_IE_CALIB_ASSESSMENT_LEN, + ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN, + ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN, + ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN, + 0, + ACX1FF_IE_PACKET_DETECT_THRESH_LEN, + ACX1FF_IE_TX_CONFIG_OPTIONS_LEN, + ACX1FF_IE_CCA_THRESHOLD_LEN, + ACX1FF_IE_EVENT_MASK_LEN, + ACX1FF_IE_DTIM_PERIOD_LEN, + 0, + ACX1FF_IE_ACI_CONFIG_SET_LEN, + 0, + 0, + 0, + 0, + 0, + 0, + ACX1FF_IE_EEPROM_VER_LEN, +}; + +static const u16 +acx111_ie_len_dot11[] = { + 0, + ACX1xx_IE_DOT11_STATION_ID_LEN, + 0, + ACX100_IE_DOT11_BEACON_PERIOD_LEN, + ACX1xx_IE_DOT11_DTIM_PERIOD_LEN, + ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN, + ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN, + ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN, + ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN, + 0, + ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN, + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN, + 0, + ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN, + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN, + ACX100_IE_DOT11_ED_THRESHOLD_LEN, + ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN, + 0, + 0, + 0, +}; + + +#undef FUNC +#define FUNC "configure" +#if !ACX_DEBUG +int +acx_s_configure(acx_device_t *adev, void *pdr, int type) +{ +#else +int +acx_s_configure_debug(acx_device_t *adev, void *pdr, int type, const char* typestr) +{ +#endif + u16 len; + int res; + + if (type < 0x1000) + len = adev->ie_len[type]; + else + len = adev->ie_len_dot11[type - 0x1000]; + + log(L_CTL, FUNC"(type:%s,len:%u)\n", typestr, len); + if (unlikely(!len)) { + log(L_DEBUG, "zero-length type %s?!\n", typestr); + } + + ((acx_ie_generic_t *)pdr)->type = cpu_to_le16(type); + ((acx_ie_generic_t *)pdr)->len = cpu_to_le16(len); + res = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIGURE, pdr, len + 4); + if (unlikely(OK != res)) { +#if ACX_DEBUG + printk("%s: "FUNC"(type:%s) FAILED\n", adev->ndev->name, typestr); +#else + printk("%s: "FUNC"(type:0x%X) FAILED\n", adev->ndev->name, type); +#endif + /* dump_stack() is already done in issue_cmd() */ + } + return res; +} + +#undef FUNC +#define FUNC "interrogate" +#if !ACX_DEBUG +int +acx_s_interrogate(acx_device_t *adev, void *pdr, int type) +{ +#else +int +acx_s_interrogate_debug(acx_device_t *adev, void *pdr, int type, + const char* typestr) +{ +#endif + u16 len; + int res; + + /* FIXME: no check whether this exceeds the array yet. + * We should probably remember the number of entries... */ + if (type < 0x1000) + len = adev->ie_len[type]; + else + len = adev->ie_len_dot11[type-0x1000]; + + log(L_CTL, FUNC"(type:%s,len:%u)\n", typestr, len); + + ((acx_ie_generic_t *)pdr)->type = cpu_to_le16(type); + ((acx_ie_generic_t *)pdr)->len = cpu_to_le16(len); + res = acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, pdr, len + 4); + if (unlikely(OK != res)) { +#if ACX_DEBUG + printk("%s: "FUNC"(type:%s) FAILED\n", adev->ndev->name, typestr); +#else + printk("%s: "FUNC"(type:0x%X) FAILED\n", adev->ndev->name, type); +#endif + /* dump_stack() is already done in issue_cmd() */ + } + return res; +} + +#if CMD_DISCOVERY +void +great_inquisitor(acx_device_t *adev) +{ + static struct { + u16 type; + u16 len; + /* 0x200 was too large here: */ + u8 data[0x100 - 4]; + } ACX_PACKED ie; + u16 type; + + FN_ENTER; + + /* 0..0x20, 0x1000..0x1020 */ + for (type = 0; type <= 0x1020; type++) { + if (type == 0x21) + type = 0x1000; + ie.type = cpu_to_le16(type); + ie.len = cpu_to_le16(sizeof(ie) - 4); + acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, &ie, sizeof(ie)); + } + FN_EXIT0; +} +#endif + + +#ifdef CONFIG_PROC_FS +/*********************************************************************** +** /proc files +*/ +/*********************************************************************** +** acx_l_proc_output +** Generate content for our /proc entry +** +** Arguments: +** buf is a pointer to write output to +** adev is the usual pointer to our private struct acx_device +** Returns: +** number of bytes actually written to buf +** Side effects: +** none +*/ +static int +acx_l_proc_output(char *buf, acx_device_t *adev) +{ + char *p = buf; + int i; + + FN_ENTER; + + p += sprintf(p, + "acx driver version:\t\t" ACX_RELEASE "\n" + "Wireless extension version:\t" STRING(WIRELESS_EXT) "\n" + "chip name:\t\t\t%s (0x%08X)\n" + "radio type:\t\t\t0x%02X\n" + "form factor:\t\t\t0x%02X\n" + "EEPROM version:\t\t\t0x%02X\n" + "firmware version:\t\t%s (0x%08X)\n", + adev->chip_name, adev->firmware_id, + adev->radio_type, + adev->form_factor, + adev->eeprom_version, + adev->firmware_version, adev->firmware_numver); + + for (i = 0; i < VEC_SIZE(adev->sta_list); i++) { + struct client *bss = &adev->sta_list[i]; + if (!bss->used) continue; + p += sprintf(p, "BSS %u BSSID "MACSTR" ESSID %s channel %u " + "Cap 0x%X SIR %u SNR %u\n", + i, MAC(bss->bssid), (char*)bss->essid, bss->channel, + bss->cap_info, bss->sir, bss->snr); + } + p += sprintf(p, "status:\t\t\t%u (%s)\n", + adev->status, acx_get_status_name(adev->status)); + + FN_EXIT1(p - buf); + return p - buf; +} + + +/*********************************************************************** +*/ +static int +acx_s_proc_diag_output(char *buf, acx_device_t *adev) +{ + char *p = buf; + unsigned long flags; + unsigned int len = 0, partlen; + u32 temp1, temp2; + u8 *st, *st_end; +#ifdef __BIG_ENDIAN + u8 *st2; +#endif + fw_stats_t *fw_stats; + char *part_str = NULL; + fw_stats_tx_t *tx = NULL; + fw_stats_rx_t *rx = NULL; + fw_stats_dma_t *dma = NULL; + fw_stats_irq_t *irq = NULL; + fw_stats_wep_t *wep = NULL; + fw_stats_pwr_t *pwr = NULL; + fw_stats_mic_t *mic = NULL; + fw_stats_aes_t *aes = NULL; + fw_stats_event_t *evt = NULL; + + FN_ENTER; + + acx_lock(adev, flags); + + if (IS_PCI(adev)) + p = acxpci_s_proc_diag_output(p, adev); + + p += sprintf(p, + "\n" + "** network status **\n" + "dev_state_mask 0x%04X\n" + "status %u (%s), " + "mode %u, channel %u, " + "reg_dom_id 0x%02X, reg_dom_chanmask 0x%04X, ", + adev->dev_state_mask, + adev->status, acx_get_status_name(adev->status), + adev->mode, adev->channel, + adev->reg_dom_id, adev->reg_dom_chanmask + ); + p += sprintf(p, + "ESSID \"%s\", essid_active %d, essid_len %d, " + "essid_for_assoc \"%s\", nick \"%s\"\n" + "WEP ena %d, restricted %d, idx %d\n", + adev->essid, adev->essid_active, (int)adev->essid_len, + adev->essid_for_assoc, adev->nick, + adev->wep_enabled, adev->wep_restricted, + adev->wep_current_index); + p += sprintf(p, "dev_addr "MACSTR"\n", MAC(adev->dev_addr)); + p += sprintf(p, "bssid "MACSTR"\n", MAC(adev->bssid)); + p += sprintf(p, "ap_filter "MACSTR"\n", MAC(adev->ap)); + + p += sprintf(p, + "\n" + "** PHY status **\n" + "tx_disabled %d, tx_level_dbm %d\n" /* "tx_level_val %d, tx_level_auto %d\n" */ + "sensitivity %d, antenna 0x%02X, ed_threshold %d, cca %d, preamble_mode %d\n" + "rate_basic 0x%04X, rate_oper 0x%04X\n" + "rts_threshold %d, frag_threshold %d, short_retry %d, long_retry %d\n" + "msdu_lifetime %d, listen_interval %d, beacon_interval %d\n", + adev->tx_disabled, adev->tx_level_dbm, /* adev->tx_level_val, adev->tx_level_auto, */ + adev->sensitivity, adev->antenna, adev->ed_threshold, adev->cca, adev->preamble_mode, + adev->rate_basic, adev->rate_oper, + adev->rts_threshold, adev->frag_threshold, adev->short_retry, adev->long_retry, + adev->msdu_lifetime, adev->listen_interval, adev->beacon_interval); + + acx_unlock(adev, flags); + + p += sprintf(p, + "\n" + "** Firmware **\n" + "NOTE: version dependent statistics layout, " + "please report if you suspect wrong parsing!\n" + "\n" + "version \"%s\"\n", adev->firmware_version); + + /* TODO: may replace kmalloc/memset with kzalloc once + * Linux 2.6.14 is widespread */ + fw_stats = kmalloc(sizeof(*fw_stats), GFP_KERNEL); + if (!fw_stats) { + FN_EXIT1(0); + return 0; + } + memset(fw_stats, 0, sizeof(*fw_stats)); + + st = (u8 *)fw_stats; + + part_str = "statistics query command"; + + if (OK != acx_s_interrogate(adev, st, ACX1xx_IE_FIRMWARE_STATISTICS)) + goto fw_stats_end; + + st += sizeof(u16); + len = *(u16 *)st; + + if (len > sizeof(*fw_stats)) { + p += sprintf(p, + "firmware version with bigger fw_stats struct detected\n" + "(%u vs. %zu), please report\n", len, sizeof(fw_stats_t)); + if (len > sizeof(*fw_stats)) { + p += sprintf(p, "struct size exceeded allocation!\n"); + len = sizeof(*fw_stats); + } + } + st += sizeof(u16); + st_end = st - 2*sizeof(u16) + len; + +#ifdef __BIG_ENDIAN + /* let's make one bold assumption here: + * (hopefully!) *all* statistics fields are u32 only, + * thus if we need to make endianness corrections + * we can simply do them in one go, in advance */ + st2 = (u8 *)fw_stats; + for (temp1 = 0; temp1 < len; temp1 += 4, st2 += 4) + *(u32 *)st2 = le32_to_cpu(*(u32 *)st2); +#endif + + part_str = "Rx/Tx"; + + /* directly at end of a struct part? --> no error! */ + if (st == st_end) + goto fw_stats_end; + + tx = (fw_stats_tx_t *)st; + st += sizeof(fw_stats_tx_t); + rx = (fw_stats_rx_t *)st; + st += sizeof(fw_stats_rx_t); + partlen = sizeof(fw_stats_tx_t) + sizeof(fw_stats_rx_t); + + if (IS_ACX100(adev)) { + /* at least ACX100 PCI F/W 1.9.8.b + * and ACX100 USB F/W 1.0.7-USB + * don't have those two fields... */ + st -= 2*sizeof(u32); + + /* our parsing doesn't quite match this firmware yet, + * log failure */ + if (st > st_end) + goto fw_stats_fail; + temp1 = temp2 = 999999999; + } else { + if (st > st_end) + goto fw_stats_fail; + temp1 = rx->rx_aci_events; + temp2 = rx->rx_aci_resets; + } + + p += sprintf(p, + "%s:\n" + " tx_desc_overfl %u\n" + " rx_OutOfMem %u, rx_hdr_overfl %u, rx_hw_stuck %u\n" + " rx_dropped_frame %u, rx_frame_ptr_err %u, rx_xfr_hint_trig %u\n" + " rx_aci_events %u, rx_aci_resets %u\n", + part_str, + tx->tx_desc_of, + rx->rx_oom, + rx->rx_hdr_of, + rx->rx_hw_stuck, + rx->rx_dropped_frame, + rx->rx_frame_ptr_err, + rx->rx_xfr_hint_trig, + temp1, + temp2); + + part_str = "DMA"; + + if (st == st_end) + goto fw_stats_end; + + dma = (fw_stats_dma_t *)st; + partlen = sizeof(fw_stats_dma_t); + st += partlen; + + if (st > st_end) + goto fw_stats_fail; + + p += sprintf(p, + "%s:\n" + " rx_dma_req %u, rx_dma_err %u, tx_dma_req %u, tx_dma_err %u\n", + part_str, + dma->rx_dma_req, + dma->rx_dma_err, + dma->tx_dma_req, + dma->tx_dma_err); + + part_str = "IRQ"; + + if (st == st_end) + goto fw_stats_end; + + irq = (fw_stats_irq_t *)st; + partlen = sizeof(fw_stats_irq_t); + st += partlen; + + if (st > st_end) + goto fw_stats_fail; + + p += sprintf(p, + "%s:\n" + " cmd_cplt %u, fiq %u\n" + " rx_hdrs %u, rx_cmplt %u, rx_mem_overfl %u, rx_rdys %u\n" + " irqs %u, tx_procs %u, decrypt_done %u\n" + " dma_0_done %u, dma_1_done %u, tx_exch_complet %u\n" + " commands %u, rx_procs %u, hw_pm_mode_changes %u\n" + " host_acks %u, pci_pm %u, acm_wakeups %u\n", + part_str, + irq->cmd_cplt, + irq->fiq, + irq->rx_hdrs, + irq->rx_cmplt, + irq->rx_mem_of, + irq->rx_rdys, + irq->irqs, + irq->tx_procs, + irq->decrypt_done, + irq->dma_0_done, + irq->dma_1_done, + irq->tx_exch_complet, + irq->commands, + irq->rx_procs, + irq->hw_pm_mode_changes, + irq->host_acks, + irq->pci_pm, + irq->acm_wakeups); + + part_str = "WEP"; + + if (st == st_end) + goto fw_stats_end; + + wep = (fw_stats_wep_t *)st; + partlen = sizeof(fw_stats_wep_t); + st += partlen; + + if ( + (IS_PCI(adev) && IS_ACX100(adev)) + || (IS_USB(adev) && IS_ACX100(adev)) + ) { + /* at least ACX100 PCI F/W 1.9.8.b + * and ACX100 USB F/W 1.0.7-USB + * don't have those two fields... */ + st -= 2*sizeof(u32); + if (st > st_end) + goto fw_stats_fail; + temp1 = temp2 = 999999999; + } else { + if (st > st_end) + goto fw_stats_fail; + temp1 = wep->wep_pkt_decrypt; + temp2 = wep->wep_decrypt_irqs; + } + + p += sprintf(p, + "%s:\n" + " wep_key_count %u, wep_default_key_count %u, dot11_def_key_mib %u\n" + " wep_key_not_found %u, wep_decrypt_fail %u\n" + " wep_pkt_decrypt %u, wep_decrypt_irqs %u\n", + part_str, + wep->wep_key_count, + wep->wep_default_key_count, + wep->dot11_def_key_mib, + wep->wep_key_not_found, + wep->wep_decrypt_fail, + temp1, + temp2); + + part_str = "power"; + + if (st == st_end) + goto fw_stats_end; + + pwr = (fw_stats_pwr_t *)st; + partlen = sizeof(fw_stats_pwr_t); + st += partlen; + + if (st > st_end) + goto fw_stats_fail; + + p += sprintf(p, + "%s:\n" + " tx_start_ctr %u, no_ps_tx_too_short %u\n" + " rx_start_ctr %u, no_ps_rx_too_short %u\n" + " lppd_started %u\n" + " no_lppd_too_noisy %u, no_lppd_too_short %u, no_lppd_matching_frame %u\n", + part_str, + pwr->tx_start_ctr, + pwr->no_ps_tx_too_short, + pwr->rx_start_ctr, + pwr->no_ps_rx_too_short, + pwr->lppd_started, + pwr->no_lppd_too_noisy, + pwr->no_lppd_too_short, + pwr->no_lppd_matching_frame); + + part_str = "MIC"; + + if (st == st_end) + goto fw_stats_end; + + mic = (fw_stats_mic_t *)st; + partlen = sizeof(fw_stats_mic_t); + st += partlen; + + if (st > st_end) + goto fw_stats_fail; + + p += sprintf(p, + "%s:\n" + " mic_rx_pkts %u, mic_calc_fail %u\n", + part_str, + mic->mic_rx_pkts, + mic->mic_calc_fail); + + part_str = "AES"; + + if (st == st_end) + goto fw_stats_end; + + aes = (fw_stats_aes_t *)st; + partlen = sizeof(fw_stats_aes_t); + st += partlen; + + if (st > st_end) + goto fw_stats_fail; + + p += sprintf(p, + "%s:\n" + " aes_enc_fail %u, aes_dec_fail %u\n" + " aes_enc_pkts %u, aes_dec_pkts %u\n" + " aes_enc_irq %u, aes_dec_irq %u\n", + part_str, + aes->aes_enc_fail, + aes->aes_dec_fail, + aes->aes_enc_pkts, + aes->aes_dec_pkts, + aes->aes_enc_irq, + aes->aes_dec_irq); + + part_str = "event"; + + if (st == st_end) + goto fw_stats_end; + + evt = (fw_stats_event_t *)st; + partlen = sizeof(fw_stats_event_t); + st += partlen; + + if (st > st_end) + goto fw_stats_fail; + + p += sprintf(p, + "%s:\n" + " heartbeat %u, calibration %u\n" + " rx_mismatch %u, rx_mem_empty %u, rx_pool %u\n" + " oom_late %u\n" + " phy_tx_err %u, tx_stuck %u\n", + part_str, + evt->heartbeat, + evt->calibration, + evt->rx_mismatch, + evt->rx_mem_empty, + evt->rx_pool, + evt->oom_late, + evt->phy_tx_err, + evt->tx_stuck); + + if (st < st_end) + goto fw_stats_bigger; + + goto fw_stats_end; + +fw_stats_fail: + st -= partlen; + p += sprintf(p, + "failed at %s part (size %u), offset %lu (struct size %u), " + "please report\n", part_str, partlen, + (unsigned long)st - (unsigned long)fw_stats, len); + +fw_stats_bigger: + for (; st < st_end; st += 4) + p += sprintf(p, + "UNKN%3lu: %u\n", (unsigned long)st - (unsigned long)fw_stats, *(u32 *)st); + +fw_stats_end: + kfree(fw_stats); + + FN_EXIT1(p - buf); + return p - buf; +} + + +/*********************************************************************** +*/ +static int +acx_s_proc_phy_output(char *buf, acx_device_t *adev) +{ + char *p = buf; + int i; + + FN_ENTER; + + /* + if (RADIO_RFMD_11 != adev->radio_type) { + printk("sorry, not yet adapted for radio types " + "other than RFMD, please verify " + "PHY size etc. first!\n"); + goto end; + } + */ + + /* The PHY area is only 0x80 bytes long; further pages after that + * only have some page number registers with altered value, + * all other registers remain the same. */ + for (i = 0; i < 0x80; i++) { + acx_s_read_phy_reg(adev, i, p++); + } + + FN_EXIT1(p - buf); + return p - buf; +} + + +/*********************************************************************** +** acx_e_read_proc_XXXX +** Handle our /proc entry +** +** Arguments: +** standard kernel read_proc interface +** Returns: +** number of bytes written to buf +** Side effects: +** none +*/ +static int +acx_e_read_proc(char *buf, char **start, off_t offset, int count, + int *eof, void *data) +{ + acx_device_t *adev = (acx_device_t*)data; + unsigned long flags; + int length; + + FN_ENTER; + + acx_sem_lock(adev); + acx_lock(adev, flags); + /* fill buf */ + length = acx_l_proc_output(buf, adev); + acx_unlock(adev, flags); + acx_sem_unlock(adev); + + /* housekeeping */ + if (length <= offset + count) + *eof = 1; + *start = buf + offset; + length -= offset; + if (length > count) + length = count; + if (length < 0) + length = 0; + FN_EXIT1(length); + return length; +} + +static int +acx_e_read_proc_diag(char *buf, char **start, off_t offset, int count, + int *eof, void *data) +{ + acx_device_t *adev = (acx_device_t*)data; + int length; + + FN_ENTER; + + acx_sem_lock(adev); + /* fill buf */ + length = acx_s_proc_diag_output(buf, adev); + acx_sem_unlock(adev); + + /* housekeeping */ + if (length <= offset + count) + *eof = 1; + *start = buf + offset; + length -= offset; + if (length > count) + length = count; + if (length < 0) + length = 0; + FN_EXIT1(length); + return length; +} + +static int +acx_e_read_proc_eeprom(char *buf, char **start, off_t offset, int count, + int *eof, void *data) +{ + acx_device_t *adev = (acx_device_t*)data; + int length; + + FN_ENTER; + + /* fill buf */ + length = 0; + if (IS_PCI(adev)) { + acx_sem_lock(adev); + length = acxpci_proc_eeprom_output(buf, adev); + acx_sem_unlock(adev); + } + + /* housekeeping */ + if (length <= offset + count) + *eof = 1; + *start = buf + offset; + length -= offset; + if (length > count) + length = count; + if (length < 0) + length = 0; + FN_EXIT1(length); + return length; +} + +static int +acx_e_read_proc_phy(char *buf, char **start, off_t offset, int count, + int *eof, void *data) +{ + acx_device_t *adev = (acx_device_t*)data; + int length; + + FN_ENTER; + + acx_sem_lock(adev); + /* fill buf */ + length = acx_s_proc_phy_output(buf, adev); + acx_sem_unlock(adev); + + /* housekeeping */ + if (length <= offset + count) + *eof = 1; + *start = buf + offset; + length -= offset; + if (length > count) + length = count; + if (length < 0) + length = 0; + FN_EXIT1(length); + return length; +} + + +/*********************************************************************** +** /proc files registration +*/ +static const char * const +proc_files[] = { "", "_diag", "_eeprom", "_phy" }; + +static read_proc_t * const +proc_funcs[] = { + acx_e_read_proc, + acx_e_read_proc_diag, + acx_e_read_proc_eeprom, + acx_e_read_proc_phy +}; + +static int +manage_proc_entries(const struct net_device *ndev, int remove) +{ + acx_device_t *adev = ndev2adev((struct net_device *)ndev); + char procbuf[80]; + int i; + + for (i = 0; i < VEC_SIZE(proc_files); i++) { + snprintf(procbuf, sizeof(procbuf), + "driver/acx_%s%s", ndev->name, proc_files[i]); + log(L_INIT, "%sing /proc entry %s\n", + remove ? "remov" : "creat", procbuf); + if (!remove) { + if (!create_proc_read_entry(procbuf, 0, 0, proc_funcs[i], adev)) { + printk("acx: cannot register /proc entry %s\n", procbuf); + return NOT_OK; + } + } else { + remove_proc_entry(procbuf, NULL); + } + } + return OK; +} + +int +acx_proc_register_entries(const struct net_device *ndev) +{ + return manage_proc_entries(ndev, 0); +} + +int +acx_proc_unregister_entries(const struct net_device *ndev) +{ + return manage_proc_entries(ndev, 1); +} +#endif /* CONFIG_PROC_FS */ + + +/*********************************************************************** +** acx_cmd_join_bssid +** +** Common code for both acx100 and acx111. +*/ +/* NB: does NOT match RATE100_nn but matches ACX[111]_SCAN_RATE_n */ +static const u8 +bitpos2genframe_txrate[] = { + 10, /* 0. 1 Mbit/s */ + 20, /* 1. 2 Mbit/s */ + 55, /* 2. 5.5 Mbit/s */ + 0x0B, /* 3. 6 Mbit/s */ + 0x0F, /* 4. 9 Mbit/s */ + 110, /* 5. 11 Mbit/s */ + 0x0A, /* 6. 12 Mbit/s */ + 0x0E, /* 7. 18 Mbit/s */ + 220, /* 8. 22 Mbit/s */ + 0x09, /* 9. 24 Mbit/s */ + 0x0D, /* 10. 36 Mbit/s */ + 0x08, /* 11. 48 Mbit/s */ + 0x0C, /* 12. 54 Mbit/s */ + 10, /* 13. 1 Mbit/s, should never happen */ + 10, /* 14. 1 Mbit/s, should never happen */ + 10, /* 15. 1 Mbit/s, should never happen */ +}; + +/* Looks scary, eh? +** Actually, each one compiled into one AND and one SHIFT, +** 31 bytes in x86 asm (more if uints are replaced by u16/u8) */ +static inline unsigned int +rate111to5bits(unsigned int rate) +{ + return (rate & 0x7) + | ( (rate & RATE111_11) / (RATE111_11/JOINBSS_RATES_11) ) + | ( (rate & RATE111_22) / (RATE111_22/JOINBSS_RATES_22) ) + ; +} + +static void +acx_s_cmd_join_bssid(acx_device_t *adev, const u8 *bssid) +{ + acx_joinbss_t tmp; + int dtim_interval; + int i; + + if (mac_is_zero(bssid)) + return; + + FN_ENTER; + + dtim_interval = (ACX_MODE_0_ADHOC == adev->mode) ? + 1 : adev->dtim_interval; + + memset(&tmp, 0, sizeof(tmp)); + + for (i = 0; i < ETH_ALEN; i++) { + tmp.bssid[i] = bssid[ETH_ALEN-1 - i]; + } + + tmp.beacon_interval = cpu_to_le16(adev->beacon_interval); + + /* Basic rate set. Control frame responses (such as ACK or CTS frames) + ** are sent with one of these rates */ + if (IS_ACX111(adev)) { + /* It was experimentally determined that rates_basic + ** can take 11g rates as well, not only rates + ** defined with JOINBSS_RATES_BASIC111_nnn. + ** Just use RATE111_nnn constants... */ + tmp.u.acx111.dtim_interval = dtim_interval; + tmp.u.acx111.rates_basic = cpu_to_le16(adev->rate_basic); + log(L_ASSOC, "rates_basic:%04X, rates_supported:%04X\n", + adev->rate_basic, adev->rate_oper); + } else { + tmp.u.acx100.dtim_interval = dtim_interval; + tmp.u.acx100.rates_basic = rate111to5bits(adev->rate_basic); + tmp.u.acx100.rates_supported = rate111to5bits(adev->rate_oper); + log(L_ASSOC, "rates_basic:%04X->%02X, " + "rates_supported:%04X->%02X\n", + adev->rate_basic, tmp.u.acx100.rates_basic, + adev->rate_oper, tmp.u.acx100.rates_supported); + } + + /* Setting up how Beacon, Probe Response, RTS, and PS-Poll frames + ** will be sent (rate/modulation/preamble) */ + tmp.genfrm_txrate = bitpos2genframe_txrate[lowest_bit(adev->rate_basic)]; + tmp.genfrm_mod_pre = 0; /* FIXME: was = adev->capab_short (which was always 0); */ + /* we can use short pre *if* all peers can understand it */ + /* FIXME #2: we need to correctly set PBCC/OFDM bits here too */ + + /* we switch fw to STA mode in MONITOR mode, it seems to be + ** the only mode where fw does not emit beacons by itself + ** but allows us to send anything (we really want to retain + ** ability to tx arbitrary frames in MONITOR mode) + */ + tmp.macmode = (adev->mode != ACX_MODE_MONITOR ? adev->mode : ACX_MODE_2_STA); + tmp.channel = adev->channel; + tmp.essid_len = adev->essid_len; + /* NOTE: the code memcpy'd essid_len + 1 before, which is WRONG! */ + memcpy(tmp.essid, adev->essid, tmp.essid_len); + acx_s_issue_cmd(adev, ACX1xx_CMD_JOIN, &tmp, tmp.essid_len + 0x11); + + log(L_ASSOC|L_DEBUG, "BSS_Type = %u\n", tmp.macmode); + acxlog_mac(L_ASSOC|L_DEBUG, "JoinBSSID MAC:", adev->bssid, "\n"); + + acx_update_capabilities(adev); + FN_EXIT0; +} + + +/*********************************************************************** +** acx_s_cmd_start_scan +** +** Issue scan command to the hardware +** +** unified function for both ACX111 and ACX100 +*/ +static void +acx_s_scan_chan(acx_device_t *adev) +{ + union { + acx111_scan_t acx111; + acx100_scan_t acx100; + } s; + + FN_ENTER; + + memset(&s, 0, sizeof(s)); + + /* first common positions... */ + + s.acx111.count = cpu_to_le16(adev->scan_count); + s.acx111.rate = adev->scan_rate; + s.acx111.options = adev->scan_mode; + s.acx111.chan_duration = cpu_to_le16(adev->scan_duration); + s.acx111.max_probe_delay = cpu_to_le16(adev->scan_probe_delay); + + /* ...then differences */ + + if (IS_ACX111(adev)) { + s.acx111.channel_list_select = 0; /* scan every allowed channel */ + /*s.acx111.channel_list_select = 1;*/ /* scan given channels */ + /*s.acx111.modulation = 0x40;*/ /* long preamble? OFDM? -> only for active scan */ + s.acx111.modulation = 0; + /*s.acx111.channel_list[0] = 6; + s.acx111.channel_list[1] = 4;*/ + } else { + s.acx100.start_chan = cpu_to_le16(1); + s.acx100.flags = cpu_to_le16(0x8000); + } + + acx_s_issue_cmd(adev, ACX1xx_CMD_SCAN, &s, sizeof(s)); + FN_EXIT0; +} + + +void +acx_s_cmd_start_scan(acx_device_t *adev) +{ + /* time_before check is 'just in case' thing */ + if (!(adev->irq_status & HOST_INT_SCAN_COMPLETE) + && time_before(jiffies, adev->scan_start + 10*HZ) + ) { + log(L_INIT, "start_scan: seems like previous scan " + "is still running. Not starting anew. Please report\n"); + return; + } + + log(L_INIT, "starting radio scan\n"); + /* remember that fw is commanded to do scan */ + adev->scan_start = jiffies; + CLEAR_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE); + /* issue it */ + acx_s_scan_chan(adev); +} + + +/*********************************************************************** +** acx111 feature config +*/ +static int +acx111_s_get_feature_config(acx_device_t *adev, + u32 *feature_options, u32 *data_flow_options) +{ + struct acx111_ie_feature_config feat; + + if (!IS_ACX111(adev)) { + return NOT_OK; + } + + memset(&feat, 0, sizeof(feat)); + + if (OK != acx_s_interrogate(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) { + return NOT_OK; + } + log(L_DEBUG, + "got Feature option:0x%X, DataFlow option: 0x%X\n", + feat.feature_options, + feat.data_flow_options); + + if (feature_options) + *feature_options = le32_to_cpu(feat.feature_options); + if (data_flow_options) + *data_flow_options = le32_to_cpu(feat.data_flow_options); + + return OK; +} + +static int +acx111_s_set_feature_config(acx_device_t *adev, + u32 feature_options, u32 data_flow_options, + unsigned int mode /* 0 == remove, 1 == add, 2 == set */) +{ + struct acx111_ie_feature_config feat; + + if (!IS_ACX111(adev)) { + return NOT_OK; + } + + if ((mode < 0) || (mode > 2)) + return NOT_OK; + + if (mode != 2) + /* need to modify old data */ + acx111_s_get_feature_config(adev, &feat.feature_options, &feat.data_flow_options); + else { + /* need to set a completely new value */ + feat.feature_options = 0; + feat.data_flow_options = 0; + } + + if (mode == 0) { /* remove */ + CLEAR_BIT(feat.feature_options, cpu_to_le32(feature_options)); + CLEAR_BIT(feat.data_flow_options, cpu_to_le32(data_flow_options)); + } else { /* add or set */ + SET_BIT(feat.feature_options, cpu_to_le32(feature_options)); + SET_BIT(feat.data_flow_options, cpu_to_le32(data_flow_options)); + } + + log(L_DEBUG, + "old: feature 0x%08X dataflow 0x%08X. mode: %u\n" + "new: feature 0x%08X dataflow 0x%08X\n", + feature_options, data_flow_options, mode, + le32_to_cpu(feat.feature_options), + le32_to_cpu(feat.data_flow_options)); + + if (OK != acx_s_configure(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) { + return NOT_OK; + } + + return OK; +} + +static inline int +acx111_s_feature_off(acx_device_t *adev, u32 f, u32 d) +{ + return acx111_s_set_feature_config(adev, f, d, 0); +} +static inline int +acx111_s_feature_on(acx_device_t *adev, u32 f, u32 d) +{ + return acx111_s_set_feature_config(adev, f, d, 1); +} +static inline int +acx111_s_feature_set(acx_device_t *adev, u32 f, u32 d) +{ + return acx111_s_set_feature_config(adev, f, d, 2); +} + + +/*********************************************************************** +** acx100_s_init_memory_pools +*/ +static int +acx100_s_init_memory_pools(acx_device_t *adev, const acx_ie_memmap_t *mmt) +{ + acx100_ie_memblocksize_t MemoryBlockSize; + acx100_ie_memconfigoption_t MemoryConfigOption; + int TotalMemoryBlocks; + int RxBlockNum; + int TotalRxBlockSize; + int TxBlockNum; + int TotalTxBlockSize; + + FN_ENTER; + + /* Let's see if we can follow this: + first we select our memory block size (which I think is + completely arbitrary) */ + MemoryBlockSize.size = cpu_to_le16(adev->memblocksize); + + /* Then we alert the card to our decision of block size */ + if (OK != acx_s_configure(adev, &MemoryBlockSize, ACX100_IE_BLOCK_SIZE)) { + goto bad; + } + + /* We figure out how many total blocks we can create, using + the block size we chose, and the beginning and ending + memory pointers, i.e.: end-start/size */ + TotalMemoryBlocks = (le32_to_cpu(mmt->PoolEnd) - le32_to_cpu(mmt->PoolStart)) / adev->memblocksize; + + log(L_DEBUG, "TotalMemoryBlocks=%u (%u bytes)\n", + TotalMemoryBlocks, TotalMemoryBlocks*adev->memblocksize); + + /* MemoryConfigOption.DMA_config bitmask: + access to ACX memory is to be done: + 0x00080000 using PCI conf space?! + 0x00040000 using IO instructions? + 0x00000000 using memory access instructions + 0x00020000 using local memory block linked list (else what?) + 0x00010000 using host indirect descriptors (else host must access ACX memory?) + */ + if (IS_PCI(adev)) { + MemoryConfigOption.DMA_config = cpu_to_le32(0x30000); + /* Declare start of the Rx host pool */ + MemoryConfigOption.pRxHostDesc = cpu2acx(adev->rxhostdesc_startphy); + log(L_DEBUG, "pRxHostDesc 0x%08X, rxhostdesc_startphy 0x%lX\n", + acx2cpu(MemoryConfigOption.pRxHostDesc), + (long)adev->rxhostdesc_startphy); + } else { + MemoryConfigOption.DMA_config = cpu_to_le32(0x20000); + } + + /* 50% of the allotment of memory blocks go to tx descriptors */ + TxBlockNum = TotalMemoryBlocks / 2; + MemoryConfigOption.TxBlockNum = cpu_to_le16(TxBlockNum); + + /* and 50% go to the rx descriptors */ + RxBlockNum = TotalMemoryBlocks - TxBlockNum; + MemoryConfigOption.RxBlockNum = cpu_to_le16(RxBlockNum); + + /* size of the tx and rx descriptor queues */ + TotalTxBlockSize = TxBlockNum * adev->memblocksize; + TotalRxBlockSize = RxBlockNum * adev->memblocksize; + log(L_DEBUG, "TxBlockNum %u RxBlockNum %u TotalTxBlockSize %u " + "TotalTxBlockSize %u\n", TxBlockNum, RxBlockNum, + TotalTxBlockSize, TotalRxBlockSize); + + + /* align the tx descriptor queue to an alignment of 0x20 (32 bytes) */ + MemoryConfigOption.rx_mem = + cpu_to_le32((le32_to_cpu(mmt->PoolStart) + 0x1f) & ~0x1f); + + /* align the rx descriptor queue to units of 0x20 + * and offset it by the tx descriptor queue */ + MemoryConfigOption.tx_mem = + cpu_to_le32((le32_to_cpu(mmt->PoolStart) + TotalRxBlockSize + 0x1f) & ~0x1f); + log(L_DEBUG, "rx_mem %08X rx_mem %08X\n", + MemoryConfigOption.tx_mem, MemoryConfigOption.rx_mem); + + /* alert the device to our decision */ + if (OK != acx_s_configure(adev, &MemoryConfigOption, ACX1xx_IE_MEMORY_CONFIG_OPTIONS)) { + goto bad; + } + + /* and tell the device to kick it into gear */ + if (OK != acx_s_issue_cmd(adev, ACX100_CMD_INIT_MEMORY, NULL, 0)) { + goto bad; + } + FN_EXIT1(OK); + return OK; +bad: + FN_EXIT1(NOT_OK); + return NOT_OK; +} + + +/*********************************************************************** +** acx100_s_create_dma_regions +** +** Note that this fn messes up heavily with hardware, but we cannot +** lock it (we need to sleep). Not a problem since IRQs can't happen +*/ +static int +acx100_s_create_dma_regions(acx_device_t *adev) +{ + acx100_ie_queueconfig_t queueconf; + acx_ie_memmap_t memmap; + int res = NOT_OK; + u32 tx_queue_start, rx_queue_start; + + FN_ENTER; + + /* read out the acx100 physical start address for the queues */ + if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) { + goto fail; + } + + tx_queue_start = le32_to_cpu(memmap.QueueStart); + rx_queue_start = tx_queue_start + TX_CNT * sizeof(txdesc_t); + + log(L_DEBUG, "initializing Queue Indicator\n"); + + memset(&queueconf, 0, sizeof(queueconf)); + + /* Not needed for PCI, so we can avoid setting them altogether */ + if (IS_USB(adev)) { + queueconf.NumTxDesc = USB_TX_CNT; + queueconf.NumRxDesc = USB_RX_CNT; + } + + /* calculate size of queues */ + queueconf.AreaSize = cpu_to_le32( + TX_CNT * sizeof(txdesc_t) + + RX_CNT * sizeof(rxdesc_t) + 8 + ); + queueconf.NumTxQueues = 1; /* number of tx queues */ + /* sets the beginning of the tx descriptor queue */ + queueconf.TxQueueStart = memmap.QueueStart; + /* done by memset: queueconf.TxQueuePri = 0; */ + queueconf.RxQueueStart = cpu_to_le32(rx_queue_start); + queueconf.QueueOptions = 1; /* auto reset descriptor */ + /* sets the end of the rx descriptor queue */ + queueconf.QueueEnd = cpu_to_le32( + rx_queue_start + RX_CNT * sizeof(rxdesc_t) + ); + /* sets the beginning of the next queue */ + queueconf.HostQueueEnd = cpu_to_le32(le32_to_cpu(queueconf.QueueEnd) + 8); + if (OK != acx_s_configure(adev, &queueconf, ACX1xx_IE_QUEUE_CONFIG)) { + goto fail; + } + + if (IS_PCI(adev)) { + /* sets the beginning of the rx descriptor queue, after the tx descrs */ + if (OK != acxpci_s_create_hostdesc_queues(adev)) + goto fail; + acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start); + } + + if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) { + goto fail; + } + + memmap.PoolStart = cpu_to_le32( + (le32_to_cpu(memmap.QueueEnd) + 4 + 0x1f) & ~0x1f + ); + + if (OK != acx_s_configure(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) { + goto fail; + } + + if (OK != acx100_s_init_memory_pools(adev, &memmap)) { + goto fail; + } + + res = OK; + goto end; + +fail: + acx_s_msleep(1000); /* ? */ + if (IS_PCI(adev)) + acxpci_free_desc_queues(adev); +end: + FN_EXIT1(res); + return res; +} + + +/*********************************************************************** +** acx111_s_create_dma_regions +** +** Note that this fn messes heavily with hardware, but we cannot +** lock it (we need to sleep). Not a problem since IRQs can't happen +*/ +#define ACX111_PERCENT(percent) ((percent)/5) + +static int +acx111_s_create_dma_regions(acx_device_t *adev) +{ + struct acx111_ie_memoryconfig memconf; + struct acx111_ie_queueconfig queueconf; + u32 tx_queue_start, rx_queue_start; + + FN_ENTER; + + /* Calculate memory positions and queue sizes */ + + /* Set up our host descriptor pool + data pool */ + if (IS_PCI(adev)) { + if (OK != acxpci_s_create_hostdesc_queues(adev)) + goto fail; + } + + memset(&memconf, 0, sizeof(memconf)); + /* the number of STAs (STA contexts) to support + ** NB: was set to 1 and everything seemed to work nevertheless... */ + memconf.no_of_stations = cpu_to_le16(VEC_SIZE(adev->sta_list)); + /* specify the memory block size. Default is 256 */ + memconf.memory_block_size = cpu_to_le16(adev->memblocksize); + /* let's use 50%/50% for tx/rx (specify percentage, units of 5%) */ + memconf.tx_rx_memory_block_allocation = ACX111_PERCENT(50); + /* set the count of our queues + ** NB: struct acx111_ie_memoryconfig shall be modified + ** if we ever will switch to more than one rx and/or tx queue */ + memconf.count_rx_queues = 1; + memconf.count_tx_queues = 1; + /* 0 == Busmaster Indirect Memory Organization, which is what we want + * (using linked host descs with their allocated mem). + * 2 == Generic Bus Slave */ + /* done by memset: memconf.options = 0; */ + /* let's use 25% for fragmentations and 75% for frame transfers + * (specified in units of 5%) */ + memconf.fragmentation = ACX111_PERCENT(75); + /* Rx descriptor queue config */ + memconf.rx_queue1_count_descs = RX_CNT; + memconf.rx_queue1_type = 7; /* must be set to 7 */ + /* done by memset: memconf.rx_queue1_prio = 0; low prio */ + if (IS_PCI(adev)) { + memconf.rx_queue1_host_rx_start = cpu2acx(adev->rxhostdesc_startphy); + } + /* Tx descriptor queue config */ + memconf.tx_queue1_count_descs = TX_CNT; + /* done by memset: memconf.tx_queue1_attributes = 0; lowest priority */ + + /* NB1: this looks wrong: (memconf,ACX1xx_IE_QUEUE_CONFIG), + ** (queueconf,ACX1xx_IE_MEMORY_CONFIG_OPTIONS) look swapped, eh? + ** But it is actually correct wrt IE numbers. + ** NB2: sizeof(memconf) == 28 == 0x1c but configure(ACX1xx_IE_QUEUE_CONFIG) + ** writes 0x20 bytes (because same IE for acx100 uses struct acx100_ie_queueconfig + ** which is 4 bytes larger. what a mess. TODO: clean it up) */ + if (OK != acx_s_configure(adev, &memconf, ACX1xx_IE_QUEUE_CONFIG)) { + goto fail; + } + + acx_s_interrogate(adev, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS); + + tx_queue_start = le32_to_cpu(queueconf.tx1_queue_address); + rx_queue_start = le32_to_cpu(queueconf.rx1_queue_address); + + log(L_INIT, "dump queue head (from card):\n" + "len: %u\n" + "tx_memory_block_address: %X\n" + "rx_memory_block_address: %X\n" + "tx1_queue address: %X\n" + "rx1_queue address: %X\n", + le16_to_cpu(queueconf.len), + le32_to_cpu(queueconf.tx_memory_block_address), + le32_to_cpu(queueconf.rx_memory_block_address), + tx_queue_start, + rx_queue_start); + + if (IS_PCI(adev)) + acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start); + + FN_EXIT1(OK); + return OK; +fail: + if (IS_PCI(adev)) + acxpci_free_desc_queues(adev); + + FN_EXIT1(NOT_OK); + return NOT_OK; +} + + +/*********************************************************************** +*/ +static void +acx_s_initialize_rx_config(acx_device_t *adev) +{ + struct { + u16 id; + u16 len; + u16 rx_cfg1; + u16 rx_cfg2; + } ACX_PACKED cfg; + + switch (adev->mode) { + case ACX_MODE_OFF: + adev->rx_config_1 = (u16) (0 + /* | RX_CFG1_INCLUDE_RXBUF_HDR */ + /* | RX_CFG1_FILTER_SSID */ + /* | RX_CFG1_FILTER_BCAST */ + /* | RX_CFG1_RCV_MC_ADDR1 */ + /* | RX_CFG1_RCV_MC_ADDR0 */ + /* | RX_CFG1_FILTER_ALL_MULTI */ + /* | RX_CFG1_FILTER_BSSID */ + /* | RX_CFG1_FILTER_MAC */ + /* | RX_CFG1_RCV_PROMISCUOUS */ + /* | RX_CFG1_INCLUDE_FCS */ + /* | RX_CFG1_INCLUDE_PHY_HDR */ + ); + adev->rx_config_2 = (u16) (0 + /*| RX_CFG2_RCV_ASSOC_REQ */ + /*| RX_CFG2_RCV_AUTH_FRAMES */ + /*| RX_CFG2_RCV_BEACON_FRAMES */ + /*| RX_CFG2_RCV_CONTENTION_FREE */ + /*| RX_CFG2_RCV_CTRL_FRAMES */ + /*| RX_CFG2_RCV_DATA_FRAMES */ + /*| RX_CFG2_RCV_BROKEN_FRAMES */ + /*| RX_CFG2_RCV_MGMT_FRAMES */ + /*| RX_CFG2_RCV_PROBE_REQ */ + /*| RX_CFG2_RCV_PROBE_RESP */ + /*| RX_CFG2_RCV_ACK_FRAMES */ + /*| RX_CFG2_RCV_OTHER */ + ); + break; + case ACX_MODE_MONITOR: + adev->rx_config_1 = (u16) (0 + /* | RX_CFG1_INCLUDE_RXBUF_HDR */ + /* | RX_CFG1_FILTER_SSID */ + /* | RX_CFG1_FILTER_BCAST */ + /* | RX_CFG1_RCV_MC_ADDR1 */ + /* | RX_CFG1_RCV_MC_ADDR0 */ + /* | RX_CFG1_FILTER_ALL_MULTI */ + /* | RX_CFG1_FILTER_BSSID */ + /* | RX_CFG1_FILTER_MAC */ + | RX_CFG1_RCV_PROMISCUOUS + /* | RX_CFG1_INCLUDE_FCS */ + /* | RX_CFG1_INCLUDE_PHY_HDR */ + ); + adev->rx_config_2 = (u16) (0 + | RX_CFG2_RCV_ASSOC_REQ + | RX_CFG2_RCV_AUTH_FRAMES + | RX_CFG2_RCV_BEACON_FRAMES + | RX_CFG2_RCV_CONTENTION_FREE + | RX_CFG2_RCV_CTRL_FRAMES + | RX_CFG2_RCV_DATA_FRAMES + | RX_CFG2_RCV_BROKEN_FRAMES + | RX_CFG2_RCV_MGMT_FRAMES + | RX_CFG2_RCV_PROBE_REQ + | RX_CFG2_RCV_PROBE_RESP + | RX_CFG2_RCV_ACK_FRAMES + | RX_CFG2_RCV_OTHER + ); + break; + default: + adev->rx_config_1 = (u16) (0 + /* | RX_CFG1_INCLUDE_RXBUF_HDR */ + /* | RX_CFG1_FILTER_SSID */ + /* | RX_CFG1_FILTER_BCAST */ + /* | RX_CFG1_RCV_MC_ADDR1 */ + /* | RX_CFG1_RCV_MC_ADDR0 */ + /* | RX_CFG1_FILTER_ALL_MULTI */ + /* | RX_CFG1_FILTER_BSSID */ + | RX_CFG1_FILTER_MAC + /* | RX_CFG1_RCV_PROMISCUOUS */ + /* | RX_CFG1_INCLUDE_FCS */ + /* | RX_CFG1_INCLUDE_PHY_HDR */ + ); + adev->rx_config_2 = (u16) (0 + | RX_CFG2_RCV_ASSOC_REQ + | RX_CFG2_RCV_AUTH_FRAMES + | RX_CFG2_RCV_BEACON_FRAMES + | RX_CFG2_RCV_CONTENTION_FREE + | RX_CFG2_RCV_CTRL_FRAMES + | RX_CFG2_RCV_DATA_FRAMES + /*| RX_CFG2_RCV_BROKEN_FRAMES */ + | RX_CFG2_RCV_MGMT_FRAMES + | RX_CFG2_RCV_PROBE_REQ + | RX_CFG2_RCV_PROBE_RESP + /*| RX_CFG2_RCV_ACK_FRAMES */ + | RX_CFG2_RCV_OTHER + ); + break; + } + adev->rx_config_1 |= RX_CFG1_INCLUDE_RXBUF_HDR; + + if ((adev->rx_config_1 & RX_CFG1_INCLUDE_PHY_HDR) + || (adev->firmware_numver >= 0x02000000)) + adev->phy_header_len = IS_ACX111(adev) ? 8 : 4; + else + adev->phy_header_len = 0; + + log(L_INIT, "setting RXconfig to %04X:%04X\n", + adev->rx_config_1, adev->rx_config_2); + cfg.rx_cfg1 = cpu_to_le16(adev->rx_config_1); + cfg.rx_cfg2 = cpu_to_le16(adev->rx_config_2); + acx_s_configure(adev, &cfg, ACX1xx_IE_RXCONFIG); +} + + +/*********************************************************************** +** acx_s_set_defaults +*/ +void +acx_s_set_defaults(acx_device_t *adev) +{ + unsigned long flags; + + FN_ENTER; + + /* do it before getting settings, prevent bogus channel 0 warning */ + adev->channel = 1; + + /* query some settings from the card. + * NOTE: for some settings, e.g. CCA and ED (ACX100!), an initial + * query is REQUIRED, otherwise the card won't work correctly! */ + adev->get_mask = GETSET_ANTENNA|GETSET_SENSITIVITY|GETSET_STATION_ID|GETSET_REG_DOMAIN; + /* Only ACX100 supports ED and CCA */ + if (IS_ACX100(adev)) + adev->get_mask |= GETSET_CCA|GETSET_ED_THRESH; + + acx_s_update_card_settings(adev); + + acx_lock(adev, flags); + + /* set our global interrupt mask */ + if (IS_PCI(adev)) + acxpci_set_interrupt_mask(adev); + + adev->led_power = 1; /* LED is active on startup */ + adev->brange_max_quality = 60; /* LED blink max quality is 60 */ + adev->brange_time_last_state_change = jiffies; + + /* copy the MAC address we just got from the card + * into our MAC address used during current 802.11 session */ + MAC_COPY(adev->dev_addr, adev->ndev->dev_addr); + MAC_BCAST(adev->ap); + + adev->essid_len = + snprintf(adev->essid, sizeof(adev->essid), "STA%02X%02X%02X", + adev->dev_addr[3], adev->dev_addr[4], adev->dev_addr[5]); + adev->essid_active = 1; + + /* we have a nick field to waste, so why not abuse it + * to announce the driver version? ;-) */ + strncpy(adev->nick, "acx " ACX_RELEASE, IW_ESSID_MAX_SIZE); + + if (IS_PCI(adev)) { /* FIXME: this should be made to apply to USB, too! */ + /* first regulatory domain entry in EEPROM == default reg. domain */ + adev->reg_dom_id = adev->cfgopt_domains.list[0]; + } + + /* 0xffff would be better, but then we won't get a "scan complete" + * interrupt, so our current infrastructure will fail: */ + adev->scan_count = 1; + adev->scan_mode = ACX_SCAN_OPT_ACTIVE; + adev->scan_duration = 100; + adev->scan_probe_delay = 200; + /* reported to break scanning: adev->scan_probe_delay = adev->cfgopt_probe_delay; */ + adev->scan_rate = ACX_SCAN_RATE_1; + + adev->mode = ACX_MODE_2_STA; + adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM; + adev->listen_interval = 100; + adev->beacon_interval = DEFAULT_BEACON_INTERVAL; + adev->dtim_interval = DEFAULT_DTIM_INTERVAL; + + adev->msdu_lifetime = DEFAULT_MSDU_LIFETIME; + + adev->rts_threshold = DEFAULT_RTS_THRESHOLD; + adev->frag_threshold = 2346; + + /* use standard default values for retry limits */ + adev->short_retry = 7; /* max. retries for (short) non-RTS packets */ + adev->long_retry = 4; /* max. retries for long (RTS) packets */ + + adev->preamble_mode = 2; /* auto */ + adev->fallback_threshold = 3; + adev->stepup_threshold = 10; + adev->rate_bcast = RATE111_1; + adev->rate_bcast100 = RATE100_1; + adev->rate_basic = RATE111_1 | RATE111_2; + adev->rate_auto = 1; + if (IS_ACX111(adev)) { + adev->rate_oper = RATE111_ALL; + } else { + adev->rate_oper = RATE111_ACX100_COMPAT; + } + + /* Supported Rates element - the rates here are given in units of + * 500 kbit/s, plus 0x80 added. See 802.11-1999.pdf item 7.3.2.2 */ + acx_l_update_ratevector(adev); + + /* set some more defaults */ + if (IS_ACX111(adev)) { + /* 30mW (15dBm) is default, at least in my acx111 card: */ + adev->tx_level_dbm = 15; + } else { + /* don't use max. level, since it might be dangerous + * (e.g. WRT54G people experience + * excessive Tx power damage!) */ + adev->tx_level_dbm = 18; + } + /* adev->tx_level_auto = 1; */ + if (IS_ACX111(adev)) { + /* start with sensitivity level 1 out of 3: */ + adev->sensitivity = 1; + } + +/* #define ENABLE_POWER_SAVE */ +#ifdef ENABLE_POWER_SAVE + adev->ps_wakeup_cfg = PS_CFG_ENABLE | PS_CFG_WAKEUP_ALL_BEAC; + adev->ps_listen_interval = 1; + adev->ps_options = PS_OPT_ENA_ENHANCED_PS | PS_OPT_TX_PSPOLL | PS_OPT_STILL_RCV_BCASTS; + adev->ps_hangover_period = 30; + adev->ps_enhanced_transition_time = 0; +#else + adev->ps_wakeup_cfg = 0; + adev->ps_listen_interval = 0; + adev->ps_options = 0; + adev->ps_hangover_period = 0; + adev->ps_enhanced_transition_time = 0; +#endif + + /* These settings will be set in fw on ifup */ + adev->set_mask = 0 + | GETSET_RETRY + | SET_MSDU_LIFETIME + /* configure card to do rate fallback when in auto rate mode */ + | SET_RATE_FALLBACK + | SET_RXCONFIG + | GETSET_TXPOWER + /* better re-init the antenna value we got above */ + | GETSET_ANTENNA +#if POWER_SAVE_80211 + | GETSET_POWER_80211 +#endif + ; + + acx_unlock(adev, flags); + acx_lock_unhold(); /* hold time 844814 CPU ticks @2GHz */ + + acx_s_initialize_rx_config(adev); + + FN_EXIT0; +} + + +/*********************************************************************** +** FIXME: this should be solved in a general way for all radio types +** by decoding the radio firmware module, +** since it probably has some standard structure describing how to +** set the power level of the radio module which it controls. +** Or maybe not, since the radio module probably has a function interface +** instead which then manages Tx level programming :-\ +*/ +static int +acx111_s_set_tx_level(acx_device_t *adev, u8 level_dbm) +{ + struct acx111_ie_tx_level tx_level; + + /* my acx111 card has two power levels in its configoptions (== EEPROM): + * 1 (30mW) [15dBm] + * 2 (10mW) [10dBm] + * For now, just assume all other acx111 cards have the same. + * FIXME: Ideally we would query it here, but we first need a + * standard way to query individual configoptions easily. + * Well, now we have proper cfgopt txpower variables, but this still + * hasn't been done yet, since it also requires dBm <-> mW conversion here... */ + if (level_dbm <= 12) { + tx_level.level = 2; /* 10 dBm */ + adev->tx_level_dbm = 10; + } else { + tx_level.level = 1; /* 15 dBm */ + adev->tx_level_dbm = 15; + } + if (level_dbm != adev->tx_level_dbm) + log(L_INIT, "acx111 firmware has specific " + "power levels only: adjusted %d dBm to %d dBm!\n", + level_dbm, adev->tx_level_dbm); + + return acx_s_configure(adev, &tx_level, ACX1xx_IE_DOT11_TX_POWER_LEVEL); +} + +static int +acx_s_set_tx_level(acx_device_t *adev, u8 level_dbm) +{ + if (IS_ACX111(adev)) { + return acx111_s_set_tx_level(adev, level_dbm); + } + if (IS_PCI(adev)) { + return acx100pci_s_set_tx_level(adev, level_dbm); + } + return OK; +} + + +/*********************************************************************** +*/ +#ifdef UNUSED +/* Returns the current tx level (ACX111) */ +static u8 +acx111_s_get_tx_level(acx_device_t *adev) +{ + struct acx111_ie_tx_level tx_level; + + tx_level.level = 0; + acx_s_interrogate(adev, &tx_level, ACX1xx_IE_DOT11_TX_POWER_LEVEL); + return tx_level.level; +} +#endif + + +/*********************************************************************** +** acx_l_rxmonitor +** Called from IRQ context only +*/ +static void +acx_l_rxmonitor(acx_device_t *adev, const rxbuffer_t *rxbuf) +{ + wlansniffrm_t *msg; + struct sk_buff *skb; + void *datap; + unsigned int skb_len; + int payload_offset; + + FN_ENTER; + + /* we are in big luck: the acx100 doesn't modify any of the fields */ + /* in the 802.11 frame. just pass this packet into the PF_PACKET */ + /* subsystem. yeah. */ + payload_offset = ((u8*)acx_get_wlan_hdr(adev, rxbuf) - (u8*)rxbuf); + skb_len = RXBUF_BYTES_USED(rxbuf) - payload_offset; + + /* sanity check */ + if (unlikely(skb_len > WLAN_A4FR_MAXLEN_WEP)) { + printk("%s: monitor mode panic: oversized frame!\n", + adev->ndev->name); + goto end; + } + + if (adev->ndev->type == ARPHRD_IEEE80211_PRISM) + skb_len += sizeof(*msg); + + /* allocate skb */ + skb = dev_alloc_skb(skb_len); + if (unlikely(!skb)) { + printk("%s: no memory for skb (%u bytes)\n", + adev->ndev->name, skb_len); + goto end; + } + + skb_put(skb, skb_len); + + if (adev->ndev->type == ARPHRD_IEEE80211) { + /* when in raw 802.11 mode, just copy frame as-is */ + datap = skb->data; + } else if (adev->ndev->type == ARPHRD_IEEE80211_PRISM) { + /* emulate prism header */ + msg = (wlansniffrm_t*)skb->data; + datap = msg + 1; + + msg->msgcode = WLANSNIFFFRM; + msg->msglen = sizeof(*msg); + strncpy(msg->devname, adev->ndev->name, sizeof(msg->devname)-1); + msg->devname[sizeof(msg->devname)-1] = '\0'; + + msg->hosttime.did = WLANSNIFFFRM_hosttime; + msg->hosttime.status = WLANITEM_STATUS_data_ok; + msg->hosttime.len = 4; + msg->hosttime.data = jiffies; + + msg->mactime.did = WLANSNIFFFRM_mactime; + msg->mactime.status = WLANITEM_STATUS_data_ok; + msg->mactime.len = 4; + msg->mactime.data = rxbuf->time; + + msg->channel.did = WLANSNIFFFRM_channel; + msg->channel.status = WLANITEM_STATUS_data_ok; + msg->channel.len = 4; + msg->channel.data = adev->channel; + + msg->rssi.did = WLANSNIFFFRM_rssi; + msg->rssi.status = WLANITEM_STATUS_no_value; + msg->rssi.len = 4; + msg->rssi.data = 0; + + msg->sq.did = WLANSNIFFFRM_sq; + msg->sq.status = WLANITEM_STATUS_no_value; + msg->sq.len = 4; + msg->sq.data = 0; + + msg->signal.did = WLANSNIFFFRM_signal; + msg->signal.status = WLANITEM_STATUS_data_ok; + msg->signal.len = 4; + msg->signal.data = rxbuf->phy_snr; + + msg->noise.did = WLANSNIFFFRM_noise; + msg->noise.status = WLANITEM_STATUS_data_ok; + msg->noise.len = 4; + msg->noise.data = rxbuf->phy_level; + + msg->rate.did = WLANSNIFFFRM_rate; + msg->rate.status = WLANITEM_STATUS_data_ok; + msg->rate.len = 4; + msg->rate.data = rxbuf->phy_plcp_signal / 5; + + msg->istx.did = WLANSNIFFFRM_istx; + msg->istx.status = WLANITEM_STATUS_data_ok; + msg->istx.len = 4; + msg->istx.data = 0; /* tx=0: it's not a tx packet */ + + skb_len -= sizeof(*msg); + + msg->frmlen.did = WLANSNIFFFRM_signal; + msg->frmlen.status = WLANITEM_STATUS_data_ok; + msg->frmlen.len = 4; + msg->frmlen.data = skb_len; + } else { + printk("acx: unsupported netdev type %d!\n", adev->ndev->type); + dev_kfree_skb(skb); + return; + } + + /* sanity check (keep it here) */ + if (unlikely((int)skb_len < 0)) { + printk("acx: skb_len=%d. Driver bug, please report\n", (int)skb_len); + dev_kfree_skb(skb); + return; + } + memcpy(datap, ((unsigned char*)rxbuf)+payload_offset, skb_len); + + skb->dev = adev->ndev; + skb->dev->last_rx = jiffies; + + skb_reset_mac_header(skb); + skb->ip_summed = CHECKSUM_NONE; + skb->pkt_type = PACKET_OTHERHOST; + skb->protocol = htons(ETH_P_80211_RAW); + netif_rx(skb); + + adev->stats.rx_packets++; + adev->stats.rx_bytes += skb->len; + +end: + FN_EXIT0; +} + + +/*********************************************************************** +** acx_l_rx_ieee802_11_frame +** +** Called from IRQ context only +*/ + +/* All these contortions are for saner dup logging +** +** We want: (a) to know about excessive dups +** (b) to not spam kernel log about occasional dups +** +** 1/64 threshold was chosen by running "ping -A" +** It gave "rx: 59 DUPs in 2878 packets" only with 4 parallel +** "ping -A" streams running. */ +/* 2005-10-11: bumped up to 1/8 +** subtract a $smallint from dup_count in order to +** avoid "2 DUPs in 19 packets" messages */ +static inline int +acx_l_handle_dup(acx_device_t *adev, u16 seq) +{ + if (adev->dup_count) { + adev->nondup_count++; + if (time_after(jiffies, adev->dup_msg_expiry)) { + /* Log only if more than 1 dup in 64 packets */ + if (adev->nondup_count/8 < adev->dup_count-5) { + printk(KERN_INFO "%s: rx: %d DUPs in " + "%d packets received in 10 secs\n", + adev->ndev->name, + adev->dup_count, + adev->nondup_count); + } + adev->dup_count = 0; + adev->nondup_count = 0; + } + } + if (unlikely(seq == adev->last_seq_ctrl)) { + if (!adev->dup_count++) + adev->dup_msg_expiry = jiffies + 10*HZ; + adev->stats.rx_errors++; + return 1; /* a dup */ + } + adev->last_seq_ctrl = seq; + return 0; +} + +static int +acx_l_rx_ieee802_11_frame(acx_device_t *adev, rxbuffer_t *rxbuf) +{ + unsigned int ftype, fstype; + const wlan_hdr_t *hdr; + int result = NOT_OK; + + FN_ENTER; + + hdr = acx_get_wlan_hdr(adev, rxbuf); + + /* see IEEE 802.11-1999.pdf chapter 7 "MAC frame formats" */ + if (unlikely((hdr->fc & WF_FC_PVERi) != 0)) { + printk_ratelimited(KERN_INFO "rx: unsupported 802.11 protocol\n"); + goto end; + } + + ftype = hdr->fc & WF_FC_FTYPEi; + fstype = hdr->fc & WF_FC_FSTYPEi; + + switch (ftype) { + /* check data frames first, for speed */ + case WF_FTYPE_DATAi: + switch (fstype) { + case WF_FSTYPE_DATAONLYi: + if (acx_l_handle_dup(adev, hdr->seq)) + break; /* a dup, simply discard it */ + + /* TODO: + if (WF_FC_FROMTODSi == (hdr->fc & WF_FC_FROMTODSi)) { + result = acx_l_process_data_frame_wds(adev, rxbuf); + break; + } + */ + + switch (adev->mode) { + case ACX_MODE_3_AP: + result = acx_l_process_data_frame_master(adev, rxbuf); + break; + case ACX_MODE_0_ADHOC: + case ACX_MODE_2_STA: + result = acx_l_process_data_frame_client(adev, rxbuf); + break; + } + case WF_FSTYPE_DATA_CFACKi: + case WF_FSTYPE_DATA_CFPOLLi: + case WF_FSTYPE_DATA_CFACK_CFPOLLi: + case WF_FSTYPE_CFPOLLi: + case WF_FSTYPE_CFACK_CFPOLLi: + /* see above. + acx_process_class_frame(adev, rxbuf, 3); */ + break; + case WF_FSTYPE_NULLi: + /* acx_l_process_NULL_frame(adev, rxbuf, 3); */ + break; + /* FIXME: same here, see above */ + case WF_FSTYPE_CFACKi: + default: + break; + } + break; + case WF_FTYPE_MGMTi: + result = acx_l_process_mgmt_frame(adev, rxbuf); + break; + case WF_FTYPE_CTLi: + if (fstype == WF_FSTYPE_PSPOLLi) + result = OK; + /* this call is irrelevant, since + * acx_process_class_frame is a stub, so return + * immediately instead. + * return acx_process_class_frame(adev, rxbuf, 3); */ + break; + default: + break; + } +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_l_process_rxbuf +** +** NB: used by USB code also +*/ +void +acx_l_process_rxbuf(acx_device_t *adev, rxbuffer_t *rxbuf) +{ + struct wlan_hdr *hdr; + unsigned int qual; + int buf_len; + u16 fc; + + hdr = acx_get_wlan_hdr(adev, rxbuf); + fc = le16_to_cpu(hdr->fc); + /* length of frame from control field to first byte of FCS */ + buf_len = RXBUF_BYTES_RCVD(adev, rxbuf); + + if ( ((WF_FC_FSTYPE & fc) != WF_FSTYPE_BEACON) + || (acx_debug & L_XFER_BEACON) + ) { + log(L_XFER|L_DATA, "rx: %s " + "time:%u len:%u signal:%u SNR:%u macstat:%02X " + "phystat:%02X phyrate:%u status:%u\n", + acx_get_packet_type_string(fc), + le32_to_cpu(rxbuf->time), + buf_len, + acx_signal_to_winlevel(rxbuf->phy_level), + acx_signal_to_winlevel(rxbuf->phy_snr), + rxbuf->mac_status, + rxbuf->phy_stat_baseband, + rxbuf->phy_plcp_signal, + adev->status); + } + + if (unlikely(acx_debug & L_DATA)) { + printk("rx: 802.11 buf[%u]: ", buf_len); + acx_dump_bytes(hdr, buf_len); + } + + /* FIXME: should check for Rx errors (rxbuf->mac_status? + * discard broken packets - but NOT for monitor!) + * and update Rx packet statistics here */ + + if (unlikely(adev->mode == ACX_MODE_MONITOR)) { + acx_l_rxmonitor(adev, rxbuf); + } else if (likely(buf_len >= WLAN_HDR_A3_LEN)) { + acx_l_rx_ieee802_11_frame(adev, rxbuf); + } else { + log(L_DEBUG|L_XFER|L_DATA, + "rx: NOT receiving packet (%s): " + "size too small (%u)\n", + acx_get_packet_type_string(fc), + buf_len); + } + + /* Now check Rx quality level, AFTER processing packet. + * I tried to figure out how to map these levels to dBm + * values, but for the life of me I really didn't + * manage to get it. Either these values are not meant to + * be expressed in dBm, or it's some pretty complicated + * calculation. */ + +#ifdef FROM_SCAN_SOURCE_ONLY + /* only consider packets originating from the MAC + * address of the device that's managing our BSSID. + * Disable it for now, since it removes information (levels + * from different peers) and slows the Rx path. */ + if (adev->ap_client + && mac_is_equal(hdr->a2, adev->ap_client->address)) { +#endif + adev->wstats.qual.level = acx_signal_to_winlevel(rxbuf->phy_level); + adev->wstats.qual.noise = acx_signal_to_winlevel(rxbuf->phy_snr); +#ifndef OLD_QUALITY + qual = acx_signal_determine_quality(adev->wstats.qual.level, + adev->wstats.qual.noise); +#else + qual = (adev->wstats.qual.noise <= 100) ? + 100 - adev->wstats.qual.noise : 0; +#endif + adev->wstats.qual.qual = qual; + adev->wstats.qual.updated = 7; /* all 3 indicators updated */ +#ifdef FROM_SCAN_SOURCE_ONLY + } +#endif +} + + +/*********************************************************************** +** acx_l_handle_txrate_auto +** +** Theory of operation: +** client->rate_cap is a bitmask of rates client is capable of. +** client->rate_cfg is a bitmask of allowed (configured) rates. +** It is set as a result of iwconfig rate N [auto] +** or iwpriv set_rates "N,N,N N,N,N" commands. +** It can be fixed (e.g. 0x0080 == 18Mbit only), +** auto (0x00ff == 18Mbit or any lower value), +** and code handles any bitmask (0x1081 == try 54Mbit,18Mbit,1Mbit _only_). +** +** client->rate_cur is a value for rate111 field in tx descriptor. +** It is always set to txrate_cfg sans zero or more most significant +** bits. This routine handles selection of new rate_cur value depending on +** outcome of last tx event. +** +** client->rate_100 is a precalculated rate value for acx100 +** (we can do without it, but will need to calculate it on each tx). +** +** You cannot configure mixed usage of 5.5 and/or 11Mbit rate +** with PBCC and CCK modulation. Either both at CCK or both at PBCC. +** In theory you can implement it, but so far it is considered not worth doing. +** +** 22Mbit, of course, is PBCC always. */ + +/* maps acx100 tx descr rate field to acx111 one */ +static u16 +rate100to111(u8 r) +{ + switch (r) { + case RATE100_1: return RATE111_1; + case RATE100_2: return RATE111_2; + case RATE100_5: + case (RATE100_5 | RATE100_PBCC511): return RATE111_5; + case RATE100_11: + case (RATE100_11 | RATE100_PBCC511): return RATE111_11; + case RATE100_22: return RATE111_22; + default: + printk("acx: unexpected acx100 txrate: %u! " + "Please report\n", r); + return RATE111_1; + } +} + + +void +acx_l_handle_txrate_auto(acx_device_t *adev, struct client *txc, + u16 cur, u8 rate100, u16 rate111, + u8 error, int pkts_to_ignore) +{ + u16 sent_rate; + int slower_rate_was_used; + + /* vda: hmm. current code will do this: + ** 1. send packets at 11 Mbit, stepup++ + ** 2. will try to send at 22Mbit. hardware will see no ACK, + ** retries at 11Mbit, success. code notes that used rate + ** is lower. stepup = 0, fallback++ + ** 3. repeat step 2 fallback_count times. Fall back to + ** 11Mbit. go to step 1. + ** If stepup_count is large (say, 16) and fallback_count + ** is small (3), this wouldn't be too bad wrt throughput */ + + if (unlikely(!cur)) { + printk("acx: BUG! ratemask is empty\n"); + return; /* or else we may lock up the box */ + } + + /* do some preparations, i.e. calculate the one rate that was + * used to send this packet */ + if (IS_ACX111(adev)) { + sent_rate = 1 << highest_bit(rate111 & RATE111_ALL); + } else { + sent_rate = rate100to111(rate100); + } + /* sent_rate has only one bit set now, corresponding to tx rate + * which was used by hardware to tx this particular packet */ + + /* now do the actual auto rate management */ + log(L_XFER, "tx: %sclient=%p/"MACSTR" used=%04X cur=%04X cfg=%04X " + "__=%u/%u ^^=%u/%u\n", + (txc->ignore_count > 0) ? "[IGN] " : "", + txc, MAC(txc->address), sent_rate, cur, txc->rate_cfg, + txc->fallback_count, adev->fallback_threshold, + txc->stepup_count, adev->stepup_threshold + ); + + /* we need to ignore old packets already in the tx queue since + * they use older rate bytes configured before our last rate change, + * otherwise our mechanism will get confused by interpreting old data. + * Do it after logging above */ + if (txc->ignore_count) { + txc->ignore_count--; + return; + } + + /* true only if the only nonzero bit in sent_rate is + ** less significant than highest nonzero bit in cur */ + slower_rate_was_used = ( cur > ((sent_rate<<1)-1) ); + + if (slower_rate_was_used || error) { + txc->stepup_count = 0; + if (++txc->fallback_count <= adev->fallback_threshold) + return; + txc->fallback_count = 0; + + /* clear highest 1 bit in cur */ + sent_rate = RATE111_54; + while (!(cur & sent_rate)) sent_rate >>= 1; + CLEAR_BIT(cur, sent_rate); + if (!cur) /* we can't disable all rates! */ + cur = sent_rate; + log(L_XFER, "tx: falling back to ratemask %04X\n", cur); + + } else { /* there was neither lower rate nor error */ + txc->fallback_count = 0; + if (++txc->stepup_count <= adev->stepup_threshold) + return; + txc->stepup_count = 0; + + /* Sanitize. Sort of not needed, but I dont trust hw that much... + ** what if it can report bogus tx rates sometimes? */ + while (!(cur & sent_rate)) sent_rate >>= 1; + + /* try to find a higher sent_rate that isn't yet in our + * current set, but is an allowed cfg */ + while (1) { + sent_rate <<= 1; + if (sent_rate > txc->rate_cfg) + /* no higher rates allowed by config */ + return; + if (!(cur & sent_rate) && (txc->rate_cfg & sent_rate)) + /* found */ + break; + /* not found, try higher one */ + } + SET_BIT(cur, sent_rate); + log(L_XFER, "tx: stepping up to ratemask %04X\n", cur); + } + + txc->rate_cur = cur; + txc->ignore_count = pkts_to_ignore; + /* calculate acx100 style rate byte if needed */ + if (IS_ACX100(adev)) { + txc->rate_100 = acx_bitpos2rate100[highest_bit(cur)]; + } +} + + +/*********************************************************************** +** acx_i_start_xmit +** +** Called by network core. Can be called outside of process context. +*/ +int +acx_i_start_xmit(struct sk_buff *skb, struct net_device *ndev) +{ + acx_device_t *adev = ndev2adev(ndev); + tx_t *tx; + void *txbuf; + unsigned long flags; + int txresult = NOT_OK; + int len; + + FN_ENTER; + + if (unlikely(!skb)) { + /* indicate success */ + txresult = OK; + goto end_no_unlock; + } + if (unlikely(!adev)) { + goto end_no_unlock; + } + + acx_lock(adev, flags); + + if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) { + goto end; + } + if (unlikely(adev->mode == ACX_MODE_OFF)) { + goto end; + } + if (unlikely(acx_queue_stopped(ndev))) { + log(L_DEBUG, "%s: called when queue stopped\n", __func__); + goto end; + } + if (unlikely(ACX_STATUS_4_ASSOCIATED != adev->status)) { + log(L_XFER, "trying to xmit, but not associated yet: " + "aborting...\n"); + /* silently drop the packet, since we're not connected yet */ + txresult = OK; + /* ...but indicate an error nevertheless */ + adev->stats.tx_errors++; + goto end; + } + + tx = acx_l_alloc_tx(adev); + if (unlikely(!tx)) { + printk_ratelimited("%s: start_xmit: txdesc ring is full, " + "dropping tx\n", ndev->name); + txresult = NOT_OK; + goto end; + } + + txbuf = acx_l_get_txbuf(adev, tx); + if (unlikely(!txbuf)) { + /* Card was removed */ + txresult = NOT_OK; + acx_l_dealloc_tx(adev, tx); + goto end; + } + len = acx_ether_to_txbuf(adev, txbuf, skb); + if (unlikely(len < 0)) { + /* Error in packet conversion */ + txresult = NOT_OK; + acx_l_dealloc_tx(adev, tx); + goto end; + } + acx_l_tx_data(adev, tx, len); + ndev->trans_start = jiffies; + + txresult = OK; + adev->stats.tx_packets++; + adev->stats.tx_bytes += skb->len; + +end: + acx_unlock(adev, flags); + +end_no_unlock: + if ((txresult == OK) && skb) + dev_kfree_skb_any(skb); + + FN_EXIT1(txresult); + return txresult; +} + + +/*********************************************************************** +** acx_l_update_ratevector +** +** Updates adev->rate_supported[_len] according to rate_{basic,oper} +*/ +const u8 +acx_bitpos2ratebyte[] = { + DOT11RATEBYTE_1, + DOT11RATEBYTE_2, + DOT11RATEBYTE_5_5, + DOT11RATEBYTE_6_G, + DOT11RATEBYTE_9_G, + DOT11RATEBYTE_11, + DOT11RATEBYTE_12_G, + DOT11RATEBYTE_18_G, + DOT11RATEBYTE_22, + DOT11RATEBYTE_24_G, + DOT11RATEBYTE_36_G, + DOT11RATEBYTE_48_G, + DOT11RATEBYTE_54_G, +}; + +void +acx_l_update_ratevector(acx_device_t *adev) +{ + u16 bcfg = adev->rate_basic; + u16 ocfg = adev->rate_oper; + u8 *supp = adev->rate_supported; + const u8 *dot11 = acx_bitpos2ratebyte; + + FN_ENTER; + + while (ocfg) { + if (ocfg & 1) { + *supp = *dot11; + if (bcfg & 1) { + *supp |= 0x80; + } + supp++; + } + dot11++; + ocfg >>= 1; + bcfg >>= 1; + } + adev->rate_supported_len = supp - adev->rate_supported; + if (acx_debug & L_ASSOC) { + printk("new ratevector: "); + acx_dump_bytes(adev->rate_supported, adev->rate_supported_len); + } + FN_EXIT0; +} + + +/*********************************************************************** +** acx_l_sta_list_init +*/ +static void +acx_l_sta_list_init(acx_device_t *adev) +{ + FN_ENTER; + memset(adev->sta_hash_tab, 0, sizeof(adev->sta_hash_tab)); + memset(adev->sta_list, 0, sizeof(adev->sta_list)); + FN_EXIT0; +} + + +/*********************************************************************** +** acx_l_sta_list_get_from_hash +*/ +static inline client_t* +acx_l_sta_list_get_from_hash(acx_device_t *adev, const u8 *address) +{ + return adev->sta_hash_tab[address[5] % VEC_SIZE(adev->sta_hash_tab)]; +} + + +/*********************************************************************** +** acx_l_sta_list_get +*/ +client_t* +acx_l_sta_list_get(acx_device_t *adev, const u8 *address) +{ + client_t *client; + FN_ENTER; + client = acx_l_sta_list_get_from_hash(adev, address); + while (client) { + if (mac_is_equal(address, client->address)) { + client->mtime = jiffies; + break; + } + client = client->next; + } + FN_EXIT0; + return client; +} + + +/*********************************************************************** +** acx_l_sta_list_del +*/ +void +acx_l_sta_list_del(acx_device_t *adev, client_t *victim) +{ + client_t *client, *next; + + client = acx_l_sta_list_get_from_hash(adev, victim->address); + next = client; + /* tricky. next = client on first iteration only, + ** on all other iters next = client->next */ + while (next) { + if (next == victim) { + client->next = victim->next; + /* Overkill */ + memset(victim, 0, sizeof(*victim)); + break; + } + client = next; + next = client->next; + } +} + + +/*********************************************************************** +** acx_l_sta_list_alloc +** +** Never fails - will evict oldest client if needed +*/ +static client_t* +acx_l_sta_list_alloc(acx_device_t *adev) +{ + int i; + unsigned long age, oldest_age; + client_t *client, *oldest; + + FN_ENTER; + + oldest = &adev->sta_list[0]; + oldest_age = 0; + for (i = 0; i < VEC_SIZE(adev->sta_list); i++) { + client = &adev->sta_list[i]; + + if (!client->used) { + goto found; + } else { + age = jiffies - client->mtime; + if (oldest_age < age) { + oldest_age = age; + oldest = client; + } + } + } + acx_l_sta_list_del(adev, oldest); + client = oldest; +found: + memset(client, 0, sizeof(*client)); + FN_EXIT0; + return client; +} + + +/*********************************************************************** +** acx_l_sta_list_add +** +** Never fails - will evict oldest client if needed +*/ +/* In case we will reimplement it differently... */ +#define STA_LIST_ADD_CAN_FAIL 0 + +static client_t* +acx_l_sta_list_add(acx_device_t *adev, const u8 *address) +{ + client_t *client; + int index; + + FN_ENTER; + + client = acx_l_sta_list_alloc(adev); + + client->mtime = jiffies; + MAC_COPY(client->address, address); + client->used = CLIENT_EXIST_1; + client->auth_alg = WLAN_AUTH_ALG_SHAREDKEY; + client->auth_step = 1; + /* give some tentative peer rate values + ** (needed because peer may do auth without probing us first, + ** thus we'll have no idea of peer's ratevector yet). + ** Will be overwritten by scanning or assoc code */ + client->rate_cap = adev->rate_basic; + client->rate_cfg = adev->rate_basic; + client->rate_cur = 1 << lowest_bit(adev->rate_basic); + + index = address[5] % VEC_SIZE(adev->sta_hash_tab); + client->next = adev->sta_hash_tab[index]; + adev->sta_hash_tab[index] = client; + + acxlog_mac(L_ASSOC, "sta_list_add: sta=", address, "\n"); + + FN_EXIT0; + return client; +} + + +/*********************************************************************** +** acx_l_sta_list_get_or_add +** +** Never fails - will evict oldest client if needed +*/ +static client_t* +acx_l_sta_list_get_or_add(acx_device_t *adev, const u8 *address) +{ + client_t *client = acx_l_sta_list_get(adev, address); + if (!client) + client = acx_l_sta_list_add(adev, address); + return client; +} + + +/*********************************************************************** +** acx_set_status +** +** This function is called in many atomic regions, must not sleep +** +** This function does not need locking UNLESS you call it +** as acx_set_status(ACX_STATUS_4_ASSOCIATED), bacause this can +** wake queue. This can race with stop_queue elsewhere. +** See acx_stop_queue comment. */ +void +acx_set_status(acx_device_t *adev, u16 new_status) +{ +#define QUEUE_OPEN_AFTER_ASSOC 1 /* this really seems to be needed now */ + u16 old_status = adev->status; + + FN_ENTER; + + log(L_ASSOC, "%s(%d):%s\n", + __func__, new_status, acx_get_status_name(new_status)); + + /* wireless_send_event never sleeps */ + if (ACX_STATUS_4_ASSOCIATED == new_status) { + union iwreq_data wrqu; + + wrqu.data.length = 0; + wrqu.data.flags = 0; + wireless_send_event(adev->ndev, SIOCGIWSCAN, &wrqu, NULL); + + wrqu.data.length = 0; + wrqu.data.flags = 0; + MAC_COPY(wrqu.ap_addr.sa_data, adev->bssid); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + wireless_send_event(adev->ndev, SIOCGIWAP, &wrqu, NULL); + } else { + union iwreq_data wrqu; + + /* send event with empty BSSID to indicate we're not associated */ + MAC_ZERO(wrqu.ap_addr.sa_data); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + wireless_send_event(adev->ndev, SIOCGIWAP, &wrqu, NULL); + } + + adev->status = new_status; + + switch (new_status) { + case ACX_STATUS_1_SCANNING: + adev->scan_retries = 0; + /* 1.0 s initial scan time */ + acx_set_timer(adev, 1000000); + break; + case ACX_STATUS_2_WAIT_AUTH: + case ACX_STATUS_3_AUTHENTICATED: + adev->auth_or_assoc_retries = 0; + acx_set_timer(adev, 1500000); /* 1.5 s */ + break; + } + +#if QUEUE_OPEN_AFTER_ASSOC + if (new_status == ACX_STATUS_4_ASSOCIATED) { + if (old_status < ACX_STATUS_4_ASSOCIATED) { + /* ah, we're newly associated now, + * so let's indicate carrier */ + acx_carrier_on(adev->ndev, "after association"); + acx_wake_queue(adev->ndev, "after association"); + } + } else { + /* not associated any more, so let's kill carrier */ + if (old_status >= ACX_STATUS_4_ASSOCIATED) { + acx_carrier_off(adev->ndev, "after losing association"); + acx_stop_queue(adev->ndev, "after losing association"); + } + } +#endif + FN_EXIT0; +} + + +/*********************************************************************** +** acx_i_timer +** +** Fires up periodically. Used to kick scan/auth/assoc if something goes wrong +*/ +void +acx_i_timer(unsigned long address) +{ + unsigned long flags; + acx_device_t *adev = (acx_device_t*)address; + + FN_ENTER; + + acx_lock(adev, flags); + + log(L_DEBUG|L_ASSOC, "%s: adev->status=%d (%s)\n", + __func__, adev->status, acx_get_status_name(adev->status)); + + switch (adev->status) { + case ACX_STATUS_1_SCANNING: + /* was set to 0 by set_status() */ + if (++adev->scan_retries < 7) { + acx_set_timer(adev, 1000000); + /* used to interrogate for scan status. + ** We rely on SCAN_COMPLETE IRQ instead */ + log(L_ASSOC, "continuing scan (%d sec)\n", + adev->scan_retries); + } else { + log(L_ASSOC, "stopping scan\n"); + /* send stop_scan cmd when we leave the interrupt context, + * and make a decision what to do next (COMPLETE_SCAN) */ + acx_schedule_task(adev, + ACX_AFTER_IRQ_CMD_STOP_SCAN + ACX_AFTER_IRQ_COMPLETE_SCAN); + } + break; + case ACX_STATUS_2_WAIT_AUTH: + /* was set to 0 by set_status() */ + if (++adev->auth_or_assoc_retries < 10) { + log(L_ASSOC, "resend authen1 request (attempt %d)\n", + adev->auth_or_assoc_retries + 1); + acx_l_transmit_authen1(adev); + } else { + /* time exceeded: fall back to scanning mode */ + log(L_ASSOC, + "authen1 request reply timeout, giving up\n"); + /* we are a STA, need to find AP anyhow */ + acx_set_status(adev, ACX_STATUS_1_SCANNING); + acx_schedule_task(adev, ACX_AFTER_IRQ_RESTART_SCAN); + } + /* used to be 1500000, but some other driver uses 2.5s */ + acx_set_timer(adev, 2500000); + break; + case ACX_STATUS_3_AUTHENTICATED: + /* was set to 0 by set_status() */ + if (++adev->auth_or_assoc_retries < 10) { + log(L_ASSOC, "resend assoc request (attempt %d)\n", + adev->auth_or_assoc_retries + 1); + acx_l_transmit_assoc_req(adev); + } else { + /* time exceeded: give up */ + log(L_ASSOC, + "association request reply timeout, giving up\n"); + /* we are a STA, need to find AP anyhow */ + acx_set_status(adev, ACX_STATUS_1_SCANNING); + acx_schedule_task(adev, ACX_AFTER_IRQ_RESTART_SCAN); + } + acx_set_timer(adev, 2500000); /* see above */ + break; + case ACX_STATUS_4_ASSOCIATED: + default: + break; + } + + acx_unlock(adev, flags); + + FN_EXIT0; +} + + +/*********************************************************************** +** acx_set_timer +** +** Sets the 802.11 state management timer's timeout. +*/ +void +acx_set_timer(acx_device_t *adev, int timeout_us) +{ + FN_ENTER; + + log(L_DEBUG|L_IRQ, "%s(%u ms)\n", __func__, timeout_us/1000); + if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) { + printk("attempt to set the timer " + "when the card interface is not up!\n"); + goto end; + } + + /* first check if the timer was already initialized, THEN modify it */ + if (adev->mgmt_timer.function) { + mod_timer(&adev->mgmt_timer, + jiffies + (timeout_us * HZ / 1000000)); + } +end: + FN_EXIT0; +} + + +/*********************************************************************** +** acx_l_transmit_assocresp +** +** We are an AP here +*/ +static const u8 +dot11ratebyte[] = { + DOT11RATEBYTE_1, + DOT11RATEBYTE_2, + DOT11RATEBYTE_5_5, + DOT11RATEBYTE_6_G, + DOT11RATEBYTE_9_G, + DOT11RATEBYTE_11, + DOT11RATEBYTE_12_G, + DOT11RATEBYTE_18_G, + DOT11RATEBYTE_22, + DOT11RATEBYTE_24_G, + DOT11RATEBYTE_36_G, + DOT11RATEBYTE_48_G, + DOT11RATEBYTE_54_G, +}; + +static inline int +find_pos(const u8 *p, int size, u8 v) +{ + int i; + for (i = 0; i < size; i++) + if (p[i] == v) + return i; + /* printk a message about strange byte? */ + return 0; +} + +static void +add_bits_to_ratemasks(u8* ratevec, int len, u16* brate, u16* orate) +{ + while (len--) { + int n = 1 << find_pos(dot11ratebyte, + sizeof(dot11ratebyte), *ratevec & 0x7f); + if (*ratevec & 0x80) + *brate |= n; + *orate |= n; + ratevec++; + } +} + +static int +acx_l_transmit_assocresp(acx_device_t *adev, const wlan_fr_assocreq_t *req) +{ + struct tx *tx; + struct wlan_hdr_mgmt *head; + struct assocresp_frame_body *body; + u8 *p; + const u8 *da; + /* const u8 *sa; */ + const u8 *bssid; + client_t *clt; + + FN_ENTER; + + /* sa = req->hdr->a1; */ + da = req->hdr->a2; + bssid = req->hdr->a3; + + clt = acx_l_sta_list_get(adev, da); + if (!clt) + goto ok; + + /* Assoc without auth is a big no-no */ + /* Let's be liberal: if already assoc'ed STA sends assoc req again, + ** we won't be rude */ + if (clt->used != CLIENT_AUTHENTICATED_2 + && clt->used != CLIENT_ASSOCIATED_3) { + acx_l_transmit_deauthen(adev, da, WLAN_MGMT_REASON_CLASS2_NONAUTH); + goto bad; + } + + clt->used = CLIENT_ASSOCIATED_3; + + if (clt->aid == 0) + clt->aid = ++adev->aid; + clt->cap_info = ieee2host16(*(req->cap_info)); + + /* We cheat here a bit. We don't really care which rates are flagged + ** as basic by the client, so we stuff them in single ratemask */ + clt->rate_cap = 0; + if (req->supp_rates) + add_bits_to_ratemasks(req->supp_rates->rates, + req->supp_rates->len, &clt->rate_cap, &clt->rate_cap); + if (req->ext_rates) + add_bits_to_ratemasks(req->ext_rates->rates, + req->ext_rates->len, &clt->rate_cap, &clt->rate_cap); + /* We can check that client supports all basic rates, + ** and deny assoc if not. But let's be liberal, right? ;) */ + clt->rate_cfg = clt->rate_cap & adev->rate_oper; + if (!clt->rate_cfg) clt->rate_cfg = 1 << lowest_bit(adev->rate_oper); + clt->rate_cur = 1 << lowest_bit(clt->rate_cfg); + if (IS_ACX100(adev)) + clt->rate_100 = acx_bitpos2rate100[lowest_bit(clt->rate_cfg)]; + clt->fallback_count = clt->stepup_count = 0; + clt->ignore_count = 16; + + tx = acx_l_alloc_tx(adev); + if (!tx) + goto bad; + head = acx_l_get_txbuf(adev, tx); + if (!head) { + acx_l_dealloc_tx(adev, tx); + goto bad; + } + body = (void*)(head + 1); + + head->fc = WF_FSTYPE_ASSOCRESPi; + head->dur = req->hdr->dur; + MAC_COPY(head->da, da); + MAC_COPY(head->sa, adev->dev_addr); + MAC_COPY(head->bssid, bssid); + head->seq = req->hdr->seq; + + body->cap_info = host2ieee16(adev->capabilities); + body->status = host2ieee16(0); + body->aid = host2ieee16(clt->aid); + p = wlan_fill_ie_rates((u8*)&body->rates, adev->rate_supported_len, + adev->rate_supported); + p = wlan_fill_ie_rates_ext(p, adev->rate_supported_len, + adev->rate_supported); + + acx_l_tx_data(adev, tx, p - (u8*)head); +ok: + FN_EXIT1(OK); + return OK; +bad: + FN_EXIT1(NOT_OK); + return NOT_OK; +} + + +/*********************************************************************** +* acx_l_transmit_reassocresp + +You may be wondering, just like me, what the hell ReAuth is. +In practice it was seen sent by STA when STA feels like losing connection. + +[802.11] + +5.4.2.3 Reassociation + +Association is sufficient for no-transition message delivery between +IEEE 802.11 stations. Additional functionality is needed to support +BSS-transition mobility. The additional required functionality +is provided by the reassociation service. Reassociation is a DSS. +The reassociation service is invoked to 'move' a current association +from one AP to another. This keeps the DS informed of the current +mapping between AP and STA as the station moves from BSS to BSS within +an ESS. Reassociation also enables changing association attributes +of an established association while the STA remains associated with +the same AP. Reassociation is always initiated by the mobile STA. + +5.4.3.1 Authentication +... +A STA may be authenticated with many other STAs at any given instant. + +5.4.3.1.1 Preauthentication + +Because the authentication process could be time-consuming (depending +on the authentication protocol in use), the authentication service can +be invoked independently of the association service. Preauthentication +is typically done by a STA while it is already associated with an AP +(with which it previously authenticated). IEEE 802.11 does not require +that STAs preauthenticate with APs. However, authentication is required +before an association can be established. If the authentication is left +until reassociation time, this may impact the speed with which a STA can +reassociate between APs, limiting BSS-transition mobility performance. +The use of preauthentication takes the authentication service overhead +out of the time-critical reassociation process. + +5.7.3 Reassociation + +For a STA to reassociate, the reassociation service causes the following +message to occur: + + Reassociation request + +* Message type: Management +* Message subtype: Reassociation request +* Information items: + - IEEE address of the STA + - IEEE address of the AP with which the STA will reassociate + - IEEE address of the AP with which the STA is currently associated + - ESSID +* Direction of message: From STA to 'new' AP + +The address of the current AP is included for efficiency. The inclusion +of the current AP address facilitates MAC reassociation to be independent +of the DS implementation. + + Reassociation response +* Message type: Management +* Message subtype: Reassociation response +* Information items: + - Result of the requested reassociation. (success/failure) + - If the reassociation is successful, the response shall include the AID. +* Direction of message: From AP to STA + +7.2.3.6 Reassociation Request frame format + +The frame body of a management frame of subtype Reassociation Request +contains the information shown in Table 9. + +Table 9 Reassociation Request frame body +Order Information +1 Capability information +2 Listen interval +3 Current AP address +4 SSID +5 Supported rates + +7.2.3.7 Reassociation Response frame format + +The frame body of a management frame of subtype Reassociation Response +contains the information shown in Table 10. + +Table 10 Reassociation Response frame body +Order Information +1 Capability information +2 Status code +3 Association ID (AID) +4 Supported rates + +*/ +static int +acx_l_transmit_reassocresp(acx_device_t *adev, const wlan_fr_reassocreq_t *req) +{ + struct tx *tx; + struct wlan_hdr_mgmt *head; + struct reassocresp_frame_body *body; + u8 *p; + const u8 *da; + /* const u8 *sa; */ + const u8 *bssid; + client_t *clt; + + FN_ENTER; + + /* sa = req->hdr->a1; */ + da = req->hdr->a2; + bssid = req->hdr->a3; + + /* Must be already authenticated, so it must be in the list */ + clt = acx_l_sta_list_get(adev, da); + if (!clt) + goto ok; + + /* Assoc without auth is a big no-no */ + /* Already assoc'ed STAs sending ReAssoc req are ok per 802.11 */ + if (clt->used != CLIENT_AUTHENTICATED_2 + && clt->used != CLIENT_ASSOCIATED_3) { + acx_l_transmit_deauthen(adev, da, WLAN_MGMT_REASON_CLASS2_NONAUTH); + goto bad; + } + + clt->used = CLIENT_ASSOCIATED_3; + if (clt->aid == 0) { + clt->aid = ++adev->aid; + } + if (req->cap_info) + clt->cap_info = ieee2host16(*(req->cap_info)); + + /* We cheat here a bit. We don't really care which rates are flagged + ** as basic by the client, so we stuff them in single ratemask */ + clt->rate_cap = 0; + if (req->supp_rates) + add_bits_to_ratemasks(req->supp_rates->rates, + req->supp_rates->len, &clt->rate_cap, &clt->rate_cap); + if (req->ext_rates) + add_bits_to_ratemasks(req->ext_rates->rates, + req->ext_rates->len, &clt->rate_cap, &clt->rate_cap); + /* We can check that client supports all basic rates, + ** and deny assoc if not. But let's be liberal, right? ;) */ + clt->rate_cfg = clt->rate_cap & adev->rate_oper; + if (!clt->rate_cfg) clt->rate_cfg = 1 << lowest_bit(adev->rate_oper); + clt->rate_cur = 1 << lowest_bit(clt->rate_cfg); + if (IS_ACX100(adev)) + clt->rate_100 = acx_bitpos2rate100[lowest_bit(clt->rate_cfg)]; + + clt->fallback_count = clt->stepup_count = 0; + clt->ignore_count = 16; + + tx = acx_l_alloc_tx(adev); + if (!tx) + goto ok; + head = acx_l_get_txbuf(adev, tx); + if (!head) { + acx_l_dealloc_tx(adev, tx); + goto ok; + } + body = (void*)(head + 1); + + head->fc = WF_FSTYPE_REASSOCRESPi; + head->dur = req->hdr->dur; + MAC_COPY(head->da, da); + MAC_COPY(head->sa, adev->dev_addr); + MAC_COPY(head->bssid, bssid); + head->seq = req->hdr->seq; + + /* IEs: 1. caps */ + body->cap_info = host2ieee16(adev->capabilities); + /* 2. status code */ + body->status = host2ieee16(0); + /* 3. AID */ + body->aid = host2ieee16(clt->aid); + /* 4. supp rates */ + p = wlan_fill_ie_rates((u8*)&body->rates, adev->rate_supported_len, + adev->rate_supported); + /* 5. ext supp rates */ + p = wlan_fill_ie_rates_ext(p, adev->rate_supported_len, + adev->rate_supported); + + acx_l_tx_data(adev, tx, p - (u8*)head); +ok: + FN_EXIT1(OK); + return OK; +bad: + FN_EXIT1(NOT_OK); + return NOT_OK; +} + + +/*********************************************************************** +** acx_l_process_disassoc_from_sta +*/ +static void +acx_l_process_disassoc_from_sta(acx_device_t *adev, const wlan_fr_disassoc_t *req) +{ + const u8 *ta; + client_t *clt; + + FN_ENTER; + + ta = req->hdr->a2; + clt = acx_l_sta_list_get(adev, ta); + if (!clt) + goto end; + + if (clt->used != CLIENT_ASSOCIATED_3 + && clt->used != CLIENT_AUTHENTICATED_2) { + /* it's disassociating, but it's + ** not even authenticated! Let it know that */ + acxlog_mac(L_ASSOC|L_XFER, "peer ", ta, "has sent disassoc " + "req but it is not even auth'ed! sending deauth\n"); + acx_l_transmit_deauthen(adev, ta, + WLAN_MGMT_REASON_CLASS2_NONAUTH); + clt->used = CLIENT_EXIST_1; + } else { + /* mark it as auth'ed only */ + clt->used = CLIENT_AUTHENTICATED_2; + } +end: + FN_EXIT0; +} + + +/*********************************************************************** +** acx_l_process_deauthen_from_sta +*/ +static void +acx_l_process_deauth_from_sta(acx_device_t *adev, const wlan_fr_deauthen_t *req) +{ + const wlan_hdr_t *hdr; + client_t *client; + + FN_ENTER; + + hdr = req->hdr; + + if (acx_debug & L_ASSOC) { + acx_print_mac("got deauth from sta:", hdr->a2, " "); + acx_print_mac("a1:", hdr->a1, " "); + acx_print_mac("a3:", hdr->a3, " "); + acx_print_mac("adev->addr:", adev->dev_addr, " "); + acx_print_mac("adev->bssid:", adev->bssid, "\n"); + } + + if (!mac_is_equal(adev->dev_addr, hdr->a1)) { + goto end; + } + + client = acx_l_sta_list_get(adev, hdr->a2); + if (!client) { + goto end; + } + client->used = CLIENT_EXIST_1; +end: + FN_EXIT0; +} + + +/*********************************************************************** +** acx_l_process_disassoc_from_ap +*/ +static void +acx_l_process_disassoc_from_ap(acx_device_t *adev, const wlan_fr_disassoc_t *req) +{ + FN_ENTER; + + if (!adev->ap_client) { + /* Hrm, we aren't assoc'ed yet anyhow... */ + goto end; + } + + printk("%s: got disassoc frame with reason %d (%s)\n", + adev->ndev->name, *req->reason, + acx_wlan_reason_str(*req->reason)); + + if (mac_is_equal(adev->dev_addr, req->hdr->a1)) { + acx_l_transmit_deauthen(adev, adev->bssid, + WLAN_MGMT_REASON_DEAUTH_LEAVING); + SET_BIT(adev->set_mask, GETSET_RESCAN); + acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG); + } +end: + FN_EXIT0; +} + + +/*********************************************************************** +** acx_l_process_deauth_from_ap +*/ +static void +acx_l_process_deauth_from_ap(acx_device_t *adev, const wlan_fr_deauthen_t *req) +{ + FN_ENTER; + + if (!adev->ap_client) { + /* Hrm, we aren't assoc'ed yet anyhow... */ + goto end; + } + + printk("%s: got deauth frame with reason %d (%s)\n", + adev->ndev->name, *req->reason, + acx_wlan_reason_str(*req->reason)); + + /* Chk: is ta verified to be from our AP? */ + if (mac_is_equal(adev->dev_addr, req->hdr->a1)) { + log(L_DEBUG, "AP sent us deauth packet\n"); + SET_BIT(adev->set_mask, GETSET_RESCAN); + acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG); + } +end: + FN_EXIT0; +} + + +/*********************************************************************** +** acx_l_rx +** +** The end of the Rx path. Pulls data from a rxhostdesc into a socket +** buffer and feeds it to the network stack via netif_rx(). +*/ +static void +acx_l_rx(acx_device_t *adev, rxbuffer_t *rxbuf) +{ + FN_ENTER; + if (likely(adev->dev_state_mask & ACX_STATE_IFACE_UP)) { + struct sk_buff *skb; + skb = acx_rxbuf_to_ether(adev, rxbuf); + if (likely(skb)) { + netif_rx(skb); + adev->ndev->last_rx = jiffies; + adev->stats.rx_packets++; + adev->stats.rx_bytes += skb->len; + } + } + FN_EXIT0; +} + + +/*********************************************************************** +** acx_l_process_data_frame_master +*/ +static int +acx_l_process_data_frame_master(acx_device_t *adev, rxbuffer_t *rxbuf) +{ + struct wlan_hdr *hdr; + struct tx *tx; + void *txbuf; + int len; + int result = NOT_OK; + + FN_ENTER; + + hdr = acx_get_wlan_hdr(adev, rxbuf); + + switch (WF_FC_FROMTODSi & hdr->fc) { + case 0: + case WF_FC_FROMDSi: + log(L_DEBUG, "ap->sta or adhoc->adhoc data frame ignored\n"); + goto done; + case WF_FC_TODSi: + break; + default: /* WF_FC_FROMTODSi */ + log(L_DEBUG, "wds data frame ignored (TODO)\n"); + goto done; + } + + /* check if it is our BSSID, if not, leave */ + if (!mac_is_equal(adev->bssid, hdr->a1)) { + goto done; + } + + if (mac_is_equal(adev->dev_addr, hdr->a3)) { + /* this one is for us */ + acx_l_rx(adev, rxbuf); + } else { + if (mac_is_bcast(hdr->a3)) { + /* this one is bcast, rx it too */ + acx_l_rx(adev, rxbuf); + } + tx = acx_l_alloc_tx(adev); + if (!tx) { + goto fail; + } + /* repackage, tx, and hope it someday reaches its destination */ + /* order is important, we do it in-place */ + MAC_COPY(hdr->a1, hdr->a3); + MAC_COPY(hdr->a3, hdr->a2); + MAC_COPY(hdr->a2, adev->bssid); + /* To_DS = 0, From_DS = 1 */ + hdr->fc = WF_FC_FROMDSi + WF_FTYPE_DATAi; + + txbuf = acx_l_get_txbuf(adev, tx); + if (txbuf) { + len = RXBUF_BYTES_RCVD(adev, rxbuf); + memcpy(txbuf, hdr, len); + acx_l_tx_data(adev, tx, len); + } else { + acx_l_dealloc_tx(adev, tx); + } + } +done: + result = OK; +fail: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_l_process_data_frame_client +*/ +static int +acx_l_process_data_frame_client(acx_device_t *adev, rxbuffer_t *rxbuf) +{ + const u8 *da, *bssid; + const wlan_hdr_t *hdr; + struct net_device *ndev = adev->ndev; + int result = NOT_OK; + + FN_ENTER; + + if (ACX_STATUS_4_ASSOCIATED != adev->status) + goto drop; + + hdr = acx_get_wlan_hdr(adev, rxbuf); + + switch (WF_FC_FROMTODSi & hdr->fc) { + case 0: + if (adev->mode != ACX_MODE_0_ADHOC) { + log(L_DEBUG, "adhoc->adhoc data frame ignored\n"); + goto drop; + } + bssid = hdr->a3; + break; + case WF_FC_FROMDSi: + if (adev->mode != ACX_MODE_2_STA) { + log(L_DEBUG, "ap->sta data frame ignored\n"); + goto drop; + } + bssid = hdr->a2; + break; + case WF_FC_TODSi: + log(L_DEBUG, "sta->ap data frame ignored\n"); + goto drop; + default: /* WF_FC_FROMTODSi: wds->wds */ + log(L_DEBUG, "wds data frame ignored (todo)\n"); + goto drop; + } + + da = hdr->a1; + + if (unlikely(acx_debug & L_DEBUG)) { + acx_print_mac("rx: da=", da, ""); + acx_print_mac(" bssid=", bssid, ""); + acx_print_mac(" adev->bssid=", adev->bssid, ""); + acx_print_mac(" adev->addr=", adev->dev_addr, "\n"); + } + + /* promiscuous mode --> receive all packets */ + if (unlikely(ndev->flags & IFF_PROMISC)) + goto process; + + /* FIRST, check if it is our BSSID */ + if (!mac_is_equal(adev->bssid, bssid)) { + /* is not our BSSID, so bail out */ + goto drop; + } + + /* then, check if it is our address */ + if (mac_is_equal(adev->dev_addr, da)) { + goto process; + } + + /* then, check if it is broadcast */ + if (mac_is_bcast(da)) { + goto process; + } + + if (mac_is_mcast(da)) { + /* unconditionally receive all multicasts */ + if (ndev->flags & IFF_ALLMULTI) + goto process; + + /* FIXME: need to check against the list of + * multicast addresses that are configured + * for the interface (ifconfig) */ + log(L_XFER, "FIXME: multicast packet, need to check " + "against a list of multicast addresses " + "(to be created!); accepting packet for now\n"); + /* for now, just accept it here */ + goto process; + } + + log(L_DEBUG, "rx: foreign packet, dropping\n"); + goto drop; +process: + /* receive packet */ + acx_l_rx(adev, rxbuf); + + result = OK; +drop: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_l_process_mgmt_frame +** +** Theory of operation: mgmt packet gets parsed (to make it easy +** to access variable-sized IEs), results stored in 'parsed'. +** Then we react to the packet. +*/ +typedef union parsed_mgmt_req { + wlan_fr_mgmt_t mgmt; + wlan_fr_assocreq_t assocreq; + wlan_fr_reassocreq_t reassocreq; + wlan_fr_assocresp_t assocresp; + wlan_fr_reassocresp_t reassocresp; + wlan_fr_beacon_t beacon; + wlan_fr_disassoc_t disassoc; + wlan_fr_authen_t authen; + wlan_fr_deauthen_t deauthen; + wlan_fr_proberesp_t proberesp; +} parsed_mgmt_req_t; + +void BUG_excessive_stack_usage(void); + +static int +acx_l_process_mgmt_frame(acx_device_t *adev, rxbuffer_t *rxbuf) +{ + parsed_mgmt_req_t parsed; /* takes ~100 bytes of stack */ + wlan_hdr_t *hdr; + int adhoc, sta_scan, sta, ap; + int len; + + if (sizeof(parsed) > 256) + BUG_excessive_stack_usage(); + + FN_ENTER; + + hdr = acx_get_wlan_hdr(adev, rxbuf); + + /* Management frames never have these set */ + if (WF_FC_FROMTODSi & hdr->fc) { + FN_EXIT1(NOT_OK); + return NOT_OK; + } + + len = RXBUF_BYTES_RCVD(adev, rxbuf); + if (WF_FC_ISWEPi & hdr->fc) + len -= 0x10; + + adhoc = (adev->mode == ACX_MODE_0_ADHOC); + sta_scan = ((adev->mode == ACX_MODE_2_STA) + && (adev->status != ACX_STATUS_4_ASSOCIATED)); + sta = ((adev->mode == ACX_MODE_2_STA) + && (adev->status == ACX_STATUS_4_ASSOCIATED)); + ap = (adev->mode == ACX_MODE_3_AP); + + switch (WF_FC_FSTYPEi & hdr->fc) { + /* beacons first, for speed */ + case WF_FSTYPE_BEACONi: + memset(&parsed.beacon, 0, sizeof(parsed.beacon)); + parsed.beacon.hdr = hdr; + parsed.beacon.len = len; + if (acx_debug & L_DATA) { + printk("beacon len:%d fc:%04X dur:%04X seq:%04X", + len, hdr->fc, hdr->dur, hdr->seq); + acx_print_mac(" a1:", hdr->a1, ""); + acx_print_mac(" a2:", hdr->a2, ""); + acx_print_mac(" a3:", hdr->a3, "\n"); + } + wlan_mgmt_decode_beacon(&parsed.beacon); + /* beacon and probe response are very similar, so... */ + acx_l_process_probe_response(adev, &parsed.beacon, rxbuf); + break; + case WF_FSTYPE_ASSOCREQi: + if (!ap) + break; + memset(&parsed.assocreq, 0, sizeof(parsed.assocreq)); + parsed.assocreq.hdr = hdr; + parsed.assocreq.len = len; + wlan_mgmt_decode_assocreq(&parsed.assocreq); + if (mac_is_equal(hdr->a1, adev->bssid) + && mac_is_equal(hdr->a3, adev->bssid)) { + acx_l_transmit_assocresp(adev, &parsed.assocreq); + } + break; + case WF_FSTYPE_REASSOCREQi: + if (!ap) + break; + memset(&parsed.assocreq, 0, sizeof(parsed.assocreq)); + parsed.assocreq.hdr = hdr; + parsed.assocreq.len = len; + wlan_mgmt_decode_assocreq(&parsed.assocreq); + /* reassocreq and assocreq are equivalent */ + acx_l_transmit_reassocresp(adev, &parsed.reassocreq); + break; + case WF_FSTYPE_ASSOCRESPi: + if (!sta_scan) + break; + memset(&parsed.assocresp, 0, sizeof(parsed.assocresp)); + parsed.assocresp.hdr = hdr; + parsed.assocresp.len = len; + wlan_mgmt_decode_assocresp(&parsed.assocresp); + acx_l_process_assocresp(adev, &parsed.assocresp); + break; + case WF_FSTYPE_REASSOCRESPi: + if (!sta_scan) + break; + memset(&parsed.assocresp, 0, sizeof(parsed.assocresp)); + parsed.assocresp.hdr = hdr; + parsed.assocresp.len = len; + wlan_mgmt_decode_assocresp(&parsed.assocresp); + acx_l_process_reassocresp(adev, &parsed.reassocresp); + break; + case WF_FSTYPE_PROBEREQi: + if (ap || adhoc) { + /* FIXME: since we're supposed to be an AP, + ** we need to return a Probe Response packet. + ** Currently firmware is doing it for us, + ** but firmware is buggy! See comment elsewhere --vda */ + } + break; + case WF_FSTYPE_PROBERESPi: + memset(&parsed.proberesp, 0, sizeof(parsed.proberesp)); + parsed.proberesp.hdr = hdr; + parsed.proberesp.len = len; + wlan_mgmt_decode_proberesp(&parsed.proberesp); + acx_l_process_probe_response(adev, &parsed.proberesp, rxbuf); + break; + case 6: + case 7: + /* exit */ + break; + case WF_FSTYPE_ATIMi: + /* exit */ + break; + case WF_FSTYPE_DISASSOCi: + if (!sta && !ap) + break; + memset(&parsed.disassoc, 0, sizeof(parsed.disassoc)); + parsed.disassoc.hdr = hdr; + parsed.disassoc.len = len; + wlan_mgmt_decode_disassoc(&parsed.disassoc); + if (sta) + acx_l_process_disassoc_from_ap(adev, &parsed.disassoc); + else + acx_l_process_disassoc_from_sta(adev, &parsed.disassoc); + break; + case WF_FSTYPE_AUTHENi: + if (!sta_scan && !ap) + break; + memset(&parsed.authen, 0, sizeof(parsed.authen)); + parsed.authen.hdr = hdr; + parsed.authen.len = len; + wlan_mgmt_decode_authen(&parsed.authen); + acx_l_process_authen(adev, &parsed.authen); + break; + case WF_FSTYPE_DEAUTHENi: + if (!sta && !ap) + break; + memset(&parsed.deauthen, 0, sizeof(parsed.deauthen)); + parsed.deauthen.hdr = hdr; + parsed.deauthen.len = len; + wlan_mgmt_decode_deauthen(&parsed.deauthen); + if (sta) + acx_l_process_deauth_from_ap(adev, &parsed.deauthen); + else + acx_l_process_deauth_from_sta(adev, &parsed.deauthen); + break; + } + + FN_EXIT1(OK); + return OK; +} + + +#ifdef UNUSED +/*********************************************************************** +** acx_process_class_frame +** +** Called from IRQ context only +*/ +static int +acx_process_class_frame(acx_device_t *adev, rxbuffer_t *rxbuf, int vala) +{ + return OK; +} +#endif + + +/*********************************************************************** +** acx_l_process_NULL_frame +*/ +#ifdef BOGUS_ITS_NOT_A_NULL_FRAME_HANDLER_AT_ALL +static int +acx_l_process_NULL_frame(acx_device_t *adev, rxbuffer_t *rxbuf, int vala) +{ + const signed char *esi; + const u8 *ebx; + const wlan_hdr_t *hdr; + const client_t *client; + int result = NOT_OK; + + hdr = acx_get_wlan_hdr(adev, rxbuf); + + switch (WF_FC_FROMTODSi & hdr->fc) { + case 0: + esi = hdr->a1; + ebx = hdr->a2; + break; + case WF_FC_FROMDSi: + esi = hdr->a1; + ebx = hdr->a3; + break; + case WF_FC_TODSi: + esi = hdr->a1; + ebx = hdr->a2; + break; + default: /* WF_FC_FROMTODSi */ + esi = hdr->a1; /* added by me! --vda */ + ebx = hdr->a2; + } + + if (esi[0x0] < 0) { + result = OK; + goto done; + } + + client = acx_l_sta_list_get(adev, ebx); + if (client) + result = NOT_OK; + else { +#ifdef IS_IT_BROKEN + log(L_DEBUG|L_XFER, "\n"); + acx_l_transmit_deauthen(adev, ebx, + WLAN_MGMT_REASON_CLASS2_NONAUTH); +#else + log(L_DEBUG, "received NULL frame from unknown client! " + "We really shouldn't send deauthen here, right?\n"); +#endif + result = OK; + } +done: + return result; +} +#endif + + +/*********************************************************************** +** acx_l_process_probe_response +*/ +static int +acx_l_process_probe_response(acx_device_t *adev, wlan_fr_proberesp_t *req, + const rxbuffer_t *rxbuf) +{ + struct client *bss; + wlan_hdr_t *hdr; + + FN_ENTER; + + hdr = req->hdr; + + if (mac_is_equal(hdr->a3, adev->dev_addr)) { + log(L_ASSOC, "huh, scan found our own MAC!?\n"); + goto ok; /* just skip this one silently */ + } + + bss = acx_l_sta_list_get_or_add(adev, hdr->a2); + + /* NB: be careful modifying bss data! It may be one + ** of the already known clients (like our AP if we are a STA) + ** Thus do not blindly modify e.g. current ratemask! */ + + if (STA_LIST_ADD_CAN_FAIL && !bss) { + /* uh oh, we found more sites/stations than we can handle with + * our current setup: pull the emergency brake and stop scanning! */ + acx_schedule_task(adev, ACX_AFTER_IRQ_CMD_STOP_SCAN); + /* TODO: a nice comment what below call achieves --vda */ + acx_set_status(adev, ACX_STATUS_2_WAIT_AUTH); + goto ok; + } + /* NB: get_or_add already filled bss->address = hdr->a2 */ + MAC_COPY(bss->bssid, hdr->a3); + + /* copy the ESSID element */ + if (req->ssid && req->ssid->len <= IW_ESSID_MAX_SIZE) { + bss->essid_len = req->ssid->len; + memcpy(bss->essid, req->ssid->ssid, req->ssid->len); + bss->essid[req->ssid->len] = '\0'; + } else { + /* Either no ESSID IE or oversized one */ + printk("%s: received packet has bogus ESSID\n", + adev->ndev->name); + } + + if (req->ds_parms) + bss->channel = req->ds_parms->curr_ch; + if (req->cap_info) + bss->cap_info = ieee2host16(*req->cap_info); + + bss->sir = acx_signal_to_winlevel(rxbuf->phy_level); + bss->snr = acx_signal_to_winlevel(rxbuf->phy_snr); + + bss->rate_cap = 0; /* operational mask */ + bss->rate_bas = 0; /* basic mask */ + if (req->supp_rates) + add_bits_to_ratemasks(req->supp_rates->rates, + req->supp_rates->len, &bss->rate_bas, &bss->rate_cap); + if (req->ext_rates) + add_bits_to_ratemasks(req->ext_rates->rates, + req->ext_rates->len, &bss->rate_bas, &bss->rate_cap); + /* Fix up any possible bogosity - code elsewhere + * is not expecting empty masks */ + if (!bss->rate_cap) + bss->rate_cap = adev->rate_basic; + if (!bss->rate_bas) + bss->rate_bas = 1 << lowest_bit(bss->rate_cap); + if (!bss->rate_cur) + bss->rate_cur = 1 << lowest_bit(bss->rate_bas); + + /* People moan about this being too noisy at L_ASSOC */ + log(L_DEBUG, + "found %s: ESSID=\"%s\" ch=%d " + "BSSID="MACSTR" caps=0x%04X SIR=%d SNR=%d\n", + (bss->cap_info & WF_MGMT_CAP_IBSS) ? "Ad-Hoc peer" : "AP", + bss->essid, bss->channel, MAC(bss->bssid), bss->cap_info, + bss->sir, bss->snr); +ok: + FN_EXIT0; + return OK; +} + + +/*********************************************************************** +** acx_l_process_assocresp +*/ +static int +acx_l_process_assocresp(acx_device_t *adev, const wlan_fr_assocresp_t *req) +{ + const wlan_hdr_t *hdr; + int res = OK; + + FN_ENTER; + + hdr = req->hdr; + + if ((ACX_MODE_2_STA == adev->mode) + && mac_is_equal(adev->dev_addr, hdr->a1)) { + u16 st = ieee2host16(*(req->status)); + if (WLAN_MGMT_STATUS_SUCCESS == st) { + adev->aid = ieee2host16(*(req->aid)); + /* tell the card we are associated when + ** we are out of interrupt context */ + acx_schedule_task(adev, ACX_AFTER_IRQ_CMD_ASSOCIATE); + } else { + + /* TODO: we shall delete peer from sta_list, and try + ** other candidates... */ + + printk("%s: association FAILED: peer sent " + "Status Code %d (%s)\n", + adev->ndev->name, st, get_status_string(st)); + res = NOT_OK; + } + } + + FN_EXIT1(res); + return res; +} + + +/*********************************************************************** +** acx_l_process_reassocresp +*/ +static int +acx_l_process_reassocresp(acx_device_t *adev, const wlan_fr_reassocresp_t *req) +{ + const wlan_hdr_t *hdr; + int result = NOT_OK; + u16 st; + + FN_ENTER; + + hdr = req->hdr; + + if (!mac_is_equal(adev->dev_addr, hdr->a1)) { + goto end; + } + st = ieee2host16(*(req->status)); + if (st == WLAN_MGMT_STATUS_SUCCESS) { + acx_set_status(adev, ACX_STATUS_4_ASSOCIATED); + result = OK; + } else { + printk("%s: reassociation FAILED: peer sent " + "response code %d (%s)\n", + adev->ndev->name, st, get_status_string(st)); + } +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_l_process_authen +** +** Called only in STA_SCAN or AP mode +*/ +static int +acx_l_process_authen(acx_device_t *adev, const wlan_fr_authen_t *req) +{ + const wlan_hdr_t *hdr; + client_t *clt; + wlan_ie_challenge_t *chal; + u16 alg, seq, status; + int ap, result; + + FN_ENTER; + + hdr = req->hdr; + + if (acx_debug & L_ASSOC) { + acx_print_mac("AUTHEN adev->addr=", adev->dev_addr, " "); + acx_print_mac("a1=", hdr->a1, " "); + acx_print_mac("a2=", hdr->a2, " "); + acx_print_mac("a3=", hdr->a3, " "); + acx_print_mac("adev->bssid=", adev->bssid, "\n"); + } + + if (!mac_is_equal(adev->dev_addr, hdr->a1) + || !mac_is_equal(adev->bssid, hdr->a3)) { + result = OK; + goto end; + } + + alg = ieee2host16(*(req->auth_alg)); + seq = ieee2host16(*(req->auth_seq)); + status = ieee2host16(*(req->status)); + + log(L_ASSOC, "auth algorithm %d, auth sequence %d, status %d\n", alg, seq, status); + + ap = (adev->mode == ACX_MODE_3_AP); + + if (adev->auth_alg <= 1) { + if (adev->auth_alg != alg) { + log(L_ASSOC, "auth algorithm mismatch: " + "our:%d peer:%d\n", adev->auth_alg, alg); + result = NOT_OK; + goto end; + } + } + if (ap) { + clt = acx_l_sta_list_get_or_add(adev, hdr->a2); + if (STA_LIST_ADD_CAN_FAIL && !clt) { + log(L_ASSOC, "could not allocate room for client\n"); + result = NOT_OK; + goto end; + } + } else { + clt = adev->ap_client; + if (!mac_is_equal(clt->address, hdr->a2)) { + printk("%s: malformed auth frame from AP?!\n", + adev->ndev->name); + result = NOT_OK; + goto end; + } + } + + /* now check which step in the authentication sequence we are + * currently in, and act accordingly */ + switch (seq) { + case 1: + if (!ap) + break; + acx_l_transmit_authen2(adev, req, clt); + break; + case 2: + if (ap) + break; + if (status == WLAN_MGMT_STATUS_SUCCESS) { + if (alg == WLAN_AUTH_ALG_OPENSYSTEM) { + acx_set_status(adev, ACX_STATUS_3_AUTHENTICATED); + acx_l_transmit_assoc_req(adev); + } else + if (alg == WLAN_AUTH_ALG_SHAREDKEY) { + acx_l_transmit_authen3(adev, req); + } + } else { + printk("%s: auth FAILED: peer sent " + "response code %d (%s), " + "still waiting for authentication\n", + adev->ndev->name, + status, get_status_string(status)); + acx_set_status(adev, ACX_STATUS_2_WAIT_AUTH); + } + break; + case 3: + if (!ap) + break; + if ((clt->auth_alg != WLAN_AUTH_ALG_SHAREDKEY) + || (alg != WLAN_AUTH_ALG_SHAREDKEY) + || (clt->auth_step != 2)) + break; + chal = req->challenge; + if (!chal + || memcmp(chal->challenge, clt->challenge_text, WLAN_CHALLENGE_LEN) + || (chal->eid != WLAN_EID_CHALLENGE) + || (chal->len != WLAN_CHALLENGE_LEN) + ) + break; + acx_l_transmit_authen4(adev, req); + MAC_COPY(clt->address, hdr->a2); + clt->used = CLIENT_AUTHENTICATED_2; + clt->auth_step = 4; + clt->seq = ieee2host16(hdr->seq); + break; + case 4: + if (ap) + break; + /* ok, we're through: we're authenticated. Woohoo!! */ + acx_set_status(adev, ACX_STATUS_3_AUTHENTICATED); + log(L_ASSOC, "Authenticated!\n"); + /* now that we're authenticated, request association */ + acx_l_transmit_assoc_req(adev); + break; + } + result = OK; +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_gen_challenge +*/ +static inline void +acx_gen_challenge(wlan_ie_challenge_t* d) +{ + FN_ENTER; + d->eid = WLAN_EID_CHALLENGE; + d->len = WLAN_CHALLENGE_LEN; + get_random_bytes(d->challenge, WLAN_CHALLENGE_LEN); + FN_EXIT0; +} + + +/*********************************************************************** +** acx_l_transmit_deauthen +*/ +static int +acx_l_transmit_deauthen(acx_device_t *adev, const u8 *addr, u16 reason) +{ + struct tx *tx; + struct wlan_hdr_mgmt *head; + struct deauthen_frame_body *body; + + FN_ENTER; + + tx = acx_l_alloc_tx(adev); + if (!tx) + goto bad; + head = acx_l_get_txbuf(adev, tx); + if (!head) { + acx_l_dealloc_tx(adev, tx); + goto bad; + } + body = (void*)(head + 1); + + head->fc = (WF_FTYPE_MGMTi | WF_FSTYPE_DEAUTHENi); + head->dur = 0; + MAC_COPY(head->da, addr); + MAC_COPY(head->sa, adev->dev_addr); + MAC_COPY(head->bssid, adev->bssid); + head->seq = 0; + + log(L_DEBUG|L_ASSOC|L_XFER, + "sending deauthen to "MACSTR" for %d\n", + MAC(addr), reason); + + body->reason = host2ieee16(reason); + + /* body is fixed size here, but beware of cutting-and-pasting this - + ** do not use sizeof(*body) for variable sized mgmt packets! */ + acx_l_tx_data(adev, tx, WLAN_HDR_A3_LEN + sizeof(*body)); + + FN_EXIT1(OK); + return OK; +bad: + FN_EXIT1(NOT_OK); + return NOT_OK; +} + + +/*********************************************************************** +** acx_l_transmit_authen1 +*/ +static int +acx_l_transmit_authen1(acx_device_t *adev) +{ + struct tx *tx; + struct wlan_hdr_mgmt *head; + struct auth_frame_body *body; + + FN_ENTER; + + log(L_ASSOC, "sending authentication1 request (auth algo %d), " + "awaiting response\n", adev->auth_alg); + + tx = acx_l_alloc_tx(adev); + if (!tx) + goto bad; + head = acx_l_get_txbuf(adev, tx); + if (!head) { + acx_l_dealloc_tx(adev, tx); + goto bad; + } + body = (void*)(head + 1); + + head->fc = WF_FSTYPE_AUTHENi; + /* duration should be 0 instead of 0x8000 to have + * the firmware calculate the value, right? */ + head->dur = 0; + MAC_COPY(head->da, adev->bssid); + MAC_COPY(head->sa, adev->dev_addr); + MAC_COPY(head->bssid, adev->bssid); + head->seq = 0; + + body->auth_alg = host2ieee16(adev->auth_alg); + body->auth_seq = host2ieee16(1); + body->status = host2ieee16(0); + + acx_l_tx_data(adev, tx, WLAN_HDR_A3_LEN + 2 + 2 + 2); + + FN_EXIT1(OK); + return OK; +bad: + FN_EXIT1(NOT_OK); + return NOT_OK; +} + + +/*********************************************************************** +** acx_l_transmit_authen2 +*/ +static int +acx_l_transmit_authen2(acx_device_t *adev, const wlan_fr_authen_t *req, + client_t *clt) +{ + struct tx *tx; + struct wlan_hdr_mgmt *head; + struct auth_frame_body *body; + unsigned int packet_len; + + FN_ENTER; + + if (!clt) + goto ok; + + MAC_COPY(clt->address, req->hdr->a2); +#ifdef UNUSED + clt->ps = ((WF_FC_PWRMGTi & req->hdr->fc) != 0); +#endif + clt->auth_alg = ieee2host16(*(req->auth_alg)); + clt->auth_step = 2; + clt->seq = ieee2host16(req->hdr->seq); + + tx = acx_l_alloc_tx(adev); + if (!tx) + goto bad; + head = acx_l_get_txbuf(adev, tx); + if (!head) { + acx_l_dealloc_tx(adev, tx); + goto bad; + } + body = (void*)(head + 1); + + head->fc = WF_FSTYPE_AUTHENi; + head->dur = 0 /* req->hdr->dur */; + MAC_COPY(head->da, req->hdr->a2); + MAC_COPY(head->sa, adev->dev_addr); + MAC_COPY(head->bssid, req->hdr->a3); + head->seq = 0 /* req->hdr->seq */; + + /* already in IEEE format, no endianness conversion */ + body->auth_alg = *(req->auth_alg); + body->auth_seq = host2ieee16(2); + body->status = host2ieee16(0); + + packet_len = WLAN_HDR_A3_LEN + 2 + 2 + 2; + if (ieee2host16(*(req->auth_alg)) == WLAN_AUTH_ALG_OPENSYSTEM) { + clt->used = CLIENT_AUTHENTICATED_2; + } else { /* shared key */ + acx_gen_challenge(&body->challenge); + memcpy(&clt->challenge_text, body->challenge.challenge, WLAN_CHALLENGE_LEN); + packet_len += 2 + 2 + 2 + 1+1+WLAN_CHALLENGE_LEN; + } + + acxlog_mac(L_ASSOC|L_XFER, + "transmit_auth2: BSSID=", head->bssid, "\n"); + + acx_l_tx_data(adev, tx, packet_len); +ok: + FN_EXIT1(OK); + return OK; +bad: + FN_EXIT1(NOT_OK); + return NOT_OK; +} + + +/*********************************************************************** +** acx_l_transmit_authen3 +*/ +static int +acx_l_transmit_authen3(acx_device_t *adev, const wlan_fr_authen_t *req) +{ + struct tx *tx; + struct wlan_hdr_mgmt *head; + struct auth_frame_body *body; + unsigned int packet_len; + + FN_ENTER; + + tx = acx_l_alloc_tx(adev); + if (!tx) + goto ok; + head = acx_l_get_txbuf(adev, tx); + if (!head) { + acx_l_dealloc_tx(adev, tx); + goto ok; + } + body = (void*)(head + 1); + + /* add WF_FC_ISWEPi: auth step 3 needs to be encrypted */ + head->fc = WF_FC_ISWEPi + WF_FSTYPE_AUTHENi; + /* FIXME: is this needed?? authen4 does it... + * I think it's even wrong since we shouldn't re-use old + * values but instead let the firmware calculate proper ones + head->dur = req->hdr->dur; + head->seq = req->hdr->seq; + */ + MAC_COPY(head->da, adev->bssid); + MAC_COPY(head->sa, adev->dev_addr); + MAC_COPY(head->bssid, adev->bssid); + + /* already in IEEE format, no endianness conversion */ + body->auth_alg = *(req->auth_alg); + body->auth_seq = host2ieee16(3); + body->status = host2ieee16(0); + memcpy(&body->challenge, req->challenge, req->challenge->len + 2); + packet_len = WLAN_HDR_A3_LEN + 8 + req->challenge->len; + + log(L_ASSOC|L_XFER, "transmit_authen3!\n"); + + acx_l_tx_data(adev, tx, packet_len); +ok: + FN_EXIT1(OK); + return OK; +} + + +/*********************************************************************** +** acx_l_transmit_authen4 +*/ +static int +acx_l_transmit_authen4(acx_device_t *adev, const wlan_fr_authen_t *req) +{ + struct tx *tx; + struct wlan_hdr_mgmt *head; + struct auth_frame_body *body; + + FN_ENTER; + + tx = acx_l_alloc_tx(adev); + if (!tx) + goto ok; + head = acx_l_get_txbuf(adev, tx); + if (!head) { + acx_l_dealloc_tx(adev, tx); + goto ok; + } + body = (void*)(head + 1); + + head->fc = WF_FSTYPE_AUTHENi; /* 0xb0 */ + head->dur = 0 /* req->hdr->dur */; + MAC_COPY(head->da, req->hdr->a2); + MAC_COPY(head->sa, adev->dev_addr); + MAC_COPY(head->bssid, req->hdr->a3); + head->seq = 0 /* req->hdr->seq */; + + /* already in IEEE format, no endianness conversion */ + body->auth_alg = *(req->auth_alg); + body->auth_seq = host2ieee16(4); + body->status = host2ieee16(0); + + acx_l_tx_data(adev, tx, WLAN_HDR_A3_LEN + 2 + 2 + 2); +ok: + FN_EXIT1(OK); + return OK; +} + + +/*********************************************************************** +** acx_l_transmit_assoc_req +** +** adev->ap_client is a current candidate AP here +*/ +static int +acx_l_transmit_assoc_req(acx_device_t *adev) +{ + struct tx *tx; + struct wlan_hdr_mgmt *head; + u8 *body, *p, *prate; + unsigned int packet_len; + u16 cap; + + FN_ENTER; + + log(L_ASSOC, "sending association request, " + "awaiting response. NOT ASSOCIATED YET\n"); + tx = acx_l_alloc_tx(adev); + if (!tx) + goto bad; + head = acx_l_get_txbuf(adev, tx); + if (!head) { + acx_l_dealloc_tx(adev, tx); + goto bad; + } + body = (void*)(head + 1); + + head->fc = WF_FSTYPE_ASSOCREQi; + head->dur = host2ieee16(0x8000); + MAC_COPY(head->da, adev->bssid); + MAC_COPY(head->sa, adev->dev_addr); + MAC_COPY(head->bssid, adev->bssid); + head->seq = 0; + + p = body; + /* now start filling the AssocReq frame body */ + + /* since this assoc request will most likely only get + * sent in the STA to AP case (and not when Ad-Hoc IBSS), + * the cap combination indicated here will thus be + * WF_MGMT_CAP_ESSi *always* (no IBSS ever) + * The specs are more than non-obvious on all that: + * + * 802.11 7.3.1.4 Capability Information field + ** APs set the ESS subfield to 1 and the IBSS subfield to 0 within + ** Beacon or Probe Response management frames. STAs within an IBSS + ** set the ESS subfield to 0 and the IBSS subfield to 1 in transmitted + ** Beacon or Probe Response management frames + ** + ** APs set the Privacy subfield to 1 within transmitted Beacon, + ** Probe Response, Association Response, and Reassociation Response + ** if WEP is required for all data type frames within the BSS. + ** STAs within an IBSS set the Privacy subfield to 1 in Beacon + ** or Probe Response management frames if WEP is required + ** for all data type frames within the IBSS */ + + /* note that returning 0 will be refused by several APs... + * (so this indicates that you're probably supposed to + * "confirm" the ESS mode) */ + cap = WF_MGMT_CAP_ESSi; + + /* this one used to be a check on wep_restricted, + * but more likely it's wep_enabled instead */ + if (adev->wep_enabled) + SET_BIT(cap, WF_MGMT_CAP_PRIVACYi); + + /* Probably we can just set these always, because our hw is + ** capable of shortpre and PBCC --vda */ + /* only ask for short preamble if the peer station supports it */ + if (adev->ap_client->cap_info & WF_MGMT_CAP_SHORT) + SET_BIT(cap, WF_MGMT_CAP_SHORTi); + /* only ask for PBCC support if the peer station supports it */ + if (adev->ap_client->cap_info & WF_MGMT_CAP_PBCC) + SET_BIT(cap, WF_MGMT_CAP_PBCCi); + + /* IEs: 1. caps */ + *(u16*)p = cap; p += 2; + /* 2. listen interval */ + *(u16*)p = host2ieee16(adev->listen_interval); p += 2; + /* 3. ESSID */ + p = wlan_fill_ie_ssid(p, + strlen(adev->essid_for_assoc), adev->essid_for_assoc); + /* 4. supp rates */ + prate = p; + p = wlan_fill_ie_rates(p, + adev->rate_supported_len, adev->rate_supported); + /* 5. ext supp rates */ + p = wlan_fill_ie_rates_ext(p, + adev->rate_supported_len, adev->rate_supported); + + if (acx_debug & L_DEBUG) { + printk("association: rates element\n"); + acx_dump_bytes(prate, p - prate); + } + + /* calculate lengths */ + packet_len = WLAN_HDR_A3_LEN + (p - body); + + log(L_ASSOC, "association: requesting caps 0x%04X, ESSID \"%s\"\n", + cap, adev->essid_for_assoc); + + acx_l_tx_data(adev, tx, packet_len); + FN_EXIT1(OK); + return OK; +bad: + FN_EXIT1(NOT_OK); + return NOT_OK; +} + + +/*********************************************************************** +** acx_l_transmit_disassoc +** +** FIXME: looks like incomplete implementation of a helper: +** acx_l_transmit_disassoc(adev, clt) - kick this client (we're an AP) +** acx_l_transmit_disassoc(adev, NULL) - leave BSSID (we're a STA) +*/ +#ifdef BROKEN +int +acx_l_transmit_disassoc(acx_device_t *adev, client_t *clt) +{ + struct tx *tx; + struct wlan_hdr_mgmt *head; + struct disassoc_frame_body *body; + + FN_ENTER; +/* if (clt != NULL) { */ + tx = acx_l_alloc_tx(adev); + if (!tx) + goto bad; + head = acx_l_get_txbuf(adev, tx); + if (!head) { + acx_l_dealloc_tx(adev, tx); + goto bad; + } + body = (void*)(head + 1); + +/* clt->used = CLIENT_AUTHENTICATED_2; - not (yet?) associated */ + + head->fc = WF_FSTYPE_DISASSOCi; + head->dur = 0; + /* huh? It muchly depends on whether we're STA or AP... + ** sta->ap: da=bssid, sa=own, bssid=bssid + ** ap->sta: da=sta, sa=bssid, bssid=bssid. FIXME! */ + MAC_COPY(head->da, adev->bssid); + MAC_COPY(head->sa, adev->dev_addr); + MAC_COPY(head->bssid, adev->dev_addr); + head->seq = 0; + + /* "Class 3 frame received from nonassociated station." */ + body->reason = host2ieee16(7); + + /* fixed size struct, ok to sizeof */ + acx_l_tx_data(adev, tx, WLAN_HDR_A3_LEN + sizeof(*body)); +/* } */ + FN_EXIT1(OK); + return OK; +bad: + FN_EXIT1(NOT_OK); + return NOT_OK; +} +#endif + + +/*********************************************************************** +** acx_s_complete_scan +** +** Called either from after_interrupt_task() if: +** 1) there was Scan_Complete IRQ, or +** 2) scanning expired in timer() +** We need to decide which ESS or IBSS to join. +** Iterates thru adev->sta_list: +** if adev->ap is not bcast, will join only specified +** ESS or IBSS with this bssid +** checks peers' caps for ESS/IBSS bit +** checks peers' SSID, allows exact match or hidden SSID +** If station to join is chosen: +** points adev->ap_client to the chosen struct client +** sets adev->essid_for_assoc for future assoc attempt +** Auth/assoc is not yet performed +** Returns OK if there is no need to restart scan +*/ +int +acx_s_complete_scan(acx_device_t *adev) +{ + struct client *bss; + unsigned long flags; + u16 needed_cap; + int i; + int idx_found = -1; + int result = OK; + + FN_ENTER; + + switch (adev->mode) { + case ACX_MODE_0_ADHOC: + needed_cap = WF_MGMT_CAP_IBSS; /* 2, we require Ad-Hoc */ + break; + case ACX_MODE_2_STA: + needed_cap = WF_MGMT_CAP_ESS; /* 1, we require Managed */ + break; + default: + printk("acx: driver bug: mode=%d in complete_scan()\n", adev->mode); + dump_stack(); + goto end; + } + + acx_lock(adev, flags); + + /* TODO: sta_iterator hiding implementation would be nice here... */ + + for (i = 0; i < VEC_SIZE(adev->sta_list); i++) { + bss = &adev->sta_list[i]; + if (!bss->used) continue; + + log(L_ASSOC, "scan table: SSID=\"%s\" CH=%d SIR=%d SNR=%d\n", + bss->essid, bss->channel, bss->sir, bss->snr); + + if (!mac_is_bcast(adev->ap)) + if (!mac_is_equal(bss->bssid, adev->ap)) + continue; /* keep looking */ + + /* broken peer with no mode flags set? */ + if (unlikely(!(bss->cap_info & (WF_MGMT_CAP_ESS | WF_MGMT_CAP_IBSS)))) { + printk("%s: strange peer "MACSTR" found with " + "neither ESS (AP) nor IBSS (Ad-Hoc) " + "capability - skipped\n", + adev->ndev->name, MAC(bss->address)); + continue; + } + log(L_ASSOC, "peer_cap 0x%04X, needed_cap 0x%04X\n", + bss->cap_info, needed_cap); + + /* does peer station support what we need? */ + if ((bss->cap_info & needed_cap) != needed_cap) + continue; /* keep looking */ + + /* strange peer with NO basic rates?! */ + if (unlikely(!bss->rate_bas)) { + printk("%s: strange peer "MACSTR" with empty rate set " + "- skipped\n", + adev->ndev->name, MAC(bss->address)); + continue; + } + + /* do we support all basic rates of this peer? */ + if ((bss->rate_bas & adev->rate_oper) != bss->rate_bas) { +/* we probably need to have all rates as operational rates, + even in case of an 11M-only configuration */ +#ifdef THIS_IS_TROUBLESOME + printk("%s: peer "MACSTR": incompatible basic rates " + "(AP requests 0x%04X, we have 0x%04X) " + "- skipped\n", + adev->ndev->name, MAC(bss->address), + bss->rate_bas, adev->rate_oper); + continue; +#else + printk("%s: peer "MACSTR": incompatible basic rates " + "(AP requests 0x%04X, we have 0x%04X). " + "Considering anyway...\n", + adev->ndev->name, MAC(bss->address), + bss->rate_bas, adev->rate_oper); +#endif + } + + if ( !(adev->reg_dom_chanmask & (1<<(bss->channel-1))) ) { + printk("%s: warning: peer "MACSTR" is on channel %d " + "outside of channel range of current " + "regulatory domain - couldn't join " + "even if other settings match. " + "You might want to adapt your config\n", + adev->ndev->name, MAC(bss->address), + bss->channel); + continue; /* keep looking */ + } + + if (!adev->essid_active || !strcmp(bss->essid, adev->essid)) { + log(L_ASSOC, + "found station with matching ESSID! ('%s' " + "station, '%s' config)\n", + bss->essid, + (adev->essid_active) ? adev->essid : "[any]"); + /* TODO: continue looking for peer with better SNR */ + bss->used = CLIENT_JOIN_CANDIDATE; + idx_found = i; + + /* stop searching if this station is + * on the current channel, otherwise + * keep looking for an even better match */ + if (bss->channel == adev->channel) + break; + } else + if (is_hidden_essid(bss->essid)) { + /* hmm, station with empty or single-space SSID: + * using hidden SSID broadcast? + */ + /* This behaviour is broken: which AP from zillion + ** of APs with hidden SSID you'd try? + ** We should use Probe requests to get Probe responses + ** and check for real SSID (are those never hidden?) */ + bss->used = CLIENT_JOIN_CANDIDATE; + if (idx_found == -1) + idx_found = i; + log(L_ASSOC, "found station with empty or " + "single-space (hidden) SSID, considering " + "for assoc attempt\n"); + /* ...and keep looking for better matches */ + } else { + log(L_ASSOC, "ESSID doesn't match! ('%s' " + "station, '%s' config)\n", + bss->essid, + (adev->essid_active) ? adev->essid : "[any]"); + } + } + + /* TODO: iterate thru join candidates instead */ + /* TODO: rescan if not associated within some timeout */ + if (idx_found != -1) { + char *essid_src; + size_t essid_len; + + bss = &adev->sta_list[idx_found]; + adev->ap_client = bss; + + if (is_hidden_essid(bss->essid)) { + /* if the ESSID of the station we found is empty + * (no broadcast), then use user-configured ESSID + * instead */ + essid_src = adev->essid; + essid_len = adev->essid_len; + } else { + essid_src = bss->essid; + essid_len = strlen(bss->essid); + } + + acx_update_capabilities(adev); + + memcpy(adev->essid_for_assoc, essid_src, essid_len); + adev->essid_for_assoc[essid_len] = '\0'; + adev->channel = bss->channel; + MAC_COPY(adev->bssid, bss->bssid); + + bss->rate_cfg = (bss->rate_cap & adev->rate_oper); + bss->rate_cur = 1 << lowest_bit(bss->rate_cfg); + bss->rate_100 = acx_rate111to100(bss->rate_cur); + + acxlog_mac(L_ASSOC, + "matching station found: ", adev->bssid, ", joining\n"); + + /* TODO: do we need to switch to the peer's channel first? */ + + if (ACX_MODE_0_ADHOC == adev->mode) { + acx_set_status(adev, ACX_STATUS_4_ASSOCIATED); + } else { + acx_l_transmit_authen1(adev); + acx_set_status(adev, ACX_STATUS_2_WAIT_AUTH); + } + } else { /* idx_found == -1 */ + /* uh oh, no station found in range */ + if (ACX_MODE_0_ADHOC == adev->mode) { + printk("%s: no matching station found in range, " + "generating our own IBSS instead\n", + adev->ndev->name); + /* we do it the HostAP way: */ + MAC_COPY(adev->bssid, adev->dev_addr); + adev->bssid[0] |= 0x02; /* 'local assigned addr' bit */ + /* add IBSS bit to our caps... */ + acx_update_capabilities(adev); + acx_set_status(adev, ACX_STATUS_4_ASSOCIATED); + /* In order to cmd_join be called below */ + idx_found = 0; + } else { + /* we shall scan again, AP can be + ** just temporarily powered off */ + log(L_ASSOC, + "no matching station found in range yet\n"); + acx_set_status(adev, ACX_STATUS_1_SCANNING); + result = NOT_OK; + } + } + + acx_unlock(adev, flags); + + if (idx_found != -1) { + if (ACX_MODE_0_ADHOC == adev->mode) { + /* need to update channel in beacon template */ + SET_BIT(adev->set_mask, SET_TEMPLATES); + if (ACX_STATE_IFACE_UP & adev->dev_state_mask) + acx_s_update_card_settings(adev); + } + /* Inform firmware on our decision to start or join BSS */ + acx_s_cmd_join_bssid(adev, adev->bssid); + } + +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_s_read_fw +** +** Loads a firmware image +** +** Returns: +** 0 unable to load file +** pointer to firmware success +*/ +firmware_image_t* +acx_s_read_fw(struct device *dev, const char *file, u32 *size) +{ + firmware_image_t *res; + const struct firmware *fw_entry; + + res = NULL; + log(L_INIT, "requesting firmware image '%s'\n", file); + if (!request_firmware(&fw_entry, file, dev)) { + *size = 8; + if (fw_entry->size >= 8) + *size = 8 + le32_to_cpu(*(u32 *)(fw_entry->data + 4)); + if (fw_entry->size != *size) { + printk("acx: firmware size does not match " + "firmware header: %d != %d, " + "aborting fw upload\n", + (int) fw_entry->size, (int) *size); + goto release_ret; + } + res = vmalloc(*size); + if (!res) { + printk("acx: no memory for firmware " + "(%u bytes)\n", *size); + goto release_ret; + } + memcpy(res, fw_entry->data, fw_entry->size); +release_ret: + release_firmware(fw_entry); + return res; + } + printk("acx: firmware image '%s' was not provided. " + "Check your hotplug scripts\n", file); + + /* checksum will be verified in write_fw, so don't bother here */ + return res; +} + + +/*********************************************************************** +** acx_s_set_wepkey +*/ +static void +acx100_s_set_wepkey(acx_device_t *adev) +{ + ie_dot11WEPDefaultKey_t dk; + int i; + + for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) { + if (adev->wep_keys[i].size != 0) { + log(L_INIT, "setting WEP key: %d with " + "total size: %d\n", i, (int) adev->wep_keys[i].size); + dk.action = 1; + dk.keySize = adev->wep_keys[i].size; + dk.defaultKeyNum = i; + memcpy(dk.key, adev->wep_keys[i].key, dk.keySize); + acx_s_configure(adev, &dk, ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE); + } + } +} + +static void +acx111_s_set_wepkey(acx_device_t *adev) +{ + acx111WEPDefaultKey_t dk; + int i; + + for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) { + if (adev->wep_keys[i].size != 0) { + log(L_INIT, "setting WEP key: %d with " + "total size: %d\n", i, (int) adev->wep_keys[i].size); + memset(&dk, 0, sizeof(dk)); + dk.action = cpu_to_le16(1); /* "add key"; yes, that's a 16bit value */ + dk.keySize = adev->wep_keys[i].size; + + /* are these two lines necessary? */ + dk.type = 0; /* default WEP key */ + dk.index = 0; /* ignored when setting default key */ + + dk.defaultKeyNum = i; + memcpy(dk.key, adev->wep_keys[i].key, dk.keySize); + acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &dk, sizeof(dk)); + } + } +} + +static void +acx_s_set_wepkey(acx_device_t *adev) +{ + if (IS_ACX111(adev)) + acx111_s_set_wepkey(adev); + else + acx100_s_set_wepkey(adev); +} + + +/*********************************************************************** +** acx100_s_init_wep +** +** FIXME: this should probably be moved into the new card settings +** management, but since we're also modifying the memory map layout here +** due to the WEP key space we want, we should take care... +*/ +static int +acx100_s_init_wep(acx_device_t *adev) +{ + acx100_ie_wep_options_t options; + ie_dot11WEPDefaultKeyID_t dk; + acx_ie_memmap_t pt; + int res = NOT_OK; + + FN_ENTER; + + if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) { + goto fail; + } + + log(L_DEBUG, "CodeEnd:%X\n", pt.CodeEnd); + + pt.WEPCacheStart = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4); + pt.WEPCacheEnd = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4); + + if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) { + goto fail; + } + + /* let's choose maximum setting: 4 default keys, plus 10 other keys: */ + options.NumKeys = cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10); + options.WEPOption = 0x00; + + log(L_ASSOC, "%s: writing WEP options\n", __func__); + acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS); + + acx100_s_set_wepkey(adev); + + if (adev->wep_keys[adev->wep_current_index].size != 0) { + log(L_ASSOC, "setting active default WEP key number: %d\n", + adev->wep_current_index); + dk.KeyID = adev->wep_current_index; + acx_s_configure(adev, &dk, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET); /* 0x1010 */ + } + /* FIXME!!! wep_key_struct is filled nowhere! But adev + * is initialized to 0, and we don't REALLY need those keys either */ +/* for (i = 0; i < 10; i++) { + if (adev->wep_key_struct[i].len != 0) { + MAC_COPY(wep_mgmt.MacAddr, adev->wep_key_struct[i].addr); + wep_mgmt.KeySize = cpu_to_le16(adev->wep_key_struct[i].len); + memcpy(&wep_mgmt.Key, adev->wep_key_struct[i].key, le16_to_cpu(wep_mgmt.KeySize)); + wep_mgmt.Action = cpu_to_le16(1); + log(L_ASSOC, "writing WEP key %d (len %d)\n", i, le16_to_cpu(wep_mgmt.KeySize)); + if (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &wep_mgmt, sizeof(wep_mgmt))) { + adev->wep_key_struct[i].index = i; + } + } + } +*/ + + /* now retrieve the updated WEPCacheEnd pointer... */ + if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) { + printk("%s: ACX1xx_IE_MEMORY_MAP read #2 FAILED\n", + adev->ndev->name); + goto fail; + } + /* ...and tell it to start allocating templates at that location */ + /* (no endianness conversion needed) */ + pt.PacketTemplateStart = pt.WEPCacheEnd; + + if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) { + printk("%s: ACX1xx_IE_MEMORY_MAP write #2 FAILED\n", + adev->ndev->name); + goto fail; + } + res = OK; + +fail: + FN_EXIT1(res); + return res; +} + + +static int +acx_s_init_max_template_generic(acx_device_t *adev, unsigned int len, unsigned int cmd) +{ + int res; + union { + acx_template_nullframe_t null; + acx_template_beacon_t b; + acx_template_tim_t tim; + acx_template_probereq_t preq; + acx_template_proberesp_t presp; + } templ; + + memset(&templ, 0, len); + templ.null.size = cpu_to_le16(len - 2); + res = acx_s_issue_cmd(adev, cmd, &templ, len); + return res; +} + +static inline int +acx_s_init_max_null_data_template(acx_device_t *adev) +{ + return acx_s_init_max_template_generic( + adev, sizeof(acx_template_nullframe_t), ACX1xx_CMD_CONFIG_NULL_DATA + ); +} + +static inline int +acx_s_init_max_beacon_template(acx_device_t *adev) +{ + return acx_s_init_max_template_generic( + adev, sizeof(acx_template_beacon_t), ACX1xx_CMD_CONFIG_BEACON + ); +} + +static inline int +acx_s_init_max_tim_template(acx_device_t *adev) +{ + return acx_s_init_max_template_generic( + adev, sizeof(acx_template_tim_t), ACX1xx_CMD_CONFIG_TIM + ); +} + +static inline int +acx_s_init_max_probe_response_template(acx_device_t *adev) +{ + return acx_s_init_max_template_generic( + adev, sizeof(acx_template_proberesp_t), ACX1xx_CMD_CONFIG_PROBE_RESPONSE + ); +} + +static inline int +acx_s_init_max_probe_request_template(acx_device_t *adev) +{ + return acx_s_init_max_template_generic( + adev, sizeof(acx_template_probereq_t), ACX1xx_CMD_CONFIG_PROBE_REQUEST + ); +} + +/*********************************************************************** +** acx_s_set_tim_template +** +** FIXME: In full blown driver we will regularly update partial virtual bitmap +** by calling this function +** (it can be done by irq handler on each DTIM irq or by timer...) + +[802.11 7.3.2.6] TIM information element: +- 1 EID +- 1 Length +1 1 DTIM Count + indicates how many beacons (including this) appear before next DTIM + (0=this one is a DTIM) +2 1 DTIM Period + number of beacons between successive DTIMs + (0=reserved, 1=all TIMs are DTIMs, 2=every other, etc) +3 1 Bitmap Control + bit0: Traffic Indicator bit associated with Assoc ID 0 (Bcast AID?) + set to 1 in TIM elements with a value of 0 in the DTIM Count field + when one or more broadcast or multicast frames are buffered at the AP. + bit1-7: Bitmap Offset (logically Bitmap_Offset = Bitmap_Control & 0xFE). +4 n Partial Virtual Bitmap + Visible part of traffic-indication bitmap. + Full bitmap consists of 2008 bits (251 octets) such that bit number N + (0<=N<=2007) in the bitmap corresponds to bit number (N mod 8) + in octet number N/8 where the low-order bit of each octet is bit0, + and the high order bit is bit7. + Each set bit in virtual bitmap corresponds to traffic buffered by AP + for a specific station (with corresponding AID?). + Partial Virtual Bitmap shows a part of bitmap which has non-zero. + Bitmap Offset is a number of skipped zero octets (see above). + 'Missing' octets at the tail are also assumed to be zero. + Example: Length=6, Bitmap_Offset=2, Partial_Virtual_Bitmap=55 55 55 + This means that traffic-indication bitmap is: + 00000000 00000000 01010101 01010101 01010101 00000000 00000000... + (is bit0 in the map is always 0 and real value is in Bitmap Control bit0?) +*/ +static int +acx_s_set_tim_template(acx_device_t *adev) +{ +/* For now, configure smallish test bitmap, all zero ("no pending data") */ + enum { bitmap_size = 5 }; + + acx_template_tim_t t; + int result; + + FN_ENTER; + + memset(&t, 0, sizeof(t)); + t.size = 5 + bitmap_size; /* eid+len+count+period+bmap_ctrl + bmap */ + t.tim_eid = WLAN_EID_TIM; + t.len = 3 + bitmap_size; /* count+period+bmap_ctrl + bmap */ + result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_TIM, &t, sizeof(t)); + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_fill_beacon_or_proberesp_template +** +** For frame format info, please see 802.11-1999.pdf item 7.2.3.9 and below!! +** +** NB: we use the fact that +** struct acx_template_proberesp and struct acx_template_beacon are the same +** (well, almost...) +** +** [802.11] Beacon's body consist of these IEs: +** 1 Timestamp +** 2 Beacon interval +** 3 Capability information +** 4 SSID +** 5 Supported rates (up to 8 rates) +** 6 FH Parameter Set (frequency-hopping PHYs only) +** 7 DS Parameter Set (direct sequence PHYs only) +** 8 CF Parameter Set (only if PCF is supported) +** 9 IBSS Parameter Set (ad-hoc only) +** +** Beacon only: +** 10 TIM (AP only) (see 802.11 7.3.2.6) +** 11 Country Information (802.11d) +** 12 FH Parameters (802.11d) +** 13 FH Pattern Table (802.11d) +** ... (?!! did not yet find relevant PDF file... --vda) +** 19 ERP Information (extended rate PHYs) +** 20 Extended Supported Rates (if more than 8 rates) +** +** Proberesp only: +** 10 Country information (802.11d) +** 11 FH Parameters (802.11d) +** 12 FH Pattern Table (802.11d) +** 13-n Requested information elements (802.11d) +** ???? +** 18 ERP Information (extended rate PHYs) +** 19 Extended Supported Rates (if more than 8 rates) +*/ +static int +acx_fill_beacon_or_proberesp_template(acx_device_t *adev, + struct acx_template_beacon *templ, + u16 fc /* in host order! */) +{ + int len; + u8 *p; + + FN_ENTER; + + memset(templ, 0, sizeof(*templ)); + MAC_BCAST(templ->da); + MAC_COPY(templ->sa, adev->dev_addr); + MAC_COPY(templ->bssid, adev->bssid); + + templ->beacon_interval = cpu_to_le16(adev->beacon_interval); + acx_update_capabilities(adev); + templ->cap = cpu_to_le16(adev->capabilities); + + p = templ->variable; + p = wlan_fill_ie_ssid(p, adev->essid_len, adev->essid); + p = wlan_fill_ie_rates(p, adev->rate_supported_len, adev->rate_supported); + p = wlan_fill_ie_ds_parms(p, adev->channel); + /* NB: should go AFTER tim, but acx seem to keep tim last always */ + p = wlan_fill_ie_rates_ext(p, adev->rate_supported_len, adev->rate_supported); + + switch (adev->mode) { + case ACX_MODE_0_ADHOC: + /* ATIM window */ + p = wlan_fill_ie_ibss_parms(p, 0); break; + case ACX_MODE_3_AP: + /* TIM IE is set up as separate template */ + break; + } + + len = p - (u8*)templ; + templ->fc = cpu_to_le16(WF_FTYPE_MGMT | fc); + /* - 2: do not count 'u16 size' field */ + templ->size = cpu_to_le16(len - 2); + + FN_EXIT1(len); + return len; +} + + +#if POWER_SAVE_80211 +/*********************************************************************** +** acx_s_set_null_data_template +*/ +static int +acx_s_set_null_data_template(acx_device_t *adev) +{ + struct acx_template_nullframe b; + int result; + + FN_ENTER; + + /* memset(&b, 0, sizeof(b)); not needed, setting all members */ + + b.size = cpu_to_le16(sizeof(b) - 2); + b.hdr.fc = WF_FTYPE_MGMTi | WF_FSTYPE_NULLi; + b.hdr.dur = 0; + MAC_BCAST(b.hdr.a1); + MAC_COPY(b.hdr.a2, adev->dev_addr); + MAC_COPY(b.hdr.a3, adev->bssid); + b.hdr.seq = 0; + + result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_NULL_DATA, &b, sizeof(b)); + + FN_EXIT1(result); + return result; +} +#endif + + +/*********************************************************************** +** acx_s_set_beacon_template +*/ +static int +acx_s_set_beacon_template(acx_device_t *adev) +{ + struct acx_template_beacon bcn; + int len, result; + + FN_ENTER; + + len = acx_fill_beacon_or_proberesp_template(adev, &bcn, WF_FSTYPE_BEACON); + result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_BEACON, &bcn, len); + + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_s_set_probe_response_template +*/ +static int +acx_s_set_probe_response_template(acx_device_t *adev) +{ + struct acx_template_proberesp pr; + int len, result; + + FN_ENTER; + + len = acx_fill_beacon_or_proberesp_template(adev, &pr, WF_FSTYPE_PROBERESP); + result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_PROBE_RESPONSE, &pr, len); + + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_s_init_packet_templates() +** +** NOTE: order is very important here, to have a correct memory layout! +** init templates: max Probe Request (station mode), max NULL data, +** max Beacon, max TIM, max Probe Response. +*/ +static int +acx_s_init_packet_templates(acx_device_t *adev) +{ + acx_ie_memmap_t mm; /* ACX100 only */ + int result = NOT_OK; + + FN_ENTER; + + log(L_DEBUG|L_INIT, "initializing max packet templates\n"); + + if (OK != acx_s_init_max_probe_request_template(adev)) + goto failed; + + if (OK != acx_s_init_max_null_data_template(adev)) + goto failed; + + if (OK != acx_s_init_max_beacon_template(adev)) + goto failed; + + if (OK != acx_s_init_max_tim_template(adev)) + goto failed; + + if (OK != acx_s_init_max_probe_response_template(adev)) + goto failed; + + if (IS_ACX111(adev)) { + /* ACX111 doesn't need the memory map magic below, + * and the other templates will be set later (acx_start) */ + result = OK; + goto success; + } + + /* ACX100 will have its TIM template set, + * and we also need to update the memory map */ + + if (OK != acx_s_set_tim_template(adev)) + goto failed_acx100; + + log(L_DEBUG, "sizeof(memmap)=%d bytes\n", (int)sizeof(mm)); + + if (OK != acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP)) + goto failed_acx100; + + mm.QueueStart = cpu_to_le32(le32_to_cpu(mm.PacketTemplateEnd) + 4); + if (OK != acx_s_configure(adev, &mm, ACX1xx_IE_MEMORY_MAP)) + goto failed_acx100; + + result = OK; + goto success; + +failed_acx100: + log(L_DEBUG|L_INIT, + /* "cb=0x%X\n" */ + "ACXMemoryMap:\n" + ".CodeStart=0x%X\n" + ".CodeEnd=0x%X\n" + ".WEPCacheStart=0x%X\n" + ".WEPCacheEnd=0x%X\n" + ".PacketTemplateStart=0x%X\n" + ".PacketTemplateEnd=0x%X\n", + /* len, */ + le32_to_cpu(mm.CodeStart), + le32_to_cpu(mm.CodeEnd), + le32_to_cpu(mm.WEPCacheStart), + le32_to_cpu(mm.WEPCacheEnd), + le32_to_cpu(mm.PacketTemplateStart), + le32_to_cpu(mm.PacketTemplateEnd)); + +failed: + printk("%s: %s() FAILED\n", adev->ndev->name, __func__); + +success: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +*/ +static int +acx_s_set_probe_request_template(acx_device_t *adev) +{ + struct acx_template_probereq probereq; + char *p; + int res; + int frame_len; + + FN_ENTER; + + memset(&probereq, 0, sizeof(probereq)); + + probereq.fc = WF_FTYPE_MGMTi | WF_FSTYPE_PROBEREQi; + MAC_BCAST(probereq.da); + MAC_COPY(probereq.sa, adev->dev_addr); + MAC_BCAST(probereq.bssid); + + p = probereq.variable; + p = wlan_fill_ie_ssid(p, adev->essid_len, adev->essid); + p = wlan_fill_ie_rates(p, adev->rate_supported_len, adev->rate_supported); + p = wlan_fill_ie_rates_ext(p, adev->rate_supported_len, adev->rate_supported); + frame_len = p - (char*)&probereq; + probereq.size = cpu_to_le16(frame_len - 2); + + res = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_PROBE_REQUEST, &probereq, frame_len); + FN_EXIT0; + return res; +} + + +/*********************************************************************** +** acx_s_init_mac +*/ +int +acx_s_init_mac(acx_device_t *adev) +{ + int result = NOT_OK; + + FN_ENTER; + + if (IS_ACX111(adev)) { + adev->ie_len = acx111_ie_len; + adev->ie_len_dot11 = acx111_ie_len_dot11; + } else { + adev->ie_len = acx100_ie_len; + adev->ie_len_dot11 = acx100_ie_len_dot11; + } + + if (IS_PCI(adev)) { + adev->memblocksize = 256; /* 256 is default */ + /* try to load radio for both ACX100 and ACX111, since both + * chips have at least some firmware versions making use of an + * external radio module */ + acxpci_s_upload_radio(adev); + } else { + adev->memblocksize = 128; + } + + if (IS_ACX111(adev)) { + /* for ACX111, the order is different from ACX100 + 1. init packet templates + 2. create station context and create dma regions + 3. init wep default keys + */ + if (OK != acx_s_init_packet_templates(adev)) + goto fail; + if (OK != acx111_s_create_dma_regions(adev)) { + printk("%s: acx111_create_dma_regions FAILED\n", + adev->ndev->name); + goto fail; + } + } else { + if (OK != acx100_s_init_wep(adev)) + goto fail; + if (OK != acx_s_init_packet_templates(adev)) + goto fail; + if (OK != acx100_s_create_dma_regions(adev)) { + printk("%s: acx100_create_dma_regions FAILED\n", + adev->ndev->name); + goto fail; + } + } + + MAC_COPY(adev->ndev->dev_addr, adev->dev_addr); + result = OK; + +fail: + if (result) + printk("acx: init_mac() FAILED\n"); + FN_EXIT1(result); + return result; +} + + +void +acx_s_set_sane_reg_domain(acx_device_t *adev, int do_set) +{ + unsigned mask; + + unsigned int i; + + for (i = 0; i < sizeof(acx_reg_domain_ids); i++) + if (acx_reg_domain_ids[i] == adev->reg_dom_id) + break; + + if (sizeof(acx_reg_domain_ids) == i) { + log(L_INIT, "Invalid or unsupported regulatory domain" + " 0x%02X specified, falling back to FCC (USA)!" + " Please report if this sounds fishy!\n", + adev->reg_dom_id); + i = 0; + adev->reg_dom_id = acx_reg_domain_ids[i]; + + /* since there was a mismatch, we need to force updating */ + do_set = 1; + } + + if (do_set) { + acx_ie_generic_t dom; + dom.m.bytes[0] = adev->reg_dom_id; + acx_s_configure(adev, &dom, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN); + } + + adev->reg_dom_chanmask = reg_domain_channel_masks[i]; + + mask = (1 << (adev->channel - 1)); + if (!(adev->reg_dom_chanmask & mask)) { + /* hmm, need to adjust our channel to reside within domain */ + mask = 1; + for (i = 1; i <= 14; i++) { + if (adev->reg_dom_chanmask & mask) { + printk("%s: adjusting selected channel from %d " + "to %d due to new regulatory domain\n", + adev->ndev->name, adev->channel, i); + adev->channel = i; + break; + } + mask <<= 1; + } + } +} + + +#if POWER_SAVE_80211 +static void +acx_s_update_80211_powersave_mode(acx_device_t *adev) +{ + /* merge both structs in a union to be able to have common code */ + union { + acx111_ie_powersave_t acx111; + acx100_ie_powersave_t acx100; + } pm; + + /* change 802.11 power save mode settings */ + log(L_INIT, "updating 802.11 power save mode settings: " + "wakeup_cfg 0x%02X, listen interval %u, " + "options 0x%02X, hangover period %u, " + "enhanced_ps_transition_time %u\n", + adev->ps_wakeup_cfg, adev->ps_listen_interval, + adev->ps_options, adev->ps_hangover_period, + adev->ps_enhanced_transition_time); + acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT); + log(L_INIT, "Previous PS mode settings: wakeup_cfg 0x%02X, " + "listen interval %u, options 0x%02X, " + "hangover period %u, " + "enhanced_ps_transition_time %u, beacon_rx_time %u\n", + pm.acx111.wakeup_cfg, + pm.acx111.listen_interval, + pm.acx111.options, + pm.acx111.hangover_period, + IS_ACX111(adev) ? + pm.acx111.enhanced_ps_transition_time + : pm.acx100.enhanced_ps_transition_time, + IS_ACX111(adev) ? + pm.acx111.beacon_rx_time + : (u32)-1 + ); + pm.acx111.wakeup_cfg = adev->ps_wakeup_cfg; + pm.acx111.listen_interval = adev->ps_listen_interval; + pm.acx111.options = adev->ps_options; + pm.acx111.hangover_period = adev->ps_hangover_period; + if (IS_ACX111(adev)) { + pm.acx111.beacon_rx_time = cpu_to_le32(adev->ps_beacon_rx_time); + pm.acx111.enhanced_ps_transition_time = cpu_to_le32(adev->ps_enhanced_transition_time); + } else { + pm.acx100.enhanced_ps_transition_time = cpu_to_le16(adev->ps_enhanced_transition_time); + } + acx_s_configure(adev, &pm, ACX1xx_IE_POWER_MGMT); + acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT); + log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg); + acx_s_msleep(40); + acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT); + log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg); + log(L_INIT, "power save mode change %s\n", + (pm.acx111.wakeup_cfg & PS_CFG_PENDING) ? "FAILED" : "was successful"); + /* FIXME: maybe verify via PS_CFG_PENDING bit here + * that power save mode change was successful. */ + /* FIXME: we shouldn't trigger a scan immediately after + * fiddling with power save mode (since the firmware is sending + * a NULL frame then). */ +} +#endif + + +/*********************************************************************** +** acx_s_update_card_settings +** +** Applies accumulated changes in various adev->xxxx members +** Called by ioctl commit handler, acx_start, acx_set_defaults, +** acx_s_after_interrupt_task (if IRQ_CMD_UPDATE_CARD_CFG), +*/ +static void +acx111_s_sens_radio_16_17(acx_device_t *adev) +{ + u32 feature1, feature2; + + if ((adev->sensitivity < 1) || (adev->sensitivity > 3)) { + printk("%s: invalid sensitivity setting (1..3), " + "setting to 1\n", adev->ndev->name); + adev->sensitivity = 1; + } + acx111_s_get_feature_config(adev, &feature1, &feature2); + CLEAR_BIT(feature1, FEATURE1_LOW_RX|FEATURE1_EXTRA_LOW_RX); + if (adev->sensitivity > 1) + SET_BIT(feature1, FEATURE1_LOW_RX); + if (adev->sensitivity > 2) + SET_BIT(feature1, FEATURE1_EXTRA_LOW_RX); + acx111_s_feature_set(adev, feature1, feature2); +} + + +void +acx_s_update_card_settings(acx_device_t *adev) +{ + unsigned long flags; + unsigned int start_scan = 0; + int i; + + FN_ENTER; + + log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X\n", + adev->get_mask, adev->set_mask); + + /* Track dependencies betweed various settings */ + + if (adev->set_mask & (GETSET_MODE|GETSET_RESCAN|GETSET_WEP)) { + log(L_INIT, "important setting has been changed. " + "Need to update packet templates, too\n"); + SET_BIT(adev->set_mask, SET_TEMPLATES); + } + if (adev->set_mask & GETSET_CHANNEL) { + /* This will actually tune RX/TX to the channel */ + SET_BIT(adev->set_mask, GETSET_RX|GETSET_TX); + switch (adev->mode) { + case ACX_MODE_0_ADHOC: + case ACX_MODE_3_AP: + /* Beacons contain channel# - update them */ + SET_BIT(adev->set_mask, SET_TEMPLATES); + } + switch (adev->mode) { + case ACX_MODE_0_ADHOC: + case ACX_MODE_2_STA: + start_scan = 1; + } + } + + /* Apply settings */ + +#ifdef WHY_SHOULD_WE_BOTHER /* imagine we were just powered off */ + /* send a disassoc request in case it's required */ + if (adev->set_mask & (GETSET_MODE|GETSET_RESCAN|GETSET_CHANNEL|GETSET_WEP)) { + if (ACX_MODE_2_STA == adev->mode) { + if (ACX_STATUS_4_ASSOCIATED == adev->status) { + log(L_ASSOC, "we were ASSOCIATED - " + "sending disassoc request\n"); + acx_lock(adev, flags); + acx_l_transmit_disassoc(adev, NULL); + /* FIXME: deauth? */ + acx_unlock(adev, flags); + } + /* need to reset some other stuff as well */ + log(L_DEBUG, "resetting bssid\n"); + MAC_ZERO(adev->bssid); + SET_BIT(adev->set_mask, SET_TEMPLATES|SET_STA_LIST); + start_scan = 1; + } + } +#endif + + if (adev->get_mask & GETSET_STATION_ID) { + u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN]; + const u8 *paddr; + + acx_s_interrogate(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID); + paddr = &stationID[4]; + for (i = 0; i < ETH_ALEN; i++) { + /* we copy the MAC address (reversed in + * the card) to the netdevice's MAC + * address, and on ifup it will be + * copied into iwadev->dev_addr */ + adev->ndev->dev_addr[ETH_ALEN - 1 - i] = paddr[i]; + } + CLEAR_BIT(adev->get_mask, GETSET_STATION_ID); + } + + if (adev->get_mask & GETSET_SENSITIVITY) { + if ((RADIO_RFMD_11 == adev->radio_type) + || (RADIO_MAXIM_0D == adev->radio_type) + || (RADIO_RALINK_15 == adev->radio_type)) { + acx_s_read_phy_reg(adev, 0x30, &adev->sensitivity); + } else { + log(L_INIT, "don't know how to get sensitivity " + "for radio type 0x%02X\n", adev->radio_type); + adev->sensitivity = 0; + } + log(L_INIT, "got sensitivity value %u\n", adev->sensitivity); + + CLEAR_BIT(adev->get_mask, GETSET_SENSITIVITY); + } + + if (adev->get_mask & GETSET_ANTENNA) { + u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN]; + + memset(antenna, 0, sizeof(antenna)); + acx_s_interrogate(adev, antenna, ACX1xx_IE_DOT11_CURRENT_ANTENNA); + adev->antenna = antenna[4]; + log(L_INIT, "got antenna value 0x%02X\n", adev->antenna); + CLEAR_BIT(adev->get_mask, GETSET_ANTENNA); + } + + if (adev->get_mask & GETSET_ED_THRESH) { + if (IS_ACX100(adev)) { + u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN]; + + memset(ed_threshold, 0, sizeof(ed_threshold)); + acx_s_interrogate(adev, ed_threshold, ACX100_IE_DOT11_ED_THRESHOLD); + adev->ed_threshold = ed_threshold[4]; + } else { + log(L_INIT, "acx111 doesn't support ED\n"); + adev->ed_threshold = 0; + } + log(L_INIT, "got Energy Detect (ED) threshold %u\n", adev->ed_threshold); + CLEAR_BIT(adev->get_mask, GETSET_ED_THRESH); + } + + if (adev->get_mask & GETSET_CCA) { + if (IS_ACX100(adev)) { + u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN]; + + memset(cca, 0, sizeof(adev->cca)); + acx_s_interrogate(adev, cca, ACX1xx_IE_DOT11_CURRENT_CCA_MODE); + adev->cca = cca[4]; + } else { + log(L_INIT, "acx111 doesn't support CCA\n"); + adev->cca = 0; + } + log(L_INIT, "got Channel Clear Assessment (CCA) value %u\n", adev->cca); + CLEAR_BIT(adev->get_mask, GETSET_CCA); + } + + if (adev->get_mask & GETSET_REG_DOMAIN) { + acx_ie_generic_t dom; + + acx_s_interrogate(adev, &dom, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN); + adev->reg_dom_id = dom.m.bytes[0]; + acx_s_set_sane_reg_domain(adev, 0); + log(L_INIT, "got regulatory domain 0x%02X\n", adev->reg_dom_id); + CLEAR_BIT(adev->get_mask, GETSET_REG_DOMAIN); + } + + if (adev->set_mask & GETSET_STATION_ID) { + u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN]; + u8 *paddr; + + paddr = &stationID[4]; + memcpy(adev->dev_addr, adev->ndev->dev_addr, ETH_ALEN); + for (i = 0; i < ETH_ALEN; i++) { + /* copy the MAC address we obtained when we noticed + * that the ethernet iface's MAC changed + * to the card (reversed in + * the card!) */ + paddr[i] = adev->dev_addr[ETH_ALEN - 1 - i]; + } + acx_s_configure(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID); + CLEAR_BIT(adev->set_mask, GETSET_STATION_ID); + } + + if (adev->set_mask & SET_TEMPLATES) { + log(L_INIT, "updating packet templates\n"); + switch (adev->mode) { + case ACX_MODE_2_STA: + acx_s_set_probe_request_template(adev); +#if POWER_SAVE_80211 + acx_s_set_null_data_template(adev); +#endif + break; + case ACX_MODE_0_ADHOC: + acx_s_set_probe_request_template(adev); +#if POWER_SAVE_80211 + /* maybe power save functionality is somehow possible + * for Ad-Hoc mode, too... FIXME: verify it somehow? firmware debug fields? */ + acx_s_set_null_data_template(adev); +#endif + /* fall through */ + case ACX_MODE_3_AP: + acx_s_set_beacon_template(adev); + acx_s_set_tim_template(adev); + /* BTW acx111 firmware would not send probe responses + ** if probe request does not have all basic rates flagged + ** by 0x80! Thus firmware does not conform to 802.11, + ** it should ignore 0x80 bit in ratevector from STA. + ** We can 'fix' it by not using this template and + ** sending probe responses by hand. TODO --vda */ + acx_s_set_probe_response_template(adev); + } + /* Needed if generated frames are to be emitted at different tx rate now */ + log(L_IRQ, "redoing cmd_join_bssid() after template cfg\n"); + acx_s_cmd_join_bssid(adev, adev->bssid); + CLEAR_BIT(adev->set_mask, SET_TEMPLATES); + } + if (adev->set_mask & SET_STA_LIST) { + acx_lock(adev, flags); + acx_l_sta_list_init(adev); + CLEAR_BIT(adev->set_mask, SET_STA_LIST); + acx_unlock(adev, flags); + } + if (adev->set_mask & SET_RATE_FALLBACK) { + u8 rate[4 + ACX1xx_IE_RATE_FALLBACK_LEN]; + + /* configure to not do fallbacks when not in auto rate mode */ + rate[4] = (adev->rate_auto) ? /* adev->txrate_fallback_retries */ 1 : 0; + log(L_INIT, "updating Tx fallback to %u retries\n", rate[4]); + acx_s_configure(adev, &rate, ACX1xx_IE_RATE_FALLBACK); + CLEAR_BIT(adev->set_mask, SET_RATE_FALLBACK); + } + if (adev->set_mask & GETSET_TXPOWER) { + log(L_INIT, "updating transmit power: %u dBm\n", + adev->tx_level_dbm); + acx_s_set_tx_level(adev, adev->tx_level_dbm); + CLEAR_BIT(adev->set_mask, GETSET_TXPOWER); + } + + if (adev->set_mask & GETSET_SENSITIVITY) { + log(L_INIT, "updating sensitivity value: %u\n", + adev->sensitivity); + switch (adev->radio_type) { + case RADIO_RFMD_11: + case RADIO_MAXIM_0D: + case RADIO_RALINK_15: + acx_s_write_phy_reg(adev, 0x30, adev->sensitivity); + break; + case RADIO_RADIA_16: + case RADIO_UNKNOWN_17: + acx111_s_sens_radio_16_17(adev); + break; + default: + log(L_INIT, "don't know how to modify sensitivity " + "for radio type 0x%02X\n", adev->radio_type); + } + CLEAR_BIT(adev->set_mask, GETSET_SENSITIVITY); + } + + if (adev->set_mask & GETSET_ANTENNA) { + /* antenna */ + u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN]; + + memset(antenna, 0, sizeof(antenna)); + antenna[4] = adev->antenna; + log(L_INIT, "updating antenna value: 0x%02X\n", + adev->antenna); + acx_s_configure(adev, &antenna, ACX1xx_IE_DOT11_CURRENT_ANTENNA); + CLEAR_BIT(adev->set_mask, GETSET_ANTENNA); + } + + if (adev->set_mask & GETSET_ED_THRESH) { + /* ed_threshold */ + log(L_INIT, "updating Energy Detect (ED) threshold: %u\n", + adev->ed_threshold); + if (IS_ACX100(adev)) { + u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN]; + + memset(ed_threshold, 0, sizeof(ed_threshold)); + ed_threshold[4] = adev->ed_threshold; + acx_s_configure(adev, &ed_threshold, ACX100_IE_DOT11_ED_THRESHOLD); + } + else + log(L_INIT, "acx111 doesn't support ED!\n"); + CLEAR_BIT(adev->set_mask, GETSET_ED_THRESH); + } + + if (adev->set_mask & GETSET_CCA) { + /* CCA value */ + log(L_INIT, "updating Channel Clear Assessment " + "(CCA) value: 0x%02X\n", adev->cca); + if (IS_ACX100(adev)) { + u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN]; + + memset(cca, 0, sizeof(cca)); + cca[4] = adev->cca; + acx_s_configure(adev, &cca, ACX1xx_IE_DOT11_CURRENT_CCA_MODE); + } + else + log(L_INIT, "acx111 doesn't support CCA!\n"); + CLEAR_BIT(adev->set_mask, GETSET_CCA); + } + + if (adev->set_mask & GETSET_LED_POWER) { + /* Enable Tx */ + log(L_INIT, "updating power LED status: %u\n", adev->led_power); + + acx_lock(adev, flags); + if (IS_PCI(adev)) + acxpci_l_power_led(adev, adev->led_power); + CLEAR_BIT(adev->set_mask, GETSET_LED_POWER); + acx_unlock(adev, flags); + } + + if (adev->set_mask & GETSET_POWER_80211) { +#if POWER_SAVE_80211 + acx_s_update_80211_powersave_mode(adev); +#endif + CLEAR_BIT(adev->set_mask, GETSET_POWER_80211); + } + + if (adev->set_mask & GETSET_CHANNEL) { + /* channel */ + log(L_INIT, "updating channel to: %u\n", adev->channel); + CLEAR_BIT(adev->set_mask, GETSET_CHANNEL); + } + + if (adev->set_mask & GETSET_TX) { + /* set Tx */ + log(L_INIT, "updating: %s Tx\n", + adev->tx_disabled ? "disable" : "enable"); + if (adev->tx_disabled) + acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0); + else + acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX, &adev->channel, 1); + CLEAR_BIT(adev->set_mask, GETSET_TX); + } + + if (adev->set_mask & GETSET_RX) { + /* Enable Rx */ + log(L_INIT, "updating: enable Rx on channel: %u\n", + adev->channel); + acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX, &adev->channel, 1); + CLEAR_BIT(adev->set_mask, GETSET_RX); + } + + if (adev->set_mask & GETSET_RETRY) { + u8 short_retry[4 + ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN]; + u8 long_retry[4 + ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN]; + + log(L_INIT, "updating short retry limit: %u, long retry limit: %u\n", + adev->short_retry, adev->long_retry); + short_retry[0x4] = adev->short_retry; + long_retry[0x4] = adev->long_retry; + acx_s_configure(adev, &short_retry, ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT); + acx_s_configure(adev, &long_retry, ACX1xx_IE_DOT11_LONG_RETRY_LIMIT); + CLEAR_BIT(adev->set_mask, GETSET_RETRY); + } + + if (adev->set_mask & SET_MSDU_LIFETIME) { + u8 xmt_msdu_lifetime[4 + ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN]; + + log(L_INIT, "updating tx MSDU lifetime: %u\n", + adev->msdu_lifetime); + *(u32 *)&xmt_msdu_lifetime[4] = cpu_to_le32((u32)adev->msdu_lifetime); + acx_s_configure(adev, &xmt_msdu_lifetime, ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME); + CLEAR_BIT(adev->set_mask, SET_MSDU_LIFETIME); + } + + if (adev->set_mask & GETSET_REG_DOMAIN) { + log(L_INIT, "updating regulatory domain: 0x%02X\n", + adev->reg_dom_id); + acx_s_set_sane_reg_domain(adev, 1); + CLEAR_BIT(adev->set_mask, GETSET_REG_DOMAIN); + } + + if (adev->set_mask & GETSET_MODE) { + adev->ndev->type = (adev->mode == ACX_MODE_MONITOR) ? + adev->monitor_type : ARPHRD_ETHER; + + switch (adev->mode) { + case ACX_MODE_3_AP: + + acx_lock(adev, flags); + acx_l_sta_list_init(adev); + adev->aid = 0; + adev->ap_client = NULL; + MAC_COPY(adev->bssid, adev->dev_addr); + /* this basically says "we're connected" */ + acx_set_status(adev, ACX_STATUS_4_ASSOCIATED); + acx_unlock(adev, flags); + + acx111_s_feature_off(adev, 0, FEATURE2_NO_TXCRYPT|FEATURE2_SNIFFER); + /* start sending beacons */ + acx_s_cmd_join_bssid(adev, adev->bssid); + break; + case ACX_MODE_MONITOR: + acx111_s_feature_on(adev, 0, FEATURE2_NO_TXCRYPT|FEATURE2_SNIFFER); + /* this stops beacons */ + acx_s_cmd_join_bssid(adev, adev->bssid); + /* this basically says "we're connected" */ + acx_set_status(adev, ACX_STATUS_4_ASSOCIATED); + SET_BIT(adev->set_mask, SET_RXCONFIG|SET_WEP_OPTIONS); + break; + case ACX_MODE_0_ADHOC: + case ACX_MODE_2_STA: + acx111_s_feature_off(adev, 0, FEATURE2_NO_TXCRYPT|FEATURE2_SNIFFER); + + acx_lock(adev, flags); + adev->aid = 0; + adev->ap_client = NULL; + acx_unlock(adev, flags); + + /* we want to start looking for peer or AP */ + start_scan = 1; + break; + case ACX_MODE_OFF: + /* TODO: disable RX/TX, stop any scanning activity etc: */ + /* adev->tx_disabled = 1; */ + /* SET_BIT(adev->set_mask, GETSET_RX|GETSET_TX); */ + + /* This stops beacons (invalid macmode...) */ + acx_s_cmd_join_bssid(adev, adev->bssid); + acx_set_status(adev, ACX_STATUS_0_STOPPED); + break; + } + CLEAR_BIT(adev->set_mask, GETSET_MODE); + } + + if (adev->set_mask & SET_RXCONFIG) { + acx_s_initialize_rx_config(adev); + CLEAR_BIT(adev->set_mask, SET_RXCONFIG); + } + + if (adev->set_mask & GETSET_RESCAN) { + switch (adev->mode) { + case ACX_MODE_0_ADHOC: + case ACX_MODE_2_STA: + start_scan = 1; + break; + } + CLEAR_BIT(adev->set_mask, GETSET_RESCAN); + } + + if (adev->set_mask & GETSET_WEP) { + /* encode */ + + ie_dot11WEPDefaultKeyID_t dkey; +#ifdef DEBUG_WEP + struct { + u16 type; + u16 len; + u8 val; + } ACX_PACKED keyindic; +#endif + log(L_INIT, "updating WEP key settings\n"); + + acx_s_set_wepkey(adev); + + dkey.KeyID = adev->wep_current_index; + log(L_INIT, "setting WEP key %u as default\n", dkey.KeyID); + acx_s_configure(adev, &dkey, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET); +#ifdef DEBUG_WEP + keyindic.val = 3; + acx_s_configure(adev, &keyindic, ACX111_IE_KEY_CHOOSE); +#endif + start_scan = 1; + CLEAR_BIT(adev->set_mask, GETSET_WEP); + } + + if (adev->set_mask & SET_WEP_OPTIONS) { + acx100_ie_wep_options_t options; + + if (IS_ACX111(adev)) { + log(L_DEBUG, "setting WEP Options for acx111 is not supported\n"); + } else { + log(L_INIT, "setting WEP Options\n"); + + /* let's choose maximum setting: 4 default keys, + * plus 10 other keys: */ + options.NumKeys = cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10); + /* don't decrypt default key only, + * don't override decryption: */ + options.WEPOption = 0; + if (adev->mode == ACX_MODE_MONITOR) { + /* don't decrypt default key only, + * override decryption mechanism: */ + options.WEPOption = 2; + } + + acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS); + } + CLEAR_BIT(adev->set_mask, SET_WEP_OPTIONS); + } + + /* Rescan was requested */ + if (start_scan) { + switch (adev->mode) { + case ACX_MODE_0_ADHOC: + case ACX_MODE_2_STA: + /* We can avoid clearing list if join code + ** will be a bit more clever about not picking + ** 'bad' AP over and over again */ + acx_lock(adev, flags); + adev->ap_client = NULL; + acx_l_sta_list_init(adev); + acx_set_status(adev, ACX_STATUS_1_SCANNING); + acx_unlock(adev, flags); + + acx_s_cmd_start_scan(adev); + } + } + + /* debug, rate, and nick don't need any handling */ + /* what about sniffing mode?? */ + + log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X - after update\n", + adev->get_mask, adev->set_mask); + +/* end: */ + FN_EXIT0; +} + + +/*********************************************************************** +** acx_e_after_interrupt_task +*/ +static int +acx_s_recalib_radio(acx_device_t *adev) +{ + if (IS_ACX111(adev)) { + acx111_cmd_radiocalib_t cal; + + printk("%s: recalibrating radio\n", adev->ndev->name); + /* automatic recalibration, choose all methods: */ + cal.methods = cpu_to_le32(0x8000000f); + /* automatic recalibration every 60 seconds (value in TUs) + * I wonder what the firmware default here is? */ + cal.interval = cpu_to_le32(58594); + return acx_s_issue_cmd_timeo(adev, ACX111_CMD_RADIOCALIB, + &cal, sizeof(cal), CMD_TIMEOUT_MS(100)); + } else { + /* On ACX100, we need to recalibrate the radio + * by issuing a GETSET_TX|GETSET_RX */ + if (/* (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0)) && + (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0)) && */ + (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX, &adev->channel, 1)) && + (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX, &adev->channel, 1)) ) + return OK; + return NOT_OK; + } +} + +static void +acx_s_after_interrupt_recalib(acx_device_t *adev) +{ + int res; + + /* this helps with ACX100 at least; + * hopefully ACX111 also does a + * recalibration here */ + + /* clear flag beforehand, since we want to make sure + * it's cleared; then only set it again on specific circumstances */ + CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_RADIO_RECALIB); + + /* better wait a bit between recalibrations to + * prevent overheating due to torturing the card + * into working too long despite high temperature + * (just a safety measure) */ + if (adev->recalib_time_last_success + && time_before(jiffies, adev->recalib_time_last_success + + RECALIB_PAUSE * 60 * HZ)) { + if (adev->recalib_msg_ratelimit <= 4) { + printk("%s: less than " STRING(RECALIB_PAUSE) + " minutes since last radio recalibration, " + "not recalibrating (maybe card is too hot?)\n", + adev->ndev->name); + adev->recalib_msg_ratelimit++; + if (adev->recalib_msg_ratelimit == 5) + printk("disabling above message until next recalib\n"); + } + return; + } + + adev->recalib_msg_ratelimit = 0; + + /* note that commands sometimes fail (card busy), + * so only clear flag if we were fully successful */ + res = acx_s_recalib_radio(adev); + if (res == OK) { + printk("%s: successfully recalibrated radio\n", + adev->ndev->name); + adev->recalib_time_last_success = jiffies; + adev->recalib_failure_count = 0; + } else { + /* failed: resubmit, but only limited + * amount of times within some time range + * to prevent endless loop */ + + adev->recalib_time_last_success = 0; /* we failed */ + + /* if some time passed between last + * attempts, then reset failure retry counter + * to be able to do next recalib attempt */ + if (time_after(jiffies, adev->recalib_time_last_attempt + 5*HZ)) + adev->recalib_failure_count = 0; + + if (adev->recalib_failure_count < 5) { + /* increment inside only, for speedup of outside path */ + adev->recalib_failure_count++; + adev->recalib_time_last_attempt = jiffies; + acx_schedule_task(adev, ACX_AFTER_IRQ_CMD_RADIO_RECALIB); + } + } +} + +static void +acx_e_after_interrupt_task(struct work_struct *work) +{ + acx_device_t *adev = container_of(work, acx_device_t, after_interrupt_task); + + FN_ENTER; + + acx_sem_lock(adev); + + if (!adev->after_interrupt_jobs) + goto end; /* no jobs to do */ + +#if TX_CLEANUP_IN_SOFTIRQ + /* can happen only on PCI */ + if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_TX_CLEANUP) { + acx_lock(adev, flags); + acxpci_l_clean_txdesc(adev); + CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_TX_CLEANUP); + acx_unlock(adev, flags); + } +#endif + /* we see lotsa tx errors */ + if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_RADIO_RECALIB) { + acx_s_after_interrupt_recalib(adev); + } + + /* a poor interrupt code wanted to do update_card_settings() */ + if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_UPDATE_CARD_CFG) { + if (ACX_STATE_IFACE_UP & adev->dev_state_mask) + acx_s_update_card_settings(adev); + CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_UPDATE_CARD_CFG); + } + + /* 1) we detected that no Scan_Complete IRQ came from fw, or + ** 2) we found too many STAs */ + if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_STOP_SCAN) { + log(L_IRQ, "sending a stop scan cmd...\n"); + acx_s_issue_cmd(adev, ACX1xx_CMD_STOP_SCAN, NULL, 0); + /* HACK: set the IRQ bit, since we won't get a + * scan complete IRQ any more on ACX111 (works on ACX100!), + * since _we_, not a fw, have stopped the scan */ + SET_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE); + CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_STOP_SCAN); + } + + /* either fw sent Scan_Complete or we detected that + ** no Scan_Complete IRQ came from fw. Finish scanning, + ** pick join partner if any */ + if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_COMPLETE_SCAN) { + if (adev->status == ACX_STATUS_1_SCANNING) { + if (OK != acx_s_complete_scan(adev)) { + SET_BIT(adev->after_interrupt_jobs, + ACX_AFTER_IRQ_RESTART_SCAN); + } + } else { + /* + scan kills current join status - restore it + ** (do we need it for STA?) */ + /* + does it happen only with active scans? + ** active and passive scans? ALL scans including + ** background one? */ + /* + was not verified that everything is restored + ** (but at least we start to emit beacons again) */ + switch (adev->mode) { + case ACX_MODE_0_ADHOC: + case ACX_MODE_3_AP: + log(L_IRQ, "redoing cmd_join_bssid() after scan\n"); + acx_s_cmd_join_bssid(adev, adev->bssid); + } + } + CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_COMPLETE_SCAN); + } + + /* STA auth or assoc timed out, start over again */ + if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_RESTART_SCAN) { + log(L_IRQ, "sending a start_scan cmd...\n"); + acx_s_cmd_start_scan(adev); + CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_RESTART_SCAN); + } + + /* whee, we got positive assoc response! 8) */ + if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_ASSOCIATE) { + acx_ie_generic_t pdr; + /* tiny race window exists, checking that we still a STA */ + switch (adev->mode) { + case ACX_MODE_2_STA: + pdr.m.aid = cpu_to_le16(adev->aid); + acx_s_configure(adev, &pdr, ACX1xx_IE_ASSOC_ID); + acx_set_status(adev, ACX_STATUS_4_ASSOCIATED); + log(L_ASSOC|L_DEBUG, "ASSOCIATED!\n"); + CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_ASSOCIATE); + } + } +end: + acx_sem_unlock(adev); + FN_EXIT0; +} + + +/*********************************************************************** +** acx_schedule_task +** +** Schedule the call of the after_interrupt method after leaving +** the interrupt context. +*/ +void +acx_schedule_task(acx_device_t *adev, unsigned int set_flag) +{ + SET_BIT(adev->after_interrupt_jobs, set_flag); + SCHEDULE_WORK(&adev->after_interrupt_task); +} + + +/*********************************************************************** +*/ +void +acx_init_task_scheduler(acx_device_t *adev) +{ + /* configure task scheduler */ + INIT_WORK(&adev->after_interrupt_task, acx_e_after_interrupt_task); +} + + +/*********************************************************************** +** acx_s_start +*/ +void +acx_s_start(acx_device_t *adev) +{ + FN_ENTER; + + /* + * Ok, now we do everything that can possibly be done with ioctl + * calls to make sure that when it was called before the card + * was up we get the changes asked for + */ + + SET_BIT(adev->set_mask, SET_TEMPLATES|SET_STA_LIST|GETSET_WEP + |GETSET_TXPOWER|GETSET_ANTENNA|GETSET_ED_THRESH|GETSET_CCA + |GETSET_REG_DOMAIN|GETSET_MODE|GETSET_CHANNEL + |GETSET_TX|GETSET_RX|GETSET_STATION_ID); + + log(L_INIT, "updating initial settings on iface activation\n"); + acx_s_update_card_settings(adev); + + FN_EXIT0; +} + + +/*********************************************************************** +** acx_update_capabilities +*/ +void +acx_update_capabilities(acx_device_t *adev) +{ + u16 cap = 0; + + switch (adev->mode) { + case ACX_MODE_3_AP: + SET_BIT(cap, WF_MGMT_CAP_ESS); break; + case ACX_MODE_0_ADHOC: + SET_BIT(cap, WF_MGMT_CAP_IBSS); break; + /* other types of stations do not emit beacons */ + } + + if (adev->wep_restricted) { + SET_BIT(cap, WF_MGMT_CAP_PRIVACY); + } + if (adev->cfgopt_dot11ShortPreambleOption) { + SET_BIT(cap, WF_MGMT_CAP_SHORT); + } + if (adev->cfgopt_dot11PBCCOption) { + SET_BIT(cap, WF_MGMT_CAP_PBCC); + } + if (adev->cfgopt_dot11ChannelAgility) { + SET_BIT(cap, WF_MGMT_CAP_AGILITY); + } + log(L_DEBUG, "caps updated from 0x%04X to 0x%04X\n", + adev->capabilities, cap); + adev->capabilities = cap; +} + +/*********************************************************************** +** Common function to parse ALL configoption struct formats +** (ACX100 and ACX111; FIXME: how to make it work with ACX100 USB!?!?). +** FIXME: logging should be removed here and added to a /proc file instead +*/ +void +acx_s_parse_configoption(acx_device_t *adev, const acx111_ie_configoption_t *pcfg) +{ + const u8 *pEle; + int i; + int is_acx111 = IS_ACX111(adev); + + if (acx_debug & L_DEBUG) { + printk("configoption struct content:\n"); + acx_dump_bytes(pcfg, sizeof(*pcfg)); + } + + if (( is_acx111 && (adev->eeprom_version == 5)) + || (!is_acx111 && (adev->eeprom_version == 4)) + || (!is_acx111 && (adev->eeprom_version == 5))) { + /* these versions are known to be supported */ + } else { + printk("unknown chip and EEPROM version combination (%s, v%d), " + "don't know how to parse config options yet. " + "Please report\n", is_acx111 ? "ACX111" : "ACX100", + adev->eeprom_version); + return; + } + + /* first custom-parse the first part which has chip-specific layout */ + + pEle = (const u8 *) pcfg; + + pEle += 4; /* skip (type,len) header */ + + memcpy(adev->cfgopt_NVSv, pEle, sizeof(adev->cfgopt_NVSv)); + pEle += sizeof(adev->cfgopt_NVSv); + + if (is_acx111) { + adev->cfgopt_NVS_vendor_offs = le16_to_cpu(*(u16 *)pEle); + pEle += sizeof(adev->cfgopt_NVS_vendor_offs); + + adev->cfgopt_probe_delay = 200; /* good default value? */ + pEle += 2; /* FIXME: unknown, value 0x0001 */ + } else { + memcpy(adev->cfgopt_MAC, pEle, sizeof(adev->cfgopt_MAC)); + pEle += sizeof(adev->cfgopt_MAC); + + adev->cfgopt_probe_delay = le16_to_cpu(*(u16 *)pEle); + pEle += sizeof(adev->cfgopt_probe_delay); + if ((adev->cfgopt_probe_delay < 100) || (adev->cfgopt_probe_delay > 500)) { + printk("strange probe_delay value %d, " + "tweaking to 200\n", adev->cfgopt_probe_delay); + adev->cfgopt_probe_delay = 200; + } + } + + adev->cfgopt_eof_memory = le32_to_cpu(*(u32 *)pEle); + pEle += sizeof(adev->cfgopt_eof_memory); + + printk("NVS_vendor_offs:%04X probe_delay:%d eof_memory:%d\n", + adev->cfgopt_NVS_vendor_offs, + adev->cfgopt_probe_delay, + adev->cfgopt_eof_memory); + + adev->cfgopt_dot11CCAModes = *pEle++; + adev->cfgopt_dot11Diversity = *pEle++; + adev->cfgopt_dot11ShortPreambleOption = *pEle++; + adev->cfgopt_dot11PBCCOption = *pEle++; + adev->cfgopt_dot11ChannelAgility = *pEle++; + adev->cfgopt_dot11PhyType = *pEle++; + adev->cfgopt_dot11TempType = *pEle++; + printk("CCAModes:%02X Diversity:%02X ShortPreOpt:%02X " + "PBCC:%02X ChanAgil:%02X PHY:%02X Temp:%02X\n", + adev->cfgopt_dot11CCAModes, + adev->cfgopt_dot11Diversity, + adev->cfgopt_dot11ShortPreambleOption, + adev->cfgopt_dot11PBCCOption, + adev->cfgopt_dot11ChannelAgility, + adev->cfgopt_dot11PhyType, + adev->cfgopt_dot11TempType); + + /* then use common parsing for next part which has common layout */ + + pEle++; /* skip table_count (6) */ + + adev->cfgopt_antennas.type = pEle[0]; + adev->cfgopt_antennas.len = pEle[1]; + printk("AntennaID:%02X Len:%02X Data:", + adev->cfgopt_antennas.type, adev->cfgopt_antennas.len); + for (i = 0; i < pEle[1]; i++) { + adev->cfgopt_antennas.list[i] = pEle[i+2]; + printk("%02X ", pEle[i+2]); + } + printk("\n"); + + pEle += pEle[1] + 2; + adev->cfgopt_power_levels.type = pEle[0]; + adev->cfgopt_power_levels.len = pEle[1]; + printk("PowerLevelID:%02X Len:%02X Data:", + adev->cfgopt_power_levels.type, adev->cfgopt_power_levels.len); + for (i = 0; i < pEle[1]; i++) { + adev->cfgopt_power_levels.list[i] = le16_to_cpu(*(u16 *)&pEle[i*2+2]); + printk("%04X ", adev->cfgopt_power_levels.list[i]); + } + printk("\n"); + + pEle += pEle[1]*2 + 2; + adev->cfgopt_data_rates.type = pEle[0]; + adev->cfgopt_data_rates.len = pEle[1]; + printk("DataRatesID:%02X Len:%02X Data:", + adev->cfgopt_data_rates.type, adev->cfgopt_data_rates.len); + for (i = 0; i < pEle[1]; i++) { + adev->cfgopt_data_rates.list[i] = pEle[i+2]; + printk("%02X ", pEle[i+2]); + } + printk("\n"); + + pEle += pEle[1] + 2; + adev->cfgopt_domains.type = pEle[0]; + adev->cfgopt_domains.len = pEle[1]; + printk("DomainID:%02X Len:%02X Data:", + adev->cfgopt_domains.type, adev->cfgopt_domains.len); + for (i = 0; i < pEle[1]; i++) { + adev->cfgopt_domains.list[i] = pEle[i+2]; + printk("%02X ", pEle[i+2]); + } + printk("\n"); + + pEle += pEle[1] + 2; + adev->cfgopt_product_id.type = pEle[0]; + adev->cfgopt_product_id.len = pEle[1]; + for (i = 0; i < pEle[1]; i++) { + adev->cfgopt_product_id.list[i] = pEle[i+2]; + } + printk("ProductID:%02X Len:%02X Data:%.*s\n", + adev->cfgopt_product_id.type, adev->cfgopt_product_id.len, + adev->cfgopt_product_id.len, (char *)adev->cfgopt_product_id.list); + + pEle += pEle[1] + 2; + adev->cfgopt_manufacturer.type = pEle[0]; + adev->cfgopt_manufacturer.len = pEle[1]; + for (i = 0; i < pEle[1]; i++) { + adev->cfgopt_manufacturer.list[i] = pEle[i+2]; + } + printk("ManufacturerID:%02X Len:%02X Data:%.*s\n", + adev->cfgopt_manufacturer.type, adev->cfgopt_manufacturer.len, + adev->cfgopt_manufacturer.len, (char *)adev->cfgopt_manufacturer.list); +/* + printk("EEPROM part:\n"); + for (i=0; i<58; i++) { + printk("%02X =======> 0x%02X\n", + i, (u8 *)adev->cfgopt_NVSv[i-2]); + } +*/ +} + + +/*********************************************************************** +*/ +static int __init +acx_e_init_module(void) +{ + int r1,r2; + + acx_struct_size_check(); +#if 0 + printk("acx: this driver is still EXPERIMENTAL\n" + "acx: reading README file and/or Craig's HOWTO is " + "recommended, visit http://acx100.sf.net in case " + "of further questions/discussion\n"); +#endif + printk(KERN_INFO "acx: Loaded combined PCI/USB driver, firmware_ver=%s\n", + firmware_ver); +#if defined(CONFIG_NET_ACX_PCI) + r1 = acxpci_e_init_module(); +#else + r1 = -EINVAL; +#endif +#if defined(CONFIG_NET_ACX_USB) + r2 = acxusb_e_init_module(); +#else + r2 = -EINVAL; +#endif + if (r2 && r1) /* both failed! */ + return r2 ? r2 : r1; + /* return success if at least one succeeded */ + return 0; +} + +static void __exit +acx_e_cleanup_module(void) +{ +#if defined(CONFIG_NET_ACX_PCI) + acxpci_e_cleanup_module(); +#endif +#if defined(CONFIG_NET_ACX_USB) + acxusb_e_cleanup_module(); +#endif +} + +module_init(acx_e_init_module) +module_exit(acx_e_cleanup_module) --- linux-2.6.28.orig/ubuntu/aufs/dentry.h +++ linux-2.6.28/ubuntu/aufs/dentry.h @@ -0,0 +1,396 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * lookup and dentry operations + * + * $Id: dentry.h,v 1.7 2008/09/01 02:54:54 sfjro Exp $ + */ + +#ifndef __AUFS_DENTRY_H__ +#define __AUFS_DENTRY_H__ + +#ifdef __KERNEL__ + +#include +#include +#include +#include "misc.h" +#include "super.h" +#include "vfsub.h" + +/* nameidata open_intent */ +enum { + AuIntent_AUFS, + AuIntent_BRANCH, + AuIntent_Last +}; + +struct au_hdintent { + struct list_head hdi_list; + struct file *hdi_file[AuIntent_Last]; +}; + +struct au_hdentry { + struct dentry *hd_dentry; + +#ifdef CONFIG_AUFS_BR_NFS + spinlock_t hd_lock; /* intest_list */ + struct list_head *hd_intent_list; +#endif +}; + +struct au_dinfo { + atomic_t di_generation; + + struct au_rwsem di_rwsem; + aufs_bindex_t di_bstart, di_bend, di_bwh, di_bdiropq; + struct au_hdentry *di_hdentry; +}; + +/* nameidata extension flags */ +#define AuNdx_DLGT 1 +#define AuNdx_DIRPERM1 (1 << 1) +#define au_ftest_ndx(flags, name) ((flags) & AuNdx_##name) +#define au_fset_ndx(flags, name) { (flags) |= AuNdx_##name; } +#define au_fclr_ndx(flags, name) { (flags) &= ~AuNdx_##name; } +#ifndef CONFIG_AUFS_DLGT +#undef AuNdx_DLGT +#define AuNdx_DLGT 0 +#undef AuNdx_DIRPERM1 +#define AuNdx_DIRPERM1 0 +#endif + +struct au_ndx { + struct vfsmount *nfsmnt; + unsigned int flags; + struct nameidata *nd; + struct au_branch *br; + struct file *nd_file; +}; + +/* ---------------------------------------------------------------------- */ + +static inline void au_do_h_dentry_init(struct au_hdentry *hdentry) +{ + hdentry->hd_dentry = NULL; +} + +#ifdef CONFIG_AUFS_BR_NFS +static inline void au_h_dentry_init(struct au_hdentry *hdentry) +{ + au_do_h_dentry_init(hdentry); + spin_lock_init(&hdentry->hd_lock); +} + +static inline void au_h_dentry_init_all(struct au_hdentry *hdentry, int n) +{ + while (n--) + spin_lock_init(&hdentry[n].hd_lock); +} + +/* br_nfs.c */ +struct file *au_h_intent(struct dentry *dentry, aufs_bindex_t bindex, + struct file *file); +int au_br_nfs_h_intent(struct file *nd_file, struct dentry *dentry, + aufs_bindex_t bindex, struct nameidata *nd); +void au_hintent_put(struct au_hdentry *hd, int do_free); +int au_fake_intent(struct nameidata *nd, int perm); +int au_hin_after_reval(struct nameidata *nd, struct dentry *dentry, + aufs_bindex_t bindex, struct file *file); +struct dentry *au_lkup_hash(const char *name, struct dentry *parent, int len, + struct au_ndx *ndx); +#else + +static inline void au_h_dentry_init(struct au_hdentry *hdentry) +{ + au_do_h_dentry_init(hdentry); +} + +static inline void au_h_dentry_init_all(struct au_hdentry *hdentry, int n) +{ + /* nothing */ +} + +static inline +struct file *au_h_intent(struct dentry *dentry, aufs_bindex_t bindex, + struct file *file) +{ + /* return ERR_PTR(-ENOSYS); */ + return NULL; +} + +static inline +int au_br_nfs_h_intent(struct file *nd_file, struct dentry *dentry, + aufs_bindex_t bindex, struct nameidata *nd) +{ + return 0; +} + +static inline void au_hintent_put(struct au_hdentry *hd, int do_free) +{ + /* empty */ +} + +static inline int au_fake_intent(struct nameidata *nd, int perm) +{ + return 0; +} + +static inline +int au_hin_after_reval(struct nameidata *nd, struct dentry *dentry, + aufs_bindex_t bindex, struct file *file) +{ + return 0; +} + +#ifdef CONFIG_AUFS_DLGT +static inline +struct dentry *au_lkup_hash(const char *name, struct dentry *parent, int len, + struct au_ndx *ndx) +{ + /* return ERR_PTR(-ENOSYS); */ + return vfsub_lookup_one_len(name, parent, len); +} +#endif +#endif /* CONFIG_AUFS_BR_NFS */ + +#ifdef CONFIG_AUFS_DLGT +/* dlgt.c */ +struct dentry *au_lkup_one_dlgt(const char *name, struct dentry *parent, + int len, unsigned int flags); +#elif defined(CONFIG_AUFS_BR_NFS) +/* regardelss kernel version */ +static inline +struct dentry *au_lkup_one_dlgt(const char *name, struct dentry *parent, + int len, unsigned int flags) +{ + return vfsub_lookup_one_len(name, parent, len); +} +#endif + +/* dentry.c */ +extern struct dentry_operations aufs_dop; +#if defined(CONFIG_AUFS_BR_NFS) || defined(CONFIG_AUFS_DLGT) +struct dentry *au_lkup_one(const char *name, struct dentry *parent, int len, + struct au_ndx *ndx); +#else +static inline +struct dentry *au_lkup_one(const char *name, struct dentry *parent, int len, + struct au_ndx *ndx) +{ + /* todo? ndx->nd_file = NULL; */ + return vfsub_lookup_one_len(name, parent, len); +} +#endif +struct dentry *au_sio_lkup_one(const char *name, struct dentry *parent, int len, + struct au_ndx *ndx); +int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type, + struct nameidata *nd); +int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex); +int au_refresh_hdentry(struct dentry *dentry, mode_t type); +int au_reval_dpath(struct dentry *dentry, au_gen_t sgen); + +/* dinfo.c */ +int au_alloc_dinfo(struct dentry *dentry); +struct au_dinfo *au_di(struct dentry *dentry); + +void di_read_lock(struct dentry *d, int flags, unsigned int lsc); +void di_read_unlock(struct dentry *d, int flags); +void di_downgrade_lock(struct dentry *d, int flags); +void di_write_lock(struct dentry *d, unsigned int lsc); +void di_write_unlock(struct dentry *d); +void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir); +void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir); +void di_write_unlock2(struct dentry *d1, struct dentry *d2); + +struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex); + +aufs_bindex_t au_dbtail(struct dentry *dentry); +aufs_bindex_t au_dbtaildir(struct dentry *dentry); +#if 0 /* reserved for future use */ +aufs_bindex_t au_dbtail_generic(struct dentry *dentry); +#endif + +void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex); +void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex, + struct dentry *h_dentry); + +void au_update_dbrange(struct dentry *dentry, int do_put_zero); +void au_update_dbstart(struct dentry *dentry); +void au_update_dbend(struct dentry *dentry); +int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry); + +/* ---------------------------------------------------------------------- */ + +/* todo: memory barrier? */ +static inline au_gen_t au_digen(struct dentry *d) +{ + return atomic_read(&au_di(d)->di_generation); +} + +#ifdef CONFIG_AUFS_HINOTIFY +static inline au_gen_t au_digen_dec(struct dentry *d) +{ + return atomic_dec_return(&au_di(d)->di_generation); +} + +static inline void au_hin_di_reinit(struct dentry *d) +{ + d->d_fsdata = NULL; +} +#else +static inline void au_hin_di_reinit(struct dentry *d) +{ + /* empty */ +} +#endif /* CONFIG_AUFS_HINOTIFY */ + +/* ---------------------------------------------------------------------- */ + +/* lock subclass for dinfo */ +enum { + AuLsc_DI_CHILD, /* child first */ + AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hinotify */ + AuLsc_DI_CHILD3, /* copyup dirs */ + AuLsc_DI_PARENT, + AuLsc_DI_PARENT2, + AuLsc_DI_PARENT3, + AuLsc_DI_PARENT4 +}; + +/* + * di_read_lock_child, di_write_lock_child, + * di_read_lock_child2, di_write_lock_child2, + * di_read_lock_child3, di_write_lock_child3, + * di_read_lock_parent, di_write_lock_parent, + * di_read_lock_parent2, di_write_lock_parent2, + * di_read_lock_parent3, di_write_lock_parent3, + * di_read_lock_parent4, di_write_lock_parent4, + */ +#define AuReadLockFunc(name, lsc) \ +static inline void di_read_lock_##name(struct dentry *d, int flags) \ +{ di_read_lock(d, flags, AuLsc_DI_##lsc); } + +#define AuWriteLockFunc(name, lsc) \ +static inline void di_write_lock_##name(struct dentry *d) \ +{ di_write_lock(d, AuLsc_DI_##lsc); } + +#define AuRWLockFuncs(name, lsc) \ + AuReadLockFunc(name, lsc) \ + AuWriteLockFunc(name, lsc) + +AuRWLockFuncs(child, CHILD); +AuRWLockFuncs(child2, CHILD2); +AuRWLockFuncs(child3, CHILD3); +AuRWLockFuncs(parent, PARENT); +AuRWLockFuncs(parent2, PARENT2); +AuRWLockFuncs(parent3, PARENT3); +AuRWLockFuncs(parent4, PARENT4); + +#undef AuReadLockFunc +#undef AuWriteLockFunc +#undef AuRWLockFuncs + +/* to debug easier, do not make them inlined functions */ +#define DiMustReadLock(d) do { \ + SiMustAnyLock((d)->d_sb); \ + AuRwMustReadLock(&au_di(d)->di_rwsem); \ +} while (0) + +#define DiMustWriteLock(d) do { \ + SiMustAnyLock((d)->d_sb); \ + AuRwMustWriteLock(&au_di(d)->di_rwsem); \ +} while (0) + +#define DiMustAnyLock(d) do { \ + SiMustAnyLock((d)->d_sb); \ + AuRwMustAnyLock(&au_di(d)->di_rwsem); \ +} while (0) + +#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem) + +/* ---------------------------------------------------------------------- */ + +static inline aufs_bindex_t au_dbstart(struct dentry *dentry) +{ + DiMustAnyLock(dentry); + return au_di(dentry)->di_bstart; +} + +static inline aufs_bindex_t au_dbend(struct dentry *dentry) +{ + DiMustAnyLock(dentry); + return au_di(dentry)->di_bend; +} + +static inline aufs_bindex_t au_dbwh(struct dentry *dentry) +{ + DiMustAnyLock(dentry); + return au_di(dentry)->di_bwh; +} + +static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry) +{ + DiMustAnyLock(dentry); + AuDebugOn(dentry->d_inode + && dentry->d_inode->i_mode + && !S_ISDIR(dentry->d_inode->i_mode)); + return au_di(dentry)->di_bdiropq; +} + +/* todo: hard/soft set? */ +static inline void au_set_dbstart(struct dentry *dentry, aufs_bindex_t bindex) +{ + DiMustWriteLock(dentry); + AuDebugOn(au_sbend(dentry->d_sb) < bindex); + /* */ + au_di(dentry)->di_bstart = bindex; +} + +static inline void au_set_dbend(struct dentry *dentry, aufs_bindex_t bindex) +{ + DiMustWriteLock(dentry); + AuDebugOn(au_sbend(dentry->d_sb) < bindex + || bindex < au_dbstart(dentry)); + au_di(dentry)->di_bend = bindex; +} + +static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex) +{ + DiMustWriteLock(dentry); + AuDebugOn(au_sbend(dentry->d_sb) < bindex); + /* dbwh can be outside of bstart - bend range */ + au_di(dentry)->di_bwh = bindex; +} + +static inline void au_hdput(struct au_hdentry *hd, int do_free) +{ + au_hintent_put(hd, do_free); + dput(hd->hd_dentry); +} + +static inline void au_update_digen(struct dentry *dentry) +{ + AuDebugOn(!dentry->d_sb); + atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb)); + /* smp_mb(); */ /* atomic_set */ +} + +#endif /* __KERNEL__ */ +#endif /* __AUFS_DENTRY_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/wbr_policy.c +++ linux-2.6.28/ubuntu/aufs/wbr_policy.c @@ -0,0 +1,699 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * policies for selecting one among multiple writable branches + * + * $Id: wbr_policy.c,v 1.12 2008/09/01 02:55:35 sfjro Exp $ + */ + +#include +#include "aufs.h" + +static int au_cpdown_attr(struct au_hinode *hdir, struct dentry *h_dst, + struct dentry *h_src) +{ + int err, sbits; + struct iattr ia; + struct inode *h_idst, *h_isrc; + + LKTRTrace("%.*s\n", AuDLNPair(h_dst)); + h_idst = h_dst->d_inode; + /* todo? IMustLock(h_idst); */ + h_isrc = h_src->d_inode; + /* todo? IMustLock(h_isrc); */ + + ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID; + ia.ia_mode = h_isrc->i_mode; + ia.ia_uid = h_isrc->i_uid; + ia.ia_gid = h_isrc->i_gid; + sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID)); + + err = vfsub_sio_notify_change(hdir, h_dst, &ia); + + /* is this nfs only? */ + if (!err && sbits && au_test_nfs(h_dst->d_sb)) { + ia.ia_valid = ATTR_FORCE | ATTR_MODE; + ia.ia_mode = h_isrc->i_mode; + err = vfsub_sio_notify_change(hdir, h_dst, &ia); + } + + /* todo: necessary? */ + if (!err) + h_idst->i_flags = h_isrc->i_flags; + + AuTraceErr(err); + return err; +} + +struct au_cpdown_dir_args { + struct dentry *parent; + unsigned int parent_opq; /* bit-flags */ +}; + +static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst, + struct dentry *h_parent, void *arg) +{ + int err, rerr; + struct au_cpdown_dir_args *args = arg; + aufs_bindex_t bend, bopq, bstart; + unsigned char parent_opq, whed, dlgt, do_opq, made_dir, diropq; + struct dentry *h_dentry, *opq_dentry, *wh_dentry, *parent; + struct inode *h_dir, *h_inode, *inode, *dir; + + LKTRTrace("%.*s, b%d\n", AuDLNPair(dentry), bdst); + bstart = au_dbstart(dentry); + AuDebugOn(bstart <= bdst + && bdst <= au_dbend(dentry) + && au_h_dptr(dentry, bdst)); + AuDebugOn(!h_parent); + /* todo: safe? */ + parent = dget_parent(dentry); + dir = parent->d_inode; + dput(parent); + h_dir = h_parent->d_inode; + AuDebugOn(!h_dir); + AuDebugOn(h_dir != au_h_iptr(dir, bdst)); + IMustLock(h_dir); + + err = au_lkup_neg(dentry, bdst); + if (unlikely(err < 0)) + goto out; + h_dentry = au_h_dptr(dentry, bdst); + dlgt = !!au_test_dlgt(au_mntflags(dentry->d_sb)); + err = vfsub_sio_mkdir(au_hi(dir, bdst), h_dentry, S_IRWXU | S_IRUGO | S_IXUGO, + dlgt); + if (unlikely(err)) + goto out_put; + + made_dir = 1; + bend = au_dbend(dentry); + bopq = au_dbdiropq(dentry); + whed = (au_dbwh(dentry) == bdst); + if (!args->parent_opq) + args->parent_opq |= (bopq <= bdst); + parent_opq = (args->parent_opq && args->parent == dentry); + do_opq = 0; + diropq = 0; + h_inode = h_dentry->d_inode; + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); + if (whed || (parent_opq && do_opq)) { + opq_dentry = au_diropq_create(dentry, bdst, dlgt); + err = PTR_ERR(opq_dentry); + if (IS_ERR(opq_dentry)) { + mutex_unlock(&h_inode->i_mutex); + goto out_dir; + } + dput(opq_dentry); + diropq = 1; + } + + err = au_cpdown_attr(au_hi(dir, bdst), h_dentry, au_h_dptr(dentry, bstart)); + mutex_unlock(&h_inode->i_mutex); + if (unlikely(err)) + goto out_opq; + + wh_dentry = NULL; + if (whed) { + wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, /*ndx*/NULL); + err = PTR_ERR(wh_dentry); + if (IS_ERR(wh_dentry)) + goto out_opq; + err = 0; + if (wh_dentry->d_inode) + err = au_wh_unlink_dentry(au_hi(dir, bdst), wh_dentry, + dentry, dlgt); + dput(wh_dentry); + if (unlikely(err)) + goto out_opq; + } + + inode = dentry->d_inode; + if (au_ibend(inode) < bdst) + au_set_ibend(inode, bdst); + au_set_h_iptr(inode, bdst, au_igrab(h_inode), au_hi_flags(inode, 1)); + goto out; /* success */ + + /* revert */ + out_opq: + if (diropq) { + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); + rerr = au_diropq_remove(dentry, bdst, dlgt); + mutex_unlock(&h_inode->i_mutex); + if (unlikely(rerr)) { + AuIOErr("failed removing diropq for %.*s b%d (%d)\n", + AuDLNPair(dentry), bdst, rerr); + err = -EIO; + goto out; + } + } + out_dir: + if (made_dir) { + rerr = vfsub_sio_rmdir(au_hi(dir, bdst), h_dentry, dlgt); + if (unlikely(rerr)) { + AuIOErr("failed removing %.*s b%d (%d)\n", + AuDLNPair(dentry), bdst, rerr); + err = -EIO; + } + } + out_put: + au_set_h_dptr(dentry, bdst, NULL); + if (au_dbend(dentry) == bdst) + au_update_dbend(dentry); + out: + AuTraceErr(err); + return err; +} + +int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst) +{ + int err; + struct au_cpdown_dir_args args = { + .parent = dget_parent(dentry), + .parent_opq = 0 + }; + + LKTRTrace("%.*s, b%d\n", AuDLNPair(dentry), bdst); + + err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &args); + dput(args.parent); + + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +/* policies for create */ + +static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex) +{ + for (; bindex >= 0; bindex--) + if (!au_br_rdonly(au_sbr(sb, bindex))) + return bindex; + return -EROFS; +} + +/* top down parent */ +static int au_wbr_create_tdp(struct dentry *dentry, int isdir) +{ + int err; + struct super_block *sb; + aufs_bindex_t bstart, bindex; + unsigned char dirperm1; + struct dentry *parent, *h_parent; + struct inode *h_dir; + + LKTRTrace("%.*s, dir %d\n", AuDLNPair(dentry), isdir); + + sb = dentry->d_sb; + dirperm1 = !!au_test_dirperm1(au_mntflags(sb)); + bstart = au_dbstart(dentry); + AuDebugOn(bstart < 0); + err = bstart; + /* todo: can 'err' be an illegal? */ + if (/* err >= 0 && */ !au_br_rdonly(au_sbr(sb, bstart))) + goto out; + + err = -EROFS; + parent = dget_parent(dentry); + for (bindex = au_dbstart(parent); bindex < bstart; bindex++) { + h_parent = au_h_dptr(parent, bindex); + if (!h_parent) + continue; + h_dir = h_parent->d_inode; + if (!h_dir) + continue; + + if (!au_br_rdonly(au_sbr(sb, bindex)) + && (!dirperm1 + || au_test_h_perm(h_dir, MAY_WRITE | MAY_EXEC, + /*dlgt*/0))) { + err = bindex; + break; + } + } + dput(parent); + + /* bottom up here */ + if (unlikely(err < 0)) + err = au_wbr_bu(sb, bstart - 1); + + out: + LKTRTrace("b%d\n", err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +/* an exception for the policy other than tdp */ +static int au_wbr_create_exp(struct dentry *dentry) +{ + int err; + struct dentry *parent; + aufs_bindex_t bwh, bdiropq; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + + err = -1; + bwh = au_dbwh(dentry); + parent = dget_parent(dentry); + bdiropq = au_dbdiropq(parent); + if (bwh >= 0) { + if (bdiropq >= 0) + err = min(bdiropq, bwh); + else + err = bwh; + LKTRTrace("%d\n", err); + } else if (bdiropq >= 0) { + err = bdiropq; + LKTRTrace("%d\n", err); + } + dput(parent); + + if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err))) + err = -1; + + LKTRTrace("%d\n", err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +/* round robin */ +static int au_wbr_create_init_rr(struct super_block *sb) +{ + int err; + + err = au_wbr_bu(sb, au_sbend(sb)); + atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */ + + LKTRTrace("b%d\n", err); + return err; +} + +static int au_wbr_create_rr(struct dentry *dentry, int isdir) +{ + int err, nbr; + struct super_block *sb; + atomic_t *next; + unsigned int u; + aufs_bindex_t bindex, bend; + + LKTRTrace("%.*s, dir %d\n", AuDLNPair(dentry), isdir); + + sb = dentry->d_sb; + next = NULL; + err = au_wbr_create_exp(dentry); + if (err >= 0) + goto out; + + next = &au_sbi(sb)->si_wbr_rr_next; + bend = au_sbend(sb); + nbr = bend + 1; + for (bindex = 0; bindex <= bend; bindex++) { + if (!isdir) { + err = atomic_dec_return(next) + 1; + /* modulo for 0 is meaningless */ + if (unlikely(!err)) + err = atomic_dec_return(next) + 1; + } else + err = atomic_read(next); + LKTRTrace("%d\n", err); + u = err; + err = u % nbr; + LKTRTrace("%d\n", err); + if (!au_br_rdonly(au_sbr(sb, err))) + break; + err = -EROFS; + } + + out: + LKTRTrace("%d\n", err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +/* most free space */ +static void *au_wbr_statfs_arg(struct au_branch *br, struct super_block *sb, + aufs_bindex_t bindex) +{ + struct super_block *h_sb; + + h_sb = br->br_mnt->mnt_sb; + + if (!au_test_nfs(h_sb)) + return h_sb->s_root; + + /* sigh,,, why nfs s_root has wrong inode? */ + return au_di(sb->s_root)->di_hdentry[0 + bindex].hd_dentry; +} + +static void au_mfs(struct dentry *dentry) +{ + struct super_block *sb; + aufs_bindex_t bindex, bend; + unsigned char dlgt; + int err; + struct kstatfs st; + unsigned long long b, bavail; + void *arg; + struct au_branch *br; + struct au_wbr_mfs *mfs; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + + bavail = 0; + sb = dentry->d_sb; + mfs = &au_sbi(sb)->si_wbr_mfs; + mfs->mfs_bindex = -EROFS; + mfs->mfsrr_bytes = 0; + dlgt = !!au_test_dlgt(au_mntflags(sb)); + bend = au_sbend(sb); + for (bindex = 0; bindex <= bend; bindex++) { + br = au_sbr(sb, bindex); + if (au_br_rdonly(br)) + continue; + AuDebugOn(!br->br_wbr); + arg = au_wbr_statfs_arg(br, sb, bindex); + if (!arg) + continue; + + err = vfsub_statfs(arg, &st, dlgt); + LKTRTrace("b%d, %d, %llu\n", + bindex, err, (unsigned long long)st.f_bavail); + if (unlikely(err)) { + AuWarn1("failed statfs, b%d, %d\n", bindex, err); + continue; + } + + /* when the available size is equal, select lower one */ + b = st.f_bavail * st.f_bsize; + br->br_wbr->wbr_bytes = b; + if (b >= bavail) { + bavail = b; + mfs->mfs_bindex = bindex; + mfs->mfs_jiffy = jiffies; + } + } + + mfs->mfsrr_bytes = bavail; + LKTRTrace("b%d\n", mfs->mfs_bindex); +} + +static int au_wbr_create_mfs(struct dentry *dentry, int isdir) +{ + int err; + struct super_block *sb; + struct au_wbr_mfs *mfs; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + + sb = dentry->d_sb; + err = au_wbr_create_exp(dentry); + if (err >= 0) + goto out; + + mfs = &au_sbi(sb)->si_wbr_mfs; + mutex_lock(&mfs->mfs_lock); + if (unlikely(time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire) + || mfs->mfs_bindex < 0 + || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex)))) + au_mfs(dentry); + mutex_unlock(&mfs->mfs_lock); + err = mfs->mfs_bindex; + + out: + LKTRTrace("b%d\n", err); + return err; +} + +static int au_wbr_create_init_mfs(struct super_block *sb) +{ + struct au_wbr_mfs *mfs; + + mfs = &au_sbi(sb)->si_wbr_mfs; + LKTRTrace("expire %lu\n", mfs->mfs_expire); + + mutex_init(&mfs->mfs_lock); + mfs->mfs_jiffy = 0; + mfs->mfs_bindex = -EROFS; + + return 0; +} + +static int au_wbr_create_fin_mfs(struct super_block *sb) +{ + AuTraceEnter(); + mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock); + return 0; +} + +/* ---------------------------------------------------------------------- */ + +/* most free space and then round robin */ +static int au_wbr_create_mfsrr(struct dentry *dentry, int isdir) +{ + int err; + struct au_wbr_mfs *mfs; + + LKTRTrace("%.*s, %d\n", AuDLNPair(dentry), isdir); + + err = au_wbr_create_mfs(dentry, isdir); + if (err >= 0) { + mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs; + LKTRTrace("%llu bytes, %llu wmark\n", + mfs->mfsrr_bytes, mfs->mfsrr_watermark); + if (unlikely(mfs->mfsrr_bytes < mfs->mfsrr_watermark)) + err = au_wbr_create_rr(dentry, isdir); + } + + LKTRTrace("b%d\n", err); + return err; +} + +static int au_wbr_create_init_mfsrr(struct super_block *sb) +{ + int err; + + au_wbr_create_init_mfs(sb); /* ignore */ + err = au_wbr_create_init_rr(sb); + + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +/* top down parent and most free space */ +static int au_wbr_create_pmfs(struct dentry *dentry, int isdir) +{ + int err, e2; + struct super_block *sb; + struct dentry *parent, *h_parent; + aufs_bindex_t bindex, bstart, bend; + unsigned char dirperm1; + struct au_branch *br; + unsigned long long b; + struct inode *h_dir; + + LKTRTrace("%.*s, %d\n", AuDLNPair(dentry), isdir); + + err = au_wbr_create_tdp(dentry, isdir); + if (unlikely(err < 0)) + goto out; + parent = dget_parent(dentry); + bstart = au_dbstart(parent); + bend = au_dbtaildir(parent); + if (bstart == bend) + goto out_parent; /* success */ + + e2 = au_wbr_create_mfs(dentry, isdir); + if (e2 < 0) + goto out_parent; /* success */ + + /* when the available size is equal, select upper one */ + sb = dentry->d_sb; + br = au_sbr(sb, err); + AuDebugOn(!br->br_wbr); + dirperm1 = !!au_test_dirperm1(au_mntflags(sb)); + b = br->br_wbr->wbr_bytes; + LKTRTrace("b%d, %llu\n", err, b); + + if (unlikely(dirperm1)) { + for (bindex = bstart; bindex <= bend; bindex++) { + h_parent = au_h_dptr(parent, bindex); + if (!h_parent) + continue; + h_dir = h_parent->d_inode; + if (!h_dir) + continue; + + br = au_sbr(sb, bindex); + if (!au_br_rdonly(br) + && au_test_h_perm(h_dir, MAY_WRITE | MAY_EXEC, + /*dlgt*/0) + && br->br_wbr->wbr_bytes > b) { + b = br->br_wbr->wbr_bytes; + err = bindex; + LKTRTrace("b%d, %llu\n", err, b); + } + } + if (err >= 0) + goto out_parent; + } + for (bindex = bstart; bindex <= bend; bindex++) { + h_parent = au_h_dptr(parent, bindex); + if (!h_parent || !h_parent->d_inode) + continue; + + br = au_sbr(sb, bindex); + if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) { + b = br->br_wbr->wbr_bytes; + err = bindex; + LKTRTrace("b%d, %llu\n", err, b); + } + } + + out_parent: + dput(parent); + out: + LKTRTrace("b%d\n", err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +/* policies for copyup */ + +/* top down parent */ +static int au_wbr_copyup_tdp(struct dentry *dentry) +{ + return au_wbr_create_tdp(dentry, /*isdir, anything is ok*/0); +} + +/* bottom up parent */ +static int au_wbr_copyup_bup(struct dentry *dentry) +{ + int err; + struct dentry *parent, *h_parent; + aufs_bindex_t bindex, bstart; + unsigned char dirperm1; + struct super_block *sb; + struct inode *h_dir; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + + err = -EROFS; + sb = dentry->d_sb; + dirperm1 = !!au_test_dirperm1(au_mntflags(sb)); + parent = dget_parent(dentry); + bstart = au_dbstart(parent); + for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) { + h_parent = au_h_dptr(parent, bindex); + if (!h_parent) + continue; + h_dir = h_parent->d_inode; + if (!h_dir) + continue; + + if (!au_br_rdonly(au_sbr(sb, bindex)) + && (!dirperm1 + || au_test_h_perm(h_dir, MAY_WRITE | MAY_EXEC, + /*dlgt*/0))) { + err = bindex; + break; + } + } + dput(parent); + + /* bottom up here */ + if (unlikely(err < 0)) + err = au_wbr_bu(sb, bstart - 1); + + LKTRTrace("b%d\n", err); + return err; +} + +/* bottom up */ +static int au_wbr_copyup_bu(struct dentry *dentry) +{ + int err; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + + err = au_wbr_bu(dentry->d_sb, au_dbstart(dentry)); + + LKTRTrace("b%d\n", err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct au_wbr_copyup_operations au_wbr_copyup_ops[] = { + [AuWbrCopyup_TDP] = { + .copyup = au_wbr_copyup_tdp + }, + [AuWbrCopyup_BUP] = { + .copyup = au_wbr_copyup_bup + }, + [AuWbrCopyup_BU] = { + .copyup = au_wbr_copyup_bu + } +}; + +struct au_wbr_create_operations au_wbr_create_ops[] = { + [AuWbrCreate_TDP] = { + .create = au_wbr_create_tdp + }, + [AuWbrCreate_RR] = { + .create = au_wbr_create_rr, + .init = au_wbr_create_init_rr + }, + [AuWbrCreate_MFS] = { + .create = au_wbr_create_mfs, + .init = au_wbr_create_init_mfs, + .fin = au_wbr_create_fin_mfs + }, + [AuWbrCreate_MFSV] = { + .create = au_wbr_create_mfs, + .init = au_wbr_create_init_mfs, + .fin = au_wbr_create_fin_mfs + }, + [AuWbrCreate_MFSRR] = { + .create = au_wbr_create_mfsrr, + .init = au_wbr_create_init_mfsrr, + .fin = au_wbr_create_fin_mfs + }, + [AuWbrCreate_MFSRRV] = { + .create = au_wbr_create_mfsrr, + .init = au_wbr_create_init_mfsrr, + .fin = au_wbr_create_fin_mfs + }, + [AuWbrCreate_PMFS] = { + .create = au_wbr_create_pmfs, + .init = au_wbr_create_init_mfs, + .fin = au_wbr_create_fin_mfs + }, + [AuWbrCreate_PMFSV] = { + .create = au_wbr_create_pmfs, + .init = au_wbr_create_init_mfs, + .fin = au_wbr_create_fin_mfs + } +}; --- linux-2.6.28.orig/ubuntu/aufs/hinotify.c +++ linux-2.6.28/ubuntu/aufs/hinotify.c @@ -0,0 +1,1133 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * internal/hidden inotify handler + * + * $Id: hinotify.c,v 1.16 2008/09/08 02:39:54 sfjro Exp $ + */ + +#include "aufs.h" + +/* +#ifdef DbgInotify +#define AuDbgHin(args...) AuDbg(##args) +#else +#define AuDbgHin(args...) do {} while () +#endif +*/ + +static struct inotify_handle *in_handle; + +AuCacheFuncs(hinotify, AuCache_HINOTIFY); + +int au_hin_alloc(struct au_hinode *hinode, struct inode *inode, + struct inode *h_inode) +{ + int err; + struct au_hinotify *hin; + s32 wd; + + LKTRTrace("i%lu, hi%lu\n", inode->i_ino, h_inode->i_ino); + + err = -ENOMEM; + hin = au_cache_alloc_hinotify(); + if (hin) { + AuDebugOn(hinode->hi_notify); + hinode->hi_notify = hin; + spin_lock_init(&hin->hin_ignore_lock); + INIT_LIST_HEAD(&hin->hin_ignore_list); + hin->hin_aufs_inode = inode; + + inotify_init_watch(&hin->hin_watch); + wd = inotify_add_watch(in_handle, &hin->hin_watch, h_inode, + AuInMask); + if (wd >= 0) + return 0; /* success */ + + err = wd; + put_inotify_watch(&hin->hin_watch); + au_cache_free_hinotify(hin); + hinode->hi_notify = NULL; + } + + AuTraceErr(err); + return err; +} + +void au_hin_free(struct au_hinode *hinode) +{ + int err; + struct au_hinotify *hin; + + AuTraceEnter(); + + hin = hinode->hi_notify; + if (unlikely(hin)) { + err = 0; + if (atomic_read(&hin->hin_watch.count)) + err = inotify_rm_watch(in_handle, &hin->hin_watch); + if (unlikely(err)) + /* it means the watch is already removed */ + LKTRTrace("failed inotify_rm_watch() %d\n", err); + au_cache_free_hinotify(hin); + hinode->hi_notify = NULL; + } +} + +/* ---------------------------------------------------------------------- */ + +void au_hin_ctl(struct au_hinode *hinode, const __u32 mask) +{ + struct inode *h_inode; + struct inotify_watch *watch; + + h_inode = hinode->hi_inode; + LKTRTrace("hi%lu, sb %p, 0x%x\n", h_inode->i_ino, h_inode->i_sb, mask); + IMustLock(h_inode); + if (!hinode->hi_notify) + return; + + watch = &hinode->hi_notify->hin_watch; +#if 0 /* reserved for future use */ + { + u32 wd; + wd = inotify_find_update_watch(in_handle, h_inode, mask); + AuTraceErr(wd); + /* ignore an err; */ + } +#else + /* struct inotify_handle is hidden */ + mutex_lock(&h_inode->inotify_mutex); + /* mutex_lock(&watch->ih->mutex); */ + watch->mask = mask; + /* mutex_unlock(&watch->ih->mutex); */ + mutex_unlock(&h_inode->inotify_mutex); +#endif + LKTRTrace("watch %p, mask %u\n", watch, watch->mask); +} + +void au_reset_hinotify(struct inode *inode, unsigned int flags) +{ + aufs_bindex_t bindex, bend; + struct inode *hi; + struct dentry *iwhdentry; + + LKTRTrace("i%lu, 0x%x\n", inode->i_ino, flags); + + bend = au_ibend(inode); + for (bindex = au_ibstart(inode); bindex <= bend; bindex++) { + hi = au_h_iptr(inode, bindex); + if (hi) { + /* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */ + iwhdentry = au_hi_wh(inode, bindex); + if (unlikely(iwhdentry)) + dget(iwhdentry); + au_igrab(hi); + au_set_h_iptr(inode, bindex, NULL, 0); + au_set_h_iptr(inode, bindex, au_igrab(hi), + flags & ~AuHi_XINO); + iput(hi); + dput(iwhdentry); + /* mutex_unlock(&hi->i_mutex); */ + } + } +} + +/* ---------------------------------------------------------------------- */ + +void au_unpin_gp(struct au_pin *args) +{ + struct au_pin1 *gp; + + gp = au_pin_gp(args); + AuDebugOn(!gp); + if (gp->dentry) + LKTRTrace("%.*s\n", AuDLNPair(gp->dentry)); + else + AuTraceEnter(); + + au_do_unpin(gp, NULL); +} + +int au_hin_verify_gen(struct dentry *dentry) +{ + struct super_block *sb = dentry->d_sb; + au_gen_t sigen; + struct inode *inode; + + if (!au_opt_test(au_mntflags(sb), UDBA_INOTIFY)) + return 0; + + sigen = au_sigen(dentry->d_sb); + inode = dentry->d_inode; + return (au_digen(dentry) != sigen + || (inode && au_iigen(inode) != sigen)); +} + +/* ---------------------------------------------------------------------- */ + +/* cf. fsnotify_change() */ +__u32 vfsub_events_notify_change(struct iattr *ia) +{ + __u32 events; + const unsigned int amtime = (ATTR_ATIME | ATTR_MTIME); + + events = 0; + if ((ia->ia_valid & (ATTR_UID | ATTR_GID | ATTR_MODE)) + || (ia->ia_valid & amtime) == amtime) + events |= IN_ATTRIB; + if ((ia->ia_valid & ATTR_SIZE) + || (ia->ia_valid & amtime) == ATTR_MTIME) + events |= IN_MODIFY; + return events; +} + +void vfsub_ign_hinode(struct vfsub_args *vargs, __u32 events, + struct au_hinode *hinode) +{ + struct au_hinotify *hin; + struct super_block *sb; + struct au_hin_ignore *ign; + + if (!hinode) + return; + + hin = hinode->hi_notify; + if (!hin || !hin->hin_watch.mask) + return; + + sb = hin->hin_aufs_inode->i_sb; + AuDebugOn(!au_opt_test(au_mntflags(sb), UDBA_INOTIFY)); + + ign = vargs->ignore + vargs->nignore++; + ign->ign_events = events; + ign->ign_handled = 0; + ign->ign_hinode = hinode; + + { + struct inode *h_inode; + h_inode = hinode->hi_inode; + if (!mutex_is_locked(&h_inode->i_mutex)) + au_dbg_blocked(); + IMustLock(h_inode); + } +} + +static void au_hin_ignore(struct au_hin_ignore *ign) +{ + struct au_hinode *hinode; + __u32 events; + struct au_hinotify *hin; + struct inode *h_inode; + + hinode = ign->ign_hinode; + events = ign->ign_events; + LKTRTrace("0x%x\n", events); + AuDebugOn(!hinode || !events); + + hin = hinode->hi_notify; + h_inode = hinode->hi_inode; + if (h_inode && hin) { + LKTRTrace("hi%lu\n", h_inode->i_ino); +#ifdef DbgInotify + AuDbg("hi%lu, 0x%x\n", h_inode->i_ino, events); +#endif + + spin_lock(&hin->hin_ignore_lock); + list_add(&ign->ign_list, &hin->hin_ignore_list); + spin_unlock(&hin->hin_ignore_lock); + /* AuDbg("list_add %p, 0x%x\n", ign, events); */ + } +#if 1 /* todo: test dlgt */ + else + /* + * it may happen by this scenario. + * - a file and its parent dir exist on two branches + * - a file on the upper branch is opened + * - the parent dir and the file are removed by udba + * - the parent is re-accessed, and new dentry/inode in + * aufs is generated for it, based upon the one on the lower + * branch + * - the opened file is re-accessed, re-validated, and it may be + * re-connected to the new parent dentry + * it means the file in aufs cannot get the actual removed + * parent dir on the branch. + */ + INIT_LIST_HEAD(&ign->ign_list); +#endif +} + +static void au_hin_unignore(struct au_hin_ignore *ign) +{ + struct au_hinode *hinode; + __u32 events; + struct au_hinotify *hin; + struct inode *h_inode; + + hinode = ign->ign_hinode; + events = ign->ign_events; + LKTRTrace("0x%x\n", events); + /* AuDbg("0x%x\n", events); */ + AuDebugOn(!hinode || !events); + + hin = hinode->hi_notify; + h_inode = hinode->hi_inode; + if (unlikely(!h_inode || !hin)) + return; + LKTRTrace("hi%lu\n", h_inode->i_ino); +#ifdef DbgInotify + AuDbg("hi%lu, 0x%x\n", h_inode->i_ino, events); +#endif + + spin_lock(&hin->hin_ignore_lock); + au_hin_list_del(&ign->ign_list); + spin_unlock(&hin->hin_ignore_lock); + /* AuDbg("list_del %p, 0x%x\n", ign, events); */ +} + +static int au_hin_test_ignore(u32 mask, struct au_hinotify *hin) +{ + int do_ignore; + struct au_hin_ignore *ign, *tmp; + u32 events; + + do_ignore = 0; + spin_lock(&hin->hin_ignore_lock); + list_for_each_entry_safe(ign, tmp, &hin->hin_ignore_list, ign_list) { + /* AuDbg("ign %p\n", ign); */ + if (ign->ign_pid == current->pid) { + events = (mask & ign->ign_events); + if (events) { + do_ignore = 1; + ign->ign_handled |= events; + if (ign->ign_events == ign->ign_handled) { + list_del_init(&ign->ign_list); + /* + AuDbg("list_del %p, 0x%x\n", + ign, events); + */ + } + break; + } + } + } + spin_unlock(&hin->hin_ignore_lock); + + return do_ignore; +} + +void vfsub_ignore(struct vfsub_args *vargs) +{ + int n; + struct au_hin_ignore *ign; + struct super_block *sb; + struct au_hinode *hinode; + struct inode *h_inode; + + n = vargs->nignore; + if (!n) + return; + + ign = vargs->ignore; + hinode = ign->ign_hinode; + sb = hinode->hi_notify->hin_aufs_inode->i_sb; + h_inode = hinode->hi_inode; + if (unlikely(au_opt_test(au_mntflags(sb), UDBA_INOTIFY))) { + if (!mutex_is_locked(&h_inode->i_mutex)) + au_dbg_blocked(); + IMustLock(h_inode); + } + while (n-- > 0) { + ign->ign_pid = current->pid; + au_hin_ignore(ign++); + } +} + +void vfsub_unignore(struct vfsub_args *vargs) +{ + int n; + struct au_hin_ignore *ign; + + n = vargs->nignore; + if (!n) + return; + + ign = vargs->ignore; + while (n-- > 0) + au_hin_unignore(ign++); +} + +#ifdef CONFIG_AUFS_DEBUG +void au_dbg_hin_list(struct vfsub_args *vargs) +{ + int n; + struct au_hin_ignore *ign; + + n = vargs->nignore; + if (!n) + return; + + ign = vargs->ignore; + while (n-- > 0) { + /* AuDebugOn(!list_empty(&ign++->ign_list)); */ + if (list_empty(&ign++->ign_list)) + continue; + ign--; + AuDbg("%d: pid %d, 0x%x\n", + n + 1, ign->ign_pid, ign->ign_events); + ign++; + au_dbg_blocked(); + } +} +#endif + +/* ---------------------------------------------------------------------- */ + +static char *in_name(u32 mask) +{ +#ifdef CONFIG_AUFS_DEBUG +#define test_ret(flag) if (mask & flag) return #flag; + test_ret(IN_ACCESS); + test_ret(IN_MODIFY); + test_ret(IN_ATTRIB); + test_ret(IN_CLOSE_WRITE); + test_ret(IN_CLOSE_NOWRITE); + test_ret(IN_OPEN); + test_ret(IN_MOVED_FROM); + test_ret(IN_MOVED_TO); + test_ret(IN_CREATE); + test_ret(IN_DELETE); + test_ret(IN_DELETE_SELF); + test_ret(IN_MOVE_SELF); + test_ret(IN_UNMOUNT); + test_ret(IN_Q_OVERFLOW); + test_ret(IN_IGNORED); + return ""; +#undef test_ret +#else + return "??"; +#endif +} + +/* ---------------------------------------------------------------------- */ + +static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen, + struct inode *dir) +{ + struct dentry *dentry, *d, *parent; + struct qstr *dname; + + LKTRTrace("%.*s, dir%lu\n", nlen, name, dir->i_ino); + + parent = d_find_alias(dir); + if (!parent) + return NULL; + + dentry = NULL; + spin_lock(&dcache_lock); + list_for_each_entry(d, &parent->d_subdirs, d_u.d_child) { + LKTRTrace("%.*s\n", AuDLNPair(d)); + dname = &d->d_name; + if (dname->len != nlen || memcmp(dname->name, name, nlen)) + continue; + if (!atomic_read(&d->d_count) || !d->d_fsdata) { + spin_lock(&d->d_lock); + __d_drop(d); + spin_unlock(&d->d_lock); + continue; + } + + dentry = dget(d); + break; + } + spin_unlock(&dcache_lock); + dput(parent); + + if (dentry) { +#if 0 + lktr_set_pid(current->pid, LktrArrayPid); + AuDbgDentry(dentry); + lktr_clear_pid(current->pid, LktrArrayPid); +#endif + di_write_lock_child(dentry); + } + return dentry; +} + +static struct inode *lookup_wlock_by_ino(struct super_block *sb, + aufs_bindex_t bindex, ino_t h_ino) +{ + struct inode *inode; + struct au_xino_entry xinoe; + int err; + + LKTRTrace("b%d, hi%lu\n", bindex, (unsigned long)h_ino); + AuDebugOn(!au_opt_test_xino(au_mntflags(sb))); + + inode = NULL; + err = au_xino_read(sb, bindex, h_ino, &xinoe); + if (!err && xinoe.ino) + inode = ilookup(sb, xinoe.ino); + if (!inode) + goto out; + if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { + AuWarn("wrong root branch\n"); + iput(inode); + inode = NULL; + goto out; + } + + ii_write_lock_child(inode); + + out: + return inode; +} + +static int hin_xino(struct inode *inode, struct inode *h_inode) +{ + int err; + aufs_bindex_t bindex, bend, bfound, bstart; + struct inode *h_i; + + LKTRTrace("i%lu, hi%lu\n", inode->i_ino, h_inode->i_ino); + + err = 0; + if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { + AuWarn("branch root dir was changed\n"); + goto out; + } + + bfound = -1; + bend = au_ibend(inode); + bstart = au_ibstart(inode); +#if 0 /* reserved for future use */ + if (bindex == bend) { + /* keep this ino in rename case */ + goto out; + } +#endif + for (bindex = bstart; bindex <= bend; bindex++) { + if (au_h_iptr(inode, bindex) == h_inode) { + bfound = bindex; + break; + } + } + if (bfound < 0) + goto out; + + for (bindex = bstart; bindex <= bend; bindex++) { + h_i = au_h_iptr(inode, bindex); + if (h_i) + err = au_xino_write0(inode->i_sb, bindex, h_i->i_ino, + 0); + /* ignore this error */ + /* bad action? */ + } + + /* children inode number will be broken */ + + out: + AuTraceErr(err); + return err; +} + +static int hin_gen_tree(struct dentry *dentry) +{ + int err, i, j, ndentry; + struct au_dcsub_pages dpages; + struct au_dpage *dpage; + struct dentry **dentries; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + + err = au_dpages_init(&dpages, GFP_NOFS); + if (unlikely(err)) + goto out; + err = au_dcsub_pages(&dpages, dentry, NULL, NULL); + if (unlikely(err)) + goto out_dpages; + + for (i = 0; i < dpages.ndpage; i++) { + dpage = dpages.dpages + i; + dentries = dpage->dentries; + ndentry = dpage->ndentry; + for (j = 0; j < ndentry; j++) { + struct dentry *d; + d = dentries[j]; + LKTRTrace("%.*s\n", AuDLNPair(d)); + if (IS_ROOT(d)) + continue; + + d_drop(d); + au_digen_dec(d); + if (d->d_inode) + /* todo: reset children xino? + cached children only? */ + au_iigen_dec(d->d_inode); + } + } + + out_dpages: + au_dpages_free(&dpages); + + /* discard children */ + dentry_unhash(dentry); + dput(dentry); + out: + AuTraceErr(err); + return err; +} + +/* + * return 0 if processed. + */ +static int hin_gen_by_inode(char *name, unsigned int nlen, struct inode *inode, + const unsigned int isdir) +{ + int err; + struct dentry *d; + struct qstr *dname; + + LKTRTrace("%.*s, i%lu\n", nlen, name, inode->i_ino); + + err = 1; + if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { + AuWarn("branch root dir was changed\n"); + err = 0; + goto out; + } + + if (!isdir) { + AuDebugOn(!name); + au_iigen_dec(inode); + spin_lock(&dcache_lock); + list_for_each_entry(d, &inode->i_dentry, d_alias) { + dname = &d->d_name; + if (dname->len != nlen + && memcmp(dname->name, name, nlen)) + continue; + err = 0; + spin_lock(&d->d_lock); + __d_drop(d); + au_digen_dec(d); + spin_unlock(&d->d_lock); + break; + } + spin_unlock(&dcache_lock); + } else { + au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIRS); + d = d_find_alias(inode); + if (!d) { + au_iigen_dec(inode); + goto out; + } + + dname = &d->d_name; + if (dname->len == nlen && !memcmp(dname->name, name, nlen)) + err = hin_gen_tree(d); + dput(d); + } + + out: + AuTraceErr(err); + return err; +} + +static int hin_gen_by_name(struct dentry *dentry, const unsigned int isdir) +{ + int err; + struct inode *inode; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + + inode = dentry->d_inode; + if (IS_ROOT(dentry) + /* || (inode && inode->i_ino == AUFS_ROOT_INO) */ + ) { + AuWarn("branch root dir was changed\n"); + return 0; + } + + err = 0; + if (!isdir) { + d_drop(dentry); + au_digen_dec(dentry); + if (inode) + au_iigen_dec(inode); + } else { + au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIRS); + if (inode) + err = hin_gen_tree(dentry); + } + + AuTraceErr(err); + return err; +} + +static void hin_attr(struct inode *inode, struct inode *h_inode) +{ + struct dentry *h_dentry; + + LKTRTrace("i%lu, hi%lu\n", inode->i_ino, h_inode->i_ino); + + if (au_h_iptr(inode, au_ibstart(inode)) != h_inode) + return; + + h_dentry = d_find_alias(h_inode); + if (h_dentry) { + au_update_fuse_h_inode(NULL, h_dentry); + /* ignore an error*/ + dput(h_dentry); + } + + au_cpup_attr_all(inode); +} + +/* ---------------------------------------------------------------------- */ + +/* hinotify job flags */ +#define AuHinJob_XINO0 1 +#define AuHinJob_GEN (1 << 1) +#define AuHinJob_DIRENT (1 << 2) +#define AuHinJob_ATTR (1 << 3) +#define AuHinJob_ISDIR (1 << 4) +#define AuHinJob_TRYXINO0 (1 << 5) +#define AuHinJob_MNTPNT (1 << 6) +#define au_ftest_hinjob(flags, name) ((flags) & AuHinJob_##name) +#define au_fset_hinjob(flags, name) { (flags) |= AuHinJob_##name; } +#define au_fclr_hinjob(flags, name) { (flags) &= ~AuHinJob_##name; } + +struct hin_job_args { + unsigned int flags; + struct inode *inode, *h_inode, *dir, *h_dir; + struct dentry *dentry; + char *h_name; + int h_nlen; +}; + +static int hin_job(struct hin_job_args *a) +{ + const unsigned int isdir = au_ftest_hinjob(a->flags, ISDIR); + + /* reset xino */ + if (au_ftest_hinjob(a->flags, XINO0) && a->inode) + hin_xino(a->inode, a->h_inode); + /* ignore this error */ + + if (au_ftest_hinjob(a->flags, TRYXINO0) + && a->inode + && a->h_inode) { + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); + if (!a->h_inode->i_nlink) + hin_xino(a->inode, a->h_inode); + /* ignore this error */ + mutex_unlock(&a->h_inode->i_mutex); + } + + /* make the generation obsolete */ + if (au_ftest_hinjob(a->flags, GEN)) { + int err = -1; + if (a->inode) + err = hin_gen_by_inode(a->h_name, a->h_nlen, a->inode, + isdir); + if (err && a->dentry) + hin_gen_by_name(a->dentry, isdir); + /* ignore this error */ + } + + /* make dir entries obsolete */ + if (au_ftest_hinjob(a->flags, DIRENT) && a->inode) { + struct au_vdir *vdir; + IiMustWriteLock(a->inode); + vdir = au_ivdir(a->inode); + if (vdir) + vdir->vd_jiffy = 0; + /* IMustLock(a->inode); */ + /* a->inode->i_version++; */ + } + + /* update the attr */ + if (au_ftest_hinjob(a->flags, ATTR) && a->inode && a->h_inode) + hin_attr(a->inode, a->h_inode); + + /* can do nothing but warn */ + if (au_ftest_hinjob(a->flags, MNTPNT) + && a->dentry + && d_mountpoint(a->dentry)) + AuWarn("mount-point %.*s is removed or renamed\n", + AuDLNPair(a->dentry)); + + return 0; +} + +/* ---------------------------------------------------------------------- */ + +enum { CHILD, PARENT }; +struct postproc_args { + struct inode *h_dir, *dir, *h_child_inode; + u32 mask; + unsigned int flags[2]; + unsigned int h_child_nlen; + char h_child_name[]; +}; + +static void postproc(void *_args) +{ + struct postproc_args *a = _args; + struct super_block *sb; + aufs_bindex_t bindex, bend, bfound; + unsigned char xino, try_iput; + int err; + struct inode *inode; + ino_t h_ino; + struct hin_job_args args; + struct dentry *dentry; + struct au_sbinfo *sbinfo; + + AuDebugOn(!_args); + AuDebugOn(!a->h_dir); + AuDebugOn(!a->dir); + AuDebugOn(!a->mask); + LKTRTrace("mask 0x%x %s, i%lu, hi%lu, hci%lu\n", + a->mask, in_name(a->mask), a->dir->i_ino, a->h_dir->i_ino, + a->h_child_inode ? a->h_child_inode->i_ino : 0); + + inode = NULL; + dentry = NULL; + /* + * do not lock a->dir->i_mutex here + * because of d_revalidate() may cause a deadlock. + */ + sb = a->dir->i_sb; + AuDebugOn(!sb); + sbinfo = au_sbi(sb); + AuDebugOn(!sbinfo); + /* big aufs lock */ + si_noflush_write_lock(sb); + + ii_read_lock_parent(a->dir); + bfound = -1; + bend = au_ibend(a->dir); + for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++) + if (au_h_iptr(a->dir, bindex) == a->h_dir) { + bfound = bindex; + break; + } + ii_read_unlock(a->dir); + if (unlikely(bfound < 0)) + goto out; + + xino = !!au_opt_test_xino(au_mntflags(sb)); + h_ino = 0; + if (a->h_child_inode) + h_ino = a->h_child_inode->i_ino; + + if (a->h_child_nlen + && (au_ftest_hinjob(a->flags[CHILD], GEN) + || au_ftest_hinjob(a->flags[CHILD], MNTPNT))) + dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen, + a->dir); + try_iput = 0; + if (dentry) + inode = dentry->d_inode; + if (xino && !inode && h_ino + && (au_ftest_hinjob(a->flags[CHILD], XINO0) + || au_ftest_hinjob(a->flags[CHILD], TRYXINO0) + || au_ftest_hinjob(a->flags[CHILD], GEN) + || au_ftest_hinjob(a->flags[CHILD], ATTR))) { + inode = lookup_wlock_by_ino(sb, bfound, h_ino); + try_iput = 1; + } + + args.flags = a->flags[CHILD]; + args.dentry = dentry; + args.inode = inode; + args.h_inode = a->h_child_inode; + args.dir = a->dir; + args.h_dir = a->h_dir; + args.h_name = a->h_child_name; + args.h_nlen = a->h_child_nlen; + err = hin_job(&args); + if (dentry) { + if (dentry->d_fsdata) + di_write_unlock(dentry); + dput(dentry); + } + if (inode && try_iput) { + ii_write_unlock(inode); + iput(inode); + } + + ii_write_lock_parent(a->dir); + args.flags = a->flags[PARENT]; + args.dentry = NULL; + args.inode = a->dir; + args.h_inode = a->h_dir; + args.dir = NULL; + args.h_dir = NULL; + args.h_name = NULL; + args.h_nlen = 0; + err = hin_job(&args); + ii_write_unlock(a->dir); + + out: + au_nwt_done(&sbinfo->si_nowait); + si_write_unlock(sb); + + iput(a->h_child_inode); + iput(a->h_dir); + iput(a->dir); + kfree(a); +} + +static void aufs_inotify(struct inotify_watch *watch, u32 wd, u32 mask, + u32 cookie, const char *h_child_name, + struct inode *h_child_inode) +{ + struct au_hinotify *hinotify; + struct postproc_args *args; + int len, wkq_err; + unsigned char isdir, isroot, wh; + char *p; + struct inode *dir; + unsigned int flags[2]; + + LKTRTrace("i%lu, wd %d, mask 0x%x %s, cookie 0x%x, hcname %s, hi%lu\n", + watch->inode->i_ino, wd, mask, in_name(mask), cookie, + h_child_name ? h_child_name : "", + h_child_inode ? h_child_inode->i_ino : 0); + + /* if IN_UNMOUNT happens, there must be another bug */ + if (mask & (IN_IGNORED | IN_UNMOUNT)) { + put_inotify_watch(watch); + return; + } + +#ifdef DbgInotify + if (!h_child_name || strcmp(h_child_name, AUFS_XINO_FNAME)) + AuDbg("i%lu, wd %d, mask 0x%x %s, cookie 0x%x, hcname %s," + " hi%lu\n", + watch->inode->i_ino, wd, mask, in_name(mask), cookie, + h_child_name ? h_child_name : "", + h_child_inode ? h_child_inode->i_ino : 0); +#endif + + hinotify = container_of(watch, struct au_hinotify, hin_watch); + AuDebugOn(!hinotify || !hinotify->hin_aufs_inode); + if (au_hin_test_ignore(mask, hinotify)) { +#ifdef DbgInotify + AuDbg("ignored\n"); +#endif + return; + } +#if 0 /* tmp debug */ + if (h_child_name && !strcmp(h_child_name, AUFS_XINO_FNAME)) + { + AuDbg("i%lu, wd %d, mask 0x%x %s, cookie 0x%x, hcname %s, hi%lu\n", + watch->inode->i_ino, wd, mask, in_name(mask), cookie, + h_child_name ? h_child_name : "", + h_child_inode ? h_child_inode->i_ino : 0); + //au_dbg_blocked(); + } +#endif + + dir = igrab(hinotify->hin_aufs_inode); + if (!dir) + return; + isroot = (dir->i_ino == AUFS_ROOT_INO); + len = 0; + wh = 0; + if (h_child_name) { + len = strlen(h_child_name); + if (!memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { + h_child_name += AUFS_WH_PFX_LEN; + len -= AUFS_WH_PFX_LEN; + wh = 1; + } + } + + isdir = 0; + if (h_child_inode) + isdir = !!S_ISDIR(h_child_inode->i_mode); + flags[PARENT] = AuHinJob_ISDIR; + flags[CHILD] = 0; + if (isdir) + flags[CHILD] = AuHinJob_ISDIR; + switch (mask & IN_ALL_EVENTS) { + case IN_MODIFY: + /*FALLTHROUGH*/ + case IN_ATTRIB: + if (h_child_inode) { + if (!wh) + au_fset_hinjob(flags[CHILD], ATTR); + } else + au_fset_hinjob(flags[PARENT], ATTR); + break; + + /* IN_MOVED_FROM is the first event in rename(2) */ + case IN_MOVED_FROM: + case IN_MOVED_TO: + AuDebugOn(!h_child_name || !h_child_inode); + au_fset_hinjob(flags[CHILD], GEN); + au_fset_hinjob(flags[CHILD], ATTR); + if (1 || isdir) + au_fset_hinjob(flags[CHILD], XINO0); + au_fset_hinjob(flags[CHILD], MNTPNT); + + au_fset_hinjob(flags[PARENT], ATTR); + au_fset_hinjob(flags[PARENT], DIRENT); + break; + + case IN_CREATE: + AuDebugOn(!h_child_name || !h_child_inode); + au_fset_hinjob(flags[PARENT], ATTR); + au_fset_hinjob(flags[PARENT], DIRENT); + au_fset_hinjob(flags[CHILD], GEN); + /* hard link */ + if (!isdir && h_child_inode->i_nlink > 1) + au_fset_hinjob(flags[CHILD], ATTR); + break; + + case IN_DELETE: + /* + * aufs never be able to get this child inode. + * revalidation should be in d_revalidate() + * by checking i_nlink, i_generation or d_unhashed(). + */ + AuDebugOn(!h_child_name); + au_fset_hinjob(flags[PARENT], ATTR); + au_fset_hinjob(flags[PARENT], DIRENT); + au_fset_hinjob(flags[CHILD], GEN); + au_fset_hinjob(flags[CHILD], TRYXINO0); + au_fset_hinjob(flags[CHILD], MNTPNT); + break; + + case IN_DELETE_SELF: +#if 0 + if (!isroot) + au_fset_hinjob(flags[PARENT], GEN); + /*FALLTHROUGH*/ +#endif + + case IN_MOVE_SELF: +#if 0 + /* + * when an inotify is set to an aufs inode, + * such inode can be isolated and this event can be fired + * solely. + */ + AuDebugOn(h_child_name || h_child_inode); + if (unlikely(isroot)) { + AuWarn("root branch was moved\n"); + iput(dir); + return; + } + au_fset_hinjob(flags[PARENT], XINO0); + au_fset_hinjob(flags[PARENT], GEN); + au_fset_hinjob(flags[PARENT], ATTR); + au_fset_hinjob(flags[PARENT], DIRENT); + /* au_fset_hinjob(flags[PARENT], MNTPNT); */ + break; +#endif + + case IN_ACCESS: + default: + AuDebugOn(1); + } + + if (wh) + h_child_inode = NULL; + + /* iput() and kfree() will be called in postproc() */ + /* + * inotify_mutex is already acquired and kmalloc/prune_icache may lock + * iprune_mutex. strange. + */ + lockdep_off(); + args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS); + lockdep_on(); + if (unlikely(!args)) { + AuErr1("no memory\n"); + iput(dir); + return; + } + args->flags[PARENT] = flags[PARENT]; + args->flags[CHILD] = flags[CHILD]; + args->mask = mask; + args->dir = dir; + args->h_dir = igrab(watch->inode); + if (h_child_inode) + h_child_inode = igrab(h_child_inode); /* can be NULL */ + args->h_child_inode = h_child_inode; + args->h_child_nlen = len; + if (len) { + p = (void *)args; + p += sizeof(*args); + memcpy(p, h_child_name, len + 1); + } + + lockdep_off(); + wkq_err = au_wkq_nowait(postproc, args, dir->i_sb, /*dlgt*/0); + lockdep_on(); + if (unlikely(wkq_err)) + AuErr("wkq %d\n", wkq_err); +} + +static void aufs_inotify_destroy(struct inotify_watch *watch) +{ + return; +} + +static struct inotify_operations aufs_inotify_ops = { + .handle_event = aufs_inotify, + .destroy_watch = aufs_inotify_destroy +}; + +/* ---------------------------------------------------------------------- */ + +static void au_hin_destroy_cache(void) +{ + kmem_cache_destroy(au_cachep[AuCache_HINOTIFY]); + au_cachep[AuCache_HINOTIFY] = NULL; +} + +int __init au_inotify_init(void) +{ + int err; + + err = -ENOMEM; + au_cachep[AuCache_HINOTIFY] = AuCache(au_hinotify); + if (au_cachep[AuCache_HINOTIFY]) { + err = 0; + in_handle = inotify_init(&aufs_inotify_ops); + if (IS_ERR(in_handle)) { + err = PTR_ERR(in_handle); + au_hin_destroy_cache(); + } + } + AuTraceErr(err); + return err; +} + +void au_inotify_fin(void) +{ + inotify_destroy(in_handle); + if (au_cachep[AuCache_HINOTIFY]) + au_hin_destroy_cache(); +} --- linux-2.6.28.orig/ubuntu/aufs/export.c +++ linux-2.6.28/ubuntu/aufs/export.c @@ -0,0 +1,797 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * export via nfs + * + * $Id: export.c,v 1.15 2008/09/22 03:52:19 sfjro Exp $ + */ + +#include +#include +#include +#include "aufs.h" + +union conv { +#ifdef CONFIG_AUFS_INO_T_64 + __u32 a[2]; +#else + __u32 a[1]; +#endif + ino_t ino; +}; + +static ino_t decode_ino(__u32 *a) +{ + union conv u; + + BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a)); + u.a[0] = a[0]; +#ifdef CONFIG_AUFS_INO_T_64 + u.a[1] = a[1]; +#endif + return u.ino; +} + +static void encode_ino(__u32 *a, ino_t ino) +{ + union conv u; + + u.ino = ino; + a[0] = u.a[0]; +#ifdef CONFIG_AUFS_INO_T_64 + a[1] = u.a[1]; +#endif +} + +/* NFS file handle */ +enum { + Fh_br_id, + Fh_sigen, +#ifdef CONFIG_AUFS_INO_T_64 + /* support 64bit inode number */ + Fh_ino1, + Fh_ino2, + Fh_dir_ino1, + Fh_dir_ino2, +#else + Fh_ino1, + Fh_dir_ino1, +#endif + Fh_igen, + Fh_h_type, + Fh_tail, + + Fh_ino = Fh_ino1, + Fh_dir_ino = Fh_dir_ino1 +}; + +static int au_test_anon(struct dentry *dentry) +{ + return !!(dentry->d_flags & DCACHE_DISCONNECTED); +} + +/* ---------------------------------------------------------------------- */ +/* inode generation external table */ + +int au_xigen_inc(struct inode *inode) +{ + int err; + loff_t pos; + ssize_t sz; + __u32 igen; + struct super_block *sb; + struct au_sbinfo *sbinfo; + + LKTRTrace("i%lu\n", (unsigned long)inode->i_ino); + + err = 0; + sb = inode->i_sb; + if (unlikely(!au_opt_test_xino(au_mntflags(sb)))) + goto out; + + pos = inode->i_ino; + pos *= sizeof(igen); + igen = inode->i_generation + 1; + sbinfo = au_sbi(sb); + sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen, + sizeof(igen), &pos); + if (sz == sizeof(igen)) + goto out; /* success */ + + err = sz; + if (unlikely(sz >= 0)) { + err = -EIO; + AuIOErr("xigen error (%ld)\n", (long)sz); + } + + out: + AuTraceErr(err); + return err; +} + +int au_xigen_new(struct inode *inode) +{ + int err; + loff_t pos; + ssize_t sz; + struct super_block *sb; + struct au_sbinfo *sbinfo; + struct file *file; + + LKTRTrace("i%lu\n", (unsigned long)inode->i_ino); + + err = 0; + sb = inode->i_sb; + if (unlikely(!au_opt_test_xino(au_mntflags(sb)))) + goto out; + + err = -EFBIG; + pos = inode->i_ino; + if (unlikely(Au_LOFF_MAX / sizeof(inode->i_generation) - 1 < pos)) { + AuIOErr1("too large i%lld\n", pos); + goto out; + } + pos *= sizeof(inode->i_generation); + + err = 0; + sbinfo = au_sbi(sb); + file = sbinfo->si_xigen; + /* todo: dirty, at mount time */ + if (unlikely(!file)) { + if (inode->i_ino == AUFS_ROOT_INO) + goto out; + else + BUG(); + } + + if (i_size_read(file->f_dentry->d_inode) + < pos + sizeof(inode->i_generation)) { + spin_lock(&sbinfo->si_xigen_lock); + inode->i_generation = sbinfo->si_xigen_next++; + spin_unlock(&sbinfo->si_xigen_lock); + sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation, + sizeof(inode->i_generation), &pos); + } else + sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation, + sizeof(inode->i_generation), &pos); + if (sz == sizeof(inode->i_generation)) + goto out; /* success */ + + err = sz; + if (unlikely(sz >= 0)) { + err = -EIO; + AuIOErr("xigen error (%ld)\n", (long)sz); + } + + out: + AuTraceErr(err); + return err; +} + +int au_xigen_set(struct super_block *sb, struct file *base) +{ + int err; + struct au_sbinfo *sbinfo; + struct file *file; + + LKTRTrace("%.*s\n", AuDLNPair(base->f_dentry)); + SiMustWriteLock(sb); + + sbinfo = au_sbi(sb); + file = au_xino_create2(sb, base, sbinfo->si_xigen); + err = PTR_ERR(file); + if (IS_ERR(file)) + goto out; + err = 0; + if (sbinfo->si_xigen) + fput(sbinfo->si_xigen); + sbinfo->si_xigen = file; + + out: + AuTraceErr(err); + return err; +} + +void au_xigen_clr(struct super_block *sb) +{ + struct au_sbinfo *sbinfo; + + sbinfo = au_sbi(sb); + if (sbinfo->si_xigen) { + fput(sbinfo->si_xigen); + sbinfo->si_xigen = NULL; + } +} + +/* ---------------------------------------------------------------------- */ + +static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino, + ino_t dir_ino) +{ + struct dentry *dentry, *d; + struct inode *inode; + + LKTRTrace("i%lu, diri%lu\n", + (unsigned long)ino, (unsigned long)dir_ino); + + dentry = NULL; + inode = ilookup(sb, ino); + if (unlikely(!inode)) + goto out; + + dentry = ERR_PTR(-ESTALE); + if (unlikely(is_bad_inode(inode) || IS_DEADDIR(inode))) + goto out_iput; + AuDbgInode(inode); + + dentry = NULL; + if (!dir_ino || S_ISDIR(inode->i_mode)) + dentry = d_find_alias(inode); + else { + spin_lock(&dcache_lock); + list_for_each_entry(d, &inode->i_dentry, d_alias) + if (!au_test_anon(d) + && d->d_parent->d_inode->i_ino == dir_ino) { + dentry = dget_locked(d); + break; + } + spin_unlock(&dcache_lock); + } + AuDbgDentry(dentry); + + out_iput: + iput(inode); + out: + AuTraceErrPtr(dentry); + return dentry; +} + +/* ---------------------------------------------------------------------- */ + +/* todo: dirty? */ +/* + * when you mntput() for the return value of this function, + * you have to store it to your local var. + * ie. never mntput si_mntcache directly. + */ +static struct vfsmount *au_do_mnt_get(struct super_block *sb) +{ + struct mnt_namespace *ns; + struct vfsmount *pos, *mnt; + + AuTraceEnter(); + + /* vfsmount_lock is not exported */ + /* no get/put ?? */ + AuDebugOn(!current->nsproxy); + ns = current->nsproxy->mnt_ns; + AuDebugOn(!ns); + mnt = NULL; + /* the order (reverse) will not be a problem */ + list_for_each_entry(pos, &ns->list, mnt_list) + if (pos->mnt_sb == sb) { + mnt = pos; + break; + } + AuDebugOn(!mnt); + + return mntget(mnt); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) +static struct vfsmount *au_mnt_get(struct super_block *sb) +{ + struct au_sbinfo *sbinfo; + struct vfsmount *mnt; + + sbinfo = au_sbi(sb); + spin_lock(&sbinfo->si_mntcache_lock); + if (sbinfo->si_mntcache) + mnt = mntget(sbinfo->si_mntcache); + else { + sbinfo->si_mntcache = au_do_mnt_get(sb); + mnt = sbinfo->si_mntcache; + } + spin_unlock(&sbinfo->si_mntcache_lock); + return mnt; +} +#else +static struct vfsmount *au_mnt_get(struct super_block *sb) +{ + return au_do_mnt_get(sb); +} +#endif + +struct find_name_by_ino { + int called, found; + ino_t ino; + char *name; + int namelen; +}; + +static int +find_name_by_ino(void *arg, const char *name, int namelen, loff_t offset, + u64 ino, unsigned int d_type) +{ + struct find_name_by_ino *a = arg; + + a->called++; + if (a->ino != ino) + return 0; + + memcpy(a->name, name, namelen); + a->namelen = namelen; + a->found = 1; + return 1; +} + +static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino) +{ + struct dentry *dentry, *parent; + struct file *file; + struct inode *dir, *inode; + struct find_name_by_ino arg; + int err; + + parent = path->dentry; + LKTRTrace("%.*s, i%lu\n", AuDLNPair(parent), (unsigned long )ino); + + path_get(path); + file = dentry_open(parent, path->mnt, au_dir_roflags); + dentry = (void *)file; + if (IS_ERR(file)) + goto out; + + dentry = ERR_PTR(-ENOMEM); + arg.name = __getname(); + if (unlikely(!arg.name)) + goto out_file; + arg.ino = ino; + arg.found = 0; + do { + arg.called = 0; + /* smp_mb(); */ + err = vfsub_readdir(file, find_name_by_ino, &arg, /*dlgt*/0); + } while (!err && !arg.found && arg.called); + dentry = ERR_PTR(err); + if (unlikely(err)) + goto out_name; + dentry = ERR_PTR(-ENOENT); + if (!arg.found) + goto out_name; + + /* do not call au_lkup_one(), nor dlgt */ + dir = parent->d_inode; + mutex_lock(&dir->i_mutex); + dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen); + mutex_unlock(&dir->i_mutex); + AuTraceErrPtr(dentry); + if (IS_ERR(dentry)) + goto out_name; + AuDebugOn(au_test_anon(dentry)); + inode = dentry->d_inode; + if (unlikely(!inode)) { + dput(dentry); + dentry = ERR_PTR(-ENOENT); + } + + out_name: + __putname(arg.name); + out_file: + fput(file); + out: + AuTraceErrPtr(dentry); + return dentry; +} + +static /* noinline_for_stack */ +struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino, + ino_t dir_ino) +{ + struct dentry *dentry, *parent; + struct path path; + + LKTRTrace("i%lu, diri%lu\n", + (unsigned long)ino, (unsigned long)dir_ino); + + parent = sb->s_root; + if (dir_ino != AUFS_ROOT_INO) { + parent = decode_by_ino(sb, dir_ino, 0); + AuDbgDentry(parent); + dentry = parent; + if (unlikely(!parent)) + goto out; + if (IS_ERR(parent)) + goto out; + AuDebugOn(au_test_anon(parent)); + } else + dget(parent); + + path.dentry = parent; + path.mnt = au_mnt_get(sb); + dentry = au_lkup_by_ino(&path, ino); + path_put(&path); + + out: + AuTraceErrPtr(dentry); + return dentry; +} + +/* ---------------------------------------------------------------------- */ + +static int h_acceptable(void *expv, struct dentry *dentry) +{ + return 1; +} + +static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath, + char *buf, int len, struct super_block *sb) +{ + char *p; + int n; + struct path path; + + AuTraceEnter(); + + p = d_path(h_rootpath, buf, len); + if (IS_ERR(p)) + goto out; + n = strlen(p); + + path.mnt = h_rootpath->mnt; + path.dentry = h_parent; + p = d_path(&path, buf, len); + if (IS_ERR(p)) + goto out; + LKTRTrace("%s\n", p); + if (n != 1) + p += n; + LKTRTrace("%p, %s, %ld\n", + p, p, (long)(p - buf)); + + path.mnt = au_mnt_get(sb); + path.dentry = sb->s_root; + p = d_path(&path, buf, len - strlen(p)); + mntput(path.mnt); + if (IS_ERR(p)) + goto out; + if (n != 1) + p[strlen(p)] = '/'; + LKTRTrace("%s\n", p); + + out: + AuTraceErrPtr(p); + return p; +} + +static noinline_for_stack +struct dentry *decode_by_path(struct super_block *sb, aufs_bindex_t bindex, + ino_t ino, __u32 *fh, int fh_len) +{ + struct dentry *dentry, *h_parent, *root; + struct super_block *h_sb; + char *pathname, *p; + struct vfsmount *h_mnt; + struct au_branch *br; + int err; + struct nameidata nd; + + LKTRTrace("b%d\n", bindex); + SiMustAnyLock(sb); + + br = au_sbr(sb, bindex); + /* au_br_get(br); */ + h_mnt = br->br_mnt; + h_sb = h_mnt->mnt_sb; + LKTRTrace("%s, h_decode_fh\n", au_sbtype(h_sb)); + /* in linux-2.6.24, it takes struct fid * as file handle */ + /* todo: call lower fh_to_dentry()? fh_to_parent()? */ + h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail), + fh_len - Fh_tail, fh[Fh_h_type], + h_acceptable, /*context*/NULL); + dentry = h_parent; + if (unlikely(!h_parent || IS_ERR(h_parent))) { + AuWarn1("%s decode_fh failed, %ld\n", + au_sbtype(h_sb), PTR_ERR(h_parent)); + goto out; + } + dentry = NULL; + if (unlikely(au_test_anon(h_parent))) { + AuWarn1("%s decode_fh returned a disconnected dentry\n", + au_sbtype(h_sb)); + goto out_h_parent; + } + + dentry = ERR_PTR(-ENOMEM); + pathname = (void *)__get_free_page(GFP_NOFS); + if (unlikely(!pathname)) + goto out_h_parent; + + root = sb->s_root; + nd.path.mnt = h_mnt; + di_read_lock_parent(root, !AuLock_IR); + nd.path.dentry = au_h_dptr(root, bindex); + di_read_unlock(root, !AuLock_IR); + p = au_build_path(h_parent, &nd.path, pathname, PAGE_SIZE, sb); + dentry = (void *)p; + if (IS_ERR(p)) + goto out_pathname; + + LKTRTrace("%s\n", p); + err = vfsub_path_lookup(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &nd); + dentry = ERR_PTR(err); + if (unlikely(err)) + goto out_pathname; + + dentry = ERR_PTR(-ENOENT); + AuDebugOn(au_test_anon(nd.path.dentry)); + if (unlikely(!nd.path.dentry->d_inode)) + goto out_nd; + + if (ino != nd.path.dentry->d_inode->i_ino) + dentry = au_lkup_by_ino(&nd.path, ino); + else + dentry = dget(nd.path.dentry); + + out_nd: + path_put(&nd.path); + out_pathname: + free_page((unsigned long)pathname); + out_h_parent: + dput(h_parent); + out: + /* au_br_put(br); */ + AuTraceErrPtr(dentry); + return dentry; +} + +/* ---------------------------------------------------------------------- */ + +static struct dentry * +aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len, + int fh_type) +{ + struct dentry *dentry; + struct inode *inode; + __u32 *fh = fid->raw; + ino_t ino, dir_ino; + aufs_bindex_t bindex, br_id; + au_gen_t sigen; + + LKTRTrace("%d, fh{br_id %u, sigen %u, i%u, diri%u, g%u}\n", + fh_type, fh[Fh_br_id], fh[Fh_sigen], fh[Fh_ino], + fh[Fh_dir_ino], fh[Fh_igen]); + AuDebugOn(fh_len < Fh_tail); + + si_read_lock(sb, AuLock_FLUSH); + lockdep_off(); + + /* branch id may be wrapped around */ + dentry = ERR_PTR(-ESTALE); + br_id = fh[Fh_br_id]; + sigen = fh[Fh_sigen]; + bindex = au_br_index(sb, br_id); + LKTRTrace("b%d\n", bindex); + if (unlikely(bindex < 0 + || (0 && sigen != au_sigen(sb)) + || (1 && sigen + AUFS_BRANCH_MAX <= au_sigen(sb)) + )) + goto out; + + /* is this inode still cached? */ + ino = decode_ino(fh + Fh_ino); + AuDebugOn(ino == AUFS_ROOT_INO); + dir_ino = decode_ino(fh + Fh_dir_ino); + dentry = decode_by_ino(sb, ino, dir_ino); + if (IS_ERR(dentry)) + goto out; + if (dentry) + goto accept; + + /* is the parent dir cached? */ + dentry = decode_by_dir_ino(sb, ino, dir_ino); + if (IS_ERR(dentry)) + goto out; + if (dentry) + goto accept; + + /* lookup path */ + dentry = decode_by_path(sb, bindex, ino, fh, fh_len); + if (IS_ERR(dentry)) + goto out; + if (unlikely(!dentry)) + goto out; + + accept: + LKTRLabel(accept); + inode = dentry->d_inode; +#if 0 + /* support branch manupilation and udba on nfs server */ + sigen = au_sigen(sb); + if (unlikely(au_digen(dentry) != sigen + || au_iigen(inode) != sigen)) { + int err; + + //lktr_set_pid(current->pid, LktrArrayPid); + //au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIRS); + di_write_lock_child(dentry); + err = au_reval_dpath(dentry, sigen); + di_write_unlock(dentry); + //lktr_clear_pid(current->pid, LktrArrayPid); + if (unlikely(err < 0)) + goto out_dput; + } +#endif + + if (unlikely(inode->i_generation != fh[Fh_igen])) { + LKTRLabel(stale); + dput(dentry); + dentry = ERR_PTR(-ESTALE); + } + + out: + LKTRLabel(out); + lockdep_on(); + si_read_unlock(sb); + AuTraceErrPtr(dentry); + return dentry; +} + +#if 0 /* reserved for future use */ +/* support subtreecheck option */ +static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid, + int fh_len, int fh_type) +{ + struct dentry *parent; + __u32 *fh = fid->raw; + ino_t dir_ino; + + dir_ino = decode_ino(fh + Fh_dir_ino); + parent = decode_by_ino(sb, dir_ino, 0); + if (IS_ERR(parent)) + goto out; + if (!parent) + parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]), + dir_ino, fh, fh_len); + + out: + AuTraceErrPtr(parent); + return parent; +} +#endif + +/* ---------------------------------------------------------------------- */ + +static int aufs_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len, + int connectable) +{ + int err; + aufs_bindex_t bindex, bend; + struct super_block *sb, *h_sb; + struct inode *inode; + struct dentry *parent, *h_parent; + struct au_branch *br; + + LKTRTrace("%.*s, max %d, conn %d\n", + AuDLNPair(dentry), *max_len, connectable); + AuDebugOn(au_test_anon(dentry)); + + parent = NULL; + err = -ENOSPC; + if (unlikely(*max_len <= Fh_tail)) { + AuWarn1("NFSv2 client (max_len %d)?\n", *max_len); + goto out; + } + + err = FILEID_ROOT; + inode = dentry->d_inode; + AuDebugOn(!inode); + if (inode->i_ino == AUFS_ROOT_INO) + goto out; + + err = -EIO; + h_parent = NULL; + sb = dentry->d_sb; + parent = dget_parent(dentry); + aufs_read_lock(parent, AuLock_FLUSH | AuLock_IR); +#ifdef CONFIG_AUFS_DEBUG + { + unsigned int mnt_flags = au_mntflags(sb); + + if (unlikely(!au_opt_test_xino(mnt_flags))) + AuWarn1("NFS-exporting requires xino\n"); + if (unlikely(0 && !au_opt_test(mnt_flags, UDBA_INOTIFY))) + AuWarn1("udba=inotify is recommended " + "for NFS-exporting\n"); + } +#endif + + bend = au_dbtaildir(parent); + for (bindex = au_dbstart(parent); bindex <= bend; bindex++) { + h_parent = au_h_dptr(parent, bindex); + if (h_parent) { + dget(h_parent); + break; + } + } + if (unlikely(!h_parent)) + goto out_unlock; + LKTRTrace("b%d\n", bindex); + + err = -EPERM; + br = au_sbr(sb, bindex); + h_sb = br->br_mnt->mnt_sb; + if (unlikely(!h_sb->s_export_op)) { + AuErr1("%s branch is not exportable\n", au_sbtype(h_sb)); + goto out_dput; + } + + fh[Fh_br_id] = br->br_id; + fh[Fh_sigen] = au_sigen(sb); + encode_ino(fh + Fh_ino, inode->i_ino); + encode_ino(fh + Fh_dir_ino, parent->d_inode->i_ino); + fh[Fh_igen] = inode->i_generation; + + *max_len -= Fh_tail; + /* in linux-2.6.24, it takes struct fid * as file handle */ + fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail), + max_len, connectable); + err = fh[Fh_h_type]; + *max_len += Fh_tail; + /* todo: macros? */ + if (err != 255) + err = 99; + else + AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb)); + + out_dput: + dput(h_parent); + out_unlock: + aufs_read_unlock(parent, AuLock_IR); + dput(parent); + out: + AuTraceErr(err); + if (unlikely(err < 0)) + err = 255; + return err; +} + +/* ---------------------------------------------------------------------- */ + +static struct export_operations aufs_export_op = { + .fh_to_dentry = aufs_fh_to_dentry, + //.fh_to_parent = aufs_fh_to_parent, + .encode_fh = aufs_encode_fh +}; + +void au_export_init(struct super_block *sb) +{ + struct au_sbinfo *sbinfo; + + AuTraceEnter(); + SiMustWriteLock(sb); + + sb->s_export_op = &aufs_export_op; + sbinfo = au_sbi(sb); + sbinfo->si_xigen = NULL; + spin_lock_init(&sbinfo->si_xigen_lock); + /* todo: meaningless? */ + get_random_bytes(&sbinfo->si_xigen_next, sizeof(sbinfo->si_xigen_next)); + memset(&sbinfo->si_xinodir, 0, sizeof(struct path)); +} --- linux-2.6.28.orig/ubuntu/aufs/whout.h +++ linux-2.6.28/ubuntu/aufs/whout.h @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * whiteout for logical deletion and opaque directory + * + * $Id: whout.h,v 1.3 2008/06/30 03:57:35 sfjro Exp $ + */ + +#ifndef __AUFS_WHOUT_H__ +#define __AUFS_WHOUT_H__ + +#ifdef __KERNEL__ + +#include +#include +#include "dir.h" +#include "opts.h" +#include "super.h" + +int au_wh_name_alloc(const char *name, int len, struct qstr *wh); +void au_wh_name_free(struct qstr *wh); + +struct au_ndx; +int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio, + struct au_ndx *ndx); +int au_diropq_test(struct dentry *h_dentry, struct au_ndx *ndx); + +struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct qstr *prefix, + struct au_ndx *ndx); +int au_whtmp_ren(struct inode *dir, aufs_bindex_t bindex, + struct dentry *h_dentry); +int au_wh_unlink_dentry(struct au_hinode *dir, struct dentry *wh_dentry, + struct dentry *dentry, int dlgt); + +struct au_branch; +int au_wh_init(struct dentry *h_parent, struct au_branch *br, + struct vfsmount *nfsmnt, struct super_block *sb, + aufs_bindex_t bindex); + +/* diropq flags */ +#define AuDiropq_CREATE 1 +#define AuDiropq_DLGT (1 << 1) +#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name) +#define au_fset_diropq(flags, name) { (flags) |= AuDiropq_##name; } +#define au_fclr_diropq(flags, name) { (flags) &= ~AuDiropq_##name; } +#ifndef CONFIG_AUFS_DLGT +#undef AuDiropq_DLGT +#define AuDiropq_DLGT 0 +#endif + +struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex, + unsigned int flags); + +struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name, + struct au_ndx *ndx); +struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex, + struct dentry *h_parent, struct au_ndx *ndx); + +/* real rmdir the whiteout-ed dir */ +struct au_whtmp_rmdir_args { + struct inode *dir; + aufs_bindex_t bindex; + struct dentry *wh_dentry; + struct au_nhash whlist; +}; + +struct au_nhash; +int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex, + struct dentry *wh_dentry, struct au_nhash *whlist); +void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex, + struct dentry *wh_dentry, struct au_nhash *whlist, + struct au_whtmp_rmdir_args *args); + +/* ---------------------------------------------------------------------- */ + +static inline +struct dentry *au_diropq_create(struct dentry *dentry, aufs_bindex_t bindex, + int dlgt) +{ + unsigned int flags = AuDiropq_CREATE; + if (unlikely(dlgt)) + au_fset_diropq(flags, DLGT); + return au_diropq_sio(dentry, bindex, flags); +} + +static inline +int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex, int dlgt) +{ + unsigned int flags = !AuDiropq_CREATE; + if (unlikely(dlgt)) + au_fset_diropq(flags, DLGT); + return PTR_ERR(au_diropq_sio(dentry, bindex, flags)); +} + +/* ---------------------------------------------------------------------- */ + +#ifdef CONFIG_AUFS_ROBR +/* robr.c */ +int au_test_robr_wh(struct qstr *name, struct dentry *h_parent, + struct qstr *wh_name, int try_sio, struct au_ndx *ndx); +int au_test_robr_shwh(struct super_block *sb, const struct qstr *name); +#else +static inline +int au_test_robr_wh(struct qstr *name, struct dentry *h_parent, + struct qstr *wh_name, int try_sio, struct au_ndx *ndx) +{ + return au_wh_test(h_parent, wh_name, try_sio, ndx); +} + +static inline +int au_test_robr_shwh(struct super_block *sb, const struct qstr *name) +{ + if (unlikely(!au_opt_test(au_mntflags(sb), SHWH) + && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))) + return -EPERM; + return 0; +} +#endif /* CONFIG_AUFS_ROBR */ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_WHOUT_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/sysfs.c +++ linux-2.6.28/ubuntu/aufs/sysfs.c @@ -0,0 +1,520 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * sysfs interface + * + * $Id: sysfs.c,v 1.13 2008/09/15 03:14:55 sfjro Exp $ + */ + +#include +#include +#include +#include +#include "aufs.h" + + +#ifdef CONFIG_AUFS_LOCAL +static ssize_t config_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ +#define conf_bool(name) "CONFIG_AUFS_" #name "=y\n" + static const char opt[] = +#ifdef CONFIG_AUFS + "CONFIG_AUFS=y\n" +#else + "CONFIG_AUFS=m\n" +#endif +#ifdef CONFIG_AUFS_BRANCH_MAX_127 + conf_bool(BRANCH_MAX_127) +#elif defined(CONFIG_AUFS_BRANCH_MAX_511) + conf_bool(BRANCH_MAX_511) +#elif defined(CONFIG_AUFS_BRANCH_MAX_1023) + conf_bool(BRANCH_MAX_1023) +#elif defined(CONFIG_AUFS_BRANCH_MAX_32767) + conf_bool(BRANCH_MAX_32767) +#endif +#ifdef CONFIG_AUFS_HINOTIFY + conf_bool(HINOTIFY) +#endif +#ifdef CONFIG_AUFS_EXPORT + conf_bool(EXPORT) +#endif +#ifdef CONFIG_AUFS_ROBR + conf_bool(ROBR) +#endif +#ifdef CONFIG_AUFS_SHWH + conf_bool(SHWH) +#endif +#ifdef CONFIG_AUFS_DLGT + conf_bool(DLGT) +#endif +#ifdef CONFIG_AUFS_HIN_OR_DLGT + conf_bool(HIN_OR_DLGT) +#endif +#ifdef CONFIG_AUFS_RR_SQUASHFS + conf_bool(RR_SQUASHFS) +#endif +#ifdef CONFIG_AUFS_SEC_PERM_PATCH + conf_bool(SEC_PERM_PATCH) +#endif +#ifdef CONFIG_AUFS_SPLICE_PATCH + conf_bool(SPLICE_PATCH) +#endif +#ifdef CONFIG_AUFS_PUT_FILP_PATCH + conf_bool(PUT_FILP_PATCH) +#endif +#ifdef CONFIG_AUFS_LHASH_PATCH + conf_bool(LHASH_PATCH) +#endif +#ifdef CONFIG_AUFS_BR_NFS + conf_bool(BR_NFS) +#endif +#ifdef CONFIG_AUFS_BR_XFS + conf_bool(BR_XFS) +#endif +#ifdef CONFIG_AUFS_FSYNC_SUPER_PATCH + conf_bool(FSYNC_SUPER_PATCH) +#endif +#ifdef CONFIG_AUFS_DENY_WRITE_ACCESS_PATCH + conf_bool(DENY_WRITE_ACCESS_PATCH) +#endif +#ifdef CONFIG_AUFS_KSIZE_PATCH + conf_bool(KSIZE_PATCH) +#endif +#ifdef CONFIG_AUFS_WORKAROUND_FUSE + conf_bool(WORKAROUND_FUSE) +#endif +#ifdef CONFIG_AUFS_HIN_OR_FUSE + conf_bool(HIN_OR_FUSE) +#endif +#ifdef CONFIG_AUFS_STAT + conf_bool(STAT) +#endif +#ifdef CONFIG_AUFS_DEBUG + conf_bool(DEBUG) +#endif +#ifdef CONFIG_AUFS_MAGIC_SYSRQ + conf_bool(MAGIC_SYSRQ) +#endif +#ifdef CONFIG_AUFS_COMPAT + conf_bool(COMPAT) +#endif +#ifdef CONFIG_AUFS_UNIONFS22_PATCH + conf_bool(UNIONFS22_PATCH) +#endif +#ifdef CONFIG_AUFS_UNIONFS23_PATCH + conf_bool(UNIONFS23_PATCH) +#endif + ; +#undef conf_bool + + char *p = buf; + const char *end = buf + PAGE_SIZE; + + p += snprintf(p, end - p, "%s", opt); +#ifdef DbgUdbaRace + if (p < end) + p += snprintf(p, end - p, "DbgUdbaRace=%d\n", DbgUdbaRace); +#endif + if (p < end) + return p - buf; + else + return -EFBIG; +} + +static struct kobj_attribute au_config_attr = __ATTR_RO(config); +#endif + +#ifdef CONFIG_AUFS_STAT +static ssize_t stat_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + char *p = buf; + const char *end = buf + PAGE_SIZE; + int i; + + p += snprintf(p, end - p, "wkq max_busy:"); + for (i = 0; p < end && i < aufs_nwkq; i++) + p += snprintf(p, end - p, " %u", au_wkq[i].max_busy); + if (p < end) + p += snprintf(p, end - p, ", %u(generic)\n", + au_wkq[aufs_nwkq].max_busy); + + if (p < end) + return p - buf; + else + return -EFBIG; +} + +static struct kobj_attribute au_stat_attr = __ATTR_RO(stat); +#endif + +#ifdef CONFIG_AUFS_DEBUG +static ssize_t debug_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + return sprintf(buf, "%d\n", au_debug_test()); +} + +static ssize_t debug_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t sz) +{ + LKTRTrace("%.*s\n", (unsigned int)sz, buf); + + if (unlikely(!sz || (*buf != '0' && *buf != '1'))) + return -EOPNOTSUPP; + + if (*buf == '0') + au_debug_off(); + else if (*buf == '1') + au_debug_on(); + return sz; +} + +static struct kobj_attribute au_debug_attr = __ATTR(debug, S_IRUGO | S_IWUSR, + debug_show, debug_store); +#endif + +static struct attribute *au_attr[] = { +#ifdef CONFIG_AUFS_LOCAL + &au_config_attr.attr, +#endif +#ifdef CONFIG_AUFS_STAT + &au_stat_attr.attr, +#endif +#ifdef CONFIG_AUFS_DEBUG + &au_debug_attr.attr, +#endif + NULL, /* need to NULL terminate the list of attributes */ +}; + +static struct attribute_group au_attr_group_body = { + .attrs = au_attr +}; + +struct attribute_group *au_attr_group = &au_attr_group_body; + +/* ---------------------------------------------------------------------- */ + +/* + * they are copied from linux/lib/kobject.c, + * and will be exported in the future. + */ +static ssize_t au_attr_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + struct kobj_attribute *kattr; + ssize_t ret = -EIO; + + kattr = container_of(attr, struct kobj_attribute, attr); + if (kattr->show) + ret = kattr->show(kobj, kattr, buf); + return ret; +} + +#ifdef CONFIG_AUFS_DEBUG +static ssize_t au_attr_store(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t count) +{ + struct kobj_attribute *kattr; + ssize_t ret = -EIO; + + kattr = container_of(attr, struct kobj_attribute, attr); + if (kattr->store) + ret = kattr->store(kobj, kattr, buf, count); + return ret; +} +#endif + +static struct sysfs_ops sysaufs_ops = { + .show = au_attr_show, +#ifdef CONFIG_AUFS_DEBUG + .store = au_attr_store +#endif +}; + +static struct kobj_type au_ktype_body = { + .sysfs_ops = &sysaufs_ops +}; +struct kobj_type *au_ktype = &au_ktype_body; + +/* ---------------------------------------------------------------------- */ + +static int sysaufs_sbi_xi(struct seq_file *seq, struct file *xf, int dlgt, + int print_path) +{ + int err; + struct kstat st; + struct path path; + + err = vfsub_getattr(xf->f_vfsmnt, xf->f_dentry, &st, dlgt); + if (!err) { + seq_printf(seq, "%llux%lu %lld", + st.blocks, st.blksize, (long long)st.size); + if (unlikely(print_path)) { + path.dentry = xf->f_dentry; + path.mnt = xf->f_vfsmnt; + seq_putc(seq, ' '); + seq_path(seq, &path, au_esc_chars); + } + seq_putc(seq, '\n'); + } else + seq_printf(seq, "err %d\n", err); + + AuTraceErr(err); + return err; +} + +int sysaufs_sbi_xino(struct seq_file *seq, struct super_block *sb) +{ + int err; + unsigned int mnt_flags; + aufs_bindex_t bend, bindex; + unsigned char dlgt, xinodir; + struct kstat st; + struct path path; + struct au_sbinfo *sbinfo; + struct file *xf; + + AuTraceEnter(); + + sbinfo = au_sbi(sb); + mnt_flags = au_mntflags(sb); + xinodir = !!au_opt_test(mnt_flags, XINODIR); + if (unlikely(!au_opt_test_xino(mnt_flags))) { +#ifdef CONFIG_AUFS_DEBUG + AuDebugOn(sbinfo->si_xib); + bend = au_sbend(sb); + for (bindex = 0; bindex <= bend; bindex++) + AuDebugOn(au_sbr(sb, bindex)->br_xino.xi_file); +#endif + err = 0; + goto out; /* success */ + } + + dlgt = !!au_test_dlgt(mnt_flags); + err = sysaufs_sbi_xi(seq, sbinfo->si_xib, dlgt, xinodir); + + bend = au_sbend(sb); + for (bindex = 0; !err && bindex <= bend; bindex++) { + xf = au_sbr(sb, bindex)->br_xino.xi_file; + if (!xf) + continue; + seq_printf(seq, "%d: ", bindex); + err = vfsub_getattr(xf->f_vfsmnt, xf->f_dentry, &st, dlgt); + if (!err) { + seq_printf(seq, "%ld, %llux%lu %lld", + (long)file_count(xf), st.blocks, st.blksize, + (long long)st.size); + if (unlikely(xinodir)) { + path.dentry = xf->f_dentry; + path.mnt = xf->f_vfsmnt; + seq_putc(seq, ' '); + seq_path(seq, &path, au_esc_chars); + } + seq_putc(seq, '\n'); + } else + seq_printf(seq, "err %d\n", err); + } + + out: + AuTraceErr(err); + return err; +} + +#ifdef CONFIG_AUFS_EXPORT +int sysaufs_sbi_xigen(struct seq_file *seq, struct super_block *sb) +{ + int err; + unsigned int mnt_flags; + struct au_sbinfo *sbinfo; + + AuTraceEnter(); + + err = 0; + sbinfo = au_sbi(sb); + mnt_flags = au_mntflags(sb); + if (au_opt_test_xino(mnt_flags)) + err = sysaufs_sbi_xi(seq, sbinfo->si_xigen, + !!au_opt_test(mnt_flags, DLGT), + !!au_opt_test(mnt_flags, XINODIR)); + + AuTraceErr(err); + return err; +} +#endif + +/* + * the lifetime of branch is independent from the entry under sysfs. + * sysfs handles the lifetime of the entry, and never call ->show() after it is + * unlinked. + */ +#define SysaufsBr_PREFIX "br" +static int sysaufs_sbi_br(struct seq_file *seq, struct super_block *sb, + aufs_bindex_t bindex) +{ + int err; + struct dentry *root; + struct au_branch *br; + struct path path; + + LKTRTrace("b%d\n", bindex); + + err = -ENOENT; + if (unlikely(au_sbend(sb) < bindex)) + goto out; + + err = 0; + root = sb->s_root; + di_read_lock_parent(root, !AuLock_IR); + br = au_sbr(sb, bindex); + path.mnt = br->br_mnt; + path.dentry = au_h_dptr(root, bindex); + seq_path(seq, &path, au_esc_chars); + di_read_unlock(root, !AuLock_IR); + seq_printf(seq, "=%s\n", au_optstr_br_perm(br->br_perm)); + + out: + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static struct seq_file *au_seq(char *p, ssize_t len) +{ + struct seq_file *seq; + + seq = kzalloc(sizeof(*seq), GFP_NOFS); + if (seq) { + /* todo: necessary? */ + /* mutex_init(&seq.lock); */ + seq->buf = p; + seq->size = len; + return seq; /* success */ + } + + seq = ERR_PTR(-ENOMEM); + AuTraceErrPtr(seq); + return seq; +} + +/* todo: file size may exceed PAGE_SIZE */ +ssize_t sysaufs_sbi_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + ssize_t err; + struct au_sbinfo *sbinfo; + struct super_block *sb; + struct seq_file *seq; + char *name; + struct attribute **cattr; + + LKTRTrace("%s/%s\n", kobject_name(kobj), attr->name); + + sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); + sb = sbinfo->si_sb; + si_noflush_read_lock(sb); + + seq = au_seq(buf, PAGE_SIZE); + err = PTR_ERR(seq); + if (IS_ERR(seq)) + goto out; + + name = (void *)attr->name; + cattr = au_sbi_attrs; + while (*cattr) { + if (!strcmp(name, (*cattr)->name)) { + err = container_of(*cattr, struct au_sbi_attr, attr) + ->show(seq, sb); + goto out_seq; + } + cattr++; + } + + if (!strncmp(name, SysaufsBr_PREFIX, sizeof(SysaufsBr_PREFIX) - 1)) { + name += sizeof(SysaufsBr_PREFIX) - 1; + err = sysaufs_sbi_br(seq, sb, simple_strtol(name, NULL, 10)); + goto out_seq; + } + BUG(); + + out_seq: + if (!err) { + err = seq->count; + /* sysfs limit */ + if (unlikely(err == PAGE_SIZE)) + err = -EFBIG; + } + kfree(seq); + out: + si_read_unlock(sb); + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +void sysaufs_br_init(struct au_branch *br) +{ + br->br_attr.name = br->br_name; + br->br_attr.mode = S_IRUGO; + br->br_attr.owner = THIS_MODULE; +} + +void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex) +{ + struct au_sbinfo *sbinfo; + aufs_bindex_t bend; + + LKTRTrace("b%d\n", bindex); + + if (!sysaufs_brs) + return; + + sbinfo = au_sbi(sb); + bend = au_sbend(sb); + for (; bindex <= bend; bindex++) + sysfs_remove_file(&sbinfo->si_kobj, + &au_sbr(sb, bindex)->br_attr); +} + +void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex) +{ + int err; + struct kobject *kobj; + aufs_bindex_t bend; + struct au_branch *br; + + LKTRTrace("b%d\n", bindex); + + if (!sysaufs_brs) + return; + + kobj = &au_sbi(sb)->si_kobj; + bend = au_sbend(sb); + for (; bindex <= bend; bindex++) { + br = au_sbr(sb, bindex); + snprintf(br->br_name, sizeof(br->br_name), + SysaufsBr_PREFIX "%d", bindex); + err = sysfs_create_file(kobj, &br->br_attr); + if (unlikely(err)) + AuWarn("failed %s under sysfs(%d)\n", br->br_name, err); + } +} --- linux-2.6.28.orig/ubuntu/aufs/misc.c +++ linux-2.6.28/ubuntu/aufs/misc.c @@ -0,0 +1,298 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * $Id: misc.c,v 1.17 2008/09/08 02:40:48 sfjro Exp $ + */ + +#include "aufs.h" + +void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp) +{ + void *q; + + LKTRTrace("p %p, nused %d, sz %d\n", p, nused, new_sz); + AuDebugOn(new_sz <= 0); + if (new_sz <= nused) + return p; + + q = krealloc(p, new_sz, gfp); + if (q) + memset(q + nused, 0, new_sz - nused); + return q; +} + +/* ---------------------------------------------------------------------- */ + +struct nameidata *au_dup_nd(struct au_sbinfo *sbinfo, struct nameidata *dst, + struct nameidata *src) +{ + LKTRTrace("src %p\n", src); + + if (src) { + *dst = *src; + dst->flags &= ~LOOKUP_PARENT; + if (sbinfo->si_wbr_create == AuWbrCreate_TDP) { + if ((dst->flags & LOOKUP_CREATE) + && !(dst->intent.open.flags & O_CREAT)) + dst->flags &= ~LOOKUP_CREATE; + } else { + dst->flags &= ~LOOKUP_CREATE; + dst->intent.open.flags &= ~O_CREAT; + } + } else + dst = NULL; + + return dst; +} + +struct nameidata *au_fake_dm(struct nameidata *fake_nd, struct nameidata *nd, + struct super_block *sb, aufs_bindex_t bindex) +{ + LKTRTrace("nd %p, b%d\n", nd, bindex); + + if (!nd) + return NULL; + + DiMustAnyLock(nd->path.dentry); + + fake_nd->path.dentry = NULL; + fake_nd->path.mnt = NULL; + + if (bindex <= au_dbend(nd->path.dentry)) + fake_nd->path.dentry = au_h_dptr(nd->path.dentry, bindex); + if (fake_nd->path.dentry) { + fake_nd->path.mnt = au_sbr_mnt(sb, bindex); + AuDebugOn(!fake_nd->path.mnt); + path_get(&fake_nd->path); + } else + fake_nd = ERR_PTR(-ENOENT); + + AuTraceErrPtr(fake_nd); + return fake_nd; +} + +void au_fake_dm_release(struct nameidata *fake_nd) +{ + if (fake_nd) + path_put(&fake_nd->path); +} + +int au_h_create(struct inode *h_dir, struct dentry *h_dentry, int mode, + struct vfsub_args *vargs, struct nameidata *nd, + struct vfsmount *nfsmnt) +{ + int err; + + LKTRTrace("hi%lu, %.*s, 0%o, nd %d, nfsmnt %d\n", + h_dir->i_ino, AuDLNPair(h_dentry), mode, !!nd, !!nfsmnt); + + err = -ENOSYS; + if (!nfsmnt) + err = vfsub_create(h_dir, h_dentry, mode, /*nd*/NULL, vargs); + else { + struct nameidata fake_nd; + + if (nd) + fake_nd = *nd; + else + memset(&fake_nd, 0, sizeof(fake_nd)); + fake_nd.path.dentry = h_dentry; + fake_nd.path.mnt = nfsmnt; + path_get(&fake_nd.path); + fake_nd.flags = LOOKUP_CREATE; + fake_nd.intent.open.flags = O_CREAT | FMODE_READ; + fake_nd.intent.open.create_mode = mode; + + err = vfsub_create(h_dir, h_dentry, mode, &fake_nd, vargs); + path_put(&fake_nd.path); + } + + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +int au_copy_file(struct file *dst, struct file *src, loff_t len, + struct au_hinode *hdir, struct super_block *sb, + struct vfsub_args *vargs) +{ + int err, all_zero, do_kfree; + unsigned long blksize; + char *buf, *zp; + /* reduce stack usage */ + struct iattr *ia; + + LKTRTrace("%.*s, %.*s\n", + AuDLNPair(dst->f_dentry), AuDLNPair(src->f_dentry)); + AuDebugOn(!(dst->f_mode & FMODE_WRITE)); +#ifdef CONFIG_AUFS_DEBUG + { + struct dentry *parent; + parent = dget_parent(dst->f_dentry); + IMustLock(parent->d_inode); + dput(parent); + } +#endif + + err = -ENOMEM; + blksize = dst->f_dentry->d_sb->s_blocksize; + if (!blksize || PAGE_SIZE < blksize) + blksize = PAGE_SIZE; + LKTRTrace("blksize %lu\n", blksize); + /* todo: use ZERO_PAGE(0) */ + BUILD_BUG_ON(KMALLOC_MAX_SIZE < 128 << 10); + do_kfree = 1; + if (blksize <= 64 << 10 && blksize * 2 >= sizeof(*ia)) { + buf = kmalloc(blksize * 2, GFP_NOFS); + if (unlikely(!buf)) + goto out; + zp = buf + blksize; + memset(zp, 0, blksize); + } else { + BUILD_BUG_ON(PAGE_SIZE * 2 < sizeof(*ia)); +#if 0 + buf = (void *)__get_free_pages(GFP_NOFS, 1); + zp = buf + PAGE_SIZE; +#endif + do_kfree = 0; + buf = (void *)__get_free_page(GFP_NOFS); + if (unlikely(!buf)) + goto out; + zp = (void *)get_zeroed_page(GFP_NOFS); + if (unlikely(!zp)) + goto out_buf; + } + +#ifdef CONFIG_AUFS_DEBUG + if (len > (1 << 22)) + AuWarn("copying a large file %lld\n", (long long)len); +#endif + err = 0; + all_zero = 0; + src->f_pos = 0; + dst->f_pos = 0; + while (len) { + size_t sz, rbytes, wbytes; + char *p; + + LKTRTrace("len %lld\n", len); + sz = blksize; + if (len < blksize) + sz = len; + + /* support LSM and notify */ + rbytes = 0; + /* todo: signal_pending? */ + while (!rbytes || err == -EAGAIN || err == -EINTR) { + rbytes = vfsub_read_k(src, buf, sz, &src->f_pos, + vfsub_ftest(vargs->flags, DLGT)); + err = rbytes; + } + if (unlikely(err < 0)) + break; + + all_zero = 0; + if (len >= rbytes && rbytes == blksize) { +#if 1 + all_zero = !memcmp(buf, zp, rbytes); +#else /* reserved for future use */ + unsigned long long *ullp; + size_t n, i; + + all_zero = 1; + ullp = (void *)buf; + n = rbytes / sizeof(*ullp); + i = n; + while (n-- > 0 && all_zero) + all_zero = !*ullp++; + p = (void *)ullp; + i *= sizeof(*ullp); + for (; all_zero && i < rbytes; i++) + all_zero = !*p++; +#endif + } + if (!all_zero) { + wbytes = rbytes; + p = buf; + while (wbytes) { + size_t b; + /* support LSM and notify */ + vfsub_args_reinit(vargs); + vfsub_ign_hinode(vargs, IN_MODIFY, hdir); + b = vfsub_write_k(dst, p, wbytes, &dst->f_pos, + vargs); + err = b; + /* todo: signal_pending? */ + if (unlikely(err == -EAGAIN || err == -EINTR)) + continue; + if (unlikely(err < 0)) + break; + wbytes -= b; + p += b; + } + } else { + loff_t res; + LKTRLabel(hole); + res = vfsub_llseek(dst, rbytes, SEEK_CUR); + err = res; + if (unlikely(res < 0)) + break; + } + len -= rbytes; + err = 0; + } + + /* the last block may be a hole */ + if (unlikely(!err && all_zero)) { + struct dentry *h_d = dst->f_dentry; + struct inode *h_i = h_d->d_inode; + + LKTRLabel(last hole); + do { + /* todo: signal_pending? */ + vfsub_args_reinit(vargs); + vfsub_ign_hinode(vargs, IN_MODIFY, hdir); + err = vfsub_write_k(dst, "\0", 1, &dst->f_pos, vargs); + } while (err == -EAGAIN || err == -EINTR); + if (err == 1) { + ia = (void *)buf; + ia->ia_size = dst->f_pos; + ia->ia_valid = ATTR_SIZE | ATTR_FILE; + ia->ia_file = dst; + vfsub_args_reinit(vargs); + vfsub_ign_hinode(vargs, vfsub_events_notify_change(ia), + hdir); + mutex_lock_nested(&h_i->i_mutex, AuLsc_I_CHILD2); + err = vfsub_notify_change(h_d, ia, vargs); + mutex_unlock(&h_i->i_mutex); + } + } + if (do_kfree) + kfree(buf); + else + free_page((unsigned long)zp); + + out_buf: + if (unlikely(!do_kfree)) + free_page((unsigned long)buf); + out: + AuTraceErr(err); + return err; +} --- linux-2.6.28.orig/ubuntu/aufs/opts.c +++ linux-2.6.28/ubuntu/aufs/opts.c @@ -0,0 +1,1570 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * mount options/flags + * + * $Id: opts.c,v 1.15 2008/09/01 02:55:31 sfjro Exp $ + */ + +#include /* a distribution requires */ +#include +#include "aufs.h" + +/* ---------------------------------------------------------------------- */ + +enum { + Opt_br, + Opt_add, Opt_del, Opt_mod, Opt_reorder, Opt_append, Opt_prepend, + Opt_idel, Opt_imod, Opt_ireorder, + Opt_dirwh, Opt_rdcache, Opt_deblk, Opt_nhash, Opt_rendir, + Opt_xino, Opt_zxino, Opt_noxino, + Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino, + Opt_trunc_xino_path, Opt_itrunc_xino, + Opt_xinodir, + Opt_trunc_xib, Opt_notrunc_xib, + Opt_dirperm1, Opt_nodirperm1, + Opt_shwh, Opt_noshwh, + Opt_plink, Opt_noplink, Opt_list_plink, Opt_clean_plink, + Opt_udba, + /* Opt_lock, Opt_unlock, */ + Opt_cmd, Opt_cmd_args, + Opt_diropq_a, Opt_diropq_w, + Opt_warn_perm, Opt_nowarn_perm, + Opt_wbr_copyup, Opt_wbr_create, + Opt_coo, + Opt_dlgt, Opt_nodlgt, + Opt_refrof, Opt_norefrof, + Opt_verbose, Opt_noverbose, + Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err +}; + +static match_table_t options = { + {Opt_br, "br=%s"}, + {Opt_br, "br:%s"}, + + {Opt_add, "add=%d:%s"}, + {Opt_add, "add:%d:%s"}, + {Opt_add, "ins=%d:%s"}, + {Opt_add, "ins:%d:%s"}, + {Opt_append, "append=%s"}, + {Opt_append, "append:%s"}, + {Opt_prepend, "prepend=%s"}, + {Opt_prepend, "prepend:%s"}, + + {Opt_del, "del=%s"}, + {Opt_del, "del:%s"}, + /* {Opt_idel, "idel:%d"}, */ + {Opt_mod, "mod=%s"}, + {Opt_mod, "mod:%s"}, + {Opt_imod, "imod:%d:%s"}, + + {Opt_dirwh, "dirwh=%d"}, + {Opt_dirwh, "dirwh:%d"}, + + {Opt_xino, "xino=%s"}, + {Opt_xino, "xino:%s"}, +#if 0 /* def CONFIG_AUFS_EXPORT */ /* reserved for futur use */ + {Opt_xinodir, "xinodir=%s"}, + {Opt_xinodir, "xinodir:%s"}, +#endif + {Opt_noxino, "noxino"}, + {Opt_trunc_xino, "trunc_xino"}, + {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"}, + {Opt_notrunc_xino, "notrunc_xino"}, + {Opt_trunc_xino_path, "trunc_xino=%s"}, + {Opt_trunc_xino_path, "trunc_xino:%s"}, + {Opt_itrunc_xino, "itrunc_xino=%d"}, + {Opt_itrunc_xino, "itrunc_xino:%d"}, + /* {Opt_zxino, "zxino=%s"}, */ + {Opt_trunc_xib, "trunc_xib"}, + {Opt_notrunc_xib, "notrunc_xib"}, + + {Opt_plink, "plink"}, + {Opt_noplink, "noplink"}, +#ifdef CONFIG_AUFS_DEBUG + {Opt_list_plink, "list_plink"}, +#endif + {Opt_clean_plink, "clean_plink"}, + + {Opt_udba, "udba=%s"}, + + {Opt_diropq_a, "diropq=always"}, + {Opt_diropq_a, "diropq=a"}, + {Opt_diropq_w, "diropq=whiteouted"}, + {Opt_diropq_w, "diropq=w"}, + + {Opt_warn_perm, "warn_perm"}, + {Opt_nowarn_perm, "nowarn_perm"}, + +#ifdef CONFIG_AUFS_DLGT + {Opt_dlgt, "dlgt"}, + {Opt_nodlgt, "nodlgt"}, + + {Opt_dirperm1, "dirperm1"}, + {Opt_nodirperm1, "nodirperm1"}, +#endif + +#ifdef CONFIG_AUFS_SHWH + {Opt_shwh, "shwh"}, + {Opt_noshwh, "noshwh"}, +#endif + + {Opt_rendir, "rendir=%d"}, + {Opt_rendir, "rendir:%d"}, + + {Opt_refrof, "refrof"}, + {Opt_norefrof, "norefrof"}, + + {Opt_verbose, "verbose"}, + {Opt_verbose, "v"}, + {Opt_noverbose, "noverbose"}, + {Opt_noverbose, "quiet"}, + {Opt_noverbose, "q"}, + {Opt_noverbose, "silent"}, + + {Opt_rdcache, "rdcache=%d"}, + {Opt_rdcache, "rdcache:%d"}, + + {Opt_coo, "coo=%s"}, + + {Opt_wbr_create, "create=%s"}, + {Opt_wbr_create, "create:%s"}, + {Opt_wbr_create, "create_policy=%s"}, + {Opt_wbr_create, "create_policy:%s"}, + {Opt_wbr_copyup, "cpup=%s"}, + {Opt_wbr_copyup, "cpup:%s"}, + {Opt_wbr_copyup, "copyup=%s"}, + {Opt_wbr_copyup, "copyup:%s"}, + {Opt_wbr_copyup, "copyup_policy=%s"}, + {Opt_wbr_copyup, "copyup_policy:%s"}, + + /* internal use for the scripts */ + {Opt_ignore_silent, "si=%s"}, + +#if 0 /* reserved for future use */ + {Opt_deblk, "deblk=%d"}, + {Opt_deblk, "deblk:%d"}, + {Opt_nhash, "nhash=%d"}, + {Opt_nhash, "nhash:%d"}, +#endif + + {Opt_br, "dirs=%s"}, + {Opt_ignore, "debug=%d"}, + {Opt_ignore, "delete=whiteout"}, + {Opt_ignore, "delete=all"}, + {Opt_ignore, "imap=%s"}, + + {Opt_err, NULL} +}; + +/* ---------------------------------------------------------------------- */ + +static const char *au_parser_pattern(int val, struct match_token *token) +{ + while (token->pattern) { + if (token->token == val) + return token->pattern; + token++; + } + BUG(); + return "??"; +} + +/* ---------------------------------------------------------------------- */ + +#define RW "rw" +#define RO "ro" +#define WH "wh" +#define RR "rr" +#define NoLinkWH "nolwh" + +static match_table_t brperms = { + {AuBrPerm_RR, RR}, + {AuBrPerm_RO, RO}, + {AuBrPerm_RW, RW}, + + {AuBrPerm_RRWH, RR "+" WH}, + {AuBrPerm_ROWH, RO "+" WH}, + {AuBrPerm_RWNoLinkWH, RW "+" NoLinkWH}, + + {AuBrPerm_ROWH, "nfsro"}, + {AuBrPerm_RO, NULL} +}; + +static noinline_for_stack int br_perm_val(char *perm) +{ + int val; + substring_t args[MAX_OPT_ARGS]; + + AuDebugOn(!perm || !*perm); + LKTRTrace("perm %s\n", perm); + val = match_token(perm, brperms, args); + AuTraceErr(val); + return val; +} + +const char *au_optstr_br_perm(int brperm) +{ + return au_parser_pattern(brperm, (void *)brperms); +} + +/* ---------------------------------------------------------------------- */ + +static match_table_t udbalevel = { + {AuOpt_UDBA_REVAL, "reval"}, +#ifdef CONFIG_AUFS_HINOTIFY + {AuOpt_UDBA_INOTIFY, "inotify"}, +#endif + {AuOpt_UDBA_NONE, "none"}, + {-1, NULL} +}; + +static noinline_for_stack int udba_val(char *str) +{ + substring_t args[MAX_OPT_ARGS]; + return match_token(str, udbalevel, args); +} + +const char *au_optstr_udba(int udba) +{ + return au_parser_pattern(udba, (void *)udbalevel); +} + +/* ---------------------------------------------------------------------- */ + +static match_table_t coolevel = { + {AuOpt_COO_NONE, "none"}, + {AuOpt_COO_LEAF, "leaf"}, + {AuOpt_COO_ALL, "all"}, + {-1, NULL} +}; + +static noinline_for_stack int coo_val(char *str) +{ + substring_t args[MAX_OPT_ARGS]; + return match_token(str, coolevel, args); +} + +const char *au_optstr_coo(int coo) +{ + return au_parser_pattern(coo, (void *)coolevel); +} + +/* ---------------------------------------------------------------------- */ + +static match_table_t au_wbr_create_policy = { + {AuWbrCreate_TDP, "tdp"}, + {AuWbrCreate_TDP, "top-down-parent"}, + {AuWbrCreate_RR, "rr"}, + {AuWbrCreate_RR, "round-robin"}, + {AuWbrCreate_MFS, "mfs"}, + {AuWbrCreate_MFS, "most-free-space"}, + {AuWbrCreate_MFSV, "mfs:%d"}, + {AuWbrCreate_MFSV, "most-free-space:%d"}, + + {AuWbrCreate_MFSRR, "mfsrr:%d"}, + {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"}, + {AuWbrCreate_PMFS, "pmfs"}, + {AuWbrCreate_PMFSV, "pmfs:%d"}, + + {-1, NULL} +}; + +/* cf. linux/lib/parser.c */ +static int au_match_ull(substring_t *s, unsigned long long *result, int base) +{ + char *endp; + char *buf; + int ret; + + buf = kmalloc(s->to - s->from + 1, GFP_NOFS); + if (!buf) + return -ENOMEM; + memcpy(buf, s->from, s->to - s->from); + buf[s->to - s->from] = '\0'; + *result = simple_strtoull(buf, &endp, base); + ret = 0; + if (endp == buf) + ret = -EINVAL; + kfree(buf); + return ret; +} + +static int au_wbr_mfs_wmark(substring_t *arg, char *str, + struct au_opt_wbr_create *create) +{ + int err; + unsigned long long ull; + + err = 0; + if (!au_match_ull(arg, &ull, 0)) + create->mfsrr_watermark = ull; + else { + AuErr("bad integer in %s\n", str); + err = -EINVAL; + } + + AuTraceErr(err); + return err; +} + +static int au_wbr_mfs_sec(substring_t *arg, char *str, + struct au_opt_wbr_create *create) +{ + int n, err; + + err = 0; + if (!match_int(arg, &n) && 0 <= n) + create->mfs_second = n; + else { + AuErr("bad integer in %s\n", str); + err = -EINVAL; + } + + AuTraceErr(err); + return err; +} + +static noinline_for_stack +int au_wbr_create_val(char *str, struct au_opt_wbr_create *create) +{ + int err, e; + substring_t args[MAX_OPT_ARGS]; + + err = match_token(str, au_wbr_create_policy, args); + create->wbr_create = err; + switch (err) { + case AuWbrCreate_MFSRRV: + e = au_wbr_mfs_wmark(&args[0], str, create); + if (!e) + e = au_wbr_mfs_sec(&args[1], str, create); + if (unlikely(e)) + err = e; + break; + case AuWbrCreate_MFSRR: + e = au_wbr_mfs_wmark(&args[0], str, create); + if (unlikely(e)) { + err = e; + break; + } + /*FALLTHROUGH*/ + case AuWbrCreate_MFS: + case AuWbrCreate_PMFS: + create->mfs_second = AUFS_MFS_SECOND_DEF; + break; + case AuWbrCreate_MFSV: + case AuWbrCreate_PMFSV: + e = au_wbr_mfs_sec(&args[0], str, create); + if (unlikely(e)) + err = e; + break; + } + + return err; +} + +const char *au_optstr_wbr_create(int wbr_create) +{ + return au_parser_pattern(wbr_create, (void *)au_wbr_create_policy); +} + +static match_table_t au_wbr_copyup_policy = { + {AuWbrCopyup_TDP, "tdp"}, + {AuWbrCopyup_TDP, "top-down-parent"}, + {AuWbrCopyup_BUP, "bup"}, + {AuWbrCopyup_BUP, "bottom-up-parent"}, + {AuWbrCopyup_BU, "bu"}, + {AuWbrCopyup_BU, "bottom-up"}, + {-1, NULL} +}; + +static noinline_for_stack int au_wbr_copyup_val(char *str) +{ + substring_t args[MAX_OPT_ARGS]; + return match_token(str, au_wbr_copyup_policy, args); +} + +const char *au_optstr_wbr_copyup(int wbr_copyup) +{ + return au_parser_pattern(wbr_copyup, (void *)au_wbr_copyup_policy); +} + +/* ---------------------------------------------------------------------- */ + +static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY; + +static void dump_opts(struct au_opts *opts) +{ +#ifdef CONFIG_AUFS_DEBUG + /* reduce stack space */ + union { + struct au_opt_add *add; + struct au_opt_del *del; + struct au_opt_mod *mod; + struct au_opt_xino *xino; + struct au_opt_xinodir *xinodir; + struct au_opt_xino_itrunc *xino_itrunc; + struct au_opt_wbr_create *create; + } u; + struct au_opt *opt; + + AuTraceEnter(); + + opt = opts->opt; + while (/* opt < opts_tail && */ opt->type != Opt_tail) { + switch (opt->type) { + case Opt_add: + u.add = &opt->add; + LKTRTrace("add {b%d, %s, 0x%x, %p}\n", + u.add->bindex, u.add->path, u.add->perm, + u.add->nd.path.dentry); + break; + case Opt_del: + case Opt_idel: + u.del = &opt->del; + LKTRTrace("del {%s, %p}\n", u.del->path, u.del->h_root); + break; + case Opt_mod: + case Opt_imod: + u.mod = &opt->mod; + LKTRTrace("mod {%s, 0x%x, %p}\n", + u.mod->path, u.mod->perm, u.mod->h_root); + break; + case Opt_append: + u.add = &opt->add; + LKTRTrace("append {b%d, %s, 0x%x, %p}\n", + u.add->bindex, u.add->path, u.add->perm, + u.add->nd.path.dentry); + break; + case Opt_prepend: + u.add = &opt->add; + LKTRTrace("prepend {b%d, %s, 0x%x, %p}\n", + u.add->bindex, u.add->path, u.add->perm, + u.add->nd.path.dentry); + break; + case Opt_dirwh: + LKTRTrace("dirwh %d\n", opt->dirwh); + break; + case Opt_rdcache: + LKTRTrace("rdcache %d\n", opt->rdcache); + break; + case Opt_xino: + u.xino = &opt->xino; + LKTRTrace("xino {%s %.*s}\n", + u.xino->path, + AuDLNPair(u.xino->file->f_dentry)); + break; + case Opt_xinodir: + u.xinodir = &opt->xinodir; + LKTRTrace("xinodir {%s %.*s}\n", + u.xinodir->name, + AuDLNPair(u.xinodir->path.dentry)); + break; + case Opt_trunc_xino: + LKTRLabel(trunc_xino); + break; + case Opt_notrunc_xino: + LKTRLabel(notrunc_xino); + break; + case Opt_trunc_xino_path: + case Opt_itrunc_xino: + u.xino_itrunc = &opt->xino_itrunc; + LKTRTrace("trunc_xino %d\n", u.xino_itrunc->bindex); + break; + + case Opt_noxino: + LKTRLabel(noxino); + break; + case Opt_trunc_xib: + LKTRLabel(trunc_xib); + break; + case Opt_notrunc_xib: + LKTRLabel(notrunc_xib); + break; + case Opt_dirperm1: + LKTRLabel(dirperm1); + break; + case Opt_nodirperm1: + LKTRLabel(nodirperm1); + break; + case Opt_shwh: + LKTRLabel(shwh); + break; + case Opt_noshwh: + LKTRLabel(noshwh); + break; + case Opt_plink: + LKTRLabel(plink); + break; + case Opt_noplink: + LKTRLabel(noplink); + break; + case Opt_list_plink: + LKTRLabel(list_plink); + break; + case Opt_clean_plink: + LKTRLabel(clean_plink); + break; + case Opt_udba: + LKTRTrace("udba %d, %s\n", + opt->udba, au_optstr_udba(opt->udba)); + break; + case Opt_diropq_a: + LKTRLabel(diropq_a); + break; + case Opt_diropq_w: + LKTRLabel(diropq_w); + break; + case Opt_warn_perm: + LKTRLabel(warn_perm); + break; + case Opt_nowarn_perm: + LKTRLabel(nowarn_perm); + break; + case Opt_dlgt: + LKTRLabel(dlgt); + break; + case Opt_nodlgt: + LKTRLabel(nodlgt); + break; + case Opt_refrof: + LKTRLabel(refrof); + break; + case Opt_norefrof: + LKTRLabel(norefrof); + break; + case Opt_verbose: + LKTRLabel(verbose); + break; + case Opt_noverbose: + LKTRLabel(noverbose); + break; + case Opt_coo: + LKTRTrace("coo %d, %s\n", + opt->coo, au_optstr_coo(opt->coo)); + break; + case Opt_wbr_create: + u.create = &opt->wbr_create; + LKTRTrace("create %d, %s\n", u.create->wbr_create, + au_optstr_wbr_create(u.create->wbr_create)); + switch (u.create->wbr_create) { + case AuWbrCreate_MFSV: + case AuWbrCreate_PMFSV: + LKTRTrace("%d sec\n", u.create->mfs_second); + break; + case AuWbrCreate_MFSRR: + LKTRTrace("%llu watermark\n", + u.create->mfsrr_watermark); + break; + case AuWbrCreate_MFSRRV: + LKTRTrace("%llu watermark, %d sec\n", + u.create->mfsrr_watermark, + u.create->mfs_second); + break; + } + break; + case Opt_wbr_copyup: + LKTRTrace("copyup %d, %s\n", opt->wbr_copyup, + au_optstr_wbr_copyup(opt->wbr_copyup)); + break; + default: + BUG(); + } + opt++; + } +#endif +} + +void au_opts_free(struct au_opts *opts) +{ + struct au_opt *opt; + + AuTraceEnter(); + + opt = opts->opt; + while (opt->type != Opt_tail) { + switch (opt->type) { + case Opt_add: + case Opt_append: + case Opt_prepend: + path_put(&opt->add.nd.path); + break; + case Opt_del: + case Opt_idel: + dput(opt->del.h_root); + break; + case Opt_mod: + case Opt_imod: + dput(opt->mod.h_root); + break; + case Opt_xino: + fput(opt->xino.file); + break; + case Opt_xinodir: + path_put(&opt->xinodir.path); + break; + } + opt++; + } +} + +static int opt_add(struct au_opt *opt, char *opt_str, struct super_block *sb, + aufs_bindex_t bindex) +{ + int err; + struct au_opt_add *add = &opt->add; + char *p; + + LKTRTrace("%s, b%d\n", opt_str, bindex); + + add->bindex = bindex; + add->perm = AuBrPerm_Last; + add->path = opt_str; + p = strchr(opt_str, '='); + if (unlikely(p)) { + *p++ = 0; + if (*p) + add->perm = br_perm_val(p); + } + + /* LSM may detect it */ + /* do not superio. */ + err = vfsub_path_lookup(add->path, lkup_dirflags, &add->nd); + if (!err) { + if (!p /* && add->perm == AuBrPerm_Last */) { + add->perm = AuBrPerm_RO; + if (au_test_def_rr(add->nd.path.dentry->d_sb)) + add->perm = AuBrPerm_RR; + if (!bindex && !(sb->s_flags & MS_RDONLY)) + add->perm = AuBrPerm_RW; +#ifdef CONFIG_AUFS_COMPAT + add->perm = AuBrPerm_RW; +#endif + } + opt->type = Opt_add; + goto out; + } + AuErr("lookup failed %s (%d)\n", add->path, err); + err = -EINVAL; + + out: + AuTraceErr(err); + return err; +} + +/* called without aufs lock */ +int au_opts_parse(struct super_block *sb, unsigned long flags, char *str, + struct au_opts *opts) +{ + int err, n, token; + struct dentry *root; + struct au_opt *opt, *opt_tail; + char *opt_str, *p; + aufs_bindex_t bindex, bend; + unsigned char skipped; + union { + struct au_opt_del *del; + struct au_opt_mod *mod; + struct au_opt_xino *xino; + struct au_opt_xinodir *xinodir; + struct au_opt_xino_itrunc *xino_itrunc; + struct au_opt_wbr_create *create; + } u; + struct file *file; + /* reduce the stack space */ + struct { + substring_t args[MAX_OPT_ARGS]; + struct nameidata nd; + } *a; + + LKTRTrace("%s, nopts %d\n", str, opts->max_opt); + + err = -ENOMEM; + a = kmalloc(sizeof(*a), GFP_NOFS); + if (unlikely(!a)) + goto out; + + root = sb->s_root; + err = 0; + bindex = 0; + opt = opts->opt; + opt_tail = opt + opts->max_opt - 1; + opt->type = Opt_tail; + while (!err && (opt_str = strsep(&str, ",")) && *opt_str) { + err = -EINVAL; + token = match_token(opt_str, options, a->args); + LKTRTrace("%s, token %d, a->args[0]{%p, %p}\n", + opt_str, token, a->args[0].from, a->args[0].to); + + skipped = 0; + switch (token) { + case Opt_br: + err = 0; + while (!err && (opt_str = strsep(&a->args[0].from, ":")) + && *opt_str) { + err = opt_add(opt, opt_str, sb, bindex++); + if (unlikely(!err && ++opt > opt_tail)) { + err = -E2BIG; + break; + } + opt->type = Opt_tail; + skipped = 1; + } + break; + case Opt_add: + if (unlikely(match_int(&a->args[0], &n))) { + AuErr("bad integer in %s\n", opt_str); + break; + } + bindex = n; + err = opt_add(opt, a->args[1].from, sb, bindex); + break; + case Opt_append: + err = opt_add(opt, a->args[0].from, sb, + /*dummy bindex*/1); + if (!err) + opt->type = token; + break; + case Opt_prepend: + err = opt_add(opt, a->args[0].from, sb, /*bindex*/0); + if (!err) + opt->type = token; + break; + case Opt_del: + u.del = &opt->del; + u.del->path = a->args[0].from; + LKTRTrace("del path %s\n", u.del->path); + /* LSM may detect it */ + /* do not superio. */ + err = vfsub_path_lookup(u.del->path, lkup_dirflags, + &a->nd); + if (unlikely(err)) { + AuErr("lookup failed %s (%d)\n", + u.del->path, err); + break; + } + u.del->h_root = dget(a->nd.path.dentry); + path_put(&a->nd.path); + opt->type = token; + break; +#if 0 /* reserved for future use */ + case Opt_idel: + u.del = &opt->del; + u.del->path = "(indexed)"; + if (unlikely(match_int(&a->args[0], &n))) { + AuErr("bad integer in %s\n", opt_str); + break; + } + bindex = n; + aufs_read_lock(root, AuLock_FLUSH); + if (bindex < 0 || au_sbend(sb) < bindex) { + AuErr("out of bounds, %d\n", bindex); + aufs_read_unlock(root, !AuLock_IR); + break; + } + err = 0; + u.del->h_root = dget(au_h_dptr(root, bindex)); + opt->type = token; + aufs_read_unlock(root, !AuLock_IR); + break; +#endif + case Opt_mod: + u.mod = &opt->mod; + u.mod->path = a->args[0].from; + p = strchr(u.mod->path, '='); + if (unlikely(!p)) { + AuErr("no permssion %s\n", opt_str); + break; + } + *p++ = 0; + u.mod->perm = br_perm_val(p); + LKTRTrace("mod path %s, perm 0x%x, %s\n", + u.mod->path, u.mod->perm, p); + /* LSM may detect it */ + /* do not superio. */ + err = vfsub_path_lookup(u.mod->path, lkup_dirflags, + &a->nd); + if (unlikely(err)) { + AuErr("lookup failed %s (%d)\n", + u.mod->path, err); + break; + } + u.mod->h_root = dget(a->nd.path.dentry); + path_put(&a->nd.path); + opt->type = token; + break; +#ifdef IMOD /* reserved for future use */ + case Opt_imod: + u.mod = &opt->mod; + u.mod->path = "(indexed)"; + if (unlikely(match_int(&a->args[0], &n))) { + AuErr("bad integer in %s\n", opt_str); + break; + } + bindex = n; + aufs_read_lock(root, AuLock_FLUSH); + if (bindex < 0 || au_sbend(sb) < bindex) { + AuErr("out of bounds, %d\n", bindex); + aufs_read_unlock(root, !AuLock_IR); + break; + } + u.mod->perm = br_perm_val(a->args[1].from); + LKTRTrace("mod path %s, perm 0x%x, %s\n", + u.mod->path, u.mod->perm, a->args[1].from); + err = 0; + u.mod->h_root = dget(au_h_dptr(root, bindex)); + opt->type = token; + aufs_read_unlock(root, !AuLock_IR); + break; +#endif + case Opt_xino: + u.xino = &opt->xino; + file = au_xino_create(sb, a->args[0].from, /*silent*/0); + err = PTR_ERR(file); + if (IS_ERR(file)) + break; + err = -EINVAL; + if (unlikely(file->f_dentry->d_sb == sb)) { + fput(file); + AuErr("%s must be outside\n", a->args[0].from); + break; + } + err = 0; + u.xino->file = file; + u.xino->path = a->args[0].from; + opt->type = token; + break; + +#if 0 /* def CONFIG_AUFS_EXPORT */ /* reserved for futur use */ + case Opt_xinodir: + u.xinodir = &opt->xinodir; + u.xinodir->name = a->args[0].from; + err = vfsub_path_lookup(u.xinodir->name, lkup_dirflags, + &a->nd); + if (unlikely(err)) { + AuErr("lookup failed %s (%d)\n", + u.xinodir->name, err); + break; + } + u.xinodir->path = a->nd.path; + /* do not path_put() */ + opt->type = token; + break; +#endif + + case Opt_trunc_xino_path: + u.xino_itrunc = &opt->xino_itrunc; + p = a->args[0].from; + LKTRTrace("trunc_xino path %s\n", p); + /* LSM may detect it */ + /* do not superio. */ + err = vfsub_path_lookup(p, lkup_dirflags, &a->nd); + if (unlikely(err)) { + AuErr("lookup failed %s (%d)\n", p , err); + break; + } + u.xino_itrunc->bindex = -1; + aufs_read_lock(root, AuLock_FLUSH); + bend = au_sbend(sb); + for (bindex = 0; bindex <= bend; bindex++) { + if (au_h_dptr(root, bindex) + == a->nd.path.dentry) { + u.xino_itrunc->bindex = bindex; + break; + } + } + aufs_read_unlock(root, !AuLock_IR); + path_put(&a->nd.path); + if (unlikely(u.xino_itrunc->bindex < 0)) { + AuErr("no such branch %s\n", p); + err = -EINVAL; + break; + } + opt->type = token; + break; + + case Opt_itrunc_xino: + u.xino_itrunc = &opt->xino_itrunc; + if (unlikely(match_int(&a->args[0], &n))) { + AuErr("bad integer in %s\n", opt_str); + break; + } + u.xino_itrunc->bindex = n; + aufs_read_lock(root, AuLock_FLUSH); + if (n < 0 || au_sbend(sb) < n) { + AuErr("out of bounds, %d\n", n); + aufs_read_unlock(root, !AuLock_IR); + break; + } + aufs_read_unlock(root, !AuLock_IR); + err = 0; + opt->type = token; + break; + + case Opt_dirwh: + if (unlikely(match_int(&a->args[0], &opt->dirwh))) + break; + err = 0; + opt->type = token; + break; + + case Opt_rdcache: + if (unlikely(match_int(&a->args[0], &opt->rdcache))) + break; + err = 0; + opt->type = token; + break; + + case Opt_shwh: + if (flags & MS_RDONLY) { + err = 0; + opt->type = token; + } else + AuErr("shwh requires ro\n"); + break; + + case Opt_trunc_xino: + case Opt_notrunc_xino: + case Opt_noxino: + case Opt_trunc_xib: + case Opt_notrunc_xib: + case Opt_dirperm1: + case Opt_nodirperm1: + case Opt_noshwh: + case Opt_plink: + case Opt_noplink: + case Opt_list_plink: + case Opt_clean_plink: + case Opt_diropq_a: + case Opt_diropq_w: + case Opt_warn_perm: + case Opt_nowarn_perm: + case Opt_dlgt: + case Opt_nodlgt: + case Opt_refrof: + case Opt_norefrof: + case Opt_verbose: + case Opt_noverbose: + err = 0; + opt->type = token; + break; + + case Opt_udba: + opt->udba = udba_val(a->args[0].from); + if (opt->udba >= 0) { + err = 0; + opt->type = token; + } else + AuErr("wrong value, %s\n", opt_str); + break; + + case Opt_wbr_create: + u.create = &opt->wbr_create; + u.create->wbr_create + = au_wbr_create_val(a->args[0].from, u.create); + if (u.create->wbr_create >= 0) { + err = 0; + opt->type = token; + } else + AuErr("wrong value, %s\n", opt_str); + break; + case Opt_wbr_copyup: + opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from); + if (opt->wbr_copyup >= 0) { + err = 0; + opt->type = token; + } else + AuErr("wrong value, %s\n", opt_str); + break; + + case Opt_coo: + opt->coo = coo_val(a->args[0].from); + if (opt->coo >= 0) { + err = 0; + opt->type = token; + } else + AuErr("wrong value, %s\n", opt_str); + break; + + case Opt_ignore: +#ifndef CONFIG_AUFS_COMPAT + AuWarn("ignored %s\n", opt_str); +#endif + case Opt_ignore_silent: + skipped = 1; + err = 0; + break; + case Opt_err: + AuErr("unknown option %s\n", opt_str); + break; + } + + if (!err && !skipped) { + if (unlikely(++opt > opt_tail)) { + err = -E2BIG; + opt--; + opt->type = Opt_tail; + break; + } + opt->type = Opt_tail; + } + } + + kfree(a); + dump_opts(opts); + if (unlikely(err)) + au_opts_free(opts); + + out: + AuTraceErr(err); + return err; +} + +/* + * returns, + * plus: processed without an error + * zero: unprocessed + */ +static int au_opt_simple(struct super_block *sb, struct au_opt *opt, + struct au_opts *opts) +{ + int err; + struct au_sbinfo *sbinfo; + struct au_opt_wbr_create *create; + + AuTraceEnter(); + + err = 1; /* handled */ + sbinfo = au_sbi(sb); + switch (opt->type) { + case Opt_udba: + sbinfo->si_mntflags &= ~AuOptMask_UDBA; + sbinfo->si_mntflags |= opt->udba; + opts->given_udba |= opt->udba; + break; + + case Opt_plink: + au_opt_set(sbinfo->si_mntflags, PLINK); + break; + case Opt_noplink: + if (au_opt_test(sbinfo->si_mntflags, PLINK)) + au_plink_put(sb); + au_opt_clr(sbinfo->si_mntflags, PLINK); + break; + case Opt_list_plink: + if (au_opt_test(sbinfo->si_mntflags, PLINK)) + au_plink_list(sb); + break; + case Opt_clean_plink: + if (au_opt_test(sbinfo->si_mntflags, PLINK)) + au_plink_put(sb); + break; + + case Opt_diropq_a: + au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ); + break; + case Opt_diropq_w: + au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ); + break; + + case Opt_dlgt: + au_opt_set(sbinfo->si_mntflags, DLGT); + break; + case Opt_nodlgt: + au_opt_clr(sbinfo->si_mntflags, DLGT); + break; + + case Opt_warn_perm: + au_opt_set(sbinfo->si_mntflags, WARN_PERM); + break; + case Opt_nowarn_perm: + au_opt_clr(sbinfo->si_mntflags, WARN_PERM); + break; + + case Opt_refrof: + au_opt_set(sbinfo->si_mntflags, REFROF); + break; + case Opt_norefrof: + /* au_opt_set(sbinfo->si_mntflags, COO_LEAF); */ + au_opt_clr(sbinfo->si_mntflags, REFROF); + break; + + case Opt_verbose: + au_opt_set(sbinfo->si_mntflags, VERBOSE); + break; + case Opt_noverbose: + au_opt_clr(sbinfo->si_mntflags, VERBOSE); + break; + + case Opt_wbr_create: + create = &opt->wbr_create; + if (sbinfo->si_wbr_create_ops->fin) { + err = sbinfo->si_wbr_create_ops->fin(sb); + if (!err) + err = 1; + } + sbinfo->si_wbr_create = create->wbr_create; + sbinfo->si_wbr_create_ops + = au_wbr_create_ops + create->wbr_create; + switch (create->wbr_create) { + case AuWbrCreate_MFSRRV: + case AuWbrCreate_MFSRR: + sbinfo->si_wbr_mfs.mfsrr_watermark + = create->mfsrr_watermark; + /*FALLTHROUGH*/ + case AuWbrCreate_MFS: + case AuWbrCreate_MFSV: + case AuWbrCreate_PMFS: + case AuWbrCreate_PMFSV: + sbinfo->si_wbr_mfs.mfs_expire = create->mfs_second * HZ; + break; + } + if (sbinfo->si_wbr_create_ops->init) + sbinfo->si_wbr_create_ops->init(sb); /* ignore */ + break; + case Opt_wbr_copyup: + sbinfo->si_wbr_copyup = opt->wbr_copyup; + sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup; + break; + + case Opt_coo: + sbinfo->si_mntflags &= ~AuOptMask_COO; + sbinfo->si_mntflags |= opt->coo; + break; + + case Opt_dirwh: + sbinfo->si_dirwh = opt->dirwh; + break; + + case Opt_rdcache: + sbinfo->si_rdcache = opt->rdcache * HZ; + break; + + case Opt_trunc_xino: + au_opt_set(sbinfo->si_mntflags, TRUNC_XINO); + break; + case Opt_notrunc_xino: + au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO); + break; + + case Opt_dirperm1: + au_opt_set(sbinfo->si_mntflags, DIRPERM1); + break; + case Opt_nodirperm1: + au_opt_clr(sbinfo->si_mntflags, DIRPERM1); + break; + + case Opt_shwh: + au_opt_set(sbinfo->si_mntflags, SHWH); + break; + case Opt_noshwh: + au_opt_clr(sbinfo->si_mntflags, SHWH); + break; + + case Opt_trunc_xino_path: + case Opt_itrunc_xino: + err = au_xino_trunc(sb, opt->xino_itrunc.bindex); + if (!err) + err = 1; + break; + + case Opt_trunc_xib: + au_fset_opts(opts->flags, TRUNC_XIB); + break; + case Opt_notrunc_xib: + au_fclr_opts(opts->flags, TRUNC_XIB); + break; + + default: + err = 0; + break; + } + + AuTraceErr(err); + return err; +} + +/* + * returns tri-state. + * plus: processed without an error + * zero: unprocessed + * minus: error + */ +static int au_opt_br(struct super_block *sb, struct au_opt *opt, + struct au_opts *opts) +{ + int err, do_refresh; + + AuTraceEnter(); + + err = 0; + switch (opt->type) { + case Opt_append: + opt->add.bindex = au_sbend(sb) + 1; + if (unlikely(opt->add.bindex < 0)) + opt->add.bindex = 0; + goto add; + case Opt_prepend: + opt->add.bindex = 0; + add: + case Opt_add: + err = au_br_add(sb, &opt->add, + au_ftest_opts(opts->flags, REMOUNT)); + if (!err) { + err = 1; + au_fset_opts(opts->flags, REFRESH_DIR); + if (unlikely(au_br_whable(opt->add.perm))) + au_fset_opts(opts->flags, REFRESH_NONDIR); + } + break; + + case Opt_del: + case Opt_idel: + err = au_br_del(sb, &opt->del, + au_ftest_opts(opts->flags, REMOUNT)); + if (!err) { + err = 1; + au_fset_opts(opts->flags, TRUNC_XIB); + au_fset_opts(opts->flags, REFRESH_DIR); + au_fset_opts(opts->flags, REFRESH_NONDIR); + } + break; + + case Opt_mod: + case Opt_imod: + err = au_br_mod(sb, &opt->mod, + au_ftest_opts(opts->flags, REMOUNT), + &do_refresh); + if (!err) { + err = 1; + if (unlikely(do_refresh)) { + au_fset_opts(opts->flags, REFRESH_DIR); + au_fset_opts(opts->flags, REFRESH_NONDIR); + } + } + break; + } + + AuTraceErr(err); + return err; +} + +static int au_opt_xino(struct super_block *sb, struct au_opt *opt, + struct au_opt_xino **opt_xino, + struct au_opt_xinodir **opt_xinodir, + struct au_opts *opts) +{ + int err; + const int remount = !!au_ftest_opts(opts->flags, REMOUNT); + + AuTraceEnter(); + + err = 0; + switch (opt->type) { + case Opt_xino: + err = au_xino_set(sb, &opt->xino, remount); + if (!err) + *opt_xino = &opt->xino; + break; +#if 0 /* def CONFIG_AUFS_EXPORT */ /* reserved for futur use */ + case Opt_xinodir: + err = au_xinodir_set(sb, &opt->xinodir, remount); + if (!err) + *opt_xinodir = &opt->xinodir; + break; +#endif + case Opt_noxino: + au_xino_clr(sb); + *opt_xino = (void *)-1; + break; + } + + AuTraceErr(err); + return err; +} + +static int verify_opts(struct super_block *sb, unsigned int pending, + int remount) +{ + int err; + aufs_bindex_t bindex, bend; + unsigned char do_plink, skip, do_free; + struct au_branch *br; + struct au_wbr *wbr; + struct dentry *root; + struct inode *dir, *h_dir; + unsigned int mnt_flags; + + AuTraceEnter(); + mnt_flags = au_mntflags(sb); + AuDebugOn(!(mnt_flags & AuOptMask_COO)); + AuDebugOn(!(mnt_flags & AuOptMask_UDBA)); + + if (!(sb->s_flags & MS_RDONLY)) { + if (unlikely(!au_br_writable(au_sbr_perm(sb, 0)))) + AuWarn("first branch should be rw\n"); + if (unlikely(au_opt_test(mnt_flags, SHWH))) + AuWarn("shwh should be used with ro\n"); + } + + if (unlikely(au_opt_test((mnt_flags | pending), UDBA_INOTIFY) + && !au_opt_test_xino(mnt_flags))) + AuWarn("udba=inotify requires xino\n"); + + err = 0; + root = sb->s_root; + dir = sb->s_root->d_inode; + do_plink = !!au_opt_test(mnt_flags, PLINK); + bend = au_sbend(sb); + for (bindex = 0; !err && bindex <= bend; bindex++) { + skip = 0; + h_dir = au_h_iptr(dir, bindex); + br = au_sbr(sb, bindex); + do_free = 0; + wbr = br->br_wbr; + if (wbr) + wbr_wh_read_lock(wbr); + switch (br->br_perm) { + case AuBrPerm_RR: + case AuBrPerm_RO: + case AuBrPerm_RRWH: + case AuBrPerm_ROWH: + do_free = !!wbr; + skip = (!wbr + || (!wbr->wbr_whbase + && !wbr->wbr_plink + && !wbr->wbr_tmp)); + break; + + case AuBrPerm_RWNoLinkWH: + /* skip = (!br->br_whbase && !br->br_tmp); */ + skip = (!wbr || !wbr->wbr_whbase); + if (skip && wbr) { + if (do_plink) + skip = !!wbr->wbr_plink; + else + skip = !wbr->wbr_plink; + } + break; + + case AuBrPerm_RW: + /* skip = (br->br_whbase && br->br_tmp); */ + skip = (wbr && wbr->wbr_whbase); + if (skip) { + if (do_plink) + skip = !!wbr->wbr_plink; + else + skip = !wbr->wbr_plink; + } + break; + + default: + BUG(); + } + if (wbr) + wbr_wh_read_unlock(wbr); + + if (skip) + continue; + + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); + if (wbr) + wbr_wh_write_lock(wbr); + err = au_wh_init(au_h_dptr(root, bindex), br, + au_nfsmnt(sb, bindex), sb, bindex); + if (wbr) + wbr_wh_write_unlock(wbr); + mutex_unlock(&h_dir->i_mutex); + + if (!err && do_free) { + kfree(wbr); + br->br_wbr = NULL; + } + } + + AuTraceErr(err); + return err; +} + +int au_opts_mount(struct super_block *sb, struct au_opts *opts) +{ + int err; + struct inode *dir; + struct au_opt *opt; + struct au_opt_xino *opt_xino, xino; + struct au_opt_xinodir *opt_xinodir; + aufs_bindex_t bend; + struct au_sbinfo *sbinfo; + unsigned int tmp; + struct au_branch *br; + + AuTraceEnter(); + SiMustWriteLock(sb); + DiMustWriteLock(sb->s_root); + dir = sb->s_root->d_inode; + IiMustWriteLock(dir); + + err = 0; + opt_xino = NULL; + opt_xinodir = NULL; + opt = opts->opt; + while (err >= 0 && opt->type != Opt_tail) + err = au_opt_simple(sb, opt++, opts); + if (err > 0) + err = 0; + else if (unlikely(err < 0)) + goto out; + + /* disable xino, xinodir, hinotify, dlgt temporary */ + sbinfo = au_sbi(sb); + tmp = sbinfo->si_mntflags; + au_opt_clr(sbinfo->si_mntflags, XINO); + au_opt_clr(sbinfo->si_mntflags, XINODIR); + au_opt_clr(sbinfo->si_mntflags, DLGT); + au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL); + + opt = opts->opt; + while (err >= 0 && opt->type != Opt_tail) + err = au_opt_br(sb, opt++, opts); + if (err > 0) + err = 0; + else if (unlikely(err < 0)) + goto out; + + bend = au_sbend(sb); + if (unlikely(bend < 0)) { + err = -EINVAL; + AuErr("no branches\n"); + goto out; + } + + if (au_opt_test(tmp, XINO)) + au_opt_set(sbinfo->si_mntflags, XINO); + else if (au_opt_test(tmp, XINODIR)) + au_opt_set(sbinfo->si_mntflags, XINODIR); + opt = opts->opt; + while (!err && opt->type != Opt_tail) + err = au_opt_xino(sb, opt++, &opt_xino, &opt_xinodir, opts); + if (unlikely(err)) + goto out; + + /* todo: test this error case? */ + err = verify_opts(sb, tmp, /*remount*/0); + if (unlikely(err)) + goto out; + + /* enable xino */ + if (au_opt_test(tmp, XINO) && !opt_xino) { + xino.file = au_xino_def(sb); + err = PTR_ERR(xino.file); + if (IS_ERR(xino.file)) + goto out; + + br = au_xino_def_br(sbinfo); + err = au_xino_set(sb, &xino, /*remount*/0); + fput(xino.file); + if (unlikely(err)) + goto out; + au_xino_def_br_set(br, sbinfo); + } + + /* restore hinotify */ + sbinfo->si_mntflags &= ~AuOptMask_UDBA; + sbinfo->si_mntflags |= (tmp & AuOptMask_UDBA); + if (au_opt_test(tmp, UDBA_INOTIFY)) + au_reset_hinotify(dir, au_hi_flags(dir, 1) & ~AuHi_XINO); + + /* restore dlgt */ + if (au_opt_test(tmp, DLGT)) + au_opt_set(sbinfo->si_mntflags, DLGT); + + out: + AuTraceErr(err); + return err; +} + +int au_opts_remount(struct super_block *sb, struct au_opts *opts) +{ + int err, rerr; + struct inode *dir; + struct au_opt_xino *opt_xino; + struct au_opt_xinodir *opt_xinodir; + struct au_opt *opt; + unsigned char dlgt; + struct au_sbinfo *sbinfo; + + AuTraceEnter(); + SiMustWriteLock(sb); + DiMustWriteLock(sb->s_root); + dir = sb->s_root->d_inode; + IiMustWriteLock(dir); + sbinfo = au_sbi(sb); + + err = 0; + dlgt = !!au_opt_test(sbinfo->si_mntflags, DLGT); + opt_xino = NULL; + opt_xinodir = NULL; + opt = opts->opt; + while (err >= 0 && opt->type != Opt_tail) { + err = au_opt_simple(sb, opt, opts); + + /* disable it temporary */ + dlgt = !!au_opt_test(sbinfo->si_mntflags, DLGT); + au_opt_clr(sbinfo->si_mntflags, DLGT); + + if (!err) + err = au_opt_br(sb, opt, opts); + if (!err) + err = au_opt_xino(sb, opt, &opt_xino, &opt_xinodir, + opts); + + /* restore it */ + if (unlikely(dlgt)) + au_opt_set(sbinfo->si_mntflags, DLGT); + opt++; + } + if (err > 0) + err = 0; + AuTraceErr(err); + + /* go on even err */ + + /* todo: test this error case? */ + au_opt_clr(sbinfo->si_mntflags, DLGT); + rerr = verify_opts(sb, sbinfo->si_mntflags, /*remount*/1); + if (unlikely(dlgt)) + au_opt_set(sbinfo->si_mntflags, DLGT); + if (unlikely(rerr && !err)) + err = rerr; + + if (unlikely(au_ftest_opts(opts->flags, TRUNC_XIB))) { + rerr = au_xib_trunc(sb); + if (unlikely(rerr && !err)) + err = rerr; + } + + /* they are handled by the caller */ + if (!au_ftest_opts(opts->flags, REFRESH_DIR) + && (opts->given_udba || au_opt_test_xino(sbinfo->si_mntflags))) + au_fset_opts(opts->flags, REFRESH_DIR); + + LKTRTrace("status 0x%x\n", opts->flags); + AuTraceErr(err); + return err; +} --- linux-2.6.28.orig/ubuntu/aufs/hin_or_dlgt.c +++ linux-2.6.28/ubuntu/aufs/hin_or_dlgt.c @@ -0,0 +1,737 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * sub-routines for vfs in hinotify or dlgt mode + * + * $Id: hin_or_dlgt.c,v 1.6 2008/07/14 00:15:10 sfjro Exp $ + */ + +#include +#include "aufs.h" + +#if !defined(CONFIG_AUFS_HINOTIFY) && !defined(CONFIG_AUFS_DLGT) +#error mis-configuraion or Makefile +#endif + +/* ---------------------------------------------------------------------- */ + +struct permission_args { + int *errp; + struct inode *inode; + int mask; + struct nameidata *nd; +}; + +static void call_permission(void *args) +{ + struct permission_args *a = args; + *a->errp = do_vfsub_permission(a->inode, a->mask, a->nd); +} + +int vfsub_permission(struct inode *inode, int mask, struct nameidata *nd, + int dlgt) +{ + if (!dlgt) + return do_vfsub_permission(inode, mask, nd); + else { + int err, wkq_err; + struct permission_args args = { + .errp = &err, + .inode = inode, + .mask = mask, + .nd = nd + }; + wkq_err = au_wkq_wait(call_permission, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + return err; + } +} + +/* ---------------------------------------------------------------------- */ + +struct create_args { + int *errp; + struct inode *dir; + struct dentry *dentry; + int mode; + struct nameidata *nd; + struct vfsub_args *vargs; +}; + +static void call_create(void *args) +{ + struct create_args *a = args; + vfsub_ignore(a->vargs); + *a->errp = do_vfsub_create(a->dir, a->dentry, a->mode, a->nd); + if (unlikely(*a->errp)) + vfsub_unignore(a->vargs); + au_dbg_hin_list(a->vargs); +} + +int vfsub_create(struct inode *dir, struct dentry *dentry, int mode, + struct nameidata *nd, struct vfsub_args *vargs) +{ + int err; + struct create_args args = { + .errp = &err, + .dir = dir, + .dentry = dentry, + .mode = mode, + .nd = nd, + .vargs = vargs + }; + + if (!vfsub_ftest(vargs->flags, DLGT)) + call_create(&args); + else { + int wkq_err; + wkq_err = au_wkq_wait(call_create, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + } + return err; +} + +struct symlink_args { + int *errp; + struct inode *dir; + struct dentry *dentry; + const char *symname; + int mode; + struct vfsub_args *vargs; +}; + +static void call_symlink(void *args) +{ + struct symlink_args *a = args; + vfsub_ignore(a->vargs); + *a->errp = do_vfsub_symlink(a->dir, a->dentry, a->symname, a->mode); + if (unlikely(*a->errp)) + vfsub_unignore(a->vargs); + au_dbg_hin_list(a->vargs); +} + +int vfsub_symlink(struct inode *dir, struct dentry *dentry, const char *symname, + int mode, struct vfsub_args *vargs) +{ + int err; + struct symlink_args args = { + .errp = &err, + .dir = dir, + .dentry = dentry, + .symname = symname, + .mode = mode, + .vargs = vargs + }; + + if (!vfsub_ftest(vargs->flags, DLGT)) + call_symlink(&args); + else { + int wkq_err; + wkq_err = au_wkq_wait(call_symlink, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + } + return err; +} + +struct mknod_args { + int *errp; + struct inode *dir; + struct dentry *dentry; + int mode; + dev_t dev; + struct vfsub_args *vargs; +}; + +static void call_mknod(void *args) +{ + struct mknod_args *a = args; + vfsub_ignore(a->vargs); + *a->errp = do_vfsub_mknod(a->dir, a->dentry, a->mode, a->dev); + if (unlikely(*a->errp)) + vfsub_unignore(a->vargs); + au_dbg_hin_list(a->vargs); +} + +int vfsub_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev, + struct vfsub_args *vargs) +{ + int err; + struct mknod_args args = { + .errp = &err, + .dir = dir, + .dentry = dentry, + .mode = mode, + .dev = dev, + .vargs = vargs + }; + + if (!vfsub_ftest(vargs->flags, DLGT)) + call_mknod(&args); + else { + int wkq_err; + wkq_err = au_wkq_wait(call_mknod, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + } + return err; +} + +struct mkdir_args { + int *errp; + struct inode *dir; + struct dentry *dentry; + int mode; + struct vfsub_args *vargs; +}; + +static void call_mkdir(void *args) +{ + struct mkdir_args *a = args; + vfsub_ignore(a->vargs); + *a->errp = do_vfsub_mkdir(a->dir, a->dentry, a->mode); + if (unlikely(*a->errp)) + vfsub_unignore(a->vargs); + au_dbg_hin_list(a->vargs); +} + +int vfsub_mkdir(struct inode *dir, struct dentry *dentry, int mode, + struct vfsub_args *vargs) +{ + int err; + struct mkdir_args args = { + .errp = &err, + .dir = dir, + .dentry = dentry, + .mode = mode, + .vargs = vargs + }; + + if (!vfsub_ftest(vargs->flags, DLGT)) + call_mkdir(&args); + else { + int wkq_err; + wkq_err = au_wkq_wait(call_mkdir, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + } + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct link_args { + int *errp; + struct inode *dir; + struct dentry *src_dentry, *dentry; + struct vfsub_args *vargs; +}; + +static void call_link(void *args) +{ + struct link_args *a = args; + vfsub_ignore(a->vargs); + *a->errp = do_vfsub_link(a->src_dentry, a->dir, a->dentry); + if (unlikely(*a->errp)) + vfsub_unignore(a->vargs); + au_dbg_hin_list(a->vargs); +} + +int vfsub_link(struct dentry *src_dentry, struct inode *dir, + struct dentry *dentry, struct vfsub_args *vargs) +{ + int err; + struct link_args args = { + .errp = &err, + .src_dentry = src_dentry, + .dir = dir, + .dentry = dentry, + .vargs = vargs + }; + + if (!vfsub_ftest(vargs->flags, DLGT)) + call_link(&args); + else { + int wkq_err; + wkq_err = au_wkq_wait(call_link, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + } + return err; +} + +struct rename_args { + int *errp; + struct inode *src_dir, *dir; + struct dentry *src_dentry, *dentry; + struct vfsub_args *vargs; +}; + +static void call_rename(void *args) +{ + struct rename_args *a = args; + vfsub_ignore(a->vargs); + *a->errp = do_vfsub_rename(a->src_dir, a->src_dentry, a->dir, + a->dentry); + if (unlikely(*a->errp)) + vfsub_unignore(a->vargs); + au_dbg_hin_list(a->vargs); +} + +int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry, + struct inode *dir, struct dentry *dentry, + struct vfsub_args *vargs) +{ + int err; + struct rename_args args = { + .errp = &err, + .src_dir = src_dir, + .src_dentry = src_dentry, + .dir = dir, + .dentry = dentry, + .vargs = vargs + }; + + if (!vfsub_ftest(vargs->flags, DLGT)) + call_rename(&args); + else { + int wkq_err; + wkq_err = au_wkq_wait(call_rename, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + } + return err; +} + +struct rmdir_args { + int *errp; + struct inode *dir; + struct dentry *dentry; + struct vfsub_args *vargs; +}; + +static void call_rmdir(void *args) +{ + struct rmdir_args *a = args; + vfsub_ignore(a->vargs); + *a->errp = do_vfsub_rmdir(a->dir, a->dentry); + if (unlikely(*a->errp)) + vfsub_unignore(a->vargs); + au_dbg_hin_list(a->vargs); +} + +int vfsub_rmdir(struct inode *dir, struct dentry *dentry, + struct vfsub_args *vargs) +{ + int err; + struct rmdir_args args = { + .errp = &err, + .dir = dir, + .dentry = dentry, + .vargs = vargs + }; + + if (!vfsub_ftest(vargs->flags, DLGT)) + call_rmdir(&args); + else { + int wkq_err; + wkq_err = au_wkq_wait(call_rmdir, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + } + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct read_args { + ssize_t *errp; + struct file *file; + union { + void *kbuf; + char __user *ubuf; + }; + size_t count; + loff_t *ppos; +}; + +static void call_read_k(void *args) +{ + struct read_args *a = args; + LKTRTrace("%.*s, cnt %lu, pos %lld\n", + AuDLNPair(a->file->f_dentry), (unsigned long)a->count, + *a->ppos); + *a->errp = do_vfsub_read_k(a->file, a->kbuf, a->count, a->ppos); +} + +ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count, + loff_t *ppos, int dlgt) +{ + if (!dlgt) + return do_vfsub_read_u(file, ubuf, count, ppos); + else { + int wkq_err; + ssize_t err, read; + struct read_args args = { + .errp = &err, + .file = file, + .count = count, + .ppos = ppos + }; + + if (unlikely(!count)) + return 0; + + /* + * workaround an application bug. + * generally, read(2) or write(2) may return the value shorter + * than requested. But many applications don't support it, + * for example bash. + */ + err = -ENOMEM; + if (args.count > PAGE_SIZE) + args.count = PAGE_SIZE; + args.kbuf = kmalloc(args.count, GFP_NOFS); + if (unlikely(!args.kbuf)) + goto out; + + read = 0; + do { + wkq_err = au_wkq_wait(call_read_k, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + if (unlikely(err > 0 + && copy_to_user(ubuf, args.kbuf, err))) { + err = -EFAULT; + goto out_free; + } else if (!err) + break; + else if (unlikely(err < 0)) + goto out_free; + count -= err; + /* do not read too much because of file i/o pointer */ + if (count < args.count) + args.count = count; + ubuf += err; + read += err; + } while (count); + smp_mb(); /* flush ubuf */ + err = read; + + out_free: + kfree(args.kbuf); + out: + return err; + } +} + +ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count, loff_t *ppos, + int dlgt) +{ + if (!dlgt) + return do_vfsub_read_k(file, kbuf, count, ppos); + else { + ssize_t err; + int wkq_err; + struct read_args args = { + .errp = &err, + .file = file, + .count = count, + .ppos = ppos + }; + args.kbuf = kbuf; + wkq_err = au_wkq_wait(call_read_k, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + return err; + } +} + +struct write_args { + ssize_t *errp; + struct file *file; + union { + void *kbuf; + const char __user *ubuf; + }; + size_t count; + loff_t *ppos; + struct vfsub_args *vargs; +}; + +static void call_write_k(void *args) +{ + struct write_args *a = args; + vfsub_ignore(a->vargs); + *a->errp = do_vfsub_write_k(a->file, a->kbuf, a->count, a->ppos); + if (unlikely(*a->errp <= 0)) + vfsub_unignore(a->vargs); + au_dbg_hin_list(a->vargs); +} + +ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count, + loff_t *ppos, struct vfsub_args *vargs) +{ + ssize_t err; + + if (!vfsub_ftest(vargs->flags, DLGT)) { + vfsub_ignore(vargs); + err = do_vfsub_write_u(file, ubuf, count, ppos); + if (unlikely(err <= 0)) + vfsub_unignore(vargs); + au_dbg_hin_list(vargs); + } else { + ssize_t written; + int wkq_err; + struct write_args args = { + .errp = &err, + .file = file, + .count = count, + .ppos = ppos, + .vargs = vargs + }; + + if (unlikely(!count)) + return 0; + + /* + * workaround an application bug. + * generally, read(2) or write(2) may return the value shorter + * than requested. But many applications don't support it, + * for example bash. + */ + err = -ENOMEM; + if (args.count > PAGE_SIZE) + args.count = PAGE_SIZE; + args.kbuf = kmalloc(args.count, GFP_NOFS); + if (unlikely(!args.kbuf)) + goto out; + + written = 0; + do { + if (unlikely(copy_from_user(args.kbuf, ubuf, + args.count))) { + err = -EFAULT; + goto out_free; + } + + wkq_err = au_wkq_wait(call_write_k, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + if (err > 0) { + count -= err; + if (count < args.count) + args.count = count; + ubuf += err; + written += err; + } else if (!err) + break; + else if (unlikely(err < 0)) + goto out_free; + } while (count); + err = written; + + out_free: + kfree(args.kbuf); + } + out: + return err; +} + +ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos, + struct vfsub_args *vargs) +{ + ssize_t err; + struct write_args args = { + .errp = &err, + .file = file, + .count = count, + .ppos = ppos, + .vargs = vargs + }; + + args.kbuf = kbuf; + if (!vfsub_ftest(vargs->flags, DLGT)) + call_write_k(&args); + else { + int wkq_err; + wkq_err = au_wkq_wait(call_write_k, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + } + return err; +} + +struct readdir_args { + int *errp; + struct file *file; + filldir_t filldir; + void *arg; +}; + +static void call_readdir(void *args) +{ + struct readdir_args *a = args; + *a->errp = do_vfsub_readdir(a->file, a->filldir, a->arg); +} + +int vfsub_readdir(struct file *file, filldir_t filldir, void *arg, int dlgt) +{ + if (!dlgt) + return do_vfsub_readdir(file, filldir, arg); + else { + int err, wkq_err; + struct readdir_args args = { + .errp = &err, + .file = file, + .filldir = filldir, + .arg = arg + }; + wkq_err = au_wkq_wait(call_readdir, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + return err; + } +} + +/* ---------------------------------------------------------------------- */ + +struct splice_to_args { + long *errp; + struct file *in; + loff_t *ppos; + struct pipe_inode_info *pipe; + size_t len; + unsigned int flags; +}; + +static void call_splice_to(void *args) +{ + struct splice_to_args *a = args; + *a->errp = do_vfsub_splice_to(a->in, a->ppos, a->pipe, a->len, + a->flags); +} + +long vfsub_splice_to(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags, int dlgt) +{ + if (!dlgt) + return do_vfsub_splice_to(in, ppos, pipe, len, flags); + else { + long err; + int wkq_err; + struct splice_to_args args = { + .errp = &err, + .in = in, + .ppos = ppos, + .pipe = pipe, + .len = len, + .flags = flags + }; + wkq_err = au_wkq_wait(call_splice_to, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + return err; + } +} + +struct splice_from_args { + long *errp; + struct pipe_inode_info *pipe; + struct file *out; + loff_t *ppos; + size_t len; + unsigned int flags; + struct vfsub_args *vargs; +}; + +static void call_splice_from(void *args) +{ + struct splice_from_args *a = args; + vfsub_ignore(a->vargs); + *a->errp = do_vfsub_splice_from(a->pipe, a->out, a->ppos, a->len, + a->flags); + if (unlikely(*a->errp < 0)) + vfsub_unignore(a->vargs); + au_dbg_hin_list(a->vargs); +} + +long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags, + struct vfsub_args *vargs) +{ + long err; + struct splice_from_args args = { + .errp = &err, + .pipe = pipe, + .out = out, + .ppos = ppos, + .len = len, + .flags = flags, + .vargs = vargs + }; + + if (!vfsub_ftest(vargs->flags, DLGT)) + call_splice_from(&args); + else { + int wkq_err; + wkq_err = au_wkq_wait(call_splice_from, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + } + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct getattr_args { + int *errp; + struct vfsmount *mnt; + struct dentry *dentry; + struct kstat *st; +}; + +static void call_getattr(void *args) +{ + struct getattr_args *a = args; + *a->errp = do_vfsub_getattr(a->mnt, a->dentry, a->st); +} + +int vfsub_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *st, + int dlgt) +{ + if (!dlgt) + return do_vfsub_getattr(mnt, dentry, st); + else { + int err, wkq_err; + struct getattr_args args = { + .errp = &err, + .mnt = mnt, + .dentry = dentry, + .st = st + }; + wkq_err = au_wkq_wait(call_getattr, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + return err; + } +} --- linux-2.6.28.orig/ubuntu/aufs/i_op_add.c +++ linux-2.6.28/ubuntu/aufs/i_op_add.c @@ -0,0 +1,754 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * inode operations (add entry) + * + * $Id: i_op_add.c,v 1.14 2008/09/22 03:52:19 sfjro Exp $ + */ + +#include "aufs.h" + +/* + * final procedure of adding a new entry, except link(2). + * remove whiteout, instantiate, copyup the parent dir's times and size + * and update version. + * if it failed, re-create the removed whiteout. + */ +static int epilog(struct inode *dir, aufs_bindex_t bindex, + struct dentry *wh_dentry, struct dentry *dentry) +{ + int err, rerr; + aufs_bindex_t bwh; + struct inode *inode, *h_dir; + struct dentry *wh; + struct au_ndx ndx; + struct super_block *sb; + + LKTRTrace("wh %p, %.*s\n", wh_dentry, AuDLNPair(dentry)); + + sb = dentry->d_sb; + bwh = -1; + if (wh_dentry) { + h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */ + IMustLock(h_dir); + AuDebugOn(au_h_iptr(dir, bindex) != h_dir); + bwh = au_dbwh(dentry); + err = au_wh_unlink_dentry(au_hi(dir, bindex), wh_dentry, dentry, + /*dlgt*/0); + if (unlikely(err)) + goto out; + } + + inode = au_new_inode(dentry); + if (!IS_ERR(inode)) { + d_instantiate(dentry, inode); + dir = dentry->d_parent->d_inode; /* dir inode is locked */ + IMustLock(dir); + /* or always cpup dir mtime? */ + if (au_ibstart(dir) == au_dbstart(dentry)) + au_cpup_attr_timesizes(dir); + dir->i_version++; + return 0; /* success */ + } + + err = PTR_ERR(inode); + if (!wh_dentry) + goto out; + + /* revert */ + ndx.flags = 0; + if (unlikely(au_test_dlgt(au_mntflags(sb)))) + au_fset_ndx(ndx.flags, DLGT); + ndx.nfsmnt = au_nfsmnt(sb, bwh); + ndx.nd = NULL; + /* ndx.br = NULL; */ + /* dir inode is locked */ + wh = au_wh_create(dentry, bwh, wh_dentry->d_parent, &ndx); + rerr = PTR_ERR(wh); + if (IS_ERR(wh)) { + AuIOErr("%.*s reverting whiteout failed(%d, %d)\n", + AuDLNPair(dentry), err, rerr); + err = -EIO; + } else { + err = 0; + dput(wh); + } + + out: + AuTraceErr(err); + return err; +} + +/* + * simple tests for the adding inode operations. + * following the checks in vfs, plus the parent-child relationship. + */ +int au_may_add(struct dentry *dentry, aufs_bindex_t bindex, + struct dentry *h_parent, int isdir, struct au_ndx *ndx) +{ + int err, exist; + struct dentry *h_dentry; + struct inode *h_inode; + umode_t h_mode; + + LKTRTrace("%.*s/%.*s, b%d, dir %d\n", + AuDLNPair(h_parent), AuDLNPair(dentry), bindex, isdir); + + exist = !!dentry->d_inode; + h_dentry = au_h_dptr(dentry, bindex); + h_inode = h_dentry->d_inode; + if (!exist) { + err = -EEXIST; + if (unlikely(h_inode)) + goto out; + } else { + /* rename(2) case */ + err = -EIO; + if (unlikely(!h_inode || !h_inode->i_nlink)) + goto out; + + h_mode = h_inode->i_mode; + if (!isdir) { + err = -EISDIR; + if (unlikely(S_ISDIR(h_mode))) + goto out; + } else if (unlikely(!S_ISDIR(h_mode))) { + err = -ENOTDIR; + goto out; + } + } + + err = -EIO; + /* expected parent dir is locked */ + if (unlikely(h_parent != h_dentry->d_parent)) + goto out; + err = 0; + + if (unlikely(au_opt_test(au_mntflags(dentry->d_sb), UDBA_INOTIFY))) { + struct dentry *h_latest; + struct qstr *qstr = &dentry->d_name; + + err = -EACCES; + if (unlikely(au_test_h_perm + (h_parent->d_inode, MAY_EXEC | MAY_WRITE, + au_ftest_ndx(ndx->flags, DLGT)))) + goto out; + + err = -EIO; + h_latest = au_sio_lkup_one(qstr->name, h_parent, qstr->len, + ndx); + err = PTR_ERR(h_latest); + if (IS_ERR(h_latest)) + goto out; + err = -EIO; + dput(h_latest); + if (h_latest == h_dentry) + err = 0; + } + + out: + AuTraceErr(err); + return err; +} + +/* + * initial procedure of adding a new entry. + * prepare writable branch and the parent dir, lock it, + * lookup whiteout for the new entry. + */ +static struct dentry* +lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt, + struct dentry *src_dentry, struct au_pin *pin, + struct au_wr_dir_args *wr_dir_args) +{ + struct dentry *wh_dentry, *h_parent; + int err; + aufs_bindex_t bstart, bcpup; + struct au_ndx ndx; + struct super_block *sb; + unsigned int mnt_flags; + + LKTRTrace("%.*s, src %p\n", AuDLNPair(dentry), src_dentry); + + bstart = au_dbstart(dentry); + err = au_wr_dir(dentry, src_dentry, wr_dir_args); + bcpup = err; + wh_dentry = ERR_PTR(err); + if (unlikely(err < 0)) + goto out; + + sb = dentry->d_sb; + mnt_flags = au_mntflags(sb); + err = au_pin(pin, dentry, bcpup, /*di_locked*/1, + /*do_gp*/dt && au_opt_test(mnt_flags, UDBA_INOTIFY)); + wh_dentry = ERR_PTR(err); + if (unlikely(err)) + goto out; + + ndx.nfsmnt = au_nfsmnt(sb, bcpup); + ndx.flags = 0; + if (unlikely(au_test_dlgt(mnt_flags))) + au_fset_ndx(ndx.flags, DLGT); + ndx.nd = NULL; + /* ndx.br = NULL; */ + /* ndx.nd_file = NULL; */ + + h_parent = au_pinned_h_parent(pin, bcpup); + if (!au_opt_test(mnt_flags, UDBA_NONE) && au_dbstart(dentry) == bcpup) { + struct nameidata nd; + + if (unlikely(ndx.nfsmnt)) { + /* todo: dirty? */ + ndx.nd = &nd; + ndx.br = au_sbr(sb, bcpup); + memset(&nd, 0, sizeof(nd)); + nd.flags = LOOKUP_CREATE; + nd.intent.open.flags = O_EXCL; + } + err = au_may_add(dentry, bcpup, h_parent, + au_ftest_wrdir(wr_dir_args->flags, ISDIR), + &ndx); + wh_dentry = ERR_PTR(err); + if (unlikely(err)) + goto out_unpin; + ndx.nd = NULL; + ndx.br = NULL; + } + + if (dt) + au_dtime_store(dt, au_pinned_parent(pin), h_parent, + au_pinned_hdir(pin, bcpup), + au_pinned_hgdir(pin, bcpup)); + + wh_dentry = NULL; + if (/* bcpup != bstart || */ bcpup != au_dbwh(dentry)) + goto out; /* success */ + + wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, &ndx); + + out_unpin: + if (IS_ERR(wh_dentry)) + au_unpin(pin); + out: + AuTraceErrPtr(wh_dentry); + return wh_dentry; +} + +/* ---------------------------------------------------------------------- */ + +enum { Mknod, Symlink, Creat }; +struct simple_arg { + int type; + union { + struct { + int mode; + struct nameidata *nd; + } c; + struct { + const char *symname; + } s; + struct { + int mode; + dev_t dev; + } m; + } u; +}; + +static int add_simple(struct inode *dir, struct dentry *dentry, + struct simple_arg *arg) +{ + int err; + struct dentry *h_dentry, *wh_dentry, *parent; + struct inode *h_dir; + struct au_dtime dt; + struct vfsub_args vargs; + struct super_block *sb; + aufs_bindex_t bstart; + unsigned char created; + struct au_hin_ignore ign; + struct au_pin pin; + struct au_wr_dir_args wr_dir_args = { + .force_btgt = -1, + .flags = AuWrDir_ADD_ENTRY + }; + + LKTRTrace("type %d, %.*s\n", arg->type, AuDLNPair(dentry)); + IMustLock(dir); + + sb = dir->i_sb; + parent = dentry->d_parent; /* dir inode is locked */ + aufs_read_lock(dentry, AuLock_DW); + vfsub_args_init(&vargs, &ign, !!au_test_dlgt(au_mntflags(sb)), 0); + di_write_lock_parent(parent); + wh_dentry = lock_hdir_lkup_wh(dentry, &dt, /*src_dentry*/NULL, &pin, + &wr_dir_args); + err = PTR_ERR(wh_dentry); + if (IS_ERR(wh_dentry)) + goto out; + + bstart = au_dbstart(dentry); + h_dentry = au_h_dptr(dentry, bstart); + h_dir = au_pinned_h_dir(&pin); + vfsub_ign_hinode(&vargs, IN_CREATE, au_pinned_hdir(&pin, bstart)); + + switch (arg->type) { + case Creat: + AuDebugOn(au_test_nfs(h_dir->i_sb) && !arg->u.c.nd); + err = au_h_create(h_dir, h_dentry, arg->u.c.mode, &vargs, + arg->u.c.nd, au_nfsmnt(sb, bstart)); + break; + case Symlink: + err = vfsub_symlink(h_dir, h_dentry, arg->u.s.symname, + S_IALLUGO, &vargs); + break; + case Mknod: + err = vfsub_mknod(h_dir, h_dentry, arg->u.m.mode, arg->u.m.dev, + &vargs); + break; + default: + BUG(); + } + created = !err; + if (!err) + err = epilog(dir, bstart, wh_dentry, dentry); + + /* revert */ + if (unlikely(created && err && h_dentry->d_inode)) { + int rerr; + vfsub_args_reinit(&vargs); + vfsub_ign_hinode(&vargs, IN_DELETE, + au_pinned_hdir(&pin, bstart)); + rerr = vfsub_unlink(h_dir, h_dentry, &vargs); + if (rerr) { + AuIOErr("%.*s revert failure(%d, %d)\n", + AuDLNPair(dentry), err, rerr); + err = -EIO; + } + /* todo: inotify will be fired to the grand parent dir? */ + au_dtime_revert(&dt); + d_drop(dentry); + } + + au_unpin(&pin); + dput(wh_dentry); + + out: + if (unlikely(err)) { + au_update_dbstart(dentry); + d_drop(dentry); + } + di_write_unlock(parent); + aufs_read_unlock(dentry, AuLock_DW); + AuTraceErr(err); + return err; +} + +int aufs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) +{ + struct simple_arg arg = { + .type = Mknod, + .u.m = { + .mode = mode, + .dev = dev + } + }; + return add_simple(dir, dentry, &arg); +} + +int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) +{ + struct simple_arg arg = { + .type = Symlink, + .u.s.symname = symname + }; + return add_simple(dir, dentry, &arg); +} + +int aufs_create(struct inode *dir, struct dentry *dentry, int mode, + struct nameidata *nd) +{ + struct simple_arg arg = { + .type = Creat, + .u.c = { + .mode = mode, + .nd = nd + } + }; + return add_simple(dir, dentry, &arg); +} + +/* ---------------------------------------------------------------------- */ + +struct au_link_args { + aufs_bindex_t bdst, bsrc; + struct dentry *h_dentry; + struct dentry *src_parent, *parent; + struct au_pin pin; + struct au_hin_ignore ign; + struct vfsub_args vargs; + unsigned int mnt_flags; +}; + +static int au_cpup_before_link(struct dentry *src_dentry, struct inode *dir, + struct dentry *dentry, struct au_link_args *a) +{ + int err; + struct mutex *h_mtx; + const int hinotify = au_opt_test(a->mnt_flags, UDBA_INOTIFY); + + LKTRTrace("src %.*s, i%lu, dst %.*s\n", + AuDLNPair(src_dentry), dir->i_ino, AuDLNPair(dentry)); + + di_read_lock_parent(a->src_parent, AuLock_IR); + err = au_test_and_cpup_dirs(src_dentry, a->bdst); + if (unlikely(err)) + goto out; + + AuDebugOn(au_dbstart(src_dentry) != a->bsrc); + h_mtx = &au_h_dptr(src_dentry, a->bsrc)->d_inode->i_mutex; + err = au_pin(&a->pin, src_dentry, a->bdst, /*di_locked*/1, + /*do_gp*/hinotify); + if (unlikely(err)) + goto out; + mutex_lock_nested(h_mtx, AuLsc_I_CHILD); + /* todo: no KEEPLINO because of noplink? */ + err = au_sio_cpup_simple(src_dentry, a->bdst, -1, + AuCpup_DTIME /* | AuCpup_KEEPLINO */); + mutex_unlock(h_mtx); + au_unpin(&a->pin); + + out: + di_read_unlock(a->src_parent, AuLock_IR); + AuTraceErr(err); + return err; +} + +static int au_cpup_or_link(struct dentry *src_dentry, struct au_link_args *a) +{ + int err; + struct inode *h_inode; + aufs_bindex_t bstart; + struct dentry *h_src_dentry; + + AuTraceEnter(); + AuDebugOn(au_dbstart(src_dentry) != a->bsrc); + + bstart = au_ibstart(src_dentry->d_inode); + h_inode = NULL; + if (bstart <= a->bdst) + h_inode = au_h_iptr(src_dentry->d_inode, a->bdst); + if (!h_inode || !h_inode->i_nlink) { + /* copyup src_dentry as the name of dentry. */ + au_set_dbstart(src_dentry, a->bdst); + au_set_h_dptr(src_dentry, a->bdst, dget(a->h_dentry)); + h_inode = au_h_dptr(src_dentry, a->bsrc)->d_inode; + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); + err = au_sio_cpup_single(src_dentry, a->bdst, a->bsrc, -1, + AuCpup_KEEPLINO, a->parent); + mutex_unlock(&h_inode->i_mutex); + au_set_h_dptr(src_dentry, a->bdst, NULL); + au_set_dbstart(src_dentry, a->bsrc); + } else { + /* the inode of src_dentry already exists on a.bdst branch */ + h_src_dentry = d_find_alias(h_inode); + if (h_src_dentry) { + /* vfsub_args_reinit(&a->vargs); */ + vfsub_ign_hinode(&a->vargs, IN_CREATE, + au_pinned_hdir(&a->pin, a->bdst)); + err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin), + a->h_dentry, &a->vargs); + dput(h_src_dentry); + } else { + AuIOErr("no dentry found for i%lu on b%d\n", + h_inode->i_ino, a->bdst); + err = -EIO; + } + } + + if (!err) + au_plink_append(src_dentry->d_sb, src_dentry->d_inode, + a->h_dentry, a->bdst); + + AuTraceErr(err); + return err; +} + +int aufs_link(struct dentry *src_dentry, struct inode *dir, + struct dentry *dentry) +{ + int err, rerr; + struct dentry *wh_dentry, *h_src_dentry; + struct inode *inode; + struct au_dtime dt; + struct super_block *sb; + struct au_link_args *a; + struct au_wr_dir_args wr_dir_args = { + /* .force_btgt = -1, */ + .flags = AuWrDir_ADD_ENTRY + }; + + LKTRTrace("src %.*s, i%lu, dst %.*s\n", + AuDLNPair(src_dentry), dir->i_ino, AuDLNPair(dentry)); + IMustLock(dir); + inode = src_dentry->d_inode; + IMustLock(inode); + AuDebugOn(S_ISDIR(inode->i_mode)); + + err = -ENOMEM; + a = kzalloc(sizeof(*a), GFP_NOFS); + if (unlikely(!a)) + goto out; + + sb = dentry->d_sb; + a->parent = dentry->d_parent; /* dir inode is locked */ + aufs_read_and_write_lock2(dentry, src_dentry, /*AuLock_FLUSH*/0); + a->src_parent = dget_parent(src_dentry); + wr_dir_args.force_btgt = au_dbstart(src_dentry); + a->mnt_flags = au_mntflags(sb); + vfsub_args_init(&a->vargs, &a->ign, au_test_dlgt(a->mnt_flags), 0); + + di_write_lock_parent(a->parent); + wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt); + wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin, + &wr_dir_args); + err = PTR_ERR(wh_dentry); + if (IS_ERR(wh_dentry)) + goto out_unlock; + err = 0; + + a->bdst = au_dbstart(dentry); + a->h_dentry = au_h_dptr(dentry, a->bdst); + + /* todo: minor optimize, + their sb may be same while their bindex differs? */ + a->bsrc = au_dbstart(src_dentry); + if (au_opt_test(a->mnt_flags, PLINK)) { + if (a->bdst < a->bsrc + /* && h_src_dentry->d_sb != a->h_dentry->d_sb */) + err = au_cpup_or_link(src_dentry, a); + else { + h_src_dentry = au_h_dptr(src_dentry, a->bdst); + AuDebugOn(!h_src_dentry); + AuDebugOn(!h_src_dentry->d_inode); + vfsub_ign_hinode(&a->vargs, IN_CREATE, + au_pinned_hdir(&a->pin, a->bdst)); + err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin), + a->h_dentry, &a->vargs); + } + } else { + /* + * copyup src_dentry to the branch we process, + * and then link(2) to it. + */ + if (a->bdst < a->bsrc + /* && h_src_dentry->d_sb != a->h_dentry->d_sb */) { + au_unpin(&a->pin); + di_write_unlock(a->parent); + err = au_cpup_before_link(src_dentry, dir, dentry, a); + if (!err) { + di_write_lock_parent(a->parent); + err = au_pin + (&a->pin, dentry, a->bdst, + /*di_locked*/1, + /*do_gp*/au_opt_test(a->mnt_flags, + UDBA_INOTIFY)); + if (unlikely(err)) + goto out_wh; + } + } + if (!err) { + /* vfsub_args_reinit(&a->vargs); */ + vfsub_ign_hinode(&a->vargs, IN_CREATE, + au_pinned_hdir(&a->pin, a->bdst)); + h_src_dentry = au_h_dptr(src_dentry, a->bdst); + err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin), + a->h_dentry, &a->vargs); + } + } + if (unlikely(err)) + goto out_unpin; + + if (wh_dentry) { + err = au_wh_unlink_dentry(au_pinned_hdir(&a->pin, a->bdst), + wh_dentry, dentry, /*dlgt*/0); + if (unlikely(err)) + goto out_revert; + } + +#if 0 /* cannot support it */ + /* fuse has different memory inode for the same inode number */ + if (unlikely(au_test_fuse(a->h_dentry->d_sb))) { + LKTRLabel(here); + d_drop(a->h_dentry); + /*d_drop(h_src_dentry); + d_drop(src_dentry);*/ + inc_nlink(a->inode); + a->inode->i_ctime = dir->i_ctime; + } +#endif + + dir->i_version++; + if (au_ibstart(dir) == au_dbstart(dentry)) + au_cpup_attr_timesizes(dir); + if (!d_unhashed(a->h_dentry) + /* || h_old_inode->i_nlink <= nlink */ + /* || SB_NFS(h_src_dentry->d_sb) */) { + d_instantiate(dentry, au_igrab(inode)); + inc_nlink(inode); + inode->i_ctime = dir->i_ctime; + } else + /* nfs case (< 2.6.15) */ + d_drop(dentry); + goto out_unpin; /* success */ + + out_revert: + vfsub_args_reinit(&a->vargs); + vfsub_ign_hinode(&a->vargs, IN_DELETE, au_pinned_hdir(&a->pin, a->bdst)); + rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), a->h_dentry, &a->vargs); + if (!rerr) + goto out_dt; + AuIOErr("%.*s reverting failed(%d, %d)\n", + AuDLNPair(dentry), err, rerr); + err = -EIO; + out_dt: + d_drop(dentry); + au_dtime_revert(&dt); + out_unpin: + au_unpin(&a->pin); + out_wh: + dput(wh_dentry); + out_unlock: + if (unlikely(err)) { + au_update_dbstart(dentry); + d_drop(dentry); + } + di_write_unlock(a->parent); + dput(a->src_parent); + aufs_read_and_write_unlock2(dentry, src_dentry); + kfree(a); + out: + AuTraceErr(err); + return err; +} + +int aufs_mkdir(struct inode *dir, struct dentry *dentry, int mode) +{ + int err, rerr; + struct dentry *h_dentry, *wh_dentry, *parent, *opq_dentry; + struct mutex *h_mtx; + struct au_dtime dt; + aufs_bindex_t bindex; + unsigned char diropq, dlgt; + unsigned int mnt_flags; + struct au_hin_ignore ign; + struct vfsub_args vargs; + struct au_pin pin; + struct au_wr_dir_args wr_dir_args = { + .force_btgt = -1, + .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR + }; + + LKTRTrace("i%lu, %.*s, mode 0%o\n", + dir->i_ino, AuDLNPair(dentry), mode); + IMustLock(dir); +#if 0 + if (IS_DEADDIR(dir)) { + AuDbg("here\n"); + return -ENOENT; + } +#endif + + aufs_read_lock(dentry, AuLock_DW); + parent = dentry->d_parent; /* dir inode is locked */ + mnt_flags = au_mntflags(dentry->d_sb); + dlgt = !!au_test_dlgt(mnt_flags); + vfsub_args_init(&vargs, &ign, dlgt, 0); + + di_write_lock_parent(parent); + wh_dentry = lock_hdir_lkup_wh(dentry, &dt, /*src_dentry*/NULL, &pin, + &wr_dir_args); + err = PTR_ERR(wh_dentry); + if (IS_ERR(wh_dentry)) + goto out; + + bindex = au_dbstart(dentry); + h_dentry = au_h_dptr(dentry, bindex); + vfsub_ign_hinode(&vargs, IN_CREATE, au_pinned_hdir(&pin, bindex)); + err = vfsub_mkdir(au_pinned_h_dir(&pin), h_dentry, mode, &vargs); + if (unlikely(err)) + goto out_unlock; + + /* make the dir opaque */ + diropq = 0; + h_mtx = &h_dentry->d_inode->i_mutex; + if (wh_dentry || au_opt_test(mnt_flags, ALWAYS_DIROPQ)) { + mutex_lock_nested(h_mtx, AuLsc_I_CHILD); + opq_dentry = au_diropq_create(dentry, bindex, /*dlgt*/0); + mutex_unlock(h_mtx); + err = PTR_ERR(opq_dentry); + if (IS_ERR(opq_dentry)) + goto out_dir; + dput(opq_dentry); + diropq = 1; + } + + err = epilog(dir, bindex, wh_dentry, dentry); + if (!err) { + inc_nlink(dir); + goto out_unlock; /* success */ + } + + /* revert */ + if (diropq) { + LKTRLabel(revert opq); + mutex_lock_nested(h_mtx, AuLsc_I_CHILD); + rerr = au_diropq_remove(dentry, bindex, dlgt); + mutex_unlock(h_mtx); + if (rerr) { + AuIOErr("%.*s reverting diropq failed(%d, %d)\n", + AuDLNPair(dentry), err, rerr); + err = -EIO; + } + } + + out_dir: + LKTRLabel(revert dir); + vfsub_args_reinit(&vargs); + vfsub_ign_hinode(&vargs, IN_DELETE, au_pinned_hdir(&pin, bindex)); + rerr = vfsub_rmdir(au_pinned_h_dir(&pin), h_dentry, &vargs); + if (rerr) { + AuIOErr("%.*s reverting dir failed(%d, %d)\n", + AuDLNPair(dentry), err, rerr); + err = -EIO; + } + d_drop(dentry); + au_dtime_revert(&dt); + out_unlock: + au_unpin(&pin); + dput(wh_dentry); + out: + if (unlikely(err)) { + au_update_dbstart(dentry); + d_drop(dentry); + } + di_write_unlock(parent); + aufs_read_unlock(dentry, AuLock_DW); + AuTraceErr(err); + return err; +} --- linux-2.6.28.orig/ubuntu/aufs/i_op_del.c +++ linux-2.6.28/ubuntu/aufs/i_op_del.c @@ -0,0 +1,575 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * inode operations (del entry) + * + * $Id: i_op_del.c,v 1.12 2008/09/22 03:52:19 sfjro Exp $ + */ + +#include "aufs.h" + +/* returns, + * 0: wh is unnecessary + * plus: wh is necessary + * minus: error + */ +int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup) +{ + int need_wh, err; + aufs_bindex_t bstart; + struct dentry *h_dentry; + struct super_block *sb; + + LKTRTrace("%.*s, isdir %d, *bcpup %d\n", + AuDLNPair(dentry), isdir, *bcpup); + sb = dentry->d_sb; + + bstart = au_dbstart(dentry); + LKTRTrace("bcpup %d, bstart %d\n", *bcpup, bstart); + h_dentry = au_h_dptr(dentry, bstart); + if (*bcpup < 0) { + *bcpup = bstart; + if (au_test_ro(sb, bstart, dentry->d_inode)) { + err = AuWbrCopyup(au_sbi(sb), dentry); + *bcpup = err; + if (unlikely(err < 0)) + goto out; + } + } else + AuDebugOn(bstart < *bcpup + || au_test_ro(sb, *bcpup, dentry->d_inode)); + LKTRTrace("bcpup %d, bstart %d\n", *bcpup, bstart); + + if (*bcpup != bstart) { + err = au_cpup_dirs(dentry, *bcpup); + if (unlikely(err)) + goto out; + need_wh = 1; + } else { + aufs_bindex_t old_bend, new_bend, bdiropq = -1; + old_bend = au_dbend(dentry); + if (isdir) { + bdiropq = au_dbdiropq(dentry); + au_set_dbdiropq(dentry, -1); + } + need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0, + /*nd*/NULL); + err = need_wh; + if (isdir) + au_set_dbdiropq(dentry, bdiropq); + if (unlikely(err < 0)) + goto out; + new_bend = au_dbend(dentry); + if (!need_wh && old_bend != new_bend) { + au_set_h_dptr(dentry, new_bend, NULL); + au_set_dbend(dentry, old_bend); +#if 0 /* todo: remove this? */ + } else if (!au_h_dptr(dentry, new_bend)->d_inode) { + LKTRTrace("negative\n"); + au_set_h_dptr(dentry, new_bend, NULL); + au_set_dbend(dentry, old_bend); + need_wh = 0; +#endif + } + } + LKTRTrace("need_wh %d\n", need_wh); + err = need_wh; + + out: + AuTraceErr(err); + return err; +} + +/* + * simple tests for the removal inode operations. + * following the checks in vfs, plus the parent-child relationship. + */ +int au_may_del(struct dentry *dentry, aufs_bindex_t bindex, + struct dentry *h_parent, int isdir, struct au_ndx *ndx) +{ + int err, exist; + struct super_block *sb; + struct dentry *h_dentry; + struct inode *h_inode; + umode_t h_mode; + + LKTRTrace("%.*s/%.*s, b%d, dir %d\n", + AuDLNPair(h_parent), AuDLNPair(dentry), bindex, isdir); + + sb = dentry->d_sb; + exist = !!dentry->d_inode; + h_dentry = au_h_dptr(dentry, bindex); + h_inode = h_dentry->d_inode; + if (exist) { + err = -ENOENT; + if (unlikely(!h_inode || !h_inode->i_nlink)) + goto out; + + h_mode = h_inode->i_mode; + if (!isdir) { + err = -EISDIR; + if (unlikely(S_ISDIR(h_mode))) + goto out; + } else if (unlikely(!S_ISDIR(h_mode))) { + err = -ENOTDIR; + goto out; + } + } else { + /* rename(2) case */ + err = -EIO; + if (unlikely(h_inode)) + goto out; + } + + err = -ENOENT; + /* expected parent dir is locked */ + if (unlikely(h_parent != h_dentry->d_parent)) + goto out; + err = 0; + + /* + * some filesystem may unlink a dir and corrupt its consistency. + * so let's try heavy test. + */ + if (1 /*unlikely(au_opt_test(au_mntflags(sb), UDBA_INOTIFY))*/) { + struct dentry *h_latest; + struct qstr *qstr = &dentry->d_name; + + err = -EACCES; + if (unlikely(au_test_h_perm(h_parent->d_inode, + MAY_EXEC | MAY_WRITE, + au_ftest_ndx(ndx->flags, DLGT)))) + goto out; + + h_latest = au_sio_lkup_one(qstr->name, h_parent, qstr->len, + ndx); + err = -EIO; + if (IS_ERR(h_latest)) + goto out; + dput(h_latest); + if (h_latest == h_dentry) + err = 0; + } + + out: + AuTraceErr(err); + return err; +} + +static struct dentry * +lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup, + struct au_dtime *dt, struct au_pin *pin) +{ + struct dentry *wh_dentry; + int err, need_wh; + struct dentry *h_parent; + struct au_ndx ndx; + struct super_block *sb; + aufs_bindex_t bcpup; + unsigned int mnt_flags; + + LKTRTrace("%.*s, isdir %d\n", AuDLNPair(dentry), isdir); + + need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup); + err = need_wh; + wh_dentry = ERR_PTR(err); + if (unlikely(err < 0)) + goto out; + + sb = dentry->d_sb; + mnt_flags = au_mntflags(sb); + bcpup = *rbcpup; + err = au_pin(pin, dentry, bcpup, /*di_locked*/1, + /*do_gp*/au_opt_test(mnt_flags, UDBA_INOTIFY)); + wh_dentry = ERR_PTR(err); + if (unlikely(err)) + goto out; + h_parent = au_pinned_h_parent(pin, bcpup); + if (!au_opt_test(mnt_flags, UDBA_NONE) && au_dbstart(dentry) == bcpup) { + ndx.nfsmnt = au_nfsmnt(sb, bcpup); + ndx.flags = 0; + if (unlikely(au_test_dlgt(mnt_flags))) + au_fset_ndx(ndx.flags, DLGT); + ndx.nd = NULL; + /* ndx.br = au_sbr(sb, bcpup); */ + /* ndx.nd_file = NULL; */ + err = au_may_del(dentry, bcpup, h_parent, isdir, &ndx); + wh_dentry = ERR_PTR(err); + if (unlikely(err)) + goto out_unpin; + } + + au_dtime_store(dt, au_pinned_parent(pin), h_parent, + au_pinned_hdir(pin, bcpup), au_pinned_hgdir(pin, bcpup)); + wh_dentry = NULL; + if (!need_wh) + goto out; /* success, no need to create whiteout */ + + ndx.nfsmnt = au_nfsmnt(sb, bcpup); + ndx.flags = 0; + if (unlikely(au_test_dlgt(mnt_flags))) + au_fset_ndx(ndx.flags, DLGT); + ndx.nd = NULL; + /* ndx.br = NULL; */ + wh_dentry = au_wh_create(dentry, bcpup, h_parent, &ndx); + if (!IS_ERR(wh_dentry)) + goto out; /* success */ + /* returns with the parent is locked and wh_dentry is DGETed */ + + out_unpin: + au_unpin(pin); + out: + AuTraceErrPtr(wh_dentry); + return wh_dentry; +} + +static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex, + struct au_nhash *whlist, struct inode *dir) +{ + int rmdir_later, err; + struct dentry *h_dentry; + struct inode *inode, *h_inode; + struct super_block *sb; + + LKTRTrace("%.*s, b%d\n", AuDLNPair(dentry), bindex); + + inode = NULL; + h_inode = NULL; + sb = dentry->d_sb; + if (unlikely(au_opt_test(au_mntflags(sb), UDBA_INOTIFY))) { + inode = dentry->d_inode; + h_inode = au_h_iptr(inode, bindex); + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); + } + h_dentry = au_h_dptr(dentry, bindex); + err = au_whtmp_ren(dir, bindex, h_dentry); + if (unlikely(inode)) { + /* todo: bad approach? */ + if (!err) + au_hin_suspend(au_hi(inode, bindex)); + mutex_unlock(&h_inode->i_mutex); + } + if (unlikely(err)) + goto out; + + if (!au_test_nfs(h_dentry->d_sb)) { + const int dirwh = au_sbi(sb)->si_dirwh; + rmdir_later = (dirwh <= 1); + if (!rmdir_later) + rmdir_later = au_nhash_test_longer_wh(whlist, bindex, + dirwh); + if (rmdir_later) + return rmdir_later; + } + + err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist); + if (unlikely(err)) { + AuIOErr("rmdir %.*s, b%d failed, %d. ignored\n", + AuDLNPair(h_dentry), bindex, err); + /* we do not revert the inotify watch */ + err = 0; + } + + out: + AuTraceErr(err); + return err; +} + +static void epilog(struct inode *dir, struct dentry *dentry, + aufs_bindex_t bindex) +{ + /* todo: unnecessary? */ + d_drop(dentry); + dentry->d_inode->i_ctime = dir->i_ctime; + + if (atomic_read(&dentry->d_count) == 1) { + au_set_h_dptr(dentry, au_dbstart(dentry), NULL); + au_update_dbstart(dentry); + } + if (au_ibstart(dir) == bindex) + au_cpup_attr_timesizes(dir); + dir->i_version++; +} + +/* revert flags */ +#define AuRev_DLGT 1 +#define au_ftest_rev(flags, name) ((flags) & AuRev_##name) +#define au_fset_rev(flags, name) { (flags) |= AuRev_##name; } +#define au_fclr_rev(flags, name) { (flags) &= ~AuRev_##name; } +#ifndef CONFIG_AUFS_DLGT +#undef AuRev_DLGT +#define AuRev_DLGT 0 +#endif + +static int do_revert(int err, struct inode *dir, aufs_bindex_t bwh, + struct dentry *wh_dentry, struct dentry *dentry, + struct au_dtime *dt, unsigned int flags) +{ + int rerr; + + rerr = au_wh_unlink_dentry(au_hi(dir, bwh), wh_dentry, dentry, + au_ftest_rev(flags, DLGT)); + if (!rerr) { + au_set_dbwh(dentry, bwh); + au_dtime_revert(dt); + return 0; + } + + AuIOErr("%.*s reverting whiteout failed(%d, %d)\n", + AuDLNPair(dentry), err, rerr); + return -EIO; +} + +/* ---------------------------------------------------------------------- */ + +int aufs_unlink(struct inode *dir, struct dentry *dentry) +{ + int err; + struct inode *inode, *h_dir; + struct dentry *parent, *wh_dentry, *h_dentry; + struct au_dtime dt; + aufs_bindex_t bwh, bindex, bstart; + unsigned char dlgt; + struct super_block *sb; + struct au_hin_ignore ign; + struct vfsub_args vargs; + struct au_pin pin; + + LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry)); + IMustLock(dir); + inode = dentry->d_inode; + if (unlikely(!inode)) + return -ENOENT; /* possible? */ + IMustLock(inode); + + aufs_read_lock(dentry, AuLock_DW); + parent = dentry->d_parent; /* dir inode is locked */ + di_write_lock_parent(parent); + + bstart = au_dbstart(dentry); + bwh = au_dbwh(dentry); + bindex = -1; + wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &dt, &pin); + err = PTR_ERR(wh_dentry); + if (IS_ERR(wh_dentry)) + goto out; + + sb = dir->i_sb; + dlgt = !!au_test_dlgt(au_mntflags(sb)); + AuDebugOn(au_dbstart(dentry) != bstart); + h_dentry = au_h_dptr(dentry, bstart); + dget(h_dentry); + + if (bindex == bstart) { + vfsub_args_init(&vargs, &ign, dlgt, 0); + vfsub_ign_hinode(&vargs, IN_DELETE, au_pinned_hdir(&pin, + bstart)); + h_dir = au_pinned_h_dir(&pin); + err = vfsub_unlink(h_dir, h_dentry, &vargs); + } else { + /* dir inode is locked */ + AuDebugOn(!wh_dentry + || wh_dentry->d_parent != au_h_dptr(parent, bindex)); + h_dir = wh_dentry->d_parent->d_inode; + IMustLock(h_dir); + err = 0; + } + + if (!err) { + drop_nlink(inode); +#if 0 /* todo: update plink? */ + if (unlikely(!inode->i_nlink + && au_plink_test(sb, inode) + /* && atomic_read(&inode->i_count) == 2) */)) { + au_debug_on(); + DbgInode(inode); + au_debug_off(); + } +#endif +#if 0 + /* + * although this is not a dir, + * set it here since we need to detect + * the dead inode in d_revalidate(). + */ + if (!inode->i_nlink) + inode->i_flags |= S_DEAD; +#endif + epilog(dir, dentry, bindex); + + /* update target timestamps */ + if (bindex == bstart) { + au_update_fuse_h_inode(NULL, h_dentry); /*ignore*/ + inode->i_ctime = h_dentry->d_inode->i_ctime; + } else + /* todo: this timestamp may be reverted later */ + inode->i_ctime = h_dir->i_ctime; + goto out_unlock; /* success */ + } + + /* revert */ + if (wh_dentry) { + int rerr; + unsigned int rev_flags; + + rev_flags = 0; + if (unlikely(dlgt)) + au_fset_rev(rev_flags, DLGT); + rerr = do_revert(err, dir, bwh, wh_dentry, dentry, &dt, + rev_flags); + if (rerr) + err = rerr; + } + + out_unlock: + au_unpin(&pin); + dput(wh_dentry); + dput(h_dentry); + out: + di_write_unlock(parent); + aufs_read_unlock(dentry, AuLock_DW); + AuTraceErr(err); + return err; +} + +int aufs_rmdir(struct inode *dir, struct dentry *dentry) +{ + int err, rmdir_later; + struct inode *inode; + struct dentry *parent, *wh_dentry, *h_dentry; + struct au_dtime dt; + aufs_bindex_t bwh, bindex, bstart; + struct au_whtmp_rmdir_args *args; + struct au_nhash *whlist; + struct super_block *sb; + unsigned int mnt_flags; + struct au_pin pin; + + LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry)); + IMustLock(dir); +#if 0 + err = -ENOENT; /* possible? */ + if (unlikely(IS_DEADDIR(dir))) { + AuDbg("here\n"); + goto out; + } +#endif + inode = dentry->d_inode; + err = -ENOENT; /* possible? */ + if (unlikely(!inode + //|| IS_DEADDIR(inode) || IS_DEADDIR(dir) + )) { + //AuDbg("here\n"); + goto out; + } + IMustLock(inode); + + whlist = au_nhash_new(GFP_NOFS); + err = PTR_ERR(whlist); + if (IS_ERR(whlist)) + goto out; + + err = -ENOMEM; + args = kmalloc(sizeof(*args), GFP_NOFS); + if (unlikely(!args)) + goto out_whlist; + + aufs_read_lock(dentry, AuLock_DW); + parent = dentry->d_parent; /* dir inode is locked */ + di_write_lock_parent(parent); + err = au_test_empty(dentry, whlist); + if (unlikely(err)) + goto out_args; + + bstart = au_dbstart(dentry); + bwh = au_dbwh(dentry); + bindex = -1; + wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &dt, &pin); + err = PTR_ERR(wh_dentry); + if (IS_ERR(wh_dentry)) + goto out_args; + + AuDebugOn(au_dbstart(dentry) != bstart); + h_dentry = au_h_dptr(dentry, bstart); + dget(h_dentry); + + rmdir_later = 0; + if (bindex == bstart) { + err = renwh_and_rmdir(dentry, bstart, whlist, dir); + if (err > 0) { + rmdir_later = err; + err = 0; + } + } else { + /* dir inode is locked */ + AuDebugOn(!wh_dentry + || wh_dentry->d_parent != au_h_dptr(parent, bindex)); + IMustLock(wh_dentry->d_parent->d_inode); + err = 0; + } + + sb = dentry->d_sb; + mnt_flags = au_mntflags(sb); + if (!err) { + if (unlikely(au_opt_test(mnt_flags, UDBA_INOTIFY) + && rmdir_later)) + au_reset_hinotify(inode, /*flags*/0); + clear_nlink(inode); + //inode->i_flags |= S_DEAD; + au_set_dbdiropq(dentry, -1); + epilog(dir, dentry, bindex); + + if (rmdir_later) { + au_whtmp_kick_rmdir(dir, bstart, h_dentry, whlist, + args); + args = NULL; + } + + goto out_unlock; /* success */ + } + + /* revert */ + LKTRLabel(revert); + if (wh_dentry) { + int rerr; + unsigned int rev_flags; + + rev_flags = 0; + if (unlikely(au_test_dlgt(mnt_flags))) + au_fset_rev(rev_flags, DLGT); + rerr = do_revert(err, dir, bwh, wh_dentry, dentry, &dt, + rev_flags); + if (rerr) + err = rerr; + } + + out_unlock: + au_unpin(&pin); + dput(wh_dentry); + dput(h_dentry); + out_args: + di_write_unlock(parent); + aufs_read_unlock(dentry, AuLock_DW); + kfree(args); + out_whlist: + au_nhash_del(whlist); + out: + AuTraceErr(err); + return err; +} --- linux-2.6.28.orig/ubuntu/aufs/file.h +++ linux-2.6.28/ubuntu/aufs/file.h @@ -0,0 +1,247 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * file operations + * + * $Id: file.h,v 1.5 2008/06/30 03:53:43 sfjro Exp $ + */ + +#ifndef __AUFS_FILE_H__ +#define __AUFS_FILE_H__ + +#ifdef __KERNEL__ + +#include +#include +#include +#include +#include "dentry.h" +#include "misc.h" +#include "super.h" + +/* ---------------------------------------------------------------------- */ + +struct au_branch; +struct au_hfile { + struct file *hf_file; + struct au_branch *hf_br; +}; + +struct au_vdir; +struct au_finfo { + atomic_t fi_generation; + + struct au_rwsem fi_rwsem; + struct au_hfile *fi_hfile; + aufs_bindex_t fi_bstart, fi_bend; + + union { + struct vm_operations_struct *fi_h_vm_ops; + struct au_vdir *fi_vdir_cache; + }; +}; + +/* ---------------------------------------------------------------------- */ + +/* file.c */ +extern struct address_space_operations aufs_aop; +unsigned int au_file_roflags(unsigned int flags); +struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags, + struct file *file); +int au_do_open(struct inode *inode, struct file *file, + int (*open)(struct file *file, int flags)); +int au_reopen_nondir(struct file *file); +struct au_pin; +int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin); +int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file), + int wlock, int locked); + +/* f_op.c */ +extern struct file_operations aufs_file_fop; +int aufs_flush(struct file *file, fl_owner_t id); + +/* finfo.c */ +struct au_finfo *au_fi(struct file *file); +struct au_branch *au_fbr(struct file *file, aufs_bindex_t bindex); +struct file *au_h_fptr(struct file *file, aufs_bindex_t bindex); + +void au_hfput(struct au_hfile *hf); +void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, + struct file *h_file); + +void au_finfo_fin(struct file *file); +int au_finfo_init(struct file *file); + +#ifdef CONFIG_AUFS_ROBR +/* robr.c */ +struct file *au_robr_safe_file(struct vm_area_struct *vma); +void au_robr_reset_file(struct vm_area_struct *vma, struct file *file); +#else +static inline struct file *au_robr_safe_file(struct vm_area_struct *vma) +{ + struct file *file; + + file = vma->vm_file; + if (file->private_data && au_test_aufs(file->f_dentry->d_sb)) + return file; + return NULL; +} + +static inline +void au_robr_reset_file(struct vm_area_struct *vma, struct file *file) +{ + vma->vm_file = file; + /* smp_mb(); */ /* flush vm_file */ +} +#endif /* CONFIG_AUFS_ROBR */ + +/* ---------------------------------------------------------------------- */ + +/* todo: memory barrier? */ +static inline au_gen_t au_figen(struct file *f) +{ + return atomic_read(&au_fi(f)->fi_generation); +} + +static inline int au_test_mmapped(struct file *f) +{ + return !!(au_fi(f)->fi_h_vm_ops); +} + +static inline int au_test_aufs_file(struct file *f) +{ + return !(f->f_dentry->d_inode->i_mode + & (S_IFCHR | S_IFBLK | S_IFIFO | S_IFSOCK)); +} + +/* ---------------------------------------------------------------------- */ + +#if !defined(CONFIG_AUFS_MODULE) || defined(CONFIG_AUFS_DENY_WRITE_ACCESS_PATCH) +int au_store_fmode_exec(struct nameidata *nd, struct inode *inode); + +static inline int au_deny_write_access(struct file *h_file) +{ + LKTRTrace("%.*s\n", AuDLNPair(h_file->f_dentry)); + return deny_write_access(h_file); +} + +static inline void au_allow_write_access(struct file *h_file) +{ + allow_write_access(h_file); +} + +#else + +static inline int au_store_fmode_exec(struct nameidata *nd, struct inode *inode) +{ + /* nothing */ + return 0; +} + +static inline int au_deny_write_access(struct file *h_file) +{ + /* nothing */ + return 0; +} + +static inline void au_allow_write_access(struct file *h_file) +{ + /* nothing */ +} +#endif /* CONFIG_AUFS_DENY_WRITE_ACCESS_PATCH */ + +/* ---------------------------------------------------------------------- */ + +/* + * fi_read_lock, fi_write_lock, + * fi_read_unlock, fi_write_unlock, fi_downgrade_lock + */ +AuSimpleRwsemFuncs(fi, struct file *f, au_fi(f)->fi_rwsem); + +/* to debug easier, do not make them inlined functions */ +#define FiMustReadLock(f) do { \ + SiMustAnyLock((f)->f_dentry->d_sb); \ + AuRwMustReadLock(&au_fi(f)->fi_rwsem); \ +} while (0) + +#define FiMustWriteLock(f) do { \ + SiMustAnyLock((f)->f_dentry->d_sb); \ + AuRwMustWriteLock(&au_fi(f)->fi_rwsem); \ +} while (0) + +#define FiMustAnyLock(f) do { \ + SiMustAnyLock((f)->f_dentry->d_sb); \ + AuRwMustAnyLock(&au_fi(f)->fi_rwsem); \ +} while (0) + +#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem) + +/* ---------------------------------------------------------------------- */ + +/* todo: hard/soft set? */ +static inline aufs_bindex_t au_fbstart(struct file *file) +{ + FiMustAnyLock(file); + return au_fi(file)->fi_bstart; +} + +static inline aufs_bindex_t au_fbend(struct file *file) +{ + FiMustAnyLock(file); + return au_fi(file)->fi_bend; +} + +static inline struct au_vdir *au_fvdir_cache(struct file *file) +{ + FiMustAnyLock(file); + return au_fi(file)->fi_vdir_cache; +} + +static inline void au_set_fbstart(struct file *file, aufs_bindex_t bindex) +{ + FiMustWriteLock(file); + AuDebugOn(au_sbend(file->f_dentry->d_sb) < bindex); + au_fi(file)->fi_bstart = bindex; +} + +static inline void au_set_fbend(struct file *file, aufs_bindex_t bindex) +{ + FiMustWriteLock(file); + AuDebugOn(au_sbend(file->f_dentry->d_sb) < bindex + || bindex < au_fbstart(file)); + au_fi(file)->fi_bend = bindex; +} + +static inline void au_set_fvdir_cache(struct file *file, + struct au_vdir *vdir_cache) +{ + FiMustWriteLock(file); + AuDebugOn(!S_ISDIR(file->f_dentry->d_inode->i_mode) + || (au_fi(file)->fi_vdir_cache && vdir_cache)); + au_fi(file)->fi_vdir_cache = vdir_cache; +} + +static inline void au_update_figen(struct file *file) +{ + atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_dentry)); + /* smp_mb(); */ /* atomic_set */ +} + +#endif /* __KERNEL__ */ +#endif /* __AUFS_FILE_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/f_op.c +++ linux-2.6.28/ubuntu/aufs/f_op.c @@ -0,0 +1,670 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * file and vm operations + * + * $Id: f_op.c,v 1.11 2008/09/01 02:55:44 sfjro Exp $ + */ + +#include +#include +#include "aufs.h" + +/* common function to regular file and dir */ +int aufs_flush(struct file *file, fl_owner_t id) +{ + int err; + struct dentry *dentry; + aufs_bindex_t bindex, bend; + struct file *h_file; + + dentry = file->f_dentry; + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + + si_noflush_read_lock(dentry->d_sb); + fi_read_lock(file); + di_read_lock_child(dentry, AuLock_IW); + + err = 0; + bend = au_fbend(file); + for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) { + h_file = au_h_fptr(file, bindex); + if (h_file && h_file->f_op && h_file->f_op->flush) { + err = h_file->f_op->flush(h_file, id); + if (!err) + au_update_fuse_h_inode + (h_file->f_vfsmnt, h_file->f_dentry); + /*ignore*/ + } + } + au_cpup_attr_timesizes(dentry->d_inode); + + di_read_unlock(dentry, AuLock_IW); + fi_read_unlock(file); + si_read_unlock(dentry->d_sb); + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static int do_open_nondir(struct file *file, int flags) +{ + int err; + aufs_bindex_t bindex; + struct super_block *sb; + struct file *h_file; + struct dentry *dentry; + struct inode *inode; + struct au_finfo *finfo; + + dentry = file->f_dentry; + LKTRTrace("%.*s, flags 0%o\n", AuDLNPair(dentry), flags); + FiMustWriteLock(file); + inode = dentry->d_inode; + AuDebugOn(!inode || S_ISDIR(inode->i_mode)); + + err = 0; + finfo = au_fi(file); + finfo->fi_h_vm_ops = NULL; + sb = dentry->d_sb; + bindex = au_dbstart(dentry); + AuDebugOn(!au_h_dptr(dentry, bindex)->d_inode); + /* O_TRUNC is processed already */ + BUG_ON(au_test_ro(sb, bindex, inode) && (flags & O_TRUNC)); + + h_file = au_h_open(dentry, bindex, flags, file); + if (IS_ERR(h_file)) + err = PTR_ERR(h_file); + else { + au_set_fbstart(file, bindex); + au_set_fbend(file, bindex); + au_set_h_fptr(file, bindex, h_file); + au_update_figen(file); + /* todo: necessary? */ + /* file->f_ra = h_file->f_ra; */ + err = 0; + } + AuTraceErr(err); + return err; +} + +static int aufs_open_nondir(struct inode *inode, struct file *file) +{ + LKTRTrace("i%lu, %.*s\n", inode->i_ino, AuDLNPair(file->f_dentry)); + + return au_do_open(inode, file, do_open_nondir); +} + +static int aufs_release_nondir(struct inode *inode, struct file *file) +{ + struct super_block *sb = file->f_dentry->d_sb; + + LKTRTrace("i%lu, %.*s\n", inode->i_ino, AuDLNPair(file->f_dentry)); + + si_noflush_read_lock(sb); + au_finfo_fin(file); + si_read_unlock(sb); + return 0; +} + +/* ---------------------------------------------------------------------- */ + +static ssize_t aufs_read(struct file *file, char __user *buf, size_t count, + loff_t *ppos) +{ + ssize_t err; + struct dentry *dentry; + struct file *h_file; + struct super_block *sb; + struct inode *h_inode; + + dentry = file->f_dentry; + LKTRTrace("%.*s, cnt %lu, pos %lld\n", + AuDLNPair(dentry), (unsigned long)count, *ppos); + + sb = dentry->d_sb; + si_read_lock(sb, AuLock_FLUSH); + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0, + /*locked*/0); + if (unlikely(err)) + goto out; + + /* support LSM and notify */ + h_file = au_h_fptr(file, au_fbstart(file)); + h_inode = h_file->f_dentry->d_inode; + err = vfsub_read_u(h_file, buf, count, ppos, + au_test_dlgt(au_mntflags(sb))); + /* todo: necessary? */ + /* file->f_ra = h_file->f_ra; */ + fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode); + + di_read_unlock(dentry, AuLock_IR); + fi_read_unlock(file); + out: + si_read_unlock(sb); + AuTraceErr(err); + return err; +} + +static ssize_t aufs_write(struct file *file, const char __user *ubuf, + size_t count, loff_t *ppos) +{ + ssize_t err; + struct dentry *dentry; + struct inode *inode; + struct super_block *sb; + unsigned int mnt_flags; + struct file *h_file; + char __user *buf = (char __user *)ubuf; + struct au_hin_ignore ign; + struct vfsub_args vargs; + aufs_bindex_t bstart; + int hinotify; + struct au_pin pin; + + dentry = file->f_dentry; + LKTRTrace("%.*s, cnt %lu, pos %lld\n", + AuDLNPair(dentry), (unsigned long)count, *ppos); + + inode = dentry->d_inode; + mutex_lock(&inode->i_mutex); + sb = dentry->d_sb; + si_read_lock(sb, AuLock_FLUSH); + mnt_flags = au_mntflags(sb); + hinotify = !!au_opt_test(mnt_flags, UDBA_INOTIFY); + vfsub_args_init(&vargs, &ign, au_test_dlgt(mnt_flags), 0); + + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1, + /*locked*/1); + if (unlikely(err)) + goto out; + err = au_ready_to_write(file, -1, &pin); + di_downgrade_lock(dentry, AuLock_IR); + if (unlikely(err)) + goto out_unlock; + + bstart = au_fbstart(file); + h_file = au_h_fptr(file, bstart); + if (!hinotify) { + au_unpin(&pin); + err = vfsub_write_u(h_file, buf, count, ppos, &vargs); + } else { + vfsub_ign_hinode(&vargs, IN_MODIFY, + au_pinned_hdir(&pin, bstart)); + err = vfsub_write_u(h_file, buf, count, ppos, &vargs); + au_unpin(&pin); + } + au_cpup_attr_timesizes(inode); + + out_unlock: + di_read_unlock(dentry, AuLock_IR); + fi_write_unlock(file); + out: + si_read_unlock(sb); + mutex_unlock(&inode->i_mutex); + AuTraceErr(err); + return err; +} + +#ifdef CONFIG_AUFS_SPLICE_PATCH +static int au_test_loopback(void) +{ + const char c = current->comm[4]; + /* true if a kernel thread named 'loop[0-9].*' accesses a file */ + const int loopback = (current->mm == NULL + && '0' <= c && c <= '9' + && strncmp(current->comm, "loop", 4) == 0); + return loopback; +} + +static ssize_t aufs_splice_read(struct file *file, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags) +{ + ssize_t err; + struct file *h_file; + struct dentry *dentry; + struct super_block *sb; + + dentry = file->f_dentry; + LKTRTrace("%.*s, pos %lld, len %lu\n", + AuDLNPair(dentry), *ppos, (unsigned long)len); + + sb = dentry->d_sb; + si_read_lock(sb, AuLock_FLUSH); + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0, + /*locked*/0); + if (unlikely(err)) + goto out; + + err = -EINVAL; + /* support LSM and notify */ + h_file = au_h_fptr(file, au_fbstart(file)); + if (/* unlikely */(au_test_loopback())) { + file->f_mapping = h_file->f_mapping; + smp_mb(); /* unnecessary? */ + } + err = vfsub_splice_to(h_file, ppos, pipe, len, flags, + au_test_dlgt(au_mntflags(sb))); + /* todo: necessasry? */ + /* file->f_ra = h_file->f_ra; */ + fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode); + di_read_unlock(dentry, AuLock_IR); + fi_read_unlock(file); + + out: + si_read_unlock(sb); + AuTraceErr(err); + return err; +} + +static ssize_t +aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos, + size_t len, unsigned int flags) +{ + ssize_t err; + struct dentry *dentry; + struct inode *inode, *h_inode; + struct super_block *sb; + struct file *h_file; + /* struct au_hin_ignore ign; */ + struct vfsub_args vargs; + unsigned int mnt_flags; + struct au_pin pin; + + dentry = file->f_dentry; + LKTRTrace("%.*s, len %lu, pos %lld\n", + AuDLNPair(dentry), (unsigned long)len, *ppos); + + inode = dentry->d_inode; + mutex_lock(&inode->i_mutex); + sb = dentry->d_sb; + si_read_lock(sb, AuLock_FLUSH); + mnt_flags = au_mntflags(sb); + vfsub_args_init(&vargs, /*&ign*/NULL, au_test_dlgt(mnt_flags), 0); + + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1, + /*locked*/1); + if (unlikely(err)) + goto out; + err = au_ready_to_write(file, -1, &pin); + di_downgrade_lock(dentry, AuLock_IR); + if (unlikely(err)) + goto out_unlock; + + /* support LSM and notify */ + /* current vfs_splice_from() doesn't fire up the inotify event */ + h_file = au_h_fptr(file, au_fbstart(file)); + h_inode = h_file->f_dentry->d_inode; + if (1 || !au_opt_test(mnt_flags, UDBA_INOTIFY)) { + au_unpin(&pin); + err = vfsub_splice_from(pipe, h_file, ppos, len, flags, &vargs); + } +#if 0 /* reserved for future use */ + else { + struct dentry *parent = dget_parent(dentry); + vfsub_ign_hinode(&vargs, IN_MODIFY, + au_pinned_hdir(&pin, bstart)); + err = vfsub_splice_from(pipe, h_file, ppos, len, flags, &vargs); + au_unpin(&pin); + } +#endif + au_cpup_attr_timesizes(inode); + + out_unlock: + di_read_unlock(dentry, AuLock_IR); + fi_write_unlock(file); + out: + si_read_unlock(sb); + mutex_unlock(&inode->i_mutex); + AuTraceErr(err); + return err; +} +#endif /* CONFIG_AUFS_SPLICE_PATCH */ + +/* ---------------------------------------------------------------------- */ + +static int aufs_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + int err; + struct dentry *dentry; + struct file *file, *h_file; + struct inode *inode; + static DECLARE_WAIT_QUEUE_HEAD(wq); + struct au_finfo *finfo; + + AuTraceEnter(); + AuDebugOn(!vma || !vma->vm_file); + /* todo: non-robr mode, user vm_file as it is? */ + wait_event(wq, (file = au_robr_safe_file(vma))); + AuDebugOn(!au_test_aufs(file->f_dentry->d_sb)); + dentry = file->f_dentry; + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + inode = dentry->d_inode; + AuDebugOn(!S_ISREG(inode->i_mode)); + + /* do not revalidate, no si lock */ + finfo = au_fi(file); + h_file = finfo->fi_hfile[0 + finfo->fi_bstart].hf_file; + AuDebugOn(!h_file || !au_test_mmapped(file)); + fi_write_lock(file); + vma->vm_file = h_file; + err = finfo->fi_h_vm_ops->fault(vma, vmf); + /* todo: necessary? */ + /* file->f_ra = h_file->f_ra; */ + au_robr_reset_file(vma, file); + fi_write_unlock(file); +#if 0 /* def CONFIG_SMP */ + /* wake_up_nr(&wq, online_cpu - 1); */ + wake_up_all(&wq); +#else + wake_up(&wq); +#endif + + if (!(err & VM_FAULT_ERROR)) { +#if 0 /* debug */ + struct page *page; + page = vmf->page; + AuDbg("%p, %d\n", page, page_mapcount(page)); + + page->mapping = file->f_mapping; + get_page(page); + file->f_mapping = h_file->f_mapping; + touch_atime(NULL, dentry); + inode->i_atime = h_file->f_dentry->d_inode->i_atime; +#endif + } + AuTraceErr(err); + return err; +} + +static struct vm_operations_struct aufs_vm_ops = { + .fault = aufs_fault, +#if 0 /* reserved for future use */ + .open = aufs_vmaopen, + .close = aufs_vmaclose, + unsigned long (*nopfn)(struct vm_area_struct *area, + unsigned long address); + page_mkwrite(struct vm_area_struct *vma, struct page *page) +#endif +}; + +/* ---------------------------------------------------------------------- */ + +static struct vm_operations_struct *au_vm_ops(struct file *h_file, + struct vm_area_struct *vma) +{ + struct vm_operations_struct *vm_ops; + int err; + + AuTraceEnter(); + + au_br_nfs_lockdep_off(h_file->f_vfsmnt->mnt_sb); + err = h_file->f_op->mmap(h_file, vma); + au_br_nfs_lockdep_on(h_file->f_vfsmnt->mnt_sb); + vm_ops = ERR_PTR(err); + if (unlikely(err)) + goto out; + vm_ops = vma->vm_ops; + err = do_munmap(current->mm, vma->vm_start, + vma->vm_end - vma->vm_start); + if (unlikely(err)) { + AuIOErr("failed internal unmapping %.*s, %d\n", + AuDLNPair(h_file->f_dentry), err); + vm_ops = ERR_PTR(-EIO); + } + + out: + AuTraceErrPtr(vm_ops); + return vm_ops; +} + +static int aufs_mmap(struct file *file, struct vm_area_struct *vma) +{ + int err; + unsigned char wlock, mmapped; + struct dentry *dentry; + struct super_block *sb; + struct file *h_file; + struct vm_operations_struct *vm_ops; + + dentry = file->f_dentry; + LKTRTrace("%.*s, %lx, len %lu\n", + AuDLNPair(dentry), vma->vm_start, + vma->vm_end - vma->vm_start); + AuDebugOn(!S_ISREG(dentry->d_inode->i_mode)); + AuDebugOn(down_write_trylock(&vma->vm_mm->mmap_sem)); + + mmapped = au_test_mmapped(file); /* can be harmless race condition */ + wlock = !!(file->f_mode & FMODE_WRITE); + sb = dentry->d_sb; + si_read_lock(sb, AuLock_FLUSH); + err = au_reval_and_lock_fdi(file, au_reopen_nondir, wlock | !mmapped, + /*locked*/0); + if (unlikely(err)) + goto out; + + if (wlock) { + struct au_pin pin; + + err = au_ready_to_write(file, -1, &pin); + di_downgrade_lock(dentry, AuLock_IR); + if (unlikely(err)) + goto out_unlock; + au_unpin(&pin); + } else if (!mmapped) + di_downgrade_lock(dentry, AuLock_IR); + + h_file = au_h_fptr(file, au_fbstart(file)); + if (unlikely(au_test_fuse(h_file->f_dentry->d_sb))) { + /* + * by this assignment, f_mapping will differs from aufs inode + * i_mapping. + * if someone else mixes the use of f_dentry->d_inode and + * f_mapping->host, then a problem may arise. + */ + file->f_mapping = h_file->f_mapping; + } + + if (0 && h_file->f_op->mmap == generic_file_mmap) { + err = generic_file_mmap(file, vma); /* instead of h_file */ + if (unlikely(err)) + goto out_unlock; + au_fi(file)->fi_h_vm_ops = vma->vm_ops; + } else { + vm_ops = NULL; + if (!mmapped) { + vm_ops = au_vm_ops(h_file, vma); + err = PTR_ERR(vm_ops); + if (IS_ERR(vm_ops)) + goto out_unlock; + } + + err = generic_file_mmap(file, vma); + if (unlikely(err)) + goto out_unlock; + vma->vm_ops = &aufs_vm_ops; + /* test again */ + if (!au_test_mmapped(file)) { + FiMustWriteLock(file); + au_fi(file)->fi_h_vm_ops = vm_ops; + } + } + + file_accessed(h_file); + au_update_fuse_h_inode(h_file->f_vfsmnt, h_file->f_dentry); /*ignore*/ + fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode); + + out_unlock: + di_read_unlock(dentry, AuLock_IR); + if (!wlock && mmapped) + fi_read_unlock(file); + else + fi_write_unlock(file); + out: + si_read_unlock(sb); + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static unsigned int aufs_poll(struct file *file, poll_table *wait) +{ + unsigned int mask; + struct file *h_file; + int err; + struct dentry *dentry; + struct super_block *sb; + + dentry = file->f_dentry; + LKTRTrace("%.*s, wait %p\n", AuDLNPair(dentry), wait); + AuDebugOn(S_ISDIR(dentry->d_inode->i_mode)); + + /* We should pretend an error happened. */ + mask = POLLERR /* | POLLIN | POLLOUT */; + sb = dentry->d_sb; + si_read_lock(sb, AuLock_FLUSH); + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0, + /*locked*/0); + if (unlikely(err)) + goto out; + + /* it is not an error of hidden_file has no operation */ + mask = DEFAULT_POLLMASK; + h_file = au_h_fptr(file, au_fbstart(file)); + if (h_file->f_op && h_file->f_op->poll) + mask = h_file->f_op->poll(h_file, wait); + di_read_unlock(dentry, AuLock_IR); + fi_read_unlock(file); + + out: + si_read_unlock(sb); + AuTraceErr((int)mask); + return mask; +} + +static int aufs_fsync_nondir(struct file *file, struct dentry *dentry, + int datasync) +{ + int err; + struct inode *inode; + struct file *h_file; + struct super_block *sb; + struct au_pin pin; + + LKTRTrace("%.*s, %d\n", AuDLNPair(dentry), datasync); + inode = dentry->d_inode; + + IMustLock(file->f_mapping->host); + if (unlikely(inode != file->f_mapping->host)) { + mutex_unlock(&file->f_mapping->host->i_mutex); + mutex_lock(&inode->i_mutex); + } + IMustLock(inode); + + sb = dentry->d_sb; + si_read_lock(sb, AuLock_FLUSH); + err = 0; /* -EBADF; */ /* posix? */ + if (unlikely(!(file->f_mode & FMODE_WRITE))) + goto out; + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1, + /*locked*/1); + if (unlikely(err)) + goto out; + err = au_ready_to_write(file, -1, &pin); + di_downgrade_lock(dentry, AuLock_IR); + if (unlikely(err)) + goto out_unlock; + au_unpin(&pin); + + err = -EINVAL; + h_file = au_h_fptr(file, au_fbstart(file)); + if (h_file->f_op && h_file->f_op->fsync) { + struct mutex *h_mtx = &h_file->f_dentry->d_inode->i_mutex; + + mutex_lock_nested(h_mtx, AuLsc_I_CHILD); + err = h_file->f_op->fsync(h_file, h_file->f_dentry, datasync); + if (!err) + au_update_fuse_h_inode(h_file->f_vfsmnt, + h_file->f_dentry); + au_cpup_attr_timesizes(inode); + mutex_unlock(h_mtx); + } + + out_unlock: + di_read_unlock(dentry, AuLock_IR); + fi_write_unlock(file); + out: + si_read_unlock(sb); + if (unlikely(inode != file->f_mapping->host)) { + mutex_unlock(&inode->i_mutex); + mutex_lock(&file->f_mapping->host->i_mutex); + } + AuTraceErr(err); + return err; +} + +static int aufs_fasync(int fd, struct file *file, int flag) +{ + int err; + struct file *h_file; + struct dentry *dentry; + struct super_block *sb; + + dentry = file->f_dentry; + LKTRTrace("%.*s, %d\n", AuDLNPair(dentry), flag); + + sb = dentry->d_sb; + si_read_lock(sb, AuLock_FLUSH); + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0, + /*locked*/0); + if (unlikely(err)) + goto out; + + h_file = au_h_fptr(file, au_fbstart(file)); + if (h_file->f_op && h_file->f_op->fasync) + err = h_file->f_op->fasync(fd, h_file, flag); + di_read_unlock(dentry, AuLock_IR); + fi_read_unlock(file); + + out: + si_read_unlock(sb); + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct file_operations aufs_file_fop = { + .read = aufs_read, + .write = aufs_write, + .poll = aufs_poll, + .mmap = aufs_mmap, + .open = aufs_open_nondir, + .flush = aufs_flush, + .release = aufs_release_nondir, + .fsync = aufs_fsync_nondir, + .fasync = aufs_fasync, +#ifdef CONFIG_AUFS_SPLICE_PATCH + .splice_write = aufs_splice_write, + .splice_read = aufs_splice_read, +#endif +}; --- linux-2.6.28.orig/ubuntu/aufs/dentry.c +++ linux-2.6.28/ubuntu/aufs/dentry.c @@ -0,0 +1,1023 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * lookup and dentry operations + * + * $Id: dentry.c,v 1.15 2008/09/22 03:52:06 sfjro Exp $ + */ + +#include "aufs.h" + +/* ---------------------------------------------------------------------- */ + +/* + * au_lkup_one() is a generic abstract entry function which calls + * lookup_one_len() or __lookup_hash() finally. it is some condisions that makes + * lookup complicated, which are nfs branch, open-intent and dlgt mode. + */ + +#if defined(CONFIG_AUFS_BR_NFS) || defined(CONFIG_AUFS_DLGT) +/* cf. lookup_one_len() in linux/fs/namei.c */ +struct dentry *au_lkup_one(const char *name, struct dentry *parent, int len, + struct au_ndx *ndx) +{ + struct dentry *dentry; + + LKTRTrace("%.*s/%.*s, ndx{%d, 0x%x}\n", + AuDLNPair(parent), len, name, !!ndx->nfsmnt, ndx->flags); + + ndx->nd_file = NULL; + if (!ndx->nfsmnt) + dentry = au_lkup_one_dlgt(name, parent, len, ndx->flags); + else + dentry = au_lkup_hash(name, parent, len, ndx); + + AuTraceErrPtr(dentry); + return dentry; +} +#endif /* CONFIG_AUFS_BR_NFS || CONFIG_AUFS_DLGT */ + +struct au_lkup_one_args { + struct dentry **errp; + const char *name; + struct dentry *parent; + int len; + struct au_ndx *ndx; +}; + +static void au_call_lkup_one(void *args) +{ + struct au_lkup_one_args *a = args; + *a->errp = au_lkup_one(a->name, a->parent, a->len, a->ndx); +} + +#define AuLkup_ALLOW_NEG 1 +#define AuLkup_DLGT (1 << 1) +#define AuLkup_DIRPERM1 (1 << 2) +#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name) +#define au_fset_lkup(flags, name) { (flags) |= AuLkup_##name; } +#define au_fclr_lkup(flags, name) { (flags) &= ~AuLkup_##name; } +#ifndef CONFIG_AUFS_DLGT +#undef AuLkup_DLGT +#define AuLkup_DLGT 0 +#undef AuLkup_DIRPERM1 +#define AuLkup_DIRPERM1 0 +#endif + +struct au_do_lookup_args { + unsigned int flags; + mode_t type; + struct nameidata *nd; +}; + +/* + * returns positive/negative dentry, NULL or an error. + * NULL means whiteout-ed or not-found. + */ +static /* noinline_for_stack */ +struct dentry *au_do_lookup(struct dentry *h_parent, struct dentry *dentry, + aufs_bindex_t bindex, struct qstr *wh_name, + struct au_do_lookup_args *args) +{ + struct dentry *h_dentry; + int err, wh_found, opq; + unsigned char wh_able; + struct inode *h_dir, *h_inode, *inode; + struct qstr *name; + struct super_block *sb; + unsigned int nd_flags; + struct au_ndx ndx = { + .flags = 0, + .nd = args->nd + }; + const int allow_neg = au_ftest_lkup(args->flags, ALLOW_NEG); + + LKTRTrace("%.*s/%.*s, b%d, {flags 0x%x, type 0%o, nd %d}\n", + AuDLNPair(h_parent), AuDLNPair(dentry), bindex, + args->flags, args->type, !!args->nd); + if (args->nd) + LKTRTrace("nd{0x%x}\n", args->nd->flags); + AuDebugOn(IS_ROOT(dentry)); + h_dir = h_parent->d_inode; + + nd_flags = 0; + wh_found = 0; + sb = dentry->d_sb; + ndx.nfsmnt = au_nfsmnt(sb, bindex); + if (unlikely(au_ftest_lkup(args->flags, DLGT))) + au_fset_ndx(ndx.flags, DLGT); + if (unlikely(au_ftest_lkup(args->flags, DIRPERM1))) + au_fset_ndx(ndx.flags, DIRPERM1); + LKTRTrace("nfsmnt %p\n", ndx.nfsmnt); + ndx.br = au_sbr(sb, bindex); + wh_able = !!au_br_whable(ndx.br->br_perm); + name = &dentry->d_name; + if (unlikely(wh_able)) + wh_found = au_test_robr_wh(name, h_parent, wh_name, + /*try_sio*/0, &ndx); + h_dentry = ERR_PTR(wh_found); + if (!wh_found) + goto real_lookup; + if (unlikely(wh_found < 0)) + goto out; + + /* We found a whiteout */ + /* au_set_dbend(dentry, bindex); */ + au_set_dbwh(dentry, bindex); + if (!allow_neg) + return NULL; /* success */ + if (unlikely(ndx.nd + && au_test_nfs(h_parent->d_sb) + && (ndx.nd->flags & LOOKUP_CREATE))) { + nd_flags = ndx.nd->flags; + ndx.nd->flags &= ~(LOOKUP_OPEN | LOOKUP_CREATE); + } + + real_lookup: + /* do not superio. */ + h_dentry = au_lkup_one(name->name, h_parent, name->len, &ndx); + if (IS_ERR(h_dentry)) + goto out; + AuDebugOn(d_unhashed(h_dentry)); + h_inode = h_dentry->d_inode; + if (!h_inode) { + if (!allow_neg) + goto out_neg; + } else if (wh_found + || (args->type && args->type != (h_inode->i_mode & S_IFMT))) + goto out_neg; + + if (au_dbend(dentry) <= bindex) + au_set_dbend(dentry, bindex); + if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry)) + au_set_dbstart(dentry, bindex); + au_set_h_dptr(dentry, bindex, h_dentry); + + err = au_br_nfs_h_intent(ndx.nd_file, dentry, bindex, args->nd); + if (unlikely(err)) { + h_dentry = ERR_PTR(err); + goto out; + } + + inode = dentry->d_inode; + if (!h_inode || !S_ISDIR(h_inode->i_mode) || !wh_able + || (inode && !S_ISDIR(inode->i_mode))) + goto out; /* success */ + + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); + opq = au_diropq_test(h_dentry, &ndx); + mutex_unlock(&h_inode->i_mutex); + if (opq > 0) + au_set_dbdiropq(dentry, bindex); + else if (unlikely(opq < 0)) { + au_set_h_dptr(dentry, bindex, NULL); + h_dentry = ERR_PTR(opq); + } + goto out; + + out_neg: + dput(h_dentry); + h_dentry = NULL; + out: + if (unlikely(nd_flags)) + ndx.nd->flags |= (nd_flags & (LOOKUP_OPEN | LOOKUP_CREATE)); + AuTraceErrPtr(h_dentry); + return h_dentry; +} + +/* + * returns the number of hidden positive dentries, + * otherwise an error. + * can be called at unlinking with @type is zero. + */ +int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type, + struct nameidata *nd) +{ + int npositive, err; + unsigned int mnt_flags; + aufs_bindex_t bindex, btail, bdiropq; + unsigned char isdir; + struct qstr whname; + struct au_do_lookup_args args = { + .type = type, + .nd = nd + }; + const struct qstr *name = &dentry->d_name; + struct dentry *parent; + struct super_block *sb; + struct inode *inode; + + LKTRTrace("%.*s, b%d, type 0%o\n", AuLNPair(name), bstart, type); + AuDebugOn(bstart < 0 || IS_ROOT(dentry)); + + /* dir may not be locked */ + parent = dget_parent(dentry); + + err = au_test_robr_shwh(dentry->d_sb, name); + if (unlikely(err)) + goto out; + + err = au_wh_name_alloc(name->name, name->len, &whname); + if (unlikely(err)) + goto out; + + sb = dentry->d_sb; + mnt_flags = au_mntflags(sb); + inode = dentry->d_inode; + isdir = !!(inode && S_ISDIR(inode->i_mode)); + args.flags = 0; + if (unlikely(au_test_dlgt(mnt_flags))) + au_fset_lkup(args.flags, DLGT); + if (unlikely(au_test_dirperm1(mnt_flags))) + au_fset_lkup(args.flags, DIRPERM1); + if (!type) + au_fset_lkup(args.flags, ALLOW_NEG); + npositive = 0; + btail = au_dbtaildir(parent); + for (bindex = bstart; bindex <= btail; bindex++) { + struct dentry *h_parent, *h_dentry; + struct inode *h_inode, *h_dir; + + h_dentry = au_h_dptr(dentry, bindex); + if (h_dentry) { + if (h_dentry->d_inode) + npositive++; + if (type != S_IFDIR) + break; + continue; + } + h_parent = au_h_dptr(parent, bindex); + if (!h_parent) + continue; + h_dir = h_parent->d_inode; + if (!h_dir || !S_ISDIR(h_dir->i_mode)) + continue; + + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); + h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname, + &args); + mutex_unlock(&h_dir->i_mutex); + err = PTR_ERR(h_dentry); + if (IS_ERR(h_dentry)) + goto out_wh; + au_fclr_lkup(args.flags, ALLOW_NEG); + + if (au_dbwh(dentry) >= 0) + break; + if (!h_dentry) + continue; + h_inode = h_dentry->d_inode; + if (!h_inode) + continue; + npositive++; + if (!args.type) + args.type = h_inode->i_mode & S_IFMT; + if (args.type != S_IFDIR) + break; + else if (isdir) { + /* the type of lowers may be different */ + bdiropq = au_dbdiropq(dentry); + if (bdiropq >= 0 && bdiropq <= bindex) + break; + } + } + + if (npositive) { + LKTRLabel(positive); + au_update_dbstart(dentry); + } + err = npositive; + if (unlikely(!au_opt_test(mnt_flags, UDBA_NONE) + && au_dbstart(dentry) < 0)) + /* both of real entry and whiteout found */ + err = -EIO; + + out_wh: + au_wh_name_free(&whname); + out: + dput(parent); + AuTraceErr(err); + return err; +} + +struct dentry *au_sio_lkup_one(const char *name, struct dentry *parent, int len, + struct au_ndx *ndx) +{ + struct dentry *dentry; + int wkq_err; + + LKTRTrace("%.*s/%.*s\n", AuDLNPair(parent), len, name); + + if (!au_test_h_perm_sio(parent->d_inode, MAY_EXEC, + au_ftest_ndx(ndx->flags, DLGT))) + dentry = au_lkup_one(name, parent, len, ndx); + else { + /* todo: ugly? */ + unsigned int flags = ndx->flags; + struct au_lkup_one_args args = { + .errp = &dentry, + .name = name, + .parent = parent, + .len = len, + .ndx = ndx + }; + + au_fclr_ndx(ndx->flags, DLGT); + au_fclr_ndx(ndx->flags, DIRPERM1); + wkq_err = au_wkq_wait(au_call_lkup_one, &args, /*dlgt*/0); + if (unlikely(wkq_err)) + dentry = ERR_PTR(wkq_err); + ndx->flags = flags; + } + + AuTraceErrPtr(dentry); + return dentry; +} + +/* + * lookup @dentry on @bindex which should be negative. + */ +int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex) +{ + int err; + struct dentry *parent, *h_parent, *h_dentry; + struct inode *h_dir; + struct au_ndx ndx = { + .flags = 0, + .nd = NULL, + /* .br = NULL */ + }; + struct super_block *sb; + unsigned int mnt_flags; + + LKTRTrace("%.*s, b%d\n", AuDLNPair(dentry), bindex); + /* dir may not be locked */ + parent = dget_parent(dentry); + AuDebugOn(!parent || !parent->d_inode + || !S_ISDIR(parent->d_inode->i_mode)); + h_parent = au_h_dptr(parent, bindex); + AuDebugOn(!h_parent); + h_dir = h_parent->d_inode; + AuDebugOn(!h_dir || !S_ISDIR(h_dir->i_mode)); + + sb = dentry->d_sb; + mnt_flags = au_mntflags(sb); + ndx.nfsmnt = au_nfsmnt(sb, bindex); + if (unlikely(au_test_dlgt(mnt_flags))) + au_fset_ndx(ndx.flags, DLGT); + if (unlikely(au_test_dirperm1(mnt_flags))) + au_fset_ndx(ndx.flags, DIRPERM1); + h_dentry = au_sio_lkup_one(dentry->d_name.name, h_parent, + dentry->d_name.len, &ndx); + err = PTR_ERR(h_dentry); + if (IS_ERR(h_dentry)) + goto out; + if (unlikely(h_dentry->d_inode)) { + err = -EIO; + AuIOErr("b%d %.*s should be negative.\n", + bindex, AuDLNPair(h_dentry)); + dput(h_dentry); + goto out; + } + + if (bindex < au_dbstart(dentry)) + au_set_dbstart(dentry, bindex); + if (au_dbend(dentry) < bindex) + au_set_dbend(dentry, bindex); + au_set_h_dptr(dentry, bindex, h_dentry); + err = 0; + + out: + dput(parent); + AuTraceErr(err); + return err; +} + +/* + * returns the number of found hidden positive dentries, + * otherwise an error. + */ +int au_refresh_hdentry(struct dentry *dentry, mode_t type) +{ + int npositive, new_sz; + struct au_dinfo *dinfo; + struct super_block *sb; + struct dentry *parent; + aufs_bindex_t bindex, parent_bend, parent_bstart, bwh, bdiropq, bend; + struct au_hdentry *p; + au_gen_t sgen; + + LKTRTrace("%.*s, type 0%o\n", AuDLNPair(dentry), type); + DiMustWriteLock(dentry); + sb = dentry->d_sb; + AuDebugOn(IS_ROOT(dentry)); + sgen = au_sigen(sb); + parent = dget_parent(dentry); + AuDebugOn(au_digen(parent) != sgen + || au_iigen(parent->d_inode) != sgen); + + npositive = -ENOMEM; + new_sz = sizeof(*dinfo->di_hdentry) * (au_sbend(sb) + 1); + dinfo = au_di(dentry); + p = au_kzrealloc(dinfo->di_hdentry, sizeof(*p) * (dinfo->di_bend + 1), + new_sz, GFP_NOFS); + if (unlikely(!p)) + goto out; + dinfo->di_hdentry = p; + + bend = dinfo->di_bend; + bwh = dinfo->di_bwh; + bdiropq = dinfo->di_bdiropq; + p += dinfo->di_bstart; + for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) { + struct dentry *hd, *hdp; + struct au_hdentry tmp, *q; + aufs_bindex_t new_bindex; + + hd = p->hd_dentry; + if (!hd) + continue; + hdp = dget_parent(hd); + if (hdp == au_h_dptr(parent, bindex)) { + dput(hdp); + continue; + } + + new_bindex = au_find_dbindex(parent, hdp); + dput(hdp); + AuDebugOn(new_bindex == bindex); + if (dinfo->di_bwh == bindex) + bwh = new_bindex; + if (dinfo->di_bdiropq == bindex) + bdiropq = new_bindex; + /* todo: test more? */ + if (new_bindex < 0) { + au_hdput(p, /*do_free*/0); + p->hd_dentry = NULL; + continue; + } + /* swap two hidden dentries, and loop again */ + q = dinfo->di_hdentry + new_bindex; + tmp = *q; + *q = *p; + *p = tmp; + if (tmp.hd_dentry) { + bindex--; + p--; + } + } + + /* todo: test more? */ + dinfo->di_bwh = -1; + if (unlikely(bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh))) + dinfo->di_bwh = bwh; + dinfo->di_bdiropq = -1; + if (unlikely(bdiropq >= 0 && bdiropq <= au_sbend(sb) + && au_sbr_whable(sb, bdiropq))) + dinfo->di_bdiropq = bdiropq; + parent_bend = au_dbend(parent); + p = dinfo->di_hdentry; + for (bindex = 0; bindex <= parent_bend; bindex++, p++) + if (p->hd_dentry) { + dinfo->di_bstart = bindex; + break; + } + p = dinfo->di_hdentry + parent_bend; + for (bindex = parent_bend; bindex >= 0; bindex--, p--) + if (p->hd_dentry) { + dinfo->di_bend = bindex; + break; + } + + npositive = 0; + parent_bstart = au_dbstart(parent); + if (type != S_IFDIR && dinfo->di_bstart == parent_bstart) + goto out_dgen; /* success */ + + npositive = au_lkup_dentry(dentry, parent_bstart, type, /*nd*/NULL); + if (npositive < 0) + goto out; + if (unlikely(dinfo->di_bwh >= 0 && dinfo->di_bwh <= dinfo->di_bstart)) + d_drop(dentry); + + out_dgen: + au_update_digen(dentry); + out: + dput(parent); + AuTraceErr(npositive); + return npositive; +} + +static int au_lock_nd(struct dentry *dentry, struct nameidata *nd) +{ + int locked = 0; + if (nd && dentry != nd->path.dentry) { + di_read_lock_parent(nd->path.dentry, 0); + locked = 1; + } + return locked; +} + +static void au_unlock_nd(int locked, struct nameidata *nd) +{ + if (locked) + di_read_unlock(nd->path.dentry, 0); +} + +/* #define TestingFuse */ +static noinline_for_stack +int au_do_h_d_reval(struct dentry *dentry, aufs_bindex_t bindex, + struct nameidata *nd, struct dentry *h_dentry) +{ + int err, valid, e; + int (*reval)(struct dentry *, struct nameidata *); + struct super_block *sb; + struct nameidata fake_nd, *p; + + LKTRTrace("%.*s, b%d, nd %d\n", AuDLNPair(dentry), bindex, !!nd); + + err = 0; + reval = NULL; + if (h_dentry->d_op) + reval = h_dentry->d_op->d_revalidate; + if (!reval) + goto out; + + sb = dentry->d_sb; + if (nd) { + memcpy(&fake_nd, nd, sizeof(*nd)); + err = au_fake_intent(&fake_nd, au_sbr_perm(sb, bindex)); + if (unlikely(err)) { + err = -EINVAL; + goto out; + } + } + p = au_fake_dm(&fake_nd, nd, sb, bindex); + AuDebugOn(IS_ERR(p)); + AuDebugOn(nd && p != &fake_nd); + LKTRTrace("b%d\n", bindex); + + /* it may return tri-state */ +#if 1 + valid = reval(h_dentry, p); +#else + if (p /*&& !IS_ROOT(h_dentry)*/) { + struct dentry *h_parent = dget_parent(h_dentry); + struct mutex *h_mtx = &h_parent->d_inode->i_mutex; +#if 0 + lktr_set_pid(current->pid, LktrArrayPid); + AuDbgDentry(p->path.dentry); + AuDbgDentry(h_dentry); + lktr_clear_pid(current->pid, LktrArrayPid); +#endif + mutex_lock_nested(h_mtx, AuLsc_I_PARENT); + valid = reval(h_dentry, p); + mutex_unlock(h_mtx); + dput(h_parent); + } else + valid = reval(h_dentry, p); +#endif + if (unlikely(valid < 0)) + err = valid; + else if (!valid) + err = -EINVAL; + else + AuDebugOn(err); + + if (p) { + AuDebugOn(!nd); + e = au_hin_after_reval(p, dentry, bindex, nd->intent.open.file); +#ifndef TestingFuse + au_update_fuse_h_inode(p->path.mnt, h_dentry); /*ignore*/ +#endif + if (unlikely(e && !err)) + err = e; + } +#ifndef TestingFuse + else + au_update_fuse_h_inode(NULL, h_dentry); /*ignore*/ +#endif + au_fake_dm_release(p); + + out: + AuTraceErr(err); + return err; +} + +static noinline_for_stack +int h_d_revalidate(struct dentry *dentry, struct inode *inode, + struct nameidata *nd, int do_udba) +{ + int err; + aufs_bindex_t bindex, btail, bstart, ibs, ibe; + unsigned char plus, locked, unhashed, is_root, h_plus; + struct super_block *sb; + struct inode *first, *h_inode, *h_cached_inode; + umode_t mode, h_mode; + struct dentry *h_dentry; + struct qstr *name; + + LKTRTrace("%.*s, nd %d\n", AuDLNPair(dentry), !!nd); + AuDebugOn(inode && au_digen(dentry) != au_iigen(inode)); + + err = 0; + sb = dentry->d_sb; + plus = 0; + mode = 0; + first = NULL; + ibs = -1; + ibe = -1; + unhashed = !!d_unhashed(dentry); + is_root = !!IS_ROOT(dentry); + name = &dentry->d_name; + + /* + * Theoretically, REVAL test should be unnecessary in case of INOTIFY. + * But inotify doesn't fire some necessary events, + * IN_ATTRIB for atime/nlink/pageio + * IN_DELETE for NFS dentry + * Let's do REVAL test too. + */ + if (do_udba && inode) { + mode = (inode->i_mode & S_IFMT); + plus = (inode->i_nlink > 0); + first = au_h_iptr(inode, au_ibstart(inode)); + ibs = au_ibstart(inode); + ibe = au_ibend(inode); + } + + bstart = au_dbstart(dentry); + btail = bstart; + if (inode && S_ISDIR(inode->i_mode)) + btail = au_dbtaildir(dentry); + locked = !!au_lock_nd(dentry, nd); + for (bindex = bstart; bindex <= btail; bindex++) { + h_dentry = au_h_dptr(dentry, bindex); + if (!h_dentry) + continue; + + LKTRTrace("b%d, %.*s\n", bindex, AuDLNPair(h_dentry)); +#ifdef TestingFuse + /* force re-lookup for fuse, in order to update attributes */ + if (unlikely(au_test_fuse(h_dentry->d_sb))) + goto err; +#endif + + if (unlikely(do_udba + && !is_root + && (unhashed != !!d_unhashed(h_dentry) + || name->len != h_dentry->d_name.len + || memcmp(name->name, h_dentry->d_name.name, + name->len) + ))) { + LKTRTrace("unhash 0x%x 0x%x, %.*s %.*s\n", + unhashed, d_unhashed(h_dentry), + AuDLNPair(dentry), AuDLNPair(h_dentry)); + goto err; + } + + err = au_do_h_d_reval(dentry, bindex, nd, h_dentry); + if (unlikely(err)) + /* do not goto err, to keep the errno */ + break; + + /* todo: plink too? */ + if (unlikely(!do_udba)) + continue; + + /* UDBA tests */ + h_inode = h_dentry->d_inode; + if (unlikely(!!inode != !!h_inode)) + goto err; + + h_plus = plus; + h_mode = mode; + h_cached_inode = h_inode; + if (h_inode) { + h_mode = (h_inode->i_mode & S_IFMT); + h_plus = (h_inode->i_nlink > 0); + } + if (inode && ibs <= bindex && bindex <= ibe) + h_cached_inode = au_h_iptr(inode, bindex); + + LKTRTrace("{%d, 0%o, %p}, h{%d, 0%o, %p}\n", + plus, mode, h_cached_inode, + h_plus, h_mode, h_inode); + if (unlikely(plus != h_plus + || mode != h_mode + || h_cached_inode != h_inode)) + goto err; + continue; + + err: + err = -EINVAL; + break; + } + au_unlock_nd(locked, nd); + + /* + * judging by timestamps is meaningless since some filesystem uses + * CURRENT_TIME_SEC instead of CURRENT_TIME. + */ + /* + * NFS may stop IN_DELETE because of DCACHE_NFSFS_RENAMED. + */ + + AuTraceErr(err); + return err; +} + +static int simple_reval_dpath(struct dentry *dentry, au_gen_t sgen) +{ + int err; + mode_t type; + struct dentry *parent; + struct inode *inode; + + LKTRTrace("%.*s, sgen %d\n", AuDLNPair(dentry), sgen); + SiMustAnyLock(dentry->d_sb); + DiMustWriteLock(dentry); + inode = dentry->d_inode; + AuDebugOn(!inode); + + if (au_digen(dentry) == sgen && au_iigen(inode) == sgen) + return 0; + + parent = dget_parent(dentry); + di_read_lock_parent(parent, AuLock_IR); + AuDebugOn(au_digen(parent) != sgen + || au_iigen(parent->d_inode) != sgen); +#ifdef CONFIG_AUFS_DEBUG + { + int i, j; + struct au_dcsub_pages dpages; + struct au_dpage *dpage; + struct dentry **dentries; + + err = au_dpages_init(&dpages, GFP_NOFS); + AuDebugOn(err); + err = au_dcsub_pages_rev(&dpages, parent, /*do_include*/1, NULL, + NULL); + AuDebugOn(err); + for (i = dpages.ndpage - 1; !err && i >= 0; i--) { + dpage = dpages.dpages + i; + dentries = dpage->dentries; + for (j = dpage->ndentry - 1; !err && j >= 0; j--) + AuDebugOn(au_digen(dentries[j]) != sgen); + } + au_dpages_free(&dpages); + } +#endif + type = (inode->i_mode & S_IFMT); + /* returns a number of positive dentries */ + err = au_refresh_hdentry(dentry, type); + if (err >= 0) + err = au_refresh_hinode(inode, dentry); + di_read_unlock(parent, AuLock_IR); + dput(parent); + AuTraceErr(err); + return err; +} + +int au_reval_dpath(struct dentry *dentry, au_gen_t sgen) +{ + int err; + struct dentry *d, *parent; + struct inode *inode; + + LKTRTrace("%.*s, sgen %d\n", AuDLNPair(dentry), sgen); + AuDebugOn(!dentry->d_inode); + DiMustWriteLock(dentry); + + if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIRS)) + return simple_reval_dpath(dentry, sgen); + + /* slow loop, keep it simple and stupid */ + /* cf: au_cpup_dirs() */ + err = 0; + parent = NULL; + while (au_digen(dentry) != sgen || au_iigen(dentry->d_inode) != sgen) { + d = dentry; + while (1) { + dput(parent); + parent = dget_parent(d); + if (au_digen(parent) == sgen + && au_iigen(parent->d_inode) == sgen) + break; + d = parent; + } + + inode = d->d_inode; + if (d != dentry) + di_write_lock_child(d); + + /* someone might update our dentry while we were sleeping */ + if (au_digen(d) != sgen || au_iigen(d->d_inode) != sgen) { + di_read_lock_parent(parent, AuLock_IR); + /* returns a number of positive dentries */ + err = au_refresh_hdentry(d, inode->i_mode & S_IFMT); + if (err >= 0) + err = au_refresh_hinode(inode, d); + di_read_unlock(parent, AuLock_IR); + } + + if (d != dentry) + di_write_unlock(d); + dput(parent); + if (unlikely(err)) + break; + } + + AuTraceErr(err); + return err; +} + +/* + * THIS IS A BOOLEAN FUNCTION: returns 1 if valid, 0 otherwise. + * nfsd passes NULL as nameidata. + */ +static int aufs_d_revalidate(struct dentry *dentry, struct nameidata *nd) +{ + int valid, err; + au_gen_t sgen; + unsigned char do_udba; + struct nameidata tmp_nd, *ndp; + struct super_block *sb; + struct inode *inode; + + LKTRTrace("dentry %.*s\n", AuDLNPair(dentry)); + if (nd && nd->path.dentry) + LKTRTrace("nd{%.*s, 0x%x}\n", + AuDLNPair(nd->path.dentry), nd->flags); + /* + * dir case: AuDebugOn(dentry->d_parent != nd->dentry); + * remove failure case:AuDebugOn(!IS_ROOT(dentry) + * && d_unhashed(dentry)); + */ + AuDebugOn(!dentry->d_fsdata); + + err = -EINVAL; +#if 0 + if (d_unhashed(dentry)) + goto __out; +#endif + sb = dentry->d_sb; +#if 1 + aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW); + inode = dentry->d_inode; +#else + si_read_lock(sb, AuLock_FLUSH); + //lktr_set_pid(current->pid, LktrArrayPid); + AuDbgDentry(dentry); + AuDbgInode(dentry->d_inode); + au_rw_write_lock_nested(&au_di(dentry)->di_rwsem, AuLsc_DI_CHILD); + LKTRLabel(clean); + //lktr_clear_pid(current->pid, LktrArrayPid); + inode = dentry->d_inode; + if (unlikely(inode && (!inode->i_nlink || IS_DEADDIR(inode)))) { + AuDbg("here\n"); + au_rw_write_unlock(&au_di(dentry)->di_rwsem); + si_read_unlock(sb); + goto __out; + } + if (inode) { + //lktr_set_pid(current->pid, LktrArrayPid); + AuDbgDentry(dentry); + AuDbgInode(inode); + ii_write_lock_child(inode); + LKTRLabel(clean); + //lktr_clear_pid(current->pid, LktrArrayPid); + } +#endif + + sgen = au_sigen(sb); + if (unlikely(au_digen(dentry) != sgen)) { + AuDebugOn(IS_ROOT(dentry)); +#ifdef ForceInotify + AuDbg("UDBA or digen, %.*s\n", AuDLNPair(dentry)); +#endif + if (inode) + err = au_reval_dpath(dentry, sgen); + if (unlikely(err)) + goto out_dgrade; + AuDebugOn(au_digen(dentry) != sgen); + } + if (unlikely(inode && au_iigen(inode) != sgen)) { + AuDebugOn(IS_ROOT(dentry)); +#ifdef ForceInotify + AuDbg("UDBA or survived, %.*s\n", AuDLNPair(dentry)); +#endif + err = au_refresh_hinode(inode, dentry); + if (unlikely(err)) + goto out_dgrade; + AuDebugOn(au_iigen(inode) != sgen); + } + di_downgrade_lock(dentry, AuLock_IR); + +#if 0 /* todo: support it? */ + /* parent dir i_nlink is not updated in the case of setattr */ + if (S_ISDIR(inode->i_mode)) { + mutex_lock(&inode->i_mutex); + ii_write_lock(inode); + au_cpup_attr_nlink(inode); + ii_write_unlock(inode); + mutex_unlock(&inode->i_mutex); + } +#endif + + AuDebugOn(au_digen(dentry) != sgen); + AuDebugOn(inode && au_iigen(inode) != sgen); + err = -EINVAL; + do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE); + if (do_udba && inode) { + aufs_bindex_t bstart = au_ibstart(inode); + if (bstart >= 0 + && au_test_higen(inode, au_h_iptr(inode, bstart))) + goto out; + } + ndp = au_dup_nd(au_sbi(sb), &tmp_nd, nd); +#if 0 + if (nd) { + path = nd->path; + nd->path.dentry = au_h_dptr(nd->path.dentry, bindex); + if (fake_nd->path.dentry) { + fake_nd->path.mnt = au_sbr_mnt(sb, bindex); + AuDebugOn(!fake_nd->path.mnt); + path_get(&fake_nd->path); + nd->path. + } + } +#endif + err = h_d_revalidate(dentry, inode, ndp, do_udba); + if (unlikely(!err && do_udba && au_dbstart(dentry) < 0)) + /* both of real entry and whiteout found */ + err = -EIO; + goto out; + + out_dgrade: + di_downgrade_lock(dentry, AuLock_IR); + out: + au_store_fmode_exec(nd, inode); + + aufs_read_unlock(dentry, AuLock_IR); + //__out: + AuTraceErr(err); + valid = !err; + if (!valid) + LKTRTrace("%.*s invalid\n", AuDLNPair(dentry)); + return valid; +} + +static void aufs_d_release(struct dentry *dentry) +{ + struct au_dinfo *dinfo; + aufs_bindex_t bend, bindex; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + AuDebugOn(!d_unhashed(dentry)); + + dinfo = dentry->d_fsdata; + if (unlikely(!dinfo)) + return; + + /* dentry may not be revalidated */ + bindex = dinfo->di_bstart; + if (bindex >= 0) { + struct au_hdentry *p; + bend = dinfo->di_bend; + AuDebugOn(bend < bindex); + p = dinfo->di_hdentry + bindex; + while (bindex++ <= bend) { + if (p->hd_dentry) + au_hdput(p, /*do_free*/1); + p++; + } + } + kfree(dinfo->di_hdentry); + au_cache_free_dinfo(dinfo); + au_hin_di_reinit(dentry); + /* todo: tmp code */ + //dentry->d_fsdata = NULL; +} + +struct dentry_operations aufs_dop = { + .d_revalidate = aufs_d_revalidate, + .d_release = aufs_d_release, + /* never use d_delete, especially in case of nfs server */ +}; --- linux-2.6.28.orig/ubuntu/aufs/whout.c +++ linux-2.6.28/ubuntu/aufs/whout.c @@ -0,0 +1,1118 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * whiteout for logical deletion and opaque directory + * + * $Id: whout.c,v 1.13 2008/09/08 02:40:12 sfjro Exp $ + */ + +#include +#include +#include "aufs.h" + +#define WH_MASK S_IRUGO + +/* If a directory contains this file, then it is opaque. We start with the + * .wh. flag so that it is blocked by lookup. + */ +static struct qstr diropq_name = { + .name = AUFS_WH_DIROPQ, + .len = sizeof(AUFS_WH_DIROPQ) - 1 +}; + +/* + * generate whiteout name, which is NOT terminated by NULL. + * @name: original d_name.name + * @len: original d_name.len + * @wh: whiteout qstr + * returns zero when succeeds, otherwise error. + * succeeded value as wh->name should be freed by au_wh_name_free(). + */ +int au_wh_name_alloc(const char *name, int len, struct qstr *wh) +{ + char *p; + + AuDebugOn(!name || !len || !wh); + + if (unlikely(len > PATH_MAX - AUFS_WH_PFX_LEN)) + return -ENAMETOOLONG; + + wh->len = len + AUFS_WH_PFX_LEN; + p = kmalloc(wh->len, GFP_NOFS); + wh->name = p; + if (p) { + memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); + memcpy(p + AUFS_WH_PFX_LEN, name, len); + /* smp_mb(); */ + return 0; + } + return -ENOMEM; +} + +void au_wh_name_free(struct qstr *wh) +{ + AuDebugOn(!wh || !wh->name); + kfree(wh->name); +} + +/* ---------------------------------------------------------------------- */ + +/* + * test if the @wh_name exists under @h_parent. + * @try_sio specifies the necessary of super-io. + */ +int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio, + struct au_ndx *ndx) +{ + int err; + struct dentry *wh_dentry; + struct inode *h_dir; + unsigned int flags; + + LKTRTrace("%.*s/%.*s, ndx{%p, 0x%x}\n", AuDLNPair(h_parent), + wh_name->len, wh_name->name, ndx->nfsmnt, ndx->flags); + h_dir = h_parent->d_inode; + AuDebugOn(!S_ISDIR(h_dir->i_mode)); + + flags = 0; + if (ndx && ndx->nd) { + flags = ndx->nd->flags; + ndx->nd->flags &= ~(LOOKUP_OPEN | LOOKUP_CREATE); + } + + if (!try_sio) + wh_dentry = au_lkup_one(wh_name->name, h_parent, + wh_name->len, ndx); + else + wh_dentry = au_sio_lkup_one(wh_name->name, h_parent, + wh_name->len, ndx); + if (flags) + ndx->nd->flags = flags; + err = PTR_ERR(wh_dentry); + if (IS_ERR(wh_dentry)) + goto out; + + err = 0; + if (!wh_dentry->d_inode) + goto out_wh; /* success */ + + err = 1; + if (S_ISREG(wh_dentry->d_inode->i_mode)) + goto out_wh; /* success */ + + err = -EIO; + AuIOErr("%.*s Invalid whiteout entry type 0%o.\n", + AuDLNPair(wh_dentry), wh_dentry->d_inode->i_mode); + + out_wh: + dput(wh_dentry); + out: + AuTraceErr(err); + return err; +} + +/* + * test if the @h_dentry sets opaque or not. + */ +int au_diropq_test(struct dentry *h_dentry, struct au_ndx *ndx) +{ + int err, try_sio; + struct inode *h_dir; + + LKTRTrace("dentry %.*s\n", AuDLNPair(h_dentry)); + h_dir = h_dentry->d_inode; + AuDebugOn(!S_ISDIR(h_dir->i_mode)); + + try_sio = au_test_h_perm_sio(h_dir, MAY_EXEC, + au_ftest_ndx(ndx->flags, DLGT)); + err = au_wh_test(h_dentry, &diropq_name, try_sio, ndx); + AuTraceErr(err); + return err; +} + +/* + * returns a negative dentry whose name is unique and temporary. + */ +struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct qstr *prefix, + struct au_ndx *ndx) +{ +#define HEX_LEN 4 + struct dentry *dentry; + int len, i; + char defname[AUFS_WH_PFX_LEN * 2 + DNAME_INLINE_LEN_MIN + 1 + + HEX_LEN + 1], *name, *p; + static unsigned char cnt; + + LKTRTrace("hp %.*s, prefix %.*s\n", + AuDLNPair(h_parent), prefix->len, prefix->name); + AuDebugOn(!h_parent->d_inode); + + name = defname; + len = sizeof(defname) - DNAME_INLINE_LEN_MIN + prefix->len - 1; + if (unlikely(prefix->len > DNAME_INLINE_LEN_MIN)) { + dentry = ERR_PTR(-ENAMETOOLONG); + if (unlikely(len >= PATH_MAX)) + goto out; + dentry = ERR_PTR(-ENOMEM); + name = kmalloc(len + 1, GFP_NOFS); + if (unlikely(!name)) + goto out; + } + + /* doubly whiteout-ed */ + memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2); + p = name + AUFS_WH_PFX_LEN * 2; + memcpy(p, prefix->name, prefix->len); + p += prefix->len; + *p++ = '.'; + AuDebugOn(name + len + 1 - p <= HEX_LEN); + + for (i = 0; i < 3; i++) { + sprintf(p, "%.*d", HEX_LEN, cnt++); + dentry = au_sio_lkup_one(name, h_parent, len, ndx); + if (IS_ERR(dentry) || !dentry->d_inode) + goto out_name; + dput(dentry); + } + /* AuWarn("could not get random name\n"); */ + dentry = ERR_PTR(-EEXIST); + AuDbg("%.*s\n", len, name); + BUG(); + + out_name: + if (unlikely(name != defname)) + kfree(name); + out: + AuTraceErrPtr(dentry); + return dentry; +#undef HEX_LEN +} + +/* + * rename the @dentry of @bindex to the whiteouted temporary name. + */ +int au_whtmp_ren(struct inode *dir, aufs_bindex_t bindex, + struct dentry *h_dentry) +{ + int err, dlgt; + struct inode *h_dir; + struct dentry *h_parent, *tmp_dentry; + struct super_block *sb; + unsigned int mnt_flags; + struct au_hin_ignore ign; + struct vfsub_args vargs; + struct au_ndx ndx = { + .flags = 0, + .nd = NULL, + /* .br = NULL */ + }; + + LKTRTrace("%.*s\n", AuDLNPair(h_dentry)); + AuDebugOn(!h_dentry->d_inode); + h_parent = h_dentry->d_parent; /* dir inode is locked */ + h_dir = h_parent->d_inode; + IMustLock(h_dir); + + sb = dir->i_sb; + mnt_flags = au_mntflags(sb); + dlgt = !!au_test_dlgt(mnt_flags); + if (unlikely(dlgt)) + au_fset_ndx(ndx.flags, DLGT); + ndx.nfsmnt = au_nfsmnt(sb, bindex); + tmp_dentry = au_whtmp_lkup(h_parent, &h_dentry->d_name, &ndx); + err = PTR_ERR(tmp_dentry); + if (IS_ERR(tmp_dentry)) + goto out; + + /* under the same dir, no need to lock_rename() */ + vfsub_args_init(&vargs, &ign, dlgt, 0); + AuDebugOn(!S_ISDIR(h_dentry->d_inode->i_mode)); + vfsub_ign_hinode(&vargs, IN_MOVED_FROM | IN_MOVED_TO, + au_hi(dir, bindex)); + err = vfsub_rename(h_dir, h_dentry, h_dir, tmp_dentry, &vargs); + AuTraceErr(err); + dput(tmp_dentry); + + out: + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static int do_unlink_wh(struct au_hinode *hdir, struct inode *h_dir, + struct dentry *wh_dentry, const int dlgt) +{ + int err; + struct au_hin_ignore ign; + struct vfsub_args vargs; + + AuDebugOn(hdir && h_dir); + AuDebugOn(!hdir && !h_dir); + if (!h_dir) + h_dir = hdir->hi_inode; + LKTRTrace("hi%lu, wh %.*s\n", h_dir->i_ino, AuDLNPair(wh_dentry)); + AuDebugOn(!wh_dentry->d_inode || !S_ISREG(wh_dentry->d_inode->i_mode)); + + /* + * forces superio when the dir has a sticky bit. + * this may be a violation of unix fs semantics. + */ + vfsub_args_init(&vargs, &ign, dlgt, + (h_dir->i_mode & S_ISVTX) + && wh_dentry->d_inode->i_uid != current->fsuid); + vfsub_ign_hinode(&vargs, IN_DELETE, hdir); + err = vfsub_unlink(h_dir, wh_dentry, &vargs); + AuTraceErr(err); + return err; +} + +int au_wh_unlink_dentry(struct au_hinode *hdir, struct dentry *wh_dentry, + struct dentry *dentry, int dlgt) +{ + int err; + + LKTRTrace("i%lu, wh %.*s, d %p\n", + hdir->hi_inode->i_ino, AuDLNPair(wh_dentry), dentry); + AuDebugOn((dentry && au_dbwh(dentry) < 0) + || !wh_dentry->d_inode + || !S_ISREG(wh_dentry->d_inode->i_mode)); + + err = do_unlink_wh(hdir, /*h_dir*/NULL, wh_dentry, dlgt); + if (!err && dentry) + au_set_dbwh(dentry, -1); + + AuTraceErr(err); + return err; +} + +static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh, + struct au_ndx *ndx) +{ + int err; + struct dentry *wh_dentry; + + LKTRTrace("%.*s/%.*s\n", AuDLNPair(h_parent), AuLNPair(wh)); + + /* au_test_h_perm() is already done */ + wh_dentry = au_lkup_one(wh->name, h_parent, wh->len, ndx); + if (IS_ERR(wh_dentry)) + err = PTR_ERR(wh_dentry); + else { + err = 0; + if (wh_dentry->d_inode && S_ISREG(wh_dentry->d_inode->i_mode)) + err = do_unlink_wh(/*hdir*/NULL, h_parent->d_inode, + wh_dentry, + au_ftest_ndx(ndx->flags, DLGT)); + dput(wh_dentry); + } + + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static void clean_wh(struct inode *h_dir, struct dentry *wh, + struct au_hinode *hdir, struct vfsub_args *vargs) +{ + int err; + + AuTraceEnter(); + + if (wh->d_inode) { + vfsub_args_reinit(vargs); + vfsub_ign_hinode(vargs, IN_DELETE, hdir); + err = vfsub_unlink(h_dir, wh, vargs); + if (unlikely(err)) + AuWarn("failed unlink %.*s (%d), ignored.\n", + AuDLNPair(wh), err); + } +} + +static void au_whdir_clean(struct inode *h_dir, struct dentry *dentry, + struct au_hinode *hdir, struct vfsub_args *vargs) +{ + int err; + + AuTraceEnter(); + + if (dentry->d_inode) { + vfsub_args_reinit(vargs); + vfsub_ign_hinode(vargs, IN_DELETE, hdir); + err = vfsub_rmdir(h_dir, dentry, vargs); + if (unlikely(err)) + AuWarn("failed rmdir %.*s (%d), ignored.\n", + AuDLNPair(dentry), err); + } +} + +static int test_linkable(struct inode *h_dir) +{ + if (h_dir->i_op && h_dir->i_op->link) + return 0; + return -ENOSYS; +} + +/* todo: should this mkdir be done in /sbin/mount.aufs script? */ +static int au_whdir(struct inode *h_dir, struct dentry *dentry, + struct au_hinode *hdir, struct vfsub_args *vargs) +{ + int err; + + err = -EEXIST; + if (!dentry->d_inode) { + int mode = S_IRWXU; + if (unlikely(au_test_nfs(dentry->d_sb))) + mode |= S_IXUGO; + vfsub_args_reinit(vargs); + vfsub_ign_hinode(vargs, IN_CREATE, hdir); + err = vfsub_mkdir(h_dir, dentry, mode, vargs); + } else if (S_ISDIR(dentry->d_inode->i_mode)) + err = 0; + else + AuErr("unknown %.*s exists\n", AuDLNPair(dentry)); + + return err; +} + +/* + * initialize the whiteout base file/dir for @br. + */ +int au_wh_init(struct dentry *h_root, struct au_branch *br, + struct vfsmount *nfsmnt, struct super_block *sb, + aufs_bindex_t bindex) +{ + int err, i; + struct inode *h_dir; + struct au_hin_ignore ign; + struct vfsub_args vargs; + struct au_hinode *hdir; + struct au_wbr *wbr = br->br_wbr; + static const struct qstr base_name[] = { + [AuBrWh_BASE] = { + .name = AUFS_WH_BASENAME, + .len = sizeof(AUFS_WH_BASENAME) - 1 + }, + [AuBrWh_PLINK] = { + .name = AUFS_WH_PLINKDIR, + .len = sizeof(AUFS_WH_PLINKDIR) - 1 + }, + [AuBrWh_TMP] = { + .name = AUFS_WH_TMPDIR, + .len = sizeof(AUFS_WH_TMPDIR) - 1 + } + }; + struct { + const struct qstr *name; + struct dentry *dentry; + } base[] = { + [AuBrWh_BASE] = { + .name = base_name + AuBrWh_BASE, + .dentry = NULL + }, + [AuBrWh_PLINK] = { + .name = base_name + AuBrWh_PLINK, + .dentry = NULL + }, + [AuBrWh_TMP] = { + .name = base_name + AuBrWh_TMP, + .dentry = NULL + } + }; + struct au_ndx ndx = { + .nfsmnt = nfsmnt, + .flags = 0, /* always no dlgt */ + .nd = NULL, + /* .br = NULL */ + }; + const unsigned int mnt_flags = au_mntflags(sb); + const int do_plink = au_opt_test(mnt_flags, PLINK); + const int do_hinotify = au_opt_test(mnt_flags, UDBA_INOTIFY); + + LKTRTrace("nfsmnt %p\n", nfsmnt); + WbrWhMustWriteLock(wbr); + SiMustWriteLock(sb); + h_dir = h_root->d_inode; + + for (i = 0; i < AuBrWh_Last; i++) { + /* doubly whiteouted */ + base[i].dentry = au_wh_lkup(h_root, (void *)base[i].name, &ndx); + err = PTR_ERR(base[i].dentry); + if (IS_ERR(base[i].dentry)) + goto out; + AuDebugOn(wbr + && wbr->wbr_wh[i] + && wbr->wbr_wh[i] != base[i].dentry); + } + + if (wbr) + for (i = 0; i < AuBrWh_Last; i++) { + dput(wbr->wbr_wh[i]); + wbr->wbr_wh[i] = NULL; + } + + err = 0; + hdir = NULL; + if (unlikely(bindex >= 0 && do_hinotify)) + hdir = au_hi(sb->s_root->d_inode, bindex); + vfsub_args_init(&vargs, &ign, au_test_dlgt(mnt_flags), 0); + + switch (br->br_perm) { + case AuBrPerm_RR: + case AuBrPerm_RO: + case AuBrPerm_RRWH: + case AuBrPerm_ROWH: + clean_wh(h_dir, base[AuBrWh_BASE].dentry, hdir, &vargs); + au_whdir_clean(h_dir, base[AuBrWh_PLINK].dentry, hdir, &vargs); + au_whdir_clean(h_dir, base[AuBrWh_TMP].dentry, hdir, &vargs); + break; + + case AuBrPerm_RWNoLinkWH: + clean_wh(h_dir, base[AuBrWh_BASE].dentry, hdir, &vargs); + if (do_plink) { + err = test_linkable(h_dir); + if (unlikely(err)) + goto out_nolink; + + err = au_whdir(h_dir, base[AuBrWh_PLINK].dentry, hdir, + &vargs); + if (unlikely(err)) + goto out_err; + wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry); + } else + au_whdir_clean(h_dir, base[AuBrWh_PLINK].dentry, hdir, + &vargs); + err = au_whdir(h_dir, base[AuBrWh_TMP].dentry, hdir, &vargs); + if (unlikely(err)) + goto out_err; + wbr->wbr_tmp = dget(base[AuBrWh_TMP].dentry); + break; + + case AuBrPerm_RW: + /* + * for the moment, aufs supports the branch filesystem + * which does not support link(2). + * testing on FAT which does not support i_op->setattr() fully + * either, copyup failed. + * finally, such filesystem will not be used as the writable + * branch. + */ + err = test_linkable(h_dir); + if (unlikely(err)) + goto out_nolink; + + err = -EEXIST; + /* + * todo: should this create be done + * in /sbin/mount.aufs script? + */ + if (!base[AuBrWh_BASE].dentry->d_inode) { + vfsub_args_reinit(&vargs); + vfsub_ign_hinode(&vargs, IN_CREATE, hdir); + err = au_h_create(h_dir, base[AuBrWh_BASE].dentry, + WH_MASK, &vargs, /*nd*/NULL, nfsmnt); + } + else if (S_ISREG(base[AuBrWh_BASE].dentry->d_inode->i_mode)) + err = 0; + else + AuErr("unknown %.*s/%.*s exists\n", + AuDLNPair(h_root), + AuDLNPair(base[AuBrWh_BASE].dentry)); + if (unlikely(err)) + goto out_err; + + if (do_plink) { + err = au_whdir(h_dir, base[AuBrWh_PLINK].dentry, hdir, + &vargs); + if (unlikely(err)) + goto out_err; + wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry); + } else + au_whdir_clean(h_dir, base[AuBrWh_PLINK].dentry, hdir, + &vargs); + wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry); + + err = au_whdir(h_dir, base[AuBrWh_TMP].dentry, hdir, &vargs); + if (unlikely(err)) + goto out_err; + wbr->wbr_tmp = dget(base[AuBrWh_TMP].dentry); + break; + + default: + BUG(); + } + + out: + for (i = 0; i < AuBrWh_Last; i++) + dput(base[i].dentry); + AuTraceErr(err); + return err; + out_nolink: + AuErr("%.*s doesn't support link(2), use noplink and rw+nolwh\n", + AuDLNPair(h_root)); + goto out; + out_err: + AuErr("an error(%d) on the writable branch %.*s(%s)\n", + err, AuDLNPair(h_root), au_sbtype(h_root->d_sb)); + goto out; +} + +struct reinit_br_wh { + struct super_block *sb; + struct au_branch *br; +}; + +static void reinit_br_wh(void *arg) +{ + int err; + struct reinit_br_wh *a = arg; + struct au_wbr *wbr; + struct inode *h_dir, *dir; + struct dentry *h_root; + aufs_bindex_t bindex; + struct au_hin_ignore ign; + struct vfsub_args vargs; + + AuTraceEnter(); + AuDebugOn(current->fsuid); + + err = 0; + wbr = a->br->br_wbr; + /* big aufs lock */ + si_noflush_write_lock(a->sb); + if (unlikely(!au_br_writable(a->br->br_perm))) + goto out; + bindex = au_br_index(a->sb, a->br->br_id); + if (unlikely(bindex < 0)) + goto out; + + AuDebugOn(!wbr); + AuDebugOn(!wbr->wbr_whbase || !wbr->wbr_whbase->d_inode); + + dir = a->sb->s_root->d_inode; + ii_read_lock_parent(dir); + h_root = dget_parent(wbr->wbr_whbase); + h_dir = h_root->d_inode; + AuDebugOn(!h_dir->i_op || !h_dir->i_op->link); + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); + wbr_wh_write_lock(wbr); + if (!au_verify_parent(wbr->wbr_whbase, h_dir)) { + vfsub_args_init(&vargs, &ign, /*dlgt*/0, 0); + vfsub_ign_hinode(&vargs, IN_DELETE, au_hi(dir, bindex)); + err = vfsub_unlink(h_dir, wbr->wbr_whbase, &vargs); + } else { + AuWarn("%.*s is moved, ignored\n", AuDLNPair(wbr->wbr_whbase)); + err = 0; + } + dput(wbr->wbr_whbase); + wbr->wbr_whbase = NULL; + if (!err) + err = au_wh_init(h_root, a->br, au_do_nfsmnt(a->br->br_mnt), + a->sb, bindex); + wbr_wh_write_unlock(wbr); + mutex_unlock(&h_dir->i_mutex); + dput(h_root); + ii_read_unlock(dir); + + out: + if (wbr) + atomic_dec_return(&wbr->wbr_wh_running); + au_br_put(a->br); + au_nwt_done(&au_sbi(a->sb)->si_nowait); + si_write_unlock(a->sb); + kfree(arg); + if (unlikely(err)) + AuIOErr("err %d\n", err); +} + +static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br) +{ + int do_dec, wkq_err; + struct reinit_br_wh *arg; + + AuTraceEnter(); + AuDebugOn(!br->br_wbr); + + do_dec = 1; + if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1) + goto out; + + /* ignore ENOMEM */ + arg = kmalloc(sizeof(*arg), GFP_NOFS); + if (arg) { + /* + * dec(wh_running), kfree(arg) and au_br_put() + * in reinit function + */ + arg->sb = sb; + arg->br = br; + au_br_get(br); + wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*dlgt*/0); + if (unlikely(wkq_err)) { + atomic_dec_return(&br->br_wbr->wbr_wh_running); + au_br_put(br); + kfree(arg); + } + do_dec = 0; + } + + out: + if (do_dec) + atomic_dec_return(&br->br_wbr->wbr_wh_running); +} + +/* + * create the whiteout @wh. + */ +static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex, + struct dentry *wh, struct inode *dir) +{ + int err, dlgt; + struct au_branch *br; + struct au_wbr *wbr; + struct dentry *h_parent; + struct inode *h_dir; + struct au_hin_ignore ign; + struct vfsub_args vargs; + + LKTRTrace("%.*s\n", AuDLNPair(wh)); + h_parent = wh->d_parent; /* dir inode is locked */ + h_dir = h_parent->d_inode; + IMustLock(h_dir); + br = au_sbr(sb, bindex); + wbr = br->br_wbr; + AuDebugOn(!wbr); + + dlgt = !!au_test_dlgt(au_mntflags(sb)); + wbr_wh_read_lock(wbr); + if (wbr->wbr_whbase) { + vfsub_args_init(&vargs, &ign, dlgt, 0); + if (unlikely(dir)) + vfsub_ign_hinode(&vargs, IN_CREATE, au_hi(dir, bindex)); + err = vfsub_link(wbr->wbr_whbase, h_dir, wh, &vargs); + if (!err || err != -EMLINK) + goto out; + + /* link count full. re-initialize br_whbase. */ + kick_reinit_br_wh(sb, br); + } + + /* return this error in this context */ + vfsub_args_init(&vargs, &ign, dlgt, 0); + if (unlikely(dir)) + vfsub_ign_hinode(&vargs, IN_CREATE, au_hi(dir, bindex)); + err = au_h_create(h_dir, wh, WH_MASK, &vargs, /*nd*/NULL, + au_do_nfsmnt(br->br_mnt)); + + out: + wbr_wh_read_unlock(wbr); + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +/* + * create or remove the diropq. + */ +static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex, + unsigned int flags) +{ + struct dentry *opq_dentry, *h_dentry; + struct inode *h_dir; + int err, dlgt; + struct super_block *sb; + struct au_ndx ndx = { + .flags = 0, + .nd = NULL, + /* .br = NULL */ + }; + + LKTRTrace("%.*s, bindex %d, flags 0x%x\n", + AuDLNPair(dentry), bindex, flags); + h_dentry = au_h_dptr(dentry, bindex); + AuDebugOn(!h_dentry); + h_dir = h_dentry->d_inode; + AuDebugOn(!h_dir || !S_ISDIR(h_dir->i_mode)); + + /* already checked by au_test_h_perm(). */ + sb = dentry->d_sb; + ndx.nfsmnt = au_nfsmnt(sb, bindex); + dlgt = 0; + if (unlikely(au_ftest_diropq(flags, DLGT))) { + dlgt = 1; + au_fset_ndx(ndx.flags, DLGT); + } + opq_dentry = au_lkup_one(diropq_name.name, h_dentry, diropq_name.len, + &ndx); + if (IS_ERR(opq_dentry)) + goto out; + + if (au_ftest_diropq(flags, CREATE)) { + AuDebugOn(opq_dentry->d_inode); + err = link_or_create_wh(dentry->d_sb, bindex, opq_dentry, + dentry->d_inode); + if (!err) { + au_set_dbdiropq(dentry, bindex); + goto out; /* success */ + } + } else { + AuDebugOn(/* !S_ISDIR(dentry->d_inode->i_mode) + * || */!opq_dentry->d_inode); + err = do_unlink_wh(au_hi(dentry->d_inode, bindex), + /*h_dir*/NULL, opq_dentry, dlgt); + if (!err) + au_set_dbdiropq(dentry, -1); + } + dput(opq_dentry); + opq_dentry = ERR_PTR(err); + + out: + AuTraceErrPtr(opq_dentry); + return opq_dentry; +} + +struct do_diropq_args { + struct dentry **errp; + struct dentry *dentry; + aufs_bindex_t bindex; + unsigned int flags; +}; + +static void call_do_diropq(void *args) +{ + struct do_diropq_args *a = args; + *a->errp = do_diropq(a->dentry, a->bindex, a->flags); +} + +struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex, + unsigned int flags) +{ + struct dentry *diropq, *h_dentry; + + LKTRTrace("%.*s, bindex %d, flags 0x%x\n", + AuDLNPair(dentry), bindex, flags); + + h_dentry = au_h_dptr(dentry, bindex); + if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE, + au_ftest_diropq(flags, DLGT))) + diropq = do_diropq(dentry, bindex, flags); + else { + int wkq_err; + struct do_diropq_args args = { + .errp = &diropq, + .dentry = dentry, + .bindex = bindex, + .flags = flags + }; + wkq_err = au_wkq_wait(call_do_diropq, &args, /*dlgt*/0); + if (unlikely(wkq_err)) + diropq = ERR_PTR(wkq_err); + } + + AuTraceErrPtr(diropq); + return diropq; +} + +/* ---------------------------------------------------------------------- */ + +/* + * lookup whiteout dentry. + * @h_parent: hidden parent dentry which must exist and be locked + * @base_name: name of dentry which will be whiteouted + * returns dentry for whiteout. + */ +struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name, + struct au_ndx *ndx) +{ + int err; + struct qstr wh_name; + struct dentry *wh_dentry; + + LKTRTrace("%.*s/%.*s\n", AuDLNPair(h_parent), AuLNPair(base_name)); + + err = au_wh_name_alloc(base_name->name, base_name->len, &wh_name); + wh_dentry = ERR_PTR(err); + if (!err) { + /* do not superio. */ + wh_dentry = au_lkup_one(wh_name.name, h_parent, + wh_name.len, ndx); + au_wh_name_free(&wh_name); + } + AuTraceErrPtr(wh_dentry); + return wh_dentry; +} + +/* + * link/create a whiteout for @dentry on @bindex. + */ +struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex, + struct dentry *h_parent, struct au_ndx *ndx) +{ + struct dentry *wh_dentry; + struct inode *dir; + int err; + struct super_block *sb; + + LKTRTrace("%.*s/%.*s on b%d\n", AuDLNPair(h_parent), + AuDLNPair(dentry), bindex); + + sb = dentry->d_sb; + wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, ndx); + if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) { + dir = dentry->d_parent->d_inode; /* dir is locked */ + IMustLock(dir); + err = link_or_create_wh(sb, bindex, wh_dentry, dir); + if (!err) + au_set_dbwh(dentry, bindex); + else { + dput(wh_dentry); + wh_dentry = ERR_PTR(err); + } + } + + AuTraceErrPtr(wh_dentry); + return wh_dentry; +} + +/* ---------------------------------------------------------------------- */ + +/* Delete all whiteouts in this directory on branch bindex. */ +static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist, + aufs_bindex_t bindex, struct au_ndx *ndx) +{ + int err, i; + struct qstr wh_name; + char *p; + struct inode *h_inode; + struct hlist_head *head; + struct au_vdir_wh *tpos; + struct hlist_node *pos; + struct au_vdir_destr *str; + + LKTRTrace("%.*s\n", AuDLNPair(h_dentry)); + h_inode = h_dentry->d_inode; + AuDebugOn(IS_RDONLY(h_inode)); + + err = -ENOMEM; + p = __getname(); + wh_name.name = p; + if (unlikely(!wh_name.name)) + goto out; + memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); + p += AUFS_WH_PFX_LEN; + + /* already checked by au_test_h_perm(). */ + err = 0; + for (i = 0; !err && i < AuSize_NHASH; i++) { + head = whlist->heads + i; + hlist_for_each_entry(tpos, pos, head, wh_hash) { + if (tpos->wh_bindex != bindex) + continue; + str = &tpos->wh_str; + if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) { + memcpy(p, str->name, str->len); + wh_name.len = AUFS_WH_PFX_LEN + str->len; + err = unlink_wh_name(h_dentry, &wh_name, ndx); + if (!err) + continue; + break; + } + AuIOErr("whiteout name too long %.*s\n", + str->len, str->name); + err = -EIO; + break; + } + } + __putname(wh_name.name); + + out: + AuTraceErr(err); + return err; +} + +struct del_wh_children_args { + int *errp; + struct dentry *h_dentry; + struct au_nhash *whlist; + aufs_bindex_t bindex; + struct au_ndx *ndx; +}; + +static void call_del_wh_children(void *args) +{ + struct del_wh_children_args *a = args; + *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->ndx); +} + +/* ---------------------------------------------------------------------- */ + +/* + * rmdir the whiteouted temporary named dir @h_dentry. + * @whlist: whiteouted children. + */ +int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex, + struct dentry *wh_dentry, struct au_nhash *whlist) +{ + int err, dlgt; + struct inode *wh_inode, *h_dir; + struct super_block *sb; + unsigned int mnt_flags; + struct au_hin_ignore ign; + struct vfsub_args vargs; + struct au_ndx ndx = { + .flags = 0, + .nd = NULL, + /* .br = NULL */ + }; + + LKTRTrace("i%lu, %.*s, b%d\n", + dir->i_ino, AuDLNPair(wh_dentry), bindex); + /* IMustLock(dir); */ + IiMustAnyLock(dir); + h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */ + IMustLock(h_dir); + + sb = dir->i_sb; + mnt_flags = au_mntflags(sb); + dlgt = !!au_test_dlgt(mnt_flags); + if (unlikely(dlgt)) + au_fset_ndx(ndx.flags, DLGT); + ndx.nfsmnt = au_nfsmnt(sb, bindex); + wh_inode = wh_dentry->d_inode; + mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD); + + /* + * someone else might change some whiteouts while we were sleeping. + * it means this whlist may have an obsoleted entry. + */ + if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE, dlgt)) + err = del_wh_children(wh_dentry, whlist, bindex, &ndx); + else { + int wkq_err; + /* ugly */ + unsigned int flags = ndx.flags; + struct del_wh_children_args args = { + .errp = &err, + .h_dentry = wh_dentry, + .whlist = whlist, + .bindex = bindex, + .ndx = &ndx + }; + + ndx.flags = 0; + wkq_err = au_wkq_wait(call_del_wh_children, &args, /*dlgt*/0); + if (unlikely(wkq_err)) + err = wkq_err; + ndx.flags = flags; + } + mutex_unlock(&wh_inode->i_mutex); + + if (!err) { + vfsub_args_init(&vargs, &ign, dlgt, 0); + vfsub_ign_hinode(&vargs, IN_DELETE, au_hi(dir, bindex)); + err = vfsub_rmdir(h_dir, wh_dentry, &vargs); + /* d_drop(h_dentry); */ + } + + if (!err) { + if (au_ibstart(dir) == bindex) { + au_cpup_attr_timesizes(dir); + /* au_cpup_attr_nlink(dir); */ + drop_nlink(dir); + } + return 0; /* success */ + } + + AuWarn("failed removing %.*s(%d), ignored\n", + AuDLNPair(wh_dentry), err); + return err; +} + +static void au_whtmp_rmdir_free_args(struct au_whtmp_rmdir_args *args) +{ + au_nhash_fin(&args->whlist); + dput(args->wh_dentry); + iput(args->dir); + kfree(args); +} + +static void call_rmdir_whtmp(void *args) +{ + int err; + struct au_whtmp_rmdir_args *a = args; + struct super_block *sb; + struct dentry *h_parent; + struct inode *h_dir; + + LKTRTrace("%.*s, b%d, dir i%lu\n", + AuDLNPair(a->wh_dentry), a->bindex, a->dir->i_ino); + + /* rmdir by nfsd may cause deadlock with this i_mutex */ + /* mutex_lock(&a->dir->i_mutex); */ + sb = a->dir->i_sb; + si_noflush_read_lock(sb); + err = au_test_ro(sb, a->bindex, NULL); + if (unlikely(err)) + goto out; + + err = -EIO; + ii_write_lock_parent(a->dir); + h_parent = dget_parent(a->wh_dentry); + h_dir = h_parent->d_inode; + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); + if (!au_verify_parent(a->wh_dentry, h_dir)) + err = au_whtmp_rmdir(a->dir, a->bindex, a->wh_dentry, + &a->whlist); + mutex_unlock(&h_dir->i_mutex); + dput(h_parent); + ii_write_unlock(a->dir); + + out: + /* mutex_unlock(&a->dir->i_mutex); */ + au_nwt_done(&au_sbi(sb)->si_nowait); + si_read_unlock(sb); + au_whtmp_rmdir_free_args(a); + if (unlikely(err)) + AuIOErr("err %d\n", err); +} + +void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex, + struct dentry *wh_dentry, struct au_nhash *whlist, + struct au_whtmp_rmdir_args *args) +{ + int wkq_err; + + LKTRTrace("%.*s\n", AuDLNPair(wh_dentry)); + IMustLock(dir); + + /* all post-process will be done in do_rmdir_whtmp(). */ + args->dir = au_igrab(dir); + args->bindex = bindex; + args->wh_dentry = dget(wh_dentry); + au_nhash_init(&args->whlist); + au_nhash_move(&args->whlist, whlist); + wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, dir->i_sb, /*dlgt*/0); + if (unlikely(wkq_err)) { + AuWarn("rmdir error %.*s (%d), ignored\n", + AuDLNPair(wh_dentry), wkq_err); + au_whtmp_rmdir_free_args(args); + } +} --- linux-2.6.28.orig/ubuntu/aufs/hinode.h +++ linux-2.6.28/ubuntu/aufs/hinode.h @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * lower (branch filesystem) inode and setting inotify + * + * $Id: hinode.h,v 1.9 2008/08/25 01:49:59 sfjro Exp $ + */ + +#ifndef __AUFS_HINODE_H__ +#define __AUFS_HINODE_H__ + +#ifdef __KERNEL__ + +#include +#include +#include +#include "super.h" +#include "vfsub.h" + +/* ---------------------------------------------------------------------- */ + +struct au_hinotify { +#ifdef CONFIG_AUFS_HINOTIFY + spinlock_t hin_ignore_lock; + struct list_head hin_ignore_list; + + struct inotify_watch hin_watch; + struct inode *hin_aufs_inode; /* no get/put */ +#endif +}; + +struct au_hinode { + struct inode *hi_inode; + aufs_bindex_t hi_id; +#ifdef CONFIG_AUFS_HINOTIFY + struct au_hinotify *hi_notify; +#endif + + /* reference to the copied-up whiteout with get/put */ + struct dentry *hi_whdentry; +}; + +struct au_hin_ignore { +#ifdef CONFIG_AUFS_HINOTIFY + struct list_head ign_list; + + pid_t ign_pid; + __u32 ign_events, ign_handled; + struct au_hinode *ign_hinode; +#endif +}; + +/* ---------------------------------------------------------------------- */ + +#ifdef CONFIG_AUFS_HINOTIFY +/* inotify events */ +static const __u32 AuInMask = (IN_MOVE | IN_DELETE | IN_CREATE + /* | IN_ACCESS */ + | IN_MODIFY | IN_ATTRIB + /* | IN_DELETE_SELF | IN_MOVE_SELF */ + ); + +static inline +void au_hin_init(struct au_hinode *hinode, struct au_hinotify *val) +{ + hinode->hi_notify = val; +} + +/* hinotify.c */ +int au_hin_alloc(struct au_hinode *hinode, struct inode *inode, + struct inode *h_inode); +void au_hin_free(struct au_hinode *hinode); +void au_hin_ctl(struct au_hinode *hinode, const __u32 mask); +void au_reset_hinotify(struct inode *inode, unsigned int flags); + +int au_hin_verify_gen(struct dentry *dentry); + +int __init au_inotify_init(void); +void au_inotify_fin(void); + +static inline void au_hin_suspend(struct au_hinode *hinode) +{ + au_hin_ctl(hinode, 0); +} + +static inline void au_hin_resume(struct au_hinode *hinode) +{ + au_hin_ctl(hinode, AuInMask); +} + +#else + +static inline +void au_hin_init(struct au_hinode *hinode, struct au_hinotify *val) +{ + /* empty */ +} + +static inline +int au_hin_alloc(struct au_hinode *hinode, struct inode *inode, + struct inode *h_inode) +{ + return -EOPNOTSUPP; +} + +static inline void au_hin_free(struct au_hinode *hinode) +{ + /* nothing */ +} + +static inline void au_reset_hinotify(struct inode *inode, unsigned int flags) +{ + /* nothing */ +} + +static inline int au_hin_verify_gen(struct dentry *dentry) +{ + return 0; +} + +static inline int au_inotify_init(void) +{ + return 0; +} + +#define au_inotify_fin() do {} while (0) + +static inline void au_hin_suspend(struct au_hinode *hinode) +{ + /* empty */ +} + +static inline void au_hin_resume(struct au_hinode *hinode) +{ + /* empty */ +} +#endif /* CONFIG_AUFS_HINOTIFY */ + +#if defined(CONFIG_AUFS_HINOTIFY) && defined(CONFIG_AUFS_DEBUG) +static inline void au_hin_list_del(struct list_head *e) +{ + list_del_init(e); +} + +void au_dbg_hin_list(struct vfsub_args *vargs); +#else +static inline void au_hin_list_del(struct list_head *e) +{ + list_del(e); +} + +static inline void au_dbg_hin_list(struct vfsub_args *vargs) +{ + /* empty */ +} +#endif /* CONFIG_AUFS_DEBUG */ + +/* ---------------------------------------------------------------------- */ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_HINODE_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/sysrq.c +++ linux-2.6.28/ubuntu/aufs/sysrq.c @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * magic sysrq hanlder + * + * $Id: sysrq.c,v 1.10 2008/09/08 02:40:48 sfjro Exp $ + */ + +#include +#include +#include +/* #include */ +#include "aufs.h" + +static void sysrq_sb(struct super_block *sb) +{ + char *plevel; + struct inode *i; + + plevel = au_plevel; + au_plevel = KERN_WARNING; + au_debug_on(); + + pr_warning("si=%lx\n", au_si_mask ^ (unsigned long)au_sbi(sb)); + pr_warning(AUFS_NAME ": superblock\n"); + au_dpri_sb(sb); + pr_warning(AUFS_NAME ": root dentry\n"); + au_dpri_dentry(sb->s_root); + pr_warning(AUFS_NAME ": root inode\n"); + au_dpri_inode(sb->s_root->d_inode); + pr_warning(AUFS_NAME ": isolated inode\n"); + list_for_each_entry(i, &sb->s_inodes, i_sb_list) + if (list_empty(&i->i_dentry)) + au_dpri_inode(i); + + au_plevel = plevel; + au_debug_off(); +} + +/* ---------------------------------------------------------------------- */ + +/* module parameter */ +static char *aufs_sysrq_key = "a"; +module_param_named(sysrq, aufs_sysrq_key, charp, S_IRUGO); +MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME); + +static void au_sysrq(int key, struct tty_struct *tty) +{ + struct kobject *kobj; + struct au_sbinfo *sbinfo; + + /* spin_lock(&au_kset->list_lock); */ + list_for_each_entry(kobj, &au_kset->list, entry) { + sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); + sysrq_sb(sbinfo->si_sb); + } + /* spin_unlock(&au_kset->list_lock); */ +} + +static struct sysrq_key_op au_sysrq_op = { + .handler = au_sysrq, + .help_msg = "Aufs", + .action_msg = "Aufs", + /* todo: test mask? */ + .enable_mask = SYSRQ_ENABLE_DUMP +}; + +/* ---------------------------------------------------------------------- */ + +int __init au_sysrq_init(void) +{ + int err; + char key; + + err = -1; + key = *aufs_sysrq_key; + if ('a' <= key && key <= 'z') + err = register_sysrq_key(key, &au_sysrq_op); + if (unlikely(err)) + AuErr("err %d, sysrq=%c\n", err, key); + return err; +} + +void au_sysrq_fin(void) +{ + int err; + err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op); + if (unlikely(err)) + AuErr("err %d (ignored)\n", err); +} --- linux-2.6.28.orig/ubuntu/aufs/xino.c +++ linux-2.6.28/ubuntu/aufs/xino.c @@ -0,0 +1,1259 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * external inode number translation table and bitmap + * + * $Id: xino.c,v 1.16 2008/09/15 03:16:30 sfjro Exp $ + */ + +#include +#include "aufs.h" + +/* ---------------------------------------------------------------------- */ + +ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size, + loff_t *pos) +{ + ssize_t err; + mm_segment_t oldfs; + + LKTRTrace("%.*s, sz %lu, *pos %lld\n", + AuDLNPair(file->f_dentry), (unsigned long)size, *pos); + + oldfs = get_fs(); + set_fs(KERNEL_DS); + do { + /* todo: signal_pending? */ + err = func(file, (char __user *)buf, size, pos); + } while (err == -EAGAIN || err == -EINTR); + set_fs(oldfs); + +#if 0 /* reserved for future use */ + if (err > 0) + fsnotify_access(file->f_dentry); +#endif + + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *buf, + size_t size, loff_t *pos) +{ + ssize_t err; + mm_segment_t oldfs; + + lockdep_off(); + oldfs = get_fs(); + set_fs(KERNEL_DS); + do { + /* todo: signal_pending? */ + err = func(file, (const char __user *)buf, size, pos); + } while (err == -EAGAIN || err == -EINTR); + set_fs(oldfs); + lockdep_on(); + + if (err >= 0) + au_update_fuse_h_inode(file->f_vfsmnt, file->f_dentry); + /*ignore*/ + +#if 0 /* reserved for future use */ + if (err > 0) + fsnotify_modify(file->f_dentry); +#endif + + AuTraceErr(err); + return err; +} + +struct do_xino_fwrite_args { + ssize_t *errp; + au_writef_t func; + struct file *file; + void *buf; + size_t size; + loff_t *pos; +}; + +static void call_do_xino_fwrite(void *args) +{ + struct do_xino_fwrite_args *a = args; + *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos); +} + +ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size, + loff_t *pos) +{ + ssize_t err; + + LKTRTrace("%.*s, sz %lu, *pos %lld\n", + AuDLNPair(file->f_dentry), (unsigned long)size, *pos); + + /* todo: signal block and no wkq? */ + /* + * it breaks RLIMIT_FSIZE and normal user's limit, + * users should care about quota and real 'filesystem full.' + */ + if (!au_test_wkq(current)) { + int wkq_err; + struct do_xino_fwrite_args args = { + .errp = &err, + .func = func, + .file = file, + .buf = buf, + .size = size, + .pos = pos + }; + wkq_err = au_wkq_wait(call_do_xino_fwrite, &args, /*dlgt*/0); + if (unlikely(wkq_err)) + err = wkq_err; + } else + err = do_xino_fwrite(func, file, buf, size, pos); + + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct xino_do_trunc_args { + struct super_block *sb; + struct au_branch *br; +}; + +static void xino_do_trunc(void *_args) +{ + struct xino_do_trunc_args *args = _args; + struct super_block *sb; + aufs_bindex_t bindex; + int err; + struct file *file; + struct inode *dir; + struct au_sbinfo *sbinfo; + struct kobject *kobj; + + err = 0; + sb = args->sb; + dir = sb->s_root->d_inode; + si_noflush_write_lock(sb); + ii_read_lock_parent(dir); + bindex = au_br_index(sb, args->br->br_id); + AuDebugOn(bindex < 0); + err = au_xino_trunc(sb, bindex); + if (unlikely(err)) + goto out; + + file = args->br->br_xino.xi_file; + au_update_fuse_h_inode(args->br->br_mnt, file->f_dentry); /*ignore*/ + if (file->f_dentry->d_inode->i_blocks >= args->br->br_xino_upper) + args->br->br_xino_upper += AUFS_XINO_TRUNC_STEP; + + out: + ii_read_unlock(dir); + if (unlikely(err)) + AuWarn("err b%d, (%d)\n", bindex, err); + atomic_dec_return(&args->br->br_xino_running); + au_br_put(args->br); + sbinfo = au_sbi(sb); + kobj = &sbinfo->si_kobj; + au_nwt_done(&sbinfo->si_nowait); + si_write_unlock(sb); + kobject_put(kobj); + kfree(args); +} + +static void xino_try_trunc(struct super_block *sb, struct au_branch *br) +{ + struct xino_do_trunc_args *args; + struct au_sbinfo *sbinfo; + struct file *file = br->br_xino.xi_file; + int wkq_err; + + au_update_fuse_h_inode(br->br_mnt, file->f_dentry); /*ignore*/ + if (file->f_dentry->d_inode->i_blocks < br->br_xino_upper) + return; + if (atomic_inc_return(&br->br_xino_running) > 1) + goto out; + + /* lock and kfree() will be called in trunc_xino() */ + args = kmalloc(sizeof(*args), GFP_NOFS); + if (unlikely(!args)) { + AuErr1("no memory\n"); + goto out_args; + } + + sbinfo = au_sbi(sb); + kobject_get(&sbinfo->si_kobj); + au_br_get(br); + args->sb = sb; + args->br = br; + wkq_err = au_wkq_nowait(xino_do_trunc, args, sb, /*dlgt*/0); + if (!wkq_err) + return; /* success */ + + AuErr("wkq %d\n", wkq_err); + au_br_put(br); + kobject_put(&sbinfo->si_kobj); + + out_args: + kfree(args); + out: + atomic_dec_return(&br->br_xino_running); +} + +/* ---------------------------------------------------------------------- */ + +static int au_xino_do_write(au_writef_t write, struct file *file, + ino_t h_ino, struct au_xino_entry *xinoe) +{ + loff_t pos; + ssize_t sz; + + AuTraceEnter(); + + pos = h_ino; + if (unlikely(Au_LOFF_MAX / sizeof(*xinoe) - 1 < pos)) { + AuIOErr1("too large hi%lu\n", (unsigned long)h_ino); + return -EFBIG; + } + pos *= sizeof(*xinoe); + sz = xino_fwrite(write, file, xinoe, sizeof(*xinoe), &pos); + if (sz == sizeof(*xinoe)) + return 0; /* success */ + + AuIOErr("write failed (%ld)\n", (long)sz); + return -EIO; +} + +/* + * write @ino to the xinofile for the specified branch{@sb, @bindex} + * at the position of @_ino. + * when @ino is zero, it is written to the xinofile and means no entry. + */ +int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, + struct au_xino_entry *xinoe) +{ + int err; + struct file *file; + struct au_branch *br; + unsigned int mnt_flags; + + LKTRTrace("b%d, hi%lu, i%lu\n", + bindex, (unsigned long)h_ino, (unsigned long)xinoe->ino); + BUILD_BUG_ON(sizeof(long long) != sizeof(Au_LOFF_MAX) + || ((loff_t)-1) > 0); + + mnt_flags = au_mntflags(sb); + if (unlikely(!au_opt_test_xino(mnt_flags))) + return 0; + + br = au_sbr(sb, bindex); + file = br->br_xino.xi_file; + AuDebugOn(!file); + + err = au_xino_do_write(au_sbi(sb)->si_xwrite, file, h_ino, xinoe); + if (!err) { + if (unlikely(au_opt_test(mnt_flags, TRUNC_XINO) + && au_test_trunc_xino(br->br_mnt->mnt_sb))) + xino_try_trunc(sb, br); + return 0; /* success */ + } + + AuIOErr("write failed (%d)\n", err); + return -EIO; +} + +/* ---------------------------------------------------------------------- */ + +static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE; +static ino_t xib_calc_ino(unsigned long pindex, int bit) +{ + ino_t ino; + + AuDebugOn(bit < 0 || page_bits <= bit); + ino = AUFS_FIRST_INO + pindex * page_bits + bit; + return ino; +} + +static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit) +{ + AuDebugOn(ino < AUFS_FIRST_INO); + ino -= AUFS_FIRST_INO; + *pindex = ino / page_bits; + *bit = ino % page_bits; +} + +static int xib_pindex(struct super_block *sb, unsigned long pindex) +{ + int err; + struct au_sbinfo *sbinfo; + loff_t pos; + ssize_t sz; + struct file *xib; + unsigned long *p; + + LKTRTrace("pindex %lu\n", pindex); + sbinfo = au_sbi(sb); + MtxMustLock(&sbinfo->si_xib_mtx); + AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE + || !au_opt_test_xino(sbinfo->si_mntflags)); + + if (pindex == sbinfo->si_xib_last_pindex) + return 0; + + xib = sbinfo->si_xib; + p = sbinfo->si_xib_buf; + pos = sbinfo->si_xib_last_pindex; + pos *= PAGE_SIZE; + sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos); + if (unlikely(sz != PAGE_SIZE)) + goto out; + + pos = pindex; + pos *= PAGE_SIZE; + if (i_size_read(xib->f_dentry->d_inode) >= pos + PAGE_SIZE) + sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos); + else { + memset(p, 0, PAGE_SIZE); + sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos); + } + if (sz == PAGE_SIZE) { + sbinfo->si_xib_last_pindex = pindex; + return 0; /* success */ + } + + out: + AuIOErr1("write failed (%ld)\n", (long)sz); + err = sz; + if (sz >= 0) + err = -EIO; + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +int au_xino_write0(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, + ino_t ino) +{ + int err, bit; + unsigned long pindex; + struct au_sbinfo *sbinfo; + struct au_xino_entry xinoe = { + .ino = 0 + }; + + LKTRTrace("b%d, hi%lu, i%lu\n", + bindex, (unsigned long)h_ino, (unsigned long)ino); + + if (unlikely(!au_opt_test_xino(au_mntflags(sb)))) + return 0; + + err = 0; + sbinfo = au_sbi(sb); + if (unlikely(ino)) { + AuDebugOn(ino < AUFS_FIRST_INO); + xib_calc_bit(ino, &pindex, &bit); + AuDebugOn(page_bits <= bit); + mutex_lock(&sbinfo->si_xib_mtx); + err = xib_pindex(sb, pindex); + if (!err) { + clear_bit(bit, sbinfo->si_xib_buf); + sbinfo->si_xib_next_bit = bit; + } + mutex_unlock(&sbinfo->si_xib_mtx); + } + + if (!err) + err = au_xino_write(sb, bindex, h_ino, &xinoe); + return err; +} + +ino_t au_xino_new_ino(struct super_block *sb) +{ + ino_t ino; + struct au_sbinfo *sbinfo; + int free_bit, err; + unsigned long *p, pindex, ul, pend; + struct file *file; + + AuTraceEnter(); + + if (unlikely(!au_opt_test_xino(au_mntflags(sb)))) + return iunique(sb, AUFS_FIRST_INO); + + sbinfo = au_sbi(sb); + mutex_lock(&sbinfo->si_xib_mtx); + p = sbinfo->si_xib_buf; + free_bit = sbinfo->si_xib_next_bit; + if (free_bit < page_bits && !test_bit(free_bit, p)) + goto out; /* success */ + free_bit = find_first_zero_bit(p, page_bits); + if (free_bit < page_bits) + goto out; /* success */ + + pindex = sbinfo->si_xib_last_pindex; + for (ul = pindex - 1; ul < ULONG_MAX; ul--) { + err = xib_pindex(sb, ul); + if (unlikely(err)) + goto out_err; + free_bit = find_first_zero_bit(p, page_bits); + if (free_bit < page_bits) + goto out; /* success */ + } + + file = sbinfo->si_xib; + pend = i_size_read(file->f_dentry->d_inode) / PAGE_SIZE; + for (ul = pindex + 1; ul <= pend; ul++) { + err = xib_pindex(sb, ul); + if (unlikely(err)) + goto out_err; + free_bit = find_first_zero_bit(p, page_bits); + if (free_bit < page_bits) + goto out; /* success */ + } + BUG(); + + out: + set_bit(free_bit, p); + sbinfo->si_xib_next_bit++; + pindex = sbinfo->si_xib_last_pindex; + mutex_unlock(&sbinfo->si_xib_mtx); + ino = xib_calc_ino(pindex, free_bit); + LKTRTrace("i%lu\n", (unsigned long)ino); + return ino; + out_err: + mutex_unlock(&sbinfo->si_xib_mtx); + LKTRTrace("i0\n"); + return 0; +} + +/* + * read @ino from xinofile for the specified branch{@sb, @bindex} + * at the position of @h_ino. + * if @ino does not exist and @do_new is true, get new one. + */ +int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, + struct au_xino_entry *xinoe) +{ + int err; + struct file *file; + loff_t pos; + ssize_t sz; + struct au_sbinfo *sbinfo; + + LKTRTrace("b%d, hi%lu\n", bindex, (unsigned long)h_ino); + + xinoe->ino = 0; + if (unlikely(!au_opt_test_xino(au_mntflags(sb)))) + return 0; /* no ino */ + + err = 0; + sbinfo = au_sbi(sb); + pos = h_ino; + if (unlikely(Au_LOFF_MAX / sizeof(*xinoe) - 1 < pos)) { + AuIOErr1("too large hi%lu\n", (unsigned long)h_ino); + return -EFBIG; + } + pos *= sizeof(*xinoe); + + file = au_sbr(sb, bindex)->br_xino.xi_file; + AuDebugOn(!file); + if (i_size_read(file->f_dentry->d_inode) < pos + sizeof(*xinoe)) + return 0; /* no ino */ + + sz = xino_fread(sbinfo->si_xread, file, xinoe, sizeof(*xinoe), &pos); + if (sz == sizeof(*xinoe)) + return 0; /* success */ + + err = sz; + if (unlikely(sz >= 0)) { + err = -EIO; + AuIOErr("xino read error (%ld)\n", (long)sz); + } + + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct file *au_xino_create(struct super_block *sb, char *fname, int silent) +{ + struct file *file; + int err; + struct dentry *h_parent; + struct inode *h_dir; + struct vfsub_args vargs; + + LKTRTrace("%s\n", fname); + + /* + * at mount-time, and the xino file is the default path, + * hinotify is disabled so we have no inotify events to ignore. + * when a user specified the xino, we cannot get au_hdir to be ignored. + */ + vfsub_args_init(&vargs, /*ign*/NULL, /*dlgt*/0, 0); + file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE, + S_IRUGO | S_IWUGO); + if (IS_ERR(file)) { + if (!silent) + AuErr("open %s(%ld)\n", fname, PTR_ERR(file)); + return file; + } + + /* keep file count */ + h_parent = dget_parent(file->f_dentry); + h_dir = h_parent->d_inode; + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); + err = vfsub_unlink(h_dir, file->f_dentry, &vargs); + mutex_unlock(&h_dir->i_mutex); + dput(h_parent); + if (unlikely(err)) { + if (!silent) + AuErr("unlink %s(%d)\n", fname, err); + goto out; + } + + if (sb != file->f_dentry->d_sb) + return file; /* success */ + + if (!silent) + AuErr("%s must be outside\n", fname); + err = -EINVAL; + + out: + fput(file); + file = ERR_PTR(err); + return file; +} + +/* + * find another branch who is on the same filesystem of the specified + * branch{@btgt}. search until @bend. + */ +static int is_sb_shared(struct super_block *sb, aufs_bindex_t btgt, + aufs_bindex_t bend) +{ + aufs_bindex_t bindex; + struct super_block *tgt_sb = au_sbr_sb(sb, btgt); + + for (bindex = 0; bindex < btgt; bindex++) + if (unlikely(tgt_sb == au_sbr_sb(sb, bindex))) + return bindex; + for (bindex++; bindex <= bend; bindex++) + if (unlikely(tgt_sb == au_sbr_sb(sb, bindex))) + return bindex; + return -1; +} + +/* + * create a new xinofile at the same place/path as @base_file. + */ +struct file *au_xino_create2(struct super_block *sb, struct file *base_file, + struct file *copy_src) +{ + struct file *file; + int err; + struct dentry *base, *dentry, *parent; + struct inode *dir, *inode; + struct qstr *name; + struct au_hinode *hdir; + struct au_branch *br; + aufs_bindex_t bindex; + struct au_hin_ignore ign; + struct vfsub_args vargs; + struct au_ndx ndx = { + .nfsmnt = NULL, + .flags = 0, + .nd = NULL, + /* .br = NULL */ + }; + + base = base_file->f_dentry; + LKTRTrace("%.*s\n", AuDLNPair(base)); + parent = base->d_parent; /* dir inode is locked */ + dir = parent->d_inode; + IMustLock(dir); + + file = ERR_PTR(-EINVAL); + if (unlikely(au_test_nfs(parent->d_sb))) + goto out; + + /* do not superio, nor NFS. */ + name = &base->d_name; + dentry = au_lkup_one(name->name, parent, name->len, &ndx); + if (IS_ERR(dentry)) { + file = (void *)dentry; + AuErr("%.*s lookup err %ld\n", AuLNPair(name), PTR_ERR(dentry)); + goto out; + } + + hdir = NULL; + br = au_xino_def_br(au_sbi(sb)); + if (br) { + bindex = au_find_bindex(sb, br); + if (bindex >= 0) + hdir = au_hi(sb->s_root->d_inode, bindex); + } + vfsub_args_init(&vargs, &ign, 0, 0); + vfsub_ign_hinode(&vargs, IN_CREATE, hdir); + err = vfsub_create(dir, dentry, S_IRUGO | S_IWUGO, NULL, &vargs); + if (unlikely(err)) { + file = ERR_PTR(err); + AuErr("%.*s create err %d\n", AuLNPair(name), err); + goto out_dput; + } + file = dentry_open(dget(dentry), mntget(base_file->f_vfsmnt), + O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE); + if (IS_ERR(file)) { + AuErr("%.*s open err %ld\n", AuLNPair(name), PTR_ERR(file)); + goto out_dput; + } + vfsub_args_reinit(&vargs); + vfsub_ign_hinode(&vargs, IN_DELETE, hdir); + err = vfsub_unlink(dir, dentry, &vargs); + if (unlikely(err)) { + AuErr("%.*s unlink err %d\n", AuLNPair(name), err); + goto out_fput; + } + + if (copy_src) { + inode = copy_src->f_dentry->d_inode; + err = au_copy_file(file, copy_src, i_size_read(inode), + hdir, sb, &vargs); + if (unlikely(err)) { + AuErr("%.*s copy err %d\n", AuLNPair(name), err); + goto out_fput; + } + } + goto out_dput; /* success */ + + out_fput: + fput(file); + file = ERR_PTR(err); + out_dput: + dput(dentry); + out: + AuTraceErrPtr(file); + return file; +} + +/* ---------------------------------------------------------------------- */ + +/* + * initialize the xinofile for the specified branch{@sb, @bindex} + * at the place/path where @base_file indicates. + * test whether another branch is on the same filesystem or not, + * if @do_test is true. + */ +int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t h_ino, + struct file *base_file, int do_test) +{ + int err; + struct au_branch *shared_br; + aufs_bindex_t bshared, bend, bindex; + unsigned char do_create; + struct inode *dir; + struct au_xino_entry xinoe; + struct dentry *parent; + struct file *file; + struct super_block *tgt_sb; + + LKTRTrace("base_file %p, do_test %d\n", base_file, do_test); + SiMustWriteLock(sb); + AuDebugOn(!au_opt_test_xino(au_mntflags(sb))); + AuDebugOn(br->br_xino.xi_file); + + do_create = 1; + bshared = -1; + shared_br = NULL; + bend = au_sbend(sb); + if (do_test) { + tgt_sb = br->br_mnt->mnt_sb; + for (bindex = 0; bindex <= bend; bindex++) + if (unlikely(tgt_sb == au_sbr_sb(sb, bindex))) { + bshared = bindex; + break; + } + } + if (unlikely(bshared >= 0)) { + shared_br = au_sbr(sb, bshared); + do_create = !shared_br->br_xino.xi_file; + } + + if (do_create) { + parent = dget_parent(base_file->f_dentry); + dir = parent->d_inode; + mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT); + file = au_xino_create2(sb, base_file, NULL); + mutex_unlock(&dir->i_mutex); + dput(parent); + err = PTR_ERR(file); + if (IS_ERR(file)) + goto out; + br->br_xino.xi_file = file; + } else { + br->br_xino.xi_file = shared_br->br_xino.xi_file; + get_file(br->br_xino.xi_file); + } + + xinoe.ino = AUFS_ROOT_INO; +#if 0 /* reserved for future use */ + xinoe.h_gen = h_inode->i_generation; + WARN_ON(xinoe.h_gen == AuXino_INVALID_HGEN); +#endif + err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file, + h_ino, &xinoe); + if (!err) + return 0; /* success */ + + + out: + AuTraceErr(err); + return err; +} + +/* too slow */ +static int do_xib_restore(struct super_block *sb, struct file *file, void *page) +{ + int err, bit; + struct au_sbinfo *sbinfo; + au_readf_t func; + loff_t pos, pend; + ssize_t sz; + struct au_xino_entry *xinoe; + unsigned long pindex; + + AuTraceEnter(); + SiMustWriteLock(sb); + + err = 0; + sbinfo = au_sbi(sb); + func = sbinfo->si_xread; + pend = i_size_read(file->f_dentry->d_inode); +#ifdef CONFIG_AUFS_DEBUG + if (unlikely(pend > (1 << 22))) + AuWarn("testing a large xino file %lld\n", (long long)pend); +#endif + pos = 0; + while (pos < pend) { + sz = xino_fread(func, file, page, PAGE_SIZE, &pos); + err = sz; + if (unlikely(sz <= 0)) + goto out; + + err = 0; + for (xinoe = page; sz > 0; xinoe++, sz -= sizeof(xinoe)) { + if (unlikely(xinoe->ino < AUFS_FIRST_INO)) + continue; + + xib_calc_bit(xinoe->ino, &pindex, &bit); + AuDebugOn(page_bits <= bit); + err = xib_pindex(sb, pindex); + if (!err) + set_bit(bit, sbinfo->si_xib_buf); + else + goto out; + } + } + + out: + AuTraceErr(err); + return err; +} + +static int xib_restore(struct super_block *sb) +{ + int err; + aufs_bindex_t bindex, bend; + void *page; + + AuTraceEnter(); + + err = -ENOMEM; + page = (void *)__get_free_page(GFP_NOFS); + if (unlikely(!page)) + goto out; + + err = 0; + bend = au_sbend(sb); + for (bindex = 0; !err && bindex <= bend; bindex++) + if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0) + err = do_xib_restore + (sb, au_sbr(sb, bindex)->br_xino.xi_file, page); + else + LKTRTrace("b%d\n", bindex); + free_page((unsigned long)page); + + out: + AuTraceErr(err); + return err; +} + +int au_xib_trunc(struct super_block *sb) +{ + int err; + struct au_sbinfo *sbinfo; + unsigned long *p; + loff_t pos; + ssize_t sz; + struct dentry *parent; + struct inode *dir; + struct file *file; + unsigned int mnt_flags; + + AuTraceEnter(); + SiMustWriteLock(sb); + + mnt_flags = au_mntflags(sb); + if (unlikely(!au_opt_test_xino(mnt_flags))) + return 0; + + sbinfo = au_sbi(sb); + parent = dget_parent(sbinfo->si_xib->f_dentry); + dir = parent->d_inode; + mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT); + file = au_xino_create2(sb, sbinfo->si_xib, NULL); + mutex_unlock(&dir->i_mutex); + dput(parent); + err = PTR_ERR(file); + if (IS_ERR(file)) + goto out; + fput(sbinfo->si_xib); + sbinfo->si_xib = file; + + p = sbinfo->si_xib_buf; + memset(p, 0, PAGE_SIZE); + pos = 0; + sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos); + if (unlikely(sz != PAGE_SIZE)) { + err = sz; + AuIOErr("err %d\n", err); + if (sz >= 0) + err = -EIO; + goto out; + } + + if (au_opt_test_xino(mnt_flags)) { + mutex_lock(&sbinfo->si_xib_mtx); + err = xib_restore(sb); + mutex_unlock(&sbinfo->si_xib_mtx); +#if 0 /* reserved for future use */ + } else { + /* is it really safe? */ + /* dont trust BKL */ + AuDebugOn(!kernel_locked()); + ino = AUFS_FIRST_INO; + list_for_each_entry(inode, &sb->s_inodes, i_sb_list) + if (ino < inode->i_ino) + ino = inode->i_ino; + + /* make iunique to return larger than active max inode number */ + iunique(sb, ino); + err = 0; +#endif + } + +out: + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +/* + * xino mount option handlers + */ +static au_readf_t find_readf(struct file *h_file) +{ + const struct file_operations *fop = h_file->f_op; + + if (fop) { + if (fop->read) + return fop->read; + if (fop->aio_read) + return do_sync_read; + } + return ERR_PTR(-ENOSYS); +} + +static au_writef_t find_writef(struct file *h_file) +{ + const struct file_operations *fop = h_file->f_op; + + if (fop) { + if (fop->write) + return fop->write; + if (fop->aio_write) + return do_sync_write; + } + return ERR_PTR(-ENOSYS); +} + +/* xino bitmap */ +static void xino_clear_xib(struct super_block *sb) +{ + struct au_sbinfo *sbinfo; + + AuTraceEnter(); + SiMustWriteLock(sb); + + sbinfo = au_sbi(sb); + sbinfo->si_xread = NULL; + sbinfo->si_xwrite = NULL; + if (sbinfo->si_xib) + fput(sbinfo->si_xib); + sbinfo->si_xib = NULL; + free_page((unsigned long)sbinfo->si_xib_buf); + sbinfo->si_xib_buf = NULL; +} + +static int au_xino_set_xib(struct super_block *sb, struct file *base) +{ + int err; + struct au_sbinfo *sbinfo; + struct file *file; + loff_t pos; + + LKTRTrace("%.*s\n", AuDLNPair(base->f_dentry)); + SiMustWriteLock(sb); + + sbinfo = au_sbi(sb); + file = au_xino_create2(sb, base, sbinfo->si_xib); + err = PTR_ERR(file); + if (IS_ERR(file)) + goto out; + if (sbinfo->si_xib) + fput(sbinfo->si_xib); + sbinfo->si_xib = file; + sbinfo->si_xread = find_readf(file); + AuDebugOn(IS_ERR(sbinfo->si_xread)); + sbinfo->si_xwrite = find_writef(file); + AuDebugOn(IS_ERR(sbinfo->si_xwrite)); + + err = -ENOMEM; + if (!sbinfo->si_xib_buf) + sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS); + if (unlikely(!sbinfo->si_xib_buf)) + goto out_unset; + + sbinfo->si_xib_last_pindex = 0; + sbinfo->si_xib_next_bit = 0; + + /* no need to lock for i_size_read() */ + if (i_size_read(file->f_dentry->d_inode) < PAGE_SIZE) { + pos = 0; + err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf, + PAGE_SIZE, &pos); + if (unlikely(err != PAGE_SIZE)) + goto out_free; + } + err = 0; + goto out; /* success */ + + out_free: + free_page((unsigned long)sbinfo->si_xib_buf); + sbinfo->si_xib_buf = NULL; + if (err >= 0) + err = -EIO; + out_unset: + fput(sbinfo->si_xib); + sbinfo->si_xib = NULL; + sbinfo->si_xread = NULL; + sbinfo->si_xwrite = NULL; + out: + AuTraceErr(err); + return err; +} + +/* xino for each branch */ +static void xino_clear_br(struct super_block *sb) +{ + aufs_bindex_t bindex, bend; + struct au_branch *br; + + AuTraceEnter(); + SiMustWriteLock(sb); + + bend = au_sbend(sb); + for (bindex = 0; bindex <= bend; bindex++) { + br = au_sbr(sb, bindex); + if (unlikely(!br || !br->br_xino.xi_file)) + continue; + + fput(br->br_xino.xi_file); + br->br_xino.xi_file = NULL; + } +} + +static int au_xino_set_br(struct super_block *sb, struct file *base) +{ + int err; + aufs_bindex_t bindex, bend, bshared; + struct { + struct file *old, *new; + } *fpair, *p; + struct au_branch *br; + struct au_xino_entry xinoe; + struct inode *inode; + au_writef_t writef; + + LKTRTrace("%.*s\n", AuDLNPair(base->f_dentry)); + SiMustWriteLock(sb); + + err = -ENOMEM; + bend = au_sbend(sb); + fpair = kcalloc(bend + 1, sizeof(*fpair), GFP_NOFS); + if (unlikely(!fpair)) + goto out; + + inode = sb->s_root->d_inode; + xinoe.ino = AUFS_ROOT_INO; + writef = au_sbi(sb)->si_xwrite; + for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) { + br = au_sbr(sb, bindex); + bshared = is_sb_shared(sb, bindex, bindex - 1); + if (bshared >= 0) { + /* shared xino */ + *p = fpair[bshared]; + get_file(p->new); + } + + if (!p->new) { + /* new xino */ + p->old = br->br_xino.xi_file; + p->new = au_xino_create2(sb, base, br->br_xino.xi_file); + err = PTR_ERR(p->new); + if (IS_ERR(p->new)) { + p->new = NULL; + goto out_pair; + } + } + + err = au_xino_do_write(writef, p->new, + au_h_iptr(inode, bindex)->i_ino, &xinoe); + if (unlikely(err)) + goto out_pair; + } + + for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) { + br = au_sbr(sb, bindex); + AuDebugOn(p->old != br->br_xino.xi_file); + if (br->br_xino.xi_file) + fput(br->br_xino.xi_file); + get_file(p->new); + br->br_xino.xi_file = p->new; + } + + out_pair: + for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) + if (p->new) + fput(p->new); + else + break; + kfree(fpair); + out: + AuTraceErr(err); + return err; +} + +void au_xino_clr(struct super_block *sb) +{ + struct au_sbinfo *sbinfo; + + AuTraceEnter(); + SiMustWriteLock(sb); + + au_xigen_clr(sb); + xino_clear_xib(sb); + xino_clear_br(sb); + sbinfo = au_sbi(sb); + /* lvalue, do not call au_mntflags() */ + au_opt_clr(sbinfo->si_mntflags, XINO); + au_xino_def_br_set(NULL, sbinfo); +} + +int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount) +{ + int err, skip; + struct dentry *parent, *cur_parent; + struct qstr *dname, *cur_name; + struct file *cur_xino; + struct inode *dir; + struct au_sbinfo *sbinfo; + + LKTRTrace("remount %d\n", remount); + SiMustWriteLock(sb); + + err = 0; + sbinfo = au_sbi(sb); + parent = dget_parent(xino->file->f_dentry); + if (remount) { + skip = 0; + dname = &xino->file->f_dentry->d_name; + cur_xino = sbinfo->si_xib; + if (cur_xino) { + cur_parent = dget_parent(cur_xino->f_dentry); + cur_name = &cur_xino->f_dentry->d_name; + skip = (cur_parent == parent + && dname->len == cur_name->len + && !memcmp(dname->name, cur_name->name, + dname->len)); + dput(cur_parent); + } + if (skip) + goto out; + } + + au_opt_set(sbinfo->si_mntflags, XINO); + au_xino_def_br_set(NULL, sbinfo); + dir = parent->d_inode; + mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT); + err = au_xino_set_xib(sb, xino->file); + if (!err) + err = au_xigen_set(sb, xino->file); + if (!err) + err = au_xino_set_br(sb, xino->file); + mutex_unlock(&dir->i_mutex); + if (!err) + goto out; /* success */ + + /* reset all */ + AuIOErr("failed creating xino(%d).\n", err); + + out: + dput(parent); + AuTraceErr(err); + return err; +} + +int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex) +{ + int err; + struct au_branch *br; + struct file *new_xino; + struct super_block *h_sb; + aufs_bindex_t bi, bend; + struct dentry *parent; + struct inode *dir; + + LKTRTrace("b%d\n", bindex); + SiMustWriteLock(sb); + + err = -EINVAL; + bend = au_sbend(sb); + if (unlikely(bindex < 0 || bend < bindex)) + goto out; + br = au_sbr(sb, bindex); + if (unlikely(!br->br_xino.xi_file)) + goto out; + + parent = dget_parent(br->br_xino.xi_file->f_dentry); + dir = parent->d_inode; + mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT); + new_xino = au_xino_create2(sb, br->br_xino.xi_file, + br->br_xino.xi_file); + mutex_unlock(&dir->i_mutex); + dput(parent); + err = PTR_ERR(new_xino); + if (IS_ERR(new_xino)) + goto out; + err = 0; + fput(br->br_xino.xi_file); + br->br_xino.xi_file = new_xino; + + h_sb = br->br_mnt->mnt_sb; + for (bi = 0; bi <= bend; bi++) { + if (unlikely(bi == bindex)) + continue; + br = au_sbr(sb, bi); + if (br->br_mnt->mnt_sb != h_sb) + continue; + + fput(br->br_xino.xi_file); + br->br_xino.xi_file = new_xino; + get_file(new_xino); + } + + out: + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +/* + * create a xinofile at the default place/path. + */ +struct file *au_xino_def(struct super_block *sb) +{ + struct file *file; + aufs_bindex_t bend, bindex, bwr; + char *page, *p; + struct path path; + struct dentry *root; + + AuTraceEnter(); + + root = sb->s_root; + bend = au_sbend(sb); + bwr = -1; + for (bindex = 0; bindex <= bend; bindex++) + if (au_br_writable(au_sbr_perm(sb, bindex)) + && !au_test_nfs(au_h_dptr(root, bindex)->d_sb)) { + bwr = bindex; + break; + } + + if (bwr >= 0) { + file = ERR_PTR(-ENOMEM); + page = __getname(); + if (unlikely(!page)) + goto out; + path.mnt = au_sbr_mnt(sb, bwr); + path.dentry = au_h_dptr(root, bwr); + p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME)); + file = (void *)p; + if (!IS_ERR(p)) { + strcat(p, "/" AUFS_XINO_FNAME); + LKTRTrace("%s\n", p); + file = au_xino_create(sb, p, /*silent*/0); + if (!IS_ERR(file)) + au_xino_def_br_set(au_sbr(sb, bwr), au_sbi(sb)); + } + __putname(page); + } else { + file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0); + if (unlikely(au_test_nfs(file->f_dentry->d_sb))) { + AuErr("xino or noxino option is required " + "since %s is NFS\n", AUFS_XINO_DEFPATH); + fput(file); + file = ERR_PTR(-EINVAL); + } + if (!IS_ERR(file)) + au_xino_def_br_set(NULL, au_sbi(sb)); + } + + out: + AuTraceErrPtr(file); + return file; +} --- linux-2.6.28.orig/ubuntu/aufs/vfsub.c +++ linux-2.6.28/ubuntu/aufs/vfsub.c @@ -0,0 +1,689 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * sub-routines for VFS + * + * $Id: vfsub.c,v 1.11 2008/08/04 00:32:35 sfjro Exp $ + */ + +#include +#include "aufs.h" + +/* ---------------------------------------------------------------------- */ + +void vfsub_args_init(struct vfsub_args *vargs, struct au_hin_ignore *ign, + int dlgt, int force_unlink) +{ + do_vfsub_args_reinit(vargs, ign); + vargs->flags = 0; + if (unlikely(dlgt)) + vfsub_fset(vargs->flags, DLGT); + if (force_unlink) + vfsub_fset(vargs->flags, FORCE_UNLINK); +} + +/* ---------------------------------------------------------------------- */ + +struct file *vfsub_filp_open(const char *path, int oflags, int mode) +{ + struct file *err; + + LKTRTrace("%s\n", path); + + lockdep_off(); + err = filp_open(path, oflags, mode); + lockdep_on(); + if (!IS_ERR(err)) + au_update_fuse_h_inode(err->f_vfsmnt, err->f_dentry); /*ignore*/ + return err; +} + +int vfsub_path_lookup(const char *name, unsigned int flags, + struct nameidata *nd) +{ + int err; + + LKTRTrace("%s\n", name); + + /* lockdep_off(); */ + err = path_lookup(name, flags, nd); + /* lockdep_on(); */ + if (!err) + au_update_fuse_h_inode(nd->path.mnt, nd->path.dentry); + /*ignore*/ + return err; +} + +struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent, + int len) +{ + struct dentry *d; + + LKTRTrace("%.*s/%.*s\n", AuDLNPair(parent), len, name); + IMustLock(parent->d_inode); + + d = lookup_one_len(name, parent, len); + if (!IS_ERR(d)) + au_update_fuse_h_inode(NULL, d); /*ignore*/ + return d; +} + +#ifdef CONFIG_AUFS_LHASH_PATCH +struct dentry *vfsub__lookup_hash(struct qstr *name, struct dentry *parent, + struct nameidata *nd) +{ + struct dentry *d; + + LKTRTrace("%.*s/%.*s, nd %d\n", + AuDLNPair(parent), AuLNPair(name), !!nd); + if (nd) + LKTRTrace("nd{0x%x}\n", nd->flags); + IMustLock(parent->d_inode); + + d = __lookup_hash(name, parent, nd); + if (!IS_ERR(d)) + au_update_fuse_h_inode(NULL, d); /*ignore*/ + return d; +} +#endif + +/* ---------------------------------------------------------------------- */ + +int do_vfsub_create(struct inode *dir, struct dentry *dentry, int mode, + struct nameidata *nd) +{ + int err; + struct vfsmount *mnt; + + LKTRTrace("i%lu, %.*s, 0x%x\n", dir->i_ino, AuDLNPair(dentry), mode); + IMustLock(dir); + + err = vfs_create(dir, dentry, mode, nd); + if (!err) { + mnt = NULL; + if (nd) + mnt = nd->path.mnt; + /* dir inode is locked */ + au_update_fuse_h_inode(mnt, dentry->d_parent); /*ignore*/ + au_update_fuse_h_inode(mnt, dentry); /*ignore*/ + } + return err; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) +#define VfsubSymlinkArgs dir, dentry, symname +#else +#define VfsubSymlinkArgs dir, dentry, symname, mode +#endif + +int do_vfsub_symlink(struct inode *dir, struct dentry *dentry, + const char *symname, int mode) +{ + int err; + + LKTRTrace("i%lu, %.*s, %s, 0x%x\n", + dir->i_ino, AuDLNPair(dentry), symname, mode); + IMustLock(dir); + + err = vfs_symlink(dir, dentry, NULL, symname); + if (!err) { + /* dir inode is locked */ + au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/ + au_update_fuse_h_inode(NULL, dentry); /*ignore*/ + } + return err; +} + +int do_vfsub_mknod(struct inode *dir, struct dentry *dentry, int mode, + dev_t dev) +{ + int err; + + LKTRTrace("i%lu, %.*s, 0x%x\n", dir->i_ino, AuDLNPair(dentry), mode); + IMustLock(dir); + + err = vfs_mknod(dir, dentry, NULL, mode, dev); + if (!err) { + /* dir inode is locked */ + au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/ + au_update_fuse_h_inode(NULL, dentry); /*ignore*/ + } + return err; +} + +int do_vfsub_link(struct dentry *src_dentry, struct inode *dir, + struct dentry *dentry) +{ + int err; + + LKTRTrace("%.*s, i%lu, %.*s\n", + AuDLNPair(src_dentry), dir->i_ino, AuDLNPair(dentry)); + IMustLock(dir); + + lockdep_off(); + err = vfs_link(src_dentry, NULL, dir, dentry, NULL); + + lockdep_on(); + if (!err) { + LKTRTrace("src_i %p, dst_i %p\n", + src_dentry->d_inode, dentry->d_inode); + /* fuse has different memory inode for the same inumber */ + au_update_fuse_h_inode(NULL, src_dentry); /*ignore*/ + /* dir inode is locked */ + au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/ + au_update_fuse_h_inode(NULL, dentry); /*ignore*/ + } + return err; +} + +int do_vfsub_rename(struct inode *src_dir, struct dentry *src_dentry, + struct inode *dir, struct dentry *dentry) +{ + int err; + + LKTRTrace("i%lu, %.*s, i%lu, %.*s\n", + src_dir->i_ino, AuDLNPair(src_dentry), + dir->i_ino, AuDLNPair(dentry)); + IMustLock(dir); + IMustLock(src_dir); + + lockdep_off(); + err = vfs_rename(src_dir, src_dentry, NULL, dir, dentry, NULL); + lockdep_on(); + if (!err) { + /* dir inode is locked */ + au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/ + au_update_fuse_h_inode(NULL, src_dentry->d_parent); /*ignore*/ + au_update_fuse_h_inode(NULL, src_dentry); /*ignore*/ + } + return err; +} + +int do_vfsub_mkdir(struct inode *dir, struct dentry *dentry, int mode) +{ + int err; + + LKTRTrace("i%lu, %.*s, 0x%x\n", dir->i_ino, AuDLNPair(dentry), mode); + IMustLock(dir); + + err = vfs_mkdir(dir, dentry, NULL, mode); + + if (!err) { + /* dir inode is locked */ + au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/ + au_update_fuse_h_inode(NULL, dentry); /*ignore*/ + } + return err; +} + +int do_vfsub_rmdir(struct inode *dir, struct dentry *dentry) +{ + int err; + + LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry)); + IMustLock(dir); + + lockdep_off(); + err = vfs_rmdir(dir, dentry, NULL); + + lockdep_on(); + /* dir inode is locked */ + if (!err) + au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/ + return err; +} + +int do_vfsub_unlink(struct inode *dir, struct dentry *dentry) +{ + int err; + + LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry)); + IMustLock(dir); + + /* vfs_unlink() locks inode */ + lockdep_off(); + err = vfs_unlink(dir, dentry, NULL); + + lockdep_on(); + /* dir inode is locked */ + if (!err) + au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/ + return err; +} + +/* ---------------------------------------------------------------------- */ + +ssize_t do_vfsub_read_u(struct file *file, char __user *ubuf, size_t count, + loff_t *ppos) +{ + ssize_t err; + + LKTRTrace("%.*s, cnt %lu, pos %lld\n", + AuDLNPair(file->f_dentry), (unsigned long)count, *ppos); + + /* todo: always off, regardless nfs branch? */ + au_br_nfs_lockdep_off(file->f_vfsmnt->mnt_sb); + err = vfs_read(file, ubuf, count, ppos); + au_br_nfs_lockdep_on(file->f_vfsmnt->mnt_sb); + if (err >= 0) + au_update_fuse_h_inode(file->f_vfsmnt, file->f_dentry); + /*ignore*/ + return err; +} + +/* todo: kernel_read()? */ +ssize_t do_vfsub_read_k(struct file *file, void *kbuf, size_t count, + loff_t *ppos) +{ + ssize_t err; + mm_segment_t oldfs; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + err = do_vfsub_read_u(file, (char __user *)kbuf, count, ppos); + set_fs(oldfs); + return err; +} + +ssize_t do_vfsub_write_u(struct file *file, const char __user *ubuf, + size_t count, loff_t *ppos) +{ + ssize_t err; + + LKTRTrace("%.*s, cnt %lu, pos %lld\n", + AuDLNPair(file->f_dentry), (unsigned long)count, *ppos); + + lockdep_off(); + err = vfs_write(file, ubuf, count, ppos); + lockdep_on(); + if (err >= 0) + au_update_fuse_h_inode(file->f_vfsmnt, file->f_dentry); + /*ignore*/ + return err; +} + +ssize_t do_vfsub_write_k(struct file *file, void *kbuf, size_t count, + loff_t *ppos) +{ + ssize_t err; + mm_segment_t oldfs; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + err = do_vfsub_write_u(file, (const char __user *)kbuf, count, ppos); + set_fs(oldfs); + return err; +} + +int do_vfsub_readdir(struct file *file, filldir_t filldir, void *arg) +{ + int err; + + LKTRTrace("%.*s\n", AuDLNPair(file->f_dentry)); + + lockdep_off(); + err = vfs_readdir(file, filldir, arg); + lockdep_on(); + if (err >= 0) + au_update_fuse_h_inode(file->f_vfsmnt, file->f_dentry); + /*ignore*/ + return err; +} + +#ifdef CONFIG_AUFS_SPLICE_PATCH +long do_vfsub_splice_to(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags) +{ + long err; + + LKTRTrace("%.*s, pos %lld, len %lu, 0x%x\n", + AuDLNPair(in->f_dentry), *ppos, (unsigned long)len, flags); + + lockdep_off(); + err = vfs_splice_to(in, ppos, pipe, len, flags); + lockdep_on(); + if (err >= 0) + au_update_fuse_h_inode(in->f_vfsmnt, in->f_dentry); /*ignore*/ + return err; +} + +long do_vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags) +{ + long err; + + LKTRTrace("%.*s, pos %lld, len %lu, 0x%x\n", + AuDLNPair(out->f_dentry), *ppos, (unsigned long)len, flags); + + lockdep_off(); + err = vfs_splice_from(pipe, out, ppos, len, flags); + lockdep_on(); + if (err >= 0) + au_update_fuse_h_inode(out->f_vfsmnt, out->f_dentry); /*ignore*/ + return err; +} +#endif + +/* ---------------------------------------------------------------------- */ + +struct au_vfsub_mkdir_args { + int *errp; + struct inode *dir; + struct dentry *dentry; + int mode; + struct vfsub_args *vargs; +}; + +static void au_call_vfsub_mkdir(void *args) +{ + struct au_vfsub_mkdir_args *a = args; + *a->errp = vfsub_mkdir(a->dir, a->dentry, a->mode, a->vargs); +} + +int vfsub_sio_mkdir(struct au_hinode *hdir, struct dentry *dentry, int mode, + int dlgt) +{ + int err, do_sio, wkq_err; + struct inode *dir = hdir->hi_inode; + struct au_hin_ignore ign; + struct vfsub_args vargs; + + LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry)); + + vfsub_args_init(&vargs, &ign, dlgt, /*force_unlink*/0); + vfsub_ign_hinode(&vargs, IN_CREATE, hdir); + do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE, dlgt); + if (!do_sio) + err = vfsub_mkdir(dir, dentry, mode, &vargs); + else { + struct au_vfsub_mkdir_args args = { + .errp = &err, + .dir = dir, + .dentry = dentry, + .mode = mode, + .vargs = &vargs + }; + vfsub_fclr(vargs.flags, DLGT); + wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args, /*dlgt*/0); + if (unlikely(wkq_err)) + err = wkq_err; + } + + AuTraceErr(err); + return err; +} + +struct au_vfsub_rmdir_args { + int *errp; + struct inode *dir; + struct dentry *dentry; + struct vfsub_args *vargs; +}; + +static void au_call_vfsub_rmdir(void *args) +{ + struct au_vfsub_rmdir_args *a = args; + *a->errp = vfsub_rmdir(a->dir, a->dentry, a->vargs); +} + +int vfsub_sio_rmdir(struct au_hinode *hdir, struct dentry *dentry, int dlgt) +{ + int err, do_sio, wkq_err; + struct inode *dir = hdir->hi_inode; + struct au_hin_ignore ign; + struct vfsub_args vargs; + + LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry)); + + vfsub_args_init(&vargs, &ign, dlgt, /*force_unlink*/0); + vfsub_ign_hinode(&vargs, IN_DELETE, hdir); + do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE, dlgt); + if (!do_sio) + err = vfsub_rmdir(dir, dentry, &vargs); + else { + struct au_vfsub_rmdir_args args = { + .errp = &err, + .dir = dir, + .dentry = dentry, + .vargs = &vargs + }; + vfsub_fclr(vargs.flags, DLGT); + wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args, /*dlgt*/0); + if (unlikely(wkq_err)) + err = wkq_err; + } + + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct notify_change_args { + int *errp; + struct dentry *h_dentry; + struct iattr *ia; + struct vfsub_args *vargs; +}; + +static void call_notify_change(void *args) +{ + struct notify_change_args *a = args; + struct inode *h_inode; + + LKTRTrace("%.*s, ia_valid 0x%x\n", + AuDLNPair(a->h_dentry), a->ia->ia_valid); + h_inode = a->h_dentry->d_inode; + IMustLock(h_inode); + + *a->errp = -EPERM; + if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) { + vfsub_ignore(a->vargs); + lockdep_off(); + *a->errp = notify_change(a->h_dentry, NULL, a->ia); + lockdep_on(); + if (!*a->errp) + au_update_fuse_h_inode(NULL, a->h_dentry); /*ignore*/ + else + vfsub_unignore(a->vargs); + au_dbg_hin_list(a->vargs); + } + AuTraceErr(*a->errp); +} + +#ifdef CONFIG_AUFS_DLGT +static void vfsub_notify_change_dlgt(struct notify_change_args *args, + unsigned int flags) +{ + if (!vfsub_ftest(flags, DLGT)) + call_notify_change(args); + else { + int wkq_err; + wkq_err = au_wkq_wait(call_notify_change, args, /*dlgt*/1); + if (unlikely(wkq_err)) + *args->errp = wkq_err; + } +} +#else +static void vfsub_notify_change_dlgt(struct notify_change_args *args, + unsigned int flags) +{ + call_notify_change(args); +} +#endif + +int vfsub_notify_change(struct dentry *dentry, struct iattr *ia, + struct vfsub_args *vargs) +{ + int err; + struct notify_change_args args = { + .errp = &err, + .h_dentry = dentry, + .ia = ia, + .vargs = vargs + }; + + vfsub_notify_change_dlgt(&args, vargs->flags); + + AuTraceErr(err); + return err; +} + +int vfsub_sio_notify_change(struct au_hinode *hdir, struct dentry *dentry, + struct iattr *ia) +{ + int err, wkq_err; + struct au_hin_ignore ign; + struct vfsub_args vargs; + __u32 events; + struct notify_change_args args = { + .errp = &err, + .h_dentry = dentry, + .ia = ia, + .vargs = &vargs + }; + + LKTRTrace("%.*s, 0x%x\n", AuDLNPair(dentry), ia->ia_valid); + + vfsub_args_init(&vargs, &ign, /*dlgt*/0, /*force_unlink*/0); + events = vfsub_events_notify_change(ia); + if (events) + vfsub_ign_hinode(&vargs, events, hdir); + wkq_err = au_wkq_wait(call_notify_change, &args, /*dlgt*/0); + if (unlikely(wkq_err)) + err = wkq_err; + + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct unlink_args { + int *errp; + struct inode *dir; + struct dentry *dentry; + struct vfsub_args *vargs; +}; + +static void call_unlink(void *args) +{ + struct unlink_args *a = args; + struct inode *h_inode; + const int stop_sillyrename = (au_test_nfs(a->dentry->d_sb) + && atomic_read(&a->dentry->d_count) == 1); + + LKTRTrace("%.*s, stop_silly %d, cnt %d\n", + AuDLNPair(a->dentry), stop_sillyrename, + atomic_read(&a->dentry->d_count)); + + if (!stop_sillyrename) + dget(a->dentry); + h_inode = a->dentry->d_inode; + if (h_inode) + atomic_inc_return(&h_inode->i_count); + vfsub_ignore(a->vargs); + *a->errp = do_vfsub_unlink(a->dir, a->dentry); + if (unlikely(*a->errp || (a->dentry->d_flags & DCACHE_NFSFS_RENAMED))) + vfsub_unignore(a->vargs); + au_dbg_hin_list(a->vargs); + if (!stop_sillyrename) + dput(a->dentry); + if (h_inode) + iput(h_inode); + + AuTraceErr(*a->errp); +} + +/* + * @dir: must be locked. + * @dentry: target dentry. + */ +int vfsub_unlink(struct inode *dir, struct dentry *dentry, + struct vfsub_args *vargs) +{ + int err; + struct unlink_args args = { + .errp = &err, + .dir = dir, + .dentry = dentry, + .vargs = vargs + }; + + if (!vfsub_ftest(vargs->flags, DLGT) + && !vfsub_ftest(vargs->flags, FORCE_UNLINK)) + call_unlink(&args); + else { + int wkq_err; + wkq_err = au_wkq_wait(call_unlink, &args, + vfsub_ftest(vargs->flags, DLGT)); + if (unlikely(wkq_err)) + err = wkq_err; + } + + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct statfs_args { + int *errp; + void *arg; + struct kstatfs *buf; +}; + +static void call_statfs(void *args) +{ + struct statfs_args *a = args; + *a->errp = vfs_statfs(a->arg, a->buf); +} + +#ifdef CONFIG_AUFS_DLGT +static void vfsub_statfs_dlgt(struct statfs_args *args, int dlgt) +{ + if (!dlgt) + call_statfs(args); + else { + int wkq_err; + wkq_err = au_wkq_wait(call_statfs, args, /*dlgt*/1); + if (unlikely(wkq_err)) + *args->errp = wkq_err; + } +} +#else +static void vfsub_statfs_dlgt(struct statfs_args *args, int dlgt) +{ + call_statfs(args); +} +#endif + +int vfsub_statfs(void *arg, struct kstatfs *buf, int dlgt) +{ + int err; + struct statfs_args args = { + .errp = &err, + .arg = arg, + .buf = buf + }; + + vfsub_statfs_dlgt(&args, dlgt); + + return err; +} --- linux-2.6.28.orig/ubuntu/aufs/wkq.c +++ linux-2.6.28/ubuntu/aufs/wkq.c @@ -0,0 +1,363 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * workqueue for asynchronous/super-io/delegated operations + * + * $Id: wkq.c,v 1.13 2008/09/15 03:16:36 sfjro Exp $ + */ + +#include +#include "aufs.h" + +struct au_wkq *au_wkq; + +struct au_cred { +#ifdef CONFIG_AUFS_DLGT + int umask; + uid_t fsuid; + gid_t fsgid; + kernel_cap_t cap_effective, cap_inheritable, cap_permitted; +#if 0 /* reserved for future use */ + unsigned keep_capabilities:1; + struct user_struct *user; + struct fs_struct *fs; + struct nsproxy *nsproxy; +#endif +#endif +}; + +struct au_wkinfo { + struct work_struct wk; + struct super_block *sb; + + unsigned int flags; + struct au_cred cred; + + au_wkq_func_t func; + void *args; + + atomic_t *busyp; + struct completion *comp; +}; + +/* ---------------------------------------------------------------------- */ + +#ifdef CONFIG_AUFS_DLGT +static void cred_store(struct au_cred *cred) +{ + cred->umask = current->fs->umask; + cred->fsuid = current->fsuid; + cred->fsgid = current->fsgid; + cred->cap_effective = current->cap_effective; + cred->cap_inheritable = current->cap_inheritable; + cred->cap_permitted = current->cap_permitted; +} + +static void cred_revert(struct au_cred *cred) +{ + AuDebugOn(!au_test_wkq(current)); + current->fs->umask = cred->umask; + current->fsuid = cred->fsuid; + current->fsgid = cred->fsgid; + current->cap_effective = cred->cap_effective; + current->cap_inheritable = cred->cap_inheritable; + current->cap_permitted = cred->cap_permitted; +} + +static void cred_switch(struct au_cred *old, struct au_cred *new) +{ + cred_store(old); + cred_revert(new); +} + +static void dlgt_cred_store(unsigned int flags, struct au_wkinfo *wkinfo) +{ + if (unlikely(au_ftest_wkq(flags, DLGT))) + cred_store(&wkinfo->cred); +} + +static void dlgt_func(struct au_wkinfo *wkinfo) +{ + if (!au_ftest_wkq(wkinfo->flags, DLGT)) + wkinfo->func(wkinfo->args); + else { + struct au_cred cred; + cred_switch(&cred, &wkinfo->cred); + wkinfo->func(wkinfo->args); + cred_revert(&cred); + } +} +#else +static void dlgt_cred_store(unsigned int flags, struct au_wkinfo *wkinfo) +{ + /* empty */ +} + +static void dlgt_func(struct au_wkinfo *wkinfo) +{ + wkinfo->func(wkinfo->args); +} +#endif /* CONFIG_AUFS_DLGT */ + +/* ---------------------------------------------------------------------- */ + +static void update_busy(struct au_wkq *wkq, struct au_wkinfo *wkinfo) +{ +#ifdef CONFIG_AUFS_STAT + unsigned int new, old; + + do { + new = atomic_read(wkinfo->busyp); + old = wkq->max_busy; + if (new <= old) + break; + } while (cmpxchg(&wkq->max_busy, old, new) == old); +#endif +} + +static int enqueue(struct au_wkq *wkq, struct au_wkinfo *wkinfo) +{ + AuTraceEnter(); + + wkinfo->busyp = &wkq->busy; + update_busy(wkq, wkinfo); + if (au_ftest_wkq(wkinfo->flags, WAIT)) + return !queue_work(wkq->q, &wkinfo->wk); + else + return !schedule_work(&wkinfo->wk); +} + +static void do_wkq(struct au_wkinfo *wkinfo) +{ + unsigned int idle, n; + int i, idle_idx; + + AuTraceEnter(); + + while (1) { + if (au_ftest_wkq(wkinfo->flags, WAIT)) { + idle_idx = 0; + idle = UINT_MAX; + for (i = 0; i < aufs_nwkq; i++) { + n = atomic_inc_return(&au_wkq[i].busy); + if (n == 1 && !enqueue(au_wkq + i, wkinfo)) + return; /* success */ + + if (n < idle) { + idle_idx = i; + idle = n; + } + atomic_dec_return(&au_wkq[i].busy); + } + } else + idle_idx = aufs_nwkq; + + atomic_inc_return(&au_wkq[idle_idx].busy); + if (!enqueue(au_wkq + idle_idx, wkinfo)) + return; /* success */ + + /* impossible? */ + AuWarn1("failed to queue_work()\n"); + yield(); + } +} + +static void wkq_func(struct work_struct *wk) +{ + struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk); + + LKTRTrace("wkinfo{0x%x, %p, %p, %p}\n", + wkinfo->flags, wkinfo->func, wkinfo->busyp, wkinfo->comp); + + dlgt_func(wkinfo); + atomic_dec_return(wkinfo->busyp); + if (au_ftest_wkq(wkinfo->flags, WAIT)) + complete(wkinfo->comp); + else { + kobject_put(&au_sbi(wkinfo->sb)->si_kobj); + module_put(THIS_MODULE); + kfree(wkinfo); + } +} + +#if defined(CONFIG_4KSTACKS) || defined(Test4KSTACKS) +#define AuWkqCompDeclare(name) struct completion *comp = NULL + +static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp) +{ + *comp = kmalloc(sizeof(**comp), GFP_NOFS); + if (*comp) { + init_completion(*comp); + wkinfo->comp = *comp; + return 0; + } + return -ENOMEM; +} + +static void au_wkq_comp_free(struct completion *comp) +{ + kfree(comp); +} + +#else + +#define AuWkqCompDeclare(name) \ + DECLARE_COMPLETION_ONSTACK(_ ## name); \ + struct completion *comp = &_ ## name + +static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp) +{ + wkinfo->comp = *comp; + return 0; +} + +static void au_wkq_comp_free(struct completion *comp) +{ + /* empty */ +} +#endif /* 4KSTACKS */ + +/* todo: break to three funcs */ +int au_wkq_run(au_wkq_func_t func, void *args, struct super_block *sb, + unsigned int flags) +{ + int err; + AuWkqCompDeclare(comp); + struct au_wkinfo _wkinfo = { + .flags = flags, + .func = func, + .args = args + }, *wkinfo = &_wkinfo; + const unsigned char do_wait = au_ftest_wkq(flags, WAIT); + + LKTRTrace("0x%x\n", flags); +#if 1 /* tmp debug */ + if (au_test_wkq(current)) + au_dbg_blocked(); +#endif + AuDebugOn(au_test_wkq(current)); + + if (do_wait) { + err = au_wkq_comp_alloc(wkinfo, &comp); + if (unlikely(err)) + goto out; + } else { + AuDebugOn(!sb); + /* + * wkq_func() must free this wkinfo. + * it highly depends upon the implementation of workqueue. + */ + err = -ENOMEM; + wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS); + if (unlikely(!wkinfo)) + goto out; + + err = 0; + wkinfo->sb = sb; + wkinfo->flags = flags; + wkinfo->func = func; + wkinfo->args = args; + wkinfo->comp = NULL; + kobject_get(&au_sbi(sb)->si_kobj); + __module_get(THIS_MODULE); + } + + INIT_WORK(&wkinfo->wk, wkq_func); + dlgt_cred_store(flags, wkinfo); + do_wkq(wkinfo); + if (do_wait) { + /* no timeout, no interrupt */ + wait_for_completion(wkinfo->comp); + au_wkq_comp_free(comp); + } + out: + AuTraceErr(err); + return err; +} + +int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb, + int dlgt) +{ + int err; + unsigned int flags = !AuWkq_WAIT; + + AuTraceEnter(); + + if (unlikely(dlgt)) + au_fset_wkq(flags, DLGT); + atomic_inc_return(&au_sbi(sb)->si_nowait.nw_len); + err = au_wkq_run(func, args, sb, flags); + if (unlikely(err)) + atomic_dec_return(&au_sbi(sb)->si_nowait.nw_len); + + return err; +} + +/* ---------------------------------------------------------------------- */ + +void au_wkq_fin(void) +{ + int i; + + AuTraceEnter(); + + for (i = 0; i < aufs_nwkq; i++) + if (au_wkq[i].q && !IS_ERR(au_wkq[i].q)) + destroy_workqueue(au_wkq[i].q); + kfree(au_wkq); +} + +int __init au_wkq_init(void) +{ + int err, i; + struct au_wkq *nowaitq; + + LKTRTrace("%d\n", aufs_nwkq); + + /* '+1' is for accounting of nowait queue */ + err = -ENOMEM; + au_wkq = kcalloc(aufs_nwkq + 1, sizeof(*au_wkq), GFP_NOFS); + if (unlikely(!au_wkq)) + goto out; + + err = 0; + for (i = 0; i < aufs_nwkq; i++) { + au_wkq[i].q = create_singlethread_workqueue(AUFS_WKQ_NAME); + if (au_wkq[i].q && !IS_ERR(au_wkq[i].q)) { + atomic_set(&au_wkq[i].busy, 0); + au_wkq_max_busy_init(au_wkq + i); + continue; + } + + err = PTR_ERR(au_wkq[i].q); + au_wkq_fin(); + break; + } + + /* nowait accounting */ + nowaitq = au_wkq + aufs_nwkq; + atomic_set(&nowaitq->busy, 0); + au_wkq_max_busy_init(nowaitq); + nowaitq->q = NULL; + /* smp_mb(); */ /* atomic_set */ + + out: + AuTraceErr(err); + return err; +} --- linux-2.6.28.orig/ubuntu/aufs/i_op.c +++ linux-2.6.28/ubuntu/aufs/i_op.c @@ -0,0 +1,1003 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * inode operations (except add/del/rename) + * + * $Id: i_op.c,v 1.19 2008/09/08 02:39:57 sfjro Exp $ + */ + +#include +#include +#include "aufs.h" + +static int silly_lock(struct inode *inode, struct nameidata *nd) +{ + int locked = 0; + struct super_block *sb = inode->i_sb; + + LKTRTrace("i%lu, nd %p\n", inode->i_ino, nd); + + if (!nd || !nd->path.dentry) { + si_read_lock(sb, AuLock_FLUSH); + ii_read_lock_child(inode); + } else if (nd->path.dentry->d_inode != inode) { + locked = 1; + /* lock child first, then parent */ + si_read_lock(sb, AuLock_FLUSH); + ii_read_lock_child(inode); + di_read_lock_parent(nd->path.dentry, 0); + } else { + locked = 2; + aufs_read_lock(nd->path.dentry, AuLock_FLUSH | AuLock_IR); + } + return locked; +} + +static void silly_unlock(int locked, struct inode *inode, struct nameidata *nd) +{ + struct super_block *sb = inode->i_sb; + + LKTRTrace("locked %d, i%lu, nd %p\n", locked, inode->i_ino, nd); + + switch (locked) { + case 0: + ii_read_unlock(inode); + si_read_unlock(sb); + break; + case 1: + di_read_unlock(nd->path.dentry, 0); + ii_read_unlock(inode); + si_read_unlock(sb); + break; + case 2: + aufs_read_unlock(nd->path.dentry, AuLock_IR); + break; + default: + BUG(); + } +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) +static int h_permission(struct inode *h_inode, int mask, + struct vfsmount *h_mnt, int brperm, int dlgt) +{ + int err, submask; + const int write_mask = (mask & (MAY_WRITE | MAY_APPEND)); + + LKTRTrace("ino %lu, mask 0x%x, brperm 0x%x\n", + h_inode->i_ino, mask, brperm); + + err = -EACCES; + if (unlikely((write_mask && IS_IMMUTABLE(h_inode)) + || ((mask & MAY_EXEC) && S_ISREG(h_inode->i_mode) + && (h_mnt->mnt_flags & MNT_NOEXEC)) + )) + goto out; + + /* + * - skip hidden fs test in the case of write to ro branch. + * - nfs dir permission write check is optimized, but a policy for + * link/rename requires a real check. + */ + submask = mask & ~MAY_APPEND; + if ((write_mask && !au_br_writable(brperm)) + || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode) + && write_mask && !(mask & MAY_READ)) + || !h_inode->i_op + || !h_inode->i_op->permission) { + /* LKTRLabel(generic_permission); */ + err = generic_permission(h_inode, submask, NULL); + } else { + /* LKTRLabel(h_inode->permission); */ + err = h_inode->i_op->permission(h_inode, submask); + AuTraceErr(err); + } + +#if 1 /* todo: export? */ + if (!err) + err = au_security_inode_permission(h_inode, mask, NULL, + dlgt); +#endif + + out: + AuTraceErr(err); + return err; +} + +static int aufs_permission(struct inode *inode, int mask) +{ + int err; + aufs_bindex_t bindex, bend; + unsigned char locked, dlgt; + const unsigned char isdir = S_ISDIR(inode->i_mode); + struct inode *h_inode; + struct super_block *sb; + unsigned int mnt_flags; + const int write_mask = (mask & (MAY_WRITE | MAY_APPEND)); + + LKTRTrace("ino %lu, mask 0x%x, isdir %d, write_mask %d\n", + inode->i_ino, mask, isdir, write_mask); + + sb = inode->i_sb; + locked = silly_lock(inode, NULL); + mnt_flags = au_mntflags(sb); + dlgt = !!au_test_dlgt(mnt_flags); + + if (/* unlikely */(!isdir || write_mask + || au_test_dirperm1(mnt_flags))) { + h_inode = au_h_iptr(inode, au_ibstart(inode)); + AuDebugOn(!h_inode + || ((h_inode->i_mode & S_IFMT) + != (inode->i_mode & S_IFMT))); + err = 0; + bindex = au_ibstart(inode); + LKTRTrace("b%d\n", bindex); + err = h_permission(h_inode, mask, au_sbr_mnt(sb, bindex), + au_sbr_perm(sb, bindex), dlgt); + + if (write_mask && !err) { + /* test whether the upper writable branch exists */ + err = -EROFS; + for (; bindex >= 0; bindex--) + if (!au_br_rdonly(au_sbr(sb, bindex))) { + err = 0; + break; + } + } + goto out; + } + + /* non-write to dir */ + err = 0; + bend = au_ibend(inode); + for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) { + h_inode = au_h_iptr(inode, bindex); + if (!h_inode) + continue; + AuDebugOn(!S_ISDIR(h_inode->i_mode)); + + LKTRTrace("b%d\n", bindex); + err = h_permission(h_inode, mask, au_sbr_mnt(sb, bindex), + au_sbr_perm(sb, bindex), dlgt); + } + + out: + silly_unlock(locked, inode, NULL); + AuTraceErr(err); + return err; +} +#else + +static int h_permission(struct inode *h_inode, int mask, + struct nameidata *fake_nd, int brperm, int dlgt) +{ + int err, submask; + const int write_mask = (mask & (MAY_WRITE | MAY_APPEND)); + + LKTRTrace("ino %lu, mask 0x%x, brperm 0x%x\n", + h_inode->i_ino, mask, brperm); + + err = -EACCES; + if (unlikely((write_mask && IS_IMMUTABLE(h_inode)) + || ((mask & MAY_EXEC) && S_ISREG(h_inode->i_mode) + && fake_nd && fake_nd->path.mnt + && (fake_nd->path.mnt->mnt_flags & MNT_NOEXEC)) + )) + goto out; + + /* + * - skip hidden fs test in the case of write to ro branch. + * - nfs dir permission write check is optimized, but a policy for + * link/rename requires a real check. + */ + submask = mask & ~MAY_APPEND; + if ((write_mask && !au_br_writable(brperm)) + || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode) + && write_mask && !(mask & MAY_READ)) + || !h_inode->i_op + || !h_inode->i_op->permission) { + /* LKTRLabel(generic_permission); */ + err = generic_permission(h_inode, submask, NULL); + } else { + /* LKTRLabel(h_inode->permission); */ + err = h_inode->i_op->permission(h_inode, submask, fake_nd); + AuTraceErr(err); + } + +#if 1 /* todo: export? */ + if (!err) + err = au_security_inode_permission(h_inode, mask, fake_nd, + dlgt); +#endif + + out: + AuTraceErr(err); + return err; +} + +static int aufs_permission(struct inode *inode, int mask, struct nameidata *nd) +{ + int err; + aufs_bindex_t bindex, bend; + unsigned char locked, dlgt, do_nd; + const unsigned char isdir = S_ISDIR(inode->i_mode); + struct inode *h_inode; + struct super_block *sb; + unsigned int mnt_flags; + struct path path; + const int write_mask = (mask & (MAY_WRITE | MAY_APPEND)); + + LKTRTrace("ino %lu, mask 0x%x, isdir %d, write_mask %d, " + "nd %d{%d, %d}\n", + inode->i_ino, mask, isdir, write_mask, + !!nd, nd ? !!nd->path.dentry : 0, nd ? !!nd->path.mnt : 0); + + sb = inode->i_sb; + locked = silly_lock(inode, nd); + do_nd = (nd && locked >= 1); + mnt_flags = au_mntflags(sb); + dlgt = !!au_test_dlgt(mnt_flags); + + if (/* unlikely */(!isdir || write_mask + || au_test_dirperm1(mnt_flags))) { + h_inode = au_h_iptr(inode, au_ibstart(inode)); + AuDebugOn(!h_inode + || ((h_inode->i_mode & S_IFMT) + != (inode->i_mode & S_IFMT))); + err = 0; + bindex = au_ibstart(inode); + LKTRTrace("b%d\n", bindex); + if (do_nd) { + path = nd->path; + nd->path.mnt = au_sbr_mnt(sb, bindex); + nd->path.dentry = au_h_dptr(nd->path.dentry, bindex); + path_get(&nd->path); + err = h_permission(h_inode, mask, nd, + au_sbr_perm(sb, bindex), dlgt); + path_put(&nd->path); + nd->path = path; + } else { + AuDebugOn(nd && nd->path.mnt); + err = h_permission(h_inode, mask, nd, + au_sbr_perm(sb, bindex), dlgt); + } + + if (write_mask && !err) { + /* test whether the upper writable branch exists */ + err = -EROFS; + for (; bindex >= 0; bindex--) + if (!au_br_rdonly(au_sbr(sb, bindex))) { + err = 0; + break; + } + } + goto out; + } + + /* non-write to dir */ + if (do_nd) + path = nd->path; + else { + path.mnt = NULL; + path.dentry = NULL; + } + err = 0; + bend = au_ibend(inode); + for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) { + h_inode = au_h_iptr(inode, bindex); + if (!h_inode) + continue; + AuDebugOn(!S_ISDIR(h_inode->i_mode)); + + LKTRTrace("b%d\n", bindex); + if (do_nd) { + nd->path.mnt = au_sbr_mnt(sb, bindex); + nd->path.dentry = au_h_dptr(path.dentry, bindex); + path_get(&nd->path); + err = h_permission(h_inode, mask, nd, + au_sbr_perm(sb, bindex), dlgt); + path_put(&nd->path); + } else { + AuDebugOn(nd && nd->path.mnt); + err = h_permission(h_inode, mask, nd, + au_sbr_perm(sb, bindex), dlgt); + } + } + if (do_nd) + nd->path = path; + + out: + silly_unlock(locked, inode, nd); + AuTraceErr(err); + return err; +} +#endif /* KERNEL_VERSION(2, 6, 27) */ + +/* ---------------------------------------------------------------------- */ + +static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry, + struct nameidata *nd) +{ + struct dentry *ret, *parent; + int err, npositive; + struct inode *inode, *h_inode; + struct nameidata tmp_nd, *ndp; + aufs_bindex_t bstart; + struct mutex *mtx; + struct super_block *sb; + + LKTRTrace("dir %lu, %.*s, nd{0x%x}\n", + dir->i_ino, AuDLNPair(dentry), nd ? nd->flags : 0); + AuDebugOn(IS_ROOT(dentry)); + IMustLock(dir); + + sb = dir->i_sb; + si_read_lock(sb, AuLock_FLUSH); + err = au_alloc_dinfo(dentry); + ret = ERR_PTR(err); + if (unlikely(err)) + goto out; + + /* nd can be NULL */ + ndp = au_dup_nd(au_sbi(sb), &tmp_nd, nd); + parent = dentry->d_parent; /* dir inode is locked */ + di_read_lock_parent(parent, AuLock_IR); + npositive = au_lkup_dentry(dentry, au_dbstart(parent), /*type*/0, ndp); + di_read_unlock(parent, AuLock_IR); + err = npositive; + ret = ERR_PTR(err); + if (unlikely(err < 0)) + goto out_unlock; + + inode = NULL; + if (npositive) { + bstart = au_dbstart(dentry); + h_inode = au_h_dptr(dentry, bstart)->d_inode; + AuDebugOn(!h_inode); + if (!S_ISDIR(h_inode->i_mode)) { + /* + * stop 'race'-ing between hardlinks under different + * parents. + */ + mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx; + mutex_lock(mtx); + inode = au_new_inode(dentry); + mutex_unlock(mtx); + } else + inode = au_new_inode(dentry); + ret = (void *)inode; + } + if (!IS_ERR(inode)) { + ret = d_splice_alias(inode, dentry); + if (unlikely(IS_ERR(ret) && inode)) + ii_write_unlock(inode); + AuDebugOn(nd + && (nd->flags & LOOKUP_OPEN) + && nd->intent.open.file + && nd->intent.open.file->f_dentry); + au_store_fmode_exec(nd, inode); + } + + out_unlock: + di_write_unlock(dentry); + out: + si_read_unlock(sb); + AuTraceErrPtr(ret); + return ret; +} + +/* ---------------------------------------------------------------------- */ + +/* + * decide the branch and the parent dir where we will create a new entry. + * returns new bindex or an error. + * copyup the parent dir if needed. + */ +int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry, + struct au_wr_dir_args *args) +{ + int err; + aufs_bindex_t bcpup, bstart, src_bstart; + struct super_block *sb; + struct dentry *parent; + struct au_sbinfo *sbinfo; + const int add_entry = au_ftest_wrdir(args->flags, ADD_ENTRY); + + LKTRTrace("%.*s, src %p, {%d, 0x%x}\n", + AuDLNPair(dentry), src_dentry, args->force_btgt, args->flags); + + sb = dentry->d_sb; + sbinfo = au_sbi(sb); + parent = dget_parent(dentry); + bstart = au_dbstart(dentry); + bcpup = bstart; + if (args->force_btgt < 0) { + if (src_dentry) { + src_bstart = au_dbstart(src_dentry); + if (src_bstart < bstart) + bcpup = src_bstart; + } else if (add_entry) { + err = AuWbrCreate(sbinfo, dentry, + au_ftest_wrdir(args->flags, ISDIR)); + bcpup = err; + } + + if (bcpup < 0 || au_test_ro(sb, bcpup, dentry->d_inode)) { + if (add_entry) + err = AuWbrCopyup(sbinfo, dentry); + else { + di_read_lock_parent(parent, !AuLock_IR); + err = AuWbrCopyup(sbinfo, dentry); + di_read_unlock(parent, !AuLock_IR); + } + bcpup = err; + if (unlikely(err < 0)) + goto out; + } + } else { + bcpup = args->force_btgt; + AuDebugOn(au_test_ro(sb, bcpup, dentry->d_inode)); + } + LKTRTrace("bstart %d, bcpup %d\n", bstart, bcpup); + if (bstart < bcpup) + au_update_dbrange(dentry, /*do_put_zero*/1); + + err = bcpup; + if (bcpup == bstart) + goto out; /* success */ + + /* copyup the new parent into the branch we process */ + if (add_entry) { + au_update_dbstart(dentry); + IMustLock(parent->d_inode); + DiMustWriteLock(parent); + IiMustWriteLock(parent->d_inode); + } else + di_write_lock_parent(parent); + + err = 0; + if (!au_h_dptr(parent, bcpup)) { + if (bstart < bcpup) + err = au_cpdown_dirs(dentry, bcpup); + else + err = au_cpup_dirs(dentry, bcpup); + } + if (!err && add_entry) { + struct dentry *h_parent; + struct inode *h_dir; + + h_parent = au_h_dptr(parent, bcpup); + AuDebugOn(!h_parent); + h_dir = h_parent->d_inode; + AuDebugOn(!h_dir); + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); + err = au_lkup_neg(dentry, bcpup); + mutex_unlock(&h_dir->i_mutex); + if (bstart < bcpup && au_dbstart(dentry) < 0) { + au_set_dbstart(dentry, 0); + au_update_dbrange(dentry, /*do_put_zero*/0); + } + } + + if (!add_entry) + di_write_unlock(parent); + if (!err) + err = bcpup; /* success */ + out: + dput(parent); + LKTRTrace("err %d\n", err); + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct dentry *au_do_pinned_h_parent(struct au_pin1 *pin, aufs_bindex_t bindex) +{ + if (pin && pin->parent) + return au_h_dptr(pin->parent, bindex); + return NULL; +} + +void au_do_unpin(struct au_pin1 *p, struct au_pin1 *gp) +{ + LKTRTrace("%p, %p\n", p, gp); + AuDebugOn(!p); + + if (unlikely(!p->h_dir)) + return; + + LKTRTrace("p{%.*s, %d, %d, %d, %d}\n", + AuDLNPair(p->dentry), p->lsc_di, p->lsc_hi, + !!p->parent, !!p->h_dir); + + mutex_unlock(&p->h_dir->i_mutex); + if (unlikely(gp)) + au_do_unpin(gp, NULL); + if (!p->di_locked) + di_read_unlock(p->parent, AuLock_IR); + iput(p->h_dir); + dput(p->parent); + p->parent = NULL; + p->h_dir = NULL; +} + +int au_do_pin(struct au_pin1 *p, struct au_pin1 *gp, const aufs_bindex_t bindex, + const int do_gp) +{ + int err; + struct dentry *h_dentry; + + LKTRTrace("%.*s, %d, b%d, %d\n", + AuDLNPair(p->dentry), !!gp, bindex, do_gp); + AuDebugOn(do_gp && !gp); + /* AuDebugOn(!do_gp && gp); */ + + err = 0; + if (unlikely(IS_ROOT(p->dentry))) + goto out; + + h_dentry = NULL; + if (bindex <= au_dbend(p->dentry)) + h_dentry = au_h_dptr(p->dentry, bindex); + + p->parent = dget_parent(p->dentry); + if (!p->di_locked) + di_read_lock(p->parent, AuLock_IR, p->lsc_di); + else + DiMustAnyLock(p->parent); + AuDebugOn(!p->parent->d_inode); + p->h_dir = au_igrab(au_h_iptr(p->parent->d_inode, bindex)); + /* udba case */ + if (unlikely(p->do_verify && !p->h_dir)) { + err = -EIO; + if (!p->di_locked) + di_read_unlock(p->parent, AuLock_IR); + dput(p->parent); + p->parent = NULL; + goto out; + } + + if (unlikely(do_gp)) { + gp->dentry = p->parent; + err = au_do_pin(gp, NULL, bindex, 0); + if (unlikely(err)) + gp->dentry = NULL; + } + mutex_lock_nested(&p->h_dir->i_mutex, p->lsc_hi); + if (!err) { + /* todo: call d_revalidate() here? */ + if (!h_dentry + || !p->do_verify + || !au_verify_parent(h_dentry, p->h_dir)) + goto out; /* success */ + else { + AuWarn1("bypassed %.*s/%.*s?\n", + AuDLNPair(p->parent), AuDLNPair(p->dentry)); + err = -EIO; + } + } + + AuDbgDentry(p->dentry); + AuDbgDentry(h_dentry); + AuDbgDentry(p->parent); + AuDbgInode(p->h_dir); + if (h_dentry) + AuDbgDentry(h_dentry->d_parent); + + au_do_unpin(p, gp); + if (unlikely(do_gp)) + gp->dentry = NULL; + + out: + AuTraceErr(err); + return err; +} + +void au_pin_init(struct au_pin *args, struct dentry *dentry, int di_locked, + int lsc_di, int lsc_hi, int do_gp) +{ + struct au_pin1 *p; + unsigned char do_verify; + + AuTraceEnter(); + + memset(args, 0, sizeof(*args)); + p = args->pin + AuPin_PARENT; + p->dentry = dentry; + p->di_locked = di_locked; + p->lsc_di = lsc_di; + p->lsc_hi = lsc_hi; + p->do_verify = !au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE); + if (!do_gp) + return; + + do_verify = p->do_verify; + p = au_pin_gp(args); + if (unlikely(p)) { + p->lsc_di = lsc_di + 1; /* child first */ + p->lsc_hi = lsc_hi - 1; /* parent first */ + p->do_verify = do_verify; + } +} + +int au_pin(struct au_pin *args, struct dentry *dentry, aufs_bindex_t bindex, + int di_locked, int do_gp) +{ + LKTRTrace("%.*s, b%d, di_locked %d, do_gp %d\n", + AuDLNPair(dentry), bindex, di_locked, do_gp); + + au_pin_init(args, dentry, di_locked, AuLsc_DI_PARENT, AuLsc_I_PARENT2, + do_gp); + return au_do_pin(args->pin + AuPin_PARENT, au_pin_gp(args), bindex, do_gp); +} + +/* ---------------------------------------------------------------------- */ + +struct au_icpup_args { + aufs_bindex_t btgt; + unsigned char isdir, hinotify, did_cpup; /* flags */ + struct dentry *h_dentry; + struct inode *h_inode; + struct au_pin pin; + struct au_hin_ignore ign[2]; + struct vfsub_args vargs; +}; + +/* todo: refine it */ +static int au_lock_and_icpup(struct dentry *dentry, loff_t sz, + struct au_icpup_args *a) +{ + int err; + aufs_bindex_t bstart; + struct super_block *sb; + struct dentry *hi_wh, *parent; + struct inode *inode; + struct au_wr_dir_args wr_dir_args = { + .force_btgt = -1, + .flags = 0 + }; + + LKTRTrace("%.*s, %lld\n", AuDLNPair(dentry), sz); + + di_write_lock_child(dentry); + bstart = au_dbstart(dentry); + sb = dentry->d_sb; + inode = dentry->d_inode; + a->isdir = !!S_ISDIR(inode->i_mode); + if (unlikely(a->isdir)) + au_fset_wrdir(wr_dir_args.flags, ISDIR); + /* plink or hi_wh() */ + if (bstart != au_ibstart(inode)) + wr_dir_args.force_btgt = au_ibstart(inode); + err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args); + if (unlikely(err < 0)) + goto out_dentry; + a->btgt = err; + a->did_cpup = (err != bstart); + err = 0; + + /* crazy udba locks */ + a->hinotify = !!au_opt_test(au_mntflags(sb), UDBA_INOTIFY); + parent = NULL; + if (!IS_ROOT(dentry)) { + parent = dget_parent(dentry); + di_write_lock_parent(parent); + } + err = au_pin(&a->pin, dentry, a->btgt, /*di_locked*/!!parent, + /*dp_gp*/a->hinotify); + if (unlikely(err)) { + if (parent) { + di_write_unlock(parent); + dput(parent); + } + goto out_dentry; + } + a->h_dentry = au_h_dptr(dentry, bstart); + a->h_inode = a->h_dentry->d_inode; + AuDebugOn(!a->h_inode); + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); + if (!a->did_cpup) { + au_unpin_gp(&a->pin); + if (parent) { + au_pin_set_parent_lflag(&a->pin, /*lflag*/0); + di_downgrade_lock(parent, AuLock_IR); + dput(parent); + } + goto out; /* success */ + } + + hi_wh = NULL; + if (!d_unhashed(dentry)) { + if (parent) { + au_pin_set_parent_lflag(&a->pin, /*lflag*/0); + di_downgrade_lock(parent, AuLock_IR); + dput(parent); + } + err = au_sio_cpup_simple(dentry, a->btgt, sz, AuCpup_DTIME); + if (!err) + a->h_dentry = au_h_dptr(dentry, a->btgt); + } else { + hi_wh = au_hi_wh(inode, a->btgt); + if (!hi_wh) { + err = au_sio_cpup_wh(dentry, a->btgt, sz, + /*file*/NULL); + if (!err) + hi_wh = au_hi_wh(inode, a->btgt); + /* todo: revalidate hi_wh? */ + } + if (parent) { + au_pin_set_parent_lflag(&a->pin, /*lflag*/0); + di_downgrade_lock(parent, AuLock_IR); + dput(parent); + } + if (!hi_wh) + a->h_dentry = au_h_dptr(dentry, a->btgt); + else + a->h_dentry = hi_wh; /* do not dget here */ + } + + mutex_unlock(&a->h_inode->i_mutex); + a->h_inode = a->h_dentry->d_inode; + AuDebugOn(!a->h_inode); + if (!err) { + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); + au_unpin_gp(&a->pin); + goto out; /* success */ + } + + au_unpin(&a->pin); + + out_dentry: + di_write_unlock(dentry); + out: + AuTraceErr(err); + return err; +} + +static int aufs_setattr(struct dentry *dentry, struct iattr *ia) +{ + int err; + struct inode *inode; + struct super_block *sb; + __u32 events; + struct file *file; + loff_t sz; + struct au_icpup_args *a; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + inode = dentry->d_inode; + IMustLock(inode); + + err = -ENOMEM; + a = kzalloc(sizeof(*a), GFP_NOFS); + if (unlikely(!a)) + goto out; + + file = NULL; + sb = dentry->d_sb; + si_read_lock(sb, AuLock_FLUSH); + vfsub_args_init(&a->vargs, a->ign, au_test_dlgt(au_mntflags(sb)), 0); + + if (ia->ia_valid & ATTR_FILE) { + /* currently ftruncate(2) only */ + file = ia->ia_file; + fi_write_lock(file); + ia->ia_file = au_h_fptr(file, au_fbstart(file)); + } + + sz = -1; + if ((ia->ia_valid & ATTR_SIZE) + && ia->ia_size < i_size_read(inode)) + sz = ia->ia_size; + err = au_lock_and_icpup(dentry, sz, a); + if (unlikely(err < 0)) + goto out_si; + if (a->did_cpup) { + ia->ia_file = NULL; + ia->ia_valid &= ~ATTR_FILE; + } + + if ((ia->ia_valid & ATTR_SIZE) + && ia->ia_size < i_size_read(inode)) { + err = vmtruncate(inode, ia->ia_size); + if (unlikely(err)) + goto out_unlock; + } + + if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) + ia->ia_valid &= ~ATTR_MODE; + + events = 0; + if (unlikely(a->hinotify)) { + events = vfsub_events_notify_change(ia); + if (events) { + if (unlikely(a->isdir)) + vfsub_ign_hinode(&a->vargs, events, + au_hi(inode, a->btgt)); + vfsub_ign_hinode(&a->vargs, events, + au_pinned_hdir(&a->pin, a->btgt)); + } + } + err = vfsub_notify_change(a->h_dentry, ia, &a->vargs); + if (!err) + au_cpup_attr_changeable(inode); + + out_unlock: + mutex_unlock(&a->h_inode->i_mutex); + au_unpin(&a->pin); + di_write_unlock(dentry); + out_si: + if (file) { + fi_write_unlock(file); + ia->ia_file = file; + ia->ia_valid |= ATTR_FILE; + } + si_read_unlock(sb); + kfree(a); + out: + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static int h_readlink(struct dentry *dentry, int bindex, char __user *buf, + int bufsiz) +{ + struct super_block *sb; + struct dentry *h_dentry; + + LKTRTrace("%.*s, b%d, %d\n", AuDLNPair(dentry), bindex, bufsiz); + + h_dentry = au_h_dptr(dentry, bindex); + if (unlikely(/* !h_dentry + || !h_dentry->d_inode + || */ + !h_dentry->d_inode->i_op + || !h_dentry->d_inode->i_op->readlink)) + return -EINVAL; + + sb = dentry->d_sb; + if (!au_test_ro(sb, bindex, dentry->d_inode)) { + touch_atime(au_sbr_mnt(sb, bindex), h_dentry); + au_update_fuse_h_inode(NULL, h_dentry); /*ignore*/ + fsstack_copy_attr_atime(dentry->d_inode, h_dentry->d_inode); + } + return h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz); +} + +static int aufs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) +{ + int err; + + LKTRTrace("%.*s, %d\n", AuDLNPair(dentry), bufsiz); + + aufs_read_lock(dentry, AuLock_IR); + err = h_readlink(dentry, au_dbstart(dentry), buf, bufsiz); + aufs_read_unlock(dentry, AuLock_IR); + AuTraceErr(err); + return err; +} + +static void *aufs_follow_link(struct dentry *dentry, struct nameidata *nd) +{ + int err; + char *buf; + mm_segment_t old_fs; + + LKTRTrace("%.*s, nd %.*s\n", + AuDLNPair(dentry), AuDLNPair(nd->path.dentry)); + + err = -ENOMEM; + buf = __getname(); + if (unlikely(!buf)) + goto out; + + aufs_read_lock(dentry, AuLock_IR); + old_fs = get_fs(); + set_fs(KERNEL_DS); + err = h_readlink(dentry, au_dbstart(dentry), (char __user *)buf, + PATH_MAX); + set_fs(old_fs); + aufs_read_unlock(dentry, AuLock_IR); + + if (err >= 0) { + buf[err] = 0; + /* will be freed by put_link */ + nd_set_link(nd, buf); + return NULL; /* success */ + } + __putname(buf); + + out: + path_put(&nd->path); + AuTraceErr(err); + return ERR_PTR(err); +} + +static void aufs_put_link(struct dentry *dentry, struct nameidata *nd, + void *cookie) +{ + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + __putname(nd_get_link(nd)); +} + +/* ---------------------------------------------------------------------- */ + +static void aufs_truncate_range(struct inode *inode, loff_t start, loff_t end) +{ + AuUnsupport(); +} + +/* ---------------------------------------------------------------------- */ + +struct inode_operations aufs_symlink_iop = { + .permission = aufs_permission, + .setattr = aufs_setattr, +#ifdef CONFIG_AUFS_HIN_OR_FUSE + .getattr = aufs_getattr, +#endif + + .readlink = aufs_readlink, + .follow_link = aufs_follow_link, + .put_link = aufs_put_link +}; + +struct inode_operations aufs_dir_iop = { + .create = aufs_create, + .lookup = aufs_lookup, + .link = aufs_link, + .unlink = aufs_unlink, + .symlink = aufs_symlink, + .mkdir = aufs_mkdir, + .rmdir = aufs_rmdir, + .mknod = aufs_mknod, + .rename = aufs_rename, + + .permission = aufs_permission, + .setattr = aufs_setattr, +#ifdef CONFIG_AUFS_HIN_OR_FUSE + .getattr = aufs_getattr, +#endif + +#if 0 /* reserved for future use */ + .setxattr = aufs_setxattr, + .getxattr = aufs_getxattr, + .listxattr = aufs_listxattr, + .removexattr = aufs_removexattr +#endif +}; + +struct inode_operations aufs_iop = { + .permission = aufs_permission, + .setattr = aufs_setattr, +#ifdef CONFIG_AUFS_HIN_OR_FUSE + .getattr = aufs_getattr, +#endif + +#if 0 /* reserved for future use */ + .setxattr = aufs_setxattr, + .getxattr = aufs_getxattr, + .listxattr = aufs_listxattr, + .removexattr = aufs_removexattr, +#endif + + .truncate_range = aufs_truncate_range +}; --- linux-2.6.28.orig/ubuntu/aufs/Kconfig +++ linux-2.6.28/ubuntu/aufs/Kconfig @@ -0,0 +1,265 @@ +config AUFS + tristate "Another unionfs" + help + Aufs is a stackable unification filesystem such as Unionfs, + which unifies several directories and provides a merged single + directory. + In the early days, aufs was entirely re-designed and + re-implemented Unionfs Version 1.x series. After many original + ideas, approaches and improvements, it becomes totally + different from Unionfs while keeping the basic features. + See Unionfs for the basic features. +if AUFS +comment "These options are for 2.6.27-3-generic" +choice + prompt "Maximum number of branches" + default AUFS_BRANCH_MAX_127 + help + Specifies the maximum number of branches (or member directories) in a single aufs. The larger value consumes more system resources and has an impact to performance. +config AUFS_BRANCH_MAX_127 + bool "127" + help + Specifies the maximum number of branches (or member directories) in a single aufs. The larger value consumes more system resources and has an impact to performance. +config AUFS_BRANCH_MAX_511 + bool "511" + help + Specifies the maximum number of branches (or member directories) in a single aufs. The larger value consumes more system resources and has an impact to performance. +config AUFS_BRANCH_MAX_1023 + bool "1023" + help + Specifies the maximum number of branches (or member directories) in a single aufs. The larger value consumes more system resources and has an impact to performance. +config AUFS_BRANCH_MAX_32767 + bool "32767" + help + Specifies the maximum number of branches (or member directories) in a single aufs. The larger value consumes more system resources and has an impact to performance. +endchoice +config AUFS_STAT + bool "Use /fs/aufs/stat" + depends on SYSFS + help + Shows some statistic data via /fs/aufs/stat. + See detail in aufs.5. +comment "SYSFS and AUFS_STAT are disabled" + depends on SYSFS = n +config AUFS_HINOTIFY + bool "Use inotify to detect actions on a branch" + depends on INOTIFY + help + If you want to modify files on branches directly, eg. bypassing aufs, + and want aufs to detect the changes of them fully, then enable this + option and use 'udba=inotify' mount option. + It will have a negative impact to the performance. + See detail in aufs.5. +comment "INOTIFY and AUFS_HINOTIFY are disabled" + depends on INOTIFY = n +config AUFS_EXPORT + bool "NFS-exportable aufs" + depends on (AUFS = y && EXPORTFS = y) || (AUFS = m && EXPORTFS) + help + If you want to export your mounted aufs, then enable this + option. There are several requirements to export aufs. + See detail in aufs.5. +comment "EXPORTFS and AUFS_EXPORT are disabled" + depends on EXPORTFS = n +comment "AUFS_EXPORT is disabled since EXPORTFS is a module but AUFS" + depends on EXPORTFS = m && AUFS = y +config AUFS_INO_T_64 + bool + depends on 64BIT && !(ALPHA || S390) + default y +config AUFS_ROBR + bool "Aufs as an readonly branch of another aufs mount" + help + If you want make your aufs to be a part of another aufs, then + enable this option. In other words, you can specify your aufs + path in 'br:' mount option for another aufs, but cannot + specify 'rw' as the branch permission. + It will have a negative impact to the performance. + See detail in aufs.5. +config AUFS_DLGT + bool "Delegate the internal branch access the kernel thread" + help + If you want aufs to delegate + the internal access to the branches which is made by aufs, to + the kernel thread, in order to hide the access issued by your + application from your LSM or something or make your + application to be traced strictly by the task I/O accounting, + then enable this option and use 'dlgt' mount option. + It will have a negative impact to the performance. + See detail in aufs.5. +config AUFS_HIN_OR_DLGT + bool + depends on AUFS_HINOTIFY || AUFS_DLGT + default y + help + Automatic configuration for internal use. +config AUFS_SHWH + bool "Show whiteouts" + help + If you want to make the whiteouts in aufs visible, then enable + this option and specify 'shwh' mount option. Although it may + sounds like philosophy or something, but in technically it + simply shows the name of whiteout with keeping its behaviour. +config AUFS_RR_SQUASHFS + bool "Make squashfs branch RR (real readonly) by default" + default y + help + If you use squashfs or LZMA patched squashfs as an aufs branch + and want to set '=rr' to it by default, then enable this + configuration. + 'rr' stands for real readonly and it optimizes some aspects of + 'ro.' + See detail in aufs.5. +config AUFS_SEC_PERM_PATCH + bool "sec_perm-2.6.24.patch was applied or not" + depends on AUFS = m + depends on SECURITY + help + If you build aufs as a module and enabled CONFIG_SECURITY, + then you need to apply the patch + 'CVS_TREE/aufs/patch/sec_perm-2.6.24.patch' to your kernel + source, and enable this configuration. + The sec_perm-2.6.24.patch exports a kernel function + security_inode_permission() to modules. +comment "SECURITY and AUFS_SEC_PERM_PATCH are disabled" + depends on SECURITY = n +config AUFS_SPLICE_PATCH + bool "splice.patch for sendfile(2) and splice(2)" + help + If you use 'loopback mount' on a fs-image file, or use + splice(2) or sendfile(2) systemcall in aufs, then you need to + apply the patch 'CVS_TREE/aufs/patch/splice.patch' to your + kernel source, and enable this configuration. + The splice.patch makes the kernel function do_splice_to/from() + global and exports them to modules. +config AUFS_PUT_FILP_PATCH + bool "put_filp.patch for NFS branch" + depends on AUFS = m + depends on NFS_FS + help + If you build aufs as a module and use mounted NFS as an aufs + branch filesystem, then you need to apply the patch + 'CVS_TREE/aufs/patch/put_filp.patch' to your kernel source, + and enable this configuration. + The put_filp.patch exports a kernel function put_filp() to + modules. +comment "NFS_FS and AUFS_PUT_FILP_PATCH are disabled" + depends on NFS_FS = n +config AUFS_LHASH_PATCH + bool "lhash.patch for NFS branch" + depends on NFS_FS + help + If you use mounted NFS as an aufs branch filesystem, then you + need to apply the patch 'CVS_TREE/aufs/patch/lhash.patch' (or + lhash-2.6.22.patch for linux-2.6.22 and later) to your kernel + source, and enable this configuration. + The patch file makes the kernel function __lookup_hash() global + and exports it to modules. +comment "NFS_FS and AUFS_LHASH_PATCH are disabled" + depends on NFS_FS = n +config AUFS_BR_NFS + bool + depends on NFS_FS + default n if (!AUFS_LHASH_PATCH || !(AUFS = y || AUFS_PUT_FILP_PATCH)) + default y + help + Automatic configuration for internal use. + When aufs supports NFS branch, enabled automatically. +config AUFS_BR_XFS + bool + depends on XFS_FS + default y + help + Automatic configuration for internal use. + When aufs supports XFS branch, enabled automatically. +config AUFS_FSYNC_SUPER_PATCH + bool "fsync_super-2.6.xx.patch was applied or not" + depends on AUFS = m + help + If you build aufs as a module and want to flush everything for + branch filesystems which are not marked as 'rr' nor 'rr+wh' at + umount or remount time, then you need to apply the patch + 'CVS_TREE/aufs/patch/fsync_super-2.6.16.patch' or + '...-2.6.19.patch' to your kernel source, and enable this + configuration. + It may be helpful at shutdown time in case of your aufs is a + root filesystem. But this behaviour will not guarantee the + consistency of branch filesystems. To guarantee it, try the + approach described in the aufs manual, and do not forget + installing auplink script. + The fsync_super-2.6.xx.patch does nothing but exports a kernel + function fsync_super() to modules. +config AUFS_DENY_WRITE_ACCESS_PATCH + bool "deny_write_access.patch was applied or not" + depends on AUFS = m + help + A security enhancement to deny writing to a running executable + which exists on an aufs branch filesystem and executed through + aufs. If you applied + 'CVS_TREE/aufs/patch/deny_write_access.patch' to your kernel + and you are compiling aufs as a module, then enable this + option. + The write_deny_access.patch does nothing but export the + function. +config AUFS_WORKAROUND_FUSE + bool "Special handling for FUSE-based filesystem" + depends on FUSE_FS + help + A FUSE-based filesystem may not initialize its inode + attributes and the FUSE developer thinks the inode attributes + in a positive dentry which is returned by VFS lookup operation + are not reliable. + If you use a FUSE-based filesystem as an aufs branch, and it + customizes the inode attribute on it without overriding + fuse_lowlevel_ops.lookup, probably you need to enable this + configuration. + If you enable this configuration, aufs calls getattr operation + in every lookup and revalidate operation for the FUSE-based + filesystem branch. + It will have a negative impact to the performance even if you do + not use a FUSE-based filesystem branch. +config AUFS_HIN_OR_FUSE + bool + depends on AUFS_HINOTIFY || AUFS_WORKAROUND_FUSE + default y + help + Automatic configuration for internal use. +config AUFS_DEBUG + bool "Debug aufs" + default y + help + Enable this to compile aufs internal debug code. + It will have a negative impact to the performance. +config AUFS_MAGIC_SYSRQ + bool + depends on AUFS_DEBUG && MAGIC_SYSRQ + default y + help + Automatic configuration for internal use. + When aufs supports Magic SysRq, enabled automatically. +config AUFS_COMPAT + bool "Compatibility with Unionfs (obsolete)" + help + This makes aufs compatible with unionfs-style mount options and some + behaviours. + The dirs= mount option and =nfsro branch permission flag are always + interpreted as br: mount option and =ro flag respectively. The + 'debug', 'delete' and 'imap' mount options are ignored. + If you disable this option, you will get, + - aufs issues a warning about the ignored mount options + - the default branch permission flag is set. RW for the first branch, + and RO for the rests. + - the name of a internal file which represents the directory is + 'opaque', becomes '.wh..wh..opq' + - the 'diropq=w' mount option is set by default +config AUFS_UNIONFS22_PATCH + bool "Unionfs-2.2 or later patch is applied or not (obsolete)" + help + Unionfs version 2.2 (and later) patch introduces some changes in VFS layer which has an impact to aufs. If you have applied such patch to your kernel, you need to enable this configuration even if you disabled CONFIG_UNIONFS. +config AUFS_UNIONFS23_PATCH + bool "Unionfs-2.3 or later patch is applied or not (obsolete)" + select AUFS_SPLICE_PATCH + select AUFS_UNIONFS22_PATCH + help + Unionfs version 2.3 (and later) patch introduces some changes in VFS layer which has an impact to aufs. If you have applied such patch to your kernel, you need to enable this configuration even if you disabled CONFIG_UNIONFS. +endif --- linux-2.6.28.orig/ubuntu/aufs/module.h +++ linux-2.6.28/ubuntu/aufs/module.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * module initialization and module-global + * + * $Id: module.h,v 1.8 2008/08/25 01:50:37 sfjro Exp $ + */ + +#ifndef __AUFS_MODULE_H__ +#define __AUFS_MODULE_H__ + +#ifdef __KERNEL__ + +/* module parameters */ +extern short aufs_nwkq; +extern int sysaufs_brs; + +/* ---------------------------------------------------------------------- */ + +extern char au_esc_chars[]; +extern int au_dir_roflags; + +/* kmem cache */ +enum { + AuCache_DINFO, + AuCache_ICNTNR, + AuCache_FINFO, + AuCache_VDIR, + AuCache_DEHSTR, +#ifdef CONFIG_AUFS_HINOTIFY + AuCache_HINOTIFY, +#endif + AuCache_Last +}; + +extern struct kmem_cache *au_cachep[]; + +#define AuCacheArgs(type, sz) (type), (sz), 0, SLAB_RECLAIM_ACCOUNT, NULL +#define AuCache(type) \ + kmem_cache_create(AuCacheArgs(#type, sizeof(struct type))) + +/* ---------------------------------------------------------------------- */ + +#define AuCacheFuncs(name, index) \ +static inline void *au_cache_alloc_##name(void) \ +{ return kmem_cache_alloc(au_cachep[index], GFP_NOFS); } \ +static inline void au_cache_free_##name(void *p) \ +{ kmem_cache_free(au_cachep[index], p); } + +AuCacheFuncs(dinfo, AuCache_DINFO); +AuCacheFuncs(icntnr, AuCache_ICNTNR); +AuCacheFuncs(finfo, AuCache_FINFO); +AuCacheFuncs(vdir, AuCache_VDIR); +AuCacheFuncs(dehstr, AuCache_DEHSTR); + +#endif /* __KERNEL__ */ +#endif /* __AUFS_MODULE_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/wkq.h +++ linux-2.6.28/ubuntu/aufs/wkq.h @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * workqueue for asynchronous/super-io/delegated operations + * + * $Id: wkq.h,v 1.7 2008/09/15 03:16:36 sfjro Exp $ + */ + +#ifndef __AUFS_WKQ_H__ +#define __AUFS_WKQ_H__ + +#ifdef __KERNEL__ + +#include +#include +#include +#include + +/* ---------------------------------------------------------------------- */ + +/* internal workqueue named AUFS_WKQ_NAME */ +struct au_wkq { + struct workqueue_struct *q; + + /* balancing */ + atomic_t busy; + + /* accounting */ +#ifdef CONFIG_AUFS_STAT + unsigned int max_busy; +#endif +}; + +/* + * in the next operation, wait for the 'nowait' tasks in system-wide workqueue + */ +struct au_nowait_tasks { + atomic_t nw_len; + wait_queue_head_t nw_wq; +}; + +/* ---------------------------------------------------------------------- */ + +extern struct au_wkq *au_wkq; +typedef void (*au_wkq_func_t)(void *args); + +/* wkq flags */ +#define AuWkq_WAIT 1 +#define AuWkq_DLGT (1 << 1) +#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name) +#define au_fset_wkq(flags, name) { (flags) |= AuWkq_##name; } +#define au_fclr_wkq(flags, name) { (flags) &= ~AuWkq_##name; } +#ifndef CONFIG_AUFS_DLGT +#undef AuWkq_DLGT +#define AuWkq_DLGT 0 +#endif + +int au_wkq_run(au_wkq_func_t func, void *args, struct super_block *sb, + unsigned int flags); +int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb, + int dlgt); +int __init au_wkq_init(void); +void au_wkq_fin(void); + +/* ---------------------------------------------------------------------- */ + +static inline int au_test_wkq(struct task_struct *tsk) +{ + return (!tsk->mm && !strcmp(tsk->comm, AUFS_WKQ_NAME)); +#if 0 /* reserved for future use, per-cpu workqueue */ + return (!tsk->mm + && !memcmp(tsk->comm, AUFS_WKQ_NAME "/", + sizeof(AUFS_WKQ_NAME))); +#endif +} + +static inline int au_wkq_wait(au_wkq_func_t func, void *args, int dlgt) +{ + unsigned int flags = AuWkq_WAIT; + if (unlikely(dlgt)) + au_fset_wkq(flags, DLGT); + return au_wkq_run(func, args, /*sb*/NULL, flags); +} + +static inline void au_wkq_max_busy_init(struct au_wkq *wkq) +{ +#ifdef CONFIG_AUFS_STAT + wkq->max_busy = 0; +#endif +} + +/* todo: memory barrier? */ +static inline void au_nwt_init(struct au_nowait_tasks *nwt) +{ + atomic_set(&nwt->nw_len, 0); + smp_mb(); /* atomic_set */ + init_waitqueue_head(&nwt->nw_wq); +} + +/* todo: make it void */ +static inline int au_nwt_done(struct au_nowait_tasks *nwt) +{ + int ret; + + AuTraceEnter(); + + ret = atomic_dec_return(&nwt->nw_len); + if (!ret) + wake_up_all(&nwt->nw_wq); + return ret; +} + +static inline int au_nwt_flush(struct au_nowait_tasks *nwt) +{ + wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len)); + return 0; +} + +#endif /* __KERNEL__ */ +#endif /* __AUFS_WKQ_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/br_nfs.c +++ linux-2.6.28/ubuntu/aufs/br_nfs.c @@ -0,0 +1,347 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * lookup functions for NFS branch in linux-2.6.19 and later + * + * $Id: br_nfs.c,v 1.7 2008/07/21 02:54:22 sfjro Exp $ + */ + +#include "aufs.h" + +static struct file *au_find_h_intent(struct au_hdentry *hd, struct file *file) +{ + struct file *h_file, *hf; + struct au_hdintent *hdi, *tmp, *do_free; + + LKTRTrace("%.*s\n", AuDLNPair(hd->hd_dentry)); + + h_file = NULL; + do_free = NULL; + spin_lock(&hd->hd_lock); + list_for_each_entry_safe(hdi, tmp, hd->hd_intent_list, hdi_list) { + hf = hdi->hdi_file[AuIntent_BRANCH]; + if (hdi->hdi_file[AuIntent_AUFS] == file + && hf->f_dentry == hd->hd_dentry) { + h_file = hf; + do_free = hdi; + list_del(&hdi->hdi_list); + break; + } + } + spin_unlock(&hd->hd_lock); + kfree(do_free); + + return h_file; +} + +struct file *au_h_intent(struct dentry *dentry, aufs_bindex_t bindex, + struct file *file) +{ + struct file *h_file; + struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex; + + LKTRTrace("%.*s, b%d, f %p\n", AuDLNPair(dentry), bindex, file); + DiMustAnyLock(dentry); + AuDebugOn(bindex < au_di(dentry)->di_bstart + || bindex > au_di(dentry)->di_bend); + + h_file = NULL; + if (!hd->hd_intent_list || !file) + return h_file; /* success */ + + /* AuDebugOn(au_test_wkq(current)); */ + h_file = au_find_h_intent(hd, file); + return h_file; +} + +static int au_set_h_intent(struct dentry *dentry, aufs_bindex_t bindex, + struct file *file, struct file *h_file) +{ + int err; + struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex; + struct au_hdintent *hdi; + struct file *hf; + + LKTRTrace("%.*s, b%d, f %p\n", AuDLNPair(dentry), bindex, file); + /* d_revalidate() holds read_lock */ + /* DiMustWriteLock(dentry); */ + AuDebugOn(bindex < au_di(dentry)->di_bstart + || bindex > au_di(dentry)->di_bend + || !file + || !h_file + /* || au_test_wkq(current) */); + + err = -ENOMEM; + if (hd->hd_intent_list) { + while (1) { + hf = au_find_h_intent(hd, file); + if (!hf) + break; + fput(hf); + AuWarn("freed hfile %.*s b%d left\n", + AuDLNPair(dentry), bindex); + } + } else { + spin_lock(&hd->hd_lock); + if (!hd->hd_intent_list) { + hd->hd_intent_list + = kmalloc(sizeof(*hd->hd_intent_list), + GFP_ATOMIC); + if (unlikely(!hd->hd_intent_list)) { + spin_unlock(&hd->hd_lock); + goto out; + } + INIT_LIST_HEAD(hd->hd_intent_list); + } + spin_unlock(&hd->hd_lock); + } + + hdi = kmalloc(sizeof(*hdi), GFP_NOFS); + if (unlikely(!hdi)) + goto out; + + err = 0; + /* hdi->hdi_pid = current->pid; */ + hdi->hdi_file[AuIntent_AUFS] = file; + hdi->hdi_file[AuIntent_BRANCH] = h_file; + spin_lock(&hd->hd_lock); + list_add(&hdi->hdi_list, hd->hd_intent_list); + spin_unlock(&hd->hd_lock); + + out: + AuTraceErr(err); + return err; +} + +int au_br_nfs_h_intent(struct file *nd_file, struct dentry *dentry, + aufs_bindex_t bindex, struct nameidata *nd) +{ + int err; + + AuTraceEnter(); + + err = 0; + if (!nd_file) + goto out; + + AuDebugOn(!nd); + err = au_set_h_intent(dentry, bindex, nd->intent.open.file, nd_file); + if (unlikely(err)) { + fput(nd_file); + au_set_h_dptr(dentry, bindex, NULL); + /* todo: update bstart and bend? */ + } + + out: + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +void au_hintent_put(struct au_hdentry *hd, int do_free) +{ + struct au_hdintent *hdi, *tmp; + struct file *hf; + + if (unlikely(hd->hd_intent_list)) { + /* no spin lock */ + list_for_each_entry_safe(hdi, tmp, hd->hd_intent_list, + hdi_list) { + LKTRTrace("hdi %p\n", hdi); + hf = hdi->hdi_file[AuIntent_BRANCH]; + if (unlikely(hf)) + fput(hf); + /* list_del(&hdi->hdi_list); */ + kfree(hdi); + } + if (do_free) + kfree(hd->hd_intent_list); + } +} + +/* ---------------------------------------------------------------------- */ + +int au_fake_intent(/* struct au_ndsub *save, */struct nameidata *nd, + int perm) +{ + int err; + + LKTRTrace("perm %d\n", perm); + + err = 0; + nd->intent.open.file = NULL; + if (nd->flags & LOOKUP_OPEN) { + err = -ENFILE; + nd->intent.open.file = get_empty_filp(); + if (unlikely(!nd->intent.open.file)) + goto out; + + err = 0; + if (!au_br_writable(perm)) { + nd->intent.open.flags = FMODE_READ + | au_file_roflags(nd->intent.open.flags); + nd->flags &= ~LOOKUP_CREATE; + } + } + + out: + AuTraceErr(err); + return err; +} + +int au_hin_after_reval(struct nameidata *nd, struct dentry *dentry, + aufs_bindex_t bindex, struct file *file) +{ + int err; + + LKTRTrace("nd %p, %.*s, b%d, f %d\n", + nd, AuDLNPair(dentry), bindex, !!file); + + err = 0; + if ((nd->flags & LOOKUP_OPEN) + && nd->intent.open.file + && !IS_ERR(nd->intent.open.file)) { + if (nd->intent.open.file->f_dentry) { + err = au_set_h_intent(dentry, bindex, file, + nd->intent.open.file); + if (!err) + nd->intent.open.file = NULL; + } + if (unlikely(nd->intent.open.file)) + put_filp(nd->intent.open.file); + } + + return err; +} + +#ifdef CONFIG_AUFS_DLGT +struct au_lookup_hash_args { + struct dentry **errp; + struct qstr *name; + struct dentry *base; + struct nameidata *nd; +}; + +static void au_call_lookup_hash(void *args) +{ + struct au_lookup_hash_args *a = args; + *a->errp = vfsub__lookup_hash(a->name, a->base, a->nd); +} + +static struct dentry * +au_lkup_hash_dlgt(struct qstr *this, struct dentry *parent, + struct nameidata *nd, unsigned int flags) +{ + struct dentry *dentry; + int dirperm1; + + dirperm1 = au_ftest_ndx(flags, DIRPERM1); + if (!dirperm1 && !au_ftest_ndx(flags, DLGT)) + dentry = vfsub__lookup_hash(this, parent, nd); + else { + int wkq_err; + struct au_lookup_hash_args args = { + .errp = &dentry, + .name = this, + .base = parent, + .nd = nd + }; + wkq_err = au_wkq_wait(au_call_lookup_hash, &args, + /*dlgt*/!dirperm1); + if (unlikely(wkq_err)) + dentry = ERR_PTR(wkq_err); + } + + AuTraceErrPtr(dentry); + return dentry; +} +#else +static struct dentry * +au_lkup_hash_dlgt(struct qstr *this, struct dentry *parent, + struct nameidata *nd, unsigned int flags) +{ + return vfsub__lookup_hash(this, parent, nd); +} +#endif /* CONFIG_AUFS_DLGT */ + +struct dentry *au_lkup_hash(const char *name, struct dentry *parent, + int len, struct au_ndx *ndx) +{ + struct dentry *dentry; + char *p; + unsigned long hash; + struct qstr this; + unsigned int c; + struct nameidata tmp_nd, *ndo; + int err; + + LKTRTrace("%.*s/%.*s\n", AuDLNPair(parent), len, name); + + /* todo: export and call __lookup_one_len() in fs/namei.c? */ + dentry = ERR_PTR(-EACCES); + this.name = name; + this.len = len; + if (unlikely(!len)) + goto out; + + p = (void *)name; + hash = init_name_hash(); + while (len--) { + c = *p++; + if (unlikely(c == '/' || c == '\0')) + goto out; + hash = partial_name_hash(c, hash); + } + this.hash = end_name_hash(hash); + + ndo = ndx->nd; + if (ndo) { + tmp_nd = *ndo; + err = au_fake_intent(&tmp_nd, ndx->br->br_perm); + dentry = ERR_PTR(err); + if (unlikely(err)) + goto out_intent; + } else + memset(&tmp_nd, 0, sizeof(tmp_nd)); + + tmp_nd.path.dentry = parent; + tmp_nd.path.mnt = ndx->nfsmnt; + path_get(&tmp_nd.path); + dentry = au_lkup_hash_dlgt(&this, parent, &tmp_nd, ndx->flags); + if (!IS_ERR(dentry)) { + /* why negative dentry for a new dir was unhashed? */ + if (unlikely(d_unhashed(dentry))) + d_rehash(dentry); + if (tmp_nd.intent.open.file + && tmp_nd.intent.open.file->f_dentry) { + ndx->nd_file = tmp_nd.intent.open.file; + tmp_nd.intent.open.file = NULL; + /* au_br_get(ndx->br); */ + } + } + path_put(&tmp_nd.path); + + out_intent: + if (tmp_nd.intent.open.file) + put_filp(tmp_nd.intent.open.file); + out: + AuTraceErrPtr(dentry); + return dentry; +} --- linux-2.6.28.orig/ubuntu/aufs/debug.h +++ linux-2.6.28/ubuntu/aufs/debug.h @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * debug print functions + * + * $Id: debug.h,v 1.8 2008/09/22 03:52:03 sfjro Exp $ + */ + +#ifndef __AUFS_DEBUG_H__ +#define __AUFS_DEBUG_H__ + +#ifdef __KERNEL__ + +#include +#include +#include +#include + +/* to debug easier, do not make it an inlined function */ +#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx)) + +#ifdef CONFIG_AUFS_DEBUG +/* sparse warns about pointer */ +#define AuDebugOn(a) BUG_ON(!!(a)) +extern atomic_t au_cond; +#define au_debug_on() atomic_inc_return(&au_cond) +#define au_debug_off() atomic_dec_return(&au_cond) +static inline int au_debug_test(void) +{ + return atomic_read(&au_cond); +} +#else +#define AuDebugOn(a) do {} while (0) +#define au_debug_on() do {} while (0) +#define au_debug_off() do {} while (0) +static inline int au_debug_test(void) +{ + return 0; +} +#endif /* CONFIG_AUFS_DEBUG */ + +/* ---------------------------------------------------------------------- */ + +/* debug print */ +#if defined(CONFIG_LKTR) || defined(CONFIG_LKTR_MODULE) +#include +#ifdef CONFIG_AUFS_DEBUG +#undef LktrCond +#define LktrCond unlikely(au_debug_test() || (lktr_cond && lktr_cond())) +#endif +#else +#define LktrCond au_debug_test() +#define LKTRDumpVma(pre, vma, suf) do {} while (0) +#define LKTRDumpStack() do {} while (0) +#define LKTRTrace(fmt, args...) do { \ + if (LktrCond) \ + AuDbg(fmt, ##args); \ +} while (0) +#define LKTRLabel(label) LKTRTrace("%s\n", #label) +#endif /* CONFIG_LKTR */ + +#define AuTraceErr(e) do { \ + if (unlikely((e) < 0)) \ + LKTRTrace("err %d\n", (int)(e)); \ +} while (0) + +#define AuTraceErrPtr(p) do { \ + if (IS_ERR(p)) \ + LKTRTrace("err %ld\n", PTR_ERR(p)); \ +} while (0) + +#define AuTraceEnter() LKTRLabel(enter) + +/* dirty macros for debug print, use with "%.*s" and caution */ +#define AuLNPair(qstr) (qstr)->len, (qstr)->name +#define AuDLNPair(d) AuLNPair(&(d)->d_name) + +/* ---------------------------------------------------------------------- */ + +#define AuDpri(lvl, fmt, arg...) \ + printk(lvl AUFS_NAME " %s:%d:%s[%d]: " fmt, \ + __func__, __LINE__, current->comm, current->pid, ##arg) +#define AuDbg(fmt, arg...) AuDpri(KERN_DEBUG, fmt, ##arg) +#define AuInfo(fmt, arg...) AuDpri(KERN_INFO, fmt, ##arg) +#define AuWarn(fmt, arg...) AuDpri(KERN_WARNING, fmt, ##arg) +#define AuErr(fmt, arg...) AuDpri(KERN_ERR, fmt, ##arg) +#define AuIOErr(fmt, arg...) AuErr("I/O Error, " fmt, ##arg) +#define AuIOErrWhck(fmt, arg...) AuErr("I/O Error, try whck. " fmt, ##arg) +#define AuWarn1(fmt, arg...) do { \ + static unsigned char _c; \ + if (!_c++) AuWarn(fmt, ##arg); \ +} while (0) + +#define AuErr1(fmt, arg...) do { \ + static unsigned char _c; \ + if (!_c++) AuErr(fmt, ##arg); \ +} while (0) + +#define AuIOErr1(fmt, arg...) do { \ + static unsigned char _c; \ + if (!_c++) AuIOErr(fmt, ##arg); \ +} while (0) + +#define AuUnsupportMsg "This operation is not supported." \ + " Please report this application to aufs-users ML." +#define AuUnsupport(fmt, args...) do { \ + AuErr(AuUnsupportMsg "\n" fmt, ##args); \ + dump_stack(); \ +} while (0) + +/* ---------------------------------------------------------------------- */ + +struct au_sbinfo; +#ifdef CONFIG_AUFS_DEBUG +extern char *au_plevel; +struct au_nhash; +void au_dpri_whlist(struct au_nhash *whlist); +struct au_vdir; +void au_dpri_vdir(struct au_vdir *vdir); +void au_dpri_inode(struct inode *inode); +void au_dpri_dentry(struct dentry *dentry); +void au_dpri_file(struct file *filp); +void au_dpri_sb(struct super_block *sb); +void au_dbg_sleep(int sec); +void au_dbg_sleep_jiffy(int jiffy); +#ifndef ATTR_TIMES_SET +#define ATTR_TIMES_SET 0 +#endif +void au_dbg_iattr(struct iattr *ia); +int __init au_debug_init(void); +void au_debug_sbinfo_init(struct au_sbinfo *sbinfo); +#define AuDbgWhlist(w) do { \ + LKTRTrace(#w "\n"); \ + au_dpri_whlist(w); \ +} while (0) + +#define AuDbgVdir(v) do { \ + LKTRTrace(#v "\n"); \ + au_dpri_vdir(v); \ +} while (0) + +#define AuDbgInode(i) do { \ + LKTRTrace(#i "\n"); \ + au_dpri_inode(i); \ +} while (0) + +#define AuDbgDentry(d) do { \ + LKTRTrace(#d "\n"); \ + au_dpri_dentry(d); \ +} while (0) + +#define AuDbgFile(f) do { \ + LKTRTrace(#f "\n"); \ + au_dpri_file(f); \ +} while (0) + +#define AuDbgSb(sb) do { \ + LKTRTrace(#sb "\n"); \ + au_dpri_sb(sb); \ +} while (0) + +#define AuDbgSleep(sec) do { \ + AuDbg("sleep %d sec\n", sec); \ + au_dbg_sleep(sec); \ +} while (0) + +#define AuDbgSleepJiffy(jiffy) do { \ + AuDbg("sleep %d jiffies\n", jiffy); \ + au_dbg_sleep_jiffy(jiffy); \ +} while (0) + +#define AuDbgIAttr(ia) do { \ + AuDbg("ia_valid 0x%x\n", (ia)->ia_valid); \ + au_dbg_iattr(ia); \ +} while (0) +#else +static inline int au_debug_init(void) +{ + return 0; +} +static inline void au_debug_sbinfo_init(struct au_sbinfo *sbinfo) +{ + /* empty */ +} +#define AuDbgWhlist(w) do {} while (0) +#define AuDbgVdir(v) do {} while (0) +#define AuDbgInode(i) do {} while (0) +#define AuDbgDentry(d) do {} while (0) +#define AuDbgFile(f) do {} while (0) +#define AuDbgSb(sb) do {} while (0) +#define AuDbgSleep(sec) do {} while (0) +#define AuDbgSleepJiffy(jiffy) do {} while (0) +#define AuDbgIAttr(ia) do {} while (0) +#endif /* CONFIG_AUFS_DEBUG */ + +#ifdef DbgUdbaRace +#define AuDbgSleep_UdbaRace() AuDbgSleep(DbgUdbaRace) +#else +#define AuDbgSleep_UdbaRace() do {} while (0) +#endif + +#ifdef CONFIG_AUFS_MAGIC_SYSRQ +int __init au_sysrq_init(void); +void au_sysrq_fin(void); + +#ifdef CONFIG_HW_CONSOLE +#define au_dbg_blocked() do { \ + WARN_ON(1); \ + handle_sysrq('w', vc_cons[fg_console].d->vc_tty); \ +} while (0) +#else +#define au_dbg_blocked() do {} while (0) +#endif + +#else +static inline int au_sysrq_init(void) +{ + return 0; +} +#define au_sysrq_fin() do {} while (0) +#define au_dbg_blocked() do {} while (0) +#endif /* CONFIG_AUFS_MAGIC_SYSRQ */ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_DEBUG_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/misc.h +++ linux-2.6.28/ubuntu/aufs/misc.h @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * $Id: misc.h,v 1.7 2008/09/22 03:52:19 sfjro Exp $ + */ + +#ifndef __AUFS_MISC_H__ +#define __AUFS_MISC_H__ + +#ifdef __KERNEL__ + +#include +#include +#include + +/* ---------------------------------------------------------------------- */ + +typedef unsigned int au_gen_t; +/* see linux/include/linux/jiffies.h */ +#define AuGenYounger(a, b) ((int)(b) - (int)(a) < 0) +#define AuGenOlder(a, b) AufsGenYounger(b, a) + +/* ---------------------------------------------------------------------- */ + +struct au_rwsem { + struct rw_semaphore rwsem; +#ifdef CONFIG_AUFS_DEBUG + atomic_t rcnt; +#endif +}; + +#ifdef CONFIG_AUFS_DEBUG +#define AuDbgRcntInit(rw) do { \ + atomic_set(&(rw)->rcnt, 0); \ + smp_mb(); /* atomic set */ \ +} while (0) + +#define AuDbgRcntInc(rw) atomic_inc_return(&(rw)->rcnt) +#define AuDbgRcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->rcnt) < 0) +#else +#define AuDbgRcntInit(rw) do {} while (0) +#define AuDbgRcntInc(rw) do {} while (0) +#define AuDbgRcntDec(rw) do {} while (0) +#endif /* CONFIG_AUFS_DEBUG */ + +static inline void au_rw_init_nolock(struct au_rwsem *rw) +{ + AuDbgRcntInit(rw); + init_rwsem(&rw->rwsem); +} + +static inline void au_rw_init_wlock(struct au_rwsem *rw) +{ + au_rw_init_nolock(rw); + down_write(&rw->rwsem); +} + +static inline void au_rw_init_wlock_nested(struct au_rwsem *rw, + unsigned int lsc) +{ + au_rw_init_nolock(rw); + down_write_nested(&rw->rwsem, lsc); +} + +static inline void au_rw_read_lock(struct au_rwsem *rw) +{ + down_read(&rw->rwsem); + AuDbgRcntInc(rw); +} + +static inline void au_rw_read_lock_nested(struct au_rwsem *rw, unsigned int lsc) +{ + down_read_nested(&rw->rwsem, lsc); + AuDbgRcntInc(rw); +} + +static inline void au_rw_read_unlock(struct au_rwsem *rw) +{ + AuDbgRcntDec(rw); + up_read(&rw->rwsem); + //au_dbg_sleep_jiffy(1 * HZ / HZ); +} + +static inline void au_rw_dgrade_lock(struct au_rwsem *rw) +{ + AuDbgRcntInc(rw); + downgrade_write(&rw->rwsem); + //au_dbg_sleep_jiffy(1 * HZ / HZ); +} + +static inline void au_rw_write_lock(struct au_rwsem *rw) +{ + down_write(&rw->rwsem); +} + +static inline void au_rw_write_lock_nested(struct au_rwsem *rw, + unsigned int lsc) +{ + down_write_nested(&rw->rwsem, lsc); +} + +static inline void au_rw_write_unlock(struct au_rwsem *rw) +{ + up_write(&rw->rwsem); + //au_dbg_sleep_jiffy(1 * HZ / HZ); +} + +/* why is not _nested version defined */ +static inline int au_rw_read_trylock(struct au_rwsem *rw) +{ + int ret = down_read_trylock(&rw->rwsem); + if (ret) + AuDbgRcntInc(rw); + return ret; +} + +static inline int au_rw_write_trylock(struct au_rwsem *rw) +{ + return down_write_trylock(&rw->rwsem); +} + +#undef AuDbgRcntInit +#undef AuDbgRcntInc +#undef AuDbgRcntDec + +/* to debug easier, do not make them inlined functions */ +#define AuRwMustNoWaiters(rw) AuDebugOn(!list_empty(&(rw)->rwsem.wait_list)) +#define AuRwMustAnyLock(rw) AuDebugOn(down_write_trylock(&(rw)->rwsem)) +#ifdef CONFIG_AUFS_DEBUG +#define AuRwMustReadLock(rw) do { \ + AuRwMustAnyLock(rw); \ + AuDebugOn(!atomic_read(&(rw)->rcnt)); \ +} while (0) + +#define AuRwMustWriteLock(rw) do { \ + AuRwMustAnyLock(rw); \ + AuDebugOn(atomic_read(&(rw)->rcnt)); \ +} while (0) +#else +#define AuRwMustReadLock(rw) AuRwMustAnyLock(rw) +#define AuRwMustWriteLock(rw) AuRwMustAnyLock(rw) +#endif /* CONFIG_AUFS_DEBUG */ + +#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \ +static inline void prefix##_read_lock(param) \ +{ au_rw_read_lock(&(rwsem)); } \ +static inline void prefix##_write_lock(param) \ +{ au_rw_write_lock(&(rwsem)); } \ +static inline int prefix##_read_trylock(param) \ +{ return au_rw_read_trylock(&(rwsem)); } \ +static inline int prefix##_write_trylock(param) \ +{ return au_rw_write_trylock(&(rwsem)); } +/* static inline void prefix##_read_trylock_nested(param, lsc) +{au_rw_read_trylock_nested(&(rwsem, lsc));} +static inline void prefix##_write_trylock_nestd(param, lsc) +{au_rw_write_trylock_nested(&(rwsem), nested);} */ + +#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \ +static inline void prefix##_read_unlock(param) \ +{ au_rw_read_unlock(&(rwsem)); } \ +static inline void prefix##_write_unlock(param) \ +{ au_rw_write_unlock(&(rwsem)); } \ +static inline void prefix##_downgrade_lock(param) \ +{ au_rw_dgrade_lock(&(rwsem)); } + +#define AuSimpleRwsemFuncs(prefix, param, rwsem) \ + AuSimpleLockRwsemFuncs(prefix, param, rwsem) \ + AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) + +/* ---------------------------------------------------------------------- */ + +void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp); + +struct au_nd_store { + unsigned int flags; + struct path path; + struct open_intent intent; +}; +struct au_sbinfo; +void au_nd_store(struct au_nd_store *store, struct nameidata *nd, + struct au_sbinfo *sbinfo); +void au_nd_revert(struct au_nd_store *store, struct nameidata *nd, + struct au_sbinfo *sbinfo); + +struct nameidata *au_dup_nd(struct au_sbinfo *sbinfo, struct nameidata *dst, + struct nameidata *src); + +struct nameidata *au_fake_dm(struct nameidata *fake_nd, struct nameidata *nd, + struct super_block *sb, aufs_bindex_t bindex); +void au_fake_dm_release(struct nameidata *fake_nd); +struct vfsub_args; +int au_h_create(struct inode *h_dir, struct dentry *h_dentry, int mode, + struct vfsub_args *vargs, struct nameidata *nd, + struct vfsmount *nfsmnt); + +struct au_hinode; +int au_copy_file(struct file *dst, struct file *src, loff_t len, + struct au_hinode *hdir, struct super_block *sb, + struct vfsub_args *vargs); + +#endif /* __KERNEL__ */ +#endif /* __AUFS_MISC_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/iinfo.c +++ linux-2.6.28/ubuntu/aufs/iinfo.c @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * inode private data + * + * $Id: iinfo.c,v 1.8 2008/09/15 03:16:36 sfjro Exp $ + */ + +#include "aufs.h" + +struct au_iinfo *au_ii(struct inode *inode) +{ + struct au_iinfo *iinfo; + + iinfo = &(container_of(inode, struct aufs_icntnr, vfs_inode)->iinfo); + /* bad_inode case */ + if (unlikely(!iinfo->ii_hinode)) + return NULL; + AuDebugOn(!iinfo->ii_hinode + /* || au_sbi(inode->i_sb)->si_bend < iinfo->ii_bend */ + || iinfo->ii_bend < iinfo->ii_bstart); + return iinfo; +} + +struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex) +{ + struct inode *hidden_inode; + + IiMustAnyLock(inode); + AuDebugOn(bindex < 0 || au_ibend(inode) < bindex); + hidden_inode = au_ii(inode)->ii_hinode[0 + bindex].hi_inode; + AuDebugOn(hidden_inode && atomic_read(&hidden_inode->i_count) <= 0); + return hidden_inode; +} + +aufs_bindex_t au_ii_br_id(struct inode *inode, aufs_bindex_t bindex) +{ + IiMustAnyLock(inode); + AuDebugOn(bindex < 0 + || au_ibend(inode) < bindex + || !au_ii(inode)->ii_hinode[0 + bindex].hi_inode); + return au_ii(inode)->ii_hinode[0 + bindex].hi_id; +} + +/* todo: hard/soft set? */ +void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex) +{ + struct au_iinfo *iinfo = au_ii(inode); + struct inode *h_inode; + + IiMustWriteLock(inode); + AuDebugOn(au_sbend(inode->i_sb) < bindex); + iinfo->ii_bstart = bindex; + h_inode = iinfo->ii_hinode[bindex + 0].hi_inode; + if (h_inode) + au_cpup_igen(inode, h_inode); +} + +unsigned int au_hi_flags(struct inode *inode, int isdir) +{ + unsigned int flags; + const unsigned int mnt_flags = au_mntflags(inode->i_sb); + + flags = 0; + if (au_opt_test_xino(mnt_flags)) + au_fset_hi(flags, XINO); + if (unlikely(isdir && au_opt_test(mnt_flags, UDBA_INOTIFY))) + au_fset_hi(flags, NOTIFY); + return flags; +} + +void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex, + struct inode *h_inode, unsigned int flags) +{ + struct au_hinode *hinode; + struct inode *hi; + struct au_iinfo *iinfo = au_ii(inode); + + LKTRTrace("i%lu, b%d, hi%lu, flags 0x%x\n", + inode->i_ino, bindex, h_inode ? h_inode->i_ino : 0, flags); + IiMustWriteLock(inode); + hinode = iinfo->ii_hinode + bindex; + hi = hinode->hi_inode; + AuDebugOn(bindex < au_ibstart(inode) || au_ibend(inode) < bindex); + AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0); + AuDebugOn(h_inode && hi); + + if (hi) + au_hiput(hinode); + hinode->hi_inode = h_inode; + if (h_inode) { + int err; + struct super_block *sb = inode->i_sb; + + if (bindex == iinfo->ii_bstart) + au_cpup_igen(inode, h_inode); + hinode->hi_id = au_sbr_id(sb, bindex); + if (au_ftest_hi(flags, XINO)) { + struct au_xino_entry xinoe = { + .ino = inode->i_ino, + /* .h_gen = h_inode->i_generation */ + }; + err = au_xino_write(sb, bindex, h_inode->i_ino, &xinoe); + if (unlikely(err)) + AuIOErr1("failed au_xino_write() %d\n", err); + } + + if (unlikely(au_ftest_hi(flags, NOTIFY) + && au_br_hinotifyable(au_sbr_perm(sb, bindex)))) { + err = au_hin_alloc(hinode, inode, h_inode); + if (unlikely(err)) + AuIOErr1("au_hin_alloc() %d\n", err); + } + } +} + +void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex, + struct dentry *h_wh) +{ + struct au_hinode *hinode; + + IiMustWriteLock(inode); + hinode = au_ii(inode)->ii_hinode + bindex; + AuDebugOn(hinode->hi_whdentry); + hinode->hi_whdentry = h_wh; +} + +void au_update_iigen(struct inode *inode) +{ + AuDebugOn(!inode->i_sb); + atomic_set(&au_ii(inode)->ii_generation, au_sigen(inode->i_sb)); + /* smp_mb(); */ /* atomic_set */ +} + +/* it may be called at remount time, too */ +void au_update_brange(struct inode *inode, int do_put_zero) +{ + struct au_iinfo *iinfo; + + LKTRTrace("i%lu, %d\n", inode->i_ino, do_put_zero); + IiMustWriteLock(inode); + + iinfo = au_ii(inode); + if (unlikely(!iinfo) || iinfo->ii_bstart < 0) + return; + + if (do_put_zero) { + aufs_bindex_t bindex; + for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; + bindex++) { + struct inode *h_i; + h_i = iinfo->ii_hinode[0 + bindex].hi_inode; + if (h_i && !h_i->i_nlink) + au_set_h_iptr(inode, bindex, NULL, 0); + } + } + + iinfo->ii_bstart = -1; + while (++iinfo->ii_bstart <= iinfo->ii_bend) + if (iinfo->ii_hinode[0 + iinfo->ii_bstart].hi_inode) + break; + if (iinfo->ii_bstart > iinfo->ii_bend) { + iinfo->ii_bstart = -1; + iinfo->ii_bend = -1; + return; + } + + iinfo->ii_bend++; + while (0 <= --iinfo->ii_bend) + if (iinfo->ii_hinode[0 + iinfo->ii_bend].hi_inode) + break; + AuDebugOn(iinfo->ii_bstart > iinfo->ii_bend || iinfo->ii_bend < 0); +} + +/* ---------------------------------------------------------------------- */ + +int au_iinfo_init(struct inode *inode) +{ + struct au_iinfo *iinfo; + struct super_block *sb; + int nbr, i; + + sb = inode->i_sb; + AuDebugOn(!sb); + iinfo = &(container_of(inode, struct aufs_icntnr, vfs_inode)->iinfo); + AuDebugOn(iinfo->ii_hinode); + nbr = au_sbend(sb) + 1; + if (unlikely(nbr <= 0)) + nbr = 1; + iinfo->ii_hinode = kcalloc(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS); + if (iinfo->ii_hinode) { + for (i = 0; i < nbr; i++) + iinfo->ii_hinode[i].hi_id = -1; + atomic_set(&iinfo->ii_generation, au_sigen(sb)); + /* smp_mb(); */ /* atomic_set */ + au_rw_init_nolock(&iinfo->ii_rwsem); + iinfo->ii_bstart = -1; + iinfo->ii_bend = -1; + iinfo->ii_vdir = NULL; + return 0; + } + return -ENOMEM; +} + +static int au_iinfo_write0(struct super_block *sb, struct au_hinode *hinode, + ino_t ino) +{ + int err, locked; + aufs_bindex_t bindex; + + err = 0; + locked = si_noflush_read_trylock(sb); /* crucio! */ + bindex = au_br_index(sb, hinode->hi_id); + if (bindex >= 0) + err = au_xino_write0(sb, bindex, hinode->hi_inode->i_ino, ino); + /* error action? */ + if (locked) + si_read_unlock(sb); + return err; +} + +void au_iinfo_fin(struct inode *inode) +{ + struct au_iinfo *iinfo; + aufs_bindex_t bend; + unsigned char unlinked; + struct au_hinode *hi; + struct super_block *sb; + ino_t ino; + + iinfo = au_ii(inode); + /* bad_inode case */ + if (unlikely(!iinfo)) + return; + + if (unlikely(iinfo->ii_vdir)) + au_vdir_free(iinfo->ii_vdir); + + if (iinfo->ii_bstart >= 0) { + sb = inode->i_sb; + unlinked = !inode->i_nlink; + ino = 0; + if (unlinked) + ino = inode->i_ino; + hi = iinfo->ii_hinode + iinfo->ii_bstart; + bend = iinfo->ii_bend; + while (iinfo->ii_bstart++ <= bend) { + if (hi->hi_inode) { + if (unlinked || !hi->hi_inode->i_nlink) { + au_iinfo_write0(sb, hi, ino); + /* ignore this error */ + ino = 0; + } + au_hiput(hi); + } + hi++; + } + } + + kfree(iinfo->ii_hinode); +} --- linux-2.6.28.orig/ubuntu/aufs/file.c +++ linux-2.6.28/ubuntu/aufs/file.c @@ -0,0 +1,762 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * handling file/dir, and address_space operation + * + * $Id: file.c,v 1.16 2008/09/22 03:52:09 sfjro Exp $ + */ + +#include +#include "aufs.h" + +/* + * a dirty trick for handling FMODE_EXEC and deny_write_access(). + * because FMODE_EXEC flag is not passed to f_op->open(), + * set it to file->private_data temporary. + */ +#if !defined(CONFIG_AUFS_MODULE) || defined(CONFIG_AUFS_DENY_WRITE_ACCESS_PATCH) +int au_store_fmode_exec(struct nameidata *nd, struct inode *inode) +{ + int err; + union { + void *p; + unsigned long ul; + } u; + + err = 0; + if (nd + && (nd->flags & LOOKUP_OPEN) + && nd->intent.open.file + && (nd->intent.open.flags & FMODE_EXEC) + && inode + && S_ISREG(inode->i_mode)) { + u.ul = nd->intent.open.flags; + nd->intent.open.file->private_data = u.p; + /* smp_mb(); */ + err = 1; + } + + return err; +} +#endif + +/* drop flags for writing */ +unsigned int au_file_roflags(unsigned int flags) +{ + flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC); + flags |= O_RDONLY | O_NOATIME; + return flags; +} + +/* common functions to regular file and dir */ +struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags, + struct file *file) +{ + struct file *h_file; + struct dentry *h_dentry; + struct inode *h_inode; + struct super_block *sb; + struct au_branch *br; + int err; + + LKTRTrace("%.*s, b%d, flags 0%o, f %d\n", + AuDLNPair(dentry), bindex, flags, !!file); + h_dentry = au_h_dptr(dentry, bindex); + AuDebugOn(!h_dentry); + h_inode = h_dentry->d_inode; + + /* a race condition can happen between open and unlink/rmdir */ + h_file = ERR_PTR(-ENOENT); + if (unlikely((!d_unhashed(dentry) && d_unhashed(h_dentry)) + || !h_inode)) + goto out; + + sb = dentry->d_sb; + br = au_sbr(sb, bindex); + au_br_get(br); + /* drop flags for writing */ + if (au_test_ro(sb, bindex, dentry->d_inode)) + flags = au_file_roflags(flags); + flags &= ~O_CREAT; + + h_file = NULL; + if (unlikely(file && au_test_nfs(h_dentry->d_sb))) + h_file = au_h_intent(dentry, bindex, file); + if (!h_file) + h_file = dentry_open(dget(h_dentry), mntget(br->br_mnt), flags); + + /* + * a dirty trick for handling FMODE_EXEC and deny_write_access(). + */ + if (file && (file->f_mode & FMODE_EXEC)) { + h_file->f_mode |= FMODE_EXEC; + smp_mb(); /* flush f_mode */ + err = au_deny_write_access(h_file); + if (unlikely(err)) { + fput(h_file); + h_file = ERR_PTR(err); + } + } + if (IS_ERR(h_file)) + au_br_put(br); + +out: + AuTraceErrPtr(h_file); + return h_file; +} + +static int do_coo(struct dentry *dentry, aufs_bindex_t bstart) +{ + int err; + struct dentry *parent; + aufs_bindex_t bcpup; + struct mutex *h_mtx; + struct super_block *sb; + struct au_pin pin; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + AuDebugOn(IS_ROOT(dentry)); + DiMustWriteLock(dentry); + + parent = dget_parent(dentry); + di_write_lock_parent(parent); + sb = dentry->d_sb; + err = AuWbrCopyup(au_sbi(sb), dentry); + bcpup = err; + if (err < 0) { + err = 0; /* stop copyup, it is not an error */ + goto out_dgrade; + } + err = 0; + + if (!au_h_dptr(parent, bcpup)) { + err = au_cpup_dirs(dentry, bcpup); + if (unlikely(err)) + goto out_dgrade; + } + + di_downgrade_lock(parent, AuLock_IR); + err = au_pin(&pin, dentry, bcpup, /*di_locked*/1, + /*do_gp*/au_opt_test(au_mntflags(sb), UDBA_INOTIFY)); + if (unlikely(err)) + goto out; + h_mtx = &au_h_dptr(dentry, bstart)->d_inode->i_mutex; + mutex_lock_nested(h_mtx, AuLsc_I_CHILD); + AuDebugOn(au_h_dptr(dentry, bcpup)); + err = au_sio_cpup_simple(dentry, bcpup, -1, AuCpup_DTIME); + AuTraceErr(err); + mutex_unlock(h_mtx); + au_unpin(&pin); + goto out; + + out_dgrade: + di_downgrade_lock(parent, AuLock_IR); + out: + di_read_unlock(parent, AuLock_IR); + dput(parent); + AuTraceErr(err); + return err; +} + +int au_do_open(struct inode *inode, struct file *file, + int (*open)(struct file *file, int flags)) +{ + int err; + struct dentry *dentry; + struct super_block *sb; + aufs_bindex_t bstart; + unsigned char coo; + + dentry = file->f_dentry; + LKTRTrace("i%lu, %.*s\n", inode->i_ino, AuDLNPair(dentry)); + + sb = dentry->d_sb; + si_read_lock(sb, AuLock_FLUSH); + coo = 0; + switch (au_mntflags(sb) & AuOptMask_COO) { + case AuOpt_COO_LEAF: + coo = !S_ISDIR(inode->i_mode); + break; + case AuOpt_COO_ALL: + coo = 1; + break; + } + err = au_finfo_init(file); + if (unlikely(err)) + goto out; + + if (!coo) + di_read_lock_child(dentry, AuLock_IR); + else { + di_write_lock_child(dentry); + bstart = au_dbstart(dentry); + if (au_test_ro(sb, bstart, dentry->d_inode)) { + err = do_coo(dentry, bstart); + if (err) { + di_write_unlock(dentry); + goto out_finfo; + } + } + di_downgrade_lock(dentry, AuLock_IR); + } + + err = open(file, file->f_flags); + di_read_unlock(dentry, AuLock_IR); + + out_finfo: + fi_write_unlock(file); + if (unlikely(err)) + au_finfo_fin(file); + out: + si_read_unlock(sb); + AuTraceErr(err); + return err; +} + +int au_reopen_nondir(struct file *file) +{ + int err; + aufs_bindex_t bstart, bindex, bend; + struct dentry *dentry; + struct file *h_file, *h_file_tmp; + + dentry = file->f_dentry; + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + bstart = au_dbstart(dentry); + //bstart = au_ibstart(inode); + AuDebugOn(S_ISDIR(dentry->d_inode->i_mode) + || !au_h_dptr(dentry, bstart)->d_inode); + + h_file_tmp = NULL; + if (au_fbstart(file) == bstart) { + h_file = au_h_fptr(file, bstart); + if (file->f_mode == h_file->f_mode) + return 0; /* success */ + h_file_tmp = h_file; + get_file(h_file_tmp); + au_set_h_fptr(file, bstart, NULL); + } + AuDebugOn(au_fbstart(file) < bstart + || au_fi(file)->fi_hfile[0 + bstart].hf_file); + + h_file = au_h_open(dentry, bstart, file->f_flags & ~O_TRUNC, file); + err = PTR_ERR(h_file); + if (IS_ERR(h_file)) + goto out; /* todo: close all? */ + err = 0; + /* cpup_file_flags(h_file, file); */ + au_set_fbstart(file, bstart); + au_set_h_fptr(file, bstart, h_file); + au_update_figen(file); + /* todo: necessary? */ + /* file->f_ra = h_file->f_ra; */ + + /* close lower files */ + bend = au_fbend(file); + for (bindex = bstart + 1; bindex <= bend; bindex++) + au_set_h_fptr(file, bindex, NULL); + au_set_fbend(file, bstart); + + out: + if (h_file_tmp) + fput(h_file_tmp); + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static int au_ready_to_write_wh(struct file *file, loff_t len, + aufs_bindex_t bcpup) +{ + int err; + aufs_bindex_t old_bstart; + struct inode *inode; + struct dentry *dentry, *hi_wh, *old_h_dentry; + struct au_dinfo *dinfo; + struct super_block *sb; + + AuTraceEnter(); + + dentry = file->f_dentry; + inode = dentry->d_inode; + hi_wh = au_hi_wh(inode, bcpup); + if (!hi_wh) + err = au_sio_cpup_wh(dentry, bcpup, len, file); + else { + /* already copied-up after unlink */ + dinfo = au_di(dentry); + old_bstart = dinfo->di_bstart; + dinfo->di_bstart = bcpup; + old_h_dentry = dinfo->di_hdentry[0 + bcpup].hd_dentry; + dinfo->di_hdentry[0 + bcpup].hd_dentry = hi_wh; + err = au_reopen_nondir(file); + dinfo->di_hdentry[0 + bcpup].hd_dentry = old_h_dentry; + dinfo->di_bstart = old_bstart; + } + + sb = dentry->d_sb; + if (!err && inode->i_nlink > 1 && au_opt_test(au_mntflags(sb), PLINK)) + au_plink_append(sb, inode, au_h_dptr(dentry, bcpup), bcpup); + + AuTraceErr(err); + return err; +} + +/* + * prepare the @file for writing. + */ +int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin) +{ + int err; + struct dentry *dentry, *parent, *h_dentry; + struct inode *h_inode, *inode; + struct super_block *sb; + aufs_bindex_t bstart, bcpup; + + dentry = file->f_dentry; + LKTRTrace("%.*s, len %lld\n", AuDLNPair(dentry), len); + FiMustWriteLock(file); + + sb = dentry->d_sb; + bstart = au_fbstart(file); + AuDebugOn(au_fbr(file, bstart) != au_sbr(sb, bstart)); + + inode = dentry->d_inode; + AuDebugOn(S_ISDIR(inode->i_mode)); + LKTRTrace("rdonly %d, bstart %d\n", + au_test_ro(sb, bstart, inode), bstart); + + err = au_test_ro(sb, bstart, inode); + if (!err && (au_h_fptr(file, bstart)->f_mode & FMODE_WRITE)) { + err = au_pin(pin, dentry, bstart, /*di_locked*/0, /*dp_gp*/0); + goto out; + } + + /* need to cpup */ + parent = dget_parent(dentry); + di_write_lock_parent(parent); + err = AuWbrCopyup(au_sbi(sb), dentry); + bcpup = err; + if (unlikely(err < 0)) + goto out_dgrade; + err = 0; + + if (!au_h_dptr(parent, bcpup)) { + err = au_cpup_dirs(dentry, bcpup); + if (unlikely(err)) + goto out_dgrade; + } + + err = au_pin(pin, dentry, bcpup, /*di_locked*/1, + /*dp_gp*/au_opt_test(au_mntflags(sb), UDBA_INOTIFY)); + if (unlikely(err)) + goto out_dgrade; + + AuDebugOn(au_fbstart(file) != bstart); + h_dentry = au_h_fptr(file, bstart)->f_dentry; + h_inode = h_dentry->d_inode; + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); + if (d_unhashed(dentry) /* || d_unhashed(h_dentry) */ + /* || !h_inode->i_nlink */) { + err = au_ready_to_write_wh(file, len, bcpup); + di_downgrade_lock(parent, AuLock_IR); + } else { + di_downgrade_lock(parent, AuLock_IR); + if (!au_h_dptr(dentry, bcpup)) + err = au_sio_cpup_simple(dentry, bcpup, len, + AuCpup_DTIME); + AuTraceErr(err); + if (!err) + err = au_reopen_nondir(file); + AuTraceErr(err); + } + mutex_unlock(&h_inode->i_mutex); + + if (!err) { + au_unpin_gp(pin); + au_pin_set_parent_lflag(pin, /*lflag*/0); + goto out_dput; /* success */ + } + au_unpin(pin); + goto out_unlock; + + out_dgrade: + di_downgrade_lock(parent, AuLock_IR); + out_unlock: + di_read_unlock(parent, AuLock_IR); + out_dput: + dput(parent); + out: + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static int au_file_refresh_by_inode(struct file *file, int *need_reopen) +{ + int err; + struct au_finfo *finfo; + struct dentry *dentry, *parent, *old_h_dentry, *hi_wh; + struct inode *inode, *dir; + aufs_bindex_t bstart, new_bstart, old_bstart; + struct super_block *sb; + struct au_dinfo *dinfo; + unsigned int mnt_flags; + struct au_pin pin; + + dentry = file->f_dentry; + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + FiMustWriteLock(file); + + err = 0; + finfo = au_fi(file); + inode = dentry->d_inode; + sb = dentry->d_sb; + mnt_flags = au_mntflags(sb); + again: + bstart = au_ibstart(inode); + if (bstart == finfo->fi_bstart) + goto out; + + new_bstart = bstart; + parent = dget_parent(dentry); + dir = parent->d_inode; + if (au_test_ro(sb, bstart, inode)) { + di_read_lock_parent(parent, !AuLock_IR); + err = AuWbrCopyup(au_sbi(sb), dentry); + new_bstart = err; + di_read_unlock(parent, !AuLock_IR); + if (unlikely(err < 0)) + goto out_dput; + err = 0; + } + /* someone else might change our inode while we were sleeping */ + /* todo: test more? */ + if (bstart != au_ibstart(inode)) { + err = 0; + dput(parent); + goto again; + } + di_read_lock_parent(parent, AuLock_IR); + bstart = new_bstart; + + hi_wh = au_hi_wh(inode, bstart); + if (au_opt_test(mnt_flags, PLINK) + && au_plink_test(sb, inode) + && !d_unhashed(dentry)) { + err = au_test_and_cpup_dirs(dentry, bstart); + if (unlikely(err)) + goto out_unlock; + + /* always superio. */ +#if 1 + err = au_pin(&pin, dentry, bstart, /*di_locked*/1, + /*do_gp*/au_opt_test(mnt_flags, UDBA_INOTIFY)); + if (!err) + err = au_sio_cpup_simple(dentry, bstart, -1, AuCpup_DTIME); + au_unpin(&pin); +#else /* reserved for future use */ + if (!au_test_wkq(current)) { + int wkq_err; + struct cpup_pseudo_link_args args = { + .errp = &err, + .dentry = dentry, + .bdst = bstart, + .do_lock = 1 + }; + wkq_err = au_wkq_wait(call_cpup_pseudo_link, &args); + if (unlikely(wkq_err)) + err = wkq_err; + } else + err = cpup_pseudo_link(dentry, bstart, /*do_lock*/1); +#endif + } else if (hi_wh) { + /* already copied-up after unlink */ + dinfo = au_di(dentry); + old_bstart = dinfo->di_bstart; + dinfo->di_bstart = bstart; + old_h_dentry = dinfo->di_hdentry[0 + bstart].hd_dentry; + dinfo->di_hdentry[0 + bstart].hd_dentry = hi_wh; + err = au_reopen_nondir(file); + dinfo->di_hdentry[0 + bstart].hd_dentry = old_h_dentry; + dinfo->di_bstart = old_bstart; + *need_reopen = 0; + } + + out_unlock: + di_read_unlock(parent, AuLock_IR); + out_dput: + dput(parent); + out: + AuTraceErr(err); + return err; +} + +/* + * after branch manipulating, refresh the file. + */ +static int refresh_file(struct file *file, int (*reopen)(struct file *file)) +{ + int err, new_sz, need_reopen; + struct dentry *dentry; + aufs_bindex_t bend, bindex, brid; + struct au_hfile *p; + struct au_finfo *finfo; + struct super_block *sb; + struct inode *inode; + + dentry = file->f_dentry; + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + FiMustWriteLock(file); + DiMustAnyLock(dentry); + inode = dentry->d_inode; + IiMustAnyLock(inode); + + err = -ENOMEM; + sb = dentry->d_sb; + finfo = au_fi(file); + new_sz = sizeof(*finfo->fi_hfile) * (au_sbend(sb) + 1); + p = au_kzrealloc(finfo->fi_hfile, sizeof(*p) * (finfo->fi_bend + 1), + new_sz, GFP_NOFS); + if (unlikely(!p)) + goto out; + finfo->fi_hfile = p; + + p += finfo->fi_bstart; + brid = p->hf_br->br_id; + bend = finfo->fi_bend; + for (bindex = finfo->fi_bstart; bindex <= bend; bindex++, p++) { + struct au_hfile tmp, *q; + aufs_bindex_t new_bindex; + + if (!p->hf_file) + continue; + new_bindex = au_find_bindex(sb, p->hf_br); + if (new_bindex == bindex) + continue; + /* todo: test more? */ + if (new_bindex < 0) { + au_set_h_fptr(file, bindex, NULL); + continue; + } + + /* swap two hidden inode, and loop again */ + q = finfo->fi_hfile + new_bindex; + tmp = *q; + *q = *p; + *p = tmp; + if (tmp.hf_file) { + bindex--; + p--; + } + } + { + aufs_bindex_t s = finfo->fi_bstart, e = finfo->fi_bend; + finfo->fi_bstart = 0; + finfo->fi_bend = au_sbend(sb); + finfo->fi_bstart = s; + finfo->fi_bend = e; + } + + p = finfo->fi_hfile; + if (!au_test_mmapped(file) && !d_unhashed(dentry)) { + bend = au_sbend(sb); + for (finfo->fi_bstart = 0; finfo->fi_bstart <= bend; + finfo->fi_bstart++, p++) + if (p->hf_file) { + if (p->hf_file->f_dentry + && p->hf_file->f_dentry->d_inode) + break; + else + au_hfput(p); + } + } else { + bend = au_br_index(sb, brid); + for (finfo->fi_bstart = 0; finfo->fi_bstart < bend; + finfo->fi_bstart++, p++) + if (p->hf_file) + au_hfput(p); + bend = au_sbend(sb); + } + + p = finfo->fi_hfile + bend; + for (finfo->fi_bend = bend; finfo->fi_bend >= finfo->fi_bstart; + finfo->fi_bend--, p--) + if (p->hf_file) { + if (p->hf_file->f_dentry + && p->hf_file->f_dentry->d_inode) + break; + else + au_hfput(p); + } + AuDebugOn(finfo->fi_bend < finfo->fi_bstart); + + err = 0; + need_reopen = 1; + if (!au_test_mmapped(file)) + err = au_file_refresh_by_inode(file, &need_reopen); + if (!err && need_reopen && !d_unhashed(dentry)) + err = reopen(file); + if (!err) { + au_update_figen(file); + return 0; /* success */ + } + + /* error, close all hidden files */ + bend = au_fbend(file); + for (bindex = au_fbstart(file); bindex <= bend; bindex++) + au_set_h_fptr(file, bindex, NULL); + + out: + AuTraceErr(err); + return err; +} + +/* common function to regular file and dir */ +int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file), + int wlock, int locked) +{ + int err; + struct dentry *dentry; + struct super_block *sb; + aufs_bindex_t bstart; + unsigned char pseudo_link; + au_gen_t sgen, fgen; + + dentry = file->f_dentry; + LKTRTrace("%.*s, w %d, l %d\n", AuDLNPair(dentry), wlock, locked); + sb = dentry->d_sb; + SiMustAnyLock(sb); + + err = 0; + sgen = au_sigen(sb); + fi_write_lock(file); + fgen = au_figen(file); + di_write_lock_child(dentry); + bstart = au_dbstart(dentry); + pseudo_link = (bstart != au_ibstart(dentry->d_inode)); + if (sgen == fgen && !pseudo_link && au_fbstart(file) == bstart) { + if (!wlock) { + di_downgrade_lock(dentry, AuLock_IR); + fi_downgrade_lock(file); + } + goto out; /* success */ + } + + LKTRTrace("sgen %d, fgen %d\n", sgen, fgen); + if (unlikely(sgen != au_digen(dentry) + || sgen != au_iigen(dentry->d_inode))) { + /* + * d_path() and path_lookup() is a simple and good approach + * to revalidate. but si_rwsem in DEBUG_RWSEM will cause a + * deadlock. removed the code. + */ + err = au_reval_dpath(dentry, sgen); + if (unlikely(err < 0)) + goto out; + AuDebugOn(au_digen(dentry) != sgen + || au_iigen(dentry->d_inode) != sgen); + } + + err = refresh_file(file, reopen + /* , au_opt_test(au_mnt_flags(sb), REFROF) */); + if (!err) { + if (!wlock) { + di_downgrade_lock(dentry, AuLock_IR); + fi_downgrade_lock(file); + } + } else { + di_write_unlock(dentry); + fi_write_unlock(file); + } + + out: + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +/* cf. aufs_nopage() */ +/* for madvise(2) */ +static int aufs_readpage(struct file *file, struct page *page) +{ + AuTraceEnter(); + unlock_page(page); + return 0; +} + +/* they will never be called. */ +#ifdef CONFIG_AUFS_DEBUG +static int aufs_prepare_write(struct file *file, struct page *page, + unsigned from, unsigned to) +{ AuUnsupport(); return 0; } +static int aufs_commit_write(struct file *file, struct page *page, + unsigned from, unsigned to) +{ AuUnsupport(); return 0; } +static int aufs_write_begin(struct file *file, struct address_space *mapping, + loff_t pos, unsigned len, unsigned flags, + struct page **pagep, void **fsdata) +{ AuUnsupport(); return 0; } +static int aufs_write_end(struct file *file, struct address_space *mapping, + loff_t pos, unsigned len, unsigned copied, + struct page *page, void *fsdata) +{ AuUnsupport(); return 0; } +static int aufs_writepage(struct page *page, struct writeback_control *wbc) +{ AuUnsupport(); return 0; } +static void aufs_sync_page(struct page *page) +{ AuUnsupport(); } + +static int aufs_set_page_dirty(struct page *page) +{ AuUnsupport(); return 0; } +static void aufs_invalidatepage(struct page *page, unsigned long offset) +{ AuUnsupport(); } +static int aufs_releasepage(struct page *page, gfp_t gfp) +{ AuUnsupport(); return 0; } +static ssize_t aufs_direct_IO(int rw, struct kiocb *iocb, + const struct iovec *iov, loff_t offset, + unsigned long nr_segs) +{ AuUnsupport(); return 0; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) +static struct page *aufs_get_xip_page(struct address_space *mapping, + sector_t offset, int create) +{ AuUnsupport(); return NULL; } +#endif +#endif /* CONFIG_AUFS_DEBUG */ + +struct address_space_operations aufs_aop = { + .readpage = aufs_readpage, +#ifdef CONFIG_AUFS_DEBUG + .writepage = aufs_writepage, + .sync_page = aufs_sync_page, + .set_page_dirty = aufs_set_page_dirty, + .prepare_write = aufs_prepare_write, + .commit_write = aufs_commit_write, + .write_begin = aufs_write_begin, + .write_end = aufs_write_end, + .invalidatepage = aufs_invalidatepage, + .releasepage = aufs_releasepage, + .direct_IO = aufs_direct_IO, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) + .get_xip_page = aufs_get_xip_page, +#endif +#endif /* CONFIG_AUFS_DEBUG */ +}; --- linux-2.6.28.orig/ubuntu/aufs/cpup.c +++ linux-2.6.28/ubuntu/aufs/cpup.c @@ -0,0 +1,1105 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * copy-up functions, see wbr_policy.c for copy-down + * + * $Id: cpup.c,v 1.17 2008/09/22 03:52:19 sfjro Exp $ + */ + +#include +#include +#include "aufs.h" + +/* todo? violent cpup_attr_*() functions don't care inode lock */ + +void au_cpup_attr_timesizes(struct inode *inode) +{ + struct inode *h_inode; + + LKTRTrace("i%lu\n", inode->i_ino); + /* todo? IMustLock(inode); */ + h_inode = au_h_iptr(inode, au_ibstart(inode)); + AuDebugOn(!h_inode); + /* todo? IMustLock(!h_inode); */ + + fsstack_copy_attr_times(inode, h_inode); + vfsub_copy_inode_size(inode, h_inode); +} + +void au_cpup_attr_nlink(struct inode *inode) +{ + struct inode *h_inode; + + LKTRTrace("i%lu\n", inode->i_ino); + /* todo? IMustLock(inode); */ + AuDebugOn(!inode->i_mode); + + h_inode = au_h_iptr(inode, au_ibstart(inode)); + inode->i_nlink = h_inode->i_nlink; + + /* + * fewer nlink makes find(1) noisy, but larger nlink doesn't. + * it may includes whplink directory. + */ + if (unlikely(S_ISDIR(h_inode->i_mode))) { + aufs_bindex_t bindex, bend; + bend = au_ibend(inode); + for (bindex = au_ibstart(inode) + 1; bindex <= bend; bindex++) { + h_inode = au_h_iptr(inode, bindex); + if (h_inode) + au_add_nlink(inode, h_inode); + } + } +} + +void au_cpup_attr_changeable(struct inode *inode) +{ + struct inode *h_inode; + + LKTRTrace("i%lu\n", inode->i_ino); + /* todo? IMustLock(inode); */ + h_inode = au_h_iptr(inode, au_ibstart(inode)); + AuDebugOn(!h_inode); + + inode->i_mode = h_inode->i_mode; + inode->i_uid = h_inode->i_uid; + inode->i_gid = h_inode->i_gid; + au_cpup_attr_timesizes(inode); + + /* todo: remove this? */ + inode->i_flags = h_inode->i_flags; +} + +void au_cpup_igen(struct inode *inode, struct inode *h_inode) +{ + struct au_iinfo *iinfo = au_ii(inode); + iinfo->ii_higen = h_inode->i_generation; + iinfo->ii_hsb1 = h_inode->i_sb; +} + +void au_cpup_attr_all(struct inode *inode) +{ + struct inode *h_inode; + + LKTRTrace("i%lu\n", inode->i_ino); + /* todo? IMustLock(inode); */ + h_inode = au_h_iptr(inode, au_ibstart(inode)); + AuDebugOn(!h_inode); + + au_cpup_attr_changeable(inode); + if (inode->i_nlink > 0) + au_cpup_attr_nlink(inode); + + switch (inode->i_mode & S_IFMT) { + case S_IFBLK: + case S_IFCHR: + inode->i_rdev = au_h_rdev(h_inode, /*h_mnt*/NULL, + /*h_dentry*/NULL); + } + inode->i_blkbits = h_inode->i_blkbits; + au_cpup_igen(inode, h_inode); +} + +/* ---------------------------------------------------------------------- */ + +/* Note: dt_dentry and dt_hidden_dentry are not dget/dput-ed */ + +/* keep the timestamps of the parent dir when cpup */ +void au_dtime_store(struct au_dtime *dt, struct dentry *dentry, + struct dentry *h_dentry, struct au_hinode *hinode, + struct au_hinode *hdir) +{ + struct inode *h_inode; + + LKTRTrace("%.*s, hdir %d\n", AuDLNPair(dentry), !!hdir); + AuDebugOn(!dentry || !h_dentry || !h_dentry->d_inode); + + dt->dt_dentry = dentry; + dt->dt_h_dentry = h_dentry; + dt->dt_hinode = hinode; + dt->dt_hdir = hdir; + h_inode = h_dentry->d_inode; + dt->dt_atime = h_inode->i_atime; + dt->dt_mtime = h_inode->i_mtime; + /* smp_mb(); */ +} + +void au_dtime_revert(struct au_dtime *dt) +{ + struct iattr attr; + int err; + struct au_hin_ignore ign[2]; + struct vfsub_args vargs; + + LKTRTrace("%.*s\n", AuDLNPair(dt->dt_dentry)); + + attr.ia_atime = dt->dt_atime; + attr.ia_mtime = dt->dt_mtime; + attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET + | ATTR_ATIME | ATTR_ATIME_SET; + + vfsub_args_init(&vargs, ign, + au_test_dlgt(au_mntflags(dt->dt_dentry->d_sb)), 0); + /* + * IN_ATTRIB should be divided into + * IN_ATTRIB_ATIME, IN_ATTRIB_MTIME ..., + * and define all ORed new IN_ATTRIB macro. + */ + vfsub_ign_hinode(&vargs, IN_ATTRIB, dt->dt_hinode); + vfsub_ign_hinode(&vargs, IN_ATTRIB, dt->dt_hdir); + err = vfsub_notify_change(dt->dt_h_dentry, &attr, &vargs); + if (unlikely(err)) + AuWarn("restoring timestamps failed(%d). ignored\n", err); +} + +/* ---------------------------------------------------------------------- */ + +static noinline_for_stack +int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src, + struct au_hinode *hdir, struct vfsub_args *vargs) +{ + int err, sbits; + struct dentry *h_dst; + struct iattr ia; + struct inode *h_isrc, *h_idst; + + h_dst = au_h_dptr(dst, bindex); + LKTRTrace("%.*s\n", AuDLNPair(h_dst)); + h_idst = h_dst->d_inode; + /* todo? IMustLock(h_idst); */ + h_isrc = h_src->d_inode; + /* todo? IMustLock(h_isrc); */ + + ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID + | ATTR_ATIME | ATTR_MTIME + | ATTR_ATIME_SET | ATTR_MTIME_SET; + ia.ia_mode = h_isrc->i_mode; + ia.ia_uid = h_isrc->i_uid; + ia.ia_gid = h_isrc->i_gid; + ia.ia_atime = h_isrc->i_atime; + ia.ia_mtime = h_isrc->i_mtime; + sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID)); + + vfsub_args_reinit(vargs); + vfsub_ign_hinode(vargs, IN_ATTRIB, hdir); + err = vfsub_notify_change(h_dst, &ia, vargs); + + /* is this nfs only? */ + if (!err && sbits && au_test_nfs(h_dst->d_sb)) { + ia.ia_valid = ATTR_FORCE | ATTR_MODE; + ia.ia_mode = h_isrc->i_mode; + vfsub_args_reinit(vargs); + vfsub_ign_hinode(vargs, IN_ATTRIB, hdir); + err = vfsub_notify_change(h_dst, &ia, vargs); + } + + /* todo? remove this? */ + if (!err) + h_idst->i_flags = h_isrc->i_flags; + + AuTraceErr(err); + return err; +} + +/* + * to support a sparse file which is opened with O_APPEND, + * we need to close the file. + */ +static noinline_for_stack +int cpup_regular(struct dentry *dentry, aufs_bindex_t bdst, aufs_bindex_t bsrc, + loff_t len, struct au_hinode *hdir, struct vfsub_args *vargs) +{ + int err, i; + struct super_block *sb; + struct inode *h_inode; + enum { SRC, DST }; + struct { + aufs_bindex_t bindex; + unsigned int flags; + struct dentry *dentry; + struct file *file; + void *label, *label_file; + } *h, hidden[] = { + { + .bindex = bsrc, + .flags = O_RDONLY | O_NOATIME | O_LARGEFILE, + .file = NULL, + .label = &&out, + .label_file = &&out_src_file + }, + { + .bindex = bdst, + .flags = O_WRONLY | O_NOATIME | O_LARGEFILE, + .file = NULL, + .label = &&out_src_file, + .label_file = &&out_dst_file + } + }; + + LKTRTrace("dentry %.*s, bdst %d, bsrc %d, len %lld\n", + AuDLNPair(dentry), bdst, bsrc, len); + AuDebugOn(bsrc <= bdst); + AuDebugOn(!len); + sb = dentry->d_sb; + AuDebugOn(au_test_ro(sb, bdst, dentry->d_inode)); + /* bsrc branch can be ro/rw. */ + + h = hidden; + for (i = 0; i < 2; i++, h++) { + h->dentry = au_h_dptr(dentry, h->bindex); + AuDebugOn(!h->dentry); + h_inode = h->dentry->d_inode; + AuDebugOn(!h_inode || !S_ISREG(h_inode->i_mode)); + h->file = au_h_open(dentry, h->bindex, h->flags, /*file*/NULL); + err = PTR_ERR(h->file); + if (IS_ERR(h->file)) + goto *h->label; + err = -EINVAL; + if (unlikely(!h->file->f_op)) + goto *h->label_file; + } + + /* stop updating while we copyup */ + IMustLock(hidden[SRC].dentry->d_inode); + err = au_copy_file(hidden[DST].file, hidden[SRC].file, len, hdir, sb, + vargs); + + out_dst_file: + fput(hidden[DST].file); + au_sbr_put(sb, hidden[DST].bindex); + out_src_file: + fput(hidden[SRC].file); + au_sbr_put(sb, hidden[SRC].bindex); + out: + AuTraceErr(err); + return err; +} + +static int au_do_cpup_regular(struct dentry *dentry, aufs_bindex_t bdst, + aufs_bindex_t bsrc, loff_t len, + struct au_hinode *hdir, struct dentry *h_dst, + struct vfsub_args *vargs) +{ + int err, rerr; + loff_t l; + + AuTraceEnter(); + + err = 0; + l = i_size_read(au_h_iptr(dentry->d_inode, bsrc)); + if (len == -1 || l < len) + len = l; + if (len) + err = cpup_regular(dentry, bdst, bsrc, len, hdir, vargs); + if (!err) + goto out; /* success */ + + vfsub_args_reinit(vargs); + vfsub_ign_hinode(vargs, IN_DELETE, hdir); + rerr = vfsub_unlink(hdir->hi_inode, h_dst, vargs); + if (rerr) { + AuIOErr("failed unlinking cpup-ed %.*s(%d, %d)\n", + AuDLNPair(h_dst), err, rerr); + err = -EIO; + } + + out: + AuTraceErr(err); + return err; +} + +static int au_do_cpup_symlink(struct dentry *h_dst, struct dentry *h_src, + struct inode *h_dir, umode_t mode, + struct vfsub_args *vargs) +{ + int err, symlen; + char *sym; + mm_segment_t old_fs; + + AuTraceEnter(); + + err = -ENOMEM; + sym = __getname(); + if (unlikely(!sym)) + goto out; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + symlen = h_src->d_inode->i_op->readlink(h_src, (char __user *)sym, + PATH_MAX); + err = symlen; + set_fs(old_fs); + + if (symlen > 0) { + sym[symlen] = 0; + err = vfsub_symlink(h_dir, h_dst, sym, mode, vargs); + } + __putname(sym); + + out: + AuTraceErr(err); + return err; +} + +/* return with hidden dst inode is locked */ +static noinline_for_stack +int cpup_entry(struct dentry *dentry, aufs_bindex_t bdst, aufs_bindex_t bsrc, + loff_t len, unsigned int flags, struct dentry *dst_parent, + struct vfsub_args *vargs) +{ + int err; + unsigned char isdir, hinotify; + struct dentry *h_src, *h_dst, *h_parent, *gparent; + struct inode *h_inode, *h_dir; + struct au_dtime dt; + umode_t mode; + struct super_block *sb; + struct au_hinode *hgdir, *hdir; + unsigned int mnt_flags; + const int do_dt = au_ftest_cpup(flags, DTIME); + + LKTRTrace("%.*s, i%lu, bdst %d, bsrc %d, len %lld, dtime %u\n", + AuDLNPair(dentry), dentry->d_inode->i_ino, bdst, bsrc, len, + do_dt); + sb = dentry->d_sb; + AuDebugOn(bdst >= bsrc || au_test_ro(sb, bdst, NULL)); + /* bsrc branch can be ro/rw. */ + + h_src = au_h_dptr(dentry, bsrc); + AuDebugOn(!h_src); + h_inode = h_src->d_inode; + AuDebugOn(!h_inode); + AuDebugOn(h_inode != au_h_iptr(dentry->d_inode, bsrc)); + + /* stop referencing while we are creating */ + h_dst = au_h_dptr(dentry, bdst); + AuDebugOn(h_dst && h_dst->d_inode); + h_parent = h_dst->d_parent; /* dir inode is locked */ + h_dir = h_parent->d_inode; + IMustLock(h_dir); + AuDebugOn(h_parent != h_dst->d_parent); + + hdir = NULL; + mnt_flags = au_mntflags(sb); + hinotify = !!au_opt_test(mnt_flags, UDBA_INOTIFY); + if (unlikely(hinotify)) { + hdir = au_hi(dst_parent->d_inode, bdst); + AuDebugOn(hdir->hi_inode != h_dir); + } + + if (do_dt) { + hgdir = NULL; + if (unlikely(hinotify && !IS_ROOT(dst_parent))) { + gparent = dget_parent(dst_parent); + hgdir = au_hi(gparent->d_inode, bdst); + IMustLock(hgdir->hi_inode); + dput(gparent); + } + au_dtime_store(&dt, dst_parent, h_parent, hdir, hgdir); + } + + isdir = 0; + vfsub_args_reinit(vargs); + vfsub_ign_hinode(vargs, IN_CREATE, hdir); + mode = h_inode->i_mode; + switch (mode & S_IFMT) { + case S_IFREG: + /* stop updating while we are referencing */ + IMustLock(h_inode); + err = au_h_create(h_dir, h_dst, mode | S_IWUSR, vargs, NULL, + au_nfsmnt(sb, bdst)); + if (!err) + err = au_do_cpup_regular(dentry, bdst, bsrc, len, + hdir, h_dst, vargs); + break; + case S_IFDIR: + isdir = 1; + err = vfsub_mkdir(h_dir, h_dst, mode, vargs); + if (!err) { + /* setattr case: dir is not locked */ + if (0 && au_ibstart(dst_parent->d_inode) == bdst) + au_cpup_attr_nlink(dst_parent->d_inode); + au_cpup_attr_nlink(dentry->d_inode); + } + break; + case S_IFLNK: + err = au_do_cpup_symlink(h_dst, h_src, h_dir, mode, vargs); + break; + case S_IFCHR: + case S_IFBLK: + AuDebugOn(!capable(CAP_MKNOD)); + /*FALLTHROUGH*/ + case S_IFIFO: + case S_IFSOCK: + err = vfsub_mknod(h_dir, h_dst, mode, + au_h_rdev(h_inode, /*h_mnt*/NULL, h_src), + vargs); + break; + default: + AuIOErr("Unknown inode type 0%o\n", mode); + err = -EIO; + } + + if (unlikely(hinotify + && !isdir + && au_opt_test_xino(mnt_flags) + && h_inode->i_nlink == 1 + //&& dentry->d_inode->i_nlink == 1 + && bdst < bsrc + && !au_ftest_cpup(flags, KEEPLINO))) + au_xino_write0(sb, bsrc, h_inode->i_ino, /*ino*/0); + /* ignore this error */ + + if (do_dt) + au_dtime_revert(&dt); + AuTraceErr(err); + return err; +} + +/* + * copyup the @dentry from @bsrc to @bdst. + * the caller must set the both of hidden dentries. + * @len is for truncating when it is -1 copyup the entire file. + */ +static int au_cpup_single(struct dentry *dentry, aufs_bindex_t bdst, + aufs_bindex_t bsrc, loff_t len, unsigned int flags, + struct dentry *dst_parent, struct vfsub_args *vargs) +{ + int err, rerr; + unsigned int mnt_flags; + aufs_bindex_t old_ibstart; + unsigned char isdir, plink, hinotify; + struct au_dtime dt; + struct dentry *h_src, *h_dst, *h_parent, *gparent; + struct inode *dst_inode, *h_dir, *inode; + struct super_block *sb; + struct au_hinode *hgdir, *hdir; + + LKTRTrace("%.*s, i%lu, bdst %d, bsrc %d, len %lld, flags 0x%x\n", + AuDLNPair(dentry), dentry->d_inode->i_ino, bdst, bsrc, len, + flags); + sb = dentry->d_sb; + AuDebugOn(bsrc <= bdst); + h_dst = au_h_dptr(dentry, bdst); + AuDebugOn(!h_dst || h_dst->d_inode); + h_parent = h_dst->d_parent; /* dir inode is locked */ + h_dir = h_parent->d_inode; + IMustLock(h_dir); + h_src = au_h_dptr(dentry, bsrc); + AuDebugOn(!h_src || !h_src->d_inode); + inode = dentry->d_inode; + IiMustWriteLock(inode); + if (!dst_parent) + dst_parent = dget_parent(dentry); + else + dget(dst_parent); + + mnt_flags = au_mntflags(sb); + plink = !!au_opt_test(mnt_flags, PLINK); + hinotify = !!au_opt_test(mnt_flags, UDBA_INOTIFY); + hdir = NULL; + if (unlikely(hinotify)) + hdir = au_hi(dst_parent->d_inode, bdst); + dst_inode = au_h_iptr(inode, bdst); + if (unlikely(dst_inode)) { + if (unlikely(!plink)) { + err = -EIO; + AuIOErr("i%lu exists on a upper branch " + "but plink is disabled\n", inode->i_ino); + goto out; + } + + if (dst_inode->i_nlink) { + const int do_dt = au_ftest_cpup(flags, DTIME); + + h_src = au_plink_lkup(sb, bdst, inode); + err = PTR_ERR(h_src); + if (IS_ERR(h_src)) + goto out; + AuDebugOn(!h_src->d_inode); + + if (do_dt) { + hgdir = NULL; + if (unlikely(hinotify && !IS_ROOT(dst_parent))) { + gparent = dget_parent(dst_parent); + hgdir = au_hi(gparent->d_inode, bdst); + IMustLock(hgdir->hi_inode); + dput(gparent); + } + au_dtime_store(&dt, dst_parent, h_parent, hdir, + hgdir); + } + vfsub_args_reinit(vargs); + vfsub_ign_hinode(vargs, IN_CREATE, hdir); + err = vfsub_link(h_src, h_dir, h_dst, vargs); + if (do_dt) + au_dtime_revert(&dt); + dput(h_src); + goto out; + } else + /* todo: cpup_wh_file? */ + /* udba work */ + au_update_brange(inode, 1); + } + + old_ibstart = au_ibstart(inode); + err = cpup_entry(dentry, bdst, bsrc, len, flags, dst_parent, vargs); + if (unlikely(err)) + goto out; + dst_inode = h_dst->d_inode; + mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2); + + /* todo: test dlgt? */ + err = cpup_iattr(dentry, bdst, h_src, hdir, vargs); +#if 0 /* reserved for future use */ + if (0 && !err) + err = cpup_xattrs(h_src, h_dst); +#endif + isdir = S_ISDIR(dst_inode->i_mode); + if (!err) { + if (bdst < old_ibstart) + au_set_ibstart(inode, bdst); + au_set_h_iptr(inode, bdst, au_igrab(dst_inode), + au_hi_flags(inode, isdir)); + mutex_unlock(&dst_inode->i_mutex); + if (!isdir + && h_src->d_inode->i_nlink > 1 + && plink) + au_plink_append(sb, inode, h_dst, bdst); + goto out; /* success */ + } + + /* revert */ + mutex_unlock(&dst_inode->i_mutex); + hgdir = NULL; + if (unlikely(au_opt_test(mnt_flags, UDBA_INOTIFY) + && !IS_ROOT(dst_parent))) { + gparent = dget_parent(dst_parent); + hgdir = au_hi(gparent->d_inode, bdst); + dput(gparent); + } + au_dtime_store(&dt, dst_parent, h_parent, hdir, hgdir); + vfsub_args_reinit(vargs); + vfsub_ign_hinode(vargs, IN_DELETE, hdir); + if (!isdir) + rerr = vfsub_unlink(h_dir, h_dst, vargs); + else + rerr = vfsub_rmdir(h_dir, h_dst, vargs); + au_dtime_revert(&dt); + if (rerr) { + AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr); + err = -EIO; + } + + out: + dput(dst_parent); + AuTraceErr(err); + return err; +} + +struct au_cpup_single_args { + int *errp; + struct dentry *dentry; + aufs_bindex_t bdst, bsrc; + loff_t len; + unsigned int flags; + struct dentry *dst_parent; + struct vfsub_args *vargs; +}; + +static void au_call_cpup_single(void *args) +{ + struct au_cpup_single_args *a = args; + *a->errp = au_cpup_single(a->dentry, a->bdst, a->bsrc, a->len, + a->flags, a->dst_parent, a->vargs); +} + +int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst, + aufs_bindex_t bsrc, loff_t len, unsigned int flags, + struct dentry *dst_parent) +{ + int err, wkq_err; + struct dentry *h_dentry; + umode_t mode; + struct au_hin_ignore ign; + struct vfsub_args vargs; + + LKTRTrace("%.*s, i%lu, bdst %d, bsrc %d, len %lld, flags 0x%x\n", + AuDLNPair(dentry), dentry->d_inode->i_ino, bdst, bsrc, len, + flags); + + vfsub_args_init(&vargs, &ign, au_test_dlgt(au_mntflags(dentry->d_sb)), + /*force_unlink*/0); + h_dentry = au_h_dptr(dentry, bsrc); + mode = h_dentry->d_inode->i_mode & S_IFMT; + if ((mode != S_IFCHR && mode != S_IFBLK) + || capable(CAP_MKNOD)) + err = au_cpup_single(dentry, bdst, bsrc, len, flags, + dst_parent, &vargs); + else { + struct au_cpup_single_args args = { + .errp = &err, + .dentry = dentry, + .bdst = bdst, + .bsrc = bsrc, + .len = len, + .flags = flags, + .dst_parent = dst_parent, + .vargs = &vargs + }; + vfsub_fclr(vargs.flags, DLGT); + wkq_err = au_wkq_wait(au_call_cpup_single, &args, /*dlgt*/0); + if (unlikely(wkq_err)) + err = wkq_err; + } + + AuTraceErr(err); + return err; +} + +/* + * copyup the @dentry from the first active hidden branch to @bdst, + * using au_cpup_single(). + */ +static int au_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, + unsigned int flags, struct vfsub_args *vargs) +{ + int err; + struct inode *inode; + aufs_bindex_t bsrc, bend; + + LKTRTrace("%.*s, bdst %d, len %lld, flags 0x%x\n", + AuDLNPair(dentry), bdst, len, flags); + inode = dentry->d_inode; + AuDebugOn(!S_ISDIR(inode->i_mode) && au_dbstart(dentry) < bdst); + + bend = au_dbend(dentry); + for (bsrc = bdst + 1; bsrc <= bend; bsrc++) + if (au_h_dptr(dentry, bsrc)) + break; + AuDebugOn(!au_h_dptr(dentry, bsrc)); + + err = au_lkup_neg(dentry, bdst); + if (!err) { + err = au_cpup_single(dentry, bdst, bsrc, len, flags, NULL, + vargs); + if (!err) + return 0; /* success */ + + /* revert */ + au_set_h_dptr(dentry, bdst, NULL); + au_set_dbstart(dentry, bsrc); + } + + AuTraceErr(err); + return err; +} + +struct au_cpup_simple_args { + int *errp; + struct dentry *dentry; + aufs_bindex_t bdst; + loff_t len; + unsigned int flags; + struct vfsub_args *vargs; +}; + +static void au_call_cpup_simple(void *args) +{ + struct au_cpup_simple_args *a = args; + *a->errp = au_cpup_simple(a->dentry, a->bdst, a->len, a->flags, + a->vargs); +} + +int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, + unsigned int flags) +{ + int err, wkq_err; + unsigned char do_sio, dlgt; + struct dentry *parent; + struct inode *h_dir, *dir; + struct au_hin_ignore ign; + struct vfsub_args vargs; + + LKTRTrace("%.*s, b%d, len %lld, flags 0x%x\n", + AuDLNPair(dentry), bdst, len, flags); + + parent = dget_parent(dentry); + dir = parent->d_inode; + h_dir = au_h_iptr(dir, bdst); + dlgt = !!au_test_dlgt(au_mntflags(dir->i_sb)); + do_sio = !!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE, dlgt); + if (!do_sio) { + /* + * testing CAP_MKNOD is for generic fs, + * but CAP_FSETID is for xfs only, currently. + */ + umode_t mode = dentry->d_inode->i_mode; + do_sio = (((mode & (S_IFCHR | S_IFBLK)) + && !capable(CAP_MKNOD)) + || ((mode & (S_ISUID | S_ISGID)) + && !capable(CAP_FSETID))); + } + vfsub_args_init(&vargs, &ign, dlgt, /*force_unlink*/0); + if (!do_sio) + err = au_cpup_simple(dentry, bdst, len, flags, &vargs); + else { + struct au_cpup_simple_args args = { + .errp = &err, + .dentry = dentry, + .bdst = bdst, + .len = len, + .flags = flags, + .vargs = &vargs + }; + vfsub_fclr(vargs.flags, DLGT); + wkq_err = au_wkq_wait(au_call_cpup_simple, &args, /*dlgt*/0); + if (unlikely(wkq_err)) + err = wkq_err; + } + + dput(parent); + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static int au_do_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, + struct dentry *wh_dentry, struct file *file, + loff_t len, struct vfsub_args *vargs) +{ + int err; + struct au_dinfo *dinfo; + aufs_bindex_t bstart; + struct dentry *h_d_bdst, *h_d_bstart; + + AuTraceEnter(); + + dinfo = au_di(dentry); + bstart = dinfo->di_bstart; + h_d_bdst = dinfo->di_hdentry[0 + bdst].hd_dentry; + dinfo->di_bstart = bdst; + dinfo->di_hdentry[0 + bdst].hd_dentry = wh_dentry; + h_d_bstart = dinfo->di_hdentry[0 + bstart].hd_dentry; + if (file) + dinfo->di_hdentry[0 + bstart].hd_dentry + = au_h_fptr(file, au_fbstart(file))->f_dentry; + err = au_cpup_single(dentry, bdst, bstart, len, !AuCpup_DTIME, + /*h_parent*/NULL, vargs); + if (!err && file) { + err = au_reopen_nondir(file); + dinfo->di_hdentry[0 + bstart].hd_dentry = h_d_bstart; + } + dinfo->di_hdentry[0 + bdst].hd_dentry = h_d_bdst; + dinfo->di_bstart = bstart; + + AuTraceErr(err); + return err; +} + +/* + * copyup the deleted file for writing. + */ +static int au_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, + struct file *file) +{ + int err; + unsigned char dlgt; + struct dentry *parent, *h_parent, *wh_dentry; + struct super_block *sb; + unsigned int mnt_flags; + struct au_dtime dt; + struct au_hin_ignore ign; + struct vfsub_args vargs; + struct au_hinode *hgdir, *hdir; + struct au_ndx ndx = { + .nd = NULL, + .flags = 0, + /* .br = NULL */ + }; + + LKTRTrace("%.*s, bdst %d, len %llu\n", AuDLNPair(dentry), bdst, len); + AuDebugOn(S_ISDIR(dentry->d_inode->i_mode) + || (file && !(file->f_mode & FMODE_WRITE))); + DiMustWriteLock(dentry); + + parent = dget_parent(dentry); + IiMustAnyLock(parent->d_inode); + h_parent = au_h_dptr(parent, bdst); + AuDebugOn(!h_parent); + + sb = parent->d_sb; + mnt_flags = au_mntflags(sb); + dlgt = 0; + ndx.nfsmnt = au_nfsmnt(sb, bdst); + if (unlikely(au_test_dlgt(mnt_flags))) { + dlgt = 1; + au_fset_ndx(ndx.flags, DLGT); + } + wh_dentry = au_whtmp_lkup(h_parent, &dentry->d_name, &ndx); + err = PTR_ERR(wh_dentry); + if (IS_ERR(wh_dentry)) + goto out; + + hdir = NULL; + hgdir = NULL; + if (unlikely(au_opt_test(mnt_flags, UDBA_INOTIFY))) { + hdir = au_hi(parent->d_inode, bdst); + if (!IS_ROOT(parent)) { + struct dentry *gparent; + gparent = dget_parent(parent); + hgdir = au_hi(gparent->d_inode, bdst); + dput(gparent); + } + } + au_dtime_store(&dt, parent, h_parent, hdir, hgdir); + vfsub_args_init(&vargs, &ign, dlgt, /*force_unlink*/0); + err = au_do_cpup_wh(dentry, bdst, wh_dentry, file, len, &vargs); + if (unlikely(err)) + goto out_wh; + + AuDebugOn(!d_unhashed(dentry)); + /* dget first to force sillyrename on nfs */ + dget(wh_dentry); + vfsub_args_reinit(&vargs); + vfsub_ign_hinode(&vargs, IN_DELETE, hdir); + err = vfsub_unlink(h_parent->d_inode, wh_dentry, &vargs); + if (unlikely(err)) { + AuIOErr("failed remove copied-up tmp file %.*s(%d)\n", + AuDLNPair(wh_dentry), err); + err = -EIO; + } + au_dtime_revert(&dt); + au_set_hi_wh(dentry->d_inode, bdst, wh_dentry); + + out_wh: + dput(wh_dentry); + out: + dput(parent); + AuTraceErr(err); + return err; +} + +struct au_cpup_wh_args { + int *errp; + struct dentry *dentry; + aufs_bindex_t bdst; + loff_t len; + struct file *file; +}; + +static void au_call_cpup_wh(void *args) +{ + struct au_cpup_wh_args *a = args; + *a->errp = au_cpup_wh(a->dentry, a->bdst, a->len, a->file); +} + +int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, + struct file *file) +{ + int err, wkq_err; + struct dentry *parent, *h_tmp, *h_parent; + struct inode *dir, *h_dir, *h_tmpdir; + struct au_wbr *wbr; + + AuTraceEnter(); + parent = dget_parent(dentry); + dir = parent->d_inode; + IiMustAnyLock(dir); + + h_tmp = NULL; + h_parent = NULL; + h_dir = au_igrab(au_h_iptr(dir, bdst)); + h_tmpdir = h_dir; + if (unlikely(!h_dir->i_nlink)) { + DiMustWriteLock(parent); + wbr = au_sbr(dentry->d_sb, bdst)->br_wbr; + AuDebugOn(!wbr); + h_tmp = wbr->wbr_tmp; + + h_parent = dget(au_h_dptr(parent, bdst)); + au_set_h_dptr(parent, bdst, NULL); + au_set_h_dptr(parent, bdst, dget(h_tmp)); + h_tmpdir = h_tmp->d_inode; + au_set_h_iptr(dir, bdst, NULL, 0); + au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0); + mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3); + } + + if (!au_test_h_perm_sio + (h_tmpdir, MAY_EXEC | MAY_WRITE, + au_test_dlgt(au_mntflags(dentry->d_sb)))) + err = au_cpup_wh(dentry, bdst, len, file); + else { + struct au_cpup_wh_args args = { + .errp = &err, + .dentry = dentry, + .bdst = bdst, + .len = len, + .file = file + }; + wkq_err = au_wkq_wait(au_call_cpup_wh, &args, /*dlgt*/0); + if (unlikely(wkq_err)) + err = wkq_err; + } + + /* todo: is this restore safe? */ + if (unlikely(h_tmp)) { + mutex_unlock(&h_tmpdir->i_mutex); + au_set_h_iptr(dir, bdst, NULL, 0); + au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0); + au_set_h_dptr(parent, bdst, NULL); + au_set_h_dptr(parent, bdst, h_parent); + } + iput(h_dir); + dput(parent); + + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +/* + * generic routine for both of copy-up and copy-down. + * Although I've tried building a path by dcsub, I gave up this approach. + * Since the ancestor directory may be moved/renamed during copy. + */ +/* cf. revalidate function in file.c */ +int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst, + int (*cp)(struct dentry *dentry, aufs_bindex_t bdst, + struct dentry *h_parent, void *arg), + void *arg) +{ + int err, hinotify; + struct super_block *sb; + struct dentry *d, *parent, *h_parent, *real_parent; + struct au_pin pin; + + LKTRTrace("%.*s, b%d, parent i%lu\n", + AuDLNPair(dentry), bdst, (unsigned long)parent_ino(dentry)); + sb = dentry->d_sb; + AuDebugOn(au_test_ro(sb, bdst, NULL)); + err = 0; + parent = dget_parent(dentry); + IiMustWriteLock(parent->d_inode); + if (unlikely(IS_ROOT(parent))) + goto out; + + /* do not use au_dpage */ + real_parent = parent; + hinotify = !!au_opt_test(au_mntflags(sb), UDBA_INOTIFY); + while (1) { + dput(parent); + parent = dget_parent(dentry); + h_parent = au_h_dptr(parent, bdst); + if (h_parent) + goto out; /* success */ + + /* find top dir which is needed to cpup */ + do { + d = parent; + dput(parent); + parent = dget_parent(d); + di_read_lock_parent3(parent, !AuLock_IR); + h_parent = au_h_dptr(parent, bdst); + di_read_unlock(parent, !AuLock_IR); + } while (!h_parent); + + if (d != real_parent) + di_write_lock_child3(d); + + /* somebody else might create while we were sleeping */ + if (!au_h_dptr(d, bdst) || !au_h_dptr(d, bdst)->d_inode) { + if (au_h_dptr(d, bdst)) + au_update_dbstart(d); + + au_pin_init(&pin, d, /*di_locked*/0, + AuLsc_DI_PARENT3, AuLsc_I_PARENT2, hinotify); + err = au_do_pin(pin.pin + AuPin_PARENT, au_pin_gp(&pin), + bdst, hinotify); + if (!err) { + err = cp(d, bdst, h_parent, arg); + au_unpin(&pin); + } + } + + if (d != real_parent) + di_write_unlock(d); + if (unlikely(err)) + break; + } + + out: + dput(parent); + AuTraceErr(err); + return err; +} + +static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst, + struct dentry *h_parent, void *arg) +{ + int err; + + err = au_sio_cpup_simple(dentry, bdst, -1, AuCpup_DTIME); + + AuTraceErr(err); + return err; +} + +int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst) +{ + int err; + + err = au_cp_dirs(dentry, bdst, au_cpup_dir, NULL); + + AuTraceErr(err); + return err; +} + +int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst) +{ + int err; + struct dentry *parent; + struct inode *dir; + + parent = dget_parent(dentry); + dir = parent->d_inode; + LKTRTrace("%.*s, b%d, parent i%lu\n", + AuDLNPair(dentry), bdst, dir->i_ino); + DiMustReadLock(parent); + IiMustReadLock(dir); + + err = 0; + if (au_h_iptr(dir, bdst)) + goto out; + + di_read_unlock(parent, AuLock_IR); + di_write_lock_parent(parent); + /* someone else might change our inode while we were sleeping */ + if (unlikely(!au_h_iptr(dir, bdst))) + err = au_cpup_dirs(dentry, bdst); + di_downgrade_lock(parent, AuLock_IR); + + out: + dput(parent); + AuTraceErr(err); + return err; +} --- linux-2.6.28.orig/ubuntu/aufs/dlgt.c +++ linux-2.6.28/ubuntu/aufs/dlgt.c @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * lookup functions in 'delegate' mode + * + * $Id: dlgt.c,v 1.5 2008/08/11 02:50:34 sfjro Exp $ + */ + +#include "aufs.h" + +/* ---------------------------------------------------------------------- */ + +struct au_lookup_one_len_args { + struct dentry **errp; + const char *name; + struct dentry *parent; + int len; +}; + +static void au_call_lookup_one_len(void *args) +{ + struct au_lookup_one_len_args *a = args; + *a->errp = vfsub_lookup_one_len(a->name, a->parent, a->len); +} + +struct dentry *au_lkup_one_dlgt(const char *name, struct dentry *parent, + int len, unsigned int flags) +{ + struct dentry *dentry; + int dirperm1; + + LKTRTrace("%.*s/%.*s, 0x%x\n", AuDLNPair(parent), len, name, flags); + + dirperm1 = au_ftest_ndx(flags, DIRPERM1); + if (!dirperm1 && !au_ftest_ndx(flags, DLGT)) + dentry = vfsub_lookup_one_len(name, parent, len); + else { + int wkq_err; + struct au_lookup_one_len_args args = { + .errp = &dentry, + .name = name, + .parent = parent, + .len = len + }; + wkq_err = au_wkq_wait(au_call_lookup_one_len, &args, + /*dlgt*/!dirperm1); + if (unlikely(wkq_err)) + dentry = ERR_PTR(wkq_err); + } + + AuTraceErrPtr(dentry); + return dentry; +} + +/* ---------------------------------------------------------------------- */ + +struct security_inode_permission_args { + int *errp; + struct inode *h_inode; + int mask; + struct nameidata *fake_nd; +}; + +static void call_security_inode_permission(void *args) +{ + struct security_inode_permission_args *a = args; + LKTRTrace("fsuid %d\n", current->fsuid); + *a->errp = vfsub_security_inode_permission(a->h_inode, a->mask, + a->fake_nd); +} + +int au_security_inode_permission(struct inode *h_inode, int mask, + struct nameidata *fake_nd, int dlgt) +{ + int err; + + AuTraceEnter(); + + if (!dlgt) + err = vfsub_security_inode_permission(h_inode, mask, fake_nd); + else { + int wkq_err; + struct security_inode_permission_args args = { + .errp = &err, + .h_inode = h_inode, + .mask = mask, + .fake_nd = fake_nd + }; + wkq_err = au_wkq_wait(call_security_inode_permission, &args, + /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + } + + AuTraceErr(err); + return err; +} --- linux-2.6.28.orig/ubuntu/aufs/br_xfs.c +++ linux-2.6.28/ubuntu/aufs/br_xfs.c @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * special handling inode attributes on XFS branch in linux-2.6.24 and later + * + * $Id: br_xfs.c,v 1.3 2008/07/07 01:12:38 sfjro Exp $ + */ + +#include "aufs.h" + +/* h_mnt can be NULL, is it safe? */ +dev_t au_h_rdev(struct inode *h_inode, struct vfsmount *h_mnt, + struct dentry *h_dentry) +{ + dev_t rdev; + int err; + struct kstat st; + + LKTRTrace("hi%lu\n", h_inode->i_ino); + if (h_dentry) + LKTRTrace("%.*s\n", AuDLNPair(h_dentry)); + + rdev = h_inode->i_rdev; + if (!rdev || !au_test_xfs(h_inode->i_sb)) + goto out; + + rdev = 0; + if (!h_dentry) { + err = 0; + h_dentry = d_find_alias(h_inode); + if (unlikely(!h_dentry)) + goto failure; + err = PTR_ERR(h_dentry); + if (IS_ERR(h_dentry)) { + h_dentry = NULL; + goto failure; + } + LKTRTrace("%.*s\n", AuDLNPair(h_dentry)); + } else + dget(h_dentry); + + err = vfsub_getattr(h_mnt, h_dentry, &st, /*dlgt*/0); + dput(h_dentry); + if (!err) { + rdev = st.rdev; + goto out; /* success */ + } + + failure: + AuIOErr("failed rdev for XFS inode, hi%lu, %d\n", h_inode->i_ino, err); + out: + return rdev; +} --- linux-2.6.28.orig/ubuntu/aufs/dinfo.c +++ linux-2.6.28/ubuntu/aufs/dinfo.c @@ -0,0 +1,426 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * dentry private data + * + * $Id: dinfo.c,v 1.7 2008/09/22 03:52:19 sfjro Exp $ + */ + +#include "aufs.h" + +int au_alloc_dinfo(struct dentry *dentry) +{ + struct au_dinfo *dinfo; + struct super_block *sb; + int nbr; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + AuDebugOn(dentry->d_fsdata); + + dinfo = au_cache_alloc_dinfo(); + if (dinfo) { + sb = dentry->d_sb; + nbr = au_sbend(sb) + 1; + if (unlikely(nbr <= 0)) + nbr = 1; + dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), + GFP_NOFS); + if (dinfo->di_hdentry) { + au_h_dentry_init_all(dinfo->di_hdentry, nbr); + atomic_set(&dinfo->di_generation, au_sigen(sb)); + /* smp_mb(); */ /* atomic_set */ + au_rw_init_wlock_nested(&dinfo->di_rwsem, + AuLsc_DI_CHILD); + dinfo->di_bstart = -1; + dinfo->di_bend = -1; + dinfo->di_bwh = -1; + dinfo->di_bdiropq = -1; + + dentry->d_fsdata = dinfo; + dentry->d_op = &aufs_dop; + return 0; /* success */ + } + au_cache_free_dinfo(dinfo); + } + AuTraceErr(-ENOMEM); + return -ENOMEM; +} + +struct au_dinfo *au_di(struct dentry *dentry) +{ + struct au_dinfo *dinfo = dentry->d_fsdata; + AuDebugOn(!dinfo + || !dinfo->di_hdentry + /* || au_sbi(dentry->d_sb)->si_bend < dinfo->di_bend */ + || dinfo->di_bend < dinfo->di_bstart + /* dbwh can be outside of this range */ + || (0 <= dinfo->di_bdiropq + && (dinfo->di_bdiropq < dinfo->di_bstart + /* || dinfo->di_bend < dinfo->di_bdiropq */)) + ); + return dinfo; +} + +/* ---------------------------------------------------------------------- */ + +static void do_ii_write_lock(struct inode *inode, unsigned int lsc) +{ + switch (lsc) { + case AuLsc_DI_CHILD: + ii_write_lock_child(inode); + break; + case AuLsc_DI_CHILD2: + ii_write_lock_child2(inode); + break; + case AuLsc_DI_CHILD3: + ii_write_lock_child3(inode); + break; + case AuLsc_DI_PARENT: + ii_write_lock_parent(inode); + break; + case AuLsc_DI_PARENT2: + ii_write_lock_parent2(inode); + break; + case AuLsc_DI_PARENT3: + ii_write_lock_parent3(inode); + break; + case AuLsc_DI_PARENT4: + ii_write_lock_parent4(inode); + break; + default: + BUG(); + } +} + +static void do_ii_read_lock(struct inode *inode, unsigned int lsc) +{ + switch (lsc) { + case AuLsc_DI_CHILD: + ii_read_lock_child(inode); + break; + case AuLsc_DI_CHILD2: + ii_read_lock_child2(inode); + break; + case AuLsc_DI_CHILD3: + ii_read_lock_child3(inode); + break; + case AuLsc_DI_PARENT: + ii_read_lock_parent(inode); + break; + case AuLsc_DI_PARENT2: + ii_read_lock_parent2(inode); + break; + case AuLsc_DI_PARENT3: + ii_read_lock_parent3(inode); + break; + case AuLsc_DI_PARENT4: + ii_read_lock_parent4(inode); + break; + default: + BUG(); + } +} + +void di_read_lock(struct dentry *d, int flags, unsigned int lsc) +{ + LKTRTrace("%.*s, %u\n", AuDLNPair(d), lsc); + SiMustAnyLock(d->d_sb); + + /* todo: always nested? */ + au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc); + if (d->d_inode) { + if (au_ftest_lock(flags, IW)) + do_ii_write_lock(d->d_inode, lsc); + else if (au_ftest_lock(flags, IR)) + do_ii_read_lock(d->d_inode, lsc); + } +} + +void di_read_unlock(struct dentry *d, int flags) +{ + LKTRTrace("%.*s\n", AuDLNPair(d)); + SiMustAnyLock(d->d_sb); + + if (d->d_inode) { + if (au_ftest_lock(flags, IW)) + ii_write_unlock(d->d_inode); + else if (au_ftest_lock(flags, IR)) + ii_read_unlock(d->d_inode); + } + au_rw_read_unlock(&au_di(d)->di_rwsem); +} + +void di_downgrade_lock(struct dentry *d, int flags) +{ + SiMustAnyLock(d->d_sb); + + au_rw_dgrade_lock(&au_di(d)->di_rwsem); + if (d->d_inode && au_ftest_lock(flags, IR)) + ii_downgrade_lock(d->d_inode); +} + +void di_write_lock(struct dentry *d, unsigned int lsc) +{ + LKTRTrace("%.*s, %u\n", AuDLNPair(d), lsc); + SiMustAnyLock(d->d_sb); + + /* todo: always nested? */ + au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc); + if (d->d_inode) + do_ii_write_lock(d->d_inode, lsc); +} + +void di_write_unlock(struct dentry *d) +{ + LKTRTrace("%.*s\n", AuDLNPair(d)); + SiMustAnyLock(d->d_sb); + + if (d->d_inode) + ii_write_unlock(d->d_inode); + au_rw_write_unlock(&au_di(d)->di_rwsem); +} + +void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir) +{ + AuTraceEnter(); + AuDebugOn(d1 == d2 + || d1->d_inode == d2->d_inode + || d1->d_sb != d2->d_sb); + + if (isdir && au_test_subdir(d1, d2)) { + di_write_lock_child(d1); + di_write_lock_child2(d2); + } else { + /* there should be no races */ + di_write_lock_child(d2); + di_write_lock_child2(d1); + } +} + +void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir) +{ + AuTraceEnter(); + AuDebugOn(d1 == d2 + || d1->d_inode == d2->d_inode + || d1->d_sb != d2->d_sb); + + if (isdir && au_test_subdir(d1, d2)) { + di_write_lock_parent(d1); + di_write_lock_parent2(d2); + } else { + /* there should be no races */ + di_write_lock_parent(d2); + di_write_lock_parent2(d1); + } +} + +void di_write_unlock2(struct dentry *d1, struct dentry *d2) +{ + di_write_unlock(d1); + if (d1->d_inode == d2->d_inode) + au_rw_write_unlock(&au_di(d2)->di_rwsem); + else + di_write_unlock(d2); +} + +/* ---------------------------------------------------------------------- */ + +struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex) +{ + struct dentry *d; + + DiMustAnyLock(dentry); + if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry)) + return NULL; + AuDebugOn(bindex < 0 + /* || bindex > au_sbend(dentry->d_sb) */); + d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry; + AuDebugOn(d && (atomic_read(&d->d_count) <= 0)); + return d; +} + +aufs_bindex_t au_dbtail(struct dentry *dentry) +{ + aufs_bindex_t bend, bwh; + + bend = au_dbend(dentry); + if (0 <= bend) { + bwh = au_dbwh(dentry); + if (!bwh) + return bwh; + if (0 < bwh && bwh < bend) + return bwh - 1; + } + return bend; +} + +aufs_bindex_t au_dbtaildir(struct dentry *dentry) +{ + aufs_bindex_t bend, bopq; + + AuDebugOn(dentry->d_inode + && dentry->d_inode->i_mode + && !S_ISDIR(dentry->d_inode->i_mode)); + + bend = au_dbtail(dentry); + if (0 <= bend) { + bopq = au_dbdiropq(dentry); + AuDebugOn(bend < bopq); + if (0 <= bopq && bopq < bend) + bend = bopq; + } + return bend; +} + +#if 0 /* reserved for future use */ +aufs_bindex_t au_dbtail_generic(struct dentry *dentry) +{ + struct inode *inode; + + inode = dentry->d_inode; + if (inode && S_ISDIR(inode->i_mode)) + return au_dbtaildir(dentry); + else + return au_dbtail(dentry); +} +#endif + +/* ---------------------------------------------------------------------- */ + +void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex) +{ + DiMustWriteLock(dentry); + AuDebugOn(au_sbend(dentry->d_sb) < bindex); + AuDebugOn((bindex >= 0 + && (bindex < au_dbstart(dentry) + || au_dbend(dentry) < bindex)) + || (dentry->d_inode + && dentry->d_inode->i_mode + && !S_ISDIR(dentry->d_inode->i_mode))); + au_di(dentry)->di_bdiropq = bindex; +} + +void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex, + struct dentry *h_dentry) +{ + struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex; + DiMustWriteLock(dentry); + AuDebugOn(bindex < au_di(dentry)->di_bstart + || bindex > au_di(dentry)->di_bend + || (h_dentry && atomic_read(&h_dentry->d_count) <= 0) + || (h_dentry && hd->hd_dentry) + ); + if (hd->hd_dentry) + au_hdput(hd, /*do_free*/0); + hd->hd_dentry = h_dentry; +} + +/* ---------------------------------------------------------------------- */ + +void au_update_dbrange(struct dentry *dentry, int do_put_zero) +{ + struct au_dinfo *dinfo; + aufs_bindex_t bindex; + struct dentry *h_d; + + LKTRTrace("%.*s, %d\n", AuDLNPair(dentry), do_put_zero); + DiMustWriteLock(dentry); + + dinfo = au_di(dentry); + if (unlikely(!dinfo) || dinfo->di_bstart < 0) + return; + + if (do_put_zero) { + for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; + bindex++) { + h_d = dinfo->di_hdentry[0 + bindex].hd_dentry; + if (h_d && !h_d->d_inode) + au_set_h_dptr(dentry, bindex, NULL); + } + } + + dinfo->di_bstart = -1; + while (++dinfo->di_bstart <= dinfo->di_bend) + if (dinfo->di_hdentry[0 + dinfo->di_bstart].hd_dentry) + break; + if (dinfo->di_bstart > dinfo->di_bend) { + dinfo->di_bstart = -1; + dinfo->di_bend = -1; + return; + } + + dinfo->di_bend++; + while (0 <= --dinfo->di_bend) + if (dinfo->di_hdentry[0 + dinfo->di_bend].hd_dentry) + break; + AuDebugOn(dinfo->di_bstart > dinfo->di_bend || dinfo->di_bend < 0); +} + +void au_update_dbstart(struct dentry *dentry) +{ + aufs_bindex_t bindex, + bstart = au_dbstart(dentry), + bend = au_dbend(dentry); + struct dentry *h_dentry; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + DiMustWriteLock(dentry); + + for (bindex = bstart; bindex <= bend; bindex++) { + h_dentry = au_h_dptr(dentry, bindex); + if (!h_dentry) + continue; + if (h_dentry->d_inode) { + au_set_dbstart(dentry, bindex); + return; + } + au_set_h_dptr(dentry, bindex, NULL); + } +} + +void au_update_dbend(struct dentry *dentry) +{ + aufs_bindex_t bindex, + bstart = au_dbstart(dentry), + bend = au_dbend(dentry); + struct dentry *h_dentry; + + DiMustWriteLock(dentry); + for (bindex = bend; bindex <= bstart; bindex--) { + h_dentry = au_h_dptr(dentry, bindex); + if (!h_dentry) + continue; + if (h_dentry->d_inode) { + au_set_dbend(dentry, bindex); + return; + } + au_set_h_dptr(dentry, bindex, NULL); + } +} + +int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry) +{ + aufs_bindex_t bindex, bend; + + bend = au_dbend(dentry); + for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) + if (au_h_dptr(dentry, bindex) == h_dentry) + return bindex; + return -1; +} --- linux-2.6.28.orig/ubuntu/aufs/dcsub.c +++ linux-2.6.28/ubuntu/aufs/dcsub.c @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * sub-routines for dentry cache + * + * $Id: dcsub.c,v 1.7 2008/07/21 02:54:22 sfjro Exp $ + */ + +#include "aufs.h" + +static void au_dpage_free(struct au_dpage *dpage) +{ + int i; + + AuTraceEnter(); + AuDebugOn(!dpage); + + for (i = 0; i < dpage->ndentry; i++) + dput(dpage->dentries[i]); + free_page((unsigned long)dpage->dentries); +} + +int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp) +{ + int err; + void *p; + + AuTraceEnter(); + + err = -ENOMEM; + dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp); + if (unlikely(!dpages->dpages)) + goto out; + p = (void *)__get_free_page(gfp); + if (unlikely(!p)) + goto out_dpages; + dpages->dpages[0].ndentry = 0; + dpages->dpages[0].dentries = p; + dpages->ndpage = 1; + return 0; /* success */ + + out_dpages: + kfree(dpages->dpages); + out: + AuTraceErr(err); + return err; +} + +void au_dpages_free(struct au_dcsub_pages *dpages) +{ + int i; + + AuTraceEnter(); + + for (i = 0; i < dpages->ndpage; i++) + au_dpage_free(dpages->dpages + i); + kfree(dpages->dpages); +} + +static int au_dpages_append(struct au_dcsub_pages *dpages, + struct dentry *dentry, gfp_t gfp) +{ + int err, sz; + struct au_dpage *dpage; + void *p; + + /* AuTraceEnter(); */ + + dpage = dpages->dpages + dpages->ndpage - 1; + AuDebugOn(!dpage); + sz = PAGE_SIZE / sizeof(dentry); + if (unlikely(dpage->ndentry >= sz)) { + LKTRLabel(new dpage); + err = -ENOMEM; + sz = dpages->ndpage * sizeof(*dpages->dpages); + p = au_kzrealloc(dpages->dpages, sz, + sz + sizeof(*dpages->dpages), gfp); + if (unlikely(!p)) + goto out; + dpages->dpages = p; + dpage = dpages->dpages + dpages->ndpage; + p = (void *)__get_free_page(gfp); + if (unlikely(!p)) + goto out; + dpage->ndentry = 0; + dpage->dentries = p; + dpages->ndpage++; + } + + dpage->dentries[dpage->ndentry++] = dget(dentry); + return 0; /* success */ + + out: + /* AuTraceErr(err); */ + return err; +} + +int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root, + au_dpages_test test, void *arg) +{ + int err; + struct dentry *this_parent = root; + struct list_head *next; + struct super_block *sb = root->d_sb; + + AuTraceEnter(); + + err = 0; + spin_lock(&dcache_lock); + repeat: + next = this_parent->d_subdirs.next; + resume: + if (this_parent->d_sb == sb + && !IS_ROOT(this_parent) + && atomic_read(&this_parent->d_count) + && this_parent->d_inode + && (!test || test(this_parent, arg))) { + err = au_dpages_append(dpages, this_parent, GFP_ATOMIC); + if (unlikely(err)) + goto out; + } + + while (next != &this_parent->d_subdirs) { + struct list_head *tmp = next; + struct dentry *dentry = list_entry(tmp, struct dentry, + d_u.d_child); + next = tmp->next; + if (unlikely(/*d_unhashed(dentry) || */!dentry->d_inode)) + continue; + if (!list_empty(&dentry->d_subdirs)) { + this_parent = dentry; + goto repeat; + } + if (dentry->d_sb == sb + && atomic_read(&dentry->d_count) + && (!test || test(dentry, arg))) { + err = au_dpages_append(dpages, dentry, GFP_ATOMIC); + if (unlikely(err)) + goto out; + } + } + + if (this_parent != root) { + next = this_parent->d_u.d_child.next; + this_parent = this_parent->d_parent; /* dcache_lock is locked */ + goto resume; + } + out: + spin_unlock(&dcache_lock); +#if 0 /* debug */ + if (!err) { + int i, j; + j = 0; + for (i = 0; i < dpages->ndpage; i++) { + if ((dpages->dpages + i)->ndentry) + AuDbg("%d: %d\n", + i, (dpages->dpages + i)->ndentry); + j += (dpages->dpages + i)->ndentry; + } + if (j) + AuDbg("ndpage %d, %d\n", dpages->ndpage, j); + } +#endif + AuTraceErr(err); + return err; +} + +int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry, + int do_include, au_dpages_test test, void *arg) +{ + int err; + + AuTraceEnter(); + + err = 0; + spin_lock(&dcache_lock); + if (do_include && (!test || test(dentry, arg))) { + err = au_dpages_append(dpages, dentry, GFP_ATOMIC); + if (unlikely(err)) + goto out; + } + while (!IS_ROOT(dentry)) { + dentry = dentry->d_parent; /* dcache_lock is locked */ + if (!test || test(dentry, arg)) { + err = au_dpages_append(dpages, dentry, GFP_ATOMIC); + if (unlikely(err)) + break; + } + } + + out: + spin_unlock(&dcache_lock); + + AuTraceErr(err); + return err; +} + +struct dentry *au_test_subdir(struct dentry *d1, struct dentry *d2) +{ + struct dentry *trap, **dentries; + int err, i, j; + struct au_dcsub_pages dpages; + struct au_dpage *dpage; + + LKTRTrace("%.*s, %.*s\n", AuDLNPair(d1), AuDLNPair(d2)); + + trap = ERR_PTR(-ENOMEM); + err = au_dpages_init(&dpages, GFP_NOFS); + if (unlikely(err)) + goto out; + err = au_dcsub_pages_rev(&dpages, d1, /*do_include*/1, NULL, NULL); + if (unlikely(err)) + goto out_dpages; + + trap = d1; + for (i = 0; !err && i < dpages.ndpage; i++) { + dpage = dpages.dpages + i; + dentries = dpage->dentries; + for (j = 0; !err && j < dpage->ndentry; j++) { + struct dentry *d; + d = dentries[j]; + err = (d == d2); + if (!err) + trap = d; + } + } + if (!err) + trap = NULL; + + out_dpages: + au_dpages_free(&dpages); + out: + AuTraceErrPtr(trap); + return trap; +} --- linux-2.6.28.orig/ubuntu/aufs/branch.c +++ linux-2.6.28/ubuntu/aufs/branch.c @@ -0,0 +1,1025 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * branch management + * + * $Id: branch.c,v 1.16 2008/09/08 02:39:41 sfjro Exp $ + */ + +#include +#include +#include +#include +#include "aufs.h" + +static void au_br_do_free(struct au_branch *br) +{ + int i; + struct au_wbr *wbr; + + AuTraceEnter(); + + if (br->br_xino.xi_file) + fput(br->br_xino.xi_file); + wbr = br->br_wbr; + if (wbr) + for (i = 0; i < AuBrWh_Last; i++) + dput(wbr->wbr_wh[i]); + /* do not call au_br_nfs_lockdep_off() here */ + if (!au_test_nfs(br->br_mnt->mnt_sb)) + mntput(br->br_mnt); + else { + lockdep_off(); + mntput(br->br_mnt); + lockdep_on(); + } + AuDebugOn(au_br_count(br)); + if (wbr) + AuDebugOn(atomic_read(&wbr->wbr_wh_running)); + kfree(wbr); + kfree(br); +} + +/* + * frees all branches + */ +void au_br_free(struct au_sbinfo *sbinfo) +{ + aufs_bindex_t bmax; + struct au_branch **br; + + AuTraceEnter(); + bmax = sbinfo->si_bend + 1; + br = sbinfo->si_branch; + while (bmax--) + au_br_do_free(*br++); +} + +/* + * find the index of a branch which is specified by @br_id. + */ +int au_br_index(struct super_block *sb, aufs_bindex_t br_id) +{ + aufs_bindex_t bindex, bend; + + AuTraceEnter(); + + bend = au_sbend(sb); + for (bindex = 0; bindex <= bend; bindex++) + if (au_sbr_id(sb, bindex) == br_id) + return bindex; + return -1; +} + +/* + * test if the @h_sb is real-readonly. + */ +int au_test_def_rr(struct super_block *h_sb) +{ + switch (h_sb->s_magic) { +#ifdef CONFIG_AUFS_RR_SQUASHFS + case SQUASHFS_MAGIC_LZMA: + case SQUASHFS_MAGIC: + case SQUASHFS_MAGIC_LZMA_SWAP: + case SQUASHFS_MAGIC_SWAP: + return 1; /* real readonly */ +#endif + +#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE) + case ISOFS_SUPER_MAGIC: + return 1; +#endif + +#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE) + case CRAMFS_MAGIC: + return 1; +#endif + +#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE) + case ROMFS_MAGIC: + return 1; +#endif + + default: + return 0; + } +} + +/* ---------------------------------------------------------------------- */ + +/* + * test if two hidden_dentries have overlapping branches. + */ +static int do_test_overlap(struct super_block *sb, struct dentry *h_d1, + struct dentry *h_d2) +{ + struct dentry *d; + + LKTRTrace("%.*s, %.*s\n", AuDLNPair(h_d1), AuDLNPair(h_d2)); + + d = au_test_subdir(h_d1, h_d2); + if (unlikely(d)) { + AuDbgDentry(h_d1); + AuDbgDentry(h_d2); + } + return !!d; +} + +static int test_overlap_loopback(struct super_block *sb, struct dentry *h_d1, + struct dentry *h_d2) +{ +#if defined(CONFIG_BLK_DEV_LOOP) || defined(CONFIG_BLK_DEV_LOOP_MODULE) + struct inode *h_inode; + struct loop_device *l; + + LKTRTrace("%.*s, %.*s\n", AuDLNPair(h_d1), AuDLNPair(h_d2)); + AuDbgDentry(h_d1); + AuDbgDentry(h_d2); + AuDbgSb(h_d1->d_sb); + AuDbgSb(h_d2->d_sb); + + h_inode = h_d1->d_inode; + if (MAJOR(h_inode->i_sb->s_dev) != LOOP_MAJOR) + return 0; + + l = h_inode->i_sb->s_bdev->bd_disk->private_data; + h_d1 = l->lo_backing_file->f_dentry; + /* h_d1 can be local NFS. in this case aufs cannot detect the loop */ + AuDbgDentry(h_d1); + AuDbgDentry(h_d2); + AuDbgSb(h_d1->d_sb); + AuDbgSb(h_d2->d_sb); + if (unlikely(h_d1->d_sb == sb)) + return 1; + return do_test_overlap(sb, h_d1, h_d2); +#else + return 0; +#endif +} + +static int test_overlap(struct super_block *sb, struct dentry *h_d1, + struct dentry *h_d2) +{ + LKTRTrace("d1 %.*s, d2 %.*s\n", AuDLNPair(h_d1), AuDLNPair(h_d2)); + + if (unlikely(h_d1 == h_d2)) { + AuDbgDentry(h_d1); + AuDbgDentry(h_d2); + return 1; + } + return do_test_overlap(sb, h_d1, h_d2) + || do_test_overlap(sb, h_d2, h_d1) + || test_overlap_loopback(sb, h_d1, h_d2) + || test_overlap_loopback(sb, h_d2, h_d1); +} + +/* ---------------------------------------------------------------------- */ + +static int au_br_init_wh(struct super_block *sb, aufs_bindex_t bindex, + struct au_branch *br, int new_perm, + struct dentry *h_root, struct vfsmount *h_mnt) +{ + int err, old_perm; + struct inode *h_dir; + struct au_wbr *wbr; + + LKTRTrace("b%d, new_perm %d\n", bindex, new_perm); + + wbr = br->br_wbr; + h_dir = h_root->d_inode; + old_perm = br->br_perm; + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); + if (wbr) + wbr_wh_write_lock(wbr); + br->br_perm = new_perm; + err = au_wh_init(h_root, br, au_do_nfsmnt(h_mnt), sb, bindex); + br->br_perm = old_perm; + if (wbr) + wbr_wh_write_unlock(wbr); + mutex_unlock(&h_dir->i_mutex); + if (!err && wbr && !au_br_writable(new_perm)) { + AuDebugOn(wbr->wbr_whbase); + AuDebugOn(wbr->wbr_plink); + AuDebugOn(wbr->wbr_tmp); + kfree(wbr); + br->br_wbr = NULL; + } + + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +/* + * returns a newly allocated branch. @new_nbranch is a number of branches + * after adding a branch. + */ +static struct au_branch *alloc_addbr(struct super_block *sb, int new_nbranch, + int perm) +{ + struct au_branch **branchp, *add_branch; + int sz; + void *p; + struct dentry *root; + struct inode *inode; + struct au_hinode *hinodep; + struct au_hdentry *hdentryp; + + LKTRTrace("new_nbranch %d\n", new_nbranch); + SiMustWriteLock(sb); + root = sb->s_root; + DiMustWriteLock(root); + inode = root->d_inode; + IiMustWriteLock(inode); + + add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS); + if (unlikely(!add_branch)) + goto out; + add_branch->br_wbr = NULL; + if (unlikely(au_br_writable(perm))) { + add_branch->br_wbr = kmalloc(sizeof(*add_branch->br_wbr), + GFP_NOFS); + if (unlikely(!add_branch->br_wbr)) + goto out_br; + } + + sz = sizeof(*branchp) * (new_nbranch - 1); + if (unlikely(!sz)) + sz = sizeof(*branchp); + p = au_sbi(sb)->si_branch; + branchp = au_kzrealloc(p, sz, sizeof(*branchp) * new_nbranch, GFP_NOFS); + if (unlikely(!branchp)) + goto out_wbr; + au_sbi(sb)->si_branch = branchp; + + sz = sizeof(*hdentryp) * (new_nbranch - 1); + if (unlikely(!sz)) + sz = sizeof(*hdentryp); + p = au_di(root)->di_hdentry; + hdentryp = au_kzrealloc(p, sz, sizeof(*hdentryp) * new_nbranch, + GFP_NOFS); + if (unlikely(!hdentryp)) + goto out_wbr; + au_di(root)->di_hdentry = hdentryp; + + sz = sizeof(*hinodep) * (new_nbranch - 1); + if (unlikely(!sz)) + sz = sizeof(*hinodep); + p = au_ii(inode)->ii_hinode; + hinodep = au_kzrealloc(p, sz, sizeof(*hinodep) * new_nbranch, GFP_NOFS); + if (unlikely(!hinodep)) + goto out_wbr; + au_ii(inode)->ii_hinode = hinodep; + return add_branch; /* success */ + + out_wbr: + kfree(add_branch->br_wbr); + out_br: + kfree(add_branch); + out: + AuTraceErr(-ENOMEM); + return ERR_PTR(-ENOMEM); +} + +/* + * test if the branch permission is legal or not. + */ +static int test_br(struct super_block *sb, struct inode *inode, int brperm, + char *path) +{ + int err; + + err = 0; + if (unlikely(au_br_writable(brperm) && IS_RDONLY(inode))) { + AuErr("write permission for readonly fs or inode, %s\n", path); + err = -EINVAL; + } + + AuTraceErr(err); + return err; +} + +static int au_unsupported_fs(struct super_block *sb) +{ + return (sb->s_magic == PROC_SUPER_MAGIC +#ifdef SYSFS_MAGIC + || sb->s_magic == SYSFS_MAGIC +#endif + || !strcmp(au_sbtype(sb), "unionfs")); +} + +/* + * returns: + * 0: success, the caller will add it + * plus: success, it is already unified, the caller should ignore it + * minus: error + */ +static int test_add(struct super_block *sb, struct au_opt_add *add, int remount) +{ + int err; + struct dentry *root; + struct inode *inode, *h_inode; + aufs_bindex_t bend, bindex; + + LKTRTrace("%s, remo%d\n", add->path, remount); + + root = sb->s_root; + bend = au_sbend(sb); + if (unlikely(bend >= 0 + && au_find_dbindex(root, add->nd.path.dentry) >= 0)) { + err = 1; + if (!remount) { + err = -EINVAL; + AuErr("%s duplicated\n", add->path); + } + goto out; + } + + err = -ENOSPC; /* -E2BIG; */ + if (unlikely(AUFS_BRANCH_MAX <= add->bindex + || AUFS_BRANCH_MAX - 1 <= bend)) { + AuErr("number of branches exceeded %s\n", add->path); + goto out; + } + + err = -EDOM; + if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) { + AuErr("bad index %d\n", add->bindex); + goto out; + } + + inode = add->nd.path.dentry->d_inode; + AuDebugOn(!inode || !S_ISDIR(inode->i_mode)); + err = -ENOENT; + if (unlikely(!inode->i_nlink)) { + AuErr("no existence %s\n", add->path); + goto out; + } + + err = -EINVAL; + if (unlikely(inode->i_sb == sb)) { + AuErr("%s must be outside\n", add->path); + goto out; + } + + if (unlikely(au_test_nested(inode->i_sb))) { + AuErr("nested " AUFS_NAME " %s\n", add->path); + goto out; + } + + if (unlikely(au_unsupported_fs(inode->i_sb))) { + AuErr("unsupported filesystem, %s\n", add->path); + goto out; + } + + if (unlikely(au_test_unsupported_nfs(inode->i_sb))) { + AuErr(AuNoNfsBranchMsg " %s\n", add->path); + goto out; + } + + err = test_br(sb, add->nd.path.dentry->d_inode, add->perm, add->path); + if (unlikely(err)) + goto out; + + if (bend < 0) + return 0; /* success */ + + err = -EINVAL; + for (bindex = 0; bindex <= bend; bindex++) + if (unlikely(test_overlap(sb, add->nd.path.dentry, + au_h_dptr(root, bindex)))) { + AuErr("%s is overlapped\n", add->path); + goto out; + } + + err = 0; + h_inode = au_h_dptr(root, 0)->d_inode; + if (unlikely(au_opt_test(au_mntflags(sb), WARN_PERM) + && ((h_inode->i_mode & S_IALLUGO) + != (inode->i_mode & S_IALLUGO) + || h_inode->i_uid != inode->i_uid + || h_inode->i_gid != inode->i_gid))) + AuWarn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n", + add->path, + inode->i_uid, inode->i_gid, (inode->i_mode & S_IALLUGO), + h_inode->i_uid, h_inode->i_gid, + (h_inode->i_mode & S_IALLUGO)); + + out: + AuTraceErr(err); + return err; +} + +static int au_wbr_init(struct au_branch *br, struct super_block *sb, + int perm, struct path *path) +{ + int err; + struct au_wbr *wbr; + + AuTraceEnter(); + wbr = br->br_wbr; + AuDebugOn(!wbr); + + au_rw_init_nolock(&wbr->wbr_wh_rwsem); + memset(wbr->wbr_wh, 0, sizeof(wbr->wbr_wh)); + atomic_set(&wbr->wbr_wh_running, 0); + wbr->wbr_bytes = 0; + + err = au_br_init_wh(sb, /*bindex*/-1, br, perm, + path->dentry, path->mnt); + + AuTraceErr(err); + return err; +} + +static int au_br_init(struct au_branch *br, struct super_block *sb, + struct au_opt_add *add) +{ + int err; + unsigned int mnt_flags; + + AuTraceEnter(); + + err = 0; + if (unlikely(au_br_writable(add->perm))) { + err = au_wbr_init(br, sb, add->perm, &add->nd.path); + if (unlikely(err)) + goto out; + } + + br->br_xino.xi_file = NULL; + mutex_init(&br->br_xino.xi_nondir_mtx); + br->br_mnt = mntget(add->nd.path.mnt); + mnt_flags = au_mntflags(sb); + if (au_opt_test(mnt_flags, XINO)) { + err = au_xino_br(sb, br, add->nd.path.dentry->d_inode->i_ino, + au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1); + if (unlikely(err)) { + AuDebugOn(br->br_xino.xi_file); + goto out; + } +#if 0 /* reserved for future use */ + } else if (au_opt_test(mnt_flags, XINODIR)) { + err = au_xinodir_br(sb, br, add->nd.path.dentry->d_inode->i_ino, + /*do_test*/1); + if (unlikely(err)) { + AuDebugOn(br->br_xino.xi_file); + goto out; + } +#endif + } + + br->br_id = au_new_br_id(sb); + br->br_perm = add->perm; + atomic_set(&br->br_count, 0); + br->br_xino_upper = AUFS_XINO_TRUNC_INIT; + atomic_set(&br->br_xino_running, 0); + sysaufs_br_init(br); + br->br_generation = au_sigen(sb); + /* smp_mb(); */ /* atomic_set */ + + out: + AuTraceErr(err); + return err; +} + +int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount) +{ + int err, amount; + aufs_bindex_t bend, add_bindex; + struct dentry *root, *dentry; + struct au_iinfo *iinfo; + struct au_sbinfo *sbinfo; + struct au_dinfo *dinfo; + struct inode *root_inode; + unsigned long long maxb; + struct au_branch **branchp, *add_branch; + struct au_hdentry *hdentryp; + struct au_hinode *hinodep; + + dentry = add->nd.path.dentry; + LKTRTrace("b%d, %s, 0x%x, %.*s\n", + add->bindex, add->path, add->perm, AuDLNPair(dentry)); + SiMustWriteLock(sb); + root = sb->s_root; + DiMustWriteLock(root); + root_inode = root->d_inode; + IMustLock(root_inode); + IiMustWriteLock(root_inode); + + err = test_add(sb, add, remount); + if (unlikely(err < 0)) + goto out; + if (err) + return 0; /* success */ + + bend = au_sbend(sb); + add_branch = alloc_addbr(sb, bend + 2, add->perm); + err = PTR_ERR(add_branch); + if (IS_ERR(add_branch)) + goto out; + err = au_br_init(add_branch, sb, add); + if (unlikely(err)) { + au_br_do_free(add_branch); + goto out; + } + + add_bindex = add->bindex; + if (remount) + sysaufs_brs_del(sb, add_bindex); + + sbinfo = au_sbi(sb); + dinfo = au_di(root); + iinfo = au_ii(root_inode); + + amount = bend + 1 - add_bindex; + branchp = sbinfo->si_branch + add_bindex; + memmove(branchp + 1, branchp, sizeof(*branchp) * amount); + *branchp = add_branch; + hdentryp = dinfo->di_hdentry + add_bindex; + memmove(hdentryp + 1, hdentryp, sizeof(*hdentryp) * amount); + au_h_dentry_init(hdentryp); + hinodep = iinfo->ii_hinode + add_bindex; + memmove(hinodep + 1, hinodep, sizeof(*hinodep) * amount); + hinodep->hi_inode = NULL; + au_hin_init(hinodep, NULL); + + sbinfo->si_bend++; + dinfo->di_bend++; + iinfo->ii_bend++; + if (unlikely(bend < 0)) { + sbinfo->si_bend = 0; + dinfo->di_bstart = 0; + iinfo->ii_bstart = 0; + } + au_set_h_dptr(root, add_bindex, dget(dentry)); + au_set_h_iptr(root_inode, add_bindex, au_igrab(dentry->d_inode), 0); + if (remount) + sysaufs_brs_add(sb, add_bindex); + + if (!add_bindex) + au_cpup_attr_all(root_inode); + else + au_add_nlink(root_inode, dentry->d_inode); + maxb = dentry->d_sb->s_maxbytes; + if (sb->s_maxbytes < maxb) + sb->s_maxbytes = maxb; + + /* safe d_parent reference */ + if (!au_xino_def_br(sbinfo) + && add_branch->br_xino.xi_file + && add_branch->br_xino.xi_file->f_dentry->d_parent == dentry) + au_xino_def_br_set(add_branch, sbinfo); + + out: + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +#define AuVerbose(do_info, fmt, args...) do { \ + if (!do_info) \ + LKTRTrace(fmt, ##args); \ + else \ + AuInfo(fmt, ##args); \ +} while (0) + +/* + * test if the branch is deletable or not. + */ +static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex, + au_gen_t sigen) +{ + int err, i, j, ndentry; + struct au_dcsub_pages dpages; + struct au_dpage *dpage; + struct dentry *d; + aufs_bindex_t bstart, bend; + unsigned char verbose; + struct inode *inode; + + LKTRTrace("b%d, gen%d\n", bindex, sigen); + SiMustWriteLock(root->d_sb); + + err = au_dpages_init(&dpages, GFP_NOFS); + if (unlikely(err)) + goto out; + err = au_dcsub_pages(&dpages, root, NULL, NULL); + if (unlikely(err)) + goto out_dpages; + + verbose = !!au_opt_test(au_mntflags(root->d_sb), VERBOSE); + for (i = 0; !err && i < dpages.ndpage; i++) { + dpage = dpages.dpages + i; + ndentry = dpage->ndentry; + for (j = 0; !err && j < ndentry; j++) { + d = dpage->dentries[j]; + AuDebugOn(!atomic_read(&d->d_count)); + inode = d->d_inode; + AuDebugOn(!inode); + if (au_digen(d) == sigen + && au_iigen(inode) == sigen) + di_read_lock_child(d, AuLock_IR); + else { + di_write_lock_child(d); + err = au_reval_dpath(d, sigen); + if (!err) + di_downgrade_lock(d, AuLock_IR); + else { + di_write_unlock(d); + break; + } + } + + bstart = au_dbstart(d); + bend = au_dbend(d); + if (bstart <= bindex + && bindex <= bend + && au_h_dptr(d, bindex) + && (!S_ISDIR(d->d_inode->i_mode) + || bstart == bend)) { + err = -EBUSY; + AuVerbose(verbose, "busy %.*s\n", AuDLNPair(d)); + } + di_read_unlock(d, AuLock_IR); + } + } + + out_dpages: + au_dpages_free(&dpages); + out: + AuTraceErr(err); + return err; +} + +static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex, + au_gen_t sigen) +{ + int err; + struct inode *i; + aufs_bindex_t bstart, bend; + unsigned char verbose; + + LKTRTrace("b%d, gen%d\n", bindex, sigen); + SiMustWriteLock(sb); + + err = 0; + verbose = !!au_opt_test(au_mntflags(sb), VERBOSE); + list_for_each_entry(i, &sb->s_inodes, i_sb_list) { + AuDebugOn(!atomic_read(&i->i_count)); + if (!list_empty(&i->i_dentry)) + continue; + + if (au_iigen(i) == sigen) + ii_read_lock_child(i); + else { + ii_write_lock_child(i); + err = au_refresh_hinode_self(i); + if (!err) + ii_downgrade_lock(i); + else { + ii_write_unlock(i); + break; + } + } + + bstart = au_ibstart(i); + bend = au_ibend(i); + if (bstart <= bindex + && bindex <= bend + && au_h_iptr(i, bindex) + && (!S_ISDIR(i->i_mode) || bstart == bend)) { + err = -EBUSY; + AuVerbose(verbose, "busy i%lu\n", i->i_ino); + ii_read_unlock(i); + break; + } + ii_read_unlock(i); + } + + AuTraceErr(err); + return err; +} + +static int test_children_busy(struct dentry *root, aufs_bindex_t bindex) +{ + int err; + au_gen_t sigen; + + LKTRTrace("b%d\n", bindex); + SiMustWriteLock(root->d_sb); + DiMustWriteLock(root); + /* dont trust BKL */ + AuDebugOn(!kernel_locked()); + + sigen = au_sigen(root->d_sb); + DiMustNoWaiters(root); + IiMustNoWaiters(root->d_inode); + di_write_unlock(root); + err = test_dentry_busy(root, bindex, sigen); + if (!err) + err = test_inode_busy(root->d_sb, bindex, sigen); + di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */ + + AuTraceErr(err); + return err; +} + +int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount) +{ + int err, rerr, i; + aufs_bindex_t bindex, bend, br_id; + unsigned char do_wh, verbose; + struct au_sbinfo *sbinfo; + struct au_dinfo *dinfo; + struct au_iinfo *iinfo; + struct au_branch *br, **brp; + struct au_wbr *wbr; + struct au_hdentry *hdp; + struct au_hinode *hip; + + LKTRTrace("%s, %.*s\n", del->path, AuDLNPair(del->h_root)); + SiMustWriteLock(sb); + DiMustWriteLock(sb->s_root); + IiMustWriteLock(sb->s_root->d_inode); + + err = 0; + bindex = au_find_dbindex(sb->s_root, del->h_root); + if (bindex < 0) { + if (remount) + goto out; /* success */ + err = -ENOENT; + AuErr("%s no such branch\n", del->path); + goto out; + } + LKTRTrace("bindex b%d\n", bindex); + + err = -EBUSY; + verbose = !!au_opt_test(au_mntflags(sb), VERBOSE); + bend = au_sbend(sb); + if (unlikely(!bend)) { + AuVerbose(verbose, "no more branches left\n"); + goto out; + } + br = au_sbr(sb, bindex); + if (unlikely(au_br_count(br))) { + AuVerbose(verbose, "%d file(s) opened\n", au_br_count(br)); + goto out; + } + + wbr = br->br_wbr; + do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_tmp); + if (do_wh) { +#if 0 /* reserved for future use */ + /* remove whiteout base */ + err = au_br_init_wh(sb, bindex, br, AuBr_RO, del->h_root, + br->br_mnt); + if (unlikely(err)) + goto out; +#else + for (i = 0; i < AuBrWh_Last; i++) { + dput(wbr->wbr_wh[i]); + wbr->wbr_wh[i] = NULL; + } +#endif + } + + err = test_children_busy(sb->s_root, bindex); + if (unlikely(err)) { + if (unlikely(do_wh)) + goto out_wh; + goto out; + } + + err = 0; + if (remount) + sysaufs_brs_del(sb, bindex); + sbinfo = au_sbi(sb); + dinfo = au_di(sb->s_root); + iinfo = au_ii(sb->s_root->d_inode); + + dput(au_h_dptr(sb->s_root, bindex)); + au_hiput(iinfo->ii_hinode + bindex); + br_id = br->br_id; + au_br_do_free(br); + + /* todo: realloc and shrink memory? */ + if (bindex < bend) { + const aufs_bindex_t n = bend - bindex; + + brp = sbinfo->si_branch + bindex; + memmove(brp, brp + 1, sizeof(*brp) * n); + hdp = dinfo->di_hdentry + bindex; + memmove(hdp, hdp + 1, sizeof(*hdp) * n); + hip = iinfo->ii_hinode + bindex; + memmove(hip, hip + 1, sizeof(*hip) * n); + } + sbinfo->si_branch[0 + bend] = NULL; + dinfo->di_hdentry[0 + bend].hd_dentry = NULL; + iinfo->ii_hinode[0 + bend].hi_inode = NULL; + au_hin_init(iinfo->ii_hinode + bend, NULL); + + sbinfo->si_bend--; + dinfo->di_bend--; + iinfo->ii_bend--; + if (remount) + sysaufs_brs_add(sb, bindex); + + if (!bindex) + au_cpup_attr_all(sb->s_root->d_inode); + else + au_sub_nlink(sb->s_root->d_inode, del->h_root->d_inode); + if (au_opt_test(au_mntflags(sb), PLINK)) + au_plink_half_refresh(sb, br_id); + + if (sb->s_maxbytes == del->h_root->d_sb->s_maxbytes) { + bend--; + sb->s_maxbytes = 0; + for (bindex = 0; bindex <= bend; bindex++) { + unsigned long long maxb; + maxb = au_sbr_sb(sb, bindex)->s_maxbytes; + if (sb->s_maxbytes < maxb) + sb->s_maxbytes = maxb; + } + } + + if (au_xino_def_br(sbinfo) == br) + au_xino_def_br_set(NULL, sbinfo); + goto out; /* success */ + + out_wh: + /* revert */ + rerr = au_br_init_wh(sb, bindex, br, br->br_perm, del->h_root, + br->br_mnt); + if (rerr) + AuWarn("failed re-creating base whiteout, %s. (%d)\n", + del->path, rerr); + out: + AuTraceErr(err); + return err; +} + +static int do_need_sigen_inc(int a, int b) +{ + return (au_br_whable(a) && !au_br_whable(b)); +} + +static int need_sigen_inc(int old, int new) +{ + return (do_need_sigen_inc(old, new) + || do_need_sigen_inc(new, old)); +} + +static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex) +{ + int err; + struct file *file, *hf; + + AuTraceEnter(); + SiMustWriteLock(sb); + + /* no need file_list_lock() since sbinfo is locked */ + err = 0; + list_for_each_entry(file, &sb->s_files, f_u.fu_list) { + LKTRTrace("%.*s\n", AuDLNPair(file->f_dentry)); + if (!au_test_aufs_file(file)) + continue; + + fi_read_lock(file); + if (!S_ISREG(file->f_dentry->d_inode->i_mode) + || !(file->f_mode & FMODE_WRITE) + || au_fbstart(file) != bindex) { + FiMustNoWaiters(file); + fi_read_unlock(file); + continue; + } + + if (unlikely(au_test_mmapped(file))) { + err = -EBUSY; + FiMustNoWaiters(file); + fi_read_unlock(file); + break; + } + + /* todo: already flushed? */ + hf = au_h_fptr(file, au_fbstart(file)); + hf->f_flags = au_file_roflags(hf->f_flags); + hf->f_mode &= ~FMODE_WRITE; + put_write_access(hf->f_dentry->d_inode); + FiMustNoWaiters(file); + fi_read_unlock(file); + } + + AuTraceErr(err); + return err; +} + +int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount, + int *do_update) +{ + int err; + struct dentry *root; + aufs_bindex_t bindex; + struct au_branch *br; + struct inode *hidden_dir; + + LKTRTrace("%s, %.*s, 0x%x\n", + mod->path, AuDLNPair(mod->h_root), mod->perm); + SiMustWriteLock(sb); + root = sb->s_root; + DiMustWriteLock(root); + IiMustWriteLock(root->d_inode); + + bindex = au_find_dbindex(root, mod->h_root); + if (bindex < 0) { + if (remount) + return 0; /* success */ + err = -ENOENT; + AuErr("%s no such branch\n", mod->path); + goto out; + } + LKTRTrace("bindex b%d\n", bindex); + + hidden_dir = mod->h_root->d_inode; + err = test_br(sb, hidden_dir, mod->perm, mod->path); + if (unlikely(err)) + goto out; + + br = au_sbr(sb, bindex); + if (br->br_perm == mod->perm) + return 0; /* success */ + + if (au_br_writable(br->br_perm)) { +#if 1 + /* remove whiteout base */ + err = au_br_init_wh(sb, bindex, br, mod->perm, mod->h_root, + br->br_mnt); + if (unlikely(err)) + goto out; +#else /* reserved for future use */ + struct au_wbr *wbr; + wbr = br->wbr; + if (wbr) + for (i = 0; i < AuBrWh_Last; i++) { + dput(wbr->wbr_wh[i]); + wbr->wbr_wh[i] = NULL; + } +#endif + + if (!au_br_writable(mod->perm)) { + /* rw --> ro, file might be mmapped */ + +#if 1 /* todo: test more? */ + DiMustNoWaiters(root); + IiMustNoWaiters(root->d_inode); + di_write_unlock(root); + err = au_br_mod_files_ro(sb, bindex); + /* aufs_write_lock() calls ..._child() */ + di_write_lock_child(root); +#endif + } + } else if (au_br_writable(mod->perm)) { + /* ro --> rw */ + err = -ENOMEM; + br->br_wbr = kmalloc(sizeof(*br->br_wbr), GFP_NOFS); + if (br->br_wbr) { + struct path path = { + .mnt = br->br_mnt, + .dentry = mod->h_root + }; + + err = au_wbr_init(br, sb, mod->perm, &path); + if (unlikely(err)) { + kfree(br->br_wbr); + br->br_wbr = NULL; + } + } + } + + if (!err) { + *do_update |= need_sigen_inc(br->br_perm, mod->perm); + br->br_perm = mod->perm; + } + + out: + AuTraceErr(err); + return err; +} --- linux-2.6.28.orig/ubuntu/aufs/aufs.h +++ linux-2.6.28/ubuntu/aufs/aufs.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * main header files + * + * $Id: aufs.h,v 1.4 2008/06/30 03:58:55 sfjro Exp $ + */ + +#ifndef __AUFS_H__ +#define __AUFS_H__ + +#ifdef __KERNEL__ + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) +#error you got wrong version +#endif + +#include "debug.h" + +#include "branch.h" +#include "cpup.h" +#include "dcsub.h" +#include "dentry.h" +#include "dir.h" +#include "file.h" +#include "hinode.h" +#include "inode.h" +#include "misc.h" +#include "module.h" +#include "opts.h" +#include "super.h" +#include "sysaufs.h" +#include "vfsub.h" +#include "whout.h" +#include "wkq.h" +/* reserved for future use */ +/* #include "xattr.h" */ + +#ifdef AuNoInlineForStack +#undef noinline_for_stack +#define noinline_for_stack /* */ +#endif + +#endif /* __KERNEL__ */ +#endif /* __AUFS_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/plink.c +++ linux-2.6.28/ubuntu/aufs/plink.c @@ -0,0 +1,360 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * pseudo-link + * + * $Id: plink.c,v 1.9 2008/09/01 02:55:35 sfjro Exp $ + */ + +#include "aufs.h" + +struct pseudo_link { + struct list_head list; + struct inode *inode; +}; + +#ifdef CONFIG_AUFS_DEBUG +void au_plink_list(struct super_block *sb) +{ + struct au_sbinfo *sbinfo; + struct list_head *plink_list; + struct pseudo_link *plink; + + AuTraceEnter(); + SiMustAnyLock(sb); + sbinfo = au_sbi(sb); + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); + + plink_list = &sbinfo->si_plink; + spin_lock(&sbinfo->si_plink_lock); + list_for_each_entry(plink, plink_list, list) + AuDbg("%lu\n", plink->inode->i_ino); + spin_unlock(&sbinfo->si_plink_lock); +} +#endif + +int au_plink_test(struct super_block *sb, struct inode *inode) +{ + int found; + struct au_sbinfo *sbinfo; + struct list_head *plink_list; + struct pseudo_link *plink; + + LKTRTrace("i%lu\n", inode->i_ino); + SiMustAnyLock(sb); + sbinfo = au_sbi(sb); + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); + + found = 0; + plink_list = &sbinfo->si_plink; + spin_lock(&sbinfo->si_plink_lock); + list_for_each_entry(plink, plink_list, list) + if (plink->inode == inode) { + found = 1; + break; + } + spin_unlock(&sbinfo->si_plink_lock); + return found; +} + +/* 20 is max digits length of ulong 64 */ +#define PLINK_NAME_LEN ((20 + 1) * 2) + +static int plink_name(char *name, int len, struct inode *inode, + aufs_bindex_t bindex) +{ + int rlen; + struct inode *h_inode; + + LKTRTrace("i%lu, b%d\n", inode->i_ino, bindex); + AuDebugOn(len != PLINK_NAME_LEN); + h_inode = au_h_iptr(inode, bindex); + AuDebugOn(!h_inode); + rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino); + AuDebugOn(rlen >= len); + return rlen; +} + +struct dentry *au_plink_lkup(struct super_block *sb, aufs_bindex_t bindex, + struct inode *inode) +{ + struct dentry *h_dentry, *h_parent; + struct au_branch *br; + struct au_wbr *wbr; + struct inode *h_dir; + char tgtname[PLINK_NAME_LEN]; + int len; + struct au_ndx ndx = { + .flags = 0, + .nd = NULL, + /* .br = NULL */ + }; + + LKTRTrace("b%d, i%lu\n", bindex, inode->i_ino); + br = au_sbr(sb, bindex); + wbr = br->br_wbr; + AuDebugOn(!wbr); + h_parent = wbr->wbr_plink; + AuDebugOn(!h_parent); + h_dir = h_parent->d_inode; + AuDebugOn(!h_dir); + + len = plink_name(tgtname, sizeof(tgtname), inode, bindex); + + /* always superio. */ + ndx.nfsmnt = au_do_nfsmnt(br->br_mnt); + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2); + h_dentry = au_sio_lkup_one(tgtname, h_parent, len, &ndx); + mutex_unlock(&h_dir->i_mutex); + return h_dentry; +} + +static int do_whplink(char *tgt, int len, struct dentry *h_parent, + struct dentry *h_dentry, struct vfsmount *nfsmnt, + struct super_block *sb) +{ + int err, dlgt; + struct dentry *h_tgt; + struct inode *h_dir; + struct vfsub_args vargs; + struct au_ndx ndx = { + .nfsmnt = nfsmnt, + .flags = 0, + .nd = NULL, + /* .br = NULL */ + }; + + AuTraceEnter(); + + dlgt = !!au_test_dlgt(au_mntflags(sb)); + if (unlikely(dlgt)) + au_fset_ndx(ndx.flags, DLGT); + h_tgt = au_lkup_one(tgt, h_parent, len, &ndx); + err = PTR_ERR(h_tgt); + if (IS_ERR(h_tgt)) + goto out; + + err = 0; + vfsub_args_init(&vargs, NULL, dlgt, 0); + /* wh.plink dir is not monitored */ + h_dir = h_parent->d_inode; + if (unlikely(h_tgt->d_inode && h_tgt->d_inode != h_dentry->d_inode)) + err = vfsub_unlink(h_dir, h_tgt, &vargs); + if (!err && !h_tgt->d_inode) { + err = vfsub_link(h_dentry, h_dir, h_tgt, &vargs); + /* todo: unnecessary? */ + /* inc_nlink(inode); */ + } + dput(h_tgt); + + out: + AuTraceErr(err); + return err; +} + +struct do_whplink_args { + int *errp; + char *tgt; + int len; + struct dentry *h_parent; + struct dentry *h_dentry; + struct vfsmount *nfsmnt; + struct super_block *sb; +}; + +static void call_do_whplink(void *args) +{ + struct do_whplink_args *a = args; + *a->errp = do_whplink(a->tgt, a->len, a->h_parent, a->h_dentry, + a->nfsmnt, a->sb); +} + +static int whplink(struct dentry *h_dentry, struct inode *inode, + aufs_bindex_t bindex, struct super_block *sb) +{ + int err, len, wkq_err; + struct au_branch *br; + struct au_wbr *wbr; + struct dentry *h_parent; + struct inode *h_dir; + char tgtname[PLINK_NAME_LEN]; + + LKTRTrace("%.*s\n", AuDLNPair(h_dentry)); + br = au_sbr(inode->i_sb, bindex); + wbr = br->br_wbr; + AuDebugOn(!wbr); + h_parent = wbr->wbr_plink; + AuDebugOn(!h_parent); + h_dir = h_parent->d_inode; + AuDebugOn(!h_dir); + + len = plink_name(tgtname, sizeof(tgtname), inode, bindex); + + /* always superio. */ + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2); + if (!au_test_wkq(current)) { + struct do_whplink_args args = { + .errp = &err, + .tgt = tgtname, + .len = len, + .h_parent = h_parent, + .h_dentry = h_dentry, + .nfsmnt = au_do_nfsmnt(br->br_mnt), + .sb = sb + }; + wkq_err = au_wkq_wait(call_do_whplink, &args, /*dlgt*/0); + if (unlikely(wkq_err)) + err = wkq_err; + } else + err = do_whplink(tgtname, len, h_parent, h_dentry, + au_do_nfsmnt(br->br_mnt), sb); + mutex_unlock(&h_dir->i_mutex); + + AuTraceErr(err); + return err; +} + +void au_plink_append(struct super_block *sb, struct inode *inode, + struct dentry *h_dentry, aufs_bindex_t bindex) +{ + struct au_sbinfo *sbinfo; + struct list_head *plink_list; + struct pseudo_link *plink; + int found, err, cnt; + + LKTRTrace("i%lu\n", inode->i_ino); + SiMustAnyLock(sb); + sbinfo = au_sbi(sb); + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); + + cnt = 0; + found = 0; + plink_list = &sbinfo->si_plink; + spin_lock(&sbinfo->si_plink_lock); + list_for_each_entry(plink, plink_list, list) { + cnt++; + if (plink->inode == inode) { + found = 1; + break; + } + } + + err = 0; + if (!found) { + plink = kmalloc(sizeof(*plink), GFP_ATOMIC); + if (plink) { + plink->inode = au_igrab(inode); + list_add(&plink->list, plink_list); + cnt++; + } else + err = -ENOMEM; + } + spin_unlock(&sbinfo->si_plink_lock); + +#if 0 /* todo: test here */ + if (found) + return; /* success */ +#endif + + if (!err) + err = whplink(h_dentry, inode, bindex, sb); + + if (unlikely(cnt > AUFS_PLINK_WARN)) + AuWarn1("unexpectedly many pseudo links, %d\n", cnt); + if (unlikely(err)) + AuWarn("err %d, damaged pseudo link. ignored.\n", err); +} + +static void do_put_plink(struct pseudo_link *plink, int do_del) +{ + AuTraceEnter(); + + iput(plink->inode); + if (do_del) + list_del(&plink->list); + kfree(plink); +} + +void au_plink_put(struct super_block *sb) +{ + struct au_sbinfo *sbinfo; + struct list_head *plink_list; + struct pseudo_link *plink, *tmp; + + AuTraceEnter(); + SiMustWriteLock(sb); + sbinfo = au_sbi(sb); + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); + + plink_list = &sbinfo->si_plink; + /* spin_lock(&sbinfo->si_plink_lock); */ + list_for_each_entry_safe(plink, tmp, plink_list, list) + do_put_plink(plink, 0); + INIT_LIST_HEAD(plink_list); + /* spin_unlock(&sbinfo->si_plink_lock); */ +} + +void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id) +{ + struct au_sbinfo *sbinfo; + struct list_head *plink_list; + struct pseudo_link *plink, *tmp; + struct inode *inode; + aufs_bindex_t bstart, bend, bindex; + int do_put; + + AuTraceEnter(); + SiMustWriteLock(sb); + sbinfo = au_sbi(sb); + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); + + plink_list = &sbinfo->si_plink; + /* spin_lock(&sbinfo->si_plink_lock); */ + list_for_each_entry_safe(plink, tmp, plink_list, list) { + do_put = 0; + inode = au_igrab(plink->inode); + ii_write_lock_child(inode); + bstart = au_ibstart(inode); + bend = au_ibend(inode); + if (bstart >= 0) { + for (bindex = bstart; bindex <= bend; bindex++) { + if (!au_h_iptr(inode, bindex) + || au_ii_br_id(inode, bindex) != br_id) + continue; + au_set_h_iptr(inode, bindex, NULL, 0); + do_put = 1; + break; + } + } else + do_put_plink(plink, 1); + + if (do_put) { + for (bindex = bstart; bindex <= bend; bindex++) + if (au_h_iptr(inode, bindex)) { + do_put = 0; + break; + } + if (do_put) + do_put_plink(plink, 1); + } + ii_write_unlock(inode); + iput(inode); + } + /* spin_unlock(&sbinfo->si_plink_lock); */ +} --- linux-2.6.28.orig/ubuntu/aufs/inode.c +++ linux-2.6.28/ubuntu/aufs/inode.c @@ -0,0 +1,420 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * inode functions + * + * $Id: inode.c,v 1.13 2008/09/22 03:52:19 sfjro Exp $ + */ + +#include "aufs.h" + +int au_refresh_hinode_self(struct inode *inode) +{ + int err, new_sz, update; + struct inode *first; + struct au_hinode *p, *q, tmp; + struct super_block *sb; + struct au_iinfo *iinfo; + aufs_bindex_t bindex, bend, new_bindex; + + LKTRTrace("i%lu\n", inode->i_ino); + IiMustWriteLock(inode); + + err = -ENOMEM; + update = 0; + sb = inode->i_sb; + bend = au_sbend(sb); + new_sz = sizeof(*iinfo->ii_hinode) * (bend + 1); + iinfo = au_ii(inode); + p = au_kzrealloc(iinfo->ii_hinode, sizeof(*p) * (iinfo->ii_bend + 1), + new_sz, GFP_NOFS); + if (unlikely(!p)) + goto out; + + iinfo->ii_hinode = p; + p = iinfo->ii_hinode + iinfo->ii_bstart; + first = p->hi_inode; + err = 0; + for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; + bindex++, p++) { + if (!p->hi_inode) + continue; + + new_bindex = au_br_index(sb, p->hi_id); + if (new_bindex == bindex) + continue; + if (new_bindex < 0) { + update++; + au_hiput(p); + p->hi_inode = NULL; + continue; + } + + if (new_bindex < iinfo->ii_bstart) + iinfo->ii_bstart = new_bindex; + if (iinfo->ii_bend < new_bindex) + iinfo->ii_bend = new_bindex; + /* swap two hidden inode, and loop again */ + q = iinfo->ii_hinode + new_bindex; + tmp = *q; + *q = *p; + *p = tmp; + if (tmp.hi_inode) { + bindex--; + p--; + } + } + au_update_brange(inode, /*do_put_zero*/0); + + if (unlikely(err)) + goto out; + + if (1 || first != au_h_iptr(inode, iinfo->ii_bstart)) + au_cpup_attr_all(inode); + if (update && S_ISDIR(inode->i_mode)) + inode->i_version++; + au_update_iigen(inode); + + out: + AuTraceErr(err); + return err; +} + +int au_refresh_hinode(struct inode *inode, struct dentry *dentry) +{ + int err, update; + struct inode *first; + struct au_hinode *p; + struct super_block *sb; + struct au_iinfo *iinfo; + aufs_bindex_t bindex, bend; + unsigned char isdir; + unsigned int flags; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + IiMustWriteLock(inode); + + err = au_refresh_hinode_self(inode); + if (unlikely(err)) + goto out; + + sb = dentry->d_sb; + bend = au_sbend(sb); + iinfo = au_ii(inode); + update = 0; + p = iinfo->ii_hinode + iinfo->ii_bstart; + first = p->hi_inode; + isdir = S_ISDIR(inode->i_mode); + flags = au_hi_flags(inode, isdir); + bend = au_dbend(dentry); + for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) { + struct inode *hi; + struct dentry *hd; + + hd = au_h_dptr(dentry, bindex); + if (!hd || !hd->d_inode) + continue; + + if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) { + hi = au_h_iptr(inode, bindex); + if (hi) { + if (hi == hd->d_inode) + continue; + err = -ESTALE; + break; + } + } + if (bindex < iinfo->ii_bstart) + iinfo->ii_bstart = bindex; + if (iinfo->ii_bend < bindex) + iinfo->ii_bend = bindex; + au_set_h_iptr(inode, bindex, au_igrab(hd->d_inode), flags); + update++; + } + au_update_brange(inode, /*do_put_zero*/0); + + if (unlikely(err)) + goto out; + + if (1 || first != au_h_iptr(inode, iinfo->ii_bstart)) + au_cpup_attr_all(inode); + if (update && isdir) + inode->i_version++; + au_update_iigen(inode); + + out: + AuTraceErr(err); + return err; +} + +static int set_inode(struct inode *inode, struct dentry *dentry) +{ + int err; + struct dentry *h_dentry; + struct inode *h_inode; + umode_t mode; + aufs_bindex_t bindex, bstart, btail; + unsigned char isdir; + struct au_iinfo *iinfo; + unsigned int flags; + + LKTRTrace("i%lu, %.*s\n", inode->i_ino, AuDLNPair(dentry)); + AuDebugOn(!(inode->i_state & I_NEW)); + IiMustWriteLock(inode); + bstart = au_dbstart(dentry); + h_dentry = au_h_dptr(dentry, bstart); + AuDebugOn(!h_dentry); + h_inode = h_dentry->d_inode; + AuDebugOn(!h_inode); + + err = 0; + isdir = 0; + mode = h_inode->i_mode; + switch (mode & S_IFMT) { + case S_IFREG: + btail = au_dbtail(dentry); + inode->i_op = &aufs_iop; + inode->i_fop = &aufs_file_fop; + inode->i_mapping->a_ops = &aufs_aop; + break; + case S_IFDIR: + isdir = 1; + btail = au_dbtaildir(dentry); + inode->i_op = &aufs_dir_iop; + inode->i_fop = &aufs_dir_fop; + break; + case S_IFLNK: + btail = au_dbtail(dentry); + inode->i_op = &aufs_symlink_iop; + /* inode->i_fop = &aufs_file_fop; */ + break; + case S_IFBLK: + case S_IFCHR: + case S_IFIFO: + case S_IFSOCK: + btail = au_dbtail(dentry); + init_special_inode(inode, mode, + au_h_rdev(h_inode, /*h_mnt*/NULL, h_dentry)); + break; + default: + AuIOErr("Unknown file type 0%o\n", mode); + err = -EIO; + goto out; + } + + /* do not set inotify for whiteouted dirs (SHWH mode) */ + flags = au_hi_flags(inode, isdir); + if (unlikely(au_opt_test(au_mntflags(dentry->d_sb), SHWH) + && au_ftest_hi(flags, NOTIFY) + && dentry->d_name.len > AUFS_WH_PFX_LEN + && !memcmp(dentry->d_name.name, AUFS_WH_PFX, + AUFS_WH_PFX_LEN))) + au_fclr_hi(flags, NOTIFY); + iinfo = au_ii(inode); + iinfo->ii_bstart = bstart; + iinfo->ii_bend = btail; + for (bindex = bstart; bindex <= btail; bindex++) { + h_dentry = au_h_dptr(dentry, bindex); + if (!h_dentry) + continue; + AuDebugOn(!h_dentry->d_inode); + au_set_h_iptr(inode, bindex, au_igrab(h_dentry->d_inode), + flags); + } + au_cpup_attr_all(inode); + + out: + AuTraceErr(err); + return err; +} + +/* successful returns with iinfo write_locked */ +/* todo: return with unlocked? */ +static int reval_inode(struct inode *inode, struct dentry *dentry, int *matched) +{ + int err; + struct inode *h_inode, *h_dinode; + aufs_bindex_t bindex, bend; + + LKTRTrace("i%lu, %.*s\n", inode->i_ino, AuDLNPair(dentry)); + + *matched = 0; + + /* + * before this function, if aufs got any iinfo lock, it must be only + * one, the parent dir. + * it can happen by UDBA and the obsoleted inode number. + */ + err = -EIO; + if (unlikely(inode->i_ino == parent_ino(dentry))) + goto out; + /* todo: test here */ + //AuDebugOn(IS_DEADDIR(inode)); + + err = 0; + h_dinode = au_h_dptr(dentry, au_dbstart(dentry))->d_inode; + /* mutex_lock_nested(&inode->i_mutex, AuLsc_I_CHILD); */ + ii_write_lock_new_child(inode); + bend = au_ibend(inode); + for (bindex = au_ibstart(inode); bindex <= bend; bindex++) { + h_inode = au_h_iptr(inode, bindex); + if (h_inode && h_inode == h_dinode) { + /* && (ibs != bstart + || !au_test_higen(inode, h_inode))); */ + *matched = 1; + err = 0; + if (unlikely(au_iigen(inode) != au_digen(dentry))) + err = au_refresh_hinode(inode, dentry); + break; + } + } + if (unlikely(err)) + ii_write_unlock(inode); + /* mutex_unlock(&inode->i_mutex); */ + + out: + AuTraceErr(err); + return err; +} + +/* successful returns with iinfo write_locked */ +/* todo: return with unlocked? */ +struct inode *au_new_inode(struct dentry *dentry) +{ + struct inode *inode, *h_inode; + struct dentry *h_dentry; + ino_t h_ino; + struct super_block *sb; + int err, match; + aufs_bindex_t bstart; + struct au_xino_entry xinoe; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + sb = dentry->d_sb; + bstart = au_dbstart(dentry); + h_dentry = au_h_dptr(dentry, bstart); + AuDebugOn(!h_dentry); + h_inode = h_dentry->d_inode; + AuDebugOn(!h_inode); + + h_ino = h_inode->i_ino; + err = au_xino_read(sb, bstart, h_ino, &xinoe); + inode = ERR_PTR(err); + if (unlikely(err)) + goto out; + new_ino: + if (!xinoe.ino) { + xinoe.ino = au_xino_new_ino(sb); + if (!xinoe.ino) { + inode = ERR_PTR(-EIO); + goto out; + } + } + + LKTRTrace("i%lu\n", (unsigned long)xinoe.ino); + inode = au_iget_locked(sb, xinoe.ino); + err = PTR_ERR(inode); + if (IS_ERR(inode)) + goto out; + /* todo: test here */ + //AuDebugOn(IS_DEADDIR(inode)); + + LKTRTrace("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW)); + if (inode->i_state & I_NEW) { + ii_write_lock_new_child(inode); + err = set_inode(inode, dentry); + unlock_new_inode(inode); + if (!err) + goto out; /* success */ + iget_failed(inode); + ii_write_unlock(inode); + goto out_iput; + } else { + AuDebugOn(inode->i_state & I_LOCK); + err = reval_inode(inode, dentry, &match); + if (!err) + goto out; /* success */ + else if (match) + goto out_iput; + } + + if (unlikely(au_test_unique_ino(h_dentry, h_ino))) + AuWarn1("Un-notified UDBA or repeatedly renamed dir," + " b%d, %s, %.*s, hi%lu, i%lu.\n", + bstart, au_sbtype(h_dentry->d_sb), AuDLNPair(dentry), + (unsigned long)h_ino, (unsigned long)xinoe.ino); + xinoe.ino = 0; + err = au_xino_write0(sb, bstart, h_ino, 0); + if (!err) { + iput(inode); + goto new_ino; + } + /* force noxino? */ + + out_iput: + iput(inode); + inode = ERR_PTR(err); + out: + AuTraceErrPtr(inode); + return inode; +} + +/* ---------------------------------------------------------------------- */ + +int au_test_ro(struct super_block *sb, aufs_bindex_t bindex, + struct inode *inode) +{ + int err; + + err = au_br_rdonly(au_sbr(sb, bindex)); + + /* pseudo-link after flushed may out of bounds */ + if (!err + && inode + && au_ibstart(inode) <= bindex + && bindex <= au_ibend(inode)) { + /* + * permission check is unnecessary since vfsub routine + * will be called later + */ + struct inode *hi = au_h_iptr(inode, bindex); + if (hi) + err = IS_IMMUTABLE(hi) ? -EROFS : 0; + } + + AuTraceErr(err); + return err; +} + +int au_test_h_perm(struct inode *h_inode, int mask, int dlgt) +{ + if (!current->fsuid) + return 0; + /* todo: fake nameidata? */ + return vfsub_permission(h_inode, mask, NULL, dlgt); +} + +int au_test_h_perm_sio(struct inode *h_inode, int mask, int dlgt) +{ + if (unlikely(au_test_nfs(h_inode->i_sb) + && (mask & MAY_WRITE) + && S_ISDIR(h_inode->i_mode))) + mask |= MAY_READ; /* force permission check */ + return au_test_h_perm(h_inode, mask, dlgt); +} --- linux-2.6.28.orig/ubuntu/aufs/finfo.c +++ linux-2.6.28/ubuntu/aufs/finfo.c @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * file private data + * + * $Id: finfo.c,v 1.4 2008/06/30 03:50:21 sfjro Exp $ + */ + +#include "aufs.h" + +struct au_finfo *au_fi(struct file *file) +{ + struct au_finfo *finfo = file->private_data; + AuDebugOn(!finfo + || !finfo->fi_hfile + || (0 < finfo->fi_bend + && (/* au_sbi(file->f_dentry->d_sb)->si_bend + < finfo->fi_bend + || */ finfo->fi_bend < finfo->fi_bstart))); + return finfo; +} + +struct au_branch *au_fbr(struct file *file, aufs_bindex_t bindex) +{ + struct au_finfo *finfo = au_fi(file); + struct au_hfile *hf; + + FiMustAnyLock(file); + AuDebugOn(!finfo + || finfo->fi_bstart < 0 + || bindex < finfo->fi_bstart + || finfo->fi_bend < bindex); + hf = finfo->fi_hfile + bindex; + AuDebugOn(hf->hf_br && au_br_count(hf->hf_br) <= 0); + return hf->hf_br; +} + +struct file *au_h_fptr(struct file *file, aufs_bindex_t bindex) +{ + struct au_finfo *finfo = au_fi(file); + struct au_hfile *hf; + + FiMustAnyLock(file); + AuDebugOn(!finfo + || finfo->fi_bstart < 0 + || bindex < finfo->fi_bstart + || finfo->fi_bend < bindex); + hf = finfo->fi_hfile + bindex; + AuDebugOn(hf->hf_file + && file_count(hf->hf_file) <= 0 + && au_br_count(hf->hf_br) <= 0); + return hf->hf_file; +} + +void au_hfput(struct au_hfile *hf) +{ + if (hf->hf_file->f_mode & FMODE_EXEC) + au_allow_write_access(hf->hf_file); + fput(hf->hf_file); + hf->hf_file = NULL; + AuDebugOn(!hf->hf_br); + au_br_put(hf->hf_br); + hf->hf_br = NULL; +} + +void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val) +{ + struct au_finfo *finfo = au_fi(file); + struct au_hfile *hf; + + FiMustWriteLock(file); + AuDebugOn(!finfo + || finfo->fi_bstart < 0 + || bindex < finfo->fi_bstart + || finfo->fi_bend < bindex); + AuDebugOn(val && file_count(val) <= 0); + hf = finfo->fi_hfile + bindex; + AuDebugOn(val && hf->hf_file); + if (hf->hf_file) + au_hfput(hf); + if (val) { + hf->hf_file = val; + hf->hf_br = au_sbr(file->f_dentry->d_sb, bindex); + } +} + +void au_finfo_fin(struct file *file) +{ + struct au_finfo *finfo; + struct dentry *dentry; + aufs_bindex_t bindex, bend; + + dentry = file->f_dentry; + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + SiMustAnyLock(dentry->d_sb); + + fi_write_lock(file); + bend = au_fbend(file); + bindex = au_fbstart(file); + if (bindex >= 0) + for (; bindex <= bend; bindex++) + au_set_h_fptr(file, bindex, NULL); + + finfo = au_fi(file); +#ifdef CONFIG_AUFS_DEBUG + if (finfo->fi_bstart >= 0) { + bend = au_fbend(file); + for (bindex = finfo->fi_bstart; bindex <= bend; bindex++) { + struct au_hfile *hf; + hf = finfo->fi_hfile + bindex; + AuDebugOn(hf->hf_file || hf->hf_br); + } + } +#endif + + kfree(finfo->fi_hfile); + fi_write_unlock(file); + au_cache_free_finfo(finfo); +} + +int au_finfo_init(struct file *file) +{ + struct au_finfo *finfo; + struct dentry *dentry; + union { + void *p; + unsigned long ul; + } u; + + dentry = file->f_dentry; + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + AuDebugOn(!dentry->d_inode); + + finfo = au_cache_alloc_finfo(); + if (finfo) { + finfo->fi_hfile = kcalloc(au_sbend(dentry->d_sb) + 1, + sizeof(*finfo->fi_hfile), GFP_NOFS); + if (finfo->fi_hfile) { + au_rw_init_wlock(&finfo->fi_rwsem); + finfo->fi_bstart = -1; + finfo->fi_bend = -1; + atomic_set(&finfo->fi_generation, au_digen(dentry)); + /* smp_mb(); */ /* atomic_set */ + + /* + * a dirty trick for handling FMODE_EXEC and + * deny_write_access(). + * because FMODE_EXEC flag is not passed to + * f_op->open(), + * aufs set it to file->private_data temporary in lookup + * or dentry revalidation operations. + * restore the flag to f_mode here. + */ + u.p = file->private_data; + if (u.ul & FMODE_EXEC) { + file->f_mode |= FMODE_EXEC; + smp_mb(); /* flush f_mode */ + } + + file->private_data = finfo; + return 0; /* success */ + } + au_cache_free_finfo(finfo); + } + + AuTraceErr(-ENOMEM); + return -ENOMEM; +} --- linux-2.6.28.orig/ubuntu/aufs/opts.h +++ linux-2.6.28/ubuntu/aufs/opts.h @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * mount options/flags + * + * $Id: opts.h,v 1.6 2008/08/17 23:03:27 sfjro Exp $ + */ + +#ifndef __AUFS_OPTS_H__ +#define __AUFS_OPTS_H__ + +#ifdef __KERNEL__ + +#include +#include +#include +#include "wkq.h" + +/* ---------------------------------------------------------------------- */ +/* mount flags */ + +/* external inode number bitmap and translation table */ +#define AuOpt_XINO 1 +#define AuOpt_XINODIR (1 << 1) +#define AuOpt_TRUNC_XINO (1 << 2) +#define AuOpt_UDBA_NONE (1 << 3) /* users direct branch access */ +#define AuOpt_UDBA_REVAL (1 << 4) +#define AuOpt_UDBA_INOTIFY (1 << 5) +#define AuOpt_SHWH (1 << 6) +#define AuOpt_PLINK (1 << 7) +#define AuOpt_WARN_PERM (1 << 8) +#define AuOpt_DIRPERM1 (1 << 9) +#define AuOpt_DLGT (1 << 10) +#define AuOpt_COO_NONE (1 << 11) /* copyup on open */ +#define AuOpt_COO_LEAF (1 << 12) +#define AuOpt_COO_ALL (1 << 13) +#define AuOpt_ALWAYS_DIROPQ (1 << 14) +#define AuOpt_REFROF (1 << 15) +#define AuOpt_VERBOSE (1 << 16) + +#if 1 /* ndef CONFIG_AUFS_EXPORT */ /* reserved for future use */ +#undef AuOpt_XINODIR +#define AuOpt_XINODIR 0 +#endif +#ifndef CONFIG_AUFS_HINOTIFY +#undef AuOpt_UDBA_INOTIFY +#define AuOpt_UDBA_INOTIFY 0 +#endif +#ifndef CONFIG_AUFS_SHWH +#undef AuOpt_SHWH +#define AuOpt_SHWH 0 +#endif +#ifndef CONFIG_AUFS_DLGT +#undef AuOpt_DIRPERM1 +#define AuOpt_DIRPERM1 0 +#undef AuOpt_DLGT +#define AuOpt_DLGT 0 +#endif + +/* policies to select one among multiple writable branches */ +enum { + AuWbrCreate_TDP, /* top down parent */ + AuWbrCreate_RR, /* round robin */ + AuWbrCreate_MFS, /* most free space */ + AuWbrCreate_MFSV, /* mfs with seconds */ + AuWbrCreate_MFSRR, /* mfs then rr */ + AuWbrCreate_MFSRRV, /* mfs then rr with seconds */ + AuWbrCreate_PMFS, /* parent and mfs */ + AuWbrCreate_PMFSV, /* parent and mfs with seconds */ + + AuWbrCreate_Def = AuWbrCreate_TDP +}; + +enum { + AuWbrCopyup_TDP, /* top down parent */ + AuWbrCopyup_BUP, /* bottom up parent */ + AuWbrCopyup_BU, /* bottom up */ + + AuWbrCopyup_Def = AuWbrCopyup_TDP +}; + +#define AuOptMask_COO (AuOpt_COO_NONE \ + | AuOpt_COO_LEAF \ + | AuOpt_COO_ALL) +#define AuOptMask_UDBA (AuOpt_UDBA_NONE \ + | AuOpt_UDBA_REVAL \ + | AuOpt_UDBA_INOTIFY) + +#ifdef CONFIG_AUFS_COMPAT +#define AuOpt_DefExtra1 AuOpt_ALWAYS_DIROPQ +#else +#define AuOpt_DefExtra1 0 +#endif + +#define AuOpt_Def (AuOpt_XINO \ + | AuOpt_UDBA_REVAL \ + | AuOpt_WARN_PERM \ + | AuOpt_COO_NONE \ + | AuOpt_PLINK \ + | AuOpt_DefExtra1) + +/* ---------------------------------------------------------------------- */ + +struct au_opt_add { + aufs_bindex_t bindex; + char *path; + int perm; + struct nameidata nd; +}; + +struct au_opt_del { + char *path; + struct dentry *h_root; +}; + +struct au_opt_mod { + char *path; + int perm; + struct dentry *h_root; +}; + +struct au_opt_xino { + char *path; + struct file *file; +}; + +struct au_opt_xinodir { + char *name; + struct path path; +}; + +struct au_opt_xino_itrunc { + aufs_bindex_t bindex; +}; + +struct au_opt_xino_trunc_v { + unsigned long long upper; + int step; +}; + +struct au_opt_wbr_create { + int wbr_create; + int mfs_second; + unsigned long long mfsrr_watermark; +}; + +struct au_opt { + int type; + union { + struct au_opt_xino xino; + struct au_opt_xinodir xinodir; + struct au_opt_xino_itrunc xino_itrunc; + struct au_opt_add add; + struct au_opt_del del; + struct au_opt_mod mod; + int dirwh; + int rdcache; + int deblk; + int nhash; + int udba; + int coo; + struct au_opt_wbr_create wbr_create; + int wbr_copyup; + }; +}; + +/* opts flags */ +#define AuOpts_REMOUNT 1 +#define AuOpts_REFRESH_DIR (1 << 1) +#define AuOpts_REFRESH_NONDIR (1 << 2) +#define AuOpts_TRUNC_XIB (1 << 3) +#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name) +#define au_fset_opts(flags, name) { (flags) |= AuOpts_##name; } +#define au_fclr_opts(flags, name) { (flags) &= ~AuOpts_##name; } + +struct au_opts { + struct au_opt *opt; + int max_opt; + + unsigned int given_udba; + unsigned int flags; +}; + +/* ---------------------------------------------------------------------- */ + +const char *au_optstr_br_perm(int brperm); +const char *au_optstr_udba(int udba); +const char *au_optstr_coo(int coo); +const char *au_optstr_wbr_copyup(int wbr_copyup); +const char *au_optstr_wbr_create(int wbr_create); + +void au_opts_free(struct au_opts *opts); +int au_opts_parse(struct super_block *sb, unsigned long flags, char *str, + struct au_opts *opts); +int au_opts_mount(struct super_block *sb, struct au_opts *opts); +int au_opts_remount(struct super_block *sb, struct au_opts *opts); + +/* ---------------------------------------------------------------------- */ + +#define au_opt_test(flags, name) (flags & AuOpt_##name) + +static inline int au_opt_test_xino(unsigned int flags) +{ + return (flags & (AuOpt_XINO | AuOpt_XINODIR)); +} + +#define au_opt_set(flags, name) do { \ + BUILD_BUG_ON(AuOpt_##name & (AuOptMask_COO | AuOptMask_UDBA)); \ + ((flags) |= AuOpt_##name); \ +} while (0) + +#define au_opt_set_coo(flags, name) do { \ + (flags) &= ~AuOptMask_COO; \ + ((flags) |= AuOpt_##name); \ +} while (0) + +#define au_opt_set_udba(flags, name) do { \ + (flags) &= ~AuOptMask_UDBA; \ + ((flags) |= AuOpt_##name); \ +} while (0) + +#define au_opt_clr(flags, name) { ((flags) &= ~AuOpt_##name); } + +static inline int au_test_dlgt(unsigned int flags) +{ + return (au_opt_test(flags, DLGT) && !au_test_wkq(current)); +} + +static inline int au_test_dirperm1(unsigned int flags) +{ + return (au_opt_test(flags, DIRPERM1) && !au_test_wkq(current)); +} + +#endif /* __KERNEL__ */ +#endif /* __AUFS_OPTS_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/Makefile +++ linux-2.6.28/ubuntu/aufs/Makefile @@ -0,0 +1,74 @@ +# AUFS Makefile for the Linux 2.6.25 and later +# $Id: Makefile,v 1.8 2008/08/04 00:32:21 sfjro Exp $ + +# the environment variables are not inherited since 2.6.23 +ifdef AUFS_EXTRA_CFLAGS +ccflags-y += ${AUFS_EXTRA_CFLAGS} +endif + +######################################## + +ifdef CONFIG_AUFS_RR_SQUASHFS +# cf. squashfs3.2-r2 and sqlzma patch. +ccflags-y += -DSQUASHFS_MAGIC=0x73717368 +ccflags-y += -DSQUASHFS_MAGIC_SWAP=0x68737173 +ccflags-y += -DSQUASHFS_MAGIC_LZMA=0x71736873 +ccflags-y += -DSQUASHFS_MAGIC_LZMA_SWAP=0x73687371 +endif + +# defined in ${srctree}/fs/fuse/inode.c +ccflags-$(CONFIG_AUFS_WORKAROUND_FUSE) += -DFUSE_SUPER_MAGIC=0x65735546 + +# defined in ${srctree}/fs/xfs/xfs_sb.h +# tristate +ifdef CONFIG_XFS_FS +ccflags-y += -DXFS_SB_MAGIC=0x58465342 +endif + +# defined in ${srctree}/mm/shmem.c in linux-2.6.26 and earlier +# tristate +ifdef CONFIG_TMPFS +ccflags-y += -DTMPFS_MAGIC=0x01021994 +endif + +# defined in ${srctree}fs/sysfs/mount.c +# bool +ccflags-$(CONFIG_SYSFS) += -DSYSFS_MAGIC=0x62656572 + +ifndef EXTRAVERSION +EXTRAVERSION = $(shell echo ${KERNELVERSION} | cut -f3- -d. | cut -f2- -d-) +endif +# for -mm tree, support the latest version only +ifneq ($(strip $(shell echo ${EXTRAVERSION} | fgrep -- mm)),) +ccflags-y += -DCONFIG_AUFS_UNIONFS22_PATCH -DCONFIG_AUFS_UNIONFS23_PATCH +endif + +-include $(dir $(lastword ${MAKEFILE_LIST}))priv.mk +#$(warning ${ccflags-y}) + +######################################## + +obj-$(CONFIG_AUFS) += aufs.o +aufs-y := module.o super.o sbinfo.o branch.o xino.o sysaufs.o opts.o \ + wkq.o vfsub.o dcsub.o \ + cpup.o whout.o plink.o wbr_policy.o \ + dentry.o dinfo.o \ + file.o f_op.o finfo.o \ + dir.o vdir.o \ + inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o iinfo.o \ + misc.o + +aufs-$(CONFIG_SYSFS) += sysfs.o +aufs-$(CONFIG_AUFS_BR_NFS) += br_nfs.o +aufs-$(CONFIG_AUFS_BR_XFS) += br_xfs.o +aufs-$(CONFIG_AUFS_WORKAROUND_FUSE) += br_fuse.o +aufs-$(CONFIG_AUFS_DLGT) += dlgt.o +aufs-$(CONFIG_AUFS_HINOTIFY) += hinotify.o +aufs-$(CONFIG_AUFS_HIN_OR_DLGT) += hin_or_dlgt.o +aufs-$(CONFIG_AUFS_HIN_OR_FUSE) += hin_or_fuse.o +aufs-$(CONFIG_AUFS_EXPORT) += export.o +aufs-$(CONFIG_AUFS_ROBR) += robr.o +# reserved for future use +#aufs-$(CONFIG_AUFS_XATTR) += xattr.o +aufs-$(CONFIG_AUFS_DEBUG) += debug.o +aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o --- linux-2.6.28.orig/ubuntu/aufs/hin_or_fuse.c +++ linux-2.6.28/ubuntu/aufs/hin_or_fuse.c @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * inode attributes on FUSE branch or HINOTIFY + * + * $Id: hin_or_fuse.c,v 1.6 2008/09/15 03:14:30 sfjro Exp $ + */ + +#include "aufs.h" + +static struct dentry * +au_h_dget_any(struct dentry *dentry, aufs_bindex_t *bindex) +{ + struct dentry *h_dentry; + struct inode *inode, *h_inode; + struct super_block *sb; + aufs_bindex_t ib, db; + + /* must be positive dentry */ + inode = dentry->d_inode; + LKTRTrace("%.*s, i%lu\n", AuDLNPair(dentry), inode->i_ino); + + sb = dentry->d_sb; + db = au_dbstart(dentry); + ib = au_ibstart(inode); + if (db == ib) { + *bindex = db; + h_dentry = dget(au_h_dptr(dentry, db)); + if (h_dentry) + goto out; /* success */ + } + + *bindex = ib; + h_inode = au_h_iptr(inode, ib); + h_dentry = d_find_alias(h_inode); + if (h_dentry) + goto out; /* success */ + +#if 0 + if (au_opt_test(au_mntflags(sb), PLINK) + && au_plink_test(sb, inode)) { + h_dentry = au_plink_lkup(sb, ib, inode); + if (IS_ERR(h_dentry)) + goto out; + AuDebugOn(!h_dentry->d_inode); + goto out; /* success */ + } +#endif + + h_dentry = dget(au_hi_wh(inode, ib)); + + out: + AuTraceErrPtr(h_dentry); + return h_dentry; +} + +int aufs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *st) +{ + int err; + unsigned int mnt_flags; + aufs_bindex_t bindex; + struct inode *inode; + struct dentry *h_dentry; + struct super_block *sb, *h_sb; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + + err = 0; + inode = dentry->d_inode; + sb = dentry->d_sb; + aufs_read_lock(dentry, AuLock_FLUSH | AuLock_IR); + + /* todo: nfs branch too? */ + /* todo: test bit inotify option too? */ + mnt_flags = au_mntflags(sb); + bindex = au_ibstart(inode); + h_sb = au_sbr_sb(sb, bindex); + if (!au_test_fuse(h_sb) + //&& !au_test_nfs(h_sb) /* todo: fix me */ + && (au_iigen(inode) == au_sigen(sb) + || (au_opt_test(mnt_flags, PLINK) && au_plink_test(sb, inode)))) + goto fill; + + h_dentry = au_h_dget_any(dentry, &bindex); + err = PTR_ERR(h_dentry); + if (IS_ERR(h_dentry)) + goto out; + + err = -EIO; + if (h_dentry && h_dentry->d_inode) + err = vfsub_getattr(au_sbr_mnt(sb, bindex), h_dentry, st, + au_test_dlgt(mnt_flags)); + dput(h_dentry); + if (!err) { + au_cpup_attr_all(inode); + fill: + generic_fillattr(inode, st); + } + + out: + aufs_read_unlock(dentry, AuLock_IR); + AuTraceErr(err); + return err; +} --- linux-2.6.28.orig/ubuntu/aufs/sysaufs.h +++ linux-2.6.28/ubuntu/aufs/sysaufs.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * sysfs interface and lifetime management + * + * $Id: sysaufs.h,v 1.11 2008/09/15 03:14:55 sfjro Exp $ + */ + +#ifndef __SYSAUFS_H__ +#define __SYSAUFS_H__ + +#ifdef __KERNEL__ + +#include +#include +#include "module.h" +#include "super.h" + +#define SysaufsSb_PREFIX "si_" /* followed by %p */ + +struct au_sbi_attr { + struct attribute attr; + int (*show)(struct seq_file *seq, struct super_block *sb); +}; + +/* ---------------------------------------------------------------------- */ + +/* sysaufs.c */ +extern unsigned long au_si_mask; +extern struct kset *au_kset; +extern struct attribute *au_sbi_attrs[]; +int sysaufs_si_init(struct au_sbinfo *sbinfo); +int __init sysaufs_init(void); +void sysaufs_fin(void); + +/* ---------------------------------------------------------------------- */ + +struct au_branch; +#ifdef CONFIG_SYSFS +/* sysfs.c */ +extern struct attribute_group *au_attr_group; +extern struct kobj_type *au_ktype; + +int sysaufs_sbi_xino(struct seq_file *seq, struct super_block *sb); +#ifdef CONFIG_AUFS_EXPORT +int sysaufs_sbi_xigen(struct seq_file *seq, struct super_block *sb); +#endif +int sysaufs_sbi_mntpnt1(struct seq_file *seq, struct super_block *sb); +ssize_t sysaufs_sbi_show(struct kobject *kobj, struct attribute *attr, + char *buf); + +void sysaufs_br_init(struct au_branch *br); +void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex); +void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex); +#else +#define au_attr_group NULL +#define au_ktype NULL + +static inline +int sysaufs_sbi_xino(struct seq_file *seq, struct super_block *sb) +{ + return 0; +} + +#ifdef CONFIG_AUFS_EXPORT +static inline +int sysaufs_sbi_xigen(struct seq_file *seq, struct super_block *sb) +{ + return 0; +} +#endif + +static inline +int sysaufs_sbi_mntpnt1(struct seq_file *seq, struct super_block *sb) +{ + return 0; +} + +static inline +ssize_t sysaufs_sbi_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + return 0; +} + +static inline void sysaufs_br_init(struct au_branch *br) +{ + /* empty */ +} + +static inline void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex) +{ + /* nothing */ +} + +static inline void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex) +{ + /* nothing */ +} +#endif /* CONFIG_SYSFS */ + +#endif /* __KERNEL__ */ +#endif /* __SYSAUFS_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/vdir.c +++ linux-2.6.28/ubuntu/aufs/vdir.c @@ -0,0 +1,941 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * virtual or vertical directory + * + * $Id: vdir.c,v 1.11 2008/09/22 03:52:19 sfjro Exp $ + */ + +#include "aufs.h" + +static int calc_size(int namelen) +{ + int sz; + + sz = sizeof(struct au_vdir_de) + namelen; + if (sizeof(ino_t) == sizeof(long)) { + const int mask = sizeof(ino_t) - 1; + if (sz & mask) { + sz += sizeof(ino_t); + sz &= ~mask; + } + } + + AuDebugOn(sz % sizeof(ino_t)); + return sz; +} + +static int set_deblk_end(union au_vdir_deblk_p *p, + union au_vdir_deblk_p *deblk_end) +{ + if (calc_size(0) <= deblk_end->p - p->p) { + p->de->de_str.len = 0; + /* smp_mb(); */ + return 0; + } + return -1; /* error */ +} + +/* returns true or false */ +static int is_deblk_end(union au_vdir_deblk_p *p, + union au_vdir_deblk_p *deblk_end) +{ + if (calc_size(0) <= deblk_end->p - p->p) + return !p->de->de_str.len; + return 1; +} + +static au_vdir_deblk_t *last_deblk(struct au_vdir *vdir) +{ + return vdir->vd_deblk[vdir->vd_nblk - 1]; +} + +void au_nhash_init(struct au_nhash *nhash) +{ + int i; + for (i = 0; i < AuSize_NHASH; i++) + INIT_HLIST_HEAD(nhash->heads + i); +} + +struct au_nhash *au_nhash_new(gfp_t gfp) +{ + struct au_nhash *nhash; + + nhash = kmalloc(sizeof(*nhash), gfp); + if (nhash) { + au_nhash_init(nhash); + return nhash; + } + return ERR_PTR(-ENOMEM); +} + +void au_nhash_del(struct au_nhash *nhash) +{ + au_nhash_fin(nhash); + kfree(nhash); +} + +void au_nhash_move(struct au_nhash *dst, struct au_nhash *src) +{ + int i; + + AuTraceEnter(); + + *dst = *src; + for (i = 0; i < AuSize_NHASH; i++) { + struct hlist_head *h; + h = dst->heads + i; + if (h->first) + h->first->pprev = &h->first; + INIT_HLIST_HEAD(src->heads + i); + } + /* smp_mb(); */ +} + +/* ---------------------------------------------------------------------- */ + +void au_nhash_fin(struct au_nhash *whlist) +{ + int i; + struct hlist_head *head; + struct au_vdir_wh *tpos; + struct hlist_node *pos, *n; + + AuTraceEnter(); + + for (i = 0; i < AuSize_NHASH; i++) { + head = whlist->heads + i; + hlist_for_each_entry_safe(tpos, pos, n, head, wh_hash) { + /* hlist_del(pos); */ + kfree(tpos); + } + } +} + +int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt, + int limit) +{ + int n, i; + struct hlist_head *head; + struct au_vdir_wh *tpos; + struct hlist_node *pos; + + LKTRTrace("limit %d\n", limit); + + n = 0; + for (i = 0; i < AuSize_NHASH; i++) { + head = whlist->heads + i; + hlist_for_each_entry(tpos, pos, head, wh_hash) + if (tpos->wh_bindex == btgt && ++n > limit) + return 1; + } + return 0; +} + +static unsigned int au_name_hash(const unsigned char *name, unsigned int len) +{ + return (full_name_hash(name, len) % AuSize_NHASH); +} + +/* returns found(true) or not */ +int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int namelen) +{ + struct hlist_head *head; + struct au_vdir_wh *tpos; + struct hlist_node *pos; + struct au_vdir_destr *str; + + LKTRTrace("%.*s\n", namelen, name); + + head = whlist->heads + au_name_hash(name, namelen); + hlist_for_each_entry(tpos, pos, head, wh_hash) { + str = &tpos->wh_str; + LKTRTrace("%.*s\n", str->len, str->name); + if (str->len == namelen && !memcmp(str->name, name, namelen)) + return 1; + } + return 0; +} + +int au_nhash_append_wh(struct au_nhash *whlist, char *name, int namelen, + ino_t ino, unsigned int d_type, aufs_bindex_t bindex, + unsigned char shwh) +{ + int err; + struct au_vdir_destr *str; + struct au_vdir_wh *wh; + + LKTRTrace("%.*s\n", namelen, name); + + err = -ENOMEM; + wh = kmalloc(sizeof(*wh) + namelen, GFP_NOFS); + if (unlikely(!wh)) + goto out; + err = 0; + wh->wh_bindex = bindex; + if (unlikely(shwh)) + au_shwh_init_wh(wh, ino, d_type); + str = &wh->wh_str; + str->len = namelen; + memcpy(str->name, name, namelen); + hlist_add_head(&wh->wh_hash, + whlist->heads + au_name_hash(name, namelen)); + /* smp_mb(); */ + + out: + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +void au_vdir_free(struct au_vdir *vdir) +{ + au_vdir_deblk_t **deblk; + + AuTraceEnter(); + + deblk = vdir->vd_deblk; + while (vdir->vd_nblk--) { + kfree(*deblk); + deblk++; + } + kfree(vdir->vd_deblk); + au_cache_free_vdir(vdir); +} + +static int append_deblk(struct au_vdir *vdir) +{ + int err, sz, i; + au_vdir_deblk_t **o; + union au_vdir_deblk_p p, deblk_end; + + AuTraceEnter(); + + err = -ENOMEM; + sz = sizeof(*o) * vdir->vd_nblk; + o = au_kzrealloc(vdir->vd_deblk, sz, sz + sizeof(*o), GFP_NOFS); + if (unlikely(!o)) + goto out; + vdir->vd_deblk = o; + p.deblk = kmalloc(sizeof(*p.deblk), GFP_NOFS); + if (p.deblk) { + i = vdir->vd_nblk++; + vdir->vd_deblk[i] = p.deblk; + vdir->vd_last.i = i; + vdir->vd_last.p.p = p.p; + deblk_end.deblk = p.deblk + 1; + err = set_deblk_end(&p, &deblk_end); + AuDebugOn(err); + } + + out: + AuTraceErr(err); + return err; +} + +static struct au_vdir *alloc_vdir(void) +{ + struct au_vdir *vdir; + int err; + + AuTraceEnter(); + + err = -ENOMEM; + vdir = au_cache_alloc_vdir(); + if (unlikely(!vdir)) + goto out; + vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS); + if (unlikely(!vdir->vd_deblk)) + goto out_free; + + vdir->vd_nblk = 0; + vdir->vd_version = 0; + vdir->vd_jiffy = 0; + err = append_deblk(vdir); + if (!err) + return vdir; /* success */ + + kfree(vdir->vd_deblk); + + out_free: + au_cache_free_vdir(vdir); + out: + vdir = ERR_PTR(err); + AuTraceErrPtr(vdir); + return vdir; +} + +static int reinit_vdir(struct au_vdir *vdir) +{ + int err; + union au_vdir_deblk_p p, deblk_end; + + AuTraceEnter(); + + while (vdir->vd_nblk > 1) { + kfree(vdir->vd_deblk[vdir->vd_nblk - 1]); + vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; + vdir->vd_nblk--; + } + p.deblk = vdir->vd_deblk[0]; + deblk_end.deblk = p.deblk + 1; + err = set_deblk_end(&p, &deblk_end); + AuDebugOn(err); + vdir->vd_version = 0; + vdir->vd_jiffy = 0; + vdir->vd_last.i = 0; + vdir->vd_last.p.deblk = vdir->vd_deblk[0]; + /* smp_mb(); */ + return err; +} + +/* ---------------------------------------------------------------------- */ + +static void free_dehlist(struct au_nhash *dehlist) +{ + int i; + struct hlist_head *head; + struct au_vdir_dehstr *tpos; + struct hlist_node *pos, *n; + + AuTraceEnter(); + + for (i = 0; i < AuSize_NHASH; i++) { + head = dehlist->heads + i; + hlist_for_each_entry_safe(tpos, pos, n, head, hash) { + /* hlist_del(pos); */ + au_cache_free_dehstr(tpos); + } + } +} + +/* returns found(true) or not */ +static int test_known(struct au_nhash *delist, char *name, int namelen) +{ + struct hlist_head *head; + struct au_vdir_dehstr *tpos; + struct hlist_node *pos; + struct au_vdir_destr *str; + + LKTRTrace("%.*s\n", namelen, name); + + head = delist->heads + au_name_hash(name, namelen); + hlist_for_each_entry(tpos, pos, head, hash) { + str = tpos->str; + LKTRTrace("%.*s\n", str->len, str->name); + if (str->len == namelen && !memcmp(str->name, name, namelen)) + return 1; + } + return 0; + +} + +static int append_de(struct au_vdir *vdir, char *name, int namelen, ino_t ino, + unsigned int d_type, struct au_nhash *delist) +{ + int err, sz; + union au_vdir_deblk_p p, *room, deblk_end; + struct au_vdir_dehstr *dehstr; + + LKTRTrace("%.*s %d, i%lu, dt%u\n", + namelen, name, namelen, (unsigned long)ino, d_type); + + p.deblk = last_deblk(vdir); + deblk_end.deblk = p.deblk + 1; + room = &vdir->vd_last.p; + AuDebugOn(room->p < p.p || deblk_end.p <= room->p + || !is_deblk_end(room, &deblk_end)); + + sz = calc_size(namelen); + if (unlikely(sz > deblk_end.p - room->p)) { + err = append_deblk(vdir); + if (unlikely(err)) + goto out; + p.deblk = last_deblk(vdir); + deblk_end.deblk = p.deblk + 1; + /* smp_mb(); */ + AuDebugOn(room->p != p.p); + } + + err = -ENOMEM; + dehstr = au_cache_alloc_dehstr(); + if (unlikely(!dehstr)) + goto out; + dehstr->str = &room->de->de_str; + hlist_add_head(&dehstr->hash, + delist->heads + au_name_hash(name, namelen)); + + room->de->de_ino = ino; + room->de->de_type = d_type; + room->de->de_str.len = namelen; + memcpy(room->de->de_str.name, name, namelen); + + err = 0; + room->p += sz; + if (unlikely(set_deblk_end(room, &deblk_end))) + err = append_deblk(vdir); + /* smp_mb(); */ + + out: + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, + unsigned int d_type, ino_t *ino) +{ + int err; + struct au_xino_entry xinoe; + struct mutex *mtx; + const int isdir = (d_type == DT_DIR); + + /* prevent hardlinks from race condition */ + mtx = NULL; + if (!isdir) { + mtx = &au_sbr(sb, bindex)->br_xino.xi_nondir_mtx; + mutex_lock(mtx); + } + err = au_xino_read(sb, bindex, h_ino, &xinoe); + if (unlikely(err)) + goto out; + + if (!xinoe.ino) { + err = -EIO; + xinoe.ino = au_xino_new_ino(sb); + if (unlikely(!xinoe.ino)) + goto out; + +#if 0 /* reserved for future use */ + struct inode *h_inode; + xinoe.h_gen = AuXino_INVALID_HGEN; + h_inode = ilookup(au_sbr_sb(sb, bindex), h_ino); + if (h_inode) { + if (!is_bad_inode(h_inode)) { + xinoe.h_gen = h_inode->i_generation; + WARN_ON(xinoe.h_gen == AuXino_INVALID_HGEN); + } + iput(h_inode); + } +#endif + err = au_xino_write(sb, bindex, h_ino, &xinoe); + if (unlikely(err)) + goto out; + } + + *ino = xinoe.ino; + + out: + if (!isdir) + mutex_unlock(mtx); + AuTraceErr(err); + return err; +} + +static int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, + unsigned int d_type, ino_t *ino) +{ +#ifdef CONFIG_AUFS_SHWH + return au_ino(sb, bindex, h_ino, d_type, ino); +#else + return 0; +#endif +} + +#define AuFillVdir_CALLED 1 +#define AuFillVdir_SHWH (1 << 1) +#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name) +#define au_fset_fillvdir(flags, name) { (flags) |= AuFillVdir_##name; } +#define au_fclr_fillvdir(flags, name) { (flags) &= ~AuFillVdir_##name; } +#ifndef CONFIG_AUFS_SHWH +#undef AuFillVdir_SHWH +#define AuFillVdir_SHWH 0 +#endif + +struct fillvdir_arg { + struct file *file; + struct au_vdir *vdir; + struct au_nhash *delist; + struct au_nhash *whlist; + aufs_bindex_t bindex; + unsigned int flags; + int err; +}; + +static int fillvdir(void *__arg, const char *__name, int namelen, loff_t offset, + u64 h_ino, unsigned int d_type) +{ + struct fillvdir_arg *arg = __arg; + char *name = (void *)__name; + aufs_bindex_t bindex, bend; + struct super_block *sb; + ino_t ino; + + LKTRTrace("%.*s, namelen %d, i%llu, dt%u\n", + namelen, name, namelen, (unsigned long long)h_ino, d_type); + + sb = arg->file->f_dentry->d_sb; + bend = arg->bindex; + arg->err = 0; + au_fset_fillvdir(arg->flags, CALLED); + /* smp_mb(); */ + if (namelen <= AUFS_WH_PFX_LEN + || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { + for (bindex = 0; bindex < bend; bindex++) + if (test_known(arg->delist + bindex, name, namelen) + || au_nhash_test_known_wh(arg->whlist + bindex, + name, namelen)) + goto out; /* already exists or whiteouted */ + + ino = 1; /* why does gcc warns? */ + arg->err = au_ino(sb, bend, h_ino, d_type, &ino); + if (!arg->err) + arg->err = append_de(arg->vdir, name, namelen, ino, + d_type, arg->delist + bend); + } else { + name += AUFS_WH_PFX_LEN; + namelen -= AUFS_WH_PFX_LEN; + for (bindex = 0; bindex < bend; bindex++) + if (au_nhash_test_known_wh(arg->whlist + bend, name, + namelen)) + goto out; /* already whiteouted */ + + ino = 1; /* dummy */ + if (unlikely(au_ftest_fillvdir(arg->flags, SHWH))) + arg->err = au_wh_ino(sb, bend, h_ino, d_type, &ino); + if (!arg->err) + arg->err = au_nhash_append_wh + (arg->whlist + bend, name, namelen, ino, d_type, + bend, au_ftest_fillvdir(arg->flags, SHWH)); + } + + out: + if (!arg->err) + arg->vdir->vd_jiffy = jiffies; + /* smp_mb(); */ + AuTraceErr(arg->err); + return arg->err; +} + +static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir, + aufs_bindex_t bstart, aufs_bindex_t bend, + struct au_nhash *_whlist, struct au_nhash *_delist) +{ +#ifdef CONFIG_AUFS_SHWH + int err, i; + struct hlist_head *head; + struct au_vdir_wh *tpos; + struct hlist_node *pos, *n; + char *p, *o; + struct au_nhash *whlist, *delist; + struct au_vdir_destr *destr; + aufs_bindex_t bindex; + + AuTraceEnter(); + AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH)); + + err = -ENOMEM; + o = p = __getname(); + if (unlikely(!p)) + goto out; + + err = 0; + memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); + p += AUFS_WH_PFX_LEN; + for (bindex = bstart; !err && bindex <= bend; bindex++) { + whlist = _whlist + bindex; + delist = _delist + bindex; + + for (i = 0; i < AuSize_NHASH; i++) { + head = whlist->heads + i; + hlist_for_each_entry_safe(tpos, pos, n, head, wh_hash) { + destr = &tpos->wh_str; + memcpy(p, destr->name, destr->len); + err = append_de(vdir, o, + destr->len + AUFS_WH_PFX_LEN, + tpos->wh_ino, tpos->wh_type, + delist); + if (unlikely(err)) + break; + } + } + } + + __putname(o); + + out: + AuTraceErr(err); + return err; +#else + return 0; +#endif +} + +static int au_do_read_vdir(struct fillvdir_arg *arg) +{ + int err; + unsigned int mnt_flags; + loff_t offset; + aufs_bindex_t bend, bindex, bstart; + unsigned char dlgt, shwh; + struct super_block *sb; + struct file *hf; + + AuTraceEnter(); + + err = -ENOMEM; + bend = au_fbend(arg->file); + arg->delist = kmalloc(sizeof(*arg->delist) * (bend + 1), GFP_NOFS); + if (unlikely(!arg->delist)) + goto out; + arg->whlist = kmalloc(sizeof(*arg->whlist) * (bend + 1), GFP_NOFS); + if (unlikely(!arg->whlist)) + goto out_delist; + err = 0; + for (bindex = 0; bindex <= bend; bindex++) { + au_nhash_init(arg->delist + bindex); + au_nhash_init(arg->whlist + bindex); + } + + sb = arg->file->f_dentry->d_sb; + mnt_flags = au_mntflags(sb); + dlgt = !!au_test_dlgt(mnt_flags); + arg->flags = 0; + shwh = 0; + if (unlikely(au_opt_test(mnt_flags, SHWH))) { + shwh = 1; + au_fset_fillvdir(arg->flags, SHWH); + } + bstart = au_fbstart(arg->file); + for (bindex = bstart; !err && bindex <= bend; bindex++) { + hf = au_h_fptr(arg->file, bindex); + if (!hf) + continue; + + offset = vfsub_llseek(hf, 0, SEEK_SET); + err = offset; + if (unlikely(offset)) + break; + arg->bindex = bindex; + do { + arg->err = 0; + au_fclr_fillvdir(arg->flags, CALLED); + /* smp_mb(); */ + err = vfsub_readdir(hf, fillvdir, arg, dlgt); + if (err >= 0) + err = arg->err; + } while (!err && au_ftest_fillvdir(arg->flags, CALLED)); + } + + if (unlikely(!err && shwh)) + err = au_handle_shwh(sb, arg->vdir, bstart, bend, arg->whlist, + arg->delist); + + for (bindex = bstart; bindex <= bend; bindex++) { + free_dehlist(arg->delist + bindex); + au_nhash_fin(arg->whlist + bindex); + } + kfree(arg->whlist); + + out_delist: + kfree(arg->delist); + out: + AuTraceErr(err); + return err; +} + +static int read_vdir(struct file *file, int may_read) +{ + int err; + unsigned long expire; + struct fillvdir_arg arg; + unsigned char do_read; + struct dentry *dentry; + struct inode *inode; + struct au_vdir *vdir, *allocated; + struct super_block *sb; + + dentry = file->f_dentry; + LKTRTrace("%.*s, may %d\n", AuDLNPair(dentry), may_read); + FiMustWriteLock(file); + inode = dentry->d_inode; + IMustLock(inode); + IiMustWriteLock(inode); + AuDebugOn(!S_ISDIR(inode->i_mode)); + + err = 0; + allocated = NULL; + do_read = 0; + sb = inode->i_sb; + expire = au_sbi(sb)->si_rdcache; + vdir = au_ivdir(inode); + if (!vdir) { + AuDebugOn(au_fvdir_cache(file)); + do_read = 1; + vdir = alloc_vdir(); + err = PTR_ERR(vdir); + if (IS_ERR(vdir)) + goto out; + err = 0; + allocated = vdir; + } else if (may_read + && (inode->i_version != vdir->vd_version + || time_after(jiffies, vdir->vd_jiffy + expire))) { + LKTRTrace("iver %llu, vdver %lu, exp %lu\n", + (unsigned long long)inode->i_version, + vdir->vd_version, vdir->vd_jiffy + expire); + do_read = 1; + err = reinit_vdir(vdir); + if (unlikely(err)) + goto out; + } + + if (!do_read) + return 0; /* success */ + + arg.file = file; + arg.vdir = vdir; + err = au_do_read_vdir(&arg); + if (!err) { + /* todo: necessary? */ + /* file->f_pos = 0; */ + vdir->vd_version = inode->i_version; + vdir->vd_last.i = 0; + vdir->vd_last.p.deblk = vdir->vd_deblk[0]; + if (allocated) + au_set_ivdir(inode, allocated); + } else if (allocated) + au_vdir_free(allocated); + + out: + AuTraceErr(err); + return err; +} + +static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src) +{ + int err, i, rerr, n; + + AuTraceEnter(); + AuDebugOn(tgt->vd_nblk != 1); + + err = -ENOMEM; + if (tgt->vd_nblk < src->vd_nblk) { + au_vdir_deblk_t **p; + p = au_kzrealloc(tgt->vd_deblk, sizeof(*p) * tgt->vd_nblk, + sizeof(*p) * src->vd_nblk, GFP_NOFS); + if (unlikely(!p)) + goto out; + tgt->vd_deblk = p; + } + + tgt->vd_nblk = src->vd_nblk; + n = src->vd_nblk; + memcpy(tgt->vd_deblk[0], src->vd_deblk[0], AuSize_DEBLK); + /* tgt->vd_last.i = 0; */ + /* tgt->vd_last.p.deblk = tgt->vd_deblk[0]; */ + tgt->vd_version = src->vd_version; + tgt->vd_jiffy = src->vd_jiffy; + + for (i = 1; i < n; i++) { + tgt->vd_deblk[i] = kmalloc(AuSize_DEBLK, GFP_NOFS); + if (tgt->vd_deblk[i]) + memcpy(tgt->vd_deblk[i], src->vd_deblk[i], + AuSize_DEBLK); + else + goto out; + } + /* smp_mb(); */ + return 0; /* success */ + + out: + rerr = reinit_vdir(tgt); + BUG_ON(rerr); + AuTraceErr(err); + return err; +} + +int au_vdir_init(struct file *file) +{ + int err; + struct dentry *dentry; + struct inode *inode; + struct au_vdir *vdir_cache, *allocated; + + dentry = file->f_dentry; + LKTRTrace("%.*s, pos %lld\n", AuDLNPair(dentry), file->f_pos); + FiMustWriteLock(file); + inode = dentry->d_inode; + IiMustWriteLock(inode); + AuDebugOn(!S_ISDIR(inode->i_mode)); + + err = read_vdir(file, !file->f_pos); + if (unlikely(err)) + goto out; + + allocated = NULL; + vdir_cache = au_fvdir_cache(file); + if (!vdir_cache) { + vdir_cache = alloc_vdir(); + err = PTR_ERR(vdir_cache); + if (IS_ERR(vdir_cache)) + goto out; + allocated = vdir_cache; + } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) { + err = reinit_vdir(vdir_cache); + if (unlikely(err)) + goto out; + } else + return 0; /* success */ + + err = copy_vdir(vdir_cache, au_ivdir(inode)); + if (!err) { + file->f_version = inode->i_version; + if (allocated) + au_set_fvdir_cache(file, allocated); + } else if (allocated) + au_vdir_free(allocated); + + out: + AuTraceErr(err); + return err; +} + +static loff_t calc_offset(struct au_vdir *vdir) +{ + loff_t offset; + union au_vdir_deblk_p p; + + p.deblk = vdir->vd_deblk[vdir->vd_last.i]; + offset = vdir->vd_last.p.p - p.p; + offset += sizeof(*p.deblk) * vdir->vd_last.i; + return offset; +} + +/* returns true or false */ +static int seek_vdir(struct file *file) +{ + int valid, i, n; + struct dentry *dentry; + struct au_vdir *vdir_cache; + loff_t offset; + union au_vdir_deblk_p p, deblk_end; + + dentry = file->f_dentry; + LKTRTrace("%.*s, pos %lld\n", AuDLNPair(dentry), file->f_pos); + vdir_cache = au_fvdir_cache(file); + AuDebugOn(!vdir_cache); + + valid = 1; + offset = calc_offset(vdir_cache); + LKTRTrace("offset %lld\n", offset); + if (file->f_pos == offset) + goto out; + + vdir_cache->vd_last.i = 0; + vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0]; + if (!file->f_pos) + goto out; + + valid = 0; + i = file->f_pos / AuSize_DEBLK; + LKTRTrace("i %d\n", i); + if (i >= vdir_cache->vd_nblk) + goto out; + + n = vdir_cache->vd_nblk; + for (; i < n; i++) { + p.deblk = vdir_cache->vd_deblk[i]; + deblk_end.deblk = p.deblk + 1; + offset = i; + offset *= AuSize_DEBLK; + while (!is_deblk_end(&p, &deblk_end) && offset < file->f_pos) { + int l; + l = calc_size(p.de->de_str.len); + offset += l; + p.p += l; + } + if (!is_deblk_end(&p, &deblk_end)) { + valid = 1; + vdir_cache->vd_last.i = i; + vdir_cache->vd_last.p = p; + break; + } + } + + out: + /* smp_mb(); */ + AuTraceErr(!valid); + return valid; +} + +int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir) +{ + int err, l; + struct dentry *dentry; + struct au_vdir *vdir_cache; + struct au_vdir_de *de; + union au_vdir_deblk_p deblk_end; + + dentry = file->f_dentry; + LKTRTrace("%.*s, pos %lld\n", AuDLNPair(dentry), file->f_pos); + vdir_cache = au_fvdir_cache(file); + AuDebugOn(!vdir_cache); + + if (!seek_vdir(file)) + return 0; + + while (1) { + deblk_end.deblk + = vdir_cache->vd_deblk[vdir_cache->vd_last.i] + 1; + while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) { + de = vdir_cache->vd_last.p.de; + LKTRTrace("%.*s, off%lld, i%lu, dt%d\n", + de->de_str.len, de->de_str.name, + file->f_pos, (unsigned long)de->de_ino, + de->de_type); + err = filldir(dirent, de->de_str.name, de->de_str.len, + file->f_pos, de->de_ino, de->de_type); + if (unlikely(err)) { + AuTraceErr(err); + /* todo: ignore the error caused by udba? */ + /* return err; */ + return 0; + } + + l = calc_size(de->de_str.len); + vdir_cache->vd_last.p.p += l; + file->f_pos += l; + } + if (vdir_cache->vd_last.i < vdir_cache->vd_nblk - 1) { + vdir_cache->vd_last.i++; + vdir_cache->vd_last.p.deblk + = vdir_cache->vd_deblk[vdir_cache->vd_last.i]; + file->f_pos = sizeof(*vdir_cache->vd_last.p.deblk) + * vdir_cache->vd_last.i; + continue; + } + break; + } + + /* smp_mb(); */ + return 0; +} --- linux-2.6.28.orig/ubuntu/aufs/module.c +++ linux-2.6.28/ubuntu/aufs/module.c @@ -0,0 +1,247 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * module global variables and operations + * + * $Id: module.c,v 1.10 2008/08/25 01:50:37 sfjro Exp $ + */ + +#include +#include "aufs.h" + +/* ---------------------------------------------------------------------- */ + +/* + * aufs caches + */ +struct kmem_cache *au_cachep[AuCache_Last]; +static int __init create_cache(void) +{ + au_cachep[AuCache_DINFO] = AuCache(au_dinfo); + if (au_cachep[AuCache_DINFO]) + au_cachep[AuCache_ICNTNR] = AuCache(aufs_icntnr); + if (au_cachep[AuCache_ICNTNR]) + au_cachep[AuCache_FINFO] = AuCache(au_finfo); + if (au_cachep[AuCache_FINFO]) + au_cachep[AuCache_VDIR] = AuCache(au_vdir); + if (au_cachep[AuCache_VDIR]) + au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr); + if (au_cachep[AuCache_DEHSTR]) + return 0; + + return -ENOMEM; +} + +static void destroy_cache(void) +{ + int i; + for (i = 0; i < AuCache_Last; i++) + if (au_cachep[i]) { + kmem_cache_destroy(au_cachep[i]); + au_cachep[i] = NULL; + } +} + +/* ---------------------------------------------------------------------- */ + +char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */ +int au_dir_roflags; + +/* + * functions for module interface. + */ +MODULE_LICENSE("GPL"); +/* MODULE_LICENSE("GPL v2"); */ +MODULE_AUTHOR("Junjiro Okajima"); +MODULE_DESCRIPTION(AUFS_NAME " -- Another unionfs"); +MODULE_VERSION(AUFS_VERSION); + +/* it should be 'byte', but param_set_byte() prints it by "%c" */ +short aufs_nwkq = AUFS_NWKQ_DEF; +MODULE_PARM_DESC(nwkq, "the number of workqueue thread, " AUFS_WKQ_NAME); +module_param_named(nwkq, aufs_nwkq, short, S_IRUGO); + +int sysaufs_brs; +MODULE_PARM_DESC(brs, "use /fs/aufs/si_*/brN"); +module_param_named(brs, sysaufs_brs, int, S_IRUGO); + +/* ---------------------------------------------------------------------- */ + +static int __init aufs_init(void) +{ + int err, i; + char *p; + + au_debug_init(); +#ifdef CONFIG_AUFS_INO_T_64 + BUILD_BUG_ON(sizeof(ino_t) != sizeof(long long)); +#else + BUILD_BUG_ON(sizeof(ino_t) != sizeof(int)); +#endif + + p = au_esc_chars; + for (i = 1; i <= ' '; i++) + *p++ = i; + *p++ = '\\'; + *p++ = '\x7f'; + *p = 0; + + au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE); + + err = -EINVAL; + if (unlikely(aufs_nwkq <= 0)) + goto out; + + err = sysaufs_init(); + if (unlikely(err)) + goto out; + err = au_wkq_init(); + if (unlikely(err)) + goto out_sysaufs; + err = au_inotify_init(); + if (unlikely(err)) + goto out_wkq; + err = au_sysrq_init(); + if (unlikely(err)) + goto out_inotify; + + err = create_cache(); + if (unlikely(err)) + goto out_sysrq; + + err = register_filesystem(&aufs_fs_type); + if (unlikely(err)) + goto out_cache; + pr_info(AUFS_NAME " " AUFS_VERSION "\n"); + return 0; /* success */ + + out_cache: + destroy_cache(); + out_sysrq: + au_sysrq_fin(); + out_inotify: + au_inotify_fin(); + out_wkq: + au_wkq_fin(); + out_sysaufs: + sysaufs_fin(); + out: + AuTraceErr(err); + return err; +} + +static void __exit aufs_exit(void) +{ + unregister_filesystem(&aufs_fs_type); + destroy_cache(); + + au_sysrq_fin(); + au_inotify_fin(); + au_wkq_fin(); + sysaufs_fin(); +} + +module_init(aufs_init); +module_exit(aufs_exit); + +/* ---------------------------------------------------------------------- */ + +/* fake Kconfig */ +#if 1 + +#ifdef CONFIG_AUFS_HINOTIFY +#ifndef CONFIG_INOTIFY +#error enable CONFIG_INOTIFY to use CONFIG_AUFS_HINOTIFY. +#endif +#endif /* CONFIG_AUFS_HINOTIFY */ + +#if AUFS_BRANCH_MAX > 511 && PAGE_SIZE > 4096 +#warning pagesize is larger than 4kb, \ + CONFIG_AUFS_BRANCH_MAX_511 or smaller is recommended. +#endif + +#ifdef CONFIG_AUFS_STAT +#ifndef CONFIG_SYSFS +#error CONFIG_AUFS_STAT requires CONFIG_SYSFS. +#endif +#endif /* CONFIG_AUFS_STAT */ + +#ifdef CONFIG_AUFS_SYSAUFS +#warning CONFIG_AUFS_SYSAUFS is unnecessary for linux-2.6.25 and later. +#endif + +#ifdef CONFIG_AUFS_EXPORT +#if !defined(CONFIG_EXPORTFS) && !defined(CONFIG_EXPORTFS_MODULE) +#error CONFIG_AUFS_EXPORT requires CONFIG_EXPORTFS +#endif +#if defined(CONFIG_EXPORTFS_MODULE) && defined(CONFIG_AUFS) +#error need CONFIG_EXPORTFS = y to link aufs statically with CONFIG_AUFS_EXPORT +#endif +#endif /* CONFIG_AUFS_EXPORT */ + +#ifdef CONFIG_AUFS_SEC_PERM_PATCH +#ifndef CONFIG_SECURITY +#warning CONFIG_AUFS_SEC_PERM_PATCH is unnecessary since CONFIG_SECURITY is disabled. +#endif +#ifdef CONFIG_AUFS +#warning CONFIG_AUFS_SEC_PERM_PATCH is unnecessary since CONFIG_AUFS is not a module. +#endif +#endif + +#ifdef CONFIG_AUFS_PUT_FILP_PATCH +#if !defined(CONFIG_NFS_FS) && !defined(CONFIG_NFS_FS_MODULE) +#warning CONFIG_AUFS_PUT_FILP_PATCH is unnecessary since CONFIG_NFS_FS is disabled. +#endif +#ifdef CONFIG_AUFS +#warning CONFIG_AUFS_PUT_FILP_PATCH is unnecessary since CONFIG_AUFS is not a module. +#endif +#endif /* CONFIG_AUFS_PUT_FILP_PATCH */ + +#ifdef CONFIG_AUFS_LHASH_PATCH +#if !defined(CONFIG_NFS_FS) && !defined(CONFIG_NFS_FS_MODULE) +#warning CONFIG_AUFS_LHASH_PATCH is unnecessary since CONFIG_NFS_FS is disabled. +#endif +#endif + +#ifdef CONFIG_AUFS_KSIZE_PATCH +#warning CONFIG_AUFS_KSIZE_PATCH is unnecessary for linux-2.6.22 and later. +#endif + +#ifdef CONFIG_AUFS_WORKAROUND_FUSE +#if !defined(CONFIG_FUSE_FS) && !defined(CONFIG_FUSE_FS_MODULE) +#warning CONFIG_AUFS_WORKAROUND_FUSE is enabled while FUSE is disabled. +#endif +#endif + +#ifdef CONFIG_DEBUG_PROVE_LOCKING +#if MAX_LOCKDEP_SUBCLASSES < AuLsc_I_End +#warning lockdep will not work since aufs uses deeper locks. +#endif +#endif + +#ifdef CONFIG_AUFS_COMPAT +#warning CONFIG_AUFS_COMPAT will be removed in the near future. +#endif + +#if defined(CONFIG_AUFS_UNIONFS23_PATCH) \ + && !defined(CONFIG_AUFS_UNIONFS22_PATCH) +#error mis-configuration. CONFIG_AUFS_UNIONFS23_PATCH is enabled but CONFIG_AUFS_UNIONFS22_PATCH. +#endif + +#endif --- linux-2.6.28.orig/ubuntu/aufs/super.c +++ linux-2.6.28/ubuntu/aufs/super.c @@ -0,0 +1,863 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * mount and super_block operations + * + * $Id: super.c,v 1.16 2008/09/15 03:14:49 sfjro Exp $ + */ + +#include +#include +#include +#include +#include + +#include "aufs.h" + +/* + * super_operations + */ +static struct inode *aufs_alloc_inode(struct super_block *sb) +{ + struct aufs_icntnr *c; + + AuTraceEnter(); + + c = au_cache_alloc_icntnr(); + if (c) { + inode_init_once(&c->vfs_inode); + c->vfs_inode.i_version = 1; /* sigen(sb); */ + c->iinfo.ii_hinode = NULL; + return &c->vfs_inode; + } + return NULL; +} + +static void aufs_destroy_inode(struct inode *inode) +{ + int err; + + LKTRTrace("i%lu\n", inode->i_ino); + + if (!inode->i_nlink) { + struct super_block *sb = inode->i_sb; + int locked; + + /* in nowait task, sbi is write-locked */ + /* todo: test kernel thread */ + locked = si_noflush_read_trylock(sb); + err = au_xigen_inc(inode); + if (unlikely(err)) + AuWarn1("failed resetting i_generation, %d\n", err); + if (locked) + si_read_unlock(sb); + } + + au_iinfo_fin(inode); + au_cache_free_icntnr(container_of(inode, struct aufs_icntnr, + vfs_inode)); +} + +struct inode *au_iget_locked(struct super_block *sb, ino_t ino) +{ + struct inode *inode; + int err; + + LKTRTrace("i%lu\n", (unsigned long)ino); + + inode = iget_locked(sb, ino); + if (unlikely(!inode)) { + inode = ERR_PTR(-ENOMEM); + goto out; + } + AuDebugOn(IS_ERR(inode)); + if (unlikely(!(inode->i_state & I_NEW))) + goto out; + + err = au_xigen_new(inode); + if (!err) + err = au_iinfo_init(inode); + if (!err) + inode->i_version++; + else { + iget_failed(inode); + inode = ERR_PTR(err); + } + + out: + /* never return NULL */ + AuDebugOn(!inode); + AuTraceErrPtr(inode); + return inode; +} + +static int au_show_brs(struct seq_file *seq, struct super_block *sb) +{ + int err; + aufs_bindex_t bindex, bend; + struct dentry *root; + struct path path; + + AuTraceEnter(); + + err = 0; + root = sb->s_root; + bend = au_sbend(sb); + for (bindex = 0; !err && bindex <= bend; bindex++) { + path.mnt = au_sbr_mnt(sb, bindex); + path.dentry = au_h_dptr(root, bindex); + err = seq_path(seq, &path, au_esc_chars); + if (err > 0) + err = seq_printf + (seq, "=%s", + au_optstr_br_perm(au_sbr_perm(sb, bindex))); + if (!err && bindex != bend) + err = seq_putc(seq, ':'); + } + + AuTraceErr(err); + return err; +} + +static void au_show_wbr_create(struct seq_file *m, int v, + struct au_sbinfo *sbinfo) +{ + const char *pat; + + AuDebugOn(v == AuWbrCreate_Def); + + seq_printf(m, ",create="); + pat = au_optstr_wbr_create(v); + switch (v) { + case AuWbrCreate_TDP: + case AuWbrCreate_RR: + case AuWbrCreate_MFS: + case AuWbrCreate_PMFS: + seq_printf(m, pat); + break; + case AuWbrCreate_MFSV: + seq_printf(m, /*pat*/"mfs:%lu", + sbinfo->si_wbr_mfs.mfs_expire / HZ); + break; + case AuWbrCreate_PMFSV: + seq_printf(m, /*pat*/"pmfs:%lu", + sbinfo->si_wbr_mfs.mfs_expire / HZ); + break; + case AuWbrCreate_MFSRR: + seq_printf(m, /*pat*/"mfsrr:%llu", + sbinfo->si_wbr_mfs.mfsrr_watermark); + break; + case AuWbrCreate_MFSRRV: + seq_printf(m, /*pat*/"mfsrr:%llu:%lu", + sbinfo->si_wbr_mfs.mfsrr_watermark, + sbinfo->si_wbr_mfs.mfs_expire / HZ); + break; + } +} + +/* seq_file will re-call me in case of too long string */ +static int aufs_show_options(struct seq_file *m, struct vfsmount *mnt) +{ + int err, n; + struct super_block *sb; + struct au_sbinfo *sbinfo; + struct dentry *root; + struct file *xino; + unsigned int mnt_flags, v; + struct path path; + + AuTraceEnter(); + + sb = mnt->mnt_sb; + root = sb->s_root; + if (!sysaufs_brs) + aufs_read_lock(root, !AuLock_IR); + else + si_noflush_read_lock(sb); + sbinfo = au_sbi(sb); + seq_printf(m, ",si=%lx", au_si_mask ^ (unsigned long)sbinfo); + mnt_flags = au_mntflags(sb); + if (au_opt_test(mnt_flags, XINO)) { + seq_puts(m, ",xino="); + xino = sbinfo->si_xib; + path.mnt = xino->f_vfsmnt; + path.dentry = xino->f_dentry; + err = seq_path(m, &path, au_esc_chars); + if (unlikely(err <= 0)) + goto out; + err = 0; +#define Deleted "\\040(deleted)" + m->count -= sizeof(Deleted) - 1; + AuDebugOn(memcmp(m->buf + m->count, Deleted, + sizeof(Deleted) - 1)); +#undef Deleted +#ifdef CONFIG_AUFS_EXPORT /* reserved for future use */ + } else if (au_opt_test(mnt_flags, XINODIR)) { + seq_puts(m, ",xinodir="); + seq_path(m, &sbinfo->si_xinodir, au_esc_chars); +#endif + } else + seq_puts(m, ",noxino"); + +#define AuBool(name, str) do { \ + v = au_opt_test(mnt_flags, name); \ + if (v != au_opt_test(AuOpt_Def, name)) \ + seq_printf(m, ",%s" #str, v ? "" : "no"); \ +} while (0) + +#define AuStr(name, str) do { \ + v = mnt_flags & AuOptMask_##name; \ + if (v != (AuOpt_Def & AuOptMask_##name)) \ + seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \ +} while (0) + +#ifdef CONFIG_AUFS_COMPAT +#define AuStr_BrOpt "dirs=" +#else +#define AuStr_BrOpt "br:" +#endif + + AuBool(TRUNC_XINO, trunc_xino); + AuBool(DIRPERM1, dirperm1); + AuBool(SHWH, shwh); + AuBool(PLINK, plink); + AuStr(UDBA, udba); + + v = sbinfo->si_wbr_create; + if (v != AuWbrCreate_Def) + au_show_wbr_create(m, v, sbinfo); + + v = sbinfo->si_wbr_copyup; + if (v != AuWbrCopyup_Def) + seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v)); + + v = au_opt_test(mnt_flags, ALWAYS_DIROPQ); + if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ)) + seq_printf(m, ",diropq=%c", v ? 'a' : 'w'); + AuBool(REFROF, refrof); + AuBool(DLGT, dlgt); + AuBool(WARN_PERM, warn_perm); + AuBool(VERBOSE, verbose); + + n = sbinfo->si_dirwh; + if (n != AUFS_DIRWH_DEF) + seq_printf(m, ",dirwh=%d", n); + n = sbinfo->si_rdcache / HZ; + if (n != AUFS_RDCACHE_DEF) + seq_printf(m, ",rdcache=%d", n); + + AuStr(COO, coo); + + out: + if (!sysaufs_brs) { + seq_puts(m, "," AuStr_BrOpt); + au_show_brs(m, sb); + aufs_read_unlock(root, !AuLock_IR); + } else + si_read_unlock(sb); + return 0; + +#undef AuBool +#undef AuStr +#undef AuStr_BrOpt +} + +/* todo: in case of round-robin policy, return the sum of all rw branches? */ +static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf) +{ + int err; + + AuTraceEnter(); + + aufs_read_lock(dentry->d_sb->s_root, 0); + err = vfsub_statfs(au_h_dptr(dentry->d_sb->s_root, 0), buf, + !!au_test_dlgt(au_mntflags(dentry->d_sb))); + aufs_read_unlock(dentry->d_sb->s_root, 0); + if (!err) { + buf->f_type = AUFS_SUPER_MAGIC; + buf->f_namelen -= AUFS_WH_PFX_LEN; + memset(&buf->f_fsid, 0, sizeof(buf->f_fsid)); + } + /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */ + + AuTraceErr(err); + return err; +} + +static void au_fsync_br(struct super_block *sb) +{ +#ifdef CONFIG_AUFS_FSYNC_SUPER_PATCH + aufs_bindex_t bend, bindex; + int brperm; + struct super_block *h_sb; + + AuTraceEnter(); + + si_write_lock(sb); + bend = au_sbend(sb); + for (bindex = 0; bindex < bend; bindex++) { + brperm = au_sbr_perm(sb, bindex); + if (brperm == AuBrPerm_RR || brperm == AuBrPerm_RRWH) + continue; + h_sb = au_sbr_sb(sb, bindex); + if (bdev_read_only(h_sb->s_bdev)) + continue; + + lockdep_off(); + down_write(&h_sb->s_umount); + shrink_dcache_sb(h_sb); + fsync_super(h_sb); + up_write(&h_sb->s_umount); + lockdep_on(); + } + si_write_unlock(sb); +#endif +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) +/* this IS NOT for super_operations */ +static void aufs_umount_begin(struct super_block *arg) +#define AuUmountBeginSb(arg) (arg) +#else +/* this IS for super_operations */ +static void aufs_umount_begin(struct vfsmount *arg, int flags) +#define AuUmountBeginSb(arg) (arg)->mnt_sb +#endif +{ + struct super_block *sb = AuUmountBeginSb(arg); + struct au_sbinfo *sbinfo; + + AuTraceEnter(); + /* dont trust BKL */ + AuDebugOn(!kernel_locked()); + + sbinfo = au_sbi(sb); + if (unlikely(!sbinfo)) + return; + + au_fsync_br(sb); + + si_write_lock(sb); + if (au_opt_test(au_mntflags(sb), PLINK)) + au_plink_put(sb); + au_mnt_reset(sbinfo); +#if 0 /* reserved for future use */ + if (sbinfo->si_wbr_create_ops->fin) + sbinfo->si_wbr_create_ops->fin(sb); +#endif + si_write_unlock(sb); +} + +/* final actions when unmounting a file system */ +static void aufs_put_super(struct super_block *sb) +{ + struct au_sbinfo *sbinfo; + + AuTraceEnter(); + + sbinfo = au_sbi(sb); + if (unlikely(!sbinfo)) + return; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) + aufs_umount_begin(sb); +#endif + kobject_put(&sbinfo->si_kobj); +} + +/* ---------------------------------------------------------------------- */ + +/* + * refresh dentry and inode at remount time. + */ +static int do_refresh(struct dentry *dentry, mode_t type, + unsigned int dir_flags) +{ + int err; + struct dentry *parent; + struct inode *inode; + + LKTRTrace("%.*s, 0%o\n", AuDLNPair(dentry), type); + inode = dentry->d_inode; + AuDebugOn(!inode); + + di_write_lock_child(dentry); + parent = dget_parent(dentry); + di_read_lock_parent(parent, AuLock_IR); + /* returns a number of positive dentries */ + err = au_refresh_hdentry(dentry, type); + if (err >= 0) { + err = au_refresh_hinode(inode, dentry); + if (!err && type == S_IFDIR) + au_reset_hinotify(inode, dir_flags); + } + if (unlikely(err)) + AuErr("unrecoverable error %d, %.*s\n", err, AuDLNPair(dentry)); + di_read_unlock(parent, AuLock_IR); + dput(parent); + di_write_unlock(dentry); + + AuTraceErr(err); + return err; +} + +static int test_dir(struct dentry *dentry, void *arg) +{ + return S_ISDIR(dentry->d_inode->i_mode); +} + +/* todo: merge with refresh_nondir()? */ +static int refresh_dir(struct dentry *root, au_gen_t sgen) +{ + int err, i, j, ndentry, e; + struct au_dcsub_pages dpages; + struct au_dpage *dpage; + struct dentry **dentries; + struct inode *inode; + const unsigned int flags = au_hi_flags(root->d_inode, /*isdir*/1); + + LKTRTrace("sgen %d\n", sgen); + SiMustWriteLock(root->d_sb); + /* dont trust BKL */ + AuDebugOn(au_digen(root) != sgen || !kernel_locked()); + + err = 0; + list_for_each_entry(inode, &root->d_sb->s_inodes, i_sb_list) + if (S_ISDIR(inode->i_mode) && au_iigen(inode) != sgen) { + ii_write_lock_child(inode); + e = au_refresh_hinode_self(inode); + ii_write_unlock(inode); + if (unlikely(e)) { + LKTRTrace("e %d, i%lu\n", e, inode->i_ino); + if (!err) + err = e; + /* go on even if err */ + } + } + + e = au_dpages_init(&dpages, GFP_NOFS); + if (unlikely(e)) { + if (!err) + err = e; + goto out; + } + e = au_dcsub_pages(&dpages, root, test_dir, NULL); + if (unlikely(e)) { + if (!err) + err = e; + goto out_dpages; + } + + for (i = 0; !e && i < dpages.ndpage; i++) { + dpage = dpages.dpages + i; + dentries = dpage->dentries; + ndentry = dpage->ndentry; + for (j = 0; !e && j < ndentry; j++) { + struct dentry *d; + d = dentries[j]; +#ifdef CONFIG_AUFS_DEBUG + { + struct dentry *parent; + parent = dget_parent(d); + AuDebugOn(!S_ISDIR(d->d_inode->i_mode) + || IS_ROOT(d) + || au_digen(parent) != sgen); + dput(parent); + } +#endif + if (au_digen(d) != sgen) { + e = do_refresh(d, S_IFDIR, flags); + if (unlikely(e && !err)) + err = e; + /* break on err */ + } + } + } + + out_dpages: + au_dpages_free(&dpages); + out: + AuTraceErr(err); + return err; +} + +static int test_nondir(struct dentry *dentry, void *arg) +{ + return !S_ISDIR(dentry->d_inode->i_mode); +} + +static int refresh_nondir(struct dentry *root, au_gen_t sgen, int do_dentry) +{ + int err, i, j, ndentry, e; + struct au_dcsub_pages dpages; + struct au_dpage *dpage; + struct dentry **dentries; + struct inode *inode; + + LKTRTrace("sgen %d\n", sgen); + SiMustWriteLock(root->d_sb); + /* dont trust BKL */ + AuDebugOn(au_digen(root) != sgen || !kernel_locked()); + + err = 0; + list_for_each_entry(inode, &root->d_sb->s_inodes, i_sb_list) + if (!S_ISDIR(inode->i_mode) && au_iigen(inode) != sgen) { + ii_write_lock_child(inode); + e = au_refresh_hinode_self(inode); + ii_write_unlock(inode); + if (unlikely(e)) { + LKTRTrace("e %d, i%lu\n", e, inode->i_ino); + if (!err) + err = e; + /* go on even if err */ + } + } + + if (!do_dentry) + goto out; + + e = au_dpages_init(&dpages, GFP_NOFS); + if (unlikely(e)) { + if (!err) + err = e; + goto out; + } + e = au_dcsub_pages(&dpages, root, test_nondir, NULL); + if (unlikely(e)) { + if (!err) + err = e; + goto out_dpages; + } + + for (i = 0; i < dpages.ndpage; i++) { + dpage = dpages.dpages + i; + dentries = dpage->dentries; + ndentry = dpage->ndentry; + for (j = 0; j < ndentry; j++) { + struct dentry *d; + d = dentries[j]; +#ifdef CONFIG_AUFS_DEBUG + { + struct dentry *parent; + parent = dget_parent(d); + AuDebugOn(S_ISDIR(d->d_inode->i_mode) + || au_digen(parent) != sgen); + dput(parent); + } +#endif + inode = d->d_inode; + if (inode && au_digen(d) != sgen) { + e = do_refresh(d, inode->i_mode & S_IFMT, 0); + if (unlikely(e && !err)) + err = e; + /* go on even err */ + } + } + } + + out_dpages: + au_dpages_free(&dpages); + out: + AuTraceErr(err); + return err; +} + +/* stop extra interpretation of errno in mount(8), and strange error messages */ +static int cvt_err(int err) +{ + AuTraceErr(err); + + switch (err) { + case -ENOENT: + case -ENOTDIR: + case -EEXIST: + case -EIO: + err = -EINVAL; + } + return err; +} + +/* protected by s_umount */ +static int aufs_remount_fs(struct super_block *sb, int *flags, char *data) +{ + int err, rerr; + au_gen_t sigen; + struct dentry *root; + struct inode *inode; + struct au_opts opts; + struct au_sbinfo *sbinfo; + unsigned char dlgt; + + LKTRTrace("flags 0x%x, data %s, len %lu\n", + *flags, data ? data : "NULL", + (unsigned long)(data ? strlen(data) : 0)); + + au_fsync_br(sb); + + err = 0; + if (!data || !*data) + goto out; /* success */ + + err = -ENOMEM; + memset(&opts, 0, sizeof(opts)); + opts.opt = (void *)__get_free_page(GFP_NOFS); + if (unlikely(!opts.opt)) + goto out; + opts.max_opt = PAGE_SIZE / sizeof(*opts.opt); + opts.flags = AuOpts_REMOUNT; + + /* parse it before aufs lock */ + err = au_opts_parse(sb, *flags, data, &opts); + if (unlikely(err)) + goto out_opts; + + sbinfo = au_sbi(sb); + root = sb->s_root; + inode = root->d_inode; + mutex_lock(&inode->i_mutex); + aufs_write_lock(root); + + /* au_do_opts() may return an error */ + err = au_opts_remount(sb, &opts); + au_opts_free(&opts); + + if (au_ftest_opts(opts.flags, REFRESH_DIR) + || au_ftest_opts(opts.flags, REFRESH_NONDIR)) { + dlgt = !!au_opt_test(sbinfo->si_mntflags, DLGT); + au_opt_clr(sbinfo->si_mntflags, DLGT); + au_sigen_inc(sb); + au_reset_hinotify(inode, au_hi_flags(inode, /*isdir*/1)); + sigen = au_sigen(sb); + au_fclr_si(sbinfo, FAILED_REFRESH_DIRS); + + DiMustNoWaiters(root); + IiMustNoWaiters(root->d_inode); + di_write_unlock(root); + + rerr = refresh_dir(root, sigen); + if (unlikely(rerr)) { + au_fset_si(sbinfo, FAILED_REFRESH_DIRS); + AuWarn("Refreshing directories failed, ignores (%d)\n", + rerr); + } + + if (unlikely(au_ftest_opts(opts.flags, REFRESH_NONDIR))) { + rerr = refresh_nondir(root, sigen, !rerr); + if (unlikely(rerr)) + AuWarn("Refreshing non-directories failed," + " ignores (%d)\n", rerr); + } + + /* aufs_write_lock() calls ..._child() */ + di_write_lock_child(root); + + au_cpup_attr_all(inode); + if (unlikely(dlgt)) + au_opt_set(sbinfo->si_mntflags, DLGT); + } + + aufs_write_unlock(root); + mutex_unlock(&inode->i_mutex); + + out_opts: + free_page((unsigned long)opts.opt); + out: + err = cvt_err(err); + AuTraceErr(err); + return err; +} + +static struct super_operations aufs_sop = { + .alloc_inode = aufs_alloc_inode, + .destroy_inode = aufs_destroy_inode, + .drop_inode = generic_delete_inode, + + .show_options = aufs_show_options, + .statfs = aufs_statfs, + + .put_super = aufs_put_super, + .remount_fs = aufs_remount_fs, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) + .umount_begin = aufs_umount_begin +#endif +}; + +/* ---------------------------------------------------------------------- */ + +static int alloc_root(struct super_block *sb) +{ + int err; + struct inode *inode; + struct dentry *root; + + AuTraceEnter(); + + err = -ENOMEM; + inode = au_iget_locked(sb, AUFS_ROOT_INO); + err = PTR_ERR(inode); + if (IS_ERR(inode)) + goto out; + inode->i_op = &aufs_dir_iop; + inode->i_fop = &aufs_dir_fop; + inode->i_mode = S_IFDIR; + unlock_new_inode(inode); + root = d_alloc_root(inode); + if (unlikely(!root)) + goto out_iput; + err = PTR_ERR(root); + if (IS_ERR(root)) + goto out_iput; + + err = au_alloc_dinfo(root); + if (!err) { + sb->s_root = root; + return 0; /* success */ + } + dput(root); + goto out; /* do not iput */ + + out_iput: + iget_failed(inode); + iput(inode); + out: + AuTraceErr(err); + return err; + +} + +static int aufs_fill_super(struct super_block *sb, void *raw_data, int silent) +{ + int err; + struct dentry *root; + struct inode *inode; + struct au_opts opts; + char *arg = raw_data; + + if (unlikely(!arg || !*arg)) { + err = -EINVAL; + AuErr("no arg\n"); + goto out; + } + LKTRTrace("%s, silent %d\n", arg, silent); + + err = -ENOMEM; + memset(&opts, 0, sizeof(opts)); + opts.opt = (void *)__get_free_page(GFP_NOFS); + if (unlikely(!opts.opt)) + goto out; + opts.max_opt = PAGE_SIZE / sizeof(*opts.opt); + + err = au_si_alloc(sb); + if (unlikely(err)) + goto out_opts; + SiMustWriteLock(sb); + /* all timestamps always follow the ones on the branch */ + sb->s_flags |= MS_NOATIME | MS_NODIRATIME; + sb->s_op = &aufs_sop; + sb->s_magic = AUFS_SUPER_MAGIC; + au_export_init(sb); + + err = alloc_root(sb); + if (unlikely(err)) { + AuDebugOn(sb->s_root); + si_write_unlock(sb); + goto out_info; + } + root = sb->s_root; + DiMustWriteLock(root); + inode = root->d_inode; + inode->i_nlink = 2; + + /* + * actually we can parse options regardless aufs lock here. + * but at remount time, parsing must be done before aufs lock. + * so we follow the same rule. + */ + ii_write_lock_parent(inode); + aufs_write_unlock(root); + err = au_opts_parse(sb, sb->s_flags, arg, &opts); + if (unlikely(err)) + goto out_root; + + /* lock vfs_inode first, then aufs. */ + mutex_lock(&inode->i_mutex); + inode->i_op = &aufs_dir_iop; + inode->i_fop = &aufs_dir_fop; + aufs_write_lock(root); + + sb->s_maxbytes = 0; + err = au_opts_mount(sb, &opts); + au_opts_free(&opts); + if (unlikely(err)) + goto out_unlock; + AuDebugOn(!sb->s_maxbytes); + + aufs_write_unlock(root); + mutex_unlock(&inode->i_mutex); + goto out_opts; /* success */ + + out_unlock: + aufs_write_unlock(root); + mutex_unlock(&inode->i_mutex); + out_root: + dput(root); + sb->s_root = NULL; + out_info: + kobject_put(&au_sbi(sb)->si_kobj); + sb->s_fs_info = NULL; + out_opts: + free_page((unsigned long)opts.opt); + out: + AuTraceErr(err); + err = cvt_err(err); + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static int aufs_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *raw_data, + struct vfsmount *mnt) +{ + int err; + struct super_block *sb; + + /* all timestamps always follow the ones on the branch */ + /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */ + err = get_sb_nodev(fs_type, flags, raw_data, aufs_fill_super, mnt); + if (!err) { + sb = mnt->mnt_sb; + au_mnt_init(au_sbi(sb), mnt); + si_write_lock(sb); + sysaufs_brs_add(sb, 0); + si_write_unlock(sb); + } + return err; +} + +struct file_system_type aufs_fs_type = { + .name = AUFS_FSTYPE, + .fs_flags = + FS_RENAME_DOES_D_MOVE /* a race between rename and others*/ + | FS_REVAL_DOT, /* for NFS branch */ + .get_sb = aufs_get_sb, + .kill_sb = generic_shutdown_super, + /* no need to __module_get() and module_put(). */ + .owner = THIS_MODULE, +}; --- linux-2.6.28.orig/ubuntu/aufs/robr.c +++ linux-2.6.28/ubuntu/aufs/robr.c @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * 'robr', aufs as readonly branch of another aufs + * + * $Id: robr.c,v 1.6 2008/07/21 02:53:51 sfjro Exp $ + */ + +#include "aufs.h" + +/* ---------------------------------------------------------------------- */ + +int au_test_robr_wh(struct qstr *name, struct dentry *h_parent, + struct qstr *wh_name, int try_sio, struct au_ndx *ndx) +{ + if (strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) + return au_wh_test(h_parent, wh_name, try_sio, ndx); + return -EPERM; +} + +int au_test_robr_shwh(struct super_block *sb, const struct qstr *name) +{ + return 0; +} + +/* ---------------------------------------------------------------------- */ + +struct au_robr_lvma { + struct list_head list; + struct vm_area_struct *vma; +}; + +struct file *au_robr_safe_file(struct vm_area_struct *vma) +{ + struct file *file = vma->vm_file; + struct super_block *sb = file->f_dentry->d_sb; + struct au_robr_lvma *lvma, *entry; + struct au_sbinfo *sbinfo; + unsigned char found, warn; + + AuTraceEnter(); + AuDebugOn(!au_test_aufs(sb)); + + warn = 0; + found = 0; + sbinfo = au_sbi(sb); + spin_lock(&sbinfo->si_lvma_lock); + list_for_each_entry(entry, &sbinfo->si_lvma, list) { + found = (entry->vma == vma); + if (unlikely(found)) + break; + } + if (!found) { + lvma = kmalloc(sizeof(*lvma), GFP_ATOMIC); + if (lvma) { + lvma->vma = vma; + list_add(&lvma->list, &sbinfo->si_lvma); + } else { + warn = 1; + file = NULL; + } + } else + file = NULL; + spin_unlock(&sbinfo->si_lvma_lock); + + if (unlikely(warn)) + AuWarn1("no memory for lvma\n"); + return file; +} + +void au_robr_reset_file(struct vm_area_struct *vma, struct file *file) +{ + struct super_block *sb = file->f_dentry->d_sb; + struct au_robr_lvma *entry, *found; + struct au_sbinfo *sbinfo; + + AuTraceEnter(); + AuDebugOn(!au_test_aufs(sb)); + + vma->vm_file = file; + /* smp_mb(); */ /* flush vm_file */ + + found = NULL; + sbinfo = au_sbi(sb); + spin_lock(&sbinfo->si_lvma_lock); + list_for_each_entry(entry, &sbinfo->si_lvma, list) + if (entry->vma == vma) { + found = entry; + break; + } + AuDebugOn(!found); + list_del(&found->list); + spin_unlock(&sbinfo->si_lvma_lock); + kfree(found); +} --- linux-2.6.28.orig/ubuntu/aufs/dcsub.h +++ linux-2.6.28/ubuntu/aufs/dcsub.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * sub-routines for dentry cache + * + * $Id: dcsub.h,v 1.4 2008/07/21 02:54:22 sfjro Exp $ + */ + +#ifndef __AUFS_DCSUB_H__ +#define __AUFS_DCSUB_H__ + +#ifdef __KERNEL__ + +#include + +struct au_dpage { + int ndentry; + struct dentry **dentries; +}; + +struct au_dcsub_pages { + int ndpage; + struct au_dpage *dpages; +}; + +/* ---------------------------------------------------------------------- */ + +int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp); +void au_dpages_free(struct au_dcsub_pages *dpages); +typedef int (*au_dpages_test)(struct dentry *dentry, void *arg); +int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root, + au_dpages_test test, void *arg); +int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry, + int do_include, au_dpages_test test, void *arg); +struct dentry *au_test_subdir(struct dentry *d1, struct dentry *d2); + +#endif /* __KERNEL__ */ +#endif /* __AUFS_DCSUB_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/sbinfo.c +++ linux-2.6.28/ubuntu/aufs/sbinfo.c @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * superblock private data + * + * $Id: sbinfo.c,v 1.11 2008/07/27 22:49:36 sfjro Exp $ + */ + +#include +#include "aufs.h" + +/* + * they are necessary regardless sysfs is disabled. + */ +void au_si_free(struct kobject *kobj) +{ + struct au_sbinfo *sbinfo; + struct super_block *sb; + + LKTRTrace("kobj %p\n", kobj); + sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); + LKTRTrace("sbinfo %p\n", sbinfo); + AuDebugOn(!list_empty(&sbinfo->si_plink)); + + sb = sbinfo->si_sb; + si_write_lock(sb); + au_xino_clr(sb); + au_br_free(sbinfo); + kfree(sbinfo->si_branch); + au_export_put(sbinfo); + si_write_unlock(sb); + + kfree(sbinfo); +} + +int au_si_alloc(struct super_block *sb) +{ + int err; + struct au_sbinfo *sbinfo; + + AuTraceEnter(); + + err = -ENOMEM; + sbinfo = kmalloc(sizeof(*sbinfo), GFP_NOFS); + if (unlikely(!sbinfo)) + goto out; + sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS); + if (unlikely(!sbinfo->si_branch)) + goto out_sbinfo; + + memset(&sbinfo->si_kobj, 0, sizeof(sbinfo->si_kobj)); + err = sysaufs_si_init(sbinfo); + if (unlikely(err)) + goto out_br; + + au_rw_init_wlock(&sbinfo->si_rwsem); + sbinfo->si_generation = 0; + sbinfo->au_si_status = 0; + sbinfo->si_bend = -1; + sbinfo->si_last_br_id = 0; + + sbinfo->si_wbr_copyup = AuWbrCopyup_Def; + sbinfo->si_wbr_create = AuWbrCreate_Def; + sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + AuWbrCopyup_Def; + sbinfo->si_wbr_create_ops = au_wbr_create_ops + AuWbrCreate_Def; + + sbinfo->si_mntflags = AuOpt_Def; + + sbinfo->si_xread = NULL; + sbinfo->si_xwrite = NULL; + sbinfo->si_xib = NULL; + mutex_init(&sbinfo->si_xib_mtx); + sbinfo->si_xib_buf = NULL; + au_xino_def_br_set(NULL, sbinfo); + /* leave si_xib_last_pindex and si_xib_next_bit */ + + au_nwt_init(&sbinfo->si_nowait); + + sbinfo->si_rdcache = AUFS_RDCACHE_DEF * HZ; + sbinfo->si_dirwh = AUFS_DIRWH_DEF; + + spin_lock_init(&sbinfo->si_plink_lock); + INIT_LIST_HEAD(&sbinfo->si_plink); + + au_robr_lvma_init(sbinfo); + + /* leave other members for sysaufs and si_mnt. */ + sbinfo->si_sb = sb; + + sb->s_fs_info = sbinfo; + + au_debug_sbinfo_init(sbinfo); + return 0; /* success */ + + out_br: + kfree(sbinfo->si_branch); + out_sbinfo: + kfree(sbinfo); + out: + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct au_branch *au_sbr(struct super_block *sb, aufs_bindex_t bindex) +{ + struct au_branch *br; + + SiMustAnyLock(sb); + AuDebugOn(bindex < 0 || au_sbend(sb) < bindex); + br = au_sbi(sb)->si_branch[0 + bindex]; + AuDebugOn(!br); + return br; +} + +au_gen_t au_sigen_inc(struct super_block *sb) +{ + au_gen_t gen; + + SiMustWriteLock(sb); + gen = ++au_sbi(sb)->si_generation; + au_update_digen(sb->s_root); + au_update_iigen(sb->s_root->d_inode); + sb->s_root->d_inode->i_version++; + return gen; +} + +int au_find_bindex(struct super_block *sb, struct au_branch *br) +{ + aufs_bindex_t bindex, bend; + + bend = au_sbend(sb); + for (bindex = 0; bindex <= bend; bindex++) + if (au_sbr(sb, bindex) == br) + return bindex; + return -1; +} + +/* ---------------------------------------------------------------------- */ + +/* dentry and super_block lock. call at entry point */ +void aufs_read_lock(struct dentry *dentry, int flags) +{ + si_read_lock(dentry->d_sb, flags); + if (au_ftest_lock(flags, DW)) + di_write_lock_child(dentry); + else + di_read_lock_child(dentry, flags); +} + +void aufs_read_unlock(struct dentry *dentry, int flags) +{ + if (au_ftest_lock(flags, DW)) + di_write_unlock(dentry); + else + di_read_unlock(dentry, flags); + si_read_unlock(dentry->d_sb); +} + +void aufs_write_lock(struct dentry *dentry) +{ + si_write_lock(dentry->d_sb); + di_write_lock_child(dentry); +} + +void aufs_write_unlock(struct dentry *dentry) +{ + di_write_unlock(dentry); + si_write_unlock(dentry->d_sb); +} + +void aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags) +{ + AuDebugOn(d1 == d2 || d1->d_sb != d2->d_sb); + si_read_lock(d1->d_sb, flags); + di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIR)); +} + +void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2) +{ + AuDebugOn(d1 == d2 || d1->d_sb != d2->d_sb); + di_write_unlock2(d1, d2); + si_read_unlock(d1->d_sb); +} + +/* ---------------------------------------------------------------------- */ + +aufs_bindex_t au_new_br_id(struct super_block *sb) +{ + aufs_bindex_t br_id; + struct au_sbinfo *sbinfo; + + AuTraceEnter(); + SiMustWriteLock(sb); + + sbinfo = au_sbi(sb); + while (1) { + br_id = ++sbinfo->si_last_br_id; + if (br_id && au_br_index(sb, br_id) < 0) + return br_id; + } +} --- linux-2.6.28.orig/ubuntu/aufs/vfsub.h +++ linux-2.6.28/ubuntu/aufs/vfsub.h @@ -0,0 +1,518 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * sub-routines for VFS + * + * $Id: vfsub.h,v 1.11 2008/08/25 01:51:04 sfjro Exp $ + */ + +#ifndef __AUFS_VFSUB_H__ +#define __AUFS_VFSUB_H__ + +#ifdef __KERNEL__ + +#include +#include +#include +#include +#include +#include + +/* ---------------------------------------------------------------------- */ + +/* vfsub flags */ +#define Vfsub_DLGT 1 /* operation with delegation */ +#define Vfsub_FORCE_UNLINK (1 << 1) /* force unlinking */ +#define vfsub_ftest(flags, name) ((flags) & Vfsub_##name) +#define vfsub_fset(flags, name) { (flags) |= Vfsub_##name; } +#define vfsub_fclr(flags, name) { (flags) &= ~Vfsub_##name; } +#ifndef CONFIG_AUFS_DLGT +#undef Vfsub_DLGT +#define Vfsub_DLGT 0 +#endif + +struct au_hin_ignore; +struct vfsub_args { +#ifdef CONFIG_AUFS_HINOTIFY + /* inotify events to be ignored */ + int nignore; + struct au_hin_ignore *ignore; +#endif + + unsigned int flags; +}; + +struct au_hinode; +#ifdef CONFIG_AUFS_HINOTIFY +static inline +void do_vfsub_args_reinit(struct vfsub_args *vargs, struct au_hin_ignore *ign) +{ + vargs->nignore = 0; + vargs->ignore = ign; +} + +static inline void vfsub_args_reinit(struct vfsub_args *vargs) +{ + vargs->nignore = 0; +} + +__u32 vfsub_events_notify_change(struct iattr *ia); +void vfsub_ign_hinode(struct vfsub_args *vargs, __u32 events, + struct au_hinode *hinode); +void vfsub_ignore(struct vfsub_args *vargs); +void vfsub_unignore(struct vfsub_args *vargs); +#else +static inline +void do_vfsub_args_reinit(struct vfsub_args *vargs, struct au_hin_ignore *ign) +{ + /* empty */ +} + +static inline void vfsub_args_reinit(struct vfsub_args *vargs) +{ + /* empty */ +} + +static inline __u32 vfsub_events_notify_change(struct iattr *ia) +{ + return 0; +} + +static inline void vfsub_ign_hinode(struct vfsub_args *vargs, __u32 events, + struct au_hinode *hinode) +{ + /* empty */ +} + +static inline void vfsub_ignore(struct vfsub_args *vargs) +{ + /* empty */ +} + +static inline void vfsub_unignore(struct vfsub_args *vargs) +{ + /* empty */ +} +#endif /* CONFIG_AUFS_HINOTIFY */ + +void vfsub_args_init(struct vfsub_args *vargs, struct au_hin_ignore *ign, + int dlgt, int force_unlink); + +/* ---------------------------------------------------------------------- */ + +/* inotify_inode_watched() is not exported */ +static inline int au_test_inotify(struct inode *inode) +{ +#ifdef CONFIG_INOTIFY + return !list_empty(&inode->inotify_watches); +#endif + return 0; +} + +/* ---------------------------------------------------------------------- */ + +/* lock subclass for hidden inode */ +/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */ +/* reduce? gave up. */ +enum { + AuLsc_I_Begin = I_MUTEX_QUOTA, /* 4 */ + AuLsc_I_PARENT, /* hidden inode, parent first */ + AuLsc_I_PARENT2, /* copyup dirs */ + AuLsc_I_PARENT3, /* rename with hinotify */ + AuLsc_I_PARENT4, /* ditto */ + AuLsc_I_CHILD, + AuLsc_I_CHILD2, + AuLsc_I_End +}; + +#define IMustLock(i) MtxMustLock(&(i)->i_mutex) + +static inline void vfsub_lock_rename_mutex(struct super_block *sb) +{ + lockdep_off(); + mutex_lock(&sb->s_vfs_rename_mutex); + lockdep_on(); +} + +static inline void vfsub_unlock_rename_mutex(struct super_block *sb) +{ + lockdep_off(); + mutex_unlock(&sb->s_vfs_rename_mutex); + lockdep_on(); +} + +static inline +struct dentry *vfsub_lock_rename(struct dentry *d1, struct dentry *d2) +{ + struct dentry *d; + + lockdep_off(); + d = lock_rename(d1, d2); + lockdep_on(); + return d; +} + +static inline void vfsub_unlock_rename(struct dentry *d1, struct dentry *d2) +{ + lockdep_off(); + unlock_rename(d1, d2); + lockdep_on(); +} + +static inline int au_verify_parent(struct dentry *dentry, struct inode *dir) +{ + IMustLock(dir); + return (/* !dir->i_nlink || */ dentry->d_parent->d_inode != dir); +} + +/* ---------------------------------------------------------------------- */ + +#ifdef CONFIG_AUFS_WORKAROUND_FUSE +/* br_fuse.c */ +int au_update_fuse_h_inode(struct vfsmount *h_mnt, struct dentry *h_dentry); +#else +static inline +int au_update_fuse_h_inode(struct vfsmount *h_mnt, struct dentry *h_dentry) +{ + return 0; +} +#endif + +#ifdef CONFIG_AUFS_BR_XFS +/* br_xfs.c */ +dev_t au_h_rdev(struct inode *h_inode, struct vfsmount *h_mnt, + struct dentry *h_dentry); +#else +static inline +dev_t au_h_rdev(struct inode *h_inode, struct vfsmount *h_mnt, + struct dentry *h_dentry) +{ + return h_inode->i_rdev; +} +#endif + +/* simple abstractions, for future use */ +static inline +int do_vfsub_permission(struct inode *inode, int mask, struct nameidata *nd) +{ + LKTRTrace("i%lu, mask 0x%x, nd %d\n", inode->i_ino, mask, !!nd); + IMustLock(inode); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) + return inode_permission(inode, mask); +#else + return permission(inode, mask, nd); +#endif +} + +static inline +int vfsub_security_inode_permission(struct inode *inode, int mask, + struct nameidata *nd) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) + return security_inode_permission(inode, mask); +#else + return security_inode_permission(inode, mask, nd); +#endif +} + +/* ---------------------------------------------------------------------- */ + +struct file *vfsub_filp_open(const char *path, int oflags, int mode); +int vfsub_path_lookup(const char *name, unsigned int flags, + struct nameidata *nd); +struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent, + int len); + +#ifdef CONFIG_AUFS_LHASH_PATCH +struct dentry *vfsub__lookup_hash(struct qstr *name, struct dentry *parent, + struct nameidata *nd); +#endif + +/* ---------------------------------------------------------------------- */ + +int do_vfsub_create(struct inode *dir, struct dentry *dentry, int mode, + struct nameidata *nd); +int do_vfsub_symlink(struct inode *dir, struct dentry *dentry, + const char *symname, int mode); +int do_vfsub_mknod(struct inode *dir, struct dentry *dentry, int mode, + dev_t dev); +int do_vfsub_link(struct dentry *src_dentry, struct inode *dir, + struct dentry *dentry); +int do_vfsub_rename(struct inode *src_dir, struct dentry *src_dentry, + struct inode *dir, struct dentry *dentry); +int do_vfsub_mkdir(struct inode *dir, struct dentry *dentry, int mode); +int do_vfsub_rmdir(struct inode *dir, struct dentry *dentry); +int do_vfsub_unlink(struct inode *dir, struct dentry *dentry); + +/* ---------------------------------------------------------------------- */ + +ssize_t do_vfsub_read_u(struct file *file, char __user *ubuf, size_t count, + loff_t *ppos); +/* todo: kernel_read()? */ +ssize_t do_vfsub_read_k(struct file *file, void *kbuf, size_t count, + loff_t *ppos); +ssize_t do_vfsub_write_u(struct file *file, const char __user *ubuf, + size_t count, loff_t *ppos); +ssize_t do_vfsub_write_k(struct file *file, void *kbuf, size_t count, + loff_t *ppos); +int do_vfsub_readdir(struct file *file, filldir_t filldir, void *arg); + +/* ---------------------------------------------------------------------- */ + +#ifndef CONFIG_AUFS_UNIONFS22_PATCH +static inline void vfsub_copy_inode_size(struct inode *inode, + struct inode *h_inode) +{ + spin_lock(&inode->i_lock); + fsstack_copy_inode_size(inode, h_inode); + spin_unlock(&inode->i_lock); +} +#else +static inline void vfsub_copy_inode_size(struct inode *inode, + struct inode *h_inode) +{ + fsstack_copy_inode_size(inode, h_inode); +} +#endif + +#ifndef CONFIG_AUFS_UNIONFS23_PATCH +#define vfs_splice_to do_splice_to +#define vfs_splice_from do_splice_from +#endif + +#ifdef CONFIG_AUFS_SPLICE_PATCH +long do_vfsub_splice_to(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags); +long do_vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags); +#else +static inline +long do_vfsub_splice_to(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags) +{ + return -ENOSYS; +} + +static inline +long do_vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags) +{ + return -ENOSYS; +} +#endif /* CONFIG_AUFS_SPLICE_PATCH */ + +/* ---------------------------------------------------------------------- */ + +static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin) +{ + loff_t err; + + LKTRTrace("%.*s\n", AuDLNPair(file->f_dentry)); + + lockdep_off(); + err = vfs_llseek(file, offset, origin); + lockdep_on(); + return err; +} + +static inline int do_vfsub_getattr(struct vfsmount *mnt, struct dentry *dentry, + struct kstat *st) +{ + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + return vfs_getattr(mnt, dentry, st); +} + +/* ---------------------------------------------------------------------- */ + +#ifdef CONFIG_AUFS_HIN_OR_DLGT +/* hin_or_dlgt.c */ +int vfsub_permission(struct inode *inode, int mask, struct nameidata *nd, + int dlgt); + +int vfsub_create(struct inode *dir, struct dentry *dentry, int mode, + struct nameidata *nd, struct vfsub_args *vargs); +int vfsub_symlink(struct inode *dir, struct dentry *dentry, const char *symname, + int mode, struct vfsub_args *vargs); +int vfsub_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev, + struct vfsub_args *vargs); +int vfsub_link(struct dentry *src_dentry, struct inode *dir, + struct dentry *dentry, struct vfsub_args *vargs); +int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry, + struct inode *dir, struct dentry *dentry, + struct vfsub_args *vargs); +int vfsub_mkdir(struct inode *dir, struct dentry *dentry, int mode, + struct vfsub_args *vargs); +int vfsub_rmdir(struct inode *dir, struct dentry *dentry, + struct vfsub_args *vargs); + +ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count, + loff_t *ppos, int dlgt); +ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count, loff_t *ppos, + int dlgt); +ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count, + loff_t *ppos, struct vfsub_args *vargs); +ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos, + struct vfsub_args *vargs); +int vfsub_readdir(struct file *file, filldir_t filldir, void *arg, int dlgt); +long vfsub_splice_to(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags, int dlgt); +long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags, + struct vfsub_args *vargs); + +int vfsub_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *st, + int dlgt); +#else + +static inline +int vfsub_permission(struct inode *inode, int mask, struct nameidata *nd, + int dlgt) +{ + return do_vfsub_permission(inode, mask, nd); +} + +static inline +int vfsub_create(struct inode *dir, struct dentry *dentry, int mode, + struct nameidata *nd, struct vfsub_args *vargs) +{ + return do_vfsub_create(dir, dentry, mode, nd); +} + +static inline +int vfsub_symlink(struct inode *dir, struct dentry *dentry, const char *symname, + int mode, struct vfsub_args *vargs) +{ + return do_vfsub_symlink(dir, dentry, symname, mode); +} + +static inline +int vfsub_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev, + struct vfsub_args *vargs) +{ + return do_vfsub_mknod(dir, dentry, mode, dev); +} + +static inline +int vfsub_link(struct dentry *src_dentry, struct inode *dir, + struct dentry *dentry, struct vfsub_args *vargs) +{ + return do_vfsub_link(src_dentry, dir, dentry); +} + +static inline +int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry, + struct inode *dir, struct dentry *dentry, + struct vfsub_args *vargs) +{ + return do_vfsub_rename(src_dir, src_dentry, dir, dentry); +} + +static inline +int vfsub_mkdir(struct inode *dir, struct dentry *dentry, int mode, + struct vfsub_args *vargs) +{ + return do_vfsub_mkdir(dir, dentry, mode); +} + +static inline +int vfsub_rmdir(struct inode *dir, struct dentry *dentry, + struct vfsub_args *vargs) +{ + return do_vfsub_rmdir(dir, dentry); +} + +static inline +ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count, + loff_t *ppos, int dlgt) +{ + return do_vfsub_read_u(file, ubuf, count, ppos); +} + +static inline +ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count, loff_t *ppos, + int dlgt) +{ + return do_vfsub_read_k(file, kbuf, count, ppos); +} + +static inline +ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count, + loff_t *ppos, struct vfsub_args *vargs) +{ + return do_vfsub_write_u(file, ubuf, count, ppos); +} + +static inline +ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos, + struct vfsub_args *vargs) +{ + return do_vfsub_write_k(file, kbuf, count, ppos); +} + +static inline +int vfsub_readdir(struct file *file, filldir_t filldir, void *arg, int dlgt) +{ + return do_vfsub_readdir(file, filldir, arg); +} + +static inline +long vfsub_splice_to(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags, int dlgt) +{ + return do_vfsub_splice_to(in, ppos, pipe, len, flags); +} + +static inline +long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags, + struct vfsub_args *vargs) +{ + return do_vfsub_splice_from(pipe, out, ppos, len, flags); +} + +static inline +int vfsub_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *st, + int dlgt) +{ + return do_vfsub_getattr(mnt, dentry, st); +} +#endif /* HIN_OR_DLGT */ + +/* ---------------------------------------------------------------------- */ + +int vfsub_sio_mkdir(struct au_hinode *hdir, struct dentry *dentry, int mode, + int dlgt); +int vfsub_sio_rmdir(struct au_hinode *hdir, struct dentry *dentry, int dlgt); +int vfsub_sio_notify_change(struct au_hinode *hdir, struct dentry *dentry, + struct iattr *ia); + +/* ---------------------------------------------------------------------- */ + +int vfsub_notify_change(struct dentry *dentry, struct iattr *ia, + struct vfsub_args *vargs); +int vfsub_unlink(struct inode *dir, struct dentry *dentry, + struct vfsub_args *vargs); +int vfsub_statfs(void *arg, struct kstatfs *buf, int dlgt); + +#endif /* __KERNEL__ */ +#endif /* __AUFS_VFSUB_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/branch.h +++ linux-2.6.28/ubuntu/aufs/branch.h @@ -0,0 +1,393 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * branch filesystems and xino for them + * + * $Id: branch.h,v 1.12 2008/09/15 03:14:03 sfjro Exp $ + */ + +#ifndef __AUFS_BRANCH_H__ +#define __AUFS_BRANCH_H__ + +#ifdef __KERNEL__ + +#include +#include +#include +#include +#include "misc.h" +#include "super.h" + +/* ---------------------------------------------------------------------- */ + +/* an entry in a xino file */ +struct au_xino_entry { + ino_t ino; + /* __u32 h_gen; */ /* reserved for future use */ +} __packed; + +/* reserved for future use */ +/* #define AuXino_INVALID_HGEN (-1) */ + +/* a xino file */ +struct au_xino_file { + struct file *xi_file; + struct mutex xi_nondir_mtx; + + /* reserved for future use */ +#if 0 + struct file **xi_file; + + /* array management */ + unsigned long long xi_limit; /* Max xino file size */ + unsigned long long xi_size; /* s_maxbytes */ + + /* truncation */ + unsigned long long xi_upper; /* watermark in bytes */ + unsigned long long xi_step; /* to next watermark in bytes */ + + /* truncation */ + blkcnt_t xi_upper; /* watermark in blocks */ + atomic_t xi_running; +#endif +}; + +/* members for writable branch only */ +enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_TMP, AuBrWh_Last}; +struct au_wbr { + struct au_rwsem wbr_wh_rwsem; + struct dentry *wbr_wh[AuBrWh_Last]; + atomic_t wbr_wh_running; +#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */ +#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */ +#define wbr_tmp wbr_wh[AuBrWh_TMP] /* temporary dir */ + + /* mfs mode */ + unsigned long long wbr_bytes; +}; + +/* protected by superblock rwsem */ +struct au_branch { + struct au_xino_file br_xino; + + aufs_bindex_t br_id; + + int br_perm; + struct vfsmount *br_mnt; + atomic_t br_count; + + struct au_wbr *br_wbr; + +#if 1 /* reserved for future use */ + /* xino truncation */ + blkcnt_t br_xino_upper; /* watermark in blocks */ + atomic_t br_xino_running; +#endif + +#ifdef CONFIG_SYSFS + /* an entry under sysfs per mount-point */ + char br_name[8]; + struct attribute br_attr; +#endif + + au_gen_t br_generation; +}; + +/* ---------------------------------------------------------------------- */ + +/* branch permission and attribute */ +enum { + AuBrPerm_RW, /* writable, linkable wh */ + AuBrPerm_RO, /* readonly, no wh */ + AuBrPerm_RR, /* natively readonly, no wh */ + + AuBrPerm_RWNoLinkWH, /* un-linkable whiteouts */ + + AuBrPerm_ROWH, + AuBrPerm_RRWH, /* whiteout-able */ + + AuBrPerm_Last +}; + +static inline int au_br_writable(int brperm) +{ + return (brperm == AuBrPerm_RW || brperm == AuBrPerm_RWNoLinkWH); +} + +static inline int au_br_whable(int brperm) +{ + return (brperm == AuBrPerm_RW + || brperm == AuBrPerm_ROWH + || brperm == AuBrPerm_RRWH); +} + +#if 0 /* reserved for future use */ +static inline int au_br_linkable_wh(int brperm) +{ + return (brperm == AuBrPerm_RW); +} +#endif + +static inline int au_br_hinotifyable(int brperm) +{ +#ifdef CONFIG_AUFS_HINOTIFY + return (brperm != AuBrPerm_RR && brperm != AuBrPerm_RRWH); +#else + return 0; +#endif +} + +/* ---------------------------------------------------------------------- */ + +/* branch.c */ +struct au_sbinfo; +void au_br_free(struct au_sbinfo *sinfo); +int au_test_def_rr(struct super_block *h_sb); +int au_br_index(struct super_block *sb, aufs_bindex_t br_id); +struct au_opt_add; +int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount); +struct au_opt_del; +int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount); +struct au_opt_mod; +int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount, + int *do_update); + +/* xino.c */ +#define Au_LOFF_MAX ((loff_t)LLONG_MAX) +int au_xib_trunc(struct super_block *sb); +ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size, + loff_t *pos); +ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size, + loff_t *pos); +struct file *au_xino_create(struct super_block *sb, char *fname, int silent); +struct file *au_xino_create2(struct super_block *sb, struct file *base_file, + struct file *copy_src); +ino_t au_xino_new_ino(struct super_block *sb); +int au_xino_write0(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, + ino_t ino); +int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, + struct au_xino_entry *xinoe); +int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, + struct au_xino_entry *xinoe); +int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino, + struct file *base_file, int do_test); +int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex); + +struct au_opt_xino; +int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount); +void au_xino_clr(struct super_block *sb); +struct file *au_xino_def(struct super_block *sb); + +struct au_opt_xinodir; +#if 0 /* def CONFIG_AUFS_EXPORT */ /* reserved for future use */ +/* export.c */ +int au_xinodir_br(struct super_block *sb, struct au_branch *br, ino_t hino, + int do_test); +int au_xinodir_set(struct super_block *sb, struct au_opt_xinodir *xinodir, + int remount); +#else +static inline +int au_xinodir_br(struct super_block *sb, struct au_branch *br, ino_t hino, + int do_test) +{ + return 0; +} + +static inline +int au_xinodir_set(struct super_block *sb, struct au_opt_xinodir *xinodir, + int remount) +{ + return 0; +} +#endif + +/* ---------------------------------------------------------------------- */ + +/* todo: memory barrier? */ +static inline int au_br_count(struct au_branch *br) +{ + return atomic_read(&br->br_count); +} + +static inline int au_br_get(struct au_branch *br) +{ + return atomic_inc_return(&br->br_count); +} + +static inline int au_br_put(struct au_branch *br) +{ + return atomic_dec_return(&br->br_count); +} + +static inline au_gen_t au_br_gen(struct au_branch *br) +{ + return br->br_generation; +} + +/* + * test if the @br is readonly or not. + */ +static inline int au_br_rdonly(struct au_branch *br) +{ + return ((br->br_mnt->mnt_sb->s_flags & MS_RDONLY) + || !au_br_writable(br->br_perm)) + ? -EROFS : 0; +} + +/* ---------------------------------------------------------------------- */ + +/* Superblock to branch */ +static inline +aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex) +{ + return au_sbr(sb, bindex)->br_id; +} + +static inline +struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex) +{ + return au_sbr(sb, bindex)->br_mnt; +} + +static inline +struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex) +{ + return au_sbr_mnt(sb, bindex)->mnt_sb; +} + +#if 0 /* reserved for future use */ +static inline int au_sbr_count(struct super_block *sb, aufs_bindex_t bindex) +{ + return au_br_count(au_sbr(sb, bindex)); +} + +static inline void au_sbr_get(struct super_block *sb, aufs_bindex_t bindex) +{ + au_br_get(au_sbr(sb, bindex)); +} +#endif + +static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex) +{ + au_br_put(au_sbr(sb, bindex)); +} + +static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex) +{ + return au_sbr(sb, bindex)->br_perm; +} + +static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex) +{ + return au_br_whable(au_sbr_perm(sb, bindex)); +} + +static inline int au_test_trunc_xino(struct super_block *sb) +{ + return au_test_tmpfs(sb); +} + +/* temporary support for i#1 in cramfs */ +static inline int au_test_unique_ino(struct dentry *h_dentry, ino_t h_ino) +{ +#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE) + if (unlikely(h_dentry->d_sb->s_magic == CRAMFS_MAGIC)) + return (h_ino != 1); +#endif + return 1; +} + +static inline struct vfsmount *au_do_nfsmnt(struct vfsmount *h_mnt) +{ + if (!au_test_nfs(h_mnt->mnt_sb)) + return NULL; + return h_mnt; +} + +static inline void au_br_nfs_lockdep_off(struct super_block *sb) +{ + if (au_test_nfs(sb)) + lockdep_off(); +} + +static inline void au_br_nfs_lockdep_on(struct super_block *sb) +{ + /* hoping this condition will be optimized... */ + if (au_test_nfs(sb)) + lockdep_on(); +} + +#ifdef CONFIG_AUFS_BR_NFS +static inline int au_test_unsupported_nfs(struct super_block *h_sb) +{ + return 0; +} + +/* it doesn't mntget() */ +static inline +struct vfsmount *au_nfsmnt(struct super_block *sb, aufs_bindex_t bindex) +{ + return au_do_nfsmnt(au_sbr_mnt(sb, bindex)); +} + +#define AuNoNfsBranchMsg "dummy" + +#else +static inline int au_test_unsupported_nfs(struct super_block *h_sb) +{ + return (h_sb->s_magic == NFS_SUPER_MAGIC); +} + +static inline +struct vfsmount *au_nfsmnt(struct super_block *sb, aufs_bindex_t bindex) +{ + return NULL; +} + +#define AuNoNfsBranchMsg "NFS branch is not supported" \ + ", try some configurations and patches included in aufs source CVS." + +#endif /* CONFIG_AUFS_BR_NFS */ + +/* ---------------------------------------------------------------------- */ + +/* + * br_wh_read_lock, br_wh_write_lock + * br_wh_read_unlock, br_wh_write_unlock, br_wh_downgrade_lock + */ +AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, wbr->wbr_wh_rwsem); + +/* to debug easier, do not make them inlined functions */ +#define WbrWhMustReadLock(wbr) do { \ + /* SiMustAnyLock(sb); */ \ + AuRwMustReadLock(&(wbr)->wbr_wh_rwsem); \ +} while (0) + +#define WbrWhMustWriteLock(wbr) do { \ + /* SiMustAnyLock(sb); */ \ + AuRwMustWriteLock(&(wbr)->wbr_wh_rwsem); \ +} while (0) + +#define WbrWhMustAnyLock(br) do { \ + /* SiMustAnyLock(sb); */ \ + AuRwMustAnyLock(&(wbr)->wbr_wh_rwsem); \ +} while (0) + +#endif /* __KERNEL__ */ +#endif /* __AUFS_BRANCH_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/cpup.h +++ linux-2.6.28/ubuntu/aufs/cpup.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * copy-up/down functions + * + * $Id: cpup.h,v 1.5 2008/09/01 02:54:48 sfjro Exp $ + */ + +#ifndef __AUFS_CPUP_H__ +#define __AUFS_CPUP_H__ + +#ifdef __KERNEL__ + +#include +#include + +void au_cpup_attr_timesizes(struct inode *inode); +void au_cpup_attr_nlink(struct inode *inode); +void au_cpup_attr_changeable(struct inode *inode); +void au_cpup_igen(struct inode *inode, struct inode *h_inode); +void au_cpup_attr_all(struct inode *inode); + +/* ---------------------------------------------------------------------- */ + +/* cpup flags */ +#define AuCpup_DTIME 1 /* do dtime_store/revert */ +#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino, + for link(2) */ +#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name) +#define au_fset_cpup(flags, name) { (flags) |= AuCpup_##name; } +#define au_fclr_cpup(flags, name) { (flags) &= ~AuCpup_##name; } + +int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst, + aufs_bindex_t bsrc, loff_t len, unsigned int flags, + struct dentry *dst_parent); +int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, + unsigned int flags); +int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, + struct file *file); + +int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst, + int (*cp)(struct dentry *dentry, aufs_bindex_t bdst, + struct dentry *h_parent, void *arg), + void *arg); +int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst); +int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst); + +/* ---------------------------------------------------------------------- */ + +/* keep timestamps when copyup */ +struct au_dtime { + struct dentry *dt_dentry, *dt_h_dentry; + struct au_hinode *dt_hinode, *dt_hdir; + struct timespec dt_atime, dt_mtime; +}; +void au_dtime_store(struct au_dtime *dt, struct dentry *dentry, + struct dentry *h_dentry, struct au_hinode *hinode, + struct au_hinode *hdir); +void au_dtime_revert(struct au_dtime *dt); + +#endif /* __KERNEL__ */ +#endif /* __AUFS_CPUP_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/br_fuse.c +++ linux-2.6.28/ubuntu/aufs/br_fuse.c @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * special handling for inode attributes on FUSE branch + * + * $Id: br_fuse.c,v 1.6 2008/07/27 22:49:28 sfjro Exp $ + */ + +#include "aufs.h" + +/* h_mnt can be NULL, is it safe? */ +int au_update_fuse_h_inode(struct vfsmount *h_mnt, struct dentry *h_dentry) +{ + int err; + struct kstat st; + + LKTRTrace("%.*s\n", AuDLNPair(h_dentry)); + + err = 0; + if (unlikely(h_dentry->d_inode + /* && atomic_read(&h_dentry->d_inode->i_count) */ + && au_test_fuse(h_dentry->d_sb))) { + err = vfsub_getattr(h_mnt, h_dentry, &st, /*dlgt*/0); + if (unlikely(err)) { + AuDbg("err %d\n", err); + au_debug_on(); + AuDbgDentry(h_dentry); + au_debug_off(); + WARN_ON(err); + } + } + return err; +} + +#if 0 /* temp */ +/* + * This function was born after a discussion with the FUSE developer. + * The inode attributes on a filesystem who defines i_op->getattr() + * is unreliable since such fs may not maintain the attributes at lookup. + * This function doesn't want the result of stat, instead wants the side-effect + * which refreshes the attributes. + * Hmm, there seems to be no such filesystem except fuse. + */ +int vfsub_i_attr(struct vfsmount *mnt, struct dentry *dentry, int dlgt) +{ + int err; + struct inode *inode; + struct inode_operations *op; + struct kstat st; + + inode = dentry->d_inode; + AuDebugOn(!inode); + + err = 0; + op = inode->i_op; + if (unlikely(op && op->getattr && !au_test_aufs(dentry->d_sb))) { + err = security_inode_getattr(mnt, dentry); + if (!err) + err = op->getattr(mnt, dentry, &st); + } + AuTraceErr(err); + return err; +} +#endif --- linux-2.6.28.orig/ubuntu/aufs/sysaufs.c +++ linux-2.6.28/ubuntu/aufs/sysaufs.c @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * sysfs interface and lifetime management + * they are necessary regardless sysfs is disabled. + * + * $Id: sysaufs.c,v 1.10 2008/09/15 03:14:55 sfjro Exp $ + */ + +#include +#include +#include +#include +#include "aufs.h" + +/* ---------------------------------------------------------------------- */ + +unsigned long au_si_mask; + +/* ---------------------------------------------------------------------- */ + +struct kset *au_kset; + +#define AuSbiAttr(_name) { \ + .attr = { .name = __stringify(_name), .mode = 0444 }, \ + .show = sysaufs_sbi_##_name, \ +} + +static struct au_sbi_attr au_sbi_attr_xino = AuSbiAttr(xino); +#ifdef CONFIG_AUFS_EXPORT +static struct au_sbi_attr au_sbi_attr_xigen = AuSbiAttr(xigen); +#endif +struct attribute *au_sbi_attrs[] = { + &au_sbi_attr_xino.attr, +#ifdef CONFIG_AUFS_EXPORT + &au_sbi_attr_xigen.attr, +#endif + NULL, +}; + +static struct sysfs_ops au_sbi_ops = { + .show = sysaufs_sbi_show +}; + +static struct kobj_type au_sbi_ktype = { + .release = au_si_free, + .sysfs_ops = &au_sbi_ops, + .default_attrs = au_sbi_attrs +}; + +/* ---------------------------------------------------------------------- */ + +int sysaufs_si_init(struct au_sbinfo *sbinfo) +{ + int err; + + sbinfo->si_kobj.kset = au_kset; + /* some people doesn't like to show a pointer in kernel */ + err = kobject_init_and_add(&sbinfo->si_kobj, &au_sbi_ktype, + NULL/*&au_kset->kobj*/, + SysaufsSb_PREFIX "%lx", + au_si_mask ^ (unsigned long)sbinfo); + AuTraceErr(err); + return err; +} + + +/* ---------------------------------------------------------------------- */ + +void sysaufs_fin(void) +{ + sysfs_remove_group(&au_kset->kobj, au_attr_group); + kset_unregister(au_kset); +} + +int __init sysaufs_init(void) +{ + int err; + + get_random_bytes(&au_si_mask, sizeof(au_si_mask)); + + au_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj); + err = PTR_ERR(au_kset); + if (IS_ERR(au_kset)) + goto out; + err = sysfs_create_group(&au_kset->kobj, au_attr_group); + if (unlikely(err)) + kset_unregister(au_kset); + + out: + AuTraceErr(err); + return err; +} --- linux-2.6.28.orig/ubuntu/aufs/debug.c +++ linux-2.6.28/ubuntu/aufs/debug.c @@ -0,0 +1,512 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * debug print functions + * + * $Id: debug.c,v 1.14 2008/09/22 03:52:03 sfjro Exp $ + */ + +#include "aufs.h" + +atomic_t au_cond = ATOMIC_INIT(0); + +char *au_plevel = KERN_DEBUG; +#define dpri(fmt, arg...) do { \ + if (LktrCond) \ + printk("%s" fmt, au_plevel, ##arg); \ +} while (0) + +/* ---------------------------------------------------------------------- */ + +void au_dpri_whlist(struct au_nhash *whlist) +{ + int i; + struct hlist_head *head; + struct au_vdir_wh *tpos; + struct hlist_node *pos; + + for (i = 0; i < AuSize_NHASH; i++) { + head = whlist->heads + i; + hlist_for_each_entry(tpos, pos, head, wh_hash) + dpri("b%d, %.*s, %d\n", + tpos->wh_bindex, + tpos->wh_str.len, tpos->wh_str.name, + tpos->wh_str.len); + } +} + +void au_dpri_vdir(struct au_vdir *vdir) +{ + int i; + union au_vdir_deblk_p p; + unsigned char *o; + + if (!vdir || IS_ERR(vdir)) { + dpri("err %ld\n", PTR_ERR(vdir)); + return; + } + + dpri("nblk %d, deblk %p, last{%d, %p}, ver %lu\n", + vdir->vd_nblk, vdir->vd_deblk, + vdir->vd_last.i, vdir->vd_last.p.p, vdir->vd_version); + for (i = 0; i < vdir->vd_nblk; i++) { + p.deblk = vdir->vd_deblk[i]; + o = p.p; + dpri("[%d]: %p\n", i, o); + } +} + +static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, + struct dentry *wh) +{ + char *n = NULL; + int l = 0, ntfy = 0; + + if (!inode || IS_ERR(inode)) { + dpri("i%d: err %ld\n", bindex, PTR_ERR(inode)); + return -1; + } + + /* the type of i_blocks depends upon CONFIG_LSF */ + BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long) + && sizeof(inode->i_blocks) != sizeof(u64)); + if (wh) { + n = (void *)wh->d_name.name; + l = wh->d_name.len; + } + + ntfy = au_test_inotify(inode); + dpri("i%d: i%lu, %s, cnt %d, nl %u, 0%o, ntfy %d, sz %llu, blk %llu," + " ct %lld, np %lu, st 0x%lx, f 0x%x, g %x%s%.*s\n", + bindex, + inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??", + atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode, + ntfy, + i_size_read(inode), (unsigned long long)inode->i_blocks, + (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff, + inode->i_mapping ? inode->i_mapping->nrpages : 0, + inode->i_state, inode->i_flags, inode->i_generation, + l ? ", wh " : "", l, n); + return 0; +} + +void au_dpri_inode(struct inode *inode) +{ + struct au_iinfo *iinfo; + aufs_bindex_t bindex; + int err; + + err = do_pri_inode(-1, inode, NULL); + if (err || !au_test_aufs(inode->i_sb)) + return; + + iinfo = au_ii(inode); + if (!iinfo) + return; + dpri("i-1: bstart %d, bend %d, gen %d\n", + iinfo->ii_bstart, iinfo->ii_bend, au_iigen(inode)); + if (iinfo->ii_bstart < 0) + return; + for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++) + do_pri_inode(bindex, iinfo->ii_hinode[0 + bindex].hi_inode, + iinfo->ii_hinode[0 + bindex].hi_whdentry); +} + +static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry, + struct list_head *intent) +{ + struct dentry *wh = NULL; + + if (!dentry || IS_ERR(dentry)) { + dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry)); + return -1; + } + /* do not call dget_parent() here */ + dpri("d%d: %.*s?/%.*s, %s, cnt %d, flags 0x%x, intent %d\n", + bindex, + AuDLNPair(dentry->d_parent), AuDLNPair(dentry), + dentry->d_sb ? au_sbtype(dentry->d_sb) : "??", + atomic_read(&dentry->d_count), dentry->d_flags, !!intent); + if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) { + struct au_iinfo *iinfo = au_ii(dentry->d_inode); + if (iinfo) + wh = iinfo->ii_hinode[0 + bindex].hi_whdentry; + } + do_pri_inode(bindex, dentry->d_inode, wh); + return 0; +} + +static struct list_head *au_dbg_h_intent(struct au_dinfo *dinfo, + aufs_bindex_t bindex) +{ +#ifdef CONFIG_AUFS_BR_NFS + return dinfo->di_hdentry[0 + bindex].hd_intent_list; +#else + return NULL; +#endif +} + +void au_dpri_dentry(struct dentry *dentry) +{ + struct au_dinfo *dinfo; + aufs_bindex_t bindex; + int err; + + err = do_pri_dentry(-1, dentry, NULL); + if (err || !au_test_aufs(dentry->d_sb)) + return; + + dinfo = au_di(dentry); + if (!dinfo) + return; + dpri("d-1: bstart %d, bend %d, bwh %d, bdiropq %d, gen %d\n", + dinfo->di_bstart, dinfo->di_bend, + dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry)); + if (dinfo->di_bstart < 0) + return; + for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; bindex++) + do_pri_dentry(bindex, dinfo->di_hdentry[0 + bindex].hd_dentry, + au_dbg_h_intent(dinfo, bindex)); +} + +static int do_pri_file(aufs_bindex_t bindex, struct file *file) +{ + char a[32]; + + if (!file || IS_ERR(file)) { + dpri("f%d: err %ld\n", bindex, PTR_ERR(file)); + return -1; + } + a[0] = 0; + if (bindex < 0 + && file->f_dentry + && au_test_aufs(file->f_dentry->d_sb) + && au_fi(file)) + snprintf(a, sizeof(a), ", mmapped %d", au_test_mmapped(file)); + dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, pos %llu%s\n", + bindex, file->f_mode, file->f_flags, (long)file_count(file), + file->f_pos, a); + if (file->f_dentry) + do_pri_dentry(bindex, file->f_dentry, NULL); + return 0; +} + +void au_dpri_file(struct file *file) +{ + struct au_finfo *finfo; + aufs_bindex_t bindex; + int err; + + err = do_pri_file(-1, file); + if (err || !file->f_dentry || !au_test_aufs(file->f_dentry->d_sb)) + return; + + finfo = au_fi(file); + if (!finfo) + return; + if (finfo->fi_bstart < 0) + return; + for (bindex = finfo->fi_bstart; bindex <= finfo->fi_bend; bindex++) { + struct au_hfile *hf; + hf = finfo->fi_hfile + bindex; + do_pri_file(bindex, hf ? hf->hf_file : NULL); + } +} + +static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br) +{ + struct vfsmount *mnt; + struct super_block *sb; + + if (!br || IS_ERR(br) + || !(mnt = br->br_mnt) || IS_ERR(mnt) + || !(sb = mnt->mnt_sb) || IS_ERR(sb)) { + dpri("s%d: err %ld\n", bindex, PTR_ERR(br)); + return -1; + } + + dpri("s%d: {perm 0x%x, cnt %d, wbr %p}, " + "%s, dev 0x%02x%02x, flags 0x%lx, cnt(BIAS) %d, active %d, " + "xino %d\n", + bindex, br->br_perm, au_br_count(br), br->br_wbr, + au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev), + sb->s_flags, sb->s_count - S_BIAS, + atomic_read(&sb->s_active), !!br->br_xino.xi_file); + return 0; +} + +void au_dpri_sb(struct super_block *sb) +{ + struct au_sbinfo *sbinfo; + aufs_bindex_t bindex; + int err; + /* to reuduce stack size */ + struct { + struct vfsmount mnt; + struct au_branch fake; + } *a; + + /* this function can be called from magic sysrq */ + a = kzalloc(sizeof(*a), GFP_ATOMIC); + if (unlikely(!a)) { + dpri("no memory\n"); + return; + } + + a->mnt.mnt_sb = sb; + a->fake.br_perm = 0; + a->fake.br_mnt = &a->mnt; + a->fake.br_xino.xi_file = NULL; + atomic_set(&a->fake.br_count, 0); + smp_mb(); /* atomic_set */ + err = do_pri_br(-1, &a->fake); + kfree(a); + dpri("dev 0x%x\n", sb->s_dev); + if (err || !au_test_aufs(sb)) + return; + + sbinfo = au_sbi(sb); + if (!sbinfo) + return; + dpri("gen %u\n", sbinfo->si_generation); + for (bindex = 0; bindex <= sbinfo->si_bend; bindex++) + do_pri_br(bindex, sbinfo->si_branch[0 + bindex]); +} + +/* ---------------------------------------------------------------------- */ + +void au_dbg_sleep(int sec) +{ + static DECLARE_WAIT_QUEUE_HEAD(wq); + wait_event_timeout(wq, 0, sec * HZ); +} + +void au_dbg_sleep_jiffy(int jiffy) +{ + static DECLARE_WAIT_QUEUE_HEAD(wq); + wait_event_timeout(wq, 0, jiffy); +} + +void au_dbg_iattr(struct iattr *ia) +{ +#define AuBit(name) if (ia->ia_valid & ATTR_ ## name) dpri(#name "\n") + AuBit(MODE); + AuBit(UID); + AuBit(GID); + AuBit(SIZE); + AuBit(ATIME); + AuBit(MTIME); + AuBit(CTIME); + AuBit(ATIME_SET); + AuBit(MTIME_SET); + AuBit(FORCE); + AuBit(ATTR_FLAG); + AuBit(KILL_SUID); + AuBit(KILL_SGID); + AuBit(FILE); + AuBit(KILL_PRIV); + AuBit(OPEN); + AuBit(TIMES_SET); +#undef AuBit + dpri("ia_file %p\n", ia->ia_file); +} + +/* ---------------------------------------------------------------------- */ + +void au_debug_sbinfo_init(struct au_sbinfo *sbinfo) +{ +#ifdef ForceInotify + au_opt_set_udba(sbinfo->si_mntflags, UDBA_INOTIFY); +#endif +#ifdef ForceDlgt + au_opt_set(sbinfo->si_mntflags, DLGT); +#endif +#ifdef ForceNoPlink + au_opt_clr(sbinfo->si_mntflags, PLINK); +#endif +#ifdef ForceNoXino + au_opt_clr(sbinfo->si_mntflags, XINO); +#endif +#ifdef ForceNoRefrof + au_opt_clr(sbinfo->si_mntflags, REFROF); +#endif +#ifdef ForceShwh + au_opt_set(sbinfo->si_mntflags, SHWH); +#endif +} + +int __init au_debug_init(void) +{ + aufs_bindex_t bindex; + struct au_vdir_destr destr; + + bindex = -1; + AuDebugOn(bindex >= 0); + + destr.len = -1; + AuDebugOn(destr.len < NAME_MAX); + +#ifdef CONFIG_4KSTACKS + AuWarn("CONFIG_4KSTACKS is defined.\n"); +#endif + +#ifdef ForceBrs + sysaufs_brs = 1; +#endif + +#if 0 /* verbose debug */ + { + union { + struct au_branch *br; + struct au_dinfo *di; + struct au_finfo *fi; + struct au_iinfo *ii; + struct au_hinode *hi; + struct au_sbinfo *si; + struct au_vdir_destr *destr; + struct au_vdir_de *de; + struct au_vdir_wh *wh; + struct au_vdir *vd; + } u; + + pr_info("br{" + "xino %d, " + "id %d, perm %d, mnt %d, count %d, " + "wbr %d, " + "xup %d, xrun %d, " + "gen %d, " + "sa %d} %d\n", + offsetof(typeof(*u.br), br_xino), + offsetof(typeof(*u.br), br_id), + offsetof(typeof(*u.br), br_perm), + offsetof(typeof(*u.br), br_mnt), + offsetof(typeof(*u.br), br_count), + offsetof(typeof(*u.br), wbr), + offsetof(typeof(*u.br), br_xino_upper), + offsetof(typeof(*u.br), br_xino_running), + offsetof(typeof(*u.br), br_generation), + offsetof(typeof(*u.br), br_sabr), + sizeof(*u.br)); + pr_info("di{gen %d, rwsem %d, bstart %d, bend %d, bwh %d, " + "bdiropq %d, hdentry %d} %d\n", + offsetof(typeof(*u.di), di_generation), + offsetof(typeof(*u.di), di_rwsem), + offsetof(typeof(*u.di), di_bstart), + offsetof(typeof(*u.di), di_bend), + offsetof(typeof(*u.di), di_bwh), + offsetof(typeof(*u.di), di_bdiropq), + offsetof(typeof(*u.di), di_hdentry), + sizeof(*u.di)); + pr_info("fi{gen %d, rwsem %d, hfile %d, bstart %d, bend %d, " + "h_vm_ops %d, vdir_cach %d} %d\n", + offsetof(typeof(*u.fi), fi_generation), + offsetof(typeof(*u.fi), fi_rwsem), + offsetof(typeof(*u.fi), fi_hfile), + offsetof(typeof(*u.fi), fi_bstart), + offsetof(typeof(*u.fi), fi_bend), + offsetof(typeof(*u.fi), fi_h_vm_ops), + offsetof(typeof(*u.fi), fi_vdir_cache), + sizeof(*u.fi)); + pr_info("ii{gen %d, hsb %d, " + "rwsem %d, bstart %d, bend %d, hinode %d, vdir %d} " + "%d\n", + offsetof(typeof(*u.ii), ii_generation), + offsetof(typeof(*u.ii), ii_hsb1), + offsetof(typeof(*u.ii), ii_rwsem), + offsetof(typeof(*u.ii), ii_bstart), + offsetof(typeof(*u.ii), ii_bend), + offsetof(typeof(*u.ii), ii_hinode), + offsetof(typeof(*u.ii), ii_vdir), + sizeof(*u.ii)); + pr_info("hi{inode %d, id %d, notify %d, wh %d} %d\n", + offsetof(typeof(*u.hi), hi_inode), + offsetof(typeof(*u.hi), hi_id), + offsetof(typeof(*u.hi), hi_notify), + offsetof(typeof(*u.hi), hi_whdentry), + sizeof(*u.hi)); + pr_info("si{nwt %d, rwsem %d, gen %d, stat %d, " + "bend %d, last id %d, br %d, " + "cpup %d, creat %d, ops %d, ops %d, " + "rr %d, mfs %d, " + "mntflags %d, " + "xread %d, xwrite %d, xib %d, xmtx %d, buf %d, " + "xlast %d, xnext %d, " + "rdcache %d, " + "dirwh %d, " + "pl_lock %d, pl %d, " + "mnt %d, " + "sys %d, " + /* "lvma_l %d, lvma %d" */ + "} %d\n", + offsetof(typeof(*u.si), si_nowait), + offsetof(typeof(*u.si), si_rwsem), + offsetof(typeof(*u.si), si_generation), + offsetof(typeof(*u.si), au_si_status), + offsetof(typeof(*u.si), si_bend), + offsetof(typeof(*u.si), si_last_br_id), + offsetof(typeof(*u.si), si_branch), + offsetof(typeof(*u.si), si_wbr_copyup), + offsetof(typeof(*u.si), si_wbr_create), + offsetof(typeof(*u.si), si_wbr_copyup_ops), + offsetof(typeof(*u.si), si_wbr_create_ops), + offsetof(typeof(*u.si), si_wbr_rr_next), + offsetof(typeof(*u.si), si_wbr_mfs), + offsetof(typeof(*u.si), si_mntflags), + offsetof(typeof(*u.si), si_xread), + offsetof(typeof(*u.si), si_xwrite), + offsetof(typeof(*u.si), si_xib), + offsetof(typeof(*u.si), si_xib_mtx), + offsetof(typeof(*u.si), si_xib_buf), + offsetof(typeof(*u.si), si_xib_last_pindex), + offsetof(typeof(*u.si), si_xib_next_bit), + offsetof(typeof(*u.si), si_rdcache), + offsetof(typeof(*u.si), si_dirwh), + offsetof(typeof(*u.si), si_plink_lock), + offsetof(typeof(*u.si), si_plink), + offsetof(typeof(*u.si), si_mnt), + offsetof(typeof(*u.si), si_sa), + /*offsetof(typeof(*u.si), si_lvma_lock), + offsetof(typeof(*u.si), si_lvma),*/ + sizeof(*u.si)); + pr_info("destr{len %d, name %d} %d\n", + offsetof(typeof(*u.destr), len), + offsetof(typeof(*u.destr), name), + sizeof(*u.destr)); + pr_info("de{ino %d, type %d, str %d} %d\n", + offsetof(typeof(*u.de), de_ino), + offsetof(typeof(*u.de), de_type), + offsetof(typeof(*u.de), de_str), + sizeof(*u.de)); + pr_info("wh{hash %d, bindex %d, str %d} %d\n", + offsetof(typeof(*u.wh), wh_hash), + offsetof(typeof(*u.wh), wh_bindex), + offsetof(typeof(*u.wh), wh_str), + sizeof(*u.wh)); + pr_info("vd{deblk %d, nblk %d, last %d, ver %d, jiffy %d} %d\n", + offsetof(typeof(*u.vd), vd_deblk), + offsetof(typeof(*u.vd), vd_nblk), + offsetof(typeof(*u.vd), vd_last), + offsetof(typeof(*u.vd), vd_version), + offsetof(typeof(*u.vd), vd_jiffy), + sizeof(*u.vd)); + } +#endif + + return 0; +} --- linux-2.6.28.orig/ubuntu/aufs/dir.h +++ linux-2.6.28/ubuntu/aufs/dir.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * directory operations + * + * $Id: dir.h,v 1.3 2008/05/26 04:04:23 sfjro Exp $ + */ + +#ifndef __AUFS_DIR_H__ +#define __AUFS_DIR_H__ + +#ifdef __KERNEL__ + +#include +#include + +/* ---------------------------------------------------------------------- */ + +/* need to be faster and smaller */ + +/* todo: changeable? */ +#define AuSize_DEBLK 512 +#define AuSize_NHASH 32 +#if AuSize_DEBLK < NAME_MAX || PAGE_SIZE < AuSize_DEBLK +#error invalid size AuSize_DEBLK +#endif + +typedef char au_vdir_deblk_t[AuSize_DEBLK]; + +struct au_nhash { + struct hlist_head heads[AuSize_NHASH]; +}; + +struct au_vdir_destr { + unsigned char len; + char name[0]; +} __packed; + +struct au_vdir_dehstr { + struct hlist_node hash; + struct au_vdir_destr *str; +}; + +struct au_vdir_de { + ino_t de_ino; + unsigned char de_type; + /* caution: packed */ + struct au_vdir_destr de_str; +} __packed; + +struct au_vdir_wh { + struct hlist_node wh_hash; + aufs_bindex_t wh_bindex; +#ifdef CONFIG_AUFS_SHWH + ino_t wh_ino; + unsigned char wh_type; + /* caution: packed */ +#endif + struct au_vdir_destr wh_str; +} __packed; + +union au_vdir_deblk_p { + unsigned char *p; + au_vdir_deblk_t *deblk; + struct au_vdir_de *de; +}; + +struct au_vdir { + au_vdir_deblk_t **vd_deblk; + int vd_nblk; + struct { + int i; + union au_vdir_deblk_p p; + } vd_last; + + unsigned long vd_version; + unsigned long vd_jiffy; +}; + +/* ---------------------------------------------------------------------- */ + +/* dir.c */ +extern struct file_operations aufs_dir_fop; +int au_test_empty_lower(struct dentry *dentry); +int au_test_empty(struct dentry *dentry, struct au_nhash *whlist); + +/* vdir.c */ +struct au_nhash *au_nhash_new(gfp_t gfp); +void au_nhash_del(struct au_nhash *nhash); +void au_nhash_init(struct au_nhash *nhash); +void au_nhash_move(struct au_nhash *dst, struct au_nhash *src); +void au_nhash_fin(struct au_nhash *nhash); +int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt, + int limit); +int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int namelen); +int au_nhash_append_wh(struct au_nhash *whlist, char *name, int namelen, + ino_t ino, unsigned int d_type, aufs_bindex_t bindex, + unsigned char shwh); +void au_vdir_free(struct au_vdir *vdir); +int au_vdir_init(struct file *file); +int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir); + +/* ---------------------------------------------------------------------- */ + +static inline +void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino, unsigned char d_type) +{ +#ifdef CONFIG_AUFS_SHWH + wh->wh_ino = ino; + wh->wh_type = d_type; +#endif +} + +static inline void au_add_nlink(struct inode *dir, struct inode *h_dir) +{ + AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode)); + dir->i_nlink += h_dir->i_nlink - 2; + if (unlikely(h_dir->i_nlink < 2)) + dir->i_nlink += 2; +} + +static inline void au_sub_nlink(struct inode *dir, struct inode *h_dir) +{ + AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode)); + dir->i_nlink -= h_dir->i_nlink - 2; + if (unlikely(h_dir->i_nlink < 2)) + dir->i_nlink -= 2; +} + +#endif /* __KERNEL__ */ +#endif /* __AUFS_DIR_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/super.h +++ linux-2.6.28/ubuntu/aufs/super.h @@ -0,0 +1,494 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * super_block operations + * + * $Id: super.h,v 1.14 2008/09/15 03:14:52 sfjro Exp $ + */ + +#ifndef __AUFS_SUPER_H__ +#define __AUFS_SUPER_H__ + +#ifdef __KERNEL__ + +#include +#include +#include +#include +#include +#include "misc.h" +#include "wkq.h" + +typedef ssize_t (*au_readf_t)(struct file *, char __user *, size_t, loff_t *); +typedef ssize_t (*au_writef_t)(struct file *, const char __user *, size_t, + loff_t *); + +struct au_wbr_copyup_operations { + int (*copyup)(struct dentry *dentry); +}; + +struct au_wbr_create_operations { + int (*create)(struct dentry *dentry, int isdir); + int (*init)(struct super_block *sb); + int (*fin)(struct super_block *sb); +}; + +struct au_wbr_mfs { + struct mutex mfs_lock; /* protect this structure */ + unsigned long mfs_jiffy; + unsigned long mfs_expire; + aufs_bindex_t mfs_bindex; + + unsigned long long mfsrr_bytes; + unsigned long long mfsrr_watermark; +}; + +/* sbinfo status flags */ +/* + * set true when refresh_dirs() failed at remount time. + * then try refreshing dirs at access time again. + * if it is false, refreshing dirs at access time is unnecesary + */ +#define AuSi_FAILED_REFRESH_DIRS 1 +#define au_ftest_si(sbinfo, name) ((sbinfo)->au_si_status & AuSi_##name) +#define au_fset_si(sbinfo, name) \ + { (sbinfo)->au_si_status |= AuSi_##name; } +#define au_fclr_si(sbinfo, name) \ + { (sbinfo)->au_si_status &= ~AuSi_##name; } + +struct au_branch; +struct au_sbinfo { + /* nowait tasks in the system-wide workqueue */ + struct au_nowait_tasks si_nowait; + + struct au_rwsem si_rwsem; + + /* branch management */ + au_gen_t si_generation; + + /* see above flags */ + unsigned char au_si_status; + + aufs_bindex_t si_bend; + aufs_bindex_t si_last_br_id; + struct au_branch **si_branch; + + /* policy to select a writable branch */ + unsigned char si_wbr_copyup; + unsigned char si_wbr_create; + struct au_wbr_copyup_operations *si_wbr_copyup_ops; + struct au_wbr_create_operations *si_wbr_create_ops; + + /* round robin */ + atomic_t si_wbr_rr_next; + + /* most free space */ + struct au_wbr_mfs si_wbr_mfs; + + /* mount flags */ + /* include/asm-ia64/siginfo.h defines a macro named si_flags */ + unsigned int si_mntflags; + + /* external inode number (bitmap and translation table) */ + au_readf_t si_xread; + au_writef_t si_xwrite; + struct file *si_xib; + struct mutex si_xib_mtx; /* protect xib members */ + unsigned long *si_xib_buf; + unsigned long si_xib_last_pindex; + int si_xib_next_bit; + /* reserved for future use */ + /* unsigned long long si_xib_limit; */ /* Max xib file size */ + +#ifdef CONFIG_AUFS_HINOTIFY + struct au_branch *si_xino_def_br; +#endif + +#ifdef CONFIG_AUFS_EXPORT + /* i_generation */ + struct file *si_xigen; + /* todo: atomic_t? */ + spinlock_t si_xigen_lock; + __u32 si_xigen_next; +#endif + + /* readdir cache time, max, in HZ */ + unsigned long si_rdcache; + + /* + * If the number of whiteouts are larger than si_dirwh, leave all of + * them after au_whtmp_ren to reduce the cost of rmdir(2). + * future fsck.aufs or kernel thread will remove them later. + * Otherwise, remove all whiteouts and the dir in rmdir(2). + */ + unsigned int si_dirwh; + + /* + * rename(2) a directory with all children. + */ + /* reserved for future use */ + /* int si_rendir; */ + + /* pseudo_link list */ /* todo: dirty? */ + spinlock_t si_plink_lock; + struct list_head si_plink; + +#if defined(CONFIG_AUFS_EXPORT) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) + /* dirty, for export, async ops, and sysfs */ + spinlock_t si_mntcache_lock; + struct vfsmount *si_mntcache; /* no get/put */ +#endif + + /* + * sysfs and lifetime management. + * this is not a small structure and it may be a waste of memory in case + * of sysfs is disabled, particulary when many aufs-es are mounted. + */ + struct kobject si_kobj; + +#ifdef CONFIG_AUFS_ROBR + /* locked vma list for mmap() */ /* todo: dirty? */ + spinlock_t si_lvma_lock; + struct list_head si_lvma; +#endif + +#ifdef CONFIG_AUFS_EXPORT /* reserved for future use */ + struct path si_xinodir; +#endif + + /* dirty, necessary for unmounting, sysfs and sysrq */ + struct super_block *si_sb; +}; + +/* ---------------------------------------------------------------------- */ + +/* policy to select one among writable branches */ +#define AuWbrCopyup(sbinfo, args...) \ + (sbinfo)->si_wbr_copyup_ops->copyup(args) +#define AuWbrCreate(sbinfo, args...) \ + (sbinfo)->si_wbr_create_ops->create(args) + +/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */ +#define AuLock_DW 1 /* write-lock dentry */ +#define AuLock_IR (1 << 1) /* read-lock inode */ +#define AuLock_IW (1 << 2) /* write-lock inode */ +#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */ +#define AuLock_DIR (1 << 4) /* target is a dir */ +#define au_ftest_lock(flags, name) ((flags) & AuLock_##name) +#define au_fset_lock(flags, name) { (flags) |= AuLock_##name; } +#define au_fclr_lock(flags, name) { (flags) &= ~AuLock_##name; } + +/* ---------------------------------------------------------------------- */ + +/* super.c */ +extern struct file_system_type aufs_fs_type; +struct inode *au_iget_locked(struct super_block *sb, ino_t ino); + +/* sbinfo.c */ +void au_si_free(struct kobject *kobj); +int au_si_alloc(struct super_block *sb); +struct au_branch *au_sbr(struct super_block *sb, aufs_bindex_t bindex); +au_gen_t au_sigen_inc(struct super_block *sb); +int au_find_bindex(struct super_block *sb, struct au_branch *br); + +void aufs_read_lock(struct dentry *dentry, int flags); +void aufs_read_unlock(struct dentry *dentry, int flags); +void aufs_write_lock(struct dentry *dentry); +void aufs_write_unlock(struct dentry *dentry); +void aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int isdir); +void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2); + +aufs_bindex_t au_new_br_id(struct super_block *sb); + +/* wbr_policy.c */ +extern struct au_wbr_copyup_operations au_wbr_copyup_ops[]; +extern struct au_wbr_create_operations au_wbr_create_ops[]; +int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst); + +/* ---------------------------------------------------------------------- */ + +#if defined(CONFIG_AUFS_EXPORT) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) +static inline void au_mnt_init(struct au_sbinfo *sbinfo, struct vfsmount *mnt) +{ + spin_lock_init(&sbinfo->si_mntcache_lock); + sbinfo->si_mntcache = mnt; +} + +static inline void au_mnt_reset(struct au_sbinfo *sbinfo) +{ + spin_lock(&sbinfo->si_mntcache_lock); + sbinfo->si_mntcache = NULL; + spin_unlock(&sbinfo->si_mntcache_lock); +} +#else +static inline void au_mnt_init(struct au_sbinfo *sbinfo, struct vfsmount *mnt) +{ + /* emptr */ +} + +static inline void au_mnt_reset(struct au_sbinfo *sbinfo) +{ + /* emptr */ +} +#endif /* EXPORT && < 2.6.26 */ + +/* ---------------------------------------------------------------------- */ + +static inline struct au_sbinfo *au_sbi(struct super_block *sb) +{ + return sb->s_fs_info; +} + +static inline const char *au_sbtype(struct super_block *sb) +{ + return sb->s_type->name; +} + +static inline int au_test_aufs(struct super_block *sb) +{ + return (sb->s_magic == AUFS_SUPER_MAGIC); +} + +static inline int au_test_nfs(struct super_block *sb) +{ +#ifdef CONFIG_AUFS_BR_NFS + return (sb->s_magic == NFS_SUPER_MAGIC); +#else + return 0; +#endif +} + +static inline int au_test_fuse(struct super_block *sb) +{ +#ifdef CONFIG_AUFS_WORKAROUND_FUSE + return (sb->s_magic == FUSE_SUPER_MAGIC); +#else + return 0; +#endif +} + +static inline int au_test_xfs(struct super_block *sb) +{ +#ifdef CONFIG_AUFS_BR_XFS + return (sb->s_magic == XFS_SB_MAGIC); +#else + return 0; +#endif +} + +static inline int au_test_tmpfs(struct super_block *sb) +{ +#ifdef CONFIG_TMPFS + return (sb->s_magic == TMPFS_MAGIC); +#else + return 0; +#endif +} + +/* ---------------------------------------------------------------------- */ + +#ifdef CONFIG_AUFS_HINOTIFY +static inline void au_xino_def_br_set(struct au_branch *br, + struct au_sbinfo *sbinfo) +{ + sbinfo->si_xino_def_br = br; +} + +static inline struct au_branch *au_xino_def_br(struct au_sbinfo *sbinfo) +{ + return sbinfo->si_xino_def_br; +} +#else +static inline void au_xino_def_br_set(struct au_branch *br, + struct au_sbinfo *sbinfo) +{ + /* empty */ +} + +static inline struct au_branch *au_xino_def_br(struct au_sbinfo *sbinfo) +{ + return NULL; +} +#endif + +/* ---------------------------------------------------------------------- */ + +#ifdef CONFIG_AUFS_EXPORT +void au_export_init(struct super_block *sb); + +static inline int au_test_nfsd(struct task_struct *tsk) +{ + return (!tsk->mm && !strcmp(tsk->comm, "nfsd")); +} + +static inline void au_nfsd_lockdep_off(void) +{ + if (au_test_nfsd(current)) + lockdep_off(); +} + +static inline void au_nfsd_lockdep_on(void) +{ + if (au_test_nfsd(current)) + lockdep_on(); +} + +static inline void au_export_put(struct au_sbinfo *sbinfo) +{ + path_put(&sbinfo->si_xinodir); +} + +int au_xigen_inc(struct inode *inode); +int au_xigen_new(struct inode *inode); +int au_xigen_set(struct super_block *sb, struct file *base); +void au_xigen_clr(struct super_block *sb); + +#else +static inline void au_export_init(struct super_block *sb) +{ + /* nothing */ +} + +static inline int au_test_nfsd(struct task_struct *tsk) +{ + return 0; +} + +#define au_nfsd_lockdep_off() do {} while (0) +#define au_nfsd_lockdep_on() do {} while (0) + +static inline void au_export_put(struct au_sbinfo *sbinfo) +{ + /* nothing */ +} + +static inline int au_xigen_inc(struct inode *inode) +{ + return 0; +} + +static inline int au_xigen_new(struct inode *inode) +{ + return 0; +} + +static inline int au_xigen_set(struct super_block *sb, struct file *base) +{ + return 0; +} + +static inline void au_xigen_clr(struct super_block *sb) +{ + /* empty */ +} +#endif /* CONFIG_AUFS_EXPORT */ + +#ifdef CONFIG_AUFS_ROBR +static inline int au_test_nested(struct super_block *h_sb) +{ + return 0; +} + +static inline void au_robr_lvma_init(struct au_sbinfo *sbinfo) +{ + spin_lock_init(&sbinfo->si_lvma_lock); + INIT_LIST_HEAD(&sbinfo->si_lvma); +} +#else +static inline int au_test_nested(struct super_block *h_sb) +{ + int err = 0; + if (unlikely(au_test_aufs(h_sb))) { + err = -EINVAL; + AuTraceErr(err); + } + return err; +} + +static inline void au_robr_lvma_init(struct au_sbinfo *sbinfo) +{ + /* empty */ +} +#endif /* CONFIG_AUFS_ROBR */ + +/* ---------------------------------------------------------------------- */ + +/* lock superblock. mainly for entry point functions */ +/* + * si_noflush_read_lock, si_noflush_write_lock, + * si_read_unlock, si_write_unlock, si_downgrade_lock + */ +AuSimpleLockRwsemFuncs(si_noflush, struct super_block *sb, + au_sbi(sb)->si_rwsem); +AuSimpleUnlockRwsemFuncs(si, struct super_block *sb, au_sbi(sb)->si_rwsem); + +static inline void si_read_lock(struct super_block *sb, int flags) +{ + if (au_ftest_lock(flags, FLUSH)) + au_nwt_flush(&au_sbi(sb)->si_nowait); + si_noflush_read_lock(sb); +} + +static inline void si_write_lock(struct super_block *sb) +{ + au_nwt_flush(&au_sbi(sb)->si_nowait); + si_noflush_write_lock(sb); +} + +static inline int si_read_trylock(struct super_block *sb, int flags) +{ + if (au_ftest_lock(flags, FLUSH)) + au_nwt_flush(&au_sbi(sb)->si_nowait); + return si_noflush_read_trylock(sb); +} + +static inline int si_write_trylock(struct super_block *sb, int flags) +{ + if (au_ftest_lock(flags, FLUSH)) + au_nwt_flush(&au_sbi(sb)->si_nowait); + return si_noflush_write_trylock(sb); +} + +/* to debug easier, do not make them inlined functions */ +#define SiMustReadLock(sb) AuRwMustReadLock(&au_sbi(sb)->si_rwsem) +#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem) +#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem) + +/* ---------------------------------------------------------------------- */ + +static inline aufs_bindex_t au_sbend(struct super_block *sb) +{ + SiMustAnyLock(sb); + return au_sbi(sb)->si_bend; +} + +static inline unsigned int au_mntflags(struct super_block *sb) +{ + SiMustAnyLock(sb); + return au_sbi(sb)->si_mntflags; +} + +static inline au_gen_t au_sigen(struct super_block *sb) +{ + SiMustAnyLock(sb); + return au_sbi(sb)->si_generation; +} + +#endif /* __KERNEL__ */ +#endif /* __AUFS_SUPER_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/i_op_ren.c +++ linux-2.6.28/ubuntu/aufs/i_op_ren.c @@ -0,0 +1,1211 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * inode operation (rename entry) + * todo: this is crazy monster + * + * $Id: i_op_ren.c,v 1.14 2008/09/22 03:52:12 sfjro Exp $ + */ + +#include "aufs.h" + +enum { SRC, DST }; + +#define AuRen_ISDIR 1 +#define AuRen_ISSAMEDIR (1 << 1) +#define AuRen_WHSRC (1 << 2) +#define AuRen_WHDST (1 << 3) +#define AuRen_DLGT (1 << 4) +#define AuRen_VFSLOCK (1 << 5) +#define AuRen_PINNED (1 << 6) +#define au_ftest_ren(flags, name) ((flags) & AuRen_##name) +#define au_fset_ren(flags, name) { (flags) |= AuRen_##name; } +#define au_fclr_ren(flags, name) { (flags) &= ~AuRen_##name; } +#ifndef CONFIG_AUFS_DLGT +#undef AuRen_DLGT +#define AuRen_DLGT 0 +#endif + +struct au_ren_args { + /* original args */ + struct dentry *src_dentry, *dentry; + struct inode *src_dir, *dir; + + struct dentry *h_dentry[2], *h_parent[2], *h_trap, *h_locked[2]; + /* todo: remove them */ + struct dentry *parent[2], *gparent[2]; + struct au_pin pin[2]; + struct au_nhash whlist; + aufs_bindex_t btgt, bstart[2]; + /* do_rename() only */ + unsigned char need_diropq, bycpup; + struct super_block *sb; + unsigned int flags; + unsigned int mnt_flags; + struct au_ndx ndx; + + /* do_rename() only */ +#ifdef CONFIG_AUFS_BR_NFS + struct au_hin_ignore ign[3]; +#else + struct au_hin_ignore ign[2]; +#endif + struct vfsub_args vargs; + struct au_whtmp_rmdir_args *thargs; + struct dentry *wh_dentry[2], *h_dst, *h_src; +}; + +/* ---------------------------------------------------------------------- */ + +#define RevertFailure(fmt, args...) do { \ + AuIOErrWhck("revert failure: " fmt " (%d, %d)\n", \ + ##args, err, rerr); \ + err = -EIO; \ + } while (0) + +static noinline_for_stack +void au_ren_rev_diropq(int err, struct au_ren_args *a) +{ + int rerr; + struct mutex *h_mtx; + + /* lock inode simply since inotify is not set to h_inode. */ + h_mtx = &au_h_dptr(a->src_dentry, a->btgt)->d_inode->i_mutex; + mutex_lock_nested(h_mtx, AuLsc_I_CHILD); + rerr = au_diropq_remove(a->src_dentry, a->btgt, + au_ftest_ren(a->flags, DLGT)); + mutex_unlock(h_mtx); + if (rerr) + RevertFailure("remove diropq %.*s", AuDLNPair(a->src_dentry)); +} + +static noinline_for_stack +void au_ren_rev_rename(int err, struct au_ren_args *a) +{ + int rerr; + struct dentry *h_d; + struct qstr *name = &a->src_dentry->d_name; + + h_d = au_lkup_one(name->name, a->h_parent[SRC], name->len, &a->ndx); + rerr = PTR_ERR(h_d); + if (IS_ERR(h_d)) { + RevertFailure("au_lkup_one %.*s", AuDLNPair(a->src_dentry)); + return; + } + + AuDebugOn(h_d->d_inode); + vfsub_args_reinit(&a->vargs); + vfsub_ign_hinode(&a->vargs, IN_MOVED_FROM, au_pinned_hdir(a->pin + DST, + a->btgt)); + vfsub_ign_hinode(&a->vargs, IN_MOVED_TO, au_pinned_hdir(a->pin + SRC, + a->btgt)); + rerr = vfsub_rename(au_pinned_h_dir(a->pin + DST), + au_h_dptr(a->src_dentry, a->btgt), + au_pinned_h_dir(a->pin + SRC), h_d, &a->vargs); + d_drop(h_d); + dput(h_d); + /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */ + if (rerr) + RevertFailure("rename %.*s", AuDLNPair(a->src_dentry)); +} + +static noinline_for_stack +void au_ren_rev_cpup(int err, struct au_ren_args *a) +{ + int rerr; + + vfsub_args_reinit(&a->vargs); + vfsub_ign_hinode(&a->vargs, IN_DELETE, au_pinned_hdir(a->pin + DST, + a->btgt)); + rerr = vfsub_unlink(au_pinned_h_dir(a->pin + DST), a->h_dentry[DST], + &a->vargs); + au_set_h_dptr(a->src_dentry, a->btgt, NULL); + au_set_dbstart(a->src_dentry, a->bstart[SRC]); + if (rerr) + RevertFailure("unlink %.*s", AuDLNPair(a->h_dentry[DST])); +} + +static noinline_for_stack +void au_ren_rev_whtmp(int err, struct au_ren_args *a) +{ + int rerr; + struct dentry *h_d; + struct mutex *h_mtx; + struct qstr *name = &a->dentry->d_name; + + h_d = au_lkup_one(name->name, a->h_parent[DST], name->len, &a->ndx); + rerr = PTR_ERR(h_d); + if (IS_ERR(h_d)) { + RevertFailure("lookup %.*s", AuLNPair(name)); + return; + } + if (h_d->d_inode) { + d_drop(h_d); + dput(h_d); + return; + } + + h_mtx = &a->h_dst->d_inode->i_mutex; + mutex_lock_nested(h_mtx, AuLsc_I_CHILD); + au_hin_resume(au_hi(a->src_dentry->d_inode, a->btgt)); + mutex_unlock(h_mtx); + vfsub_args_reinit(&a->vargs); + vfsub_ign_hinode(&a->vargs, IN_MOVED_TO | IN_MOVED_FROM, + au_pinned_hdir(a->pin + DST, a->btgt)); + rerr = vfsub_rename(au_pinned_h_dir(a->pin + DST), a->h_dst, + au_pinned_h_dir(a->pin + DST), h_d, &a->vargs); + d_drop(h_d); + dput(h_d); + if (!rerr) { + au_set_h_dptr(a->dentry, a->btgt, NULL); + au_set_h_dptr(a->dentry, a->btgt, dget(a->h_dst)); + } else + RevertFailure("rename %.*s", AuDLNPair(a->h_dst)); +} + +static noinline_for_stack +void au_ren_rev_whsrc(int err, struct au_ren_args *a) +{ + int rerr; + + rerr = au_wh_unlink_dentry(au_pinned_hdir(a->pin + SRC, a->btgt), + a->wh_dentry[SRC], a->src_dentry, /*dlgt*/0); + if (rerr) + RevertFailure("unlink %.*s", AuDLNPair(a->wh_dentry[SRC])); +} +#undef RevertFailure + +/* ---------------------------------------------------------------------- */ + +static /* noinline_for_stack */ +int au_ren_or_cpup(struct au_ren_args *a) +{ + int err; + + AuTraceEnter(); + + if (au_dbstart(a->src_dentry) == a->btgt) { + if (a->need_diropq && au_dbdiropq(a->src_dentry) == a->btgt) + a->need_diropq = 0; + vfsub_ign_hinode(&a->vargs, IN_MOVED_FROM, + au_pinned_hdir(a->pin + SRC, a->btgt)); + vfsub_ign_hinode(&a->vargs, IN_MOVED_TO, + au_pinned_hdir(a->pin + DST, a->btgt)); + /* nfs_rename() calls d_delete() */ + if (au_test_nfs(au_pinned_h_dir(a->pin + DST)->i_sb) + && a->h_dentry[DST]->d_inode + && (S_ISDIR(a->h_dentry[DST]->d_inode->i_mode) + || atomic_read(&a->h_dentry[DST]->d_count) <= 2)) + vfsub_ign_hinode(&a->vargs, IN_DELETE, + au_pinned_hdir(a->pin + DST, a->btgt)); + AuDebugOn(au_dbstart(a->src_dentry) != a->btgt); + err = vfsub_rename(au_pinned_h_dir(a->pin + SRC), + au_h_dptr(a->src_dentry, a->btgt), + au_pinned_h_dir(a->pin + DST), + a->h_dentry[DST], &a->vargs); + } else { + struct mutex *h_mtx = &a->h_dentry[SRC]->d_inode->i_mutex; + + a->bycpup = 1; + mutex_lock_nested(h_mtx, AuLsc_I_CHILD); + au_set_dbstart(a->src_dentry, a->btgt); + au_set_h_dptr(a->src_dentry, a->btgt, dget(a->h_dentry[DST])); + err = au_sio_cpup_single(a->src_dentry, a->btgt, a->bstart[SRC], + -1, !AuCpup_DTIME, a->parent[DST]); + if (unlikely(err)) { + au_set_h_dptr(a->src_dentry, a->btgt, NULL); + au_set_dbstart(a->src_dentry, a->bstart[SRC]); + } + mutex_unlock(h_mtx); + } + + return err; +} + +static /* noinline_for_stack */ +int au_ren_del_whtmp(struct au_ren_args *a) +{ + int err; + + AuTraceEnter(); + + if (au_test_nfs(a->h_dst->d_sb) + || !au_nhash_test_longer_wh(&a->whlist, a->btgt, + au_sbi(a->sb)->si_dirwh)) { + err = au_whtmp_rmdir(a->dir, a->btgt, a->h_dst, &a->whlist); + if (unlikely(err)) + AuWarn("failed removing whtmp dir %.*s (%d), " + "ignored.\n", AuDLNPair(a->h_dst), err); + } else { + au_whtmp_kick_rmdir(a->dir, a->btgt, a->h_dst, &a->whlist, + a->thargs); + dput(a->h_dst); + a->thargs = NULL; + } + + return 0; +} + +static /* noinline_for_stack */ +int au_ren_diropq(struct au_ren_args *a) +{ + int err; + struct dentry *diropq; + struct mutex *h_mtx; + + AuTraceEnter(); + + err = 0; + h_mtx = &au_h_dptr(a->src_dentry, a->btgt)->d_inode->i_mutex; + mutex_lock_nested(h_mtx, AuLsc_I_CHILD); + diropq = au_diropq_create(a->src_dentry, a->btgt, + au_ftest_ren(a->flags, DLGT)); + mutex_unlock(h_mtx); + if (IS_ERR(diropq)) + err = PTR_ERR(diropq); + dput(diropq); + + return err; +} + +static /* noinline_for_stack */ +int do_rename(struct au_ren_args *a) +{ + int err; + aufs_bindex_t bindex, bend; + struct dentry *h_d; + + LKTRTrace("%.*s/%.*s, %.*s/%.*s, " + "hd{%p, %p}, hp{%p, %p}, wh %p, btgt %d, bstart{%d, %d}, " + "flags 0x%x\n", + AuDLNPair(a->parent[SRC]), AuDLNPair(a->src_dentry), + AuDLNPair(a->parent[DST]), AuDLNPair(a->dentry), + a->h_dentry[SRC], a->h_dentry[DST], + a->h_parent[SRC], a->h_parent[DST], + &a->whlist, a->btgt, + a->bstart[SRC], a->bstart[DST], + a->flags); + + /* prepare workqueue args */ + if (au_ftest_ren(a->flags, ISDIR) && a->h_dentry[DST]->d_inode) { + err = -ENOMEM; + a->thargs = kmalloc(sizeof(*a->thargs), GFP_NOFS); + if (unlikely(!a->thargs)) + goto out; + a->h_dst = dget(a->h_dentry[DST]); + } + + a->ndx.nfsmnt = au_nfsmnt(a->sb, a->btgt); + if (unlikely(au_ftest_ren(a->flags, DLGT))) + au_fset_ndx(a->ndx.flags, DLGT); + + /* create whiteout for src_dentry */ + if (au_ftest_ren(a->flags, WHSRC)) { + a->wh_dentry[SRC] = au_wh_create(a->src_dentry, a->btgt, + a->h_parent[SRC], &a->ndx); + err = PTR_ERR(a->wh_dentry[SRC]); + if (IS_ERR(a->wh_dentry[SRC])) + goto out_thargs; + } + + /* lookup whiteout for dentry */ + if (au_ftest_ren(a->flags, WHDST)) { + h_d = au_wh_lkup(a->h_parent[DST], &a->dentry->d_name, &a->ndx); + err = PTR_ERR(h_d); + if (IS_ERR(h_d)) + goto out_whsrc; + if (!h_d->d_inode) + dput(h_d); + else + a->wh_dentry[DST] = h_d; + } + + /* rename dentry to tmpwh */ + if (a->thargs) { + struct au_hinode *hinode; + + AuDbgDentry(a->h_dentry[DST]); + err = au_whtmp_ren(a->dir, a->btgt, a->h_dentry[DST]); + if (unlikely(err)) + goto out_whdst; + AuDbgDentry(a->h_dentry[DST]); + hinode = au_hi(a->dentry->d_inode, a->btgt); + /* todo: bad approach? */ + mutex_lock_nested(&hinode->hi_inode->i_mutex, AuLsc_I_CHILD); + au_hin_suspend(hinode); + mutex_unlock(&hinode->hi_inode->i_mutex); + au_set_h_dptr(a->dentry, a->btgt, NULL); + AuDbgDentry(a->h_dentry[DST]); + err = au_lkup_neg(a->dentry, a->btgt); + if (unlikely(err)) + goto out_whtmp; + a->h_dentry[DST] = au_h_dptr(a->dentry, a->btgt); + } + + /* cpup src */ + if (a->h_dentry[DST]->d_inode && a->bstart[SRC] != a->btgt) { + struct mutex *h_mtx = &a->h_dentry[SRC]->d_inode->i_mutex; + + mutex_lock_nested(h_mtx, AuLsc_I_CHILD); + err = au_sio_cpup_simple(a->src_dentry, a->btgt, -1, + !AuCpup_DTIME); + mutex_unlock(h_mtx); + if (unlikely(err)) + goto out_whtmp; + } + + /* rename by vfs_rename or cpup */ + a->need_diropq = au_ftest_ren(a->flags, ISDIR) + && (a->wh_dentry[DST] + || au_dbdiropq(a->dentry) == a->btgt + /* hide the lower to keep xino */ + || a->btgt < au_dbend(a->dentry) + || au_opt_test(a->mnt_flags, ALWAYS_DIROPQ)); + a->bycpup = 0; + vfsub_args_init(&a->vargs, a->ign, au_ftest_ren(a->flags, DLGT), 0); + err = au_ren_or_cpup(a); + if (unlikely(err)) + goto out_whtmp; + + /* make dir opaque */ + if (a->need_diropq) { + err = au_ren_diropq(a); + if (unlikely(err)) + goto out_rename; + } + + /* update target timestamps */ + AuDebugOn(au_dbstart(a->src_dentry) != a->btgt); + a->h_src = au_h_dptr(a->src_dentry, a->btgt); + au_update_fuse_h_inode(NULL, a->h_src); /*ignore*/ + /* fsstack_copy_attr_atime(a->src_dentry->d_inode, a->h_src->d_inode); */ + a->src_dentry->d_inode->i_ctime = a->h_src->d_inode->i_ctime; + + /* remove whiteout for dentry */ + if (a->wh_dentry[DST]) { + err = au_wh_unlink_dentry(au_pinned_hdir(a->pin + DST, a->btgt), + a->wh_dentry[DST], a->dentry, + /*dlgt*/0); + if (unlikely(err)) + goto out_diropq; + } + + /* remove whtmp */ + if (a->thargs) + /* ignore this error */ + au_ren_del_whtmp(a); + + err = 0; + goto out_success; + + out_diropq: + if (a->need_diropq) + au_ren_rev_diropq(err, a); + out_rename: + if (!a->bycpup) + au_ren_rev_rename(err, a); + else + au_ren_rev_cpup(err, a); + out_whtmp: + if (a->thargs) + au_ren_rev_whtmp(err, a); + out_whdst: + dput(a->wh_dentry[DST]); + a->wh_dentry[DST] = NULL; + out_whsrc: + if (a->wh_dentry[SRC]) + au_ren_rev_whsrc(err, a); + d_drop(a->src_dentry); + bend = au_dbend(a->src_dentry); + for (bindex = au_dbstart(a->src_dentry); bindex <= bend; bindex++) { + h_d = au_h_dptr(a->src_dentry, bindex); + if (h_d) + d_drop(h_d); + } + d_drop(a->dentry); + bend = au_dbend(a->dentry); + for (bindex = au_dbstart(a->dentry); bindex <= bend; bindex++) { + h_d = au_h_dptr(a->dentry, bindex); + if (h_d) + d_drop(h_d); + } + au_update_dbstart(a->dentry); + if (a->thargs) + d_drop(a->h_dst); + out_success: + dput(a->wh_dentry[SRC]); + dput(a->wh_dentry[DST]); + out_thargs: + if (a->thargs) { + dput(a->h_dst); + kfree(a->thargs); + } + out: + AuTraceErr(err); + return err; +} + +/* + * test if @dentry dir can be rename destination or not. + * success means, it is a logically empty dir. + */ +static int may_rename_dstdir(struct dentry *dentry, aufs_bindex_t btgt, + struct au_nhash *whlist) +{ + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + + return au_test_empty(dentry, whlist); +} + +/* + * test if @dentry dir can be rename source or not. + * if it can, return 0 and @children is filled. + * success means, + * - or, it is a logically empty dir. + * - or, it exists on writable branch and has no children including whiteouts + * on the lower branch. + */ +static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt) +{ + int err; + aufs_bindex_t bstart; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + + bstart = au_dbstart(dentry); + if (bstart != btgt) { + struct au_nhash *whlist; + + whlist = au_nhash_new(GFP_NOFS); + err = PTR_ERR(whlist); + if (IS_ERR(whlist)) + goto out; + err = au_test_empty(dentry, whlist); + au_nhash_del(whlist); + goto out; + } + + if (bstart == au_dbtaildir(dentry)) + return 0; /* success */ + + err = au_test_empty_lower(dentry); + + out: + if (/* unlikely */(err == -ENOTEMPTY)) { + AuWarn1("renaming dir who has child(ren) on multiple branches," + " is not supported\n"); + err = -EXDEV; + } + AuTraceErr(err); + return err; +} + +/* mainly for link(2) and rename(2) */ +int au_wbr(struct dentry *dentry, aufs_bindex_t btgt) +{ + aufs_bindex_t bdiropq, bwh; + struct dentry *parent; + + LKTRTrace("%.*s, b%d\n", AuDLNPair(dentry), btgt); + parent = dentry->d_parent; + IMustLock(parent->d_inode); /* dir is locked */ + + bdiropq = au_dbdiropq(parent); + bwh = au_dbwh(dentry); + if (au_br_rdonly(au_sbr(dentry->d_sb, btgt)) + || (0 <= bdiropq && bdiropq < btgt) + || (0 <= bwh && bwh < btgt)) + btgt = -1; + + LKTRTrace("btgt %d\n", btgt); + return btgt; +} + +/* + * simple tests for rename. + * following the checks in vfs, plus the parent-child relationship. + */ +static int au_may_ren(struct au_ren_args *a) +{ + int err; + struct inode *h_inode; + + AuTraceEnter(); + + if (a->bstart[SRC] == a->btgt) { + err = au_may_del(a->src_dentry, a->btgt, a->h_parent[SRC], + au_ftest_ren(a->flags, ISDIR), &a->ndx); + if (unlikely(err)) + goto out; + err = -EINVAL; + if (unlikely(a->h_dentry[SRC] == a->h_trap)) + goto out; + } + + err = 0; + if (a->bstart[DST] != a->btgt) + goto out; + + err = -EIO; + h_inode = a->h_dentry[DST]->d_inode; + if (!a->dentry->d_inode) { + if (unlikely(h_inode)) + goto out; + err = au_may_add(a->dentry, a->btgt, a->h_parent[DST], + au_ftest_ren(a->flags, ISDIR), &a->ndx); + } else { + if (unlikely(!h_inode || !h_inode->i_nlink)) + goto out; + err = au_may_del(a->dentry, a->btgt, a->h_parent[DST], + au_ftest_ren(a->flags, ISDIR), &a->ndx); + if (unlikely(err)) + goto out; + err = -ENOTEMPTY; + if (unlikely(a->h_dentry[DST] == a->h_trap)) + goto out; + err = 0; + } + + out: + if (unlikely(err == -ENOENT || err == -EEXIST)) + err = -EIO; + AuTraceErr(err); + return err; +} + +/* + * locking order + * (VFS) + * - src_dir and dir by lock_rename() + * - inode if exitsts + * (aufs) + * - lock all + * + src_dentry and dentry by aufs_read_and_write_lock2() which calls, + * + si_read_lock + * + di_write_lock2_child() + * + di_write_lock_child() + * + ii_write_lock_child() + * + di_write_lock_child2() + * + ii_write_lock_child2() + * + src_parent and parent + * + di_write_lock_parent() + * + ii_write_lock_parent() + * + di_write_lock_parent2() + * + ii_write_lock_parent2() + * + if udab=inotify is specified, lock grand parents (crazy) + * + di_read_lock_gparent() + * + ii_read_lock_gparent() + * + di_read_lock_gparent2() + * + ii_read_lock_gparent2() + * + mutex_lock_gparent() + * + mutex_lock_gparent2() + * + lower src_dir and dir by vfsub_lock_rename()? + * + verify the every relations between child, parent and grand parent. if any + * of them failed, unlock all and return -EBUSY. + */ +static void au_ren_pin_init(struct au_pin *first, struct dentry *d1, + struct au_pin *next, struct dentry *d2) +{ + AuTraceEnter(); + + /* AuLsc_DI_PARENT3 is for higher gparent initially */ + au_pin_init(first, d1, /*di_locked*/1, AuLsc_DI_PARENT2, + AuLsc_I_PARENT2, /*do_gp*/1); + /* AuLsc_DI_PARENT4 is for lower gparent initially */ + au_pin_init(next, d2, /*di_locked*/1, AuLsc_DI_PARENT3, + AuLsc_I_PARENT4, /*do_gp*/1); +} + +static void au_ren_fake_pin(struct au_ren_args *a) +{ + int i; + struct au_pin1 *p; + struct inode *h_i; + + AuTraceEnter(); + + /* they increment the ref counter */ + for (i = 0; i < 2; i++) { + p = a->pin[i].pin + AuPin_PARENT; + au_pin_set_parent(a->pin + i, a->parent[i]); + dput(a->parent[i]); + h_i = a->h_parent[i]->d_inode; + au_pin_set_h_dir(a->pin + i, h_i); + iput(h_i); + + if (!a->gparent[i]) { + au_pin_set_gparent(a->pin + i, NULL); + au_pin_set_h_gdir(a->pin + i, NULL); + } else { + au_pin_set_gparent(a->pin + i, a->gparent[i]); + dput(a->gparent[i]); + h_i = au_h_iptr(a->gparent[i]->d_inode, a->btgt); + au_pin_set_h_gdir(a->pin + i, h_i); + iput(h_i); + } + } +} + +/* crazy */ +/* cf. i_op.c: au_do_pin() */ +static int au_ren_pin4(int higher, int lower, struct au_ren_args *a) +{ + int err, i, lsc; + struct au_pin *p; + struct au_pin1 *p4[4]; + struct inode *h_dir; + + LKTRTrace("%d, %d\n", higher, lower); + + p = a->pin + higher; + p4[0] = au_pin_gp(p); /* highest */ + p4[1] = p->pin + AuPin_PARENT; + p = a->pin + lower; + p4[2] = au_pin_gp(p); + p4[3] = p->pin + AuPin_PARENT; + + if (a->gparent[higher]) { + au_pin_do_set_parent(p4[0], a->gparent[higher]); + au_pin_do_set_dentry(p4[0], a->parent[higher]); + } + au_pin_do_set_parent(p4[1], a->parent[higher]); + if (a->gparent[lower]) { + au_pin_do_set_parent(p4[2], a->gparent[lower]); + au_pin_do_set_dentry(p4[2], a->parent[lower]); + } + au_pin_do_set_parent(p4[3], a->parent[lower]); + + DiMustWriteLock(p4[3]->parent); + di_write_unlock(p4[1]->parent); + if (p4[2]->parent) + di_read_lock_parent2(p4[2]->parent, AuLock_IR); + di_write_lock_parent3(p4[1]->parent); + if (p4[0]->parent) + di_read_lock_parent4(p4[0]->parent, AuLock_IR); + + lsc = AuLsc_I_PARENT; + for (i = 0; i < 4; i++, lsc++) { + if (p4[i]->parent) { + h_dir = au_h_iptr(p4[i]->parent->d_inode, a->btgt); + au_pin_do_set_h_dir(p4[i], h_dir); + mutex_lock_nested(&h_dir->i_mutex, lsc); + } + } + + err = 0; + AuTraceErr(err); + return err; +} + +static struct dentry *au_ren_pin3(int higher, int lower, struct au_ren_args *a) +{ + struct dentry *h_trap; + struct au_pin *p; + int err; + + LKTRTrace("%d, %d\n", higher, lower); + + p = a->pin + higher; + err = au_do_pin(p->pin + AuPin_PARENT, au_pin_gp(p), a->btgt, + /*do_gp*/1); + h_trap = ERR_PTR(err); + if (unlikely(err)) + goto out; + p = a->pin + lower; + err = au_do_pin(p->pin + AuPin_PARENT, NULL, a->btgt, /*do_gp*/0); + h_trap = ERR_PTR(err); + if (unlikely(err)) { + au_do_unpin(p->pin + AuPin_PARENT, au_pin_gp(p)); + goto out; + } + h_trap = au_pinned_h_parent(p, a->btgt); + + out: + AuTraceErrPtr(h_trap); + return h_trap; +} + +static struct dentry *au_ren_pin(struct au_ren_args *a) +{ + struct dentry *h_trap; + struct inode *h_gdir; + int err, i, same_gp; + + AuTraceEnter(); + AuDebugOn(!au_opt_test(a->mnt_flags, UDBA_INOTIFY)); + + vfsub_lock_rename_mutex(a->h_dentry[SRC]->d_sb); + au_fset_ren(a->flags, VFSLOCK); + + /* gdir is not locked */ + same_gp = 0; + if (!IS_ROOT(a->parent[SRC])) + a->gparent[SRC] = dget_parent(a->parent[SRC]); + if (!IS_ROOT(a->parent[DST])) { + a->gparent[DST] = dget_parent(a->parent[DST]); + same_gp = (a->gparent[SRC] == a->gparent[DST]); + } + + /* + * patterns + * - gparent[SRC] is parent[DST] + * - parent[SRC] is gparent[DST] + * - gparent[SRC] is gparent[DST] + * - gparent[SRC] is a descendant of parent[DST] + * - parent[SRC] is an ancestor of gparent[DST] + * - not within grand parent range + */ + err = 0; + h_trap = ERR_PTR(-EBUSY); + if (a->gparent[SRC] == a->parent[DST]) { + LKTRLabel(here); + au_ren_pin_init(a->pin + DST, a->dentry, a->pin + SRC, + a->src_dentry); + h_trap = au_ren_pin3(DST, SRC, a); + if (!IS_ERR(h_trap)) { + h_gdir = au_pinned_h_dir(a->pin + DST); + err = au_verify_parent(a->h_parent[SRC], h_gdir); + if (unlikely(err)) + h_trap = ERR_PTR(-EBUSY); + } + } else if (a->parent[SRC] == a->gparent[DST] || same_gp) { + LKTRLabel(here); + au_ren_pin_init(a->pin + SRC, a->src_dentry, a->pin + DST, + a->dentry); + h_trap = au_ren_pin3(SRC, DST, a); + if (!IS_ERR(h_trap)) { + if (!same_gp) + h_gdir = au_pinned_h_dir(a->pin + SRC); + else + h_gdir = au_pinned_h_gdir(a->pin + SRC); + err = au_verify_parent(a->h_parent[DST], h_gdir); + if (unlikely(err)) + h_trap = ERR_PTR(-EBUSY); + } + } else if (a->gparent[SRC] + && (h_trap = au_test_subdir(a->gparent[SRC], + a->parent[DST]))) { + LKTRLabel(here); + au_ren_pin_init(a->pin + DST, a->dentry, a->pin + SRC, + a->src_dentry); + if (a->gparent[DST]) { + err = au_ren_pin4(DST, SRC, a); + if (unlikely(err)) + h_trap = ERR_PTR(err); + } else { + struct dentry *t; + t = au_ren_pin3(DST, SRC, a); + AuDebugOn(t == h_trap); + } + } else /* if (a->gparent[DST] + && (h_trap = au_test_subdir(a->gparent[DST], + a->parent[SRC]))) */ { + LKTRLabel(here); + h_trap = NULL; + if (a->gparent[DST]) + h_trap = au_test_subdir(a->gparent[DST], + a->parent[SRC]); + au_ren_pin_init(a->pin + SRC, a->src_dentry, a->pin + DST, + a->dentry); + err = au_ren_pin4(SRC, DST, a); + if (unlikely(err)) + h_trap = ERR_PTR(err); + } + au_fset_ren(a->flags, PINNED); + + if (!IS_ERR(h_trap)) { + err = 0; + for (i = 0; !err && i < 2; i++) { + h_gdir = au_pinned_h_gdir(a->pin + i); + if (h_gdir) + err = au_verify_parent(a->h_parent[i], h_gdir); + } + if (unlikely(err)) + h_trap = ERR_PTR(err); + } + + dput(a->gparent[SRC]); + dput(a->gparent[DST]); + /* memset(a->gparent, 0, sizeof(a->gparent)); */ + AuTraceErrPtr(h_trap); + return h_trap; +} + +static void au_ren_unlock(struct au_ren_args *a) +{ + int i; + + AuTraceEnter(); + + if (a->h_locked[0]) + vfsub_unlock_rename(a->h_locked[0], a->h_locked[1]); + if (au_ftest_ren(a->flags, PINNED)) { + au_unpin(a->pin + SRC); + au_unpin(a->pin + DST); + memset(a->gparent, 0, sizeof(a->gparent)); + } + if (au_ftest_ren(a->flags, VFSLOCK)) + vfsub_unlock_rename_mutex(a->h_dentry[SRC]->d_sb); + for (i = 0; i < 2; i++) + if (unlikely(a->gparent[i])) { + di_read_unlock(a->gparent[i], AuLock_IR); + dput(a->gparent[i]); + } +} + +static int au_ren_lock(struct au_ren_args *a) +{ + int err; + const int hinotify = au_opt_test(a->mnt_flags, UDBA_INOTIFY); + + AuTraceEnter(); + + err = 0; + if (!hinotify + || (au_ftest_ren(a->flags, ISSAMEDIR) && IS_ROOT(a->parent[SRC]))) { + au_ren_pin_init(a->pin + SRC, a->src_dentry, a->pin + DST, + a->dentry); + LKTRLabel(here); + a->h_locked[0] = a->h_parent[SRC]; + a->h_locked[1] = a->h_parent[DST]; + a->h_trap = vfsub_lock_rename(a->h_locked[0], a->h_locked[1]); + au_ren_fake_pin(a); + } else if (au_ftest_ren(a->flags, ISSAMEDIR) + && !IS_ROOT(a->parent[SRC])) { + /* this and next block should not be compiled when + hinotify is not enabled */ + /* irregular/tricky rename lock */ + LKTRLabel(here); + au_ren_pin_init(a->pin + SRC, a->src_dentry, a->pin + DST, + a->dentry); + a->gparent[SRC] = dget_parent(a->parent[SRC]); + di_read_lock_parent2(a->gparent[SRC], AuLock_IR); + a->h_locked[0] = a->h_parent[SRC]; + a->h_locked[1] = dget_parent(a->h_parent[SRC]); + a->h_trap = vfsub_lock_rename(a->h_locked[0], a->h_locked[1]); + err = au_verify_parent(a->h_parent[SRC], + a->h_locked[1]->d_inode); + dput(a->h_locked[1]); + if (!err) + au_ren_fake_pin(a); + } else { + /* 3 or 4 dir locks. crazy */ + LKTRLabel(here); + a->h_trap = au_ren_pin(a); + if (IS_ERR(a->h_trap)) + err = PTR_ERR(a->h_trap); + } + + if (!err && au_dbstart(a->src_dentry) == a->btgt) + err = au_verify_parent(a->h_dentry[SRC], + a->h_parent[SRC]->d_inode); + if (!err && au_dbstart(a->dentry) == a->btgt) + err = au_verify_parent(a->h_dentry[DST], + a->h_parent[DST]->d_inode); + if (unlikely(err)) { + err = -EBUSY; + au_ren_unlock(a); + } + AuTraceErr(err); + return err; +} + +int aufs_rename(struct inode *src_dir, struct dentry *src_dentry, + struct inode *dir, struct dentry *dentry) +{ + int err; + aufs_bindex_t bend, bindex; + unsigned char do_dt_dstdir, hinotify; + struct inode *inode[2]; + enum { PARENT, CHILD }; + /* reduce stack space */ + struct { + struct au_ren_args a; + struct au_dtime dt[2][2]; + } *p; + struct au_wr_dir_args wr_dir_args = { + /* .force_btgt = -1, */ + .flags = AuWrDir_ADD_ENTRY + }; + + //lktr_set_pid(current->pid, LktrArrayPid); + LKTRTrace("i%lu, %.*s, i%lu, %.*s\n", + src_dir->i_ino, AuDLNPair(src_dentry), + dir->i_ino, AuDLNPair(dentry)); + AuDebugOn(IS_ROOT(src_dentry) || IS_ROOT(dentry)); + IMustLock(src_dir); + IMustLock(dir); + inode[DST] = dentry->d_inode; + if (inode[DST]) { + IMustLock(inode[DST]); + au_igrab(inode[DST]); + } + + err = -ENOMEM; + BUILD_BUG_ON(sizeof(*p) > PAGE_SIZE); + p = kzalloc(sizeof(*p), GFP_NOFS); + if (unlikely(!p)) + goto out; + + err = -ENOTDIR; + p->a.src_dir = src_dir; + p->a.src_dentry = src_dentry; + p->a.dir = dir; + p->a.dentry = dentry; + p->a.sb = src_dentry->d_sb; + inode[SRC] = src_dentry->d_inode; + p->a.flags = 0; + if (S_ISDIR(inode[SRC]->i_mode)) { + au_fset_ren(p->a.flags, ISDIR); + if (unlikely(inode[DST] && !S_ISDIR(inode[DST]->i_mode))) + goto out_free; + aufs_read_and_write_lock2(dentry, src_dentry, AuLock_DIR); + } else + aufs_read_and_write_lock2(dentry, src_dentry, 0); + + p->a.mnt_flags = au_mntflags(p->a.sb); + if (unlikely(au_test_dlgt(p->a.mnt_flags))) + au_fset_ren(p->a.flags, DLGT); + p->a.parent[SRC] = src_dentry->d_parent; /* dir inode is locked */ + p->a.parent[DST] = dentry->d_parent; /* dir inode is locked */ + au_fset_ren(p->a.flags, ISSAMEDIR); /* temporary */ + di_write_lock_parent(p->a.parent[DST]); + + /* which branch we process */ + p->a.bstart[SRC] = au_dbstart(src_dentry); + p->a.bstart[DST] = au_dbstart(dentry); + if (au_ftest_ren(p->a.flags, ISDIR)) + au_fset_wrdir(wr_dir_args.flags, ISDIR); + wr_dir_args.force_btgt = p->a.bstart[SRC]; + if (dentry->d_inode && p->a.bstart[DST] < p->a.bstart[SRC]) + wr_dir_args.force_btgt = p->a.bstart[DST]; + wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt); + err = au_wr_dir(dentry, src_dentry, &wr_dir_args); + p->a.btgt = err; + if (unlikely(err < 0)) + goto out_unlock; + + /* are they available to be renamed */ + err = 0; + au_nhash_init(&p->a.whlist); + if (au_ftest_ren(p->a.flags, ISDIR) && inode[DST]) { + au_set_dbstart(dentry, p->a.bstart[DST]); + err = may_rename_dstdir(dentry, p->a.btgt, &p->a.whlist); + au_set_dbstart(dentry, p->a.btgt); + } + p->a.h_dentry[DST] = au_h_dptr(dentry, au_dbstart(dentry)); + if (unlikely(err)) + goto out_unlock; + /* todo: minor optimize, + their sb may be same while their bindex differs? */ + p->a.h_dentry[SRC] = au_h_dptr(src_dentry, au_dbstart(src_dentry)); + if (au_ftest_ren(p->a.flags, ISDIR)) { + err = may_rename_srcdir(src_dentry, p->a.btgt); + if (unlikely(err)) + goto out_children; + } + + /* prepare the writable parent dir on the same branch */ + if (p->a.bstart[DST] == p->a.btgt) { + au_fset_ren(p->a.flags, WHDST); + } else { + err = au_cpup_dirs(dentry, p->a.btgt); + if (unlikely(err)) + goto out_children; + } + + if (src_dir != dir) { + /* + * this temporary unlock is safe, + * because dir->i_mutex is locked. + */ + di_write_unlock(p->a.parent[DST]); + di_write_lock_parent(p->a.parent[SRC]); + err = au_wr_dir_need_wh + (src_dentry, au_ftest_ren(p->a.flags, ISDIR), + &p->a.btgt); + di_write_unlock(p->a.parent[SRC]); + di_write_lock2_parent(p->a.parent[SRC], p->a.parent[DST], + /*isdir*/1); + au_fclr_ren(p->a.flags, ISSAMEDIR); + } else + err = au_wr_dir_need_wh + (src_dentry, au_ftest_ren(p->a.flags, ISDIR), + &p->a.btgt); + if (unlikely(err < 0)) + goto out_children; + if (err) + au_fset_ren(p->a.flags, WHSRC); + + hinotify = au_opt_test(p->a.mnt_flags, UDBA_INOTIFY); + p->a.h_parent[SRC] = au_h_dptr(p->a.parent[SRC], p->a.btgt); + p->a.h_parent[DST] = au_h_dptr(p->a.parent[DST], p->a.btgt); + err = au_ren_lock(&p->a); + if (unlikely(err)) + goto out_children; + + if (!au_opt_test(p->a.mnt_flags, UDBA_NONE)) { + p->a.ndx.nfsmnt = au_nfsmnt(p->a.sb, p->a.btgt); + if (unlikely(au_ftest_ren(p->a.flags, DLGT))) + au_fset_ndx(p->a.ndx.flags, DLGT); + err = au_may_ren(&p->a); + if (unlikely(err)) + goto out_hdir; + memset(&p->a.ndx, 0, sizeof(p->a.ndx)); + } + + /* store timestamps to be revertible */ + au_dtime_store(p->dt[PARENT] + SRC, p->a.parent[SRC], + p->a.h_parent[SRC], + au_pinned_hdir(p->a.pin + SRC, p->a.btgt), + au_pinned_hgdir(p->a.pin + SRC, p->a.btgt) + /* hgdir[SRC] */); + if (!au_ftest_ren(p->a.flags, ISSAMEDIR)) + au_dtime_store(p->dt[PARENT] + DST, p->a.parent[DST], + p->a.h_parent[DST], + au_pinned_hdir(p->a.pin + DST, p->a.btgt), + au_pinned_hgdir(p->a.pin + DST, p->a.btgt) + /* hgdir[DST] */); + do_dt_dstdir = 0; + if (au_ftest_ren(p->a.flags, ISDIR)) { + au_dtime_store(p->dt[CHILD] + SRC, src_dentry, + p->a.h_dentry[SRC], au_hi(inode[SRC], p->a.btgt), + au_pinned_hdir(p->a.pin + SRC, p->a.btgt)); + if (p->a.h_dentry[DST]->d_inode) { + do_dt_dstdir = 1; + au_dtime_store(p->dt[CHILD] + DST, dentry, + p->a.h_dentry[DST], + au_hi(inode[DST], p->a.btgt), + au_pinned_hdir(p->a.pin + DST, + p->a.btgt)); + } + } + + err = do_rename(&p->a); + if (unlikely(err)) + goto out_dt; + + /* update dir attributes */ + dir->i_version++; + if (au_ftest_ren(p->a.flags, ISDIR)) { + /* is this updating defined in POSIX? */ + /* mutex_lock(&inode[SRC]->i_mutex); */ + au_cpup_attr_timesizes(inode[SRC]); + /* mutex_unlock(&inode[SRC]->i_mutex); */ + + au_cpup_attr_nlink(dir); + if (inode[DST]) { + clear_nlink(inode[DST]); + au_cpup_attr_timesizes(inode[DST]); + } + } + if (au_ibstart(dir) == p->a.btgt) + au_cpup_attr_timesizes(dir); + + if (!au_ftest_ren(p->a.flags, ISSAMEDIR)) { + src_dir->i_version++; + if (au_ftest_ren(p->a.flags, ISDIR)) + au_cpup_attr_nlink(src_dir); + if (au_ibstart(src_dir) == p->a.btgt) + au_cpup_attr_timesizes(src_dir); + } + + /* todo: simple d_drop(src_dentry) is not enough? */ + /* dput/iput all lower dentries */ + au_set_dbwh(src_dentry, -1); + bend = au_dbend(src_dentry); + for (bindex = p->a.btgt + 1; bindex <= bend; bindex++) { + struct dentry *hd; + hd = au_h_dptr(src_dentry, bindex); + if (hd) + au_set_h_dptr(src_dentry, bindex, NULL); + } + au_set_dbend(src_dentry, p->a.btgt); + + if (au_opt_test(p->a.mnt_flags, PLINK) + && !au_plink_test(src_dentry->d_sb, inode[SRC])) { + bend = au_ibend(inode[SRC]); + for (bindex = p->a.btgt + 1; bindex <= bend; bindex++) { + struct inode *hi; + hi = au_h_iptr(inode[SRC], bindex); + if (hi) { + au_xino_write0(p->a.sb, bindex, hi->i_ino, 0); + /* ignore this error */ + au_set_h_iptr(inode[SRC], bindex, NULL, 0); + } + } + au_set_ibend(inode[SRC], p->a.btgt); + } + goto out_hdir; /* success */ + + out_dt: + au_dtime_revert(p->dt[PARENT] + SRC); + if (!au_ftest_ren(p->a.flags, ISSAMEDIR)) + au_dtime_revert(p->dt[PARENT] + DST); + if (au_ftest_ren(p->a.flags, ISDIR) && err != -EIO) { + struct dentry *hd; + + hd = p->dt[CHILD][SRC].dt_h_dentry; + mutex_lock_nested(&hd->d_inode->i_mutex, AuLsc_I_CHILD); + au_dtime_revert(p->dt[CHILD] + SRC); + mutex_unlock(&hd->d_inode->i_mutex); + if (do_dt_dstdir) { + hd = p->dt[CHILD][DST].dt_h_dentry; + mutex_lock_nested(&hd->d_inode->i_mutex, AuLsc_I_CHILD); + au_dtime_revert(p->dt[CHILD] + DST); + mutex_unlock(&hd->d_inode->i_mutex); + } + } + out_hdir: + au_ren_unlock(&p->a); + out_children: + au_nhash_fin(&p->a.whlist); + out_unlock: + if (unlikely(err && au_ftest_ren(p->a.flags, ISDIR))) { + au_update_dbstart(dentry); + d_drop(dentry); + } + if (!err) { + d_move(src_dentry, dentry); +#if 0 + lktr_set_pid(current->pid, LktrArrayPid); + AuDbgDentry(src_dentry); + AuDbgDentry(dentry); + lktr_clear_pid(current->pid, LktrArrayPid); +#endif +#if 0 + if (inode[DST]) { + inode[DST]->i_flags |= S_DEAD; + ii_write_unlock(inode[DST]); + } +#endif + } + if (au_ftest_ren(p->a.flags, ISSAMEDIR)) + di_write_unlock(p->a.parent[DST]); + else + di_write_unlock2(p->a.parent[SRC], p->a.parent[DST]); + aufs_read_and_write_unlock2(dentry, src_dentry); + out_free: + kfree(p); + out: + iput(inode[DST]); + AuTraceErr(err); + //lktr_clear_pid(current->pid, LktrArrayPid); + return err; +} --- linux-2.6.28.orig/ubuntu/aufs/BOM +++ linux-2.6.28/ubuntu/aufs/BOM @@ -0,0 +1,3 @@ +Downloaded from: pserver:anonymous@aufs.cvs.sourceforge.net:/cvsroot/aufs +Current Version: Mon, 22 Sep 2008 +Comments: Unmodified upstream checkout --- linux-2.6.28.orig/ubuntu/aufs/inode.h +++ linux-2.6.28/ubuntu/aufs/inode.h @@ -0,0 +1,545 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * inode operations + * + * $Id: inode.h,v 1.13 2008/09/15 03:14:44 sfjro Exp $ + */ + +#ifndef __AUFS_INODE_H__ +#define __AUFS_INODE_H__ + +#ifdef __KERNEL__ + +#include +#include +#include +#include +#include "hinode.h" +#include "misc.h" +#include "super.h" + +struct au_hinode; +struct au_vdir; +struct au_iinfo { + atomic_t ii_generation; + struct super_block *ii_hsb1; /* no get/put */ + + struct au_rwsem ii_rwsem; + aufs_bindex_t ii_bstart, ii_bend; + __u32 ii_higen; + struct au_hinode *ii_hinode; + struct au_vdir *ii_vdir; +}; + +struct aufs_icntnr { + struct au_iinfo iinfo; + struct inode vfs_inode; +}; + +struct au_pin1 { + /* input */ + struct dentry *dentry; + unsigned char di_locked, lsc_di, lsc_hi; + /* auto */ + unsigned char do_verify; + + /* output */ + struct dentry *parent; + struct inode *h_dir; +}; + +enum {AuPin_PARENT, AuPin_GPARENT}; +struct au_pin { +#ifdef CONFIG_AUFS_HINOTIFY + struct au_pin1 pin[2]; +#else + struct au_pin1 pin[1]; /* no grand parent */ +#endif +}; + +/* ---------------------------------------------------------------------- */ + +/* inode.c */ +int au_refresh_hinode_self(struct inode *inode); +int au_refresh_hinode(struct inode *inode, struct dentry *dentry); +struct inode *au_new_inode(struct dentry *dentry); +int au_test_ro(struct super_block *sb, aufs_bindex_t bindex, + struct inode *inode); +int au_test_h_perm(struct inode *h_inode, int mask, int dlgt); +int au_test_h_perm_sio(struct inode *h_inode, int mask, int dlgt); + +/* i_op.c */ +extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop; + +/* au_wr_dir flags */ +#define AuWrDir_ADD_ENTRY 1 +#define AuWrDir_ISDIR (1 << 1) +#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name) +#define au_fset_wrdir(flags, name) { (flags) |= AuWrDir_##name; } +#define au_fclr_wrdir(flags, name) { (flags) &= ~AuWrDir_##name; } + +struct au_wr_dir_args { + aufs_bindex_t force_btgt; + unsigned char flags; +}; +int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry, + struct au_wr_dir_args *args); + +void au_pin_init(struct au_pin *args, struct dentry *dentry, int di_locked, + int lsc_di, int lsc_hi, int do_gp); +int au_pin(struct au_pin *args, struct dentry *dentry, aufs_bindex_t bindex, + int di_locked, int do_gp) __must_check; +int au_do_pin(struct au_pin1 *p, struct au_pin1 *gp, const aufs_bindex_t bindex, + const int do_gp) __must_check; +void au_do_unpin(struct au_pin1 *p, struct au_pin1 *gp); + +/* i_op_add.c */ +struct au_ndx; +int au_may_add(struct dentry *dentry, aufs_bindex_t bindex, + struct dentry *h_parent, int isdir, struct au_ndx *ndx); +int aufs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev); +int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname); +int aufs_create(struct inode *dir, struct dentry *dentry, int mode, + struct nameidata *nd); +int aufs_link(struct dentry *src_dentry, struct inode *dir, + struct dentry *dentry); +int aufs_mkdir(struct inode *dir, struct dentry *dentry, int mode); + +/* i_op_del.c */ +int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup); +int au_may_del(struct dentry *dentry, aufs_bindex_t bindex, + struct dentry *h_parent, int isdir, struct au_ndx *ndx); +int aufs_unlink(struct inode *dir, struct dentry *dentry); +int aufs_rmdir(struct inode *dir, struct dentry *dentry); + +/* i_op_ren.c */ +int au_wbr(struct dentry *dentry, aufs_bindex_t btgt); +int aufs_rename(struct inode *src_dir, struct dentry *src_dentry, + struct inode *dir, struct dentry *dentry); + +#ifdef CONFIG_AUFS_DLGT +/* dlgt.c */ +int au_security_inode_permission(struct inode *h_inode, int mask, + struct nameidata *fake_nd, int dlgt); +#else +static inline +int au_security_inode_permission(struct inode *h_inode, int mask, + struct nameidata *fake_nd, int dlgt) +{ + return vfsub_security_inode_permission(h_inode, mask, fake_nd); +} +#endif /* CONFIG_AUFS_DLGT */ + +#ifdef CONFIG_AUFS_HIN_OR_FUSE +/* hin_or_fuse.c */ +int aufs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *st); +#endif + +#if 0 /* reserved for future use */ +/* xattr.c */ +int aufs_setxattr(struct dentry *dentry, const char *name, const void *value, + size_t sz, int flags); +ssize_t aufs_getxattr(struct dentry *dentry, const char *name, void *value, + size_t sz); +ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t sz); +int aufs_removexattr(struct dentry *dentry, const char *name); +#endif + +/* iinfo.c */ +struct au_iinfo *au_ii(struct inode *inode); +struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex); +aufs_bindex_t au_ii_br_id(struct inode *inode, aufs_bindex_t bindex); + +void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex); +void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex, + struct dentry *h_wh); +unsigned int au_hi_flags(struct inode *inode, int isdir); + +/* hinode flags */ +#define AuHi_XINO 1 +#define AuHi_NOTIFY (1 << 1) +#define au_ftest_hi(flags, name) ((flags) & AuHi_##name) +#define au_fset_hi(flags, name) { (flags) |= AuHi_##name; } +#define au_fclr_hi(flags, name) { (flags) &= ~AuHi_##name; } +#ifndef CONFIG_AUFS_HINOTIFY +#undef AuHi_NOTIFY +#define AuHi_NOTIFY 0 +#endif + +void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex, + struct inode *h_inode, unsigned int flags); + +void au_update_iigen(struct inode *inode); +void au_update_brange(struct inode *inode, int do_put_zero); + +int au_iinfo_init(struct inode *inode); +void au_iinfo_fin(struct inode *inode); + +/* plink.c */ +#ifdef CONFIG_AUFS_DEBUG +void au_plink_list(struct super_block *sb); +#else +static inline void au_plink_list(struct super_block *sb) +{ + /* nothing */ +} +#endif +int au_plink_test(struct super_block *sb, struct inode *inode); +struct dentry *au_plink_lkup(struct super_block *sb, aufs_bindex_t bindex, + struct inode *inode); +void au_plink_append(struct super_block *sb, struct inode *inode, + struct dentry *h_dentry, aufs_bindex_t bindex); +void au_plink_put(struct super_block *sb); +void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id); + +/* ---------------------------------------------------------------------- */ + +/* lock subclass for iinfo */ +enum { + AuLsc_II_CHILD, /* child first */ + AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hinotify */ + AuLsc_II_CHILD3, /* copyup dirs */ + AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */ + AuLsc_II_PARENT2, + AuLsc_II_PARENT3, + AuLsc_II_PARENT4, + AuLsc_II_NEW_CHILD, +}; + +/* + * ii_read_lock_child, ii_write_lock_child, + * ii_read_lock_child2, ii_write_lock_child2, + * ii_read_lock_child3, ii_write_lock_child3, + * ii_read_lock_parent, ii_write_lock_parent, + * ii_read_lock_parent2, ii_write_lock_parent2, + * ii_read_lock_parent3, ii_write_lock_parent3, + * ii_read_lock_parent4, ii_write_lock_parent4, + * ii_read_lock_new_child, ii_write_lock_new_child, + */ +#define AuReadLockFunc(name, lsc) \ +static inline void ii_read_lock_##name(struct inode *i) \ +{ au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); } + +#define AuWriteLockFunc(name, lsc) \ +static inline void ii_write_lock_##name(struct inode *i) \ +{ au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); } + +#define AuRWLockFuncs(name, lsc) \ + AuReadLockFunc(name, lsc) \ + AuWriteLockFunc(name, lsc) + +AuRWLockFuncs(child, CHILD); +AuRWLockFuncs(child2, CHILD2); +AuRWLockFuncs(child3, CHILD3); +AuRWLockFuncs(parent, PARENT); +AuRWLockFuncs(parent2, PARENT2); +AuRWLockFuncs(parent3, PARENT3); +AuRWLockFuncs(parent4, PARENT4); +AuRWLockFuncs(new_child, NEW_CHILD); + +#undef AuReadLockFunc +#undef AuWriteLockFunc +#undef AuRWLockFuncs + +/* + * ii_read_unlock, ii_write_unlock, ii_downgrade_lock + */ +AuSimpleUnlockRwsemFuncs(ii, struct inode *i, au_ii(i)->ii_rwsem); + +/* to debug easier, do not make them inlined functions */ +#define IiMustReadLock(i) do { \ + SiMustAnyLock((i)->i_sb); \ + AuRwMustReadLock(&au_ii(i)->ii_rwsem); \ +} while (0) + +#define IiMustWriteLock(i) do { \ + SiMustAnyLock((i)->i_sb); \ + AuRwMustWriteLock(&au_ii(i)->ii_rwsem); \ +} while (0) + +#define IiMustAnyLock(i) do { \ + SiMustAnyLock((i)->i_sb); \ + AuRwMustAnyLock(&au_ii(i)->ii_rwsem); \ +} while (0) + +#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem) + +/* ---------------------------------------------------------------------- */ + +static inline struct inode *au_igrab(struct inode *inode) +{ + if (inode) { + AuDebugOn(!atomic_read(&inode->i_count)); + atomic_inc_return(&inode->i_count); + } + return inode; +} + +/* ---------------------------------------------------------------------- */ + +static inline aufs_bindex_t au_ibstart(struct inode *inode) +{ + IiMustAnyLock(inode); + return au_ii(inode)->ii_bstart; +} + +static inline aufs_bindex_t au_ibend(struct inode *inode) +{ + IiMustAnyLock(inode); + return au_ii(inode)->ii_bend; +} + +static inline struct au_vdir *au_ivdir(struct inode *inode) +{ + IiMustAnyLock(inode); + AuDebugOn(!S_ISDIR(inode->i_mode)); + return au_ii(inode)->ii_vdir; +} + +static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex) +{ + struct au_hinode *hinode; + IiMustAnyLock(inode); + hinode = au_ii(inode)->ii_hinode + bindex; + return hinode->hi_whdentry; +} + +static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex) +{ + IiMustWriteLock(inode); + AuDebugOn(au_sbend(inode->i_sb) < bindex || bindex < au_ibstart(inode)); + au_ii(inode)->ii_bend = bindex; +} + +static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir) +{ + IiMustWriteLock(inode); + AuDebugOn(!S_ISDIR(inode->i_mode) || (au_ii(inode)->ii_vdir && vdir)); + au_ii(inode)->ii_vdir = vdir; +} + +static inline void au_hiput(struct au_hinode *hinode) +{ + au_hin_free(hinode); + dput(hinode->hi_whdentry); + iput(hinode->hi_inode); +} + +static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex) +{ + /* todo: this lock check causes some unnecessary locks in callers. */ + IiMustAnyLock(inode); + return au_ii(inode)->ii_hinode + bindex; +} + +/* tiny test for inode number */ +/* tmpfs generation is too rough */ +static inline int au_test_higen(struct inode *inode, struct inode *h_inode) +{ + struct au_iinfo *iinfo; + + IiMustAnyLock(inode); + + iinfo = au_ii(inode); + return !(iinfo->ii_hsb1 == h_inode->i_sb + && iinfo->ii_higen == h_inode->i_generation); +} + +static inline au_gen_t au_iigen(struct inode *inode) +{ + return atomic_read(&au_ii(inode)->ii_generation); +} + +#ifdef CONFIG_AUFS_HINOTIFY +static inline au_gen_t au_iigen_dec(struct inode *inode) +{ + /* AuDbg("i%lu\n", inode->i_ino); */ + return atomic_dec_return(&au_ii(inode)->ii_generation); +} +#endif + +/* ---------------------------------------------------------------------- */ + +#ifdef CONFIG_AUFS_HINOTIFY +static inline struct au_pin1 *au_pin_gp(struct au_pin *args) +{ + return args->pin + AuPin_GPARENT; +} + +/* hinotify.c */ +void au_unpin_gp(struct au_pin *args); + +#else + +static inline struct au_pin1 *au_pin_gp(struct au_pin *args) +{ + return NULL; +} + +static inline void au_unpin_gp(struct au_pin *args) +{ + /* empty */ +} +#endif /* HINOTIFY */ + +static inline void au_unpin(struct au_pin *args) +{ + au_do_unpin(args->pin + AuPin_PARENT, au_pin_gp(args)); +} + +static inline +struct au_hinode *au_do_pinned_hdir(struct au_pin1 *pin, aufs_bindex_t bindex) +{ + if (pin && pin->parent) + return au_hi(pin->parent->d_inode, bindex); + return NULL; +} + +struct dentry *au_do_pinned_h_parent(struct au_pin1 *pin, aufs_bindex_t bindex); + +static inline struct dentry *au_do_pinned_parent(struct au_pin1 *pin) +{ + if (pin) + return pin->parent; + return NULL; +} + +static inline struct inode *au_do_pinned_h_dir(struct au_pin1 *pin) +{ + if (pin) + return pin->h_dir; + return NULL; +} + +static inline +void au_pin_do_set_dentry(struct au_pin1 *pin, struct dentry *dentry) +{ + if (pin) + pin->dentry = dentry; +} + +static inline +void au_pin_do_set_parent(struct au_pin1 *pin, struct dentry *parent) +{ + if (pin) { + dput(pin->parent); + pin->parent = dget(parent); + } +} + +static inline void au_pin_do_set_h_dir(struct au_pin1 *pin, struct inode *h_dir) +{ + if (pin) { + iput(pin->h_dir); + pin->h_dir = au_igrab(h_dir); + } +} + +static inline +void au_pin_do_set_parent_lflag(struct au_pin1 *pin, unsigned char lflag) +{ + if (pin) + pin->di_locked = lflag; +} + +static inline +struct au_hinode *au_pinned_hdir(struct au_pin *args, aufs_bindex_t bindex) +{ + return au_do_pinned_hdir(args->pin + AuPin_PARENT, bindex); +} + +static inline +struct au_hinode *au_pinned_hgdir(struct au_pin *args, aufs_bindex_t bindex) +{ + return au_do_pinned_hdir(au_pin_gp(args), bindex); +} + +static inline +struct dentry *au_pinned_h_parent(struct au_pin *args, aufs_bindex_t bindex) +{ + return au_do_pinned_h_parent(args->pin + AuPin_PARENT, bindex); +} + +#if 0 /* reserved for future use */ +static inline +struct dentry *au_pinned_h_gparent(struct au_pin *args, aufs_bindex_t bindex) +{ + return au_do_pinned_h_parent(au_pin_gp(args), bindex); +} +#endif + +static inline +struct dentry *au_pinned_parent(struct au_pin *args) +{ + return au_do_pinned_parent(args->pin + AuPin_PARENT); +} + +static inline +struct dentry *au_pinned_gparent(struct au_pin *args) +{ + return au_do_pinned_parent(au_pin_gp(args)); +} + +static inline +struct inode *au_pinned_h_dir(struct au_pin *args) +{ + return au_do_pinned_h_dir(args->pin + AuPin_PARENT); +} + +static inline +struct inode *au_pinned_h_gdir(struct au_pin *args) +{ + return au_do_pinned_h_dir(au_pin_gp(args)); +} + +static inline void au_pin_set_parent(struct au_pin *args, struct dentry *d) +{ + au_pin_do_set_parent(args->pin + AuPin_PARENT, d); +} + +static inline void au_pin_set_gparent(struct au_pin *args, struct dentry *d) +{ + au_pin_do_set_parent(au_pin_gp(args), d); +} + +static inline void au_pin_set_h_dir(struct au_pin *args, struct inode *h_dir) +{ + au_pin_do_set_h_dir(args->pin + AuPin_PARENT, h_dir); +} + +static inline void au_pin_set_h_gdir(struct au_pin *args, struct inode *h_dir) +{ + au_pin_do_set_h_dir(au_pin_gp(args), h_dir); +} + +static inline +void au_pin_set_parent_lflag(struct au_pin *args, unsigned char lflag) +{ + au_pin_do_set_parent_lflag(args->pin + AuPin_PARENT, lflag); +} + +static inline +void au_pin_set_gparent_lflag(struct au_pin *args, unsigned char lflag) +{ + au_pin_do_set_parent_lflag(au_pin_gp(args), lflag); +} + +#endif /* __KERNEL__ */ +#endif /* __AUFS_INODE_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/dir.c +++ linux-2.6.28/ubuntu/aufs/dir.c @@ -0,0 +1,547 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs is free software; you can redistribute it and/or modify + * it under the terms of the 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 St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * directory operations + * + * $Id: dir.c,v 1.13 2008/09/22 03:52:19 sfjro Exp $ + */ + +#include +#include "aufs.h" + +static int reopen_dir(struct file *file) +{ + int err; + struct dentry *dentry, *h_dentry; + aufs_bindex_t bindex, btail, bstart; + struct file *h_file; + + dentry = file->f_dentry; + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode)); + + /* open all hidden dirs */ + bstart = au_dbstart(dentry); +#if 1 /* todo: necessary? */ + for (bindex = au_fbstart(file); bindex < bstart; bindex++) + au_set_h_fptr(file, bindex, NULL); +#endif + au_set_fbstart(file, bstart); + btail = au_dbtaildir(dentry); +#if 1 /* todo: necessary? */ + for (bindex = au_fbend(file); btail < bindex; bindex--) + au_set_h_fptr(file, bindex, NULL); +#endif + au_set_fbend(file, btail); + for (bindex = bstart; bindex <= btail; bindex++) { + h_dentry = au_h_dptr(dentry, bindex); + if (!h_dentry) + continue; + h_file = au_h_fptr(file, bindex); + if (h_file) { + AuDebugOn(h_file->f_dentry != h_dentry); + continue; + } + + h_file = au_h_open(dentry, bindex, file->f_flags, file); + err = PTR_ERR(h_file); + if (IS_ERR(h_file)) + goto out; /* close all? */ + /* cpup_file_flags(h_file, file); */ + au_set_h_fptr(file, bindex, h_file); + } + au_update_figen(file); + /* todo: necessary? */ + /* file->f_ra = h_file->f_ra; */ + err = 0; + + out: + AuTraceErr(err); + return err; +} + +static int do_open_dir(struct file *file, int flags) +{ + int err; + aufs_bindex_t bindex, btail; + struct dentry *dentry, *h_dentry; + struct file *h_file; + + dentry = file->f_dentry; + LKTRTrace("%.*s, 0x%x\n", AuDLNPair(dentry), flags); + AuDebugOn(!dentry->d_inode || !S_ISDIR(dentry->d_inode->i_mode)); + + err = 0; + au_set_fvdir_cache(file, NULL); + file->f_version = dentry->d_inode->i_version; + bindex = au_dbstart(dentry); + au_set_fbstart(file, bindex); + btail = au_dbtaildir(dentry); + au_set_fbend(file, btail); + for (; !err && bindex <= btail; bindex++) { + h_dentry = au_h_dptr(dentry, bindex); + if (!h_dentry) + continue; + + h_file = au_h_open(dentry, bindex, flags, file); + if (IS_ERR(h_file)) { + err = PTR_ERR(h_file); + break; + } + au_set_h_fptr(file, bindex, h_file); + } + au_update_figen(file); + /* todo: necessary? */ + /* file->f_ra = h_file->f_ra; */ + if (!err) + return 0; /* success */ + + /* close all */ + for (bindex = au_fbstart(file); bindex <= btail; bindex++) + au_set_h_fptr(file, bindex, NULL); + au_set_fbstart(file, -1); + au_set_fbend(file, -1); + return err; +} + +static int aufs_open_dir(struct inode *inode, struct file *file) +{ + LKTRTrace("i%lu, %.*s\n", inode->i_ino, AuDLNPair(file->f_dentry)); + + return au_do_open(inode, file, do_open_dir); +} + +static int aufs_release_dir(struct inode *inode, struct file *file) +{ + struct au_vdir *vdir_cache; + struct super_block *sb; + + LKTRTrace("i%lu, %.*s\n", inode->i_ino, AuDLNPair(file->f_dentry)); + + sb = file->f_dentry->d_sb; + si_noflush_read_lock(sb); + fi_write_lock(file); + vdir_cache = au_fvdir_cache(file); + if (vdir_cache) + au_vdir_free(vdir_cache); + fi_write_unlock(file); + au_finfo_fin(file); + si_read_unlock(sb); + return 0; +} + +static int fsync_dir(struct dentry *dentry, int datasync) +{ + int err; + struct inode *inode; + struct super_block *sb; + aufs_bindex_t bend, bindex; + + LKTRTrace("%.*s, %d\n", AuDLNPair(dentry), datasync); + DiMustAnyLock(dentry); + sb = dentry->d_sb; + SiMustAnyLock(sb); + inode = dentry->d_inode; + IMustLock(inode); + IiMustAnyLock(inode); + + err = 0; + bend = au_dbend(dentry); + for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) { + struct dentry *h_dentry; + struct inode *h_inode; + struct file_operations *fop; + + if (au_test_ro(sb, bindex, inode)) + continue; + h_dentry = au_h_dptr(dentry, bindex); + if (!h_dentry) + continue; + h_inode = h_dentry->d_inode; + if (!h_inode) + continue; + + /* cf. fs/nsfd/vfs.c and fs/nfsd/nfs4recover.c */ + /* todo: inotiry fired? */ + mutex_lock(&h_inode->i_mutex); + fop = (void *)h_inode->i_fop; + err = filemap_fdatawrite(h_inode->i_mapping); + if (!err && fop && fop->fsync) + err = fop->fsync(NULL, h_dentry, datasync); + if (!err) + err = filemap_fdatawrite(h_inode->i_mapping); + if (!err) + au_update_fuse_h_inode(NULL, h_dentry); /*ignore*/ + mutex_unlock(&h_inode->i_mutex); + } + + AuTraceErr(err); + return err; +} + +/* + * @file may be NULL + */ +static int aufs_fsync_dir(struct file *file, struct dentry *dentry, + int datasync) +{ + int err; + struct inode *inode; + struct file *h_file; + struct super_block *sb; + aufs_bindex_t bend, bindex; + + LKTRTrace("%.*s, %d\n", AuDLNPair(dentry), datasync); + inode = dentry->d_inode; + IMustLock(inode); + + err = 0; + sb = dentry->d_sb; + si_noflush_read_lock(sb); + if (file) { + err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1, + /*locked*/1); + if (unlikely(err)) + goto out; + } else + di_write_lock_child(dentry); + + if (file) { + bend = au_fbend(file); + for (bindex = au_fbstart(file); !err && bindex <= bend; + bindex++) { + h_file = au_h_fptr(file, bindex); + if (!h_file || au_test_ro(sb, bindex, inode)) + continue; + + err = -EINVAL; + if (h_file->f_op && h_file->f_op->fsync) { + /* todo: try do_fsync() in fs/sync.c? */ + mutex_lock(&h_file->f_mapping->host->i_mutex); + err = h_file->f_op->fsync + (h_file, h_file->f_dentry, datasync); + if (!err) + au_update_fuse_h_inode + (h_file->f_vfsmnt, + h_file->f_dentry); + /*ignore*/ + mutex_unlock(&h_file->f_mapping->host->i_mutex); + } + } + } else + err = fsync_dir(dentry, datasync); + au_cpup_attr_timesizes(inode); + di_write_unlock(dentry); + if (file) + fi_write_unlock(file); + + out: + si_read_unlock(sb); + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static int aufs_readdir(struct file *file, void *dirent, filldir_t filldir) +{ + int err, iflag; + struct dentry *dentry; + struct inode *inode; + struct super_block *sb; + + dentry = file->f_dentry; + LKTRTrace("%.*s, pos %lld\n", AuDLNPair(dentry), file->f_pos); + inode = dentry->d_inode; + IMustLock(inode); + + au_nfsd_lockdep_off(); + sb = dentry->d_sb; + si_read_lock(sb, AuLock_FLUSH); + err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1, /*locked*/1); + if (unlikely(err)) + goto out; + + err = au_vdir_init(file); + if (unlikely(err)) { + di_write_unlock(dentry); + goto out_unlock; + } + + /* nfsd filldir calls lookup_one_len(). */ + iflag = AuLock_IW; + if (unlikely(au_test_nfsd(current))) + iflag = AuLock_IR; + di_downgrade_lock(dentry, iflag); + err = au_vdir_fill_de(file, dirent, filldir); + + fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibstart(inode))); + di_read_unlock(dentry, iflag); + + out_unlock: + fi_write_unlock(file); + out: + si_read_unlock(sb); + au_nfsd_lockdep_on(); + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +#define AuTestEmpty_WHONLY 1 +#define AuTestEmpty_DLGT (1 << 1) +#define AuTestEmpty_DIRPERM1 (1 << 2) +#define AuTestEmpty_CALLED (1 << 3) +#define AuTestEmpty_SHWH (1 << 4) +#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name) +#define au_fset_testempty(flags, name) { (flags) |= AuTestEmpty_##name; } +#define au_fclr_testempty(flags, name) { (flags) &= ~AuTestEmpty_##name; } +#ifndef CONFIG_AUFS_DLGT +#undef AuTestEmpty_DLGT +#define AuTestEmpty_DLGT 0 +#undef AuTestEmpty_DIRPERM1 +#define AuTestEmpty_DIRPERM1 0 +#endif +#ifndef CONFIG_AUFS_SHWH +#undef AuTestEmpty_SHWH +#define AuTestEmpty_SHWH 0 +#endif + +struct test_empty_arg { + struct au_nhash *whlist; + unsigned int flags; + int err; + aufs_bindex_t bindex; +}; + +static int test_empty_cb(void *__arg, const char *__name, int namelen, + loff_t offset, u64 ino, unsigned int d_type) +{ + struct test_empty_arg *arg = __arg; + char *name = (void *)__name; + + LKTRTrace("%.*s\n", namelen, name); + + arg->err = 0; + au_fset_testempty(arg->flags, CALLED); + /* smp_mb(); */ + if (name[0] == '.' + && (namelen == 1 || (name[1] == '.' && namelen == 2))) + return 0; /* success */ + + if (namelen <= AUFS_WH_PFX_LEN + || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { + if (au_ftest_testempty(arg->flags, WHONLY) + && !au_nhash_test_known_wh(arg->whlist, name, namelen)) + arg->err = -ENOTEMPTY; + goto out; + } + + name += AUFS_WH_PFX_LEN; + namelen -= AUFS_WH_PFX_LEN; + if (!au_nhash_test_known_wh(arg->whlist, name, namelen)) + arg->err = au_nhash_append_wh + (arg->whlist, name, namelen, ino, d_type, arg->bindex, + au_ftest_testempty(arg->flags, SHWH)); + + out: + /* smp_mb(); */ + AuTraceErr(arg->err); + return arg->err; +} + +static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg) +{ + int err, dlgt; + struct file *h_file; + + LKTRTrace("%.*s, {%p, 0x%x, %d}\n", + AuDLNPair(dentry), arg->whlist, arg->flags, arg->bindex); + + h_file = au_h_open(dentry, arg->bindex, + O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE, + /*file*/NULL); + err = PTR_ERR(h_file); + if (IS_ERR(h_file)) + goto out; + err = 0; + if (unlikely(au_opt_test(au_mntflags(dentry->d_sb), UDBA_INOTIFY) + && !h_file->f_dentry->d_inode->i_nlink)) + goto out_put; + + dlgt = au_ftest_testempty(arg->flags, DLGT); + do { + arg->err = 0; + au_fclr_testempty(arg->flags, CALLED); + /* smp_mb(); */ + err = vfsub_readdir(h_file, test_empty_cb, arg, dlgt); + if (err >= 0) + err = arg->err; + } while (!err && au_ftest_testempty(arg->flags, CALLED)); + + out_put: + fput(h_file); + au_sbr_put(dentry->d_sb, arg->bindex); + out: + AuTraceErr(err); + return err; +} + +struct do_test_empty_args { + int *errp; + struct dentry *dentry; + struct test_empty_arg *arg; +}; + +static void call_do_test_empty(void *args) +{ + struct do_test_empty_args *a = args; + *a->errp = do_test_empty(a->dentry, a->arg); +} + +static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg) +{ + int err, wkq_err; + struct dentry *h_dentry; + struct inode *h_inode; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + h_dentry = au_h_dptr(dentry, arg->bindex); + AuDebugOn(!h_dentry); + h_inode = h_dentry->d_inode; + AuDebugOn(!h_inode); + + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); + err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ, + au_test_dlgt(au_mntflags(dentry->d_sb))); + mutex_unlock(&h_inode->i_mutex); + if (!err) + err = do_test_empty(dentry, arg); + else { + struct do_test_empty_args args = { + .errp = &err, + .dentry = dentry, + .arg = arg + }; + unsigned int flags = arg->flags; + + au_fclr_testempty(arg->flags, DLGT); + au_fclr_testempty(arg->flags, DIRPERM1); + wkq_err = au_wkq_wait(call_do_test_empty, &args, /*dlgt*/0); + if (unlikely(wkq_err)) + err = wkq_err; + arg->flags = flags; + } + + AuTraceErr(err); + return err; +} + +int au_test_empty_lower(struct dentry *dentry) +{ + int err; + struct inode *inode; + struct test_empty_arg arg; + struct au_nhash *whlist; + aufs_bindex_t bindex, bstart, btail; + unsigned int mnt_flags; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + inode = dentry->d_inode; + AuDebugOn(!inode || !S_ISDIR(inode->i_mode)); + + whlist = au_nhash_new(GFP_NOFS); + err = PTR_ERR(whlist); + if (IS_ERR(whlist)) + goto out; + + bstart = au_dbstart(dentry); + mnt_flags = au_mntflags(dentry->d_sb); + arg.whlist = whlist; + arg.flags = 0; + if (unlikely(au_test_dlgt(mnt_flags))) + au_fset_testempty(arg.flags, DLGT); + if (unlikely(au_opt_test(mnt_flags, SHWH))) + au_fset_testempty(arg.flags, SHWH); + arg.bindex = bstart; + err = do_test_empty(dentry, &arg); + if (unlikely(err)) + goto out_whlist; + + au_fset_testempty(arg.flags, WHONLY); + if (unlikely(au_test_dirperm1(mnt_flags))) + au_fset_testempty(arg.flags, DIRPERM1); + btail = au_dbtaildir(dentry); + for (bindex = bstart + 1; !err && bindex <= btail; bindex++) { + struct dentry *h_dentry; + h_dentry = au_h_dptr(dentry, bindex); + if (h_dentry && h_dentry->d_inode) { + arg.bindex = bindex; + err = do_test_empty(dentry, &arg); + } + } + + out_whlist: + au_nhash_del(whlist); + out: + AuTraceErr(err); + return err; +} + +int au_test_empty(struct dentry *dentry, struct au_nhash *whlist) +{ + int err; + struct inode *inode; + struct test_empty_arg arg; + aufs_bindex_t bindex, btail; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + inode = dentry->d_inode; + AuDebugOn(!inode || !S_ISDIR(inode->i_mode)); + + err = 0; + arg.whlist = whlist; + arg.flags = AuTestEmpty_WHONLY; + if (unlikely(au_opt_test(au_mntflags(dentry->d_sb), SHWH))) + au_fset_testempty(arg.flags, SHWH); + btail = au_dbtaildir(dentry); + for (bindex = au_dbstart(dentry); !err && bindex <= btail; bindex++) { + struct dentry *h_dentry; + h_dentry = au_h_dptr(dentry, bindex); + if (h_dentry && h_dentry->d_inode) { + arg.bindex = bindex; + err = sio_test_empty(dentry, &arg); + } + } + + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct file_operations aufs_dir_fop = { + .read = generic_read_dir, + .readdir = aufs_readdir, + .open = aufs_open_dir, + .release = aufs_release_dir, + .flush = aufs_flush, + .fsync = aufs_fsync_dir, +}; --- linux-2.6.28.orig/ubuntu/ndiswrapper/ntoskernel_io.c +++ linux-2.6.28/ubuntu/ndiswrapper/ntoskernel_io.c @@ -0,0 +1,1106 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#include "ntoskernel.h" +#include "ndis.h" +#include "wrapndis.h" +#include "usb.h" +#include "loader.h" +#include "ntoskernel_io_exports.h" + +wstdcall void WIN_FUNC(IoAcquireCancelSpinLock,1) + (KIRQL *irql) __acquires(irql) +{ + spin_lock_bh(&irp_cancel_lock); + *irql = 0; +} + +wstdcall void WIN_FUNC(IoReleaseCancelSpinLock,1) + (KIRQL irql) __releases(irql) +{ + spin_unlock_bh(&irp_cancel_lock); +} + +wstdcall int WIN_FUNC(IoIsWdmVersionAvailable,2) + (UCHAR major, UCHAR minor) +{ + IOENTER("%d, %x", major, minor); + if (major == 1 && + (minor == 0x30 || // Windows 2003 + minor == 0x20 || // Windows XP + minor == 0x10)) // Windows 2000 + IOEXIT(return TRUE); + IOEXIT(return FALSE); +} + +wstdcall BOOLEAN WIN_FUNC(IoIs32bitProcess,1) + (struct irp *irp) +{ +#ifdef CONFIG_X86_64 + return FALSE; +#else + return TRUE; +#endif +} + +wstdcall void WIN_FUNC(IoInitializeIrp,3) + (struct irp *irp, USHORT size, CCHAR stack_count) +{ + IOENTER("irp: %p, %d, %d", irp, size, stack_count); + + memset(irp, 0, size); + irp->size = size; + irp->stack_count = stack_count; + irp->current_location = stack_count; + IoGetCurrentIrpStackLocation(irp) = IRP_SL(irp, stack_count); + IOEXIT(return); +} + +wstdcall void WIN_FUNC(IoReuseIrp,2) + (struct irp *irp, NTSTATUS status) +{ + IOENTER("%p, %d", irp, status); + if (irp) { + UCHAR alloc_flags; + + alloc_flags = irp->alloc_flags; + IoInitializeIrp(irp, irp->size, irp->stack_count); + irp->alloc_flags = alloc_flags; + irp->io_status.status = status; + } + IOEXIT(return); +} + +wstdcall struct irp *WIN_FUNC(IoAllocateIrp,2) + (char stack_count, BOOLEAN charge_quota) +{ + struct irp *irp; + int irp_size; + + IOENTER("count: %d", stack_count); + stack_count++; + irp_size = IoSizeOfIrp(stack_count); + irp = kmalloc(irp_size, irql_gfp()); + if (irp) + IoInitializeIrp(irp, irp_size, stack_count); + IOTRACE("irp %p", irp); + IOEXIT(return irp); +} + +wstdcall BOOLEAN WIN_FUNC(IoCancelIrp,1) + (struct irp *irp) +{ + typeof(irp->cancel_routine) cancel_routine; + + /* NB: this function may be called at DISPATCH_LEVEL */ + IOTRACE("irp: %p", irp); + if (!irp) + return FALSE; + DUMP_IRP(irp); + IoAcquireCancelSpinLock(&irp->cancel_irql); + cancel_routine = xchg(&irp->cancel_routine, NULL); + IOTRACE("%p", cancel_routine); + irp->cancel = TRUE; + if (cancel_routine) { + struct io_stack_location *irp_sl; + irp_sl = IoGetCurrentIrpStackLocation(irp); + IOTRACE("%p, %p", irp_sl, irp_sl->dev_obj); + /* cancel_routine will release the spin lock */ + __release(irp->cancel_irql); + LIN2WIN2(cancel_routine, irp_sl->dev_obj, irp); + /* in usb's cancel, irp->cancel is set to indicate + * status of cancel */ + IOEXIT(return xchg(&irp->cancel, TRUE)); + } else { + IOTRACE("irp %p already canceled", irp); + IoReleaseCancelSpinLock(irp->cancel_irql); + IOEXIT(return FALSE); + } +} + +wstdcall void IoQueueThreadIrp(struct irp *irp) +{ + struct nt_thread *thread; + KIRQL irql; + + thread = get_current_nt_thread(); + if (thread) { + IOTRACE("thread: %p, task: %p", thread, thread->task); + irp->flags |= IRP_SYNCHRONOUS_API; + irql = nt_spin_lock_irql(&thread->lock, DISPATCH_LEVEL); + InsertTailList(&thread->irps, &irp->thread_list); + IoIrpThread(irp) = thread; + nt_spin_unlock_irql(&thread->lock, irql); + } else + IoIrpThread(irp) = NULL; +} + +wstdcall void IoDequeueThreadIrp(struct irp *irp) +{ + struct nt_thread *thread; + KIRQL irql; + + thread = IoIrpThread(irp); + if (thread) { + irql = nt_spin_lock_irql(&thread->lock, DISPATCH_LEVEL); + RemoveEntryList(&irp->thread_list); + nt_spin_unlock_irql(&thread->lock, irql); + } +} + +wstdcall void WIN_FUNC(IoFreeIrp,1) + (struct irp *irp) +{ + IOENTER("irp = %p", irp); + if (irp->flags & IRP_SYNCHRONOUS_API) + IoDequeueThreadIrp(irp); + kfree(irp); + + IOEXIT(return); +} + +wstdcall struct irp *WIN_FUNC(IoBuildAsynchronousFsdRequest,6) + (ULONG major_fn, struct device_object *dev_obj, void *buffer, + ULONG length, LARGE_INTEGER *offset, + struct io_status_block *user_status) +{ + struct irp *irp; + struct io_stack_location *irp_sl; + + IOENTER("%p", dev_obj); + if (!dev_obj) + IOEXIT(return NULL); + irp = IoAllocateIrp(dev_obj->stack_count, FALSE); + if (irp == NULL) { + WARNING("couldn't allocate irp"); + IOEXIT(return NULL); + } + + irp_sl = IoGetNextIrpStackLocation(irp); + irp_sl->major_fn = major_fn; + IOTRACE("major_fn: %d", major_fn); + irp_sl->minor_fn = 0; + irp_sl->flags = 0; + irp_sl->control = 0; + irp_sl->dev_obj = dev_obj; + irp_sl->file_obj = NULL; + irp_sl->completion_routine = NULL; + + if (dev_obj->flags & DO_DIRECT_IO) { + irp->mdl = IoAllocateMdl(buffer, length, FALSE, FALSE, irp); + if (irp->mdl == NULL) { + IoFreeIrp(irp); + return NULL; + } + MmProbeAndLockPages(irp->mdl, KernelMode, + major_fn == IRP_MJ_WRITE ? + IoReadAccess : IoWriteAccess); + IOTRACE("mdl: %p", irp->mdl); + } else if (dev_obj->flags & DO_BUFFERED_IO) { + irp->associated_irp.system_buffer = buffer; + irp->flags = IRP_BUFFERED_IO; + irp->mdl = NULL; + IOTRACE("buffer: %p", buffer); + } + if (major_fn == IRP_MJ_READ) { + irp_sl->params.read.length = length; + irp_sl->params.read.byte_offset = *offset; + } else if (major_fn == IRP_MJ_WRITE) { + irp_sl->params.write.length = length; + irp_sl->params.write.byte_offset = *offset; + } + irp->user_status = user_status; + IOTRACE("irp: %p", irp); + return irp; +} + +wstdcall struct irp *WIN_FUNC(IoBuildSynchronousFsdRequest,7) + (ULONG major_fn, struct device_object *dev_obj, void *buf, + ULONG length, LARGE_INTEGER *offset, struct nt_event *event, + struct io_status_block *user_status) +{ + struct irp *irp; + + irp = IoBuildAsynchronousFsdRequest(major_fn, dev_obj, buf, length, + offset, user_status); + if (irp == NULL) + return NULL; + irp->user_event = event; + IoQueueThreadIrp(irp); + return irp; +} + +wstdcall struct irp *WIN_FUNC(IoBuildDeviceIoControlRequest,9) + (ULONG ioctl, struct device_object *dev_obj, + void *input_buf, ULONG input_buf_len, void *output_buf, + ULONG output_buf_len, BOOLEAN internal_ioctl, + struct nt_event *event, struct io_status_block *io_status) +{ + struct irp *irp; + struct io_stack_location *irp_sl; + ULONG buf_len; + + IOENTER("%p, 0x%08x, %d", dev_obj, ioctl, internal_ioctl); + if (!dev_obj) + IOEXIT(return NULL); + irp = IoAllocateIrp(dev_obj->stack_count, FALSE); + if (irp == NULL) { + WARNING("couldn't allocate irp"); + return NULL; + } + irp_sl = IoGetNextIrpStackLocation(irp); + irp_sl->params.dev_ioctl.code = ioctl; + irp_sl->params.dev_ioctl.input_buf_len = input_buf_len; + irp_sl->params.dev_ioctl.output_buf_len = output_buf_len; + irp_sl->major_fn = (internal_ioctl) ? + IRP_MJ_INTERNAL_DEVICE_CONTROL : IRP_MJ_DEVICE_CONTROL; + IOTRACE("%d", IO_METHOD_FROM_CTL_CODE(ioctl)); + + switch (IO_METHOD_FROM_CTL_CODE(ioctl)) { + case METHOD_BUFFERED: + buf_len = max(input_buf_len, output_buf_len); + if (buf_len) { + irp->associated_irp.system_buffer = + ExAllocatePoolWithTag(NonPagedPool, buf_len, 0); + if (!irp->associated_irp.system_buffer) { + IoFreeIrp(irp); + IOEXIT(return NULL); + } + irp->associated_irp.system_buffer = input_buf; + if (input_buf) + memcpy(irp->associated_irp.system_buffer, + input_buf, input_buf_len); + irp->flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER; + if (output_buf) + irp->flags = IRP_INPUT_OPERATION; + irp->user_buf = output_buf; + } else + irp->user_buf = NULL; + break; + case METHOD_IN_DIRECT: + case METHOD_OUT_DIRECT: + if (input_buf) { + irp->associated_irp.system_buffer = + ExAllocatePoolWithTag(NonPagedPool, + input_buf_len, 0); + if (!irp->associated_irp.system_buffer) { + IoFreeIrp(irp); + IOEXIT(return NULL); + } + memcpy(irp->associated_irp.system_buffer, + input_buf, input_buf_len); + irp->flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER; + } + /* TODO: we are supposed to setup MDL, but USB layer + * doesn't use MDLs. Moreover, USB layer mirrors + * non-DMAable buffers, so no need to allocate + * DMAable buffer here */ + if (output_buf) { + irp->associated_irp.system_buffer = + ExAllocatePoolWithTag(NonPagedPool, + output_buf_len, 0); + if (!irp->associated_irp.system_buffer) { + IoFreeIrp(irp); + IOEXIT(return NULL); + } + irp->flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER; + } + break; + case METHOD_NEITHER: + irp->user_buf = output_buf; + irp_sl->params.dev_ioctl.type3_input_buf = input_buf; + break; + } + + irp->user_status = io_status; + irp->user_event = event; + IoQueueThreadIrp(irp); + + IOTRACE("irp: %p", irp); + IOEXIT(return irp); +} + +wfastcall NTSTATUS WIN_FUNC(IofCallDriver,2) + (struct device_object *dev_obj, struct irp *irp) +{ + struct io_stack_location *irp_sl; + NTSTATUS status; + driver_dispatch_t *major_func; + struct driver_object *drv_obj; + + if (irp->current_location <= 0) { + ERROR("invalid irp: %p, %d", irp, irp->current_location); + return STATUS_INVALID_PARAMETER; + } + IOTRACE("%p, %p, %p, %d, %d, %p", dev_obj, irp, dev_obj->drv_obj, + irp->current_location, irp->stack_count, + IoGetCurrentIrpStackLocation(irp)); + IoSetNextIrpStackLocation(irp); + DUMP_IRP(irp); + irp_sl = IoGetCurrentIrpStackLocation(irp); + drv_obj = dev_obj->drv_obj; + irp_sl->dev_obj = dev_obj; + major_func = drv_obj->major_func[irp_sl->major_fn]; + IOTRACE("major_func: %p, dev_obj: %p", major_func, dev_obj); + if (major_func) + status = LIN2WIN2(major_func, dev_obj, irp); + else { + ERROR("major_function %d is not implemented", + irp_sl->major_fn); + status = STATUS_NOT_SUPPORTED; + } + IOEXIT(return status); +} + +wfastcall void WIN_FUNC(IofCompleteRequest,2) + (struct irp *irp, CHAR prio_boost) +{ + struct io_stack_location *irp_sl; + +#ifdef IO_DEBUG + DUMP_IRP(irp); + if (irp->io_status.status == STATUS_PENDING) { + ERROR("invalid irp: %p, STATUS_PENDING", irp); + return; + } + if (irp->current_location < 0 || + irp->current_location >= irp->stack_count) { + ERROR("invalid irp: %p, %d", irp, irp->current_location); + return; + } +#endif + for (irp_sl = IoGetCurrentIrpStackLocation(irp); + irp->current_location < irp->stack_count; irp_sl++) { + struct device_object *dev_obj; + NTSTATUS status; + + DUMP_IRP(irp); + if (irp_sl->control & SL_PENDING_RETURNED) + irp->pending_returned = TRUE; + + /* current_location and dev_obj must be same as when + * driver called IoSetCompletionRoutine, which sets + * completion routine at next (lower) location, which + * is what we are going to call below; so we set + * current_location and dev_obj for the previous + * (higher) location */ + IoSkipCurrentIrpStackLocation(irp); + if (irp->current_location < irp->stack_count) + dev_obj = IoGetCurrentIrpStackLocation(irp)->dev_obj; + else + dev_obj = NULL; + + IOTRACE("%d, %d, %p", irp->current_location, irp->stack_count, + dev_obj); + if (irp_sl->completion_routine && + ((irp->io_status.status == STATUS_SUCCESS && + irp_sl->control & SL_INVOKE_ON_SUCCESS) || + (irp->io_status.status != STATUS_SUCCESS && + irp_sl->control & SL_INVOKE_ON_ERROR) || + (irp->cancel == TRUE && + irp_sl->control & SL_INVOKE_ON_CANCEL))) { + IOTRACE("calling completion_routine at: %p, %p", + irp_sl->completion_routine, irp_sl->context); + status = LIN2WIN3(irp_sl->completion_routine, + dev_obj, irp, irp_sl->context); + IOTRACE("status: %08X", status); + if (status == STATUS_MORE_PROCESSING_REQUIRED) + IOEXIT(return); + } else { + /* propagate pending status to next irp_sl */ + if (irp->pending_returned && + irp->current_location < irp->stack_count) + IoMarkIrpPending(irp); + } + } + + if (irp->user_status) { + irp->user_status->status = irp->io_status.status; + irp->user_status->info = irp->io_status.info; + } + + if (irp->user_event) { + IOTRACE("setting event %p", irp->user_event); + KeSetEvent(irp->user_event, prio_boost, FALSE); + } + + if (irp->associated_irp.system_buffer && + (irp->flags & IRP_DEALLOCATE_BUFFER)) + ExFreePool(irp->associated_irp.system_buffer); + else { + struct mdl *mdl; + while ((mdl = irp->mdl)) { + irp->mdl = mdl->next; + MmUnlockPages(mdl); + IoFreeMdl(mdl); + } + } + IOTRACE("freeing irp %p", irp); + IoFreeIrp(irp); + IOEXIT(return); +} + +wstdcall NTSTATUS IoPassIrpDown(struct device_object *dev_obj, struct irp *irp) +{ + IoSkipCurrentIrpStackLocation(irp); + IOEXIT(return IoCallDriver(dev_obj, irp)); +} + +wstdcall NTSTATUS IoIrpSyncComplete(struct device_object *dev_obj, + struct irp *irp, void *context) +{ + if (irp->pending_returned == TRUE) + KeSetEvent(context, IO_NO_INCREMENT, FALSE); + IOEXIT(return STATUS_MORE_PROCESSING_REQUIRED); +} +WIN_FUNC_DECL(IoIrpSyncComplete,3) + +wstdcall NTSTATUS IoSyncForwardIrp(struct device_object *dev_obj, + struct irp *irp) +{ + struct nt_event event; + NTSTATUS status; + + IoCopyCurrentIrpStackLocationToNext(irp); + KeInitializeEvent(&event, SynchronizationEvent, FALSE); + /* completion function is called as Windows function */ + IoSetCompletionRoutine(irp, WIN_FUNC_PTR(IoIrpSyncComplete,3), &event, + TRUE, TRUE, TRUE); + status = IoCallDriver(dev_obj, irp); + IOTRACE("%08X", status); + if (status == STATUS_PENDING) { + KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, + NULL); + status = irp->io_status.status; + } + IOTRACE("%08X", status); + IOEXIT(return status); +} +WIN_FUNC_DECL(IoSyncForwardIrp,2) + +wstdcall NTSTATUS IoAsyncForwardIrp(struct device_object *dev_obj, + struct irp *irp) +{ + NTSTATUS status; + + IoCopyCurrentIrpStackLocationToNext(irp); + status = IoCallDriver(dev_obj, irp); + IOEXIT(return status); +} +WIN_FUNC_DECL(IoAsyncForwardIrp,2) + +wstdcall NTSTATUS IoInvalidDeviceRequest(struct device_object *dev_obj, + struct irp *irp) +{ + struct io_stack_location *irp_sl; + NTSTATUS status; + + irp_sl = IoGetCurrentIrpStackLocation(irp); + WARNING("%d:%d not implemented", irp_sl->major_fn, irp_sl->minor_fn); + irp->io_status.status = STATUS_SUCCESS; + irp->io_status.info = 0; + status = irp->io_status.status; + IoCompleteRequest(irp, IO_NO_INCREMENT); + IOEXIT(return status); +} +WIN_FUNC_DECL(IoInvalidDeviceRequest,2) + +static irqreturn_t io_irq_isr(int irq, void *data ISR_PT_REGS_PARAM_DECL) +{ + struct kinterrupt *interrupt = data; + BOOLEAN ret; + +#ifdef CONFIG_DEBUG_SHIRQ + if (!interrupt->u.enabled) + EXIT1(return IRQ_NONE); +#endif + TRACE6("%p", interrupt); + nt_spin_lock(interrupt->actual_lock); + ret = LIN2WIN2(interrupt->isr, interrupt, interrupt->isr_ctx); + nt_spin_unlock(interrupt->actual_lock); + if (ret == TRUE) + EXIT6(return IRQ_HANDLED); + else + EXIT6(return IRQ_NONE); +} + +wstdcall NTSTATUS WIN_FUNC(IoConnectInterrupt,11) + (struct kinterrupt **kinterrupt, PKSERVICE_ROUTINE isr, void *isr_ctx, + NT_SPIN_LOCK *lock, ULONG vector, KIRQL irql, KIRQL synch_irql, + enum kinterrupt_mode mode, BOOLEAN shared, KAFFINITY cpu_mask, + BOOLEAN save_fp) +{ + struct kinterrupt *interrupt; + IOENTER(""); + interrupt = kzalloc(sizeof(*interrupt), GFP_KERNEL); + if (!interrupt) + IOEXIT(return STATUS_INSUFFICIENT_RESOURCES); + interrupt->vector = vector; + interrupt->cpu_mask = cpu_mask; + nt_spin_lock_init(&interrupt->lock); + if (lock) + interrupt->actual_lock = lock; + else + interrupt->actual_lock = &interrupt->lock; + interrupt->shared = shared; + interrupt->save_fp = save_fp; + interrupt->isr = isr; + interrupt->isr_ctx = isr_ctx; + InitializeListHead(&interrupt->list); + interrupt->irql = irql; + interrupt->synch_irql = synch_irql; + interrupt->mode = mode; + if (request_irq(vector, io_irq_isr, shared ? IRQF_SHARED : 0, + "ndiswrapper", interrupt)) { + WARNING("request for irq %d failed", vector); + kfree(interrupt); + IOEXIT(return STATUS_INSUFFICIENT_RESOURCES); + } + *kinterrupt = interrupt; +#ifdef CONFIG_DEBUG_SHIRQ + interrupt->u.enabled = 1; +#endif + IOEXIT(return STATUS_SUCCESS); +} + +wstdcall void WIN_FUNC(IoDisconnectInterrupt,1) + (struct kinterrupt *interrupt) +{ +#ifdef CONFIG_DEBUG_SHIRQ + interrupt->u.enabled = 0; +#endif + free_irq(interrupt->vector, interrupt); + kfree(interrupt); +} + +wstdcall struct mdl *WIN_FUNC(IoAllocateMdl,5) + (void *virt, ULONG length, BOOLEAN second_buf, BOOLEAN charge_quota, + struct irp *irp) +{ + struct mdl *mdl; + mdl = allocate_init_mdl(virt, length); + if (!mdl) + return NULL; + if (irp) { + if (second_buf == TRUE) { + struct mdl *last; + + last = irp->mdl; + while (last->next) + last = last->next; + last->next = mdl; + } else + irp->mdl = mdl; + } + IOTRACE("%p", mdl); + return mdl; +} + +wstdcall void WIN_FUNC(IoFreeMdl,1) + (struct mdl *mdl) +{ + IOTRACE("%p", mdl); + free_mdl(mdl); +} + +wstdcall struct io_workitem *WIN_FUNC(IoAllocateWorkItem,1) + (struct device_object *dev_obj) +{ + struct io_workitem *io_workitem; + + IOENTER("%p", dev_obj); + io_workitem = kmalloc(sizeof(*io_workitem), irql_gfp()); + if (!io_workitem) + IOEXIT(return NULL); + io_workitem->dev_obj = dev_obj; + IOEXIT(return io_workitem); +} + +wstdcall void WIN_FUNC(IoFreeWorkItem,1) + (struct io_workitem *io_workitem) +{ + kfree(io_workitem); + IOEXIT(return); +} + +wstdcall void WIN_FUNC(IoQueueWorkItem,4) + (struct io_workitem *io_workitem, void *func, + enum work_queue_type queue_type, void *context) +{ + IOENTER("%p, %p", io_workitem, io_workitem->dev_obj); + io_workitem->worker_routine = func; + io_workitem->context = context; + schedule_ntos_work_item(func, io_workitem->dev_obj, context); + IOEXIT(return); +} + +wstdcall void WIN_FUNC(ExQueueWorkItem,2) + (struct io_workitem *io_workitem, enum work_queue_type queue_type) +{ + IOENTER("%p", io_workitem); + schedule_ntos_work_item(io_workitem->worker_routine, + io_workitem->dev_obj, io_workitem->context); +} + +wstdcall NTSTATUS WIN_FUNC(IoAllocateDriverObjectExtension,4) + (struct driver_object *drv_obj, void *client_id, ULONG extlen, + void **ext) +{ + struct custom_ext *ce; + + IOENTER("%p, %p", drv_obj, client_id); + ce = kmalloc(sizeof(*ce) + extlen, irql_gfp()); + if (ce == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + IOTRACE("custom_ext: %p", ce); + ce->client_id = client_id; + spin_lock_bh(&ntoskernel_lock); + InsertTailList(&drv_obj->drv_ext->custom_ext, &ce->list); + spin_unlock_bh(&ntoskernel_lock); + + *ext = (void *)ce + sizeof(*ce); + IOTRACE("ext: %p", *ext); + IOEXIT(return STATUS_SUCCESS); +} + +wstdcall void *WIN_FUNC(IoGetDriverObjectExtension,2) + (struct driver_object *drv_obj, void *client_id) +{ + struct custom_ext *ce; + void *ret; + + IOENTER("drv_obj: %p, client_id: %p", drv_obj, client_id); + ret = NULL; + spin_lock_bh(&ntoskernel_lock); + nt_list_for_each_entry(ce, &drv_obj->drv_ext->custom_ext, list) { + if (ce->client_id == client_id) { + ret = (void *)ce + sizeof(*ce); + break; + } + } + spin_unlock_bh(&ntoskernel_lock); + IOTRACE("ret: %p", ret); + return ret; +} + +void free_custom_extensions(struct driver_extension *drv_ext) +{ + struct nt_list *ent; + + IOENTER("%p", drv_ext); + spin_lock_bh(&ntoskernel_lock); + while ((ent = RemoveHeadList(&drv_ext->custom_ext))) + kfree(ent); + spin_unlock_bh(&ntoskernel_lock); + IOEXIT(return); +} + +wstdcall NTSTATUS WIN_FUNC(IoCreateDevice,7) + (struct driver_object *drv_obj, ULONG dev_ext_length, + struct unicode_string *dev_name, DEVICE_TYPE dev_type, + ULONG dev_chars, BOOLEAN exclusive, struct device_object **newdev) +{ + struct device_object *dev; + struct dev_obj_ext *dev_obj_ext; + int size; + + IOENTER("%p, %u, %p", drv_obj, dev_ext_length, dev_name); + + size = sizeof(*dev) + dev_ext_length + sizeof(*dev_obj_ext); + dev = allocate_object(size, OBJECT_TYPE_DEVICE, dev_name); + if (!dev) + IOEXIT(return STATUS_INSUFFICIENT_RESOURCES); + if (dev_ext_length) + dev->dev_ext = dev + 1; + else + dev->dev_ext = NULL; + + dev_obj_ext = ((void *)(dev + 1)) + dev_ext_length; + dev_obj_ext->dev_obj = dev; + dev_obj_ext->size = 0; + dev_obj_ext->type = IO_TYPE_DEVICE; + dev->dev_obj_ext = dev_obj_ext; + + dev->type = dev_type; + dev->flags = 0; + dev->size = sizeof(*dev) + dev_ext_length; + dev->ref_count = 1; + dev->attached = NULL; + dev->stack_count = 1; + + dev->drv_obj = drv_obj; + dev->next = drv_obj->dev_obj; + drv_obj->dev_obj = dev; + + dev->align_req = 1; + dev->characteristics = dev_chars; + dev->io_timer = NULL; + KeInitializeEvent(&dev->lock, SynchronizationEvent, TRUE); + dev->vpb = NULL; + + IOTRACE("dev: %p, ext: %p", dev, dev->dev_ext); + *newdev = dev; + IOEXIT(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(IoCreateUnprotectedSymbolicLink,2) + (struct unicode_string *link, struct unicode_string *dev_name) +{ + struct ansi_string ansi; + + IOENTER("%p, %p", dev_name, link); + if (dev_name && (RtlUnicodeStringToAnsiString(&ansi, dev_name, TRUE) == + STATUS_SUCCESS)) { + IOTRACE("dev_name: %s", ansi.buf); + RtlFreeAnsiString(&ansi); + } + if (link && (RtlUnicodeStringToAnsiString(&ansi, link, TRUE) == + STATUS_SUCCESS)) { + IOTRACE("link: %s", ansi.buf); + RtlFreeAnsiString(&ansi); + } +// TODO(); + IOEXIT(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(IoCreateSymbolicLink,2) + (struct unicode_string *link, struct unicode_string *dev_name) +{ + IOEXIT(return IoCreateUnprotectedSymbolicLink(link, dev_name)); +} + +wstdcall NTSTATUS WIN_FUNC(IoDeleteSymbolicLink,1) + (struct unicode_string *link) +{ + struct ansi_string ansi; + + IOENTER("%p", link); + if (link && (RtlUnicodeStringToAnsiString(&ansi, link, TRUE) == + STATUS_SUCCESS)) { + IOTRACE("dev_name: %s", ansi.buf); + RtlFreeAnsiString(&ansi); + } + IOEXIT(return STATUS_SUCCESS); +} + +wstdcall void WIN_FUNC(IoDeleteDevice,1) + (struct device_object *dev) +{ + IOENTER("%p", dev); + if (dev == NULL) + IOEXIT(return); + IOTRACE("drv_obj: %p", dev->drv_obj); + if (dev->drv_obj) { + struct device_object *prev; + + prev = dev->drv_obj->dev_obj; + IOTRACE("dev_obj: %p", prev); + if (prev == dev) + dev->drv_obj->dev_obj = dev->next; + else if (prev) { + while (prev->next != dev) + prev = prev->next; + prev->next = dev->next; + } + } + ObDereferenceObject(dev); + IOEXIT(return); +} + +wstdcall void WIN_FUNC(IoDetachDevice,1) + (struct device_object *tgt) +{ + struct device_object *tail; + + IOENTER("%p", tgt); + if (!tgt) + IOEXIT(return); + tail = tgt->attached; + if (!tail) + IOEXIT(return); + IOTRACE("tail: %p", tail); + + spin_lock_bh(&ntoskernel_lock); + tgt->attached = tail->attached; + IOTRACE("attached:%p", tgt->attached); + for ( ; tail; tail = tail->attached) { + IOTRACE("tail:%p", tail); + tail->stack_count--; + } + spin_unlock_bh(&ntoskernel_lock); + IOEXIT(return); +} + +wstdcall struct device_object *WIN_FUNC(IoGetAttachedDevice,1) + (struct device_object *dev) +{ + IOENTER("%p", dev); + if (!dev) + IOEXIT(return NULL); + spin_lock_bh(&ntoskernel_lock); + while (dev->attached) + dev = dev->attached; + spin_unlock_bh(&ntoskernel_lock); + IOEXIT(return dev); +} + +wstdcall struct device_object *WIN_FUNC(IoGetAttachedDeviceReference,1) + (struct device_object *dev) +{ + IOENTER("%p", dev); + if (!dev) + IOEXIT(return NULL); + dev = IoGetAttachedDevice(dev); + ObReferenceObject(dev); + IOEXIT(return dev); +} + +wstdcall struct device_object *WIN_FUNC(IoAttachDeviceToDeviceStack,2) + (struct device_object *src, struct device_object *tgt) +{ + struct device_object *attached; + struct dev_obj_ext *src_dev_ext; + + IOENTER("%p, %p", src, tgt); + attached = IoGetAttachedDevice(tgt); + IOTRACE("%p", attached); + src_dev_ext = src->dev_obj_ext; + spin_lock_bh(&ntoskernel_lock); + if (attached) + attached->attached = src; + src->attached = NULL; + src->stack_count = attached->stack_count + 1; + src_dev_ext->attached_to = attached; + spin_unlock_bh(&ntoskernel_lock); + IOTRACE("stack_count: %d -> %d", attached->stack_count, + src->stack_count); + IOEXIT(return attached); +} + +wstdcall NTSTATUS WIN_FUNC(IoGetDeviceProperty,5) + (struct device_object *pdo, enum device_registry_property dev_property, + ULONG buffer_len, void *buffer, ULONG *result_len) +{ + struct ansi_string ansi; + struct unicode_string unicode; + struct wrap_device *wd; + ULONG need; + + IOENTER("dev_obj = %p, dev_property = %d, buffer_len = %u, " + "buffer = %p, result_len = %p", pdo, dev_property, + buffer_len, buffer, result_len); + + wd = pdo->reserved; + switch (dev_property) { + case DevicePropertyDeviceDescription: + case DevicePropertyFriendlyName: + case DevicePropertyDriverKeyName: + if (wrap_is_pci_bus(wd->dev_bus)) + RtlInitAnsiString(&ansi, "PCI"); + else // if (wrap_is_usb_bus(wd->dev_bus)) + RtlInitAnsiString(&ansi, "USB"); + need = sizeof(wchar_t) * (ansi.max_length + 1); + if (buffer_len < need) { + *result_len = need; + IOEXIT(return STATUS_BUFFER_TOO_SMALL); + } + unicode.max_length = buffer_len; + unicode.buf = buffer; + if (RtlAnsiStringToUnicodeString(&unicode, &ansi, + FALSE) != STATUS_SUCCESS) { + *result_len = unicode.length; + IOEXIT(return STATUS_BUFFER_TOO_SMALL); + } + IOEXIT(return STATUS_SUCCESS); + default: + WARNING("%d not implemented", dev_property); + IOEXIT(return STATUS_INVALID_PARAMETER_2); + } +} + +wstdcall NTSTATUS WIN_FUNC(IoGetDeviceObjectPointer,4) + (struct unicode_string *name, ACCESS_MASK desired_access, + void *file_obj, struct device_object *dev_obj) +{ + struct common_object_header *coh; + + dev_obj = NULL; + /* TODO: access is not checked and file_obj is set to NULL */ + file_obj = NULL; + spin_lock_bh(&ntoskernel_lock); + nt_list_for_each_entry(coh, &object_list, list) { + TRACE5("header: %p, type: %d", coh, coh->type); + if (coh->type != OBJECT_TYPE_DEVICE) + continue; + if (!RtlCompareUnicodeString(&coh->name, name, TRUE)) { + dev_obj = HEADER_TO_OBJECT(coh); + TRACE5("dev_obj: %p", dev_obj); + break; + } + } + spin_unlock_bh(&ntoskernel_lock); + if (dev_obj) + IOEXIT(return STATUS_SUCCESS); + else + IOEXIT(return STATUS_OBJECT_NAME_INVALID); +} + +/* NOTE: Make sure to compile with -freg-struct-return, so gcc will + * return union in register, like Windows */ +wstdcall union power_state WIN_FUNC(PoSetPowerState,3) + (struct device_object *dev_obj, enum power_state_type type, + union power_state state) +{ + IOEXIT(return state); +} + +wstdcall NTSTATUS WIN_FUNC(PoCallDriver,2) + (struct device_object *dev_obj, struct irp *irp) +{ + return IoCallDriver(dev_obj, irp); +} + +wstdcall NTSTATUS WIN_FUNC(PoRequestPowerIrp,6) + (struct device_object *dev_obj, UCHAR minor_fn, + union power_state power_state, void *completion_func, + void *context, struct irp **pirp) +{ + struct irp *irp; + struct io_stack_location *irp_sl; + + TRACE1("%p, %d, %p", dev_obj, dev_obj->stack_count, dev_obj->drv_obj); + irp = IoAllocateIrp(dev_obj->stack_count, FALSE); + if (!irp) + return STATUS_INSUFFICIENT_RESOURCES; + irp_sl = IoGetNextIrpStackLocation(irp); + irp_sl->major_fn = IRP_MJ_POWER; + irp_sl->minor_fn = minor_fn; + if (minor_fn == IRP_MN_WAIT_WAKE) + irp_sl->params.power.type = SystemPowerState; + else + irp_sl->params.power.type = DevicePowerState; + irp_sl->params.power.state = power_state; + irp_sl->completion_routine = completion_func; + irp->io_status.status = STATUS_NOT_SUPPORTED; + *pirp = irp; + return PoCallDriver(dev_obj, irp); +} + +wstdcall void WIN_FUNC(PoStartNextPowerIrp,1) + (struct irp *irp) +{ + IOENTER("irp = %p", irp); + IOEXIT(return); +} + +wstdcall void WIN_FUNC(IoInitializeRemoveLockEx,5) + (struct io_remove_lock *lock, ULONG alloc_tag, ULONG max_locked_min, + ULONG high_mark, ULONG lock_size) +{ + TODO(); +} + +wstdcall void *WIN_FUNC(IoAllocateErrorLogEntry,2) + (void *io_object, UCHAR entry_size) +{ + /* not implemented fully */ + void *ret = kmalloc(sizeof(struct io_error_log_packet) + entry_size, + irql_gfp()); + TRACE2("%p", ret); + if (ret) + return ret + sizeof(struct io_error_log_packet); + else + return NULL; +} + +wstdcall void WIN_FUNC(IoWriteErrorLogEntry,1) + (void *entry) +{ + /* TODO: log error with codes and message */ + ERROR(""); +} + +wstdcall void WIN_FUNC(IoFreeErrorLogEntry,1) + (void *entry) +{ + TRACE2("%p", entry); + kfree(entry - sizeof(struct io_error_log_packet)); +} + +wstdcall NTSTATUS WIN_FUNC(IoAcquireRemoveLockEx,5) + (struct io_remove_lock lock, void *tag, char *file, ULONG line, + ULONG lock_size) +{ + TODO(); + IOEXIT(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(IoReleaseRemoveLockEx,3) + (struct io_remove_lock lock, void *tag, ULONG lock_size) +{ + TODO(); + IOEXIT(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(IoRegisterDeviceInterface,4) + (struct device_object *pdo, struct guid *guid_class, + struct unicode_string *reference, struct unicode_string *link) +{ + struct ansi_string ansi; + + /* TODO: check if pdo is valid */ + RtlInitAnsiString(&ansi, "ndis"); + ENTER1("pdo: %p, ref: %p, link: %p, %x, %x, %x", pdo, reference, link, + guid_class->data1, guid_class->data2, guid_class->data3); + return RtlAnsiStringToUnicodeString(link, &ansi, TRUE); +} + +wstdcall NTSTATUS WIN_FUNC(IoSetDeviceInterfaceState,2) + (struct unicode_string *link, BOOLEAN enable) +{ + ENTER1("link: %p, enable: %d", link, enable); + return STATUS_SUCCESS; +} + +wstdcall NTSTATUS WIN_FUNC(IoOpenDeviceRegistryKey,4) + (struct device_object *dev_obj, ULONG type, ACCESS_MASK mask, + void **handle) +{ + ENTER1("dev_obj: %p", dev_obj); + *handle = dev_obj; + return STATUS_SUCCESS; +} + +wstdcall NTSTATUS WIN_FUNC(IoWMIRegistrationControl,2) + (struct device_object *dev_obj, ULONG action) +{ + ENTER2("%p, %d", dev_obj, action); + EXIT2(return STATUS_SUCCESS); +} + +wstdcall void WIN_FUNC(IoInvalidateDeviceRelations,2) + (struct device_object *dev_obj, enum device_relation_type type) +{ + INFO("%p, %d", dev_obj, type); + TODO(); +} + +wstdcall void WIN_FUNC(IoInvalidateDeviceState,1) + (struct device_object *pdo) +{ + INFO("%p", pdo); + TODO(); +} --- linux-2.6.28.orig/ubuntu/ndiswrapper/wrapmem.h +++ linux-2.6.28/ubuntu/ndiswrapper/wrapmem.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2006 Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#ifndef _WRAPMEM_H_ + +/* set ALLOC_DEBUG to 1 to get information about memory used by both + * ndiswrapper and Windows driver by reading + * /proc/net/ndiswrapper/debug; this will also show memory leaks + * (memory allocated but not freed) when ndiswrapper module is + * unloaded. + + * ALLOC_DEBUG=2: details about individual allocations leaking is printed + * ALLOC_DEBUG=3: tags in ExAllocatePoolWithTag leaking printed +*/ + +//#ifndef ALLOC_DEBUG +//#define ALLOC_DEBUG 1 +//#endif + +enum alloc_type { ALLOC_TYPE_KMALLOC_ATOMIC, ALLOC_TYPE_KMALLOC_NON_ATOMIC, + ALLOC_TYPE_VMALLOC_ATOMIC, ALLOC_TYPE_VMALLOC_NON_ATOMIC, + ALLOC_TYPE_SLACK, ALLOC_TYPE_PAGES, ALLOC_TYPE_MAX }; + +int wrapmem_init(void); +void wrapmem_exit(void); +void *slack_kmalloc(size_t size); +void slack_kfree(void *ptr); +void wrapmem_info(void); + +#ifdef ALLOC_DEBUG +void *wrap_kmalloc(size_t size, gfp_t flags, const char *file, int line); +void *wrap_kzalloc(size_t size, gfp_t flags, const char *file, int line); +void wrap_kfree(void *ptr); +void *wrap_vmalloc(unsigned long size, const char *file, int line); +void *wrap__vmalloc(unsigned long size, gfp_t flags, pgprot_t prot, + const char *file, int line); +void wrap_vfree(void *ptr); +void *wrap_alloc_pages(gfp_t flags, unsigned int size, + const char *file, int line); +void wrap_free_pages(unsigned long ptr, int order); +int alloc_size(enum alloc_type type); + +#ifndef _WRAPMEM_C_ +#undef kmalloc +#undef kzalloc +#undef kfree +#undef vmalloc +#undef __vmalloc +#undef vfree +#define kmalloc(size, flags) \ + wrap_kmalloc(size, flags, __FILE__, __LINE__) +#define kzalloc(size, flags) \ + wrap_kzalloc(size, flags, __FILE__, __LINE__) +#define vmalloc(size) \ + wrap_vmalloc(size, __FILE__, __LINE__) +#define __vmalloc(size, flags, prot) \ + wrap__vmalloc(size, flags, prot, __FILE__, __LINE__) +#define kfree(ptr) wrap_kfree(ptr) +#define vfree(ptr) wrap_vfree(ptr) + +#define wrap_get_free_pages(flags, size) \ + wrap_alloc_pages(flags, size, __FILE__, __LINE__) +#undef free_pages +#define free_pages(ptr, order) wrap_free_pages(ptr, order) + +#if ALLOC_DEBUG > 1 +void *wrap_ExAllocatePoolWithTag(enum pool_type pool_type, SIZE_T size, + ULONG tag, const char *file, int line); +#define ExAllocatePoolWithTag(pool_type, size, tag) \ + wrap_ExAllocatePoolWithTag(pool_type, size, tag, __FILE__, __LINE__) +#endif + +#endif // _WRAPMEM_C_ + +#else + +#define wrap_get_free_pages(flags, size) \ + (void *)__get_free_pages(flags, get_order(size)) + +#endif // ALLOC_DEBUG + +#endif --- linux-2.6.28.orig/ubuntu/ndiswrapper/proc.c +++ linux-2.6.28/ubuntu/ndiswrapper/proc.c @@ -0,0 +1,565 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ +#include +#include +#include + +#include "ndis.h" +#include "iw_ndis.h" +#include "wrapndis.h" +#include "pnp.h" +#include "wrapper.h" + +#define MAX_PROC_STR_LEN 32 + +static struct proc_dir_entry *wrap_procfs_entry; + +static int procfs_read_ndis_stats(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + char *p = page; + struct ndis_device *wnd = (struct ndis_device *)data; + struct ndis_wireless_stats stats; + NDIS_STATUS res; + ndis_rssi rssi; + + if (off != 0) { + *eof = 1; + return 0; + } + + res = mp_query(wnd, OID_802_11_RSSI, &rssi, sizeof(rssi)); + if (!res) + p += sprintf(p, "signal_level=%d dBm\n", (s32)rssi); + + res = mp_query(wnd, OID_802_11_STATISTICS, &stats, sizeof(stats)); + if (!res) { + + p += sprintf(p, "tx_frames=%Lu\n", stats.tx_frag); + p += sprintf(p, "tx_multicast_frames=%Lu\n", + stats.tx_multi_frag); + p += sprintf(p, "tx_failed=%Lu\n", stats.failed); + p += sprintf(p, "tx_retry=%Lu\n", stats.retry); + p += sprintf(p, "tx_multi_rerty=%Lu\n", stats.multi_retry); + p += sprintf(p, "tx_rtss_success=%Lu\n", stats.rtss_succ); + p += sprintf(p, "tx_rtss_fail=%Lu\n", stats.rtss_fail); + p += sprintf(p, "ack_fail=%Lu\n", stats.ack_fail); + p += sprintf(p, "frame_duplicates=%Lu\n", stats.frame_dup); + p += sprintf(p, "rx_frames=%Lu\n", stats.rx_frag); + p += sprintf(p, "rx_multicast_frames=%Lu\n", + stats.rx_multi_frag); + p += sprintf(p, "fcs_errors=%Lu\n", stats.fcs_err); + } + + if (p - page > count) { + ERROR("wrote %lu bytes (limit is %u)\n", + (unsigned long)(p - page), count); + *eof = 1; + } + + return (p - page); +} + +static int procfs_read_ndis_encr(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + char *p = page; + struct ndis_device *wnd = (struct ndis_device *)data; + int i, encr_status, auth_mode, infra_mode; + NDIS_STATUS res; + struct ndis_essid essid; + mac_address ap_address; + + if (off != 0) { + *eof = 1; + return 0; + } + + res = mp_query(wnd, OID_802_11_BSSID, + &ap_address, sizeof(ap_address)); + if (res) + memset(ap_address, 0, ETH_ALEN); + p += sprintf(p, "ap_address=%2.2X", ap_address[0]); + for (i = 1 ; i < ETH_ALEN ; i++) + p += sprintf(p, ":%2.2X", ap_address[i]); + p += sprintf(p, "\n"); + + res = mp_query(wnd, OID_802_11_SSID, &essid, sizeof(essid)); + if (!res) + p += sprintf(p, "essid=%.*s\n", essid.length, essid.essid); + + res = mp_query_int(wnd, OID_802_11_ENCRYPTION_STATUS, &encr_status); + if (!res) { + typeof(&wnd->encr_info.keys[0]) tx_key; + p += sprintf(p, "tx_key=%u\n", wnd->encr_info.tx_key_index); + p += sprintf(p, "key="); + tx_key = &wnd->encr_info.keys[wnd->encr_info.tx_key_index]; + if (tx_key->length > 0) + for (i = 0; i < tx_key->length; i++) + p += sprintf(p, "%2.2X", tx_key->key[i]); + else + p += sprintf(p, "off"); + p += sprintf(p, "\n"); + p += sprintf(p, "encr_mode=%d\n", encr_status); + } + res = mp_query_int(wnd, OID_802_11_AUTHENTICATION_MODE, &auth_mode); + if (!res) + p += sprintf(p, "auth_mode=%d\n", auth_mode); + res = mp_query_int(wnd, OID_802_11_INFRASTRUCTURE_MODE, &infra_mode); + p += sprintf(p, "mode=%s\n", (infra_mode == Ndis802_11IBSS) ? + "adhoc" : (infra_mode == Ndis802_11Infrastructure) ? + "managed" : "auto"); + if (p - page > count) { + WARNING("wrote %lu bytes (limit is %u)", + (unsigned long)(p - page), count); + *eof = 1; + } + + return (p - page); +} + +static int procfs_read_ndis_hw(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + char *p = page; + struct ndis_device *wnd = (struct ndis_device *)data; + struct ndis_configuration config; + unsigned int power_mode; + NDIS_STATUS res; + ndis_tx_power_level tx_power; + ULONG bit_rate; + ndis_rts_threshold rts_threshold; + ndis_fragmentation_threshold frag_threshold; + ndis_antenna antenna; + ULONG packet_filter; + int n; + mac_address mac; + char *hw_status[] = {"ready", "initializing", "resetting", "closing", + "not ready"}; + + if (off != 0) { + *eof = 1; + return 0; + } + + res = mp_query_int(wnd, OID_GEN_HARDWARE_STATUS, &n); + if (res == NDIS_STATUS_SUCCESS && + n >= 0 && n < sizeof(hw_status) / sizeof(hw_status[0])) + p += sprintf(p, "status=%s\n", hw_status[n]); + + res = mp_query(wnd, OID_802_3_CURRENT_ADDRESS, mac, sizeof(mac)); + if (!res) + p += sprintf(p, "mac: " MACSTRSEP "\n", MAC2STR(mac)); + res = mp_query(wnd, OID_802_11_CONFIGURATION, &config, sizeof(config)); + if (!res) { + p += sprintf(p, "beacon_period=%u msec\n", + config.beacon_period); + p += sprintf(p, "atim_window=%u msec\n", config.atim_window); + p += sprintf(p, "frequency=%u kHZ\n", config.ds_config); + p += sprintf(p, "hop_pattern=%u\n", + config.fh_config.hop_pattern); + p += sprintf(p, "hop_set=%u\n", + config.fh_config.hop_set); + p += sprintf(p, "dwell_time=%u msec\n", + config.fh_config.dwell_time); + } + + res = mp_query(wnd, OID_802_11_TX_POWER_LEVEL, + &tx_power, sizeof(tx_power)); + if (!res) + p += sprintf(p, "tx_power=%u mW\n", tx_power); + + res = mp_query(wnd, OID_GEN_LINK_SPEED, &bit_rate, sizeof(bit_rate)); + if (!res) + p += sprintf(p, "bit_rate=%u kBps\n", (u32)bit_rate / 10); + + res = mp_query(wnd, OID_802_11_RTS_THRESHOLD, + &rts_threshold, sizeof(rts_threshold)); + if (!res) + p += sprintf(p, "rts_threshold=%u bytes\n", rts_threshold); + + res = mp_query(wnd, OID_802_11_FRAGMENTATION_THRESHOLD, + &frag_threshold, sizeof(frag_threshold)); + if (!res) + p += sprintf(p, "frag_threshold=%u bytes\n", frag_threshold); + + res = mp_query_int(wnd, OID_802_11_POWER_MODE, &power_mode); + if (!res) + p += sprintf(p, "power_mode=%s\n", + (power_mode == NDIS_POWER_OFF) ? "always_on" : + (power_mode == NDIS_POWER_MAX) ? + "max_savings" : "min_savings"); + + res = mp_query(wnd, OID_802_11_NUMBER_OF_ANTENNAS, + &antenna, sizeof(antenna)); + if (!res) + p += sprintf(p, "num_antennas=%u\n", antenna); + + res = mp_query(wnd, OID_802_11_TX_ANTENNA_SELECTED, + &antenna, sizeof(antenna)); + if (!res) + p += sprintf(p, "tx_antenna=%u\n", antenna); + + res = mp_query(wnd, OID_802_11_RX_ANTENNA_SELECTED, + &antenna, sizeof(antenna)); + if (!res) + p += sprintf(p, "rx_antenna=%u\n", antenna); + + p += sprintf(p, "encryption_modes=%s%s%s%s%s%s%s\n", + test_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr) ? + "WEP" : "none", + + test_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr) ? + "; TKIP with WPA" : "", + test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) ? + ", WPA2" : "", + test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth) ? + ", WPA2PSK" : "", + + test_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr) ? + "; AES/CCMP with WPA" : "", + test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) ? + ", WPA2" : "", + test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth) ? + ", WPA2PSK" : ""); + + res = mp_query_int(wnd, OID_GEN_CURRENT_PACKET_FILTER, &packet_filter); + if (!res) { + if (packet_filter != wnd->packet_filter) + WARNING("wrong packet_filter? 0x%08x, 0x%08x\n", + packet_filter, wnd->packet_filter); + p += sprintf(p, "packet_filter: 0x%08x\n", packet_filter); + } + if (p - page > count) { + WARNING("wrote %lu bytes (limit is %u)", + (unsigned long)(p - page), count); + *eof = 1; + } + + return (p - page); +} + +static int procfs_read_ndis_settings(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + char *p = page; + struct ndis_device *wnd = (struct ndis_device *)data; + struct wrap_device_setting *setting; + + if (off != 0) { + *eof = 1; + return 0; + } + + p += sprintf(p, "hangcheck_interval=%d\n", + hangcheck_interval == 0 ? + (int)(wnd->hangcheck_interval / HZ) : -1); + + list_for_each_entry(setting, &wnd->wd->settings, list) { + p += sprintf(p, "%s=%s\n", setting->name, setting->value); + } + + list_for_each_entry(setting, &wnd->wd->driver->settings, list) { + p += sprintf(p, "%s=%s\n", setting->name, setting->value); + } + + return (p - page); +} + +static int procfs_write_ndis_settings(struct file *file, const char __user *buf, + unsigned long count, void *data) +{ + struct ndis_device *wnd = (struct ndis_device *)data; + char setting[MAX_PROC_STR_LEN], *p; + unsigned int i; + NDIS_STATUS res; + + if (count > MAX_PROC_STR_LEN) + return -EINVAL; + + memset(setting, 0, sizeof(setting)); + if (copy_from_user(setting, buf, count)) + return -EFAULT; + + if ((p = strchr(setting, '\n'))) + *p = 0; + + if ((p = strchr(setting, '='))) + *p = 0; + + if (!strcmp(setting, "hangcheck_interval")) { + if (!p) + return -EINVAL; + p++; + i = simple_strtol(p, NULL, 10); + hangcheck_del(wnd); + if (i > 0) { + wnd->hangcheck_interval = i * HZ; + hangcheck_add(wnd); + } + } else if (!strcmp(setting, "suspend")) { + if (!p) + return -EINVAL; + p++; + i = simple_strtol(p, NULL, 10); + if (i <= 0 || i > 3) + return -EINVAL; + if (wrap_is_pci_bus(wnd->wd->dev_bus)) + i = wrap_pnp_suspend_pci_device(wnd->wd->pci.pdev, + PMSG_SUSPEND); + else +#ifdef ENABLE_USB + i = wrap_pnp_suspend_usb_device(wnd->wd->usb.intf, + PMSG_SUSPEND); +#else + i = -1; +#endif + if (i) + return -EINVAL; + } else if (!strcmp(setting, "resume")) { + if (wrap_is_pci_bus(wnd->wd->dev_bus)) + i = wrap_pnp_resume_pci_device(wnd->wd->pci.pdev); + else +#ifdef ENABLE_USB + i = wrap_pnp_resume_usb_device(wnd->wd->usb.intf); +#else + i = -1; +#endif + if (i) + return -EINVAL; + } else if (!strcmp(setting, "stats_enabled")) { + if (!p) + return -EINVAL; + p++; + i = simple_strtol(p, NULL, 10); + if (i > 0) + wnd->iw_stats_enabled = TRUE; + else + wnd->iw_stats_enabled = FALSE; + } else if (!strcmp(setting, "packet_filter")) { + if (!p) + return -EINVAL; + p++; + i = simple_strtol(p, NULL, 10); + res = mp_set_int(wnd, OID_GEN_CURRENT_PACKET_FILTER, i); + if (res) + WARNING("setting packet_filter failed: %08X", res); + } else if (!strcmp(setting, "reinit")) { + if (ndis_reinit(wnd) != NDIS_STATUS_SUCCESS) + return -EFAULT; + } else { + struct ndis_configuration_parameter param; + struct unicode_string key; + struct ansi_string ansi; + + if (!p) + return -EINVAL; + p++; + RtlInitAnsiString(&ansi, p); + if (RtlAnsiStringToUnicodeString(¶m.data.string, &ansi, + TRUE) != STATUS_SUCCESS) + EXIT1(return -EFAULT); + param.type = NdisParameterString; + RtlInitAnsiString(&ansi, setting); + if (RtlAnsiStringToUnicodeString(&key, &ansi, + TRUE) != STATUS_SUCCESS) { + RtlFreeUnicodeString(¶m.data.string); + EXIT1(return -EINVAL); + } + NdisWriteConfiguration(&res, wnd->nmb, &key, ¶m); + RtlFreeUnicodeString(&key); + RtlFreeUnicodeString(¶m.data.string); + if (res != NDIS_STATUS_SUCCESS) + return -EFAULT; + } + return count; +} + +int wrap_procfs_add_ndis_device(struct ndis_device *wnd) +{ + struct proc_dir_entry *procfs_entry; + + if (wrap_procfs_entry == NULL) + return -ENOMEM; + + if (wnd->procfs_iface) { + ERROR("%s already registered?", wnd->netdev_name); + return -EINVAL; + } + wnd->procfs_iface = proc_mkdir(wnd->netdev_name, wrap_procfs_entry); + if (wnd->procfs_iface == NULL) { + ERROR("couldn't create proc directory"); + return -ENOMEM; + } + wnd->procfs_iface->uid = proc_uid; + wnd->procfs_iface->gid = proc_gid; + + procfs_entry = create_proc_entry("hw", S_IFREG | S_IRUSR | S_IRGRP, + wnd->procfs_iface); + if (procfs_entry == NULL) { + ERROR("couldn't create proc entry for 'hw'"); + goto err_hw; + } else { + procfs_entry->uid = proc_uid; + procfs_entry->gid = proc_gid; + procfs_entry->data = wnd; + procfs_entry->read_proc = procfs_read_ndis_hw; + } + + procfs_entry = create_proc_entry("stats", S_IFREG | S_IRUSR | S_IRGRP, + wnd->procfs_iface); + if (procfs_entry == NULL) { + ERROR("couldn't create proc entry for 'stats'"); + goto err_stats; + } else { + procfs_entry->uid = proc_uid; + procfs_entry->gid = proc_gid; + procfs_entry->data = wnd; + procfs_entry->read_proc = procfs_read_ndis_stats; + } + + procfs_entry = create_proc_entry("encr", S_IFREG | S_IRUSR | S_IRGRP, + wnd->procfs_iface); + if (procfs_entry == NULL) { + ERROR("couldn't create proc entry for 'encr'"); + goto err_encr; + } else { + procfs_entry->uid = proc_uid; + procfs_entry->gid = proc_gid; + procfs_entry->data = wnd; + procfs_entry->read_proc = procfs_read_ndis_encr; + } + + procfs_entry = create_proc_entry("settings", S_IFREG | + S_IRUSR | S_IRGRP | + S_IWUSR | S_IWGRP, wnd->procfs_iface); + if (procfs_entry == NULL) { + ERROR("couldn't create proc entry for 'settings'"); + goto err_settings; + } else { + procfs_entry->uid = proc_uid; + procfs_entry->gid = proc_gid; + procfs_entry->data = wnd; + procfs_entry->read_proc = procfs_read_ndis_settings; + procfs_entry->write_proc = procfs_write_ndis_settings; + } + return 0; + +err_settings: + remove_proc_entry("encr", wnd->procfs_iface); +err_encr: + remove_proc_entry("stats", wnd->procfs_iface); +err_stats: + remove_proc_entry("hw", wnd->procfs_iface); +err_hw: + remove_proc_entry(wnd->netdev_name, wrap_procfs_entry); + wnd->procfs_iface = NULL; + return -ENOMEM; +} + +void wrap_procfs_remove_ndis_device(struct ndis_device *wnd) +{ + struct proc_dir_entry *procfs_iface = xchg(&wnd->procfs_iface, NULL); + + if (procfs_iface == NULL) + return; + remove_proc_entry("hw", procfs_iface); + remove_proc_entry("stats", procfs_iface); + remove_proc_entry("encr", procfs_iface); + remove_proc_entry("settings", procfs_iface); + if (wrap_procfs_entry) + remove_proc_entry(wnd->netdev_name, wrap_procfs_entry); +} + +static int procfs_read_debug(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + char *p = page; + enum alloc_type type; + + if (off != 0) { + *eof = 1; + return 0; + } + p += sprintf(p, "%d\n", debug); + type = 0; +#ifdef ALLOC_DEBUG + for (type = 0; type < ALLOC_TYPE_MAX; type++) + p += sprintf(p, "total size of allocations in %d: %d\n", + type, alloc_size(type)); +#endif + return (p - page); +} + +static int procfs_write_debug(struct file *file, const char __user *buf, + unsigned long count, void *data) +{ + int i; + char setting[MAX_PROC_STR_LEN], *p; + + if (count > MAX_PROC_STR_LEN) + return -EINVAL; + + memset(setting, 0, sizeof(setting)); + if (copy_from_user(setting, buf, count)) + return -EFAULT; + + if ((p = strchr(setting, '\n'))) + *p = 0; + + if ((p = strchr(setting, '='))) + *p = 0; + + i = simple_strtol(setting, NULL, 10); + if (i >= 0 && i < 10) + debug = i; + else + return -EINVAL; + return count; +} + +int wrap_procfs_init(void) +{ + struct proc_dir_entry *procfs_entry; + + wrap_procfs_entry = proc_mkdir(DRIVER_NAME, proc_net_root); + if (wrap_procfs_entry == NULL) { + ERROR("couldn't create procfs directory"); + return -ENOMEM; + } + wrap_procfs_entry->uid = proc_uid; + wrap_procfs_entry->gid = proc_gid; + + procfs_entry = create_proc_entry("debug", S_IFREG | S_IRUSR | S_IRGRP, + wrap_procfs_entry); + if (procfs_entry == NULL) { + ERROR("couldn't create proc entry for 'debug'"); + return -ENOMEM; + } else { + procfs_entry->uid = proc_uid; + procfs_entry->gid = proc_gid; + procfs_entry->read_proc = procfs_read_debug; + procfs_entry->write_proc = procfs_write_debug; + } + return 0; +} + +void wrap_procfs_remove(void) +{ + if (wrap_procfs_entry == NULL) + return; + remove_proc_entry("debug", wrap_procfs_entry); + remove_proc_entry(DRIVER_NAME, proc_net_root); +} --- linux-2.6.28.orig/ubuntu/ndiswrapper/ntoskernel.h +++ linux-2.6.28/ubuntu/ndiswrapper/ntoskernel.h @@ -0,0 +1,1165 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#ifndef _NTOSKERNEL_H_ +#define _NTOSKERNEL_H_ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(CONFIG_X86) && !defined(CONFIG_X86_64) +#error "this module is for x86 or x86_64 architectures only" +#endif + +/* Interrupt backwards compatibility stuff */ +#include +#ifndef IRQ_HANDLED +#define IRQ_HANDLED +#define IRQ_NONE +#define irqreturn_t void +#endif + +/* pci functions in 2.6 kernels have problems allocating dma buffers, + * but seem to work fine with dma functions + */ +#include + +#define PCI_DMA_ALLOC_COHERENT(pci_dev,size,dma_handle) \ + dma_alloc_coherent(&pci_dev->dev,size,dma_handle, \ + GFP_KERNEL | __GFP_REPEAT) +#define PCI_DMA_FREE_COHERENT(pci_dev,size,cpu_addr,dma_handle) \ + dma_free_coherent(&pci_dev->dev,size,cpu_addr,dma_handle) +#define PCI_DMA_MAP_SINGLE(pci_dev,addr,size,direction) \ + dma_map_single(&pci_dev->dev,addr,size,direction) +#define PCI_DMA_UNMAP_SINGLE(pci_dev,dma_handle,size,direction) \ + dma_unmap_single(&pci_dev->dev,dma_handle,size,direction) +#define MAP_SG(pci_dev, sglist, nents, direction) \ + dma_map_sg(&pci_dev->dev, sglist, nents, direction) +#define UNMAP_SG(pci_dev, sglist, nents, direction) \ + dma_unmap_sg(&pci_dev->dev, sglist, nents, direction) +#define PCI_DMA_MAP_ERROR(dma_addr) dma_mapping_error(dma_addr) + + +#if defined(CONFIG_NET_RADIO) && !defined(CONFIG_WIRELESS_EXT) +#define CONFIG_WIRELESS_EXT +#endif + +#define prepare_wait_condition(task, var, value) \ +do { \ + var = value; \ + task = current; \ + barrier(); \ +} while (0) + +/* Wait in wait_state (e.g., TASK_INTERRUPTIBLE) for condition to + * become true; timeout is either jiffies (> 0) to wait or 0 to wait + * forever. + * When timeout == 0, return value is + * > 0 if condition becomes true, or + * < 0 if signal is pending on the thread. + * When timeout > 0, return value is + * > 0 if condition becomes true before timeout, + * < 0 if signal is pending on the thread before timeout, or + * 0 if timedout (condition may have become true at the same time) + */ + +#define wait_condition(condition, timeout, wait_state) \ +({ \ + long ret = timeout ? timeout : 1; \ + while (1) { \ + if (signal_pending(current)) { \ + ret = -ERESTARTSYS; \ + break; \ + } \ + set_current_state(wait_state); \ + if (condition) { \ + __set_current_state(TASK_RUNNING); \ + break; \ + } \ + if (timeout) { \ + ret = schedule_timeout(ret); \ + if (!ret) \ + break; \ + } else \ + schedule(); \ + } \ + ret; \ +}) + +#ifdef WRAP_WQ + +struct workqueue_struct; + +struct workqueue_thread { + spinlock_t lock; + struct task_struct *task; + struct completion *completion; + char name[16]; + int pid; + /* whether any work_structs pending? <0 implies quit */ + s8 pending; + /* list of work_structs pending */ + struct list_head work_list; +}; + +typedef struct workqueue_struct { + u8 singlethread; + u8 qon; + int num_cpus; + struct workqueue_thread threads[0]; +} workqueue_struct_t; + +typedef struct { + struct list_head list; + void (*func)(void *data); + void *data; + /* whether/on which thread scheduled */ + struct workqueue_thread *thread; +} work_struct_t; + +#define initialize_work(work, pfunc, pdata) \ + do { \ + (work)->func = (pfunc); \ + (work)->data = (pdata); \ + (work)->thread = NULL; \ + } while (0) + +#undef create_singlethread_workqueue +#define create_singlethread_workqueue(name) wrap_create_wq(name, 1, 0) +#undef create_workqueue +#define create_workqueue(name) wrap_create_wq(name, 0, 0) +#undef destroy_workqueue +#define destroy_workqueue wrap_destroy_wq +#undef queue_work +#define queue_work wrap_queue_work +#undef flush_workqueue +#define flush_workqueue wrap_flush_wq + +workqueue_struct_t *wrap_create_wq(const char *name, u8 singlethread, u8 freeze); +void wrap_destroy_wq_on(workqueue_struct_t *workq, int cpu); +void wrap_destroy_wq(workqueue_struct_t *workq); +int wrap_queue_work_on(workqueue_struct_t *workq, work_struct_t *work, + int cpu); +int wrap_queue_work(workqueue_struct_t *workq, work_struct_t *work); +void wrap_cancel_work(work_struct_t *work); +void wrap_flush_wq_on(workqueue_struct_t *workq, int cpu); +void wrap_flush_wq(workqueue_struct_t *workq); +typedef void *worker_param_t; +#define worker_param_data(param, type, member) param + +#else // WRAP_WQ + +typedef struct workqueue_struct workqueue_struct_t; +typedef struct work_struct work_struct_t; + +#if defined(INIT_WORK_NAR) || defined(INIT_DELAYED_WORK_DEFERRABLE) +#define initialize_work(work, func, data) INIT_WORK(work, func) +typedef struct work_struct *worker_param_t; +#define worker_param_data(param, type, member) \ + container_of(param, type, member) +#else +#define initialize_work(work, func, data) INIT_WORK(work, func, data) +typedef void *worker_param_t; +#define worker_param_data(param, type, member) param +#endif // INIT_WORK_NAR + +#endif // WRAP_WQ + +struct nt_thread *wrap_worker_init(workqueue_struct_t *wq); + +#ifdef module_param +#define WRAP_MODULE_PARM_INT(name, perm) module_param(name, int, perm) +#define WRAP_MODULE_PARM_STRING(name, perm) module_param(name, charp, perm) +#else +#define WRAP_MODULE_PARM_INT(name, perm) MODULE_PARM(name, "i") +#define WRAP_MODULE_PARM_STRING(name, perm) MODULE_PARM(name, "s") +#endif + +#ifndef LOCK_PREFIX +#ifdef LOCK +#define LOCK_PREFIX LOCK +#else +#ifdef CONFIG_SMP +#define LOCK_PREFIX "lock ; " +#else +#define LOCK_PREFIX "" +#endif +#endif +#endif + +#ifndef NETDEV_TX_OK +#define NETDEV_TX_OK 0 +#endif + +#ifndef NETDEV_TX_BUSY +#define NETDEV_TX_BUSY 1 +#endif + +#ifndef CHECKSUM_HW +#define CHECKSUM_HW CHECKSUM_PARTIAL +#endif + +#ifndef offset_in_page +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK) +#endif + +#ifndef PMSG_SUSPEND +#ifdef PM_SUSPEND +/* this is not correct - the value of PM_SUSPEND is different from + * PMSG_SUSPEND, but ndiswrapper doesn't care about the value when + * suspending */ +#define PMSG_SUSPEND PM_SUSPEND +#define PSMG_ON PM_ON +#else +typedef u32 pm_message_t; +#define PMSG_SUSPEND 2 +#define PMSG_ON 0 +#endif +#endif + +#ifndef PCI_D0 +#define PCI_D0 0 +#endif + +#ifndef PCI_D3hot +#define PCI_D3hot 3 +#endif + +#ifndef PCI_D3cold +#define PCI_D3cold 3 +#endif + +#ifndef PM_EVENT_SUSPEND +#define PM_EVENT_SUSPEND 2 +#endif + +#if !defined(HAVE_NETDEV_PRIV) +#define netdev_priv(dev) ((dev)->priv) +#endif + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) +#define ISR_PT_REGS_PARAM_DECL +#define ISR_PT_REGS_ARG +#else +#define ISR_PT_REGS_PARAM_DECL , struct pt_regs *regs +#define ISR_PT_REGS_ARG , NULL +#endif + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16) +#define for_each_possible_cpu(_cpu) for_each_cpu(_cpu) +#endif + +#ifndef flush_icache_range +#define flush_icache_range(start, end) do { } while (0) +#endif + +#ifndef CHECKSUM_PARTIAL +#define CHECKSUM_PARTIAL CHECKSUM_HW +#endif + +#ifndef IRQF_SHARED +#define IRQF_SHARED SA_SHIRQ +#endif + +#define memcpy_skb(skb, from, length) \ + memcpy(skb_put(skb, length), from, length) + +#ifndef DMA_24BIT_MASK +#define DMA_24BIT_MASK 0x0000000000ffffffULL +#endif + +#ifndef DMA_30BIT_MASK +#define DMA_30BIT_MASK 0x000000003fffffffULL +#endif + +#ifndef DMA_31BIT_MASK +#define DMA_31BIT_MASK 0x000000007fffffffULL +#endif + +#ifndef DMA_32BIT_MASK +#define DMA_32BIT_MASK 0x00000000ffffffffULL +#endif + +#ifndef __GFP_DMA32 +#define __GFP_DMA32 GFP_DMA +#endif + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22) +#define wrap_kmem_cache_create(name, size, align, flags) \ + kmem_cache_create(name, size, align, flags, NULL, NULL) +#else +#define wrap_kmem_cache_create(name, size, align, flags) \ + kmem_cache_create(name, size, align, flags, NULL) +#endif + +#include "winnt_types.h" +#include "ndiswrapper.h" +#include "pe_linker.h" +#include "wrapmem.h" +#include "lin2win.h" +#include "loader.h" + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) +static inline void netif_tx_lock(struct net_device *dev) +{ + spin_lock(&dev->xmit_lock); +} +static inline void netif_tx_unlock(struct net_device *dev) +{ + spin_unlock(&dev->xmit_lock); +} +static inline void netif_tx_lock_bh(struct net_device *dev) +{ + spin_lock_bh(&dev->xmit_lock); +} +static inline void netif_tx_unlock_bh(struct net_device *dev) +{ + spin_unlock_bh(&dev->xmit_lock); +} +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) +static inline void netif_poll_enable(struct net_device *dev) +{ +} +static inline void netif_poll_disable(struct net_device *dev) +{ +} +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) +#define proc_net_root init_net.proc_net +#else +#define proc_net_root proc_net +#endif + +/* TICK is 100ns */ +#define TICKSPERSEC 10000000 +#define TICKSPERMSEC 10000 +#define SECSPERDAY 86400 +#define TICKSPERJIFFY ((TICKSPERSEC + HZ - 1) / HZ) + +#define int_div_round(x, y) (((x) + (y - 1)) / (y)) + +/* 1601 to 1970 is 369 years plus 89 leap days */ +#define SECS_1601_TO_1970 ((369 * 365 + 89) * (u64)SECSPERDAY) +#define TICKS_1601_TO_1970 (SECS_1601_TO_1970 * TICKSPERSEC) + +/* 100ns units to HZ; if sys_time is negative, relative to current + * clock, otherwise from year 1601 */ +#define SYSTEM_TIME_TO_HZ(sys_time) \ + (((sys_time) <= 0) ? \ + int_div_round(((u64)HZ * (-(sys_time))), TICKSPERSEC) : \ + int_div_round(((s64)HZ * ((sys_time) - ticks_1601())), TICKSPERSEC)) + +#define MSEC_TO_HZ(ms) int_div_round((ms * HZ), 1000) +#define USEC_TO_HZ(us) int_div_round((us * HZ), 1000000) + +extern u64 wrap_ticks_to_boot; + +static inline u64 ticks_1601(void) +{ + return wrap_ticks_to_boot + (u64)jiffies * TICKSPERJIFFY; +} + +typedef void (*generic_func)(void); + +struct wrap_export { + const char *name; + generic_func func; +}; + +#ifdef CONFIG_X86_64 + +#define WIN_SYMBOL(name, argc) \ + {#name, (generic_func) win2lin_ ## name ## _ ## argc} +#define WIN_WIN_SYMBOL(name, argc) \ + {#name, (generic_func) win2lin__win_ ## name ## _ ## argc} +#define WIN_FUNC_DECL(name, argc) \ + extern typeof(name) win2lin_ ## name ## _ ## argc; +#define WIN_FUNC_PTR(name, argc) win2lin_ ## name ## _ ## argc + +#else + +#define WIN_SYMBOL(name, argc) {#name, (generic_func)name} +#define WIN_WIN_SYMBOL(name, argc) {#name, (generic_func)_win_ ## name} +#define WIN_FUNC_DECL(name, argc) +#define WIN_FUNC_PTR(name, argc) name + +#endif + +#define WIN_FUNC(name, argc) name +/* map name s to f - if f is different from s */ +#define WIN_SYMBOL_MAP(s, f) + +#define POOL_TAG(A, B, C, D) \ + ((ULONG)((A) + ((B) << 8) + ((C) << 16) + ((D) << 24))) + +struct pe_image { + char name[MAX_DRIVER_NAME_LEN]; + UINT (*entry)(struct driver_object *, struct unicode_string *) wstdcall; + void *image; + int size; + int type; + + IMAGE_NT_HEADERS *nt_hdr; + IMAGE_OPTIONAL_HEADER *opt_hdr; +}; + +struct ndis_mp_block; + +struct wrap_timer { + struct nt_slist slist; + struct timer_list timer; + struct nt_timer *nt_timer; + long repeat; +#ifdef TIMER_DEBUG + unsigned long wrap_timer_magic; +#endif +}; + +struct ntos_work_item { + struct nt_list list; + void *arg1; + void *arg2; + NTOS_WORK_FUNC func; +}; + +struct wrap_device_setting { + struct nt_list list; + char name[MAX_SETTING_NAME_LEN]; + char value[MAX_SETTING_VALUE_LEN]; + void *encoded; +}; + +struct wrap_bin_file { + char name[MAX_DRIVER_NAME_LEN]; + size_t size; + void *data; +}; + +#define WRAP_DRIVER_CLIENT_ID 1 + +struct wrap_driver { + struct nt_list list; + struct driver_object *drv_obj; + char name[MAX_DRIVER_NAME_LEN]; + char version[MAX_SETTING_VALUE_LEN]; + unsigned short num_pe_images; + struct pe_image pe_images[MAX_DRIVER_PE_IMAGES]; + unsigned short num_bin_files; + struct wrap_bin_file *bin_files; + struct nt_list wrap_devices; + struct nt_list settings; + int dev_type; + struct ndis_driver *ndis_driver; +}; + +enum hw_status { + HW_INITIALIZED = 1, HW_SUSPENDED, HW_HALTED, HW_PRESENT, +}; + +struct wrap_device { + /* first part is (de)initialized once by loader */ + struct nt_list list; + int dev_bus; + int vendor; + int device; + int subvendor; + int subdevice; + char conf_file_name[MAX_DRIVER_NAME_LEN]; + char driver_name[MAX_DRIVER_NAME_LEN]; + struct wrap_driver *driver; + struct nt_list settings; + + /* rest should be (de)initialized when a device is + * (un)plugged */ + struct cm_resource_list *resource_list; + unsigned long hw_status; + struct device_object *pdo; + union { + struct { + struct pci_dev *pdev; + enum device_power_state wake_state; + } pci; + struct { + struct usb_device *udev; + struct usb_interface *intf; + int num_alloc_urbs; + struct nt_list wrap_urb_list; + } usb; + }; + union { + struct ndis_device *wnd; + }; +}; + +#define wrap_is_pci_bus(dev_bus) \ + (WRAP_BUS(dev_bus) == WRAP_PCI_BUS || \ + WRAP_BUS(dev_bus) == WRAP_PCMCIA_BUS) +#ifdef ENABLE_USB +/* earlier versions of ndiswrapper used 0 as USB_BUS */ +#define wrap_is_usb_bus(dev_bus) \ + (WRAP_BUS(dev_bus) == WRAP_USB_BUS || \ + WRAP_BUS(dev_bus) == WRAP_INTERNAL_BUS) +#else +#define wrap_is_usb_bus(dev_bus) 0 +#endif +#define wrap_is_bluetooth_device(dev_bus) \ + (WRAP_DEVICE(dev_bus) == WRAP_BLUETOOTH_DEVICE1 || \ + WRAP_DEVICE(dev_bus) == WRAP_BLUETOOTH_DEVICE2) + +extern workqueue_struct_t *ntos_wq; +#define schedule_ntos_work(work_struct) queue_work(ntos_wq, work_struct) +#define schedule_work(work_struct) queue_work(ntos_wq, work_struct) + +extern workqueue_struct_t *ndis_wq; +#define schedule_ndis_work(work_struct) queue_work(ndis_wq, work_struct) + +extern workqueue_struct_t *wrapndis_wq; +#define schedule_wrapndis_work(work_struct) queue_work(wrapndis_wq, work_struct) + +#define atomic_unary_op(var, size, oper) \ +do { \ + if (size == 1) \ + __asm__ __volatile__( \ + LOCK_PREFIX oper "b %b0\n\t" : "+m" (var)); \ + else if (size == 2) \ + __asm__ __volatile__( \ + LOCK_PREFIX oper "w %w0\n\t" : "+m" (var)); \ + else if (size == 4) \ + __asm__ __volatile__( \ + LOCK_PREFIX oper "l %0\n\t" : "+m" (var)); \ + else if (size == 8) \ + __asm__ __volatile__( \ + LOCK_PREFIX oper "q %q0\n\t" : "+m" (var)); \ + else { \ + extern void _invalid_op_size_(void); \ + _invalid_op_size_(); \ + } \ +} while (0) + +#define atomic_inc_var_size(var, size) atomic_unary_op(var, size, "inc") + +#define atomic_inc_var(var) atomic_inc_var_size(var, sizeof(var)) + +#define atomic_dec_var_size(var, size) atomic_unary_op(var, size, "dec") + +#define atomic_dec_var(var) atomic_dec_var_size(var, sizeof(var)) + +#define pre_atomic_add(var, i) \ +({ \ + typeof(var) pre; \ + __asm__ __volatile__( \ + LOCK_PREFIX "xadd %0, %1\n\t" \ + : "=r"(pre), "+m"(var) \ + : "0"(i)); \ + pre; \ +}) + +#define post_atomic_add(var, i) (pre_atomic_add(var, i) + i) + +#ifndef in_atomic +#define in_atomic() in_interrupt() +#endif + +#ifndef preempt_enable_no_resched +#define preempt_enable_no_resched() preempt_enable() +#endif + +//#define DEBUG_IRQL 1 + +#ifdef DEBUG_IRQL +#define assert_irql(cond) \ +do { \ + KIRQL _irql_ = current_irql(); \ + if (!(cond)) { \ + WARNING("assertion '%s' failed: %d", #cond, _irql_); \ + DBG_BLOCK(4) { \ + dump_stack(); \ + } \ + } \ +} while (0) +#else +#define assert_irql(cond) do { } while (0) +#endif + +/* When preempt is enabled, we should preempt_disable to raise IRQL to + * DISPATCH_LEVEL, to be consistent with the semantics. However, using + * a mutex instead, so that only ndiswrapper threads run one at a time + * on a processor when at DISPATCH_LEVEL seems to be enough. So that + * is what we will use until we learn otherwise. If + * preempt_(en|dis)able is required for some reason, comment out + * following #define. */ + +#define WRAP_PREEMPT 1 + +#if !defined(CONFIG_PREEMPT) || defined(CONFIG_PREEMPT_RT) +#ifndef WRAP_PREEMPT +#define WRAP_PREEMPT 1 +#endif +#endif + +//#undef WRAP_PREEMPT + +#ifdef WRAP_PREEMPT + +typedef struct { + int count; + struct mutex lock; +#ifdef CONFIG_SMP + typeof(current->cpus_allowed) cpus_allowed; +#endif + struct task_struct *task; +} irql_info_t; + +DECLARE_PER_CPU(irql_info_t, irql_info); + +static inline KIRQL raise_irql(KIRQL newirql) +{ + irql_info_t *info; + + assert(newirql == DISPATCH_LEVEL); + info = &get_cpu_var(irql_info); + if (info->task == current) { + assert(info->count > 0); + assert(mutex_is_locked(&info->lock)); +#if defined(CONFIG_SMP) && defined(DEBUG) + do { + cpumask_t cpumask; + cpumask = cpumask_of_cpu(smp_processor_id()); + cpus_xor(cpumask, cpumask, current->cpus_allowed); + assert(cpus_empty(cpumask)); + } while (0); +#endif + info->count++; + put_cpu_var(irql_info); + return DISPATCH_LEVEL; + } + /* TODO: is this enough to pin down to current cpu? */ +#ifdef CONFIG_SMP + assert(task_cpu(current) == smp_processor_id()); + info->cpus_allowed = current->cpus_allowed; + current->cpus_allowed = cpumask_of_cpu(smp_processor_id()); +#endif + put_cpu_var(irql_info); + mutex_lock(&info->lock); + assert(info->count == 0); + assert(info->task == NULL); + info->count = 1; + info->task = current; + return PASSIVE_LEVEL; +} + +static inline void lower_irql(KIRQL oldirql) +{ + irql_info_t *info; + + assert(oldirql <= DISPATCH_LEVEL); + info = &get_cpu_var(irql_info); + assert(info->task == current); + assert(mutex_is_locked(&info->lock)); + assert(info->count > 0); + if (--info->count == 0) { + info->task = NULL; +#ifdef CONFIG_SMP + current->cpus_allowed = info->cpus_allowed; +#endif + mutex_unlock(&info->lock); + } + put_cpu_var(irql_info); +} + +static inline KIRQL current_irql(void) +{ + int count; + if (in_irq() || irqs_disabled()) + EXIT4(return DIRQL); + if (in_atomic() || in_interrupt()) + EXIT4(return SOFT_IRQL); + count = get_cpu_var(irql_info).count; + put_cpu_var(irql_info); + if (count) + EXIT6(return DISPATCH_LEVEL); + else + EXIT6(return PASSIVE_LEVEL); +} + +#else + +static inline KIRQL current_irql(void) +{ + if (in_irq() || irqs_disabled()) + EXIT4(return DIRQL); + if (in_interrupt()) + EXIT4(return SOFT_IRQL); + if (in_atomic()) + EXIT6(return DISPATCH_LEVEL); + else + EXIT6(return PASSIVE_LEVEL); +} + +static inline KIRQL raise_irql(KIRQL newirql) +{ + KIRQL ret = in_atomic() ? DISPATCH_LEVEL : PASSIVE_LEVEL; + assert(newirql == DISPATCH_LEVEL); + assert(current_irql() <= DISPATCH_LEVEL); + preempt_disable(); + return ret; +} + +static inline void lower_irql(KIRQL oldirql) +{ + assert(current_irql() == DISPATCH_LEVEL); + preempt_enable(); +} + +#endif + +#define irql_gfp() (in_atomic() ? GFP_ATOMIC : GFP_KERNEL) + +/* Windows spinlocks are of type ULONG_PTR which is not big enough to + * store Linux spinlocks; so we implement Windows spinlocks using + * ULONG_PTR space with our own functions/macros */ + +/* Windows seems to use 0 for unlocked state of spinlock - if Linux + * convention of 1 for unlocked state is used, at least prism54 driver + * crashes */ + +#define NT_SPIN_LOCK_UNLOCKED 0 +#define NT_SPIN_LOCK_LOCKED 1 + +static inline void nt_spin_lock_init(NT_SPIN_LOCK *lock) +{ + *lock = NT_SPIN_LOCK_UNLOCKED; +} + +#ifdef CONFIG_SMP + +static inline void nt_spin_lock(NT_SPIN_LOCK *lock) +{ + __asm__ __volatile__( + "1:\t" + " xchgl %1, %0\n\t" + " testl %1, %1\n\t" + " jz 3f\n" + "2:\t" + " rep; nop\n\t" + " cmpl %2, %0\n\t" + " je 1b\n\t" + " jmp 2b\n" + "3:\n\t" + : "+m" (*lock) + : "r" (NT_SPIN_LOCK_LOCKED), "i" (NT_SPIN_LOCK_UNLOCKED)); +} + +static inline void nt_spin_unlock(NT_SPIN_LOCK *lock) +{ + *lock = NT_SPIN_LOCK_UNLOCKED; +} + +#else // CONFIG_SMP + +#define nt_spin_lock(lock) do { } while (0) + +#define nt_spin_unlock(lock) do { } while (0) + +#endif // CONFIG_SMP + +/* When kernel would've disabled preempt (e.g., in interrupt + * handlers), we need to fake preempt so driver thinks it is running + * at right IRQL */ + +/* raise IRQL to given (higher) IRQL if necessary before locking */ +static inline KIRQL nt_spin_lock_irql(NT_SPIN_LOCK *lock, KIRQL newirql) +{ + KIRQL oldirql = raise_irql(newirql); + nt_spin_lock(lock); + return oldirql; +} + +/* lower IRQL to given (lower) IRQL if necessary after unlocking */ +static inline void nt_spin_unlock_irql(NT_SPIN_LOCK *lock, KIRQL oldirql) +{ + nt_spin_unlock(lock); + lower_irql(oldirql); +} + +#define nt_spin_lock_irqsave(lock, flags) \ +do { \ + local_irq_save(flags); \ + preempt_disable(); \ + nt_spin_lock(lock); \ +} while (0) + +#define nt_spin_unlock_irqrestore(lock, flags) \ +do { \ + nt_spin_unlock(lock); \ + preempt_enable_no_resched(); \ + local_irq_restore(flags); \ + preempt_check_resched(); \ +} while (0) + +static inline ULONG SPAN_PAGES(void *ptr, SIZE_T length) +{ + return PAGE_ALIGN(((unsigned long)ptr & (PAGE_SIZE - 1)) + length) + >> PAGE_SHIFT; +} + +#ifdef CONFIG_X86_64 + +/* TODO: can these be implemented without using spinlock? */ + +static inline struct nt_slist *PushEntrySList(nt_slist_header *head, + struct nt_slist *entry, + NT_SPIN_LOCK *lock) +{ + KIRQL irql = nt_spin_lock_irql(lock, DISPATCH_LEVEL); + entry->next = head->next; + head->next = entry; + head->depth++; + nt_spin_unlock_irql(lock, irql); + TRACE4("%p, %p, %p", head, entry, entry->next); + return entry->next; +} + +static inline struct nt_slist *PopEntrySList(nt_slist_header *head, + NT_SPIN_LOCK *lock) +{ + struct nt_slist *entry; + KIRQL irql = nt_spin_lock_irql(lock, DISPATCH_LEVEL); + entry = head->next; + if (entry) { + head->next = entry->next; + head->depth--; + } + nt_spin_unlock_irql(lock, irql); + TRACE4("%p, %p", head, entry); + return entry; +} + +#else + +#define u64_low_32(x) ((u32)x) +#define u64_high_32(x) ((u32)(x >> 32)) + +static inline u64 cmpxchg8b(volatile u64 *ptr, u64 old, u64 new) +{ + u64 prev; + + __asm__ __volatile__( + "\n" + LOCK_PREFIX "cmpxchg8b %0\n" + : "+m" (*ptr), "=A" (prev) + : "A" (old), "b" (u64_low_32(new)), "c" (u64_high_32(new))); + return prev; +} + +/* slist routines below update slist atomically - no need for + * spinlocks */ + +static inline struct nt_slist *PushEntrySList(nt_slist_header *head, + struct nt_slist *entry, + NT_SPIN_LOCK *lock) +{ + nt_slist_header old, new; + do { + old.align = head->align; + entry->next = old.next; + new.next = entry; + new.depth = old.depth + 1; + } while (cmpxchg8b(&head->align, old.align, new.align) != old.align); + TRACE4("%p, %p, %p", head, entry, old.next); + return old.next; +} + +static inline struct nt_slist *PopEntrySList(nt_slist_header *head, + NT_SPIN_LOCK *lock) +{ + struct nt_slist *entry; + nt_slist_header old, new; + do { + old.align = head->align; + entry = old.next; + if (!entry) + break; + new.next = entry->next; + new.depth = old.depth - 1; + } while (cmpxchg8b(&head->align, old.align, new.align) != old.align); + TRACE4("%p, %p", head, entry); + return entry; +} + +#endif + +#define sleep_hz(n) \ +do { \ + set_current_state(TASK_INTERRUPTIBLE); \ + schedule_timeout(n); \ +} while (0) + +int ntoskernel_init(void); +void ntoskernel_exit(void); +int ntoskernel_init_device(struct wrap_device *wd); +void ntoskernel_exit_device(struct wrap_device *wd); +void *allocate_object(ULONG size, enum common_object_type type, + struct unicode_string *name); +void free_object(void *object); + +int usb_init(void); +void usb_exit(void); +int usb_init_device(struct wrap_device *wd); +void usb_exit_device(struct wrap_device *wd); +void usb_cancel_pending_urbs(void); + +int crt_init(void); +void crt_exit(void); +int rtl_init(void); +void rtl_exit(void); +int wrap_procfs_init(void); +void wrap_procfs_remove(void); + +int link_pe_images(struct pe_image *pe_image, unsigned short n); + +int stricmp(const char *s1, const char *s2); +void dump_bytes(const char *name, const u8 *from, int len); +struct mdl *allocate_init_mdl(void *virt, ULONG length); +void free_mdl(struct mdl *mdl); +struct driver_object *find_bus_driver(const char *name); +void free_custom_extensions(struct driver_extension *drv_obj_ext); +struct nt_thread *get_current_nt_thread(void); +u64 ticks_1601(void); +int schedule_ntos_work_item(NTOS_WORK_FUNC func, void *arg1, void *arg2); +void wrap_init_timer(struct nt_timer *nt_timer, enum timer_type type, + struct ndis_mp_block *nmb); +BOOLEAN wrap_set_timer(struct nt_timer *nt_timer, unsigned long expires_hz, + unsigned long repeat_hz, struct kdpc *kdpc); + +LONG InterlockedDecrement(LONG volatile *val) wfastcall; +LONG InterlockedIncrement(LONG volatile *val) wfastcall; +struct nt_list *ExInterlockedInsertHeadList + (struct nt_list *head, struct nt_list *entry, + NT_SPIN_LOCK *lock) wfastcall; +struct nt_list *ExInterlockedInsertTailList + (struct nt_list *head, struct nt_list *entry, + NT_SPIN_LOCK *lock) wfastcall; +struct nt_list *ExInterlockedRemoveHeadList + (struct nt_list *head, NT_SPIN_LOCK *lock) wfastcall; +NTSTATUS IofCallDriver(struct device_object *dev_obj, struct irp *irp) wfastcall; +KIRQL KfRaiseIrql(KIRQL newirql) wfastcall; +void KfLowerIrql(KIRQL oldirql) wfastcall; +KIRQL KfAcquireSpinLock(NT_SPIN_LOCK *lock) wfastcall; +void KfReleaseSpinLock(NT_SPIN_LOCK *lock, KIRQL oldirql) wfastcall; +void IofCompleteRequest(struct irp *irp, CHAR prio_boost) wfastcall; +void KefReleaseSpinLockFromDpcLevel(NT_SPIN_LOCK *lock) wfastcall; + +LONG ObfReferenceObject(void *object) wfastcall; +void ObfDereferenceObject(void *object) wfastcall; + +#define ObReferenceObject(object) ObfReferenceObject(object) +#define ObDereferenceObject(object) ObfDereferenceObject(object) + +void WRITE_PORT_UCHAR(ULONG_PTR port, UCHAR value) wstdcall; +UCHAR READ_PORT_UCHAR(ULONG_PTR port) wstdcall; + +#undef ExAllocatePoolWithTag +void *ExAllocatePoolWithTag(enum pool_type pool_type, SIZE_T size, + ULONG tag) wstdcall; +#if defined(ALLOC_DEBUG) && ALLOC_DEBUG > 1 +#define ExAllocatePoolWithTag(pool_type, size, tag) \ + wrap_ExAllocatePoolWithTag(pool_type, size, tag, __FILE__, __LINE__) +#endif + +void ExFreePool(void *p) wstdcall; +ULONG MmSizeOfMdl(void *base, ULONG length) wstdcall; +void __iomem *MmMapIoSpace(PHYSICAL_ADDRESS phys_addr, SIZE_T size, + enum memory_caching_type cache) wstdcall; +void MmUnmapIoSpace(void __iomem *addr, SIZE_T size) wstdcall; +void MmProbeAndLockPages(struct mdl *mdl, KPROCESSOR_MODE access_mode, + enum lock_operation operation) wstdcall; +void MmUnlockPages(struct mdl *mdl) wstdcall; +void KeInitializeEvent(struct nt_event *nt_event, + enum event_type type, BOOLEAN state) wstdcall; +LONG KeSetEvent(struct nt_event *nt_event, KPRIORITY incr, + BOOLEAN wait) wstdcall; +LONG KeResetEvent(struct nt_event *nt_event) wstdcall; +void KeClearEvent(struct nt_event *nt_event) wstdcall; +void KeInitializeDpc(struct kdpc *kdpc, void *func, void *ctx) wstdcall; +BOOLEAN queue_kdpc(struct kdpc *kdpc); +BOOLEAN dequeue_kdpc(struct kdpc *kdpc); + +void KeFlushQueuedDpcs(void) wstdcall; +NTSTATUS IoConnectInterrupt(struct kinterrupt **kinterrupt, + PKSERVICE_ROUTINE service_routine, + void *service_context, NT_SPIN_LOCK *lock, + ULONG vector, KIRQL irql, KIRQL synch_irql, + enum kinterrupt_mode interrupt_mode, + BOOLEAN shareable, KAFFINITY processor_enable_mask, + BOOLEAN floating_save) wstdcall; +void IoDisconnectInterrupt(struct kinterrupt *interrupt) wstdcall; +BOOLEAN KeSynchronizeExecution(struct kinterrupt *interrupt, + PKSYNCHRONIZE_ROUTINE synch_routine, + void *ctx) wstdcall; + +NTSTATUS KeWaitForSingleObject(void *object, KWAIT_REASON reason, + KPROCESSOR_MODE waitmode, BOOLEAN alertable, + LARGE_INTEGER *timeout) wstdcall; +struct mdl *IoAllocateMdl(void *virt, ULONG length, BOOLEAN second_buf, + BOOLEAN charge_quota, struct irp *irp) wstdcall; +void MmBuildMdlForNonPagedPool(struct mdl *mdl) wstdcall; +void IoFreeMdl(struct mdl *mdl) wstdcall; +NTSTATUS IoCreateDevice(struct driver_object *driver, ULONG dev_ext_length, + struct unicode_string *dev_name, DEVICE_TYPE dev_type, + ULONG dev_chars, BOOLEAN exclusive, + struct device_object **dev_obj) wstdcall; +NTSTATUS IoCreateSymbolicLink(struct unicode_string *link, + struct unicode_string *dev_name) wstdcall; +void IoDeleteDevice(struct device_object *dev) wstdcall; +void IoDetachDevice(struct device_object *topdev) wstdcall; +struct device_object *IoGetAttachedDevice(struct device_object *dev) wstdcall; +struct device_object *IoGetAttachedDeviceReference + (struct device_object *dev) wstdcall; +NTSTATUS IoAllocateDriverObjectExtension + (struct driver_object *drv_obj, void *client_id, ULONG extlen, + void **ext) wstdcall; +void *IoGetDriverObjectExtension(struct driver_object *drv, + void *client_id) wstdcall; +struct device_object *IoAttachDeviceToDeviceStack + (struct device_object *src, struct device_object *dst) wstdcall; +void KeInitializeEvent(struct nt_event *nt_event, enum event_type type, + BOOLEAN state) wstdcall; +struct irp *IoAllocateIrp(char stack_count, BOOLEAN charge_quota) wstdcall; +void IoFreeIrp(struct irp *irp) wstdcall; +BOOLEAN IoCancelIrp(struct irp *irp) wstdcall; +struct irp *IoBuildSynchronousFsdRequest + (ULONG major_func, struct device_object *dev_obj, void *buf, + ULONG length, LARGE_INTEGER *offset, struct nt_event *event, + struct io_status_block *status) wstdcall; +struct irp *IoBuildAsynchronousFsdRequest + (ULONG major_func, struct device_object *dev_obj, void *buf, + ULONG length, LARGE_INTEGER *offset, + struct io_status_block *status) wstdcall; +NTSTATUS PoCallDriver(struct device_object *dev_obj, struct irp *irp) wstdcall; + +NTSTATUS IoPassIrpDown(struct device_object *dev_obj, struct irp *irp) wstdcall; +WIN_FUNC_DECL(IoPassIrpDown,2); +NTSTATUS IoSyncForwardIrp(struct device_object *dev_obj, + struct irp *irp) wstdcall; +NTSTATUS IoAsyncForwardIrp(struct device_object *dev_obj, + struct irp *irp) wstdcall; +NTSTATUS IoInvalidDeviceRequest(struct device_object *dev_obj, + struct irp *irp) wstdcall; + +KIRQL KeGetCurrentIrql(void) wstdcall; +void KeInitializeSpinLock(NT_SPIN_LOCK *lock) wstdcall; +void KeAcquireSpinLock(NT_SPIN_LOCK *lock, KIRQL *irql) wstdcall; +void KeReleaseSpinLock(NT_SPIN_LOCK *lock, KIRQL oldirql) wstdcall; +KIRQL KeAcquireSpinLockRaiseToDpc(NT_SPIN_LOCK *lock) wstdcall; + +void IoAcquireCancelSpinLock(KIRQL *irql) wstdcall; +void IoReleaseCancelSpinLock(KIRQL irql) wstdcall; + +void RtlCopyMemory(void *dst, const void *src, SIZE_T length) wstdcall; +NTSTATUS RtlUnicodeStringToAnsiString + (struct ansi_string *dst, const struct unicode_string *src, + BOOLEAN dup) wstdcall; +NTSTATUS RtlAnsiStringToUnicodeString + (struct unicode_string *dst, const struct ansi_string *src, + BOOLEAN dup) wstdcall; +void RtlInitAnsiString(struct ansi_string *dst, const char *src) wstdcall; +void RtlInitString(struct ansi_string *dst, const char *src) wstdcall; +void RtlInitUnicodeString(struct unicode_string *dest, + const wchar_t *src) wstdcall; +void RtlFreeUnicodeString(struct unicode_string *string) wstdcall; +void RtlFreeAnsiString(struct ansi_string *string) wstdcall; +LONG RtlCompareUnicodeString(const struct unicode_string *s1, + const struct unicode_string *s2, + BOOLEAN case_insensitive) wstdcall; +void RtlCopyUnicodeString(struct unicode_string *dst, + struct unicode_string *src) wstdcall; +NTSTATUS RtlUpcaseUnicodeString(struct unicode_string *dst, + struct unicode_string *src, + BOOLEAN alloc) wstdcall; +void KeInitializeTimer(struct nt_timer *nt_timer) wstdcall; +void KeInitializeTimerEx(struct nt_timer *nt_timer, + enum timer_type type) wstdcall; +BOOLEAN KeSetTimerEx(struct nt_timer *nt_timer, LARGE_INTEGER duetime_ticks, + LONG period_ms, struct kdpc *kdpc) wstdcall; +BOOLEAN KeSetTimer(struct nt_timer *nt_timer, LARGE_INTEGER duetime_ticks, + struct kdpc *kdpc) wstdcall; +BOOLEAN KeCancelTimer(struct nt_timer *nt_timer) wstdcall; +void KeInitializeDpc(struct kdpc *kdpc, void *func, void *ctx) wstdcall; +struct nt_thread *KeGetCurrentThread(void) wstdcall; +NTSTATUS ObReferenceObjectByHandle(void *handle, ACCESS_MASK desired_access, + void *obj_type, KPROCESSOR_MODE access_mode, + void **object, void *handle_info) wstdcall; + +void adjust_user_shared_data_addr(char *driver, unsigned long length); + +extern spinlock_t ntoskernel_lock; +extern spinlock_t irp_cancel_lock; +extern struct nt_list object_list; +#ifdef CONFIG_X86_64 +extern struct kuser_shared_data kuser_shared_data; +#endif + +#define IoCompleteRequest(irp, prio) IofCompleteRequest(irp, prio) +#define IoCallDriver(dev, irp) IofCallDriver(dev, irp) + +#if defined(IO_DEBUG) +#define DUMP_IRP(_irp) \ +do { \ + struct io_stack_location *_irp_sl; \ + _irp_sl = IoGetCurrentIrpStackLocation(_irp); \ + IOTRACE("irp: %p, stack size: %d, cl: %d, sl: %p, dev_obj: %p, " \ + "mj_fn: %d, minor_fn: %d, nt_urb: %p, event: %p", \ + _irp, _irp->stack_count, (_irp)->current_location, \ + _irp_sl, _irp_sl->dev_obj, _irp_sl->major_fn, \ + _irp_sl->minor_fn, IRP_URB(_irp), \ + (_irp)->user_event); \ +} while (0) +#else +#define DUMP_IRP(_irp) do { } while (0) +#endif + +#endif // _NTOSKERNEL_H_ --- linux-2.6.28.orig/ubuntu/ndiswrapper/wrapper.c +++ linux-2.6.28/ubuntu/ndiswrapper/wrapper.c @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#include "ndis.h" +#include "iw_ndis.h" +#include "loader.h" +#include "pnp.h" +#include "wrapper.h" + +char *if_name = "wlan%d"; +int proc_uid, proc_gid; +int hangcheck_interval; +static char *utils_version = UTILS_VERSION; + +#if defined(DEBUG) && (DEBUG > 0) +int debug = DEBUG; +#else +int debug = 0; +#endif + +WRAP_MODULE_PARM_STRING(if_name, 0400); +MODULE_PARM_DESC(if_name, "Network interface name or template " + "(default: wlan%d)"); +WRAP_MODULE_PARM_INT(proc_uid, 0600); +MODULE_PARM_DESC(proc_uid, "The uid of the files created in /proc " + "(default: 0)."); +WRAP_MODULE_PARM_INT(proc_gid, 0600); +MODULE_PARM_DESC(proc_gid, "The gid of the files created in /proc " + "(default: 0)."); +WRAP_MODULE_PARM_INT(debug, 0600); +MODULE_PARM_DESC(debug, "debug level"); + +/* 0 - default value provided by NDIS driver, + * positive value - force hangcheck interval to that many seconds + * negative value - disable hangcheck + */ +WRAP_MODULE_PARM_INT(hangcheck_interval, 0600); +MODULE_PARM_DESC(hangcheck_interval, "The interval, in seconds, for checking" + " if driver is hung. (default: 0)"); + +WRAP_MODULE_PARM_STRING(utils_version, 0400); +MODULE_PARM_DESC(utils_version, "Compatible version of utils " + "(read only: " UTILS_VERSION ")"); + +MODULE_AUTHOR("ndiswrapper team "); +#ifdef MODULE_DESCRIPTION +MODULE_DESCRIPTION("NDIS wrapper driver"); +#endif +#ifdef MODULE_VERSION +MODULE_VERSION(DRIVER_VERSION); +#endif +MODULE_LICENSE("GPL"); + +static void module_cleanup(void) +{ + loader_exit(); +#ifdef ENABLE_USB + usb_exit(); +#endif + + wrap_procfs_remove(); + wrapndis_exit(); + ndis_exit(); + rtl_exit(); + crt_exit(); + ntoskernel_exit(); + wrapmem_exit(); +} + +static int __init wrapper_init(void) +{ + printk(KERN_INFO "%s version %s loaded (smp=%s, preempt=%s)\n", + DRIVER_NAME, DRIVER_VERSION, +#ifdef CONFIG_SMP + "yes" +#else + "no" +#endif + , +#ifdef CONFIG_PREEMPT_RT + "rt" +#elif defined(CONFIG_PREEMPT) + "yes" +#else + "no" +#endif + ); + + if (wrapmem_init() || ntoskernel_init() || crt_init() || + rtl_init() || ndis_init() || wrapndis_init() || +#ifdef ENABLE_USB + usb_init() || +#endif + wrap_procfs_init() || loader_init()) { + module_cleanup(); + ERROR("%s: initialization failed", DRIVER_NAME); + return -EINVAL; + } + EXIT1(return 0); +} + +static void __exit wrapper_exit(void) +{ + ENTER1(""); + module_cleanup(); +} + +module_init(wrapper_init); +module_exit(wrapper_exit); --- linux-2.6.28.orig/ubuntu/ndiswrapper/usb.c +++ linux-2.6.28/ubuntu/ndiswrapper/usb.c @@ -0,0 +1,1457 @@ +/* + * Copyright (C) 2004 Jan Kiszka + * Copyright (C) 2005 Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#include "ndis.h" +#include "usb.h" +#include "usb_exports.h" + +#ifdef USB_DEBUG +static unsigned int urb_id = 0; + +#define DUMP_WRAP_URB(wrap_urb, dir) \ + USBTRACE("urb %p (%d) %s: buf: %p, len: %d, pipe: 0x%x, %d", \ + (wrap_urb)->urb, (wrap_urb)->id, \ + (dir == USB_DIR_OUT) ? "going down" : "coming back", \ + (wrap_urb)->urb->transfer_buffer, \ + (wrap_urb)->urb->transfer_buffer_length, \ + (wrap_urb)->urb->pipe, (wrap_urb)->urb->status) + +#define DUMP_URB_BUFFER(urb, dir) \ + while (debug >= 2) { \ + int i; \ + char msg[20], *t; \ + if (!urb->transfer_buffer) \ + break; \ + if (!((usb_pipein(urb->pipe) && dir == USB_DIR_IN) || \ + (usb_pipeout(urb->pipe) && dir == USB_DIR_OUT))) \ + break; \ + t = msg; \ + t += sprintf(t, "%d: ", (urb)->actual_length); \ + for (i = 0; i < urb->actual_length && \ + t < &msg[sizeof(msg) - 4]; i++) \ + t += sprintf(t, "%02X ", \ + ((char *)urb->transfer_buffer)[i]); \ + *t = 0; \ + USBTRACE("%s", msg); \ + break; \ + } + +#else + +#define DUMP_WRAP_URB(wrap_urb, dir) (void)0 +#define DUMP_URB_BUFFER(urb, dir) (void)0 + +#endif + +#define CUR_ALT_SETTING(intf) (intf)->cur_altsetting + +#ifndef USB_CTRL_SET_TIMEOUT +#define USB_CTRL_SET_TIMEOUT 5000 +#endif + +#ifndef USB_CTRL_GET_TIMEOUT +#define USB_CTRL_GET_TIMEOUT 5000 +#endif + +#ifndef URB_NO_TRANSFER_DMA_MAP +#define URB_NO_TRANSFER_DMA_MAP 0 +#endif + +/* wrap_urb->flags */ +/* transfer_buffer for urb is allocated; free it in wrap_free_urb */ +#define WRAP_URB_COPY_BUFFER 0x01 + +static int inline wrap_cancel_urb(struct wrap_urb *wrap_urb) +{ + int ret; + USBTRACE("%p, %p, %d", wrap_urb, wrap_urb->urb, wrap_urb->state); + if (wrap_urb->state != URB_SUBMITTED) + USBEXIT(return -1); + ret = usb_unlink_urb(wrap_urb->urb); + USBTRACE("ret: %d", ret); + if (ret == -EINPROGRESS) + return 0; + else { + WARNING("unlink failed: %d", ret); + return ret; + } +} + +#define URB_STATUS(wrap_urb) (wrap_urb->urb->status) + +static struct nt_list wrap_urb_complete_list; +static spinlock_t wrap_urb_complete_list_lock; + +static work_struct_t wrap_urb_complete_work; +static void wrap_urb_complete_worker(worker_param_t dummy); + +static void kill_all_urbs(struct wrap_device *wd, int complete) +{ + struct nt_list *ent; + struct wrap_urb *wrap_urb; + KIRQL irql; + + USBTRACE("%d", wd->usb.num_alloc_urbs); + while (1) { + IoAcquireCancelSpinLock(&irql); + ent = RemoveHeadList(&wd->usb.wrap_urb_list); + IoReleaseCancelSpinLock(irql); + if (!ent) + break; + wrap_urb = container_of(ent, struct wrap_urb, list); + if (wrap_urb->state == URB_SUBMITTED) { + WARNING("Windows driver %s didn't free urb: %p", + wd->driver->name, wrap_urb->urb); + if (!complete) + wrap_urb->urb->complete = NULL; + usb_kill_urb(wrap_urb->urb); + } + USBTRACE("%p, %p", wrap_urb, wrap_urb->urb); + usb_free_urb(wrap_urb->urb); + kfree(wrap_urb); + } + wd->usb.num_alloc_urbs = 0; +} + +/* for a given Linux urb status code, return corresponding NT urb status */ +static USBD_STATUS wrap_urb_status(int urb_status) +{ + switch (urb_status) { + case 0: + return USBD_STATUS_SUCCESS; + case -EPROTO: + return USBD_STATUS_TIMEOUT; + case -EILSEQ: + return USBD_STATUS_CRC; + case -EPIPE: + return USBD_STATUS_INVALID_PIPE_HANDLE; + case -ECOMM: + return USBD_STATUS_DATA_OVERRUN; + case -ENOSR: + return USBD_STATUS_DATA_UNDERRUN; + case -EOVERFLOW: + return USBD_STATUS_BABBLE_DETECTED; + case -EREMOTEIO: + return USBD_STATUS_ERROR_SHORT_TRANSFER;; + case -ENODEV: + case -ESHUTDOWN: + case -ENOENT: + return USBD_STATUS_DEVICE_GONE; + case -ENOMEM: + return USBD_STATUS_NO_MEMORY; + case -EINVAL: + return USBD_STATUS_REQUEST_FAILED; + default: + return USBD_STATUS_NOT_SUPPORTED; + } +} + +/* for a given USBD_STATUS, return its corresponding NTSTATUS (for irp) */ +static NTSTATUS nt_urb_irp_status(USBD_STATUS nt_urb_status) +{ + switch (nt_urb_status) { + case USBD_STATUS_SUCCESS: + return STATUS_SUCCESS; + case USBD_STATUS_DEVICE_GONE: + return STATUS_DEVICE_REMOVED; + case USBD_STATUS_PENDING: + return STATUS_PENDING; + case USBD_STATUS_NOT_SUPPORTED: + return STATUS_NOT_IMPLEMENTED; + case USBD_STATUS_NO_MEMORY: + return STATUS_NO_MEMORY; + case USBD_STATUS_REQUEST_FAILED: + return STATUS_NOT_SUPPORTED; + default: + return STATUS_FAILURE; + } +} + +static void wrap_free_urb(struct urb *urb) +{ + struct irp *irp; + struct wrap_urb *wrap_urb; + + USBTRACE("freeing urb: %p", urb); + wrap_urb = urb->context; + irp = wrap_urb->irp; + if (wrap_urb->flags & WRAP_URB_COPY_BUFFER) { + USBTRACE("freeing DMA buffer for URB: %p %p", + urb, urb->transfer_buffer); + usb_buffer_free(IRP_WRAP_DEVICE(irp)->usb.udev, + urb->transfer_buffer_length, + urb->transfer_buffer, urb->transfer_dma); + } + if (urb->setup_packet) + kfree(urb->setup_packet); + if (IRP_WRAP_DEVICE(irp)->usb.num_alloc_urbs > MAX_ALLOCATED_URBS) { + IoAcquireCancelSpinLock(&irp->cancel_irql); + RemoveEntryList(&wrap_urb->list); + IRP_WRAP_DEVICE(irp)->usb.num_alloc_urbs--; + IoReleaseCancelSpinLock(irp->cancel_irql); + usb_free_urb(urb); + kfree(wrap_urb); + } else { + wrap_urb->state = URB_FREE; + wrap_urb->flags = 0; + wrap_urb->irp = NULL; + } + return; +} + +void wrap_suspend_urbs(struct wrap_device *wd) +{ + /* TODO: do we need to cancel urbs? */ + USBTRACE("%p, %d", wd, wd->usb.num_alloc_urbs); +} + +void wrap_resume_urbs(struct wrap_device *wd) +{ + /* TODO: do we need to resubmit urbs? */ + USBTRACE("%p, %d", wd, wd->usb.num_alloc_urbs); +} + +wstdcall void wrap_cancel_irp(struct device_object *dev_obj, struct irp *irp) +{ + struct urb *urb; + + /* NB: this function is called holding Cancel spinlock */ + USBENTER("irp: %p", irp); + urb = IRP_WRAP_URB(irp)->urb; + USBTRACE("canceling urb %p", urb); + if (wrap_cancel_urb(IRP_WRAP_URB(irp))) { + irp->cancel = FALSE; + ERROR("urb %p can't be canceld: %d", urb, + IRP_WRAP_URB(irp)->state); + } else + USBTRACE("urb %p canceled", urb); + IoReleaseCancelSpinLock(irp->cancel_irql); + return; +} +WIN_FUNC_DECL(wrap_cancel_irp,2) + +static struct urb *wrap_alloc_urb(struct irp *irp, unsigned int pipe, + void *buf, unsigned int buf_len) +{ + struct urb *urb; + gfp_t alloc_flags; + struct wrap_urb *wrap_urb; + struct wrap_device *wd; + + USBENTER("irp: %p", irp); + wd = IRP_WRAP_DEVICE(irp); + alloc_flags = irql_gfp(); + IoAcquireCancelSpinLock(&irp->cancel_irql); + urb = NULL; + nt_list_for_each_entry(wrap_urb, &wd->usb.wrap_urb_list, list) { + if (cmpxchg(&wrap_urb->state, URB_FREE, + URB_ALLOCATED) == URB_FREE) { + urb = wrap_urb->urb; + usb_init_urb(urb); + break; + } + } + if (!urb) { + IoReleaseCancelSpinLock(irp->cancel_irql); + wrap_urb = kzalloc(sizeof(*wrap_urb), alloc_flags); + if (!wrap_urb) { + WARNING("couldn't allocate memory"); + return NULL; + } + urb = usb_alloc_urb(0, alloc_flags); + if (!urb) { + WARNING("couldn't allocate urb"); + kfree(wrap_urb); + return NULL; + } + IoAcquireCancelSpinLock(&irp->cancel_irql); + wrap_urb->urb = urb; + wrap_urb->state = URB_ALLOCATED; + InsertTailList(&wd->usb.wrap_urb_list, &wrap_urb->list); + wd->usb.num_alloc_urbs++; + } + +#ifdef URB_ASYNC_UNLINK + urb->transfer_flags |= URB_ASYNC_UNLINK; +#elif defined(USB_ASYNC_UNLINK) + urb->transfer_flags |= USB_ASYNC_UNLINK; +#endif + urb->context = wrap_urb; + wrap_urb->irp = irp; + IRP_WRAP_URB(irp) = wrap_urb; + /* called as Windows function */ + irp->cancel_routine = WIN_FUNC_PTR(wrap_cancel_irp,2); + IoReleaseCancelSpinLock(irp->cancel_irql); + USBTRACE("urb: %p", urb); + + urb->transfer_buffer_length = buf_len; + if (buf_len && buf && (!virt_addr_valid(buf) +#if defined(CONFIG_HIGHMEM) || defined(CONFIG_HIGHMEM4G) + || PageHighMem(virt_to_page(buf)) +#endif + )) { + urb->transfer_buffer = + usb_buffer_alloc(wd->usb.udev, buf_len, alloc_flags, + &urb->transfer_dma); + if (!urb->transfer_buffer) { + WARNING("couldn't allocate dma buf"); + IoAcquireCancelSpinLock(&irp->cancel_irql); + wrap_urb->state = URB_FREE; + wrap_urb->irp = NULL; + IRP_WRAP_URB(irp) = NULL; + IoReleaseCancelSpinLock(irp->cancel_irql); + return NULL; + } + if (urb->transfer_dma) + urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + wrap_urb->flags |= WRAP_URB_COPY_BUFFER; + if (usb_pipeout(pipe)) + memcpy(urb->transfer_buffer, buf, buf_len); + USBTRACE("DMA buf for urb %p: %p", urb, urb->transfer_buffer); + } else + urb->transfer_buffer = buf; + return urb; +} + +static USBD_STATUS wrap_submit_urb(struct irp *irp) +{ + int ret; + struct urb *urb; + union nt_urb *nt_urb; + + urb = IRP_WRAP_URB(irp)->urb; + nt_urb = IRP_URB(irp); +#ifdef USB_DEBUG + if (IRP_WRAP_URB(irp)->state != URB_ALLOCATED) { + ERROR("urb %p is in wrong state: %d", + urb, IRP_WRAP_URB(irp)->state); + NT_URB_STATUS(nt_urb) = USBD_STATUS_REQUEST_FAILED; + return NT_URB_STATUS(nt_urb); + } + IRP_WRAP_URB(irp)->id = pre_atomic_add(urb_id, 1); +#endif + DUMP_WRAP_URB(IRP_WRAP_URB(irp), USB_DIR_OUT); + irp->io_status.status = STATUS_PENDING; + irp->io_status.info = 0; + NT_URB_STATUS(nt_urb) = USBD_STATUS_PENDING; + IoMarkIrpPending(irp); + DUMP_URB_BUFFER(urb, USB_DIR_OUT); + USBTRACE("%p", urb); + IRP_WRAP_URB(irp)->state = URB_SUBMITTED; + ret = usb_submit_urb(urb, irql_gfp()); + if (ret) { + USBTRACE("ret: %d", ret); + wrap_free_urb(urb); + /* we assume that IRP was not in pending state before */ + IoUnmarkIrpPending(irp); + NT_URB_STATUS(nt_urb) = wrap_urb_status(ret); + USBEXIT(return NT_URB_STATUS(nt_urb)); + } else + USBEXIT(return USBD_STATUS_PENDING); +} + +static void wrap_urb_complete(struct urb *urb ISR_PT_REGS_PARAM_DECL) +{ + struct irp *irp; + struct wrap_urb *wrap_urb; + + wrap_urb = urb->context; + USBTRACE("%p (%p) completed", wrap_urb, urb); + irp = wrap_urb->irp; + DUMP_WRAP_URB(wrap_urb, USB_DIR_IN); + irp->cancel_routine = NULL; +#ifdef USB_DEBUG + if (wrap_urb->state != URB_SUBMITTED) { + WARNING("urb %p in wrong state: %d (%d)", urb, wrap_urb->state, + urb->status); + return; + } +#endif + wrap_urb->state = URB_COMPLETED; + spin_lock(&wrap_urb_complete_list_lock); + InsertTailList(&wrap_urb_complete_list, &wrap_urb->complete_list); + spin_unlock(&wrap_urb_complete_list_lock); + schedule_ntos_work(&wrap_urb_complete_work); +} + +/* one worker for all devices */ +static void wrap_urb_complete_worker(worker_param_t dummy) +{ + struct irp *irp; + struct urb *urb; + struct usbd_bulk_or_intr_transfer *bulk_int_tx; + struct usbd_vendor_or_class_request *vc_req; + union nt_urb *nt_urb; + struct wrap_urb *wrap_urb; + struct nt_list *ent; + unsigned long flags; + + USBENTER(""); + while (1) { + spin_lock_irqsave(&wrap_urb_complete_list_lock, flags); + ent = RemoveHeadList(&wrap_urb_complete_list); + spin_unlock_irqrestore(&wrap_urb_complete_list_lock, flags); + if (!ent) + break; + wrap_urb = container_of(ent, struct wrap_urb, complete_list); + urb = wrap_urb->urb; +#ifdef USB_DEBUG + if (wrap_urb->state != URB_COMPLETED && + wrap_urb->state != URB_INT_UNLINKED) + WARNING("urb %p in wrong state: %d", + urb, wrap_urb->state); +#endif + irp = wrap_urb->irp; + DUMP_IRP(irp); + nt_urb = IRP_URB(irp); + USBTRACE("urb: %p, nt_urb: %p, status: %d", + urb, nt_urb, urb->status); + switch (urb->status) { + case 0: + /* succesfully transferred */ + irp->io_status.info = urb->actual_length; + if (nt_urb->header.function == + URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER) { + bulk_int_tx = &nt_urb->bulk_int_transfer; + bulk_int_tx->transfer_buffer_length = + urb->actual_length; + DUMP_URB_BUFFER(urb, USB_DIR_IN); + if ((wrap_urb->flags & WRAP_URB_COPY_BUFFER) && + usb_pipein(urb->pipe)) + memcpy(bulk_int_tx->transfer_buffer, + urb->transfer_buffer, + urb->actual_length); + } else { // vendor or class request + vc_req = &nt_urb->vendor_class_request; + vc_req->transfer_buffer_length = + urb->actual_length; + DUMP_URB_BUFFER(urb, USB_DIR_IN); + if ((wrap_urb->flags & WRAP_URB_COPY_BUFFER) && + usb_pipein(urb->pipe)) + memcpy(vc_req->transfer_buffer, + urb->transfer_buffer, + urb->actual_length); + } + NT_URB_STATUS(nt_urb) = USBD_STATUS_SUCCESS; + irp->io_status.status = STATUS_SUCCESS; + break; + case -ENOENT: + case -ECONNRESET: + /* urb canceled */ + irp->io_status.info = 0; + TRACE2("urb %p canceled", urb); + NT_URB_STATUS(nt_urb) = USBD_STATUS_SUCCESS; + irp->io_status.status = STATUS_CANCELLED; + break; + default: + TRACE2("irp: %p, urb: %p, status: %d/%d", + irp, urb, urb->status, wrap_urb->state); + irp->io_status.info = 0; + NT_URB_STATUS(nt_urb) = wrap_urb_status(urb->status); + irp->io_status.status = + nt_urb_irp_status(NT_URB_STATUS(nt_urb)); + break; + } + wrap_free_urb(urb); + IoCompleteRequest(irp, IO_NO_INCREMENT); + } + USBEXIT(return); +} + +static USBD_STATUS wrap_bulk_or_intr_trans(struct irp *irp) +{ + usbd_pipe_handle pipe_handle; + struct urb *urb; + unsigned int pipe; + struct usbd_bulk_or_intr_transfer *bulk_int_tx; + USBD_STATUS status; + struct usb_device *udev; + union nt_urb *nt_urb; + + nt_urb = IRP_URB(irp); + udev = IRP_WRAP_DEVICE(irp)->usb.udev; + bulk_int_tx = &nt_urb->bulk_int_transfer; + pipe_handle = bulk_int_tx->pipe_handle; + USBTRACE("flags: 0x%x, length: %u, buffer: %p, handle: %p", + bulk_int_tx->transfer_flags, + bulk_int_tx->transfer_buffer_length, + bulk_int_tx->transfer_buffer, pipe_handle); + + if (USBD_IS_BULK_PIPE(pipe_handle)) { + if (bulk_int_tx->transfer_flags & USBD_TRANSFER_DIRECTION_IN) + pipe = usb_rcvbulkpipe(udev, + pipe_handle->bEndpointAddress); + else + pipe = usb_sndbulkpipe(udev, + pipe_handle->bEndpointAddress); + } else { + if (bulk_int_tx->transfer_flags & USBD_TRANSFER_DIRECTION_IN) + pipe = usb_rcvintpipe(udev, + pipe_handle->bEndpointAddress); + else + pipe = usb_sndintpipe(udev, + pipe_handle->bEndpointAddress); + } + + DUMP_IRP(irp); + urb = wrap_alloc_urb(irp, pipe, bulk_int_tx->transfer_buffer, + bulk_int_tx->transfer_buffer_length); + if (!urb) { + ERROR("couldn't allocate urb"); + return USBD_STATUS_NO_MEMORY; + } + if (usb_pipein(pipe) && + (!(bulk_int_tx->transfer_flags & USBD_SHORT_TRANSFER_OK))) { + USBTRACE("short not ok"); + urb->transfer_flags |= URB_SHORT_NOT_OK; + } + if (usb_pipebulk(pipe)) { + usb_fill_bulk_urb(urb, udev, pipe, urb->transfer_buffer, + bulk_int_tx->transfer_buffer_length, + wrap_urb_complete, urb->context); + USBTRACE("submitting bulk urb %p on pipe 0x%x (ep 0x%x)", + urb, urb->pipe, pipe_handle->bEndpointAddress); + } else { + usb_fill_int_urb(urb, udev, pipe, urb->transfer_buffer, + bulk_int_tx->transfer_buffer_length, + wrap_urb_complete, urb->context, + pipe_handle->bInterval); + USBTRACE("submitting interrupt urb %p on pipe 0x%x (ep 0x%x), " + "intvl: %d", urb, urb->pipe, + pipe_handle->bEndpointAddress, pipe_handle->bInterval); + } + status = wrap_submit_urb(irp); + USBTRACE("status: %08X", status); + USBEXIT(return status); +} + +static USBD_STATUS wrap_vendor_or_class_req(struct irp *irp) +{ + u8 req_type; + unsigned int pipe; + struct usbd_vendor_or_class_request *vc_req; + struct usb_device *udev; + union nt_urb *nt_urb; + USBD_STATUS status; + struct urb *urb; + struct usb_ctrlrequest *dr; + + nt_urb = IRP_URB(irp); + udev = IRP_WRAP_DEVICE(irp)->usb.udev; + vc_req = &nt_urb->vendor_class_request; + USBTRACE("bits: %x, req: %x, val: %08x, index: %08x, flags: %x," + "buf: %p, len: %d", vc_req->reserved_bits, vc_req->request, + vc_req->value, vc_req->index, vc_req->transfer_flags, + vc_req->transfer_buffer, vc_req->transfer_buffer_length); + + USBTRACE("%x", nt_urb->header.function); + switch (nt_urb->header.function) { + case URB_FUNCTION_VENDOR_DEVICE: + req_type = USB_TYPE_VENDOR | USB_RECIP_DEVICE; + break; + case URB_FUNCTION_VENDOR_INTERFACE: + req_type = USB_TYPE_VENDOR | USB_RECIP_INTERFACE; + break; + case URB_FUNCTION_VENDOR_ENDPOINT: + req_type = USB_TYPE_VENDOR | USB_RECIP_ENDPOINT; + break; + case URB_FUNCTION_VENDOR_OTHER: + req_type = USB_TYPE_VENDOR | USB_RECIP_OTHER; + break; + case URB_FUNCTION_CLASS_DEVICE: + req_type = USB_TYPE_CLASS | USB_RECIP_DEVICE; + break; + case URB_FUNCTION_CLASS_INTERFACE: + req_type = USB_TYPE_CLASS | USB_RECIP_INTERFACE; + break; + case URB_FUNCTION_CLASS_ENDPOINT: + req_type = USB_TYPE_CLASS | USB_RECIP_ENDPOINT; + break; + case URB_FUNCTION_CLASS_OTHER: + req_type = USB_TYPE_CLASS | USB_RECIP_OTHER; + break; + default: + ERROR("unknown request type: %x", nt_urb->header.function); + req_type = 0; + break; + } + + req_type |= vc_req->reserved_bits; + USBTRACE("req type: %08x", req_type); + + if (vc_req->transfer_flags & USBD_TRANSFER_DIRECTION_IN) { + pipe = usb_rcvctrlpipe(udev, 0); + req_type |= USB_DIR_IN; + USBTRACE("pipe: %x, dir in", pipe); + } else { + pipe = usb_sndctrlpipe(udev, 0); + req_type |= USB_DIR_OUT; + USBTRACE("pipe: %x, dir out", pipe); + } + urb = wrap_alloc_urb(irp, pipe, vc_req->transfer_buffer, + vc_req->transfer_buffer_length); + if (!urb) { + ERROR("couldn't allocate urb"); + return USBD_STATUS_NO_MEMORY; + } + + if (usb_pipein(pipe) && + (!(vc_req->transfer_flags & USBD_SHORT_TRANSFER_OK))) { + USBTRACE("short not ok"); + urb->transfer_flags |= URB_SHORT_NOT_OK; + } + + dr = kzalloc(sizeof(*dr), GFP_ATOMIC); + if (!dr) { + ERROR("couldn't allocate memory"); + wrap_free_urb(urb); + return USBD_STATUS_NO_MEMORY; + } + dr->bRequestType = req_type; + dr->bRequest = vc_req->request; + dr->wValue = cpu_to_le16(vc_req->value); + dr->wIndex = cpu_to_le16((u16)vc_req->index); + dr->wLength = cpu_to_le16((u16)urb->transfer_buffer_length); + + usb_fill_control_urb(urb, udev, pipe, (unsigned char *)dr, + urb->transfer_buffer, urb->transfer_buffer_length, + wrap_urb_complete, urb->context); + status = wrap_submit_urb(irp); + USBTRACE("status: %08X", status); + USBEXIT(return status); +} + +static USBD_STATUS wrap_reset_pipe(struct usb_device *udev, struct irp *irp) +{ + int ret; + union nt_urb *nt_urb; + usbd_pipe_handle pipe_handle; + unsigned int pipe1, pipe2; + + nt_urb = IRP_URB(irp); + pipe_handle = nt_urb->pipe_req.pipe_handle; + /* TODO: not clear if both directions should be cleared? */ + if (USBD_IS_BULK_PIPE(pipe_handle)) { + pipe1 = usb_rcvbulkpipe(udev, pipe_handle->bEndpointAddress); + pipe2 = usb_sndbulkpipe(udev, pipe_handle->bEndpointAddress); + } else if (USBD_IS_INT_PIPE(pipe_handle)) { + pipe1 = usb_rcvintpipe(udev, pipe_handle->bEndpointAddress); + pipe2 = pipe1; + } else { + WARNING("invalid pipe %d", pipe_handle->bEndpointAddress); + return USBD_STATUS_INVALID_PIPE_HANDLE; + } + USBTRACE("ep: %d, pipe: 0x%x", pipe_handle->bEndpointAddress, pipe1); + ret = usb_clear_halt(udev, pipe1); + if (ret) + USBTRACE("resetting pipe %d failed: %d", pipe1, ret); + if (pipe2 != pipe1) { + ret = usb_clear_halt(udev, pipe2); + if (ret) + USBTRACE("resetting pipe %d failed: %d", pipe2, ret); + } +// return wrap_urb_status(ret); + return USBD_STATUS_SUCCESS; +} + +static USBD_STATUS wrap_abort_pipe(struct usb_device *udev, struct irp *irp) +{ + union nt_urb *nt_urb; + usbd_pipe_handle pipe_handle; + struct wrap_urb *wrap_urb; + struct wrap_device *wd; + KIRQL irql; + + wd = IRP_WRAP_DEVICE(irp); + nt_urb = IRP_URB(irp); + pipe_handle = nt_urb->pipe_req.pipe_handle; + USBENTER("%p, %x", irp, pipe_handle->bEndpointAddress); + IoAcquireCancelSpinLock(&irql); + nt_list_for_each_entry(wrap_urb, &wd->usb.wrap_urb_list, list) { + USBTRACE("%p, %p, %d, %x, %x", wrap_urb, wrap_urb->urb, + wrap_urb->state, wrap_urb->urb->pipe, + usb_pipeendpoint(wrap_urb->urb->pipe)); + /* for WG111T driver, urbs for endpoint 0 should also + * be canceled */ + if ((usb_pipeendpoint(wrap_urb->urb->pipe) == + pipe_handle->bEndpointAddress) || + (usb_pipeendpoint(wrap_urb->urb->pipe) == 0)) { + if (wrap_cancel_urb(wrap_urb) == 0) + USBTRACE("canceled wrap_urb: %p", wrap_urb); + } + } + IoReleaseCancelSpinLock(irql); + NT_URB_STATUS(nt_urb) = USBD_STATUS_CANCELED; + USBEXIT(return USBD_STATUS_SUCCESS); +} + +static USBD_STATUS wrap_set_clear_feature(struct usb_device *udev, + struct irp *irp) +{ + union nt_urb *nt_urb; + struct urb_control_feature_request *feat_req; + int ret = 0; + __u8 request, type; + __u16 feature; + + nt_urb = IRP_URB(irp); + feat_req = &nt_urb->feat_req; + feature = feat_req->feature_selector; + switch (nt_urb->header.function) { + case URB_FUNCTION_SET_FEATURE_TO_DEVICE: + request = USB_REQ_SET_FEATURE; + type = USB_DT_DEVICE; + break; + case URB_FUNCTION_SET_FEATURE_TO_INTERFACE: + request = USB_REQ_SET_FEATURE; + type = USB_DT_INTERFACE; + break; + case URB_FUNCTION_SET_FEATURE_TO_ENDPOINT: + request = USB_REQ_SET_FEATURE; + type = USB_DT_ENDPOINT; + break; + case URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE: + request = USB_REQ_CLEAR_FEATURE; + type = USB_DT_DEVICE; + break; + case URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE: + request = USB_REQ_CLEAR_FEATURE; + type = USB_DT_INTERFACE; + break; + case URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT: + request = USB_REQ_CLEAR_FEATURE; + type = USB_DT_ENDPOINT; + break; + default: + WARNING("invalid function: %x", nt_urb->header.function); + NT_URB_STATUS(nt_urb) = USBD_STATUS_NOT_SUPPORTED; + return NT_URB_STATUS(nt_urb); + } + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), request, type, + feature, feat_req->index, NULL, 0, 1000); + NT_URB_STATUS(nt_urb) = wrap_urb_status(ret); + USBEXIT(return NT_URB_STATUS(nt_urb)); +} + +static USBD_STATUS wrap_get_status_request(struct usb_device *udev, + struct irp *irp) +{ + union nt_urb *nt_urb; + struct urb_control_get_status_request *status_req; + int ret = 0; + __u8 type; + + nt_urb = IRP_URB(irp); + status_req = &nt_urb->status_req; + switch (nt_urb->header.function) { + case URB_FUNCTION_GET_STATUS_FROM_DEVICE: + type = USB_RECIP_DEVICE; + break; + case URB_FUNCTION_GET_STATUS_FROM_INTERFACE: + type = USB_RECIP_INTERFACE; + break; + case URB_FUNCTION_GET_STATUS_FROM_ENDPOINT: + type = USB_RECIP_ENDPOINT; + break; + default: + WARNING("invalid function: %x", nt_urb->header.function); + NT_URB_STATUS(nt_urb) = USBD_STATUS_NOT_SUPPORTED; + return NT_URB_STATUS(nt_urb); + } + assert(status_req->transfer_buffer_length == sizeof(u16)); + ret = usb_get_status(udev, type, status_req->index, + status_req->transfer_buffer); + if (ret >= 0) { + assert(ret <= status_req->transfer_buffer_length); + status_req->transfer_buffer_length = ret; + NT_URB_STATUS(nt_urb) = USBD_STATUS_SUCCESS; + } else + NT_URB_STATUS(nt_urb) = wrap_urb_status(ret); + USBEXIT(return NT_URB_STATUS(nt_urb)); +} + +static void set_intf_pipe_info(struct wrap_device *wd, + struct usb_interface *usb_intf, + struct usbd_interface_information *intf) +{ + int i; + struct usb_endpoint_descriptor *ep; + struct usbd_pipe_information *pipe; + + for (i = 0; i < CUR_ALT_SETTING(usb_intf)->desc.bNumEndpoints; i++) { + ep = &(CUR_ALT_SETTING(usb_intf)->endpoint[i]).desc; + if (i >= intf->bNumEndpoints) { + ERROR("intf %p has only %d endpoints, " + "ignoring endpoints above %d", + intf, intf->bNumEndpoints, i); + break; + } + pipe = &intf->pipes[i]; + + if (pipe->flags & USBD_PF_CHANGE_MAX_PACKET) + USBTRACE("pkt_sz: %d: %d", pipe->wMaxPacketSize, + pipe->max_tx_size); + USBTRACE("driver wants max_tx_size to %d", + pipe->max_tx_size); + + pipe->wMaxPacketSize = le16_to_cpu(ep->wMaxPacketSize); + pipe->bEndpointAddress = ep->bEndpointAddress; + pipe->type = ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; + if (pipe->type == UsbdPipeTypeInterrupt) { + /* Windows and Linux differ in how the + * bInterval is interpretted */ + /* for low speed: + interval (Windows) -> frames per ms (Linux) + 0 to 15 -> 8 + 16 to 35 -> 16 + 36 to 255 -> 32 + + for full speed: interval -> frames per ms + 1 -> 1 + 2 to 3 -> 2 + 4 to 7 -> 4 + 8 to 15 -> 8 + 16 to 31 -> 16 + 32 to 255 -> 32 + + for high speed: interval -> microframes + 1 -> 1 + 2 -> 2 + 3 -> 4 + 4 -> 8 + 5 -> 16 + 6 -> 32 + 7 to 255 -> 32 + */ + if (wd->usb.udev->speed == USB_SPEED_LOW) + pipe->bInterval = ep->bInterval + 5; + else if (wd->usb.udev->speed == USB_SPEED_FULL) + pipe->bInterval = ep->bInterval; + else { + int j, k; + for (j = k = 1; j < ep->bInterval; k++) + j *= 2; + pipe->bInterval = k; + } + } + pipe->handle = ep; + USBTRACE("%d: ep 0x%x, type %d, pkt_sz %d, intv %d (%d)," + "type: %d, handle %p", i, ep->bEndpointAddress, + ep->bmAttributes, pipe->wMaxPacketSize, ep->bInterval, + pipe->bInterval, pipe->type, pipe->handle); + } +} + +static USBD_STATUS wrap_select_configuration(struct wrap_device *wd, + union nt_urb *nt_urb, + struct irp *irp) +{ + int i, ret; + struct usbd_select_configuration *sel_conf; + struct usb_device *udev; + struct usbd_interface_information *intf; + struct usb_config_descriptor *config; + struct usb_interface *usb_intf; + + udev = wd->usb.udev; + sel_conf = &nt_urb->select_conf; + config = sel_conf->config; + USBTRACE("%p", config); + if (config == NULL) { + kill_all_urbs(wd, 1); + ret = usb_reset_configuration(udev); + return wrap_urb_status(ret); + } + + USBTRACE("conf: %d, type: %d, length: %d, numif: %d, attr: %08x", + config->bConfigurationValue, config->bDescriptorType, + config->wTotalLength, config->bNumInterfaces, + config->bmAttributes); + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + USB_REQ_SET_CONFIGURATION, 0, + config->bConfigurationValue, 0, + NULL, 0, USB_CTRL_SET_TIMEOUT); + if (ret < 0) { + ERROR("ret: %d", ret); + return wrap_urb_status(ret); + } + sel_conf->handle = udev->actconfig; + intf = &sel_conf->intf; + for (i = 0; i < config->bNumInterfaces && intf->bLength > 0; + i++, intf = (((void *)intf) + intf->bLength)) { + + USBTRACE("intf: %d, alt setting: %d", + intf->bInterfaceNumber, intf->bAlternateSetting); + ret = usb_set_interface(udev, intf->bInterfaceNumber, + intf->bAlternateSetting); + if (ret < 0) { + ERROR("failed with %d", ret); + return wrap_urb_status(ret); + } + usb_intf = usb_ifnum_to_if(udev, intf->bInterfaceNumber); + if (!usb_intf) { + ERROR("couldn't obtain ifnum"); + return USBD_STATUS_REQUEST_FAILED; + } + USBTRACE("intf: %p, num ep: %d", intf, intf->bNumEndpoints); + set_intf_pipe_info(wd, usb_intf, intf); + } + return USBD_STATUS_SUCCESS; +} + +static USBD_STATUS wrap_select_interface(struct wrap_device *wd, + union nt_urb *nt_urb, + struct irp *irp) +{ + int ret; + struct usbd_select_interface *sel_intf; + struct usb_device *udev; + struct usbd_interface_information *intf; + struct usb_interface *usb_intf; + + udev = wd->usb.udev; + sel_intf = &nt_urb->select_intf; + intf = &sel_intf->intf; + + ret = usb_set_interface(udev, intf->bInterfaceNumber, + intf->bAlternateSetting); + if (ret < 0) { + ERROR("failed with %d", ret); + return wrap_urb_status(ret); + } + usb_intf = usb_ifnum_to_if(udev, intf->bInterfaceNumber); + if (!usb_intf) { + ERROR("couldn't get interface information"); + return USBD_STATUS_REQUEST_FAILED; + } + USBTRACE("intf: %p, num ep: %d", usb_intf, intf->bNumEndpoints); + set_intf_pipe_info(wd, usb_intf, intf); + return USBD_STATUS_SUCCESS; +} + +static int wrap_usb_get_string(struct usb_device *udev, unsigned short langid, + unsigned char index, void *buf, int size) +{ + int i, ret; + /* if langid is 0, return array of langauges supported in + * buf */ + for (i = 0; i < 3; i++) { + ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, + (USB_DT_STRING << 8) + index, langid, + buf, size, USB_CTRL_GET_TIMEOUT); + if (ret > 0 || ret == -EPIPE) + break; + } + return ret; +} + +static USBD_STATUS wrap_get_descriptor(struct wrap_device *wd, + union nt_urb *nt_urb, struct irp *irp) +{ + struct usbd_control_descriptor_request *control_desc; + int ret = 0; + struct usb_device *udev; + + udev = wd->usb.udev; + control_desc = &nt_urb->control_desc; + USBTRACE("desctype = %d, descindex = %d, transfer_buffer = %p," + "transfer_buffer_length = %d", control_desc->desc_type, + control_desc->index, control_desc->transfer_buffer, + control_desc->transfer_buffer_length); + + if (control_desc->desc_type == USB_DT_STRING) { + USBTRACE("langid: %x", control_desc->language_id); + ret = wrap_usb_get_string(udev, control_desc->language_id, + control_desc->index, + control_desc->transfer_buffer, + control_desc->transfer_buffer_length); + } else { + ret = usb_get_descriptor(udev, control_desc->desc_type, + control_desc->index, + control_desc->transfer_buffer, + control_desc->transfer_buffer_length); + } + if (ret < 0) { + USBTRACE("request %d failed: %d", control_desc->desc_type, ret); + control_desc->transfer_buffer_length = 0; + return wrap_urb_status(ret); + } else { + USBTRACE("ret: %08x", ret); + control_desc->transfer_buffer_length = ret; + irp->io_status.info = ret; + return USBD_STATUS_SUCCESS; + } +} + +static USBD_STATUS wrap_process_nt_urb(struct irp *irp) +{ + union nt_urb *nt_urb; + struct usb_device *udev; + USBD_STATUS status; + struct wrap_device *wd; + + wd = IRP_WRAP_DEVICE(irp); + udev = wd->usb.udev; + nt_urb = IRP_URB(irp); + USBENTER("nt_urb = %p, irp = %p, length = %d, function = %x", + nt_urb, irp, nt_urb->header.length, nt_urb->header.function); + + DUMP_IRP(irp); + switch (nt_urb->header.function) { + /* bulk/int and vendor/class urbs are submitted to + * Linux USB core; if the call is sucessful, urb's + * completion worker will return IRP later */ + case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: + USBTRACE("submitting bulk/int irp: %p", irp); + status = wrap_bulk_or_intr_trans(irp); + break; + + case URB_FUNCTION_VENDOR_DEVICE: + case URB_FUNCTION_VENDOR_INTERFACE: + case URB_FUNCTION_VENDOR_ENDPOINT: + case URB_FUNCTION_VENDOR_OTHER: + case URB_FUNCTION_CLASS_DEVICE: + case URB_FUNCTION_CLASS_INTERFACE: + case URB_FUNCTION_CLASS_ENDPOINT: + case URB_FUNCTION_CLASS_OTHER: + USBTRACE("submitting vendor/class irp: %p", irp); + status = wrap_vendor_or_class_req(irp); + break; + + /* rest are synchronous */ + case URB_FUNCTION_SELECT_CONFIGURATION: + status = wrap_select_configuration(wd, nt_urb, irp); + NT_URB_STATUS(nt_urb) = status; + break; + + case URB_FUNCTION_SELECT_INTERFACE: + status = wrap_select_interface(wd, nt_urb, irp); + NT_URB_STATUS(nt_urb) = status; + break; + + case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE: + status = wrap_get_descriptor(wd, nt_urb, irp); + NT_URB_STATUS(nt_urb) = status; + break; + + case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL: + status = wrap_reset_pipe(udev, irp); + NT_URB_STATUS(nt_urb) = status; + break; + + case URB_FUNCTION_ABORT_PIPE: + status = wrap_abort_pipe(udev, irp); + break; + + case URB_FUNCTION_SET_FEATURE_TO_DEVICE: + case URB_FUNCTION_SET_FEATURE_TO_INTERFACE: + case URB_FUNCTION_SET_FEATURE_TO_ENDPOINT: + case URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE: + case URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE: + case URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT: + status = wrap_set_clear_feature(udev, irp); + break; + + case URB_FUNCTION_GET_STATUS_FROM_DEVICE: + case URB_FUNCTION_GET_STATUS_FROM_INTERFACE: + case URB_FUNCTION_GET_STATUS_FROM_ENDPOINT: + status = wrap_get_status_request(udev, irp); + break; + + default: + ERROR("function %x not implemented", nt_urb->header.function); + status = NT_URB_STATUS(nt_urb) = USBD_STATUS_NOT_SUPPORTED; + break; + } + USBTRACE("status: %08X", status); + return status; +} + +static USBD_STATUS wrap_reset_port(struct irp *irp) +{ + no_warn_unused int ret, lock = 0; + struct wrap_device *wd; + + wd = IRP_WRAP_DEVICE(irp); + USBENTER("%p, %p", wd, wd->usb.udev); + lock = usb_lock_device_for_reset(wd->usb.udev, wd->usb.intf); + if (lock < 0) { + WARNING("locking failed: %d", lock); +// return wrap_urb_status(lock); + return USBD_STATUS_SUCCESS; + } + ret = usb_reset_device(wd->usb.udev); + if (ret < 0) + USBTRACE("reset failed: %d", ret); + /* TODO: should reconfigure? */ + if (lock) + usb_unlock_device(wd->usb.udev); +// return wrap_urb_status(ret); + return USBD_STATUS_SUCCESS; +} + +static USBD_STATUS wrap_get_port_status(struct irp *irp) +{ + struct wrap_device *wd; + ULONG *status; + enum usb_device_state state; + + wd = IRP_WRAP_DEVICE(irp); + USBENTER("%p, %p", wd, wd->usb.udev); + status = IoGetCurrentIrpStackLocation(irp)->params.others.arg1; + state = wd->usb.udev->state; + if (state != USB_STATE_NOTATTACHED && + state != USB_STATE_SUSPENDED) { + *status |= USBD_PORT_CONNECTED; + if (state == USB_STATE_CONFIGURED) + *status |= USBD_PORT_ENABLED; + } + USBTRACE("state: %d, *status: %08X", state, *status); + return USBD_STATUS_SUCCESS; +} + +NTSTATUS wrap_submit_irp(struct device_object *pdo, struct irp *irp) +{ + struct io_stack_location *irp_sl; + struct wrap_device *wd; + USBD_STATUS status; + struct usbd_idle_callback *idle_callback; + + USBENTER("%p, %p", pdo, irp); + wd = pdo->reserved; + if (wd->usb.intf == NULL) { + USBTRACE("%p", irp); + irp->io_status.status = STATUS_DEVICE_REMOVED; + irp->io_status.info = 0; + USBEXIT(return STATUS_DEVICE_REMOVED); + } + IRP_WRAP_DEVICE(irp) = wd; + irp_sl = IoGetCurrentIrpStackLocation(irp); + switch (irp_sl->params.dev_ioctl.code) { + case IOCTL_INTERNAL_USB_SUBMIT_URB: + status = wrap_process_nt_urb(irp); + break; + case IOCTL_INTERNAL_USB_RESET_PORT: + status = wrap_reset_port(irp); + break; + case IOCTL_INTERNAL_USB_GET_PORT_STATUS: + status = wrap_get_port_status(irp); + break; + case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION: + idle_callback = irp_sl->params.dev_ioctl.type3_input_buf; + USBTRACE("suspend function: %p", idle_callback->callback); + status = USBD_STATUS_NOT_SUPPORTED; + break; + default: + ERROR("ioctl %08X NOT IMPLEMENTED", + irp_sl->params.dev_ioctl.code); + status = USBD_STATUS_NOT_SUPPORTED; + break; + } + + USBTRACE("status: %08X", status); + if (status == USBD_STATUS_PENDING) { + /* don't touch this IRP - it may have been already + * completed/returned */ + return STATUS_PENDING; + } else { + irp->io_status.status = nt_urb_irp_status(status); + if (status != USBD_STATUS_SUCCESS) + irp->io_status.info = 0; + USBEXIT(return irp->io_status.status); + } +} + +/* TODO: The example on msdn in reference section suggests that second + * argument should be an array of usbd_interface_information, but + * description and examples elsewhere suggest that it should be + * usbd_interface_list_entry structre. Which is correct? */ + +wstdcall union nt_urb *WIN_FUNC(USBD_CreateConfigurationRequestEx,2) + (struct usb_config_descriptor *config, + struct usbd_interface_list_entry *intf_list) +{ + int size, i, n; + struct usbd_interface_information *intf; + struct usbd_pipe_information *pipe; + struct usb_interface_descriptor *intf_desc; + struct usbd_select_configuration *select_conf; + + USBENTER("config = %p, intf_list = %p", config, intf_list); + + /* calculate size required; select_conf already has space for + * one intf structure */ + size = sizeof(*select_conf) - sizeof(*intf); + for (n = 0; n < config->bNumInterfaces; n++) { + i = intf_list[n].intf_desc->bNumEndpoints; + /* intf already has space for one pipe */ + size += sizeof(*intf) + (i - 1) * sizeof(*pipe); + } + /* don't use kmalloc - driver frees it with ExFreePool */ + select_conf = ExAllocatePoolWithTag(NonPagedPool, size, + POOL_TAG('L', 'U', 'S', 'B')); + if (!select_conf) { + WARNING("couldn't allocate memory"); + return NULL; + } + memset(select_conf, 0, size); + intf = &select_conf->intf; + select_conf->handle = config; + for (n = 0; n < config->bNumInterfaces && intf_list[n].intf_desc; n++) { + /* initialize 'intf' fields in intf_list so they point + * to appropriate entry; these may be read/written by + * driver after this function returns */ + intf_list[n].intf = intf; + intf_desc = intf_list[n].intf_desc; + + i = intf_desc->bNumEndpoints; + intf->bLength = sizeof(*intf) + (i - 1) * sizeof(*pipe); + + intf->bInterfaceNumber = intf_desc->bInterfaceNumber; + intf->bAlternateSetting = intf_desc->bAlternateSetting; + intf->bInterfaceClass = intf_desc->bInterfaceClass; + intf->bInterfaceSubClass = intf_desc->bInterfaceSubClass; + intf->bInterfaceProtocol = intf_desc->bInterfaceProtocol; + intf->bNumEndpoints = intf_desc->bNumEndpoints; + + pipe = &intf->pipes[0]; + for (i = 0; i < intf->bNumEndpoints; i++) { + memset(&pipe[i], 0, sizeof(*pipe)); + pipe[i].max_tx_size = + USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE; + } + intf->handle = intf_desc; + intf = (((void *)intf) + intf->bLength); + } + select_conf->header.function = URB_FUNCTION_SELECT_CONFIGURATION; + select_conf->header.length = size; + select_conf->config = config; + USBEXIT(return (union nt_urb *)select_conf); +} + +WIN_SYMBOL_MAP("_USBD_CreateConfigurationRequestEx@8", USBD_CreateConfigurationRequestEx) + +wstdcall struct usb_interface_descriptor * +WIN_FUNC(USBD_ParseConfigurationDescriptorEx,7) + (struct usb_config_descriptor *config, void *start, + LONG bInterfaceNumber, LONG bAlternateSetting, LONG bInterfaceClass, + LONG bInterfaceSubClass, LONG bInterfaceProtocol) +{ + void *pos; + struct usb_interface_descriptor *intf; + + USBENTER("config = %p, start = %p, ifnum = %d, alt_setting = %d," + " class = %d, subclass = %d, proto = %d", config, start, + bInterfaceNumber, bAlternateSetting, bInterfaceClass, + bInterfaceSubClass, bInterfaceProtocol); + + for (pos = start; + pos < ((void *)config + le16_to_cpu(config->wTotalLength)); + pos += intf->bLength) { + + intf = pos; + + if ((intf->bDescriptorType == USB_DT_INTERFACE) && + ((bInterfaceNumber == -1) || + (intf->bInterfaceNumber == bInterfaceNumber)) && + ((bAlternateSetting == -1) || + (intf->bAlternateSetting == bAlternateSetting)) && + ((bInterfaceClass == -1) || + (intf->bInterfaceClass == bInterfaceClass)) && + ((bInterfaceSubClass == -1) || + (intf->bInterfaceSubClass == bInterfaceSubClass)) && + ((bInterfaceProtocol == -1) || + (intf->bInterfaceProtocol == bInterfaceProtocol))) { + USBTRACE("selected interface = %p", intf); + USBEXIT(return intf); + } + } + USBEXIT(return NULL); +} + +WIN_SYMBOL_MAP("_USBD_ParseConfigurationDescriptorEx@28", USBD_ParseConfigurationDescriptorEx) + +wstdcall union nt_urb *WIN_FUNC(USBD_CreateConfigurationRequest,2) + (struct usb_config_descriptor *config, USHORT *size) +{ + union nt_urb *nt_urb; + struct usbd_interface_list_entry intf_list[2]; + struct usb_interface_descriptor *intf_desc; + + USBENTER("config = %p, urb_size = %p", config, size); + + intf_desc = USBD_ParseConfigurationDescriptorEx(config, config, -1, -1, + -1, -1, -1); + intf_list[0].intf_desc = intf_desc; + intf_list[0].intf = NULL; + intf_list[1].intf_desc = NULL; + intf_list[1].intf = NULL; + nt_urb = USBD_CreateConfigurationRequestEx(config, intf_list); + if (!nt_urb) + return NULL; + + *size = nt_urb->select_conf.header.length; + USBEXIT(return nt_urb); +} + +wstdcall struct usb_interface_descriptor * +WIN_FUNC(USBD_ParseConfigurationDescriptor,3) + (struct usb_config_descriptor *config, UCHAR bInterfaceNumber, + UCHAR bAlternateSetting) +{ + return USBD_ParseConfigurationDescriptorEx(config, config, + bInterfaceNumber, + bAlternateSetting, + -1, -1, -1); +} + +wstdcall usb_common_descriptor_t *WIN_FUNC(USBD_ParseDescriptors,4) + (void *buf, ULONG length, void *start, LONG type) +{ + usb_common_descriptor_t *descr = start; + + while ((void *)descr < buf + length) { + if (descr->bDescriptorType == type) + return descr; + if (descr->bLength == 0) + break; + descr = (void *)descr + descr->bLength; + } + USBEXIT(return NULL); +} + +WIN_SYMBOL_MAP("_USBD_ParseDescriptors@16", USBD_ParseDescriptors) + +wstdcall void WIN_FUNC(USBD_GetUSBDIVersion,1) + (struct usbd_version_info *version_info) +{ + /* this function is obsolete in Windows XP */ + if (version_info) { + version_info->usbdi_version = USBDI_VERSION_XP; + /* TODO: how do we get this correctly? */ + version_info->supported_usb_version = 0x110; + } + USBEXIT(return); +} + +wstdcall void +USBD_InterfaceGetUSBDIVersion(void *context, + struct usbd_version_info *version_info, + ULONG *hcd_capa) +{ + struct wrap_device *wd = context; + + if (version_info) { + version_info->usbdi_version = USBDI_VERSION_XP; + if (wd->usb.udev->speed == USB_SPEED_HIGH) + version_info->supported_usb_version = 0x200; + else + version_info->supported_usb_version = 0x110; + } + *hcd_capa = USB_HCD_CAPS_SUPPORTS_RT_THREADS; + USBEXIT(return); +} + +wstdcall BOOLEAN USBD_InterfaceIsDeviceHighSpeed(void *context) +{ + struct wrap_device *wd = context; + + USBTRACE("wd: %p", wd); + if (wd->usb.udev->speed == USB_SPEED_HIGH) + USBEXIT(return TRUE); + else + USBEXIT(return FALSE); +} + +wstdcall void USBD_InterfaceReference(void *context) +{ + USBTRACE("%p", context); + TODO(); +} + +wstdcall void USBD_InterfaceDereference(void *context) +{ + USBTRACE("%p", context); + TODO(); +} + +wstdcall NTSTATUS USBD_InterfaceQueryBusTime(void *context, ULONG *frame) +{ + struct wrap_device *wd = context; + + *frame = usb_get_current_frame_number(wd->usb.udev); + USBEXIT(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS USBD_InterfaceSubmitIsoOutUrb(void *context, + union nt_urb *nt_urb) +{ + /* TODO: implement this */ + TODO(); + USBEXIT(return STATUS_NOT_IMPLEMENTED); +} + +wstdcall NTSTATUS +USBD_InterfaceQueryBusInformation(void *context, ULONG level, void *buf, + ULONG *buf_length, ULONG *buf_actual_length) +{ + struct wrap_device *wd = context; + struct usb_bus_information_level *bus_info; + struct usb_bus *bus; + + bus = wd->usb.udev->bus; + bus_info = buf; + TODO(); + USBEXIT(return STATUS_NOT_IMPLEMENTED); +} + +wstdcall NTSTATUS +USBD_InterfaceLogEntry(void *context, ULONG driver_tag, ULONG enum_tag, + ULONG p1, ULONG p2) +{ + ERROR("%p, %x, %x, %x, %x", context, driver_tag, enum_tag, p1, p2); + USBEXIT(return STATUS_SUCCESS); +} + +int usb_init(void) +{ + InitializeListHead(&wrap_urb_complete_list); + spin_lock_init(&wrap_urb_complete_list_lock); + initialize_work(&wrap_urb_complete_work, wrap_urb_complete_worker, NULL); +#ifdef USB_DEBUG + urb_id = 0; +#endif + return 0; +} + +void usb_exit(void) +{ + USBEXIT(return); +} + +int usb_init_device(struct wrap_device *wd) +{ + InitializeListHead(&wd->usb.wrap_urb_list); + wd->usb.num_alloc_urbs = 0; + USBEXIT(return 0); +} + +void usb_exit_device(struct wrap_device *wd) +{ + kill_all_urbs(wd, 0); + USBEXIT(return); +} --- linux-2.6.28.orig/ubuntu/ndiswrapper/pnp.h +++ linux-2.6.28/ubuntu/ndiswrapper/pnp.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2005 Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#ifndef _PNP_H_ +#define _PNP_H_ + +#include "ntoskernel.h" +#include "ndis.h" +#include "wrapndis.h" + +NTSTATUS pnp_start_device(struct wrap_device *wd); +NTSTATUS pnp_stop_device(struct wrap_device *wd); +NTSTATUS pnp_remove_device(struct wrap_device *wd); + +int wrap_pnp_start_pci_device(struct pci_dev *pdev, + const struct pci_device_id *ent); +void __devexit wrap_pnp_remove_pci_device(struct pci_dev *pdev); +int wrap_pnp_suspend_pci_device(struct pci_dev *pdev, pm_message_t state); +int wrap_pnp_resume_pci_device(struct pci_dev *pdev); + +#ifdef ENABLE_USB +int wrap_pnp_start_usb_device(struct usb_interface *intf, + const struct usb_device_id *usb_id); +void wrap_pnp_remove_usb_device(struct usb_interface *intf); +int wrap_pnp_suspend_usb_device(struct usb_interface *intf, + pm_message_t state); +int wrap_pnp_resume_usb_device(struct usb_interface *intf); +#endif + +#endif --- linux-2.6.28.orig/ubuntu/ndiswrapper/ntoskernel.c +++ linux-2.6.28/ubuntu/ndiswrapper/ntoskernel.c @@ -0,0 +1,2677 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#include "ntoskernel.h" +#include "ndis.h" +#include "usb.h" +#include "pnp.h" +#include "loader.h" +#include "ntoskernel_exports.h" + +/* MDLs describe a range of virtual address with an array of physical + * pages right after the header. For different ranges of virtual + * addresses, the number of entries of physical pages may be different + * (depending on number of entries required). If we want to allocate + * MDLs from a pool, the size has to be constant. So we assume that + * maximum range used by a driver is MDL_CACHE_PAGES; if a driver + * requests an MDL for a bigger region, we allocate it with kmalloc; + * otherwise, we allocate from the pool */ + +#define MDL_CACHE_PAGES 3 +#define MDL_CACHE_SIZE (sizeof(struct mdl) + \ + (sizeof(PFN_NUMBER) * MDL_CACHE_PAGES)) +struct wrap_mdl { + struct nt_list list; + struct mdl mdl[0]; +}; + +/* everything here is for all drivers/devices - not per driver/device */ +static spinlock_t dispatcher_lock; +spinlock_t ntoskernel_lock; +static void *mdl_cache; +static struct nt_list wrap_mdl_list; + +static work_struct_t kdpc_work; +static void kdpc_worker(worker_param_t dummy); + +static struct nt_list kdpc_list; +static spinlock_t kdpc_list_lock; + +static struct nt_list callback_objects; + +struct nt_list object_list; + +struct bus_driver { + struct nt_list list; + char name[MAX_DRIVER_NAME_LEN]; + struct driver_object drv_obj; +}; + +static struct nt_list bus_driver_list; + +static work_struct_t ntos_work; +static struct nt_list ntos_work_list; +static spinlock_t ntos_work_lock; +static void ntos_work_worker(worker_param_t dummy); +static struct nt_thread *ntos_worker_thread; +spinlock_t irp_cancel_lock; +static NT_SPIN_LOCK nt_list_lock; +static struct nt_slist wrap_timer_slist; + +/* compute ticks (100ns) since 1601 until when system booted into + * wrap_ticks_to_boot */ +u64 wrap_ticks_to_boot; + +#if defined(CONFIG_X86_64) +static struct timer_list shared_data_timer; +struct kuser_shared_data kuser_shared_data; +static void update_user_shared_data_proc(unsigned long data); +#endif + +WIN_SYMBOL_MAP("KeTickCount", &jiffies) + +WIN_SYMBOL_MAP("NlsMbCodePageTag", FALSE) + +workqueue_struct_t *ntos_wq; + +#ifdef WRAP_PREEMPT +DEFINE_PER_CPU(irql_info_t, irql_info); +#endif + +#if defined(CONFIG_X86_64) +static void update_user_shared_data_proc(unsigned long data) +{ + /* timer is supposed to be scheduled every 10ms, but bigger + * intervals seem to work (tried upto 50ms) */ + *((ULONG64 *)&kuser_shared_data.system_time) = ticks_1601(); + *((ULONG64 *)&kuser_shared_data.interrupt_time) = + jiffies * TICKSPERSEC / HZ; + *((ULONG64 *)&kuser_shared_data.tick) = jiffies; + + mod_timer(&shared_data_timer, jiffies + MSEC_TO_HZ(30)); +} +#endif + +void *allocate_object(ULONG size, enum common_object_type type, + struct unicode_string *name) +{ + struct common_object_header *hdr; + void *body; + + /* we pad header as prefix to body */ + hdr = ExAllocatePoolWithTag(NonPagedPool, OBJECT_SIZE(size), 0); + if (!hdr) { + WARNING("couldn't allocate memory"); + return NULL; + } + memset(hdr, 0, OBJECT_SIZE(size)); + if (name) { + hdr->name.buf = ExAllocatePoolWithTag(NonPagedPool, + name->max_length, 0); + if (!hdr->name.buf) { + ExFreePool(hdr); + return NULL; + } + memcpy(hdr->name.buf, name->buf, name->max_length); + hdr->name.length = name->length; + hdr->name.max_length = name->max_length; + } + hdr->type = type; + hdr->ref_count = 1; + spin_lock_bh(&ntoskernel_lock); + /* threads are looked up often (in KeWaitForXXX), so optimize + * for fast lookups of threads */ + if (type == OBJECT_TYPE_NT_THREAD) + InsertHeadList(&object_list, &hdr->list); + else + InsertTailList(&object_list, &hdr->list); + spin_unlock_bh(&ntoskernel_lock); + body = HEADER_TO_OBJECT(hdr); + TRACE3("allocated hdr: %p, body: %p", hdr, body); + return body; +} + +void free_object(void *object) +{ + struct common_object_header *hdr; + + hdr = OBJECT_TO_HEADER(object); + spin_lock_bh(&ntoskernel_lock); + RemoveEntryList(&hdr->list); + spin_unlock_bh(&ntoskernel_lock); + TRACE3("freed hdr: %p, body: %p", hdr, object); + if (hdr->name.buf) + ExFreePool(hdr->name.buf); + ExFreePool(hdr); +} + +static int add_bus_driver(const char *name) +{ + struct bus_driver *bus_driver; + + bus_driver = kzalloc(sizeof(*bus_driver), GFP_KERNEL); + if (!bus_driver) { + ERROR("couldn't allocate memory"); + return -ENOMEM; + } + strncpy(bus_driver->name, name, sizeof(bus_driver->name)); + bus_driver->name[sizeof(bus_driver->name)-1] = 0; + spin_lock_bh(&ntoskernel_lock); + InsertTailList(&bus_driver_list, &bus_driver->list); + spin_unlock_bh(&ntoskernel_lock); + TRACE1("bus driver %s is at %p", name, &bus_driver->drv_obj); + return STATUS_SUCCESS; +} + +struct driver_object *find_bus_driver(const char *name) +{ + struct bus_driver *bus_driver; + struct driver_object *drv_obj; + + spin_lock_bh(&ntoskernel_lock); + drv_obj = NULL; + nt_list_for_each_entry(bus_driver, &bus_driver_list, list) { + if (strcmp(bus_driver->name, name) == 0) { + drv_obj = &bus_driver->drv_obj; + break; + } + } + spin_unlock_bh(&ntoskernel_lock); + return drv_obj; +} + +wfastcall struct nt_list *WIN_FUNC(ExfInterlockedInsertHeadList,3) + (struct nt_list *head, struct nt_list *entry, NT_SPIN_LOCK *lock) +{ + struct nt_list *first; + unsigned long flags; + + ENTER5("head = %p, entry = %p", head, entry); + nt_spin_lock_irqsave(lock, flags); + first = InsertHeadList(head, entry); + nt_spin_unlock_irqrestore(lock, flags); + TRACE5("head = %p, old = %p", head, first); + return first; +} + +wfastcall struct nt_list *WIN_FUNC(ExInterlockedInsertHeadList,3) + (struct nt_list *head, struct nt_list *entry, NT_SPIN_LOCK *lock) +{ + ENTER5("%p", head); + return ExfInterlockedInsertHeadList(head, entry, lock); +} + +wfastcall struct nt_list *WIN_FUNC(ExfInterlockedInsertTailList,3) + (struct nt_list *head, struct nt_list *entry, NT_SPIN_LOCK *lock) +{ + struct nt_list *last; + unsigned long flags; + + ENTER5("head = %p, entry = %p", head, entry); + nt_spin_lock_irqsave(lock, flags); + last = InsertTailList(head, entry); + nt_spin_unlock_irqrestore(lock, flags); + TRACE5("head = %p, old = %p", head, last); + return last; +} + +wfastcall struct nt_list *WIN_FUNC(ExInterlockedInsertTailList,3) + (struct nt_list *head, struct nt_list *entry, NT_SPIN_LOCK *lock) +{ + ENTER5("%p", head); + return ExfInterlockedInsertTailList(head, entry, lock); +} + +wfastcall struct nt_list *WIN_FUNC(ExfInterlockedRemoveHeadList,2) + (struct nt_list *head, NT_SPIN_LOCK *lock) +{ + struct nt_list *ret; + unsigned long flags; + + ENTER5("head = %p", head); + nt_spin_lock_irqsave(lock, flags); + ret = RemoveHeadList(head); + nt_spin_unlock_irqrestore(lock, flags); + TRACE5("head = %p, ret = %p", head, ret); + return ret; +} + +wfastcall struct nt_list *WIN_FUNC(ExInterlockedRemoveHeadList,2) + (struct nt_list *head, NT_SPIN_LOCK *lock) +{ + ENTER5("%p", head); + return ExfInterlockedRemoveHeadList(head, lock); +} + +wfastcall struct nt_list *WIN_FUNC(ExfInterlockedRemoveTailList,2) + (struct nt_list *head, NT_SPIN_LOCK *lock) +{ + struct nt_list *ret; + unsigned long flags; + + ENTER5("head = %p", head); + nt_spin_lock_irqsave(lock, flags); + ret = RemoveTailList(head); + nt_spin_unlock_irqrestore(lock, flags); + TRACE5("head = %p, ret = %p", head, ret); + return ret; +} + +wfastcall struct nt_list *WIN_FUNC(ExInterlockedRemoveTailList,2) + (struct nt_list *head, NT_SPIN_LOCK *lock) +{ + ENTER5("%p", head); + return ExfInterlockedRemoveTailList(head, lock); +} + +wfastcall void WIN_FUNC(InitializeSListHead,1) + (nt_slist_header *head) +{ + memset(head, 0, sizeof(*head)); +} + +wfastcall struct nt_slist *WIN_FUNC(ExInterlockedPushEntrySList,3) + (nt_slist_header *head, struct nt_slist *entry, NT_SPIN_LOCK *lock) +{ + struct nt_slist *ret; + + ret = PushEntrySList(head, entry, lock); + return ret; +} + +wstdcall struct nt_slist *WIN_FUNC(ExpInterlockedPushEntrySList,2) + (nt_slist_header *head, struct nt_slist *entry) +{ + struct nt_slist *ret; + + ret = PushEntrySList(head, entry, &nt_list_lock); + return ret; +} + +wfastcall struct nt_slist *WIN_FUNC(InterlockedPushEntrySList,2) + (nt_slist_header *head, struct nt_slist *entry) +{ + struct nt_slist *ret; + + ret = PushEntrySList(head, entry, &nt_list_lock); + return ret; +} + +wfastcall struct nt_slist *WIN_FUNC(ExInterlockedPopEntrySList,2) + (nt_slist_header *head, NT_SPIN_LOCK *lock) +{ + struct nt_slist *ret; + + ret = PopEntrySList(head, lock); + return ret; +} + +wstdcall struct nt_slist *WIN_FUNC(ExpInterlockedPopEntrySList,1) + (nt_slist_header *head) +{ + struct nt_slist *ret; + + ret = PopEntrySList(head, &nt_list_lock); + return ret; +} + +wfastcall struct nt_slist *WIN_FUNC(InterlockedPopEntrySList,1) + (nt_slist_header *head) +{ + struct nt_slist *ret; + + ret = PopEntrySList(head, &nt_list_lock); + return ret; +} + +wstdcall USHORT WIN_FUNC(ExQueryDepthSList,1) + (nt_slist_header *head) +{ + USHORT depth; + ENTER5("%p", head); + depth = head->depth; + TRACE5("%d, %p", depth, head->next); + return depth; +} + +wfastcall LONG WIN_FUNC(InterlockedIncrement,1) + (LONG volatile *val) +{ + return post_atomic_add(*val, 1); +} + +wfastcall LONG WIN_FUNC(InterlockedDecrement,1) + (LONG volatile *val) +{ + return post_atomic_add(*val, -1); +} + +wfastcall LONG WIN_FUNC(InterlockedExchange,2) + (LONG volatile *target, LONG val) +{ + return xchg(target, val); +} + +wfastcall LONG WIN_FUNC(InterlockedCompareExchange,3) + (LONG volatile *dest, LONG new, LONG old) +{ + return cmpxchg(dest, old, new); +} + +wfastcall void WIN_FUNC(ExInterlockedAddLargeStatistic,2) + (LARGE_INTEGER volatile *plint, ULONG n) +{ + unsigned long flags; + + local_irq_save(flags); +#ifdef CONFIG_X86_64 + __asm__ __volatile__( + "\n" + LOCK_PREFIX "add %1, %0\n\t" + : "+m" (*plint) + : "r" (n)); +#else + __asm__ __volatile__( + "1:\t" + " movl %1, %%ebx\n\t" + " movl %%edx, %%ecx\n\t" + " addl %%eax, %%ebx\n\t" + " adcl $0, %%ecx\n\t" + LOCK_PREFIX "cmpxchg8b %0\n\t" + " jnz 1b\n\t" + : "+m" (*plint) + : "m" (n), "A" (*plint) + : "ebx", "ecx"); +#endif + local_irq_restore(flags); +} + +static void initialize_object(struct dispatcher_header *dh, enum dh_type type, + int state) +{ + memset(dh, 0, sizeof(*dh)); + set_object_type(dh, type); + dh->signal_state = state; + InitializeListHead(&dh->wait_blocks); +} + +static void timer_proc(unsigned long data) +{ + struct wrap_timer *wrap_timer = (struct wrap_timer *)data; + struct nt_timer *nt_timer; + struct kdpc *kdpc; + + nt_timer = wrap_timer->nt_timer; + TIMERENTER("%p(%p), %lu", wrap_timer, nt_timer, jiffies); +#ifdef TIMER_DEBUG + BUG_ON(wrap_timer->wrap_timer_magic != WRAP_TIMER_MAGIC); + BUG_ON(nt_timer->wrap_timer_magic != WRAP_TIMER_MAGIC); +#endif + kdpc = nt_timer->kdpc; + if (kdpc) + queue_kdpc(kdpc); + KeSetEvent((struct nt_event *)nt_timer, 0, FALSE); + if (wrap_timer->repeat) + mod_timer(&wrap_timer->timer, jiffies + wrap_timer->repeat); + TIMEREXIT(return); +} + +void wrap_init_timer(struct nt_timer *nt_timer, enum timer_type type, + struct ndis_mp_block *nmb) +{ + struct wrap_timer *wrap_timer; + + /* TODO: if a timer is initialized more than once, we allocate + * memory for wrap_timer more than once for the same nt_timer, + * wasting memory. We can check if nt_timer->wrap_timer_magic is + * set and not allocate, but it is not guaranteed always to be + * safe */ + TIMERENTER("%p", nt_timer); + /* we allocate memory for wrap_timer behind driver's back and + * there is no NDIS/DDK function where this memory can be + * freed, so we use slack_kmalloc so it gets freed when driver + * is unloaded */ + if (nmb) + wrap_timer = kmalloc(sizeof(*wrap_timer), irql_gfp()); + else + wrap_timer = slack_kmalloc(sizeof(*wrap_timer)); + if (!wrap_timer) { + ERROR("couldn't allocate memory for timer"); + return; + } + + memset(wrap_timer, 0, sizeof(*wrap_timer)); + init_timer(&wrap_timer->timer); + wrap_timer->timer.data = (unsigned long)wrap_timer; + wrap_timer->timer.function = timer_proc; + wrap_timer->nt_timer = nt_timer; +#ifdef TIMER_DEBUG + wrap_timer->wrap_timer_magic = WRAP_TIMER_MAGIC; +#endif + nt_timer->wrap_timer = wrap_timer; + nt_timer->kdpc = NULL; + initialize_object(&nt_timer->dh, type, 0); + nt_timer->wrap_timer_magic = WRAP_TIMER_MAGIC; + TIMERTRACE("timer %p (%p)", wrap_timer, nt_timer); + spin_lock_bh(&ntoskernel_lock); + if (nmb) { + wrap_timer->slist.next = nmb->wnd->wrap_timer_slist.next; + nmb->wnd->wrap_timer_slist.next = &wrap_timer->slist; + } else { + wrap_timer->slist.next = wrap_timer_slist.next; + wrap_timer_slist.next = &wrap_timer->slist; + } + spin_unlock_bh(&ntoskernel_lock); + TIMEREXIT(return); +} + +wstdcall void WIN_FUNC(KeInitializeTimerEx,2) + (struct nt_timer *nt_timer, enum timer_type type) +{ + TIMERENTER("%p", nt_timer); + wrap_init_timer(nt_timer, type, NULL); +} + +wstdcall void WIN_FUNC(KeInitializeTimer,1) + (struct nt_timer *nt_timer) +{ + TIMERENTER("%p", nt_timer); + wrap_init_timer(nt_timer, NotificationTimer, NULL); +} + +/* expires and repeat are in HZ */ +BOOLEAN wrap_set_timer(struct nt_timer *nt_timer, unsigned long expires_hz, + unsigned long repeat_hz, struct kdpc *kdpc) +{ + struct wrap_timer *wrap_timer; + + TIMERENTER("%p, %lu, %lu, %p, %lu", + nt_timer, expires_hz, repeat_hz, kdpc, jiffies); + + wrap_timer = nt_timer->wrap_timer; + TIMERTRACE("%p", wrap_timer); +#ifdef TIMER_DEBUG + if (wrap_timer->nt_timer != nt_timer) + WARNING("bad timers: %p, %p, %p", wrap_timer, nt_timer, + wrap_timer->nt_timer); + if (nt_timer->wrap_timer_magic != WRAP_TIMER_MAGIC) { + WARNING("buggy Windows timer didn't initialize timer %p", + nt_timer); + return FALSE; + } + if (wrap_timer->wrap_timer_magic != WRAP_TIMER_MAGIC) { + WARNING("timer %p is not initialized (%lx)?", + wrap_timer, wrap_timer->wrap_timer_magic); + wrap_timer->wrap_timer_magic = WRAP_TIMER_MAGIC; + } +#endif + KeClearEvent((struct nt_event *)nt_timer); + nt_timer->kdpc = kdpc; + wrap_timer->repeat = repeat_hz; + if (mod_timer(&wrap_timer->timer, jiffies + expires_hz)) + TIMEREXIT(return TRUE); + else + TIMEREXIT(return FALSE); +} + +wstdcall BOOLEAN WIN_FUNC(KeSetTimerEx,4) + (struct nt_timer *nt_timer, LARGE_INTEGER duetime_ticks, + LONG period_ms, struct kdpc *kdpc) +{ + unsigned long expires_hz, repeat_hz; + + TIMERENTER("%p, %Ld, %d", nt_timer, duetime_ticks, period_ms); + expires_hz = SYSTEM_TIME_TO_HZ(duetime_ticks); + repeat_hz = MSEC_TO_HZ(period_ms); + return wrap_set_timer(nt_timer, expires_hz, repeat_hz, kdpc); +} + +wstdcall BOOLEAN WIN_FUNC(KeSetTimer,3) + (struct nt_timer *nt_timer, LARGE_INTEGER duetime_ticks, + struct kdpc *kdpc) +{ + TIMERENTER("%p, %Ld, %p", nt_timer, duetime_ticks, kdpc); + return KeSetTimerEx(nt_timer, duetime_ticks, 0, kdpc); +} + +wstdcall BOOLEAN WIN_FUNC(KeCancelTimer,1) + (struct nt_timer *nt_timer) +{ + struct wrap_timer *wrap_timer; + int ret; + + TIMERENTER("%p", nt_timer); + wrap_timer = nt_timer->wrap_timer; + if (!wrap_timer) { + ERROR("invalid wrap_timer"); + return TRUE; + } +#ifdef TIMER_DEBUG + BUG_ON(wrap_timer->wrap_timer_magic != WRAP_TIMER_MAGIC); +#endif + TIMERTRACE("canceling timer %p(%p)", wrap_timer, nt_timer); + /* disable timer before deleting so if it is periodic timer, it + * won't be re-armed after deleting */ + wrap_timer->repeat = 0; + ret = del_timer(&wrap_timer->timer); + /* the documentation for KeCancelTimer suggests the DPC is + * deqeued, but actually DPC is left to run */ + if (ret) + TIMEREXIT(return TRUE); + else + TIMEREXIT(return FALSE); +} + +wstdcall BOOLEAN WIN_FUNC(KeReadStateTimer,1) + (struct nt_timer *nt_timer) +{ + if (nt_timer->dh.signal_state) + return TRUE; + else + return FALSE; +} + +wstdcall void WIN_FUNC(KeInitializeDpc,3) + (struct kdpc *kdpc, void *func, void *ctx) +{ + ENTER3("%p, %p, %p", kdpc, func, ctx); + memset(kdpc, 0, sizeof(*kdpc)); + kdpc->func = func; + kdpc->ctx = ctx; + InitializeListHead(&kdpc->list); +} + +static void kdpc_worker(worker_param_t dummy) +{ + struct nt_list *entry; + struct kdpc *kdpc; + unsigned long flags; + KIRQL irql; + + WORKENTER(""); + irql = raise_irql(DISPATCH_LEVEL); + while (1) { + spin_lock_irqsave(&kdpc_list_lock, flags); + entry = RemoveHeadList(&kdpc_list); + if (entry) { + kdpc = container_of(entry, struct kdpc, list); + assert(kdpc->queued); + kdpc->queued = 0; + } else + kdpc = NULL; + spin_unlock_irqrestore(&kdpc_list_lock, flags); + if (!kdpc) + break; + WORKTRACE("%p, %p, %p, %p, %p", kdpc, kdpc->func, kdpc->ctx, + kdpc->arg1, kdpc->arg2); + assert_irql(_irql_ == DISPATCH_LEVEL); + LIN2WIN4(kdpc->func, kdpc, kdpc->ctx, kdpc->arg1, kdpc->arg2); + assert_irql(_irql_ == DISPATCH_LEVEL); + } + lower_irql(irql); + WORKEXIT(return); +} + +wstdcall void WIN_FUNC(KeFlushQueuedDpcs,0) + (void) +{ + kdpc_worker(NULL); +} + +BOOLEAN queue_kdpc(struct kdpc *kdpc) +{ + BOOLEAN ret; + unsigned long flags; + + WORKENTER("%p", kdpc); + spin_lock_irqsave(&kdpc_list_lock, flags); + if (kdpc->queued) + ret = FALSE; + else { + if (unlikely(kdpc->importance == HighImportance)) + InsertHeadList(&kdpc_list, &kdpc->list); + else + InsertTailList(&kdpc_list, &kdpc->list); + kdpc->queued = 1; + ret = TRUE; + } + spin_unlock_irqrestore(&kdpc_list_lock, flags); + if (ret == TRUE) + schedule_ntos_work(&kdpc_work); + WORKTRACE("%d", ret); + return ret; +} + +BOOLEAN dequeue_kdpc(struct kdpc *kdpc) +{ + BOOLEAN ret; + unsigned long flags; + + WORKENTER("%p", kdpc); + spin_lock_irqsave(&kdpc_list_lock, flags); + if (kdpc->queued) { + RemoveEntryList(&kdpc->list); + kdpc->queued = 0; + ret = TRUE; + } else + ret = FALSE; + spin_unlock_irqrestore(&kdpc_list_lock, flags); + WORKTRACE("%d", ret); + return ret; +} + +wstdcall BOOLEAN WIN_FUNC(KeInsertQueueDpc,3) + (struct kdpc *kdpc, void *arg1, void *arg2) +{ + WORKENTER("%p, %p, %p", kdpc, arg1, arg2); + kdpc->arg1 = arg1; + kdpc->arg2 = arg2; + return queue_kdpc(kdpc); +} + +wstdcall BOOLEAN WIN_FUNC(KeRemoveQueueDpc,1) + (struct kdpc *kdpc) +{ + return dequeue_kdpc(kdpc); +} + +wstdcall void WIN_FUNC(KeSetImportanceDpc,2) + (struct kdpc *kdpc, enum kdpc_importance importance) +{ + kdpc->importance = importance; +} + +static void ntos_work_worker(worker_param_t dummy) +{ + struct ntos_work_item *ntos_work_item; + struct nt_list *cur; + + while (1) { + spin_lock_bh(&ntos_work_lock); + cur = RemoveHeadList(&ntos_work_list); + spin_unlock_bh(&ntos_work_lock); + if (!cur) + break; + ntos_work_item = container_of(cur, struct ntos_work_item, list); + WORKTRACE("%p: executing %p, %p, %p", current, + ntos_work_item->func, ntos_work_item->arg1, + ntos_work_item->arg2); + LIN2WIN2(ntos_work_item->func, ntos_work_item->arg1, + ntos_work_item->arg2); + kfree(ntos_work_item); + } + WORKEXIT(return); +} + +int schedule_ntos_work_item(NTOS_WORK_FUNC func, void *arg1, void *arg2) +{ + struct ntos_work_item *ntos_work_item; + + WORKENTER("adding work: %p, %p, %p", func, arg1, arg2); + ntos_work_item = kmalloc(sizeof(*ntos_work_item), irql_gfp()); + if (!ntos_work_item) { + ERROR("couldn't allocate memory"); + return -ENOMEM; + } + ntos_work_item->func = func; + ntos_work_item->arg1 = arg1; + ntos_work_item->arg2 = arg2; + spin_lock_bh(&ntos_work_lock); + InsertTailList(&ntos_work_list, &ntos_work_item->list); + spin_unlock_bh(&ntos_work_lock); + schedule_ntos_work(&ntos_work); + WORKEXIT(return 0); +} + +wstdcall void WIN_FUNC(KeInitializeSpinLock,1) + (NT_SPIN_LOCK *lock) +{ + ENTER6("%p", lock); + nt_spin_lock_init(lock); +} + +wstdcall void WIN_FUNC(KeAcquireSpinLock,2) + (NT_SPIN_LOCK *lock, KIRQL *irql) +{ + ENTER6("%p", lock); + *irql = nt_spin_lock_irql(lock, DISPATCH_LEVEL); +} + +wstdcall void WIN_FUNC(KeReleaseSpinLock,2) + (NT_SPIN_LOCK *lock, KIRQL oldirql) +{ + ENTER6("%p", lock); + nt_spin_unlock_irql(lock, oldirql); +} + +wstdcall void WIN_FUNC(KeAcquireSpinLockAtDpcLevel,1) + (NT_SPIN_LOCK *lock) +{ + ENTER6("%p", lock); + nt_spin_lock(lock); +} + +wstdcall void WIN_FUNC(KeReleaseSpinLockFromDpcLevel,1) + (NT_SPIN_LOCK *lock) +{ + ENTER6("%p", lock); + nt_spin_unlock(lock); +} + +wstdcall void WIN_FUNC(KeRaiseIrql,2) + (KIRQL newirql, KIRQL *oldirql) +{ + ENTER6("%d", newirql); + *oldirql = raise_irql(newirql); +} + +wstdcall KIRQL WIN_FUNC(KeRaiseIrqlToDpcLevel,0) + (void) +{ + return raise_irql(DISPATCH_LEVEL); +} + +wstdcall void WIN_FUNC(KeLowerIrql,1) + (KIRQL irql) +{ + ENTER6("%d", irql); + lower_irql(irql); +} + +wstdcall KIRQL WIN_FUNC(KeAcquireSpinLockRaiseToDpc,1) + (NT_SPIN_LOCK *lock) +{ + ENTER6("%p", lock); + return nt_spin_lock_irql(lock, DISPATCH_LEVEL); +} + +#undef ExAllocatePoolWithTag + +wstdcall void *WIN_FUNC(ExAllocatePoolWithTag,3) + (enum pool_type pool_type, SIZE_T size, ULONG tag) +{ + void *addr; + + ENTER4("pool_type: %d, size: %lu, tag: 0x%x", pool_type, size, tag); + assert_irql(_irql_ <= DISPATCH_LEVEL); + if (size < PAGE_SIZE) + addr = kmalloc(size, irql_gfp()); + else { + if (irql_gfp() & GFP_ATOMIC) { + addr = __vmalloc(size, GFP_ATOMIC | __GFP_HIGHMEM, + PAGE_KERNEL); + TRACE1("%p, %lu", addr, size); + } else { + addr = vmalloc(size); + TRACE1("%p, %lu", addr, size); + } + } + DBG_BLOCK(1) { + if (addr) + TRACE4("addr: %p, %lu", addr, size); + else + TRACE1("failed: %lu", size); + } + return addr; +} +WIN_FUNC_DECL(ExAllocatePoolWithTag,3) + +wstdcall void WIN_FUNC(ExFreePoolWithTag,2) + (void *addr, ULONG tag) +{ + TRACE4("%p", addr); + if ((unsigned long)addr < VMALLOC_START || + (unsigned long)addr >= VMALLOC_END) + kfree(addr); + else + vfree(addr); + + EXIT4(return); +} + +wstdcall void WIN_FUNC(ExFreePool,1) + (void *addr) +{ + ExFreePoolWithTag(addr, 0); +} +WIN_FUNC_DECL(ExFreePool,1) + +wstdcall void WIN_FUNC(ExInitializeNPagedLookasideList,7) + (struct npaged_lookaside_list *lookaside, + LOOKASIDE_ALLOC_FUNC *alloc_func, LOOKASIDE_FREE_FUNC *free_func, + ULONG flags, SIZE_T size, ULONG tag, USHORT depth) +{ + ENTER3("lookaside: %p, size: %lu, flags: %u, head: %p, " + "alloc: %p, free: %p", lookaside, size, flags, + lookaside, alloc_func, free_func); + + memset(lookaside, 0, sizeof(*lookaside)); + + lookaside->size = size; + lookaside->tag = tag; + lookaside->depth = 4; + lookaside->maxdepth = 256; + lookaside->pool_type = NonPagedPool; + + if (alloc_func) + lookaside->alloc_func = alloc_func; + else + lookaside->alloc_func = WIN_FUNC_PTR(ExAllocatePoolWithTag,3); + if (free_func) + lookaside->free_func = free_func; + else + lookaside->free_func = WIN_FUNC_PTR(ExFreePool,1); + +#ifndef CONFIG_X86_64 + nt_spin_lock_init(&lookaside->obsolete); +#endif + EXIT3(return); +} + +wstdcall void WIN_FUNC(ExDeleteNPagedLookasideList,1) + (struct npaged_lookaside_list *lookaside) +{ + struct nt_slist *entry; + + ENTER3("lookaside = %p", lookaside); + while ((entry = ExpInterlockedPopEntrySList(&lookaside->head))) + LIN2WIN1(lookaside->free_func, entry); + EXIT3(return); +} + +#if defined(ALLOC_DEBUG) && ALLOC_DEBUG > 1 +#define ExAllocatePoolWithTag(pool_type, size, tag) \ + wrap_ExAllocatePoolWithTag(pool_type, size, tag, __FILE__, __LINE__) +#endif + +wstdcall NTSTATUS WIN_FUNC(ExCreateCallback,4) + (struct callback_object **object, struct object_attributes *attributes, + BOOLEAN create, BOOLEAN allow_multiple_callbacks) +{ + struct callback_object *obj; + + ENTER2(""); + spin_lock_bh(&ntoskernel_lock); + nt_list_for_each_entry(obj, &callback_objects, callback_funcs) { + if (obj->attributes == attributes) { + spin_unlock_bh(&ntoskernel_lock); + *object = obj; + return STATUS_SUCCESS; + } + } + spin_unlock_bh(&ntoskernel_lock); + obj = allocate_object(sizeof(struct callback_object), + OBJECT_TYPE_CALLBACK, NULL); + if (!obj) + EXIT2(return STATUS_INSUFFICIENT_RESOURCES); + InitializeListHead(&obj->callback_funcs); + nt_spin_lock_init(&obj->lock); + obj->allow_multiple_callbacks = allow_multiple_callbacks; + obj->attributes = attributes; + *object = obj; + EXIT2(return STATUS_SUCCESS); +} + +wstdcall void *WIN_FUNC(ExRegisterCallback,3) + (struct callback_object *object, PCALLBACK_FUNCTION func, void *context) +{ + struct callback_func *callback; + KIRQL irql; + + ENTER2(""); + irql = nt_spin_lock_irql(&object->lock, DISPATCH_LEVEL); + if (object->allow_multiple_callbacks == FALSE && + !IsListEmpty(&object->callback_funcs)) { + nt_spin_unlock_irql(&object->lock, irql); + EXIT2(return NULL); + } + nt_spin_unlock_irql(&object->lock, irql); + callback = kmalloc(sizeof(*callback), GFP_KERNEL); + if (!callback) { + ERROR("couldn't allocate memory"); + return NULL; + } + callback->func = func; + callback->context = context; + callback->object = object; + irql = nt_spin_lock_irql(&object->lock, DISPATCH_LEVEL); + InsertTailList(&object->callback_funcs, &callback->list); + nt_spin_unlock_irql(&object->lock, irql); + EXIT2(return callback); +} + +wstdcall void WIN_FUNC(ExUnregisterCallback,1) + (struct callback_func *callback) +{ + struct callback_object *object; + KIRQL irql; + + ENTER3("%p", callback); + if (!callback) + return; + object = callback->object; + irql = nt_spin_lock_irql(&object->lock, DISPATCH_LEVEL); + RemoveEntryList(&callback->list); + nt_spin_unlock_irql(&object->lock, irql); + kfree(callback); + return; +} + +wstdcall void WIN_FUNC(ExNotifyCallback,3) + (struct callback_object *object, void *arg1, void *arg2) +{ + struct callback_func *callback; + KIRQL irql; + + ENTER3("%p", object); + irql = nt_spin_lock_irql(&object->lock, DISPATCH_LEVEL); + nt_list_for_each_entry(callback, &object->callback_funcs, list) { + LIN2WIN3(callback->func, callback->context, arg1, arg2); + } + nt_spin_unlock_irql(&object->lock, irql); + return; +} + +/* check and set signaled state; should be called with dispatcher_lock held */ +/* @grab indicates if the event should be grabbed or checked + * - note that a semaphore may stay in signaled state for multiple + * 'grabs' if the count is > 1 */ +static int grab_object(struct dispatcher_header *dh, + struct task_struct *thread, int grab) +{ + EVENTTRACE("%p, %p, %d, %d", dh, thread, grab, dh->signal_state); + if (unlikely(is_mutex_object(dh))) { + struct nt_mutex *nt_mutex; + nt_mutex = container_of(dh, struct nt_mutex, dh); + EVENTTRACE("%p, %p, %d, %p, %d", nt_mutex, + nt_mutex->owner_thread, dh->signal_state, + thread, grab); + /* either no thread owns the mutex or this thread owns + * it */ + assert(dh->signal_state == 1 && nt_mutex->owner_thread == NULL); + assert(dh->signal_state < 1 && nt_mutex->owner_thread != NULL); + if ((dh->signal_state == 1 && nt_mutex->owner_thread == NULL) || + nt_mutex->owner_thread == thread) { + if (grab) { + dh->signal_state--; + nt_mutex->owner_thread = thread; + } + EVENTEXIT(return 1); + } + } else if (dh->signal_state > 0) { + /* to grab, decrement signal_state for synchronization + * or semaphore objects */ + if (grab && (is_synch_object(dh) || is_semaphore_object(dh))) + dh->signal_state--; + EVENTEXIT(return 1); + } + EVENTEXIT(return 0); +} + +/* this function should be called holding dispatcher_lock */ +static void object_signalled(struct dispatcher_header *dh) +{ + struct nt_list *cur, *next; + struct wait_block *wb; + + EVENTENTER("%p", dh); + nt_list_for_each_safe(cur, next, &dh->wait_blocks) { + wb = container_of(cur, struct wait_block, list); + assert(wb->thread != NULL); + assert(wb->object == NULL); + if (!grab_object(dh, wb->thread, 1)) + continue; + EVENTTRACE("%p (%p): waking %p", dh, wb, wb->thread); + RemoveEntryList(cur); + wb->object = dh; + *(wb->wait_done) = 1; + wake_up_process(wb->thread); + } + EVENTEXIT(return); +} + +wstdcall NTSTATUS WIN_FUNC(KeWaitForMultipleObjects,8) + (ULONG count, void *object[], enum wait_type wait_type, + KWAIT_REASON wait_reason, KPROCESSOR_MODE wait_mode, + BOOLEAN alertable, LARGE_INTEGER *timeout, + struct wait_block *wait_block_array) +{ + int i, res = 0, wait_count, wait_done; + typeof(jiffies) wait_hz = 0; + struct wait_block *wb, wb_array[THREAD_WAIT_OBJECTS]; + struct dispatcher_header *dh; + + EVENTENTER("%p, %d, %u, %p", current, count, wait_type, timeout); + + if (count > MAX_WAIT_OBJECTS || + (count > THREAD_WAIT_OBJECTS && wait_block_array == NULL)) + EVENTEXIT(return STATUS_INVALID_PARAMETER); + + if (wait_block_array == NULL) + wb = wb_array; + else + wb = wait_block_array; + + /* If *timeout == 0: In the case of WaitAny, if an object can + * be grabbed (object is in signaled state), grab and + * return. In the case of WaitAll, we have to first make sure + * all objects can be grabbed. If any/some of them can't be + * grabbed, either we return STATUS_TIMEOUT or wait for them, + * depending on how to satisfy wait. If all of them can be + * grabbed, we will grab them in the next loop below */ + + spin_lock_bh(&dispatcher_lock); + for (i = wait_count = 0; i < count; i++) { + dh = object[i]; + EVENTTRACE("%p: event %p (%d)", current, dh, dh->signal_state); + /* wait_type == 1 for WaitAny, 0 for WaitAll */ + if (grab_object(dh, current, wait_type)) { + if (wait_type == WaitAny) { + spin_unlock_bh(&dispatcher_lock); + EVENTEXIT(return STATUS_WAIT_0 + i); + } + } else { + EVENTTRACE("%p: wait for %p", current, dh); + wait_count++; + } + } + + if (timeout && *timeout == 0 && wait_count) { + spin_unlock_bh(&dispatcher_lock); + EVENTEXIT(return STATUS_TIMEOUT); + } + + /* get the list of objects the thread needs to wait on and add + * the thread on the wait list for each such object */ + /* if *timeout == 0, this step will grab all the objects */ + wait_done = 0; + for (i = 0; i < count; i++) { + dh = object[i]; + EVENTTRACE("%p: event %p (%d)", current, dh, dh->signal_state); + wb[i].object = NULL; + if (grab_object(dh, current, 1)) { + EVENTTRACE("%p: no wait for %p (%d)", + current, dh, dh->signal_state); + /* mark that we are not waiting on this object */ + wb[i].thread = NULL; + } else { + wb[i].wait_done = &wait_done; + wb[i].thread = current; + EVENTTRACE("%p: wait for %p", current, dh); + InsertTailList(&dh->wait_blocks, &wb[i].list); + } + } + spin_unlock_bh(&dispatcher_lock); + if (wait_count == 0) + EVENTEXIT(return STATUS_SUCCESS); + + assert(timeout == NULL || *timeout != 0); + if (timeout == NULL) + wait_hz = 0; + else + wait_hz = SYSTEM_TIME_TO_HZ(*timeout); + + DBG_BLOCK(2) { + KIRQL irql = current_irql(); + if (irql >= DISPATCH_LEVEL) { + TRACE2("wait in atomic context: %lu, %d, %ld", + wait_hz, in_atomic(), in_interrupt()); + } + } + assert_irql(_irql_ < DISPATCH_LEVEL); + EVENTTRACE("%p: sleep for %ld on %p", current, wait_hz, &wait_done); + /* we don't honor 'alertable' - according to decription for + * this, even if waiting in non-alertable state, thread may be + * alerted in some circumstances */ + while (wait_count) { + res = wait_condition(wait_done, wait_hz, TASK_INTERRUPTIBLE); + spin_lock_bh(&dispatcher_lock); + EVENTTRACE("%p woke up: %d, %d", current, res, wait_done); + /* the event may have been set by the time + * wrap_wait_event returned and spinlock obtained, so + * don't rely on value of 'res' - check event status */ + if (!wait_done) { + assert(res <= 0); + /* timed out or interrupted; remove from wait list */ + for (i = 0; i < count; i++) { + if (!wb[i].thread) + continue; + EVENTTRACE("%p: timedout, dequeue %p (%p)", + current, object[i], wb[i].object); + assert(wb[i].object == NULL); + RemoveEntryList(&wb[i].list); + } + spin_unlock_bh(&dispatcher_lock); + if (res < 0) + EVENTEXIT(return STATUS_ALERTED); + else + EVENTEXIT(return STATUS_TIMEOUT); + } + assert(res > 0); + /* woken because object(s) signalled */ + for (i = 0; wait_count && i < count; i++) { + if (!wb[i].thread || !wb[i].object) + continue; + DBG_BLOCK(1) { + if (wb[i].object != object[i]) { + EVENTTRACE("oops %p != %p", + wb[i].object, object[i]); + continue; + } + } + wait_count--; + if (wait_type == WaitAny) { + int j; + /* done; remove from rest of wait list */ + for (j = i + 1; j < count; j++) { + if (wb[j].thread && !wb[j].object) + RemoveEntryList(&wb[j].list); + } + spin_unlock_bh(&dispatcher_lock); + EVENTEXIT(return STATUS_WAIT_0 + i); + } + } + wait_done = 0; + spin_unlock_bh(&dispatcher_lock); + if (wait_count == 0) + EVENTEXIT(return STATUS_SUCCESS); + + /* this thread is still waiting for more objects, so + * let it wait for remaining time and those objects */ + if (timeout) + wait_hz = res; + else + wait_hz = 0; + } + /* should never reach here, but compiler wants return value */ + ERROR("%p: wait_hz: %ld", current, wait_hz); + EVENTEXIT(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(KeWaitForSingleObject,5) + (void *object, KWAIT_REASON wait_reason, KPROCESSOR_MODE wait_mode, + BOOLEAN alertable, LARGE_INTEGER *timeout) +{ + return KeWaitForMultipleObjects(1, &object, WaitAny, wait_reason, + wait_mode, alertable, timeout, NULL); +} + +wstdcall void WIN_FUNC(KeInitializeEvent,3) + (struct nt_event *nt_event, enum event_type type, BOOLEAN state) +{ + EVENTENTER("event = %p, type = %d, state = %d", nt_event, type, state); + initialize_object(&nt_event->dh, type, state); + EVENTEXIT(return); +} + +wstdcall LONG WIN_FUNC(KeSetEvent,3) + (struct nt_event *nt_event, KPRIORITY incr, BOOLEAN wait) +{ + LONG old_state; + + EVENTENTER("%p, %d", nt_event, nt_event->dh.type); + if (wait == TRUE) + WARNING("wait = %d, not yet implemented", wait); + spin_lock_bh(&dispatcher_lock); + old_state = nt_event->dh.signal_state; + nt_event->dh.signal_state = 1; + if (old_state == 0) + object_signalled(&nt_event->dh); + spin_unlock_bh(&dispatcher_lock); + EVENTEXIT(return old_state); +} + +wstdcall void WIN_FUNC(KeClearEvent,1) + (struct nt_event *nt_event) +{ + EVENTENTER("%p", nt_event); + nt_event->dh.signal_state = 0; + EVENTEXIT(return); +} + +wstdcall LONG WIN_FUNC(KeResetEvent,1) + (struct nt_event *nt_event) +{ + LONG old_state; + + EVENTENTER("%p", nt_event); + old_state = xchg(&nt_event->dh.signal_state, 0); + EVENTEXIT(return old_state); +} + +wstdcall LONG WIN_FUNC(KeReadStateEvent,1) + (struct nt_event *nt_event) +{ + LONG state; + + state = nt_event->dh.signal_state; + EVENTTRACE("%d", state); + return state; +} + +wstdcall void WIN_FUNC(KeInitializeMutex,2) + (struct nt_mutex *mutex, ULONG level) +{ + EVENTENTER("%p", mutex); + initialize_object(&mutex->dh, MutexObject, 1); + mutex->dh.size = sizeof(*mutex); + InitializeListHead(&mutex->list); + mutex->abandoned = FALSE; + mutex->apc_disable = 1; + mutex->owner_thread = NULL; + EVENTEXIT(return); +} + +wstdcall LONG WIN_FUNC(KeReleaseMutex,2) + (struct nt_mutex *mutex, BOOLEAN wait) +{ + LONG ret; + struct task_struct *thread; + + EVENTENTER("%p, %d, %p", mutex, wait, current); + if (wait == TRUE) + WARNING("wait: %d", wait); + thread = current; + spin_lock_bh(&dispatcher_lock); + EVENTTRACE("%p, %p, %p, %d", mutex, thread, mutex->owner_thread, + mutex->dh.signal_state); + if ((mutex->owner_thread == thread) && (mutex->dh.signal_state <= 0)) { + ret = mutex->dh.signal_state++; + if (ret == 0) { + mutex->owner_thread = NULL; + object_signalled(&mutex->dh); + } + } else { + ret = STATUS_MUTANT_NOT_OWNED; + WARNING("invalid mutex: %p, %p, %p", mutex, mutex->owner_thread, + thread); + } + EVENTTRACE("%p, %p, %p, %d", mutex, thread, mutex->owner_thread, + mutex->dh.signal_state); + spin_unlock_bh(&dispatcher_lock); + EVENTEXIT(return ret); +} + +wstdcall void WIN_FUNC(KeInitializeSemaphore,3) + (struct nt_semaphore *semaphore, LONG count, LONG limit) +{ + EVENTENTER("%p: %d", semaphore, count); + /* if limit > 1, we need to satisfy as many waits (until count + * becomes 0); so we keep decrementing count everytime a wait + * is satisified */ + initialize_object(&semaphore->dh, SemaphoreObject, count); + semaphore->dh.size = sizeof(*semaphore); + semaphore->limit = limit; + EVENTEXIT(return); +} + +wstdcall LONG WIN_FUNC(KeReleaseSemaphore,4) + (struct nt_semaphore *semaphore, KPRIORITY incr, LONG adjustment, + BOOLEAN wait) +{ + LONG ret; + + EVENTENTER("%p", semaphore); + spin_lock_bh(&dispatcher_lock); + ret = semaphore->dh.signal_state; + assert(ret >= 0); + if (semaphore->dh.signal_state + adjustment <= semaphore->limit) + semaphore->dh.signal_state += adjustment; + else { + WARNING("releasing %d over limit %d", adjustment, + semaphore->limit); + semaphore->dh.signal_state = semaphore->limit; + } + if (semaphore->dh.signal_state > 0) + object_signalled(&semaphore->dh); + spin_unlock_bh(&dispatcher_lock); + EVENTEXIT(return ret); +} + +wstdcall NTSTATUS WIN_FUNC(KeDelayExecutionThread,3) + (KPROCESSOR_MODE wait_mode, BOOLEAN alertable, LARGE_INTEGER *interval) +{ + int res; + long timeout; + + if (wait_mode != 0) + ERROR("invalid wait_mode %d", wait_mode); + + timeout = SYSTEM_TIME_TO_HZ(*interval); + EVENTTRACE("%p, %Ld, %ld", current, *interval, timeout); + if (timeout <= 0) + EVENTEXIT(return STATUS_SUCCESS); + + if (alertable) + set_current_state(TASK_INTERRUPTIBLE); + else + set_current_state(TASK_UNINTERRUPTIBLE); + + res = schedule_timeout(timeout); + EVENTTRACE("%p, %d", current, res); + if (res == 0) + EVENTEXIT(return STATUS_SUCCESS); + else + EVENTEXIT(return STATUS_ALERTED); +} + +wstdcall ULONGLONG WIN_FUNC(KeQueryInterruptTime,0) + (void) +{ + EXIT5(return jiffies * TICKSPERJIFFY); +} + +wstdcall ULONG WIN_FUNC(KeQueryTimeIncrement,0) + (void) +{ + EXIT5(return TICKSPERSEC / HZ); +} + +wstdcall void WIN_FUNC(KeQuerySystemTime,1) + (LARGE_INTEGER *time) +{ + *time = ticks_1601(); + TRACE5("%Lu, %lu", *time, jiffies); +} + +wstdcall void WIN_FUNC(KeQueryTickCount,1) + (LARGE_INTEGER *count) +{ + *count = jiffies; +} + +wstdcall LARGE_INTEGER WIN_FUNC(KeQueryPerformanceCounter,1) + (LARGE_INTEGER *counter) +{ + if (counter) + *counter = HZ; + return jiffies; +} + +wstdcall KAFFINITY WIN_FUNC(KeQueryActiveProcessors,0) + (void) +{ + int i, n; + KAFFINITY bits = 0; +#ifdef num_online_cpus + n = num_online_cpus(); +#else + n = NR_CPUS; +#endif + for (i = 0; i < n; i++) + bits = (bits << 1) | 1; + return bits; +} + +struct nt_thread *get_current_nt_thread(void) +{ + struct task_struct *task = current; + struct nt_thread *thread; + struct common_object_header *header; + + TRACE6("task: %p", task); + thread = NULL; + spin_lock_bh(&ntoskernel_lock); + nt_list_for_each_entry(header, &object_list, list) { + TRACE6("%p, %d", header, header->type); + if (header->type != OBJECT_TYPE_NT_THREAD) + break; + thread = HEADER_TO_OBJECT(header); + TRACE6("%p, %p", thread, thread->task); + if (thread->task == task) + break; + else + thread = NULL; + } + spin_unlock_bh(&ntoskernel_lock); + if (thread == NULL) + TRACE4("couldn't find thread for task %p, %d", task, task->pid); + TRACE6("%p", thread); + return thread; +} + +static struct task_struct *get_nt_thread_task(struct nt_thread *thread) +{ + struct task_struct *task; + struct common_object_header *header; + + TRACE6("%p", thread); + task = NULL; + spin_lock_bh(&ntoskernel_lock); + nt_list_for_each_entry(header, &object_list, list) { + TRACE6("%p, %d", header, header->type); + if (header->type != OBJECT_TYPE_NT_THREAD) + break; + if (thread == HEADER_TO_OBJECT(header)) { + task = thread->task; + break; + } + } + spin_unlock_bh(&ntoskernel_lock); + if (task == NULL) + TRACE2("%p: couldn't find task for %p", current, thread); + return task; +} + +static struct nt_thread *create_nt_thread(struct task_struct *task) +{ + struct nt_thread *thread; + thread = allocate_object(sizeof(*thread), OBJECT_TYPE_NT_THREAD, NULL); + if (!thread) { + ERROR("couldn't allocate thread object"); + EXIT2(return NULL); + } + thread->task = task; + if (task) + thread->pid = task->pid; + else + thread->pid = 0; + nt_spin_lock_init(&thread->lock); + InitializeListHead(&thread->irps); + initialize_object(&thread->dh, ThreadObject, 0); + thread->dh.size = sizeof(*thread); + thread->prio = LOW_PRIORITY; + return thread; +} + +wstdcall struct nt_thread *WIN_FUNC(KeGetCurrentThread,0) + (void) +{ + struct nt_thread *thread = get_current_nt_thread(); + TRACE2("%p, %p", thread, current); + return thread; +} + +wstdcall KPRIORITY WIN_FUNC(KeQueryPriorityThread,1) + (struct nt_thread *thread) +{ + KPRIORITY prio; + struct task_struct *task; + + TRACE2("%p", thread); +#ifdef CONFIG_X86_64 + /* sis163u driver for amd64 passes 0x1f from thread created by + * PsCreateSystemThread - no idea what is 0x1f */ + if (thread == (void *)0x1f) + thread = get_current_nt_thread(); +#endif + if (!thread) { + TRACE2("invalid thread"); + EXIT2(return LOW_REALTIME_PRIORITY); + } + task = get_nt_thread_task(thread); + if (!task) { + TRACE2("couldn't find task for thread: %p", thread); + EXIT2(return LOW_REALTIME_PRIORITY); + } + + prio = thread->prio; + + TRACE2("%d", prio); + return prio; +} + +wstdcall KPRIORITY WIN_FUNC(KeSetPriorityThread,2) + (struct nt_thread *thread, KPRIORITY prio) +{ + KPRIORITY old_prio; + struct task_struct *task; + + TRACE2("thread: %p, priority = %u", thread, prio); +#ifdef CONFIG_X86_64 + if (thread == (void *)0x1f) + thread = get_current_nt_thread(); +#endif + if (!thread) { + TRACE2("invalid thread"); + EXIT2(return LOW_REALTIME_PRIORITY); + } + task = get_nt_thread_task(thread); + if (!task) { + TRACE2("couldn't find task for thread: %p", thread); + EXIT2(return LOW_REALTIME_PRIORITY); + } + + old_prio = thread->prio; + thread->prio = prio; + + TRACE2("%d, %d", old_prio, thread->prio); + return old_prio; +} + +struct thread_trampoline { + void (*func)(void *) wstdcall; + void *ctx; + struct nt_thread *thread; + struct completion started; +}; + +static int ntdriver_thread(void *data) +{ + struct thread_trampoline *thread_tramp = data; + /* yes, a tramp! */ + typeof(thread_tramp->func) func = thread_tramp->func; + typeof(thread_tramp->ctx) ctx = thread_tramp->ctx; + + thread_tramp->thread->task = current; + thread_tramp->thread->pid = current->pid; + TRACE2("thread: %p, task: %p (%d)", thread_tramp->thread, + current, current->pid); + complete(&thread_tramp->started); + +#ifdef PF_NOFREEZE + current->flags |= PF_NOFREEZE; +#endif + strncpy(current->comm, "ntdriver", sizeof(current->comm)); + current->comm[sizeof(current->comm)-1] = 0; + LIN2WIN1(func, ctx); + ERROR("task: %p", current); + return 0; +} + +wstdcall NTSTATUS WIN_FUNC(PsCreateSystemThread,7) + (void **handle, ULONG access, void *obj_attr, void *process, + void *client_id, void (*func)(void *) wstdcall, void *ctx) +{ + struct thread_trampoline thread_tramp; + + ENTER2("handle = %p, access = %u, obj_attr = %p, process = %p, " + "client_id = %p, func = %p, context = %p", handle, access, + obj_attr, process, client_id, func, ctx); + + thread_tramp.thread = create_nt_thread(NULL); + if (!thread_tramp.thread) { + ERROR("couldn't allocate thread object"); + EXIT2(return STATUS_RESOURCES); + } + TRACE2("thread: %p", thread_tramp.thread); + thread_tramp.func = func; + thread_tramp.ctx = ctx; + init_completion(&thread_tramp.started); + + thread_tramp.thread->task = kthread_run(ntdriver_thread, + &thread_tramp, "ntdriver"); + if (IS_ERR(thread_tramp.thread->task)) { + free_object(thread_tramp.thread); + EXIT2(return STATUS_FAILURE); + } + TRACE2("created task: %p", thread_tramp.thread->task); + + wait_for_completion(&thread_tramp.started); + *handle = OBJECT_TO_HEADER(thread_tramp.thread); + TRACE2("created thread: %p, %p", thread_tramp.thread, *handle); + EXIT2(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(PsTerminateSystemThread,1) + (NTSTATUS status) +{ + struct nt_thread *thread; + + TRACE2("%p, %08X", current, status); + thread = get_current_nt_thread(); + TRACE2("%p", thread); + if (thread) { + KeSetEvent((struct nt_event *)&thread->dh, 0, FALSE); + while (1) { + struct nt_list *ent; + struct irp *irp; + KIRQL irql; + irql = nt_spin_lock_irql(&thread->lock, DISPATCH_LEVEL); + ent = RemoveHeadList(&thread->irps); + nt_spin_unlock_irql(&thread->lock, irql); + if (!ent) + break; + irp = container_of(ent, struct irp, thread_list); + IOTRACE("%p", irp); + IoCancelIrp(irp); + } + /* the driver may later query this status with + * ZwQueryInformationThread */ + thread->status = status; + } else + ERROR("couldn't find thread for task: %p", current); + + complete_and_exit(NULL, status); + ERROR("oops: %p, %d", thread->task, thread->pid); + return STATUS_FAILURE; +} + +wstdcall BOOLEAN WIN_FUNC(KeRemoveEntryDeviceQueue,2) + (struct kdevice_queue *dev_queue, struct kdevice_queue_entry *entry) +{ + struct kdevice_queue_entry *e; + KIRQL irql; + + irql = nt_spin_lock_irql(&dev_queue->lock, DISPATCH_LEVEL); + nt_list_for_each_entry(e, &dev_queue->list, list) { + if (e == entry) { + RemoveEntryList(&e->list); + nt_spin_unlock_irql(&dev_queue->lock, irql); + return TRUE; + } + } + nt_spin_unlock_irql(&dev_queue->lock, irql); + return FALSE; +} + +wstdcall BOOLEAN WIN_FUNC(KeSynchronizeExecution,3) + (struct kinterrupt *interrupt, PKSYNCHRONIZE_ROUTINE synch_routine, + void *ctx) +{ + BOOLEAN ret; + unsigned long flags; + + nt_spin_lock_irqsave(interrupt->actual_lock, flags); + ret = LIN2WIN1(synch_routine, ctx); + nt_spin_unlock_irqrestore(interrupt->actual_lock, flags); + TRACE6("%d", ret); + return ret; +} + +wstdcall void *WIN_FUNC(MmAllocateContiguousMemorySpecifyCache,5) + (SIZE_T size, PHYSICAL_ADDRESS lowest, PHYSICAL_ADDRESS highest, + PHYSICAL_ADDRESS boundary, enum memory_caching_type cache_type) +{ + void *addr; + gfp_t flags; + + ENTER2("%lu, 0x%lx, 0x%lx, 0x%lx, %d", size, (long)lowest, + (long)highest, (long)boundary, cache_type); + flags = irql_gfp(); + addr = wrap_get_free_pages(flags, size); + TRACE2("%p, %lu, 0x%x", addr, size, flags); + if (addr && ((virt_to_phys(addr) + size) <= highest)) + EXIT2(return addr); +#ifdef CONFIG_X86_64 + /* GFP_DMA is really only 16MB even on x86-64, but there is no + * other zone available */ + if (highest <= DMA_31BIT_MASK) + flags |= __GFP_DMA; + else if (highest <= DMA_32BIT_MASK) + flags |= __GFP_DMA32; +#else + if (highest <= DMA_24BIT_MASK) + flags |= __GFP_DMA; + else if (highest > DMA_30BIT_MASK) + flags |= __GFP_HIGHMEM; +#endif + addr = wrap_get_free_pages(flags, size); + TRACE2("%p, %lu, 0x%x", addr, size, flags); + return addr; +} + +wstdcall void WIN_FUNC(MmFreeContiguousMemorySpecifyCache,3) + (void *base, SIZE_T size, enum memory_caching_type cache_type) +{ + TRACE2("%p, %lu", base, size); + free_pages((unsigned long)base, get_order(size)); +} + +wstdcall PHYSICAL_ADDRESS WIN_FUNC(MmGetPhysicalAddress,1) + (void *base) +{ + unsigned long phy = virt_to_phys(base); + TRACE2("%p, %p", base, (void *)phy); + return phy; +} + +/* Atheros card with pciid 168C:0014 calls this function with 0xf0000 + * and 0xf6ef0 address, and then check for things that seem to be + * related to ACPI: "_SM_" and "_DMI_". This may be the hack they do + * to check if this card is installed in IBM thinkpads; we can + * probably get this device to work if we create a buffer with the + * strings as required by the driver and return virtual address for + * that address instead */ +wstdcall void __iomem *WIN_FUNC(MmMapIoSpace,3) + (PHYSICAL_ADDRESS phys_addr, SIZE_T size, + enum memory_caching_type cache) +{ + void __iomem *virt; + ENTER1("cache type: %d", cache); + if (cache == MmCached) + virt = ioremap(phys_addr, size); + else + virt = ioremap_nocache(phys_addr, size); + TRACE1("%Lx, %lu, %p", phys_addr, size, virt); + return virt; +} + +wstdcall void WIN_FUNC(MmUnmapIoSpace,2) + (void __iomem *addr, SIZE_T size) +{ + ENTER1("%p, %lu", addr, size); + iounmap(addr); + return; +} + +wstdcall ULONG WIN_FUNC(MmSizeOfMdl,2) + (void *base, ULONG length) +{ + return (sizeof(struct mdl) + + (sizeof(PFN_NUMBER) * SPAN_PAGES(base, length))); +} + +struct mdl *allocate_init_mdl(void *virt, ULONG length) +{ + struct wrap_mdl *wrap_mdl; + struct mdl *mdl; + int mdl_size = MmSizeOfMdl(virt, length); + + if (mdl_size <= MDL_CACHE_SIZE) { + wrap_mdl = kmem_cache_alloc(mdl_cache, irql_gfp()); + if (!wrap_mdl) + return NULL; + spin_lock_bh(&dispatcher_lock); + InsertHeadList(&wrap_mdl_list, &wrap_mdl->list); + spin_unlock_bh(&dispatcher_lock); + mdl = wrap_mdl->mdl; + TRACE3("allocated mdl from cache: %p(%p), %p(%d)", + wrap_mdl, mdl, virt, length); + memset(mdl, 0, MDL_CACHE_SIZE); + MmInitializeMdl(mdl, virt, length); + /* mark the MDL as allocated from cache pool so when + * it is freed, we free it back to the pool */ + mdl->flags = MDL_ALLOCATED_FIXED_SIZE | MDL_CACHE_ALLOCATED; + } else { + wrap_mdl = + kmalloc(sizeof(*wrap_mdl) + mdl_size, irql_gfp()); + if (!wrap_mdl) + return NULL; + mdl = wrap_mdl->mdl; + TRACE3("allocated mdl from memory: %p(%p), %p(%d)", + wrap_mdl, mdl, virt, length); + spin_lock_bh(&dispatcher_lock); + InsertHeadList(&wrap_mdl_list, &wrap_mdl->list); + spin_unlock_bh(&dispatcher_lock); + memset(mdl, 0, mdl_size); + MmInitializeMdl(mdl, virt, length); + mdl->flags = MDL_ALLOCATED_FIXED_SIZE; + } + return mdl; +} + +void free_mdl(struct mdl *mdl) +{ + /* A driver may allocate Mdl with NdisAllocateBuffer and free + * with IoFreeMdl (e.g., 64-bit Broadcom). Since we need to + * treat buffers allocated with Ndis calls differently, we + * must call NdisFreeBuffer if it is allocated with Ndis + * function. We set 'pool' field in Ndis functions. */ + if (!mdl) + return; + if (mdl->pool) + NdisFreeBuffer(mdl); + else { + struct wrap_mdl *wrap_mdl = (struct wrap_mdl *) + ((char *)mdl - offsetof(struct wrap_mdl, mdl)); + spin_lock_bh(&dispatcher_lock); + RemoveEntryList(&wrap_mdl->list); + spin_unlock_bh(&dispatcher_lock); + + if (mdl->flags & MDL_CACHE_ALLOCATED) { + TRACE3("freeing mdl cache: %p, %p, %p", + wrap_mdl, mdl, mdl->mappedsystemva); + kmem_cache_free(mdl_cache, wrap_mdl); + } else { + TRACE3("freeing mdl: %p, %p, %p", + wrap_mdl, mdl, mdl->mappedsystemva); + kfree(wrap_mdl); + } + } + return; +} + +wstdcall void WIN_FUNC(IoBuildPartialMdl,4) + (struct mdl *source, struct mdl *target, void *virt, ULONG length) +{ + MmInitializeMdl(target, virt, length); + target->flags |= MDL_PARTIAL; +} + +wstdcall void WIN_FUNC(MmBuildMdlForNonPagedPool,1) + (struct mdl *mdl) +{ + PFN_NUMBER *mdl_pages; + int i, n; + + ENTER4("%p", mdl); + /* already mapped */ +// mdl->mappedsystemva = MmGetMdlVirtualAddress(mdl); + mdl->flags |= MDL_SOURCE_IS_NONPAGED_POOL; + TRACE4("%p, %p, %p, %d, %d", mdl, mdl->mappedsystemva, mdl->startva, + mdl->byteoffset, mdl->bytecount); + n = SPAN_PAGES(MmGetSystemAddressForMdl(mdl), MmGetMdlByteCount(mdl)); + if (n > MDL_CACHE_PAGES) + WARNING("%p, %d, %d", MmGetSystemAddressForMdl(mdl), + MmGetMdlByteCount(mdl), n); + mdl_pages = MmGetMdlPfnArray(mdl); + for (i = 0; i < n; i++) + mdl_pages[i] = (ULONG_PTR)mdl->startva + (i * PAGE_SIZE); + EXIT4(return); +} + +wstdcall void *WIN_FUNC(MmMapLockedPages,2) + (struct mdl *mdl, KPROCESSOR_MODE access_mode) +{ + /* already mapped */ +// mdl->mappedsystemva = MmGetMdlVirtualAddress(mdl); + mdl->flags |= MDL_MAPPED_TO_SYSTEM_VA; + /* what is the need for MDL_PARTIAL_HAS_BEEN_MAPPED? */ + if (mdl->flags & MDL_PARTIAL) + mdl->flags |= MDL_PARTIAL_HAS_BEEN_MAPPED; + return mdl->mappedsystemva; +} + +wstdcall void *WIN_FUNC(MmMapLockedPagesSpecifyCache,6) + (struct mdl *mdl, KPROCESSOR_MODE access_mode, + enum memory_caching_type cache_type, void *base_address, + ULONG bug_check, enum mm_page_priority priority) +{ + return MmMapLockedPages(mdl, access_mode); +} + +wstdcall void WIN_FUNC(MmUnmapLockedPages,2) + (void *base, struct mdl *mdl) +{ + mdl->flags &= ~MDL_MAPPED_TO_SYSTEM_VA; + return; +} + +wstdcall void WIN_FUNC(MmProbeAndLockPages,3) + (struct mdl *mdl, KPROCESSOR_MODE access_mode, + enum lock_operation operation) +{ + /* already locked */ + mdl->flags |= MDL_PAGES_LOCKED; + return; +} + +wstdcall void WIN_FUNC(MmUnlockPages,1) + (struct mdl *mdl) +{ + mdl->flags &= ~MDL_PAGES_LOCKED; + return; +} + +wstdcall BOOLEAN WIN_FUNC(MmIsAddressValid,1) + (void *virt_addr) +{ + if (virt_addr_valid(virt_addr)) + return TRUE; + else + return FALSE; +} + +wstdcall void *WIN_FUNC(MmLockPagableDataSection,1) + (void *address) +{ + return address; +} + +wstdcall void WIN_FUNC(MmUnlockPagableImageSection,1) + (void *handle) +{ + return; +} + +wstdcall NTSTATUS WIN_FUNC(ObReferenceObjectByHandle,6) + (void *handle, ACCESS_MASK desired_access, void *obj_type, + KPROCESSOR_MODE access_mode, void **object, void *handle_info) +{ + struct common_object_header *hdr; + + TRACE2("%p", handle); + hdr = HANDLE_TO_HEADER(handle); + atomic_inc_var(hdr->ref_count); + *object = HEADER_TO_OBJECT(hdr); + TRACE2("%p, %p, %d, %p", hdr, object, hdr->ref_count, *object); + return STATUS_SUCCESS; +} + +/* DDK doesn't say if return value should be before incrementing or + * after incrementing reference count, but according to #reactos + * devels, it should be return value after incrementing */ +wfastcall LONG WIN_FUNC(ObfReferenceObject,1) + (void *object) +{ + struct common_object_header *hdr; + LONG ret; + + hdr = OBJECT_TO_HEADER(object); + ret = post_atomic_add(hdr->ref_count, 1); + TRACE2("%p, %d, %p", hdr, hdr->ref_count, object); + return ret; +} + +static int dereference_object(void *object) +{ + struct common_object_header *hdr; + int ref_count; + + ENTER2("object: %p", object); + hdr = OBJECT_TO_HEADER(object); + TRACE2("hdr: %p", hdr); + ref_count = post_atomic_add(hdr->ref_count, -1); + TRACE2("object: %p, %d", object, ref_count); + if (ref_count < 0) + ERROR("invalid object: %p (%d)", object, ref_count); + if (ref_count <= 0) { + free_object(object); + return 1; + } else + return 0; +} + +wfastcall void WIN_FUNC(ObfDereferenceObject,1) + (void *object) +{ + TRACE2("%p", object); + dereference_object(object); +} + +wstdcall NTSTATUS WIN_FUNC(ZwCreateFile,11) + (void **handle, ACCESS_MASK access_mask, + struct object_attributes *obj_attr, struct io_status_block *iosb, + LARGE_INTEGER *size, ULONG file_attr, ULONG share_access, + ULONG create_disposition, ULONG create_options, void *ea_buffer, + ULONG ea_length) +{ + struct common_object_header *coh; + struct file_object *fo; + struct ansi_string ansi; + struct wrap_bin_file *bin_file; + char *file_basename; + NTSTATUS status; + + spin_lock_bh(&ntoskernel_lock); + nt_list_for_each_entry(coh, &object_list, list) { + if (coh->type != OBJECT_TYPE_FILE) + continue; + /* TODO: check if file is opened in shared mode */ + if (!RtlCompareUnicodeString(&coh->name, obj_attr->name, TRUE)) { + fo = HEADER_TO_OBJECT(coh); + bin_file = fo->wrap_bin_file; + *handle = coh; + spin_unlock_bh(&ntoskernel_lock); + ObReferenceObject(fo); + iosb->status = FILE_OPENED; + iosb->info = bin_file->size; + EXIT2(return STATUS_SUCCESS); + } + } + spin_unlock_bh(&ntoskernel_lock); + + if (RtlUnicodeStringToAnsiString(&ansi, obj_attr->name, TRUE) != + STATUS_SUCCESS) + EXIT2(return STATUS_INSUFFICIENT_RESOURCES); + + file_basename = strrchr(ansi.buf, '\\'); + if (file_basename) + file_basename++; + else + file_basename = ansi.buf; + TRACE2("file: '%s', '%s'", ansi.buf, file_basename); + + fo = allocate_object(sizeof(struct file_object), OBJECT_TYPE_FILE, + obj_attr->name); + if (!fo) { + RtlFreeAnsiString(&ansi); + iosb->status = STATUS_INSUFFICIENT_RESOURCES; + iosb->info = 0; + EXIT2(return STATUS_FAILURE); + } + coh = OBJECT_TO_HEADER(fo); + bin_file = get_bin_file(file_basename); + if (bin_file) { + TRACE2("%s, %s", bin_file->name, file_basename); + fo->flags = FILE_OPENED; + } else if (access_mask & FILE_WRITE_DATA) { + bin_file = kzalloc(sizeof(*bin_file), GFP_KERNEL); + if (bin_file) { + strncpy(bin_file->name, file_basename, + sizeof(bin_file->name)); + bin_file->name[sizeof(bin_file->name)-1] = 0; + bin_file->data = vmalloc(*size); + if (bin_file->data) { + memset(bin_file->data, 0, *size); + bin_file->size = *size; + fo->flags = FILE_CREATED; + } else { + kfree(bin_file); + bin_file = NULL; + } + } + } else + bin_file = NULL; + + RtlFreeAnsiString(&ansi); + if (!bin_file) { + iosb->status = FILE_DOES_NOT_EXIST; + iosb->info = 0; + free_object(fo); + EXIT2(return STATUS_FAILURE); + } + + fo->wrap_bin_file = bin_file; + fo->current_byte_offset = 0; + if (access_mask & FILE_READ_DATA) + fo->read_access = TRUE; + if (access_mask & FILE_WRITE_DATA) + fo->write_access = TRUE; + iosb->status = FILE_OPENED; + iosb->info = bin_file->size; + *handle = coh; + TRACE2("handle: %p", *handle); + status = STATUS_SUCCESS; + EXIT2(return status); +} + +wstdcall NTSTATUS WIN_FUNC(ZwOpenFile,6) + (void **handle, ACCESS_MASK access_mask, + struct object_attributes *obj_attr, struct io_status_block *iosb, + ULONG share_access, ULONG open_options) +{ + LARGE_INTEGER size; + return ZwCreateFile(handle, access_mask, obj_attr, iosb, &size, 0, + share_access, 0, open_options, NULL, 0); +} + +wstdcall NTSTATUS WIN_FUNC(ZwReadFile,9) + (void *handle, struct nt_event *event, void *apc_routine, + void *apc_context, struct io_status_block *iosb, void *buffer, + ULONG length, LARGE_INTEGER *byte_offset, ULONG *key) +{ + struct file_object *fo; + struct common_object_header *coh; + ULONG count; + size_t offset; + struct wrap_bin_file *file; + + TRACE2("%p", handle); + coh = handle; + if (coh->type != OBJECT_TYPE_FILE) { + ERROR("handle %p is invalid: %d", handle, coh->type); + EXIT2(return STATUS_FAILURE); + } + fo = HANDLE_TO_OBJECT(coh); + file = fo->wrap_bin_file; + TRACE2("file: %s (%zu)", file->name, file->size); + spin_lock_bh(&ntoskernel_lock); + if (byte_offset) + offset = *byte_offset; + else + offset = fo->current_byte_offset; + count = min((size_t)length, file->size - offset); + TRACE2("count: %u, offset: %zu, length: %u", count, offset, length); + memcpy(buffer, ((void *)file->data) + offset, count); + fo->current_byte_offset = offset + count; + spin_unlock_bh(&ntoskernel_lock); + iosb->status = STATUS_SUCCESS; + iosb->info = count; + EXIT2(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(ZwWriteFile,9) + (void *handle, struct nt_event *event, void *apc_routine, + void *apc_context, struct io_status_block *iosb, void *buffer, + ULONG length, LARGE_INTEGER *byte_offset, ULONG *key) +{ + struct file_object *fo; + struct common_object_header *coh; + struct wrap_bin_file *file; + unsigned long offset; + + TRACE2("%p", handle); + coh = handle; + if (coh->type != OBJECT_TYPE_FILE) { + ERROR("handle %p is invalid: %d", handle, coh->type); + EXIT2(return STATUS_FAILURE); + } + fo = HANDLE_TO_OBJECT(coh); + file = fo->wrap_bin_file; + TRACE2("file: %zu, %u", file->size, length); + spin_lock_bh(&ntoskernel_lock); + if (byte_offset) + offset = *byte_offset; + else + offset = fo->current_byte_offset; + if (length + offset > file->size) { + WARNING("%lu, %u", length + offset, (unsigned int)file->size); + /* TODO: implement writing past end of current size */ + iosb->status = STATUS_FAILURE; + iosb->info = 0; + } else { + memcpy(file->data + offset, buffer, length); + iosb->status = STATUS_SUCCESS; + iosb->info = length; + fo->current_byte_offset = offset + length; + } + spin_unlock_bh(&ntoskernel_lock); + EXIT2(return iosb->status); +} + +wstdcall NTSTATUS WIN_FUNC(ZwClose,1) + (void *handle) +{ + struct common_object_header *coh; + + TRACE2("%p", handle); + if (handle == NULL) { + TRACE1(""); + EXIT2(return STATUS_SUCCESS); + } + coh = handle; + if (coh->type == OBJECT_TYPE_FILE) { + struct file_object *fo; + struct wrap_bin_file *bin_file; + typeof(fo->flags) flags; + + fo = HANDLE_TO_OBJECT(handle); + flags = fo->flags; + bin_file = fo->wrap_bin_file; + if (dereference_object(fo)) { + if (flags == FILE_CREATED) { + vfree(bin_file->data); + kfree(bin_file); + } else + free_bin_file(bin_file); + } + } else if (coh->type == OBJECT_TYPE_NT_THREAD) { + struct nt_thread *thread = HANDLE_TO_OBJECT(handle); + TRACE2("thread: %p (%p)", thread, handle); + ObDereferenceObject(thread); + } else { + /* TODO: can we just dereference object here? */ + WARNING("closing handle 0x%x not implemented", coh->type); + } + EXIT2(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(ZwQueryInformationFile,5) + (void *handle, struct io_status_block *iosb, void *info, + ULONG length, enum file_info_class class) +{ + struct file_object *fo; + struct file_name_info *fni; + struct file_std_info *fsi; + struct wrap_bin_file *file; + struct common_object_header *coh; + + ENTER2("%p", handle); + coh = handle; + if (coh->type != OBJECT_TYPE_FILE) { + ERROR("handle %p is invalid: %d", coh, coh->type); + EXIT2(return STATUS_FAILURE); + } + fo = HANDLE_TO_OBJECT(handle); + TRACE2("fo: %p, %d", fo, class); + switch (class) { + case FileNameInformation: + fni = info; + fni->length = min(length, (typeof(length))coh->name.length); + memcpy(fni->name, coh->name.buf, fni->length); + iosb->status = STATUS_SUCCESS; + iosb->info = fni->length; + break; + case FileStandardInformation: + fsi = info; + file = fo->wrap_bin_file; + fsi->alloc_size = file->size; + fsi->eof = file->size; + fsi->num_links = 1; + fsi->delete_pending = FALSE; + fsi->dir = FALSE; + iosb->status = STATUS_SUCCESS; + iosb->info = 0; + break; + default: + WARNING("type %d not implemented yet", class); + iosb->status = STATUS_FAILURE; + iosb->info = 0; + break; + } + EXIT2(return iosb->status); +} + +wstdcall NTSTATUS WIN_FUNC(ZwOpenSection,3) + (void **handle, ACCESS_MASK access, struct object_attributes *obj_attrs) +{ + INFO("%p, 0x%x, %d", obj_attrs, obj_attrs->attributes, access); + TODO(); + *handle = obj_attrs; + return STATUS_SUCCESS; +} + +wstdcall NTSTATUS WIN_FUNC(ZwMapViewOfSection,10) + (void *secn_handle, void *process_handle, void **base_address, + ULONG zero_bits, LARGE_INTEGER *secn_offset, SIZE_T *view_size, + enum section_inherit inherit, ULONG alloc_type, ULONG protect) +{ + INFO("%p, %p, %p", secn_handle, process_handle, base_address); + TODO(); + *base_address = (void *)0xdeadbeef; + return STATUS_SUCCESS; +} + +wstdcall NTSTATUS WIN_FUNC(ZwUnmapViewOfSection,2) + (void *process_handle, void *base_address) +{ + INFO("%p, %p", process_handle, base_address); + TODO(); + return STATUS_SUCCESS; +} + +wstdcall NTSTATUS WIN_FUNC(ZwCreateKey,7) + (void **handle, ACCESS_MASK desired_access, + struct object_attributes *attr, ULONG title_index, + struct unicode_string *class, ULONG create_options, + ULONG *disposition) +{ + struct ansi_string ansi; + if (RtlUnicodeStringToAnsiString(&ansi, attr->name, TRUE) == + STATUS_SUCCESS) { + TRACE1("key: %s", ansi.buf); + RtlFreeAnsiString(&ansi); + } + *handle = NULL; + return STATUS_SUCCESS; +} + +wstdcall NTSTATUS WIN_FUNC(ZwOpenKey,3) + (void **handle, ACCESS_MASK desired_access, + struct object_attributes *attr) +{ + struct ansi_string ansi; + if (RtlUnicodeStringToAnsiString(&ansi, attr->name, TRUE) == + STATUS_SUCCESS) { + TRACE1("key: %s", ansi.buf); + RtlFreeAnsiString(&ansi); + } + *handle = NULL; + return STATUS_SUCCESS; +} + +wstdcall NTSTATUS WIN_FUNC(ZwSetValueKey,6) + (void *handle, struct unicode_string *name, ULONG title_index, + ULONG type, void *data, ULONG data_size) +{ + struct ansi_string ansi; + if (RtlUnicodeStringToAnsiString(&ansi, name, TRUE) == + STATUS_SUCCESS) { + TRACE1("key: %s", ansi.buf); + RtlFreeAnsiString(&ansi); + } + return STATUS_SUCCESS; +} + +wstdcall NTSTATUS WIN_FUNC(ZwQueryValueKey,6) + (void *handle, struct unicode_string *name, + enum key_value_information_class class, void *info, + ULONG length, ULONG *res_length) +{ + struct ansi_string ansi; + if (RtlUnicodeStringToAnsiString(&ansi, name, TRUE) == STATUS_SUCCESS) { + TRACE1("key: %s", ansi.buf); + RtlFreeAnsiString(&ansi); + } + TODO(); + return STATUS_INVALID_PARAMETER; +} + +wstdcall NTSTATUS WIN_FUNC(ZwDeleteKey,1) + (void *handle) +{ + ENTER2("%p", handle); + return STATUS_SUCCESS; +} + +wstdcall NTSTATUS WIN_FUNC(ZwPowerInformation,4) + (INT info_level, void *in_buf, ULONG in_buf_len, void *out_buf, + ULONG out_buf_len) +{ + INFO("%d, %u, %u", info_level, in_buf_len, out_buf_len); + TODO(); + return STATUS_ACCESS_DENIED; +} + +wstdcall NTSTATUS WIN_FUNC(WmiSystemControl,4) + (struct wmilib_context *info, struct device_object *dev_obj, + struct irp *irp, void *irp_disposition) +{ + TODO(); + return STATUS_SUCCESS; +} + +wstdcall NTSTATUS WIN_FUNC(WmiCompleteRequest,5) + (struct device_object *dev_obj, struct irp *irp, NTSTATUS status, + ULONG buffer_used, CCHAR priority_boost) +{ + TODO(); + return STATUS_SUCCESS; +} + +noregparm NTSTATUS WIN_FUNC(WmiTraceMessage,12) + (void *tracehandle, ULONG message_flags, + void *message_guid, USHORT message_no, ...) +{ + TODO(); + EXIT2(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(WmiQueryTraceInformation,4) + (enum trace_information_class trace_info_class, void *trace_info, + ULONG *req_length, void *buf) +{ + TODO(); + EXIT2(return STATUS_SUCCESS); +} + +/* this function can't be wstdcall as it takes variable number of args */ +noregparm ULONG WIN_FUNC(DbgPrint,12) + (char *format, ...) +{ +#ifdef DEBUG + va_list args; + static char buf[100]; + + va_start(args, format); + vsnprintf(buf, sizeof(buf), format, args); + printk(KERN_DEBUG "%s (%s): %s", DRIVER_NAME, __FUNCTION__, buf); + va_end(args); +#endif + return STATUS_SUCCESS; +} + +wstdcall void WIN_FUNC(KeBugCheckEx,5) + (ULONG code, ULONG_PTR param1, ULONG_PTR param2, + ULONG_PTR param3, ULONG_PTR param4) +{ + TODO(); + return; +} + +wstdcall void WIN_FUNC(ExSystemTimeToLocalTime,2) + (LARGE_INTEGER *system_time, LARGE_INTEGER *local_time) +{ + *local_time = *system_time; +} + +wstdcall ULONG WIN_FUNC(ExSetTimerResolution,2) + (ULONG time, BOOLEAN set) +{ + /* why a driver should change system wide timer resolution is + * beyond me */ + return time; +} + +wstdcall void WIN_FUNC(DbgBreakPoint,0) + (void) +{ + TODO(); +} + +wstdcall void WIN_FUNC(_except_handler3,0) + (void) +{ + TODO(); +} + +wstdcall void WIN_FUNC(__C_specific_handler,0) + (void) +{ + TODO(); +} + +wstdcall void WIN_FUNC(_purecall,0) + (void) +{ + TODO(); +} + +wstdcall void WIN_FUNC(__chkstk,0) + (void) +{ + TODO(); +} + +struct worker_init_struct { + work_struct_t work; + struct completion completion; + struct nt_thread *nt_thread; +}; + +static void wrap_worker_init_func(worker_param_t param) +{ + struct worker_init_struct *worker_init_struct; + + worker_init_struct = + worker_param_data(param, struct worker_init_struct, work); + TRACE1("%p", worker_init_struct); + worker_init_struct->nt_thread = create_nt_thread(current); + if (!worker_init_struct->nt_thread) + WARNING("couldn't create worker thread"); + complete(&worker_init_struct->completion); +} + +struct nt_thread *wrap_worker_init(workqueue_struct_t *wq) +{ + struct worker_init_struct worker_init_struct; + + TRACE1("%p", &worker_init_struct); + init_completion(&worker_init_struct.completion); + initialize_work(&worker_init_struct.work, wrap_worker_init_func, + &worker_init_struct); + worker_init_struct.nt_thread = NULL; + if (wq) + queue_work(wq, &worker_init_struct.work); + else + schedule_work(&worker_init_struct.work); + wait_for_completion(&worker_init_struct.completion); + TRACE1("%p", worker_init_struct.nt_thread); + return worker_init_struct.nt_thread; +} + +int ntoskernel_init(void) +{ + struct timeval now; + + spin_lock_init(&dispatcher_lock); + spin_lock_init(&ntoskernel_lock); + spin_lock_init(&ntos_work_lock); + spin_lock_init(&kdpc_list_lock); + spin_lock_init(&irp_cancel_lock); + InitializeListHead(&wrap_mdl_list); + InitializeListHead(&kdpc_list); + InitializeListHead(&callback_objects); + InitializeListHead(&bus_driver_list); + InitializeListHead(&object_list); + InitializeListHead(&ntos_work_list); + + nt_spin_lock_init(&nt_list_lock); + + initialize_work(&kdpc_work, kdpc_worker, NULL); + initialize_work(&ntos_work, ntos_work_worker, NULL); + wrap_timer_slist.next = NULL; + + do_gettimeofday(&now); + wrap_ticks_to_boot = TICKS_1601_TO_1970; + wrap_ticks_to_boot += (u64)now.tv_sec * TICKSPERSEC; + wrap_ticks_to_boot += now.tv_usec * 10; + wrap_ticks_to_boot -= jiffies * TICKSPERJIFFY; + TRACE2("%Lu", wrap_ticks_to_boot); + +#ifdef WRAP_PREEMPT + do { + int cpu; + for_each_possible_cpu(cpu) { + irql_info_t *info; + info = &per_cpu(irql_info, cpu); + mutex_init(&(info->lock)); + info->task = NULL; + info->count = 0; + } + } while (0); +#endif + + ntos_wq = create_singlethread_workqueue("ntos_wq"); + if (!ntos_wq) { + WARNING("couldn't create ntos_wq thread"); + return -ENOMEM; + } + ntos_worker_thread = wrap_worker_init(ntos_wq); + TRACE1("%p", ntos_worker_thread); + + if (add_bus_driver("PCI") +#ifdef ENABLE_USB + || add_bus_driver("USB") +#endif + ) { + ntoskernel_exit(); + return -ENOMEM; + } + mdl_cache = + wrap_kmem_cache_create("wrap_mdl", + sizeof(struct wrap_mdl) + MDL_CACHE_SIZE, + 0, 0); + TRACE2("%p", mdl_cache); + if (!mdl_cache) { + ERROR("couldn't allocate MDL cache"); + ntoskernel_exit(); + return -ENOMEM; + } + +#if defined(CONFIG_X86_64) + memset(&kuser_shared_data, 0, sizeof(kuser_shared_data)); + *((ULONG64 *)&kuser_shared_data.system_time) = ticks_1601(); + init_timer(&shared_data_timer); + shared_data_timer.function = update_user_shared_data_proc; + shared_data_timer.data = (unsigned long)0; +#endif + return 0; +} + +int ntoskernel_init_device(struct wrap_device *wd) +{ +#if defined(CONFIG_X86_64) + if (kuser_shared_data.reserved1) + mod_timer(&shared_data_timer, jiffies + MSEC_TO_HZ(30)); +#endif + return 0; +} + +void ntoskernel_exit_device(struct wrap_device *wd) +{ + ENTER2(""); + + KeFlushQueuedDpcs(); + EXIT2(return); +} + +void ntoskernel_exit(void) +{ + struct nt_list *cur; + + ENTER2(""); + + /* free kernel (Ke) timers */ + TRACE2("freeing timers"); + while (1) { + struct wrap_timer *wrap_timer; + struct nt_slist *slist; + + spin_lock_bh(&ntoskernel_lock); + if ((slist = wrap_timer_slist.next)) + wrap_timer_slist.next = slist->next; + spin_unlock_bh(&ntoskernel_lock); + TIMERTRACE("%p", slist); + if (!slist) + break; + wrap_timer = container_of(slist, struct wrap_timer, slist); + if (del_timer_sync(&wrap_timer->timer)) + WARNING("Buggy Windows driver left timer %p running", + wrap_timer->nt_timer); + memset(wrap_timer, 0, sizeof(*wrap_timer)); + slack_kfree(wrap_timer); + } + + TRACE2("freeing MDLs"); + if (mdl_cache) { + spin_lock_bh(&ntoskernel_lock); + if (!IsListEmpty(&wrap_mdl_list)) + ERROR("Windows driver didn't free all MDLs; " + "freeing them now"); + while ((cur = RemoveHeadList(&wrap_mdl_list))) { + struct wrap_mdl *wrap_mdl; + wrap_mdl = container_of(cur, struct wrap_mdl, list); + if (wrap_mdl->mdl->flags & MDL_CACHE_ALLOCATED) + kmem_cache_free(mdl_cache, wrap_mdl); + else + kfree(wrap_mdl); + } + spin_unlock_bh(&ntoskernel_lock); + kmem_cache_destroy(mdl_cache); + mdl_cache = NULL; + } + + TRACE2("freeing callbacks"); + spin_lock_bh(&ntoskernel_lock); + while ((cur = RemoveHeadList(&callback_objects))) { + struct callback_object *object; + struct nt_list *ent; + object = container_of(cur, struct callback_object, list); + while ((ent = RemoveHeadList(&object->callback_funcs))) { + struct callback_func *f; + f = container_of(ent, struct callback_func, list); + kfree(f); + } + kfree(object); + } + spin_unlock_bh(&ntoskernel_lock); + + spin_lock_bh(&ntoskernel_lock); + while ((cur = RemoveHeadList(&bus_driver_list))) { + struct bus_driver *bus_driver; + bus_driver = container_of(cur, struct bus_driver, list); + /* TODO: make sure all all drivers are shutdown/removed */ + kfree(bus_driver); + } + spin_unlock_bh(&ntoskernel_lock); + +#if defined(CONFIG_X86_64) + del_timer_sync(&shared_data_timer); +#endif + if (ntos_wq) + destroy_workqueue(ntos_wq); + TRACE1("%p", ntos_worker_thread); + if (ntos_worker_thread) + ObDereferenceObject(ntos_worker_thread); + ENTER2("freeing objects"); + spin_lock_bh(&ntoskernel_lock); + while ((cur = RemoveHeadList(&object_list))) { + struct common_object_header *hdr; + hdr = container_of(cur, struct common_object_header, list); + if (hdr->type == OBJECT_TYPE_NT_THREAD) + TRACE1("object %p(%d) was not freed, freeing it now", + HEADER_TO_OBJECT(hdr), hdr->type); + else + WARNING("object %p(%d) was not freed, freeing it now", + HEADER_TO_OBJECT(hdr), hdr->type); + ExFreePool(hdr); + } + spin_unlock_bh(&ntoskernel_lock); + + EXIT2(return); +} --- linux-2.6.28.orig/ubuntu/ndiswrapper/win2lin_stubs.S +++ linux-2.6.28/ubuntu/ndiswrapper/win2lin_stubs.S @@ -0,0 +1,288 @@ +/* + * Copyright (C) 2005 Karl Vogel, Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#include + +#ifdef CONFIG_X86_64 + +/* +# Windows <---> Linux register usage conversion when calling functions +# V = Volatile +# NV = Non Volatile (needs to be saved) +# +# Win Lin +# --------------------------------------- +# Rax Return V Return V +# Rbx NV NV +# Rcx Arg1 V Arg4 V +# Rdx Arg2 V Arg3 V +# Rsi NV Arg2 V +# Rdi NV Arg1 V +# Rsp NV NV +# Rbp NV NV +# R8 Arg3 V Arg5 V +# R9 Arg4 V Arg6 V +# R10 V V +# R11 V V +# R12 NV NV +# R13 NV NV +# R14 NV NV +# R15 NV NV +# +# In addition, Linux uses %rax to indicate number of SSE registers used +# when variadic functions are called. Since there is no way to obtain this +# from Windows, for now, we just assume this is 0 (hence %rax is cleared). +# +# Windows pushes arguments 5 and higher onto stack in case of integer +# variables and 4 and higher in case of floating point variabes (passed +# in SSE registers). + +In a windows function, the stackframe/registers look like this: + +# 0x0048 .... +# 0x0040 arg8 +# 0x0038 arg7 +# 0x0030 arg6 +# 0x0028 arg5 +# 0x0020 shadow/spill space for arg4 +# 0x0018 shadow/spill space for arg3 +# 0x0010 shadow/spill space for arg2 +# 0x0008 shadow/spill space for arg1 +# 0x0000 ret + +# register spill space is same irrespective of number of arguments - even +# if Windows function takes less than 4 arguments, 32 bytes above return +# address is reserved for the function + +In Linux it should look like: + +# 0x0018 .... +# 0x0010 arg8 +# 0x0008 arg7 +# 0x0000 ret + +*/ + +# +# setup for Windows to Linux function call +# + + .text + +.macro win2lin_prolog + push %rsi + push %rdi +.endm + +.macro win2lin_epilog + pop %rdi + pop %rsi +.endm + +# when Windows function calls Linux function, the function address is in %r10 + +.macro call_lin_func + xor %rax, %rax # rax indicates number of SSE regs + call *%r10 +.endm + +# before prolog, 0(%rsp) is return address, 8(%rsp) would be arg1 +# (but it is in register) and so on, so n'th arg would be at n*8(%rsp) +# for n > 4. But in prolog, we push 2 registers that are non-volaile in +# Windows, but volatile in Linux. So after prolog, args are at (n+2)*8(%rsp) + +#define win2lin_win_arg(n) (n+2)*8(%rsp) + +#define win2lin_arg1 mov %rcx, %rdi +#define win2lin_arg2 mov %rdx, %rsi +#define win2lin_arg3 mov %r8, %rdx +#define win2lin_arg4 mov %r9, %rcx +#define win2lin_arg5 mov win2lin_win_arg(5), %r8 +#define win2lin_arg6 mov win2lin_win_arg(6), %r9 + + .type win2lin0, @function +win2lin0: + win2lin_prolog + call_lin_func + win2lin_epilog + ret + .size win2lin0, .-win2lin0 + + .type win2lin1, @function +win2lin1: + win2lin_prolog + win2lin_arg1 + call_lin_func + win2lin_epilog + ret + .size win2lin1, .-win2lin1 + + .type win2lin2, @function +win2lin2: + win2lin_prolog + win2lin_arg1 + win2lin_arg2 + call_lin_func + win2lin_epilog + ret + .size win2lin2, .-win2lin2 + + .type win2lin3, @function +win2lin3: + win2lin_prolog + win2lin_arg1 + win2lin_arg2 + win2lin_arg3 + call_lin_func + win2lin_epilog + ret + .size win2lin3, .-win2lin3 + + .type win2lin4, @function +win2lin4: + win2lin_prolog + win2lin_arg1 + win2lin_arg2 + win2lin_arg3 + win2lin_arg4 + call_lin_func + win2lin_epilog + ret + .size win2lin4, .-win2lin4 + + .type win2lin5, @function +win2lin5: + win2lin_prolog + win2lin_arg1 + win2lin_arg2 + win2lin_arg3 + win2lin_arg4 + win2lin_arg5 + call_lin_func + win2lin_epilog + ret + .size win2lin5, .-win2lin5 + + .type win2lin6, @function +win2lin6: + win2lin_prolog + win2lin_arg1 + win2lin_arg2 + win2lin_arg3 + win2lin_arg4 + win2lin_arg5 + win2lin_arg6 + call_lin_func + win2lin_epilog + ret + .size win2lin6, .-win2lin6 + +# Allocate stack frame for Linux arguments before calling function. +# First 6 args are passed through registers, so we need space for 7 and above. +# The arguments should have been copied onto stack already. + +.macro call_lin_func_args n + sub $(\n-6)*8, %rsp + call_lin_func + add $(\n-6)*8, %rsp + .endm + +# m is index of Linux arg required, n is total number of args to function +# After stack frame is allocated, Linux arg 7 should be at 0(%rsp), +# arg 8 should be at 1*8(%rsp) and so on. So Linux arg m should be at (m-7)*8 +# Stack frame starts at -(n-6)*8(%rsp), so before stack frame is allocated +# Linux arg m should be at (6-n+m-7)*8(%rsp) + +#define win2lin_lin_arg(m,n) (m-1-n)*8(%rsp) + + .type win2lin7, @function +win2lin7: + win2lin_prolog + + win2lin_arg1 + win2lin_arg2 + win2lin_arg3 + win2lin_arg4 + win2lin_arg5 + win2lin_arg6 + + # copy windows argument 7 onto stack for Linux function + mov win2lin_win_arg(7), %r11 + mov %r11, win2lin_lin_arg(7,7) + + call_lin_func_args(7) + win2lin_epilog + ret + .size win2lin7, .-win2lin7 + + .type win2lin8, @function +win2lin8: + win2lin_prolog + + win2lin_arg1 + win2lin_arg2 + win2lin_arg3 + win2lin_arg4 + win2lin_arg5 + win2lin_arg6 + + # copy windows arguments 7 and 8 onto stack for Linux function + mov win2lin_win_arg(7), %r11 + mov %r11, win2lin_lin_arg(7,8) + mov win2lin_win_arg(8), %r11 + mov %r11, win2lin_lin_arg(8,8) + + call_lin_func_args(8) + win2lin_epilog + ret + .size win2lin8, .-win2lin8 + + .type win2lin9, @function +win2lin9: +win2lin10: +win2lin11: +win2lin12: + win2lin_prolog + + # since we destroy rsi and rdi here, first copy windows + # arguments 7 through 12 onto stack for Linux function + mov %rcx, %r11 # save rcx + lea win2lin_win_arg(7), %rsi # source (windows arg 7 and up) + lea win2lin_lin_arg(7,12), %rdi # = destination + mov $6, %rcx # 6 arguments + rep + movsq + mov %r11, %rcx # restore rcx + + win2lin_arg1 + win2lin_arg2 + win2lin_arg3 + win2lin_arg4 + win2lin_arg5 + win2lin_arg6 + + call_lin_func_args(12) + win2lin_epilog + ret + .size win2lin9, .-win2lin9 + +#define win2lin(name, argc) \ +ENTRY(win2lin_ ## name ## _ ## argc) \ + lea name(%rip), %r10 ; \ + jmp win2lin ## argc + +#include "win2lin_stubs.h" + +#endif // CONFIG_X86_64 --- linux-2.6.28.orig/ubuntu/ndiswrapper/ndis.h +++ linux-2.6.28/ubuntu/ndiswrapper/ndis.h @@ -0,0 +1,1309 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#ifndef _NDIS_H_ +#define _NDIS_H_ + +#include "ntoskernel.h" + +//#define ALLOW_POOL_OVERFLOW 1 + +#define NDIS_DMA_24BITS 0 +#define NDIS_DMA_32BITS 1 +#define NDIS_DMA_64BITS 2 + +#ifdef CONFIG_X86_64 +#define MAXIMUM_PROCESSORS 64 +#else +#define MAXIMUM_PROCESSORS 32 +#endif + +typedef UINT NDIS_STATUS; +typedef UCHAR NDIS_DMA_SIZE; +typedef LONG ndis_rssi; +typedef ULONG ndis_key_index; +typedef ULONG ndis_tx_power_level; +typedef ULONGULONG ndis_key_rsc; +typedef UCHAR ndis_rates[NDIS_MAX_RATES]; +typedef UCHAR ndis_rates_ex[NDIS_MAX_RATES_EX]; +typedef UCHAR mac_address[ETH_ALEN]; +typedef ULONG ndis_fragmentation_threshold; +typedef ULONG ndis_rts_threshold; +typedef ULONG ndis_antenna; +typedef ULONG ndis_oid; + +typedef UCHAR ndis_pmkid_vavlue[16]; + +typedef uint64_t NDIS_PHY_ADDRESS; + +struct ndis_sg_element { + PHYSICAL_ADDRESS address; + ULONG length; + ULONG_PTR reserved; +}; + +struct ndis_sg_list { + ULONG nent; + ULONG_PTR reserved; + struct ndis_sg_element elements[]; +}; + +/* when sending packets, ndiswrapper associates exactly one sg element + * in sg list */ +struct wrap_tx_sg_list { + ULONG nent; + ULONG_PTR reserved; + struct ndis_sg_element elements[1]; +}; + +struct ndis_phy_addr_unit { + NDIS_PHY_ADDRESS phy_addr; + UINT length; +}; + +typedef struct mdl ndis_buffer; + +struct ndis_buffer_pool { + ndis_buffer *free_descr; +// NT_SPIN_LOCK lock; + spinlock_t lock; + UINT max_descr; + UINT num_allocated_descr; +}; + +#define NDIS_PROTOCOL_ID_DEFAULT 0x00 +#define NDIS_PROTOCOL_ID_TCP_IP 0x02 +#define NDIS_PROTOCOL_ID_IPX 0x06 +#define NDIS_PROTOCOL_ID_NBF 0x07 +#define NDIS_PROTOCOL_ID_MAX 0x0F +#define NDIS_PROTOCOL_ID_MASK 0x0F + +#define fPACKET_WRAPPER_RESERVED 0x3F +#define fPACKET_CONTAINS_MEDIA_SPECIFIC_INFO 0x40 +#define fPACKET_ALLOCATED_BY_NDIS 0x80 + +#define PROTOCOL_RESERVED_SIZE_IN_PACKET (4 * sizeof(void *)) + +struct transport_header_offset { + USHORT protocol_type; + USHORT header_offset; +}; + +struct ndis_network_address { + USHORT length; + USHORT type; + UCHAR address[1]; +}; + +struct ndis_network_address_list { + LONG count; + USHORT type; + struct ndis_network_address address[1]; +}; + +struct ndis_tcp_ip_checksum_packet_info { + union { + struct { + ULONG v4:1; + ULONG v6:1; + ULONG tcp:1; + ULONG udp:1; + ULONG ip:1; + } tx; + struct { + ULONG tcp_failed:1; + ULONG udp_failed:1; + ULONG ip_failed:1; + ULONG tcp_succeeded:1; + ULONG udp_succeeded:1; + ULONG ip_succeeded:1; + ULONG loopback:1; + } rx; + ULONG value; + }; +}; + +enum ndis_task { + TcpIpChecksumNdisTask, IpSecNdisTask, TcpLargeSendNdisTask, MaxNdisTask +}; + +enum ndis_encapsulation { + UNSPECIFIED_Encapsulation, NULL_Encapsulation, + IEEE_802_3_Encapsulation, IEEE_802_5_Encapsulation, + LLC_SNAP_ROUTED_Encapsulation, LLC_SNAP_BRIDGED_Encapsulation +}; + +#define NDIS_TASK_OFFLOAD_VERSION 1 + +struct ndis_encapsulation_format { + enum ndis_encapsulation encap; + struct { + ULONG fixed_header_size:1; + ULONG reserved:31; + } flags; + ULONG header_size; +}; + +struct ndis_task_offload_header { + ULONG version; + ULONG size; + ULONG reserved; + ULONG offset_first_task; + struct ndis_encapsulation_format encap_format; +}; + +struct ndis_task_offload { + ULONG version; + ULONG size; + enum ndis_task task; + ULONG offset_next_task; + ULONG task_buf_length; + UCHAR task_buf[1]; +}; + +struct v4_checksum { + union { + struct { + ULONG ip_opts:1; + ULONG tcp_opts:1; + ULONG tcp_csum:1; + ULONG udp_csum:1; + ULONG ip_csum:1; + }; + ULONG value; + }; +}; + +struct v6_checksum { + ULONG ip_supported:1; + ULONG tcp_supported:1; + ULONG tcp_csum:1; + ULONG udp_csum:1; +}; + +struct ndis_task_tcp_ip_checksum { + struct v4_checksum v4_tx; + struct v4_checksum v4_rx; + struct v6_checksum v6_tx; + struct v6_checksum v6_rx; +}; + +struct ndis_task_tcp_large_send { + ULONG version; + ULONG max_size; + ULONG min_seg_count; + BOOLEAN tcp_opts; + BOOLEAN ip_opts; +}; + +struct ndis_packet; + +struct ndis_packet_pool { + struct ndis_packet *free_descr; +// NT_SPIN_LOCK lock; + spinlock_t lock; + UINT max_descr; + UINT num_allocated_descr; + UINT num_used_descr; + UINT proto_rsvd_length; +}; + +struct ndis_packet_stack { + ULONG_PTR IM_reserved[2]; + ULONG_PTR ndis_reserved[4]; +}; + +enum ndis_per_packet_info { + TcpIpChecksumPacketInfo, IpSecPacketInfo, TcpLargeSendPacketInfo, + ClassificationHandlePacketInfo, NdisReserved, + ScatterGatherListPacketInfo, Ieee8021QInfo, OriginalPacketInfo, + PacketCancelId, MaxPerPacketInfo +}; + +struct ndis_packet_extension { + void *info[MaxPerPacketInfo]; +}; + +struct ndis_packet_private { + UINT nr_pages; + UINT len; + ndis_buffer *buffer_head; + ndis_buffer *buffer_tail; + struct ndis_packet_pool *pool; + UINT count; + ULONG flags; + BOOLEAN valid_counts; + UCHAR packet_flags; + USHORT oob_offset; +}; + +struct ndis_packet { + struct ndis_packet_private private; + /* for use by miniport */ + union { + /* for connectionless mininports */ + struct { + UCHAR miniport_reserved[2 * sizeof(void *)]; + UCHAR wrapper_reserved[2 * sizeof(void *)]; + } cl_reserved; + /* for deserialized miniports */ + struct { + UCHAR miniport_reserved_ex[3 * sizeof(void *)]; + UCHAR wrapper_reserved_ex[sizeof(void *)]; + } deserailized_reserved; + struct { + UCHAR mac_reserved[4 * sizeof(void *)]; + } mac_reserved; + }; + ULONG_PTR reserved[2]; + UCHAR protocol_reserved[1]; +}; + +/* OOB data */ +struct ndis_packet_oob_data { + union { + ULONGLONG time_to_tx; + ULONGLONG time_txed; + }; + ULONGLONG time_rxed; + UINT header_size; + UINT media_size; + void *media; + NDIS_STATUS status; + + /* ndiswrapper specific info; extension should be right after + * ndis's oob_data */ + struct ndis_packet_extension ext; + union { + /* used for tx only */ + struct { + struct sk_buff *tx_skb; + union { + struct wrap_tx_sg_list wrap_tx_sg_list; + struct ndis_sg_list *tx_sg_list; + }; + }; + /* used for rx only */ + struct { + unsigned char header[ETH_HLEN]; + unsigned char *look_ahead; + UINT look_ahead_size; + }; + }; +}; + +#define NDIS_PACKET_OOB_DATA(packet) \ + (struct ndis_packet_oob_data *)(((void *)(packet)) + \ + (packet)->private.oob_offset) + +enum ndis_device_pnp_event { + NdisDevicePnPEventQueryRemoved, NdisDevicePnPEventRemoved, + NdisDevicePnPEventSurpriseRemoved, NdisDevicePnPEventQueryStopped, + NdisDevicePnPEventStopped, NdisDevicePnPEventPowerProfileChanged, + NdisDevicePnPEventMaximum +}; + +enum ndis_request_type { + NdisRequestQueryInformation, NdisRequestSetInformation, + NdisRequestQueryStatistics, NdisRequestOpen, NdisRequestClose, + NdisRequestSend, NdisRequestTransferData, NdisRequestReset, + NdisRequestGeneric1, NdisRequestGeneric2, NdisRequestGeneric3, + NdisRequestGeneric4 +}; + +struct ndis_request { + mac_address mac; + enum ndis_request_type request_type; + union data { + struct query_info { + UINT oid; + void *buf; + UINT buf_len; + UINT written; + UINT needed; + } query_info; + struct set_info { + UINT oid; + void *buf; + UINT buf_len; + UINT written; + UINT needed; + } set_info; + } data; +}; + +enum ndis_medium { + NdisMedium802_3, NdisMedium802_5, NdisMediumFddi, NdisMediumWan, + NdisMediumLocalTalk, NdisMediumDix, NdisMediumArcnetRaw, + NdisMediumArcnet878_2, NdisMediumAtm, NdisMediumWirelessWan, + NdisMediumIrda, NdisMediumBpc, NdisMediumCoWan, + NdisMedium1394, NdisMediumMax +}; + +enum ndis_physical_medium { + NdisPhysicalMediumUnspecified, NdisPhysicalMediumWirelessLan, + NdisPhysicalMediumCableModem, NdisPhysicalMediumPhoneLine, + NdisPhysicalMediumPowerLine, NdisPhysicalMediumDSL, + NdisPhysicalMediumFibreChannel, NdisPhysicalMedium1394, + NdisPhysicalMediumWirelessWan, NdisPhysicalMediumMax +}; + +enum ndis_power_state { + NdisDeviceStateUnspecified = 0, + NdisDeviceStateD0, NdisDeviceStateD1, NdisDeviceStateD2, + NdisDeviceStateD3, NdisDeviceStateMaximum +}; + +enum ndis_power_profile { + NdisPowerProfileBattery, NdisPowerProfileAcOnLine +}; + +struct ndis_pm_wakeup_capabilities { + enum ndis_power_state min_magic_packet_wakeup; + enum ndis_power_state min_pattern_wakeup; + enum ndis_power_state min_link_change_wakeup; +}; + +#define NDIS_PNP_WAKE_UP_MAGIC_PACKET 0x00000001 +#define NDIS_PNP_WAKE_UP_PATTERN_MATCH 0x00000002 +#define NDIS_PNP_WAKE_UP_LINK_CHANGE 0x00000004 + +enum net_pnp_event_code { + NetEventSetPower, NetEventQueryPower, NetEventQueryRemoveDevice, + NetEventCancelRemoveDevice, NetEventReconfigure, NetEventBindList, + NetEventBindsComplete, NetEventPnPCapabilities, NetEventMaximum +}; + +struct net_pnp_event { + enum net_pnp_event_code code; + void *buf; + ULONG buf_length; + ULONG_PTR ndis_reserved[4]; + ULONG_PTR transport_reserved[4]; + ULONG_PTR tdi_reserved[4]; + ULONG_PTR tdi_client_reserved[4]; +}; + +struct ndis_pnp_capabilities { + ULONG flags; + struct ndis_pm_wakeup_capabilities wakeup; +}; + +typedef void (*ndis_isr_handler)(BOOLEAN *recognized, BOOLEAN *queue_handler, + void *handle) wstdcall; +typedef void (*ndis_interrupt_handler)(void *ctx) wstdcall; + +struct miniport { + /* NDIS 3.0 */ + UCHAR major_version; + UCHAR minor_version; + USHORT filler; + UINT reserved; + BOOLEAN (*hangcheck)(void *ctx) wstdcall; + void (*disable_interrupt)(void *ctx) wstdcall; + void (*enable_interrupt)(void *ctx) wstdcall; + void (*mp_halt)(void *ctx) wstdcall; + ndis_interrupt_handler handle_interrupt; + NDIS_STATUS (*init)(NDIS_STATUS *error_status, UINT *medium_index, + enum ndis_medium medium[], UINT medium_array_size, + void *handle, void *conf_handle) wstdcall; + ndis_isr_handler isr; + NDIS_STATUS (*queryinfo)(void *ctx, ndis_oid oid, void *buffer, + ULONG buflen, ULONG *written, + ULONG *needed) wstdcall; + void *reconfig; + NDIS_STATUS (*reset)(BOOLEAN *reset_address, void *ctx) wstdcall; + NDIS_STATUS (*send)(void *ctx, struct ndis_packet *packet, + UINT flags) wstdcall; + NDIS_STATUS (*setinfo)(void *ctx, ndis_oid oid, void *buffer, + ULONG buflen, ULONG *written, + ULONG *needed) wstdcall; + NDIS_STATUS (*tx_data)(struct ndis_packet *ndis_packet, + UINT *bytes_txed, void *mp_ctx, void *rx_ctx, + UINT offset, UINT bytes_to_tx) wstdcall; + /* NDIS 4.0 extensions */ + void (*return_packet)(void *ctx, void *packet) wstdcall; + void (*send_packets)(void *ctx, struct ndis_packet **packets, + INT nr_of_packets) wstdcall; + void (*alloc_complete)(void *handle, void *virt, + NDIS_PHY_ADDRESS *phys, + ULONG size, void *ctx) wstdcall; + /* NDIS 5.0 extensions */ + NDIS_STATUS (*co_create_vc)(void *ctx, void *vc_handle, + void *vc_ctx) wstdcall; + NDIS_STATUS (*co_delete_vc)(void *vc_ctx) wstdcall; + NDIS_STATUS (*co_activate_vc)(void *vc_ctx, void *call_params) wstdcall; + NDIS_STATUS (*co_deactivate_vc)(void *vc_ctx) wstdcall; + NDIS_STATUS (*co_send_packets)(void *vc_ctx, void **packets, + UINT nr_of_packets) wstdcall; + NDIS_STATUS (*co_request)(void *ctx, void *vc_ctx, UINT *req) wstdcall; + /* NDIS 5.1 extensions */ + void (*cancel_send_packets)(void *ctx, void *id) wstdcall; + void (*pnp_event_notify)(void *ctx, enum ndis_device_pnp_event event, + void *inf_buf, ULONG inf_buf_len) wstdcall; + void (*shutdown)(void *ctx) wstdcall; + void *reserved1; + void *reserved2; + void *reserved3; + void *reserved4; +}; + +struct ndis_spinlock { + NT_SPIN_LOCK klock; + KIRQL irql; +}; + +union ndis_rw_lock_refcount { + UCHAR cache_line[16]; +}; + +struct ndis_rw_lock { + union { + struct { + NT_SPIN_LOCK klock; + void *context; + }; + UCHAR reserved[16]; + }; + union { + union ndis_rw_lock_refcount ref_count[MAXIMUM_PROCESSORS]; + /* ndiswrapper specific */ + volatile int count; + }; +}; + +struct lock_state { + USHORT state; + KIRQL irql; +}; + +struct ndis_work_item; +typedef void (*NDIS_PROC)(struct ndis_work_item *, void *) wstdcall; + +struct ndis_work_item { + void *ctx; + NDIS_PROC func; + union { + UCHAR reserved[8 * sizeof(void *)]; + /* ndiswrapper specific */ + struct nt_list list; + }; +}; + +struct alloc_shared_mem { + void *ctx; + ULONG size; + BOOLEAN cached; +}; + +struct ndis_mp_block; + +/* this is opaque to drivers, so we can use it as we please */ +struct ndis_mp_interrupt { + struct kinterrupt *kinterrupt; + NT_SPIN_LOCK lock; + union { + void *reserved; + unsigned int irq; + }; + ndis_isr_handler isr; + ndis_interrupt_handler mp_dpc; + struct kdpc intr_dpc; + struct ndis_mp_block *nmb; + UCHAR dpc_count; + BOOLEAN enable; + struct nt_event dpc_completed_event; + BOOLEAN shared; + BOOLEAN req_isr; +}; + +struct ndis_binary_data { + USHORT len; + void *buf; +}; + +enum ndis_parameter_type { + NdisParameterInteger, NdisParameterHexInteger, + NdisParameterString, NdisParameterMultiString, NdisParameterBinary, +}; + +typedef struct unicode_string NDIS_STRING; + +struct ndis_configuration_parameter { + enum ndis_parameter_type type; + union { + ULONG integer; + NDIS_STRING string; + } data; +}; + +struct ndis_driver { + struct miniport mp; +}; + +/* IDs used to store extensions in driver_object's custom extension */ +#define NDIS_DRIVER_CLIENT_ID 10 + +struct ndis_wireless_stats { + ULONG length; + LARGE_INTEGER tx_frag; + LARGE_INTEGER tx_multi_frag; + LARGE_INTEGER failed; + LARGE_INTEGER retry; + LARGE_INTEGER multi_retry; + LARGE_INTEGER rtss_succ; + LARGE_INTEGER rtss_fail; + LARGE_INTEGER ack_fail; + LARGE_INTEGER frame_dup; + LARGE_INTEGER rx_frag; + LARGE_INTEGER rx_multi_frag; + LARGE_INTEGER fcs_err; + LARGE_INTEGER tkip_local_mic_failures; + LARGE_INTEGER tkip_icv_errors; + LARGE_INTEGER tkip_counter_measures_invoked; + LARGE_INTEGER tkip_replays; + LARGE_INTEGER ccmp_format_errors; + LARGE_INTEGER ccmp_replays; + LARGE_INTEGER ccmp_decrypt_errors; + LARGE_INTEGER fourway_handshake_failures; + LARGE_INTEGER wep_undecryptable_count; + LARGE_INTEGER wep_icv_errorcount; + LARGE_INTEGER decrypt_success_count; + LARGE_INTEGER decrypt_failure_count; +}; + +enum ndis_status_type { + Ndis802_11StatusType_Authentication, + Ndis802_11StatusType_MediaStreamMode, + Ndis802_11StatusType_PMKID_CandidateList, + Ndis802_11StatusType_RadioState, +}; + +struct ndis_status_indication { + enum ndis_status_type status_type; +}; + +enum ndis_radio_status { + Ndis802_11RadioStatusOn, Ndis802_11RadioStatusHardwareOff, + Ndis802_11RadioStatusSoftwareOff, +}; + +struct ndis_radio_status_indication +{ + enum ndis_status_type status_type; + enum ndis_radio_status radio_state; +}; + +enum ndis_media_stream_mode { + Ndis802_11MediaStreamOff, Ndis802_11MediaStreamOn +}; + +enum wrapper_work { + LINK_STATUS_OFF, LINK_STATUS_ON, SET_MULTICAST_LIST, COLLECT_IW_STATS, + HANGCHECK, NETIF_WAKEQ, +}; + +struct encr_info { + struct encr_key { + ULONG length; + UCHAR key[NDIS_ENCODING_TOKEN_MAX]; + } keys[MAX_ENCR_KEYS]; + unsigned short tx_key_index; +}; + +struct ndis_essid { + ULONG length; + UCHAR essid[NDIS_ESSID_MAX_SIZE]; +}; + +enum ndis_infrastructure_mode { + Ndis802_11IBSS, Ndis802_11Infrastructure, Ndis802_11AutoUnknown, + Ndis802_11InfrastructureMax +}; + +enum authentication_mode { + Ndis802_11AuthModeOpen, Ndis802_11AuthModeShared, + Ndis802_11AuthModeAutoSwitch, Ndis802_11AuthModeWPA, + Ndis802_11AuthModeWPAPSK, Ndis802_11AuthModeWPANone, + Ndis802_11AuthModeWPA2, Ndis802_11AuthModeWPA2PSK, + Ndis802_11AuthModeMax +}; + +enum encryption_status { + Ndis802_11WEPEnabled, + Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled, + Ndis802_11WEPDisabled, + Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled, + Ndis802_11WEPKeyAbsent, + Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent, + Ndis802_11WEPNotSupported, + Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported, + Ndis802_11Encryption2Enabled, Ndis802_11Encryption2KeyAbsent, + Ndis802_11Encryption3Enabled, Ndis802_11Encryption3KeyAbsent +}; + +struct ndis_auth_encr_pair { + enum authentication_mode auth_mode; + enum encryption_status encr_mode; +}; + +struct ndis_capability { + ULONG length; + ULONG version; + ULONG num_PMKIDs; + ULONG num_auth_encr_pair; + struct ndis_auth_encr_pair auth_encr_pair[1]; +}; + +struct ndis_guid { + struct guid guid; + union { + ndis_oid oid; + NDIS_STATUS status; + }; + ULONG size; + ULONG flags; +}; + +struct ndis_timer { + struct nt_timer nt_timer; + struct kdpc kdpc; +}; + +struct ndis_mp_timer { + struct nt_timer nt_timer; + struct kdpc kdpc; + DPC func; + void *ctx; + struct ndis_mp_block *nmb; + struct ndis_mp_timer *next; +}; + +typedef struct cm_partial_resource_list NDIS_RESOURCE_LIST; + +struct ndis_event { + struct nt_event nt_event; +}; + +struct ndis_bind_paths { + UINT number; + struct unicode_string paths[1]; +}; + +struct ndis_reference { + NT_SPIN_LOCK lock; + USHORT ref_count; + BOOLEAN closing; +}; + +struct ndis_filterdbs { + union { + void *eth_db; + void *null_db; + }; + void *tr_db; + void *fddi_db; + void *arc_db; +}; + +enum ndis_interface_type { + NdisInterfaceInternal, NdisInterfaceIsa, NdisInterfaceEisa, + NdisInterfaceMca, NdisInterfaceTurboChannel, NdisInterfacePci, + NdisInterfacePcMcia, +}; + +struct auth_encr_capa { + unsigned long auth; + unsigned long encr; +}; + +struct ndis_pmkid_candidate { + mac_address bssid; + DWORD flags; +}; + +struct ndis_pmkid_candidate_list { + ULONG version; + ULONG num_candidates; + struct ndis_pmkid_candidate candidates[1]; +}; + +/* + * This struct contains function pointers that the drivers references + * directly via macros, so it's important that they are at the correct + * position. + */ +struct ndis_mp_block { + void *signature; + struct ndis_mp_block *next; + struct driver_object *drv_obj; + void *mp_ctx; + struct unicode_string name; + struct ndis_bind_paths *bindpaths; + void *openqueue; + struct ndis_reference reference; + void *device_ctx; + UCHAR padding; + UCHAR lock_acquired; + UCHAR pmode_opens; + UCHAR assigned_cpu; + NT_SPIN_LOCK lock; + enum ndis_request_type *mediarequest; + struct ndis_mp_interrupt *interrupt; + ULONG flags; + ULONG pnp_flags; + struct nt_list packet_list; + struct ndis_packet *first_pending_tx_packet; + struct ndis_packet *return_packet_queue; + ULONG request_buffer; + void *set_mcast_buffer; + struct ndis_mp_block *primary_mp; + void *wrapper_ctx; + void *bus_data_ctx; + ULONG pnp_capa; + void *resources; + struct ndis_timer wakeup_dpc_timer; + struct unicode_string basename; + struct unicode_string symlink_name; + ULONG ndis_hangcheck_interval; + USHORT hanghcheck_ticks; + USHORT hangcheck_tick; + NDIS_STATUS ndis_reset_status; + void *resetopen; + struct ndis_filterdbs filterdbs; + void *rx_packet; + void *send_complete; + void *send_resource_avail; + void *reset_complete; + + enum ndis_medium media_type; + ULONG bus_number; + enum ndis_interface_type bus_type; + enum ndis_interface_type adapter_type; + struct device_object *fdo; + struct device_object *pdo; + struct device_object *next_device; + void *mapreg; + void *call_mgraflist; + void *mp_thread; + void *setinfobuf; + USHORT setinfo_buf_len; + USHORT max_send_pkts; + NDIS_STATUS fake_status; + void *lock_handler; + struct unicode_string *adapter_instance_name; + void *timer_queue; + UINT mac_options; + void *pending_req; + UINT max_long_addrs; + UINT max_short_addrs; + UINT cur_lookahead; + UINT max_lookahead; + + ndis_interrupt_handler irq_bh; + void *disable_intr; + void *enable_intr; + void *send_pkts; + void *deferred_send; + void *eth_rx_indicate; + void *tr_rx_indicate; + void *fddi_rx_indicate; + void *eth_rx_complete; + void *tr_rx_complete; + void *fddi_rx_complete; + + void *status; + void *status_complete; + void *td_complete; + + void *queryinfo_complete; + void *setinfo_complete; + void *wan_tx_complete; + void *wan_rx; + void *wan_rx_complete; + /* ndiswrapper specific */ + struct ndis_device *wnd; +}; + +struct ndis_device { + struct ndis_mp_block *nmb; + struct wrap_device *wd; + struct net_device *net_dev; + void *shutdown_ctx; + struct ndis_mp_interrupt *mp_interrupt; + struct kdpc irq_kdpc; + unsigned long mem_start; + unsigned long mem_end; + + struct net_device_stats net_stats; + struct iw_statistics iw_stats; + BOOLEAN iw_stats_enabled; + struct ndis_wireless_stats ndis_stats; + + work_struct_t tx_work; + struct ndis_packet *tx_ring[TX_RING_SIZE]; + u8 tx_ring_start; + u8 tx_ring_end; + u8 is_tx_ring_full; + u8 tx_ok; + spinlock_t tx_ring_lock; + struct semaphore tx_ring_mutex; + unsigned int max_tx_packets; + struct semaphore ndis_req_mutex; + struct task_struct *ndis_req_task; + int ndis_req_done; + NDIS_STATUS ndis_req_status; + ULONG packet_filter; + + ULONG sg_dma_size; + ULONG dma_map_count; + dma_addr_t *dma_map_addr; + + int hangcheck_interval; + struct timer_list hangcheck_timer; + int iw_stats_interval; + struct timer_list iw_stats_timer; + unsigned long scan_timestamp; + struct encr_info encr_info; + char nick[IW_ESSID_MAX_SIZE + 1]; + struct ndis_essid essid; + struct auth_encr_capa capa; + enum ndis_infrastructure_mode infrastructure_mode; + int max_pmkids; + int num_pmkids; + struct ndis_pmkid *pmkids; + mac_address mac; + struct proc_dir_entry *procfs_iface; + + work_struct_t ndis_work; + unsigned long ndis_pending_work; + UINT attributes; + int iw_auth_wpa_version; + int iw_auth_cipher_pairwise; + int iw_auth_cipher_group; + int iw_auth_key_mgmt; + int iw_auth_80211_alg; + struct ndis_packet_pool *tx_packet_pool; + struct ndis_buffer_pool *tx_buffer_pool; + int multicast_size; + struct v4_checksum rx_csum; + struct v4_checksum tx_csum; + enum ndis_physical_medium physical_medium; + ULONG ndis_wolopts; + struct nt_slist wrap_timer_slist; + int drv_ndis_version; + struct ndis_pnp_capabilities pnp_capa; + char netdev_name[IFNAMSIZ]; +}; + +BOOLEAN ndis_isr(struct kinterrupt *kinterrupt, void *ctx) wstdcall; + +int ndis_init(void); +void ndis_exit(void); +int ndis_init_device(struct ndis_device *wnd); +void ndis_exit_device(struct ndis_device *wnd); + +int wrap_procfs_add_ndis_device(struct ndis_device *wnd); +void wrap_procfs_remove_ndis_device(struct ndis_device *wnd); + +void NdisAllocatePacketPoolEx(NDIS_STATUS *status, + struct ndis_packet_pool **pool_handle, + UINT num_descr, UINT overflowsize, + UINT proto_rsvd_length) wstdcall; +void NdisFreePacketPool(struct ndis_packet_pool *pool) wstdcall; +void NdisAllocatePacket(NDIS_STATUS *status, struct ndis_packet **packet, + struct ndis_packet_pool *pool) wstdcall; +void NdisFreePacket(struct ndis_packet *descr) wstdcall; +void NdisAllocateBufferPool(NDIS_STATUS *status, + struct ndis_buffer_pool **pool_handle, + UINT num_descr) wstdcall; +void NdisFreeBufferPool(struct ndis_buffer_pool *pool) wstdcall; +void NdisAllocateBuffer(NDIS_STATUS *status, ndis_buffer **buffer, + struct ndis_buffer_pool *pool, void *virt, + UINT length) wstdcall; +void NdisFreeBuffer(ndis_buffer *descr) wstdcall; +void NdisMIndicateReceivePacket(struct ndis_mp_block *nmb, + struct ndis_packet **packets, + UINT nr_packets) wstdcall; +void NdisMSendComplete(struct ndis_mp_block *nmb, struct ndis_packet *packet, + NDIS_STATUS status) wstdcall; +void NdisMSendResourcesAvailable(struct ndis_mp_block *nmb) wstdcall; +void NdisMIndicateStatus(struct ndis_mp_block *nmb, + NDIS_STATUS status, void *buf, UINT len) wstdcall; +void NdisMIndicateStatusComplete(struct ndis_mp_block *nmb) wstdcall; +void NdisMQueryInformationComplete(struct ndis_mp_block *nmb, + NDIS_STATUS status) wstdcall; +void NdisMSetInformationComplete(struct ndis_mp_block *nmb, + NDIS_STATUS status) wstdcall; +void NdisMResetComplete(struct ndis_mp_block *nmb, NDIS_STATUS status, + BOOLEAN address_reset) wstdcall; +ULONG NDIS_BUFFER_TO_SPAN_PAGES(ndis_buffer *buffer) wstdcall; +BOOLEAN NdisWaitEvent(struct ndis_event *event, UINT timeout) wstdcall; +void NdisSetEvent(struct ndis_event *event) wstdcall; +void NdisMDeregisterInterrupt(struct ndis_mp_interrupt *mp_interrupt) wstdcall; +void EthRxIndicateHandler(struct ndis_mp_block *nmb, void *rx_ctx, + char *header1, char *header, UINT header_size, + void *look_ahead, UINT look_ahead_size, + UINT packet_size) wstdcall; +void EthRxComplete(struct ndis_mp_block *nmb) wstdcall; +void NdisMTransferDataComplete(struct ndis_mp_block *nmb, + struct ndis_packet *packet, NDIS_STATUS status, + UINT bytes_txed) wstdcall; +void NdisWriteConfiguration(NDIS_STATUS *status, struct ndis_mp_block *nmb, + struct unicode_string *key, + struct ndis_configuration_parameter *param) wstdcall; +void NdisReadConfiguration(NDIS_STATUS *status, + struct ndis_configuration_parameter **param, + struct ndis_mp_block *nmb, + struct unicode_string *key, + enum ndis_parameter_type type) wstdcall; + +/* Required OIDs */ +#define OID_GEN_SUPPORTED_LIST 0x00010101 +#define OID_GEN_HARDWARE_STATUS 0x00010102 +#define OID_GEN_MEDIA_SUPPORTED 0x00010103 +#define OID_GEN_MEDIA_IN_USE 0x00010104 +#define OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105 +#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106 +#define OID_GEN_LINK_SPEED 0x00010107 +#define OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108 +#define OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109 +#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A +#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B +#define OID_GEN_VENDOR_ID 0x0001010C +#define OID_GEN_VENDOR_DESCRIPTION 0x0001010D +#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010E +#define OID_GEN_CURRENT_LOOKAHEAD 0x0001010F +#define OID_GEN_DRIVER_VERSION 0x00010110 +#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111 +#define OID_GEN_PROTOCOL_OPTIONS 0x00010112 +#define OID_GEN_MAC_OPTIONS 0x00010113 +#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114 +#define OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115 +#define OID_GEN_VENDOR_DRIVER_VERSION 0x00010116 +#define OID_GEN_SUPPORTED_GUIDS 0x00010117 +#define OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118 /* Set only */ +#define OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119 /* Set only */ +#define OID_GEN_MACHINE_NAME 0x0001021A +#define OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B /* Set only */ +#define OID_GEN_VLAN_ID 0x0001021C + +/* Optional OIDs. */ +#define OID_GEN_MEDIA_CAPABILITIES 0x00010201 +#define OID_GEN_PHYSICAL_MEDIUM 0x00010202 + +/* Required statistics OIDs. */ +#define OID_GEN_XMIT_OK 0x00020101 +#define OID_GEN_RCV_OK 0x00020102 +#define OID_GEN_XMIT_ERROR 0x00020103 +#define OID_GEN_RCV_ERROR 0x00020104 +#define OID_GEN_RCV_NO_BUFFER 0x00020105 + +/* Optional OID statistics */ +#define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 +#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202 +#define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 +#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204 +#define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 +#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206 +#define OID_GEN_DIRECTED_BYTES_RCV 0x00020207 +#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208 +#define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 +#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A +#define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B +#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C +#define OID_GEN_RCV_CRC_ERROR 0x0002020D +#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E +#define OID_GEN_GET_TIME_CAPS 0x0002020F +#define OID_GEN_GET_NETCARD_TIME 0x00020210 +#define OID_GEN_NETCARD_LOAD 0x00020211 +#define OID_GEN_DEVICE_PROFILE 0x00020212 + +/* 802.3 (ethernet) OIDs */ +#define OID_802_3_PERMANENT_ADDRESS 0x01010101 +#define OID_802_3_CURRENT_ADDRESS 0x01010102 +#define OID_802_3_MULTICAST_LIST 0x01010103 +#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 +#define OID_802_3_MAC_OPTIONS 0x01010105 +#define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001 +#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101 +#define OID_802_3_XMIT_ONE_COLLISION 0x01020102 +#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103 +#define OID_802_3_XMIT_DEFERRED 0x01020201 +#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202 +#define OID_802_3_RCV_OVERRUN 0x01020203 +#define OID_802_3_XMIT_UNDERRUN 0x01020204 +#define OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205 +#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 +#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 + +/* PnP and power management OIDs */ +#define OID_PNP_CAPABILITIES 0xFD010100 +#define OID_PNP_SET_POWER 0xFD010101 +#define OID_PNP_QUERY_POWER 0xFD010102 +#define OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103 +#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104 +#define OID_PNP_WAKE_UP_PATTERN_LIST 0xFD010105 +#define OID_PNP_ENABLE_WAKE_UP 0xFD010106 + +/* PnP/PM Statistics (Optional). */ +#define OID_PNP_WAKE_UP_OK 0xFD020200 +#define OID_PNP_WAKE_UP_ERROR 0xFD020201 + +/* The following bits are defined for OID_PNP_ENABLE_WAKE_UP */ +#define NDIS_PNP_WAKE_UP_MAGIC_PACKET 0x00000001 +#define NDIS_PNP_WAKE_UP_PATTERN_MATCH 0x00000002 +#define NDIS_PNP_WAKE_UP_LINK_CHANGE 0x00000004 + +/* 802.11 OIDs */ +#define OID_802_11_BSSID 0x0D010101 +#define OID_802_11_SSID 0x0D010102 +#define OID_802_11_NETWORK_TYPES_SUPPORTED 0x0D010203 +#define OID_802_11_NETWORK_TYPE_IN_USE 0x0D010204 +#define OID_802_11_TX_POWER_LEVEL 0x0D010205 +#define OID_802_11_RSSI 0x0D010206 +#define OID_802_11_RSSI_TRIGGER 0x0D010207 +#define OID_802_11_INFRASTRUCTURE_MODE 0x0D010108 +#define OID_802_11_FRAGMENTATION_THRESHOLD 0x0D010209 +#define OID_802_11_RTS_THRESHOLD 0x0D01020A +#define OID_802_11_NUMBER_OF_ANTENNAS 0x0D01020B +#define OID_802_11_RX_ANTENNA_SELECTED 0x0D01020C +#define OID_802_11_TX_ANTENNA_SELECTED 0x0D01020D +#define OID_802_11_SUPPORTED_RATES 0x0D01020E +#define OID_802_11_DESIRED_RATES 0x0D010210 +#define OID_802_11_CONFIGURATION 0x0D010211 +#define OID_802_11_STATISTICS 0x0D020212 +#define OID_802_11_ADD_WEP 0x0D010113 +#define OID_802_11_REMOVE_WEP 0x0D010114 +#define OID_802_11_DISASSOCIATE 0x0D010115 +#define OID_802_11_POWER_MODE 0x0D010216 +#define OID_802_11_BSSID_LIST 0x0D010217 +#define OID_802_11_AUTHENTICATION_MODE 0x0D010118 +#define OID_802_11_PRIVACY_FILTER 0x0D010119 +#define OID_802_11_BSSID_LIST_SCAN 0x0D01011A +#define OID_802_11_WEP_STATUS 0x0D01011B +#define OID_802_11_ENCRYPTION_STATUS OID_802_11_WEP_STATUS +#define OID_802_11_RELOAD_DEFAULTS 0x0D01011C +#define OID_802_11_ADD_KEY 0x0D01011D +#define OID_802_11_REMOVE_KEY 0x0D01011E +#define OID_802_11_ASSOCIATION_INFORMATION 0x0D01011F +#define OID_802_11_TEST 0x0D010120 +#define OID_802_11_MEDIA_STREAM_MODE 0x0D010121 +#define OID_802_11_CAPABILITY 0x0D010122 +#define OID_802_11_PMKID 0x0D010123 + +#define NDIS_STATUS_SUCCESS 0 +#define NDIS_STATUS_PENDING 0x00000103 +#define NDIS_STATUS_NOT_RECOGNIZED 0x00010001 +#define NDIS_STATUS_NOT_COPIED 0x00010002 +#define NDIS_STATUS_NOT_ACCEPTED 0x00010003 +#define NDIS_STATUS_CALL_ACTIVE 0x00010007 +#define NDIS_STATUS_ONLINE 0x40010003 +#define NDIS_STATUS_RESET_START 0x40010004 +#define NDIS_STATUS_RESET_END 0x40010005 +#define NDIS_STATUS_RING_STATUS 0x40010006 +#define NDIS_STATUS_CLOSED 0x40010007 +#define NDIS_STATUS_WAN_LINE_UP 0x40010008 +#define NDIS_STATUS_WAN_LINE_DOWN 0x40010009 +#define NDIS_STATUS_WAN_FRAGMENT 0x4001000A +#define NDIS_STATUS_MEDIA_CONNECT 0x4001000B +#define NDIS_STATUS_MEDIA_DISCONNECT 0x4001000C +#define NDIS_STATUS_HARDWARE_LINE_UP 0x4001000D +#define NDIS_STATUS_HARDWARE_LINE_DOWN 0x4001000E +#define NDIS_STATUS_INTERFACE_UP 0x4001000F +#define NDIS_STATUS_INTERFACE_DOWN 0x40010010 +#define NDIS_STATUS_MEDIA_BUSY 0x40010011 +#define NDIS_STATUS_MEDIA_SPECIFIC_INDICATION 0x40010012 +#define NDIS_STATUS_WW_INDICATION NDIS_STATUS_MEDIA_SPECIFIC_INDICATION +#define NDIS_STATUS_LINK_SPEED_CHANGE 0x40010013 +#define NDIS_STATUS_WAN_GET_STATS 0x40010014 +#define NDIS_STATUS_WAN_CO_FRAGMENT 0x40010015 +#define NDIS_STATUS_WAN_CO_LINKPARAMS 0x40010016 +#define NDIS_STATUS_NOT_RESETTABLE 0x80010001 +#define NDIS_STATUS_SOFT_ERRORS 0x80010003 +#define NDIS_STATUS_HARD_ERRORS 0x80010004 +#define NDIS_STATUS_BUFFER_OVERFLOW 0x80000005 +#define NDIS_STATUS_FAILURE 0xC0000001 +#define NDIS_STATUS_INVALID_PARAMETER 0xC000000D +#define NDIS_STATUS_RESOURCES 0xC000009A +#define NDIS_STATUS_CLOSING 0xC0010002 +#define NDIS_STATUS_BAD_VERSION 0xC0010004 +#define NDIS_STATUS_BAD_CHARACTERISTICS 0xC0010005 +#define NDIS_STATUS_ADAPTER_NOT_FOUND 0xC0010006 +#define NDIS_STATUS_OPEN_FAILED 0xC0010007 +#define NDIS_STATUS_DEVICE_FAILED 0xC0010008 +#define NDIS_STATUS_MULTICAST_FULL 0xC0010009 +#define NDIS_STATUS_MULTICAST_EXISTS 0xC001000A +#define NDIS_STATUS_MULTICAST_NOT_FOUND 0xC001000B +#define NDIS_STATUS_REQUEST_ABORTED 0xC001000C +#define NDIS_STATUS_RESET_IN_PROGRESS 0xC001000D +#define NDIS_STATUS_CLOSING_INDICATING 0xC001000E +#define NDIS_STATUS_BAD_VERSION 0xC0010004 +#define NDIS_STATUS_NOT_SUPPORTED 0xC00000BB +#define NDIS_STATUS_INVALID_PACKET 0xC001000F +#define NDIS_STATUS_OPEN_LIST_FULL 0xC0010010 +#define NDIS_STATUS_ADAPTER_NOT_READY 0xC0010011 +#define NDIS_STATUS_ADAPTER_NOT_OPEN 0xC0010012 +#define NDIS_STATUS_NOT_INDICATING 0xC0010013 +#define NDIS_STATUS_INVALID_LENGTH 0xC0010014 +#define NDIS_STATUS_INVALID_DATA 0xC0010015 +#define NDIS_STATUS_BUFFER_TOO_SHORT 0xC0010016 +#define NDIS_STATUS_INVALID_OID 0xC0010017 +#define NDIS_STATUS_ADAPTER_REMOVED 0xC0010018 +#define NDIS_STATUS_UNSUPPORTED_MEDIA 0xC0010019 +#define NDIS_STATUS_GROUP_ADDRESS_IN_USE 0xC001001A +#define NDIS_STATUS_FILE_NOT_FOUND 0xC001001B +#define NDIS_STATUS_ERROR_READING_FILE 0xC001001C +#define NDIS_STATUS_ALREADY_MAPPED 0xC001001D +#define NDIS_STATUS_RESOURCE_CONFLICT 0xC001001E +#define NDIS_STATUS_NO_CABLE 0xC001001F +#define NDIS_STATUS_INVALID_SAP 0xC0010020 +#define NDIS_STATUS_SAP_IN_USE 0xC0010021 +#define NDIS_STATUS_INVALID_ADDRESS 0xC0010022 +#define NDIS_STATUS_VC_NOT_ACTIVATED 0xC0010023 +#define NDIS_STATUS_DEST_OUT_OF_ORDER 0xC0010024 +#define NDIS_STATUS_VC_NOT_AVAILABLE 0xC0010025 +#define NDIS_STATUS_CELLRATE_NOT_AVAILABLE 0xC0010026 +#define NDIS_STATUS_INCOMPATABLE_QOS 0xC0010027 +#define NDIS_STATUS_AAL_PARAMS_UNSUPPORTED 0xC0010028 +#define NDIS_STATUS_NO_ROUTE_TO_DESTINATION 0xC0010029 +#define NDIS_STATUS_TOKEN_RING_OPEN_ERROR 0xC0011000 +#define NDIS_STATUS_INVALID_DEVICE_REQUEST 0xC0000010 +#define NDIS_STATUS_NETWORK_UNREACHABLE 0xC000023C + +/* Event codes */ + +#define EVENT_NDIS_RESOURCE_CONFLICT 0xC0001388 +#define EVENT_NDIS_OUT_OF_RESOURCE 0xC0001389 +#define EVENT_NDIS_HARDWARE_FAILURE 0xC000138A +#define EVENT_NDIS_ADAPTER_NOT_FOUND 0xC000138B +#define EVENT_NDIS_INTERRUPT_CONNECT 0xC000138C +#define EVENT_NDIS_DRIVER_FAILURE 0xC000138D +#define EVENT_NDIS_BAD_VERSION 0xC000138E +#define EVENT_NDIS_TIMEOUT 0x8000138F +#define EVENT_NDIS_NETWORK_ADDRESS 0xC0001390 +#define EVENT_NDIS_UNSUPPORTED_CONFIGURATION 0xC0001391 +#define EVENT_NDIS_INVALID_VALUE_FROM_ADAPTER 0xC0001392 +#define EVENT_NDIS_MISSING_CONFIGURATION_PARAMETER 0xC0001393 +#define EVENT_NDIS_BAD_IO_BASE_ADDRESS 0xC0001394 +#define EVENT_NDIS_RECEIVE_SPACE_SMALL 0x40001395 +#define EVENT_NDIS_ADAPTER_DISABLED 0x80001396 +#define EVENT_NDIS_IO_PORT_CONFLICT 0x80001397 +#define EVENT_NDIS_PORT_OR_DMA_CONFLICT 0x80001398 +#define EVENT_NDIS_MEMORY_CONFLICT 0x80001399 +#define EVENT_NDIS_INTERRUPT_CONFLICT 0x8000139A +#define EVENT_NDIS_DMA_CONFLICT 0x8000139B +#define EVENT_NDIS_INVALID_DOWNLOAD_FILE_ERROR 0xC000139C +#define EVENT_NDIS_MAXRECEIVES_ERROR 0x8000139D +#define EVENT_NDIS_MAXTRANSMITS_ERROR 0x8000139E +#define EVENT_NDIS_MAXFRAMESIZE_ERROR 0x8000139F +#define EVENT_NDIS_MAXINTERNALBUFS_ERROR 0x800013A0 +#define EVENT_NDIS_MAXMULTICAST_ERROR 0x800013A1 +#define EVENT_NDIS_PRODUCTID_ERROR 0x800013A2 +#define EVENT_NDIS_LOBE_FAILUE_ERROR 0x800013A3 +#define EVENT_NDIS_SIGNAL_LOSS_ERROR 0x800013A4 +#define EVENT_NDIS_REMOVE_RECEIVED_ERROR 0x800013A5 +#define EVENT_NDIS_TOKEN_RING_CORRECTION 0x400013A6 +#define EVENT_NDIS_ADAPTER_CHECK_ERROR 0xC00013A7 +#define EVENT_NDIS_RESET_FAILURE_ERROR 0x800013A8 +#define EVENT_NDIS_CABLE_DISCONNECTED_ERROR 0x800013A9 +#define EVENT_NDIS_RESET_FAILURE_CORRECTION 0x800013AA + +/* packet filter bits used by NDIS_OID_PACKET_FILTER */ +#define NDIS_PACKET_TYPE_DIRECTED 0x00000001 +#define NDIS_PACKET_TYPE_MULTICAST 0x00000002 +#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004 +#define NDIS_PACKET_TYPE_BROADCAST 0x00000008 +#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010 +#define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020 +#define NDIS_PACKET_TYPE_SMT 0x00000040 +#define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080 +#define NDIS_PACKET_TYPE_GROUP 0x00001000 +#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00002000 +#define NDIS_PACKET_TYPE_FUNCTIONAL 0x00004000 +#define NDIS_PACKET_TYPE_MAC_FRAME 0x00008000 + +/* memory allocation flags */ +#define NDIS_MEMORY_CONTIGUOUS 0x00000001 +#define NDIS_MEMORY_NONCACHED 0x00000002 + +/* Atrribute flags to NdisMSetAtrributesEx */ +#define NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT 0x00000001 +#define NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT 0x00000002 +#define NDIS_ATTRIBUTE_IGNORE_TOKEN_RING_ERRORS 0x00000004 +#define NDIS_ATTRIBUTE_BUS_MASTER 0x00000008 +#define NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER 0x00000010 +#define NDIS_ATTRIBUTE_DESERIALIZE 0x00000020 +#define NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND 0x00000040 +#define NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK 0x00000080 +#define NDIS_ATTRIBUTE_NOT_CO_NDIS 0x00000100 +#define NDIS_ATTRIBUTE_USES_SAFE_BUFFER_APIS 0x00000200 + +#define OID_TCP_TASK_OFFLOAD 0xFC010201 + +#define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA 0x00000001 +#define NDIS_MAC_OPTION_RECEIVE_SERIALIZED 0x00000002 +#define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND 0x00000004 +#define NDIS_MAC_OPTION_NO_LOOPBACK 0x00000008 +#define NDIS_MAC_OPTION_FULL_DUPLEX 0x00000010 +#define NDIS_MAC_OPTION_EOTX_INDICATION 0x00000020 +#define NDIS_MAC_OPTION_8021P_PRIORITY 0x00000040 +#define NDIS_MAC_OPTION_SUPPORTS_MAC_ADDRESS_OVERWRITE 0x00000080 +#define NDIS_MAC_OPTION_RECEIVE_AT_DPC 0x00000100 +#define NDIS_MAC_OPTION_8021Q_VLAN 0x00000200 +#define NDIS_MAC_OPTION_RESERVED 0x80000000 + +#define deserialized_driver(wnd) (wnd->attributes & NDIS_ATTRIBUTE_DESERIALIZE) + +static inline void serialize_lock(struct ndis_device *wnd) +{ + nt_spin_lock(&wnd->nmb->lock); +} + +static inline void serialize_unlock(struct ndis_device *wnd) +{ + nt_spin_unlock(&wnd->nmb->lock); +} + +static inline KIRQL serialize_lock_irql(struct ndis_device *wnd) +{ + if (deserialized_driver(wnd)) + return raise_irql(DISPATCH_LEVEL); + else + return nt_spin_lock_irql(&wnd->nmb->lock, DISPATCH_LEVEL); +} + +static inline void serialize_unlock_irql(struct ndis_device *wnd, + KIRQL irql) +{ + if (deserialized_driver(wnd)) + lower_irql(irql); + else + nt_spin_unlock_irql(&wnd->nmb->lock, irql); +} + +static inline void if_serialize_lock(struct ndis_device *wnd) +{ + if (!deserialized_driver(wnd)) + nt_spin_lock(&wnd->nmb->lock); +} + +static inline void if_serialize_unlock(struct ndis_device *wnd) +{ + if (!deserialized_driver(wnd)) + nt_spin_unlock(&wnd->nmb->lock); +} + +#endif /* NDIS_H */ --- linux-2.6.28.orig/ubuntu/ndiswrapper/ndiswrapper.h +++ linux-2.6.28/ubuntu/ndiswrapper/ndiswrapper.h @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#ifndef _NDISWRAPPER_H_ +#define _NDISWRAPPER_H_ + +#define DRIVER_VERSION "1.53" +#define UTILS_VERSION "1.9" + +#define DRIVER_NAME "ndiswrapper" +#define DRIVER_CONFIG_DIR "/etc/ndiswrapper" + +#define SSID_MAX_WPA_IE_LEN 40 +#define NDIS_ESSID_MAX_SIZE 32 +#define NDIS_ENCODING_TOKEN_MAX 32 +#define MAX_ENCR_KEYS 4 +#define TX_RING_SIZE 16 +#define NDIS_MAX_RATES 8 +#define NDIS_MAX_RATES_EX 16 +#define WLAN_EID_GENERIC 221 +#define MAX_WPA_IE_LEN 64 +#define MAX_STR_LEN 512 + +#define WRAP_PCI_BUS 5 +#define WRAP_PCMCIA_BUS 8 +/* some USB devices, e.g., DWL-G120 have BusType as 0 */ +#define WRAP_INTERNAL_BUS 0 +/* documentation at msdn says 15 is PNP bus, but inf files from all + * vendors say 15 is USB; which is correct? */ +#define WRAP_USB_BUS 15 + +/* NDIS device must be 0, for compatability with old versions of + * ndiswrapper where device type for NDIS drivers is 0 */ +#define WRAP_NDIS_DEVICE 0 +#define WRAP_USB_DEVICE 1 +#define WRAP_BLUETOOTH_DEVICE1 2 +#define WRAP_BLUETOOTH_DEVICE2 3 + +#define WRAP_DEVICE_BUS(dev, bus) ((dev) << 8 | (bus)) +#define WRAP_BUS(dev_bus) ((dev_bus) & 0x000FF) +#define WRAP_DEVICE(dev_bus) ((dev_bus) >> 8) + +#define MAX_DRIVER_NAME_LEN 32 +#define MAX_VERSION_STRING_LEN 64 +#define MAX_SETTING_NAME_LEN 128 +#define MAX_SETTING_VALUE_LEN 256 + +#define MAX_DRIVER_PE_IMAGES 4 +#define MAX_DRIVER_BIN_FILES 5 +#define MAX_DEVICE_SETTINGS 512 + +#define MAX_ALLOCATED_URBS 15 + +#define DEV_ANY_ID -1 + +#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +#define MACSTRSEP "%02x:%02x:%02x:%02x:%02x:%02x" +#define MACSTR "%02x%02x%02x%02x%02x%02x" +#define MACINTADR(a) (int*)&((a)[0]), (int*)&((a)[1]), (int*)&((a)[2]), \ + (int*)&((a)[3]), (int*)&((a)[4]), (int*)&((a)[5]) + +#ifdef __KERNEL__ +/* DEBUG macros */ + +#define MSG(level, fmt, ...) \ + printk(level "ndiswrapper (%s:%d): " fmt "\n", \ + __FUNCTION__, __LINE__ , ## __VA_ARGS__) + +#define WARNING(fmt, ...) MSG(KERN_WARNING, fmt, ## __VA_ARGS__) +#define ERROR(fmt, ...) MSG(KERN_ERR, fmt , ## __VA_ARGS__) +#define INFO(fmt, ...) MSG(KERN_INFO, fmt , ## __VA_ARGS__) +#define TODO() WARNING("not fully implemented (yet)") + +#define TRACE(fmt, ...) do { } while (0) +#define TRACE1(fmt, ...) do { } while (0) +#define TRACE2(fmt, ...) do { } while (0) +#define TRACE3(fmt, ...) do { } while (0) +#define TRACE4(fmt, ...) do { } while (0) +#define TRACE5(fmt, ...) do { } while (0) +#define TRACE6(fmt, ...) do { } while (0) + +/* for a block of code */ +#define DBG_BLOCK(level) while (0) + +extern int debug; + +#if defined DEBUG +#undef TRACE +#define TRACE(level, fmt, ...) \ +do { \ + if (debug >= level) \ + printk(KERN_INFO "%s (%s:%d): " fmt "\n", DRIVER_NAME, \ + __FUNCTION__, __LINE__ , ## __VA_ARGS__); \ +} while (0) +#undef DBG_BLOCK +#define DBG_BLOCK(level) if (debug >= level) +#endif + +#if defined(DEBUG) && DEBUG >= 1 +#undef TRACE1 +#define TRACE1(fmt, ...) TRACE(1, fmt , ## __VA_ARGS__) +#endif + +#if defined(DEBUG) && DEBUG >= 2 +#undef TRACE2 +#define TRACE2(fmt, ...) TRACE(2, fmt , ## __VA_ARGS__) +#endif + +#if defined(DEBUG) && DEBUG >= 3 +#undef TRACE3 +#define TRACE3(fmt, ...) TRACE(3, fmt , ## __VA_ARGS__) +#endif + +#if defined(DEBUG) && DEBUG >= 4 +#undef TRACE4 +#define TRACE4(fmt, ...) TRACE(4, fmt , ## __VA_ARGS__) +#endif + +#if defined(DEBUG) && DEBUG >= 5 +#undef TRACE5 +#define TRACE5(fmt, ...) TRACE(5, fmt , ## __VA_ARGS__) +#endif + +#if defined(DEBUG) && DEBUG >= 6 +#undef TRACE6 +#define TRACE6(fmt, ...) TRACE(6, fmt , ## __VA_ARGS__) +#endif + +#define ENTER1(fmt, ...) TRACE1("Enter " fmt , ## __VA_ARGS__) +#define ENTER2(fmt, ...) TRACE2("Enter " fmt , ## __VA_ARGS__) +#define ENTER3(fmt, ...) TRACE3("Enter " fmt , ## __VA_ARGS__) +#define ENTER4(fmt, ...) TRACE4("Enter " fmt , ## __VA_ARGS__) +#define ENTER5(fmt, ...) TRACE5("Enter " fmt , ## __VA_ARGS__) +#define ENTER6(fmt, ...) TRACE6("Enter " fmt , ## __VA_ARGS__) + +#define EXIT1(stmt) do { TRACE1("Exit"); stmt; } while(0) +#define EXIT2(stmt) do { TRACE2("Exit"); stmt; } while(0) +#define EXIT3(stmt) do { TRACE3("Exit"); stmt; } while(0) +#define EXIT4(stmt) do { TRACE4("Exit"); stmt; } while(0) +#define EXIT5(stmt) do { TRACE5("Exit"); stmt; } while(0) +#define EXIT6(stmt) do { TRACE6("Exit"); stmt; } while(0) + +#if defined(USB_DEBUG) +#define USBTRACE TRACE1 +#define USBENTER ENTER1 +#define USBEXIT EXIT1 +#else +#define USBTRACE(fmt, ...) +#define USBENTER(fmt, ...) +#define USBEXIT(stmt) stmt +#endif + +#if defined(EVENT_DEBUG) +#define EVENTTRACE TRACE1 +#define EVENTENTER ENTER1 +#define EVENTEXIT EXIT1 +#else +#define EVENTTRACE(fmt, ...) +#define EVENTENTER(fmt, ...) +#define EVENTEXIT(stmt) stmt +#endif + +#if defined(TIMER_DEBUG) +#define TIMERTRACE TRACE1 +#define TIMERENTER ENTER1 +#define TIMEREXIT EXIT1 +#else +#define TIMERTRACE(fmt, ...) +#define TIMERENTER(fmt, ...) +#define TIMEREXIT(stmt) stmt +#endif + +#if defined(IO_DEBUG) +#define IOTRACE TRACE1 +#define IOENTER ENTER1 +#define IOEXIT EXIT1 +#else +#define IOTRACE(fmt, ...) +#define IOENTER(fmt, ...) +#define IOEXIT(stmt) stmt +#endif + +#if defined(WORK_DEBUG) +#define WORKTRACE TRACE1 +#define WORKENTER ENTER1 +#define WORKEXIT EXIT1 +#else +#define WORKTRACE(fmt, ...) +#define WORKENTER(fmt, ...) +#define WORKEXIT(stmt) stmt +#endif + +#ifdef DEBUG +#define assert(expr) \ +do { \ + if (!(expr)) { \ + ERROR("assertion '%s' failed", #expr); \ + dump_stack(); \ + } \ +} while (0) +#else +#define assert(expr) do { } while (0) +#endif + +#endif // __KERNEL__ + +#endif // NDISWRAPPER_H --- linux-2.6.28.orig/ubuntu/ndiswrapper/Kconfig +++ linux-2.6.28/ubuntu/ndiswrapper/Kconfig @@ -0,0 +1,4 @@ +config NDISWRAPPER + tristate "Wrapper for Windows NDIS network drivers" + depends on NET + default m --- linux-2.6.28.orig/ubuntu/ndiswrapper/hal.c +++ linux-2.6.28/ubuntu/ndiswrapper/hal.c @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#include "ntoskernel.h" +#include "hal_exports.h" + +wstdcall void WIN_FUNC(WRITE_PORT_ULONG,2) + (ULONG_PTR port, ULONG value) +{ + outl(value, port); +} + +wstdcall ULONG WIN_FUNC(READ_PORT_ULONG,1) + (ULONG_PTR port) +{ + return inl(port); +} + +wstdcall void WIN_FUNC(WRITE_PORT_USHORT,2) + (ULONG_PTR port, USHORT value) +{ + outw(value, port); +} + +wstdcall USHORT WIN_FUNC(READ_PORT_USHORT,1) + (ULONG_PTR port) +{ + return inw(port); +} + +wstdcall void WIN_FUNC(WRITE_PORT_UCHAR,2) + (ULONG_PTR port, UCHAR value) +{ + outb(value, port); +} + +wstdcall UCHAR WIN_FUNC(READ_PORT_UCHAR,1) + (ULONG_PTR port) +{ + return inb(port); +} + +wstdcall void WIN_FUNC(WRITE_PORT_BUFFER_USHORT,3) + (ULONG_PTR port, USHORT *buf, ULONG count) +{ + outsw(port, buf, count); +} + +wstdcall void WIN_FUNC(READ_PORT_BUFFER_USHORT,3) + (ULONG_PTR port, USHORT *buf, ULONG count) +{ + insw(port, buf, count); +} + +wstdcall void WIN_FUNC(WRITE_PORT_BUFFER_ULONG,3) + (ULONG_PTR port, ULONG *buf, ULONG count) +{ + outsl(port, buf, count); +} + +wstdcall void WIN_FUNC(READ_PORT_BUFFER_ULONG,3) + (ULONG_PTR port, ULONG *buf, ULONG count) +{ + insl(port, buf, count); +} + +wstdcall USHORT WIN_FUNC(READ_REGISTER_USHORT,1) + (void __iomem *reg) +{ + return readw(reg); +} + +wstdcall void WIN_FUNC(WRITE_REGISTER_ULONG,2) + (void __iomem *reg, UINT val) +{ + writel(val, reg); +} + +wstdcall void WIN_FUNC(WRITE_REGISTER_USHORT,2) + (void __iomem *reg, USHORT val) +{ + writew(val, reg); +} + +wstdcall void WIN_FUNC(WRITE_REGISTER_UCHAR,2) + (void __iomem *reg, UCHAR val) +{ + writeb(val, reg); +} + +wstdcall void WIN_FUNC(KeStallExecutionProcessor,1) + (ULONG usecs) +{ + udelay(usecs); +} + +wstdcall KIRQL WIN_FUNC(KeGetCurrentIrql,0) + (void) +{ + return current_irql(); +} + +wfastcall KIRQL WIN_FUNC(KfRaiseIrql,1) + (KIRQL newirql) +{ + return raise_irql(newirql); +} + +wfastcall void WIN_FUNC(KfLowerIrql,1) + (KIRQL oldirql) +{ + lower_irql(oldirql); +} + +wfastcall KIRQL WIN_FUNC(KfAcquireSpinLock,1) + (NT_SPIN_LOCK *lock) +{ + return nt_spin_lock_irql(lock, DISPATCH_LEVEL); +} + +wfastcall void WIN_FUNC(KfReleaseSpinLock,2) + (NT_SPIN_LOCK *lock, KIRQL oldirql) +{ + nt_spin_unlock_irql(lock, oldirql); +} + +wfastcall void WIN_FUNC(KefAcquireSpinLockAtDpcLevel,1) + (NT_SPIN_LOCK *lock) +{ +#ifdef DEBUG_IRQL + if (current_irql() != DISPATCH_LEVEL) + ERROR("irql != DISPATCH_LEVEL"); +#endif + nt_spin_lock(lock); +} + +wfastcall void WIN_FUNC(KefReleaseSpinLockFromDpcLevel,1) + (NT_SPIN_LOCK *lock) +{ +#ifdef DEBUG_IRQL + if (current_irql() != DISPATCH_LEVEL) + ERROR("irql != DISPATCH_LEVEL"); +#endif + nt_spin_unlock(lock); +} --- linux-2.6.28.orig/ubuntu/ndiswrapper/longlong.h +++ linux-2.6.28/ubuntu/ndiswrapper/longlong.h @@ -0,0 +1,1333 @@ +/* longlong.h -- definitions for mixed size 32/64 bit arithmetic. + Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000 + Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* You have to define the following before including this file: + + UWtype -- An unsigned type, default type for operations (typically a "word") + UHWtype -- An unsigned type, at least half the size of UWtype. + UDWtype -- An unsigned type, at least twice as large a UWtype + W_TYPE_SIZE -- size in bits of UWtype + + UQItype -- Unsigned 8 bit type. + SItype, USItype -- Signed and unsigned 32 bit types. + DItype, UDItype -- Signed and unsigned 64 bit types. + + On a 32 bit machine UWtype should typically be USItype; + on a 64 bit machine, UWtype should typically be UDItype. +*/ + +#define __BITS4 (W_TYPE_SIZE / 4) +#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2)) +#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1)) +#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2)) + +#ifndef W_TYPE_SIZE +#define W_TYPE_SIZE 32 +#define UWtype USItype +#define UHWtype USItype +#define UDWtype UDItype +#endif + +/* Define auxiliary asm macros. + + 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) multiplies two + UWtype integers MULTIPLER and MULTIPLICAND, and generates a two UWtype + word product in HIGH_PROD and LOW_PROD. + + 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a + UDWtype product. This is just a variant of umul_ppmm. + + 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, + denominator) divides a UDWtype, composed by the UWtype integers + HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient + in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less + than DENOMINATOR for correct operation. If, in addition, the most + significant bit of DENOMINATOR must be 1, then the pre-processor symbol + UDIV_NEEDS_NORMALIZATION is defined to 1. + + 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, + denominator). Like udiv_qrnnd but the numbers are signed. The quotient + is rounded towards 0. + + 5) count_leading_zeros(count, x) counts the number of zero-bits from the + msb to the first nonzero bit in the UWtype X. This is the number of + steps X needs to be shifted left to set the msb. Undefined for X == 0, + unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value. + + 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts + from the least significant end. + + 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, + high_addend_2, low_addend_2) adds two UWtype integers, composed by + HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2 + respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow + (i.e. carry out) is not stored anywhere, and is lost. + + 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend, + high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers, + composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and + LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE + and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, + and is lost. + + If any of these macros are left undefined for a particular CPU, + C macros are used. */ + +/* The CPUs come in alphabetical order below. + + Please add support for more CPUs here, or improve the current support + for the CPUs below! + (E.g. WE32100, IBM360.) */ + +#if defined (__GNUC__) && !defined (NO_ASM) + +/* We sometimes need to clobber "cc" with gcc2, but that would not be + understood by gcc1. Use cpp to avoid major code duplication. */ +#if __GNUC__ < 2 +#define __CLOBBER_CC +#define __AND_CLOBBER_CC +#else /* __GNUC__ >= 2 */ +#define __CLOBBER_CC : "cc" +#define __AND_CLOBBER_CC , "cc" +#endif /* __GNUC__ < 2 */ + +#if defined (__alpha) && W_TYPE_SIZE == 64 +#define umul_ppmm(ph, pl, m0, m1) \ + do { \ + UDItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("umulh %r1,%2,%0" \ + : "=r" ((UDItype) ph) \ + : "%rJ" (__m0), \ + "rI" (__m1)); \ + (pl) = __m0 * __m1; \ + } while (0) +#define UMUL_TIME 46 +#ifndef LONGLONG_STANDALONE +#define udiv_qrnnd(q, r, n1, n0, d) \ + do { UDItype __r; \ + (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ + (r) = __r; \ + } while (0) +extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype); +#define UDIV_TIME 220 +#endif /* LONGLONG_STANDALONE */ +#ifdef __alpha_cix__ +#define count_leading_zeros(COUNT,X) \ + __asm__("ctlz %1,%0" : "=r"(COUNT) : "r"(X)) +#define count_trailing_zeros(COUNT,X) \ + __asm__("cttz %1,%0" : "=r"(COUNT) : "r"(X)) +#define COUNT_LEADING_ZEROS_0 64 +#else +extern const UQItype __clz_tab[]; +#define count_leading_zeros(COUNT,X) \ + do { \ + UDItype __xr = (X), __t, __a; \ + __asm__("cmpbge $31,%1,%0" : "=r"(__t) : "r"(__xr)); \ + __a = __clz_tab[__t ^ 0xff] - 1; \ + __asm__("extbl %1,%2,%0" : "=r"(__t) : "r"(__xr), "r"(__a)); \ + (COUNT) = 64 - (__clz_tab[__t] + __a*8); \ + } while (0) +#define count_trailing_zeros(COUNT,X) \ + do { \ + UDItype __xr = (X), __t, __a; \ + __asm__("cmpbge $31,%1,%0" : "=r"(__t) : "r"(__xr)); \ + __t = ~__t & -~__t; \ + __a = ((__t & 0xCC) != 0) * 2; \ + __a += ((__t & 0xF0) != 0) * 4; \ + __a += ((__t & 0xAA) != 0); \ + __asm__("extbl %1,%2,%0" : "=r"(__t) : "r"(__xr), "r"(__a)); \ + __a <<= 3; \ + __t &= -__t; \ + __a += ((__t & 0xCC) != 0) * 2; \ + __a += ((__t & 0xF0) != 0) * 4; \ + __a += ((__t & 0xAA) != 0); \ + (COUNT) = __a; \ + } while (0) +#endif /* __alpha_cix__ */ +#endif /* __alpha */ + +#if defined (__arc__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add.f %1, %4, %5\n\tadc %0, %2, %3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%r" ((USItype) (ah)), \ + "rIJ" ((USItype) (bh)), \ + "%r" ((USItype) (al)), \ + "rIJ" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub.f %1, %4, %5\n\tsbc %0, %2, %3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "r" ((USItype) (ah)), \ + "rIJ" ((USItype) (bh)), \ + "r" ((USItype) (al)), \ + "rIJ" ((USItype) (bl))) +/* Call libgcc routine. */ +#define umul_ppmm(w1, w0, u, v) \ +do { \ + DWunion __w; \ + __w.ll = __umulsidi3 (u, v); \ + w1 = __w.s.high; \ + w0 = __w.s.low; \ +} while (0) +#define __umulsidi3 __umulsidi3 +UDItype __umulsidi3 (USItype, USItype); +#endif + +#if defined (__arm__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("adds %1, %4, %5\n\tadc %0, %2, %3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%r" ((USItype) (ah)), \ + "rI" ((USItype) (bh)), \ + "%r" ((USItype) (al)), \ + "rI" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subs %1, %4, %5\n\tsbc %0, %2, %3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "r" ((USItype) (ah)), \ + "rI" ((USItype) (bh)), \ + "r" ((USItype) (al)), \ + "rI" ((USItype) (bl))) +#define umul_ppmm(xh, xl, a, b) \ +{register USItype __t0, __t1, __t2; \ + __asm__ ("%@ Inlined umul_ppmm\n" \ + " mov %2, %5, lsr #16\n" \ + " mov %0, %6, lsr #16\n" \ + " bic %3, %5, %2, lsl #16\n" \ + " bic %4, %6, %0, lsl #16\n" \ + " mul %1, %3, %4\n" \ + " mul %4, %2, %4\n" \ + " mul %3, %0, %3\n" \ + " mul %0, %2, %0\n" \ + " adds %3, %4, %3\n" \ + " addcs %0, %0, #65536\n" \ + " adds %1, %1, %3, lsl #16\n" \ + " adc %0, %0, %3, lsr #16" \ + : "=&r" ((USItype) (xh)), \ + "=r" ((USItype) (xl)), \ + "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \ + : "r" ((USItype) (a)), \ + "r" ((USItype) (b)));} +#define UMUL_TIME 20 +#define UDIV_TIME 100 +#endif /* __arm__ */ + +#if defined (__hppa) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add %4,%5,%1\n\taddc %2,%3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%rM" ((USItype) (ah)), \ + "rM" ((USItype) (bh)), \ + "%rM" ((USItype) (al)), \ + "rM" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub %4,%5,%1\n\tsubb %2,%3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "rM" ((USItype) (ah)), \ + "rM" ((USItype) (bh)), \ + "rM" ((USItype) (al)), \ + "rM" ((USItype) (bl))) +#if defined (_PA_RISC1_1) +#define umul_ppmm(w1, w0, u, v) \ + do { \ + union \ + { \ + UDItype __f; \ + struct {USItype __w1, __w0;} __w1w0; \ + } __t; \ + __asm__ ("xmpyu %1,%2,%0" \ + : "=x" (__t.__f) \ + : "x" ((USItype) (u)), \ + "x" ((USItype) (v))); \ + (w1) = __t.__w1w0.__w1; \ + (w0) = __t.__w1w0.__w0; \ + } while (0) +#define UMUL_TIME 8 +#else +#define UMUL_TIME 30 +#endif +#define UDIV_TIME 40 +#define count_leading_zeros(count, x) \ + do { \ + USItype __tmp; \ + __asm__ ( \ + "ldi 1,%0\n" \ +" extru,= %1,15,16,%%r0 ; Bits 31..16 zero?\n" \ +" extru,tr %1,15,16,%1 ; No. Shift down, skip add.\n"\ +" ldo 16(%0),%0 ; Yes. Perform add.\n" \ +" extru,= %1,23,8,%%r0 ; Bits 15..8 zero?\n" \ +" extru,tr %1,23,8,%1 ; No. Shift down, skip add.\n"\ +" ldo 8(%0),%0 ; Yes. Perform add.\n" \ +" extru,= %1,27,4,%%r0 ; Bits 7..4 zero?\n" \ +" extru,tr %1,27,4,%1 ; No. Shift down, skip add.\n"\ +" ldo 4(%0),%0 ; Yes. Perform add.\n" \ +" extru,= %1,29,2,%%r0 ; Bits 3..2 zero?\n" \ +" extru,tr %1,29,2,%1 ; No. Shift down, skip add.\n"\ +" ldo 2(%0),%0 ; Yes. Perform add.\n" \ +" extru %1,30,1,%1 ; Extract bit 1.\n" \ +" sub %0,%1,%0 ; Subtract it.\n" \ + : "=r" (count), "=r" (__tmp) : "1" (x)); \ + } while (0) +#endif + +#if (defined (__i370__) || defined (__mvs__)) && W_TYPE_SIZE == 32 +#define umul_ppmm(xh, xl, m0, m1) \ + do { \ + union {UDItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __xx; \ + USItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("mr %0,%3" \ + : "=r" (__xx.__i.__h), \ + "=r" (__xx.__i.__l) \ + : "%1" (__m0), \ + "r" (__m1)); \ + (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ + (xh) += ((((SItype) __m0 >> 31) & __m1) \ + + (((SItype) __m1 >> 31) & __m0)); \ + } while (0) +#define smul_ppmm(xh, xl, m0, m1) \ + do { \ + union {DItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __xx; \ + __asm__ ("mr %0,%3" \ + : "=r" (__xx.__i.__h), \ + "=r" (__xx.__i.__l) \ + : "%1" (m0), \ + "r" (m1)); \ + (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ + } while (0) +#define sdiv_qrnnd(q, r, n1, n0, d) \ + do { \ + union {DItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __xx; \ + __xx.__i.__h = n1; __xx.__i.__l = n0; \ + __asm__ ("dr %0,%2" \ + : "=r" (__xx.__ll) \ + : "0" (__xx.__ll), "r" (d)); \ + (q) = __xx.__i.__l; (r) = __xx.__i.__h; \ + } while (0) +#endif + +#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addl %5,%1\n\tadcl %3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%0" ((USItype) (ah)), \ + "g" ((USItype) (bh)), \ + "%1" ((USItype) (al)), \ + "g" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subl %5,%1\n\tsbbl %3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "0" ((USItype) (ah)), \ + "g" ((USItype) (bh)), \ + "1" ((USItype) (al)), \ + "g" ((USItype) (bl))) +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("mull %3" \ + : "=a" ((USItype) (w0)), \ + "=d" ((USItype) (w1)) \ + : "%0" ((USItype) (u)), \ + "rm" ((USItype) (v))) +#define udiv_qrnnd(q, r, n1, n0, dv) \ + __asm__ ("divl %4" \ + : "=a" ((USItype) (q)), \ + "=d" ((USItype) (r)) \ + : "0" ((USItype) (n0)), \ + "1" ((USItype) (n1)), \ + "rm" ((USItype) (dv))) +#define count_leading_zeros(count, x) \ + do { \ + USItype __cbtmp; \ + __asm__ ("bsrl %1,%0" \ + : "=r" (__cbtmp) : "rm" ((USItype) (x))); \ + (count) = __cbtmp ^ 31; \ + } while (0) +#define count_trailing_zeros(count, x) \ + __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x))) +#define UMUL_TIME 40 +#define UDIV_TIME 40 +#endif /* 80x86 */ + +#if defined (__i960__) && W_TYPE_SIZE == 32 +#define umul_ppmm(w1, w0, u, v) \ + ({union {UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + __asm__ ("emul %2,%1,%0" \ + : "=d" (__xx.__ll) \ + : "%dI" ((USItype) (u)), \ + "dI" ((USItype) (v))); \ + (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) +#define __umulsidi3(u, v) \ + ({UDItype __w; \ + __asm__ ("emul %2,%1,%0" \ + : "=d" (__w) \ + : "%dI" ((USItype) (u)), \ + "dI" ((USItype) (v))); \ + __w; }) +#endif /* __i960__ */ + +#if defined (__M32R__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + /* The cmp clears the condition bit. */ \ + __asm__ ("cmp %0,%0\n\taddx %%5,%1\n\taddx %%3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%0" ((USItype) (ah)), \ + "r" ((USItype) (bh)), \ + "%1" ((USItype) (al)), \ + "r" ((USItype) (bl)) \ + : "cbit") +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + /* The cmp clears the condition bit. */ \ + __asm__ ("cmp %0,%0\n\tsubx %5,%1\n\tsubx %3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "0" ((USItype) (ah)), \ + "r" ((USItype) (bh)), \ + "1" ((USItype) (al)), \ + "r" ((USItype) (bl)) \ + : "cbit") +#endif /* __M32R__ */ + +#if defined (__mc68000__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add%.l %5,%1\n\taddx%.l %3,%0" \ + : "=d" ((USItype) (sh)), \ + "=&d" ((USItype) (sl)) \ + : "%0" ((USItype) (ah)), \ + "d" ((USItype) (bh)), \ + "%1" ((USItype) (al)), \ + "g" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub%.l %5,%1\n\tsubx%.l %3,%0" \ + : "=d" ((USItype) (sh)), \ + "=&d" ((USItype) (sl)) \ + : "0" ((USItype) (ah)), \ + "d" ((USItype) (bh)), \ + "1" ((USItype) (al)), \ + "g" ((USItype) (bl))) + +/* The '020, '030, '040 and CPU32 have 32x32->64 and 64/32->32q-32r. */ +#if defined (__mc68020__) || defined(mc68020) \ + || defined(__mc68030__) || defined(mc68030) \ + || defined(__mc68040__) || defined(mc68040) \ + || defined(__mcpu32__) || defined(mcpu32) +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("mulu%.l %3,%1:%0" \ + : "=d" ((USItype) (w0)), \ + "=d" ((USItype) (w1)) \ + : "%0" ((USItype) (u)), \ + "dmi" ((USItype) (v))) +#define UMUL_TIME 45 +#define udiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("divu%.l %4,%1:%0" \ + : "=d" ((USItype) (q)), \ + "=d" ((USItype) (r)) \ + : "0" ((USItype) (n0)), \ + "1" ((USItype) (n1)), \ + "dmi" ((USItype) (d))) +#define UDIV_TIME 90 +#define sdiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("divs%.l %4,%1:%0" \ + : "=d" ((USItype) (q)), \ + "=d" ((USItype) (r)) \ + : "0" ((USItype) (n0)), \ + "1" ((USItype) (n1)), \ + "dmi" ((USItype) (d))) + +#else /* not mc68020 */ +#if !defined(__mcf5200__) +/* %/ inserts REGISTER_PREFIX, %# inserts IMMEDIATE_PREFIX. */ +#define umul_ppmm(xh, xl, a, b) \ + __asm__ ("| Inlined umul_ppmm\n" \ + " move%.l %2,%/d0\n" \ + " move%.l %3,%/d1\n" \ + " move%.l %/d0,%/d2\n" \ + " swap %/d0\n" \ + " move%.l %/d1,%/d3\n" \ + " swap %/d1\n" \ + " move%.w %/d2,%/d4\n" \ + " mulu %/d3,%/d4\n" \ + " mulu %/d1,%/d2\n" \ + " mulu %/d0,%/d3\n" \ + " mulu %/d0,%/d1\n" \ + " move%.l %/d4,%/d0\n" \ + " eor%.w %/d0,%/d0\n" \ + " swap %/d0\n" \ + " add%.l %/d0,%/d2\n" \ + " add%.l %/d3,%/d2\n" \ + " jcc 1f\n" \ + " add%.l %#65536,%/d1\n" \ + "1: swap %/d2\n" \ + " moveq %#0,%/d0\n" \ + " move%.w %/d2,%/d0\n" \ + " move%.w %/d4,%/d2\n" \ + " move%.l %/d2,%1\n" \ + " add%.l %/d1,%/d0\n" \ + " move%.l %/d0,%0" \ + : "=g" ((USItype) (xh)), \ + "=g" ((USItype) (xl)) \ + : "g" ((USItype) (a)), \ + "g" ((USItype) (b)) \ + : "d0", "d1", "d2", "d3", "d4") +#define UMUL_TIME 100 +#define UDIV_TIME 400 +#endif /* not mcf5200 */ +#endif /* not mc68020 */ + +/* The '020, '030, '040 and '060 have bitfield insns. */ +#if defined (__mc68020__) || defined(mc68020) \ + || defined(__mc68030__) || defined(mc68030) \ + || defined(__mc68040__) || defined(mc68040) \ + || defined(__mc68060__) || defined(mc68060) +#define count_leading_zeros(count, x) \ + __asm__ ("bfffo %1{%b2:%b2},%0" \ + : "=d" ((USItype) (count)) \ + : "od" ((USItype) (x)), "n" (0)) +#endif +#endif /* mc68000 */ + +#if defined (__m88000__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addu.co %1,%r4,%r5\n\taddu.ci %0,%r2,%r3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%rJ" ((USItype) (ah)), \ + "rJ" ((USItype) (bh)), \ + "%rJ" ((USItype) (al)), \ + "rJ" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subu.co %1,%r4,%r5\n\tsubu.ci %0,%r2,%r3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "rJ" ((USItype) (ah)), \ + "rJ" ((USItype) (bh)), \ + "rJ" ((USItype) (al)), \ + "rJ" ((USItype) (bl))) +#define count_leading_zeros(count, x) \ + do { \ + USItype __cbtmp; \ + __asm__ ("ff1 %0,%1" \ + : "=r" (__cbtmp) \ + : "r" ((USItype) (x))); \ + (count) = __cbtmp ^ 31; \ + } while (0) +#define COUNT_LEADING_ZEROS_0 63 /* sic */ +#if defined (__mc88110__) +#define umul_ppmm(wh, wl, u, v) \ + do { \ + union {UDItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __xx; \ + __asm__ ("mulu.d %0,%1,%2" \ + : "=r" (__xx.__ll) \ + : "r" ((USItype) (u)), \ + "r" ((USItype) (v))); \ + (wh) = __xx.__i.__h; \ + (wl) = __xx.__i.__l; \ + } while (0) +#define udiv_qrnnd(q, r, n1, n0, d) \ + ({union {UDItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __xx; \ + USItype __q; \ + __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ + __asm__ ("divu.d %0,%1,%2" \ + : "=r" (__q) \ + : "r" (__xx.__ll), \ + "r" ((USItype) (d))); \ + (r) = (n0) - __q * (d); (q) = __q; }) +#define UMUL_TIME 5 +#define UDIV_TIME 25 +#else +#define UMUL_TIME 17 +#define UDIV_TIME 150 +#endif /* __mc88110__ */ +#endif /* __m88000__ */ + +#if defined (__mips__) && W_TYPE_SIZE == 32 +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("multu %2,%3" \ + : "=l" ((USItype) (w0)), \ + "=h" ((USItype) (w1)) \ + : "d" ((USItype) (u)), \ + "d" ((USItype) (v))) +#define UMUL_TIME 10 +#define UDIV_TIME 100 +#endif /* __mips__ */ + +#if defined (__ns32000__) && W_TYPE_SIZE == 32 +#define umul_ppmm(w1, w0, u, v) \ + ({union {UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + __asm__ ("meid %2,%0" \ + : "=g" (__xx.__ll) \ + : "%0" ((USItype) (u)), \ + "g" ((USItype) (v))); \ + (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) +#define __umulsidi3(u, v) \ + ({UDItype __w; \ + __asm__ ("meid %2,%0" \ + : "=g" (__w) \ + : "%0" ((USItype) (u)), \ + "g" ((USItype) (v))); \ + __w; }) +#define udiv_qrnnd(q, r, n1, n0, d) \ + ({union {UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ + __asm__ ("deid %2,%0" \ + : "=g" (__xx.__ll) \ + : "0" (__xx.__ll), \ + "g" ((USItype) (d))); \ + (r) = __xx.__i.__l; (q) = __xx.__i.__h; }) +#define count_trailing_zeros(count,x) \ + do { \ + __asm__ ("ffsd %2,%0" \ + : "=r" ((USItype) (count)) \ + : "0" ((USItype) 0), \ + "r" ((USItype) (x))); \ + } while (0) +#endif /* __ns32000__ */ + +/* FIXME: We should test _IBMR2 here when we add assembly support for the + system vendor compilers. + FIXME: What's needed for gcc PowerPC VxWorks? __vxworks__ is not good + enough, since that hits ARM and m68k too. */ +#if (defined (_ARCH_PPC) /* AIX */ \ + || defined (_ARCH_PWR) /* AIX */ \ + || defined (_ARCH_COM) /* AIX */ \ + || defined (__powerpc__) /* gcc */ \ + || defined (__POWERPC__) /* BEOS */ \ + || defined (__ppc__) /* Darwin */ \ + || defined (PPC) /* GNU/Linux, SysV */ \ + ) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + do { \ + if (__builtin_constant_p (bh) && (bh) == 0) \ + __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ + else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \ + __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ + else \ + __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ + : "=r" (sh), "=&r" (sl) \ + : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \ + } while (0) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + if (__builtin_constant_p (ah) && (ah) == 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ + else if (__builtin_constant_p (ah) && (ah) == ~(USItype) 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ + else if (__builtin_constant_p (bh) && (bh) == 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ + else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ + else \ + __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ + : "=r" (sh), "=&r" (sl) \ + : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \ + } while (0) +#define count_leading_zeros(count, x) \ + __asm__ ("{cntlz|cntlzw} %0,%1" : "=r" (count) : "r" (x)) +#define COUNT_LEADING_ZEROS_0 32 +#if defined (_ARCH_PPC) || defined (__powerpc__) || defined (__POWERPC__) \ + || defined (__ppc__) || defined (PPC) || defined (__vxworks__) +#define umul_ppmm(ph, pl, m0, m1) \ + do { \ + USItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("mulhwu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ + (pl) = __m0 * __m1; \ + } while (0) +#define UMUL_TIME 15 +#define smul_ppmm(ph, pl, m0, m1) \ + do { \ + SItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("mulhw %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ + (pl) = __m0 * __m1; \ + } while (0) +#define SMUL_TIME 14 +#define UDIV_TIME 120 +#elif defined (_ARCH_PWR) +#define UMUL_TIME 8 +#define smul_ppmm(xh, xl, m0, m1) \ + __asm__ ("mul %0,%2,%3" : "=r" (xh), "=q" (xl) : "r" (m0), "r" (m1)) +#define SMUL_TIME 4 +#define sdiv_qrnnd(q, r, nh, nl, d) \ + __asm__ ("div %0,%2,%4" : "=r" (q), "=q" (r) : "r" (nh), "1" (nl), "r" (d)) +#define UDIV_TIME 100 +#endif +#endif /* 32-bit POWER architecture variants. */ + +/* We should test _IBMR2 here when we add assembly support for the system + vendor compilers. */ +#if (defined (_ARCH_PPC64) || defined (__powerpc64__)) && W_TYPE_SIZE == 64 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + do { \ + if (__builtin_constant_p (bh) && (bh) == 0) \ + __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ + else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ + __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ + else \ + __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ + : "=r" (sh), "=&r" (sl) \ + : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \ + } while (0) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + if (__builtin_constant_p (ah) && (ah) == 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ + else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ + else if (__builtin_constant_p (bh) && (bh) == 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ + else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ + else \ + __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ + : "=r" (sh), "=&r" (sl) \ + : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \ + } while (0) +#define count_leading_zeros(count, x) \ + __asm__ ("cntlzd %0,%1" : "=r" (count) : "r" (x)) +#define COUNT_LEADING_ZEROS_0 64 +#define umul_ppmm(ph, pl, m0, m1) \ + do { \ + UDItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ + (pl) = __m0 * __m1; \ + } while (0) +#define UMUL_TIME 15 +#define smul_ppmm(ph, pl, m0, m1) \ + do { \ + DItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ + (pl) = __m0 * __m1; \ + } while (0) +#define SMUL_TIME 14 /* ??? */ +#define UDIV_TIME 120 /* ??? */ +#endif /* 64-bit PowerPC. */ + +#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("a %1,%5\n\tae %0,%3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%0" ((USItype) (ah)), \ + "r" ((USItype) (bh)), \ + "%1" ((USItype) (al)), \ + "r" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("s %1,%5\n\tse %0,%3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "0" ((USItype) (ah)), \ + "r" ((USItype) (bh)), \ + "1" ((USItype) (al)), \ + "r" ((USItype) (bl))) +#define umul_ppmm(ph, pl, m0, m1) \ + do { \ + USItype __m0 = (m0), __m1 = (m1); \ + __asm__ ( \ + "s r2,r2\n" \ +" mts r10,%2\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" cas %0,r2,r0\n" \ +" mfs r10,%1" \ + : "=r" ((USItype) (ph)), \ + "=r" ((USItype) (pl)) \ + : "%r" (__m0), \ + "r" (__m1) \ + : "r2"); \ + (ph) += ((((SItype) __m0 >> 31) & __m1) \ + + (((SItype) __m1 >> 31) & __m0)); \ + } while (0) +#define UMUL_TIME 20 +#define UDIV_TIME 200 +#define count_leading_zeros(count, x) \ + do { \ + if ((x) >= 0x10000) \ + __asm__ ("clz %0,%1" \ + : "=r" ((USItype) (count)) \ + : "r" ((USItype) (x) >> 16)); \ + else \ + { \ + __asm__ ("clz %0,%1" \ + : "=r" ((USItype) (count)) \ + : "r" ((USItype) (x))); \ + (count) += 16; \ + } \ + } while (0) +#endif + +#if defined (__sh2__) && W_TYPE_SIZE == 32 +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ( \ + "dmulu.l %2,%3\n\tsts macl,%1\n\tsts mach,%0" \ + : "=r" ((USItype)(w1)), \ + "=r" ((USItype)(w0)) \ + : "r" ((USItype)(u)), \ + "r" ((USItype)(v)) \ + : "macl", "mach") +#define UMUL_TIME 5 +#endif + +#if defined (__SH5__) && __SHMEDIA__ && W_TYPE_SIZE == 32 +#define __umulsidi3(u,v) ((UDItype)(USItype)u*(USItype)v) +#define count_leading_zeros(count, x) \ + do \ + { \ + UDItype x_ = (USItype)(x); \ + SItype c_; \ + \ + __asm__ ("nsb %1, %0" : "=r" (c_) : "r" (x_)); \ + (count) = c_ - 31; \ + } \ + while (0) +#define COUNT_LEADING_ZEROS_0 32 +#endif + +#if defined (__sparc__) && !defined (__arch64__) && !defined (__sparcv9) \ + && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addcc %r4,%5,%1\n\taddx %r2,%3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%rJ" ((USItype) (ah)), \ + "rI" ((USItype) (bh)), \ + "%rJ" ((USItype) (al)), \ + "rI" ((USItype) (bl)) \ + __CLOBBER_CC) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subcc %r4,%5,%1\n\tsubx %r2,%3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "rJ" ((USItype) (ah)), \ + "rI" ((USItype) (bh)), \ + "rJ" ((USItype) (al)), \ + "rI" ((USItype) (bl)) \ + __CLOBBER_CC) +#if defined (__sparc_v8__) +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("umul %2,%3,%1;rd %%y,%0" \ + : "=r" ((USItype) (w1)), \ + "=r" ((USItype) (w0)) \ + : "r" ((USItype) (u)), \ + "r" ((USItype) (v))) +#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \ + __asm__ ("mov %2,%%y;nop;nop;nop;udiv %3,%4,%0;umul %0,%4,%1;sub %3,%1,%1"\ + : "=&r" ((USItype) (__q)), \ + "=&r" ((USItype) (__r)) \ + : "r" ((USItype) (__n1)), \ + "r" ((USItype) (__n0)), \ + "r" ((USItype) (__d))) +#else +#if defined (__sparclite__) +/* This has hardware multiply but not divide. It also has two additional + instructions scan (ffs from high bit) and divscc. */ +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("umul %2,%3,%1;rd %%y,%0" \ + : "=r" ((USItype) (w1)), \ + "=r" ((USItype) (w0)) \ + : "r" ((USItype) (u)), \ + "r" ((USItype) (v))) +#define udiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("! Inlined udiv_qrnnd\n" \ +" wr %%g0,%2,%%y ! Not a delayed write for sparclite\n" \ +" tst %%g0\n" \ +" divscc %3,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%0\n" \ +" rd %%y,%1\n" \ +" bl,a 1f\n" \ +" add %1,%4,%1\n" \ +"1: ! End of inline udiv_qrnnd" \ + : "=r" ((USItype) (q)), \ + "=r" ((USItype) (r)) \ + : "r" ((USItype) (n1)), \ + "r" ((USItype) (n0)), \ + "rI" ((USItype) (d)) \ + : "g1" __AND_CLOBBER_CC) +#define UDIV_TIME 37 +#define count_leading_zeros(count, x) \ + do { \ + __asm__ ("scan %1,1,%0" \ + : "=r" ((USItype) (count)) \ + : "r" ((USItype) (x))); \ + } while (0) +/* Early sparclites return 63 for an argument of 0, but they warn that future + implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0 + undefined. */ +#else +/* SPARC without integer multiplication and divide instructions. + (i.e. at least Sun4/20,40,60,65,75,110,260,280,330,360,380,470,490) */ +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("! Inlined umul_ppmm\n" \ +" wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr\n"\ +" sra %3,31,%%o5 ! Don't move this insn\n" \ +" and %2,%%o5,%%o5 ! Don't move this insn\n" \ +" andcc %%g0,0,%%g1 ! Don't move this insn\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,0,%%g1\n" \ +" add %%g1,%%o5,%0\n" \ +" rd %%y,%1" \ + : "=r" ((USItype) (w1)), \ + "=r" ((USItype) (w0)) \ + : "%rI" ((USItype) (u)), \ + "r" ((USItype) (v)) \ + : "g1", "o5" __AND_CLOBBER_CC) +#define UMUL_TIME 39 /* 39 instructions */ +/* It's quite necessary to add this much assembler for the sparc. + The default udiv_qrnnd (in C) is more than 10 times slower! */ +#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \ + __asm__ ("! Inlined udiv_qrnnd\n" \ +" mov 32,%%g1\n" \ +" subcc %1,%2,%%g0\n" \ +"1: bcs 5f\n" \ +" addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n" \ +" sub %1,%2,%1 ! this kills msb of n\n" \ +" addx %1,%1,%1 ! so this can't give carry\n" \ +" subcc %%g1,1,%%g1\n" \ +"2: bne 1b\n" \ +" subcc %1,%2,%%g0\n" \ +" bcs 3f\n" \ +" addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n" \ +" b 3f\n" \ +" sub %1,%2,%1 ! this kills msb of n\n" \ +"4: sub %1,%2,%1\n" \ +"5: addxcc %1,%1,%1\n" \ +" bcc 2b\n" \ +" subcc %%g1,1,%%g1\n" \ +"! Got carry from n. Subtract next step to cancel this carry.\n" \ +" bne 4b\n" \ +" addcc %0,%0,%0 ! shift n1n0 and a 0-bit in lsb\n" \ +" sub %1,%2,%1\n" \ +"3: xnor %0,0,%0\n" \ +" ! End of inline udiv_qrnnd" \ + : "=&r" ((USItype) (__q)), \ + "=&r" ((USItype) (__r)) \ + : "r" ((USItype) (__d)), \ + "1" ((USItype) (__n1)), \ + "0" ((USItype) (__n0)) : "g1" __AND_CLOBBER_CC) +#define UDIV_TIME (3+7*32) /* 7 instructions/iteration. 32 iterations. */ +#endif /* __sparclite__ */ +#endif /* __sparc_v8__ */ +#endif /* sparc32 */ + +#if ((defined (__sparc__) && defined (__arch64__)) || defined (__sparcv9)) \ + && W_TYPE_SIZE == 64 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addcc %r4,%5,%1\n\t" \ + "add %r2,%3,%0\n\t" \ + "bcs,a,pn %%xcc, 1f\n\t" \ + "add %0, 1, %0\n" \ + "1:" \ + : "=r" ((UDItype)(sh)), \ + "=&r" ((UDItype)(sl)) \ + : "%rJ" ((UDItype)(ah)), \ + "rI" ((UDItype)(bh)), \ + "%rJ" ((UDItype)(al)), \ + "rI" ((UDItype)(bl)) \ + __CLOBBER_CC) + +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subcc %r4,%5,%1\n\t" \ + "sub %r2,%3,%0\n\t" \ + "bcs,a,pn %%xcc, 1f\n\t" \ + "sub %0, 1, %0\n\t" \ + "1:" \ + : "=r" ((UDItype)(sh)), \ + "=&r" ((UDItype)(sl)) \ + : "rJ" ((UDItype)(ah)), \ + "rI" ((UDItype)(bh)), \ + "rJ" ((UDItype)(al)), \ + "rI" ((UDItype)(bl)) \ + __CLOBBER_CC) + +#define umul_ppmm(wh, wl, u, v) \ + do { \ + UDItype tmp1, tmp2, tmp3, tmp4; \ + __asm__ __volatile__ ( \ + "srl %7,0,%3\n\t" \ + "mulx %3,%6,%1\n\t" \ + "srlx %6,32,%2\n\t" \ + "mulx %2,%3,%4\n\t" \ + "sllx %4,32,%5\n\t" \ + "srl %6,0,%3\n\t" \ + "sub %1,%5,%5\n\t" \ + "srlx %5,32,%5\n\t" \ + "addcc %4,%5,%4\n\t" \ + "srlx %7,32,%5\n\t" \ + "mulx %3,%5,%3\n\t" \ + "mulx %2,%5,%5\n\t" \ + "sethi %%hi(0x80000000),%2\n\t" \ + "addcc %4,%3,%4\n\t" \ + "srlx %4,32,%4\n\t" \ + "add %2,%2,%2\n\t" \ + "movcc %%xcc,%%g0,%2\n\t" \ + "addcc %5,%4,%5\n\t" \ + "sllx %3,32,%3\n\t" \ + "add %1,%3,%1\n\t" \ + "add %5,%2,%0" \ + : "=r" ((UDItype)(wh)), \ + "=&r" ((UDItype)(wl)), \ + "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4) \ + : "r" ((UDItype)(u)), \ + "r" ((UDItype)(v)) \ + __CLOBBER_CC); \ + } while (0) +#define UMUL_TIME 96 +#define UDIV_TIME 230 +#endif /* sparc64 */ + +#if defined (__vax__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addl2 %5,%1\n\tadwc %3,%0" \ + : "=g" ((USItype) (sh)), \ + "=&g" ((USItype) (sl)) \ + : "%0" ((USItype) (ah)), \ + "g" ((USItype) (bh)), \ + "%1" ((USItype) (al)), \ + "g" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subl2 %5,%1\n\tsbwc %3,%0" \ + : "=g" ((USItype) (sh)), \ + "=&g" ((USItype) (sl)) \ + : "0" ((USItype) (ah)), \ + "g" ((USItype) (bh)), \ + "1" ((USItype) (al)), \ + "g" ((USItype) (bl))) +#define umul_ppmm(xh, xl, m0, m1) \ + do { \ + union { \ + UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + USItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("emul %1,%2,$0,%0" \ + : "=r" (__xx.__ll) \ + : "g" (__m0), \ + "g" (__m1)); \ + (xh) = __xx.__i.__h; \ + (xl) = __xx.__i.__l; \ + (xh) += ((((SItype) __m0 >> 31) & __m1) \ + + (((SItype) __m1 >> 31) & __m0)); \ + } while (0) +#define sdiv_qrnnd(q, r, n1, n0, d) \ + do { \ + union {DItype __ll; \ + struct {SItype __l, __h;} __i; \ + } __xx; \ + __xx.__i.__h = n1; __xx.__i.__l = n0; \ + __asm__ ("ediv %3,%2,%0,%1" \ + : "=g" (q), "=g" (r) \ + : "g" (__xx.__ll), "g" (d)); \ + } while (0) +#endif /* __vax__ */ + +#if defined (__z8000__) && W_TYPE_SIZE == 16 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \ + : "=r" ((unsigned int)(sh)), \ + "=&r" ((unsigned int)(sl)) \ + : "%0" ((unsigned int)(ah)), \ + "r" ((unsigned int)(bh)), \ + "%1" ((unsigned int)(al)), \ + "rQR" ((unsigned int)(bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \ + : "=r" ((unsigned int)(sh)), \ + "=&r" ((unsigned int)(sl)) \ + : "0" ((unsigned int)(ah)), \ + "r" ((unsigned int)(bh)), \ + "1" ((unsigned int)(al)), \ + "rQR" ((unsigned int)(bl))) +#define umul_ppmm(xh, xl, m0, m1) \ + do { \ + union {long int __ll; \ + struct {unsigned int __h, __l;} __i; \ + } __xx; \ + unsigned int __m0 = (m0), __m1 = (m1); \ + __asm__ ("mult %S0,%H3" \ + : "=r" (__xx.__i.__h), \ + "=r" (__xx.__i.__l) \ + : "%1" (__m0), \ + "rQR" (__m1)); \ + (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ + (xh) += ((((signed int) __m0 >> 15) & __m1) \ + + (((signed int) __m1 >> 15) & __m0)); \ + } while (0) +#endif /* __z8000__ */ + +#endif /* __GNUC__ */ + +/* If this machine has no inline assembler, use C macros. */ + +#if !defined (add_ssaaaa) +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + do { \ + UWtype __x; \ + __x = (al) + (bl); \ + (sh) = (ah) + (bh) + (__x < (al)); \ + (sl) = __x; \ + } while (0) +#endif + +#if !defined (sub_ddmmss) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + UWtype __x; \ + __x = (al) - (bl); \ + (sh) = (ah) - (bh) - (__x > (al)); \ + (sl) = __x; \ + } while (0) +#endif + +#if !defined (umul_ppmm) +#define umul_ppmm(w1, w0, u, v) \ + do { \ + UWtype __x0, __x1, __x2, __x3; \ + UHWtype __ul, __vl, __uh, __vh; \ + \ + __ul = __ll_lowpart (u); \ + __uh = __ll_highpart (u); \ + __vl = __ll_lowpart (v); \ + __vh = __ll_highpart (v); \ + \ + __x0 = (UWtype) __ul * __vl; \ + __x1 = (UWtype) __ul * __vh; \ + __x2 = (UWtype) __uh * __vl; \ + __x3 = (UWtype) __uh * __vh; \ + \ + __x1 += __ll_highpart (__x0);/* this can't give carry */ \ + __x1 += __x2; /* but this indeed can */ \ + if (__x1 < __x2) /* did we get it? */ \ + __x3 += __ll_B; /* yes, add it in the proper pos. */ \ + \ + (w1) = __x3 + __ll_highpart (__x1); \ + (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ + } while (0) +#endif + +#if !defined (__umulsidi3) +#define __umulsidi3(u, v) \ + ({DWunion __w; \ + umul_ppmm (__w.s.high, __w.s.low, u, v); \ + __w.ll; }) +#endif + +/* Define this unconditionally, so it can be used for debugging. */ +#define __udiv_qrnnd_c(q, r, n1, n0, d) \ + do { \ + UWtype __d1, __d0, __q1, __q0; \ + UWtype __r1, __r0, __m; \ + __d1 = __ll_highpart (d); \ + __d0 = __ll_lowpart (d); \ + \ + __r1 = (n1) % __d1; \ + __q1 = (n1) / __d1; \ + __m = (UWtype) __q1 * __d0; \ + __r1 = __r1 * __ll_B | __ll_highpart (n0); \ + if (__r1 < __m) \ + { \ + __q1--, __r1 += (d); \ + if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ + if (__r1 < __m) \ + __q1--, __r1 += (d); \ + } \ + __r1 -= __m; \ + \ + __r0 = __r1 % __d1; \ + __q0 = __r1 / __d1; \ + __m = (UWtype) __q0 * __d0; \ + __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ + if (__r0 < __m) \ + { \ + __q0--, __r0 += (d); \ + if (__r0 >= (d)) \ + if (__r0 < __m) \ + __q0--, __r0 += (d); \ + } \ + __r0 -= __m; \ + \ + (q) = (UWtype) __q1 * __ll_B | __q0; \ + (r) = __r0; \ + } while (0) + +/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through + __udiv_w_sdiv (defined in libgcc or elsewhere). */ +#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd) +#define udiv_qrnnd(q, r, nh, nl, d) \ + do { \ + USItype __r; \ + (q) = __udiv_w_sdiv (&__r, nh, nl, d); \ + (r) = __r; \ + } while (0) +#endif + +/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */ +#if !defined (udiv_qrnnd) +#define UDIV_NEEDS_NORMALIZATION 1 +#define udiv_qrnnd __udiv_qrnnd_c +#endif + +#if !defined (count_leading_zeros) +extern const UQItype __clz_tab[]; +#define count_leading_zeros(count, x) \ + do { \ + UWtype __xr = (x); \ + UWtype __a; \ + \ + if (W_TYPE_SIZE <= 32) \ + { \ + __a = __xr < ((UWtype)1<<2*__BITS4) \ + ? (__xr < ((UWtype)1<<__BITS4) ? 0 : __BITS4) \ + : (__xr < ((UWtype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \ + } \ + else \ + { \ + for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \ + if (((__xr >> __a) & 0xff) != 0) \ + break; \ + } \ + \ + (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \ + } while (0) +#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE +#endif + +#if !defined (count_trailing_zeros) +/* Define count_trailing_zeros using count_leading_zeros. The latter might be + defined in asm, but if it is not, the C version above is good enough. */ +#define count_trailing_zeros(count, x) \ + do { \ + UWtype __ctz_x = (x); \ + UWtype __ctz_c; \ + count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \ + (count) = W_TYPE_SIZE - 1 - __ctz_c; \ + } while (0) +#endif + +#ifndef UDIV_NEEDS_NORMALIZATION +#define UDIV_NEEDS_NORMALIZATION 0 +#endif --- linux-2.6.28.orig/ubuntu/ndiswrapper/winnt_types.h +++ linux-2.6.28/ubuntu/ndiswrapper/winnt_types.h @@ -0,0 +1,1702 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#ifndef _WINNT_TYPES_H_ +#define _WINNT_TYPES_H_ + +#define TRUE 1 +#define FALSE 0 + +#define PASSIVE_LEVEL 0 +#define APC_LEVEL 1 +#define DISPATCH_LEVEL 2 +#define DEVICE_LEVEL_BASE 4 + +/* soft interrupts / bottom-half's are disabled at SOFT_IRQL */ +#define SOFT_IRQL (DEVICE_LEVEL_BASE + 1) +#define DIRQL (DEVICE_LEVEL_BASE + 2) + +#define STATUS_WAIT_0 0 +#define STATUS_SUCCESS 0 +#define STATUS_ALERTED 0x00000101 +#define STATUS_TIMEOUT 0x00000102 +#define STATUS_PENDING 0x00000103 +#define STATUS_FAILURE 0xC0000001 +#define STATUS_NOT_IMPLEMENTED 0xC0000002 +#define STATUS_INVALID_PARAMETER 0xC000000D +#define STATUS_INVALID_DEVICE_REQUEST 0xC0000010 +#define STATUS_MORE_PROCESSING_REQUIRED 0xC0000016 +#define STATUS_ACCESS_DENIED 0xC0000022 +#define STATUS_BUFFER_TOO_SMALL 0xC0000023 +#define STATUS_OBJECT_NAME_INVALID 0xC0000023 +#define STATUS_MUTANT_NOT_OWNED 0xC0000046 +#define STATUS_RESOURCES 0xC000009A +#define STATUS_DELETE_PENDING 0xC0000056 +#define STATUS_INSUFFICIENT_RESOURCES 0xC000009A +#define STATUS_NOT_SUPPORTED 0xC00000BB +#define STATUS_INVALID_PARAMETER_2 0xC00000F0 +#define STATUS_NO_MEMORY 0xC0000017 +#define STATUS_CANCELLED 0xC0000120 +#define STATUS_DEVICE_REMOVED 0xC00002B6 +#define STATUS_DEVICE_NOT_CONNECTED 0xC000009D + +#define STATUS_BUFFER_OVERFLOW 0x80000005 + +#define SL_PENDING_RETURNED 0x01 +#define SL_INVOKE_ON_CANCEL 0x20 +#define SL_INVOKE_ON_SUCCESS 0x40 +#define SL_INVOKE_ON_ERROR 0x80 + +#define IRP_MJ_CREATE 0x00 +#define IRP_MJ_CREATE_NAMED_PIPE 0x01 +#define IRP_MJ_CLOSE 0x02 +#define IRP_MJ_READ 0x03 +#define IRP_MJ_WRITE 0x04 + +#define IRP_MJ_DEVICE_CONTROL 0x0E +#define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0F +#define IRP_MJ_POWER 0x16 +#define IRP_MJ_SYSTEM_CONTROL 0x0E +#define IRP_MJ_PNP 0x1b +#define IRP_MJ_MAXIMUM_FUNCTION 0x1b + +#define IRP_MN_WAIT_WAKE 0x00 +#define IRP_MN_POWER_SEQUENCE 0x01 +#define IRP_MN_SET_POWER 0x02 +#define IRP_MN_QUERY_POWER 0x03 + +#define IRP_MN_REGINFO 0x08 +#define IRP_MN_REGINFO_EX 0x0b + +#define IRP_MN_START_DEVICE 0x00 +#define IRP_MN_QUERY_REMOVE_DEVICE 0x01 +#define IRP_MN_REMOVE_DEVICE 0x02 +#define IRP_MN_CANCEL_REMOVE_DEVICE 0x03 +#define IRP_MN_STOP_DEVICE 0x04 +#define IRP_MN_QUERY_STOP_DEVICE 0x05 +#define IRP_MN_CANCEL_STOP_DEVICE 0x06 +#define IRP_MN_QUERY_DEVICE_RELATIONS 0x07 +#define IRP_MN_QUERY_INTERFACE 0x08 + +#define IRP_BUFFERED_IO 0x00000010 +#define IRP_DEALLOCATE_BUFFER 0x00000020 +#define IRP_INPUT_OPERATION 0x00000040 + +#define IRP_DEFFER_IO_COMPLETION 0x00000800 + +#define THREAD_WAIT_OBJECTS 3 +#define MAX_WAIT_OBJECTS 64 + +#define LOW_PRIORITY 0 +#define LOW_REALTIME_PRIORITY 16 +#define HIGH_PRIORITY 31 +#define MAXIMUM_PRIORITY 32 + +#define PROCESSOR_FEATURE_MAX 64 + +#define IO_NO_INCREMENT 0 + +#define WMIREG_ACTION_REGISTER 1 +#define WMIREG_ACTION_DEREGISTER 2 +#define WMIREG_ACTION_REREGISTER 3 +#define WMIREG_ACTION_UPDATE_GUIDS 4 + +#define WMIREGISTER 0 +#define WMIUPDATE 1 + +#ifdef CONFIG_X86_64 +#define wstdcall +#define wfastcall +#define noregparm + +#define KI_USER_SHARED_DATA 0xfffff78000000000UL + +#else + +#define noregparm __attribute__((regparm(0))) +#define wstdcall __attribute__((__stdcall__, regparm(0))) +#if defined(__GNUC__) && ((__GNUC__ == 3 && __GNUC_MINOR__ > 3) || __GNUC__ > 3) +#undef fastcall +#define wfastcall __attribute__((fastcall)) +#else +#error "gcc 3.4 or newer should be used for compiling this module" +#endif + +#define KI_USER_SHARED_DATA 0xffdf0000 + +#endif + +#define packed __attribute__((packed)) +#define no_warn_unused __attribute__((unused)) + +typedef u8 BOOLEAN; +typedef u8 BYTE; +typedef u8 *LPBYTE; +typedef s8 CHAR; +typedef u8 UCHAR; +typedef s16 SHORT; +typedef u16 USHORT; +typedef u16 WORD; +typedef s32 INT; +typedef u32 UINT; +typedef u32 DWORD; +typedef s32 LONG; +typedef u32 ULONG; +typedef s64 LONGLONG; +typedef u64 ULONGLONG; +typedef u64 ULONGULONG; +typedef u64 ULONG64; + +typedef CHAR CCHAR; +typedef USHORT wchar_t; +typedef SHORT CSHORT; +typedef LONGLONG LARGE_INTEGER; + +typedef LONG NTSTATUS; + +typedef LONG KPRIORITY; +typedef LARGE_INTEGER PHYSICAL_ADDRESS; +typedef UCHAR KIRQL; +typedef CHAR KPROCESSOR_MODE; + +/* ULONG_PTR is 32 bits on 32-bit platforms and 64 bits on 64-bit + * platform, which is same as 'unsigned long' in Linux */ +typedef unsigned long ULONG_PTR; + +typedef ULONG_PTR SIZE_T; +typedef ULONG_PTR KAFFINITY; +typedef ULONG ACCESS_MASK; + +typedef ULONG_PTR PFN_NUMBER; +typedef ULONG SECURITY_INFORMATION; + +/* non-negative numbers indicate success */ +#define NT_SUCCESS(status) ((NTSTATUS)(status) >= 0) + +struct ansi_string { + USHORT length; + USHORT max_length; + char *buf; +}; + +struct unicode_string { + USHORT length; + USHORT max_length; + wchar_t *buf; +}; + +struct nt_slist { + struct nt_slist *next; +}; + +#ifdef CONFIG_X86_64 +/* it is not clear how nt_slist_head is used to store pointer to + * slists and depth; here we assume 'align' field is used to store + * depth and 'region' field is used to store slist pointers */ +struct nt_slist_head { + union { + USHORT depth; + ULONGLONG align; + }; + union { + ULONGLONG region; + struct nt_slist *next; + }; +} __attribute__((aligned(16))); +typedef struct nt_slist_head nt_slist_header; +#else +union nt_slist_head { + ULONGLONG align; + struct { + struct nt_slist *next; + USHORT depth; + USHORT sequence; + }; +}; +typedef union nt_slist_head nt_slist_header; +#endif + +struct nt_list { + struct nt_list *next; + struct nt_list *prev; +}; + +typedef ULONG_PTR NT_SPIN_LOCK; + +enum kdpc_importance {LowImportance, MediumImportance, HighImportance}; + +struct kdpc; +typedef void (*DPC)(struct kdpc *kdpc, void *ctx, void *arg1, + void *arg2) wstdcall; +struct kdpc { + SHORT type; + UCHAR nr_cpu; + UCHAR importance; + struct nt_list list; + DPC func; + void *ctx; + void *arg1; + void *arg2; + union { + NT_SPIN_LOCK *lock; + /* 'lock' is not used; 'queued' represents whether + * kdpc is queued or not */ + int queued; + }; +}; + +enum pool_type { + NonPagedPool, PagedPool, NonPagedPoolMustSucceed, DontUseThisType, + NonPagedPoolCacheAligned, PagedPoolCacheAligned, + NonPagedPoolCacheAlignedMustS, MaxPoolType, + NonPagedPoolSession = 32, + PagedPoolSession = NonPagedPoolSession + 1, + NonPagedPoolMustSucceedSession = PagedPoolSession + 1, + DontUseThisTypeSession = NonPagedPoolMustSucceedSession + 1, + NonPagedPoolCacheAlignedSession = DontUseThisTypeSession + 1, + PagedPoolCacheAlignedSession = NonPagedPoolCacheAlignedSession + 1, + NonPagedPoolCacheAlignedMustSSession = PagedPoolCacheAlignedSession + 1 +}; + +enum memory_caching_type_orig { + MmFrameBufferCached = 2 +}; + +enum memory_caching_type { + MmNonCached = FALSE, MmCached = TRUE, + MmWriteCombined = MmFrameBufferCached, MmHardwareCoherentCached, + MmNonCachedUnordered, MmUSWCCached, MmMaximumCacheType +}; + +enum lock_operation { + IoReadAccess, IoWriteAccess, IoModifyAccess +}; + +enum mode { + KernelMode, UserMode, MaximumMode +}; + +struct mdl { + struct mdl *next; + CSHORT size; + CSHORT flags; + /* NdisFreeBuffer doesn't pass pool, so we store pool in + * unused field 'process' */ + union { + void *process; + void *pool; + }; + void *mappedsystemva; + void *startva; + ULONG bytecount; + ULONG byteoffset; +}; + +#define MDL_MAPPED_TO_SYSTEM_VA 0x0001 +#define MDL_PAGES_LOCKED 0x0002 +#define MDL_SOURCE_IS_NONPAGED_POOL 0x0004 +#define MDL_ALLOCATED_FIXED_SIZE 0x0008 +#define MDL_PARTIAL 0x0010 +#define MDL_PARTIAL_HAS_BEEN_MAPPED 0x0020 +#define MDL_IO_PAGE_READ 0x0040 +#define MDL_WRITE_OPERATION 0x0080 +#define MDL_PARENT_MAPPED_SYSTEM_VA 0x0100 +#define MDL_FREE_EXTRA_PTES 0x0200 +#define MDL_IO_SPACE 0x0800 +#define MDL_NETWORK_HEADER 0x1000 +#define MDL_MAPPING_CAN_FAIL 0x2000 +#define MDL_ALLOCATED_MUST_SUCCEED 0x4000 + +#define MDL_POOL_ALLOCATED 0x0400 +#define MDL_CACHE_ALLOCATED 0x8000 + +#define PAGE_START(ptr) ((void *)((ULONG_PTR)(ptr) & ~(PAGE_SIZE - 1))) +#define BYTE_OFFSET(ptr) ((ULONG)((ULONG_PTR)(ptr) & (PAGE_SIZE - 1))) + +#define MmGetMdlByteCount(mdl) ((mdl)->bytecount) +#define MmGetMdlVirtualAddress(mdl) ((mdl)->startva + (mdl)->byteoffset) +#define MmGetMdlByteOffset(mdl) ((mdl)->byteoffset) +#define MmGetSystemAddressForMdl(mdl) ((mdl)->mappedsystemva) +#define MmGetSystemAddressForMdlSafe(mdl, priority) ((mdl)->mappedsystemva) +#define MmGetMdlPfnArray(mdl) ((PFN_NUMBER *)(mdl + 1)) +#define MmInitializeMdl(mdl, baseva, length) \ +do { \ + (mdl)->next = NULL; \ + (mdl)->size = MmSizeOfMdl(baseva, length); \ + (mdl)->flags = 0; \ + (mdl)->startva = PAGE_START(baseva); \ + (mdl)->byteoffset = BYTE_OFFSET(baseva); \ + (mdl)->bytecount = length; \ + (mdl)->mappedsystemva = baseva; \ + TRACE4("%p %p %p %d %d", (mdl), baseva, (mdl)->startva, \ + (mdl)->byteoffset, length); \ +} while (0) + +struct kdevice_queue_entry { + struct nt_list list; + ULONG sort_key; + BOOLEAN inserted; +}; + +struct kdevice_queue { + USHORT type; + USHORT size; + struct nt_list list; + NT_SPIN_LOCK lock; + BOOLEAN busy; +}; + +struct wait_context_block { + struct kdevice_queue_entry wait_queue_entry; + void *device_routine; + void *device_context; + ULONG num_regs; + void *device_object; + void *current_irp; + void *buffer_chaining_dpc; +}; + +struct wait_block { + struct nt_list list; + struct task_struct *thread; + void *object; + int *wait_done; + USHORT wait_key; + USHORT wait_type; +}; + +struct dispatcher_header { + UCHAR type; + UCHAR absolute; + UCHAR size; + UCHAR inserted; + LONG signal_state; + struct nt_list wait_blocks; +}; + +enum event_type { + NotificationEvent, + SynchronizationEvent, +}; + +enum timer_type { + NotificationTimer = NotificationEvent, + SynchronizationTimer = SynchronizationEvent, +}; + +enum dh_type { + NotificationObject = NotificationEvent, + SynchronizationObject = SynchronizationEvent, + MutexObject, + SemaphoreObject, + ThreadObject, +}; + +enum wait_type { + WaitAll, WaitAny +}; + +/* objects that use dispatcher_header have it as the first field, so + * whenever we need to initialize dispatcher_header, we can convert + * that object into a nt_event and access dispatcher_header */ +struct nt_event { + struct dispatcher_header dh; +}; + +struct wrap_timer; + +#define WRAP_TIMER_MAGIC 47697249 + +struct nt_timer { + struct dispatcher_header dh; + /* We can't fit Linux timer in this structure. Instead of + * padding the nt_timer structure, we replace due_time field + * with *wrap_timer and allocate memory for it when nt_timer is + * initialized */ + union { + ULONGLONG due_time; + struct wrap_timer *wrap_timer; + }; + struct nt_list nt_timer_list; + struct kdpc *kdpc; + union { + LONG period; + LONG wrap_timer_magic; + }; +}; + +struct nt_mutex { + struct dispatcher_header dh; + struct nt_list list; + struct task_struct *owner_thread; + BOOLEAN abandoned; + BOOLEAN apc_disable; +}; + +struct nt_semaphore { + struct dispatcher_header dh; + LONG limit; +}; + +struct nt_thread { + struct dispatcher_header dh; + /* the rest in Windows is a long structure; since this + * structure is opaque to drivers, we just define what we + * need */ + int pid; + NTSTATUS status; + struct task_struct *task; + struct nt_list irps; + NT_SPIN_LOCK lock; + KPRIORITY prio; +}; + +#define set_object_type(dh, type) ((dh)->type = (type)) +#define is_notify_object(dh) ((dh)->type == NotificationObject) +#define is_synch_object(dh) ((dh)->type == SynchronizationObject) +#define is_mutex_object(dh) ((dh)->type == MutexObject) +#define is_semaphore_object(dh) ((dh)->type == SemaphoreObject) +#define is_nt_thread_object(dh) ((dh)->type == ThreadObject) + +#define IO_TYPE_ADAPTER 1 +#define IO_TYPE_CONTROLLER 2 +#define IO_TYPE_DEVICE 3 +#define IO_TYPE_DRIVER 4 +#define IO_TYPE_FILE 5 +#define IO_TYPE_IRP 6 +#define IO_TYPE_DEVICE_OBJECT_EXTENSION 13 + +struct irp; +struct dev_obj_ext; +struct driver_object; + +struct device_object { + CSHORT type; + USHORT size; + LONG ref_count; + struct driver_object *drv_obj; + struct device_object *next; + struct device_object *attached; + struct irp *current_irp; + void *io_timer; + ULONG flags; + ULONG characteristics; + void *vpb; + void *dev_ext; + CCHAR stack_count; + union { + struct nt_list queue_list; + struct wait_context_block wcb; + } queue; + ULONG align_req; + struct kdevice_queue dev_queue; + struct kdpc dpc; + ULONG active_threads; + void *security_desc; + struct nt_event lock; + USHORT sector_size; + USHORT spare1; + struct dev_obj_ext *dev_obj_ext; + void *reserved; +}; + +struct dev_obj_ext { + CSHORT type; + CSHORT size; + struct device_object *dev_obj; + struct device_object *attached_to; +}; + +struct io_status_block { + union { + NTSTATUS status; + void *pointer; + }; + ULONG_PTR info; +}; + +#ifdef CONFIG_X86_64 +struct io_status_block32 { + NTSTATUS status; + ULONG info; +}; +#endif + +#define DEVICE_TYPE ULONG + +struct driver_extension; + +typedef NTSTATUS driver_dispatch_t(struct device_object *dev_obj, + struct irp *irp) wstdcall; + +struct driver_object { + CSHORT type; + CSHORT size; + struct device_object *dev_obj; + ULONG flags; + void *start; + ULONG driver_size; + void *section; + struct driver_extension *drv_ext; + struct unicode_string name; + struct unicode_string *hardware_database; + void *fast_io_dispatch; + void *init; + void *start_io; + void (*unload)(struct driver_object *driver) wstdcall; + driver_dispatch_t *major_func[IRP_MJ_MAXIMUM_FUNCTION + 1]; +}; + +struct driver_extension { + struct driver_object *drv_obj; + NTSTATUS (*add_device)(struct driver_object *drv_obj, + struct device_object *dev_obj) wstdcall; + ULONG count; + struct unicode_string service_key_name; + struct nt_list custom_ext; +}; + +struct custom_ext { + struct nt_list list; + void *client_id; +}; + +struct wrap_bin_file; + +struct file_object { + CSHORT type; + CSHORT size; + struct device_object *dev_obj; + void *volume_parameter_block; + void *fs_context; + void *fs_context2; + void *section_object_pointer; + void *private_cache_map; + NTSTATUS final_status; + union { + struct file_object *related_file_object; + struct wrap_bin_file *wrap_bin_file; + }; + BOOLEAN lock_operation; + BOOLEAN delete_pending; + BOOLEAN read_access; + BOOLEAN write_access; + BOOLEAN delete_access; + BOOLEAN shared_read; + BOOLEAN shared_write; + BOOLEAN shared_delete; + ULONG flags; + struct unicode_string _name_; + LARGE_INTEGER current_byte_offset; + ULONG waiters; + ULONG busy; + void *last_lock; + struct nt_event lock; + struct nt_event event; + void *completion_context; +}; + +#ifdef CONFIG_X86_64 +#define POINTER_ALIGN __attribute__((aligned(8))) +#else +#define POINTER_ALIGN +#endif + +#define CACHE_ALIGN __attribute__((aligned(128))) + +enum system_power_state { + PowerSystemUnspecified = 0, + PowerSystemWorking, PowerSystemSleeping1, PowerSystemSleeping2, + PowerSystemSleeping3, PowerSystemHibernate, PowerSystemShutdown, + PowerSystemMaximum, +}; + +enum device_power_state { + PowerDeviceUnspecified = 0, + PowerDeviceD0, PowerDeviceD1, PowerDeviceD2, PowerDeviceD3, + PowerDeviceMaximum, +}; + +union power_state { + enum system_power_state system_state; + enum device_power_state device_state; +}; + +enum power_state_type { + SystemPowerState = 0, DevicePowerState, +}; + +enum power_action { + PowerActionNone = 0, + PowerActionReserved, PowerActionSleep, PowerActionHibernate, + PowerActionShutdown, PowerActionShutdownReset, PowerActionShutdownOff, + PowerActionWarmEject, +}; + +struct guid { + ULONG data1; + USHORT data2; + USHORT data3; + UCHAR data4[8]; +}; + +struct nt_interface { + USHORT size; + USHORT version; + void *context; + void (*reference)(void *context) wstdcall; + void (*dereference)(void *context) wstdcall; +}; + +enum interface_type { + InterfaceTypeUndefined = -1, Internal, Isa, Eisa, MicroChannel, + TurboChannel, PCIBus, VMEBus, NuBus, PCMCIABus, CBus, MPIBus, + MPSABus, ProcessorInternal, InternalPowerBus, PNPISABus, + PNPBus, MaximumInterfaceType, +}; + +#define CmResourceTypeNull 0 +#define CmResourceTypePort 1 +#define CmResourceTypeInterrupt 2 +#define CmResourceTypeMemory 3 +#define CmResourceTypeDma 4 +#define CmResourceTypeDeviceSpecific 5 +#define CmResourceTypeBusNumber 6 +#define CmResourceTypeMaximum 7 + +#define CmResourceTypeNonArbitrated 128 +#define CmResourceTypeConfigData 128 +#define CmResourceTypeDevicePrivate 129 +#define CmResourceTypePcCardConfig 130 +#define CmResourceTypeMfCardConfig 131 + +enum cm_share_disposition { + CmResourceShareUndetermined = 0, CmResourceShareDeviceExclusive, + CmResourceShareDriverExclusive, CmResourceShareShared +}; + +#define CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE 0 +#define CM_RESOURCE_INTERRUPT_LATCHED 1 +#define CM_RESOURCE_MEMORY_READ_WRITE 0x0000 +#define CM_RESOURCE_MEMORY_READ_ONLY 0x0001 +#define CM_RESOURCE_MEMORY_WRITE_ONLY 0x0002 +#define CM_RESOURCE_MEMORY_PREFETCHABLE 0x0004 + +#define CM_RESOURCE_MEMORY_COMBINEDWRITE 0x0008 +#define CM_RESOURCE_MEMORY_24 0x0010 +#define CM_RESOURCE_MEMORY_CACHEABLE 0x0020 + +#define CM_RESOURCE_PORT_MEMORY 0x0000 +#define CM_RESOURCE_PORT_IO 0x0001 +#define CM_RESOURCE_PORT_10_BIT_DECODE 0x0004 +#define CM_RESOURCE_PORT_12_BIT_DECODE 0x0008 +#define CM_RESOURCE_PORT_16_BIT_DECODE 0x0010 +#define CM_RESOURCE_PORT_POSITIVE_DECODE 0x0020 +#define CM_RESOURCE_PORT_PASSIVE_DECODE 0x0040 +#define CM_RESOURCE_PORT_WINDOW_DECODE 0x0080 + +#define CM_RESOURCE_DMA_8 0x0000 +#define CM_RESOURCE_DMA_16 0x0001 +#define CM_RESOURCE_DMA_32 0x0002 +#define CM_RESOURCE_DMA_8_AND_16 0x0004 +#define CM_RESOURCE_DMA_BUS_MASTER 0x0008 +#define CM_RESOURCE_DMA_TYPE_A 0x0010 +#define CM_RESOURCE_DMA_TYPE_B 0x0020 +#define CM_RESOURCE_DMA_TYPE_F 0x0040 + +#define MAX_RESOURCES 20 + +#pragma pack(push,4) +struct cm_partial_resource_descriptor { + UCHAR type; + UCHAR share; + USHORT flags; + union { + struct { + PHYSICAL_ADDRESS start; + ULONG length; + } generic; + struct { + PHYSICAL_ADDRESS start; + ULONG length; + } port; + struct { + ULONG level; + ULONG vector; + KAFFINITY affinity; + } interrupt; + struct { + PHYSICAL_ADDRESS start; + ULONG length; + } memory; + struct { + ULONG channel; + ULONG port; + ULONG reserved1; + } dma; + struct { + ULONG data[3]; + } device_private; + struct { + ULONG start; + ULONG length; + ULONG reserved; + } bus_number; + struct { + ULONG data_size; + ULONG reserved1; + ULONG reserved2; + } device_specific_data; + } u; +}; +#pragma pack(pop) + +struct cm_partial_resource_list { + USHORT version; + USHORT revision; + ULONG count; + struct cm_partial_resource_descriptor partial_descriptors[1]; +}; + +struct cm_full_resource_descriptor { + enum interface_type interface_type; + ULONG bus_number; + struct cm_partial_resource_list partial_resource_list; +}; + +struct cm_resource_list { + ULONG count; + struct cm_full_resource_descriptor list[1]; +}; + +enum file_info_class { + FileDirectoryInformation = 1, + FileBasicInformation = 4, + FileStandardInformation = 5, + FileNameInformation = 9, + FilePositionInformation = 14, + FileAlignmentInformation = 17, + FileNetworkOpenInformation = 34, + FileAttributeTagInformation = 35, + FileMaximumInformation = 41, +}; + +enum fs_info_class { + FileFsVolumeInformation = 1, + /* ... */ + FileFsMaximumInformation = 9, +}; + +enum device_relation_type { + BusRelations, EjectionRelations, PowerRelations, RemovalRelations, + TargetDeviceRelation, SingleBusRelations, +}; + +enum bus_query_id_type { + BusQueryDeviceID = 0, BusQueryHardwareIDs = 1, + BusQueryCompatibleIDs = 2, BusQueryInstanceID = 3, + BusQueryDeviceSerialNumber = 4, +}; + +enum device_text_type { + DeviceTextDescription = 0, DeviceTextLocationInformation = 1, +}; + +enum device_usage_notification_type { + DeviceUsageTypeUndefined, DeviceUsageTypePaging, + DeviceUsageTypeHibernation, DevbiceUsageTypeDumpFile, +}; + +#define METHOD_BUFFERED 0 +#define METHOD_IN_DIRECT 1 +#define METHOD_OUT_DIRECT 2 +#define METHOD_NEITHER 3 + +#define CTL_CODE(dev_type, func, method, access) \ + (((dev_type) << 16) | ((access) << 14) | ((func) << 2) | (method)) + +#define IO_METHOD_FROM_CTL_CODE(code) (code & 0x3) + +#ifndef CONFIG_X86_64 +#pragma pack(push,4) +#endif +struct io_stack_location { + UCHAR major_fn; + UCHAR minor_fn; + UCHAR flags; + UCHAR control; + union { + struct { + void *security_context; + ULONG options; + USHORT POINTER_ALIGN file_attributes; + USHORT share_access; + ULONG POINTER_ALIGN ea_length; + } create; + struct { + ULONG length; + ULONG POINTER_ALIGN key; + LARGE_INTEGER byte_offset; + } read; + struct { + ULONG length; + ULONG POINTER_ALIGN key; + LARGE_INTEGER byte_offset; + } write; + struct { + ULONG length; + enum file_info_class POINTER_ALIGN file_info_class; + } query_file; + struct { + ULONG length; + enum file_info_class POINTER_ALIGN file_info_class; + struct file_object *file_object; + union { + struct { + BOOLEAN replace_if_exists; + BOOLEAN advance_only; + }; + ULONG cluster_count; + void *delete_handle; + }; + } set_file; + struct { + ULONG length; + enum fs_info_class POINTER_ALIGN fs_info_class; + } query_volume; + struct { + ULONG output_buf_len; + ULONG POINTER_ALIGN input_buf_len; + ULONG POINTER_ALIGN code; + void *type3_input_buf; + } dev_ioctl; + struct { + SECURITY_INFORMATION security_info; + ULONG POINTER_ALIGN length; + } query_security; + struct { + SECURITY_INFORMATION security_info; + void *security_descriptor; + } set_security; + struct { + void *vpb; + struct device_object *device_object; + } mount_volume; + struct { + void *vpb; + struct device_object *device_object; + } verify_volume; + struct { + void *srb; + } scsi; + struct { + enum device_relation_type type; + } query_device_relations; + struct { + const struct guid *type; + USHORT size; + USHORT version; + struct nt_interface *intf; + void *intf_data; + } query_intf; + struct { + void *capabilities; + } device_capabilities; + struct { + void *io_resource_requirement_list; + } filter_resource_requirements; + struct { + ULONG which_space; + void *buffer; + ULONG offset; + ULONG POINTER_ALIGN length; + } read_write_config; + struct { + BOOLEAN lock; + } set_lock; + struct { + enum bus_query_id_type id_type; + } query_id; + struct { + enum device_text_type device_text_type; + ULONG POINTER_ALIGN locale_id; + } query_device_text; + struct { + BOOLEAN in_path; + BOOLEAN reserved[3]; + enum device_usage_notification_type POINTER_ALIGN type; + } usage_notification; + struct { + enum system_power_state power_state; + } wait_wake; + struct { + void *power_sequence; + } power_sequence; + struct { + ULONG sys_context; + enum power_state_type POINTER_ALIGN type; + union power_state POINTER_ALIGN state; + enum power_action POINTER_ALIGN shutdown_type; + } power; + struct { + struct cm_resource_list *allocated_resources; + struct cm_resource_list *allocated_resources_translated; + } start_device; + struct { + ULONG_PTR provider_id; + void *data_path; + ULONG buf_len; + void *buf; + } wmi; + struct { + void *arg1; + void *arg2; + void *arg3; + void *arg4; + } others; + } params; + struct device_object *dev_obj; + struct file_object *file_obj; + NTSTATUS (*completion_routine)(struct device_object *, + struct irp *, void *) wstdcall; + void *context; +}; +#ifndef CONFIG_X86_64 +#pragma pack(pop) +#endif + +struct kapc { + CSHORT type; + CSHORT size; + ULONG spare0; + struct nt_thread *thread; + struct nt_list list; + void *kernele_routine; + void *rundown_routine; + void *normal_routine; + void *normal_context; + void *sys_arg1; + void *sys_arg2; + CCHAR apc_state_index; + KPROCESSOR_MODE apc_mode; + BOOLEAN inserted; +}; + +#define IRP_NOCACHE 0x00000001 +#define IRP_SYNCHRONOUS_API 0x00000004 +#define IRP_ASSOCIATED_IRP 0x00000008 + +enum urb_state { + URB_INVALID = 1, URB_ALLOCATED, URB_SUBMITTED, + URB_COMPLETED, URB_FREE, URB_SUSPEND, URB_INT_UNLINKED }; + +struct wrap_urb { + struct nt_list list; + enum urb_state state; + struct nt_list complete_list; + unsigned int flags; + struct urb *urb; + struct irp *irp; +#ifdef USB_DEBUG + unsigned int id; +#endif +}; + +struct irp { + SHORT type; + USHORT size; + struct mdl *mdl; + ULONG flags; + union { + struct irp *master_irp; + LONG irp_count; + void *system_buffer; + } associated_irp; + struct nt_list thread_list; + struct io_status_block io_status; + KPROCESSOR_MODE requestor_mode; + BOOLEAN pending_returned; + CHAR stack_count; + CHAR current_location; + BOOLEAN cancel; + KIRQL cancel_irql; + CCHAR apc_env; + UCHAR alloc_flags; + struct io_status_block *user_status; + struct nt_event *user_event; + union { + struct { + void *user_apc_routine; + void *user_apc_context; + } async_params; + LARGE_INTEGER alloc_size; + } overlay; + void (*cancel_routine)(struct device_object *, struct irp *) wstdcall; + void *user_buf; + union { + struct { + union { + struct kdevice_queue_entry dev_q_entry; + struct { + void *driver_context[4]; + }; + }; + void *thread; + char *aux_buf; + struct { + struct nt_list list; + union { + struct io_stack_location *csl; + ULONG packet_type; + }; + }; + struct file_object *file_object; + } overlay; + union { + struct kapc apc; + /* space for apc is used for ndiswrapper + * specific fields */ + struct { + struct wrap_urb *wrap_urb; + struct wrap_device *wrap_device; + }; + }; + void *completion_key; + } tail; +}; + +#define IoSizeOfIrp(stack_count) \ + ((USHORT)(sizeof(struct irp) + \ + ((stack_count) * sizeof(struct io_stack_location)))) +#define IoGetCurrentIrpStackLocation(irp) \ + (irp)->tail.overlay.csl +#define IoGetNextIrpStackLocation(irp) \ + (IoGetCurrentIrpStackLocation(irp) - 1) +#define IoGetPreviousIrpStackLocation(irp) \ + (IoGetCurrentIrpStackLocation(irp) + 1) + +#define IoSetNextIrpStackLocation(irp) \ +do { \ + KIRQL _irql_; \ + IoAcquireCancelSpinLock(&_irql_); \ + (irp)->current_location--; \ + IoGetCurrentIrpStackLocation(irp)--; \ + IoReleaseCancelSpinLock(_irql_); \ +} while (0) + +#define IoSkipCurrentIrpStackLocation(irp) \ +do { \ + KIRQL _irql_; \ + IoAcquireCancelSpinLock(&_irql_); \ + (irp)->current_location++; \ + IoGetCurrentIrpStackLocation(irp)++; \ + IoReleaseCancelSpinLock(_irql_); \ +} while (0) + +static inline void +IoCopyCurrentIrpStackLocationToNext(struct irp *irp) +{ + struct io_stack_location *next; + next = IoGetNextIrpStackLocation(irp); + memcpy(next, IoGetCurrentIrpStackLocation(irp), + offsetof(struct io_stack_location, completion_routine)); + next->control = 0; +} + +static inline void +IoSetCompletionRoutine(struct irp *irp, void *routine, void *context, + BOOLEAN success, BOOLEAN error, BOOLEAN cancel) +{ + struct io_stack_location *irp_sl = IoGetNextIrpStackLocation(irp); + irp_sl->completion_routine = routine; + irp_sl->context = context; + irp_sl->control = 0; + if (success) + irp_sl->control |= SL_INVOKE_ON_SUCCESS; + if (error) + irp_sl->control |= SL_INVOKE_ON_ERROR; + if (cancel) + irp_sl->control |= SL_INVOKE_ON_CANCEL; +} + +#define IoMarkIrpPending(irp) \ + (IoGetCurrentIrpStackLocation((irp))->control |= SL_PENDING_RETURNED) +#define IoUnmarkIrpPending(irp) \ + (IoGetCurrentIrpStackLocation((irp))->control &= ~SL_PENDING_RETURNED) + +#define IRP_SL(irp, n) (((struct io_stack_location *)((irp) + 1)) + (n)) +#define IRP_DRIVER_CONTEXT(irp) (irp)->tail.overlay.driver_context +#define IoIrpThread(irp) ((irp)->tail.overlay.thread) + +#define IRP_URB(irp) \ + (union nt_urb *)(IoGetCurrentIrpStackLocation(irp)->params.others.arg1) + +#define IRP_WRAP_DEVICE(irp) (irp)->tail.wrap_device +#define IRP_WRAP_URB(irp) (irp)->tail.wrap_urb + +struct wmi_guid_reg_info { + struct guid *guid; + ULONG instance_count; + ULONG flags; +}; + +struct wmilib_context { + ULONG guid_count; + struct wmi_guid_reg_info *guid_list; + void *query_wmi_reg_info; + void *query_wmi_data_block; + void *set_wmi_data_block; + void *set_wmi_data_item; + void *execute_wmi_method; + void *wmi_function_control; +}; + +enum key_value_information_class { + KeyValueBasicInformation, KeyValueFullInformation, + KeyValuePartialInformation, KeyValueFullInformationAlign64, + KeyValuePartialInformationAlign64 +}; + +struct file_name_info { + ULONG length; + wchar_t *name; +}; + +struct file_std_info { + LARGE_INTEGER alloc_size; + LARGE_INTEGER eof; + ULONG num_links; + BOOLEAN delete_pending; + BOOLEAN dir; +}; + +enum nt_obj_type { + NT_OBJ_EVENT = 10, NT_OBJ_MUTEX, NT_OBJ_THREAD, NT_OBJ_TIMER, + NT_OBJ_SEMAPHORE, +}; + +enum common_object_type { + OBJECT_TYPE_NONE, OBJECT_TYPE_DEVICE, OBJECT_TYPE_DRIVER, + OBJECT_TYPE_NT_THREAD, OBJECT_TYPE_FILE, OBJECT_TYPE_CALLBACK, +}; + +struct common_object_header { + struct nt_list list; + enum common_object_type type; + UINT size; + UINT ref_count; + BOOLEAN close_in_process; + BOOLEAN permanent; + struct unicode_string name; +}; + +#define OBJECT_TO_HEADER(object) \ + (struct common_object_header *)((void *)(object) - \ + sizeof(struct common_object_header)) +#define OBJECT_SIZE(size) \ + ((size) + sizeof(struct common_object_header)) +#define HEADER_TO_OBJECT(hdr) \ + ((void *)(hdr) + sizeof(struct common_object_header)) +#define HANDLE_TO_OBJECT(handle) HEADER_TO_OBJECT(handle) +#define HANDLE_TO_HEADER(handle) (handle) + +enum work_queue_type { + CriticalWorkQueue, DelayedWorkQueue, HyperCriticalWorkQueue, + MaximumWorkQueue +}; + +typedef void (*NTOS_WORK_FUNC)(void *arg1, void *arg2) wstdcall; + +struct io_workitem { + enum work_queue_type type; + struct device_object *dev_obj; + NTOS_WORK_FUNC worker_routine; + void *context; +}; + +struct io_workitem_entry { + struct nt_list list; + struct io_workitem *io_workitem; +}; + +enum mm_page_priority { + LowPagePriority, NormalPagePriority = 16, HighPagePriority = 32 +}; + +enum kinterrupt_mode { + LevelSensitive, Latched +}; + +enum ntos_wait_reason { + Executive, FreePage, PageIn, PoolAllocation, DelayExecution, + Suspended, UserRequest, WrExecutive, WrFreePage, WrPageIn, + WrPoolAllocation, WrDelayExecution, WrSuspended, WrUserRequest, + WrEventPair, WrQueue, WrLpcReceive, WrLpcReply, WrVirtualMemory, + WrPageOut, WrRendezvous, Spare2, Spare3, Spare4, Spare5, Spare6, + WrKernel, MaximumWaitReason +}; + +typedef enum ntos_wait_reason KWAIT_REASON; + +typedef void *LOOKASIDE_ALLOC_FUNC(enum pool_type pool_type, + SIZE_T size, ULONG tag) wstdcall; +typedef void LOOKASIDE_FREE_FUNC(void *) wstdcall; + +struct npaged_lookaside_list { + nt_slist_header head; + USHORT depth; + USHORT maxdepth; + ULONG totalallocs; + union { + ULONG allocmisses; + ULONG allochits; + } u1; + ULONG totalfrees; + union { + ULONG freemisses; + ULONG freehits; + } u2; + enum pool_type pool_type; + ULONG tag; + ULONG size; + LOOKASIDE_ALLOC_FUNC *alloc_func; + LOOKASIDE_FREE_FUNC *free_func; + struct nt_list list; + ULONG lasttotallocs; + union { + ULONG lastallocmisses; + ULONG lastallochits; + } u3; + ULONG pad[2]; +#ifndef CONFIG_X86_64 + NT_SPIN_LOCK obsolete; +#endif +} +#ifdef CONFIG_X86_64 +CACHE_ALIGN +#endif +; + +enum device_registry_property { + DevicePropertyDeviceDescription, DevicePropertyHardwareID, + DevicePropertyCompatibleIDs, DevicePropertyBootConfiguration, + DevicePropertyBootConfigurationTranslated, + DevicePropertyClassName, DevicePropertyClassGuid, + DevicePropertyDriverKeyName, DevicePropertyManufacturer, + DevicePropertyFriendlyName, DevicePropertyLocationInformation, + DevicePropertyPhysicalDeviceObjectName, DevicePropertyBusTypeGuid, + DevicePropertyLegacyBusType, DevicePropertyBusNumber, + DevicePropertyEnumeratorName, DevicePropertyAddress, + DevicePropertyUINumber, DevicePropertyInstallState, + DevicePropertyRemovalPolicy +}; + +enum trace_information_class { + TraceIdClass, TraceHandleClass, TraceEnableFlagsClass, + TraceEnableLevelClass, GlobalLoggerHandleClass, EventLoggerHandleClass, + AllLoggerHandlesClass, TraceHandleByNameClass +}; + +struct kinterrupt; +typedef BOOLEAN (*PKSERVICE_ROUTINE)(struct kinterrupt *interrupt, + void *context) wstdcall; +typedef BOOLEAN (*PKSYNCHRONIZE_ROUTINE)(void *context) wstdcall; + +struct kinterrupt { + ULONG vector; + KAFFINITY cpu_mask; + NT_SPIN_LOCK lock; + NT_SPIN_LOCK *actual_lock; + BOOLEAN shared; + BOOLEAN save_fp; + union { + CHAR processor_number; +#ifdef CONFIG_DEBUG_SHIRQ + CHAR enabled; +#endif + } u; + PKSERVICE_ROUTINE isr; + void *isr_ctx; + struct nt_list list; + KIRQL irql; + KIRQL synch_irql; + enum kinterrupt_mode mode; +}; + +struct time_fields { + CSHORT year; + CSHORT month; + CSHORT day; + CSHORT hour; + CSHORT minute; + CSHORT second; + CSHORT milliseconds; + CSHORT weekday; +}; + +struct object_attributes { + ULONG length; + void *root_dir; + struct unicode_string *name; + ULONG attributes; + void *security_descr; + void *security_qos; +}; + +typedef void (*PCALLBACK_FUNCTION)(void *context, void *arg1, + void *arg2) wstdcall; + +struct callback_object; +struct callback_func { + PCALLBACK_FUNCTION func; + void *context; + struct nt_list list; + struct callback_object *object; +}; + +struct callback_object { + NT_SPIN_LOCK lock; + struct nt_list list; + struct nt_list callback_funcs; + BOOLEAN allow_multiple_callbacks; + struct object_attributes *attributes; +}; + +enum section_inherit { + ViewShare = 1, ViewUnmap = 2 +}; + +struct ksystem_time { + ULONG low_part; + LONG high1_time; + LONG high2_time; +}; + +enum nt_product_type { + nt_product_win_nt = 1, nt_product_lan_man_nt, nt_product_server +}; + +enum alt_arch_type { + arch_type_standard, arch_type_nex98x86, end_alternatives +}; + +struct kuser_shared_data { + ULONG tick_count; + ULONG tick_count_multiplier; + volatile struct ksystem_time interrupt_time; + volatile struct ksystem_time system_time; + volatile struct ksystem_time time_zone_bias; + USHORT image_number_low; + USHORT image_number_high; + wchar_t nt_system_root[260]; + ULONG max_stack_trace_depth; + ULONG crypto_exponent; + ULONG time_zone_id; + ULONG large_page_min; + ULONG reserved2[7]; + enum nt_product_type nt_product_type; + BOOLEAN product_type_is_valid; + ULONG nt_major_version; + ULONG nt_minor_version; + BOOLEAN processor_features[PROCESSOR_FEATURE_MAX]; + ULONG reserved1; + ULONG reserved3; + volatile LONG time_slip; + enum alt_arch_type alt_arch_type; + LARGE_INTEGER system_expiration_date; + ULONG suite_mask; + BOOLEAN kdbg_enabled; + volatile ULONG active_console; + volatile ULONG dismount_count; + ULONG com_plus_package; + ULONG last_system_rite_event_tick_count; + ULONG num_phys_pages; + BOOLEAN safe_boot_mode; + ULONG trace_log; + ULONGLONG fill0; + ULONGLONG sys_call[4]; + union { + volatile struct ksystem_time tick_count; + volatile ULONG64 tick_count_quad; + } tick; +}; + +#define REG_NONE (0) +#define REG_SZ (1) +#define REG_EXPAND_SZ (2) +#define REG_BINARY (3) +#define REG_DWORD (4) + +#define RTL_REGISTRY_ABSOLUTE 0 +#define RTL_REGISTRY_SERVICES 1 +#define RTL_REGISTRY_CONTROL 2 +#define RTL_REGISTRY_WINDOWS_NT 3 +#define RTL_REGISTRY_DEVICEMAP 4 +#define RTL_REGISTRY_USER 5 +#define RTL_REGISTRY_MAXIMUM 6 +#define RTL_REGISTRY_HANDLE 0x40000000 +#define RTL_REGISTRY_OPTIONAL 0x80000000 + +#define RTL_QUERY_REGISTRY_SUBKEY 0x00000001 +#define RTL_QUERY_REGISTRY_TOPKEY 0x00000002 +#define RTL_QUERY_REGISTRY_REQUIRED 0x00000004 +#define RTL_QUERY_REGISTRY_NOVALUE 0x00000008 +#define RTL_QUERY_REGISTRY_NOEXPAND 0x00000010 +#define RTL_QUERY_REGISTRY_DIRECT 0x00000020 +#define RTL_QUERY_REGISTRY_DELETE 0x00000040 + +typedef NTSTATUS (*PRTL_QUERY_REGISTRY_ROUTINE)(wchar_t *name, ULONG type, + void *data, ULONG length, + void *context, + void *entry) wstdcall; + +struct rtl_query_registry_table { + PRTL_QUERY_REGISTRY_ROUTINE query_func; + ULONG flags; + wchar_t *name; + void *context; + ULONG def_type; + void *def_data; + ULONG def_length; +}; + +struct io_remove_lock { + BOOLEAN removed; + BOOLEAN reserved[3]; + LONG io_count; + struct nt_event remove_event; +}; + +struct io_error_log_packet { + UCHAR major_fn_code; + UCHAR retry_count; + USHORT dump_data_size; + USHORT nr_of_strings; + USHORT string_offset; + USHORT event_category; + NTSTATUS error_code; + ULONG unique_error_value; + NTSTATUS final_status; + ULONG sequence_number; + ULONG io_control_code; + LARGE_INTEGER device_offset; + ULONG dump_data[1]; +}; + +/* some of the functions below are slightly different from DDK's + * implementation; e.g., Insert functions return appropriate + * pointer */ + +/* instead of using Linux's lists, we implement list manipulation + * functions because nt_list is used by drivers and we don't want to + * worry about Linux's list being different from nt_list (right now + * they are same, but in future they could be different) */ + +static inline void InitializeListHead(struct nt_list *head) +{ + head->next = head->prev = head; +} + +static inline BOOLEAN IsListEmpty(struct nt_list *head) +{ + if (head == head->next) + return TRUE; + else + return FALSE; +} + +static inline void RemoveEntryList(struct nt_list *entry) +{ + entry->prev->next = entry->next; + entry->next->prev = entry->prev; +} + +static inline struct nt_list *RemoveHeadList(struct nt_list *head) +{ + struct nt_list *entry; + + entry = head->next; + if (entry == head) + return NULL; + else { + RemoveEntryList(entry); + return entry; + } +} + +static inline struct nt_list *RemoveTailList(struct nt_list *head) +{ + struct nt_list *entry; + + entry = head->prev; + if (entry == head) + return NULL; + else { + RemoveEntryList(entry); + return entry; + } +} + +static inline void InsertListEntry(struct nt_list *entry, struct nt_list *prev, + struct nt_list *next) +{ + next->prev = entry; + entry->next = next; + entry->prev = prev; + prev->next = entry; +} + +static inline struct nt_list *InsertHeadList(struct nt_list *head, + struct nt_list *entry) +{ + struct nt_list *ret; + + if (IsListEmpty(head)) + ret = NULL; + else + ret = head->next; + + InsertListEntry(entry, head, head->next); + return ret; +} + +static inline struct nt_list *InsertTailList(struct nt_list *head, + struct nt_list *entry) +{ + struct nt_list *ret; + + if (IsListEmpty(head)) + ret = NULL; + else + ret = head->prev; + + InsertListEntry(entry, head->prev, head); + return ret; +} + +#define nt_list_for_each(pos, head) \ + for (pos = (head)->next; pos != (head); pos = pos->next) + +#define nt_list_for_each_entry(pos, head, member) \ + for (pos = container_of((head)->next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = container_of(pos->member.next, typeof(*pos), member)) + +#define nt_list_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) + +/* device object flags */ +#define DO_VERIFY_VOLUME 0x00000002 +#define DO_BUFFERED_IO 0x00000004 +#define DO_EXCLUSIVE 0x00000008 +#define DO_DIRECT_IO 0x00000010 +#define DO_MAP_IO_BUFFER 0x00000020 +#define DO_DEVICE_HAS_NAME 0x00000040 +#define DO_DEVICE_INITIALIZING 0x00000080 +#define DO_SYSTEM_BOOT_PARTITION 0x00000100 +#define DO_LONG_TERM_REQUESTS 0x00000200 +#define DO_NEVER_LAST_DEVICE 0x00000400 +#define DO_SHUTDOWN_REGISTERED 0x00000800 +#define DO_BUS_ENUMERATED_DEVICE 0x00001000 +#define DO_POWER_PAGABLE 0x00002000 +#define DO_POWER_INRUSH 0x00004000 +#define DO_LOW_PRIORITY_FILESYSTEM 0x00010000 + +/* Various supported device types (used with IoCreateDevice()) */ + +#define FILE_DEVICE_BEEP 0x00000001 +#define FILE_DEVICE_CD_ROM 0x00000002 +#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 +#define FILE_DEVICE_CONTROLLER 0x00000004 +#define FILE_DEVICE_DATALINK 0x00000005 +#define FILE_DEVICE_DFS 0x00000006 +#define FILE_DEVICE_DISK 0x00000007 +#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 +#define FILE_DEVICE_FILE_SYSTEM 0x00000009 +#define FILE_DEVICE_INPORT_PORT 0x0000000A +#define FILE_DEVICE_KEYBOARD 0x0000000B +#define FILE_DEVICE_MAILSLOT 0x0000000C +#define FILE_DEVICE_MIDI_IN 0x0000000D +#define FILE_DEVICE_MIDI_OUT 0x0000000E +#define FILE_DEVICE_MOUSE 0x0000000F +#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010 +#define FILE_DEVICE_NAMED_PIPE 0x00000011 +#define FILE_DEVICE_NETWORK 0x00000012 +#define FILE_DEVICE_NETWORK_BROWSER 0x00000013 +#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014 +#define FILE_DEVICE_NULL 0x00000015 +#define FILE_DEVICE_PARALLEL_PORT 0x00000016 +#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017 +#define FILE_DEVICE_PRINTER 0x00000018 +#define FILE_DEVICE_SCANNER 0x00000019 +#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001A +#define FILE_DEVICE_SERIAL_PORT 0x0000001B +#define FILE_DEVICE_SCREEN 0x0000001C +#define FILE_DEVICE_SOUND 0x0000001D +#define FILE_DEVICE_STREAMS 0x0000001E +#define FILE_DEVICE_TAPE 0x0000001F +#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020 +#define FILE_DEVICE_TRANSPORT 0x00000021 +#define FILE_DEVICE_UNKNOWN 0x00000022 +#define FILE_DEVICE_VIDEO 0x00000023 +#define FILE_DEVICE_VIRTUAL_DISK 0x00000024 +#define FILE_DEVICE_WAVE_IN 0x00000025 +#define FILE_DEVICE_WAVE_OUT 0x00000026 +#define FILE_DEVICE_8042_PORT 0x00000027 +#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028 +#define FILE_DEVICE_BATTERY 0x00000029 +#define FILE_DEVICE_BUS_EXTENDER 0x0000002A +#define FILE_DEVICE_MODEM 0x0000002B +#define FILE_DEVICE_VDM 0x0000002C +#define FILE_DEVICE_MASS_STORAGE 0x0000002D +#define FILE_DEVICE_SMB 0x0000002E +#define FILE_DEVICE_KS 0x0000002F +#define FILE_DEVICE_CHANGER 0x00000030 +#define FILE_DEVICE_SMARTCARD 0x00000031 +#define FILE_DEVICE_ACPI 0x00000032 +#define FILE_DEVICE_DVD 0x00000033 +#define FILE_DEVICE_FULLSCREEN_VIDEO 0x00000034 +#define FILE_DEVICE_DFS_FILE_SYSTEM 0x00000035 +#define FILE_DEVICE_DFS_VOLUME 0x00000036 +#define FILE_DEVICE_SERENUM 0x00000037 +#define FILE_DEVICE_TERMSRV 0x00000038 +#define FILE_DEVICE_KSEC 0x00000039 +#define FILE_DEVICE_FIPS 0x0000003A + +/* Device characteristics */ + +#define FILE_REMOVABLE_MEDIA 0x00000001 +#define FILE_READ_ONLY_DEVICE 0x00000002 +#define FILE_FLOPPY_DISKETTE 0x00000004 +#define FILE_WRITE_ONCE_MEDIA 0x00000008 +#define FILE_REMOTE_DEVICE 0x00000010 +#define FILE_DEVICE_IS_MOUNTED 0x00000020 +#define FILE_VIRTUAL_VOLUME 0x00000040 +#define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080 +#define FILE_DEVICE_SECURE_OPEN 0x00000100 + +#define FILE_READ_DATA 0x0001 +#define FILE_WRITE_DATA 0x0002 + +#define FILE_SUPERSEDED 0x00000000 +#define FILE_OPENED 0x00000001 +#define FILE_CREATED 0x00000002 +#define FILE_OVERWRITTEN 0x00000003 +#define FILE_EXISTS 0x00000004 +#define FILE_DOES_NOT_EXIST 0x00000005 + + +#endif /* WINNT_TYPES_H */ --- linux-2.6.28.orig/ubuntu/ndiswrapper/loader.c +++ linux-2.6.28/ubuntu/ndiswrapper/loader.c @@ -0,0 +1,877 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#include "ndis.h" +#include "loader.h" +#include "wrapndis.h" +#include "pnp.h" + +#include +#include +#include +#include + +/* + Network adapter: ClassGuid = {4d36e972-e325-11ce-bfc1-08002be10318} + Network client: ClassGuid = {4d36e973-e325-11ce-bfc1-08002be10318} + PCMCIA adapter: ClassGuid = {4d36e977-e325-11ce-bfc1-08002be10318} + USB: ClassGuid = {36fc9e60-c465-11cf-8056-444553540000} +*/ + +/* the indices used here must match macros WRAP_NDIS_DEVICE etc. */ +static struct guid class_guids[] = { + /* Network */ + {0x4d36e972, 0xe325, 0x11ce, }, + /* USB WDM */ + {0x36fc9e60, 0xc465, 0x11cf, }, + /* Bluetooth */ + {0xe0cbf06c, 0xcd8b, 0x4647, }, + /* ivtcorporatino.com's bluetooth device claims this is + * bluetooth guid */ + {0xf12d3cf8, 0xb11d, 0x457e, }, +}; + +struct semaphore loader_mutex; +static struct completion loader_complete; + +static struct nt_list wrap_devices; +static struct nt_list wrap_drivers; + +static int wrap_device_type(int data1) +{ + int i; + for (i = 0; i < sizeof(class_guids) / sizeof(class_guids[0]); i++) + if (data1 == class_guids[i].data1) + return i; + ERROR("unknown device: 0x%x\n", data1); + return -1; +} + +/* load driver for given device, if not already loaded */ +struct wrap_driver *load_wrap_driver(struct wrap_device *wd) +{ + int ret; + struct nt_list *cur; + struct wrap_driver *wrap_driver; + + ENTER1("device: %04X:%04X:%04X:%04X", wd->vendor, wd->device, + wd->subvendor, wd->subdevice); + if (down_interruptible(&loader_mutex)) { + WARNING("couldn't obtain loader_mutex"); + EXIT1(return NULL); + } + wrap_driver = NULL; + nt_list_for_each(cur, &wrap_drivers) { + wrap_driver = container_of(cur, struct wrap_driver, list); + if (!stricmp(wrap_driver->name, wd->driver_name)) { + TRACE1("driver %s already loaded", wrap_driver->name); + break; + } else + wrap_driver = NULL; + } + up(&loader_mutex); + + if (!wrap_driver) { + char *argv[] = {"loadndisdriver", WRAP_CMD_LOAD_DRIVER, +#if defined(DEBUG) && DEBUG >= 1 + "1", +#else + "0", +#endif + UTILS_VERSION, wd->driver_name, + wd->conf_file_name, NULL}; + char *env[] = {NULL}; + + TRACE1("loading driver %s", wd->driver_name); + if (down_interruptible(&loader_mutex)) { + WARNING("couldn't obtain loader_mutex"); + EXIT1(return NULL); + } + INIT_COMPLETION(loader_complete); + ret = call_usermodehelper("/sbin/loadndisdriver", argv, env, 1); + if (ret) { + up(&loader_mutex); + ERROR("couldn't load driver %s; check system log " + "for messages from 'loadndisdriver'", + wd->driver_name); + EXIT1(return NULL); + } + wait_for_completion(&loader_complete); + TRACE1("%s", wd->driver_name); + wrap_driver = NULL; + nt_list_for_each(cur, &wrap_drivers) { + wrap_driver = container_of(cur, struct wrap_driver, + list); + if (!stricmp(wrap_driver->name, wd->driver_name)) { + wd->driver = wrap_driver; + break; + } else + wrap_driver = NULL; + } + up(&loader_mutex); + if (wrap_driver) + TRACE1("driver %s is loaded", wrap_driver->name); + else + ERROR("couldn't load driver '%s'", wd->driver_name); + } + EXIT1(return wrap_driver); +} + +/* load the driver files from userspace. */ +static int load_sys_files(struct wrap_driver *driver, + struct load_driver *load_driver) +{ + int i, err; + + TRACE1("num_pe_images = %d", load_driver->num_sys_files); + TRACE1("loading driver: %s", load_driver->name); + strncpy(driver->name, load_driver->name, sizeof(driver->name)); + driver->name[sizeof(driver->name)-1] = 0; + TRACE1("driver: %s", driver->name); + err = 0; + driver->num_pe_images = 0; + for (i = 0; i < load_driver->num_sys_files; i++) { + struct pe_image *pe_image; + pe_image = &driver->pe_images[driver->num_pe_images]; + + strncpy(pe_image->name, load_driver->sys_files[i].name, + sizeof(pe_image->name)); + pe_image->name[sizeof(pe_image->name)-1] = 0; + TRACE1("image size: %lu bytes", + (unsigned long)load_driver->sys_files[i].size); + +#ifdef CONFIG_X86_64 +#ifdef PAGE_KERNEL_EXECUTABLE + pe_image->image = + __vmalloc(load_driver->sys_files[i].size, + GFP_KERNEL | __GFP_HIGHMEM, + PAGE_KERNEL_EXECUTABLE); +#elif defined PAGE_KERNEL_EXEC + pe_image->image = + __vmalloc(load_driver->sys_files[i].size, + GFP_KERNEL | __GFP_HIGHMEM, + PAGE_KERNEL_EXEC); +#else +#error x86_64 should have either PAGE_KERNEL_EXECUTABLE or PAGE_KERNEL_EXEC +#endif +#else + /* hate to play with kernel macros, but PAGE_KERNEL_EXEC is + * not available to modules! */ +#ifdef cpu_has_nx + if (cpu_has_nx) + pe_image->image = + __vmalloc(load_driver->sys_files[i].size, + GFP_KERNEL | __GFP_HIGHMEM, + __pgprot(__PAGE_KERNEL & ~_PAGE_NX)); + else + pe_image->image = + vmalloc(load_driver->sys_files[i].size); +#else + pe_image->image = + vmalloc(load_driver->sys_files[i].size); +#endif +#endif + if (!pe_image->image) { + ERROR("couldn't allocate memory"); + err = -ENOMEM; + break; + } + TRACE1("image is at %p", pe_image->image); + + if (copy_from_user(pe_image->image, + load_driver->sys_files[i].data, + load_driver->sys_files[i].size)) { + ERROR("couldn't load file %s", + load_driver->sys_files[i].name); + err = -EFAULT; + break; + } + pe_image->size = load_driver->sys_files[i].size; + driver->num_pe_images++; + } + + if (!err && link_pe_images(driver->pe_images, driver->num_pe_images)) { + ERROR("couldn't prepare driver '%s'", load_driver->name); + err = -EINVAL; + } + + if (driver->num_pe_images < load_driver->num_sys_files || err) { + for (i = 0; i < driver->num_pe_images; i++) + if (driver->pe_images[i].image) + vfree(driver->pe_images[i].image); + driver->num_pe_images = 0; + EXIT1(return err); + } else + EXIT1(return 0); +} + +struct wrap_bin_file *get_bin_file(char *bin_file_name) +{ + int i = 0; + struct wrap_driver *driver, *cur; + + ENTER1("%s", bin_file_name); + if (down_interruptible(&loader_mutex)) { + WARNING("couldn't obtain loader_mutex"); + EXIT1(return NULL); + } + driver = NULL; + nt_list_for_each_entry(cur, &wrap_drivers, list) { + for (i = 0; i < cur->num_bin_files; i++) + if (!stricmp(cur->bin_files[i].name, bin_file_name)) { + driver = cur; + break; + } + if (driver) + break; + } + up(&loader_mutex); + if (!driver) { + TRACE1("coudln't find bin file '%s'", bin_file_name); + return NULL; + } + + if (!driver->bin_files[i].data) { + char *argv[] = {"loadndisdriver", WRAP_CMD_LOAD_BIN_FILE, +#if defined(DEBUG) && DEBUG >= 1 + "1", +#else + "0", +#endif + UTILS_VERSION, driver->name, + driver->bin_files[i].name, NULL}; + char *env[] = {NULL}; + int ret; + + TRACE1("loading bin file %s/%s", driver->name, + driver->bin_files[i].name); + if (down_interruptible(&loader_mutex)) { + WARNING("couldn't obtain loader_mutex"); + EXIT1(return NULL); + } + INIT_COMPLETION(loader_complete); + ret = call_usermodehelper("/sbin/loadndisdriver", argv, env, 1); + if (ret) { + up(&loader_mutex); + ERROR("couldn't load file %s/%s; check system log " + "for messages from 'loadndisdriver' (%d)", + driver->name, driver->bin_files[i].name, ret); + EXIT1(return NULL); + } + wait_for_completion(&loader_complete); + up(&loader_mutex); + if (!driver->bin_files[i].data) { + WARNING("couldn't load binary file %s", + driver->bin_files[i].name); + EXIT1(return NULL); + } + } + EXIT2(return &(driver->bin_files[i])); +} + +/* called with loader_mutex down */ +static int add_bin_file(struct load_driver_file *driver_file) +{ + struct wrap_driver *driver, *cur; + struct wrap_bin_file *bin_file; + int i = 0; + + driver = NULL; + nt_list_for_each_entry(cur, &wrap_drivers, list) { + for (i = 0; i < cur->num_bin_files; i++) + if (!stricmp(cur->bin_files[i].name, + driver_file->name)) { + driver = cur; + break; + } + if (driver) + break; + } + if (!driver) { + ERROR("couldn't find %s", driver_file->name); + return -EINVAL; + } + bin_file = &driver->bin_files[i]; + strncpy(bin_file->name, driver_file->name, sizeof(bin_file->name)); + bin_file->name[sizeof(bin_file->name)-1] = 0; + bin_file->data = vmalloc(driver_file->size); + if (!bin_file->data) { + ERROR("couldn't allocate memory"); + return -ENOMEM; + } + bin_file->size = driver_file->size; + if (copy_from_user(bin_file->data, driver_file->data, bin_file->size)) { + ERROR("couldn't copy data"); + free_bin_file(bin_file); + return -EFAULT; + } + return 0; +} + +void free_bin_file(struct wrap_bin_file *bin_file) +{ + TRACE2("unloading %s", bin_file->name); + if (bin_file->data) + vfree(bin_file->data); + bin_file->data = NULL; + bin_file->size = 0; + EXIT2(return); +} + +/* load firmware files from userspace */ +static int load_bin_files_info(struct wrap_driver *driver, + struct load_driver *load_driver) +{ + struct wrap_bin_file *bin_files; + int i; + + ENTER1("%s, %d", load_driver->name, load_driver->num_bin_files); + driver->num_bin_files = 0; + driver->bin_files = NULL; + if (load_driver->num_bin_files == 0) + EXIT1(return 0); + bin_files = kzalloc(load_driver->num_bin_files * sizeof(*bin_files), + GFP_KERNEL); + if (!bin_files) { + ERROR("couldn't allocate memory"); + EXIT1(return -ENOMEM); + } + + for (i = 0; i < load_driver->num_bin_files; i++) { + strncpy(bin_files[i].name, load_driver->bin_files[i].name, + sizeof(bin_files[i].name)); + bin_files[i].name[sizeof(bin_files[i].name)-1] = 0; + TRACE2("loaded bin file %s", bin_files[i].name); + } + driver->num_bin_files = load_driver->num_bin_files; + driver->bin_files = bin_files; + EXIT1(return 0); +} + +/* load settnigs for a device. called with loader_mutex down */ +static int load_settings(struct wrap_driver *wrap_driver, + struct load_driver *load_driver) +{ + int i, num_settings; + + ENTER1("%p, %p", wrap_driver, load_driver); + + num_settings = 0; + for (i = 0; i < load_driver->num_settings; i++) { + struct load_device_setting *load_setting = + &load_driver->settings[i]; + struct wrap_device_setting *setting; + ULONG data1; + + setting = kzalloc(sizeof(*setting), GFP_KERNEL); + if (!setting) { + ERROR("couldn't allocate memory"); + break; + } + strncpy(setting->name, load_setting->name, + sizeof(setting->name)); + setting->name[sizeof(setting->name)-1] = 0; + strncpy(setting->value, load_setting->value, + sizeof(setting->value)); + setting->value[sizeof(setting->value)-1] = 0; + TRACE2("%p: %s=%s", setting, setting->name, setting->value); + + if (strcmp(setting->name, "driver_version") == 0) { + strncpy(wrap_driver->version, setting->value, + sizeof(wrap_driver->version)); + wrap_driver->version[sizeof(wrap_driver->version)-1] = 0; + } else if (strcmp(setting->name, "class_guid") == 0 && + sscanf(setting->value, "%x", &data1) == 1) { + wrap_driver->dev_type = wrap_device_type(data1); + if (wrap_driver->dev_type < 0) { + WARNING("unknown guid: %x", data1); + wrap_driver->dev_type = 0; + } + } + InsertTailList(&wrap_driver->settings, &setting->list); + num_settings++; + } + /* it is not a fatal error if some settings couldn't be loaded */ + if (num_settings > 0) + EXIT1(return 0); + else + EXIT1(return -EINVAL); +} + +void unload_wrap_device(struct wrap_device *wd) +{ + struct nt_list *cur; + ENTER1("unloading device %p (%04X:%04X:%04X:%04X), driver %s", wd, + wd->vendor, wd->device, wd->subvendor, wd->subdevice, + wd->driver_name); + if (down_interruptible(&loader_mutex)) + WARNING("couldn't obtain loader_mutex"); + while ((cur = RemoveHeadList(&wd->settings))) { + struct wrap_device_setting *setting; + setting = container_of(cur, struct wrap_device_setting, list); + kfree(setting); + } + RemoveEntryList(&wd->list); + up(&loader_mutex); + kfree(wd); + EXIT1(return); +} + +/* should be called with loader_mutex down */ +void unload_wrap_driver(struct wrap_driver *driver) +{ + int i; + struct driver_object *drv_obj; + struct nt_list *cur, *next; + + ENTER1("unloading driver: %s (%p)", driver->name, driver); + TRACE1("freeing %d images", driver->num_pe_images); + drv_obj = driver->drv_obj; + for (i = 0; i < driver->num_pe_images; i++) + if (driver->pe_images[i].image) { + TRACE1("freeing image at %p", + driver->pe_images[i].image); + vfree(driver->pe_images[i].image); + } + + TRACE1("freeing %d bin files", driver->num_bin_files); + for (i = 0; i < driver->num_bin_files; i++) { + TRACE1("freeing image at %p", driver->bin_files[i].data); + if (driver->bin_files[i].data) + vfree(driver->bin_files[i].data); + } + if (driver->bin_files) + kfree(driver->bin_files); + RtlFreeUnicodeString(&drv_obj->name); + RemoveEntryList(&driver->list); + nt_list_for_each_safe(cur, next, &driver->settings) { + struct wrap_device_setting *setting; + struct ndis_configuration_parameter *param; + + setting = container_of(cur, struct wrap_device_setting, list); + TRACE2("%p", setting); + param = setting->encoded; + if (param) { + TRACE2("%p", param); + if (param->type == NdisParameterString) + RtlFreeUnicodeString(¶m->data.string); + ExFreePool(param); + } + kfree(setting); + } + /* this frees driver */ + free_custom_extensions(drv_obj->drv_ext); + kfree(drv_obj->drv_ext); + TRACE1("drv_obj: %p", drv_obj); + + EXIT1(return); +} + +/* call the entry point of the driver */ +static int start_wrap_driver(struct wrap_driver *driver) +{ + int i; + NTSTATUS ret, res; + struct driver_object *drv_obj; + typeof(driver->pe_images[0].entry) entry; + + ENTER1("%s", driver->name); + drv_obj = driver->drv_obj; + for (ret = res = 0, i = 0; i < driver->num_pe_images; i++) + /* dlls are already started by loader */ + if (driver->pe_images[i].type == IMAGE_FILE_EXECUTABLE_IMAGE) { + entry = driver->pe_images[i].entry; + drv_obj->start = driver->pe_images[i].entry; + drv_obj->driver_size = driver->pe_images[i].size; + TRACE1("entry: %p, %p, drv_obj: %p", + entry, *entry, drv_obj); + res = LIN2WIN2(entry, drv_obj, &drv_obj->name); + ret |= res; + TRACE1("entry returns %08X", res); + break; + } + if (ret) { + ERROR("driver initialization failed: %08X", ret); + RtlFreeUnicodeString(&drv_obj->name); + /* this frees ndis_driver */ + free_custom_extensions(drv_obj->drv_ext); + kfree(drv_obj->drv_ext); + TRACE1("drv_obj: %p", drv_obj); + ObDereferenceObject(drv_obj); + EXIT1(return -EINVAL); + } + EXIT1(return 0); +} + +/* + * add driver to list of loaded driver but make sure this driver is + * not loaded before. called with loader_mutex down + */ +static int add_wrap_driver(struct wrap_driver *driver) +{ + struct wrap_driver *tmp; + + ENTER1("name: %s", driver->name); + nt_list_for_each_entry(tmp, &wrap_drivers, list) { + if (stricmp(tmp->name, driver->name) == 0) { + ERROR("cannot add duplicate driver"); + EXIT1(return -EBUSY); + } + } + InsertHeadList(&wrap_drivers, &driver->list); + EXIT1(return 0); +} + +/* load a driver from userspace and initialize it. called with + * loader_mutex down */ +static int load_user_space_driver(struct load_driver *load_driver) +{ + struct driver_object *drv_obj; + struct ansi_string ansi_reg; + struct wrap_driver *wrap_driver = NULL; + + ENTER1("%p", load_driver); + drv_obj = allocate_object(sizeof(*drv_obj), OBJECT_TYPE_DRIVER, NULL); + if (!drv_obj) { + ERROR("couldn't allocate memory"); + EXIT1(return -ENOMEM); + } + TRACE1("drv_obj: %p", drv_obj); + drv_obj->drv_ext = kzalloc(sizeof(*(drv_obj->drv_ext)), GFP_KERNEL); + if (!drv_obj->drv_ext) { + ERROR("couldn't allocate memory"); + ObDereferenceObject(drv_obj); + EXIT1(return -ENOMEM); + } + InitializeListHead(&drv_obj->drv_ext->custom_ext); + if (IoAllocateDriverObjectExtension(drv_obj, + (void *)WRAP_DRIVER_CLIENT_ID, + sizeof(*wrap_driver), + (void **)&wrap_driver) != + STATUS_SUCCESS) + EXIT1(return -ENOMEM); + TRACE1("driver: %p", wrap_driver); + memset(wrap_driver, 0, sizeof(*wrap_driver)); + InitializeListHead(&wrap_driver->list); + InitializeListHead(&wrap_driver->settings); + InitializeListHead(&wrap_driver->wrap_devices); + wrap_driver->drv_obj = drv_obj; + RtlInitAnsiString(&ansi_reg, "/tmp"); + if (RtlAnsiStringToUnicodeString(&drv_obj->name, &ansi_reg, TRUE) != + STATUS_SUCCESS) { + ERROR("couldn't initialize registry path"); + free_custom_extensions(drv_obj->drv_ext); + kfree(drv_obj->drv_ext); + TRACE1("drv_obj: %p", drv_obj); + ObDereferenceObject(drv_obj); + EXIT1(return -EINVAL); + } + strncpy(wrap_driver->name, load_driver->name, sizeof(wrap_driver->name)); + wrap_driver->name[sizeof(wrap_driver->name)-1] = 0; + if (load_sys_files(wrap_driver, load_driver) || + load_bin_files_info(wrap_driver, load_driver) || + load_settings(wrap_driver, load_driver) || + start_wrap_driver(wrap_driver) || + add_wrap_driver(wrap_driver)) { + unload_wrap_driver(wrap_driver); + EXIT1(return -EINVAL); + } else { + printk(KERN_INFO "%s: driver %s (%s) loaded\n", + DRIVER_NAME, wrap_driver->name, wrap_driver->version); + add_taint(TAINT_PROPRIETARY_MODULE); + EXIT1(return 0); + } +} + +static struct pci_device_id wrap_pci_id_table[] = { + {PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID}, +}; + +static struct pci_driver wrap_pci_driver = { + .name = DRIVER_NAME, + .id_table = wrap_pci_id_table, + .probe = wrap_pnp_start_pci_device, + .remove = __devexit_p(wrap_pnp_remove_pci_device), + .suspend = wrap_pnp_suspend_pci_device, + .resume = wrap_pnp_resume_pci_device, +}; + +#ifdef ENABLE_USB +static struct usb_device_id wrap_usb_id_table[] = { + { + .driver_info = 1 + }, +}; + +static struct usb_driver wrap_usb_driver = { + .name = DRIVER_NAME, + .id_table = wrap_usb_id_table, + .probe = wrap_pnp_start_usb_device, + .disconnect = __devexit_p(wrap_pnp_remove_usb_device), + .suspend = wrap_pnp_suspend_usb_device, + .resume = wrap_pnp_resume_usb_device, +}; +#endif + +/* register drivers for pci and usb */ +static void register_devices(void) +{ + int res; + + res = pci_register_driver(&wrap_pci_driver); + if (res < 0) { + ERROR("couldn't register pci driver: %d", res); + wrap_pci_driver.name = NULL; + } + +#ifdef ENABLE_USB + res = usb_register(&wrap_usb_driver); + if (res < 0) { + ERROR("couldn't register usb driver: %d", res); + wrap_usb_driver.name = NULL; + } +#endif + EXIT1(return); +} + +static void unregister_devices(void) +{ + struct nt_list *cur, *next; + + if (down_interruptible(&loader_mutex)) + WARNING("couldn't obtain loader_mutex"); + nt_list_for_each_safe(cur, next, &wrap_devices) { + struct wrap_device *wd; + wd = container_of(cur, struct wrap_device, list); + set_bit(HW_PRESENT, &wd->hw_status); + } + up(&loader_mutex); + + if (wrap_pci_driver.name) + pci_unregister_driver(&wrap_pci_driver); +#ifdef ENABLE_USB + if (wrap_usb_driver.name) + usb_deregister(&wrap_usb_driver); +#endif +} + +struct wrap_device *load_wrap_device(struct load_device *load_device) +{ + int ret; + struct nt_list *cur; + struct wrap_device *wd = NULL; + char vendor[5], device[5], subvendor[5], subdevice[5], bus[5]; + + ENTER1("%04x, %04x, %04x, %04x", load_device->vendor, + load_device->device, load_device->subvendor, + load_device->subdevice); + if (sprintf(vendor, "%04x", load_device->vendor) == 4 && + sprintf(device, "%04x", load_device->device) == 4 && + sprintf(subvendor, "%04x", load_device->subvendor) == 4 && + sprintf(subdevice, "%04x", load_device->subdevice) == 4 && + sprintf(bus, "%04x", load_device->bus) == 4) { + char *argv[] = {"loadndisdriver", WRAP_CMD_LOAD_DEVICE, +#if defined(DEBUG) && DEBUG >= 1 + "1", +#else + "0", +#endif + UTILS_VERSION, vendor, device, + subvendor, subdevice, bus, NULL}; + char *env[] = {NULL}; + TRACE2("%s, %s, %s, %s, %s", vendor, device, + subvendor, subdevice, bus); + if (down_interruptible(&loader_mutex)) { + WARNING("couldn't obtain loader_mutex"); + EXIT1(return NULL); + } + INIT_COMPLETION(loader_complete); + ret = call_usermodehelper("/sbin/loadndisdriver", argv, env, 1); + if (ret) { + up(&loader_mutex); + TRACE1("couldn't load device %04x:%04x; check system " + "log for messages from 'loadndisdriver'", + load_device->vendor, load_device->device); + EXIT1(return NULL); + } + wait_for_completion(&loader_complete); + wd = NULL; + nt_list_for_each(cur, &wrap_devices) { + wd = container_of(cur, struct wrap_device, list); + TRACE2("%p, %04x, %04x, %04x, %04x", wd, wd->vendor, + wd->device, wd->subvendor, wd->subdevice); + if (wd->vendor == load_device->vendor && + wd->device == load_device->device) + break; + else + wd = NULL; + } + up(&loader_mutex); + } else + wd = NULL; + EXIT1(return wd); +} + +struct wrap_device *get_wrap_device(void *dev, int bus) +{ + struct nt_list *cur; + struct wrap_device *wd; + + if (down_interruptible(&loader_mutex)) { + WARNING("couldn't obtain loader_mutex"); + return NULL; + } + wd = NULL; + nt_list_for_each(cur, &wrap_devices) { + wd = container_of(cur, struct wrap_device, list); + if (bus == WRAP_PCI_BUS && + wrap_is_pci_bus(wd->dev_bus) && wd->pci.pdev == dev) + break; + else if (bus == WRAP_USB_BUS && + wrap_is_usb_bus(wd->dev_bus) && wd->usb.udev == dev) + break; + else + wd = NULL; + } + up(&loader_mutex); + return wd; +} + +/* called with loader_mutex is down */ +static int wrapper_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct load_driver *load_driver; + struct load_device load_device; + struct load_driver_file load_bin_file; + int ret; + void __user *addr = (void __user *)arg; + + ENTER1("cmd: %u", cmd); + + ret = 0; + switch (cmd) { + case WRAP_IOCTL_LOAD_DEVICE: + if (copy_from_user(&load_device, addr, sizeof(load_device))) { + ret = -EFAULT; + break; + } + TRACE2("%04x, %04x, %04x, %04x", load_device.vendor, + load_device.device, load_device.subvendor, + load_device.subdevice); + if (load_device.vendor) { + struct wrap_device *wd; + wd = kzalloc(sizeof(*wd), GFP_KERNEL); + if (!wd) { + ret = -ENOMEM; + break; + } + InitializeListHead(&wd->settings); + wd->dev_bus = WRAP_BUS(load_device.bus); + wd->vendor = load_device.vendor; + wd->device = load_device.device; + wd->subvendor = load_device.subvendor; + wd->subdevice = load_device.subdevice; + strncpy(wd->conf_file_name, load_device.conf_file_name, + sizeof(wd->conf_file_name)); + wd->conf_file_name[sizeof(wd->conf_file_name)-1] = 0; + strncpy(wd->driver_name, load_device.driver_name, + sizeof(wd->driver_name)); + wd->driver_name[sizeof(wd->driver_name)-1] = 0; + InsertHeadList(&wrap_devices, &wd->list); + ret = 0; + } else + ret = -EINVAL; + break; + case WRAP_IOCTL_LOAD_DRIVER: + TRACE1("loading driver at %p", addr); + load_driver = vmalloc(sizeof(*load_driver)); + if (!load_driver) { + ret = -ENOMEM; + break; + } + if (copy_from_user(load_driver, addr, sizeof(*load_driver))) + ret = -EFAULT; + else + ret = load_user_space_driver(load_driver); + vfree(load_driver); + break; + case WRAP_IOCTL_LOAD_BIN_FILE: + if (copy_from_user(&load_bin_file, addr, sizeof(load_bin_file))) + ret = -EFAULT; + else + ret = add_bin_file(&load_bin_file); + break; + default: + ERROR("unknown ioctl %u", cmd); + ret = -EINVAL; + break; + } + complete(&loader_complete); + EXIT1(return ret); +} + +static int wrapper_ioctl_release(struct inode *inode, struct file *file) +{ + ENTER1(""); + return 0; +} + +static struct file_operations wrapper_fops = { + .owner = THIS_MODULE, + .ioctl = wrapper_ioctl, + .release = wrapper_ioctl_release, +}; + +static struct miscdevice wrapper_misc = { + .name = DRIVER_NAME, + .minor = MISC_DYNAMIC_MINOR, + .fops = &wrapper_fops +}; + +int loader_init(void) +{ + int err; + + InitializeListHead(&wrap_drivers); + InitializeListHead(&wrap_devices); + init_MUTEX(&loader_mutex); + init_completion(&loader_complete); + if ((err = misc_register(&wrapper_misc)) < 0 ) { + ERROR("couldn't register module (%d)", err); + unregister_devices(); + EXIT1(return err); + } + register_devices(); + EXIT1(return 0); +} + +void loader_exit(void) +{ + struct nt_list *cur, *next; + + ENTER1(""); + misc_deregister(&wrapper_misc); + unregister_devices(); + if (down_interruptible(&loader_mutex)) + WARNING("couldn't obtain loader_mutex"); + nt_list_for_each_safe(cur, next, &wrap_drivers) { + struct wrap_driver *driver; + driver = container_of(cur, struct wrap_driver, list); + unload_wrap_driver(driver); + } + up(&loader_mutex); + EXIT1(return); +} --- linux-2.6.28.orig/ubuntu/ndiswrapper/loader.h +++ linux-2.6.28/ubuntu/ndiswrapper/loader.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#ifndef _LOADER_H_ +#define _LOADER_H_ + +#include "ndiswrapper.h" + +#ifndef __KERNEL__ +#define __user +#endif + +struct load_driver_file { + char driver_name[MAX_DRIVER_NAME_LEN]; + char name[MAX_DRIVER_NAME_LEN]; + size_t size; + void __user *data; +}; + +struct load_device_setting { + char name[MAX_SETTING_NAME_LEN]; + char value[MAX_SETTING_VALUE_LEN]; +}; + +struct load_device { + int bus; + int vendor; + int device; + int subvendor; + int subdevice; + char conf_file_name[MAX_DRIVER_NAME_LEN]; + char driver_name[MAX_DRIVER_NAME_LEN]; +}; + +struct load_devices { + int count; + struct load_device *devices; +}; + +struct load_driver { + char name[MAX_DRIVER_NAME_LEN]; + char conf_file_name[MAX_DRIVER_NAME_LEN]; + unsigned int num_sys_files; + struct load_driver_file sys_files[MAX_DRIVER_PE_IMAGES]; + unsigned int num_settings; + struct load_device_setting settings[MAX_DEVICE_SETTINGS]; + unsigned int num_bin_files; + struct load_driver_file bin_files[MAX_DRIVER_BIN_FILES]; +}; + +#define WRAP_IOCTL_LOAD_DEVICE _IOW(('N' + 'd' + 'i' + 'S'), 0, \ + struct load_device *) +#define WRAP_IOCTL_LOAD_DRIVER _IOW(('N' + 'd' + 'i' + 'S'), 1, \ + struct load_driver *) +#define WRAP_IOCTL_LOAD_BIN_FILE _IOW(('N' + 'd' + 'i' + 'S'), 2, \ + struct load_driver_file *) + +#define WRAP_CMD_LOAD_DEVICE "load_device" +#define WRAP_CMD_LOAD_DRIVER "load_driver" +#define WRAP_CMD_LOAD_BIN_FILE "load_bin_file" + +int loader_init(void); +void loader_exit(void); + +#ifdef __KERNEL__ +struct wrap_device *load_wrap_device(struct load_device *load_device); +struct wrap_driver *load_wrap_driver(struct wrap_device *device); +struct wrap_bin_file *get_bin_file(char *bin_file_name); +void free_bin_file(struct wrap_bin_file *bin_file); +void unload_wrap_driver(struct wrap_driver *driver); +void unload_wrap_device(struct wrap_device *wd); +struct wrap_device *get_wrap_device(void *dev, int bus_type); + +extern struct semaphore loader_mutex; +#endif + +#endif /* LOADER_H */ + --- linux-2.6.28.orig/ubuntu/ndiswrapper/iw_ndis.h +++ linux-2.6.28/ubuntu/ndiswrapper/iw_ndis.h @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#ifndef _IW_NDIS_H_ +#define _IW_NDIS_H_ + +#include "ndis.h" + +#define WL_NOISE -96 /* typical noise level in dBm */ +#define WL_SIGMAX -32 /* typical maximum signal level in dBm */ + +struct ndis_encr_key { + ULONG struct_size; + ULONG index; + ULONG length; + UCHAR key[NDIS_ENCODING_TOKEN_MAX]; +}; + +struct ndis_add_key { + ULONG struct_size; + ndis_key_index index; + ULONG length; + mac_address bssid; + UCHAR pad[6]; + ndis_key_rsc rsc; + UCHAR key[NDIS_ENCODING_TOKEN_MAX]; +}; + +struct ndis_remove_key { + ULONG struct_size; + ndis_key_index index; + mac_address bssid; +}; + +struct ndis_fixed_ies { + UCHAR time_stamp[8]; + USHORT beacon_interval; + USHORT capa; +}; + +struct ndis_variable_ies { + ULONG elem_id; + UCHAR length; + UCHAR data[1]; +}; + +enum ndis_reload_defaults { Ndis802_11ReloadWEPKeys }; + +struct ndis_assoc_info { + ULONG length; + USHORT req_ies; + struct req_ie { + USHORT capa; + USHORT listen_interval; + mac_address cur_ap_address; + } req_ie; + ULONG req_ie_length; + ULONG offset_req_ies; + USHORT resp_ies; + struct resp_ie { + USHORT capa; + USHORT status_code; + USHORT assoc_id; + } resp_ie; + ULONG resp_ie_length; + ULONG offset_resp_ies; +}; + +struct ndis_configuration_fh { + ULONG length; + ULONG hop_pattern; + ULONG hop_set; + ULONG dwell_time; +}; + +struct ndis_configuration { + ULONG length; + ULONG beacon_period; + ULONG atim_window; + ULONG ds_config; + struct ndis_configuration_fh fh_config; +}; + +struct ndis_wlan_bssid { + ULONG length; + mac_address mac; + UCHAR reserved[2]; + struct ndis_essid ssid; + ULONG privacy; + ndis_rssi rssi; + UINT net_type; + struct ndis_configuration config; + UINT mode; + ndis_rates rates; +}; + +struct ndis_wlan_bssid_ex { + ULONG length; + mac_address mac; + UCHAR reserved[2]; + struct ndis_essid ssid; + ULONG privacy; + ndis_rssi rssi; + UINT net_type; + struct ndis_configuration config; + UINT mode; + ndis_rates_ex rates_ex; + ULONG ie_length; + UCHAR ies[1]; +}; + +/* we use bssid_list as bssid_list_ex also */ +struct ndis_bssid_list { + ULONG num_items; + struct ndis_wlan_bssid bssid[1]; +}; + +enum ndis_priv_filter { + Ndis802_11PrivFilterAcceptAll, Ndis802_11PrivFilter8021xWEP +}; + +enum network_type { + Ndis802_11FH, Ndis802_11DS, Ndis802_11OFDM5, Ndis802_11OFDM24, + /* MSDN site uses Ndis802_11Automode, which is not mentioned + * in DDK, so add one and assign it to + * Ndis802_11NetworkTypeMax */ + Ndis802_11Automode, Ndis802_11NetworkTypeMax = Ndis802_11Automode +}; + +struct network_type_list { + ULONG num; + enum network_type types[1]; +}; + +enum ndis_power { + NDIS_POWER_OFF = 0, NDIS_POWER_MAX, NDIS_POWER_MIN, +}; + +struct ndis_auth_req { + ULONG length; + mac_address bssid; + ULONG flags; +}; + +struct ndis_bssid_info { + mac_address bssid; + ndis_pmkid_vavlue pmkid; +}; + +struct ndis_pmkid { + ULONG length; + ULONG bssid_info_count; + struct ndis_bssid_info bssid_info[1]; +}; + +int add_wep_key(struct ndis_device *wnd, char *key, int key_len, + int index); +int set_essid(struct ndis_device *wnd, const char *ssid, int ssid_len); +int set_infra_mode(struct ndis_device *wnd, + enum ndis_infrastructure_mode mode); +int get_ap_address(struct ndis_device *wnd, mac_address mac); +int set_ndis_auth_mode(struct ndis_device *wnd, ULONG auth_mode); +int set_iw_auth_mode(struct ndis_device *wnd, int wpa_version, + int auth_80211_alg); +int set_auth_mode(struct ndis_device *wnd); +int set_ndis_encr_mode(struct ndis_device *wnd, int cipher_pairwise, + int cipher_groupwise); +int get_ndis_encr_mode(struct ndis_device *wnd); +int set_encr_mode(struct ndis_device *wnd); +int set_iw_encr_mode(struct ndis_device *wnd, int cipher_pairwise, + int cipher_groupwise); +int get_ndis_auth_mode(struct ndis_device *wnd); +int set_priv_filter(struct ndis_device *wnd); +int set_scan(struct ndis_device *wnd); +NDIS_STATUS disassociate(struct ndis_device *wnd, int reset_ssid); +void set_default_iw_params(struct ndis_device *wnd); +extern const struct iw_handler_def ndis_handler_def; + +#define PRIV_RESET SIOCIWFIRSTPRIV+16 +#define PRIV_POWER_PROFILE SIOCIWFIRSTPRIV+17 +#define PRIV_NETWORK_TYPE SIOCIWFIRSTPRIV+18 +#define PRIV_DEAUTHENTICATE SIOCIWFIRSTPRIV+19 +#define PRIV_MEDIA_STREAM_MODE SIOCIWFIRSTPRIV+20 +#define PRIV_RELOAD_DEFAULTS SIOCIWFIRSTPRIV+23 + +#define RSN_INFO_ELEM 0x30 + +/* these have to match what is in wpa_supplicant */ + +typedef enum { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP } wpa_alg; +typedef enum { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, + CIPHER_WEP104 } wpa_cipher; +typedef enum { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE, + KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE } wpa_key_mgmt; + +#endif // IW_NDIS_H --- linux-2.6.28.orig/ubuntu/ndiswrapper/iw_ndis.c +++ linux-2.6.28/ubuntu/ndiswrapper/iw_ndis.c @@ -0,0 +1,1956 @@ + /* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "iw_ndis.h" +#include "wrapndis.h" + +static int freq_chan[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, + 2447, 2452, 2457, 2462, 2467, 2472, 2484 }; + +static const char *network_names[] = {"IEEE 802.11FH", "IEEE 802.11b", + "IEEE 802.11a", "IEEE 802.11g", "Auto"}; + +int set_essid(struct ndis_device *wnd, const char *ssid, int ssid_len) +{ + NDIS_STATUS res; + struct ndis_essid req; + + if (ssid_len > NDIS_ESSID_MAX_SIZE) + return -EINVAL; + + memset(&req, 0, sizeof(req)); + req.length = ssid_len; + if (ssid_len) + memcpy(&req.essid, ssid, ssid_len); + + res = mp_set(wnd, OID_802_11_SSID, &req, sizeof(req)); + if (res) { + WARNING("setting essid failed (%08X)", res); + EXIT2(return -EINVAL); + } + memcpy(&wnd->essid, &req, sizeof(req)); + EXIT2(return 0); +} + +static int set_assoc_params(struct ndis_device *wnd) +{ + TRACE2("wpa_version=0x%x auth_alg=0x%x key_mgmt=0x%x " + "cipher_pairwise=0x%x cipher_group=0x%x", + wnd->iw_auth_wpa_version, wnd->iw_auth_80211_alg, + wnd->iw_auth_key_mgmt, wnd->iw_auth_cipher_pairwise, + wnd->iw_auth_cipher_group); + set_auth_mode(wnd); + set_priv_filter(wnd); + set_encr_mode(wnd); + return 0; +} + +static int iw_set_essid(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + char ssid[NDIS_ESSID_MAX_SIZE]; + int length; + + ENTER2(""); + memset(ssid, 0, sizeof(ssid)); + /* there is no way to turn off essid other than to set to + * random bytes; instead, we use off to mean any */ + if (wrqu->essid.flags) { + /* wireless-tools prior to version 20 add extra 1, and + * later than 20 don't! Deal with that mess */ + length = wrqu->essid.length - 1; + if (length > 0) + length--; + while (length < wrqu->essid.length && extra[length]) + length++; + TRACE2("%d", length); + if (length <= 0 || length > NDIS_ESSID_MAX_SIZE) + EXIT2(return -EINVAL); + } else + length = 0; + + set_assoc_params(wnd); + + memcpy(ssid, extra, length); + if (set_essid(wnd, ssid, length)) + EXIT2(return -EINVAL); + + EXIT2(return 0); +} + +static int iw_get_essid(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + NDIS_STATUS res; + struct ndis_essid req; + + ENTER2(""); + memset(&req, 0, sizeof(req)); + res = mp_query(wnd, OID_802_11_SSID, &req, sizeof(req)); + if (res) { + WARNING("getting essid failed (%08X)", res); + EXIT2(return -EOPNOTSUPP); + } + memcpy(extra, req.essid, req.length); + if (req.length > 0) + wrqu->essid.flags = 1; + else + wrqu->essid.flags = 0; + wrqu->essid.length = req.length; + EXIT2(return 0); +} + +int set_infra_mode(struct ndis_device *wnd, + enum ndis_infrastructure_mode mode) +{ + NDIS_STATUS res; + unsigned int i; + + ENTER2("%d", mode); + res = mp_query_int(wnd, OID_802_11_INFRASTRUCTURE_MODE, + &wnd->infrastructure_mode); + if (res != NDIS_STATUS_SUCCESS) { + WARNING("getting operating mode to failed (%08X)", res); + EXIT2(return -EINVAL); + } + if (wnd->infrastructure_mode == mode) + EXIT2(return 0); + res = mp_set_int(wnd, OID_802_11_INFRASTRUCTURE_MODE, mode); + if (res) { + WARNING("setting operating mode to %d failed (%08X)", + mode, res); + EXIT2(return -EINVAL); + } + /* NDIS drivers clear keys when infrastructure mode is + * changed. But Linux tools assume otherwise. So set the + * keys */ + if (wnd->iw_auth_key_mgmt == 0 || + wnd->iw_auth_key_mgmt == IW_AUTH_KEY_MGMT_802_1X) { + for (i = 0; i < MAX_ENCR_KEYS; i++) { + if (wnd->encr_info.keys[i].length > 0) + add_wep_key(wnd, wnd->encr_info.keys[i].key, + wnd->encr_info.keys[i].length, i); + } + } + wnd->infrastructure_mode = mode; + EXIT2(return 0); +} + +static int iw_set_infra_mode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + enum ndis_infrastructure_mode ndis_mode; + + ENTER2("%d", wrqu->mode); + switch (wrqu->mode) { + case IW_MODE_ADHOC: + ndis_mode = Ndis802_11IBSS; + break; + case IW_MODE_INFRA: + ndis_mode = Ndis802_11Infrastructure; + break; + case IW_MODE_AUTO: + ndis_mode = Ndis802_11AutoUnknown; + break; + default: + EXIT2(return -EINVAL); + } + + if (set_infra_mode(wnd, ndis_mode)) + EXIT2(return -EINVAL); + + EXIT2(return 0); +} + +static int iw_get_infra_mode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + int ndis_mode, iw_mode; + NDIS_STATUS res; + + ENTER2(""); + res = mp_query_int(wnd, OID_802_11_INFRASTRUCTURE_MODE, &ndis_mode); + if (res) { + WARNING("getting operating mode failed (%08X)", res); + EXIT2(return -EOPNOTSUPP); + } + + switch(ndis_mode) { + case Ndis802_11IBSS: + iw_mode = IW_MODE_ADHOC; + break; + case Ndis802_11Infrastructure: + iw_mode = IW_MODE_INFRA; + break; + case Ndis802_11AutoUnknown: + iw_mode = IW_MODE_AUTO; + break; + default: + ERROR("invalid operating mode (%u)", ndis_mode); + EXIT2(return -EINVAL); + } + wrqu->mode = iw_mode; + EXIT2(return 0); +} + +static const char *network_type_to_name(int net_type) +{ + if (net_type >= 0 && + net_type < (sizeof(network_names)/sizeof(network_names[0]))) + return network_names[net_type]; + else + return network_names[sizeof(network_names) / + sizeof(network_names[0]) - 1]; +} + +static int iw_get_network_type(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + unsigned int network_type; + NDIS_STATUS res; + + ENTER2(""); + res = mp_query_int(wnd, OID_802_11_NETWORK_TYPE_IN_USE, + &network_type); + if (res) { + WARNING("getting network type failed: %08X", res); + network_type = -1; + } + strncpy(wrqu->name, network_type_to_name(network_type), + sizeof(wrqu->name) - 1); + wrqu->name[sizeof(wrqu->name)-1] = 0; + return 0; +} + +static int iw_get_freq(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + NDIS_STATUS res; + struct ndis_configuration req; + + ENTER2(""); + memset(&req, 0, sizeof(req)); + res = mp_query(wnd, OID_802_11_CONFIGURATION, &req, sizeof(req)); + if (res) { + WARNING("getting configuration failed (%08X)", res); + EXIT2(return -EOPNOTSUPP); + } + + memset(&(wrqu->freq), 0, sizeof(struct iw_freq)); + + /* see comment in wireless.h above the "struct iw_freq" + definition for an explanation of this if + NOTE: 1000000 is due to the kHz + */ + if (req.ds_config > 1000000) { + wrqu->freq.m = req.ds_config / 10; + wrqu->freq.e = 1; + } + else + wrqu->freq.m = req.ds_config; + + /* convert from kHz to Hz */ + wrqu->freq.e += 3; + + return 0; +} + +static int iw_set_freq(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + NDIS_STATUS res; + struct ndis_configuration req; + + ENTER2(""); + /* this OID is valid only when not associated */ + if (netif_carrier_ok(wnd->net_dev)) + EXIT2(return 0); + memset(&req, 0, sizeof(req)); + res = mp_query(wnd, OID_802_11_CONFIGURATION, &req, sizeof(req)); + if (res) { + WARNING("getting configuration failed (%08X)", res); + EXIT2(return 0); + } + + if (wrqu->freq.m < 1000 && wrqu->freq.e == 0) { + if (wrqu->freq.m >= 1 && + wrqu->freq.m <= (sizeof(freq_chan) / sizeof(freq_chan[0]))) + req.ds_config = freq_chan[wrqu->freq.m - 1] * 1000; + else + return -EINVAL; + } else { + int i; + req.ds_config = wrqu->freq.m; + for (i = wrqu->freq.e; i > 0; i--) + req.ds_config *= 10; + req.ds_config /= 1000; + } + res = mp_set(wnd, OID_802_11_CONFIGURATION, &req, sizeof(req)); + if (res) + WARNING("setting configuration failed (%08X)", res); + return 0; +} + +static int iw_get_tx_power(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + ndis_tx_power_level ndis_power; + NDIS_STATUS res; + + ENTER2(""); + res = mp_query(wnd, OID_802_11_TX_POWER_LEVEL, + &ndis_power, sizeof(ndis_power)); + if (res) + return -EOPNOTSUPP; + wrqu->txpower.flags = IW_TXPOW_MWATT; + wrqu->txpower.disabled = 0; + wrqu->txpower.fixed = 0; + wrqu->txpower.value = ndis_power; + return 0; +} + +static int iw_set_tx_power(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + ndis_tx_power_level ndis_power; + NDIS_STATUS res; + + ENTER2(""); + if (wrqu->txpower.disabled) + ndis_power = 0; + else { + if (wrqu->txpower.flags == IW_TXPOW_MWATT) + ndis_power = wrqu->txpower.value; + else { // wrqu->txpower.flags == IW_TXPOW_DBM + if (wrqu->txpower.value > 20) + ndis_power = 128; + else if (wrqu->txpower.value < -43) + ndis_power = 127; + else { + signed char tmp; + tmp = wrqu->txpower.value; + tmp = -12 - tmp; + tmp <<= 2; + ndis_power = (unsigned char)tmp; + } + } + } + TRACE2("%d", ndis_power); + res = mp_set(wnd, OID_802_11_TX_POWER_LEVEL, + &ndis_power, sizeof(ndis_power)); + if (res) + EXIT2(return -EOPNOTSUPP); + if (ndis_power == 0) + res = disassociate(wnd, 0); + EXIT2(return 0); +} + +static int iw_get_bitrate(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + ULONG ndis_rate; + int res; + + ENTER2(""); + res = mp_query(wnd, OID_GEN_LINK_SPEED, &ndis_rate, sizeof(ndis_rate)); + if (res) { + WARNING("getting bitrate failed (%08X)", res); + ndis_rate = 0; + } + + wrqu->bitrate.value = ndis_rate * 100; + return 0; +} + +static int iw_set_bitrate(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + int i, n; + NDIS_STATUS res; + ndis_rates_ex rates; + + ENTER2(""); + if (wrqu->bitrate.fixed == 0) + EXIT2(return 0); + + res = mp_query_info(wnd, OID_802_11_SUPPORTED_RATES, &rates, + sizeof(rates), &n, NULL); + if (res) { + WARNING("getting bit rate failed (%08X)", res); + EXIT2(return 0); + } + for (i = 0; i < n; i++) { + if (rates[i] & 0x80) + continue; + if ((rates[i] & 0x7f) * 500000 > wrqu->bitrate.value) { + TRACE2("setting rate %d to 0", + (rates[i] & 0x7f) * 500000); + rates[i] = 0; + } + } + + res = mp_set(wnd, OID_802_11_DESIRED_RATES, &rates, n); + if (res) { + WARNING("setting bit rate failed (%08X)", res); + EXIT2(return 0); + } + + return 0; +} + +static int iw_set_dummy(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + /* Do nothing. Used for ioctls that are not implemented. */ + return 0; +} + +static int iw_get_rts_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + ndis_rts_threshold threshold; + NDIS_STATUS res; + + ENTER2(""); + res = mp_query(wnd, OID_802_11_RTS_THRESHOLD, + &threshold, sizeof(threshold)); + if (res) + return -EOPNOTSUPP; + + wrqu->rts.value = threshold; + return 0; +} + +static int iw_set_rts_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + ndis_rts_threshold threshold; + NDIS_STATUS res; + + ENTER2(""); + threshold = wrqu->rts.value; + res = mp_set(wnd, OID_802_11_RTS_THRESHOLD, + &threshold, sizeof(threshold)); + if (res == NDIS_STATUS_INVALID_DATA) + return -EINVAL; + if (res) + return -EOPNOTSUPP; + + return 0; +} + +static int iw_get_frag_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + ndis_fragmentation_threshold frag_threshold; + NDIS_STATUS res; + + ENTER2(""); + res = mp_query(wnd, OID_802_11_FRAGMENTATION_THRESHOLD, + &frag_threshold, sizeof(frag_threshold)); + if (res) + return -ENOTSUPP; + + wrqu->frag.value = frag_threshold; + return 0; +} + +static int iw_set_frag_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + ndis_rts_threshold threshold; + NDIS_STATUS res; + + ENTER2(""); + threshold = wrqu->frag.value; + res = mp_set(wnd, OID_802_11_FRAGMENTATION_THRESHOLD, + &threshold, sizeof(threshold)); + if (res == NDIS_STATUS_INVALID_DATA) + return -EINVAL; + if (res) + return -EOPNOTSUPP; + return 0; +} + +int get_ap_address(struct ndis_device *wnd, mac_address ap_addr) +{ + NDIS_STATUS res; + + res = mp_query(wnd, OID_802_11_BSSID, ap_addr, ETH_ALEN); + TRACE2(MACSTRSEP, MAC2STR(ap_addr)); + if (res) { + TRACE2("res: %08X", res); + memset(ap_addr, 0x0, ETH_ALEN); + EXIT2(return -EOPNOTSUPP); + } + EXIT2(return 0); +} + +static int iw_get_ap_address(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + mac_address ap_addr; + + ENTER2(""); + get_ap_address(wnd, ap_addr); + memcpy(wrqu->ap_addr.sa_data, ap_addr, ETH_ALEN); + wrqu->ap_addr.sa_family = ARPHRD_ETHER; + EXIT2(return 0); +} + +static int iw_set_ap_address(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + NDIS_STATUS res; + mac_address ap_addr; + + ENTER2(""); + memcpy(ap_addr, wrqu->ap_addr.sa_data, ETH_ALEN); + TRACE2(MACSTRSEP, MAC2STR(ap_addr)); + res = mp_set(wnd, OID_802_11_BSSID, ap_addr, ETH_ALEN); + /* user apps may set ap's mac address, which is not required; + * they may fail to work if this function fails, so return + * success */ + if (res) + WARNING("setting AP mac address failed (%08X)", res); + + EXIT2(return 0); +} + +int set_iw_auth_mode(struct ndis_device *wnd, int wpa_version, + int auth_80211_alg) +{ + NDIS_STATUS res; + ULONG auth_mode; + + ENTER2("%d, %d", wpa_version, auth_80211_alg); + if (wpa_version & IW_AUTH_WPA_VERSION_WPA2) { + if (wnd->iw_auth_key_mgmt & IW_AUTH_KEY_MGMT_802_1X) + auth_mode = Ndis802_11AuthModeWPA2; + else + auth_mode = Ndis802_11AuthModeWPA2PSK; + } else if (wpa_version & IW_AUTH_WPA_VERSION_WPA) { + if (wnd->iw_auth_key_mgmt & IW_AUTH_KEY_MGMT_802_1X) + auth_mode = Ndis802_11AuthModeWPA; + else if (wnd->iw_auth_key_mgmt & IW_AUTH_KEY_MGMT_PSK) + auth_mode = Ndis802_11AuthModeWPAPSK; + else + auth_mode = Ndis802_11AuthModeWPANone; + } else if (auth_80211_alg & IW_AUTH_ALG_SHARED_KEY) { + if (auth_80211_alg & IW_AUTH_ALG_OPEN_SYSTEM) + auth_mode = Ndis802_11AuthModeAutoSwitch; + else + auth_mode = Ndis802_11AuthModeShared; + } else + auth_mode = Ndis802_11AuthModeOpen; + + res = mp_set_int(wnd, OID_802_11_AUTHENTICATION_MODE, auth_mode); + if (res) { + WARNING("setting auth mode to %u failed (%08X)", + auth_mode, res); + if (res == NDIS_STATUS_INVALID_DATA) + EXIT2(return -EINVAL); + return -EOPNOTSUPP; + } + wnd->iw_auth_wpa_version = wpa_version; + wnd->iw_auth_80211_alg = auth_80211_alg; + EXIT2(return 0); +} + +int set_ndis_auth_mode(struct ndis_device *wnd, ULONG auth_mode) +{ + NDIS_STATUS res; + + ENTER2("%d", auth_mode); + res = mp_set_int(wnd, OID_802_11_AUTHENTICATION_MODE, auth_mode); + if (res) { + WARNING("setting auth mode to %u failed (%08X)", + auth_mode, res); + if (res == NDIS_STATUS_INVALID_DATA) + EXIT2(return -EINVAL); + return -EOPNOTSUPP; + } + switch (auth_mode) { + case Ndis802_11AuthModeWPA: + wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_WPA; + wnd->iw_auth_key_mgmt = IW_AUTH_KEY_MGMT_802_1X; + break; + case Ndis802_11AuthModeWPAPSK: + wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_WPA; + wnd->iw_auth_key_mgmt = IW_AUTH_KEY_MGMT_PSK; + case Ndis802_11AuthModeWPANone: + wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_DISABLED; + wnd->iw_auth_key_mgmt = IW_AUTH_KEY_MGMT_PSK; + break; + case Ndis802_11AuthModeWPA2: + wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_WPA2; + wnd->iw_auth_key_mgmt = IW_AUTH_KEY_MGMT_802_1X; + break; + case Ndis802_11AuthModeWPA2PSK: + wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_WPA2; + wnd->iw_auth_key_mgmt = IW_AUTH_KEY_MGMT_PSK; + break; + case Ndis802_11AuthModeOpen: + wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_DISABLED; + wnd->iw_auth_80211_alg = IW_AUTH_ALG_OPEN_SYSTEM; + break; + case Ndis802_11AuthModeShared: + wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_DISABLED; + wnd->iw_auth_80211_alg = IW_AUTH_ALG_SHARED_KEY; + break; + case Ndis802_11AuthModeAutoSwitch: + wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_DISABLED; + wnd->iw_auth_80211_alg = IW_AUTH_ALG_SHARED_KEY; + wnd->iw_auth_80211_alg |= IW_AUTH_ALG_OPEN_SYSTEM; + break; + default: + WARNING("invalid authentication algorithm: %d", auth_mode); + break; + } + EXIT2(return 0); +} + +int set_auth_mode(struct ndis_device *wnd) +{ + return set_iw_auth_mode(wnd, wnd->iw_auth_wpa_version, + wnd->iw_auth_80211_alg); +} + +int get_ndis_auth_mode(struct ndis_device *wnd) +{ + ULONG mode; + NDIS_STATUS res; + + res = mp_query_int(wnd, OID_802_11_AUTHENTICATION_MODE, &mode); + if (res) { + WARNING("getting authentication mode failed (%08X)", res); + EXIT2(return -EOPNOTSUPP); + } + TRACE2("%d", mode); + return mode; +} + +int set_iw_encr_mode(struct ndis_device *wnd, int cipher_pairwise, + int cipher_groupwise) +{ + NDIS_STATUS res; + ULONG ndis_mode; + + ENTER2("%d, %d", cipher_pairwise, cipher_groupwise); + if (cipher_pairwise & IW_AUTH_CIPHER_CCMP) + ndis_mode = Ndis802_11Encryption3Enabled; + else if (cipher_pairwise & IW_AUTH_CIPHER_TKIP) + ndis_mode = Ndis802_11Encryption2Enabled; + else if (cipher_pairwise & + (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104)) + ndis_mode = Ndis802_11Encryption1Enabled; + else if (cipher_groupwise & IW_AUTH_CIPHER_CCMP) + ndis_mode = Ndis802_11Encryption3Enabled; + else if (cipher_groupwise & IW_AUTH_CIPHER_TKIP) + ndis_mode = Ndis802_11Encryption2Enabled; + else + ndis_mode = Ndis802_11EncryptionDisabled; + + res = mp_set_int(wnd, OID_802_11_ENCRYPTION_STATUS, ndis_mode); + if (res) { + WARNING("setting encryption mode to %u failed (%08X)", + ndis_mode, res); + if (res == NDIS_STATUS_INVALID_DATA) + EXIT2(return -EINVAL); + return -EOPNOTSUPP; + } + wnd->iw_auth_cipher_pairwise = cipher_pairwise; + wnd->iw_auth_cipher_group = cipher_groupwise; + EXIT2(return 0); +} + +int set_encr_mode(struct ndis_device *wnd) +{ + return set_iw_encr_mode(wnd, wnd->iw_auth_cipher_pairwise, + wnd->iw_auth_cipher_group); +} + +int get_ndis_encr_mode(struct ndis_device *wnd) +{ + ULONG mode; + NDIS_STATUS res; + + ENTER2(""); + res = mp_query_int(wnd, OID_802_11_ENCRYPTION_STATUS, &mode); + if (res) { + WARNING("getting encryption status failed (%08X)", res); + EXIT2(return -EOPNOTSUPP); + } else + EXIT2(return mode); +} + +static int iw_get_encr(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + int index, mode; + struct encr_info *encr_info = &wnd->encr_info; + + ENTER2("wnd = %p", wnd); + wrqu->data.length = 0; + extra[0] = 0; + + index = (wrqu->encoding.flags & IW_ENCODE_INDEX); + TRACE2("index = %u", index); + if (index > 0) + index--; + else + index = encr_info->tx_key_index; + + if (index < 0 || index >= MAX_ENCR_KEYS) { + WARNING("encryption index out of range (%u)", index); + EXIT2(return -EINVAL); + } + + if (index != encr_info->tx_key_index) { + if (encr_info->keys[index].length > 0) { + wrqu->data.flags |= IW_ENCODE_ENABLED; + wrqu->data.length = encr_info->keys[index].length; + memcpy(extra, encr_info->keys[index].key, + encr_info->keys[index].length); + } + else + wrqu->data.flags |= IW_ENCODE_DISABLED; + + EXIT2(return 0); + } + + /* transmit key */ + mode = get_ndis_encr_mode(wnd); + if (mode < 0) + EXIT2(return -EOPNOTSUPP); + + if (mode == Ndis802_11EncryptionDisabled || + mode == Ndis802_11EncryptionNotSupported) + wrqu->data.flags |= IW_ENCODE_DISABLED; + else { + if (mode == Ndis802_11Encryption1KeyAbsent || + mode == Ndis802_11Encryption2KeyAbsent || + mode == Ndis802_11Encryption3KeyAbsent) + wrqu->data.flags |= IW_ENCODE_NOKEY; + else { + wrqu->data.flags |= IW_ENCODE_ENABLED; + wrqu->encoding.flags |= index+1; + wrqu->data.length = encr_info->keys[index].length; + memcpy(extra, encr_info->keys[index].key, + encr_info->keys[index].length); + } + } + mode = get_ndis_auth_mode(wnd); + if (mode < 0) + EXIT2(return -EOPNOTSUPP); + + if (mode == Ndis802_11AuthModeOpen) + wrqu->data.flags |= IW_ENCODE_OPEN; + else if (mode == Ndis802_11AuthModeAutoSwitch) + wrqu->data.flags |= IW_ENCODE_RESTRICTED; + else // Ndis802_11AuthModeAutoSwitch, Ndis802_11AuthModeWPA etc. + wrqu->data.flags |= IW_ENCODE_RESTRICTED; + + EXIT2(return 0); +} + +/* index must be 0 - N, as per NDIS */ +int add_wep_key(struct ndis_device *wnd, char *key, int key_len, + int index) +{ + struct ndis_encr_key ndis_key; + NDIS_STATUS res; + + ENTER2("key index: %d, length: %d", index, key_len); + if (key_len <= 0 || key_len > NDIS_ENCODING_TOKEN_MAX) { + WARNING("invalid key length (%d)", key_len); + EXIT2(return -EINVAL); + } + if (index < 0 || index >= MAX_ENCR_KEYS) { + WARNING("invalid key index (%d)", index); + EXIT2(return -EINVAL); + } + ndis_key.struct_size = sizeof(ndis_key); + ndis_key.length = key_len; + memcpy(&ndis_key.key, key, key_len); + ndis_key.index = index; + + if (index == wnd->encr_info.tx_key_index) { + ndis_key.index |= (1 << 31); + res = set_iw_encr_mode(wnd, IW_AUTH_CIPHER_WEP104, + IW_AUTH_CIPHER_NONE); + if (res) + WARNING("encryption couldn't be enabled (%08X)", res); + } + TRACE2("key %d: " MACSTRSEP, index, MAC2STR(key)); + res = mp_set(wnd, OID_802_11_ADD_WEP, &ndis_key, sizeof(ndis_key)); + if (res) { + WARNING("adding encryption key %d failed (%08X)", + index+1, res); + EXIT2(return -EINVAL); + } + + /* Atheros driver messes up ndis_key during ADD_WEP, so + * don't rely on that; instead use info in key and key_len */ + wnd->encr_info.keys[index].length = key_len; + memcpy(&wnd->encr_info.keys[index].key, key, key_len); + + EXIT2(return 0); +} + +/* remove_key is for both wep and wpa */ +static int remove_key(struct ndis_device *wnd, int index, + mac_address bssid) +{ + NDIS_STATUS res; + if (wnd->encr_info.keys[index].length == 0) + EXIT2(return 0); + wnd->encr_info.keys[index].length = 0; + memset(&wnd->encr_info.keys[index].key, 0, + sizeof(wnd->encr_info.keys[index].length)); + if (wnd->iw_auth_cipher_pairwise == IW_AUTH_CIPHER_TKIP || + wnd->iw_auth_cipher_pairwise == IW_AUTH_CIPHER_CCMP || + wnd->iw_auth_cipher_group == IW_AUTH_CIPHER_TKIP || + wnd->iw_auth_cipher_group == IW_AUTH_CIPHER_CCMP) { + struct ndis_remove_key remove_key; + remove_key.struct_size = sizeof(remove_key); + remove_key.index = index; + if (bssid) { + /* pairwise key */ + if (memcmp(bssid, "\xff\xff\xff\xff\xff\xff", + ETH_ALEN) != 0) + remove_key.index |= (1 << 30); + memcpy(remove_key.bssid, bssid, + sizeof(remove_key.bssid)); + } else + memset(remove_key.bssid, 0xff, + sizeof(remove_key.bssid)); + if (mp_set(wnd, OID_802_11_REMOVE_KEY, + &remove_key, sizeof(remove_key))) + EXIT2(return -EINVAL); + } else { + ndis_key_index keyindex = index; + res = mp_set_int(wnd, OID_802_11_REMOVE_WEP, keyindex); + if (res) { + WARNING("removing encryption key %d failed (%08X)", + keyindex, res); + EXIT2(return -EINVAL); + } + } + /* if it is transmit key, disable encryption */ + if (index == wnd->encr_info.tx_key_index) { + res = set_iw_encr_mode(wnd, IW_AUTH_CIPHER_NONE, + IW_AUTH_CIPHER_NONE); + if (res) + WARNING("changing encr status failed (%08X)", res); + } + TRACE2("key %d removed", index); + EXIT2(return 0); +} + +static int iw_set_wep(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + NDIS_STATUS res; + unsigned int index, key_len; + struct encr_info *encr_info = &wnd->encr_info; + unsigned char *key; + + ENTER2(""); + index = (wrqu->encoding.flags & IW_ENCODE_INDEX); + TRACE2("index = %u", index); + + /* iwconfig gives index as 1 - N */ + if (index > 0) + index--; + else + index = encr_info->tx_key_index; + + if (index < 0 || index >= MAX_ENCR_KEYS) { + WARNING("encryption index out of range (%u)", index); + EXIT2(return -EINVAL); + } + + /* remove key if disabled */ + if (wrqu->data.flags & IW_ENCODE_DISABLED) { + if (remove_key(wnd, index, NULL)) + EXIT2(return -EINVAL); + else + EXIT2(return 0); + } + + /* global encryption state (for all keys) */ + if (wrqu->data.flags & IW_ENCODE_OPEN) + res = set_ndis_auth_mode(wnd, Ndis802_11AuthModeOpen); + else // if (wrqu->data.flags & IW_ENCODE_RESTRICTED) + res = set_ndis_auth_mode(wnd, Ndis802_11AuthModeShared); + if (res) { + WARNING("setting authentication mode failed (%08X)", res); + EXIT2(return -EINVAL); + } + + TRACE2("key length: %d", wrqu->data.length); + + if (wrqu->data.length > 0) { + key_len = wrqu->data.length; + key = extra; + } else { // must be set as tx key + if (encr_info->keys[index].length == 0) { + WARNING("key %d is not set", index+1); + EXIT2(return -EINVAL); + } + key_len = encr_info->keys[index].length; + key = encr_info->keys[index].key; + encr_info->tx_key_index = index; + } + + if (add_wep_key(wnd, key, key_len, index)) + EXIT2(return -EINVAL); + + if (index == encr_info->tx_key_index) { + /* if transmit key is at index other than 0, some + * drivers, at least Atheros and TI, want another + * (global) non-transmit key to be set; don't know why */ + if (index != 0) { + int i; + for (i = 0; i < MAX_ENCR_KEYS; i++) + if (i != index && + encr_info->keys[i].length != 0) + break; + if (i == MAX_ENCR_KEYS) { + if (index == 0) + i = index + 1; + else + i = index - 1; + if (add_wep_key(wnd, key, key_len, i)) + WARNING("couldn't add broadcast key" + " at %d", i); + } + } + /* ndis drivers want essid to be set after setting encr */ + set_essid(wnd, wnd->essid.essid, wnd->essid.length); + } + EXIT2(return 0); +} + +static int iw_set_nick(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + + if (wrqu->data.length >= IW_ESSID_MAX_SIZE || wrqu->data.length <= 0) + return -EINVAL; + memcpy(wnd->nick, extra, wrqu->data.length); + wnd->nick[wrqu->data.length] = 0; + return 0; +} + +static int iw_get_nick(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + + wrqu->data.length = strlen(wnd->nick); + memcpy(extra, wnd->nick, wrqu->data.length); + return 0; +} + +static char *ndis_translate_scan(struct net_device *dev, char *event, + char *end_buf, void *item, + struct iw_request_info *info) +{ + struct iw_event iwe; + char *current_val; + int i, nrates; + unsigned char buf[MAX_WPA_IE_LEN * 2 + 30]; + struct ndis_wlan_bssid *bssid; + struct ndis_wlan_bssid_ex *bssid_ex; + + ENTER2("%p, %p", event, item); + bssid = item; + bssid_ex = item; + /* add mac address */ + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWAP; + iwe.u.ap_addr.sa_family = ARPHRD_ETHER; + iwe.len = IW_EV_ADDR_LEN; + memcpy(iwe.u.ap_addr.sa_data, bssid->mac, ETH_ALEN); + event = iwe_stream_add_event(info, event, end_buf, &iwe, IW_EV_ADDR_LEN); + + /* add essid */ + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWESSID; + iwe.u.data.length = bssid->ssid.length; + if (iwe.u.data.length > IW_ESSID_MAX_SIZE) + iwe.u.data.length = IW_ESSID_MAX_SIZE; + iwe.u.data.flags = 1; + iwe.len = IW_EV_POINT_LEN + iwe.u.data.length; + event = iwe_stream_add_point(info, event, end_buf, &iwe, bssid->ssid.essid); + + /* add protocol name */ + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWNAME; + strncpy(iwe.u.name, network_type_to_name(bssid->net_type), IFNAMSIZ); + event = iwe_stream_add_event(info, event, end_buf, &iwe, IW_EV_CHAR_LEN); + + /* add mode */ + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWMODE; + if (bssid->mode == Ndis802_11IBSS) + iwe.u.mode = IW_MODE_ADHOC; + else if (bssid->mode == Ndis802_11Infrastructure) + iwe.u.mode = IW_MODE_INFRA; + else // if (bssid->mode == Ndis802_11AutoUnknown) + iwe.u.mode = IW_MODE_AUTO; + event = iwe_stream_add_event(info, event, end_buf, &iwe, IW_EV_UINT_LEN); + + /* add freq */ + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWFREQ; + iwe.u.freq.m = bssid->config.ds_config; + if (bssid->config.ds_config > 1000000) { + iwe.u.freq.m = bssid->config.ds_config / 10; + iwe.u.freq.e = 1; + } + else + iwe.u.freq.m = bssid->config.ds_config; + /* convert from kHz to Hz */ + iwe.u.freq.e += 3; + iwe.len = IW_EV_FREQ_LEN; + event = iwe_stream_add_event(info, event, end_buf, &iwe, IW_EV_FREQ_LEN); + + /* add qual */ + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = IWEVQUAL; + i = 100 * (bssid->rssi - WL_NOISE) / (WL_SIGMAX - WL_NOISE); + if (i < 0) + i = 0; + else if (i > 100) + i = 100; + iwe.u.qual.level = bssid->rssi; + iwe.u.qual.noise = WL_NOISE; + iwe.u.qual.qual = i; + iwe.len = IW_EV_QUAL_LEN; + event = iwe_stream_add_event(info, event, end_buf, &iwe, IW_EV_QUAL_LEN); + + /* add key info */ + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWENCODE; + if (bssid->privacy == Ndis802_11PrivFilterAcceptAll) + iwe.u.data.flags = IW_ENCODE_DISABLED; + else + iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; + iwe.u.data.length = 0; + iwe.len = IW_EV_POINT_LEN; + event = iwe_stream_add_point(info, event, end_buf, &iwe, bssid->ssid.essid); + + /* add rate */ + memset(&iwe, 0, sizeof(iwe)); + current_val = event + IW_EV_LCP_LEN; + iwe.cmd = SIOCGIWRATE; + if (bssid->length > sizeof(*bssid)) + nrates = NDIS_MAX_RATES_EX; + else + nrates = NDIS_MAX_RATES; + for (i = 0 ; i < nrates ; i++) { + if (bssid->rates[i] & 0x7f) { + iwe.u.bitrate.value = ((bssid->rates[i] & 0x7f) * + 500000); + current_val = iwe_stream_add_value(info, event, current_val, + end_buf, &iwe, + IW_EV_PARAM_LEN); + } + } + + if ((current_val - event) > IW_EV_LCP_LEN) + event = current_val; + + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = IWEVCUSTOM; + sprintf(buf, "bcn_int=%d", bssid->config.beacon_period); + iwe.u.data.length = strlen(buf); + event = iwe_stream_add_point(info, event, end_buf, &iwe, buf); + + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = IWEVCUSTOM; + sprintf(buf, "atim=%u", bssid->config.atim_window); + iwe.u.data.length = strlen(buf); + event = iwe_stream_add_point(info, event, end_buf, &iwe, buf); + + TRACE2("%d, %u", bssid->length, (unsigned int)sizeof(*bssid)); + if (bssid->length > sizeof(*bssid)) { + unsigned char *iep = (unsigned char *)bssid_ex->ies + + sizeof(struct ndis_fixed_ies); + no_warn_unused unsigned char *end = iep + bssid_ex->ie_length; + + while (iep + 1 < end && iep + 2 + iep[1] <= end) { + unsigned char ielen = 2 + iep[1]; + + if (ielen > SSID_MAX_WPA_IE_LEN) { + iep += ielen; + continue; + } + if ((iep[0] == WLAN_EID_GENERIC && iep[1] >= 4 && + memcmp(iep + 2, "\x00\x50\xf2\x01", 4) == 0) || + iep[0] == RSN_INFO_ELEM) { + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = IWEVGENIE; + iwe.u.data.length = ielen; + event = iwe_stream_add_point(info, event, end_buf, + &iwe, iep); + } + iep += ielen; + } + } + TRACE2("event = %p, current_val = %p", event, current_val); + EXIT2(return event); +} + +int set_scan(struct ndis_device *wnd) +{ + NDIS_STATUS res; + + ENTER2(""); + res = mp_set(wnd, OID_802_11_BSSID_LIST_SCAN, NULL, 0); + if (res) { + WARNING("scanning failed (%08X)", res); + EXIT2(return -EOPNOTSUPP); + } + wnd->scan_timestamp = jiffies; + EXIT2(return 0); +} + +static int iw_set_scan(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + return set_scan(wnd); +} + +static int iw_get_scan(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + unsigned int i, list_len, needed; + NDIS_STATUS res; + struct ndis_bssid_list *bssid_list = NULL; + char *event = extra; + struct ndis_wlan_bssid *cur_item ; + + ENTER2(""); + if (time_before(jiffies, wnd->scan_timestamp + 3 * HZ)) + return -EAGAIN; + /* try with space for a few scan items */ + list_len = sizeof(ULONG) + sizeof(struct ndis_wlan_bssid_ex) * 8; + bssid_list = kmalloc(list_len, GFP_KERNEL); + if (!bssid_list) { + ERROR("couldn't allocate memory"); + return -ENOMEM; + } + /* some drivers don't set bssid_list->num_items to 0 if + OID_802_11_BSSID_LIST returns no items (prism54 driver, e.g.,) */ + memset(bssid_list, 0, list_len); + + needed = 0; + res = mp_query_info(wnd, OID_802_11_BSSID_LIST, + bssid_list, list_len, NULL, &needed); + if (res == NDIS_STATUS_INVALID_LENGTH || + res == NDIS_STATUS_BUFFER_TOO_SHORT) { + /* now try with required space */ + kfree(bssid_list); + list_len = needed; + bssid_list = kmalloc(list_len, GFP_KERNEL); + if (!bssid_list) { + ERROR("couldn't allocate memory"); + return -ENOMEM; + } + memset(bssid_list, 0, list_len); + + res = mp_query(wnd, OID_802_11_BSSID_LIST, + bssid_list, list_len); + } + if (res) { + WARNING("getting BSSID list failed (%08X)", res); + kfree(bssid_list); + EXIT2(return -EOPNOTSUPP); + } + TRACE2("%d", bssid_list->num_items); + cur_item = &bssid_list->bssid[0]; + for (i = 0; i < bssid_list->num_items; i++) { + event = ndis_translate_scan(dev, event, + extra + IW_SCAN_MAX_DATA, cur_item, info); + cur_item = (struct ndis_wlan_bssid *)((char *)cur_item + + cur_item->length); + } + wrqu->data.length = event - extra; + wrqu->data.flags = 0; + kfree(bssid_list); + EXIT2(return 0); +} + +static int iw_set_power_mode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + NDIS_STATUS res; + ULONG power_mode; + + if (wrqu->power.disabled == 1) + power_mode = NDIS_POWER_OFF; + else if (wrqu->power.flags & IW_POWER_MIN) + power_mode = NDIS_POWER_MIN; + else // if (wrqu->power.flags & IW_POWER_MAX) + power_mode = NDIS_POWER_MAX; + + TRACE2("%d", power_mode); + res = mp_set(wnd, OID_802_11_POWER_MODE, + &power_mode, sizeof(power_mode)); + if (res) + WARNING("setting power mode failed (%08X)", res); + return 0; +} + +static int iw_get_power_mode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + NDIS_STATUS res; + ULONG power_mode; + + ENTER2(""); + res = mp_query(wnd, OID_802_11_POWER_MODE, + &power_mode, sizeof(power_mode)); + if (res) + return -ENOTSUPP; + + if (power_mode == NDIS_POWER_OFF) + wrqu->power.disabled = 1; + else { + if (wrqu->power.flags != 0) + return 0; + wrqu->power.flags |= IW_POWER_ALL_R; + wrqu->power.flags |= IW_POWER_TIMEOUT; + wrqu->power.value = 0; + wrqu->power.disabled = 0; + + if (power_mode == NDIS_POWER_MIN) + wrqu->power.flags |= IW_POWER_MIN; + else // if (power_mode == NDIS_POWER_MAX) + wrqu->power.flags |= IW_POWER_MAX; + } + return 0; +} + +static int iw_get_sensitivity(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + NDIS_STATUS res; + ndis_rssi rssi_trigger; + + ENTER2(""); + res = mp_query(wnd, OID_802_11_RSSI_TRIGGER, + &rssi_trigger, sizeof(rssi_trigger)); + if (res) + return -EOPNOTSUPP; + wrqu->param.value = rssi_trigger; + wrqu->param.disabled = (rssi_trigger == 0); + wrqu->param.fixed = 1; + return 0; +} + +static int iw_set_sensitivity(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + NDIS_STATUS res; + ndis_rssi rssi_trigger; + + ENTER2(""); + if (wrqu->param.disabled) + rssi_trigger = 0; + else + rssi_trigger = wrqu->param.value; + res = mp_set(wnd, OID_802_11_RSSI_TRIGGER, + &rssi_trigger, sizeof(rssi_trigger)); + if (res == NDIS_STATUS_INVALID_DATA) + return -EINVAL; + if (res) + return -EOPNOTSUPP; + return 0; +} + +static int iw_get_ndis_stats(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + struct iw_statistics *stats = &wnd->iw_stats; + memcpy(&wrqu->qual, &stats->qual, sizeof(stats->qual)); + return 0; +} + +static int iw_get_range(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct iw_range *range = (struct iw_range *)extra; + struct iw_point *data = &wrqu->data; + struct ndis_device *wnd = netdev_priv(dev); + unsigned int i, n; + NDIS_STATUS res; + ndis_rates_ex rates; + ndis_tx_power_level tx_power; + + ENTER2(""); + data->length = sizeof(struct iw_range); + memset(range, 0, sizeof(struct iw_range)); + + range->txpower_capa = IW_TXPOW_MWATT; + range->num_txpower = 0; + + res = mp_query(wnd, OID_802_11_TX_POWER_LEVEL, + &tx_power, sizeof(tx_power)); + if (!res) { + range->num_txpower = 1; + range->txpower[0] = tx_power; + } + + range->we_version_compiled = WIRELESS_EXT; + range->we_version_source = 18; + + range->retry_capa = IW_RETRY_LIMIT; + range->retry_flags = IW_RETRY_LIMIT; + range->min_retry = 0; + range->max_retry = 255; + + range->num_channels = 1; + + range->max_qual.qual = 100; + range->max_qual.level = 154; + range->max_qual.noise = 154; + range->sensitivity = 3; + + range->max_encoding_tokens = 4; + range->num_encoding_sizes = 2; + range->encoding_size[0] = 5; + range->encoding_size[1] = 13; + + range->num_bitrates = 0; + memset(&rates, 0, sizeof(rates)); + res = mp_query_info(wnd, OID_802_11_SUPPORTED_RATES, + &rates, sizeof(rates), &n, NULL); + if (res) + WARNING("getting bit rates failed: %08X", res); + else { + for (i = 0; i < n && range->num_bitrates < IW_MAX_BITRATES; i++) + if (rates[i] & 0x80) + continue; + else if (rates[i] & 0x7f) { + range->bitrate[range->num_bitrates] = + (rates[i] & 0x7f) * 500000; + range->num_bitrates++; + } + } + + range->num_channels = (sizeof(freq_chan)/sizeof(freq_chan[0])); + + for (i = 0; i < (sizeof(freq_chan)/sizeof(freq_chan[0])) && + i < IW_MAX_FREQUENCIES; i++) { + range->freq[i].i = i + 1; + range->freq[i].m = freq_chan[i] * 100000; + range->freq[i].e = 1; + } + range->num_frequency = i; + + range->min_rts = 0; + range->max_rts = 2347; + range->min_frag = 256; + range->max_frag = 2346; + + /* Event capability (kernel + driver) */ + range->event_capa[0] = (IW_EVENT_CAPA_K_0 | + IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) | + IW_EVENT_CAPA_MASK(SIOCGIWAP) | + IW_EVENT_CAPA_MASK(SIOCGIWSCAN)); + range->event_capa[1] = IW_EVENT_CAPA_K_1; + range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVTXDROP) | + IW_EVENT_CAPA_MASK(IWEVCUSTOM) | + IW_EVENT_CAPA_MASK(IWEVREGISTERED) | + IW_EVENT_CAPA_MASK(IWEVEXPIRED)); + + range->enc_capa = 0; + + if (test_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr)) + range->enc_capa |= IW_ENC_CAPA_CIPHER_TKIP; + if (test_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr)) + range->enc_capa |= IW_ENC_CAPA_CIPHER_CCMP; + + if (test_bit(Ndis802_11AuthModeWPA, &wnd->capa.auth) || + test_bit(Ndis802_11AuthModeWPAPSK, &wnd->capa.auth)) + range->enc_capa |= IW_ENC_CAPA_WPA; + if (test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) || + test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth)) + range->enc_capa |= IW_ENC_CAPA_WPA2; + + return 0; +} + +void set_default_iw_params(struct ndis_device *wnd) +{ + wnd->iw_auth_key_mgmt = 0; + wnd->iw_auth_wpa_version = 0; + set_infra_mode(wnd, Ndis802_11Infrastructure); + set_ndis_auth_mode(wnd, Ndis802_11AuthModeOpen); + set_priv_filter(wnd); + set_iw_encr_mode(wnd, IW_AUTH_CIPHER_NONE, IW_AUTH_CIPHER_NONE); +} + +static int deauthenticate(struct ndis_device *wnd) +{ + int ret; + + ENTER2(""); + ret = disassociate(wnd, 1); + set_default_iw_params(wnd); + EXIT2(return ret); +} + +NDIS_STATUS disassociate(struct ndis_device *wnd, int reset_ssid) +{ + NDIS_STATUS res; + u8 buf[NDIS_ESSID_MAX_SIZE]; + int i; + + TRACE2(""); + res = mp_set(wnd, OID_802_11_DISASSOCIATE, NULL, 0); + /* disassociate causes radio to be turned off; if reset_ssid + * is given, set ssid to random to enable radio */ + if (reset_ssid) { + get_random_bytes(buf, sizeof(buf)); + for (i = 0; i < sizeof(buf); i++) + buf[i] = 'a' + (buf[i] % 26); + set_essid(wnd, buf, sizeof(buf)); + } + return res; +} + +static ULONG ndis_priv_mode(struct ndis_device *wnd) +{ + if (wnd->iw_auth_wpa_version & IW_AUTH_WPA_VERSION_WPA2 || + wnd->iw_auth_wpa_version & IW_AUTH_WPA_VERSION_WPA) + return Ndis802_11PrivFilter8021xWEP; + else + return Ndis802_11PrivFilterAcceptAll; +} + +int set_priv_filter(struct ndis_device *wnd) +{ + NDIS_STATUS res; + ULONG flags; + + flags = ndis_priv_mode(wnd); + ENTER2("filter: %d", flags); + res = mp_set_int(wnd, OID_802_11_PRIVACY_FILTER, flags); + if (res) + TRACE2("setting privacy filter to %d failed (%08X)", + flags, res); + EXIT2(return 0); +} + +static int iw_set_mlme(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + struct iw_mlme *mlme = (struct iw_mlme *)extra; + + ENTER2(""); + switch (mlme->cmd) { + case IW_MLME_DEAUTH: + return deauthenticate(wnd); + case IW_MLME_DISASSOC: + TRACE2("cmd=%d reason_code=%d", mlme->cmd, mlme->reason_code); + return disassociate(wnd, 1); + default: + return -EOPNOTSUPP; + } + + return 0; +} + +static int iw_set_genie(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + /* + * NDIS drivers do not allow IEs to be configured; this is + * done by the driver based on other configuration. Return 0 + * to avoid causing issues with user space programs that + * expect this function to succeed. + */ + return 0; +} + +static int iw_set_auth(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + TRACE2("index=%d value=%d", wrqu->param.flags & IW_AUTH_INDEX, + wrqu->param.value); + switch (wrqu->param.flags & IW_AUTH_INDEX) { + case IW_AUTH_WPA_VERSION: + wnd->iw_auth_wpa_version = wrqu->param.value; + break; + case IW_AUTH_CIPHER_PAIRWISE: + wnd->iw_auth_cipher_pairwise = wrqu->param.value; + break; + case IW_AUTH_CIPHER_GROUP: + wnd->iw_auth_cipher_group = wrqu->param.value; + break; + case IW_AUTH_KEY_MGMT: + wnd->iw_auth_key_mgmt = wrqu->param.value; + break; + case IW_AUTH_80211_AUTH_ALG: + wnd->iw_auth_80211_alg = wrqu->param.value; + break; + case IW_AUTH_WPA_ENABLED: + if (wrqu->param.value) + deauthenticate(wnd); + break; + case IW_AUTH_TKIP_COUNTERMEASURES: + case IW_AUTH_DROP_UNENCRYPTED: + case IW_AUTH_RX_UNENCRYPTED_EAPOL: + case IW_AUTH_PRIVACY_INVOKED: + TRACE2("%d not implemented: %d", + wrqu->param.flags & IW_AUTH_INDEX, wrqu->param.value); + break; + default: + WARNING("invalid cmd %d", wrqu->param.flags & IW_AUTH_INDEX); + return -EOPNOTSUPP; + } + return 0; +} + +static int iw_get_auth(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + + ENTER2("index=%d", wrqu->param.flags & IW_AUTH_INDEX); + switch (wrqu->param.flags & IW_AUTH_INDEX) { + case IW_AUTH_WPA_VERSION: + wrqu->param.value = wnd->iw_auth_wpa_version; + break; + case IW_AUTH_CIPHER_PAIRWISE: + wrqu->param.value = wnd->iw_auth_cipher_pairwise; + break; + case IW_AUTH_CIPHER_GROUP: + wrqu->param.value = wnd->iw_auth_cipher_group; + break; + case IW_AUTH_KEY_MGMT: + wrqu->param.value = wnd->iw_auth_key_mgmt; + break; + case IW_AUTH_80211_AUTH_ALG: + wrqu->param.value = wnd->iw_auth_80211_alg; + break; + default: + WARNING("invalid cmd %d", wrqu->param.flags & IW_AUTH_INDEX); + return -EOPNOTSUPP; + } + return 0; +} + +static int iw_set_encodeext(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; + struct ndis_device *wnd = netdev_priv(dev); + struct ndis_add_key ndis_key; + int i, keyidx; + NDIS_STATUS res; + u8 *addr; + + keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX; + ENTER2("%d", keyidx); + if (keyidx) + keyidx--; + else + keyidx = wnd->encr_info.tx_key_index; + + if (keyidx < 0 || keyidx >= MAX_ENCR_KEYS) + return -EINVAL; + + if (ext->alg == WPA_ALG_WEP) { + if (!test_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr)) + EXIT2(return -1); + if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) + wnd->encr_info.tx_key_index = keyidx; + if (add_wep_key(wnd, ext->key, ext->key_len, keyidx)) + EXIT2(return -1); + else + EXIT2(return 0); + } + if ((wrqu->encoding.flags & IW_ENCODE_DISABLED) || + ext->alg == IW_ENCODE_ALG_NONE || ext->key_len == 0) + EXIT2(return remove_key(wnd, keyidx, ndis_key.bssid)); + + if (ext->key_len > sizeof(ndis_key.key)) { + TRACE2("incorrect key length (%u)", ext->key_len); + EXIT2(return -1); + } + + memset(&ndis_key, 0, sizeof(ndis_key)); + + ndis_key.struct_size = + sizeof(ndis_key) - sizeof(ndis_key.key) + ext->key_len; + ndis_key.length = ext->key_len; + ndis_key.index = keyidx; + + if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { + for (i = 0; i < 6 ; i++) + ndis_key.rsc |= (((u64)ext->rx_seq[i]) << (i * 8)); + TRACE2("0x%Lx", ndis_key.rsc); + ndis_key.index |= 1 << 29; + } + + addr = ext->addr.sa_data; + if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { + /* group key */ + if (wnd->infrastructure_mode == Ndis802_11IBSS) + memset(ndis_key.bssid, 0xff, ETH_ALEN); + else + get_ap_address(wnd, ndis_key.bssid); + } else { + /* pairwise key */ + ndis_key.index |= (1 << 30); + memcpy(ndis_key.bssid, addr, ETH_ALEN); + } + TRACE2(MACSTRSEP, MAC2STR(ndis_key.bssid)); + + if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) + ndis_key.index |= (1 << 31); + + if (ext->alg == IW_ENCODE_ALG_TKIP && ext->key_len == 32) { + /* wpa_supplicant gives us the Michael MIC RX/TX keys in + * different order than NDIS spec, so swap the order here. */ + memcpy(ndis_key.key, ext->key, 16); + memcpy(ndis_key.key + 16, ext->key + 24, 8); + memcpy(ndis_key.key + 24, ext->key + 16, 8); + } else + memcpy(ndis_key.key, ext->key, ext->key_len); + + res = mp_set(wnd, OID_802_11_ADD_KEY, &ndis_key, ndis_key.struct_size); + if (res) { + TRACE2("adding key failed (%08X), %u", + res, ndis_key.struct_size); + EXIT2(return -1); + } + wnd->encr_info.keys[keyidx].length = ext->key_len; + memcpy(&wnd->encr_info.keys[keyidx].key, ndis_key.key, ext->key_len); + if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) + wnd->encr_info.tx_key_index = keyidx; + TRACE2("key %d added", keyidx); + + EXIT2(return 0); +} + +static int iw_get_encodeext(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + /* struct iw_encode_ext *ext = (struct iw_encode_ext *) extra; */ + /* TODO */ + ENTER2(""); + return 0; +} + +static int iw_set_pmksa(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct iw_pmksa *pmksa = (struct iw_pmksa *)extra; + struct ndis_pmkid pmkid; + NDIS_STATUS res; + struct ndis_device *wnd = netdev_priv(dev); + + /* TODO: must keep local list of PMKIDs since NDIS drivers + * expect that all PMKID entries are included whenever a new + * one is added. */ + + ENTER2("%d", pmksa->cmd); + if ((pmksa->cmd == IW_PMKSA_ADD || pmksa->cmd == IW_PMKSA_REMOVE) && + (!(wnd->iw_auth_wpa_version & IW_AUTH_WPA_VERSION_WPA2))) + EXIT2(return -EOPNOTSUPP); + + memset(&pmkid, 0, sizeof(pmkid)); + if (pmksa->cmd == IW_PMKSA_ADD) { + pmkid.bssid_info_count = 1; + memcpy(pmkid.bssid_info[0].bssid, pmksa->bssid.sa_data, + ETH_ALEN); + memcpy(pmkid.bssid_info[0].pmkid, pmksa->pmkid, IW_PMKID_LEN); + } + pmkid.length = sizeof(pmkid); + + res = mp_set(wnd, OID_802_11_PMKID, &pmkid, pmkid.length); + if (res == NDIS_STATUS_FAILURE) + EXIT2(return -EOPNOTSUPP); + TRACE2("OID_802_11_PMKID -> %d", res); + if (res) + return -EINVAL; + + return 0; +} + +#define WEXT(id) [id - SIOCIWFIRST] + +static const iw_handler ndis_handler[] = { + WEXT(SIOCGIWNAME) = iw_get_network_type, + WEXT(SIOCSIWESSID) = iw_set_essid, + WEXT(SIOCGIWESSID) = iw_get_essid, + WEXT(SIOCSIWMODE) = iw_set_infra_mode, + WEXT(SIOCGIWMODE) = iw_get_infra_mode, + WEXT(SIOCGIWFREQ) = iw_get_freq, + WEXT(SIOCSIWFREQ) = iw_set_freq, + WEXT(SIOCGIWTXPOW) = iw_get_tx_power, + WEXT(SIOCSIWTXPOW) = iw_set_tx_power, + WEXT(SIOCGIWRATE) = iw_get_bitrate, + WEXT(SIOCSIWRATE) = iw_set_bitrate, + WEXT(SIOCGIWRTS) = iw_get_rts_threshold, + WEXT(SIOCSIWRTS) = iw_set_rts_threshold, + WEXT(SIOCGIWFRAG) = iw_get_frag_threshold, + WEXT(SIOCSIWFRAG) = iw_set_frag_threshold, + WEXT(SIOCGIWAP) = iw_get_ap_address, + WEXT(SIOCSIWAP) = iw_set_ap_address, + WEXT(SIOCSIWENCODE) = iw_set_wep, + WEXT(SIOCGIWENCODE) = iw_get_encr, + WEXT(SIOCSIWSCAN) = iw_set_scan, + WEXT(SIOCGIWSCAN) = iw_get_scan, + WEXT(SIOCGIWPOWER) = iw_get_power_mode, + WEXT(SIOCSIWPOWER) = iw_set_power_mode, + WEXT(SIOCGIWRANGE) = iw_get_range, + WEXT(SIOCGIWSTATS) = iw_get_ndis_stats, + WEXT(SIOCGIWSENS) = iw_get_sensitivity, + WEXT(SIOCSIWSENS) = iw_set_sensitivity, + WEXT(SIOCGIWNICKN) = iw_get_nick, + WEXT(SIOCSIWNICKN) = iw_set_nick, + WEXT(SIOCSIWCOMMIT) = iw_set_dummy, + WEXT(SIOCSIWMLME) = iw_set_mlme, + WEXT(SIOCSIWGENIE) = iw_set_genie, + WEXT(SIOCSIWAUTH) = iw_set_auth, + WEXT(SIOCGIWAUTH) = iw_get_auth, + WEXT(SIOCSIWENCODEEXT) = iw_set_encodeext, + WEXT(SIOCGIWENCODEEXT) = iw_get_encodeext, + WEXT(SIOCSIWPMKSA) = iw_set_pmksa, +}; + +/* private ioctl's */ + +static int priv_reset(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int res; + ENTER2(""); + res = mp_reset(netdev_priv(dev)); + if (res) { + WARNING("reset failed: %08X", res); + return -EOPNOTSUPP; + } + return 0; +} + +static int priv_deauthenticate(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int res; + ENTER2(""); + res = deauthenticate(netdev_priv(dev)); + return res; +} + +static int priv_power_profile(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + struct miniport *mp; + ULONG profile_inf; + + ENTER2(""); + mp = &wnd->wd->driver->ndis_driver->mp; + if (!mp->pnp_event_notify) + EXIT2(return -EOPNOTSUPP); + + /* 1 for AC and 0 for Battery */ + if (wrqu->param.value) + profile_inf = NdisPowerProfileAcOnLine; + else + profile_inf = NdisPowerProfileBattery; + + LIN2WIN4(mp->pnp_event_notify, wnd->nmb->mp_ctx, + NdisDevicePnPEventPowerProfileChanged, + &profile_inf, sizeof(profile_inf)); + EXIT2(return 0); +} + +static int priv_network_type(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + enum network_type network_type; + NDIS_STATUS res; + char type; + + ENTER2(""); + type = wrqu->param.value; + if (type == 'f') + network_type = Ndis802_11FH; + else if (type == 'b') + network_type = Ndis802_11DS; + else if (type == 'a') + network_type = Ndis802_11OFDM5; + else if (type == 'g' || type == 'n') + network_type = Ndis802_11OFDM24; + else + network_type = Ndis802_11Automode; + + res = mp_set_int(wnd, OID_802_11_NETWORK_TYPE_IN_USE, network_type); + if (res) { + WARNING("setting network type to %d failed (%08X)", + network_type, res); + EXIT2(return -EINVAL); + } + + EXIT2(return 0); +} + +static int priv_media_stream_mode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + NDIS_STATUS res; + int mode; + + ENTER2(""); + if (wrqu->param.value > 0) + mode = Ndis802_11MediaStreamOn; + else + mode = Ndis802_11MediaStreamOff; + res = mp_set_int(wnd, OID_802_11_MEDIA_STREAM_MODE, mode); + if (res) { + WARNING("oid failed (%08X)", res); + EXIT2(return -EINVAL); + } + EXIT2(return 0); +} + +static int priv_reload_defaults(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + int res; + ENTER2(""); + res = mp_set_int(wnd, OID_802_11_RELOAD_DEFAULTS, + Ndis802_11ReloadWEPKeys); + if (res) { + WARNING("reloading defaults failed: %08X", res); + return -EOPNOTSUPP; + } + return 0; +} + +static const struct iw_priv_args priv_args[] = { + {PRIV_RESET, 0, 0, "ndis_reset"}, + {PRIV_POWER_PROFILE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, + "power_profile"}, + {PRIV_DEAUTHENTICATE, 0, 0, "deauthenticate"}, + {PRIV_NETWORK_TYPE, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 1, 0, + "network_type"}, + {PRIV_MEDIA_STREAM_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, + "media_stream"}, + + {PRIV_RELOAD_DEFAULTS, 0, 0, "reload_defaults"}, +}; + +#define WEPRIV(id) [id - SIOCIWFIRSTPRIV] + +static const iw_handler priv_handler[] = { + WEPRIV(PRIV_RESET) = priv_reset, + WEPRIV(PRIV_POWER_PROFILE) = priv_power_profile, + WEPRIV(PRIV_DEAUTHENTICATE) = priv_deauthenticate, + WEPRIV(PRIV_NETWORK_TYPE) = priv_network_type, + WEPRIV(PRIV_MEDIA_STREAM_MODE) = priv_media_stream_mode, + WEPRIV(PRIV_RELOAD_DEFAULTS) = priv_reload_defaults, +}; + +const struct iw_handler_def ndis_handler_def = { + .num_standard = sizeof(ndis_handler) / sizeof(ndis_handler[0]), + .num_private = sizeof(priv_handler) / sizeof(priv_handler[0]), + .num_private_args = sizeof(priv_args) / sizeof(priv_args[0]), + + .standard = (iw_handler *)ndis_handler, + .private = (iw_handler *)priv_handler, + .private_args = (struct iw_priv_args *)priv_args, + .get_wireless_stats = get_iw_stats, +}; --- linux-2.6.28.orig/ubuntu/ndiswrapper/divdi3.c +++ linux-2.6.28/ubuntu/ndiswrapper/divdi3.c @@ -0,0 +1,329 @@ +/* 64-bit multiplication and division + Copyright (C) 1989, 1992-1999, 2000, 2001, 2002, 2003 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include + +#if BITS_PER_LONG != 32 +#error This is for 32-bit targets only +#endif + +typedef unsigned int UQItype __attribute__ ((mode (QI))); +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef int DItype __attribute__ ((mode (DI))); +typedef unsigned int UDItype __attribute__ ((mode (DI))); +#define Wtype SItype +#define HWtype SItype +#define DWtype DItype +#define UWtype USItype +#define UHWtype USItype +#define UDWtype UDItype +#define W_TYPE_SIZE 32 + +#include "longlong.h" + +#if defined(__BIG_ENDIAN) +struct DWstruct { Wtype high, low;}; +#elif defined(__LITTLE_ENDIAN) +struct DWstruct { Wtype low, high;}; +#else +#error Unhandled endianity +#endif +typedef union { struct DWstruct s; DWtype ll; } DWunion; + +/* Prototypes of exported functions. */ +extern DWtype __divdi3 (DWtype u, DWtype v); +extern DWtype __moddi3 (DWtype u, DWtype v); +extern UDWtype __udivdi3 (UDWtype u, UDWtype v); +extern UDWtype __umoddi3 (UDWtype u, UDWtype v); + +static UDWtype +__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp) +{ + DWunion ww; + DWunion nn, dd; + DWunion rr; + UWtype d0, d1, n0, n1, n2; + UWtype q0, q1; + UWtype b, bm; + + nn.ll = n; + dd.ll = d; + + d0 = dd.s.low; + d1 = dd.s.high; + n0 = nn.s.low; + n1 = nn.s.high; + +#if !UDIV_NEEDS_NORMALIZATION + if (d1 == 0) + { + if (d0 > n1) + { + /* 0q = nn / 0D */ + + udiv_qrnnd (q0, n0, n1, n0, d0); + q1 = 0; + + /* Remainder in n0. */ + } + else + { + /* qq = NN / 0d */ + + if (d0 == 0) + d0 = 1 / d0; /* Divide intentionally by zero. */ + + udiv_qrnnd (q1, n1, 0, n1, d0); + udiv_qrnnd (q0, n0, n1, n0, d0); + + /* Remainder in n0. */ + } + + if (rp != 0) + { + rr.s.low = n0; + rr.s.high = 0; + *rp = rr.ll; + } + } + +#else /* UDIV_NEEDS_NORMALIZATION */ + + if (d1 == 0) + { + if (d0 > n1) + { + /* 0q = nn / 0D */ + + count_leading_zeros (bm, d0); + + if (bm != 0) + { + /* Normalize, i.e. make the most significant bit of the + denominator set. */ + + d0 = d0 << bm; + n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm)); + n0 = n0 << bm; + } + + udiv_qrnnd (q0, n0, n1, n0, d0); + q1 = 0; + + /* Remainder in n0 >> bm. */ + } + else + { + /* qq = NN / 0d */ + + if (d0 == 0) + d0 = 1 / d0; /* Divide intentionally by zero. */ + + count_leading_zeros (bm, d0); + + if (bm == 0) + { + /* From (n1 >= d0) /\ (the most significant bit of d0 is set), + conclude (the most significant bit of n1 is set) /\ (the + leading quotient digit q1 = 1). + + This special case is necessary, not an optimization. + (Shifts counts of W_TYPE_SIZE are undefined.) */ + + n1 -= d0; + q1 = 1; + } + else + { + /* Normalize. */ + + b = W_TYPE_SIZE - bm; + + d0 = d0 << bm; + n2 = n1 >> b; + n1 = (n1 << bm) | (n0 >> b); + n0 = n0 << bm; + + udiv_qrnnd (q1, n1, n2, n1, d0); + } + + /* n1 != d0... */ + + udiv_qrnnd (q0, n0, n1, n0, d0); + + /* Remainder in n0 >> bm. */ + } + + if (rp != 0) + { + rr.s.low = n0 >> bm; + rr.s.high = 0; + *rp = rr.ll; + } + } +#endif /* UDIV_NEEDS_NORMALIZATION */ + + else + { + if (d1 > n1) + { + /* 00 = nn / DD */ + + q0 = 0; + q1 = 0; + + /* Remainder in n1n0. */ + if (rp != 0) + { + rr.s.low = n0; + rr.s.high = n1; + *rp = rr.ll; + } + } + else + { + /* 0q = NN / dd */ + + count_leading_zeros (bm, d1); + if (bm == 0) + { + /* From (n1 >= d1) /\ (the most significant bit of d1 is set), + conclude (the most significant bit of n1 is set) /\ (the + quotient digit q0 = 0 or 1). + + This special case is necessary, not an optimization. */ + + /* The condition on the next line takes advantage of that + n1 >= d1 (true due to program flow). */ + if (n1 > d1 || n0 >= d0) + { + q0 = 1; + sub_ddmmss (n1, n0, n1, n0, d1, d0); + } + else + q0 = 0; + + q1 = 0; + + if (rp != 0) + { + rr.s.low = n0; + rr.s.high = n1; + *rp = rr.ll; + } + } + else + { + UWtype m1, m0; + /* Normalize. */ + + b = W_TYPE_SIZE - bm; + + d1 = (d1 << bm) | (d0 >> b); + d0 = d0 << bm; + n2 = n1 >> b; + n1 = (n1 << bm) | (n0 >> b); + n0 = n0 << bm; + + udiv_qrnnd (q0, n1, n2, n1, d1); + umul_ppmm (m1, m0, q0, d0); + + if (m1 > n1 || (m1 == n1 && m0 > n0)) + { + q0--; + sub_ddmmss (m1, m0, m1, m0, d1, d0); + } + + q1 = 0; + + /* Remainder in (n1n0 - m1m0) >> bm. */ + if (rp != 0) + { + sub_ddmmss (n1, n0, n1, n0, m1, m0); + rr.s.low = (n1 << b) | (n0 >> bm); + rr.s.high = n1 >> bm; + *rp = rr.ll; + } + } + } + } + + ww.s.low = q0; + ww.s.high = q1; + return ww.ll; +} + +DWtype +__divdi3 (DWtype u, DWtype v) +{ + Wtype c = 0; + DWtype w; + + if (u < 0) + { + c = ~c; + u = -u; + } + if (v < 0) + { + c = ~c; + v = -v; + } + w = __udivmoddi4 (u, v, NULL); + if (c) + w = -w; + return w; +} + +DWtype +__moddi3 (DWtype u, DWtype v) +{ + Wtype c = 0; + DWtype w; + + if (u < 0) + { + c = ~c; + u = -u; + } + if (v < 0) + v = -v; + __udivmoddi4 (u, v, &w); + if (c) + w = -w; + return w; +} + +UDWtype +__udivdi3 (UDWtype u, UDWtype v) +{ + return __udivmoddi4 (u, v, NULL); +} + +UDWtype +__umoddi3 (UDWtype u, UDWtype v) +{ + UDWtype w; + + __udivmoddi4 (u, v, &w); + return w; +} --- linux-2.6.28.orig/ubuntu/ndiswrapper/Makefile +++ linux-2.6.28/ubuntu/ndiswrapper/Makefile @@ -0,0 +1,38 @@ +ndiswrapper-objs := crt.o hal.o iw_ndis.o loader.o ndis.o ntoskernel.o ntoskernel_io.o \ + pe_linker.o pnp.o proc.o rtl.o wrapmem.o wrapndis.o wrapper.o usb.o + +EXPORTS = crt_exports.h hal_exports.h ndis_exports.h ntoskernel_exports.h \ + ntoskernel_io_exports.h rtl_exports.h usb_exports.h + +STUB_SRCS = crt.c hal.c ndis.c ntoskernel.c ntoskernel_io.c \ + pnp.c rtl.c wrapndis.c usb.c + + +EXTRA_CFLAGS += -DENABLE_USB -I$(obj) +EXTRA_AFLAGS += -I$(obj) + +# generate exports symbol table from C files +quiet_cmd_mkexport = MKEXPORT $@ +cmd_mkexport = $(SHELL) $(srctree)/$(src)/mkexport.sh $< $@ + +%_exports.h: %.c $(srctree)/$(src)/mkexport.sh FORCE + $(call if_changed,mkexport) + +$(addprefix $(obj)/,$(EXPORTS:_exports.h=.o)): %.o: %_exports.h +extra-y += $(EXPORTS) + +ifeq ($(CONFIG_X86_64),y) +quiet_cmd_mkstubs = MKSTUBS $@ +cmd_mkstubs = $(SHELL) $(srctree)/$(src)/mkstubs.sh $(addprefix $(srctree)/$(src)/,$(STUB_SRCS)) >$@ + +$(obj)/win2lin_stubs.h: $(addprefix $(srctree)/$(src)/,$(STUB_SRCS)) FORCE + $(call if_changed,mkstubs) + +$(obj)/win2lin_stubs.o: $(obj)/win2lin_stubs.h +extra-y += win2lin_stubs.h +ndiswrapper-objs += win2lin_stubs.o +else +ndiswrapper-objs += divdi3.o +endif + +obj-$(CONFIG_NDISWRAPPER) := ndiswrapper.o --- linux-2.6.28.orig/ubuntu/ndiswrapper/wrapmem.c +++ linux-2.6.28/ubuntu/ndiswrapper/wrapmem.c @@ -0,0 +1,360 @@ +/* + * Copyright (C) 2006 Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#define _WRAPMEM_C_ + +#include "ntoskernel.h" + +struct slack_alloc_info { + struct nt_list list; + size_t size; +}; + +static struct nt_list allocs; +static struct nt_list slack_allocs; +static spinlock_t alloc_lock; + +struct vmem_block { + struct nt_list list; + int size; +}; + +static struct nt_list vmem_list; + +#if defined(ALLOC_DEBUG) +struct alloc_info { + enum alloc_type type; + size_t size; +#if ALLOC_DEBUG > 1 + struct nt_list list; + const char *file; + int line; + ULONG tag; +#endif +}; + +static atomic_t alloc_sizes[ALLOC_TYPE_MAX]; +#endif + +void wrapmem_info(void) +{ +#ifdef ALLOC_DEBUG + enum alloc_type type; + for (type = 0; type < ALLOC_TYPE_MAX; type++) + INFO("total size of allocations in %d: %d", + type, atomic_read(&alloc_sizes[type])); +#endif +} + +/* allocate memory and add it to list of allocated pointers; if a + * driver doesn't free this memory for any reason (buggy driver or we + * allocate space behind driver's back since we need more space than + * corresponding Windows structure provides etc.), this gets freed + * automatically when module is unloaded + */ +void *slack_kmalloc(size_t size) +{ + struct slack_alloc_info *info; + gfp_t flags; + + ENTER4("size = %lu", (unsigned long)size); + + if (irql_gfp() & GFP_ATOMIC) + flags = GFP_ATOMIC; + else + flags = GFP_KERNEL; + info = kmalloc(size + sizeof(*info), flags); + if (!info) + return NULL; + info->size = size; + spin_lock_bh(&alloc_lock); + InsertTailList(&slack_allocs, &info->list); + spin_unlock_bh(&alloc_lock); +#ifdef ALLOC_DEBUG + atomic_add(size, &alloc_sizes[ALLOC_TYPE_SLACK]); +#endif + TRACE4("%p, %p", info, info + 1); + EXIT4(return info + 1); +} + +/* free pointer and remove from list of allocated pointers */ +void slack_kfree(void *ptr) +{ + struct slack_alloc_info *info; + + ENTER4("%p", ptr); + info = ptr - sizeof(*info); + spin_lock_bh(&alloc_lock); + RemoveEntryList(&info->list); + spin_unlock_bh(&alloc_lock); +#ifdef ALLOC_DEBUG + atomic_sub(info->size, &alloc_sizes[ALLOC_TYPE_SLACK]); +#endif + kfree(info); + EXIT4(return); +} + +#if defined(ALLOC_DEBUG) +void *wrap_kmalloc(size_t size, gfp_t flags, const char *file, int line) +{ + struct alloc_info *info; + + info = kmalloc(size + sizeof(*info), flags); + if (!info) + return NULL; + if (flags & GFP_ATOMIC) + info->type = ALLOC_TYPE_KMALLOC_ATOMIC; + else + info->type = ALLOC_TYPE_KMALLOC_NON_ATOMIC; + info->size = size; + atomic_add(size, &alloc_sizes[info->type]); +#if ALLOC_DEBUG > 1 + info->file = file; + info->line = line; + info->tag = 0; + spin_lock_bh(&alloc_lock); + InsertTailList(&allocs, &info->list); + spin_unlock_bh(&alloc_lock); +#endif + TRACE4("%p", info + 1); + return (info + 1); +} + +void *wrap_kzalloc(size_t size, gfp_t flags, const char *file, int line) +{ + void *ptr = wrap_kmalloc(size, flags, file, line); + if (ptr) + memset(ptr, 0, size); + return ptr; +} + +void wrap_kfree(void *ptr) +{ + struct alloc_info *info; + + TRACE4("%p", ptr); + if (!ptr) + return; + info = ptr - sizeof(*info); + atomic_sub(info->size, &alloc_sizes[info->type]); +#if ALLOC_DEBUG > 1 + spin_lock_bh(&alloc_lock); + RemoveEntryList(&info->list); + spin_unlock_bh(&alloc_lock); + if (!(info->type == ALLOC_TYPE_KMALLOC_ATOMIC || + info->type == ALLOC_TYPE_KMALLOC_NON_ATOMIC)) + WARNING("invliad type: %d", info->type); +#endif + kfree(info); +} + +void *wrap_vmalloc(unsigned long size, const char *file, int line) +{ + struct alloc_info *info; + + info = vmalloc(size + sizeof(*info)); + if (!info) + return NULL; + info->type = ALLOC_TYPE_VMALLOC_NON_ATOMIC; + info->size = size; + atomic_add(size, &alloc_sizes[info->type]); +#if ALLOC_DEBUG > 1 + info->file = file; + info->line = line; + info->tag = 0; + spin_lock_bh(&alloc_lock); + InsertTailList(&allocs, &info->list); + spin_unlock_bh(&alloc_lock); +#endif + return (info + 1); +} + +void *wrap__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot, + const char *file, int line) +{ + struct alloc_info *info; + + info = __vmalloc(size + sizeof(*info), gfp_mask, prot); + if (!info) + return NULL; + if (gfp_mask & GFP_ATOMIC) + info->type = ALLOC_TYPE_VMALLOC_ATOMIC; + else + info->type = ALLOC_TYPE_VMALLOC_NON_ATOMIC; + info->size = size; + atomic_add(size, &alloc_sizes[info->type]); +#if ALLOC_DEBUG > 1 + info->file = file; + info->line = line; + info->tag = 0; + spin_lock_bh(&alloc_lock); + InsertTailList(&allocs, &info->list); + spin_unlock_bh(&alloc_lock); +#endif + return (info + 1); +} + +void wrap_vfree(void *ptr) +{ + struct alloc_info *info; + + info = ptr - sizeof(*info); + atomic_sub(info->size, &alloc_sizes[info->type]); +#if ALLOC_DEBUG > 1 + spin_lock_bh(&alloc_lock); + RemoveEntryList(&info->list); + spin_unlock_bh(&alloc_lock); + if (!(info->type == ALLOC_TYPE_VMALLOC_ATOMIC || + info->type == ALLOC_TYPE_VMALLOC_NON_ATOMIC)) + WARNING("invliad type: %d", info->type); +#endif + vfree(info); +} + +void *wrap_alloc_pages(gfp_t flags, unsigned int size, + const char *file, int line) +{ + struct alloc_info *info; + + size += sizeof(*info); + info = (struct alloc_info *)__get_free_pages(flags, get_order(size)); + if (!info) + return NULL; + info->type = ALLOC_TYPE_PAGES; + info->size = size; + atomic_add(size, &alloc_sizes[info->type]); +#if ALLOC_DEBUG > 1 + info->file = file; + info->line = line; + info->tag = 0; + spin_lock_bh(&alloc_lock); + InsertTailList(&allocs, &info->list); + spin_unlock_bh(&alloc_lock); +#endif + return info + 1; +} + +void wrap_free_pages(unsigned long ptr, int order) +{ + struct alloc_info *info; + + info = (void *)ptr - sizeof(*info); + atomic_sub(info->size, &alloc_sizes[info->type]); +#if ALLOC_DEBUG > 1 + spin_lock_bh(&alloc_lock); + RemoveEntryList(&info->list); + spin_unlock_bh(&alloc_lock); + if (info->type != ALLOC_TYPE_PAGES) + WARNING("invliad type: %d", info->type); +#endif + free_pages((unsigned long)info, get_order(info->size)); +} + +#if ALLOC_DEBUG > 1 +#undef ExAllocatePoolWithTag +void *wrap_ExAllocatePoolWithTag(enum pool_type pool_type, SIZE_T size, + ULONG tag, const char *file, int line) +{ + void *addr; + struct alloc_info *info; + + ENTER4("pool_type: %d, size: %lu, tag: %u", pool_type, size, tag); + addr = ExAllocatePoolWithTag(pool_type, size, tag); + if (!addr) + return NULL; + info = addr - sizeof(*info); + info->file = file; + info->line = line; + info->tag = tag; + EXIT4(return addr); +} +#endif + +int alloc_size(enum alloc_type type) +{ + if (type >= 0 && type < ALLOC_TYPE_MAX) + return atomic_read(&alloc_sizes[type]); + else + return -EINVAL; +} + +#endif // ALLOC_DEBUG + +int wrapmem_init(void) +{ + InitializeListHead(&allocs); + InitializeListHead(&slack_allocs); + InitializeListHead(&vmem_list); + spin_lock_init(&alloc_lock); + return 0; +} + +void wrapmem_exit(void) +{ + enum alloc_type type; + struct nt_list *ent; + + /* free all pointers on the slack list */ + while (1) { + struct slack_alloc_info *info; + spin_lock_bh(&alloc_lock); + ent = RemoveHeadList(&slack_allocs); + spin_unlock_bh(&alloc_lock); + if (!ent) + break; + info = container_of(ent, struct slack_alloc_info, list); +#ifdef ALLOC_DEBUG + atomic_sub(info->size, &alloc_sizes[ALLOC_TYPE_SLACK]); +#endif + kfree(info); + } + type = 0; +#ifdef ALLOC_DEBUG + for (type = 0; type < ALLOC_TYPE_MAX; type++) { + int n = atomic_read(&alloc_sizes[type]); + if (n) + WARNING("%d bytes of memory in %d leaking", n, type); + } + +#if ALLOC_DEBUG > 1 + while (1) { + struct alloc_info *info; + + spin_lock_bh(&alloc_lock); + ent = RemoveHeadList(&allocs); + spin_unlock_bh(&alloc_lock); + if (!ent) + break; + info = container_of(ent, struct alloc_info, list); + atomic_sub(info->size, &alloc_sizes[ALLOC_TYPE_SLACK]); + WARNING("%p in %d of size %zu allocated at %s(%d) " + "with tag 0x%08X leaking; freeing it now", + info + 1, info->type, info->size, info->file, + info->line, info->tag); + if (info->type == ALLOC_TYPE_KMALLOC_ATOMIC || + info->type == ALLOC_TYPE_KMALLOC_NON_ATOMIC) + kfree(info); + else if (info->type == ALLOC_TYPE_VMALLOC_ATOMIC || + info->type == ALLOC_TYPE_VMALLOC_NON_ATOMIC) + vfree(info); + else if (info->type == ALLOC_TYPE_PAGES) + free_pages((unsigned long)info, get_order(info->size)); + else + WARNING("invalid type: %d; not freed", info->type); + } +#endif +#endif + return; +} --- linux-2.6.28.orig/ubuntu/ndiswrapper/pnp.c +++ linux-2.6.28/ubuntu/ndiswrapper/pnp.c @@ -0,0 +1,742 @@ +/* + * Copyright (C) 2005 Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#include "usb.h" +#include "pnp.h" +#include "wrapndis.h" +#include "loader.h" + +/* Functions callable from the NDIS driver */ +wstdcall NTSTATUS pdoDispatchDeviceControl(struct device_object *pdo, + struct irp *irp); +wstdcall NTSTATUS pdoDispatchPnp(struct device_object *pdo, struct irp *irp); +wstdcall NTSTATUS pdoDispatchPower(struct device_object *pdo, struct irp *irp); + +static NTSTATUS start_pdo(struct device_object *pdo) +{ + int i, ret, count, resources_size; + struct wrap_device *wd; + struct pci_dev *pdev; + struct cm_partial_resource_descriptor *entry; + struct cm_partial_resource_list *partial_resource_list; + + ENTER1("%p, %p", pdo, pdo->reserved); + wd = pdo->reserved; + if (ntoskernel_init_device(wd)) + EXIT1(return STATUS_FAILURE); + if (wrap_is_usb_bus(wd->dev_bus)) { +#ifdef ENABLE_USB + if (usb_init_device(wd)) { + ntoskernel_exit_device(wd); + EXIT1(return STATUS_FAILURE); + } +#endif + EXIT1(return STATUS_SUCCESS); + } + if (!wrap_is_pci_bus(wd->dev_bus)) + EXIT1(return STATUS_SUCCESS); + pdev = wd->pci.pdev; + ret = pci_enable_device(pdev); + if (ret) { + ERROR("couldn't enable PCI device: %x", ret); + return STATUS_FAILURE; + } + ret = pci_request_regions(pdev, DRIVER_NAME); + if (ret) { + ERROR("couldn't request PCI regions: %x", ret); + goto err_enable; + } + pci_set_power_state(pdev, PCI_D0); +#ifdef CONFIG_X86_64 + /* 64-bit broadcom driver doesn't work if DMA is allocated + * from over 1GB */ + if (wd->vendor == 0x14e4) { + if (pci_set_dma_mask(pdev, DMA_30BIT_MASK) || + pci_set_consistent_dma_mask(pdev, DMA_30BIT_MASK)) + WARNING("couldn't set DMA mask; this driver " + "may not work with more than 1GB RAM"); + } +#endif + /* IRQ resource entry is filled in from pdev, instead of + * pci_resource macros */ + for (i = count = 0; pci_resource_start(pdev, i); i++) + if ((pci_resource_flags(pdev, i) & IORESOURCE_MEM) || + (pci_resource_flags(pdev, i) & IORESOURCE_IO)) + count++; + /* space for entry for IRQ is already in + * cm_partial_resource_list */ + resources_size = sizeof(struct cm_resource_list) + + sizeof(struct cm_partial_resource_descriptor) * count; + TRACE2("resources: %d, %d", count, resources_size); + wd->resource_list = kzalloc(resources_size, GFP_KERNEL); + if (!wd->resource_list) { + WARNING("couldn't allocate memory"); + goto err_regions; + } + wd->resource_list->count = 1; + wd->resource_list->list[0].interface_type = PCIBus; + /* bus_number is not used by WDM drivers */ + wd->resource_list->list[0].bus_number = pdev->bus->number; + + partial_resource_list = + &wd->resource_list->list->partial_resource_list; + partial_resource_list->version = 1; + partial_resource_list->revision = 1; + partial_resource_list->count = count + 1; + + for (i = count = 0; pci_resource_start(pdev, i); i++) { + entry = &partial_resource_list->partial_descriptors[count]; + TRACE2("%d", count); + if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) { + entry->type = CmResourceTypeMemory; + entry->flags = CM_RESOURCE_MEMORY_READ_WRITE; + entry->share = CmResourceShareDeviceExclusive; + } else if (pci_resource_flags(pdev, i) & IORESOURCE_IO) { + entry->type = CmResourceTypePort; + entry->flags = CM_RESOURCE_PORT_IO; + entry->share = CmResourceShareDeviceExclusive; +#if 0 + } else if (pci_resource_flags(pdev, i) & IORESOURCE_DMA) { + /* it looks like no driver uses this resource */ + typeof(pci_resource_flags(pdev, 0)) flags; + entry->type = CmResourceTypeDma; + flags = pci_resource_flags(pdev, i); + if (flags & IORESOURCE_DMA_TYPEA) + entry->flags |= CM_RESOURCE_DMA_TYPE_A; + else if (flags & IORESOURCE_DMA_TYPEB) + entry->flags |= CM_RESOURCE_DMA_TYPE_B; + else if (flags & IORESOURCE_DMA_TYPEF) + entry->flags |= CM_RESOURCE_DMA_TYPE_F; + if (flags & IORESOURCE_DMA_8BIT) + entry->flags |= CM_RESOURCE_DMA_8; + else if (flags & IORESOURCE_DMA_16BIT) + entry->flags |= CM_RESOURCE_DMA_16; + /* what about 32bit DMA? */ + else if (flags & IORESOURCE_DMA_8AND16BIT) + entry->flags |= CM_RESOURCE_DMA_8_AND_16; + if (flags & IORESOURCE_DMA_MASTER) + entry->flags |= CM_RESOURCE_DMA_BUS_MASTER; + entry->u.dma.channel = pci_resource_start(pdev, i); + /* what should this be? */ + entry->u.dma.port = 1; +#endif + } else + continue; + /* TODO: Add other resource types? */ + entry->u.generic.start = + (ULONG_PTR)pci_resource_start(pdev, i); + entry->u.generic.length = pci_resource_len(pdev, i); + count++; + } + + /* put IRQ resource at the end */ + entry = &partial_resource_list->partial_descriptors[count++]; + entry->type = CmResourceTypeInterrupt; + entry->flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE; + /* we assume all devices use shared IRQ */ + entry->share = CmResourceShareShared; + /* as per documentation, interrupt level should be DIRQL, but + * examples from DDK as well some drivers, such as AR5211, + * RT8180L use interrupt level as interrupt vector also in + * NdisMRegisterInterrupt */ + entry->u.interrupt.level = pdev->irq; + entry->u.interrupt.vector = pdev->irq; + entry->u.interrupt.affinity = -1; + + TRACE2("resource list count %d, irq: %d", + partial_resource_list->count, pdev->irq); + pci_set_drvdata(pdev, wd); + EXIT1(return STATUS_SUCCESS); +err_regions: + pci_release_regions(pdev); +err_enable: + pci_disable_device(pdev); + wd->pci.pdev = NULL; + wd->pdo = NULL; + EXIT1(return STATUS_FAILURE); +} + +static void remove_pdo(struct device_object *pdo) +{ + struct wrap_device *wd = pdo->reserved; + + ntoskernel_exit_device(wd); + if (wrap_is_pci_bus(wd->dev_bus)) { + struct pci_dev *pdev = wd->pci.pdev; + pci_release_regions(pdev); + pci_disable_device(pdev); + wd->pci.pdev = NULL; + pci_set_drvdata(pdev, NULL); + } else if (wrap_is_usb_bus(wd->dev_bus)) { +#ifdef ENABLE_USB + usb_exit_device(wd); +#endif + } + if (wd->resource_list) + kfree(wd->resource_list); + wd->resource_list = NULL; + return; +} + +static NTSTATUS IoSendIrpTopDev(struct device_object *dev_obj, ULONG major_fn, + ULONG minor_fn, struct io_stack_location *sl) +{ + NTSTATUS status; + struct nt_event event; + struct irp *irp; + struct io_stack_location *irp_sl; + struct device_object *top_dev = IoGetAttachedDeviceReference(dev_obj); + + KeInitializeEvent(&event, NotificationEvent, FALSE); + irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, top_dev, NULL, 0, NULL, + &event, NULL); + irp->io_status.status = STATUS_NOT_IMPLEMENTED; + irp->io_status.info = 0; + irp_sl = IoGetNextIrpStackLocation(irp); + if (sl) + memcpy(irp_sl, sl, sizeof(*irp_sl)); + irp_sl->major_fn = major_fn; + irp_sl->minor_fn = minor_fn; + status = IoCallDriver(top_dev, irp); + if (status == STATUS_PENDING) { + KeWaitForSingleObject(&event, Executive, KernelMode, + FALSE, NULL); + status = irp->io_status.status; + } + ObDereferenceObject(top_dev); + return status; +} + +wstdcall NTSTATUS pdoDispatchDeviceControl(struct device_object *pdo, + struct irp *irp) +{ + struct io_stack_location *irp_sl; + NTSTATUS status; + + DUMP_IRP(irp); + irp_sl = IoGetCurrentIrpStackLocation(irp); +#ifdef ENABLE_USB + status = wrap_submit_irp(pdo, irp); + IOTRACE("status: %08X", status); + if (status != STATUS_PENDING) + IoCompleteRequest(irp, IO_NO_INCREMENT); +#else + status = irp->io_status.status = STATUS_NOT_IMPLEMENTED; + IoCompleteRequest(irp, IO_NO_INCREMENT); +#endif + IOEXIT(return status); +} +WIN_FUNC_DECL(pdoDispatchDeviceControl,2) + +wstdcall NTSTATUS pdoDispatchPnp(struct device_object *pdo, struct irp *irp) +{ + struct io_stack_location *irp_sl; + struct wrap_device *wd; + NTSTATUS status; +#ifdef ENABLE_USB + struct usbd_bus_interface_usbdi *usb_intf; +#endif + + irp_sl = IoGetCurrentIrpStackLocation(irp); + TRACE2("%p %d:%d", pdo, irp_sl->major_fn, irp_sl->minor_fn); + wd = pdo->reserved; + switch (irp_sl->minor_fn) { + case IRP_MN_START_DEVICE: + status = start_pdo(pdo); + break; + case IRP_MN_QUERY_STOP_DEVICE: + case IRP_MN_STOP_DEVICE: + case IRP_MN_QUERY_REMOVE_DEVICE: + status = STATUS_SUCCESS; + break; + case IRP_MN_REMOVE_DEVICE: + remove_pdo(pdo); + status = STATUS_SUCCESS; + break; + case IRP_MN_QUERY_INTERFACE: +#ifdef ENABLE_USB + if (!wrap_is_usb_bus(wd->dev_bus)) { + status = STATUS_NOT_IMPLEMENTED; + break; + } + TRACE2("type: %x, size: %d, version: %d", + irp_sl->params.query_intf.type->data1, + irp_sl->params.query_intf.size, + irp_sl->params.query_intf.version); + usb_intf = (struct usbd_bus_interface_usbdi *) + irp_sl->params.query_intf.intf; + usb_intf->Context = wd; + usb_intf->InterfaceReference = USBD_InterfaceReference; + usb_intf->InterfaceDereference = USBD_InterfaceDereference; + usb_intf->GetUSBDIVersion = USBD_InterfaceGetUSBDIVersion; + usb_intf->QueryBusTime = USBD_InterfaceQueryBusTime; + usb_intf->SubmitIsoOutUrb = USBD_InterfaceSubmitIsoOutUrb; + usb_intf->QueryBusInformation = + USBD_InterfaceQueryBusInformation; + if (irp_sl->params.query_intf.version >= + USB_BUSIF_USBDI_VERSION_1) + usb_intf->IsDeviceHighSpeed = + USBD_InterfaceIsDeviceHighSpeed; + if (irp_sl->params.query_intf.version >= + USB_BUSIF_USBDI_VERSION_2) + usb_intf->LogEntry = USBD_InterfaceLogEntry; + status = STATUS_SUCCESS; +#else + status = STATUS_NOT_IMPLEMENTED; +#endif + break; + default: + TRACE2("fn %d not implemented", irp_sl->minor_fn); + status = STATUS_SUCCESS; + break; + } + irp->io_status.status = status; + TRACE2("status: %08X", status); + IoCompleteRequest(irp, IO_NO_INCREMENT); + IOEXIT(return status); +} +WIN_FUNC_DECL(pdoDispatchPnp,2) + +wstdcall NTSTATUS pdoDispatchPower(struct device_object *pdo, struct irp *irp) +{ + struct io_stack_location *irp_sl; + struct wrap_device *wd; + union power_state power_state; + struct pci_dev *pdev; + NTSTATUS status; + + irp_sl = IoGetCurrentIrpStackLocation(irp); + wd = pdo->reserved; + TRACE2("pdo: %p, fn: %d:%d, wd: %p", + pdo, irp_sl->major_fn, irp_sl->minor_fn, wd); + switch (irp_sl->minor_fn) { + case IRP_MN_WAIT_WAKE: + /* TODO: this is not complete/correct */ + TRACE2("state: %d, completion: %p", + irp_sl->params.power.state.system_state, + irp_sl->completion_routine); + IoMarkIrpPending(irp); + status = STATUS_PENDING; + break; + case IRP_MN_SET_POWER: + power_state = irp_sl->params.power.state; + if (power_state.device_state == PowerDeviceD0) { + TRACE2("resuming %p", wd); + if (wrap_is_pci_bus(wd->dev_bus)) { + pdev = wd->pci.pdev; + pci_restore_state(pdev); + if (wd->pci.wake_state == PowerDeviceD3) { + pci_enable_wake(wd->pci.pdev, + PCI_D3hot, 0); + pci_enable_wake(wd->pci.pdev, + PCI_D3cold, 0); + } + pci_set_power_state(pdev, PCI_D0); + } else { // usb device +#ifdef ENABLE_USB + wrap_resume_urbs(wd); +#endif + } + } else { + TRACE2("suspending device %p", wd); + if (wrap_is_pci_bus(wd->dev_bus)) { + pdev = wd->pci.pdev; + pci_save_state(pdev); + TRACE2("%d", wd->pci.wake_state); + if (wd->pci.wake_state == PowerDeviceD3) { + pci_enable_wake(wd->pci.pdev, + PCI_D3hot, 1); + pci_enable_wake(wd->pci.pdev, + PCI_D3cold, 1); + } + pci_set_power_state(pdev, PCI_D3hot); + } else { // usb device +#ifdef ENABLE_USB + wrap_suspend_urbs(wd); +#endif + } + } + status = STATUS_SUCCESS; + break; + case IRP_MN_QUERY_POWER: + status = STATUS_SUCCESS; + break; + default: + TRACE2("fn %d not implemented", irp_sl->minor_fn); + status = STATUS_SUCCESS; + break; + } + irp->io_status.status = status; + IoCompleteRequest(irp, IO_NO_INCREMENT); + return status; +} +WIN_FUNC_DECL(pdoDispatchPower,2) + +static NTSTATUS pnp_set_device_power_state(struct wrap_device *wd, + enum device_power_state state) +{ + NTSTATUS status; + struct device_object *pdo; + struct io_stack_location irp_sl; + + pdo = wd->pdo; + IOTRACE("%p, %p", pdo, IoGetAttachedDevice(pdo)); + memset(&irp_sl, 0, sizeof(irp_sl)); + irp_sl.params.power.state.device_state = state; + irp_sl.params.power.type = DevicePowerState; + if (state > PowerDeviceD0) { + status = IoSendIrpTopDev(pdo, IRP_MJ_POWER, IRP_MN_QUERY_POWER, + &irp_sl); + if (status != STATUS_SUCCESS) { + TRACE1("query of power to %d returns %08X", + state, status); + EXIT1(return status); + } + } + status = IoSendIrpTopDev(pdo, IRP_MJ_POWER, IRP_MN_SET_POWER, &irp_sl); + if (status != STATUS_SUCCESS) + WARNING("setting power to %d failed: %08X", state, status); + EXIT1(return status); +} + +NTSTATUS pnp_start_device(struct wrap_device *wd) +{ + struct device_object *fdo; + struct device_object *pdo; + struct io_stack_location irp_sl; + NTSTATUS status; + + pdo = wd->pdo; + /* TODO: for now we use same resources for both translated + * resources and raw resources */ + memset(&irp_sl, 0, sizeof(irp_sl)); + irp_sl.params.start_device.allocated_resources = + wd->resource_list; + irp_sl.params.start_device.allocated_resources_translated = + wd->resource_list; + status = IoSendIrpTopDev(pdo, IRP_MJ_PNP, IRP_MN_START_DEVICE, &irp_sl); + fdo = IoGetAttachedDevice(pdo); + if (status == STATUS_SUCCESS) + fdo->drv_obj->drv_ext->count++; + else + WARNING("Windows driver couldn't initialize the device (%08X)", + status); + EXIT1(return status); +} + +NTSTATUS pnp_stop_device(struct wrap_device *wd) +{ + struct device_object *pdo; + NTSTATUS status; + + pdo = wd->pdo; + status = IoSendIrpTopDev(pdo, IRP_MJ_PNP, IRP_MN_QUERY_STOP_DEVICE, + NULL); + if (status != STATUS_SUCCESS) + WARNING("status: %08X", status); + /* for now we ignore query status */ + status = IoSendIrpTopDev(pdo, IRP_MJ_PNP, IRP_MN_STOP_DEVICE, NULL); + if (status != STATUS_SUCCESS) + WARNING("status: %08X", status); + if (status != STATUS_SUCCESS) + WARNING("status: %08X", status); + EXIT2(return status); +} + +NTSTATUS pnp_remove_device(struct wrap_device *wd) +{ + struct device_object *pdo, *fdo; + struct driver_object *fdo_drv_obj; + NTSTATUS status; + + pdo = wd->pdo; + fdo = IoGetAttachedDevice(pdo); + fdo_drv_obj = fdo->drv_obj; + TRACE2("%p, %p, %p", pdo, fdo, fdo_drv_obj); + status = IoSendIrpTopDev(pdo, IRP_MJ_PNP, IRP_MN_QUERY_REMOVE_DEVICE, + NULL); + if (status != STATUS_SUCCESS) + WARNING("status: %08X", status); + + status = IoSendIrpTopDev(pdo, IRP_MJ_PNP, IRP_MN_REMOVE_DEVICE, NULL); + if (status != STATUS_SUCCESS) + WARNING("status: %08X", status); + /* TODO: should we use count in drv_ext or driver's Object + * header reference count to keep count of devices associated + * with a driver? */ + if (status == STATUS_SUCCESS) + fdo_drv_obj->drv_ext->count--; + TRACE1("count: %d", fdo_drv_obj->drv_ext->count); + if (fdo_drv_obj->drv_ext->count < 0) + WARNING("wrong count: %d", fdo_drv_obj->drv_ext->count); + if (fdo_drv_obj->drv_ext->count == 0) { + struct wrap_driver *wrap_driver; + TRACE1("unloading driver: %p", fdo_drv_obj); + wrap_driver = + IoGetDriverObjectExtension(fdo_drv_obj, + (void *)WRAP_DRIVER_CLIENT_ID); + if (fdo_drv_obj->unload) + LIN2WIN1(fdo_drv_obj->unload, fdo_drv_obj); + if (wrap_driver) { + if (down_interruptible(&loader_mutex)) + WARNING("couldn't obtain loader_mutex"); + unload_wrap_driver(wrap_driver); + up(&loader_mutex); + } else + ERROR("couldn't get wrap_driver"); + ObDereferenceObject(fdo_drv_obj); + } + IoDeleteDevice(pdo); + unload_wrap_device(wd); + EXIT1(return status); +} + +WIN_FUNC_DECL(IoInvalidDeviceRequest,2) + +static struct device_object *alloc_pdo(struct driver_object *drv_obj) +{ + struct device_object *pdo; + NTSTATUS status ; + int i; + struct ansi_string ansi_name; + struct unicode_string unicode_name; + + RtlInitAnsiString(&ansi_name, "NDISpdo"); + if (RtlAnsiStringToUnicodeString(&unicode_name, &ansi_name, TRUE) == + STATUS_SUCCESS) { + status = IoCreateDevice(drv_obj, 0, &unicode_name, + FILE_DEVICE_UNKNOWN, + FILE_AUTOGENERATED_DEVICE_NAME, + FALSE, &pdo); + RtlFreeUnicodeString(&unicode_name); + } else { + status = IoCreateDevice(drv_obj, 0, NULL, + FILE_DEVICE_UNKNOWN, + FILE_AUTOGENERATED_DEVICE_NAME, + FALSE, &pdo); + } + TRACE1("%p, %d, %p", drv_obj, status, pdo); + if (status != STATUS_SUCCESS) + return NULL; + /* dispatch routines are called as Windows functions */ + for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) + drv_obj->major_func[i] = WIN_FUNC_PTR(IoInvalidDeviceRequest,2); + drv_obj->major_func[IRP_MJ_INTERNAL_DEVICE_CONTROL] = + WIN_FUNC_PTR(pdoDispatchDeviceControl,2); + drv_obj->major_func[IRP_MJ_DEVICE_CONTROL] = + WIN_FUNC_PTR(pdoDispatchDeviceControl,2); + drv_obj->major_func[IRP_MJ_POWER] = WIN_FUNC_PTR(pdoDispatchPower,2); + drv_obj->major_func[IRP_MJ_PNP] = WIN_FUNC_PTR(pdoDispatchPnp,2); + return pdo; +} + +static int wrap_pnp_start_device(struct wrap_device *wd) +{ + struct wrap_driver *driver; + struct device_object *pdo; + struct driver_object *pdo_drv_obj; + + ENTER1("wd: %p", wd); + + if (!((wrap_is_pci_bus(wd->dev_bus)) || + (wrap_is_usb_bus(wd->dev_bus)))) { + ERROR("bus type %d (%d) not supported", + WRAP_BUS(wd->dev_bus), wd->dev_bus); + EXIT1(return -EINVAL); + } + driver = load_wrap_driver(wd); + if (!driver) + return -ENODEV; + + wd->driver = driver; + wd->dev_bus = WRAP_DEVICE_BUS(driver->dev_type, WRAP_BUS(wd->dev_bus)); + TRACE1("dev type: %d, bus type: %d, %d", WRAP_DEVICE(wd->dev_bus), + WRAP_BUS(wd->dev_bus), wd->dev_bus); + TRACE1("%d, %d", driver->dev_type, wrap_is_usb_bus(wd->dev_bus)); + /* first create pdo */ + if (wrap_is_pci_bus(wd->dev_bus)) + pdo_drv_obj = find_bus_driver("PCI"); + else // if (wrap_is_usb_bus(wd->dev_bus)) + pdo_drv_obj = find_bus_driver("USB"); + if (!pdo_drv_obj) + return -EINVAL; + pdo = alloc_pdo(pdo_drv_obj); + if (!pdo) + return -ENOMEM; + wd->pdo = pdo; + pdo->reserved = wd; + if (WRAP_DEVICE(wd->dev_bus) == WRAP_NDIS_DEVICE) { + if (init_ndis_driver(driver->drv_obj)) { + IoDeleteDevice(pdo); + return -EINVAL; + } + } + TRACE1("%p", driver->drv_obj->drv_ext->add_device); + if (driver->drv_obj->drv_ext->add_device(driver->drv_obj, pdo) != + STATUS_SUCCESS) { + IoDeleteDevice(pdo); + return -ENOMEM; + } + if (pnp_start_device(wd) != STATUS_SUCCESS) { + /* TODO: we need proper cleanup, to deallocate memory, + * for example */ + pnp_remove_device(wd); + return -EINVAL; + } + return 0; +} + +/* + * This function should not be marked __devinit because PCI IDs are + * added dynamically. + */ +int wrap_pnp_start_pci_device(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct load_device load_device; + struct wrap_device *wd; + + ENTER1("called for %04x:%04x:%04x:%04x", pdev->vendor, pdev->device, + pdev->subsystem_vendor, pdev->subsystem_device); + + load_device.bus = WRAP_PCI_BUS; + load_device.vendor = pdev->vendor; + load_device.device = pdev->device; + load_device.subvendor = pdev->subsystem_vendor; + load_device.subdevice = pdev->subsystem_device; + wd = load_wrap_device(&load_device); + if (!wd) + EXIT1(return -ENODEV); + wd->pci.pdev = pdev; + return wrap_pnp_start_device(wd); +} + +void wrap_pnp_remove_pci_device(struct pci_dev *pdev) +{ + struct wrap_device *wd; + + wd = (struct wrap_device *)pci_get_drvdata(pdev); + ENTER1("%p, %p", pdev, wd); + if (!wd) + EXIT1(return); + pnp_remove_device(wd); +} + +int wrap_pnp_suspend_pci_device(struct pci_dev *pdev, pm_message_t state) +{ + struct wrap_device *wd; + + wd = (struct wrap_device *)pci_get_drvdata(pdev); + return pnp_set_device_power_state(wd, PowerDeviceD3); +} + +int wrap_pnp_resume_pci_device(struct pci_dev *pdev) +{ + struct wrap_device *wd; + + wd = (struct wrap_device *)pci_get_drvdata(pdev); + return pnp_set_device_power_state(wd, PowerDeviceD0); +} + +#ifdef ENABLE_USB +int wrap_pnp_start_usb_device(struct usb_interface *intf, + const struct usb_device_id *usb_id) +{ + struct wrap_device *wd; + int ret; + struct usb_device *udev = interface_to_usbdev(intf); + ENTER1("%04x, %04x, %04x", udev->descriptor.idVendor, + udev->descriptor.idProduct, udev->descriptor.bDeviceClass); + + /* USB device (e.g., RNDIS) may have multiple interfaces; + initialize one interface only (is there a way to know which + of these interfaces is for network?) */ + + if ((wd = get_wrap_device(udev, WRAP_USB_BUS))) { + TRACE1("device already initialized: %p", wd); + usb_set_intfdata(intf, NULL); + ret = 0; + } else { + struct load_device load_device; + + load_device.bus = WRAP_USB_BUS; + load_device.vendor = le16_to_cpu(udev->descriptor.idVendor); + load_device.device = le16_to_cpu(udev->descriptor.idProduct); + load_device.subvendor = 0; + load_device.subdevice = 0; + wd = load_wrap_device(&load_device); + TRACE2("%p", wd); + if (wd) { + /* some devices (e.g., TI 4150, RNDIS) need + * full reset */ + ret = usb_reset_device(udev); + if (ret) + WARNING("reset failed: %d", ret); + usb_set_intfdata(intf, wd); + wd->usb.intf = intf; + wd->usb.udev = udev; + ret = wrap_pnp_start_device(wd); + } else + ret = -ENODEV; + } + + TRACE2("ret: %d", ret); + if (ret) + EXIT1(return ret); + else + return 0; +} + +void __devexit wrap_pnp_remove_usb_device(struct usb_interface *intf) +{ + struct wrap_device *wd; + + wd = (struct wrap_device *)usb_get_intfdata(intf); + TRACE1("%p, %p", intf, wd); + if (wd == NULL) + EXIT1(return); + usb_set_intfdata(intf, NULL); + wd->usb.intf = NULL; + pnp_remove_device(wd); +} + +int wrap_pnp_suspend_usb_device(struct usb_interface *intf, pm_message_t state) +{ + struct wrap_device *wd; + struct device_object *pdo; + + wd = usb_get_intfdata(intf); + ENTER1("%p, %p", intf, wd); + if (!wd) + EXIT1(return 0); + pdo = wd->pdo; + if (pnp_set_device_power_state(wd, PowerDeviceD3)) + return -1; + return 0; +} + +int wrap_pnp_resume_usb_device(struct usb_interface *intf) +{ + struct wrap_device *wd; + wd = usb_get_intfdata(intf); + ENTER1("%p, %p", intf, wd); + if (!wd) + EXIT1(return 0); + if (pnp_set_device_power_state(wd, PowerDeviceD0)) + return -1; + return 0; +} + +#endif // USB --- linux-2.6.28.orig/ubuntu/ndiswrapper/mkstubs.sh +++ linux-2.6.28/ubuntu/ndiswrapper/mkstubs.sh @@ -0,0 +1,12 @@ +#! /bin/sh + +for file in "$@"; do + echo + echo "# automatically generated from $file" + sed -n \ + -e 's/.*WIN_FUNC(\([^\,]\+\) *\, *\([0-9]\+\)).*/\ + win2lin(\1, \2)/p' \ + -e 's/.*WIN_FUNC_PTR(\([^\,]\+\) *\, *\([0-9]\+\)).*/\ + win2lin(\1, \2)/p' \ + $file | sed -e 's/[ \t ]\+//' | sort -u; \ +done --- linux-2.6.28.orig/ubuntu/ndiswrapper/rtl.c +++ linux-2.6.28/ubuntu/ndiswrapper/rtl.c @@ -0,0 +1,716 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#include "ntoskernel.h" +#include "rtl_exports.h" + +wstdcall SIZE_T WIN_FUNC(RtlCompareMemory,3) + (const void *a, const void *b, SIZE_T len) +{ + size_t i; + char *x, *y; + + x = (char *)a; + y = (char *)b; + /* MSDN says this should return number of bytes that compare as + * equal. This can be interpretted as either all bytes that are + * equal in 'len' bytes or that only until the bytes compare as + * not equal. Initially we had it the former way, but Realtek driver + * doesn't like it that way - it takes many attempts to associate + * with WPA. ReactOS returns the number of bytes that are equal + * upto when they compare as not equal. + * According to lords at #reactos, that is the way it should be + * and that msdn is wrong about it! + */ + for (i = 0; i < len && x[i] == y[i]; i++) + ; + return i; +} + +wstdcall void WIN_FUNC(RtlCopyMemory,3) + (void *dst, const void *src, SIZE_T length) +{ + memcpy(dst, src, length); +} + +wstdcall void WIN_FUNC(RtlZeroMemory,2) + (void *dst, SIZE_T length) +{ + memset(dst, 0, length); +} + +wstdcall void WIN_FUNC(RtlSecureZeroMemory,2) + (void *dst, SIZE_T length) +{ + memset(dst, 0, length); +} + +wstdcall void WIN_FUNC(RtlFillMemory,3) + (void *dest, SIZE_T length, UCHAR fill) +{ + memset(dest, fill, length); +} + +wstdcall void WIN_FUNC(RtlMoveMemory,3) + (void *dest, const void *src, SIZE_T length) +{ + memmove(dest, src, length); +} + +wstdcall LONG WIN_FUNC(RtlCompareString,3) + (const struct ansi_string *s1, const struct ansi_string *s2, + BOOLEAN case_insensitive) +{ + unsigned int len; + LONG ret = 0; + const char *p1, *p2; + + ENTER2(""); + len = min(s1->length, s2->length); + p1 = s1->buf; + p2 = s2->buf; + if (case_insensitive) + while (!ret && len--) + ret = toupper(*p1++) - toupper(*p2++); + else + while (!ret && len--) + ret = *p1++ - *p2++; + if (!ret) + ret = s1->length - s2->length; + EXIT2(return ret); +} + +wstdcall LONG WIN_FUNC(RtlCompareUnicodeString,3) + (const struct unicode_string *s1, const struct unicode_string *s2, + BOOLEAN case_insensitive) +{ + unsigned int len; + LONG ret = 0; + const wchar_t *p1, *p2; + + ENTER2(""); + + len = min(s1->length, s2->length) / sizeof(wchar_t); + p1 = s1->buf; + p2 = s2->buf; + if (case_insensitive) + while (!ret && len--) + ret = toupper((u8)*p1++) - toupper((u8)*p2++); + else + while (!ret && len--) + ret = (u8)*p1++ - (u8)*p2++; + if (!ret) + ret = s1->length - s2->length; + TRACE2("len: %d, ret: %d", len, ret); + EXIT2(return ret); +} + +wstdcall BOOLEAN WIN_FUNC(RtlEqualString,3) + (const struct ansi_string *s1, const struct ansi_string *s2, + BOOLEAN case_insensitive) +{ + ENTER1(""); + if (s1->length != s2->length) + return FALSE; + return !RtlCompareString(s1, s2, case_insensitive); +} + +wstdcall BOOLEAN WIN_FUNC(RtlEqualUnicodeString,3) + (const struct unicode_string *s1, const struct unicode_string *s2, + BOOLEAN case_insensitive) +{ + if (s1->length != s2->length) + return FALSE; + return !RtlCompareUnicodeString(s1, s2, case_insensitive); +} + +wstdcall void WIN_FUNC(RtlCopyUnicodeString,2) + (struct unicode_string *dst, struct unicode_string *src) +{ + ENTER1("%p, %p", dst, src); + if (src && src->buf && dst->buf) { + dst->length = min(src->length, dst->max_length); + memcpy(dst->buf, src->buf, dst->length); + if (dst->length < dst->max_length) + dst->buf[dst->length / sizeof(dst->buf[0])] = 0; + } else + dst->length = 0; + EXIT1(return); +} + +wstdcall void WIN_FUNC(RtlCopyString,2) + (struct ansi_string *dst, struct ansi_string *src) +{ + ENTER1("%p, %p", dst, src); + if (src && src->buf && dst->buf) { + dst->length = min(src->length, dst->max_length); + memcpy(dst->buf, src->buf, dst->length); + if (dst->length < dst->max_length) + dst->buf[dst->length] = 0; + } else + dst->length = 0; + EXIT1(return); +} + +wstdcall NTSTATUS WIN_FUNC(RtlAppendUnicodeToString,2) + (struct unicode_string *dst, wchar_t *src) +{ + if (src) { + int len; + for (len = 0; src[len]; len++) + ; + if (dst->length + (len * sizeof(dst->buf[0])) > dst->max_length) + return STATUS_BUFFER_TOO_SMALL; + memcpy(&dst->buf[dst->length], src, len * sizeof(dst->buf[0])); + dst->length += len * sizeof(dst->buf[0]); + if (dst->max_length > dst->length) + dst->buf[dst->length / sizeof(dst->buf[0])] = 0; + } + return STATUS_SUCCESS; +} + +wstdcall NTSTATUS WIN_FUNC(RtlAppendUnicodeStringToString,2) + (struct unicode_string *dst, struct unicode_string *src) +{ + if (dst->max_length < src->length + dst->length) + return STATUS_BUFFER_TOO_SMALL; + if (src->length) { + memcpy(&dst->buf[dst->length], src->buf, src->length); + dst->length += src->length; + if (dst->max_length > dst->length) + dst->buf[dst->length / sizeof(dst->buf[0])] = 0; + } + EXIT2(return STATUS_SUCCESS); +} + +wstdcall ULONG WIN_FUNC(RtlxAnsiStringToUnicodeSize,1) + (const struct ansi_string *string) +{ + int i; + + for (i = 0; i < string->max_length && string->buf[i]; i++) + ; + return (i * sizeof(wchar_t)); +} + +wstdcall ULONG WIN_FUNC(RtlxUnicodeStringToAnsiSize,1) + (const struct unicode_string *string) +{ + int i; + + for (i = 0; i < string->max_length && string->buf[i]; i++) + ; + return i; +} + +wstdcall NTSTATUS WIN_FUNC(RtlAnsiStringToUnicodeString,3) + (struct unicode_string *dst, const struct ansi_string *src, + BOOLEAN alloc) +{ + int i, n; + + n = RtlxAnsiStringToUnicodeSize(src); + TRACE2("%d, %d, %d, %d, %p", n, dst->max_length, src->length, + src->max_length, src->buf); + if (alloc == TRUE) { +#if 0 + if (n == 0) { + dst->length = dst->max_length = 0; + dst->buf = NULL; + EXIT2(return STATUS_SUCCESS); + } +#endif + dst->max_length = n + sizeof(dst->buf[0]); + dst->buf = ExAllocatePoolWithTag(NonPagedPool, + dst->max_length, 0); + if (!dst->buf) { + dst->max_length = dst->length = 0; + EXIT2(return STATUS_NO_MEMORY); + } + } else if (dst->max_length < n) + EXIT2(return STATUS_BUFFER_TOO_SMALL); + + dst->length = n; + n /= sizeof(dst->buf[0]); + for (i = 0; i < n; i++) + dst->buf[i] = src->buf[i]; + if (i * sizeof(dst->buf[0]) < dst->max_length) + dst->buf[i] = 0; + TRACE2("dst: length: %d, max_length: %d, string: %p", + dst->length, dst->max_length, src->buf); + EXIT2(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(RtlUnicodeStringToAnsiString,3) + (struct ansi_string *dst, const struct unicode_string *src, + BOOLEAN alloc) +{ + int i, n; + + n = RtlxUnicodeStringToAnsiSize(src); + TRACE2("%d, %d, %d, %d, %p", n, dst->max_length, src->length, + src->max_length, src->buf); + if (alloc == TRUE) { +#if 0 + if (n == 0) { + dst->length = dst->max_length = 0; + dst->buf = NULL; + EXIT2(return STATUS_SUCCESS); + } +#endif + dst->max_length = n + sizeof(dst->buf[0]); + dst->buf = ExAllocatePoolWithTag(NonPagedPool, + dst->max_length, 0); + if (!dst->buf) { + dst->max_length = dst->length = 0; + EXIT1(return STATUS_NO_MEMORY); + } + } else if (dst->max_length < n) + EXIT2(return STATUS_BUFFER_TOO_SMALL); + + dst->length = n; + for (i = 0; i < n; i++) + dst->buf[i] = src->buf[i]; + if (i < dst->max_length) + dst->buf[i] = 0; + TRACE2("string: %p, len: %d(%d)", dst->buf, dst->length, + dst->max_length); + EXIT2(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(RtlUnicodeStringToInteger,3) + (struct unicode_string *ustring, ULONG base, ULONG *value) +{ + int i, sign = 1; + ULONG res; + typeof(ustring->buf) string; + + if (ustring->length == 0) { + *value = 0; + return STATUS_SUCCESS; + } + + string = ustring->buf; + i = 0; + while (i < (ustring->length / sizeof(*string)) && string[i] == ' ') + i++; + if (string[i] == '+') + i++; + else if (string[i] == '-') { + i++; + sign = -1; + } + if (base == 0) { + base = 10; + if (i <= ((ustring->length / sizeof(*string)) - 2) && + string[i] == '0') { + i++; + if (string[i] == 'b') { + base = 2; + i++; + } else if (string[i] == 'o') { + base = 8; + i++; + } else if (string[i] == 'x') { + base = 16; + i++; + } + } + } + if (!(base == 2 || base == 8 || base == 10 || base == 16)) + EXIT2(return STATUS_INVALID_PARAMETER); + + for (res = 0; i < (ustring->length / sizeof(*string)); i++) { + int v; + if (isdigit((char)string[i])) + v = string[i] - '0'; + else if (isxdigit((char)string[i])) + v = tolower((char)string[i]) - 'a' + 10; + else + v = base; + if (v >= base) + EXIT2(return STATUS_INVALID_PARAMETER); + res = res * base + v; + } + *value = sign * res; + EXIT3(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(RtlCharToInteger,3) + (const char *string, ULONG base, ULONG *value) +{ + int sign = 1; + ULONG res; + + if (!string || !value) + EXIT2(return STATUS_INVALID_PARAMETER); + while (*string == ' ') + string++; + if (*string == '+') + string++; + else if (*string == '-') { + string++; + sign = -1; + } + if (base == 0) { + base = 10; + if (*string == '0') { + string++; + if (*string == 'b') { + base = 2; + string++; + } else if (*string == 'o') { + base = 8; + string++; + } else if (*string == 'x') { + base = 16; + string++; + } + } + } + if (!(base == 2 || base == 8 || base == 10 || base == 16)) + EXIT2(return STATUS_INVALID_PARAMETER); + + for (res = 0; *string; string++) { + int v; + if (isdigit(*string)) + v = *string - '0'; + else if (isxdigit(*string)) + v = tolower(*string) - 'a' + 10; + else + v = base; + if (v >= base) + EXIT2(return STATUS_INVALID_PARAMETER); + res = res * base + v; + } + *value = sign * res; + EXIT3(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(RtlIntegerToUnicodeString,3) + (ULONG value, ULONG base, struct unicode_string *ustring) +{ + typeof(ustring->buf) buf = ustring->buf; + int i; + + if (base == 0) + base = 10; + if (!(base == 2 || base == 8 || base == 10 || base == 16)) + return STATUS_INVALID_PARAMETER; + for (i = 0; value && i < ustring->max_length / sizeof(*buf); i++) { + int r; + r = value % base; + value /= base; + if (r < 10) + buf[i] = r + '0'; + else + buf[i] = r + 'a' - 10; + } + if (value) + return STATUS_BUFFER_OVERFLOW; + ustring->length = i * sizeof(*buf); + return STATUS_SUCCESS; +} + +wstdcall LARGE_INTEGER WIN_FUNC(RtlConvertUlongToLargeInteger,1) + (ULONG ul) +{ + LARGE_INTEGER li = ul; + return li; +} + +wfastcall USHORT WIN_FUNC(RtlUshortByteSwap,1) + (USHORT src) +{ + return __swab16(src); +} + +wfastcall ULONG WIN_FUNC(RtlUlongByteSwap,1) + (ULONG src) +{ + /* ULONG is 32 bits for both 32-bit and 64-bit architectures */ + return __swab32(src); +} + +wstdcall NTSTATUS WIN_FUNC(RtlUpcaseUnicodeString,3) + (struct unicode_string *dst, struct unicode_string *src, BOOLEAN alloc) +{ + USHORT i, n; + + if (alloc) { + dst->buf = ExAllocatePoolWithTag(NonPagedPool, src->length, 0); + if (dst->buf) { + dst->max_length = src->length; + } else + EXIT2(return STATUS_NO_MEMORY); + } else { + if (dst->max_length < src->length) + EXIT2(return STATUS_BUFFER_OVERFLOW); + } + + n = src->length / sizeof(src->buf[0]); + for (i = 0; i < n; i++) + dst->buf[i] = toupper(src->buf[i]); + + dst->length = src->length; + EXIT3(return STATUS_SUCCESS); +} + +wstdcall void WIN_FUNC(RtlInitUnicodeString,2) + (struct unicode_string *dst, const wchar_t *src) +{ + ENTER2("%p", dst); + if (dst == NULL) + EXIT1(return); + if (src == NULL) { + dst->max_length = dst->length = 0; + dst->buf = NULL; + } else { + int i; + for (i = 0; (char)src[i]; i++) + ; + dst->buf = (typeof(dst->buf))src; + dst->length = i * sizeof(dst->buf[0]); + dst->max_length = (i + 1) * sizeof(dst->buf[0]); + } + EXIT1(return); +} + +wstdcall void WIN_FUNC(RtlInitAnsiString,2) + (struct ansi_string *dst, const char *src) +{ + ENTER2("%p", dst); + if (dst == NULL) + EXIT2(return); + if (src == NULL) { + dst->max_length = dst->length = 0; + dst->buf = NULL; + } else { + int i; + for (i = 0; src[i]; i++) + ; + dst->buf = (typeof(dst->buf))src; + dst->length = i; + dst->max_length = i + 1; + } + TRACE2("%p", dst->buf); + EXIT2(return); +} + +wstdcall void WIN_FUNC(RtlInitString,2) + (struct ansi_string *dst, const char *src) +{ + ENTER2("%p", dst); + RtlInitAnsiString(dst, src); + EXIT2(return); +} + +wstdcall void WIN_FUNC(RtlFreeUnicodeString,1) + (struct unicode_string *string) +{ + ENTER2("%p", string); + if (string == NULL) + return; + if (string->buf) + ExFreePool(string->buf); + string->length = string->max_length = 0; + string->buf = NULL; + return; +} + +wstdcall void WIN_FUNC(RtlFreeAnsiString,1) + (struct ansi_string *string) +{ + ENTER2("%p", string); + if (string == NULL) + return; + if (string->buf) + ExFreePool(string->buf); + string->length = string->max_length = 0; + string->buf = NULL; + return; +} + +/* guid string is of the form: {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */ +wstdcall NTSTATUS WIN_FUNC(RtlGUIDFromString,2) + (struct unicode_string *guid_string, struct guid *guid) +{ + struct ansi_string ansi; + NTSTATUS ret; + int i, j, k, l, m; + + ret = RtlUnicodeStringToAnsiString(&ansi, guid_string, TRUE); + if (ret != STATUS_SUCCESS) + return ret; + if (ansi.length != 37 || ansi.buf[0] != '{' || + ansi.buf[36] != '}' || ansi.buf[9] != '-' || + ansi.buf[14] != '-' || ansi.buf[19] != '-' || + ansi.buf[24] != '-') { + RtlFreeAnsiString(&ansi); + EXIT2(return STATUS_INVALID_PARAMETER); + } + memcpy(&guid->data4, &ansi.buf[29], sizeof(guid->data3)); + /* set end of data3 for scanf */ + ansi.buf[29] = 0; + if (sscanf(&ansi.buf[1], "%x", &i) == 1 && + sscanf(&ansi.buf[10], "%x", &j) == 1 && + sscanf(&ansi.buf[15], "%x", &k) == 1 && + sscanf(&ansi.buf[20], "%x", &l) == 1 && + sscanf(&ansi.buf[25], "%x", &m) == 1) { + guid->data1 = (i << 16) | (j < 8) | k; + guid->data2 = l; + guid->data3 = m; + ret = STATUS_SUCCESS; + } else + ret = STATUS_INVALID_PARAMETER; + RtlFreeAnsiString(&ansi); + return ret; +} + +wstdcall NTSTATUS WIN_FUNC(RtlQueryRegistryValues,5) + (ULONG relative, wchar_t *path, struct rtl_query_registry_table *tbl, + void *context, void *env) +{ + struct ansi_string ansi; + struct unicode_string unicode; + NTSTATUS status, ret; + static int i = 0; + + ENTER3("%x, %p", relative, tbl); +// TODO(); + + RtlInitUnicodeString(&unicode, path); + if (RtlUnicodeStringToAnsiString(&ansi, &unicode, TRUE) == + STATUS_SUCCESS) { + TRACE2("%s", ansi.buf); + RtlFreeAnsiString(&ansi); + } + ret = STATUS_SUCCESS; + for (; tbl->name; tbl++) { + RtlInitUnicodeString(&unicode, tbl->name); + if (RtlUnicodeStringToAnsiString(&ansi, &unicode, TRUE) == + STATUS_SUCCESS) { + TRACE2("name: %s", ansi.buf); + RtlFreeAnsiString(&ansi); + } + TRACE2("flags: %08X", tbl->flags); + if (tbl->flags == RTL_QUERY_REGISTRY_DIRECT) { + TRACE2("type: %08X", tbl->def_type); + if (tbl->def_type == REG_DWORD) { + /* Atheros USB driver needs this, but + * don't know where and how to get its + * value */ + if (tbl->def_data) { + TRACE2("def_data: %x", + *(int *)tbl->def_data); + *(DWORD *)tbl->context = 0x5f292a + i++; +// *(DWORD *)tbl->def_data; + } else + *(DWORD *)tbl->context = 0x2345dbe; + } + } else { + void *data; + ULONG type, length; + + if (!tbl->query_func) { + ERROR("oops: no query_func"); + ret = STATUS_INVALID_PARAMETER; + break; + } + if (tbl->flags & RTL_QUERY_REGISTRY_NOVALUE) { + data = NULL; + type = REG_NONE; + length = 0; + } else { + data = tbl->def_data; + type = tbl->def_type; + length = tbl->def_length;; + } + TRACE2("calling query_func: %p", tbl->query_func); + status = LIN2WIN6(tbl->query_func, tbl->name, type, + data, length, context, env); + TRACE2("status: %08X", status); + if (status) { + if (status == STATUS_BUFFER_TOO_SMALL) + ret = STATUS_BUFFER_TOO_SMALL; + else + EXIT2(return STATUS_INVALID_PARAMETER); + } + } + } + EXIT3(return ret); +} + +wstdcall NTSTATUS WIN_FUNC(RtlWriteRegistryValue,6) + (ULONG relative, wchar_t *path, wchar_t *name, ULONG type, + void *data, ULONG length) +{ + struct ansi_string ansi; + struct unicode_string unicode; + + ENTER3("%d", relative); + TODO(); + + RtlInitUnicodeString(&unicode, path); + if (RtlUnicodeStringToAnsiString(&ansi, &unicode, TRUE) == + STATUS_SUCCESS) { + TRACE2("%s", ansi.buf); + RtlFreeAnsiString(&ansi); + } + RtlInitUnicodeString(&unicode, name); + if (RtlUnicodeStringToAnsiString(&ansi, &unicode, TRUE) == + STATUS_SUCCESS) { + TRACE2("%s", ansi.buf); + RtlFreeAnsiString(&ansi); + } + EXIT5(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(RtlDeleteRegistryValue,3) + (ULONG relative, wchar_t *path, wchar_t *name) +{ + return STATUS_SUCCESS; +} + +wstdcall void WIN_FUNC(RtlAssert,4) + (char *failed_assertion, char *file_name, ULONG line_num, char *message) +{ + ERROR("assertion '%s' failed at %s line %d%s", + failed_assertion, file_name, line_num, message ? message : ""); + return; +} + +wstdcall void WIN_FUNC(RtlUnwind,0) + (void) +{ + TODO(); +} + +wstdcall void WIN_FUNC(RtlRaiseException,1) + (void *exception_record) +{ + TODO(); +} + +int rtl_init(void) +{ + return 0; +} + +/* called when module is being removed */ +void rtl_exit(void) +{ + EXIT4(return); +} --- linux-2.6.28.orig/ubuntu/ndiswrapper/pe_linker.c +++ linux-2.6.28/ubuntu/ndiswrapper/pe_linker.c @@ -0,0 +1,609 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#ifdef TEST_LOADER + +#include "usr_linker.h" + +#else + +#include +#include + +//#define DEBUGLINKER 2 + +#include "ntoskernel.h" + +#endif + +struct pe_exports { + char *dll; + char *name; + generic_func addr; +}; + +static struct pe_exports pe_exports[40]; +static int num_pe_exports; + +#define RVA2VA(image, rva, type) (type)(ULONG_PTR)((void *)image + rva) +#define CHECK_SZ(a,b) { if (sizeof(a) != b) { \ + ERROR("%s is bad, got %zd, expected %d", \ + #a , sizeof(a), (b)); return -EINVAL; } } + +#if defined(DEBUGLINKER) && DEBUGLINKER > 0 +#define DBGLINKER(fmt, ...) printk(KERN_INFO "%s (%s:%d): " fmt "\n", \ + DRIVER_NAME, __FUNCTION__, \ + __LINE__ , ## __VA_ARGS__); +static const char *image_directory_name[] = { + "EXPORT", + "IMPORT", + "RESOURCE", + "EXCEPTION", + "SECURITY", + "BASERELOC", + "DEBUG", + "COPYRIGHT", + "GLOBALPTR", + "TLS", + "LOAD_CONFIG", + "BOUND_IMPORT", + "IAT", + "DELAY_IMPORT", + "COM_DESCRIPTOR" }; +#else +#define DBGLINKER(fmt, ...) do { } while (0) +#endif + +#ifndef TEST_LOADER +extern struct wrap_export ntoskernel_exports[], ntoskernel_io_exports[], + ndis_exports[], crt_exports[], hal_exports[], rtl_exports[]; +#ifdef ENABLE_USB +extern struct wrap_export usb_exports[]; +#endif + +static char *get_export(char *name) +{ + int i; + + for (i = 0 ; ntoskernel_exports[i].name != NULL; i++) + if (strcmp(ntoskernel_exports[i].name, name) == 0) + return (char *)ntoskernel_exports[i].func; + + for (i = 0 ; ntoskernel_io_exports[i].name != NULL; i++) + if (strcmp(ntoskernel_io_exports[i].name, name) == 0) + return (char *)ntoskernel_io_exports[i].func; + + for (i = 0 ; ndis_exports[i].name != NULL; i++) + if (strcmp(ndis_exports[i].name, name) == 0) + return (char *)ndis_exports[i].func; + + for (i = 0 ; crt_exports[i].name != NULL; i++) + if (strcmp(crt_exports[i].name, name) == 0) + return (char *)crt_exports[i].func; + + for (i = 0 ; hal_exports[i].name != NULL; i++) + if (strcmp(hal_exports[i].name, name) == 0) + return (char *)hal_exports[i].func; + + for (i = 0 ; rtl_exports[i].name != NULL; i++) + if (strcmp(rtl_exports[i].name, name) == 0) + return (char *)rtl_exports[i].func; + +#ifdef ENABLE_USB + for (i = 0 ; usb_exports[i].name != NULL; i++) + if (strcmp(usb_exports[i].name, name) == 0) + return (char *)usb_exports[i].func; +#endif + + for (i = 0; i < num_pe_exports; i++) + if (strcmp(pe_exports[i].name, name) == 0) + return (char *)pe_exports[i].addr; + + return NULL; +} +#endif // TEST_LOADER + +static void *get_dll_init(char *name) +{ + int i; + for (i = 0; i < num_pe_exports; i++) + if ((strcmp(pe_exports[i].dll, name) == 0) && + (strcmp(pe_exports[i].name, "DllInitialize") == 0)) + return (void *)pe_exports[i].addr; + return NULL; +} + +/* + * Find and validate the coff header + * + */ +static int check_nt_hdr(IMAGE_NT_HEADERS *nt_hdr) +{ + int i; + WORD attr; + PIMAGE_OPTIONAL_HEADER opt_hdr; + + /* Validate the "PE\0\0" signature */ + if (nt_hdr->Signature != IMAGE_NT_SIGNATURE) { + ERROR("is this driver file? bad signature %08x", + nt_hdr->Signature); + return -EINVAL; + } + + opt_hdr = &nt_hdr->OptionalHeader; + /* Make sure Image is PE32 or PE32+ */ +#ifdef CONFIG_X86_64 + if (opt_hdr->Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) { + ERROR("kernel is 64-bit, but Windows driver is not 64-bit;" + "bad magic: %04X", opt_hdr->Magic); + return -EINVAL; + } +#else + if (opt_hdr->Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + ERROR("kernel is 32-bit, but Windows driver is not 32-bit;" + "bad magic: %04X", opt_hdr->Magic); + return -EINVAL; + } +#endif + + /* Validate the image for the current architecture. */ +#ifdef CONFIG_X86_64 + if (nt_hdr->FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64) { + ERROR("kernel is 64-bit, but Windows driver is not 64-bit;" + " (PE signature is %04X)", nt_hdr->FileHeader.Machine); + return -EINVAL; + } +#else + if (nt_hdr->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) { + ERROR("kernel is 32-bit, but Windows driver is not 32-bit;" + " (PE signature is %04X)", nt_hdr->FileHeader.Machine); + return -EINVAL; + } +#endif + + /* Must have attributes */ +#ifdef CONFIG_X86_64 + attr = IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_LARGE_ADDRESS_AWARE; +#else + attr = IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_32BIT_MACHINE; +#endif + if ((nt_hdr->FileHeader.Characteristics & attr) != attr) + return -EINVAL; + + /* Must be relocatable */ + attr = IMAGE_FILE_RELOCS_STRIPPED; + if ((nt_hdr->FileHeader.Characteristics & attr)) + return -EINVAL; + + /* Make sure we have at least one section */ + if (nt_hdr->FileHeader.NumberOfSections == 0) + return -EINVAL; + + if (opt_hdr->SectionAlignment < opt_hdr->FileAlignment) { + ERROR("alignment mismatch: secion: 0x%x, file: 0x%x", + opt_hdr->SectionAlignment, opt_hdr->FileAlignment); + return -EINVAL; + } + + DBGLINKER("number of datadictionary entries %d", + opt_hdr->NumberOfRvaAndSizes); + for (i = 0; i < opt_hdr->NumberOfRvaAndSizes; i++) { + DBGLINKER("datadirectory %s RVA:%X Size:%d", + (i<=IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR)? + image_directory_name[i] : "unknown", + opt_hdr->DataDirectory[i].VirtualAddress, + opt_hdr->DataDirectory[i].Size); + } + + if ((nt_hdr->FileHeader.Characteristics & IMAGE_FILE_DLL)) + return IMAGE_FILE_DLL; + if ((nt_hdr->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) + return IMAGE_FILE_EXECUTABLE_IMAGE; + return -EINVAL; +} + +static int import(void *image, IMAGE_IMPORT_DESCRIPTOR *dirent, char *dll) +{ + ULONG_PTR *lookup_tbl, *address_tbl; + char *symname = NULL; + int i; + int ret = 0; + void *adr; + + lookup_tbl = RVA2VA(image, dirent->u.OriginalFirstThunk, ULONG_PTR *); + address_tbl = RVA2VA(image, dirent->FirstThunk, ULONG_PTR *); + + for (i = 0; lookup_tbl[i]; i++) { + if (IMAGE_SNAP_BY_ORDINAL(lookup_tbl[i])) { + ERROR("ordinal import not supported: %Lu", + (uint64_t)lookup_tbl[i]); + return -1; + } + else { + symname = RVA2VA(image, + ((lookup_tbl[i] & + ~IMAGE_ORDINAL_FLAG) + 2), char *); + } + + adr = get_export(symname); + if (adr == NULL) { + ERROR("unknown symbol: %s:'%s'", dll, symname); + ret = -1; + } else { + DBGLINKER("found symbol: %s:%s: addr: %p, rva = %Lu", + dll, symname, adr, (uint64_t)address_tbl[i]); + address_tbl[i] = (ULONG_PTR)adr; + } + } + return ret; +} + +static int read_exports(struct pe_image *pe) +{ + IMAGE_EXPORT_DIRECTORY *export_dir_table; + uint32_t *export_addr_table; + int i; + uint32_t *name_table; + PIMAGE_OPTIONAL_HEADER opt_hdr; + IMAGE_DATA_DIRECTORY *export_data_dir; + + opt_hdr = &pe->nt_hdr->OptionalHeader; + export_data_dir = + &opt_hdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; + + if (export_data_dir->Size == 0) { + DBGLINKER("no exports"); + return 0; + } + + export_dir_table = + RVA2VA(pe->image, export_data_dir->VirtualAddress, + IMAGE_EXPORT_DIRECTORY *); + + name_table = (unsigned int *)(pe->image + + export_dir_table->AddressOfNames); + export_addr_table = (uint32_t *) + (pe->image + export_dir_table->AddressOfFunctions); + + for (i = 0; i < export_dir_table->NumberOfNames; i++) { + + if (export_data_dir->VirtualAddress <= *export_addr_table || + *export_addr_table >= (export_data_dir->VirtualAddress + + export_data_dir->Size)) + DBGLINKER("forwarder rva"); + + DBGLINKER("export symbol: %s, at %p", + (char *)(pe->image + *name_table), + pe->image + *export_addr_table); + + pe_exports[num_pe_exports].dll = pe->name; + pe_exports[num_pe_exports].name = pe->image + *name_table; + pe_exports[num_pe_exports].addr = + pe->image + *export_addr_table; + + num_pe_exports++; + name_table++; + export_addr_table++; + } + return 0; +} + +static int fixup_imports(void *image, IMAGE_NT_HEADERS *nt_hdr) +{ + int i; + char *name; + int ret = 0; + IMAGE_IMPORT_DESCRIPTOR *dirent; + IMAGE_DATA_DIRECTORY *import_data_dir; + PIMAGE_OPTIONAL_HEADER opt_hdr; + + opt_hdr = &nt_hdr->OptionalHeader; + import_data_dir = + &opt_hdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; + dirent = RVA2VA(image, import_data_dir->VirtualAddress, + IMAGE_IMPORT_DESCRIPTOR *); + + for (i = 0; dirent[i].Name; i++) { + name = RVA2VA(image, dirent[i].Name, char*); + + DBGLINKER("imports from dll: %s", name); + ret += import(image, &dirent[i], name); + } + return ret; +} + +static int fixup_reloc(void *image, IMAGE_NT_HEADERS *nt_hdr) +{ + ULONG_PTR base; + ULONG_PTR size; + IMAGE_BASE_RELOCATION *fixup_block; + IMAGE_DATA_DIRECTORY *base_reloc_data_dir; + PIMAGE_OPTIONAL_HEADER opt_hdr; + + opt_hdr = &nt_hdr->OptionalHeader; + base = opt_hdr->ImageBase; + base_reloc_data_dir = + &opt_hdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; + if (base_reloc_data_dir->Size == 0) + return 0; + + fixup_block = RVA2VA(image, base_reloc_data_dir->VirtualAddress, + IMAGE_BASE_RELOCATION *); + DBGLINKER("fixup_block=%p, image=%p", fixup_block, image); + DBGLINKER("fixup_block info: %x %d", + fixup_block->VirtualAddress, fixup_block->SizeOfBlock); + + while (fixup_block->SizeOfBlock) { + int i; + WORD fixup, offset; + + size = (fixup_block->SizeOfBlock - + sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD); + DBGLINKER("found %Lu relocations in this block", + (uint64_t)size); + + for (i = 0; i < size; i++) { + fixup = fixup_block->TypeOffset[i]; + offset = fixup & 0xfff; + switch ((fixup >> 12) & 0x0f) { + case IMAGE_REL_BASED_ABSOLUTE: + break; + + case IMAGE_REL_BASED_HIGHLOW: { + uint32_t addr; + uint32_t *loc = + RVA2VA(image, + fixup_block->VirtualAddress + + offset, uint32_t *); + addr = RVA2VA(image, (*loc - base), uint32_t); + DBGLINKER("relocation: *%p (Val:%X)= %X", + loc, *loc, addr); + *loc = addr; + } + break; + + case IMAGE_REL_BASED_DIR64: { + uint64_t addr; + uint64_t *loc = + RVA2VA(image, + fixup_block->VirtualAddress + + offset, uint64_t *); + addr = RVA2VA(image, (*loc - base), uint64_t); + DBGLINKER("relocation: *%p (Val:%llX)= %llx", + loc, *loc, addr); + *loc = addr; + } + break; + + default: + ERROR("unknown fixup: %08X", + (fixup >> 12) & 0x0f); + return -EOPNOTSUPP; + break; + } + } + DBGLINKER("finished relocating block"); + + fixup_block = (IMAGE_BASE_RELOCATION *) + ((void *)fixup_block + fixup_block->SizeOfBlock); + }; + DBGLINKER("done relocating all"); + + return 0; +} + +/* Expand the image in memroy if necessary. The image on disk does not + * necessarily maps the image of the driver in memory, so we have to + * re-write it in order to fullfill the sections alignements. The + * advantage to do that is that rva_to_va becomes a simple + * addition. */ +static int fix_pe_image(struct pe_image *pe) +{ + void *image; + IMAGE_SECTION_HEADER *sect_hdr; + int i, sections; + int image_size; + + if (pe->size == pe->opt_hdr->SizeOfImage) { + /* Nothing to do */ + return 0; + } + + image_size = pe->opt_hdr->SizeOfImage; +#ifdef CONFIG_X86_64 +#ifdef PAGE_KERNEL_EXECUTABLE + image = __vmalloc(image_size, GFP_KERNEL | __GFP_HIGHMEM, + PAGE_KERNEL_EXECUTABLE); +#elif defined PAGE_KERNEL_EXEC + image = __vmalloc(image_size, GFP_KERNEL | __GFP_HIGHMEM, + PAGE_KERNEL_EXEC); +#else +#error x86_64 should have either PAGE_KERNEL_EXECUTABLE or PAGE_KERNEL_EXEC +#endif +#else +#ifdef cpu_has_nx + /* hate to play with kernel macros, but PAGE_KERNEL_EXEC is + * not available to modules! */ + if (cpu_has_nx) + image = __vmalloc(image_size, GFP_KERNEL | __GFP_HIGHMEM, + __pgprot(__PAGE_KERNEL & ~_PAGE_NX)); + else + image = vmalloc(image_size); +#else + image = vmalloc(image_size); +#endif +#endif + if (image == NULL) { + ERROR("failed to allocate enough space for new image:" + " %d bytes", image_size); + return -ENOMEM; + } + + /* Copy all the headers, ie everything before the first section. */ + + sections = pe->nt_hdr->FileHeader.NumberOfSections; + sect_hdr = IMAGE_FIRST_SECTION(pe->nt_hdr); + + DBGLINKER("copying headers: %u bytes", sect_hdr->PointerToRawData); + + memcpy(image, pe->image, sect_hdr->PointerToRawData); + + /* Copy all the sections */ + for (i = 0; i < sections; i++) { + DBGLINKER("Copy section %s from %x to %x", + sect_hdr->Name, sect_hdr->PointerToRawData, + sect_hdr->VirtualAddress); + if (sect_hdr->VirtualAddress+sect_hdr->SizeOfRawData > + image_size) { + ERROR("Invalid section %s in driver", sect_hdr->Name); + vfree(image); + return -EINVAL; + } + + memcpy(image+sect_hdr->VirtualAddress, + pe->image + sect_hdr->PointerToRawData, + sect_hdr->SizeOfRawData); + sect_hdr++; + } + + vfree(pe->image); + pe->image = image; + pe->size = image_size; + + /* Update our internal pointers */ + pe->nt_hdr = (IMAGE_NT_HEADERS *) + (pe->image + ((IMAGE_DOS_HEADER *)pe->image)->e_lfanew); + pe->opt_hdr = &pe->nt_hdr->OptionalHeader; + + DBGLINKER("set nt headers: nt_hdr=%p, opt_hdr=%p, image=%p", + pe->nt_hdr, pe->opt_hdr, pe->image); + + return 0; +} + +#if defined(CONFIG_X86_64) +static void fix_user_shared_data_addr(char *driver, unsigned long length) +{ + unsigned long i, n, max_addr, *addr; + + n = length - sizeof(unsigned long); + max_addr = KI_USER_SHARED_DATA + sizeof(kuser_shared_data); + for (i = 0; i < n; i++) { + addr = (unsigned long *)(driver + i); + if (*addr >= KI_USER_SHARED_DATA && *addr < max_addr) { + *addr -= KI_USER_SHARED_DATA; + *addr += (unsigned long)&kuser_shared_data; + kuser_shared_data.reserved1 = 1; + } + } +} +#endif + +int link_pe_images(struct pe_image *pe_image, unsigned short n) +{ + int i; + struct pe_image *pe; + +#ifdef DEBUG + /* Sanity checkings */ + CHECK_SZ(IMAGE_SECTION_HEADER, IMAGE_SIZEOF_SECTION_HEADER); + CHECK_SZ(IMAGE_FILE_HEADER, IMAGE_SIZEOF_FILE_HEADER); + CHECK_SZ(IMAGE_OPTIONAL_HEADER, IMAGE_SIZEOF_NT_OPTIONAL_HEADER); + CHECK_SZ(IMAGE_NT_HEADERS, 4 + IMAGE_SIZEOF_FILE_HEADER + + IMAGE_SIZEOF_NT_OPTIONAL_HEADER); + CHECK_SZ(IMAGE_DOS_HEADER, 0x40); + CHECK_SZ(IMAGE_EXPORT_DIRECTORY, 40); + CHECK_SZ(IMAGE_BASE_RELOCATION, 8); + CHECK_SZ(IMAGE_IMPORT_DESCRIPTOR, 20); +#endif + + for (i = 0; i < n; i++) { + IMAGE_DOS_HEADER *dos_hdr; + pe = &pe_image[i]; + dos_hdr = pe->image; + + if (pe->size < sizeof(IMAGE_DOS_HEADER)) { + TRACE1("image too small: %d", pe->size); + return -EINVAL; + } + + pe->nt_hdr = + (IMAGE_NT_HEADERS *)(pe->image + dos_hdr->e_lfanew); + pe->opt_hdr = &pe->nt_hdr->OptionalHeader; + + pe->type = check_nt_hdr(pe->nt_hdr); + if (pe->type <= 0) { + TRACE1("type <= 0"); + return -EINVAL; + } + + if (fix_pe_image(pe)) { + TRACE1("bad PE image"); + return -EINVAL; + } + + if (read_exports(pe)) { + TRACE1("read exports failed"); + return -EINVAL; + } + } + + for (i = 0; i < n; i++) { + pe = &pe_image[i]; + + if (fixup_reloc(pe->image, pe->nt_hdr)) { + TRACE1("fixup reloc failed"); + return -EINVAL; + } + if (fixup_imports(pe->image, pe->nt_hdr)) { + TRACE1("fixup imports failed"); + return -EINVAL; + } +#if defined(CONFIG_X86_64) + INFO("fixing KI_USER_SHARED_DATA address in the driver"); + fix_user_shared_data_addr(pe_image[i].image, pe_image[i].size); +#endif + flush_icache_range(pe->image, pe->size); + + pe->entry = + RVA2VA(pe->image, + pe->opt_hdr->AddressOfEntryPoint, void *); + TRACE1("entry is at %p, rva at %08X", pe->entry, + pe->opt_hdr->AddressOfEntryPoint); + } + + for (i = 0; i < n; i++) { + pe = &pe_image[i]; + + if (pe->type == IMAGE_FILE_DLL) { + struct unicode_string ustring; + char *buf = "0/0t0m0p00"; + int (*dll_entry)(struct unicode_string *ustring) + wstdcall; + + memset(&ustring, 0, sizeof(ustring)); + ustring.buf = (wchar_t *)buf; + dll_entry = (void *)get_dll_init(pe->name); + + TRACE1("calling dll_init at %p", dll_entry); + if (!dll_entry || dll_entry(&ustring)) + ERROR("DLL initialize failed for %s", + pe->name); + } + else if (pe->type != IMAGE_FILE_EXECUTABLE_IMAGE) + ERROR("illegal image type: %d", pe->type); + } + return 0; +} --- linux-2.6.28.orig/ubuntu/ndiswrapper/crt.c +++ linux-2.6.28/ubuntu/ndiswrapper/crt.c @@ -0,0 +1,578 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#include "ntoskernel.h" +#include "crt_exports.h" + +#ifdef CONFIG_X86_64 +/* Windows long is 32-bit, so strip single 'l' in integer formats */ +static void strip_l_modifier(char *str) +{ + char *ptr = str; + int in_format = 0; + char *lptr = NULL; + char last = 0; + char *end_ptr; + char *wptr; + + /* Replace single 'l' inside integer formats with '\0' */ + for (ptr = str; *ptr; ptr++) { + if (!in_format) { + if (*ptr == '%') + in_format = 1; + last = *ptr; + continue; + } + switch (*ptr) { + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': + case 'p': + case 'n': + case 'm': + if (lptr) { + *lptr = '\0'; + lptr = NULL; + } + in_format = 0; + break; + case 'c': + case 'C': + case 's': + case 'S': + case 'f': + case 'e': + case 'E': + case 'g': + case 'G': + case 'a': + case 'A': + lptr = NULL; + in_format = 0; + break; + case '%': + lptr = NULL; + if (last == '%') + in_format = 0; + else + in_format = 1; /* ignore previous junk */ + break; + case 'l': + if (last == 'l') + lptr = NULL; + else + lptr = ptr; + break; + default: + break; + } + last = *ptr; + } + + /* Purge zeroes from the resulting string */ + end_ptr = ptr; + wptr = str; + for (ptr = str; ptr < end_ptr; ptr++) + if (*ptr != 0) + *(wptr++) = *ptr; + *wptr = 0; +} + +/* + * va_list on x86_64 Linux is designed to allow passing arguments in registers + * even to variadic functions. va_list is a structure holding pointers to the + * register save area, which holds the arguments passed in registers, and to + * the stack, which may have the arguments that did not fit the registers. + * va_list also holds offsets in the register save area for the next general + * purpose and floating point registers that the next va_arg() would fetch. + * + * Unlike Linux, the Windows va_list is just a pointer to the stack. No + * arguments are passed in the registers. That's why we construct the Linux + * va_list so that the register save area is never used. For that goal, we set + * the offsets to the maximal allowed values, meaning that the arguments passed + * in the registers have been exhausted. The values are 48 for general purpose + * registers (6 registers, 8 bytes each) and 304 for floating point registers + * (16 registers, 16 bytes each, on top of general purpose register). + */ + +struct x86_64_va_list { + int gp_offset; + int fp_offset; + void *overflow_arg_area; + void *reg_save_area; +}; + +#define VA_LIST_DECL(_args) \ + va_list _args##new; \ + struct x86_64_va_list *_args##x; +#define VA_LIST_PREP(_args) \ +do { \ + _args##x = (struct x86_64_va_list *)&_args##new; \ + _args##x->gp_offset = 6 * 8; /* GP registers exhausted */ \ + _args##x->fp_offset = 6 * 8 + 16 * 16; /* FP registers exhausted */ \ + _args##x->overflow_arg_area = (void *)_args; \ + _args##x->reg_save_area = NULL; \ +} while (0) +#define VA_LIST_CONV(_args) (_args##new) +#define VA_LIST_FREE(_args) +#define FMT_DECL(_fmt) \ + char *_fmt##copy; \ + int _fmt##len; +#define FMT_PREP(_fmt) \ +do { \ + _fmt##len = strlen(format) + 1; \ + _fmt##copy = kmalloc(_fmt##len, GFP_KERNEL); \ + if (_fmt##copy) { \ + memcpy(_fmt##copy, format, _fmt##len); \ + strip_l_modifier(_fmt##copy); \ + } \ +} while (0) +#define FMT_CONV(_fmt) (_fmt##copy ? _fmt##copy : format) +#define FMT_FREE(_fmt) kfree(_fmt##copy) + +#else /* !CONFIG_X86_64 */ + +#define VA_LIST_DECL(_args) +#define VA_LIST_PREP(_args) +#define VA_LIST_CONV(_args) (_args) +#define VA_LIST_FREE(_args) +#define FMT_DECL(_fmt) +#define FMT_PREP(_fmt) +#define FMT_CONV(_fmt) (format) +#define FMT_FREE(_fmt) + +#endif /* !CONFIG_X86_64 */ + +noregparm INT WIN_FUNC(_win_sprintf,12) + (char *buf, const char *format, ...) +{ + va_list args; + int res; + FMT_DECL(format) + + FMT_PREP(format); + va_start(args, format); + res = vsprintf(buf, FMT_CONV(format), args); + va_end(args); + FMT_FREE(format); + + TRACE2("buf: %p: %s", buf, buf); + return res; +} + +noregparm INT WIN_FUNC(swprintf,12) + (wchar_t *buf, const wchar_t *format, ...) +{ + TODO(); + EXIT2(return 0); +} + +noregparm INT WIN_FUNC(_win_vsprintf,3) + (char *str, const char *format, va_list ap) +{ + INT i; + VA_LIST_DECL(ap) + FMT_DECL(format) + + VA_LIST_PREP(ap); + FMT_PREP(format); + + i = vsprintf(str, FMT_CONV(format), VA_LIST_CONV(ap)); + TRACE2("str: %p: %s", str, str); + + FMT_FREE(format); + VA_LIST_FREE(ap); + EXIT2(return i); +} + +noregparm INT WIN_FUNC(_win_snprintf,12) + (char *buf, SIZE_T count, const char *format, ...) +{ + va_list args; + int res; + FMT_DECL(format) + + FMT_PREP(format); + va_start(args, format); + res = vsnprintf(buf, count, FMT_CONV(format), args); + va_end(args); + TRACE2("buf: %p: %s", buf, buf); + + FMT_FREE(format); + return res; +} + +noregparm INT WIN_FUNC(_win__snprintf,12) + (char *buf, SIZE_T count, const char *format, ...) +{ + va_list args; + int res; + FMT_DECL(format) + + FMT_PREP(format); + va_start(args, format); + res = vsnprintf(buf, count, FMT_CONV(format), args); + va_end(args); + TRACE2("buf: %p: %s", buf, buf); + + FMT_FREE(format); + return res; +} + +noregparm INT WIN_FUNC(_win_vsnprintf,4) + (char *str, SIZE_T size, const char *format, va_list ap) +{ + INT i; + VA_LIST_DECL(ap) + FMT_DECL(format) + + VA_LIST_PREP(ap); + FMT_PREP(format); + + i = vsnprintf(str, size, FMT_CONV(format), VA_LIST_CONV(ap)); + TRACE2("str: %p: %s", str, str); + + FMT_FREE(format); + VA_LIST_FREE(ap); + EXIT2(return i); +} + +noregparm INT WIN_FUNC(_win__vsnprintf,4) + (char *str, SIZE_T size, const char *format, va_list ap) +{ + INT i; + VA_LIST_DECL(ap) + FMT_DECL(format) + + VA_LIST_PREP(ap); + FMT_PREP(format); + + i = vsnprintf(str, size, FMT_CONV(format), VA_LIST_CONV(ap)); + TRACE2("str: %p: %s", str, str); + + FMT_FREE(format); + VA_LIST_FREE(ap); + EXIT2(return i); +} + +noregparm char *WIN_FUNC(_win_strncpy,3) + (char *dst, char *src, SIZE_T n) +{ + return strncpy(dst, src, n); +} + +noregparm SIZE_T WIN_FUNC(_win_strlen,1) + (const char *s) +{ + return strlen(s); +} + +noregparm INT WIN_FUNC(_win_strncmp,3) + (const char *s1, const char *s2, SIZE_T n) +{ + return strncmp(s1, s2, n); +} + +noregparm INT WIN_FUNC(_win_strcmp,2) + (const char *s1, const char *s2) +{ + return strcmp(s1, s2); +} + +noregparm INT WIN_FUNC(_win_stricmp,2) + (const char *s1, const char *s2) +{ + return stricmp(s1, s2); +} + +noregparm char *WIN_FUNC(_win_strncat,3) + (char *dest, const char *src, SIZE_T n) +{ + return strncat(dest, src, n); +} + +noregparm INT WIN_FUNC(_win_wcscmp,2) + (const wchar_t *s1, const wchar_t *s2) +{ + while (*s1 && *s1 == *s2) { + s1++; + s2++; + } + return *s1 - *s2; +} + +noregparm INT WIN_FUNC(_win_wcsicmp,2) + (const wchar_t *s1, const wchar_t *s2) +{ + while (*s1 && tolower((char)*s1) == tolower((char)*s2)) { + s1++; + s2++; + } + return tolower((char)*s1) - tolower((char)*s2); +} + +noregparm SIZE_T WIN_FUNC(_win_wcslen,1) + (const wchar_t *s) +{ + const wchar_t *t = s; + while (*t) + t++; + return t - s; +} + +noregparm wchar_t *WIN_FUNC(_win_wcsncpy,3) + (wchar_t *dest, const wchar_t *src, SIZE_T n) +{ + const wchar_t *s; + wchar_t *d; + s = src + n; + d = dest; + while (src < s && (*d++ = *src++)) + ; + if (s > src) + memset(d, 0, (s - src) * sizeof(wchar_t)); + return dest; +} + +noregparm wchar_t *WIN_FUNC(_win_wcscpy,2) + (wchar_t *dest, const wchar_t *src) +{ + wchar_t *d = dest; + while ((*d++ = *src++)) + ; + return dest; +} + +noregparm wchar_t *WIN_FUNC(_win_wcscat,2) + (wchar_t *dest, const wchar_t *src) +{ + wchar_t *d; + d = dest; + while (*d) + d++; + while ((*d++ = *src++)) + ; + return dest; +} + +noregparm INT WIN_FUNC(_win_towupper,1) + (wchar_t c) +{ + return toupper(c); +} + +noregparm INT WIN_FUNC(_win_towlower,1) + (wchar_t c) +{ + return tolower(c); +} + +noregparm INT WIN_FUNC(_win_tolower,1) + (INT c) +{ + return tolower(c); +} + +noregparm INT WIN_FUNC(_win_toupper,1) + (INT c) +{ + return toupper(c); +} + +noregparm void *WIN_FUNC(_win_strcpy,2) + (void *to, const void *from) +{ + return strcpy(to, from); +} + +noregparm char *WIN_FUNC(_win_strstr,2) + (const char *s1, const char *s2) +{ + return strstr(s1, s2); +} + +noregparm char *WIN_FUNC(_win_strchr,2) + (const char *s, int c) +{ + return strchr(s, c); +} + +noregparm char *WIN_FUNC(_win_strrchr,2) + (const char *s, int c) +{ + return strrchr(s, c); +} + +noregparm void *WIN_FUNC(_win_memmove,3) + (void *to, void *from, SIZE_T count) +{ + return memmove(to, from, count); +} + +noregparm void *WIN_FUNC(_win_memchr,3) + (const void *s, INT c, SIZE_T n) +{ + return memchr(s, c, n); +} + +noregparm void *WIN_FUNC(_win_memcpy,3) + (void *to, const void *from, SIZE_T n) +{ + return memcpy(to, from, n); +} + +noregparm void *WIN_FUNC(_win_memset,3) + (void *s, char c, SIZE_T count) +{ + return memset(s, c, count); +} + +noregparm int WIN_FUNC(_win_memcmp,3) + (void *s1, void *s2, SIZE_T n) +{ + return memcmp(s1, s2, n); +} + +noregparm void WIN_FUNC(_win_srand,1) + (UINT seed) +{ + net_srandom(seed); +} + +noregparm int WIN_FUNC(rand,0) + (void) +{ + char buf[6]; + int i, n; + + get_random_bytes(buf, sizeof(buf)); + for (n = i = 0; i < sizeof(buf) ; i++) + n += buf[i]; + return n; +} + +noregparm int WIN_FUNC(_win_atoi,1) + (const char *ptr) +{ + int i = simple_strtol(ptr, NULL, 10); + return i; +} + +noregparm int WIN_FUNC(_win_isprint,1) + (int c) +{ + return isprint(c); +} + +wstdcall s64 WIN_FUNC(_alldiv,2) + (s64 a, s64 b) +{ + return (a / b); +} + +wstdcall u64 WIN_FUNC(_aulldiv,2) + (u64 a, u64 b) +{ + return (a / b); +} + +wstdcall s64 WIN_FUNC(_allmul,2) + (s64 a, s64 b) +{ + return (a * b); +} + +wstdcall u64 WIN_FUNC(_aullmul,2) + (u64 a, u64 b) +{ + return (a * b); +} + +wstdcall s64 WIN_FUNC(_allrem,2) + (s64 a, s64 b) +{ + return (a % b); +} + +wstdcall u64 WIN_FUNC(_aullrem,2) + (u64 a, u64 b) +{ + return (a % b); +} + +__attribute__((regparm(3))) s64 WIN_FUNC(_allshl,2) + (s64 a, u8 b) +{ + return (a << b); +} + +__attribute__((regparm(3))) u64 WIN_FUNC(_aullshl,2) + (u64 a, u8 b) +{ + return (a << b); +} + +__attribute__((regparm(3))) s64 WIN_FUNC(_allshr,2) + (s64 a, u8 b) +{ + return (a >> b); +} + +__attribute__((regparm(3))) u64 WIN_FUNC(_aullshr,2) + (u64 a, u8 b) +{ + return (a >> b); +} + +int stricmp(const char *s1, const char *s2) +{ + while (*s1 && tolower(*s1) == tolower(*s2)) { + s1++; + s2++; + } + return *s1 - *s2; +} + +void dump_bytes(const char *ctx, const u8 *from, int len) +{ + int i, j; + u8 *buf; + + buf = kmalloc(len * 3 + 1, irql_gfp()); + if (!buf) { + ERROR("couldn't allocate memory"); + return; + } + for (i = j = 0; i < len; i++, j += 3) { + sprintf(&buf[j], "%02x ", from[i]); + } + buf[j] = 0; + printk(KERN_DEBUG "%s: %p: %s\n", ctx, from, buf); + kfree(buf); +} + +int crt_init(void) +{ + return 0; +} + +/* called when module is being removed */ +void crt_exit(void) +{ + EXIT4(return); +} --- linux-2.6.28.orig/ubuntu/ndiswrapper/wrapndis.c +++ linux-2.6.28/ubuntu/ndiswrapper/wrapndis.c @@ -0,0 +1,2085 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#include "ndis.h" +#include "iw_ndis.h" +#include "pnp.h" +#include "loader.h" +#include "wrapndis.h" +#include +#include +#include +#include +#include +#include "wrapper.h" + +/* Functions callable from the NDIS driver */ +wstdcall NTSTATUS NdisDispatchDeviceControl(struct device_object *fdo, + struct irp *irp); +wstdcall NTSTATUS NdisDispatchPnp(struct device_object *fdo, struct irp *irp); +wstdcall NTSTATUS NdisDispatchPower(struct device_object *fdo, struct irp *irp); + +workqueue_struct_t *wrapndis_wq; +static struct nt_thread *wrapndis_worker_thread; + +static int set_packet_filter(struct ndis_device *wnd, + ULONG packet_filter); +static void add_iw_stats_timer(struct ndis_device *wnd); +static void del_iw_stats_timer(struct ndis_device *wnd); +static NDIS_STATUS ndis_start_device(struct ndis_device *wnd); +static int ndis_remove_device(struct ndis_device *wnd); +static void set_multicast_list(struct ndis_device *wnd); +static int ndis_net_dev_open(struct net_device *net_dev); +static int ndis_net_dev_close(struct net_device *net_dev); + +/* MiniportReset */ +NDIS_STATUS mp_reset(struct ndis_device *wnd) +{ + NDIS_STATUS res; + struct miniport *mp; + BOOLEAN reset_address; + KIRQL irql; + + ENTER2("wnd: %p", wnd); + if (down_interruptible(&wnd->tx_ring_mutex)) + EXIT3(return NDIS_STATUS_FAILURE); + if (down_interruptible(&wnd->ndis_req_mutex)) { + up(&wnd->tx_ring_mutex); + EXIT3(return NDIS_STATUS_FAILURE); + } + mp = &wnd->wd->driver->ndis_driver->mp; + prepare_wait_condition(wnd->ndis_req_task, wnd->ndis_req_done, 0); + WARNING("%s is being reset", wnd->net_dev->name); + irql = serialize_lock_irql(wnd); + assert_irql(_irql_ == DISPATCH_LEVEL); + res = LIN2WIN2(mp->reset, &reset_address, wnd->nmb->mp_ctx); + serialize_unlock_irql(wnd, irql); + + TRACE2("%08X, %08X", res, reset_address); + if (res == NDIS_STATUS_PENDING) { + /* wait for NdisMResetComplete */ + if (wait_condition((wnd->ndis_req_done > 0), 0, + TASK_INTERRUPTIBLE) < 0) + res = NDIS_STATUS_FAILURE; + else { + res = wnd->ndis_req_status; + reset_address = wnd->ndis_req_done - 1; + } + TRACE2("%08X, %08X", res, reset_address); + } + up(&wnd->ndis_req_mutex); + if (res == NDIS_STATUS_SUCCESS && reset_address) { + set_packet_filter(wnd, wnd->packet_filter); + set_multicast_list(wnd); + } + up(&wnd->tx_ring_mutex); + EXIT3(return res); +} + +/* MiniportRequest(Query/Set)Information */ +NDIS_STATUS mp_request(enum ndis_request_type request, + struct ndis_device *wnd, ndis_oid oid, + void *buf, ULONG buflen, ULONG *written, ULONG *needed) +{ + NDIS_STATUS res; + ULONG w, n; + struct miniport *mp; + KIRQL irql; + + if (down_interruptible(&wnd->ndis_req_mutex)) + EXIT3(return NDIS_STATUS_FAILURE); + if (!written) + written = &w; + if (!needed) + needed = &n; + mp = &wnd->wd->driver->ndis_driver->mp; + prepare_wait_condition(wnd->ndis_req_task, wnd->ndis_req_done, 0); + irql = serialize_lock_irql(wnd); + assert_irql(_irql_ == DISPATCH_LEVEL); + switch (request) { + case NdisRequestQueryInformation: + TRACE2("%p, %08X, %p", mp->queryinfo, oid, wnd->nmb->mp_ctx); + res = LIN2WIN6(mp->queryinfo, wnd->nmb->mp_ctx, oid, buf, + buflen, written, needed); + break; + case NdisRequestSetInformation: + TRACE2("%p, %08X, %p", mp->setinfo, oid, wnd->nmb->mp_ctx); + res = LIN2WIN6(mp->setinfo, wnd->nmb->mp_ctx, oid, buf, + buflen, written, needed); + break; + default: + WARNING("invalid request %d, %08X", request, oid); + res = NDIS_STATUS_NOT_SUPPORTED; + break; + } + serialize_unlock_irql(wnd, irql); + TRACE2("%08X, %08X", res, oid); + if (res == NDIS_STATUS_PENDING) { + /* wait for NdisMQueryInformationComplete */ + if (wait_condition((wnd->ndis_req_done > 0), 0, + TASK_INTERRUPTIBLE) < 0) + res = NDIS_STATUS_FAILURE; + else + res = wnd->ndis_req_status; + TRACE2("%08X, %08X", res, oid); + } + up(&wnd->ndis_req_mutex); + DBG_BLOCK(2) { + if (res || needed) + TRACE2("%08X, %d, %d, %d", res, buflen, *written, + *needed); + } + EXIT3(return res); +} + +/* MiniportPnPEventNotify */ +static NDIS_STATUS mp_pnp_event(struct ndis_device *wnd, + enum ndis_device_pnp_event event, + ULONG power_profile) +{ + struct miniport *mp; + + ENTER1("%p, %d", wnd, event); + mp = &wnd->wd->driver->ndis_driver->mp; + if (!mp->pnp_event_notify) { + TRACE1("Windows driver %s doesn't support " + "MiniportPnpEventNotify", wnd->wd->driver->name); + return NDIS_STATUS_FAILURE; + } + /* RNDIS driver doesn't like to be notified if device is + * already halted */ + if (!test_bit(HW_INITIALIZED, &wnd->wd->hw_status)) + EXIT1(return NDIS_STATUS_SUCCESS); + switch (event) { + case NdisDevicePnPEventSurpriseRemoved: + TRACE1("%u, %p", + (wnd->attributes & NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK), + mp->pnp_event_notify); + if ((wnd->attributes & NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK) && + !test_bit(HW_PRESENT, &wnd->wd->hw_status) && + mp->pnp_event_notify) { + TRACE1("calling surprise_removed"); + LIN2WIN4(mp->pnp_event_notify, wnd->nmb->mp_ctx, + NdisDevicePnPEventSurpriseRemoved, NULL, 0); + } else + TRACE1("Windows driver %s doesn't support " + "MiniportPnpEventNotify for safe unplugging", + wnd->wd->driver->name); + return NDIS_STATUS_SUCCESS; + case NdisDevicePnPEventPowerProfileChanged: + if (power_profile) + power_profile = NdisPowerProfileAcOnLine; + LIN2WIN4(mp->pnp_event_notify, wnd->nmb->mp_ctx, + NdisDevicePnPEventPowerProfileChanged, + &power_profile, (ULONG)sizeof(power_profile)); + return NDIS_STATUS_SUCCESS; + default: + WARNING("event %d not yet implemented", event); + return NDIS_STATUS_SUCCESS; + } +} + +/* MiniportInitialize */ +static NDIS_STATUS mp_init(struct ndis_device *wnd) +{ + NDIS_STATUS error_status, status; + UINT medium_index; + enum ndis_medium medium_array[] = {NdisMedium802_3}; + struct miniport *mp; + + ENTER1("irql: %d", current_irql()); + if (test_bit(HW_INITIALIZED, &wnd->wd->hw_status)) { + WARNING("device %p already initialized!", wnd); + return NDIS_STATUS_FAILURE; + } + + if (!wnd->wd->driver->ndis_driver || + !wnd->wd->driver->ndis_driver->mp.init) { + WARNING("assuming WDM (non-NDIS) driver"); + EXIT1(return NDIS_STATUS_NOT_RECOGNIZED); + } + mp = &wnd->wd->driver->ndis_driver->mp; + status = LIN2WIN6(mp->init, &error_status, &medium_index, medium_array, + sizeof(medium_array) / sizeof(medium_array[0]), + wnd->nmb, wnd->nmb); + TRACE1("init returns: %08X, irql: %d", status, current_irql()); + if (status != NDIS_STATUS_SUCCESS) { + WARNING("couldn't initialize device: %08X", status); + EXIT1(return NDIS_STATUS_FAILURE); + } + + /* Wait a little to let card power up otherwise ifup might + * fail after boot */ + sleep_hz(HZ / 5); + status = mp_pnp_event(wnd, NdisDevicePnPEventPowerProfileChanged, + NdisPowerProfileAcOnLine); + if (status != NDIS_STATUS_SUCCESS) + TRACE1("setting power failed: %08X", status); + set_bit(HW_INITIALIZED, &wnd->wd->hw_status); + /* the description about NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND is + * misleading/confusing */ + status = mp_query(wnd, OID_PNP_CAPABILITIES, + &wnd->pnp_capa, sizeof(wnd->pnp_capa)); + if (status == NDIS_STATUS_SUCCESS) { + TRACE1("%d, %d", wnd->pnp_capa.wakeup.min_magic_packet_wakeup, + wnd->pnp_capa.wakeup.min_pattern_wakeup); + wnd->attributes |= NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND; + status = mp_query_int(wnd, OID_PNP_ENABLE_WAKE_UP, + &wnd->ndis_wolopts); + TRACE1("%08X, %x", status, wnd->ndis_wolopts); + } else if (status == NDIS_STATUS_NOT_SUPPORTED) + wnd->attributes &= ~NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND; + TRACE1("%d", wnd->pnp_capa.wakeup.min_magic_packet_wakeup); + /* although some NDIS drivers support suspend, Linux kernel + * has issues with suspending USB devices */ + if (wrap_is_usb_bus(wnd->wd->dev_bus)) { + wnd->attributes &= ~NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND; + wnd->ndis_wolopts = 0; + } + mp_set_int(wnd, OID_802_11_POWER_MODE, NDIS_POWER_OFF); + EXIT1(return NDIS_STATUS_SUCCESS); +} + +/* MiniportHalt */ +static void mp_halt(struct ndis_device *wnd) +{ + struct miniport *mp; + + ENTER1("%p", wnd); + if (!test_and_clear_bit(HW_INITIALIZED, &wnd->wd->hw_status)) { + WARNING("device %p is not initialized - not halting", wnd); + return; + } + hangcheck_del(wnd); + del_iw_stats_timer(wnd); + if (wnd->physical_medium == NdisPhysicalMediumWirelessLan && + wrap_is_pci_bus(wnd->wd->dev_bus)) { + up(&wnd->ndis_req_mutex); + disassociate(wnd, 0); + if (down_interruptible(&wnd->ndis_req_mutex)) + WARNING("couldn't obtain ndis_req_mutex"); + } + mp = &wnd->wd->driver->ndis_driver->mp; + TRACE1("halt: %p", mp->mp_halt); + LIN2WIN1(mp->mp_halt, wnd->nmb->mp_ctx); + /* if a driver doesn't call NdisMDeregisterInterrupt during + * halt, deregister it now */ + if (wnd->mp_interrupt) + NdisMDeregisterInterrupt(wnd->mp_interrupt); + /* cancel any timers left by bugyy windows driver; also free + * the memory for timers */ + while (1) { + struct nt_slist *slist; + struct wrap_timer *wrap_timer; + + spin_lock_bh(&ntoskernel_lock); + if ((slist = wnd->wrap_timer_slist.next)) + wnd->wrap_timer_slist.next = slist->next; + spin_unlock_bh(&ntoskernel_lock); + TIMERTRACE("%p", slist); + if (!slist) + break; + wrap_timer = container_of(slist, struct wrap_timer, slist); + wrap_timer->repeat = 0; + /* ktimer that this wrap_timer is associated to can't + * be touched, as it may have been freed by the driver + * already */ + if (del_timer_sync(&wrap_timer->timer)) + WARNING("Buggy Windows driver left timer %p " + "running", wrap_timer->nt_timer); + memset(wrap_timer, 0, sizeof(*wrap_timer)); + kfree(wrap_timer); + } + EXIT1(return); +} + +static NDIS_STATUS mp_set_power_state(struct ndis_device *wnd, + enum ndis_power_state state) +{ + NDIS_STATUS status; + + TRACE1("%d", state); + if (state == NdisDeviceStateD0) { + status = NDIS_STATUS_SUCCESS; + up(&wnd->ndis_req_mutex); + if (test_and_clear_bit(HW_HALTED, &wnd->wd->hw_status)) { + status = mp_init(wnd); + if (status == NDIS_STATUS_SUCCESS) { + set_packet_filter(wnd, wnd->packet_filter); + set_multicast_list(wnd); + } + } else if (test_and_clear_bit(HW_SUSPENDED, + &wnd->wd->hw_status)) { + status = mp_set_int(wnd, OID_PNP_SET_POWER, state); + if (status != NDIS_STATUS_SUCCESS) + WARNING("%s: setting power to state %d failed? " + "%08X", wnd->net_dev->name, state, + status); + } else + return NDIS_STATUS_FAILURE; + + if (wrap_is_pci_bus(wnd->wd->dev_bus)) { + pci_enable_wake(wnd->wd->pci.pdev, PCI_D3hot, 0); + pci_enable_wake(wnd->wd->pci.pdev, PCI_D3cold, 0); + } + if (status == NDIS_STATUS_SUCCESS) { + up(&wnd->tx_ring_mutex); + netif_device_attach(wnd->net_dev); + hangcheck_add(wnd); + add_iw_stats_timer(wnd); + } else + WARNING("%s: couldn't set power to state %d; device not" + " resumed", wnd->net_dev->name, state); + EXIT1(return status); + } else { + if (down_interruptible(&wnd->tx_ring_mutex)) + EXIT1(return NDIS_STATUS_FAILURE); + netif_device_detach(wnd->net_dev); + hangcheck_del(wnd); + del_iw_stats_timer(wnd); + status = NDIS_STATUS_NOT_SUPPORTED; + if (wnd->attributes & NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND) { + status = mp_set_int(wnd, OID_PNP_ENABLE_WAKE_UP, + wnd->ndis_wolopts); + TRACE2("0x%x, 0x%x", status, wnd->ndis_wolopts); + if (status == NDIS_STATUS_SUCCESS) { + if (wnd->ndis_wolopts) + wnd->wd->pci.wake_state = + PowerDeviceD3; + else + wnd->wd->pci.wake_state = + PowerDeviceUnspecified; + } else + WARNING("couldn't set wake-on-lan options: " + "0x%x, %08X", wnd->ndis_wolopts, status); + status = mp_set_int(wnd, OID_PNP_SET_POWER, state); + if (status == NDIS_STATUS_SUCCESS) + set_bit(HW_SUSPENDED, &wnd->wd->hw_status); + else + WARNING("suspend failed: %08X", status); + } + if (status != NDIS_STATUS_SUCCESS) { + WARNING("%s does not support power management; " + "halting the device", wnd->net_dev->name); + mp_halt(wnd); + set_bit(HW_HALTED, &wnd->wd->hw_status); + status = STATUS_SUCCESS; + } + if (down_interruptible(&wnd->ndis_req_mutex)) + WARNING("couldn't lock ndis_req_mutex"); + EXIT1(return status); + } +} + +static int ndis_set_mac_address(struct net_device *dev, void *p) +{ + struct ndis_device *wnd = netdev_priv(dev); + struct sockaddr *addr = p; + struct ndis_configuration_parameter param; + struct unicode_string key; + struct ansi_string ansi; + NDIS_STATUS res; + unsigned char mac_string[2 * ETH_ALEN + 1]; + mac_address mac; + + memcpy(mac, addr->sa_data, sizeof(mac)); + memset(mac_string, 0, sizeof(mac_string)); + res = snprintf(mac_string, sizeof(mac_string), MACSTR, MAC2STR(mac)); + if (res != (sizeof(mac_string) - 1)) + EXIT1(return -EINVAL); + TRACE1("new mac: %s", mac_string); + + RtlInitAnsiString(&ansi, mac_string); + if (RtlAnsiStringToUnicodeString(¶m.data.string, &ansi, + TRUE) != STATUS_SUCCESS) + EXIT1(return -EINVAL); + + param.type = NdisParameterString; + RtlInitAnsiString(&ansi, "NetworkAddress"); + if (RtlAnsiStringToUnicodeString(&key, &ansi, TRUE) != STATUS_SUCCESS) { + RtlFreeUnicodeString(¶m.data.string); + EXIT1(return -EINVAL); + } + NdisWriteConfiguration(&res, wnd->nmb, &key, ¶m); + RtlFreeUnicodeString(&key); + RtlFreeUnicodeString(¶m.data.string); + + if (res != NDIS_STATUS_SUCCESS) + EXIT1(return -EFAULT); + if (ndis_reinit(wnd) == NDIS_STATUS_SUCCESS) { + res = mp_query(wnd, OID_802_3_CURRENT_ADDRESS, + mac, sizeof(mac)); + if (res == NDIS_STATUS_SUCCESS) { + TRACE1("mac:" MACSTRSEP, MAC2STR(mac)); + memcpy(dev->dev_addr, mac, sizeof(mac)); + } else + ERROR("couldn't get mac address: %08X", res); + } + EXIT1(return 0); +} + +static int setup_tx_sg_list(struct ndis_device *wnd, struct sk_buff *skb, + struct ndis_packet_oob_data *oob_data) +{ + struct ndis_sg_element *sg_element; + struct ndis_sg_list *sg_list; + int i; + + ENTER3("%p, %d", skb, skb_shinfo(skb)->nr_frags); + if (skb_shinfo(skb)->nr_frags <= 1) { + sg_element = &oob_data->wrap_tx_sg_list.elements[0]; + sg_element->address = + PCI_DMA_MAP_SINGLE(wnd->wd->pci.pdev, skb->data, + skb->len, PCI_DMA_TODEVICE); + sg_element->length = skb->len; + oob_data->wrap_tx_sg_list.nent = 1; + oob_data->ext.info[ScatterGatherListPacketInfo] = + &oob_data->wrap_tx_sg_list; + TRACE3("%Lx, %u", sg_element->address, sg_element->length); + return 0; + } + sg_list = kmalloc(sizeof(*sg_list) + + (skb_shinfo(skb)->nr_frags + 1) * sizeof(*sg_element), + GFP_ATOMIC); + if (!sg_list) + return -ENOMEM; + sg_list->nent = skb_shinfo(skb)->nr_frags + 1; + TRACE3("%p, %d", sg_list, sg_list->nent); + sg_element = sg_list->elements; + sg_element->length = skb_headlen(skb); + sg_element->address = + PCI_DMA_MAP_SINGLE(wnd->wd->pci.pdev, skb->data, + skb_headlen(skb), PCI_DMA_TODEVICE); + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + sg_element++; + sg_element->length = frag->size; + sg_element->address = + pci_map_page(wnd->wd->pci.pdev, frag->page, + frag->page_offset, frag->size, + PCI_DMA_TODEVICE); + TRACE3("%Lx, %u", sg_element->address, sg_element->length); + } + oob_data->ext.info[ScatterGatherListPacketInfo] = sg_list; + return 0; +} + +static void free_tx_sg_list(struct ndis_device *wnd, + struct ndis_packet_oob_data *oob_data) +{ + int i; + struct ndis_sg_element *sg_element; + struct ndis_sg_list *sg_list = + oob_data->ext.info[ScatterGatherListPacketInfo]; + sg_element = sg_list->elements; + TRACE3("%p, %d", sg_list, sg_list->nent); + PCI_DMA_UNMAP_SINGLE(wnd->wd->pci.pdev, sg_element->address, + sg_element->length, PCI_DMA_TODEVICE); + if (sg_list->nent == 1) + EXIT3(return); + for (i = 1; i < sg_list->nent; i++, sg_element++) { + TRACE3("%Lx, %u", sg_element->address, sg_element->length); + pci_unmap_page(wnd->wd->pci.pdev, sg_element->address, + sg_element->length, PCI_DMA_TODEVICE); + } + TRACE3("%p", sg_list); + kfree(sg_list); +} + +static struct ndis_packet *alloc_tx_packet(struct ndis_device *wnd, + struct sk_buff *skb) +{ + struct ndis_packet *packet; + ndis_buffer *buffer; + struct ndis_packet_oob_data *oob_data; + NDIS_STATUS status; + + NdisAllocatePacket(&status, &packet, wnd->tx_packet_pool); + if (status != NDIS_STATUS_SUCCESS) + return NULL; + NdisAllocateBuffer(&status, &buffer, wnd->tx_buffer_pool, + skb->data, skb->len); + if (status != NDIS_STATUS_SUCCESS) { + NdisFreePacket(packet); + return NULL; + } + packet->private.buffer_head = buffer; + packet->private.buffer_tail = buffer; + + oob_data = NDIS_PACKET_OOB_DATA(packet); + oob_data->tx_skb = skb; + if (wnd->sg_dma_size) { + if (setup_tx_sg_list(wnd, skb, oob_data)) { + NdisFreeBuffer(buffer); + NdisFreePacket(packet); + return NULL; + } + } + if (skb->ip_summed == CHECKSUM_PARTIAL) { + struct ndis_tcp_ip_checksum_packet_info csum; + int protocol; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21) + protocol = ntohs(skb->protocol); +#else + protocol = skb->nh.iph->protocol; +#endif + csum.value = 0; + csum.tx.v4 = 1; + if (protocol == IPPROTO_TCP) + csum.tx.tcp = 1; + else if (protocol == IPPROTO_UDP) + csum.tx.udp = 1; +// csum->tx.ip = 1; + packet->private.flags |= NDIS_PROTOCOL_ID_TCP_IP; + oob_data->ext.info[TcpIpChecksumPacketInfo] = + (void *)(ULONG_PTR)csum.value; + } + DBG_BLOCK(4) { + dump_bytes(__FUNCTION__, skb->data, skb->len); + } + TRACE4("%p, %p, %p", packet, buffer, skb); + return packet; +} + +void free_tx_packet(struct ndis_device *wnd, struct ndis_packet *packet, + NDIS_STATUS status) +{ + ndis_buffer *buffer; + struct ndis_packet_oob_data *oob_data; + struct sk_buff *skb; + struct ndis_packet_pool *pool; + + assert_irql(_irql_ <= DISPATCH_LEVEL); + assert(packet->private.packet_flags); + oob_data = NDIS_PACKET_OOB_DATA(packet); + skb = oob_data->tx_skb; + buffer = packet->private.buffer_head; + TRACE4("%p, %p, %p, %08X", packet, buffer, skb, status); + if (status == NDIS_STATUS_SUCCESS) { + pre_atomic_add(wnd->net_stats.tx_bytes, packet->private.len); + atomic_inc_var(wnd->net_stats.tx_packets); + } else { + TRACE1("packet dropped: %08X", status); + atomic_inc_var(wnd->net_stats.tx_dropped); + } + if (wnd->sg_dma_size) + free_tx_sg_list(wnd, oob_data); + NdisFreeBuffer(buffer); + dev_kfree_skb_any(skb); + pool = packet->private.pool; + NdisFreePacket(packet); + if (netif_queue_stopped(wnd->net_dev) && + ((pool->max_descr - pool->num_used_descr) >= + (wnd->max_tx_packets / 4))) { + set_bit(NETIF_WAKEQ, &wnd->ndis_pending_work); + schedule_wrapndis_work(&wnd->ndis_work); + } + EXIT4(return); +} + +/* MiniportSend and MiniportSendPackets */ +/* this function is called holding tx_ring_mutex. start and n are such + * that start + n < TX_RING_SIZE; i.e., packets don't wrap around + * ring */ +static u8 mp_tx_packets(struct ndis_device *wnd, u8 start, u8 n) +{ + NDIS_STATUS res; + struct miniport *mp; + struct ndis_packet *packet; + u8 sent; + KIRQL irql; + + ENTER3("%d, %d", start, n); + mp = &wnd->wd->driver->ndis_driver->mp; + if (mp->send_packets) { + if (deserialized_driver(wnd)) { + LIN2WIN3(mp->send_packets, wnd->nmb->mp_ctx, + &wnd->tx_ring[start], n); + sent = n; + } else { + irql = serialize_lock_irql(wnd); + LIN2WIN3(mp->send_packets, wnd->nmb->mp_ctx, + &wnd->tx_ring[start], n); + serialize_unlock_irql(wnd, irql); + for (sent = 0; sent < n && wnd->tx_ok; sent++) { + struct ndis_packet_oob_data *oob_data; + packet = wnd->tx_ring[start + sent]; + oob_data = NDIS_PACKET_OOB_DATA(packet); + switch ((res = + xchg(&oob_data->status, + NDIS_STATUS_NOT_RECOGNIZED))) { + case NDIS_STATUS_SUCCESS: + free_tx_packet(wnd, packet, + NDIS_STATUS_SUCCESS); + break; + case NDIS_STATUS_PENDING: + break; + case NDIS_STATUS_RESOURCES: + wnd->tx_ok = 0; + /* resubmit this packet and + * the rest when resources + * become available */ + sent--; + break; + case NDIS_STATUS_FAILURE: + free_tx_packet(wnd, packet, + NDIS_STATUS_FAILURE); + break; + default: + ERROR("%p: invalid status: %08X", + packet, res); + free_tx_packet(wnd, packet, + oob_data->status); + break; + } + TRACE3("%p, %d", packet, res); + } + } + TRACE3("sent: %d(%d)", sent, n); + } else { + for (sent = 0; sent < n && wnd->tx_ok; sent++) { + struct ndis_packet_oob_data *oob_data; + packet = wnd->tx_ring[start + sent]; + oob_data = NDIS_PACKET_OOB_DATA(packet); + oob_data->status = NDIS_STATUS_NOT_RECOGNIZED; + irql = serialize_lock_irql(wnd); + res = LIN2WIN3(mp->send, wnd->nmb->mp_ctx, + packet, packet->private.flags); + serialize_unlock_irql(wnd, irql); + switch (res) { + case NDIS_STATUS_SUCCESS: + free_tx_packet(wnd, packet, res); + break; + case NDIS_STATUS_PENDING: + break; + case NDIS_STATUS_RESOURCES: + wnd->tx_ok = 0; + /* resend this packet when resources + * become available */ + sent--; + break; + case NDIS_STATUS_FAILURE: + free_tx_packet(wnd, packet, res); + break; + default: + ERROR("packet %p: invalid status: %08X", + packet, res); + break; + } + } + } + EXIT3(return sent); +} + +static void tx_worker(worker_param_t param) +{ + struct ndis_device *wnd; + s8 n; + + wnd = worker_param_data(param, struct ndis_device, tx_work); + ENTER3("tx_ok %d", wnd->tx_ok); + while (wnd->tx_ok) { + if (down_interruptible(&wnd->tx_ring_mutex)) + break; + spin_lock_bh(&wnd->tx_ring_lock); + n = wnd->tx_ring_end - wnd->tx_ring_start; + TRACE3("%d, %d, %d", wnd->tx_ring_start, wnd->tx_ring_end, n); + /* end == start if either ring is empty or full; in + * the latter case is_tx_ring_full is set */ + if (n == 0) { + if (wnd->is_tx_ring_full) + n = TX_RING_SIZE - wnd->tx_ring_start; + else { + spin_unlock_bh(&wnd->tx_ring_lock); + up(&wnd->tx_ring_mutex); + break; + } + } else if (n < 0) + n = TX_RING_SIZE - wnd->tx_ring_start; + spin_unlock_bh(&wnd->tx_ring_lock); + if (unlikely(n > wnd->max_tx_packets)) + n = wnd->max_tx_packets; + n = mp_tx_packets(wnd, wnd->tx_ring_start, n); + if (n) { + wnd->net_dev->trans_start = jiffies; + wnd->tx_ring_start = + (wnd->tx_ring_start + n) % TX_RING_SIZE; + wnd->is_tx_ring_full = 0; + } + up(&wnd->tx_ring_mutex); + TRACE3("%d, %d, %d", wnd->tx_ring_start, wnd->tx_ring_end, n); + } + EXIT3(return); +} + +static int tx_skbuff(struct sk_buff *skb, struct net_device *dev) +{ + struct ndis_device *wnd = netdev_priv(dev); + struct ndis_packet *packet; + + packet = alloc_tx_packet(wnd, skb); + if (!packet) { + TRACE2("couldn't allocate packet"); + netif_tx_lock(dev); + netif_stop_queue(dev); + netif_tx_unlock(dev); + return NETDEV_TX_BUSY; + } + spin_lock(&wnd->tx_ring_lock); + wnd->tx_ring[wnd->tx_ring_end++] = packet; + if (wnd->tx_ring_end == TX_RING_SIZE) + wnd->tx_ring_end = 0; + if (wnd->tx_ring_end == wnd->tx_ring_start) { + netif_tx_lock(dev); + wnd->is_tx_ring_full = 1; + netif_stop_queue(dev); + netif_tx_unlock(dev); + } + spin_unlock(&wnd->tx_ring_lock); + TRACE4("ring: %d, %d", wnd->tx_ring_start, wnd->tx_ring_end); + schedule_wrapndis_work(&wnd->tx_work); + return NETDEV_TX_OK; +} + +static int set_packet_filter(struct ndis_device *wnd, ULONG packet_filter) +{ + NDIS_STATUS res; + + while (1) { + res = mp_set_int(wnd, OID_GEN_CURRENT_PACKET_FILTER, + packet_filter); + if (res == NDIS_STATUS_SUCCESS) + break; + TRACE2("couldn't set filter 0x%08x", packet_filter); + /* NDIS_PACKET_TYPE_PROMISCUOUS may not work with 802.11 */ + if (packet_filter & NDIS_PACKET_TYPE_PROMISCUOUS) { + packet_filter &= ~NDIS_PACKET_TYPE_PROMISCUOUS; + continue; + } + if (packet_filter & NDIS_PACKET_TYPE_ALL_LOCAL) { + packet_filter &= ~NDIS_PACKET_TYPE_ALL_LOCAL; + continue; + } + if (packet_filter & NDIS_PACKET_TYPE_ALL_FUNCTIONAL) { + packet_filter &= ~NDIS_PACKET_TYPE_ALL_FUNCTIONAL; + continue; + } + if (packet_filter & NDIS_PACKET_TYPE_MULTICAST) { + packet_filter &= ~NDIS_PACKET_TYPE_MULTICAST; + packet_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST; + continue; + } + if (packet_filter & NDIS_PACKET_TYPE_ALL_MULTICAST) { + packet_filter &= ~NDIS_PACKET_TYPE_ALL_MULTICAST; + continue; + } + break; + } + + wnd->packet_filter = packet_filter; + res = mp_query_int(wnd, OID_GEN_CURRENT_PACKET_FILTER, &packet_filter); + if (packet_filter != wnd->packet_filter) { + WARNING("filter not set: 0x%08x, 0x%08x", + packet_filter, wnd->packet_filter); + wnd->packet_filter = packet_filter; + } + if (wnd->packet_filter) + EXIT3(return 0); + else + EXIT3(return -1); +} + +static int ndis_net_dev_open(struct net_device *net_dev) +{ + ENTER1("%p", netdev_priv(net_dev)); + netif_start_queue(net_dev); + netif_poll_enable(net_dev); + EXIT1(return 0); +} + +static int ndis_net_dev_close(struct net_device *net_dev) +{ + ENTER1("%p", netdev_priv(net_dev)); + netif_poll_disable(net_dev); + netif_tx_disable(net_dev); + EXIT1(return 0); +} + +static int ndis_change_mtu(struct net_device *net_dev, int mtu) +{ + struct ndis_device *wnd = netdev_priv(net_dev); + int max; + + if (mtu < ETH_ZLEN) + return -EINVAL; + if (mp_query_int(wnd, OID_GEN_MAXIMUM_TOTAL_SIZE, &max) != + NDIS_STATUS_SUCCESS) + return -EOPNOTSUPP; + TRACE1("%d", max); + max -= ETH_HLEN; + if (max <= ETH_ZLEN) + return -EINVAL; + if (mtu + ETH_HLEN > max) + return -EINVAL; + net_dev->mtu = mtu; + return 0; +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +static void ndis_poll_controller(struct net_device *dev) +{ + struct ndis_device *wnd = netdev_priv(dev); + + disable_irq(dev->irq); + ndis_isr(wnd->mp_interrupt->kinterrupt, wnd->mp_interrupt); + enable_irq(dev->irq); +} +#endif + +/* called from BH context */ +static struct net_device_stats *ndis_get_stats(struct net_device *dev) +{ + struct ndis_device *wnd = netdev_priv(dev); + return &wnd->net_stats; +} + +/* called from BH context */ +static void ndis_set_multicast_list(struct net_device *dev) +{ + struct ndis_device *wnd = netdev_priv(dev); + set_bit(SET_MULTICAST_LIST, &wnd->ndis_pending_work); + schedule_wrapndis_work(&wnd->ndis_work); +} + +/* called from BH context */ +struct iw_statistics *get_iw_stats(struct net_device *dev) +{ + struct ndis_device *wnd = netdev_priv(dev); + return &wnd->iw_stats; +} + +static void update_iw_stats(struct ndis_device *wnd) +{ + struct iw_statistics *iw_stats = &wnd->iw_stats; + struct ndis_wireless_stats ndis_stats; + NDIS_STATUS res; + ndis_rssi rssi; + int qual; + + ENTER2("%p", wnd); + if (wnd->iw_stats_enabled == FALSE || !netif_carrier_ok(wnd->net_dev)) { + memset(iw_stats, 0, sizeof(*iw_stats)); + EXIT2(return); + } + res = mp_query(wnd, OID_802_11_RSSI, &rssi, sizeof(rssi)); + if (res == NDIS_STATUS_SUCCESS) + iw_stats->qual.level = rssi; + + qual = 100 * (rssi - WL_NOISE) / (WL_SIGMAX - WL_NOISE); + if (qual < 0) + qual = 0; + else if (qual > 100) + qual = 100; + + iw_stats->qual.noise = WL_NOISE; + iw_stats->qual.qual = qual; + + res = mp_query(wnd, OID_802_11_STATISTICS, + &ndis_stats, sizeof(ndis_stats)); + if (res != NDIS_STATUS_SUCCESS) + EXIT2(return); + iw_stats->discard.retries = (unsigned long)ndis_stats.retry + + (unsigned long)ndis_stats.multi_retry; + iw_stats->discard.misc = (unsigned long)ndis_stats.fcs_err + + (unsigned long)ndis_stats.rtss_fail + + (unsigned long)ndis_stats.ack_fail + + (unsigned long)ndis_stats.frame_dup; + + EXIT2(return); +} + +static void set_multicast_list(struct ndis_device *wnd) +{ + struct net_device *net_dev; + ULONG packet_filter; + NDIS_STATUS res; + + net_dev = wnd->net_dev; + packet_filter = wnd->packet_filter; + + TRACE2("0x%08x", packet_filter); + if (net_dev->flags & IFF_PROMISC) { + packet_filter |= NDIS_PACKET_TYPE_PROMISCUOUS | + NDIS_PACKET_TYPE_ALL_LOCAL; + } else if (net_dev->flags & IFF_ALLMULTI || + net_dev->mc_count > wnd->multicast_size) { + packet_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST; + TRACE2("0x%08x", packet_filter); + } else if (net_dev->mc_count > 0) { + int i, size; + char *buf; + struct dev_mc_list *mclist; + size = min(wnd->multicast_size, net_dev->mc_count); + TRACE2("%d, %d", wnd->multicast_size, net_dev->mc_count); + buf = kmalloc(size * ETH_ALEN, GFP_KERNEL); + if (!buf) { + WARNING("couldn't allocate memory"); + EXIT2(return); + } + mclist = net_dev->mc_list; + for (i = 0; i < size && mclist; mclist = mclist->next) { + if (mclist->dmi_addrlen != ETH_ALEN) + continue; + memcpy(buf + i * ETH_ALEN, mclist->dmi_addr, ETH_ALEN); + TRACE2(MACSTRSEP, MAC2STR(mclist->dmi_addr)); + i++; + } + res = mp_set(wnd, OID_802_3_MULTICAST_LIST, buf, i * ETH_ALEN); + if (res == NDIS_STATUS_SUCCESS && i > 0) + packet_filter |= NDIS_PACKET_TYPE_MULTICAST; + else + packet_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST; + kfree(buf); + } + TRACE2("0x%08x", packet_filter); + res = set_packet_filter(wnd, packet_filter); + if (res) + TRACE1("couldn't set packet filter (%08X)", res); + EXIT2(return); +} + +static void link_status_off(struct ndis_device *wnd) +{ +#ifdef CONFIG_WIRELESS_EXT + union iwreq_data wrqu; + + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + wireless_send_event(wnd->net_dev, SIOCGIWAP, &wrqu, NULL); +#endif + EXIT2(return); +} + +static void link_status_on(struct ndis_device *wnd) +{ +#ifdef CONFIG_WIRELESS_EXT + struct ndis_assoc_info *ndis_assoc_info; + union iwreq_data wrqu; + NDIS_STATUS res; + const int assoc_size = sizeof(*ndis_assoc_info) + IW_CUSTOM_MAX + 32; +#endif + + ENTER2(""); +#ifdef CONFIG_WIRELESS_EXT + memset(&wrqu, 0, sizeof(wrqu)); + ndis_assoc_info = kzalloc(assoc_size, GFP_KERNEL); + if (!ndis_assoc_info) { + ERROR("couldn't allocate memory"); + goto send_assoc_event; + } + res = mp_query(wnd, OID_802_11_ASSOCIATION_INFORMATION, + ndis_assoc_info, assoc_size); + if (res) { + TRACE2("query assoc_info failed (%08X)", res); + kfree(ndis_assoc_info); + goto send_assoc_event; + } + TRACE2("%u, 0x%x, %u, 0x%x, %u", ndis_assoc_info->length, + ndis_assoc_info->req_ies, ndis_assoc_info->req_ie_length, + ndis_assoc_info->resp_ies, ndis_assoc_info->resp_ie_length); + if (ndis_assoc_info->req_ie_length > 0) { + wrqu.data.length = ndis_assoc_info->req_ie_length; + wireless_send_event(wnd->net_dev, IWEVASSOCREQIE, &wrqu, + ((char *)ndis_assoc_info) + + ndis_assoc_info->offset_req_ies); + } + if (ndis_assoc_info->resp_ie_length > 0) { + wrqu.data.length = ndis_assoc_info->resp_ie_length; + wireless_send_event(wnd->net_dev, IWEVASSOCRESPIE, &wrqu, + ((char *)ndis_assoc_info) + + ndis_assoc_info->offset_resp_ies); + } + kfree(ndis_assoc_info); + +send_assoc_event: + get_ap_address(wnd, wrqu.ap_addr.sa_data); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + TRACE2(MACSTRSEP, MAC2STR(wrqu.ap_addr.sa_data)); + wireless_send_event(wnd->net_dev, SIOCGIWAP, &wrqu, NULL); +#endif + EXIT2(return); +} + +static void iw_stats_timer_proc(unsigned long data) +{ + struct ndis_device *wnd = (struct ndis_device *)data; + + ENTER2("%d", wnd->iw_stats_interval); + if (wnd->iw_stats_interval > 0) { + set_bit(COLLECT_IW_STATS, &wnd->ndis_pending_work); + schedule_wrapndis_work(&wnd->ndis_work); + } + mod_timer(&wnd->iw_stats_timer, jiffies + wnd->iw_stats_interval); +} + +static void add_iw_stats_timer(struct ndis_device *wnd) +{ + if (wnd->physical_medium != NdisPhysicalMediumWirelessLan) + return; + if (wnd->iw_stats_interval < 0) + wnd->iw_stats_interval *= -1; + wnd->iw_stats_timer.data = (unsigned long)wnd; + wnd->iw_stats_timer.function = iw_stats_timer_proc; + mod_timer(&wnd->iw_stats_timer, jiffies + wnd->iw_stats_interval); +} + +static void del_iw_stats_timer(struct ndis_device *wnd) +{ + ENTER2("%d", wnd->iw_stats_interval); + wnd->iw_stats_interval *= -1; + del_timer_sync(&wnd->iw_stats_timer); + EXIT2(return); +} + +static void hangcheck_proc(unsigned long data) +{ + struct ndis_device *wnd = (struct ndis_device *)data; + + ENTER3("%d", wnd->hangcheck_interval); + if (wnd->hangcheck_interval > 0) { + set_bit(HANGCHECK, &wnd->ndis_pending_work); + schedule_wrapndis_work(&wnd->ndis_work); + } + mod_timer(&wnd->hangcheck_timer, jiffies + wnd->hangcheck_interval); + EXIT3(return); +} + +void hangcheck_add(struct ndis_device *wnd) +{ + if (!wnd->wd->driver->ndis_driver->mp.hangcheck || + hangcheck_interval < 0) + EXIT2(return); + + if (hangcheck_interval > 0) + wnd->hangcheck_interval = hangcheck_interval * HZ; + if (wnd->hangcheck_interval < 0) + wnd->hangcheck_interval *= -1; + wnd->hangcheck_timer.data = (unsigned long)wnd; + wnd->hangcheck_timer.function = hangcheck_proc; + mod_timer(&wnd->hangcheck_timer, jiffies + wnd->hangcheck_interval); + EXIT2(return); +} + +void hangcheck_del(struct ndis_device *wnd) +{ + ENTER2("%d", wnd->hangcheck_interval); + if (wnd->hangcheck_interval > 0) + wnd->hangcheck_interval *= -1; + del_timer_sync(&wnd->hangcheck_timer); + EXIT2(return); +} + +/* worker procedure to take care of setting/checking various states */ +static void ndis_worker(worker_param_t param) +{ + struct ndis_device *wnd; + + wnd = worker_param_data(param, struct ndis_device, ndis_work); + WORKTRACE("0x%lx", wnd->ndis_pending_work); + + if (test_and_clear_bit(NETIF_WAKEQ, &wnd->ndis_pending_work)) { + netif_tx_lock_bh(wnd->net_dev); + netif_wake_queue(wnd->net_dev); + netif_tx_unlock_bh(wnd->net_dev); + } + + if (test_and_clear_bit(LINK_STATUS_OFF, &wnd->ndis_pending_work)) + link_status_off(wnd); + + if (test_and_clear_bit(LINK_STATUS_ON, &wnd->ndis_pending_work)) + link_status_on(wnd); + + if (test_and_clear_bit(COLLECT_IW_STATS, &wnd->ndis_pending_work)) + update_iw_stats(wnd); + + if (test_and_clear_bit(SET_MULTICAST_LIST, + &wnd->ndis_pending_work)) + set_multicast_list(wnd); + + if (test_and_clear_bit(HANGCHECK, &wnd->ndis_pending_work)) { + struct miniport *mp; + BOOLEAN reset; + KIRQL irql; + + mp = &wnd->wd->driver->ndis_driver->mp; + irql = serialize_lock_irql(wnd); + reset = LIN2WIN1(mp->hangcheck, wnd->nmb->mp_ctx); + serialize_unlock_irql(wnd, irql); + if (reset) { + TRACE2("%s needs reset", wnd->net_dev->name); + mp_reset(wnd); + } + } + WORKEXIT(return); +} + +NDIS_STATUS ndis_reinit(struct ndis_device *wnd) +{ + NDIS_STATUS status; + + wnd->attributes &= ~NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND; + status = mp_set_power_state(wnd, NdisDeviceStateD3); + if (status != NDIS_STATUS_SUCCESS) { + ERROR("halting device %s failed: %08X", wnd->net_dev->name, + status); + return status; + } + status = mp_set_power_state(wnd, NdisDeviceStateD0); + if (status != NDIS_STATUS_SUCCESS) + ERROR("starting device %s failed: %08X", wnd->net_dev->name, + status); + return status; +} + +static void get_encryption_capa(struct ndis_device *wnd, char *buf, + const int buf_len) +{ + int i, mode; + NDIS_STATUS res; + struct ndis_assoc_info ndis_assoc_info; + struct ndis_add_key ndis_key; + struct ndis_capability *c; + + ENTER1("%p", wnd); + /* set network type to g, b, or a, in that order */ + res = mp_query(wnd, OID_802_11_NETWORK_TYPES_SUPPORTED, buf, buf_len); + if (res == NDIS_STATUS_SUCCESS) { + struct network_type_list *net_types; + unsigned long types = 0; + net_types = (typeof(net_types))buf; + for (i = 0; i < net_types->num; i++) { + TRACE2("%d", net_types->types[i]); + set_bit(net_types->types[i], &types); + } + if (types & Ndis802_11OFDM24) + mode = Ndis802_11OFDM24; + else if (types & Ndis802_11DS) + mode = Ndis802_11DS; + else if (types & Ndis802_11OFDM5) + mode = Ndis802_11OFDM5; + else + mode = Ndis802_11DS; + mp_set_int(wnd, OID_802_11_NETWORK_TYPE_IN_USE, mode); + } + /* check if WEP is supported */ + if (set_iw_encr_mode(wnd, IW_AUTH_CIPHER_WEP104, + IW_AUTH_CIPHER_NONE) == 0 && + get_ndis_encr_mode(wnd) == Ndis802_11Encryption1KeyAbsent) + set_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr); + + /* check if WPA is supported */ + if (set_ndis_auth_mode(wnd, Ndis802_11AuthModeWPA) == 0 && + get_ndis_auth_mode(wnd) == Ndis802_11AuthModeWPA) + set_bit(Ndis802_11AuthModeWPA, &wnd->capa.encr); + else + EXIT1(return); + + if (set_ndis_auth_mode(wnd, Ndis802_11AuthModeWPAPSK) == 0 && + get_ndis_auth_mode(wnd) == Ndis802_11AuthModeWPAPSK) + set_bit(Ndis802_11AuthModeWPAPSK, &wnd->capa.encr); + + /* check for highest encryption */ + mode = 0; + if (set_iw_encr_mode(wnd, IW_AUTH_CIPHER_CCMP, + IW_AUTH_CIPHER_NONE) == 0 && + (i = get_ndis_encr_mode(wnd)) > 0 && + (i == Ndis802_11Encryption3KeyAbsent || + i == Ndis802_11Encryption3Enabled)) + mode = Ndis802_11Encryption3Enabled; + else if (set_iw_encr_mode(wnd, IW_AUTH_CIPHER_TKIP, + IW_AUTH_CIPHER_NONE) == 0 && + (i = get_ndis_encr_mode(wnd)) > 0 && + (i == Ndis802_11Encryption2KeyAbsent || + i == Ndis802_11Encryption2Enabled)) + mode = Ndis802_11Encryption2Enabled; + else if (set_iw_encr_mode(wnd, IW_AUTH_CIPHER_WEP104, + IW_AUTH_CIPHER_NONE) == 0 && + (i = get_ndis_encr_mode(wnd)) > 0 && + (i == Ndis802_11Encryption1KeyAbsent || + i == Ndis802_11Encryption1Enabled)) + mode = Ndis802_11Encryption1Enabled; + + TRACE1("mode: %d", mode); + if (mode == 0) + EXIT1(return); + set_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr); + if (mode == Ndis802_11Encryption1Enabled) + EXIT1(return); + + ndis_key.length = 32; + ndis_key.index = 0xC0000001; + ndis_key.struct_size = sizeof(ndis_key); + res = mp_set(wnd, OID_802_11_ADD_KEY, &ndis_key, ndis_key.struct_size); + TRACE2("%08X, %lu", res, (unsigned long)sizeof(ndis_key)); + if (res && res != NDIS_STATUS_INVALID_DATA) + EXIT1(return); + res = mp_query(wnd, OID_802_11_ASSOCIATION_INFORMATION, + &ndis_assoc_info, sizeof(ndis_assoc_info)); + TRACE1("%08X", res); + if (res == NDIS_STATUS_NOT_SUPPORTED) + EXIT1(return); + + set_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr); + if (mode == Ndis802_11Encryption3Enabled) + set_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr); + /* not all drivers support OID_802_11_CAPABILITY, so we don't + * know for sure if driver support WPA or WPAPSK; assume + * WPAPSK */ + set_bit(Ndis802_11AuthModeWPAPSK, &wnd->capa.auth); + wnd->max_pmkids = 1; + + memset(buf, 0, buf_len); + c = (struct ndis_capability *)buf; + res = mp_query(wnd, OID_802_11_CAPABILITY, buf, buf_len); + if (!(res == NDIS_STATUS_SUCCESS && c->version == 2)) + EXIT1(return); + wnd->max_pmkids = c->num_PMKIDs; + + for (i = 0; i < c->num_auth_encr_pair; i++) { + struct ndis_auth_encr_pair *ae; + + ae = &c->auth_encr_pair[i]; + if ((char *)(ae + 1) > buf + buf_len) + break; + switch (ae->auth_mode) { + case Ndis802_11AuthModeOpen: + case Ndis802_11AuthModeShared: + case Ndis802_11AuthModeWPA: + case Ndis802_11AuthModeWPAPSK: + case Ndis802_11AuthModeWPANone: + case Ndis802_11AuthModeWPA2: + case Ndis802_11AuthModeWPA2PSK: + set_bit(ae->auth_mode, &wnd->capa.auth); + break; + default: + WARNING("unknown auth_mode: %d", ae->auth_mode); + break; + } + switch (ae->encr_mode) { + case Ndis802_11EncryptionDisabled: + case Ndis802_11Encryption1Enabled: + case Ndis802_11Encryption2Enabled: + case Ndis802_11Encryption3Enabled: + set_bit(ae->encr_mode, &wnd->capa.encr); + break; + default: + WARNING("unknown encr_mode: %d", ae->encr_mode); + break; + } + } + EXIT1(return); +} + +wstdcall NTSTATUS NdisDispatchDeviceControl(struct device_object *fdo, + struct irp *irp) +{ + struct ndis_device *wnd; + + TRACE3("fdo: %p", fdo); + /* for now, we don't have anything intresting here, so pass it + * down to bus driver */ + wnd = fdo->reserved; + return IoPassIrpDown(wnd->nmb->pdo, irp); +} +WIN_FUNC_DECL(NdisDispatchDeviceControl,2) + +wstdcall NTSTATUS NdisDispatchPower(struct device_object *fdo, struct irp *irp) +{ + struct io_stack_location *irp_sl; + struct ndis_device *wnd; + enum ndis_power_state state; + NTSTATUS status; + NDIS_STATUS ndis_status; + + irp_sl = IoGetCurrentIrpStackLocation(irp); + wnd = fdo->reserved; + IOTRACE("fdo: %p, fn: %d:%d, wnd: %p", fdo, irp_sl->major_fn, + irp_sl->minor_fn, wnd); + if ((irp_sl->params.power.type == SystemPowerState && + irp_sl->params.power.state.system_state > PowerSystemWorking) || + (irp_sl->params.power.type == DevicePowerState && + irp_sl->params.power.state.device_state > PowerDeviceD0)) + state = NdisDeviceStateD3; + else + state = NdisDeviceStateD0; + switch (irp_sl->minor_fn) { + case IRP_MN_SET_POWER: + if (state == NdisDeviceStateD0) { + status = IoSyncForwardIrp(wnd->nmb->pdo, irp); + if (status != STATUS_SUCCESS) + break; + ndis_status = mp_set_power_state(wnd, state); + if (ndis_status != NDIS_STATUS_SUCCESS) + WARNING("couldn't set power to %d: %08X", + state, ndis_status); + TRACE2("%s: device resumed", wnd->net_dev->name); + irp->io_status.status = status = STATUS_SUCCESS; + IoCompleteRequest(irp, IO_NO_INCREMENT); + break; + } else { + ndis_status = mp_set_power_state(wnd, state); + /* TODO: handle error case */ + if (ndis_status != NDIS_STATUS_SUCCESS) + WARNING("setting power to %d failed: %08X", + state, ndis_status); + status = IoAsyncForwardIrp(wnd->nmb->pdo, irp); + } + break; + case IRP_MN_QUERY_POWER: + if (wnd->attributes & NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND) { + ndis_status = mp_query(wnd, OID_PNP_QUERY_POWER, + &state, sizeof(state)); + TRACE2("%d, %08X", state, ndis_status); + /* this OID must always succeed */ + if (ndis_status != NDIS_STATUS_SUCCESS) + TRACE1("query power returns %08X", ndis_status); + irp->io_status.status = STATUS_SUCCESS; + } else + irp->io_status.status = STATUS_SUCCESS; + status = IoPassIrpDown(wnd->nmb->pdo, irp); + break; + case IRP_MN_WAIT_WAKE: + case IRP_MN_POWER_SEQUENCE: + /* TODO: implement WAIT_WAKE */ + status = IoPassIrpDown(wnd->nmb->pdo, irp); + break; + default: + status = IoPassIrpDown(wnd->nmb->pdo, irp); + break; + } + IOEXIT(return status); +} +WIN_FUNC_DECL(NdisDispatchPower,2) + +wstdcall NTSTATUS NdisDispatchPnp(struct device_object *fdo, struct irp *irp) +{ + struct io_stack_location *irp_sl; + struct ndis_device *wnd; + struct device_object *pdo; + NTSTATUS status; + + IOTRACE("fdo: %p, irp: %p", fdo, irp); + irp_sl = IoGetCurrentIrpStackLocation(irp); + wnd = fdo->reserved; + pdo = wnd->nmb->pdo; + switch (irp_sl->minor_fn) { + case IRP_MN_START_DEVICE: + status = IoSyncForwardIrp(pdo, irp); + if (status != STATUS_SUCCESS) + break; + if (ndis_start_device(wnd) == NDIS_STATUS_SUCCESS) + status = STATUS_SUCCESS; + else + status = STATUS_FAILURE; + irp->io_status.status = status; + IoCompleteRequest(irp, IO_NO_INCREMENT); + break; + case IRP_MN_QUERY_STOP_DEVICE: + /* TODO: implement in NDIS */ + status = IoPassIrpDown(wnd->nmb->pdo, irp); + break; + case IRP_MN_STOP_DEVICE: + mp_halt(wnd); + irp->io_status.status = STATUS_SUCCESS; + status = IoAsyncForwardIrp(pdo, irp); + break; + case IRP_MN_REMOVE_DEVICE: + TRACE1("%s", wnd->net_dev->name); + mp_pnp_event(wnd, NdisDevicePnPEventSurpriseRemoved, 0); + if (ndis_remove_device(wnd)) { + status = STATUS_FAILURE; + break; + } + /* wnd is already freed */ + status = IoAsyncForwardIrp(pdo, irp); + IoDetachDevice(fdo); + IoDeleteDevice(fdo); + break; + default: + status = IoAsyncForwardIrp(pdo, irp); + break; + } + IOTRACE("status: %08X", status); + IOEXIT(return status); +} +WIN_FUNC_DECL(NdisDispatchPnp,2) + +static void set_task_offload(struct ndis_device *wnd, void *buf, + const int buf_size) +{ + struct ndis_task_offload_header *task_offload_header; + struct ndis_task_offload *task_offload; + struct ndis_task_tcp_ip_checksum *csum = NULL; + struct ndis_task_tcp_large_send *tso = NULL; + NDIS_STATUS status; + + memset(buf, 0, buf_size); + task_offload_header = buf; + task_offload_header->version = NDIS_TASK_OFFLOAD_VERSION; + task_offload_header->size = sizeof(*task_offload_header); + task_offload_header->encap_format.flags.fixed_header_size = 1; + task_offload_header->encap_format.header_size = sizeof(struct ethhdr); + task_offload_header->encap_format.encap = IEEE_802_3_Encapsulation; + status = mp_query(wnd, OID_TCP_TASK_OFFLOAD, buf, buf_size); + TRACE1("%08X", status); + if (status != NDIS_STATUS_SUCCESS) + EXIT1(return); + if (task_offload_header->offset_first_task == 0) + EXIT1(return); + task_offload = ((void *)task_offload_header + + task_offload_header->offset_first_task); + while (1) { + TRACE1("%d, %d", task_offload->version, task_offload->task); + switch(task_offload->task) { + case TcpIpChecksumNdisTask: + csum = (void *)task_offload->task_buf; + break; + case TcpLargeSendNdisTask: + tso = (void *)task_offload->task_buf; + break; + default: + TRACE1("%d", task_offload->task); + break; + } + if (task_offload->offset_next_task == 0) + break; + task_offload = (void *)task_offload + + task_offload->offset_next_task; + } + if (tso) + TRACE1("%u, %u, %d, %d", tso->max_size, tso->min_seg_count, + tso->tcp_opts, tso->ip_opts); + if (!csum) + EXIT1(return); + TRACE1("%08x, %08x", csum->v4_tx.value, csum->v4_rx.value); + task_offload_header->encap_format.flags.fixed_header_size = 1; + task_offload_header->encap_format.header_size = sizeof(struct ethhdr); + task_offload_header->offset_first_task = sizeof(*task_offload_header); + task_offload = ((void *)task_offload_header + + task_offload_header->offset_first_task); + task_offload->offset_next_task = 0; + task_offload->size = sizeof(*task_offload); + task_offload->task = TcpIpChecksumNdisTask; + memcpy(task_offload->task_buf, csum, sizeof(*csum)); + task_offload->task_buf_length = sizeof(*csum); + status = mp_set(wnd, OID_TCP_TASK_OFFLOAD, task_offload_header, + sizeof(*task_offload_header) + + sizeof(*task_offload) + sizeof(*csum)); + TRACE1("%08X", status); + if (status != NDIS_STATUS_SUCCESS) + EXIT2(return); + wnd->tx_csum = csum->v4_tx; + if (csum->v4_tx.tcp_csum && csum->v4_tx.udp_csum) { + if (csum->v4_tx.ip_csum) { + wnd->net_dev->features |= NETIF_F_HW_CSUM; + TRACE1("hw checksum enabled"); + } else { + wnd->net_dev->features |= NETIF_F_IP_CSUM; + TRACE1("IP checksum enabled"); + } + if (wnd->sg_dma_size) + wnd->net_dev->features |= NETIF_F_SG; + } + wnd->rx_csum = csum->v4_rx; + EXIT1(return); +} + +static void get_supported_oids(struct ndis_device *wnd) +{ + NDIS_STATUS res; + int i, n, needed; + ndis_oid *oids; + + res = mp_query_info(wnd, OID_GEN_SUPPORTED_LIST, NULL, 0, NULL, + &needed); + if (!(res == NDIS_STATUS_BUFFER_TOO_SHORT || + res == NDIS_STATUS_INVALID_LENGTH)) + EXIT1(return); + oids = kmalloc(needed, GFP_KERNEL); + if (!oids) { + TRACE1("couldn't allocate memory"); + EXIT1(return); + } + res = mp_query(wnd, OID_GEN_SUPPORTED_LIST, oids, needed); + if (res) { + TRACE1("failed: %08X", res); + kfree(oids); + EXIT1(return); + } + for (i = 0, n = needed / sizeof(*oids); i < n; i++) { + TRACE1("oid: %08X", oids[i]); + /* if a wireless device didn't say so for + * OID_GEN_PHYSICAL_MEDIUM (they should, but in case) */ + if (wnd->physical_medium != NdisPhysicalMediumWirelessLan && + oids[i] == OID_802_11_SSID) + wnd->physical_medium = NdisPhysicalMediumWirelessLan; + } + kfree(oids); + EXIT1(return); +} + +static void ndis_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + struct ndis_device *wnd = netdev_priv(dev); + strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 2); + strcat(info->driver, "+"); + strncat(info->driver, wnd->wd->driver->name, + sizeof(info->driver) - strlen(DRIVER_NAME) - 1); + strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 2); + strcat(info->version, "+"); + strncat(info->version, wnd->wd->driver->version, + sizeof(info->version) - strlen(DRIVER_VERSION) - 1); + if (wrap_is_pci_bus(wnd->wd->dev_bus)) + strncpy(info->bus_info, pci_name(wnd->wd->pci.pdev), + sizeof(info->bus_info) - 1); +#ifdef ENABLE_USB + else + usb_make_path(wnd->wd->usb.udev, info->bus_info, + sizeof(info->bus_info) - 1); +#endif + return; +} + +static u32 ndis_get_link(struct net_device *dev) +{ + struct ndis_device *wnd = netdev_priv(dev); + return netif_carrier_ok(wnd->net_dev); +} + +static void ndis_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct ndis_device *wnd = netdev_priv(dev); + + wol->supported = 0; + wol->wolopts = 0; + if (!(wnd->attributes & NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND)) + EXIT2(return); + if (!wrap_is_pci_bus(wnd->wd->dev_bus)) + EXIT2(return); + /* we always suspend to D3 */ + if (wnd->pnp_capa.wakeup.min_magic_packet_wakeup < NdisDeviceStateD3) + return; + wol->supported |= WAKE_MAGIC; + if (wnd->ndis_wolopts & NDIS_PNP_WAKE_UP_MAGIC_PACKET) + wol->wolopts |= WAKE_MAGIC; + return; +} + +static int ndis_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct ndis_device *wnd = netdev_priv(dev); + + if (!(wnd->attributes & NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND)) + return -EOPNOTSUPP; + if (wnd->pnp_capa.wakeup.min_magic_packet_wakeup < NdisDeviceStateD3) + EXIT2(return -EOPNOTSUPP); + TRACE2("0x%x", wol->wolopts); + if (wol->wolopts & WAKE_MAGIC) { + wnd->ndis_wolopts |= NDIS_PNP_WAKE_UP_MAGIC_PACKET; + if (wol->wolopts != WAKE_MAGIC) + WARNING("ignored wake-on-lan options: 0x%x", + wol->wolopts & ~WAKE_MAGIC); + } else if (!wol->wolopts) + wnd->ndis_wolopts = 0; + else + return -EOPNOTSUPP; + TRACE2("0x%x", wnd->ndis_wolopts); + return 0; +} + +static u32 ndis_get_tx_csum(struct net_device *dev) +{ + struct ndis_device *wnd = netdev_priv(dev); + if (wnd->tx_csum.tcp_csum && wnd->tx_csum.udp_csum) + return 1; + else + return 0; +} + +static u32 ndis_get_rx_csum(struct net_device *dev) +{ + struct ndis_device *wnd = netdev_priv(dev); + if (wnd->rx_csum.value) + return 1; + else + return 0; +} + +static int ndis_set_tx_csum(struct net_device *dev, u32 data) +{ + struct ndis_device *wnd = netdev_priv(dev); + + if (data && (wnd->tx_csum.value == 0)) + return -EOPNOTSUPP; + + if (wnd->tx_csum.ip_csum) { + ethtool_op_set_tx_hw_csum(dev, data); + } else + ethtool_op_set_tx_csum(dev, data); + return 0; +} + +static int ndis_set_rx_csum(struct net_device *dev, u32 data) +{ + struct ndis_device *wnd = netdev_priv(dev); + + if (data && (wnd->tx_csum.value == 0)) + return -EOPNOTSUPP; + + /* TODO: enable/disable rx csum through NDIS */ + return 0; +} + +static u32 ndis_get_sg(struct net_device *dev) +{ + struct ndis_device *wnd = netdev_priv(dev); + if (wnd->sg_dma_size) + return ethtool_op_get_sg(dev); + else + return 0; +} + +static int ndis_set_sg(struct net_device *dev, u32 data) +{ + struct ndis_device *wnd = netdev_priv(dev); + if (wnd->sg_dma_size) + return ethtool_op_set_sg(dev, data); + else + return -EOPNOTSUPP; +} + +static struct ethtool_ops ndis_ethtool_ops = { + .get_drvinfo = ndis_get_drvinfo, + .get_link = ndis_get_link, + .get_wol = ndis_get_wol, + .set_wol = ndis_set_wol, + .get_tx_csum = ndis_get_tx_csum, + .get_rx_csum = ndis_get_rx_csum, + .set_tx_csum = ndis_set_tx_csum, + .set_rx_csum = ndis_set_rx_csum, + .get_sg = ndis_get_sg, + .set_sg = ndis_set_sg, +}; + +static int notifier_event(struct notifier_block *notifier, unsigned long event, + void *ptr) +{ + struct net_device *net_dev = ptr; + + ENTER2("0x%lx", event); + if (net_dev->open == ndis_net_dev_open && event == NETDEV_CHANGENAME) { + struct ndis_device *wnd = netdev_priv(net_dev); + /* called with rtnl lock held, so no need to lock */ + wrap_procfs_remove_ndis_device(wnd); + printk(KERN_INFO "%s: changing interface name from '%s' to " + "'%s'\n", DRIVER_NAME, wnd->netdev_name, net_dev->name); + memcpy(wnd->netdev_name, net_dev->name, + sizeof(wnd->netdev_name)); + wrap_procfs_add_ndis_device(wnd); + } + return NOTIFY_DONE; +} + +static struct notifier_block netdev_notifier = { + .notifier_call = notifier_event, +}; + +static NDIS_STATUS ndis_start_device(struct ndis_device *wnd) +{ + struct wrap_device *wd; + struct net_device *net_dev; + NDIS_STATUS status; + char *buf; + const int buf_len = 256; + mac_address mac; + struct transport_header_offset *tx_header_offset; + int n; + + ENTER2("%d", in_atomic()); + status = mp_init(wnd); + if (status == NDIS_STATUS_NOT_RECOGNIZED) + EXIT1(return NDIS_STATUS_SUCCESS); + if (status != NDIS_STATUS_SUCCESS) + EXIT1(return status); + wd = wnd->wd; + net_dev = wnd->net_dev; + + get_supported_oids(wnd); + memset(mac, 0, sizeof(mac)); + status = mp_query(wnd, OID_802_3_CURRENT_ADDRESS, mac, sizeof(mac)); + if (memcmp(mac, "\x00\x00\x00\x00\x00\x00", sizeof(mac)) == 0) { + status = mp_query(wnd, OID_802_3_PERMANENT_ADDRESS, mac, + sizeof(mac)); + if (status != NDIS_STATUS_SUCCESS) { + ERROR("couldn't get mac address: %08X", status); + goto err_start; + } + } + TRACE1("mac:" MACSTRSEP, MAC2STR(mac)); + memcpy(net_dev->dev_addr, mac, ETH_ALEN); + + strncpy(net_dev->name, if_name, IFNAMSIZ - 1); + net_dev->name[IFNAMSIZ - 1] = 0; + + wnd->packet_filter = NDIS_PACKET_TYPE_DIRECTED | + NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_MULTICAST; + net_dev->open = ndis_net_dev_open; + net_dev->hard_start_xmit = tx_skbuff; + net_dev->stop = ndis_net_dev_close; + net_dev->get_stats = ndis_get_stats; + net_dev->change_mtu = ndis_change_mtu; + net_dev->do_ioctl = NULL; + if (wnd->physical_medium == NdisPhysicalMediumWirelessLan) { + net_dev->wireless_handlers = &ndis_handler_def; + } + net_dev->set_multicast_list = ndis_set_multicast_list; + net_dev->set_mac_address = ndis_set_mac_address; + net_dev->ethtool_ops = &ndis_ethtool_ops; + if (wnd->mp_interrupt) + net_dev->irq = wnd->mp_interrupt->irq; + net_dev->mem_start = wnd->mem_start; + net_dev->mem_end = wnd->mem_end; + status = mp_query_int(wnd, OID_802_3_MAXIMUM_LIST_SIZE, + &wnd->multicast_size); + if (status != NDIS_STATUS_SUCCESS || wnd->multicast_size < 0) + wnd->multicast_size = 0; + if (wnd->multicast_size > 0) + net_dev->flags |= IFF_MULTICAST; + else + net_dev->flags &= ~IFF_MULTICAST; +#ifdef CONFIG_NET_POLL_CONTROLLER + net_dev->poll_controller = ndis_poll_controller; +#endif + + buf = kmalloc(buf_len, GFP_KERNEL); + if (!buf) { + WARNING("couldn't allocate memory"); + goto err_start; + } + + set_task_offload(wnd, buf, buf_len); +#ifdef NETIF_F_LLTX + net_dev->features |= NETIF_F_LLTX; +#endif + + if (register_netdev(net_dev)) { + ERROR("cannot register net device %s", net_dev->name); + goto err_register; + } + memcpy(wnd->netdev_name, net_dev->name, sizeof(wnd->netdev_name)); + memset(buf, 0, buf_len); + status = mp_query(wnd, OID_GEN_VENDOR_DESCRIPTION, buf, buf_len); + if (status != NDIS_STATUS_SUCCESS) { + WARNING("couldn't get vendor information: 0x%x", status); + buf[0] = 0; + } + wnd->drv_ndis_version = n = 0; + mp_query_int(wnd, OID_GEN_DRIVER_VERSION, &wnd->drv_ndis_version); + mp_query_int(wnd, OID_GEN_VENDOR_DRIVER_VERSION, &n); + + printk(KERN_INFO "%s: ethernet device " MACSTRSEP " using %sNDIS " + "driver: %s, version: 0x%x, NDIS version: 0x%x, vendor: '%s', " + "%s\n", net_dev->name, MAC2STR(net_dev->dev_addr), + deserialized_driver(wnd) ? "" : "serialized ", + wnd->wd->driver->name, n, wnd->drv_ndis_version, buf, + wnd->wd->conf_file_name); + + if (deserialized_driver(wnd)) { + /* deserialized drivers don't have a limit, but we + * keep max at TX_RING_SIZE */ + wnd->max_tx_packets = TX_RING_SIZE; + } else { + status = mp_query_int(wnd, OID_GEN_MAXIMUM_SEND_PACKETS, + &wnd->max_tx_packets); + if (status != NDIS_STATUS_SUCCESS) + wnd->max_tx_packets = 1; + if (wnd->max_tx_packets > TX_RING_SIZE) + wnd->max_tx_packets = TX_RING_SIZE; + } + TRACE2("maximum send packets: %d", wnd->max_tx_packets); + NdisAllocatePacketPoolEx(&status, &wnd->tx_packet_pool, + wnd->max_tx_packets, 0, + PROTOCOL_RESERVED_SIZE_IN_PACKET); + if (status != NDIS_STATUS_SUCCESS) { + ERROR("couldn't allocate packet pool"); + goto packet_pool_err; + } + NdisAllocateBufferPool(&status, &wnd->tx_buffer_pool, + wnd->max_tx_packets + 4); + if (status != NDIS_STATUS_SUCCESS) { + ERROR("couldn't allocate buffer pool"); + goto buffer_pool_err; + } + TRACE1("pool: %p", wnd->tx_buffer_pool); + + if (mp_query_int(wnd, OID_GEN_MAXIMUM_TOTAL_SIZE, &n) == + NDIS_STATUS_SUCCESS && n > ETH_HLEN) + ndis_change_mtu(wnd->net_dev, n - ETH_HLEN); + + if (mp_query_int(wnd, OID_GEN_MAC_OPTIONS, &n) == NDIS_STATUS_SUCCESS) + TRACE2("mac options supported: 0x%x", n); + + tx_header_offset = (typeof(tx_header_offset))buf; + tx_header_offset->protocol_type = NDIS_PROTOCOL_ID_TCP_IP; + tx_header_offset->header_offset = sizeof(ETH_HLEN); + status = mp_set(wnd, OID_GEN_TRANSPORT_HEADER_OFFSET, + tx_header_offset, sizeof(*tx_header_offset)); + TRACE2("%08X", status); + + status = mp_query_int(wnd, OID_GEN_PHYSICAL_MEDIUM, + &wnd->physical_medium); + if (status != NDIS_STATUS_SUCCESS) + wnd->physical_medium = NdisPhysicalMediumUnspecified; + + if (wnd->physical_medium == NdisPhysicalMediumWirelessLan) { + mp_set_int(wnd, OID_802_11_POWER_MODE, NDIS_POWER_OFF); + get_encryption_capa(wnd, buf, buf_len); + TRACE1("capbilities = %ld", wnd->capa.encr); + printk(KERN_INFO "%s: encryption modes supported: " + "%s%s%s%s%s%s%s\n", net_dev->name, + test_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr) ? + "WEP" : "none", + + test_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr) ? + "; TKIP with WPA" : "", + test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) ? + ", WPA2" : "", + test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth) ? + ", WPA2PSK" : "", + + test_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr) ? + "; AES/CCMP with WPA" : "", + test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) ? + ", WPA2" : "", + test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth) ? + ", WPA2PSK" : ""); + + set_default_iw_params(wnd); + } + kfree(buf); + wrap_procfs_add_ndis_device(wnd); + hangcheck_add(wnd); + add_iw_stats_timer(wnd); + EXIT1(return NDIS_STATUS_SUCCESS); + +buffer_pool_err: + wnd->tx_buffer_pool = NULL; + if (wnd->tx_packet_pool) { + NdisFreePacketPool(wnd->tx_packet_pool); + wnd->tx_packet_pool = NULL; + } +packet_pool_err: +err_register: + kfree(buf); +err_start: + ndis_remove_device(wnd); + EXIT1(return NDIS_STATUS_FAILURE); +} + +static int ndis_remove_device(struct ndis_device *wnd) +{ + s8 tx_pending; + + /* prevent setting essid during disassociation */ + memset(&wnd->essid, 0, sizeof(wnd->essid)); + wnd->tx_ok = 0; + if (wnd->max_tx_packets) + unregister_netdev(wnd->net_dev); + netif_carrier_off(wnd->net_dev); + /* if device is suspended, but resume failed, tx_ring_mutex + * may already be locked */ + if (down_trylock(&wnd->tx_ring_mutex)) + WARNING("couldn't obtain tx_ring_mutex"); + spin_lock_bh(&wnd->tx_ring_lock); + tx_pending = wnd->tx_ring_end - wnd->tx_ring_start; + if (tx_pending < 0) + tx_pending += TX_RING_SIZE; + else if (tx_pending == 0 && wnd->is_tx_ring_full) + tx_pending = TX_RING_SIZE - 1; + wnd->is_tx_ring_full = 0; + /* throw away pending packets */ + while (tx_pending-- > 0) { + struct ndis_packet *packet; + + packet = wnd->tx_ring[wnd->tx_ring_start]; + free_tx_packet(wnd, packet, NDIS_STATUS_CLOSING); + wnd->tx_ring_start = (wnd->tx_ring_start + 1) % TX_RING_SIZE; + } + spin_unlock_bh(&wnd->tx_ring_lock); + up(&wnd->tx_ring_mutex); + wrap_procfs_remove_ndis_device(wnd); + mp_halt(wnd); + ndis_exit_device(wnd); + + if (wnd->tx_packet_pool) { + NdisFreePacketPool(wnd->tx_packet_pool); + wnd->tx_packet_pool = NULL; + } + if (wnd->tx_buffer_pool) { + NdisFreeBufferPool(wnd->tx_buffer_pool); + wnd->tx_buffer_pool = NULL; + } + if (wnd->pmkids) + kfree(wnd->pmkids); + printk(KERN_INFO "%s: device %s removed\n", DRIVER_NAME, + wnd->net_dev->name); + kfree(wnd->nmb); + free_netdev(wnd->net_dev); + EXIT2(return 0); +} + +static wstdcall NTSTATUS NdisAddDevice(struct driver_object *drv_obj, + struct device_object *pdo) +{ + struct device_object *fdo; + struct ndis_mp_block *nmb; + NTSTATUS status; + struct ndis_device *wnd; + struct net_device *net_dev; + struct wrap_device *wd; + unsigned long i; + + ENTER2("%p, %p", drv_obj, pdo); + if (strlen(if_name) >= IFNAMSIZ) { + ERROR("interface name '%s' is too long", if_name); + return STATUS_INVALID_PARAMETER; + } + net_dev = alloc_etherdev(sizeof(*wnd)); + if (!net_dev) { + ERROR("couldn't allocate device"); + return STATUS_RESOURCES; + } + wd = pdo->reserved; + if (wrap_is_pci_bus(wd->dev_bus)) + SET_NETDEV_DEV(net_dev, &wd->pci.pdev->dev); + if (wrap_is_usb_bus(wd->dev_bus)) + SET_NETDEV_DEV(net_dev, &wd->usb.intf->dev); + status = IoCreateDevice(drv_obj, 0, NULL, FILE_DEVICE_UNKNOWN, 0, + FALSE, &fdo); + if (status != STATUS_SUCCESS) { + free_netdev(net_dev); + EXIT2(return status); + } + wnd = netdev_priv(net_dev); + TRACE1("wnd: %p", wnd); + + nmb = kmalloc(sizeof(*nmb), GFP_KERNEL); + if (!nmb) { + WARNING("couldn't allocate memory"); + IoDeleteDevice(fdo); + free_netdev(net_dev); + return STATUS_RESOURCES; + } +#if defined(DEBUG) && DEBUG >= 6 + /* poison nmb so if a driver accesses uninitialized pointers, we + * know what it is */ + for (i = 0; i < sizeof(*nmb) / sizeof(unsigned long); i++) + ((unsigned long *)nmb)[i] = i + 0x8a3fc1; +#endif + + wnd->nmb = nmb; + nmb->wnd = wnd; + nmb->pdo = pdo; + wd->wnd = wnd; + wnd->wd = wd; + wnd->net_dev = net_dev; + fdo->reserved = wnd; + nmb->fdo = fdo; + if (ndis_init_device(wnd)) { + IoDeleteDevice(fdo); + kfree(nmb); + free_netdev(net_dev); + EXIT1(return STATUS_RESOURCES); + } + nmb->next_device = IoAttachDeviceToDeviceStack(fdo, pdo); + spin_lock_init(&wnd->tx_ring_lock); + init_MUTEX(&wnd->tx_ring_mutex); + init_MUTEX(&wnd->ndis_req_mutex); + wnd->ndis_req_done = 0; + initialize_work(&wnd->tx_work, tx_worker, wnd); + wnd->tx_ring_start = 0; + wnd->tx_ring_end = 0; + wnd->is_tx_ring_full = 0; + wnd->capa.encr = 0; + wnd->capa.auth = 0; + wnd->attributes = 0; + wnd->dma_map_count = 0; + wnd->dma_map_addr = NULL; + wnd->nick[0] = 0; + init_timer(&wnd->hangcheck_timer); + wnd->scan_timestamp = 0; + init_timer(&wnd->iw_stats_timer); + wnd->iw_stats_interval = 10 * HZ; + wnd->ndis_pending_work = 0; + memset(&wnd->essid, 0, sizeof(wnd->essid)); + memset(&wnd->encr_info, 0, sizeof(wnd->encr_info)); + wnd->infrastructure_mode = Ndis802_11Infrastructure; + initialize_work(&wnd->ndis_work, ndis_worker, wnd); + wnd->iw_stats_enabled = TRUE; + + TRACE1("nmb: %p, pdo: %p, fdo: %p, attached: %p, next: %p", + nmb, pdo, fdo, fdo->attached, nmb->next_device); + + /* dispatch routines are called as Windows functions */ + for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) + drv_obj->major_func[i] = WIN_FUNC_PTR(IoPassIrpDown,2); + + drv_obj->major_func[IRP_MJ_PNP] = WIN_FUNC_PTR(NdisDispatchPnp,2); + drv_obj->major_func[IRP_MJ_POWER] = WIN_FUNC_PTR(NdisDispatchPower,2); + drv_obj->major_func[IRP_MJ_INTERNAL_DEVICE_CONTROL] = + WIN_FUNC_PTR(NdisDispatchDeviceControl,2); +// drv_obj->major_func[IRP_MJ_DEVICE_CONTROL] = +// WIN_FUNC_PTR(NdisDispatchDeviceControl,2); + EXIT2(return STATUS_SUCCESS); +} + +int init_ndis_driver(struct driver_object *drv_obj) +{ + ENTER1("%p", drv_obj); + drv_obj->drv_ext->add_device = NdisAddDevice; + return 0; +} + +int wrapndis_init(void) +{ + wrapndis_wq = create_singlethread_workqueue("wrapndis_wq"); + if (!wrapndis_wq) + EXIT1(return -ENOMEM); + wrapndis_worker_thread = wrap_worker_init(wrapndis_wq); + TRACE1("%p", wrapndis_worker_thread); + register_netdevice_notifier(&netdev_notifier); + return 0; +} + +void wrapndis_exit(void) +{ + unregister_netdevice_notifier(&netdev_notifier); + if (wrapndis_wq) + destroy_workqueue(wrapndis_wq); + TRACE1("%p", wrapndis_worker_thread); + if (wrapndis_worker_thread) + ObDereferenceObject(wrapndis_worker_thread); +} --- linux-2.6.28.orig/ubuntu/ndiswrapper/lin2win.h +++ linux-2.6.28/ubuntu/ndiswrapper/lin2win.h @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2006 Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#ifdef CONFIG_X86_64 + +/* Windows functions must have 32 bytes of shadow space for arguments + * above return address, irrespective of number of args. So argc >= 4 + */ + +#define alloc_win_stack_frame(argc) \ + "sub $(" #argc "+1)*8, %%rsp\n\t" +#define free_win_stack_frame(argc) \ + "add $(" #argc "+1)*8, %%rsp\n\t" + +/* m is index of Windows arg required; Windows arg 1 should be at + * 0(%rsp), arg 2 at 8(%rsp) and so on after the frame is allocated. +*/ + +#define lin2win_win_arg(m) "(" #m "-1)*8(%%rsp)" + +/* args for Windows function must be in clobber / output list */ + +#define outputs() \ + "=a" (_ret), "=c" (_dummy), "=d" (_dummy), \ + "=r" (r8), "=r" (r9), "=r" (r10), "=r" (r11) + +#define clobbers() "cc" + +#define LIN2WIN0(func) \ +({ \ + u64 _ret, _dummy; \ + register u64 r8 __asm__("r8"); \ + register u64 r9 __asm__("r9"); \ + register u64 r10 __asm__("r10"); \ + register u64 r11 __asm__("r11"); \ + __asm__ __volatile__( \ + alloc_win_stack_frame(4) \ + "callq *%[fptr]\n\t" \ + free_win_stack_frame(4) \ + : outputs() \ + : [fptr] "r" (func) \ + : clobbers()); \ + _ret; \ +}) + +#define LIN2WIN1(func, arg1) \ +({ \ + u64 _ret, _dummy; \ + register u64 r8 __asm__("r8"); \ + register u64 r9 __asm__("r9"); \ + register u64 r10 __asm__("r10"); \ + register u64 r11 __asm__("r11"); \ + __asm__ __volatile__( \ + alloc_win_stack_frame(4) \ + "callq *%[fptr]\n\t" \ + free_win_stack_frame(4) \ + : outputs() \ + : "c" (arg1), [fptr] "r" (func) \ + : clobbers()); \ + _ret; \ +}) + +#define LIN2WIN2(func, arg1, arg2) \ +({ \ + u64 _ret, _dummy; \ + register u64 r8 __asm__("r8"); \ + register u64 r9 __asm__("r9"); \ + register u64 r10 __asm__("r10"); \ + register u64 r11 __asm__("r11"); \ + __asm__ __volatile__( \ + alloc_win_stack_frame(4) \ + "callq *%[fptr]\n\t" \ + free_win_stack_frame(4) \ + : outputs() \ + : "c" (arg1), "d" (arg2), [fptr] "r" (func) \ + : clobbers()); \ + _ret; \ +}) + +#define LIN2WIN3(func, arg1, arg2, arg3) \ +({ \ + u64 _ret, _dummy; \ + register u64 r8 __asm__("r8") = (u64)arg3; \ + register u64 r9 __asm__("r9"); \ + register u64 r10 __asm__("r10"); \ + register u64 r11 __asm__("r11"); \ + __asm__ __volatile__( \ + alloc_win_stack_frame(4) \ + "callq *%[fptr]\n\t" \ + free_win_stack_frame(4) \ + : outputs() \ + : "c" (arg1), "d" (arg2), "r" (r8), \ + [fptr] "r" (func) \ + : clobbers()); \ + _ret; \ +}) + +#define LIN2WIN4(func, arg1, arg2, arg3, arg4) \ +({ \ + u64 _ret, _dummy; \ + register u64 r8 __asm__("r8") = (u64)arg3; \ + register u64 r9 __asm__("r9") = (u64)arg4; \ + register u64 r10 __asm__("r10"); \ + register u64 r11 __asm__("r11"); \ + __asm__ __volatile__( \ + alloc_win_stack_frame(4) \ + "callq *%[fptr]\n\t" \ + free_win_stack_frame(4) \ + : outputs() \ + : "c" (arg1), "d" (arg2), "r" (r8), "r" (r9), \ + [fptr] "r" (func) \ + : clobbers()); \ + _ret; \ +}) + +#define LIN2WIN5(func, arg1, arg2, arg3, arg4, arg5) \ +({ \ + u64 _ret, _dummy; \ + register u64 r8 __asm__("r8") = (u64)arg3; \ + register u64 r9 __asm__("r9") = (u64)arg4; \ + register u64 r10 __asm__("r10"); \ + register u64 r11 __asm__("r11"); \ + __asm__ __volatile__( \ + alloc_win_stack_frame(5) \ + "movq %[rarg5], " lin2win_win_arg(5) "\n\t" \ + "callq *%[fptr]\n\t" \ + free_win_stack_frame(5) \ + : outputs() \ + : "c" (arg1), "d" (arg2), "r" (r8), "r" (r9), \ + [rarg5] "ri" ((u64)arg5), \ + [fptr] "r" (func) \ + : clobbers()); \ + _ret; \ +}) + +#define LIN2WIN6(func, arg1, arg2, arg3, arg4, arg5, arg6) \ +({ \ + u64 _ret, _dummy; \ + register u64 r8 __asm__("r8") = (u64)arg3; \ + register u64 r9 __asm__("r9") = (u64)arg4; \ + register u64 r10 __asm__("r10"); \ + register u64 r11 __asm__("r11"); \ + __asm__ __volatile__( \ + alloc_win_stack_frame(6) \ + "movq %[rarg5], " lin2win_win_arg(5) "\n\t" \ + "movq %[rarg6], " lin2win_win_arg(6) "\n\t" \ + "callq *%[fptr]\n\t" \ + free_win_stack_frame(6) \ + : outputs() \ + : "c" (arg1), "d" (arg2), "r" (r8), "r" (r9), \ + [rarg5] "ri" ((u64)arg5), [rarg6] "ri" ((u64)arg6), \ + [fptr] "r" (func) \ + : clobbers()); \ + _ret; \ +}) + +#else // CONFIG_X86_64 + +#define LIN2WIN1(func, arg1) \ +({ \ + TRACE6("calling %p", func); \ + func(arg1); \ +}) +#define LIN2WIN2(func, arg1, arg2) \ +({ \ + TRACE6("calling %p", func); \ + func(arg1, arg2); \ +}) +#define LIN2WIN3(func, arg1, arg2, arg3) \ +({ \ + TRACE6("calling %p", func); \ + func(arg1, arg2, arg3); \ +}) +#define LIN2WIN4(func, arg1, arg2, arg3, arg4) \ +({ \ + TRACE6("calling %p", func); \ + func(arg1, arg2, arg3, arg4); \ +}) +#define LIN2WIN5(func, arg1, arg2, arg3, arg4, arg5) \ +({ \ + TRACE6("calling %p", func); \ + func(arg1, arg2, arg3, arg4, arg5); \ +}) +#define LIN2WIN6(func, arg1, arg2, arg3, arg4, arg5, arg6) \ +({ \ + TRACE6("calling %p", func); \ + func(arg1, arg2, arg3, arg4, arg5, arg6); \ +}) + +#endif // CONFIG_X86_64 --- linux-2.6.28.orig/ubuntu/ndiswrapper/usb.h +++ linux-2.6.28/ubuntu/ndiswrapper/usb.h @@ -0,0 +1,376 @@ +/* + * Copyright (C) 2004 Jan Kiszka + * Copyright (C) 2005 Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#ifndef _USB_H_ +#define _USB_H_ + +#include "ntoskernel.h" + +#define IOCTL_INTERNAL_USB_SUBMIT_URB 0x00220003 +#define IOCTL_INTERNAL_USB_RESET_PORT 0x00220007 +#define IOCTL_INTERNAL_USB_GET_PORT_STATUS 0x00220013 +#define IOCTL_INTERNAL_USB_CYCLE_PORT 0x0022001F +#define IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION 0x00220027 + +#define URB_FUNCTION_SELECT_CONFIGURATION 0x0000 +#define URB_FUNCTION_SELECT_INTERFACE 0x0001 +#define URB_FUNCTION_ABORT_PIPE 0x0002 +#define URB_FUNCTION_TAKE_FRAME_LENGTH_CONTROL 0x0003 +#define URB_FUNCTION_RELEASE_FRAME_LENGTH_CONTROL 0x0004 +#define URB_FUNCTION_GET_FRAME_LENGTH 0x0005 +#define URB_FUNCTION_SET_FRAME_LENGTH 0x0006 +#define URB_FUNCTION_GET_CURRENT_FRAME_NUMBER 0x0007 +#define URB_FUNCTION_CONTROL_TRANSFER 0x0008 +#define URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER 0x0009 +#define URB_FUNCTION_ISOCH_TRANSFER 0x000A +#define URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE 0x000B +#define URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE 0x000C +#define URB_FUNCTION_SET_FEATURE_TO_DEVICE 0x000D +#define URB_FUNCTION_SET_FEATURE_TO_INTERFACE 0x000E +#define URB_FUNCTION_SET_FEATURE_TO_ENDPOINT 0x000F +#define URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE 0x0010 +#define URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE 0x0011 +#define URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT 0x0012 +#define URB_FUNCTION_GET_STATUS_FROM_DEVICE 0x0013 +#define URB_FUNCTION_GET_STATUS_FROM_INTERFACE 0x0014 +#define URB_FUNCTION_GET_STATUS_FROM_ENDPOINT 0x0015 +#define URB_FUNCTION_RESERVED_0X0016 0x0016 +#define URB_FUNCTION_VENDOR_DEVICE 0x0017 +#define URB_FUNCTION_VENDOR_INTERFACE 0x0018 +#define URB_FUNCTION_VENDOR_ENDPOINT 0x0019 +#define URB_FUNCTION_CLASS_DEVICE 0x001A +#define URB_FUNCTION_CLASS_INTERFACE 0x001B +#define URB_FUNCTION_CLASS_ENDPOINT 0x001C +#define URB_FUNCTION_RESERVE_0X001D 0x001D +#define URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL 0x001E +#define URB_FUNCTION_CLASS_OTHER 0x001F +#define URB_FUNCTION_VENDOR_OTHER 0x0020 +#define URB_FUNCTION_GET_STATUS_FROM_OTHER 0x0021 +#define URB_FUNCTION_CLEAR_FEATURE_TO_OTHER 0x0022 +#define URB_FUNCTION_SET_FEATURE_TO_OTHER 0x0023 +#define URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT 0x0024 +#define URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT 0x0025 +#define URB_FUNCTION_GET_CONFIGURATION 0x0026 +#define URB_FUNCTION_GET_INTERFACE 0x0027 +#define URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE 0x0028 +#define URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE 0x0029 +#define URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR 0x002A +#define URB_FUNCTION_RESERVE_0X002B 0x002B +#define URB_FUNCTION_RESERVE_0X002C 0x002C +#define URB_FUNCTION_RESERVE_0X002D 0x002D +#define URB_FUNCTION_RESERVE_0X002E 0x002E +#define URB_FUNCTION_RESERVE_0X002F 0x002F +// USB 2.0 calls start at 0x0030 +#define URB_FUNCTION_SYNC_RESET_PIPE 0x0030 +#define URB_FUNCTION_SYNC_CLEAR_STALL 0x0031 +#define URB_FUNCTION_CONTROL_TRANSFER_EX 0x0032 + +#define USBD_PF_CHANGE_MAX_PACKET 0x00000001 + +#define USBD_TRANSFER_DIRECTION_OUT 0 +#define USBD_TRANSFER_DIRECTION_IN 1 + +#define USBD_SHORT_TRANSFER_OK 0x00000002 +#define USBD_START_ISO_TRANSFER_ASAP 0x00000004 +#define USBD_DEFAULT_PIPE_TRANSFER 0x00000008 + +#define USBD_TRANSFER_DIRECTION(flags) \ + ((flags) & USBD_TRANSFER_DIRECTION_IN) + +enum pipe_type {UsbdPipeTypeControl = USB_ENDPOINT_XFER_CONTROL, + UsbdPipeTypeIsochronous = USB_ENDPOINT_XFER_ISOC, + UsbdPipeTypeBulk = USB_ENDPOINT_XFER_BULK, + UsbdPipeTypeInterrupt = USB_ENDPOINT_XFER_INT}; + +#define USBD_IS_BULK_PIPE(pipe_handle) \ + (((pipe_handle)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) \ + == USB_ENDPOINT_XFER_BULK) + +#define USBD_IS_INT_PIPE(pipe_handle) \ + (((pipe_handle)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) \ + == USB_ENDPOINT_XFER_INT) + +#define USBD_PORT_ENABLED 0x00000001 +#define USBD_PORT_CONNECTED 0x00000002 + +typedef LONG USBD_STATUS; + +#define USBD_STATUS_SUCCESS 0x0 +#define USBD_STATUS_PENDING 0x40000000 +#define USBD_STATUS_CANCELED 0x00010000 + +#define USBD_STATUS_CRC 0xC0000001 +#define USBD_STATUS_BTSTUFF 0xC0000002 +#define USBD_STATUS_DATA_TOGGLE_MISMATCH 0xC0000003 +#define USBD_STATUS_STALL_PID 0xC0000004 +#define USBD_STATUS_DEV_NOT_RESPONDING 0xC0000005 +#define USBD_STATUS_PID_CHECK_FAILURE 0xC0000006 +#define USBD_STATUS_UNEXPECTED_PID 0xC0000007 +#define USBD_STATUS_DATA_OVERRUN 0xC0000008 +#define USBD_STATUS_DATA_UNDERRUN 0xC0000009 +#define USBD_STATUS_RESERVED1 0xC000000A +#define USBD_STATUS_RESERVED2 0xC000000B +#define USBD_STATUS_BUFFER_OVERRUN 0xC000000C +#define USBD_STATUS_BUFFER_UNDERRUN 0xC000000D +#define USBD_STATUS_NOT_ACCESSED 0xC000000F +#define USBD_STATUS_FIFO 0xC0000010 +#define USBD_STATUS_XACT_ERROR 0xC0000011 +#define USBD_STATUS_BABBLE_DETECTED 0xC0000012 +#define USBD_STATUS_DATA_BUFFER_ERROR 0xC0000013 + +#define USBD_STATUS_NOT_SUPPORTED 0xC0000E00 +#define USBD_STATUS_BUFFER_TOO_SMALL 0xC0003000 +#define USBD_STATUS_TIMEOUT 0xC0006000 +#define USBD_STATUS_DEVICE_GONE 0xC0007000 + +#define USBD_STATUS_NO_MEMORY 0x80000100 +#define USBD_STATUS_INVALID_URB_FUNCTION 0x80000200 +#define USBD_STATUS_INVALID_PARAMETER 0x80000300 +#define USBD_STATUS_REQUEST_FAILED 0x80000500 +#define USBD_STATUS_INVALID_PIPE_HANDLE 0x80000600 +#define USBD_STATUS_ERROR_SHORT_TRANSFER 0x80000900 + +#define USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE PAGE_SIZE + +struct urb_hcd_area { + void *reserved8[8]; +}; + +typedef struct usb_endpoint_descriptor *usbd_pipe_handle; +typedef struct usb_descriptor_header usb_common_descriptor_t; + +struct usbd_pipe_information { + USHORT wMaxPacketSize; + UCHAR bEndpointAddress; + UCHAR bInterval; + enum pipe_type type; + usbd_pipe_handle handle; + ULONG max_tx_size; + ULONG flags; +}; + +struct usbd_interface_information { + USHORT bLength; + UCHAR bInterfaceNumber; + UCHAR bAlternateSetting; + UCHAR bInterfaceClass; + UCHAR bInterfaceSubClass; + UCHAR bInterfaceProtocol; + UCHAR reserved; + void *handle; + ULONG bNumEndpoints; + struct usbd_pipe_information pipes[1]; +}; + +struct usbd_interface_list_entry { + struct usb_interface_descriptor *intf_desc; + struct usbd_interface_information *intf; +}; + +struct nt_urb_header { + USHORT length; + USHORT function; + USBD_STATUS status; + void *usbd_dev_handle; + ULONG usbd_flags; +}; + +struct usbd_select_interface { + struct nt_urb_header header; + void *handle; + struct usbd_interface_information intf; +}; + +struct usbd_select_configuration { + struct nt_urb_header header; + struct usb_config_descriptor *config; + void *handle; + struct usbd_interface_information intf; +}; + +struct usbd_control_descriptor_request { + struct nt_urb_header header; + void *reserved; + ULONG reserved0; + ULONG transfer_buffer_length; + void *transfer_buffer; + struct mdl *mdl; + union nt_urb *urb_link; + struct urb_hcd_area hca; + USHORT reserved1; + UCHAR index; + UCHAR desc_type; + USHORT language_id; + USHORT reserved2; +}; + +struct usbd_bulk_or_intr_transfer { + struct nt_urb_header header; + usbd_pipe_handle pipe_handle; + ULONG transfer_flags; + ULONG transfer_buffer_length; + void *transfer_buffer; + struct mdl *mdl; + union nt_urb *urb_link; + struct urb_hcd_area hca; +}; + +struct usbd_pipe_request { + struct nt_urb_header header; + usbd_pipe_handle pipe_handle; +}; + +struct usbd_vendor_or_class_request { + struct nt_urb_header header; + void *reserved; + ULONG transfer_flags; + ULONG transfer_buffer_length; + void *transfer_buffer; + struct mdl *mdl; + union nt_urb *link; + struct urb_hcd_area hca; + UCHAR reserved_bits; + UCHAR request; + USHORT value; + USHORT index; + USHORT reserved1; +}; + +struct urb_control_feature_request { + struct nt_urb_header header; + void *reserved; + ULONG reserved2; + ULONG reserved3; + void *reserved4; + struct mdl *reserved5; + union nt_urb *link; + struct urb_hcd_area hca; + USHORT reserved0; + USHORT feature_selector; + USHORT index; + USHORT reserved1; +}; + +struct urb_control_get_status_request { + struct nt_urb_header header; + void *reserved; + ULONG reserved0; + ULONG transfer_buffer_length; + void *transfer_buffer; + struct mdl *mdl; + union nt_urb *link; + struct urb_hcd_area hca; + UCHAR reserved1[4]; + USHORT index; + USHORT reserved2; +}; + +struct usbd_iso_packet_desc { + ULONG offset; + ULONG length; + USBD_STATUS status; +}; + +struct usbd_isochronous_transfer { + struct nt_urb_header header; + usbd_pipe_handle pipe_handle; + ULONG transfer_flags; + ULONG transfer_buffer_length; + void *transfer_buffer; + struct mdl *mdl; + union nt_urb *urb_link; + struct urb_hcd_area hca; + ULONG start_frame; + ULONG number_of_packets; + ULONG error_count; + struct usbd_iso_packet_desc iso_packet[1]; +}; + +union nt_urb { + struct nt_urb_header header; + struct usbd_select_interface select_intf; + struct usbd_select_configuration select_conf; + struct usbd_bulk_or_intr_transfer bulk_int_transfer; + struct usbd_control_descriptor_request control_desc; + struct usbd_vendor_or_class_request vendor_class_request; + struct usbd_isochronous_transfer isochronous; + struct usbd_pipe_request pipe_req; + struct urb_control_feature_request feat_req; + struct urb_control_get_status_request status_req; +}; + +struct usbd_bus_interface_usbdi { + USHORT Size; + USHORT Version; + void *Context; + void *InterfaceReference; + void *InterfaceDereference; + void *GetUSBDIVersion; + void *QueryBusTime; + void *SubmitIsoOutUrb; + void *QueryBusInformation; + /* version 1 and above have following field */ + void *IsDeviceHighSpeed; + /* version 2 (and above) have following field */ + void *LogEntry; +}; + +struct usbd_bus_information_level { + ULONG TotalBandwidth; + ULONG ConsumedBandwidth; + /* level 1 and above have following fields */ + ULONG ControllerNameLength; + wchar_t ControllerName[1]; +}; + +#define USBDI_VERSION_XP 0x00000500 // Windows XP +#define USB_HCD_CAPS_SUPPORTS_RT_THREADS 0x00000001 +#define USB_BUSIF_USBDI_VERSION_0 0x0000 +#define USB_BUSIF_USBDI_VERSION_1 0x0001 +#define USB_BUSIF_USBDI_VERSION_2 0x0002 + +struct usbd_version_info { + ULONG usbdi_version; + ULONG supported_usb_version; +}; + +struct usbd_idle_callback { + void *callback; + void *context; +}; + +#define NT_URB_STATUS(nt_urb) ((nt_urb)->header.status) + +NTSTATUS wrap_submit_irp(struct device_object *pdo, struct irp *irp); +void wrap_suspend_urbs(struct wrap_device *wd); +void wrap_resume_urbs(struct wrap_device *wd); + +void USBD_InterfaceGetUSBDIVersion(void *context, + struct usbd_version_info *version_info, + ULONG *hcd_capa) wstdcall; +BOOLEAN USBD_InterfaceIsDeviceHighSpeed(void *context) wstdcall; +void USBD_InterfaceReference(void *context) wstdcall; +void USBD_InterfaceDereference(void *context) wstdcall; +NTSTATUS USBD_InterfaceQueryBusTime(void *context, ULONG *frame) wstdcall; +NTSTATUS USBD_InterfaceSubmitIsoOutUrb(void *context, + union nt_urb *nt_urb) wstdcall; +NTSTATUS USBD_InterfaceQueryBusInformation(void *context, ULONG level, void *buf, + ULONG *buf_length, + ULONG *buf_actual_length) wstdcall; +NTSTATUS USBD_InterfaceLogEntry(void *context, ULONG driver_tag, ULONG enum_tag, + ULONG p1, ULONG p2) wstdcall; + +#endif /* USB_H */ --- linux-2.6.28.orig/ubuntu/ndiswrapper/mkexport.sh +++ linux-2.6.28/ubuntu/ndiswrapper/mkexport.sh @@ -0,0 +1,42 @@ +#! /bin/sh + +# Generate exports symbol table from C files + +input="$1" +output="$2" +exports=$(basename "$output" .h) +exec >"$output" + +echo "/* automatically generated from src */"; + +sed -n -e '/^\(wstdcall\|wfastcall\|noregparm\|__attribute__\)/{ +:more +N +s/\([^{]\)$/\1/ +t more +s/\n{$/;/ +p +}' $input + +echo "#ifdef CONFIG_X86_64"; + +sed -n \ + -e 's/.*WIN_FUNC(\([^\,]\+\) *\, *\([0-9]\+\)).*/'\ +'WIN_FUNC_DECL(\1, \2)/p' \ + -e 's/.*WIN_FUNC_PTR(\([^\,]\+\) *\, *\([0-9]\+\)).*/'\ +'WIN_FUNC_DECL(\1, \2)/p' $input | sort -u + +echo "#endif" +echo "extern struct wrap_export $exports[];" +echo "struct wrap_export $exports[] = {" + +sed -n \ + -e 's/.*WIN_FUNC(_win_\([^\,]\+\) *\, *\([0-9]\+\)).*/'\ +' WIN_WIN_SYMBOL(\1, \2),/p' \ + -e 's/.*WIN_FUNC(\([^\,]\+\) *\, *\([0-9]\+\)).*/'\ +' WIN_SYMBOL(\1, \2),/p' \ + -e 's/.*WIN_SYMBOL_MAP(\("[^"]\+"\)[ ,\n]\+\([^)]\+\)).*/'\ +' {\1, (generic_func)\2},/p' $input | sort -u + +echo " {NULL, NULL}" +echo "};" --- linux-2.6.28.orig/ubuntu/ndiswrapper/wrapper.h +++ linux-2.6.28/ubuntu/ndiswrapper/wrapper.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#ifndef WRAPPER_H +#define WRAPPER_H + +extern char *if_name; +extern int proc_uid; +extern int proc_gid; +extern int hangcheck_interval; + +#endif /* WRAPPER_H */ --- linux-2.6.28.orig/ubuntu/ndiswrapper/pe_linker.h +++ linux-2.6.28/ubuntu/ndiswrapper/pe_linker.h @@ -0,0 +1,993 @@ +/* + * This file is an excerpt of winnt.h from WINE, which bears the + * following copyright: + * + * Win32 definitions for Windows NT + * + * Copyright 1996 Alexandre Julliard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * File formats definitions + */ +typedef struct _IMAGE_DOS_HEADER { + WORD e_magic; /* 00: MZ Header signature */ + WORD e_cblp; /* 02: Bytes on last page of file */ + WORD e_cp; /* 04: Pages in file */ + WORD e_crlc; /* 06: Relocations */ + WORD e_cparhdr; /* 08: Size of header in paragraphs */ + WORD e_minalloc; /* 0a: Minimum extra paragraphs needed */ + WORD e_maxalloc; /* 0c: Maximum extra paragraphs needed */ + WORD e_ss; /* 0e: Initial (relative) SS value */ + WORD e_sp; /* 10: Initial SP value */ + WORD e_csum; /* 12: Checksum */ + WORD e_ip; /* 14: Initial IP value */ + WORD e_cs; /* 16: Initial (relative) CS value */ + WORD e_lfarlc; /* 18: File address of relocation table */ + WORD e_ovno; /* 1a: Overlay number */ + WORD e_res[4]; /* 1c: Reserved words */ + WORD e_oemid; /* 24: OEM identifier (for e_oeminfo) */ + WORD e_oeminfo; /* 26: OEM information; e_oemid specific */ + WORD e_res2[10]; /* 28: Reserved words */ + DWORD e_lfanew; /* 3c: Offset to extended header */ +} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; + +#define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */ +#define IMAGE_OS2_SIGNATURE 0x454E /* NE */ +#define IMAGE_OS2_SIGNATURE_LE 0x454C /* LE */ +#define IMAGE_OS2_SIGNATURE_LX 0x584C /* LX */ +#define IMAGE_VXD_SIGNATURE 0x454C /* LE */ +#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */ + +/* + * This is the Windows executable (NE) header. + * the name IMAGE_OS2_HEADER is misleading, but in the SDK this way. + */ +typedef struct +{ + WORD ne_magic; /* 00 NE signature 'NE' */ + BYTE ne_ver; /* 02 Linker version number */ + BYTE ne_rev; /* 03 Linker revision number */ + WORD ne_enttab; /* 04 Offset to entry table relative to NE */ + WORD ne_cbenttab; /* 06 Length of entry table in bytes */ + LONG ne_crc; /* 08 Checksum */ + WORD ne_flags; /* 0c Flags about segments in this file */ + WORD ne_autodata; /* 0e Automatic data segment number */ + WORD ne_heap; /* 10 Initial size of local heap */ + WORD ne_stack; /* 12 Initial size of stack */ + DWORD ne_csip; /* 14 Initial CS:IP */ + DWORD ne_sssp; /* 18 Initial SS:SP */ + WORD ne_cseg; /* 1c # of entries in segment table */ + WORD ne_cmod; /* 1e # of entries in module reference tab. */ + WORD ne_cbnrestab; /* 20 Length of nonresident-name table */ + WORD ne_segtab; /* 22 Offset to segment table */ + WORD ne_rsrctab; /* 24 Offset to resource table */ + WORD ne_restab; /* 26 Offset to resident-name table */ + WORD ne_modtab; /* 28 Offset to module reference table */ + WORD ne_imptab; /* 2a Offset to imported name table */ + DWORD ne_nrestab; /* 2c Offset to nonresident-name table */ + WORD ne_cmovent; /* 30 # of movable entry points */ + WORD ne_align; /* 32 Logical sector alignment shift count */ + WORD ne_cres; /* 34 # of resource segments */ + BYTE ne_exetyp; /* 36 Flags indicating target OS */ + BYTE ne_flagsothers; /* 37 Additional information flags */ + WORD ne_pretthunks; /* 38 Offset to return thunks */ + WORD ne_psegrefbytes; /* 3a Offset to segment ref. bytes */ + WORD ne_swaparea; /* 3c Reserved by Microsoft */ + WORD ne_expver; /* 3e Expected Windows version number */ +} IMAGE_OS2_HEADER, *PIMAGE_OS2_HEADER; + +typedef struct _IMAGE_VXD_HEADER { + WORD e32_magic; + BYTE e32_border; + BYTE e32_worder; + DWORD e32_level; + WORD e32_cpu; + WORD e32_os; + DWORD e32_ver; + DWORD e32_mflags; + DWORD e32_mpages; + DWORD e32_startobj; + DWORD e32_eip; + DWORD e32_stackobj; + DWORD e32_esp; + DWORD e32_pagesize; + DWORD e32_lastpagesize; + DWORD e32_fixupsize; + DWORD e32_fixupsum; + DWORD e32_ldrsize; + DWORD e32_ldrsum; + DWORD e32_objtab; + DWORD e32_objcnt; + DWORD e32_objmap; + DWORD e32_itermap; + DWORD e32_rsrctab; + DWORD e32_rsrccnt; + DWORD e32_restab; + DWORD e32_enttab; + DWORD e32_dirtab; + DWORD e32_dircnt; + DWORD e32_fpagetab; + DWORD e32_frectab; + DWORD e32_impmod; + DWORD e32_impmodcnt; + DWORD e32_impproc; + DWORD e32_pagesum; + DWORD e32_datapage; + DWORD e32_preload; + DWORD e32_nrestab; + DWORD e32_cbnrestab; + DWORD e32_nressum; + DWORD e32_autodata; + DWORD e32_debuginfo; + DWORD e32_debuglen; + DWORD e32_instpreload; + DWORD e32_instdemand; + DWORD e32_heapsize; + BYTE e32_res3[12]; + DWORD e32_winresoff; + DWORD e32_winreslen; + WORD e32_devid; + WORD e32_ddkver; +} IMAGE_VXD_HEADER, *PIMAGE_VXD_HEADER; + +/* These defines describe the meanings of the bits in the + Characteristics field */ + +#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 /* No relocation info */ +#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 +#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 +#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 +#define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010 +#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 +#define IMAGE_FILE_16BIT_MACHINE 0x0040 +#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 +#define IMAGE_FILE_32BIT_MACHINE 0x0100 +#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 +#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 +#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 +#define IMAGE_FILE_SYSTEM 0x1000 +#define IMAGE_FILE_DLL 0x2000 +#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 +#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 + +/* These are the settings of the Machine field. */ +#define IMAGE_FILE_MACHINE_UNKNOWN 0 +#define IMAGE_FILE_MACHINE_I860 0x014d +#define IMAGE_FILE_MACHINE_I386 0x014c +#define IMAGE_FILE_MACHINE_R3000 0x0162 +#define IMAGE_FILE_MACHINE_R4000 0x0166 +#define IMAGE_FILE_MACHINE_R10000 0x0168 +#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169 +#define IMAGE_FILE_MACHINE_ALPHA 0x0184 +#define IMAGE_FILE_MACHINE_SH3 0x01a2 +#define IMAGE_FILE_MACHINE_SH3DSP 0x01a3 +#define IMAGE_FILE_MACHINE_SH3E 0x01a4 +#define IMAGE_FILE_MACHINE_SH4 0x01a6 +#define IMAGE_FILE_MACHINE_SH5 0x01a8 +#define IMAGE_FILE_MACHINE_ARM 0x01c0 +#define IMAGE_FILE_MACHINE_THUMB 0x01c2 +#define IMAGE_FILE_MACHINE_AM33 0x01d3 +#define IMAGE_FILE_MACHINE_POWERPC 0x01f0 +#define IMAGE_FILE_MACHINE_POWERPCFP 0x01f1 +#define IMAGE_FILE_MACHINE_IA64 0x0200 +#define IMAGE_FILE_MACHINE_MIPS16 0x0266 +#define IMAGE_FILE_MACHINE_ALPHA64 0x0284 +#define IMAGE_FILE_MACHINE_MIPSFPU 0x0366 +#define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466 +#define IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64 +#define IMAGE_FILE_MACHINE_TRICORE 0x0520 +#define IMAGE_FILE_MACHINE_CEF 0x0cef +#define IMAGE_FILE_MACHINE_EBC 0x0ebc +#define IMAGE_FILE_MACHINE_AMD64 0x8664 +#define IMAGE_FILE_MACHINE_M32R 0x9041 +#define IMAGE_FILE_MACHINE_CEE 0xc0ee + +#define IMAGE_SIZEOF_FILE_HEADER 20 +#define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER 56 +#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28 +#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER32 224 +#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER64 240 +#define IMAGE_SIZEOF_SHORT_NAME 8 +#define IMAGE_SIZEOF_SECTION_HEADER 40 +#define IMAGE_SIZEOF_SYMBOL 18 +#define IMAGE_SIZEOF_AUX_SYMBOL 18 +#define IMAGE_SIZEOF_RELOCATION 10 +#define IMAGE_SIZEOF_BASE_RELOCATION 8 +#define IMAGE_SIZEOF_LINENUMBER 6 +#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 + +/* Possible Magic values */ +#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x010b +#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x020b +#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x0107 + +#ifdef CONFIG_X86_64 +#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER IMAGE_SIZEOF_NT_OPTIONAL_HEADER64 +#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR64_MAGIC +#else +#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER IMAGE_SIZEOF_NT_OPTIONAL_HEADER32 +#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR32_MAGIC +#endif + +/* These are indexes into the DataDirectory array */ +#define IMAGE_FILE_EXPORT_DIRECTORY 0 +#define IMAGE_FILE_IMPORT_DIRECTORY 1 +#define IMAGE_FILE_RESOURCE_DIRECTORY 2 +#define IMAGE_FILE_EXCEPTION_DIRECTORY 3 +#define IMAGE_FILE_SECURITY_DIRECTORY 4 +#define IMAGE_FILE_BASE_RELOCATION_TABLE 5 +#define IMAGE_FILE_DEBUG_DIRECTORY 6 +#define IMAGE_FILE_DESCRIPTION_STRING 7 +#define IMAGE_FILE_MACHINE_VALUE 8 /* Mips */ +#define IMAGE_FILE_THREAD_LOCAL_STORAGE 9 +#define IMAGE_FILE_CALLBACK_DIRECTORY 10 + +/* Directory Entries, indices into the DataDirectory array */ + +#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 +#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 +#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 +#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 +#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 +#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 +#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 +#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 +#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 /* (MIPS GP) */ +#define IMAGE_DIRECTORY_ENTRY_TLS 9 +#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 +#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 +#define IMAGE_DIRECTORY_ENTRY_IAT 12 /* Import Address Table */ +#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 +#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 + +/* Subsystem Values */ + +#define IMAGE_SUBSYSTEM_UNKNOWN 0 +#define IMAGE_SUBSYSTEM_NATIVE 1 +#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 /* Windows GUI subsystem */ +#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 /* Windows character subsystem */ +#define IMAGE_SUBSYSTEM_OS2_CUI 5 +#define IMAGE_SUBSYSTEM_POSIX_CUI 7 +#define IMAGE_SUBSYSTEM_NATIVE_WINDOWS 8 /* native Win9x driver */ +#define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9 /* Windows CE subsystem */ +#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10 +#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 +#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 +#define IMAGE_SUBSYSTEM_EFI_ROM 13 +#define IMAGE_SUBSYSTEM_XBOX 14 + +typedef struct _IMAGE_FILE_HEADER { + WORD Machine; + WORD NumberOfSections; + DWORD TimeDateStamp; + DWORD PointerToSymbolTable; + DWORD NumberOfSymbols; + WORD SizeOfOptionalHeader; + WORD Characteristics; +} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; + +typedef struct _IMAGE_DATA_DIRECTORY { + DWORD VirtualAddress; + DWORD Size; +} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; + +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 + +typedef struct _IMAGE_OPTIONAL_HEADER32 { + + /* Standard fields */ + + WORD Magic; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + DWORD SizeOfCode; + DWORD SizeOfInitializedData; + DWORD SizeOfUninitializedData; + DWORD AddressOfEntryPoint; + DWORD BaseOfCode; + DWORD BaseOfData; + + /* NT additional fields */ + DWORD ImageBase; + DWORD SectionAlignment; + DWORD FileAlignment; + WORD MajorOperatingSystemVersion; + WORD MinorOperatingSystemVersion; + WORD MajorImageVersion; + WORD MinorImageVersion; + WORD MajorSubsystemVersion; + WORD MinorSubsystemVersion; + DWORD Win32VersionValue; + DWORD SizeOfImage; + DWORD SizeOfHeaders; + DWORD CheckSum; + WORD Subsystem; + WORD DllCharacteristics; + DWORD SizeOfStackReserve; + DWORD SizeOfStackCommit; + DWORD SizeOfHeapReserve; + DWORD SizeOfHeapCommit; + DWORD LoaderFlags; + DWORD NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32; + +typedef struct _IMAGE_OPTIONAL_HEADER64 { + + /* Standard fields */ + + WORD Magic; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + DWORD SizeOfCode; + DWORD SizeOfInitializedData; + DWORD SizeOfUninitializedData; + DWORD AddressOfEntryPoint; + DWORD BaseOfCode; + + /* NT additional fields */ + ULONGLONG ImageBase; + DWORD SectionAlignment; + DWORD FileAlignment; + WORD MajorOperatingSystemVersion; + WORD MinorOperatingSystemVersion; + WORD MajorImageVersion; + WORD MinorImageVersion; + WORD MajorSubsystemVersion; + WORD MinorSubsystemVersion; + DWORD Win32VersionValue; + DWORD SizeOfImage; + DWORD SizeOfHeaders; + DWORD CheckSum; + WORD Subsystem; + WORD DllCharacteristics; + ULONGLONG SizeOfStackReserve; + ULONGLONG SizeOfStackCommit; + ULONGLONG SizeOfHeapReserve; + ULONGLONG SizeOfHeapCommit; + DWORD LoaderFlags; + DWORD NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64; + +#ifdef CONFIG_X86_64 +typedef IMAGE_OPTIONAL_HEADER64 IMAGE_OPTIONAL_HEADER; +typedef PIMAGE_OPTIONAL_HEADER64 PIMAGE_OPTIONAL_HEADER; +#else +typedef IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER; +typedef PIMAGE_OPTIONAL_HEADER32 PIMAGE_OPTIONAL_HEADER; +#endif + +typedef struct _IMAGE_NT_HEADERS32 { + DWORD Signature; /* "PE"\0\0 */ /* 0x00 */ + IMAGE_FILE_HEADER FileHeader; /* 0x04 */ + IMAGE_OPTIONAL_HEADER32 OptionalHeader; /* 0x18 */ +} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32; + +typedef struct _IMAGE_NT_HEADERS64 { + DWORD Signature; /* "PE"\0\0 */ /* 0x00 */ + IMAGE_FILE_HEADER FileHeader; /* 0x04 */ + IMAGE_OPTIONAL_HEADER64 OptionalHeader; /* 0x18 */ +} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64; + +#ifdef CONFIG_X86_64 +typedef IMAGE_NT_HEADERS64 IMAGE_NT_HEADERS; +typedef PIMAGE_NT_HEADERS64 PIMAGE_NT_HEADERS; +#else +typedef IMAGE_NT_HEADERS32 IMAGE_NT_HEADERS; +typedef PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS; +#endif + +#define IMAGE_SIZEOF_SHORT_NAME 8 + +typedef struct _IMAGE_SECTION_HEADER { + BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; + union { + DWORD PhysicalAddress; + DWORD VirtualSize; + } Misc; + DWORD VirtualAddress; + DWORD SizeOfRawData; + DWORD PointerToRawData; + DWORD PointerToRelocations; + DWORD PointerToLinenumbers; + WORD NumberOfRelocations; + WORD NumberOfLinenumbers; + DWORD Characteristics; +} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; + +#define IMAGE_SIZEOF_SECTION_HEADER 40 + +#define IMAGE_FIRST_SECTION(ntheader) \ +((PIMAGE_SECTION_HEADER)((LPBYTE)&((PIMAGE_NT_HEADERS)(ntheader))->OptionalHeader + \ +((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader)) + +/* These defines are for the Characteristics bitfield. */ +/* #define IMAGE_SCN_TYPE_REG 0x00000000 - Reserved */ +/* #define IMAGE_SCN_TYPE_DSECT 0x00000001 - Reserved */ +/* #define IMAGE_SCN_TYPE_NOLOAD 0x00000002 - Reserved */ +/* #define IMAGE_SCN_TYPE_GROUP 0x00000004 - Reserved */ +#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* Reserved */ +/* #define IMAGE_SCN_TYPE_COPY 0x00000010 - Reserved */ + +#define IMAGE_SCN_CNT_CODE 0x00000020 +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 + +#define IMAGE_SCN_LNK_OTHER 0x00000100 +#define IMAGE_SCN_LNK_INFO 0x00000200 +/* #define IMAGE_SCN_TYPE_OVER 0x00000400 - Reserved */ +#define IMAGE_SCN_LNK_REMOVE 0x00000800 +#define IMAGE_SCN_LNK_COMDAT 0x00001000 + +/* 0x00002000 - Reserved */ +/* #define IMAGE_SCN_MEM_PROTECTED 0x00004000 - Obsolete */ +#define IMAGE_SCN_MEM_FARDATA 0x00008000 + +/* #define IMAGE_SCN_MEM_SYSHEAP 0x00010000 - Obsolete */ +#define IMAGE_SCN_MEM_PURGEABLE 0x00020000 +#define IMAGE_SCN_MEM_16BIT 0x00020000 +#define IMAGE_SCN_MEM_LOCKED 0x00040000 +#define IMAGE_SCN_MEM_PRELOAD 0x00080000 + +#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 +#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 +#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 +#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 +#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 /* Default */ +#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 +#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 +#define IMAGE_SCN_ALIGN_128BYTES 0x00800000 +#define IMAGE_SCN_ALIGN_256BYTES 0x00900000 +#define IMAGE_SCN_ALIGN_512BYTES 0x00A00000 +#define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000 +#define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000 +#define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000 +#define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000 +/* 0x00F00000 - Unused */ +#define IMAGE_SCN_ALIGN_MASK 0x00F00000 + +#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 + + +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 +#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 +#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 +#define IMAGE_SCN_MEM_SHARED 0x10000000 +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 +#define IMAGE_SCN_MEM_READ 0x40000000 +#define IMAGE_SCN_MEM_WRITE 0x80000000 + +typedef struct _IMAGE_SYMBOL { + union { + BYTE ShortName[8]; + struct { + DWORD Short; + DWORD Long; + } Name; + DWORD LongName[2]; + } N; + DWORD Value; + SHORT SectionNumber; + WORD Type; + BYTE StorageClass; + BYTE NumberOfAuxSymbols; +} IMAGE_SYMBOL; +typedef IMAGE_SYMBOL *PIMAGE_SYMBOL; + +#define IMAGE_SIZEOF_SYMBOL 18 + +typedef struct _IMAGE_LINENUMBER { + union { + DWORD SymbolTableIndex; + DWORD VirtualAddress; + } Type; + WORD Linenumber; +} IMAGE_LINENUMBER; +typedef IMAGE_LINENUMBER *PIMAGE_LINENUMBER; + +#define IMAGE_SIZEOF_LINENUMBER 6 + +typedef union _IMAGE_AUX_SYMBOL { + struct { + DWORD TagIndex; + union { + struct { + WORD Linenumber; + WORD Size; + } LnSz; + DWORD TotalSize; + } Misc; + union { + struct { + DWORD PointerToLinenumber; + DWORD PointerToNextFunction; + } Function; + struct { + WORD Dimension[4]; + } Array; + } FcnAry; + WORD TvIndex; + } Sym; + struct { + BYTE Name[IMAGE_SIZEOF_SYMBOL]; + } File; + struct { + DWORD Length; + WORD NumberOfRelocations; + WORD NumberOfLinenumbers; + DWORD CheckSum; + SHORT Number; + BYTE Selection; + } Section; +} IMAGE_AUX_SYMBOL; +typedef IMAGE_AUX_SYMBOL *PIMAGE_AUX_SYMBOL; + +#define IMAGE_SIZEOF_AUX_SYMBOL 18 + +#define IMAGE_SYM_UNDEFINED (SHORT)0 +#define IMAGE_SYM_ABSOLUTE (SHORT)-1 +#define IMAGE_SYM_DEBUG (SHORT)-2 + +#define IMAGE_SYM_TYPE_NULL 0x0000 +#define IMAGE_SYM_TYPE_VOID 0x0001 +#define IMAGE_SYM_TYPE_CHAR 0x0002 +#define IMAGE_SYM_TYPE_SHORT 0x0003 +#define IMAGE_SYM_TYPE_INT 0x0004 +#define IMAGE_SYM_TYPE_LONG 0x0005 +#define IMAGE_SYM_TYPE_FLOAT 0x0006 +#define IMAGE_SYM_TYPE_DOUBLE 0x0007 +#define IMAGE_SYM_TYPE_STRUCT 0x0008 +#define IMAGE_SYM_TYPE_UNION 0x0009 +#define IMAGE_SYM_TYPE_ENUM 0x000A +#define IMAGE_SYM_TYPE_MOE 0x000B +#define IMAGE_SYM_TYPE_BYTE 0x000C +#define IMAGE_SYM_TYPE_WORD 0x000D +#define IMAGE_SYM_TYPE_UINT 0x000E +#define IMAGE_SYM_TYPE_DWORD 0x000F +#define IMAGE_SYM_TYPE_PCODE 0x8000 + +#define IMAGE_SYM_DTYPE_NULL 0 +#define IMAGE_SYM_DTYPE_POINTER 1 +#define IMAGE_SYM_DTYPE_FUNCTION 2 +#define IMAGE_SYM_DTYPE_ARRAY 3 + +#define IMAGE_SYM_CLASS_END_OF_FUNCTION (BYTE )-1 +#define IMAGE_SYM_CLASS_NULL 0x0000 +#define IMAGE_SYM_CLASS_AUTOMATIC 0x0001 +#define IMAGE_SYM_CLASS_EXTERNAL 0x0002 +#define IMAGE_SYM_CLASS_STATIC 0x0003 +#define IMAGE_SYM_CLASS_REGISTER 0x0004 +#define IMAGE_SYM_CLASS_EXTERNAL_DEF 0x0005 +#define IMAGE_SYM_CLASS_LABEL 0x0006 +#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 0x0007 +#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 0x0008 +#define IMAGE_SYM_CLASS_ARGUMENT 0x0009 +#define IMAGE_SYM_CLASS_STRUCT_TAG 0x000A +#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 0x000B +#define IMAGE_SYM_CLASS_UNION_TAG 0x000C +#define IMAGE_SYM_CLASS_TYPE_DEFINITION 0x000D +#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 0x000E +#define IMAGE_SYM_CLASS_ENUM_TAG 0x000F +#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 0x0010 +#define IMAGE_SYM_CLASS_REGISTER_PARAM 0x0011 +#define IMAGE_SYM_CLASS_BIT_FIELD 0x0012 + +#define IMAGE_SYM_CLASS_FAR_EXTERNAL 0x0044 +#define IMAGE_SYM_CLASS_BLOCK 0x0064 +#define IMAGE_SYM_CLASS_FUNCTION 0x0065 +#define IMAGE_SYM_CLASS_END_OF_STRUCT 0x0066 +#define IMAGE_SYM_CLASS_FILE 0x0067 +#define IMAGE_SYM_CLASS_SECTION 0x0068 +#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 0x0069 + +#define N_BTMASK 0x000F +#define N_TMASK 0x0030 +#define N_TMASK1 0x00C0 +#define N_TMASK2 0x00F0 +#define N_BTSHFT 4 +#define N_TSHIFT 2 + +#define BTYPE(x) ((x) & N_BTMASK) + +#ifndef ISPTR +#define ISPTR(x) (((x) & N_TMASK) == (IMAGE_SYM_DTYPE_POINTER << N_BTSHFT)) +#endif + +#ifndef ISFCN +#define ISFCN(x) (((x) & N_TMASK) == (IMAGE_SYM_DTYPE_FUNCTION << N_BTSHFT)) +#endif + +#ifndef ISARY +#define ISARY(x) (((x) & N_TMASK) == (IMAGE_SYM_DTYPE_ARRAY << N_BTSHFT)) +#endif + +#ifndef ISTAG +#define ISTAG(x) ((x)==IMAGE_SYM_CLASS_STRUCT_TAG || (x)==IMAGE_SYM_CLASS_UNION_TAG || (x)==IMAGE_SYM_CLASS_ENUM_TAG) +#endif + +#ifndef INCREF +#define INCREF(x) ((((x)&~N_BTMASK)<>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK)) +#endif + +#define IMAGE_COMDAT_SELECT_NODUPLICATES 1 +#define IMAGE_COMDAT_SELECT_ANY 2 +#define IMAGE_COMDAT_SELECT_SAME_SIZE 3 +#define IMAGE_COMDAT_SELECT_EXACT_MATCH 4 +#define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5 +#define IMAGE_COMDAT_SELECT_LARGEST 6 +#define IMAGE_COMDAT_SELECT_NEWEST 7 + +#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1 +#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2 +#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3 + +/* Export module directory */ + +typedef struct _IMAGE_EXPORT_DIRECTORY { + DWORD Characteristics; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + DWORD Name; + DWORD Base; + DWORD NumberOfFunctions; + DWORD NumberOfNames; + DWORD AddressOfFunctions; + DWORD AddressOfNames; + DWORD AddressOfNameOrdinals; +} IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY; + +/* Import name entry */ +typedef struct _IMAGE_IMPORT_BY_NAME { + WORD Hint; + BYTE Name[1]; +} IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME; + +/* Import thunk */ +typedef struct _IMAGE_THUNK_DATA32 { + union { + DWORD ForwarderString; + DWORD Function; + DWORD Ordinal; + DWORD AddressOfData; + } u1; +} IMAGE_THUNK_DATA32,*PIMAGE_THUNK_DATA32; + +typedef struct _IMAGE_THUNK_DATA64 { + union { + ULONGLONG ForwarderString; + ULONGLONG Function; + ULONGLONG Ordinal; + ULONGLONG AddressOfData; + } u1; +} IMAGE_THUNK_DATA64,*PIMAGE_THUNK_DATA64; + +#ifdef CONFIG_X86_64 +typedef IMAGE_THUNK_DATA32 IMAGE_THUNK_DATA; +typedef PIMAGE_THUNK_DATA32 PIMAGE_THUNK_DATA; +#else +typedef IMAGE_THUNK_DATA64 IMAGE_THUNK_DATA; +typedef PIMAGE_THUNK_DATA64 PIMAGE_THUNK_DATA; +#endif + +/* Import module directory */ + +typedef struct packed _IMAGE_IMPORT_DESCRIPTOR { + union { + DWORD Characteristics; /* 0 for terminating null + * import descriptor */ + DWORD OriginalFirstThunk; /* RVA to original unbound + * IAT */ + } u; + DWORD TimeDateStamp; /* 0 if not bound, + * -1 if bound, and real date\time stamp + * in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT + * (new BIND) + * otherwise date/time stamp of DLL bound to + * (Old BIND) + */ + DWORD ForwarderChain; /* -1 if no forwarders */ + DWORD Name; + /* RVA to IAT (if bound this IAT has actual addresses) */ + DWORD FirstThunk; +} IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR; + +#define IMAGE_ORDINAL_FLAG32 0x80000000 +#define IMAGE_ORDINAL_FLAG64 0x8000000000000000UL +#define IMAGE_SNAP_BY_ORDINAL32(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG32) != 0) +#define IMAGE_SNAP_BY_ORDINAL64(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG64) != 0) +#define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) + +#ifdef CONFIG_X86_64 +#define IMAGE_ORDINAL_FLAG IMAGE_ORDINAL_FLAG64 +#define IMAGE_SNAP_BY_ORDINAL IMAGE_SNAP_BY_ORDINAL64 +#else +#define IMAGE_ORDINAL_FLAG IMAGE_ORDINAL_FLAG32 +#define IMAGE_SNAP_BY_ORDINAL IMAGE_SNAP_BY_ORDINAL32 +#endif + +typedef struct _IMAGE_BOUND_IMPORT_DESCRIPTOR +{ + DWORD TimeDateStamp; + WORD OffsetModuleName; + WORD NumberOfModuleForwarderRefs; +/* Array of zero or more IMAGE_BOUND_FORWARDER_REF follows */ +} IMAGE_BOUND_IMPORT_DESCRIPTOR, *PIMAGE_BOUND_IMPORT_DESCRIPTOR; + +typedef struct _IMAGE_BOUND_FORWARDER_REF +{ + DWORD TimeDateStamp; + WORD OffsetModuleName; + WORD Reserved; +} IMAGE_BOUND_FORWARDER_REF, *PIMAGE_BOUND_FORWARDER_REF; + +typedef struct _IMAGE_BASE_RELOCATION +{ + DWORD VirtualAddress; + DWORD SizeOfBlock; + WORD TypeOffset[0]; +} IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION; + +typedef struct _IMAGE_RELOCATION +{ + union { + DWORD VirtualAddress; + DWORD RelocCount; + } DUMMYUNIONNAME; + DWORD SymbolTableIndex; + WORD Type; +} IMAGE_RELOCATION, *PIMAGE_RELOCATION; + +#define IMAGE_SIZEOF_RELOCATION 10 + +/* generic relocation types */ +#define IMAGE_REL_BASED_ABSOLUTE 0 +#define IMAGE_REL_BASED_HIGH 1 +#define IMAGE_REL_BASED_LOW 2 +#define IMAGE_REL_BASED_HIGHLOW 3 +#define IMAGE_REL_BASED_HIGHADJ 4 +#define IMAGE_REL_BASED_MIPS_JMPADDR 5 +#define IMAGE_REL_BASED_SECTION 6 +#define IMAGE_REL_BASED_REL 7 +#define IMAGE_REL_BASED_MIPS_JMPADDR16 9 +#define IMAGE_REL_BASED_IA64_IMM64 9 /* yes, 9 too */ +#define IMAGE_REL_BASED_DIR64 10 +#define IMAGE_REL_BASED_HIGH3ADJ 11 + +/* I386 relocation types */ +#define IMAGE_REL_I386_ABSOLUTE 0 +#define IMAGE_REL_I386_DIR16 1 +#define IMAGE_REL_I386_REL16 2 +#define IMAGE_REL_I386_DIR32 6 +#define IMAGE_REL_I386_DIR32NB 7 +#define IMAGE_REL_I386_SEG12 9 +#define IMAGE_REL_I386_SECTION 10 +#define IMAGE_REL_I386_SECREL 11 +#define IMAGE_REL_I386_REL32 20 + +/* MIPS relocation types */ +#define IMAGE_REL_MIPS_ABSOLUTE 0x0000 +#define IMAGE_REL_MIPS_REFHALF 0x0001 +#define IMAGE_REL_MIPS_REFWORD 0x0002 +#define IMAGE_REL_MIPS_JMPADDR 0x0003 +#define IMAGE_REL_MIPS_REFHI 0x0004 +#define IMAGE_REL_MIPS_REFLO 0x0005 +#define IMAGE_REL_MIPS_GPREL 0x0006 +#define IMAGE_REL_MIPS_LITERAL 0x0007 +#define IMAGE_REL_MIPS_SECTION 0x000A +#define IMAGE_REL_MIPS_SECREL 0x000B +#define IMAGE_REL_MIPS_SECRELLO 0x000C +#define IMAGE_REL_MIPS_SECRELHI 0x000D +#define IMAGE_REL_MIPS_JMPADDR16 0x0010 +#define IMAGE_REL_MIPS_REFWORDNB 0x0022 +#define IMAGE_REL_MIPS_PAIR 0x0025 + +/* ALPHA relocation types */ +#define IMAGE_REL_ALPHA_ABSOLUTE 0x0000 +#define IMAGE_REL_ALPHA_REFLONG 0x0001 +#define IMAGE_REL_ALPHA_REFQUAD 0x0002 +#define IMAGE_REL_ALPHA_GPREL 0x0003 +#define IMAGE_REL_ALPHA_LITERAL 0x0004 +#define IMAGE_REL_ALPHA_LITUSE 0x0005 +#define IMAGE_REL_ALPHA_GPDISP 0x0006 +#define IMAGE_REL_ALPHA_BRADDR 0x0007 +#define IMAGE_REL_ALPHA_HINT 0x0008 +#define IMAGE_REL_ALPHA_INLINE_REFLONG 0x0009 +#define IMAGE_REL_ALPHA_REFHI 0x000A +#define IMAGE_REL_ALPHA_REFLO 0x000B +#define IMAGE_REL_ALPHA_PAIR 0x000C +#define IMAGE_REL_ALPHA_MATCH 0x000D +#define IMAGE_REL_ALPHA_SECTION 0x000E +#define IMAGE_REL_ALPHA_SECREL 0x000F +#define IMAGE_REL_ALPHA_REFLONGNB 0x0010 +#define IMAGE_REL_ALPHA_SECRELLO 0x0011 +#define IMAGE_REL_ALPHA_SECRELHI 0x0012 +#define IMAGE_REL_ALPHA_REFQ3 0x0013 +#define IMAGE_REL_ALPHA_REFQ2 0x0014 +#define IMAGE_REL_ALPHA_REFQ1 0x0015 +#define IMAGE_REL_ALPHA_GPRELLO 0x0016 +#define IMAGE_REL_ALPHA_GPRELHI 0x0017 + +/* PowerPC relocation types */ +#define IMAGE_REL_PPC_ABSOLUTE 0x0000 +#define IMAGE_REL_PPC_ADDR64 0x0001 +#define IMAGE_REL_PPC_ADDR 0x0002 +#define IMAGE_REL_PPC_ADDR24 0x0003 +#define IMAGE_REL_PPC_ADDR16 0x0004 +#define IMAGE_REL_PPC_ADDR14 0x0005 +#define IMAGE_REL_PPC_REL24 0x0006 +#define IMAGE_REL_PPC_REL14 0x0007 +#define IMAGE_REL_PPC_TOCREL16 0x0008 +#define IMAGE_REL_PPC_TOCREL14 0x0009 +#define IMAGE_REL_PPC_ADDR32NB 0x000A +#define IMAGE_REL_PPC_SECREL 0x000B +#define IMAGE_REL_PPC_SECTION 0x000C +#define IMAGE_REL_PPC_IFGLUE 0x000D +#define IMAGE_REL_PPC_IMGLUE 0x000E +#define IMAGE_REL_PPC_SECREL16 0x000F +#define IMAGE_REL_PPC_REFHI 0x0010 +#define IMAGE_REL_PPC_REFLO 0x0011 +#define IMAGE_REL_PPC_PAIR 0x0012 +#define IMAGE_REL_PPC_SECRELLO 0x0013 +#define IMAGE_REL_PPC_SECRELHI 0x0014 +#define IMAGE_REL_PPC_GPREL 0x0015 +#define IMAGE_REL_PPC_TYPEMASK 0x00FF +/* modifier bits */ +#define IMAGE_REL_PPC_NEG 0x0100 +#define IMAGE_REL_PPC_BRTAKEN 0x0200 +#define IMAGE_REL_PPC_BRNTAKEN 0x0400 +#define IMAGE_REL_PPC_TOCDEFN 0x0800 + +/* SH3 ? relocation type */ +#define IMAGE_REL_SH3_ABSOLUTE 0x0000 +#define IMAGE_REL_SH3_DIRECT16 0x0001 +#define IMAGE_REL_SH3_DIRECT 0x0002 +#define IMAGE_REL_SH3_DIRECT8 0x0003 +#define IMAGE_REL_SH3_DIRECT8_WORD 0x0004 +#define IMAGE_REL_SH3_DIRECT8_LONG 0x0005 +#define IMAGE_REL_SH3_DIRECT4 0x0006 +#define IMAGE_REL_SH3_DIRECT4_WORD 0x0007 +#define IMAGE_REL_SH3_DIRECT4_LONG 0x0008 +#define IMAGE_REL_SH3_PCREL8_WORD 0x0009 +#define IMAGE_REL_SH3_PCREL8_LONG 0x000A +#define IMAGE_REL_SH3_PCREL12_WORD 0x000B +#define IMAGE_REL_SH3_STARTOF_SECTION 0x000C +#define IMAGE_REL_SH3_SIZEOF_SECTION 0x000D +#define IMAGE_REL_SH3_SECTION 0x000E +#define IMAGE_REL_SH3_SECREL 0x000F +#define IMAGE_REL_SH3_DIRECT32_NB 0x0010 + +/* ARM (Archimedes?) relocation types */ +#define IMAGE_REL_ARM_ABSOLUTE 0x0000 +#define IMAGE_REL_ARM_ADDR 0x0001 +#define IMAGE_REL_ARM_ADDR32NB 0x0002 +#define IMAGE_REL_ARM_BRANCH24 0x0003 +#define IMAGE_REL_ARM_BRANCH11 0x0004 +#define IMAGE_REL_ARM_SECTION 0x000E +#define IMAGE_REL_ARM_SECREL 0x000F + +/* IA64 relocation types */ +#define IMAGE_REL_IA64_ABSOLUTE 0x0000 +#define IMAGE_REL_IA64_IMM14 0x0001 +#define IMAGE_REL_IA64_IMM22 0x0002 +#define IMAGE_REL_IA64_IMM64 0x0003 +#define IMAGE_REL_IA64_DIR 0x0004 +#define IMAGE_REL_IA64_DIR64 0x0005 +#define IMAGE_REL_IA64_PCREL21B 0x0006 +#define IMAGE_REL_IA64_PCREL21M 0x0007 +#define IMAGE_REL_IA64_PCREL21F 0x0008 +#define IMAGE_REL_IA64_GPREL22 0x0009 +#define IMAGE_REL_IA64_LTOFF22 0x000A +#define IMAGE_REL_IA64_SECTION 0x000B +#define IMAGE_REL_IA64_SECREL22 0x000C +#define IMAGE_REL_IA64_SECREL64I 0x000D +#define IMAGE_REL_IA64_SECREL 0x000E +#define IMAGE_REL_IA64_LTOFF64 0x000F +#define IMAGE_REL_IA64_DIR32NB 0x0010 +#define IMAGE_REL_IA64_RESERVED_11 0x0011 +#define IMAGE_REL_IA64_RESERVED_12 0x0012 +#define IMAGE_REL_IA64_RESERVED_13 0x0013 +#define IMAGE_REL_IA64_RESERVED_14 0x0014 +#define IMAGE_REL_IA64_RESERVED_15 0x0015 +#define IMAGE_REL_IA64_RESERVED_16 0x0016 +#define IMAGE_REL_IA64_ADDEND 0x001F + +/* archive format */ + +#define IMAGE_ARCHIVE_START_SIZE 8 +#define IMAGE_ARCHIVE_START "!\n" +#define IMAGE_ARCHIVE_END "`\n" +#define IMAGE_ARCHIVE_PAD "\n" +#define IMAGE_ARCHIVE_LINKER_MEMBER "/ " +#define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// " + +typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER +{ + BYTE Name[16]; + BYTE Date[12]; + BYTE UserID[6]; + BYTE GroupID[6]; + BYTE Mode[8]; + BYTE Size[10]; + BYTE EndHeader[2]; +} IMAGE_ARCHIVE_MEMBER_HEADER, *PIMAGE_ARCHIVE_MEMBER_HEADER; + +#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 + +/* + * Resource directory stuff + */ +typedef struct _IMAGE_RESOURCE_DIRECTORY { + DWORD Characteristics; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + WORD NumberOfNamedEntries; + WORD NumberOfIdEntries; + /* IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[]; */ +} IMAGE_RESOURCE_DIRECTORY,*PIMAGE_RESOURCE_DIRECTORY; + +#define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000 +#define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000 + +typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY { + union { + struct { +#ifdef BITFIELDS_BIGENDIAN + unsigned NameIsString:1; + unsigned NameOffset:31; +#else + unsigned NameOffset:31; + unsigned NameIsString:1; +#endif + } DUMMYSTRUCTNAME1; + DWORD Name; + struct { +#ifdef WORDS_BIGENDIAN + WORD __pad; + WORD Id; +#else + WORD Id; + WORD __pad; +#endif + } DUMMYSTRUCTNAME2; + } DUMMYUNIONNAME1; + union { + DWORD OffsetToData; + struct { +#ifdef BITFIELDS_BIGENDIAN + unsigned DataIsDirectory:1; + unsigned OffsetToDirectory:31; +#else + unsigned OffsetToDirectory:31; + unsigned DataIsDirectory:1; +#endif + } DUMMYSTRUCTNAME3; + } DUMMYUNIONNAME2; +} IMAGE_RESOURCE_DIRECTORY_ENTRY,*PIMAGE_RESOURCE_DIRECTORY_ENTRY; + + +typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING { + WORD Length; + CHAR NameString[ 1 ]; +} IMAGE_RESOURCE_DIRECTORY_STRING,*PIMAGE_RESOURCE_DIRECTORY_STRING; + --- linux-2.6.28.orig/ubuntu/ndiswrapper/wrapndis.h +++ linux-2.6.28/ubuntu/ndiswrapper/wrapndis.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#ifndef _WRAPNDIS_H_ +#define _WRAPNDIS_H_ + +#include "ndis.h" +#include "pnp.h" + +int wrapndis_init(void); +void wrapndis_exit(void); + +NDIS_STATUS mp_reset(struct ndis_device *wnd); + +NDIS_STATUS mp_request(enum ndis_request_type request, + struct ndis_device *wnd, ndis_oid oid, + void *buf, ULONG buflen, ULONG *written, ULONG *needed); + +static inline NDIS_STATUS mp_query_info(struct ndis_device *wnd, + ndis_oid oid, void *buf, ULONG buflen, + ULONG *written, ULONG *needed) +{ + return mp_request(NdisRequestQueryInformation, wnd, oid, + buf, buflen, written, needed); +} + +static inline NDIS_STATUS mp_set_info(struct ndis_device *wnd, + ndis_oid oid, void *buf, ULONG buflen, + ULONG *written, ULONG *needed) +{ + return mp_request(NdisRequestSetInformation, wnd, oid, + buf, buflen, written, needed); +} + +static inline NDIS_STATUS mp_query(struct ndis_device *wnd, ndis_oid oid, + void *buf, ULONG buflen) +{ + return mp_request(NdisRequestQueryInformation, wnd, oid, + buf, buflen, NULL, NULL); +} + +static inline NDIS_STATUS mp_query_int(struct ndis_device *wnd, + ndis_oid oid, ULONG *data) +{ + return mp_request(NdisRequestQueryInformation, wnd, oid, + data, sizeof(ULONG), NULL, NULL); +} + +static inline NDIS_STATUS mp_set(struct ndis_device *wnd, ndis_oid oid, + void *buf, ULONG buflen) +{ + return mp_request(NdisRequestSetInformation, wnd, oid, + buf, buflen, NULL, NULL); +} + +static inline NDIS_STATUS mp_set_int(struct ndis_device *wnd, + ndis_oid oid, ULONG data) +{ + return mp_request(NdisRequestSetInformation, wnd, oid, + &data, sizeof(ULONG), NULL, NULL); +} + +void free_tx_packet(struct ndis_device *wnd, struct ndis_packet *packet, + NDIS_STATUS status); +int init_ndis_driver(struct driver_object *drv_obj); +NDIS_STATUS ndis_reinit(struct ndis_device *wnd); + +void hangcheck_add(struct ndis_device *wnd); +void hangcheck_del(struct ndis_device *wnd); + +driver_dispatch_t winNdisDispatchPnp; +driver_dispatch_t winNdisDispatchPower; +driver_dispatch_t winNdisDispatchDeviceControl; + +struct iw_statistics *get_iw_stats(struct net_device *dev); + +#endif --- linux-2.6.28.orig/ubuntu/ndiswrapper/BOM +++ linux-2.6.28/ubuntu/ndiswrapper/BOM @@ -0,0 +1,2 @@ +Downloaded from: http://sourceforge.net/project/showfiles.php?group_id=93482 +Current Version: 1.53 --- linux-2.6.28.orig/ubuntu/ndiswrapper/ndis.c +++ linux-2.6.28/ubuntu/ndiswrapper/ndis.c @@ -0,0 +1,2988 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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. + * + */ + +#include "ndis.h" +#include "iw_ndis.h" +#include "wrapndis.h" +#include "pnp.h" +#include "loader.h" +#include +#include +#include "ndis_exports.h" + +#define MAX_ALLOCATED_NDIS_PACKETS TX_RING_SIZE +#define MAX_ALLOCATED_NDIS_BUFFERS TX_RING_SIZE + +static void ndis_worker(worker_param_t dummy); +static work_struct_t ndis_work; +static struct nt_list ndis_work_list; +static spinlock_t ndis_work_list_lock; + +workqueue_struct_t *ndis_wq; +static struct nt_thread *ndis_worker_thread; + +static void *ndis_get_routine_address(char *name); + +wstdcall void WIN_FUNC(NdisInitializeWrapper,4) + (void **driver_handle, struct driver_object *driver, + struct unicode_string *reg_path, void *unused) +{ + ENTER1("handle: %p, driver: %p", driver_handle, driver); + *driver_handle = driver; + EXIT1(return); +} + +wstdcall void WIN_FUNC(NdisTerminateWrapper,2) + (struct device_object *dev_obj, void *system_specific) +{ + EXIT1(return); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisMRegisterMiniport,3) + (struct driver_object *drv_obj, struct miniport *mp, UINT length) +{ + int min_length; + struct wrap_driver *wrap_driver; + struct ndis_driver *ndis_driver; + + min_length = ((char *)&mp->co_create_vc) - ((char *)mp); + + ENTER1("%p %p %d", drv_obj, mp, length); + + if (mp->major_version < 4) { + ERROR("Driver is using ndis version %d which is too old.", + mp->major_version); + EXIT1(return NDIS_STATUS_BAD_VERSION); + } + + if (length < min_length) { + ERROR("Characteristics length %d is too small", length); + EXIT1(return NDIS_STATUS_BAD_CHARACTERISTICS); + } + + TRACE1("%d.%d, %d, %u", mp->major_version, mp->minor_version, length, + (u32)sizeof(struct miniport)); + wrap_driver = IoGetDriverObjectExtension(drv_obj, + (void *)WRAP_DRIVER_CLIENT_ID); + if (!wrap_driver) { + ERROR("couldn't get wrap_driver"); + EXIT1(return NDIS_STATUS_RESOURCES); + } + if (IoAllocateDriverObjectExtension( + drv_obj, (void *)NDIS_DRIVER_CLIENT_ID, + sizeof(*ndis_driver), (void **)&ndis_driver) != + STATUS_SUCCESS) + EXIT1(return NDIS_STATUS_RESOURCES); + wrap_driver->ndis_driver = ndis_driver; + TRACE1("driver: %p", ndis_driver); + memcpy(&ndis_driver->mp, mp, min_t(int, sizeof(*mp), length)); + + DBG_BLOCK(2) { + int i; + void **func; + char *mp_funcs[] = { + "queryinfo", "reconfig", "reset", "send", "setinfo", + "tx_data", "return_packet", "send_packets", + "alloc_complete", "co_create_vc", "co_delete_vc", + "co_activate_vc", "co_deactivate_vc", + "co_send_packets", "co_request", "cancel_send_packets", + "pnp_event_notify", "shutdown", + }; + func = (void **)&ndis_driver->mp.queryinfo; + for (i = 0; i < (sizeof(mp_funcs) / sizeof(mp_funcs[0])); i++) + TRACE2("function '%s' is at %p", mp_funcs[i], func[i]); + } + EXIT1(return NDIS_STATUS_SUCCESS); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisMRegisterDevice,6) + (struct driver_object *drv_obj, struct unicode_string *dev_name, + struct unicode_string *link, void **funcs, + struct device_object **dev_obj, void **dev_obj_handle) +{ + NTSTATUS status; + struct device_object *tmp; + int i; + + ENTER1("%p, %p, %p", drv_obj, dev_name, link); + status = IoCreateDevice(drv_obj, 0, dev_name, FILE_DEVICE_NETWORK, 0, + FALSE, &tmp); + + if (status != STATUS_SUCCESS) + EXIT1(return NDIS_STATUS_RESOURCES); + if (link) + status = IoCreateSymbolicLink(link, dev_name); + if (status != STATUS_SUCCESS) { + IoDeleteDevice(tmp); + EXIT1(return NDIS_STATUS_RESOURCES); + } + + *dev_obj = tmp; + *dev_obj_handle = *dev_obj; + for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) + if (funcs[i] && i != IRP_MJ_PNP && i != IRP_MJ_POWER) { + drv_obj->major_func[i] = funcs[i]; + TRACE1("mj_fn for 0x%x is at %p", i, funcs[i]); + } + EXIT1(return NDIS_STATUS_SUCCESS); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisMDeregisterDevice,1) + (struct device_object *dev_obj) +{ + ENTER2("%p", dev_obj); + IoDeleteDevice(dev_obj); + return NDIS_STATUS_SUCCESS; +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisAllocateMemoryWithTag,3) + (void **dest, UINT length, ULONG tag) +{ + void *addr; + + assert_irql(_irql_ <= DISPATCH_LEVEL); + addr = ExAllocatePoolWithTag(NonPagedPool, length, tag); + TRACE4("%p", addr); + if (addr) { + *dest = addr; + EXIT4(return NDIS_STATUS_SUCCESS); + } else + EXIT4(return NDIS_STATUS_FAILURE); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisAllocateMemory,4) + (void **dest, UINT length, UINT flags, NDIS_PHY_ADDRESS highest_address) +{ + return NdisAllocateMemoryWithTag(dest, length, 0); +} + +/* length_tag is either length or tag, depending on if + * NdisAllocateMemory or NdisAllocateMemoryTag is used to allocate + * memory */ +wstdcall void WIN_FUNC(NdisFreeMemory,3) + (void *addr, UINT length_tag, UINT flags) +{ + TRACE4("%p", addr); + ExFreePool(addr); +} + +noregparm void WIN_FUNC(NdisWriteErrorLogEntry,12) + (struct driver_object *drv_obj, ULONG error, ULONG count, ...) +{ + va_list args; + int i; + ULONG code; + + va_start(args, count); + ERROR("log: %08X, count: %d, return_address: %p", + error, count, __builtin_return_address(0)); + for (i = 0; i < count; i++) { + code = va_arg(args, ULONG); + ERROR("code: 0x%x", code); + } + va_end(args); + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisOpenConfiguration,3) + (NDIS_STATUS *status, struct ndis_mp_block **conf_handle, + struct ndis_mp_block *handle) +{ + ENTER2("%p", conf_handle); + *conf_handle = handle; + *status = NDIS_STATUS_SUCCESS; + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisOpenProtocolConfiguration,3) + (NDIS_STATUS *status, void **confhandle, + struct unicode_string *section) +{ + ENTER2("%p", confhandle); + *status = NDIS_STATUS_SUCCESS; + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisOpenConfigurationKeyByName,4) + (NDIS_STATUS *status, void *handle, + struct unicode_string *key, void **subkeyhandle) +{ + struct ansi_string ansi; + ENTER2(""); + if (RtlUnicodeStringToAnsiString(&ansi, key, TRUE) == STATUS_SUCCESS) { + TRACE2("%s", ansi.buf); + RtlFreeAnsiString(&ansi); + } + *subkeyhandle = handle; + *status = NDIS_STATUS_SUCCESS; + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisOpenConfigurationKeyByIndex,5) + (NDIS_STATUS *status, void *handle, ULONG index, + struct unicode_string *key, void **subkeyhandle) +{ + ENTER2("%u", index); +// *subkeyhandle = handle; + *status = NDIS_STATUS_FAILURE; + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisCloseConfiguration,1) + (void *handle) +{ + /* instead of freeing all configuration parameters as we are + * supposed to do here, we free them when the device is + * removed */ + ENTER2("%p", handle); + return; +} + +wstdcall void WIN_FUNC(NdisOpenFile,5) + (NDIS_STATUS *status, struct wrap_bin_file **file, + UINT *filelength, struct unicode_string *filename, + NDIS_PHY_ADDRESS highest_address) +{ + struct ansi_string ansi; + struct wrap_bin_file *bin_file; + + ENTER2("%p, %d, %llx, %p", status, *filelength, highest_address, *file); + if (RtlUnicodeStringToAnsiString(&ansi, filename, TRUE) != + STATUS_SUCCESS) { + *status = NDIS_STATUS_RESOURCES; + EXIT2(return); + } + TRACE2("%s", ansi.buf); + bin_file = get_bin_file(ansi.buf); + if (bin_file) { + *file = bin_file; + *filelength = bin_file->size; + *status = NDIS_STATUS_SUCCESS; + } else + *status = NDIS_STATUS_FILE_NOT_FOUND; + + RtlFreeAnsiString(&ansi); + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisMapFile,3) + (NDIS_STATUS *status, void **mappedbuffer, struct wrap_bin_file *file) +{ + ENTER2("%p", file); + + if (!file) { + *status = NDIS_STATUS_ALREADY_MAPPED; + EXIT2(return); + } + + *status = NDIS_STATUS_SUCCESS; + *mappedbuffer = file->data; + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisUnmapFile,1) + (struct wrap_bin_file *file) +{ + ENTER2("%p", file); + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisCloseFile,1) + (struct wrap_bin_file *file) +{ + ENTER2("%p", file); + free_bin_file(file); + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisGetSystemUpTime,1) + (ULONG *ms) +{ + *ms = 1000 * jiffies / HZ; + EXIT5(return); +} + +wstdcall ULONG WIN_FUNC(NDIS_BUFFER_TO_SPAN_PAGES,1) + (ndis_buffer *buffer) +{ + ULONG n, length; + + if (buffer == NULL) + EXIT2(return 0); + if (MmGetMdlByteCount(buffer) == 0) + EXIT2(return 1); + + length = MmGetMdlByteCount(buffer); + n = SPAN_PAGES(MmGetMdlVirtualAddress(buffer), length); + TRACE4("%p, %p, %d, %d", buffer->startva, buffer->mappedsystemva, + length, n); + EXIT3(return n); +} + +wstdcall void WIN_FUNC(NdisGetBufferPhysicalArraySize,2) + (ndis_buffer *buffer, UINT *arraysize) +{ + ENTER3("%p", buffer); + *arraysize = NDIS_BUFFER_TO_SPAN_PAGES(buffer); + EXIT3(return); +} + +static struct ndis_configuration_parameter * +ndis_encode_setting(struct wrap_device_setting *setting, + enum ndis_parameter_type type) +{ + struct ansi_string ansi; + struct ndis_configuration_parameter *param; + + param = setting->encoded; + if (param) { + if (param->type == type) + EXIT2(return param); + if (param->type == NdisParameterString) + RtlFreeUnicodeString(¶m->data.string); + setting->encoded = NULL; + } else + param = ExAllocatePoolWithTag(NonPagedPool, sizeof(*param), 0); + if (!param) { + ERROR("couldn't allocate memory"); + return NULL; + } + switch(type) { + case NdisParameterInteger: + param->data.integer = simple_strtol(setting->value, NULL, 0); + TRACE2("0x%x", (ULONG)param->data.integer); + break; + case NdisParameterHexInteger: + param->data.integer = simple_strtol(setting->value, NULL, 16); + TRACE2("0x%x", (ULONG)param->data.integer); + break; + case NdisParameterString: + RtlInitAnsiString(&ansi, setting->value); + TRACE2("'%s'", ansi.buf); + if (RtlAnsiStringToUnicodeString(¶m->data.string, + &ansi, TRUE)) { + ExFreePool(param); + EXIT2(return NULL); + } + break; + case NdisParameterBinary: + param->data.integer = simple_strtol(setting->value, NULL, 2); + TRACE2("0x%x", (ULONG)param->data.integer); + break; + default: + ERROR("unknown type: %d", type); + ExFreePool(param); + return NULL; + } + param->type = type; + setting->encoded = param; + EXIT2(return param); +} + +static int ndis_decode_setting(struct wrap_device_setting *setting, + struct ndis_configuration_parameter *param) +{ + struct ansi_string ansi; + struct ndis_configuration_parameter *prev; + + ENTER2("%p, %p", setting, param); + prev = setting->encoded; + if (prev && prev->type == NdisParameterString) { + RtlFreeUnicodeString(&prev->data.string); + setting->encoded = NULL; + } + switch(param->type) { + case NdisParameterInteger: + snprintf(setting->value, sizeof(u32), "%u", + param->data.integer); + setting->value[sizeof(ULONG)] = 0; + break; + case NdisParameterHexInteger: + snprintf(setting->value, sizeof(u32), "%x", + param->data.integer); + setting->value[sizeof(ULONG)] = 0; + break; + case NdisParameterString: + ansi.buf = setting->value; + ansi.max_length = MAX_SETTING_VALUE_LEN; + if ((RtlUnicodeStringToAnsiString(&ansi, ¶m->data.string, + FALSE) != STATUS_SUCCESS) + || ansi.length >= MAX_SETTING_VALUE_LEN) { + EXIT1(return -1); + } + if (ansi.length == ansi.max_length) + ansi.length--; + setting->value[ansi.length] = 0; + break; + case NdisParameterBinary: + snprintf(setting->value, sizeof(u32), "%u", + param->data.integer); + setting->value[sizeof(ULONG)] = 0; + break; + default: + TRACE2("unknown setting type: %d", param->type); + return -1; + } + TRACE2("setting changed %s='%s', %d", setting->name, setting->value, + ansi.length); + return 0; +} + +static int read_setting(struct nt_list *setting_list, char *keyname, int length, + struct ndis_configuration_parameter **param, + enum ndis_parameter_type type) +{ + struct wrap_device_setting *setting; + if (down_interruptible(&loader_mutex)) + WARNING("couldn't obtain loader_mutex"); + nt_list_for_each_entry(setting, setting_list, list) { + if (strnicmp(keyname, setting->name, length) == 0) { + TRACE2("setting %s='%s'", keyname, setting->value); + up(&loader_mutex); + *param = ndis_encode_setting(setting, type); + if (*param) + EXIT2(return 0); + else + EXIT2(return -1); + } + } + up(&loader_mutex); + EXIT2(return -1); +} + +wstdcall void WIN_FUNC(NdisReadConfiguration,5) + (NDIS_STATUS *status, struct ndis_configuration_parameter **param, + struct ndis_mp_block *nmb, struct unicode_string *key, + enum ndis_parameter_type type) +{ + struct ansi_string ansi; + int ret; + + ENTER2("nmb: %p", nmb); + ret = RtlUnicodeStringToAnsiString(&ansi, key, TRUE); + if (ret != STATUS_SUCCESS || ansi.buf == NULL) { + *param = NULL; + *status = NDIS_STATUS_FAILURE; + RtlFreeAnsiString(&ansi); + EXIT2(return); + } + TRACE2("%d, %s", type, ansi.buf); + + if (read_setting(&nmb->wnd->wd->settings, ansi.buf, + ansi.length, param, type) == 0 || + read_setting(&nmb->wnd->wd->driver->settings, ansi.buf, + ansi.length, param, type) == 0) + *status = NDIS_STATUS_SUCCESS; + else { + TRACE2("setting %s not found (type:%d)", ansi.buf, type); + *status = NDIS_STATUS_FAILURE; + } + RtlFreeAnsiString(&ansi); + EXIT2(return); + +} + +wstdcall void WIN_FUNC(NdisWriteConfiguration,4) + (NDIS_STATUS *status, struct ndis_mp_block *nmb, + struct unicode_string *key, struct ndis_configuration_parameter *param) +{ + struct ansi_string ansi; + char *keyname; + struct wrap_device_setting *setting; + + ENTER2("nmb: %p", nmb); + if (RtlUnicodeStringToAnsiString(&ansi, key, TRUE)) { + *status = NDIS_STATUS_FAILURE; + EXIT2(return); + } + keyname = ansi.buf; + TRACE2("%s", keyname); + + if (down_interruptible(&loader_mutex)) + WARNING("couldn't obtain loader_mutex"); + nt_list_for_each_entry(setting, &nmb->wnd->wd->settings, list) { + if (strnicmp(keyname, setting->name, ansi.length) == 0) { + up(&loader_mutex); + if (ndis_decode_setting(setting, param)) + *status = NDIS_STATUS_FAILURE; + else + *status = NDIS_STATUS_SUCCESS; + RtlFreeAnsiString(&ansi); + EXIT2(return); + } + } + up(&loader_mutex); + setting = kzalloc(sizeof(*setting), GFP_KERNEL); + if (setting) { + if (ansi.length == ansi.max_length) + ansi.length--; + memcpy(setting->name, keyname, ansi.length); + setting->name[ansi.length] = 0; + if (ndis_decode_setting(setting, param)) + *status = NDIS_STATUS_FAILURE; + else { + *status = NDIS_STATUS_SUCCESS; + if (down_interruptible(&loader_mutex)) + WARNING("couldn't obtain loader_mutex"); + InsertTailList(&nmb->wnd->wd->settings, &setting->list); + up(&loader_mutex); + } + } else + *status = NDIS_STATUS_RESOURCES; + + RtlFreeAnsiString(&ansi); + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisReadNetworkAddress,4) + (NDIS_STATUS *status, void **addr, UINT *len, + struct ndis_mp_block *nmb) +{ + struct ndis_device *wnd = nmb->wnd; + struct ndis_configuration_parameter *param; + struct unicode_string key; + struct ansi_string ansi; + typeof(wnd->mac) mac; + int i, ret; + + ENTER2("%p", nmb); + RtlInitAnsiString(&ansi, "NetworkAddress"); + *status = NDIS_STATUS_FAILURE; + if (RtlAnsiStringToUnicodeString(&key, &ansi, TRUE) != STATUS_SUCCESS) + EXIT1(return); + + NdisReadConfiguration(&ret, ¶m, nmb, &key, NdisParameterString); + RtlFreeUnicodeString(&key); + if (ret != NDIS_STATUS_SUCCESS) + EXIT1(return); + ret = RtlUnicodeStringToAnsiString(&ansi, ¶m->data.string, TRUE); + if (ret != STATUS_SUCCESS) + EXIT1(return); + + i = 0; + if (ansi.length >= 2 * sizeof(mac)) { + for (i = 0; i < sizeof(mac); i++) { + char c[3]; + int x; + c[0] = ansi.buf[i*2]; + c[1] = ansi.buf[i*2+1]; + c[2] = 0; + ret = sscanf(c, "%x", &x); + if (ret != 1) + break; + mac[i] = x; + } + } + TRACE2("%s, %d, " MACSTR, ansi.buf, i, MAC2STR(mac)); + RtlFreeAnsiString(&ansi); + if (i == sizeof(mac)) { + memcpy(wnd->mac, mac, sizeof(wnd->mac)); + *len = sizeof(mac); + *addr = wnd->mac; + *status = NDIS_STATUS_SUCCESS; + } + EXIT1(return); +} + +wstdcall void WIN_FUNC(NdisInitializeString,2) + (struct unicode_string *dest, UCHAR *src) +{ + struct ansi_string ansi; + + ENTER2(""); + if (src == NULL) { + dest->length = dest->max_length = 0; + dest->buf = NULL; + } else { + RtlInitAnsiString(&ansi, src); + /* the string is freed with NdisFreeMemory */ + RtlAnsiStringToUnicodeString(dest, &ansi, TRUE); + } + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisInitAnsiString,2) + (struct ansi_string *dst, CHAR *src) +{ + RtlInitAnsiString(dst, src); + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisInitUnicodeString,2) + (struct unicode_string *dest, const wchar_t *src) +{ + RtlInitUnicodeString(dest, src); + return; +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisAnsiStringToUnicodeString,2) + (struct unicode_string *dst, struct ansi_string *src) +{ + ENTER2(""); + if (dst == NULL || src == NULL) + EXIT2(return NDIS_STATUS_FAILURE); + if (RtlAnsiStringToUnicodeString(dst, src, FALSE) == STATUS_SUCCESS) + return NDIS_STATUS_SUCCESS; + else + return NDIS_STATUS_FAILURE; +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisUnicodeStringToAnsiString,2) + (struct ansi_string *dst, struct unicode_string *src) +{ + ENTER2(""); + if (dst == NULL || src == NULL) + EXIT2(return NDIS_STATUS_FAILURE); + if (RtlUnicodeStringToAnsiString(dst, src, FALSE) == STATUS_SUCCESS) + return NDIS_STATUS_SUCCESS; + else + return NDIS_STATUS_FAILURE; +} + +wstdcall NTSTATUS WIN_FUNC(NdisUpcaseUnicodeString,2) + (struct unicode_string *dst, struct unicode_string *src) +{ + EXIT2(return RtlUpcaseUnicodeString(dst, src, FALSE)); +} + +wstdcall void WIN_FUNC(NdisMSetAttributesEx,5) + (struct ndis_mp_block *nmb, void *mp_ctx, + UINT hangcheck_interval, UINT attributes, ULONG adaptertype) +{ + struct ndis_device *wnd; + + ENTER1("%p, %p, %d, %08x, %d", nmb, mp_ctx, hangcheck_interval, + attributes, adaptertype); + wnd = nmb->wnd; + nmb->mp_ctx = mp_ctx; + wnd->attributes = attributes; + + if ((attributes & NDIS_ATTRIBUTE_BUS_MASTER) && + wrap_is_pci_bus(wnd->wd->dev_bus)) + pci_set_master(wnd->wd->pci.pdev); + + if (hangcheck_interval > 0) + wnd->hangcheck_interval = 2 * hangcheck_interval * HZ; + else + wnd->hangcheck_interval = 2 * HZ; + + EXIT1(return); +} + +wstdcall ULONG WIN_FUNC(NdisReadPciSlotInformation,5) + (struct ndis_mp_block *nmb, ULONG slot, + ULONG offset, char *buf, ULONG len) +{ + struct wrap_device *wd = nmb->wnd->wd; + ULONG i; + for (i = 0; i < len; i++) + if (pci_read_config_byte(wd->pci.pdev, offset + i, &buf[i]) != + PCIBIOS_SUCCESSFUL) + break; + DBG_BLOCK(2) { + if (i != len) + WARNING("%u, %u", i, len); + } + return i; +} + +wstdcall ULONG WIN_FUNC(NdisImmediateReadPciSlotInformation,5) + (struct ndis_mp_block *nmb, ULONG slot, + ULONG offset, char *buf, ULONG len) +{ + return NdisReadPciSlotInformation(nmb, slot, offset, buf, len); +} + +wstdcall ULONG WIN_FUNC(NdisWritePciSlotInformation,5) + (struct ndis_mp_block *nmb, ULONG slot, + ULONG offset, char *buf, ULONG len) +{ + struct wrap_device *wd = nmb->wnd->wd; + ULONG i; + for (i = 0; i < len; i++) + if (pci_write_config_byte(wd->pci.pdev, offset + i, buf[i]) != + PCIBIOS_SUCCESSFUL) + break; + DBG_BLOCK(2) { + if (i != len) + WARNING("%u, %u", i, len); + } + return i; +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisMRegisterIoPortRange,4) + (void **virt, struct ndis_mp_block *nmb, UINT start, UINT len) +{ + ENTER3("%08x %08x", start, len); + *virt = (void *)(ULONG_PTR)start; + return NDIS_STATUS_SUCCESS; +} + +wstdcall void WIN_FUNC(NdisMDeregisterIoPortRange,4) + (struct ndis_mp_block *nmb, UINT start, UINT len, void* virt) +{ + ENTER1("%08x %08x", start, len); +} + +wstdcall void WIN_FUNC(NdisReadPortUchar,3) + (struct ndis_mp_block *nmb, ULONG port, char *data) +{ + *data = inb(port); +} + +wstdcall void WIN_FUNC(NdisImmediateReadPortUchar,3) + (struct ndis_mp_block *nmb, ULONG port, char *data) +{ + *data = inb(port); +} + +wstdcall void WIN_FUNC(NdisWritePortUchar,3) + (struct ndis_mp_block *nmb, ULONG port, char data) +{ + outb(data, port); +} + +wstdcall void WIN_FUNC(NdisImmediateWritePortUchar,3) + (struct ndis_mp_block *nmb, ULONG port, char data) +{ + outb(data, port); +} + +wstdcall void WIN_FUNC(NdisMQueryAdapterResources,4) + (NDIS_STATUS *status, struct ndis_mp_block *nmb, + NDIS_RESOURCE_LIST *resource_list, UINT *size) +{ + struct ndis_device *wnd = nmb->wnd; + NDIS_RESOURCE_LIST *list; + UINT resource_length; + + list = &wnd->wd->resource_list->list->partial_resource_list; + resource_length = sizeof(struct cm_partial_resource_list) + + sizeof(struct cm_partial_resource_descriptor) * + (list->count - 1); + TRACE2("%p, %p,%d (%d), %p %d %d", wnd, resource_list, *size, + resource_length, &list->partial_descriptors[list->count-1], + list->partial_descriptors[list->count-1].u.interrupt.level, + list->partial_descriptors[list->count-1].u.interrupt.vector); + if (*size < sizeof(*list)) { + *size = resource_length; + *status = NDIS_STATUS_BUFFER_TOO_SHORT; + } else { + ULONG count; + if (*size >= resource_length) { + *size = resource_length; + count = list->count; + } else { + UINT n = sizeof(*list); + count = 1; + while (count++ < list->count && n < *size) + n += sizeof(list->partial_descriptors); + *size = n; + } + memcpy(resource_list, list, *size); + resource_list->count = count; + *status = NDIS_STATUS_SUCCESS; + } + EXIT2(return); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisMPciAssignResources,3) + (struct ndis_mp_block *nmb, ULONG slot_number, + NDIS_RESOURCE_LIST **resources) +{ + struct ndis_device *wnd = nmb->wnd; + + ENTER2("%p, %p", wnd, wnd->wd->resource_list); + *resources = &wnd->wd->resource_list->list->partial_resource_list; + EXIT2(return NDIS_STATUS_SUCCESS); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisMMapIoSpace,4) + (void __iomem **virt, struct ndis_mp_block *nmb, + NDIS_PHY_ADDRESS phy_addr, UINT len) +{ + struct ndis_device *wnd = nmb->wnd; + + ENTER2("%Lx, %d", phy_addr, len); + *virt = MmMapIoSpace(phy_addr, len, MmCached); + if (*virt == NULL) { + ERROR("ioremap failed"); + EXIT2(return NDIS_STATUS_FAILURE); + } + wnd->mem_start = phy_addr; + wnd->mem_end = phy_addr + len; + TRACE2("%p", *virt); + EXIT2(return NDIS_STATUS_SUCCESS); +} + +wstdcall void WIN_FUNC(NdisMUnmapIoSpace,3) + (struct ndis_mp_block *nmb, void __iomem *virt, UINT len) +{ + ENTER2("%p, %d", virt, len); + MmUnmapIoSpace(virt, len); + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisAllocateSpinLock,1) + (struct ndis_spinlock *lock) +{ + TRACE4("lock %p, %p", lock, &lock->klock); + KeInitializeSpinLock(&lock->klock); + lock->irql = PASSIVE_LEVEL; + return; +} + +wstdcall void WIN_FUNC(NdisFreeSpinLock,1) + (struct ndis_spinlock *lock) +{ + TRACE4("lock %p, %p", lock, &lock->klock); + return; +} + +wstdcall void WIN_FUNC(NdisAcquireSpinLock,1) + (struct ndis_spinlock *lock) +{ + ENTER6("lock %p, %p", lock, &lock->klock); +// assert_irql(_irql_ <= DISPATCH_LEVEL); + lock->irql = nt_spin_lock_irql(&lock->klock, DISPATCH_LEVEL); + return; +} + +wstdcall void WIN_FUNC(NdisReleaseSpinLock,1) + (struct ndis_spinlock *lock) +{ + ENTER6("lock %p, %p", lock, &lock->klock); +// assert_irql(_irql_ == DISPATCH_LEVEL); + nt_spin_unlock_irql(&lock->klock, lock->irql); + return; +} + +wstdcall void WIN_FUNC(NdisDprAcquireSpinLock,1) + (struct ndis_spinlock *lock) +{ + ENTER6("lock %p", &lock->klock); +// assert_irql(_irql_ == DISPATCH_LEVEL); + nt_spin_lock(&lock->klock); + return; +} + +wstdcall void WIN_FUNC(NdisDprReleaseSpinLock,1) + (struct ndis_spinlock *lock) +{ + ENTER6("lock %p", &lock->klock); +// assert_irql(_irql_ == DISPATCH_LEVEL); + nt_spin_unlock(&lock->klock); + return; +} + +wstdcall void WIN_FUNC(NdisInitializeReadWriteLock,1) + (struct ndis_rw_lock *rw_lock) +{ + ENTER3("%p", rw_lock); + memset(rw_lock, 0, sizeof(*rw_lock)); + KeInitializeSpinLock(&rw_lock->klock); + return; +} + +/* read/write locks are implemented in a rather simplisitic way - we + * should probably use Linux's rw_lock implementation */ + +wstdcall void WIN_FUNC(NdisAcquireReadWriteLock,3) + (struct ndis_rw_lock *rw_lock, BOOLEAN write, + struct lock_state *lock_state) +{ + if (write) { + while (1) { + if (cmpxchg(&rw_lock->count, 0, -1) == 0) + return; + while (rw_lock->count) + cpu_relax(); + } + return; + } + while (1) { + typeof(rw_lock->count) count; + while ((count = rw_lock->count) < 0) + cpu_relax(); + if (cmpxchg(&rw_lock->count, count, count + 1) == count) + return; + } +} + +wstdcall void WIN_FUNC(NdisReleaseReadWriteLock,2) + (struct ndis_rw_lock *rw_lock, struct lock_state *lock_state) +{ + if (rw_lock->count > 0) + pre_atomic_add(rw_lock->count, -1); + else if (rw_lock->count == -1) + rw_lock->count = 0; + else + WARNING("invalid state: %d", rw_lock->count); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisMAllocateMapRegisters,5) + (struct ndis_mp_block *nmb, UINT dmachan, + NDIS_DMA_SIZE dmasize, ULONG basemap, ULONG max_buf_size) +{ + struct ndis_device *wnd = nmb->wnd; + + ENTER2("%p, %d %d %d %d", wnd, dmachan, dmasize, basemap, max_buf_size); + if (wnd->dma_map_count > 0) { + WARNING("%s: map registers already allocated: %u", + wnd->net_dev->name, wnd->dma_map_count); + EXIT2(return NDIS_STATUS_RESOURCES); + } + if (dmasize == NDIS_DMA_24BITS) { + if (pci_set_dma_mask(wnd->wd->pci.pdev, DMA_24BIT_MASK) || + pci_set_consistent_dma_mask(wnd->wd->pci.pdev, + DMA_24BIT_MASK)) + WARNING("setting dma mask failed"); + } else if (dmasize == NDIS_DMA_32BITS) { + /* consistent dma is in low 32-bits by default */ + if (pci_set_dma_mask(wnd->wd->pci.pdev, DMA_32BIT_MASK)) + WARNING("setting dma mask failed"); +#ifdef CONFIG_X86_64 + } else if (dmasize == NDIS_DMA_64BITS) { + if (pci_set_dma_mask(wnd->wd->pci.pdev, DMA_64BIT_MASK) || + pci_set_consistent_dma_mask(wnd->wd->pci.pdev, + DMA_64BIT_MASK)) + WARNING("setting dma mask failed"); + else + wnd->net_dev->features |= NETIF_F_HIGHDMA; +#endif + } + /* since memory for buffer is allocated with kmalloc, buffer + * is physically contiguous, so entire map will fit in one + * register */ + if (basemap > 64) { + WARNING("Windows driver %s requesting too many (%u) " + "map registers", wnd->wd->driver->name, basemap); + /* As per NDIS, NDIS_STATUS_RESOURCES should be + * returned, but with that Atheros PCI driver fails - + * for now tolerate it */ +// EXIT2(return NDIS_STATUS_RESOURCES); + } + + wnd->dma_map_addr = kmalloc(basemap * sizeof(*(wnd->dma_map_addr)), + GFP_KERNEL); + if (!wnd->dma_map_addr) + EXIT2(return NDIS_STATUS_RESOURCES); + memset(wnd->dma_map_addr, 0, basemap * sizeof(*(wnd->dma_map_addr))); + wnd->dma_map_count = basemap; + TRACE2("%u", wnd->dma_map_count); + EXIT2(return NDIS_STATUS_SUCCESS); +} + +wstdcall void WIN_FUNC(NdisMFreeMapRegisters,1) + (struct ndis_mp_block *nmb) +{ + struct ndis_device *wnd = nmb->wnd; + int i; + + ENTER2("wnd: %p", wnd); + if (wnd->dma_map_addr) { + for (i = 0; i < wnd->dma_map_count; i++) { + if (wnd->dma_map_addr[i]) + WARNING("%s: dma addr %p not freed by " + "Windows driver", wnd->net_dev->name, + (void *)wnd->dma_map_addr[i]); + } + kfree(wnd->dma_map_addr); + wnd->dma_map_addr = NULL; + } else + WARNING("map registers already freed?"); + wnd->dma_map_count = 0; + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisMStartBufferPhysicalMapping,6) + (struct ndis_mp_block *nmb, ndis_buffer *buf, + ULONG index, BOOLEAN write_to_dev, + struct ndis_phy_addr_unit *phy_addr_array, UINT *array_size) +{ + struct ndis_device *wnd = nmb->wnd; + + ENTER3("%p, %p, %u, %u", wnd, buf, index, wnd->dma_map_count); + if (unlikely(wnd->sg_dma_size || !write_to_dev || + index >= wnd->dma_map_count)) { + WARNING("invalid request: %d, %d, %d, %d", wnd->sg_dma_size, + write_to_dev, index, wnd->dma_map_count); + phy_addr_array[0].phy_addr = 0; + phy_addr_array[0].length = 0; + *array_size = 0; + return; + } + if (wnd->dma_map_addr[index]) { + TRACE2("buffer %p at %d is already mapped: %lx", buf, index, + (unsigned long)wnd->dma_map_addr[index]); +// *array_size = 1; + return; + } + TRACE3("%p, %p, %u", buf, MmGetSystemAddressForMdl(buf), + MmGetMdlByteCount(buf)); + DBG_BLOCK(4) { + dump_bytes(__FUNCTION__, MmGetSystemAddressForMdl(buf), + MmGetMdlByteCount(buf)); + } + wnd->dma_map_addr[index] = + PCI_DMA_MAP_SINGLE(wnd->wd->pci.pdev, + MmGetSystemAddressForMdl(buf), + MmGetMdlByteCount(buf), PCI_DMA_TODEVICE); + phy_addr_array[0].phy_addr = wnd->dma_map_addr[index]; + phy_addr_array[0].length = MmGetMdlByteCount(buf); + TRACE4("%Lx, %d, %d", phy_addr_array[0].phy_addr, + phy_addr_array[0].length, index); + *array_size = 1; +} + +wstdcall void WIN_FUNC(NdisMCompleteBufferPhysicalMapping,3) + (struct ndis_mp_block *nmb, ndis_buffer *buf, ULONG index) +{ + struct ndis_device *wnd = nmb->wnd; + + ENTER3("%p, %p %u (%u)", wnd, buf, index, wnd->dma_map_count); + + if (unlikely(wnd->sg_dma_size)) + WARNING("buffer %p may have been unmapped already", buf); + if (index >= wnd->dma_map_count) { + ERROR("invalid map register (%u >= %u)", + index, wnd->dma_map_count); + return; + } + TRACE4("%lx", (unsigned long)wnd->dma_map_addr[index]); + if (wnd->dma_map_addr[index]) { + PCI_DMA_UNMAP_SINGLE(wnd->wd->pci.pdev, wnd->dma_map_addr[index], + MmGetMdlByteCount(buf), PCI_DMA_TODEVICE); + wnd->dma_map_addr[index] = 0; + } else + WARNING("map registers at %u not used", index); +} + +wstdcall void WIN_FUNC(NdisMAllocateSharedMemory,5) + (struct ndis_mp_block *nmb, ULONG size, + BOOLEAN cached, void **virt, NDIS_PHY_ADDRESS *phys) +{ + dma_addr_t dma_addr; + struct wrap_device *wd = nmb->wnd->wd; + + ENTER3("size: %u, cached: %d", size, cached); + *virt = PCI_DMA_ALLOC_COHERENT(wd->pci.pdev, size, &dma_addr); + if (*virt) + *phys = dma_addr; + else + WARNING("couldn't allocate %d bytes of %scached DMA memory", + size, cached ? "" : "un-"); + EXIT3(return); +} + +wstdcall void WIN_FUNC(NdisMFreeSharedMemory,5) + (struct ndis_mp_block *nmb, ULONG size, BOOLEAN cached, + void *virt, NDIS_PHY_ADDRESS addr) +{ + struct wrap_device *wd = nmb->wnd->wd; + ENTER3("%p, %Lx, %u", virt, addr, size); + PCI_DMA_FREE_COHERENT(wd->pci.pdev, size, virt, addr); + EXIT3(return); +} + +wstdcall void alloc_shared_memory_async(void *arg1, void *arg2) +{ + struct ndis_device *wnd; + struct alloc_shared_mem *alloc_shared_mem; + struct miniport *mp; + void *virt; + NDIS_PHY_ADDRESS phys; + KIRQL irql; + + wnd = arg1; + alloc_shared_mem = arg2; + mp = &wnd->wd->driver->ndis_driver->mp; + NdisMAllocateSharedMemory(wnd->nmb, alloc_shared_mem->size, + alloc_shared_mem->cached, &virt, &phys); + irql = serialize_lock_irql(wnd); + assert_irql(_irql_ == DISPATCH_LEVEL); + LIN2WIN5(mp->alloc_complete, wnd->nmb, virt, + &phys, alloc_shared_mem->size, alloc_shared_mem->ctx); + serialize_unlock_irql(wnd, irql); + kfree(alloc_shared_mem); +} +WIN_FUNC_DECL(alloc_shared_memory_async,2) + +wstdcall NDIS_STATUS WIN_FUNC(NdisMAllocateSharedMemoryAsync,4) + (struct ndis_mp_block *nmb, ULONG size, BOOLEAN cached, void *ctx) +{ + struct ndis_device *wnd = nmb->wnd; + struct alloc_shared_mem *alloc_shared_mem; + + ENTER3("wnd: %p", wnd); + alloc_shared_mem = kmalloc(sizeof(*alloc_shared_mem), irql_gfp()); + if (!alloc_shared_mem) { + WARNING("couldn't allocate memory"); + return NDIS_STATUS_FAILURE; + } + + alloc_shared_mem->size = size; + alloc_shared_mem->cached = cached; + alloc_shared_mem->ctx = ctx; + if (schedule_ntos_work_item(WIN_FUNC_PTR(alloc_shared_memory_async,2), + wnd, alloc_shared_mem)) + EXIT3(return NDIS_STATUS_FAILURE); + EXIT3(return NDIS_STATUS_PENDING); +} + +/* Some drivers allocate NDIS_BUFFER (aka MDL) very often; instead of + * allocating and freeing with kernel functions, we chain them into + * ndis_buffer_pool. When an MDL is freed, it is added to the list of + * free MDLs. When allocated, we first check if there is one in free + * list and if so just return it; otherwise, we allocate a new one and + * return that. This reduces memory fragmentation. Windows DDK says + * that the driver itself shouldn't check what is returned in + * pool_handle, presumably because buffer pools are not used in + * XP. However, as long as driver follows rest of the semantics - that + * it should indicate maximum number of MDLs used with num_descr and + * pass the same pool_handle in other buffer functions, this should + * work. Sadly, though, NdisFreeBuffer doesn't pass the pool_handle, + * so we use 'process' field of MDL to store pool_handle. */ + +wstdcall void WIN_FUNC(NdisAllocateBufferPool,3) + (NDIS_STATUS *status, struct ndis_buffer_pool **pool_handle, + UINT num_descr) +{ + struct ndis_buffer_pool *pool; + + ENTER1("buffers: %d", num_descr); + pool = kmalloc(sizeof(*pool), irql_gfp()); + if (!pool) { + *status = NDIS_STATUS_RESOURCES; + EXIT3(return); + } + spin_lock_init(&pool->lock); + pool->max_descr = num_descr; + pool->num_allocated_descr = 0; + pool->free_descr = NULL; + *pool_handle = pool; + *status = NDIS_STATUS_SUCCESS; + TRACE1("pool: %p, num_descr: %d", pool, num_descr); + EXIT1(return); +} + +wstdcall void WIN_FUNC(NdisAllocateBuffer,5) + (NDIS_STATUS *status, ndis_buffer **buffer, + struct ndis_buffer_pool *pool, void *virt, UINT length) +{ + ndis_buffer *descr; + + ENTER4("pool: %p (%d)", pool, pool->num_allocated_descr); + /* NDIS drivers should call this at DISPATCH_LEVEL, but + * alloc_tx_packet calls at SOFT_IRQL */ + assert_irql(_irql_ <= SOFT_LEVEL); + if (!pool) { + *status = NDIS_STATUS_FAILURE; + *buffer = NULL; + EXIT4(return); + } + spin_lock_bh(&pool->lock); + if ((descr = pool->free_descr)) + pool->free_descr = descr->next; + spin_unlock_bh(&pool->lock); + if (descr) { + typeof(descr->flags) flags; + flags = descr->flags; + memset(descr, 0, sizeof(*descr)); + MmInitializeMdl(descr, virt, length); + if (flags & MDL_CACHE_ALLOCATED) + descr->flags |= MDL_CACHE_ALLOCATED; + } else { + if (pool->num_allocated_descr > pool->max_descr) { + TRACE2("pool %p is full: %d(%d)", pool, + pool->num_allocated_descr, pool->max_descr); +#ifndef ALLOW_POOL_OVERFLOW + *status = NDIS_STATUS_FAILURE; + *buffer = NULL; + return; +#endif + } + descr = allocate_init_mdl(virt, length); + if (!descr) { + WARNING("couldn't allocate buffer"); + *status = NDIS_STATUS_FAILURE; + *buffer = NULL; + EXIT4(return); + } + TRACE4("buffer %p for %p, %d", descr, virt, length); + atomic_inc_var(pool->num_allocated_descr); + } + /* TODO: make sure this mdl can map given buffer */ + MmBuildMdlForNonPagedPool(descr); +// descr->flags |= MDL_ALLOCATED_FIXED_SIZE | +// MDL_MAPPED_TO_SYSTEM_VA | MDL_PAGES_LOCKED; + descr->pool = pool; + *buffer = descr; + *status = NDIS_STATUS_SUCCESS; + TRACE4("buffer: %p", descr); + EXIT4(return); +} + +wstdcall void WIN_FUNC(NdisFreeBuffer,1) + (ndis_buffer *buffer) +{ + struct ndis_buffer_pool *pool; + + ENTER4("%p", buffer); + if (!buffer || !buffer->pool) { + ERROR("invalid buffer"); + EXIT4(return); + } + pool = buffer->pool; + if (pool->num_allocated_descr > MAX_ALLOCATED_NDIS_BUFFERS) { + /* NB NB NB: set mdl's 'pool' field to NULL before + * calling free_mdl; otherwise free_mdl calls + * NdisFreeBuffer back */ + atomic_dec_var(pool->num_allocated_descr); + buffer->pool = NULL; + free_mdl(buffer); + } else { + spin_lock_bh(&pool->lock); + buffer->next = pool->free_descr; + pool->free_descr = buffer; + spin_unlock_bh(&pool->lock); + } + EXIT4(return); +} + +wstdcall void WIN_FUNC(NdisFreeBufferPool,1) + (struct ndis_buffer_pool *pool) +{ + ndis_buffer *cur, *next; + + TRACE3("pool: %p", pool); + if (!pool) { + WARNING("invalid pool"); + EXIT3(return); + } + spin_lock_bh(&pool->lock); + cur = pool->free_descr; + while (cur) { + next = cur->next; + cur->pool = NULL; + free_mdl(cur); + cur = next; + } + spin_unlock_bh(&pool->lock); + kfree(pool); + pool = NULL; + EXIT3(return); +} + +wstdcall void WIN_FUNC(NdisAdjustBufferLength,2) + (ndis_buffer *buffer, UINT length) +{ + ENTER4("%p, %d", buffer, length); + buffer->bytecount = length; +} + +wstdcall void WIN_FUNC(NdisQueryBuffer,3) + (ndis_buffer *buffer, void **virt, UINT *length) +{ + ENTER4("buffer: %p", buffer); + if (virt) + *virt = MmGetSystemAddressForMdl(buffer); + *length = MmGetMdlByteCount(buffer); + TRACE4("%p, %u", virt? *virt : NULL, *length); + return; +} + +wstdcall void WIN_FUNC(NdisQueryBufferSafe,4) + (ndis_buffer *buffer, void **virt, UINT *length, + enum mm_page_priority priority) +{ + ENTER4("%p, %p, %p, %d", buffer, virt, length, priority); + if (virt) + *virt = MmGetSystemAddressForMdlSafe(buffer, priority); + *length = MmGetMdlByteCount(buffer); + TRACE4("%p, %u", virt? *virt : NULL, *length); +} + +wstdcall void *WIN_FUNC(NdisBufferVirtualAddress,1) + (ndis_buffer *buffer) +{ + ENTER3("%p", buffer); + return MmGetSystemAddressForMdl(buffer); +} + +wstdcall ULONG WIN_FUNC(NdisBufferLength,1) + (ndis_buffer *buffer) +{ + ENTER3("%p", buffer); + return MmGetMdlByteCount(buffer); +} + +wstdcall void WIN_FUNC(NdisQueryBufferOffset,3) + (ndis_buffer *buffer, UINT *offset, UINT *length) +{ + ENTER3("%p", buffer); + *offset = MmGetMdlByteOffset(buffer); + *length = MmGetMdlByteCount(buffer); + TRACE3("%d, %d", *offset, *length); +} + +wstdcall void WIN_FUNC(NdisUnchainBufferAtBack,2) + (struct ndis_packet *packet, ndis_buffer **buffer) +{ + ndis_buffer *b, *btail; + + ENTER3("%p", packet); + b = packet->private.buffer_head; + if (!b) { + /* no buffer in packet */ + *buffer = NULL; + EXIT3(return); + } + btail = packet->private.buffer_tail; + *buffer = btail; + if (b == btail) { + /* one buffer in packet */ + packet->private.buffer_head = NULL; + packet->private.buffer_tail = NULL; + } else { + while (b->next != btail) + b = b->next; + packet->private.buffer_tail = b; + b->next = NULL; + } + packet->private.valid_counts = FALSE; + EXIT3(return); +} + +wstdcall void WIN_FUNC(NdisUnchainBufferAtFront,2) + (struct ndis_packet *packet, ndis_buffer **buffer) +{ + ENTER3("%p", packet); + if (packet->private.buffer_head == NULL) { + /* no buffer in packet */ + *buffer = NULL; + EXIT3(return); + } + + *buffer = packet->private.buffer_head; + if (packet->private.buffer_head == packet->private.buffer_tail) { + /* one buffer in packet */ + packet->private.buffer_head = NULL; + packet->private.buffer_tail = NULL; + } else + packet->private.buffer_head = (*buffer)->next; + + packet->private.valid_counts = FALSE; + EXIT3(return); +} + +wstdcall void WIN_FUNC(NdisGetFirstBufferFromPacketSafe,6) + (struct ndis_packet *packet, ndis_buffer **first_buffer, + void **first_buffer_va, UINT *first_buffer_length, + UINT *total_buffer_length, enum mm_page_priority priority) +{ + ndis_buffer *b = packet->private.buffer_head; + + ENTER3("%p(%p)", packet, b); + *first_buffer = b; + if (b) { + *first_buffer_va = MmGetSystemAddressForMdlSafe(b, priority); + *first_buffer_length = *total_buffer_length = + MmGetMdlByteCount(b); + for (b = b->next; b; b = b->next) + *total_buffer_length += MmGetMdlByteCount(b); + } else { + *first_buffer_va = NULL; + *first_buffer_length = 0; + *total_buffer_length = 0; + } + TRACE3("%p, %d, %d", *first_buffer_va, *first_buffer_length, + *total_buffer_length); + EXIT3(return); +} + +wstdcall void WIN_FUNC(NdisGetFirstBufferFromPacket,6) + (struct ndis_packet *packet, ndis_buffer **first_buffer, + void **first_buffer_va, UINT *first_buffer_length, + UINT *total_buffer_length, enum mm_page_priority priority) +{ + NdisGetFirstBufferFromPacketSafe(packet, first_buffer, + first_buffer_va, first_buffer_length, + total_buffer_length, + NormalPagePriority); +} + +wstdcall void WIN_FUNC(NdisAllocatePacketPoolEx,5) + (NDIS_STATUS *status, struct ndis_packet_pool **pool_handle, + UINT num_descr, UINT overflowsize, UINT proto_rsvd_length) +{ + struct ndis_packet_pool *pool; + + ENTER3("buffers: %d, length: %d", num_descr, proto_rsvd_length); + pool = kzalloc(sizeof(*pool), irql_gfp()); + if (!pool) { + *status = NDIS_STATUS_RESOURCES; + EXIT3(return); + } + spin_lock_init(&pool->lock); + pool->max_descr = num_descr; + pool->num_allocated_descr = 0; + pool->num_used_descr = 0; + pool->free_descr = NULL; + pool->proto_rsvd_length = proto_rsvd_length; + *pool_handle = pool; + *status = NDIS_STATUS_SUCCESS; + TRACE3("pool: %p", pool); + EXIT3(return); +} + +wstdcall void WIN_FUNC(NdisAllocatePacketPool,4) + (NDIS_STATUS *status, struct ndis_packet_pool **pool_handle, + UINT num_descr, UINT proto_rsvd_length) +{ + NdisAllocatePacketPoolEx(status, pool_handle, num_descr, 0, + proto_rsvd_length); + EXIT3(return); +} + +wstdcall void WIN_FUNC(NdisFreePacketPool,1) + (struct ndis_packet_pool *pool) +{ + struct ndis_packet *packet, *next; + + ENTER3("pool: %p", pool); + if (!pool) { + WARNING("invalid pool"); + EXIT3(return); + } + spin_lock_bh(&pool->lock); + packet = pool->free_descr; + while (packet) { + next = (struct ndis_packet *)packet->reserved[0]; + kfree(packet); + packet = next; + } + pool->num_allocated_descr = 0; + pool->num_used_descr = 0; + pool->free_descr = NULL; + spin_unlock_bh(&pool->lock); + kfree(pool); + EXIT3(return); +} + +wstdcall UINT WIN_FUNC(NdisPacketPoolUsage,1) + (struct ndis_packet_pool *pool) +{ + EXIT4(return pool->num_used_descr); +} + +wstdcall void WIN_FUNC(NdisAllocatePacket,3) + (NDIS_STATUS *status, struct ndis_packet **ndis_packet, + struct ndis_packet_pool *pool) +{ + struct ndis_packet *packet; + int packet_length; + + ENTER4("pool: %p", pool); + if (!pool) { + *status = NDIS_STATUS_RESOURCES; + *ndis_packet = NULL; + EXIT4(return); + } + assert_irql(_irql_ <= SOFT_LEVEL); + if (pool->num_used_descr > pool->max_descr) { + TRACE3("pool %p is full: %d(%d)", pool, + pool->num_used_descr, pool->max_descr); +#ifndef ALLOW_POOL_OVERFLOW + *status = NDIS_STATUS_RESOURCES; + *ndis_packet = NULL; + return; +#endif + } + /* packet has space for 1 byte in protocol_reserved field */ + packet_length = sizeof(*packet) - 1 + pool->proto_rsvd_length + + sizeof(struct ndis_packet_oob_data); + spin_lock_bh(&pool->lock); + if ((packet = pool->free_descr)) + pool->free_descr = (void *)packet->reserved[0]; + spin_unlock_bh(&pool->lock); + if (!packet) { + packet = kmalloc(packet_length, irql_gfp()); + if (!packet) { + WARNING("couldn't allocate packet"); + *status = NDIS_STATUS_RESOURCES; + *ndis_packet = NULL; + return; + } + atomic_inc_var(pool->num_allocated_descr); + } + TRACE4("%p, %p", pool, packet); + atomic_inc_var(pool->num_used_descr); + memset(packet, 0, packet_length); + packet->private.oob_offset = + packet_length - sizeof(struct ndis_packet_oob_data); + packet->private.packet_flags = fPACKET_ALLOCATED_BY_NDIS; + packet->private.pool = pool; + *ndis_packet = packet; + *status = NDIS_STATUS_SUCCESS; + EXIT4(return); +} + +wstdcall void WIN_FUNC(NdisDprAllocatePacket,3) + (NDIS_STATUS *status, struct ndis_packet **packet, + struct ndis_packet_pool *pool) +{ + NdisAllocatePacket(status, packet, pool); +} + +wstdcall void WIN_FUNC(NdisFreePacket,1) + (struct ndis_packet *packet) +{ + struct ndis_packet_pool *pool; + + ENTER4("%p, %p", packet, packet->private.pool); + pool = packet->private.pool; + if (!pool) { + ERROR("invalid pool %p", packet); + EXIT4(return); + } + assert((int)pool->num_used_descr > 0); + atomic_dec_var(pool->num_used_descr); + if (packet->reserved[1]) { + TRACE3("%p, %p", packet, (void *)packet->reserved[1]); + kfree((void *)packet->reserved[1]); + packet->reserved[1] = 0; + } + if (pool->num_allocated_descr > MAX_ALLOCATED_NDIS_PACKETS) { + TRACE3("%p", pool); + atomic_dec_var(pool->num_allocated_descr); + kfree(packet); + } else { + TRACE4("%p, %p, %p", pool, packet, pool->free_descr); + spin_lock_bh(&pool->lock); + packet->reserved[0] = + (typeof(packet->reserved[0]))pool->free_descr; + pool->free_descr = packet; + spin_unlock_bh(&pool->lock); + } + EXIT4(return); +} + +wstdcall struct ndis_packet_stack *WIN_FUNC(NdisIMGetCurrentPacketStack,2) + (struct ndis_packet *packet, BOOLEAN *stacks_remain) +{ + struct ndis_packet_stack *stack; + + if (!packet->reserved[1]) { + stack = kzalloc(2 * sizeof(*stack), irql_gfp()); + TRACE3("%p, %p", packet, stack); + packet->reserved[1] = (typeof(packet->reserved[1]))stack; + } else { + stack = (void *)packet->reserved[1];; + if (xchg(&stack->ndis_reserved[0], 1)) { + stack++; + if (xchg(&stack->ndis_reserved[0], 1)) + stack = NULL; + } + TRACE3("%p", stack); + } + if (stack) + *stacks_remain = TRUE; + else + *stacks_remain = FALSE; + + EXIT3(return stack); +} + +wstdcall void WIN_FUNC(NdisCopyFromPacketToPacketSafe,7) + (struct ndis_packet *dst, UINT dst_offset, UINT num_to_copy, + struct ndis_packet *src, UINT src_offset, UINT *num_copied, + enum mm_page_priority priority) +{ + UINT dst_n, src_n, n, left; + ndis_buffer *dst_buf; + ndis_buffer *src_buf; + + ENTER4(""); + if (!dst || !src) { + *num_copied = 0; + EXIT4(return); + } + + dst_buf = dst->private.buffer_head; + src_buf = src->private.buffer_head; + + if (!dst_buf || !src_buf) { + *num_copied = 0; + EXIT4(return); + } + dst_n = MmGetMdlByteCount(dst_buf) - dst_offset; + src_n = MmGetMdlByteCount(src_buf) - src_offset; + + n = min(src_n, dst_n); + n = min(n, num_to_copy); + memcpy(MmGetSystemAddressForMdl(dst_buf) + dst_offset, + MmGetSystemAddressForMdl(src_buf) + src_offset, n); + + left = num_to_copy - n; + while (left > 0) { + src_offset += n; + dst_offset += n; + dst_n -= n; + src_n -= n; + if (dst_n == 0) { + dst_buf = dst_buf->next; + if (!dst_buf) + break; + dst_n = MmGetMdlByteCount(dst_buf); + dst_offset = 0; + } + if (src_n == 0) { + src_buf = src_buf->next; + if (!src_buf) + break; + src_n = MmGetMdlByteCount(src_buf); + src_offset = 0; + } + + n = min(src_n, dst_n); + n = min(n, left); + memcpy(MmGetSystemAddressForMdl(dst_buf) + dst_offset, + MmGetSystemAddressForMdl(src_buf) + src_offset, n); + left -= n; + } + *num_copied = num_to_copy - left; + EXIT4(return); +} + +wstdcall void WIN_FUNC(NdisCopyFromPacketToPacket,6) + (struct ndis_packet *dst, UINT dst_offset, UINT num_to_copy, + struct ndis_packet *src, UINT src_offset, UINT *num_copied) +{ + NdisCopyFromPacketToPacketSafe(dst, dst_offset, num_to_copy, + src, src_offset, num_copied, + NormalPagePriority); + return; +} + +wstdcall void WIN_FUNC(NdisIMCopySendPerPacketInfo,2) + (struct ndis_packet *dst, struct ndis_packet *src) +{ + struct ndis_packet_oob_data *dst_oob, *src_oob; + dst_oob = NDIS_PACKET_OOB_DATA(dst); + src_oob = NDIS_PACKET_OOB_DATA(src); + memcpy(&dst_oob->ext, &src_oob->ext, sizeof(dst_oob->ext)); + return; +} + +wstdcall void WIN_FUNC(NdisSend,3) + (NDIS_STATUS *status, struct ndis_mp_block *nmb, + struct ndis_packet *packet) +{ + struct ndis_device *wnd = nmb->wnd; + struct miniport *mp; + KIRQL irql; + + mp = &wnd->wd->driver->ndis_driver->mp; + if (mp->send_packets) { + irql = serialize_lock_irql(wnd); + assert_irql(_irql_ == DISPATCH_LEVEL); + LIN2WIN3(mp->send_packets, wnd->nmb->mp_ctx, &packet, 1); + serialize_unlock_irql(wnd, irql); + if (deserialized_driver(wnd)) + *status = NDIS_STATUS_PENDING; + else { + struct ndis_packet_oob_data *oob_data; + oob_data = NDIS_PACKET_OOB_DATA(packet); + *status = oob_data->status; + switch (*status) { + case NDIS_STATUS_SUCCESS: + free_tx_packet(wnd, packet, *status); + break; + case NDIS_STATUS_PENDING: + break; + case NDIS_STATUS_RESOURCES: + wnd->tx_ok = 0; + break; + case NDIS_STATUS_FAILURE: + default: + free_tx_packet(wnd, packet, *status); + break; + } + } + } else { + irql = serialize_lock_irql(wnd); + assert_irql(_irql_ == DISPATCH_LEVEL); + *status = LIN2WIN3(mp->send, wnd->nmb->mp_ctx, packet, 0); + serialize_unlock_irql(wnd, irql); + switch (*status) { + case NDIS_STATUS_SUCCESS: + free_tx_packet(wnd, packet, *status); + break; + case NDIS_STATUS_PENDING: + break; + case NDIS_STATUS_RESOURCES: + wnd->tx_ok = 0; + break; + case NDIS_STATUS_FAILURE: + default: + free_tx_packet(wnd, packet, *status); + break; + } + } + EXIT3(return); +} + +/* called for serialized drivers only */ +wstdcall void mp_timer_dpc(struct kdpc *kdpc, void *ctx, void *arg1, void *arg2) +{ + struct ndis_mp_timer *timer; + struct ndis_mp_block *nmb; + + timer = ctx; + TIMERENTER("%p, %p, %p, %p", timer, timer->func, timer->ctx, timer->nmb); + assert_irql(_irql_ == DISPATCH_LEVEL); + nmb = timer->nmb; + serialize_lock(nmb->wnd); + LIN2WIN4(timer->func, NULL, timer->ctx, NULL, NULL); + serialize_unlock(nmb->wnd); + TIMEREXIT(return); +} +WIN_FUNC_DECL(mp_timer_dpc,4) + +wstdcall void WIN_FUNC(NdisMInitializeTimer,4) + (struct ndis_mp_timer *timer, struct ndis_mp_block *nmb, + DPC func, void *ctx) +{ + TIMERENTER("%p, %p, %p, %p", timer, func, ctx, nmb); + assert_irql(_irql_ == PASSIVE_LEVEL); + timer->func = func; + timer->ctx = ctx; + timer->nmb = nmb; + if (deserialized_driver(nmb->wnd)) + KeInitializeDpc(&timer->kdpc, func, ctx); + else + KeInitializeDpc(&timer->kdpc, WIN_FUNC_PTR(mp_timer_dpc,4), + timer); + wrap_init_timer(&timer->nt_timer, NotificationTimer, nmb); + TIMEREXIT(return); +} + +wstdcall void WIN_FUNC(NdisMSetPeriodicTimer,2) + (struct ndis_mp_timer *timer, UINT period_ms) +{ + unsigned long expires = MSEC_TO_HZ(period_ms); + + TIMERENTER("%p, %u, %ld", timer, period_ms, expires); + assert_irql(_irql_ <= DISPATCH_LEVEL); + wrap_set_timer(&timer->nt_timer, expires, expires, &timer->kdpc); + TIMEREXIT(return); +} + +wstdcall void WIN_FUNC(NdisMCancelTimer,2) + (struct ndis_mp_timer *timer, BOOLEAN *canceled) +{ + TIMERENTER("%p", timer); + assert_irql(_irql_ <= DISPATCH_LEVEL); + *canceled = KeCancelTimer(&timer->nt_timer); + TIMERTRACE("%d", *canceled); + return; +} + +wstdcall void WIN_FUNC(NdisInitializeTimer,3) + (struct ndis_timer *timer, void *func, void *ctx) +{ + TIMERENTER("%p, %p, %p", timer, func, ctx); + assert_irql(_irql_ == PASSIVE_LEVEL); + KeInitializeDpc(&timer->kdpc, func, ctx); + wrap_init_timer(&timer->nt_timer, NotificationTimer, NULL); + TIMEREXIT(return); +} + +/* NdisMSetTimer is a macro that calls NdisSetTimer with + * ndis_mp_timer typecast to ndis_timer */ + +wstdcall void WIN_FUNC(NdisSetTimer,2) + (struct ndis_timer *timer, UINT duetime_ms) +{ + unsigned long expires = MSEC_TO_HZ(duetime_ms); + + TIMERENTER("%p, %p, %u, %ld", timer, timer->nt_timer.wrap_timer, + duetime_ms, expires); + assert_irql(_irql_ <= DISPATCH_LEVEL); + wrap_set_timer(&timer->nt_timer, expires, 0, &timer->kdpc); + TIMEREXIT(return); +} + +wstdcall void WIN_FUNC(NdisCancelTimer,2) + (struct ndis_timer *timer, BOOLEAN *canceled) +{ + TIMERENTER("%p", timer); + assert_irql(_irql_ <= DISPATCH_LEVEL); + *canceled = KeCancelTimer(&timer->nt_timer); + TIMEREXIT(return); +} + +wstdcall void WIN_FUNC(NdisMRegisterAdapterShutdownHandler,3) + (struct ndis_mp_block *nmb, void *ctx, void *func) +{ + struct ndis_device *wnd = nmb->wnd; + ENTER1("%p", func); + wnd->wd->driver->ndis_driver->mp.shutdown = func; + wnd->shutdown_ctx = ctx; +} + +wstdcall void WIN_FUNC(NdisMDeregisterAdapterShutdownHandler,1) + (struct ndis_mp_block *nmb) +{ + struct ndis_device *wnd = nmb->wnd; + wnd->wd->driver->ndis_driver->mp.shutdown = NULL; + wnd->shutdown_ctx = NULL; +} + +/* TODO: rt61 (serialized) driver doesn't want MiniportEnableInterrupt + * to be called in irq handler, but mrv800c (deserialized) driver + * wants. NDIS is confusing about when to call MiniportEnableInterrupt + * For now, handle these cases with two separate irq handlers based on + * observation of these two drivers. However, it is likely not + * correct. */ +wstdcall void deserialized_irq_handler(struct kdpc *kdpc, void *ctx, + void *arg1, void *arg2) +{ + struct ndis_device *wnd = ctx; + ndis_interrupt_handler irq_handler = arg1; + struct miniport *mp = arg2; + + TRACE6("%p", irq_handler); + assert_irql(_irql_ == DISPATCH_LEVEL); + LIN2WIN1(irq_handler, wnd->nmb->mp_ctx); + if (mp->enable_interrupt) + LIN2WIN1(mp->enable_interrupt, wnd->nmb->mp_ctx); + EXIT6(return); +} +WIN_FUNC_DECL(deserialized_irq_handler,4) + +wstdcall void serialized_irq_handler(struct kdpc *kdpc, void *ctx, + void *arg1, void *arg2) +{ + struct ndis_device *wnd = ctx; + ndis_interrupt_handler irq_handler = arg1; + + TRACE6("%p, %p, %p", wnd, irq_handler, arg2); + assert_irql(_irql_ == DISPATCH_LEVEL); + serialize_lock(wnd); + LIN2WIN1(irq_handler, arg2); + serialize_unlock(wnd); + EXIT6(return); +} +WIN_FUNC_DECL(serialized_irq_handler,4) + +wstdcall BOOLEAN ndis_isr(struct kinterrupt *kinterrupt, void *ctx) +{ + struct ndis_mp_interrupt *mp_interrupt = ctx; + struct ndis_device *wnd = mp_interrupt->nmb->wnd; + BOOLEAN recognized, queue_handler; + + TRACE6("%p", wnd); + /* kernel may call ISR when registering interrupt, in + * the same context if DEBUG_SHIRQ is enabled */ + assert_irql(_irql_ == DIRQL || _irql_ == PASSIVE_LEVEL); + if (mp_interrupt->shared) + LIN2WIN3(mp_interrupt->isr, &recognized, &queue_handler, + wnd->nmb->mp_ctx); + else { + struct miniport *mp; + mp = &wnd->wd->driver->ndis_driver->mp; + LIN2WIN1(mp->disable_interrupt, wnd->nmb->mp_ctx); + /* it is not shared interrupt, so handler must be called */ + recognized = queue_handler = TRUE; + } + if (recognized) { + if (queue_handler) { + TRACE5("%p", &wnd->irq_kdpc); + queue_kdpc(&wnd->irq_kdpc); + } + EXIT6(return TRUE); + } + EXIT6(return FALSE); +} +WIN_FUNC_DECL(ndis_isr,2) + +wstdcall NDIS_STATUS WIN_FUNC(NdisMRegisterInterrupt,7) + (struct ndis_mp_interrupt *mp_interrupt, + struct ndis_mp_block *nmb, UINT vector, UINT level, + BOOLEAN req_isr, BOOLEAN shared, enum kinterrupt_mode mode) +{ + struct ndis_device *wnd = nmb->wnd; + struct miniport *mp; + + ENTER1("%p, vector:%d, level:%d, req_isr:%d, shared:%d, mode:%d", + mp_interrupt, vector, level, req_isr, shared, mode); + + mp = &wnd->wd->driver->ndis_driver->mp; + nt_spin_lock_init(&mp_interrupt->lock); + mp_interrupt->irq = vector; + mp_interrupt->isr = mp->isr; + mp_interrupt->mp_dpc = mp->handle_interrupt; + mp_interrupt->nmb = nmb; + mp_interrupt->req_isr = req_isr; + if (shared && !req_isr) + WARNING("shared but dynamic interrupt!"); + mp_interrupt->shared = shared; + wnd->mp_interrupt = mp_interrupt; + if (mp->enable_interrupt) + mp_interrupt->enable = TRUE; + else + mp_interrupt->enable = FALSE; + + if (deserialized_driver(wnd)) { + KeInitializeDpc(&wnd->irq_kdpc, + WIN_FUNC_PTR(deserialized_irq_handler,4), + nmb->wnd); + wnd->irq_kdpc.arg1 = mp->handle_interrupt; + wnd->irq_kdpc.arg2 = mp; + TRACE2("%p, %p, %p, %p", wnd->irq_kdpc.arg1, wnd->irq_kdpc.arg2, + nmb->wnd, nmb->mp_ctx); + } else { + KeInitializeDpc(&wnd->irq_kdpc, + WIN_FUNC_PTR(serialized_irq_handler,4), + nmb->wnd); + wnd->irq_kdpc.arg1 = mp->handle_interrupt; + wnd->irq_kdpc.arg2 = nmb->mp_ctx; + TRACE2("%p, %p, %p", wnd->irq_kdpc.arg1, wnd->irq_kdpc.arg2, + nmb->wnd); + } + + if (IoConnectInterrupt(&mp_interrupt->kinterrupt, + WIN_FUNC_PTR(ndis_isr,2), mp_interrupt, NULL, + vector, DIRQL, DIRQL, mode, shared, 0, FALSE) != + STATUS_SUCCESS) { + printk(KERN_WARNING "%s: request for IRQ %d failed\n", + DRIVER_NAME, vector); + return NDIS_STATUS_RESOURCES; + } + printk(KERN_INFO "%s: using IRQ %d\n", DRIVER_NAME, vector); + EXIT1(return NDIS_STATUS_SUCCESS); +} + +wstdcall void WIN_FUNC(NdisMDeregisterInterrupt,1) + (struct ndis_mp_interrupt *mp_interrupt) +{ + struct ndis_mp_block *nmb; + + ENTER1("%p", mp_interrupt); + nmb = xchg(&mp_interrupt->nmb, NULL); + TRACE1("%p", nmb); + if (!nmb) { + WARNING("interrupt already freed?"); + return; + } + nmb->wnd->mp_interrupt = NULL; + if (dequeue_kdpc(&nmb->wnd->irq_kdpc)) + TRACE2("interrupt kdpc was pending"); + flush_workqueue(wrapndis_wq); + IoDisconnectInterrupt(mp_interrupt->kinterrupt); + EXIT1(return); +} + +wstdcall BOOLEAN WIN_FUNC(NdisMSynchronizeWithInterrupt,3) + (struct ndis_mp_interrupt *mp_interrupt, + PKSYNCHRONIZE_ROUTINE sync_func, void *ctx) +{ + return KeSynchronizeExecution(mp_interrupt->kinterrupt, sync_func, ctx); +} + +/* called via function pointer; but 64-bit RNDIS driver calls directly */ +wstdcall void WIN_FUNC(NdisMIndicateStatus,4) + (struct ndis_mp_block *nmb, NDIS_STATUS status, void *buf, UINT len) +{ + struct ndis_device *wnd = nmb->wnd; + struct ndis_status_indication *si; + + ENTER2("status=0x%x len=%d", status, len); + switch (status) { + case NDIS_STATUS_MEDIA_CONNECT: + netif_carrier_on(wnd->net_dev); + wnd->tx_ok = 1; + if (netif_queue_stopped(wnd->net_dev)) + netif_wake_queue(wnd->net_dev); + if (wnd->physical_medium == NdisPhysicalMediumWirelessLan) { + set_bit(LINK_STATUS_ON, &wnd->ndis_pending_work); + schedule_wrapndis_work(&wnd->ndis_work); + } + break; + case NDIS_STATUS_MEDIA_DISCONNECT: + netif_carrier_off(wnd->net_dev); + netif_stop_queue(wnd->net_dev); + wnd->tx_ok = 0; + if (wnd->physical_medium == NdisPhysicalMediumWirelessLan) { + memset(&wnd->essid, 0, sizeof(wnd->essid)); + set_bit(LINK_STATUS_OFF, &wnd->ndis_pending_work); + schedule_wrapndis_work(&wnd->ndis_work); + } + break; + case NDIS_STATUS_MEDIA_SPECIFIC_INDICATION: + if (!buf) + break; + si = buf; + TRACE2("status_type=%d", si->status_type); + switch (si->status_type) { + case Ndis802_11StatusType_MediaStreamMode: + break; +#ifdef CONFIG_WIRELESS_EXT + case Ndis802_11StatusType_Authentication: + buf = (char *)buf + sizeof(*si); + len -= sizeof(*si); + while (len > 0) { + int pairwise_error = 0, group_error = 0; + struct ndis_auth_req *auth_req = + (struct ndis_auth_req *)buf; + TRACE1(MACSTRSEP, MAC2STR(auth_req->bssid)); + if (auth_req->flags & 0x01) + TRACE2("reauth request"); + if (auth_req->flags & 0x02) + TRACE2("key update request"); + if (auth_req->flags & 0x06) { + pairwise_error = 1; + TRACE2("pairwise_error"); + } + if (auth_req->flags & 0x0E) { + group_error = 1; + TRACE2("group_error"); + } + if (pairwise_error || group_error) { + union iwreq_data wrqu; + struct iw_michaelmicfailure micfailure; + + memset(&micfailure, 0, sizeof(micfailure)); + if (pairwise_error) + micfailure.flags |= + IW_MICFAILURE_PAIRWISE; + if (group_error) + micfailure.flags |= + IW_MICFAILURE_GROUP; + memcpy(micfailure.src_addr.sa_data, + auth_req->bssid, ETH_ALEN); + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = sizeof(micfailure); + wireless_send_event(wnd->net_dev, + IWEVMICHAELMICFAILURE, + &wrqu, (u8 *)&micfailure); + } + len -= auth_req->length; + buf = (char *)buf + auth_req->length; + } + break; + case Ndis802_11StatusType_PMKID_CandidateList: + { + u8 *end; + unsigned long i; + struct ndis_pmkid_candidate_list *cand; + + cand = buf + sizeof(struct ndis_status_indication); + if (len < sizeof(struct ndis_status_indication) + + sizeof(struct ndis_pmkid_candidate_list) || + cand->version != 1) { + WARNING("unrecognized PMKID ignored"); + EXIT1(return); + } + + end = (u8 *)buf + len; + TRACE2("PMKID ver %d num_cand %d", + cand->version, cand->num_candidates); + for (i = 0; i < cand->num_candidates; i++) { + struct iw_pmkid_cand pcand; + union iwreq_data wrqu; + struct ndis_pmkid_candidate *c = + &cand->candidates[i]; + if ((u8 *)(c + 1) > end) { + TRACE2("truncated PMKID"); + break; + } + TRACE2("%ld: " MACSTRSEP " 0x%x", + i, MAC2STR(c->bssid), c->flags); + memset(&pcand, 0, sizeof(pcand)); + if (c->flags & 0x01) + pcand.flags |= IW_PMKID_CAND_PREAUTH; + pcand.index = i; + memcpy(pcand.bssid.sa_data, c->bssid, ETH_ALEN); + + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = sizeof(pcand); + wireless_send_event(wnd->net_dev, IWEVPMKIDCAND, + &wrqu, (u8 *)&pcand); + } + break; + } + case Ndis802_11StatusType_RadioState: + { + struct ndis_radio_status_indication *radio_status = buf; + if (radio_status->radio_state == + Ndis802_11RadioStatusOn) + INFO("radio is turned on"); + else if (radio_status->radio_state == + Ndis802_11RadioStatusHardwareOff) + INFO("radio is turned off by hardware"); + else if (radio_status->radio_state == + Ndis802_11RadioStatusSoftwareOff) + INFO("radio is turned off by software"); + break; + } +#endif + default: + /* is this RSSI indication? */ + TRACE2("unknown indication: %x", si->status_type); + break; + } + break; + default: + TRACE2("unknown status: %08X", status); + break; + } + + EXIT2(return); +} + +/* called via function pointer; but 64-bit RNDIS driver calls directly */ +wstdcall void WIN_FUNC(NdisMIndicateStatusComplete,1) + (struct ndis_mp_block *nmb) +{ + struct ndis_device *wnd = nmb->wnd; + ENTER2("%p", wnd); + if (wnd->tx_ok) + schedule_wrapndis_work(&wnd->tx_work); +} + +/* called via function pointer */ +wstdcall void NdisMSendComplete(struct ndis_mp_block *nmb, + struct ndis_packet *packet, NDIS_STATUS status) +{ + struct ndis_device *wnd = nmb->wnd; + ENTER4("%p, %08X", packet, status); + assert_irql(_irql_ <= DISPATCH_LEVEL); + if (deserialized_driver(wnd)) + free_tx_packet(wnd, packet, status); + else { + struct ndis_packet_oob_data *oob_data; + NDIS_STATUS pkt_status; + TRACE3("%p, %08x", packet, status); + oob_data = NDIS_PACKET_OOB_DATA(packet); + switch ((pkt_status = xchg(&oob_data->status, status))) { + case NDIS_STATUS_NOT_RECOGNIZED: + free_tx_packet(wnd, packet, status); + break; + case NDIS_STATUS_PENDING: + case 0: + break; + default: + WARNING("%p: invalid status: %08X", packet, pkt_status); + break; + } + /* In case a serialized driver has earlier requested a + * pause by returning NDIS_STATUS_RESOURCES during + * MiniportSend(Packets), wakeup tx worker now. + */ + if (xchg(&wnd->tx_ok, 1) == 0) { + TRACE3("%d, %d", wnd->tx_ring_start, wnd->tx_ring_end); + schedule_wrapndis_work(&wnd->tx_work); + } + } + EXIT3(return); +} + +/* called via function pointer */ +wstdcall void NdisMSendResourcesAvailable(struct ndis_mp_block *nmb) +{ + struct ndis_device *wnd = nmb->wnd; + ENTER3("%d, %d", wnd->tx_ring_start, wnd->tx_ring_end); + wnd->tx_ok = 1; + schedule_wrapndis_work(&wnd->tx_work); + EXIT3(return); +} + +wstdcall void return_packet(void *arg1, void *arg2) +{ + struct ndis_device *wnd; + struct ndis_packet *packet; + struct miniport *mp; + KIRQL irql; + + wnd = arg1; + packet = arg2; + ENTER4("%p, %p", wnd, packet); + mp = &wnd->wd->driver->ndis_driver->mp; + irql = serialize_lock_irql(wnd); + assert_irql(_irql_ == DISPATCH_LEVEL); + LIN2WIN2(mp->return_packet, wnd->nmb->mp_ctx, packet); + serialize_unlock_irql(wnd, irql); + EXIT4(return); +} +WIN_FUNC_DECL(return_packet,2) + +/* called via function pointer */ +wstdcall void NdisMIndicateReceivePacket(struct ndis_mp_block *nmb, + struct ndis_packet **packets, + UINT nr_packets) +{ + struct ndis_device *wnd; + ndis_buffer *buffer; + struct ndis_packet *packet; + struct sk_buff *skb; + ULONG i, length, total_length; + struct ndis_packet_oob_data *oob_data; + void *virt; + struct ndis_tcp_ip_checksum_packet_info csum; + + ENTER3("%p, %d", nmb, nr_packets); + assert_irql(_irql_ <= DISPATCH_LEVEL); + wnd = nmb->wnd; + for (i = 0; i < nr_packets; i++) { + packet = packets[i]; + if (!packet) { + WARNING("empty packet ignored"); + continue; + } + wnd->net_dev->last_rx = jiffies; + /* get total number of bytes in packet */ + NdisGetFirstBufferFromPacketSafe(packet, &buffer, &virt, + &length, &total_length, + NormalPagePriority); + TRACE3("%d, %d", length, total_length); + oob_data = NDIS_PACKET_OOB_DATA(packet); + TRACE3("0x%x, 0x%x, %Lu", packet->private.flags, + packet->private.packet_flags, oob_data->time_rxed); + skb = dev_alloc_skb(total_length); + if (skb) { + while (buffer) { + memcpy_skb(skb, MmGetSystemAddressForMdl(buffer), + MmGetMdlByteCount(buffer)); + buffer = buffer->next; + } + skb->dev = wnd->net_dev; + skb->protocol = eth_type_trans(skb, wnd->net_dev); + pre_atomic_add(wnd->net_stats.rx_bytes, total_length); + atomic_inc_var(wnd->net_stats.rx_packets); + csum.value = (typeof(csum.value))(ULONG_PTR) + oob_data->ext.info[TcpIpChecksumPacketInfo]; + TRACE3("0x%05x", csum.value); + if (wnd->rx_csum.value && + (csum.rx.tcp_succeeded || csum.rx.udp_succeeded || + csum.rx.ip_succeeded)) + skb->ip_summed = CHECKSUM_UNNECESSARY; + else + skb->ip_summed = CHECKSUM_NONE; + + if (in_interrupt()) + netif_rx(skb); + else + netif_rx_ni(skb); + } else { + WARNING("couldn't allocate skb; packet dropped"); + atomic_inc_var(wnd->net_stats.rx_dropped); + } + + /* serialized drivers check the status upon return + * from this function */ + if (!deserialized_driver(wnd)) { + oob_data->status = NDIS_STATUS_SUCCESS; + continue; + } + + /* if a deserialized driver sets + * NDIS_STATUS_RESOURCES, then it reclaims the packet + * upon return from this function */ + if (oob_data->status == NDIS_STATUS_RESOURCES) + continue; + + assert(oob_data->status == NDIS_STATUS_SUCCESS); + /* deserialized driver doesn't check the status upon + * return from this function; we need to call + * MiniportReturnPacket later for this packet. Calling + * MiniportReturnPacket from here is not correct - the + * driver doesn't expect it (at least Centrino driver + * crashes) */ + schedule_ntos_work_item(WIN_FUNC_PTR(return_packet,2), + wnd, packet); + } + EXIT3(return); +} + +/* called via function pointer (by NdisMEthIndicateReceive macro); the + * first argument is nmb->eth_db */ +wstdcall void EthRxIndicateHandler(struct ndis_mp_block *nmb, void *rx_ctx, + char *header1, char *header, UINT header_size, + void *look_ahead, UINT look_ahead_size, + UINT packet_size) +{ + struct sk_buff *skb = NULL; + struct ndis_device *wnd; + unsigned int skb_size = 0; + KIRQL irql; + struct ndis_packet_oob_data *oob_data; + + ENTER3("nmb = %p, rx_ctx = %p, buf = %p, size = %d, buf = %p, " + "size = %d, packet = %d", nmb, rx_ctx, header, header_size, + look_ahead, look_ahead_size, packet_size); + + wnd = nmb->wnd; + TRACE3("wnd = %p", wnd); + if (!wnd) { + ERROR("nmb is NULL"); + EXIT3(return); + } + wnd->net_dev->last_rx = jiffies; + + if (look_ahead_size < packet_size) { + struct ndis_packet *packet; + struct miniport *mp; + unsigned int bytes_txed; + NDIS_STATUS res; + + NdisAllocatePacket(&res, &packet, wnd->tx_packet_pool); + if (res != NDIS_STATUS_SUCCESS) { + atomic_inc_var(wnd->net_stats.rx_dropped); + EXIT3(return); + } + oob_data = NDIS_PACKET_OOB_DATA(packet); + mp = &wnd->wd->driver->ndis_driver->mp; + irql = serialize_lock_irql(wnd); + assert_irql(_irql_ == DISPATCH_LEVEL); + res = LIN2WIN6(mp->tx_data, packet, &bytes_txed, nmb, + rx_ctx, look_ahead_size, packet_size); + serialize_unlock_irql(wnd, irql); + TRACE3("%d, %d, %d", header_size, look_ahead_size, bytes_txed); + if (res == NDIS_STATUS_SUCCESS) { + ndis_buffer *buffer; + struct ndis_tcp_ip_checksum_packet_info csum; + skb = dev_alloc_skb(header_size + look_ahead_size + + bytes_txed); + if (!skb) { + ERROR("couldn't allocate skb; packet dropped"); + atomic_inc_var(wnd->net_stats.rx_dropped); + NdisFreePacket(packet); + return; + } + memcpy_skb(skb, header, header_size); + memcpy_skb(skb, look_ahead, look_ahead_size); + buffer = packet->private.buffer_head; + while (buffer) { + memcpy_skb(skb, + MmGetSystemAddressForMdl(buffer), + MmGetMdlByteCount(buffer)); + buffer = buffer->next; + } + skb_size = header_size + look_ahead_size + bytes_txed; + csum.value = (typeof(csum.value))(ULONG_PTR) + oob_data->ext.info[TcpIpChecksumPacketInfo]; + TRACE3("0x%05x", csum.value); + if (wnd->rx_csum.value && + (csum.rx.tcp_succeeded || csum.rx.udp_succeeded)) + skb->ip_summed = CHECKSUM_UNNECESSARY; + else + skb->ip_summed = CHECKSUM_NONE; + NdisFreePacket(packet); + } else if (res == NDIS_STATUS_PENDING) { + /* driver will call td_complete */ + oob_data->look_ahead = kmalloc(look_ahead_size, + GFP_ATOMIC); + if (!oob_data->look_ahead) { + NdisFreePacket(packet); + ERROR("packet dropped"); + atomic_inc_var(wnd->net_stats.rx_dropped); + EXIT3(return); + } + assert(sizeof(oob_data->header) == header_size); + memcpy(oob_data->header, header, + sizeof(oob_data->header)); + memcpy(oob_data->look_ahead, look_ahead, + look_ahead_size); + oob_data->look_ahead_size = look_ahead_size; + EXIT3(return); + } else { + WARNING("packet dropped: %08X", res); + atomic_inc_var(wnd->net_stats.rx_dropped); + NdisFreePacket(packet); + EXIT3(return); + } + } else { + skb_size = header_size + packet_size; + skb = dev_alloc_skb(skb_size); + if (skb) { + memcpy_skb(skb, header, header_size); + memcpy_skb(skb, look_ahead, packet_size); + } + } + + if (skb) { + skb->dev = wnd->net_dev; + skb->protocol = eth_type_trans(skb, wnd->net_dev); + pre_atomic_add(wnd->net_stats.rx_bytes, skb_size); + atomic_inc_var(wnd->net_stats.rx_packets); + if (in_interrupt()) + netif_rx(skb); + else + netif_rx_ni(skb); + } + + EXIT3(return); +} + +/* called via function pointer */ +wstdcall void NdisMTransferDataComplete(struct ndis_mp_block *nmb, + struct ndis_packet *packet, + NDIS_STATUS status, UINT bytes_txed) +{ + struct ndis_device *wnd = nmb->wnd; + struct sk_buff *skb; + unsigned int skb_size; + struct ndis_packet_oob_data *oob_data; + ndis_buffer *buffer; + struct ndis_tcp_ip_checksum_packet_info csum; + + ENTER3("wnd = %p, packet = %p, bytes_txed = %d", + wnd, packet, bytes_txed); + if (!packet) { + WARNING("illegal packet"); + EXIT3(return); + } + wnd->net_dev->last_rx = jiffies; + oob_data = NDIS_PACKET_OOB_DATA(packet); + skb_size = sizeof(oob_data->header) + oob_data->look_ahead_size + + bytes_txed; + skb = dev_alloc_skb(skb_size); + if (!skb) { + kfree(oob_data->look_ahead); + NdisFreePacket(packet); + ERROR("couldn't allocate skb; packet dropped"); + atomic_inc_var(wnd->net_stats.rx_dropped); + EXIT3(return); + } + memcpy_skb(skb, oob_data->header, sizeof(oob_data->header)); + memcpy_skb(skb, oob_data->look_ahead, oob_data->look_ahead_size); + buffer = packet->private.buffer_head; + while (buffer) { + memcpy_skb(skb, MmGetSystemAddressForMdl(buffer), + MmGetMdlByteCount(buffer)); + buffer = buffer->next; + } + kfree(oob_data->look_ahead); + NdisFreePacket(packet); + skb->dev = wnd->net_dev; + skb->protocol = eth_type_trans(skb, wnd->net_dev); + pre_atomic_add(wnd->net_stats.rx_bytes, skb_size); + atomic_inc_var(wnd->net_stats.rx_packets); + + csum.value = (typeof(csum.value))(ULONG_PTR) + oob_data->ext.info[TcpIpChecksumPacketInfo]; + TRACE3("0x%05x", csum.value); + if (wnd->rx_csum.value && + (csum.rx.tcp_succeeded || csum.rx.udp_succeeded)) + skb->ip_summed = CHECKSUM_UNNECESSARY; + else + skb->ip_summed = CHECKSUM_NONE; + + if (in_interrupt()) + netif_rx(skb); + else + netif_rx_ni(skb); +} + +/* called via function pointer */ +wstdcall void EthRxComplete(struct ndis_mp_block *nmb) +{ + TRACE3(""); +} + +/* called via function pointer */ +wstdcall void NdisMQueryInformationComplete(struct ndis_mp_block *nmb, + NDIS_STATUS status) +{ + struct ndis_device *wnd = nmb->wnd; + typeof(wnd->ndis_req_task) task; + + ENTER2("nmb: %p, wnd: %p, %08X", nmb, wnd, status); + wnd->ndis_req_status = status; + wnd->ndis_req_done = 1; + if ((task = xchg(&wnd->ndis_req_task, NULL))) + wake_up_process(task); + else + WARNING("invalid task"); + EXIT2(return); +} + +/* called via function pointer */ +wstdcall void NdisMSetInformationComplete(struct ndis_mp_block *nmb, + NDIS_STATUS status) +{ + struct ndis_device *wnd = nmb->wnd; + typeof(wnd->ndis_req_task) task; + + ENTER2("status = %08X", status); + wnd->ndis_req_status = status; + wnd->ndis_req_done = 1; + if ((task = xchg(&wnd->ndis_req_task, NULL))) + wake_up_process(task); + else + WARNING("invalid task"); + EXIT2(return); +} + +/* called via function pointer */ +wstdcall void NdisMResetComplete(struct ndis_mp_block *nmb, + NDIS_STATUS status, BOOLEAN address_reset) +{ + struct ndis_device *wnd = nmb->wnd; + typeof(wnd->ndis_req_task) task; + + ENTER2("status: %08X, %u", status, address_reset); + wnd->ndis_req_status = status; + wnd->ndis_req_done = address_reset + 1; + if ((task = xchg(&wnd->ndis_req_task, NULL))) + wake_up_process(task); + else + WARNING("invalid task"); + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisMSleep,1) + (ULONG us) +{ + unsigned long delay; + + ENTER4("%p: us: %u", current, us); + delay = USEC_TO_HZ(us); + sleep_hz(delay); + TRACE4("%p: done", current); +} + +wstdcall void WIN_FUNC(NdisGetCurrentSystemTime,1) + (LARGE_INTEGER *time) +{ + *time = ticks_1601(); + TRACE5("%Lu, %lu", *time, jiffies); +} + +wstdcall LONG WIN_FUNC(NdisInterlockedDecrement,1) + (LONG *val) +{ + return InterlockedDecrement(val); +} + +wstdcall LONG WIN_FUNC(NdisInterlockedIncrement,1) + (LONG *val) +{ + return InterlockedIncrement(val); +} + +wstdcall struct nt_list *WIN_FUNC(NdisInterlockedInsertHeadList,3) + (struct nt_list *head, struct nt_list *entry, + struct ndis_spinlock *lock) +{ + return ExInterlockedInsertHeadList(head, entry, &lock->klock); +} + +wstdcall struct nt_list *WIN_FUNC(NdisInterlockedInsertTailList,3) + (struct nt_list *head, struct nt_list *entry, + struct ndis_spinlock *lock) +{ + return ExInterlockedInsertTailList(head, entry, &lock->klock); +} + +wstdcall struct nt_list *WIN_FUNC(NdisInterlockedRemoveHeadList,2) + (struct nt_list *head, struct ndis_spinlock *lock) +{ + return ExInterlockedRemoveHeadList(head, &lock->klock); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisMInitializeScatterGatherDma,3) + (struct ndis_mp_block *nmb, BOOLEAN dma_size, ULONG max_phy_map) +{ + struct ndis_device *wnd = nmb->wnd; + ENTER2("dma_size=%d, maxtransfer=%u", dma_size, max_phy_map); +#ifdef CONFIG_X86_64 + if (dma_size != NDIS_DMA_64BITS) { + TRACE1("DMA size is not 64-bits"); + if (pci_set_dma_mask(wnd->wd->pci.pdev, DMA_32BIT_MASK) || + pci_set_consistent_dma_mask(wnd->wd->pci.pdev, + DMA_32BIT_MASK)) + WARNING("setting dma mask failed"); + } +#endif + if ((wnd->attributes & NDIS_ATTRIBUTE_BUS_MASTER) && + wrap_is_pci_bus(wnd->wd->dev_bus)) { + wnd->sg_dma_size = max_phy_map; + return NDIS_STATUS_SUCCESS; + } else + EXIT1(return NDIS_STATUS_NOT_SUPPORTED); +} + +wstdcall ULONG WIN_FUNC(NdisMGetDmaAlignment,1) + (struct ndis_mp_block *nmb) +{ + ENTER3(""); + return dma_get_cache_alignment(); +} + +wstdcall CHAR WIN_FUNC(NdisSystemProcessorCount,0) + (void) +{ + return NR_CPUS; +} + +wstdcall void WIN_FUNC(NdisGetCurrentProcessorCounts,3) + (ULONG *idle, ULONG *kernel_user, ULONG *index) +{ + int cpu = smp_processor_id(); + *idle = kstat_cpu(cpu).cpustat.idle; + *kernel_user = kstat_cpu(cpu).cpustat.system + + kstat_cpu(cpu).cpustat.user; + *index = cpu; +} + +wstdcall void WIN_FUNC(NdisInitializeEvent,1) + (struct ndis_event *ndis_event) +{ + EVENTENTER("%p", ndis_event); + KeInitializeEvent(&ndis_event->nt_event, NotificationEvent, 0); +} + +wstdcall BOOLEAN WIN_FUNC(NdisWaitEvent,2) + (struct ndis_event *ndis_event, UINT ms) +{ + LARGE_INTEGER ticks; + NTSTATUS res; + + EVENTENTER("%p %u", ndis_event, ms); + ticks = -((LARGE_INTEGER)ms * TICKSPERMSEC); + res = KeWaitForSingleObject(&ndis_event->nt_event, 0, 0, TRUE, + ms == 0 ? NULL : &ticks); + if (res == STATUS_SUCCESS) + EXIT3(return TRUE); + else + EXIT3(return FALSE); +} + +wstdcall void WIN_FUNC(NdisSetEvent,1) + (struct ndis_event *ndis_event) +{ + EVENTENTER("%p", ndis_event); + KeSetEvent(&ndis_event->nt_event, 0, 0); +} + +wstdcall void WIN_FUNC(NdisResetEvent,1) + (struct ndis_event *ndis_event) +{ + EVENTENTER("%p", ndis_event); + KeResetEvent(&ndis_event->nt_event); +} + +static void ndis_worker(worker_param_t dummy) +{ + struct nt_list *ent; + struct ndis_work_item *ndis_work_item; + + WORKENTER(""); + while (1) { + spin_lock_bh(&ndis_work_list_lock); + ent = RemoveHeadList(&ndis_work_list); + spin_unlock_bh(&ndis_work_list_lock); + if (!ent) + break; + ndis_work_item = container_of(ent, struct ndis_work_item, list); + WORKTRACE("%p: %p, %p", ndis_work_item, + ndis_work_item->func, ndis_work_item->ctx); + LIN2WIN2(ndis_work_item->func, ndis_work_item, + ndis_work_item->ctx); + WORKTRACE("%p done", ndis_work_item); + } + WORKEXIT(return); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisScheduleWorkItem,1) + (struct ndis_work_item *ndis_work_item) +{ + ENTER3("%p", ndis_work_item); + spin_lock_bh(&ndis_work_list_lock); + InsertTailList(&ndis_work_list, &ndis_work_item->list); + spin_unlock_bh(&ndis_work_list_lock); + WORKTRACE("scheduling %p", ndis_work_item); + schedule_ndis_work(&ndis_work); + EXIT3(return NDIS_STATUS_SUCCESS); +} + +wstdcall void WIN_FUNC(NdisMGetDeviceProperty,6) + (struct ndis_mp_block *nmb, void **phy_dev, void **func_dev, + void **next_dev, void **alloc_res, void**trans_res) +{ + ENTER2("nmb: %p, phy_dev = %p, func_dev = %p, next_dev = %p, " + "alloc_res = %p, trans_res = %p", nmb, phy_dev, func_dev, + next_dev, alloc_res, trans_res); + if (phy_dev) + *phy_dev = nmb->pdo; + if (func_dev) + *func_dev = nmb->fdo; + if (next_dev) + *next_dev = nmb->next_device; +} + +wstdcall void WIN_FUNC(NdisMRegisterUnloadHandler,2) + (struct driver_object *drv_obj, void *unload) +{ + if (drv_obj) + drv_obj->unload = unload; + return; +} + +wstdcall UINT WIN_FUNC(NdisGetVersion,0) + (void) +{ + return 0x00050001; +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisMQueryAdapterInstanceName,2) + (struct unicode_string *name, struct ndis_mp_block *nmb) +{ + struct ndis_device *wnd = nmb->wnd; + struct ansi_string ansi; + + if (wrap_is_pci_bus(wnd->wd->dev_bus)) + RtlInitAnsiString(&ansi, "PCI Ethernet Adapter"); + else + RtlInitAnsiString(&ansi, "USB Ethernet Adapter"); + + if (RtlAnsiStringToUnicodeString(name, &ansi, TRUE)) + EXIT2(return NDIS_STATUS_RESOURCES); + else + EXIT2(return NDIS_STATUS_SUCCESS); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisWriteEventLogEntry,7) + (void *handle, NDIS_STATUS code, ULONG value, USHORT n, + void *strings, ULONG datasize, void *data) +{ + TRACE1("0x%x, 0x%x, %u, %u", code, value, n, datasize); + return NDIS_STATUS_SUCCESS; +} + +wstdcall void *WIN_FUNC(NdisGetRoutineAddress,1) + (struct unicode_string *unicode_string) +{ + struct ansi_string ansi_string; + void *address; + + if (RtlUnicodeStringToAnsiString(&ansi_string, unicode_string, TRUE) != + STATUS_SUCCESS) + EXIT1(return NULL); + INFO("%s", ansi_string.buf); + address = ndis_get_routine_address(ansi_string.buf); + RtlFreeAnsiString(&ansi_string); + return address; +} + +wstdcall ULONG WIN_FUNC(NdisReadPcmciaAttributeMemory,4) + (struct ndis_mp_block *nmb, ULONG offset, void *buffer, + ULONG length) +{ + TODO(); + return 0; +} + +wstdcall ULONG WIN_FUNC(NdisWritePcmciaAttributeMemory,4) + (struct ndis_mp_block *nmb, ULONG offset, void *buffer, + ULONG length) +{ + TODO(); + return 0; +} + +wstdcall void WIN_FUNC(NdisMCoIndicateReceivePacket,3) + (struct ndis_mp_block *nmb, struct ndis_packet **packets, + UINT nr_packets) +{ + ENTER3("nmb = %p", nmb); + NdisMIndicateReceivePacket(nmb, packets, nr_packets); + EXIT3(return); +} + +wstdcall void WIN_FUNC(NdisMCoSendComplete,3) + (NDIS_STATUS status, struct ndis_mp_block *nmb, + struct ndis_packet *packet) +{ + ENTER3("%08x", status); + NdisMSendComplete(nmb, packet, status); + EXIT3(return); +} + +wstdcall void WIN_FUNC(NdisMCoRequestComplete,3) + (NDIS_STATUS status, struct ndis_mp_block *nmb, + struct ndis_request *ndis_request) +{ + struct ndis_device *wnd = nmb->wnd; + typeof(wnd->ndis_req_task) task; + + ENTER3("%08X", status); + wnd->ndis_req_status = status; + wnd->ndis_req_done = 1; + if ((task = xchg(&wnd->ndis_req_task, NULL))) + wake_up_process(task); + else + WARNING("invalid task"); + EXIT3(return); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisIMNotifiyPnPEvent,2) + (struct ndis_mp_block *nmb, struct net_pnp_event *event) +{ + ENTER2("%p, %d", nmb, event->code); + /* NdisWrapper never calls protocol's pnp event notifier, so + * nothing to do here */ + EXIT2(return NDIS_STATUS_SUCCESS); +} + +wstdcall void WIN_FUNC(NdisCompletePnPEvent,2) + (NDIS_STATUS status, void *handle, struct net_pnp_event *event) +{ + ENTER2("%d, %p, %d", status, handle, event->code); + /* NdisWrapper never calls protocol's pnp event notifier, so + * nothing to do here */ + EXIT2(return); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisMSetMiniportSecondary,2) + (struct ndis_mp_block *nmb2, struct ndis_mp_block *nmb1) +{ + ENTER3("%p, %p", nmb1, nmb2); + TODO(); + EXIT3(return NDIS_STATUS_SUCCESS); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisMPromoteMiniport,1) + (struct ndis_mp_block *nmb) +{ + ENTER3("%p", nmb); + TODO(); + EXIT3(return NDIS_STATUS_SUCCESS); +} + +wstdcall void WIN_FUNC(NdisMCoActivateVcComplete,3) + (NDIS_STATUS status, void *handle, void *params) +{ + TODO(); +} + +wstdcall void WIN_FUNC(NdisMCoDeactivateVcComplete,2) + (NDIS_STATUS status, void *handle) +{ + TODO(); +} + +wstdcall void WIN_FUNC(NdisMRemoveMiniport,1) + (void *handle) +{ + TODO(); +} + +static void *ndis_get_routine_address(char *name) +{ + int i; + ENTER2("%p", name); + for (i = 0; i < sizeof(ndis_exports) / sizeof(ndis_exports[0]); i++) { + if (strcmp(name, ndis_exports[i].name) == 0) { + TRACE2("%p", ndis_exports[i].func); + return ndis_exports[i].func; + } + } + EXIT2(return NULL); +} + +/* ndis_init_device is called for each device */ +int ndis_init_device(struct ndis_device *wnd) +{ + struct ndis_mp_block *nmb = wnd->nmb; + + KeInitializeSpinLock(&nmb->lock); + wnd->mp_interrupt = NULL; + wnd->wrap_timer_slist.next = NULL; + if (wnd->wd->driver->ndis_driver) + wnd->wd->driver->ndis_driver->mp.shutdown = NULL; + + nmb->filterdbs.eth_db = nmb; + nmb->filterdbs.tr_db = nmb; + nmb->filterdbs.fddi_db = nmb; + nmb->filterdbs.arc_db = nmb; + + nmb->rx_packet = WIN_FUNC_PTR(NdisMIndicateReceivePacket,3); + nmb->send_complete = WIN_FUNC_PTR(NdisMSendComplete,3); + nmb->send_resource_avail = WIN_FUNC_PTR(NdisMSendResourcesAvailable,1); + nmb->status = WIN_FUNC_PTR(NdisMIndicateStatus,4); + nmb->status_complete = WIN_FUNC_PTR(NdisMIndicateStatusComplete,1); + nmb->queryinfo_complete = WIN_FUNC_PTR(NdisMQueryInformationComplete,2); + nmb->setinfo_complete = WIN_FUNC_PTR(NdisMSetInformationComplete,2); + nmb->reset_complete = WIN_FUNC_PTR(NdisMResetComplete,3); + nmb->eth_rx_indicate = WIN_FUNC_PTR(EthRxIndicateHandler,8); + nmb->eth_rx_complete = WIN_FUNC_PTR(EthRxComplete,1); + nmb->td_complete = WIN_FUNC_PTR(NdisMTransferDataComplete,4); + return 0; +} + +/* ndis_exit_device is called for each device */ +void ndis_exit_device(struct ndis_device *wnd) +{ + struct wrap_device_setting *setting; + ENTER2("%p", wnd); + if (down_interruptible(&loader_mutex)) + WARNING("couldn't obtain loader_mutex"); + nt_list_for_each_entry(setting, &wnd->wd->settings, list) { + struct ndis_configuration_parameter *param; + param = setting->encoded; + if (param) { + if (param->type == NdisParameterString) + RtlFreeUnicodeString(¶m->data.string); + ExFreePool(param); + setting->encoded = NULL; + } + } + up(&loader_mutex); +} + +/* ndis_init is called once when module is loaded */ +int ndis_init(void) +{ + InitializeListHead(&ndis_work_list); + spin_lock_init(&ndis_work_list_lock); + initialize_work(&ndis_work, ndis_worker, NULL); + + ndis_wq = create_singlethread_workqueue("ndis_wq"); + if (!ndis_wq) { + WARNING("couldn't create worker thread"); + EXIT1(return -ENOMEM); + } + + ndis_worker_thread = wrap_worker_init(ndis_wq); + TRACE1("%p", ndis_worker_thread); + return 0; +} + +/* ndis_exit is called once when module is removed */ +void ndis_exit(void) +{ + ENTER1(""); + if (ndis_wq) + destroy_workqueue(ndis_wq); + TRACE1("%p", ndis_worker_thread); + if (ndis_worker_thread) + ObDereferenceObject(ndis_worker_thread); + EXIT1(return); +} --- linux-2.6.28.orig/ubuntu/atl2/atl2.h +++ linux-2.6.28/ubuntu/atl2/atl2.h @@ -0,0 +1,120 @@ +/* atl2.h -- atl2 driver definitions + * + * Copyright(c) 2007 Atheros Corporation. All rights reserved. + * Copyright(c) 2006 xiong huang + * Copyright(c) 2007 Chris Snook + * + * Derived from Intel e1000 driver + * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _ATL2_H_ +#define _ATL2_H_ + +#include +#include + +#include "atl2_hw.h" + +struct atl2_ring_header { + /* pointer to the descriptor ring memory */ + void *desc; + /* physical adress of the descriptor ring */ + dma_addr_t dma; + /* length of descriptor ring in bytes */ + unsigned int size; +}; + +/* board specific private data structure */ +struct atl2_adapter { + /* OS defined structs */ + struct net_device *netdev; + struct pci_dev *pdev; + struct net_device_stats net_stats; +#ifdef NETIF_F_HW_VLAN_TX + struct vlan_group *vlgrp; +#endif + u32 wol; + u16 link_speed; + u16 link_duplex; + + spinlock_t stats_lock; + spinlock_t tx_lock; + + struct work_struct reset_task; + struct work_struct link_chg_task; + struct timer_list watchdog_timer; + struct timer_list phy_config_timer; + + unsigned long cfg_phy; + bool mac_disabled; + + /* All Descriptor memory */ + dma_addr_t ring_dma; + void *ring_vir_addr; + int ring_size; + + tx_pkt_header_t *txd_ring; + dma_addr_t txd_dma; + + tx_pkt_status_t *txs_ring; + dma_addr_t txs_dma; + + rx_desc_t *rxd_ring; + dma_addr_t rxd_dma; + + u32 txd_ring_size; // bytes per unit + u32 txs_ring_size; // dwords per unit + u32 rxd_ring_size; // 1536bytes per unit + + // read /write ptr: + // host + u32 txd_write_ptr; + u32 txs_next_clear; + u32 rxd_read_ptr; + + // nic + atomic_t txd_read_ptr; + atomic_t txs_write_ptr; + u32 rxd_write_ptr; + + /* Interrupt Moderator timer ( 2us resolution) */ + u16 imt; + /* Interrupt Clear timer (2us resolution) */ + u16 ict; + + unsigned long flags; + /* structs defined in atl2_hw.h */ + u32 bd_number; // board number; + bool pci_using_64; + bool have_msi; + struct atl2_hw hw; + + u32 usr_cmd; +// u32 regs_buff[ATL2_REGS_LEN]; + u32 pci_state[16]; + + u32 *config_space; +}; + +enum atl2_state_t { + __ATL2_TESTING, + __ATL2_RESETTING, + __ATL2_DOWN +}; + +#endif /* _ATL2_H_ */ --- linux-2.6.28.orig/ubuntu/atl2/Kconfig +++ linux-2.6.28/ubuntu/atl2/Kconfig @@ -0,0 +1,10 @@ +config ATL2 + tristate "Atheros L2 Fast Ethernet support (EXPERIMENTAL)" + depends on PCI && EXPERIMENTAL + select CRC32 + select MII + help + This driver supports the Atheros L2 fast ethernet adapter. + + To compile this driver as a module, choose M here. The module + will be called atl2. --- linux-2.6.28.orig/ubuntu/atl2/atl2_ethtool.c +++ linux-2.6.28/ubuntu/atl2/atl2_ethtool.c @@ -0,0 +1,416 @@ +/* atl2_ethtool.c -- atl2 ethtool support + * + * Copyright(c) 2007 Atheros Corporation. All rights reserved. + * Copyright(c) 2006 xiong huang + * Copyright(c) 2007 Chris Snook + * + * Derived from Intel e1000 driver + * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "atl2.h" +#include "atl2_hw.h" + +extern char atl2_driver_name[]; +extern char atl2_driver_version[]; + +extern int atl2_up(struct atl2_adapter *adapter); +extern void atl2_down(struct atl2_adapter *adapter); +extern void atl2_reinit_locked(struct atl2_adapter *adapter); +extern s32 atl2_reset_hw(struct atl2_hw *hw); + +static int +atl2_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + struct atl2_hw *hw = &adapter->hw; + + ecmd->supported = (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_Autoneg | + SUPPORTED_TP); + ecmd->advertising = ADVERTISED_TP; + + ecmd->advertising |= ADVERTISED_Autoneg; + ecmd->advertising |= hw->autoneg_advertised; + + ecmd->port = PORT_TP; + ecmd->phy_address = 0; + ecmd->transceiver = XCVR_INTERNAL; + + if (adapter->link_speed != SPEED_0) { + ecmd->speed = adapter->link_speed; + if (adapter->link_duplex == FULL_DUPLEX) + ecmd->duplex = DUPLEX_FULL; + else + ecmd->duplex = DUPLEX_HALF; + } else { + ecmd->speed = -1; + ecmd->duplex = -1; + } + + ecmd->autoneg = AUTONEG_ENABLE; + return 0; +} + +static int +atl2_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + struct atl2_hw *hw = &adapter->hw; + + while (test_and_set_bit(__ATL2_RESETTING, &adapter->flags)) + msleep(1); + + if (ecmd->autoneg == AUTONEG_ENABLE) { +#define MY_ADV_MASK (ADVERTISE_10_HALF| \ + ADVERTISE_10_FULL| \ + ADVERTISE_100_HALF| \ + ADVERTISE_100_FULL) + + if ((ecmd->advertising&MY_ADV_MASK) == MY_ADV_MASK) { + hw->MediaType = MEDIA_TYPE_AUTO_SENSOR; + hw->autoneg_advertised = MY_ADV_MASK; + } else if ((ecmd->advertising&MY_ADV_MASK) == ADVERTISE_100_FULL) { + hw->MediaType = MEDIA_TYPE_100M_FULL; + hw->autoneg_advertised = ADVERTISE_100_FULL; + } else if ((ecmd->advertising&MY_ADV_MASK) == ADVERTISE_100_HALF) { + hw->MediaType = MEDIA_TYPE_100M_HALF; + hw->autoneg_advertised = ADVERTISE_100_HALF; + } else if ((ecmd->advertising&MY_ADV_MASK) == ADVERTISE_10_FULL) { + hw->MediaType = MEDIA_TYPE_10M_FULL; + hw->autoneg_advertised = ADVERTISE_10_FULL; + } else if ((ecmd->advertising&MY_ADV_MASK) == ADVERTISE_10_HALF) { + hw->MediaType = MEDIA_TYPE_10M_HALF; + hw->autoneg_advertised = ADVERTISE_10_HALF; + } else { + clear_bit(__ATL2_RESETTING, &adapter->flags); + return -EINVAL; + } + ecmd->advertising = hw->autoneg_advertised | + ADVERTISED_TP | ADVERTISED_Autoneg; + } else { + clear_bit(__ATL2_RESETTING, &adapter->flags); + return -EINVAL; + } + + /* reset the link */ + if (netif_running(adapter->netdev)) { + atl2_down(adapter); + atl2_up(adapter); + } else + atl2_reset_hw(&adapter->hw); + + clear_bit(__ATL2_RESETTING, &adapter->flags); + return 0; +} + +static u32 +atl2_get_tx_csum(struct net_device *netdev) +{ + return (netdev->features & NETIF_F_HW_CSUM) != 0; +} + +static u32 +atl2_get_msglevel(struct net_device *netdev) +{ + return 0; +} + +/* + * It's sane for this to be empty, but we might want to take advantage of this. + */ +static void +atl2_set_msglevel(struct net_device *netdev, u32 data) +{ +} + +static int +atl2_get_regs_len(struct net_device *netdev) +{ +#define ATL2_REGS_LEN 42 + return ATL2_REGS_LEN * sizeof(u32); +} + +static void +atl2_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + struct atl2_hw *hw = &adapter->hw; + u32 *regs_buff = p; + u16 phy_data; + + memset(p, 0, ATL2_REGS_LEN * sizeof(u32)); + + regs->version = (1 << 24) | (hw->revision_id << 16) | hw->device_id; + + regs_buff[0] = ATL2_READ_REG(hw, REG_VPD_CAP); + regs_buff[1] = ATL2_READ_REG(hw, REG_SPI_FLASH_CTRL); + regs_buff[2] = ATL2_READ_REG(hw, REG_SPI_FLASH_CONFIG); + regs_buff[3] = ATL2_READ_REG(hw, REG_TWSI_CTRL); + regs_buff[4] = ATL2_READ_REG(hw, REG_PCIE_DEV_MISC_CTRL); + regs_buff[5] = ATL2_READ_REG(hw, REG_MASTER_CTRL); + regs_buff[6] = ATL2_READ_REG(hw, REG_MANUAL_TIMER_INIT); + regs_buff[7] = ATL2_READ_REG(hw, REG_IRQ_MODU_TIMER_INIT); + regs_buff[8] = ATL2_READ_REG(hw, REG_PHY_ENABLE); + regs_buff[9] = ATL2_READ_REG(hw, REG_CMBDISDMA_TIMER); + regs_buff[10] = ATL2_READ_REG(hw, REG_IDLE_STATUS); + regs_buff[11] = ATL2_READ_REG(hw, REG_MDIO_CTRL); + regs_buff[12] = ATL2_READ_REG(hw, REG_SERDES_LOCK); + regs_buff[13] = ATL2_READ_REG(hw, REG_MAC_CTRL); + regs_buff[14] = ATL2_READ_REG(hw, REG_MAC_IPG_IFG); + regs_buff[15] = ATL2_READ_REG(hw, REG_MAC_STA_ADDR); + regs_buff[16] = ATL2_READ_REG(hw, REG_MAC_STA_ADDR+4); + regs_buff[17] = ATL2_READ_REG(hw, REG_RX_HASH_TABLE); + regs_buff[18] = ATL2_READ_REG(hw, REG_RX_HASH_TABLE+4); + regs_buff[19] = ATL2_READ_REG(hw, REG_MAC_HALF_DUPLX_CTRL); + regs_buff[20] = ATL2_READ_REG(hw, REG_MTU); + regs_buff[21] = ATL2_READ_REG(hw, REG_WOL_CTRL); + regs_buff[22] = ATL2_READ_REG(hw, REG_SRAM_TXRAM_END); + regs_buff[23] = ATL2_READ_REG(hw, REG_DESC_BASE_ADDR_HI); + regs_buff[24] = ATL2_READ_REG(hw, REG_TXD_BASE_ADDR_LO); + regs_buff[25] = ATL2_READ_REG(hw, REG_TXD_MEM_SIZE); + regs_buff[26] = ATL2_READ_REG(hw, REG_TXS_BASE_ADDR_LO); + regs_buff[27] = ATL2_READ_REG(hw, REG_TXS_MEM_SIZE); + regs_buff[28] = ATL2_READ_REG(hw, REG_RXD_BASE_ADDR_LO); + regs_buff[29] = ATL2_READ_REG(hw, REG_RXD_BUF_NUM); + regs_buff[30] = ATL2_READ_REG(hw, REG_DMAR); + regs_buff[31] = ATL2_READ_REG(hw, REG_TX_CUT_THRESH); + regs_buff[32] = ATL2_READ_REG(hw, REG_DMAW); + regs_buff[33] = ATL2_READ_REG(hw, REG_PAUSE_ON_TH); + regs_buff[34] = ATL2_READ_REG(hw, REG_PAUSE_OFF_TH); + regs_buff[35] = ATL2_READ_REG(hw, REG_MB_TXD_WR_IDX); + regs_buff[36] = ATL2_READ_REG(hw, REG_MB_RXD_RD_IDX); + regs_buff[38] = ATL2_READ_REG(hw, REG_ISR); + regs_buff[39] = ATL2_READ_REG(hw, REG_IMR); + + atl2_read_phy_reg(hw, MII_BMCR, &phy_data); + regs_buff[40] = (u32)phy_data; + atl2_read_phy_reg(hw, MII_BMSR, &phy_data); + regs_buff[41] = (u32)phy_data; +} + +static int +atl2_get_eeprom_len(struct net_device *netdev) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + + if (!atl2_check_eeprom_exist(&adapter->hw)) { + return 512; + } else + return 0; +} + +static int +atl2_get_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, u8 *bytes) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + struct atl2_hw *hw = &adapter->hw; + u32 *eeprom_buff; + int first_dword, last_dword; + int ret_val = 0; + int i; + + if (eeprom->len == 0) + return -EINVAL; + + if (atl2_check_eeprom_exist(hw)) { + return -EINVAL; + } + + eeprom->magic = hw->vendor_id | (hw->device_id << 16); + + first_dword = eeprom->offset >> 2; + last_dword = (eeprom->offset + eeprom->len - 1) >> 2; + + eeprom_buff = kmalloc(sizeof(u32) * (last_dword - first_dword + 1), GFP_KERNEL); + if (!eeprom_buff) + return -ENOMEM; + + for (i=first_dword; i < last_dword; i++) { + if (!atl2_read_eeprom(hw, i*4, &(eeprom_buff[i-first_dword]))) + return -EIO; + } + + memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3), + eeprom->len); + kfree(eeprom_buff); + + return ret_val; +} + +static int +atl2_set_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, u8 *bytes) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + struct atl2_hw *hw = &adapter->hw; + u32 *eeprom_buff; + u32 *ptr; + int max_len, first_dword, last_dword, ret_val = 0; + int i; + + if (eeprom->len == 0) + return -EOPNOTSUPP; + + if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16))) + return -EFAULT; + + max_len = 512; + + first_dword = eeprom->offset >> 2; + last_dword = (eeprom->offset + eeprom->len - 1) >> 2; + eeprom_buff = kmalloc(max_len, GFP_KERNEL); + if (!eeprom_buff) + return -ENOMEM; + + ptr = (u32 *)eeprom_buff; + + if (eeprom->offset & 3) { + /* need read/modify/write of first changed EEPROM word */ + /* only the second byte of the word is being modified */ + if (!atl2_read_eeprom(hw, first_dword*4, &(eeprom_buff[0]))) + return -EIO; + ptr++; + } + if (((eeprom->offset + eeprom->len) & 3) ) { + /* need read/modify/write of last changed EEPROM word */ + /* only the first byte of the word is being modified */ + + if (!atl2_read_eeprom(hw, last_dword*4, &(eeprom_buff[last_dword - first_dword]))) + return -EIO; + } + + /* Device's eeprom is always little-endian, word addressable */ + memcpy(ptr, bytes, eeprom->len); + + for (i = 0; i < last_dword - first_dword + 1; i++) { + if (!atl2_write_eeprom(hw, ((first_dword+i)*4), eeprom_buff[i])) + return -EIO; + } + + kfree(eeprom_buff); + return ret_val; +} + +static void +atl2_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + + strncpy(drvinfo->driver, atl2_driver_name, 32); + strncpy(drvinfo->version, atl2_driver_version, 32); + strncpy(drvinfo->fw_version, "L2", 32); + strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); + drvinfo->n_stats = 0; + drvinfo->testinfo_len = 0; + drvinfo->regdump_len = atl2_get_regs_len(netdev); + drvinfo->eedump_len = atl2_get_eeprom_len(netdev); +} + +static void +atl2_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + + wol->supported = WAKE_MAGIC; + wol->wolopts = 0; + + if (adapter->wol & ATL2_WUFC_EX) + wol->wolopts |= WAKE_UCAST; + if (adapter->wol & ATL2_WUFC_MC) + wol->wolopts |= WAKE_MCAST; + if (adapter->wol & ATL2_WUFC_BC) + wol->wolopts |= WAKE_BCAST; + if (adapter->wol & ATL2_WUFC_MAG) + wol->wolopts |= WAKE_MAGIC; + if (adapter->wol & ATL2_WUFC_LNKC) + wol->wolopts |= WAKE_PHY; +} + +static int +atl2_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + + if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE)) + return -EOPNOTSUPP; + + if (wol->wolopts & (WAKE_MCAST|WAKE_BCAST|WAKE_MCAST)) + return -EOPNOTSUPP; + + /* these settings will always override what we currently have */ + adapter->wol = 0; + + if (wol->wolopts & WAKE_MAGIC) + adapter->wol |= ATL2_WUFC_MAG; + if (wol->wolopts & WAKE_PHY) + adapter->wol |= ATL2_WUFC_LNKC; + + return 0; +} + +static int +atl2_nway_reset(struct net_device *netdev) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + if (netif_running(netdev)) + atl2_reinit_locked(adapter); + return 0; +} + +static struct ethtool_ops atl2_ethtool_ops = { + .get_settings = atl2_get_settings, + .set_settings = atl2_set_settings, + .get_drvinfo = atl2_get_drvinfo, + .get_regs_len = atl2_get_regs_len, + .get_regs = atl2_get_regs, + .get_wol = atl2_get_wol, + .set_wol = atl2_set_wol, + .get_msglevel = atl2_get_msglevel, + .set_msglevel = atl2_set_msglevel, + .nway_reset = atl2_nway_reset, + .get_link = ethtool_op_get_link, + .get_eeprom_len = atl2_get_eeprom_len, + .get_eeprom = atl2_get_eeprom, + .set_eeprom = atl2_set_eeprom, + .get_tx_csum = atl2_get_tx_csum, + .get_sg = ethtool_op_get_sg, + .set_sg = ethtool_op_set_sg, +#ifdef NETIF_F_TSO + .get_tso = ethtool_op_get_tso, +#endif +#if 0 //FIXME: not implemented? +//#ifdef ETHTOOL_GPERMADDR + .get_perm_addr = ethtool_op_get_perm_addr, +#endif +}; + +void +atl2_set_ethtool_ops(struct net_device *netdev) +{ + SET_ETHTOOL_OPS(netdev, &atl2_ethtool_ops); +} --- linux-2.6.28.orig/ubuntu/atl2/Makefile +++ linux-2.6.28/ubuntu/atl2/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_ATL2) += atl2.o + +atl2-objs += atl2_main.o atl2_hw.o atl2_ethtool.o atl2_param.o --- linux-2.6.28.orig/ubuntu/atl2/atl2_param.c +++ linux-2.6.28/ubuntu/atl2/atl2_param.c @@ -0,0 +1,317 @@ +/* atl2_param.c -- atl2 parameter processing + * + * Copyright(c) 2007 Atheros Corporation. All rights reserved. + * Copyright(c) 2006 xiong huang + * Copyright(c) 2007 Chris Snook + * + * Derived from Intel e1000 driver + * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include "atl2.h" + +/* This is the only thing that needs to be changed to adjust the + * maximum number of ports that the driver can manage. + */ +#define ATL2_MAX_NIC 4 + +#define OPTION_UNSET -1 +#define OPTION_DISABLED 0 +#define OPTION_ENABLED 1 + +/* All parameters are treated the same, as an integer array of values. + * This macro just reduces the need to repeat the same declaration code + * over and over (plus this helps to avoid typo bugs). + */ +#define ATL2_PARAM_INIT { [0 ... ATL2_MAX_NIC] = OPTION_UNSET } +#ifndef module_param_array +/* Module Parameters are always initialized to -1, so that the driver + * can tell the difference between no user specified value or the + * user asking for the default value. + * The true default values are loaded in when atl2_check_options is called. + * + * This is a GCC extension to ANSI C. + * See the item "Labeled Elements in Initializers" in the section + * "Extensions to the C Language Family" of the GCC documentation. + */ + +#define ATL2_PARAM(X, desc) \ + static const int __devinitdata X[ATL2_MAX_NIC + 1] = ATL2_PARAM_INIT; \ + MODULE_PARM(X, "1-" __MODULE_STRING(ATL2_MAX_NIC) "i"); \ + MODULE_PARM_DESC(X, desc); +#else +#define ATL2_PARAM(X, desc) \ + static int __devinitdata X[ATL2_MAX_NIC+1] = ATL2_PARAM_INIT; \ + static int num_##X = 0; \ + module_param_array_named(X, X, int, &num_##X, 0); \ + MODULE_PARM_DESC(X, desc); +#endif + +/* Transmit Memory Size + * + * Valid Range: 64-2048 + * + * Default Value: 128 + */ +#define ATL2_MIN_TX_MEMSIZE 4 // 4KB +#define ATL2_MAX_TX_MEMSIZE 64 // 64KB +#define ATL2_DEFAULT_TX_MEMSIZE 8 // 8KB +ATL2_PARAM(TxMemSize, "Bytes of Transmit Memory"); + +/* Receive Memory Block Count + * + * Valid Range: 16-512 + * + * Default Value: 128 + */ +#define ATL2_MIN_RXD_COUNT 16 +#define ATL2_MAX_RXD_COUNT 512 +#define ATL2_DEFAULT_RXD_COUNT 64 +ATL2_PARAM(RxMemBlock, "Number of receive memory block"); + +/* User Specified MediaType Override + * + * Valid Range: 0-5 + * - 0 - auto-negotiate at all supported speeds + * - 1 - only link at 1000Mbps Full Duplex + * - 2 - only link at 100Mbps Full Duplex + * - 3 - only link at 100Mbps Half Duplex + * - 4 - only link at 10Mbps Full Duplex + * - 5 - only link at 10Mbps Half Duplex + * Default Value: 0 + */ +ATL2_PARAM(MediaType, "MediaType Select"); + +/* Interrupt Moderate Timer in units of 2 us + * + * Valid Range: 10-65535 + * + * Default Value: 45000(90ms) + */ +#define INT_MOD_DEFAULT_CNT 100 // 200us +#define INT_MOD_MAX_CNT 65000 +#define INT_MOD_MIN_CNT 50 +ATL2_PARAM(IntModTimer, "Interrupt Moderator Timer"); + +/* FlashVendor + * Valid Range: 0-2 + * 0 - Atmel + * 1 - SST + * 2 - ST + */ +ATL2_PARAM(FlashVendor, "SPI Flash Vendor"); + +#define AUTONEG_ADV_DEFAULT 0x2F +#define AUTONEG_ADV_MASK 0x2F +#define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL + +#define FLASH_VENDOR_DEFAULT 0 +#define FLASH_VENDOR_MIN 0 +#define FLASH_VENDOR_MAX 2 + +struct atl2_option { + enum { enable_option, range_option, list_option } type; + char *name; + char *err; + int def; + union { + struct { /* range_option info */ + int min; + int max; + } r; + struct { /* list_option info */ + int nr; + struct atl2_opt_list { int i; char *str; } *p; + } l; + } arg; +}; + +static int __devinit +atl2_validate_option(int *value, struct atl2_option *opt) +{ + int i; + struct atl2_opt_list *ent; + + if(*value == OPTION_UNSET) { + *value = opt->def; + return 0; + } + + switch (opt->type) { + case enable_option: + switch (*value) { + case OPTION_ENABLED: + printk(KERN_INFO "%s Enabled\n", opt->name); + return 0; + break; + case OPTION_DISABLED: + printk(KERN_INFO "%s Disabled\n", opt->name); + return 0; + break; + } + break; + case range_option: + if(*value >= opt->arg.r.min && *value <= opt->arg.r.max) { + printk(KERN_INFO "%s set to %i\n", opt->name, *value); + return 0; + } + break; + case list_option: + for(i = 0; i < opt->arg.l.nr; i++) { + ent = &opt->arg.l.p[i]; + if(*value == ent->i) { + if(ent->str[0] != '\0') + printk(KERN_INFO "%s\n", ent->str); + return 0; + } + } + break; + default: + BUG(); + } + + printk(KERN_INFO "Invalid %s specified (%i) %s\n", + opt->name, *value, opt->err); + *value = opt->def; + return -1; +} + +/** + * atl2_check_options - Range Checking for Command Line Parameters + * @adapter: board private structure + * + * This routine checks all command line parameters for valid user + * input. If an invalid value is given, or if no user specified + * value exists, a default value is used. The final value is stored + * in a variable in the adapter structure. + **/ +void __devinit +atl2_check_options(struct atl2_adapter *adapter) +{ + int val; + struct atl2_option opt; + int bd = adapter->bd_number; + if(bd >= ATL2_MAX_NIC) { + printk(KERN_NOTICE "Warning: no configuration for board #%i\n", bd); + printk(KERN_NOTICE "Using defaults for all values\n"); +#ifndef module_param_array + bd = ATL2_MAX_NIC; +#endif + } + + /* Bytes of Transmit Memory */ + opt.type = range_option; + opt.name = "Bytes of Transmit Memory"; + opt.err = "using default of " __MODULE_STRING(ATL2_DEFAULT_TX_MEMSIZE); + opt.def = ATL2_DEFAULT_TX_MEMSIZE; + opt.arg.r.min = ATL2_MIN_TX_MEMSIZE; + opt.arg.r.max = ATL2_MAX_TX_MEMSIZE; +#ifdef module_param_array + if(num_TxMemSize > bd) { +#endif + val = TxMemSize[bd]; + atl2_validate_option(&val, &opt); + adapter->txd_ring_size = ((u32) val) * 1024; +#ifdef module_param_array + } else { + adapter->txd_ring_size = ((u32)opt.def) * 1024; + } +#endif + // txs ring size: + adapter->txs_ring_size = adapter->txd_ring_size / 128; + if (adapter->txs_ring_size > 160) + adapter->txs_ring_size = 160; + + /* Receive Memory Block Count */ + opt.type = range_option; + opt.name = "Number of receive memory block"; + opt.err = "using default of " __MODULE_STRING(ATL2_DEFAULT_RXD_COUNT); + opt.def = ATL2_DEFAULT_RXD_COUNT; + opt.arg.r.min = ATL2_MIN_RXD_COUNT; + opt.arg.r.max = ATL2_MAX_RXD_COUNT; +#ifdef module_param_array + if(num_RxMemBlock > bd) { +#endif + val = RxMemBlock[bd]; + atl2_validate_option(&val, &opt); + adapter->rxd_ring_size = (u32)val; //((u16)val)&~1; // even number +#ifdef module_param_array + } else { + adapter->rxd_ring_size = (u32)opt.def; + } +#endif + // init RXD Flow control value + adapter->hw.fc_rxd_hi = (adapter->rxd_ring_size/8)*7; + adapter->hw.fc_rxd_lo = (ATL2_MIN_RXD_COUNT/8) > (adapter->rxd_ring_size/12) ? + (ATL2_MIN_RXD_COUNT/8) : (adapter->rxd_ring_size/12); + + /* Interrupt Moderate Timer */ + opt.type = range_option; + opt.name = "Interrupt Moderate Timer"; + opt.err = "using default of " __MODULE_STRING(INT_MOD_DEFAULT_CNT); + opt.def = INT_MOD_DEFAULT_CNT; + opt.arg.r.min = INT_MOD_MIN_CNT; + opt.arg.r.max = INT_MOD_MAX_CNT; +#ifdef module_param_array + if(num_IntModTimer > bd) { +#endif + val = IntModTimer[bd]; + atl2_validate_option(&val, &opt); + adapter->imt = (u16) val; +#ifdef module_param_array + } else { + adapter->imt = (u16)(opt.def); + } +#endif + /* Flash Vendor */ + opt.type = range_option; + opt.name = "SPI Flash Vendor"; + opt.err = "using default of " __MODULE_STRING(FLASH_VENDOR_DEFAULT); + opt.def = FLASH_VENDOR_DEFAULT; + opt.arg.r.min = FLASH_VENDOR_MIN; + opt.arg.r.max = FLASH_VENDOR_MAX; +#ifdef module_param_array + if(num_FlashVendor > bd) { +#endif + val = FlashVendor[bd]; + atl2_validate_option(&val, &opt); + adapter->hw.flash_vendor = (u8) val; +#ifdef module_param_array + } else { + adapter->hw.flash_vendor = (u8)(opt.def); + } +#endif + /* MediaType */ + opt.type = range_option; + opt.name = "Speed/Duplex Selection"; + opt.err = "using default of " __MODULE_STRING(MEDIA_TYPE_AUTO_SENSOR); + opt.def = MEDIA_TYPE_AUTO_SENSOR; + opt.arg.r.min = MEDIA_TYPE_AUTO_SENSOR; + opt.arg.r.max = MEDIA_TYPE_10M_HALF; +#ifdef module_param_array + if(num_MediaType > bd) { +#endif + val = MediaType[bd]; + atl2_validate_option(&val, &opt); + adapter->hw.MediaType = (u16) val; +#ifdef module_param_array + } else { + adapter->hw.MediaType = (u16)(opt.def); + } +#endif +} --- linux-2.6.28.orig/ubuntu/atl2/atl2_main.c +++ linux-2.6.28/ubuntu/atl2/atl2_main.c @@ -0,0 +1,1851 @@ +/* atl2_main.c -- atl2 driver main functions + * + * Copyright(c) 2007 Atheros Corporation. All rights reserved. + * Copyright(c) 2006 xiong huang + * Copyright(c) 2007 Chris Snook + * + * Derived from Intel e1000 driver + * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "atl2.h" + +#define ATL2_DRV_VERSION "2.0.4" + +char atl2_driver_name[] = "atl2"; +static const char atl2_driver_string[] = "Atheros(R) L2 Ethernet Driver"; +static char atl2_copyright[] = "Copyright (c) 2007 Atheros Corporation."; +char atl2_driver_version[] = ATL2_DRV_VERSION; + +MODULE_AUTHOR("Atheros Corporation , Chris Snook "); +MODULE_DESCRIPTION("Atheros Fast Ethernet Network Driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(ATL2_DRV_VERSION); + +/* FIXME: remove this after merging, goes in pci_ids.h */ +#ifndef PCI_DEVICE_ID_ATTANSIC_L2 +#define PCI_DEVICE_ID_ATTANSIC_L2 0x2048 +#endif + +/* + * atl2_pci_tbl - PCI Device ID Table + */ +static struct pci_device_id atl2_pci_tbl[] = { + {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L2)}, + /* required last entry */ + {0,} +}; +MODULE_DEVICE_TABLE(pci, atl2_pci_tbl); + +extern void atl2_set_ethtool_ops(struct net_device *netdev); +#ifdef ETHTOOL_OPS_COMPAT +extern int ethtool_ioctl(struct ifreq *ifr); +#endif + +#define COPYBREAK_DEFAULT 256 +static unsigned int copybreak __read_mostly = COPYBREAK_DEFAULT; +module_param(copybreak, uint, 0644); +MODULE_PARM_DESC(copybreak, "Maximum size of packet that is copied to a new buffer on receive"); + +extern void atl2_check_options(struct atl2_adapter *adapter); +#ifdef SIOCDEVPRIVATE +extern int atl2_priv_ioctl(struct net_device* netdev, struct ifreq* ifr); +#endif + +/** + * atl2_sw_init - Initialize general software structures (struct atl2_adapter) + * @adapter: board private structure to initialize + * + * atl2_sw_init initializes the Adapter private data structure. + * Fields are initialized based on PCI device information and + * OS network device settings (MTU size). + **/ +static int __devinit +atl2_sw_init(struct atl2_adapter *adapter) +{ + struct atl2_hw *hw = &adapter->hw; + struct pci_dev *pdev = adapter->pdev; + + /* PCI config space info */ + hw->vendor_id = pdev->vendor; + hw->device_id = pdev->device; + hw->subsystem_vendor_id = pdev->subsystem_vendor; + hw->subsystem_id = pdev->subsystem_device; + + pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id); + pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word); + + adapter->wol = 0; + adapter->ict = 50000; // 100ms + adapter->link_speed = SPEED_0; // hardware init + adapter->link_duplex = FULL_DUPLEX; + + hw->phy_configured = false; + hw->preamble_len = 7; + hw->ipgt = 0x60; + hw->min_ifg = 0x50; + hw->ipgr1 = 0x40; + hw->ipgr2 = 0x60; + hw->retry_buf = 2; + hw->max_retry = 0xf; + hw->lcol = 0x37; + hw->jam_ipg = 7; + hw->fc_rxd_hi = 0; + hw->fc_rxd_lo = 0; + hw->max_frame_size = adapter->netdev->mtu; + + spin_lock_init(&adapter->stats_lock); + spin_lock_init(&adapter->tx_lock); + + set_bit(__ATL2_DOWN, &adapter->flags); + + return 0; +} + +/** + * atl2_set_multi - Multicast and Promiscuous mode set + * @netdev: network interface device structure + * + * The set_multi entry point is called whenever the multicast address + * list or the network interface flags are updated. This routine is + * responsible for configuring the hardware for proper multicast, + * promiscuous mode, and all-multi behavior. + **/ +static void +atl2_set_multi(struct net_device *netdev) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + struct atl2_hw *hw = &adapter->hw; + struct dev_mc_list *mc_ptr; + u32 rctl; + u32 hash_value; + + /* Check for Promiscuous and All Multicast modes */ + rctl = ATL2_READ_REG(hw, REG_MAC_CTRL); + + if(netdev->flags & IFF_PROMISC) { + rctl |= MAC_CTRL_PROMIS_EN; + } else if(netdev->flags & IFF_ALLMULTI) { + rctl |= MAC_CTRL_MC_ALL_EN; + rctl &= ~MAC_CTRL_PROMIS_EN; + } else { + rctl &= ~(MAC_CTRL_PROMIS_EN | MAC_CTRL_MC_ALL_EN); + } + + ATL2_WRITE_REG(hw, REG_MAC_CTRL, rctl); + + /* clear the old settings from the multicast hash table */ + ATL2_WRITE_REG(hw, REG_RX_HASH_TABLE, 0); + ATL2_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0); + + /* comoute mc addresses' hash value ,and put it into hash table */ + for(mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) { + hash_value = atl2_hash_mc_addr(hw, mc_ptr->dmi_addr); + atl2_hash_set(hw, hash_value); + } +} + +static void +init_ring_ptrs(struct atl2_adapter *adapter) +{ + // Read / Write Ptr Initialize: + adapter->txd_write_ptr = 0; + atomic_set(&adapter->txd_read_ptr, 0); + + adapter->rxd_read_ptr = 0; + adapter->rxd_write_ptr = 0; + + atomic_set(&adapter->txs_write_ptr, 0); + adapter->txs_next_clear = 0; +} + +/** + * atl2_configure - Configure Transmit&Receive Unit after Reset + * @adapter: board private structure + * + * Configure the Tx /Rx unit of the MAC after a reset. + **/ +static int +atl2_configure(struct atl2_adapter *adapter) +{ + struct atl2_hw * hw = &adapter->hw; + u32 value; + + // clear interrupt status + ATL2_WRITE_REG(&adapter->hw, REG_ISR, 0xffffffff); + + // set MAC Address + value = (((u32)hw->mac_addr[2]) << 24) | + (((u32)hw->mac_addr[3]) << 16) | + (((u32)hw->mac_addr[4]) << 8 ) | + (((u32)hw->mac_addr[5]) ) ; + ATL2_WRITE_REG(hw, REG_MAC_STA_ADDR, value); + value = (((u32)hw->mac_addr[0]) << 8 ) | + (((u32)hw->mac_addr[1]) ) ; + ATL2_WRITE_REG(hw, (REG_MAC_STA_ADDR+4), value); + + // HI base address + ATL2_WRITE_REG(hw, REG_DESC_BASE_ADDR_HI, + (u32)((adapter->ring_dma & 0xffffffff00000000ULL) >> 32)); + + // LO base address + ATL2_WRITE_REG(hw, REG_TXD_BASE_ADDR_LO, + (u32)(adapter->txd_dma & 0x00000000ffffffffULL)); + ATL2_WRITE_REG(hw, REG_TXS_BASE_ADDR_LO, + (u32)(adapter->txs_dma & 0x00000000ffffffffULL)); + ATL2_WRITE_REG(hw, REG_RXD_BASE_ADDR_LO, + (u32)(adapter->rxd_dma & 0x00000000ffffffffULL)); + + // element count + ATL2_WRITE_REGW(hw, REG_TXD_MEM_SIZE, (u16)(adapter->txd_ring_size/4)); + ATL2_WRITE_REGW(hw, REG_TXS_MEM_SIZE, (u16)adapter->txs_ring_size); + ATL2_WRITE_REGW(hw, REG_RXD_BUF_NUM, (u16)adapter->rxd_ring_size); + + /* config Internal SRAM */ +/* + ATL2_WRITE_REGW(hw, REG_SRAM_TXRAM_END, sram_tx_end); + ATL2_WRITE_REGW(hw, REG_SRAM_TXRAM_END, sram_rx_end); +*/ + + /* config IPG/IFG */ + value = (((u32)hw->ipgt & MAC_IPG_IFG_IPGT_MASK) << MAC_IPG_IFG_IPGT_SHIFT) | + (((u32)hw->min_ifg & MAC_IPG_IFG_MIFG_MASK) << MAC_IPG_IFG_MIFG_SHIFT) | + (((u32)hw->ipgr1 & MAC_IPG_IFG_IPGR1_MASK) << MAC_IPG_IFG_IPGR1_SHIFT)| + (((u32)hw->ipgr2 & MAC_IPG_IFG_IPGR2_MASK) << MAC_IPG_IFG_IPGR2_SHIFT); + ATL2_WRITE_REG(hw, REG_MAC_IPG_IFG, value); + + /* config Half-Duplex Control */ + value = ((u32)hw->lcol & MAC_HALF_DUPLX_CTRL_LCOL_MASK) | + (((u32)hw->max_retry & MAC_HALF_DUPLX_CTRL_RETRY_MASK) << + MAC_HALF_DUPLX_CTRL_RETRY_SHIFT) | + MAC_HALF_DUPLX_CTRL_EXC_DEF_EN | + (0xa << MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT) | + (((u32)hw->jam_ipg & MAC_HALF_DUPLX_CTRL_JAMIPG_MASK) << + MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT); + ATL2_WRITE_REG(hw, REG_MAC_HALF_DUPLX_CTRL, value); + + /* set Interrupt Moderator Timer */ + ATL2_WRITE_REGW(hw, REG_IRQ_MODU_TIMER_INIT, adapter->imt); + ATL2_WRITE_REG(hw, REG_MASTER_CTRL, MASTER_CTRL_ITIMER_EN); + + /* set Interrupt Clear Timer */ + ATL2_WRITE_REGW(hw, REG_CMBDISDMA_TIMER, adapter->ict); + + /* set MTU */ + ATL2_WRITE_REG(hw, REG_MTU, adapter->netdev->mtu + + ENET_HEADER_SIZE + VLAN_SIZE + ETHERNET_FCS_SIZE); + + /* 1590 */ + ATL2_WRITE_REG(hw, REG_TX_CUT_THRESH, 0x177); + + /* flow control */ + ATL2_WRITE_REGW(hw, REG_PAUSE_ON_TH, hw->fc_rxd_hi); + ATL2_WRITE_REGW(hw, REG_PAUSE_OFF_TH, hw->fc_rxd_lo); + + /* Init mailbox */ + ATL2_WRITE_REGW(hw, REG_MB_TXD_WR_IDX, (u16)adapter->txd_write_ptr); + ATL2_WRITE_REGW(hw, REG_MB_RXD_RD_IDX, (u16)adapter->rxd_read_ptr); + + /* enable DMA read/write */ + ATL2_WRITE_REGB(hw, REG_DMAR, DMAR_EN); + ATL2_WRITE_REGB(hw, REG_DMAW, DMAW_EN); + + value = ATL2_READ_REG(&adapter->hw, REG_ISR); + if ((value & ISR_PHY_LINKDOWN) != 0) { + value = 1; // config failed + } else { + value = 0; + } + + // clear all interrupt status + ATL2_WRITE_REG(&adapter->hw, REG_ISR, 0x3fffffff); + ATL2_WRITE_REG(&adapter->hw, REG_ISR, 0); + return value; +} + +/** + * atl2_setup_ring_resources - allocate Tx / RX descriptor resources + * @adapter: board private structure + * + * Return 0 on success, negative on failure + **/ +static s32 +atl2_setup_ring_resources(struct atl2_adapter *adapter) +{ + struct pci_dev *pdev = adapter->pdev; + int size; + u8 offset = 0; + + /* real ring DMA buffer */ + adapter->ring_size = size = + adapter->txd_ring_size * 1 + 7 + // dword align + adapter->txs_ring_size * 4 + 7 + // dword align + adapter->rxd_ring_size * 1536 + 127; // 128bytes align + + adapter->ring_vir_addr = pci_alloc_consistent(pdev, size, &adapter->ring_dma); + if (!adapter->ring_vir_addr) { + return -ENOMEM; + } +#if 0 + if (adapter->pci_using_64) { + // test whether HIDWORD dma buffer is not cross boundary + if ( ((adapter->ring_dma &0xffffffff00000000ULL)>>32) + != (((adapter->ring_dma+size)&0xffffffff00000000ULL)>>32) ) { + pci_free_consistent(pdev, adapter->ring_size, adapter->ring_vir_addr, adapter->ring_dma); + DEBUGOUT("memory allocated cross 32bit boundary !"); + return -ENOMEM; + } + } +#endif + memset(adapter->ring_vir_addr, 0, adapter->ring_size); + + // Init TXD Ring + adapter->txd_dma = adapter->ring_dma ; + offset = (adapter->txd_dma & 0x7) ? (8 - (adapter->txd_dma & 0x7)) : 0; + adapter->txd_dma += offset; + adapter->txd_ring = (tx_pkt_header_t*) (adapter->ring_vir_addr + offset); + + // Init TXS Ring + adapter->txs_dma = adapter->txd_dma + adapter->txd_ring_size; + offset = (adapter->txs_dma & 0x7) ? (8- (adapter->txs_dma & 0x7)) : 0; + adapter->txs_dma += offset; + adapter->txs_ring = (tx_pkt_status_t*) + (((u8*)adapter->txd_ring) + (adapter->txd_ring_size+offset)); + + // Init RXD Ring + adapter->rxd_dma = adapter->txs_dma + adapter->txs_ring_size*4; + offset = (adapter->rxd_dma & 127) ? (128 - (adapter->rxd_dma & 127)) : 0; + if (offset > 7) { + offset -= 8; + } else { + offset += (128 - 8); + } + adapter->rxd_dma += offset; + adapter->rxd_ring = (rx_desc_t*) (((u8*)adapter->txs_ring) + + (adapter->txs_ring_size*4 + offset)); + +// Read / Write Ptr Initialize: +// init_ring_ptrs(adapter); + + return ATL2_SUCCESS; +} + +/** + * atl2_irq_enable - Enable default interrupt generation settings + * @adapter: board private structure + **/ +static inline void +atl2_irq_enable(struct atl2_adapter *adapter) +{ + ATL2_WRITE_REG(&adapter->hw, REG_IMR, IMR_NORMAL_MASK); + ATL2_WRITE_FLUSH(&adapter->hw); +} + +/** + * atl2_irq_disable - Mask off interrupt generation on the NIC + * @adapter: board private structure + **/ +static inline void +atl2_irq_disable(struct atl2_adapter *adapter) +{ + ATL2_WRITE_REG(&adapter->hw, REG_IMR, 0); + ATL2_WRITE_FLUSH(&adapter->hw); + synchronize_irq(adapter->pdev->irq); +} + +#ifdef NETIF_F_HW_VLAN_TX +static void +atl2_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + u32 ctrl; + + atl2_irq_disable(adapter); + adapter->vlgrp = grp; + + if(grp) { + /* enable VLAN tag insert/strip */ + ctrl = ATL2_READ_REG(&adapter->hw, REG_MAC_CTRL); + ctrl |= MAC_CTRL_RMV_VLAN; + ATL2_WRITE_REG(&adapter->hw, REG_MAC_CTRL, ctrl); + } else { + /* disable VLAN tag insert/strip */ + ctrl = ATL2_READ_REG(&adapter->hw, REG_MAC_CTRL); + ctrl &= ~MAC_CTRL_RMV_VLAN; + ATL2_WRITE_REG(&adapter->hw, REG_MAC_CTRL, ctrl); + } + + atl2_irq_enable(adapter); +} + +static void +atl2_restore_vlan(struct atl2_adapter *adapter) +{ + atl2_vlan_rx_register(adapter->netdev, adapter->vlgrp); +} +#endif + +static void +atl2_intr_rx(struct atl2_adapter* adapter) +{ + struct net_device *netdev = adapter->netdev; + rx_desc_t* rxd; + struct sk_buff* skb; + + do { + rxd = adapter->rxd_ring+adapter->rxd_write_ptr; + if (!rxd->status.update) + break; // end of tx + + // clear this flag at once + rxd->status.update = 0; + + if (rxd->status.ok && rxd->status.pkt_size >= 60) { + int rx_size = (int)(rxd->status.pkt_size - 4); + // alloc new buffer + skb = netdev_alloc_skb(netdev, rx_size + NET_IP_ALIGN); + if (NULL == skb) { + printk(KERN_WARNING"%s: Memory squeeze, deferring packet.\n", + netdev->name); + /* We should check that some rx space is free. + * If not, free one and mark stats->rx_dropped++. */ + adapter->net_stats.rx_dropped++; + break; + } +/* FIXME: ??? + if (rx_size > 1400) { + int s,c; + c = 0; + printk("rx_size= %d\n", rx_size); + for (s=0; s < 800; s++) { + if (0 == c) { + printk("%04x ", s); + } + printk("%02x ", rxd->packet[s]); + if (++c == 16) { + c = 0; + printk("\n"); + } + } + printk(KERN_WARNING"\n"); + } +*/ + skb_reserve(skb, NET_IP_ALIGN); + skb->dev = netdev; +/* gone in 2.6.23, just use memcpy? -- CHS + eth_copy_and_sum(skb, rxd->packet, rx_size, 0); */ + memcpy(skb->data, rxd->packet, rx_size); /* totally untested -- CHS */ + skb_put(skb, rx_size); + /* FIXME ??? + memcpy(skb_put(skb, rx_size), + rxd->packet, + rx_size); + */ + skb->protocol = eth_type_trans(skb, netdev); +#ifdef NETIF_F_HW_VLAN_TX + if(adapter->vlgrp && (rxd->status.vlan)) { + u16 vlan_tag = (rxd->status.vtag>>4) | + ((rxd->status.vtag&7) << 13) | + ((rxd->status.vtag&8) << 9); + vlan_hwaccel_rx(skb, adapter->vlgrp, vlan_tag); + } else +#endif + netif_rx(skb); + adapter->net_stats.rx_bytes += rx_size; + adapter->net_stats.rx_packets++; + netdev->last_rx = jiffies; + } else { + adapter->net_stats.rx_errors++; + + if (rxd->status.ok && rxd->status.pkt_size <= 60) { + adapter->net_stats.rx_length_errors++; + } + if (rxd->status.mcast) adapter->net_stats.multicast++; + if (rxd->status.crc) adapter->net_stats.rx_crc_errors++; + if (rxd->status.align) adapter->net_stats.rx_frame_errors++; + } + + // advance write ptr + if (++adapter->rxd_write_ptr == adapter->rxd_ring_size) + adapter->rxd_write_ptr = 0; + } while (1); + + // update mailbox ? + adapter->rxd_read_ptr = adapter->rxd_write_ptr; + ATL2_WRITE_REGW(&adapter->hw, REG_MB_RXD_RD_IDX, adapter->rxd_read_ptr); +} + +static void +atl2_intr_tx(struct atl2_adapter* adapter) +{ + u32 txd_read_ptr; + u32 txs_write_ptr; + tx_pkt_status_t* txs; + tx_pkt_header_t* txph; + int free_hole = 0; + + do { + txs_write_ptr = (u32) atomic_read(&adapter->txs_write_ptr); + txs = adapter->txs_ring + txs_write_ptr; + if (!txs->update) + break; // tx stop here + + free_hole = 1; + txs->update = 0; + + if (++txs_write_ptr == adapter->txs_ring_size) + txs_write_ptr = 0; + atomic_set(&adapter->txs_write_ptr, (int)txs_write_ptr); + + txd_read_ptr = (u32) atomic_read(&adapter->txd_read_ptr); + txph = (tx_pkt_header_t*) (((u8*)adapter->txd_ring) + txd_read_ptr); + + if ( txph->pkt_size != txs->pkt_size) { + tx_pkt_status_t* old_txs = txs; + printk(KERN_WARNING + "%s: txs packet size do not coinsist with txd" + " txd_:0x%08x, txs_:0x%08x!\n", + adapter->netdev->name, + *(u32*)txph, *(u32*)txs); + printk(KERN_WARNING + "txd read ptr: 0x%x\n", + txd_read_ptr); + txs = adapter->txs_ring + txs_write_ptr; + printk(KERN_WARNING + "txs-behind:0x%08x\n", + *(u32*)txs); + if (txs_write_ptr < 2) { + txs = adapter->txs_ring + + (adapter->txs_ring_size + + txs_write_ptr - 2); + } else { + txs = adapter->txs_ring + (txs_write_ptr - 2); + } + printk(KERN_WARNING + "txs-before:0x%08x\n", + *(u32*)txs); + txs = old_txs; + } + + txd_read_ptr += (((u32)(txph->pkt_size)+7)& ~3);//4for TPH + if (txd_read_ptr >= adapter->txd_ring_size) + txd_read_ptr -= adapter->txd_ring_size; + + atomic_set(&adapter->txd_read_ptr, (int)txd_read_ptr); + + // tx statistics: + if (txs->ok) + adapter->net_stats.tx_packets++; + else + adapter->net_stats.tx_errors++; + + if (txs->defer) adapter->net_stats.collisions++; + if (txs->abort_col) adapter->net_stats.tx_aborted_errors++; + if (txs->late_col) adapter->net_stats.tx_window_errors++; + if (txs->underun) adapter->net_stats.tx_fifo_errors++; + } while (1); + + if (free_hole) { + if(netif_queue_stopped(adapter->netdev) && + netif_carrier_ok(adapter->netdev)) + netif_wake_queue(adapter->netdev); + } +} + +static void +atl2_check_for_link(struct atl2_adapter* adapter) +{ + struct net_device *netdev = adapter->netdev; + u16 phy_data = 0; + + spin_lock(&adapter->stats_lock); + atl2_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data); + atl2_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data); + spin_unlock(&adapter->stats_lock); + + // notify upper layer link down ASAP + if (!(phy_data & BMSR_LSTATUS)) { // Link Down + if (netif_carrier_ok(netdev)) { // old link state: Up + printk(KERN_INFO "%s: %s NIC Link is Down\n", + atl2_driver_name, netdev->name); + adapter->link_speed = SPEED_0; + netif_carrier_off(netdev); + netif_stop_queue(netdev); + } + } + schedule_work(&adapter->link_chg_task); +} + +static inline void +atl2_clear_phy_int(struct atl2_adapter *adapter) +{ + u16 phy_data; + spin_lock(&adapter->stats_lock); + atl2_read_phy_reg(&adapter->hw, 19, &phy_data); + spin_unlock(&adapter->stats_lock); +} + +/** + * atl2_intr - Interrupt Handler + * @irq: interrupt number + * @data: pointer to a network interface device structure + * @pt_regs: CPU registers structure + **/ +static irqreturn_t +atl2_intr(int irq, void *data) +{ + struct atl2_adapter *adapter = netdev_priv(data); + struct atl2_hw *hw = &adapter->hw; + u32 status; + + status = ATL2_READ_REG(hw, REG_ISR); + if (0 == status) + return IRQ_NONE; + + // link event + if (status & ISR_PHY) { + atl2_clear_phy_int(adapter); + } + + // clear ISR status, and Enable CMB DMA/Disable Interrupt + ATL2_WRITE_REG(hw, REG_ISR, status | ISR_DIS_INT); + + // FIXME: if PCIe link is down, how did we read the register? -- CHS + // check if PCIE PHY Link down + if (status & ISR_PHY_LINKDOWN) { + if(netif_running(adapter->netdev)) { // reset MAC + ATL2_WRITE_REG(hw, REG_ISR, 0); + ATL2_WRITE_REG(hw, REG_IMR, 0); + ATL2_WRITE_FLUSH(hw); + schedule_work(&adapter->reset_task); + return IRQ_HANDLED; + } + } + + // check if DMA read/write error ? + if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) + { + //ATL2_WRITE_REG(&adapter->hw, REG_MASTER_CTRL, MASTER_CTRL_SOFT_RST); + ATL2_WRITE_REG(hw, REG_ISR, 0); + ATL2_WRITE_REG(hw, REG_IMR, 0); + ATL2_WRITE_FLUSH(hw); + schedule_work(&adapter->reset_task); + return IRQ_HANDLED; + } + + // link event + if (status & (ISR_PHY | ISR_MANUAL)) + { + adapter->net_stats.tx_carrier_errors++; + atl2_check_for_link(adapter); + } + + // transmit event + if (status & ISR_TX_EVENT) { + atl2_intr_tx(adapter); + } + + // rx exception + if (status & ISR_RX_EVENT) { + atl2_intr_rx(adapter); + } + + // re-enable Interrupt + ATL2_WRITE_REG(&adapter->hw, REG_ISR, 0); + return IRQ_HANDLED; +} + +static int +atl2_request_irq(struct atl2_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + int flags, err = 0; + + flags = IRQF_SHARED; +#ifdef CONFIG_PCI_MSI + adapter->have_msi = true; + if ((err = pci_enable_msi(adapter->pdev))) + adapter->have_msi = false; + + if (adapter->have_msi) + flags &= ~IRQF_SHARED; +#endif + + return request_irq(adapter->pdev->irq, &atl2_intr, flags, netdev->name, netdev); +} + +/** + * atl2_free_ring_resources - Free Tx / RX descriptor Resources + * @adapter: board private structure + * + * Free all transmit software resources + **/ +static void +atl2_free_ring_resources(struct atl2_adapter *adapter) +{ + struct pci_dev *pdev = adapter->pdev; + pci_free_consistent(pdev, adapter->ring_size, adapter->ring_vir_addr, adapter->ring_dma); +} + +/** + * atl2_open - Called when a network interface is made active + * @netdev: network interface device structure + * + * Returns 0 on success, negative value on failure + * + * The open entry point is called when a network interface is made + * active by the system (IFF_UP). At this point all resources needed + * for transmit and receive operations are allocated, the interrupt + * handler is registered with the OS, the watchdog timer is started, + * and the stack is notified that the interface is ready. + **/ +static int +atl2_open(struct net_device *netdev) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + int err; + u32 val; + + /* disallow open during test */ + if (test_bit(__ATL2_TESTING, &adapter->flags)) + return -EBUSY; + + /* allocate transmit descriptors */ + if((err = atl2_setup_ring_resources(adapter))) + return err; + + if((err = atl2_init_hw(&adapter->hw))) { + err = -EIO; + goto err_init_hw; + } + + /* hardware has been reset, we need to reload some things */ + atl2_set_multi(netdev); + init_ring_ptrs(adapter); + +#ifdef NETIF_F_HW_VLAN_TX + atl2_restore_vlan(adapter); +#endif + + if (atl2_configure(adapter)) { + err = -EIO; + goto err_config; + } + + if ((err = atl2_request_irq(adapter))) + goto err_req_irq; + + clear_bit(__ATL2_DOWN, &adapter->flags); + + mod_timer(&adapter->watchdog_timer, jiffies + 4*HZ); + + val = ATL2_READ_REG(&adapter->hw, REG_MASTER_CTRL); + ATL2_WRITE_REG(&adapter->hw, REG_MASTER_CTRL, val | MASTER_CTRL_MANUAL_INT); + + atl2_irq_enable(adapter); + + return 0; + +err_init_hw: +err_req_irq: +err_config: + atl2_free_ring_resources(adapter); + atl2_reset_hw(&adapter->hw); + + return err; +} + +void +atl2_down(struct atl2_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + + /* signal that we're down so the interrupt handler does not + * reschedule our watchdog timer */ + set_bit(__ATL2_DOWN, &adapter->flags); + +#ifdef NETIF_F_LLTX + netif_stop_queue(netdev); +#else + netif_tx_disable(netdev); +#endif + + /* reset MAC to disable all RX/TX */ + atl2_reset_hw(&adapter->hw); + msleep(1); + + atl2_irq_disable(adapter); + + del_timer_sync(&adapter->watchdog_timer); + del_timer_sync(&adapter->phy_config_timer); + clear_bit(0, &adapter->cfg_phy); + + netif_carrier_off(netdev); + adapter->link_speed = SPEED_0; + adapter->link_duplex = -1; + +// atl2_reset(adapter); +} + +static void +atl2_free_irq(struct atl2_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + + free_irq(adapter->pdev->irq, netdev); + +#ifdef CONFIG_PCI_MSI + if (adapter->have_msi) + pci_disable_msi(adapter->pdev); +#endif +} + +/** + * atl2_close - Disables a network interface + * @netdev: network interface device structure + * + * Returns 0, this is not allowed to fail + * + * The close entry point is called when an interface is de-activated + * by the OS. The hardware is still under the drivers control, but + * needs to be disabled. A global MAC reset is issued to stop the + * hardware, and all transmit and receive resources are freed. + **/ +static int +atl2_close(struct net_device *netdev) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + + WARN_ON(test_bit(__ATL2_RESETTING, &adapter->flags)); + + atl2_down(adapter); + atl2_free_irq(adapter); + atl2_free_ring_resources(adapter); + + return 0; +} + +static inline int +TxsFreeUnit(struct atl2_adapter *adapter) +{ + u32 txs_write_ptr = (u32) atomic_read(&adapter->txs_write_ptr); + + return (adapter->txs_next_clear >= txs_write_ptr) ? + (int) (adapter->txs_ring_size - adapter->txs_next_clear + + txs_write_ptr - 1) : + (int) (txs_write_ptr - adapter->txs_next_clear - 1); +} + +static inline int +TxdFreeBytes(struct atl2_adapter *adapter) +{ + u32 txd_read_ptr = (u32)atomic_read(&adapter->txd_read_ptr); + + return (adapter->txd_write_ptr >= txd_read_ptr) ? + (int) (adapter->txd_ring_size - adapter->txd_write_ptr + + txd_read_ptr - 1): + (int) (txd_read_ptr - adapter->txd_write_ptr - 1); +} + +static int +atl2_xmit_frame(struct sk_buff *skb, struct net_device *netdev) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + unsigned long flags; + tx_pkt_header_t* txph; + u32 offset, copy_len; + int txs_unused; + int txbuf_unused; + + if (test_bit(__ATL2_DOWN, &adapter->flags)) { + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; + } + + if (unlikely(skb->len <= 0)) { + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; + } + +#ifdef NETIF_F_LLTX + local_irq_save(flags); + if (!spin_trylock(&adapter->tx_lock)) { + /* Collision - tell upper layer to requeue */ + local_irq_restore(flags); + return NETDEV_TX_LOCKED; + } +#else + spin_lock_irqsave(&adapter->tx_lock, flags); +#endif + txs_unused = TxsFreeUnit(adapter); + txbuf_unused = TxdFreeBytes(adapter); + + if (txs_unused < 1 || skb->len > txbuf_unused) { + // no enough resource + netif_stop_queue(netdev); + spin_unlock_irqrestore(&adapter->tx_lock, flags); + return NETDEV_TX_BUSY; + } + + offset = adapter->txd_write_ptr; + + txph = (tx_pkt_header_t*) (((u8*)adapter->txd_ring)+offset); + + *(u32*)txph = 0; + txph->pkt_size = skb->len; + + offset += 4; + if (offset >= adapter->txd_ring_size) + offset -= adapter->txd_ring_size; + copy_len = adapter->txd_ring_size - offset; + if (copy_len >= skb->len) { + memcpy(((u8*)adapter->txd_ring)+offset, skb->data, skb->len); + offset += ((u32)(skb->len+3)&~3); + } else { + memcpy(((u8*)adapter->txd_ring)+offset, skb->data, copy_len); + memcpy((u8*)adapter->txd_ring, skb->data+copy_len, skb->len-copy_len); + offset = ((u32)(skb->len-copy_len+3)&~3); + } +#ifdef NETIF_F_HW_VLAN_TX + if (adapter->vlgrp && vlan_tx_tag_present(skb)) { + u16 vlan_tag = vlan_tx_tag_get(skb); + vlan_tag = (vlan_tag << 4) | + (vlan_tag >> 13) | + ((vlan_tag >>9) & 0x8); + txph->ins_vlan = 1; + txph->vlan = vlan_tag; + } +#endif + if (offset >= adapter->txd_ring_size) + offset -= adapter->txd_ring_size; + adapter->txd_write_ptr = offset; + + // clear txs before send + adapter->txs_ring[adapter->txs_next_clear].update = 0; + if (++adapter->txs_next_clear == adapter->txs_ring_size) + adapter->txs_next_clear = 0; + + ATL2_WRITE_REGW(&adapter->hw, REG_MB_TXD_WR_IDX, (adapter->txd_write_ptr >> 2)); + + spin_unlock_irqrestore(&adapter->tx_lock, flags); + + netdev->trans_start = jiffies; + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; +} + +/** + * atl2_get_stats - Get System Network Statistics + * @netdev: network interface device structure + * + * Returns the address of the device statistics structure. + * The statistics are actually updated from the timer callback. + **/ +static struct net_device_stats * +atl2_get_stats(struct net_device *netdev) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + + return &adapter->net_stats; +} + +/** + * atl2_change_mtu - Change the Maximum Transfer Unit + * @netdev: network interface device structure + * @new_mtu: new value for maximum frame size + * + * Returns 0 on success, negative on failure + **/ +static int +atl2_change_mtu(struct net_device *netdev, int new_mtu) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + struct atl2_hw *hw = &adapter->hw; + + if ((new_mtu < 40) || (new_mtu > (ETH_DATA_LEN + VLAN_SIZE))) + return -EINVAL; + + /* set MTU */ + if (hw->max_frame_size != new_mtu) { +// while (test_and_set_bit(__ATL2_RESETTING, &adapter->flags)) +// msleep(1); + netdev->mtu = new_mtu; + + ATL2_WRITE_REG(hw, REG_MTU, + new_mtu + ENET_HEADER_SIZE + VLAN_SIZE + ETHERNET_FCS_SIZE); +// clear_bit(__ATL2_RESETTING, &adapter->flags); + } + + return 0; +} + +/** + * atl2_set_mac - Change the Ethernet Address of the NIC + * @netdev: network interface device structure + * @p: pointer to an address structure + * + * Returns 0 on success, negative on failure + **/ +static int +atl2_set_mac(struct net_device *netdev, void *p) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + struct sockaddr *addr = p; + + if (!is_valid_ether_addr(addr->sa_data)) + return -EADDRNOTAVAIL; + + if (netif_running(netdev)) + return -EBUSY; + + memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); + memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len); + + atl2_set_mac_addr(&adapter->hw); + + return 0; +} + +/** + * atl2_mii_ioctl - + * @netdev: + * @ifreq: + * @cmd: + **/ +static int +atl2_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + struct mii_ioctl_data *data = if_mii(ifr); + unsigned long flags; + + switch (cmd) { + case SIOCGMIIPHY: + data->phy_id = 0; + break; + case SIOCGMIIREG: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + spin_lock_irqsave(&adapter->stats_lock, flags); + if (atl2_read_phy_reg(&adapter->hw, data->reg_num & 0x1F, &data->val_out)) { + spin_unlock_irqrestore(&adapter->stats_lock, flags); + return -EIO; + } + spin_unlock_irqrestore(&adapter->stats_lock, flags); + break; + case SIOCSMIIREG: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + if (data->reg_num & ~(0x1F)) + return -EFAULT; + spin_lock_irqsave(&adapter->stats_lock, flags); + if (atl2_write_phy_reg(&adapter->hw, data->reg_num, data->val_in)) { + spin_unlock_irqrestore(&adapter->stats_lock, flags); + return -EIO; + } + spin_unlock_irqrestore(&adapter->stats_lock, flags); + break; + default: + return -EOPNOTSUPP; + } + return ATL2_SUCCESS; +} + +/** + * atl2_ioctl - + * @netdev: + * @ifreq: + * @cmd: + **/ +static int +atl2_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) +{ + switch (cmd) { + case SIOCGMIIPHY: + case SIOCGMIIREG: + case SIOCSMIIREG: + return atl2_mii_ioctl(netdev, ifr, cmd); +#ifdef ETHTOOL_OPS_COMPAT + case SIOCETHTOOL: + return ethtool_ioctl(ifr); +#endif + default: + return -EOPNOTSUPP; + } +} + +/** + * atl2_tx_timeout - Respond to a Tx Hang + * @netdev: network interface device structure + **/ +static void +atl2_tx_timeout(struct net_device *netdev) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + + /* Do the reset outside of interrupt context */ + schedule_work(&adapter->reset_task); +} + +/** + * atl2_watchdog - Timer Call-back + * @data: pointer to netdev cast into an unsigned long + **/ +static void +atl2_watchdog(unsigned long data) +{ + struct atl2_adapter *adapter = (struct atl2_adapter *) data; + u32 drop_rxd, drop_rxs; + unsigned long flags; + + if (!test_bit(__ATL2_DOWN, &adapter->flags)) { + spin_lock_irqsave(&adapter->stats_lock, flags); + drop_rxd = ATL2_READ_REG(&adapter->hw, REG_STS_RXD_OV); + drop_rxs = ATL2_READ_REG(&adapter->hw, REG_STS_RXS_OV); + adapter->net_stats.rx_over_errors += (drop_rxd+drop_rxs); + spin_unlock_irqrestore(&adapter->stats_lock, flags); + + /* Reset the timer */ + mod_timer(&adapter->watchdog_timer, jiffies + 4 * HZ); + } +} + +/** + * atl2_phy_config - Timer Call-back + * @data: pointer to netdev cast into an unsigned long + **/ +static void +atl2_phy_config(unsigned long data) +{ + struct atl2_adapter *adapter = (struct atl2_adapter *) data; + struct atl2_hw *hw = &adapter->hw; + unsigned long flags; + + spin_lock_irqsave(&adapter->stats_lock, flags); + atl2_write_phy_reg(hw, MII_ADVERTISE, hw->mii_autoneg_adv_reg); + atl2_write_phy_reg(hw, MII_BMCR, MII_CR_RESET|MII_CR_AUTO_NEG_EN|MII_CR_RESTART_AUTO_NEG); + spin_unlock_irqrestore(&adapter->stats_lock, flags); + clear_bit(0, &adapter->cfg_phy); +} + +int +atl2_up(struct atl2_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + int err = 0; + u32 val; + + /* hardware has been reset, we need to reload some things */ + + err = atl2_init_hw(&adapter->hw); + if (err) { + err = -EIO; + return err; + } + + atl2_set_multi(netdev); + init_ring_ptrs(adapter); + +#ifdef NETIF_F_HW_VLAN_TX + atl2_restore_vlan(adapter); +#endif + + if (atl2_configure(adapter)) { + err = -EIO; + goto err_up; + } + + clear_bit(__ATL2_DOWN, &adapter->flags); + + val = ATL2_READ_REG(&adapter->hw, REG_MASTER_CTRL); + ATL2_WRITE_REG(&adapter->hw, REG_MASTER_CTRL, val | MASTER_CTRL_MANUAL_INT); + + atl2_irq_enable(adapter); + +err_up: + return err; +} + +void +atl2_reinit_locked(struct atl2_adapter *adapter) +{ + WARN_ON(in_interrupt()); + while (test_and_set_bit(__ATL2_RESETTING, &adapter->flags)) + msleep(1); + atl2_down(adapter); + atl2_up(adapter); + clear_bit(__ATL2_RESETTING, &adapter->flags); +} + +static void +atl2_reset_task(struct work_struct *work) +{ + struct atl2_adapter *adapter; + adapter = container_of(work, struct atl2_adapter, reset_task); + + atl2_reinit_locked(adapter); +} + +static inline void +atl2_setup_mac_ctrl(struct atl2_adapter *adapter) +{ + u32 value; + struct atl2_hw* hw = &adapter->hw; + struct net_device* netdev = adapter->netdev; + + /* Config MAC CTRL Register */ + value = MAC_CTRL_TX_EN | MAC_CTRL_RX_EN | MAC_CTRL_MACLP_CLK_PHY; + + // duplex + if (FULL_DUPLEX == adapter->link_duplex) + value |= MAC_CTRL_DUPLX; + + // flow control + value |= (MAC_CTRL_TX_FLOW | MAC_CTRL_RX_FLOW); + + // PAD & CRC + value |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD); + + // preamble length + value |= (((u32)adapter->hw.preamble_len & MAC_CTRL_PRMLEN_MASK) << + MAC_CTRL_PRMLEN_SHIFT); + + // vlan + if (adapter->vlgrp) + value |= MAC_CTRL_RMV_VLAN; + + // filter mode + value |= MAC_CTRL_BC_EN; + if (netdev->flags & IFF_PROMISC) + value |= MAC_CTRL_PROMIS_EN; + else if (netdev->flags & IFF_ALLMULTI) + value |= MAC_CTRL_MC_ALL_EN; + + // half retry buffer + value |= (((u32)(adapter->hw.retry_buf & MAC_CTRL_HALF_LEFT_BUF_MASK)) << + MAC_CTRL_HALF_LEFT_BUF_SHIFT); + + ATL2_WRITE_REG(hw, REG_MAC_CTRL, value); +} + +static int +atl2_check_link(struct atl2_adapter *adapter) +{ + struct atl2_hw *hw = &adapter->hw; + struct net_device * netdev = adapter->netdev; + int ret_val; + u16 speed, duplex, phy_data; + int reconfig = 0; + + // MII_BMSR must read twise + atl2_read_phy_reg(hw, MII_BMSR, &phy_data); + atl2_read_phy_reg(hw, MII_BMSR, &phy_data); + if (!(phy_data&BMSR_LSTATUS)) { // link down + if (netif_carrier_ok(netdev)) { // old link state: Up + u32 value; + //disable rx + value = ATL2_READ_REG(hw, REG_MAC_CTRL); + value &= ~MAC_CTRL_RX_EN; + ATL2_WRITE_REG(hw, REG_MAC_CTRL, value); + adapter->link_speed = SPEED_0; + netif_carrier_off(netdev); + netif_stop_queue(netdev); + } + return ATL2_SUCCESS; + } + + // Link Up + ret_val = atl2_get_speed_and_duplex(hw, &speed, &duplex); + if (ret_val) + return ret_val; + switch( hw->MediaType ) { + case MEDIA_TYPE_100M_FULL: + if (speed != SPEED_100 || duplex != FULL_DUPLEX) + reconfig = 1; + break; + case MEDIA_TYPE_100M_HALF: + if (speed != SPEED_100 || duplex != HALF_DUPLEX) + reconfig = 1; + break; + case MEDIA_TYPE_10M_FULL: + if (speed != SPEED_10 || duplex != FULL_DUPLEX) + reconfig = 1; + break; + case MEDIA_TYPE_10M_HALF: + if (speed != SPEED_10 || duplex != HALF_DUPLEX) + reconfig = 1; + break; + } + // link result is our setting + if (0 == reconfig) { + if (adapter->link_speed != speed || adapter->link_duplex != duplex ) { + adapter->link_speed = speed; + adapter->link_duplex = duplex; + atl2_setup_mac_ctrl(adapter); + printk(KERN_INFO "%s: %s NIC Link is Up<%d Mbps %s>\n", + atl2_driver_name, netdev->name, + adapter->link_speed, + adapter->link_duplex == FULL_DUPLEX ? + "Full Duplex" : "Half Duplex"); + } + + if (!netif_carrier_ok(netdev)) { // Link down -> Up + netif_carrier_on(netdev); + netif_wake_queue(netdev); + } + return ATL2_SUCCESS; + } + + // change orignal link status + if (netif_carrier_ok(netdev)) { + u32 value; + // disable rx + value = ATL2_READ_REG(hw, REG_MAC_CTRL); + value &= ~MAC_CTRL_RX_EN; + ATL2_WRITE_REG(hw, REG_MAC_CTRL, value); + + adapter->link_speed = SPEED_0; + netif_carrier_off(netdev); + netif_stop_queue(netdev); + } + + // auto-neg, insert timer to re-config phy (if interval smaller than 5 seconds, something strange) + if (!test_bit(__ATL2_DOWN, &adapter->flags)) { + if (!test_and_set_bit(0, &adapter->cfg_phy)) { + mod_timer(&adapter->phy_config_timer, jiffies + 5 * HZ); + } + } + + return ATL2_SUCCESS; +} + +/** + * atl2_link_chg_task - deal with link change event Out of interrupt context + * @netdev: network interface device structure + **/ +static void +atl2_link_chg_task(struct work_struct *work) +{ + struct atl2_adapter *adapter; + unsigned long flags; + + adapter = container_of(work, struct atl2_adapter, link_chg_task); + + spin_lock_irqsave(&adapter->stats_lock, flags); + atl2_check_link(adapter); + spin_unlock_irqrestore(&adapter->stats_lock, flags); +} + +static void +atl2_setup_pcicmd(struct pci_dev *pdev) +{ + u16 cmd; + + pci_read_config_word(pdev, PCI_COMMAND, &cmd); + + if (cmd & PCI_COMMAND_INTX_DISABLE) + cmd &= ~PCI_COMMAND_INTX_DISABLE; + if (cmd & PCI_COMMAND_IO) + cmd &= ~PCI_COMMAND_IO; + if (0 == (cmd & PCI_COMMAND_MEMORY)) + cmd |= PCI_COMMAND_MEMORY; + if (0 == (cmd & PCI_COMMAND_MASTER)) + cmd |= PCI_COMMAND_MASTER; + pci_write_config_word(pdev, PCI_COMMAND, cmd); + + /* + * some motherboards BIOS(PXE/EFI) driver may set PME + * while they transfer control to OS (Windows/Linux) + * so we should clear this bit before NIC work normally + */ + pci_write_config_dword(pdev, REG_PM_CTRLSTAT, 0); +} + +/** + * atl2_probe - Device Initialization Routine + * @pdev: PCI device information struct + * @ent: entry in atl2_pci_tbl + * + * Returns 0 on success, negative on failure + * + * atl2_probe initializes an adapter identified by a pci_dev structure. + * The OS initialization, configuring of the adapter private structure, + * and a hardware reset occur. + **/ +static int __devinit +atl2_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + struct net_device *netdev; + struct atl2_adapter *adapter; + static int cards_found = 0; + unsigned long mmio_start; + int mmio_len; + int err; + + if((err = pci_enable_device(pdev))) + return err; + + /* + * atl2 is a shared-high-32-bit device, so we're stuck with 32-bit DMA + * until the kernel has the proper infrastructure to support 64-bit DMA + * on these devices. + */ + if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) && + (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))) { + printk(KERN_ERR "atl2: No usable DMA configuration, aborting\n"); + goto err_dma; + } + + // Mark all PCI regions associated with PCI device + // pdev as being reserved by owner atl2_driver_name + if((err = pci_request_regions(pdev, atl2_driver_name))) + goto err_pci_reg; + + // Enables bus-mastering on the device and calls + // pcibios_set_master to do the needed arch specific settings + pci_set_master(pdev); + + err = -ENOMEM; + netdev = alloc_etherdev(sizeof(struct atl2_adapter)); + if(!netdev) + goto err_alloc_etherdev; + + SET_NETDEV_DEV(netdev, &pdev->dev); + + pci_set_drvdata(pdev, netdev); + adapter = netdev_priv(netdev); + adapter->netdev = netdev; + adapter->pdev = pdev; + adapter->hw.back = adapter; + + mmio_start = pci_resource_start(pdev, 0x0); + mmio_len = pci_resource_len(pdev, 0x0); + + adapter->hw.mem_rang = (u32)mmio_len; + adapter->hw.hw_addr = ioremap(mmio_start, mmio_len); + if(!adapter->hw.hw_addr) { + err = -EIO; + goto err_ioremap; + } + + atl2_setup_pcicmd(pdev); + + netdev->open = &atl2_open; + netdev->stop = &atl2_close; + netdev->hard_start_xmit = &atl2_xmit_frame; + netdev->get_stats = &atl2_get_stats; + netdev->set_multicast_list = &atl2_set_multi; + netdev->set_mac_address = &atl2_set_mac; + netdev->change_mtu = &atl2_change_mtu; + netdev->do_ioctl = &atl2_ioctl; + atl2_set_ethtool_ops(netdev); + +#ifdef HAVE_TX_TIMEOUT + netdev->tx_timeout = &atl2_tx_timeout; + netdev->watchdog_timeo = 5 * HZ; //FIXME -- CHS +#endif +#ifdef NETIF_F_HW_VLAN_TX + netdev->vlan_rx_register = atl2_vlan_rx_register; +#endif + strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1); + + netdev->mem_start = mmio_start; + netdev->mem_end = mmio_start + mmio_len; + //netdev->base_addr = adapter->io_base; + adapter->bd_number = cards_found; + adapter->pci_using_64 = false; + + /* setup the private structure */ + + if((err = atl2_sw_init(adapter))) + goto err_sw_init; + + err = -EIO; + +#ifdef NETIF_F_HW_VLAN_TX + netdev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX ); +#endif + +#ifdef NETIF_F_LLTX + netdev->features |= NETIF_F_LLTX; +#endif + + /* Init PHY as early as possible due to power saving issue */ + atl2_phy_init(&adapter->hw); + + /* reset the controller to + * put the device in a known good starting state */ + + if (atl2_reset_hw(&adapter->hw)) { + err = -EIO; + goto err_reset; + } + + /* copy the MAC address out of the EEPROM */ + atl2_read_mac_addr(&adapter->hw); + memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len); +//FIXME: do we still need this? +#ifdef ETHTOOL_GPERMADDR + memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len); + + if (!is_valid_ether_addr(netdev->perm_addr)) { +#else + if (!is_valid_ether_addr(netdev->dev_addr)) { +#endif + err = -EIO; + goto err_eeprom; + } + + atl2_check_options(adapter); + + init_timer(&adapter->watchdog_timer); + adapter->watchdog_timer.function = &atl2_watchdog; + adapter->watchdog_timer.data = (unsigned long) adapter; + + init_timer(&adapter->phy_config_timer); + adapter->phy_config_timer.function = &atl2_phy_config; + adapter->phy_config_timer.data = (unsigned long) adapter; + + INIT_WORK(&adapter->reset_task, atl2_reset_task); + INIT_WORK(&adapter->link_chg_task, atl2_link_chg_task); + + strcpy(netdev->name, "eth%d"); // ?? + if((err = register_netdev(netdev))) + goto err_register; + + /* assume we have no link for now */ + netif_carrier_off(netdev); + netif_stop_queue(netdev); + + cards_found++; + + return 0; + +//err_init_hw: +err_reset: +err_register: +err_sw_init: +err_eeprom: + iounmap(adapter->hw.hw_addr); +err_ioremap: + free_netdev(netdev); +err_alloc_etherdev: + pci_release_regions(pdev); +err_pci_reg: +err_dma: + pci_disable_device(pdev); + return err; +} + +/** + * atl2_remove - Device Removal Routine + * @pdev: PCI device information struct + * + * atl2_remove is called by the PCI subsystem to alert the driver + * that it should release a PCI device. The could be caused by a + * Hot-Plug event, or because the driver is going to be removed from + * memory. + **/ +/* FIXME: write the original MAC address back in case it was changed from a + * BIOS-set value, as in atl1 -- CHS */ +static void __devexit +atl2_remove(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct atl2_adapter *adapter = netdev_priv(netdev); + + /* flush_scheduled work may reschedule our watchdog task, so + * explicitly disable watchdog tasks from being rescheduled */ + set_bit(__ATL2_DOWN, &adapter->flags); + + del_timer_sync(&adapter->watchdog_timer); + del_timer_sync(&adapter->phy_config_timer); + + flush_scheduled_work(); + + unregister_netdev(netdev); + + atl2_force_ps(&adapter->hw); + + iounmap(adapter->hw.hw_addr); + pci_release_regions(pdev); + + free_netdev(netdev); + + pci_disable_device(pdev); +} + +static int +atl2_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct atl2_adapter *adapter = netdev_priv(netdev); + struct atl2_hw * hw = &adapter->hw; + u16 speed, duplex; + u32 ctrl = 0; + u32 wufc = adapter->wol; + +#ifdef CONFIG_PM + int retval = 0; +#endif + + netif_device_detach(netdev); + + if (netif_running(netdev)) { + WARN_ON(test_bit(__ATL2_RESETTING, &adapter->flags)); + atl2_down(adapter); + } + +#ifdef CONFIG_PM + retval = pci_save_state(pdev); + if (retval) + return retval; +#endif + + atl2_read_phy_reg(hw, MII_BMSR, (u16*)&ctrl); + atl2_read_phy_reg(hw, MII_BMSR, (u16*)&ctrl); + if(ctrl & BMSR_LSTATUS) + wufc &= ~ATL2_WUFC_LNKC; + + if (0 != (ctrl & BMSR_LSTATUS) && 0 != wufc) { + u32 ret_val; + /* get current link speed & duplex */ + ret_val = atl2_get_speed_and_duplex(hw, &speed, &duplex); + if (ret_val) { + printk(KERN_DEBUG "%s: get speed&duplex error while suspend\n", atl2_driver_name); + goto wol_dis; + } + + ctrl = 0; + + /* turn on magic packet wol */ + if (wufc & ATL2_WUFC_MAG) + ctrl |= (WOL_MAGIC_EN | WOL_MAGIC_PME_EN); + + /* ignore Link Chg event when Link is up */ + ATL2_WRITE_REG(hw, REG_WOL_CTRL, ctrl); + + /* Config MAC CTRL Register */ + ctrl = MAC_CTRL_RX_EN | MAC_CTRL_MACLP_CLK_PHY; + if (FULL_DUPLEX == adapter->link_duplex) + ctrl |= MAC_CTRL_DUPLX; + ctrl |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD); + ctrl |= (((u32)adapter->hw.preamble_len & + MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT); + ctrl |= (((u32)(adapter->hw.retry_buf & + MAC_CTRL_HALF_LEFT_BUF_MASK)) << + MAC_CTRL_HALF_LEFT_BUF_SHIFT); + if (wufc & ATL2_WUFC_MAG) { + /* magic packet maybe Broadcast&multicast&Unicast frame */ + ctrl |= MAC_CTRL_BC_EN; + } + + ATL2_WRITE_REG(hw, REG_MAC_CTRL, ctrl); + + /* pcie patch */ + ctrl = ATL2_READ_REG(hw, REG_PCIE_PHYMISC); + ctrl |= PCIE_PHYMISC_FORCE_RCV_DET; + ATL2_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl); + ctrl = ATL2_READ_REG(hw, REG_PCIE_DLL_TX_CTRL1); + ctrl |= PCIE_DLL_TX_CTRL1_SEL_NOR_CLK; + ATL2_WRITE_REG(hw, REG_PCIE_DLL_TX_CTRL1, ctrl); + + pci_enable_wake(pdev, pci_choose_state(pdev, state), 1); + goto suspend_exit; + } + + if (0 == (ctrl&BMSR_LSTATUS) && 0 != (wufc&ATL2_WUFC_LNKC)) { + /* link is down, so only LINK CHG WOL event enable */ + ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN); + ATL2_WRITE_REG(hw, REG_WOL_CTRL, ctrl); + ATL2_WRITE_REG(hw, REG_MAC_CTRL, 0); + + /* pcie patch */ + ctrl = ATL2_READ_REG(hw, REG_PCIE_PHYMISC); + ctrl |= PCIE_PHYMISC_FORCE_RCV_DET; + ATL2_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl); + ctrl = ATL2_READ_REG(hw, REG_PCIE_DLL_TX_CTRL1); + ctrl |= PCIE_DLL_TX_CTRL1_SEL_NOR_CLK; + ATL2_WRITE_REG(hw, REG_PCIE_DLL_TX_CTRL1, ctrl); + + hw->phy_configured = false; /* re-init PHY when resume */ + + pci_enable_wake(pdev, pci_choose_state(pdev, state), 1); + + goto suspend_exit; + } + +wol_dis: + /* WOL disabled */ + ATL2_WRITE_REG(hw, REG_WOL_CTRL, 0); + + /* pcie patch */ + ctrl = ATL2_READ_REG(hw, REG_PCIE_PHYMISC); + ctrl |= PCIE_PHYMISC_FORCE_RCV_DET; + ATL2_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl); + ctrl = ATL2_READ_REG(hw, REG_PCIE_DLL_TX_CTRL1); + ctrl |= PCIE_DLL_TX_CTRL1_SEL_NOR_CLK; + ATL2_WRITE_REG(hw, REG_PCIE_DLL_TX_CTRL1, ctrl); + + atl2_force_ps(hw); + hw->phy_configured = false; /* re-init PHY when resume */ + + pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); + +suspend_exit: + if (netif_running(netdev)) + atl2_free_irq(adapter); + + pci_disable_device(pdev); + + pci_set_power_state(pdev, pci_choose_state(pdev, state)); + + return 0; +} + +#ifdef CONFIG_PM +static int +atl2_resume(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct atl2_adapter *adapter = netdev_priv(netdev); + u32 err; + + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + + if ((err = pci_enable_device(pdev))) { + printk(KERN_ERR "atl2: Cannot enable PCI device from suspend\n"); + return err; + } + + pci_set_master(pdev); + + ATL2_READ_REG(&adapter->hw, REG_WOL_CTRL); /* clear WOL status */ + + pci_enable_wake(pdev, PCI_D3hot, 0); + pci_enable_wake(pdev, PCI_D3cold, 0); + + ATL2_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0); + + if (netif_running(netdev) && (err = atl2_request_irq(adapter))) + return err; + + atl2_reset_hw(&adapter->hw); + + if(netif_running(netdev)) + atl2_up(adapter); + + netif_device_attach(netdev); + + return 0; +} +#endif + +static void +atl2_shutdown(struct pci_dev *pdev) +{ + atl2_suspend(pdev, PMSG_SUSPEND); +} + +static struct pci_driver atl2_driver = { + .name = atl2_driver_name, + .id_table = atl2_pci_tbl, + .probe = atl2_probe, + .remove = __devexit_p(atl2_remove), + /* Power Managment Hooks */ + .suspend = atl2_suspend, +#ifdef CONFIG_PM + .resume = atl2_resume, +#endif + .shutdown = atl2_shutdown, +}; + +/** + * atl2_init_module - Driver Registration Routine + * + * atl2_init_module is the first routine called when the driver is + * loaded. All it does is register with the PCI subsystem. + **/ +static int __init +atl2_init_module(void) +{ + int ret; + printk(KERN_INFO "%s - version %s\n", atl2_driver_string, atl2_driver_version); + printk(KERN_INFO "%s\n", atl2_copyright); + + ret = pci_register_driver(&atl2_driver); + if (copybreak != COPYBREAK_DEFAULT) { + if (copybreak == 0) + printk(KERN_INFO "atl2: copybreak disabled\n"); + else + printk(KERN_INFO "atl2: copybreak enabled for packets <= %u bytes\n", copybreak); + } + return ret; +} +module_init(atl2_init_module); + +/** + * atl2_exit_module - Driver Exit Cleanup Routine + * + * atl2_exit_module is called just before the driver is removed + * from memory. + **/ +static void __exit +atl2_exit_module(void) +{ + pci_unregister_driver(&atl2_driver); +} +module_exit(atl2_exit_module); + +void +atl2_read_pci_cfg(struct atl2_hw *hw, u32 reg, u16 *value) +{ + struct atl2_adapter *adapter = hw->back; + pci_read_config_word(adapter->pdev, reg, value); +} + +void +atl2_write_pci_cfg(struct atl2_hw *hw, u32 reg, u16 *value) +{ + struct atl2_adapter *adapter = hw->back; + pci_write_config_word(adapter->pdev, reg, *value); +} --- linux-2.6.28.orig/ubuntu/atl2/atl2_osdep.h +++ linux-2.6.28/ubuntu/atl2/atl2_osdep.h @@ -0,0 +1,72 @@ +/* atl2_osdep.h -- atl2 compat cruft + * + * Copyright(c) 2007 Atheros Corporation. All rights reserved. + * Copyright(c) 2006 xiong huang + * Copyright(c) 2007 Chris Snook + * + * Derived from Intel e1000 driver + * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _ATL2_OSDEP_H_ +#define _ATL2_OSDEP_H_ + +#include +#include +#include +#include + +#define usec_delay(x) udelay(x) +#ifndef msec_delay +#define msec_delay(x) do { \ + if(in_interrupt()) BUG(); \ + else msleep(x); \ + } while (0) + +/* Some workarounds require millisecond delays and are run during interrupt + * context. Most notably, when establishing link, the phy may need tweaking + * but cannot process phy register reads/writes faster than millisecond + * intervals...and we establish link due to a "link status change" interrupt. + */ +#define msec_delay_irq(x) mdelay(x) +#endif + +#define PCI_COMMAND_REGISTER PCI_COMMAND +#define CMD_MEM_WRT_INVALIDATE PCI_COMMAND_INVALIDATE +#define ETH_ADDR_LEN ETH_ALEN + +#define ATL2_WRITE_REG(a, reg, value) (writel((value), ((a)->hw_addr + reg))) + +#define ATL2_WRITE_FLUSH(a) (readl((a)->hw_addr)) + +#define ATL2_READ_REG(a, reg) (readl((a)->hw_addr + reg)) + +#define ATL2_WRITE_REGB(a, reg, value) (writeb((value), ((a)->hw_addr + reg))) + +#define ATL2_READ_REGB(a, reg) (readb((a)->hw_addr + reg)) + +#define ATL2_WRITE_REGW(a, reg, value) (writew((value), ((a)->hw_addr + reg))) + +#define ATL2_READ_REGW(a, reg) (readw((a)->hw_addr + reg)) + +#define ATL2_WRITE_REG_ARRAY(a, reg, offset, value) \ + (writel((value), (((a)->hw_addr + reg) + ((offset) << 2)))) + +#define ATL2_READ_REG_ARRAY(a, reg, offset) \ + (readl(((a)->hw_addr + reg) + ((offset) << 2))) + +#endif /* _ATL2_OSDEP_H_ */ --- linux-2.6.28.orig/ubuntu/atl2/atl2_hw.c +++ linux-2.6.28/ubuntu/atl2/atl2_hw.c @@ -0,0 +1,760 @@ +/* atl2_hw.c -- atl2 hardware control functions + * + * Copyright(c) 2007 Atheros Corporation. All rights reserved. + * Copyright(c) 2006 xiong huang + * Copyright(c) 2007 Chris Snook + * + * Derived from Intel e1000 driver + * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include + +#include "atl2.h" +#include "atl2_hw.h" + +#define LBYTESWAP( a ) ( ( ( (a) & 0x00ff00ff ) << 8 ) | ( ( (a) & 0xff00ff00 ) >> 8 ) ) +#define LONGSWAP( a ) ( ( LBYTESWAP( a ) << 16 ) | ( LBYTESWAP( a ) >> 16 ) ) +#define SHORTSWAP( a ) ( ( (a) << 8 ) | ( (a) >> 8 ) ) + +/* + * Reset the transmit and receive units; mask and clear all interrupts. + * + * hw - Struct containing variables accessed by shared code + * return : ATL2_SUCCESS or idle status (if error) + */ +s32 +atl2_reset_hw(struct atl2_hw *hw) +{ + u32 icr; + u16 pci_cfg_cmd_word; + int i; + + /* Workaround for PCI problem when BIOS sets MMRBC incorrectly. */ + atl2_read_pci_cfg(hw, PCI_REG_COMMAND, &pci_cfg_cmd_word); + if ((pci_cfg_cmd_word & + (CMD_IO_SPACE|CMD_MEMORY_SPACE|CMD_BUS_MASTER)) != + (CMD_IO_SPACE|CMD_MEMORY_SPACE|CMD_BUS_MASTER)) { + pci_cfg_cmd_word |= + (CMD_IO_SPACE|CMD_MEMORY_SPACE|CMD_BUS_MASTER); + atl2_write_pci_cfg(hw, PCI_REG_COMMAND, &pci_cfg_cmd_word); + } + + /* Clear Interrupt mask to stop board from generating + * interrupts & Clear any pending interrupt events + */ +// ATL2_WRITE_REG(hw, REG_IMR, 0); +// ATL2_WRITE_REG(hw, REG_ISR, 0xffffffff); + + /* Issue Soft Reset to the MAC. This will reset the chip's + * transmit, receive, DMA. It will not effect + * the current PCI configuration. The global reset bit is self- + * clearing, and should clear within a microsecond. + */ + ATL2_WRITE_REG(hw, REG_MASTER_CTRL, MASTER_CTRL_SOFT_RST); + wmb(); + msec_delay(1); // delay about 1ms + + /* Wait at least 10ms for All module to be Idle */ + for (i=0; i < 10; i++) { + icr = ATL2_READ_REG(hw, REG_IDLE_STATUS); + if (!icr) + break; + msec_delay(1); // delay 1 ms + cpu_relax(); + } + + if (icr) + return icr; + + return ATL2_SUCCESS; +} + +#define CUSTOM_SPI_CS_SETUP 2 +#define CUSTOM_SPI_CLK_HI 2 +#define CUSTOM_SPI_CLK_LO 2 +#define CUSTOM_SPI_CS_HOLD 2 +#define CUSTOM_SPI_CS_HI 3 + +static struct atl2_spi_flash_dev flash_table[] = +{ +/* manu_name WRSR READ PROGRAM WREN WRDI RDSR RDID SECTOR_ERASE CHIP_ERASE */ + {"Atmel", 0x0, 0x03, 0x02, 0x06, 0x04, 0x05, 0x15, 0x52, 0x62 }, + {"SST", 0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0x90, 0x20, 0x60 }, + {"ST", 0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0xAB, 0xD8, 0xC7 }, +}; + +static bool +atl2_spi_read(struct atl2_hw* hw, u32 addr, u32* buf) +{ + int i; + u32 value; + + ATL2_WRITE_REG(hw, REG_SPI_DATA, 0); + ATL2_WRITE_REG(hw, REG_SPI_ADDR, addr); + + value = SPI_FLASH_CTRL_WAIT_READY | + (CUSTOM_SPI_CS_SETUP & SPI_FLASH_CTRL_CS_SETUP_MASK) << SPI_FLASH_CTRL_CS_SETUP_SHIFT | + (CUSTOM_SPI_CLK_HI & SPI_FLASH_CTRL_CLK_HI_MASK) << SPI_FLASH_CTRL_CLK_HI_SHIFT | + (CUSTOM_SPI_CLK_LO & SPI_FLASH_CTRL_CLK_LO_MASK) << SPI_FLASH_CTRL_CLK_LO_SHIFT | + (CUSTOM_SPI_CS_HOLD & SPI_FLASH_CTRL_CS_HOLD_MASK) << SPI_FLASH_CTRL_CS_HOLD_SHIFT | + (CUSTOM_SPI_CS_HI & SPI_FLASH_CTRL_CS_HI_MASK) << SPI_FLASH_CTRL_CS_HI_SHIFT | + (0x1 & SPI_FLASH_CTRL_INS_MASK) << SPI_FLASH_CTRL_INS_SHIFT; + + ATL2_WRITE_REG(hw, REG_SPI_FLASH_CTRL, value); + + value |= SPI_FLASH_CTRL_START; + + ATL2_WRITE_REG(hw, REG_SPI_FLASH_CTRL, value); + + for (i = 0; i < 10; i++) + { + msec_delay(1); // 1ms + value = ATL2_READ_REG(hw, REG_SPI_FLASH_CTRL); + if (!(value & SPI_FLASH_CTRL_START)) + break; + } + + if (value & SPI_FLASH_CTRL_START) + return false; + + *buf = ATL2_READ_REG(hw, REG_SPI_DATA); + + return true; +} + +/* + * get_permanent_address + * return 0 if get valid mac address, + */ +static int +get_permanent_address(struct atl2_hw *hw) +{ + u32 Addr[2]; + u32 i, Control; + u16 Register; + u8 EthAddr[NODE_ADDRESS_SIZE]; + bool KeyValid; + + if (is_valid_ether_addr(hw->perm_mac_addr)) + return 0; + + Addr[0] = 0; + Addr[1] = 0; + + if (!atl2_check_eeprom_exist(hw)) { /* eeprom exists */ + Register = 0; + KeyValid = false; + + /* Read out all EEPROM content */ + i = 0; + while (1) { + if (atl2_read_eeprom(hw, i + 0x100, &Control)) { + if (KeyValid) { + if (Register == REG_MAC_STA_ADDR) + Addr[0] = Control; + else if (Register == (REG_MAC_STA_ADDR + 4)) + Addr[1] = Control; + KeyValid = false; + } else if ((Control & 0xff) == 0x5A) { + KeyValid = true; + Register = (u16) (Control >> 16); + } else { + break; /* assume data end while encount an invalid KEYWORD */ + } + } else { + break; /* read error */ + } + i += 4; + } + + *(u32*) &EthAddr[2] = LONGSWAP(Addr[0]); + *(u16*) &EthAddr[0] = SHORTSWAP(*(u16*)&Addr[1]); + + if (is_valid_ether_addr(EthAddr)) { + memcpy(hw->perm_mac_addr, EthAddr, NODE_ADDRESS_SIZE); + return 0; + } + return 1; + } + + // see if SPI FLAHS exist ? + Addr[0] = 0; + Addr[1] = 0; + Register = 0; + KeyValid = false; + i = 0; + while (1) { + if (atl2_spi_read(hw, i + 0x1f000, &Control)) { + if (KeyValid) { + if (Register == REG_MAC_STA_ADDR) + Addr[0] = Control; + else if (Register == (REG_MAC_STA_ADDR + 4)) + Addr[1] = Control; + KeyValid = false; + } else if ((Control & 0xff) == 0x5A) { + KeyValid = true; + Register = (u16) (Control >> 16); + } else { + break; /* data end */ + } + } else { + break; /* read error */ + } + i += 4; + } + + *(u32*) &EthAddr[2] = LONGSWAP(Addr[0]); + *(u16*) &EthAddr[0] = SHORTSWAP(*(u16*)&Addr[1]); + if (is_valid_ether_addr(EthAddr)) { + memcpy(hw->perm_mac_addr, EthAddr, NODE_ADDRESS_SIZE); + return 0; + } + /* maybe MAC-address is from BIOS */ + Addr[0] = ATL2_READ_REG(hw,REG_MAC_STA_ADDR); + Addr[1] = ATL2_READ_REG(hw,REG_MAC_STA_ADDR+4); + *(u32*) &EthAddr[2] = LONGSWAP(Addr[0]); + *(u16*) &EthAddr[0] = SHORTSWAP(*(u16*)&Addr[1]); + + if (is_valid_ether_addr(EthAddr)) { + memcpy(hw->perm_mac_addr, EthAddr, NODE_ADDRESS_SIZE); + return 0; + } + + return 1; +} + +/* + * Reads the adapter's MAC address from the EEPROM + * + * hw - Struct containing variables accessed by shared code + */ +s32 +atl2_read_mac_addr(struct atl2_hw *hw) +{ + u16 i; + + if (get_permanent_address(hw)) { + // for test + hw->perm_mac_addr[0] = 0x00; + hw->perm_mac_addr[1] = 0x13; + hw->perm_mac_addr[2] = 0x74; + hw->perm_mac_addr[3] = 0x00; + hw->perm_mac_addr[4] = 0x5c; + hw->perm_mac_addr[5] = 0x38; + } + + for(i = 0; i < NODE_ADDRESS_SIZE; i++) + hw->mac_addr[i] = hw->perm_mac_addr[i]; + + return ATL2_SUCCESS; +} + +/* + * Hashes an address to determine its location in the multicast table + * + * hw - Struct containing variables accessed by shared code + * mc_addr - the multicast address to hash + * + * atl2_hash_mc_addr + * purpose + * set hash value for a multicast address + * hash calcu processing : + * 1. calcu 32bit CRC for multicast address + * 2. reverse crc with MSB to LSB + */ +u32 +atl2_hash_mc_addr(struct atl2_hw *hw, u8 *mc_addr) +{ + u32 crc32, value=0; + int i; + + crc32 = ether_crc_le(6, mc_addr); + + for (i=0; i<32; i++) + value |= (((crc32>>i)&1)<<(31-i)); + + return value; +} + +/* + * Sets the bit in the multicast table corresponding to the hash value. + * + * hw - Struct containing variables accessed by shared code + * hash_value - Multicast address hash value + */ +void +atl2_hash_set(struct atl2_hw *hw, u32 hash_value) +{ + u32 hash_bit, hash_reg; + u32 mta; + + /* The HASH Table is a register array of 2 32-bit registers. + * It is treated like an array of 64 bits. We want to set + * bit BitArray[hash_value]. So we figure out what register + * the bit is in, read it, OR in the new bit, then write + * back the new value. The register is determined by the + * upper 7 bits of the hash value and the bit within that + * register are determined by the lower 5 bits of the value. + */ + hash_reg = (hash_value >> 31) & 0x1; + hash_bit = (hash_value >> 26) & 0x1F; + + mta = ATL2_READ_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg); + + mta |= (1 << hash_bit); + + ATL2_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg, mta); +} + +/* + * atl2_init_pcie - init PCIE module + */ +static void +atl2_init_pcie(struct atl2_hw *hw) +{ + u32 value; + value = LTSSM_TEST_MODE_DEF; + ATL2_WRITE_REG(hw, REG_LTSSM_TEST_MODE, value); + + value = PCIE_DLL_TX_CTRL1_DEF; + ATL2_WRITE_REG(hw, REG_PCIE_DLL_TX_CTRL1, value); +} + +void +atl2_init_flash_opcode(struct atl2_hw *hw) +{ + if (hw->flash_vendor >= ARRAY_SIZE(flash_table)) { + hw->flash_vendor = 0; // ATMEL + } + // Init OP table + ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_PROGRAM, flash_table[hw->flash_vendor].cmdPROGRAM); + ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_SC_ERASE, flash_table[hw->flash_vendor].cmdSECTOR_ERASE); + ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_CHIP_ERASE, flash_table[hw->flash_vendor].cmdCHIP_ERASE); + ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_RDID, flash_table[hw->flash_vendor].cmdRDID); + ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_WREN, flash_table[hw->flash_vendor].cmdWREN); + ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_RDSR, flash_table[hw->flash_vendor].cmdRDSR); + ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_WRSR, flash_table[hw->flash_vendor].cmdWRSR); + ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_READ, flash_table[hw->flash_vendor].cmdREAD); +} + +/******************************************************************** +* Performs basic configuration of the adapter. +* +* hw - Struct containing variables accessed by shared code +* Assumes that the controller has previously been reset and is in a +* post-reset uninitialized state. Initializes multicast table, +* and Calls routines to setup link +* Leaves the transmit and receive units disabled and uninitialized. +********************************************************************/ +s32 +atl2_init_hw(struct atl2_hw *hw) +{ + u32 ret_val = 0; + + atl2_init_pcie(hw); + + /* Zero out the Multicast HASH table */ + /* clear the old settings from the multicast hash table */ + ATL2_WRITE_REG(hw, REG_RX_HASH_TABLE, 0); + ATL2_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0); + + atl2_init_flash_opcode(hw); + + ret_val = atl2_phy_init(hw); + + return ret_val; +} + +/* + * Detects the current speed and duplex settings of the hardware. + * + * hw - Struct containing variables accessed by shared code + * speed - Speed of the connection + * duplex - Duplex setting of the connection + */ +s32 +atl2_get_speed_and_duplex(struct atl2_hw *hw, u16 *speed, u16 *duplex) +{ + s32 ret_val; + u16 phy_data; + + // ; --- Read PHY Specific Status Register (17) + ret_val = atl2_read_phy_reg(hw, MII_AT001_PSSR, &phy_data); + if (ret_val) + return ret_val; + + if (!(phy_data & MII_AT001_PSSR_SPD_DPLX_RESOLVED)) + return ATL2_ERR_PHY_RES; + + switch(phy_data & MII_AT001_PSSR_SPEED) { + case MII_AT001_PSSR_100MBS: + *speed = SPEED_100; + break; + case MII_AT001_PSSR_10MBS: + *speed = SPEED_10; + break; + default: + return ATL2_ERR_PHY_SPEED; + break; + } + + if (phy_data & MII_AT001_PSSR_DPLX) { + *duplex = FULL_DUPLEX; + } else { + *duplex = HALF_DUPLEX; + } + + return ATL2_SUCCESS; +} + +/* + * Reads the value from a PHY register + * hw - Struct containing variables accessed by shared code + * reg_addr - address of the PHY register to read + */ +s32 +atl2_read_phy_reg(struct atl2_hw *hw, u16 reg_addr, u16 *phy_data) +{ + u32 val; + int i; + + val = ((u32)(reg_addr & MDIO_REG_ADDR_MASK)) << MDIO_REG_ADDR_SHIFT | + MDIO_START | + MDIO_SUP_PREAMBLE | + MDIO_RW | + MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT; + ATL2_WRITE_REG(hw, REG_MDIO_CTRL, val); + + wmb(); + + for (i=0; iMediaType) { + case MEDIA_TYPE_AUTO_SENSOR: + mii_autoneg_adv_reg |= + (MII_AR_10T_HD_CAPS | + MII_AR_10T_FD_CAPS | + MII_AR_100TX_HD_CAPS | + MII_AR_100TX_FD_CAPS); + hw->autoneg_advertised = + ADVERTISE_10_HALF | + ADVERTISE_10_FULL | + ADVERTISE_100_HALF | + ADVERTISE_100_FULL; + break; + case MEDIA_TYPE_100M_FULL: + mii_autoneg_adv_reg |= MII_AR_100TX_FD_CAPS; + hw->autoneg_advertised = ADVERTISE_100_FULL; + break; + case MEDIA_TYPE_100M_HALF: + mii_autoneg_adv_reg |= MII_AR_100TX_HD_CAPS; + hw->autoneg_advertised = ADVERTISE_100_HALF; + break; + case MEDIA_TYPE_10M_FULL: + mii_autoneg_adv_reg |= MII_AR_10T_FD_CAPS; + hw->autoneg_advertised = ADVERTISE_10_FULL; + break; + default: + mii_autoneg_adv_reg |= MII_AR_10T_HD_CAPS; + hw->autoneg_advertised = ADVERTISE_10_HALF; + break; + } + + /* flow control fixed to enable all */ + mii_autoneg_adv_reg |= (MII_AR_ASM_DIR | MII_AR_PAUSE); + + hw->mii_autoneg_adv_reg = mii_autoneg_adv_reg; + + ret_val = atl2_write_phy_reg(hw, MII_ADVERTISE, mii_autoneg_adv_reg); + + if(ret_val) + return ret_val; + + return ATL2_SUCCESS; +} + +/* + * Resets the PHY and make all config validate + * + * hw - Struct containing variables accessed by shared code + * + * Sets bit 15 and 12 of the MII Control regiser (for F001 bug) + */ +static s32 +atl2_phy_commit(struct atl2_hw *hw) +{ + s32 ret_val; + u16 phy_data; + +/* FIXME: use or remove -- CHS + if (hw->MediaType == MEDIA_TYPE_AUTO_SENSOR) { + phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN; + } else { + switch (hw->MediaType) + { + case MEDIA_TYPE_100M_FULL: + phy_data = MII_CR_FULL_DUPLEX|MII_CR_SPEED_100|MII_CR_RESET; + break; + case MEDIA_TYPE_100M_HALF: + phy_data = MII_CR_SPEED_100|MII_CR_RESET; + break; + case MEDIA_TYPE_10M_FULL: + phy_data = MII_CR_FULL_DUPLEX|MII_CR_SPEED_10|MII_CR_RESET; + break; + default: // MEDIA_TYPE_10M_HALF: + phy_data = MII_CR_SPEED_10|MII_CR_RESET; + break; + } + } +*/ + phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG; + ret_val = atl2_write_phy_reg(hw, MII_BMCR, phy_data); + if (ret_val) { // bug fixed + u32 val; + int i; + /* pcie serdes link may be down ! */ + for (i=0; i < 25; i++) { + msec_delay(1); + val = ATL2_READ_REG(hw, REG_MDIO_CTRL); + if (!(val & (MDIO_START | MDIO_BUSY))) + break; + } + + if (0 != (val & (MDIO_START | MDIO_BUSY))) { + printk(KERN_ERR "atl2: PCIe link down for at least 25ms !\n"); + return ret_val; + } + } + return ATL2_SUCCESS; +} + +s32 +atl2_phy_init(struct atl2_hw *hw) +{ + s32 ret_val; + u16 phy_val; + + if (hw->phy_configured) + return 0; + + /* Enable PHY */ + ATL2_WRITE_REGW(hw, REG_PHY_ENABLE, 1); + ATL2_WRITE_FLUSH(hw); + msec_delay(1); + + /* check if the PHY is in powersaving mode */ + atl2_write_phy_reg(hw, MII_DBG_ADDR, 0); + atl2_read_phy_reg(hw, MII_DBG_DATA, &phy_val); + + /* 024E / 124E 0r 0274 / 1274 ? */ + if (phy_val & 0x1000) { + phy_val &= ~0x1000; + atl2_write_phy_reg(hw, MII_DBG_DATA, phy_val); + } + + msec_delay(1); + + + /*Enable PHY LinkChange Interrupt */ + ret_val = atl2_write_phy_reg(hw, 18, 0xC00); + if (ret_val) + return ret_val; + + /* setup AutoNeg parameters */ + ret_val = atl2_phy_setup_autoneg_adv(hw); + if(ret_val) + return ret_val; + + /* SW.Reset & En-Auto-Neg to restart Auto-Neg */ + ret_val = atl2_phy_commit(hw); + if (ret_val) + return ret_val; + + hw->phy_configured = true; + + return ret_val; +} + +void +atl2_set_mac_addr(struct atl2_hw *hw) +{ + u32 value; + // 00-0B-6A-F6-00-DC + // 0: 6AF600DC 1: 000B + // low dword + value = (((u32)hw->mac_addr[2]) << 24) | + (((u32)hw->mac_addr[3]) << 16) | + (((u32)hw->mac_addr[4]) << 8 ) | + (((u32)hw->mac_addr[5]) ) ; + ATL2_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 0, value); + // hight dword + value = (((u32)hw->mac_addr[0]) << 8 ) | + (((u32)hw->mac_addr[1]) ) ; + ATL2_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 1, value); +} + +/* + * check_eeprom_exist + * return 0 if eeprom exist + */ +int +atl2_check_eeprom_exist(struct atl2_hw *hw) +{ + u32 value; + + value = ATL2_READ_REG(hw, REG_SPI_FLASH_CTRL); + if (value & SPI_FLASH_CTRL_EN_VPD) { + value &= ~SPI_FLASH_CTRL_EN_VPD; + ATL2_WRITE_REG(hw, REG_SPI_FLASH_CTRL, value); + } + value = ATL2_READ_REGW(hw, REG_PCIE_CAP_LIST); + return ((value & 0xFF00) == 0x6C00) ? 0 : 1; +} + +// FIXME: This doesn't look right. -- CHS +bool +atl2_write_eeprom(struct atl2_hw *hw, u32 offset, u32 value) +{ + return true; +} + +bool +atl2_read_eeprom(struct atl2_hw *hw, u32 Offset, u32 *pValue) +{ + int i; + u32 Control; + + if (Offset & 0x3) + return false; /* address do not align */ + + ATL2_WRITE_REG(hw, REG_VPD_DATA, 0); + Control = (Offset & VPD_CAP_VPD_ADDR_MASK) << VPD_CAP_VPD_ADDR_SHIFT; + ATL2_WRITE_REG(hw, REG_VPD_CAP, Control); + + for (i = 0; i < 10; i++) { + msec_delay(2); + Control = ATL2_READ_REG(hw, REG_VPD_CAP); + if (Control & VPD_CAP_VPD_FLAG) + break; + } + + if (Control & VPD_CAP_VPD_FLAG) { + *pValue = ATL2_READ_REG(hw, REG_VPD_DATA); + return true; + } + return false; /* timeout */ +} + +void +atl2_force_ps(struct atl2_hw *hw) +{ + u16 phy_val; + + atl2_write_phy_reg(hw, MII_DBG_ADDR, 0); + atl2_read_phy_reg(hw, MII_DBG_DATA, &phy_val); + atl2_write_phy_reg(hw, MII_DBG_DATA, phy_val | 0x1000); + + atl2_write_phy_reg(hw, MII_DBG_ADDR, 2); + atl2_write_phy_reg(hw, MII_DBG_DATA, 0x3000); + atl2_write_phy_reg(hw, MII_DBG_ADDR, 3); + atl2_write_phy_reg(hw, MII_DBG_DATA, 0); +} --- linux-2.6.28.orig/ubuntu/atl2/atl2_hw.h +++ linux-2.6.28/ubuntu/atl2/atl2_hw.h @@ -0,0 +1,758 @@ +/* atl2_hw.h -- atl2 hardware definitions + * + * Copyright(c) 2007 Atheros Corporation. All rights reserved. + * Copyright(c) 2006 xiong huang + * Copyright(c) 2007 Chris Snook + * + * Derived from Intel e1000 driver + * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Some of these defines are unused for various reasons. Some describe + * hardware features we don't yet use. Some are specific to the cousin atl1 + * hardware, which we may merge this driver with in the future. Please + * remember this is a surrogate for hardware specs, and don't unnecessarily + * abuse the content or formatting. -- CHS + */ + +#ifndef _ATL2_HW_H_ +#define _ATL2_HW_H_ + +#include "atl2_osdep.h" + +struct atl2_adapter; +struct atl2_hw; + +/* function prototype */ +s32 atl2_reset_hw(struct atl2_hw *hw); +s32 atl2_read_mac_addr(struct atl2_hw *hw); +s32 atl2_init_hw(struct atl2_hw *hw); +s32 atl2_get_speed_and_duplex(struct atl2_hw *hw, u16 *speed, u16 *duplex); +u32 atl2_auto_get_fc(struct atl2_adapter *adapter, u16 duplex); +u32 atl2_hash_mc_addr(struct atl2_hw *hw, u8 *mc_addr); +void atl2_hash_set(struct atl2_hw *hw, u32 hash_value); +s32 atl2_read_phy_reg(struct atl2_hw *hw, u16 reg_addr, u16 *phy_data); +s32 atl2_write_phy_reg(struct atl2_hw *hw, u32 reg_addr, u16 phy_data); +void atl2_read_pci_cfg(struct atl2_hw *hw, u32 reg, u16 *value); +void atl2_write_pci_cfg(struct atl2_hw *hw, u32 reg, u16 *value); +s32 atl2_validate_mdi_setting(struct atl2_hw *hw); +void atl2_set_mac_addr(struct atl2_hw *hw); +bool atl2_read_eeprom(struct atl2_hw *hw, u32 Offset, u32 *pValue); +bool atl2_write_eeprom(struct atl2_hw *hw, u32 offset, u32 value); +s32 atl2_phy_init(struct atl2_hw *hw); +int atl2_check_eeprom_exist(struct atl2_hw *hw); +void atl2_force_ps(struct atl2_hw *hw); + +/* register definition */ +#define REG_PM_CTRLSTAT 0x44 + +#define REG_PCIE_CAP_LIST 0x58 + +#define REG_VPD_CAP 0x6C +#define VPD_CAP_ID_MASK 0xff +#define VPD_CAP_ID_SHIFT 0 +#define VPD_CAP_NEXT_PTR_MASK 0xFF +#define VPD_CAP_NEXT_PTR_SHIFT 8 +#define VPD_CAP_VPD_ADDR_MASK 0x7FFF +#define VPD_CAP_VPD_ADDR_SHIFT 16 +#define VPD_CAP_VPD_FLAG 0x80000000 + +#define REG_VPD_DATA 0x70 + +#define REG_SPI_FLASH_CTRL 0x200 +#define SPI_FLASH_CTRL_STS_NON_RDY 0x1 +#define SPI_FLASH_CTRL_STS_WEN 0x2 +#define SPI_FLASH_CTRL_STS_WPEN 0x80 +#define SPI_FLASH_CTRL_DEV_STS_MASK 0xFF +#define SPI_FLASH_CTRL_DEV_STS_SHIFT 0 +#define SPI_FLASH_CTRL_INS_MASK 0x7 +#define SPI_FLASH_CTRL_INS_SHIFT 8 +#define SPI_FLASH_CTRL_START 0x800 +#define SPI_FLASH_CTRL_EN_VPD 0x2000 +#define SPI_FLASH_CTRL_LDSTART 0x8000 +#define SPI_FLASH_CTRL_CS_HI_MASK 0x3 +#define SPI_FLASH_CTRL_CS_HI_SHIFT 16 +#define SPI_FLASH_CTRL_CS_HOLD_MASK 0x3 +#define SPI_FLASH_CTRL_CS_HOLD_SHIFT 18 +#define SPI_FLASH_CTRL_CLK_LO_MASK 0x3 +#define SPI_FLASH_CTRL_CLK_LO_SHIFT 20 +#define SPI_FLASH_CTRL_CLK_HI_MASK 0x3 +#define SPI_FLASH_CTRL_CLK_HI_SHIFT 22 +#define SPI_FLASH_CTRL_CS_SETUP_MASK 0x3 +#define SPI_FLASH_CTRL_CS_SETUP_SHIFT 24 +#define SPI_FLASH_CTRL_EROM_PGSZ_MASK 0x3 +#define SPI_FLASH_CTRL_EROM_PGSZ_SHIFT 26 +#define SPI_FLASH_CTRL_WAIT_READY 0x10000000 + +#define REG_SPI_ADDR 0x204 + +#define REG_SPI_DATA 0x208 + +#define REG_SPI_FLASH_CONFIG 0x20C +#define SPI_FLASH_CONFIG_LD_ADDR_MASK 0xFFFFFF +#define SPI_FLASH_CONFIG_LD_ADDR_SHIFT 0 +#define SPI_FLASH_CONFIG_VPD_ADDR_MASK 0x3 +#define SPI_FLASH_CONFIG_VPD_ADDR_SHIFT 24 +#define SPI_FLASH_CONFIG_LD_EXIST 0x4000000 + +#define REG_SPI_FLASH_OP_PROGRAM 0x210 +#define REG_SPI_FLASH_OP_SC_ERASE 0x211 +#define REG_SPI_FLASH_OP_CHIP_ERASE 0x212 +#define REG_SPI_FLASH_OP_RDID 0x213 +#define REG_SPI_FLASH_OP_WREN 0x214 +#define REG_SPI_FLASH_OP_RDSR 0x215 +#define REG_SPI_FLASH_OP_WRSR 0x216 +#define REG_SPI_FLASH_OP_READ 0x217 + +#define REG_TWSI_CTRL 0x218 +#define TWSI_CTRL_LD_OFFSET_MASK 0xFF +#define TWSI_CTRL_LD_OFFSET_SHIFT 0 +#define TWSI_CTRL_LD_SLV_ADDR_MASK 0x7 +#define TWSI_CTRL_LD_SLV_ADDR_SHIFT 8 +#define TWSI_CTRL_SW_LDSTART 0x800 +#define TWSI_CTRL_HW_LDSTART 0x1000 +#define TWSI_CTRL_SMB_SLV_ADDR_MASK 0x0x7F +#define TWSI_CTRL_SMB_SLV_ADDR_SHIFT 15 +#define TWSI_CTRL_LD_EXIST 0x400000 +#define TWSI_CTRL_READ_FREQ_SEL_MASK 0x3 +#define TWSI_CTRL_READ_FREQ_SEL_SHIFT 23 +#define TWSI_CTRL_FREQ_SEL_100K 0 +#define TWSI_CTRL_FREQ_SEL_200K 1 +#define TWSI_CTRL_FREQ_SEL_300K 2 +#define TWSI_CTRL_FREQ_SEL_400K 3 +#define TWSI_CTRL_SMB_SLV_ADDR +#define TWSI_CTRL_WRITE_FREQ_SEL_MASK 0x3 +#define TWSI_CTRL_WRITE_FREQ_SEL_SHIFT 24 + +#define REG_PCIE_DEV_MISC_CTRL 0x21C +#define PCIE_DEV_MISC_CTRL_EXT_PIPE 0x2 +#define PCIE_DEV_MISC_CTRL_RETRY_BUFDIS 0x1 +#define PCIE_DEV_MISC_CTRL_SPIROM_EXIST 0x4 +#define PCIE_DEV_MISC_CTRL_SERDES_ENDIAN 0x8 +#define PCIE_DEV_MISC_CTRL_SERDES_SEL_DIN 0x10 + +#define REG_PCIE_PHYMISC 0x1000 +#define PCIE_PHYMISC_FORCE_RCV_DET 0x4 + +#define REG_PCIE_DLL_TX_CTRL1 0x1104 +#define PCIE_DLL_TX_CTRL1_SEL_NOR_CLK 0x0400 +#define PCIE_DLL_TX_CTRL1_DEF 0x0568 + +#define REG_LTSSM_TEST_MODE 0x12FC +#define LTSSM_TEST_MODE_DEF 0x6500 + +/* Master Control Register */ +#define REG_MASTER_CTRL 0x1400 +#define MASTER_CTRL_SOFT_RST 0x1 +#define MASTER_CTRL_MTIMER_EN 0x2 +#define MASTER_CTRL_ITIMER_EN 0x4 +#define MASTER_CTRL_MANUAL_INT 0x8 +#define MASTER_CTRL_REV_NUM_SHIFT 16 +#define MASTER_CTRL_REV_NUM_MASK 0xff +#define MASTER_CTRL_DEV_ID_SHIFT 24 +#define MASTER_CTRL_DEV_ID_MASK 0xff + +/* Timer Initial Value Register */ +#define REG_MANUAL_TIMER_INIT 0x1404 + +/* IRQ ModeratorTimer Initial Value Register */ +#define REG_IRQ_MODU_TIMER_INIT 0x1408 + +#define REG_PHY_ENABLE 0x140C +// IRQ Anti-Lost Timer Initial Value Register +//#define REG_IRQ_CLR_TIMER 0x140c // Maximum allowance for software to clear the interrupt. +// IRQ Anti-Lost Timer Initial Value Register +#define REG_CMBDISDMA_TIMER 0x140E + +/* Block IDLE Status Register */ +#define REG_IDLE_STATUS 0x1410 +#define IDLE_STATUS_RXMAC 1 /* 1: RXMAC state machine is in non-IDLE state. 0: RXMAC is idling */ +#define IDLE_STATUS_TXMAC 2 /* 1: TXMAC state machine is in non-IDLE state. 0: TXMAC is idling */ +#define IDLE_STATUS_DMAR 8 /* 1: DMAR state machine is in non-IDLE state. 0: DMAR is idling */ +#define IDLE_STATUS_DMAW 4 /* 1: DMAW state machine is in non-IDLE state. 0: DMAW is idling */ + +/* MDIO Control Register */ +#define REG_MDIO_CTRL 0x1414 +#define MDIO_DATA_MASK 0xffff /* On MDIO write, the 16-bit control data to write to PHY MII management register */ +#define MDIO_DATA_SHIFT 0 /* On MDIO read, the 16-bit status data that was read from the PHY MII management register. */ +#define MDIO_REG_ADDR_MASK 0x1f /* MDIO register address */ +#define MDIO_REG_ADDR_SHIFT 16 +#define MDIO_RW 0x200000 /* 1: read, 0: write */ +#define MDIO_SUP_PREAMBLE 0x400000 /* Suppress preamble */ +#define MDIO_START 0x800000 /* Write 1 to initiate the MDIO master. And this bit is self cleared after one cycle. */ +#define MDIO_CLK_SEL_SHIFT 24 +#define MDIO_CLK_25_4 0 +#define MDIO_CLK_25_6 2 +#define MDIO_CLK_25_8 3 +#define MDIO_CLK_25_10 4 +#define MDIO_CLK_25_14 5 +#define MDIO_CLK_25_20 6 +#define MDIO_CLK_25_28 7 +#define MDIO_BUSY 0x8000000 +#define MDIO_WAIT_TIMES 10 + +/* SerDes Lock Detect Control and Status Register */ +#define REG_SERDES_LOCK 0x1424 +#define SERDES_LOCK_DETECT 1 /* 1: SerDes lock detected. This signal comes from Analog SerDes. */ +#define SERDES_LOCK_DETECT_EN 2 /* 1: Enable SerDes Lock detect function. */ + +/* MAC Control Register */ +#define REG_MAC_CTRL 0x1480 +#define MAC_CTRL_TX_EN 1 /* 1: Transmit Enable */ +#define MAC_CTRL_RX_EN 2 /* 1: Receive Enable */ +#define MAC_CTRL_TX_FLOW 4 /* 1: Transmit Flow Control Enable */ +#define MAC_CTRL_RX_FLOW 8 /* 1: Receive Flow Control Enable */ +#define MAC_CTRL_LOOPBACK 0x10 /* 1: Loop back at G/MII Interface */ +#define MAC_CTRL_DUPLX 0x20 /* 1: Full-duplex mode 0: Half-duplex mode */ +#define MAC_CTRL_ADD_CRC 0x40 /* 1: Instruct MAC to attach CRC on all egress Ethernet frames */ +#define MAC_CTRL_PAD 0x80 /* 1: Instruct MAC to pad short frames to 60-bytes, and then attach CRC. This bit has higher priority over CRC_EN */ +#define MAC_CTRL_PRMLEN_SHIFT 10 /* Preamble length, it's 0x07 by standard */ +#define MAC_CTRL_PRMLEN_MASK 0xf +#define MAC_CTRL_RMV_VLAN 0x4000 /* 1: to remove VLAN Tag automatically from all receive packets */ +#define MAC_CTRL_PROMIS_EN 0x8000 /* 1: Promiscuous Mode Enable */ +#define MAC_CTRL_DBG_TX_BKPRESURE 0x100000 /* 1: transmit maximum backoff (half-duplex test bit) */ +#define MAC_CTRL_MC_ALL_EN 0x2000000 /* 1: upload all multicast frame without error to system */ +#define MAC_CTRL_BC_EN 0x4000000 /* 1: upload all broadcast frame without error to system */ +#define MAC_CTRL_MACLP_CLK_PHY 0x8000000 /* 1: MAC-LoopBack clock from phy, 0:from sys_25M */ +#define MAC_CTRL_HALF_LEFT_BUF_SHIFT 28 +#define MAC_CTRL_HALF_LEFT_BUF_MASK 0xF /* When half-duplex mode, should hold some bytes for mac retry . (8*4bytes unit) */ + +/* MAC IPG/IFG Control Register */ +#define REG_MAC_IPG_IFG 0x1484 +#define MAC_IPG_IFG_IPGT_SHIFT 0 /* Desired back to back inter-packet gap. The default is 96-bit time. */ +#define MAC_IPG_IFG_IPGT_MASK 0x7f +#define MAC_IPG_IFG_MIFG_SHIFT 8 /* Minimum number of IFG to enforce in between RX frames. */ +#define MAC_IPG_IFG_MIFG_MASK 0xff /* Frame gap below such IFP is dropped. */ +#define MAC_IPG_IFG_IPGR1_SHIFT 16 /* 64bit Carrier-Sense window */ +#define MAC_IPG_IFG_IPGR1_MASK 0x7f +#define MAC_IPG_IFG_IPGR2_SHIFT 24 /* 96-bit IPG window */ +#define MAC_IPG_IFG_IPGR2_MASK 0x7f + +/* MAC STATION ADDRESS */ +#define REG_MAC_STA_ADDR 0x1488 + +/* Hash table for multicast address */ +#define REG_RX_HASH_TABLE 0x1490 + +/* MAC Half-Duplex Control Register */ +#define REG_MAC_HALF_DUPLX_CTRL 0x1498 +#define MAC_HALF_DUPLX_CTRL_LCOL_SHIFT 0 /* Collision Window. */ +#define MAC_HALF_DUPLX_CTRL_LCOL_MASK 0x3ff +#define MAC_HALF_DUPLX_CTRL_RETRY_SHIFT 12 /* Retransmission maximum, afterwards the packet will be discarded. */ +#define MAC_HALF_DUPLX_CTRL_RETRY_MASK 0xf +#define MAC_HALF_DUPLX_CTRL_EXC_DEF_EN 0x10000 /* 1: Allow the transmission of a packet which has been excessively deferred */ +#define MAC_HALF_DUPLX_CTRL_NO_BACK_C 0x20000 /* 1: No back-off on collision, immediately start the retransmission. */ +#define MAC_HALF_DUPLX_CTRL_NO_BACK_P 0x40000 /* 1: No back-off on backpressure, immediately start the transmission after back pressure */ +#define MAC_HALF_DUPLX_CTRL_ABEBE 0x80000 /* 1: Alternative Binary Exponential Back-off Enabled */ +#define MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT 20 /* Maximum binary exponential number. */ +#define MAC_HALF_DUPLX_CTRL_ABEBT_MASK 0xf +#define MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT 24 /* IPG to start JAM for collision based flow control in half-duplex */ +#define MAC_HALF_DUPLX_CTRL_JAMIPG_MASK 0xf /* mode. In unit of 8-bit time. */ + +/* Maximum Frame Length Control Register */ +#define REG_MTU 0x149c + +/* Wake-On-Lan control register */ +#define REG_WOL_CTRL 0x14a0 +#define WOL_PATTERN_EN 0x00000001 +#define WOL_PATTERN_PME_EN 0x00000002 +#define WOL_MAGIC_EN 0x00000004 +#define WOL_MAGIC_PME_EN 0x00000008 +#define WOL_LINK_CHG_EN 0x00000010 +#define WOL_LINK_CHG_PME_EN 0x00000020 +#define WOL_PATTERN_ST 0x00000100 +#define WOL_MAGIC_ST 0x00000200 +#define WOL_LINKCHG_ST 0x00000400 +#define WOL_PT0_EN 0x00010000 +#define WOL_PT1_EN 0x00020000 +#define WOL_PT2_EN 0x00040000 +#define WOL_PT3_EN 0x00080000 +#define WOL_PT4_EN 0x00100000 +#define WOL_PT0_MATCH 0x01000000 +#define WOL_PT1_MATCH 0x02000000 +#define WOL_PT2_MATCH 0x04000000 +#define WOL_PT3_MATCH 0x08000000 +#define WOL_PT4_MATCH 0x10000000 + +/* Internal SRAM Partition Register */ +#define REG_SRAM_TXRAM_END 0x1500 /* Internal tail address of TXRAM default: 2byte*1024 */ +#define REG_SRAM_RXRAM_END 0x1502 /* Internal tail address of RXRAM default: 2byte*1024 */ + +/* +#define REG_SRAM_TCPH_PATH_ADDR (REG_SRAM_RFD_ADDR+48) +#define SRAM_TCPH_ADDR_MASK 0x0fff +#define SRAM_TCPH_ADDR_SHIFT 0 +#define SRAM_PATH_ADDR_MASK 0x0fff +#define SRAM_PATH_ADDR_SHIFT 16 +*/ + +/* Descriptor Control register */ +#define REG_DESC_BASE_ADDR_HI 0x1540 +#define REG_TXD_BASE_ADDR_LO 0x1544 /* The base address of the Transmit Data Memory low 32-bit(dword align) */ +#define REG_TXD_MEM_SIZE 0x1548 /* Transmit Data Memory size(by double word , max 256KB) */ +#define REG_TXS_BASE_ADDR_LO 0x154C /* The base address of the Transmit Status Memory low 32-bit(dword word align) */ +#define REG_TXS_MEM_SIZE 0x1550 /* double word unit, max 4*2047 bytes. */ +#define REG_RXD_BASE_ADDR_LO 0x1554 /* The base address of the Transmit Status Memory low 32-bit(unit 8 bytes) */ +#define REG_RXD_BUF_NUM 0x1558 /* Receive Data & Status Memory buffer number (unit 1536bytes, max 1536*2047) */ + +/* DMAR Control Register */ +#define REG_DMAR 0x1580 +#define DMAR_EN 0x1 /* 1: Enable DMAR */ + +/* TX Cur-Through (early tx threshold) Control Register */ +#define REG_TX_CUT_THRESH 0x1590 /* TxMac begin transmit packet threshold(unit word) */ + +/* DMAW Control Register */ +#define REG_DMAW 0x15A0 +#define DMAW_EN 0x1 + +/* Flow control register */ +#define REG_PAUSE_ON_TH 0x15A8 /* RXD high watermark of overflow threshold configuration register */ +#define REG_PAUSE_OFF_TH 0x15AA /* RXD lower watermark of overflow threshold configuration register */ + +/* Mailbox Register */ +#define REG_MB_TXD_WR_IDX 0x15f0 /* double word align */ +#define REG_MB_RXD_RD_IDX 0x15F4 /* RXD Read index (unit: 1536byets) */ + +/* Interrupt Status Register */ +#define REG_ISR 0x1600 +#define ISR_TIMER 1 /* Interrupt when Timer is counted down to zero */ +#define ISR_MANUAL 2 /* Software manual interrupt, for debug. Set when SW_MAN_INT_EN is set in Table 51 Selene Master Control Register (Offset 0x1400). */ +#define ISR_RXF_OV 4 /* RXF overflow interrupt */ +#define ISR_TXF_UR 8 /* TXF underrun interrupt */ +#define ISR_TXS_OV 0x10 /* Internal transmit status buffer full interrupt */ +#define ISR_RXS_OV 0x20 /* Internal receive status buffer ful interrupt */ +#define ISR_LINK_CHG 0x40 /* Link Status Change Interrupt */ +#define ISR_HOST_TXD_UR 0x80 +#define ISR_HOST_RXD_OV 0x100 /* Host rx data memory full , one pulse */ +//#define ISR_HOST_TXS_OV 0x200 /* Host tx status memory full , one pulse */ +#define ISR_DMAR_TO_RST 0x200 /* DMAR op timeout interrupt. SW should do Reset */ +#define ISR_DMAW_TO_RST 0x400 +#define ISR_PHY 0x800 /* phy interrupt */ +#define ISR_TS_UPDATE 0x10000 /* interrupt after new tx pkt status written to host */ +#define ISR_RS_UPDATE 0x20000 /* interrupt ater new rx pkt status written to host. */ +#define ISR_TX_EARLY 0x40000 /* interrupt when txmac begin transmit one packet */ +#define ISR_UR_DETECTED 0x1000000 +#define ISR_FERR_DETECTED 0x2000000 +#define ISR_NFERR_DETECTED 0x4000000 +#define ISR_CERR_DETECTED 0x8000000 +#define ISR_PHY_LINKDOWN 0x10000000 +#define ISR_DIS_INT 0x80000000 + +#define ISR_TX_EVENT (ISR_TXF_UR|ISR_TXS_OV|ISR_HOST_TXD_UR|ISR_TS_UPDATE|ISR_TX_EARLY) +#define ISR_RX_EVENT (ISR_RXF_OV|ISR_RXS_OV|ISR_HOST_RXD_OV|ISR_RS_UPDATE) + +/* Interrupt Mask Register */ +#define REG_IMR 0x1604 + +#define IMR_NORMAL_MASK (\ + /*ISR_LINK_CHG |*/\ + ISR_MANUAL |\ + ISR_DMAR_TO_RST |\ + ISR_DMAW_TO_RST |\ + ISR_PHY |\ + ISR_PHY_LINKDOWN |\ + ISR_TS_UPDATE |\ + ISR_RS_UPDATE ) + +/* Receive MAC Statistics Registers */ +#define REG_STS_RX_PAUSE 0x1700 /* The number of Pause packet received */ +#define REG_STS_RXD_OV 0x1704 /* The number of frame dropped due to occurrence of RX FIFO overflow */ +#define REG_STS_RXS_OV 0x1708 /* The number of frame dropped due to occerrence of RX Status Buffer Overflow */ +#define REG_STS_RX_FILTER 0x170C /* The number of packet dropped due to address filtering */ + +/* MII definitions */ + +/* PHY Common Register */ +#define MII_AT001_CR 0x09 +#define MII_AT001_SR 0x0A +#define MII_AT001_ESR 0x0F +#define MII_AT001_PSCR 0x10 +#define MII_AT001_PSSR 0x11 +#define MII_SMARTSPEED 0x14 +#define MII_DBG_ADDR 0x1D +#define MII_DBG_DATA 0x1E + +/* PHY Control Register */ +#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */ +#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */ +#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */ +#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */ +#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */ +#define MII_CR_POWER_DOWN 0x0800 /* Power down */ +#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */ +#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */ +#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */ +#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */ +#define MII_CR_SPEED_MASK 0x2040 +#define MII_CR_SPEED_1000 0x0040 +#define MII_CR_SPEED_100 0x2000 +#define MII_CR_SPEED_10 0x0000 + +/* PHY Status Register */ +#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */ +#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */ +#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */ +#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */ +#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */ +#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */ +#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */ +#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */ +#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */ +#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */ +#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */ +#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */ +#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */ +#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */ +#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */ + +/* Link partner ability register. */ +#define MII_LPA_SLCT 0x001f /* Same as advertise selector */ +#define MII_LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */ +#define MII_LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */ +#define MII_LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */ +#define MII_LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */ +#define MII_LPA_100BASE4 0x0200 /* 100BASE-T4 */ +#define MII_LPA_PAUSE 0x0400 /* PAUSE */ +#define MII_LPA_ASYPAUSE 0x0800 /* Asymmetrical PAUSE */ +#define MII_LPA_RFAULT 0x2000 /* Link partner faulted */ +#define MII_LPA_LPACK 0x4000 /* Link partner acked us */ +#define MII_LPA_NPAGE 0x8000 /* Next page bit */ + +/* Autoneg Advertisement Register */ +#define MII_AR_SELECTOR_FIELD 0x0001 /* indicates IEEE 802.3 CSMA/CD */ +#define MII_AR_10T_HD_CAPS 0x0020 /* 10T Half Duplex Capable */ +#define MII_AR_10T_FD_CAPS 0x0040 /* 10T Full Duplex Capable */ +#define MII_AR_100TX_HD_CAPS 0x0080 /* 100TX Half Duplex Capable */ +#define MII_AR_100TX_FD_CAPS 0x0100 /* 100TX Full Duplex Capable */ +#define MII_AR_100T4_CAPS 0x0200 /* 100T4 Capable */ +#define MII_AR_PAUSE 0x0400 /* Pause operation desired */ +#define MII_AR_ASM_DIR 0x0800 /* Asymmetric Pause Direction bit */ +#define MII_AR_REMOTE_FAULT 0x2000 /* Remote Fault detected */ +#define MII_AR_NEXT_PAGE 0x8000 /* Next Page ability supported */ +#define MII_AR_SPEED_MASK 0x01E0 +#define MII_AR_DEFAULT_CAP_MASK 0x0DE0 + +/* 1000BASE-T Control Register */ +#define MII_AT001_CR_1000T_HD_CAPS 0x0100 /* Advertise 1000T HD capability */ +#define MII_AT001_CR_1000T_FD_CAPS 0x0200 /* Advertise 1000T FD capability */ +#define MII_AT001_CR_1000T_REPEATER_DTE 0x0400 /* 1=Repeater/switch device port, 0=DTE device */ +#define MII_AT001_CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master, 0=Configure PHY as Slave */ +#define MII_AT001_CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value, 0=Automatic Master/Slave config */ +#define MII_AT001_CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */ +#define MII_AT001_CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */ +#define MII_AT001_CR_1000T_TEST_MODE_2 0x4000 /* Master Transmit Jitter test */ +#define MII_AT001_CR_1000T_TEST_MODE_3 0x6000 /* Slave Transmit Jitter test */ +#define MII_AT001_CR_1000T_TEST_MODE_4 0x8000 /* Transmitter Distortion test */ +#define MII_AT001_CR_1000T_SPEED_MASK 0x0300 +#define MII_AT001_CR_1000T_DEFAULT_CAP_MASK 0x0300 + +/* 1000BASE-T Status Register */ +#define MII_AT001_SR_1000T_LP_HD_CAPS 0x0400 /* LP is 1000T HD capable */ +#define MII_AT001_SR_1000T_LP_FD_CAPS 0x0800 /* LP is 1000T FD capable */ +#define MII_AT001_SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */ +#define MII_AT001_SR_1000T_LOCAL_RX_STATUS 0x2000 /* Local receiver OK */ +#define MII_AT001_SR_1000T_MS_CONFIG_RES 0x4000 /* 1=Local TX is Master, 0=Slave */ +#define MII_AT001_SR_1000T_MS_CONFIG_FAULT 0x8000 /* Master/Slave config fault */ +#define MII_AT001_SR_1000T_REMOTE_RX_STATUS_SHIFT 12 +#define MII_AT001_SR_1000T_LOCAL_RX_STATUS_SHIFT 13 + +/* Extended Status Register */ +#define MII_AT001_ESR_1000T_HD_CAPS 0x1000 /* 1000T HD capable */ +#define MII_AT001_ESR_1000T_FD_CAPS 0x2000 /* 1000T FD capable */ +#define MII_AT001_ESR_1000X_HD_CAPS 0x4000 /* 1000X HD capable */ +#define MII_AT001_ESR_1000X_FD_CAPS 0x8000 /* 1000X FD capable */ + +/* AT001 PHY Specific Control Register */ +#define MII_AT001_PSCR_JABBER_DISABLE 0x0001 /* 1=Jabber Function disabled */ +#define MII_AT001_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enabled */ +#define MII_AT001_PSCR_SQE_TEST 0x0004 /* 1=SQE Test enabled *// +#define MII_AT001_PSCR_MAC_POWERDOWN 0x0008 +#define MII_AT001_PSCR_CLK125_DISABLE 0x0010 /* 1=CLK125 low, 0=CLK125 toggling */ +#define MII_AT001_PSCR_MDI_MANUAL_MODE 0x0000 /* MDI Crossover Mode bits 6:5, Manual MDI configuration */ +#define MII_AT001_PSCR_MDIX_MANUAL_MODE 0x0020 /* Manual MDIX configuration */ +#define MII_AT001_PSCR_AUTO_X_1000T 0x0040 /* 1000BASE-T: Auto crossover, 100BASE-TX/10BASE-T: MDI Mode */ +#define MII_AT001_PSCR_AUTO_X_MODE 0x0060 /* Auto crossover enabled all speeds. */ +#define MII_AT001_PSCR_10BT_EXT_DIST_ENABLE 0x0080 /* 1=Enable Extended 10BASE-T distance (Lower 10BASE-T RX Threshold), 0=Normal 10BASE-T RX Threshold */ +#define MII_AT001_PSCR_MII_5BIT_ENABLE 0x0100 /* 1=5-Bit interface in 100BASE-TX, 0=MII interface in 100BASE-TX */ +#define MII_AT001_PSCR_SCRAMBLER_DISABLE 0x0200 /* 1=Scrambler disable */ +#define MII_AT001_PSCR_FORCE_LINK_GOOD 0x0400 /* 1=Force link good */ +#define MII_AT001_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Transmit */ +#define MII_AT001_PSCR_POLARITY_REVERSAL_SHIFT 1 +#define MII_AT001_PSCR_AUTO_X_MODE_SHIFT 5 +#define MII_AT001_PSCR_10BT_EXT_DIST_ENABLE_SHIFT 7 + +/* AT001 PHY Specific Status Register */ +#define MII_AT001_PSSR_SPD_DPLX_RESOLVED 0x0800 /* 1=Speed & Duplex resolved */ +#define MII_AT001_PSSR_DPLX 0x2000 /* 1=Duplex 0=Half Duplex */ +#define MII_AT001_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */ +#define MII_AT001_PSSR_10MBS 0x0000 /* 00=10Mbs */ +#define MII_AT001_PSSR_100MBS 0x4000 /* 01=100Mbs */ +#define MII_AT001_PSSR_1000MBS 0x8000 /* 10=1000Mbs */ + +/* PCI Command Register Bit Definitions */ +#define PCI_REG_COMMAND 0x04 +#define CMD_IO_SPACE 0x0001 +#define CMD_MEMORY_SPACE 0x0002 +#define CMD_BUS_MASTER 0x0004 + +/* Wake Up Filter Control */ +#define ATL2_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */ +#define ATL2_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */ +#define ATL2_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */ +#define ATL2_WUFC_MC 0x00000008 /* Multicast Wakeup Enable */ +#define ATL2_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */ + +/* Error Codes */ +#define ATL2_SUCCESS 0 +#define ATL2_ERR_EEPROM 1 +#define ATL2_ERR_PHY 2 +#define ATL2_ERR_CONFIG 3 +#define ATL2_ERR_PARAM 4 +#define ATL2_ERR_MAC_TYPE 5 +#define ATL2_ERR_PHY_TYPE 6 +#define ATL2_ERR_PHY_SPEED 7 +#define ATL2_ERR_PHY_RES 8 + +#define SPEED_0 0xffff +#define SPEED_10 10 +#define SPEED_100 100 +#define HALF_DUPLEX 1 +#define FULL_DUPLEX 2 + +#define MEDIA_TYPE_AUTO_SENSOR 0 +#define MEDIA_TYPE_100M_FULL 1 +#define MEDIA_TYPE_100M_HALF 2 +#define MEDIA_TYPE_10M_FULL 3 +#define MEDIA_TYPE_10M_HALF 4 + +#define ADVERTISE_10_HALF 0x0001 +#define ADVERTISE_10_FULL 0x0002 +#define ADVERTISE_100_HALF 0x0004 +#define ADVERTISE_100_FULL 0x0008 +#define ADVERTISE_1000_HALF 0x0010 /* Not used, just FYI */ +#define ADVERTISE_1000_FULL 0x0020 + +#define AUTONEG_ADVERTISE_SPEED_DEFAULT 0x000F /* Everything */ +#define AUTONEG_ADVERTISE_10_100_ALL 0x000F /* All 10/100 speeds*/ +#define AUTONEG_ADVERTISE_10_ALL 0x0003 /* 10Mbps Full & Half speeds*/ + +/* The size (in bytes) of a ethernet packet */ +#define ENET_HEADER_SIZE 14 +#define MAXIMUM_ETHERNET_FRAME_SIZE 1518 /* with FCS */ +#define MINIMUM_ETHERNET_FRAME_SIZE 64 /* with FCS */ +#define ETHERNET_FCS_SIZE 4 +#define MAX_JUMBO_FRAME_SIZE 0x2000 +#define VLAN_SIZE 4 + +#define PHY_AUTO_NEG_TIME 45 /* 4.5 Seconds */ +#define PHY_FORCE_TIME 20 /* 2.0 Seconds */ + +/* For checksumming , the sum of all words in the EEPROM should equal 0xBABA */ +#define EEPROM_SUM 0xBABA +#define NODE_ADDRESS_SIZE 6 + +typedef struct _tx_pkt_header { + unsigned pkt_size : 11; + unsigned : 4; // reserved + unsigned ins_vlan : 1; // txmac should insert vlan + unsigned short vlan ; // vlan tag +} tx_pkt_header_t; +/* FIXME: replace above bitfields with MASK/SHIFT defines below */ +#define TX_PKT_HEADER_SIZE_MASK 0x7FF +#define TX_PKT_HEADER_SIZE_SHIFT 0 +#define TX_PKT_HEADER_INS_VLAN_MASK 0x1 +#define TX_PKT_HEADER_INS_VLAN_SHIFT 15 +#define TX_PKT_HEADER_VLAN_TAG_MASK 0xFFFF +#define TX_PKT_HEADER_VLAN_TAG_SHIFT 16 + +typedef struct _tx_pkt_status { + unsigned pkt_size : 11; + unsigned : 5; // reserved + unsigned ok : 1; // current packet is transmitted ok without error + unsigned bcast : 1; // current packet is broadcast + unsigned mcast : 1; // current packet is multicast + unsigned pause : 1; // transmiited a pause frame + unsigned ctrl : 1; + unsigned defer : 1; // current packet is xmitted with defer. + unsigned exc_defer : 1; + unsigned single_col : 1; + unsigned multi_col : 1; + unsigned late_col : 1; + unsigned abort_col : 1; + unsigned underun : 1; // current packet is abort due to txram underrun. + unsigned : 3; // reserved + unsigned update : 1; // always 1'b1 in tx_status_buf. +} tx_pkt_status_t; +/* FIXME: replace above bitfields with MASK/SHIFT defines below */ +#define TX_PKT_STATUS_SIZE_MASK 0x7FF +#define TX_PKT_STATUS_SIZE_SHIFT 0 +#define TX_PKT_STATUS_OK_MASK 0x1 +#define TX_PKT_STATUS_OK_SHIFT 16 +#define TX_PKT_STATUS_BCAST_MASK 0x1 +#define TX_PKT_STATUS_BCAST_SHIFT 17 +#define TX_PKT_STATUS_MCAST_MASK 0x1 +#define TX_PKT_STATUS_MCAST_SHIFT 18 +#define TX_PKT_STATUS_PAUSE_MASK 0x1 +#define TX_PKT_STATUS_PAUSE_SHIFT 19 +#define TX_PKT_STATUS_CTRL_MASK 0x1 +#define TX_PKT_STATUS_CTRL_SHIFT 20 +#define TX_PKT_STATUS_DEFER_MASK 0x1 +#define TX_PKT_STATUS_DEFER_SHIFT 21 +#define TX_PKT_STATUS_EXC_DEFER_MASK 0x1 +#define TX_PKT_STATUS_EXC_DEFER_SHIFT 22 +#define TX_PKT_STATUS_SINGLE_COL_MASK 0x1 +#define TX_PKT_STATUS_SINGLE_COL_SHIFT 23 +#define TX_PKT_STATUS_MULTI_COL_MASK 0x1 +#define TX_PKT_STATUS_MULTI_COL_SHIFT 24 +#define TX_PKT_STATUS_LATE_COL_MASK 0x1 +#define TX_PKT_STATUS_LATE_COL_SHIFT 25 +#define TX_PKT_STATUS_ABORT_COL_MASK 0x1 +#define TX_PKT_STATUS_ABORT_COL_SHIFT 26 +#define TX_PKT_STATUS_UNDERRUN_MASK 0x1 +#define TX_PKT_STATUS_UNDERRUN_SHIFT 27 +#define TX_PKT_STATUS_UPDATE_MASK 0x1 +#define TX_PKT_STATUS_UPDATE_SHIFT 31 + +typedef struct _rx_pkt_status { + unsigned pkt_size : 11; // packet size, max 2047bytes + unsigned : 5; // reserved + unsigned ok : 1; // current packet is received ok without error. + unsigned bcast : 1; // current packet is broadcast. + unsigned mcast : 1; // current packet is multicast. + unsigned pause : 1; + unsigned ctrl : 1; + unsigned crc : 1; // received a packet with crc error. + unsigned code : 1; // received a packet with code error. + unsigned runt : 1; // received a packet less than 64bytes with good crc + unsigned frag : 1; // ....................................with bad crc + unsigned trunc : 1; // current frame is cutted due to rxram full. + unsigned align : 1; // this packet is alignment error. + unsigned vlan : 1; // this packet has vlan + unsigned : 3; // reserved + unsigned update : 1; + unsigned short vtag ; // vlan tag + unsigned : 16; +} rx_pkt_status_t; +/* FIXME: replace above bitfields with MASK/SHIFT defines below */ +#define RX_PKT_STATUS_SIZE_MASK 0x7FF +#define RX_PKT_STATUS_SIZE_SHIFT 0 +#define RX_PKT_STATUS_OK_MASK 0x1 +#define RX_PKT_STATUS_OK_SHIFT 16 +#define RX_PKT_STATUS_BCAST_MASK 0x1 +#define RX_PKT_STATUS_BCAST_SHIFT 17 +#define RX_PKT_STATUS_MCAST_MASK 0x1 +#define RX_PKT_STATUS_MCAST_SHIFT 18 +#define RX_PKT_STATUS_PAUSE_MASK 0x1 +#define RX_PKT_STATUS_PAUSE_SHIFT 19 +#define RX_PKT_STATUS_CTRL_MASK 0x1 +#define RX_PKT_STATUS_CTRL_SHIFT 20 +#define RX_PKT_STATUS_CRC_MASK 0x1 +#define RX_PKT_STATUS_CRC_SHIFT 21 +#define RX_PKT_STATUS_CODE_MASK 0x1 +#define RX_PKT_STATUS_CODE_SHIFT 22 +#define RX_PKT_STATUS_RUNT_MASK 0x1 +#define RX_PKT_STATUS_RUNT_SHIFT 23 +#define RX_PKT_STATUS_FRAG_MASK 0x1 +#define RX_PKT_STATUS_FRAG_SHIFT 24 +#define RX_PKT_STATUS_TRUNK_MASK 0x1 +#define RX_PKT_STATUS_TRUNK_SHIFT 25 +#define RX_PKT_STATUS_ALIGN_MASK 0x1 +#define RX_PKT_STATUS_ALIGN_SHIFT 26 +#define RX_PKT_STATUS_VLAN_MASK 0x1 +#define RX_PKT_STATUS_VLAN_SHIFT 27 +#define RX_PKT_STATUS_UPDATE_MASK 0x1 +#define RX_PKT_STATUS_UPDATE_SHIFT 31 +#define RX_PKT_STATUS_VLAN_TAG_MASK 0xFFFF +#define RX_PKT_STATUS_VLAN_TAG_SHIFT 32 + +typedef struct _rx_desc { + rx_pkt_status_t status; + unsigned char packet[1536-sizeof(rx_pkt_status_t)]; +} rx_desc_t; + +typedef enum { + atl2_10_half = 0, + atl2_10_full = 1, + atl2_100_half = 2, + atl2_100_full = 3 +} atl2_speed_duplex_type; + +struct atl2_spi_flash_dev { + const char *manu_name; /* manufacturer id */ + /* op-code */ + u8 cmdWRSR; + u8 cmdREAD; + u8 cmdPROGRAM; + u8 cmdWREN; + u8 cmdWRDI; + u8 cmdRDSR; + u8 cmdRDID; + u8 cmdSECTOR_ERASE; + u8 cmdCHIP_ERASE; +}; + +/* Structure containing variables used by the shared code (atl2_hw.c) */ +struct atl2_hw { + u8 *hw_addr; + void *back; + + u8 preamble_len; + u8 max_retry; // Retransmission maximum , afterwards the packet will be discarded. + u8 jam_ipg; // IPG to start JAM for collision based flow control in half-duplex mode. In unit of 8-bit time. + u8 ipgt; // Desired back to back inter-packet gap. The default is 96-bit time. + u8 min_ifg; // Minimum number of IFG to enforce in between RX frames. Frame gap below such IFP is dropped. + u8 ipgr1; // 64bit Carrier-Sense window + u8 ipgr2; // 96-bit IPG window + u8 retry_buf; // When half-duplex mode, should hold some bytes for mac retry . (8*4bytes unit) + + u16 fc_rxd_hi; + u16 fc_rxd_lo; + u16 lcol; // Collision Window + u16 max_frame_size; + + u16 MediaType; + u16 autoneg_advertised; + u16 pci_cmd_word; + + u16 mii_autoneg_adv_reg; + + u32 mem_rang; + u32 txcw; + u32 mc_filter_type; + u32 num_mc_addrs; + u32 collision_delta; + u32 tx_packet_delta; + u16 phy_spd_default; + + u16 device_id; + u16 vendor_id; + u16 subsystem_id; + u16 subsystem_vendor_id; + u8 revision_id; + + // spi flash + u8 flash_vendor; + + u8 dma_fairness; + u8 mac_addr[NODE_ADDRESS_SIZE]; + u8 perm_mac_addr[NODE_ADDRESS_SIZE]; + + // bool phy_preamble_sup; + bool phy_configured; +}; + +#endif /* _ATL2_HW_H_ */ --- linux-2.6.28.orig/ubuntu/atl2/BOM +++ linux-2.6.28/ubuntu/atl2/BOM @@ -0,0 +1,2 @@ +Downloaded from: http://people.redhat.com/csnook/atl2/ +Current Version: 2.0.4 --- linux-2.6.28.orig/ubuntu/iscsitarget/digest.h +++ linux-2.6.28/ubuntu/iscsitarget/digest.h @@ -0,0 +1,20 @@ +/* + * iSCSI digest handling. + * (C) 2004 Xiranet Communications GmbH + * This code is licensed under the GPL. + */ + +#ifndef __IET_DIGEST_H__ +#define __IET_DIGEST_H__ + +extern void digest_alg_available(unsigned int *val); +extern int digest_init(struct iscsi_conn *conn); +extern void digest_cleanup(struct iscsi_conn *conn); + +extern int digest_rx_header(struct iscsi_cmnd *cmnd); +extern int digest_rx_data(struct iscsi_cmnd *cmnd); + +extern void digest_tx_header(struct iscsi_cmnd *cmnd); +extern void digest_tx_data(struct iscsi_cmnd *cmnd); + +#endif /* __IET_DIGEST_H__ */ --- linux-2.6.28.orig/ubuntu/iscsitarget/conn.c +++ linux-2.6.28/ubuntu/iscsitarget/conn.c @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2002-2003 Ardis Technolgies + * + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include + +#include "iscsi.h" +#include "iscsi_dbg.h" +#include "digest.h" + +static void print_conn_state(char *p, size_t size, unsigned long state) +{ + if (test_bit(CONN_ACTIVE, &state)) + snprintf(p, size, "%s", "active"); + else if (test_bit(CONN_CLOSING, &state)) + snprintf(p, size, "%s", "closing"); + else + snprintf(p, size, "%s", "unknown"); +} + +static void print_digest_state(char *p, size_t size, unsigned long flags) +{ + if (DIGEST_NONE & flags) + snprintf(p, size, "%s", "none"); + else if (DIGEST_CRC32C & flags) + snprintf(p, size, "%s", "crc32c"); + else + snprintf(p, size, "%s", "unknown"); +} + +void conn_info_show(struct seq_file *seq, struct iscsi_session *session) +{ + struct iscsi_conn *conn; + struct sock *sk; + char buf[64]; + + list_for_each_entry(conn, &session->conn_list, list) { + sk = conn->sock->sk; + switch (sk->sk_family) { + case AF_INET: + snprintf(buf, sizeof(buf), + "%u.%u.%u.%u", NIPQUAD(inet_sk(sk)->daddr)); + break; + case AF_INET6: + snprintf(buf, sizeof(buf), + "[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]", + NIP6(inet6_sk(sk)->daddr)); + break; + default: + break; + } + seq_printf(seq, "\t\tcid:%u ip:%s ", conn->cid, buf); + print_conn_state(buf, sizeof(buf), conn->state); + seq_printf(seq, "state:%s ", buf); + print_digest_state(buf, sizeof(buf), conn->hdigest_type); + seq_printf(seq, "hd:%s ", buf); + print_digest_state(buf, sizeof(buf), conn->ddigest_type); + seq_printf(seq, "dd:%s\n", buf); + } +} + +struct iscsi_conn *conn_lookup(struct iscsi_session *session, u16 cid) +{ + struct iscsi_conn *conn; + + list_for_each_entry(conn, &session->conn_list, list) { + if (conn->cid == cid) + return conn; + } + return NULL; +} + +static void iet_state_change(struct sock *sk) +{ + struct iscsi_conn *conn = sk->sk_user_data; + struct iscsi_target *target = conn->session->target; + + if (sk->sk_state != TCP_ESTABLISHED) + conn_close(conn); + else + nthread_wakeup(target); + + target->nthread_info.old_state_change(sk); +} + +static void iet_data_ready(struct sock *sk, int len) +{ + struct iscsi_conn *conn = sk->sk_user_data; + struct iscsi_target *target = conn->session->target; + + nthread_wakeup(target); + target->nthread_info.old_data_ready(sk, len); +} + +/* + * @locking: grabs the target's nthread_lock to protect it from races with + * set_conn_wspace_wait() + */ +static void iet_write_space(struct sock *sk) +{ + struct iscsi_conn *conn = sk->sk_user_data; + struct network_thread_info *info = &conn->session->target->nthread_info; + + spin_lock_bh(&info->nthread_lock); + + if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk) && + test_bit(CONN_WSPACE_WAIT, &conn->state)) { + clear_bit(CONN_WSPACE_WAIT, &conn->state); + __nthread_wakeup(info); + } + + spin_unlock_bh(&info->nthread_lock); + + info->old_write_space(sk); +} + +static void iet_socket_bind(struct iscsi_conn *conn) +{ + int opt = 1; + mm_segment_t oldfs; + struct iscsi_session *session = conn->session; + struct iscsi_target *target = session->target; + + dprintk(D_GENERIC, "%llu\n", (unsigned long long) session->sid); + + conn->sock = SOCKET_I(conn->file->f_dentry->d_inode); + conn->sock->sk->sk_user_data = conn; + + write_lock_bh(&conn->sock->sk->sk_callback_lock); + target->nthread_info.old_state_change = conn->sock->sk->sk_state_change; + conn->sock->sk->sk_state_change = iet_state_change; + + target->nthread_info.old_data_ready = conn->sock->sk->sk_data_ready; + conn->sock->sk->sk_data_ready = iet_data_ready; + + target->nthread_info.old_write_space = conn->sock->sk->sk_write_space; + conn->sock->sk->sk_write_space = iet_write_space; + write_unlock_bh(&conn->sock->sk->sk_callback_lock); + + oldfs = get_fs(); + set_fs(get_ds()); + conn->sock->ops->setsockopt(conn->sock, SOL_TCP, TCP_NODELAY, (void *)&opt, sizeof(opt)); + set_fs(oldfs); +} + +int conn_free(struct iscsi_conn *conn) +{ + dprintk(D_GENERIC, "%p %#Lx %u\n", conn->session, + (unsigned long long) conn->session->sid, conn->cid); + + assert(atomic_read(&conn->nr_cmnds) == 0); + assert(list_empty(&conn->pdu_list)); + assert(list_empty(&conn->write_list)); + + list_del(&conn->list); + list_del(&conn->poll_list); + + digest_cleanup(conn); + kfree(conn); + + return 0; +} + +static int iet_conn_alloc(struct iscsi_session *session, struct conn_info *info) +{ + struct iscsi_conn *conn; + + dprintk(D_SETUP, "%#Lx:%u\n", (unsigned long long) session->sid, info->cid); + + conn = kzalloc(sizeof(*conn), GFP_KERNEL); + if (!conn) + return -ENOMEM; + + conn->session = session; + conn->cid = info->cid; + conn->stat_sn = info->stat_sn; + conn->exp_stat_sn = info->exp_stat_sn; + + conn->hdigest_type = info->header_digest; + conn->ddigest_type = info->data_digest; + if (digest_init(conn) < 0) { + kfree(conn); + return -ENOMEM; + } + + spin_lock_init(&conn->list_lock); + atomic_set(&conn->nr_cmnds, 0); + atomic_set(&conn->nr_busy_cmnds, 0); + INIT_LIST_HEAD(&conn->pdu_list); + INIT_LIST_HEAD(&conn->write_list); + INIT_LIST_HEAD(&conn->poll_list); + + list_add(&conn->list, &session->conn_list); + + set_bit(CONN_ACTIVE, &conn->state); + + conn->file = fget(info->fd); + iet_socket_bind(conn); + + list_add(&conn->poll_list, &session->target->nthread_info.active_conns); + + nthread_wakeup(conn->session->target); + + return 0; +} + +void conn_close(struct iscsi_conn *conn) +{ + if (test_and_clear_bit(CONN_ACTIVE, &conn->state)) + set_bit(CONN_CLOSING, &conn->state); + + nthread_wakeup(conn->session->target); +} + +int conn_add(struct iscsi_session *session, struct conn_info *info) +{ + struct iscsi_conn *conn; + int err = -EEXIST; + + conn = conn_lookup(session, info->cid); + if (conn) + return err; + + return iet_conn_alloc(session, info); +} + +int conn_del(struct iscsi_session *session, struct conn_info *info) +{ + struct iscsi_conn *conn; + int err = -EEXIST; + + conn = conn_lookup(session, info->cid); + if (!conn) + return err; + + conn_close(conn); + + return 0; +} --- linux-2.6.28.orig/ubuntu/iscsitarget/param.c +++ linux-2.6.28/ubuntu/iscsitarget/param.c @@ -0,0 +1,194 @@ +/* + * (C) 2005 FUJITA Tomonori + * + * This code is licenced under the GPL. + */ + +#include "iscsi.h" +#include "iscsi_dbg.h" +#include "digest.h" + +struct target_type *target_type_array[] = { + &disk_ops, +}; + +#define CHECK_PARAM(info, iparam, word, min, max) \ +do { \ + if (!info->partial || (info->partial & 1 << key_##word)) \ + if (iparam[key_##word] < min || \ + iparam[key_##word] > max) { \ + eprintk("%s: %u is out of range (%u %u)\n", \ + #word, iparam[key_##word], min, max); \ + iparam[key_##word] = min; \ + } \ +} while (0) + +#define SET_PARAM(param, info, iparam, word) \ +({ \ + int changed = 0; \ + if (!info->partial || (info->partial & 1 << key_##word)) { \ + if (param->word != iparam[key_##word]) \ + changed = 1; \ + param->word = iparam[key_##word]; \ + } \ + changed; \ +}) + +#define GET_PARAM(param, info, iparam, word) \ +do { \ + iparam[key_##word] = param->word; \ +} while (0) + +static void sess_param_check(struct iscsi_param_info *info) +{ + u32 *iparam = info->session_param; + + CHECK_PARAM(info, iparam, max_connections, 1, 1); + CHECK_PARAM(info, iparam, max_recv_data_length, 512, + (u32) ((ISCSI_CONN_IOV_MAX - 1) * PAGE_CACHE_SIZE)); + CHECK_PARAM(info, iparam, max_xmit_data_length, 512, + (u32) ((ISCSI_CONN_IOV_MAX - 1) * PAGE_CACHE_SIZE)); + CHECK_PARAM(info, iparam, error_recovery_level, 0, 0); + CHECK_PARAM(info, iparam, data_pdu_inorder, 1, 1); + CHECK_PARAM(info, iparam, data_sequence_inorder, 1, 1); + + digest_alg_available(&iparam[key_header_digest]); + digest_alg_available(&iparam[key_data_digest]); + + CHECK_PARAM(info, iparam, ofmarker, 0, 0); + CHECK_PARAM(info, iparam, ifmarker, 0, 0); +} + +static void sess_param_set(struct iscsi_sess_param *param, struct iscsi_param_info *info) +{ + u32 *iparam = info->session_param; + + SET_PARAM(param, info, iparam, initial_r2t); + SET_PARAM(param, info, iparam, immediate_data); + SET_PARAM(param, info, iparam, max_connections); + SET_PARAM(param, info, iparam, max_recv_data_length); + SET_PARAM(param, info, iparam, max_xmit_data_length); + SET_PARAM(param, info, iparam, max_burst_length); + SET_PARAM(param, info, iparam, first_burst_length); + SET_PARAM(param, info, iparam, default_wait_time); + SET_PARAM(param, info, iparam, default_retain_time); + SET_PARAM(param, info, iparam, max_outstanding_r2t); + SET_PARAM(param, info, iparam, data_pdu_inorder); + SET_PARAM(param, info, iparam, data_sequence_inorder); + SET_PARAM(param, info, iparam, error_recovery_level); + SET_PARAM(param, info, iparam, header_digest); + SET_PARAM(param, info, iparam, data_digest); + SET_PARAM(param, info, iparam, ofmarker); + SET_PARAM(param, info, iparam, ifmarker); + SET_PARAM(param, info, iparam, ofmarkint); + SET_PARAM(param, info, iparam, ifmarkint); +} + +static void sess_param_get(struct iscsi_sess_param *param, struct iscsi_param_info *info) +{ + u32 *iparam = info->session_param; + + GET_PARAM(param, info, iparam, initial_r2t); + GET_PARAM(param, info, iparam, immediate_data); + GET_PARAM(param, info, iparam, max_connections); + GET_PARAM(param, info, iparam, max_recv_data_length); + GET_PARAM(param, info, iparam, max_xmit_data_length); + GET_PARAM(param, info, iparam, max_burst_length); + GET_PARAM(param, info, iparam, first_burst_length); + GET_PARAM(param, info, iparam, default_wait_time); + GET_PARAM(param, info, iparam, default_retain_time); + GET_PARAM(param, info, iparam, max_outstanding_r2t); + GET_PARAM(param, info, iparam, data_pdu_inorder); + GET_PARAM(param, info, iparam, data_sequence_inorder); + GET_PARAM(param, info, iparam, error_recovery_level); + GET_PARAM(param, info, iparam, header_digest); + GET_PARAM(param, info, iparam, data_digest); + GET_PARAM(param, info, iparam, ofmarker); + GET_PARAM(param, info, iparam, ifmarker); + GET_PARAM(param, info, iparam, ofmarkint); + GET_PARAM(param, info, iparam, ifmarkint); +} + +static void trgt_param_check(struct iscsi_param_info *info) +{ + u32 *iparam = info->target_param; + + CHECK_PARAM(info, iparam, wthreads, MIN_NR_WTHREADS, MAX_NR_WTHREADS); + CHECK_PARAM(info, iparam, target_type, 0, + (unsigned int) ARRAY_SIZE(target_type_array) - 1); + CHECK_PARAM(info, iparam, queued_cmnds, MIN_NR_QUEUED_CMNDS, MAX_NR_QUEUED_CMNDS); +} + +static void trgt_param_set(struct iscsi_target *target, struct iscsi_param_info *info) +{ + struct iscsi_trgt_param *param = &target->trgt_param; + u32 *iparam = info->target_param; + + if (SET_PARAM(param, info, iparam, wthreads)) + wthread_start(target); + SET_PARAM(param, info, iparam, target_type); + SET_PARAM(param, info, iparam, queued_cmnds); +} + +static void trgt_param_get(struct iscsi_trgt_param *param, struct iscsi_param_info *info) +{ + u32 *iparam = info->target_param; + + GET_PARAM(param, info, iparam, wthreads); + GET_PARAM(param, info, iparam, target_type); + GET_PARAM(param, info, iparam, queued_cmnds); +} + +static int trgt_param(struct iscsi_target *target, struct iscsi_param_info *info, int set) +{ + + if (set) { + trgt_param_check(info); + trgt_param_set(target, info); + } else + trgt_param_get(&target->trgt_param, info); + + return 0; +} + +static int sess_param(struct iscsi_target *target, struct iscsi_param_info *info, int set) +{ + struct iscsi_session *session = NULL; + struct iscsi_sess_param *param; + int err = -ENOENT; + + if (set) + sess_param_check(info); + + if (info->sid) { + if (!(session = session_lookup(target, info->sid))) + goto out; + param = &session->param; + } else { + param = &target->sess_param; + } + + if (set) { + sess_param_set(param, info); + show_param(param); + } else + sess_param_get(param, info); + + err = 0; +out: + return err; +} + +int iscsi_param_set(struct iscsi_target *target, struct iscsi_param_info *info, int set) +{ + int err; + + if (info->param_type == key_session) + err = sess_param(target, info, set); + else if (info->param_type == key_target) + err = trgt_param(target, info, set); + else + err = -EINVAL; + + return err; +} --- linux-2.6.28.orig/ubuntu/iscsitarget/null-io.c +++ linux-2.6.28/ubuntu/iscsitarget/null-io.c @@ -0,0 +1,114 @@ +/* + * Target device null I/O. + * (C) 2005 MING Zhang + * This code is licenced under the GPL. + * + * The nullio mode will not return any meaningful or previous written + * data. It is only for performance measurement purpose. + */ + +#include +#include +#include +#include + +#include "iscsi.h" +#include "iscsi_dbg.h" +#include "iotype.h" + +struct nullio_data { + u64 sectors; +}; + +enum { + Opt_sectors, Opt_ignore, Opt_err, +}; + +static match_table_t tokens = { + {Opt_sectors, "Sectors=%u"}, + {Opt_ignore, "Type=%s"}, + {Opt_err, NULL}, +}; + +static int parse_nullio_params(struct iet_volume *volume, char *params) +{ + int err = 0; + char *p, *q; + struct nullio_data *data = volume->private; + + while ((p = strsep(¶ms, ",")) != NULL) { + substring_t args[MAX_OPT_ARGS]; + int token; + if (!*p) + continue; + token = match_token(p, tokens, args); + switch (token) { + case Opt_sectors: + q = match_strdup(&args[0]); + if (!q) + return -ENOMEM; + data->sectors = simple_strtoull(q, NULL, 10); + kfree(q); + break; + case Opt_ignore: + break; + default: + eprintk("Unknown %s\n", p); + return -EINVAL; + break; + } + } + return err; +} + +static void nullio_detach(struct iet_volume *lu) +{ + struct nullio_data *p = lu->private; + + kfree(p); + lu->private = NULL; +} + +static int nullio_attach(struct iet_volume *lu, char *args) +{ + int err = 0; + struct nullio_data *p; + + if (lu->private) { + printk("already attached ? %d\n", lu->lun); + return -EBUSY; + } + + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (!p) + return -ENOMEM; + + lu->private = p; + + if ((err = parse_nullio_params(lu, args)) < 0) { + eprintk("%d\n", err); + goto out; + } + + lu->blk_shift = SECTOR_SIZE_BITS; + lu->blk_cnt = (p->sectors = p->sectors ? : 1 << 27); /* 64 GB */ + +out: + if (err < 0) + nullio_detach(lu); + return err; +} + +void nullio_show(struct iet_volume *lu, struct seq_file *seq) +{ + struct nullio_data *p = lu->private; + seq_printf(seq, " sectors:%llu\n", p->sectors); +} + +struct iotype nullio = +{ + .name = "nullio", + .attach = nullio_attach, + .detach = nullio_detach, + .show = nullio_show, +}; --- linux-2.6.28.orig/ubuntu/iscsitarget/target.c +++ linux-2.6.28/ubuntu/iscsitarget/target.c @@ -0,0 +1,281 @@ +/* + * Copyright (C) 2002-2003 Ardis Technolgies + * + * Released under the terms of the GNU GPL v2.0. + */ + +#include "iscsi.h" +#include "digest.h" +#include "iscsi_dbg.h" + +#define MAX_NR_TARGETS (1UL << 30) + +static LIST_HEAD(target_list); +static DECLARE_MUTEX(target_list_sem); +static u32 next_target_id; +static u32 nr_targets; + +static struct iscsi_sess_param default_session_param = { + .initial_r2t = 1, + .immediate_data = 1, + .max_connections = 1, + .max_recv_data_length = 8192, + .max_xmit_data_length = 8192, + .max_burst_length = 262144, + .first_burst_length = 65536, + .default_wait_time = 2, + .default_retain_time = 20, + .max_outstanding_r2t = 1, + .data_pdu_inorder = 1, + .data_sequence_inorder = 1, + .error_recovery_level = 0, + .header_digest = DIGEST_NONE, + .data_digest = DIGEST_NONE, + .ofmarker = 0, + .ifmarker = 0, + .ofmarkint = 2048, + .ifmarkint = 2048, +}; + +static struct iscsi_trgt_param default_target_param = { + .wthreads = DEFAULT_NR_WTHREADS, + .target_type = 0, + .queued_cmnds = DEFAULT_NR_QUEUED_CMNDS, +}; + +inline int target_lock(struct iscsi_target *target, int interruptible) +{ + int err = 0; + + if (interruptible) + err = down_interruptible(&target->target_sem); + else + down(&target->target_sem); + + return err; +} + +inline void target_unlock(struct iscsi_target *target) +{ + up(&target->target_sem); +} + +static struct iscsi_target *__target_lookup_by_id(u32 id) +{ + struct iscsi_target *target; + + list_for_each_entry(target, &target_list, t_list) { + if (target->tid == id) + return target; + } + return NULL; +} + +static struct iscsi_target *__target_lookup_by_name(char *name) +{ + struct iscsi_target *target; + + list_for_each_entry(target, &target_list, t_list) { + if (!strcmp(target->name, name)) + return target; + } + return NULL; +} + +struct iscsi_target *target_lookup_by_id(u32 id) +{ + struct iscsi_target *target; + + down(&target_list_sem); + target = __target_lookup_by_id(id); + up(&target_list_sem); + + return target; +} + +static int target_thread_start(struct iscsi_target *target) +{ + int err; + + if ((err = nthread_start(target)) < 0) + return err; + + if ((err = wthread_start(target)) < 0) { + nthread_stop(target); + } + + return err; +} + +static void target_thread_stop(struct iscsi_target *target) +{ + wthread_stop(target); + nthread_stop(target); +} + +static int iscsi_target_create(struct target_info *info, u32 tid) +{ + int err = -EINVAL, len; + char *name = info->name; + struct iscsi_target *target; + + dprintk(D_SETUP, "%u %s\n", tid, name); + + if (!(len = strlen(name))) { + eprintk("The length of the target name is zero %u\n", tid); + return err; + } + + if (!try_module_get(THIS_MODULE)) { + eprintk("Fail to get module %u\n", tid); + return err; + } + + target = kzalloc(sizeof(*target), GFP_KERNEL); + if (!target) { + err = -ENOMEM; + goto out; + } + + target->tid = info->tid = tid; + + memcpy(&target->sess_param, &default_session_param, sizeof(default_session_param)); + memcpy(&target->trgt_param, &default_target_param, sizeof(default_target_param)); + + strncpy(target->name, name, sizeof(target->name) - 1); + + init_MUTEX(&target->target_sem); + + INIT_LIST_HEAD(&target->session_list); + INIT_LIST_HEAD(&target->volumes); + + atomic_set(&target->nr_volumes, 0); + + list_add(&target->t_list, &target_list); + + nthread_init(target); + wthread_init(target); + + if ((err = target_thread_start(target)) < 0) { + target_thread_stop(target); + goto out; + } + + return 0; +out: + kfree(target); + module_put(THIS_MODULE); + + return err; +} + +int target_add(struct target_info *info) +{ + int err = -EEXIST; + u32 tid = info->tid; + + down(&target_list_sem); + + if (nr_targets > MAX_NR_TARGETS) { + err = -EBUSY; + goto out; + } + + if (__target_lookup_by_name(info->name)) + goto out; + + if (tid && __target_lookup_by_id(tid)) + goto out; + + if (!tid) { + do { + if (!++next_target_id) + ++next_target_id; + } while (__target_lookup_by_id(next_target_id)); + + tid = next_target_id; + } + + if (!(err = iscsi_target_create(info, tid))) + nr_targets++; +out: + up(&target_list_sem); + + return err; +} + +static void target_destroy(struct iscsi_target *target) +{ + dprintk(D_SETUP, "%u\n", target->tid); + + target_thread_stop(target); + + while (!list_empty(&target->volumes)) { + struct iet_volume *volume; + volume = list_entry(target->volumes.next, struct iet_volume, list); + volume->l_state = IDEV_DEL; + iscsi_volume_destroy(volume); + } + + kfree(target); + + module_put(THIS_MODULE); +} + +int target_del(u32 id) +{ + struct iscsi_target *target; + int err; + + if ((err = down_interruptible(&target_list_sem)) < 0) + return err; + + if (!(target = __target_lookup_by_id(id))) { + err = -ENOENT; + goto out; + } + + target_lock(target, 0); + + if (!list_empty(&target->session_list)) { + err = -EBUSY; + target_unlock(target); + goto out; + } + + list_del(&target->t_list); + nr_targets--; + + target_unlock(target); + up(&target_list_sem); + + target_destroy(target); + return 0; +out: + up(&target_list_sem); + return err; +} + +int iet_info_show(struct seq_file *seq, iet_show_info_t *func) +{ + int err; + struct iscsi_target *target; + + if ((err = down_interruptible(&target_list_sem)) < 0) + return err; + + list_for_each_entry(target, &target_list, t_list) { + seq_printf(seq, "tid:%u name:%s\n", target->tid, target->name); + + if ((err = target_lock(target, 1)) < 0) + break; + + func(seq, target); + + target_unlock(target); + } + + up(&target_list_sem); + + return 0; +} --- linux-2.6.28.orig/ubuntu/iscsitarget/iscsi_hdr.h +++ linux-2.6.28/ubuntu/iscsitarget/iscsi_hdr.h @@ -0,0 +1,509 @@ +/* + * Copyright (C) 2002-2003 Ardis Technolgies + * + * Released under the terms of the GNU GPL v2.0. + */ + +#ifndef __ISCSI_HDR_H__ +#define __ISCSI_HDR_H__ + +#include +#include + +#define ISCSI_VERSION 0 + +#ifndef __packed +#define __packed __attribute__ ((packed)) +#endif + +struct iscsi_hdr { + u8 opcode; /* 0 */ + u8 flags; + u8 spec1[2]; +#if defined(__BIG_ENDIAN_BITFIELD) + struct { /* 4 */ + unsigned ahslength : 8; + unsigned datalength : 24; + } length; +#elif defined(__LITTLE_ENDIAN_BITFIELD) + u32 length; /* 4 */ +#endif + u16 lun[4]; /* 8 */ + u32 itt; /* 16 */ + u32 ttt; /* 20 */ + u32 sn; /* 24 */ + u32 exp_sn; /* 28 */ + u32 max_sn; /* 32 */ + u32 spec3[3]; /* 36 */ +} __packed; /* 48 */ + +/* Opcode encoding bits */ +#define ISCSI_OP_RETRY 0x80 +#define ISCSI_OP_IMMEDIATE 0x40 +#define ISCSI_OPCODE_MASK 0x3F + +/* Client to Server Message Opcode values */ +#define ISCSI_OP_NOOP_OUT 0x00 +#define ISCSI_OP_SCSI_CMD 0x01 +#define ISCSI_OP_SCSI_TASK_MGT_MSG 0x02 +#define ISCSI_OP_LOGIN_CMD 0x03 +#define ISCSI_OP_TEXT_CMD 0x04 +#define ISCSI_OP_SCSI_DATA_OUT 0x05 +#define ISCSI_OP_LOGOUT_CMD 0x06 +#define ISCSI_OP_SNACK_CMD 0x10 + +#define ISCSI_OP_VENDOR1_CMD 0x1c +#define ISCSI_OP_VENDOR2_CMD 0x1d +#define ISCSI_OP_VENDOR3_CMD 0x1e +#define ISCSI_OP_VENDOR4_CMD 0x1f + +/* Server to Client Message Opcode values */ +#define ISCSI_OP_NOOP_IN 0x20 +#define ISCSI_OP_SCSI_RSP 0x21 +#define ISCSI_OP_SCSI_TASK_MGT_RSP 0x22 +#define ISCSI_OP_LOGIN_RSP 0x23 +#define ISCSI_OP_TEXT_RSP 0x24 +#define ISCSI_OP_SCSI_DATA_IN 0x25 +#define ISCSI_OP_LOGOUT_RSP 0x26 +#define ISCSI_OP_R2T 0x31 +#define ISCSI_OP_ASYNC_MSG 0x32 +#define ISCSI_OP_REJECT 0x3f + +struct iscsi_ahs_hdr { + u16 ahslength; + u8 ahstype; +} __packed; + +#define ISCSI_AHSTYPE_CDB 1 +#define ISCSI_AHSTYPE_RLENGTH 2 + +union iscsi_sid { + struct { + u8 isid[6]; /* Initiator Session ID */ + u16 tsih; /* Target Session ID */ + } id; + u64 id64; +} __packed; + +struct iscsi_scsi_cmd_hdr { + u8 opcode; + u8 flags; + u16 rsvd1; + u8 ahslength; + u8 datalength[3]; + u16 lun[4]; + u32 itt; + u32 data_length; + u32 cmd_sn; + u32 exp_stat_sn; + u8 scb[16]; +} __packed; + +#define ISCSI_CMD_FINAL 0x80 +#define ISCSI_CMD_READ 0x40 +#define ISCSI_CMD_WRITE 0x20 +#define ISCSI_CMD_ATTR_MASK 0x07 +#define ISCSI_CMD_UNTAGGED 0x00 +#define ISCSI_CMD_SIMPLE 0x01 +#define ISCSI_CMD_ORDERED 0x02 +#define ISCSI_CMD_HEAD_OF_QUEUE 0x03 +#define ISCSI_CMD_ACA 0x04 + +struct iscsi_cdb_ahdr { + u16 ahslength; + u8 ahstype; + u8 reserved; + u8 cdb[0]; +} __packed; + +struct iscsi_rlength_ahdr { + u16 ahslength; + u8 ahstype; + u8 reserved; + u32 read_length; +} __packed; + +struct iscsi_scsi_rsp_hdr { + u8 opcode; + u8 flags; + u8 response; + u8 cmd_status; + u8 ahslength; + u8 datalength[3]; + u32 rsvd1[2]; + u32 itt; + u32 snack; + u32 stat_sn; + u32 exp_cmd_sn; + u32 max_cmd_sn; + u32 exp_data_sn; + u32 bi_residual_count; + u32 residual_count; +} __packed; + +#define ISCSI_FLG_RESIDUAL_UNDERFLOW 0x02 +#define ISCSI_FLG_RESIDUAL_OVERFLOW 0x04 +#define ISCSI_FLG_BIRESIDUAL_UNDERFLOW 0x08 +#define ISCSI_FLG_BIRESIDUAL_OVERFLOW 0x10 + +#define ISCSI_RESPONSE_COMMAND_COMPLETED 0x00 +#define ISCSI_RESPONSE_TARGET_FAILURE 0x01 + +struct iscsi_sense_data { + u16 length; + u8 data[0]; +} __packed; + +struct iscsi_task_mgt_hdr { + u8 opcode; + u8 function; + u16 rsvd1; + u8 ahslength; + u8 datalength[3]; + u16 lun[4]; + u32 itt; + u32 rtt; + u32 cmd_sn; + u32 exp_stat_sn; + u32 ref_cmd_sn; + u32 exp_data_sn; + u32 rsvd2[2]; +} __packed; + +#define ISCSI_FUNCTION_MASK 0x7f + +#define ISCSI_FUNCTION_ABORT_TASK 1 +#define ISCSI_FUNCTION_ABORT_TASK_SET 2 +#define ISCSI_FUNCTION_CLEAR_ACA 3 +#define ISCSI_FUNCTION_CLEAR_TASK_SET 4 +#define ISCSI_FUNCTION_LOGICAL_UNIT_RESET 5 +#define ISCSI_FUNCTION_TARGET_WARM_RESET 6 +#define ISCSI_FUNCTION_TARGET_COLD_RESET 7 +#define ISCSI_FUNCTION_TASK_REASSIGN 8 + +struct iscsi_task_rsp_hdr { + u8 opcode; + u8 flags; + u8 response; + u8 rsvd1; + u8 ahslength; + u8 datalength[3]; + u32 rsvd2[2]; + u32 itt; + u32 rsvd3; + u32 stat_sn; + u32 exp_cmd_sn; + u32 max_cmd_sn; + u32 rsvd4[3]; +} __packed; + +#define ISCSI_RESPONSE_FUNCTION_COMPLETE 0 +#define ISCSI_RESPONSE_UNKNOWN_TASK 1 +#define ISCSI_RESPONSE_UNKNOWN_LUN 2 +#define ISCSI_RESPONSE_TASK_ALLEGIANT 3 +#define ISCSI_RESPONSE_FAILOVER_UNSUPPORTED 4 +#define ISCSI_RESPONSE_FUNCTION_UNSUPPORTED 5 +#define ISCSI_RESPONSE_NO_AUTHORIZATION 6 +#define ISCSI_RESPONSE_FUNCTION_REJECTED 255 + +struct iscsi_data_out_hdr { + u8 opcode; + u8 flags; + u16 rsvd1; + u8 ahslength; + u8 datalength[3]; + u16 lun[4]; + u32 itt; + u32 ttt; + u32 rsvd2; + u32 exp_stat_sn; + u32 rsvd3; + u32 data_sn; + u32 buffer_offset; + u32 rsvd4; +} __packed; + +struct iscsi_data_in_hdr { + u8 opcode; + u8 flags; + u8 rsvd1; + u8 cmd_status; + u8 ahslength; + u8 datalength[3]; + u32 rsvd2[2]; + u32 itt; + u32 ttt; + u32 stat_sn; + u32 exp_cmd_sn; + u32 max_cmd_sn; + u32 data_sn; + u32 buffer_offset; + u32 residual_count; +} __packed; + +#define ISCSI_FLG_STATUS 0x01 + +struct iscsi_r2t_hdr { + u8 opcode; + u8 flags; + u16 rsvd1; + u8 ahslength; + u8 datalength[3]; + u16 lun[4]; + u32 itt; + u32 ttt; + u32 stat_sn; + u32 exp_cmd_sn; + u32 max_cmd_sn; + u32 r2t_sn; + u32 buffer_offset; + u32 data_length; +} __packed; + +struct iscsi_async_msg_hdr { + u8 opcode; + u8 flags; + u16 rsvd1; + u8 ahslength; + u8 datalength[3]; + u16 lun[4]; + u32 ffffffff; + u32 rsvd2; + u32 stat_sn; + u32 exp_cmd_sn; + u32 max_cmd_sn; + u8 async_event; + u8 async_vcode; + u16 param1; + u16 param2; + u16 param3; + u32 rsvd3; +} __packed; + +#define ISCSI_ASYNC_SCSI 0 +#define ISCSI_ASYNC_LOGOUT 1 +#define ISCSI_ASYNC_DROP_CONNECTION 2 +#define ISCSI_ASYNC_DROP_SESSION 3 +#define ISCSI_ASYNC_PARAM_REQUEST 4 +#define ISCSI_ASYNC_VENDOR 255 + +struct iscsi_text_req_hdr { + u8 opcode; + u8 flags; + u16 rsvd1; + u8 ahslength; + u8 datalength[3]; + u32 rsvd2[2]; + u32 itt; + u32 ttt; + u32 cmd_sn; + u32 exp_stat_sn; + u32 rsvd3[4]; +} __packed; + +struct iscsi_text_rsp_hdr { + u8 opcode; + u8 flags; + u16 rsvd1; + u8 ahslength; + u8 datalength[3]; + u32 rsvd2[2]; + u32 itt; + u32 ttt; + u32 stat_sn; + u32 exp_cmd_sn; + u32 max_cmd_sn; + u32 rsvd3[3]; +} __packed; + +struct iscsi_login_req_hdr { + u8 opcode; + u8 flags; + u8 max_version; /* Max. version supported */ + u8 min_version; /* Min. version supported */ + u8 ahslength; + u8 datalength[3]; + union iscsi_sid sid; + u32 itt; /* Initiator Task Tag */ + u16 cid; /* Connection ID */ + u16 rsvd1; + u32 cmd_sn; + u32 exp_stat_sn; + u32 rsvd2[4]; +} __packed; + +struct iscsi_login_rsp_hdr { + u8 opcode; + u8 flags; + u8 max_version; /* Max. version supported */ + u8 active_version; /* Active version */ + u8 ahslength; + u8 datalength[3]; + union iscsi_sid sid; + u32 itt; /* Initiator Task Tag */ + u32 rsvd1; + u32 stat_sn; + u32 exp_cmd_sn; + u32 max_cmd_sn; + u8 status_class; /* see Login RSP ststus classes below */ + u8 status_detail; /* see Login RSP Status details below */ + u8 rsvd2[10]; +} __packed; + +#define ISCSI_FLG_FINAL 0x80 +#define ISCSI_FLG_TRANSIT 0x80 +#define ISCSI_FLG_CSG_SECURITY 0x00 +#define ISCSI_FLG_CSG_LOGIN 0x04 +#define ISCSI_FLG_CSG_FULL_FEATURE 0x0c +#define ISCSI_FLG_CSG_MASK 0x0c +#define ISCSI_FLG_NSG_SECURITY 0x00 +#define ISCSI_FLG_NSG_LOGIN 0x01 +#define ISCSI_FLG_NSG_FULL_FEATURE 0x03 +#define ISCSI_FLG_NSG_MASK 0x03 + +/* Login Status response classes */ +#define ISCSI_STATUS_SUCCESS 0x00 +#define ISCSI_STATUS_REDIRECT 0x01 +#define ISCSI_STATUS_INITIATOR_ERR 0x02 +#define ISCSI_STATUS_TARGET_ERR 0x03 + +/* Login Status response detail codes */ +/* Class-0 (Success) */ +#define ISCSI_STATUS_ACCEPT 0x00 + +/* Class-1 (Redirection) */ +#define ISCSI_STATUS_TGT_MOVED_TEMP 0x01 +#define ISCSI_STATUS_TGT_MOVED_PERM 0x02 + +/* Class-2 (Initiator Error) */ +#define ISCSI_STATUS_INIT_ERR 0x00 +#define ISCSI_STATUS_AUTH_FAILED 0x01 +#define ISCSI_STATUS_TGT_FORBIDDEN 0x02 +#define ISCSI_STATUS_TGT_NOT_FOUND 0x03 +#define ISCSI_STATUS_TGT_REMOVED 0x04 +#define ISCSI_STATUS_NO_VERSION 0x05 +#define ISCSI_STATUS_TOO_MANY_CONN 0x06 +#define ISCSI_STATUS_MISSING_FIELDS 0x07 +#define ISCSI_STATUS_CONN_ADD_FAILED 0x08 +#define ISCSI_STATUS_INV_SESSION_TYPE 0x09 +#define ISCSI_STATUS_SESSION_NOT_FOUND 0x0a +#define ISCSI_STATUS_INV_REQ_TYPE 0x0b + +/* Class-3 (Target Error) */ +#define ISCSI_STATUS_TARGET_ERROR 0x00 +#define ISCSI_STATUS_SVC_UNAVAILABLE 0x01 +#define ISCSI_STATUS_NO_RESOURCES 0x02 + +struct iscsi_logout_req_hdr { + u8 opcode; + u8 flags; + u16 rsvd1; + u8 ahslength; + u8 datalength[3]; + u32 rsvd2[2]; + u32 itt; + u16 cid; + u16 rsvd3; + u32 cmd_sn; + u32 exp_stat_sn; + u32 rsvd4[4]; +} __packed; + +struct iscsi_logout_rsp_hdr { + u8 opcode; + u8 flags; + u8 response; + u8 rsvd1; + u8 ahslength; + u8 datalength[3]; + u32 rsvd2[2]; + u32 itt; + u32 rsvd3; + u32 stat_sn; + u32 exp_cmd_sn; + u32 max_cmd_sn; + u32 rsvd4; + u16 time2wait; + u16 time2retain; + u32 rsvd5; +} __packed; + +struct iscsi_snack_req_hdr { + u8 opcode; + u8 flags; + u16 rsvd1; + u8 ahslength; + u8 datalength[3]; + u32 rsvd2[2]; + u32 itt; + u32 ttt; + u32 rsvd3; + u32 exp_stat_sn; + u32 rsvd4[2]; + u32 beg_run; + u32 run_length; +} __packed; + +struct iscsi_reject_hdr { + u8 opcode; + u8 flags; + u8 reason; + u8 rsvd1; + u8 ahslength; + u8 datalength[3]; + u32 rsvd2[2]; + u32 ffffffff; + u32 rsvd3; + u32 stat_sn; + u32 exp_cmd_sn; + u32 max_cmd_sn; + u32 data_sn; + u32 rsvd4[2]; +} __packed; + +#define ISCSI_REASON_NO_FULL_FEATURE_PHASE 0x01 +#define ISCSI_REASON_DATA_DIGEST_ERROR 0x02 +#define ISCSI_REASON_DATA_SNACK_REJECT 0x03 +#define ISCSI_REASON_PROTOCOL_ERROR 0x04 +#define ISCSI_REASON_UNSUPPORTED_COMMAND 0x05 +#define ISCSI_REASON_IMMEDIATE_COMMAND_REJECT 0x06 +#define ISCSI_REASON_TASK_IN_PROGRESS 0x07 +#define ISCSI_REASON_INVALID_SNACK 0x08 +#define ISCSI_REASON_NO_BOOKMARK 0x09 +#define ISCSI_REASON_BOOKMARK_REJECT 0x0a +#define ISCSI_REASON_NEGOTIATION_RESET 0x0b +#define ISCSI_REASON_WAITING_LOGOUT 0x0c + + +struct iscsi_nop_out_hdr { + u8 opcode; + u8 flags; + u16 rsvd1; + u8 ahslength; + u8 datalength[3]; + u16 lun[4]; + u32 itt; + u32 ttt; + u32 cmd_sn; + u32 exp_stat_sn; + u32 rsvd2[4]; +} __packed; + +struct iscsi_nop_in_hdr { + u8 opcode; + u8 flags; + u16 rsvd1; + u8 ahslength; + u8 datalength[3]; + u16 lun[4]; + u32 itt; + u32 ttt; + u32 stat_sn; + u32 exp_cmd_sn; + u32 max_cmd_sn; + u32 rsvd2[3]; +} __packed; + +#define ISCSI_RESERVED_TAG (0xffffffffU) + +#endif /* __ISCSI_HDR_H__ */ --- linux-2.6.28.orig/ubuntu/iscsitarget/iscsi_dbg.h +++ linux-2.6.28/ubuntu/iscsitarget/iscsi_dbg.h @@ -0,0 +1,130 @@ +#ifndef ISCSI_DBG_H +#define ISCSI_DBG_H + +#define D_SETUP (1UL << 0) +#define D_EXIT (1UL << 1) +#define D_GENERIC (1UL << 2) +#define D_READ (1UL << 3) +#define D_WRITE (1UL << 4) +#define D_IOD (1UL << 5) +#define D_THREAD (1UL << 6) +#define D_TASK_MGT (1UL << 7) +#define D_IOMODE (1UL << 8) + +#define D_DATA (D_READ | D_WRITE) + +extern unsigned long debug_enable_flags; + +#define PFX "iscsi_trgt: " + +#define dprintk(debug, fmt, args...) do { \ + if ((debug) & debug_enable_flags) { \ + printk(KERN_DEBUG PFX "%s(%d) " fmt, __FUNCTION__,\ + __LINE__, args);\ + } \ +} while (0) + +#define eprintk(fmt, args...) do { \ + printk(KERN_ERR PFX "%s(%d) " fmt, __FUNCTION__, \ + __LINE__, args);\ +} while (0) + +#define iprintk(X...) printk(KERN_INFO PFX X) + +#define assert(p) do { \ + if (!(p)) { \ + printk(KERN_CRIT PFX "BUG at %s:%d assert(%s)\n",\ + __FILE__, __LINE__, #p); \ + dump_stack(); \ + BUG(); \ + } \ +} while (0) + +#ifdef D_IOV +static inline void iscsi_dump_iov(struct msghdr *msg) +{ + int i; + printk(PFX "%p, %d\n", msg->msg_iov, msg->msg_iovlen); + for (i = 0; i < min_t(size_t, msg->msg_iovlen, ISCSI_CONN_IOV_MAX); i++) + printk(PFX "%d: %p,%d\n", i, msg->msg_iov[i].iov_base, + msg->msg_iov[i].iov_len); +} +#else +#define iscsi_dump_iov(x) do {} while (0) +#endif + +#ifdef D_DUMP_PDU +static void iscsi_dump_char(int ch) +{ + static unsigned char text[16]; + static int i = 0; + + if (ch < 0) { + while ((i % 16) != 0) { + printk(" "); + text[i] = ' '; + i++; + if ((i % 16) == 0) + printk(" | %.16s |\n", text); + else if ((i % 4) == 0) + printk(" |"); + } + i = 0; + return; + } + + text[i] = (ch < 0x20 || (ch >= 0x80 && ch <= 0xa0)) ? ' ' : ch; + printk(" %02x", ch); + i++; + if ((i % 16) == 0) { + printk(" | %.16s |\n", text); + i = 0; + } else if ((i % 4) == 0) + printk(" |"); +} + +static inline void iscsi_dump_pdu(struct iscsi_pdu *pdu) +{ + unsigned char *buf; + int i; + + buf = (void *)&pdu->bhs; + printk(PFX "BHS: (%p,%d)\n", buf, sizeof(pdu->bhs)); + for (i = 0; i < sizeof(pdu->bhs); i++) + iscsi_dump_char(*buf++); + iscsi_dump_char(-1); + + buf = (void *)pdu->ahs; + printk(PFX "AHS: (%p,%d)\n", buf, pdu->ahssize); + for (i = 0; i < pdu->ahssize; i++) + iscsi_dump_char(*buf++); + iscsi_dump_char(-1); + + printk(PFX "Data: (%d)\n", pdu->datasize); +} + +#else +#define iscsi_dump_pdu(x) do {} while (0) +#endif + +#define show_param(param)\ +{\ + dprintk(D_SETUP, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",\ + (param)->initial_r2t,\ + (param)->immediate_data,\ + (param)->max_connections,\ + (param)->max_recv_data_length,\ + (param)->max_xmit_data_length,\ + (param)->max_burst_length,\ + (param)->first_burst_length,\ + (param)->default_wait_time,\ + (param)->default_retain_time,\ + (param)->max_outstanding_r2t,\ + (param)->data_pdu_inorder,\ + (param)->data_sequence_inorder,\ + (param)->error_recovery_level,\ + (param)->header_digest,\ + (param)->data_digest);\ +} + +#endif --- linux-2.6.28.orig/ubuntu/iscsitarget/Kconfig +++ linux-2.6.28/ubuntu/iscsitarget/Kconfig @@ -0,0 +1,3 @@ +config SCSI_ISCSITARGET + tristate "iSCSI Target Driver" + depends on SCSI --- linux-2.6.28.orig/ubuntu/iscsitarget/target_disk.c +++ linux-2.6.28/ubuntu/iscsitarget/target_disk.c @@ -0,0 +1,488 @@ +/* + * (C) 2004 - 2005 FUJITA Tomonori + * This code is licenced under the GPL. + * + * heavily based on code from kernel/iscsi.c: + * Copyright (C) 2002-2003 Ardis Technolgies , + * licensed under the terms of the GNU GPL v2.0, + */ + +#include +#include + +#include "iscsi.h" +#include "iscsi_dbg.h" + +static int insert_disconnect_pg(u8 *ptr) +{ + unsigned char disconnect_pg[] = {0x02, 0x0e, 0x80, 0x80, 0x00, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + memcpy(ptr, disconnect_pg, sizeof(disconnect_pg)); + return sizeof(disconnect_pg); +} + +static int insert_caching_pg(u8 *ptr, int wcache, int rcache) +{ + unsigned char caching_pg[] = {0x08, 0x12, 0x10, 0x00, 0xff, 0xff, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}; + + memcpy(ptr, caching_pg, sizeof(caching_pg)); + if (wcache) + ptr[2] |= 0x04; /* set WCE bit if we're caching writes */ + if (!rcache) + ptr[2] |= 0x01; /* Read Cache Disable */ + + return sizeof(caching_pg); +} + +static int insert_ctrl_m_pg(u8 *ptr) +{ + unsigned char ctrl_m_pg[] = {0x0a, 0x0a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x4b}; + + memcpy(ptr, ctrl_m_pg, sizeof(ctrl_m_pg)); + return sizeof(ctrl_m_pg); +} + +static int insert_iec_m_pg(u8 *ptr) +{ + unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00}; + + memcpy(ptr, iec_m_pg, sizeof(iec_m_pg)); + return sizeof(iec_m_pg); +} + +static int insert_format_m_pg(u8 *ptr) +{ + unsigned char format_m_pg[] = {0x03, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00}; + memcpy(ptr, format_m_pg, sizeof(format_m_pg)); + return sizeof(format_m_pg); +} + +static int insert_geo_m_pg(u8 *ptr, u64 sec) +{ + unsigned char geo_m_pg[] = {0x04, 0x16, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3a, 0x98, 0x00, 0x00}; + u32 ncyl; + u32 n; + + /* assume 0xff heads, 15krpm. */ + memcpy(ptr, geo_m_pg, sizeof(geo_m_pg)); + ncyl = sec >> 14; /* 256 * 64 */ + memcpy(&n, ptr+1, sizeof(u32)); + n = n | cpu_to_be32(ncyl); + memcpy(ptr+1, &n, sizeof(u32)); + return sizeof(geo_m_pg); +} + +static int build_mode_sense_response(struct iscsi_cmnd *cmnd) +{ + struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd); + struct tio *tio = cmnd->tio; + u8 *data, *scb = req->scb; + int len = 4, err = 0; + u8 pcode; + + /* changeable parameter mode pages are unsupported */ + if ((scb[2] & 0xc0) >> 6 == 0x1) + return -1; + + pcode = req->scb[2] & 0x3f; + + assert(!tio); + tio = cmnd->tio = tio_alloc(1); + data = page_address(tio->pvec[0]); + assert(data); + clear_page(data); + + if (LUReadonly(cmnd->lun)) + data[2] = 0x80; + + if ((scb[1] & 0x8)) + data[3] = 0; + else { + data[3] = 8; + len += 8; + *(u32 *)(data + 4) = (cmnd->lun->blk_cnt >> 32) ? + cpu_to_be32(0xffffffff) : cpu_to_be32(cmnd->lun->blk_cnt); + *(u32 *)(data + 8) = cpu_to_be32(1 << cmnd->lun->blk_shift); + } + + switch (pcode) { + case 0x0: + break; + case 0x2: + len += insert_disconnect_pg(data + len); + break; + case 0x3: + len += insert_format_m_pg(data + len); + break; + case 0x4: + len += insert_geo_m_pg(data + len, cmnd->lun->blk_cnt); + break; + case 0x8: + len += insert_caching_pg(data + len, LUWCache(cmnd->lun), + LURCache(cmnd->lun)); + break; + case 0xa: + len += insert_ctrl_m_pg(data + len); + break; + case 0x1c: + len += insert_iec_m_pg(data + len); + break; + case 0x3f: + len += insert_disconnect_pg(data + len); + len += insert_format_m_pg(data + len); + len += insert_geo_m_pg(data + len, cmnd->lun->blk_cnt); + len += insert_caching_pg(data + len, LUWCache(cmnd->lun), + LURCache(cmnd->lun)); + len += insert_ctrl_m_pg(data + len); + len += insert_iec_m_pg(data + len); + break; + default: + err = -1; + } + + data[0] = len - 1; + + tio_set(tio, len, 0); + + return err; +} + +static int build_inquiry_response(struct iscsi_cmnd *cmnd) +{ + struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd); + struct tio *tio = cmnd->tio; + u8 *data; + u8 *scb = req->scb; + int err = -1; + + /* + * - CmdDt and EVPD both set or EVPD and Page Code set: illegal + * - CmdDt set: not supported + */ + if ((scb[1] & 0x3) > 0x1 || (!(scb[1] & 0x3) && scb[2])) + return err; + + assert(!tio); + tio = cmnd->tio = tio_alloc(1); + data = page_address(tio->pvec[0]); + assert(data); + clear_page(data); + + if (!(scb[1] & 0x3)) { + data[2] = 4; + data[3] = 0x52; + data[4] = 59; + data[7] = 0x02; + memset(data + 8, 0x20, 28); + memcpy(data + 8, + VENDOR_ID, min_t(size_t, strlen(VENDOR_ID), 8)); + memcpy(data + 16, + PRODUCT_ID, min_t(size_t, strlen(PRODUCT_ID), 16)); + memcpy(data + 32, + PRODUCT_REV, min_t(size_t, strlen(PRODUCT_REV), 4)); + data[58] = 0x03; + data[59] = 0x20; + data[60] = 0x09; + data[61] = 0x60; + data[62] = 0x03; + data[63] = 0x00; + tio_set(tio, 64, 0); + err = 0; + } else if (scb[1] & 0x1) { + /* EVPD bit set */ + if (scb[2] == 0x0) { + data[1] = 0x0; + data[3] = 3; + data[4] = 0x0; + data[5] = 0x80; + data[6] = 0x83; + tio_set(tio, 7, 0); + err = 0; + } else if (scb[2] == 0x80) { + int len = (cmnd->lun && strlen(cmnd->lun->scsi_sn)) ? + SCSI_SN_LEN : 4; + + data[1] = 0x80; + data[3] = len; + memset(data + 4, 0x20, len); + tio_set(tio, len + 4, 0); + err = 0; + + if (len == SCSI_SN_LEN) { + char *p, *q; + + p = data + 4 + len - 1; + q = cmnd->lun->scsi_sn + len - 1; + + for (; len > 0; len--, q--) + if (isascii(*q) && isprint(*q)) + *(p--) = *q; + } + } else if (scb[2] == 0x83) { + u32 len = SCSI_ID_LEN * sizeof(u8); + + data[1] = 0x83; + data[3] = len + 4; + data[4] = 0x1; + data[5] = 0x1; + data[7] = len; + if (cmnd->lun) /* We need this ? */ + memcpy(data + 8, cmnd->lun->scsi_id, len); + tio_set(tio, len + 8, 0); + err = 0; + } + } + + tio_set(tio, min_t(u8, tio->size, scb[4]), 0); + if (!cmnd->lun) + data[0] = TYPE_NO_LUN; + + return err; +} + +static int build_report_luns_response(struct iscsi_cmnd *cmnd) +{ + struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd); + struct tio *tio = cmnd->tio; + u32 *data, size, len; + struct iet_volume *lun; + int rest, idx = 0; + + size = (u32)req->scb[6] << 24 | (u32)req->scb[7] << 16 | + (u32)req->scb[8] << 8 | (u32)req->scb[9]; + if (size < 16) + return -1; + + len = atomic_read(&cmnd->conn->session->target->nr_volumes) * 8; + size = min(size & ~(8 - 1), len + 8); + + assert(!tio); + tio = cmnd->tio = tio_alloc(get_pgcnt(size, 0)); + tio_set(tio, size, 0); + + data = page_address(tio->pvec[idx]); + assert(data); + *data++ = cpu_to_be32(len); + *data++ = 0; + size -= 8; + rest = PAGE_CACHE_SIZE - 8; + list_for_each_entry(lun, &cmnd->conn->session->target->volumes, list) { + if (lun->l_state != IDEV_RUNNING) + continue; + + *data++ = cpu_to_be32((0x3ff & lun->lun) << 16 | + ((lun->lun > 0xff) ? (0x1 << 30) : 0)); + *data++ = 0; + if ((size -= 8) == 0) + break; + if ((rest -= 8) == 0) { + idx++; + data = page_address(tio->pvec[idx]); + rest = PAGE_CACHE_SIZE; + } + } + + return 0; +} + +static int build_read_capacity_response(struct iscsi_cmnd *cmnd) +{ + struct tio *tio = cmnd->tio; + u32 *data; + + assert(!tio); + tio = cmnd->tio = tio_alloc(1); + data = page_address(tio->pvec[0]); + assert(data); + clear_page(data); + + data[0] = (cmnd->lun->blk_cnt >> 32) ? + cpu_to_be32(0xffffffff) : cpu_to_be32(cmnd->lun->blk_cnt - 1); + data[1] = cpu_to_be32(1U << cmnd->lun->blk_shift); + + tio_set(tio, 8, 0); + return 0; +} + +static int build_request_sense_response(struct iscsi_cmnd *cmnd) +{ + struct tio *tio = cmnd->tio; + u8 *data; + + assert(!tio); + tio = cmnd->tio = tio_alloc(1); + data = page_address(tio->pvec[0]); + assert(data); + memset(data, 0, 18); + data[0] = 0xf0; + data[1] = 0; + data[2] = NO_SENSE; + data[7] = 10; + tio_set(tio, 18, 0); + + return 0; +} + +static int build_service_action_response(struct iscsi_cmnd *cmnd) +{ + struct tio *tio = cmnd->tio; + u32 *data; + u64 *data64; + +/* assert((req->scb[1] & 0x1f) == 0x10); */ + assert(!tio); + tio = cmnd->tio = tio_alloc(1); + data = page_address(tio->pvec[0]); + assert(data); + clear_page(data); + data64 = (u64*) data; + data64[0] = cpu_to_be64(cmnd->lun->blk_cnt - 1); + data[2] = cpu_to_be32(1UL << cmnd->lun->blk_shift); + + tio_set(tio, 12, 0); + return 0; +} + +static int build_read_response(struct iscsi_cmnd *cmnd) +{ + struct tio *tio = cmnd->tio; + + assert(tio); + assert(cmnd->lun); + + return tio_read(cmnd->lun, tio); +} + +static int build_write_response(struct iscsi_cmnd *cmnd) +{ + int err; + struct tio *tio = cmnd->tio; + + assert(tio); + assert(cmnd->lun); + + list_del_init(&cmnd->list); + err = tio_write(cmnd->lun, tio); + if (!err && !LUWCache(cmnd->lun)) + err = tio_sync(cmnd->lun, tio); + + return err; +} + +static int build_sync_cache_response(struct iscsi_cmnd *cmnd) +{ + assert(cmnd->lun); + return tio_sync(cmnd->lun, NULL); +} + +static int build_generic_response(struct iscsi_cmnd *cmnd) +{ + return 0; +} + +static int build_reserve_response(struct iscsi_cmnd *cmnd) +{ + return volume_reserve(cmnd->lun, cmnd->conn->session->sid); +} + +static int build_release_response(struct iscsi_cmnd *cmnd) +{ + return volume_release(cmnd->lun, + cmnd->conn->session->sid, 0); +} + +static int build_reservation_conflict_response(struct iscsi_cmnd *cmnd) +{ + return -EBUSY; +} + +static int disk_execute_cmnd(struct iscsi_cmnd *cmnd) +{ + struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd); + + req->opcode &= ISCSI_OPCODE_MASK; + + if (is_volume_reserved(cmnd->lun, + cmnd->conn->session->sid)) { + switch (req->scb[0]) { + case INQUIRY: + case RELEASE: + case REPORT_LUNS: + case REQUEST_SENSE: + /* allowed commands when reserved */ + break; + default: + /* return reservation conflict for all others */ + send_scsi_rsp(cmnd, + build_reservation_conflict_response); + return 0; + } + } + + switch (req->scb[0]) { + case INQUIRY: + send_data_rsp(cmnd, build_inquiry_response); + break; + case REPORT_LUNS: + send_data_rsp(cmnd, build_report_luns_response); + break; + case READ_CAPACITY: + send_data_rsp(cmnd, build_read_capacity_response); + break; + case MODE_SENSE: + send_data_rsp(cmnd, build_mode_sense_response); + break; + case REQUEST_SENSE: + send_data_rsp(cmnd, build_request_sense_response); + break; + case SERVICE_ACTION_IN: + send_data_rsp(cmnd, build_service_action_response); + break; + case READ_6: + case READ_10: + case READ_16: + send_data_rsp(cmnd, build_read_response); + break; + case WRITE_6: + case WRITE_10: + case WRITE_16: + case WRITE_VERIFY: + send_scsi_rsp(cmnd, build_write_response); + break; + case SYNCHRONIZE_CACHE: + send_scsi_rsp(cmnd, build_sync_cache_response); + break; + case RESERVE: + send_scsi_rsp(cmnd, build_reserve_response); + break; + case RELEASE: + send_scsi_rsp(cmnd, build_release_response); + break; + case START_STOP: + case TEST_UNIT_READY: + case VERIFY: + case VERIFY_16: + send_scsi_rsp(cmnd, build_generic_response); + break; + default: + eprintk("%s\n", "we should not come here!"); + break; + } + + return 0; +} + +struct target_type disk_ops = +{ + .id = 0, + .execute_cmnd = disk_execute_cmnd, +}; --- linux-2.6.28.orig/ubuntu/iscsitarget/nthread.c +++ linux-2.6.28/ubuntu/iscsitarget/nthread.c @@ -0,0 +1,731 @@ +/* + * Network thread. + * (C) 2004 - 2005 FUJITA Tomonori + * This code is licenced under the GPL. + */ + +#include +#include +#include +#include + +#include "iscsi.h" +#include "iscsi_dbg.h" +#include "digest.h" + +enum daemon_state_bit { + D_ACTIVE, + D_DATA_READY, +}; + +void __nthread_wakeup(struct network_thread_info *info) +{ + set_bit(D_DATA_READY, &info->flags); + wake_up_process(info->task); +} + +void nthread_wakeup(struct iscsi_target *target) +{ + struct network_thread_info *info = &target->nthread_info; + + spin_lock_bh(&info->nthread_lock); + __nthread_wakeup(info); + spin_unlock_bh(&info->nthread_lock); +} + +static inline void iscsi_conn_init_read(struct iscsi_conn *conn, void *data, size_t len) +{ + len = (len + 3) & -4; // XXX ??? + conn->read_iov[0].iov_base = data; + conn->read_iov[0].iov_len = len; + conn->read_msg.msg_iov = conn->read_iov; + conn->read_msg.msg_iovlen = 1; + conn->read_size = (len + 3) & -4; +} + +static void iscsi_conn_read_ahs(struct iscsi_conn *conn, struct iscsi_cmnd *cmnd) +{ + cmnd->pdu.ahs = kmalloc(cmnd->pdu.ahssize, __GFP_NOFAIL|GFP_KERNEL); + assert(cmnd->pdu.ahs); + iscsi_conn_init_read(conn, cmnd->pdu.ahs, cmnd->pdu.ahssize); +} + +static struct iscsi_cmnd * iscsi_get_send_cmnd(struct iscsi_conn *conn) +{ + struct iscsi_cmnd *cmnd = NULL; + + spin_lock(&conn->list_lock); + if (!list_empty(&conn->write_list)) { + cmnd = list_entry(conn->write_list.next, struct iscsi_cmnd, list); + list_del_init(&cmnd->list); + } + spin_unlock(&conn->list_lock); + + return cmnd; +} + +static int is_data_available(struct iscsi_conn *conn) +{ + int avail, res; + mm_segment_t oldfs; + struct socket *sock = conn->sock; + + oldfs = get_fs(); + set_fs(get_ds()); + res = sock->ops->ioctl(sock, SIOCINQ, (unsigned long) &avail); + set_fs(oldfs); + return (res >= 0) ? avail : res; +} + +static void forward_iov(struct msghdr *msg, int len) +{ + while (msg->msg_iov->iov_len <= len) { + len -= msg->msg_iov->iov_len; + msg->msg_iov++; + msg->msg_iovlen--; + } + + msg->msg_iov->iov_base = (char *) msg->msg_iov->iov_base + len; + msg->msg_iov->iov_len -= len; +} + +static int do_recv(struct iscsi_conn *conn, int state) +{ + mm_segment_t oldfs; + struct msghdr msg; + struct iovec iov[ISCSI_CONN_IOV_MAX]; + int i, len, res; + + if (!test_bit(CONN_ACTIVE, &conn->state)) { + res = -EIO; + goto out; + } + + if (is_data_available(conn) <= 0) { + res = -EAGAIN; + goto out; + } + + msg.msg_iov = iov; + msg.msg_iovlen = min_t(size_t, conn->read_msg.msg_iovlen, ISCSI_CONN_IOV_MAX); + for (i = 0, len = 0; i < msg.msg_iovlen; i++) { + iov[i] = conn->read_msg.msg_iov[i]; + len += iov[i].iov_len; + } + + oldfs = get_fs(); + set_fs(get_ds()); + res = sock_recvmsg(conn->sock, &msg, len, MSG_DONTWAIT | MSG_NOSIGNAL); + set_fs(oldfs); + + if (res <= 0) { + switch (res) { + case -EAGAIN: + case -ERESTARTSYS: + break; + default: + eprintk("%d\n", res); + conn_close(conn); + break; + } + } else { + conn->read_size -= res; + if (conn->read_size) + forward_iov(&conn->read_msg, res); + else + conn->read_state = state; + } + +out: + dprintk(D_IOD, "%d\n", res); + + return res; +} + +enum rx_state { + RX_INIT_BHS, /* Must be zero. */ + RX_BHS, + + RX_INIT_AHS, + RX_AHS, + + RX_INIT_HDIGEST, + RX_HDIGEST, + RX_CHECK_HDIGEST, + + RX_INIT_DATA, + RX_DATA, + + RX_INIT_DDIGEST, + RX_DDIGEST, + RX_CHECK_DDIGEST, + + RX_END, +}; + +static void rx_ddigest(struct iscsi_conn *conn, int state) +{ + struct iscsi_cmnd *cmnd = conn->read_cmnd; + int res = digest_rx_data(cmnd); + + if (!res) + conn->read_state = state; + else + conn_close(conn); +} + +static void rx_hdigest(struct iscsi_conn *conn, int state) +{ + struct iscsi_cmnd *cmnd = conn->read_cmnd; + int res = digest_rx_header(cmnd); + + if (!res) + conn->read_state = state; + else + conn_close(conn); +} + +static struct iscsi_cmnd *create_cmnd(struct iscsi_conn *conn) +{ + struct iscsi_cmnd *cmnd; + + cmnd = cmnd_alloc(conn, 1); + iscsi_conn_init_read(cmnd->conn, &cmnd->pdu.bhs, sizeof(cmnd->pdu.bhs)); + conn->read_state = RX_BHS; + + return cmnd; +} + +static int recv(struct iscsi_conn *conn) +{ + struct iscsi_cmnd *cmnd = conn->read_cmnd; + int hdigest, ddigest, res = 1; + + if (!test_bit(CONN_ACTIVE, &conn->state)) + return -EIO; + + hdigest = conn->hdigest_type & DIGEST_NONE ? 0 : 1; + ddigest = conn->ddigest_type & DIGEST_NONE ? 0 : 1; + + switch (conn->read_state) { + case RX_INIT_BHS: + assert(!cmnd); + cmnd = conn->read_cmnd = create_cmnd(conn); + case RX_BHS: + res = do_recv(conn, RX_INIT_AHS); + if (res <= 0 || conn->read_state != RX_INIT_AHS) + break; + case RX_INIT_AHS: + iscsi_cmnd_get_length(&cmnd->pdu); + if (cmnd->pdu.ahssize) { + iscsi_conn_read_ahs(conn, cmnd); + conn->read_state = RX_AHS; + } else + conn->read_state = hdigest ? RX_INIT_HDIGEST : RX_INIT_DATA; + + if (conn->read_state != RX_AHS) + break; + case RX_AHS: + res = do_recv(conn, hdigest ? RX_INIT_HDIGEST : RX_INIT_DATA); + if (res <= 0 || conn->read_state != RX_INIT_HDIGEST) + break; + case RX_INIT_HDIGEST: + iscsi_conn_init_read(conn, &cmnd->hdigest, sizeof(u32)); + conn->read_state = RX_HDIGEST; + case RX_HDIGEST: + res = do_recv(conn, RX_CHECK_HDIGEST); + if (res <= 0 || conn->read_state != RX_CHECK_HDIGEST) + break; + case RX_CHECK_HDIGEST: + rx_hdigest(conn, RX_INIT_DATA); + if (conn->read_state != RX_INIT_DATA) + break; + case RX_INIT_DATA: + cmnd_rx_start(cmnd); + conn->read_state = cmnd->pdu.datasize ? RX_DATA : RX_END; + if (conn->read_state != RX_DATA) + break; + case RX_DATA: + res = do_recv(conn, ddigest ? RX_INIT_DDIGEST : RX_END); + if (res <= 0 || conn->read_state != RX_INIT_DDIGEST) + break; + case RX_INIT_DDIGEST: + iscsi_conn_init_read(conn, &cmnd->ddigest, sizeof(u32)); + conn->read_state = RX_DDIGEST; + case RX_DDIGEST: + res = do_recv(conn, RX_CHECK_DDIGEST); + if (res <= 0 || conn->read_state != RX_CHECK_DDIGEST) + break; + case RX_CHECK_DDIGEST: + rx_ddigest(conn, RX_END); + break; + default: + eprintk("%d %d %x\n", res, conn->read_state, cmnd_opcode(cmnd)); + assert(0); + } + + if (res <= 0) + return res; + + if (conn->read_state != RX_END) + return res; + + if (conn->read_size) { + eprintk("%d %x %d\n", res, cmnd_opcode(cmnd), conn->read_size); + assert(0); + } + + cmnd_rx_end(cmnd); + if (conn->read_size) { + eprintk("%x %d\n", cmnd_opcode(cmnd), conn->read_size); + conn->read_state = RX_DATA; + return 1; + } + + conn->read_cmnd = NULL; + conn->read_state = RX_INIT_BHS; + + return 0; +} + +/* + * @locking: grabs the target's nthread_lock to protect it from races with + * iet_write_space() + */ +static void set_conn_wspace_wait(struct iscsi_conn *conn) +{ + struct network_thread_info *info = &conn->session->target->nthread_info; + struct sock *sk = conn->sock->sk; + + spin_lock_bh(&info->nthread_lock); + + if (sk_stream_wspace(sk) < sk_stream_min_wspace(sk)) + set_bit(CONN_WSPACE_WAIT, &conn->state); + + spin_unlock_bh(&info->nthread_lock); +} + +/* This is taken from the Ardis code. */ +static int write_data(struct iscsi_conn *conn) +{ + mm_segment_t oldfs; + struct file *file; + struct socket *sock; + ssize_t (*sendpage)(struct socket *, struct page *, int, size_t, int); + struct tio *tio; + struct iovec *iop; + int saved_size, size, sendsize; + int offset, idx; + int flags, res; + + file = conn->file; + saved_size = size = conn->write_size; + iop = conn->write_iop; + + if (iop) while (1) { + loff_t off = 0; + unsigned long count; + struct iovec *vec; + int rest; + + vec = iop; + for (count = 0; vec->iov_len; count++, vec++) + ; + oldfs = get_fs(); + set_fs(KERNEL_DS); + res = vfs_writev(file, (struct iovec __user *) iop, count, &off); + set_fs(oldfs); + dprintk(D_DATA, "%#Lx:%u: %d(%ld)\n", + (unsigned long long) conn->session->sid, conn->cid, + res, (long) iop->iov_len); + if (unlikely(res <= 0)) { + if (res == -EAGAIN || res == -EINTR) { + conn->write_iop = iop; + goto out_iov; + } + goto err; + } + + rest = res; + size -= res; + while (iop->iov_len <= rest && rest) { + rest -= iop->iov_len; + iop++; + } + iop->iov_base += rest; + iop->iov_len -= rest; + + if (!iop->iov_len) { + conn->write_iop = NULL; + if (size) + break; + goto out_iov; + } + } + + if (!(tio = conn->write_tcmnd)) { + eprintk("%s\n", "warning data missing!"); + return 0; + } + offset = conn->write_offset; + idx = offset >> PAGE_CACHE_SHIFT; + offset &= ~PAGE_CACHE_MASK; + + sock = conn->sock; + sendpage = sock->ops->sendpage ? : sock_no_sendpage; + flags = MSG_DONTWAIT; + + while (1) { + sendsize = PAGE_CACHE_SIZE - offset; + if (size <= sendsize) { + res = sendpage(sock, tio->pvec[idx], offset, size, flags); + dprintk(D_DATA, "%s %#Lx:%u: %d(%lu,%u,%u)\n", + sock->ops->sendpage ? "sendpage" : "writepage", + (unsigned long long ) conn->session->sid, conn->cid, + res, tio->pvec[idx]->index, offset, size); + if (unlikely(res <= 0)) { + if (res == -EAGAIN || res == -EINTR) { + goto out; + } + goto err; + } + if (res == size) { + conn->write_tcmnd = NULL; + conn->write_size = 0; + return saved_size; + } + offset += res; + size -= res; + continue; + } + + res = sendpage(sock, tio->pvec[idx], offset,sendsize, flags | MSG_MORE); + dprintk(D_DATA, "%s %#Lx:%u: %d(%lu,%u,%u)\n", + sock->ops->sendpage ? "sendpage" : "writepage", + (unsigned long long ) conn->session->sid, conn->cid, + res, tio->pvec[idx]->index, offset, sendsize); + if (unlikely(res <= 0)) { + if (res == -EAGAIN || res == -EINTR) { + goto out; + } + goto err; + } + if (res == sendsize) { + idx++; + offset = 0; + } else + offset += res; + size -= res; + } + out: + conn->write_offset = (idx << PAGE_CACHE_SHIFT) + offset; + out_iov: + conn->write_size = size; + if (res == -EAGAIN) { + set_conn_wspace_wait(conn); + if (saved_size == size) + return res; + } + + return saved_size - size; + + err: + eprintk("error %d at %#Lx:%u\n", res, + (unsigned long long) conn->session->sid, conn->cid); + return res; +} + +static void exit_tx(struct iscsi_conn *conn, int res) +{ + if (res > 0) + return; + + switch (res) { + case -EAGAIN: + case -ERESTARTSYS: + break; + default: + eprintk("%d %d %d\n", conn->write_size, conn->write_state, res); + conn_close(conn); + break; + } +} + +static int tx_ddigest(struct iscsi_cmnd *cmnd, int state) +{ + int res, rest = cmnd->conn->write_size; + struct msghdr msg = {.msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT}; + struct kvec iov; + + iov.iov_base = (char *) (&cmnd->ddigest) + (sizeof(u32) - rest); + iov.iov_len = rest; + + res = kernel_sendmsg(cmnd->conn->sock, &msg, &iov, 1, rest); + + if (res > 0) { + cmnd->conn->write_size -= res; + if (!cmnd->conn->write_size) + cmnd->conn->write_state = state; + } else + exit_tx(cmnd->conn, res); + + return res; +} + +static void init_tx_hdigest(struct iscsi_cmnd *cmnd) +{ + struct iscsi_conn *conn = cmnd->conn; + struct iovec *iop; + + if (conn->hdigest_type & DIGEST_NONE) + return; + + digest_tx_header(cmnd); + + for (iop = conn->write_iop; iop->iov_len; iop++) + ; + iop->iov_base = &(cmnd->hdigest); + iop->iov_len = sizeof(u32); + conn->write_size += sizeof(u32); + iop++; + iop->iov_len = 0; + + return; +} + +enum tx_state { + TX_INIT, /* Must be zero. */ + TX_BHS_DATA, + TX_INIT_DDIGEST, + TX_DDIGEST, + TX_END, +}; + +static int do_send(struct iscsi_conn *conn, int state) +{ + int res; + + res = write_data(conn); + + if (res > 0) { + if (!conn->write_size) + conn->write_state = state; + } else + exit_tx(conn, res); + + return res; +} + +static int send(struct iscsi_conn *conn) +{ + struct iscsi_cmnd *cmnd = conn->write_cmnd; + int ddigest, res = 0; + + ddigest = conn->ddigest_type != DIGEST_NONE ? 1 : 0; + + switch (conn->write_state) { + case TX_INIT: + assert(!cmnd); + cmnd = conn->write_cmnd = iscsi_get_send_cmnd(conn); + if (!cmnd) + return 0; + cmnd_tx_start(cmnd); + init_tx_hdigest(cmnd); + conn->write_state = TX_BHS_DATA; + case TX_BHS_DATA: + res = do_send(conn, ddigest && cmnd->pdu.datasize ? TX_INIT_DDIGEST : TX_END); + if (res <= 0 || conn->write_state != TX_INIT_DDIGEST) + break; + case TX_INIT_DDIGEST: + digest_tx_data(cmnd); + assert(!cmnd->conn->write_size); + cmnd->conn->write_size += sizeof(u32); + conn->write_state = TX_DDIGEST; + case TX_DDIGEST: + res = tx_ddigest(cmnd, TX_END); + break; + default: + eprintk("%d %d %x\n", res, conn->write_state, cmnd_opcode(cmnd)); + assert(0); + } + + if (res <= 0) + return res; + + if (conn->write_state != TX_END) + return res; + + if (conn->write_size) { + eprintk("%d %x %u\n", res, cmnd_opcode(cmnd), conn->write_size); + assert(!conn->write_size); + } + cmnd_tx_end(cmnd); + cmnd_release(cmnd, 0); + conn->write_cmnd = NULL; + conn->write_state = TX_INIT; + + return 0; +} + +static void process_io(struct iscsi_conn *conn) +{ + struct iscsi_target *target = conn->session->target; + int res, wakeup = 0; + + res = recv(conn); + + if (is_data_available(conn) > 0 || res > 0) + wakeup = 1; + + if (!test_bit(CONN_ACTIVE, &conn->state)) { + wakeup = 1; + goto out; + } + + if (test_bit(CONN_WSPACE_WAIT, &conn->state)) + goto out; + + res = send(conn); + + if (!list_empty(&conn->write_list) || conn->write_cmnd) + wakeup = 1; + +out: + if (wakeup) + nthread_wakeup(target); + + return; +} + +static void close_conn(struct iscsi_conn *conn) +{ + struct iscsi_session *session = conn->session; + struct iscsi_target *target = session->target; + struct iscsi_cmnd *cmnd; + + assert(conn); + + conn->sock->ops->shutdown(conn->sock, 2); + + write_lock_bh(&conn->sock->sk->sk_callback_lock); + conn->sock->sk->sk_state_change = target->nthread_info.old_state_change; + conn->sock->sk->sk_data_ready = target->nthread_info.old_data_ready; + conn->sock->sk->sk_write_space = target->nthread_info.old_write_space; + write_unlock_bh(&conn->sock->sk->sk_callback_lock); + + fput(conn->file); + conn->file = NULL; + conn->sock = NULL; + + while (atomic_read(&conn->nr_busy_cmnds)) + yield(); + + while (!list_empty(&conn->pdu_list)) { + cmnd = list_entry(conn->pdu_list.next, struct iscsi_cmnd, conn_list); + + list_del_init(&cmnd->list); + cmnd_release(cmnd, 1); + } + + if (atomic_read(&conn->nr_cmnds)) { + eprintk("%u\n", atomic_read(&conn->nr_cmnds)); + list_for_each_entry(cmnd, &conn->pdu_list, conn_list) + eprintk("%x %x\n", cmnd_opcode(cmnd), cmnd_itt(cmnd)); + assert(0); + } + + event_send(target->tid, session->sid, conn->cid, E_CONN_CLOSE, 0); + conn_free(conn); + + if (list_empty(&session->conn_list)) + session_del(target, session->sid); +} + +static int istd(void *arg) +{ + struct iscsi_target *target = arg; + struct network_thread_info *info = &target->nthread_info; + struct iscsi_conn *conn, *tmp; + + __set_current_state(TASK_RUNNING); + do { + spin_lock_bh(&info->nthread_lock); + __set_current_state(TASK_INTERRUPTIBLE); + + if (!test_bit(D_DATA_READY, &info->flags)) { + spin_unlock_bh(&info->nthread_lock); + schedule(); + spin_lock_bh(&info->nthread_lock); + } + __set_current_state(TASK_RUNNING); + clear_bit(D_DATA_READY, &info->flags); + spin_unlock_bh(&info->nthread_lock); + + target_lock(target, 0); + list_for_each_entry_safe(conn, tmp, &info->active_conns, poll_list) { + if (test_bit(CONN_ACTIVE, &conn->state)) + process_io(conn); + else + close_conn(conn); + } + target_unlock(target); + + } while (!kthread_should_stop()); + + return 0; +} + +int nthread_init(struct iscsi_target *target) +{ + struct network_thread_info *info = &target->nthread_info; + + info->flags = 0; + info->task = NULL; + + info->old_state_change = NULL; + info->old_data_ready = NULL; + info->old_write_space = NULL; + + INIT_LIST_HEAD(&info->active_conns); + + spin_lock_init(&info->nthread_lock); + + return 0; +} + +int nthread_start(struct iscsi_target *target) +{ + int err = 0; + struct network_thread_info *info = &target->nthread_info; + struct task_struct *task; + + if (info->task) { + eprintk("Target (%u) already runs\n", target->tid); + return -EALREADY; + } + + task = kthread_run(istd, target, "istd%d", target->tid); + + if (IS_ERR(task)) + err = PTR_ERR(task); + else + info->task = task; + + return err; +} + +int nthread_stop(struct iscsi_target *target) +{ + int err; + struct network_thread_info *info = &target->nthread_info; + + if (!info->task) + return -ESRCH; + + err = kthread_stop(info->task); + + if (!err) + info->task = NULL; + + return err; +} --- linux-2.6.28.orig/ubuntu/iscsitarget/event.c +++ linux-2.6.28/ubuntu/iscsitarget/event.c @@ -0,0 +1,97 @@ +/* + * Event notification code. + * (C) 2005 FUJITA Tomonori + * This code is licenced under the GPL. + * + * Some functions are based on audit code. + */ + +#include +#include "iet_u.h" +#include "iscsi_dbg.h" + +static struct sock *nl; +static u32 ietd_pid; + +static int event_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) +{ + u32 uid, pid, seq; + char *data; + + pid = NETLINK_CREDS(skb)->pid; + uid = NETLINK_CREDS(skb)->uid; + seq = nlh->nlmsg_seq; + data = NLMSG_DATA(nlh); + + ietd_pid = pid; + + return 0; +} + +static void event_recv_skb(struct sk_buff *skb) +{ + int err; + struct nlmsghdr *nlh; + u32 rlen; + + while (skb->len >= NLMSG_SPACE(0)) { + nlh = (struct nlmsghdr *)skb->data; + if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) + break; + rlen = NLMSG_ALIGN(nlh->nlmsg_len); + if (rlen > skb->len) + rlen = skb->len; + if ((err = event_recv_msg(skb, nlh))) { + netlink_ack(skb, nlh, -err); + } else if (nlh->nlmsg_flags & NLM_F_ACK) + netlink_ack(skb, nlh, 0); + skb_pull(skb, rlen); + } +} + +static int notify(void *data, int len, int gfp_mask) +{ + struct sk_buff *skb; + struct nlmsghdr *nlh; + static u32 seq = 0; + + if (!(skb = alloc_skb(NLMSG_SPACE(len), gfp_mask))) + return -ENOMEM; + + nlh = __nlmsg_put(skb, ietd_pid, seq++, NLMSG_DONE, len - sizeof(*nlh), 0); + + memcpy(NLMSG_DATA(nlh), data, len); + + return netlink_unicast(nl, skb, ietd_pid, 0); +} + +int event_send(u32 tid, u64 sid, u32 cid, u32 state, int atomic) +{ + int err; + struct iet_event event; + + event.tid = tid; + event.sid = sid; + event.cid = cid; + event.state = state; + + err = notify(&event, NLMSG_SPACE(sizeof(struct iet_event)), 0); + + return err; +} + +int event_init(void) +{ + nl = netlink_kernel_create(&init_net, NETLINK_IET, 1, event_recv_skb, + NULL, THIS_MODULE); + if (!nl) + return -ENOMEM; + else + return 0; +} + +void event_exit(void) +{ + if (nl) + sock_release(nl->sk_socket); +} --- linux-2.6.28.orig/ubuntu/iscsitarget/wthread.c +++ linux-2.6.28/ubuntu/iscsitarget/wthread.c @@ -0,0 +1,189 @@ +/* + * Worker thread. + * (C) 2004 - 2005 FUJITA Tomonori + * This code is licenced under the GPL. + */ + +#include + +#include "iscsi.h" +#include "iscsi_dbg.h" + +void wthread_queue(struct iscsi_cmnd *cmnd) +{ + struct worker_thread_info *info = &cmnd->conn->session->target->wthread_info; + + if (!list_empty(&cmnd->list)) { + struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd); + eprintk("%x %p %x %x %x %x %lx %x\n", + cmnd_itt(cmnd), req, req->opcode, req->scb[0], cmnd->pdu.datasize, + be32_to_cpu(req->data_length), cmnd->flags, req->flags); + + if (cmnd->lun) + eprintk("%u\n", cmnd->lun->lun); + assert(list_empty(&cmnd->list)); + } + + spin_lock(&info->wthread_lock); + list_add_tail(&cmnd->list, &info->work_queue); + spin_unlock(&info->wthread_lock); + + atomic_inc(&cmnd->conn->nr_busy_cmnds); + + wake_up(&info->wthread_sleep); +} + +static struct iscsi_cmnd * get_ready_cmnd(struct worker_thread_info *info) +{ + struct iscsi_cmnd *cmnd = NULL; + + spin_lock(&info->wthread_lock); + if (!list_empty(&info->work_queue)) { + cmnd = list_entry(info->work_queue.next, struct iscsi_cmnd, list); + list_del_init(&cmnd->list); + + assert(cmnd->conn); + } + spin_unlock(&info->wthread_lock); + + return cmnd; +} + +static int cmnd_execute(struct iscsi_cmnd *cmnd) +{ + int type = cmnd->conn->session->target->trgt_param.target_type; + + assert(target_type_array[type]->execute_cmnd); + return target_type_array[type]->execute_cmnd(cmnd); +} + +static int worker_thread(void *arg) +{ + struct worker_thread *wt = (struct worker_thread *) arg; + struct worker_thread_info *info = wt->w_info; + struct iscsi_cmnd *cmnd; + struct iscsi_conn *conn; + DECLARE_WAITQUEUE(wait, current); + + add_wait_queue(&info->wthread_sleep, &wait); + + __set_current_state(TASK_RUNNING); + do { + while (!list_empty(&info->work_queue) && + (cmnd = get_ready_cmnd(info))) { + conn = cmnd->conn; + cmnd_execute(cmnd); + assert(conn); + atomic_dec(&conn->nr_busy_cmnds); + } + + __set_current_state(TASK_INTERRUPTIBLE); + if (list_empty(&info->work_queue)) + schedule(); + + __set_current_state(TASK_RUNNING); + } while (!kthread_should_stop()); + + remove_wait_queue(&info->wthread_sleep, &wait); + + return 0; +} + +static int start_one_worker_thread(struct iscsi_target *target) +{ + struct worker_thread_info *info = &target->wthread_info; + struct worker_thread *wt; + struct task_struct *task; + + if (!(wt = kmalloc(sizeof(struct worker_thread), GFP_KERNEL))) + return -ENOMEM; + + wt->w_info = info; + task = kthread_create(worker_thread, wt, "istiod%d", target->tid); + if (IS_ERR(task)) { + kfree(wt); + return PTR_ERR(task); + } + + wt->w_task = task; + list_add(&wt->w_list, &info->wthread_list); + info->nr_running_wthreads++; + + wake_up_process(task); + + return 0; +} + +static int stop_one_worker_thread(struct worker_thread *wt) +{ + struct worker_thread_info *info = wt->w_info; + int err; + + assert(wt->w_task); + err = kthread_stop(wt->w_task); + + if (err < 0 && err != -EINTR) + return err; + + list_del(&wt->w_list); + kfree(wt); + info->nr_running_wthreads--; + + return 0; +} + +int wthread_init(struct iscsi_target *target) +{ + struct worker_thread_info *info = &target->wthread_info; + + spin_lock_init(&info->wthread_lock); + + info->nr_running_wthreads = 0; + + INIT_LIST_HEAD(&info->work_queue); + INIT_LIST_HEAD(&info->wthread_list); + + init_waitqueue_head(&info->wthread_sleep); + + return 0; +} + +int wthread_start(struct iscsi_target *target) +{ + int err = 0; + struct worker_thread_info *info = &target->wthread_info; + + while (info->nr_running_wthreads < target->trgt_param.wthreads) { + if ((err = start_one_worker_thread(target)) < 0) { + eprintk("Fail to create a worker thread %d\n", err); + goto out; + } + } + + while (info->nr_running_wthreads > target->trgt_param.wthreads) { + struct worker_thread *wt; + wt = list_entry(info->wthread_list.next, struct worker_thread, w_list); + if ((err = stop_one_worker_thread(wt)) < 0) { + eprintk("Fail to stop a worker thread %d\n", err); + break; + } + } +out: + return err; +} + +int wthread_stop(struct iscsi_target *target) +{ + struct worker_thread *wt, *tmp; + int err = 0; + struct worker_thread_info *info = &target->wthread_info; + + list_for_each_entry_safe(wt, tmp, &info->wthread_list, w_list) { + if ((err = stop_one_worker_thread(wt)) < 0) { + eprintk("Fail to stop a worker thread %d\n", err); + return err; + } + } + + return err; +} --- linux-2.6.28.orig/ubuntu/iscsitarget/Makefile +++ linux-2.6.28/ubuntu/iscsitarget/Makefile @@ -0,0 +1,17 @@ +# +# Makefile for the Linux kernel device drivers. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (not a .c file). +# +# Note 2! The CFLAGS definitions are now in the main makefile. + +EXTRA_CFLAGS += -I$(src)/include + +obj-m += iscsi_trgt.o +iscsi_trgt-objs := tio.o iscsi.o nthread.o wthread.o config.o digest.o \ + conn.o session.o target.o volume.o iotype.o \ + file-io.o null-io.o target_disk.o event.o param.o \ + block-io.o + --- linux-2.6.28.orig/ubuntu/iscsitarget/file-io.c +++ linux-2.6.28/ubuntu/iscsitarget/file-io.c @@ -0,0 +1,324 @@ +/* + * Target device file I/O. + * (C) 2004 - 2005 FUJITA Tomonori + * This code is licenced under the GPL. + */ + +#include +#include +#include +#include + +#include "iscsi.h" +#include "iscsi_dbg.h" +#include "iotype.h" + +struct fileio_data { + char *path; + struct file *filp; +}; + +static int fileio_make_request(struct iet_volume *lu, struct tio *tio, int rw) +{ + struct fileio_data *p = lu->private; + struct file *filp; + mm_segment_t oldfs; + struct page *page; + u32 offset, size; + loff_t ppos, count; + char *buf; + int i, err = 0; + ssize_t ret; + + assert(p); + filp = p->filp; + size = tio->size; + offset= tio->offset; + + ppos = (loff_t) tio->idx << PAGE_CACHE_SHIFT; + ppos += offset; + + for (i = 0; i < tio->pg_cnt; i++) { + page = tio->pvec[i]; + assert(page); + buf = page_address(page); + buf += offset; + + if (offset + size > PAGE_CACHE_SIZE) + count = PAGE_CACHE_SIZE - offset; + else + count = size; + + oldfs = get_fs(); + set_fs(get_ds()); + + if (rw == READ) + ret = do_sync_read(filp, buf, count, &ppos); + else + ret = do_sync_write(filp, buf, count, &ppos); + + set_fs(oldfs); + + if (ret != count) { + eprintk("I/O error %lld, %ld\n", count, (long) ret); + err = -EIO; + } + + size -= count; + offset = 0; + } + assert(!size); + + return err; +} + +static int fileio_sync(struct iet_volume *lu, struct tio *tio) +{ + struct fileio_data *p = lu->private; + struct inode *inode = p->filp->f_dentry->d_inode; + struct address_space *mapping = inode->i_mapping; + loff_t ppos, count; + int res; + + if (tio) { + ppos = (loff_t) tio->idx << PAGE_CACHE_SHIFT; + count = tio->size; + } else { + ppos = 0; + count = lu->blk_cnt << lu->blk_shift; + } + + res = sync_page_range(inode, mapping, ppos, count); + if (res) { + eprintk("I/O error: syncing pages failed: %d\n", res); + return -EIO; + } else + return 0; +} + +static int open_path(struct iet_volume *volume, const char *path) +{ + int err = 0; + struct fileio_data *info = volume->private; + struct file *filp; + mm_segment_t oldfs; + int flags; + + info->path = kstrdup(path, GFP_KERNEL); + if (!info->path) + return -ENOMEM; + + oldfs = get_fs(); + set_fs(get_ds()); + flags = (LUReadonly(volume) ? O_RDONLY : O_RDWR) | O_LARGEFILE; + filp = filp_open(path, flags, 0); + set_fs(oldfs); + + if (IS_ERR(filp)) { + err = PTR_ERR(filp); + eprintk("Can't open %s %d\n", path, err); + info->filp = NULL; + } else + info->filp = filp; + + return err; +} + +static int set_scsiid(struct iet_volume *volume, const char *id) +{ + size_t len; + + if ((len = strlen(id)) > SCSI_ID_LEN - VENDOR_ID_LEN) { + eprintk("SCSI ID too long, %zd provided, %u max\n", len, + SCSI_ID_LEN - VENDOR_ID_LEN); + return -EINVAL; + } + + memcpy(volume->scsi_id + VENDOR_ID_LEN, id, len); + + return 0; +} + +static void gen_scsiid(struct iet_volume *volume, struct inode *inode) +{ + int i; + u32 *p; + + strlcpy(volume->scsi_id, VENDOR_ID, VENDOR_ID_LEN); + + for (i = VENDOR_ID_LEN; i < SCSI_ID_LEN; i++) + if (volume->scsi_id[i]) + return; + + p = (u32 *) (volume->scsi_id + VENDOR_ID_LEN); + *(p + 0) = volume->target->trgt_param.target_type; + *(p + 1) = volume->target->tid; + *(p + 2) = (unsigned int) inode->i_ino; + *(p + 3) = (unsigned int) inode->i_sb->s_dev; +} + +static int set_scsisn(struct iet_volume *volume, const char *sn) +{ + size_t len; + + if ((len = strlen(sn)) > SCSI_SN_LEN) { + eprintk("SCSI SN too long, %zd provided, %u max\n", len, + SCSI_SN_LEN); + return -EINVAL; + } + memcpy(volume->scsi_sn, sn, len); + return 0; +} + +enum { + Opt_scsiid, Opt_scsisn, Opt_path, Opt_ignore, Opt_err, +}; + +static match_table_t tokens = { + {Opt_scsiid, "ScsiId=%s"}, + {Opt_scsisn, "ScsiSN=%s"}, + {Opt_path, "Path=%s"}, + {Opt_ignore, "Type=%s"}, + {Opt_ignore, "IOMode=%s"}, + {Opt_err, NULL}, +}; + +static int parse_fileio_params(struct iet_volume *volume, char *params) +{ + struct fileio_data *info = volume->private; + int err = 0; + char *p, *q; + + while ((p = strsep(¶ms, ",")) != NULL) { + substring_t args[MAX_OPT_ARGS]; + int token; + if (!*p) + continue; + token = match_token(p, tokens, args); + switch (token) { + case Opt_scsiid: + if (!(q = match_strdup(&args[0]))) { + err = -ENOMEM; + goto out; + } + err = set_scsiid(volume, q); + kfree(q); + if (err < 0) + goto out; + break; + case Opt_scsisn: + if (!(q = match_strdup(&args[0]))) { + err = -ENOMEM; + goto out; + } + err = set_scsisn(volume, q); + kfree(q); + if (err < 0) + goto out; + break; + case Opt_path: + if (info->path) { + iprintk("Target %s, LUN %u: " + "duplicate \"Path\" param\n", + volume->target->name, volume->lun); + err = -EINVAL; + goto out; + } + if (!(q = match_strdup(&args[0]))) { + err = -ENOMEM; + goto out; + } + err = open_path(volume, q); + kfree(q); + if (err < 0) + goto out; + break; + case Opt_ignore: + break; + default: + iprintk("Target %s, LUN %u: unknown param %s\n", + volume->target->name, volume->lun, p); + return -EINVAL; + } + } + + if (!info->path) { + iprintk("Target %s, LUN %u: missing \"Path\" param\n", + volume->target->name, volume->lun); + err = -EINVAL; + } +out: + return err; +} + +static void fileio_detach(struct iet_volume *lu) +{ + struct fileio_data *p = lu->private; + + kfree(p->path); + if (p->filp) + filp_close(p->filp, NULL); + kfree(p); + lu->private = NULL; +} + +static int fileio_attach(struct iet_volume *lu, char *args) +{ + int err = 0; + struct fileio_data *p; + struct inode *inode; + + if (lu->private) { + printk("already attached ? %d\n", lu->lun); + return -EBUSY; + } + + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (!p) + return -ENOMEM; + + lu->private = p; + + if ((err = parse_fileio_params(lu, args)) < 0) { + eprintk("%d\n", err); + goto out; + } + inode = p->filp->f_dentry->d_inode; + + gen_scsiid(lu, inode); + + if (S_ISREG(inode->i_mode)) + ; + else if (S_ISBLK(inode->i_mode)) + inode = inode->i_bdev->bd_inode; + else { + err = -EINVAL; + goto out; + } + + lu->blk_shift = SECTOR_SIZE_BITS; + lu->blk_cnt = inode->i_size >> lu->blk_shift; + + /* we're using the page cache */ + SetLURCache(lu); +out: + if (err < 0) + fileio_detach(lu); + return err; +} + +static void fileio_show(struct iet_volume *lu, struct seq_file *seq) +{ + struct fileio_data *p = lu->private; + seq_printf(seq, " path:%s\n", p->path); +} + +struct iotype fileio = +{ + .name = "fileio", + .attach = fileio_attach, + .make_request = fileio_make_request, + .sync = fileio_sync, + .detach = fileio_detach, + .show = fileio_show, +}; --- linux-2.6.28.orig/ubuntu/iscsitarget/block-io.c +++ linux-2.6.28/ubuntu/iscsitarget/block-io.c @@ -0,0 +1,393 @@ +/* + * Target device block I/O. + * + * Based on file I/O driver from FUJITA Tomonori + * (C) 2004 - 2005 FUJITA Tomonori + * (C) 2006 Andre Brinkmann + * (C) 2007 Ross Walker + * (C) 2007 Ming Zhang + * This code is licenced under the GPL. + */ + +#include +#include +#include +#include + +#include "iscsi.h" +#include "iscsi_dbg.h" +#include "iotype.h" + +struct blockio_data { + char *path; + struct block_device *bdev; + fmode_t fmode; +}; + +struct tio_work { + atomic_t error; + atomic_t bios_remaining; + struct completion tio_complete; +}; + +static void blockio_bio_endio(struct bio *bio, int error) +{ + struct tio_work *tio_work = bio->bi_private; + + error = test_bit(BIO_UPTODATE, &bio->bi_flags) ? error : -EIO; + + if (error) + atomic_set(&tio_work->error, error); + + /* If last bio signal completion */ + if (atomic_dec_and_test(&tio_work->bios_remaining)) + complete(&tio_work->tio_complete); + + bio_put(bio); +} + +/* + * Blockio_make_request(): The function translates an iscsi-request into + * a number of requests to the corresponding block device. + */ +static int +blockio_make_request(struct iet_volume *volume, struct tio *tio, int rw) +{ + struct blockio_data *bio_data = volume->private; + struct request_queue *bdev_q = bdev_get_queue(bio_data->bdev); + struct tio_work *tio_work; + struct bio *tio_bio = NULL, *bio = NULL, *biotail = NULL; + + u32 offset = tio->offset; + u32 size = tio->size; + u32 tio_index = 0; + + int max_pages = 1; + int err = 0; + + loff_t ppos = ((loff_t) tio->idx << PAGE_SHIFT) + offset; + + /* Calculate max_pages for bio_alloc (memory saver) */ + if (bdev_q) + max_pages = bio_get_nr_vecs(bio_data->bdev); + + tio_work = kzalloc(sizeof (*tio_work), GFP_KERNEL); + if (!tio_work) + return -ENOMEM; + + atomic_set(&tio_work->error, 0); + atomic_set(&tio_work->bios_remaining, 0); + init_completion(&tio_work->tio_complete); + + /* Main processing loop, allocate and fill all bios */ + while (tio_index < tio->pg_cnt) { + bio = bio_alloc(GFP_KERNEL, min(max_pages, BIO_MAX_PAGES)); + if (!bio) { + err = -ENOMEM; + goto out; + } + + bio->bi_sector = ppos >> volume->blk_shift; + bio->bi_bdev = bio_data->bdev; + bio->bi_end_io = blockio_bio_endio; + bio->bi_private = tio_work; + + if (tio_bio) + biotail = biotail->bi_next = bio; + else + tio_bio = biotail = bio; + + atomic_inc(&tio_work->bios_remaining); + + /* Loop for filling bio */ + while (tio_index < tio->pg_cnt) { + unsigned int bytes = PAGE_SIZE - offset; + + if (bytes > size) + bytes = size; + + if (!bio_add_page(bio, tio->pvec[tio_index], bytes, offset)) + break; + + size -= bytes; + ppos += bytes; + + offset = 0; + + tio_index++; + } + } + + /* Walk the list, submitting bios 1 by 1 */ + while (tio_bio) { + bio = tio_bio; + tio_bio = tio_bio->bi_next; + bio->bi_next = NULL; + + submit_bio(rw, bio); + } + + if (bdev_q && bdev_q->unplug_fn) + bdev_q->unplug_fn(bdev_q); + + wait_for_completion(&tio_work->tio_complete); + + err = atomic_read(&tio_work->error); + + kfree(tio_work); + + return err; +out: + while (tio_bio) { + bio = tio_bio; + tio_bio = tio_bio->bi_next; + + bio_put(bio); + } + + kfree(tio_work); + + return err; +} + +static int +blockio_open_path(struct iet_volume *volume, const char *path) +{ + struct blockio_data *bio_data = volume->private; + struct block_device *bdev; + int err = 0; + + bio_data->fmode = FMODE_READ|FMODE_WRITE; + bio_data->path = kstrdup(path, GFP_KERNEL); + if (!bio_data->path) + return -ENOMEM; + + bdev = open_bdev_exclusive(path, bio_data->fmode, THIS_MODULE); + if (IS_ERR(bdev)) { + err = PTR_ERR(bdev); + eprintk("Can't open device %s, error %d\n", path, err); + bio_data->bdev = NULL; + } else { + if (LUReadonly(volume)) + set_device_ro(bdev,1); + bio_data->bdev = bdev; + fsync_bdev(bio_data->bdev); + } + + return err; +} + +static int +set_scsiid(struct iet_volume *volume, const char *id) +{ + size_t len; + + if ((len = strlen(id)) > SCSI_ID_LEN - VENDOR_ID_LEN) { + eprintk("SCSI ID too long, %zd provided, %u max\n", len, + SCSI_ID_LEN - VENDOR_ID_LEN); + return -EINVAL; + } + + memcpy(volume->scsi_id + VENDOR_ID_LEN, id, len); + + return 0; +} + +static void +gen_scsiid(struct iet_volume *volume, struct inode *inode) +{ + int i; + u32 *p; + + strlcpy(volume->scsi_id, VENDOR_ID, VENDOR_ID_LEN); + + for (i = VENDOR_ID_LEN; i < SCSI_ID_LEN; i++) + if (volume->scsi_id[i]) + return; + + /* If a scsi id doesn't exist generate a 16 byte one: + * Bytes 1-4: target type + * Bytes 5-8: target id + * Bytes 9-12: inode number + * Bytes 13-16: device type + */ + p = (u32 *) (volume->scsi_id + VENDOR_ID_LEN); + *(p + 0) = volume->target->trgt_param.target_type; + *(p + 1) = volume->target->tid; + *(p + 2) = volume->lun; + *(p + 3) = (unsigned int) inode->i_sb->s_dev; +} + +static int +set_scsisn(struct iet_volume *volume, const char *sn) +{ + size_t len; + + if ((len = strlen(sn)) > SCSI_SN_LEN) { + eprintk("SCSI SN too long, %zd provided, %u max\n", len, + SCSI_SN_LEN); + return -EINVAL; + } + + memcpy(volume->scsi_sn, sn, len); + + return 0; +} + +/* Create an enumeration of our accepted actions */ +enum +{ + Opt_scsiid, Opt_scsisn, Opt_path, Opt_ignore, Opt_err, +}; + +/* Create a match table using our action enums and their matching options */ +static match_table_t tokens = { + {Opt_scsiid, "ScsiId=%s"}, + {Opt_scsisn, "ScsiSN=%s"}, + {Opt_path, "Path=%s"}, + {Opt_ignore, "Type=%s"}, + {Opt_ignore, "IOMode=%s"}, + {Opt_err, NULL}, +}; + +static int +parse_blockio_params(struct iet_volume *volume, char *params) +{ + struct blockio_data *info = volume->private; + int err = 0; + char *p, *q; + + /* Loop through parameters separated by commas, look up our + * parameter in match table, return enumeration and arguments + * select case based on the returned enum and run the action */ + while ((p = strsep(¶ms, ",")) != NULL) { + substring_t args[MAX_OPT_ARGS]; + int token; + if (!*p) + continue; + token = match_token(p, tokens, args); + switch (token) { + case Opt_scsiid: + if (!(q = match_strdup(&args[0]))) { + err = -ENOMEM; + goto out; + } + err = set_scsiid(volume, q); + kfree(q); + if (err < 0) + goto out; + break; + case Opt_scsisn: + if (!(q = match_strdup(&args[0]))) { + err = -ENOMEM; + goto out; + } + err = set_scsisn(volume, q); + kfree(q); + if (err < 0) + goto out; + break; + case Opt_path: + if (info->path) { + iprintk("Target %s, LUN %u: " + "duplicate \"Path\" param\n", + volume->target->name, volume->lun); + err = -EINVAL; + goto out; + } + if (!(q = match_strdup(&args[0]))) { + err = -ENOMEM; + goto out; + } + err = blockio_open_path(volume, q); + kfree(q); + if (err < 0) + goto out; + break; + case Opt_ignore: + break; + default: + iprintk("Target %s, LUN %u: unknown param %s\n", + volume->target->name, volume->lun, p); + return -EINVAL; + } + } + + if (!info->path) { + iprintk("Target %s, LUN %u: missing \"Path\" param\n", + volume->target->name, volume->lun); + err = -EINVAL; + } + out: + return err; +} + +static void +blockio_detach(struct iet_volume *volume) +{ + struct blockio_data *bio_data = volume->private; + + if (bio_data->bdev) + close_bdev_exclusive(bio_data->bdev,bio_data->fmode); + kfree(bio_data->path); + + kfree(volume->private); +} + +static int +blockio_attach(struct iet_volume *volume, char *args) +{ + struct blockio_data *bio_data; + int err = 0; + + if (volume->private) { + eprintk("Lun %u already attached on Target %s \n", + volume->lun, volume->target->name); + return -EBUSY; + } + + bio_data = kzalloc(sizeof (*bio_data), GFP_KERNEL); + if (!bio_data) + return -ENOMEM; + + volume->private = bio_data; + + if ((err = parse_blockio_params(volume, args)) < 0) { + eprintk("Error attaching Lun %u to Target %s \n", + volume->lun, volume->target->name); + goto out; + } + + /* Assign a vendor id, generate scsi id if none exists */ + gen_scsiid(volume, bio_data->bdev->bd_inode); + + /* Offer neither write nor read caching */ + ClearLURCache(volume); + ClearLUWCache(volume); + + volume->blk_shift = SECTOR_SIZE_BITS; + volume->blk_cnt = bio_data->bdev->bd_inode->i_size >> volume->blk_shift; + + out: + if (err < 0) + blockio_detach(volume); + + return err; +} + +static void +blockio_show(struct iet_volume *volume, struct seq_file *seq) +{ + struct blockio_data *bio_data = volume->private; + + /* Used to display blockio volume info in /proc/net/iet/volumes */ + seq_printf(seq, " path:%s\n", bio_data->path); +} + +struct iotype blockio = { + .name = "blockio", + .attach = blockio_attach, + .make_request = blockio_make_request, + .detach = blockio_detach, + .show = blockio_show, +}; --- linux-2.6.28.orig/ubuntu/iscsitarget/digest.c +++ linux-2.6.28/ubuntu/iscsitarget/digest.c @@ -0,0 +1,279 @@ +/* + * iSCSI digest handling. + * (C) 2004 - 2006 Xiranet Communications GmbH + * This code is licensed under the GPL. + */ + +#include + +#include "iscsi.h" +#include "digest.h" +#include "iscsi_dbg.h" + +void digest_alg_available(unsigned int *val) +{ + if (*val & DIGEST_CRC32C && + !crypto_has_alg("crc32c", 0, CRYPTO_ALG_ASYNC)) { + printk("CRC32C digest algorithm not available in kernel\n"); + *val |= ~DIGEST_CRC32C; + } +} + +/** + * initialize support for digest calculation. + * + * digest_init - + * @conn: ptr to connection to make use of digests + * + * @return: 0 on success, < 0 on error + */ +int digest_init(struct iscsi_conn *conn) +{ + int err = 0; + + if (!(conn->hdigest_type & DIGEST_ALL)) + conn->hdigest_type = DIGEST_NONE; + + if (!(conn->ddigest_type & DIGEST_ALL)) + conn->ddigest_type = DIGEST_NONE; + + if (conn->hdigest_type & DIGEST_CRC32C || + conn->ddigest_type & DIGEST_CRC32C) { + conn->rx_hash.tfm = crypto_alloc_hash("crc32c", 0, + CRYPTO_ALG_ASYNC); + conn->rx_hash.flags = 0; + if (IS_ERR(conn->rx_hash.tfm)) { + conn->rx_hash.tfm = NULL; + err = -ENOMEM; + goto out; + } + + conn->tx_hash.tfm = crypto_alloc_hash("crc32c", 0, + CRYPTO_ALG_ASYNC); + conn->tx_hash.flags = 0; + if (IS_ERR(conn->tx_hash.tfm)) { + conn->tx_hash.tfm = NULL; + err = -ENOMEM; + goto out; + } + } + +out: + if (err) + digest_cleanup(conn); + + return err; +} + +/** + * free resources used for digest calculation. + * + * digest_cleanup - + * @conn: ptr to connection that made use of digests + */ +void digest_cleanup(struct iscsi_conn *conn) +{ + if (conn->tx_hash.tfm) + crypto_free_hash(conn->tx_hash.tfm); + if (conn->rx_hash.tfm) + crypto_free_hash(conn->rx_hash.tfm); +} + +/** + * debug handling of header digest errors: + * simulates a digest error after n PDUs / every n-th PDU of type + * HDIGEST_ERR_CORRUPT_PDU_TYPE. + */ +static inline void __dbg_simulate_header_digest_error(struct iscsi_cmnd *cmnd) +{ +#define HDIGEST_ERR_AFTER_N_CMNDS 1000 +#define HDIGEST_ERR_ONLY_ONCE 1 +#define HDIGEST_ERR_CORRUPT_PDU_TYPE ISCSI_OP_SCSI_CMD +#define HDIGEST_ERR_CORRUPT_PDU_WITH_DATA_ONLY 0 + + static int num_cmnds = 0; + static int num_errs = 0; + + if (cmnd_opcode(cmnd) == HDIGEST_ERR_CORRUPT_PDU_TYPE) { + if (HDIGEST_ERR_CORRUPT_PDU_WITH_DATA_ONLY) { + if (cmnd->pdu.datasize) + num_cmnds++; + } else + num_cmnds++; + } + + if ((num_cmnds == HDIGEST_ERR_AFTER_N_CMNDS) + && (!(HDIGEST_ERR_ONLY_ONCE && num_errs))) { + printk("*** Faking header digest error ***\n"); + printk("\tcmnd: 0x%x, itt 0x%x, sn 0x%x\n", + cmnd_opcode(cmnd), + be32_to_cpu(cmnd->pdu.bhs.itt), + be32_to_cpu(cmnd->pdu.bhs.sn)); + cmnd->hdigest = ~cmnd->hdigest; + /* make things even worse by manipulating header fields */ + cmnd->pdu.datasize += 8; + num_errs++; + num_cmnds = 0; + } + return; +} + +/** + * debug handling of data digest errors: + * simulates a digest error after n PDUs / every n-th PDU of type + * DDIGEST_ERR_CORRUPT_PDU_TYPE. + */ +static inline void __dbg_simulate_data_digest_error(struct iscsi_cmnd *cmnd) +{ +#define DDIGEST_ERR_AFTER_N_CMNDS 50 +#define DDIGEST_ERR_ONLY_ONCE 1 +#define DDIGEST_ERR_CORRUPT_PDU_TYPE ISCSI_OP_SCSI_DATA_OUT +#define DDIGEST_ERR_CORRUPT_UNSOL_DATA_ONLY 0 + + static int num_cmnds = 0; + static int num_errs = 0; + + if ((cmnd->pdu.datasize) + && (cmnd_opcode(cmnd) == DDIGEST_ERR_CORRUPT_PDU_TYPE)) { + switch (cmnd_opcode(cmnd)) { + case ISCSI_OP_SCSI_DATA_OUT: + if ((DDIGEST_ERR_CORRUPT_UNSOL_DATA_ONLY) + && (cmnd->pdu.bhs.ttt != ISCSI_RESERVED_TAG)) + break; + default: + num_cmnds++; + } + } + + if ((num_cmnds == DDIGEST_ERR_AFTER_N_CMNDS) + && (!(DDIGEST_ERR_ONLY_ONCE && num_errs)) + && (cmnd->pdu.datasize) + && (!cmnd->conn->read_overflow)) { + printk("*** Faking data digest error: ***"); + printk("\tcmnd 0x%x, itt 0x%x, sn 0x%x\n", + cmnd_opcode(cmnd), + be32_to_cpu(cmnd->pdu.bhs.itt), + be32_to_cpu(cmnd->pdu.bhs.sn)); + cmnd->ddigest = ~cmnd->ddigest; + num_errs++; + num_cmnds = 0; + } +} + +static void digest_header(struct hash_desc *hash, struct iscsi_pdu *pdu, + u8 *crc) +{ + struct scatterlist sg[2]; + unsigned int nbytes = sizeof(struct iscsi_hdr); + + sg_init_table(sg, pdu->ahssize ? 2 : 1); + + sg_set_buf(&sg[0], &pdu->bhs, nbytes); + if (pdu->ahssize) { + sg_set_buf(&sg[1], pdu->ahs, pdu->ahssize); + nbytes += pdu->ahssize; + } + + crypto_hash_init(hash); + crypto_hash_update(hash, sg, nbytes); + crypto_hash_final(hash, crc); +} + +int digest_rx_header(struct iscsi_cmnd *cmnd) +{ + u32 crc; + + digest_header(&cmnd->conn->rx_hash, &cmnd->pdu, (u8 *) &crc); + if (crc != cmnd->hdigest) + return -EIO; + + return 0; +} + +void digest_tx_header(struct iscsi_cmnd *cmnd) +{ + digest_header(&cmnd->conn->tx_hash, &cmnd->pdu, (u8 *) &cmnd->hdigest); +} + +static void digest_data(struct hash_desc *hash, struct iscsi_cmnd *cmnd, + struct tio *tio, u32 offset, u8 *crc) +{ + struct scatterlist *sg = cmnd->conn->hash_sg; + u32 size, length; + int i, idx, count; + unsigned int nbytes; + + size = cmnd->pdu.datasize; + nbytes = size = (size + 3) & ~3; + + offset += tio->offset; + idx = offset >> PAGE_CACHE_SHIFT; + offset &= ~PAGE_CACHE_MASK; + count = get_pgcnt(size, offset); + assert(idx + count <= tio->pg_cnt); + + assert(count <= ISCSI_CONN_IOV_MAX); + + sg_init_table(sg, ARRAY_SIZE(cmnd->conn->hash_sg)); + crypto_hash_init(hash); + + for (i = 0; size; i++) { + if (offset + size > PAGE_CACHE_SIZE) + length = PAGE_CACHE_SIZE - offset; + else + length = size; + + sg_set_page(&sg[i], tio->pvec[idx + i], length, offset); + size -= length; + offset = 0; + } + + sg_mark_end(&sg[i - 1]); + + crypto_hash_update(hash, sg, nbytes); + crypto_hash_final(hash, crc); +} + +int digest_rx_data(struct iscsi_cmnd *cmnd) +{ + struct tio *tio; + struct iscsi_cmnd *scsi_cmnd; + struct iscsi_data_out_hdr *req; + u32 offset, crc; + + switch (cmnd_opcode(cmnd)) { + case ISCSI_OP_SCSI_REJECT: + case ISCSI_OP_PDU_REJECT: + case ISCSI_OP_DATA_REJECT: + return 0; + case ISCSI_OP_SCSI_DATA_OUT: + scsi_cmnd = cmnd->req; + req = (struct iscsi_data_out_hdr *) &cmnd->pdu.bhs; + tio = scsi_cmnd->tio; + offset = be32_to_cpu(req->buffer_offset); + break; + default: + tio = cmnd->tio; + offset = 0; + } + + digest_data(&cmnd->conn->rx_hash, cmnd, tio, offset, (u8 *) &crc); + + if (!cmnd->conn->read_overflow && + (cmnd_opcode(cmnd) != ISCSI_OP_PDU_REJECT)) { + if (crc != cmnd->ddigest) + return -EIO; + } + + return 0; +} + +void digest_tx_data(struct iscsi_cmnd *cmnd) +{ + struct tio *tio = cmnd->tio; + struct iscsi_data_out_hdr *req = (struct iscsi_data_out_hdr *)&cmnd->pdu.bhs; + + assert(tio); + digest_data(&cmnd->conn->tx_hash, cmnd, tio, + be32_to_cpu(req->buffer_offset), (u8 *) &cmnd->ddigest); +} --- linux-2.6.28.orig/ubuntu/iscsitarget/volume.c +++ linux-2.6.28/ubuntu/iscsitarget/volume.c @@ -0,0 +1,264 @@ +/* + * Volume manager + * (C) 2004 - 2005 FUJITA Tomonori + * This code is licenced under the GPL. + */ + +#include +#include + +#include "iscsi.h" +#include "iscsi_dbg.h" +#include "iotype.h" + +struct iet_volume *volume_lookup(struct iscsi_target *target, u32 lun) +{ + struct iet_volume *volume; + + list_for_each_entry(volume, &target->volumes, list) { + if (volume->lun == lun) + return volume; + } + return NULL; +} + +enum { + Opt_type, + Opt_iomode, + Opt_err, +}; + +static match_table_t tokens = { + {Opt_type, "Type=%s"}, + {Opt_iomode, "IOMode=%s"}, + {Opt_err, NULL}, +}; + +static int set_iotype(struct iet_volume *volume, char *params) +{ + int err = 0; + substring_t args[MAX_OPT_ARGS]; + char *p, *argp = NULL, *buf = (char *) get_zeroed_page(GFP_USER); + + if (!buf) + return -ENOMEM; + strncpy(buf, params, PAGE_CACHE_SIZE); + + while ((p = strsep(&buf, ",")) != NULL) { + int token; + + if (!*p) + continue; + token = match_token(p, tokens, args); + switch (token) { + case Opt_type: + if (!(argp = match_strdup(&args[0]))) + err = -ENOMEM; + if (argp && !(volume->iotype = get_iotype(argp))) + err = -ENOENT; + kfree(argp); + break; + case Opt_iomode: + if (!(argp = match_strdup(&args[0]))) + err = -ENOMEM; + if (argp && !strcmp(argp, "ro")) + SetLUReadonly(volume); + else if (argp && !strcmp(argp, "wb")) + SetLUWCache(volume); + kfree(argp); + break; + default: + break; + } + } + + if (!err && !volume->iotype && !(volume->iotype = get_iotype("fileio"))) { + eprintk("%s\n", "Cannot find fileio"); + err = -EINVAL; + } + + free_page((unsigned long) buf); + + return err; +} + +int volume_add(struct iscsi_target *target, struct volume_info *info) +{ + int ret; + struct iet_volume *volume; + char *args; + + volume = volume_lookup(target, info->lun); + if (volume) + return -EEXIST; + + if (info->lun > 0x3fff) + return -EINVAL; + + volume = kzalloc(sizeof(*volume), GFP_KERNEL); + if (!volume) + return -ENOMEM; + + volume->target = target; + volume->lun = info->lun; + + args = kzalloc(info->args_len + 1, GFP_KERNEL); + if (!args) { + ret = -ENOMEM; + goto free_volume; + } + + ret = copy_from_user(args, (void *)(unsigned long)info->args_ptr, + info->args_len); + if (ret) { + ret = -EFAULT; + goto free_args; + } + + ret = set_iotype(volume, args); + if (ret < 0) + goto free_args; + + ret = volume->iotype->attach(volume, args); + if (ret < 0) + goto free_args; + + INIT_LIST_HEAD(&volume->queue.wait_list); + spin_lock_init(&volume->queue.queue_lock); + spin_lock_init(&volume->reserve_lock); + + volume->l_state = IDEV_RUNNING; + atomic_set(&volume->l_count, 0); + + list_add_tail(&volume->list, &target->volumes); + atomic_inc(&target->nr_volumes); + + kfree(args); + + return 0; +free_args: + kfree(args); +free_volume: + put_iotype(volume->iotype); + kfree(volume); + + return ret; +} + +void iscsi_volume_destroy(struct iet_volume *volume) +{ + assert(volume->l_state == IDEV_DEL); + assert(!atomic_read(&volume->l_count)); + + volume->iotype->detach(volume); + put_iotype(volume->iotype); + list_del(&volume->list); + kfree(volume); +} + +int iscsi_volume_del(struct iscsi_target *target, struct volume_info *info) +{ + struct iet_volume *volume; + + eprintk("%x %x\n", target->tid, info->lun); + if (!(volume = volume_lookup(target, info->lun))) + return -ENOENT; + + volume->l_state = IDEV_DEL; + atomic_dec(&target->nr_volumes); + if (!atomic_read(&volume->l_count)) + iscsi_volume_destroy(volume); + + return 0; +} + +struct iet_volume *volume_get(struct iscsi_target *target, u32 lun) +{ + struct iet_volume *volume; + + if ((volume = volume_lookup(target, lun))) { + if (volume->l_state == IDEV_RUNNING) + atomic_inc(&volume->l_count); + else + volume = NULL; + } + return volume; +} + +void volume_put(struct iet_volume *volume) +{ + if (atomic_dec_and_test(&volume->l_count) && volume->l_state == IDEV_DEL) + iscsi_volume_destroy(volume); +} + +int volume_reserve(struct iet_volume *volume, u64 sid) +{ + if (!volume) + return -ENOENT; + + spin_lock(&volume->reserve_lock); + if (volume->reserve_sid && volume->reserve_sid != sid) { + spin_unlock(&volume->reserve_lock); + return -EBUSY; + } + + volume->reserve_sid = sid; + spin_unlock(&volume->reserve_lock); + + return 0; +} + +int is_volume_reserved(struct iet_volume *volume, u64 sid) +{ + if (!volume || !volume->reserve_sid || volume->reserve_sid == sid) + return 0; + + return -EBUSY; +} + +int volume_release(struct iet_volume *volume, u64 sid, int force) +{ + if (force || volume->reserve_sid == sid) + volume->reserve_sid = 0; + + return 0; +} + +static void iet_volume_info_show(struct seq_file *seq, struct iscsi_target *target) +{ + struct iet_volume *volume; + + list_for_each_entry(volume, &target->volumes, list) { + seq_printf(seq, "\tlun:%u state:%x iotype:%s", + volume->lun, volume->l_state, volume->iotype->name); + if (LUReadonly(volume)) + seq_printf(seq, " iomode:ro"); + else if (LUWCache(volume)) + seq_printf(seq, " iomode:wb"); + else + seq_printf(seq, " iomode:wt"); + + if (volume->iotype->show) + volume->iotype->show(volume, seq); + else + seq_printf(seq, "\n"); + } +} + +static int iet_volumes_info_show(struct seq_file *seq, void *v) +{ + return iet_info_show(seq, iet_volume_info_show); +} + +static int iet_volume_seq_open(struct inode *inode, struct file *file) +{ + return single_open(file, iet_volumes_info_show, NULL); +} + +struct file_operations volume_seq_fops = { + .owner = THIS_MODULE, + .open = iet_volume_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; --- linux-2.6.28.orig/ubuntu/iscsitarget/iscsi.c +++ linux-2.6.28/ubuntu/iscsitarget/iscsi.c @@ -0,0 +1,1787 @@ +/* + * Copyright (C) 2002-2003 Ardis Technolgies + * + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include +#include + +#include "iscsi.h" +#include "iscsi_dbg.h" +#include "iotype.h" + +unsigned long debug_enable_flags; + +static struct kmem_cache *iscsi_cmnd_cache; +static u8 dummy_data[PAGE_SIZE]; + +static int ctr_major; +static char ctr_name[] = "ietctl"; +extern struct file_operations ctr_fops; + +static u32 cmnd_write_size(struct iscsi_cmnd *cmnd) +{ + struct iscsi_scsi_cmd_hdr *hdr = cmnd_hdr(cmnd); + + if (hdr->flags & ISCSI_CMD_WRITE) + return be32_to_cpu(hdr->data_length); + return 0; +} + +static u32 cmnd_read_size(struct iscsi_cmnd *cmnd) +{ + struct iscsi_scsi_cmd_hdr *hdr = cmnd_hdr(cmnd); + + if (hdr->flags & ISCSI_CMD_READ) { + struct iscsi_rlength_ahdr *ahdr = + (struct iscsi_rlength_ahdr *)cmnd->pdu.ahs; + + if (!(hdr->flags & ISCSI_CMD_WRITE)) + return be32_to_cpu(hdr->data_length); + if (ahdr && ahdr->ahstype == ISCSI_AHSTYPE_RLENGTH) + return be32_to_cpu(ahdr->read_length); + } + return 0; +} + +static void iscsi_device_queue_cmnd(struct iscsi_cmnd *cmnd) +{ + set_cmnd_waitio(cmnd); + wthread_queue(cmnd); +} + +static void iscsi_scsi_queuecmnd(struct iscsi_cmnd *cmnd) +{ + struct iscsi_queue *queue = &cmnd->lun->queue; + + dprintk(D_GENERIC, "%p\n", cmnd); + + if ((cmnd->pdu.bhs.flags & ISCSI_CMD_ATTR_MASK) != ISCSI_CMD_UNTAGGED && + (cmnd->pdu.bhs.flags & ISCSI_CMD_ATTR_MASK) != ISCSI_CMD_SIMPLE) { + cmnd->pdu.bhs.flags &= ~ISCSI_CMD_ATTR_MASK; + cmnd->pdu.bhs.flags |= ISCSI_CMD_UNTAGGED; + } + + spin_lock(&queue->queue_lock); + + set_cmnd_queued(cmnd); + + switch (cmnd->pdu.bhs.flags & ISCSI_CMD_ATTR_MASK) { + case ISCSI_CMD_UNTAGGED: + case ISCSI_CMD_SIMPLE: + if (!list_empty(&queue->wait_list) || queue->ordered_cmnd) + goto pending; + queue->active_cnt++; + break; + + default: + BUG(); + } + spin_unlock(&queue->queue_lock); + + iscsi_device_queue_cmnd(cmnd); + return; + pending: + assert(list_empty(&cmnd->list)); + + list_add_tail(&cmnd->list, &queue->wait_list); + spin_unlock(&queue->queue_lock); + return; +} + +static void iscsi_scsi_dequeuecmnd(struct iscsi_cmnd *cmnd) +{ + struct iscsi_queue *queue; + + if (!cmnd->lun) + return; + queue = &cmnd->lun->queue; + spin_lock(&queue->queue_lock); + switch (cmnd->pdu.bhs.flags & ISCSI_CMD_ATTR_MASK) { + case ISCSI_CMD_UNTAGGED: + case ISCSI_CMD_SIMPLE: + --queue->active_cnt; + break; + case ISCSI_CMD_ORDERED: + case ISCSI_CMD_HEAD_OF_QUEUE: + case ISCSI_CMD_ACA: + BUG(); + default: + /* Should the iscsi_scsi_queuecmnd func reject this ? */ + break; + } + + while (!list_empty(&queue->wait_list)) { + cmnd = list_entry(queue->wait_list.next, struct iscsi_cmnd, list); + switch ((cmnd->pdu.bhs.flags & ISCSI_CMD_ATTR_MASK)) { + case ISCSI_CMD_UNTAGGED: + case ISCSI_CMD_SIMPLE: + list_del_init(&cmnd->list); + queue->active_cnt++; + iscsi_device_queue_cmnd(cmnd); + break; + case ISCSI_CMD_ORDERED: + case ISCSI_CMD_HEAD_OF_QUEUE: + case ISCSI_CMD_ACA: + BUG(); + } + } + + spin_unlock(&queue->queue_lock); + + return; +} + +/** + * create a new command. + * + * iscsi_cmnd_create - + * @conn: ptr to connection (for i/o) + * + * @return ptr to command or NULL + */ + +struct iscsi_cmnd *cmnd_alloc(struct iscsi_conn *conn, int req) +{ + struct iscsi_cmnd *cmnd; + + /* TODO: async interface is necessary ? */ + cmnd = kmem_cache_alloc(iscsi_cmnd_cache, GFP_KERNEL|__GFP_NOFAIL); + + memset(cmnd, 0, sizeof(*cmnd)); + INIT_LIST_HEAD(&cmnd->list); + INIT_LIST_HEAD(&cmnd->pdu_list); + INIT_LIST_HEAD(&cmnd->conn_list); + INIT_LIST_HEAD(&cmnd->hash_list); + cmnd->conn = conn; + spin_lock(&conn->list_lock); + atomic_inc(&conn->nr_cmnds); + if (req) + list_add_tail(&cmnd->conn_list, &conn->pdu_list); + spin_unlock(&conn->list_lock); + cmnd->tio = NULL; + + dprintk(D_GENERIC, "%p:%p\n", conn, cmnd); + + return cmnd; +} + +/** + * create a new command used as response. + * + * iscsi_cmnd_create_rsp_cmnd - + * @cmnd: ptr to request command + * + * @return ptr to response command or NULL + */ + +static struct iscsi_cmnd *iscsi_cmnd_create_rsp_cmnd(struct iscsi_cmnd *cmnd, int final) +{ + struct iscsi_cmnd *rsp = cmnd_alloc(cmnd->conn, 0); + + if (final) + set_cmnd_final(rsp); + list_add_tail(&rsp->pdu_list, &cmnd->pdu_list); + rsp->req = cmnd; + return rsp; +} + +static struct iscsi_cmnd *get_rsp_cmnd(struct iscsi_cmnd *req) +{ + return list_entry(req->pdu_list.prev, struct iscsi_cmnd, pdu_list); +} + +static void iscsi_cmnds_init_write(struct list_head *send) +{ + struct iscsi_cmnd *cmnd = list_entry(send->next, struct iscsi_cmnd, list); + struct iscsi_conn *conn = cmnd->conn; + struct list_head *pos, *next; + + spin_lock(&conn->list_lock); + + list_for_each_safe(pos, next, send) { + cmnd = list_entry(pos, struct iscsi_cmnd, list); + + dprintk(D_GENERIC, "%p:%x\n", cmnd, cmnd_opcode(cmnd)); + + list_del_init(&cmnd->list); + assert(conn == cmnd->conn); + list_add_tail(&cmnd->list, &conn->write_list); + } + + spin_unlock(&conn->list_lock); + + nthread_wakeup(conn->session->target); +} + +static void iscsi_cmnd_init_write(struct iscsi_cmnd *cmnd) +{ + LIST_HEAD(head); + + if (!list_empty(&cmnd->list)) { + eprintk("%x %x %x %x %lx %u %u %u %u %u %u %u %d %d\n", + cmnd_itt(cmnd), cmnd_ttt(cmnd), cmnd_opcode(cmnd), + cmnd_scsicode(cmnd), cmnd->flags, cmnd->r2t_sn, + cmnd->r2t_length, cmnd->is_unsolicited_data, + cmnd->target_task_tag, cmnd->outstanding_r2t, + cmnd->hdigest, cmnd->ddigest, + list_empty(&cmnd->pdu_list), list_empty(&cmnd->hash_list)); + + assert(list_empty(&cmnd->list)); + } + list_add(&cmnd->list, &head); + iscsi_cmnds_init_write(&head); +} + +static void do_send_data_rsp(struct iscsi_cmnd *cmnd) +{ + struct iscsi_conn *conn = cmnd->conn; + struct iscsi_cmnd *data_cmnd; + struct tio *tio = cmnd->tio; + struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd); + struct iscsi_data_in_hdr *rsp; + u32 pdusize, expsize, scsisize, size, offset, sn; + LIST_HEAD(send); + + dprintk(D_GENERIC, "%p\n", cmnd); + pdusize = conn->session->param.max_xmit_data_length; + expsize = cmnd_read_size(cmnd); + size = min(expsize, tio->size); + offset = 0; + sn = 0; + + while (1) { + data_cmnd = iscsi_cmnd_create_rsp_cmnd(cmnd, size <= pdusize); + tio_get(tio); + data_cmnd->tio = tio; + rsp = (struct iscsi_data_in_hdr *)&data_cmnd->pdu.bhs; + + rsp->opcode = ISCSI_OP_SCSI_DATA_IN; + rsp->itt = req->itt; + rsp->ttt = cpu_to_be32(ISCSI_RESERVED_TAG); + rsp->buffer_offset = offset; + rsp->data_sn = cpu_to_be32(sn); + + if (size <= pdusize) { + data_cmnd->pdu.datasize = size; + rsp->flags = ISCSI_FLG_FINAL | ISCSI_FLG_STATUS; + + scsisize = tio->size; + if (scsisize < expsize) { + rsp->flags |= ISCSI_FLG_RESIDUAL_UNDERFLOW; + size = expsize - scsisize; + } else if (scsisize > expsize) { + rsp->flags |= ISCSI_FLG_RESIDUAL_OVERFLOW; + size = scsisize - expsize; + } else + size = 0; + rsp->residual_count = cpu_to_be32(size); + list_add_tail(&data_cmnd->list, &send); + + break; + } + + data_cmnd->pdu.datasize = pdusize; + + size -= pdusize; + offset += pdusize; + sn++; + + list_add_tail(&data_cmnd->list, &send); + } + + iscsi_cmnds_init_write(&send); +} + +static struct iscsi_cmnd *create_scsi_rsp(struct iscsi_cmnd *req) +{ + struct iscsi_cmnd *rsp; + struct iscsi_scsi_cmd_hdr *req_hdr = cmnd_hdr(req); + struct iscsi_scsi_rsp_hdr *rsp_hdr; + + rsp = iscsi_cmnd_create_rsp_cmnd(req, 1); + + rsp_hdr = (struct iscsi_scsi_rsp_hdr *)&rsp->pdu.bhs; + rsp_hdr->opcode = ISCSI_OP_SCSI_RSP; + rsp_hdr->flags = ISCSI_FLG_FINAL; + rsp_hdr->response = ISCSI_RESPONSE_COMMAND_COMPLETED; + rsp_hdr->cmd_status = SAM_STAT_GOOD; + rsp_hdr->itt = req_hdr->itt; + + return rsp; +} + +static struct iscsi_cmnd *create_sense_rsp(struct iscsi_cmnd *req, + u8 sense_key, u8 asc, u8 ascq) +{ + struct iscsi_cmnd *rsp; + struct iscsi_scsi_rsp_hdr *rsp_hdr; + struct tio *tio; + struct iscsi_sense_data *sense; + + rsp = iscsi_cmnd_create_rsp_cmnd(req, 1); + + rsp_hdr = (struct iscsi_scsi_rsp_hdr *)&rsp->pdu.bhs; + rsp_hdr->opcode = ISCSI_OP_SCSI_RSP; + rsp_hdr->flags = ISCSI_FLG_FINAL; + rsp_hdr->response = ISCSI_RESPONSE_COMMAND_COMPLETED; + rsp_hdr->cmd_status = SAM_STAT_CHECK_CONDITION; + rsp_hdr->itt = cmnd_hdr(req)->itt; + + tio = rsp->tio = tio_alloc(1); + sense = (struct iscsi_sense_data *) page_address(tio->pvec[0]); + assert(sense); + clear_page(sense); + sense->length = cpu_to_be16(14); + sense->data[0] = 0xf0; + sense->data[2] = sense_key; + sense->data[7] = 6; // Additional sense length + sense->data[12] = asc; + sense->data[13] = ascq; + + rsp->pdu.datasize = sizeof(struct iscsi_sense_data) + 14; + tio->size = (rsp->pdu.datasize + 3) & -4; + tio->offset = 0; + + return rsp; +} + +void send_scsi_rsp(struct iscsi_cmnd *req, int (*func)(struct iscsi_cmnd *)) +{ + struct iscsi_cmnd *rsp; + struct iscsi_scsi_rsp_hdr *rsp_hdr; + u32 size; + int ret = func(req); + + switch (ret) { + case 0: + case -EBUSY: + rsp = create_scsi_rsp(req); + rsp_hdr = (struct iscsi_scsi_rsp_hdr *) &rsp->pdu.bhs; + if ((size = cmnd_read_size(req)) != 0) { + rsp_hdr->flags |= ISCSI_FLG_RESIDUAL_UNDERFLOW; + rsp_hdr->residual_count = cpu_to_be32(size); + } + if (ret == -EBUSY) + rsp_hdr->cmd_status = SAM_STAT_RESERVATION_CONFLICT; + break; + case -EIO: + /* Medium Error/Write Fault */ + rsp = create_sense_rsp(req, MEDIUM_ERROR, 0x03, 0x0); + break; + default: + rsp = create_sense_rsp(req, ILLEGAL_REQUEST, 0x24, 0x0); + } + iscsi_cmnd_init_write(rsp); +} + +void send_data_rsp(struct iscsi_cmnd *req, int (*func)(struct iscsi_cmnd *)) +{ + struct iscsi_cmnd *rsp; + + switch (func(req)) { + case 0: + do_send_data_rsp(req); + return; + case -EIO: + /* Medium Error/Unrecovered Read Error */ + rsp = create_sense_rsp(req, MEDIUM_ERROR, 0x11, 0x0); + break; + default: + rsp = create_sense_rsp(req, ILLEGAL_REQUEST, 0x24, 0x0); + } + iscsi_cmnd_init_write(rsp); +} + +/** + * Free a command. + * Also frees the additional header. + * + * iscsi_cmnd_remove - + * @cmnd: ptr to command + */ + +static void iscsi_cmnd_remove(struct iscsi_cmnd *cmnd) +{ + struct iscsi_conn *conn; + + if (!cmnd) + return; + dprintk(D_GENERIC, "%p\n", cmnd); + conn = cmnd->conn; + kfree(cmnd->pdu.ahs); + + if (!list_empty(&cmnd->list)) { + struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd); + + eprintk("cmnd %p still on some list?, %x, %x, %x, %x, %x, %x, %x %lx\n", + cmnd, req->opcode, req->scb[0], req->flags, req->itt, + be32_to_cpu(req->data_length), + req->cmd_sn, be32_to_cpu(cmnd->pdu.datasize), + conn->state); + + if (cmnd->req) { + struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd->req); + eprintk("%p %x %u\n", req, req->opcode, req->scb[0]); + } + dump_stack(); + BUG(); + } + list_del(&cmnd->list); + spin_lock(&conn->list_lock); + atomic_dec(&conn->nr_cmnds); + list_del(&cmnd->conn_list); + spin_unlock(&conn->list_lock); + + if (cmnd->tio) + tio_put(cmnd->tio); + + kmem_cache_free(iscsi_cmnd_cache, cmnd); +} + +static void cmnd_skip_pdu(struct iscsi_cmnd *cmnd) +{ + struct iscsi_conn *conn = cmnd->conn; + struct tio *tio = cmnd->tio; + char *addr; + u32 size; + int i; + + eprintk("%x %x %x %u\n", cmnd_itt(cmnd), cmnd_opcode(cmnd), + cmnd_hdr(cmnd)->scb[0], cmnd->pdu.datasize); + + if (!(size = cmnd->pdu.datasize)) + return; + + if (tio) + assert(tio->pg_cnt > 0); + else + tio = cmnd->tio = tio_alloc(1); + + addr = page_address(tio->pvec[0]); + assert(addr); + size = (size + 3) & -4; + conn->read_size = size; + for (i = 0; size > PAGE_CACHE_SIZE; i++, size -= PAGE_CACHE_SIZE) { + assert(i < ISCSI_CONN_IOV_MAX); + conn->read_iov[i].iov_base = addr; + conn->read_iov[i].iov_len = PAGE_CACHE_SIZE; + } + conn->read_iov[i].iov_base = addr; + conn->read_iov[i].iov_len = size; + conn->read_msg.msg_iov = conn->read_iov; + conn->read_msg.msg_iovlen = ++i; +} + +static void iscsi_cmnd_reject(struct iscsi_cmnd *req, int reason) +{ + struct iscsi_cmnd *rsp; + struct iscsi_reject_hdr *rsp_hdr; + struct tio *tio; + char *addr; + + rsp = iscsi_cmnd_create_rsp_cmnd(req, 1); + rsp_hdr = (struct iscsi_reject_hdr *)&rsp->pdu.bhs; + + rsp_hdr->opcode = ISCSI_OP_REJECT; + rsp_hdr->ffffffff = ISCSI_RESERVED_TAG; + rsp_hdr->reason = reason; + + rsp->tio = tio = tio_alloc(1); + addr = page_address(tio->pvec[0]); + clear_page(addr); + memcpy(addr, &req->pdu.bhs, sizeof(struct iscsi_hdr)); + tio->size = rsp->pdu.datasize = sizeof(struct iscsi_hdr); + cmnd_skip_pdu(req); + + req->pdu.bhs.opcode = ISCSI_OP_PDU_REJECT; +} + +static void cmnd_set_sn(struct iscsi_cmnd *cmnd, int set_stat_sn) +{ + struct iscsi_conn *conn = cmnd->conn; + struct iscsi_session *sess = conn->session; + + if (set_stat_sn) + cmnd->pdu.bhs.sn = cpu_to_be32(conn->stat_sn++); + cmnd->pdu.bhs.exp_sn = cpu_to_be32(sess->exp_cmd_sn); + cmnd->pdu.bhs.max_sn = cpu_to_be32(sess->exp_cmd_sn + sess->max_queued_cmnds); +} + +static void update_stat_sn(struct iscsi_cmnd *cmnd) +{ + struct iscsi_conn *conn = cmnd->conn; + u32 exp_stat_sn; + + cmnd->pdu.bhs.exp_sn = exp_stat_sn = be32_to_cpu(cmnd->pdu.bhs.exp_sn); + dprintk(D_GENERIC, "%x,%x\n", cmnd_opcode(cmnd), exp_stat_sn); + if ((int)(exp_stat_sn - conn->exp_stat_sn) > 0 && + (int)(exp_stat_sn - conn->stat_sn) <= 0) { + // free pdu resources + cmnd->conn->exp_stat_sn = exp_stat_sn; + } +} + +static int check_cmd_sn(struct iscsi_cmnd *cmnd) +{ + struct iscsi_session *session = cmnd->conn->session; + u32 cmd_sn; + + cmnd->pdu.bhs.sn = cmd_sn = be32_to_cpu(cmnd->pdu.bhs.sn); + dprintk(D_GENERIC, "%d(%d)\n", cmd_sn, session->exp_cmd_sn); + if ((s32)(cmd_sn - session->exp_cmd_sn) >= 0) + return 0; + eprintk("sequence error (%x,%x)\n", cmd_sn, session->exp_cmd_sn); + return -ISCSI_REASON_PROTOCOL_ERROR; +} + +static struct iscsi_cmnd *__cmnd_find_hash(struct iscsi_session *session, u32 itt, u32 ttt) +{ + struct list_head *head; + struct iscsi_cmnd *cmnd; + + head = &session->cmnd_hash[cmnd_hashfn(itt)]; + + list_for_each_entry(cmnd, head, hash_list) { + if (cmnd->pdu.bhs.itt == itt) { + if ((ttt != ISCSI_RESERVED_TAG) && (ttt != cmnd->target_task_tag)) + continue; + return cmnd; + } + } + + return NULL; +} + +static struct iscsi_cmnd *cmnd_find_hash(struct iscsi_session *session, u32 itt, u32 ttt) +{ + struct iscsi_cmnd *cmnd; + + spin_lock(&session->cmnd_hash_lock); + + cmnd = __cmnd_find_hash(session, itt, ttt); + + spin_unlock(&session->cmnd_hash_lock); + + return cmnd; +} + +static int cmnd_insert_hash(struct iscsi_cmnd *cmnd) +{ + struct iscsi_session *session = cmnd->conn->session; + struct iscsi_cmnd *tmp; + struct list_head *head; + int err = 0; + u32 itt = cmnd->pdu.bhs.itt; + + dprintk(D_GENERIC, "%p:%x\n", cmnd, itt); + if (itt == ISCSI_RESERVED_TAG) { + err = -ISCSI_REASON_PROTOCOL_ERROR; + goto out; + } + + head = &session->cmnd_hash[cmnd_hashfn(cmnd->pdu.bhs.itt)]; + + spin_lock(&session->cmnd_hash_lock); + + tmp = __cmnd_find_hash(session, itt, ISCSI_RESERVED_TAG); + if (!tmp) { + list_add_tail(&cmnd->hash_list, head); + set_cmnd_hashed(cmnd); + } else + err = -ISCSI_REASON_TASK_IN_PROGRESS; + + spin_unlock(&session->cmnd_hash_lock); + + if (!err) { + update_stat_sn(cmnd); + err = check_cmd_sn(cmnd); + } + +out: + return err; +} + +static void __cmnd_remove_hash(struct iscsi_cmnd *cmnd) +{ + list_del(&cmnd->hash_list); +} + +static void cmnd_remove_hash(struct iscsi_cmnd *cmnd) +{ + struct iscsi_session *session = cmnd->conn->session; + struct iscsi_cmnd *tmp; + + spin_lock(&session->cmnd_hash_lock); + + tmp = __cmnd_find_hash(session, cmnd->pdu.bhs.itt, ISCSI_RESERVED_TAG); + + if (tmp && tmp == cmnd) + __cmnd_remove_hash(tmp); + else + eprintk("%p:%x not found\n", cmnd, cmnd_itt(cmnd)); + + spin_unlock(&session->cmnd_hash_lock); +} + +static void cmnd_skip_data(struct iscsi_cmnd *req) +{ + struct iscsi_cmnd *rsp; + struct iscsi_scsi_rsp_hdr *rsp_hdr; + u32 size; + + rsp = get_rsp_cmnd(req); + rsp_hdr = (struct iscsi_scsi_rsp_hdr *)&rsp->pdu.bhs; + if (cmnd_opcode(rsp) != ISCSI_OP_SCSI_RSP) { + eprintk("unexpected response command %u\n", cmnd_opcode(rsp)); + return; + } + + size = cmnd_write_size(req); + if (size) { + rsp_hdr->flags |= ISCSI_FLG_RESIDUAL_UNDERFLOW; + rsp_hdr->residual_count = cpu_to_be32(size); + } + size = cmnd_read_size(req); + if (size) { + if (cmnd_hdr(req)->flags & ISCSI_CMD_WRITE) { + rsp_hdr->flags |= ISCSI_FLG_BIRESIDUAL_UNDERFLOW; + rsp_hdr->bi_residual_count = cpu_to_be32(size); + } else { + rsp_hdr->flags |= ISCSI_FLG_RESIDUAL_UNDERFLOW; + rsp_hdr->residual_count = cpu_to_be32(size); + } + } + req->pdu.bhs.opcode = + (req->pdu.bhs.opcode & ~ISCSI_OPCODE_MASK) | ISCSI_OP_SCSI_REJECT; + + cmnd_skip_pdu(req); +} + +static int cmnd_recv_pdu(struct iscsi_conn *conn, struct tio *tio, u32 offset, u32 size) +{ + int idx, i; + char *addr; + + dprintk(D_GENERIC, "%p %u,%u\n", tio, offset, size); + offset += tio->offset; + + if (!(offset < tio->offset + tio->size) || + !(offset + size <= tio->offset + tio->size)) { + eprintk("%u %u %u %u", offset, size, tio->offset, tio->size); + return -EIO; + } + assert(offset < tio->offset + tio->size); + assert(offset + size <= tio->offset + tio->size); + + idx = offset >> PAGE_CACHE_SHIFT; + offset &= ~PAGE_CACHE_MASK; + + conn->read_msg.msg_iov = conn->read_iov; + conn->read_size = size = (size + 3) & -4; + conn->read_overflow = 0; + + i = 0; + while (1) { + assert(tio->pvec[idx]); + addr = page_address(tio->pvec[idx]); + assert(addr); + conn->read_iov[i].iov_base = addr + offset; + if (offset + size <= PAGE_CACHE_SIZE) { + conn->read_iov[i].iov_len = size; + conn->read_msg.msg_iovlen = ++i; + break; + } + conn->read_iov[i].iov_len = PAGE_CACHE_SIZE - offset; + size -= conn->read_iov[i].iov_len; + offset = 0; + if (++i >= ISCSI_CONN_IOV_MAX) { + conn->read_msg.msg_iovlen = i; + conn->read_overflow = size; + conn->read_size -= size; + break; + } + + idx++; + } + + return 0; +} + +static void set_offset_and_length(struct iet_volume *lu, u8 *cmd, loff_t *off, u32 *len) +{ + assert(lu); + + switch (cmd[0]) { + case READ_6: + case WRITE_6: + *off = ((cmd[1] & 0x1f) << 16) + (cmd[2] << 8) + cmd[3]; + *len = cmd[4]; + if (!*len) + *len = 256; + break; + case READ_10: + case WRITE_10: + case WRITE_VERIFY: + *off = (u32)cmd[2] << 24 | (u32)cmd[3] << 16 | + (u32)cmd[4] << 8 | (u32)cmd[5]; + *len = (cmd[7] << 8) + cmd[8]; + break; + case READ_16: + case WRITE_16: + *off = (u64)cmd[2] << 56 | (u64)cmd[3] << 48 | + (u64)cmd[4] << 40 | (u64)cmd[5] << 32 | + (u64)cmd[6] << 24 | (u64)cmd[7] << 16 | + (u64)cmd[8] << 8 | (u64)cmd[9]; + *len = (u32)cmd[10] << 24 | (u32)cmd[11] << 16 | + (u32)cmd[12] << 8 | (u32)cmd[13]; + break; + default: + BUG(); + } + + *off <<= lu->blk_shift; + *len <<= lu->blk_shift; +} + +static u32 translate_lun(u16 * data) +{ + u8 *p = (u8 *) data; + u32 lun = ~0U; + + switch (*p >> 6) { + case 0: + lun = p[1]; + break; + case 1: + lun = (0x3f & p[0]) << 8 | p[1]; + break; + case 2: + case 3: + default: + eprintk("%u %u %u %u\n", data[0], data[1], data[2], data[3]); + break; + } + + return lun; +} + +static void send_r2t(struct iscsi_cmnd *req) +{ + struct iscsi_cmnd *rsp; + struct iscsi_r2t_hdr *rsp_hdr; + u32 length, offset, burst; + LIST_HEAD(send); + + length = req->r2t_length; + burst = req->conn->session->param.max_burst_length; + offset = be32_to_cpu(cmnd_hdr(req)->data_length) - length; + + do { + rsp = iscsi_cmnd_create_rsp_cmnd(req, 0); + rsp->pdu.bhs.ttt = req->target_task_tag; + + rsp_hdr = (struct iscsi_r2t_hdr *)&rsp->pdu.bhs; + rsp_hdr->opcode = ISCSI_OP_R2T; + rsp_hdr->flags = ISCSI_FLG_FINAL; + memcpy(rsp_hdr->lun, cmnd_hdr(req)->lun, 8); + rsp_hdr->itt = cmnd_hdr(req)->itt; + rsp_hdr->r2t_sn = cpu_to_be32(req->r2t_sn++); + rsp_hdr->buffer_offset = cpu_to_be32(offset); + if (length > burst) { + rsp_hdr->data_length = cpu_to_be32(burst); + length -= burst; + offset += burst; + } else { + rsp_hdr->data_length = cpu_to_be32(length); + length = 0; + } + + dprintk(D_WRITE, "%x %u %u %u %u\n", cmnd_itt(req), + be32_to_cpu(rsp_hdr->data_length), + be32_to_cpu(rsp_hdr->buffer_offset), + be32_to_cpu(rsp_hdr->r2t_sn), req->outstanding_r2t); + + list_add_tail(&rsp->list, &send); + + if (++req->outstanding_r2t >= req->conn->session->param.max_outstanding_r2t) + break; + + } while (length); + + iscsi_cmnds_init_write(&send); +} + +static void scsi_cmnd_exec(struct iscsi_cmnd *cmnd) +{ + if (cmnd->r2t_length) { + if (!cmnd->is_unsolicited_data) + send_r2t(cmnd); + } else { + if (cmnd->lun) { + iscsi_scsi_queuecmnd(cmnd); + } else { + iscsi_device_queue_cmnd(cmnd); + } + } +} + +static int noop_out_start(struct iscsi_conn *conn, struct iscsi_cmnd *cmnd) +{ + u32 size, tmp; + int i, err = 0; + + if (cmnd_ttt(cmnd) != cpu_to_be32(ISCSI_RESERVED_TAG)) { + /* + * We don't request a NOP-Out by sending a NOP-In. + * See 10.18.2 in the draft 20. + */ + eprintk("initiator bug %x\n", cmnd_itt(cmnd)); + err = -ISCSI_REASON_PROTOCOL_ERROR; + goto out; + } + + if (cmnd_itt(cmnd) == cpu_to_be32(ISCSI_RESERVED_TAG)) { + if (!(cmnd->pdu.bhs.opcode & ISCSI_OP_IMMEDIATE)) + eprintk("%s\n","initiator bug!"); + update_stat_sn(cmnd); + err = check_cmd_sn(cmnd); + if (err) + goto out; + } else if ((err = cmnd_insert_hash(cmnd)) < 0) { + eprintk("ignore this request %x\n", cmnd_itt(cmnd)); + goto out; + } + + if ((size = cmnd->pdu.datasize)) { + size = (size + 3) & -4; + conn->read_msg.msg_iov = conn->read_iov; + if (cmnd->pdu.bhs.itt != cpu_to_be32(ISCSI_RESERVED_TAG)) { + struct tio *tio; + int pg_cnt = get_pgcnt(size, 0); + + assert(pg_cnt < ISCSI_CONN_IOV_MAX); + cmnd->tio = tio = tio_alloc(pg_cnt); + tio_set(tio, size, 0); + + for (i = 0; i < pg_cnt; i++) { + conn->read_iov[i].iov_base + = page_address(tio->pvec[i]); + tmp = min_t(u32, size, PAGE_CACHE_SIZE); + conn->read_iov[i].iov_len = tmp; + conn->read_size += tmp; + size -= tmp; + } + } else { + for (i = 0; i < ISCSI_CONN_IOV_MAX; i++) { + conn->read_iov[i].iov_base = dummy_data; + tmp = min_t(u32, size, sizeof(dummy_data)); + conn->read_iov[i].iov_len = tmp; + conn->read_size += tmp; + size -= tmp; + } + } + assert(!size); + conn->read_overflow = size; + conn->read_msg.msg_iovlen = i; + } + +out: + return err; +} + +static u32 get_next_ttt(struct iscsi_session *session) +{ + u32 ttt; + + if (session->next_ttt == ISCSI_RESERVED_TAG) + session->next_ttt++; + ttt = session->next_ttt++; + + return cpu_to_be32(ttt); +} + +static void scsi_cmnd_start(struct iscsi_conn *conn, struct iscsi_cmnd *req) +{ + struct iscsi_scsi_cmd_hdr *req_hdr = cmnd_hdr(req); + + dprintk(D_GENERIC, "scsi command: %02x\n", req_hdr->scb[0]); + + req->lun = volume_get(conn->session->target, translate_lun(req_hdr->lun)); + if (!req->lun) { + switch (req_hdr->scb[0]) { + case INQUIRY: + case REPORT_LUNS: + break; + default: + eprintk("%x %x\n", cmnd_itt(req), req_hdr->scb[0]); + create_sense_rsp(req, ILLEGAL_REQUEST, 0x25, 0x0); + cmnd_skip_data(req); + goto out; + } + } else + set_cmnd_lunit(req); + + switch (req_hdr->scb[0]) { + case SERVICE_ACTION_IN: + if ((req_hdr->scb[1] & 0x1f) != 0x10) + goto error; + case INQUIRY: + case REPORT_LUNS: + case TEST_UNIT_READY: + case SYNCHRONIZE_CACHE: + case VERIFY: + case VERIFY_16: + case START_STOP: + case READ_CAPACITY: + case MODE_SENSE: + case REQUEST_SENSE: + case RESERVE: + case RELEASE: + { + if (!(req_hdr->flags & ISCSI_CMD_FINAL) || req->pdu.datasize) { + /* unexpected unsolicited data */ + eprintk("%x %x\n", cmnd_itt(req), req_hdr->scb[0]); + create_sense_rsp(req, ABORTED_COMMAND, 0xc, 0xc); + cmnd_skip_data(req); + } + break; + } + case READ_6: + case READ_10: + case READ_16: + { + loff_t offset; + u32 length; + + if (!(req_hdr->flags & ISCSI_CMD_FINAL) || req->pdu.datasize) { + /* unexpected unsolicited data */ + eprintk("%x %x\n", cmnd_itt(req), req_hdr->scb[0]); + create_sense_rsp(req, ABORTED_COMMAND, 0xc, 0xc); + cmnd_skip_data(req); + break; + } + + set_offset_and_length(req->lun, req_hdr->scb, &offset, &length); + req->tio = tio_alloc(get_pgcnt(length, offset)); + tio_set(req->tio, length, offset); + break; + } + case WRITE_6: + case WRITE_10: + case WRITE_16: + case WRITE_VERIFY: + { + struct iscsi_sess_param *param = &conn->session->param; + loff_t offset; + u32 length; + + req->r2t_length = be32_to_cpu(req_hdr->data_length) - req->pdu.datasize; + req->is_unsolicited_data = !(req_hdr->flags & ISCSI_CMD_FINAL); + req->target_task_tag = get_next_ttt(conn->session); + + if (LUReadonly(req->lun)) { + create_sense_rsp(req, DATA_PROTECT, 0x27, 0x0); + cmnd_skip_data(req); + break; + } + + if (!param->immediate_data && req->pdu.datasize) + eprintk("%x %x\n", cmnd_itt(req), req_hdr->scb[0]); + + if (param->initial_r2t && !(req_hdr->flags & ISCSI_CMD_FINAL)) + eprintk("%x %x\n", cmnd_itt(req), req_hdr->scb[0]); + + if (req_hdr->scb[0] == WRITE_VERIFY && req_hdr->scb[1] & 0x02) + eprintk("Verification is ignored %x\n", cmnd_itt(req)); + + set_offset_and_length(req->lun, req_hdr->scb, &offset, &length); + if (cmnd_write_size(req) != length) + eprintk("%x %u %u\n", cmnd_itt(req), cmnd_write_size(req), length); + + req->tio = tio_alloc(get_pgcnt(length, offset)); + tio_set(req->tio, length, offset); + + if (req->pdu.datasize) { + if (cmnd_recv_pdu(conn, req->tio, 0, req->pdu.datasize) < 0) + assert(0); + } + break; + } + error: + default: + eprintk("Unsupported %x\n", req_hdr->scb[0]); + create_sense_rsp(req, ILLEGAL_REQUEST, 0x20, 0x0); + cmnd_skip_data(req); + break; + } + +out: + return; +} + +static void data_out_start(struct iscsi_conn *conn, struct iscsi_cmnd *cmnd) +{ + struct iscsi_data_out_hdr *req = (struct iscsi_data_out_hdr *)&cmnd->pdu.bhs; + struct iscsi_cmnd *scsi_cmnd = NULL; + u32 offset = be32_to_cpu(req->buffer_offset); + + update_stat_sn(cmnd); + + cmnd->req = scsi_cmnd = cmnd_find_hash(conn->session, req->itt, req->ttt); + if (!scsi_cmnd) { + eprintk("unable to find scsi task %x %x\n", + cmnd_itt(cmnd), cmnd_ttt(cmnd)); + goto skip_data; + } + + if (scsi_cmnd->r2t_length < cmnd->pdu.datasize) { + eprintk("invalid data len %x %u %u\n", + cmnd_itt(scsi_cmnd), cmnd->pdu.datasize, scsi_cmnd->r2t_length); + goto skip_data; + } + + if (scsi_cmnd->r2t_length + offset != cmnd_write_size(scsi_cmnd)) { + eprintk("%x %u %u %u\n", cmnd_itt(scsi_cmnd), scsi_cmnd->r2t_length, + offset, cmnd_write_size(scsi_cmnd)); + goto skip_data; + } + + scsi_cmnd->r2t_length -= cmnd->pdu.datasize; + + if (req->ttt == cpu_to_be32(ISCSI_RESERVED_TAG)) { + /* unsolicited burst data */ + if (scsi_cmnd->pdu.bhs.flags & ISCSI_FLG_FINAL) { + eprintk("unexpected data from %x %x\n", + cmnd_itt(cmnd), cmnd_ttt(cmnd)); + goto skip_data; + } + } + + dprintk(D_WRITE, "%u %p %p %p %u %u\n", req->ttt, cmnd, scsi_cmnd, + scsi_cmnd->tio, offset, cmnd->pdu.datasize); + + if (cmnd_recv_pdu(conn, scsi_cmnd->tio, offset, cmnd->pdu.datasize) < 0) + goto skip_data; + return; + +skip_data: + cmnd->pdu.bhs.opcode = ISCSI_OP_DATA_REJECT; + cmnd_skip_pdu(cmnd); + return; +} + +static void data_out_end(struct iscsi_conn *conn, struct iscsi_cmnd *cmnd) +{ + struct iscsi_data_out_hdr *req = (struct iscsi_data_out_hdr *) &cmnd->pdu.bhs; + struct iscsi_cmnd *scsi_cmnd; + u32 offset; + + assert(cmnd); + scsi_cmnd = cmnd->req; + assert(scsi_cmnd); + + if (conn->read_overflow) { + eprintk("%x %u\n", cmnd_itt(cmnd), conn->read_overflow); + assert(scsi_cmnd->tio); + offset = be32_to_cpu(req->buffer_offset); + offset += cmnd->pdu.datasize - conn->read_overflow; + if (cmnd_recv_pdu(conn, scsi_cmnd->tio, offset, conn->read_overflow) < 0) + assert(0); + return; + } + + if (req->ttt == cpu_to_be32(ISCSI_RESERVED_TAG)) { + if (req->flags & ISCSI_FLG_FINAL) { + scsi_cmnd->is_unsolicited_data = 0; + if (!cmnd_pending(scsi_cmnd)) + scsi_cmnd_exec(scsi_cmnd); + } + } else { + /* TODO : proper error handling */ + if (!(req->flags & ISCSI_FLG_FINAL) && scsi_cmnd->r2t_length == 0) + eprintk("initiator error %x\n", cmnd_itt(scsi_cmnd)); + + if (!(req->flags & ISCSI_FLG_FINAL)) + goto out; + + scsi_cmnd->outstanding_r2t--; + + if (scsi_cmnd->r2t_length == 0) + assert(list_empty(&scsi_cmnd->pdu_list)); + + scsi_cmnd_exec(scsi_cmnd); + } + +out: + iscsi_cmnd_remove(cmnd); + return; +} + +static int __cmnd_abort(struct iscsi_cmnd *cmnd) +{ + if (cmnd_waitio(cmnd)) + return -ISCSI_RESPONSE_UNKNOWN_TASK; + + if (cmnd->conn->read_cmnd != cmnd) + cmnd_release(cmnd, 1); + else if (cmnd_rxstart(cmnd)) + set_cmnd_tmfabort(cmnd); + else + return -ISCSI_RESPONSE_UNKNOWN_TASK; + + return 0; +} + +static int cmnd_abort(struct iscsi_session *session, u32 itt) +{ + struct iscsi_cmnd *cmnd; + int err = -ISCSI_RESPONSE_UNKNOWN_TASK; + + if ((cmnd = cmnd_find_hash(session, itt, ISCSI_RESERVED_TAG))) { + eprintk("%x %x %x %u %u %u %u\n", cmnd_itt(cmnd), cmnd_opcode(cmnd), + cmnd->r2t_length, cmnd_scsicode(cmnd), + cmnd_write_size(cmnd), cmnd->is_unsolicited_data, + cmnd->outstanding_r2t); + err = __cmnd_abort(cmnd); + } + + return err; +} + +static int target_reset(struct iscsi_cmnd *req, u32 lun, int all) +{ + struct iscsi_target *target = req->conn->session->target; + struct iscsi_session *session; + struct iscsi_conn *conn; + struct iscsi_cmnd *cmnd, *tmp; + struct iet_volume *volumes; + + list_for_each_entry(session, &target->session_list, list) { + list_for_each_entry(conn, &session->conn_list, list) { + list_for_each_entry_safe(cmnd, tmp, &conn->pdu_list, conn_list) { + if (cmnd == req) + continue; + + if (all) + __cmnd_abort(cmnd); + else if (translate_lun(cmnd_hdr(cmnd)->lun) == lun) + __cmnd_abort(cmnd); + } + } + } + + list_for_each_entry(volumes, &target->volumes, list) + if (all || volumes->lun == lun) + /* force release */ + volume_release(volumes, 0, 1); + + return 0; +} + +static void task_set_abort(struct iscsi_cmnd *req) +{ + struct iscsi_session *session = req->conn->session; + struct iscsi_conn *conn; + struct iscsi_cmnd *cmnd, *tmp; + + list_for_each_entry(conn, &session->conn_list, list) { + list_for_each_entry_safe(cmnd, tmp, &conn->pdu_list, conn_list) { + if (cmnd != req) + __cmnd_abort(cmnd); + } + } +} + +static inline char *tmf_desc(int fun) +{ + static char *tmf_desc[] = { + "Unknown Function", + "Abort Task", + "Abort Task Set", + "Clear ACA", + "Clear Task Set", + "Logical Unit Reset", + "Target Warm Reset", + "Target Cold Reset", + "Task Reassign", + }; + + if ((fun < ISCSI_FUNCTION_ABORT_TASK) || + (fun > ISCSI_FUNCTION_TASK_REASSIGN)) + fun = 0; + + return tmf_desc[fun]; +} + +static inline char *rsp_desc(int rsp) +{ + static char *rsp_desc[] = { + "Function Complete", + "Unknown Task", + "Unknown LUN", + "Task Allegiant", + "Failover Unsupported", + "Function Unsupported", + "No Authorization", + "Function Rejected", + "Unknown Response", + }; + + if (((rsp < ISCSI_RESPONSE_FUNCTION_COMPLETE) || + (rsp > ISCSI_RESPONSE_NO_AUTHORIZATION)) && + (rsp != ISCSI_RESPONSE_FUNCTION_REJECTED)) + rsp = 8; + else if (rsp == ISCSI_RESPONSE_FUNCTION_REJECTED) + rsp = 7; + + return rsp_desc[rsp]; +} + +static void execute_task_management(struct iscsi_cmnd *req) +{ + struct iscsi_conn *conn = req->conn; + struct iscsi_session *session = conn->session; + struct iscsi_target *target = session->target; + struct iscsi_cmnd *rsp; + struct iscsi_task_mgt_hdr *req_hdr = (struct iscsi_task_mgt_hdr *)&req->pdu.bhs; + struct iscsi_task_rsp_hdr *rsp_hdr; + u32 lun; + int err, function = req_hdr->function & ISCSI_FUNCTION_MASK; + + rsp = iscsi_cmnd_create_rsp_cmnd(req, 1); + rsp_hdr = (struct iscsi_task_rsp_hdr *)&rsp->pdu.bhs; + + rsp_hdr->opcode = ISCSI_OP_SCSI_TASK_MGT_RSP; + rsp_hdr->flags = ISCSI_FLG_FINAL; + rsp_hdr->itt = req_hdr->itt; + rsp_hdr->response = ISCSI_RESPONSE_FUNCTION_COMPLETE; + + switch (function) { + case ISCSI_FUNCTION_ABORT_TASK: + case ISCSI_FUNCTION_ABORT_TASK_SET: + case ISCSI_FUNCTION_CLEAR_ACA: + case ISCSI_FUNCTION_CLEAR_TASK_SET: + case ISCSI_FUNCTION_LOGICAL_UNIT_RESET: + lun = translate_lun(req_hdr->lun); + if (!volume_lookup(target, lun)) { + rsp_hdr->response = ISCSI_RESPONSE_UNKNOWN_LUN; + goto out; + } + } + + switch (function) { + case ISCSI_FUNCTION_ABORT_TASK: + if ((err = cmnd_abort(conn->session, req_hdr->rtt)) < 0) + rsp_hdr->response = -err; + break; + case ISCSI_FUNCTION_ABORT_TASK_SET: + task_set_abort(req); + break; + case ISCSI_FUNCTION_CLEAR_ACA: + rsp_hdr->response = ISCSI_RESPONSE_FUNCTION_UNSUPPORTED; + break; + case ISCSI_FUNCTION_CLEAR_TASK_SET: + rsp_hdr->response = ISCSI_RESPONSE_FUNCTION_UNSUPPORTED; + break; + case ISCSI_FUNCTION_LOGICAL_UNIT_RESET: + target_reset(req, translate_lun(req_hdr->lun), 0); + break; + case ISCSI_FUNCTION_TARGET_WARM_RESET: + case ISCSI_FUNCTION_TARGET_COLD_RESET: + target_reset(req, 0, 1); + if (function == ISCSI_FUNCTION_TARGET_COLD_RESET) + set_cmnd_close(rsp); + break; + case ISCSI_FUNCTION_TASK_REASSIGN: + rsp_hdr->response = ISCSI_RESPONSE_FUNCTION_UNSUPPORTED; + break; + default: + rsp_hdr->response = ISCSI_RESPONSE_FUNCTION_REJECTED; + break; + } +out: + iprintk("%s (%02x) issued on tid:%d lun:%d by sid:%llu (%s)\n", + tmf_desc(function), function, target->tid, + translate_lun(req_hdr->lun), session->sid, + rsp_desc(rsp_hdr->response)); + + iscsi_cmnd_init_write(rsp); +} + +static void noop_out_exec(struct iscsi_cmnd *req) +{ + struct iscsi_cmnd *rsp; + struct iscsi_nop_in_hdr *rsp_hdr; + + if (cmnd_itt(req) != cpu_to_be32(ISCSI_RESERVED_TAG)) { + rsp = iscsi_cmnd_create_rsp_cmnd(req, 1); + + rsp_hdr = (struct iscsi_nop_in_hdr *)&rsp->pdu.bhs; + rsp_hdr->opcode = ISCSI_OP_NOOP_IN; + rsp_hdr->flags = ISCSI_FLG_FINAL; + rsp_hdr->itt = req->pdu.bhs.itt; + rsp_hdr->ttt = cpu_to_be32(ISCSI_RESERVED_TAG); + + if (req->pdu.datasize) + assert(req->tio); + else + assert(!req->tio); + + if (req->tio) { + tio_get(req->tio); + rsp->tio = req->tio; + } + + assert(get_pgcnt(req->pdu.datasize, 0) < ISCSI_CONN_IOV_MAX); + rsp->pdu.datasize = req->pdu.datasize; + iscsi_cmnd_init_write(rsp); + } else + iscsi_cmnd_remove(req); +} + +static void logout_exec(struct iscsi_cmnd *req) +{ + struct iscsi_logout_req_hdr *req_hdr; + struct iscsi_cmnd *rsp; + struct iscsi_logout_rsp_hdr *rsp_hdr; + + req_hdr = (struct iscsi_logout_req_hdr *)&req->pdu.bhs; + rsp = iscsi_cmnd_create_rsp_cmnd(req, 1); + rsp_hdr = (struct iscsi_logout_rsp_hdr *)&rsp->pdu.bhs; + rsp_hdr->opcode = ISCSI_OP_LOGOUT_RSP; + rsp_hdr->flags = ISCSI_FLG_FINAL; + rsp_hdr->itt = req_hdr->itt; + set_cmnd_close(rsp); + iscsi_cmnd_init_write(rsp); +} + +static void iscsi_cmnd_exec(struct iscsi_cmnd *cmnd) +{ + dprintk(D_GENERIC, "%p,%x,%u\n", cmnd, cmnd_opcode(cmnd), cmnd->pdu.bhs.sn); + + switch (cmnd_opcode(cmnd)) { + case ISCSI_OP_NOOP_OUT: + noop_out_exec(cmnd); + break; + case ISCSI_OP_SCSI_CMD: + scsi_cmnd_exec(cmnd); + break; + case ISCSI_OP_SCSI_TASK_MGT_MSG: + execute_task_management(cmnd); + break; + case ISCSI_OP_LOGOUT_CMD: + logout_exec(cmnd); + break; + case ISCSI_OP_SCSI_REJECT: + iscsi_cmnd_init_write(get_rsp_cmnd(cmnd)); + break; + case ISCSI_OP_TEXT_CMD: + case ISCSI_OP_SNACK_CMD: + break; + default: + eprintk("unexpected cmnd op %x\n", cmnd_opcode(cmnd)); + break; + } +} + +static void __cmnd_send_pdu(struct iscsi_conn *conn, struct tio *tio, u32 offset, u32 size) +{ + dprintk(D_GENERIC, "%p %u,%u\n", tio, offset, size); + offset += tio->offset; + + assert(offset <= tio->offset + tio->size); + assert(offset + size <= tio->offset + tio->size); + + conn->write_tcmnd = tio; + conn->write_offset = offset; + conn->write_size += size; +} + +static void cmnd_send_pdu(struct iscsi_conn *conn, struct iscsi_cmnd *cmnd) +{ + u32 size; + struct tio *tio; + + if (!cmnd->pdu.datasize) + return; + + size = (cmnd->pdu.datasize + 3) & -4; + tio = cmnd->tio; + assert(tio); + assert(tio->size == size); + __cmnd_send_pdu(conn, tio, 0, size); +} + +static void set_cork(struct socket *sock, int on) +{ + int opt = on; + mm_segment_t oldfs; + + oldfs = get_fs(); + set_fs(get_ds()); + sock->ops->setsockopt(sock, SOL_TCP, TCP_CORK, (void *)&opt, sizeof(opt)); + set_fs(oldfs); +} + +void cmnd_release(struct iscsi_cmnd *cmnd, int force) +{ + struct iscsi_cmnd *req, *rsp; + int is_last = 0; + + if (!cmnd) + return; + +/* eprintk("%x %lx %d\n", cmnd_opcode(cmnd), cmnd->flags, force); */ + + req = cmnd->req; + is_last = cmnd_final(cmnd); + + if (force) { + while (!list_empty(&cmnd->pdu_list)) { + rsp = list_entry(cmnd->pdu_list.next, struct iscsi_cmnd, pdu_list); + list_del_init(&rsp->list); + list_del(&rsp->pdu_list); + iscsi_cmnd_remove(rsp); + } + list_del_init(&cmnd->list); + } else + if (cmnd_queued(cmnd)) + iscsi_scsi_dequeuecmnd(cmnd); + + if (cmnd_hashed(cmnd)) + cmnd_remove_hash(cmnd); + + if (cmnd_lunit(cmnd)) { + assert(cmnd->lun); + volume_put(cmnd->lun); + } + + list_del_init(&cmnd->pdu_list); + iscsi_cmnd_remove(cmnd); + + if (is_last) { + assert(!force); + assert(req); + cmnd_release(req, 0); + } + + return; +} + +void cmnd_tx_start(struct iscsi_cmnd *cmnd) +{ + struct iscsi_conn *conn = cmnd->conn; + struct iovec *iop; + + dprintk(D_GENERIC, "%p:%x\n", cmnd, cmnd_opcode(cmnd)); + assert(cmnd); + iscsi_cmnd_set_length(&cmnd->pdu); + + set_cork(conn->sock, 1); + + conn->write_iop = iop = conn->write_iov; + iop->iov_base = &cmnd->pdu.bhs; + iop->iov_len = sizeof(cmnd->pdu.bhs); + iop++; + conn->write_size = sizeof(cmnd->pdu.bhs); + + switch (cmnd_opcode(cmnd)) { + case ISCSI_OP_NOOP_IN: + cmnd_set_sn(cmnd, 1); + cmnd_send_pdu(conn, cmnd); + break; + case ISCSI_OP_SCSI_RSP: + cmnd_set_sn(cmnd, 1); + cmnd_send_pdu(conn, cmnd); + break; + case ISCSI_OP_SCSI_TASK_MGT_RSP: + cmnd_set_sn(cmnd, 1); + break; + case ISCSI_OP_TEXT_RSP: + cmnd_set_sn(cmnd, 1); + break; + case ISCSI_OP_SCSI_DATA_IN: + { + struct iscsi_data_in_hdr *rsp = (struct iscsi_data_in_hdr *)&cmnd->pdu.bhs; + u32 offset; + + cmnd_set_sn(cmnd, (rsp->flags & ISCSI_FLG_FINAL) ? 1 : 0); + offset = rsp->buffer_offset; + rsp->buffer_offset = cpu_to_be32(offset); + __cmnd_send_pdu(conn, cmnd->tio, offset, cmnd->pdu.datasize); + break; + } + case ISCSI_OP_LOGOUT_RSP: + cmnd_set_sn(cmnd, 1); + break; + case ISCSI_OP_R2T: + cmnd_set_sn(cmnd, 0); + cmnd->pdu.bhs.sn = cpu_to_be32(conn->stat_sn); + break; + case ISCSI_OP_ASYNC_MSG: + cmnd_set_sn(cmnd, 1); + break; + case ISCSI_OP_REJECT: + cmnd_set_sn(cmnd, 1); + cmnd_send_pdu(conn, cmnd); + break; + default: + eprintk("unexpected cmnd op %x\n", cmnd_opcode(cmnd)); + break; + } + + iop->iov_len = 0; + // move this? + conn->write_size = (conn->write_size + 3) & -4; + iscsi_dump_pdu(&cmnd->pdu); +} + +void cmnd_tx_end(struct iscsi_cmnd *cmnd) +{ + struct iscsi_conn *conn = cmnd->conn; + + dprintk(D_GENERIC, "%p:%x\n", cmnd, cmnd_opcode(cmnd)); + switch (cmnd_opcode(cmnd)) { + case ISCSI_OP_NOOP_IN: + case ISCSI_OP_SCSI_RSP: + case ISCSI_OP_SCSI_TASK_MGT_RSP: + case ISCSI_OP_TEXT_RSP: + case ISCSI_OP_R2T: + case ISCSI_OP_ASYNC_MSG: + case ISCSI_OP_REJECT: + case ISCSI_OP_SCSI_DATA_IN: + case ISCSI_OP_LOGOUT_RSP: + break; + default: + eprintk("unexpected cmnd op %x\n", cmnd_opcode(cmnd)); + assert(0); + break; + } + + if (cmnd_close(cmnd)) + conn_close(conn); + + list_del_init(&cmnd->list); + set_cork(cmnd->conn->sock, 0); +} + +/** + * Push the command for execution. + * This functions reorders the commands. + * Called from the read thread. + * + * iscsi_session_push_cmnd - + * @cmnd: ptr to command + */ + +static void iscsi_session_push_cmnd(struct iscsi_cmnd *cmnd) +{ + struct iscsi_session *session = cmnd->conn->session; + struct list_head *entry; + u32 cmd_sn; + + dprintk(D_GENERIC, "%p:%x %u,%u\n", + cmnd, cmnd_opcode(cmnd), cmnd->pdu.bhs.sn, session->exp_cmd_sn); + + if (cmnd->pdu.bhs.opcode & ISCSI_OP_IMMEDIATE) { + iscsi_cmnd_exec(cmnd); + return; + } + + cmd_sn = cmnd->pdu.bhs.sn; + if (cmd_sn == session->exp_cmd_sn) { + while (1) { + session->exp_cmd_sn = ++cmd_sn; + iscsi_cmnd_exec(cmnd); + + if (list_empty(&session->pending_list)) + break; + cmnd = list_entry(session->pending_list.next, struct iscsi_cmnd, list); + if (cmnd->pdu.bhs.sn != cmd_sn) + break; +/* eprintk("find out-of-order %x %u %u\n", */ +/* cmnd_itt(cmnd), cmd_sn, cmnd->pdu.bhs.sn); */ + list_del_init(&cmnd->list); + clear_cmnd_pending(cmnd); + } + } else { +/* eprintk("out-of-order %x %u %u\n", */ +/* cmnd_itt(cmnd), cmd_sn, session->exp_cmd_sn); */ + + set_cmnd_pending(cmnd); + if (before(cmd_sn, session->exp_cmd_sn)) /* close the conn */ + eprintk("unexpected cmd_sn (%u,%u)\n", cmd_sn, session->exp_cmd_sn); + + if (after(cmd_sn, session->exp_cmd_sn + session->max_queued_cmnds)) + eprintk("too large cmd_sn (%u,%u)\n", cmd_sn, session->exp_cmd_sn); + + list_for_each(entry, &session->pending_list) { + struct iscsi_cmnd *tmp = list_entry(entry, struct iscsi_cmnd, list); + if (before(cmd_sn, tmp->pdu.bhs.sn)) + break; + } + + assert(list_empty(&cmnd->list)); + + list_add_tail(&cmnd->list, entry); + } +} + +static int check_segment_length(struct iscsi_cmnd *cmnd) +{ + struct iscsi_conn *conn = cmnd->conn; + struct iscsi_sess_param *param = &conn->session->param; + + if (cmnd->pdu.datasize > param->max_recv_data_length) { + eprintk("data too long %x %u %u\n", cmnd_itt(cmnd), + cmnd->pdu.datasize, param->max_recv_data_length); + + if (get_pgcnt(cmnd->pdu.datasize, 0) > ISCSI_CONN_IOV_MAX) { + conn_close(conn); + return -EINVAL; + } + } + + return 0; +} + +void cmnd_rx_start(struct iscsi_cmnd *cmnd) +{ + struct iscsi_conn *conn = cmnd->conn; + int err = 0; + + iscsi_dump_pdu(&cmnd->pdu); + + set_cmnd_rxstart(cmnd); + if (check_segment_length(cmnd) < 0) + return; + + switch (cmnd_opcode(cmnd)) { + case ISCSI_OP_NOOP_OUT: + err = noop_out_start(conn, cmnd); + break; + case ISCSI_OP_SCSI_CMD: + if (!(err = cmnd_insert_hash(cmnd))) + scsi_cmnd_start(conn, cmnd); + break; + case ISCSI_OP_SCSI_TASK_MGT_MSG: + err = cmnd_insert_hash(cmnd); + break; + case ISCSI_OP_SCSI_DATA_OUT: + data_out_start(conn, cmnd); + break; + case ISCSI_OP_LOGOUT_CMD: + err = cmnd_insert_hash(cmnd); + break; + case ISCSI_OP_TEXT_CMD: + case ISCSI_OP_SNACK_CMD: + err = -ISCSI_REASON_UNSUPPORTED_COMMAND; + break; + default: + err = -ISCSI_REASON_UNSUPPORTED_COMMAND; + break; + } + + if (err < 0) { + eprintk("%x %x %d\n", cmnd_opcode(cmnd), cmnd_itt(cmnd), err); + iscsi_cmnd_reject(cmnd, -err); + } +} + +void cmnd_rx_end(struct iscsi_cmnd *cmnd) +{ + struct iscsi_conn *conn = cmnd->conn; + + if (cmnd_tmfabort(cmnd)) { + cmnd_release(cmnd, 1); + return; + } + + dprintk(D_GENERIC, "%p:%x\n", cmnd, cmnd_opcode(cmnd)); + switch (cmnd_opcode(cmnd)) { + case ISCSI_OP_SCSI_REJECT: + case ISCSI_OP_NOOP_OUT: + case ISCSI_OP_SCSI_CMD: + case ISCSI_OP_SCSI_TASK_MGT_MSG: + case ISCSI_OP_TEXT_CMD: + case ISCSI_OP_LOGOUT_CMD: + iscsi_session_push_cmnd(cmnd); + break; + case ISCSI_OP_SCSI_DATA_OUT: + data_out_end(conn, cmnd); + break; + case ISCSI_OP_SNACK_CMD: + break; + case ISCSI_OP_PDU_REJECT: + iscsi_cmnd_init_write(get_rsp_cmnd(cmnd)); + break; + case ISCSI_OP_DATA_REJECT: + cmnd_release(cmnd, 0); + break; + default: + eprintk("unexpected cmnd op %x\n", cmnd_opcode(cmnd)); + BUG(); + break; + } +} + +static void iscsi_exit(void) +{ + unregister_chrdev(ctr_major, ctr_name); + + iet_procfs_exit(); + + event_exit(); + + tio_exit(); + + iotype_exit(); + + if (iscsi_cmnd_cache) + kmem_cache_destroy(iscsi_cmnd_cache); +} + +static int iscsi_init(void) +{ + int err = -ENOMEM; + + printk("iSCSI Enterprise Target Software - version %s\n", IET_VERSION_STRING); + + if ((ctr_major = register_chrdev(0, ctr_name, &ctr_fops)) < 0) { + eprintk("failed to register the control device %d\n", ctr_major); + return ctr_major; + } + + if ((err = iet_procfs_init()) < 0) + goto err; + + if ((err = event_init()) < 0) + goto err; + + iscsi_cmnd_cache = KMEM_CACHE(iscsi_cmnd, 0); + if (!iscsi_cmnd_cache) + goto err; + + if ((err = tio_init()) < 0) + goto err; + + if ((err = iotype_init()) < 0) + goto err; + + return 0; + +err: + iscsi_exit(); + return err; +} + +module_param(debug_enable_flags, ulong, S_IRUGO); + +module_init(iscsi_init); +module_exit(iscsi_exit); + +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/ubuntu/iscsitarget/tio.c +++ linux-2.6.28/ubuntu/iscsitarget/tio.c @@ -0,0 +1,121 @@ +/* + * Target I/O. + * (C) 2005 FUJITA Tomonori + * This code is licenced under the GPL. + */ + +#include "iscsi.h" +#include "iscsi_dbg.h" +#include "iotype.h" + +static int tio_add_pages(struct tio *tio, int count) +{ + int i; + struct page *page; + + dprintk(D_GENERIC, "%p %d (%d)\n", tio, count, tio->pg_cnt); + + tio->pg_cnt = count; + + count *= sizeof(struct page *); + + do { + tio->pvec = kzalloc(count, GFP_KERNEL); + if (!tio->pvec) + yield(); + } while (!tio->pvec); + + for (i = 0; i < tio->pg_cnt; i++) { + do { + if (!(page = alloc_page(GFP_KERNEL))) + yield(); + } while (!page); + tio->pvec[i] = page; + } + return 0; +} + +static struct kmem_cache *tio_cache; + +struct tio *tio_alloc(int count) +{ + struct tio *tio; + + tio = kmem_cache_alloc(tio_cache, GFP_KERNEL | __GFP_NOFAIL); + + tio->pg_cnt = 0; + tio->idx = 0; + tio->offset = 0; + tio->size = 0; + tio->pvec = NULL; + + atomic_set(&tio->count, 1); + + if (count) + tio_add_pages(tio, count); + + return tio; +} + +static void tio_free(struct tio *tio) +{ + int i; + for (i = 0; i < tio->pg_cnt; i++) { + assert(tio->pvec[i]); + __free_page(tio->pvec[i]); + } + kfree(tio->pvec); + kmem_cache_free(tio_cache, tio); +} + +void tio_put(struct tio *tio) +{ + assert(atomic_read(&tio->count)); + if (atomic_dec_and_test(&tio->count)) + tio_free(tio); +} + +void tio_get(struct tio *tio) +{ + atomic_inc(&tio->count); +} + +void tio_set(struct tio *tio, u32 size, loff_t offset) +{ + tio->idx = offset >> PAGE_CACHE_SHIFT; + tio->offset = offset & ~PAGE_CACHE_MASK; + tio->size = size; +} + +int tio_read(struct iet_volume *lu, struct tio *tio) +{ + struct iotype *iot = lu->iotype; + assert(iot); + return iot->make_request ? iot->make_request(lu, tio, READ) : 0; +} + +int tio_write(struct iet_volume *lu, struct tio *tio) +{ + struct iotype *iot = lu->iotype; + assert(iot); + return iot->make_request ? iot->make_request(lu, tio, WRITE) : 0; +} + +int tio_sync(struct iet_volume *lu, struct tio *tio) +{ + struct iotype *iot = lu->iotype; + assert(iot); + return iot->sync ? iot->sync(lu, tio) : 0; +} + +int tio_init(void) +{ + tio_cache = KMEM_CACHE(tio, 0); + return tio_cache ? 0 : -ENOMEM; +} + +void tio_exit(void) +{ + if (tio_cache) + kmem_cache_destroy(tio_cache); +} --- linux-2.6.28.orig/ubuntu/iscsitarget/session.c +++ linux-2.6.28/ubuntu/iscsitarget/session.c @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2002-2003 Ardis Technolgies + * + * Released under the terms of the GNU GPL v2.0. + */ + +#include "iscsi.h" +#include "iscsi_dbg.h" + +struct iscsi_session *session_lookup(struct iscsi_target *target, u64 sid) +{ + struct iscsi_session *session; + + list_for_each_entry(session, &target->session_list, list) { + if (session->sid == sid) + return session; + } + return NULL; +} + +static struct iscsi_session * +iet_session_alloc(struct iscsi_target *target, struct session_info *info) +{ + int i; + struct iscsi_session *session; + + dprintk(D_SETUP, "%p %u %#Lx\n", target, target->tid, + (unsigned long long) info->sid); + + session = kzalloc(sizeof(*session), GFP_KERNEL); + if (!session) + return NULL; + + session->target = target; + session->sid = info->sid; + memcpy(&session->param, &target->sess_param, sizeof(session->param)); + session->max_queued_cmnds = target->trgt_param.queued_cmnds; + + session->exp_cmd_sn = info->exp_cmd_sn; + session->max_cmd_sn = info->max_cmd_sn; + + session->initiator = kstrdup(info->initiator_name, GFP_KERNEL); + if (!session->initiator) { + kfree(session); + return NULL; + } + + INIT_LIST_HEAD(&session->conn_list); + INIT_LIST_HEAD(&session->pending_list); + + spin_lock_init(&session->cmnd_hash_lock); + for (i = 0; i < ARRAY_SIZE(session->cmnd_hash); i++) + INIT_LIST_HEAD(&session->cmnd_hash[i]); + + session->next_ttt = 1; + + list_add(&session->list, &target->session_list); + + return session; +} + +static int session_free(struct iscsi_session *session) +{ + int i; + + dprintk(D_SETUP, "%#Lx\n", (unsigned long long) session->sid); + + assert(list_empty(&session->conn_list)); + + for (i = 0; i < ARRAY_SIZE(session->cmnd_hash); i++) { + if (!list_empty(&session->cmnd_hash[i])) + BUG(); + } + + list_del(&session->list); + + kfree(session->initiator); + kfree(session); + + return 0; +} + +int session_add(struct iscsi_target *target, struct session_info *info) +{ + struct iscsi_session *session; + int err = -EEXIST; + + session = session_lookup(target, info->sid); + if (session) + return err; + + session = iet_session_alloc(target, info); + if (!session) + err = -ENOMEM; + + return err; +} + +int session_del(struct iscsi_target *target, u64 sid) +{ + struct iscsi_session *session; + + session = session_lookup(target, sid); + if (!session) + return -ENOENT; + + if (!list_empty(&session->conn_list)) { + eprintk("%llu still have connections\n", (unsigned long long) session->sid); + return -EBUSY; + } + + return session_free(session); +} + +static void iet_session_info_show(struct seq_file *seq, struct iscsi_target *target) +{ + struct iscsi_session *session; + + list_for_each_entry(session, &target->session_list, list) { + seq_printf(seq, "\tsid:%llu initiator:%s\n", + (unsigned long long) session->sid, session->initiator); + conn_info_show(seq, session); + } +} + +static int iet_sessions_info_show(struct seq_file *seq, void *v) +{ + return iet_info_show(seq, iet_session_info_show); +} + +static int iet_session_seq_open(struct inode *inode, struct file *file) +{ + return single_open(file, iet_sessions_info_show, NULL); +} + +struct file_operations session_seq_fops = { + .owner = THIS_MODULE, + .open = iet_session_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; --- linux-2.6.28.orig/ubuntu/iscsitarget/iotype.h +++ linux-2.6.28/ubuntu/iscsitarget/iotype.h @@ -0,0 +1,29 @@ +/* + * (C) 2004 - 2005 FUJITA Tomonori + * This code is licenced under the GPL. + */ + +#include "iscsi.h" + +#ifndef __IOTYPE_H__ +#define __IOTYPE_H__ + +struct iotype { + const char *name; + struct list_head iot_list; + + int (*attach)(struct iet_volume *dev, char *args); + int (*make_request)(struct iet_volume *dev, struct tio *tio, int rw); + int (*sync)(struct iet_volume *dev, struct tio *tio); + void (*detach)(struct iet_volume *dev); + void (*show)(struct iet_volume *dev, struct seq_file *seq); +}; + +extern struct iotype fileio; +extern struct iotype nullio; +extern struct iotype blockio; + +extern int iotype_init(void); +extern void iotype_exit(void); + +#endif --- linux-2.6.28.orig/ubuntu/iscsitarget/BOM +++ linux-2.6.28/ubuntu/iscsitarget/BOM @@ -0,0 +1,5 @@ +Downloaded from: http://iscsitarget.sourceforge.net/ +Current Version: 0.4.17 + +Applied iscsitarget.diff in order to compile with 2.6.28. + --- linux-2.6.28.orig/ubuntu/iscsitarget/iotype.c +++ linux-2.6.28/ubuntu/iscsitarget/iotype.c @@ -0,0 +1,110 @@ +/* + * Manager for various I/O types. + * (C) 2004 - 2005 FUJITA Tomonori + * This code is licenced under the GPL. + */ + +#include "iscsi.h" +#include "iotype.h" +#include "iscsi_dbg.h" + +static LIST_HEAD(iotypes); +static rwlock_t iotypes_lock = RW_LOCK_UNLOCKED; + +static struct iotype *find_iotype(const char *name) +{ + struct iotype *iot = NULL; + + list_for_each_entry(iot, &iotypes, iot_list) { + if (strcmp(iot->name, name) == 0) + return iot; + } + return NULL; +} + +struct iotype *get_iotype(const char *name) +{ + struct iotype *iot; + + read_lock(&iotypes_lock); + iot = find_iotype(name); + read_unlock(&iotypes_lock); + + return iot; +} + +void put_iotype(struct iotype *iot) +{ + if (!iot) + return; + return; +} + +static int register_iotype(struct iotype *iot) +{ + int err = 0; + struct iotype *p; + + write_lock(&iotypes_lock); + + p = find_iotype(iot->name); + if (p) + err = -EBUSY; + else + list_add_tail(&iot->iot_list, &iotypes); + + write_unlock(&iotypes_lock); + + return err; +} + +static int unregister_iotype(struct iotype *iot) +{ + int err = 0; + struct iotype *p; + + write_lock(&iotypes_lock); + + p = find_iotype(iot->name); + if (p && p == iot) + list_del_init(&iot->iot_list); + else + err = -EINVAL; + + write_unlock(&iotypes_lock); + + + return err; +} + +struct iotype *iotype_array[] = { + &fileio, + &blockio, + &nullio, +}; + +int iotype_init(void) +{ + int i, err; + + for (i = 0; i < ARRAY_SIZE(iotype_array); i++) { + if (!(err = register_iotype(iotype_array[i]))) + iprintk("Registered io type %s\n", + iotype_array[i]->name); + else { + eprintk("Failed to register io type %s\n", + iotype_array[i]->name); + break; + } + } + + return err; +} + +void iotype_exit(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(iotype_array); i++) + unregister_iotype(iotype_array[i]); +} --- linux-2.6.28.orig/ubuntu/iscsitarget/iet_u.h +++ linux-2.6.28/ubuntu/iscsitarget/iet_u.h @@ -0,0 +1,139 @@ +#ifndef _IET_U_H +#define _IET_U_H + +#define IET_VERSION_STRING "0.4.15" + +/* The maximum length of 223 bytes in the RFC. */ +#define ISCSI_NAME_LEN 256 +#define ISCSI_ARGS_LEN 2048 + +#define ISCSI_LISTEN_PORT 3260 + +#define VENDOR_ID_LEN 8 +#define SCSI_ID_LEN 24 +#define SCSI_SN_LEN 16 + +#ifndef aligned_u64 +#define aligned_u64 unsigned long long __attribute__((aligned(8))) +#endif + +struct target_info { + u32 tid; + char name[ISCSI_NAME_LEN]; +}; + +struct volume_info { + u32 tid; + u32 lun; + aligned_u64 args_ptr; + u32 args_len; +}; + +struct session_info { + u32 tid; + + aligned_u64 sid; + char initiator_name[ISCSI_NAME_LEN]; + u32 exp_cmd_sn; + u32 max_cmd_sn; +}; + +#define DIGEST_ALL (DIGEST_NONE | DIGEST_CRC32C) +#define DIGEST_NONE (1 << 0) +#define DIGEST_CRC32C (1 << 1) + +struct conn_info { + u32 tid; + aligned_u64 sid; + + u32 cid; + u32 stat_sn; + u32 exp_stat_sn; + int header_digest; + int data_digest; + int fd; +}; + +enum { + key_initial_r2t, + key_immediate_data, + key_max_connections, + key_max_recv_data_length, + key_max_xmit_data_length, + key_max_burst_length, + key_first_burst_length, + key_default_wait_time, + key_default_retain_time, + key_max_outstanding_r2t, + key_data_pdu_inorder, + key_data_sequence_inorder, + key_error_recovery_level, + key_header_digest, + key_data_digest, + key_ofmarker, + key_ifmarker, + key_ofmarkint, + key_ifmarkint, + session_key_last, +}; + +enum { + key_wthreads, + key_target_type, + key_queued_cmnds, + target_key_last, +}; + +enum { + key_session, + key_target, +}; + +struct iscsi_param_info { + u32 tid; + aligned_u64 sid; + + u32 param_type; + u32 partial; + + u32 session_param[session_key_last]; + u32 target_param[target_key_last]; +}; + +enum iet_event_state { + E_CONN_CLOSE, +}; + +struct iet_event { + u32 tid; + aligned_u64 sid; + u32 cid; + u32 state; +}; + +#define DEFAULT_NR_WTHREADS 8 +#define MIN_NR_WTHREADS 1 +#define MAX_NR_WTHREADS 128 + +#define DEFAULT_NR_QUEUED_CMNDS 32 +#define MIN_NR_QUEUED_CMNDS 1 +#define MAX_NR_QUEUED_CMNDS 256 + +#define NETLINK_IET 21 + +#define ADD_TARGET _IOW('i', 0, struct target_info) +#define DEL_TARGET _IOW('i', 1, struct target_info) +#define START_TARGET _IO('i', 2) +#define STOP_TARGET _IO('i', 3) +#define ADD_VOLUME _IOW('i', 4, struct volume_info) +#define DEL_VOLUME _IOW('i', 5, struct volume_info) +#define ADD_SESSION _IOW('i', 6, struct session_info) +#define DEL_SESSION _IOW('i', 7, struct session_info) +#define GET_SESSION_INFO _IOWR('i', 8, struct session_info) +#define ADD_CONN _IOW('i', 9, struct conn_info) +#define DEL_CONN _IOW('i', 10, struct conn_info) +#define GET_CONN_INFO _IOWR('i', 11, struct conn_info) +#define ISCSI_PARAM_SET _IOW('i', 12, struct iscsi_param_info) +#define ISCSI_PARAM_GET _IOWR('i', 13, struct iscsi_param_info) + +#endif --- linux-2.6.28.orig/ubuntu/iscsitarget/iscsi.h +++ linux-2.6.28/ubuntu/iscsitarget/iscsi.h @@ -0,0 +1,456 @@ +/* + * Copyright (C) 2002-2003 Ardis Technolgies + * + * Released under the terms of the GNU GPL v2.0. + */ + +#ifndef __ISCSI_H__ +#define __ISCSI_H__ + +#include +#include +#include +#include +#include +#include + +#include "iscsi_hdr.h" +#include "iet_u.h" + +struct iscsi_sess_param { + int initial_r2t; + int immediate_data; + int max_connections; + int max_recv_data_length; + int max_xmit_data_length; + int max_burst_length; + int first_burst_length; + int default_wait_time; + int default_retain_time; + int max_outstanding_r2t; + int data_pdu_inorder; + int data_sequence_inorder; + int error_recovery_level; + int header_digest; + int data_digest; + int ofmarker; + int ifmarker; + int ofmarkint; + int ifmarkint; +}; + +struct iscsi_trgt_param { + int wthreads; + int target_type; + int queued_cmnds; +}; + +struct tio { + u32 pg_cnt; + + pgoff_t idx; + u32 offset; + u32 size; + + struct page **pvec; + + atomic_t count; +}; + +struct network_thread_info { + struct task_struct *task; + unsigned long flags; + struct list_head active_conns; + + spinlock_t nthread_lock; + + void (*old_state_change)(struct sock *); + void (*old_data_ready)(struct sock *, int); + void (*old_write_space)(struct sock *); +}; + +struct worker_thread_info; + +struct worker_thread { + struct task_struct *w_task; + struct list_head w_list; + struct worker_thread_info *w_info; +}; + +struct worker_thread_info { + spinlock_t wthread_lock; + + u32 nr_running_wthreads; + + struct list_head wthread_list; + struct list_head work_queue; + + wait_queue_head_t wthread_sleep; +}; + +struct iscsi_cmnd; + +struct target_type { + int id; + int (*execute_cmnd) (struct iscsi_cmnd *); +}; + +enum iscsi_device_state { + IDEV_RUNNING, + IDEV_DEL, +}; + +struct iscsi_target { + struct list_head t_list; + u32 tid; + + char name[ISCSI_NAME_LEN]; + + struct iscsi_sess_param sess_param; + struct iscsi_trgt_param trgt_param; + + atomic_t nr_volumes; + struct list_head volumes; + struct list_head session_list; + + struct network_thread_info nthread_info; + struct worker_thread_info wthread_info; + + struct semaphore target_sem; +}; + +struct iscsi_queue { + spinlock_t queue_lock; + struct iscsi_cmnd *ordered_cmnd; + struct list_head wait_list; + int active_cnt; +}; + +struct iet_volume { + u32 lun; + + enum iscsi_device_state l_state; + atomic_t l_count; + + struct iscsi_target *target; + struct list_head list; + + struct iscsi_queue queue; + + u8 scsi_id[SCSI_ID_LEN]; + u8 scsi_sn[SCSI_SN_LEN]; + + u32 blk_shift; + u64 blk_cnt; + + u64 reserve_sid; + spinlock_t reserve_lock; + + unsigned long flags; + + struct iotype *iotype; + void *private; +}; + +enum lu_flags { + LU_READONLY, + LU_WCACHE, + LU_RCACHE, +}; + +#define LUReadonly(lu) test_bit(LU_READONLY, &(lu)->flags) +#define SetLUReadonly(lu) set_bit(LU_READONLY, &(lu)->flags) + +#define LUWCache(lu) test_bit(LU_WCACHE, &(lu)->flags) +#define SetLUWCache(lu) set_bit(LU_WCACHE, &(lu)->flags) +#define ClearLUWCache(lu) clear_bit(LU_WCACHE, &(lu)->flags) + +#define LURCache(lu) test_bit(LU_RCACHE, &(lu)->flags) +#define SetLURCache(lu) set_bit(LU_RCACHE, &(lu)->flags) +#define ClearLURCache(lu) clear_bit(LU_RCACHE, &(lu)->flags) + +#define IET_HASH_ORDER 8 +#define cmnd_hashfn(itt) hash_long((itt), IET_HASH_ORDER) + +struct iscsi_session { + struct list_head list; + struct iscsi_target *target; + + char *initiator; + u64 sid; + + u32 exp_cmd_sn; + u32 max_cmd_sn; + + struct iscsi_sess_param param; + u32 max_queued_cmnds; + + struct list_head conn_list; + + struct list_head pending_list; + + spinlock_t cmnd_hash_lock; + struct list_head cmnd_hash[1 << IET_HASH_ORDER]; + + u32 next_ttt; +}; + +enum connection_state_bit { + CONN_ACTIVE, + CONN_CLOSING, + CONN_WSPACE_WAIT, +}; + +#define ISCSI_CONN_IOV_MAX (((256 << 10) >> PAGE_SHIFT) + 1) + +struct iscsi_conn { + struct list_head list; /* list entry in session list */ + struct iscsi_session *session; /* owning session */ + + u16 cid; + unsigned long state; + + u32 stat_sn; + u32 exp_stat_sn; + + int hdigest_type; + int ddigest_type; + + struct list_head poll_list; + + struct file *file; + struct socket *sock; + spinlock_t list_lock; + atomic_t nr_cmnds; + atomic_t nr_busy_cmnds; + struct list_head pdu_list; /* in/outcoming pdus */ + struct list_head write_list; /* list of data pdus to be sent */ + + struct iscsi_cmnd *read_cmnd; + struct msghdr read_msg; + struct iovec read_iov[ISCSI_CONN_IOV_MAX]; + u32 read_size; + u32 read_overflow; + int read_state; + + struct iscsi_cmnd *write_cmnd; + struct iovec write_iov[ISCSI_CONN_IOV_MAX]; + struct iovec *write_iop; + struct tio *write_tcmnd; + u32 write_size; + u32 write_offset; + int write_state; + + struct hash_desc rx_hash; + struct hash_desc tx_hash; + struct scatterlist hash_sg[ISCSI_CONN_IOV_MAX]; +}; + +struct iscsi_pdu { + struct iscsi_hdr bhs; + void *ahs; + unsigned int ahssize; + unsigned int datasize; +}; + +typedef void (iet_show_info_t)(struct seq_file *seq, struct iscsi_target *target); + +struct iscsi_cmnd { + struct list_head list; + struct list_head conn_list; + unsigned long flags; + struct iscsi_conn *conn; + struct iet_volume *lun; + + struct iscsi_pdu pdu; + struct list_head pdu_list; + + struct list_head hash_list; + + struct tio *tio; + + u32 r2t_sn; + u32 r2t_length; + u32 is_unsolicited_data; + u32 target_task_tag; + u32 outstanding_r2t; + + u32 hdigest; + u32 ddigest; + + struct iscsi_cmnd *req; +}; + +#define ISCSI_OP_SCSI_REJECT ISCSI_OP_VENDOR1_CMD +#define ISCSI_OP_PDU_REJECT ISCSI_OP_VENDOR2_CMD +#define ISCSI_OP_DATA_REJECT ISCSI_OP_VENDOR3_CMD +#define ISCSI_OP_SCSI_ABORT ISCSI_OP_VENDOR4_CMD + +/* iscsi.c */ +extern struct iscsi_cmnd *cmnd_alloc(struct iscsi_conn *, int); +extern void cmnd_rx_start(struct iscsi_cmnd *); +extern void cmnd_rx_end(struct iscsi_cmnd *); +extern void cmnd_tx_start(struct iscsi_cmnd *); +extern void cmnd_tx_end(struct iscsi_cmnd *); +extern void cmnd_release(struct iscsi_cmnd *, int); +extern void send_data_rsp(struct iscsi_cmnd *, int (*)(struct iscsi_cmnd *)); +extern void send_scsi_rsp(struct iscsi_cmnd *, int (*)(struct iscsi_cmnd *)); + +/* conn.c */ +extern struct iscsi_conn *conn_lookup(struct iscsi_session *, u16); +extern int conn_add(struct iscsi_session *, struct conn_info *); +extern int conn_del(struct iscsi_session *, struct conn_info *); +extern int conn_free(struct iscsi_conn *); +extern void conn_close(struct iscsi_conn *); +extern void conn_info_show(struct seq_file *, struct iscsi_session *); + +/* nthread.c */ +extern int nthread_init(struct iscsi_target *); +extern int nthread_start(struct iscsi_target *); +extern int nthread_stop(struct iscsi_target *); +extern void __nthread_wakeup(struct network_thread_info *); +extern void nthread_wakeup(struct iscsi_target *); + +/* wthread.c */ +extern int wthread_init(struct iscsi_target *); +extern int wthread_start(struct iscsi_target *); +extern int wthread_stop(struct iscsi_target *); +extern void wthread_queue(struct iscsi_cmnd *); +extern struct target_type *target_type_array[]; + +/* target.c */ +extern int target_lock(struct iscsi_target *, int); +extern void target_unlock(struct iscsi_target *); +struct iscsi_target *target_lookup_by_id(u32); +extern int target_add(struct target_info *); +extern int target_del(u32 id); + +/* config.c */ +extern int iet_procfs_init(void); +extern void iet_procfs_exit(void); +extern int iet_info_show(struct seq_file *, iet_show_info_t *); + +/* session.c */ +extern struct file_operations session_seq_fops; +extern struct iscsi_session *session_lookup(struct iscsi_target *, u64); +extern int session_add(struct iscsi_target *, struct session_info *); +extern int session_del(struct iscsi_target *, u64); + +/* volume.c */ +extern struct file_operations volume_seq_fops; +extern int volume_add(struct iscsi_target *, struct volume_info *); +extern int iscsi_volume_del(struct iscsi_target *, struct volume_info *); +extern void iscsi_volume_destroy(struct iet_volume *); +extern struct iet_volume *volume_lookup(struct iscsi_target *, u32); +extern struct iet_volume *volume_get(struct iscsi_target *, u32); +extern void volume_put(struct iet_volume *); +extern int volume_reserve(struct iet_volume *volume, u64 sid); +extern int volume_release(struct iet_volume *volume, u64 sid, int force); +extern int is_volume_reserved(struct iet_volume *volume, u64 sid); + +/* tio.c */ +extern int tio_init(void); +extern void tio_exit(void); +extern struct tio *tio_alloc(int); +extern void tio_get(struct tio *); +extern void tio_put(struct tio *); +extern void tio_set(struct tio *, u32, loff_t); +extern int tio_read(struct iet_volume *, struct tio *); +extern int tio_write(struct iet_volume *, struct tio *); +extern int tio_sync(struct iet_volume *, struct tio *); + +/* iotype.c */ +extern struct iotype *get_iotype(const char *name); +extern void put_iotype(struct iotype *iot); + +/* params.c */ +extern int iscsi_param_set(struct iscsi_target *, struct iscsi_param_info *, int); + +/* target_disk.c */ +extern struct target_type disk_ops; + +/* event.c */ +extern int event_send(u32, u64, u32, u32, int); +extern int event_init(void); +extern void event_exit(void); + +#define get_pgcnt(size, offset) ((((size) + ((offset) & ~PAGE_CACHE_MASK)) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT) + +static inline void iscsi_cmnd_get_length(struct iscsi_pdu *pdu) +{ +#if defined(__BIG_ENDIAN) + pdu->ahssize = pdu->bhs.length.ahslength * 4; + pdu->datasize = pdu->bhs.length.datalength; +#elif defined(__LITTLE_ENDIAN) + pdu->ahssize = (pdu->bhs.length & 0xff) * 4; + pdu->datasize = be32_to_cpu(pdu->bhs.length & ~0xff); +#else +#error +#endif +} + +static inline void iscsi_cmnd_set_length(struct iscsi_pdu *pdu) +{ +#if defined(__BIG_ENDIAN) + pdu->bhs.length.ahslength = pdu->ahssize / 4; + pdu->bhs.length.datalength = pdu->datasize; +#elif defined(__LITTLE_ENDIAN) + pdu->bhs.length = cpu_to_be32(pdu->datasize) | (pdu->ahssize / 4); +#else +#error +#endif +} + +#define cmnd_hdr(cmnd) ((struct iscsi_scsi_cmd_hdr *) (&((cmnd)->pdu.bhs))) +#define cmnd_ttt(cmnd) cpu_to_be32((cmnd)->pdu.bhs.ttt) +#define cmnd_itt(cmnd) cpu_to_be32((cmnd)->pdu.bhs.itt) +#define cmnd_opcode(cmnd) ((cmnd)->pdu.bhs.opcode & ISCSI_OPCODE_MASK) +#define cmnd_scsicode(cmnd) cmnd_hdr(cmnd)->scb[0] + +#define SECTOR_SIZE_BITS 9 + +enum cmnd_flags { + CMND_hashed, + CMND_queued, + CMND_final, + CMND_waitio, + CMND_close, + CMND_lunit, + CMND_pending, + CMND_tmfabort, + CMND_rxstart, +}; + +#define set_cmnd_hashed(cmnd) set_bit(CMND_hashed, &(cmnd)->flags) +#define cmnd_hashed(cmnd) test_bit(CMND_hashed, &(cmnd)->flags) + +#define set_cmnd_queued(cmnd) set_bit(CMND_queued, &(cmnd)->flags) +#define cmnd_queued(cmnd) test_bit(CMND_queued, &(cmnd)->flags) + +#define set_cmnd_final(cmnd) set_bit(CMND_final, &(cmnd)->flags) +#define cmnd_final(cmnd) test_bit(CMND_final, &(cmnd)->flags) + +#define set_cmnd_waitio(cmnd) set_bit(CMND_waitio, &(cmnd)->flags) +#define cmnd_waitio(cmnd) test_bit(CMND_waitio, &(cmnd)->flags) + +#define set_cmnd_close(cmnd) set_bit(CMND_close, &(cmnd)->flags) +#define cmnd_close(cmnd) test_bit(CMND_close, &(cmnd)->flags) + +#define set_cmnd_lunit(cmnd) set_bit(CMND_lunit, &(cmnd)->flags) +#define cmnd_lunit(cmnd) test_bit(CMND_lunit, &(cmnd)->flags) + +#define set_cmnd_pending(cmnd) set_bit(CMND_pending, &(cmnd)->flags) +#define clear_cmnd_pending(cmnd) clear_bit(CMND_pending, &(cmnd)->flags) +#define cmnd_pending(cmnd) test_bit(CMND_pending, &(cmnd)->flags) + +#define set_cmnd_tmfabort(cmnd) set_bit(CMND_tmfabort, &(cmnd)->flags) +#define cmnd_tmfabort(cmnd) test_bit(CMND_tmfabort, &(cmnd)->flags) + +#define set_cmnd_rxstart(cmnd) set_bit(CMND_rxstart, &(cmnd)->flags) +#define cmnd_rxstart(cmnd) test_bit(CMND_rxstart, &(cmnd)->flags) + +#define VENDOR_ID "IET" +#define PRODUCT_ID "VIRTUAL-DISK" +#define PRODUCT_REV "0" + +#endif /* __ISCSI_H__ */ --- linux-2.6.28.orig/ubuntu/iscsitarget/config.c +++ linux-2.6.28/ubuntu/iscsitarget/config.c @@ -0,0 +1,316 @@ +/* + * (C) 2004 - 2005 FUJITA Tomonori + * + * This code is licenced under the GPL. + */ + +#include + +#include "iscsi.h" +#include "iscsi_dbg.h" + +struct proc_entries { + const char *name; + struct file_operations *fops; +}; + +static struct proc_entries iet_proc_entries[] = +{ + {"volume", &volume_seq_fops}, + {"session", &session_seq_fops}, +}; + +static struct proc_dir_entry *proc_iet_dir; + +void iet_procfs_exit(void) +{ + int i; + + if (!proc_iet_dir) + return; + + for (i = 0; i < ARRAY_SIZE(iet_proc_entries); i++) + remove_proc_entry(iet_proc_entries[i].name, proc_iet_dir); + + remove_proc_entry(proc_iet_dir->name, proc_iet_dir->parent); +} + +int iet_procfs_init(void) +{ + int i; + struct proc_dir_entry *ent; + + if (!(proc_iet_dir = proc_mkdir("iet", init_net.proc_net))) + goto err; + + proc_iet_dir->owner = THIS_MODULE; + + for (i = 0; i < ARRAY_SIZE(iet_proc_entries); i++) { + ent = create_proc_entry(iet_proc_entries[i].name, 0, proc_iet_dir); + if (ent) + ent->proc_fops = iet_proc_entries[i].fops; + else + goto err; + } + + return 0; + +err: + if (proc_iet_dir) + iet_procfs_exit(); + + return -ENOMEM; +} + +static int get_conn_info(struct iscsi_target *target, unsigned long ptr) +{ + int err; + struct iscsi_session *session; + struct conn_info info; + struct iscsi_conn *conn; + + if ((err = copy_from_user(&info, (void *) ptr, sizeof(info))) < 0) + return err; + + session = session_lookup(target, info.sid); + if (!session) + return -ENOENT; + conn = conn_lookup(session, info.cid); + + info.cid = conn->cid; + info.stat_sn = conn->stat_sn; + info.exp_stat_sn = conn->exp_stat_sn; + + if (copy_to_user((void *) ptr, &info, sizeof(info))) + return -EFAULT; + + return 0; +} + +static int add_conn(struct iscsi_target *target, unsigned long ptr) +{ + int err; + struct iscsi_session *session; + struct conn_info info; + + if ((err = copy_from_user(&info, (void *) ptr, sizeof(info))) < 0) + return err; + + if (!(session = session_lookup(target, info.sid))) + return -ENOENT; + + return conn_add(session, &info); +} + +static int del_conn(struct iscsi_target *target, unsigned long ptr) +{ + int err; + struct iscsi_session *session; + struct conn_info info; + + if ((err = copy_from_user(&info, (void *) ptr, sizeof(info))) < 0) + return err; + + if (!(session = session_lookup(target, info.sid))) + return -ENOENT; + + return conn_del(session, &info); +} + +static int get_session_info(struct iscsi_target *target, unsigned long ptr) +{ + int err; + struct iscsi_session *session; + struct session_info info; + + if ((err = copy_from_user(&info, (void *) ptr, sizeof(info))) < 0) + return err; + + session = session_lookup(target, info.sid); + + if (!session) + return -ENOENT; + + info.exp_cmd_sn = session->exp_cmd_sn; + info.max_cmd_sn = session->max_cmd_sn; + + if (copy_to_user((void *) ptr, &info, sizeof(info))) + return -EFAULT; + + return 0; +} + +static int add_session(struct iscsi_target *target, unsigned long ptr) +{ + int err; + struct session_info info; + + if ((err = copy_from_user(&info, (void *) ptr, sizeof(info))) < 0) + return err; + + return session_add(target, &info); +} + +static int del_session(struct iscsi_target *target, unsigned long ptr) +{ + int err; + struct session_info info; + + if ((err = copy_from_user(&info, (void *) ptr, sizeof(info))) < 0) + return err; + + return session_del(target, info.sid); +} + +static int add_volume(struct iscsi_target *target, unsigned long ptr) +{ + int err; + struct volume_info info; + + if ((err = copy_from_user(&info, (void *) ptr, sizeof(info))) < 0) + return err; + + return volume_add(target, &info); +} + +static int del_volume(struct iscsi_target *target, unsigned long ptr) +{ + int err; + struct volume_info info; + + if ((err = copy_from_user(&info, (void *) ptr, sizeof(info))) < 0) + return err; + + return iscsi_volume_del(target, &info); +} + +static int iscsi_param_config(struct iscsi_target *target, unsigned long ptr, int set) +{ + int err; + struct iscsi_param_info info; + + if ((err = copy_from_user(&info, (void *) ptr, sizeof(info))) < 0) + goto out; + + if ((err = iscsi_param_set(target, &info, set)) < 0) + goto out; + + if (!set) + err = copy_to_user((void *) ptr, &info, sizeof(info)); + +out: + return err; +} + +static int add_target(unsigned long ptr) +{ + int err; + struct target_info info; + + if ((err = copy_from_user(&info, (void *) ptr, sizeof(info))) < 0) + return err; + + if (!(err = target_add(&info))) + err = copy_to_user((void *) ptr, &info, sizeof(info)); + + return err; +} + +static long ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct iscsi_target *target = NULL; + long err; + u32 id; + + if ((err = get_user(id, (u32 *) arg)) != 0) + goto done; + + if (cmd == DEL_TARGET) { + err = target_del(id); + goto done; + } + + target = target_lookup_by_id(id); + + if (cmd == ADD_TARGET) + if (target) { + err = -EEXIST; + eprintk("Target %u already exist!\n", id); + goto done; + } + + switch (cmd) { + case ADD_TARGET: + assert(!target); + err = add_target(arg); + goto done; + } + + if (!target) { + eprintk("can't find the target %u\n", id); + err = -EINVAL; + goto done; + } + + if ((err = target_lock(target, 1)) < 0) { + eprintk("interrupted %ld %d\n", err, cmd); + goto done; + } + + switch (cmd) { + case ADD_VOLUME: + err = add_volume(target, arg); + break; + + case DEL_VOLUME: + err = del_volume(target, arg); + break; + + case ADD_SESSION: + err = add_session(target, arg); + break; + + case DEL_SESSION: + err = del_session(target, arg); + break; + + case GET_SESSION_INFO: + err = get_session_info(target, arg); + break; + + case ISCSI_PARAM_SET: + err = iscsi_param_config(target, arg, 1); + break; + + case ISCSI_PARAM_GET: + err = iscsi_param_config(target, arg, 0); + break; + + case ADD_CONN: + err = add_conn(target, arg); + break; + + case DEL_CONN: + err = del_conn(target, arg); + break; + + case GET_CONN_INFO: + err = get_conn_info(target, arg); + break; + default: + eprintk("invalid ioctl cmd %x\n", cmd); + err = -EINVAL; + } + + if (target) + target_unlock(target); + +done: + return err; +} + +struct file_operations ctr_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = ioctl, + .compat_ioctl = ioctl, +}; --- linux-2.6.28.orig/ubuntu/iscsitarget/include/iet_u.h +++ linux-2.6.28/ubuntu/iscsitarget/include/iet_u.h @@ -0,0 +1,139 @@ +#ifndef _IET_U_H +#define _IET_U_H + +#define IET_VERSION_STRING "0.4.17" + +/* The maximum length of 223 bytes in the RFC. */ +#define ISCSI_NAME_LEN 256 +#define ISCSI_ARGS_LEN 2048 + +#define ISCSI_LISTEN_PORT 3260 + +#define VENDOR_ID_LEN 8 +#define SCSI_ID_LEN 24 +#define SCSI_SN_LEN 16 + +#ifndef aligned_u64 +#define aligned_u64 unsigned long long __attribute__((aligned(8))) +#endif + +struct target_info { + u32 tid; + char name[ISCSI_NAME_LEN]; +}; + +struct volume_info { + u32 tid; + u32 lun; + aligned_u64 args_ptr; + u32 args_len; +}; + +struct session_info { + u32 tid; + + aligned_u64 sid; + char initiator_name[ISCSI_NAME_LEN]; + u32 exp_cmd_sn; + u32 max_cmd_sn; +}; + +#define DIGEST_ALL (DIGEST_NONE | DIGEST_CRC32C) +#define DIGEST_NONE (1 << 0) +#define DIGEST_CRC32C (1 << 1) + +struct conn_info { + u32 tid; + aligned_u64 sid; + + u32 cid; + u32 stat_sn; + u32 exp_stat_sn; + int header_digest; + int data_digest; + int fd; +}; + +enum { + key_initial_r2t, + key_immediate_data, + key_max_connections, + key_max_recv_data_length, + key_max_xmit_data_length, + key_max_burst_length, + key_first_burst_length, + key_default_wait_time, + key_default_retain_time, + key_max_outstanding_r2t, + key_data_pdu_inorder, + key_data_sequence_inorder, + key_error_recovery_level, + key_header_digest, + key_data_digest, + key_ofmarker, + key_ifmarker, + key_ofmarkint, + key_ifmarkint, + session_key_last, +}; + +enum { + key_wthreads, + key_target_type, + key_queued_cmnds, + target_key_last, +}; + +enum { + key_session, + key_target, +}; + +struct iscsi_param_info { + u32 tid; + aligned_u64 sid; + + u32 param_type; + u32 partial; + + u32 session_param[session_key_last]; + u32 target_param[target_key_last]; +}; + +enum iet_event_state { + E_CONN_CLOSE, +}; + +struct iet_event { + u32 tid; + aligned_u64 sid; + u32 cid; + u32 state; +}; + +#define DEFAULT_NR_WTHREADS 8 +#define MIN_NR_WTHREADS 1 +#define MAX_NR_WTHREADS 128 + +#define DEFAULT_NR_QUEUED_CMNDS 32 +#define MIN_NR_QUEUED_CMNDS 1 +#define MAX_NR_QUEUED_CMNDS 256 + +#define NETLINK_IET 21 + +#define ADD_TARGET _IOW('i', 0, struct target_info) +#define DEL_TARGET _IOW('i', 1, struct target_info) +#define START_TARGET _IO('i', 2) +#define STOP_TARGET _IO('i', 3) +#define ADD_VOLUME _IOW('i', 4, struct volume_info) +#define DEL_VOLUME _IOW('i', 5, struct volume_info) +#define ADD_SESSION _IOW('i', 6, struct session_info) +#define DEL_SESSION _IOW('i', 7, struct session_info) +#define GET_SESSION_INFO _IOWR('i', 8, struct session_info) +#define ADD_CONN _IOW('i', 9, struct conn_info) +#define DEL_CONN _IOW('i', 10, struct conn_info) +#define GET_CONN_INFO _IOWR('i', 11, struct conn_info) +#define ISCSI_PARAM_SET _IOW('i', 12, struct iscsi_param_info) +#define ISCSI_PARAM_GET _IOWR('i', 13, struct iscsi_param_info) + +#endif --- linux-2.6.28.orig/ubuntu/lirc/Kconfig +++ linux-2.6.28/ubuntu/lirc/Kconfig @@ -0,0 +1,94 @@ +config LIRC_DEV + tristate "LIRC Device support" + default m + +config LIRC_ATIUSB + tristate "LIRC ATI RF Remote" + default m + depends on LIRC_DEV + +config LIRC_BT829 + tristate "LIRC BT829" + default m + depends on LIRC_DEV + +config LIRC_CMDIR + tristate "LIRC CommandIR kernel support" + default m + depends on LIRC_DEV + +config LIRC_I2C + tristate "LIRC I2C interface remote" + default m + depends on LIRC_DEV + +config LIRC_IGORPLUGUSB + tristate "LIRC IGOR custom remote" + default m + depends on LIRC_DEV + +config LIRC_IMON + tristate "LIRC Imon remote or pad" + default m + depends on LIRC_DEV + +config LIRC_IT87 + tristate "LIRC IT87" + default m + depends on LIRC_DEV + +config LIRC_MCEUSB + tristate "LIRC Microsoft Media Center Remote" + default m + depends on LIRC_DEV + +config LIRC_MCEUSB2 + tristate "LIRC Microsoft Media Center Remote v2" + default m + depends on LIRC_DEV + +config LIRC_PVR150 + tristate "LIRC Hauppauge PVR-XXX remote" + default m + depends on LIRC_DEV + depends on VIDEO_IVTV + +config LIRC_PARALLEL + tristate "LIRC Parallel port custom remote" + default n + depends on LIRC_DEV + +config LIRC_SASEM + tristate "LIRC Sasem" + default m + depends on LIRC_DEV + +config LIRC_SERIAL + tristate "LIRC Serial port remote" + default m + depends on LIRC_DEV + +config LIRC_SERIAL_IGOR + tristate "LIRC Igor design serial remote" + default m + depends on LIRC_DEV + +config LIRC_SIR + tristate "LIRC Laptop port IR (SIR))" + default m + depends on LIRC_DEV + +config LIRC_STREAMZAP + tristate "LIRC Streamzap remote" + default m + depends on LIRC_DEV + +config LIRC_TTUSBIR + tristate "LIRC TT USB IR device" + default m + depends on LIRC_DEV + +config LIRC_GPIO + tristate "LIRC TV Card GPIO remote" + default n + depends on LIRC_DEV --- linux-2.6.28.orig/ubuntu/lirc/kcompat.h +++ linux-2.6.28/ubuntu/lirc/kcompat.h @@ -0,0 +1,369 @@ +/* $Id: kcompat.h,v 5.36 2008/05/14 16:37:49 lirc Exp $ */ + +#ifndef _KCOMPAT_H +#define _KCOMPAT_H + +#include + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) +#define LIRC_THIS_MODULE(x) x, +#else /* >= 2.6.16 */ +#define LIRC_THIS_MODULE(x) +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) + +#include + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#define LIRC_HAVE_DEVFS +#define LIRC_HAVE_DEVFS_26 +#endif + +#define LIRC_HAVE_SYSFS + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) + +typedef struct class_simple lirc_class_t; + +static inline lirc_class_t *class_create(struct module *owner, char *name) +{ + return class_simple_create(owner, name); +} + +static inline void class_destroy(lirc_class_t *cls) +{ + class_simple_destroy(cls); +} + +#define lirc_device_create(cs, parent, dev, fmt, args...) \ + class_simple_device_add(cs, dev, parent, fmt, ## args) + +static inline void lirc_device_destroy(lirc_class_t *cls, dev_t devt) +{ + class_simple_device_remove(devt); +} + +#else /* >= 2.6.13 */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15) + +#define lirc_device_create(cs, parent, dev, fmt, args...) \ + class_device_create(cs, dev, parent, fmt, ## args) + +#else /* >= 2.6.15 */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) + +#define lirc_device_create(cs, parent, dev, fmt, args...) \ + class_device_create(cs, NULL, dev, parent, fmt, ## args) + +#else /* >= 2.6.26 */ + +#define lirc_device_create device_create + +#endif /* >= 2.6.26 */ + +#define LIRC_DEVFS_PREFIX + +#endif /* >= 2.6.15 */ + +typedef struct class lirc_class_t; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) + +#define lirc_device_destroy class_device_destroy + +#else + +#define lirc_device_destroy device_destroy + +#endif + +#endif /* >= 2.6.13 */ + +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) +#define LIRC_HAVE_DEVFS +#define LIRC_HAVE_DEVFS_24 +#endif + +#ifndef LIRC_DEVFS_PREFIX +#define LIRC_DEVFS_PREFIX "usb/" +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0) +#include +#include +static inline void del_timer_sync(struct timer_list *timerlist) +{ + start_bh_atomic(); + del_timer(timerlist); + end_bh_atomic(); +} +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +#ifdef daemonize +#undef daemonize +#endif +#define daemonize(name) do { \ + \ + lock_kernel(); \ + \ + exit_mm(current); \ + exit_files(current); \ + exit_fs(current); \ + current->session = 1; \ + current->pgrp = 1; \ + current->euid = 0; \ + current->tty = NULL; \ + sigfillset(¤t->blocked); \ + \ + strcpy(current->comm, name); \ + \ + unlock_kernel(); \ + \ +} while (0) + +/* Not sure when this was introduced, sometime during 2.5.X */ +#define MODULE_PARM_int(x) MODULE_PARM(x, "i") +#define MODULE_PARM_bool(x) MODULE_PARM(x, "i") +#define MODULE_PARM_long(x) MODULE_PARM(x, "l") +#define module_param(x, y, z) MODULE_PARM_##y(x) +#else +#include +#endif /* Linux < 2.6.0 */ + +/* DevFS header */ +#if defined(LIRC_HAVE_DEVFS) +#include +#endif + +#ifdef LIRC_HAVE_DEVFS_24 +#ifdef register_chrdev +#undef register_chrdev +#endif +#define register_chrdev devfs_register_chrdev +#ifdef unregister_chrdev +#undef unregister_chrdev +#endif +#define unregister_chrdev devfs_unregister_chrdev +#endif /* DEVFS 2.4 */ + +#ifndef LIRC_HAVE_SYSFS +#define class_destroy(x) do { } while (0) +#define class_create(x, y) NULL +#define lirc_class_destroy(x, y) do { } while (0) +#define lirc_class_create(x, y, z, xx, yy, zz) 0 +#define IS_ERR(x) 0 +typedef struct class_simple +{ + int notused; +} lirc_class_t; +#endif /* No SYSFS */ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0) +#define KERNEL_2_5 + +/* + * We still are using MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT in the set_use_inc + * function of all modules for 2.4 kernel compatibility. + * + * For 2.6 kernels reference counting is done in lirc_dev by + * try_module_get()/module_put() because the old approach is racy. + * + */ +#ifdef MOD_INC_USE_COUNT +#undef MOD_INC_USE_COUNT +#endif +#define MOD_INC_USE_COUNT + +#ifdef MOD_DEC_USE_COUNT +#undef MOD_DEC_USE_COUNT +#endif +#define MOD_DEC_USE_COUNT + +#ifdef EXPORT_NO_SYMBOLS +#undef EXPORT_NO_SYMBOLS +#endif +#define EXPORT_NO_SYMBOLS + +#else /* Kernel < 2.5.0 */ + +static inline int try_module_get(struct module *module) +{ + return 1; +} + +static inline void module_put(struct module *module) +{ +} + +#endif /* Kernel >= 2.5.0 */ + +#ifndef MODULE_LICENSE +#define MODULE_LICENSE(x) +#endif + +#ifndef MODULE_PARM_DESC +#define MODULE_PARM_DESC(x, y) +#endif + +#ifndef MODULE_ALIAS_CHARDEV_MAJOR +#define MODULE_ALIAS_CHARDEV_MAJOR(x) +#endif + +#ifndef MODULE_DEVICE_TABLE +#define MODULE_DEVICE_TABLE(x, y) +#endif + +#include +#ifndef IRQ_RETVAL +typedef void irqreturn_t; +#define IRQ_NONE +#define IRQ_HANDLED +#define IRQ_RETVAL(x) +#endif + +#ifndef MOD_IN_USE +#ifdef CONFIG_MODULE_UNLOAD +#define MOD_IN_USE module_refcount(THIS_MODULE) +#else +#error "LIRC modules currently require" +#error " 'Loadable module support ---> Module unloading'" +#error "to be enabled in the kernel" +#endif +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#if !defined(local_irq_save) +#define local_irq_save(flags) do { save_flags(flags); cli(); } while (0) +#endif +#if !defined(local_irq_restore) +#define local_irq_restore(flags) do { restore_flags(flags); } while (0) +#endif +#endif + +#if KERNEL_VERSION(2, 4, 0) <= LINUX_VERSION_CODE +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 22) +#include +static inline char *pci_name(struct pci_dev *pdev) +{ + return pdev->slot_name; +} +#endif /* kernel < 2.4.22 */ +#endif /* kernel >= 2.4.0 */ + +/*************************** I2C specific *****************************/ +#include + +#ifndef I2C_CLIENT_END +#error "********************************************************" +#error " Sorry, this driver needs the new I2C stack. " +#error " You can get it at http://www2.lm-sensors.nu/~lm78/. " +#error "********************************************************" +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) + +#undef i2c_get_clientdata +#define i2c_get_clientdata(client) ((client)->data) + + +#undef i2c_set_clientdata +#define i2c_set_clientdata(client_ptr, new_data) do { \ + (client_ptr)->data = new_data; \ +} while (0) + + +#endif + +/* removed in 2.6.14 */ +#ifndef I2C_ALGO_BIT +# define I2C_ALGO_BIT 0 +#endif + +/* removed in 2.6.16 */ +#ifndef I2C_DRIVERID_EXP3 +# define I2C_DRIVERID_EXP3 0xf003 +#endif + +/*************************** USB specific *****************************/ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) +#include + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 8) +static inline int usb_kill_urb(struct urb *urb) +{ + return usb_unlink_urb(urb); +} +#endif + +/* removed in 2.6.14 */ +#ifndef URB_ASYNC_UNLINK +#define URB_ASYNC_UNLINK 0 +#endif +#endif + +/*************************** bttv specific ****************************/ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15) /* BTTV_* -> BTTV_BOARD_* */ +#define BTTV_BOARD_UNKNOWN BTTV_UNKNOWN +#define BTTV_BOARD_PXELVWPLTVPAK BTTV_PXELVWPLTVPAK +#define BTTV_BOARD_PXELVWPLTVPRO BTTV_PXELVWPLTVPRO +#define BTTV_BOARD_PV_BT878P_9B BTTV_PV_BT878P_9B +#define BTTV_BOARD_PV_BT878P_PLUS BTTV_PV_BT878P_PLUS +#define BTTV_BOARD_AVERMEDIA BTTV_AVERMEDIA +#define BTTV_BOARD_AVPHONE98 BTTV_AVPHONE98 +#define BTTV_BOARD_AVERMEDIA98 BTTV_AVERMEDIA98 +#define BTTV_BOARD_CHRONOS_VS2 BTTV_CHRONOS_VS2 +#define BTTV_BOARD_MIRO BTTV_MIRO +#define BTTV_BOARD_DYNALINK BTTV_DYNALINK +#define BTTV_BOARD_WINVIEW_601 BTTV_WINVIEW_601 +#ifdef BTTV_KWORLD +#define BTTV_BOARD_KWORLD BTTV_KWORLD +#endif +#define BTTV_BOARD_MAGICTVIEW061 BTTV_MAGICTVIEW061 +#define BTTV_BOARD_MAGICTVIEW063 BTTV_MAGICTVIEW063 +#define BTTV_BOARD_PHOEBE_TVMAS BTTV_PHOEBE_TVMAS +#ifdef BTTV_BESTBUY_EASYTV2 +#define BTTV_BOARD_BESTBUY_EASYTV BTTV_BESTBUY_EASYTV +#define BTTV_BOARD_BESTBUY_EASYTV2 BTTV_BESTBUY_EASYTV2 +#endif +#define BTTV_BOARD_FLYVIDEO BTTV_FLYVIDEO +#define BTTV_BOARD_FLYVIDEO_98 BTTV_FLYVIDEO_98 +#define BTTV_BOARD_TYPHOON_TVIEW BTTV_TYPHOON_TVIEW +#ifdef BTTV_FLYVIDEO_98FM +#define BTTV_BOARD_FLYVIDEO_98FM BTTV_FLYVIDEO_98FM +#endif +#define BTTV_BOARD_WINFAST2000 BTTV_WINFAST2000 +#ifdef BTTV_GVBCTV5PCI +#define BTTV_BOARD_GVBCTV5PCI BTTV_GVBCTV5PCI +#endif +#endif /* end BTTV_* -> BTTV_BOARD_* */ + + +/******************************* pm.h *********************************/ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) +typedef u32 pm_message_t; +#endif /* kernel < 2.6.11 */ +#endif /* kernel >= 2.6.0 */ + +/*************************** interrupt.h ******************************/ +/* added in 2.6.18, old defines removed in 2.6.24 */ +#ifndef IRQF_DISABLED +#define IRQF_DISABLED SA_INTERRUPT +#endif +#ifndef IRQF_SHARED +#define IRQF_SHARED SA_SHIRQ +#endif + +/*************************** spinlock.h *******************************/ +/* added in 2.6.11 */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) +#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED +#endif + +#endif /* _KCOMPAT_H */ --- linux-2.6.28.orig/ubuntu/lirc/Makefile +++ linux-2.6.28/ubuntu/lirc/Makefile @@ -0,0 +1,24 @@ +#include $(src)/../../.config + +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src) + +obj-$(CONFIG_LIRC_DEV) += lirc_dev/ +obj-$(CONFIG_LIRC_ATIUSB) += lirc_atiusb/ +obj-$(CONFIG_LIRC_BT829) += lirc_bt829/ +obj-$(CONFIG_LIRC_CMDIR) += lirc_cmdir/ +obj-$(CONFIG_LIRC_I2C) += lirc_i2c/ +obj-$(CONFIG_LIRC_IGORPLUGUSB) += lirc_igorplugusb/ +obj-$(CONFIG_LIRC_IMON) += lirc_imon/ +obj-$(CONFIG_LIRC_IT87) += lirc_it87/ +obj-$(CONFIG_LIRC_MCEUSB) += lirc_mceusb/ +obj-$(CONFIG_LIRC_MCEUSB2) += lirc_mceusb2/ +obj-$(CONFIG_LIRC_PVR150) += lirc_pvr150/ +obj-$(CONFIG_LIRC_PARALLEL) += lirc_parallel/ +obj-$(CONFIG_LIRC_SASEM) += lirc_sasem/ +obj-$(CONFIG_LIRC_SERIAL) += lirc_serial/ +obj-$(CONFIG_LIRC_SERIAL_IGOR) += lirc_serial_igor/ +obj-$(CONFIG_LIRC_SIR) += lirc_sir/ +obj-$(CONFIG_LIRC_STREAMZAP) += lirc_streamzap/ +obj-$(CONFIG_LIRC_TTUSBIR) += lirc_ttusbir/ +obj-$(CONFIG_LIRC_GPIO) += lirc_gpio/ +obj-$(CONFIG_LIRC_TTUSBIR) += lirc_ttusbir/ --- linux-2.6.28.orig/ubuntu/lirc/lirc.h +++ linux-2.6.28/ubuntu/lirc/lirc.h @@ -0,0 +1,110 @@ +/* $Id: lirc.h,v 5.14 2008/01/12 21:57:57 lirc Exp $ */ + +#ifndef _LINUX_LIRC_H +#define _LINUX_LIRC_H + +#if defined(__linux__) +#include +#include +#else +#include +#if defined(__NetBSD__) +#include +#endif +typedef u_int32_t __u32; +#endif + +#define PULSE_BIT 0x01000000 +#define PULSE_MASK 0x00FFFFFF + +typedef int lirc_t; + +/* + * lirc compatible hardware features + */ + + +#define LIRC_MODE2SEND(x) (x) +#define LIRC_SEND2MODE(x) (x) +#define LIRC_MODE2REC(x) ((x) << 16) +#define LIRC_REC2MODE(x) ((x) >> 16) + +#define LIRC_MODE_RAW 0x00000001 +#define LIRC_MODE_PULSE 0x00000002 +#define LIRC_MODE_MODE2 0x00000004 +#define LIRC_MODE_CODE 0x00000008 +#define LIRC_MODE_LIRCCODE 0x00000010 +#define LIRC_MODE_STRING 0x00000020 + + +#define LIRC_CAN_SEND_RAW LIRC_MODE2SEND(LIRC_MODE_RAW) +#define LIRC_CAN_SEND_PULSE LIRC_MODE2SEND(LIRC_MODE_PULSE) +#define LIRC_CAN_SEND_MODE2 LIRC_MODE2SEND(LIRC_MODE_MODE2) +#define LIRC_CAN_SEND_CODE LIRC_MODE2SEND(LIRC_MODE_CODE) +#define LIRC_CAN_SEND_LIRCCODE LIRC_MODE2SEND(LIRC_MODE_LIRCCODE) +#define LIRC_CAN_SEND_STRING LIRC_MODE2SEND(LIRC_MODE_STRING) + +#define LIRC_CAN_SEND_MASK 0x0000003f + +#define LIRC_CAN_SET_SEND_CARRIER 0x00000100 +#define LIRC_CAN_SET_SEND_DUTY_CYCLE 0x00000200 +#define LIRC_CAN_SET_TRANSMITTER_MASK 0x00000400 + +#define LIRC_CAN_REC_RAW LIRC_MODE2REC(LIRC_MODE_RAW) +#define LIRC_CAN_REC_PULSE LIRC_MODE2REC(LIRC_MODE_PULSE) +#define LIRC_CAN_REC_MODE2 LIRC_MODE2REC(LIRC_MODE_MODE2) +#define LIRC_CAN_REC_CODE LIRC_MODE2REC(LIRC_MODE_CODE) +#define LIRC_CAN_REC_LIRCCODE LIRC_MODE2REC(LIRC_MODE_LIRCCODE) +#define LIRC_CAN_REC_STRING LIRC_MODE2REC(LIRC_MODE_STRING) + +#define LIRC_CAN_REC_MASK LIRC_MODE2REC(LIRC_CAN_SEND_MASK) + +#define LIRC_CAN_SET_REC_CARRIER (LIRC_CAN_SET_SEND_CARRIER << 16) +#define LIRC_CAN_SET_REC_DUTY_CYCLE (LIRC_CAN_SET_SEND_DUTY_CYCLE << 16) + +#define LIRC_CAN_SET_REC_DUTY_CYCLE_RANGE 0x40000000 +#define LIRC_CAN_SET_REC_CARRIER_RANGE 0x80000000 +#define LIRC_CAN_GET_REC_RESOLUTION 0x20000000 + +#define LIRC_CAN_SEND(x) ((x)&LIRC_CAN_SEND_MASK) +#define LIRC_CAN_REC(x) ((x)&LIRC_CAN_REC_MASK) + +#define LIRC_CAN_NOTIFY_DECODE 0x01000000 + +/* + * IOCTL commands for lirc driver + */ + +#define LIRC_GET_FEATURES _IOR('i', 0x00000000, __u32) + +#define LIRC_GET_SEND_MODE _IOR('i', 0x00000001, __u32) +#define LIRC_GET_REC_MODE _IOR('i', 0x00000002, __u32) +#define LIRC_GET_SEND_CARRIER _IOR('i', 0x00000003, __u32) +#define LIRC_GET_REC_CARRIER _IOR('i', 0x00000004, __u32) +#define LIRC_GET_SEND_DUTY_CYCLE _IOR('i', 0x00000005, __u32) +#define LIRC_GET_REC_DUTY_CYCLE _IOR('i', 0x00000006, __u32) +#define LIRC_GET_REC_RESOLUTION _IOR('i', 0x00000007, __u32) + +/* code length in bits, currently only for LIRC_MODE_LIRCCODE */ +#define LIRC_GET_LENGTH _IOR('i', 0x0000000f, __u32) + +#define LIRC_SET_SEND_MODE _IOW('i', 0x00000011, __u32) +#define LIRC_SET_REC_MODE _IOW('i', 0x00000012, __u32) +/* Note: these can reset the according pulse_width */ +#define LIRC_SET_SEND_CARRIER _IOW('i', 0x00000013, __u32) +#define LIRC_SET_REC_CARRIER _IOW('i', 0x00000014, __u32) +#define LIRC_SET_SEND_DUTY_CYCLE _IOW('i', 0x00000015, __u32) +#define LIRC_SET_REC_DUTY_CYCLE _IOW('i', 0x00000016, __u32) +#define LIRC_SET_TRANSMITTER_MASK _IOW('i', 0x00000017, __u32) + +/* to set a range use + LIRC_SET_REC_DUTY_CYCLE_RANGE/LIRC_SET_REC_CARRIER_RANGE with the + lower bound first and later + LIRC_SET_REC_DUTY_CYCLE/LIRC_SET_REC_CARRIER with the upper bound */ + +#define LIRC_SET_REC_DUTY_CYCLE_RANGE _IOW('i', 0x0000001e, __u32) +#define LIRC_SET_REC_CARRIER_RANGE _IOW('i', 0x0000001f, __u32) + +#define LIRC_NOTIFY_DECODE _IO('i', 0x00000020) + +#endif --- linux-2.6.28.orig/ubuntu/lirc/lirc_igorplugusb/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_igorplugusb/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_IGORPLUGUSB) += lirc_igorplugusb.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_igorplugusb/lirc_igorplugusb.c +++ linux-2.6.28/ubuntu/lirc/lirc_igorplugusb/lirc_igorplugusb.c @@ -0,0 +1,697 @@ +/* lirc_igorplugusb - USB remote support for LIRC + * + * Supports the standard homebrew IgorPlugUSB receiver with Igor's firmware. + * See http://www.cesko.host.sk/IgorPlugUSB/IgorPlug-USB%20(AVR)_eng.htm + * + * The device can only record bursts of up to 36 pulses/spaces. + * Works fine with RC5. Longer commands lead to device buffer overrun. + * (Maybe a better firmware or a microcontroller with more ram can help?) + * + * Version 0.1 [beta status] + * + * Copyright (C) 2004 Jan M. Hochstein + * + * + * This driver was derived from: + * Paul Miller + * "lirc_atiusb" module + * Vladimir Dergachev 's 2002 + * "USB ATI Remote support" (input device) + * Adrian Dewhurst 's 2002 + * "USB StreamZap remote driver" (LIRC) + * Artur Lipowski 's 2002 + * "lirc_dev" and "lirc_gpio" LIRC modules + * + */ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) +#error "*******************************************************" +#error "Sorry, this driver needs kernel version 2.4.0 or higher" +#error "*******************************************************" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kcompat.h" +#include "lirc.h" +#include "lirc_dev/lirc_dev.h" + +#if !defined(KERNEL_2_5) +#define USB_CTRL_GET_TIMEOUT 5 +#endif + +/* lock irctl structure */ +#define IRLOCK down_interruptible(&ir->lock) +#define IRUNLOCK up(&ir->lock) + +/* module identification */ +#define DRIVER_VERSION "0.1" +#define DRIVER_AUTHOR \ + "Jan M. Hochstein " +#define DRIVER_DESC "USB remote driver for LIRC" +#define DRIVER_NAME "lirc_igorplugusb" + +/* debugging support */ +#ifdef CONFIG_USB_DEBUG +static int debug = 1; +#else +static int debug; +#endif + +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG fmt, ## args); \ + } while (0) + +/* general constants */ +#define SUCCESS 0 + +/* One mode2 pulse/space has 4 bytes. */ +#define CODE_LENGTH sizeof(lirc_t) + +/* Igor's firmware cannot record bursts longer than 36. */ +#define DEVICE_BUFLEN 36 + +/** Header at the beginning of the device's buffer: + unsigned char data_length + unsigned char data_start (!=0 means ring-buffer overrun) + unsigned char counter (incremented by each burst) +**/ +#define DEVICE_HEADERLEN 3 + +/* This is for the gap */ +#define ADDITIONAL_LIRC_BYTES 2 + +/* times to poll per second */ +#define SAMPLE_RATE 100 + +static int sample_rate = SAMPLE_RATE; + +/**** Igor's USB Request Codes */ + +#define SET_INFRABUFFER_EMPTY 1 +/** + * Params: none + * Answer: empty + * +**/ + +#define GET_INFRACODE 2 +/** + * Params: + * wValue: offset to begin reading infra buffer + * + * Answer: infra data + * +**/ + +#define SET_DATAPORT_DIRECTION 3 +/** + * Params: + * wValue: (byte) 1 bit for each data port pin (0=in, 1=out) + * + * Answer: empty + * +**/ + +#define GET_DATAPORT_DIRECTION 4 +/** + * Params: none + * + * Answer: (byte) 1 bit for each data port pin (0=in, 1=out) + * +**/ + +#define SET_OUT_DATAPORT 5 +/** + * Params: + * wValue: byte to write to output data port + * + * Answer: empty + * +**/ + +#define GET_OUT_DATAPORT 6 +/** + * Params: none + * + * Answer: least significant 3 bits read from output data port + * +**/ + +#define GET_IN_DATAPORT 7 +/** + * Params: none + * + * Answer: least significant 3 bits read from input data port + * +**/ + +#define READ_EEPROM 8 +/** + * Params: + * wValue: offset to begin reading EEPROM + * + * Answer: EEPROM bytes + * +**/ + +#define WRITE_EEPROM 9 +/** + * Params: + * wValue: offset to EEPROM byte + * wIndex: byte to write + * + * Answer: empty + * +**/ + +#define SEND_RS232 10 +/** + * Params: + * wValue: byte to send + * + * Answer: empty + * +**/ + +#define RECV_RS232 11 +/** + * Params: none + * + * Answer: byte received + * +**/ + +#define SET_RS232_BAUD 12 +/** + * Params: + * wValue: byte to write to UART bit rate register (UBRR) + * + * Answer: empty + * +**/ + +#define GET_RS232_BAUD 13 +/** + * Params: none + * + * Answer: byte read from UART bit rate register (UBRR) + * +**/ + + +/* data structure for each usb remote */ +struct irctl { + + /* usb */ + struct usb_device *usbdev; + struct urb *urb_in; + int devnum; + + unsigned char *buf_in; + unsigned int len_in; + int in_space; + struct timeval last_time; + +#if defined(KERNEL_2_5) + dma_addr_t dma_in; +#endif + + /* lirc */ + struct lirc_plugin *p; + + /* handle sending (init strings) */ + int send_flags; + wait_queue_head_t wait_out; + + struct semaphore lock; +}; + +static int unregister_from_lirc(struct irctl *ir) +{ + struct lirc_plugin *p = ir->p; + int devnum; + + if (!ir->p) + return -EINVAL; + + devnum = ir->devnum; + dprintk(DRIVER_NAME "[%d]: unregister from lirc called\n", devnum); + + lirc_unregister_plugin(p->minor); + + printk(DRIVER_NAME "[%d]: usb remote disconnected\n", devnum); + + lirc_buffer_free(p->rbuf); + kfree(p->rbuf); + kfree(p); + kfree(ir); + ir->p = NULL; + return SUCCESS; +} + +static int set_use_inc(void *data) +{ + struct irctl *ir = data; + + if (!ir) { + printk(DRIVER_NAME "[?]: set_use_inc called with no context\n"); + return -EIO; + } + dprintk(DRIVER_NAME "[%d]: set use inc\n", ir->devnum); + + MOD_INC_USE_COUNT; + + if (!ir->usbdev) + return -ENODEV; + + return SUCCESS; +} + +static void set_use_dec(void *data) +{ + struct irctl *ir = data; + + if (!ir) { + printk(DRIVER_NAME "[?]: set_use_dec called with no context\n"); + return; + } + dprintk(DRIVER_NAME "[%d]: set use dec\n", ir->devnum); + + MOD_DEC_USE_COUNT; +} + + +/** + * Called in user context. + * return 0 if data was added to the buffer and + * -ENODATA if none was available. This should add some number of bits + * evenly divisible by code_length to the buffer +**/ +static int usb_remote_poll(void *data, struct lirc_buffer *buf) +{ + int ret; + struct irctl *ir = (struct irctl *)data; + + if (!ir->usbdev) /* Has the device been removed? */ + return -ENODEV; + + memset(ir->buf_in, 0, ir->len_in); + + ret = usb_control_msg( + ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), + GET_INFRACODE, USB_TYPE_VENDOR|USB_DIR_IN, + 0/* offset */, /*unused*/0, + ir->buf_in, ir->len_in, + /*timeout*/HZ * USB_CTRL_GET_TIMEOUT); + if (ret > 0) { + int i = DEVICE_HEADERLEN; + lirc_t code, timediff; + struct timeval now; + + if (ret <= 1) /* ACK packet has 1 byte --> ignore */ + return -ENODATA; + + dprintk(DRIVER_NAME ": Got %d bytes. Header: %02x %02x %02x\n", + ret, ir->buf_in[0], ir->buf_in[1], ir->buf_in[2]); + + if (ir->buf_in[2] != 0) { + printk(DRIVER_NAME "[%d]: Device buffer overrun.\n", + ir->devnum); + /* start at earliest byte */ + i = DEVICE_HEADERLEN + ir->buf_in[2]; + /* where are we now? space, gap or pulse? */ + } + + do_gettimeofday(&now); + timediff = now.tv_sec - ir->last_time.tv_sec; + if (timediff + 1 > PULSE_MASK / 1000000) + timediff = PULSE_MASK; + else { + timediff *= 1000000; + timediff += now.tv_usec - ir->last_time.tv_usec; + } + ir->last_time.tv_sec = now.tv_sec; + ir->last_time.tv_usec = now.tv_usec; + + /* create leading gap */ + code = timediff; + lirc_buffer_write_n(buf, (unsigned char *)&code, 1); + ir->in_space = 1; /* next comes a pulse */ + + /* MODE2: pulse/space (PULSE_BIT) in 1us units */ + + while (i < ret) { + /* 1 Igor-tick = 85.333333 us */ + code = (unsigned int)ir->buf_in[i] * 85 + + (unsigned int)ir->buf_in[i] / 3; + ir->last_time.tv_usec += code; + if (ir->in_space) + code |= PULSE_BIT; + lirc_buffer_write_n(buf, (unsigned char *)&code, 1); + /* 1 chunk = CODE_LENGTH bytes */ + ir->in_space ^= 1; + ++i; + } + + ret = usb_control_msg( + ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), + SET_INFRABUFFER_EMPTY, USB_TYPE_VENDOR|USB_DIR_IN, + /*unused*/0, /*unused*/0, + /*dummy*/ir->buf_in, /*dummy*/ir->len_in, + /*timeout*/HZ * USB_CTRL_GET_TIMEOUT); + if (ret < 0) + printk(DRIVER_NAME "[%d]: SET_INFRABUFFER_EMPTY: " + "error %d\n", ir->devnum, ret); + return SUCCESS; + } else + printk(DRIVER_NAME "[%d]: GET_INFRACODE: error %d\n", + ir->devnum, ret); + + return -ENODATA; +} + + + +#if defined(KERNEL_2_5) +static int usb_remote_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_device *dev = NULL; + struct usb_host_interface *idesc = NULL; + struct usb_host_endpoint *ep_ctl2; +#else +static void *usb_remote_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id) +{ + struct usb_interface *intf; + struct usb_interface_descriptor *idesc; + struct usb_endpoint_descriptor *ep_ctl2; +#endif + struct irctl *ir = NULL; + struct lirc_plugin *plugin = NULL; + struct lirc_buffer *rbuf = NULL; + int devnum, pipe, maxp, bytes_in_key; + int minor = 0; + char buf[63], name[128] = ""; + int mem_failure = 0; + int ret; + + dprintk(DRIVER_NAME ": usb probe called.\n"); + +#if defined(KERNEL_2_5) + dev = interface_to_usbdev(intf); + +# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 5) + idesc = &intf->altsetting[intf->act_altsetting]; /* in 2.6.4 */ +# else + idesc = intf->cur_altsetting; /* in 2.6.6 */ +# endif + + if (idesc->desc.bNumEndpoints != 1) + return -ENODEV; + ep_ctl2 = idesc->endpoint; + if (((ep_ctl2->desc.bEndpointAddress & USB_ENDPOINT_DIR_MASK) + != USB_DIR_IN) + || (ep_ctl2->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + != USB_ENDPOINT_XFER_CONTROL) + return -ENODEV; + pipe = usb_rcvctrlpipe(dev, ep_ctl2->desc.bEndpointAddress); +#else + intf = &dev->actconfig->interface[ifnum]; + idesc = &intf->altsetting[intf->act_altsetting]; + if (idesc->bNumEndpoints != 1) + return NULL; + ep_ctl2 = idesc->endpoint; + if (((ep_ctl2->bEndpointAddress & USB_ENDPOINT_DIR_MASK) + != USB_DIR_IN) + || (ep_ctl2->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + != USB_ENDPOINT_XFER_CONTROL) + return NULL; + pipe = usb_rcvctrlpipe(dev, ep_ctl2->bEndpointAddress); +#endif + devnum = dev->devnum; + maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); + + bytes_in_key = CODE_LENGTH; + + dprintk(DRIVER_NAME "[%d]: bytes_in_key=%d maxp=%d\n", + devnum, bytes_in_key, maxp); + + + /* allocate kernel memory */ + mem_failure = 0; + ir = kmalloc(sizeof(struct irctl), GFP_KERNEL); + if (!ir) { + mem_failure = 1; + goto mem_failure_switch; + } + + memset(ir, 0, sizeof(struct irctl)); + + plugin = kmalloc(sizeof(struct lirc_plugin), GFP_KERNEL); + if (!plugin) { + mem_failure = 2; + goto mem_failure_switch; + } + + rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); + if (!rbuf) { + mem_failure = 3; + goto mem_failure_switch; + } + + if (lirc_buffer_init(rbuf, bytes_in_key, + DEVICE_BUFLEN+ADDITIONAL_LIRC_BYTES)) { + mem_failure = 4; + goto mem_failure_switch; + } + +#if defined(KERNEL_2_5) + ir->buf_in = usb_buffer_alloc(dev, + DEVICE_BUFLEN+DEVICE_HEADERLEN, + GFP_ATOMIC, &ir->dma_in); +#else + ir->buf_in = kmalloc(DEVICE_BUFLEN+DEVICE_HEADERLEN, + GFP_KERNEL); +#endif + if (!ir->buf_in) { + mem_failure = 5; + goto mem_failure_switch; + } + + memset(plugin, 0, sizeof(struct lirc_plugin)); + + strcpy(plugin->name, DRIVER_NAME " "); + plugin->minor = -1; + plugin->code_length = bytes_in_key*8; /* in bits */ + plugin->features = LIRC_CAN_REC_MODE2; + plugin->data = ir; + plugin->rbuf = rbuf; + plugin->set_use_inc = &set_use_inc; + plugin->set_use_dec = &set_use_dec; + plugin->sample_rate = sample_rate; /* per second */ + plugin->add_to_buf = &usb_remote_poll; +#ifdef LIRC_HAVE_SYSFS + plugin->dev = &dev->dev; +#endif + plugin->owner = THIS_MODULE; + + init_MUTEX(&ir->lock); + init_waitqueue_head(&ir->wait_out); + + minor = lirc_register_plugin(plugin); + if (minor < 0) + mem_failure = 9; + +mem_failure_switch: + + /* free allocated memory in case of failure */ + switch (mem_failure) { + case 9: +#if defined(KERNEL_2_5) + usb_buffer_free(dev, DEVICE_BUFLEN+DEVICE_HEADERLEN, + ir->buf_in, ir->dma_in); +#else + kfree(ir->buf_in); +#endif + case 5: + lirc_buffer_free(rbuf); + case 4: + kfree(rbuf); + case 3: + kfree(plugin); + case 2: + kfree(ir); + case 1: + printk(DRIVER_NAME "[%d]: out of memory (code=%d)\n", + devnum, mem_failure); +#if defined(KERNEL_2_5) + return -ENOMEM; +#else + return NULL; +#endif + } + + plugin->minor = minor; + ir->p = plugin; + ir->devnum = devnum; + ir->usbdev = dev; + ir->len_in = DEVICE_BUFLEN+DEVICE_HEADERLEN; + ir->in_space = 1; /* First mode2 event is a space. */ + do_gettimeofday(&ir->last_time); + + if (dev->descriptor.iManufacturer + && usb_string(dev, dev->descriptor.iManufacturer, buf, 63) > 0) + strncpy(name, buf, 128); + if (dev->descriptor.iProduct + && usb_string(dev, dev->descriptor.iProduct, buf, 63) > 0) + snprintf(name, 128, "%s %s", name, buf); + printk(DRIVER_NAME "[%d]: %s on usb%d:%d\n", devnum, name, + dev->bus->busnum, devnum); + + /* clear device buffer */ + ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), + SET_INFRABUFFER_EMPTY, USB_TYPE_VENDOR|USB_DIR_IN, + /*unused*/0, /*unused*/0, + /*dummy*/ir->buf_in, /*dummy*/ir->len_in, + /*timeout*/HZ * USB_CTRL_GET_TIMEOUT); + if (ret < 0) + printk(DRIVER_NAME "[%d]: SET_INFRABUFFER_EMPTY: error %d\n", + devnum, ret); + +#if defined(KERNEL_2_5) + usb_set_intfdata(intf, ir); + return SUCCESS; +#else + return ir; +#endif +} + + +#if defined(KERNEL_2_5) +static void usb_remote_disconnect(struct usb_interface *intf) +{ + struct usb_device *dev = interface_to_usbdev(intf); + struct irctl *ir = usb_get_intfdata(intf); + usb_set_intfdata(intf, NULL); +#else +static void usb_remote_disconnect(struct usb_device *dev, void *ptr) +{ + struct irctl *ir = ptr; +#endif + + if (!ir || !ir->p) + return; + + ir->usbdev = NULL; + wake_up_all(&ir->wait_out); + + IRLOCK; +#if defined(KERNEL_2_5) + usb_buffer_free(dev, ir->len_in, ir->buf_in, ir->dma_in); +#else + kfree(ir->buf_in); +#endif + IRUNLOCK; + + unregister_from_lirc(ir); +} + +static struct usb_device_id usb_remote_id_table [] = { + /* Igor Plug USB (Atmel's Manufact. ID) */ + { USB_DEVICE(0x03eb, 0x0002) }, + + /* Terminating entry */ + { } +}; + +static struct usb_driver usb_remote_driver = { + LIRC_THIS_MODULE(.owner = THIS_MODULE) + .name = DRIVER_NAME, + .probe = usb_remote_probe, + .disconnect = usb_remote_disconnect, + .id_table = usb_remote_id_table +}; + +static int __init usb_remote_init(void) +{ + int i; + + printk(KERN_INFO "\n" + DRIVER_NAME ": " DRIVER_DESC " v" DRIVER_VERSION "\n"); + printk(DRIVER_NAME ": " DRIVER_AUTHOR "\n"); + dprintk(DRIVER_NAME ": debug mode enabled\n"); + + request_module("lirc_dev"); + + i = usb_register(&usb_remote_driver); + if (i < 0) { + printk(DRIVER_NAME ": usb register failed, result = %d\n", i); + return -ENODEV; + } + + return SUCCESS; +} + +static void __exit usb_remote_exit(void) +{ + usb_deregister(&usb_remote_driver); +} + +module_init(usb_remote_init); +module_exit(usb_remote_exit); + +#if defined(KERNEL_2_5) +#include +MODULE_INFO(vermagic, VERMAGIC_STRING); +#endif + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(usb, usb_remote_id_table); + +module_param(sample_rate, int, 0644); +MODULE_PARM_DESC(sample_rate, "Sampling rate in Hz (default: 100)"); + +EXPORT_NO_SYMBOLS; + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_i2c/lirc_i2c.c +++ linux-2.6.28/ubuntu/lirc/lirc_i2c/lirc_i2c.c @@ -0,0 +1,681 @@ +/* $Id: lirc_i2c.c,v 1.46 2008/05/04 13:49:53 lirc Exp $ */ + +/* + * i2c IR lirc plugin for Hauppauge and Pixelview cards - new 2.3.x i2c stack + * + * Copyright (c) 2000 Gerd Knorr + * modified for PixelView (BT878P+W/FM) by + * Michal Kochanowicz + * Christoph Bartelmus + * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by + * Ulrich Mueller + * modified for Asus TV-Box and Creative/VisionTek BreakOut-Box by + * Stefan Jahn + * modified for inclusion into kernel sources by + * Jerome Brock + * modified for Leadtek Winfast PVR2000 by + * Thomas Reitmayr (treitmayr@yahoo.com) + * modified for Hauppauge HVR-1300 by + * Jan Frey (jfrey@gmx.de) + * + * parts are cut&pasted from the old lirc_haup.c driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "kcompat.h" +#include "lirc_dev/lirc_dev.h" + +struct IR { + struct lirc_plugin l; + struct i2c_client c; + int nextkey; + unsigned char b[3]; + unsigned char bits; + unsigned char flag; +}; + +/* ----------------------------------------------------------------------- */ + +#define DEVICE_NAME "lirc_i2c" + +/* ----------------------------------------------------------------------- */ +/* insmod parameters */ + +static int debug; /* debug output */ +static int minor = -1; /* minor number */ + +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG DEVICE_NAME ": " fmt, \ + ## args); \ + } while (0) + +/* ----------------------------------------------------------------------- */ + +static inline int reverse(int data, int bits) +{ + int i; + int c; + + for (c = 0, i = 0; i < bits; i++) + c |= (((data & (1<c, keybuf, 1); + /* poll IR chip */ + if (i2c_master_recv(&ir->c, keybuf, sizeof(keybuf)) != sizeof(keybuf)) { + dprintk("read error\n"); + return -EIO; + } + + dprintk("key (0x%02x%02x%02x%02x)\n", + keybuf[0], keybuf[1], keybuf[2], keybuf[3]); + + /* key pressed ? */ + if (keybuf[2] == 0xff) + return -ENODATA; + + /* remove repeat bit */ + keybuf[2] &= 0x7f; + keybuf[3] |= 0x80; + + lirc_buffer_write_1(buf, keybuf); + return 0; +} + +static int add_to_buf_pcf8574(void *data, struct lirc_buffer *buf) +{ + struct IR *ir = data; + int rc; + unsigned char all, mask; + unsigned char key; + + /* compute all valid bits (key code + pressed/release flag) */ + all = ir->bits | ir->flag; + + /* save IR writable mask bits */ + mask = i2c_smbus_read_byte(&ir->c) & ~all; + + /* send bit mask */ + rc = i2c_smbus_write_byte(&ir->c, (0xff & all) | mask); + + /* receive scan code */ + rc = i2c_smbus_read_byte(&ir->c); + + if (rc == -1) { + dprintk("%s read error\n", ir->c.name); + return -EIO; + } + + /* drop duplicate polls */ + if (ir->b[0] == (rc & all)) + return -ENODATA; + + ir->b[0] = rc & all; + + dprintk("%s key 0x%02X %s\n", ir->c.name, rc & ir->bits, + (rc & ir->flag) ? "released" : "pressed"); + + if (rc & ir->flag) { + /* ignore released buttons */ + return -ENODATA; + } + + /* set valid key code */ + key = rc & ir->bits; + lirc_buffer_write_1(buf, &key); + return 0; +} + +/* common for Hauppauge IR receivers */ +static int add_to_buf_haup_common(void *data, struct lirc_buffer *buf, + unsigned char *keybuf, int size, int offset) +{ + struct IR *ir = data; + __u16 code; + unsigned char codes[2]; + + /* poll IR chip */ + if (size == i2c_master_recv(&ir->c, keybuf, size)) { + ir->b[0] = keybuf[offset]; + ir->b[1] = keybuf[offset+1]; + ir->b[2] = keybuf[offset+2]; + dprintk("key (0x%02x/0x%02x)\n", ir->b[0], ir->b[1]); + } else { + dprintk("read error\n"); + /* keep last successfull read buffer */ + } + + /* key pressed ? */ + if ((ir->b[0] & 0x80) == 0) + return -ENODATA; + + /* look what we have */ + code = (((__u16)ir->b[0]&0x7f)<<6) | (ir->b[1]>>2); + + codes[0] = (code >> 8) & 0xff; + codes[1] = code & 0xff; + + /* return it */ + lirc_buffer_write_1(buf, codes); + return 0; +} + +/* specific for the Hauppauge PVR150 IR receiver */ +static int add_to_buf_haup_pvr150(void *data, struct lirc_buffer *buf) +{ + unsigned char keybuf[6]; + /* fetch 6 bytes, first relevant is at offset 3 */ + return add_to_buf_haup_common(data, buf, keybuf, 6, 3); +} + +/* used for all Hauppauge IR receivers but the PVR150 */ +static int add_to_buf_haup(void *data, struct lirc_buffer *buf) +{ + unsigned char keybuf[3]; + /* fetch 3 bytes, first relevant is at offset 0 */ + return add_to_buf_haup_common(data, buf, keybuf, 3, 0); +} + + +static int add_to_buf_pvr2000(void *data, struct lirc_buffer *buf) +{ + struct IR *ir = data; + unsigned char key; + s32 flags; + s32 code; + + /* poll IR chip */ + flags = i2c_smbus_read_byte_data(&ir->c, 0x10); + if (-1 == flags) { + dprintk("read error\n"); + return -ENODATA; + } + /* key pressed ? */ + if (0 == (flags & 0x80)) + return -ENODATA; + + /* read actual key code */ + code = i2c_smbus_read_byte_data(&ir->c, 0x00); + if (-1 == code) { + dprintk("read error\n"); + return -ENODATA; + } + + key = code & 0xFF; + + dprintk("IR Key/Flags: (0x%02x/0x%02x)\n", key, flags & 0xFF); + + /* return it */ + lirc_buffer_write_1(buf, &key); + return 0; +} + +static int add_to_buf_pixelview(void *data, struct lirc_buffer *buf) +{ + struct IR *ir = data; + unsigned char key; + + /* poll IR chip */ + if (1 != i2c_master_recv(&ir->c, &key, 1)) { + dprintk("read error\n"); + return -1; + } + dprintk("key %02x\n", key); + + /* return it */ + lirc_buffer_write_1(buf, &key); + return 0; +} + +static int add_to_buf_pv951(void *data, struct lirc_buffer *buf) +{ + struct IR *ir = data; + unsigned char key; + unsigned char codes[4]; + + /* poll IR chip */ + if (1 != i2c_master_recv(&ir->c, &key, 1)) { + dprintk("read error\n"); + return -ENODATA; + } + /* ignore 0xaa */ + if (key == 0xaa) + return -ENODATA; + dprintk("key %02x\n", key); + + codes[0] = 0x61; + codes[1] = 0xD6; + codes[2] = reverse(key, 8); + codes[3] = (~codes[2])&0xff; + + lirc_buffer_write_1(buf, codes); + return 0; +} + +static int add_to_buf_knc1(void *data, struct lirc_buffer *buf) +{ + static unsigned char last_key = 0xFF; + struct IR *ir = data; + unsigned char key; + + /* poll IR chip */ + if (1 != i2c_master_recv(&ir->c, &key, 1)) { + dprintk("read error\n"); + return -ENODATA; + } + + /* it seems that 0xFE indicates that a button is still hold + down, while 0xFF indicates that no button is hold + down. 0xFE sequences are sometimes interrupted by 0xFF */ + + dprintk("key %02x\n", key); + + if (key == 0xFF) + return -ENODATA; + + if (key == 0xFE) + key = last_key; + + last_key = key; + lirc_buffer_write_1(buf, &key); + + return 0; +} + +static int set_use_inc(void *data) +{ + struct IR *ir = data; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) + i2c_use_client(&ir->c); +#else + int ret; + + /* lock bttv in memory while /dev/lirc is in use */ + ret = i2c_use_client(&ir->c); + if (ret != 0) + return ret; +#endif + + MOD_INC_USE_COUNT; + return 0; +} + +static void set_use_dec(void *data) +{ + struct IR *ir = data; + + i2c_release_client(&ir->c); + MOD_DEC_USE_COUNT; +} + +static struct lirc_plugin lirc_template = { + .name = "lirc_i2c", + .set_use_inc = set_use_inc, + .set_use_dec = set_use_dec, + .dev = NULL, + .owner = THIS_MODULE, +}; + +/* ----------------------------------------------------------------------- */ + +static int ir_attach(struct i2c_adapter *adap, int addr, + unsigned short flags, int kind); +static int ir_detach(struct i2c_client *client); +static int ir_probe(struct i2c_adapter *adap); +static int ir_command(struct i2c_client *client, unsigned int cmd, void *arg); + +static struct i2c_driver driver = { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) + .name = "i2c ir driver", + .flags = I2C_DF_NOTIFY, +#else + .driver = { + .owner = THIS_MODULE, + .name = "i2c ir driver", + }, +#endif + .id = I2C_DRIVERID_EXP3, /* FIXME */ + .attach_adapter = ir_probe, + .detach_client = ir_detach, + .command = ir_command, +}; + +static struct i2c_client client_template = { + .name = "unset", + .driver = &driver +}; + +static int ir_attach(struct i2c_adapter *adap, int addr, + unsigned short flags, int kind) +{ + struct IR *ir; + int err; + + client_template.adapter = adap; + client_template.addr = addr; + + ir = kmalloc(sizeof(struct IR), GFP_KERNEL); + if (!ir) + return -ENOMEM; + memcpy(&ir->l, &lirc_template, sizeof(struct lirc_plugin)); + memcpy(&ir->c, &client_template, sizeof(struct i2c_client)); + + ir->c.adapter = adap; + ir->c.addr = addr; + i2c_set_clientdata(&ir->c, ir); + ir->l.data = ir; + ir->l.minor = minor; + ir->l.sample_rate = 10; + ir->nextkey = -1; + + switch (addr) { + case 0x64: + strlcpy(ir->c.name, "Pixelview IR", I2C_NAME_SIZE); + ir->l.code_length = 8; + ir->l.add_to_buf = add_to_buf_pixelview; + break; + case 0x4b: + strlcpy(ir->c.name, "PV951 IR", I2C_NAME_SIZE); + ir->l.code_length = 32; + ir->l.add_to_buf = add_to_buf_pv951; + break; + case 0x71: +#ifdef I2C_HW_B_CX2341X + if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848) || + adap->id == (I2C_ALGO_BIT | I2C_HW_B_CX2341X)) { +#else + if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) { +#endif + /* The PVR150 IR receiver uses the same protocol as + * other Hauppauge cards, but the data flow is + * different, so we need to deal with it by its own. */ + strlcpy(ir->c.name, "Hauppauge PVR150", I2C_NAME_SIZE); + } else /* I2C_HW_B_CX2388x */ + strlcpy(ir->c.name, "Hauppauge HVR1300", I2C_NAME_SIZE); + ir->l.code_length = 13; + ir->l.add_to_buf = add_to_buf_haup_pvr150; + break; + case 0x6b: + strlcpy(ir->c.name, "Adaptec IR", I2C_NAME_SIZE); + ir->l.code_length = 32; + ir->l.add_to_buf = add_to_buf_adap; + break; + case 0x18: + case 0x1a: +#ifdef I2C_HW_B_CX2341X + if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848) || + adap->id == (I2C_ALGO_BIT | I2C_HW_B_CX2341X)) { +#else + if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) { +#endif + strlcpy(ir->c.name, "Hauppauge IR", I2C_NAME_SIZE); + ir->l.code_length = 13; + ir->l.add_to_buf = add_to_buf_haup; + } else { /* I2C_HW_B_CX2388x */ + strlcpy(ir->c.name, "Leadtek IR", I2C_NAME_SIZE); + ir->l.code_length = 8; + ir->l.add_to_buf = add_to_buf_pvr2000; + } + break; + case 0x30: + strlcpy(ir->c.name, "KNC ONE IR", I2C_NAME_SIZE); + ir->l.code_length = 8; + ir->l.add_to_buf = add_to_buf_knc1; + break; + case 0x21: + case 0x23: + strlcpy(ir->c.name, "TV-Box IR", I2C_NAME_SIZE); + ir->l.code_length = 8; + ir->l.add_to_buf = add_to_buf_pcf8574; + ir->bits = flags & 0xff; + ir->flag = (flags >> 8) & 0xff; + break; + default: + /* shouldn't happen */ + printk("lirc_i2c: Huh? unknown i2c address (0x%02x)?\n", addr); + kfree(ir); + return -1; + } + printk(KERN_INFO "lirc_i2c: chip 0x%x found @ 0x%02x (%s)\n", + adap->id, addr, ir->c.name); + + /* register device */ + err = i2c_attach_client(&ir->c); + if (err) { + kfree(ir); + return err; + } + ir->l.minor = lirc_register_plugin(&ir->l); + + return 0; +} + +static int ir_detach(struct i2c_client *client) +{ + struct IR *ir = i2c_get_clientdata(client); + + /* unregister device */ + lirc_unregister_plugin(ir->l.minor); + i2c_detach_client(&ir->c); + + /* free memory */ + kfree(ir); + return 0; +} + +static int ir_probe(struct i2c_adapter *adap) +{ + /* The external IR receiver is at i2c address 0x34 (0x35 for + * reads). Future Hauppauge cards will have an internal + * receiver at 0x30 (0x31 for reads). In theory, both can be + * fitted, and Hauppauge suggest an external overrides an + * internal. + * + * That's why we probe 0x1a (~0x34) first. CB + * + * The i2c address for the Hauppauge PVR-150 card is 0xe2, + * so we need to probe 0x71 as well. */ + + static const int probe[] = { + 0x1a, /* Hauppauge IR external */ + 0x18, /* Hauppauge IR internal */ + 0x71, /* Hauppauge IR (PVR150) */ + 0x4b, /* PV951 IR */ + 0x64, /* Pixelview IR */ + 0x30, /* KNC ONE IR */ + 0x6b, /* Adaptec IR */ + -1}; + +#ifdef I2C_HW_B_CX2388x + static const int probe_cx88[] = { + 0x18, /* Leadtek Winfast PVR2000 */ + 0x71, /* Hauppauge HVR-IR */ + -1}; +#endif + + struct i2c_client c; + char buf; + int i, rc; + +#ifdef I2C_HW_B_CX2341X + if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848) || + adap->id == (I2C_ALGO_BIT | I2C_HW_B_CX2341X)) +#else + if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) +#endif + { + memset(&c, 0, sizeof(c)); + c.adapter = adap; + for (i = 0; -1 != probe[i]; i++) { + c.addr = probe[i]; + rc = i2c_master_recv(&c, &buf, 1); + dprintk("probe 0x%02x @ %s: %s\n", + probe[i], adap->name, + (1 == rc) ? "yes" : "no"); + if (1 == rc) + ir_attach(adap, probe[i], 0, 0); + } + } + +#ifdef I2C_HW_B_CX2388x + /* Leadtek Winfast PVR2000 or Hauppauge HVR-1300 */ + else if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_CX2388x)) { + memset(&c, 0, sizeof(c)); + c.adapter = adap; + for (i = 0; -1 != probe_cx88[i]; i++) { + c.addr = probe_cx88[i]; + rc = i2c_master_recv(&c, &buf, 1); + dprintk("probe 0x%02x @ %s: %s\n", + c.addr, adap->name, + (1 == rc) ? "yes" : "no"); + if (1 == rc) + ir_attach(adap, c.addr, 0, 0); + } + } +#endif + + /* Asus TV-Box and Creative/VisionTek BreakOut-Box (PCF8574) */ + else if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_RIVA)) { + /* addresses to probe; + leave 0x24 and 0x25 because SAA7113H possibly uses it + 0x21 and 0x22 possibly used by SAA7108E + Asus: 0x21 is a correct address (channel 1 of PCF8574) + Creative: 0x23 is a correct address (channel 3 of PCF8574) + VisionTek: 0x23 is a correct address (channel 3 of PCF8574) + */ + static const int pcf_probe[] = { 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, -1 }; + int ret1, ret2, ret3, ret4; + unsigned char bits = 0, flag = 0; + + memset(&c, 0, sizeof(c)); + c.adapter = adap; + for (i = 0; -1 != pcf_probe[i]; i++) { + c.addr = pcf_probe[i]; + ret1 = i2c_smbus_write_byte(&c, 0xff); + ret2 = i2c_smbus_read_byte(&c); + ret3 = i2c_smbus_write_byte(&c, 0x00); + ret4 = i2c_smbus_read_byte(&c); + + /* ensure that the writable bitmask works correctly */ + rc = 0; + if (ret1 != -1 && ret2 != -1 && + ret3 != -1 && ret4 != -1) { + /* in the Asus TV-Box: bit 1-0 */ + if (((ret2 & 0x03) == 0x03) && + ((ret4 & 0x03) == 0x00)) { + bits = (unsigned char) ~0x07; + flag = 0x04; + rc = 1; + } + /* in the Creative/VisionTek BreakOut-Box: bit 7-6 */ + if (((ret2 & 0xc0) == 0xc0) && + ((ret4 & 0xc0) == 0x00)) { + bits = (unsigned char) ~0xe0; + flag = 0x20; + rc = 1; + } + } + dprintk("probe 0x%02x @ %s: %s\n", + c.addr, adap->name, rc ? "yes" : "no"); + if (rc) + ir_attach(adap, pcf_probe[i], + bits|(flag<<8), 0); + } + } + + return 0; +} + +static int ir_command(struct i2c_client *client, unsigned int cmd, void *arg) +{ + /* nothing */ + return 0; +} + +/* ----------------------------------------------------------------------- */ +#ifdef MODULE + +int init_module(void) +{ + request_module("bttv"); + request_module("rivatv"); + request_module("ivtv"); + request_module("cx8800"); + i2c_add_driver(&driver); + return 0; +} + +void cleanup_module(void) +{ + i2c_del_driver(&driver); +} + +MODULE_DESCRIPTION("Infrared receiver driver for Hauppauge and " + "Pixelview cards (i2c stack)"); +MODULE_AUTHOR("Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, " + "Ulrich Mueller, Stefan Jahn, Jerome Brock"); +MODULE_LICENSE("GPL"); + +module_param(minor, int, 0444); +MODULE_PARM_DESC(minor, "Preferred minor device number"); + +module_param(debug, bool, 0644); +MODULE_PARM_DESC(debug, "Enable debugging messages"); + +EXPORT_NO_SYMBOLS; + +#endif /* MODULE */ + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_i2c/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_i2c/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_I2C) += lirc_i2c.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_mceusb/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_mceusb/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_MCEUSB) += lirc_mceusb.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_mceusb/lirc_mceusb.c +++ linux-2.6.28/ubuntu/lirc/lirc_mceusb/lirc_mceusb.c @@ -0,0 +1,1000 @@ +/* + * USB Microsoft IR Transceiver driver - 0.2 + * + * Copyright (c) 2003-2004 Dan Conti (dconti@acm.wwu.edu) + * + * This driver is based on the USB skeleton driver packaged with the + * kernel, and the notice from that package has been retained below. + * + * The Microsoft IR Transceiver is a neat little IR receiver with two + * emitters on it designed for Windows Media Center. This driver might + * work for all media center remotes, but I have only tested it with + * the philips model. The first revision of this driver only supports + * the receive function - the transmit function will be much more + * tricky due to the nature of the hardware. Microsoft chose to build + * this device inexpensively, therefore making it extra dumb. + * There is no interrupt endpoint on this device; all usb traffic + * happens over two bulk endpoints. As a result of this, poll() for + * this device is an actual hardware poll (instead of a receive queue + * check) and is rather expensive. + * + * All trademarks property of their respective owners. This driver was + * originally based on the USB skeleton driver, although significant + * portions of that code have been removed as the driver has evolved. + * + * 2003_11_11 - Restructured to minimalize code interpretation in the + * driver. The normal use case will be with lirc. + * + * 2004_01_01 - Removed all code interpretation. Generate mode2 data + * for passing off to lirc. Cleanup + * + * 2004_01_04 - Removed devfs handle. Put in a temporary workaround + * for a known issue where repeats generate two + * sequential spaces (last_was_repeat_gap) + * + * 2004_02_17 - Changed top level api to no longer use fops, and + * instead use new interface for polling via + * lirc_thread. Restructure data read/mode2 generation to + * a single pass, reducing number of buffers. Rev to .2 + * + * 2004_02_27 - Last of fixups to plugin->add_to_buf API. Properly + * handle broken fragments from the receiver. Up the + * sample rate and remove any pacing from + * fetch_more_data. Fixes all known issues. + * + * TODO + * - Fix up minor number, registration of major/minor with usb subsystem + * + */ +/* + * USB Skeleton driver - 1.1 + * + * Copyright (C) 2001-2003 Greg Kroah-Hartman (greg@kroah.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2. + * + * + * This driver is to be used as a skeleton driver to be able to create a + * USB driver quickly. The design of it is based on the usb-serial and + * dc2xx drivers. + * + * Thanks to Oliver Neukum, David Brownell, and Alan Stern for their help + * in debugging this driver. + * + * + * History: + * + * 2003-05-06 - 1.1 - changes due to usb core changes with usb_register_dev() + * 2003-02-25 - 1.0 - fix races involving urb->status, unlink_urb(), and + * disconnect. Fix transfer amount in read(). Use + * macros instead of magic numbers in probe(). Change + * size variables to size_t. Show how to eliminate + * DMA bounce buffer. + * 2002_12_12 - 0.9 - compile fixes and got rid of fixed minor array. + * 2002_09_26 - 0.8 - changes due to USB core conversion to struct device + * driver. + * 2002_02_12 - 0.7 - zero out dev in probe function for devices that do + * not have both a bulk in and bulk out endpoint. + * Thanks to Holger Waechtler for the fix. + * 2001_11_05 - 0.6 - fix minor locking problem in skel_disconnect. + * Thanks to Pete Zaitcev for the fix. + * 2001_09_04 - 0.5 - fix devfs bug in skel_disconnect. Thanks to wim delvaux + * 2001_08_21 - 0.4 - more small bug fixes. + * 2001_05_29 - 0.3 - more bug fixes based on review from linux-usb-devel + * 2001_05_24 - 0.2 - bug fixes based on review from linux-usb-devel people + * 2001_05_01 - 0.1 - first version + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef KERNEL_2_5 +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +#include +#else +#include +#endif +#else +#include +#include +#include +#include +#include +#include +#endif + +#ifdef CONFIG_USB_DEBUG +static int debug = 1; +#else +static int debug; +#endif + +#include "kcompat.h" +#include "lirc.h" +#include "lirc_dev/lirc_dev.h" + +/* Use our own dbg macro */ +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG __FILE__ ": " \ + fmt "\n", ## args); \ + } while (0) + +/* Version Information */ +#define DRIVER_VERSION "v0.2" +#define DRIVER_AUTHOR "Dan Conti, dconti@acm.wwu.edu" +#define DRIVER_DESC "USB Microsoft IR Transceiver Driver" +#define DRIVER_NAME "lirc_mceusb" + +/* Define these values to match your device */ +#define USB_MCEUSB_VENDOR_ID 0x045e +#define USB_MCEUSB_PRODUCT_ID 0x006d + +/* table of devices that work with this driver */ +static struct usb_device_id mceusb_table[] = { + { USB_DEVICE(USB_MCEUSB_VENDOR_ID, USB_MCEUSB_PRODUCT_ID) }, + { } /* Terminating entry */ +}; + +/* we can have up to this number of device plugged in at once */ +#define MAX_DEVICES 16 + +/* Structure to hold all of our device specific stuff */ +struct usb_skel { + struct usb_device *udev; /* save off the usb device pointer */ + struct usb_interface *interface; /* the interface for this device */ + unsigned char minor; /* the starting minor number for this device */ + unsigned char num_ports; /* the number of ports this device has */ + char num_interrupt_in; /* number of interrupt in endpoints */ + char num_bulk_in; /* number of bulk in endpoints */ + char num_bulk_out; /* number of bulk out endpoints */ + + unsigned char *bulk_in_buffer; /* the buffer to receive data */ + int bulk_in_size; /* the size of the receive buffer */ + __u8 bulk_in_endpointAddr; /* the address of bulk in endpoint */ + + unsigned char *bulk_out_buffer; /* the buffer to send data */ + int bulk_out_size; /* the size of the send buffer */ + struct urb *write_urb; /* the urb used to send data */ + __u8 bulk_out_endpointAddr; /* the address of bulk out endpoint */ + + atomic_t write_busy; /* true iff write urb is busy */ + struct completion write_finished; /* wait for the write to finish */ + + wait_queue_head_t wait_q; /* for timeouts */ + int open_count; /* number of times this port has been opened */ + struct semaphore sem; /* locks this structure */ + + int present; /* if the device is not disconnected */ + + struct lirc_plugin *plugin; + + lirc_t lircdata[256]; /* place to store data until lirc processes it */ + int lircidx; /* current index */ + int lirccnt; /* remaining values */ + + int usb_valid_bytes_in_bulk_buffer; /* leftover data from prior read */ + int mce_bytes_left_in_packet; /* for packets split across reads */ + + /* Value to hold the last received space; 0 if last value + * received was a pulse */ + int last_space; + +#ifdef KERNEL_2_5 + dma_addr_t dma_in; + dma_addr_t dma_out; +#endif +}; + +#define MCE_TIME_UNIT 50 + +/* driver api */ +#ifdef KERNEL_2_5 +static int mceusb_probe(struct usb_interface *interface, + const struct usb_device_id *id); +static void mceusb_disconnect(struct usb_interface *interface); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void mceusb_write_bulk_callback(struct urb *urb, struct pt_regs *regs); +#else +static void mceusb_write_bulk_callback(struct urb *urb); +#endif +#else +static void *mceusb_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id); +static void mceusb_disconnect(struct usb_device *dev, void *ptr); +static void mceusb_write_bulk_callback(struct urb *urb); +#endif + +/* read data from the usb bus; convert to mode2 */ +static int msir_fetch_more_data(struct usb_skel *dev, int dont_block); + +/* helper functions */ +static void msir_cleanup(struct usb_skel *dev); +static void set_use_dec(void *data); +static int set_use_inc(void *data); + +/* array of pointers to our devices that are currently connected */ +static struct usb_skel *minor_table[MAX_DEVICES]; + +/* lock to protect the minor_table structure */ +static DECLARE_MUTEX(minor_table_mutex); +static void mceusb_setup(struct usb_device *udev); + +/* usb specific object needed to register this driver with the usb subsystem */ +static struct usb_driver mceusb_driver = { + LIRC_THIS_MODULE(.owner = THIS_MODULE) + .name = DRIVER_NAME, + .probe = mceusb_probe, + .disconnect = mceusb_disconnect, + .id_table = mceusb_table, +}; + + +/** + * usb_mceusb_debug_data + */ +static inline void usb_mceusb_debug_data(const char *function, int size, + const unsigned char *data) +{ + int i; + if (!debug) + return; + + printk(KERN_DEBUG __FILE__": %s - length = %d, data = ", + function, size); + for (i = 0; i < size; ++i) + printk(KERN_DEBUG "%.2x ", data[i]); + printk(KERN_DEBUG "\n"); +} + +/** + *mceusb_delete + */ +static inline void mceusb_delete(struct usb_skel *dev) +{ + dprintk("%s", __func__); + minor_table[dev->minor] = NULL; +#ifdef KERNEL_2_5 + usb_buffer_free(dev->udev, dev->bulk_in_size, + dev->bulk_in_buffer, dev->dma_in); + usb_buffer_free(dev->udev, dev->bulk_out_size, + dev->bulk_out_buffer, dev->dma_out); +#else + if (dev->bulk_in_buffer != NULL) + kfree(dev->bulk_in_buffer); + if (dev->bulk_out_buffer != NULL) + kfree(dev->bulk_out_buffer); +#endif + if (dev->write_urb != NULL) + usb_free_urb(dev->write_urb); + kfree(dev); +} + +static void mceusb_setup(struct usb_device *udev) +{ + char data[8]; + int res; + + memset(data, 0, 8); + + /* Get Status */ + res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + USB_REQ_GET_STATUS, USB_DIR_IN, + 0, 0, data, 2, HZ * 3); + + /* res = usb_get_status( udev, 0, 0, data ); */ + dprintk("%s - res = %d status = 0x%x 0x%x", __func__, + res, data[0], data[1]); + + /* This is a strange one. They issue a set address to the device + * on the receive control pipe and expect a certain value pair back + */ + memset(data, 0, 8); + + res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + 5, USB_TYPE_VENDOR, 0, 0, + data, 2, HZ * 3); + dprintk("%s - res = %d, devnum = %d", __func__, res, udev->devnum); + dprintk("%s - data[0] = %d, data[1] = %d", __func__, + data[0], data[1]); + + + /* set feature */ + res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + USB_REQ_SET_FEATURE, USB_TYPE_VENDOR, + 0xc04e, 0x0000, NULL, 0, HZ * 3); + + dprintk("%s - res = %d", __func__, res); + + /* These two are sent by the windows driver, but stall for + * me. I dont have an analyzer on the linux side so i can't + * see what is actually different and why the device takes + * issue with them + */ +#if 0 + /* this is some custom control message they send */ + res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + 0x04, USB_TYPE_VENDOR, + 0x0808, 0x0000, NULL, 0, HZ * 3); + + dprintk("%s - res = %d", __func__, res); + + /* this is another custom control message they send */ + res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + 0x02, USB_TYPE_VENDOR, + 0x0000, 0x0100, NULL, 0, HZ * 3); + + dprintk("%s - res = %d", __func__, res); +#endif +} + +static void msir_cleanup(struct usb_skel *dev) +{ + memset(dev->bulk_in_buffer, 0, dev->bulk_in_size); + + dev->usb_valid_bytes_in_bulk_buffer = 0; + + dev->last_space = PULSE_MASK; + + dev->mce_bytes_left_in_packet = 0; + dev->lircidx = 0; + dev->lirccnt = 0; + memset(dev->lircdata, 0, sizeof(dev->lircdata)); +} + +static int set_use_inc(void *data) +{ + MOD_INC_USE_COUNT; + return 0; +} + +static void set_use_dec(void *data) +{ + MOD_DEC_USE_COUNT; +} + +/* + * msir_fetch_more_data + * + * The goal here is to read in more remote codes from the remote. In + * the event that the remote isn't sending us anything, the caller + * will block until a key is pressed (i.e. this performs phys read, + * filtering, and queueing of data) unless dont_block is set to 1; in + * this situation, it will perform a few reads and will exit out if it + * does not see any appropriate data + * + * dev->sem should be locked when this function is called - fine grain + * locking isn't really important here anyways + * + * This routine always returns the number of words available + * + */ +static int msir_fetch_more_data(struct usb_skel *dev, int dont_block) +{ + int retries = 0; + int words_to_read = + (sizeof(dev->lircdata)/sizeof(lirc_t)) - dev->lirccnt; + int partial, this_read = 0; + int bulkidx = 0; + int bytes_left_in_packet = 0; + signed char *signedp = (signed char*)dev->bulk_in_buffer; + + if (words_to_read == 0) + return dev->lirccnt; + + /* this forces all existing data to be read by lirc before we + * issue another usb command. this is the only form of + * throttling we have + */ + if (dev->lirccnt) + return dev->lirccnt; + + /* reserve room for our leading space */ + if (dev->last_space) + words_to_read--; + + while (words_to_read) { + /* handle signals and USB disconnects */ + if (signal_pending(current)) + return dev->lirccnt ? dev->lirccnt : -EINTR; + if (!dev->udev) + return -ENODEV; + + bulkidx = 0; + + /* + * perform data read (phys or from previous buffer) + */ + + /* use leftovers if present, otherwise perform a read */ + if (dev->usb_valid_bytes_in_bulk_buffer) { + this_read = dev->usb_valid_bytes_in_bulk_buffer; + partial = this_read; + dev->usb_valid_bytes_in_bulk_buffer = 0; + } else { + int retval; + + this_read = dev->bulk_in_size; + partial = 0; + retval = usb_bulk_msg(dev->udev, + usb_rcvbulkpipe(dev->udev, + dev->bulk_in_endpointAddr), + (unsigned char *)dev->bulk_in_buffer, + this_read, &partial, HZ*10); + + /* retry a few times on overruns; map all + other errors to -EIO */ + if (retval) { + if (retval == -EOVERFLOW && retries < 5) { + retries++; + interruptible_sleep_on_timeout( + &dev->wait_q, HZ); + continue; + } else + return -EIO; + } + + retries = 0; + if (partial) + this_read = partial; + + /* skip the header */ + bulkidx += 2; + + /* check for empty reads (header only) */ + if (this_read == 2) { + /* assume no data */ + if (dont_block) + break; + + /* sleep for a bit before performing + another read */ + interruptible_sleep_on_timeout(&dev->wait_q, 1); + continue; + } + } + + /* + * process data + */ + + /* at this point this_read is > 0 */ + while (bulkidx < this_read && + (words_to_read > (dev->last_space ? 1 : 0))) { + /* while( bulkidx < this_read && words_to_read) */ + int keycode; + int pulse = 0; + + /* read packet length if needed */ + if (!bytes_left_in_packet) { + /* we assume we are on a packet length + * value. it is possible, in some + * cases, to get a packet that does + * not start with a length, apparently + * due to some sort of fragmenting, + * but occaisonally we do not receive + * the second half of a fragment + */ + bytes_left_in_packet = + 128 + signedp[bulkidx++]; + + /* unfortunately rather than keep all + * the data in the packetized format, + * the transceiver sends a trailing 8 + * bytes that aren't part of the + * transmittion from the remote, + * aren't packetized, and dont really + * have any value. we can basically + * tell we have hit them if 1) we have + * a loooong space currently stored + * up, and 2) the bytes_left value for + * this packet is obviously wrong + */ + if (bytes_left_in_packet > 4) { + if (dev->mce_bytes_left_in_packet) { + bytes_left_in_packet = + dev->mce_bytes_left_in_packet; + bulkidx--; + } + bytes_left_in_packet = 0; + bulkidx = this_read; + } + + /* always clear this if we have a + valid packet */ + dev->mce_bytes_left_in_packet = 0; + + /* continue here to verify we haven't + hit the end of the bulk_in */ + continue; + + } + + /* + * generate mode2 + */ + + keycode = signedp[bulkidx++]; + if (keycode < 0) { + pulse = 1; + keycode += 128; + } + keycode *= MCE_TIME_UNIT; + + bytes_left_in_packet--; + + if (pulse) { + if (dev->last_space) { + dev->lircdata[dev->lirccnt++] = + dev->last_space; + dev->last_space = 0; + words_to_read--; + + /* clear the lirc_t for the pulse */ + dev->lircdata[dev->lirccnt] = 0; + } + dev->lircdata[dev->lirccnt] += keycode; + dev->lircdata[dev->lirccnt] |= PULSE_BIT; + } else { + /* on pulse->space transition, add one + for the existing pulse */ + if (dev->lircdata[dev->lirccnt] && + !dev->last_space) { + dev->lirccnt++; + words_to_read--; + } + + dev->last_space += keycode; + } + } + } + + /* save off some info if we are exiting mid-packet, or with + leftovers */ + if (bytes_left_in_packet) + dev->mce_bytes_left_in_packet = bytes_left_in_packet; + if (bulkidx < this_read) { + dev->usb_valid_bytes_in_bulk_buffer = (this_read - bulkidx); + memcpy(dev->bulk_in_buffer, &(dev->bulk_in_buffer[bulkidx]), + dev->usb_valid_bytes_in_bulk_buffer); + } + return dev->lirccnt; +} + +/* mceusb_add_to_buf: called by lirc_dev to fetch all available keys + * this is used as a polling interface for us: since we set + * plugin->sample_rate we will periodically get the below call to + * check for new data returns 0 on success, or -ENODATA if nothing is + * available + */ +static int mceusb_add_to_buf(void *data, struct lirc_buffer *buf) +{ + struct usb_skel *dev = (struct usb_skel *) data; + + down(&dev->sem); + + /* verify device still present */ + if (dev->udev == NULL) { + up(&dev->sem); + return -ENODEV; + } + + if (!dev->lirccnt) { + int res; + dev->lircidx = 0; + + res = msir_fetch_more_data(dev, 1); + + if (res == 0) + res = -ENODATA; + if (res < 0) { + up(&dev->sem); + return res; + } + } + + if (dev->lirccnt) { + int keys_to_copy; + + /* determine available buffer space and available data */ + keys_to_copy = lirc_buffer_available(buf); + if (keys_to_copy > dev->lirccnt) + keys_to_copy = dev->lirccnt; + + lirc_buffer_write_n(buf, + (unsigned char *) &(dev->lircdata[dev->lircidx]), + keys_to_copy); + dev->lircidx += keys_to_copy; + dev->lirccnt -= keys_to_copy; + + up(&dev->sem); + return 0; + } + + up(&dev->sem); + return -ENODATA; +} + +/** + * mceusb_write_bulk_callback + */ +#if defined(KERNEL_2_5) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void mceusb_write_bulk_callback(struct urb *urb, struct pt_regs *regs) +#else +static void mceusb_write_bulk_callback(struct urb *urb) +#endif +{ + struct usb_skel *dev = (struct usb_skel *)urb->context; + + dprintk("%s - minor %d", __func__, dev->minor); + + if ((urb->status != -ENOENT) && + (urb->status != -ECONNRESET)) { + dprintk("%s - nonzero write buld status received: %d", + __func__, urb->status); + return; + } + + return; +} + +/** + * mceusb_probe + * + * Called by the usb core when a new device is connected that it + * thinks this driver might be interested in. + */ +#ifdef KERNEL_2_5 +static int mceusb_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct usb_device *udev = interface_to_usbdev(interface); + struct usb_host_interface *iface_desc; +#else +static void *mceusb_probe(struct usb_device *udev, unsigned int ifnum, + const struct usb_device_id *id) +{ + struct usb_interface *interface = &udev->actconfig->interface[ifnum]; + struct usb_interface_descriptor *iface_desc; +#endif + struct usb_skel *dev = NULL; + struct usb_endpoint_descriptor *endpoint; + + struct lirc_plugin *plugin; + struct lirc_buffer *rbuf; + + int minor; + size_t buffer_size; + int i; + int retval = -ENOMEM; + char junk[64]; + int partial = 0; + + /* See if the device offered us matches what we can accept */ + if (cpu_to_le16(udev->descriptor.idVendor) != USB_MCEUSB_VENDOR_ID || + cpu_to_le16(udev->descriptor.idProduct) != USB_MCEUSB_PRODUCT_ID) { + dprintk("Wrong Vendor/Product IDs"); +#ifdef KERNEL_2_5 + return -ENODEV; +#else + return NULL; +#endif + } + + /* select a "subminor" number (part of a minor number) */ + down(&minor_table_mutex); + for (minor = 0; minor < MAX_DEVICES; ++minor) { + if (minor_table[minor] == NULL) + break; + } + if (minor >= MAX_DEVICES) { + info("Too many devices plugged in, " + "can not handle this device."); + goto error; + } + + /* allocate memory for our device state and initialize it */ + dev = kmalloc(sizeof(struct usb_skel), GFP_KERNEL); + if (dev == NULL) { + err("Out of memory"); +#ifdef KERNEL_2_5 + retval = -ENOMEM; +#endif + goto error; + } + minor_table[minor] = dev; + + memset(dev, 0x00, sizeof(*dev)); + init_MUTEX(&dev->sem); + dev->udev = udev; + dev->interface = interface; + dev->minor = minor; + + /* set up the endpoint information */ + /* check out the endpoints */ + /* use only the first bulk-in and bulk-out endpoints */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 5) + iface_desc = &interface->altsetting[0]; +#else + iface_desc = interface->cur_altsetting; +#endif + +#ifdef KERNEL_2_5 + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { + endpoint = &iface_desc->endpoint[i].desc; +#else + for (i = 0; i < iface_desc->bNumEndpoints; ++i) { + endpoint = &iface_desc->endpoint[i]; +#endif + if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) && + ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_BULK)) { + dprintk("we found a bulk in endpoint"); + buffer_size = endpoint->wMaxPacketSize; + dev->bulk_in_size = buffer_size; + dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; +#ifdef KERNEL_2_5 + dev->bulk_in_buffer = + usb_buffer_alloc(udev, buffer_size, + GFP_ATOMIC, &dev->dma_in); +#else + dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); +#endif + if (!dev->bulk_in_buffer) { + err("Couldn't allocate bulk_in_buffer"); + goto error; + } + } + + if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) + == 0x00) + && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_BULK)) { + dprintk("we found a bulk out endpoint"); +#ifdef KERNEL_2_5 + dev->write_urb = usb_alloc_urb(0, GFP_KERNEL); +#else + dev->write_urb = usb_alloc_urb(0); +#endif + if (!dev->write_urb) { + err("No free urbs available"); + goto error; + } + buffer_size = endpoint->wMaxPacketSize; + dev->bulk_out_size = buffer_size; + dev->bulk_out_endpointAddr = endpoint->bEndpointAddress; +#ifdef KERNEL_2_5 + dev->bulk_out_buffer = + usb_buffer_alloc(udev, buffer_size, + GFP_ATOMIC, &dev->dma_out); +#else + dev->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL); +#endif + if (!dev->bulk_out_buffer) { + err("Couldn't allocate bulk_out_buffer"); + goto error; + } +#ifdef KERNEL_2_5 + usb_fill_bulk_urb(dev->write_urb, udev, + usb_sndbulkpipe + (udev, endpoint->bEndpointAddress), + dev->bulk_out_buffer, buffer_size, + mceusb_write_bulk_callback, dev); +#else + FILL_BULK_URB(dev->write_urb, udev, + usb_sndbulkpipe(udev, + endpoint->bEndpointAddress), + dev->bulk_out_buffer, buffer_size, + mceusb_write_bulk_callback, dev); +#endif + } + } + + if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) { + err("Couldn't find both bulk-in and bulk-out endpoints"); + goto error; + } + + /* init the waitq */ + init_waitqueue_head(&dev->wait_q); + + + /* Set up our lirc plugin */ + plugin = kmalloc(sizeof(struct lirc_plugin), GFP_KERNEL); + if (!plugin) { + err("out of memory"); + goto error; + } + memset(plugin, 0, sizeof(struct lirc_plugin)); + + rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); + if (!rbuf) { + err("out of memory"); + kfree(plugin); + goto error; + } + + /* the lirc_atiusb module doesn't memset rbuf here ... ? */ + if (lirc_buffer_init(rbuf, sizeof(lirc_t), 128)) { + err("out of memory"); + kfree(plugin); + kfree(rbuf); + goto error; + } + + strcpy(plugin->name, DRIVER_NAME " "); + plugin->minor = minor; + plugin->code_length = sizeof(lirc_t) * 8; + plugin->features = LIRC_CAN_REC_MODE2; /* | LIRC_CAN_SEND_MODE2; */ + plugin->data = dev; + plugin->rbuf = rbuf; + plugin->ioctl = NULL; + plugin->set_use_inc = &set_use_inc; + plugin->set_use_dec = &set_use_dec; + plugin->sample_rate = 80; /* sample at 100hz (10ms) */ + plugin->add_to_buf = &mceusb_add_to_buf; + /* plugin->fops = &mceusb_fops; */ +#ifdef LIRC_HAVE_SYSFS + plugin->dev = &udev->dev; +#endif + plugin->owner = THIS_MODULE; + if (lirc_register_plugin(plugin) < 0) { + kfree(plugin); + lirc_buffer_free(rbuf); + kfree(rbuf); + goto error; + } + dev->plugin = plugin; + + /* clear off the first few messages. these look like + * calibration or test data, i can't really tell + * this also flushes in case we have random ir data queued up + */ + for (i = 0; i < 40; i++) + (void) usb_bulk_msg(udev, + usb_rcvbulkpipe(udev, + dev->bulk_in_endpointAddr), + junk, 64, &partial, HZ*10); + + msir_cleanup(dev); + mceusb_setup(udev); + +#ifdef KERNEL_2_5 + /* we can register the device now, as it is ready */ + usb_set_intfdata(interface, dev); +#endif + /* let the user know what node this device is now attached to */ + /* info("USB Microsoft IR Transceiver device now attached to msir%d", + dev->minor); */ + up(&minor_table_mutex); +#ifdef KERNEL_2_5 + return 0; +#else + return dev; +#endif +error: + mceusb_delete(dev); + dev = NULL; + dprintk("%s: retval = %x", __func__, retval); + up(&minor_table_mutex); +#ifdef KERNEL_2_5 + return retval; +#else + return NULL; +#endif +} + +/** + * mceusb_disconnect + * + * Called by the usb core when the device is removed from the system. + * + * This routine guarantees that the driver will not submit any more urbs + * by clearing dev->udev. It is also supposed to terminate any currently + * active urbs. Unfortunately, usb_bulk_msg(), used in skel_read(), does + * not provide any way to do this. But at least we can cancel an active + * write. + */ +#ifdef KERNEL_2_5 +static void mceusb_disconnect(struct usb_interface *interface) +#else +static void mceusb_disconnect(struct usb_device *udev, void *ptr) +#endif +{ + struct usb_skel *dev; + int minor; +#ifdef KERNEL_2_5 + dev = usb_get_intfdata(interface); + usb_set_intfdata(interface, NULL); +#else + dev = (struct usb_skel *)ptr; +#endif + + down(&minor_table_mutex); + down(&dev->sem); + minor = dev->minor; + + /* unhook lirc things */ + lirc_unregister_plugin(minor); + lirc_buffer_free(dev->plugin->rbuf); + kfree(dev->plugin->rbuf); + kfree(dev->plugin); +#ifdef KERNEL_2_5 + /* terminate an ongoing write */ + if (atomic_read(&dev->write_busy)) { + usb_kill_urb(dev->write_urb); + wait_for_completion(&dev->write_finished); + } + + /* prevent device read, write and ioctl */ + dev->present = 0; +#endif + + mceusb_delete(dev); + + info("Microsoft IR Transceiver #%d now disconnected", minor); + up(&dev->sem); + up(&minor_table_mutex); +} + + + +/** + * usb_mceusb_init + */ +static int __init usb_mceusb_init(void) +{ + int result; + + /* register this driver with the USB subsystem */ + result = usb_register(&mceusb_driver); +#ifdef KERNEL_2_5 + if (result) { +#else + if (result < 0) { +#endif + err("usb_register failed for the " DRIVER_NAME + " driver. error number %d", result); +#ifdef KERNEL_2_5 + return result; +#else + return -1; +#endif + } + + info(DRIVER_DESC " " DRIVER_VERSION); + return 0; +} + + +/** + * usb_mceusb_exit + */ +static void __exit usb_mceusb_exit(void) +{ + /* deregister this driver with the USB subsystem */ + usb_deregister(&mceusb_driver); +} + +module_init(usb_mceusb_init); +module_exit(usb_mceusb_exit); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(usb, mceusb_table); + +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Debug enabled or not"); + +EXPORT_NO_SYMBOLS; --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/Makefile @@ -0,0 +1,5 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER \ + -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. \ + -I$(srctree)/drivers/media/video + +obj-$(CONFIG_LIRC_GPIO) += lirc_gpio.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/lirc_gpio.c +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/lirc_gpio.c @@ -0,0 +1,630 @@ +/* + * Remote control driver for the TV-card + * key codes are obtained from GPIO port + * + * (L) by Artur Lipowski + * patch for the AverMedia by Santiago Garcia Mantinan + * and Christoph Bartelmus + * patch for the BestBuy by Miguel Angel Alvarez + * patch for the Winfast TV2000 by Juan Toledo + * + * patch for the I-O Data GV-BCTV5/PCI by Jens C. Rasmussen + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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: lirc_gpio.c,v 1.50 2007/09/27 19:47:20 lirc Exp $ + * + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "kcompat.h" +#include "lirc_dev/lirc_dev.h" + +/* Obsoleted in current kernels. Added here for portability */ +struct bttv bttvs[BTTV_MAX]; +unsigned int bttv_debug; +unsigned int bttv_num; /* number of Bt848s in use */ + +int bttv_get_cardinfo(unsigned int card, int *type, unsigned *cardid) +{ + printk("The bttv_* interface is obsolete and will go away,\n" + "please use the new, sysfs based interface instead.\n"); + if (card >= bttv_num) { + return -1; + } + *type = bttvs[card].c.type; + *cardid = bttvs[card].cardid; + return 0; +} + +wait_queue_head_t* bttv_get_gpio_queue(unsigned int card) +{ + struct bttv *btv; + + if (card >= bttv_num) { + return NULL; + } + + btv = &bttvs[card]; + if (bttvs[card].shutdown) { + return NULL; + } + return &btv->gpioq; +} +/* End of obsolete code */ + + +/* insmod parameters */ +static int debug; +static int card; +static int minor = -1; +static int bttv_id = BTTV_BOARD_UNKNOWN; +static unsigned long gpio_mask; +static unsigned long gpio_enable; +static unsigned long gpio_lock_mask; +static unsigned long gpio_xor_mask; +static int soft_gap; +static int sample_rate = 10; + +struct rcv_info { + int bttv_id; + int card_id; + unsigned long gpio_mask; + unsigned long gpio_enable; + unsigned long gpio_lock_mask; + unsigned long gpio_xor_mask; + int soft_gap; + int sample_rate; + unsigned char code_length; +}; + +static struct rcv_info rcv_infos[] = { + {BTTV_BOARD_UNKNOWN, + 0, 0, 0, 0, 0, 0, 1, 0}, + {BTTV_BOARD_PXELVWPLTVPAK, + 0, 0x00003e00, 0, 0x0010000, 0, 0, 15, 32}, + {BTTV_BOARD_PXELVWPLTVPRO, + 0, 0x00001f00, 0, 0x0008000, 0, 500, 12, 32}, + {BTTV_BOARD_PV_BT878P_9B, + 0, 0x00001f00, 0, 0x0008000, 0, 500, 12, 32}, + {BTTV_BOARD_PV_BT878P_PLUS, + 0, 0x00001f00, 0, 0x0008000, 0, 500, 12, 32}, +#ifdef BTTV_BOARD_PV_M4900 + {BTTV_BOARD_PV_M4900, + 0, 0x00001f00, 0, 0x0008000, 0, 500, 12, 32}, +#endif + {BTTV_BOARD_AVERMEDIA, + 0, 0x00f88000, 0, 0x0010000, 0x00010000, 0, 10, 32}, + + /* mapped to Capture98 */ + {BTTV_BOARD_AVPHONE98, + 0x00011461, 0x003b8000, 0x00004000, + 0x0800000, 0x00800000, 0, 10, 0}, + {BTTV_BOARD_AVERMEDIA98, + 0x00021461, 0x003b8000, 0x00004000, + 0x0800000, 0x00800000, 0, 10, 0}, + + /* mapped to Phone98 */ + {BTTV_BOARD_AVPHONE98, + 0x00031461, 0x00f88000, 0, 0x0010000, 0x00010000, 0, 10, 32}, + /* is this one correct? */ + {BTTV_BOARD_AVERMEDIA98, + 0x00041461, 0x00f88000, 0, 0x0010000, 0x00010000, 0, 10, 32}, + /* work-around for VDOMATE */ + {BTTV_BOARD_AVERMEDIA98, + 0x03001461, 0x00f88000, 0, 0x0010000, 0x00010000, 0, 10, 32}, + /* reported by Danijel Korzinek, AVerTV GOw/FM */ + {BTTV_BOARD_AVERMEDIA98, + 0x00000000, 0x00f88000, 0, 0x0010000, 0x00010000, 0, 10, 32}, + + {BTTV_BOARD_CHRONOS_VS2, + 0, 0x000000f8, 0, 0x0000100, 0, 0, 20, 0}, + /* CPH031 and CPH033 cards (?) */ + /* MIRO was just a work-around */ + {BTTV_BOARD_MIRO, + 0, 0x00001f00, 0, 0x0004000, 0, 0, 10, 32}, + {BTTV_BOARD_DYNALINK, + 0, 0x00001f00, 0, 0x0004000, 0, 0, 10, 32}, +#ifdef BTTV_BOARD_ASKEY_CPH03X + {BTTV_BOARD_ASKEY_CPH03X, + 0, 0x00001f00, 0, 0x0004000, 0, 0, 10, 32}, +#endif + {BTTV_BOARD_WINVIEW_601, + 0, 0x00001f00, 0, 0x0004000, 0, 0, 0, 32}, +#ifdef BTTV_BOARD_KWORLD + {BTTV_BOARD_KWORLD, + 0, 0x00007f00, 0, 0x0004000, 0, 0, 12, 32}, +#endif + /* just a guess */ + {BTTV_BOARD_MAGICTVIEW061, + 0, 0x0028e000, 0, 0x0020000, 0, 0, 20, 32}, + {BTTV_BOARD_MAGICTVIEW063, + 0, 0x0028e000, 0, 0x0020000, 0, 0, 20, 32}, + {BTTV_BOARD_PHOEBE_TVMAS, + 0, 0x0028e000, 0, 0x0020000, 0, 0, 20, 32}, +#ifdef BTTV_BOARD_BESTBUY_EASYTV2 + {BTTV_BOARD_BESTBUY_EASYTV, + 0, 0x00007F00, 0, 0x0004000, 0, 0, 10, 8}, + {BTTV_BOARD_BESTBUY_EASYTV2, + 0, 0x00007F00, 0, 0x0008000, 0, 0, 10, 8}, +#endif + /* lock_mask probably also 0x100, or maybe it is 0x0 for all others? */ + {BTTV_BOARD_FLYVIDEO, + 0, 0x000000f8, 0, 0, 0, 0, 0, 42}, + {BTTV_BOARD_FLYVIDEO_98, + 0, 0x000000f8, 0, 0x0000100, 0, 0, 0, 42}, + {BTTV_BOARD_TYPHOON_TVIEW, + 0, 0x000000f8, 0, 0x0000100, 0, 0, 0, 42}, +#ifdef BTTV_BOARD_FLYVIDEO_98FM + /* smorar@alfonzo.smuts.uct.ac.za */ + {BTTV_BOARD_FLYVIDEO_98FM, + 0, 0x000000f8, 0, 0x0000100, 0, 0, 0, 42}, +#endif + /* The Leadtek WinFast TV 2000 XP card (id 0x6606107d) uses an + * extra gpio bit compared to the original TV 2000 card (id + * 0x217d6606); as the bttv-0.7.100 driver does not + * distinguish between the two cards, we enable the extra bit + * based on the card id: */ + {BTTV_BOARD_WINFAST2000, + 0x6606107d, 0x000008f8, 0, 0x0000100, 0, 0, 0, 32}, + {BTTV_BOARD_WINFAST2000, + 0x6609107d, 0x000008f8, 0, 0x0000100, 0, 0, 0, 32}, + {BTTV_BOARD_WINFAST2000, + 0xff06107d, 0x000008f8, 0, 0x0000100, 0, 0, 0, 32}, + /* default: */ + {BTTV_BOARD_WINFAST2000, + 0, 0x000000f8, 0, 0x0000100, 0, 0, 0, 32}, +#ifdef BTTV_BOARD_GVBCTV5PCI + {BTTV_BOARD_GVBCTV5PCI, + 0, 0x00f0b000, 0, 0, 0, 0, 20, 8}, +#endif +}; + +static unsigned char code_length; +static unsigned char code_bytes = 1; + +#define MAX_BYTES 8 + +#define SUCCESS 0 +#define LOGHEAD "lirc_gpio (%d): " + +/* how many bits GPIO value can be shifted right before processing + * it is computed from the value of gpio_mask_parameter + */ +static unsigned char gpio_pre_shift; + +static inline int reverse(int data, int bits) +{ + int i; + int c; + + for (c = 0, i = 0; i < bits; i++) + c |= (((data & (1<>= gpio_pre_shift; + while (mask) { + if (mask & 1u) + codes[0] |= (gpio_val & 1u) << shift++; + mask >>= 1; + gpio_val >>= 1; + } + + dprintk(LOGHEAD "code is %lx\n", card, (unsigned long) codes[0]); + switch (bttv_id) { + case BTTV_BOARD_AVERMEDIA: + codes[2] = (codes[0]<<2)&0xff; + codes[3] = (~codes[2])&0xff; + codes[0] = 0x02; + codes[1] = 0xFD; + break; + case BTTV_BOARD_AVPHONE98: + codes[2] = ((codes[0]&(~0x1))<<2)&0xff; + codes[3] = (~codes[2])&0xff; + if (codes[0]&0x1) { + codes[0] = 0xc0; + codes[1] = 0x3f; + } else { + codes[0] = 0x40; + codes[1] = 0xbf; + } + break; + case BTTV_BOARD_AVERMEDIA98: + break; + case BTTV_BOARD_FLYVIDEO: + case BTTV_BOARD_FLYVIDEO_98: + case BTTV_BOARD_TYPHOON_TVIEW: +#ifdef BTTV_BOARD_FLYVIDEO_98FM + case BTTV_BOARD_FLYVIDEO_98FM: +#endif + codes[4] = codes[0]<<3; + codes[5] = ((~codes[4])&0xff); + + codes[0] = 0x00; + codes[1] = 0x1A; + codes[2] = 0x1F; + codes[3] = 0x2F; + break; + case BTTV_BOARD_MAGICTVIEW061: + case BTTV_BOARD_MAGICTVIEW063: + case BTTV_BOARD_PHOEBE_TVMAS: + codes[0] = (codes[0]&0x01) + | ((codes[0]&0x02)<<1) + | ((codes[0]&0x04)<<2) + | ((codes[0]&0x08)>>2) + | ((codes[0]&0x10)>>1); + /* FALLTHROUGH */ + case BTTV_BOARD_MIRO: + case BTTV_BOARD_DYNALINK: +#ifdef BTTV_BOARD_ASKEY_CPH03X + case BTTV_BOARD_ASKEY_CPH03X: +#endif + case BTTV_BOARD_PXELVWPLTVPAK: + case BTTV_BOARD_PXELVWPLTVPRO: + case BTTV_BOARD_PV_BT878P_9B: + case BTTV_BOARD_PV_BT878P_PLUS: +#ifdef BTTV_BOARD_PV_M4900 + case BTTV_BOARD_PV_M4900: +#endif +#ifdef BTTV_BOARD_KWORLD + case BTTV_BOARD_KWORLD: +#endif + codes[2] = reverse(codes[0], 8); + codes[3] = (~codes[2])&0xff; + codes[0] = 0x61; + codes[1] = 0xD6; + break; +#if 0 + /* derived from e-tech config file */ + /* 26 + 16 bits */ + /* won't apply it until it's confirmed with a fly98 */ + case BTTV_BOARD_FLYVIDEO_98: + case BTTV_BOARD_FLYVIDEO_98FM: + codes[4] = codes[0]<<3; + codes[5] = (~codes[4])&0xff; + + codes[0] = 0x00; + codes[1] = 0x1A; + codes[2] = 0x1F; + codes[3] = 0x2F; + break; +#endif + case BTTV_BOARD_WINFAST2000: + /* shift extra bit */ + codes[0] = (codes[0]&0x1f) | ((codes[0]&0x20) << 1); + case BTTV_BOARD_WINVIEW_601: + codes[2] = reverse(codes[0], 8); + codes[3] = (~codes[2])&0xff; + codes[0] = 0xC0; + codes[1] = 0x3F; + break; + default: + break; + } + + return SUCCESS; +} + +/* add_to_buf - copy a code to the buffer */ +static int add_to_buf(void *data, struct lirc_buffer *buf) +{ + static unsigned long next_time; + static unsigned char prev_codes[MAX_BYTES]; + unsigned long code = 0; + unsigned char cur_codes[MAX_BYTES]; + + if (bttv_read_gpio(card, &code)) { + dprintk(LOGHEAD "cannot read GPIO\n", card); + return -EIO; + } + + if (build_key(code, cur_codes)) + return -EFAULT; + + if (soft_gap) { + if (!memcmp(prev_codes, cur_codes, code_bytes) && + jiffies < next_time) + return -EAGAIN; + + next_time = jiffies + soft_gap; + } + memcpy(prev_codes, cur_codes, code_bytes); + + lirc_buffer_write_1(buf, cur_codes); + + return SUCCESS; +} + +static int set_use_inc(void *data) +{ + MOD_INC_USE_COUNT; + return 0; +} + +static void set_use_dec(void *data) +{ + MOD_DEC_USE_COUNT; +} + +static wait_queue_head_t *get_queue(void *data) +{ + return bttv_get_gpio_queue(card); +} + +static struct lirc_plugin plugin = { + .name = "lirc_gpio ", + .add_to_buf = add_to_buf, + .get_queue = get_queue, + .set_use_inc = set_use_inc, + .set_use_dec = set_use_dec, + .dev = NULL, + .owner = THIS_MODULE, +}; + +/* + * + */ +static int gpio_remote_init(void) +{ + int ret; + unsigned int mask; + + /* "normalize" gpio_mask + * this means shift it right until first bit is set + */ + while (!(gpio_mask & 1u)) { + gpio_pre_shift++; + gpio_mask >>= 1; + } + + if (code_length) + plugin.code_length = code_length; + else { + /* calculate scan code length in bits if needed */ + plugin.code_length = 1; + mask = gpio_mask >> 1; + while (mask) { + if (mask & 1u) + plugin.code_length++; + mask >>= 1; + } + } + + code_bytes = (plugin.code_length/8) + (plugin.code_length % 8 ? 1 : 0); + if (MAX_BYTES < code_bytes) { + printk(LOGHEAD "scan code too long (%d bytes)\n", + minor, code_bytes); + return -EBADRQC; + } + + if (gpio_enable) { + if (bttv_gpio_enable(card, gpio_enable, gpio_enable)) { + printk(LOGHEAD "gpio_enable failure\n", minor); + return -EIO; + } + } + + + /* translate ms to jiffies */ + soft_gap = (soft_gap*HZ) / 1000; + + plugin.minor = minor; + plugin.sample_rate = sample_rate; + + ret = lirc_register_plugin(&plugin); + + if (0 > ret) { + printk(LOGHEAD "device registration failed with %d\n", + minor, ret); + return ret; + } + + minor = ret; + printk(LOGHEAD "driver registered\n", minor); + + return SUCCESS; +} + +#ifdef MODULE +/* + * + */ +int init_module(void) +{ + int type, cardid, card_type; + + if (MAX_IRCTL_DEVICES < minor) { + printk(KERN_INFO "lirc_gpio: parameter minor (%d) " + "must be less than %d!\n", + minor, MAX_IRCTL_DEVICES - 1); + return -EBADRQC; + } + + request_module("bttv"); + + /* if gpio_mask not zero then use module parameters + * instead of autodetecting TV card + */ + if (gpio_mask) { + if (sample_rate != 0 && + (2 > sample_rate || HZ < sample_rate)) { + printk(LOGHEAD "parameter sample_rate " + "must be between 2 and %d!\n", minor, HZ); + return -EBADRQC; + } + + if (sample_rate != 0 && soft_gap && + ((2000/sample_rate) > soft_gap || 1000 < soft_gap)) { + printk(LOGHEAD "parameter soft_gap " + "must be between %d and 1000!\n", + minor, 2000/sample_rate); + return -EBADRQC; + } + } else { + if (bttv_get_cardinfo(card, &type, &cardid) == -1) { + printk(LOGHEAD "could not get card type\n", minor); + return -EBADRQC; + } + printk(LOGHEAD "card type 0x%x, id 0x%x\n", minor, + type, cardid); + + if (type == BTTV_BOARD_UNKNOWN) { + printk(LOGHEAD "cannot detect TV card nr %d!\n", + minor, card); + return -EBADRQC; + } + for (card_type = 1; + card_type < sizeof(rcv_infos)/sizeof(struct rcv_info); + card_type++) { + if (rcv_infos[card_type].bttv_id == type && + (rcv_infos[card_type].card_id == 0 || + rcv_infos[card_type].card_id == cardid)) { + bttv_id = rcv_infos[card_type].bttv_id; + gpio_mask = rcv_infos[card_type].gpio_mask; + gpio_enable = rcv_infos[card_type].gpio_enable; + gpio_lock_mask = + rcv_infos[card_type].gpio_lock_mask; + gpio_xor_mask = + rcv_infos[card_type].gpio_xor_mask; + soft_gap = rcv_infos[card_type].soft_gap; + sample_rate = rcv_infos[card_type].sample_rate; + code_length = rcv_infos[card_type].code_length; + break; + } + } + if (type == BTTV_BOARD_AVPHONE98 && cardid == 0x00011461) + bttv_id = BTTV_BOARD_AVERMEDIA98; + + if (type == BTTV_BOARD_AVERMEDIA98 && cardid == 0x00041461) + bttv_id = BTTV_BOARD_AVPHONE98; + + if (type == BTTV_BOARD_AVERMEDIA98 && cardid == 0x03001461) + bttv_id = BTTV_BOARD_AVPHONE98; + + if (type == BTTV_BOARD_AVERMEDIA98 && cardid == 0x00000000) + bttv_id = BTTV_BOARD_AVPHONE98; + + if (card_type == sizeof(rcv_infos)/sizeof(struct rcv_info)) { + printk(LOGHEAD "TV card type 0x%x not supported!\n", + minor, type); + return -EBADRQC; + } + } + + request_module("lirc_dev"); + + return gpio_remote_init(); +} + +/* + * + */ +void cleanup_module(void) +{ + lirc_unregister_plugin(minor); + + dprintk(LOGHEAD "module successfully unloaded\n", minor); +} + +/* Dont try to use it as a static version ! */ +MODULE_DESCRIPTION("Driver module for remote control (data " + "from bt848 GPIO port)"); +MODULE_AUTHOR("Artur Lipowski"); +MODULE_LICENSE("GPL"); + +module_param(minor, int, 0444); +MODULE_PARM_DESC(minor, "Preferred minor device number"); + +module_param(card, int, 0444); +MODULE_PARM_DESC(card, "TV card number to attach to"); + +module_param(gpio_mask, long, 0444); +MODULE_PARM_DESC(gpio_mask, "gpio_mask"); + +module_param(gpio_lock_mask, long, 0444); +MODULE_PARM_DESC(gpio_lock_mask, "gpio_lock_mask"); + +module_param(gpio_xor_mask, long, 0444); +MODULE_PARM_DESC(gpio_xor_mask, "gpio_xor_mask"); + +module_param(soft_gap, int, 0444); +MODULE_PARM_DESC(soft_gap, "Time between keypresses (in ms)"); + +module_param(sample_rate, int, 0444); +MODULE_PARM_DESC(sample_rate, "Sample rate (between 2 and HZ)"); + +module_param(bttv_id, int, 0444); +MODULE_PARM_DESC(bttv_id, "BTTV card type"); + +module_param(debug, bool, 0644); +MODULE_PARM_DESC(debug, "Enable debugging messages"); + +EXPORT_NO_SYMBOLS; + +#endif /* MODULE */ + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_imon/lirc_imon.c +++ linux-2.6.28/ubuntu/lirc/lirc_imon/lirc_imon.c @@ -0,0 +1,1524 @@ +/* + * lirc_imon.c: LIRC plugin/VFD driver for Ahanix/Soundgraph IMON IR/VFD + * + * $Id: lirc_imon.c,v 1.23 2008/01/19 10:06:46 lirc Exp $ + * + * Version 0.3 + * Supports newer iMON models that send decoded IR signals. + * This includes the iMON PAD model. + * Removed module option for vfd_proto_6p. This driver supports + * multiple iMON devices so it is meaningless to have + * a global option to set protocol variants. + * + * Version 0.2 beta 2 [January 31, 2005] + * USB disconnect/reconnect no longer causes problems for lircd + * + * Version 0.2 beta 1 [January 29, 2005] + * Added support for original iMON receiver(ext USB) + * + * Version 0.2 alpha 2 [January 24, 2005] + * Added support for VFDs with 6-packet protocol + * + * Version 0.2 alpha 1 [January 23, 2005] + * Added support for 2.6 kernels + * Reworked disconnect handling + * Incorporated Changwoo Ryu's algorithm + * + * Version 0.1 alpha 1[July 5, 2004] + * + * Copyright(C) 2004 Venky Raju(dev@venky.ws) + * + * lirc_imon is free software; you can redistribute it and/or modify + * it under the terms of the 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 + +#ifdef HAVE_CONFIG_H +#include +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 22) +#error "*** Sorry, this driver requires kernel version 2.4.22 or higher" +#endif + +#include + +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#include +#else +#include +#endif +#include + +#include "kcompat.h" +#include "lirc.h" +#include "lirc_dev/lirc_dev.h" + + +#define MOD_AUTHOR "Venky Raju " +#define MOD_DESC "Driver for Soundgraph iMON MultiMedia IR/VFD w/imon pad2keys patch" +#define MOD_NAME "lirc_imon" +#define MOD_VERSION "0.3p2k" + +#define VFD_MINOR_BASE 144 /* Same as LCD */ +#define DEVFS_MODE (S_IFCHR | S_IRUSR | S_IWUSR | \ + S_IRGRP | S_IWGRP | S_IROTH) +#define DEVFS_NAME LIRC_DEVFS_PREFIX "lcd%d" + +#define BUF_CHUNK_SIZE 4 +#define BUF_SIZE 128 + +#define BIT_DURATION 250 /* each bit received is 250us */ + +#define SUCCESS 0 +#define TRUE 1 +#define FALSE 0 + +#define CURSOR_LIMIT 16 + +/* ------------------------------------------------------------ + * P R O T O T Y P E S + * ------------------------------------------------------------ + */ + +/* USB Callback prototypes */ +#ifdef KERNEL_2_5 +static int imon_probe(struct usb_interface *interface, + const struct usb_device_id *id); +static void imon_disconnect(struct usb_interface *interface); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void usb_rx_callback(struct urb *urb, struct pt_regs *regs); +static void usb_tx_callback(struct urb *urb, struct pt_regs *regs); +#else +static void usb_rx_callback(struct urb *urb); +static void usb_tx_callback(struct urb *urb); +#endif +#else +static void *imon_probe(struct usb_device *dev, unsigned int intf, + const struct usb_device_id *id); +static void imon_disconnect(struct usb_device *dev, void *data); +static void usb_rx_callback(struct urb *urb); +static void usb_tx_callback(struct urb *urb); +#endif + +/* VFD file_operations function prototypes */ +static int vfd_open(struct inode *inode, struct file *file); +static int vfd_close(struct inode *inode, struct file *file); +static ssize_t vfd_write(struct file *file, const char *buf, + size_t n_bytes, loff_t *pos); + +/* LCD file_operations override function prototypes */ +static ssize_t lcd_write(struct file *file, const char *buf, + size_t n_bytes, loff_t *pos); + +/* LIRC plugin function prototypes */ +static int ir_open(void *data); +static void ir_close(void *data); + +/* Driver init/exit prototypes */ +static int __init imon_init(void); +static void __exit imon_exit(void); + +/* ------------------------------------------------------------ + * G L O B A L S + * ------------------------------------------------------------ + */ + +struct imon_context { + struct usb_device *dev; + int vfd_supported; /* not all controllers do */ + int vfd_isopen; /* VFD port has been opened */ +#if !defined(KERNEL_2_5) + int subminor; /* index into minor_table */ + devfs_handle_t devfs; +#endif + int ir_isopen; /* IR port open */ + int ir_isassociating; /* IR port open for association */ + int dev_present; /* USB device presence */ + struct semaphore sem; /* to lock this object */ + wait_queue_head_t remove_ok; /* For unexpected USB disconnects */ + + int vfd_proto_6p; /* VFD requires 6th packet */ + int ir_onboard_decode; /* IR signals decoded onboard */ + + struct lirc_plugin *plugin; + struct usb_endpoint_descriptor *rx_endpoint; + struct usb_endpoint_descriptor *tx_endpoint; + struct urb *rx_urb; + struct urb *tx_urb; + unsigned char usb_rx_buf[8]; + unsigned char usb_tx_buf[8]; + + struct rx_data { + int count; /* length of 0 or 1 sequence */ + int prev_bit; /* logic level of sequence */ + int initial_space; /* initial space flag */ + } rx; + + struct tx_t { + unsigned char data_buf[35]; /* user data buffer */ + struct completion finished; /* wait for write to finish */ + atomic_t busy; /* write in progress */ + int status; /* status of tx completion */ + } tx; + + int key_x; + int key_y; + int last_count; /* number of times pressed */ +}; + +#define LOCK_CONTEXT down(&context->sem) +#define UNLOCK_CONTEXT up(&context->sem) + +/* VFD file operations */ +static struct file_operations vfd_fops = { + .owner = THIS_MODULE, + .open = &vfd_open, + .write = &vfd_write, + .release = &vfd_close +}; + +/* USB Device ID for IMON USB Control Board */ +static struct usb_device_id imon_usb_id_table[] = { + { USB_DEVICE(0x0aa8, 0xffda) }, /* IR & VFD */ + { USB_DEVICE(0x0aa8, 0x8001) }, /* IR only */ + { USB_DEVICE(0x15c2, 0xffda) }, /* IR & VFD */ + { USB_DEVICE(0x15c2, 0xffdc) }, /* IR & VFD */ + { USB_DEVICE(0x04e8, 0xff30) }, /* ext IR only */ + {} +}; + +/* Some iMON VFD models requires a 6th packet */ +static unsigned short vfd_proto_6p_vendor_list[] = { + /* terminate this list with a 0 */ + 0x15c2, + 0 }; +static unsigned char vfd_packet6[] = { + 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF }; + +/* Newer iMON models decode the signal onboard */ +static unsigned short ir_onboard_decode_product_list[] = { + /* terminate this list with a 0 */ + 0xffdc, + 0 }; + +/* USB Device data */ +static struct usb_driver imon_driver = { + LIRC_THIS_MODULE(.owner = THIS_MODULE) + .name = MOD_NAME, + .probe = imon_probe, + .disconnect = imon_disconnect, + .id_table = imon_usb_id_table, +#if !defined(KERNEL_2_5) + .fops = &vfd_fops, + .minor = VFD_MINOR_BASE, +#endif +}; + +#ifdef KERNEL_2_5 +static struct usb_class_driver imon_class = { + .name = DEVFS_NAME, + .fops = &vfd_fops, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15) + .mode = DEVFS_MODE, +#endif + .minor_base = VFD_MINOR_BASE, +}; +#endif + +/* to prevent races between open() and disconnect() */ +static DECLARE_MUTEX(disconnect_sem); + +static int debug; +#ifdef LIRC_IMON_LCD +static int is_lcd = 1; +#else +static int is_lcd; /* If LIRC_IMON_LCD not defined, default to non-LCD */ +#endif + +/* pad2keys module parameter. pad2keys patch active? */ +static int pad2keys_active = 0; + +#if !defined(KERNEL_2_5) + +#define MAX_DEVICES 4 /* In case there's more than one iMON device */ +static struct imon_context *minor_table[MAX_DEVICES]; + +/* +static DECLARE_MUTEX(minor_table_sem); +#define LOCK_MINOR_TABLE down(&minor_table_sem) +#define UNLOCK_MINOR_TABLE up(&minor_table_sem) +*/ + +/* the global usb devfs handle */ +extern devfs_handle_t usb_devfs_handle; + +#endif + +/* ------------------------------------------------------------ + * M O D U L E C O D E + * ------------------------------------------------------------ + */ + +MODULE_AUTHOR(MOD_AUTHOR); +MODULE_DESCRIPTION(MOD_DESC); +MODULE_VERSION(MOD_VERSION); /* MBr: was missing */ +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(usb, imon_usb_id_table); + +module_param(debug, int, 0); +MODULE_PARM_DESC(debug, "Debug messages: 0=no, 1=yes(default: no)"); + +#ifdef LIRC_IMON_LCD +module_param(is_lcd, int, 1); +MODULE_PARM_DESC(is_lcd, "The device is an LCD: 0=no (it's a VFD), " + "1=yes (default:yes)"); +#else +module_param(is_lcd, int, 0); +MODULE_PARM_DESC(is_lcd, "The device is an LCD: 0=no (it's a VFD), " + "1=yes (default:no)"); +#endif +module_param (pad2keys_active, int, 0); +MODULE_PARM_DESC (pad2keys_active, "pad2keys patch active: 0=no, 1=yes (default: no)"); + +static inline void delete_context(struct imon_context *context) +{ + if (context->vfd_supported) + usb_free_urb(context->tx_urb); + usb_free_urb(context->rx_urb); + lirc_buffer_free(context->plugin->rbuf); + kfree(context->plugin->rbuf); + kfree(context->plugin); + kfree(context); + + if (debug) + info("%s: context deleted", __FUNCTION__); +} + +static inline void deregister_from_lirc(struct imon_context *context) +{ + int retval; + int minor = context->plugin->minor; + + retval = lirc_unregister_plugin(minor); + if (retval) + err("%s: unable to deregister from lirc(%d)", + __FUNCTION__, retval); + else + info("Deregistered iMON plugin(minor:%d)", minor); + +} + +/** + * Called when the VFD device(e.g. /dev/usb/lcd) + * is opened by the application. + */ +static int vfd_open(struct inode *inode, struct file *file) +{ +#ifdef KERNEL_2_5 + struct usb_interface *interface; +#endif + struct imon_context *context = NULL; + int subminor; + int retval = SUCCESS; + + /* prevent races with disconnect */ + down(&disconnect_sem); + +#ifdef KERNEL_2_5 + subminor = iminor(inode); + interface = usb_find_interface(&imon_driver, subminor); + if (!interface) { + err("%s: could not find interface for minor %d", + __FUNCTION__, subminor); + retval = -ENODEV; + goto exit; + } + context = usb_get_intfdata(interface); +#else + subminor = MINOR(inode->i_rdev) - VFD_MINOR_BASE; + if (subminor < 0 || subminor >= MAX_DEVICES) { + err("%s: no record of minor %d", __FUNCTION__, subminor); + retval = -ENODEV; + goto exit; + } + context = minor_table[subminor]; +#endif + + if (!context) { + err("%s: no context found for minor %d", + __FUNCTION__, subminor); + retval = -ENODEV; + goto exit; + } + + LOCK_CONTEXT; + + if (!context->vfd_supported) { + err("%s: VFD not supported by device", __FUNCTION__); + retval = -ENODEV; + } else if (context->vfd_isopen) { + err("%s: VFD port is already open", __FUNCTION__); + retval = -EBUSY; + } else { + MOD_INC_USE_COUNT; + context->vfd_isopen = TRUE; + file->private_data = context; + info("VFD port opened"); + } + + UNLOCK_CONTEXT; + +exit: + up(&disconnect_sem); + return retval; +} + +/** + * Called when the VFD device(e.g. /dev/usb/lcd) + * is closed by the application. + */ +static int vfd_close(struct inode *inode, struct file *file) +{ + struct imon_context *context = NULL; + int retval = SUCCESS; + + context = (struct imon_context *) file->private_data; + + if (!context) { + err("%s: no context for device", __FUNCTION__); + return -ENODEV; + } + + LOCK_CONTEXT; + + if (!context->vfd_supported) { + err("%s: VFD not supported by device", __FUNCTION__); + retval = -ENODEV; + } else if (!context->vfd_isopen) { + err("%s: VFD is not open", __FUNCTION__); + retval = -EIO; + } else { + context->vfd_isopen = FALSE; + MOD_DEC_USE_COUNT; + info("VFD port closed"); + if (!context->dev_present && !context->ir_isopen) { + /* Device disconnected before close and IR port is not + * open. If IR port is open, context will be deleted by + * ir_close. */ + UNLOCK_CONTEXT; + delete_context(context); + return retval; + } + } + + UNLOCK_CONTEXT; + return retval; +} + +/** + * Sends a packet to the VFD. + */ +static inline int send_packet(struct imon_context *context) +{ + unsigned int pipe; + int interval = 0; + int retval = SUCCESS; + + pipe = usb_sndintpipe(context->dev, + context->tx_endpoint->bEndpointAddress); +#ifdef KERNEL_2_5 + interval = context->tx_endpoint->bInterval; +#endif /* Use 0 for 2.4 kernels */ + + usb_fill_int_urb(context->tx_urb, context->dev, pipe, + context->usb_tx_buf, sizeof(context->usb_tx_buf), + usb_tx_callback, context, interval); + + context->tx_urb->actual_length = 0; + + init_completion(&context->tx.finished); + atomic_set(&(context->tx.busy), 1); + +#ifdef KERNEL_2_5 + retval = usb_submit_urb(context->tx_urb, GFP_KERNEL); +#else + retval = usb_submit_urb(context->tx_urb); +#endif + if (retval != SUCCESS) { + atomic_set(&(context->tx.busy), 0); + err("%s: error submitting urb(%d)", __FUNCTION__, retval); + } else { + /* Wait for tranmission to complete(or abort) */ + UNLOCK_CONTEXT; + wait_for_completion(&context->tx.finished); + LOCK_CONTEXT; + + retval = context->tx.status; + if (retval != SUCCESS) + err("%s: packet tx failed(%d)", __FUNCTION__, retval); + } + + return retval; +} + +/** + * Sends an associate packet to the iMON 2.4G. + * + * This might not be such a good idea, since it has an id + * collition with some versions of the "IR & VFD" combo. + * The only way to determine if it is a RF version is to look + * at the product description string.(Which we currently do + * not fetch). + */ +static inline int send_associate_24g(struct imon_context *context) +{ + int retval; + const unsigned char packet[8] = { 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20 }; + + if (!context) { + err("%s: no context for device", __FUNCTION__); + return -ENODEV; + } + + LOCK_CONTEXT; + + if (!context->dev_present) { + err("%s: no iMON device present", __FUNCTION__); + retval = -ENODEV; + goto exit; + } + + memcpy(context->usb_tx_buf, packet, sizeof(packet)); + retval = send_packet(context); + +exit: + UNLOCK_CONTEXT; + + return retval; +} + +#ifdef KERNEL_2_5 +/** + * This is the sysfs functions to handle the association og the iMON 2.4G LT. + * + * + */ + +static ssize_t show_associate_remote(struct device *d, + struct device_attribute *attr, + char *buf) +{ + struct imon_context *context = dev_get_drvdata(d); + + if (!context) + return -ENODEV; + + if (context->ir_isassociating) { + strcpy(buf, "The device it associating press some button " + "on the remote.\n"); + } else if (context->ir_isopen) { + strcpy(buf, "Device is open and ready to associate.\n" + "Echo something into this file to start " + "the process.\n"); + } else { + strcpy(buf, "Device is closed, you need to open it to " + "associate the remote(you can use irw).\n"); + } + return strlen(buf); +} + +static ssize_t store_associate_remote(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct imon_context *context; + + context = dev_get_drvdata(d); + + if (!context) + return -ENODEV; + + if (!context->ir_isopen) + return -EINVAL; + + if (context->ir_isopen) { + context->ir_isassociating = TRUE; + send_associate_24g(context); + } + + return count; +} + +static DEVICE_ATTR(associate_remote, S_IWUSR | S_IRUGO, show_associate_remote, + store_associate_remote); + +static struct attribute *imon_sysfs_entries[] = { + &dev_attr_associate_remote.attr, + NULL +}; + +static struct attribute_group imon_attribute_group = { + .attrs = imon_sysfs_entries +}; + +#endif + + + +/** + * Writes data to the VFD. The IMON VFD is 2x16 characters + * and requires data in 5 consecutive USB interrupt packets, + * each packet but the last carrying 7 bytes. + * + * I don't know if the VFD board supports features such as + * scrolling, clearing rows, blanking, etc. so at + * the caller must provide a full screen of data. If fewer + * than 32 bytes are provided spaces will be appended to + * generate a full screen. + */ +static ssize_t vfd_write(struct file *file, const char *buf, + size_t n_bytes, loff_t *pos) +{ + int i; + int offset; + int seq; + int retval = SUCCESS; + struct imon_context *context; + + context = (struct imon_context *) file->private_data; + if (!context) { + err("%s: no context for device", __FUNCTION__); + return -ENODEV; + } + + LOCK_CONTEXT; + + if (!context->dev_present) { + err("%s: no iMON device present", __FUNCTION__); + retval = -ENODEV; + goto exit; + } + + if (n_bytes <= 0 || n_bytes > 32) { + err("%s: invalid payload size", __FUNCTION__); + retval = -EINVAL; + goto exit; + } + + if (copy_from_user(context->tx.data_buf, buf, n_bytes)) + return -EFAULT; + + /* Pad with spaces */ + for (i = n_bytes; i < 32; ++i) + context->tx.data_buf[i] = ' '; + + for (i = 32; i < 35; ++i) + context->tx.data_buf[i] = 0xFF; + + offset = 0; + seq = 0; + + do { + memcpy(context->usb_tx_buf, context->tx.data_buf + offset, 7); + context->usb_tx_buf[7] = (unsigned char) seq; + + retval = send_packet(context); + if (retval != SUCCESS) { + err("%s: send packet failed for packet #%d", + __FUNCTION__, seq/2); + goto exit; + } else { + seq += 2; + offset += 7; + } + + } while (offset < 35); + + if (context->vfd_proto_6p) { + /* Send packet #6 */ + memcpy(context->usb_tx_buf, vfd_packet6, 7); + context->usb_tx_buf[7] = (unsigned char) seq; + retval = send_packet(context); + if (retval != SUCCESS) + err("%s: send packet failed for packet #%d", + __FUNCTION__, seq/2); + } + +exit: + UNLOCK_CONTEXT; + + return(retval == SUCCESS) ? n_bytes : retval; +} + +/** + * Writes data to the LCD. The iMON OEM LCD screen excepts 8-byte + * packets. We accept data as 16 hexadecimal digits, followed by a + * newline (to make it easy to drive the device from a command-line + * -- even though the actual binary data is a bit complicated). + * + * The device itself is not a "traditional" text-mode display. It's + * actually a 16x96 pixel bitmap display. That means if you want to + * display text, you've got to have your own "font" and translate the + * text into bitmaps for display. This is really flexible (you can + * display whatever diacritics you need, and so on), but it's also + * a lot more complicated than most LCDs... + */ +static ssize_t lcd_write(struct file *file, const char *buf, + size_t n_bytes, loff_t *pos) +{ + int retval = SUCCESS; + struct imon_context *context; + + context = (struct imon_context *) file->private_data; + if (!context) { + err("%s: no context for device", __FUNCTION__); + return -ENODEV; + } + + LOCK_CONTEXT; + + if (!context->dev_present) { + err("%s: no iMON device present", __FUNCTION__); + retval = -ENODEV; + goto exit; + } + + if (n_bytes != 8) { + err("%s: invalid payload size: %d (expecting 8)", + __FUNCTION__, (int) n_bytes); + retval = -EINVAL; + goto exit; + } + + if (copy_from_user(context->usb_tx_buf, buf, 8)) + return -EFAULT; + + retval = send_packet(context); + if (retval != SUCCESS) { + err("%s: send packet failed!", + __FUNCTION__); + goto exit; + } else if (debug) { + info("%s: write %d bytes to LCD", __FUNCTION__, (int) n_bytes); + } +exit: + UNLOCK_CONTEXT; + return (retval == SUCCESS) ? n_bytes : retval; +} + +/** + * Callback function for USB core API: transmit data + */ +#if defined(KERNEL_2_5) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void usb_tx_callback(struct urb *urb, struct pt_regs *regs) +#else +static void usb_tx_callback(struct urb *urb) +#endif +{ + struct imon_context *context; + + if (!urb) + return; + context = (struct imon_context *) urb->context; + if (!context) + return; + + context->tx.status = urb->status; + + /* notify waiters that write has finished */ + atomic_set(&context->tx.busy, 0); + complete(&context->tx.finished); + + return; +} + +/** + * Called by lirc_dev when the application opens /dev/lirc + */ +static int ir_open(void *data) +{ + int retval = SUCCESS; + struct imon_context *context; + + /* prevent races with disconnect */ + down(&disconnect_sem); + + context = (struct imon_context *) data; + + LOCK_CONTEXT; + + if (context->ir_isopen) { + err("%s: IR port is already open", __FUNCTION__); + retval = -EBUSY; + goto exit; + } + + /* initial IR protocol decode variables */ + context->rx.count = 0; + context->rx.initial_space = 1; + context->rx.prev_bit = 0; + + /* init pad context for pad2keys */ + context ->key_x = 0; + context ->key_y = 0; + context ->last_count = 0; + + usb_fill_int_urb(context->rx_urb, context->dev, + usb_rcvintpipe(context->dev, + context->rx_endpoint->bEndpointAddress), + context->usb_rx_buf, sizeof(context->usb_rx_buf), + usb_rx_callback, context, context->rx_endpoint->bInterval); + +#ifdef KERNEL_2_5 + retval = usb_submit_urb(context->rx_urb, GFP_KERNEL); +#else + retval = usb_submit_urb(context->rx_urb); +#endif + + if (retval) + err("%s: usb_submit_urb failed for ir_open(%d)", + __FUNCTION__, retval); + else { + MOD_INC_USE_COUNT; + context->ir_isopen = TRUE; + info("IR port opened"); + } + +exit: + UNLOCK_CONTEXT; + + up(&disconnect_sem); + return SUCCESS; +} + +/** + * Called by lirc_dev when the application closes /dev/lirc + */ +static void ir_close(void *data) +{ + struct imon_context *context; + + context = (struct imon_context *)data; + if (!context) { + err("%s: no context for device", __FUNCTION__); + return; + } + + LOCK_CONTEXT; + + usb_kill_urb(context->rx_urb); + context->ir_isopen = FALSE; + context->ir_isassociating = FALSE; + MOD_DEC_USE_COUNT; + info("IR port closed"); + + if (!context->dev_present) { + /* Device disconnected while IR port was + * still open. Plugin was not deregistered + * at disconnect time, so do it now. */ + deregister_from_lirc(context); + + if (!context->vfd_isopen) { + UNLOCK_CONTEXT; + delete_context(context); + return; + } + /* If VFD port is open, context will be deleted by vfd_close */ + } + + UNLOCK_CONTEXT; + return; +} + +/** + * Convert bit count to time duration(in us) and submit + * the value to lirc_dev. + */ +static inline void submit_data(struct imon_context *context) +{ + unsigned char buf[4]; + int value = context->rx.count; + int i; + + if (debug) + info("submitting data to LIRC\n"); + + value *= BIT_DURATION; + value &= PULSE_MASK; + if (context->rx.prev_bit) + value |= PULSE_BIT; + + for (i = 0; i < 4; ++i) + buf[i] = value>>(i*8); + + lirc_buffer_write_1(context->plugin->rbuf, buf); + wake_up(&context->plugin->rbuf->wait_poll); + return; +} + +/** + * Process the incoming packet + */ +static inline void incoming_packet(struct imon_context *context, + struct urb *urb) +{ + int len = urb->actual_length; + unsigned char *buf = urb->transfer_buffer; + int octet, bit; + unsigned char mask; + int chunk_num; +#ifdef DEBUG + int i; +#endif + + if (len != 8) { + warn("%s: invalid incoming packet size(%d)", + __FUNCTION__, len); + return; + } + + /* iMON 2.4G associate frame */ + if (buf[0] == 0x00 && + buf[2] == 0xFF && /* REFID */ + buf[3] == 0xFF && + buf[4] == 0xFF && + buf[5] == 0xFF && /* iMON 2.4G */ + ((buf[6] == 0x4E && buf[7] == 0xDF) || /* LT */ + (buf[6] == 0x5E && buf[7] == 0xDF))) { /* DT */ + warn("%s: remote associated refid=%02X", __FUNCTION__, buf[1]); + context->ir_isassociating = FALSE; + } + + chunk_num = buf[7]; + + if (chunk_num == 0xFF) + return; /* filler frame, no data here */ + + if (buf[0] == 0xFF && + buf[1] == 0xFF && + buf[2] == 0xFF && + buf[3] == 0xFF && + buf[4] == 0xFF && + buf[5] == 0xFF && /* iMON 2.4G */ + ((buf[6] == 0x4E && buf[7] == 0xAF) || /* LT */ + (buf[6] == 0x5E && buf[7] == 0xAF))) /* DT */ + return; /* filler frame, no data here */ + +#ifdef DEBUG + for (i = 0; i < 8; ++i) + printk(KERN_INFO "%02x ", buf[i]); + printk(KERN_INFO "\n"); +#endif + + if (context->ir_onboard_decode) { + /* The signals have been decoded onboard the iMON controller */ + + if (pad2keys_active) + { + /* imon pad2keys patch + * + * make PAD and mouse buttons available for use with VDR, + * based on pad-mouse-emu patch from venky's forum + * + * last change: M.Brakemeier 2007-10-14 + * + * generated PAD key codes: + * Mouse_N 0x690281B7 + * Mouse_S 0x688291B7 + * Mouse_W 0x6A8281B7 + * Mouse_E 0x688A81B7 + * + * mouse buttons (non-synthetic): + * MouseRightClick 0x688481B7 + * MouseLeftClick 0x688301B7 + */ + if((buf[0] & 0x40) && + !(buf[1] & 0x01 || buf[1] >> 2 & 0x01)) + { + int rel_x = (buf[1] & 0x08) | (buf[1] & 0x10) >> 2 | (buf[1] & 0x20) >> 4 | (buf[1] & 0x40) >> 6; + int rel_y = (buf[2] & 0x08) | (buf[2] & 0x10) >> 2 | (buf[2] & 0x20) >> 4 | (buf[2] & 0x40) >> 6; + + if(buf[0] & 0x02) + rel_x |= ~0x10+1; + if(buf[0] & 0x01) + rel_y |= ~0x10+1; + + /* keyboard direction key emulation */ + if( context->last_count > 32 ) + { /* Hopefully eliminate drift*/ + context->last_count=0; + context->key_y=0; + context->key_x=0; + } + context->last_count++; + + /* limit decoded events */ + if(abs(context->key_x) > CURSOR_LIMIT || abs(context->key_y) > CURSOR_LIMIT ) + { + if(abs(context->key_y ) > abs(context->key_x)) + { /* mouse s/n */ + if(context->key_y > 0 && rel_y > 0) + { /* mouse s */ + buf[0] = 0x68; + buf[1] = 0x82; + buf[2] = 0x91; + } + else if(context->key_y < 0 && rel_y < 0) + { /* mouse n */ + buf[0] = 0x69; + buf[1] = 0x02; + buf[2] = 0x81; + } + } + else + { /* mouse e/w*/ + if(context->key_x > 0 && rel_x > 0 ) + { /* mouse e */ + buf[0] = 0x68; + buf[1] = 0x8A; + buf[2] = 0x81; + } + else if(context->key_x < 0 && rel_x < 0 ) + { /* mouse w */ + buf[0] = 0x6A; + buf[1] = 0x82; + buf[2] = 0x81; + } + } + } + else + { + context->key_x += rel_x; + context->key_y += rel_y; + + return; /* discard those key codes */ + } + } + /* a key was pressed, reset count */ + context->key_x = 0; + context->key_y = 0; + context->last_count = 0; + } + + lirc_buffer_write_1(context->plugin->rbuf, buf); + wake_up(&context->plugin->rbuf->wait_poll); + return; + } + + /* Translate received data to pulse and space lengths. + * Received data is active low, i.e. pulses are 0 and + * spaces are 1. + * + * My original algorithm was essentially similar to + * Changwoo Ryu's with the exception that he switched + * the incoming bits to active high and also fed an + * initial space to LIRC at the start of a new sequence + * if the previous bit was a pulse. + * + * I've decided to adopt his algorithm. */ + + if (chunk_num == 1 && context->rx.initial_space) { + /* LIRC requires a leading space */ + context->rx.prev_bit = 0; + context->rx.count = 4; + submit_data(context); + context->rx.count = 0; + } + + for (octet = 0; octet < 5; ++octet) { + mask = 0x80; + for (bit = 0; bit < 8; ++bit) { + int curr_bit = !(buf[octet] & mask); + if (curr_bit != context->rx.prev_bit) { + if (context->rx.count) { + submit_data(context); + context->rx.count = 0; + } + context->rx.prev_bit = curr_bit; + } + ++context->rx.count; + mask >>= 1; + } + } + + if (chunk_num == 10) { + if (context->rx.count) { + submit_data(context); + context->rx.count = 0; + } + context->rx.initial_space = context->rx.prev_bit; + } +} + +/** + * Callback function for USB core API: receive data + */ +#if defined(KERNEL_2_5) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void usb_rx_callback(struct urb *urb, struct pt_regs *regs) +#else +static void usb_rx_callback(struct urb *urb) +#endif +{ + struct imon_context *context; + + if (!urb) + return; + context = (struct imon_context *) urb->context; + if (!context) + return; + + switch (urb->status) { + case -ENOENT: /* usbcore unlink successful! */ + return; + case SUCCESS: + if (context->ir_isopen) + incoming_packet(context, urb); + break; + default : + warn("%s: status(%d): ignored", __FUNCTION__, urb->status); + break; + } + +#ifdef KERNEL_2_5 + usb_submit_urb(context->rx_urb, GFP_ATOMIC); +#endif + return; +} + + + +/** + * Callback function for USB core API: Probe + */ +#ifdef KERNEL_2_5 +static int imon_probe(struct usb_interface *interface, + const struct usb_device_id *id) +#else +static void *imon_probe(struct usb_device *dev, unsigned int intf, + const struct usb_device_id *id) +#endif +{ +#ifdef KERNEL_2_5 + struct usb_device *dev = NULL; + struct usb_host_interface *iface_desc = NULL; +#else + struct usb_interface *interface = NULL; + struct usb_interface_descriptor *iface_desc = NULL; + char name[10]; + int subminor = 0; +#endif + struct usb_endpoint_descriptor *rx_endpoint = NULL; + struct usb_endpoint_descriptor *tx_endpoint = NULL; + struct urb *rx_urb = NULL; + struct urb *tx_urb = NULL; + struct lirc_plugin *plugin = NULL; + struct lirc_buffer *rbuf = NULL; + int lirc_minor = 0; + int num_endpoints; + int retval = SUCCESS; + int vfd_ep_found; + int ir_ep_found; + int alloc_status; + int vfd_proto_6p = FALSE; + int ir_onboard_decode = FALSE; + struct imon_context *context = NULL; + int i; + + info("%s: found IMON device", __FUNCTION__); + + /* + * If it's the LCD, as opposed to the VFD, we just need to replace + * the "write" file op. + */ + if (is_lcd) + vfd_fops.write = &lcd_write; + +#if !defined(KERNEL_2_5) + for (subminor = 0; subminor < MAX_DEVICES; ++subminor) { + if (minor_table[subminor] == NULL) + break; + } + if (subminor == MAX_DEVICES) { + err("%s: allowed max number of devices already present", + __FUNCTION__); + retval = -ENOMEM; + goto exit; + } +#endif + +#ifdef KERNEL_2_5 + dev = usb_get_dev(interface_to_usbdev(interface)); + iface_desc = interface->cur_altsetting; + num_endpoints = iface_desc->desc.bNumEndpoints; +#else + interface = &dev->actconfig->interface[intf]; + iface_desc = &interface->altsetting[interface->act_altsetting]; + num_endpoints = iface_desc->bNumEndpoints; +#endif + + /* + * Scan the endpoint list and set: + * first input endpoint = IR endpoint + * first output endpoint = VFD endpoint + */ + + ir_ep_found = FALSE; + vfd_ep_found = FALSE; + + for (i = 0; i < num_endpoints && !(ir_ep_found && vfd_ep_found); ++i) { + struct usb_endpoint_descriptor *ep; + int ep_dir; + int ep_type; +#ifdef KERNEL_2_5 + ep = &iface_desc->endpoint[i].desc; +#else + ep = &iface_desc->endpoint[i]; +#endif + ep_dir = ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK; + ep_type = ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; + + if (!ir_ep_found && + ep_dir == USB_DIR_IN && + ep_type == USB_ENDPOINT_XFER_INT) { + + rx_endpoint = ep; + ir_ep_found = TRUE; + if (debug) + info("%s: found IR endpoint", __FUNCTION__); + + } else if (!vfd_ep_found && + ep_dir == USB_DIR_OUT && + ep_type == USB_ENDPOINT_XFER_INT) { + tx_endpoint = ep; + vfd_ep_found = TRUE; + if (debug) + info("%s: found VFD endpoint", __FUNCTION__); + } + } + + /* Input endpoint is mandatory */ + if (!ir_ep_found) { + err("%s: no valid input(IR) endpoint found.", __FUNCTION__); + retval = -ENODEV; + goto exit; + } else { + /* Determine if the IR signals are decoded onboard */ + unsigned short product_id; + unsigned short *id_list_item; + + product_id = cpu_to_le16(dev->descriptor.idProduct); + id_list_item = ir_onboard_decode_product_list; + while (*id_list_item) { + if (*id_list_item++ == product_id) { + ir_onboard_decode = TRUE; + break; + } + } + + if (debug) + info("ir_onboard_decode: %d", ir_onboard_decode); + } + + /* Determine if VFD requires 6 packets */ + if (vfd_ep_found) { + unsigned short vendor_id; + unsigned short *id_list_item; + + vendor_id = cpu_to_le16(dev->descriptor.idVendor); + id_list_item = vfd_proto_6p_vendor_list; + while (*id_list_item) { + if (*id_list_item++ == vendor_id) { + vfd_proto_6p = TRUE; + break; + } + } + + if (debug) + info("vfd_proto_6p: %d", vfd_proto_6p); + } + + + /* Allocate memory */ + + alloc_status = SUCCESS; + + context = kmalloc(sizeof(struct imon_context), GFP_KERNEL); + if (!context) { + err("%s: kmalloc failed for context", __FUNCTION__); + alloc_status = 1; + goto alloc_status_switch; + } + plugin = kmalloc(sizeof(struct lirc_plugin), GFP_KERNEL); + if (!plugin) { + err("%s: kmalloc failed for lirc_plugin", __FUNCTION__); + alloc_status = 2; + goto alloc_status_switch; + } + rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); + if (!rbuf) { + err("%s: kmalloc failed for lirc_buffer", __FUNCTION__); + alloc_status = 3; + goto alloc_status_switch; + } + if (lirc_buffer_init(rbuf, BUF_CHUNK_SIZE, BUF_SIZE)) { + err("%s: lirc_buffer_init failed", __FUNCTION__); + alloc_status = 4; + goto alloc_status_switch; + } +#ifdef KERNEL_2_5 + rx_urb = usb_alloc_urb(0, GFP_KERNEL); +#else + rx_urb = usb_alloc_urb(0); +#endif + if (!rx_urb) { + err("%s: usb_alloc_urb failed for IR urb", __FUNCTION__); + alloc_status = 5; + goto alloc_status_switch; + } + if (vfd_ep_found) { +#ifdef KERNEL_2_5 + tx_urb = usb_alloc_urb(0, GFP_KERNEL); +#else + tx_urb = usb_alloc_urb(0); +#endif + if (!tx_urb) { + err("%s: usb_alloc_urb failed for VFD urb", + __FUNCTION__); + alloc_status = 6; + goto alloc_status_switch; + } + } + + /* clear all members of imon_context and lirc_plugin */ + memset(context, 0, sizeof(struct imon_context)); + init_MUTEX(&context->sem); + context->vfd_proto_6p = vfd_proto_6p; + context->ir_onboard_decode = ir_onboard_decode; + + memset(plugin, 0, sizeof(struct lirc_plugin)); + + strcpy(plugin->name, MOD_NAME); + plugin->minor = -1; + plugin->code_length = (ir_onboard_decode) ? + 32 : sizeof(lirc_t) * 8; + plugin->sample_rate = 0; + plugin->features = (ir_onboard_decode) ? + LIRC_CAN_REC_LIRCCODE : LIRC_CAN_REC_MODE2; + plugin->data = context; + plugin->rbuf = rbuf; + plugin->set_use_inc = ir_open; + plugin->set_use_dec = ir_close; +#ifdef LIRC_HAVE_SYSFS + plugin->dev = &dev->dev; +#endif + plugin->owner = THIS_MODULE; + + LOCK_CONTEXT; + + lirc_minor = lirc_register_plugin(plugin); + if (lirc_minor < 0) { + err("%s: lirc_register_plugin failed", __FUNCTION__); + alloc_status = 7; + UNLOCK_CONTEXT; + goto alloc_status_switch; + } else + info("%s: Registered iMON plugin(minor:%d)", + __FUNCTION__, lirc_minor); + +alloc_status_switch: + + switch (alloc_status) { + case 7: + if (vfd_ep_found) + usb_free_urb(tx_urb); + case 6: + usb_free_urb(rx_urb); + case 5: + lirc_buffer_free(rbuf); + case 4: + kfree(rbuf); + case 3: + kfree(plugin); + case 2: + kfree(context); + context = NULL; + case 1: + retval = -ENOMEM; + } + + /* Needed while unregistering! */ + plugin->minor = lirc_minor; + + context->dev = dev; + context->dev_present = TRUE; + context->rx_endpoint = rx_endpoint; + context->rx_urb = rx_urb; + if (vfd_ep_found) { + context->vfd_supported = TRUE; + context->tx_endpoint = tx_endpoint; + context->tx_urb = tx_urb; + } + context->plugin = plugin; + +#ifdef KERNEL_2_5 + usb_set_intfdata(interface, context); + + if (cpu_to_le16(dev->descriptor.idProduct) == 0xffdc) { + int err; + + err = sysfs_create_group(&interface->dev.kobj, + &imon_attribute_group); + if (err) + err("%s: Could not create sysfs entries(%d)", + __FUNCTION__, err); + } +#else + minor_table[subminor] = context; + context->subminor = subminor; +#endif + + if (vfd_ep_found) { + if (debug) + info("Registering VFD with devfs"); +#ifdef KERNEL_2_5 + if (usb_register_dev(interface, &imon_class)) { + /* Not a fatal error, so ignore */ + info("%s: could not get a minor number for VFD", + __FUNCTION__); + } +#else + sprintf(name, DEVFS_NAME, subminor); + if (!(context->devfs = devfs_register(usb_devfs_handle, name, + DEVFS_FL_DEFAULT, + USB_MAJOR, VFD_MINOR_BASE + subminor, + DEVFS_MODE, &vfd_fops, NULL))) { + /* not a fatal error so ignore */ + info("%s: devfs register failed for VFD", + __FUNCTION__); + } +#endif + } + + info("%s: iMON device on usb<%d:%d> initialized", + __FUNCTION__, dev->bus->busnum, dev->devnum); + + UNLOCK_CONTEXT; + + exit: +#ifdef KERNEL_2_5 + return retval; +#else + return (retval == SUCCESS) ? context : NULL; +#endif +} + +/** + * Callback function for USB core API: disonnect + */ +#ifdef KERNEL_2_5 +static void imon_disconnect(struct usb_interface *interface) +#else +static void imon_disconnect(struct usb_device *dev, void *data) +#endif +{ + struct imon_context *context; + + /* prevent races with ir_open()/vfd_open() */ + down(&disconnect_sem); + +#ifdef KERNEL_2_5 + context = usb_get_intfdata(interface); +#else + context = (struct imon_context *)data; +#endif + LOCK_CONTEXT; + + info("%s: iMON device disconnected", __FUNCTION__); + +#ifdef KERNEL_2_5 + /* sysfs_remove_group is safe to call even if sysfs_create_group + * hasn't been called */ + sysfs_remove_group(&interface->dev.kobj, + &imon_attribute_group); + usb_set_intfdata(interface, NULL); +#else + minor_table[context->subminor] = NULL; +#endif + context->dev_present = FALSE; + + /* Stop reception */ + usb_kill_urb(context->rx_urb); + + /* Abort ongoing write */ + if (atomic_read(&context->tx.busy)) { + usb_kill_urb(context->tx_urb); + wait_for_completion(&context->tx.finished); + } + + /* De-register from lirc_dev if IR port is not open */ + if (!context->ir_isopen) + deregister_from_lirc(context); + + if (context->vfd_supported) +#ifdef KERNEL_2_5 + usb_deregister_dev(interface, &imon_class); +#else + if (context->devfs) + devfs_unregister(context->devfs); +#endif + + UNLOCK_CONTEXT; + + if (!context->ir_isopen && !context->vfd_isopen) + delete_context(context); + + up(&disconnect_sem); +} + +static int __init imon_init(void) +{ + int rc; + + info(MOD_DESC ", v" MOD_VERSION); + info(MOD_AUTHOR); + + rc = usb_register(&imon_driver); + if (rc) { + err("%s: usb register failed(%d)", __FUNCTION__, rc); + return -ENODEV; + } + return SUCCESS; +} + +static void __exit imon_exit(void) +{ + usb_deregister(&imon_driver); + info("module removed. Goodbye!"); +} + + +module_init(imon_init); +module_exit(imon_exit); + +#if !defined(KERNEL_2_5) +EXPORT_NO_SYMBOLS; +#endif --- linux-2.6.28.orig/ubuntu/lirc/lirc_imon/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_imon/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_IMON) += lirc_imon.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_serial_igor/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_serial_igor/Makefile @@ -0,0 +1,4 @@ + +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_SERIAL_IGOR) += lirc_serial_igor.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_serial_igor/lirc_serial_igor.c +++ linux-2.6.28/ubuntu/lirc/lirc_serial_igor/lirc_serial_igor.c @@ -0,0 +1,1341 @@ +/* $Id: lirc_serial.c,v 5.87 2007/12/15 17:28:01 lirc Exp $ */ + +/**************************************************************************** + ** lirc_serial.c *********************************************************** + **************************************************************************** + * + * lirc_serial - Device driver that records pulse- and pause-lengths + * (space-lengths) between DDCD event on a serial port. + * + * Copyright (C) 1996,97 Ralph Metzler + * Copyright (C) 1998 Trent Piepho + * Copyright (C) 1998 Ben Pfaff + * Copyright (C) 1999 Christoph Bartelmus + * Copyright (C) 2007 Andrei Tanas (suspend/resume support) + * Copyright (C) 2007 Mario Limonciello Compile for Ubuntu with igor support + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You 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 + * + */ + +/* Steve's changes to improve transmission fidelity: + - for systems with the rdtsc instruction and the clock counter, a + send_pule that times the pulses directly using the counter. + This means that the LIRC_SERIAL_TRANSMITTER_LATENCY fudge is + not needed. Measurement shows very stable waveform, even where + PCI activity slows the access to the UART, which trips up other + versions. + - For other system, non-integer-microsecond pulse/space lengths, + done using fixed point binary. So, much more accurate carrier + frequency. + - fine tuned transmitter latency, taking advantage of fractional + microseconds in previous change + - Fixed bug in the way transmitter latency was accounted for by + tuning the pulse lengths down - the send_pulse routine ignored + this overhead as it timed the overall pulse length - so the + pulse frequency was right but overall pulse length was too + long. Fixed by accounting for latency on each pulse/space + iteration. + + Steve Davies July 2001 +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18) +#error "**********************************************************" +#error " Sorry, this driver needs kernel version 2.2.18 or higher " +#error "**********************************************************" +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) +#include +#endif + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#include +#else +#include +#endif +#include +#include +#include + +#if defined(LIRC_SERIAL_NSLU2) +#include +/* From Intel IXP42X Developer's Manual (#252480-005): */ +/* ftp://download.intel.com/design/network/manuals/25248005.pdf */ +#define UART_IE_IXP42X_UUE 0x40 /* IXP42X UART Unit enable */ +#define UART_IE_IXP42X_RTOIE 0x10 /* IXP42X Receiver Data Timeout int.enable */ +#ifndef NSLU2_LED_GRN_GPIO +/* added in 2.6.22 */ +#define NSLU2_LED_GRN_GPIO NSLU2_LED_GRN +#endif +#endif + +#include "lirc.h" +#include "kcompat.h" +#include "lirc_dev/lirc_dev.h" + +#if defined(LIRC_SERIAL_SOFTCARRIER) && !defined(LIRC_SERIAL_TRANSMITTER) +#warning "Software carrier only affects transmitting" +#endif + +#if defined(rdtscl) + +#define USE_RDTSC +#warning "Note: using rdtsc instruction" +#endif + +#ifdef LIRC_SERIAL_ANIMAX +#ifdef LIRC_SERIAL_TRANSMITTER +#warning "******************************************" +#warning " This receiver does not have a " +#warning " transmitter diode " +#warning "******************************************" +#endif +#endif + +#define LIRC_DRIVER_NAME "lirc_serial_igor" + +struct lirc_serial_igor +{ + int signal_pin; + int signal_pin_change; + int on; + int off; + long (*send_pulse)(unsigned long length); + void (*send_space)(long length); + int features; +}; + +#define LIRC_HOMEBREW 0 +#define LIRC_IRDEO 1 +#define LIRC_IRDEO_REMOTE 2 +#define LIRC_ANIMAX 3 +#define LIRC_IGOR 4 +#define LIRC_NSLU2 5 + +static int type = LIRC_IGOR; + +/* Set defaults for NSLU2 */ +#if defined(LIRC_SERIAL_NSLU2) +#ifndef LIRC_IRQ +#define LIRC_IRQ IRQ_IXP4XX_UART2 +#endif +#ifndef LIRC_PORT +#define LIRC_PORT (IXP4XX_UART2_BASE_VIRT + REG_OFFSET) +#endif +#ifndef LIRC_IOMMAP +#define LIRC_IOMMAP IXP4XX_UART2_BASE_PHYS +#endif +#ifndef LIRC_IOSHIFT +#define LIRC_IOSHIFT 2 +#endif +#ifndef LIRC_ALLOW_MMAPPED_IO +#define LIRC_ALLOW_MMAPPED_IO +#endif +#endif + +#if defined(LIRC_ALLOW_MMAPPED_IO) +#ifndef LIRC_IOMMAP +#define LIRC_IOMMAP 0 +#endif +#ifndef LIRC_IOSHIFT +#define LIRC_IOSHIFT 0 +#endif +static int iommap = LIRC_IOMMAP; +static int ioshift = LIRC_IOSHIFT; +#endif + +static int softcarrier; + +static int share_irq; +static int debug; + +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \ + fmt, ## args); \ + } while (0) + +/* forward declarations */ +static long send_pulse_irdeo(unsigned long length); +static long send_pulse_homebrew(unsigned long length); +static void send_space_irdeo(long length); +static void send_space_homebrew(long length); + +static struct lirc_serial_igor hardware[] = { + /* home-brew receiver/transmitter */ + { + UART_MSR_DCD, + UART_MSR_DDCD, + UART_MCR_RTS|UART_MCR_OUT2|UART_MCR_DTR, + UART_MCR_RTS|UART_MCR_OUT2, + send_pulse_homebrew, + send_space_homebrew, + ( +#ifdef LIRC_SERIAL_TRANSMITTER + LIRC_CAN_SET_SEND_DUTY_CYCLE| + LIRC_CAN_SET_SEND_CARRIER| + LIRC_CAN_SEND_PULSE| +#endif + LIRC_CAN_REC_MODE2) + }, + + /* IRdeo classic */ + { + UART_MSR_DSR, + UART_MSR_DDSR, + UART_MCR_OUT2, + UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2, + send_pulse_irdeo, + send_space_irdeo, + (LIRC_CAN_SET_SEND_DUTY_CYCLE| + LIRC_CAN_SEND_PULSE| + LIRC_CAN_REC_MODE2) + }, + + /* IRdeo remote */ + { + UART_MSR_DSR, + UART_MSR_DDSR, + UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2, + UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2, + send_pulse_irdeo, + send_space_irdeo, + (LIRC_CAN_SET_SEND_DUTY_CYCLE| + LIRC_CAN_SEND_PULSE| + LIRC_CAN_REC_MODE2) + }, + + /* AnimaX */ + { + UART_MSR_DCD, + UART_MSR_DDCD, + 0, + UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2, + NULL, + NULL, + LIRC_CAN_REC_MODE2 + }, + + /* home-brew receiver/transmitter (Igor Cesko's variation) */ + { + UART_MSR_DSR, + UART_MSR_DDSR, + UART_MCR_RTS|UART_MCR_OUT2|UART_MCR_DTR, + UART_MCR_RTS|UART_MCR_OUT2, + send_pulse_homebrew, + send_space_homebrew, + ( +#ifdef LIRC_SERIAL_TRANSMITTER + LIRC_CAN_SET_SEND_DUTY_CYCLE| + LIRC_CAN_SET_SEND_CARRIER| + LIRC_CAN_SEND_PULSE| +#endif + LIRC_CAN_REC_MODE2) + }, + +#if defined(LIRC_SERIAL_NSLU2) + /* Modified Linksys Network Storage Link USB 2.0 (NSLU2): + We receive on CTS of the 2nd serial port (R142,LHS), we + transmit with a IR diode between GPIO[1] (green status LED), + and ground (Matthias Goebl ). + See also http://www.nslu2-linux.org for this device */ + { + UART_MSR_CTS, + UART_MSR_DCTS, + UART_MCR_RTS|UART_MCR_OUT2|UART_MCR_DTR, + UART_MCR_RTS|UART_MCR_OUT2, + send_pulse_homebrew, + send_space_homebrew, + ( +#ifdef LIRC_SERIAL_TRANSMITTER + LIRC_CAN_SET_SEND_DUTY_CYCLE| + LIRC_CAN_SET_SEND_CARRIER| + LIRC_CAN_SEND_PULSE| +#endif + LIRC_CAN_REC_MODE2) + }, +#endif + +}; + +#define RS_ISR_PASS_LIMIT 256 + +/* A long pulse code from a remote might take upto 300 bytes. The + daemon should read the bytes as soon as they are generated, so take + the number of keys you think you can push before the daemon runs + and multiply by 300. The driver will warn you if you overrun this + buffer. If you have a slow computer or non-busmastering IDE disks, + maybe you will need to increase this. */ + +/* This MUST be a power of two! It has to be larger than 1 as well. */ + +#define RBUF_LEN 256 +#define WBUF_LEN 256 + +static int sense = -1; /* -1 = auto, 0 = active high, 1 = active low */ +static int txsense; /* 0 = active high, 1 = active low */ + +#ifndef LIRC_IRQ +#define LIRC_IRQ 4 +#endif +#ifndef LIRC_PORT +#define LIRC_PORT 0x3f8 +#endif + +static int io = LIRC_PORT; +static int irq = LIRC_IRQ; + +static struct timeval lasttv = {0, 0}; + +static struct lirc_buffer rbuf; + +static lirc_t wbuf[WBUF_LEN]; + +static unsigned int freq = 38000; +static unsigned int duty_cycle = 50; + +/* Initialized in init_timing_params() */ +static unsigned long period; +static unsigned long pulse_width; +static unsigned long space_width; + +#if defined(__i386__) +/* + From: + Linux I/O port programming mini-HOWTO + Author: Riku Saikkonen + v, 28 December 1997 + + [...] + Actually, a port I/O instruction on most ports in the 0-0x3ff range + takes almost exactly 1 microsecond, so if you're, for example, using + the parallel port directly, just do additional inb()s from that port + to delay. + [...] +*/ +/* transmitter latency 1.5625us 0x1.90 - this figure arrived at from + * comment above plus trimming to match actual measured frequency. + * This will be sensitive to cpu speed, though hopefully most of the 1.5us + * is spent in the uart access. Still - for reference test machine was a + * 1.13GHz Athlon system - Steve + */ + +/* changed from 400 to 450 as this works better on slower machines; + faster machines will use the rdtsc code anyway */ + +#define LIRC_SERIAL_TRANSMITTER_LATENCY 450 + +#else + +/* does anybody have information on other platforms ? */ +/* 256 = 1<<8 */ +#define LIRC_SERIAL_TRANSMITTER_LATENCY 256 + +#endif /* __i386__ */ + +static inline unsigned int sinp(int offset) +{ +#if defined(LIRC_ALLOW_MMAPPED_IO) + if (iommap != 0) { /* the register is memory-mapped */ + offset <<= ioshift; + return readb(io + offset); + } +#endif + return inb(io + offset); +} + +static inline void soutp(int offset, int value) +{ +#if defined(LIRC_ALLOW_MMAPPED_IO) + if (iommap != 0) { /* the register is memory-mapped */ + offset <<= ioshift; + writeb(value, io + offset); + } +#endif + outb(value, io + offset); +} + +static inline void on(void) +{ +#if defined(LIRC_SERIAL_NSLU2) + /* On NSLU2, we put the transmit diode between the output of the green + status LED and ground */ + if (type == LIRC_NSLU2) { + gpio_line_set(NSLU2_LED_GRN_GPIO, IXP4XX_GPIO_LOW); + return; + } +#endif + if (txsense) + soutp(UART_MCR, hardware[type].off); + else + soutp(UART_MCR, hardware[type].on); +} + +static inline void off(void) +{ +#if defined(LIRC_SERIAL_NSLU2) + if (type == LIRC_NSLU2) { + gpio_line_set(NSLU2_LED_GRN_GPIO, IXP4XX_GPIO_HIGH); + return; + } +#endif + if (txsense) + soutp(UART_MCR, hardware[type].on); + else + soutp(UART_MCR, hardware[type].off); +} + +#ifndef MAX_UDELAY_MS +#define MAX_UDELAY_US 5000 +#else +#define MAX_UDELAY_US (MAX_UDELAY_MS*1000) +#endif + +static inline void safe_udelay(unsigned long usecs) +{ + while (usecs > MAX_UDELAY_US) { + udelay(MAX_UDELAY_US); + usecs -= MAX_UDELAY_US; + } + udelay(usecs); +} + +#ifdef USE_RDTSC +/* This is an overflow/precision juggle, complicated in that we can't + do long long divide in the kernel */ + +/* When we use the rdtsc instruction to measure clocks, we keep the + * pulse and space widths as clock cycles. As this is CPU speed + * dependent, the widths must be calculated in init_port and ioctl + * time + */ + +/* So send_pulse can quickly convert microseconds to clocks */ +static unsigned long conv_us_to_clocks; + +static inline int init_timing_params(unsigned int new_duty_cycle, + unsigned int new_freq) +{ + unsigned long long loops_per_sec, work; + + duty_cycle = new_duty_cycle; + freq = new_freq; + + loops_per_sec = current_cpu_data.loops_per_jiffy; + loops_per_sec *= HZ; + + /* How many clocks in a microsecond?, avoiding long long divide */ + work = loops_per_sec; + work *= 4295; /* 4295 = 2^32 / 1e6 */ + conv_us_to_clocks = (work>>32); + + /* Carrier period in clocks, approach good up to 32GHz clock, + gets carrier frequency within 8Hz */ + period = loops_per_sec>>3; + period /= (freq>>3); + + /* Derive pulse and space from the period */ + + pulse_width = period*duty_cycle/100; + space_width = period - pulse_width; + dprintk("in init_timing_params, freq=%d, duty_cycle=%d, " + "clk/jiffy=%ld, pulse=%ld, space=%ld, " + "conv_us_to_clocks=%ld\n", + freq, duty_cycle, current_cpu_data.loops_per_jiffy, + pulse_width, space_width, conv_us_to_clocks); + return 0; +} +#else /* ! USE_RDTSC */ +static inline int init_timing_params(unsigned int new_duty_cycle, + unsigned int new_freq) +{ +/* period, pulse/space width are kept with 8 binary places - + * IE multiplied by 256. */ + if (256*1000000L/new_freq*new_duty_cycle/100 <= + LIRC_SERIAL_TRANSMITTER_LATENCY) + return(-EINVAL); + if (256*1000000L/new_freq*(100-new_duty_cycle)/100 <= + LIRC_SERIAL_TRANSMITTER_LATENCY) + return(-EINVAL); + duty_cycle = new_duty_cycle; + freq = new_freq; + period = 256*1000000L/freq; + pulse_width = period*duty_cycle/100; + space_width = period-pulse_width; + dprintk("in init_timing_params, freq=%d pulse=%ld, " + "space=%ld\n", freq, pulse_width, space_width); + return 0; +} +#endif /* USE_RDTSC */ + + +/* return value: space length delta */ + +static long send_pulse_irdeo(unsigned long length) +{ + long rawbits; + int i; + unsigned char output; + unsigned char chunk, shifted; + + /* how many bits have to be sent ? */ + rawbits = length*1152/10000; + if (duty_cycle > 50) + chunk = 3; + else + chunk = 1; + for (i = 0, output = 0x7f; rawbits > 0; rawbits -= 3) { + shifted = chunk<<(i*3); + shifted >>= 1; + output &= (~shifted); + i++; + if (i == 3) { + soutp(UART_TX, output); + while (!(sinp(UART_LSR) & UART_LSR_THRE)); + output = 0x7f; + i = 0; + } + } + if (i != 0) { + soutp(UART_TX, output); + while (!(sinp(UART_LSR) & UART_LSR_TEMT)); + } + + if (i == 0) + return ((-rawbits)*10000/1152); + else + return ((3-i)*3*10000/1152+(-rawbits)*10000/1152); +} + +#ifdef USE_RDTSC +/* Version that uses Pentium rdtsc instruction to measure clocks */ + +/* This version does sub-microsecond timing using rdtsc instruction, + * and does away with the fudged LIRC_SERIAL_TRANSMITTER_LATENCY + * Implicitly i586 architecture... - Steve + */ + +static inline long send_pulse_homebrew_softcarrier(unsigned long length) +{ + int flag; + unsigned long target, start, now; + + /* Get going quick as we can */ + rdtscl(start); on(); + /* Convert length from microseconds to clocks */ + length *= conv_us_to_clocks; + /* And loop till time is up - flipping at right intervals */ + now = start; + target = pulse_width; + flag = 1; + while ((now-start) < length) { + /* Delay till flip time */ + do + rdtscl(now); + while ((now-start) < target); + + /* flip */ + if (flag) { + rdtscl(now); off(); + target += space_width; + } else { + rdtscl(now); on(); + target += pulse_width; + } + flag = !flag; + } + rdtscl(now); + return (((now-start)-length)/conv_us_to_clocks); +} +#else /* ! USE_RDTSC */ +/* Version using udelay() */ + +/* here we use fixed point arithmetic, with 8 + fractional bits. that gets us within 0.1% or so of the right average + frequency, albeit with some jitter in pulse length - Steve */ + +/* To match 8 fractional bits used for pulse/space length */ + +static inline long send_pulse_homebrew_softcarrier(unsigned long length) +{ + int flag; + unsigned long actual, target, d; + length <<= 8; + + actual = 0; target = 0; flag = 0; + while (actual < length) { + if (flag) { + off(); + target += space_width; + } else { + on(); + target += pulse_width; + } + d = (target-actual-LIRC_SERIAL_TRANSMITTER_LATENCY+128)>>8; + /* Note - we've checked in ioctl that the pulse/space + widths are big enough so that d is > 0 */ + udelay(d); + actual += (d<<8)+LIRC_SERIAL_TRANSMITTER_LATENCY; + flag = !flag; + } + return ((actual-length)>>8); +} +#endif /* USE_RDTSC */ + +static long send_pulse_homebrew(unsigned long length) +{ + if (length <= 0) + return 0; + + if (softcarrier) + return send_pulse_homebrew_softcarrier(length); + else { + on(); + safe_udelay(length); + return 0; + } +} + +static void send_space_irdeo(long length) +{ + if (length <= 0) + return; + + safe_udelay(length); +} + +static void send_space_homebrew(long length) +{ + off(); + if (length <= 0) + return; + safe_udelay(length); +} + +static inline void rbwrite(lirc_t l) +{ + if (lirc_buffer_full(&rbuf)) { /* no new signals will be accepted */ + dprintk("Buffer overrun\n"); + return; + } + _lirc_buffer_write_1(&rbuf, (void *)&l); +} + +static inline void frbwrite(lirc_t l) +{ + /* simple noise filter */ + static lirc_t pulse = 0L, space = 0L; + static unsigned int ptr; + + if (ptr > 0 && (l&PULSE_BIT)) { + pulse += l&PULSE_MASK; + if (pulse > 250) { + rbwrite(space); + rbwrite(pulse|PULSE_BIT); + ptr = 0; + pulse = 0; + } + return; + } + if (!(l&PULSE_BIT)) { + if (ptr == 0) { + if (l > 20000) { + space = l; + ptr++; + return; + } + } else { + if (l > 20000) { + space += pulse; + if (space > PULSE_MASK) + space = PULSE_MASK; + space += l; + if (space > PULSE_MASK) + space = PULSE_MASK; + pulse = 0; + return; + } + rbwrite(space); + rbwrite(pulse|PULSE_BIT); + ptr = 0; + pulse = 0; + } + } + rbwrite(l); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) +static irqreturn_t irq_handler(int i, void *blah) +#else +static irqreturn_t irq_handler(int i, void *blah, struct pt_regs *regs) +#endif +{ + struct timeval tv; + int status, counter, dcd; + long deltv; + lirc_t data; + static int last_dcd = -1; + + if ((sinp(UART_IIR) & UART_IIR_NO_INT)) { + /* not our interrupt */ + return IRQ_RETVAL(IRQ_NONE); + } + + counter = 0; + do { + counter++; + status = sinp(UART_MSR); + if (counter > RS_ISR_PASS_LIMIT) { + printk(KERN_WARNING LIRC_DRIVER_NAME ": AIEEEE: " + "We're caught!\n"); + break; + } + if ((status&hardware[type].signal_pin_change) && sense != -1) { + /* get current time */ + do_gettimeofday(&tv); + + /* New mode, written by Trent Piepho + . */ + + /* The old format was not very portable. + We now use the type lirc_t to pass pulses + and spaces to user space. + + If PULSE_BIT is set a pulse has been + received, otherwise a space has been + received. The driver needs to know if your + receiver is active high or active low, or + the space/pulse sense could be + inverted. The bits denoted by PULSE_MASK are + the length in microseconds. Lengths greater + than or equal to 16 seconds are clamped to + PULSE_MASK. All other bits are unused. + This is a much simpler interface for user + programs, as well as eliminating "out of + phase" errors with space/pulse + autodetection. */ + + /* calculate time since last interrupt in + microseconds */ + dcd = (status & hardware[type].signal_pin) ? 1:0; + + if (dcd == last_dcd) { + printk(KERN_WARNING LIRC_DRIVER_NAME + ": ignoring spike: %d %d %lx %lx %lx %lx\n", + dcd, sense, + tv.tv_sec, lasttv.tv_sec, + tv.tv_usec, lasttv.tv_usec); + continue; + } + + deltv = tv.tv_sec-lasttv.tv_sec; + if (tv.tv_sec < lasttv.tv_sec || + (tv.tv_sec == lasttv.tv_sec && + tv.tv_usec < lasttv.tv_usec)) { + printk(KERN_WARNING LIRC_DRIVER_NAME + ": AIEEEE: your clock just jumped " + "backwards\n"); + printk(KERN_WARNING LIRC_DRIVER_NAME + ": %d %d %lx %lx %lx %lx\n", + dcd, sense, + tv.tv_sec, lasttv.tv_sec, + tv.tv_usec, lasttv.tv_usec); + data = PULSE_MASK; + } else if (deltv > 15) { + data = PULSE_MASK; /* really long time */ + if (!(dcd^sense)) { /* sanity check */ + printk(KERN_WARNING LIRC_DRIVER_NAME + ": AIEEEE: " + "%d %d %lx %lx %lx %lx\n", + dcd, sense, + tv.tv_sec, lasttv.tv_sec, + tv.tv_usec, lasttv.tv_usec); + /* detecting pulse while this + MUST be a space! */ + sense = sense ? 0:1; + } + } else + data = (lirc_t) (deltv*1000000 + + tv.tv_usec - + lasttv.tv_usec); + frbwrite(dcd^sense ? data : (data|PULSE_BIT)); + lasttv = tv; + last_dcd = dcd; + wake_up_interruptible(&rbuf.wait_poll); + } + } while (!(sinp(UART_IIR) & UART_IIR_NO_INT)); /* still pending ? */ + return IRQ_RETVAL(IRQ_HANDLED); +} + +static void hardware_init_port(void) +{ + unsigned long flags; + local_irq_save(flags); + + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + /* First of all, disable all interrupts */ + soutp(UART_IER, sinp(UART_IER) & + (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); + + /* Clear registers. */ + sinp(UART_LSR); + sinp(UART_RX); + sinp(UART_IIR); + sinp(UART_MSR); + +#if defined(LIRC_SERIAL_NSLU2) + if (type == LIRC_NSLU2) { /* Setup NSLU2 UART */ + /* Enable UART */ + soutp(UART_IER, sinp(UART_IER) | UART_IE_IXP42X_UUE); + /* Disable Receiver data Time out interrupt */ + soutp(UART_IER, sinp(UART_IER) & ~UART_IE_IXP42X_RTOIE); + /* set out2 = interupt unmask; off() doesn't set MCR + on NSLU2 */ + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_OUT2); + } +#endif + + /* Set line for power source */ + off(); + + /* Clear registers again to be sure. */ + sinp(UART_LSR); + sinp(UART_RX); + sinp(UART_IIR); + sinp(UART_MSR); + + switch (type) { + case LIRC_IRDEO: + case LIRC_IRDEO_REMOTE: + /* setup port to 7N1 @ 115200 Baud */ + /* 7N1+start = 9 bits at 115200 ~ 3 bits at 38kHz */ + + /* Set DLAB 1. */ + soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB); + /* Set divisor to 1 => 115200 Baud */ + soutp(UART_DLM, 0); + soutp(UART_DLL, 1); + /* Set DLAB 0 + 7N1 */ + soutp(UART_LCR, UART_LCR_WLEN7); + /* THR interrupt already disabled at this point */ + break; + default: + break; + } + + local_irq_restore(flags); +} + +static int init_port(void) +{ + int i, nlow, nhigh; + + /* Reserve io region. */ +#if defined(LIRC_ALLOW_MMAPPED_IO) + /* Future MMAP-Developers: Attention! + For memory mapped I/O you *might* need to use ioremap() first, + for the NSLU2 it's done in boot code. */ + if (((iommap != 0) + && (request_mem_region(iommap, 8<= nhigh ? 1 : 0); + printk(KERN_INFO LIRC_DRIVER_NAME ": auto-detected active " + "%s receiver\n", sense ? "low":"high"); + } else + printk(KERN_INFO LIRC_DRIVER_NAME ": Manually using active " + "%s receiver\n", sense ? "low":"high"); + + return 0; +} + +static int set_use_inc(void *data) +{ + int result; + unsigned long flags; + + /* Init read buffer. */ + if (lirc_buffer_init(&rbuf, sizeof(lirc_t), RBUF_LEN) < 0) + return -ENOMEM; + + /* initialize timestamp */ + do_gettimeofday(&lasttv); + + result = request_irq(irq, irq_handler, + IRQF_DISABLED | (share_irq ? IRQF_SHARED:0), + LIRC_DRIVER_NAME, (void *)&hardware); + + switch (result) { + case -EBUSY: + printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", irq); + lirc_buffer_free(&rbuf); + return -EBUSY; + case -EINVAL: + printk(KERN_ERR LIRC_DRIVER_NAME + ": Bad irq number or handler\n"); + lirc_buffer_free(&rbuf); + return -EINVAL; + default: + dprintk("Interrupt %d, port %04x obtained\n", irq, io); + break; + }; + + local_irq_save(flags); + + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + soutp(UART_IER, sinp(UART_IER)|UART_IER_MSI); + + local_irq_restore(flags); + + MOD_INC_USE_COUNT; + return 0; +} + +static void set_use_dec(void *data) +{ unsigned long flags; + + local_irq_save(flags); + + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + /* First of all, disable all interrupts */ + soutp(UART_IER, sinp(UART_IER) & + (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); + local_irq_restore(flags); + + free_irq(irq, (void *)&hardware); + + dprintk("freed IRQ %d\n", irq); + lirc_buffer_free(&rbuf); + + MOD_DEC_USE_COUNT; +} + +static ssize_t lirc_write(struct file *file, const char *buf, + size_t n, loff_t *ppos) +{ + int i, count; + unsigned long flags; + long delta = 0; + + if (!(hardware[type].features&LIRC_CAN_SEND_PULSE)) + return(-EBADF); + + if (n%sizeof(lirc_t)) return(-EINVAL); + count = n/sizeof(lirc_t); + if (count > WBUF_LEN || count%2 == 0) return(-EINVAL); + if (copy_from_user(wbuf, buf, n)) return -EFAULT; + local_irq_save(flags); + if (type == LIRC_IRDEO) { + /* DTR, RTS down */ + on(); + } + for (i = 0; i < count; i++) { + if (i%2) + hardware[type].send_space(wbuf[i]-delta); + else + delta = hardware[type].send_pulse(wbuf[i]); + } + off(); + local_irq_restore(flags); + return(n); +} + +static int lirc_ioctl(struct inode *node, struct file *filep, unsigned int cmd, + unsigned long arg) +{ + int result; + unsigned long value; + unsigned int ivalue; + + switch (cmd) { + case LIRC_GET_SEND_MODE: + if (!(hardware[type].features&LIRC_CAN_SEND_MASK)) + return(-ENOIOCTLCMD); + + result = put_user(LIRC_SEND2MODE + (hardware[type].features&LIRC_CAN_SEND_MASK), + (unsigned long *) arg); + if (result) + return result; + break; + + case LIRC_SET_SEND_MODE: + if (!(hardware[type].features&LIRC_CAN_SEND_MASK)) + return(-ENOIOCTLCMD); + + result = get_user(value, (unsigned long *) arg); + if (result) + return result; + /* only LIRC_MODE_PULSE supported */ + if (value != LIRC_MODE_PULSE) + return -ENOSYS; + break; + + case LIRC_GET_LENGTH: + return -ENOSYS; + break; + + case LIRC_SET_SEND_DUTY_CYCLE: + dprintk("SET_SEND_DUTY_CYCLE\n"); + if (!(hardware[type].features&LIRC_CAN_SET_SEND_DUTY_CYCLE)) + return -ENOIOCTLCMD; + + result = get_user(ivalue, (unsigned int *) arg); + if (result) + return result; + if (ivalue <= 0 || ivalue > 100) + return -EINVAL; + return init_timing_params(ivalue, freq); + break; + + case LIRC_SET_SEND_CARRIER: + dprintk("SET_SEND_CARRIER\n"); + if (!(hardware[type].features&LIRC_CAN_SET_SEND_CARRIER)) + return -ENOIOCTLCMD; + + result = get_user(ivalue, (unsigned int *) arg); + if (result) + return result; + if (ivalue > 500000 || ivalue < 20000) + return -EINVAL; + return init_timing_params(duty_cycle, ivalue); + break; + + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static struct file_operations lirc_fops = { + .write = lirc_write, +}; + +static struct lirc_plugin plugin = { + .name = LIRC_DRIVER_NAME, + .minor = -1, + .code_length = 1, + .sample_rate = 0, + .data = NULL, + .add_to_buf = NULL, + .get_queue = NULL, + .rbuf = &rbuf, + .set_use_inc = set_use_inc, + .set_use_dec = set_use_dec, + .ioctl = lirc_ioctl, + .fops = &lirc_fops, + .dev = NULL, + .owner = THIS_MODULE, +}; + +#ifdef MODULE + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) +static struct platform_device *lirc_serial_igor_dev; + +static int __devinit lirc_serial_igor_probe(struct platform_device *dev) +{ + return 0; +} + +static int __devexit lirc_serial_igor_remove(struct platform_device * dev) +{ + return 0; +} + +static int lirc_serial_igor_suspend(struct platform_device *dev, + pm_message_t state) +{ + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + /* Disable all interrupts */ + soutp(UART_IER, sinp(UART_IER) & + (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); + + /* Clear registers. */ + sinp(UART_LSR); + sinp(UART_RX); + sinp(UART_IIR); + sinp(UART_MSR); + + return 0; +} + +static int lirc_serial_igor_resume(struct platform_device *dev) +{ + unsigned long flags; + + hardware_init_port(); + + local_irq_save(flags); + /* Enable Interrupt */ + do_gettimeofday(&lasttv); + soutp(UART_IER, sinp(UART_IER)|UART_IER_MSI); + off(); + + lirc_buffer_clear(&rbuf); + + local_irq_restore(flags); + + return 0; +} + +static struct platform_driver lirc_serial_igor_driver = { + .probe = lirc_serial_igor_probe, + .remove = __devexit_p(lirc_serial_igor_remove), + .suspend = lirc_serial_igor_suspend, + .resume = lirc_serial_igor_resume, + .driver = { + .name = "lirc_serial_igor", + .owner = THIS_MODULE, + }, +}; + +static int __init lirc_serial_igor_init(void) +{ + int result; + + result = platform_driver_register(&lirc_serial_igor_driver); + if (result) { + printk("lirc register returned %d\n", result); + return result; + } + + lirc_serial_igor_dev = platform_device_alloc("lirc_serial_igor", 0); + if (!lirc_serial_igor_dev) { + result = -ENOMEM; + goto exit_driver_unregister; + } + + result = platform_device_add(lirc_serial_igor_dev); + if (result) + goto exit_device_put; + + return 0; + +exit_device_put: + platform_device_put(lirc_serial_igor_dev); +exit_driver_unregister: + platform_driver_unregister(&lirc_serial_igor_driver); + return result; +} + +static void __exit lirc_serial_igor_exit(void) +{ + platform_device_unregister(lirc_serial_igor_dev); + platform_driver_unregister(&lirc_serial_igor_driver); +} +#endif + +int __init init_module(void) +{ + int result; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) + result = lirc_serial_igor_init(); + if (result) + return result; +#endif + switch (type) { + case LIRC_HOMEBREW: + case LIRC_IRDEO: + case LIRC_IRDEO_REMOTE: + case LIRC_ANIMAX: + case LIRC_IGOR: +#if defined(LIRC_SERIAL_NSLU2) + case LIRC_NSLU2: +#endif + break; + default: + result = -EINVAL; + goto exit_serial_exit; + } + if (!softcarrier) { + switch (type) { + case LIRC_HOMEBREW: + case LIRC_IGOR: + case LIRC_NSLU2: + hardware[type].features &= + ~(LIRC_CAN_SET_SEND_DUTY_CYCLE| + LIRC_CAN_SET_SEND_CARRIER); + break; + } + } + result = init_port(); + if (result < 0) + goto exit_serial_exit; + plugin.features = hardware[type].features; + plugin.minor = lirc_register_plugin(&plugin); + if (plugin.minor < 0) { + printk(KERN_ERR LIRC_DRIVER_NAME + ": register_chrdev failed!\n"); + result = -EIO; + goto exit_release; + } + return 0; +exit_release: + release_region(io, 8); +exit_serial_exit: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) + lirc_serial_igor_exit(); +#endif + return result; +} + +void __exit cleanup_module(void) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) + lirc_serial_igor_exit(); +#endif +#if defined(LIRC_ALLOW_MMAPPED_IO) + if (iommap != 0) + release_mem_region(iommap, 8< + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + * + */ + +/*********************************************************************** + ************************* Includes *********************** + ***********************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18) +#error "**********************************************************" +#error " Sorry, this driver needs kernel version 2.2.18 or higher " +#error "**********************************************************" +#endif + +#include + +#ifdef CONFIG_SMP +#error "--- Sorry, this driver is not SMP safe. ---" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#include +#include +#include +#include +#else +#include +#include +#include +#include +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) +#include +#endif + +#include +#include + +#include "lirc.h" +#include "kcompat.h" +#include "lirc_dev/lirc_dev.h" + +#include "lirc_parallel.h" + +#define LIRC_DRIVER_NAME "lirc_parallel" + +#ifndef LIRC_IRQ +#define LIRC_IRQ 7 +#endif +#ifndef LIRC_PORT +#define LIRC_PORT 0x378 +#endif +#ifndef LIRC_TIMER +#define LIRC_TIMER 65536 +#endif + +/*********************************************************************** + ************************* Globale Variablen *********************** + ***********************************************************************/ + +static int debug; +static int check_pselecd; + +unsigned int irq = LIRC_IRQ; +unsigned int io = LIRC_PORT; +#ifdef LIRC_TIMER +unsigned int timer; +unsigned int default_timer = LIRC_TIMER; +#endif + +#define WBUF_SIZE (256) +#define RBUF_SIZE (256) /* this must be a power of 2 larger than 1 */ + +static lirc_t wbuf[WBUF_SIZE]; +static lirc_t rbuf[RBUF_SIZE]; + +DECLARE_WAIT_QUEUE_HEAD(lirc_wait); + +unsigned int rptr; +unsigned int wptr; +unsigned int lost_irqs; +int is_open; + +struct parport *pport; +struct pardevice *ppdevice; +int is_claimed; + +unsigned int tx_mask = 1; + +/*********************************************************************** + ************************* Interne Funktionen *********************** + ***********************************************************************/ + +static inline unsigned int in(int offset) +{ + switch (offset) { + case LIRC_LP_BASE: + return (parport_read_data(pport)); + case LIRC_LP_STATUS: + return (parport_read_status(pport)); + case LIRC_LP_CONTROL: + return (parport_read_control(pport)); + } + return 0; /* make compiler happy */ +} + +static inline void out(int offset, int value) +{ + switch (offset) { + case LIRC_LP_BASE: + parport_write_data(pport, value); + break; + case LIRC_LP_CONTROL: + parport_write_control(pport, value); + break; + case LIRC_LP_STATUS: + printk(KERN_INFO "%s: attempt to write to status register\n", + LIRC_DRIVER_NAME); + break; + } +} + +static inline unsigned int lirc_get_timer(void) +{ + return (in(LIRC_PORT_TIMER)&LIRC_PORT_TIMER_BIT); +} + +static inline unsigned int lirc_get_signal(void) +{ + return (in(LIRC_PORT_SIGNAL)&LIRC_PORT_SIGNAL_BIT); +} + +static inline void lirc_on(void) +{ + out(LIRC_PORT_DATA, tx_mask); +} + +static inline void lirc_off(void) +{ + out(LIRC_PORT_DATA, 0); +} + +static unsigned int init_lirc_timer(void) +{ + struct timeval tv, now; + unsigned int level, newlevel, timeelapsed, newtimer; + int count = 0; + + do_gettimeofday(&tv); + tv.tv_sec++; /* wait max. 1 sec. */ + level = lirc_get_timer(); + do { + newlevel = lirc_get_timer(); + if (level == 0 && newlevel != 0) + count++; + level = newlevel; + do_gettimeofday(&now); + } while (count < 1000 && (now.tv_sec < tv.tv_sec + || (now.tv_sec == tv.tv_sec + && now.tv_usec < tv.tv_usec))); + + timeelapsed = ((now.tv_sec + 1 - tv.tv_sec)*1000000 + + (now.tv_usec - tv.tv_usec)); + if (count >= 1000 && timeelapsed > 0) { + if (default_timer == 0) { + /* autodetect timer */ + newtimer = (1000000*count)/timeelapsed; + printk(KERN_INFO "%s: %u Hz timer detected\n", + LIRC_DRIVER_NAME, newtimer); + return newtimer; + } else { + newtimer = (1000000*count)/timeelapsed; + if (abs(newtimer - default_timer) > default_timer/10) { + /* bad timer */ + printk(KERN_NOTICE "%s: bad timer: %u Hz\n", + LIRC_DRIVER_NAME, newtimer); + printk(KERN_NOTICE "%s: using default timer: " + "%u Hz\n", + LIRC_DRIVER_NAME, default_timer); + return default_timer; + } else { + printk(KERN_INFO "%s: %u Hz timer detected\n", + LIRC_DRIVER_NAME, newtimer); + return newtimer; /* use detected value */ + } + } + } else { + printk(KERN_NOTICE "%s: no timer detected\n", LIRC_DRIVER_NAME); + return 0; + } +} + +static int lirc_claim(void) +{ + if (parport_claim(ppdevice) != 0) { + printk(KERN_WARNING "%s: could not claim port\n", + LIRC_DRIVER_NAME); + printk(KERN_WARNING "%s: waiting for port becoming available" + "\n", LIRC_DRIVER_NAME); + if (parport_claim_or_block(ppdevice) < 0) { + printk(KERN_NOTICE "%s: could not claim port, giving" + " up\n", LIRC_DRIVER_NAME); + return 0; + } + } + out(LIRC_LP_CONTROL, LP_PSELECP|LP_PINITP); + is_claimed = 1; + return 1; +} + +/*********************************************************************** + ************************* interrupt handler ************************ + ***********************************************************************/ + +static inline void rbuf_write(lirc_t signal) +{ + unsigned int nwptr; + + nwptr = (wptr + 1) & (RBUF_SIZE - 1); + if (nwptr == rptr) { + /* no new signals will be accepted */ + lost_irqs++; + printk(KERN_NOTICE "%s: buffer overrun\n", LIRC_DRIVER_NAME); + return; + } + rbuf[wptr] = signal; + wptr = nwptr; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void irq_handler(int i, void *blah, struct pt_regs *regs) +#else +static void irq_handler(int i, void *blah) +#endif +{ + struct timeval tv; + static struct timeval lasttv; + static int init; + long signal; + lirc_t data; + unsigned int level, newlevel; + unsigned int timeout; + + if (!MOD_IN_USE) + return; + + if (!is_claimed) + return; + + /* disable interrupt */ + /* + disable_irq(irq); + out(LIRC_PORT_IRQ, in(LIRC_PORT_IRQ) & (~LP_PINTEN)); + */ + if (check_pselecd && (in(1) & LP_PSELECD)) + return; + +#ifdef LIRC_TIMER + if (init) { + do_gettimeofday(&tv); + + signal = tv.tv_sec - lasttv.tv_sec; + if (signal > 15) + /* really long time */ + data = PULSE_MASK; + else + data = (lirc_t) (signal*1000000 + + tv.tv_usec - lasttv.tv_usec + + LIRC_SFH506_DELAY); + + rbuf_write(data); /* space */ + } else { + if (timer == 0) { + /* wake up; we'll lose this signal + * but it will be garbage if the device + * is turned on anyway */ + timer = init_lirc_timer(); + /* enable_irq(irq); */ + return; + } + init = 1; + } + + timeout = timer/10; /* timeout after 1/10 sec. */ + signal = 1; + level = lirc_get_timer(); + do { + newlevel = lirc_get_timer(); + if (level == 0 && newlevel != 0) + signal++; + level = newlevel; + + /* giving up */ + if (signal > timeout + || (check_pselecd && (in(1) & LP_PSELECD))) { + signal = 0; + printk(KERN_NOTICE "%s: timeout\n", LIRC_DRIVER_NAME); + break; + } + } + while (lirc_get_signal()); + if (signal != 0) { + /* ajust value to usecs */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) + unsigned long long helper; + + helper = ((unsigned long long) signal)*1000000; + do_div(helper, timer); + signal = (long) helper; +#else + signal = (long) ((((double) signal)*1000000)/timer); +#endif + + if (signal > LIRC_SFH506_DELAY) + data = signal - LIRC_SFH506_DELAY; + else + data = 1; + rbuf_write(PULSE_BIT|data); /* pulse */ + } + do_gettimeofday(&lasttv); +#else + /* add your code here */ +#endif + + wake_up_interruptible(&lirc_wait); + + /* enable interrupt */ + /* + enable_irq(irq); + out(LIRC_PORT_IRQ, in(LIRC_PORT_IRQ)|LP_PINTEN); + */ +} + +/*********************************************************************** + ************************** file_operations ************************ + ***********************************************************************/ + +static loff_t lirc_lseek(struct file *filep, loff_t offset, int orig) +{ + return -ESPIPE; +} + +static ssize_t lirc_read(struct file *filep, char *buf, size_t n, loff_t *ppos) +{ + int result = 0; + int count = 0; + DECLARE_WAITQUEUE(wait, current); + + if (n % sizeof(lirc_t)) + return -EINVAL; + + add_wait_queue(&lirc_wait, &wait); + set_current_state(TASK_INTERRUPTIBLE); + while (count < n) { + if (rptr != wptr) { + if (copy_to_user(buf+count, (char *) &rbuf[rptr], + sizeof(lirc_t))) { + result = -EFAULT; + break; + } + rptr = (rptr + 1) & (RBUF_SIZE - 1); + count += sizeof(lirc_t); + } else { + if (filep->f_flags & O_NONBLOCK) { + result = -EAGAIN; + break; + } + if (signal_pending(current)) { + result = -ERESTARTSYS; + break; + } + schedule(); + set_current_state(TASK_INTERRUPTIBLE); + } + } + remove_wait_queue(&lirc_wait, &wait); + set_current_state(TASK_RUNNING); + return (count ? count : result); +} + +static ssize_t lirc_write(struct file *filep, const char *buf, size_t n, + loff_t *ppos) +{ + int count; + unsigned int i; + unsigned int level, newlevel; + unsigned long flags; + lirc_t counttimer; + + if (!is_claimed) + return(-EBUSY); + + if (n % sizeof(lirc_t)) + return(-EINVAL); + + count = n / sizeof(lirc_t); + + if (count > WBUF_SIZE || count % 2 == 0) + return(-EINVAL); + + if (copy_from_user(wbuf, buf, n)) + return -EFAULT; + +#ifdef LIRC_TIMER + if (timer == 0) { + /* try again if device is ready */ + timer = init_lirc_timer(); + if (timer == 0) + return(-EIO); + } + + /* ajust values from usecs */ + for (i = 0; i < count; i++) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) + unsigned long long helper; + + helper = ((unsigned long long) wbuf[i])*timer; + do_div(helper, 1000000); + wbuf[i] = (lirc_t) helper; +#else + wbuf[i] = (lirc_t) (((double) wbuf[i])*timer/1000000); +#endif + } + + local_irq_save(flags); + i = 0; + while (i < count) { + level = lirc_get_timer(); + counttimer = 0; + lirc_on(); + do { + newlevel = lirc_get_timer(); + if (level == 0 && newlevel != 0) + counttimer++; + level = newlevel; + if (check_pselecd && (in(1) & LP_PSELECD)) { + lirc_off(); + local_irq_restore(flags); + return -EIO; + } + } while (counttimer < wbuf[i]); + i++; + + lirc_off(); + if (i == count) + break; + counttimer = 0; + do { + newlevel = lirc_get_timer(); + if (level == 0 && newlevel != 0) + counttimer++; + level = newlevel; + if (check_pselecd && (in(1) & LP_PSELECD)) { + local_irq_restore(flags); + return -EIO; + } + } while (counttimer < wbuf[i]); + i++; + } + local_irq_restore(flags); +#else + /* place code that handles write + * without external timer here */ +#endif + return n; +} + +static unsigned int lirc_poll(struct file *file, poll_table *wait) +{ + poll_wait(file, &lirc_wait, wait); + if (rptr != wptr) + return (POLLIN|POLLRDNORM); + return 0; +} + +static int lirc_ioctl(struct inode *node, struct file *filep, unsigned int cmd, + unsigned long arg) +{ + int result; + unsigned long features = LIRC_CAN_SET_TRANSMITTER_MASK | + LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2; + unsigned long mode; + unsigned int ivalue; + + switch (cmd) { + case LIRC_GET_FEATURES: + result = put_user(features, (unsigned long *) arg); + if (result) + return result; + break; + case LIRC_GET_SEND_MODE: + result = put_user(LIRC_MODE_PULSE, (unsigned long *) arg); + if (result) + return result; + break; + case LIRC_GET_REC_MODE: + result = put_user(LIRC_MODE_MODE2, (unsigned long *) arg); + if (result) + return result; + break; + case LIRC_SET_SEND_MODE: + result = get_user(mode, (unsigned long *) arg); + if (result) + return result; + if (mode != LIRC_MODE_PULSE) + return -EINVAL; + break; + case LIRC_SET_REC_MODE: + result = get_user(mode, (unsigned long *) arg); + if (result) + return result; + if (mode != LIRC_MODE_MODE2) + return -ENOSYS; + break; + case LIRC_SET_TRANSMITTER_MASK: + result = get_user(ivalue, (unsigned int *) arg); + if (result) + return result; + if ((ivalue & LIRC_PARALLEL_TRANSMITTER_MASK) != ivalue) + return LIRC_PARALLEL_MAX_TRANSMITTERS; + tx_mask = ivalue; + break; + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static int lirc_open(struct inode *node, struct file *filep) +{ + if (MOD_IN_USE || !lirc_claim()) + return -EBUSY; + + parport_enable_irq(pport); + + /* init read ptr */ + rptr = 0; + wptr = 0; + lost_irqs = 0; + + MOD_INC_USE_COUNT; + is_open = 1; + return 0; +} + +static int lirc_close(struct inode *node, struct file *filep) +{ + if (is_claimed) { + is_claimed = 0; + parport_release(ppdevice); + } + is_open = 0; + MOD_DEC_USE_COUNT; + return 0; +} + +static struct file_operations lirc_fops = { + .llseek = lirc_lseek, + .read = lirc_read, + .write = lirc_write, + .poll = lirc_poll, + .ioctl = lirc_ioctl, + .open = lirc_open, + .release = lirc_close +}; + +static int set_use_inc(void *data) +{ +#if WE_DONT_USE_LOCAL_OPEN_CLOSE + MOD_INC_USE_COUNT; +#endif + return 0; +} + +static void set_use_dec(void *data) +{ +#if WE_DONT_USE_LOCAL_OPEN_CLOSE + MOD_DEC_USE_COUNT; +#endif +} + +static struct lirc_plugin plugin = { + .name = LIRC_DRIVER_NAME, + .minor = -1, + .code_length = 1, + .sample_rate = 0, + .data = NULL, + .add_to_buf = NULL, + .get_queue = NULL, + .set_use_inc = set_use_inc, + .set_use_dec = set_use_dec, + .fops = &lirc_fops, + .dev = NULL, + .owner = THIS_MODULE, +}; + +#ifdef MODULE + +static int pf(void *handle); +static void kf(void *handle); + +static struct timer_list poll_timer; +static void poll_state(unsigned long ignored); + +static void poll_state(unsigned long ignored) +{ + printk(KERN_NOTICE "%s: time\n", + LIRC_DRIVER_NAME); + del_timer(&poll_timer); + if (is_claimed) + return; + kf(NULL); + if (!is_claimed) { + printk(KERN_NOTICE "%s: could not claim port, giving up\n", + LIRC_DRIVER_NAME); + init_timer(&poll_timer); + poll_timer.expires = jiffies + HZ; + poll_timer.data = (unsigned long)current; + poll_timer.function = poll_state; + add_timer(&poll_timer); + } +} + +static int pf(void *handle) +{ + parport_disable_irq(pport); + is_claimed = 0; + return 0; +} + +static void kf(void *handle) +{ + if (!is_open) + return; + if (!lirc_claim()) + return; + parport_enable_irq(pport); + lirc_off(); + /* this is a bit annoying when you actually print...*/ + /* + printk(KERN_INFO "%s: reclaimed port\n", LIRC_DRIVER_NAME); + */ +} + +/*********************************************************************** + ****************** init_module()/cleanup_module() ****************** + ***********************************************************************/ + +int init_module(void) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 3) + pport = parport_find_base(io); +#else + pport = parport_enumerate(); + while (pport != NULL) { + if (pport->base == io) + break; + pport = pport->next; + } +#endif + if (pport == NULL) { + printk(KERN_NOTICE "%s: no port at %x found\n", + LIRC_DRIVER_NAME, io); + return -ENXIO; + } + ppdevice = parport_register_device(pport, LIRC_DRIVER_NAME, + pf, kf, irq_handler, 0, NULL); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 3) + parport_put_port(pport); +#endif + if (ppdevice == NULL) { + printk(KERN_NOTICE "%s: parport_register_device() failed\n", + LIRC_DRIVER_NAME); + return -ENXIO; + } + if (parport_claim(ppdevice) != 0) + goto skip_init; + is_claimed = 1; + out(LIRC_LP_CONTROL, LP_PSELECP|LP_PINITP); + +#ifdef LIRC_TIMER + if (debug) + out(LIRC_PORT_DATA, tx_mask); + + timer = init_lirc_timer(); + +#if 0 /* continue even if device is offline */ + if (timer == 0) { + is_claimed = 0; + parport_release(pport); + parport_unregister_device(ppdevice); + return -EIO; + } + +#endif + if (debug) + out(LIRC_PORT_DATA, 0); +#endif + + is_claimed = 0; + parport_release(ppdevice); + skip_init: + plugin.minor = lirc_register_plugin(&plugin); + if (plugin.minor < 0) { + printk(KERN_NOTICE "%s: register_chrdev() failed\n", + LIRC_DRIVER_NAME); + parport_unregister_device(ppdevice); + return -EIO; + } + printk(KERN_INFO "%s: installed using port 0x%04x irq %d\n", + LIRC_DRIVER_NAME, io, irq); + return 0; +} + +void cleanup_module(void) +{ + parport_unregister_device(ppdevice); + lirc_unregister_plugin(plugin.minor); +} + +MODULE_DESCRIPTION("Infrared receiver driver for parallel ports."); +MODULE_AUTHOR("Christoph Bartelmus"); +MODULE_LICENSE("GPL"); + +module_param(io, int, 0444); +MODULE_PARM_DESC(io, "I/O address base (0x3bc, 0x378 or 0x278)"); + +module_param(irq, int, 0444); +MODULE_PARM_DESC(irq, "Interrupt (7 or 5)"); + +module_param(tx_mask, int, 0444); +MODULE_PARM_DESC(tx_maxk, "Transmitter mask (default: 0x01)"); + +module_param(debug, bool, 0644); +MODULE_PARM_DESC(debug, "Enable debugging messages"); + +module_param(check_pselecd, bool, 0644); +MODULE_PARM_DESC(debug, "Check for printer (default: 0)"); + +EXPORT_NO_SYMBOLS; + +#endif /* MODULE */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_parallel/lirc_parallel.h +++ linux-2.6.28/ubuntu/lirc/lirc_parallel/lirc_parallel.h @@ -0,0 +1,26 @@ +/* $Id: lirc_parallel.h,v 5.2 2007/01/25 04:32:05 lirc Exp $ */ + +#ifndef _LIRC_PARALLEL_H +#define _LIRC_PARALLEL_H + +#include + +#define LIRC_PORT_LEN 3 + +#define LIRC_LP_BASE 0 +#define LIRC_LP_STATUS 1 +#define LIRC_LP_CONTROL 2 + +#define LIRC_PORT_DATA LIRC_LP_BASE /* base */ +#define LIRC_PORT_TIMER LIRC_LP_STATUS /* status port */ +#define LIRC_PORT_TIMER_BIT LP_PBUSY /* busy signal */ +#define LIRC_PORT_SIGNAL LIRC_LP_STATUS /* status port */ +#define LIRC_PORT_SIGNAL_BIT LP_PACK /* ack signal */ +#define LIRC_PORT_IRQ LIRC_LP_CONTROL /* control port */ + +#define LIRC_SFH506_DELAY 0 /* delay t_phl in usecs */ + +#define LIRC_PARALLEL_MAX_TRANSMITTERS 8 +#define LIRC_PARALLEL_TRANSMITTER_MASK ((1< + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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 + * + * ITE IT8705 and IT8712(not tested) CIR-port support for lirc based + * via cut and paste from lirc_sir.c (C) 2000 Milan Pikula + * + * Attention: Sendmode only tested with debugging logs + * + * 2001/02/27 Christoph Bartelmus : + * reimplemented read function + * 2005/06/05 Andrew Calkin implemented support for Asus Digimatrix, + * based on work of the following member of the Outertrack Digimatrix + * Forum: Art103 + */ + + +#include +#include + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +#include +#include +#include +#include +#else +#include +#include +#include +#include +#endif + +#include + +#include "lirc.h" +#include "lirc_dev/lirc_dev.h" +#include "kcompat.h" + +#include "lirc_it87.h" + +#ifdef LIRC_IT87_DIGIMATRIX +static int digimatrix = 1; +static int it87_freq = 36; /* kHz */ +static int irq = 9; +#else +static int digimatrix; +static int it87_freq = 38; /* kHz */ +static int irq = IT87_CIR_DEFAULT_IRQ; +#endif + +static unsigned long it87_bits_in_byte_out; +static unsigned long it87_send_counter; +static unsigned char it87_RXEN_mask = IT87_CIR_RCR_RXEN; + +#define RBUF_LEN 1024 +#define WBUF_LEN 1024 + +#define LIRC_DRIVER_NAME "lirc_it87" + +/* timeout for sequences in jiffies (=5/100s) */ +/* must be longer than TIME_CONST */ +#define IT87_TIMEOUT (HZ*5/100) + +/* insmod parameters */ +static int debug; +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \ + fmt, ## args); \ + } while (0) + +static int io = IT87_CIR_DEFAULT_IOBASE; +/* receiver demodulator default: off */ +static int it87_enable_demodulator; + +static int timer_enabled; +static DEFINE_SPINLOCK(timer_lock); +static struct timer_list timerlist; +/* time of last signal change detected */ +static struct timeval last_tv = {0, 0}; +/* time of last UART data ready interrupt */ +static struct timeval last_intr_tv = {0, 0}; +static int last_value; + +static DECLARE_WAIT_QUEUE_HEAD(lirc_read_queue); + +static DEFINE_SPINLOCK(hardware_lock); +static DEFINE_SPINLOCK(dev_lock); + +static lirc_t rx_buf[RBUF_LEN]; +unsigned int rx_tail, rx_head; +static lirc_t tx_buf[WBUF_LEN]; + +/* SECTION: Prototypes */ + +/* Communication with user-space */ +static int lirc_open(struct inode *inode, struct file *file); +static int lirc_close(struct inode *inode, struct file *file); +static unsigned int lirc_poll(struct file *file, poll_table *wait); +static ssize_t lirc_read(struct file *file, char *buf, + size_t count, loff_t *ppos); +static ssize_t lirc_write(struct file *file, const char *buf, + size_t n, loff_t *pos); +static int lirc_ioctl(struct inode *node, struct file *filep, + unsigned int cmd, unsigned long arg); +static void add_read_queue(int flag, unsigned long val); +#ifdef MODULE +static int init_chrdev(void); +static void drop_chrdev(void); +#endif + /* Hardware */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static irqreturn_t it87_interrupt(int irq, void *dev_id, + struct pt_regs *regs); +#else +static irqreturn_t it87_interrupt(int irq, void *dev_id); +#endif +static void send_space(unsigned long len); +static void send_pulse(unsigned long len); +static void init_send(void); +static void terminate_send(unsigned long len); +static int init_hardware(void); +static void drop_hardware(void); + /* Initialisation */ +static int init_port(void); +static void drop_port(void); +int init_module(void); +void cleanup_module(void); + + +/* SECTION: Communication with user-space */ + +static int lirc_open(struct inode *inode, struct file *file) +{ + spin_lock(&dev_lock); + if (MOD_IN_USE) { + spin_unlock(&dev_lock); + return -EBUSY; + } + MOD_INC_USE_COUNT; + spin_unlock(&dev_lock); + return 0; +} + + +static int lirc_close(struct inode *inode, struct file *file) +{ + MOD_DEC_USE_COUNT; + return 0; +} + + +static unsigned int lirc_poll(struct file *file, poll_table *wait) +{ + poll_wait(file, &lirc_read_queue, wait); + if (rx_head != rx_tail) + return POLLIN | POLLRDNORM; + return 0; +} + + +static ssize_t lirc_read(struct file *file, char *buf, + size_t count, loff_t *ppos) +{ + int n = 0; + int retval = 0; + + while (n < count) { + if (file->f_flags & O_NONBLOCK && rx_head == rx_tail) { + retval = -EAGAIN; + break; + } + retval = wait_event_interruptible(lirc_read_queue, + rx_head != rx_tail); + if (retval) + break; + + if (copy_to_user((void *) buf + n, (void *) (rx_buf + rx_head), + sizeof(lirc_t))) { + retval = -EFAULT; + break; + } + rx_head = (rx_head + 1) & (RBUF_LEN - 1); + n += sizeof(lirc_t); + } + if (n) + return n; + return retval; +} + + +static ssize_t lirc_write(struct file *file, const char *buf, + size_t n, loff_t *pos) +{ + int i = 0; + + if (n % sizeof(lirc_t) || (n / sizeof(lirc_t)) > WBUF_LEN) + return -EINVAL; + if (copy_from_user(tx_buf, buf, n)) + return -EFAULT; + n /= sizeof(lirc_t); + init_send(); + while (1) { + if (i >= n) + break; + if (tx_buf[i]) + send_pulse(tx_buf[i]); + i++; + if (i >= n) + break; + if (tx_buf[i]) + send_space(tx_buf[i]); + i++; + } + terminate_send(tx_buf[i - 1]); + return n; +} + + +static int lirc_ioctl(struct inode *node, struct file *filep, + unsigned int cmd, unsigned long arg) +{ + int retval = 0; + unsigned long value = 0; + unsigned int ivalue; + unsigned long hw_flags; + + if (cmd == LIRC_GET_FEATURES) + value = LIRC_CAN_SEND_PULSE | + LIRC_CAN_SET_SEND_CARRIER | + LIRC_CAN_REC_MODE2; + else if (cmd == LIRC_GET_SEND_MODE) + value = LIRC_MODE_PULSE; + else if (cmd == LIRC_GET_REC_MODE) + value = LIRC_MODE_MODE2; + + switch (cmd) { + case LIRC_GET_FEATURES: + case LIRC_GET_SEND_MODE: + case LIRC_GET_REC_MODE: + retval = put_user(value, (unsigned long *) arg); + break; + + case LIRC_SET_SEND_MODE: + case LIRC_SET_REC_MODE: + retval = get_user(value, (unsigned long *) arg); + break; + + case LIRC_SET_SEND_CARRIER: + retval = get_user(ivalue, (unsigned int *) arg); + if (retval) + return retval; + ivalue /= 1000; + if (ivalue > IT87_CIR_FREQ_MAX || + ivalue < IT87_CIR_FREQ_MIN) + return -EINVAL; + + it87_freq = ivalue; + + spin_lock_irqsave(&hardware_lock, hw_flags); + outb(((inb(io + IT87_CIR_TCR2) & IT87_CIR_TCR2_TXMPW) | + (it87_freq - IT87_CIR_FREQ_MIN) << 3), + io + IT87_CIR_TCR2); + spin_unlock_irqrestore(&hardware_lock, hw_flags); + dprintk("demodulation frequency: %d kHz\n", it87_freq); + + break; + + default: + retval = -ENOIOCTLCMD; + } + + if (retval) + return retval; + + if (cmd == LIRC_SET_REC_MODE) { + if (value != LIRC_MODE_MODE2) + retval = -ENOSYS; + } else if (cmd == LIRC_SET_SEND_MODE) { + if (value != LIRC_MODE_PULSE) + retval = -ENOSYS; + } + return retval; +} + +static void add_read_queue(int flag, unsigned long val) +{ + unsigned int new_rx_tail; + lirc_t newval; + + dprintk("add flag %d with val %lu\n", flag, val); + + newval = val & PULSE_MASK; + + /* statistically pulses are ~TIME_CONST/2 too long: we could + maybe make this more exactly but this is good enough */ + if (flag) { + /* pulse */ + if (newval > TIME_CONST / 2) + newval -= TIME_CONST / 2; + else /* should not ever happen */ + newval = 1; + newval |= PULSE_BIT; + } else + newval += TIME_CONST / 2; + new_rx_tail = (rx_tail + 1) & (RBUF_LEN - 1); + if (new_rx_tail == rx_head) { + dprintk("Buffer overrun.\n"); + return; + } + rx_buf[rx_tail] = newval; + rx_tail = new_rx_tail; + wake_up_interruptible(&lirc_read_queue); +} + + +static struct file_operations lirc_fops = { + .read = lirc_read, + .write = lirc_write, + .poll = lirc_poll, + .ioctl = lirc_ioctl, + .open = lirc_open, + .release = lirc_close, +}; + +static int set_use_inc(void *data) +{ + return 0; +} + +static void set_use_dec(void *data) +{ + +} +static struct lirc_plugin plugin = { + .name = LIRC_DRIVER_NAME, + .minor = -1, + .code_length = 1, + .sample_rate = 0, + .data = NULL, + .add_to_buf = NULL, + .get_queue = NULL, + .set_use_inc = set_use_inc, + .set_use_dec = set_use_dec, + .fops = &lirc_fops, + .dev = NULL, + .owner = THIS_MODULE, +}; + + +#ifdef MODULE +static int init_chrdev(void) +{ + plugin.minor = lirc_register_plugin(&plugin); + + if (plugin.minor < 0) { + printk(KERN_ERR LIRC_DRIVER_NAME ": init_chrdev() failed.\n"); + return -EIO; + } + return 0; +} + + +static void drop_chrdev(void) +{ + lirc_unregister_plugin(plugin.minor); +} +#endif + + +/* SECTION: Hardware */ +static long delta(struct timeval *tv1, struct timeval *tv2) +{ + unsigned long deltv; + + deltv = tv2->tv_sec - tv1->tv_sec; + if (deltv > 15) + deltv = 0xFFFFFF; + else + deltv = deltv*1000000 + tv2->tv_usec - tv1->tv_usec; + return deltv; +} + +static void it87_timeout(unsigned long data) +{ + unsigned long flags; + + /* avoid interference with interrupt */ + spin_lock_irqsave(&timer_lock, flags); + + if (digimatrix) { + /* We have timed out. + Disable the RX mechanism. + */ + + outb((inb(io + IT87_CIR_RCR) & ~IT87_CIR_RCR_RXEN) | + IT87_CIR_RCR_RXACT, io + IT87_CIR_RCR); + if (it87_RXEN_mask) + outb(inb(io + IT87_CIR_RCR) | IT87_CIR_RCR_RXEN, + io + IT87_CIR_RCR); + dprintk(" TIMEOUT\n"); + timer_enabled = 0; + + /* fifo clear */ + outb(inb(io + IT87_CIR_TCR1) | IT87_CIR_TCR1_FIFOCLR, + io+IT87_CIR_TCR1); + + } else { + /* if last received signal was a pulse, but receiving + stopped within the 9 bit frame, we need to finish + this pulse and simulate a signal change to from + pulse to space. Otherwise upper layers will receive + two sequences next time. */ + + if (last_value) { + unsigned long pulse_end; + + /* determine 'virtual' pulse end: */ + pulse_end = delta(&last_tv, &last_intr_tv); + dprintk("timeout add %d for %lu usec\n", + last_value, pulse_end); + add_read_queue(last_value, pulse_end); + last_value = 0; + last_tv = last_intr_tv; + } + } + spin_unlock_irqrestore(&timer_lock, flags); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static irqreturn_t it87_interrupt(int irq, void *dev_id, struct pt_regs *regs) +#else +static irqreturn_t it87_interrupt(int irq, void *dev_id) +#endif +{ + unsigned char data; + struct timeval curr_tv; + static unsigned long deltv; + unsigned long deltintrtv; + unsigned long flags, hw_flags; + int iir, lsr; + int fifo = 0; + static char lastbit; + char bit; + + /* Bit duration in microseconds */ + const unsigned long bit_duration = 1000000ul / + (115200 / IT87_CIR_BAUDRATE_DIVISOR); + + + iir = inb(io + IT87_CIR_IIR); + + switch (iir & IT87_CIR_IIR_IID) { + case 0x4: + case 0x6: + lsr = inb(io + IT87_CIR_RSR) & (IT87_CIR_RSR_RXFTO | + IT87_CIR_RSR_RXFBC); + fifo = lsr & IT87_CIR_RSR_RXFBC; + dprintk("iir: 0x%x fifo: 0x%x\n", iir, lsr); + + /* avoid interference with timer */ + spin_lock_irqsave(&timer_lock, flags); + spin_lock_irqsave(&hardware_lock, hw_flags); + if (digimatrix) { + static unsigned long acc_pulse; + static unsigned long acc_space; + + do { + data = inb(io + IT87_CIR_DR); + data = ~data; + fifo--; + if (data != 0x00) { + if (timer_enabled) + del_timer(&timerlist); + /* start timer for end of + * sequence detection */ + timerlist.expires = jiffies + + IT87_TIMEOUT; + add_timer(&timerlist); + timer_enabled = 1; + } + /* Loop through */ + for (bit = 0; bit < 8; ++bit) { + if ((data >> bit) & 1) { + ++acc_pulse; + if (lastbit == 0) { + add_read_queue(0, + acc_space * + bit_duration); + acc_space = 0; + } + } else { + ++acc_space; + if (lastbit == 1) { + add_read_queue(1, + acc_pulse * + bit_duration); + acc_pulse = 0; + } + } + lastbit = (data >> bit) & 1; + } + + } while (fifo != 0); + } else { /* Normal Operation */ + do { + del_timer(&timerlist); + data = inb(io + IT87_CIR_DR); + + dprintk("data=%.2x\n", data); + do_gettimeofday(&curr_tv); + deltv = delta(&last_tv, &curr_tv); + deltintrtv = delta(&last_intr_tv, &curr_tv); + + dprintk("t %lu , d %d\n", + deltintrtv, (int)data); + + /* if nothing came in last 2 cycles, + it was gap */ + if (deltintrtv > TIME_CONST * 2) { + if (last_value) { + dprintk("GAP\n"); + + /* simulate signal change */ + add_read_queue(last_value, + deltv - + deltintrtv); + last_value = 0; + last_tv.tv_sec = + last_intr_tv.tv_sec; + last_tv.tv_usec = + last_intr_tv.tv_usec; + deltv = deltintrtv; + } + } + data = 1; + if (data ^ last_value) { + /* deltintrtv > 2*TIME_CONST, + remember ? */ + /* the other case is timeout */ + add_read_queue(last_value, + deltv-TIME_CONST); + last_value = data; + last_tv = curr_tv; + if (last_tv.tv_usec >= TIME_CONST) + last_tv.tv_usec -= TIME_CONST; + else { + last_tv.tv_sec--; + last_tv.tv_usec += 1000000 - + TIME_CONST; + } + } + last_intr_tv = curr_tv; + if (data) { + /* start timer for end of + * sequence detection */ + timerlist.expires = + jiffies + IT87_TIMEOUT; + add_timer(&timerlist); + } + outb((inb(io + IT87_CIR_RCR) & + ~IT87_CIR_RCR_RXEN) | + IT87_CIR_RCR_RXACT, + io + IT87_CIR_RCR); + if (it87_RXEN_mask) + outb(inb(io + IT87_CIR_RCR) | + IT87_CIR_RCR_RXEN, + io + IT87_CIR_RCR); + fifo--; + } while (fifo != 0); + } + spin_unlock_irqrestore(&hardware_lock, hw_flags); + spin_unlock_irqrestore(&timer_lock, flags); + + return IRQ_RETVAL(IRQ_HANDLED); + + default: + /* not our irq */ + dprintk("unknown IRQ (shouldn't happen) !!\n"); + return IRQ_RETVAL(IRQ_NONE); + } +} + + +static void send_it87(unsigned long len, unsigned long stime, + unsigned char send_byte, unsigned int count_bits) +{ + long count = len / stime; + long time_left = 0; + static unsigned char byte_out; + unsigned long hw_flags; + + dprintk("%s: len=%ld, sb=%d\n", __FUNCTION__, len, send_byte); + + time_left = (long)len - (long)count * (long)stime; + count += ((2 * time_left) / stime); + while (count) { + long i = 0; + for (i = 0; i < count_bits; i++) { + byte_out = (byte_out << 1) | (send_byte & 1); + it87_bits_in_byte_out++; + } + if (it87_bits_in_byte_out == 8) { + dprintk("out=0x%x, tsr_txfbc: 0x%x\n", + byte_out, + inb(io + IT87_CIR_TSR) & + IT87_CIR_TSR_TXFBC); + + while ((inb(io + IT87_CIR_TSR) & + IT87_CIR_TSR_TXFBC) >= IT87_CIR_FIFO_SIZE) + ; + + spin_lock_irqsave(&hardware_lock, hw_flags); + outb(byte_out, io + IT87_CIR_DR); + spin_unlock_irqrestore(&hardware_lock, hw_flags); + + it87_bits_in_byte_out = 0; + it87_send_counter++; + byte_out = 0; + } + count--; + } +} + + +/* +maybe: exchange space and pulse because +it8705 only modulates 0-bits +*/ + + +static void send_space(unsigned long len) +{ + send_it87(len, TIME_CONST, IT87_CIR_SPACE, IT87_CIR_BAUDRATE_DIVISOR); +} + +static void send_pulse(unsigned long len) +{ + send_it87(len, TIME_CONST, IT87_CIR_PULSE, IT87_CIR_BAUDRATE_DIVISOR); +} + + +static void init_send() +{ + unsigned long flags; + + spin_lock_irqsave(&hardware_lock, flags); + /* RXEN=0: receiver disable */ + it87_RXEN_mask = 0; + outb(inb(io + IT87_CIR_RCR) & ~IT87_CIR_RCR_RXEN, + io + IT87_CIR_RCR); + spin_unlock_irqrestore(&hardware_lock, flags); + it87_bits_in_byte_out = 0; + it87_send_counter = 0; +} + + +static void terminate_send(unsigned long len) +{ + unsigned long flags; + unsigned long last = 0; + + last = it87_send_counter; + /* make sure all necessary data has been sent */ + while (last == it87_send_counter) + send_space(len); + /* wait until all data sent */ + while ((inb(io + IT87_CIR_TSR) & IT87_CIR_TSR_TXFBC) != 0); + /* then reenable receiver */ + spin_lock_irqsave(&hardware_lock, flags); + it87_RXEN_mask = IT87_CIR_RCR_RXEN; + outb(inb(io + IT87_CIR_RCR) | IT87_CIR_RCR_RXEN, + io + IT87_CIR_RCR); + spin_unlock_irqrestore(&hardware_lock, flags); +} + + +static int init_hardware(void) +{ + unsigned long flags; + unsigned char it87_rcr = 0; + + spin_lock_irqsave(&hardware_lock, flags); + /* init cir-port */ + /* enable r/w-access to Baudrate-Register */ + outb(IT87_CIR_IER_BR, io + IT87_CIR_IER); + outb(IT87_CIR_BAUDRATE_DIVISOR % 0x100, io+IT87_CIR_BDLR); + outb(IT87_CIR_BAUDRATE_DIVISOR / 0x100, io+IT87_CIR_BDHR); + /* Baudrate Register off, define IRQs: Input only */ + if (digimatrix) { + outb(IT87_CIR_IER_IEC | IT87_CIR_IER_RFOIE, io + IT87_CIR_IER); + /* RX: HCFS=0, RXDCR = 001b (33,75..38,25 kHz), RXEN=1 */ + } else { + outb(IT87_CIR_IER_IEC | IT87_CIR_IER_RDAIE, io + IT87_CIR_IER); + /* RX: HCFS=0, RXDCR = 001b (35,6..40,3 kHz), RXEN=1 */ + } + it87_rcr = (IT87_CIR_RCR_RXEN & it87_RXEN_mask) | 0x1; + if (it87_enable_demodulator) + it87_rcr |= IT87_CIR_RCR_RXEND; + outb(it87_rcr, io + IT87_CIR_RCR); + if (digimatrix) { + /* Set FIFO depth to 1 byte, and disable TX */ + outb(inb(io + IT87_CIR_TCR1) | 0x00, + io + IT87_CIR_TCR1); + + /* TX: it87_freq (36kHz), + 'reserved' sensitivity setting (0x00) */ + outb(((it87_freq - IT87_CIR_FREQ_MIN) << 3) | 0x00, + io + IT87_CIR_TCR2); + } else { + /* TX: 38kHz, 13,3us (pulse-width */ + outb(((it87_freq - IT87_CIR_FREQ_MIN) << 3) | 0x06, + io + IT87_CIR_TCR2); + } + spin_unlock_irqrestore(&hardware_lock, flags); + return 0; +} + + +static void drop_hardware(void) +{ + unsigned long flags; + + spin_lock_irqsave(&hardware_lock, flags); + disable_irq(irq); + /* receiver disable */ + it87_RXEN_mask = 0; + outb(0x1, io + IT87_CIR_RCR); + /* turn off irqs */ + outb(0, io + IT87_CIR_IER); + /* fifo clear */ + outb(IT87_CIR_TCR1_FIFOCLR, io+IT87_CIR_TCR1); + /* reset */ + outb(IT87_CIR_IER_RESET, io+IT87_CIR_IER); + enable_irq(irq); + spin_unlock_irqrestore(&hardware_lock, flags); +} + + +static unsigned char it87_read(unsigned char port) +{ + outb(port, IT87_ADRPORT); + return inb(IT87_DATAPORT); +} + + +static void it87_write(unsigned char port, unsigned char data) +{ + outb(port, IT87_ADRPORT); + outb(data, IT87_DATAPORT); +} + + +/* SECTION: Initialisation */ + +static int init_port(void) +{ + unsigned long hw_flags; + int retval = 0; + + unsigned char init_bytes[4] = {IT87_INIT}; + unsigned char it87_chipid = 0; + unsigned char ldn = 0; + unsigned int it87_io = 0; + unsigned int it87_irq = 0; + + /* Enter MB PnP Mode */ + outb(init_bytes[0], IT87_ADRPORT); + outb(init_bytes[1], IT87_ADRPORT); + outb(init_bytes[2], IT87_ADRPORT); + outb(init_bytes[3], IT87_ADRPORT); + + /* 8712 or 8705 ? */ + it87_chipid = it87_read(IT87_CHIP_ID1); + if (it87_chipid != 0x87) { + retval = -ENXIO; + return retval; + } + it87_chipid = it87_read(IT87_CHIP_ID2); + if ((it87_chipid != 0x12) && (it87_chipid != 0x05)) { + printk(KERN_INFO LIRC_DRIVER_NAME + ": no IT8705/12 found, exiting..\n"); + retval = -ENXIO; + return retval; + } + printk(KERN_INFO LIRC_DRIVER_NAME + ": found IT87%.2x.\n", + it87_chipid); + + /* get I/O-Port and IRQ */ + if (it87_chipid == 0x12) + ldn = IT8712_CIR_LDN; + else + ldn = IT8705_CIR_LDN; + it87_write(IT87_LDN, ldn); + + it87_io = it87_read(IT87_CIR_BASE_MSB) * 256 + + it87_read(IT87_CIR_BASE_LSB); + if (it87_io == 0) { + if (io == 0) + io = IT87_CIR_DEFAULT_IOBASE; + printk(KERN_INFO LIRC_DRIVER_NAME + ": set default io 0x%x\n", + io); + it87_write(IT87_CIR_BASE_MSB, io / 0x100); + it87_write(IT87_CIR_BASE_LSB, io % 0x100); + } else + io = it87_io; + + it87_irq = it87_read(IT87_CIR_IRQ); + if (digimatrix || it87_irq == 0) { + if (irq == 0) + irq = IT87_CIR_DEFAULT_IRQ; + printk(KERN_INFO LIRC_DRIVER_NAME + ": set default irq 0x%x\n", + irq); + it87_write(IT87_CIR_IRQ, irq); + } else + irq = it87_irq; + + spin_lock_irqsave(&hardware_lock, hw_flags); + /* reset */ + outb(IT87_CIR_IER_RESET, io+IT87_CIR_IER); + /* fifo clear */ + outb(IT87_CIR_TCR1_FIFOCLR | + /* IT87_CIR_TCR1_ILE | */ + IT87_CIR_TCR1_TXRLE | + IT87_CIR_TCR1_TXENDF, io+IT87_CIR_TCR1); + spin_unlock_irqrestore(&hardware_lock, hw_flags); + + /* get I/O port access and IRQ line */ + if (request_region(io, 8, LIRC_DRIVER_NAME) == NULL) { + printk(KERN_ERR LIRC_DRIVER_NAME + ": i/o port 0x%.4x already in use.\n", io); + /* Leaving MB PnP Mode */ + it87_write(IT87_CFGCTRL, 0x2); + return -EBUSY; + } + + /* activate CIR-Device */ + it87_write(IT87_CIR_ACT, 0x1); + + /* Leaving MB PnP Mode */ + it87_write(IT87_CFGCTRL, 0x2); + + retval = request_irq(irq, it87_interrupt, 0 /*IRQF_DISABLED*/, + LIRC_DRIVER_NAME, NULL); + if (retval < 0) { + printk(KERN_ERR LIRC_DRIVER_NAME + ": IRQ %d already in use.\n", + irq); + release_region(io, 8); + return retval; + } + + printk(KERN_INFO LIRC_DRIVER_NAME + ": I/O port 0x%.4x, IRQ %d.\n", io, irq); + + init_timer(&timerlist); + timerlist.function = it87_timeout; + timerlist.data = 0xabadcafe; + + return 0; +} + + +static void drop_port(void) +{ +/* + unsigned char init_bytes[4] = {IT87_INIT}; + + / * Enter MB PnP Mode * / + outb(init_bytes[0], IT87_ADRPORT); + outb(init_bytes[1], IT87_ADRPORT); + outb(init_bytes[2], IT87_ADRPORT); + outb(init_bytes[3], IT87_ADRPORT); + + / * deactivate CIR-Device * / + it87_write(IT87_CIR_ACT, 0x0); + + / * Leaving MB PnP Mode * / + it87_write(IT87_CFGCTRL, 0x2); +*/ + + del_timer_sync(&timerlist); + free_irq(irq, NULL); + release_region(io, 8); +} + + +static int init_lirc_it87(void) +{ + int retval; + + init_waitqueue_head(&lirc_read_queue); + retval = init_port(); + if (retval < 0) + return retval; + init_hardware(); + printk(KERN_INFO LIRC_DRIVER_NAME ": Installed.\n"); + return 0; +} + + +#ifdef MODULE + +int init_module(void) +{ + int retval; + + retval = init_chrdev(); + if (retval < 0) + return retval; + retval = init_lirc_it87(); + if (retval) { + drop_chrdev(); + return retval; + } + return 0; +} + + +void cleanup_module(void) +{ + drop_hardware(); + drop_chrdev(); + drop_port(); + printk(KERN_INFO LIRC_DRIVER_NAME ": Uninstalled.\n"); +} + +MODULE_DESCRIPTION("LIRC driver for ITE IT8712/IT8705 CIR port"); +MODULE_AUTHOR("Hans-Günter Lütke Uphues"); +MODULE_LICENSE("GPL"); + +module_param(io, int, 0444); +MODULE_PARM_DESC(io, "I/O base address (default: 0x310)"); + +module_param(irq, int, 0444); +#ifdef LIRC_IT87_DIGIMATRIX +MODULE_PARM_DESC(irq, "Interrupt (1,3-12) (default: 9)"); +#else +MODULE_PARM_DESC(irq, "Interrupt (1,3-12) (default: 7)"); +#endif + +module_param(it87_enable_demodulator, bool, 0444); +MODULE_PARM_DESC(it87_enable_demodulator, + "Receiver demodulator enable/disable (1/0), default: 0"); + +module_param(debug, bool, 0644); +MODULE_PARM_DESC(debug, "Enable debugging messages"); + +module_param(digimatrix, bool, 0644); +#ifdef LIRC_IT87_DIGIMATRIX +MODULE_PARM_DESC(digimatrix, + "Asus Digimatrix it87 compat. enable/disable (1/0), default: 1"); +#else +MODULE_PARM_DESC(digimatrix, + "Asus Digimatrix it87 compat. enable/disable (1/0), default: 0"); +#endif + + +module_param(it87_freq, int, 0444); +#ifdef LIRC_IT87_DIGIMATRIX +MODULE_PARM_DESC(it87_freq, + "Carrier demodulator frequency (kHz), (default: 36)"); +#else +MODULE_PARM_DESC(it87_freq, + "Carrier demodulator frequency (kHz), (default: 38)"); +#endif + +EXPORT_NO_SYMBOLS; + +#endif /* MODULE */ + + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_streamzap/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_streamzap/Makefile @@ -0,0 +1,3 @@ + +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. +obj-$(CONFIG_LIRC_STREAMZAP) += lirc_streamzap.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_streamzap/lirc_streamzap.c +++ linux-2.6.28/ubuntu/lirc/lirc_streamzap/lirc_streamzap.c @@ -0,0 +1,912 @@ +/* $Id: lirc_streamzap.c,v 1.27 2008/01/13 11:13:50 lirc Exp $ */ + +/* + * Streamzap Remote Control driver + * + * Copyright (c) 2005 Christoph Bartelmus + * + * This driver was based on the work of Greg Wickham and Adrian + * Dewhurst. It was substantially rewritten to support correct signal + * gaps and now maintains a delay buffer, which is used to present + * consistent timing behaviour to user space applications. Without the + * delay buffer an ugly hack would be required in lircd, which can + * cause sluggish signal decoding in certain situations. + * + * This driver is based on the USB skeleton driver packaged with the + * kernel; copyright (C) 2001-2003 Greg Kroah-Hartman (greg@kroah.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) +#error "*******************************************************" +#error "Sorry, this driver needs kernel version 2.4.0 or higher" +#error "*******************************************************" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#include +#else +#include +#endif +#include + +#include "lirc.h" +#include "kcompat.h" +#include "lirc_dev/lirc_dev.h" + +#define DRIVER_VERSION "$Revision: 1.27 $" +#define DRIVER_NAME "lirc_streamzap" +#define DRIVER_DESC "Streamzap Remote Control driver" + +/* ------------------------------------------------------------------ */ + +static int debug; + +#define USB_STREAMZAP_VENDOR_ID 0x0e9c +#define USB_STREAMZAP_PRODUCT_ID 0x0000 + +/* Use our own dbg macro */ +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG DRIVER_NAME "[%d]: " \ + fmt "\n", ## args); \ + } while (0) + +/* + * table of devices that work with this driver + */ +static struct usb_device_id streamzap_table [] = { + { USB_DEVICE(USB_STREAMZAP_VENDOR_ID, USB_STREAMZAP_PRODUCT_ID) }, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(usb, streamzap_table); + +#define STREAMZAP_PULSE_MASK 0xf0 +#define STREAMZAP_SPACE_MASK 0x0f +#define STREAMZAP_RESOLUTION 256 + +/* number of samples buffered */ +#define STREAMZAP_BUFFER_SIZE 128 + +enum StreamzapDecoderState { + PulseSpace, + FullPulse, + FullSpace, + IgnorePulse +}; + +/* Structure to hold all of our device specific stuff */ +/* some remarks regarding locking: + theoretically this struct can be accessed from three threads: + + - from lirc_dev through set_use_inc/set_use_dec + + - from the USB layer throuh probe/disconnect/irq + + Careful placement of lirc_register_plugin/lirc_unregister_plugin + calls will prevent conflicts. lirc_dev makes sure that + set_use_inc/set_use_dec are not being executed and will not be + called after lirc_unregister_plugin returns. + + - by the timer callback + + The timer is only running when the device is connected and the + LIRC device is open. Making sure the timer is deleted by + set_use_dec will make conflicts impossible. +*/ +struct usb_streamzap { + + /* usb */ + /* save off the usb device pointer */ + struct usb_device *udev; + /* the interface for this device */ + struct usb_interface *interface; + + /* buffer & dma */ + unsigned char *buf_in; + dma_addr_t dma_in; + unsigned int buf_in_len; + + struct usb_endpoint_descriptor *endpoint; + + /* IRQ */ + struct urb *urb_in; + + /* lirc */ + struct lirc_plugin plugin; + struct lirc_buffer delay_buf; + struct lirc_buffer lirc_buf; + + /* timer used to support delay buffering */ + struct timer_list delay_timer; + int timer_running; + spinlock_t timer_lock; + + /* tracks whether we are currently receiving some signal */ + int idle; + /* sum of signal lengths received since signal start */ + unsigned long sum; + /* start time of signal; necessary for gap tracking */ + struct timeval signal_last; + struct timeval signal_start; + enum StreamzapDecoderState decoder_state; + struct timer_list flush_timer; + int flush; + int in_use; +}; + + +/* local function prototypes */ +#ifdef KERNEL_2_5 +static int streamzap_probe(struct usb_interface *interface, + const struct usb_device_id *id); +static void streamzap_disconnect(struct usb_interface *interface); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void usb_streamzap_irq(struct urb *urb, struct pt_regs *regs); +#else +static void usb_streamzap_irq(struct urb *urb); +#endif +#else +static void *streamzap_probe(struct usb_device *udev, unsigned int ifnum, + const struct usb_device_id *id); +static void streamzap_disconnect(struct usb_device *dev, void *ptr); +static void usb_streamzap_irq(struct urb *urb); +#endif +static int streamzap_use_inc(void *data); +static void streamzap_use_dec(void *data); +static int streamzap_ioctl(struct inode *node, struct file *filep, + unsigned int cmd, unsigned long arg); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) +static int streamzap_suspend(struct usb_interface *intf, pm_message_t message); +static int streamzap_resume(struct usb_interface *intf); +#endif + +/* usb specific object needed to register this driver with the usb subsystem */ + +static struct usb_driver streamzap_driver = { + LIRC_THIS_MODULE(.owner = THIS_MODULE) + .name = DRIVER_NAME, + .probe = streamzap_probe, + .disconnect = streamzap_disconnect, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) + .suspend = streamzap_suspend, + .resume = streamzap_resume, +#endif + .id_table = streamzap_table, +}; + +static void stop_timer(struct usb_streamzap *sz) +{ + unsigned long flags; + + spin_lock_irqsave(&sz->timer_lock, flags); + if (sz->timer_running) { + sz->timer_running = 0; + del_timer_sync(&sz->delay_timer); + } + spin_unlock_irqrestore(&sz->timer_lock, flags); +} + +static void flush_timeout(unsigned long arg) +{ + struct usb_streamzap *sz = (struct usb_streamzap *) arg; + + /* finally start accepting data */ + sz->flush = 0; +} +static void delay_timeout(unsigned long arg) +{ + unsigned long flags; + /* deliver data every 10 ms */ + static unsigned long timer_inc = + (10000/(1000000/HZ)) == 0 ? 1:(10000/(1000000/HZ)); + struct usb_streamzap *sz = (struct usb_streamzap *) arg; + lirc_t data; + + spin_lock_irqsave(&sz->timer_lock, flags); + + if (!lirc_buffer_empty(&sz->delay_buf) && + !lirc_buffer_full(&sz->lirc_buf)) { + lirc_buffer_read_1(&sz->delay_buf, (unsigned char *) &data); + lirc_buffer_write_1(&sz->lirc_buf, (unsigned char *) &data); + } + if (!lirc_buffer_empty(&sz->delay_buf)) { + while (lirc_buffer_available(&sz->delay_buf) < + STREAMZAP_BUFFER_SIZE/2 && + !lirc_buffer_full(&sz->lirc_buf)) { + lirc_buffer_read_1(&sz->delay_buf, + (unsigned char *) &data); + lirc_buffer_write_1(&sz->lirc_buf, + (unsigned char *) &data); + } + if (sz->timer_running) { + sz->delay_timer.expires += timer_inc; + add_timer(&sz->delay_timer); + } + } else { + sz->timer_running = 0; + } + + if (!lirc_buffer_empty(&sz->lirc_buf)) + wake_up(&sz->lirc_buf.wait_poll); + + spin_unlock_irqrestore(&sz->timer_lock, flags); +} + +static inline void flush_delay_buffer(struct usb_streamzap *sz) +{ + lirc_t data; + int empty = 1; + + while (!lirc_buffer_empty(&sz->delay_buf)) { + empty = 0; + lirc_buffer_read_1(&sz->delay_buf, (unsigned char *) &data); + if (!lirc_buffer_full(&sz->lirc_buf)) { + lirc_buffer_write_1(&sz->lirc_buf, + (unsigned char *) &data); + } else { + dprintk("buffer overflow\n", sz->plugin.minor); + } + } + if (!empty) + wake_up(&sz->lirc_buf.wait_poll); +} + +static inline void push(struct usb_streamzap *sz, unsigned char *data) +{ + unsigned long flags; + + spin_lock_irqsave(&sz->timer_lock, flags); + if (lirc_buffer_full(&sz->delay_buf)) { + lirc_t data; + + lirc_buffer_read_1(&sz->delay_buf, (unsigned char *) &data); + if (!lirc_buffer_full(&sz->lirc_buf)) { + lirc_buffer_write_1(&sz->lirc_buf, + (unsigned char *) &data); + } else { + dprintk("buffer overflow", sz->plugin.minor); + } + } + + lirc_buffer_write_1(&sz->delay_buf, data); + + if (!sz->timer_running) { + sz->delay_timer.expires = jiffies + HZ/10; + add_timer(&sz->delay_timer); + sz->timer_running = 1; + } + + spin_unlock_irqrestore(&sz->timer_lock, flags); +} + +static inline void push_full_pulse(struct usb_streamzap *sz, + unsigned char value) +{ + lirc_t pulse; + + if (sz->idle) { + long deltv; + lirc_t tmp; + + sz->signal_last = sz->signal_start; + do_gettimeofday(&sz->signal_start); + + deltv = sz->signal_start.tv_sec-sz->signal_last.tv_sec; + if (deltv > 15) { + tmp = PULSE_MASK; /* really long time */ + } else { + tmp = (lirc_t) (deltv*1000000+ + sz->signal_start.tv_usec - + sz->signal_last.tv_usec); + tmp -= sz->sum; + } + dprintk("ls %u", sz->plugin.minor, tmp); + push(sz, (char *)&tmp); + + sz->idle = 0; + sz->sum = 0; + } + + pulse = ((lirc_t) value)*STREAMZAP_RESOLUTION; + pulse += STREAMZAP_RESOLUTION/2; + sz->sum += pulse; + pulse |= PULSE_BIT; + + dprintk("p %u", sz->plugin.minor, pulse&PULSE_MASK); + push(sz, (char *)&pulse); +} + +static inline void push_half_pulse(struct usb_streamzap *sz, + unsigned char value) +{ + push_full_pulse(sz, (value & STREAMZAP_PULSE_MASK)>>4); +} + +static inline void push_full_space(struct usb_streamzap *sz, + unsigned char value) +{ + lirc_t space; + + space = ((lirc_t) value)*STREAMZAP_RESOLUTION; + space += STREAMZAP_RESOLUTION/2; + sz->sum += space; + dprintk("s %u", sz->plugin.minor, space); + push(sz, (char *)&space); +} + +static inline void push_half_space(struct usb_streamzap *sz, + unsigned char value) +{ + push_full_space(sz, value & STREAMZAP_SPACE_MASK); +} + +/* + * usb_streamzap_irq - IRQ handler + * + * This procedure is invoked on reception of data from + * the usb remote. + */ +#if defined(KERNEL_2_5) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void usb_streamzap_irq(struct urb *urb, struct pt_regs *regs) +#else +static void usb_streamzap_irq(struct urb *urb) +#endif +{ + struct usb_streamzap *sz; + int len; + unsigned int i = 0; + + if (!urb) + return; + + sz = urb->context; + len = urb->actual_length; + + switch (urb->status) { + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* this urb is terminated, clean up */ + /* sz might already be invalid at this point */ + dprintk("urb status: %d", -1, urb->status); + return; + default: + break; + } + + dprintk("received %d", sz->plugin.minor, urb->actual_length); + if (!sz->flush) { + for (i = 0; i < urb->actual_length; i++) { + dprintk("%d: %x", sz->plugin.minor, + i, (unsigned char) sz->buf_in[i]); + switch (sz->decoder_state) { + case PulseSpace: + if ((sz->buf_in[i]&STREAMZAP_PULSE_MASK) == + STREAMZAP_PULSE_MASK) { + sz->decoder_state = FullPulse; + continue; + } else if ((sz->buf_in[i]&STREAMZAP_SPACE_MASK) + == STREAMZAP_SPACE_MASK) { + push_half_pulse(sz, sz->buf_in[i]); + sz->decoder_state = FullSpace; + continue; + } else { + push_half_pulse(sz, sz->buf_in[i]); + push_half_space(sz, sz->buf_in[i]); + } + break; + case FullPulse: + push_full_pulse(sz, sz->buf_in[i]); + sz->decoder_state = IgnorePulse; + break; + case FullSpace: + if (sz->buf_in[i] == 0xff) { + sz->idle = 1; + stop_timer(sz); + flush_delay_buffer(sz); + } else + push_full_space(sz, sz->buf_in[i]); + sz->decoder_state = PulseSpace; + break; + case IgnorePulse: + if ((sz->buf_in[i]&STREAMZAP_SPACE_MASK) == + STREAMZAP_SPACE_MASK) { + sz->decoder_state = FullSpace; + continue; + } + push_half_space(sz, sz->buf_in[i]); + sz->decoder_state = PulseSpace; + break; + } + } + } + +#ifdef KERNEL_2_5 + /* resubmit only for 2.6 */ + usb_submit_urb(urb, GFP_ATOMIC); +#endif + + return; +} + +/** + * streamzap_probe + * + * Called by usb-core to associated with a candidate device + * On any failure the return value is the ERROR + * On success return 0 + */ +#ifdef KERNEL_2_5 +static int streamzap_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct usb_device *udev = interface_to_usbdev(interface); + struct usb_host_interface *iface_host; +#else +static void *streamzap_probe(struct usb_device *udev, unsigned int ifnum, + const struct usb_device_id *id) +{ + struct usb_interface *interface = &udev->actconfig->interface[ifnum]; + struct usb_interface_descriptor *iface_host; +#endif + int retval = -ENOMEM; + struct usb_streamzap *sz = NULL; + char buf[63], name[128] = ""; + + /*************************************************** + * Allocate space for device driver specific data + */ + sz = kmalloc(sizeof(struct usb_streamzap), GFP_KERNEL); + if (sz == NULL) + goto error; + + memset(sz, 0, sizeof(*sz)); + sz->udev = udev; + sz->interface = interface; + + /*************************************************** + * Check to ensure endpoint information matches requirements + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 5) + iface_host = &interface->altsetting[interface->act_altsetting]; +#else + iface_host = interface->cur_altsetting; +#endif + +#ifdef KERNEL_2_5 + if (iface_host->desc.bNumEndpoints != 1) { +#else + if (iface_host->bNumEndpoints != 1) { +#endif +#ifdef KERNEL_2_5 + err("%s: Unexpected desc.bNumEndpoints (%d)", __FUNCTION__, + iface_host->desc.bNumEndpoints); +#else + err("%s: Unexpected desc.bNumEndpoints (%d)", __FUNCTION__, + iface_host->bNumEndpoints); +#endif + retval = -ENODEV; + goto error; + } + +#ifdef KERNEL_2_5 + sz->endpoint = &(iface_host->endpoint[0].desc); +#else + sz->endpoint = &(iface_host->endpoint[0]); +#endif + if ((sz->endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) + != USB_DIR_IN) { + err("%s: endpoint doesn't match input device 02%02x", + __FUNCTION__, sz->endpoint->bEndpointAddress); + retval = -ENODEV; + goto error; + } + + if ((sz->endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + != USB_ENDPOINT_XFER_INT) { + err("%s: endpoint attributes don't match xfer 02%02x", + __FUNCTION__, sz->endpoint->bmAttributes); + retval = -ENODEV; + goto error; + } + + if (sz->endpoint->wMaxPacketSize == 0) { + err("%s: endpoint message size==0? ", __FUNCTION__); + retval = -ENODEV; + goto error; + } + + /*************************************************** + * Allocate the USB buffer and IRQ URB + */ + + sz->buf_in_len = sz->endpoint->wMaxPacketSize; +#ifdef KERNEL_2_5 + sz->buf_in = usb_buffer_alloc(sz->udev, sz->buf_in_len, + GFP_ATOMIC, &sz->dma_in); +#else + sz->buf_in = kmalloc(sz->buf_in_len, GFP_KERNEL); +#endif + if (sz->buf_in == NULL) + goto error; + +#ifdef KERNEL_2_5 + sz->urb_in = usb_alloc_urb(0, GFP_KERNEL); +#else + + sz->urb_in = usb_alloc_urb(0); +#endif + if (sz->urb_in == NULL) + goto error; + + /*************************************************** + * Connect this device to the LIRC sub-system + */ + + if (lirc_buffer_init(&sz->lirc_buf, sizeof(lirc_t), + STREAMZAP_BUFFER_SIZE)) + goto error; + + if (lirc_buffer_init(&sz->delay_buf, sizeof(lirc_t), + STREAMZAP_BUFFER_SIZE)) { + lirc_buffer_free(&sz->lirc_buf); + goto error; + } + + /*************************************************** + * As required memory is allocated now populate the plugin structure + */ + + memset(&sz->plugin, 0, sizeof(sz->plugin)); + + strcpy(sz->plugin.name, DRIVER_NAME); + sz->plugin.minor = -1; + sz->plugin.sample_rate = 0; + sz->plugin.code_length = sizeof(lirc_t) * 8; + sz->plugin.features = LIRC_CAN_REC_MODE2|LIRC_CAN_GET_REC_RESOLUTION; + sz->plugin.data = sz; + sz->plugin.rbuf = &sz->lirc_buf; + sz->plugin.set_use_inc = &streamzap_use_inc; + sz->plugin.set_use_dec = &streamzap_use_dec; + sz->plugin.ioctl = streamzap_ioctl; +#ifdef LIRC_HAVE_SYSFS + sz->plugin.dev = &udev->dev; +#endif + sz->plugin.owner = THIS_MODULE; + + sz->idle = 1; + sz->decoder_state = PulseSpace; + init_timer(&sz->delay_timer); + sz->delay_timer.function = delay_timeout; + sz->delay_timer.data = (unsigned long) sz; + sz->timer_running = 0; + spin_lock_init(&sz->timer_lock); + + init_timer(&sz->flush_timer); + sz->flush_timer.function = flush_timeout; + sz->flush_timer.data = (unsigned long) sz; + /*************************************************** + * Complete final initialisations + */ + + usb_fill_int_urb(sz->urb_in, udev, + usb_rcvintpipe(udev, sz->endpoint->bEndpointAddress), + sz->buf_in, sz->buf_in_len, usb_streamzap_irq, sz, + sz->endpoint->bInterval); + + if (udev->descriptor.iManufacturer + && usb_string(udev, udev->descriptor.iManufacturer, buf, 63) > 0) + strncpy(name, buf, 128); + + if (udev->descriptor.iProduct + && usb_string(udev, udev->descriptor.iProduct, buf, 63) > 0) + snprintf(name, 128, "%s %s", name, buf); + + printk(KERN_INFO DRIVER_NAME "[%d]: %s on usb%d:%d attached\n", + sz->plugin.minor, name, + udev->bus->busnum, sz->udev->devnum); + +#ifdef KERNEL_2_5 + usb_set_intfdata(interface, sz); +#endif + + if (lirc_register_plugin(&sz->plugin) < 0) { + lirc_buffer_free(&sz->delay_buf); + lirc_buffer_free(&sz->lirc_buf); + goto error; + } + +#ifdef KERNEL_2_5 + return 0; +#else + return sz; +#endif + +error: + + /*************************************************** + * Premise is that a 'goto error' can be invoked from inside the + * probe function and all necessary cleanup actions will be taken + * including freeing any necessary memory blocks + */ + + if (retval == -ENOMEM) + err("Out of memory"); + + if (sz) { + + if (sz->urb_in) + usb_free_urb(sz->urb_in); + + if (sz->buf_in) { +#ifdef KERNEL_2_5 + usb_buffer_free(udev, sz->buf_in_len, + sz->buf_in, sz->dma_in); +#else + kfree(sz->buf_in); +#endif + } + kfree(sz); + } + +#ifdef KERNEL_2_5 + return retval; +#else + return NULL; +#endif +} + +static int streamzap_use_inc(void *data) +{ + struct usb_streamzap *sz = data; + + if (!sz) { + dprintk("%s called with no context", -1, __FUNCTION__); + return -EINVAL; + } + dprintk("set use inc", sz->plugin.minor); + + MOD_INC_USE_COUNT; + + while (!lirc_buffer_empty(&sz->lirc_buf)) + lirc_buffer_remove_1(&sz->lirc_buf); + while (!lirc_buffer_empty(&sz->delay_buf)) + lirc_buffer_remove_1(&sz->delay_buf); + + sz->flush_timer.expires = jiffies + HZ; + sz->flush = 1; + add_timer(&sz->flush_timer); + + sz->urb_in->dev = sz->udev; +#ifdef KERNEL_2_5 + if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) { +#else + if (usb_submit_urb(sz->urb_in)) { +#endif + dprintk("open result = -EIO error submitting urb", + sz->plugin.minor); + MOD_DEC_USE_COUNT; + return -EIO; + } + sz->in_use++; + + return 0; +} + +static void streamzap_use_dec(void *data) +{ + struct usb_streamzap *sz = data; + + if (!sz) { + dprintk("%s called with no context", -1, __FUNCTION__); + return; + } + dprintk("set use dec", sz->plugin.minor); + + if (sz->flush) { + sz->flush = 0; + del_timer_sync(&sz->flush_timer); + } + + stop_timer(sz); + + usb_kill_urb(sz->urb_in); + + MOD_DEC_USE_COUNT; + sz->in_use--; +} + +static int streamzap_ioctl(struct inode *node, struct file *filep, + unsigned int cmd, unsigned long arg) +{ + int result; + + switch (cmd) { + case LIRC_GET_REC_RESOLUTION: + result = put_user(STREAMZAP_RESOLUTION, (unsigned long *) arg); + if (result) + return(result); + break; + default: + return -ENOIOCTLCMD; + } + return 0; +} + +/** + * streamzap_disconnect + * + * Called by the usb core when the device is removed from the system. + * + * This routine guarantees that the driver will not submit any more urbs + * by clearing dev->udev. It is also supposed to terminate any currently + * active urbs. Unfortunately, usb_bulk_msg(), used in streamzap_read(), + * does not provide any way to do this. + */ +#ifdef KERNEL_2_5 +static void streamzap_disconnect(struct usb_interface *interface) +#else +static void streamzap_disconnect(struct usb_device *dev, void *ptr) +#endif +{ + struct usb_streamzap *sz; + int errnum; + int minor; + +#ifdef KERNEL_2_5 + sz = usb_get_intfdata(interface); +#else + sz = ptr; +#endif + + /* + * unregister from the LIRC sub-system + */ + + errnum = lirc_unregister_plugin(sz->plugin.minor); + if (errnum != 0) + dprintk("error in lirc_unregister: (returned %d)", + sz->plugin.minor, errnum); + + lirc_buffer_free(&sz->delay_buf); + lirc_buffer_free(&sz->lirc_buf); + + /* + * unregister from the USB sub-system + */ + + usb_free_urb(sz->urb_in); + +#ifdef KERNEL_2_5 + usb_buffer_free(sz->udev, sz->buf_in_len, sz->buf_in, sz->dma_in); +#else + kfree(sz->buf_in); +#endif + + minor = sz->plugin.minor; + kfree(sz); + + printk(KERN_INFO DRIVER_NAME "[%d]: disconnected\n", minor); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) +static int streamzap_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct usb_streamzap *sz = usb_get_intfdata(intf); + + printk(DRIVER_NAME "[%d]: suspend\n", sz->plugin.minor); + if (sz->in_use) { + if (sz->flush) { + sz->flush = 0; + del_timer_sync(&sz->flush_timer); + } + + stop_timer(sz); + + usb_kill_urb(sz->urb_in); + } + return 0; +} + +static int streamzap_resume(struct usb_interface *intf) +{ + struct usb_streamzap *sz = usb_get_intfdata(intf); + + while (!lirc_buffer_empty(&sz->lirc_buf)) + lirc_buffer_remove_1(&sz->lirc_buf); + while (!lirc_buffer_empty(&sz->delay_buf)) + lirc_buffer_remove_1(&sz->delay_buf); + + if (sz->in_use) { + sz->flush_timer.expires = jiffies + HZ; + sz->flush = 1; + add_timer(&sz->flush_timer); + + sz->urb_in->dev = sz->udev; +#ifdef KERNEL_2_5 + if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) { +#else + if (usb_submit_urb(sz->urb_in)) { +#endif + dprintk("open result = -EIO error submitting urb", + sz->plugin.minor); + MOD_DEC_USE_COUNT; + return -EIO; + } + } + return 0; +} +#endif + +#ifdef MODULE + +/** + * usb_streamzap_init + */ +static int __init usb_streamzap_init(void) +{ + int result; + + /* register this driver with the USB subsystem */ + + result = usb_register(&streamzap_driver); + + if (result) { + err("usb_register failed. Error number %d", + result); + return result; + } + + printk(KERN_INFO DRIVER_NAME " " DRIVER_VERSION " registered\n"); + return 0; +} + +/** + * usb_streamzap_exit + */ +static void __exit usb_streamzap_exit(void) +{ + /* deregister this driver with the USB subsystem */ + usb_deregister(&streamzap_driver); +} + + +module_init(usb_streamzap_init); +module_exit(usb_streamzap_exit); + +MODULE_AUTHOR("Christoph Bartelmus, Greg Wickham, Adrian Dewhurst"); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); + +module_param(debug, bool, 0644); +MODULE_PARM_DESC(debug, "Enable debugging messages"); + +EXPORT_NO_SYMBOLS; + +#endif /* MODULE */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_bt829/lirc_bt829.c +++ linux-2.6.28/ubuntu/lirc/lirc_bt829/lirc_bt829.c @@ -0,0 +1,403 @@ +/* + * Remote control driver for the TV-card based on bt829 + * + * by Leonid Froenchenko + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) +#error "This driver needs kernel version 2.4.0 or higher" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kcompat.h" +#include "lirc_dev/lirc_dev.h" + +static int poll_main(void); +static int atir_init_start(void); + +static void write_index(unsigned char index, unsigned int value); +static unsigned int read_index(unsigned char index); + +static void do_i2c_start(void); +static void do_i2c_stop(void); + +static void seems_wr_byte(unsigned char al); +static unsigned char seems_rd_byte(void); + +static unsigned int read_index(unsigned char al); +static void write_index(unsigned char ah, unsigned int edx); + +static void cycle_delay(int cycle); + +static void do_set_bits(unsigned char bl); +static unsigned char do_get_bits(void); + +#define DATA_PCI_OFF 0x7FFC00 +#define WAIT_CYCLE 20 + +static int debug; +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG fmt, ## args); \ + } while (0) + +static int atir_minor; +static unsigned long pci_addr_phys; +static unsigned char *pci_addr_lin; + +static struct lirc_plugin atir_plugin; + +static struct pci_dev *do_pci_probe(void) +{ + struct pci_dev *my_dev; +#ifndef KERNEL_2_5 + /* unnecessary with recent kernels */ + if (!pci_present()) + printk(KERN_ERR "ATIR: no pci in this kernel\n"); +#endif + my_dev = pci_get_device(PCI_VENDOR_ID_ATI, + PCI_DEVICE_ID_ATI_264VT, NULL); + if (my_dev) { + printk(KERN_ERR "ATIR: Using device: %s\n", + pci_name(my_dev)); + pci_addr_phys = 0; + if (my_dev->resource[0].flags & IORESOURCE_MEM) { + pci_addr_phys = my_dev->resource[0].start; + printk(KERN_INFO "ATIR memory at 0x%08X \n", + (unsigned int)pci_addr_phys); + } + if (pci_addr_phys == 0) { + printk(KERN_ERR "ATIR no memory resource ?\n"); + return NULL; + } + } else { + printk(KERN_ERR "ATIR: pci_prob failed\n"); + return NULL; + } + return my_dev; +} + +static int atir_add_to_buf(void *data, struct lirc_buffer *buf) +{ + unsigned char key; + int status; + status = poll_main(); + key = (status >> 8) & 0xFF; + if (status & 0xFF) { + dprintk("ATIR reading key %02X\n", key); + lirc_buffer_write_1(buf, &key); + return 0; + } + return -ENODATA; +} + +static int atir_set_use_inc(void *data) +{ + MOD_INC_USE_COUNT; + dprintk("ATIR driver is opened\n"); + return 0; +} + +static void atir_set_use_dec(void *data) +{ + MOD_DEC_USE_COUNT; + dprintk("ATIR driver is closed\n"); +} + +int init_module(void) +{ + struct pci_dev *pdev; + + pdev = do_pci_probe(); + if (pdev == NULL) + return 1; + + if (!atir_init_start()) + return 1; + + strcpy(atir_plugin.name, "ATIR"); + atir_plugin.minor = -1; + atir_plugin.code_length = 8; + atir_plugin.sample_rate = 10; + atir_plugin.data = 0; + atir_plugin.add_to_buf = atir_add_to_buf; + atir_plugin.set_use_inc = atir_set_use_inc; + atir_plugin.set_use_dec = atir_set_use_dec; +#ifdef LIRC_HAVE_SYSFS + atir_plugin.dev = &pdev->dev; +#endif + atir_plugin.owner = THIS_MODULE; + + atir_minor = lirc_register_plugin(&atir_plugin); + dprintk("ATIR driver is registered on minor %d\n", atir_minor); + + return 0; +} + + +void cleanup_module(void) +{ + lirc_unregister_plugin(atir_minor); +} + + +static int atir_init_start(void) +{ + pci_addr_lin = ioremap(pci_addr_phys + DATA_PCI_OFF, 0x400); + if (pci_addr_lin == 0) { + printk(KERN_INFO "atir: pci mem must be mapped\n"); + return 0; + } + return 1; +} + +static void cycle_delay(int cycle) +{ + udelay(WAIT_CYCLE*cycle); +} + + +static int poll_main() +{ + unsigned char status_high, status_low; + + do_i2c_start(); + + seems_wr_byte(0xAA); + seems_wr_byte(0x01); + + do_i2c_start(); + + seems_wr_byte(0xAB); + + status_low = seems_rd_byte(); + status_high = seems_rd_byte(); + + do_i2c_stop(); + + return (status_high << 8) | status_low; +} + +static void do_i2c_start(void) +{ + do_set_bits(3); + cycle_delay(4); + + do_set_bits(1); + cycle_delay(7); + + do_set_bits(0); + cycle_delay(2); +} + +static void do_i2c_stop(void) +{ + unsigned char bits; + bits = do_get_bits() & 0xFD; + do_set_bits(bits); + cycle_delay(1); + + bits |= 1; + do_set_bits(bits); + cycle_delay(2); + + bits |= 2; + do_set_bits(bits); + bits = 3; + do_set_bits(bits); + cycle_delay(2); +} + +static void seems_wr_byte(unsigned char value) +{ + int i; + unsigned char reg; + + reg = do_get_bits(); + for (i = 0; i < 8; i++) { + if (value & 0x80) + reg |= 0x02; + else + reg &= 0xFD; + + do_set_bits(reg); + cycle_delay(1); + + reg |= 1; + do_set_bits(reg); + cycle_delay(1); + + reg &= 0xFE; + do_set_bits(reg); + cycle_delay(1); + value <<= 1; + } + cycle_delay(2); + + reg |= 2; + do_set_bits(reg); + + reg |= 1; + do_set_bits(reg); + + cycle_delay(1); + do_get_bits(); + + reg &= 0xFE; + do_set_bits(reg); + cycle_delay(3); +} + +static unsigned char seems_rd_byte(void) +{ + int i; + int rd_byte; + unsigned char bits_2, bits_1; + + bits_1 = do_get_bits() | 2; + do_set_bits(bits_1); + + rd_byte = 0; + for (i = 0; i < 8; i++) { + bits_1 &= 0xFE; + do_set_bits(bits_1); + cycle_delay(2); + + bits_1 |= 1; + do_set_bits(bits_1); + cycle_delay(1); + + bits_2 = do_get_bits(); + if (bits_2 & 2) + rd_byte |= 1; + + rd_byte <<= 1; + } + + bits_1 = 0; + if (bits_2 == 0) + bits_1 |= 2; + + do_set_bits(bits_1); + cycle_delay(2); + + bits_1 |= 1; + do_set_bits(bits_1); + cycle_delay(3); + + bits_1 &= 0xFE; + do_set_bits(bits_1); + cycle_delay(2); + + rd_byte >>= 1; + rd_byte &= 0xFF; + return rd_byte; +} + +static void do_set_bits(unsigned char new_bits) +{ + int reg_val; + reg_val = read_index(0x34); + if (new_bits & 2) { + reg_val &= 0xFFFFFFDF; + reg_val |= 1; + } else { + reg_val &= 0xFFFFFFFE; + reg_val |= 0x20; + } + reg_val |= 0x10; + write_index(0x34, reg_val); + + reg_val = read_index(0x31); + if (new_bits & 1) { + reg_val |= 0x1000000; + } else { + reg_val &= 0xFEFFFFFF; + } + reg_val |= 0x8000000; + write_index(0x31, reg_val); +} + +static unsigned char do_get_bits(void) +{ + unsigned char bits; + int reg_val; + + reg_val = read_index(0x34); + reg_val |= 0x10; + reg_val &= 0xFFFFFFDF; + write_index(0x34, reg_val); + + reg_val = read_index(0x34); + bits = 0; + if (reg_val & 8) { + bits |= 2; + } else { + bits &= 0xFD; + } + reg_val = read_index(0x31); + if (reg_val & 0x1000000) { + bits |= 1; + } else { + bits &= 0xFE; + } + return bits; +} + +static unsigned int read_index(unsigned char index) +{ + unsigned char *addr; + unsigned int value; + /* addr = pci_addr_lin + DATA_PCI_OFF + ((index & 0xFF) << 2); */ + addr = pci_addr_lin + ((index & 0xFF) << 2); + value = readl(addr); + return value; +} + +static void write_index(unsigned char index, unsigned int reg_val) +{ + unsigned char *addr; + addr = pci_addr_lin + ((index & 0xFF) << 2); + writel(reg_val, addr); +} + +MODULE_AUTHOR("Froenchenko Leonid"); +MODULE_DESCRIPTION("IR remote driver for bt829 based TV cards"); +MODULE_LICENSE("GPL"); + +module_param(debug, bool, 0644); +MODULE_PARM_DESC(debug, "Debug enabled or not"); + +EXPORT_NO_SYMBOLS; + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_bt829/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_bt829/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_ATIUSB) += lirc_bt829.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_atiusb/lirc_atiusb.c +++ linux-2.6.28/ubuntu/lirc/lirc_atiusb/lirc_atiusb.c @@ -0,0 +1,1437 @@ +/* lirc_atiusb - USB remote support for LIRC + * (currently only supports X10 USB remotes) + * (supports ATI Remote Wonder and ATI Remote Wonder II, too) + * + * Copyright (C) 2003-2004 Paul Miller + * + * This driver was derived from: + * Vladimir Dergachev 's 2002 + * "USB ATI Remote support" (input device) + * Adrian Dewhurst 's 2002 + * "USB StreamZap remote driver" (LIRC) + * Artur Lipowski 's 2002 + * "lirc_dev" and "lirc_gpio" LIRC modules + * Michael Wojciechowski + * initial xbox support + * Vassilis Virvilis 2006 + * reworked the patch for lirc submission + * + * $Id: lirc_atiusb.c,v 1.69 2008/04/28 06:47:29 lirc Exp $ + */ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) +#error "*******************************************************" +#error "Sorry, this driver needs kernel version 2.4.0 or higher" +#error "*******************************************************" +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#include +#else +#include +#endif +#include +#include +#include +#include + +#include "lirc.h" +#include "kcompat.h" +#include "lirc_dev/lirc_dev.h" + +#define DRIVER_VERSION "$Revision: 1.69 $" +#define DRIVER_AUTHOR "Paul Miller " +#define DRIVER_DESC "USB remote driver for LIRC" +#define DRIVER_NAME "lirc_atiusb" + +#define CODE_LENGTH code_length[ir->remote_type] +#define CODE_MIN_LENGTH code_min_length[ir->remote_type] +#define DECODE_LENGTH decode_length[ir->remote_type] + +#define RW2_MODENAV_KEYCODE 0x3F +#define RW2_NULL_MODE 0xFF +/* Fake (virtual) keycode indicating compass mouse usage */ +#define RW2_MOUSE_KEYCODE 0xFF +#define RW2_PRESSRELEASE_KEYCODE 0xFE + +#define RW2_PRESS_CODE 1 +#define RW2_HOLD_CODE 2 +#define RW2_RELEASE_CODE 0 + +/* module parameters */ +#ifdef CONFIG_USB_DEBUG +static int debug = 1; +#else +static int debug; +#endif +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG fmt, ## args); \ + } while (0) + +/* ATI, ATI2, XBOX */ +static const int code_length[] = {5, 3, 6}; +static const int code_min_length[] = {3, 3, 6}; +static const int decode_length[] = {5, 3, 1}; +/* USB_BUFF_LEN must be the maximum value of the code_length array. + * It is used for static arrays. */ +#define USB_BUFF_LEN 6 + +static int mask = 0xFFFF; /* channel acceptance bit mask */ +static int unique; /* enable channel-specific codes */ +static int repeat = 10; /* repeat time in 1/100 sec */ +static int emit_updown; /* send seperate press/release codes (rw2) */ +static int emit_modekeys; /* send keycodes for aux1-4, pc, and mouse (rw2) */ +static unsigned long repeat_jiffies; /* repeat timeout */ +static int mdeadzone; /* mouse sensitivity >= 0 */ +static int mgradient = 375; /* 1000*gradient from cardinal direction */ + +/* get hi and low bytes of a 16-bits int */ +#define HI(a) ((unsigned char)((a) >> 8)) +#define LO(a) ((unsigned char)((a) & 0xff)) + +/* lock irctl structure */ +#define IRLOCK down_interruptible(&ir->lock) +#define IRUNLOCK up(&ir->lock) + +/* general constants */ +#define SUCCESS 0 +#define SEND_FLAG_IN_PROGRESS 1 +#define SEND_FLAG_COMPLETE 2 +#define FREE_ALL 0xFF + +/* endpoints */ +#define EP_KEYS 0 +#define EP_MOUSE 1 +#define EP_MOUSE_ADDR 0x81 +#define EP_KEYS_ADDR 0x82 + +#define VENDOR_ATI1 0x0bc7 +#define VENDOR_ATI2 0x0471 +#define VENDOR_MS1 0x040b +#define VENDOR_MS2 0x045e +#define VENDOR_MS3 0xFFFF + +static struct usb_device_id usb_remote_table [] = { + /* X10 USB Firecracker Interface */ + { USB_DEVICE(VENDOR_ATI1, 0x0002) }, + + /* X10 VGA Video Sender */ + { USB_DEVICE(VENDOR_ATI1, 0x0003) }, + + /* ATI Wireless Remote Receiver */ + { USB_DEVICE(VENDOR_ATI1, 0x0004) }, + + /* NVIDIA Wireless Remote Receiver */ + { USB_DEVICE(VENDOR_ATI1, 0x0005) }, + + /* ATI Wireless Remote Receiver */ + { USB_DEVICE(VENDOR_ATI1, 0x0006) }, + + /* X10 USB Wireless Transceivers */ + { USB_DEVICE(VENDOR_ATI1, 0x0007) }, + { USB_DEVICE(VENDOR_ATI1, 0x0008) }, + { USB_DEVICE(VENDOR_ATI1, 0x0009) }, + { USB_DEVICE(VENDOR_ATI1, 0x000A) }, + { USB_DEVICE(VENDOR_ATI1, 0x000B) }, + { USB_DEVICE(VENDOR_ATI1, 0x000C) }, + { USB_DEVICE(VENDOR_ATI1, 0x000D) }, + { USB_DEVICE(VENDOR_ATI1, 0x000E) }, + { USB_DEVICE(VENDOR_ATI1, 0x000F) }, + + /* ATI Remote Wonder 2: Input Device */ + { USB_DEVICE(VENDOR_ATI2, 0x0602) }, + + /* ATI Remote Wonder 2: Controller (???) */ + { USB_DEVICE(VENDOR_ATI2, 0x0603) }, + + /* Gamester Xbox DVD Movie Playback Kit IR */ + { USB_DEVICE(VENDOR_MS1, 0x6521) }, + + /* Microsoft Xbox DVD Movie Playback Kit IR */ + { USB_DEVICE(VENDOR_MS2, 0x0284) }, + + /* Some chinese manufacterer -- conflicts with the joystick from the + * same manufacterer */ + { USB_DEVICE(VENDOR_MS3, 0xFFFF) }, + + /* Terminating entry */ + { } +}; + + +/* init strings */ +#define USB_OUTLEN 7 + +static char init1[] = {0x01, 0x00, 0x20, 0x14}; +static char init2[] = {0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20}; + +struct in_endpt { + /* inner link in list of endpoints for the remote specified by ir */ + struct list_head iep_list_link; + struct irctl *ir; + struct urb *urb; + struct usb_endpoint_descriptor *ep; + int type; + + /* buffers and dma */ + unsigned char *buf; + unsigned int len; +#ifdef KERNEL_2_5 + dma_addr_t dma; +#endif + + /* handle repeats */ + unsigned char old[USB_BUFF_LEN]; + unsigned long old_jiffies; +}; + +struct out_endpt { + struct irctl *ir; + struct urb *urb; + struct usb_endpoint_descriptor *ep; + + /* buffers and dma */ + unsigned char *buf; +#ifdef KERNEL_2_5 + dma_addr_t dma; +#endif + + /* handle sending (init strings) */ + int send_flags; + wait_queue_head_t wait; +}; + + +/* data structure for each usb remote */ +struct irctl { + /* inner link in list of all remotes managed by this module */ + struct list_head remote_list_link; + /* Number of usb interfaces associated with this device */ + int dev_refcount; + + /* usb */ + struct usb_device *usbdev; + /* Head link to list of all inbound endpoints in this remote */ + struct list_head iep_listhead; + struct out_endpt *out_init; + int devnum; + + /* remote type based on usb_device_id tables */ + enum { + ATI1_COMPATIBLE, + ATI2_COMPATIBLE, + XBOX_COMPATIBLE + } remote_type; + + /* rw2 current mode (mirror's remote's state) */ + int mode; + + /* lirc */ + struct lirc_plugin *p; + int connected; + + /* locking */ + struct semaphore lock; +}; + +/* list of all registered devices via the remote_list_link in irctl */ +static struct list_head remote_list; + +/* Convenience macros to retrieve a pointer to the surrounding struct from + * the given list_head reference within, pointed at by link. */ +#define get_iep_from_link(link) \ + list_entry((link), struct in_endpt, iep_list_link); +#define get_irctl_from_link(link) \ + list_entry((link), struct irctl, remote_list_link); + +/* send packet - used to initialize remote */ +static void send_packet(struct out_endpt *oep, u16 cmd, unsigned char *data) +{ + struct irctl *ir = oep->ir; + DECLARE_WAITQUEUE(wait, current); + int timeout = HZ; /* 1 second */ + unsigned char buf[USB_OUTLEN]; + + dprintk(DRIVER_NAME "[%d]: send called (%#x)\n", ir->devnum, cmd); + + IRLOCK; + oep->urb->transfer_buffer_length = LO(cmd) + 1; + oep->urb->dev = oep->ir->usbdev; + oep->send_flags = SEND_FLAG_IN_PROGRESS; + + memcpy(buf+1, data, LO(cmd)); + buf[0] = HI(cmd); + memcpy(oep->buf, buf, LO(cmd)+1); + + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&oep->wait, &wait); + +#ifdef KERNEL_2_5 + if (usb_submit_urb(oep->urb, GFP_ATOMIC)) { +#else + if (usb_submit_urb(oep->urb)) { +#endif + set_current_state(TASK_RUNNING); + remove_wait_queue(&oep->wait, &wait); + IRUNLOCK; + return; + } + IRUNLOCK; + + while (timeout && (oep->urb->status == -EINPROGRESS) + && !(oep->send_flags & SEND_FLAG_COMPLETE)) { + timeout = schedule_timeout(timeout); + rmb(); + } + + dprintk(DRIVER_NAME "[%d]: send complete (%#x)\n", ir->devnum, cmd); + + set_current_state(TASK_RUNNING); + remove_wait_queue(&oep->wait, &wait); +#ifdef KERNEL_2_5 + oep->urb->transfer_flags |= URB_ASYNC_UNLINK; +#endif + usb_unlink_urb(oep->urb); +} + +static int unregister_from_lirc(struct irctl *ir) +{ + struct lirc_plugin *p = ir->p; + int devnum; + + devnum = ir->devnum; + dprintk(DRIVER_NAME "[%d]: unregister from lirc called\n", devnum); + + lirc_unregister_plugin(p->minor); + + printk(DRIVER_NAME "[%d]: usb remote disconnected\n", devnum); + return SUCCESS; +} + + +static int set_use_inc(void *data) +{ + struct irctl *ir = data; + struct list_head *pos, *n; + struct in_endpt *iep; + int rtn; + + if (!ir) { + printk(DRIVER_NAME "[?]: set_use_inc called with no context\n"); + return -EIO; + } + dprintk(DRIVER_NAME "[%d]: set use inc\n", ir->devnum); + + MOD_INC_USE_COUNT; + + IRLOCK; + if (!ir->connected) { + if (!ir->usbdev) { + IRUNLOCK; + dprintk(DRIVER_NAME "[%d]: !ir->usbdev\n", ir->devnum); + return -ENOENT; + } + + /* Iterate through the inbound endpoints */ + list_for_each_safe(pos, n, &ir->iep_listhead) { + /* extract the current in_endpt */ + iep = get_iep_from_link(pos); + iep->urb->dev = ir->usbdev; + dprintk(DRIVER_NAME "[%d]: linking iep 0x%02x (%p)\n", + ir->devnum, iep->ep->bEndpointAddress, iep); +#ifdef KERNEL_2_5 + rtn = usb_submit_urb(iep->urb, GFP_ATOMIC); +#else + rtn = usb_submit_urb(iep->urb); +#endif + if (rtn) { + printk(DRIVER_NAME "[%d]: open result = %d " + "error submitting urb\n", + ir->devnum, rtn); + IRUNLOCK; + MOD_DEC_USE_COUNT; + return -EIO; + } + } + ir->connected = 1; + } + IRUNLOCK; + + return SUCCESS; +} + +static void set_use_dec(void *data) +{ + struct irctl *ir = data; + struct list_head *pos, *n; + struct in_endpt *iep; + + if (!ir) { + printk(DRIVER_NAME "[?]: set_use_dec called with no context\n"); + return; + } + dprintk(DRIVER_NAME "[%d]: set use dec\n", ir->devnum); + + IRLOCK; + if (ir->connected) { + /* Free inbound usb urbs */ + list_for_each_safe(pos, n, &ir->iep_listhead) { + iep = get_iep_from_link(pos); + dprintk(DRIVER_NAME "[%d]: unlinking iep 0x%02x (%p)\n", + ir->devnum, iep->ep->bEndpointAddress, iep); + usb_kill_urb(iep->urb); + } + ir->connected = 0; + } + IRUNLOCK; + MOD_DEC_USE_COUNT; +} + +static void print_data(struct in_endpt *iep, char *buf, int len) +{ + const int clen = code_length[iep->ir->remote_type]; + char codes[clen * 3 + 1]; + int i; + + if (len <= 0) + return; + + for (i = 0; i < len && i < clen; i++) + snprintf(codes+i*3, 4, "%02x ", buf[i] & 0xFF); + printk(DRIVER_NAME "[%d]: data received %s (ep=0x%x length=%d)\n", + iep->ir->devnum, codes, iep->ep->bEndpointAddress, len); +} + +static int code_check_ati1(struct in_endpt *iep, int len) +{ + struct irctl *ir = iep->ir; + int i, chan; + + /* ATI RW1: some remotes emit both 4 and 5 byte length codes. */ + /* ATI RW2: emit 3 byte codes */ + if (len < CODE_MIN_LENGTH || len > CODE_LENGTH) + return -1; + + /* *** channel not tested with 4/5-byte Dutch remotes *** */ + chan = ((iep->buf[len-1]>>4) & 0x0F); + + /* strip channel code */ + if (!unique) { + iep->buf[len-1] &= 0x0F; + iep->buf[len-3] -= (chan<<4); + } + + if (!((1U<devnum, chan+1); + return -1; + } + dprintk(DRIVER_NAME "[%d]: accept channel %d\n", ir->devnum, chan+1); + + if (ir->remote_type == ATI1_COMPATIBLE) { + for (i = len; i < CODE_LENGTH; i++) iep->buf[i] = 0; + /* check for repeats */ + if (memcmp(iep->old, iep->buf, len) == 0) { + if (iep->old_jiffies + repeat_jiffies > jiffies) + return -1; + } else + memcpy(iep->old, iep->buf, CODE_LENGTH); + iep->old_jiffies = jiffies; + } + + return SUCCESS; +} + +/* + * Since the ATI Remote Wonder II has quite a different structure from the + * prior version, this function was seperated out to clarify the sanitization + * process. + * + * Here is a summary of the main differences: + * + * a. The rw2 has no sense of a transmission channel. But, it does have an + * auxilliary mode state, which is set by the mode buttons Aux1 through + * Aux4 and "PC". These map respectively to 0-4 in the first byte of the + * recv buffer. Any subsequent button press sends this mode number as its + * "channel code." Annoyingly enough, the mode setting buttons all send + * the same key code (0x3f), and can only be distinguished via their mode + * byte. + * + * Because of this, old-style "unique"-parameter-enabled channel squashing + * kills the functionality of the aux1-aux4 and PC buttons. However, to + * not do so would cause each remote key to send a different code depending + * on the active aux. Further complicating matters, using the mouse norb + * also sends an identical code as would pushing the active aux button. To + * handle this we need a seperate parameter, like rw2modes, with the + * following values and meanings: + * + * 0: Don't squash any channel info + * 1: Only squash channel data for non-mode setting keys + * 2: Ignore aux keypresses, but don't squash channel + * 3: Ignore aux keypresses and squash channel data + * + * Option 1 may seem useless since the mouse sends the same code, but one + * need only ignore in userspace any press of a mode-setting code that only + * reaffirms the current mode. The 3rd party lirccd should be able to + * handle this easily enough, but lircd doesn't keep the state necessary + * for this. TODO We could work around this in the driver by emitting a + * single 02 (press) code for a mode key only if that mode is not currently + * active. + * + * Option 2 would be useful for those wanting super configurability, + * offering the ability to program 5 times the number actions based on the + * current mode. + * + * b. The rw2 has its own built in repeat handling; the keys endpoint + * encodes this in the second byte as 1 for press, 2 for hold, and 0 for + * release. This is generally much more responsive than lirc's built-in + * timeout handling. + * + * The problem is that the remote can send the release-recieve pair + * (0,1) while one is still holding down the same button if the + * transmission is momentarilly interrupted. (It seems that the receiver + * manages this count instead of the remote.) By default, this information + * is squashed to 2. + * + * In order to expose the built-in repeat code, set the emit_updown + * parameter as described below. + * + * c. The mouse norb is much more sensitive than on the rw1. It emulates + * a joystick-like controller with the second byte representing the x-axis + * and the third, the y-axis. Treated as signed integers, these axes range + * approximately as follows: + * + * x: (left) -46 ... 46 (right) (0xd2..0x2e) + * y: (up) -46 ... 46 (down) (0xd2..0x2e) + * + * NB these values do not correspond to the pressure with which the mouse + * norb is pushed in a given direction, but rather seems to indicate the + * duration for which a given direction is held. + * + * These are normalized to 8 cardinal directions for easy configuration via + * lircd.conf. The normalization can be fined tuned with the mdeadzone and + * mgradient parameters as described below. + * + * d. The interrupt rate of the mouse vs. the normal keys is different. + * + * mouse: ~27Hz (37ms between interrupts) + * keys: ~10Hz (100ms between interrupts) + * + * This means that the normal gap mechanism for lircd won't work as + * expected; is emit_updown>0 if you can get away with it. + */ +static int code_check_ati2(struct in_endpt *iep, int len) +{ + struct irctl *ir = iep->ir; + int mode, i; + char *buf = iep->buf; + + if (len != CODE_LENGTH) { + dprintk(DRIVER_NAME + "[%d]: Huh? Abnormal length (%d) buffer recieved.\n", + ir->devnum, len); + return -1; + } + for (i = len; i < CODE_LENGTH; i++) iep->buf[i] = 0; + + mode = buf[0]; + + /* Squash the mode indicator if unique wasn't set non-zero */ + if (!unique) + buf[0] = 0; + + if (iep->ep->bEndpointAddress == EP_KEYS_ADDR) { + /* ignore mouse navigation indicator key and + * mode-set (aux) keys */ + if (buf[2] == RW2_MODENAV_KEYCODE) { + if (emit_modekeys >= 2) /* emit raw */ + buf[0] = mode; + else if (emit_modekeys == 1) { + /* translate */ + buf[0] = mode; + if (ir->mode != mode) { + buf[1] = 0x03; + ir->mode = mode; + return SUCCESS; + } + } else { + dprintk(DRIVER_NAME + "[%d]: ignore dummy code 0x%x " + "(ep=0x%x)\n", ir->devnum, + buf[2], iep->ep->bEndpointAddress); + return -1; + } + } + + if (buf[1] != 2) { + /* handle press/release codes */ + if (emit_updown == 0) /* ignore */ + return -1; + else if (emit_updown == 1) /* normalize keycode */ + buf[2] = RW2_PRESSRELEASE_KEYCODE; + /* else emit raw */ + } + + } else { + int x = (signed char)buf[1]; + int y = (signed char)buf[2]; + int code = 0x00; + int dir_ew, dir_ns; + + buf[2] = RW2_MOUSE_KEYCODE; + + /* sensitivity threshold (use L2norm^2) */ + if (mdeadzone > (x*x+y*y)) { + buf[1] = 0x00; + return SUCCESS; + } + +/* Nybble encoding: xy, 2 is -1 (S or W); 1 (N or E) */ +#define MOUSE_N 0x01 +#define MOUSE_NE 0x11 +#define MOUSE_E 0x10 +#define MOUSE_SE 0x12 +#define MOUSE_S 0x02 +#define MOUSE_SW 0x22 +#define MOUSE_W 0x20 +#define MOUSE_NW 0x21 + + /* cardinal leanings: positive x -> E, positive y -> S */ + dir_ew = (x > 0) ? MOUSE_E : MOUSE_W; + dir_ns = (y > 0) ? MOUSE_S : MOUSE_N; + + /* convert coordintes(angle) into compass direction */ + if (x == 0) + code = dir_ns; + else if (y == 0) + code = dir_ew; + else { + if (abs(1000*y/x) > mgradient) + code = dir_ns; + if (abs(1000*x/y) > mgradient) + code |= dir_ew; + } + + buf[1] = code; + dprintk(DRIVER_NAME "[%d]: mouse compass=0x%x %s%s (%d,%d)\n", + ir->devnum, code, + (code & MOUSE_S ? "S" : (code & MOUSE_N ? "N" : "")), + (code & MOUSE_E ? "E" : (code & MOUSE_W ? "W" : "")), + x, y); + } + + return SUCCESS; +} + +static int code_check_xbox(struct in_endpt *iep, int len) +{ + struct irctl *ir = iep->ir; + const int clen = CODE_LENGTH; + + if (len != clen) { + dprintk(DRIVER_NAME ": We got %d instead of %d bytes from xbox " + "ir.. ?\n", len, clen); + return -1; + } + + /* check for repeats */ + if (memcmp(iep->old, iep->buf, len) == 0) { + if (iep->old_jiffies + repeat_jiffies > jiffies) + return -1; + } else { + /* the third byte of xbox ir packet seems to contain key info + * the last two bytes are.. some kind of clock? */ + iep->buf[0] = iep->buf[2]; + memset(iep->buf + 1, 0, len - 1); + memcpy(iep->old, iep->buf, len); + } + iep->old_jiffies = jiffies; + + return SUCCESS; +} + +#if defined(KERNEL_2_5) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void usb_remote_recv(struct urb *urb, struct pt_regs *regs) +#else +static void usb_remote_recv(struct urb *urb) +#endif +{ + struct in_endpt *iep; + int len, result = -1; + + if (!urb) + return; + iep = urb->context; + if (!iep) { +#ifdef KERNEL_2_5 + urb->transfer_flags |= URB_ASYNC_UNLINK; +#endif + usb_unlink_urb(urb); + return; + } + if (!iep->ir->usbdev) + return; + + len = urb->actual_length; + if (debug) + print_data(iep, urb->transfer_buffer, len); + + switch (urb->status) { + + /* success */ + case SUCCESS: + switch (iep->ir->remote_type) { + case XBOX_COMPATIBLE: + result = code_check_xbox(iep, len); + break; + case ATI2_COMPATIBLE: + result = code_check_ati2(iep, len); + break; + case ATI1_COMPATIBLE: + default: + result = code_check_ati1(iep, len); + } + if (result < 0) + break; + lirc_buffer_write_1(iep->ir->p->rbuf, iep->buf); + wake_up(&iep->ir->p->rbuf->wait_poll); + break; + + /* unlink */ + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: +#ifdef KERNEL_2_5 + urb->transfer_flags |= URB_ASYNC_UNLINK; +#endif + usb_unlink_urb(urb); + return; + + case -EPIPE: + default: + break; + } + + /* resubmit urb */ +#ifdef KERNEL_2_5 + usb_submit_urb(urb, GFP_ATOMIC); +#endif +} + +#if defined(KERNEL_2_5) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void usb_remote_send(struct urb *urb, struct pt_regs *regs) +#else +static void usb_remote_send(struct urb *urb) +#endif +{ + struct out_endpt *oep; + + if (!urb) + return; + oep = urb->context; + if (!oep) { +#ifdef KERNEL_2_5 + urb->transfer_flags |= URB_ASYNC_UNLINK; +#endif + usb_unlink_urb(urb); + return; + } + if (!oep->ir->usbdev) + return; + + dprintk(DRIVER_NAME "[%d]: usb out called\n", oep->ir->devnum); + + if (urb->status) + return; + + oep->send_flags |= SEND_FLAG_COMPLETE; + wmb(); + if (waitqueue_active(&oep->wait)) + wake_up(&oep->wait); +} + + +/*************************************************************************** + * Initialization and removal + ***************************************************************************/ + +/* + * Free iep according to mem_failure which specifies a checkpoint into the + * initialization sequence for rollback recovery. + */ +static void free_in_endpt(struct in_endpt *iep, int mem_failure) +{ + struct irctl *ir; + dprintk(DRIVER_NAME ": free_in_endpt(%p, %d)\n", iep, mem_failure); + if (!iep) + return; + + ir = iep->ir; + if (!ir) { + dprintk(DRIVER_NAME ": free_in_endpt: WARNING! null ir\n"); + return; + } + IRLOCK; + switch (mem_failure) { + case FREE_ALL: + case 5: + list_del(&iep->iep_list_link); + dprintk(DRIVER_NAME "[%d]: free_in_endpt removing ep=0x%0x " + "from list\n", ir->devnum, iep->ep->bEndpointAddress); + case 4: + if (iep->urb) { +#ifdef KERNEL_2_5 + iep->urb->transfer_flags |= URB_ASYNC_UNLINK; +#endif + usb_unlink_urb(iep->urb); + usb_free_urb(iep->urb); + iep->urb = 0; + } else + dprintk(DRIVER_NAME "[%d]: free_in_endpt null urb!\n", + ir->devnum); + case 3: +#ifdef KERNEL_2_5 + usb_buffer_free(iep->ir->usbdev, iep->len, iep->buf, iep->dma); +#else + kfree(iep->buf); +#endif + iep->buf = 0; + case 2: + kfree(iep); + } + IRUNLOCK; +} + +/* + * Construct a new inbound endpoint for this remote, and add it to the list of + * in_epts in ir. + */ +static struct in_endpt *new_in_endpt(struct irctl *ir, + struct usb_endpoint_descriptor *ep) +{ + struct usb_device *dev = ir->usbdev; + struct in_endpt *iep; + int pipe, maxp, len, addr; + int mem_failure; + + addr = ep->bEndpointAddress; + pipe = usb_rcvintpipe(dev, addr); + maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); + +/* len = (maxp > USB_BUFLEN) ? USB_BUFLEN : maxp; + * len -= (len % CODE_LENGTH); */ + len = CODE_LENGTH; + + dprintk(DRIVER_NAME "[%d]: acceptable inbound endpoint (0x%x) found " + "(maxp=%d len=%d)\n", ir->devnum, addr, maxp, len); + + mem_failure = 0; + iep = kmalloc(sizeof(*iep), GFP_KERNEL); + if (!iep) { + mem_failure = 1; + goto new_in_endpt_failure_check; + } + memset(iep, 0, sizeof(*iep)); + iep->ir = ir; + iep->ep = ep; + iep->len = len; + +#ifdef KERNEL_2_5 + iep->buf = usb_buffer_alloc(dev, len, GFP_ATOMIC, &iep->dma); +#else + iep->buf = kmalloc(len, GFP_KERNEL); +#endif + if (!iep->buf) { + mem_failure = 2; + goto new_in_endpt_failure_check; + } + +#ifdef KERNEL_2_5 + iep->urb = usb_alloc_urb(0, GFP_KERNEL); +#else + iep->urb = usb_alloc_urb(0); +#endif + if (!iep->urb) + mem_failure = 3; + +new_in_endpt_failure_check: + + if (mem_failure) { + free_in_endpt(iep, mem_failure); + printk(DRIVER_NAME "[%d]: ep=0x%x out of memory (code=%d)\n", + ir->devnum, addr, mem_failure); + return NULL; + } + list_add_tail(&iep->iep_list_link, &ir->iep_listhead); + dprintk(DRIVER_NAME "[%d]: adding ep=0x%0x to list\n", + ir->devnum, iep->ep->bEndpointAddress); + return iep; +} + +static void free_out_endpt(struct out_endpt *oep, int mem_failure) +{ + struct irctl *ir; + dprintk(DRIVER_NAME ": free_out_endpt(%p, %d)\n", oep, mem_failure); + if (!oep) + return; + + wake_up_all(&oep->wait); + + ir = oep->ir; + if (!ir) { + dprintk(DRIVER_NAME ": free_out_endpt: WARNING! null ir\n"); + return; + } + IRLOCK; + switch (mem_failure) { + case FREE_ALL: + case 4: + if (oep->urb) { +#ifdef KERNEL_2_5 + oep->urb->transfer_flags |= URB_ASYNC_UNLINK; +#endif + usb_unlink_urb(oep->urb); + usb_free_urb(oep->urb); + oep->urb = 0; + } else { + dprintk(DRIVER_NAME "[%d]: free_out_endpt: null urb!\n", + ir->devnum); + } + case 3: +#ifdef KERNEL_2_5 + usb_buffer_free(oep->ir->usbdev, USB_OUTLEN, + oep->buf, oep->dma); +#else + kfree(oep->buf); +#endif + oep->buf = 0; + case 2: + kfree(oep); + } + IRUNLOCK; +} + +static struct out_endpt *new_out_endpt(struct irctl *ir, + struct usb_endpoint_descriptor *ep) +{ +#ifdef KERNEL_2_5 + struct usb_device *dev = ir->usbdev; +#endif + struct out_endpt *oep; + int mem_failure; + + dprintk(DRIVER_NAME "[%d]: acceptable outbound endpoint (0x%x) found\n", + ir->devnum, ep->bEndpointAddress); + + mem_failure = 0; + oep = kmalloc(sizeof(*oep), GFP_KERNEL); + if (!oep) + mem_failure = 1; + else { + memset(oep, 0, sizeof(*oep)); + oep->ir = ir; + oep->ep = ep; + init_waitqueue_head(&oep->wait); + +#ifdef KERNEL_2_5 + oep->buf = usb_buffer_alloc(dev, USB_OUTLEN, + GFP_ATOMIC, &oep->dma); +#else + oep->buf = kmalloc(USB_OUTLEN, GFP_KERNEL); +#endif + if (!oep->buf) + mem_failure = 2; + else { +#ifdef KERNEL_2_5 + oep->urb = usb_alloc_urb(0, GFP_KERNEL); +#else + oep->urb = usb_alloc_urb(0); +#endif + if (!oep->urb) + mem_failure = 3; + } + } + if (mem_failure) { + free_out_endpt(oep, mem_failure); + printk(DRIVER_NAME "[%d]: ep=0x%x out of memory (code=%d)\n", + ir->devnum, ep->bEndpointAddress, mem_failure); + return NULL; + } + return oep; +} + +static void free_irctl(struct irctl *ir, int mem_failure) +{ + struct list_head *pos, *n; + struct in_endpt *in; + dprintk(DRIVER_NAME ": free_irctl(%p, %d)\n", ir, mem_failure); + + if (!ir) + return; + + list_for_each_safe(pos, n, &ir->iep_listhead) { + in = get_iep_from_link(pos); + free_in_endpt(in, FREE_ALL); + } + if (ir->out_init) { + free_out_endpt(ir->out_init, FREE_ALL); + ir->out_init = NULL; + } + + IRLOCK; + switch (mem_failure) { + case FREE_ALL: + case 6: + if (!--ir->dev_refcount) { + list_del(&ir->remote_list_link); + dprintk(DRIVER_NAME "[%d]: free_irctl: removing " + "remote from list\n", ir->devnum); + } else { + dprintk(DRIVER_NAME "[%d]: free_irctl: refcount at %d," + "aborting free_irctl\n", + ir->devnum, ir->dev_refcount); + IRUNLOCK; + return; + } + case 5: + case 4: + case 3: + if (ir->p) { + switch (mem_failure) { + case 5: + lirc_buffer_free(ir->p->rbuf); + case 4: + kfree(ir->p->rbuf); + case 3: + kfree(ir->p); + } + } else + printk(DRIVER_NAME "[%d]: ir->p is a null pointer!\n", + ir->devnum); + case 2: + IRUNLOCK; + kfree(ir); + return; + } + IRUNLOCK; +} + +static struct irctl *new_irctl(struct usb_device *dev) +{ + struct irctl *ir; + struct lirc_plugin *plugin; + int type, devnum; + int mem_failure; + int dclen; + + devnum = dev->devnum; + + /* determine remote type */ + switch (cpu_to_le16(dev->descriptor.idVendor)) { + case VENDOR_ATI1: + type = ATI1_COMPATIBLE; + break; + case VENDOR_ATI2: + type = ATI2_COMPATIBLE; + break; + case VENDOR_MS1: + case VENDOR_MS2: + case VENDOR_MS3: + type = XBOX_COMPATIBLE; + break; + default: + dprintk(DRIVER_NAME "[%d]: unknown type\n", devnum); + return NULL; + } + dprintk(DRIVER_NAME "[%d]: remote type = %d\n", devnum, type); + + /* allocate kernel memory */ + mem_failure = 0; + ir = kmalloc(sizeof(*ir), GFP_KERNEL); + if (!ir) { + mem_failure = 1; + goto new_irctl_failure_check; + } + + /* at this stage we cannot use the macro [DE]CODE_LENGTH: ir + * is not yet setup */ + dclen = decode_length[type]; + memset(ir, 0, sizeof(*ir)); + /* add this infrared remote struct to remote_list, keeping track + * of the number of drivers registered. */ + dprintk(DRIVER_NAME "[%d]: adding remote to list\n", devnum); + list_add_tail(&ir->remote_list_link, &remote_list); + ir->dev_refcount = 1; + + plugin = kmalloc(sizeof(*plugin), GFP_KERNEL); + if (!plugin) { + mem_failure = 2; + goto new_irctl_failure_check; + } + + memset(plugin, 0, sizeof(*plugin)); + ir->p = plugin; + plugin->rbuf = kmalloc(sizeof(*(plugin->rbuf)), GFP_KERNEL); + if (!plugin->rbuf) { + mem_failure = 3; + goto new_irctl_failure_check; + } + + if (lirc_buffer_init(plugin->rbuf, dclen, 1)) { + mem_failure = 4; + goto new_irctl_failure_check; + } + + strcpy(plugin->name, DRIVER_NAME " "); + plugin->minor = -1; + plugin->code_length = dclen * 8; + plugin->features = LIRC_CAN_REC_LIRCCODE; + plugin->data = ir; + plugin->set_use_inc = &set_use_inc; + plugin->set_use_dec = &set_use_dec; +#ifdef LIRC_HAVE_SYSFS + plugin->dev = &dev->dev; +#endif + plugin->owner = THIS_MODULE; + ir->usbdev = dev; + ir->remote_type = type; + ir->devnum = devnum; + ir->mode = RW2_NULL_MODE; + + init_MUTEX(&ir->lock); + INIT_LIST_HEAD(&ir->iep_listhead); + +new_irctl_failure_check: + + if (mem_failure) { + free_irctl(ir, mem_failure); + printk(DRIVER_NAME "[%d]: out of memory (code=%d)\n", + devnum, mem_failure); + return NULL; + } + return ir; +} + + +/* + * Scan the global list of remotes to see if the device listed is one of them. + * If it is, the corresponding irctl is returned, with its dev_refcount + * incremented. Otherwise, returns null. + */ +static struct irctl *get_prior_reg_ir(struct usb_device *dev) +{ + struct list_head *pos; + struct irctl *ir = NULL; + + dprintk(DRIVER_NAME "[%d]: scanning remote_list...\n", dev->devnum); + list_for_each(pos, &remote_list) { + ir = get_irctl_from_link(pos); + if (ir->usbdev != dev) { + dprintk(DRIVER_NAME "[%d]: device %d isn't it...", + dev->devnum, ir->devnum); + ir = NULL; + } else { + dprintk(DRIVER_NAME "[%d]: prior instance found.\n", + dev->devnum); + ir->dev_refcount++; + break; + } + } + return ir; +} + +/* If the USB interface has an out endpoint for control (eg, the first Remote + * Wonder) send the appropriate initialization packets. */ +static void send_outbound_init(struct irctl *ir) +{ + if (ir->out_init) { + struct out_endpt *oep = ir->out_init; + dprintk(DRIVER_NAME "[%d]: usb_remote_probe: initializing " + "outbound ep\n", ir->devnum); + usb_fill_int_urb(oep->urb, ir->usbdev, + usb_sndintpipe(ir->usbdev, oep->ep->bEndpointAddress), + oep->buf, USB_OUTLEN, usb_remote_send, + oep, oep->ep->bInterval); + + send_packet(oep, 0x8004, init1); + send_packet(oep, 0x8007, init2); + } +} + +/* Log driver and usb info */ +static void log_usb_dev_info(struct usb_device *dev) +{ + char buf[63], name[128] = ""; + if (dev->descriptor.iManufacturer + && usb_string(dev, dev->descriptor.iManufacturer, buf, 63) > 0) + strncpy(name, buf, 128); + if (dev->descriptor.iProduct + && usb_string(dev, dev->descriptor.iProduct, buf, 63) > 0) + snprintf(name, 128, "%s %s", name, buf); + printk(DRIVER_NAME "[%d]: %s on usb%d:%d\n", dev->devnum, name, + dev->bus->busnum, dev->devnum); +} + + +#ifdef KERNEL_2_5 +static int usb_remote_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_device *dev = interface_to_usbdev(intf); + struct usb_host_interface *idesc; +#else +static void *usb_remote_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id) +{ + struct usb_interface *intf = &dev->actconfig->interface[ifnum]; + struct usb_interface_descriptor *idesc; +#endif + struct usb_endpoint_descriptor *ep; + struct in_endpt *iep; + struct irctl *ir; + int i, type; + + dprintk(DRIVER_NAME "[%d]: usb_remote_probe: dev:%p, intf:%p, id:%p)\n", + dev->devnum, dev, intf, id); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 5) + idesc = &intf->altsetting[intf->act_altsetting]; +#else + idesc = intf->cur_altsetting; +#endif + + /* Check if a usb remote has already been registered for this device */ + ir = get_prior_reg_ir(dev); + + if (!ir) { + ir = new_irctl(dev); + if (!ir) +#ifdef KERNEL_2_5 + return -ENOMEM; +#else + return NULL; +#endif + } + type = ir->remote_type; + + /* step through the endpoints to find first in and first out endpoint + * of type interrupt transfer */ +#ifdef KERNEL_2_5 + for (i = 0; i < idesc->desc.bNumEndpoints; ++i) { + ep = &idesc->endpoint[i].desc; +#else + for (i = 0; i < idesc->bNumEndpoints; ++i) { + ep = &idesc->endpoint[i]; +#endif + dprintk(DRIVER_NAME "[%d]: processing endpoint %d\n", + dev->devnum, i); + if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == + USB_DIR_IN) && + ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_INT)) { + + iep = new_in_endpt(ir, ep); + if (iep) + usb_fill_int_urb(iep->urb, dev, + usb_rcvintpipe(dev, + iep->ep->bEndpointAddress), + iep->buf, iep->len, usb_remote_recv, + iep, iep->ep->bInterval); + } + + if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == + USB_DIR_OUT) && + ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_INT) && + (ir->out_init == NULL)) + ir->out_init = new_out_endpt(ir, ep); + } + if (list_empty(&ir->iep_listhead)) { + printk(DRIVER_NAME "[%d]: inbound endpoint not found\n", + ir->devnum); + free_irctl(ir, FREE_ALL); +#ifdef KERNEL_2_5 + return -ENODEV; +#else + return NULL; +#endif + } + if (ir->dev_refcount == 1) { + ir->p->minor = lirc_register_plugin(ir->p); + if (ir->p->minor < 0) { + free_irctl(ir, FREE_ALL); +#ifdef KERNEL_2_5 + return -ENODEV; +#else + return NULL; +#endif + } + + /* Note new driver registration in kernel logs */ + log_usb_dev_info(dev); + + /* outbound data (initialization) */ + send_outbound_init(ir); + } + +#ifdef KERNEL_2_5 + usb_set_intfdata(intf, ir); + return SUCCESS; +#else + return ir; +#endif +} + +#ifdef KERNEL_2_5 +static void usb_remote_disconnect(struct usb_interface *intf) +{ +/* struct usb_device *dev = interface_to_usbdev(intf); */ + struct irctl *ir = usb_get_intfdata(intf); + usb_set_intfdata(intf, NULL); +#else +static void usb_remote_disconnect(struct usb_device *dev, void *ptr) +{ + struct irctl *ir = ptr; +#endif + + dprintk(DRIVER_NAME ": disconnecting remote %d:\n", + (ir? ir->devnum: -1)); + if (!ir || !ir->p) + return; + + if (ir->usbdev) { + /* Only unregister once */ + ir->usbdev = NULL; + unregister_from_lirc(ir); + } + + /* This also removes the current remote from remote_list */ + free_irctl(ir, FREE_ALL); +} + +static struct usb_driver usb_remote_driver = { + LIRC_THIS_MODULE(.owner = THIS_MODULE) + .name = DRIVER_NAME, + .probe = usb_remote_probe, + .disconnect = usb_remote_disconnect, + .id_table = usb_remote_table +}; + +static int __init usb_remote_init(void) +{ + int i; + + INIT_LIST_HEAD(&remote_list); + + printk(KERN_INFO "\n" DRIVER_NAME ": " DRIVER_DESC " " + DRIVER_VERSION "\n"); + printk(DRIVER_NAME ": " DRIVER_AUTHOR "\n"); + dprintk(DRIVER_NAME ": debug mode enabled: " + "$Id: lirc_atiusb.c,v 1.69 2008/04/28 06:47:29 lirc Exp $\n"); + + request_module("lirc_dev"); + + repeat_jiffies = repeat*HZ/100; + + i = usb_register(&usb_remote_driver); + if (i) { + printk(DRIVER_NAME ": usb register failed, result = %d\n", i); + return -ENODEV; + } + + return SUCCESS; +} + +static void __exit usb_remote_exit(void) +{ + usb_deregister(&usb_remote_driver); +} + +module_init(usb_remote_init); +module_exit(usb_remote_exit); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(usb, usb_remote_table); + +module_param(debug, bool, 0644); +MODULE_PARM_DESC(debug, "Debug enabled or not (default: 0)"); + +module_param(mask, int, 0644); +MODULE_PARM_DESC(mask, "Set channel acceptance bit mask (default: 0xFFFF)"); + +module_param(unique, bool, 0644); +MODULE_PARM_DESC(unique, "Enable channel-specific codes (default: 0)"); + +module_param(repeat, int, 0644); +MODULE_PARM_DESC(repeat, "Repeat timeout (1/100 sec) (default: 10)"); + +module_param(mdeadzone, int, 0644); +MODULE_PARM_DESC(mdeadzone, "rw2 mouse sensitivity threshold (default: 0)"); + +/* + * Enabling this will cause the built-in Remote Wonder II repeate coding to + * not be squashed. The second byte of the keys output will then be: + * + * 1 initial press (button down) + * 2 holding (button remains pressed) + * 0 release (button up) + * + * By default, the driver emits 2 for both 1 and 2, and emits nothing for 0. + * This is good for people having trouble getting their rw2 to send a good + * consistent signal to the receiver. + * + * However, if you have no troubles with the driver outputting up-down pairs + * at random points while you're still holding a button, then you can enable + * this parameter to get finer grain repeat control out of your remote: + * + * 1 Emit a single (per-channel) virtual code for all up/down events + * 2 Emit the actual rw2 output + * + * 1 is easier to write lircd configs for; 2 allows full control. + */ +module_param(emit_updown, int, 0644); +MODULE_PARM_DESC(emit_updown, "emit press/release codes (rw2): 0:don't " + "(default), 1:emit 2 codes only, 2:code for each button"); + +module_param(emit_modekeys, int, 0644); +MODULE_PARM_DESC(emit_modekeys, "emit keycodes for aux1-aux4, pc, and mouse " + "(rw2): 0:don't (default), 1:emit translated codes: one for " + "mode switch, one for same mode, 2:raw codes"); + +module_param(mgradient, int, 0644); +MODULE_PARM_DESC(mgradient, "rw2 mouse: 1000*gradient from E to NE (default: " + "500 => .5 => ~27 degrees)"); + +EXPORT_NO_SYMBOLS; --- linux-2.6.28.orig/ubuntu/lirc/lirc_atiusb/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_atiusb/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_ATIUSB) += lirc_atiusb.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_serial/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_serial/Makefile @@ -0,0 +1,4 @@ + +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_SERIAL_IGOR) += lirc_serial.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_serial/lirc_serial.c +++ linux-2.6.28/ubuntu/lirc/lirc_serial/lirc_serial.c @@ -0,0 +1,1368 @@ +/* $Id: lirc_serial.c,v 5.89 2008/04/06 19:03:52 lirc Exp $ */ + +/**************************************************************************** + ** lirc_serial.c *********************************************************** + **************************************************************************** + * + * lirc_serial - Device driver that records pulse- and pause-lengths + * (space-lengths) between DDCD event on a serial port. + * + * Copyright (C) 1996,97 Ralph Metzler + * Copyright (C) 1998 Trent Piepho + * Copyright (C) 1998 Ben Pfaff + * Copyright (C) 1999 Christoph Bartelmus + * Copyright (C) 2007 Andrei Tanas (suspend/resume support) + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You 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 + * + */ + +/* Steve's changes to improve transmission fidelity: + - for systems with the rdtsc instruction and the clock counter, a + send_pule that times the pulses directly using the counter. + This means that the LIRC_SERIAL_TRANSMITTER_LATENCY fudge is + not needed. Measurement shows very stable waveform, even where + PCI activity slows the access to the UART, which trips up other + versions. + - For other system, non-integer-microsecond pulse/space lengths, + done using fixed point binary. So, much more accurate carrier + frequency. + - fine tuned transmitter latency, taking advantage of fractional + microseconds in previous change + - Fixed bug in the way transmitter latency was accounted for by + tuning the pulse lengths down - the send_pulse routine ignored + this overhead as it timed the overall pulse length - so the + pulse frequency was right but overall pulse length was too + long. Fixed by accounting for latency on each pulse/space + iteration. + + Steve Davies July 2001 +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18) +#error "**********************************************************" +#error " Sorry, this driver needs kernel version 2.2.18 or higher " +#error "**********************************************************" +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) +#include +#endif + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#include +#else +#include +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +#include +#else +#include +#endif +#include +#include + +#if defined(LIRC_SERIAL_NSLU2) +#include +/* From Intel IXP42X Developer's Manual (#252480-005): */ +/* ftp://download.intel.com/design/network/manuals/25248005.pdf */ +#define UART_IE_IXP42X_UUE 0x40 /* IXP42X UART Unit enable */ +#define UART_IE_IXP42X_RTOIE 0x10 /* IXP42X Receiver Data Timeout int.enable */ +#ifndef NSLU2_LED_GRN_GPIO +/* added in 2.6.22 */ +#define NSLU2_LED_GRN_GPIO NSLU2_LED_GRN +#endif +#endif + +#include "lirc.h" +#include "kcompat.h" +#include "lirc_dev/lirc_dev.h" + +#if defined(LIRC_SERIAL_SOFTCARRIER) && !defined(LIRC_SERIAL_TRANSMITTER) +#warning "Software carrier only affects transmitting" +#endif + +#if defined(rdtscl) + +#define USE_RDTSC +#warning "Note: using rdtsc instruction" +#endif + +#ifdef LIRC_SERIAL_ANIMAX +#ifdef LIRC_SERIAL_TRANSMITTER +#warning "******************************************" +#warning " This receiver does not have a " +#warning " transmitter diode " +#warning "******************************************" +#endif +#endif + +#define LIRC_DRIVER_NAME "lirc_serial" + +struct lirc_serial { + int signal_pin; + int signal_pin_change; + int on; + int off; + long (*send_pulse)(unsigned long length); + void (*send_space)(long length); + int features; +}; + +#define LIRC_HOMEBREW 0 +#define LIRC_IRDEO 1 +#define LIRC_IRDEO_REMOTE 2 +#define LIRC_ANIMAX 3 +#define LIRC_IGOR 4 +#define LIRC_NSLU2 5 + +#ifdef LIRC_SERIAL_IRDEO +static int type = LIRC_IRDEO; +#elif defined(LIRC_SERIAL_IRDEO_REMOTE) +static int type = LIRC_IRDEO_REMOTE; +#elif defined(LIRC_SERIAL_ANIMAX) +static int type = LIRC_ANIMAX; +#elif defined(LIRC_SERIAL_IGOR) +static int type = LIRC_IGOR; +#elif defined(LIRC_SERIAL_NSLU2) +static int type = LIRC_NSLU2; +#else +static int type = LIRC_HOMEBREW; +#endif + +/* Set defaults for NSLU2 */ +#if defined(LIRC_SERIAL_NSLU2) +#ifndef LIRC_IRQ +#define LIRC_IRQ IRQ_IXP4XX_UART2 +#endif +#ifndef LIRC_PORT +#define LIRC_PORT (IXP4XX_UART2_BASE_VIRT + REG_OFFSET) +#endif +#ifndef LIRC_IOMMAP +#define LIRC_IOMMAP IXP4XX_UART2_BASE_PHYS +#endif +#ifndef LIRC_IOSHIFT +#define LIRC_IOSHIFT 2 +#endif +#ifndef LIRC_ALLOW_MMAPPED_IO +#define LIRC_ALLOW_MMAPPED_IO +#endif +#endif + +#if defined(LIRC_ALLOW_MMAPPED_IO) +#ifndef LIRC_IOMMAP +#define LIRC_IOMMAP 0 +#endif +#ifndef LIRC_IOSHIFT +#define LIRC_IOSHIFT 0 +#endif +static int iommap = LIRC_IOMMAP; +static int ioshift = LIRC_IOSHIFT; +#endif + +#ifdef LIRC_SERIAL_SOFTCARRIER +static int softcarrier = 1; +#else +static int softcarrier; +#endif + +static int share_irq; +static int debug; + +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \ + fmt, ## args); \ + } while (0) + +/* forward declarations */ +static long send_pulse_irdeo(unsigned long length); +static long send_pulse_homebrew(unsigned long length); +static void send_space_irdeo(long length); +static void send_space_homebrew(long length); + +static struct lirc_serial hardware[] = { + /* home-brew receiver/transmitter */ + { + UART_MSR_DCD, + UART_MSR_DDCD, + UART_MCR_RTS|UART_MCR_OUT2|UART_MCR_DTR, + UART_MCR_RTS|UART_MCR_OUT2, + send_pulse_homebrew, + send_space_homebrew, + ( +#ifdef LIRC_SERIAL_TRANSMITTER + LIRC_CAN_SET_SEND_DUTY_CYCLE| + LIRC_CAN_SET_SEND_CARRIER| + LIRC_CAN_SEND_PULSE| +#endif + LIRC_CAN_REC_MODE2) + }, + + /* IRdeo classic */ + { + UART_MSR_DSR, + UART_MSR_DDSR, + UART_MCR_OUT2, + UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2, + send_pulse_irdeo, + send_space_irdeo, + (LIRC_CAN_SET_SEND_DUTY_CYCLE| + LIRC_CAN_SEND_PULSE| + LIRC_CAN_REC_MODE2) + }, + + /* IRdeo remote */ + { + UART_MSR_DSR, + UART_MSR_DDSR, + UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2, + UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2, + send_pulse_irdeo, + send_space_irdeo, + (LIRC_CAN_SET_SEND_DUTY_CYCLE| + LIRC_CAN_SEND_PULSE| + LIRC_CAN_REC_MODE2) + }, + + /* AnimaX */ + { + UART_MSR_DCD, + UART_MSR_DDCD, + 0, + UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2, + NULL, + NULL, + LIRC_CAN_REC_MODE2 + }, + + /* home-brew receiver/transmitter (Igor Cesko's variation) */ + { + UART_MSR_DSR, + UART_MSR_DDSR, + UART_MCR_RTS|UART_MCR_OUT2|UART_MCR_DTR, + UART_MCR_RTS|UART_MCR_OUT2, + send_pulse_homebrew, + send_space_homebrew, + ( +#ifdef LIRC_SERIAL_TRANSMITTER + LIRC_CAN_SET_SEND_DUTY_CYCLE| + LIRC_CAN_SET_SEND_CARRIER| + LIRC_CAN_SEND_PULSE| +#endif + LIRC_CAN_REC_MODE2) + }, + +#if defined(LIRC_SERIAL_NSLU2) + /* Modified Linksys Network Storage Link USB 2.0 (NSLU2): + We receive on CTS of the 2nd serial port (R142,LHS), we + transmit with a IR diode between GPIO[1] (green status LED), + and ground (Matthias Goebl ). + See also http://www.nslu2-linux.org for this device */ + { + UART_MSR_CTS, + UART_MSR_DCTS, + UART_MCR_RTS|UART_MCR_OUT2|UART_MCR_DTR, + UART_MCR_RTS|UART_MCR_OUT2, + send_pulse_homebrew, + send_space_homebrew, + ( +#ifdef LIRC_SERIAL_TRANSMITTER + LIRC_CAN_SET_SEND_DUTY_CYCLE| + LIRC_CAN_SET_SEND_CARRIER| + LIRC_CAN_SEND_PULSE| +#endif + LIRC_CAN_REC_MODE2) + }, +#endif + +}; + +#define RS_ISR_PASS_LIMIT 256 + +/* A long pulse code from a remote might take upto 300 bytes. The + daemon should read the bytes as soon as they are generated, so take + the number of keys you think you can push before the daemon runs + and multiply by 300. The driver will warn you if you overrun this + buffer. If you have a slow computer or non-busmastering IDE disks, + maybe you will need to increase this. */ + +/* This MUST be a power of two! It has to be larger than 1 as well. */ + +#define RBUF_LEN 256 +#define WBUF_LEN 256 + +static int sense = -1; /* -1 = auto, 0 = active high, 1 = active low */ +static int txsense; /* 0 = active high, 1 = active low */ + +#ifndef LIRC_IRQ +#define LIRC_IRQ 4 +#endif +#ifndef LIRC_PORT +#define LIRC_PORT 0x3f8 +#endif + +static int io = LIRC_PORT; +static int irq = LIRC_IRQ; + +static struct timeval lasttv = {0, 0}; + +static struct lirc_buffer rbuf; + +static lirc_t wbuf[WBUF_LEN]; + +static unsigned int freq = 38000; +static unsigned int duty_cycle = 50; + +/* Initialized in init_timing_params() */ +static unsigned long period; +static unsigned long pulse_width; +static unsigned long space_width; + +#if defined(__i386__) +/* + From: + Linux I/O port programming mini-HOWTO + Author: Riku Saikkonen + v, 28 December 1997 + + [...] + Actually, a port I/O instruction on most ports in the 0-0x3ff range + takes almost exactly 1 microsecond, so if you're, for example, using + the parallel port directly, just do additional inb()s from that port + to delay. + [...] +*/ +/* transmitter latency 1.5625us 0x1.90 - this figure arrived at from + * comment above plus trimming to match actual measured frequency. + * This will be sensitive to cpu speed, though hopefully most of the 1.5us + * is spent in the uart access. Still - for reference test machine was a + * 1.13GHz Athlon system - Steve + */ + +/* changed from 400 to 450 as this works better on slower machines; + faster machines will use the rdtsc code anyway */ + +#define LIRC_SERIAL_TRANSMITTER_LATENCY 450 + +#else + +/* does anybody have information on other platforms ? */ +/* 256 = 1<<8 */ +#define LIRC_SERIAL_TRANSMITTER_LATENCY 256 + +#endif /* __i386__ */ + +static inline unsigned int sinp(int offset) +{ +#if defined(LIRC_ALLOW_MMAPPED_IO) + if (iommap != 0) { + /* the register is memory-mapped */ + offset <<= ioshift; + return readb(io + offset); + } +#endif + return inb(io + offset); +} + +static inline void soutp(int offset, int value) +{ +#if defined(LIRC_ALLOW_MMAPPED_IO) + if (iommap != 0) { + /* the register is memory-mapped */ + offset <<= ioshift; + writeb(value, io + offset); + } +#endif + outb(value, io + offset); +} + +static inline void on(void) +{ +#if defined(LIRC_SERIAL_NSLU2) + /* On NSLU2, we put the transmit diode between the output of the green + status LED and ground */ + if (type == LIRC_NSLU2) { + gpio_line_set(NSLU2_LED_GRN_GPIO, IXP4XX_GPIO_LOW); + return; + } +#endif + if (txsense) + soutp(UART_MCR, hardware[type].off); + else + soutp(UART_MCR, hardware[type].on); +} + +static inline void off(void) +{ +#if defined(LIRC_SERIAL_NSLU2) + if (type == LIRC_NSLU2) { + gpio_line_set(NSLU2_LED_GRN_GPIO, IXP4XX_GPIO_HIGH); + return; + } +#endif + if (txsense) + soutp(UART_MCR, hardware[type].on); + else + soutp(UART_MCR, hardware[type].off); +} + +#ifndef MAX_UDELAY_MS +#define MAX_UDELAY_US 5000 +#else +#define MAX_UDELAY_US (MAX_UDELAY_MS*1000) +#endif + +static inline void safe_udelay(unsigned long usecs) +{ + while (usecs > MAX_UDELAY_US) { + udelay(MAX_UDELAY_US); + usecs -= MAX_UDELAY_US; + } + udelay(usecs); +} + +#ifdef USE_RDTSC +/* This is an overflow/precision juggle, complicated in that we can't + do long long divide in the kernel */ + +/* When we use the rdtsc instruction to measure clocks, we keep the + * pulse and space widths as clock cycles. As this is CPU speed + * dependent, the widths must be calculated in init_port and ioctl + * time + */ + +/* So send_pulse can quickly convert microseconds to clocks */ +static unsigned long conv_us_to_clocks; + +static inline int init_timing_params(unsigned int new_duty_cycle, + unsigned int new_freq) +{ + unsigned long long loops_per_sec, work; + + duty_cycle = new_duty_cycle; + freq = new_freq; + + loops_per_sec = current_cpu_data.loops_per_jiffy; + loops_per_sec *= HZ; + + /* How many clocks in a microsecond?, avoiding long long divide */ + work = loops_per_sec; + work *= 4295; /* 4295 = 2^32 / 1e6 */ + conv_us_to_clocks = (work>>32); + + /* Carrier period in clocks, approach good up to 32GHz clock, + gets carrier frequency within 8Hz */ + period = loops_per_sec>>3; + period /= (freq>>3); + + /* Derive pulse and space from the period */ + + pulse_width = period*duty_cycle/100; + space_width = period - pulse_width; + dprintk("in init_timing_params, freq=%d, duty_cycle=%d, " + "clk/jiffy=%ld, pulse=%ld, space=%ld, " + "conv_us_to_clocks=%ld\n", + freq, duty_cycle, current_cpu_data.loops_per_jiffy, + pulse_width, space_width, conv_us_to_clocks); + return 0; +} +#else /* ! USE_RDTSC */ +static inline int init_timing_params(unsigned int new_duty_cycle, + unsigned int new_freq) +{ +/* period, pulse/space width are kept with 8 binary places - + * IE multiplied by 256. */ + if (256*1000000L/new_freq*new_duty_cycle/100 <= + LIRC_SERIAL_TRANSMITTER_LATENCY) + return -EINVAL; + if (256*1000000L/new_freq*(100-new_duty_cycle)/100 <= + LIRC_SERIAL_TRANSMITTER_LATENCY) + return -EINVAL; + duty_cycle = new_duty_cycle; + freq = new_freq; + period = 256*1000000L/freq; + pulse_width = period*duty_cycle/100; + space_width = period-pulse_width; + dprintk("in init_timing_params, freq=%d pulse=%ld, " + "space=%ld\n", freq, pulse_width, space_width); + return 0; +} +#endif /* USE_RDTSC */ + + +/* return value: space length delta */ + +static long send_pulse_irdeo(unsigned long length) +{ + long rawbits; + int i; + unsigned char output; + unsigned char chunk, shifted; + + /* how many bits have to be sent ? */ + rawbits = length*1152/10000; + if (duty_cycle > 50) + chunk = 3; + else + chunk = 1; + for (i = 0, output = 0x7f; rawbits > 0; rawbits -= 3) { + shifted = chunk<<(i*3); + shifted >>= 1; + output &= (~shifted); + i++; + if (i == 3) { + soutp(UART_TX, output); + while (!(sinp(UART_LSR) & UART_LSR_THRE)); + output = 0x7f; + i = 0; + } + } + if (i != 0) { + soutp(UART_TX, output); + while (!(sinp(UART_LSR) & UART_LSR_TEMT)); + } + + if (i == 0) + return ((-rawbits)*10000/1152); + else + return ((3-i)*3*10000/1152+(-rawbits)*10000/1152); +} + +#ifdef USE_RDTSC +/* Version that uses Pentium rdtsc instruction to measure clocks */ + +/* This version does sub-microsecond timing using rdtsc instruction, + * and does away with the fudged LIRC_SERIAL_TRANSMITTER_LATENCY + * Implicitly i586 architecture... - Steve + */ + +static inline long send_pulse_homebrew_softcarrier(unsigned long length) +{ + int flag; + unsigned long target, start, now; + + /* Get going quick as we can */ + rdtscl(start); on(); + /* Convert length from microseconds to clocks */ + length *= conv_us_to_clocks; + /* And loop till time is up - flipping at right intervals */ + now = start; + target = pulse_width; + flag = 1; + while ((now-start) < length) { + /* Delay till flip time */ + do + rdtscl(now); + while ((now-start) < target); + + /* flip */ + if (flag) { + rdtscl(now); off(); + target += space_width; + } else { + rdtscl(now); on(); + target += pulse_width; + } + flag = !flag; + } + rdtscl(now); + return (((now-start)-length)/conv_us_to_clocks); +} +#else /* ! USE_RDTSC */ +/* Version using udelay() */ + +/* here we use fixed point arithmetic, with 8 + fractional bits. that gets us within 0.1% or so of the right average + frequency, albeit with some jitter in pulse length - Steve */ + +/* To match 8 fractional bits used for pulse/space length */ + +static inline long send_pulse_homebrew_softcarrier(unsigned long length) +{ + int flag; + unsigned long actual, target, d; + length <<= 8; + + actual = 0; target = 0; flag = 0; + while (actual < length) { + if (flag) { + off(); + target += space_width; + } else { + on(); + target += pulse_width; + } + d = (target-actual-LIRC_SERIAL_TRANSMITTER_LATENCY+128)>>8; + /* Note - we've checked in ioctl that the pulse/space + widths are big enough so that d is > 0 */ + udelay(d); + actual += (d<<8)+LIRC_SERIAL_TRANSMITTER_LATENCY; + flag = !flag; + } + return ((actual-length)>>8); +} +#endif /* USE_RDTSC */ + +static long send_pulse_homebrew(unsigned long length) +{ + if (length <= 0) + return 0; + + if (softcarrier) + return send_pulse_homebrew_softcarrier(length); + else { + on(); + safe_udelay(length); + return 0; + } +} + +static void send_space_irdeo(long length) +{ + if (length <= 0) + return; + + safe_udelay(length); +} + +static void send_space_homebrew(long length) +{ + off(); + if (length <= 0) + return; + safe_udelay(length); +} + +static inline void rbwrite(lirc_t l) +{ + if (lirc_buffer_full(&rbuf)) { + /* no new signals will be accepted */ + dprintk("Buffer overrun\n"); + return; + } + _lirc_buffer_write_1(&rbuf, (void *)&l); +} + +static inline void frbwrite(lirc_t l) +{ + /* simple noise filter */ + static lirc_t pulse = 0L, space = 0L; + static unsigned int ptr; + + if (ptr > 0 && (l&PULSE_BIT)) { + pulse += l&PULSE_MASK; + if (pulse > 250) { + rbwrite(space); + rbwrite(pulse|PULSE_BIT); + ptr = 0; + pulse = 0; + } + return; + } + if (!(l&PULSE_BIT)) { + if (ptr == 0) { + if (l > 20000) { + space = l; + ptr++; + return; + } + } else { + if (l > 20000) { + space += pulse; + if (space > PULSE_MASK) + space = PULSE_MASK; + space += l; + if (space > PULSE_MASK) + space = PULSE_MASK; + pulse = 0; + return; + } + rbwrite(space); + rbwrite(pulse|PULSE_BIT); + ptr = 0; + pulse = 0; + } + } + rbwrite(l); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) +static irqreturn_t irq_handler(int i, void *blah) +#else +static irqreturn_t irq_handler(int i, void *blah, struct pt_regs *regs) +#endif +{ + struct timeval tv; + int status, counter, dcd; + long deltv; + lirc_t data; + static int last_dcd = -1; + + if ((sinp(UART_IIR) & UART_IIR_NO_INT)) { + /* not our interrupt */ + return IRQ_RETVAL(IRQ_NONE); + } + + counter = 0; + do { + counter++; + status = sinp(UART_MSR); + if (counter > RS_ISR_PASS_LIMIT) { + printk(KERN_WARNING LIRC_DRIVER_NAME ": AIEEEE: " + "We're caught!\n"); + break; + } + if ((status&hardware[type].signal_pin_change) && sense != -1) { + /* get current time */ + do_gettimeofday(&tv); + + /* New mode, written by Trent Piepho + . */ + + /* The old format was not very portable. + We now use the type lirc_t to pass pulses + and spaces to user space. + + If PULSE_BIT is set a pulse has been + received, otherwise a space has been + received. The driver needs to know if your + receiver is active high or active low, or + the space/pulse sense could be + inverted. The bits denoted by PULSE_MASK are + the length in microseconds. Lengths greater + than or equal to 16 seconds are clamped to + PULSE_MASK. All other bits are unused. + This is a much simpler interface for user + programs, as well as eliminating "out of + phase" errors with space/pulse + autodetection. */ + + /* calculate time since last interrupt in + microseconds */ + dcd = (status & hardware[type].signal_pin) ? 1:0; + + if (dcd == last_dcd) { + printk(KERN_WARNING LIRC_DRIVER_NAME + ": ignoring spike: %d %d %lx %lx %lx %lx\n", + dcd, sense, + tv.tv_sec, lasttv.tv_sec, + tv.tv_usec, lasttv.tv_usec); + continue; + } + + deltv = tv.tv_sec-lasttv.tv_sec; + if (tv.tv_sec < lasttv.tv_sec || + (tv.tv_sec == lasttv.tv_sec && + tv.tv_usec < lasttv.tv_usec)) { + printk(KERN_WARNING LIRC_DRIVER_NAME + ": AIEEEE: your clock just jumped " + "backwards\n"); + printk(KERN_WARNING LIRC_DRIVER_NAME + ": %d %d %lx %lx %lx %lx\n", + dcd, sense, + tv.tv_sec, lasttv.tv_sec, + tv.tv_usec, lasttv.tv_usec); + data = PULSE_MASK; + } else if (deltv > 15) { + data = PULSE_MASK; /* really long time */ + if (!(dcd^sense)) { + /* sanity check */ + printk(KERN_WARNING LIRC_DRIVER_NAME + ": AIEEEE: " + "%d %d %lx %lx %lx %lx\n", + dcd, sense, + tv.tv_sec, lasttv.tv_sec, + tv.tv_usec, lasttv.tv_usec); + /* detecting pulse while this + MUST be a space! */ + sense = sense ? 0:1; + } + } else + data = (lirc_t) (deltv*1000000 + + tv.tv_usec - + lasttv.tv_usec); + frbwrite(dcd^sense ? data : (data|PULSE_BIT)); + lasttv = tv; + last_dcd = dcd; + wake_up_interruptible(&rbuf.wait_poll); + } + } while (!(sinp(UART_IIR) & UART_IIR_NO_INT)); /* still pending ? */ + return IRQ_RETVAL(IRQ_HANDLED); +} + +static void hardware_init_port(void) +{ + unsigned long flags; + local_irq_save(flags); + + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + /* First of all, disable all interrupts */ + soutp(UART_IER, sinp(UART_IER) & + (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); + + /* Clear registers. */ + sinp(UART_LSR); + sinp(UART_RX); + sinp(UART_IIR); + sinp(UART_MSR); + +#if defined(LIRC_SERIAL_NSLU2) + if (type == LIRC_NSLU2) { + /* Setup NSLU2 UART */ + + /* Enable UART */ + soutp(UART_IER, sinp(UART_IER) | UART_IE_IXP42X_UUE); + /* Disable Receiver data Time out interrupt */ + soutp(UART_IER, sinp(UART_IER) & ~UART_IE_IXP42X_RTOIE); + /* set out2 = interupt unmask; off() doesn't set MCR + on NSLU2 */ + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_OUT2); + } +#endif + + /* Set line for power source */ + off(); + + /* Clear registers again to be sure. */ + sinp(UART_LSR); + sinp(UART_RX); + sinp(UART_IIR); + sinp(UART_MSR); + + switch (type) { + case LIRC_IRDEO: + case LIRC_IRDEO_REMOTE: + /* setup port to 7N1 @ 115200 Baud */ + /* 7N1+start = 9 bits at 115200 ~ 3 bits at 38kHz */ + + /* Set DLAB 1. */ + soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB); + /* Set divisor to 1 => 115200 Baud */ + soutp(UART_DLM, 0); + soutp(UART_DLL, 1); + /* Set DLAB 0 + 7N1 */ + soutp(UART_LCR, UART_LCR_WLEN7); + /* THR interrupt already disabled at this point */ + break; + default: + break; + } + + local_irq_restore(flags); +} + +static int init_port(void) +{ + int i, nlow, nhigh; + + /* Reserve io region. */ +#if defined(LIRC_ALLOW_MMAPPED_IO) + /* Future MMAP-Developers: Attention! + For memory mapped I/O you *might* need to use ioremap() first, + for the NSLU2 it's done in boot code. */ + if (((iommap != 0) + && (request_mem_region(iommap, 8<= nhigh ? 1 : 0); + printk(KERN_INFO LIRC_DRIVER_NAME ": auto-detected active " + "%s receiver\n", sense ? "low":"high"); + } else + printk(KERN_INFO LIRC_DRIVER_NAME ": Manually using active " + "%s receiver\n", sense ? "low":"high"); + + return 0; +} + +static int set_use_inc(void *data) +{ + int result; + unsigned long flags; + + /* Init read buffer. */ + if (lirc_buffer_init(&rbuf, sizeof(lirc_t), RBUF_LEN) < 0) + return -ENOMEM; + + /* initialize timestamp */ + do_gettimeofday(&lasttv); + + result = request_irq(irq, irq_handler, + IRQF_DISABLED | (share_irq ? IRQF_SHARED:0), + LIRC_DRIVER_NAME, (void *)&hardware); + + switch (result) { + case -EBUSY: + printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", irq); + lirc_buffer_free(&rbuf); + return -EBUSY; + case -EINVAL: + printk(KERN_ERR LIRC_DRIVER_NAME + ": Bad irq number or handler\n"); + lirc_buffer_free(&rbuf); + return -EINVAL; + default: + dprintk("Interrupt %d, port %04x obtained\n", irq, io); + break; + }; + + local_irq_save(flags); + + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + soutp(UART_IER, sinp(UART_IER)|UART_IER_MSI); + + local_irq_restore(flags); + + MOD_INC_USE_COUNT; + return 0; +} + +static void set_use_dec(void *data) +{ unsigned long flags; + + local_irq_save(flags); + + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + /* First of all, disable all interrupts */ + soutp(UART_IER, sinp(UART_IER) & + (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); + local_irq_restore(flags); + + free_irq(irq, (void *)&hardware); + + dprintk("freed IRQ %d\n", irq); + lirc_buffer_free(&rbuf); + + MOD_DEC_USE_COUNT; +} + +static ssize_t lirc_write(struct file *file, const char *buf, + size_t n, loff_t *ppos) +{ + int i, count; + unsigned long flags; + long delta = 0; + + if (!(hardware[type].features&LIRC_CAN_SEND_PULSE)) + return -EBADF; + + if (n % sizeof(lirc_t)) + return -EINVAL; + count = n / sizeof(lirc_t); + if (count > WBUF_LEN || count % 2 == 0) + return -EINVAL; + if (copy_from_user(wbuf, buf, n)) + return -EFAULT; + local_irq_save(flags); + if (type == LIRC_IRDEO) { + /* DTR, RTS down */ + on(); + } + for (i = 0; i < count; i++) { + if (i%2) + hardware[type].send_space(wbuf[i]-delta); + else + delta = hardware[type].send_pulse(wbuf[i]); + } + off(); + local_irq_restore(flags); + return n; +} + +static int lirc_ioctl(struct inode *node, struct file *filep, unsigned int cmd, + unsigned long arg) +{ + int result; + unsigned long value; + unsigned int ivalue; + + switch (cmd) { + case LIRC_GET_SEND_MODE: + if (!(hardware[type].features&LIRC_CAN_SEND_MASK)) + return -ENOIOCTLCMD; + + result = put_user(LIRC_SEND2MODE + (hardware[type].features&LIRC_CAN_SEND_MASK), + (unsigned long *) arg); + if (result) + return result; + break; + + case LIRC_SET_SEND_MODE: + if (!(hardware[type].features&LIRC_CAN_SEND_MASK)) + return -ENOIOCTLCMD; + + result = get_user(value, (unsigned long *) arg); + if (result) + return result; + /* only LIRC_MODE_PULSE supported */ + if (value != LIRC_MODE_PULSE) + return -ENOSYS; + break; + + case LIRC_GET_LENGTH: + return -ENOSYS; + break; + + case LIRC_SET_SEND_DUTY_CYCLE: + dprintk("SET_SEND_DUTY_CYCLE\n"); + if (!(hardware[type].features&LIRC_CAN_SET_SEND_DUTY_CYCLE)) + return -ENOIOCTLCMD; + + result = get_user(ivalue, (unsigned int *) arg); + if (result) + return result; + if (ivalue <= 0 || ivalue > 100) + return -EINVAL; + return init_timing_params(ivalue, freq); + break; + + case LIRC_SET_SEND_CARRIER: + dprintk("SET_SEND_CARRIER\n"); + if (!(hardware[type].features&LIRC_CAN_SET_SEND_CARRIER)) + return -ENOIOCTLCMD; + + result = get_user(ivalue, (unsigned int *) arg); + if (result) + return result; + if (ivalue > 500000 || ivalue < 20000) + return -EINVAL; + return init_timing_params(duty_cycle, ivalue); + break; + + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static struct file_operations lirc_fops = { + .write = lirc_write, +}; + +static struct lirc_plugin plugin = { + .name = LIRC_DRIVER_NAME, + .minor = -1, + .code_length = 1, + .sample_rate = 0, + .data = NULL, + .add_to_buf = NULL, + .get_queue = NULL, + .rbuf = &rbuf, + .set_use_inc = set_use_inc, + .set_use_dec = set_use_dec, + .ioctl = lirc_ioctl, + .fops = &lirc_fops, + .dev = NULL, + .owner = THIS_MODULE, +}; + +#ifdef MODULE + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) +static struct platform_device *lirc_serial_dev; + +static int __devinit lirc_serial_probe(struct platform_device *dev) +{ + return 0; +} + +static int __devexit lirc_serial_remove(struct platform_device *dev) +{ + return 0; +} + +static int lirc_serial_suspend(struct platform_device *dev, + pm_message_t state) +{ + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + /* Disable all interrupts */ + soutp(UART_IER, sinp(UART_IER) & + (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); + + /* Clear registers. */ + sinp(UART_LSR); + sinp(UART_RX); + sinp(UART_IIR); + sinp(UART_MSR); + + return 0; +} + +static int lirc_serial_resume(struct platform_device *dev) +{ + unsigned long flags; + + hardware_init_port(); + + local_irq_save(flags); + /* Enable Interrupt */ + do_gettimeofday(&lasttv); + soutp(UART_IER, sinp(UART_IER)|UART_IER_MSI); + off(); + + lirc_buffer_clear(&rbuf); + + local_irq_restore(flags); + + return 0; +} + +static struct platform_driver lirc_serial_driver = { + .probe = lirc_serial_probe, + .remove = __devexit_p(lirc_serial_remove), + .suspend = lirc_serial_suspend, + .resume = lirc_serial_resume, + .driver = { + .name = "lirc_serial", + .owner = THIS_MODULE, + }, +}; + +static int __init lirc_serial_init(void) +{ + int result; + + result = platform_driver_register(&lirc_serial_driver); + if (result) { + printk("lirc register returned %d\n", result); + return result; + } + + lirc_serial_dev = platform_device_alloc("lirc_serial", 0); + if (!lirc_serial_dev) { + result = -ENOMEM; + goto exit_driver_unregister; + } + + result = platform_device_add(lirc_serial_dev); + if (result) + goto exit_device_put; + + return 0; + +exit_device_put: + platform_device_put(lirc_serial_dev); +exit_driver_unregister: + platform_driver_unregister(&lirc_serial_driver); + return result; +} + +static void __exit lirc_serial_exit(void) +{ + platform_device_unregister(lirc_serial_dev); + platform_driver_unregister(&lirc_serial_driver); +} +#endif + +int __init init_module(void) +{ + int result; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) + result = lirc_serial_init(); + if (result) + return result; +#endif + switch (type) { + case LIRC_HOMEBREW: + case LIRC_IRDEO: + case LIRC_IRDEO_REMOTE: + case LIRC_ANIMAX: + case LIRC_IGOR: +#if defined(LIRC_SERIAL_NSLU2) + case LIRC_NSLU2: +#endif + break; + default: + result = -EINVAL; + goto exit_serial_exit; + } + if (!softcarrier) { + switch (type) { + case LIRC_HOMEBREW: + case LIRC_IGOR: + case LIRC_NSLU2: + hardware[type].features &= + ~(LIRC_CAN_SET_SEND_DUTY_CYCLE| + LIRC_CAN_SET_SEND_CARRIER); + break; + } + } + result = init_port(); + if (result < 0) + goto exit_serial_exit; + plugin.features = hardware[type].features; + plugin.minor = lirc_register_plugin(&plugin); + if (plugin.minor < 0) { + printk(KERN_ERR LIRC_DRIVER_NAME + ": register_chrdev failed!\n"); + result = -EIO; + goto exit_release; + } + return 0; +exit_release: + release_region(io, 8); +exit_serial_exit: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) + lirc_serial_exit(); +#endif + return result; +} + +void __exit cleanup_module(void) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) + lirc_serial_exit(); +#endif +#if defined(LIRC_ALLOW_MMAPPED_IO) + if (iommap != 0) + release_mem_region(iommap, 8< + * + * Transmitter support and reception code cleanup. + * (C) by Daniel Melander + * + * Derived from ATI USB driver by Paul Miller and the original + * MCE USB driver by Dan Corti + * + * This driver will only work reliably with kernel version 2.6.10 + * or higher, probably because of differences in USB device enumeration + * in the kernel code. Device initialization fails most of the time + * with earlier kernel versions. + * + ********************************************************************** + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 5) +#error "*******************************************************" +#error "Sorry, this driver needs kernel version 2.6.5 or higher" +#error "*******************************************************" +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#include +#else +#include +#endif +#include +#include +#include +#include + +#include "lirc.h" +#include "kcompat.h" +#include "lirc_dev/lirc_dev.h" + +#define DRIVER_VERSION "$Revision: 1.44 $" +#define DRIVER_AUTHOR "Daniel Melander , " \ + "Martin Blatter " +#define DRIVER_DESC "Philips eHome USB IR Transceiver and Microsoft " \ + "MCE 2005 Remote Control driver for LIRC" +#define DRIVER_NAME "lirc_mceusb2" + +#define USB_BUFLEN 16 /* USB reception buffer length */ +#define LIRCBUF_SIZE 256 /* LIRC work buffer length */ + +/* MCE constants */ +#define MCE_CMDBUF_SIZE 384 /* MCE Command buffer length */ +#define MCE_TIME_UNIT 50 /* Approx 50us resolution */ +#define MCE_CODE_LENGTH 5 /* Normal length of packet (with header) */ +#define MCE_PACKET_SIZE 4 /* Normal length of packet (without header) */ +#define MCE_PACKET_HEADER 0x84 /* Actual header format is 0x80 + num_bytes */ +#define MCE_CONTROL_HEADER 0x9F /* MCE status header */ +#define MCE_TX_HEADER_LENGTH 3 /* # of bytes in the initializing tx header */ +#define MCE_MAX_CHANNELS 2 /* Two transmitters, hardware dependent? */ +#define MCE_DEFAULT_TX_MASK 0x03 /* Val opts: TX1=0x01, TX2=0x02, ALL=0x03 */ +#define MCE_PULSE_BIT 0x80 /* Pulse bit, MSB set == PULSE else SPACE */ +#define MCE_PULSE_MASK 0x7F /* Pulse mask */ +#define MCE_MAX_PULSE_LENGTH 0x7F /* Longest transmittable pulse symbol */ + + +/* module parameters */ +#ifdef CONFIG_USB_DEBUG +static int debug = 1; +#else +static int debug; +#endif +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG fmt, ## args); \ + } while (0) + +/* lock irctl structure */ +/*#define IRLOCK down_interruptible(&ir->lock) */ +#define IRLOCK down(&ir->lock) +#define IRUNLOCK up(&ir->lock) + +/* general constants */ +#define SUCCESS 0 +#define SEND_FLAG_IN_PROGRESS 1 +#define SEND_FLAG_COMPLETE 2 +#define RECV_FLAG_IN_PROGRESS 3 +#define RECV_FLAG_COMPLETE 4 + +#define PHILUSB_INBOUND 1 +#define PHILUSB_OUTBOUND 2 + +#define VENDOR_PHILIPS 0x0471 +#define VENDOR_SMK 0x0609 +#define VENDOR_TATUNG 0x1460 +#define VENDOR_GATEWAY 0x107b +#define VENDOR_SHUTTLE 0x1308 +#define VENDOR_SHUTTLE2 0x051c +#define VENDOR_MITSUMI 0x03ee +#define VENDOR_TOPSEED 0x1784 +#define VENDOR_RICAVISION 0x179d +#define VENDOR_ITRON 0x195d +#define VENDOR_FIC 0x1509 +#define VENDOR_LG 0x043e +#define VENDOR_MICROSOFT 0x045e +#define VENDOR_FORMOSA 0x147a +#define VENDOR_FINTEK 0x1934 + +static struct usb_device_id usb_remote_table [] = { + /* Philips eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_PHILIPS, 0x0815) }, + /* Philips Infrared Transceiver - HP branded */ + { USB_DEVICE(VENDOR_PHILIPS, 0x060c) }, + /* Philips SRM5100 */ + { USB_DEVICE(VENDOR_PHILIPS, 0x060d) }, + /* SMK/Toshiba G83C0004D410 */ + { USB_DEVICE(VENDOR_SMK, 0x031d) }, + /* SMK eHome Infrared Transceiver (Sony VAIO) */ + { USB_DEVICE(VENDOR_SMK, 0x0322) }, + /* bundled with Hauppauge PVR-150 */ + { USB_DEVICE(VENDOR_SMK, 0x0334) }, + /* Tatung eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_TATUNG, 0x9150) }, + /* Shuttle eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_SHUTTLE, 0xc001) }, + /* Shuttle eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_SHUTTLE2, 0xc001) }, + /* Gateway eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_GATEWAY, 0x3009) }, + /* Mitsumi */ + { USB_DEVICE(VENDOR_MITSUMI, 0x2501) }, + /* Topseed eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_TOPSEED, 0x0001) }, + /* Topseed HP eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_TOPSEED, 0x0006) }, + /* Topseed eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_TOPSEED, 0x0007) }, + /* Topseed eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_TOPSEED, 0x0008) }, + /* Ricavision internal Infrared Transceiver */ + { USB_DEVICE(VENDOR_RICAVISION, 0x0010) }, + /* Itron ione Libra Q-11 */ + { USB_DEVICE(VENDOR_ITRON, 0x7002) }, + /* FIC eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_FIC, 0x9242) }, + /* LG eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_LG, 0x9803) }, + /* Microsoft MCE Infrared Transceiver */ + { USB_DEVICE(VENDOR_MICROSOFT, 0x00a0) }, + /* Formosa eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_FORMOSA, 0xe015) }, + /* Formosa aim / Trust MCE Infrared Receiver */ + { USB_DEVICE(VENDOR_FORMOSA, 0xe017) }, + /* Formosa Industrial Computing / Beanbag Emulation Device */ + { USB_DEVICE(VENDOR_FORMOSA, 0xe018) }, + /* Fintek eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_FINTEK, 0x0602) }, + /* Terminating entry */ + { } +}; + +/* data structure for each usb remote */ +struct irctl { + + /* usb */ + struct usb_device *usbdev; + struct urb *urb_in; + int devnum; + struct usb_endpoint_descriptor *usb_ep_in; + struct usb_endpoint_descriptor *usb_ep_out; + + /* buffers and dma */ + unsigned char *buf_in; + unsigned int len_in; + dma_addr_t dma_in; + dma_addr_t dma_out; + + /* lirc */ + struct lirc_plugin *p; + lirc_t lircdata; + unsigned char is_pulse; + int connected; + + unsigned char transmitter_mask; + unsigned int carrier_freq; + + /* handle sending (init strings) */ + int send_flags; + wait_queue_head_t wait_out; + + struct semaphore lock; +}; + +/* init strings */ +static char init1[] = {0x00, 0xff, 0xaa, 0xff, 0x0b}; +static char init2[] = {0xff, 0x18}; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) +static inline unsigned long usecs_to_jiffies(const unsigned int u) +{ + if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET)) + return MAX_JIFFY_OFFSET; +#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ) + return (u + (USEC_PER_SEC / HZ) - 1) / (USEC_PER_SEC / HZ); +#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC) + return u * (HZ / USEC_PER_SEC); +#else + return (u * HZ + USEC_PER_SEC - 1) / USEC_PER_SEC; +#endif +} +#endif + + +static void usb_remote_printdata(struct irctl *ir, char *buf, int len) +{ + char codes[USB_BUFLEN*3 + 1]; + int i; + + if (len <= 0) + return; + + for (i = 0; i < len && i < USB_BUFLEN; i++) + snprintf(codes+i*3, 4, "%02x ", buf[i] & 0xFF); + + printk(KERN_INFO "" DRIVER_NAME "[%d]: data received %s (length=%d)\n", + ir->devnum, codes, len); +} + +static void usb_async_callback(struct urb *urb, struct pt_regs *regs) +{ + struct irctl *ir; + int len; + + if (!urb) + return; + + ir = urb->context; + if (ir) { + len = urb->actual_length; + + dprintk(DRIVER_NAME + "[%d]: callback called (status=%d len=%d)\n", + ir->devnum, urb->status, len); + + if (debug) + usb_remote_printdata(ir, urb->transfer_buffer, len); + } + +} + + +/* request incoming or send outgoing usb packet - used to initialize remote */ +static void request_packet_async(struct irctl *ir, + struct usb_endpoint_descriptor *ep, + unsigned char *data, int size, int urb_type) +{ + int res; + struct urb *async_urb; + unsigned char *async_buf; + + if (urb_type) { + async_urb = usb_alloc_urb(0, GFP_KERNEL); + if (async_urb) { + /* alloc buffer */ + async_buf = kmalloc(size, GFP_KERNEL); + if (async_buf) { + if (urb_type == PHILUSB_OUTBOUND) { + /* outbound data */ + usb_fill_int_urb(async_urb, ir->usbdev, + usb_sndintpipe(ir->usbdev, + ep->bEndpointAddress), + async_buf, + size, + (usb_complete_t) usb_async_callback, + ir, ep->bInterval); + + memcpy(async_buf, data, size); + async_urb->transfer_flags = + URB_ASYNC_UNLINK; + } else { + /* inbound data */ + usb_fill_int_urb(async_urb, ir->usbdev, + usb_rcvintpipe(ir->usbdev, + ep->bEndpointAddress), + async_buf, size, + (usb_complete_t) usb_async_callback, + ir, ep->bInterval); + + async_urb->transfer_flags = + URB_ASYNC_UNLINK; + } + } else { + usb_free_urb(async_urb); + return; + } + } + } else { + /* standard request */ + async_urb = ir->urb_in; + ir->send_flags = RECV_FLAG_IN_PROGRESS; + } + dprintk(DRIVER_NAME "[%d]: receive request called (size=%#x)\n", + ir->devnum, size); + + async_urb->transfer_buffer_length = size; + async_urb->dev = ir->usbdev; + + res = usb_submit_urb(async_urb, GFP_ATOMIC); + if (res) { + dprintk(DRIVER_NAME "[%d]: receive request FAILED! (res=%d)\n", + ir->devnum, res); + return; + } + dprintk(DRIVER_NAME "[%d]: receive request complete (res=%d)\n", + ir->devnum, res); +} + +static int unregister_from_lirc(struct irctl *ir) +{ + struct lirc_plugin *p = ir->p; + int devnum; + int rtn; + + devnum = ir->devnum; + dprintk(DRIVER_NAME "[%d]: unregister from lirc called\n", devnum); + + rtn = lirc_unregister_plugin(p->minor); + if (rtn > 0) { + printk(DRIVER_NAME "[%d]: error in lirc_unregister minor: %d\n" + "Trying again...\n", devnum, p->minor); + if (rtn == -EBUSY) { + printk(DRIVER_NAME + "[%d]: device is opened, will unregister" + " on close\n", devnum); + return -EAGAIN; + } + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ); + + rtn = lirc_unregister_plugin(p->minor); + if (rtn > 0) + printk(DRIVER_NAME "[%d]: lirc_unregister failed\n", + devnum); + } + + if (rtn != SUCCESS) { + printk(DRIVER_NAME "[%d]: didn't free resources\n", devnum); + return -EAGAIN; + } + + printk(DRIVER_NAME "[%d]: usb remote disconnected\n", devnum); + + lirc_buffer_free(p->rbuf); + kfree(p->rbuf); + kfree(p); + kfree(ir); + return SUCCESS; +} + +static int set_use_inc(void *data) +{ + struct irctl *ir = data; + + if (!ir) { + printk(DRIVER_NAME "[?]: set_use_inc called with no context\n"); + return -EIO; + } + dprintk(DRIVER_NAME "[%d]: set use inc\n", ir->devnum); + + MOD_INC_USE_COUNT; + + if (!ir->connected) { + if (!ir->usbdev) + return -ENOENT; + ir->connected = 1; + } + + return SUCCESS; +} + +static void set_use_dec(void *data) +{ + struct irctl *ir = data; + + if (!ir) { + printk(DRIVER_NAME "[?]: set_use_dec called with no context\n"); + return; + } + dprintk(DRIVER_NAME "[%d]: set use dec\n", ir->devnum); + + if (ir->connected) { + IRLOCK; + ir->connected = 0; + IRUNLOCK; + } + MOD_DEC_USE_COUNT; +} + +static void send_packet_to_lirc(struct irctl *ir) +{ + if (ir->lircdata != 0) { + lirc_buffer_write_1(ir->p->rbuf, + (unsigned char *) &ir->lircdata); + wake_up(&ir->p->rbuf->wait_poll); + ir->lircdata = 0; + } +} + +static void usb_remote_recv(struct urb *urb, struct pt_regs *regs) +{ + struct irctl *ir; + int buf_len, packet_len; + int i, j; + + if (!urb) + return; + + ir = urb->context; + if (!ir) { + urb->transfer_flags |= URB_ASYNC_UNLINK; + usb_unlink_urb(urb); + return; + } + + buf_len = urb->actual_length; + packet_len = 0; + + if (debug) + usb_remote_printdata(ir, urb->transfer_buffer, buf_len); + + if (ir->send_flags == RECV_FLAG_IN_PROGRESS) { + ir->send_flags = SEND_FLAG_COMPLETE; + dprintk(DRIVER_NAME "[%d]: setup answer received %d bytes\n", + ir->devnum, buf_len); + } + + switch (urb->status) { + /* success */ + case SUCCESS: + for (i = 0; i < buf_len; i++) { + /* decode mce packets on the form (84),AA,BB,CC,DD */ + switch (ir->buf_in[i]) { + /* data headers */ + case 0x8F: + case 0x8E: + case 0x8D: + case 0x8C: + case 0x8B: + case 0x8A: + case 0x89: + case 0x88: + case 0x87: + case 0x86: + case 0x85: + case 0x84: + case 0x83: + case 0x82: + case 0x81: + case 0x80: + /* decode packet data */ + packet_len = ir->buf_in[i] & MCE_PULSE_MASK; + for (j = 1; + j <= packet_len && (i+j < buf_len); + j++) { + /* rising/falling flank */ + if (ir->is_pulse != + (ir->buf_in[i + j] & + MCE_PULSE_BIT)) { + send_packet_to_lirc(ir); + ir->is_pulse = + ir->buf_in[i + j] & + MCE_PULSE_BIT; + } + + /* accumulate mce pulse/space values */ + ir->lircdata += + (ir->buf_in[i + j] & + MCE_PULSE_MASK)*MCE_TIME_UNIT; + ir->lircdata |= + (ir->is_pulse ? PULSE_BIT : 0); + } + + i += packet_len; + break; + + /* status header (0x9F) */ + case MCE_CONTROL_HEADER: + /* A transmission containing one or + more consecutive ir commands always + ends with a GAP of 100ms followed by the + sequence 0x9F 0x01 0x01 0x9F 0x15 + 0x00 0x00 0x80 */ + + /* + Uncomment this if the last 100ms + "infinity"-space should be transmitted + to lirc directly instead of at the beginning + of the next transmission. Changes pulse/space order. + + if (++i < buf_len && ir->buf_in[i]==0x01) + send_packet_to_lirc(ir); + + */ + + /* end decode loop */ + i = buf_len; + break; + default: + break; + } + } + + break; + + /* unlink */ + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + urb->transfer_flags |= URB_ASYNC_UNLINK; + usb_unlink_urb(urb); + return; + + case -EPIPE: + default: + break; + } + + /* resubmit urb */ + usb_submit_urb(urb, GFP_ATOMIC); +} + + +static ssize_t lirc_write(struct file *file, const char *buf, + size_t n, loff_t *ppos) +{ + int i, count = 0, cmdcount = 0; + struct irctl *ir = NULL; + lirc_t wbuf[LIRCBUF_SIZE]; /* Workbuffer with values from lirc */ + unsigned char cmdbuf[MCE_CMDBUF_SIZE]; /* MCE command buffer */ + unsigned long signal_duration = 0; /* Singnal length in us */ + struct timeval start_time, end_time; + + do_gettimeofday(&start_time); + + /* Retrieve lirc_plugin data for the device */ + ir = lirc_get_pdata(file); + if (!ir && !ir->usb_ep_out) + return -EFAULT; + + if (n % sizeof(lirc_t)) + return(-EINVAL); + count = n / sizeof(lirc_t); + + /* Check if command is within limits */ + if (count > LIRCBUF_SIZE || count%2 == 0) + return(-EINVAL); + if (copy_from_user(wbuf, buf, n)) + return -EFAULT; + + /* MCE tx init header */ + cmdbuf[cmdcount++] = MCE_CONTROL_HEADER; + cmdbuf[cmdcount++] = 0x08; + cmdbuf[cmdcount++] = ir->transmitter_mask; + + /* Generate mce packet data */ + for (i = 0; (i < count) && (cmdcount < MCE_CMDBUF_SIZE); i++) { + signal_duration += wbuf[i]; + wbuf[i] = wbuf[i] / MCE_TIME_UNIT; + + do { /* loop to support long pulses/spaces > 127*50us=6.35ms */ + + /* Insert mce packet header every 4th entry */ + if ((cmdcount < MCE_CMDBUF_SIZE) && + (cmdcount - MCE_TX_HEADER_LENGTH) % + MCE_CODE_LENGTH == 0) + cmdbuf[cmdcount++] = MCE_PACKET_HEADER; + + /* Insert mce packet data */ + if (cmdcount < MCE_CMDBUF_SIZE) + cmdbuf[cmdcount++] = + (wbuf[i] < MCE_PULSE_BIT ? + wbuf[i] : MCE_MAX_PULSE_LENGTH) | + (i & 1 ? 0x00 : MCE_PULSE_BIT); + else + return -EINVAL; + } while ((wbuf[i] > MCE_MAX_PULSE_LENGTH) && + (wbuf[i] -= MCE_MAX_PULSE_LENGTH)); + } + + /* Fix packet length in last header */ + cmdbuf[cmdcount - (cmdcount - MCE_TX_HEADER_LENGTH) % MCE_CODE_LENGTH] = + 0x80 + (cmdcount - MCE_TX_HEADER_LENGTH) % MCE_CODE_LENGTH - 1; + + /* Check if we have room for the empty packet at the end */ + if (cmdcount >= MCE_CMDBUF_SIZE) + return -EINVAL; + + /* All mce commands end with an empty packet (0x80) */ + cmdbuf[cmdcount++] = 0x80; + + /* Transmit the command to the mce device */ + request_packet_async(ir, ir->usb_ep_out, cmdbuf, + cmdcount, PHILUSB_OUTBOUND); + + /* The lircd gap calculation expects the write function to + wait the time it takes for the ircommand to be sent before + it returns. */ + do_gettimeofday(&end_time); + signal_duration -= (end_time.tv_usec - start_time.tv_usec) + + (end_time.tv_sec - start_time.tv_sec) * 1000000; + + /* delay with the closest number of ticks */ + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(usecs_to_jiffies(signal_duration)); + + return n; +} + +static void set_transmitter_mask(struct irctl *ir, unsigned int mask) +{ + + /* SMK Transceiver does not use the inverted scheme, nor does Topseed*/ + if ((ir->usbdev->descriptor.idVendor == VENDOR_SMK && + (ir->usbdev->descriptor.idProduct == 0x031d || + ir->usbdev->descriptor.idProduct == 0x0322 || + ir->usbdev->descriptor.idProduct == 0x0334)) || + (ir->usbdev->descriptor.idVendor == VENDOR_TOPSEED && + (ir->usbdev->descriptor.idProduct == 0x0001 || + ir->usbdev->descriptor.idProduct == 0x0007 || + ir->usbdev->descriptor.idProduct == 0x0008))) + ir->transmitter_mask = mask; + else + /* The mask begins at 0x02 and has an inverted + numbering scheme */ + ir->transmitter_mask = (mask != 0x03 ? mask ^ 0x03 : mask) << 1; +} + + +/* Sets the send carrier frequency */ +static int set_send_carrier(struct irctl *ir, int carrier) +{ + int clk = 10000000; + int prescaler = 0, divisor = 0; + unsigned char cmdbuf[] = { 0x9F, 0x06, 0x01, 0x80 }; + + /* Carrier is changed */ + if (ir->carrier_freq != carrier) { + + if (carrier <= 0) { + ir->carrier_freq = carrier; + dprintk(DRIVER_NAME "[%d]: SET_CARRIER disabling " + "carrier modulation\n", ir->devnum); + request_packet_async(ir, ir->usb_ep_out, + cmdbuf, sizeof(cmdbuf), + PHILUSB_OUTBOUND); + return carrier; + } + + for (prescaler = 0; prescaler < 4; ++prescaler) { + divisor = (clk >> (2 * prescaler)) / carrier; + if (divisor <= 0xFF) { + ir->carrier_freq = carrier; + cmdbuf[2] = prescaler; + cmdbuf[3] = divisor; + dprintk(DRIVER_NAME "[%d]: SET_CARRIER " + "requesting %d Hz\n", + ir->devnum, carrier); + + /* Transmit the new carrier to the mce + device */ + request_packet_async(ir, ir->usb_ep_out, + cmdbuf, sizeof(cmdbuf), + PHILUSB_OUTBOUND); + return carrier; + } + } + + return -EINVAL; + + } + + return carrier; +} + + +static int lirc_ioctl(struct inode *node, struct file *filep, + unsigned int cmd, unsigned long arg) +{ + int result; + unsigned int ivalue; + unsigned long lvalue; + struct irctl *ir = NULL; + + /* Retrieve lirc_plugin data for the device */ + ir = lirc_get_pdata(filep); + if (!ir && !ir->usb_ep_out) + return -EFAULT; + + + switch (cmd) { + case LIRC_SET_TRANSMITTER_MASK: + + result = get_user(ivalue, (unsigned int *) arg); + if (result) + return result; + switch (ivalue) { + case 0x01: /* Transmitter 1 => 0x04 */ + case 0x02: /* Transmitter 2 => 0x02 */ + case 0x03: /* Transmitter 1 & 2 => 0x06 */ + set_transmitter_mask(ir, ivalue); + break; + + default: /* Unsupported transmitter mask */ + return MCE_MAX_CHANNELS; + } + + dprintk(DRIVER_NAME ": SET_TRANSMITTERS mask=%d\n", ivalue); + break; + + case LIRC_GET_SEND_MODE: + + result = put_user(LIRC_SEND2MODE(LIRC_CAN_SEND_PULSE & + LIRC_CAN_SEND_MASK), + (unsigned long *) arg); + + if (result) + return result; + break; + + case LIRC_SET_SEND_MODE: + + result = get_user(lvalue, (unsigned long *) arg); + + if (result) + return result; + if (lvalue != (LIRC_MODE_PULSE&LIRC_CAN_SEND_MASK)) + return -EINVAL; + break; + + case LIRC_SET_SEND_CARRIER: + + result = get_user(ivalue, (unsigned int *) arg); + if (result) + return result; + + set_send_carrier(ir, ivalue); + break; + + default: + return -ENOIOCTLCMD; + } + + return 0; +} + +static struct file_operations lirc_fops = { + .write = lirc_write, +}; + + +static int usb_remote_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_device *dev = interface_to_usbdev(intf); + struct usb_host_interface *idesc; + struct usb_endpoint_descriptor *ep = NULL; + struct usb_endpoint_descriptor *ep_in = NULL; + struct usb_endpoint_descriptor *ep_out = NULL; + struct usb_host_config *config; + struct irctl *ir = NULL; + struct lirc_plugin *plugin = NULL; + struct lirc_buffer *rbuf = NULL; + int devnum, pipe, maxp; + int minor = 0; + int i; + char buf[63], name[128] = ""; + int mem_failure = 0; + + dprintk(DRIVER_NAME ": usb probe called\n"); + + usb_reset_device(dev); + + config = dev->actconfig; + + idesc = intf->cur_altsetting; + + /* step through the endpoints to find first bulk in and out endpoint */ + for (i = 0; i < idesc->desc.bNumEndpoints; ++i) { + ep = &idesc->endpoint[i].desc; + + if ((ep_in == NULL) + && ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) + == USB_DIR_IN) + && (((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_BULK) + || ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_INT))) { + + dprintk(DRIVER_NAME ": acceptable inbound endpoint " + "found\n"); + ep_in = ep; + ep_in->bmAttributes = USB_ENDPOINT_XFER_INT; + ep_in->bInterval = 1; + } + + if ((ep_out == NULL) + && ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) + == USB_DIR_OUT) + && (((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_BULK) + || ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_INT))) { + + dprintk(DRIVER_NAME ": acceptable outbound endpoint " + "found\n"); + ep_out = ep; + ep_out->bmAttributes = USB_ENDPOINT_XFER_INT; + ep_out->bInterval = 1; + } + } + if (ep_in == NULL) { + dprintk(DRIVER_NAME ": inbound and/or endpoint not found\n"); + return -ENODEV; + } + + devnum = dev->devnum; + pipe = usb_rcvintpipe(dev, ep_in->bEndpointAddress); + maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); + + /* allocate kernel memory */ + mem_failure = 0; + ir = kmalloc(sizeof(struct irctl), GFP_KERNEL); + if (!ir) { + mem_failure = 1; + goto mem_failure_switch; + } + + memset(ir, 0, sizeof(struct irctl)); + + plugin = kmalloc(sizeof(struct lirc_plugin), GFP_KERNEL); + if (!plugin) { + mem_failure = 2; + goto mem_failure_switch; + } + + rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); + if (!rbuf) { + mem_failure = 3; + goto mem_failure_switch; + } + + if (lirc_buffer_init(rbuf, sizeof(lirc_t), LIRCBUF_SIZE)) { + mem_failure = 4; + goto mem_failure_switch; + } + + ir->buf_in = usb_buffer_alloc(dev, maxp, GFP_ATOMIC, &ir->dma_in); + if (!ir->buf_in) { + mem_failure = 5; + goto mem_failure_switch; + } + + ir->urb_in = usb_alloc_urb(0, GFP_KERNEL); + if (!ir->urb_in) { + mem_failure = 7; + goto mem_failure_switch; + } + + memset(plugin, 0, sizeof(struct lirc_plugin)); + + strcpy(plugin->name, DRIVER_NAME " "); + plugin->minor = -1; + plugin->features = LIRC_CAN_SEND_PULSE | + LIRC_CAN_SET_TRANSMITTER_MASK | + LIRC_CAN_REC_MODE2 | + LIRC_CAN_SET_SEND_CARRIER; + plugin->data = ir; + plugin->rbuf = rbuf; + plugin->set_use_inc = &set_use_inc; + plugin->set_use_dec = &set_use_dec; + plugin->code_length = sizeof(lirc_t) * 8; + plugin->ioctl = lirc_ioctl; + plugin->fops = &lirc_fops; + plugin->dev = &dev->dev; + plugin->owner = THIS_MODULE; + + init_MUTEX(&ir->lock); + init_waitqueue_head(&ir->wait_out); + + minor = lirc_register_plugin(plugin); + if (minor < 0) + mem_failure = 9; + +mem_failure_switch: + + /* free allocated memory incase of failure */ + switch (mem_failure) { + case 9: + usb_free_urb(ir->urb_in); + case 7: + usb_buffer_free(dev, maxp, ir->buf_in, ir->dma_in); + case 5: + lirc_buffer_free(rbuf); + case 4: + kfree(rbuf); + case 3: + kfree(plugin); + case 2: + kfree(ir); + case 1: + printk(DRIVER_NAME "[%d]: out of memory (code=%d)\n", + devnum, mem_failure); + return -ENOMEM; + } + + plugin->minor = minor; + ir->p = plugin; + ir->devnum = devnum; + ir->usbdev = dev; + ir->len_in = maxp; + ir->connected = 0; + + ir->lircdata = PULSE_MASK; + ir->is_pulse = 0; + + /* ir->usbdev must be set */ + set_transmitter_mask(ir, MCE_DEFAULT_TX_MASK); + /* Saving usb interface data for use by the transmitter routine */ + ir->usb_ep_in = ep_in; + ir->usb_ep_out = ep_out; + + if (dev->descriptor.iManufacturer + && usb_string(dev, dev->descriptor.iManufacturer, buf, 63) > 0) + strncpy(name, buf, 128); + if (dev->descriptor.iProduct + && usb_string(dev, dev->descriptor.iProduct, buf, 63) > 0) + snprintf(name, 128, "%s %s", name, buf); + printk(DRIVER_NAME "[%d]: %s on usb%d:%d\n", devnum, name, + dev->bus->busnum, devnum); + + /* inbound data */ + usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in, + maxp, (usb_complete_t) usb_remote_recv, ir, ep_in->bInterval); + + /* initialize device */ + request_packet_async(ir, ep_in, NULL, maxp, PHILUSB_INBOUND); + request_packet_async(ir, ep_in, NULL, maxp, PHILUSB_INBOUND); + request_packet_async(ir, ep_out, init1, + sizeof(init1), PHILUSB_OUTBOUND); + request_packet_async(ir, ep_in, NULL, maxp, PHILUSB_INBOUND); + request_packet_async(ir, ep_out, init2, + sizeof(init2), PHILUSB_OUTBOUND); + request_packet_async(ir, ep_in, NULL, maxp, 0); + + usb_set_intfdata(intf, ir); + + return SUCCESS; +} + + +static void usb_remote_disconnect(struct usb_interface *intf) +{ + struct usb_device *dev = interface_to_usbdev(intf); + struct irctl *ir = usb_get_intfdata(intf); + + usb_set_intfdata(intf, NULL); + + if (!ir || !ir->p) + return; + + ir->usbdev = NULL; + wake_up_all(&ir->wait_out); + + IRLOCK; + usb_kill_urb(ir->urb_in); + usb_free_urb(ir->urb_in); + usb_buffer_free(dev, ir->len_in, ir->buf_in, ir->dma_in); + IRUNLOCK; + + unregister_from_lirc(ir); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) +static int usb_remote_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct irctl *ir = usb_get_intfdata(intf); + printk(DRIVER_NAME "[%d]: suspend\n", ir->devnum); + usb_kill_urb(ir->urb_in); + return 0; +} + +static int usb_remote_resume(struct usb_interface *intf) +{ + struct irctl *ir = usb_get_intfdata(intf); + printk(DRIVER_NAME "[%d]: resume\n", ir->devnum); + if (usb_submit_urb(ir->urb_in, GFP_ATOMIC)) + return -EIO; + return 0; +} +#endif + +static struct usb_driver usb_remote_driver = { + LIRC_THIS_MODULE(.owner = THIS_MODULE) + .name = DRIVER_NAME, + .probe = usb_remote_probe, + .disconnect = usb_remote_disconnect, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) + .suspend = usb_remote_suspend, + .resume = usb_remote_resume, +#endif + .id_table = usb_remote_table +}; + +static int __init usb_remote_init(void) +{ + int i; + + printk(KERN_INFO "\n"); + printk(KERN_INFO DRIVER_NAME ": " DRIVER_DESC " " DRIVER_VERSION "\n"); + printk(KERN_INFO DRIVER_NAME ": " DRIVER_AUTHOR "\n"); + dprintk(DRIVER_NAME ": debug mode enabled\n"); + + request_module("lirc_dev"); + + i = usb_register(&usb_remote_driver); + if (i < 0) { + printk(DRIVER_NAME ": usb register failed, result = %d\n", i); + return -ENODEV; + } + + return SUCCESS; +} + +static void __exit usb_remote_exit(void) +{ + usb_deregister(&usb_remote_driver); +} + +module_init(usb_remote_init); +module_exit(usb_remote_exit); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(usb, usb_remote_table); + +module_param(debug, bool, 0644); +MODULE_PARM_DESC(debug, "Debug enabled or not"); + +EXPORT_NO_SYMBOLS; --- linux-2.6.28.orig/ubuntu/lirc/lirc_mceusb2/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_mceusb2/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_MCEUSB2) += lirc_mceusb2.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_sasem/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_sasem/Makefile @@ -0,0 +1,2 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. +obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_sasem/lirc_sasem.c +++ linux-2.6.28/ubuntu/lirc/lirc_sasem/lirc_sasem.c @@ -0,0 +1,1130 @@ +/* $Id: lirc_sasem.c,v 1.21 2007/09/30 09:58:46 lirc Exp $ */ + +/* lirc_sasem.c - USB remote support for LIRC + * Version 0.5 + * + * Copyright (C) 2004-2005 Oliver Stabel + * Tim Davies + * + * This driver was derived from: + * Venky Raju + * "lirc_imon - "LIRC plugin/VFD driver for Ahanix/Soundgraph IMON IR/VFD" + * Paul Miller 's 2003-2004 + * "lirc_atiusb - USB remote support for LIRC" + * Culver Consulting Services 's 2003 + * "Sasem OnAir VFD/IR USB driver" + * + * + * 2004/06/13 - 0.1 + * initial version + * + * 2004/06/28 - 0.2 + * added file system support to write data to VFD device (used + * in conjunction with LCDProc) + * + * 2004/11/22 - 0.3 + * Ported to 2.6 kernel + * - Tim Davies + * + * 2005/03/29 - 0.4 + * A few tidyups and keypress timings + * - Tim Davies + * + * 2005/06/23 - 0.5 + * A complete rewrite (shamelessly) based on lirc_imon.c + * Tim Davies + * + * NOTE - The LCDproc iMon driver should work with this module. More info at + * http://www.frogstorm.info/sasem + */ + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 22) +#error "*** Sorry, this driver requires kernel version 2.4.22 or higher" +#endif + +#include + +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#include +#else +#include +#endif +#include + +#include "kcompat.h" +#include "lirc.h" +#include "lirc_dev/lirc_dev.h" + + +#define MOD_AUTHOR "Oliver Stabel , " \ + "Tim Davies " +#define MOD_DESC "USB Driver for Sasem Remote Controller V1.1" +#define MOD_NAME "lirc_sasem" +#define MOD_VERSION "0.5" + +#define VFD_MINOR_BASE 144 /* Same as LCD */ +#define DEVFS_MODE S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH +#define DEVFS_NAME LIRC_DEVFS_PREFIX "lcd%d" + +#define BUF_CHUNK_SIZE 8 +#define BUF_SIZE 128 + +#define SUCCESS 0 +#define TRUE 1 +#define FALSE 0 + +#define IOCTL_LCD_CONTRAST 1 + +/* ------------------------------------------------------------ + * P R O T O T Y P E S + * ------------------------------------------------------------ + */ + +/* USB Callback prototypes */ +#ifdef KERNEL_2_5 +static int sasem_probe(struct usb_interface *interface, + const struct usb_device_id *id); +static void sasem_disconnect(struct usb_interface *interface); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void usb_rx_callback(struct urb *urb, struct pt_regs *regs); +static void usb_tx_callback(struct urb *urb, struct pt_regs *regs); +#else +static void usb_rx_callback(struct urb *urb); +static void usb_tx_callback(struct urb *urb); +#endif +#else +static void *sasem_probe(struct usb_device *dev, unsigned int intf, + const struct usb_device_id *id); +static void sasem_disconnect(struct usb_device *dev, void *data); +static void usb_rx_callback(struct urb *urb); +static void usb_tx_callback(struct urb *urb); +#endif + +/* VFD file_operations function prototypes */ +static int vfd_open(struct inode *inode, struct file *file); +static int vfd_ioctl(struct inode *inode, struct file *file, + unsigned cmd, unsigned long arg); +static int vfd_close(struct inode *inode, struct file *file); +static ssize_t vfd_write(struct file *file, const char *buf, + size_t n_bytes, loff_t *pos); + +/* LIRC plugin function prototypes */ +static int ir_open(void *data); +static void ir_close(void *data); + +/* Driver init/exit prototypes */ +static int __init sasem_init(void); +static void __exit sasem_exit(void); + +/* ------------------------------------------------------------ + * G L O B A L S + * ------------------------------------------------------------ + */ + +struct sasem_context { + + struct usb_device *dev; + int vfd_isopen; /* VFD port has been opened */ + unsigned int vfd_contrast; /* VFD contrast */ +#if !defined(KERNEL_2_5) + int subminor; /* index into minor_table */ + devfs_handle_t devfs; +#endif + int ir_isopen; /* IR port has been opened */ + int dev_present; /* USB device presence */ + struct semaphore sem; /* to lock this object */ + wait_queue_head_t remove_ok; /* For unexpected USB disconnects */ + + struct lirc_plugin *plugin; + struct usb_endpoint_descriptor *rx_endpoint; + struct usb_endpoint_descriptor *tx_endpoint; + struct urb *rx_urb; + struct urb *tx_urb; + unsigned char usb_rx_buf [8]; + unsigned char usb_tx_buf [8]; + + struct tx_t { + unsigned char data_buf [32]; /* user data buffer */ + struct completion finished; /* wait for write to finish */ + atomic_t busy; /* write in progress */ + int status; /* status of tx completion */ + } tx; + + /* for dealing with repeat codes (wish there was a toggle bit!) */ + struct timeval presstime; + char lastcode[8]; + int codesaved; +}; + +#define LOCK_CONTEXT down(&context->sem) +#define UNLOCK_CONTEXT up(&context->sem) + +/* VFD file operations */ +static struct file_operations vfd_fops = { + + .owner = THIS_MODULE, + .open = &vfd_open, + .write = &vfd_write, + .ioctl = &vfd_ioctl, + .release = &vfd_close +}; + +/* USB Device ID for Sasem USB Control Board */ +static struct usb_device_id sasem_usb_id_table [] = { + { USB_DEVICE(0x11ba, 0x0101) }, /* Sasem */ + {} +}; + +/* USB Device data */ +static struct usb_driver sasem_driver = { + LIRC_THIS_MODULE(.owner = THIS_MODULE) + .name = MOD_NAME, + .probe = sasem_probe, + .disconnect = sasem_disconnect, + .id_table = sasem_usb_id_table, +#if !defined(KERNEL_2_5) + .fops = &vfd_fops, + .minor = VFD_MINOR_BASE, +#endif +}; + +#ifdef KERNEL_2_5 +static struct usb_class_driver sasem_class = { + .name = DEVFS_NAME, + .fops = &vfd_fops, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15) + .mode = DEVFS_MODE, +#endif + .minor_base = VFD_MINOR_BASE, +}; +#endif + +/* to prevent races between open() and disconnect() */ +static DECLARE_MUTEX(disconnect_sem); + +static int debug; + +#if !defined(KERNEL_2_5) + +#define MAX_DEVICES 4 /* In case there's more than one Sasem device */ +static struct sasem_context *minor_table [MAX_DEVICES]; + +/* the global usb devfs handle */ +extern devfs_handle_t usb_devfs_handle; + +#endif + +/* ------------------------------------------------------------ + * M O D U L E C O D E + * ------------------------------------------------------------ + */ + +MODULE_AUTHOR(MOD_AUTHOR); +MODULE_DESCRIPTION(MOD_DESC); +MODULE_LICENSE("GPL"); +module_param(debug, int, 0); +MODULE_PARM_DESC(debug, "Debug messages: 0=no, 1=yes (default: no)"); + +static inline void delete_context(struct sasem_context *context) +{ + usb_free_urb(context->tx_urb); /* VFD */ + usb_free_urb(context->rx_urb); /* IR */ + lirc_buffer_free(context->plugin->rbuf); + kfree(context->plugin->rbuf); + kfree(context->plugin); + kfree(context); + + if (debug) + info("%s: context deleted", __FUNCTION__); +} + +static inline void deregister_from_lirc(struct sasem_context *context) +{ + int retval; + int minor = context->plugin->minor; + + retval = lirc_unregister_plugin(minor); + if (retval) + err("%s: unable to deregister from lirc (%d)", + __FUNCTION__, retval); + else + info("Deregistered Sasem plugin (minor:%d)", minor); + +} + +/** + * Called when the VFD device (e.g. /dev/usb/lcd) + * is opened by the application. + */ +static int vfd_open(struct inode *inode, struct file *file) +{ +#ifdef KERNEL_2_5 + struct usb_interface *interface; +#endif + struct sasem_context *context = NULL; + int subminor; + int retval = SUCCESS; + + /* prevent races with disconnect */ + down(&disconnect_sem); + +#ifdef KERNEL_2_5 + subminor = iminor(inode); + interface = usb_find_interface(&sasem_driver, subminor); + if (!interface) { + err("%s: could not find interface for minor %d", + __FUNCTION__, subminor); + retval = -ENODEV; + goto exit; + } + context = usb_get_intfdata(interface); +#else + subminor = MINOR(inode->i_rdev) - VFD_MINOR_BASE; + if (subminor < 0 || subminor >= MAX_DEVICES) { + err("%s: no record of minor %d", __FUNCTION__, subminor); + retval = -ENODEV; + goto exit; + } + context = minor_table [subminor]; +#endif + + if (!context) { + err("%s: no context found for minor %d", + __FUNCTION__, subminor); + retval = -ENODEV; + goto exit; + } + + LOCK_CONTEXT; + + if (context->vfd_isopen) { + err("%s: VFD port is already open", __FUNCTION__); + retval = -EBUSY; + } else { + MOD_INC_USE_COUNT; + context->vfd_isopen = TRUE; + file->private_data = context; + info("VFD port opened"); + } + + UNLOCK_CONTEXT; + +exit: + up(&disconnect_sem); + return retval; +} + +/** + * Called when the VFD device (e.g. /dev/usb/lcd) + * is closed by the application. + */ +static int vfd_ioctl(struct inode *inode, struct file *file, + unsigned cmd, unsigned long arg) +{ + struct sasem_context *context = NULL; + + context = (struct sasem_context *) file->private_data; + + if (!context) { + err("%s: no context for device", __FUNCTION__); + return -ENODEV; + } + + LOCK_CONTEXT; + + switch (cmd) { + case IOCTL_LCD_CONTRAST: + if (arg > 1000) + arg = 1000; + if (arg < 0) + arg = 0; + context->vfd_contrast = (unsigned int)arg; + break; + default: + info("Unknown IOCTL command"); + UNLOCK_CONTEXT; + return -ENOIOCTLCMD; /* not supported */ + } + + UNLOCK_CONTEXT; + return 0; +} + +/** + * Called when the VFD device (e.g. /dev/usb/lcd) + * is closed by the application. + */ +static int vfd_close(struct inode *inode, struct file *file) +{ + struct sasem_context *context = NULL; + int retval = SUCCESS; + + context = (struct sasem_context *) file->private_data; + + if (!context) { + err("%s: no context for device", __FUNCTION__); + return -ENODEV; + } + + LOCK_CONTEXT; + + if (!context->vfd_isopen) { + err("%s: VFD is not open", __FUNCTION__); + retval = -EIO; + } else { + context->vfd_isopen = FALSE; + MOD_DEC_USE_COUNT; + info("VFD port closed"); + if (!context->dev_present && !context->ir_isopen) { + + /* Device disconnected before close and IR port is + * not open. If IR port is open, context will be + * deleted by ir_close. */ + UNLOCK_CONTEXT; + delete_context(context); + return retval; + } + } + + UNLOCK_CONTEXT; + return retval; +} + +/** + * Sends a packet to the VFD. + */ +static inline int send_packet(struct sasem_context *context) +{ + unsigned int pipe; + int interval = 0; + int retval = SUCCESS; + + pipe = usb_sndintpipe(context->dev, + context->tx_endpoint->bEndpointAddress); +#ifdef KERNEL_2_5 + interval = context->tx_endpoint->bInterval; +#endif /* Use 0 for 2.4 kernels */ + + usb_fill_int_urb(context->tx_urb, context->dev, pipe, + context->usb_tx_buf, sizeof(context->usb_tx_buf), + usb_tx_callback, context, interval); + + context->tx_urb->actual_length = 0; + + init_completion(&context->tx.finished); + atomic_set(&(context->tx.busy), 1); + +#ifdef KERNEL_2_5 + retval = usb_submit_urb(context->tx_urb, GFP_KERNEL); +#else + retval = usb_submit_urb(context->tx_urb); +#endif + if (retval != SUCCESS) { + atomic_set(&(context->tx.busy), 0); + err("%s: error submitting urb (%d)", __FUNCTION__, retval); + } else { + /* Wait for tranmission to complete (or abort) */ + UNLOCK_CONTEXT; + wait_for_completion(&context->tx.finished); + LOCK_CONTEXT; + + retval = context->tx.status; + if (retval != SUCCESS) + err("%s: packet tx failed (%d)", __FUNCTION__, retval); + } + + return retval; +} + +/** + * Writes data to the VFD. The Sasem VFD is 2x16 characters + * and requires data in 9 consecutive USB interrupt packets, + * each packet carrying 8 bytes. + */ +static ssize_t vfd_write(struct file *file, const char *buf, + size_t n_bytes, loff_t *pos) +{ + int i; + int retval = SUCCESS; + struct sasem_context *context; + + context = (struct sasem_context *) file->private_data; + if (!context) { + err("%s: no context for device", __FUNCTION__); + return -ENODEV; + } + + LOCK_CONTEXT; + + if (!context->dev_present) { + err("%s: no Sasem device present", __FUNCTION__); + retval = -ENODEV; + goto exit; + } + + if (n_bytes <= 0 || n_bytes > 32) { + err("%s: invalid payload size", __FUNCTION__); + retval = -EINVAL; + goto exit; + } + + copy_from_user(context->tx.data_buf, buf, n_bytes); + + /* Pad with spaces */ + for (i = n_bytes; i < 32; ++i) + context->tx.data_buf [i] = ' '; + + /* Nine 8 byte packets to be sent */ + /* NOTE: "\x07\x01\0\0\0\0\0\0" or "\x0c\0\0\0\0\0\0\0" + * will clear the VFD */ + for (i = 0; i < 9; i++) { + switch (i) { + case 0: + memcpy(context->usb_tx_buf, "\x07\0\0\0\0\0\0\0", 8); + context->usb_tx_buf[1] = (context->vfd_contrast) ? + (0x2B - (context->vfd_contrast - 1) / 250):0x2B; + break; + case 1: + memcpy(context->usb_tx_buf, "\x09\x01\0\0\0\0\0\0", 8); + break; + case 2: + memcpy(context->usb_tx_buf, "\x0b\x01\0\0\0\0\0\0", 8); + break; + case 3: + memcpy(context->usb_tx_buf, context->tx.data_buf, 8); + break; + case 4: + memcpy(context->usb_tx_buf, + context->tx.data_buf + 8, 8); + break; + case 5: + memcpy(context->usb_tx_buf, "\x09\x01\0\0\0\0\0\0", 8); + break; + case 6: + memcpy(context->usb_tx_buf, "\x0b\x02\0\0\0\0\0\0", 8); + break; + case 7: + memcpy(context->usb_tx_buf, + context->tx.data_buf + 16, 8); + break; + case 8: + memcpy(context->usb_tx_buf, + context->tx.data_buf + 24, 8); + break; + } + retval = send_packet(context); + if (retval != SUCCESS) { + + err("%s: send packet failed for packet #%d", + __FUNCTION__, i); + goto exit; + } + } +exit: + + UNLOCK_CONTEXT; + + return (retval == SUCCESS) ? n_bytes : retval; +} + +/** + * Callback function for USB core API: transmit data + */ +#if defined(KERNEL_2_5) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void usb_tx_callback(struct urb *urb, struct pt_regs *regs) +#else +static void usb_tx_callback(struct urb *urb) +#endif +{ + struct sasem_context *context; + + if (!urb) + return; + context = (struct sasem_context *) urb->context; + if (!context) + return; + + context->tx.status = urb->status; + + /* notify waiters that write has finished */ + atomic_set(&context->tx.busy, 0); + complete(&context->tx.finished); + + return; +} + +/** + * Called by lirc_dev when the application opens /dev/lirc + */ +static int ir_open(void *data) +{ + int retval = SUCCESS; + struct sasem_context *context; + + /* prevent races with disconnect */ + down(&disconnect_sem); + + context = (struct sasem_context *) data; + + LOCK_CONTEXT; + + if (context->ir_isopen) { + err("%s: IR port is already open", __FUNCTION__); + retval = -EBUSY; + goto exit; + } + + usb_fill_int_urb(context->rx_urb, context->dev, + usb_rcvintpipe(context->dev, + context->rx_endpoint->bEndpointAddress), + context->usb_rx_buf, sizeof(context->usb_rx_buf), + usb_rx_callback, context, context->rx_endpoint->bInterval); + +#ifdef KERNEL_2_5 + retval = usb_submit_urb(context->rx_urb, GFP_KERNEL); +#else + retval = usb_submit_urb(context->rx_urb); +#endif + + if (retval) + err("%s: usb_submit_urb failed for ir_open (%d)", + __FUNCTION__, retval); + else { + MOD_INC_USE_COUNT; + context->ir_isopen = TRUE; + info("IR port opened"); + } + +exit: + UNLOCK_CONTEXT; + + up(&disconnect_sem); + return SUCCESS; +} + +/** + * Called by lirc_dev when the application closes /dev/lirc + */ +static void ir_close(void *data) +{ + struct sasem_context *context; + + context = (struct sasem_context *)data; + if (!context) { + err("%s: no context for device", __FUNCTION__); + return; + } + + LOCK_CONTEXT; + + usb_kill_urb(context->rx_urb); + context->ir_isopen = FALSE; + MOD_DEC_USE_COUNT; + info("IR port closed"); + + if (!context->dev_present) { + + /* + * Device disconnected while IR port was + * still open. Plugin was not deregistered + * at disconnect time, so do it now. + */ + deregister_from_lirc(context); + + if (!context->vfd_isopen) { + + UNLOCK_CONTEXT; + delete_context(context); + return; + } + /* If VFD port is open, context will be deleted by vfd_close */ + } + + UNLOCK_CONTEXT; + return; +} + +/** + * Process the incoming packet + */ +static inline void incoming_packet(struct sasem_context *context, + struct urb *urb) +{ + int len = urb->actual_length; + unsigned char *buf = urb->transfer_buffer; + long ms; + struct timeval tv; + + if (len != 8) { + warn("%s: invalid incoming packet size (%d)", + __FUNCTION__, len); + return; + } + +#ifdef DEBUG + int i; + for (i = 0; i < 8; ++i) + printk(KERN_INFO "%02x ", buf [i]); + printk(KERN_INFO "\n"); +#endif + + /* Lirc could deal with the repeat code, but we really need to block it + * if it arrives too late. Otherwise we could repeat the wrong code. */ + + /* get the time since the last button press */ + do_gettimeofday(&tv); + ms = (tv.tv_sec - context->presstime.tv_sec) * 1000 + + (tv.tv_usec - context->presstime.tv_usec) / 1000; + + if (memcmp(buf, "\x08\0\0\0\0\0\0\0", 8) == 0) { + /* the repeat code is being sent, so we copy + * the old code to LIRC */ + + /* NOTE: Only if the last code was less than 250ms ago + * - no one should be able to push another (undetected) button + * in that time and then get a false repeat of the previous + * press but it is long enough for a genuine repeat */ + if ((ms < 250) && (context->codesaved != 0)) { + memcpy(buf, &context->lastcode, 8); + context->presstime.tv_sec = tv.tv_sec; + context->presstime.tv_usec = tv.tv_usec; + } + } else { + /* save the current valid code for repeats */ + memcpy(&context->lastcode, buf, 8); + /* set flag to signal a valid code was save; + * just for safety reasons */ + context->codesaved = 1; + context->presstime.tv_sec = tv.tv_sec; + context->presstime.tv_usec = tv.tv_usec; + } + + lirc_buffer_write_1(context->plugin->rbuf, buf); + wake_up(&context->plugin->rbuf->wait_poll); +} + +/** + * Callback function for USB core API: receive data + */ +#if defined(KERNEL_2_5) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void usb_rx_callback(struct urb *urb, struct pt_regs *regs) +#else +static void usb_rx_callback(struct urb *urb) +#endif +{ + struct sasem_context *context; + + if (!urb) + return; + context = (struct sasem_context *) urb->context; + if (!context) + return; + + switch (urb->status) { + + case -ENOENT: /* usbcore unlink successful! */ + return; + + case SUCCESS: + if (context->ir_isopen) + incoming_packet(context, urb); + break; + + default: + warn("%s: status (%d): ignored", + __FUNCTION__, urb->status); + break; + } + +#ifdef KERNEL_2_5 + usb_submit_urb(context->rx_urb, GFP_ATOMIC); +#endif + return; +} + + + +/** + * Callback function for USB core API: Probe + */ +#ifdef KERNEL_2_5 +static int sasem_probe(struct usb_interface *interface, + const struct usb_device_id *id) +#else +static void *sasem_probe(struct usb_device *dev, unsigned int intf, + const struct usb_device_id *id) +#endif +{ +#ifdef KERNEL_2_5 + struct usb_device *dev = NULL; + struct usb_host_interface *iface_desc = NULL; +#else + struct usb_interface *interface = NULL; + struct usb_interface_descriptor *iface_desc = NULL; + char name [10]; + int subminor = 0; +#endif + struct usb_endpoint_descriptor *rx_endpoint = NULL; + struct usb_endpoint_descriptor *tx_endpoint = NULL; + struct urb *rx_urb = NULL; + struct urb *tx_urb = NULL; + struct lirc_plugin *plugin = NULL; + struct lirc_buffer *rbuf = NULL; + int lirc_minor = 0; + int num_endpoints; + int retval = SUCCESS; + int vfd_ep_found; + int ir_ep_found; + int alloc_status; + struct sasem_context *context = NULL; + int i; + + info("%s: found Sasem device", __FUNCTION__); + +#if !defined(KERNEL_2_5) + for (subminor = 0; subminor < MAX_DEVICES; ++subminor) { + if (minor_table [subminor] == NULL) + break; + } + if (subminor == MAX_DEVICES) { + err("%s: allowed number of devices already present", + __FUNCTION__); + retval = -ENOMEM; + goto exit; + } +#endif + +#ifdef KERNEL_2_5 + dev = usb_get_dev(interface_to_usbdev(interface)); + iface_desc = interface->cur_altsetting; + num_endpoints = iface_desc->desc.bNumEndpoints; +#else + interface = &dev->actconfig->interface [intf]; + iface_desc = &interface->altsetting [interface->act_altsetting]; + num_endpoints = iface_desc->bNumEndpoints; +#endif + + /* + * Scan the endpoint list and set: + * first input endpoint = IR endpoint + * first output endpoint = VFD endpoint + */ + + ir_ep_found = FALSE; + vfd_ep_found = FALSE; + + for (i = 0; i < num_endpoints && !(ir_ep_found && vfd_ep_found); ++i) { + + struct usb_endpoint_descriptor *ep; + int ep_dir; + int ep_type; +#ifdef KERNEL_2_5 + ep = &iface_desc->endpoint [i].desc; +#else + ep = &iface_desc->endpoint [i]; +#endif + ep_dir = ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK; + ep_type = ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; + + if (!ir_ep_found && + ep_dir == USB_DIR_IN && + ep_type == USB_ENDPOINT_XFER_INT) { + + rx_endpoint = ep; + ir_ep_found = TRUE; + if (debug) + info("%s: found IR endpoint", __FUNCTION__); + + } else if (!vfd_ep_found && + ep_dir == USB_DIR_OUT && + ep_type == USB_ENDPOINT_XFER_INT) { + + tx_endpoint = ep; + vfd_ep_found = TRUE; + if (debug) + info("%s: found VFD endpoint", __FUNCTION__); + } + } + + /* Input endpoint is mandatory */ + if (!ir_ep_found) { + + err("%s: no valid input (IR) endpoint found.", __FUNCTION__); + retval = -ENODEV; + goto exit; + } + + /* Warning if no VFD endpoint */ + if (!vfd_ep_found) + info("%s: no valid output (VFD) endpoint found.", __FUNCTION__); + + + /* Allocate memory */ + alloc_status = SUCCESS; + + context = kmalloc(sizeof(struct sasem_context), GFP_KERNEL); + if (!context) { + err("%s: kmalloc failed for context", __FUNCTION__); + alloc_status = 1; + goto alloc_status_switch; + } + plugin = kmalloc(sizeof(struct lirc_plugin), GFP_KERNEL); + if (!plugin) { + err("%s: kmalloc failed for lirc_plugin", __FUNCTION__); + alloc_status = 2; + goto alloc_status_switch; + } + rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); + if (!rbuf) { + err("%s: kmalloc failed for lirc_buffer", __FUNCTION__); + alloc_status = 3; + goto alloc_status_switch; + } + if (lirc_buffer_init(rbuf, BUF_CHUNK_SIZE, BUF_SIZE)) { + err("%s: lirc_buffer_init failed", __FUNCTION__); + alloc_status = 4; + goto alloc_status_switch; + } +#ifdef KERNEL_2_5 + rx_urb = usb_alloc_urb(0, GFP_KERNEL); +#else + rx_urb = usb_alloc_urb(0); +#endif + if (!rx_urb) { + err("%s: usb_alloc_urb failed for IR urb", __FUNCTION__); + alloc_status = 5; + goto alloc_status_switch; + } + if (vfd_ep_found) { +#ifdef KERNEL_2_5 + tx_urb = usb_alloc_urb(0, GFP_KERNEL); +#else + tx_urb = usb_alloc_urb(0); +#endif + if (!tx_urb) { + err("%s: usb_alloc_urb failed for VFD urb", + __FUNCTION__); + alloc_status = 6; + goto alloc_status_switch; + } + } + + /* clear all members of sasem_context and lirc_plugin */ + memset(context, 0, sizeof(struct sasem_context)); + init_MUTEX(&context->sem); + + memset(plugin, 0, sizeof(struct lirc_plugin)); + + strcpy(plugin->name, MOD_NAME); + plugin->minor = -1; + plugin->code_length = 64; + plugin->sample_rate = 0; + plugin->features = LIRC_CAN_REC_LIRCCODE; + plugin->data = context; + plugin->rbuf = rbuf; + plugin->set_use_inc = ir_open; + plugin->set_use_dec = ir_close; +#ifdef LIRC_HAVE_SYSFS + plugin->dev = &dev->dev; +#endif + plugin->owner = THIS_MODULE; + + LOCK_CONTEXT; + + lirc_minor = lirc_register_plugin(plugin); + if (lirc_minor < 0) { + err("%s: lirc_register_plugin failed", __FUNCTION__); + alloc_status = 7; + UNLOCK_CONTEXT; + } else + info("%s: Registered Sasem plugin (minor:%d)", + __FUNCTION__, lirc_minor); + +alloc_status_switch: + + switch (alloc_status) { + + case 7: + if (vfd_ep_found) + usb_free_urb(tx_urb); + case 6: + usb_free_urb(rx_urb); + case 5: + lirc_buffer_free(rbuf); + case 4: + kfree(rbuf); + case 3: + kfree(plugin); + case 2: + kfree(context); + context = NULL; + case 1: + retval = -ENOMEM; + goto exit; + } + + /* Needed while unregistering! */ + plugin->minor = lirc_minor; + + context->dev = dev; + context->dev_present = TRUE; + context->rx_endpoint = rx_endpoint; + context->rx_urb = rx_urb; + if (vfd_ep_found) { + context->tx_endpoint = tx_endpoint; + context->tx_urb = tx_urb; + context->vfd_contrast = 1000; /* range 0 - 1000 */ + } + context->plugin = plugin; + +#ifdef KERNEL_2_5 + usb_set_intfdata(interface, context); +#else + minor_table [subminor] = context; + context->subminor = subminor; +#endif + + if (vfd_ep_found) { + + if (debug) + info("Registering VFD with devfs"); +#ifdef KERNEL_2_5 + if (usb_register_dev(interface, &sasem_class)) + /* Not a fatal error, so ignore */ + info("%s: could not get a minor number for VFD", + __FUNCTION__); +#else + sprintf(name, DEVFS_NAME, subminor); + context->devfs = devfs_register(usb_devfs_handle, name, + DEVFS_FL_DEFAULT, + USB_MAJOR, VFD_MINOR_BASE + subminor, + DEVFS_MODE, &vfd_fops, NULL); + if (!context->devfs) + /* not a fatal error so ignore */ + info("%s: devfs register failed for VFD", + __FUNCTION__); +#endif + } + + info("%s: Sasem device on usb<%d:%d> initialized", + __FUNCTION__, dev->bus->busnum, dev->devnum); + + UNLOCK_CONTEXT; +exit: +#ifdef KERNEL_2_5 + return retval; +#else + return (retval == SUCCESS) ? context : NULL; +#endif +} + +/** + * Callback function for USB core API: disonnect + */ +#ifdef KERNEL_2_5 +static void sasem_disconnect(struct usb_interface *interface) +#else +static void sasem_disconnect(struct usb_device *dev, void *data) +#endif +{ + struct sasem_context *context; + + /* prevent races with ir_open()/vfd_open() */ + down(&disconnect_sem); + +#ifdef KERNEL_2_5 + context = usb_get_intfdata(interface); +#else + context = (struct sasem_context *)data; +#endif + LOCK_CONTEXT; + + info("%s: Sasem device disconnected", __FUNCTION__); + +#ifdef KERNEL_2_5 + usb_set_intfdata(interface, NULL); +#else + minor_table [context->subminor] = NULL; +#endif + context->dev_present = FALSE; + + /* Stop reception */ + usb_kill_urb(context->rx_urb); + + /* Abort ongoing write */ + if (atomic_read(&context->tx.busy)) { + + usb_kill_urb(context->tx_urb); + wait_for_completion(&context->tx.finished); + } + + /* De-register from lirc_dev if IR port is not open */ + if (!context->ir_isopen) + deregister_from_lirc(context); + +#ifdef KERNEL_2_5 + usb_deregister_dev(interface, &sasem_class); +#else + if (context->devfs) + devfs_unregister(context->devfs); +#endif + + UNLOCK_CONTEXT; + + if (!context->ir_isopen && !context->vfd_isopen) + delete_context(context); + + up(&disconnect_sem); +} + +static int __init sasem_init(void) +{ + int rc; + + info(MOD_DESC ", v" MOD_VERSION); + info(MOD_AUTHOR); + + rc = usb_register(&sasem_driver); + if (rc < 0) { + err("%s: usb register failed (%d)", __FUNCTION__, rc); + return -ENODEV; + } + return SUCCESS; +} + +static void __exit sasem_exit(void) +{ + usb_deregister(&sasem_driver); + info("module removed. Goodbye!"); +} + + +module_init(sasem_init); +module_exit(sasem_exit); + +#if !defined(KERNEL_2_5) +EXPORT_NO_SYMBOLS; +#endif --- linux-2.6.28.orig/ubuntu/lirc/lirc_pvr150/lirc_pvr150.c +++ linux-2.6.28/ubuntu/lirc/lirc_pvr150/lirc_pvr150.c @@ -0,0 +1,1481 @@ +/* $Id: $ */ + +/* + * i2c IR lirc plugin for Hauppauge PVR 150 card + * + * Copyright (c) 2000 Gerd Knorr + * modified for PixelView (BT878P+W/FM) by + * Michal Kochanowicz + * Christoph Bartelmus + * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by + * Ulrich Mueller + * modified for Asus TV-Box and Creative/VisionTek BreakOut-Box by + * Stefan Jahn + * modified for inclusion into kernel sources by + * Jerome Brock + * modified for Leadtek Winfast PVR2000 by + * Thomas Reitmayr (treitmayr@yahoo.com) + * modified for Hauppauge PVR-150 IR TX device by + * Mark Weaver + * + * parts are cut&pasted from the lirc_pvr150.c driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "kcompat.h" +#include "lirc_dev/lirc_dev.h" +#include "lirc.h" + +/* We need to be able to reset the crappy IR chip by talking to the ivtv driver */ +struct ivtv; +void ivtv_reset_ir_gpio(struct ivtv *itv); + +struct IR +{ + struct lirc_plugin l; + + /* Device info */ + struct semaphore lock; + int open; + + /* RX device */ + struct i2c_client c_rx; + + /* RX device buffer & lock */ + struct lirc_buffer buf; + struct semaphore buf_sem; + + /* RX polling thread data */ + struct completion *t_notify; + struct completion *t_notify2; + int shutdown; + int tpid; + + /* RX read data */ + unsigned char b[3]; + + /* TX device */ + struct i2c_client c_tx; + int need_boot; + + /* # devices, for shutdown */ + int devs; +}; + +/* Minor -> data mapping */ +static struct IR *ir_devices[MAX_IRCTL_DEVICES]; + +/* Block size for haup PVR-150 IR transmitter */ +#define TX_BLOCK_SIZE 99 + +/* Hauppuage IR transmitter data */ +typedef struct TX_DATA_s +{ + /* Boot block */ + unsigned char *boot_data; + + /* Start of binary data block */ + unsigned char *datap; + + /* End of binary data block */ + unsigned char *endp; + + /* Number of installed codesets */ + unsigned int num_code_sets; + + /* Pointers to codesets */ + unsigned char **code_sets; + + /* Global fixed data template */ + int fixed[TX_BLOCK_SIZE]; +} TX_DATA; + +static TX_DATA *tx_data; +struct semaphore tx_data_lock; + +/* ----------------------------------------------------------------------- */ + +#define DEVICE_NAME "lirc_pvr150" + +/* ----------------------------------------------------------------------- */ +/* insmod parameters */ + +static int debug = 0; /* debug output */ +static int disable_rx = 0; /* disable RX device */ +static int disable_tx = 0; /* disable TX device */ +static int minor = -1; /* minor number */ + +#define dprintk(fmt, args...) \ + do{ \ + if(debug) printk(KERN_DEBUG DEVICE_NAME ": " fmt, \ + ## args); \ + }while(0) + +/* ----------------------------------------------------------------------- */ + +static int add_to_buf(struct IR *ir) +{ + __u16 code; + unsigned char codes[2]; + unsigned char keybuf[6]; + int got_data = 0; + int ret; + int failures = 0; + unsigned char sendbuf[1] = { 0 }; + + if (lirc_buffer_full(&ir->buf)) { + dprintk("buffer overflow\n"); + return -EOVERFLOW; + } + + /* service the device as long as it is returning + * data and we have space + */ + do + { + /* Lock i2c bus for the duration. RX/TX chips interfere so + this is worth it + */ + down(&ir->lock); + + /* Send random "poll command" (?) Windows driver does this + and it is a good point to detect chip failure. + */ + ret = i2c_master_send(&ir->c_rx, sendbuf, 1); + if (ret != 1) + { + printk(KERN_ERR + "lirc_pvr150: i2c_master_send failed with %d\n", + ret); + if (failures >= 3) { + up(&ir->lock); + printk(KERN_ERR "lirc_pvr150: unable to read " + "from the IR chip after 3 " + "resets, giving up\n"); + return ret; + } + + /* Looks like the chip crashed, reset it */ + printk(KERN_ERR "lirc_pvr150: polling the IR receiver " + "chip failed, trying reset\n"); + + ivtv_reset_ir_gpio(i2c_get_adapdata(ir->c_rx.adapter)); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((100 * HZ + 999) / 1000); + ir->need_boot = 1; + + ++failures; + up(&ir->lock); + continue; + } + + ret = i2c_master_recv(&ir->c_rx, keybuf, sizeof(keybuf)); + up(&ir->lock); + if (ret != sizeof(keybuf)) + { + printk(KERN_ERR + "lirc_pvr150: i2c_master_recv failed with %d" + " -- keeping last read buffer\n", ret); + } + else + { + ir->b[0] = keybuf[3]; + ir->b[1] = keybuf[4]; + ir->b[2] = keybuf[5]; + dprintk("key (0x%02x/0x%02x)\n", ir->b[0], ir->b[1]); + } + + /* key pressed ? */ + if ((ir->b[0] & 0x80) == 0) + return got_data ? 0 : -ENODATA; + + /* look what we have */ + code = (((__u16)ir->b[0]&0x7f)<<6) | (ir->b[1]>>2); + + codes[0] = (code >> 8) & 0xff; + codes[1] = code & 0xff; + + /* return it */ + lirc_buffer_write_1( &ir->buf, codes ); + ++got_data; + } while (!lirc_buffer_full(&ir->buf)); + return 0; +} + +/* Main function of the polling thread -- from lirc_dev. + * We don't fit the LIRC model at all anymore. This is horrible, but + * basically we have a single RX/TX device with a nasty failure mode + * that needs to be accounted for across the pair. lirc lets us provide + * fops, but prevents us from using the internal polling, etc. if we do + * so. Hence the replication. Might be neater to extend the LIRC model + * to account for this but I'd think it's a very special case of seriously + * messed up hardware. + */ +static int lirc_thread(void *arg) +{ + struct IR *ir = arg; + + /* This thread doesn't need any user-level access, + * so get rid of all our resources + */ + daemonize("lirc_pvr150"); + + if (ir->t_notify != NULL) { + complete(ir->t_notify); + } + + dprintk("poll thread started\n"); + + do { + if (ir->open) { + set_current_state(TASK_INTERRUPTIBLE); + + /* This is ~113*2 + 24 + jitter (2*repeat gap + + code length). We use this interval as the chip + resets every time you poll it (bad!). This is + therefore just sufficient to catch all of the + button presses. It makes the remote much more + responsive. You can see the difference by + running irw and holding down a button. With + 100ms, the old polling interval, you'll notice + breaks in the repeat sequence corresponding to + lost keypresses. + */ + schedule_timeout((260 * HZ) / 1000); + if (ir->shutdown) { + break; + } + if (!add_to_buf(ir)) { + wake_up_interruptible(&ir->buf.wait_poll); + } + } else { + /* if device not opened so we can sleep half a second */ + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ/2); + } + } while (!ir->shutdown); + + if (ir->t_notify2 != NULL) { + wait_for_completion(ir->t_notify2); + } + + ir->tpid = -1; + if (ir->t_notify != NULL) { + complete(ir->t_notify); + } + + dprintk("poll thread ended\n"); + return 0; +} + +static int set_use_inc(void* data) +{ + struct IR *ir = data; + + if (ir->l.owner == NULL || try_module_get(ir->l.owner) == 0) { + return -ENODEV; + } + + /* lock bttv in memory while /dev/lirc is in use */ + /* this is completely broken code. lirc_unregister_plugin() + must be possible even when the device is open */ + if (ir->c_rx.addr) i2c_use_client(&ir->c_rx); + if (ir->c_tx.addr) i2c_use_client(&ir->c_tx); + MOD_INC_USE_COUNT; + + return 0; +} + +static void set_use_dec(void* data) +{ + struct IR *ir = data; + + if (ir->c_rx.addr) i2c_release_client(&ir->c_rx); + if (ir->c_tx.addr) i2c_release_client(&ir->c_tx); + MOD_DEC_USE_COUNT; + if (ir->l.owner != NULL) + module_put(ir->l.owner); +} + +/* safe read of a uint32 (always network byte order) */ +static __inline int read_uint32(unsigned char **data, + unsigned char *endp, unsigned int *val) +{ + if (*data + 4 > endp) + return 0; + *val = ((*data)[0] << 24) | ((*data)[1] << 16) | + ((*data)[2] << 8) | (*data)[3]; + *data += 4; + return 1; +} + +/* safe read of a uint8 */ +static __inline int read_uint8(unsigned char **data, + unsigned char *endp, unsigned char *val) +{ + if (*data + 1 > endp) + return 0; + *val = *((*data)++); + return 1; +} + +/* safe skipping of N bytes */ +static __inline int skip(unsigned char **data, + unsigned char *endp, unsigned int distance) +{ + if (*data + distance > endp) + return 0; + *data += distance; + return 1; +} + +/* decompress key data into the given buffer */ +static int get_key_data(unsigned char *buf, + unsigned int codeset, unsigned int key) +{ + unsigned char *data, *endp, *diffs, *key_block; + unsigned char keys, ndiffs, id; + unsigned int base, lim, pos, i; + + /* Binary search for the codeset */ + for (base = 0, lim = tx_data->num_code_sets; lim; lim >>= 1) { + pos = base + (lim >> 1); + data = tx_data->code_sets[pos]; + + if (!read_uint32(&data, tx_data->endp, &i)) + goto corrupt; + + if (i == codeset) + break; + else if (codeset > i) { + base = pos + 1; + --lim; + } + } + /* Not found? */ + if (!lim) + return -EPROTO; + + /* Set end of data block */ + endp = pos < tx_data->num_code_sets - 1 ? + tx_data->code_sets[pos + 1] : tx_data->endp; + + /* Read the block header */ + if (!read_uint8(&data, endp, &keys) || + !read_uint8(&data, endp, &ndiffs) || + ndiffs > TX_BLOCK_SIZE || keys == 0) + goto corrupt; + + /* Save diffs & skip */ + diffs = data; + if (!skip(&data, endp, ndiffs)) + goto corrupt; + + /* Read the id of the first key */ + if (!read_uint8(&data, endp, &id)) + goto corrupt; + + /* Unpack the first key's data */ + for (i = 0; i < TX_BLOCK_SIZE; ++i) + { + if (tx_data->fixed[i] == -1) + { + if (!read_uint8(&data, endp, &buf[i])) + goto corrupt; + } + else + { + buf[i] = (unsigned char)tx_data->fixed[i]; + } + } + + /* Early out key found/not found */ + if (key == id) + return 0; + if (keys == 1) + return -EPROTO; + + /* Sanity check */ + key_block = data; + if (!skip(&data, endp, (keys - 1) * (ndiffs + 1))) + goto corrupt; + + /* Binary search for the key */ + for (base = 0, lim = keys - 1; lim; lim >>= 1) { + /* Seek to block */ + unsigned char *key_data; + pos = base + (lim >> 1); + key_data = key_block + (ndiffs + 1) * pos; + + if (*key_data == key) { + /* skip key id */ + ++key_data; + + /* found, so unpack the diffs */ + for (i = 0; i < ndiffs; ++i) { + unsigned char val; + if (!read_uint8(&key_data, endp, &val) || + diffs[i] >= TX_BLOCK_SIZE) + goto corrupt; + buf[diffs[i]] = val; + } + + return 0; + } else if (key > *key_data) { + base = pos + 1; + --lim; + } + } + /* Key not found */ + return -EPROTO; + +corrupt: + printk(KERN_ERR "lirc_pvr150: firmware is corrupt\n"); + return -EFAULT; +} + +/* send a block of data to the IR TX device of the PVR-150 */ +static int send_data_block(struct IR *ir, unsigned char *data_block) +{ + int i, j, ret; + unsigned char buf[5]; + + for (i = 0; i < TX_BLOCK_SIZE; ) + { + int tosend = TX_BLOCK_SIZE - i; + if (tosend > 4) + tosend = 4; + buf[0] = (unsigned char)(i + 1); + for (j = 0; j < tosend; ++j) + buf[1 + j] = data_block[i + j]; + dprintk("%02x %02x %02x %02x %02x", + buf[0],buf[1],buf[2],buf[3],buf[4]); + ret = i2c_master_send(&ir->c_tx, buf, tosend + 1); + if (ret != tosend + 1) { + printk(KERN_ERR + "lirc_pvr150: i2c_master_send failed with %d\n", + ret); + return ret < 0 ? ret : -EFAULT; + } + i += tosend; + } + return 0; +} + +/* send boot data to the IR TX device of the PVR-150 */ +static int send_boot_data(struct IR *ir) +{ + int ret; + unsigned char buf[4]; + + /* send the boot block */ + ret = send_data_block(ir, tx_data->boot_data); + if (ret != 0) + return ret; + + /* kick it off? */ + buf[0] = 0x00; + buf[1] = 0x20; + ret = i2c_master_send(&ir->c_tx, buf, 2); + if (ret != 2) { + printk(KERN_ERR + "lirc_pvr150: i2c_master_send failed with %d\n", ret); + return ret < 0 ? ret : -EFAULT; + } + ret = i2c_master_send(&ir->c_tx, buf, 1); + if (ret != 1) { + printk(KERN_ERR + "lirc_pvr150: i2c_master_send failed with %d\n", ret); + return ret < 0 ? ret : -EFAULT; + } + + /* Here comes the firmware version... (hopefully) */ + ret = i2c_master_recv(&ir->c_tx, buf, 4); + if (ret != 4) { + printk(KERN_ERR + "lirc_pvr150: i2c_master_recv failed with %d\n", ret); + return 0; + } + if (buf[0] != 0x80) { + printk(KERN_ERR + "lirc_pvr150: unexpected IR TX response: %02x\n", + buf[0]); + return 0; + } + printk(KERN_INFO + "lirc_pvr150: Hauppauge PVR-150 IR blaster: " + "firmware version %d.%d.%d\n", + buf[1], buf[2], buf[3]); + + return 0; +} + +/* unload "firmware", lock held */ +static void fw_unload_locked(void) +{ + if (tx_data) { + if (tx_data->code_sets) + vfree(tx_data->code_sets); + + if (tx_data->datap) + vfree(tx_data->datap); + + vfree(tx_data); + tx_data = NULL; + dprintk("successfully unloaded PVR-150 IR " + "blaster firmware\n"); + } +} + +/* unload "firmware" for the IR TX device of the PVR-150 */ +static void fw_unload(void) +{ + down(&tx_data_lock); + fw_unload_locked(); + up(&tx_data_lock); +} + +/* load "firmware" for the IR TX device of the PVR-150 */ +static int fw_load(struct IR *ir) +{ + int ret; + unsigned int i; + unsigned char *data, version, num_global_fixed; + const struct firmware *fw_entry = NULL; + + /* Already loaded? */ + down(&tx_data_lock); + if (tx_data) { + ret = 0; + goto out; + } + + /* Request codeset data file */ + ret = request_firmware(&fw_entry, "haup-ir-blaster.bin", &ir->c_tx.dev); + if (ret != 0) { + printk(KERN_ERR + "lirc_pvr150: firmware haup-ir-blaster.bin " + "not available (%d)\n", ret); + ret = ret < 0 ? ret : -EFAULT; + goto out; + } + printk(KERN_INFO + "lirc_pvr150: firmware of size %zd loaded\n", fw_entry->size); + + /* Parse the file */ + tx_data = vmalloc(sizeof(TX_DATA)); + if (tx_data == NULL) { + printk(KERN_ERR + "lirc_pvr150: out of memory\n"); + release_firmware(fw_entry); + ret = -ENOMEM; + goto out; + } + tx_data->code_sets = NULL; + + /* Copy the data so hotplug doesn't get confused and timeout */ + tx_data->datap = vmalloc(fw_entry->size); + if (tx_data->datap == NULL) { + printk(KERN_ERR + "lirc_pvr150: out of memory\n"); + release_firmware(fw_entry); + vfree(tx_data); + ret = -ENOMEM; + goto out; + } + memcpy(tx_data->datap, fw_entry->data, fw_entry->size); + tx_data->endp = tx_data->datap + fw_entry->size; + release_firmware(fw_entry); fw_entry = NULL; + + /* Check version */ + data = tx_data->datap; + if (!read_uint8(&data, tx_data->endp, &version)) + goto corrupt; + if (version != 1) { + printk(KERN_ERR + "lirc_pvr150: unsupported code set file version (%u, " + "expected 1) -- please upgrade to a newer driver", + version); + fw_unload_locked(); + ret = -EFAULT; + goto out; + } + + /* Save boot block for later */ + tx_data->boot_data = data; + if (!skip(&data, tx_data->endp, TX_BLOCK_SIZE)) + goto corrupt; + + if (!read_uint32(&data, tx_data->endp, + &tx_data->num_code_sets)) + goto corrupt; + + printk(KERN_INFO + "lirc_pvr150: %u codesets loaded\n", tx_data->num_code_sets); + + tx_data->code_sets = vmalloc( + tx_data->num_code_sets * sizeof(char *)); + if (tx_data->code_sets == NULL) { + fw_unload_locked(); + ret = -ENOMEM; + goto out; + } + + for (i = 0; i < TX_BLOCK_SIZE; ++i) + tx_data->fixed[i] = -1; + + /* Read global fixed data template */ + if (!read_uint8(&data, tx_data->endp, &num_global_fixed) || + num_global_fixed > TX_BLOCK_SIZE) + goto corrupt; + for (i = 0; i < num_global_fixed; ++i) { + unsigned char pos, val; + if (!read_uint8(&data, tx_data->endp, &pos) || + !read_uint8(&data, tx_data->endp, &val) || + pos >= TX_BLOCK_SIZE) { + goto corrupt; + } + tx_data->fixed[pos] = (int)val; + } + + /* Filch out the position of each code set */ + for (i = 0; i < tx_data->num_code_sets; ++i) { + unsigned int id; + unsigned char keys; + unsigned char ndiffs; + + /* Save the codeset position */ + tx_data->code_sets[i] = data; + + /* Read header */ + if (!read_uint32(&data, tx_data->endp, &id) || + !read_uint8(&data, tx_data->endp, &keys) || + !read_uint8(&data, tx_data->endp, &ndiffs) || + ndiffs > TX_BLOCK_SIZE || keys == 0) + goto corrupt; + + /* skip diff positions */ + if (!skip(&data, tx_data->endp, ndiffs)) + goto corrupt; + + /* After the diffs we have the first key id + data - + global fixed */ + if (!skip(&data, tx_data->endp, + 1 + TX_BLOCK_SIZE - num_global_fixed)) + goto corrupt; + + /* Then we have keys-1 blocks of key id+diffs */ + if (!skip(&data, tx_data->endp, + (ndiffs + 1) * (keys - 1))) + goto corrupt; + } + ret = 0; + goto out; + +corrupt: + printk(KERN_ERR "lirc_pvr150: firmware is corrupt\n"); + fw_unload_locked(); + ret = -EFAULT; + +out: + up(&tx_data_lock); + return ret; +} + +/* initialise the IR TX device of the PVR-150 */ +static int tx_init(struct IR *ir) +{ + int ret; + + /* Load 'firmware' */ + ret = fw_load(ir); + if (ret != 0) + return ret; + + /* Send boot block */ + ret = send_boot_data(ir); + if (ret != 0) + return ret; + ir->need_boot = 0; + + /* Looks good */ + return 0; +} + +/* do nothing stub to make LIRC happy */ +static loff_t lseek(struct file *filep,loff_t offset,int orig) +{ + return(-ESPIPE); +} + +/* copied from lirc_dev */ +static ssize_t read(struct file *filep,char *outbuf,size_t n,loff_t *ppos) +{ + struct IR *ir = (struct IR *)filep->private_data; + unsigned char buf[ir->buf.chunk_size]; + int ret=0, written=0; + DECLARE_WAITQUEUE(wait, current); + + dprintk("read called\n"); + if (ir->c_rx.addr == 0) + return -ENODEV; + + if (down_interruptible(&ir->buf_sem)) + return -ERESTARTSYS; + + if (n % ir->buf.chunk_size) { + dprintk("read result = -EINVAL\n"); + up(&ir->buf_sem); + return -EINVAL; + } + + /* we add ourselves to the task queue before buffer check + * to avoid losing scan code (in case when queue is awaken somewhere + * beetwen while condition checking and scheduling) + */ + add_wait_queue(&ir->buf.wait_poll, &wait); + set_current_state(TASK_INTERRUPTIBLE); + + /* while we did't provide 'length' bytes, device is opened in blocking + * mode and 'copy_to_user' is happy, wait for data. + */ + while (written < n && ret == 0) { + if (lirc_buffer_empty(&ir->buf)) { + /* According to the read(2) man page, 'written' can be + * returned as less than 'n', instead of blocking + * again, returning -EWOULDBLOCK, or returning + * -ERESTARTSYS */ + if (written) break; + if (filep->f_flags & O_NONBLOCK) { + ret = -EWOULDBLOCK; + break; + } + if (signal_pending(current)) { + ret = -ERESTARTSYS; + break; + } + schedule(); + set_current_state(TASK_INTERRUPTIBLE); + } else { + lirc_buffer_read_1(&ir->buf, buf); + ret = copy_to_user((void *)outbuf+written, buf, + ir->buf.chunk_size); + written += ir->buf.chunk_size; + } + } + + remove_wait_queue(&ir->buf.wait_poll, &wait); + set_current_state(TASK_RUNNING); + up(&ir->buf_sem); + + dprintk("read result = %s (%d)\n", + ret ? "-EFAULT" : "OK", ret); + + return ret ? ret : written; +} + +/* send a keypress to the IR TX device of the PVR-150 */ +static int send_code(struct IR *ir, unsigned int code, unsigned int key) +{ + unsigned char data_block[TX_BLOCK_SIZE]; + unsigned char buf[2]; + int i, ret; + + /* Get data for the codeset/key */ + ret = get_key_data(data_block, code, key); + + if (ret == -EPROTO) { + printk(KERN_ERR + "lirc_pvr150: failed to get data for code %u, " + "key %u -- check lircd.conf entries\n", + code, key); + return ret; + } else if (ret != 0) + return ret; + + /* Send the data block */ + ret = send_data_block(ir, data_block); + if (ret != 0) + return ret; + + /* Send data block length? */ + buf[0] = 0x00; + buf[1] = 0x40; + ret = i2c_master_send(&ir->c_tx, buf, 2); + if (ret != 2) { + printk(KERN_ERR + "lirc_pvr150: i2c_master_send failed with %d\n", ret); + return ret < 0 ? ret : -EFAULT; + } + ret = i2c_master_send(&ir->c_tx, buf, 1); + if (ret != 1) { + printk(KERN_ERR + "lirc_pvr150: i2c_master_send failed with %d\n", ret); + return ret < 0 ? ret : -EFAULT; + } + + /* Send finished download? */ + ret = i2c_master_recv(&ir->c_tx, buf, 1); + if (ret != 1) { + printk(KERN_ERR + "lirc_pvr150: i2c_master_recv failed with %d\n", ret); + return ret < 0 ? ret : -EFAULT; + } + if (buf[0] != 0xA0) { + printk(KERN_ERR + "lirc_pvr150: unexpected IR TX response #1: %02x\n", + buf[0]); + return ret < 0 ? ret : -EFAULT; + } + + /* Send prepare command? */ + buf[0] = 0x00; + buf[1] = 0x80; + ret = i2c_master_send(&ir->c_tx, buf, 2); + if (ret != 2) { + printk(KERN_ERR + "lirc_pvr150: i2c_master_send failed with %d\n", ret); + return ret < 0 ? ret : -EFAULT; + } + + /* This bit NAKs until the device is ready, so we retry it + sleeping a bit each time. This seems to be what the windows + driver does, approximately. + Try for up to 1s. + */ + for (i = 0; i < 20; ++i) { + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((50 * HZ + 999) / 1000); + ret = i2c_master_send(&ir->c_tx, buf, 1); + if (ret == 1) + break; + dprintk("NAK expected: i2c_master_send " + "failed with %d (try %d)\n", ret, i+1); + } + if (ret != 1) { + printk(KERN_ERR + "lirc_pvr150: IR TX chip never got ready: last " + "i2c_master_send failed with %d\n", ret); + return ret < 0 ? ret : -EFAULT; + } + + /* Seems to be an 'ok' response */ + i = i2c_master_recv(&ir->c_tx, buf, 1); + if (i != 1) { + printk(KERN_ERR + "lirc_pvr150: i2c_master_recv failed with %d\n", ret); + return ret < 0 ? ret : -EFAULT; + } + if (buf[0] != 0x80) { + printk(KERN_ERR + "lirc_pvr150: unexpected IR TX response #2: %02x\n", + buf[0]); + return -EFAULT; + } + + /* Oh good, it worked */ + dprintk("sent code %u, key %u\n", code, key); + return 0; +} + +/* Write a code to the device. We take in a 32-bit number (a lirc_t) and then + decode this to a codeset/key index. The key data is then decompressed and + sent to the device. We have a spin lock as per i2c documentation to prevent + multiple concurrent sends which would probably cause the device to explode. + */ +static ssize_t write(struct file *filep,const char *buf,size_t n, + loff_t *ppos) +{ + struct IR *ir = (struct IR *)filep->private_data; + size_t i; + int failures = 0; + + if (ir->c_tx.addr == 0) + return -ENODEV; + + /* Validate user parameters */ + if (n % sizeof(lirc_t)) + return(-EINVAL); + + /* Lock i2c bus for the duration */ + down(&ir->lock); + + /* Send each keypress */ + for (i = 0; i < n; ) + { + int ret = 0; + lirc_t command; + + if (copy_from_user(&command, buf + i, sizeof(command))) { + up(&ir->lock); + return -EFAULT; + } + + /* Send boot data first if required */ + if (ir->need_boot == 1) + { + ret = send_boot_data(ir); + if (ret == 0) + ir->need_boot = 0; + } + + /* Send the code */ + if (ret == 0) { + ret = send_code(ir, (unsigned)command >> 16, + (unsigned)command & 0xFFFF); + if (ret == -EPROTO) { + up(&ir->lock); + return ret; + } + } + + /* Hmm, a failure. If we've had a few then give up, otherwise + try a reset + */ + if (ret != 0) { + /* Looks like the chip crashed, reset it */ + printk(KERN_ERR "lirc_pvr150: sending to the IR " + "transmitter chip failed, trying " + "reset\n"); + + if (failures >= 3) { + printk(KERN_ERR "lirc_pvr150: unable to send " + "to the IR chip after 3 " + "resets, giving up\n"); + up(&ir->lock); + return ret; + } + ivtv_reset_ir_gpio(i2c_get_adapdata(ir->c_tx.adapter)); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((100 * HZ + 999) / 1000); + ir->need_boot = 1; + ++failures; + } + else + { + i += sizeof(lirc_t); + } + } + + /* Release i2c bus */ + up(&ir->lock); + + /* All looks good */ + return n; +} + +/* copied from lirc_dev */ +static unsigned int poll(struct file *filep, poll_table * wait) +{ + struct IR *ir = (struct IR *)filep->private_data; + unsigned int ret; + + dprintk("poll called\n"); + if (ir->c_rx.addr == 0) + return -ENODEV; + + down(&ir->buf_sem); + + poll_wait(filep, &ir->buf.wait_poll, wait); + + dprintk("poll result = %s\n", + lirc_buffer_empty(&ir->buf) ? "0" : "POLLIN|POLLRDNORM"); + + ret = lirc_buffer_empty(&ir->buf) ? 0 : (POLLIN|POLLRDNORM); + + up(&ir->buf_sem); + return ret; +} + +static int ioctl(struct inode *node,struct file *filep,unsigned int cmd, + unsigned long arg) +{ + struct IR *ir = (struct IR *)filep->private_data; + int result; + unsigned long mode, features = 0; + + if (ir->c_rx.addr != 0) + features |= LIRC_CAN_REC_LIRCCODE; + if (ir->c_tx.addr != 0) + features |= LIRC_CAN_SEND_PULSE; + + switch(cmd) + { + case LIRC_GET_LENGTH: + result = put_user((unsigned long)13, + (unsigned long *)arg); + break; + case LIRC_GET_FEATURES: + result=put_user(features,(unsigned long *) arg); + if(result) return(result); + break; + case LIRC_GET_REC_MODE: + if(!(features&LIRC_CAN_REC_MASK)) + return -ENOSYS; + + result = put_user(LIRC_REC2MODE + (features&LIRC_CAN_REC_MASK), + (unsigned long*)arg); + break; + case LIRC_SET_REC_MODE: + if(!(features&LIRC_CAN_REC_MASK)) + return -ENOSYS; + + result = get_user(mode, (unsigned long*)arg); + if(!result && !(LIRC_MODE2REC(mode) & features)) { + result = -EINVAL; + } + break; + case LIRC_GET_SEND_MODE: + if(!(features&LIRC_CAN_SEND_MASK)) + return -ENOSYS; + + result=put_user(LIRC_MODE_PULSE,(unsigned long *) arg); + if(result) return(result); + break; + case LIRC_SET_SEND_MODE: + if(!(features&LIRC_CAN_SEND_MASK)) + return -ENOSYS; + + result=get_user(mode,(unsigned long *) arg); + if(result) return(result); + if(mode!=LIRC_MODE_PULSE) return(-EINVAL); + break; + default: + return(-ENOIOCTLCMD); + } + return (0); +} + +/* Open the IR device of the PVR-150. Get hold of our IR structure and + stash it in private_data for the file */ +static int open(struct inode* node,struct file* filep) +{ + struct IR *ir; + int ret; + + /* find our IR struct */ + unsigned minor = MINOR(node->i_rdev); + if (minor >= MAX_IRCTL_DEVICES) { + dprintk("minor %d: open result = -ENODEV\n", + minor); + return -ENODEV; + } + ir = ir_devices[minor]; + + /* increment in use count */ + down(&ir->lock); + ++ir->open; + ret = set_use_inc(ir); + if (ret != 0) { + --ir->open; + up(&ir->lock); + return ret; + } + up(&ir->lock); + + /* stash our IR struct */ + filep->private_data = ir; + + return(0); +} + +/* Close the IR device of the PVR-150 */ +static int close(struct inode* node,struct file* filep) +{ + /* find our IR struct */ + struct IR *ir = (struct IR *)filep->private_data; + if (ir == NULL) { + printk(KERN_ERR + "lirc_pvr150: close: no private_data " + "attached to the file!\n"); + return -ENODEV; + } + + /* decrement in use count */ + down(&ir->lock); + --ir->open; + set_use_dec(ir); + up(&ir->lock); + + return(0); +} + +static struct lirc_plugin lirc_template = { + name: "lirc_pvr150", + set_use_inc: set_use_inc, + set_use_dec: set_use_dec, + owner: THIS_MODULE +}; + +/* ----------------------------------------------------------------------- */ + +static int ir_attach(struct i2c_adapter *adap, int have_rx, int have_tx); +static int ir_detach(struct i2c_client *client); +static int ir_probe(struct i2c_adapter *adap); +static int ir_command(struct i2c_client *client, unsigned int cmd, void *arg); + +static struct i2c_driver driver = { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) + name: "i2c ir driver", + flags: I2C_DF_NOTIFY, +#else + .driver = { + owner: THIS_MODULE, + name: "i2c ir driver", + }, +#endif + id: I2C_DRIVERID_EXP3, /* FIXME */ + attach_adapter: ir_probe, + detach_client: ir_detach, + command: ir_command, +}; + +static struct i2c_client client_template = +{ + name: "unset", + driver: &driver +}; + +static struct file_operations lirc_fops = +{ + llseek: lseek, + read: read, + write: write, + poll: poll, + ioctl: ioctl, + open: open, + release: close +}; + +static int i2c_attach(struct i2c_client *client, struct IR *ir) +{ + int ret; + + i2c_set_clientdata(client, ir); + + ret = i2c_attach_client(client); + if (ret != 0) { + client->addr = 0; + return ret; + } + if (i2c_use_client(client) == NULL) { + i2c_detach_client(client); + client->addr = 0; + return ret; + } + ++ir->devs; + return 0; +} + +static int ir_attach(struct i2c_adapter *adap, int have_rx, int have_tx) +{ + struct IR *ir; + int ret, i; + + printk("lirc_pvr150: chip found with %s\n", + have_rx && have_tx ? "RX and TX" : + have_rx ? "RX only" : "TX only"); + + if (NULL == (ir = kmalloc(sizeof(struct IR),GFP_KERNEL))) + return -ENOMEM; + if (lirc_buffer_init(&ir->buf, 2, BUFLEN/2) != 0) { + kfree(ir); + return -ENOMEM; + } + init_MUTEX(&ir->lock); + init_MUTEX(&ir->buf_sem); + ir->open = 0; + ir->devs = 0; + ir->tpid = 0; + ir->need_boot = 1; + ir->shutdown = 0; + ir->t_notify = ir->t_notify2 = NULL; + for (i = 0; i < sizeof(ir->b); ++i) + ir->b[0] = 0; + + memcpy(&ir->l,&lirc_template,sizeof(struct lirc_plugin)); + ir->l.minor = -1; + + /* initialise RX device */ + client_template.adapter = adap; + memcpy(&ir->c_rx,&client_template,sizeof(struct i2c_client)); + if (have_rx) { + DECLARE_COMPLETION(tn); + + /* I2C attach to device */ + ir->c_rx.addr = 0x71; + strlcpy(ir->c_rx.name, "Hauppauge PVR150 RX", + sizeof(ir->c_rx.name)); + if ( (ret = i2c_attach(&ir->c_rx, ir)) != 0 ) + goto err; + + /* try to fire up polling thread */ + ir->t_notify = &tn; + ir->tpid = kernel_thread(lirc_thread, ir, 0); + if (ir->tpid < 0) { + printk(KERN_ERR "lirc_pvr150: lirc_register_plugin: " + "cannot run poll thread\n"); + ret = -ECHILD; + goto err; + } + wait_for_completion(&tn); + ir->t_notify = NULL; + } + + /* initialise TX device */ + memcpy(&ir->c_tx,&client_template,sizeof(struct i2c_client)); + if (have_tx) { + /* I2C attach to device */ + ir->c_tx.addr = 0x70; + strlcpy(ir->c_tx.name, "Hauppauge PVR150 TX", + sizeof(ir->c_tx.name)); + if ( (ret = i2c_attach(&ir->c_tx, ir)) != 0 ) + goto err; + } + + /* set lirc_dev stuff */ + ir->l.code_length = 13; + ir->l.rbuf = &ir->buf; + ir->l.fops = &lirc_fops; + ir->l.data = ir; + ir->l.minor = minor; + ir->l.sample_rate = 0; + + /* register with lirc */ + ir->l.minor = lirc_register_plugin(&ir->l); + if (ir->l.minor < 0 || ir->l.minor >= MAX_IRCTL_DEVICES) { + printk(KERN_ERR + "lirc_pvr150: ir_attach: " + "\"minor\" must be between 0 and %d (%d)!\n", + MAX_IRCTL_DEVICES-1, ir->l.minor); + ret = -EBADRQC; + goto err; + } + + /* store this for getting back in open() later on */ + ir_devices[ir->l.minor] = ir; + + /* if we have the tx device, load the 'firmware'. We do this + after registering with lirc as otherwise hotplug seems to take + 10s to create the lirc device. + */ + if (have_tx) { + /* Special TX init */ + ret = tx_init(ir); + if (ret != 0) + goto err; + } + return 0; + +err: + /* undo everything, hopefully... */ + if (ir->c_rx.addr) ir_detach(&ir->c_rx); + if (ir->c_tx.addr) ir_detach(&ir->c_tx); + return ret; +} + +static int ir_detach(struct i2c_client *client) +{ + struct IR *ir = i2c_get_clientdata(client); + down(&ir->lock); + + if (client == &ir->c_rx) { + DECLARE_COMPLETION(tn); + DECLARE_COMPLETION(tn2); + + /* end up polling thread */ + if (ir->tpid >= 0) { + ir->t_notify = &tn; + ir->t_notify2 = &tn2; + ir->shutdown = 1; + { + struct task_struct *p; + p = find_task_by_pid_ns(ir->tpid, &init_pid_ns); + wake_up_process(p); + } + complete(&tn2); + wait_for_completion(&tn); + ir->t_notify = NULL; + ir->t_notify2 = NULL; + } + + /* unregister device */ + i2c_release_client(&ir->c_rx); + i2c_detach_client(&ir->c_rx); + } else if (client == &ir->c_tx) { + i2c_release_client(&ir->c_tx); + i2c_detach_client(&ir->c_tx); + } else { + up(&ir->lock); + printk(KERN_ERR "lirc_pvr150: ir_detach: detached from " + "something we didn't attach to\n"); + return -ENODEV; + } + + --ir->devs; + if (ir->devs < 0) + { + up(&ir->lock); + printk(KERN_ERR "lirc_pvr150: ir_detach: invalid " + "device count\n"); + return -ENODEV; + } + else if (ir->devs == 0) + { + /* unregister lirc plugin */ + if (ir->l.minor >= 0 && ir->l.minor < MAX_IRCTL_DEVICES) + { + lirc_unregister_plugin(ir->l.minor); + ir_devices[ir->l.minor] = NULL; + } + + /* free memory */ + lirc_buffer_free(&ir->buf); + up(&ir->lock); + kfree(ir); + return 0; + } + up(&ir->lock); + return 0; +} + +static int ir_probe(struct i2c_adapter *adap) +{ + struct i2c_client c; + char buf; + +#ifdef I2C_HW_B_CX2341X + if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848) || + adap->id == (I2C_ALGO_BIT | I2C_HW_B_CX2341X)) +#else + if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) +#endif + { + int have_rx = 0, have_tx = 0; + + /* The external IR receiver is at i2c address 0x71 on the PVR-150 + The IR transmitter is at 0x70. + */ + memset(&c,0,sizeof(c)); + c.adapter = adap; + c.addr = 0x70; + + if (!disable_rx) { + if (i2c_master_recv(&c,&buf,1) == 1) + have_rx = 1; + dprintk("probe 0x70 @ %s: %s\n", + adap->name, + have_rx ? "yes" : "no"); + } + + if (!disable_tx) { + c.addr = 0x71; + if (i2c_master_recv(&c,&buf,1) == 1) + have_tx = 1; + dprintk("probe 0x71 @ %s: %s\n", + adap->name, + have_tx ? "yes" : "no"); + } + + if (have_rx || have_tx) + return ir_attach(adap, have_rx, have_tx); + else + { + printk(KERN_ERR "lirc_pvr150: %s: no devices found\n", adap->name); + } + } + + return 0; +} + +static int ir_command(struct i2c_client *client,unsigned int cmd, void *arg) +{ + /* nothing */ + return 0; +} + +/* ----------------------------------------------------------------------- */ +#ifdef MODULE + +int init_module(void) +{ + init_MUTEX(&tx_data_lock); + request_module("ivtv"); + request_module("firmware_class"); + i2c_add_driver(&driver); + return 0; +} + +void cleanup_module(void) +{ + i2c_del_driver(&driver); + /* if loaded */ + fw_unload(); +} + +MODULE_DESCRIPTION("Infrared receiver driver for Hauppauge PVR-150 card (i2c stack)"); +MODULE_AUTHOR("Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, Ulrich Mueller, Stefan Jahn, Jerome Brock, Mark Weaver"); +MODULE_LICENSE("GPL"); + +module_param(minor, int, 0444); +MODULE_PARM_DESC(minor, "Preferred minor device number"); + +module_param(debug, bool, 0644); +MODULE_PARM_DESC(debug, "Enable debugging messages"); + +module_param(disable_rx, bool, 0644); +MODULE_PARM_DESC(disable_rx, "Disable the IR receiver device"); + +module_param(disable_tx, bool, 0644); +MODULE_PARM_DESC(disable_tx, "Disable the IR transmitter device"); + +EXPORT_NO_SYMBOLS; + +#endif /* MODULE */ + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_pvr150/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_pvr150/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_PVR150) += lirc_pvr150.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_sir/lirc_sir.c +++ linux-2.6.28/ubuntu/lirc/lirc_sir/lirc_sir.c @@ -0,0 +1,1323 @@ +/* + * LIRC SIR driver, (C) 2000 Milan Pikula + * + * lirc_sir - Device driver for use with SIR (serial infra red) + * mode of IrDA on many notebooks. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + * + * + * 2000/09/16 Frank Przybylski : + * added timeout and relaxed pulse detection, removed gap bug + * + * 2000/12/15 Christoph Bartelmus : + * added support for Tekram Irmate 210 (sending does not work yet, + * kind of disappointing that nobody was able to implement that + * before), + * major clean-up + * + * 2001/02/27 Christoph Bartelmus : + * added support for StrongARM SA1100 embedded microprocessor + * parts cut'n'pasted from sa1100_ir.c (C) 2000 Russell King + */ + + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18) +#error "**********************************************************" +#error " Sorry, this driver needs kernel version 2.2.18 or higher " +#error "**********************************************************" +#endif +#include + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef LIRC_ON_SA1100 +#include +#ifdef CONFIG_SA1100_COLLIE +#include +#include +#endif +#endif + +#include + +#include "lirc.h" +#include "lirc_dev/lirc_dev.h" +#include "kcompat.h" + +/* SECTION: Definitions */ + +/**************************** Tekram dongle ***************************/ +#ifdef LIRC_SIR_TEKRAM +/* stolen from kernel source */ +/* definitions for Tekram dongle */ +#define TEKRAM_115200 0x00 +#define TEKRAM_57600 0x01 +#define TEKRAM_38400 0x02 +#define TEKRAM_19200 0x03 +#define TEKRAM_9600 0x04 +#define TEKRAM_2400 0x08 + +#define TEKRAM_PW 0x10 /* Pulse select bit */ + +/* 10bit * 1s/115200bit in miliseconds = 87ms*/ +#define TIME_CONST (10000000ul/115200ul) + +#endif + +#ifdef LIRC_SIR_ACTISYS_ACT200L +static void init_act200(void); +#elif defined(LIRC_SIR_ACTISYS_ACT220L) +static void init_act220(void); +#endif + +/******************************* SA1100 ********************************/ +#ifdef LIRC_ON_SA1100 +struct sa1100_ser2_registers { + /* HSSP control register */ + unsigned char hscr0; + /* UART registers */ + unsigned char utcr0; + unsigned char utcr1; + unsigned char utcr2; + unsigned char utcr3; + unsigned char utcr4; + unsigned char utdr; + unsigned char utsr0; + unsigned char utsr1; +} sr; + +static int irq = IRQ_Ser2ICP; + +#define LIRC_ON_SA1100_TRANSMITTER_LATENCY 0 + +/* pulse/space ratio of 50/50 */ +static unsigned long pulse_width = (13-LIRC_ON_SA1100_TRANSMITTER_LATENCY); +/* 1000000/freq-pulse_width */ +static unsigned long space_width = (13-LIRC_ON_SA1100_TRANSMITTER_LATENCY); +static unsigned int freq = 38000; /* modulation frequency */ +static unsigned int duty_cycle = 50; /* duty cycle of 50% */ + +#endif + +#define RBUF_LEN 1024 +#define WBUF_LEN 1024 + +#define LIRC_DRIVER_NAME "lirc_sir" + +#define PULSE '[' + +#ifndef LIRC_SIR_TEKRAM +/* 9bit * 1s/115200bit in milli seconds = 78.125ms*/ +#define TIME_CONST (9000000ul/115200ul) +#endif + + +/* timeout for sequences in jiffies (=5/100s) */ +/* must be longer than TIME_CONST */ +#define SIR_TIMEOUT (HZ*5/100) + +#ifndef LIRC_ON_SA1100 +#ifndef LIRC_IRQ +#define LIRC_IRQ 4 +#endif +#ifndef LIRC_PORT +#define LIRC_PORT 0x3e8 +#endif + +static int io = LIRC_PORT; +static int irq = LIRC_IRQ; +static int threshold = 3; +#endif + +static DEFINE_SPINLOCK(timer_lock); +static struct timer_list timerlist; +/* time of last signal change detected */ +static struct timeval last_tv = {0, 0}; +/* time of last UART data ready interrupt */ +static struct timeval last_intr_tv = {0, 0}; +static int last_value; + +static DECLARE_WAIT_QUEUE_HEAD(lirc_read_queue); + +static DEFINE_SPINLOCK(hardware_lock); +static DEFINE_SPINLOCK(dev_lock); + +static lirc_t rx_buf[RBUF_LEN]; +static unsigned int rx_tail, rx_head; +static lirc_t tx_buf[WBUF_LEN]; + +static int debug; +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \ + fmt, ## args); \ + } while (0) + +/* SECTION: Prototypes */ + +/* Communication with user-space */ +static int lirc_open(struct inode *inode, struct file *file); +static int lirc_close(struct inode *inode, struct file *file); +static unsigned int lirc_poll(struct file *file, poll_table *wait); +static ssize_t lirc_read(struct file *file, char *buf, size_t count, + loff_t *ppos); +static ssize_t lirc_write(struct file *file, const char *buf, size_t n, + loff_t *pos); +static int lirc_ioctl(struct inode *node, struct file *filep, unsigned int cmd, + unsigned long arg); +static void add_read_queue(int flag, unsigned long val); +#ifdef MODULE +static int init_chrdev(void); +static void drop_chrdev(void); +#endif + /* Hardware */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static irqreturn_t sir_interrupt(int irq, void *dev_id, + struct pt_regs *regs); +#else +static irqreturn_t sir_interrupt(int irq, void *dev_id); +#endif +static void send_space(unsigned long len); +static void send_pulse(unsigned long len); +static int init_hardware(void); +static void drop_hardware(void); + /* Initialisation */ +static int init_port(void); +static void drop_port(void); +int init_module(void); +void cleanup_module(void); + +#ifdef LIRC_ON_SA1100 +static inline void on(void) +{ + PPSR |= PPC_TXD2; +} + +static inline void off(void) +{ + PPSR &= ~PPC_TXD2; +} +#else +static inline unsigned int sinp(int offset) +{ + return inb(io + offset); +} + +static inline void soutp(int offset, int value) +{ + outb(value, io + offset); +} +#endif + +#ifndef MAX_UDELAY_MS +#define MAX_UDELAY_US 5000 +#else +#define MAX_UDELAY_US (MAX_UDELAY_MS*1000) +#endif + +static inline void safe_udelay(unsigned long usecs) +{ + while (usecs > MAX_UDELAY_US) { + udelay(MAX_UDELAY_US); + usecs -= MAX_UDELAY_US; + } + udelay(usecs); +} + +/* SECTION: Communication with user-space */ + +static int lirc_open(struct inode *inode, struct file *file) +{ + spin_lock(&dev_lock); + if (MOD_IN_USE) { + spin_unlock(&dev_lock); + return -EBUSY; + } + MOD_INC_USE_COUNT; + spin_unlock(&dev_lock); + return 0; +} + +static int lirc_close(struct inode *inode, struct file *file) +{ + MOD_DEC_USE_COUNT; + return 0; +} + +static unsigned int lirc_poll(struct file *file, poll_table *wait) +{ + poll_wait(file, &lirc_read_queue, wait); + if (rx_head != rx_tail) + return POLLIN | POLLRDNORM; + return 0; +} + +static ssize_t lirc_read(struct file *file, char *buf, size_t count, + loff_t *ppos) +{ + int n = 0; + int retval = 0; + DECLARE_WAITQUEUE(wait, current); + + if (n % sizeof(lirc_t)) + return -EINVAL; + + add_wait_queue(&lirc_read_queue, &wait); + set_current_state(TASK_INTERRUPTIBLE); + while (n < count) { + if (rx_head != rx_tail) { + if (copy_to_user((void *) buf + n, + (void *) (rx_buf + rx_head), + sizeof(lirc_t))) { + retval = -EFAULT; + break; + } + rx_head = (rx_head + 1) & (RBUF_LEN - 1); + n += sizeof(lirc_t); + } else { + if (file->f_flags & O_NONBLOCK) { + retval = -EAGAIN; + break; + } + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } + schedule(); + set_current_state(TASK_INTERRUPTIBLE); + } + } + remove_wait_queue(&lirc_read_queue, &wait); + set_current_state(TASK_RUNNING); + return (n ? n : retval); +} +static ssize_t lirc_write(struct file *file, const char *buf, size_t n, + loff_t *pos) +{ + unsigned long flags; + int i; + + if (n % sizeof(lirc_t) || (n/sizeof(lirc_t)) > WBUF_LEN) + return -EINVAL; + if (copy_from_user(tx_buf, buf, n)) + return -EFAULT; + i = 0; + n /= sizeof(lirc_t); +#ifdef LIRC_ON_SA1100 + /* disable receiver */ + Ser2UTCR3 = 0; +#endif + local_irq_save(flags); + while (1) { + if (i >= n) + break; + if (tx_buf[i]) + send_pulse(tx_buf[i]); + i++; + if (i >= n) + break; + if (tx_buf[i]) + send_space(tx_buf[i]); + i++; + } + local_irq_restore(flags); +#ifdef LIRC_ON_SA1100 + off(); + udelay(1000); /* wait 1ms for IR diode to recover */ + Ser2UTCR3 = 0; + /* clear status register to prevent unwanted interrupts */ + Ser2UTSR0 &= (UTSR0_RID | UTSR0_RBB | UTSR0_REB); + /* enable receiver */ + Ser2UTCR3 = UTCR3_RXE|UTCR3_RIE; +#endif + return n; +} + +static int lirc_ioctl(struct inode *node, struct file *filep, unsigned int cmd, + unsigned long arg) +{ + int retval = 0; + unsigned long value = 0; +#ifdef LIRC_ON_SA1100 + unsigned int ivalue; + + if (cmd == LIRC_GET_FEATURES) + value = LIRC_CAN_SEND_PULSE | + LIRC_CAN_SET_SEND_DUTY_CYCLE | + LIRC_CAN_SET_SEND_CARRIER | + LIRC_CAN_REC_MODE2; + else if (cmd == LIRC_GET_SEND_MODE) + value = LIRC_MODE_PULSE; + else if (cmd == LIRC_GET_REC_MODE) + value = LIRC_MODE_MODE2; +#else + if (cmd == LIRC_GET_FEATURES) + value = LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2; + else if (cmd == LIRC_GET_SEND_MODE) + value = LIRC_MODE_PULSE; + else if (cmd == LIRC_GET_REC_MODE) + value = LIRC_MODE_MODE2; +#endif + + switch (cmd) { + case LIRC_GET_FEATURES: + case LIRC_GET_SEND_MODE: + case LIRC_GET_REC_MODE: + retval = put_user(value, (unsigned long *) arg); + break; + + case LIRC_SET_SEND_MODE: + case LIRC_SET_REC_MODE: + retval = get_user(value, (unsigned long *) arg); + break; +#ifdef LIRC_ON_SA1100 + case LIRC_SET_SEND_DUTY_CYCLE: + retval = get_user(ivalue, (unsigned int *) arg); + if (retval) + return reetval; + if (ivalue <= 0 || ivalue > 100) + return -EINVAL; + /* (ivalue/100)*(1000000/freq) */ + duty_cycle = ivalue; + pulse_width = (unsigned long) duty_cycle*10000/freq; + space_width = (unsigned long) 1000000L/freq-pulse_width; + if (pulse_width >= LIRC_ON_SA1100_TRANSMITTER_LATENCY) + pulse_width -= LIRC_ON_SA1100_TRANSMITTER_LATENCY; + if (space_width >= LIRC_ON_SA1100_TRANSMITTER_LATENCY) + space_width -= LIRC_ON_SA1100_TRANSMITTER_LATENCY; + break; + case LIRC_SET_SEND_CARRIER: + retval = get_user(ivalue, (unsigned int *) arg); + if (retval) + return retval; + if (ivalue > 500000 || ivalue < 20000) + return -EINVAL; + freq = ivalue; + pulse_width = (unsigned long) duty_cycle*10000/freq; + space_width = (unsigned long) 1000000L/freq-pulse_width; + if (pulse_width >= LIRC_ON_SA1100_TRANSMITTER_LATENCY) + pulse_width -= LIRC_ON_SA1100_TRANSMITTER_LATENCY; + if (space_width >= LIRC_ON_SA1100_TRANSMITTER_LATENCY) + space_width -= LIRC_ON_SA1100_TRANSMITTER_LATENCY; + break; +#endif + default: + retval = -ENOIOCTLCMD; + + } + + if (retval) + return retval; + if (cmd == LIRC_SET_REC_MODE) { + if (value != LIRC_MODE_MODE2) + retval = -ENOSYS; + } else if (cmd == LIRC_SET_SEND_MODE) { + if (value != LIRC_MODE_PULSE) + retval = -ENOSYS; + } + + return retval; +} + +static void add_read_queue(int flag, unsigned long val) +{ + unsigned int new_rx_tail; + lirc_t newval; + + dprintk("add flag %d with val %lu\n", flag, val); + + newval = val & PULSE_MASK; + + /* statistically pulses are ~TIME_CONST/2 too long: we could + maybe make this more exactly but this is good enough */ + if (flag) { + /* pulse */ + if (newval > TIME_CONST/2) + newval -= TIME_CONST/2; + else /* should not ever happen */ + newval = 1; + newval |= PULSE_BIT; + } else { + newval += TIME_CONST/2; + } + new_rx_tail = (rx_tail + 1) & (RBUF_LEN - 1); + if (new_rx_tail == rx_head) { + dprintk("Buffer overrun.\n"); + return; + } + rx_buf[rx_tail] = newval; + rx_tail = new_rx_tail; + wake_up_interruptible(&lirc_read_queue); +} + +static struct file_operations lirc_fops = { + .read = lirc_read, + .write = lirc_write, + .poll = lirc_poll, + .ioctl = lirc_ioctl, + .open = lirc_open, + .release = lirc_close, +}; + +static int set_use_inc(void *data) +{ + return 0; +} + +static void set_use_dec(void *data) +{ +} +static struct lirc_plugin plugin = { + .name = LIRC_DRIVER_NAME, + .minor = -1, + .code_length = 1, + .sample_rate = 0, + .data = NULL, + .add_to_buf = NULL, + .get_queue = NULL, + .set_use_inc = set_use_inc, + .set_use_dec = set_use_dec, + .fops = &lirc_fops, + .dev = NULL, + .owner = THIS_MODULE, +}; + + +#ifdef MODULE +static int init_chrdev(void) +{ + plugin.minor = lirc_register_plugin(&plugin); + if (plugin.minor < 0) { + printk(KERN_ERR LIRC_DRIVER_NAME ": init_chrdev() failed.\n"); + return -EIO; + } + return 0; +} + +static void drop_chrdev(void) +{ + lirc_unregister_plugin(plugin.minor); +} +#endif + +/* SECTION: Hardware */ +static long delta(struct timeval *tv1, struct timeval *tv2) +{ + unsigned long deltv; + + deltv = tv2->tv_sec - tv1->tv_sec; + if (deltv > 15) + deltv = 0xFFFFFF; + else + deltv = deltv*1000000 + + tv2->tv_usec - + tv1->tv_usec; + return deltv; +} + +static void sir_timeout(unsigned long data) +{ + /* if last received signal was a pulse, but receiving stopped + within the 9 bit frame, we need to finish this pulse and + simulate a signal change to from pulse to space. Otherwise + upper layers will receive two sequences next time. */ + + unsigned long flags; + unsigned long pulse_end; + + /* avoid interference with interrupt */ + spin_lock_irqsave(&timer_lock, flags); + if (last_value) { +#ifndef LIRC_ON_SA1100 + /* clear unread bits in UART and restart */ + outb(UART_FCR_CLEAR_RCVR, io + UART_FCR); +#endif + /* determine 'virtual' pulse end: */ + pulse_end = delta(&last_tv, &last_intr_tv); + dprintk("timeout add %d for %lu usec\n", last_value, pulse_end); + add_read_queue(last_value, pulse_end); + last_value = 0; + last_tv = last_intr_tv; + } + spin_unlock_irqrestore(&timer_lock, flags); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static irqreturn_t sir_interrupt(int irq, void *dev_id, + struct pt_regs *regs) +#else +static irqreturn_t sir_interrupt(int irq, void *dev_id) +#endif +{ + unsigned char data; + struct timeval curr_tv; + static unsigned long deltv; +#ifdef LIRC_ON_SA1100 + int status; + static int n; + + status = Ser2UTSR0; + /* + * Deal with any receive errors first. The bytes in error may be + * the only bytes in the receive FIFO, so we do this first. + */ + while (status & UTSR0_EIF) { + int bstat; + + if (debug) { + dprintk("EIF\n"); + bstat = Ser2UTSR1; + + if (bstat & UTSR1_FRE) + dprintk("frame error\n"); + if (bstat & UTSR1_ROR) + dprintk("receive fifo overrun\n"); + if (bstat & UTSR1_PRE) + dprintk("parity error\n"); + } + + bstat = Ser2UTDR; + n++; + status = Ser2UTSR0; + } + + if (status & (UTSR0_RFS | UTSR0_RID)) { + do_gettimeofday(&curr_tv); + deltv = delta(&last_tv, &curr_tv); + do { + data = Ser2UTDR; + dprintk("%d data: %u\n", n, (unsigned int) data); + n++; + } while (status & UTSR0_RID && /* do not empty fifo in + order to get UTSR0_RID in + any case */ + Ser2UTSR1 & UTSR1_RNE); /* data ready */ + + if (status&UTSR0_RID) { + add_read_queue(0 , deltv - n * TIME_CONST); /*space*/ + add_read_queue(1, n * TIME_CONST); /*pulse*/ + n = 0; + last_tv = curr_tv; + } + } + + if (status & UTSR0_TFS) + printk(KERN_ERR "transmit fifo not full, shouldn't happen\n"); + + /* + * We must clear certain bits. + */ + status &= (UTSR0_RID | UTSR0_RBB | UTSR0_REB); + if (status) + Ser2UTSR0 = status; +#else + unsigned long deltintrtv; + unsigned long flags; + int iir, lsr; + + while ((iir = inb(io + UART_IIR) & UART_IIR_ID)) { + switch (iir&UART_IIR_ID) { /* FIXME toto treba preriedit */ + case UART_IIR_MSI: + (void) inb(io + UART_MSR); + break; + case UART_IIR_RLSI: + (void) inb(io + UART_LSR); + break; + case UART_IIR_THRI: +#if 0 + if (lsr & UART_LSR_THRE) /* FIFO is empty */ + outb(data, io + UART_TX) +#endif + break; + case UART_IIR_RDI: + /* avoid interference with timer */ + spin_lock_irqsave(&timer_lock, flags); + do { + del_timer(&timerlist); + data = inb(io + UART_RX); + do_gettimeofday(&curr_tv); + deltv = delta(&last_tv, &curr_tv); + deltintrtv = delta(&last_intr_tv, &curr_tv); + dprintk("t %lu, d %d\n", deltintrtv, (int)data); + /* if nothing came in last X cycles, + it was gap */ + if (deltintrtv > TIME_CONST * threshold) { + if (last_value) { + dprintk("GAP\n"); + /* simulate signal change */ + add_read_queue(last_value, + deltv - + deltintrtv); + last_value = 0; + last_tv.tv_sec = + last_intr_tv.tv_sec; + last_tv.tv_usec = + last_intr_tv.tv_usec; + deltv = deltintrtv; + } + } + data = 1; + if (data ^ last_value) { + /* deltintrtv > 2*TIME_CONST, + remember ? */ + /* the other case is timeout */ + add_read_queue(last_value, + deltv-TIME_CONST); + last_value = data; + last_tv = curr_tv; + if (last_tv.tv_usec >= TIME_CONST) { + last_tv.tv_usec -= TIME_CONST; + } else { + last_tv.tv_sec--; + last_tv.tv_usec += 1000000 - + TIME_CONST; + } + } + last_intr_tv = curr_tv; + if (data) { + /* start timer for end of + * sequence detection */ + timerlist.expires = jiffies + + SIR_TIMEOUT; + add_timer(&timerlist); + } + } + while ((lsr = inb(io + UART_LSR)) + & UART_LSR_DR); /* data ready */ + spin_unlock_irqrestore(&timer_lock, flags); + break; + default: + break; + } + } +#endif + return IRQ_RETVAL(IRQ_HANDLED); +} + +#ifdef LIRC_ON_SA1100 +static void send_pulse(unsigned long length) +{ + unsigned long k, delay; + int flag; + + if (length == 0) + return; + /* this won't give us the carrier frequency we really want + due to integer arithmetic, but we can accept this inaccuracy */ + + for (k = flag = 0; k < length; k += delay, flag = !flag) { + if (flag) { + off(); + delay = space_width; + } else { + on(); + delay = pulse_width; + } + safe_udelay(delay); + } + off(); +} + +static void send_space(unsigned long length) +{ + if (length == 0) + return; + off(); + safe_udelay(length); +} +#else +static void send_space(unsigned long len) +{ + safe_udelay(len); +} + +static void send_pulse(unsigned long len) +{ + long bytes_out = len / TIME_CONST; + long time_left; + + time_left = (long)len - (long)bytes_out * (long)TIME_CONST; + if (bytes_out == 0) { + bytes_out++; + time_left = 0; + } + while (bytes_out--) { + outb(PULSE, io + UART_TX); + /* FIXME treba seriozne cakanie z drivers/char/serial.c */ + while (!(inb(io + UART_LSR) & UART_LSR_THRE)); + } +#if 0 + if (time_left > 0) + safe_udelay(time_left); +#endif +} +#endif + +#ifdef CONFIG_SA1100_COLLIE +static inline int sa1100_irda_set_power_collie(int state) +{ + if (state) { + /* + * 0 - off + * 1 - short range, lowest power + * 2 - medium range, medium power + * 3 - maximum range, high power + */ + ucb1200_set_io_direction(TC35143_GPIO_IR_ON, + TC35143_IODIR_OUTPUT); + ucb1200_set_io(TC35143_GPIO_IR_ON, TC35143_IODAT_LOW); + udelay(100); + } else { + /* OFF */ + ucb1200_set_io_direction(TC35143_GPIO_IR_ON, + TC35143_IODIR_OUTPUT); + ucb1200_set_io(TC35143_GPIO_IR_ON, TC35143_IODAT_HIGH); + } + return 0; +} +#endif + +static int init_hardware(void) +{ + unsigned long flags; + + spin_lock_irqsave(&hardware_lock, flags); + /* reset UART */ +#ifdef LIRC_ON_SA1100 +#ifdef CONFIG_SA1100_BITSY + if (machine_is_bitsy()) { + printk(KERN_INFO "Power on IR module\n"); + set_bitsy_egpio(EGPIO_BITSY_IR_ON); + } +#endif +#ifdef CONFIG_SA1100_COLLIE + sa1100_irda_set_power_collie(3); /* power on */ +#endif + sr.hscr0 = Ser2HSCR0; + + sr.utcr0 = Ser2UTCR0; + sr.utcr1 = Ser2UTCR1; + sr.utcr2 = Ser2UTCR2; + sr.utcr3 = Ser2UTCR3; + sr.utcr4 = Ser2UTCR4; + + sr.utdr = Ser2UTDR; + sr.utsr0 = Ser2UTSR0; + sr.utsr1 = Ser2UTSR1; + + /* configure GPIO */ + /* output */ + PPDR |= PPC_TXD2; + PSDR |= PPC_TXD2; + /* set output to 0 */ + off(); + + /* + * Enable HP-SIR modulation, and ensure that the port is disabled. + */ + Ser2UTCR3 = 0; + Ser2HSCR0 = sr.hscr0 & (~HSCR0_HSSP); + + /* clear status register to prevent unwanted interrupts */ + Ser2UTSR0 &= (UTSR0_RID | UTSR0_RBB | UTSR0_REB); + + /* 7N1 */ + Ser2UTCR0 = UTCR0_1StpBit|UTCR0_7BitData; + /* 115200 */ + Ser2UTCR1 = 0; + Ser2UTCR2 = 1; + /* use HPSIR, 1.6 usec pulses */ + Ser2UTCR4 = UTCR4_HPSIR|UTCR4_Z1_6us; + + /* enable receiver, receive fifo interrupt */ + Ser2UTCR3 = UTCR3_RXE|UTCR3_RIE; + + /* clear status register to prevent unwanted interrupts */ + Ser2UTSR0 &= (UTSR0_RID | UTSR0_RBB | UTSR0_REB); + +#elif defined(LIRC_SIR_TEKRAM) + /* disable FIFO */ + soutp(UART_FCR, + UART_FCR_CLEAR_RCVR| + UART_FCR_CLEAR_XMIT| + UART_FCR_TRIGGER_1); + + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + /* First of all, disable all interrupts */ + soutp(UART_IER, sinp(UART_IER) & + (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); + + /* Set DLAB 1. */ + soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB); + + /* Set divisor to 12 => 9600 Baud */ + soutp(UART_DLM, 0); + soutp(UART_DLL, 12); + + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + /* power supply */ + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); + safe_udelay(50*1000); + + /* -DTR low -> reset PIC */ + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_OUT2); + udelay(1*1000); + + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); + udelay(100); + + + /* -RTS low -> send control byte */ + soutp(UART_MCR, UART_MCR_DTR|UART_MCR_OUT2); + udelay(7); + soutp(UART_TX, TEKRAM_115200|TEKRAM_PW); + + /* one byte takes ~1042 usec to transmit at 9600,8N1 */ + udelay(1500); + + /* back to normal operation */ + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); + udelay(50); + + udelay(1500); + + /* read previous control byte */ + printk(KERN_INFO LIRC_DRIVER_NAME + ": 0x%02x\n", sinp(UART_RX)); + + /* Set DLAB 1. */ + soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB); + + /* Set divisor to 1 => 115200 Baud */ + soutp(UART_DLM, 0); + soutp(UART_DLL, 1); + + /* Set DLAB 0, 8 Bit */ + soutp(UART_LCR, UART_LCR_WLEN8); + /* enable interrupts */ + soutp(UART_IER, sinp(UART_IER)|UART_IER_RDI); +#else + outb(0, io + UART_MCR); + outb(0, io + UART_IER); + /* init UART */ + /* set DLAB, speed = 115200 */ + outb(UART_LCR_DLAB | UART_LCR_WLEN7, io + UART_LCR); + outb(1, io + UART_DLL); outb(0, io + UART_DLM); + /* 7N1+start = 9 bits at 115200 ~ 3 bits at 44000 */ + outb(UART_LCR_WLEN7, io + UART_LCR); + /* FIFO operation */ + outb(UART_FCR_ENABLE_FIFO, io + UART_FCR); + /* interrupts */ + /* outb(UART_IER_RLSI|UART_IER_RDI|UART_IER_THRI, io + UART_IER); */ + outb(UART_IER_RDI, io + UART_IER); + /* turn on UART */ + outb(UART_MCR_DTR|UART_MCR_RTS|UART_MCR_OUT2, io + UART_MCR); +#ifdef LIRC_SIR_ACTISYS_ACT200L + init_act200(); +#elif defined(LIRC_SIR_ACTISYS_ACT220L) + init_act220(); +#endif +#endif + spin_unlock_irqrestore(&hardware_lock, flags); + return 0; +} + +static void drop_hardware(void) +{ + unsigned long flags; + + spin_lock_irqsave(&hardware_lock, flags); + +#ifdef LIRC_ON_SA1100 + Ser2UTCR3 = 0; + + Ser2UTCR0 = sr.utcr0; + Ser2UTCR1 = sr.utcr1; + Ser2UTCR2 = sr.utcr2; + Ser2UTCR4 = sr.utcr4; + Ser2UTCR3 = sr.utcr3; + + Ser2HSCR0 = sr.hscr0; +#ifdef CONFIG_SA1100_BITSY + if (machine_is_bitsy()) + clr_bitsy_egpio(EGPIO_BITSY_IR_ON); +#endif +#ifdef CONFIG_SA1100_COLLIE + sa1100_irda_set_power_collie(0); /* power off */ +#endif +#else + /* turn off interrupts */ + outb(0, io + UART_IER); +#endif + spin_unlock_irqrestore(&hardware_lock, flags); +} + +/* SECTION: Initialisation */ + +static int init_port(void) +{ + int retval; + + /* get I/O port access and IRQ line */ +#ifndef LIRC_ON_SA1100 + if (request_region(io, 8, LIRC_DRIVER_NAME) == NULL) { + printk(KERN_ERR LIRC_DRIVER_NAME + ": i/o port 0x%.4x already in use.\n", io); + return -EBUSY; + } +#endif + retval = request_irq(irq, sir_interrupt, IRQF_DISABLED, + LIRC_DRIVER_NAME, NULL); + if (retval < 0) { +# ifndef LIRC_ON_SA1100 + release_region(io, 8); +# endif + printk(KERN_ERR LIRC_DRIVER_NAME + ": IRQ %d already in use.\n", + irq); + return retval; + } +#ifndef LIRC_ON_SA1100 + printk(KERN_INFO LIRC_DRIVER_NAME + ": I/O port 0x%.4x, IRQ %d.\n", + io, irq); +#endif + + init_timer(&timerlist); + timerlist.function = sir_timeout; + timerlist.data = 0xabadcafe; + + return 0; +} + +static void drop_port(void) +{ + free_irq(irq, NULL); + del_timer_sync(&timerlist); +#ifndef LIRC_ON_SA1100 + release_region(io, 8); +#endif +} + +#ifdef LIRC_SIR_ACTISYS_ACT200L +/******************************************************/ +/* Crystal/Cirrus CS8130 IR transceiver, used in Actisys Act200L dongle */ +/* some code borrowed from Linux IRDA driver */ + +/* Regsiter 0: Control register #1 */ +#define ACT200L_REG0 0x00 +#define ACT200L_TXEN 0x01 /* Enable transmitter */ +#define ACT200L_RXEN 0x02 /* Enable receiver */ +#define ACT200L_ECHO 0x08 /* Echo control chars */ + +/* Register 1: Control register #2 */ +#define ACT200L_REG1 0x10 +#define ACT200L_LODB 0x01 /* Load new baud rate count value */ +#define ACT200L_WIDE 0x04 /* Expand the maximum allowable pulse */ + +/* Register 3: Transmit mode register #2 */ +#define ACT200L_REG3 0x30 +#define ACT200L_B0 0x01 /* DataBits, 0=6, 1=7, 2=8, 3=9(8P) */ +#define ACT200L_B1 0x02 /* DataBits, 0=6, 1=7, 2=8, 3=9(8P) */ +#define ACT200L_CHSY 0x04 /* StartBit Synced 0=bittime, 1=startbit */ + +/* Register 4: Output Power register */ +#define ACT200L_REG4 0x40 +#define ACT200L_OP0 0x01 /* Enable LED1C output */ +#define ACT200L_OP1 0x02 /* Enable LED2C output */ +#define ACT200L_BLKR 0x04 + +/* Register 5: Receive Mode register */ +#define ACT200L_REG5 0x50 +#define ACT200L_RWIDL 0x01 /* fixed 1.6us pulse mode */ + /*.. other various IRDA bit modes, and TV remote modes..*/ + +/* Register 6: Receive Sensitivity register #1 */ +#define ACT200L_REG6 0x60 +#define ACT200L_RS0 0x01 /* receive threshold bit 0 */ +#define ACT200L_RS1 0x02 /* receive threshold bit 1 */ + +/* Register 7: Receive Sensitivity register #2 */ +#define ACT200L_REG7 0x70 +#define ACT200L_ENPOS 0x04 /* Ignore the falling edge */ + +/* Register 8,9: Baud Rate Dvider register #1,#2 */ +#define ACT200L_REG8 0x80 +#define ACT200L_REG9 0x90 + +#define ACT200L_2400 0x5f +#define ACT200L_9600 0x17 +#define ACT200L_19200 0x0b +#define ACT200L_38400 0x05 +#define ACT200L_57600 0x03 +#define ACT200L_115200 0x01 + +/* Register 13: Control register #3 */ +#define ACT200L_REG13 0xd0 +#define ACT200L_SHDW 0x01 /* Enable access to shadow registers */ + +/* Register 15: Status register */ +#define ACT200L_REG15 0xf0 + +/* Register 21: Control register #4 */ +#define ACT200L_REG21 0x50 +#define ACT200L_EXCK 0x02 /* Disable clock output driver */ +#define ACT200L_OSCL 0x04 /* oscillator in low power, medium accuracy mode */ + +static void init_act200(void) +{ + int i; + __u8 control[] = { + ACT200L_REG15, + ACT200L_REG13 | ACT200L_SHDW, + ACT200L_REG21 | ACT200L_EXCK | ACT200L_OSCL, + ACT200L_REG13, + ACT200L_REG7 | ACT200L_ENPOS, + ACT200L_REG6 | ACT200L_RS0 | ACT200L_RS1, + ACT200L_REG5 | ACT200L_RWIDL, + ACT200L_REG4 | ACT200L_OP0 | ACT200L_OP1 | ACT200L_BLKR, + ACT200L_REG3 | ACT200L_B0, + ACT200L_REG0 | ACT200L_TXEN | ACT200L_RXEN, + ACT200L_REG8 | (ACT200L_115200 & 0x0f), + ACT200L_REG9 | ((ACT200L_115200 >> 4) & 0x0f), + ACT200L_REG1 | ACT200L_LODB | ACT200L_WIDE + }; + + /* Set DLAB 1. */ + soutp(UART_LCR, UART_LCR_DLAB | UART_LCR_WLEN8); + + /* Set divisor to 12 => 9600 Baud */ + soutp(UART_DLM, 0); + soutp(UART_DLL, 12); + + /* Set DLAB 0. */ + soutp(UART_LCR, UART_LCR_WLEN8); + /* Set divisor to 12 => 9600 Baud */ + + /* power supply */ + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); + for (i = 0; i < 50; i++) + safe_udelay(1000); + + /* Reset the dongle : set RTS low for 25 ms */ + soutp(UART_MCR, UART_MCR_DTR|UART_MCR_OUT2); + for (i = 0; i < 25; i++) + udelay(1000); + + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); + udelay(100); + + /* Clear DTR and set RTS to enter command mode */ + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_OUT2); + udelay(7); + +/* send out the control register settings for 115K 7N1 SIR operation */ + for (i = 0; i < sizeof(control); i++) { + soutp(UART_TX, control[i]); + /* one byte takes ~1042 usec to transmit at 9600,8N1 */ + udelay(1500); + } + + /* back to normal operation */ + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); + udelay(50); + + udelay(1500); + soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB); + + /* Set DLAB 1. */ + soutp(UART_LCR, UART_LCR_DLAB | UART_LCR_WLEN7); + + /* Set divisor to 1 => 115200 Baud */ + soutp(UART_DLM, 0); + soutp(UART_DLL, 1); + + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + /* Set DLAB 0, 7 Bit */ + soutp(UART_LCR, UART_LCR_WLEN7); + + /* enable interrupts */ + soutp(UART_IER, sinp(UART_IER)|UART_IER_RDI); +} +#endif + +#ifdef LIRC_SIR_ACTISYS_ACT220L +/* Derived from linux IrDA driver (drivers/net/irda/actisys.c) + * Drop me a mail for any kind of comment: maxx@spaceboyz.net */ + +void init_act220(void) +{ + int i; + + /* DLAB 1 */ + soutp(UART_LCR, UART_LCR_DLAB|UART_LCR_WLEN7); + + /* 9600 baud */ + soutp(UART_DLM, 0); + soutp(UART_DLL, 12); + + /* DLAB 0 */ + soutp(UART_LCR, UART_LCR_WLEN7); + + /* reset the dongle, set DTR low for 10us */ + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_OUT2); + udelay(10); + + /* back to normal (still 9600) */ + soutp(UART_MCR, UART_MCR_DTR|UART_MCR_RTS|UART_MCR_OUT2); + + /* send RTS pulses until we reach 115200 + * i hope this is really the same for act220l/act220l+ */ + for (i = 0; i < 3; i++) { + udelay(10); + /* set RTS low for 10 us */ + soutp(UART_MCR, UART_MCR_DTR|UART_MCR_OUT2); + udelay(10); + /* set RTS high for 10 us */ + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); + } + + /* back to normal operation */ + udelay(1500); /* better safe than sorry ;) */ + + /* Set DLAB 1. */ + soutp(UART_LCR, UART_LCR_DLAB | UART_LCR_WLEN7); + + /* Set divisor to 1 => 115200 Baud */ + soutp(UART_DLM, 0); + soutp(UART_DLL, 1); + + /* Set DLAB 0, 7 Bit */ + /* The dongle doesn't seem to have any problems with operation + at 7N1 */ + soutp(UART_LCR, UART_LCR_WLEN7); + + /* enable interrupts */ + soutp(UART_IER, UART_IER_RDI); +} +#endif + +static int init_lirc_sir(void) +{ + int retval; + + init_waitqueue_head(&lirc_read_queue); + retval = init_port(); + if (retval < 0) + return retval; + init_hardware(); + printk(KERN_INFO LIRC_DRIVER_NAME + ": Installed.\n"); + return 0; +} + +#ifdef MODULE + +int init_module(void) +{ + int retval; + + retval = init_chrdev(); + if (retval < 0) + return retval; + retval = init_lirc_sir(); + if (retval) { + drop_chrdev(); + return retval; + } + return 0; +} + +void cleanup_module(void) +{ + drop_hardware(); + drop_chrdev(); + drop_port(); + printk(KERN_INFO LIRC_DRIVER_NAME ": Uninstalled.\n"); +} + +#ifdef LIRC_SIR_TEKRAM +MODULE_DESCRIPTION("Infrared receiver driver for Tekram Irmate 210"); +MODULE_AUTHOR("Christoph Bartelmus"); +#elif defined(LIRC_ON_SA1100) +MODULE_DESCRIPTION("LIRC driver for StrongARM SA1100 embedded microprocessor"); +MODULE_AUTHOR("Christoph Bartelmus"); +#elif defined(LIRC_SIR_ACTISYS_ACT200L) +MODULE_DESCRIPTION("LIRC driver for Actisys Act200L"); +MODULE_AUTHOR("Karl Bongers"); +#elif defined(LIRC_SIR_ACTISYS_ACT220L) +MODULE_DESCRIPTION("LIRC driver for Actisys Act220L(+)"); +MODULE_AUTHOR("Jan Roemisch"); +#else +MODULE_DESCRIPTION("Infrared receiver driver for SIR type serial ports"); +MODULE_AUTHOR("Milan Pikula"); +#endif +MODULE_LICENSE("GPL"); + +#ifdef LIRC_ON_SA1100 +module_param(irq, int, 0444); +MODULE_PARM_DESC(irq, "Interrupt (16)"); +#else +module_param(io, int, 0444); +MODULE_PARM_DESC(io, "I/O address base (0x3f8 or 0x2f8)"); + +module_param(irq, int, 0444); +MODULE_PARM_DESC(irq, "Interrupt (4 or 3)"); + +module_param(threshold, int, 0444); +MODULE_PARM_DESC(threshold, "space detection threshold (3)"); +#endif + +module_param(debug, bool, 0644); +MODULE_PARM_DESC(debug, "Enable debugging messages"); + +EXPORT_NO_SYMBOLS; + +#endif /* MODULE */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_sir/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_sir/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_SIR) += lirc_sir.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_cmdir/lirc_cmdir.h +++ linux-2.6.28/ubuntu/lirc/lirc_cmdir/lirc_cmdir.h @@ -0,0 +1,27 @@ +/* $Id: lirc_cmdir.h,v 1.3 2007/09/27 19:47:20 lirc Exp $ */ + +/* + * lirc_cmdir.h + */ + +#ifndef LIRC_CMDIR_H +#define LIRC_CMDIR_H + +#define ON 1 +#define OFF 0 + +/* transmitter channel control */ +#define MAX_CHANNELS 32 + +/* CommandIR control codes */ +#define MCU_CTRL_SIZE 3 +#define FREQ_HEADER 2 +#define TX_HEADER 7 +#define TX_HEADER_NEW 8 + +extern int cmdir_write(unsigned char *buffer, int count, + void *callback_fct, int u); +extern ssize_t cmdir_read(unsigned char *buffer, size_t count); +extern int set_tx_channels(unsigned int next_tx); + +#endif --- linux-2.6.28.orig/ubuntu/lirc/lirc_cmdir/lirc_cmdir.c +++ linux-2.6.28/ubuntu/lirc/lirc_cmdir/lirc_cmdir.c @@ -0,0 +1,613 @@ +/* $Id: lirc_cmdir.c,v 1.9 2008/01/13 11:13:49 lirc Exp $ */ + +/* + * lirc_cmdir.c - Driver for InnovationOne's COMMANDIR USB Transceiver + * + * This driver requires the COMMANDIR hardware driver, available at + * http://www.commandir.com/. + * + * Copyright (C) 2005 InnovationOne - Evelyn Yeung + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + */ + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18) +#error "**********************************************************" +#error " Sorry, this driver needs kernel version 2.2.18 or higher " +#error "**********************************************************" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lirc.h" +#include "lirc_dev/lirc_dev.h" +#include "kcompat.h" +#include "lirc_cmdir.h" + +static int debug; +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG fmt, ## args); \ + } while (0) + +struct lirc_cmdir { + int features; +}; + +struct lirc_cmdir hardware = { + ( + /* LIRC_CAN_SET_SEND_DUTY_CYCLE| */ + LIRC_CAN_SET_SEND_CARRIER| + LIRC_CAN_SEND_PULSE| + LIRC_CAN_SET_TRANSMITTER_MASK| + LIRC_CAN_REC_MODE2) + , +}; + +#define LIRC_DRIVER_NAME "lirc_cmdir" +#define RBUF_LEN 256 +#define WBUF_LEN 256 +#define MAX_PACKET 64 + +static struct lirc_buffer rbuf; +static lirc_t wbuf[WBUF_LEN]; +static unsigned char cmdir_char[4*WBUF_LEN]; +static unsigned char write_control[MCU_CTRL_SIZE]; +static unsigned int last_mc_time; +static int usb_status = ON; +static unsigned char signal_num; +char timerval; + +unsigned int freq = 38000; +/* unsigned int duty_cycle = 50; */ + + +#ifndef MAX_UDELAY_MS +#define MAX_UDELAY_US 5000 +#else +#define MAX_UDELAY_US (MAX_UDELAY_MS*1000) +#endif + +static inline void safe_udelay(unsigned long usecs) +{ + while (usecs > MAX_UDELAY_US) { + udelay(MAX_UDELAY_US); + usecs -= MAX_UDELAY_US; + } + udelay(usecs); +} + +static unsigned int get_time_value(unsigned int firstint, + unsigned int secondint, unsigned char overflow) +{ /* get difference between two timestamps from MCU */ + unsigned int t_answer = 0; + + if (secondint > firstint) { + t_answer = secondint - firstint + overflow*65536; + } else { + if (overflow > 0) + t_answer = (65536 - firstint) + secondint + + (overflow - 1) * 65536; + else + t_answer = (65536 - firstint) + secondint; + } + + /* clamp to long signal */ + if (t_answer > 16000000) + t_answer = PULSE_MASK; + + return t_answer; +} + + +static int set_use_inc(void *data) +{ + /* Init read buffer. */ + if (lirc_buffer_init(&rbuf, sizeof(lirc_t), RBUF_LEN) < 0) + return -ENOMEM; + + MOD_INC_USE_COUNT; + return 0; +} + +static void set_use_dec(void *data) +{ + lirc_buffer_free(&rbuf); + MOD_DEC_USE_COUNT; +} + + +static void usb_error_handle(int retval) +{ + switch (retval) { + case -ENODEV: + /* device has been unplugged */ + if (usb_status == ON) { + usb_status = OFF; + printk(LIRC_DRIVER_NAME ": device is unplugged\n"); + } + break; + default: + printk(LIRC_DRIVER_NAME ": usb error = %d\n", retval); + break; + } +} + +static int write_to_usb(unsigned char *buffer, int count, int time_elapsed) +{ + int write_return; + + write_return = cmdir_write(buffer, count, NULL, time_elapsed); + if (write_return != count) { + usb_error_handle(write_return); + } else { + if (usb_status == OFF) { + printk(LIRC_DRIVER_NAME ": device is now plugged in\n"); + usb_status = ON; + } + } + return write_return; +} + +static void set_freq(void) +{ + /* float tempfreq = 0.0; */ + int write_return; + + /* + * Can't use floating point in 2.6 kernel! + * May be some loss of precision + */ + timerval = (1000000 / freq) / 2; + write_control[0] = FREQ_HEADER; + write_control[1] = timerval; + write_control[2] = 0; + write_return = write_to_usb(write_control, MCU_CTRL_SIZE, 0); + if (write_return == MCU_CTRL_SIZE) + printk(LIRC_DRIVER_NAME ": freq set to %dHz\n", freq); + else + printk(LIRC_DRIVER_NAME ": freq unchanged\n"); + +} + +static int cmdir_convert_RX(unsigned char *orig_rxbuffer) +{ + unsigned char tmp_char_buffer[80]; + unsigned int tmp_int_buffer[20]; + unsigned int final_data_buffer[20]; + unsigned int num_data_values = 0; + unsigned char num_data_bytes = 0; + unsigned int orig_index = 0; + int i; + + for (i = 0; i < 80; i++) + tmp_char_buffer[i] = 0; + for (i = 0; i < 20; i++) + tmp_int_buffer[i] = 0; + + /* + * get number of data bytes that follow the control bytes + * (NOT including them) + */ + num_data_bytes = orig_rxbuffer[1]; + + /* check if num_bytes is multiple of 3; if not, error */ + if (num_data_bytes % 3 > 0) + return -1; + if (num_data_bytes > 60) + return -3; + if (num_data_bytes < 3) + return -2; + + /* + * get number of ints to be returned; num_data_bytes does + * NOT include control bytes + */ + num_data_values = num_data_bytes/3; + + for (i = 0; i < num_data_values; i++) { + tmp_char_buffer[i*4] = orig_rxbuffer[(i+1)*3]; + tmp_char_buffer[i*4+1] = orig_rxbuffer[(i+1)*3+1]; + tmp_char_buffer[i*4+2] = 0; + tmp_char_buffer[i*4+3] = 0; + } + + /* convert to int array */ + memcpy((unsigned char *)tmp_int_buffer, tmp_char_buffer, + (num_data_values*4)); + + if (orig_rxbuffer[5] < 255) { + /* space */ + final_data_buffer[0] = get_time_value(last_mc_time, + tmp_int_buffer[0], + orig_rxbuffer[5]); + } else { /* is pulse */ + final_data_buffer[0] = get_time_value(last_mc_time, + tmp_int_buffer[0], + 0); + final_data_buffer[0] |= PULSE_BIT; + } + for (i = 1; i < num_data_values; i++) { + /* + * index of orig_rxbuffer that corresponds to + * overflow/pulse/space + */ + orig_index = (i + 1)*3 + 2; + if (orig_rxbuffer[orig_index] < 255) { + final_data_buffer[i] = + get_time_value(tmp_int_buffer[i - 1], + tmp_int_buffer[i], + orig_rxbuffer[orig_index]); + } else { + final_data_buffer[i] = + get_time_value(tmp_int_buffer[i - 1], + tmp_int_buffer[i], + 0); + final_data_buffer[i] |= PULSE_BIT; + } + } + last_mc_time = tmp_int_buffer[num_data_values - 1]; + + if (lirc_buffer_full(&rbuf)) { + printk(KERN_ERR LIRC_DRIVER_NAME ": lirc_buffer is full\n"); + return -EOVERFLOW; + } + lirc_buffer_write_n(&rbuf, (char *)final_data_buffer, num_data_values); + + return 0; +} + + +static int usb_read_once(void) +{ + int read_retval = 0; + int conv_retval = 0; + unsigned char read_buffer[MAX_PACKET]; + int i = 0; + int tooFull = 5; /* read up to 5 packets */ + + for (i = 0; i < MAX_PACKET; i++) + read_buffer[i] = 0; + + while (tooFull--) { + read_retval = cmdir_read(read_buffer, MAX_PACKET); + /* Loop until we unload the data build-up */ + if (read_buffer[1] < 60) + tooFull = 0; + if (!(read_retval == MAX_PACKET)) { + if (read_retval == -ENODEV) { + if (usb_status == ON) { + printk(KERN_ALERT LIRC_DRIVER_NAME + ": device is unplugged\n"); + usb_status = OFF; + } + } else { + /* supress errors */ + printk(KERN_ALERT LIRC_DRIVER_NAME + ": usb error on read = %d\n", + read_retval); + return -ENODATA; + } + dprintk("Error 3\n"); + return -ENODATA; + } else { + if (usb_status == OFF) { + usb_status = ON; + printk(LIRC_DRIVER_NAME + ": device is now plugged in\n"); + } + } + + if (read_buffer[0] & 0x08) { + conv_retval = cmdir_convert_RX(read_buffer); + if (conv_retval == 0) { + if (!tooFull) + return 0; + else + dprintk("Looping for more data...\n"); + } else { + dprintk("Error 2: %d\n", (int)conv_retval); + return -ENODATA; + } + } else { + /* There really is no data in their buffer */ + dprintk("Empty RX Buffer!\n"); + return -ENODATA; + } + } + return -1; +} + +int add_to_buf(void *data, struct lirc_buffer *buf) +{ + return usb_read_once(); +} + + +static ssize_t lirc_write(struct file *file, const char *buf, + size_t n, loff_t *ppos) +{ + int i, count; + unsigned int mod_signal_length = 0; + unsigned int time_elapse = 0; + unsigned int total_time_elapsed = 0; + unsigned int num_bytes_already_sent = 0; + unsigned int hibyte = 0; + unsigned int lobyte = 0; + int cmdir_cnt = 0; + unsigned int wait_this = 0; + struct timeval start_time; + struct timeval end_time; + unsigned int real_time_elapsed = 0; + + /* save the time we started the write: */ + do_gettimeofday(&start_time); + + if (n % sizeof(lirc_t)) + return -EINVAL; + + count = n/sizeof(lirc_t); + if (count > WBUF_LEN || count % 2 == 0) + return -EINVAL; + if (copy_from_user(wbuf, buf, n)) + return -EFAULT; + + /* + * the first time we have to flag that this is the start of a new + * signal otherwise COMMANDIR may receive 2 back-to-back pulses & + * invert the signal + */ + cmdir_char[0] = TX_HEADER_NEW; + signal_num++; + cmdir_char[1] = signal_num; + cmdir_cnt = 2; + for (i = 0; i < count; i++) { + /* conversion to number of modulation frequency pulse edges */ + mod_signal_length = wbuf[i] >> 3; + /* + * account for minor rounding errors - + * calculate length from this: + */ + time_elapse += mod_signal_length * timerval; + + hibyte = mod_signal_length / 256; + lobyte = mod_signal_length % 256; + cmdir_char[cmdir_cnt+1] = lobyte; + cmdir_char[cmdir_cnt] = hibyte; + cmdir_cnt += 2; + + /* write data to usb if full packet is collected */ + if (cmdir_cnt % MAX_PACKET == 0) { + write_to_usb(cmdir_char, MAX_PACKET, time_elapse); + + total_time_elapsed += time_elapse; + + num_bytes_already_sent += MAX_PACKET; + time_elapse = 0; + + if ((i + 1) < count) { + /* still more to send: */ + cmdir_char[0] = TX_HEADER; /* Next Packet */ + cmdir_char[1] = signal_num; + cmdir_cnt = 2; /* reset the count */ + } + } + } + + /* send last chunk of data */ + if (cmdir_cnt > 0) { + total_time_elapsed += time_elapse; + write_to_usb(cmdir_char, cmdir_cnt, time_elapse); + } + /* XXX ERS remove all this? */ + /* + * we need to _manually delay ourselves_ to remain backwards + * compatible with LIRC and prevent our queue buffer from overflowing. + * Queuing in this driver is about instant, and send_start for example + * will fill it up quickly and prevent send_stop from taking immediate + * effect. + */ + dprintk("Total elapsed time is: %d. \n", total_time_elapsed); + do_gettimeofday(&end_time); + /* + * udelay for the difference between endtime and + * start + total_time_elapsed + */ + if (start_time.tv_usec < end_time.tv_usec) + real_time_elapsed = (end_time.tv_usec - start_time.tv_usec); + else + real_time_elapsed = ((end_time.tv_usec + 1000000) - + start_time.tv_usec); + dprintk("Real time elapsed was %u.\n", real_time_elapsed); + if (real_time_elapsed < (total_time_elapsed - 1000)) + wait_this = total_time_elapsed - real_time_elapsed - 1000; + +#if 0 /* enable this for backwards compatibility */ + safe_udelay(wait_this); +#endif + + return(n); +} + + +static int lirc_ioctl(struct inode *node, struct file *filep, unsigned int cmd, + unsigned long arg) +{ + int result; + unsigned long value; + unsigned int ivalue; + unsigned int multiplier = 1; + unsigned int mask = 0; + int i; + + switch (cmd) { + case LIRC_SET_TRANSMITTER_MASK: + if (!(hardware.features&LIRC_CAN_SET_TRANSMITTER_MASK)) + return -ENOIOCTLCMD; + result = get_user(ivalue, (unsigned int *) arg); + if (result) + return result; + for (i = 0; i < MAX_CHANNELS; i++) { + multiplier = multiplier * 0x10; + mask |= multiplier; + } + if (ivalue >= mask) + return MAX_CHANNELS; + set_tx_channels(ivalue); + return 0; + break; + + case LIRC_GET_SEND_MODE: + if (!(hardware.features & LIRC_CAN_SEND_MASK)) + return -ENOIOCTLCMD; + + result = put_user(LIRC_SEND2MODE + (hardware.features & LIRC_CAN_SEND_MASK), + (unsigned long *) arg); + if (result) + return result; + break; + + case LIRC_SET_SEND_MODE: + if (!(hardware.features&LIRC_CAN_SEND_MASK)) + return -ENOIOCTLCMD; + + result = get_user(value, (unsigned long *)arg); + if (result) + return result; + break; + + case LIRC_GET_LENGTH: + return -ENOSYS; + break; + + case LIRC_SET_SEND_DUTY_CYCLE: + dprintk(KERN_WARNING LIRC_DRIVER_NAME + ": SET_SEND_DUTY_CYCLE\n"); + + if (!(hardware.features&LIRC_CAN_SET_SEND_DUTY_CYCLE)) + return -ENOIOCTLCMD; + + result = get_user(ivalue, (unsigned int *)arg); + if (result) + return result; + if (ivalue <= 0 || ivalue > 100) + return -EINVAL; + + /* TODO: */ + dprintk(LIRC_DRIVER_NAME + ": set_send_duty_cycle not yet supported\n"); + + return 0; + break; + + case LIRC_SET_SEND_CARRIER: + dprintk(KERN_WARNING LIRC_DRIVER_NAME ": SET_SEND_CARRIER\n"); + + if (!(hardware.features & LIRC_CAN_SET_SEND_CARRIER)) + return -ENOIOCTLCMD; + + result = get_user(ivalue, (unsigned int *)arg); + if (result) + return result; + if (ivalue > 500000 || ivalue < 24000) + return -EINVAL; + if (ivalue != freq) { + freq = ivalue; + set_freq(); + } + return 0; + break; + + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static struct file_operations lirc_fops = { + .write = lirc_write, +}; + +static struct lirc_plugin plugin = { + .name = LIRC_DRIVER_NAME, + .minor = -1, + .code_length = 1, + .sample_rate = 20, + .data = NULL, + .add_to_buf = add_to_buf, + .get_queue = NULL, + .rbuf = &rbuf, + .set_use_inc = set_use_inc, + .set_use_dec = set_use_dec, + .ioctl = lirc_ioctl, + .fops = &lirc_fops, + .dev = NULL, + .owner = THIS_MODULE, +}; + +#ifdef MODULE + +MODULE_AUTHOR("Evelyn Yeung, Matt Bodkin"); +MODULE_DESCRIPTION("InnovationOne driver for " + "CommandIR USB infrared transceiver"); +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif + +module_param(debug, bool, 0644); +MODULE_PARM_DESC(debug, "Enable debugging messages"); + +#ifndef KERNEL_2_5 +EXPORT_NO_SYMBOLS; +#endif + +int init_module(void) +{ + plugin.features = hardware.features; + plugin.minor = lirc_register_plugin(&plugin); + if (plugin.minor < 0) { + printk(KERN_ERR LIRC_DRIVER_NAME + ": register_chrdev failed!\n"); + return -EIO; + } + set_freq(); + return 0; +} + +void cleanup_module(void) +{ + lirc_unregister_plugin(plugin.minor); + printk(KERN_INFO LIRC_DRIVER_NAME ": module removed\n"); +} + +#endif + + --- linux-2.6.28.orig/ubuntu/lirc/lirc_cmdir/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_cmdir/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_CMDIR) += lirc_cmdir.o commandir.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_cmdir/commandir.h +++ linux-2.6.28/ubuntu/lirc/lirc_cmdir/commandir.h @@ -0,0 +1,41 @@ +/* + * commandir.h + */ + +#define ASCII0 48 + +/* transmitter channel control */ +#define MAX_DEVICES 8 +#define MAX_CHANNELS 32 +#define TX1_ENABLE 0x80 +#define TX2_ENABLE 0x40 +#define TX3_ENABLE 0x20 +#define TX4_ENABLE 0x10 + +/* command types */ +#define cNothing 0 +#define cRESET 1 +#define cFLASH 2 +#define cLCD 3 +#define cRX 4 + +/* CommandIR control codes */ +#define MCU_CTRL_SIZE 3 +#define FREQ_HEADER 2 +#define RESET_HEADER 3 +#define FLASH_HEADER 4 +#define LCD_HEADER 5 +#define TX_HEADER 7 +#define TX_HEADER_NEW 8 + +/* Queue buffering constants */ +#define SEND_IDLE 0 +#define SEND_ACTIVE 1 + +#define QUEUELENGTH 256 + +extern int cmdir_write(unsigned char *buffer, int count, + void *callback_fct, int u); +extern ssize_t cmdir_read(unsigned char *buffer, size_t count); +extern int set_tx_channels(unsigned int next_tx); + --- linux-2.6.28.orig/ubuntu/lirc/lirc_cmdir/commandir.c +++ linux-2.6.28/ubuntu/lirc/lirc_cmdir/commandir.c @@ -0,0 +1,1521 @@ + +/* + * + * Hardware Driver for COMMANDIR USB Transceiver + * 2005-2007 InnovationOne - Matt Bodkin, Evelyn Yeung + * + * Version 1.4.2 + * For 2.4.* or 2.6.* kernel versions + * Based on the USB Skeleton driver, versions 0.7 and 2.0 + * + */ + +#include +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) +#include +#else +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include "commandir.h" + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +#include +#include +#include +#include +#include +#include +#include +#else +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#include +#else +#include +#endif +#endif + +#define DRIVER_VERSION "v1.1.2" +#define DRIVER_AUTHOR "Evelyn Yeung, InnovationOne" +#define DRIVER_DESC "CommandIR USB Transceiver Driver" + +#define USB_CMDIR_VENDOR_ID 0x10c4 +#define USB_CMDIR_PRODUCT_ID 0x0003 +#define USB_CMDIR_MINOR_BASE 192 + +/* table of devices that work with this driver */ +static struct usb_device_id cmdir_table [] = +{ + { USB_DEVICE(USB_CMDIR_VENDOR_ID, USB_CMDIR_PRODUCT_ID) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, cmdir_table); + +static int cmdir_open(struct inode *inode, struct file *file); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +static void *cmdir_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id); +static int cmdir_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); +static void cmdir_disconnect(struct usb_device *dev, void *ptr); +#else +static int cmdir_probe(struct usb_interface *interface, + const struct usb_device_id *id); +static void cmdir_disconnect(struct usb_interface *interface); +#endif +static int cmdir_release(struct inode *inode, struct file *file); +static int cmdir_check(int device_num); +static void init_cmdir_var(int device_num); +static void reset_cmdir(int device_num); +static void update_cmdir_string(int device_num); +static void print_cmdir(int device_num); +static ssize_t cmdir_file_read(struct file *file, char *buffer, + size_t count, loff_t *ppos); +ssize_t cmdir_read(unsigned char *buffer, size_t count); +static ssize_t cmdir_file_write(struct file *file, const char *buffer, + size_t count, loff_t *ppos); +int cmdir_write(unsigned char *buffer, int count, void *callback_fct, int u); +int write_core(unsigned char *buffer, int count, + void *callback_fct, int device_num); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +static void cmdir_write_bulk_callback(struct urb *urb); +#else +static void cmdir_write_bulk_callback(struct urb *urb, struct pt_regs *regs); +#endif +int set_tx_channels(unsigned int next_tx); + +int add_cmdir_queue(unsigned char *buffer, int count, + void *callback_vct, int usecdelay); +int cmdir_write_queue(unsigned char *buffer, int count, void *callback_vct); +int send_queue(void); +int wait_to_tx(int usecs); + +/* circular packet queue */ +unsigned char ourbuffers[QUEUELENGTH][64]; +int waitusecs[QUEUELENGTH]; +int ourbufferlengths[QUEUELENGTH]; +int nexttosend; +int nexttofill; +int send_status = SEND_IDLE; +int last_tx_sec; +int last_tx_usec; + +static int curTXFill; +struct timeval tp; + +int debug_commandir; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) + +/* Structure to hold all of our device specific stuff */ +struct usb_skel { + struct usb_device *udev; /* save off the usb device pointer */ + struct usb_interface *interface; /* the interface for this device */ + devfs_handle_t devfs; /* devfs device node */ + unsigned char minor; /* the starting minor number */ + unsigned char num_ports; /* the number of ports this device has */ + char num_interrupt_in; /* number of interrupt in endpoints */ + char num_bulk_in; /* number of bulk in endpoints */ + char num_bulk_out; /* number of bulk out endpoints */ + + unsigned char *bulk_in_buffer; /* the buffer to receive data */ + int bulk_in_size; /* the size of the receive buffer */ + __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */ + + unsigned char *bulk_out_buffer; /* the buffer to send data */ + int bulk_out_size; /* the size of the send buffer */ + struct urb *write_urb; /* the urb used to send data */ + __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */ + + struct tq_struct tqueue; /* task queue for line discipline waking up */ + int open_count; /* number of times this port has been opened */ + struct semaphore sem; /* locks this structure */ +}; + +extern devfs_handle_t usb_devfs_handle; /* the global usb devfs handle */ + +/* array of pointers to our devices that are currently connected */ +static struct usb_skel *minor_table[MAX_DEVICES]; +/* lock to protect the minor_table structure */ +static DECLARE_MUTEX(minor_table_mutex); + +static struct file_operations cmdir_fops = { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) + .owner = THIS_MODULE, +#endif /* kernel < 2.6.16 */ +#endif /* kernel >= 2.6.0 */ + .read = cmdir_file_read, + .write = cmdir_file_write, + .ioctl = cmdir_ioctl, + .open = cmdir_open, + .release = cmdir_release, +}; + +/* usb specific object needed to register this driver with the usb subsystem */ +static struct usb_driver cmdir_driver = { + .name = "commandir", + .probe = cmdir_probe, + .disconnect = cmdir_disconnect, + .fops = &cmdir_fops, + .minor = USB_CMDIR_MINOR_BASE, + .id_table = cmdir_table, +}; + +#else /* kernel >= 2.6 */ + +/* Structure to hold all of our device specific stuff */ +struct usb_skel { + struct usb_device *udev; /* the usb device for this device */ + struct usb_interface *interface; /* the interface for this device */ + unsigned char *bulk_in_buffer; /* the buffer to receive data */ + size_t bulk_in_size; /* the size of the receive buffer */ + __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */ + __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */ + struct kref kref; +}; +#define to_skel_dev(d) container_of(d, struct usb_skel, kref) + +static struct file_operations cmdir_fops = { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) + .owner = THIS_MODULE, +#endif /* kernel < 2.6.16 */ +#endif /* kernel >= 2.6.0 */ + .read = cmdir_file_read, + .write = cmdir_file_write, + .open = cmdir_open, + .release = cmdir_release, +}; + +/* usb class driver info in order to get a minor number from the usb core, + * and to have the device registered with devfs and the driver core */ +static struct usb_class_driver cmdir_class = { + .name = "usb/commandir%d", + .fops = &cmdir_fops, + /* .mode = S_IFCHR | S_IRUSR | S_IWUSR | + * S_IRGRP | S_IWGRP | S_IROTH, */ + .minor_base = USB_CMDIR_MINOR_BASE, +}; + +static struct usb_driver cmdir_driver = { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) + .owner = THIS_MODULE, +#endif /* kernel < 2.6.16 */ +#endif /* kernel >= 2.6.0 */ + .name = "commandir", + .probe = cmdir_probe, + .disconnect = cmdir_disconnect, + .id_table = cmdir_table, +}; + +#endif /* kernel < 2.6.0 */ + +static int lcd_device; +static int rx_device; +static int def_device; + +#define DEFAULT_TRANSMITTERS 0x0F +static unsigned int transmitters = DEFAULT_TRANSMITTERS; +static unsigned int next_transmitters = DEFAULT_TRANSMITTERS; + +#define CMDIR_VAR_LEN 68 +static char cmdir_var[] = +"COMMANDIRx:\n TX Enabled: 1, 2, 3, 4\n RX: commandirx\n LCD: commandirx"; + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +static inline void cmdir_delete(struct usb_skel *dev) +{ + minor_table[dev->minor] = NULL; + if (dev->bulk_in_buffer != NULL) + kfree(dev->bulk_in_buffer); + if (dev->bulk_out_buffer != NULL) + kfree(dev->bulk_out_buffer); + if (dev->write_urb != NULL) + usb_free_urb(dev->write_urb); + kfree(dev); +} +#else +static void cmdir_delete(struct kref *kref) +{ + struct usb_skel *dev = to_skel_dev(kref); + + usb_put_dev(dev->udev); + kfree(dev->bulk_in_buffer); + kfree(dev); +} +#endif + +static int __init usb_cmdir_init(void) +{ + int result; + + /* register this driver with the USB subsystem */ + result = usb_register(&cmdir_driver); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) + if (result < 0) { + err("usb_register failed for the "__FILE__ + " driver. Error number %d", result); + return -1; + } + + info(DRIVER_DESC " " DRIVER_VERSION); + + return 0; +#else + if (result) + err("usb_register failed. Error number %d", result); + + return result; +#endif +} + +static int cmdir_open(struct inode *inode, struct file *file) +{ + struct usb_skel *dev; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 0) + struct usb_interface *interface; +#endif + int subminor; + int retval = 0; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) + subminor = MINOR(inode->i_rdev) - USB_CMDIR_MINOR_BASE; + if ((subminor < 0) || (subminor >= MAX_DEVICES)) + return -ENODEV; + MOD_INC_USE_COUNT; + + /* lock our minor table and get our local data for this minor */ + down(&minor_table_mutex); + dev = minor_table[subminor]; + if (dev == NULL) { + up(&minor_table_mutex); + MOD_DEC_USE_COUNT; + return -ENODEV; + } + + down(&dev->sem); /* lock this device */ + up(&minor_table_mutex); /* unlock the minor table */ + ++dev->open_count; /* increment our usage count for the driver */ + file->private_data = dev; /* save object in file's private structure */ + up(&dev->sem); /* unlock this device */ + + return retval; +#else + subminor = iminor(inode); + interface = usb_find_interface(&cmdir_driver, subminor); + if (!interface) { + err("%s - error, can't find device for minor %d", + __FUNCTION__, subminor); + retval = -ENODEV; + goto exit; + } + + dev = usb_get_intfdata(interface); + if (!dev) { + retval = -ENODEV; + goto exit; + } + + kref_get(&dev->kref); /* increment our usage count for the device */ + file->private_data = dev; /* save object in file's private structure */ + +exit: + return retval; +#endif +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +static void *cmdir_probe(struct usb_device *udev, unsigned int ifnum, + const struct usb_device_id *id) +{ + struct usb_skel *dev = NULL; + struct usb_interface *interface; + struct usb_interface_descriptor *iface_desc; + struct usb_endpoint_descriptor *endpoint; + int minor; + int buffer_size; + int i; + char name[10]; + + /* See if the device offered us matches what we can accept */ + if ((udev->descriptor.idVendor != USB_CMDIR_VENDOR_ID) || + (udev->descriptor.idProduct != USB_CMDIR_PRODUCT_ID)) + return NULL; + + /* select a "subminor" number (part of a minor number) */ + down(&minor_table_mutex); + for (minor = 0; minor < MAX_DEVICES; ++minor) { + if (minor_table[minor] == NULL) + break; + } + if (minor >= MAX_DEVICES) { + info("Too many devices plugged in, cannot handle this device."); + goto exit; + } + + /* allocate memory for our device state and intialize it */ + dev = kmalloc(sizeof(struct usb_skel), GFP_KERNEL); + if (dev == NULL) { + err("Out of memory"); + goto exit; + } + memset(dev, 0x00, sizeof(*dev)); + minor_table[minor] = dev; + + interface = &udev->actconfig->interface[ifnum]; + + init_MUTEX(&dev->sem); + dev->udev = udev; + dev->interface = interface; + dev->minor = minor; + + /* set up and check the endpoint information */ + iface_desc = &interface->altsetting[0]; + for (i = 0; i < iface_desc->bNumEndpoints; ++i) { + endpoint = &iface_desc->endpoint[i]; + + if ((endpoint->bEndpointAddress & 0x80) && + ((endpoint->bmAttributes & 3) == 0x02)) { + /* we found a bulk in endpoint */ + buffer_size = endpoint->wMaxPacketSize; + dev->bulk_in_size = buffer_size; + dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; + dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); + if (!dev->bulk_in_buffer) { + err("Couldn't allocate bulk_in_buffer"); + goto error; + } + } + + if (((endpoint->bEndpointAddress & 0x80) == 0x00) && + ((endpoint->bmAttributes & 3) == 0x02)) { + /* we found a bulk out endpoint */ + dev->write_urb = usb_alloc_urb(0); + if (!dev->write_urb) { + err("No free urbs available"); + goto error; + } + buffer_size = endpoint->wMaxPacketSize; + dev->bulk_out_size = buffer_size; + dev->bulk_out_endpointAddr = endpoint->bEndpointAddress; + dev->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL); + if (!dev->bulk_out_buffer) { + err("Couldn't allocate bulk_out_buffer"); + goto error; + } + FILL_BULK_URB(dev->write_urb, udev, + usb_sndbulkpipe(udev, + endpoint->bEndpointAddress), + dev->bulk_out_buffer, buffer_size, + cmdir_write_bulk_callback, dev); + } + } + + /* initialize the devfs node for this device and register it */ + sprintf(name, "commandir%d", dev->minor); + + dev->devfs = devfs_register(usb_devfs_handle, name, + DEVFS_FL_DEFAULT, USB_MAJOR, + USB_CMDIR_MINOR_BASE + dev->minor, + S_IFCHR | S_IRUSR | S_IWUSR | + S_IRGRP | S_IWGRP | S_IROTH, + &cmdir_fops, NULL); + + /* let the user know what node this device is now attached to */ + info("CommandIR USB device now attached to commandir%d", dev->minor); + + /* should reset just the one that was plugged in */ + reset_cmdir(minor); + + goto exit; + +error: + cmdir_delete(dev); + dev = NULL; + +exit: + up(&minor_table_mutex); + return dev; +} +#else +static int cmdir_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct usb_skel *dev = NULL; + struct usb_host_interface *iface_desc; + struct usb_endpoint_descriptor *endpoint; + size_t buffer_size; + + int i; + int retval = -ENOMEM; + int minor; + + /* allocate memory for our device state and initialize it */ + dev = kmalloc(sizeof(*dev), GFP_KERNEL); + if (dev == NULL) { + err("Out of memory"); + goto error; + } + memset(dev, 0x00, sizeof(*dev)); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 9) + kref_init(&dev->kref, cmdir_delete); +#else + kref_init(&dev->kref); +#endif + dev->udev = usb_get_dev(interface_to_usbdev(interface)); + dev->interface = interface; + + /* set up the endpoint information */ + /* use only the first bulk-in and bulk-out endpoints */ + iface_desc = interface->cur_altsetting; + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { + endpoint = &iface_desc->endpoint[i].desc; + + if (!dev->bulk_in_endpointAddr && + (endpoint->bEndpointAddress & USB_DIR_IN) && + ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_BULK)) { + /* we found a bulk in endpoint */ + buffer_size = endpoint->wMaxPacketSize; + dev->bulk_in_size = buffer_size; + dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; + dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); + if (!dev->bulk_in_buffer) { + err("Could not allocate bulk_in_buffer"); + goto error; + } + } + + if (!dev->bulk_out_endpointAddr && + !(endpoint->bEndpointAddress & USB_DIR_IN) && + ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_BULK)) { + /* we found a bulk out endpoint */ + dev->bulk_out_endpointAddr = endpoint->bEndpointAddress; + } + } + if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) { + err("Could not find both bulk-in and bulk-out endpoints"); + goto error; + } + + /* save our data pointer in this interface device */ + usb_set_intfdata(interface, dev); + + /* we can register the device now, as it is ready */ + retval = usb_register_dev(interface, &cmdir_class); + if (retval) { + /* something prevented us from registering this driver */ + err("Not able to get a minor for this device."); + usb_set_intfdata(interface, NULL); + goto error; + } + + /* check whether minor already includes base */ + minor = interface->minor; + if (minor >= USB_CMDIR_MINOR_BASE) + minor = minor-USB_CMDIR_MINOR_BASE; + + /* let the user know what node this device is now attached to */ + info("CommandIR USB device now attached to commandir%d", minor); + + reset_cmdir(minor); + + return 0; + +error: + if (dev) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 9) + kref_put(&dev->kref); +#else + kref_put(&dev->kref, cmdir_delete); +#endif + return retval; +} +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +static int cmdir_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct usb_skel *dev; + + dev = (struct usb_skel *)file->private_data; + + /* lock this object */ + down(&dev->sem); + + /* verify that the device wasn't unplugged */ + if (dev->udev == NULL) { + up(&dev->sem); + return -ENODEV; + } + + /* unlock the device */ + up(&dev->sem); + + /* return that we did not understand this ioctl call */ + return -ENOTTY; +} +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +static void cmdir_disconnect(struct usb_device *udev, void *ptr) +{ + struct usb_skel *dev; + int minor; + + dev = (struct usb_skel *)ptr; + + down(&minor_table_mutex); + down(&dev->sem); + + minor = dev->minor; + + /* remove our devfs node */ + devfs_unregister(dev->devfs); + + /* if the device is not opened, then we clean up right now */ + if (!dev->open_count) { + up(&dev->sem); + cmdir_delete(dev); + } else { + dev->udev = NULL; + up(&dev->sem); + } + + info("CommandIR #%d now disconnected", minor); + up(&minor_table_mutex); + + /* check if default RX device still exists */ + if (minor == rx_device) { + /* decrement until find next valid device */ + while (rx_device > 0) { + rx_device--; + if (cmdir_check(rx_device) == 0) break; + } + if (minor > 0) + info("Active Receiver is on CommandIR #%d", rx_device); + } + +} +#else +static void cmdir_disconnect(struct usb_interface *interface) +{ + struct usb_skel *dev; + int minor = interface->minor; + + /* prevent cmdir_open() from racing cmdir_disconnect() */ + lock_kernel(); + + dev = usb_get_intfdata(interface); + usb_set_intfdata(interface, NULL); + + /* give back our minor */ + usb_deregister_dev(interface, &cmdir_class); + + unlock_kernel(); + + /* decrement our usage count */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 9) + kref_put(&dev->kref); +#else + kref_put(&dev->kref, cmdir_delete); +#endif + + /* check whether minor already includes base */ + if (minor >= USB_CMDIR_MINOR_BASE) + minor = minor-USB_CMDIR_MINOR_BASE; + + info("CommandIR #%d now disconnected", minor); + + /* check if default RX device still exists */ + if (minor == rx_device) { + /* decrement until find next valid device */ + while (rx_device > 0) { + rx_device--; + if (cmdir_check(rx_device) == 0) + break; + } + if (minor > 0) + info("Active Receiver is on CommandIR #%d", rx_device); + } +} +#endif + +static int cmdir_release(struct inode *inode, struct file *file) +{ + struct usb_skel *dev; + int retval = 0; + + dev = (struct usb_skel *)file->private_data; + if (dev == NULL) + /*dbg(" - object is NULL");*/ + return -ENODEV; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) + + /* lock our minor table */ + down(&minor_table_mutex); + + /* lock our device */ + down(&dev->sem); + + if (dev->open_count <= 0) { + /*dbg(" - device not opened");*/ + retval = -ENODEV; + goto exit_not_opened; + } + + if (dev->udev == NULL) { + /* the device was unplugged before the file was released */ + /*dbg(" - device unplugged before file released");*/ + up(&dev->sem); + cmdir_delete(dev); + up(&minor_table_mutex); + MOD_DEC_USE_COUNT; + return 0; + } + + /* decrement our usage count for the device */ + --dev->open_count; + if (dev->open_count <= 0) { + /* shutdown any bulk writes that might be going on */ + usb_unlink_urb(dev->write_urb); + dev->open_count = 0; + } + + /* decrement our usage count for the module */ + MOD_DEC_USE_COUNT; + +exit_not_opened: + up(&dev->sem); + up(&minor_table_mutex); + + return retval; + +#else + /* decrement the count on our device */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 9) + kref_put(&dev->kref); +#else + kref_put(&dev->kref, cmdir_delete); +#endif + return retval; +#endif +} + +static void __exit usb_cmdir_exit(void) +{ + /* deregister this driver with the USB subsystem */ + usb_deregister(&cmdir_driver); + +} + +static int cmdir_check(int device_num) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) + if (minor_table[device_num] == NULL) + return -ENODEV; + return 0; +#else + struct usb_interface *interface; + + interface = usb_find_interface(&cmdir_driver, + USB_CMDIR_MINOR_BASE+device_num); + if (!interface) { + /* also check without adding base, for devfs */ + interface = usb_find_interface(&cmdir_driver, rx_device); + if (!interface) + return -ENODEV; + } + return 0; +#endif +} + +static void init_cmdir_var(int device_num) +{ + int i; + unsigned int multiplier = 1; + + for (i = 0; i < device_num; i++) + multiplier = multiplier*0x10; + transmitters |= multiplier * 0x0F; + next_transmitters = transmitters; + info("commandir%d reset", device_num); + return; +} + +static void reset_cmdir(int device_num) +{ + unsigned char ctrl_buffer[MCU_CTRL_SIZE]; + int retval; + int i; + + ctrl_buffer[0] = RESET_HEADER; + for (i = 1; i < MCU_CTRL_SIZE; i++) + ctrl_buffer[i] = 'j'; + retval = write_core(ctrl_buffer, MCU_CTRL_SIZE, NULL, device_num); + + init_cmdir_var(device_num); + print_cmdir(device_num); + + return; +} + +static void update_cmdir_string(int device_num) +{ + int next_comma = 0; + int next_pos = 25; + unsigned int multiplier; + int i; + + /* cmdir_var[] = "COMMANDIRx:\n" + * " TX Enabled: 1, 2, 3, 4\n" + * " RX: commandirx\n" + * " LCD: commandirx\n" */ + + cmdir_var[9] = ASCII0+device_num; + cmdir_var[50] = ASCII0+rx_device; + cmdir_var[67] = ASCII0+lcd_device; + + for (i = 25; i < 35; i++) + cmdir_var[i] = ' '; + + multiplier = 1; + for (i = 0; i < device_num; i++) + multiplier = multiplier*0x10; + + if (transmitters & (multiplier*0x01)) { + cmdir_var[next_pos] = '1'; + next_pos += 3; + next_comma++; + } + if (transmitters & (multiplier*0x02)) { + cmdir_var[next_pos] = '2'; + if (next_comma > 0) + cmdir_var[next_pos-2] = ','; + next_pos += 3; + next_comma++; + } + if (transmitters & (multiplier*0x04)) { + cmdir_var[next_pos] = '3'; + if (next_comma > 0) + cmdir_var[next_pos-2] = ','; + next_pos += 3; + next_comma++; + } + if (transmitters & (multiplier*0x08)) { + cmdir_var[next_pos] = '4'; + if (next_comma > 0) + cmdir_var[next_pos-2] = ','; + next_pos += 3; + next_comma++; + } + return; +} + +static void print_cmdir(int device_num) +{ + update_cmdir_string(device_num); + info("%s", cmdir_var); + return; +} + +static ssize_t cmdir_file_read(struct file *file, char *buffer, + size_t count, loff_t *ppos) +{ + int retval = 0; + int minor = 0; + struct usb_skel *dev; + + dev = (struct usb_skel *)file->private_data; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) + minor = dev->minor; +#else + minor = dev->interface->minor; + if (minor >= USB_CMDIR_MINOR_BASE) + minor = minor - USB_CMDIR_MINOR_BASE; +#endif + + if (((int)*ppos) == 0) { + update_cmdir_string(minor); + if (copy_to_user(buffer, cmdir_var, CMDIR_VAR_LEN)) + retval = -EFAULT; + else + retval = CMDIR_VAR_LEN; + return retval; + } else + return 0; +} + +/* Read data from CommandIR */ +ssize_t cmdir_read(unsigned char *buffer, size_t count) +{ + struct usb_skel *dev; + int retval = 0; + int len; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) + if (minor_table[rx_device] == NULL) + return -ENODEV; + dev = minor_table[rx_device]; + + /* lock this object */ + down(&dev->sem); + retval = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, + dev->bulk_in_endpointAddr), + dev->bulk_in_buffer, dev->bulk_in_size, &len, HZ*100); +#else + struct usb_interface *interface; + interface = usb_find_interface(&cmdir_driver, + USB_CMDIR_MINOR_BASE+rx_device); + if (!interface) { + /* also check without adding base, for devfs */ + interface = usb_find_interface(&cmdir_driver, rx_device); + if (!interface) + return -ENODEV; + } + dev = usb_get_intfdata(interface); + if (!dev) + return -ENODEV; + retval = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, + dev->bulk_in_endpointAddr), + dev->bulk_in_buffer, min(dev->bulk_in_size, count), + &len, HZ*10); +#endif + if (!retval) { + if (!memcpy(buffer, dev->bulk_in_buffer, len)) + retval = -EFAULT; + else { + /* current status of the TX buffer */ + curTXFill = buffer[2]; + retval = len; + } + } + /* suppress errors */ + /* + else { + err("Read from device failed, error %d",retval); + } + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) + /* unlock the device */ + up(&dev->sem); +#endif + /* printk(KERN_INFO "CommandIR Reporting TX buffer at %d bytes. \n", + * curTXFill); */ + return retval; +} +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +EXPORT_SYMBOL_NOVERS(cmdir_read); +#else +EXPORT_SYMBOL(cmdir_read); +#endif + +static ssize_t cmdir_file_write(struct file *file, const char *buffer, + size_t count, loff_t *ppos) +{ + int retval; + int i; + int equalsign = 0; + int changeType = 0; + unsigned char ctrl_buffer[MCU_CTRL_SIZE]; + char *local_buffer; + int minor; + + /* set as default - if non-specific error, + * won't keep calling this function */ + retval = count; + local_buffer = kmalloc(count, GFP_KERNEL); + + /* verify that we actually have some data to write */ + if (count == 0) { + err("Write request of 0 bytes"); + goto exit; + } + if (count > 64) { + err("Input too long"); + goto exit; + } + + /* copy the data from userspace into our local buffer */ + if (copy_from_user(local_buffer, buffer, count)) { + retval = -EFAULT; + goto exit; + } + + /* parse code */ + changeType = cNothing; + equalsign = 0; + for (i = 0; i < MCU_CTRL_SIZE; i++) + ctrl_buffer[i] = 'j'; + + for (i = 0; i < count; i++) { + switch (local_buffer[i]) { + case 'X': + case 'x': + if ((i > 0) && ((local_buffer[i - 1] == 'R') + || (local_buffer[i - 1] == 'r'))) + changeType = cRX; + break; + case 'S': + case 's': + if ((i > 1) && ((local_buffer[i - 1] == 'E') + || (local_buffer[i - 1] == 'e'))) { + if ((local_buffer[i-2] == 'R') + || (local_buffer[i-2] == 'r')) + changeType = cRESET; + } + break; + case 'L': + case 'l': + if ((i > 0) && ((local_buffer[i - 1] == 'F') + || (local_buffer[i - 1] == 'f'))) + changeType = cFLASH; + break; + case 'C': + case 'c': + if ((i > 0) && ((local_buffer[i - 1] == 'L') + || (local_buffer[i - 1] == 'l'))) + changeType = cLCD; + break; + case '=': + if (changeType != cNothing) + equalsign = i; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + if (equalsign > 0) { + minor = local_buffer[i] - ASCII0; + switch (changeType) { + case cRESET: + ctrl_buffer[0] = RESET_HEADER; + retval = write_core(ctrl_buffer, + MCU_CTRL_SIZE, + cmdir_write_bulk_callback, + minor); + if (retval != MCU_CTRL_SIZE) { + if (retval == -ENODEV) + err("Device %d " + "unplugged", minor); + else + err("Error on write to " + "%d", minor); + goto exit; + } else + retval = count; + init_cmdir_var(minor); + break; + case cFLASH: + ctrl_buffer[0] = FLASH_HEADER; + info("Flashing indicators on device %d", + minor); + retval = write_core(ctrl_buffer, + MCU_CTRL_SIZE, + cmdir_write_bulk_callback, + minor); + if (retval != MCU_CTRL_SIZE) { + if (retval == -ENODEV) + err("Device %d " + "unplugged", minor); + else + err("Error on write to " + "%d", minor); + goto exit; + } else + retval = count; + break; + case cRX: + rx_device = minor; + info("Default receiver set to %d", + minor); + break; + case cLCD: + lcd_device = minor; + info("commandir: Default LCD set to %d", + minor); + break; + default: + break; + } + } + break; + case ',': + equalsign = 0; + changeType = cNothing; + break; + default: + if ((equalsign > 0) && (local_buffer[i] > 32)) { + err("Non-numerical argument"); + goto exit; + } + break; + } + } + + if ((changeType != cNothing) && (equalsign == 0)) + err("No device specified"); + if (changeType == cNothing) + err("Unknown command"); + +exit: + kfree(local_buffer); + return retval; +} + +int cmdir_write(unsigned char *buffer, int count, + void *callback_fct, int usecdelay) +{ + /* Always add to queue, then send queue number + * no locks + * mbodkin, Sept 8, 2005 */ + int ret = 0; + if (debug_commandir == 1) { + do_gettimeofday(&tp); + printk(KERN_INFO "cmdir_write at %d\n", (int)tp.tv_usec); + } + ret = add_cmdir_queue(buffer, count, callback_fct, usecdelay); + + if (ret == -1) { + printk(KERN_INFO "cmdir_write returning 0\n"); + return 0; + } + return count; + +} +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +EXPORT_SYMBOL_NOVERS(cmdir_write); +#else +EXPORT_SYMBOL(cmdir_write); +#endif + +int add_cmdir_queue(unsigned char *buffer, int count, + void *callback_vct, int usecdelay) +{ + int ret = 0; + if ((nexttofill + 1) % (QUEUELENGTH - 1) == nexttosend) { + + /* our buffer is full */ + printk(KERN_INFO "Too many packets backlogged " + "in CommandIR Queue.\n"); + return -1; + } + /* go ahead and use this one: */ + memcpy(ourbuffers[nexttofill], buffer, count); + ourbufferlengths[nexttofill] = count; + waitusecs[nexttofill] = (usecdelay == 0) ? 10000 : usecdelay; + /* printk(KERN_INFO "Adding %d to queue at position %d.\n", + * count, nexttofill); */ + nexttofill = (nexttofill + 1) % (QUEUELENGTH - 1); + ret = nexttofill; + /* if (timer_running == 0) */ + send_queue(); /* fake it if the timer's not running */ + return ret; /* we accepted the full packet */ + +} + +int send_queue() +{ + int last_sent = 0; + int ret = 0; + if (debug_commandir == 1) { + do_gettimeofday(&tp); + printk(KERN_INFO "Send_queue() at %d\n", (int)tp.tv_usec); + } + /* initiate the send/callback routine if not already running. */ + if (send_status == SEND_IDLE) { + if (!(nexttofill == nexttosend)) { + /* start it up: */ + + last_sent = nexttosend - 1; + if (last_sent < 0) + last_sent = QUEUELENGTH - 1; + /* Final check - is it TIME to send this packet yet? */ + /* if (wait_to_tx(waitusecs[last_sent]) == 0) { */ + /* always send if there's room, + * otherwise wait until room */ + if (curTXFill < 190) { + if (debug_commandir == 1) { + do_gettimeofday(&tp); + printk(KERN_INFO "Sending packet data " + "at %d\n", (int)tp.tv_usec); + } + ret = cmdir_write_queue(ourbuffers[nexttosend], + ourbufferlengths[nexttosend], NULL); + if (ret <= 0) { + /* send failed - the device is either + * unplugged or full + * nexttosend = + * (nexttosend + 1) + * % (QUEUELENGTH - 1); */ + send_status = SEND_IDLE; + return 0; /*send_queue(); */ + } else + nexttosend = (nexttosend + 1) + % (QUEUELENGTH - 1); + return 1; + } else { + if (debug_commandir == 1) { + do_gettimeofday(&tp); + printk(KERN_INFO "Not time to send yet " + "- starting timer at %d.\n", + (int)tp.tv_usec); + printk(KERN_INFO "Enabling timer.\n"); + } + return 0; /* doesn't matter anymore */ + } + } else { + if (debug_commandir == 1) { + do_gettimeofday(&tp); + printk(KERN_INFO "No more data to send %d!\n", + (int)tp.tv_usec); + } + last_tx_sec = 0; /* reset our TX counters */ + last_tx_usec = 0; + return 1; /* nothing more to send! */ + } + } else { + if (debug_commandir == 1) + /* will try again on the callback */ + printk(KERN_INFO "Already sending\n"); + return 1; /* then the timer shouldn't be running... */ + } + return 0; /* should never get here... */ +} + + +int wait_to_tx(int usecs) +{ + /* don't return until last_time + usecs has been reached + * for non-zero last_tx's. */ + int wait_until_sec = 0, wait_until_usec = 0; + int now_sec = 0, now_usec = 0; + if (debug_commandir == 1) + printk(KERN_INFO "waittotx(%d)\n", usecs); + if (usecs == 0) + return 0; + + if (!(last_tx_sec == 0 && last_tx_usec == 0)) { + /* calculate wait time: */ + wait_until_sec = last_tx_sec + (usecs / 1000000); + wait_until_usec = last_tx_usec + usecs; + + do_gettimeofday(&tp); + now_sec = tp.tv_sec; + now_usec = tp.tv_usec; + + if (wait_until_usec > 1000000) { + /* we've spilled over to the next second. */ + wait_until_sec++; + wait_until_usec -= 1000000; + /* printk(KERN_INFO "usec rollover\n"); */ + } + if (debug_commandir == 1) + printk(KERN_INFO "Testing for the right second, now = " + "%d %d, wait = %d %d\n", + now_sec, now_usec, + wait_until_sec, wait_until_usec); + /* now we are always on the same second. */ + if (now_sec > wait_until_sec) { + if (debug_commandir == 1) + printk(KERN_INFO "Setting last_tx_sec to %d.\n", + wait_until_sec); + last_tx_sec = wait_until_sec; + last_tx_usec = wait_until_usec; + return 0; + } + + if ((now_sec == wait_until_sec) + && (now_usec > wait_until_usec)) { + if (debug_commandir == 1) + printk(KERN_INFO "Setting last_tx_sec to %d.\n", + wait_until_sec); + last_tx_sec = wait_until_sec; + last_tx_usec = wait_until_usec; + return 0; + } + return -1; /* didn't send */ + } + + do_gettimeofday(&tp); + last_tx_usec = tp.tv_usec; + last_tx_sec = tp.tv_sec; + return 0; /* if there's no last even, go ahead and send */ +} + + +int cmdir_write_queue(unsigned char *buffer, int count, void *callback_fct) +{ + int retval = count; + static char prev_signal_num; + unsigned char next_mask; + unsigned int multiplier; + int i; + + send_status = SEND_ACTIVE; + + if (count < 2) { + err("Not enough bytes (write request of %d bytes)", count); + return count; + } + + /* check data; decide which device to send to */ + switch (buffer[0]) { + case TX_HEADER: + case TX_HEADER_NEW: + /* this is LIRC transmit data */ + if (curTXFill >= 190) { + printk(KERN_INFO + "TX buffer too full to send more TX data\n"); + return 0; + } + if (next_transmitters != transmitters) { + if (buffer[1] != prev_signal_num) + /* this is new signal; change transmitter mask*/ + transmitters = next_transmitters; + } + prev_signal_num = buffer[1]; + + multiplier = 1; + for (i = 0; i < MAX_DEVICES; i++) { + next_mask = 0; + if (transmitters & (0x01*multiplier)) + next_mask |= TX1_ENABLE; + if (transmitters & (0x02*multiplier)) + next_mask |= TX2_ENABLE; + if (transmitters & (0x04*multiplier)) + next_mask |= TX3_ENABLE; + if (transmitters & (0x08*multiplier)) + next_mask |= TX4_ENABLE; + + if (next_mask > 0) { + buffer[1] = next_mask; + retval = write_core(buffer, count, + callback_fct, i); + if (retval != count) { + if (retval == -ENODEV) + err("Device %d not plugged in", + i); + else + err("Write error to device %d", + i); + return retval; + } + } + multiplier = multiplier*0x10; + } + return retval; + break; + case LCD_HEADER: + return write_core(buffer, count, callback_fct, lcd_device); + break; + default: + return write_core(buffer, count, callback_fct, def_device); + break; + } + /* should never get here */ + return retval; + +} + +int write_core(unsigned char *buffer, int count, + void *callback_fct, int device_num) +{ + struct usb_skel *dev; + int retval = count; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) + ssize_t bytes_written = 0; + if (minor_table[device_num] == NULL) + /* device is unplugged */ + return -ENODEV; + dev = minor_table[device_num]; + + /* lock this object */ + down(&dev->sem); + + /* see if we are already in the middle of a write */ + if (dev->write_urb->status == -EINPROGRESS) { + /*suppress errors - should just try sending again*/ + /*dbg(" - already writing");*/ + retval = -EINPROGRESS; + goto exit; + } + + /* we can only write as much as 1 urb will hold */ + bytes_written = (count > dev->bulk_out_size) ? + dev->bulk_out_size : count; + + /* copy the data into our urb */ + if (!(memcpy(dev->write_urb->transfer_buffer, buffer, bytes_written))) { + retval = -EFAULT; + goto exit; + } + + /* set up our urb */ + if (callback_fct == NULL) { + /*FILL_BULK_URB(dev->write_urb, dev->udev, + usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), + dev->write_urb->transfer_buffer, bytes_written, + cmdir_write_bulk_callback, dev); */ + usb_fill_bulk_urb(dev->write_urb, dev->udev, + usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), + dev->write_urb->transfer_buffer, bytes_written, + cmdir_write_bulk_callback, dev); + } else { + FILL_BULK_URB(dev->write_urb, dev->udev, + usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), + dev->write_urb->transfer_buffer, bytes_written, + callback_fct, dev); + } + + /* send the data out the bulk port */ + retval = usb_submit_urb(dev->write_urb); + if (!(retval)) + retval = bytes_written; + /* suppress errors */ + /* else { + err("Failed submitting write urb, error %d", retval); + } */ +exit: + /* unlock the device */ + up(&dev->sem); + return retval; /* this should be return error I think */ + +#else + struct usb_interface *interface; + struct urb *urb = NULL; + char *buf = NULL; + interface = usb_find_interface(&cmdir_driver, + USB_CMDIR_MINOR_BASE + device_num); + if (!interface) { + /* also check without adding base, for devfs */ + interface = usb_find_interface(&cmdir_driver, device_num); + if (!interface) + return -ENODEV; + } + dev = usb_get_intfdata(interface); + if (!dev) + return -ENODEV; + /* create a urb, and a buffer for it, and copy the data to the urb */ + urb = usb_alloc_urb(0, GFP_ATOMIC); /* Now -=Atomic=- */ + if (!urb) { + retval = -ENOMEM; + goto error; + } + buf = usb_buffer_alloc(dev->udev, count, + GFP_KERNEL, &urb->transfer_dma); + if (!buf) { + retval = -ENOMEM; + goto error; + } + if (!memcpy(buf, buffer, count)) { + retval = -EFAULT; + goto error; + } + /* initialize the urb properly */ + if (callback_fct == NULL) { + usb_fill_bulk_urb(urb, dev->udev, + usb_sndbulkpipe(dev->udev, + dev->bulk_out_endpointAddr), + buf, count, (void *) cmdir_write_bulk_callback, dev); + } else { + usb_fill_bulk_urb(urb, dev->udev, + usb_sndbulkpipe(dev->udev, + dev->bulk_out_endpointAddr), + buf, count, callback_fct, dev); + } + urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* double check this */ + + /* send the data out the bulk port */ + retval = usb_submit_urb(urb, GFP_KERNEL); + if (retval) { + err("%s - failed submitting write urb, error %d", + __FUNCTION__, retval); + goto error; + } + + /* release our reference to this urb, the USB + * core will eventually free it entirely */ + usb_free_urb(urb); + return count; + +error: + usb_buffer_free(dev->udev, count, buf, urb->transfer_dma); + usb_free_urb(urb); + return retval; +#endif +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +static void cmdir_write_bulk_callback(struct urb *urb) +{ + if (debug_commandir == 1) { + do_gettimeofday(&tp); + printk(KERN_INFO "cmdir_write_bulk_callback at %d\n", + (int)tp.tv_usec); + } + /*if ((urb->status != -ENOENT) && (urb->status != -ECONNRESET)) + return; + else { + dbg(" - urb status: %d", urb->status); + return; + }*/ + + send_status = SEND_IDLE; + /* printk(KERN_INFO "cmdir_write_bulk_callback - set idle\n"); */ + send_queue(); /* send the next packet */ + return; +} +#else +static void cmdir_write_bulk_callback(struct urb *urb, struct pt_regs *regs) +{ + struct usb_skel *dev; + dev = (struct usb_skel *)urb->context; + send_status = SEND_IDLE; + if (debug_commandir == 1) + printk(KERN_INFO "callback()\n"); + /* free up our allocated buffer */ + + usb_buffer_free(urb->dev, urb->transfer_buffer_length, + urb->transfer_buffer, urb->transfer_dma); + send_queue(); /* send the next packet */ + +} +#endif + +int set_tx_channels(unsigned int next_tx) +{ + next_transmitters = next_tx; + return 0; +} +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +EXPORT_SYMBOL_NOVERS(set_tx_channels); +#else +EXPORT_SYMBOL(set_tx_channels); +#endif + +module_init(usb_cmdir_init); +module_exit(usb_cmdir_exit); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/ubuntu/lirc/lirc_ttusbir/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_ttusbir/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_TTUSBIR) += lirc_ttusbir.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_ttusbir/lirc_ttusbir.c +++ linux-2.6.28/ubuntu/lirc/lirc_ttusbir/lirc_ttusbir.c @@ -0,0 +1,401 @@ +/**************************************************************************** + ** lirc_ttusbir.c *********************************************************** + **************************************************************************** + * + * lirc_ttusbir - LIRC device driver for the TechnoTrend USB IR Receiver + * + * Copyright (C) 2007 Stefan Macher + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* This LIRC driver provides access to the TechnoTrend USB IR Receiver. + * The receiver delivers the IR signal as raw sampled true/false data in + * isochronous USB packets each of size 128 byte. + * Currently the driver reduces the sampling rate by factor of 8 as this + * is still more than enough to decode RC-5 - others should be analyzed. + * But the driver does not rely on RC-5 it should be able to decode every + * IR signal that is not too fast. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "lirc.h" +#include "kcompat.h" +#include "lirc_dev/lirc_dev.h" + +MODULE_DESCRIPTION("TechnoTrend USB IR device driver for LIRC"); +MODULE_AUTHOR("Stefan Macher (st_maker-lirc@yahoo.de)"); +MODULE_LICENSE("GPL"); + +/* #define DEBUG */ +#ifdef DEBUG +#define DPRINTK printk +#else +#define DPRINTK(_x_, a...) +#endif + +/* function declarations */ +static int probe(struct usb_interface *intf, const struct usb_device_id *id); +static void disconnect(struct usb_interface *intf); +#if defined(KERNEL_2_5) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void urb_complete(struct urb *urb, struct pt_regs *pt_regs); +#else +static void urb_complete(struct urb *urb); +#endif +static int set_use_inc(void *data); +static void set_use_dec(void *data); + +static int num_urbs = 2; +module_param(num_urbs, int, 0444); +MODULE_PARM_DESC(num_urbs, + "Number of URBs in queue. Try to increase to 4 in case " + "of problems (default: 2; minimum: 2)"); + +/* table of devices that work with this driver */ +static struct usb_device_id device_id_table[] = { + { USB_DEVICE(0x0B48, 0x2003) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, device_id_table); + +/* USB driver definition */ +static struct usb_driver driver = { + .name = "TTUSBIR", + .id_table = &(device_id_table[0]), + .probe = probe, + .disconnect = disconnect, +}; + +/* USB device definition */ +struct ttusbir_device { + struct usb_driver *driver; + struct usb_device *udev; + struct usb_interface *interf; + struct usb_class_driver class_driver; + unsigned int ifnum; /* Interface number to use */ + unsigned int alt_setting; /* alternate setting to use */ + unsigned int endpoint; /* Endpoint to use */ + struct urb **urb; /* num_urb URB pointers*/ + char **buffer; /* 128 byte buffer for each URB */ + struct lirc_buffer rbuf; /* Buffer towards LIRC */ + struct lirc_plugin plugin; + int minor; + int last_pulse; /* remembers if last received byte was pulse or space */ + int last_num; /* remembers how many last bytes appeared */ + int opened; +}; + +/************************************* + * LIRC specific functions + */ +static int set_use_inc(void *data) +{ + int i; + struct ttusbir_device *ttusbir = data; + + DPRINTK("Sending first URBs\n"); + /* @TODO Do I need to check if I am already opened */ + ttusbir->opened = 1; + + for (i = 0; i < num_urbs; i++) + usb_submit_urb(ttusbir->urb[i], GFP_KERNEL); + + return 0; +} + +static void set_use_dec(void *data) +{ + struct ttusbir_device *ttusbir = data; + + DPRINTK("Device closed\n"); + + ttusbir->opened = 0; +} + +/************************************* + * USB specific functions + */ + +/* This mapping table is used to do a very simple filtering of the + * input signal. + * For a value with at least 4 bits set it returns 0xFF otherwise + * 0x00. For faster IR signals this can not be used. But for RC-5 we + * still have about 14 samples per pulse/space, i.e. we sample with 14 + * times higher frequency than the signal frequency */ +const unsigned char map_table[] = +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +#if defined(KERNEL_2_5) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void urb_complete(struct urb *urb, struct pt_regs *pt_regs) +#else +static void urb_complete(struct urb *urb) +#endif +{ + struct ttusbir_device *ttusbir; + unsigned char *buf; + int i; + lirc_t l; + + ttusbir = urb->context; + + if (!ttusbir->opened) + return; + + buf = (unsigned char *)urb->transfer_buffer; + + for (i = 0; i < 128; i++) { + /* Here we do the filtering and some kind of down sampling */ + buf[i] = ~map_table[buf[i]]; + if (ttusbir->last_pulse == buf[i]) { + if (ttusbir->last_num < PULSE_MASK/63) + ttusbir->last_num++; + /* else we are in a idle period and do not need to + * increment any longer */ + } else { + l = ttusbir->last_num * 62; /* about 62 = us/byte */ + if (ttusbir->last_pulse) /* pulse or space? */ + l |= PULSE_BIT; + if (!lirc_buffer_full(&ttusbir->rbuf)) { + lirc_buffer_write_1(&ttusbir->rbuf, (void *)&l); + wake_up_interruptible(&ttusbir->rbuf.wait_poll); + } + ttusbir->last_num = 0; + ttusbir->last_pulse = buf[i]; + } + } + usb_submit_urb(urb, GFP_ATOMIC); /* keep data rolling :-) */ +} + +/* Called whenever the USB subsystem thinks we could be the right driver + to handle this device +*/ +static int probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + int alt_set, endp; + int found = 0; + int i, j; + int struct_size; + struct usb_host_interface *host_interf; + struct usb_interface_descriptor *interf_desc; + struct usb_host_endpoint *host_endpoint; + struct ttusbir_device *ttusbir; + + DPRINTK("Module ttusbir probe\n"); + + /* To reduce memory fragmentation we use only one allocation */ + struct_size = sizeof(struct ttusbir_device) + + (sizeof(struct urb *) * num_urbs) + + (sizeof(char *) * num_urbs) + + (num_urbs * 128); + ttusbir = kmalloc(struct_size, GFP_KERNEL); + if (!ttusbir) + return -ENOMEM; + memset(ttusbir, 0, struct_size); + + ttusbir->urb = (struct urb **)((char *)ttusbir + + sizeof(struct ttusbir_device)); + ttusbir->buffer = (char **)((char *)ttusbir->urb + + (sizeof(struct urb *) * num_urbs)); + for (i = 0; i < num_urbs; i++) + ttusbir->buffer[i] = (char *)ttusbir->buffer + + (sizeof(char *)*num_urbs) + (i * 128); + + ttusbir->driver = &driver; + ttusbir->alt_setting = -1; + /* @TODO check if error can be returned */ + ttusbir->udev = usb_get_dev(interface_to_usbdev(intf)); + ttusbir->interf = intf; + ttusbir->last_pulse = 0x00; + ttusbir->last_num = 0; + + /* Now look for interface setting we can handle + We are searching for the alt setting where end point + 0x82 has max packet size 16 + */ + for (alt_set = 0; alt_set < intf->num_altsetting && !found; alt_set++) { + host_interf = &intf->altsetting[alt_set]; + interf_desc = &host_interf->desc; + for (endp = 0; endp < interf_desc->bNumEndpoints; endp++) { + host_endpoint = &host_interf->endpoint[endp]; + if ((host_endpoint->desc.bEndpointAddress == 0x82) && + (host_endpoint->desc.wMaxPacketSize == 0x10)) { + ttusbir->alt_setting = alt_set; + ttusbir->endpoint = endp; + found = 1; + break; + } + } + } + if (ttusbir->alt_setting != -1) + DPRINTK("alt setting: %d\n", ttusbir->alt_setting); + else { + err("Could not find alternate setting\n"); + kfree(ttusbir); + return -EINVAL; + } + + /* OK lets setup this interface setting */ + usb_set_interface(ttusbir->udev, 0, ttusbir->alt_setting); + + /* Store device info in interface structure */ + usb_set_intfdata(intf, ttusbir); + + /* Register as a LIRC plugin */ + if (lirc_buffer_init(&ttusbir->rbuf, sizeof(lirc_t), 256) < 0) { + err("Could not get memory for LIRC data buffer\n"); + usb_set_intfdata(intf, NULL); + kfree(ttusbir); + return -ENOMEM; + } + strcpy(ttusbir->plugin.name, "TTUSBIR"); + ttusbir->plugin.minor = -1; + ttusbir->plugin.code_length = 1; + ttusbir->plugin.sample_rate = 0; + ttusbir->plugin.data = ttusbir; + ttusbir->plugin.add_to_buf = NULL; + ttusbir->plugin.get_queue = NULL; + ttusbir->plugin.rbuf = &ttusbir->rbuf; + ttusbir->plugin.set_use_inc = set_use_inc; + ttusbir->plugin.set_use_dec = set_use_dec; + ttusbir->plugin.ioctl = NULL; + ttusbir->plugin.fops = NULL; + ttusbir->plugin.owner = THIS_MODULE; + ttusbir->plugin.features = LIRC_CAN_REC_MODE2; + ttusbir->minor = lirc_register_plugin(&ttusbir->plugin); + if (ttusbir->minor < 0) { + err("Error registering as LIRC plugin\n"); + usb_set_intfdata(intf, NULL); + lirc_buffer_free(&ttusbir->rbuf); + kfree(ttusbir); + return -EIO; + } + + /* Allocate and setup the URB that we will use to talk to the device */ + for (i = 0; i < num_urbs; i++) { + ttusbir->urb[i] = usb_alloc_urb(8, GFP_KERNEL); + if (!ttusbir->urb[i]) { + err("Could not allocate memory for the URB\n"); + for (j = i - 1; j >= 0; j--) + kfree(ttusbir->urb[j]); + lirc_buffer_free(&ttusbir->rbuf); + lirc_unregister_plugin(ttusbir->minor); + kfree(ttusbir); + usb_set_intfdata(intf, NULL); + return -ENOMEM; + } + ttusbir->urb[i]->dev = ttusbir->udev; + ttusbir->urb[i]->context = ttusbir; + ttusbir->urb[i]->pipe = usb_rcvisocpipe(ttusbir->udev, + ttusbir->endpoint); + ttusbir->urb[i]->interval = 1; + ttusbir->urb[i]->transfer_flags = URB_ISO_ASAP; + ttusbir->urb[i]->transfer_buffer = &ttusbir->buffer[i][0]; + ttusbir->urb[i]->complete = urb_complete; + ttusbir->urb[i]->number_of_packets = 8; + ttusbir->urb[i]->transfer_buffer_length = 128; + for (j = 0; j < 8; j++) { + ttusbir->urb[i]->iso_frame_desc[j].offset = j*16; + ttusbir->urb[i]->iso_frame_desc[j].length = 16; + } + } + return 0; +} + +/* Called when the driver is unloaded or the device is unplugged + */ +static void disconnect(struct usb_interface *intf) +{ + int i; + struct ttusbir_device *ttusbir; + + DPRINTK("Module ttusbir disconnect\n"); + + ttusbir = (struct ttusbir_device *) usb_get_intfdata(intf); + usb_set_intfdata(intf, NULL); + lirc_unregister_plugin(ttusbir->minor); + DPRINTK("unregistered\n"); + + for (i = 0; i < num_urbs; i++) { + usb_kill_urb(ttusbir->urb[i]); + usb_free_urb(ttusbir->urb[i]); + } + DPRINTK("URBs killed\n"); + lirc_buffer_free(&ttusbir->rbuf); + kfree(ttusbir); +} + +static int ttusbir_init_module(void) +{ + int result; + + DPRINTK(KERN_DEBUG "Module ttusbir init\n"); + + /* register this driver with the USB subsystem */ + result = usb_register(&driver); + if (result) + err("usb_register failed. Error number %d", result); + return result; +} + +static void ttusbir_exit_module(void) +{ + printk(KERN_DEBUG "Module ttusbir exit\n"); + /* deregister this driver with the USB subsystem */ + usb_deregister(&driver); +} + +module_init(ttusbir_init_module); +module_exit(ttusbir_exit_module); --- linux-2.6.28.orig/ubuntu/lirc/lirc_dev/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_dev/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_DEV) += lirc_dev.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_dev/lirc_dev.h +++ linux-2.6.28/ubuntu/lirc/lirc_dev/lirc_dev.h @@ -0,0 +1,264 @@ +/* + * LIRC base driver + * + * (L) by Artur Lipowski + * This code is licensed under GNU GPL + * + * $Id: lirc_dev.h,v 1.22 2008/01/13 10:45:02 lirc Exp $ + * + */ + +#ifndef _LINUX_LIRC_DEV_H +#define _LINUX_LIRC_DEV_H + +#define MAX_IRCTL_DEVICES 4 +#define BUFLEN 16 + +/* #define LIRC_BUFF_POWER_OF_2 */ +#ifdef LIRC_BUFF_POWER_OF_2 +#define mod(n, div) ((n) & ((div) - 1)) +#else +#define mod(n, div) ((n) % (div)) +#endif +#include +#include + +struct lirc_buffer { + wait_queue_head_t wait_poll; + spinlock_t lock; + + unsigned char *data; + unsigned int chunk_size; + unsigned int size; /* in chunks */ + unsigned int fill; /* in chunks */ + int head, tail; /* in chunks */ + /* Using chunks instead of bytes pretends to simplify boundary checking + * And should allow for some performance fine tunning later */ +}; +static inline void _lirc_buffer_clear(struct lirc_buffer *buf) +{ + buf->head = 0; + buf->tail = 0; + buf->fill = 0; +} +static inline int lirc_buffer_init(struct lirc_buffer *buf, + unsigned int chunk_size, + unsigned int size) +{ + /* Adjusting size to the next power of 2 would allow for + * inconditional LIRC_BUFF_POWER_OF_2 optimization */ + init_waitqueue_head(&buf->wait_poll); + spin_lock_init(&buf->lock); + _lirc_buffer_clear(buf); + buf->chunk_size = chunk_size; + buf->size = size; + buf->data = kmalloc(size*chunk_size, GFP_KERNEL); + if (buf->data == NULL) + return -1; + memset(buf->data, 0, size*chunk_size); + return 0; +} +static inline void lirc_buffer_free(struct lirc_buffer *buf) +{ + kfree(buf->data); + buf->data = NULL; + buf->head = 0; + buf->tail = 0; + buf->fill = 0; + buf->chunk_size = 0; + buf->size = 0; +} +static inline int lirc_buffer_full(struct lirc_buffer *buf) +{ + return (buf->fill >= buf->size); +} +static inline int lirc_buffer_empty(struct lirc_buffer *buf) +{ + return !(buf->fill); +} +static inline int lirc_buffer_available(struct lirc_buffer *buf) +{ + return (buf->size - buf->fill); +} +static inline void lirc_buffer_lock(struct lirc_buffer *buf, + unsigned long *flags) +{ + spin_lock_irqsave(&buf->lock, *flags); +} +static inline void lirc_buffer_unlock(struct lirc_buffer *buf, + unsigned long *flags) +{ + spin_unlock_irqrestore(&buf->lock, *flags); +} +static inline void lirc_buffer_clear(struct lirc_buffer *buf) +{ + unsigned long flags; + lirc_buffer_lock(buf, &flags); + _lirc_buffer_clear(buf); + lirc_buffer_unlock(buf, &flags); +} +static inline void _lirc_buffer_remove_1(struct lirc_buffer *buf) +{ + buf->head = mod(buf->head+1, buf->size); + buf->fill -= 1; +} +static inline void lirc_buffer_remove_1(struct lirc_buffer *buf) +{ + unsigned long flags; + lirc_buffer_lock(buf, &flags); + _lirc_buffer_remove_1(buf); + lirc_buffer_unlock(buf, &flags); +} +static inline void _lirc_buffer_read_1(struct lirc_buffer *buf, + unsigned char *dest) +{ + memcpy(dest, &buf->data[buf->head*buf->chunk_size], buf->chunk_size); + buf->head = mod(buf->head+1, buf->size); + buf->fill -= 1; +} +static inline void lirc_buffer_read_1(struct lirc_buffer *buf, + unsigned char *dest) +{ + unsigned long flags; + lirc_buffer_lock(buf, &flags); + _lirc_buffer_read_1(buf, dest); + lirc_buffer_unlock(buf, &flags); +} +static inline void _lirc_buffer_write_1(struct lirc_buffer *buf, + unsigned char *orig) +{ + memcpy(&buf->data[buf->tail*buf->chunk_size], orig, buf->chunk_size); + buf->tail = mod(buf->tail+1, buf->size); + buf->fill++; +} +static inline void lirc_buffer_write_1(struct lirc_buffer *buf, + unsigned char *orig) +{ + unsigned long flags; + lirc_buffer_lock(buf, &flags); + _lirc_buffer_write_1(buf, orig); + lirc_buffer_unlock(buf, &flags); +} +static inline void _lirc_buffer_write_n(struct lirc_buffer *buf, + unsigned char *orig, int count) +{ + memcpy(&buf->data[buf->tail * buf->chunk_size], orig, + count * buf->chunk_size); + buf->tail = mod(buf->tail + count, buf->size); + buf->fill += count; +} +static inline void lirc_buffer_write_n(struct lirc_buffer *buf, + unsigned char *orig, int count) +{ + unsigned long flags; + int space1; + + lirc_buffer_lock(buf, &flags); + if (buf->head > buf->tail) + space1 = buf->head - buf->tail; + else + space1 = buf->size - buf->tail; + + if (count > space1) { + _lirc_buffer_write_n(buf, orig, space1); + _lirc_buffer_write_n(buf, orig+(space1*buf->chunk_size), + count-space1); + } else { + _lirc_buffer_write_n(buf, orig, count); + } + lirc_buffer_unlock(buf, &flags); +} + +struct lirc_plugin { + char name[40]; + int minor; + int code_length; + int sample_rate; + unsigned long features; + void *data; + int (*add_to_buf) (void *data, struct lirc_buffer *buf); + wait_queue_head_t* (*get_queue) (void *data); + struct lirc_buffer *rbuf; + int (*set_use_inc) (void *data); + void (*set_use_dec) (void *data); + int (*ioctl) (struct inode *, struct file *, unsigned int, + unsigned long); + struct file_operations *fops; + struct device *dev; + struct module *owner; +}; +/* name: + * this string will be used for logs + * + * minor: + * indicates minor device (/dev/lirc) number for registered plugin + * if caller fills it with negative value, then the first free minor + * number will be used (if available) + * + * code_length: + * length of the remote control key code expressed in bits + * + * sample_rate: + * sample_rate equal to 0 means that no polling will be performed and + * add_to_buf will be triggered by external events (through task queue + * returned by get_queue) + * + * data: + * it may point to any plugin data and this pointer will be passed to + * all callback functions + * + * add_to_buf: + * add_to_buf will be called after specified period of the time or + * triggered by the external event, this behavior depends on value of + * the sample_rate this function will be called in user context. This + * routine should return 0 if data was added to the buffer and + * -ENODATA if none was available. This should add some number of bits + * evenly divisible by code_length to the buffer + * + * get_queue: + * this callback should return a pointer to the task queue which will + * be used for external event waiting + * + * rbuf: + * if not NULL, it will be used as a read buffer, you will have to + * write to the buffer by other means, like irq's (see also + * lirc_serial.c). + * + * set_use_inc: + * set_use_inc will be called after device is opened + * + * set_use_dec: + * set_use_dec will be called after device is closed + * + * ioctl: + * Some ioctl's can be directly handled by lirc_dev but will be + * forwared here if not NULL and only handled if it returns + * -ENOIOCTLCMD (see also lirc_serial.c). + * + * fops: + * file_operations for drivers which don't fit the current plugin model. + * + * owner: + * the module owning this struct + * + */ + + +/* following functions can be called ONLY from user context + * + * returns negative value on error or minor number + * of the registered device if success + * contens of the structure pointed by p is copied + */ +extern int lirc_register_plugin(struct lirc_plugin *p); + +/* returns negative value on error or 0 if success +*/ +extern int lirc_unregister_plugin(int minor); + +/* Returns the private data stored in the lirc_plugin + * associated with the given device file pointer. + */ +void *lirc_get_pdata(struct file *file); + +#endif --- linux-2.6.28.orig/ubuntu/lirc/lirc_dev/lirc_dev.c +++ linux-2.6.28/ubuntu/lirc/lirc_dev/lirc_dev.c @@ -0,0 +1,960 @@ +/* + * LIRC base driver + * + * (L) by Artur Lipowski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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: lirc_dev.c,v 1.58 2008/05/14 16:37:49 lirc Exp $ + * + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18) +#error "**********************************************************" +#error " Sorry, this driver needs kernel version 2.2.18 or higher " +#error "**********************************************************" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#include +#include +#else +#include +#include +#endif +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +#include +#endif +#define __KERNEL_SYSCALLS__ +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) +#include +#endif + +#include "kcompat.h" + +/* SysFS header */ +#if defined(LIRC_HAVE_SYSFS) +#include +#endif + +#include "lirc.h" +#include "lirc_dev.h" + +static int debug; +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG fmt, ## args); \ + } while (0) + +#define IRCTL_DEV_NAME "BaseRemoteCtl" +#define SUCCESS 0 +#define NOPLUG -1 +#define LOGHEAD "lirc_dev (%s[%d]): " + +struct irctl { + struct lirc_plugin p; + int attached; + int open; + + struct semaphore buffer_sem; + struct lirc_buffer *buf; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) + int tpid; + struct completion *t_notify; + struct completion *t_notify2; + int shutdown; +#else + struct task_struct *task; +#endif + long jiffies_to_wait; + +#ifdef LIRC_HAVE_DEVFS_24 + devfs_handle_t devfs_handle; +#endif +}; + +DECLARE_MUTEX(plugin_lock); + +static struct irctl irctls[MAX_IRCTL_DEVICES]; +static struct file_operations fops; + +/* Only used for sysfs but defined to void otherwise */ +static lirc_class_t *lirc_class; + +/* helper function + * initializes the irctl structure + */ +static inline void init_irctl(struct irctl *ir) +{ + memset(&ir->p, 0, sizeof(struct lirc_plugin)); + sema_init(&ir->buffer_sem, 1); + ir->p.minor = NOPLUG; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) + ir->tpid = -1; + ir->t_notify = NULL; + ir->t_notify2 = NULL; + ir->shutdown = 0; +#else + ir->task = NULL; +#endif + ir->jiffies_to_wait = 0; + + ir->open = 0; + ir->attached = 0; +} + +static void cleanup(struct irctl *ir) +{ + dprintk(LOGHEAD "cleaning up\n", ir->p.name, ir->p.minor); + +#ifdef LIRC_HAVE_DEVFS_24 + devfs_unregister(ir->devfs_handle); +#endif +#ifdef LIRC_HAVE_DEVFS_26 + devfs_remove(DEV_LIRC "/%u", ir->p.minor); +#endif + lirc_device_destroy(lirc_class, + MKDEV(IRCTL_DEV_MAJOR, ir->p.minor)); + + if (ir->buf != ir->p.rbuf) { + lirc_buffer_free(ir->buf); + kfree(ir->buf); + } + ir->buf = NULL; + + init_irctl(ir); +} + +/* helper function + * reads key codes from plugin and puts them into buffer + * buffer free space is checked and locking performed + * returns 0 on success + */ +static inline int add_to_buf(struct irctl *ir) +{ + if (lirc_buffer_full(ir->buf)) { + dprintk(LOGHEAD "buffer overflow\n", + ir->p.name, ir->p.minor); + return -EOVERFLOW; + } + + if (ir->p.add_to_buf) { + int res = -ENODATA; + int got_data = 0; + + /* service the device as long as it is returning + * data and we have space + */ + while (!lirc_buffer_full(ir->buf)) { + res = ir->p.add_to_buf(ir->p.data, ir->buf); + if (res == SUCCESS) + got_data++; + else + break; + } + + if (res == -ENODEV) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) + ir->shutdown = 1; +#else + kthread_stop(ir->task); +#endif + + return (got_data ? SUCCESS : res); + } + + return SUCCESS; +} + +/* main function of the polling thread + */ +static int lirc_thread(void *irctl) +{ + struct irctl *ir = irctl; + + /* This thread doesn't need any user-level access, + * so get rid of all our resources + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) + daemonize("lirc_dev"); + + if (ir->t_notify != NULL) + complete(ir->t_notify); +#endif + + dprintk(LOGHEAD "poll thread started\n", ir->p.name, ir->p.minor); + + do { + if (ir->open) { + if (ir->jiffies_to_wait) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(ir->jiffies_to_wait); + } else { + interruptible_sleep_on( + ir->p.get_queue(ir->p.data)); + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) + if (ir->shutdown) +#else + if (kthread_should_stop()) +#endif + break; + if (!add_to_buf(ir)) + wake_up_interruptible(&ir->buf->wait_poll); + } else { + /* if device not opened so we can sleep half a second */ + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ/2); + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) + } while (!ir->shutdown); + + if (ir->t_notify2 != NULL) + wait_for_completion(ir->t_notify2); + + ir->tpid = -1; + if (ir->t_notify != NULL) + complete(ir->t_notify); +#else + } while (!kthread_should_stop()); +#endif + + dprintk(LOGHEAD "poll thread ended\n", ir->p.name, ir->p.minor); + + return 0; +} + +int lirc_register_plugin(struct lirc_plugin *p) +{ + struct irctl *ir; + int minor; + int bytes_in_key; + int err; +#ifdef LIRC_HAVE_DEVFS_24 + char name[16]; +#endif + DECLARE_COMPLETION(tn); + + if (!p) { + printk(KERN_ERR "lirc_dev: lirc_register_plugin: " + "plugin pointer must be not NULL!\n"); + err = -EBADRQC; + goto out; + } + + if (MAX_IRCTL_DEVICES <= p->minor) { + printk(KERN_ERR "lirc_dev: lirc_register_plugin: " + "\"minor\" must be between 0 and %d (%d)!\n", + MAX_IRCTL_DEVICES-1, p->minor); + err = -EBADRQC; + goto out; + } + + if (1 > p->code_length || (BUFLEN * 8) < p->code_length) { + printk(KERN_ERR "lirc_dev: lirc_register_plugin: " + "code length in bits for minor (%d) " + "must be less than %d!\n", + p->minor, BUFLEN * 8); + err = -EBADRQC; + goto out; + } + + printk(KERN_INFO "lirc_dev: lirc_register_plugin: sample_rate: %d\n", + p->sample_rate); + if (p->sample_rate) { + if (2 > p->sample_rate || HZ < p->sample_rate) { + printk(KERN_ERR "lirc_dev: lirc_register_plugin: " + "sample_rate must be between 2 and %d!\n", HZ); + err = -EBADRQC; + goto out; + } + if (!p->add_to_buf) { + printk(KERN_ERR "lirc_dev: lirc_register_plugin: " + "add_to_buf cannot be NULL when " + "sample_rate is set\n"); + err = -EBADRQC; + goto out; + } + } else if (!(p->fops && p->fops->read) + && !p->get_queue && !p->rbuf) { + printk(KERN_ERR "lirc_dev: lirc_register_plugin: " + "fops->read, get_queue and rbuf " + "cannot all be NULL!\n"); + err = -EBADRQC; + goto out; + } else if (!p->get_queue && !p->rbuf) { + if (!(p->fops && p->fops->read && p->fops->poll) + || (!p->fops->ioctl && !p->ioctl)) { + printk(KERN_ERR "lirc_dev: lirc_register_plugin: " + "neither read, poll nor ioctl can be NULL!\n"); + err = -EBADRQC; + goto out; + } + } + + if (p->owner == NULL) { + printk(KERN_ERR "lirc_dev: lirc_register_plugin: " + "no module owner registered\n"); + err = -EBADRQC; + goto out; + } + + down(&plugin_lock); + + minor = p->minor; + + if (0 > minor) { + /* find first free slot for plugin */ + for (minor = 0; minor < MAX_IRCTL_DEVICES; minor++) + if (irctls[minor].p.minor == NOPLUG) + break; + if (MAX_IRCTL_DEVICES == minor) { + printk(KERN_ERR "lirc_dev: lirc_register_plugin: " + "no free slots for plugins!\n"); + err = -ENOMEM; + goto out_lock; + } + } else if (irctls[minor].p.minor != NOPLUG) { + printk(KERN_ERR "lirc_dev: lirc_register_plugin: " + "minor (%d) just registered!\n", minor); + err = -EBUSY; + goto out_lock; + } + + ir = &irctls[minor]; + + if (p->sample_rate) { + ir->jiffies_to_wait = HZ / p->sample_rate; + } else { + /* it means - wait for external event in task queue */ + ir->jiffies_to_wait = 0; + } + + /* some safety check 8-) */ + p->name[sizeof(p->name)-1] = '\0'; + + bytes_in_key = p->code_length/8 + (p->code_length%8 ? 1 : 0); + + if (p->rbuf) { + ir->buf = p->rbuf; + } else { + ir->buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); + if (!ir->buf) { + err = -ENOMEM; + goto out_lock; + } + if (lirc_buffer_init(ir->buf, bytes_in_key, + BUFLEN/bytes_in_key) != 0) { + kfree(ir->buf); + err = -ENOMEM; + goto out_lock; + } + } + + if (p->features == 0) + p->features = (p->code_length > 8) ? + LIRC_CAN_REC_LIRCCODE : LIRC_CAN_REC_CODE; + + ir->p = *p; + ir->p.minor = minor; + +#if defined(LIRC_HAVE_DEVFS_24) + sprintf(name, DEV_LIRC "/%d", ir->p.minor); + ir->devfs_handle = devfs_register(NULL, name, DEVFS_FL_DEFAULT, + IRCTL_DEV_MAJOR, ir->p.minor, + S_IFCHR | S_IRUSR | S_IWUSR, + &fops, NULL); +#elif defined(LIRC_HAVE_DEVFS_26) + devfs_mk_cdev(MKDEV(IRCTL_DEV_MAJOR, ir->p.minor), + S_IFCHR|S_IRUSR|S_IWUSR, + DEV_LIRC "/%u", ir->p.minor); +#endif + (void) device_create(lirc_class, ir->p.dev, + MKDEV(IRCTL_DEV_MAJOR, ir->p.minor), + NULL, "lirc%u", ir->p.minor); + + if (p->sample_rate || p->get_queue) { + /* try to fire up polling thread */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) + ir->t_notify = &tn; + ir->tpid = kernel_thread(lirc_thread, (void *)ir, 0); + if (ir->tpid < 0) { +#else + ir->task = kthread_run(lirc_thread, (void *)ir, "lirc_dev"); + if (IS_ERR(ir->task)) { +#endif + printk(KERN_ERR "lirc_dev: lirc_register_plugin: " + "cannot run poll thread for minor = %d\n", + p->minor); + err = -ECHILD; + goto out_sysfs; + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) + wait_for_completion(&tn); + ir->t_notify = NULL; +#endif + } + ir->attached = 1; + up(&plugin_lock); + +/* + * Recent kernels should handle this autmatically by increasing/decreasing + * use count when a dependant module is loaded/unloaded. + */ +#ifndef KERNEL_2_5 + MOD_INC_USE_COUNT; +#endif + dprintk("lirc_dev: plugin %s registered at minor number = %d\n", + ir->p.name, ir->p.minor); + p->minor = minor; + return minor; + +out_sysfs: + lirc_device_destroy(lirc_class, + MKDEV(IRCTL_DEV_MAJOR, ir->p.minor)); +#ifdef LIRC_HAVE_DEVFS_24 + devfs_unregister(ir->devfs_handle); +#endif +#ifdef LIRC_HAVE_DEVFS_26 + devfs_remove(DEV_LIRC "/%i", ir->p.minor); +#endif +out_lock: + up(&plugin_lock); +out: + return err; +} +EXPORT_SYMBOL(lirc_register_plugin); + +int lirc_unregister_plugin(int minor) +{ + struct irctl *ir; + DECLARE_COMPLETION(tn); + DECLARE_COMPLETION(tn2); + + if (minor < 0 || minor >= MAX_IRCTL_DEVICES) { + printk(KERN_ERR "lirc_dev: lirc_unregister_plugin: " + "\"minor\" must be between 0 and %d!\n", + MAX_IRCTL_DEVICES-1); + return -EBADRQC; + } + + ir = &irctls[minor]; + + down(&plugin_lock); + + if (ir->p.minor != minor) { + printk(KERN_ERR "lirc_dev: lirc_unregister_plugin: " + "minor (%d) device not registered!", minor); + up(&plugin_lock); + return -ENOENT; + } + + /* end up polling thread */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) + if (ir->tpid >= 0) { + ir->t_notify = &tn; + ir->t_notify2 = &tn2; + ir->shutdown = 1; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) + { + struct task_struct *p; + + p = find_task_by_pid(ir->tpid); + wake_up_process(p); + } +#else + /* 2.2.x does not export wake_up_process() */ + wake_up_interruptible(ir->p.get_queue(ir->p.data)); +#endif + complete(&tn2); + wait_for_completion(&tn); + ir->t_notify = NULL; + ir->t_notify2 = NULL; + } +#else /* kernel >= 2.6.23 */ + if (ir->task) { + wake_up_process(ir->task); + kthread_stop(ir->task); + } +#endif + + dprintk("lirc_dev: plugin %s unregistered from minor number = %d\n", + ir->p.name, ir->p.minor); + + ir->attached = 0; + if (ir->open) { + dprintk(LOGHEAD "releasing opened plugin\n", + ir->p.name, ir->p.minor); + wake_up_interruptible(&ir->buf->wait_poll); + down(&ir->buffer_sem); + ir->p.set_use_dec(ir->p.data); + module_put(ir->p.owner); + up(&ir->buffer_sem); + } else + cleanup(ir); + up(&plugin_lock); + +/* + * Recent kernels should handle this autmatically by increasing/decreasing + * use count when a dependant module is loaded/unloaded. + */ +#ifndef KERNEL_2_5 + MOD_DEC_USE_COUNT; +#endif + + return SUCCESS; +} +EXPORT_SYMBOL(lirc_unregister_plugin); + +/* + * + */ +static int irctl_open(struct inode *inode, struct file *file) +{ + struct irctl *ir; + int retval; + + if (MINOR(inode->i_rdev) >= MAX_IRCTL_DEVICES) { + dprintk("lirc_dev [%d]: open result = -ENODEV\n", + MINOR(inode->i_rdev)); + return -ENODEV; + } + + ir = &irctls[MINOR(inode->i_rdev)]; + + dprintk(LOGHEAD "open called\n", ir->p.name, ir->p.minor); + + /* if the plugin has an open function use it instead */ + if (ir->p.fops && ir->p.fops->open) + return ir->p.fops->open(inode, file); + + if (down_interruptible(&plugin_lock)) + return -ERESTARTSYS; + + if (ir->p.minor == NOPLUG) { + up(&plugin_lock); + dprintk(LOGHEAD "open result = -ENODEV\n", + ir->p.name, ir->p.minor); + return -ENODEV; + } + + if (ir->open) { + up(&plugin_lock); + dprintk(LOGHEAD "open result = -EBUSY\n", + ir->p.name, ir->p.minor); + return -EBUSY; + } + + /* there is no need for locking here because ir->open is 0 + * and lirc_thread isn't using buffer + * plugins which use irq's should allocate them on set_use_inc, + * so there should be no problem with those either. + */ + ir->buf->head = ir->buf->tail; + ir->buf->fill = 0; + + if (ir->p.owner != NULL && try_module_get(ir->p.owner)) { + ++ir->open; + retval = ir->p.set_use_inc(ir->p.data); + + if (retval != SUCCESS) { + module_put(ir->p.owner); + --ir->open; + } + } else { + if (ir->p.owner == NULL) + dprintk(LOGHEAD "no module owner!!!\n", + ir->p.name, ir->p.minor); + + retval = -ENODEV; + } + + dprintk(LOGHEAD "open result = %d\n", ir->p.name, ir->p.minor, retval); + up(&plugin_lock); + + return retval; +} + +/* + * + */ +static int irctl_close(struct inode *inode, struct file *file) +{ + struct irctl *ir = &irctls[MINOR(inode->i_rdev)]; + + dprintk(LOGHEAD "close called\n", ir->p.name, ir->p.minor); + + /* if the plugin has a close function use it instead */ + if (ir->p.fops && ir->p.fops->release) + return ir->p.fops->release(inode, file); + + if (down_interruptible(&plugin_lock)) + return -ERESTARTSYS; + + --ir->open; + if (ir->attached) { + ir->p.set_use_dec(ir->p.data); + module_put(ir->p.owner); + } else { + cleanup(ir); + } + + up(&plugin_lock); + + return SUCCESS; +} + +/* + * + */ +static unsigned int irctl_poll(struct file *file, poll_table *wait) +{ + struct irctl *ir = &irctls[MINOR(file->f_dentry->d_inode->i_rdev)]; + unsigned int ret; + + dprintk(LOGHEAD "poll called\n", ir->p.name, ir->p.minor); + + /* if the plugin has a poll function use it instead */ + if (ir->p.fops && ir->p.fops->poll) + return ir->p.fops->poll(file, wait); + + down(&ir->buffer_sem); + if (!ir->attached) { + up(&ir->buffer_sem); + return POLLERR; + } + + poll_wait(file, &ir->buf->wait_poll, wait); + + dprintk(LOGHEAD "poll result = %s\n", + ir->p.name, ir->p.minor, + lirc_buffer_empty(ir->buf) ? "0" : "POLLIN|POLLRDNORM"); + + ret = lirc_buffer_empty(ir->buf) ? 0 : (POLLIN|POLLRDNORM); + + up(&ir->buffer_sem); + return ret; +} + +/* + * + */ +static int irctl_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + unsigned long mode; + int result; + struct irctl *ir = &irctls[MINOR(inode->i_rdev)]; + + dprintk(LOGHEAD "ioctl called (0x%x)\n", + ir->p.name, ir->p.minor, cmd); + + /* if the plugin has a ioctl function use it instead */ + if (ir->p.fops && ir->p.fops->ioctl) + return ir->p.fops->ioctl(inode, file, cmd, arg); + + if (ir->p.minor == NOPLUG || !ir->attached) { + dprintk(LOGHEAD "ioctl result = -ENODEV\n", + ir->p.name, ir->p.minor); + return -ENODEV; + } + + /* Give the plugin a chance to handle the ioctl */ + if (ir->p.ioctl) { + result = ir->p.ioctl(inode, file, cmd, arg); + if (result != -ENOIOCTLCMD) + return result; + } + /* The plugin can't handle cmd */ + result = SUCCESS; + + switch (cmd) { + case LIRC_GET_FEATURES: + result = put_user(ir->p.features, (unsigned long *)arg); + break; + case LIRC_GET_REC_MODE: + if (!(ir->p.features&LIRC_CAN_REC_MASK)) + return -ENOSYS; + + result = put_user(LIRC_REC2MODE + (ir->p.features&LIRC_CAN_REC_MASK), + (unsigned long *)arg); + break; + case LIRC_SET_REC_MODE: + if (!(ir->p.features&LIRC_CAN_REC_MASK)) + return -ENOSYS; + + result = get_user(mode, (unsigned long *)arg); + if (!result && !(LIRC_MODE2REC(mode) & ir->p.features)) + result = -EINVAL; + /* + * FIXME: We should actually set the mode somehow but + * for now, lirc_serial doesn't support mode changing either + */ + break; + case LIRC_GET_LENGTH: + result = put_user((unsigned long)ir->p.code_length, + (unsigned long *)arg); + break; + default: + result = -ENOIOCTLCMD; + } + + dprintk(LOGHEAD "ioctl result = %d\n", + ir->p.name, ir->p.minor, result); + + return result; +} + +/* + * + */ +static ssize_t irctl_read(struct file *file, + char *buffer, + size_t length, + loff_t *ppos) +{ + struct irctl *ir = &irctls[MINOR(file->f_dentry->d_inode->i_rdev)]; + unsigned char buf[ir->buf->chunk_size]; + int ret = 0, written = 0; + DECLARE_WAITQUEUE(wait, current); + + dprintk(LOGHEAD "read called\n", ir->p.name, ir->p.minor); + + /* if the plugin has a specific read function use it instead */ + if (ir->p.fops && ir->p.fops->read) + return ir->p.fops->read(file, buffer, length, ppos); + + if (down_interruptible(&ir->buffer_sem)) + return -ERESTARTSYS; + if (!ir->attached) { + up(&ir->buffer_sem); + return -ENODEV; + } + + if (length % ir->buf->chunk_size) { + dprintk(LOGHEAD "read result = -EINVAL\n", + ir->p.name, ir->p.minor); + up(&ir->buffer_sem); + return -EINVAL; + } + + /* + * we add ourselves to the task queue before buffer check + * to avoid losing scan code (in case when queue is awaken somewhere + * beetwen while condition checking and scheduling) + */ + add_wait_queue(&ir->buf->wait_poll, &wait); + set_current_state(TASK_INTERRUPTIBLE); + + /* + * while we did't provide 'length' bytes, device is opened in blocking + * mode and 'copy_to_user' is happy, wait for data. + */ + while (written < length && ret == 0) { + if (lirc_buffer_empty(ir->buf)) { + /* According to the read(2) man page, 'written' can be + * returned as less than 'length', instead of blocking + * again, returning -EWOULDBLOCK, or returning + * -ERESTARTSYS */ + if (written) + break; + if (file->f_flags & O_NONBLOCK) { + ret = -EWOULDBLOCK; + break; + } + if (signal_pending(current)) { + ret = -ERESTARTSYS; + break; + } + schedule(); + set_current_state(TASK_INTERRUPTIBLE); + if (!ir->attached) { + ret = -ENODEV; + break; + } + } else { + lirc_buffer_read_1(ir->buf, buf); + ret = copy_to_user((void *)buffer+written, buf, + ir->buf->chunk_size); + written += ir->buf->chunk_size; + } + } + + remove_wait_queue(&ir->buf->wait_poll, &wait); + set_current_state(TASK_RUNNING); + up(&ir->buffer_sem); + + dprintk(LOGHEAD "read result = %s (%d)\n", + ir->p.name, ir->p.minor, ret ? "-EFAULT" : "OK", ret); + + return ret ? ret : written; +} + + +void *lirc_get_pdata(struct file *file) +{ + void *data = NULL; + + if (file && file->f_dentry && file->f_dentry->d_inode && + file->f_dentry->d_inode->i_rdev) { + struct irctl *ir; + ir = &irctls[MINOR(file->f_dentry->d_inode->i_rdev)]; + data = ir->p.data; + } + + return data; +} +EXPORT_SYMBOL(lirc_get_pdata); + + +static ssize_t irctl_write(struct file *file, const char *buffer, + size_t length, loff_t *ppos) +{ + struct irctl *ir = &irctls[MINOR(file->f_dentry->d_inode->i_rdev)]; + + dprintk(LOGHEAD "write called\n", ir->p.name, ir->p.minor); + + /* if the plugin has a specific read function use it instead */ + if (ir->p.fops && ir->p.fops->write) + return ir->p.fops->write(file, buffer, length, ppos); + + if (!ir->attached) + return -ENODEV; + + return -EINVAL; +} + + +static struct file_operations fops = { + .read = irctl_read, + .write = irctl_write, + .poll = irctl_poll, + .ioctl = irctl_ioctl, + .open = irctl_open, + .release = irctl_close +}; + + +static int lirc_dev_init(void) +{ + int i; + + for (i = 0; i < MAX_IRCTL_DEVICES; ++i) + init_irctl(&irctls[i]); + + if (register_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME, &fops)) { + printk(KERN_ERR "lirc_dev: register_chrdev failed\n"); + goto out; + } + + lirc_class = class_create(THIS_MODULE, "lirc"); + if (IS_ERR(lirc_class)) { + printk(KERN_ERR "lirc_dev: class_create failed\n"); + goto out_unregister; + } + + printk(KERN_INFO "lirc_dev: IR Remote Control driver registered, " + "major %d \n", IRCTL_DEV_MAJOR); + + return SUCCESS; + +out_unregister: +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) + if (unregister_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME)) + printk(KERN_ERR "lirc_dev: unregister_chrdev failed!\n"); +#else + /* unregister_chrdev returns void now */ + unregister_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME); +#endif +out: + return -1; +} + +/* ---------------------------------------------------------------------- */ + +/* For now dont try to use it as a static version ! */ + +#ifdef MODULE + +/* + * + */ +int init_module(void) +{ + return lirc_dev_init(); +} + +/* + * + */ +void cleanup_module(void) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) + int ret; + + ret = unregister_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME); + class_destroy(lirc_class); + + if (ret) + printk(KERN_ERR "lirc_dev: error in " + "module_unregister_chrdev: %d\n", ret); + else + dprintk("lirc_dev: module successfully unloaded\n"); +#else + /* unregister_chrdev returns void now */ + unregister_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME); + class_destroy(lirc_class); + dprintk("lirc_dev: module unloaded\n"); +#endif +} + +MODULE_DESCRIPTION("LIRC base driver module"); +MODULE_AUTHOR("Artur Lipowski"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_CHARDEV_MAJOR(IRCTL_DEV_MAJOR); + +module_param(debug, bool, 0644); +MODULE_PARM_DESC(debug, "Enable debugging messages"); + +#endif /* MODULE */ + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/squashfs/Kconfig +++ linux-2.6.28/ubuntu/squashfs/Kconfig @@ -0,0 +1,50 @@ +config SQUASHFS + tristate "SquashFS 3.3 - Squashed file system support" + select ZLIB_INFLATE + help + Saying Y here includes support for SquashFS 3.3 (a Compressed + Read-Only File System). Squashfs is a highly compressed read-only + filesystem for Linux. It uses zlib compression to compress both + files, inodes and directories. Inodes in the system are very small + and all blocks are packed to minimise data overhead. Block sizes + greater than 4K are supported up to a maximum of 1 Mbytes (default + block size 128K). SquashFS 3.3 supports 64 bit filesystems and files + (larger than 4GB), full uid/gid information, hard links and timestamps. + + Squashfs is intended for general read-only filesystem use, for + archival use (i.e. in cases where a .tar.gz file may be used), and in + embedded systems where low overhead is needed. Further information + and filesystem tools are available from http://squashfs.sourceforge.net. + + If you want to compile this as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), + say M here and read . The module + will be called squashfs. Note that the root file system (the one + containing the directory /) cannot be compiled as a module. + + If unsure, say N. + +config SQUASHFS_EMBEDDED + + bool "Additional option for memory-constrained systems" + depends on SQUASHFS + default n + help + Saying Y here allows you to specify cache size. + + If unsure, say N. + +config SQUASHFS_FRAGMENT_CACHE_SIZE + int "Number of fragments cached" if SQUASHFS_EMBEDDED + depends on SQUASHFS + default "3" + help + By default SquashFS caches the last 3 fragments read from + the filesystem. Increasing this amount may mean SquashFS + has to re-read fragments less often from disk, at the expense + of extra system memory. Decreasing this amount will mean + SquashFS uses less memory at the expense of extra reads from disk. + + Note there must be at least one cached fragment. Anything + much more than three will probably not make much difference. + --- linux-2.6.28.orig/ubuntu/squashfs/inode.c +++ linux-2.6.28/ubuntu/squashfs/inode.c @@ -0,0 +1,2187 @@ +/* + * Squashfs - a compressed read only filesystem for Linux + * + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 + * Phillip Lougher + * + * This program is free software; you can redistribute 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * inode.c + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "squashfs.h" + +int squashfs_cached_blks; + +#ifdef USE_EXPORT +static struct dentry *squashfs_get_parent(struct dentry *child); +#endif + +static int squashfs_read_inode(struct inode *i, squashfs_inode_t inode); +static int squashfs_statfs(struct dentry *, struct kstatfs *); +static int squashfs_symlink_readpage(struct file *file, struct page *page); +static long long read_blocklist(struct inode *inode, int index, + int readahead_blks, char *block_list, + unsigned short **block_p, unsigned int *bsize); +static int squashfs_readpage(struct file *file, struct page *page); +static int squashfs_readdir(struct file *, void *, filldir_t); +static struct dentry *squashfs_lookup(struct inode *, struct dentry *, + struct nameidata *); +static int squashfs_remount(struct super_block *s, int *flags, char *data); +static void squashfs_put_super(struct super_block *); +static int squashfs_get_sb(struct file_system_type *,int, const char *, void *, + struct vfsmount *); +static struct inode *squashfs_alloc_inode(struct super_block *sb); +static void squashfs_destroy_inode(struct inode *inode); +static int init_inodecache(void); +static void destroy_inodecache(void); + +static struct file_system_type squashfs_fs_type = { + .owner = THIS_MODULE, + .name = "squashfs", + .get_sb = squashfs_get_sb, + .kill_sb = kill_block_super, + .fs_flags = FS_REQUIRES_DEV +}; + +static const unsigned char squashfs_filetype_table[] = { + DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK +}; + +static struct super_operations squashfs_super_ops = { + .alloc_inode = squashfs_alloc_inode, + .destroy_inode = squashfs_destroy_inode, + .statfs = squashfs_statfs, + .put_super = squashfs_put_super, + .remount_fs = squashfs_remount +}; + +static struct super_operations squashfs_export_super_ops = { + .alloc_inode = squashfs_alloc_inode, + .destroy_inode = squashfs_destroy_inode, + .statfs = squashfs_statfs, + .put_super = squashfs_put_super, +}; + +#ifdef USE_EXPORT +static struct export_operations squashfs_export_ops = { + .get_parent = squashfs_get_parent +}; +#endif + +SQSH_EXTERN const struct address_space_operations squashfs_symlink_aops = { + .readpage = squashfs_symlink_readpage +}; + +SQSH_EXTERN const struct address_space_operations squashfs_aops = { + .readpage = squashfs_readpage +}; + +static const struct file_operations squashfs_dir_ops = { + .read = generic_read_dir, + .readdir = squashfs_readdir +}; + +SQSH_EXTERN struct inode_operations squashfs_dir_inode_ops = { + .lookup = squashfs_lookup +}; + + +static struct buffer_head *get_block_length(struct super_block *s, + int *cur_index, int *offset, int *c_byte) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + unsigned short temp; + struct buffer_head *bh; + + if (!(bh = sb_bread(s, *cur_index))) + goto out; + + if (msblk->devblksize - *offset == 1) { + if (msblk->swap) + ((unsigned char *) &temp)[1] = *((unsigned char *) + (bh->b_data + *offset)); + else + ((unsigned char *) &temp)[0] = *((unsigned char *) + (bh->b_data + *offset)); + brelse(bh); + if (!(bh = sb_bread(s, ++(*cur_index)))) + goto out; + if (msblk->swap) + ((unsigned char *) &temp)[0] = *((unsigned char *) + bh->b_data); + else + ((unsigned char *) &temp)[1] = *((unsigned char *) + bh->b_data); + *c_byte = temp; + *offset = 1; + } else { + if (msblk->swap) { + ((unsigned char *) &temp)[1] = *((unsigned char *) + (bh->b_data + *offset)); + ((unsigned char *) &temp)[0] = *((unsigned char *) + (bh->b_data + *offset + 1)); + } else { + ((unsigned char *) &temp)[0] = *((unsigned char *) + (bh->b_data + *offset)); + ((unsigned char *) &temp)[1] = *((unsigned char *) + (bh->b_data + *offset + 1)); + } + *c_byte = temp; + *offset += 2; + } + + if (SQUASHFS_CHECK_DATA(msblk->sblk.flags)) { + if (*offset == msblk->devblksize) { + brelse(bh); + if (!(bh = sb_bread(s, ++(*cur_index)))) + goto out; + *offset = 0; + } + if (*((unsigned char *) (bh->b_data + *offset)) != + SQUASHFS_MARKER_BYTE) { + ERROR("Metadata block marker corrupt @ %x\n", + *cur_index); + brelse(bh); + goto out; + } + (*offset)++; + } + return bh; + +out: + return NULL; +} + + +SQSH_EXTERN unsigned int squashfs_read_data(struct super_block *s, char *buffer, + long long index, unsigned int length, + long long *next_index, int srclength) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + struct buffer_head **bh; + unsigned int offset = index & ((1 << msblk->devblksize_log2) - 1); + unsigned int cur_index = index >> msblk->devblksize_log2; + int bytes, avail_bytes, b = 0, k = 0; + unsigned int compressed; + unsigned int c_byte = length; + + bh = kmalloc(((sblk->block_size >> msblk->devblksize_log2) + 1) * + sizeof(struct buffer_head *), GFP_KERNEL); + if (bh == NULL) + goto read_failure; + + if (c_byte) { + bytes = msblk->devblksize - offset; + compressed = SQUASHFS_COMPRESSED_BLOCK(c_byte); + c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte); + + TRACE("Block @ 0x%llx, %scompressed size %d, src size %d\n", index, + compressed ? "" : "un", (unsigned int) c_byte, srclength); + + if (c_byte > srclength || index < 0 || (index + c_byte) > sblk->bytes_used) + goto read_failure; + + bh[0] = sb_getblk(s, cur_index); + if (bh[0] == NULL) + goto block_release; + + for (b = 1; bytes < c_byte; b++) { + bh[b] = sb_getblk(s, ++cur_index); + if (bh[b] == NULL) + goto block_release; + bytes += msblk->devblksize; + } + ll_rw_block(READ, b, bh); + } else { + if (index < 0 || (index + 2) > sblk->bytes_used) + goto read_failure; + + bh[0] = get_block_length(s, &cur_index, &offset, &c_byte); + if (bh[0] == NULL) + goto read_failure; + + bytes = msblk->devblksize - offset; + compressed = SQUASHFS_COMPRESSED(c_byte); + c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); + + TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed + ? "" : "un", (unsigned int) c_byte); + + if (c_byte > srclength || (index + c_byte) > sblk->bytes_used) + goto read_failure; + + for (b = 1; bytes < c_byte; b++) { + bh[b] = sb_getblk(s, ++cur_index); + if (bh[b] == NULL) + goto block_release; + bytes += msblk->devblksize; + } + ll_rw_block(READ, b - 1, bh + 1); + } + + if (compressed) { + int zlib_err = 0; + + /* + * uncompress block + */ + + mutex_lock(&msblk->read_data_mutex); + + msblk->stream.next_out = buffer; + msblk->stream.avail_out = srclength; + + for (bytes = 0; k < b; k++) { + avail_bytes = min(c_byte - bytes, msblk->devblksize - offset); + + wait_on_buffer(bh[k]); + if (!buffer_uptodate(bh[k])) + goto release_mutex; + + msblk->stream.next_in = bh[k]->b_data + offset; + msblk->stream.avail_in = avail_bytes; + + if (k == 0) { + zlib_err = zlib_inflateInit(&msblk->stream); + if (zlib_err != Z_OK) { + ERROR("zlib_inflateInit returned unexpected result 0x%x," + " srclength %d\n", zlib_err, srclength); + goto release_mutex; + } + + if (avail_bytes == 0) { + offset = 0; + brelse(bh[k]); + continue; + } + } + + zlib_err = zlib_inflate(&msblk->stream, Z_NO_FLUSH); + if (zlib_err != Z_OK && zlib_err != Z_STREAM_END) { + ERROR("zlib_inflate returned unexpected result 0x%x," + " srclength %d, avail_in %d, avail_out %d\n", zlib_err, + srclength, msblk->stream.avail_in, msblk->stream.avail_out); + goto release_mutex; + } + + bytes += avail_bytes; + offset = 0; + brelse(bh[k]); + } + + if (zlib_err != Z_STREAM_END) + goto release_mutex; + + zlib_err = zlib_inflateEnd(&msblk->stream); + if (zlib_err != Z_OK) { + ERROR("zlib_inflateEnd returned unexpected result 0x%x," + " srclength %d\n", zlib_err, srclength); + goto release_mutex; + } + bytes = msblk->stream.total_out; + mutex_unlock(&msblk->read_data_mutex); + } else { + int i; + + for(i = 0; i < b; i++) { + wait_on_buffer(bh[i]); + if (!buffer_uptodate(bh[i])) + goto block_release; + } + + for (bytes = 0; k < b; k++) { + avail_bytes = min(c_byte - bytes, msblk->devblksize - offset); + + memcpy(buffer + bytes, bh[k]->b_data + offset, avail_bytes); + bytes += avail_bytes; + offset = 0; + brelse(bh[k]); + } + } + + if (next_index) + *next_index = index + c_byte + (length ? 0 : + (SQUASHFS_CHECK_DATA(msblk->sblk.flags) ? 3 : 2)); + + kfree(bh); + return bytes; + +release_mutex: + mutex_unlock(&msblk->read_data_mutex); + +block_release: + for (; k < b; k++) + brelse(bh[k]); + +read_failure: + ERROR("sb_bread failed reading block 0x%x\n", cur_index); + kfree(bh); + return 0; +} + + +SQSH_EXTERN int squashfs_get_cached_block(struct super_block *s, void *buffer, + long long block, unsigned int offset, + int length, long long *next_block, + unsigned int *next_offset) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + int n, i, bytes, return_length = length; + long long next_index; + + TRACE("Entered squashfs_get_cached_block [%llx:%x]\n", block, offset); + + while (1) { + for (i = 0; i < squashfs_cached_blks; i++) + if (msblk->block_cache[i].block == block) + break; + + mutex_lock(&msblk->block_cache_mutex); + + if (i == squashfs_cached_blks) { + /* read inode header block */ + if (msblk->unused_cache_blks == 0) { + mutex_unlock(&msblk->block_cache_mutex); + wait_event(msblk->waitq, msblk->unused_cache_blks); + continue; + } + + i = msblk->next_cache; + for (n = 0; n < squashfs_cached_blks; n++) { + if (msblk->block_cache[i].block != SQUASHFS_USED_BLK) + break; + i = (i + 1) % squashfs_cached_blks; + } + + msblk->next_cache = (i + 1) % squashfs_cached_blks; + + if (msblk->block_cache[i].block == SQUASHFS_INVALID_BLK) { + msblk->block_cache[i].data = vmalloc(SQUASHFS_METADATA_SIZE); + if (msblk->block_cache[i].data == NULL) { + ERROR("Failed to allocate cache block\n"); + mutex_unlock(&msblk->block_cache_mutex); + goto out; + } + } + + msblk->block_cache[i].block = SQUASHFS_USED_BLK; + msblk->unused_cache_blks --; + mutex_unlock(&msblk->block_cache_mutex); + + msblk->block_cache[i].length = squashfs_read_data(s, + msblk->block_cache[i].data, block, 0, &next_index, + SQUASHFS_METADATA_SIZE); + + if (msblk->block_cache[i].length == 0) { + ERROR("Unable to read cache block [%llx:%x]\n", block, offset); + mutex_lock(&msblk->block_cache_mutex); + msblk->block_cache[i].block = SQUASHFS_INVALID_BLK; + msblk->unused_cache_blks ++; + smp_mb(); + vfree(msblk->block_cache[i].data); + wake_up(&msblk->waitq); + mutex_unlock(&msblk->block_cache_mutex); + goto out; + } + + mutex_lock(&msblk->block_cache_mutex); + msblk->block_cache[i].block = block; + msblk->block_cache[i].next_index = next_index; + msblk->unused_cache_blks ++; + smp_mb(); + wake_up(&msblk->waitq); + TRACE("Read cache block [%llx:%x]\n", block, offset); + } + + if (msblk->block_cache[i].block != block) { + mutex_unlock(&msblk->block_cache_mutex); + continue; + } + + bytes = msblk->block_cache[i].length - offset; + + if (bytes < 1) { + mutex_unlock(&msblk->block_cache_mutex); + goto out; + } else if (bytes >= length) { + if (buffer) + memcpy(buffer, msblk->block_cache[i].data + offset, length); + if (msblk->block_cache[i].length - offset == length) { + *next_block = msblk->block_cache[i].next_index; + *next_offset = 0; + } else { + *next_block = block; + *next_offset = offset + length; + } + mutex_unlock(&msblk->block_cache_mutex); + goto finish; + } else { + if (buffer) { + memcpy(buffer, msblk->block_cache[i].data + offset, bytes); + buffer = (char *) buffer + bytes; + } + block = msblk->block_cache[i].next_index; + mutex_unlock(&msblk->block_cache_mutex); + length -= bytes; + offset = 0; + } + } + +finish: + return return_length; +out: + return 0; +} + + +static int get_fragment_location(struct super_block *s, unsigned int fragment, + long long *fragment_start_block, + unsigned int *fragment_size) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + long long start_block = + msblk->fragment_index[SQUASHFS_FRAGMENT_INDEX(fragment)]; + int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET(fragment); + struct squashfs_fragment_entry fragment_entry; + + if (msblk->swap) { + struct squashfs_fragment_entry sfragment_entry; + + if (!squashfs_get_cached_block(s, &sfragment_entry, start_block, offset, + sizeof(sfragment_entry), &start_block, &offset)) + goto out; + SQUASHFS_SWAP_FRAGMENT_ENTRY(&fragment_entry, &sfragment_entry); + } else + if (!squashfs_get_cached_block(s, &fragment_entry, start_block, offset, + sizeof(fragment_entry), &start_block, &offset)) + goto out; + + *fragment_start_block = fragment_entry.start_block; + *fragment_size = fragment_entry.size; + + return 1; + +out: + return 0; +} + + +SQSH_EXTERN void release_cached_fragment(struct squashfs_sb_info *msblk, + struct squashfs_fragment_cache *fragment) +{ + mutex_lock(&msblk->fragment_mutex); + fragment->locked --; + if (fragment->locked == 0) { + msblk->unused_frag_blks ++; + smp_mb(); + wake_up(&msblk->fragment_wait_queue); + } + mutex_unlock(&msblk->fragment_mutex); +} + + +SQSH_EXTERN +struct squashfs_fragment_cache *get_cached_fragment(struct super_block *s, + long long start_block, int length) +{ + int i, n; + struct squashfs_sb_info *msblk = s->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + + while (1) { + mutex_lock(&msblk->fragment_mutex); + + for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS && + msblk->fragment[i].block != start_block; i++); + + if (i == SQUASHFS_CACHED_FRAGMENTS) { + if (msblk->unused_frag_blks == 0) { + mutex_unlock(&msblk->fragment_mutex); + wait_event(msblk->fragment_wait_queue, msblk->unused_frag_blks); + continue; + } + + i = msblk->next_fragment; + for (n = 0; n < SQUASHFS_CACHED_FRAGMENTS; n++) { + if (msblk->fragment[i].locked == 0) + break; + i = (i + 1) % SQUASHFS_CACHED_FRAGMENTS; + } + + msblk->next_fragment = (msblk->next_fragment + 1) % + SQUASHFS_CACHED_FRAGMENTS; + + if (msblk->fragment[i].data == NULL) { + msblk->fragment[i].data = vmalloc(sblk->block_size); + if (msblk->fragment[i].data == NULL) { + ERROR("Failed to allocate fragment cache block\n"); + mutex_unlock(&msblk->fragment_mutex); + goto out; + } + } + + msblk->unused_frag_blks --; + msblk->fragment[i].block = SQUASHFS_INVALID_BLK; + msblk->fragment[i].locked = 1; + mutex_unlock(&msblk->fragment_mutex); + + msblk->fragment[i].length = squashfs_read_data(s, + msblk->fragment[i].data, start_block, length, NULL, + sblk->block_size); + + if (msblk->fragment[i].length == 0) { + ERROR("Unable to read fragment cache block [%llx]\n", start_block); + msblk->fragment[i].locked = 0; + msblk->unused_frag_blks ++; + smp_mb(); + wake_up(&msblk->fragment_wait_queue); + goto out; + } + + mutex_lock(&msblk->fragment_mutex); + msblk->fragment[i].block = start_block; + TRACE("New fragment %d, start block %lld, locked %d\n", + i, msblk->fragment[i].block, msblk->fragment[i].locked); + mutex_unlock(&msblk->fragment_mutex); + break; + } + + if (msblk->fragment[i].locked == 0) + msblk->unused_frag_blks --; + msblk->fragment[i].locked++; + mutex_unlock(&msblk->fragment_mutex); + TRACE("Got fragment %d, start block %lld, locked %d\n", i, + msblk->fragment[i].block, msblk->fragment[i].locked); + break; + } + + return &msblk->fragment[i]; + +out: + return NULL; +} + + +static void squashfs_new_inode(struct squashfs_sb_info *msblk, struct inode *i, + struct squashfs_base_inode_header *inodeb) +{ + i->i_ino = inodeb->inode_number; + i->i_mtime.tv_sec = inodeb->mtime; + i->i_atime.tv_sec = inodeb->mtime; + i->i_ctime.tv_sec = inodeb->mtime; + i->i_uid = msblk->uid[inodeb->uid]; + i->i_mode = inodeb->mode; + i->i_size = 0; + + if (inodeb->guid == SQUASHFS_GUIDS) + i->i_gid = i->i_uid; + else + i->i_gid = msblk->guid[inodeb->guid]; +} + +#ifdef USE_EXPORT +static squashfs_inode_t squashfs_inode_lookup(struct super_block *s, int ino) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + long long start = msblk->inode_lookup_table[SQUASHFS_LOOKUP_BLOCK(ino - 1)]; + int offset = SQUASHFS_LOOKUP_BLOCK_OFFSET(ino - 1); + squashfs_inode_t inode; + + TRACE("Entered squashfs_inode_lookup, inode_number = %d\n", ino); + + if (msblk->swap) { + squashfs_inode_t sinode; + + if (!squashfs_get_cached_block(s, &sinode, start, offset, + sizeof(sinode), &start, &offset)) + goto out; + SQUASHFS_SWAP_INODE_T((&inode), &sinode); + } else if (!squashfs_get_cached_block(s, &inode, start, offset, + sizeof(inode), &start, &offset)) + goto out; + + TRACE("squashfs_inode_lookup, inode = 0x%llx\n", inode); + + return inode; + +out: + return SQUASHFS_INVALID_BLK; +} + +static struct dentry *squashfs_get_parent(struct dentry *child) +{ + struct inode *i = child->d_inode; + struct inode *parent = iget(i->i_sb, SQUASHFS_I(i)->u.s2.parent_inode); + struct dentry *rv; + + TRACE("Entered squashfs_get_parent\n"); + + if(parent == NULL) { + rv = ERR_PTR(-EACCES); + goto out; + } + + rv = d_alloc_anon(parent); + if(rv == NULL) + rv = ERR_PTR(-ENOMEM); + +out: + return rv; +} +#endif + +SQSH_EXTERN struct inode *squashfs_iget(struct super_block *s, + squashfs_inode_t inode, unsigned int inode_number) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + struct inode *i = iget_locked(s, inode_number); + + TRACE("Entered squashfs_iget\n"); + + if (!i) + return ERR_PTR(-ENOMEM); + + if (i->i_state & I_NEW) { + (msblk->read_inode)(i, inode); + unlock_new_inode(i); + } + + return i; +} + + +static int squashfs_read_inode(struct inode *i, squashfs_inode_t inode) +{ + struct super_block *s = i->i_sb; + struct squashfs_sb_info *msblk = s->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + long long block = SQUASHFS_INODE_BLK(inode) + sblk->inode_table_start; + unsigned int offset = SQUASHFS_INODE_OFFSET(inode); + long long next_block; + unsigned int next_offset; + union squashfs_inode_header id, sid; + struct squashfs_base_inode_header *inodeb = &id.base, *sinodeb = &sid.base; + + TRACE("Entered squashfs_read_inode\n"); + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, sinodeb, block, offset, + sizeof(*sinodeb), &next_block, &next_offset)) + goto failed_read; + SQUASHFS_SWAP_BASE_INODE_HEADER(inodeb, sinodeb, sizeof(*sinodeb)); + } else + if (!squashfs_get_cached_block(s, inodeb, block, offset, + sizeof(*inodeb), &next_block, &next_offset)) + goto failed_read; + + squashfs_new_inode(msblk, i, inodeb); + + switch(inodeb->inode_type) { + case SQUASHFS_FILE_TYPE: { + unsigned int frag_size; + long long frag_blk; + struct squashfs_reg_inode_header *inodep = &id.reg; + struct squashfs_reg_inode_header *sinodep = &sid.reg; + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, sinodep, block, offset, + sizeof(*sinodep), &next_block, &next_offset)) + goto failed_read; + SQUASHFS_SWAP_REG_INODE_HEADER(inodep, sinodep); + } else + if (!squashfs_get_cached_block(s, inodep, block, offset, + sizeof(*inodep), &next_block, &next_offset)) + goto failed_read; + + frag_blk = SQUASHFS_INVALID_BLK; + + if (inodep->fragment != SQUASHFS_INVALID_FRAG) + if(!get_fragment_location(s, inodep->fragment, &frag_blk, + &frag_size)) + goto failed_read; + + i->i_nlink = 1; + i->i_size = inodep->file_size; + i->i_fop = &generic_ro_fops; + i->i_mode |= S_IFREG; + i->i_blocks = ((i->i_size - 1) >> 9) + 1; + SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk; + SQUASHFS_I(i)->u.s1.fragment_size = frag_size; + SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset; + SQUASHFS_I(i)->start_block = inodep->start_block; + SQUASHFS_I(i)->u.s1.block_list_start = next_block; + SQUASHFS_I(i)->offset = next_offset; + i->i_data.a_ops = &squashfs_aops; + + TRACE("File inode %x:%x, start_block %llx, " + "block_list_start %llx, offset %x\n", + SQUASHFS_INODE_BLK(inode), offset, + inodep->start_block, next_block, + next_offset); + break; + } + case SQUASHFS_LREG_TYPE: { + unsigned int frag_size; + long long frag_blk; + struct squashfs_lreg_inode_header *inodep = &id.lreg; + struct squashfs_lreg_inode_header *sinodep = &sid.lreg; + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, sinodep, block, offset, + sizeof(*sinodep), &next_block, &next_offset)) + goto failed_read; + SQUASHFS_SWAP_LREG_INODE_HEADER(inodep, sinodep); + } else + if (!squashfs_get_cached_block(s, inodep, block, offset, + sizeof(*inodep), &next_block, &next_offset)) + goto failed_read; + + frag_blk = SQUASHFS_INVALID_BLK; + + if (inodep->fragment != SQUASHFS_INVALID_FRAG) + if (!get_fragment_location(s, inodep->fragment, &frag_blk, + &frag_size)) + goto failed_read; + + i->i_nlink = inodep->nlink; + i->i_size = inodep->file_size; + i->i_fop = &generic_ro_fops; + i->i_mode |= S_IFREG; + i->i_blocks = ((i->i_size - 1) >> 9) + 1; + SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk; + SQUASHFS_I(i)->u.s1.fragment_size = frag_size; + SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset; + SQUASHFS_I(i)->start_block = inodep->start_block; + SQUASHFS_I(i)->u.s1.block_list_start = next_block; + SQUASHFS_I(i)->offset = next_offset; + i->i_data.a_ops = &squashfs_aops; + + TRACE("File inode %x:%x, start_block %llx, " + "block_list_start %llx, offset %x\n", + SQUASHFS_INODE_BLK(inode), offset, + inodep->start_block, next_block, + next_offset); + break; + } + case SQUASHFS_DIR_TYPE: { + struct squashfs_dir_inode_header *inodep = &id.dir; + struct squashfs_dir_inode_header *sinodep = &sid.dir; + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, sinodep, block, offset, + sizeof(*sinodep), &next_block, &next_offset)) + goto failed_read; + SQUASHFS_SWAP_DIR_INODE_HEADER(inodep, sinodep); + } else + if (!squashfs_get_cached_block(s, inodep, block, offset, + sizeof(*inodep), &next_block, &next_offset)) + goto failed_read; + + i->i_nlink = inodep->nlink; + i->i_size = inodep->file_size; + i->i_op = &squashfs_dir_inode_ops; + i->i_fop = &squashfs_dir_ops; + i->i_mode |= S_IFDIR; + SQUASHFS_I(i)->start_block = inodep->start_block; + SQUASHFS_I(i)->offset = inodep->offset; + SQUASHFS_I(i)->u.s2.directory_index_count = 0; + SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode; + + TRACE("Directory inode %x:%x, start_block %x, offset " + "%x\n", SQUASHFS_INODE_BLK(inode), + offset, inodep->start_block, + inodep->offset); + break; + } + case SQUASHFS_LDIR_TYPE: { + struct squashfs_ldir_inode_header *inodep = &id.ldir; + struct squashfs_ldir_inode_header *sinodep = &sid.ldir; + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, sinodep, block, offset, + sizeof(*sinodep), &next_block, &next_offset)) + goto failed_read; + SQUASHFS_SWAP_LDIR_INODE_HEADER(inodep, sinodep); + } else + if (!squashfs_get_cached_block(s, inodep, block, offset, + sizeof(*inodep), &next_block, &next_offset)) + goto failed_read; + + i->i_nlink = inodep->nlink; + i->i_size = inodep->file_size; + i->i_op = &squashfs_dir_inode_ops; + i->i_fop = &squashfs_dir_ops; + i->i_mode |= S_IFDIR; + SQUASHFS_I(i)->start_block = inodep->start_block; + SQUASHFS_I(i)->offset = inodep->offset; + SQUASHFS_I(i)->u.s2.directory_index_start = next_block; + SQUASHFS_I(i)->u.s2.directory_index_offset = next_offset; + SQUASHFS_I(i)->u.s2.directory_index_count = inodep->i_count; + SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode; + + TRACE("Long directory inode %x:%x, start_block %x, offset %x\n", + SQUASHFS_INODE_BLK(inode), offset, + inodep->start_block, inodep->offset); + break; + } + case SQUASHFS_SYMLINK_TYPE: { + struct squashfs_symlink_inode_header *inodep = &id.symlink; + struct squashfs_symlink_inode_header *sinodep = &sid.symlink; + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, sinodep, block, offset, + sizeof(*sinodep), &next_block, &next_offset)) + goto failed_read; + SQUASHFS_SWAP_SYMLINK_INODE_HEADER(inodep, sinodep); + } else + if (!squashfs_get_cached_block(s, inodep, block, offset, + sizeof(*inodep), &next_block, &next_offset)) + goto failed_read; + + i->i_nlink = inodep->nlink; + i->i_size = inodep->symlink_size; + i->i_op = &page_symlink_inode_operations; + i->i_data.a_ops = &squashfs_symlink_aops; + i->i_mode |= S_IFLNK; + SQUASHFS_I(i)->start_block = next_block; + SQUASHFS_I(i)->offset = next_offset; + + TRACE("Symbolic link inode %x:%x, start_block %llx, offset %x\n", + SQUASHFS_INODE_BLK(inode), offset, + next_block, next_offset); + break; + } + case SQUASHFS_BLKDEV_TYPE: + case SQUASHFS_CHRDEV_TYPE: { + struct squashfs_dev_inode_header *inodep = &id.dev; + struct squashfs_dev_inode_header *sinodep = &sid.dev; + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, sinodep, block, offset, + sizeof(*sinodep), &next_block, &next_offset)) + goto failed_read; + SQUASHFS_SWAP_DEV_INODE_HEADER(inodep, sinodep); + } else + if (!squashfs_get_cached_block(s, inodep, block, offset, + sizeof(*inodep), &next_block, &next_offset)) + goto failed_read; + + i->i_nlink = inodep->nlink; + i->i_mode |= (inodeb->inode_type == SQUASHFS_CHRDEV_TYPE) ? + S_IFCHR : S_IFBLK; + init_special_inode(i, i->i_mode, old_decode_dev(inodep->rdev)); + + TRACE("Device inode %x:%x, rdev %x\n", + SQUASHFS_INODE_BLK(inode), offset, inodep->rdev); + break; + } + case SQUASHFS_FIFO_TYPE: + case SQUASHFS_SOCKET_TYPE: { + struct squashfs_ipc_inode_header *inodep = &id.ipc; + struct squashfs_ipc_inode_header *sinodep = &sid.ipc; + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, sinodep, block, offset, + sizeof(*sinodep), &next_block, &next_offset)) + goto failed_read; + SQUASHFS_SWAP_IPC_INODE_HEADER(inodep, sinodep); + } else + if (!squashfs_get_cached_block(s, inodep, block, offset, + sizeof(*inodep), &next_block, &next_offset)) + goto failed_read; + + i->i_nlink = inodep->nlink; + i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE) + ? S_IFIFO : S_IFSOCK; + init_special_inode(i, i->i_mode, 0); + break; + } + default: + ERROR("Unknown inode type %d in squashfs_iget!\n", + inodeb->inode_type); + goto failed_read1; + } + + return 1; + +failed_read: + ERROR("Unable to read inode [%llx:%x]\n", block, offset); + +failed_read1: + make_bad_inode(i); + return 0; +} + + +static int read_inode_lookup_table(struct super_block *s) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + unsigned int length = SQUASHFS_LOOKUP_BLOCK_BYTES(sblk->inodes); + + TRACE("In read_inode_lookup_table, length %d\n", length); + + /* Allocate inode lookup table */ + msblk->inode_lookup_table = kmalloc(length, GFP_KERNEL); + if (msblk->inode_lookup_table == NULL) { + ERROR("Failed to allocate inode lookup table\n"); + return 0; + } + + if (!squashfs_read_data(s, (char *) msblk->inode_lookup_table, + sblk->lookup_table_start, length | + SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) { + ERROR("unable to read inode lookup table\n"); + return 0; + } + + if (msblk->swap) { + int i; + long long block; + + for (i = 0; i < SQUASHFS_LOOKUP_BLOCKS(sblk->inodes); i++) { + /* XXX */ + SQUASHFS_SWAP_LOOKUP_BLOCKS((&block), + &msblk->inode_lookup_table[i], 1); + msblk->inode_lookup_table[i] = block; + } + } + + return 1; +} + + +static int read_fragment_index_table(struct super_block *s) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + unsigned int length = SQUASHFS_FRAGMENT_INDEX_BYTES(sblk->fragments); + + if(length == 0) + return 1; + + /* Allocate fragment index table */ + msblk->fragment_index = kmalloc(length, GFP_KERNEL); + if (msblk->fragment_index == NULL) { + ERROR("Failed to allocate fragment index table\n"); + return 0; + } + + if (!squashfs_read_data(s, (char *) msblk->fragment_index, + sblk->fragment_table_start, length | + SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) { + ERROR("unable to read fragment index table\n"); + return 0; + } + + if (msblk->swap) { + int i; + long long fragment; + + for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES(sblk->fragments); i++) { + /* XXX */ + SQUASHFS_SWAP_FRAGMENT_INDEXES((&fragment), + &msblk->fragment_index[i], 1); + msblk->fragment_index[i] = fragment; + } + } + + return 1; +} + + +static int readahead_metadata(struct super_block *s) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + int i; + + squashfs_cached_blks = SQUASHFS_CACHED_BLKS; + + /* Init inode_table block pointer array */ + msblk->block_cache = kmalloc(sizeof(struct squashfs_cache) * + squashfs_cached_blks, GFP_KERNEL); + if (msblk->block_cache == NULL) { + ERROR("Failed to allocate block cache\n"); + goto failed; + } + + for (i = 0; i < squashfs_cached_blks; i++) + msblk->block_cache[i].block = SQUASHFS_INVALID_BLK; + + msblk->next_cache = 0; + msblk->unused_cache_blks = squashfs_cached_blks; + + return 1; + +failed: + return 0; +} + + +static int supported_squashfs_filesystem(struct squashfs_sb_info *msblk, int silent) +{ + struct squashfs_super_block *sblk = &msblk->sblk; + + msblk->read_inode = squashfs_read_inode; + msblk->read_blocklist = read_blocklist; + msblk->read_fragment_index_table = read_fragment_index_table; + + if (sblk->s_major == 1) { + if (!squashfs_1_0_supported(msblk)) { + SERROR("Major/Minor mismatch, Squashfs 1.0 filesystems " + "are unsupported\n"); + SERROR("Please recompile with Squashfs 1.0 support enabled\n"); + return 0; + } + } else if (sblk->s_major == 2) { + if (!squashfs_2_0_supported(msblk)) { + SERROR("Major/Minor mismatch, Squashfs 2.0 filesystems " + "are unsupported\n"); + SERROR("Please recompile with Squashfs 2.0 support enabled\n"); + return 0; + } + } else if(sblk->s_major != SQUASHFS_MAJOR || sblk->s_minor > + SQUASHFS_MINOR) { + SERROR("Major/Minor mismatch, trying to mount newer %d.%d " + "filesystem\n", sblk->s_major, sblk->s_minor); + SERROR("Please update your kernel\n"); + return 0; + } + + return 1; +} + + +static int squashfs_fill_super(struct super_block *s, void *data, int silent) +{ + struct squashfs_sb_info *msblk; + struct squashfs_super_block *sblk; + int i; + char b[BDEVNAME_SIZE]; + struct inode *root; + + TRACE("Entered squashfs_fill_superblock\n"); + + s->s_fs_info = kzalloc(sizeof(struct squashfs_sb_info), GFP_KERNEL); + if (s->s_fs_info == NULL) { + ERROR("Failed to allocate superblock\n"); + goto failure; + } + msblk = s->s_fs_info; + + msblk->stream.workspace = vmalloc(zlib_inflate_workspacesize()); + if (msblk->stream.workspace == NULL) { + ERROR("Failed to allocate zlib workspace\n"); + goto failure; + } + sblk = &msblk->sblk; + + msblk->devblksize = sb_min_blocksize(s, BLOCK_SIZE); + msblk->devblksize_log2 = ffz(~msblk->devblksize); + + mutex_init(&msblk->read_data_mutex); + mutex_init(&msblk->read_page_mutex); + mutex_init(&msblk->block_cache_mutex); + mutex_init(&msblk->fragment_mutex); + mutex_init(&msblk->meta_index_mutex); + + init_waitqueue_head(&msblk->waitq); + init_waitqueue_head(&msblk->fragment_wait_queue); + + /* sblk->bytes_used is checked in squashfs_read_data to ensure reads are not + * beyond filesystem end. As we're using squashfs_read_data to read sblk here, + * first set sblk->bytes_used to a useful value */ + sblk->bytes_used = sizeof(struct squashfs_super_block); + if (!squashfs_read_data(s, (char *) sblk, SQUASHFS_START, + sizeof(struct squashfs_super_block) | + SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, sizeof(struct squashfs_super_block))) { + SERROR("unable to read superblock\n"); + goto failed_mount; + } + + /* Check it is a SQUASHFS superblock */ + if ((s->s_magic = sblk->s_magic) != SQUASHFS_MAGIC) { + if (sblk->s_magic == SQUASHFS_MAGIC_SWAP) { + struct squashfs_super_block ssblk; + + WARNING("Mounting a different endian SQUASHFS filesystem on %s\n", + bdevname(s->s_bdev, b)); + + SQUASHFS_SWAP_SUPER_BLOCK(&ssblk, sblk); + memcpy(sblk, &ssblk, sizeof(struct squashfs_super_block)); + msblk->swap = 1; + } else { + SERROR("Can't find a SQUASHFS superblock on %s\n", + bdevname(s->s_bdev, b)); + goto failed_mount; + } + } + + /* Check the MAJOR & MINOR versions */ + if(!supported_squashfs_filesystem(msblk, silent)) + goto failed_mount; + + /* Check the filesystem does not extend beyond the end of the + block device */ + if(sblk->bytes_used < 0 || sblk->bytes_used > i_size_read(s->s_bdev->bd_inode)) + goto failed_mount; + + /* Check the root inode for sanity */ + if (SQUASHFS_INODE_OFFSET(sblk->root_inode) > SQUASHFS_METADATA_SIZE) + goto failed_mount; + + TRACE("Found valid superblock on %s\n", bdevname(s->s_bdev, b)); + TRACE("Inodes are %scompressed\n", SQUASHFS_UNCOMPRESSED_INODES(sblk->flags) + ? "un" : ""); + TRACE("Data is %scompressed\n", SQUASHFS_UNCOMPRESSED_DATA(sblk->flags) + ? "un" : ""); + TRACE("Check data is %spresent in the filesystem\n", + SQUASHFS_CHECK_DATA(sblk->flags) ? "" : "not "); + TRACE("Filesystem size %lld bytes\n", sblk->bytes_used); + TRACE("Block size %d\n", sblk->block_size); + TRACE("Number of inodes %d\n", sblk->inodes); + if (sblk->s_major > 1) + TRACE("Number of fragments %d\n", sblk->fragments); + TRACE("Number of uids %d\n", sblk->no_uids); + TRACE("Number of gids %d\n", sblk->no_guids); + TRACE("sblk->inode_table_start %llx\n", sblk->inode_table_start); + TRACE("sblk->directory_table_start %llx\n", sblk->directory_table_start); + if (sblk->s_major > 1) + TRACE("sblk->fragment_table_start %llx\n", sblk->fragment_table_start); + TRACE("sblk->uid_start %llx\n", sblk->uid_start); + + s->s_maxbytes = MAX_LFS_FILESIZE; + s->s_flags |= MS_RDONLY; + s->s_op = &squashfs_super_ops; + + if (readahead_metadata(s) == 0) + goto failed_mount; + + /* Allocate read_page block */ + msblk->read_page = vmalloc(sblk->block_size); + if (msblk->read_page == NULL) { + ERROR("Failed to allocate read_page block\n"); + goto failed_mount; + } + + /* Allocate uid and gid tables */ + msblk->uid = kmalloc((sblk->no_uids + sblk->no_guids) * + sizeof(unsigned int), GFP_KERNEL); + if (msblk->uid == NULL) { + ERROR("Failed to allocate uid/gid table\n"); + goto failed_mount; + } + msblk->guid = msblk->uid + sblk->no_uids; + + if (msblk->swap) { + unsigned int suid[sblk->no_uids + sblk->no_guids]; + + if (!squashfs_read_data(s, (char *) &suid, sblk->uid_start, + ((sblk->no_uids + sblk->no_guids) * + sizeof(unsigned int)) | + SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, (sblk->no_uids + sblk->no_guids) * sizeof(unsigned int))) { + ERROR("unable to read uid/gid table\n"); + goto failed_mount; + } + + SQUASHFS_SWAP_DATA(msblk->uid, suid, (sblk->no_uids + + sblk->no_guids), (sizeof(unsigned int) * 8)); + } else + if (!squashfs_read_data(s, (char *) msblk->uid, sblk->uid_start, + ((sblk->no_uids + sblk->no_guids) * + sizeof(unsigned int)) | + SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, (sblk->no_uids + sblk->no_guids) * sizeof(unsigned int))) { + ERROR("unable to read uid/gid table\n"); + goto failed_mount; + } + + + if (sblk->s_major == 1 && squashfs_1_0_supported(msblk)) + goto allocate_root; + + msblk->fragment = kzalloc(sizeof(struct squashfs_fragment_cache) * + SQUASHFS_CACHED_FRAGMENTS, GFP_KERNEL); + if (msblk->fragment == NULL) { + ERROR("Failed to allocate fragment block cache\n"); + goto failed_mount; + } + + for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++) { + msblk->fragment[i].block = SQUASHFS_INVALID_BLK; + } + + msblk->next_fragment = 0; + msblk->unused_frag_blks = SQUASHFS_CACHED_FRAGMENTS; + + /* Allocate and read fragment index table */ + if (msblk->read_fragment_index_table(s) == 0) + goto failed_mount; + + if(sblk->s_major < 3 || sblk->lookup_table_start == SQUASHFS_INVALID_BLK) + goto allocate_root; + + /* Allocate and read inode lookup table */ + if (read_inode_lookup_table(s) == 0) + goto failed_mount; + + s->s_op = &squashfs_export_super_ops; +#ifdef USE_EXPORT + s->s_export_op = &squashfs_export_ops; +#endif + +allocate_root: + root = new_inode(s); + if ((msblk->read_inode)(root, sblk->root_inode) == 0) + goto failed_mount; + insert_inode_hash(root); + + s->s_root = d_alloc_root(root); + if (s->s_root == NULL) { + ERROR("Root inode create failed\n"); + iput(root); + goto failed_mount; + } + + TRACE("Leaving squashfs_fill_super\n"); + return 0; + +failed_mount: + kfree(msblk->inode_lookup_table); + kfree(msblk->fragment_index); + kfree(msblk->fragment); + kfree(msblk->uid); + vfree(msblk->read_page); + kfree(msblk->block_cache); + kfree(msblk->fragment_index_2); + vfree(msblk->stream.workspace); + kfree(s->s_fs_info); + s->s_fs_info = NULL; + return -EINVAL; + +failure: + return -ENOMEM; +} + + +static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf) +{ + struct squashfs_sb_info *msblk = dentry->d_sb->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + + TRACE("Entered squashfs_statfs\n"); + + buf->f_type = SQUASHFS_MAGIC; + buf->f_bsize = sblk->block_size; + buf->f_blocks = ((sblk->bytes_used - 1) >> sblk->block_log) + 1; + buf->f_bfree = buf->f_bavail = 0; + buf->f_files = sblk->inodes; + buf->f_ffree = 0; + buf->f_namelen = SQUASHFS_NAME_LEN; + + return 0; +} + + +static int squashfs_symlink_readpage(struct file *file, struct page *page) +{ + struct inode *inode = page->mapping->host; + int index = page->index << PAGE_CACHE_SHIFT, length, bytes, avail_bytes; + long long block = SQUASHFS_I(inode)->start_block; + int offset = SQUASHFS_I(inode)->offset; + void *pageaddr = kmap(page); + + TRACE("Entered squashfs_symlink_readpage, page index %ld, start block " + "%llx, offset %x\n", page->index, + SQUASHFS_I(inode)->start_block, + SQUASHFS_I(inode)->offset); + + for (length = 0; length < index; length += bytes) { + bytes = squashfs_get_cached_block(inode->i_sb, NULL, block, + offset, PAGE_CACHE_SIZE, &block, &offset); + if (bytes == 0) { + ERROR("Unable to read symbolic link [%llx:%x]\n", block, offset); + goto skip_read; + } + } + + if (length != index) { + ERROR("(squashfs_symlink_readpage) length != index\n"); + bytes = 0; + goto skip_read; + } + + avail_bytes = min_t(int, i_size_read(inode) - length, PAGE_CACHE_SIZE); + + bytes = squashfs_get_cached_block(inode->i_sb, pageaddr, block, offset, + avail_bytes, &block, &offset); + if (bytes == 0) + ERROR("Unable to read symbolic link [%llx:%x]\n", block, offset); + +skip_read: + memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes); + kunmap(page); + flush_dcache_page(page); + SetPageUptodate(page); + unlock_page(page); + + return 0; +} + + +struct meta_index *locate_meta_index(struct inode *inode, int index, int offset) +{ + struct meta_index *meta = NULL; + struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; + int i; + + mutex_lock(&msblk->meta_index_mutex); + + TRACE("locate_meta_index: index %d, offset %d\n", index, offset); + + if (msblk->meta_index == NULL) + goto not_allocated; + + for (i = 0; i < SQUASHFS_META_NUMBER; i ++) { + if (msblk->meta_index[i].inode_number == inode->i_ino && + msblk->meta_index[i].offset >= offset && + msblk->meta_index[i].offset <= index && + msblk->meta_index[i].locked == 0) { + TRACE("locate_meta_index: entry %d, offset %d\n", i, + msblk->meta_index[i].offset); + meta = &msblk->meta_index[i]; + offset = meta->offset; + } + } + + if (meta) + meta->locked = 1; + +not_allocated: + mutex_unlock(&msblk->meta_index_mutex); + + return meta; +} + + +struct meta_index *empty_meta_index(struct inode *inode, int offset, int skip) +{ + struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; + struct meta_index *meta = NULL; + int i; + + mutex_lock(&msblk->meta_index_mutex); + + TRACE("empty_meta_index: offset %d, skip %d\n", offset, skip); + + if (msblk->meta_index == NULL) { + msblk->meta_index = kmalloc(sizeof(struct meta_index) * + SQUASHFS_META_NUMBER, GFP_KERNEL); + if (msblk->meta_index == NULL) { + ERROR("Failed to allocate meta_index\n"); + goto failed; + } + for (i = 0; i < SQUASHFS_META_NUMBER; i++) { + msblk->meta_index[i].inode_number = 0; + msblk->meta_index[i].locked = 0; + } + msblk->next_meta_index = 0; + } + + for (i = SQUASHFS_META_NUMBER; i && + msblk->meta_index[msblk->next_meta_index].locked; i --) + msblk->next_meta_index = (msblk->next_meta_index + 1) % + SQUASHFS_META_NUMBER; + + if (i == 0) { + TRACE("empty_meta_index: failed!\n"); + goto failed; + } + + TRACE("empty_meta_index: returned meta entry %d, %p\n", + msblk->next_meta_index, + &msblk->meta_index[msblk->next_meta_index]); + + meta = &msblk->meta_index[msblk->next_meta_index]; + msblk->next_meta_index = (msblk->next_meta_index + 1) % + SQUASHFS_META_NUMBER; + + meta->inode_number = inode->i_ino; + meta->offset = offset; + meta->skip = skip; + meta->entries = 0; + meta->locked = 1; + +failed: + mutex_unlock(&msblk->meta_index_mutex); + return meta; +} + + +void release_meta_index(struct inode *inode, struct meta_index *meta) +{ + meta->locked = 0; + smp_mb(); +} + + +static int read_block_index(struct super_block *s, int blocks, char *block_list, + long long *start_block, int *offset) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + unsigned int *block_listp; + int block = 0; + + if (msblk->swap) { + char sblock_list[blocks << 2]; + + if (!squashfs_get_cached_block(s, sblock_list, *start_block, + *offset, blocks << 2, start_block, offset)) { + ERROR("Fail reading block list [%llx:%x]\n", *start_block, *offset); + goto failure; + } + SQUASHFS_SWAP_INTS(((unsigned int *)block_list), + ((unsigned int *)sblock_list), blocks); + } else { + if (!squashfs_get_cached_block(s, block_list, *start_block, + *offset, blocks << 2, start_block, offset)) { + ERROR("Fail reading block list [%llx:%x]\n", *start_block, *offset); + goto failure; + } + } + + for (block_listp = (unsigned int *) block_list; blocks; + block_listp++, blocks --) + block += SQUASHFS_COMPRESSED_SIZE_BLOCK(*block_listp); + + return block; + +failure: + return -1; +} + + +#define SIZE 256 + +static inline int calculate_skip(int blocks) { + int skip = (blocks - 1) / ((SQUASHFS_SLOTS * SQUASHFS_META_ENTRIES + 1) * SQUASHFS_META_INDEXES); + return skip >= 7 ? 7 : skip + 1; +} + + +static int get_meta_index(struct inode *inode, int index, + long long *index_block, int *index_offset, + long long *data_block, char *block_list) +{ + struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + int skip = calculate_skip(i_size_read(inode) >> sblk->block_log); + int offset = 0; + struct meta_index *meta; + struct meta_entry *meta_entry; + long long cur_index_block = SQUASHFS_I(inode)->u.s1.block_list_start; + int cur_offset = SQUASHFS_I(inode)->offset; + long long cur_data_block = SQUASHFS_I(inode)->start_block; + int i; + + index /= SQUASHFS_META_INDEXES * skip; + + while (offset < index) { + meta = locate_meta_index(inode, index, offset + 1); + + if (meta == NULL) { + meta = empty_meta_index(inode, offset + 1, skip); + if (meta == NULL) + goto all_done; + } else { + if(meta->entries == 0) + goto failed; + /* XXX */ + offset = index < meta->offset + meta->entries ? index : + meta->offset + meta->entries - 1; + /* XXX */ + meta_entry = &meta->meta_entry[offset - meta->offset]; + cur_index_block = meta_entry->index_block + sblk->inode_table_start; + cur_offset = meta_entry->offset; + cur_data_block = meta_entry->data_block; + TRACE("get_meta_index: offset %d, meta->offset %d, " + "meta->entries %d\n", offset, meta->offset, meta->entries); + TRACE("get_meta_index: index_block 0x%llx, offset 0x%x" + " data_block 0x%llx\n", cur_index_block, + cur_offset, cur_data_block); + } + + for (i = meta->offset + meta->entries; i <= index && + i < meta->offset + SQUASHFS_META_ENTRIES; i++) { + int blocks = skip * SQUASHFS_META_INDEXES; + + while (blocks) { + int block = blocks > (SIZE >> 2) ? (SIZE >> 2) : blocks; + int res = read_block_index(inode->i_sb, block, block_list, + &cur_index_block, &cur_offset); + + if (res == -1) + goto failed; + + cur_data_block += res; + blocks -= block; + } + + meta_entry = &meta->meta_entry[i - meta->offset]; + meta_entry->index_block = cur_index_block - sblk->inode_table_start; + meta_entry->offset = cur_offset; + meta_entry->data_block = cur_data_block; + meta->entries ++; + offset ++; + } + + TRACE("get_meta_index: meta->offset %d, meta->entries %d\n", + meta->offset, meta->entries); + + release_meta_index(inode, meta); + } + +all_done: + *index_block = cur_index_block; + *index_offset = cur_offset; + *data_block = cur_data_block; + + return offset * SQUASHFS_META_INDEXES * skip; + +failed: + release_meta_index(inode, meta); + return -1; +} + + +static long long read_blocklist(struct inode *inode, int index, + int readahead_blks, char *block_list, + unsigned short **block_p, unsigned int *bsize) +{ + long long block_ptr; + int offset; + long long block; + int res = get_meta_index(inode, index, &block_ptr, &offset, &block, + block_list); + + TRACE("read_blocklist: res %d, index %d, block_ptr 0x%llx, offset" + " 0x%x, block 0x%llx\n", res, index, block_ptr, offset, block); + + if(res == -1) + goto failure; + + index -= res; + + while (index) { + int blocks = index > (SIZE >> 2) ? (SIZE >> 2) : index; + int res = read_block_index(inode->i_sb, blocks, block_list, + &block_ptr, &offset); + if (res == -1) + goto failure; + block += res; + index -= blocks; + } + + if (read_block_index(inode->i_sb, 1, block_list, &block_ptr, &offset) == -1) + goto failure; + *bsize = *((unsigned int *) block_list); + + return block; + +failure: + return 0; +} + + +static int squashfs_readpage(struct file *file, struct page *page) +{ + struct inode *inode = page->mapping->host; + struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + unsigned char *block_list = NULL; + long long block; + unsigned int bsize, i; + int bytes; + int index = page->index >> (sblk->block_log - PAGE_CACHE_SHIFT); + void *pageaddr; + struct squashfs_fragment_cache *fragment = NULL; + char *data_ptr = msblk->read_page; + + int mask = (1 << (sblk->block_log - PAGE_CACHE_SHIFT)) - 1; + int start_index = page->index & ~mask; + int end_index = start_index | mask; + int file_end = i_size_read(inode) >> sblk->block_log; + int sparse = 0; + + TRACE("Entered squashfs_readpage, page index %lx, start block %llx\n", + page->index, SQUASHFS_I(inode)->start_block); + + if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> + PAGE_CACHE_SHIFT)) + goto out; + + if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK + || index < file_end) { + block_list = kmalloc(SIZE, GFP_KERNEL); + if (block_list == NULL) { + ERROR("Failed to allocate block_list\n"); + goto error_out; + } + + block = (msblk->read_blocklist)(inode, index, 1, block_list, NULL, &bsize); + if (block == 0) + goto error_out; + + if (bsize == 0) { /* hole */ + bytes = index == file_end ? + (i_size_read(inode) & (sblk->block_size - 1)) : sblk->block_size; + sparse = 1; + } else { + mutex_lock(&msblk->read_page_mutex); + + bytes = squashfs_read_data(inode->i_sb, msblk->read_page, block, + bsize, NULL, sblk->block_size); + + if (bytes == 0) { + ERROR("Unable to read page, block %llx, size %x\n", block, bsize); + mutex_unlock(&msblk->read_page_mutex); + goto error_out; + } + } + } else { + fragment = get_cached_fragment(inode->i_sb, + SQUASHFS_I(inode)-> u.s1.fragment_start_block, + SQUASHFS_I(inode)->u.s1.fragment_size); + + if (fragment == NULL) { + ERROR("Unable to read page, block %llx, size %x\n", + SQUASHFS_I(inode)->u.s1.fragment_start_block, + (int) SQUASHFS_I(inode)->u.s1.fragment_size); + goto error_out; + } + bytes = i_size_read(inode) & (sblk->block_size - 1); + data_ptr = fragment->data + SQUASHFS_I(inode)->u.s1.fragment_offset; + } + + for (i = start_index; i <= end_index && bytes > 0; i++, + bytes -= PAGE_CACHE_SIZE, data_ptr += PAGE_CACHE_SIZE) { + struct page *push_page; + int avail = sparse ? 0 : min_t(unsigned int, bytes, PAGE_CACHE_SIZE); + + TRACE("bytes %d, i %d, available_bytes %d\n", bytes, i, avail); + + push_page = (i == page->index) ? page : + grab_cache_page_nowait(page->mapping, i); + + if (!push_page) + continue; + + if (PageUptodate(push_page)) + goto skip_page; + + pageaddr = kmap_atomic(push_page, KM_USER0); + memcpy(pageaddr, data_ptr, avail); + memset(pageaddr + avail, 0, PAGE_CACHE_SIZE - avail); + kunmap_atomic(pageaddr, KM_USER0); + flush_dcache_page(push_page); + SetPageUptodate(push_page); +skip_page: + unlock_page(push_page); + if(i != page->index) + page_cache_release(push_page); + } + + if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK + || index < file_end) { + if (!sparse) + mutex_unlock(&msblk->read_page_mutex); + kfree(block_list); + } else + release_cached_fragment(msblk, fragment); + + return 0; + +error_out: + SetPageError(page); +out: + pageaddr = kmap_atomic(page, KM_USER0); + memset(pageaddr, 0, PAGE_CACHE_SIZE); + kunmap_atomic(pageaddr, KM_USER0); + flush_dcache_page(page); + if (!PageError(page)) + SetPageUptodate(page); + unlock_page(page); + + kfree(block_list); + return 0; +} + + +static int get_dir_index_using_offset(struct super_block *s, + long long *next_block, unsigned int *next_offset, + long long index_start, unsigned int index_offset, int i_count, + long long f_pos) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + int i, length = 0; + struct squashfs_dir_index index; + + TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n", + i_count, (unsigned int) f_pos); + + f_pos =- 3; + if (f_pos == 0) + goto finish; + + for (i = 0; i < i_count; i++) { + if (msblk->swap) { + struct squashfs_dir_index sindex; + squashfs_get_cached_block(s, &sindex, index_start, index_offset, + sizeof(sindex), &index_start, &index_offset); + SQUASHFS_SWAP_DIR_INDEX(&index, &sindex); + } else + squashfs_get_cached_block(s, &index, index_start, index_offset, + sizeof(index), &index_start, &index_offset); + + if (index.index > f_pos) + break; + + squashfs_get_cached_block(s, NULL, index_start, index_offset, + index.size + 1, &index_start, &index_offset); + + length = index.index; + *next_block = index.start_block + sblk->directory_table_start; + } + + *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; + +finish: + return length + 3; +} + + +static int get_dir_index_using_name(struct super_block *s, + long long *next_block, unsigned int *next_offset, + long long index_start, unsigned int index_offset, int i_count, + const char *name, int size) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + int i, length = 0; + struct squashfs_dir_index *index; + char *str; + + TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count); + + str = kmalloc(sizeof(struct squashfs_dir_index) + + (SQUASHFS_NAME_LEN + 1) * 2, GFP_KERNEL); + if (str == NULL) { + ERROR("Failed to allocate squashfs_dir_index\n"); + goto failure; + } + + index = (struct squashfs_dir_index *) (str + SQUASHFS_NAME_LEN + 1); + strncpy(str, name, size); + str[size] = '\0'; + + for (i = 0; i < i_count; i++) { + if (msblk->swap) { + struct squashfs_dir_index sindex; + squashfs_get_cached_block(s, &sindex, index_start, index_offset, + sizeof(sindex), &index_start, &index_offset); + SQUASHFS_SWAP_DIR_INDEX(index, &sindex); + } else + squashfs_get_cached_block(s, index, index_start, index_offset, + sizeof(struct squashfs_dir_index), &index_start, &index_offset); + + squashfs_get_cached_block(s, index->name, index_start, index_offset, + index->size + 1, &index_start, &index_offset); + + index->name[index->size + 1] = '\0'; + + if (strcmp(index->name, str) > 0) + break; + + length = index->index; + *next_block = index->start_block + sblk->directory_table_start; + } + + *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; + kfree(str); + +failure: + return length + 3; +} + + +static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir) +{ + struct inode *i = file->f_dentry->d_inode; + struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + long long next_block = SQUASHFS_I(i)->start_block + + sblk->directory_table_start; + int next_offset = SQUASHFS_I(i)->offset, length = 0, dir_count; + struct squashfs_dir_header dirh; + struct squashfs_dir_entry *dire; + + TRACE("Entered squashfs_readdir [%llx:%x]\n", next_block, next_offset); + + dire = kmalloc(sizeof(struct squashfs_dir_entry) + + SQUASHFS_NAME_LEN + 1, GFP_KERNEL); + if (dire == NULL) { + ERROR("Failed to allocate squashfs_dir_entry\n"); + goto finish; + } + + while(file->f_pos < 3) { + char *name; + int size, i_ino; + + if(file->f_pos == 0) { + name = "."; + size = 1; + i_ino = i->i_ino; + } else { + name = ".."; + size = 2; + i_ino = SQUASHFS_I(i)->u.s2.parent_inode; + } + TRACE("Calling filldir(%x, %s, %d, %d, %d, %d)\n", + (unsigned int) dirent, name, size, (int) + file->f_pos, i_ino, squashfs_filetype_table[1]); + + if (filldir(dirent, name, size, file->f_pos, i_ino, + squashfs_filetype_table[1]) < 0) { + TRACE("Filldir returned less than 0\n"); + goto finish; + } + file->f_pos += size; + } + + length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset, + SQUASHFS_I(i)->u.s2.directory_index_start, + SQUASHFS_I(i)->u.s2.directory_index_offset, + SQUASHFS_I(i)->u.s2.directory_index_count, file->f_pos); + + while (length < i_size_read(i)) { + /* read directory header */ + if (msblk->swap) { + struct squashfs_dir_header sdirh; + + if (!squashfs_get_cached_block(i->i_sb, &sdirh, next_block, + next_offset, sizeof(sdirh), &next_block, &next_offset)) + goto failed_read; + + length += sizeof(sdirh); + SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh); + } else { + if (!squashfs_get_cached_block(i->i_sb, &dirh, next_block, + next_offset, sizeof(dirh), &next_block, &next_offset)) + goto failed_read; + + length += sizeof(dirh); + } + + dir_count = dirh.count + 1; + while (dir_count--) { + if (msblk->swap) { + struct squashfs_dir_entry sdire; + if (!squashfs_get_cached_block(i->i_sb, &sdire, next_block, + next_offset, sizeof(sdire), &next_block, &next_offset)) + goto failed_read; + + length += sizeof(sdire); + SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire); + } else { + if (!squashfs_get_cached_block(i->i_sb, dire, next_block, + next_offset, sizeof(*dire), &next_block, &next_offset)) + goto failed_read; + + length += sizeof(*dire); + } + + if (!squashfs_get_cached_block(i->i_sb, dire->name, next_block, + next_offset, dire->size + 1, &next_block, &next_offset)) + goto failed_read; + + length += dire->size + 1; + + if (file->f_pos >= length) + continue; + + dire->name[dire->size + 1] = '\0'; + + TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d, %d)\n", + (unsigned int) dirent, dire->name, dire->size + 1, + (int) file->f_pos, dirh.start_block, dire->offset, + dirh.inode_number + dire->inode_number, + squashfs_filetype_table[dire->type]); + + if (filldir(dirent, dire->name, dire->size + 1, file->f_pos, + dirh.inode_number + dire->inode_number, + squashfs_filetype_table[dire->type]) < 0) { + TRACE("Filldir returned less than 0\n"); + goto finish; + } + file->f_pos = length; + } + } + +finish: + kfree(dire); + return 0; + +failed_read: + ERROR("Unable to read directory block [%llx:%x]\n", next_block, + next_offset); + kfree(dire); + return 0; +} + + +static struct dentry *squashfs_lookup(struct inode *i, struct dentry *dentry, + struct nameidata *nd) +{ + const unsigned char *name = dentry->d_name.name; + int len = dentry->d_name.len; + struct inode *inode = NULL; + struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + long long next_block = SQUASHFS_I(i)->start_block + + sblk->directory_table_start; + int next_offset = SQUASHFS_I(i)->offset, length = 0, dir_count; + struct squashfs_dir_header dirh; + struct squashfs_dir_entry *dire; + + TRACE("Entered squashfs_lookup [%llx:%x]\n", next_block, next_offset); + + dire = kmalloc(sizeof(struct squashfs_dir_entry) + + SQUASHFS_NAME_LEN + 1, GFP_KERNEL); + if (dire == NULL) { + ERROR("Failed to allocate squashfs_dir_entry\n"); + goto exit_lookup; + } + + if (len > SQUASHFS_NAME_LEN) + goto exit_lookup; + + length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset, + SQUASHFS_I(i)->u.s2.directory_index_start, + SQUASHFS_I(i)->u.s2.directory_index_offset, + SQUASHFS_I(i)->u.s2.directory_index_count, name, len); + + while (length < i_size_read(i)) { + /* read directory header */ + if (msblk->swap) { + struct squashfs_dir_header sdirh; + if (!squashfs_get_cached_block(i->i_sb, &sdirh, next_block, + next_offset, sizeof(sdirh), &next_block, &next_offset)) + goto failed_read; + + length += sizeof(sdirh); + SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh); + } else { + if (!squashfs_get_cached_block(i->i_sb, &dirh, next_block, + next_offset, sizeof(dirh), &next_block, &next_offset)) + goto failed_read; + + length += sizeof(dirh); + } + + dir_count = dirh.count + 1; + while (dir_count--) { + if (msblk->swap) { + struct squashfs_dir_entry sdire; + if (!squashfs_get_cached_block(i->i_sb, &sdire, next_block, + next_offset, sizeof(sdire), &next_block, &next_offset)) + goto failed_read; + + length += sizeof(sdire); + SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire); + } else { + if (!squashfs_get_cached_block(i->i_sb, dire, next_block, + next_offset, sizeof(*dire), &next_block, &next_offset)) + goto failed_read; + + length += sizeof(*dire); + } + + if (!squashfs_get_cached_block(i->i_sb, dire->name, next_block, + next_offset, dire->size + 1, &next_block, &next_offset)) + goto failed_read; + + length += dire->size + 1; + + if (name[0] < dire->name[0]) + goto exit_lookup; + + if ((len == dire->size + 1) && !strncmp(name, dire->name, len)) { + squashfs_inode_t ino = SQUASHFS_MKINODE(dirh.start_block, + dire->offset); + + TRACE("calling squashfs_iget for directory entry %s, inode" + " %x:%x, %d\n", name, dirh.start_block, dire->offset, + dirh.inode_number + dire->inode_number); + + inode = squashfs_iget(i->i_sb, ino, dirh.inode_number + dire->inode_number); + + goto exit_lookup; + } + } + } + +exit_lookup: + kfree(dire); + if (inode) + return d_splice_alias(inode, dentry); + d_add(dentry, inode); + return ERR_PTR(0); + +failed_read: + ERROR("Unable to read directory block [%llx:%x]\n", next_block, + next_offset); + goto exit_lookup; +} + + +static int squashfs_remount(struct super_block *s, int *flags, char *data) +{ + *flags |= MS_RDONLY; + return 0; +} + + +static void squashfs_put_super(struct super_block *s) +{ + int i; + + if (s->s_fs_info) { + struct squashfs_sb_info *sbi = s->s_fs_info; + if (sbi->block_cache) + for (i = 0; i < squashfs_cached_blks; i++) + if (sbi->block_cache[i].block != SQUASHFS_INVALID_BLK) + vfree(sbi->block_cache[i].data); + if (sbi->fragment) + for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++) + vfree(sbi->fragment[i].data); + kfree(sbi->fragment); + kfree(sbi->block_cache); + vfree(sbi->read_page); + kfree(sbi->uid); + kfree(sbi->fragment_index); + kfree(sbi->fragment_index_2); + kfree(sbi->meta_index); + vfree(sbi->stream.workspace); + kfree(s->s_fs_info); + s->s_fs_info = NULL; + } +} + + +static int squashfs_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *data, struct vfsmount *mnt) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, squashfs_fill_super, + mnt); +} + + +static int __init init_squashfs_fs(void) +{ + int err = init_inodecache(); + if (err) + goto out; + + printk(KERN_INFO "squashfs: version 3.3 (2007/10/31) " + "Phillip Lougher\n"); + + err = register_filesystem(&squashfs_fs_type); + if (err) + destroy_inodecache(); + +out: + return err; +} + + +static void __exit exit_squashfs_fs(void) +{ + unregister_filesystem(&squashfs_fs_type); + destroy_inodecache(); +} + + +static struct kmem_cache * squashfs_inode_cachep; + + +static struct inode *squashfs_alloc_inode(struct super_block *sb) +{ + struct squashfs_inode_info *ei; + ei = kmem_cache_alloc(squashfs_inode_cachep, GFP_KERNEL); + return ei ? &ei->vfs_inode : NULL; +} + + +static void squashfs_destroy_inode(struct inode *inode) +{ + kmem_cache_free(squashfs_inode_cachep, SQUASHFS_I(inode)); +} + + +static void init_once(void *foo) +{ + struct squashfs_inode_info *ei = foo; + + inode_init_once(&ei->vfs_inode); +} + + +static int __init init_inodecache(void) +{ + squashfs_inode_cachep = kmem_cache_create("squashfs_inode_cache", + sizeof(struct squashfs_inode_info), 0, + SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT, init_once); + if (squashfs_inode_cachep == NULL) + return -ENOMEM; + return 0; +} + + +static void destroy_inodecache(void) +{ + kmem_cache_destroy(squashfs_inode_cachep); +} + + +module_init(init_squashfs_fs); +module_exit(exit_squashfs_fs); +MODULE_DESCRIPTION("squashfs 3.2-r2-CVS, a compressed read-only filesystem"); +MODULE_AUTHOR("Phillip Lougher "); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/ubuntu/squashfs/Makefile +++ linux-2.6.28/ubuntu/squashfs/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for the linux squashfs routines. +# + +obj-$(CONFIG_SQUASHFS) += squashfs.o +squashfs-objs := inode.o squashfs2_0.o --- linux-2.6.28.orig/ubuntu/squashfs/squashfs2_0.c +++ linux-2.6.28/ubuntu/squashfs/squashfs2_0.c @@ -0,0 +1,740 @@ +/* + * Squashfs - a compressed read only filesystem for Linux + * + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 + * Phillip Lougher + * + * This program is free software; you can redistribute 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * squashfs2_0.c + */ + +#include +#include +#include +#include +#include +#include + +#include "squashfs.h" +static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir); +static struct dentry *squashfs_lookup_2(struct inode *, struct dentry *, + struct nameidata *); + +static struct file_operations squashfs_dir_ops_2 = { + .read = generic_read_dir, + .readdir = squashfs_readdir_2 +}; + +static struct inode_operations squashfs_dir_inode_ops_2 = { + .lookup = squashfs_lookup_2 +}; + +static unsigned char squashfs_filetype_table[] = { + DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK +}; + +static int read_fragment_index_table_2(struct super_block *s) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + + if (!(msblk->fragment_index_2 = kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES_2 + (sblk->fragments), GFP_KERNEL))) { + ERROR("Failed to allocate uid/gid table\n"); + return 0; + } + + if (SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments) && + !squashfs_read_data(s, (char *) + msblk->fragment_index_2, + sblk->fragment_table_start, + SQUASHFS_FRAGMENT_INDEX_BYTES_2 + (sblk->fragments) | + SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments))) { + ERROR("unable to read fragment index table\n"); + return 0; + } + + if (msblk->swap) { + int i; + unsigned int fragment; + + for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES_2(sblk->fragments); + i++) { + SQUASHFS_SWAP_FRAGMENT_INDEXES_2((&fragment), + &msblk->fragment_index_2[i], 1); + msblk->fragment_index_2[i] = fragment; + } + } + + return 1; +} + + +static int get_fragment_location_2(struct super_block *s, unsigned int fragment, + long long *fragment_start_block, + unsigned int *fragment_size) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + long long start_block = + msblk->fragment_index_2[SQUASHFS_FRAGMENT_INDEX_2(fragment)]; + int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET_2(fragment); + struct squashfs_fragment_entry_2 fragment_entry; + + if (msblk->swap) { + struct squashfs_fragment_entry_2 sfragment_entry; + + if (!squashfs_get_cached_block(s, (char *) &sfragment_entry, + start_block, offset, + sizeof(sfragment_entry), &start_block, + &offset)) + goto out; + SQUASHFS_SWAP_FRAGMENT_ENTRY_2(&fragment_entry, &sfragment_entry); + } else + if (!squashfs_get_cached_block(s, (char *) &fragment_entry, + start_block, offset, + sizeof(fragment_entry), &start_block, + &offset)) + goto out; + + *fragment_start_block = fragment_entry.start_block; + *fragment_size = fragment_entry.size; + + return 1; + +out: + return 0; +} + + +static void squashfs_new_inode(struct squashfs_sb_info *msblk, struct inode *i, + struct squashfs_base_inode_header_2 *inodeb, unsigned int ino) +{ + struct squashfs_super_block *sblk = &msblk->sblk; + + i->i_ino = ino; + i->i_mtime.tv_sec = sblk->mkfs_time; + i->i_atime.tv_sec = sblk->mkfs_time; + i->i_ctime.tv_sec = sblk->mkfs_time; + i->i_uid = msblk->uid[inodeb->uid]; + i->i_mode = inodeb->mode; + i->i_nlink = 1; + i->i_size = 0; + if (inodeb->guid == SQUASHFS_GUIDS) + i->i_gid = i->i_uid; + else + i->i_gid = msblk->guid[inodeb->guid]; +} + + +static int squashfs_read_inode_2(struct inode *i, squashfs_inode_t inode) +{ + struct super_block *s = i->i_sb; + struct squashfs_sb_info *msblk = s->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + unsigned int block = SQUASHFS_INODE_BLK(inode) + + sblk->inode_table_start; + unsigned int offset = SQUASHFS_INODE_OFFSET(inode); + unsigned int ino = SQUASHFS_MK_VFS_INODE(block - + sblk->inode_table_start, offset); + long long next_block; + unsigned int next_offset; + union squashfs_inode_header_2 id, sid; + struct squashfs_base_inode_header_2 *inodeb = &id.base, + *sinodeb = &sid.base; + + TRACE("Entered squashfs_read_inode_2\n"); + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, (char *) sinodeb, block, + offset, sizeof(*sinodeb), &next_block, + &next_offset)) + goto failed_read; + SQUASHFS_SWAP_BASE_INODE_HEADER_2(inodeb, sinodeb, + sizeof(*sinodeb)); + } else + if (!squashfs_get_cached_block(s, (char *) inodeb, block, + offset, sizeof(*inodeb), &next_block, + &next_offset)) + goto failed_read; + + squashfs_new_inode(msblk, i, inodeb, ino); + + switch(inodeb->inode_type) { + case SQUASHFS_FILE_TYPE: { + struct squashfs_reg_inode_header_2 *inodep = &id.reg; + struct squashfs_reg_inode_header_2 *sinodep = &sid.reg; + long long frag_blk; + unsigned int frag_size = 0; + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, (char *) + sinodep, block, offset, + sizeof(*sinodep), &next_block, + &next_offset)) + goto failed_read; + SQUASHFS_SWAP_REG_INODE_HEADER_2(inodep, sinodep); + } else + if (!squashfs_get_cached_block(s, (char *) + inodep, block, offset, + sizeof(*inodep), &next_block, + &next_offset)) + goto failed_read; + + frag_blk = SQUASHFS_INVALID_BLK; + if (inodep->fragment != SQUASHFS_INVALID_FRAG && + !get_fragment_location_2(s, + inodep->fragment, &frag_blk, &frag_size)) + goto failed_read; + + i->i_size = inodep->file_size; + i->i_fop = &generic_ro_fops; + i->i_mode |= S_IFREG; + i->i_mtime.tv_sec = inodep->mtime; + i->i_atime.tv_sec = inodep->mtime; + i->i_ctime.tv_sec = inodep->mtime; + i->i_blocks = ((i->i_size - 1) >> 9) + 1; + SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk; + SQUASHFS_I(i)->u.s1.fragment_size = frag_size; + SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset; + SQUASHFS_I(i)->start_block = inodep->start_block; + SQUASHFS_I(i)->u.s1.block_list_start = next_block; + SQUASHFS_I(i)->offset = next_offset; + i->i_data.a_ops = &squashfs_aops; + + TRACE("File inode %x:%x, start_block %x, " + "block_list_start %llx, offset %x\n", + SQUASHFS_INODE_BLK(inode), offset, + inodep->start_block, next_block, + next_offset); + break; + } + case SQUASHFS_DIR_TYPE: { + struct squashfs_dir_inode_header_2 *inodep = &id.dir; + struct squashfs_dir_inode_header_2 *sinodep = &sid.dir; + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, (char *) + sinodep, block, offset, + sizeof(*sinodep), &next_block, + &next_offset)) + goto failed_read; + SQUASHFS_SWAP_DIR_INODE_HEADER_2(inodep, sinodep); + } else + if (!squashfs_get_cached_block(s, (char *) + inodep, block, offset, + sizeof(*inodep), &next_block, + &next_offset)) + goto failed_read; + + i->i_size = inodep->file_size; + i->i_op = &squashfs_dir_inode_ops_2; + i->i_fop = &squashfs_dir_ops_2; + i->i_mode |= S_IFDIR; + i->i_mtime.tv_sec = inodep->mtime; + i->i_atime.tv_sec = inodep->mtime; + i->i_ctime.tv_sec = inodep->mtime; + SQUASHFS_I(i)->start_block = inodep->start_block; + SQUASHFS_I(i)->offset = inodep->offset; + SQUASHFS_I(i)->u.s2.directory_index_count = 0; + SQUASHFS_I(i)->u.s2.parent_inode = 0; + + TRACE("Directory inode %x:%x, start_block %x, offset " + "%x\n", SQUASHFS_INODE_BLK(inode), + offset, inodep->start_block, + inodep->offset); + break; + } + case SQUASHFS_LDIR_TYPE: { + struct squashfs_ldir_inode_header_2 *inodep = &id.ldir; + struct squashfs_ldir_inode_header_2 *sinodep = &sid.ldir; + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, (char *) + sinodep, block, offset, + sizeof(*sinodep), &next_block, + &next_offset)) + goto failed_read; + SQUASHFS_SWAP_LDIR_INODE_HEADER_2(inodep, + sinodep); + } else + if (!squashfs_get_cached_block(s, (char *) + inodep, block, offset, + sizeof(*inodep), &next_block, + &next_offset)) + goto failed_read; + + i->i_size = inodep->file_size; + i->i_op = &squashfs_dir_inode_ops_2; + i->i_fop = &squashfs_dir_ops_2; + i->i_mode |= S_IFDIR; + i->i_mtime.tv_sec = inodep->mtime; + i->i_atime.tv_sec = inodep->mtime; + i->i_ctime.tv_sec = inodep->mtime; + SQUASHFS_I(i)->start_block = inodep->start_block; + SQUASHFS_I(i)->offset = inodep->offset; + SQUASHFS_I(i)->u.s2.directory_index_start = next_block; + SQUASHFS_I(i)->u.s2.directory_index_offset = + next_offset; + SQUASHFS_I(i)->u.s2.directory_index_count = + inodep->i_count; + SQUASHFS_I(i)->u.s2.parent_inode = 0; + + TRACE("Long directory inode %x:%x, start_block %x, " + "offset %x\n", + SQUASHFS_INODE_BLK(inode), offset, + inodep->start_block, inodep->offset); + break; + } + case SQUASHFS_SYMLINK_TYPE: { + struct squashfs_symlink_inode_header_2 *inodep = + &id.symlink; + struct squashfs_symlink_inode_header_2 *sinodep = + &sid.symlink; + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, (char *) + sinodep, block, offset, + sizeof(*sinodep), &next_block, + &next_offset)) + goto failed_read; + SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(inodep, + sinodep); + } else + if (!squashfs_get_cached_block(s, (char *) + inodep, block, offset, + sizeof(*inodep), &next_block, + &next_offset)) + goto failed_read; + + i->i_size = inodep->symlink_size; + i->i_op = &page_symlink_inode_operations; + i->i_data.a_ops = &squashfs_symlink_aops; + i->i_mode |= S_IFLNK; + SQUASHFS_I(i)->start_block = next_block; + SQUASHFS_I(i)->offset = next_offset; + + TRACE("Symbolic link inode %x:%x, start_block %llx, " + "offset %x\n", + SQUASHFS_INODE_BLK(inode), offset, + next_block, next_offset); + break; + } + case SQUASHFS_BLKDEV_TYPE: + case SQUASHFS_CHRDEV_TYPE: { + struct squashfs_dev_inode_header_2 *inodep = &id.dev; + struct squashfs_dev_inode_header_2 *sinodep = &sid.dev; + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, (char *) + sinodep, block, offset, + sizeof(*sinodep), &next_block, + &next_offset)) + goto failed_read; + SQUASHFS_SWAP_DEV_INODE_HEADER_2(inodep, sinodep); + } else + if (!squashfs_get_cached_block(s, (char *) + inodep, block, offset, + sizeof(*inodep), &next_block, + &next_offset)) + goto failed_read; + + i->i_mode |= (inodeb->inode_type == + SQUASHFS_CHRDEV_TYPE) ? S_IFCHR : + S_IFBLK; + init_special_inode(i, i->i_mode, + old_decode_dev(inodep->rdev)); + + TRACE("Device inode %x:%x, rdev %x\n", + SQUASHFS_INODE_BLK(inode), offset, + inodep->rdev); + break; + } + case SQUASHFS_FIFO_TYPE: + case SQUASHFS_SOCKET_TYPE: { + + i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE) + ? S_IFIFO : S_IFSOCK; + init_special_inode(i, i->i_mode, 0); + break; + } + default: + ERROR("Unknown inode type %d in squashfs_iget!\n", + inodeb->inode_type); + goto failed_read1; + } + + return 1; + +failed_read: + ERROR("Unable to read inode [%x:%x]\n", block, offset); + +failed_read1: + return 0; +} + + +static int get_dir_index_using_offset(struct super_block *s, long long + *next_block, unsigned int *next_offset, + long long index_start, + unsigned int index_offset, int i_count, + long long f_pos) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + int i, length = 0; + struct squashfs_dir_index_2 index; + + TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n", + i_count, (unsigned int) f_pos); + + if (f_pos == 0) + goto finish; + + for (i = 0; i < i_count; i++) { + if (msblk->swap) { + struct squashfs_dir_index_2 sindex; + squashfs_get_cached_block(s, (char *) &sindex, + index_start, index_offset, + sizeof(sindex), &index_start, + &index_offset); + SQUASHFS_SWAP_DIR_INDEX_2(&index, &sindex); + } else + squashfs_get_cached_block(s, (char *) &index, + index_start, index_offset, + sizeof(index), &index_start, + &index_offset); + + if (index.index > f_pos) + break; + + squashfs_get_cached_block(s, NULL, index_start, index_offset, + index.size + 1, &index_start, + &index_offset); + + length = index.index; + *next_block = index.start_block + sblk->directory_table_start; + } + + *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; + +finish: + return length; +} + + +static int get_dir_index_using_name(struct super_block *s, long long + *next_block, unsigned int *next_offset, + long long index_start, + unsigned int index_offset, int i_count, + const char *name, int size) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + int i, length = 0; + struct squashfs_dir_index_2 *index; + char *str; + + TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count); + + if (!(str = kmalloc(sizeof(struct squashfs_dir_index) + + (SQUASHFS_NAME_LEN + 1) * 2, GFP_KERNEL))) { + ERROR("Failed to allocate squashfs_dir_index\n"); + goto failure; + } + + index = (struct squashfs_dir_index_2 *) (str + SQUASHFS_NAME_LEN + 1); + strncpy(str, name, size); + str[size] = '\0'; + + for (i = 0; i < i_count; i++) { + if (msblk->swap) { + struct squashfs_dir_index_2 sindex; + squashfs_get_cached_block(s, (char *) &sindex, + index_start, index_offset, + sizeof(sindex), &index_start, + &index_offset); + SQUASHFS_SWAP_DIR_INDEX_2(index, &sindex); + } else + squashfs_get_cached_block(s, (char *) index, + index_start, index_offset, + sizeof(struct squashfs_dir_index_2), + &index_start, &index_offset); + + squashfs_get_cached_block(s, index->name, index_start, + index_offset, index->size + 1, + &index_start, &index_offset); + + index->name[index->size + 1] = '\0'; + + if (strcmp(index->name, str) > 0) + break; + + length = index->index; + *next_block = index->start_block + sblk->directory_table_start; + } + + *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; + kfree(str); +failure: + return length; +} + + +static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir) +{ + struct inode *i = file->f_dentry->d_inode; + struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + long long next_block = SQUASHFS_I(i)->start_block + + sblk->directory_table_start; + int next_offset = SQUASHFS_I(i)->offset, length = 0, + dir_count; + struct squashfs_dir_header_2 dirh; + struct squashfs_dir_entry_2 *dire; + + TRACE("Entered squashfs_readdir_2 [%llx:%x]\n", next_block, next_offset); + + if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) + + SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) { + ERROR("Failed to allocate squashfs_dir_entry\n"); + goto finish; + } + + length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset, + SQUASHFS_I(i)->u.s2.directory_index_start, + SQUASHFS_I(i)->u.s2.directory_index_offset, + SQUASHFS_I(i)->u.s2.directory_index_count, + file->f_pos); + + while (length < i_size_read(i)) { + /* read directory header */ + if (msblk->swap) { + struct squashfs_dir_header_2 sdirh; + + if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh, + next_block, next_offset, sizeof(sdirh), + &next_block, &next_offset)) + goto failed_read; + + length += sizeof(sdirh); + SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh); + } else { + if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh, + next_block, next_offset, sizeof(dirh), + &next_block, &next_offset)) + goto failed_read; + + length += sizeof(dirh); + } + + dir_count = dirh.count + 1; + while (dir_count--) { + if (msblk->swap) { + struct squashfs_dir_entry_2 sdire; + if (!squashfs_get_cached_block(i->i_sb, (char *) + &sdire, next_block, next_offset, + sizeof(sdire), &next_block, + &next_offset)) + goto failed_read; + + length += sizeof(sdire); + SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire); + } else { + if (!squashfs_get_cached_block(i->i_sb, (char *) + dire, next_block, next_offset, + sizeof(*dire), &next_block, + &next_offset)) + goto failed_read; + + length += sizeof(*dire); + } + + if (!squashfs_get_cached_block(i->i_sb, dire->name, + next_block, next_offset, + dire->size + 1, &next_block, + &next_offset)) + goto failed_read; + + length += dire->size + 1; + + if (file->f_pos >= length) + continue; + + dire->name[dire->size + 1] = '\0'; + + TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d)\n", + (unsigned int) dirent, dire->name, + dire->size + 1, (int) file->f_pos, + dirh.start_block, dire->offset, + squashfs_filetype_table[dire->type]); + + if (filldir(dirent, dire->name, dire->size + 1, + file->f_pos, SQUASHFS_MK_VFS_INODE( + dirh.start_block, dire->offset), + squashfs_filetype_table[dire->type]) + < 0) { + TRACE("Filldir returned less than 0\n"); + goto finish; + } + file->f_pos = length; + } + } + +finish: + kfree(dire); + return 0; + +failed_read: + ERROR("Unable to read directory block [%llx:%x]\n", next_block, + next_offset); + kfree(dire); + return 0; +} + + +static struct dentry *squashfs_lookup_2(struct inode *i, struct dentry *dentry, + struct nameidata *nd) +{ + const unsigned char *name = dentry->d_name.name; + int len = dentry->d_name.len; + struct inode *inode = NULL; + struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + long long next_block = SQUASHFS_I(i)->start_block + + sblk->directory_table_start; + int next_offset = SQUASHFS_I(i)->offset, length = 0, + dir_count; + struct squashfs_dir_header_2 dirh; + struct squashfs_dir_entry_2 *dire; + int sorted = sblk->s_major == 2 && sblk->s_minor >= 1; + + TRACE("Entered squashfs_lookup_2 [%llx:%x]\n", next_block, next_offset); + + if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) + + SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) { + ERROR("Failed to allocate squashfs_dir_entry\n"); + goto exit_loop; + } + + if (len > SQUASHFS_NAME_LEN) + goto exit_loop; + + length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset, + SQUASHFS_I(i)->u.s2.directory_index_start, + SQUASHFS_I(i)->u.s2.directory_index_offset, + SQUASHFS_I(i)->u.s2.directory_index_count, name, + len); + + while (length < i_size_read(i)) { + /* read directory header */ + if (msblk->swap) { + struct squashfs_dir_header_2 sdirh; + if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh, + next_block, next_offset, sizeof(sdirh), + &next_block, &next_offset)) + goto failed_read; + + length += sizeof(sdirh); + SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh); + } else { + if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh, + next_block, next_offset, sizeof(dirh), + &next_block, &next_offset)) + goto failed_read; + + length += sizeof(dirh); + } + + dir_count = dirh.count + 1; + while (dir_count--) { + if (msblk->swap) { + struct squashfs_dir_entry_2 sdire; + if (!squashfs_get_cached_block(i->i_sb, (char *) + &sdire, next_block,next_offset, + sizeof(sdire), &next_block, + &next_offset)) + goto failed_read; + + length += sizeof(sdire); + SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire); + } else { + if (!squashfs_get_cached_block(i->i_sb, (char *) + dire, next_block,next_offset, + sizeof(*dire), &next_block, + &next_offset)) + goto failed_read; + + length += sizeof(*dire); + } + + if (!squashfs_get_cached_block(i->i_sb, dire->name, + next_block, next_offset, dire->size + 1, + &next_block, &next_offset)) + goto failed_read; + + length += dire->size + 1; + + if (sorted && name[0] < dire->name[0]) + goto exit_loop; + + if ((len == dire->size + 1) && !strncmp(name, + dire->name, len)) { + squashfs_inode_t ino = + SQUASHFS_MKINODE(dirh.start_block, + dire->offset); + unsigned int inode_number = SQUASHFS_MK_VFS_INODE(dirh.start_block, + dire->offset); + + TRACE("calling squashfs_iget for directory " + "entry %s, inode %x:%x, %lld\n", name, + dirh.start_block, dire->offset, ino); + + inode = squashfs_iget(i->i_sb, ino, inode_number); + + goto exit_loop; + } + } + } + +exit_loop: + kfree(dire); + d_add(dentry, inode); + return ERR_PTR(0); + +failed_read: + ERROR("Unable to read directory block [%llx:%x]\n", next_block, + next_offset); + goto exit_loop; +} + + +int squashfs_2_0_supported(struct squashfs_sb_info *msblk) +{ + struct squashfs_super_block *sblk = &msblk->sblk; + + msblk->read_inode = squashfs_read_inode_2; + msblk->read_fragment_index_table = read_fragment_index_table_2; + + sblk->bytes_used = sblk->bytes_used_2; + sblk->uid_start = sblk->uid_start_2; + sblk->guid_start = sblk->guid_start_2; + sblk->inode_table_start = sblk->inode_table_start_2; + sblk->directory_table_start = sblk->directory_table_start_2; + sblk->fragment_table_start = sblk->fragment_table_start_2; + + return 1; +} --- linux-2.6.28.orig/ubuntu/squashfs/squashfs.h +++ linux-2.6.28/ubuntu/squashfs/squashfs.h @@ -0,0 +1,86 @@ +/* + * Squashfs - a compressed read only filesystem for Linux + * + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 + * Phillip Lougher + * + * This program is free software; you can redistribute 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * squashfs.h + */ + +#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY +#undef CONFIG_SQUASHFS_1_0_COMPATIBILITY +#endif + +#ifdef SQUASHFS_TRACE +#define TRACE(s, args...) printk(KERN_NOTICE "SQUASHFS: "s, ## args) +#else +#define TRACE(s, args...) {} +#endif + +#define ERROR(s, args...) printk(KERN_ERR "SQUASHFS error: "s, ## args) + +#define SERROR(s, args...) do { \ + if (!silent) \ + printk(KERN_ERR "SQUASHFS error: "s, ## args);\ + } while(0) + +#define WARNING(s, args...) printk(KERN_WARNING "SQUASHFS: "s, ## args) + +static inline struct squashfs_inode_info *SQUASHFS_I(struct inode *inode) +{ + return list_entry(inode, struct squashfs_inode_info, vfs_inode); +} + +#if defined(CONFIG_SQUASHFS_1_0_COMPATIBILITY ) || defined(CONFIG_SQUASHFS_2_0_COMPATIBILITY) +#define SQSH_EXTERN +extern unsigned int squashfs_read_data(struct super_block *s, char *buffer, + long long index, unsigned int length, + long long *next_index, int srclength); +extern int squashfs_get_cached_block(struct super_block *s, void *buffer, + long long block, unsigned int offset, + int length, long long *next_block, + unsigned int *next_offset); +extern void release_cached_fragment(struct squashfs_sb_info *msblk, struct + squashfs_fragment_cache *fragment); +extern struct squashfs_fragment_cache *get_cached_fragment(struct super_block + *s, long long start_block, + int length); +extern struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode, unsigned int inode_number); +extern const struct address_space_operations squashfs_symlink_aops; +extern const struct address_space_operations squashfs_aops; +extern struct inode_operations squashfs_dir_inode_ops; +#else +#define SQSH_EXTERN static +#endif + +#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY +extern int squashfs_1_0_supported(struct squashfs_sb_info *msblk); +#else +static inline int squashfs_1_0_supported(struct squashfs_sb_info *msblk) +{ + return 0; +} +#endif + +#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY +extern int squashfs_2_0_supported(struct squashfs_sb_info *msblk); +#else +static inline int squashfs_2_0_supported(struct squashfs_sb_info *msblk) +{ + return 0; +} +#endif --- linux-2.6.28.orig/ubuntu/squashfs/BOM +++ linux-2.6.28/ubuntu/squashfs/BOM @@ -0,0 +1,2 @@ +Downloaded from: http://sourceforge.net/project/showfiles.php?group_id=63835 +Current Version: 3.3 --- linux-2.6.28.orig/drivers/Makefile +++ linux-2.6.28/drivers/Makefile @@ -84,6 +84,7 @@ obj-$(CONFIG_CPU_FREQ) += cpufreq/ obj-$(CONFIG_CPU_IDLE) += cpuidle/ obj-y += idle/ +obj-$(CONFIG_ARCH_MXC) += mxc/ obj-$(CONFIG_MMC) += mmc/ obj-$(CONFIG_MEMSTICK) += memstick/ obj-$(CONFIG_NEW_LEDS) += leds/ --- linux-2.6.28.orig/drivers/bluetooth/hci_usb.c +++ linux-2.6.28/drivers/bluetooth/hci_usb.c @@ -137,6 +137,9 @@ { USB_DEVICE(0x413c, 0x8156), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU }, /* Dell Wireless 410 */ { USB_DEVICE(0x413c, 0x8152), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU }, + + /* Broadcom 2046 */ + { USB_DEVICE(0x0a5c, 0x2151), .driver_info = HCI_RESET }, /* Broadcom 2046 */ { USB_DEVICE(0x0a5c, 0x2151), .driver_info = HCI_RESET }, @@ -1030,8 +1033,10 @@ while ((_urb = _urb_dequeue(q))) { /* reset queue since _urb_dequeue sets it to NULL */ _urb->queue = q; - usb_kill_urb(&_urb->urb); + spin_lock_irqsave(&q->lock, flags); list_add(&_urb->list, &killed); + spin_unlock_irqrestore(&q->lock, flags); + usb_kill_urb(&_urb->urb); } spin_lock_irqsave(&q->lock, flags); --- linux-2.6.28.orig/drivers/bluetooth/bt3c_cs.c +++ linux-2.6.28/drivers/bluetooth/bt3c_cs.c @@ -345,7 +345,10 @@ int iir; irqreturn_t r = IRQ_NONE; - BUG_ON(!info->hdev); + if (!info || !info->hdev) { + BT_ERR("Call of irq %d for unknown device", irq); + return IRQ_NONE; + } iobase = info->p_dev->io.BasePort1; --- linux-2.6.28.orig/drivers/bluetooth/btsdio.c +++ linux-2.6.28/drivers/bluetooth/btsdio.c @@ -91,6 +91,7 @@ err = sdio_writesb(data->func, REG_TDAT, skb->data, skb->len); if (err < 0) { + skb_pull(skb, 4); sdio_writeb(data->func, 0x01, REG_PC_WRT, NULL); return err; } --- linux-2.6.28.orig/drivers/bluetooth/btusb.c +++ linux-2.6.28/drivers/bluetooth/btusb.c @@ -41,6 +41,7 @@ #define BT_DBG(D...) #endif +/* Backported patch would update version from 0.4 to 0.5 */ #define VERSION "0.3" static int ignore_dga; @@ -125,6 +126,9 @@ /* Dell laptop with Broadcom chip */ { USB_DEVICE(0x413c, 0x8126), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, + /* Dell Wireless 365 */ + { USB_DEVICE(0x413c, 0x8160), .driver_info = BTUSB_RESET }, + /* Dell Wireless 370 */ { USB_DEVICE(0x413c, 0x8156), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, @@ -197,6 +201,7 @@ struct usb_endpoint_descriptor *isoc_tx_ep; struct usb_endpoint_descriptor *isoc_rx_ep; + unsigned int sco_num; int isoc_altsetting; }; @@ -236,7 +241,7 @@ } } -static int btusb_submit_intr_urb(struct hci_dev *hdev) +static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags) { struct btusb_data *data = hdev->driver_data; struct urb *urb; @@ -249,13 +254,13 @@ if (!data->intr_ep) return -ENODEV; - urb = usb_alloc_urb(0, GFP_ATOMIC); + urb = usb_alloc_urb(0, mem_flags); if (!urb) return -ENOMEM; size = le16_to_cpu(data->intr_ep->wMaxPacketSize); - buf = kmalloc(size, GFP_ATOMIC); + buf = kmalloc(size, mem_flags); if (!buf) { usb_free_urb(urb); return -ENOMEM; @@ -271,7 +276,7 @@ usb_anchor_urb(urb, &data->intr_anchor); - err = usb_submit_urb(urb, GFP_ATOMIC); + err = usb_submit_urb(urb, mem_flags); if (err < 0) { BT_ERR("%s urb %p submission failed (%d)", hdev->name, urb, -err); @@ -319,7 +324,7 @@ } } -static int btusb_submit_bulk_urb(struct hci_dev *hdev) +static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags) { struct btusb_data *data = hdev->driver_data; struct urb *urb; @@ -332,13 +337,13 @@ if (!data->bulk_rx_ep) return -ENODEV; - urb = usb_alloc_urb(0, GFP_KERNEL); + urb = usb_alloc_urb(0, mem_flags); if (!urb) return -ENOMEM; size = le16_to_cpu(data->bulk_rx_ep->wMaxPacketSize); - buf = kmalloc(size, GFP_KERNEL); + buf = kmalloc(size, mem_flags); if (!buf) { usb_free_urb(urb); return -ENOMEM; @@ -353,7 +358,7 @@ usb_anchor_urb(urb, &data->bulk_anchor); - err = usb_submit_urb(urb, GFP_KERNEL); + err = usb_submit_urb(urb, mem_flags); if (err < 0) { BT_ERR("%s urb %p submission failed (%d)", hdev->name, urb, -err); @@ -430,7 +435,7 @@ urb->number_of_packets = i; } -static int btusb_submit_isoc_urb(struct hci_dev *hdev) +static int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags) { struct btusb_data *data = hdev->driver_data; struct urb *urb; @@ -443,14 +448,14 @@ if (!data->isoc_rx_ep) return -ENODEV; - urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_KERNEL); + urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, mem_flags); if (!urb) return -ENOMEM; size = le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize) * BTUSB_MAX_ISOC_FRAMES; - buf = kmalloc(size, GFP_KERNEL); + buf = kmalloc(size, mem_flags); if (!buf) { usb_free_urb(urb); return -ENOMEM; @@ -473,7 +478,7 @@ usb_anchor_urb(urb, &data->isoc_anchor); - err = usb_submit_urb(urb, GFP_KERNEL); + err = usb_submit_urb(urb, mem_flags); if (err < 0) { BT_ERR("%s urb %p submission failed (%d)", hdev->name, urb, -err); @@ -520,12 +525,24 @@ if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags)) return 0; - err = btusb_submit_intr_urb(hdev); + err = btusb_submit_intr_urb(hdev, GFP_KERNEL); + if (err < 0) + goto failed; + + err = btusb_submit_bulk_urb(hdev, GFP_KERNEL); if (err < 0) { - clear_bit(BTUSB_INTR_RUNNING, &data->flags); - clear_bit(HCI_RUNNING, &hdev->flags); + usb_kill_anchored_urbs(&data->intr_anchor); + goto failed; } + set_bit(BTUSB_BULK_RUNNING, &data->flags); + btusb_submit_bulk_urb(hdev, GFP_KERNEL); + + return 0; + +failed: + clear_bit(BTUSB_INTR_RUNNING, &data->flags); + clear_bit(HCI_RUNNING, &hdev->flags); return err; } @@ -680,8 +697,10 @@ BT_DBG("%s evt %d", hdev->name, evt); - if (evt == HCI_NOTIFY_CONN_ADD || evt == HCI_NOTIFY_CONN_DEL) + if (hdev->conn_hash.sco_num != data->sco_num) { + data->sco_num = hdev->conn_hash.sco_num; schedule_work(&data->work); + } } static int inline __set_isoc_interface(struct hci_dev *hdev, int altsetting) @@ -732,18 +751,6 @@ struct btusb_data *data = container_of(work, struct btusb_data, work); struct hci_dev *hdev = data->hdev; - if (hdev->conn_hash.acl_num > 0) { - if (!test_and_set_bit(BTUSB_BULK_RUNNING, &data->flags)) { - if (btusb_submit_bulk_urb(hdev) < 0) - clear_bit(BTUSB_BULK_RUNNING, &data->flags); - else - btusb_submit_bulk_urb(hdev); - } - } else { - clear_bit(BTUSB_BULK_RUNNING, &data->flags); - usb_kill_anchored_urbs(&data->bulk_anchor); - } - if (hdev->conn_hash.sco_num > 0) { if (data->isoc_altsetting != 2) { clear_bit(BTUSB_ISOC_RUNNING, &data->flags); @@ -754,10 +761,10 @@ } if (!test_and_set_bit(BTUSB_ISOC_RUNNING, &data->flags)) { - if (btusb_submit_isoc_urb(hdev) < 0) + if (btusb_submit_isoc_urb(hdev, GFP_KERNEL) < 0) clear_bit(BTUSB_ISOC_RUNNING, &data->flags); else - btusb_submit_isoc_urb(hdev); + btusb_submit_isoc_urb(hdev, GFP_KERNEL); } } else { clear_bit(BTUSB_ISOC_RUNNING, &data->flags); --- linux-2.6.28.orig/drivers/bluetooth/dtl1_cs.c +++ linux-2.6.28/drivers/bluetooth/dtl1_cs.c @@ -299,7 +299,10 @@ int iir, lsr; irqreturn_t r = IRQ_NONE; - BUG_ON(!info->hdev); + if (!info || !info->hdev) { + BT_ERR("Call of irq %d for unknown device", irq); + return IRQ_NONE; + } iobase = info->p_dev->io.BasePort1; --- linux-2.6.28.orig/drivers/bluetooth/bluecard_cs.c +++ linux-2.6.28/drivers/bluetooth/bluecard_cs.c @@ -503,7 +503,10 @@ unsigned int iobase; unsigned char reg; - BUG_ON(!info->hdev); + if (!info || !info->hdev) { + BT_ERR("Call of irq %d for unknown device", irq); + return IRQ_NONE; + } if (!test_bit(CARD_READY, &(info->hw_state))) return IRQ_HANDLED; --- linux-2.6.28.orig/drivers/bluetooth/btuart_cs.c +++ linux-2.6.28/drivers/bluetooth/btuart_cs.c @@ -295,7 +295,10 @@ int iir, lsr; irqreturn_t r = IRQ_NONE; - BUG_ON(!info->hdev); + if (!info || !info->hdev) { + BT_ERR("Call of irq %d for unknown device", irq); + return IRQ_NONE; + } iobase = info->p_dev->io.BasePort1; --- linux-2.6.28.orig/drivers/mtd/ftl.c +++ linux-2.6.28/drivers/mtd/ftl.c @@ -69,6 +69,7 @@ #include #include #include +#include #include #include @@ -1116,3 +1117,4 @@ MODULE_LICENSE("Dual MPL/GPL"); MODULE_AUTHOR("David Hinds "); MODULE_DESCRIPTION("Support code for Flash Translation Layer, used on PCMCIA devices"); +MODULE_ALIAS_BLOCKDEV_MAJOR(FTL_MAJOR); --- linux-2.6.28.orig/drivers/mtd/mtdchar.c +++ linux-2.6.28/drivers/mtd/mtdchar.c @@ -821,3 +821,4 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("David Woodhouse "); MODULE_DESCRIPTION("Direct character-device access to MTD devices"); +MODULE_ALIAS_CHARDEV_MAJOR(MTD_CHAR_MAJOR); --- linux-2.6.28.orig/drivers/mtd/nftlcore.c +++ linux-2.6.28/drivers/mtd/nftlcore.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -818,3 +819,4 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("David Woodhouse , Fabrice Bellard et al."); MODULE_DESCRIPTION("Support code for NAND Flash Translation Layer, used on M-Systems DiskOnChip 2000 and Millennium"); +MODULE_ALIAS_BLOCKDEV_MAJOR(NFTL_MAJOR); --- linux-2.6.28.orig/drivers/mtd/nand/Kconfig +++ linux-2.6.28/drivers/mtd/nand/Kconfig @@ -365,6 +365,42 @@ The simulator may simulate various NAND flash chips for the MTD nand layer. +config MTD_NAND_MXC_V2 + tristate "MXC NAND Version 2 support" + depends on MTD_NAND && ARCH_MXC_HAS_NFC_V2 + help + This enables the driver for the version 2 of NAND flash controller + on the MXC processors. + +config MTD_NAND_MXC_V3 + tristate "MXC NAND Version 3 support" + depends on MTD_NAND && ARCH_MXC_HAS_NFC_V3 + help + This enables the driver for the version 3 of NAND flash controller + on the MXC processors. + +config MTD_NAND_MXC_SWECC + bool "Software ECC support " + depends on MTD_NAND_MXC_V2 || MTD_NAND_MXC_V3 + help + This enables the support for Software ECC handling. By + default MXC NAND controller Hardware ECC is supported. + + +config MTD_NAND_MXC_FORCE_CE + bool "NAND chip select operation support" + depends on MTD_NAND_MXC_V2|| MTD_NAND_MXC_V3 + help + This enables the NAND chip select by using CE control line. By + default CE operation is disabled. + +config MXC_NAND_LOW_LEVEL_ERASE + bool "Low level NAND erase" + depends on MTD_NAND_MXC_V2 || MTD_NAND_MXC_V3 + help + This enables the erase of whole NAND flash. By + default low level erase operation is disabled. + config MTD_NAND_PLATFORM tristate "Support for generic platform NAND driver" depends on MTD_NAND --- linux-2.6.28.orig/drivers/mtd/nand/Makefile +++ linux-2.6.28/drivers/mtd/nand/Makefile @@ -24,6 +24,8 @@ obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o obj-$(CONFIG_MTD_NAND_ATMEL) += atmel_nand.o obj-$(CONFIG_MTD_NAND_GPIO) += gpio.o +obj-$(CONFIG_MTD_NAND_MXC_V2) += mxc_nd2.o +obj-$(CONFIG_MTD_NAND_MXC_V3) += mxc_nd2.o obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o --- linux-2.6.28.orig/drivers/mtd/nand/mxc_nd2.c +++ linux-2.6.28/drivers/mtd/nand/mxc_nd2.c @@ -0,0 +1,1433 @@ +/* + * Copyright 2004-2009 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mxc_nd2.h" + +#define DVR_VER "2.5" + +/* Global address Variables */ +static u32 nfc_axi_base, nfc_ip_base; + +struct mxc_mtd_s { + struct mtd_info mtd; + struct nand_chip nand; + struct mtd_partition *parts; + struct device *dev; +}; + +static struct mxc_mtd_s *mxc_nand_data; + +/* + * Define delays in microsec for NAND device operations + */ +#define TROP_US_DELAY 2000 + +struct nand_info { + bool bStatusRequest; + u16 colAddr; +}; + +static struct nand_info g_nandfc_info; + +#ifdef CONFIG_MTD_NAND_MXC_SWECC +static int hardware_ecc = 0; +#else +static int hardware_ecc = 1; +#endif + +static u8 num_of_interleave = 1; + +static u8 *data_buf; +static u8 *oob_buf; + +static int g_page_mask; + +static struct clk *nfc_clk; + +/* + * OOB placement block for use with hardware ecc generation + */ +static struct nand_ecclayout nand_hw_eccoob_512 = { + .eccbytes = 9, + .eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15}, + .oobavail = 4, + .oobfree = {{0, 4}} +}; + +static struct nand_ecclayout nand_hw_eccoob_2k = { + .eccbytes = 9, + .eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15}, + .oobavail = 4, + .oobfree = {{2, 4}} +}; + +static struct nand_ecclayout nand_hw_eccoob_4k = { + .eccbytes = 9, + .eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15}, + .oobavail = 4, + .oobfree = {{2, 4}} +}; + +/*! + * @defgroup NAND_MTD NAND Flash MTD Driver for MXC processors + */ + +/*! + * @file mxc_nd2.c + * + * @brief This file contains the hardware specific layer for NAND Flash on + * MXC processor + * + * @ingroup NAND_MTD + */ + +#ifdef CONFIG_MTD_PARTITIONS +static const char *part_probes[] = { "RedBoot", "cmdlinepart", NULL }; +#endif + +static wait_queue_head_t irq_waitq; + +static irqreturn_t mxc_nfc_irq(int irq, void *dev_id) +{ + /* Disable Interuupt */ + raw_write(raw_read(REG_NFC_INTRRUPT) | NFC_INT_MSK, REG_NFC_INTRRUPT); + wake_up(&irq_waitq); + + return IRQ_HANDLED; +} + +/* + * Functions to transfer data to/from spare erea. + */ +static void +copy_spare(struct mtd_info *mtd, void *pbuf, void *pspare, int len, bool bfrom) +{ + u16 i, j; + u16 m = mtd->oobsize; + u16 n = mtd->writesize >> 9; + u8 *d = (u8 *) pbuf; + u8 *s = (u8 *) pspare; + u16 t = SPARE_LEN; + + m /= num_of_interleave; + n /= num_of_interleave; + + j = (m / n >> 1) << 1; + + if (bfrom) { + for (i = 0; i < n - 1; i++) + memcpy(&d[i * j], &s[i * t], j); + + /* the last section */ + memcpy(&d[i * j], &s[i * t], len - i * j); + } else { + for (i = 0; i < n - 1; i++) + memcpy(&s[i * t], &d[i * j], j); + + /* the last section */ + memcpy(&s[i * t], &d[i * j], len - i * j); + } +} + +/*! + * This function polls the NFC to wait for the basic operation to complete by + * checking the INT bit of config2 register. + * + * @param maxRetries number of retry attempts (separated by 1 us) + * @param useirq True if IRQ should be used rather than polling + */ +static void wait_op_done(int maxRetries, bool useirq) +{ + if (useirq) { + if ((raw_read(REG_NFC_OPS_STAT) & NFC_OPS_STAT) == 0) { + /* Enable Interuupt */ + raw_write(raw_read(REG_NFC_INTRRUPT) & ~NFC_INT_MSK, + REG_NFC_INTRRUPT); + wait_event(irq_waitq, + (raw_read(REG_NFC_OPS_STAT) & NFC_OPS_STAT)); + } + WRITE_NFC_IP_REG((raw_read(REG_NFC_OPS_STAT) & + ~NFC_OPS_STAT), REG_NFC_OPS_STAT); + } else { + while (1) { + maxRetries--; + if (raw_read(REG_NFC_OPS_STAT) & NFC_OPS_STAT) { + WRITE_NFC_IP_REG((raw_read(REG_NFC_OPS_STAT) & + ~NFC_OPS_STAT), + REG_NFC_OPS_STAT); + break; + } + udelay(1); + if (maxRetries <= 0) { + DEBUG(MTD_DEBUG_LEVEL0, "%s(%d): INT not set\n", + __func__, __LINE__); + } + } + } +} + +static inline void send_atomic_cmd(u16 cmd, bool useirq) +{ + /* fill command */ + raw_write(cmd, REG_NFC_FLASH_CMD); + + /* clear status */ + ACK_OPS; + + /* send out command */ + raw_write(NFC_CMD, REG_NFC_OPS); + + /* Wait for operation to complete */ + wait_op_done(TROP_US_DELAY, useirq); +} + +static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr); +static int mxc_check_ecc_status(struct mtd_info *mtd); + +#ifdef NFC_AUTO_MODE_ENABLE +/*! + * This function handle the interleave related work + * @param mtd mtd info + * @param cmd command + */ +static void auto_cmd_interleave(struct mtd_info *mtd, u16 cmd) +{ + u32 i; + u32 j = num_of_interleave; + struct nand_chip *this = mtd->priv; + u32 addr_low = raw_read(NFC_FLASH_ADDR0); + u32 addr_high = raw_read(NFC_FLASH_ADDR8); + u32 page_addr = addr_low >> 16 | addr_high << 16; + u8 *dbuf = data_buf; + u8 *obuf = oob_buf; + u32 dlen = mtd->writesize / j; + u32 olen = mtd->oobsize / j; + + /* adjust the addr value + * since ADD_OP mode is 01 + */ + if (j > 1) + page_addr *= j; + else + page_addr *= this->numchips; + + switch (cmd) { + case NAND_CMD_PAGEPROG: + for (i = 0; i < j; i++) { + /* reset addr cycle */ + if (j > 1) + mxc_do_addr_cycle(mtd, 0, page_addr++); + + /* data transfer */ + memcpy(MAIN_AREA0, dbuf, dlen); + copy_spare(mtd, obuf, SPARE_AREA0, olen, false); + + /* update the value */ + dbuf += dlen; + obuf += olen; + + NFC_SET_RBA(0); + ACK_OPS; + raw_write(NFC_AUTO_PROG, REG_NFC_OPS); + + /* wait auto_prog_done bit set */ + while (!(raw_read(REG_NFC_OPS_STAT) & NFC_OP_DONE)) ; + } + + wait_op_done(TROP_US_DELAY, false); + while (!(raw_read(REG_NFC_OPS_STAT) & NFC_RB)) ; + + break; + case NAND_CMD_READSTART: + for (i = 0; i < j; i++) { + /* reset addr cycle */ + if (j > 1) + mxc_do_addr_cycle(mtd, 0, page_addr++); + + NFC_SET_RBA(0); + ACK_OPS; + raw_write(NFC_AUTO_READ, REG_NFC_OPS); + wait_op_done(TROP_US_DELAY, false); + + /* check ecc error */ + mxc_check_ecc_status(mtd); + + /* data transfer */ + memcpy(dbuf, MAIN_AREA0, dlen); + copy_spare(mtd, obuf, SPARE_AREA0, olen, true); + + /* update the value */ + dbuf += dlen; + obuf += olen; + } + break; + case NAND_CMD_ERASE2: + for (i = 0; i < j; i++) { + if (!i) { + page_addr = addr_low; + page_addr *= (j > 1 ? j : this->numchips); + } + mxc_do_addr_cycle(mtd, -1, page_addr++); + ACK_OPS; + raw_write(NFC_AUTO_ERASE, REG_NFC_OPS); + wait_op_done(TROP_US_DELAY, true); + } + break; + case NAND_CMD_RESET: + for (i = 0; i < j; i++) { + if (j > 1) + NFC_SET_NFC_ACTIVE_CS(i); + send_atomic_cmd(cmd, false); + } + break; + default: + break; + } +} +#endif + +static void send_addr(u16 addr, bool useirq); + +/*! + * This function issues the specified command to the NAND device and + * waits for completion. + * + * @param cmd command for NAND Flash + * @param useirq True if IRQ should be used rather than polling + */ +static void send_cmd(struct mtd_info *mtd, u16 cmd, bool useirq) +{ + DEBUG(MTD_DEBUG_LEVEL3, "send_cmd(0x%x, %d)\n", cmd, useirq); + +#ifdef NFC_AUTO_MODE_ENABLE + switch (cmd) { + case NAND_CMD_READ0: + case NAND_CMD_READOOB: + raw_write(NAND_CMD_READ0, REG_NFC_FLASH_CMD); + break; + case NAND_CMD_SEQIN: + case NAND_CMD_ERASE1: + raw_write(cmd, REG_NFC_FLASH_CMD); + break; + case NAND_CMD_PAGEPROG: + case NAND_CMD_ERASE2: + case NAND_CMD_READSTART: + raw_write(raw_read(REG_NFC_FLASH_CMD) | cmd << NFC_CMD_1_SHIFT, + REG_NFC_FLASH_CMD); + auto_cmd_interleave(mtd, cmd); + break; + case NAND_CMD_READID: + send_atomic_cmd(cmd, useirq); + send_addr(0, false); + break; + case NAND_CMD_RESET: + auto_cmd_interleave(mtd, cmd); + case NAND_CMD_STATUS: + break; + default: + break; + } +#else + send_atomic_cmd(cmd, useirq); +#endif +} + +/*! + * This function sends an address (or partial address) to the + * NAND device. The address is used to select the source/destination for + * a NAND command. + * + * @param addr address to be written to NFC. + * @param useirq True if IRQ should be used rather than polling + */ +static void send_addr(u16 addr, bool useirq) +{ + DEBUG(MTD_DEBUG_LEVEL3, "send_addr(0x%x %d)\n", addr, useirq); + + /* fill address */ + raw_write((addr << NFC_FLASH_ADDR_SHIFT), REG_NFC_FLASH_ADDR); + + /* clear status */ + ACK_OPS; + + /* send out address */ + raw_write(NFC_ADDR, REG_NFC_OPS); + + /* Wait for operation to complete */ + wait_op_done(TROP_US_DELAY, useirq); +} + +/*! + * This function requests the NFC to initate the transfer + * of data currently in the NFC RAM buffer to the NAND device. + * + * @param buf_id Specify Internal RAM Buffer number + */ +static void send_prog_page(u8 buf_id) +{ +#ifndef NFC_AUTO_MODE_ENABLE + DEBUG(MTD_DEBUG_LEVEL3, "%s\n", __FUNCTION__); + + /* set ram buffer id */ + NFC_SET_RBA(buf_id); + + /* clear status */ + ACK_OPS; + + /* transfer data from NFC ram to nand */ + raw_write(NFC_INPUT, REG_NFC_OPS); + + /* Wait for operation to complete */ + wait_op_done(TROP_US_DELAY, false); +#endif +} + +/*! + * This function requests the NFC to initated the transfer + * of data from the NAND device into in the NFC ram buffer. + * + * @param buf_id Specify Internal RAM Buffer number + */ +static void send_read_page(u8 buf_id) +{ +#ifndef NFC_AUTO_MODE_ENABLE + DEBUG(MTD_DEBUG_LEVEL3, "%s(%d)\n", __FUNCTION__, buf_id); + + /* set ram buffer id */ + NFC_SET_RBA(buf_id); + + /* clear status */ + ACK_OPS; + + /* transfer data from nand to NFC ram */ + raw_write(NFC_OUTPUT, REG_NFC_OPS); + + /* Wait for operation to complete */ + wait_op_done(TROP_US_DELAY, false); +#endif +} + +/*! + * This function requests the NFC to perform a read of the + * NAND device ID. + */ +static void send_read_id(void) +{ + /* Set RBA bits for BUFFER0 */ + NFC_SET_RBA(0); + + /* clear status */ + ACK_OPS; + + /* Read ID into main buffer */ + raw_write(NFC_ID, REG_NFC_OPS); + + /* Wait for operation to complete */ + wait_op_done(TROP_US_DELAY, false); + +} + +#ifdef NFC_AUTO_MODE_ENABLE +static inline void read_dev_status(u16 *status) +{ + u32 mask = 0xFF << 16; + + /* clear status */ + ACK_OPS; + + do { + /* send auto read status command */ + raw_write(NFC_AUTO_STATE, REG_NFC_OPS); + if (cpu_is_mx51_rev(CHIP_REV_2_0) == 1) + wait_op_done(TROP_US_DELAY, false); + *status = (raw_read(NFC_CONFIG1) & mask) >> 16; + } while ((*status & NAND_STATUS_READY) == 0); +} +#endif + +/*! + * This function requests the NFC to perform a read of the + * NAND device status and returns the current status. + * + * @return device status + */ +static u16 get_dev_status(void) +{ +#ifdef NFC_AUTO_MODE_ENABLE + int i; + u16 status = 0; + for (i = 0; i < num_of_interleave; i++) { + + /* set ative cs */ + NFC_SET_NFC_ACTIVE_CS(i); + + /* FIXME, NFC Auto erase may have + * problem, have to pollingit until + * the nand get idle, otherwise + * it may get error + */ + read_dev_status(&status); + if (status & NAND_STATUS_FAIL) + break; + } + + return status; +#else + volatile u16 *mainBuf = MAIN_AREA1; + u8 val = 1; + u16 ret; + + /* Set ram buffer id */ + NFC_SET_RBA(val); + + /* clear status */ + ACK_OPS; + + /* Read status into main buffer */ + raw_write(NFC_STATUS, REG_NFC_OPS); + + /* Wait for operation to complete */ + wait_op_done(TROP_US_DELAY, false); + + /* Status is placed in first word of main buffer */ + /* get status, then recovery area 1 data */ + ret = *mainBuf; + + return ret; +#endif +} + +static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode) +{ + raw_write((raw_read(REG_NFC_ECC_EN) | NFC_ECC_EN), REG_NFC_ECC_EN); + return; +} + +/* + * Function to record the ECC corrected/uncorrected errors resulted + * after a page read. This NFC detects and corrects upto to 4 symbols + * of 9-bits each. + */ +static int mxc_check_ecc_status(struct mtd_info *mtd) +{ + u32 ecc_stat, err; + int no_subpages = 1; + int ret = 0; + u8 ecc_bit_mask, err_limit; + + ecc_bit_mask = (IS_4BIT_ECC ? 0x7 : 0xf); + err_limit = (IS_4BIT_ECC ? 0x4 : 0x8); + + no_subpages = mtd->writesize >> 9; + + no_subpages /= num_of_interleave; + + ecc_stat = GET_NFC_ECC_STATUS(); + do { + err = ecc_stat & ecc_bit_mask; + if (err > err_limit) { + mtd->ecc_stats.failed++; + printk(KERN_WARNING "UnCorrectable RS-ECC Error\n"); + return -1; + } else { + ret += err; + } + ecc_stat >>= 4; + } while (--no_subpages); + + mtd->ecc_stats.corrected += ret; + pr_debug("%d Symbol Correctable RS-ECC Error\n", ret); + + return ret; +} + +/* + * Function to correct the detected errors. This NFC corrects all the errors + * detected. So this function just return 0. + */ +static int mxc_nand_correct_data(struct mtd_info *mtd, u_char * dat, + u_char * read_ecc, u_char * calc_ecc) +{ + return 0; +} + +/* + * Function to calculate the ECC for the data to be stored in the Nand device. + * This NFC has a hardware RS(511,503) ECC engine together with the RS ECC + * CONTROL blocks are responsible for detection and correction of up to + * 8 symbols of 9 bits each in 528 byte page. + * So this function is just return 0. + */ + +static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char * dat, + u_char * ecc_code) +{ + return 0; +} + +/*! + * This function id is used to read the data buffer from the NAND Flash. To + * read the data from NAND Flash first the data output cycle is initiated by + * the NFC, which copies the data to RAMbuffer. This data of length \b len is + * then copied to buffer \b buf. + * + * @param mtd MTD structure for the NAND Flash + * @param buf data to be read from NAND Flash + * @param len number of bytes to be read + */ +static void mxc_nand_read_buf(struct mtd_info *mtd, u_char * buf, int len) +{ + u16 col = g_nandfc_info.colAddr; + + if (mtd->writesize) { + + int j = mtd->writesize - col; + int n = mtd->oobsize + j; + + n = min(n, len); + + if (j > 0) { + if (n > j) { + memcpy(buf, &data_buf[col], j); + memcpy(buf + j, &oob_buf[0], n - j); + } else { + memcpy(buf, &data_buf[col], n); + } + } else { + col -= mtd->writesize; + memcpy(buf, &oob_buf[col], len); + } + + /* update */ + g_nandfc_info.colAddr += n; + + } else { + /* At flash identify phase, + * mtd->writesize has not been + * set correctly, it should + * be zero.And len will less 2 + */ + memcpy(buf, &data_buf[col], len); + + /* update */ + g_nandfc_info.colAddr += len; + } + +} + +/*! + * This function reads byte from the NAND Flash + * + * @param mtd MTD structure for the NAND Flash + * + * @return data read from the NAND Flash + */ +static uint8_t mxc_nand_read_byte(struct mtd_info *mtd) +{ + uint8_t ret; + + /* Check for status request */ + if (g_nandfc_info.bStatusRequest) { + return (get_dev_status() & 0xFF); + } + + mxc_nand_read_buf(mtd, &ret, 1); + + return ret; +} + +/*! + * This function reads word from the NAND Flash + * + * @param mtd MTD structure for the NAND Flash + * + * @return data read from the NAND Flash + */ +static u16 mxc_nand_read_word(struct mtd_info *mtd) +{ + u16 ret; + + mxc_nand_read_buf(mtd, (uint8_t *) &ret, sizeof(u16)); + + return ret; +} + +/*! + * This function reads byte from the NAND Flash + * + * @param mtd MTD structure for the NAND Flash + * + * @return data read from the NAND Flash + */ +static u_char mxc_nand_read_byte16(struct mtd_info *mtd) +{ + /* Check for status request */ + if (g_nandfc_info.bStatusRequest) { + return (get_dev_status() & 0xFF); + } + + return mxc_nand_read_word(mtd) & 0xFF; +} + +/*! + * This function writes data of length \b len from buffer \b buf to the NAND + * internal RAM buffer's MAIN area 0. + * + * @param mtd MTD structure for the NAND Flash + * @param buf data to be written to NAND Flash + * @param len number of bytes to be written + */ +static void mxc_nand_write_buf(struct mtd_info *mtd, + const u_char * buf, int len) +{ + u16 col = g_nandfc_info.colAddr; + int j = mtd->writesize - col; + int n = mtd->oobsize + j; + + n = min(n, len); + + if (j > 0) { + if (n > j) { + memcpy(&data_buf[col], buf, j); + memcpy(&oob_buf[0], buf + j, n - j); + } else { + memcpy(&data_buf[col], buf, n); + } + } else { + col -= mtd->writesize; + memcpy(&oob_buf[col], buf, len); + } + + /* update */ + g_nandfc_info.colAddr += n; +} + +/*! + * This function is used by the upper layer to verify the data in NAND Flash + * with the data in the \b buf. + * + * @param mtd MTD structure for the NAND Flash + * @param buf data to be verified + * @param len length of the data to be verified + * + * @return -EFAULT if error else 0 + * + */ +static int mxc_nand_verify_buf(struct mtd_info *mtd, const u_char * buf, + int len) +{ + u_char *s = data_buf; + + const u_char *p = buf; + + for (; len > 0; len--) { + if (*p++ != *s++) + return -EFAULT; + } + + return 0; +} + +/*! + * This function is used by upper layer for select and deselect of the NAND + * chip + * + * @param mtd MTD structure for the NAND Flash + * @param chip val indicating select or deselect + */ +static void mxc_nand_select_chip(struct mtd_info *mtd, int chip) +{ + + switch (chip) { + case -1: + /* Disable the NFC clock */ + clk_disable(nfc_clk); + break; + case 0 ... 7: + /* Enable the NFC clock */ + clk_enable(nfc_clk); + + NFC_SET_NFC_ACTIVE_CS(chip); + break; + + default: + break; + } +} + +/* + * Function to perform the address cycles. + */ +static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr) +{ +#ifdef NFC_AUTO_MODE_ENABLE + + if (page_addr != -1 && column != -1) { + u32 mask = 0xFFFF; + /* the column address */ + raw_write(column & mask, NFC_FLASH_ADDR0); + raw_write((raw_read(NFC_FLASH_ADDR0) | + ((page_addr & mask) << 16)), NFC_FLASH_ADDR0); + /* the row address */ + raw_write(((raw_read(NFC_FLASH_ADDR8) & (mask << 16)) | + ((page_addr & (mask << 16)) >> 16)), + NFC_FLASH_ADDR8); + } else if (page_addr != -1) { + raw_write(page_addr, NFC_FLASH_ADDR0); + } + + DEBUG(MTD_DEBUG_LEVEL3, + "AutoMode:the ADDR REGS value is (0x%x, 0x%x)\n", + raw_read(NFC_FLASH_ADDR0), raw_read(NFC_FLASH_ADDR8)); +#else + + u32 page_mask = g_page_mask; + + if (column != -1) { + send_addr(column & 0xFF, false); + if (IS_2K_PAGE_NAND) { + /* another col addr cycle for 2k page */ + send_addr((column >> 8) & 0xF, false); + } else if (IS_4K_PAGE_NAND) { + /* another col addr cycle for 4k page */ + send_addr((column >> 8) & 0x1F, false); + } + } + if (page_addr != -1) { + do { + send_addr((page_addr & 0xff), false); + page_mask >>= 8; + page_addr >>= 8; + } while (page_mask != 0); + } +#endif +} + +/*! + * This function is used by the upper layer to write command to NAND Flash for + * different operations to be carried out on NAND Flash + * + * @param mtd MTD structure for the NAND Flash + * @param command command for NAND Flash + * @param column column offset for the page read + * @param page_addr page to be read from NAND Flash + */ +static void mxc_nand_command(struct mtd_info *mtd, unsigned command, + int column, int page_addr) +{ + bool useirq = false; + + DEBUG(MTD_DEBUG_LEVEL3, + "mxc_nand_command (cmd = 0x%x, col = 0x%x, page = 0x%x)\n", + command, column, page_addr); + /* + * Reset command state information + */ + g_nandfc_info.bStatusRequest = false; + + /* + * Command pre-processing step + */ + switch (command) { + case NAND_CMD_STATUS: + g_nandfc_info.colAddr = 0; + g_nandfc_info.bStatusRequest = true; + break; + + case NAND_CMD_READ0: + g_nandfc_info.colAddr = column; + break; + + case NAND_CMD_READOOB: + g_nandfc_info.colAddr = column; + command = NAND_CMD_READ0; + break; + + case NAND_CMD_SEQIN: + if (column != 0) { + + /* FIXME: before send SEQIN command for + * partial write,We need read one page out. + * FSL NFC does not support partial write + * It alway send out 512+ecc+512+ecc ... + * for large page nand flash. But for small + * page nand flash, it did support SPARE + * ONLY operation. But to make driver + * simple. We take the same as large page,read + * whole page out and update. As for MLC nand + * NOP(num of operation) = 1. Partial written + * on one programed page is not allowed! We + * can't limit it on the driver, it need the + * upper layer applicaiton take care it + */ + + mxc_nand_command(mtd, NAND_CMD_READ0, 0, page_addr); + } + + g_nandfc_info.colAddr = column; + break; + + case NAND_CMD_PAGEPROG: +#ifndef NFC_AUTO_MODE_ENABLE + /* FIXME:the NFC interal buffer + * access has some limitation, it + * does not allow byte access. To + * make the code simple and ease use + * not every time check the address + * alignment.Use the temp buffer + * to accomadate the data.since We + * know data_buf will be at leat 4 + * byte alignment, so we can use + * memcpy safely + */ + memcpy(MAIN_AREA0, data_buf, mtd->writesize); + copy_spare(mtd, oob_buf, SPARE_AREA0, mtd->oobsize, false); +#endif + + if (IS_LARGE_PAGE_NAND) + PROG_PAGE(); + else + send_prog_page(0); + + useirq = true; + + break; + + case NAND_CMD_ERASE1: + break; + case NAND_CMD_ERASE2: + useirq = true; + + break; + } + + /* + * Write out the command to the device. + */ + send_cmd(mtd, command, useirq); + + mxc_do_addr_cycle(mtd, column, page_addr); + + /* + * Command post-processing step + */ + switch (command) { + + case NAND_CMD_READOOB: + case NAND_CMD_READ0: + if (IS_LARGE_PAGE_NAND) { + /* send read confirm command */ + send_cmd(mtd, NAND_CMD_READSTART, false); + /* read for each AREA */ + READ_PAGE(); + } else { + send_read_page(0); + } + +#ifndef NFC_AUTO_MODE_ENABLE + /* FIXME, the NFC interal buffer + * access has some limitation, it + * does not allow byte access. To + * make the code simple and ease use + * not every time check the address + * alignment.Use the temp buffer + * to accomadate the data.since We + * know data_buf will be at leat 4 + * byte alignment, so we can use + * memcpy safely + */ + memcpy(data_buf, MAIN_AREA0, mtd->writesize); + copy_spare(mtd, oob_buf, SPARE_AREA0, mtd->oobsize, true); +#endif + + break; + + case NAND_CMD_READID: + send_read_id(); + g_nandfc_info.colAddr = column; + memcpy(data_buf, MAIN_AREA0, 2048); + + break; + } +} + +static int mxc_nand_read_oob(struct mtd_info *mtd, + struct nand_chip *chip, int page, int sndcmd) +{ + if (sndcmd) { + + chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); + sndcmd = 0; + } + + memcpy(chip->oob_poi, oob_buf, mtd->oobsize); + + return sndcmd; +} + +static int mxc_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip, + uint8_t * buf) +{ + +#ifndef NFC_AUTO_MODE_ENABLE + mxc_check_ecc_status(mtd); +#endif + + memcpy(buf, data_buf, mtd->writesize); + memcpy(chip->oob_poi, oob_buf, mtd->oobsize); + + return 0; +} + +static void mxc_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, + const uint8_t * buf) +{ + memcpy(data_buf, buf, mtd->writesize); + memcpy(oob_buf, chip->oob_poi, mtd->oobsize); + +} + +/* Define some generic bad / good block scan pattern which are used + * while scanning a device for factory marked good / bad blocks. */ +static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; + +static struct nand_bbt_descr smallpage_memorybased = { + .options = NAND_BBT_SCAN2NDPAGE, + .offs = 5, + .len = 1, + .pattern = scan_ff_pattern +}; + +static struct nand_bbt_descr largepage_memorybased = { + .options = 0, + .offs = 0, + .len = 2, + .pattern = scan_ff_pattern +}; + +/* Generic flash bbt decriptors +*/ +static uint8_t bbt_pattern[] = { 'B', 'b', 't', '0' }; +static uint8_t mirror_pattern[] = { '1', 't', 'b', 'B' }; + +static struct nand_bbt_descr bbt_main_descr = { + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE + | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, + .offs = 0, + .len = 4, + .veroffs = 4, + .maxblocks = 4, + .pattern = bbt_pattern +}; + +static struct nand_bbt_descr bbt_mirror_descr = { + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE + | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, + .offs = 0, + .len = 4, + .veroffs = 4, + .maxblocks = 4, + .pattern = mirror_pattern +}; + +static int mxc_nand_scan_bbt(struct mtd_info *mtd) +{ + struct nand_chip *this = mtd->priv; + + g_page_mask = this->pagemask; + + if (IS_2K_PAGE_NAND) { + NFC_SET_NFMS(1 << NFMS_NF_PG_SZ); + this->ecc.layout = &nand_hw_eccoob_2k; + } else if (IS_4K_PAGE_NAND) { + NFC_SET_NFMS(1 << NFMS_NF_PG_SZ); + this->ecc.layout = &nand_hw_eccoob_4k; + } else { + this->ecc.layout = &nand_hw_eccoob_512; + } + + /* reconfig for interleave mode */ +#ifdef NFC_AUTO_MODE_ENABLE + if (this->numchips > 1) { + num_of_interleave = this->numchips; + this->numchips = 1; + + /* FIXEME:need remove it + * when kernel support + * 4G larger space + */ + mtd->size = this->chipsize; + mtd->erasesize *= num_of_interleave; + mtd->writesize *= num_of_interleave; + mtd->oobsize *= num_of_interleave; + this->page_shift = ffs(mtd->writesize) - 1; + this->bbt_erase_shift = + this->phys_erase_shift = ffs(mtd->erasesize) - 1; + this->chip_shift = ffs(this->chipsize) - 1; + this->oob_poi = this->buffers->databuf + mtd->writesize; + } +#endif + /* propagate ecc.layout to mtd_info */ + mtd->ecclayout = this->ecc.layout; + + /* jffs2 not write oob */ + mtd->flags &= ~MTD_OOB_WRITEABLE; + + /* use flash based bbt */ + this->bbt_td = &bbt_main_descr; + this->bbt_md = &bbt_mirror_descr; + + /* update flash based bbt */ + this->options |= NAND_USE_FLASH_BBT; + + if (!this->badblock_pattern) { + this->badblock_pattern = (mtd->writesize > 512) ? + &largepage_memorybased : &smallpage_memorybased; + } + + /* Build bad block table */ + return nand_scan_bbt(mtd, this->badblock_pattern); +} + +static void mxc_nfc_init(void) +{ + /* Disable interrupt */ + raw_write((raw_read(REG_NFC_INTRRUPT) | NFC_INT_MSK), REG_NFC_INTRRUPT); + + /* disable spare enable */ + raw_write(raw_read(REG_NFC_SP_EN) & ~NFC_SP_EN, REG_NFC_SP_EN); + + /* Unlock the internal RAM Buffer */ + raw_write(NFC_SET_BLS(NFC_BLS_UNLCOKED), REG_NFC_BLS); + + /* Blocks to be unlocked */ + UNLOCK_ADDR(0x0, 0xFFFF); + + /* Unlock Block Command for given address range */ + raw_write(NFC_SET_WPC(NFC_WPC_UNLOCK), REG_NFC_WPC); + + /* Enable symetric mode by default except mx37TO1.0 */ + if (!(cpu_is_mx37_rev(CHIP_REV_1_0) == 1)) + raw_write(raw_read(REG_NFC_ONE_CYCLE) | + NFC_ONE_CYCLE, REG_NFC_ONE_CYCLE); + +} + +static int mxc_alloc_buf(void) +{ + int err = 0; + + data_buf = kzalloc(NAND_MAX_PAGESIZE, GFP_KERNEL); + if (!data_buf) { + printk(KERN_ERR "%s: failed to allocate data_buf\n", __func__); + err = -ENOMEM; + goto out; + } + oob_buf = kzalloc(NAND_MAX_OOBSIZE, GFP_KERNEL); + if (!oob_buf) { + printk(KERN_ERR "%s: failed to allocate oob_buf\n", __func__); + err = -ENOMEM; + goto out; + } + + out: + return err; +} + +static void mxc_free_buf(void) +{ + kfree(data_buf); + kfree(oob_buf); +} + +/*! + * This function is called during the driver binding process. + * + * @param pdev the device structure used to store device specific + * information that is used by the suspend, resume and + * remove functions + * + * @return The function always returns 0. + */ +static int __init mxcnd_probe(struct platform_device *pdev) +{ + struct nand_chip *this; + struct mtd_info *mtd; + struct flash_platform_data *flash = pdev->dev.platform_data; + int nr_parts = 0, err = 0; + + nfc_axi_base = IO_ADDRESS(NFC_AXI_BASE_ADDR); + nfc_ip_base = IO_ADDRESS(NFC_BASE_ADDR); + + /* init the nfc */ + mxc_nfc_init(); + + /* init data buf */ + if (mxc_alloc_buf()) + goto out; + + /* Allocate memory for MTD device structure and private data */ + mxc_nand_data = kzalloc(sizeof(struct mxc_mtd_s), GFP_KERNEL); + if (!mxc_nand_data) { + printk(KERN_ERR "%s: failed to allocate mtd_info\n", + __FUNCTION__); + err = -ENOMEM; + goto out; + } + + memset((char *)&g_nandfc_info, 0, sizeof(g_nandfc_info)); + + mxc_nand_data->dev = &pdev->dev; + /* structures must be linked */ + this = &mxc_nand_data->nand; + mtd = &mxc_nand_data->mtd; + mtd->priv = this; + mtd->owner = THIS_MODULE; + + this->priv = mxc_nand_data; + this->cmdfunc = mxc_nand_command; + this->select_chip = mxc_nand_select_chip; + this->read_byte = mxc_nand_read_byte; + this->read_word = mxc_nand_read_word; + this->write_buf = mxc_nand_write_buf; + this->read_buf = mxc_nand_read_buf; + this->verify_buf = mxc_nand_verify_buf; + this->scan_bbt = mxc_nand_scan_bbt; + + /* NAND bus width determines access funtions used by upper layer */ + if (flash->width == 2) { + this->read_byte = mxc_nand_read_byte16; + this->options |= NAND_BUSWIDTH_16; + NFC_SET_NFMS(1 << NFMS_NF_DWIDTH); + } else { + NFC_SET_NFMS(0); + } + + nfc_clk = clk_get(&pdev->dev, "nfc_clk"); + clk_enable(nfc_clk); + + init_waitqueue_head(&irq_waitq); + err = request_irq(MXC_INT_NANDFC, mxc_nfc_irq, 0, "mxc_nd", NULL); + if (err) { + goto out_1; + } + + if (hardware_ecc) { + this->ecc.read_page = mxc_nand_read_page; + this->ecc.write_page = mxc_nand_write_page; + this->ecc.read_oob = mxc_nand_read_oob; + this->ecc.layout = &nand_hw_eccoob_512; + this->ecc.calculate = mxc_nand_calculate_ecc; + this->ecc.hwctl = mxc_nand_enable_hwecc; + this->ecc.correct = mxc_nand_correct_data; + this->ecc.mode = NAND_ECC_HW; + this->ecc.size = 512; + this->ecc.bytes = 9; + raw_write((raw_read(REG_NFC_ECC_EN) | NFC_ECC_EN), + REG_NFC_ECC_EN); + } else { + this->ecc.mode = NAND_ECC_SOFT; + raw_write((raw_read(REG_NFC_ECC_EN) & ~NFC_ECC_EN), + REG_NFC_ECC_EN); + } + + /* config the gpio */ + if (flash->init) + flash->init(); + + /* Reset NAND */ + this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); + + /* Scan to find existence of the device */ + if (nand_scan(mtd, NFC_GET_MAXCHIP_SP())) { + DEBUG(MTD_DEBUG_LEVEL0, + "MXC_ND2: Unable to find any NAND device.\n"); + err = -ENXIO; + goto out_1; + } + + /* Register the partitions */ +#ifdef CONFIG_MTD_PARTITIONS + nr_parts = + parse_mtd_partitions(mtd, part_probes, &mxc_nand_data->parts, 0); + if (nr_parts > 0) + add_mtd_partitions(mtd, mxc_nand_data->parts, nr_parts); + else if (flash->parts) + add_mtd_partitions(mtd, flash->parts, flash->nr_parts); + else +#endif + { + pr_info("Registering %s as whole device\n", mtd->name); + add_mtd_device(mtd); + } + + platform_set_drvdata(pdev, mtd); + + return 0; + + out_1: + kfree(mxc_nand_data); + out: + return err; + +} + + /*! + * Dissociates the driver from the device. + * + * @param pdev the device structure used to give information on which + * + * @return The function always returns 0. + */ + +static int __exit mxcnd_remove(struct platform_device *pdev) +{ + struct mtd_info *mtd = platform_get_drvdata(pdev); + struct flash_platform_data *flash = pdev->dev.platform_data; + + if (flash->exit) + flash->exit(); + + mxc_free_buf(); + + clk_disable(nfc_clk); + clk_put(nfc_clk); + platform_set_drvdata(pdev, NULL); + + if (mxc_nand_data) { + nand_release(mtd); + free_irq(MXC_INT_NANDFC, NULL); + kfree(mxc_nand_data); + } + + return 0; +} + +#ifdef CONFIG_PM +/*! + * This function is called to put the NAND in a low power state. Refer to the + * document driver-model/driver.txt in the kernel source tree for more + * information. + * + * @param pdev the device information structure + * + * @param state the power state the device is entering + * + * @return The function returns 0 on success and -1 on failure + */ + +static int mxcnd_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct mtd_info *info = platform_get_drvdata(pdev); + int ret = 0; + + DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND2 : NAND suspend\n"); + if (info) + ret = info->suspend(info); + + /* Disable the NFC clock */ + clk_disable(nfc_clk); + + /* Disable the NFC clock */ + clk_disable(nfc_clk); + + return ret; +} + +/*! + * This function is called to bring the NAND back from a low power state. Refer + * to the document driver-model/driver.txt in the kernel source tree for more + * information. + * + * @param pdev the device information structure + * + * @return The function returns 0 on success and -1 on failure + */ +static int mxcnd_resume(struct platform_device *pdev) +{ + struct mtd_info *info = platform_get_drvdata(pdev); + int ret = 0; + + DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND2 : NAND resume\n"); + /* Enable the NFC clock */ + clk_enable(nfc_clk); + + if (info) { + info->resume(info); + } + + return ret; +} + +#else +#define mxcnd_suspend NULL +#define mxcnd_resume NULL +#endif /* CONFIG_PM */ + +/*! + * This structure contains pointers to the power management callback functions. + */ +static struct platform_driver mxcnd_driver = { + .driver = { + .name = "mxc_nandv2_flash", + }, + .probe = mxcnd_probe, + .remove = __exit_p(mxcnd_remove), + .suspend = mxcnd_suspend, + .resume = mxcnd_resume, +}; + +/*! + * Main initialization routine + * @return 0 if successful; non-zero otherwise + */ +static int __init mxc_nd_init(void) +{ + /* Register the device driver structure. */ + pr_info("MXC MTD nand Driver %s\n", DVR_VER); + if (platform_driver_register(&mxcnd_driver) != 0) { + printk(KERN_ERR "Driver register failed for mxcnd_driver\n"); + return -ENODEV; + } + return 0; +} + +/*! + * Clean up routine + */ +static void __exit mxc_nd_cleanup(void) +{ + /* Unregister the device structure */ + platform_driver_unregister(&mxcnd_driver); +} + +module_init(mxc_nd_init); +module_exit(mxc_nd_cleanup); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("MXC NAND MTD driver Version 2-5"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/mtd/nand/mxc_nd2.h +++ linux-2.6.28/drivers/mtd/nand/mxc_nd2.h @@ -0,0 +1,675 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @file mxc_nd2.h + * + * @brief This file contains the NAND Flash Controller register information. + * + * + * @ingroup NAND_MTD + */ + +#ifndef __MXC_ND2_H__ +#define __MXC_ND2_H__ + +#include + +#define IS_2K_PAGE_NAND ((mtd->writesize / num_of_interleave) \ + == NAND_PAGESIZE_2KB) +#define IS_4K_PAGE_NAND ((mtd->writesize / num_of_interleave) \ + == NAND_PAGESIZE_4KB) +#define IS_LARGE_PAGE_NAND ((mtd->writesize / num_of_interleave) > 512) + +#define GET_NAND_OOB_SIZE (mtd->oobsize / num_of_interleave) + +#define NAND_PAGESIZE_2KB 2048 +#define NAND_PAGESIZE_4KB 4096 + +#ifdef CONFIG_ARCH_MXC_HAS_NFC_V3 +/* + * For V3 NFC registers Definition + */ +/* AXI Bus Mapped */ +#define NFC_AXI_BASE_ADDR NFC_BASE_ADDR_AXI + +#if defined(CONFIG_ARCH_MXC_HAS_NFC_V3_1) /* mx37 */ +#define MXC_INT_NANDFC MXC_INT_EMI +#define NFC_FLASH_ADDR_CMD (nfc_axi_base + 0x1E00) +#define NFC_CONFIG1 (nfc_axi_base + 0x1E04) +#define NFC_ECC_STATUS_RESULT (nfc_axi_base + 0x1E08) +#define LAUNCH_NFC (nfc_axi_base + 0x1E0c) +#define NFC_WRPROT (nfc_ip_base + 0x00) +#define NFC_WRPROT_UNLOCK_BLK_ADD0 (nfc_ip_base + 0x04) +#define NFC_CONFIG2 (nfc_ip_base + 0x14) +#define NFC_IPC (nfc_ip_base + 0x18) +#elif defined(CONFIG_ARCH_MXC_HAS_NFC_V3_2) /* mx51 */ +#define MXC_INT_NANDFC MXC_INT_NFC +#define NFC_AUTO_MODE_ENABLE +#define NFC_FLASH_CMD (nfc_axi_base + 0x1E00) +#define NFC_FLASH_ADDR0 (nfc_axi_base + 0x1E04) +#define NFC_FLASH_ADDR8 (nfc_axi_base + 0x1E24) +#define NFC_CONFIG1 (nfc_axi_base + 0x1E34) +#define NFC_ECC_STATUS_RESULT (nfc_axi_base + 0x1E38) +#define NFC_ECC_STATUS_SUM (nfc_axi_base + 0x1E3C) +#define LAUNCH_NFC (nfc_axi_base + 0x1E40) +#define NFC_WRPROT (nfc_ip_base + 0x00) +#define NFC_WRPROT_UNLOCK_BLK_ADD0 (nfc_ip_base + 0x04) +#define NFC_CONFIG2 (nfc_ip_base + 0x24) +#define NFC_CONFIG3 (nfc_ip_base + 0x28) +#define NFC_IPC (nfc_ip_base + 0x2C) +#else /* skye */ +#define NFC_FLASH_ADDR_CMD (nfc_axi_base + 0xE00) +#define NFC_CONFIG1 (nfc_axi_base + 0xE04) +#define NFC_ECC_STATUS_RESULT (nfc_axi_base + 0xE08) +#define LAUNCH_NFC (nfc_axi_base + 0xE0C) +#define NFC_WRPROT (nfc_ip_base + 0x00) +#define NFC_WRPROT_UNLOCK_BLK_ADD0 (nfc_ip_base + 0x04) +#define NFC_CONFIG2 (nfc_ip_base + 0x14) +#define NFC_IPC (nfc_ip_base + 0x18) +#endif +/*! + * Addresses for NFC RAM BUFFER Main area 0 + */ +#define MAIN_AREA0 ((u16 *)(nfc_axi_base + 0x000)) +#define MAIN_AREA1 ((u16 *)(nfc_axi_base + 0x200)) + +/*! + * Addresses for NFC SPARE BUFFER Spare area 0 + */ +#if defined(CONFIG_ARCH_MXC_HAS_NFC_V3_1) || \ + defined(CONFIG_ARCH_MXC_HAS_NFC_V3_2) +#define SPARE_AREA0 ((u16 *)(nfc_axi_base + 0x1000)) +#define SPARE_LEN 64 +#define SPARE_COUNT 8 +#define SPARE_SIZE (SPARE_LEN * SPARE_COUNT) +#else +#define SPARE_AREA0 ((u16 *)(nfc_axi_base + 0x800)) +#define SPARE_LEN 16 +#define SPARE_COUNT 4 +#define SPARE_SIZE (SPARE_LEN * SPARE_COUNT) +#endif + +#if defined(CONFIG_ARCH_MXC_HAS_NFC_V3_1) || \ + defined(CONFIG_ARCH_MXC_HAS_NFC_V3_2) +#define NFC_SPAS_WIDTH 8 +#define NFC_SPAS_SHIFT 16 + +#define IS_4BIT_ECC \ +( \ + cpu_is_mx51_rev(CHIP_REV_2_0) == 1 ? \ + !((raw_read(NFC_CONFIG2) & NFC_ECC_MODE_4) >> 6) : \ + ((raw_read(NFC_CONFIG2) & NFC_ECC_MODE_4) >> 6) \ +) + +#define NFC_SET_SPAS(v) \ + raw_write((((raw_read(NFC_CONFIG2) & \ + NFC_FIELD_RESET(NFC_SPAS_WIDTH, NFC_SPAS_SHIFT)) | ((v) << 16))), \ + NFC_CONFIG2) + +#define NFC_SET_ECC_MODE(v) \ +do { \ + if (cpu_is_mx51_rev(CHIP_REV_2_0) == 1) { \ + if ((v) == NFC_SPAS_218 || (v) == NFC_SPAS_112) \ + raw_write(((raw_read(NFC_CONFIG2) & \ + NFC_ECC_MODE_MASK) | \ + NFC_ECC_MODE_4), NFC_CONFIG2); \ + else \ + raw_write(((raw_read(NFC_CONFIG2) & \ + NFC_ECC_MODE_MASK) & \ + NFC_ECC_MODE_8), NFC_CONFIG2); \ + } else { \ + if ((v) == NFC_SPAS_218 || (v) == NFC_SPAS_112) \ + raw_write(((raw_read(NFC_CONFIG2) & \ + NFC_ECC_MODE_MASK) & \ + NFC_ECC_MODE_8), NFC_CONFIG2); \ + else \ + raw_write(((raw_read(NFC_CONFIG2) & \ + NFC_ECC_MODE_MASK) | \ + NFC_ECC_MODE_4), NFC_CONFIG2); \ + } \ +} while (0) + +#define WRITE_NFC_IP_REG(val,reg) \ + do { \ + raw_write(NFC_IPC_CREQ, NFC_IPC); \ + while (!((raw_read(NFC_IPC) & NFC_IPC_ACK)>>1));\ + raw_write(val, reg); \ + raw_write(0, NFC_IPC); \ + } while(0) + +#else +#define IS_4BIT_ECC 1 +#define NFC_SET_SPAS(v) +#define NFC_SET_ECC_MODE(v) +#define NFC_SET_NFMS(v) (NFMS |= (v)) + +#define WRITE_NFC_IP_REG(val,reg) \ + raw_write((raw_read(REG_NFC_OPS_STAT) & ~NFC_OPS_STAT), \ + REG_NFC_OPS_STAT) +#endif + +#define GET_NFC_ECC_STATUS() raw_read(REG_NFC_ECC_STATUS_RESULT); + +/*! + * Set 1 to specific operation bit, rest to 0 in LAUNCH_NFC Register for + * Specific operation + */ +#define NFC_CMD 0x1 +#define NFC_ADDR 0x2 +#define NFC_INPUT 0x4 +#define NFC_OUTPUT 0x8 +#define NFC_ID 0x10 +#define NFC_STATUS 0x20 + +#ifdef CONFIG_ARCH_MXC_HAS_NFC_V3_2 /* mx51 */ +#define NFC_AUTO_PROG 0x40 +#define NFC_AUTO_READ 0x80 +#define NFC_AUTO_ERASE 0x200 +#define NFC_COPY_BACK_0 0x400 +#define NFC_COPY_BACK_1 0x800 +#define NFC_AUTO_STATE 0x1000 +#endif + +/* Bit Definitions for NFC_IPC*/ +#define NFC_OPS_STAT (1 << 31) + +#ifdef CONFIG_ARCH_MXC_HAS_NFC_V3_2 /* mx51 */ +#define NFC_OP_DONE (1 << 30) +#define NFC_RB (1 << 28) +#define NFC_PS_WIDTH 2 +#define NFC_PS_SHIFT 0 +#define NFC_PS_512 0 +#define NFC_PS_2K 1 +#define NFC_PS_4K 2 +#else +#define NFC_RB (1 << 29) +#endif + +#define NFC_ONE_CYCLE (1 << 2) + +#ifdef CONFIG_ARCH_MXC_HAS_NFC_V3_2 /* mx51 */ +#define NFC_INT_MSK (1 << 15) +#define NFC_AUTO_PROG_DONE_MSK (1 << 14) +#define NFC_NUM_ADDR_PHASE1_WIDTH 2 +#define NFC_NUM_ADDR_PHASE1_SHIFT 12 + +#define NFC_NUM_ADDR_PHASE0_WIDTH 1 +#define NFC_NUM_ADDR_PHASE0_SHIFT 5 + +#define NFC_ONE_LESS_PHASE1 0 +#define NFC_TWO_LESS_PHASE1 1 + +#define NFC_FLASH_ADDR_SHIFT 0 +#else +#define NFC_INT_MSK (1 << 4) +#define NFC_BIG (1 << 5) +#define NFC_FLASH_ADDR_SHIFT 16 +#endif + +#define NFC_UNLOCK_END_ADDR_SHIFT 16 + +/* Bit definition for NFC_CONFIGRATION_1 */ +#define NFC_SP_EN (1 << 0) +#define NFC_CE (1 << 1) +#define NFC_RST (1 << 2) +#define NFC_ECC_EN (1 << 3) + +#define NFC_FIELD_RESET(width, shift) ~(((1 << (width)) - 1) << (shift)) + +#define NFC_RBA_SHIFT 4 + +#if defined(CONFIG_ARCH_MXC_HAS_NFC_V3_1) || \ + defined(CONFIG_ARCH_MXC_HAS_NFC_V3_2) /* mx51 */ +#define NFC_RBA_WIDTH 3 +#else +#define NFC_RBA_WIDTH 2 +#endif + +#if defined(CONFIG_ARCH_MXC_HAS_NFC_V3_2) /* mx51 */ +#define NFC_ITERATION_SHIFT 8 +#define NFC_ITERATION_WIDTH 4 +#define NFC_ACTIVE_CS_SHIFT 12 +#define NFC_ACTIVE_CS_WIDTH 3 +/* bit definition for CONFIGRATION3 */ +#define NFC_NO_SDMA (1 << 20) +#define NFC_FMP_SHIFT 16 +#define NFC_FMP_WIDTH 4 +#define NFC_RBB_MODE (1 << 15) +#define NFC_NUM_OF_DEVICES_SHIFT 12 +#define NFC_NUM_OF_DEVICES_WIDTH 4 +#define NFC_DMA_MODE_SHIFT 11 +#define NFC_DMA_MODE_WIDTH 1 +#define NFC_SBB_SHIFT 8 +#define NFC_SBB_WIDTH 3 +#define NFC_BIG (1 << 7) +#define NFC_SB2R_SHIFT 4 +#define NFC_SB2R_WIDTH 3 +#define NFC_FW_SHIFT 3 +#define NFC_FW_WIDTH 1 +#define NFC_TOO (1 << 2) +#define NFC_ADD_OP_SHIFT 0 +#define NFC_ADD_OP_WIDTH 2 +#define NFC_FW_8 1 +#define NFC_FW_16 0 +#define NFC_ST_CMD_SHITF 24 +#define NFC_ST_CMD_WIDTH 8 +#endif + +#define NFC_PPB_32 (0 << 7) +#define NFC_PPB_64 (1 << 7) +#define NFC_PPB_128 (2 << 7) +#define NFC_PPB_256 (3 << 7) +#define NFC_PPB_RESET ~(3 << 7) + +#define NFC_BLS_LOCKED (0 << 16) +#define NFC_BLS_LOCKED_DEFAULT (1 << 16) +#define NFC_BLS_UNLCOKED (2 << 16) +#define NFC_BLS_RESET ~(3 << 16) +#define NFC_WPC_LOCK_TIGHT 1 +#define NFC_WPC_LOCK (1 << 1) +#define NFC_WPC_UNLOCK (1 << 2) +#define NFC_WPC_RESET ~(7) +#if defined(CONFIG_ARCH_MXC_HAS_NFC_V3_1) || \ + defined(CONFIG_ARCH_MXC_HAS_NFC_V3_2) +#define NFC_ECC_MODE_4 (1 << 6) +#define NFC_ECC_MODE_8 ~(1 << 6) +#define NFC_ECC_MODE_MASK ~(1 << 6) +#define NFC_SPAS_16 8 +#define NFC_SPAS_64 32 +#define NFC_SPAS_128 64 +#define NFC_SPAS_112 56 +#define NFC_SPAS_218 109 +#define NFC_IPC_CREQ (1 << 0) +#define NFC_IPC_ACK (1 << 1) +#endif + +#define REG_NFC_OPS_STAT NFC_IPC +#define REG_NFC_INTRRUPT NFC_CONFIG2 +#ifdef CONFIG_ARCH_MXC_HAS_NFC_V3_2 +#define REG_NFC_FLASH_ADDR NFC_FLASH_ADDR0 +#define REG_NFC_FLASH_CMD NFC_FLASH_CMD +#else +#define REG_NFC_FLASH_ADDR NFC_FLASH_ADDR_CMD +#define REG_NFC_FLASH_CMD NFC_FLASH_ADDR_CMD +#endif +#define REG_NFC_OPS LAUNCH_NFC +#define REG_NFC_SET_RBA NFC_CONFIG1 +#define REG_NFC_RB NFC_IPC +#define REG_NFC_ECC_EN NFC_CONFIG2 +#define REG_NFC_ECC_STATUS_RESULT NFC_ECC_STATUS_RESULT +#define REG_NFC_CE NFC_CONFIG1 +#define REG_NFC_RST NFC_CONFIG1 +#define REG_NFC_PPB NFC_CONFIG2 +#define REG_NFC_SP_EN NFC_CONFIG1 +#define REG_NFC_BLS NFC_WRPROT +#define REG_UNLOCK_BLK_ADD0 NFC_WRPROT_UNLOCK_BLK_ADD0 +#define REG_UNLOCK_BLK_ADD1 NFC_WRPROT_UNLOCK_BLK_ADD1 +#define REG_UNLOCK_BLK_ADD2 NFC_WRPROT_UNLOCK_BLK_ADD2 +#define REG_UNLOCK_BLK_ADD3 NFC_WRPROT_UNLOCK_BLK_ADD3 +#define REG_NFC_WPC NFC_WRPROT +#define REG_NFC_ONE_CYCLE NFC_CONFIG2 + +/* NFC V3 Specific MACRO functions definitions */ +#define raw_write(v,a) __raw_writel(v,a) +#define raw_read(a) __raw_readl(a) + +/* Explcit ack ops status (if any), before issue of any command */ +#define ACK_OPS \ + raw_write((raw_read(REG_NFC_OPS_STAT) & ~NFC_OPS_STAT), \ + REG_NFC_OPS_STAT); + +/* Set RBA buffer id*/ +#define NFC_SET_RBA(val) \ + raw_write((raw_read(REG_NFC_SET_RBA) & \ + (NFC_FIELD_RESET(NFC_RBA_WIDTH, NFC_RBA_SHIFT))) | \ + ((val) << NFC_RBA_SHIFT), REG_NFC_SET_RBA); + +#define NFC_SET_PS(val) \ + raw_write((raw_read(NFC_CONFIG2) & \ + (NFC_FIELD_RESET(NFC_PS_WIDTH, NFC_PS_SHIFT))) | \ + ((val) << NFC_PS_SHIFT), NFC_CONFIG2); + +#ifdef CONFIG_ARCH_MXC_HAS_NFC_V3_2 +#define UNLOCK_ADDR(start_addr,end_addr) \ +{ \ + int i = 0; \ + for (; i < NAND_MAX_CHIPS; i++) \ + raw_write(start_addr | \ + (end_addr << NFC_UNLOCK_END_ADDR_SHIFT), \ + REG_UNLOCK_BLK_ADD0 + (i << 2)); \ +} +#define NFC_SET_NFC_ACTIVE_CS(val) \ + raw_write((raw_read(NFC_CONFIG1) & \ + (NFC_FIELD_RESET(NFC_ACTIVE_CS_WIDTH, NFC_ACTIVE_CS_SHIFT))) | \ + ((val) << NFC_ACTIVE_CS_SHIFT), NFC_CONFIG1); + +#define NFC_GET_MAXCHIP_SP() 8 + +#else +#define UNLOCK_ADDR(start_addr,end_addr) \ + raw_write(start_addr | \ + (end_addr << NFC_UNLOCK_END_ADDR_SHIFT), REG_UNLOCK_BLK_ADD0); + +#define NFC_SET_NFC_ACTIVE_CS(val) +#define NFC_GET_MAXCHIP_SP() 1 +#endif + +#define NFC_SET_BLS(val) ((raw_read(REG_NFC_BLS) & NFC_BLS_RESET) | val ) +#define NFC_SET_WPC(val) ((raw_read(REG_NFC_WPC) & NFC_WPC_RESET) | val ) +#define CHECK_NFC_RB raw_read(REG_NFC_RB) & NFC_RB + +#if defined(CONFIG_ARCH_MXC_HAS_NFC_V3_2) +#define NFC_SET_NFC_NUM_ADDR_PHASE1(val) \ + raw_write((raw_read(NFC_CONFIG2) & \ + (NFC_FIELD_RESET(NFC_NUM_ADDR_PHASE1_WIDTH, \ + NFC_NUM_ADDR_PHASE1_SHIFT))) | \ + ((val) << NFC_NUM_ADDR_PHASE1_SHIFT), NFC_CONFIG2); + +#define NFC_SET_NFC_NUM_ADDR_PHASE0(val) \ + raw_write((raw_read(NFC_CONFIG2) & \ + (NFC_FIELD_RESET(NFC_NUM_ADDR_PHASE0_WIDTH, \ + NFC_NUM_ADDR_PHASE0_SHIFT))) | \ + ((val) << NFC_NUM_ADDR_PHASE0_SHIFT), NFC_CONFIG2); + +#define NFC_SET_NFC_ITERATION(val) \ + raw_write((raw_read(NFC_CONFIG1) & \ + (NFC_FIELD_RESET(NFC_ITERATION_WIDTH, NFC_ITERATION_SHIFT))) | \ + ((val) << NFC_ITERATION_SHIFT), NFC_CONFIG1); + +#define NFC_SET_FW(val) \ + raw_write((raw_read(NFC_CONFIG3) & \ + (NFC_FIELD_RESET(NFC_FW_WIDTH, NFC_FW_SHIFT))) | \ + ((val) << NFC_FW_SHIFT), NFC_CONFIG3); + +#define NFC_SET_NUM_OF_DEVICE(val) \ + raw_write((raw_read(NFC_CONFIG3) & \ + (NFC_FIELD_RESET(NFC_NUM_OF_DEVICES_WIDTH, \ + NFC_NUM_OF_DEVICES_SHIFT))) | \ + ((val) << NFC_NUM_OF_DEVICES_SHIFT), NFC_CONFIG3); + +#define NFC_SET_ADD_OP_MODE(val) \ + raw_write((raw_read(NFC_CONFIG3) & \ + (NFC_FIELD_RESET(NFC_ADD_OP_WIDTH, NFC_ADD_OP_SHIFT))) | \ + ((val) << NFC_ADD_OP_SHIFT), NFC_CONFIG3); + +#define NFC_SET_ADD_CS_MODE(val) \ +{ \ + NFC_SET_ADD_OP_MODE(val); \ + NFC_SET_NUM_OF_DEVICE(this->numchips - 1); \ +} + +#define NFC_SET_ST_CMD(val) \ + raw_write((raw_read(NFC_CONFIG2) & \ + (NFC_FIELD_RESET(NFC_ST_CMD_WIDTH, \ + NFC_ST_CMD_SHITF))) | \ + ((val) << NFC_ST_CMD_SHITF), NFC_CONFIG2); + +#define NFMS_NF_DWIDTH 0 +#define NFMS_NF_PG_SZ 1 +#define NFC_CMD_1_SHIFT 8 + +#define NUM_OF_ADDR_CYCLE (fls(g_page_mask) >> 3) + +/*should set the fw,ps,spas,ppb*/ +#define NFC_SET_NFMS(v) \ +do { \ + NFC_SET_FW(NFC_FW_8); \ + if (((v) & (1 << NFMS_NF_DWIDTH))) \ + NFC_SET_FW(NFC_FW_16); \ + if (((v) & (1 << NFMS_NF_PG_SZ))) { \ + if (IS_2K_PAGE_NAND) { \ + NFC_SET_PS(NFC_PS_2K); \ + NFC_SET_NFC_NUM_ADDR_PHASE1(NUM_OF_ADDR_CYCLE); \ + NFC_SET_NFC_NUM_ADDR_PHASE0(NFC_TWO_LESS_PHASE1); \ + } else if (IS_4K_PAGE_NAND) { \ + NFC_SET_PS(NFC_PS_4K); \ + NFC_SET_NFC_NUM_ADDR_PHASE1(NUM_OF_ADDR_CYCLE); \ + NFC_SET_NFC_NUM_ADDR_PHASE0(NFC_TWO_LESS_PHASE1); \ + } else { \ + NFC_SET_PS(NFC_PS_512); \ + NFC_SET_NFC_NUM_ADDR_PHASE1(NUM_OF_ADDR_CYCLE - 1); \ + NFC_SET_NFC_NUM_ADDR_PHASE0(NFC_ONE_LESS_PHASE1); \ + } \ + NFC_SET_ADD_CS_MODE(1); \ + NFC_SET_SPAS(GET_NAND_OOB_SIZE >> 1); \ + NFC_SET_ECC_MODE(GET_NAND_OOB_SIZE >> 1); \ + NFC_SET_ST_CMD(0x70); \ + raw_write(raw_read(NFC_CONFIG3) | 1 << 20, NFC_CONFIG3); \ + } \ +} while (0) +#endif + +#ifdef CONFIG_ARCH_MXC_HAS_NFC_V3_1 +#define NFC_SET_NFMS(v) +#endif + +#define READ_PAGE() send_read_page(0) +#define PROG_PAGE() send_prog_page(0) + +#elif CONFIG_ARCH_MXC_HAS_NFC_V2 + +/* + * For V1/V2 NFC registers Definition + */ + +#define NFC_AXI_BASE_ADDR 0x00 +/* + * Addresses for NFC registers + */ +#ifdef CONFIG_ARCH_MXC_HAS_NFC_V2_1 +#define NFC_REG_BASE (nfc_ip_base + 0x1000) +#else +#define NFC_REG_BASE nfc_ip_base +#endif +#define NFC_BUF_SIZE (NFC_REG_BASE + 0xE00) +#define NFC_BUF_ADDR (NFC_REG_BASE + 0xE04) +#define NFC_FLASH_ADDR (NFC_REG_BASE + 0xE06) +#define NFC_FLASH_CMD (NFC_REG_BASE + 0xE08) +#define NFC_CONFIG (NFC_REG_BASE + 0xE0A) +#ifdef CONFIG_ARCH_MXC_HAS_NFC_V2_1 +#define NFC_ECC_STATUS_RESULT (NFC_REG_BASE + 0xE0C) +#define NFC_ECC_STATUS_RESULT_1 (NFC_REG_BASE + 0xE0C) +#define NFC_ECC_STATUS_RESULT_2 (NFC_REG_BASE + 0xE0E) +#define NFC_SPAS (NFC_REG_BASE + 0xE10) +#else +#define NFC_ECC_STATUS_RESULT (NFC_REG_BASE + 0xE0C) +#define NFC_RSLTMAIN_AREA (NFC_REG_BASE + 0xE0E) +#define NFC_RSLTSPARE_AREA (NFC_REG_BASE + 0xE10) +#endif +#define NFC_WRPROT (NFC_REG_BASE + 0xE12) +#ifdef CONFIG_ARCH_MXC_HAS_NFC_V2_1 +#define NFC_UNLOCKSTART_BLKADDR (NFC_REG_BASE + 0xE20) +#define NFC_UNLOCKEND_BLKADDR (NFC_REG_BASE + 0xE22) +#define NFC_UNLOCKSTART_BLKADDR1 (NFC_REG_BASE + 0xE24) +#define NFC_UNLOCKEND_BLKADDR1 (NFC_REG_BASE + 0xE26) +#define NFC_UNLOCKSTART_BLKADDR2 (NFC_REG_BASE + 0xE28) +#define NFC_UNLOCKEND_BLKADDR2 (NFC_REG_BASE + 0xE2A) +#define NFC_UNLOCKSTART_BLKADDR3 (NFC_REG_BASE + 0xE2C) +#define NFC_UNLOCKEND_BLKADDR3 (NFC_REG_BASE + 0xE2E) +#else +#define NFC_UNLOCKSTART_BLKADDR (NFC_REG_BASE + 0xE14) +#define NFC_UNLOCKEND_BLKADDR (NFC_REG_BASE + 0xE16) +#endif +#define NFC_NF_WRPRST (NFC_REG_BASE + 0xE18) +#define NFC_CONFIG1 (NFC_REG_BASE + 0xE1A) +#define NFC_CONFIG2 (NFC_REG_BASE + 0xE1C) + +/*! + * Addresses for NFC RAM BUFFER Main area 0 + */ +#define MAIN_AREA0 (u16 *)(nfc_ip_base + 0x000) +#define MAIN_AREA1 (u16 *)(nfc_ip_base + 0x200) + +/*! + * Addresses for NFC SPARE BUFFER Spare area 0 + */ +#ifdef CONFIG_ARCH_MXC_HAS_NFC_V2_1 +#define SPARE_AREA0 (u16 *)(nfc_ip_base + 0x1000) +#define SPARE_LEN 64 +#define SPARE_COUNT 8 +#else +#define SPARE_AREA0 (u16 *)(nfc_ip_base + 0x800) +#define SPARE_LEN 16 +#define SPARE_COUNT 4 +#endif +#define SPARE_SIZE (SPARE_LEN * SPARE_COUNT) + +#ifdef CONFIG_ARCH_MXC_HAS_NFC_V2_1 +#define REG_NFC_ECC_MODE NFC_CONFIG1 +#define SPAS_SHIFT (0) +#define REG_NFC_SPAS NFC_SPAS +#define SPAS_MASK (0xFF00) +#define IS_4BIT_ECC \ + ((raw_read(REG_NFC_ECC_MODE) & NFC_ECC_MODE_4) >> 0) + +#define NFC_SET_SPAS(v) \ + raw_write(((raw_read(REG_NFC_SPAS) & SPAS_MASK) | ((v<> 1); \ + NFC_SET_ECC_MODE(GET_NAND_OOB_SIZE >> 1); \ + } \ +} while (0) +#else +#define IS_4BIT_ECC (1) +#define NFC_SET_SPAS(v) +#define NFC_SET_ECC_MODE(v) +#define GET_ECC_STATUS() raw_read(REG_NFC_ECC_STATUS_RESULT); +#define NFC_SET_NFMS(v) (NFMS |= (v)) +#endif + +#define WRITE_NFC_IP_REG(val,reg) \ + raw_write((raw_read(REG_NFC_OPS_STAT) & ~NFC_OPS_STAT), \ + REG_NFC_OPS_STAT) + +#define GET_NFC_ECC_STATUS() raw_read(REG_NFC_ECC_STATUS_RESULT); + +/*! + * Set INT to 0, Set 1 to specific operation bit, rest to 0 in LAUNCH_NFC Register for + * Specific operation + */ +#define NFC_CMD 0x1 +#define NFC_ADDR 0x2 +#define NFC_INPUT 0x4 +#define NFC_OUTPUT 0x8 +#define NFC_ID 0x10 +#define NFC_STATUS 0x20 + +/* Bit Definitions */ +#define NFC_OPS_STAT (1 << 15) +#define NFC_SP_EN (1 << 2) +#define NFC_ECC_EN (1 << 3) +#define NFC_INT_MSK (1 << 4) +#define NFC_BIG (1 << 5) +#define NFC_RST (1 << 6) +#define NFC_CE (1 << 7) +#define NFC_ONE_CYCLE (1 << 8) +#define NFC_BLS_LOCKED 0 +#define NFC_BLS_LOCKED_DEFAULT 1 +#define NFC_BLS_UNLCOKED 2 +#define NFC_WPC_LOCK_TIGHT 1 +#define NFC_WPC_LOCK (1 << 1) +#define NFC_WPC_UNLOCK (1 << 2) +#define NFC_FLASH_ADDR_SHIFT 0 +#define NFC_UNLOCK_END_ADDR_SHIFT 0 + +#ifdef CONFIG_ARCH_MXC_HAS_NFC_V2_1 +#define NFC_ECC_MODE_4 (1<<0) +#define NFC_ECC_MODE_8 ~(1<<0) +#define NFC_SPAS_16 8 +#define NFC_SPAS_64 32 +#define NFC_SPAS_112 56 +#define NFC_SPAS_128 64 +#define NFC_SPAS_218 109 +#endif +/* NFC Register Mapping */ +#define REG_NFC_OPS_STAT NFC_CONFIG2 +#define REG_NFC_INTRRUPT NFC_CONFIG1 +#define REG_NFC_FLASH_ADDR NFC_FLASH_ADDR +#define REG_NFC_FLASH_CMD NFC_FLASH_CMD +#define REG_NFC_OPS NFC_CONFIG2 +#define REG_NFC_SET_RBA NFC_BUF_ADDR +#define REG_NFC_ECC_EN NFC_CONFIG1 +#define REG_NFC_ECC_STATUS_RESULT NFC_ECC_STATUS_RESULT +#define REG_NFC_CE NFC_CONFIG1 +#define REG_NFC_SP_EN NFC_CONFIG1 +#define REG_NFC_BLS NFC_CONFIG +#define REG_NFC_WPC NFC_WRPROT +#define REG_START_BLKADDR NFC_UNLOCKSTART_BLKADDR +#define REG_END_BLKADDR NFC_UNLOCKEND_BLKADDR +#define REG_NFC_RST NFC_CONFIG1 +#define REG_NFC_ONE_CYCLE NFC_CONFIG1 + +/* NFC V1/V2 Specific MACRO functions definitions */ + +#define raw_write(v,a) __raw_writew(v,a) +#define raw_read(a) __raw_readw(a) + +#define NFC_SET_BLS(val) val + +#define UNLOCK_ADDR(start_addr,end_addr) \ +{ \ + raw_write(start_addr,REG_START_BLKADDR); \ + raw_write(end_addr,REG_END_BLKADDR); \ +} + +#define NFC_SET_NFC_ACTIVE_CS(val) +#define NFC_GET_MAXCHIP_SP() 1 +#define NFC_SET_WPC(val) val + +/* NULL Definitions */ +#define ACK_OPS +#define NFC_SET_RBA(val) raw_write(val, REG_NFC_SET_RBA); + +#ifdef CONFIG_ARCH_MXC_HAS_NFC_V2_1 +#define READ_PAGE() send_read_page(0) +#define PROG_PAGE() send_prog_page(0) +#else +#define READ_PAGE() \ +do { \ + send_read_page(0); \ + send_read_page(1); \ + send_read_page(2); \ + send_read_page(3); \ +} while (0) + +#define PROG_PAGE() \ +do { \ + send_prog_page(0); \ + send_prog_page(1); \ + send_prog_page(2); \ + send_prog_page(3); \ +} while (0) +#endif +#define CHECK_NFC_RB 1 + +#endif + +#endif /* __MXC_ND2_H__ */ --- linux-2.6.28.orig/drivers/mtd/devices/mtd_dataflash.c +++ linux-2.6.28/drivers/mtd/devices/mtd_dataflash.c @@ -815,7 +815,8 @@ if (!(info->flags & IS_POW2PS)) return info; } - } + } else + return info; } } --- linux-2.6.28.orig/drivers/cpuidle/governors/menu.c +++ linux-2.6.28/drivers/cpuidle/governors/menu.c @@ -15,12 +15,14 @@ #include #define BREAK_FUZZ 4 /* 4 us */ +#define PRED_HISTORY_PCT 50 struct menu_device { int last_state_idx; unsigned int expected_us; unsigned int predicted_us; + unsigned int current_predicted_us; unsigned int last_measured_us; unsigned int elapsed_us; }; @@ -47,6 +49,12 @@ data->expected_us = (u32) ktime_to_ns(tick_nohz_get_sleep_length()) / 1000; + /* Recalculate predicted_us based on prediction_history_pct */ + data->predicted_us *= PRED_HISTORY_PCT; + data->predicted_us += (100 - PRED_HISTORY_PCT) * + data->current_predicted_us; + data->predicted_us /= 100; + /* find the deepest idle state that satisfies our constraints */ for (i = CPUIDLE_DRIVER_STATE_START + 1; i < dev->state_count; i++) { struct cpuidle_state *s = &dev->states[i]; @@ -97,7 +105,7 @@ measured_us = -1; /* Predict time until next break event */ - data->predicted_us = max(measured_us, data->last_measured_us); + data->current_predicted_us = max(measured_us, data->last_measured_us); if (last_idle_us + BREAK_FUZZ < data->expected_us - target->exit_latency) { --- linux-2.6.28.orig/drivers/serial/8250_pci.c +++ linux-2.6.28/drivers/serial/8250_pci.c @@ -758,6 +758,21 @@ return setup_port(priv, port, bar, offset, board->reg_shift); } +static int skip_tx_en_setup(struct serial_private *priv, + const struct pciserial_board *board, + struct uart_port *port, int idx) +{ + port->flags |= UPF_NO_TXEN_TEST; + printk(KERN_DEBUG "serial8250: skipping TxEn test for device " + "[%04x:%04x] subsystem [%04x:%04x]\n", + priv->dev->vendor, + priv->dev->device, + priv->dev->subsystem_vendor, + priv->dev->subsystem_device); + + return pci_default_setup(priv, board, port, idx); +} + /* This should be in linux/pci_ids.h */ #define PCI_VENDOR_ID_SBSMODULARIO 0x124B #define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B @@ -766,6 +781,8 @@ #define PCI_SUBDEVICE_ID_OCTPRO422 0x0208 #define PCI_SUBDEVICE_ID_POCTAL232 0x0308 #define PCI_SUBDEVICE_ID_POCTAL422 0x0408 +#define PCI_VENDOR_ID_ADVANTECH 0x13fe +#define PCI_DEVICE_ID_ADVANTECH_PCI3620 0x3620 /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 @@ -822,6 +839,27 @@ .init = pci_inteli960ni_init, .setup = pci_default_setup, }, + { + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_8257X_SOL, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .setup = skip_tx_en_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82573L_SOL, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .setup = skip_tx_en_setup, + }, + { + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82573E_SOL, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .setup = skip_tx_en_setup, + }, /* * ITE */ @@ -2132,6 +2170,10 @@ #endif static struct pci_device_id serial_pci_tbl[] = { + /* Advantech use PCI_DEVICE_ID_ADVANTECH_PCI3620 (0x3620) as 'PCI_SUBVENDOR_ID' */ + { PCI_VENDOR_ID_ADVANTECH, PCI_DEVICE_ID_ADVANTECH_PCI3620, + PCI_DEVICE_ID_ADVANTECH_PCI3620, 0x0001, 0, 0, + pbn_b2_8_921600 }, { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960, PCI_SUBVENDOR_ID_CONNECT_TECH, PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0, @@ -2271,6 +2313,9 @@ { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b2_8_115200 }, + { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_7803, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_b2_8_460800 }, { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b2_8_115200 }, @@ -2372,6 +2417,9 @@ * For now just used the hex ID 0x950a. */ { PCI_VENDOR_ID_OXSEMI, 0x950a, + PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_DUAL_SERIAL, 0, 0, + pbn_b0_2_115200 }, + { PCI_VENDOR_ID_OXSEMI, 0x950a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b0_2_1130000 }, { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954, --- linux-2.6.28.orig/drivers/serial/8250.c +++ linux-2.6.28/drivers/serial/8250.c @@ -2014,6 +2014,20 @@ serial8250_set_mctrl(&up->port, up->port.mctrl); + /* Serial over Lan (SoL) hack: + Intel 8257x Gigabit ethernet chips have a + 16550 emulation, to be used for Serial Over Lan. + Those chips take a longer time than a normal + serial device to signalize that a transmission + data was queued. Due to that, the above test generally + fails. One solution would be to delay the reading of + iir. However, this is not reliable, since the timeout + is variable. So, let's just don't test if we receive + TX irq. This way, we'll never enable UART_BUG_TXEN. + */ + if (up->port.flags & UPF_NO_TXEN_TEST) + goto dont_test_tx_en; + /* * Do a quick test to see if we receive an * interrupt when we enable the TX irq. @@ -2033,6 +2047,7 @@ up->bugs &= ~UART_BUG_TXEN; } +dont_test_tx_en: spin_unlock_irqrestore(&up->port.lock, flags); /* --- linux-2.6.28.orig/drivers/serial/Kconfig +++ linux-2.6.28/drivers/serial/Kconfig @@ -304,6 +304,31 @@ your boot loader (lilo or loadlin) about how to pass options to the kernel at boot time.) +config SERIAL_MXC + tristate "MXC Internal serial port support" + depends on ARCH_MXC + select SERIAL_CORE + help + This selects the Freescale Semiconductor MXC Internal UART driver. + If unsure, say N. + +config SERIAL_MXC_CONSOLE + bool "Support for console on a MXC/MX27/MX21 Internal serial port" + depends on SERIAL_MXC=y + select SERIAL_CORE_CONSOLE + help + Say Y here if you wish to use an MXC Internal UART as the system + console (the system console is the device which receives all kernel + messages and warnings and which allows logins in single user mode). + + Even if you say Y here, the currently visible framebuffer console + (/dev/tty0) will still be used as the system console by default, but + you can alter that using a kernel command line option such as + "console=ttymxc". (Try "man bootparam" or see the documentation of + your boot loader (lilo or loadlin) about how to pass options to the + kernel at boot time.) + + config SERIAL_AMBA_PL011 tristate "ARM AMBA PL011 serial port support" depends on ARM_AMBA --- linux-2.6.28.orig/drivers/serial/mxc_uart_early.c +++ linux-2.6.28/drivers/serial/mxc_uart_early.c @@ -0,0 +1,253 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @file drivers/serial/mxc_uart_early.c + * + * @brief Driver for the Freescale Semiconductor MXC serial ports based on + * drivers/char/8250_early.c, Copyright 2004 Hewlett-Packard Development Company, + * L.P. by Bjorn Helgaasby. + * + * Early serial console for MXC UARTS. + * + * This is for use before the serial driver has initialized, in + * particular, before the UARTs have been discovered and named. + * Instead of specifying the console device as, e.g., "ttymxc0", + * we locate the device directly by its MMIO or I/O port address. + * + * The user can specify the device directly, e.g., + * console=mxcuart,0x43f90000,115200n8 + * or platform code can call early_uart_console_init() to set + * the early UART device. + * + * After the normal serial driver starts, we try to locate the + * matching ttymxc device and start a console there. + */ + +/* + * Include Files + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct mxc_early_uart_device { + struct uart_port port; + char options[16]; /* e.g., 115200n8 */ + unsigned int baud; +}; + +int __init mxc_uart_start_console(struct uart_port *, char *); +static struct mxc_early_uart_device mxc_early_device __initdata; +static int mxc_early_uart_registered __initdata; +static struct clk *clk; + +/* + * Write out a character once the UART is ready + */ +static void __init mxcuart_console_write_char(struct uart_port *port, int ch) +{ + unsigned int status; + + do { + status = readl(port->membase + MXC_UARTUSR1); + } while ((status & MXC_UARTUSR1_TRDY) == 0); + writel(ch, port->membase + MXC_UARTUTXD); +} + +/*! + * This function is called to write the console messages through the UART port. + * + * @param co the console structure + * @param s the log message to be written to the UART + * @param count length of the message + */ +void __init early_mxcuart_console_write(struct console *co, const char *s, + u_int count) +{ + struct uart_port *port = &mxc_early_device.port; + volatile unsigned int status, oldcr1, oldcr2, oldcr3, cr2, cr3; + + /* + * First save the control registers and then disable the interrupts + */ + oldcr1 = readl(port->membase + MXC_UARTUCR1); + oldcr2 = readl(port->membase + MXC_UARTUCR2); + oldcr3 = readl(port->membase + MXC_UARTUCR3); + cr2 = + oldcr2 & ~(MXC_UARTUCR2_ATEN | MXC_UARTUCR2_RTSEN | + MXC_UARTUCR2_ESCI); + cr3 = + oldcr3 & ~(MXC_UARTUCR3_DCD | MXC_UARTUCR3_RI | + MXC_UARTUCR3_DTRDEN); + writel(MXC_UARTUCR1_UARTEN, port->membase + MXC_UARTUCR1); + writel(cr2, port->membase + MXC_UARTUCR2); + writel(cr3, port->membase + MXC_UARTUCR3); + + /* Transmit string */ + uart_console_write(port, s, count, mxcuart_console_write_char); + + /* + * Finally, wait for the transmitter to become empty + */ + do { + status = readl(port->membase + MXC_UARTUSR2); + } while (!(status & MXC_UARTUSR2_TXDC)); + + /* + * Restore the control registers + */ + writel(oldcr1, port->membase + MXC_UARTUCR1); + writel(oldcr2, port->membase + MXC_UARTUCR2); + writel(oldcr3, port->membase + MXC_UARTUCR3); +} + +static unsigned int __init probe_baud(struct uart_port *port) +{ + /* FIXME Return Default Baud Rate */ + return 115200; +} + +static int __init parse_options(struct mxc_early_uart_device *device, + char *options) +{ + struct uart_port *port = &device->port; + int mapsize = 64; + int length; + + if (!options) + return -ENODEV; + + port->uartclk = 5600000; + port->iotype = UPIO_MEM; + port->mapbase = simple_strtoul(options, &options, 0); + port->membase = ioremap(port->mapbase, mapsize); + + if ((options = strchr(options, ','))) { + options++; + device->baud = simple_strtoul(options, NULL, 0); + length = min(strcspn(options, " "), sizeof(device->options)); + strncpy(device->options, options, length); + } else { + device->baud = probe_baud(port); + snprintf(device->options, sizeof(device->options), "%u", + device->baud); + } + printk(KERN_INFO + "MXC_Early serial console at MMIO 0x%x (options '%s')\n", + port->mapbase, device->options); + return 0; +} + +static int __init mxc_early_uart_setup(struct console *console, char *options) +{ + struct mxc_early_uart_device *device = &mxc_early_device; + int err; + if (device->port.membase || device->port.iobase) + return 0; + if ((err = parse_options(device, options)) < 0) + return err; + return 0; +} + +static struct console mxc_early_uart_console __initdata = { + .name = "mxcuart", + .write = early_mxcuart_console_write, + .setup = mxc_early_uart_setup, + .flags = CON_PRINTBUFFER, + .index = -1, +}; + +static int __init mxc_early_uart_console_init(void) +{ + + if (!mxc_early_uart_registered) { + register_console(&mxc_early_uart_console); + mxc_early_uart_registered = 1; + } + + return 0; +} + +int __init mxc_early_serial_console_init(char *cmdline) +{ + char *options; + int err; + int uart_paddr; + + options = strstr(cmdline, "console=mxcuart"); + if (!options) + return -ENODEV; + + /* Extracting MXC UART Uart Port Address from cmdline */ + options = strchr(cmdline, ',') + 1; + uart_paddr = simple_strtoul(options, NULL, 16); + +#ifdef UART1_BASE_ADDR + if (uart_paddr == UART1_BASE_ADDR) + clk = clk_get(NULL, "uart_clk.0"); +#endif +#ifdef UART2_BASE_ADDR + if (uart_paddr == UART2_BASE_ADDR) + clk = clk_get(NULL, "uart_clk.1"); +#endif +#ifdef UART3_BASE_ADDR + if (uart_paddr == UART3_BASE_ADDR) + clk = clk_get(NULL, "uart_clk.2"); +#endif + if (clk == NULL) + return -1; + + /* Enable Early MXC UART Clock */ + clk_enable(clk); + + options = strchr(cmdline, ',') + 1; + if ((err = mxc_early_uart_setup(NULL, options)) < 0) + return err; + return mxc_early_uart_console_init(); +} + +int __init mxc_early_uart_console_switch(void) +{ + struct mxc_early_uart_device *device = &mxc_early_device; + struct uart_port *port = &device->port; + int mmio, line; + + if (!(mxc_early_uart_console.flags & CON_ENABLED)) + return 0; + /* Try to start the normal driver on a matching line. */ + mmio = (port->iotype == UPIO_MEM); + line = mxc_uart_start_console(port, device->options); + + if (line < 0) + printk("No ttymxc device at %s 0x%lx for console\n", + mmio ? "MMIO" : "I/O port", + mmio ? port->mapbase : (unsigned long)port->iobase); + + unregister_console(&mxc_early_uart_console); + if (mmio) + iounmap(port->membase); + + clk_disable(clk); + clk_put(clk); + + return 0; +} + +late_initcall(mxc_early_uart_console_switch); --- linux-2.6.28.orig/drivers/serial/Makefile +++ linux-2.6.28/drivers/serial/Makefile @@ -69,6 +69,8 @@ obj-$(CONFIG_SERIAL_ATMEL) += atmel_serial.o obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o obj-$(CONFIG_SERIAL_NETX) += netx-serial.o +obj-$(CONFIG_SERIAL_MXC) += mxc_uart.o +obj-$(CONFIG_SERIAL_MXC_CONSOLE) += mxc_uart_early.o obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o --- linux-2.6.28.orig/drivers/serial/mxc_uart_reg.h +++ linux-2.6.28/drivers/serial/mxc_uart_reg.h @@ -0,0 +1,128 @@ +/* + * Copyright 2004-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 __MXC_UART_REG_H__ +#define __MXC_UART_REG_H__ + +/* Address offsets of the UART registers */ +#define MXC_UARTURXD 0x000 /* Receive reg */ +#define MXC_UARTUTXD 0x040 /* Transmitter reg */ +#define MXC_UARTUCR1 0x080 /* Control reg 1 */ +#define MXC_UARTUCR2 0x084 /* Control reg 2 */ +#define MXC_UARTUCR3 0x088 /* Control reg 3 */ +#define MXC_UARTUCR4 0x08C /* Control reg 4 */ +#define MXC_UARTUFCR 0x090 /* FIFO control reg */ +#define MXC_UARTUSR1 0x094 /* Status reg 1 */ +#define MXC_UARTUSR2 0x098 /* Status reg 2 */ +#define MXC_UARTUESC 0x09C /* Escape character reg */ +#define MXC_UARTUTIM 0x0A0 /* Escape timer reg */ +#define MXC_UARTUBIR 0x0A4 /* BRM incremental reg */ +#define MXC_UARTUBMR 0x0A8 /* BRM modulator reg */ +#define MXC_UARTUBRC 0x0AC /* Baud rate count reg */ +#define MXC_UARTONEMS 0x0B0 /* One millisecond reg */ +#define MXC_UARTUTS 0x0B4 /* Test reg */ + +/* Bit definations of UCR1 */ +#define MXC_UARTUCR1_ADEN 0x8000 +#define MXC_UARTUCR1_ADBR 0x4000 +#define MXC_UARTUCR1_TRDYEN 0x2000 +#define MXC_UARTUCR1_IDEN 0x1000 +#define MXC_UARTUCR1_RRDYEN 0x0200 +#define MXC_UARTUCR1_RXDMAEN 0x0100 +#define MXC_UARTUCR1_IREN 0x0080 +#define MXC_UARTUCR1_TXMPTYEN 0x0040 +#define MXC_UARTUCR1_RTSDEN 0x0020 +#define MXC_UARTUCR1_SNDBRK 0x0010 +#define MXC_UARTUCR1_TXDMAEN 0x0008 +#define MXC_UARTUCR1_ATDMAEN 0x0004 +#define MXC_UARTUCR1_DOZE 0x0002 +#define MXC_UARTUCR1_UARTEN 0x0001 + +/* Bit definations of UCR2 */ +#define MXC_UARTUCR2_ESCI 0x8000 +#define MXC_UARTUCR2_IRTS 0x4000 +#define MXC_UARTUCR2_CTSC 0x2000 +#define MXC_UARTUCR2_CTS 0x1000 +#define MXC_UARTUCR2_PREN 0x0100 +#define MXC_UARTUCR2_PROE 0x0080 +#define MXC_UARTUCR2_STPB 0x0040 +#define MXC_UARTUCR2_WS 0x0020 +#define MXC_UARTUCR2_RTSEN 0x0010 +#define MXC_UARTUCR2_ATEN 0x0008 +#define MXC_UARTUCR2_TXEN 0x0004 +#define MXC_UARTUCR2_RXEN 0x0002 +#define MXC_UARTUCR2_SRST 0x0001 + +/* Bit definations of UCR3 */ +#define MXC_UARTUCR3_DTREN 0x2000 +#define MXC_UARTUCR3_PARERREN 0x1000 +#define MXC_UARTUCR3_FRAERREN 0x0800 +#define MXC_UARTUCR3_DSR 0x0400 +#define MXC_UARTUCR3_DCD 0x0200 +#define MXC_UARTUCR3_RI 0x0100 +#define MXC_UARTUCR3_RXDSEN 0x0040 +#define MXC_UARTUCR3_AWAKEN 0x0010 +#define MXC_UARTUCR3_DTRDEN 0x0008 +#define MXC_UARTUCR3_RXDMUXSEL 0x0004 +#define MXC_UARTUCR3_INVT 0x0002 + +/* Bit definations of UCR4 */ +#define MXC_UARTUCR4_CTSTL_OFFSET 10 +#define MXC_UARTUCR4_CTSTL_MASK (0x3F << 10) +#define MXC_UARTUCR4_INVR 0x0200 +#define MXC_UARTUCR4_ENIRI 0x0100 +#define MXC_UARTUCR4_REF16 0x0040 +#define MXC_UARTUCR4_IRSC 0x0020 +#define MXC_UARTUCR4_TCEN 0x0008 +#define MXC_UARTUCR4_OREN 0x0002 +#define MXC_UARTUCR4_DREN 0x0001 + +/* Bit definations of UFCR */ +#define MXC_UARTUFCR_RFDIV 0x0200 /* Ref freq div is set to 2 */ +#define MXC_UARTUFCR_RFDIV_OFFSET 7 +#define MXC_UARTUFCR_RFDIV_MASK (0x7 << 7) +#define MXC_UARTUFCR_TXTL_OFFSET 10 +#define MXC_UARTUFCR_DCEDTE 0x0040 + +/* Bit definations of URXD */ +#define MXC_UARTURXD_ERR 0x4000 +#define MXC_UARTURXD_OVRRUN 0x2000 +#define MXC_UARTURXD_FRMERR 0x1000 +#define MXC_UARTURXD_BRK 0x0800 +#define MXC_UARTURXD_PRERR 0x0400 + +/* Bit definations of USR1 */ +#define MXC_UARTUSR1_PARITYERR 0x8000 +#define MXC_UARTUSR1_RTSS 0x4000 +#define MXC_UARTUSR1_TRDY 0x2000 +#define MXC_UARTUSR1_RTSD 0x1000 +#define MXC_UARTUSR1_FRAMERR 0x0400 +#define MXC_UARTUSR1_RRDY 0x0200 +#define MXC_UARTUSR1_AGTIM 0x0100 +#define MXC_UARTUSR1_DTRD 0x0080 +#define MXC_UARTUSR1_AWAKE 0x0010 + +/* Bit definations of USR2 */ +#define MXC_UARTUSR2_TXFE 0x4000 +#define MXC_UARTUSR2_IDLE 0x1000 +#define MXC_UARTUSR2_RIDELT 0x0400 +#define MXC_UARTUSR2_RIIN 0x0200 +#define MXC_UARTUSR2_DCDDELT 0x0040 +#define MXC_UARTUSR2_DCDIN 0x0020 +#define MXC_UARTUSR2_TXDC 0x0008 +#define MXC_UARTUSR2_ORE 0x0002 +#define MXC_UARTUSR2_RDR 0x0001 + +/* Bit definations of UTS */ +#define MXC_UARTUTS_LOOP 0x1000 + +#endif /* __MXC_UART_REG_H__ */ --- linux-2.6.28.orig/drivers/serial/mxc_uart.c +++ linux-2.6.28/drivers/serial/mxc_uart.c @@ -0,0 +1,1948 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @file drivers/serial/mxc_uart.c + * + * @brief Driver for the Freescale Semiconductor MXC serial ports based on + * drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. + * + * @ingroup UART + */ + +/* + * Include Files + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_SERIAL_MXC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#define SUPPORT_SYSRQ +#endif +#define SERIAL_MXC_MAJOR 207 +#define SERIAL_MXC_MINOR 16 +#define MXC_ISR_PASS_LIMIT 256 +#define UART_CREAD_BIT 256 + +/* IRDA minimum pulse duration in micro seconds */ +#define MIN_PULSE_DUR 2 +/* + * Transmit DMA buffer size is set to 1024 bytes, this is limited + * by UART_XMIT_SIZE. + */ +#define TXDMA_BUFF_SIZE UART_XMIT_SIZE +/* + * Receive DMA sub-buffer size + */ +#define RXDMA_BUFF_SIZE 128 + +/*! + * This structure is used to store the information for DMA data transfer. + */ +typedef struct { + /*! + * Holds the read channel number. + */ + int rd_channel; + /*! + * Holds the write channel number. + */ + int wr_channel; + /*! + * UART Transmit Event ID + */ + int tx_event_id; + /*! + * UART Receive Event ID + */ + int rx_event_id; + /*! + * DMA Transmit tasklet + */ + struct tasklet_struct dma_tx_tasklet; + /*! + * Flag indicates if the channel is in use + */ + int dma_txchnl_inuse; +} dma_info; + +/*! + * This is used to indicate if we want echo cancellation in the Irda mode. + */ +static int echo_cancel; +extern void gpio_uart_active(int port, int no_irda); +extern void gpio_uart_inactive(int port, int no_irda); +extern void config_uartdma_event(int port); + +static uart_mxc_port *mxc_ports[MXC_UART_NR]; + +/*! + * This array holds the DMA channel information for each MXC UART + */ +static dma_info dma_list[MXC_UART_NR]; + +/*! + * This function is called by the core driver to stop UART transmission. + * This might be due to the TTY layer indicating that the user wants to stop + * transmission. + * + * @param port the port structure for the UART passed in by the core + * driver + */ +static void mxcuart_stop_tx(struct uart_port *port) +{ + uart_mxc_port *umxc = (uart_mxc_port *) port; + volatile unsigned int cr1; + + cr1 = readl(port->membase + MXC_UARTUCR1); + /* Disable Transmitter rdy interrupt */ + if (umxc->dma_enabled == 1) { + cr1 &= ~MXC_UARTUCR1_TXDMAEN; + } else { + cr1 &= ~MXC_UARTUCR1_TRDYEN; + } + writel(cr1, port->membase + MXC_UARTUCR1); +} + +/*! + * DMA Transmit tasklet method is scheduled on completion of a DMA transmit + * to send out any more data that is available in the UART xmit buffer. + * + * @param arg driver private data + */ +static void dma_tx_do_tasklet(unsigned long arg) +{ + uart_mxc_port *umxc = (uart_mxc_port *) arg; + struct circ_buf *xmit = &umxc->port.info->xmit; + mxc_dma_requestbuf_t writechnl_request; + int tx_num; + unsigned long flags; + + spin_lock_irqsave(&umxc->port.lock, flags); + tx_num = uart_circ_chars_pending(xmit); + if (tx_num > 0) { + if (xmit->tail > xmit->head) { + memcpy(umxc->tx_buf, xmit->buf + xmit->tail, + UART_XMIT_SIZE - xmit->tail); + memcpy(umxc->tx_buf + (UART_XMIT_SIZE - xmit->tail), + xmit->buf, xmit->head); + } else { + memcpy(umxc->tx_buf, xmit->buf + xmit->tail, tx_num); + } + umxc->tx_handle = dma_map_single(umxc->port.dev, umxc->tx_buf, + TXDMA_BUFF_SIZE, + DMA_TO_DEVICE); + + writechnl_request.dst_addr = umxc->port.mapbase + MXC_UARTUTXD; + writechnl_request.src_addr = umxc->tx_handle; + writechnl_request.num_of_bytes = tx_num; + + if ((mxc_dma_config(dma_list[umxc->port.line].wr_channel, + &writechnl_request, 1, + MXC_DMA_MODE_WRITE)) == 0) { + mxc_dma_enable(dma_list[umxc->port.line].wr_channel); + } + } else { + /* No more data available in the xmit queue, clear the flag */ + dma_list[umxc->port.line].dma_txchnl_inuse = 0; + } + spin_unlock_irqrestore(&umxc->port.lock, flags); +} + +/*! + * DMA Write callback is called by the SDMA controller after it has sent out all + * the data from the user buffer. This function updates the xmit buffer pointers. + * + * @param arg driver private data + * @param error any DMA error + * @param count amount of data that was transferred + */ +static void mxcuart_dma_writecallback(void *arg, int error, unsigned int count) +{ + uart_mxc_port *umxc = arg; + struct circ_buf *xmit = &umxc->port.info->xmit; + int tx_num; + + if (error != MXC_DMA_TRANSFER_ERROR) { + tx_num = count; + umxc->port.icount.tx += tx_num; + xmit->tail = (xmit->tail + tx_num) & (UART_XMIT_SIZE - 1); + } + + dma_unmap_single(umxc->port.dev, umxc->tx_handle, TXDMA_BUFF_SIZE, + DMA_TO_DEVICE); + tx_num = uart_circ_chars_pending(xmit); + /* Schedule a tasklet to send out the pending characters */ + if (tx_num > 0) { + tasklet_schedule(&dma_list[umxc->port.line].dma_tx_tasklet); + } else { + dma_list[umxc->port.line].dma_txchnl_inuse = 0; + } + if (tx_num < WAKEUP_CHARS) { + uart_write_wakeup(&umxc->port); + } +} + +/*! + * This function is called by the core driver to start transmitting characters. + * This function enables the transmit interrupts. + * + * @param port the port structure for the UART passed in by the core + * driver + */ +static void mxcuart_start_tx(struct uart_port *port) +{ + uart_mxc_port *umxc = (uart_mxc_port *) port; + struct circ_buf *xmit = &umxc->port.info->xmit; + volatile unsigned int cr1; + mxc_dma_requestbuf_t writechnl_request; + int tx_num; + + cr1 = readl(port->membase + MXC_UARTUCR1); + /* Enable Transmitter rdy interrupt */ + if (umxc->dma_enabled == 1) { + /* + * If the channel is in use then return immediately and use + * the dma_tx tasklet to transfer queued data when current DMA + * transfer is complete + */ + if (dma_list[umxc->port.line].dma_txchnl_inuse == 1) { + return; + } + tx_num = uart_circ_chars_pending(xmit); + if (tx_num > 0) { + dma_list[umxc->port.line].dma_txchnl_inuse = 1; + if (xmit->tail > xmit->head) { + memcpy(umxc->tx_buf, xmit->buf + xmit->tail, + UART_XMIT_SIZE - xmit->tail); + memcpy(umxc->tx_buf + + (UART_XMIT_SIZE - xmit->tail), xmit->buf, + xmit->head); + } else { + memcpy(umxc->tx_buf, xmit->buf + xmit->tail, + tx_num); + } + umxc->tx_handle = + dma_map_single(umxc->port.dev, umxc->tx_buf, + TXDMA_BUFF_SIZE, DMA_TO_DEVICE); + + writechnl_request.dst_addr = + umxc->port.mapbase + MXC_UARTUTXD; + writechnl_request.src_addr = umxc->tx_handle; + writechnl_request.num_of_bytes = tx_num; + if ((mxc_dma_config + (dma_list[umxc->port.line].wr_channel, + &writechnl_request, 1, + MXC_DMA_MODE_WRITE)) == 0) { + mxc_dma_enable(dma_list[umxc->port.line]. + wr_channel); + } + cr1 |= MXC_UARTUCR1_TXDMAEN; + } + } else { + cr1 |= MXC_UARTUCR1_TRDYEN; + } + writel(cr1, port->membase + MXC_UARTUCR1); +} + +/*! + * This function is called by the core driver to stop receiving characters; the + * port is in the process of being closed. + * + * @param port the port structure for the UART passed in by the core driver + */ +static void mxcuart_stop_rx(struct uart_port *port) +{ + uart_mxc_port *umxc = (uart_mxc_port *) port; + volatile unsigned int cr1; + + cr1 = readl(port->membase + MXC_UARTUCR1); + if (umxc->dma_enabled == 1) { + cr1 &= ~MXC_UARTUCR1_RXDMAEN; + } else { + cr1 &= ~MXC_UARTUCR1_RRDYEN; + } + writel(cr1, port->membase + MXC_UARTUCR1); +} + +/*! + * This function is called by the core driver to enable the modem status + * interrupts. If the port is configured to be in DTE mode then it enables the + * DCDDELT and RIDELT interrupts in addition to the DTRDEN interrupt. The RTSDEN + * interrupt is enabled only for interrupt-driven hardware flow control. + * + * @param port the port structure for the UART passed in by the core driver + */ +static void mxcuart_enable_ms(struct uart_port *port) +{ + uart_mxc_port *umxc = (uart_mxc_port *) port; + volatile unsigned int cr1, cr3; + + /* + * RTS interrupt is enabled only if we are using interrupt-driven + * software controlled hardware flow control + */ + if (umxc->hardware_flow == 0) { + cr1 = readl(umxc->port.membase + MXC_UARTUCR1); + cr1 |= MXC_UARTUCR1_RTSDEN; + writel(cr1, umxc->port.membase + MXC_UARTUCR1); + } + cr3 = readl(umxc->port.membase + MXC_UARTUCR3); + cr3 |= MXC_UARTUCR3_DTRDEN; + if (umxc->mode == MODE_DTE) { + cr3 |= MXC_UARTUCR3_DCD | MXC_UARTUCR3_RI; + } + writel(cr3, umxc->port.membase + MXC_UARTUCR3); +} + +/*! + * This function is called from the interrupt service routine if the status bit + * indicates that the receive fifo data level is above the set threshold. The + * function reads the character and queues them into the TTY layers read + * buffer. The function also looks for break characters, parity and framing + * errors in the received character and sets the appropriate flag in the TTY + * receive buffer. + * + * @param umxc the MXC UART port structure, this includes the \b uart_port + * structure and other members that are specific to MXC UARTs + */ +static void mxcuart_rx_chars(uart_mxc_port * umxc) +{ + volatile unsigned int ch, sr2; + unsigned int status, flag, max_count = 256; + + sr2 = readl(umxc->port.membase + MXC_UARTUSR2); + while (((sr2 & MXC_UARTUSR2_RDR) == 1) && (max_count-- > 0)) { + ch = readl(umxc->port.membase + MXC_UARTURXD); + + flag = TTY_NORMAL; + status = ch | UART_CREAD_BIT; + ch &= 0xFF; /* Clear the upper bits */ + umxc->port.icount.rx++; + + /* + * Check to see if there is an error in the received + * character. Perform the appropriate actions based on the + * error bit that was set. + */ + if (status & MXC_UARTURXD_ERR) { + if (status & MXC_UARTURXD_BRK) { + /* + * Clear the frame and parity error bits + * as these always get set on receiving a + * break character + */ + status &= ~(MXC_UARTURXD_FRMERR | + MXC_UARTURXD_PRERR); + umxc->port.icount.brk++; + if (uart_handle_break(&umxc->port)) { + goto ignore_char; + } + } else if (status & MXC_UARTURXD_FRMERR) { + umxc->port.icount.frame++; + } else if (status & MXC_UARTURXD_PRERR) { + umxc->port.icount.parity++; + } + if (status & MXC_UARTURXD_OVRRUN) { + umxc->port.icount.overrun++; + } + + status &= umxc->port.read_status_mask; + + if (status & MXC_UARTURXD_BRK) { + flag = TTY_BREAK; + } else if (status & MXC_UARTURXD_FRMERR) { + flag = TTY_FRAME; + } else if (status & MXC_UARTURXD_PRERR) { + flag = TTY_PARITY; + } + } + + if (uart_handle_sysrq_char(&umxc->port, ch)) { + goto ignore_char; + } + + uart_insert_char(&umxc->port, status, MXC_UARTURXD_OVRRUN, ch, + flag); + ignore_char: + sr2 = readl(umxc->port.membase + MXC_UARTUSR2); + } + tty_flip_buffer_push(umxc->port.info->port.tty); +} + +/*! + * This function is called from the interrupt service routine if the status bit + * indicates that the transmit fifo is emptied below its set threshold and + * requires data. The function pulls characters from the TTY layers write + * buffer and writes it out to the UART transmit fifo. + * + * @param umxc the MXC UART port structure, this includes the \b uart_port + * structure and other members that are specific to MXC UARTs + */ +static void mxcuart_tx_chars(uart_mxc_port * umxc) +{ + struct circ_buf *xmit = &umxc->port.info->xmit; + int count; + + /* + * Transmit the XON/XOFF character if required + */ + if (umxc->port.x_char) { + writel(umxc->port.x_char, umxc->port.membase + MXC_UARTUTXD); + umxc->port.icount.tx++; + umxc->port.x_char = 0; + return; + } + + /* + * Check to see if there is any data to be sent and that the + * port has not been currently stopped by anything. + */ + if (uart_circ_empty(xmit) || uart_tx_stopped(&umxc->port)) { + mxcuart_stop_tx(&umxc->port); + return; + } + + count = umxc->port.fifosize - umxc->tx_threshold; + do { + writel(xmit->buf[xmit->tail], + umxc->port.membase + MXC_UARTUTXD); + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + umxc->port.icount.tx++; + if (uart_circ_empty(xmit)) { + break; + } + } while (--count > 0); + + /* + * Check to see if we have flushed enough characters to ask for more + * to be sent to us, if so, we notify the user space that we can + * accept more data + */ + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) { + uart_write_wakeup(&umxc->port); + } + + if (uart_circ_empty(xmit)) { + mxcuart_stop_tx(&umxc->port); + } +} + +/*! + * This function is called from the interrupt service routine if there is a + * change in the modem signals. This function handles these signal changes and + * also clears the appropriate status register bits. + * + * @param umxc the MXC UART port structure, this includes the \b uart_port + * structure and other members that are specific to MXC UARTs + * @param sr1 contents of status register 1 + * @param sr2 contents of status register 2 + */ +static void mxcuart_modem_status(uart_mxc_port * umxc, unsigned int sr1, + unsigned int sr2) +{ + if (umxc->mode == MODE_DTE) { + if (sr2 & MXC_UARTUSR2_DCDDELT) { + uart_handle_dcd_change(&umxc->port, + !(sr2 & MXC_UARTUSR2_DCDIN)); + } + if (sr2 & MXC_UARTUSR2_RIDELT) { + umxc->port.icount.rng++; + } + } + if (sr1 & MXC_UARTUSR1_DTRD) { + umxc->port.icount.dsr++; + } + if ((umxc->hardware_flow == 0) && (sr1 & MXC_UARTUSR1_RTSD)) { + uart_handle_cts_change(&umxc->port, sr1 & MXC_UARTUSR1_RTSS); + } + + wake_up_interruptible(&umxc->port.info->delta_msr_wait); +} + +/*! + * Interrupt service routine registered to handle the muxed ANDed interrupts. + * This routine is registered only in the case where the UART interrupts are + * muxed. + * + * @param irq the interrupt number + * @param dev_id driver private data + * + * @return The function returns \b IRQ_RETVAL(1) if interrupt was handled, + * returns \b IRQ_RETVAL(0) if the interrupt was not handled. + * \b IRQ_RETVAL is defined in \b include/linux/interrupt.h. + */ +static irqreturn_t mxcuart_int(int irq, void *dev_id) +{ + uart_mxc_port *umxc = dev_id; + volatile unsigned int sr1, sr2, cr1, cr; + unsigned int pass_counter = MXC_ISR_PASS_LIMIT; + unsigned int term_cond = 0; + int handled = 0; + + sr1 = readl(umxc->port.membase + MXC_UARTUSR1); + sr2 = readl(umxc->port.membase + MXC_UARTUSR2); + cr1 = readl(umxc->port.membase + MXC_UARTUCR1); + + do { + /* Clear the bits that triggered the interrupt */ + writel(sr1, umxc->port.membase + MXC_UARTUSR1); + writel(sr2, umxc->port.membase + MXC_UARTUSR2); + /* + * Read if there is data available + */ + if (sr2 & MXC_UARTUSR2_RDR) { + mxcuart_rx_chars(umxc); + } + + if ((sr1 & (MXC_UARTUSR1_RTSD | MXC_UARTUSR1_DTRD)) || + (sr2 & (MXC_UARTUSR2_DCDDELT | MXC_UARTUSR2_RIDELT))) { + mxcuart_modem_status(umxc, sr1, sr2); + } + + /* + * Send data if there is data to be sent + */ + if ((cr1 & MXC_UARTUCR1_TRDYEN) && (sr1 & MXC_UARTUSR1_TRDY)) { + /* Echo cancellation for IRDA Transmit chars */ + if (umxc->ir_mode == IRDA && echo_cancel) { + /* Disable the receiver */ + cr = readl(umxc->port.membase + MXC_UARTUCR2); + cr &= ~MXC_UARTUCR2_RXEN; + writel(cr, umxc->port.membase + MXC_UARTUCR2); + /* Enable Transmit complete intr to reenable RX */ + cr = readl(umxc->port.membase + MXC_UARTUCR4); + cr |= MXC_UARTUCR4_TCEN; + writel(cr, umxc->port.membase + MXC_UARTUCR4); + } + mxcuart_tx_chars(umxc); + } + + if (pass_counter-- == 0) { + break; + } + + sr1 = readl(umxc->port.membase + MXC_UARTUSR1); + sr2 = readl(umxc->port.membase + MXC_UARTUSR2); + + /* Is the transmit complete to reenable the receiver? */ + if (umxc->ir_mode == IRDA && echo_cancel) { + if (sr2 & MXC_UARTUSR2_TXDC) { + cr = readl(umxc->port.membase + MXC_UARTUCR2); + cr |= MXC_UARTUCR2_RXEN; + writel(cr, umxc->port.membase + MXC_UARTUCR2); + /* Disable the Transmit complete interrupt bit */ + cr = readl(umxc->port.membase + MXC_UARTUCR4); + cr &= ~MXC_UARTUCR4_TCEN; + writel(cr, umxc->port.membase + MXC_UARTUCR4); + } + } + + /* + * If there is no data to send or receive and if there is no + * change in the modem status signals then quit the routine + */ + term_cond = sr1 & (MXC_UARTUSR1_RTSD | MXC_UARTUSR1_DTRD); + term_cond |= sr2 & (MXC_UARTUSR2_RDR | MXC_UARTUSR2_DCDDELT); + term_cond |= !(sr2 & MXC_UARTUSR2_TXFE); + } while (term_cond > 0); + + handled = 1; + return IRQ_RETVAL(handled); +} + +/*! + * Interrupt service routine registered to handle the transmit interrupts. This + * routine is registered only in the case where the UART interrupts are not + * muxed. + * + * @param irq the interrupt number + * @param dev_id driver private data + * + * @return The function returns \b IRQ_RETVAL(1) if interrupt was handled, + * returns \b IRQ_RETVAL(0) if the interrupt was not handled. + * \b IRQ_RETVAL is defined in include/linux/interrupt.h. + */ +static irqreturn_t mxcuart_tx_int(int irq, void *dev_id) +{ + uart_mxc_port *umxc = dev_id; + int handled = 0; + volatile unsigned int sr2, cr; + + /* Echo cancellation for IRDA Transmit chars */ + if (umxc->ir_mode == IRDA && echo_cancel) { + /* Disable the receiver */ + cr = readl(umxc->port.membase + MXC_UARTUCR2); + cr &= ~MXC_UARTUCR2_RXEN; + writel(cr, umxc->port.membase + MXC_UARTUCR2); + /* Enable Transmit complete to reenable receiver */ + cr = readl(umxc->port.membase + MXC_UARTUCR4); + cr |= MXC_UARTUCR4_TCEN; + writel(cr, umxc->port.membase + MXC_UARTUCR4); + } + + mxcuart_tx_chars(umxc); + + /* Is the transmit complete to reenable the receiver? */ + if (umxc->ir_mode == IRDA && echo_cancel) { + sr2 = readl(umxc->port.membase + MXC_UARTUSR2); + if (sr2 & MXC_UARTUSR2_TXDC) { + cr = readl(umxc->port.membase + MXC_UARTUCR2); + cr |= MXC_UARTUCR2_RXEN; + writel(cr, umxc->port.membase + MXC_UARTUCR2); + /* Disable the Transmit complete interrupt bit */ + cr = readl(umxc->port.membase + MXC_UARTUCR4); + cr &= ~MXC_UARTUCR4_TCEN; + writel(cr, umxc->port.membase + MXC_UARTUCR4); + } + } + + handled = 1; + + return IRQ_RETVAL(handled); +} + +/*! + * Interrupt service routine registered to handle the receive interrupts. This + * routine is registered only in the case where the UART interrupts are not + * muxed. + * + * @param irq the interrupt number + * @param dev_id driver private data + * + * @return The function returns \b IRQ_RETVAL(1) if interrupt was handled, + * returns \b IRQ_RETVAL(0) if the interrupt was not handled. + * \b IRQ_RETVAL is defined in include/linux/interrupt.h. + */ +static irqreturn_t mxcuart_rx_int(int irq, void *dev_id) +{ + uart_mxc_port *umxc = dev_id; + int handled = 0; + + /* Clear the aging timer bit */ + writel(MXC_UARTUSR1_AGTIM, umxc->port.membase + MXC_UARTUSR1); + mxcuart_rx_chars(umxc); + handled = 1; + + return IRQ_RETVAL(handled); +} + +/*! + * Interrupt service routine registered to handle the master interrupts. This + * routine is registered only in the case where the UART interrupts are not + * muxed. + * + * @param irq the interrupt number + * @param dev_id driver private data + * + * @return The function returns \b IRQ_RETVAL(1) if interrupt was handled, + * returns \b IRQ_RETVAL(0) if the interrupt was not handled. + * \b IRQ_RETVAL is defined in include/linux/interrupt.h. + */ +static irqreturn_t mxcuart_mint_int(int irq, void *dev_id) +{ + uart_mxc_port *umxc = dev_id; + int handled = 0; + volatile unsigned int sr1, sr2; + + sr1 = readl(umxc->port.membase + MXC_UARTUSR1); + sr2 = readl(umxc->port.membase + MXC_UARTUSR2); + /* Clear the modem status interrupt bits */ + writel(MXC_UARTUSR1_RTSD | MXC_UARTUSR1_DTRD, + umxc->port.membase + MXC_UARTUSR1); + writel(MXC_UARTUSR2_DCDDELT | MXC_UARTUSR2_RIDELT, + umxc->port.membase + MXC_UARTUSR2); + mxcuart_modem_status(umxc, sr1, sr2); + handled = 1; + + return IRQ_RETVAL(handled); +} + +/*! + * This function is called by the core driver to test whether the transmitter + * fifo and shift register for the UART port are empty. + * + * @param port the port structure for the UART passed in by the core driver + * + * @return The function returns TIOCSER_TEMT if it is empty, else returns 0. + */ +static unsigned int mxcuart_tx_empty(struct uart_port *port) +{ + volatile unsigned int sr2; + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); + sr2 = readl(port->membase + MXC_UARTUSR2); + spin_unlock_irqrestore(&port->lock, flags); + + return sr2 & MXC_UARTUSR2_TXDC ? TIOCSER_TEMT : 0; +} + +/*! + * This function is called by the core driver to get the current status of the + * modem input signals. The state of the output signals is not collected. + * + * @param port the port structure for the UART passed in by the core driver + * + * @return The function returns an integer that contains the ORed value of the + * status of all the modem input signals or error. + */ +static unsigned int mxcuart_get_mctrl(struct uart_port *port) +{ + uart_mxc_port *umxc = (uart_mxc_port *) port; + unsigned int result = 0; + volatile unsigned int sr1, sr2; + + sr1 = readl(umxc->port.membase + MXC_UARTUSR1); + sr2 = readl(umxc->port.membase + MXC_UARTUSR2); + + if (sr1 & MXC_UARTUSR1_RTSS) { + result |= TIOCM_CTS; + } + if (umxc->mode == MODE_DTE) { + if (!(sr2 & MXC_UARTUSR2_DCDIN)) { + result |= TIOCM_CAR; + } + if (!(sr2 & MXC_UARTUSR2_RIIN)) { + result |= TIOCM_RI; + } + } + return result; +} + +/*! + * This function is called by the core driver to set the state of the modem + * control lines. + * + * @param port the port structure for the UART passed in by the core driver + * @param mctrl the state that the modem control lines should be changed to + */ +static void mxcuart_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ + uart_mxc_port *umxc = (uart_mxc_port *) port; + volatile unsigned int cr2 = 0, cr3 = 0, uts = 0; + + cr2 = readl(port->membase + MXC_UARTUCR2); + cr3 = readl(port->membase + MXC_UARTUCR3); + uts = readl(port->membase + MXC_UARTUTS); + + if (mctrl & TIOCM_RTS) { + /* + * Return to hardware-driven hardware flow control if the + * option is enabled + */ + if (umxc->hardware_flow == 1) { + cr2 |= MXC_UARTUCR2_CTSC; + } else { + cr2 |= MXC_UARTUCR2_CTS; + cr2 &= ~MXC_UARTUCR2_CTSC; + } + } else { + cr2 &= ~(MXC_UARTUCR2_CTS | MXC_UARTUCR2_CTSC); + } + writel(cr2, port->membase + MXC_UARTUCR2); + + if (mctrl & TIOCM_DTR) { + cr3 |= MXC_UARTUCR3_DSR; + } else { + cr3 &= ~MXC_UARTUCR3_DSR; + } + writel(cr3, port->membase + MXC_UARTUCR3); + + if (mctrl & TIOCM_LOOP) { + if (umxc->ir_mode == IRDA) { + echo_cancel = 0; + } else { + uts |= MXC_UARTUTS_LOOP; + } + } else { + if (umxc->ir_mode == IRDA) { + echo_cancel = 1; + } else { + uts &= ~MXC_UARTUTS_LOOP; + } + } + writel(uts, port->membase + MXC_UARTUTS); +} + +/*! + * This function is called by the core driver to control the transmission of + * the break signal. If break_state is non-zero, the break signal is + * transmitted, the signal is terminated when another call is made with + * break_state set to 0. + * + * @param port the port structure for the UART passed in by the core + * driver + * @param break_state the requested state of the break signal + */ +static void mxcuart_break_ctl(struct uart_port *port, int break_state) +{ + volatile unsigned int cr1; + unsigned long flags; + + spin_lock_irqsave(&port->lock, flags); + cr1 = readl(port->membase + MXC_UARTUCR1); + if (break_state == -1) { + cr1 |= MXC_UARTUCR1_SNDBRK; + } else { + cr1 &= ~MXC_UARTUCR1_SNDBRK; + } + writel(cr1, port->membase + MXC_UARTUCR1); + spin_unlock_irqrestore(&port->lock, flags); +} + +/*! + * The read DMA callback, this method is called when the DMA buffer has received its + * data. This functions copies the data to the tty buffer and updates the tty buffer + * pointers. It also queues the DMA buffer back to the DMA system. + * + * @param arg driver private data + * @param error any DMA error + * @param cnt amount of data that was transferred + */ +static void mxcuart_dmaread_callback(void *arg, int error, unsigned int cnt) +{ + uart_mxc_port *umxc = arg; + struct tty_struct *tty = umxc->port.info->port.tty; + int buff_id, flip_cnt, num_bufs; + mxc_dma_requestbuf_t readchnl_request; + mxc_uart_rxdmamap *rx_buf_elem = NULL; + unsigned int sr1, sr2; + char flag; + + num_bufs = umxc->dma_rxbuf_size / RXDMA_BUFF_SIZE; + /* Clear the aging timer bit */ + writel(MXC_UARTUSR1_AGTIM, umxc->port.membase + MXC_UARTUSR1); + + buff_id = umxc->dma_rxbuf_id; + flag = TTY_NORMAL; + + if ((umxc->dma_rxbuf_id += 1) >= num_bufs) { + umxc->dma_rxbuf_id = 0; + } + + rx_buf_elem = (mxc_uart_rxdmamap *) (umxc->rx_dmamap + buff_id); + + if (error == MXC_DMA_TRANSFER_ERROR) { + + sr1 = __raw_readl(umxc->port.membase + MXC_UARTUSR1); + sr2 = __raw_readl(umxc->port.membase + MXC_UARTUSR2); + + if (sr2 & MXC_UARTUSR2_BRCD) { + umxc->port.icount.brk++; + if (uart_handle_break(&umxc->port)) { + goto drop_data; + } + } else if (sr1 & MXC_UARTUSR1_PARITYERR) { + umxc->port.icount.parity++; + } else if (sr1 & MXC_UARTUSR1_FRAMERR) { + umxc->port.icount.frame++; + } else if (sr2 & MXC_UARTUSR2_ORE) { + umxc->port.icount.overrun++; + + } + + if (umxc->port.read_status_mask & MXC_UARTURXD_BRK) { + if (sr2 & MXC_UARTUSR2_BRCD) + flag = TTY_BREAK; + } else if (umxc->port.read_status_mask & MXC_UARTURXD_PRERR) { + if (sr1 & MXC_UARTUSR1_PARITYERR) + flag = TTY_PARITY; + } else if (umxc->port.read_status_mask & MXC_UARTURXD_FRMERR) { + if (sr1 & MXC_UARTUSR1_FRAMERR) + flag = TTY_FRAME; + } else if (umxc->port.read_status_mask & MXC_UARTURXD_OVRRUN) { + if (sr2 & MXC_UARTUSR2_ORE) + flag = TTY_OVERRUN; + } +/* By default clearing all error bits in status reg */ + __raw_writel((MXC_UARTUSR2_BRCD | MXC_UARTUSR2_ORE), + umxc->port.membase + MXC_UARTUSR2); + __raw_writel((MXC_UARTUSR1_PARITYERR | MXC_UARTUSR1_FRAMERR), + umxc->port.membase + MXC_UARTUSR1); + } + + flip_cnt = tty_buffer_request_room(tty, cnt); + + /* Check for space availability in the TTY Flip buffer */ + if (flip_cnt <= 0) { + goto drop_data; + } + umxc->port.icount.rx += flip_cnt; + + tty_insert_flip_string(tty, rx_buf_elem->rx_buf, flip_cnt); + + if (flag != TTY_NORMAL) { + tty_insert_flip_char(tty, 0, flag); + } + + tty_flip_buffer_push(tty); + umxc->port.info->port.tty->real_raw = 1; + + drop_data: + readchnl_request.src_addr = umxc->port.mapbase; + readchnl_request.dst_addr = rx_buf_elem->rx_handle; + readchnl_request.num_of_bytes = RXDMA_BUFF_SIZE; + mxc_dma_config(dma_list[umxc->port.line].rd_channel, &readchnl_request, + 1, MXC_DMA_MODE_READ); + mxc_dma_enable(dma_list[umxc->port.line].rd_channel); +} + +/*! + * Allocates DMA read and write channels, creates DMA read and write buffers and + * sets the channel specific parameters. + * + * @param d_info the structure that holds all the DMA information for a + * particular MXC UART + * @param umxc the MXC UART port structure, this includes the \b uart_port + * structure and other members that are specific to MXC UARTs + * + * @return The function returns 0 on success and a non-zero value on failure. + */ +static int mxcuart_initdma(dma_info * d_info, uart_mxc_port * umxc) +{ + int ret = 0, rxbufs, i, j; + mxc_dma_requestbuf_t *readchnl_reqelem; + mxc_uart_rxdmamap *rx_buf_elem; + + /* Request for the read and write channels */ + d_info->rd_channel = mxc_dma_request(umxc->dma_rx_id, "MXC UART Read"); + if (d_info->rd_channel < 0) { + printk(KERN_ERR "MXC UART: Cannot allocate DMA read channel\n"); + return -1; + } else { + d_info->wr_channel = + mxc_dma_request(umxc->dma_tx_id, "MXC UART Write"); + if (d_info->wr_channel < 0) { + mxc_dma_free(d_info->rd_channel); + printk(KERN_ERR + "MXC UART: Cannot allocate DMA write channel\n"); + return -1; + } + } + + /* Allocate the DMA Transmit Buffer */ + if ((umxc->tx_buf = kmalloc(TXDMA_BUFF_SIZE, GFP_KERNEL)) == NULL) { + ret = -1; + goto err_dma_tx_buff; + } + rxbufs = umxc->dma_rxbuf_size / RXDMA_BUFF_SIZE; + /* Allocate the DMA Virtual Receive Buffer */ + if ((umxc->rx_dmamap = kmalloc(rxbufs * sizeof(mxc_uart_rxdmamap), + GFP_KERNEL)) == NULL) { + ret = -1; + goto err_dma_rx_buff; + } + + /* Allocate the DMA Receive Request structures */ + if ((readchnl_reqelem = + kmalloc(rxbufs * sizeof(mxc_dma_requestbuf_t), + GFP_KERNEL)) == NULL) { + ret = -1; + goto err_request; + } + + for (i = 0; i < rxbufs; i++) { + rx_buf_elem = (mxc_uart_rxdmamap *) (umxc->rx_dmamap + i); + rx_buf_elem->rx_buf = + dma_alloc_coherent(NULL, RXDMA_BUFF_SIZE, + &rx_buf_elem->rx_handle, GFP_DMA); + if (rx_buf_elem->rx_buf == NULL) { + for (j = 0; j < i; j++) { + rx_buf_elem = + (mxc_uart_rxdmamap *) (umxc->rx_dmamap + j); + dma_free_coherent(NULL, RXDMA_BUFF_SIZE, + rx_buf_elem->rx_buf, + rx_buf_elem->rx_handle); + } + ret = -1; + goto cleanup; + } + } + + umxc->dma_rxbuf_id = 0; + /* Setup the DMA read request structures */ + for (i = 0; i < rxbufs; i++) { + rx_buf_elem = (mxc_uart_rxdmamap *) (umxc->rx_dmamap + i); + (readchnl_reqelem + i)->src_addr = umxc->port.mapbase; + (readchnl_reqelem + i)->dst_addr = rx_buf_elem->rx_handle; + (readchnl_reqelem + i)->num_of_bytes = RXDMA_BUFF_SIZE; + } + mxc_dma_config(d_info->rd_channel, readchnl_reqelem, rxbufs, + MXC_DMA_MODE_READ); + mxc_dma_callback_set(d_info->rd_channel, mxcuart_dmaread_callback, + umxc); + mxc_dma_callback_set(d_info->wr_channel, mxcuart_dma_writecallback, + umxc); + + /* Start the read channel */ + mxc_dma_enable(d_info->rd_channel); + kfree(readchnl_reqelem); + tasklet_init(&d_info->dma_tx_tasklet, dma_tx_do_tasklet, + (unsigned long)umxc); + d_info->dma_txchnl_inuse = 0; + return ret; + cleanup: + kfree(readchnl_reqelem); + err_request: + kfree(umxc->rx_dmamap); + err_dma_rx_buff: + kfree(umxc->tx_buf); + err_dma_tx_buff: + mxc_dma_free(d_info->rd_channel); + mxc_dma_free(d_info->wr_channel); + + return ret; +} + +/*! + * Stops DMA and frees the DMA resources + * + * @param d_info the structure that holds all the DMA information for a + * particular MXC UART + * @param umxc the MXC UART port structure, this includes the \b uart_port + * structure and other members that are specific to MXC UARTs + */ +static void mxcuart_freedma(dma_info * d_info, uart_mxc_port * umxc) +{ + int i, rxbufs; + mxc_uart_rxdmamap *rx_buf_elem; + + rxbufs = umxc->dma_rxbuf_size / RXDMA_BUFF_SIZE; + + for (i = 0; i < rxbufs; i++) { + rx_buf_elem = (mxc_uart_rxdmamap *) (umxc->rx_dmamap + i); + dma_free_coherent(NULL, RXDMA_BUFF_SIZE, + rx_buf_elem->rx_buf, rx_buf_elem->rx_handle); + } + kfree(umxc->rx_dmamap); + kfree(umxc->tx_buf); + mxc_dma_free(d_info->rd_channel); + mxc_dma_free(d_info->wr_channel); +} + +/*! + * This function is called to free the interrupts. + * + * @param umxc the MXC UART port structure, this includes the \b uart_port + * structure and other members that are specific to MXC UARTs + */ +static void mxcuart_free_interrupts(uart_mxc_port * umxc) +{ + free_irq(umxc->port.irq, umxc); + if (umxc->ints_muxed == 0) { + free_irq(umxc->irqs[0], umxc); + free_irq(umxc->irqs[1], umxc); + } +} + +/*! + * Calculate and set the UART port clock value + * + * @param umxc the MXC UART port structure, this includes the \b uart_port + * structure and other members that are specific to MXC UARTs + * @param per_clk peripheral clock coming into the MXC UART module + * @param req_baud current baudrate requested + * @param div returns the reference frequency divider value + */ +static void mxcuart_set_ref_freq(uart_mxc_port * umxc, unsigned long per_clk, + unsigned int req_baud, int *div) +{ + unsigned int d = 1; + + /* + * Choose the smallest possible prescaler to maximize + * the chance of using integer scaling. Ensure that + * the calculation won't overflow. Limit the denom + * to 15 bits since a 16-bit denom doesn't work. + */ + if (req_baud < (1 << (31 - (4 + 15)))) + d = per_clk / (req_baud << (4 + 15)) + 1; + + umxc->port.uartclk = per_clk / d; + + /* + * Set the ONEMS register that is used by IR special case bit and + * the Escape character detect logic + */ + writel(umxc->port.uartclk / 1000, umxc->port.membase + MXC_UARTONEMS); + *div = d; +} + +/*! + * This function is called by the core driver to initialize the low-level + * driver. The function grabs the interrupt resources and registers its + * interrupt service routines. It then initializes the IOMUX registers to + * configure the pins for UART signals and finally initializes the various + * UART registers and enables the port for reception. + * + * @param port the port structure for the UART passed in by the core driver + * + * @return The function returns 0 on success and a non-zero value on failure. + */ +static int mxcuart_startup(struct uart_port *port) +{ + uart_mxc_port *umxc = (uart_mxc_port *) port; + int retval; + volatile unsigned int cr, cr1 = 0, cr2 = 0, ufcr = 0; + + /* + * Some UARTs need separate registrations for the interrupts as + * they do not take the muxed interrupt output to the ARM core + */ + if (umxc->ints_muxed == 1) { + retval = request_irq(umxc->port.irq, mxcuart_int, 0, + "mxcintuart", umxc); + if (retval != 0) { + return retval; + } + } else { + retval = request_irq(umxc->port.irq, mxcuart_tx_int, + 0, "mxcintuart", umxc); + if (retval != 0) { + return retval; + } else { + retval = request_irq(umxc->irqs[0], mxcuart_rx_int, + 0, "mxcintuart", umxc); + if (retval != 0) { + free_irq(umxc->port.irq, umxc); + return retval; + } else { + retval = + request_irq(umxc->irqs[1], mxcuart_mint_int, + 0, "mxcintuart", umxc); + if (retval != 0) { + free_irq(umxc->port.irq, umxc); + free_irq(umxc->irqs[0], umxc); + return retval; + } + } + } + } + + /* Initialize the DMA if we need SDMA data transfer */ + if (umxc->dma_enabled == 1) { + retval = mxcuart_initdma(dma_list + umxc->port.line, umxc); + if (retval != 0) { + printk + (KERN_ERR + "MXC UART: Failed to initialize DMA for UART %d\n", + umxc->port.line); + mxcuart_free_interrupts(umxc); + return retval; + } + /* Configure the GPR register to receive SDMA events */ + config_uartdma_event(umxc->port.line); + } + + /* + * Clear Status Registers 1 and 2 + */ + writel(0xFFFF, umxc->port.membase + MXC_UARTUSR1); + writel(0xFFFF, umxc->port.membase + MXC_UARTUSR2); + + /* Configure the IOMUX for the UART */ + gpio_uart_active(umxc->port.line, umxc->ir_mode); + + /* + * Set the transceiver invert bits if required + */ + if (umxc->ir_mode == IRDA) { + echo_cancel = 1; + writel(umxc->ir_rx_inv | MXC_UARTUCR4_IRSC, umxc->port.membase + + MXC_UARTUCR4); + writel(umxc->rxd_mux | umxc->ir_tx_inv, + umxc->port.membase + MXC_UARTUCR3); + } else { + writel(umxc->rxd_mux, umxc->port.membase + MXC_UARTUCR3); + } + + /* + * Initialize UCR1,2 and UFCR registers + */ + if (umxc->dma_enabled == 1) { + cr2 = (MXC_UARTUCR2_TXEN | MXC_UARTUCR2_RXEN); + } else { + cr2 = + (MXC_UARTUCR2_ATEN | MXC_UARTUCR2_TXEN | MXC_UARTUCR2_RXEN); + } + + writel(cr2, umxc->port.membase + MXC_UARTUCR2); + /* Wait till we are out of software reset */ + do { + cr = readl(umxc->port.membase + MXC_UARTUCR2); + } while (!(cr & MXC_UARTUCR2_SRST)); + + if (umxc->mode == MODE_DTE) { + ufcr |= ((umxc->tx_threshold << MXC_UARTUFCR_TXTL_OFFSET) | + MXC_UARTUFCR_DCEDTE | MXC_UARTUFCR_RFDIV | umxc-> + rx_threshold); + } else { + ufcr |= ((umxc->tx_threshold << MXC_UARTUFCR_TXTL_OFFSET) | + MXC_UARTUFCR_RFDIV | umxc->rx_threshold); + } + writel(ufcr, umxc->port.membase + MXC_UARTUFCR); + + /* + * Finally enable the UART and the Receive interrupts + */ + if (umxc->ir_mode == IRDA) { + cr1 |= MXC_UARTUCR1_IREN; + } + if (umxc->dma_enabled == 1) { + cr1 |= (MXC_UARTUCR1_RXDMAEN | MXC_UARTUCR1_ATDMAEN | + MXC_UARTUCR1_UARTEN); + } else { + cr1 |= (MXC_UARTUCR1_RRDYEN | MXC_UARTUCR1_UARTEN); + } + writel(cr1, umxc->port.membase + MXC_UARTUCR1); + + return 0; +} + +/*! + * This function is called by the core driver for the low-level driver to free + * its resources. The function frees all its interrupts and disables the UART. + * + * @param port the port structure for the UART passed in by the core driver + */ +static void mxcuart_shutdown(struct uart_port *port) +{ + uart_mxc_port *umxc = (uart_mxc_port *) port; + + /* Disable the IOMUX for the UART */ + gpio_uart_inactive(umxc->port.line, umxc->ir_mode); + mxcuart_free_interrupts(umxc); + /* Disable all interrupts, port and break condition */ + writel(0, umxc->port.membase + MXC_UARTUCR1); + writel(0, umxc->port.membase + MXC_UARTUCR3); + if (umxc->dma_enabled == 1) { + mxcuart_freedma(dma_list + umxc->port.line, umxc); + } +} + +/*! + * This function is called while changing the UART parameters. It is called to + * check if the Infrared special case bit (IRSC) in control register 4 should + * be set. + * + * @param baudrate the desired baudrate + * + * @return The functions returns 0 if the IRSC bit does not have to be set, + * else it returns a 1. + */ +/* +static int mxcuart_setir_special(u_int baudrate) +{ + u_int thresh_val; + + thresh_val = 1000000 / (8 * MIN_PULSE_DUR); + if (baudrate > thresh_val) { + return 0; + } + + return 1; +} +*/ + +/*! + * This function is called by the core driver to change the UART parameters, + * including baudrate, word length, parity, stop bits. The function also updates + * the port structures mask registers to indicate the types of events the user is + * interested in receiving. + * + * @param port the port structure for the UART passed in by the core driver + * @param termios the desired termios settings + * @param old old termios + */ +static void mxcuart_set_termios(struct uart_port *port, + struct ktermios *termios, struct ktermios *old) +{ + uart_mxc_port *umxc = (uart_mxc_port *) port; + volatile unsigned int cr4 = 0, cr2 = 0, ufcr; + u_int num, denom, baud; + u_int cr2_mask; /* Used to add the changes to CR2 */ + unsigned long flags, per_clk; + int div; + + cr2_mask = ~(MXC_UARTUCR2_IRTS | MXC_UARTUCR2_CTSC | MXC_UARTUCR2_PREN | + MXC_UARTUCR2_PROE | MXC_UARTUCR2_STPB | MXC_UARTUCR2_WS); + + per_clk = clk_get_rate(umxc->clk); + + /* + * Ask the core to get the baudrate, if requested baudrate is not + * between max and min, then either use the baudrate in old termios + * setting. If it's still invalid, we try 9600 baud. + */ + baud = uart_get_baud_rate(&umxc->port, termios, old, 0, per_clk / 16); + /* Set the Reference frequency divider */ + mxcuart_set_ref_freq(umxc, per_clk, baud, &div); + + /* Byte size, default is 8-bit mode */ + switch (termios->c_cflag & CSIZE) { + case CS7: + cr2 = 0; + break; + default: + cr2 = MXC_UARTUCR2_WS; + break; + } + /* Check to see if we need 2 Stop bits */ + if (termios->c_cflag & CSTOPB) { + cr2 |= MXC_UARTUCR2_STPB; + } + + /* Check to see if we need Parity checking */ + if (termios->c_cflag & PARENB) { + cr2 |= MXC_UARTUCR2_PREN; + if (termios->c_cflag & PARODD) { + cr2 |= MXC_UARTUCR2_PROE; + } + } + spin_lock_irqsave(&umxc->port.lock, flags); + + ufcr = readl(umxc->port.membase + MXC_UARTUFCR); + ufcr = (ufcr & (~MXC_UARTUFCR_RFDIV_MASK)) | + ((6 - div) << MXC_UARTUFCR_RFDIV_OFFSET); + writel(ufcr, umxc->port.membase + MXC_UARTUFCR); + + /* + * Update the per-port timeout + */ + uart_update_timeout(&umxc->port, termios->c_cflag, baud); + + umxc->port.read_status_mask = MXC_UARTURXD_OVRRUN; + /* + * Enable appropriate events to be passed to the TTY layer + */ + if (termios->c_iflag & INPCK) { + umxc->port.read_status_mask |= MXC_UARTURXD_FRMERR | + MXC_UARTURXD_PRERR; + } + if (termios->c_iflag & (BRKINT | PARMRK)) { + umxc->port.read_status_mask |= MXC_UARTURXD_BRK; + } + + /* + * Characters to ignore + */ + umxc->port.ignore_status_mask = 0; + if (termios->c_iflag & IGNPAR) { + umxc->port.ignore_status_mask |= MXC_UARTURXD_FRMERR | + MXC_UARTURXD_PRERR; + } + if (termios->c_iflag & IGNBRK) { + umxc->port.ignore_status_mask |= MXC_UARTURXD_BRK; + /* + * If we are ignoring parity and break indicators, + * ignore overruns too (for real raw support) + */ + if (termios->c_iflag & IGNPAR) { + umxc->port.ignore_status_mask |= MXC_UARTURXD_OVRRUN; + } + } + + /* + * Ignore all characters if CREAD is not set, still receive characters + * from the port, but throw them away. + */ + if ((termios->c_cflag & CREAD) == 0) { + umxc->port.ignore_status_mask |= UART_CREAD_BIT; + } + + cr4 = readl(umxc->port.membase + MXC_UARTUCR4); + if (UART_ENABLE_MS(port, termios->c_cflag)) { + mxcuart_enable_ms(port); + if (umxc->hardware_flow == 1) { + cr4 = (cr4 & (~MXC_UARTUCR4_CTSTL_MASK)) | + (umxc->cts_threshold << MXC_UARTUCR4_CTSTL_OFFSET); + cr2 |= MXC_UARTUCR2_CTSC; + umxc->port.info->port.tty->hw_stopped = 0; + } else { + cr2 |= MXC_UARTUCR2_IRTS; + } + } else { + cr2 |= MXC_UARTUCR2_IRTS; + } + + /* Add Parity, character length and stop bits information */ + cr2 |= (readl(umxc->port.membase + MXC_UARTUCR2) & cr2_mask); + writel(cr2, umxc->port.membase + MXC_UARTUCR2); + /* + if (umxc->ir_mode == IRDA) { + ret = mxcuart_setir_special(baud); + if (ret == 0) { + cr4 &= ~MXC_UARTUCR4_IRSC; + } else { + cr4 |= MXC_UARTUCR4_IRSC; + } + } */ + writel(cr4, umxc->port.membase + MXC_UARTUCR4); + + /* + * Set baud rate + */ + + /* Use integer scaling, if possible. Limit the denom to 15 bits. */ + num = 0; + denom = (umxc->port.uartclk + 8 * baud) / (16 * baud) - 1; + + /* Use fractional scaling if needed to limit the max error to 0.5% */ + if (denom < 100) { + u64 n64 = (u64) 16 * 0x8000 * baud + (umxc->port.uartclk / 2); + do_div(n64, umxc->port.uartclk); + num = (u_int) n64 - 1; + denom = 0x7fff; + } + writel(num, umxc->port.membase + MXC_UARTUBIR); + writel(denom, umxc->port.membase + MXC_UARTUBMR); + + spin_unlock_irqrestore(&umxc->port.lock, flags); +} + +/*! + * This function is called by the core driver to know the UART type. + * + * @param port the port structure for the UART passed in by the core driver + * + * @return The function returns a pointer to a string describing the UART port. + */ +static const char *mxcuart_type(struct uart_port *port) +{ + return port->type == PORT_MXC ? "Freescale MXC" : NULL; +} + +/*! + * This function is called by the core driver to release the memory resources + * currently in use by the UART port. + * + * @param port the port structure for the UART passed in by the core driver + */ +static void mxcuart_release_port(struct uart_port *port) +{ + release_mem_region(port->mapbase, SZ_4K); +} + +/*! + * This function is called by the core driver to request memory resources for + * the UART port. + * + * @param port the port structure for the UART passed in by the core driver + * + * @return The function returns \b -EBUSY on failure, else it returns 0. + */ +static int mxcuart_request_port(struct uart_port *port) +{ + return request_mem_region(port->mapbase, SZ_4K, "serial_mxc") + != NULL ? 0 : -EBUSY; +} + +/*! + * This function is called by the core driver to perform any autoconfiguration + * steps required for the UART port. This function sets the port->type field. + * + * @param port the port structure for the UART passed in by the core driver + * @param flags bit mask of the required configuration + */ +static void mxcuart_config_port(struct uart_port *port, int flags) +{ + if ((flags & UART_CONFIG_TYPE) && (mxcuart_request_port(port) == 0)) { + port->type = PORT_MXC; + } +} + +/*! + * This function is called by the core driver to verify that the new serial + * port information contained within \a ser is suitable for this UART port type. + * The function checks to see if the UART port type specified by the user + * application while setting the UART port information matches what is stored + * in the define \b PORT_MXC found in the header file include/linux/serial_core.h + * + * @param port the port structure for the UART passed in by the core driver + * @param ser the new serial port information + * + * @return The function returns 0 on success or \b -EINVAL if the port type + * specified is not equal to \b PORT_MXC. + */ +static int mxcuart_verify_port(struct uart_port *port, + struct serial_struct *ser) +{ + int ret = 0; + if (ser->type != PORT_UNKNOWN && ser->type != PORT_MXC) { + ret = -EINVAL; + } + return ret; +} + +/*! + * This function is used to send a high priority XON/XOFF character + * + * @param port the port structure for the UART passed in by the core driver + * @param ch the character to send + */ +static void mxcuart_send_xchar(struct uart_port *port, char ch) +{ + unsigned long flags; + + port->x_char = ch; + if (port->info->port.tty->hw_stopped) { + return; + } + + if (ch) { + spin_lock_irqsave(&port->lock, flags); + port->ops->start_tx(port); + spin_unlock_irqrestore(&port->lock, flags); + } +} + +/*! + * This function is used enable/disable the MXC UART clocks + * + * @param port the port structure for the UART passed in by the core driver + * @param state New PM state + * @param oldstate Current PM state + */ +static void +mxcuart_pm(struct uart_port *port, unsigned int state, unsigned int oldstate) +{ + uart_mxc_port *umxc = (uart_mxc_port *) port; + + if (state) + clk_disable(umxc->clk); + else + clk_enable(umxc->clk); +} + +/*! + * This structure contains the pointers to the control functions that are + * invoked by the core serial driver to access the UART hardware. The + * structure is passed to serial_core.c file during registration. + */ +static struct uart_ops mxc_ops = { + .tx_empty = mxcuart_tx_empty, + .set_mctrl = mxcuart_set_mctrl, + .get_mctrl = mxcuart_get_mctrl, + .stop_tx = mxcuart_stop_tx, + .start_tx = mxcuart_start_tx, + .stop_rx = mxcuart_stop_rx, + .enable_ms = mxcuart_enable_ms, + .break_ctl = mxcuart_break_ctl, + .startup = mxcuart_startup, + .shutdown = mxcuart_shutdown, + .set_termios = mxcuart_set_termios, + .type = mxcuart_type, + .pm = mxcuart_pm, + .release_port = mxcuart_release_port, + .request_port = mxcuart_request_port, + .config_port = mxcuart_config_port, + .verify_port = mxcuart_verify_port, + .send_xchar = mxcuart_send_xchar, +}; + +#ifdef CONFIG_SERIAL_MXC_CONSOLE + +/* + * Write out a character once the UART is ready + */ +static inline void mxcuart_console_write_char(struct uart_port *port, char ch) +{ + volatile unsigned int status; + + do { + status = readl(port->membase + MXC_UARTUSR1); + } while ((status & MXC_UARTUSR1_TRDY) == 0); + writel(ch, port->membase + MXC_UARTUTXD); +} + +/*! + * This function is called to write the console messages through the UART port. + * + * @param co the console structure + * @param s the log message to be written to the UART + * @param count length of the message + */ +static void mxcuart_console_write(struct console *co, const char *s, + u_int count) +{ + struct uart_port *port = &mxc_ports[co->index]->port; + volatile unsigned int status, oldcr1, oldcr2, oldcr3, cr2, cr3; + int i; + + /* + * First save the control registers and then disable the interrupts + */ + oldcr1 = readl(port->membase + MXC_UARTUCR1); + oldcr2 = readl(port->membase + MXC_UARTUCR2); + oldcr3 = readl(port->membase + MXC_UARTUCR3); + cr2 = + oldcr2 & ~(MXC_UARTUCR2_ATEN | MXC_UARTUCR2_RTSEN | + MXC_UARTUCR2_ESCI); + cr3 = + oldcr3 & ~(MXC_UARTUCR3_DCD | MXC_UARTUCR3_RI | + MXC_UARTUCR3_DTRDEN); + writel(MXC_UARTUCR1_UARTEN, port->membase + MXC_UARTUCR1); + writel(cr2, port->membase + MXC_UARTUCR2); + writel(cr3, port->membase + MXC_UARTUCR3); + /* + * Do each character + */ + for (i = 0; i < count; i++) { + mxcuart_console_write_char(port, s[i]); + if (s[i] == '\n') { + mxcuart_console_write_char(port, '\r'); + } + } + /* + * Finally, wait for the transmitter to become empty + */ + do { + status = readl(port->membase + MXC_UARTUSR2); + } while (!(status & MXC_UARTUSR2_TXDC)); + + /* + * Restore the control registers + */ + writel(oldcr1, port->membase + MXC_UARTUCR1); + writel(oldcr2, port->membase + MXC_UARTUCR2); + writel(oldcr3, port->membase + MXC_UARTUCR3); +} + +/*! + * Initializes the UART port to be used to print console message with the + * options specified. If no options are specified, then the function + * initializes the UART with the default options of baudrate=115200, 8 bit + * word size, no parity, no flow control. + * + * @param co The console structure + * @param options Any console options passed in from the command line + * + * @return The function returns 0 on success or error. + */ +static int __init mxcuart_console_setup(struct console *co, char *options) +{ + uart_mxc_port *umxc; + int baud = 115200; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + volatile unsigned int cr = 0; + + /* + * Check whether an invalid uart number had been specified, and if + * so, search for the first available port that does have console + * support + */ + if (co->index >= MXC_UART_NR) { + co->index = 0; + } + umxc = mxc_ports[co->index]; + + if (umxc == NULL) { + return -ENODEV; + } + + clk_enable(umxc->clk); + + /* initialize port.lock else oops */ + spin_lock_init(&umxc->port.lock); + + /* + * Initialize the UART registers + */ + writel(MXC_UARTUCR1_UARTEN, umxc->port.membase + MXC_UARTUCR1); + /* Enable the transmitter and do a software reset */ + writel(MXC_UARTUCR2_TXEN, umxc->port.membase + MXC_UARTUCR2); + /* Wait till we are out of software reset */ + do { + cr = readl(umxc->port.membase + MXC_UARTUCR2); + } while (!(cr & MXC_UARTUCR2_SRST)); + + writel(0x0, umxc->port.membase + MXC_UARTUCR3); + writel(0x0, umxc->port.membase + MXC_UARTUCR4); + /* Set TXTL to 2, RXTL to 1 and RFDIV to 2 */ + cr = 0x0800 | MXC_UARTUFCR_RFDIV | 0x1; + if (umxc->mode == MODE_DTE) { + cr |= MXC_UARTUFCR_DCEDTE; + } + writel(cr, umxc->port.membase + MXC_UARTUFCR); + writel(0xFFFF, umxc->port.membase + MXC_UARTUSR1); + writel(0xFFFF, umxc->port.membase + MXC_UARTUSR2); + + if (options != NULL) { + uart_parse_options(options, &baud, &parity, &bits, &flow); + } + gpio_uart_active(umxc->port.line, umxc->ir_mode); + return uart_set_options(&umxc->port, co, baud, parity, bits, flow); +} + +static struct uart_driver mxc_reg; + +/*! + * This structure contains the pointers to the UART console functions. It is + * passed as an argument when registering the console. + */ +static struct console mxc_console = { + .name = "ttymxc", + .write = mxcuart_console_write, + .device = uart_console_device, + .setup = mxcuart_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, + .data = &mxc_reg, +}; + +/*! + * This function registers the console callback functions with the kernel. + */ +static int __init mxcuart_console_init(void) +{ + register_console(&mxc_console); + return 0; +} + +console_initcall(mxcuart_console_init); + +static int __init find_port(struct uart_port *p) +{ + int line; + struct uart_port *port; + for (line = 0; line < MXC_UART_NR; line++) { + if (!mxc_ports[line]) + continue; + port = &mxc_ports[line]->port; + if (uart_match_port(p, port)) + return line; + } + return -ENODEV; +} + +int __init mxc_uart_start_console(struct uart_port *port, char *options) +{ + int line; + line = find_port(port); + if (line < 0) + return -ENODEV; + + add_preferred_console("ttymxc", line, options); + printk("Switching Console to ttymxc%d at %s 0x%lx (options '%s')\n", + line, port->iotype == UPIO_MEM ? "MMIO" : "I/O port", + port->iotype == + UPIO_MEM ? (unsigned long)port->mapbase : (unsigned long)port-> + iobase, options); + + if (!(mxc_console.flags & CON_ENABLED)) { + mxc_console.flags &= ~CON_PRINTBUFFER; + register_console(&mxc_console); + } + return 0; +} + +#define MXC_CONSOLE &mxc_console +#else +#define MXC_CONSOLE NULL +#endif /* CONFIG_SERIAL_MXC_CONSOLE */ + +/*! + * This structure contains the information such as the name of the UART driver + * that appears in the /dev folder, major and minor numbers etc. This structure + * is passed to the serial_core.c file. + */ +static struct uart_driver mxc_reg = { + .owner = THIS_MODULE, + .driver_name = "ttymxc", + .dev_name = "ttymxc", + .major = SERIAL_MXC_MAJOR, + .minor = SERIAL_MXC_MINOR, + .nr = MXC_UART_NR, + .cons = MXC_CONSOLE, +}; + +/*! + * This function is called to put the UART in a low power state. Refer to the + * document driver-model/driver.txt in the kernel source tree for more + * information. + * + * @param pdev the device structure used to give information on which UART + * to suspend + * @param state the power state the device is entering + * + * @return The function returns 0 on success and -1 on failure + */ +static int mxcuart_suspend(struct platform_device *pdev, pm_message_t state) +{ + uart_mxc_port *umxc = platform_get_drvdata(pdev); + + if (umxc == NULL) + return 0; /* skip disabled ports */ + + if (umxc->port.info && umxc->port.info->flags & UIF_INITIALIZED) + uart_suspend_port(&mxc_reg, &umxc->port); + + if (umxc->port.info && umxc->port.info->flags & UIF_SUSPENDED) + umxc->port.info->port.tty->hw_stopped = 1; + + return 0; +} + +/*! + * This function is called to bring the UART back from a low power state. Refer + * to the document driver-model/driver.txt in the kernel source tree for more + * information. + * + * @param pdev the device structure used to give information on which UART + * to resume + * + * @return The function returns 0 on success and -1 on failure + */ +static int mxcuart_resume(struct platform_device *pdev) +{ + uart_mxc_port *umxc = platform_get_drvdata(pdev); + + if (umxc == NULL) + return 0; /* skip disabled ports */ + + if (umxc->port.info && umxc->port.info->flags & UIF_SUSPENDED) { + umxc->port.info->port.tty->hw_stopped = 0; + uart_resume_port(&mxc_reg, &umxc->port); + } + + return 0; +} + +/*! + * This function is called during the driver binding process. Based on the UART + * that is being probed this function adds the appropriate UART port structure + * in the core driver. + * + * @param pdev the device structure used to store device specific + * information that is used by the suspend, resume and remove + * functions + * + * @return The function returns 0 if successful; -1 otherwise. + */ +static int mxcuart_probe(struct platform_device *pdev) +{ + int id = pdev->id; + + mxc_ports[id] = pdev->dev.platform_data; + mxc_ports[id]->port.ops = &mxc_ops; + + /* Do not use UARTs that are disabled during integration */ + if (mxc_ports[id]->enabled == 1) { + mxc_ports[id]->port.dev = &pdev->dev; + spin_lock_init(&mxc_ports[id]->port.lock); + /* Enable the low latency flag for DMA UART ports */ + if (mxc_ports[id]->dma_enabled == 1) { + mxc_ports[id]->port.flags |= UPF_LOW_LATENCY; + } + + mxc_ports[id]->clk = clk_get(&pdev->dev, "uart_clk"); + if (mxc_ports[id]->clk == NULL) + return -1; + + uart_add_one_port(&mxc_reg, &mxc_ports[id]->port); + platform_set_drvdata(pdev, mxc_ports[id]); + } + return 0; +} + +/*! + * Dissociates the driver from the UART device. Removes the appropriate UART + * port structure from the core driver. + * + * @param pdev the device structure used to give information on which UART + * to remove + * + * @return The function always returns 0. + */ +static int mxcuart_remove(struct platform_device *pdev) +{ + uart_mxc_port *umxc = platform_get_drvdata(pdev); + + platform_set_drvdata(pdev, NULL); + + if (umxc) { + uart_remove_one_port(&mxc_reg, &umxc->port); + } + return 0; +} + +/*! + * This structure contains pointers to the power management callback functions. + */ +static struct platform_driver mxcuart_driver = { + .driver = { + .name = "mxcintuart", + }, + .probe = mxcuart_probe, + .remove = mxcuart_remove, + .suspend = mxcuart_suspend, + .resume = mxcuart_resume, +}; + +/*! + * This function is used to initialize the UART driver module. The function + * registers the power management callback functions with the kernel and also + * registers the UART callback functions with the core serial driver. + * + * @return The function returns 0 on success and a non-zero value on failure. + */ +static int __init mxcuart_init(void) +{ + int ret = 0; + + printk(KERN_INFO "Serial: MXC Internal UART driver\n"); + ret = uart_register_driver(&mxc_reg); + if (ret == 0) { + /* Register the device driver structure. */ + ret = platform_driver_register(&mxcuart_driver); + if (ret != 0) { + uart_unregister_driver(&mxc_reg); + } + } + return ret; +} + +/*! + * This function is used to cleanup all resources before the driver exits. + */ +static void __exit mxcuart_exit(void) +{ + platform_driver_unregister(&mxcuart_driver); + uart_unregister_driver(&mxc_reg); +} + +module_init(mxcuart_init); +module_exit(mxcuart_exit); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("MXC serial port driver"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/serial/jsm/jsm_tty.c +++ linux-2.6.28/drivers/serial/jsm/jsm_tty.c @@ -161,6 +161,11 @@ channel->ch_bd->bd_ops->disable_receiver(channel); } +static void jsm_tty_enable_ms(struct uart_port *port) +{ + /* Nothing needed */ +} + static void jsm_tty_break(struct uart_port *port, int break_state) { unsigned long lock_flags; @@ -345,6 +350,7 @@ .start_tx = jsm_tty_start_tx, .send_xchar = jsm_tty_send_xchar, .stop_rx = jsm_tty_stop_rx, + .enable_ms = jsm_tty_enable_ms, .break_ctl = jsm_tty_break, .startup = jsm_tty_open, .shutdown = jsm_tty_close, --- linux-2.6.28.orig/drivers/serial/jsm/jsm_driver.c +++ linux-2.6.28/drivers/serial/jsm/jsm_driver.c @@ -84,6 +84,8 @@ brd->pci_dev = pdev; if (pdev->device == PCIE_DEVICE_ID_NEO_4_IBM) brd->maxports = 4; + else if (pdev->device == PCI_DEVICE_ID_DIGI_NEO_8) + brd->maxports = 8; else brd->maxports = 2; @@ -212,6 +214,7 @@ { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2RJ45), 0, 0, 2 }, { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_NEO_2RJ45PRI), 0, 0, 3 }, { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_4_IBM), 0, 0, 4 }, + { PCI_DEVICE(PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_NEO_8), 0, 0, 5 }, { 0, } }; MODULE_DEVICE_TABLE(pci, jsm_pci_tbl); --- linux-2.6.28.orig/drivers/hid/hid-sony.c +++ linux-2.6.28/drivers/hid/hid-sony.c @@ -102,7 +102,7 @@ } ret = sony_set_operational(hdev); - if (ret) + if (ret < 0) goto err_stop; return 0; --- linux-2.6.28.orig/drivers/hid/hid-core.c +++ linux-2.6.28/drivers/hid/hid-core.c @@ -1302,6 +1302,12 @@ { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, + { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, + { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, + { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) }, + { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, + { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) }, @@ -1529,10 +1535,6 @@ { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3) }, { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY1) }, { HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY2) }, - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651) }, - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) }, { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) }, { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, @@ -1543,8 +1545,6 @@ { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20) }, { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_8_8_4_IF_KIT) }, { HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, - { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, { } }; --- linux-2.6.28.orig/drivers/hid/hid-microsoft.c +++ linux-2.6.28/drivers/hid/hid-microsoft.c @@ -30,7 +30,7 @@ #define MS_NOGET 0x10 /* - * Microsoft Wireless Desktop Receiver (Model 1028) has several + * Microsoft Wireless Desktop Receiver (Model 1028) has * 'Usage Min/Max' where it ought to have 'Physical Min/Max' */ static void ms_report_fixup(struct hid_device *hdev, __u8 *rdesc, @@ -38,17 +38,12 @@ { unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); - if ((quirks & MS_RDESC) && rsize == 571 && rdesc[284] == 0x19 && - rdesc[286] == 0x2a && rdesc[304] == 0x19 && - rdesc[306] == 0x29 && rdesc[352] == 0x1a && - rdesc[355] == 0x2a && rdesc[557] == 0x19 && + if ((quirks & MS_RDESC) && rsize == 571 && rdesc[557] == 0x19 && rdesc[559] == 0x29) { dev_info(&hdev->dev, "fixing up Microsoft Wireless Receiver " "Model 1028 report descriptor\n"); - rdesc[284] = rdesc[304] = rdesc[557] = 0x35; - rdesc[352] = 0x36; - rdesc[286] = rdesc[355] = 0x46; - rdesc[306] = rdesc[559] = 0x45; + rdesc[557] = 0x35; + rdesc[559] = 0x45; } } --- linux-2.6.28.orig/drivers/rtc/Kconfig +++ linux-2.6.28/drivers/rtc/Kconfig @@ -657,9 +657,24 @@ firmware calls. If you do not know what you are doing, you should just say Y. +config RTC_DRV_MXC_V2 + tristate "Freescale MXC Secure Real Time Clock" + depends on ARCH_MXC + depends on RTC_CLASS + help + Support for Freescale SRTC MXC + +config RTC_MC13892 + tristate "Freescale MC13892 Real Time Clock" + depends on ARCH_MXC && MXC_PMIC_MC13892 + depends on RTC_CLASS + help + Support for Freescale MC13892 RTC + config RTC_DRV_PPC tristate "PowerPC machine dependent RTC support" depends on PPC + depends on RTC_CLASS help The PowerPC kernel has machine-specific functions for accessing the RTC. This exposes that functionality through the generic RTC --- linux-2.6.28.orig/drivers/rtc/rtc-mxc_v2.c +++ linux-2.6.28/drivers/rtc/rtc-mxc_v2.c @@ -0,0 +1,762 @@ +/* + * Copyright 2004-2009 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 + */ +/* + * Implementation based on rtc-ds1553.c + */ + +/*! + * @defgroup RTC Real Time Clock (RTC) Driver + */ +/*! + * @file rtc-mxc_v2.c + * @brief Real Time Clock interface + * + * This file contains Real Time Clock interface for Linux. + * + * @ingroup RTC + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SRTC_LPPDR_INIT 0x41736166 /* init for glitch detect */ + +#define SRTC_LPCR_SWR_LP (1 << 0) /* lp software reset */ +#define SRTC_LPCR_EN_LP (1 << 3) /* lp enable */ +#define SRTC_LPCR_WAE (1 << 4) /* lp wakeup alarm enable */ +#define SRTC_LPCR_SAE (1 << 5) /* lp security alarm enable */ +#define SRTC_LPCR_SI (1 << 6) /* lp security interrupt enable */ +#define SRTC_LPCR_ALP (1 << 7) /* lp alarm flag */ +#define SRTC_LPCR_LTC (1 << 8) /* lp lock time counter */ +#define SRTC_LPCR_LMC (1 << 9) /* lp lock monotonic counter */ +#define SRTC_LPCR_SV (1 << 10) /* lp security violation */ +#define SRTC_LPCR_NSA (1 << 11) /* lp non secure access */ +#define SRTC_LPCR_NVEIE (1 << 12) /* lp non valid state exit int en */ +#define SRTC_LPCR_IEIE (1 << 13) /* lp init state exit int enable */ +#define SRTC_LPCR_NVE (1 << 14) /* lp non valid state exit bit */ +#define SRTC_LPCR_IE (1 << 15) /* lp init state exit bit */ + +#define SRTC_LPCR_ALL_INT_EN (SRTC_LPCR_WAE | SRTC_LPCR_SAE | \ + SRTC_LPCR_SI | SRTC_LPCR_ALP | \ + SRTC_LPCR_NVEIE | SRTC_LPCR_IEIE) + +#define SRTC_LPSR_TRI (1 << 0) /* lp time read invalidate */ +#define SRTC_LPSR_PGD (1 << 1) /* lp power supply glitc detected */ +#define SRTC_LPSR_CTD (1 << 2) /* lp clock tampering detected */ +#define SRTC_LPSR_ALP (1 << 3) /* lp alarm flag */ +#define SRTC_LPSR_MR (1 << 4) /* lp monotonic counter rollover */ +#define SRTC_LPSR_TR (1 << 5) /* lp time rollover */ +#define SRTC_LPSR_EAD (1 << 6) /* lp external alarm detected */ +#define SRTC_LPSR_IT0 (1 << 7) /* lp IIM throttle */ +#define SRTC_LPSR_IT1 (1 << 8) +#define SRTC_LPSR_IT2 (1 << 9) +#define SRTC_LPSR_SM0 (1 << 10) /* lp security mode */ +#define SRTC_LPSR_SM1 (1 << 11) +#define SRTC_LPSR_STATE_LP0 (1 << 12) /* lp state */ +#define SRTC_LPSR_STATE_LP1 (1 << 13) +#define SRTC_LPSR_NVES (1 << 14) /* lp non-valid state exit status */ +#define SRTC_LPSR_IES (1 << 15) /* lp init state exit status */ + +#define MAX_PIE_NUM 15 +#define MAX_PIE_FREQ 32768 +#define MIN_PIE_FREQ 1 + +#define SRTC_PI0 (1 << 0) +#define SRTC_PI1 (1 << 1) +#define SRTC_PI2 (1 << 2) +#define SRTC_PI3 (1 << 3) +#define SRTC_PI4 (1 << 4) +#define SRTC_PI5 (1 << 5) +#define SRTC_PI6 (1 << 6) +#define SRTC_PI7 (1 << 7) +#define SRTC_PI8 (1 << 8) +#define SRTC_PI9 (1 << 9) +#define SRTC_PI10 (1 << 10) +#define SRTC_PI11 (1 << 11) +#define SRTC_PI12 (1 << 12) +#define SRTC_PI13 (1 << 13) +#define SRTC_PI14 (1 << 14) +#define SRTC_PI15 (1 << 15) + +#define PIT_ALL_ON (SRTC_PI1 | SRTC_PI2 | SRTC_PI3 | \ + SRTC_PI4 | SRTC_PI5 | SRTC_PI6 | SRTC_PI7 | \ + SRTC_PI8 | SRTC_PI9 | SRTC_PI10 | SRTC_PI11 | \ + SRTC_PI12 | SRTC_PI13 | SRTC_PI14 | SRTC_PI15) + +#define SRTC_SWR_HP (1 << 0) /* hp software reset */ +#define SRTC_EN_HP (1 << 3) /* hp enable */ +#define SRTC_TS (1 << 4) /* time syncronize hp with lp */ + +#define SRTC_IE_AHP (1 << 16) /* Alarm HP Interrupt Enable bit */ +#define SRTC_IE_WDHP (1 << 18) /* Write Done HP Interrupt Enable bit */ +#define SRTC_IE_WDLP (1 << 19) /* Write Done LP Interrupt Enable bit */ + +#define SRTC_ISR_AHP (1 << 16) /* interrupt status: alarm hp */ +#define SRTC_ISR_WDHP (1 << 18) /* interrupt status: write done hp */ +#define SRTC_ISR_WDLP (1 << 19) /* interrupt status: write done lp */ +#define SRTC_ISR_WPHP (1 << 20) /* interrupt status: write pending hp */ +#define SRTC_ISR_WPLP (1 << 21) /* interrupt status: write pending lp */ + +#define SRTC_LPSCMR 0x00 /* LP Secure Counter MSB Reg */ +#define SRTC_LPSCLR 0x04 /* LP Secure Counter LSB Reg */ +#define SRTC_LPSAR 0x08 /* LP Secure Alarm Reg */ +#define SRTC_LPSMCR 0x0C /* LP Secure Monotonic Counter Reg */ +#define SRTC_LPCR 0x10 /* LP Control Reg */ +#define SRTC_LPSR 0x14 /* LP Status Reg */ +#define SRTC_LPPDR 0x18 /* LP Power Supply Glitch Detector Reg */ +#define SRTC_LPGR 0x1C /* LP General Purpose Reg */ +#define SRTC_HPCMR 0x20 /* HP Counter MSB Reg */ +#define SRTC_HPCLR 0x24 /* HP Counter LSB Reg */ +#define SRTC_HPAMR 0x28 /* HP Alarm MSB Reg */ +#define SRTC_HPALR 0x2C /* HP Alarm LSB Reg */ +#define SRTC_HPCR 0x30 /* HP Control Reg */ +#define SRTC_HPISR 0x34 /* HP Interrupt Status Reg */ +#define SRTC_HPIENR 0x38 /* HP Interrupt Enable Reg */ + +#define SRTC_SECMODE_MASK 0x3 /* the mask of SRTC security mode */ +#define SRTC_SECMODE_LOW 0x0 /* Low Security */ +#define SRTC_SECMODE_MED 0x1 /* Medium Security */ +#define SRTC_SECMODE_HIGH 0x2 /* High Security */ +#define SRTC_SECMODE_RESERVED 0x3 /* Reserved */ + +struct rtc_drv_data { + struct rtc_device *rtc; + void __iomem *ioaddr; + unsigned long baseaddr; + int irq; + struct clk *clk; + bool irq_enable; +}; + +/*! + * @defgroup RTC Real Time Clock (RTC) Driver + */ +/*! + * @file rtc-mxc.c + * @brief Real Time Clock interface + * + * This file contains Real Time Clock interface for Linux. + * + * @ingroup RTC + */ + +static unsigned long rtc_status; + +static DEFINE_SPINLOCK(rtc_lock); + +/*! + * This function does write synchronization for writes to the lp srtc block. + * To take care of the asynchronous CKIL clock, all writes from the IP domain + * will be synchronized to the CKIL domain. + */ +static inline void rtc_write_sync_lp(void __iomem *ioaddr) +{ + while ((__raw_readl(ioaddr + SRTC_HPISR) & SRTC_ISR_WPLP) != 0) + msleep(1); + while ((__raw_readl(ioaddr + SRTC_HPISR) & SRTC_ISR_WDLP) == 0) + msleep(1); + __raw_writel(SRTC_ISR_WDLP, ioaddr + SRTC_HPISR); + while ((__raw_readl(ioaddr + SRTC_HPISR) & SRTC_ISR_WPHP) != 0) + msleep(1); +} + +static inline void rtc_write_sync_lp_no_wait(void __iomem *ioaddr) +{ + while ((__raw_readl(ioaddr + SRTC_HPISR) & SRTC_ISR_WPLP) != 0); + while ((__raw_readl(ioaddr + SRTC_HPISR) & SRTC_ISR_WDLP) == 0); + __raw_writel(SRTC_ISR_WDLP, ioaddr + SRTC_HPISR); + while ((__raw_readl(ioaddr + SRTC_HPISR) & SRTC_ISR_WPHP) != 0); +} + +/*! + * This function updates the RTC alarm registers and then clears all the + * interrupt status bits. + * + * @param alrm the new alarm value to be updated in the RTC + * + * @return 0 if successful; non-zero otherwise. + */ +static int rtc_update_alarm(struct device *dev, struct rtc_time *alrm) +{ + struct rtc_drv_data *pdata = dev_get_drvdata(dev); + void __iomem *ioaddr = pdata->ioaddr; + struct rtc_time alarm_tm, now_tm; + unsigned long now, time; + int ret; + + now = __raw_readl(ioaddr + SRTC_LPSCMR); + rtc_time_to_tm(now, &now_tm); + + alarm_tm.tm_year = now_tm.tm_year; + alarm_tm.tm_mon = now_tm.tm_mon; + alarm_tm.tm_mday = now_tm.tm_mday; + + alarm_tm.tm_hour = alrm->tm_hour; + alarm_tm.tm_min = alrm->tm_min; + alarm_tm.tm_sec = alrm->tm_sec; + + rtc_tm_to_time(&now_tm, &now); + rtc_tm_to_time(&alarm_tm, &time); + + if (time < now) { + time += 60 * 60 * 24; + rtc_time_to_tm(time, &alarm_tm); + } + ret = rtc_tm_to_time(&alarm_tm, &time); + + __raw_writel(time, ioaddr + SRTC_LPSAR); + + /* clear alarm interrupt status bit */ + __raw_writel(SRTC_LPSR_ALP, ioaddr + SRTC_LPSR); + + return ret; +} + +/*! + * This function is the RTC interrupt service routine. + * + * @param irq RTC IRQ number + * @param dev_id device ID which is not used + * + * @return IRQ_HANDLED as defined in the include/linux/interrupt.h file. + */ +static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id) +{ + struct platform_device *pdev = dev_id; + struct rtc_drv_data *pdata = platform_get_drvdata(pdev); + void __iomem *ioaddr = pdata->ioaddr; + u32 lp_status, lp_cr; + u32 events = 0; + + lp_status = __raw_readl(ioaddr + SRTC_LPSR); + lp_cr = __raw_readl(ioaddr + SRTC_LPCR); + + /* update irq data & counter */ + if (lp_status & SRTC_LPSR_ALP) { + if (lp_cr & SRTC_LPCR_ALP) + events |= (RTC_AF | RTC_IRQF); + + /* disable further lp alarm interrupts */ + lp_cr &= ~(SRTC_LPCR_ALP | SRTC_LPCR_WAE); + } + + /* Update interrupt enables */ + __raw_writel(lp_cr, ioaddr + SRTC_LPCR); + + /* If no interrupts are enabled, turn off interrupts in kernel */ + if (((lp_cr & SRTC_LPCR_ALL_INT_EN) == 0) && (pdata->irq_enable)) { + disable_irq(pdata->irq); + pdata->irq_enable = false; + } + + /* clear interrupt status */ + __raw_writel(lp_status, ioaddr + SRTC_LPSR); + + rtc_update_irq(pdata->rtc, 1, events); + return IRQ_HANDLED; +} + +/*! + * This function is used to open the RTC driver. + * + * @return 0 if successful; non-zero otherwise. + */ +static int mxc_rtc_open(struct device *dev) +{ + if (test_and_set_bit(1, &rtc_status)) + return -EBUSY; + return 0; +} + +/*! + * clear all interrupts and release the IRQ + */ +static void mxc_rtc_release(struct device *dev) +{ + struct rtc_drv_data *pdata = dev_get_drvdata(dev); + void __iomem *ioaddr = pdata->ioaddr; + unsigned long lock_flags = 0; + + spin_lock_irqsave(&rtc_lock, lock_flags); + + /* Disable all rtc interrupts */ + __raw_writel(__raw_readl(ioaddr + SRTC_LPCR) & ~(SRTC_LPCR_ALL_INT_EN), + ioaddr + SRTC_LPCR); + + /* Clear all interrupt status */ + __raw_writel(0xFFFFFFFF, ioaddr + SRTC_LPSR); + + spin_unlock_irqrestore(&rtc_lock, lock_flags); + rtc_status = 0; +} + +/*! + * This function is used to support some ioctl calls directly. + * Other ioctl calls are supported indirectly through the + * arm/common/rtctime.c file. + * + * @param cmd ioctl command as defined in include/linux/rtc.h + * @param arg value for the ioctl command + * + * @return 0 if successful or negative value otherwise. + */ +static int mxc_rtc_ioctl(struct device *dev, unsigned int cmd, + unsigned long arg) +{ + struct rtc_drv_data *pdata = dev_get_drvdata(dev); + void __iomem *ioaddr = pdata->ioaddr; + unsigned long lock_flags = 0; + u32 lp_cr; + + switch (cmd) { + case RTC_AIE_OFF: + spin_lock_irqsave(&rtc_lock, lock_flags); + lp_cr = __raw_readl(ioaddr + SRTC_LPCR); + lp_cr &= ~(SRTC_LPCR_ALP | SRTC_LPCR_WAE); + if (((lp_cr & SRTC_LPCR_ALL_INT_EN) == 0) + && (pdata->irq_enable)) { + disable_irq(pdata->irq); + pdata->irq_enable = false; + } + __raw_writel(lp_cr, ioaddr + SRTC_LPCR); + spin_unlock_irqrestore(&rtc_lock, lock_flags); + return 0; + + case RTC_AIE_ON: + spin_lock_irqsave(&rtc_lock, lock_flags); + if (!pdata->irq_enable) { + enable_irq(pdata->irq); + pdata->irq_enable = true; + } + lp_cr = __raw_readl(ioaddr + SRTC_LPCR); + lp_cr |= SRTC_LPCR_ALP | SRTC_LPCR_WAE; + __raw_writel(lp_cr, ioaddr + SRTC_LPCR); + spin_unlock_irqrestore(&rtc_lock, lock_flags); + return 0; + } + + return -ENOIOCTLCMD; +} + +/*! + * This function reads the current RTC time into tm in Gregorian date. + * + * @param tm contains the RTC time value upon return + * + * @return 0 if successful; non-zero otherwise. + */ +static int mxc_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct rtc_drv_data *pdata = dev_get_drvdata(dev); + void __iomem *ioaddr = pdata->ioaddr; + + rtc_time_to_tm(__raw_readl(ioaddr + SRTC_LPSCMR), tm); + return 0; +} + +/*! + * This function sets the internal RTC time based on tm in Gregorian date. + * + * @param tm the time value to be set in the RTC + * + * @return 0 if successful; non-zero otherwise. + */ +static int mxc_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct rtc_drv_data *pdata = dev_get_drvdata(dev); + void __iomem *ioaddr = pdata->ioaddr; + unsigned long time; + int ret; + ret = rtc_tm_to_time(tm, &time); + if (ret != 0) + return ret; + + __raw_writel(time, ioaddr + SRTC_LPSCMR); + rtc_write_sync_lp(ioaddr); + + return 0; +} + +/*! + * This function reads the current alarm value into the passed in \b alrm + * argument. It updates the \b alrm's pending field value based on the whether + * an alarm interrupt occurs or not. + * + * @param alrm contains the RTC alarm value upon return + * + * @return 0 if successful; non-zero otherwise. + */ +static int mxc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct rtc_drv_data *pdata = dev_get_drvdata(dev); + void __iomem *ioaddr = pdata->ioaddr; + + rtc_time_to_tm(__raw_readl(ioaddr + SRTC_LPSAR), &alrm->time); + alrm->pending = + ((__raw_readl(ioaddr + SRTC_LPSR) & SRTC_LPSR_ALP) != 0) ? 1 : 0; + + return 0; +} + +/*! + * This function sets the RTC alarm based on passed in alrm. + * + * @param alrm the alarm value to be set in the RTC + * + * @return 0 if successful; non-zero otherwise. + */ +static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct rtc_drv_data *pdata = dev_get_drvdata(dev); + void __iomem *ioaddr = pdata->ioaddr; + unsigned long lock_flags = 0; + u32 lp_cr; + int ret; + + if (rtc_valid_tm(&alrm->time)) { + if (alrm->time.tm_sec > 59 || + alrm->time.tm_hour > 23 || alrm->time.tm_min > 59) { + return -EINVAL; + } + } + + spin_lock_irqsave(&rtc_lock, lock_flags); + lp_cr = __raw_readl(ioaddr + SRTC_LPCR); + + ret = rtc_update_alarm(dev, &alrm->time); + if (ret) + goto out; + + if (alrm->enabled) + lp_cr |= (SRTC_LPCR_ALP | SRTC_LPCR_WAE); + else + lp_cr &= ~(SRTC_LPCR_ALP | SRTC_LPCR_WAE); + + if (lp_cr & SRTC_LPCR_ALL_INT_EN) { + if (!pdata->irq_enable) { + enable_irq(pdata->irq); + pdata->irq_enable = true; + } + } else { + if (pdata->irq_enable) { + disable_irq(pdata->irq); + pdata->irq_enable = false; + } + } + + __raw_writel(lp_cr, ioaddr + SRTC_LPCR); + +out: + spin_unlock_irqrestore(&rtc_lock, lock_flags); + rtc_write_sync_lp(ioaddr); + return ret; +} + +/*! + * This function is used to provide the content for the /proc/driver/rtc + * file. + * + * @param seq buffer to hold the information that the driver wants to write + * + * @return The number of bytes written into the rtc file. + */ +static int mxc_rtc_proc(struct device *dev, struct seq_file *seq) +{ + struct rtc_drv_data *pdata = dev_get_drvdata(dev); + void __iomem *ioaddr = pdata->ioaddr; + + seq_printf(seq, "alarm_IRQ\t: %s\n", + (((__raw_readl(ioaddr + SRTC_LPCR)) & SRTC_LPCR_ALP) != + 0) ? "yes" : "no"); + + return 0; +} + +/*! + * The RTC driver structure + */ +static struct rtc_class_ops mxc_rtc_ops = { + .open = mxc_rtc_open, + .release = mxc_rtc_release, + .ioctl = mxc_rtc_ioctl, + .read_time = mxc_rtc_read_time, + .set_time = mxc_rtc_set_time, + .read_alarm = mxc_rtc_read_alarm, + .set_alarm = mxc_rtc_set_alarm, + .proc = mxc_rtc_proc, +}; + +/*! MXC RTC Power management control */ + +static struct timespec mxc_rtc_delta; + +static int mxc_rtc_probe(struct platform_device *pdev) +{ + struct clk *clk; + struct timespec tv; + struct resource *res; + struct rtc_device *rtc; + struct rtc_drv_data *pdata = NULL; + struct mxc_srtc_platform_data *plat_data = NULL; + void __iomem *ioaddr; + void __iomem *srtc_secmode_addr; + int ret = 0; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + pdata->clk = clk_get(&pdev->dev, "rtc_clk"); + clk_enable(pdata->clk); + pdata->baseaddr = res->start; + pdata->ioaddr = ioremap(pdata->baseaddr, 0x40); + ioaddr = pdata->ioaddr; + + /* Configure and enable the RTC */ + pdata->irq = platform_get_irq(pdev, 0); + if (pdata->irq >= 0) { + if (request_irq(pdata->irq, mxc_rtc_interrupt, IRQF_SHARED, + pdev->name, pdev) < 0) { + dev_warn(&pdev->dev, "interrupt not available.\n"); + pdata->irq = -1; + } else { + disable_irq(pdata->irq); + pdata->irq_enable = false; + } + } + + clk = clk_get(NULL, "rtc_clk"); + if (clk_get_rate(clk) != 32768) { + printk(KERN_ALERT "rtc clock is not valid"); + ret = -EINVAL; + clk_put(clk); + goto err_out; + } + clk_put(clk); + + /* initialize glitch detect */ + __raw_writel(SRTC_LPPDR_INIT, ioaddr + SRTC_LPPDR); + rtc_write_sync_lp_no_wait(ioaddr); + + /* clear lp interrupt status */ + __raw_writel(0xFFFFFFFF, ioaddr + SRTC_LPSR); + rtc_write_sync_lp_no_wait(ioaddr); + + plat_data = (struct mxc_srtc_platform_data *)pdev->dev.platform_data; + clk = clk_get(NULL, "iim_clk"); + clk_enable(clk); + srtc_secmode_addr = ioremap(plat_data->srtc_sec_mode_addr, 1); + + /* Check SRTC security mode */ + if (((__raw_readl(srtc_secmode_addr) & SRTC_SECMODE_MASK) == + SRTC_SECMODE_LOW) && (cpu_is_mx51_rev(CHIP_REV_1_0) == 1)) { + /* Workaround for MX51 TO1 due to inaccurate CKIL clock */ + __raw_writel(SRTC_LPCR_EN_LP, ioaddr + SRTC_LPCR); + rtc_write_sync_lp_no_wait(ioaddr); + } else { + /* move out of init state */ + __raw_writel((SRTC_LPCR_IE | SRTC_LPCR_NSA), + ioaddr + SRTC_LPCR); + + rtc_write_sync_lp_no_wait(ioaddr); + + while ((__raw_readl(ioaddr + SRTC_LPSR) & SRTC_LPSR_IES) == 0); + + /* move out of non-valid state */ + __raw_writel((SRTC_LPCR_IE | SRTC_LPCR_NVE | SRTC_LPCR_NSA | + SRTC_LPCR_EN_LP), ioaddr + SRTC_LPCR); + + rtc_write_sync_lp_no_wait(ioaddr); + + while ((__raw_readl(ioaddr + SRTC_LPSR) & SRTC_LPSR_NVES) == 0); + + __raw_writel(0xFFFFFFFF, ioaddr + SRTC_LPSR); + rtc_write_sync_lp_no_wait(ioaddr); + } + clk_disable(clk); + clk_put(clk); + + rtc = rtc_device_register(pdev->name, &pdev->dev, + &mxc_rtc_ops, THIS_MODULE); + if (IS_ERR(rtc)) { + ret = PTR_ERR(rtc); + goto err_out; + } + + pdata->rtc = rtc; + platform_set_drvdata(pdev, pdata); + + tv.tv_nsec = 0; + tv.tv_sec = __raw_readl(ioaddr + SRTC_LPSCMR); + + /* By default, devices should wakeup if they can */ + /* So srtc is set as "should wakeup" as it can */ + device_init_wakeup(&pdev->dev, 1); + + return ret; + +err_out: + clk_disable(pdata->clk); + iounmap(ioaddr); + if (pdata->irq >= 0) + free_irq(pdata->irq, pdev); + kfree(pdata); + return ret; +} + +static int __exit mxc_rtc_remove(struct platform_device *pdev) +{ + struct rtc_drv_data *pdata = platform_get_drvdata(pdev); + rtc_device_unregister(pdata->rtc); + if (pdata->irq >= 0) + free_irq(pdata->irq, pdev); + + clk_disable(pdata->clk); + clk_put(pdata->clk); + kfree(pdata); + mxc_rtc_release(NULL); + return 0; +} + +/*! + * This function is called to save the system time delta relative to + * the MXC RTC when enterring a low power state. This time delta is + * then used on resume to adjust the system time to account for time + * loss while suspended. + * + * @param pdev not used + * @param state Power state to enter. + * + * @return The function always returns 0. + */ +static int mxc_rtc_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct rtc_drv_data *pdata = platform_get_drvdata(pdev); + void __iomem *ioaddr = pdata->ioaddr; + struct timespec tv; + + if (device_may_wakeup(&pdev->dev)) { + enable_irq_wake(pdata->irq); + } else { + /* calculate time delta for suspend. RTC precision is + 1 second; adjust delta for avg 1/2 sec err */ + tv.tv_nsec = NSEC_PER_SEC >> 1; + tv.tv_sec = __raw_readl(ioaddr + SRTC_LPSCMR); + set_normalized_timespec(&mxc_rtc_delta, + xtime.tv_sec - tv.tv_sec, + xtime.tv_nsec - tv.tv_nsec); + + if (pdata->irq_enable) + disable_irq(pdata->irq); + } + + clk_disable(pdata->clk); + + return 0; +} + +/*! + * This function is called to correct the system time based on the + * current MXC RTC time relative to the time delta saved during + * suspend. + * + * @param pdev not used + * + * @return The function always returns 0. + */ +static int mxc_rtc_resume(struct platform_device *pdev) +{ + struct rtc_drv_data *pdata = platform_get_drvdata(pdev); + void __iomem *ioaddr = pdata->ioaddr; + struct timespec tv; + struct timespec ts; + + clk_enable(pdata->clk); + + if (device_may_wakeup(&pdev->dev)) { + disable_irq_wake(pdata->irq); + } else { + if (pdata->irq_enable) + enable_irq(pdata->irq); + + tv.tv_nsec = 0; + tv.tv_sec = __raw_readl(ioaddr + SRTC_LPSCMR); + + /* + * restore wall clock using delta against this RTC; + * adjust again for avg 1/2 second RTC sampling error + */ + set_normalized_timespec(&ts, + tv.tv_sec + mxc_rtc_delta.tv_sec, + (NSEC_PER_SEC >> 1) + + mxc_rtc_delta.tv_nsec); + do_settimeofday(&ts); + } + + return 0; +} + +/*! + * Contains pointers to the power management callback functions. + */ +static struct platform_driver mxc_rtc_driver = { + .driver = { + .name = "mxc_rtc", + }, + .probe = mxc_rtc_probe, + .remove = __exit_p(mxc_rtc_remove), + .suspend = mxc_rtc_suspend, + .resume = mxc_rtc_resume, +}; + +/*! + * This function creates the /proc/driver/rtc file and registers the device RTC + * in the /dev/misc directory. It also reads the RTC value from external source + * and setup the internal RTC properly. + * + * @return -1 if RTC is failed to initialize; 0 is successful. + */ +static int __init mxc_rtc_init(void) +{ + return platform_driver_register(&mxc_rtc_driver); +} + +/*! + * This function removes the /proc/driver/rtc file and un-registers the + * device RTC from the /dev/misc directory. + */ +static void __exit mxc_rtc_exit(void) +{ + platform_driver_unregister(&mxc_rtc_driver); + +} + +module_init(mxc_rtc_init); +module_exit(mxc_rtc_exit); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("Realtime Clock Driver (RTC)"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/rtc/Makefile +++ linux-2.6.28/drivers/rtc/Makefile @@ -70,3 +70,5 @@ obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o +obj-$(CONFIG_RTC_DRV_MXC_V2) += rtc-mxc_v2.o +obj-$(CONFIG_RTC_MC13892) += rtc-mc13892.o --- linux-2.6.28.orig/drivers/rtc/rtc-mc13892.c +++ linux-2.6.28/drivers/rtc/rtc-mc13892.c @@ -0,0 +1,256 @@ +/* + * Copyright 2008-2009 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 + */ + +#include +#include +#include + +#include +#include + +#define RTC_TIME_LSH 0 +#define RTC_DAY_LSH 0 +#define RTCALARM_TIME_LSH 0 +#define RTCALARM_DAY_LSH 0 + +#define RTC_TIME_WID 17 +#define RTC_DAY_WID 15 +#define RTCALARM_TIME_WID 17 +#define RTCALARM_DAY_WID 15 + +static unsigned long rtc_status; + +static int mxc_rtc_open(struct device *dev) +{ + if (test_and_set_bit(1, &rtc_status)) + return -EBUSY; + return 0; +} + +static void mxc_rtc_release(struct device *dev) +{ + clear_bit(1, &rtc_status); +} + +static int mxc_rtc_ioctl(struct device *dev, unsigned int cmd, + unsigned long arg) +{ + switch (cmd) { + case RTC_AIE_OFF: + pr_debug("alarm off\n"); + CHECK_ERROR(pmic_write_reg(REG_RTC_ALARM, 0x100000, 0x100000)); + return 0; + case RTC_AIE_ON: + pr_debug("alarm on\n"); + CHECK_ERROR(pmic_write_reg(REG_RTC_ALARM, 0, 0x100000)); + return 0; + } + + return -ENOIOCTLCMD; +} + +static int mxc_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + unsigned int tod_reg_val = 0; + unsigned int day_reg_val = 0, day_reg_val2; + unsigned int mask, value; + unsigned long time; + + do { + mask = BITFMASK(RTC_DAY); + CHECK_ERROR(pmic_read_reg(REG_RTC_DAY, &value, mask)); + day_reg_val = BITFEXT(value, RTC_DAY); + + mask = BITFMASK(RTC_TIME); + CHECK_ERROR(pmic_read_reg(REG_RTC_TIME, &value, mask)); + tod_reg_val = BITFEXT(value, RTC_TIME); + + mask = BITFMASK(RTC_DAY); + CHECK_ERROR(pmic_read_reg(REG_RTC_DAY, &value, mask)); + day_reg_val2 = BITFEXT(value, RTC_DAY); + } while (day_reg_val != day_reg_val2); + + time = (unsigned long)((unsigned long)(tod_reg_val & + 0x0001FFFF) + + (unsigned long)(day_reg_val * 86400)); + + rtc_time_to_tm(time, tm); + + return 0; +} + +static int mxc_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + unsigned int tod_reg_val = 0; + unsigned int day_reg_val, day_reg_val2 = 0; + unsigned int mask, value; + unsigned long time; + + if (rtc_valid_tm(tm)) + return -1; + + rtc_tm_to_time(tm, &time); + + tod_reg_val = time % 86400; + day_reg_val = time / 86400; + + do { + mask = BITFMASK(RTC_DAY); + value = BITFVAL(RTC_DAY, day_reg_val); + CHECK_ERROR(pmic_write_reg(REG_RTC_DAY, value, mask)); + + mask = BITFMASK(RTC_TIME); + value = BITFVAL(RTC_TIME, tod_reg_val); + CHECK_ERROR(pmic_write_reg(REG_RTC_TIME, value, mask)); + + mask = BITFMASK(RTC_DAY); + CHECK_ERROR(pmic_read_reg(REG_RTC_DAY, &value, mask)); + day_reg_val2 = BITFEXT(value, RTC_DAY); + } while (day_reg_val != day_reg_val2); + + return 0; +} + +static int mxc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + unsigned int tod_reg_val = 0; + unsigned int day_reg_val = 0; + unsigned int mask, value; + unsigned long time; + + mask = BITFMASK(RTCALARM_TIME); + CHECK_ERROR(pmic_read_reg(REG_RTC_ALARM, &value, mask)); + tod_reg_val = BITFEXT(value, RTCALARM_TIME); + + mask = BITFMASK(RTCALARM_DAY); + CHECK_ERROR(pmic_read_reg(REG_RTC_DAY_ALARM, &value, mask)); + day_reg_val = BITFEXT(value, RTCALARM_DAY); + + time = (unsigned long)((unsigned long)(tod_reg_val & + 0x0001FFFF) + + (unsigned long)(day_reg_val * 86400)); + rtc_time_to_tm(time, &(alrm->time)); + + return 0; +} + +static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + unsigned int tod_reg_val = 0; + unsigned int day_reg_val = 0; + unsigned int mask, value; + unsigned long time; + + if (rtc_valid_tm(&alrm->time)) + return -1; + + rtc_tm_to_time(&alrm->time, &time); + + tod_reg_val = time % 86400; + day_reg_val = time / 86400; + + mask = BITFMASK(RTCALARM_TIME); + value = BITFVAL(RTCALARM_TIME, tod_reg_val); + CHECK_ERROR(pmic_write_reg(REG_RTC_ALARM, value, mask)); + + mask = BITFMASK(RTCALARM_DAY); + value = BITFVAL(RTCALARM_DAY, day_reg_val); + CHECK_ERROR(pmic_write_reg(REG_RTC_DAY_ALARM, value, mask)); + + return 0; +} + +struct rtc_drv_data { + struct rtc_device *rtc; + pmic_event_callback_t event; +}; + +static struct rtc_class_ops mxc_rtc_ops = { + .open = mxc_rtc_open, + .release = mxc_rtc_release, + .ioctl = mxc_rtc_ioctl, + .read_time = mxc_rtc_read_time, + .set_time = mxc_rtc_set_time, + .read_alarm = mxc_rtc_read_alarm, + .set_alarm = mxc_rtc_set_alarm, +}; + +static void mxc_rtc_alarm_int(void *data) +{ + struct rtc_drv_data *pdata = data; + + rtc_update_irq(pdata->rtc, 1, RTC_AF | RTC_IRQF); +} + +static int mxc_rtc_probe(struct platform_device *pdev) +{ + struct rtc_drv_data *pdata = NULL; + + printk(KERN_INFO "mc13892 rtc probe start\n"); + + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + + if (!pdata) + return -ENOMEM; + + pdata->event.func = mxc_rtc_alarm_int; + pdata->event.param = pdata; + CHECK_ERROR(pmic_event_subscribe(EVENT_TODAI, pdata->event)); + + device_init_wakeup(&pdev->dev, 1); + pdata->rtc = rtc_device_register(pdev->name, &pdev->dev, + &mxc_rtc_ops, THIS_MODULE); + + platform_set_drvdata(pdev, pdata); + if (IS_ERR(pdata->rtc)) + return -1; + + printk(KERN_INFO "mc13892 rtc probe succeed\n"); + return 0; +} + +static int __exit mxc_rtc_remove(struct platform_device *pdev) +{ + struct rtc_drv_data *pdata = platform_get_drvdata(pdev); + + rtc_device_unregister(pdata->rtc); + CHECK_ERROR(pmic_event_unsubscribe(EVENT_TODAI, pdata->event)); + + return 0; +} + +static struct platform_driver mxc_rtc_driver = { + .driver = { + .name = "pmic_rtc", + }, + .probe = mxc_rtc_probe, + .remove = __exit_p(mxc_rtc_remove), +}; + +static int __init mxc_rtc_init(void) +{ + return platform_driver_register(&mxc_rtc_driver); +} + +static void __exit mxc_rtc_exit(void) +{ + platform_driver_unregister(&mxc_rtc_driver); + +} + +module_init(mxc_rtc_init); +module_exit(mxc_rtc_exit); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("MC13892 Realtime Clock Driver (RTC)"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/i2c/i2c-core.c +++ linux-2.6.28/drivers/i2c/i2c-core.c @@ -1831,7 +1831,8 @@ case I2C_SMBUS_QUICK: msg[0].len = 0; /* Special case: The read/write field is used as data */ - msg[0].flags = flags | (read_write==I2C_SMBUS_READ)?I2C_M_RD:0; + msg[0].flags = flags | (read_write == I2C_SMBUS_READ ? + I2C_M_RD : 0); num = 1; break; case I2C_SMBUS_BYTE: --- linux-2.6.28.orig/drivers/i2c/i2c-dev.c +++ linux-2.6.28/drivers/i2c/i2c-dev.c @@ -614,6 +614,7 @@ "Simon G. Vogl "); MODULE_DESCRIPTION("I2C /dev entries driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS_CHARDEV_MAJOR(I2C_MAJOR); module_init(i2c_dev_init); module_exit(i2c_dev_exit); --- linux-2.6.28.orig/drivers/i2c/busses/i2c-piix4.c +++ linux-2.6.28/drivers/i2c/busses/i2c-piix4.c @@ -226,6 +226,70 @@ return 0; } +static int __devinit piix4_setup_sb800(struct pci_dev *PIIX4_dev, + const struct pci_device_id *id) +{ + unsigned short smba_idx = 0xcd6; + u8 smba_en_lo, smba_en_hi, i2ccfg, i2ccfg_offset = 0x10, smb_en = 0x2c; + + /* SB800 SMBus does not support forcing address */ + if (force || force_addr) { + dev_err(&PIIX4_dev->dev, "SB800 SMBus does not support " + "forcing address!\n"); + return -EINVAL; + } + + /* Determine the address of the SMBus areas */ + if (!request_region(smba_idx, 2, "smba_idx")) { + dev_err(&PIIX4_dev->dev, "SMBus base address index region " + "0x%x already in use!\n", smba_idx); + return -EBUSY; + } + outb_p(smb_en, smba_idx); + smba_en_lo = inb_p(smba_idx + 1); + outb_p(smb_en + 1, smba_idx); + smba_en_hi = inb_p(smba_idx + 1); + release_region(smba_idx, 2); + + if ((smba_en_lo & 1) == 0) { + dev_err(&PIIX4_dev->dev, + "Host SMBus controller not enabled!\n"); + return -ENODEV; + } + + piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0; + 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); + return -EBUSY; + } + + /* Request the SMBus I2C bus config region */ + if (!request_region(piix4_smba + i2ccfg_offset, 1, "i2ccfg")) { + dev_err(&PIIX4_dev->dev, "SMBus I2C bus config region " + "0x%x already in use!\n", piix4_smba + i2ccfg_offset); + release_region(piix4_smba, SMBIOSIZE); + piix4_smba = 0; + return -EBUSY; + } + i2ccfg = inb_p(piix4_smba + i2ccfg_offset); + release_region(piix4_smba + i2ccfg_offset, 1); + + if (i2ccfg & 1) + dev_dbg(&PIIX4_dev->dev, "Using IRQ for SMBus.\n"); + else + dev_dbg(&PIIX4_dev->dev, "Using SMI# for SMBus.\n"); + + dev_info(&PIIX4_dev->dev, + "SMBus Host Controller at 0x%x, revision %d\n", + piix4_smba, i2ccfg >> 4); + + return 0; +} + static int piix4_transaction(void) { int temp; @@ -434,7 +498,14 @@ { int retval; - retval = piix4_setup(dev, id); + if ((dev->vendor == PCI_VENDOR_ID_ATI) && + (dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS) && + (dev->revision >= 0x40)) + /* base address location etc changed in SB800 */ + retval = piix4_setup_sb800(dev, id); + else + retval = piix4_setup(dev, id); + if (retval) return retval; --- linux-2.6.28.orig/drivers/i2c/busses/mxc_i2c_hs_reg.h +++ linux-2.6.28/drivers/i2c/busses/mxc_i2c_hs_reg.h @@ -0,0 +1,97 @@ +/* + * Copyright 2008 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 __MXC_I2C_HS_REG_H__ +#define __MXC_I2C_HS_REG_H__ + +#define HISADR 0x00 + +#define HIMADR 0x04 +#define HIMADR_LSB_ADR(x) ((x) << 1) +#define HIMADR_MSB_ADR(x) (((x) & 0x7) << 8) + +#define HICR 0x08 +#define HICR_HIEN 0x1 +#define HICR_DMA_EN_RX 0x2 +#define HICR_DMA_EN_TR 0x4 +#define HICR_RSTA 0x8 +#define HICR_TXAK 0x10 +#define HICR_MTX 0x20 +#define HICR_MSTA 0x40 +#define HICR_HIIEN 0x80 +#define HICR_ADDR_MODE 0x100 +#define HICR_MST_CODE(x) (((x)&0x7) << 9) +#define HICR_HSM_EN 0x1000 +#define HICR_SAMC(x) (((x)&0x3) << 13) +#define SAMC_7_10 0 +#define SMAC_7 1 +#define SMAC_10 2 + +#define HISR 0x0c +#define HISR_RDF 0x1 +#define HISR_TDE 0x2 +#define HISR_HIAAS 0x4 +#define HISR_HIAL 0x8 +#define HISR_BTD 0x10 +#define HISR_RDC_ZERO 0x20 +#define HISR_TDC_ZERO 0x40 +#define HISR_RXAK 0x80 +#define HISR_HIBB 0x100 +#define HISR_SRW 0x200 +#define HISR_SADDR_MODE 0x400 +#define HISR_SHS_MODE 0x800 + +#define HIIMR 0x10 +#define HIIMR_RDF 0x1 +#define HIIMR_TDE 0x2 +#define HIIMR_AAS 0x4 +#define HIIMR_AL 0x8 +#define HIIMR_BTD 0x10 +#define HIIMR_RDC 0x20 +#define HIIMR_TDC 0x40 +#define HIIMR_RXAK 0x80 + +#define HITDR 0x14 + +#define HIRDR 0x18 + +#define HIFSFDR 0x1c + +#define HIHSFDR 0x20 + +#define HITFR 0x24 +#define HITFR_TFEN 0x1 +#define HITFR_TFLSH 0x2 +#define HITFR_TFWM(x) (((x) & 0x7) << 2) +#define HITFR_TFC(x) (((x) >> 8) & 0xF) +#define HITFR_MAX_COUNT 8 + +#define HIRFR 0x28 +#define HIRFR_RFEN 0x1 +#define HIRFR_RFLSH 0x2 +#define HIRFR_RFWM(x) (((x) & 0x7) << 2) +#define HIRFR_RFC(x) (((x) >> 8) & 0xF) +#define HIRFR_MAX_COUNT 8 + +#define HITDCR 0x2c +#define HITDCR_TDC(x) ((x) & 0xFF) +#define HITDCR_TDC_EN 0x100 +#define HITDCR_TDC_RSTA 0x200 +#define HITDCR_MAX_COUNT 0xFF + +#define HIRDCR 0x30 +#define HIRDCR_RDC(x) ((x) & 0xFF) +#define HIRDCR_RDC_EN 0x100 +#define HIRDCR_RDC_RSTA 0x200 +#define HIRDCR_MAX_COUNT 0xFF + +#endif --- linux-2.6.28.orig/drivers/i2c/busses/i2c-acorn.c +++ linux-2.6.28/drivers/i2c/busses/i2c-acorn.c @@ -84,6 +84,7 @@ static struct i2c_adapter ioc_ops = { .id = I2C_HW_B_IOC, + .nr = 0, .algo_data = &ioc_data, }; @@ -91,7 +92,7 @@ { force_ones = FORCE_ONES | SCL | SDA; - return i2c_bit_add_bus(&ioc_ops); + return i2c_bit_add_numbered_bus(&ioc_ops); } module_init(i2c_ioc_init); --- linux-2.6.28.orig/drivers/i2c/busses/mxc_i2c.c +++ linux-2.6.28/drivers/i2c/busses/mxc_i2c.c @@ -0,0 +1,789 @@ +/* + * Copyright 2004-2008 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 + */ + +/*! + * @file mxc_i2c.c + * + * @brief Driver for the Freescale Semiconductor MXC I2C buses. + * + * Based on i2c driver algorithm for PCF8584 adapters + * + * @ingroup MXCI2C + */ + +/* + * Include Files + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mxc_i2c_reg.h" + +/*! + * In case the MXC device has multiple I2C modules, this structure is used to + * store information specific to each I2C module. + */ +typedef struct { + /*! + * This structure is used to identify the physical i2c bus along with + * the access algorithms necessary to access it. + */ + struct i2c_adapter adap; + + /*! + * This waitqueue is used to wait for the data transfer to complete. + */ + wait_queue_head_t wq; + + /*! + * The base address of the I2C device. + */ + unsigned long membase; + + /*! + * The interrupt number used by the I2C device. + */ + int irq; + + /*! + * The default clock divider value to be used. + */ + unsigned int clkdiv; + + /*! + * The clock source for the device. + */ + struct clk *clk; + + /*! + * The current power state of the device + */ + bool low_power; + + /*! + * Boolean to indicate if data was transferred + */ + bool transfer_done; + + /*! + * Boolean to indicate if we received an ACK for the data transmitted + */ + bool tx_success; +} mxc_i2c_device; + +struct clk_div_table { + int reg_value; + int div; +}; + +static const struct clk_div_table i2c_clk_table[] = { + {0x20, 22}, {0x21, 24}, {0x22, 26}, {0x23, 28}, + {0, 30}, {1, 32}, {0x24, 32}, {2, 36}, + {0x25, 36}, {0x26, 40}, {3, 42}, {0x27, 44}, + {4, 48}, {0x28, 48}, {5, 52}, {0x29, 56}, + {6, 60}, {0x2A, 64}, {7, 72}, {0x2B, 72}, + {8, 80}, {0x2C, 80}, {9, 88}, {0x2D, 96}, + {0xA, 104}, {0x2E, 112}, {0xB, 128}, {0x2F, 128}, + {0xC, 144}, {0xD, 160}, {0x30, 160}, {0xE, 192}, + {0x31, 192}, {0x32, 224}, {0xF, 240}, {0x33, 256}, + {0x10, 288}, {0x11, 320}, {0x34, 320}, {0x12, 384}, + {0x35, 384}, {0x36, 448}, {0x13, 480}, {0x37, 512}, + {0x14, 576}, {0x15, 640}, {0x38, 640}, {0x16, 768}, + {0x39, 768}, {0x3A, 896}, {0x17, 960}, {0x3B, 1024}, + {0x18, 1152}, {0x19, 1280}, {0x3C, 1280}, {0x1A, 1536}, + {0x3D, 1536}, {0x3E, 1792}, {0x1B, 1920}, {0x3F, 2048}, + {0x1C, 2304}, {0x1D, 2560}, {0x1E, 3072}, {0x1F, 3840}, + {0, 0} +}; + +extern void gpio_i2c_active(int i2c_num); +extern void gpio_i2c_inactive(int i2c_num); + +/*! + * Transmit a \b STOP signal to the slave device. + * + * @param dev the mxc i2c structure used to get to the right i2c device + */ +static void mxc_i2c_stop(mxc_i2c_device * dev) +{ + unsigned int cr, sr; + int retry = 16; + + cr = readw(dev->membase + MXC_I2CR); + cr &= ~(MXC_I2CR_MSTA | MXC_I2CR_MTX); + writew(cr, dev->membase + MXC_I2CR); + + /* Wait till the Bus Busy bit is reset */ + sr = readw(dev->membase + MXC_I2SR); + while (retry-- && ((sr & MXC_I2SR_IBB))) { + udelay(3); + sr = readw(dev->membase + MXC_I2SR); + } + if (retry <= 0) + dev_err(&dev->adap.dev, "Could not set I2C Bus Busy bit" + " to zero.\n"); +} + +/*! + * Wait for the transmission of the data byte to complete. This function waits + * till we get a signal from the interrupt service routine indicating completion + * of the address cycle or we time out. + * + * @param dev the mxc i2c structure used to get to the right i2c device + * @param trans_flag transfer flag + * + * + * @return The function returns 0 on success or -1 if an ack was not received + */ + +static int mxc_i2c_wait_for_tc(mxc_i2c_device * dev, int trans_flag) +{ + int retry = 16; + + while (retry-- && !dev->transfer_done) { + wait_event_interruptible_timeout(dev->wq, + dev->transfer_done, + dev->adap.timeout); + } + dev->transfer_done = false; + + if (retry <= 0) { + /* Unable to send data */ + dev_err(&dev->adap.dev, "Data not transmitted\n"); + return -1; + } + + if (!dev->tx_success) { + /* An ACK was not received for transmitted byte */ + dev_err(&dev->adap.dev, "ACK not received \n"); + return -1; + } + + return 0; +} + +/*! + * Transmit a \b START signal to the slave device. + * + * @param dev the mxc i2c structure used to get to the right i2c device + * @param *msg pointer to a message structure that contains the slave + * address + * + * @return The function returns EBUSY on failure, 0 on success. + */ +static int mxc_i2c_start(mxc_i2c_device *dev, struct i2c_msg *msg) +{ + volatile unsigned int cr, sr; + unsigned int addr_trans; + int retry = 16; + + /* + * Set the slave address and the requested transfer mode + * in the data register + */ + addr_trans = msg->addr << 1; + if (msg->flags & I2C_M_RD) { + addr_trans |= 0x01; + } + + /* Set the Master bit */ + cr = readw(dev->membase + MXC_I2CR); + cr |= MXC_I2CR_MSTA; + writew(cr, dev->membase + MXC_I2CR); + + /* Wait till the Bus Busy bit is set */ + sr = readw(dev->membase + MXC_I2SR); + while (retry-- && (!(sr & MXC_I2SR_IBB))) { + udelay(3); + sr = readw(dev->membase + MXC_I2SR); + } + if (retry <= 0) { + dev_err(&dev->adap.dev, "Could not grab Bus ownership\n"); + return -EBUSY; + } + + /* Set the Transmit bit */ + cr = readw(dev->membase + MXC_I2CR); + cr |= MXC_I2CR_MTX; + writew(cr, dev->membase + MXC_I2CR); + + writew(addr_trans, dev->membase + MXC_I2DR); + return 0; +} + +/*! + * Transmit a \b REPEAT START to the slave device + * + * @param dev the mxc i2c structure used to get to the right i2c device + * @param *msg pointer to a message structure that contains the slave + * address + */ +static void mxc_i2c_repstart(mxc_i2c_device * dev, struct i2c_msg *msg) +{ + volatile unsigned int cr; + unsigned int addr_trans; + + /* + * Set the slave address and the requested transfer mode + * in the data register + */ + addr_trans = msg->addr << 1; + if (msg->flags & I2C_M_RD) { + addr_trans |= 0x01; + } + cr = readw(dev->membase + MXC_I2CR); + cr |= MXC_I2CR_RSTA; + writew(cr, dev->membase + MXC_I2CR); + udelay(3); + writew(addr_trans, dev->membase + MXC_I2DR); +} + +/*! + * Read the received data. The function waits till data is available or times + * out. Generates a stop signal if this is the last message to be received. + * Sends an ack for all the bytes received except the last byte. + * + * @param dev the mxc i2c structure used to get to the right i2c device + * @param *msg pointer to a message structure that contains the slave + * address and a pointer to the receive buffer + * @param last indicates that this is the last message to be received + * @param addr_comp flag indicates that we just finished the address cycle + * + * @return The function returns the number of bytes read or -1 on time out. + */ +static int mxc_i2c_readbytes(mxc_i2c_device * dev, struct i2c_msg *msg, + int last, int addr_comp) +{ + int i; + char *buf = msg->buf; + int len = msg->len; + volatile unsigned int cr; + + cr = readw(dev->membase + MXC_I2CR); + /* + * Clear MTX to switch to receive mode. + */ + cr &= ~MXC_I2CR_MTX; + /* + * Clear the TXAK bit to gen an ack when receiving only one byte. + */ + if (len == 1) { + cr |= MXC_I2CR_TXAK; + } else { + cr &= ~MXC_I2CR_TXAK; + } + writew(cr, dev->membase + MXC_I2CR); + /* + * Dummy read only at the end of an address cycle + */ + if (addr_comp > 0) { + readw(dev->membase + MXC_I2DR); + } + + for (i = 0; i < len; i++) { + /* + * Wait for data transmission to complete + */ + if (mxc_i2c_wait_for_tc(dev, msg->flags)) { + mxc_i2c_stop(dev); + return -1; + } + /* + * Do not generate an ACK for the last byte + */ + if (i == (len - 2)) { + cr = readw(dev->membase + MXC_I2CR); + cr |= MXC_I2CR_TXAK; + writew(cr, dev->membase + MXC_I2CR); + } else if (i == (len - 1)) { + if (last) { + mxc_i2c_stop(dev); + } + } + /* Read the data */ + *buf++ = readw(dev->membase + MXC_I2DR); + } + + return i; +} + +/*! + * Write the data to the data register. Generates a stop signal if this is + * the last message to be sent or if no ack was received for the data sent. + * + * @param dev the mxc i2c structure used to get to the right i2c device + * @param *msg pointer to a message structure that contains the slave + * address and data to be sent + * @param last indicates that this is the last message to be received + * + * @return The function returns the number of bytes written or -1 on time out + * or if no ack was received for the data that was sent. + */ +static int mxc_i2c_writebytes(mxc_i2c_device * dev, struct i2c_msg *msg, + int last) +{ + int i; + char *buf = msg->buf; + int len = msg->len; + volatile unsigned int cr; + + cr = readw(dev->membase + MXC_I2CR); + /* Set MTX to switch to transmit mode */ + cr |= MXC_I2CR_MTX; + writew(cr, dev->membase + MXC_I2CR); + + for (i = 0; i < len; i++) { + /* + * Write the data + */ + writew(*buf++, dev->membase + MXC_I2DR); + if (mxc_i2c_wait_for_tc(dev, msg->flags)) { + mxc_i2c_stop(dev); + return -1; + } + } + if (last > 0) { + mxc_i2c_stop(dev); + } + + return i; +} + +/*! + * Function enables the I2C module and initializes the registers. + * + * @param dev the mxc i2c structure used to get to the right i2c device + * @param trans_flag transfer flag + */ +static void mxc_i2c_module_en(mxc_i2c_device * dev, int trans_flag) +{ + clk_enable(dev->clk); + /* Set the frequency divider */ + writew(dev->clkdiv, dev->membase + MXC_IFDR); + /* Clear the status register */ + writew(0x0, dev->membase + MXC_I2SR); + /* Enable I2C and its interrupts */ + writew(MXC_I2CR_IEN, dev->membase + MXC_I2CR); + writew(MXC_I2CR_IEN | MXC_I2CR_IIEN, dev->membase + MXC_I2CR); +} + +/*! + * Disables the I2C module. + * + * @param dev the mxc i2c structure used to get to the right i2c device + */ +static void mxc_i2c_module_dis(mxc_i2c_device * dev) +{ + writew(0x0, dev->membase + MXC_I2CR); + clk_disable(dev->clk); +} + +/*! + * The function is registered in the adapter structure. It is called when an MXC + * driver wishes to transfer data to a device connected to the I2C device. + * + * @param adap adapter structure for the MXC i2c device + * @param msgs[] array of messages to be transferred to the device + * @param num number of messages to be transferred to the device + * + * @return The function returns the number of messages transferred, + * \b -EREMOTEIO on I2C failure and a 0 if the num argument is + * less than 0. + */ +static int mxc_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], + int num) +{ + mxc_i2c_device *dev = (mxc_i2c_device *) (i2c_get_adapdata(adap)); + int i, ret = 0, addr_comp = 0; + volatile unsigned int sr; + int retry = 5; + + if (dev->low_power) { + dev_err(&dev->adap.dev, "I2C Device in low power mode\n"); + return -EREMOTEIO; + } + + if (num < 1) { + return 0; + } + + mxc_i2c_module_en(dev, msgs[0].flags); + sr = readw(dev->membase + MXC_I2SR); + /* + * Check bus state + */ + + while ((sr & MXC_I2SR_IBB) && retry--) { + udelay(5); + sr = readw(dev->membase + MXC_I2SR); + } + + if ((sr & MXC_I2SR_IBB) && retry < 0) { + mxc_i2c_module_dis(dev); + dev_err(&dev->adap.dev, "Bus busy\n"); + return -EREMOTEIO; + } + + //gpio_i2c_active(dev->adap.id); + dev->transfer_done = false; + dev->tx_success = false; + for (i = 0; i < num && ret >= 0; i++) { + addr_comp = 0; + /* + * Send the slave address and transfer direction in the + * address cycle + */ + if (i == 0) { + /* + * Send a start or repeat start signal + */ + if (mxc_i2c_start(dev, &msgs[0])) + return -EREMOTEIO; + /* Wait for the address cycle to complete */ + if (mxc_i2c_wait_for_tc(dev, msgs[0].flags)) { + mxc_i2c_stop(dev); + //gpio_i2c_inactive(dev->adap.id); + mxc_i2c_module_dis(dev); + return -EREMOTEIO; + } + addr_comp = 1; + } else { + /* + * Generate repeat start only if required i.e the address + * changed or the transfer direction changed + */ + if ((msgs[i].addr != msgs[i - 1].addr) || + ((msgs[i].flags & I2C_M_RD) != + (msgs[i - 1].flags & I2C_M_RD))) { + mxc_i2c_repstart(dev, &msgs[i]); + /* Wait for the address cycle to complete */ + if (mxc_i2c_wait_for_tc(dev, msgs[i].flags)) { + mxc_i2c_stop(dev); + //gpio_i2c_inactive(dev->adap.id); + mxc_i2c_module_dis(dev); + return -EREMOTEIO; + } + addr_comp = 1; + } + } + + /* Transfer the data */ + if (msgs[i].flags & I2C_M_RD) { + /* Read the data */ + ret = mxc_i2c_readbytes(dev, &msgs[i], (i + 1 == num), + addr_comp); + if (ret < 0) { + dev_err(&dev->adap.dev, "mxc_i2c_readbytes:" + " fail.\n"); + break; + } + } else { + /* Write the data */ + ret = mxc_i2c_writebytes(dev, &msgs[i], (i + 1 == num)); + if (ret < 0) { + dev_err(&dev->adap.dev, "mxc_i2c_writebytes:" + " fail.\n"); + break; + } + } + } + + //gpio_i2c_inactive(dev->adap.id); + mxc_i2c_module_dis(dev); + /* + * Decrease by 1 as we do not want Start message to be included in + * the count + */ + return (i < 0 ? ret : i); +} + +/*! + * Returns the i2c functionality supported by this driver. + * + * @param adap adapter structure for this i2c device + * + * @return Returns the functionality that is supported. + */ +static u32 mxc_i2c_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +/*! + * Stores the pointers for the i2c algorithm functions. The algorithm functions + * is used by the i2c bus driver to talk to the i2c bus + */ +static struct i2c_algorithm mxc_i2c_algorithm = { + .master_xfer = mxc_i2c_xfer, + .functionality = mxc_i2c_func +}; + +/*! + * Interrupt Service Routine. It signals to the process about the data transfer + * completion. Also sets a flag if bus arbitration is lost. + * @param irq the interrupt number + * @param dev_id driver private data + * + * @return The function returns \b IRQ_HANDLED. + */ +static irqreturn_t mxc_i2c_handler(int irq, void *dev_id) +{ + mxc_i2c_device *dev = dev_id; + volatile unsigned int sr, cr; + + sr = readw(dev->membase + MXC_I2SR); + cr = readw(dev->membase + MXC_I2CR); + + /* + * Clear the interrupt bit + */ + writew(0x0, dev->membase + MXC_I2SR); + + if (sr & MXC_I2SR_IAL) { + dev_err(&dev->adap.dev, "Bus Arbitration lost\n"); + } else { + /* Interrupt due byte transfer completion */ + dev->tx_success = true; + /* Check if RXAK is received in Transmit mode */ + if ((cr & MXC_I2CR_MTX) && (sr & MXC_I2SR_RXAK)) { + dev->tx_success = false; + } + dev->transfer_done = true; + wake_up_interruptible(&dev->wq); + } + + return IRQ_HANDLED; +} + +/*! + * This function is called to put the I2C adapter in a low power state. Refer to the + * document driver-model/driver.txt in the kernel source tree for more + * information. + * + * @param pdev the device structure used to give information on which I2C + * to suspend + * @param state the power state the device is entering + * + * @return The function returns 0 on success and -1 on failure. + */ +static int mxci2c_suspend(struct platform_device *pdev, pm_message_t state) +{ + mxc_i2c_device *mxcdev = platform_get_drvdata(pdev); + volatile unsigned int sr = 0; + + if (mxcdev == NULL) { + return -1; + } + + /* Prevent further calls to be processed */ + mxcdev->low_power = true; + /* Wait till we finish the current transfer */ + sr = readw(mxcdev->membase + MXC_I2SR); + while (sr & MXC_I2SR_IBB) { + msleep(10); + sr = readw(mxcdev->membase + MXC_I2SR); + } + gpio_i2c_inactive(mxcdev->adap.id); + + return 0; +} + +/*! + * This function is called to bring the I2C adapter back from a low power state. Refer + * to the document driver-model/driver.txt in the kernel source tree for more + * information. + * + * @param pdev the device structure used to give information on which I2C + * to resume + * + * @return The function returns 0 on success and -1 on failure + */ +static int mxci2c_resume(struct platform_device *pdev) +{ + mxc_i2c_device *mxcdev = platform_get_drvdata(pdev); + + if (mxcdev == NULL) + return -1; + + mxcdev->low_power = false; + gpio_i2c_active(mxcdev->adap.id); + + return 0; +} + +/*! + * This function is called during the driver binding process. + * + * @param pdev the device structure used to store device specific + * information that is used by the suspend, resume and remove + * functions + * + * @return The function always returns 0. + */ +static int mxci2c_probe(struct platform_device *pdev) +{ + mxc_i2c_device *mxc_i2c; + struct mxc_i2c_platform_data *i2c_plat_data = pdev->dev.platform_data; + struct resource *res; + int id = pdev->id; + u32 clk_freq; + int ret = 0; + int i; + + mxc_i2c = kzalloc(sizeof(mxc_i2c_device), GFP_KERNEL); + if (!mxc_i2c) { + return -ENOMEM; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) { + ret = -ENODEV; + goto err1; + } + mxc_i2c->membase = IO_ADDRESS(res->start); + + /* + * Request the I2C interrupt + */ + mxc_i2c->irq = platform_get_irq(pdev, 0); + if (mxc_i2c->irq < 0) { + ret = mxc_i2c->irq; + goto err1; + } + + ret = request_irq(mxc_i2c->irq, mxc_i2c_handler, + 0, pdev->name, mxc_i2c); + if (ret < 0) { + goto err1; + } + + init_waitqueue_head(&mxc_i2c->wq); + + mxc_i2c->low_power = false; + + gpio_i2c_active(id); + + mxc_i2c->clk = clk_get(&pdev->dev, "i2c_clk"); + clk_freq = clk_get_rate(mxc_i2c->clk); + mxc_i2c->clkdiv = -1; + if (i2c_plat_data->i2c_clk) { + /* Calculate divider and round up any fractional part */ + int div = (clk_freq + i2c_plat_data->i2c_clk - 1) / + i2c_plat_data->i2c_clk; + for (i = 0; i2c_clk_table[i].div != 0; i++) { + if (i2c_clk_table[i].div >= div) { + mxc_i2c->clkdiv = i2c_clk_table[i].reg_value; + break; + } + } + } + if (mxc_i2c->clkdiv == -1) { + i--; + mxc_i2c->clkdiv = 0x1F; /* Use max divider */ + } + dev_dbg(&pdev->dev, "i2c speed is %d/%d = %d bps, reg val = 0x%02X\n", + clk_freq, i2c_clk_table[i].div, + clk_freq / i2c_clk_table[i].div, mxc_i2c->clkdiv); + + /* + * Set the adapter information + */ + strlcpy(mxc_i2c->adap.name, pdev->name, 48); + mxc_i2c->adap.id = mxc_i2c->adap.nr = id; + mxc_i2c->adap.algo = &mxc_i2c_algorithm; + mxc_i2c->adap.timeout = 1; + platform_set_drvdata(pdev, mxc_i2c); + i2c_set_adapdata(&mxc_i2c->adap, mxc_i2c); + if ((ret = i2c_add_numbered_adapter(&mxc_i2c->adap)) < 0) { + goto err2; + } + + printk(KERN_INFO "MXC I2C driver\n"); + return 0; + + err2: + free_irq(mxc_i2c->irq, mxc_i2c); + gpio_i2c_inactive(id); + err1: + dev_err(&pdev->dev, "failed to probe i2c adapter\n"); + kfree(mxc_i2c); + return ret; +} + +/*! + * Dissociates the driver from the I2C device. + * + * @param pdev the device structure used to give information on which I2C + * to remove + * + * @return The function always returns 0. + */ +static int mxci2c_remove(struct platform_device *pdev) +{ + mxc_i2c_device *mxc_i2c = platform_get_drvdata(pdev); + int id = pdev->id; + + free_irq(mxc_i2c->irq, mxc_i2c); + i2c_del_adapter(&mxc_i2c->adap); + gpio_i2c_inactive(id); + clk_put(mxc_i2c->clk); + platform_set_drvdata(pdev, NULL); + return 0; +} + +/*! + * This structure contains pointers to the power management callback functions. + */ +static struct platform_driver mxci2c_driver = { + .driver = { + .name = "mxc_i2c", + .owner = THIS_MODULE, + }, + .probe = mxci2c_probe, + .remove = mxci2c_remove, + .suspend = mxci2c_suspend, + .resume = mxci2c_resume, +}; + +/*! + * Function requests the interrupts and registers the i2c adapter structures. + * + * @return The function returns 0 on success and a non-zero value on failure. + */ +static int __init mxc_i2c_init(void) +{ + /* Register the device driver structure. */ + return platform_driver_register(&mxci2c_driver); +} + +/*! + * This function is used to cleanup all resources before the driver exits. + */ +static void __exit mxc_i2c_exit(void) +{ + platform_driver_unregister(&mxci2c_driver); +} + +subsys_initcall(mxc_i2c_init); +module_exit(mxc_i2c_exit); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("MXC I2C driver"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/i2c/busses/Kconfig +++ linux-2.6.28/drivers/i2c/busses/Kconfig @@ -391,9 +391,28 @@ This driver can also be built as a module. If so, the module will be called i2c-mpc. +config I2C_MXC + tristate "MXC I2C support" + depends on I2C && ARCH_MXC + help + If you say yes to this option, support will be included for Freescale + MXC I2C modules. + + This driver can also be built as a module. + +config I2C_MXC_HS + tristate "MXC HIGH SPEED I2C support" + depends on I2C && ARCH_MXC + help + If you say yes to this option, support will be included for Freescale + MXC HIGH SPEED I2C modules. + + This driver can also be built as a module. + 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. --- linux-2.6.28.orig/drivers/i2c/busses/mxc_i2c_reg.h +++ linux-2.6.28/drivers/i2c/busses/mxc_i2c_reg.h @@ -0,0 +1,40 @@ +/* + * Copyright 2004-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 __MXC_I2C_REG_H__ +#define __MXC_I2C_REG_H__ + +/* Address offsets of the I2C registers */ +#define MXC_IADR 0x00 /* Address Register */ +#define MXC_IFDR 0x04 /* Freq div register */ +#define MXC_I2CR 0x08 /* Control regsiter */ +#define MXC_I2SR 0x0C /* Status register */ +#define MXC_I2DR 0x10 /* Data I/O register */ + +/* Bit definitions of I2CR */ +#define MXC_I2CR_IEN 0x0080 +#define MXC_I2CR_IIEN 0x0040 +#define MXC_I2CR_MSTA 0x0020 +#define MXC_I2CR_MTX 0x0010 +#define MXC_I2CR_TXAK 0x0008 +#define MXC_I2CR_RSTA 0x0004 + +/* Bit definitions of I2SR */ +#define MXC_I2SR_ICF 0x0080 +#define MXC_I2SR_IAAS 0x0040 +#define MXC_I2SR_IBB 0x0020 +#define MXC_I2SR_IAL 0x0010 +#define MXC_I2SR_SRW 0x0004 +#define MXC_I2SR_IIF 0x0002 +#define MXC_I2SR_RXAK 0x0001 + +#endif /* __MXC_I2C_REG_H__ */ --- linux-2.6.28.orig/drivers/i2c/busses/Makefile +++ linux-2.6.28/drivers/i2c/busses/Makefile @@ -67,6 +67,8 @@ obj-$(CONFIG_I2C_STUB) += i2c-stub.o obj-$(CONFIG_SCx200_ACB) += scx200_acb.o obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o +obj-$(CONFIG_I2C_MXC) += mxc_i2c.o +obj-$(CONFIG_I2C_MXC_HS) += mxc_i2c_hs.o ifeq ($(CONFIG_I2C_DEBUG_BUS),y) EXTRA_CFLAGS += -DDEBUG --- linux-2.6.28.orig/drivers/i2c/busses/i2c-pxa.c +++ linux-2.6.28/drivers/i2c/busses/i2c-pxa.c @@ -644,7 +644,7 @@ i2c_pxa_start_message(i2c); - while (timeout-- && i2c->msg_num > 0) { + while (i2c->msg_num > 0 && --timeout) { i2c_pxa_handler(0, i2c); udelay(10); } --- linux-2.6.28.orig/drivers/i2c/busses/mxc_i2c_hs.c +++ linux-2.6.28/drivers/i2c/busses/mxc_i2c_hs.c @@ -0,0 +1,549 @@ +/* + * Copyright 2008 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mxc_i2c_hs_reg.h" + +typedef struct { + struct device *dev; + + unsigned long reg_base_virt; + unsigned long reg_base_phy; + int irq; + unsigned int speed; + struct clk *ipg_clk; + struct clk *serial_clk; + bool low_power; + + struct i2c_msg *msg; + int index; +} mxc_i2c_hs; + +struct clk_div_table { + int reg_value; + int div; +}; + +static const struct clk_div_table i2c_clk_table[] = { + {0x0, 16}, {0x1, 18}, {0x2, 20}, {0x3, 22}, + {0x20, 24}, {0x21, 26}, {0x22, 28}, {0x23, 30}, + {0x4, 32}, {0x5, 36}, {0x6, 40}, {0x7, 44}, + {0x24, 48}, {0x25, 52}, {0x26, 56}, {0x27, 60}, + {0x8, 64}, {0x9, 72}, {0xa, 80}, {0xb, 88}, + {0x28, 96}, {0x29, 104}, {0x2a, 112}, {0x2b, 120}, + {0xc, 128}, {0xd, 144}, {0xe, 160}, {0xf, 176}, + {0x2c, 192}, {0x2d, 208}, {0x2e, 224}, {0x2f, 240}, + {0x10, 256}, {0x11, 288}, {0x12, 320}, {0x13, 352}, + {0x30, 384}, {0x31, 416}, {0x32, 448}, {0x33, 480}, + {0x14, 512}, {0x15, 576}, {0x16, 640}, {0x17, 704}, + {0x34, 768}, {0x35, 832}, {0x36, 896}, {0x37, 960}, + {0x18, 1024}, {0x19, 1152}, {0x1a, 1280}, {0x1b, 1408}, + {0x38, 1536}, {0x39, 1664}, {0x3a, 1792}, {0x3b, 1920}, + {0x1c, 2048}, {0x1d, 2304}, {0x1e, 2560}, {0x1f, 2816}, + {0x3c, 3072}, {0x3d, 3328}, {0x3E, 3584}, {0x3F, 3840}, + {-1, -1} +}; + +static struct i2c_adapter *adap; + +extern void gpio_i2c_hs_inactive(void); +extern void gpio_i2c_hs_active(void); + +static u16 reg_read(mxc_i2c_hs *i2c_hs, u32 reg_offset) +{ + return __raw_readw(i2c_hs->reg_base_virt + reg_offset); +} + +static void reg_write(mxc_i2c_hs *i2c_hs, u32 reg_offset, u16 data) +{ + __raw_writew(data, i2c_hs->reg_base_virt + reg_offset); +} + +static void reg_set_mask(mxc_i2c_hs *i2c_hs, u32 reg_offset, u16 mask) +{ + u16 value; + + value = reg_read(i2c_hs, reg_offset); + value |= mask; + reg_write(i2c_hs, reg_offset, value); +} +static void reg_clear_mask(mxc_i2c_hs *i2c_hs, u32 reg_offset, u16 mask) +{ + u16 value; + + value = reg_read(i2c_hs, reg_offset); + value &= ~mask; + reg_write(i2c_hs, reg_offset, value); +} + +static void mxci2c_hs_set_div(mxc_i2c_hs *i2c_hs) +{ + unsigned long clk_freq; + int i; + int div = -1;; + + clk_freq = clk_get_rate(i2c_hs->serial_clk); + if (i2c_hs->speed) { + div = (clk_freq + i2c_hs->speed - 1) / i2c_hs->speed; + for (i = 0; i2c_clk_table[i].div >= 0; i++) { + if (i2c_clk_table[i].div >= div) { + div = i2c_clk_table[i].reg_value; + reg_write(i2c_hs, HIFSFDR, div); + break; + } + } + } +} + +static int mxci2c_hs_enable(mxc_i2c_hs *i2c_hs) +{ + gpio_i2c_hs_active(); + clk_enable(i2c_hs->ipg_clk); + clk_enable(i2c_hs->serial_clk); + mxci2c_hs_set_div(i2c_hs); + reg_write(i2c_hs, HICR, reg_read(i2c_hs, HICR) | HICR_HIEN); + + return 0; +} + +static int mxci2c_hs_disable(mxc_i2c_hs *i2c_hs) +{ + reg_write(i2c_hs, HICR, reg_read(i2c_hs, HICR) & (~HICR_HIEN)); + clk_disable(i2c_hs->ipg_clk); + clk_disable(i2c_hs->serial_clk); + + return 0; +} + +static int mxci2c_hs_bus_busy(mxc_i2c_hs *i2c_hs) +{ + u16 value; + int retry = 1000; + + while (retry--) { + value = reg_read(i2c_hs, HISR); + if (value & HISR_HIBB) { + udelay(1); + } else { + break; + } + } + + if (retry <= 0) { + dev_dbg(NULL, "%s: Bus Busy!\n", __func__); + return 1; + } else { + return 0; + } +} + +static int mxci2c_hs_start(mxc_i2c_hs *i2c_hs, int repeat_start, u16 address) +{ + u16 mask; + int ret = 0; + + mxci2c_hs_bus_busy(i2c_hs); + + /*7 bit address */ + reg_clear_mask(i2c_hs, HICR, HICR_ADDR_MODE); + + /*send start */ + if (repeat_start) + mask = HICR_RSTA; + else + mask = HICR_MSTA; + reg_set_mask(i2c_hs, HICR, mask); + + return ret; +} + +static int mxci2c_hs_stop(mxc_i2c_hs *i2c_hs) +{ + reg_clear_mask(i2c_hs, HICR, HICR_MSTA); + reg_clear_mask(i2c_hs, HICR, HICR_HIIEN); + + return 0; +} + +static int mxci2c_wait_writefifo(mxc_i2c_hs *i2c_hs) +{ + int i, num, left; + int retry, ret = 0; + + retry = 10000; + while (retry--) { + udelay(10); + if (reg_read(i2c_hs, HISR) & (HISR_TDE | HISR_TDC_ZERO)) { + if (i2c_hs->index < i2c_hs->msg->len) { + left = i2c_hs->msg->len - i2c_hs->index; + num = + (left > + HITFR_MAX_COUNT) ? HITFR_MAX_COUNT : left; + for (i = 0; i < num; i++) { + reg_write(i2c_hs, HITDR, + i2c_hs->msg->buf[i2c_hs-> + index + i]); + } + i2c_hs->index += num; + } else { + if (reg_read(i2c_hs, HISR) & HISR_TDC_ZERO) { + msleep(1); + break; + } + } + } + } + + if (retry <= 0) { + printk(KERN_ERR "%s:wait error\n", __func__); + ret = -1; + } + + return ret; +} + +static int mxci2c_wait_readfifo(mxc_i2c_hs *i2c_hs) +{ + int i, num, left; + int retry, ret = 0; + u16 value; + + retry = 10000; + while (retry--) { + udelay(10); + value = reg_read(i2c_hs, HISR); + if (value & (HISR_RDF | HISR_RDC_ZERO)) { + if (i2c_hs->index < i2c_hs->msg->len) { + left = i2c_hs->msg->len - i2c_hs->index; + num = + (left > + HITFR_MAX_COUNT) ? HITFR_MAX_COUNT : left; + for (i = 0; i < num; i++) { + i2c_hs->msg->buf[i2c_hs->index + i] = + reg_read(i2c_hs, HIRDR); + } + i2c_hs->index += num; + } else { + if (value & HISR_RDC_ZERO) { + break; + } + } + } + } + + if (retry <= 0) { + printk(KERN_ERR "%s:wait error\n", __func__); + ret = -1; + } + + return ret; +} + +static int mxci2c_hs_read(mxc_i2c_hs *i2c_hs, int repeat_start, + struct i2c_msg *msg) +{ + int ret; + + if (msg->len > HIRDCR_MAX_COUNT) { + printk(KERN_ERR "%s: error: msg too long, max longth 256\n", + __func__); + return -1; + } + + ret = 0; + i2c_hs->msg = msg; + i2c_hs->index = 0; + + /*set address */ + reg_write(i2c_hs, HIMADR, HIMADR_LSB_ADR(msg->addr)); + + /*receive mode */ + reg_clear_mask(i2c_hs, HICR, HICR_MTX); + + reg_clear_mask(i2c_hs, HICR, HICR_HIIEN); + + /*FIFO*/ reg_set_mask(i2c_hs, HIRFR, HIRFR_RFEN | HIRFR_RFWM(7)); + reg_set_mask(i2c_hs, HIRFR, HIRFR_RFLSH); + + /*TDCR*/ + reg_write(i2c_hs, HIRDCR, HIRDCR_RDC_EN | HIRDCR_RDC(msg->len)); + + mxci2c_hs_start(i2c_hs, repeat_start, msg->addr); + + ret = mxci2c_wait_readfifo(i2c_hs); + + if (ret < 0) + return ret; + else + return msg->len; +} + +static int mxci2c_hs_write(mxc_i2c_hs *i2c_hs, int repeat_start, + struct i2c_msg *msg) +{ + int ret, i; + + if (msg->len > HITDCR_MAX_COUNT) { + printk(KERN_ERR "%s: error: msg too long, max longth 256\n", + __func__); + return -1; + } + + ret = 0; + i2c_hs->msg = msg; + i2c_hs->index = 0; + + /*set address */ + reg_write(i2c_hs, HIMADR, HIMADR_LSB_ADR(msg->addr)); + + /*transmit mode */ + reg_set_mask(i2c_hs, HICR, HICR_MTX); + + reg_clear_mask(i2c_hs, HICR, HICR_HIIEN); + + /* TDCR */ + reg_write(i2c_hs, HITDCR, HITDCR_TDC_EN | HITDCR_TDC(msg->len)); + + /* FIFO */ + reg_set_mask(i2c_hs, HITFR, HITFR_TFEN); + reg_set_mask(i2c_hs, HITFR, HITFR_TFLSH); + + if (msg->len > HITFR_MAX_COUNT) + i2c_hs->index = HITFR_MAX_COUNT; + else { + i2c_hs->index = msg->len; + } + + for (i = 0; i < i2c_hs->index; i++) { + reg_write(i2c_hs, HITDR, msg->buf[i]); + } + + mxci2c_hs_start(i2c_hs, repeat_start, msg->addr); + + ret = mxci2c_wait_writefifo(i2c_hs); + + if (ret < 0) + return ret; + else + return msg->len; +} + +static int mxci2c_hs_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], + int num) +{ + int i; + int ret = -EIO; + + mxc_i2c_hs *i2c_hs = (mxc_i2c_hs *) (i2c_get_adapdata(adap)); + + if (i2c_hs->low_power) { + dev_err(&adap->dev, "I2C Device in low power mode\n"); + return -EREMOTEIO; + } + + if (num < 1) { + return 0; + } + + mxci2c_hs_enable(i2c_hs); + + for (i = 0; i < num; i++) { + if (msgs[i].flags & I2C_M_RD) { + ret = mxci2c_hs_read(i2c_hs, 0, &msgs[i]); + if (ret < 0) + break; + } else { + ret = mxci2c_hs_write(i2c_hs, 0, &msgs[i]); + if (ret < 0) + break; + } + mxci2c_hs_stop(i2c_hs); + } + mxci2c_hs_stop(i2c_hs); + + mxci2c_hs_disable(i2c_hs); + + if (ret < 0) + return ret; + + return i; +} + +static u32 mxci2c_hs_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + +/*! + * Stores the pointers for the i2c algorithm functions. The algorithm functions + * is used by the i2c bus driver to talk to the i2c bus + */ +static struct i2c_algorithm mxci2c_hs_algorithm = { + .master_xfer = mxci2c_hs_xfer, + .functionality = mxci2c_hs_func +}; + +static int mxci2c_hs_probe(struct platform_device *pdev) +{ + mxc_i2c_hs *i2c_hs; + struct mxc_i2c_platform_data *i2c_plat_data = pdev->dev.platform_data; + struct resource *res; + int id = pdev->id; + int ret = 0; + + i2c_hs = kzalloc(sizeof(mxc_i2c_hs), GFP_KERNEL); + if (!i2c_hs) { + return -ENOMEM; + } + + i2c_hs->dev = &pdev->dev; + + i2c_hs->speed = i2c_plat_data->i2c_clk; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) { + ret = -ENODEV; + goto err1; + } + i2c_hs->reg_base_virt = IO_ADDRESS(res->start); + i2c_hs->reg_base_phy = res->start; + + i2c_hs->ipg_clk = clk_get(&pdev->dev, "hsi2c_clk"); + i2c_hs->serial_clk = clk_get(&pdev->dev, "hsi2c_serial_clk"); + + /* + * Request the I2C interrupt + */ + i2c_hs->irq = platform_get_irq(pdev, 0); + if (i2c_hs->irq < 0) { + ret = i2c_hs->irq; + goto err1; + } + + i2c_hs->low_power = false; + + /* + * Set the adapter information + */ + adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL); + if (!adap) { + ret = -ENODEV; + goto err1; + } + strlcpy(adap->name, pdev->name, 48); + adap->id = adap->nr = id; + adap->algo = &mxci2c_hs_algorithm; + adap->timeout = 1; + platform_set_drvdata(pdev, i2c_hs); + i2c_set_adapdata(adap, i2c_hs); + ret = i2c_add_numbered_adapter(adap); + if (ret < 0) { + goto err2; + } + + printk(KERN_INFO "MXC HS I2C driver\n"); + return 0; + + err2: + kfree(adap); + err1: + dev_err(&pdev->dev, "failed to probe high speed i2c adapter\n"); + kfree(i2c_hs); + return ret; +} + +static int mxci2c_hs_suspend(struct platform_device *pdev, pm_message_t state) +{ + mxc_i2c_hs *i2c_hs = platform_get_drvdata(pdev); + + if (i2c_hs == NULL) { + return -1; + } + + /* Prevent further calls to be processed */ + i2c_hs->low_power = true; + + gpio_i2c_hs_inactive(); + + return 0; +} + +static int mxci2c_hs_resume(struct platform_device *pdev) +{ + mxc_i2c_hs *i2c_hs = platform_get_drvdata(pdev); + + if (i2c_hs == NULL) + return -1; + + i2c_hs->low_power = false; + gpio_i2c_hs_active(); + + return 0; +} + +static int mxci2c_hs_remove(struct platform_device *pdev) +{ + mxc_i2c_hs *i2c_hs = platform_get_drvdata(pdev); + + i2c_del_adapter(adap); + gpio_i2c_hs_inactive(); + platform_set_drvdata(pdev, NULL); + kfree(i2c_hs); + return 0; +} + +static struct platform_driver mxci2c_hs_driver = { + .driver = { + .name = "mxc_i2c_hs", + .owner = THIS_MODULE, + }, + .probe = mxci2c_hs_probe, + .remove = mxci2c_hs_remove, + .suspend = mxci2c_hs_suspend, + .resume = mxci2c_hs_resume, +}; + +/*! + * Function requests the interrupts and registers the i2c adapter structures. + * + * @return The function returns 0 on success and a non-zero value on failure. + */ +static int __init mxci2c_hs_init(void) +{ + /* Register the device driver structure. */ + return platform_driver_register(&mxci2c_hs_driver); +} + +/*! + * This function is used to cleanup all resources before the driver exits. + */ +static void __exit mxci2c_hs_exit(void) +{ + platform_driver_unregister(&mxci2c_hs_driver); +} + +subsys_initcall(mxci2c_hs_init); +module_exit(mxci2c_hs_exit); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("MXC HIGH SPEED I2C driver"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/i2c/busses/i2c-amd8111.c +++ linux-2.6.28/drivers/i2c/busses/i2c-amd8111.c @@ -72,7 +72,7 @@ { int timeout = 500; - while (timeout-- && (inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_IBF)) + while ((inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_IBF) && --timeout) udelay(1); if (!timeout) { @@ -88,7 +88,7 @@ { int timeout = 500; - while (timeout-- && (~inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_OBF)) + while ((~inb(smbus->base + AMD_EC_SC) & AMD_EC_SC_OBF) && --timeout) udelay(1); if (!timeout) { --- linux-2.6.28.orig/drivers/atm/fore200e.c +++ linux-2.6.28/drivers/atm/fore200e.c @@ -2519,8 +2519,8 @@ return err; sprintf(buf, "%s%s", fore200e->bus->proc_name, FW_EXT); - if (request_firmware(&firmware, buf, device) == 1) { - printk(FORE200E "missing %s firmware image\n", fore200e->bus->model_name); + if ((err = request_firmware(&firmware, buf, device)) < 0) { + printk(FORE200E "problem loading firmware image %s\n", fore200e->bus->model_name); return err; } --- linux-2.6.28.orig/drivers/block/nbd.c +++ linux-2.6.28/drivers/block/nbd.c @@ -56,7 +56,7 @@ static unsigned int nbds_max = 16; static struct nbd_device *nbd_dev; -static int max_part; +static int max_part = 15; /* * Use just one lock (or at most 1 per NIC). Two arguments for this: @@ -406,6 +406,7 @@ ret = sysfs_create_file(&disk_to_dev(lo->disk)->kobj, &pid_attr.attr); if (ret) { printk(KERN_ERR "nbd: sysfs_create_file failed!"); + lo->pid = 0; return ret; } @@ -413,6 +414,7 @@ nbd_end_request(req); sysfs_remove_file(&disk_to_dev(lo->disk)->kobj, &pid_attr.attr); + lo->pid = 0; return 0; } @@ -547,6 +549,15 @@ BUG_ON(lo->magic != LO_MAGIC); + if (unlikely(!lo->sock)) { + printk(KERN_ERR "%s: Attempted send on closed socket\n", + lo->disk->disk_name); + req->errors++; + nbd_end_request(req); + spin_lock_irq(q->queue_lock); + continue; + } + spin_lock_irq(&lo->queue_lock); list_add_tail(&req->queuelist, &lo->waiting_queue); spin_unlock_irq(&lo->queue_lock); @@ -648,6 +659,8 @@ set_capacity(lo->disk, lo->bytesize >> 9); return 0; case NBD_DO_IT: + if (lo->pid) + return -EBUSY; if (!lo->file) return -EINVAL; thread = kthread_create(nbd_thread, lo, lo->disk->disk_name); --- linux-2.6.28.orig/drivers/block/floppy.c +++ linux-2.6.28/drivers/block/floppy.c @@ -177,6 +177,7 @@ #include #include #include +#include #include /* for invalidate_buffers() */ #include @@ -4573,6 +4574,13 @@ MODULE_SUPPORTED_DEVICE("fd"); MODULE_LICENSE("GPL"); +/* This doesn't actually get used other than for module information */ +static const struct pnp_device_id floppy_pnpids[] = { + { "PNP0700", 0 }, + { } +}; +MODULE_DEVICE_TABLE(pnp, floppy_pnpids); + #else __setup("floppy=", floppy_setup); --- linux-2.6.28.orig/drivers/block/xen-blkfront.c +++ linux-2.6.28/drivers/block/xen-blkfront.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -82,6 +83,7 @@ enum blkif_state connected; int ring_ref; struct blkif_front_ring ring; + struct scatterlist sg[BLKIF_MAX_SEGMENTS_PER_REQUEST]; unsigned int evtchn, irq; struct request_queue *rq; struct work_struct work; @@ -204,12 +206,11 @@ struct blkfront_info *info = req->rq_disk->private_data; unsigned long buffer_mfn; struct blkif_request *ring_req; - struct req_iterator iter; - struct bio_vec *bvec; unsigned long id; unsigned int fsect, lsect; - int ref; + int i, ref; grant_ref_t gref_head; + struct scatterlist *sg; if (unlikely(info->connected != BLKIF_STATE_CONNECTED)) return 1; @@ -238,12 +239,13 @@ if (blk_barrier_rq(req)) ring_req->operation = BLKIF_OP_WRITE_BARRIER; - ring_req->nr_segments = 0; - rq_for_each_segment(bvec, req, iter) { - BUG_ON(ring_req->nr_segments == BLKIF_MAX_SEGMENTS_PER_REQUEST); - buffer_mfn = pfn_to_mfn(page_to_pfn(bvec->bv_page)); - fsect = bvec->bv_offset >> 9; - lsect = fsect + (bvec->bv_len >> 9) - 1; + ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg); + BUG_ON(ring_req->nr_segments > BLKIF_MAX_SEGMENTS_PER_REQUEST); + + for_each_sg(info->sg, sg, ring_req->nr_segments, i) { + buffer_mfn = pfn_to_mfn(page_to_pfn(sg_page(sg))); + fsect = sg->offset >> 9; + lsect = fsect + (sg->length >> 9) - 1; /* install a grant reference. */ ref = gnttab_claim_grant_reference(&gref_head); BUG_ON(ref == -ENOSPC); @@ -254,16 +256,12 @@ buffer_mfn, rq_data_dir(req) ); - info->shadow[id].frame[ring_req->nr_segments] = - mfn_to_pfn(buffer_mfn); - - ring_req->seg[ring_req->nr_segments] = + info->shadow[id].frame[i] = mfn_to_pfn(buffer_mfn); + ring_req->seg[i] = (struct blkif_request_segment) { .gref = ref, .first_sect = fsect, .last_sect = lsect }; - - ring_req->nr_segments++; } info->ring.req_prod_pvt++; @@ -628,6 +626,8 @@ SHARED_RING_INIT(sring); FRONT_RING_INIT(&info->ring, sring, PAGE_SIZE); + sg_init_table(info->sg, BLKIF_MAX_SEGMENTS_PER_REQUEST); + err = xenbus_grant_ring(dev, virt_to_mfn(info->ring.sring)); if (err < 0) { free_page((unsigned long)sring); --- linux-2.6.28.orig/drivers/block/paride/pg.c +++ linux-2.6.28/drivers/block/paride/pg.c @@ -718,5 +718,6 @@ } MODULE_LICENSE("GPL"); +MODULE_ALIAS_CHARDEV_MAJOR(PG_MAJOR); module_init(pg_init) module_exit(pg_exit) --- linux-2.6.28.orig/drivers/block/paride/pcd.c +++ linux-2.6.28/drivers/block/paride/pcd.c @@ -967,5 +967,6 @@ } MODULE_LICENSE("GPL"); +MODULE_ALIAS_BLOCKDEV_MAJOR(PCD_MAJOR); module_init(pcd_init) module_exit(pcd_exit) --- linux-2.6.28.orig/drivers/block/paride/pf.c +++ linux-2.6.28/drivers/block/paride/pf.c @@ -988,5 +988,6 @@ } MODULE_LICENSE("GPL"); +MODULE_ALIAS_BLOCKDEV_MAJOR(PF_MAJOR); module_init(pf_init) module_exit(pf_exit) --- linux-2.6.28.orig/drivers/block/paride/pt.c +++ linux-2.6.28/drivers/block/paride/pt.c @@ -1008,5 +1008,6 @@ } MODULE_LICENSE("GPL"); +MODULE_ALIAS_CHARDEV_MAJOR(PT_MAJOR); module_init(pt_init) module_exit(pt_exit) --- linux-2.6.28.orig/drivers/block/aoe/aoe.h +++ linux-2.6.28/drivers/block/aoe/aoe.h @@ -18,6 +18,7 @@ enum { AOECMD_ATA, AOECMD_CFG, + AOECMD_VEND_MIN = 0xf0, AOEFL_RSP = (1<<3), AOEFL_ERR = (1<<2), --- linux-2.6.28.orig/drivers/block/aoe/aoenet.c +++ linux-2.6.28/drivers/block/aoe/aoenet.c @@ -153,6 +153,8 @@ aoecmd_cfg_rsp(skb); break; default: + if (h->cmd >= AOECMD_VEND_MIN) + break; /* don't complain about vendor commands */ printk(KERN_INFO "aoe: unknown cmd %d\n", h->cmd); } exit: --- linux-2.6.28.orig/drivers/hwmon/abituguru3.c +++ linux-2.6.28/drivers/hwmon/abituguru3.c @@ -279,7 +279,7 @@ { "OTES1 Fan", 36, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, - { 0x0011, "AT8 32X(ATI RD580-ULI M1575)", { + { 0x0011, "AT8 32X", { { "CPU Core", 0, 0, 10, 1, 0 }, { "DDR", 1, 0, 20, 1, 0 }, { "DDR VTT", 2, 0, 10, 1, 0 }, @@ -402,7 +402,7 @@ { "AUX3 Fan", 36, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, - { 0x0016, "AW9D-MAX (Intel i975-ICH7)", { + { 0x0016, "AW9D-MAX", { { "CPU Core", 0, 0, 10, 1, 0 }, { "DDR2", 1, 0, 20, 1, 0 }, { "DDR2 VTT", 2, 0, 10, 1, 0 }, @@ -509,7 +509,7 @@ { "AUX3 FAN", 36, 2, 60, 1, 0 }, { NULL, 0, 0, 0, 0, 0 } } }, - { 0x001A, "IP35 Pro(Intel P35-ICH9R)", { + { 0x001A, "IP35 Pro", { { "CPU Core", 0, 0, 10, 1, 0 }, { "DDR2", 1, 0, 20, 1, 0 }, { "DDR2 VTT", 2, 0, 10, 1, 0 }, @@ -1128,6 +1128,7 @@ { const char *board_vendor, *board_name; int i, err = (force) ? 1 : -ENODEV; + size_t sublen; board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); if (!board_vendor || strcmp(board_vendor, "http://www.abit.com.tw/")) @@ -1137,9 +1138,20 @@ if (!board_name) return err; + /* At the moment, we don't care about the part of the vendor + * DMI string contained in brackets. Truncate the string at + * the first occurrence of a bracket. Trim any trailing space + * from the substring. + */ + sublen = strcspn(board_name, "("); + while (sublen > 0 && board_name[sublen - 1] == ' ') + sublen--; + for (i = 0; abituguru3_motherboards[i].id; i++) { const char *dmi_name = abituguru3_motherboards[i].dmi_name; - if (dmi_name && !strcmp(dmi_name, board_name)) + if (!dmi_name || strlen(dmi_name) != sublen) + continue; + if (!strncasecmp(board_name, dmi_name, sublen)) break; } @@ -1153,7 +1165,7 @@ static inline int abituguru3_dmi_detect(void) { - return -ENODEV; + return 1; } #endif /* CONFIG_DMI */ --- linux-2.6.28.orig/drivers/hwmon/Kconfig +++ linux-2.6.28/drivers/hwmon/Kconfig @@ -888,4 +888,9 @@ a problem with I2C support and want to see more of what is going on. +config SENSORS_ISL29003 + tristate "ISL29003 Light Sensor" + depends on MACH_MX37_3DS || MACH_MX51_3DS + default y + endif # HWMON --- linux-2.6.28.orig/drivers/hwmon/hdaps.c +++ linux-2.6.28/drivers/hwmon/hdaps.c @@ -533,6 +533,9 @@ HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad Z60m"), HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61m"), HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61p"), + HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T61P"), + HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R61"), + HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T61"), { .ident = NULL } }; --- linux-2.6.28.orig/drivers/hwmon/f71882fg.c +++ linux-2.6.28/drivers/hwmon/f71882fg.c @@ -837,7 +837,7 @@ devid = superio_inw(sioaddr, SIO_REG_MANID); if (devid != SIO_FINTEK_ID) { - printk(KERN_INFO DRVNAME ": Not a Fintek device\n"); + pr_debug(DRVNAME ": Not a Fintek device\n"); goto exit; } --- linux-2.6.28.orig/drivers/hwmon/isl29003.c +++ linux-2.6.28/drivers/hwmon/isl29003.c @@ -0,0 +1,436 @@ +/* + * Copyright 2008-2009 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 + */ + +/*! + * @file drivers/hwmon/isl29003.c + * + * @brief ISL29003 light sensor Driver + * + * @ingroup + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum isl29003_width { + ISL29003_WIDTH_16 = 0, + ISL29003_WIDTH_12, + ISL29003_WIDTH_8, + ISL29003_WIDTH_4, +}; + +enum isl29003_gain { + ISL29003_GAIN_1000 = 0, + ISL29003_GAIN_4000, + ISL29003_GAIN_16000, + ISL29003_GAIN_64000, +}; + +enum isl29003_mode { + ISL29003_MODE_DIODE1 = 0, + ISL29003_MODE_DIODE2, + ISL29003_MODE_DIODE1_2, +}; + +struct isl29003_param { + enum isl29003_width width; + enum isl29003_gain gain; + enum isl29003_mode mode; +}; + +/* bit definition for ISL29003_CMD reg */ +#define ENABLE 7 +#define ADCPD 6 +#define TIMEING_MODE 5 +#define MODE 2 +#define WIDTH 0 + +/* bit definition for ISL29003_CTRL reg */ +#define INT_FLAG 5 +#define GAIN 2 +#define INT_PERSIST 0 + +enum isl29003_reg { + ISL29003_CMD = 0, + ISL29003_CTRL, + ISL29003_THRS_HI, + ISL29003_THRS_LO, + ISL29003_LSB_S, + ISL29003_MSB_S, + ISL29003_LSB_T, + ISL29003_MSB_T, + ISL29003_SYNC_IIC = 0x80, + ISL29003_CLAR_INT = 0x40 +}; + +/* default configure for ISL29003 */ +#define ISL29003_WIDTH_DEFAULT ISL29003_WIDTH_16 +#define ISL29003_GAIN_DEFAULT ISL29003_GAIN_16000 +#define ISL29003_MODE_DEFAULT ISL29003_MODE_DIODE1 + +/* range table for different GAIN settings */ +int range[4] = { 973, 3892, 15568, 62272 }; + +/* width table for different WIDTH settings */ +int width[4] = { 16, 1, 256, 16 }; + +struct isl29003_data { + struct i2c_client *client; + struct device *hwmon_dev; + struct regulator *vdd_reg; + struct isl29003_param param; + int lux_coeff; + unsigned char enable; +}; + +static struct i2c_client *isl29003_client; + +/*! + * This function do the isl29003 register read. + */ +int isl29003_read(struct i2c_client *client, u8 reg) +{ + return i2c_smbus_read_byte_data(client, reg); +} + +/*! + * This function do the isl29003 register write. + */ +int isl29003_write(struct i2c_client *client, u8 reg, char value) +{ + return i2c_smbus_write_byte_data(client, reg, value); +} + +/*! + * This function do the isl29003 config and enable. + */ +static int isl29003_on(void) +{ + unsigned char cmd; + int err = 0; + struct mxc_lightsensor_platform_data *ls_data; + struct isl29003_data *data = i2c_get_clientdata(isl29003_client); + + if (data->enable) + goto exit; + + ls_data = (struct mxc_lightsensor_platform_data *) + (isl29003_client->dev).platform_data; + + /* coeff=range*100k/rext/2^n */ + data->lux_coeff = range[data->param.gain] * 100 / + ls_data->rext / width[data->param.width]; + + if (data->vdd_reg) + regulator_enable(data->vdd_reg); + msleep(100); + + cmd = data->param.gain << GAIN; + if (isl29003_write(isl29003_client, ISL29003_CTRL, cmd)) { + err = -ENODEV; + goto exit; + } + + cmd = (data->param.width << WIDTH) | (data->param.mode << MODE) | + (1 << ENABLE); + if (isl29003_write(isl29003_client, ISL29003_CMD, cmd)) { + err = -ENODEV; + goto exit; + } + + data->enable = 1; + + pr_info("isl29003 on\n"); + return 0; +exit: + return err; +} + +/*! + * This function shut down the isl29003. + */ +static int isl29003_off(void) +{ + struct isl29003_data *data = i2c_get_clientdata(isl29003_client); + int cmd; + + if (!data->enable) + return 0; + + cmd = isl29003_read(isl29003_client, ISL29003_CMD); + if (cmd < 0) + return -ENODEV; + + cmd = ((cmd | (1 << ADCPD)) & (~(1 << ENABLE))); + if (isl29003_write(isl29003_client, ISL29003_CMD, (char)cmd)) + return -ENODEV; + + if (data->vdd_reg) + regulator_disable(data->vdd_reg); + + data->enable = 0; + + pr_info("isl29003 off\n"); + return 0; +} + +/*! + * This function read the isl29003 lux registers and convert them to the lux + * value. + * + * @output buffer this param holds the lux value, when =-1, read fail + * + * @return 0 + */ +static int isl29003_read_lux(void) +{ + int d; + int lux; + struct isl29003_data *data = i2c_get_clientdata(isl29003_client); + + d = isl29003_read(isl29003_client, ISL29003_MSB_S); + if (d < 0) + goto err; + + lux = d; + d = isl29003_read(isl29003_client, ISL29003_LSB_S); + if (d < 0) + goto err; + + lux = (lux << 8) + d; + + if (data->param.width < ISL29003_WIDTH_8) + lux = (data->lux_coeff * lux) >> 12; + else + lux = data->lux_coeff * lux; + + return lux; +err: + return -1; +} + +static ssize_t ls_enable(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + char *endp; + int enable = simple_strtoul(buf, &endp, 0); + size_t size = endp - buf; + + if (*endp && isspace(*endp)) + size++; + if (size != count) + return -EINVAL; + + if (enable == 1) { + if (isl29003_on()) + pr_info("device open fail\n"); + } + if (enable == 0) { + if (isl29003_off()) + pr_info("device powerdown fail\n"); + } + + return count; +} + +static SENSOR_DEVICE_ATTR(enable, S_IWUGO, NULL, ls_enable, 0); + +static ssize_t show_lux(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%u\n", isl29003_read_lux()); +} + +static SENSOR_DEVICE_ATTR(lux, S_IRUGO, show_lux, NULL, 0); + +static int isl29003_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + int err = 0; + struct isl29003_data *data; + struct regulator *vdd_reg; + struct mxc_lightsensor_platform_data *ls_data; + + ls_data = (struct mxc_lightsensor_platform_data *) + (client->dev).platform_data; + + if (ls_data && ls_data->vdd_reg) + vdd_reg = regulator_get(&client->dev, ls_data->vdd_reg); + else + vdd_reg = NULL; + + /* check the existence of the device */ + if (vdd_reg) + regulator_enable(vdd_reg); + msleep(100); + if (isl29003_read(client, ISL29003_CMD)) + err = -ENODEV; + + if (vdd_reg) + regulator_disable(vdd_reg); + if (err < 0) + goto exit1; + + isl29003_client = client; + data = kzalloc(sizeof(struct isl29003_data), GFP_KERNEL); + if (data == NULL) { + err = -ENOMEM; + goto exit1; + } + + i2c_set_clientdata(client, data); + data->client = client; + + data->param.width = ISL29003_WIDTH_DEFAULT; + data->param.gain = ISL29003_GAIN_DEFAULT; + data->param.mode = ISL29003_MODE_DEFAULT; + + data->enable = 0; + + err = device_create_file(&client->dev, + &sensor_dev_attr_enable.dev_attr); + if (err) + goto exit2; + + err = device_create_file(&client->dev, &sensor_dev_attr_lux.dev_attr); + if (err) + goto exit_remove1; + + /* Register sysfs hooks */ + data->hwmon_dev = hwmon_device_register(&client->dev); + if (IS_ERR(data->hwmon_dev)) { + err = PTR_ERR(data->hwmon_dev); + goto exit_remove2; + } + + data->vdd_reg = vdd_reg; + return 0; + +exit_remove2: + device_remove_file(&client->dev, &sensor_dev_attr_lux.dev_attr); +exit_remove1: + device_remove_file(&client->dev, &sensor_dev_attr_enable.dev_attr); +exit2: + kfree(data); +exit1: + if (vdd_reg) { + regulator_put(vdd_reg); + vdd_reg = NULL; + } + isl29003_client = NULL; + return err; +} + +static int isl29003_i2c_remove(struct i2c_client *client) +{ + int err; + struct isl29003_data *data = i2c_get_clientdata(client); + + if (data->vdd_reg) { + regulator_put(data->vdd_reg); + data->vdd_reg = NULL; + } + hwmon_device_unregister(data->hwmon_dev); + device_remove_file(&client->dev, &sensor_dev_attr_enable.dev_attr); + device_remove_file(&client->dev, &sensor_dev_attr_lux.dev_attr); + err = i2c_detach_client(client); + if (err) + return err; + kfree(client); + return 0; +} + +static int isl29003_suspend(struct i2c_client *client, pm_message_t message) +{ + int cmd; + + struct isl29003_data *data = i2c_get_clientdata(client); + + if (!data->enable) + goto exit; + + cmd = isl29003_read(client, ISL29003_CMD); + if (cmd < 0) + goto err; + + cmd = (cmd | (1 << ADCPD)); + if (isl29003_write(client, ISL29003_CMD, (char)cmd)) + goto err; +exit: + return 0; +err: + return -ENODEV; +} + +static int isl29003_resume(struct i2c_client *client) +{ + int cmd; + + struct isl29003_data *data = i2c_get_clientdata(client); + + if (!data->enable) + goto exit; + + cmd = isl29003_read(client, ISL29003_CMD); + if (cmd < 0) + goto err; + + cmd = (cmd & (~(1 << ADCPD))); + if (isl29003_write(client, ISL29003_CMD, (char)cmd)) + goto err; +exit: + return 0; +err: + return -ENODEV; +} + +static const struct i2c_device_id isl29003_id[] = { + {"isl29003", 0}, + {} +}; +MODULE_DEVICE_TABLE(i2c, isl29003_id); + +static struct i2c_driver isl29003_driver = { + .driver = { + .name = "isl29003", + }, + .probe = isl29003_i2c_probe, + .remove = isl29003_i2c_remove, + .suspend = isl29003_suspend, + .resume = isl29003_resume, + .id_table = isl29003_id, +}; + +static int __init isl29003_init(void) +{ + return i2c_add_driver(&isl29003_driver);; +} + +static void __exit isl29003_cleanup(void) +{ + i2c_del_driver(&isl29003_driver); +} + +module_init(isl29003_init); +module_exit(isl29003_cleanup); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("ISL29003 light sensor driver"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/hwmon/Makefile +++ linux-2.6.28/drivers/hwmon/Makefile @@ -78,6 +78,7 @@ obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o +obj-$(CONFIG_SENSORS_ISL29003) += isl29003.o ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y) EXTRA_CFLAGS += -DDEBUG --- linux-2.6.28.orig/drivers/hwmon/it87.c +++ linux-2.6.28/drivers/hwmon/it87.c @@ -207,7 +207,7 @@ #define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)<0?(((val)-500)/1000):\ ((val)+500)/1000),-128,127)) -#define TEMP_FROM_REG(val) (((val)>0x80?(val)-0x100:(val))*1000) +#define TEMP_FROM_REG(val) ((val) * 1000) #define PWM_TO_REG(val) ((val) >> 1) #define PWM_FROM_REG(val) (((val)&0x7f) << 1) @@ -261,9 +261,9 @@ u8 has_fan; /* Bitfield, fans enabled */ u16 fan[5]; /* Register values, possibly combined */ u16 fan_min[5]; /* Register values, possibly combined */ - u8 temp[3]; /* Register value */ - u8 temp_high[3]; /* Register value */ - u8 temp_low[3]; /* Register value */ + s8 temp[3]; /* Register value */ + s8 temp_high[3]; /* Register value */ + s8 temp_low[3]; /* Register value */ u8 sensor; /* Register value */ u8 fan_div[3]; /* Register encoding, shifted right */ u8 vid; /* Register encoding, combined */ --- linux-2.6.28.orig/drivers/parport/parport_serial.c +++ linux-2.6.28/drivers/parport/parport_serial.c @@ -64,6 +64,11 @@ static int __devinit netmos_parallel_init(struct pci_dev *dev, struct parport_pc_pci *card, int autoirq, int autodma) { + /* the rule described below doesn't hold for this device */ + if (dev->device == PCI_DEVICE_ID_NETMOS_9835 && + dev->subsystem_vendor == PCI_VENDOR_ID_IBM && + dev->subsystem_device == 0x0299) + return -ENODEV; /* * Netmos uses the subdevice ID to indicate the number of parallel * and serial ports. The form is 0x00PS, where

is the number of --- linux-2.6.28.orig/drivers/pci/quirks.c +++ linux-2.6.28/drivers/pci/quirks.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "pci.h" int isa_dma_bridge_buggy; @@ -1543,6 +1544,30 @@ } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_e100_interrupt); +/* + * The 82575 and 82598 may experience data corruption issues when transitioning + * out of L0S. To prevent this we need to disable L0S on the pci-e link + */ +static void __devinit quirk_disable_aspm_l0s(struct pci_dev *dev) +{ + dev_info(&dev->dev, "Disabling L0s\n"); + pci_disable_link_state(dev, PCIE_LINK_STATE_L0S); +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10a7, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10a9, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10b6, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10c6, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10c7, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10c8, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10d6, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10db, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10dd, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10e1, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10ec, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10f1, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10f4, quirk_disable_aspm_l0s); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1508, quirk_disable_aspm_l0s); + static void __devinit fixup_rev1_53c810(struct pci_dev* dev) { /* rev 1 ncr53c810 chips don't set the class at all which means @@ -1778,7 +1803,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE, quirk_msi_ht_cap); - /* The nVidia CK804 chipset may have 2 HT MSI mappings. * MSI are supported if the MSI capability set in any of these mappings. */ @@ -1829,6 +1853,9 @@ PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB, ht_enable_msi_mapping); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8132_BRIDGE, + ht_enable_msi_mapping); + /* The P5N32-SLI Premium motherboard from Asus has a problem with msi * for the MCP55 NIC. It is not yet determined whether the msi problem * also affects other devices. As for now, turn off msi for this device. --- linux-2.6.28.orig/drivers/pci/syscall.c +++ linux-2.6.28/drivers/pci/syscall.c @@ -14,10 +14,8 @@ #include #include "pci.h" -asmlinkage long -sys_pciconfig_read(unsigned long bus, unsigned long dfn, - unsigned long off, unsigned long len, - void __user *buf) +SYSCALL_DEFINE5(pciconfig_read, unsigned long, bus, unsigned long, dfn, + unsigned long, off, unsigned long, len, void __user *, buf) { struct pci_dev *dev; u8 byte; @@ -86,10 +84,8 @@ return err; } -asmlinkage long -sys_pciconfig_write(unsigned long bus, unsigned long dfn, - unsigned long off, unsigned long len, - void __user *buf) +SYSCALL_DEFINE5(pciconfig_write, unsigned long, bus, unsigned long, dfn, + unsigned long, off, unsigned long, len, void __user *, buf) { struct pci_dev *dev; u8 byte; --- linux-2.6.28.orig/drivers/pci/pci-sysfs.c +++ linux-2.6.28/drivers/pci/pci-sysfs.c @@ -777,8 +777,8 @@ return -EINVAL; rom = pci_map_rom(pdev, &size); /* size starts out as PCI window size */ - if (!rom) - return 0; + if (!rom || !size) + return -EIO; if (off >= size) count = 0; --- linux-2.6.28.orig/drivers/pci/intel-iommu.c +++ linux-2.6.28/drivers/pci/intel-iommu.c @@ -71,6 +71,8 @@ /* bitmap for indexing intel_iommus */ static int g_num_of_iommus; +static int rwbf_quirk = 0; + static DEFINE_SPINLOCK(async_umap_flush_lock); static LIST_HEAD(unmaps_to_do); @@ -506,7 +508,7 @@ u32 val; unsigned long flag; - if (!cap_rwbf(iommu->cap)) + if (!rwbf_quirk && !cap_rwbf(iommu->cap)) return; val = iommu->gcmd | DMA_GCMD_WBF; @@ -2436,3 +2438,13 @@ return pfn >> VTD_PAGE_SHIFT; } EXPORT_SYMBOL_GPL(intel_iommu_iova_to_pfn); + +static void __devinit quirk_iommu_rwbf(struct pci_dev *dev) +{ + /* Mobile 4 Series Chipset neglects to set RWBF capability, + but needs it */ + printk(KERN_INFO "DMAR: Forcing write-buffer flush capability\n"); + rwbf_quirk = 1; +} + +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf); --- linux-2.6.28.orig/drivers/pci/setup-res.c +++ linux-2.6.28/drivers/pci/setup-res.c @@ -157,7 +157,7 @@ } if (ret) { - dev_err(&dev->dev, "BAR %d: can't allocate %s resource %pR\n", + dev_warn(&dev->dev, "BAR %d: can't allocate %s resource %pR\n", resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res); } else { res->flags &= ~IORESOURCE_STARTALIGN; --- linux-2.6.28.orig/drivers/pci/msi.c +++ linux-2.6.28/drivers/pci/msi.c @@ -378,21 +378,19 @@ entry->msi_attrib.masked = 1; entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ entry->msi_attrib.pos = pos; - if (entry->msi_attrib.maskbit) { - entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos, - entry->msi_attrib.is_64); - } entry->dev = dev; if (entry->msi_attrib.maskbit) { - unsigned int maskbits, temp; + unsigned int base, maskbits, temp; + + base = msi_mask_bits_reg(pos, entry->msi_attrib.is_64); + entry->mask_base = (void __iomem *)(long)base; + /* All MSIs are unmasked by default, Mask them all */ - pci_read_config_dword(dev, - msi_mask_bits_reg(pos, entry->msi_attrib.is_64), - &maskbits); + pci_read_config_dword(dev, base, &maskbits); temp = (1 << multi_msi_capable(control)); temp = ((temp - 1) & ~temp); maskbits |= temp; - pci_write_config_dword(dev, entry->msi_attrib.is_64, maskbits); + pci_write_config_dword(dev, base, maskbits); entry->msi_attrib.maskbits_mask = temp; } list_add_tail(&entry->list, &dev->msi_list); --- linux-2.6.28.orig/drivers/pci/rom.c +++ linux-2.6.28/drivers/pci/rom.c @@ -63,7 +63,7 @@ * The PCI window size could be much larger than the * actual image size. */ -size_t pci_get_rom_size(void __iomem *rom, size_t size) +size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size) { void __iomem *image; int last_image; @@ -72,8 +72,10 @@ do { void __iomem *pds; /* Standard PCI ROMs start out with these bytes 55 AA */ - if (readb(image) != 0x55) + if (readb(image) != 0x55) { + dev_err(&pdev->dev, "Invalid ROM contents\n"); break; + } if (readb(image + 1) != 0xAA) break; /* get the PCI data structure and check its signature */ @@ -159,7 +161,7 @@ * size is much larger than the actual size of the ROM. * True size is important if the ROM is going to be copied. */ - *size = pci_get_rom_size(rom, *size); + *size = pci_get_rom_size(pdev, rom, *size); return rom; } --- linux-2.6.28.orig/drivers/pci/hotplug/pciehp_core.c +++ linux-2.6.28/drivers/pci/hotplug/pciehp_core.c @@ -126,8 +126,10 @@ mutex_lock(&slot->ctrl->crit_sect); /* has it been >1 sec since our last toggle? */ - if ((get_seconds() - slot->last_emi_toggle) < 1) + if ((get_seconds() - slot->last_emi_toggle) < 1) { + mutex_unlock(&slot->ctrl->crit_sect); return -EINVAL; + } /* see what our current state is */ retval = get_lock_status(hotplug_slot, &value); --- linux-2.6.28.orig/drivers/pci/pcie/aspm.c +++ linux-2.6.28/drivers/pci/pcie/aspm.c @@ -33,6 +33,11 @@ struct pcie_link_state { struct list_head sibiling; struct pci_dev *pdev; + bool downstream_has_switch; + + struct pcie_link_state *parent; + struct list_head children; + struct list_head link; /* ASPM state */ unsigned int support_state; @@ -125,7 +130,7 @@ link_state->clk_pm_enabled = !!enable; } -static void pcie_check_clock_pm(struct pci_dev *pdev) +static void pcie_check_clock_pm(struct pci_dev *pdev, int blacklist) { int pos; u32 reg32; @@ -149,10 +154,26 @@ if (!(reg16 & PCI_EXP_LNKCTL_CLKREQ_EN)) enabled = 0; } - link_state->clk_pm_capable = capable; link_state->clk_pm_enabled = enabled; link_state->bios_clk_state = enabled; - pcie_set_clock_pm(pdev, policy_to_clkpm_state(pdev)); + if (!blacklist) { + link_state->clk_pm_capable = capable; + pcie_set_clock_pm(pdev, policy_to_clkpm_state(pdev)); + } else { + link_state->clk_pm_capable = 0; + pcie_set_clock_pm(pdev, 0); + } +} + +static bool pcie_aspm_downstream_has_switch(struct pci_dev *pdev) +{ + struct pci_dev *child_dev; + + list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) { + if (child_dev->pcie_type == PCI_EXP_TYPE_UPSTREAM) + return true; + } + return false; } /* @@ -419,9 +440,9 @@ { struct pci_dev *child_dev; - /* If no child, disable the link */ + /* If no child, ignore the link */ if (list_empty(&pdev->subordinate->devices)) - return 0; + return state; list_for_each_entry(child_dev, &pdev->subordinate->devices, bus_list) { if (child_dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) { /* @@ -462,6 +483,9 @@ int valid = 1; struct pcie_link_state *link_state = pdev->link_state; + /* If no child, disable the link */ + if (list_empty(&pdev->subordinate->devices)) + state = 0; /* * if the downstream component has pci bridge function, don't do ASPM * now @@ -493,20 +517,52 @@ link_state->enabled_state = state; } +static struct pcie_link_state *get_root_port_link(struct pcie_link_state *link) +{ + struct pcie_link_state *root_port_link = link; + while (root_port_link->parent) + root_port_link = root_port_link->parent; + return root_port_link; +} + +/* check the whole hierarchy, and configure each link in the hierarchy */ static void __pcie_aspm_configure_link_state(struct pci_dev *pdev, unsigned int state) { struct pcie_link_state *link_state = pdev->link_state; + struct pcie_link_state *root_port_link = get_root_port_link(link_state); + struct pcie_link_state *leaf; - if (link_state->support_state == 0) - return; state &= PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1; - /* state 0 means disabling aspm */ - state = pcie_aspm_check_state(pdev, state); + /* check all links who have specific root port link */ + list_for_each_entry(leaf, &link_list, sibiling) { + if (!list_empty(&leaf->children) || + get_root_port_link(leaf) != root_port_link) + continue; + state = pcie_aspm_check_state(leaf->pdev, state); + } + /* check root port link too in case it hasn't children */ + state = pcie_aspm_check_state(root_port_link->pdev, state); + if (link_state->enabled_state == state) return; - __pcie_aspm_config_link(pdev, state); + + /* + * we must change the hierarchy. See comments in + * __pcie_aspm_config_link for the order + **/ + if (state & PCIE_LINK_STATE_L1) { + list_for_each_entry(leaf, &link_list, sibiling) { + if (get_root_port_link(leaf) == root_port_link) + __pcie_aspm_config_link(leaf->pdev, state); + } + } else { + list_for_each_entry_reverse(leaf, &link_list, sibiling) { + if (get_root_port_link(leaf) == root_port_link) + __pcie_aspm_config_link(leaf->pdev, state); + } + } } /* @@ -570,6 +626,7 @@ unsigned int state; struct pcie_link_state *link_state; int error = 0; + int blacklist; if (aspm_disabled || !pdev->is_pcie || pdev->link_state) return; @@ -580,29 +637,58 @@ if (list_empty(&pdev->subordinate->devices)) goto out; - if (pcie_aspm_sanity_check(pdev)) - goto out; + blacklist = !!pcie_aspm_sanity_check(pdev); mutex_lock(&aspm_lock); link_state = kzalloc(sizeof(*link_state), GFP_KERNEL); if (!link_state) goto unlock_out; - pdev->link_state = link_state; - pcie_aspm_configure_common_clock(pdev); - - pcie_aspm_cap_init(pdev); + link_state->downstream_has_switch = pcie_aspm_downstream_has_switch(pdev); + INIT_LIST_HEAD(&link_state->children); + INIT_LIST_HEAD(&link_state->link); + if (pdev->bus->self) {/* this is a switch */ + struct pcie_link_state *parent_link_state; + + parent_link_state = pdev->bus->parent->self->link_state; + if (!parent_link_state) { + kfree(link_state); + goto unlock_out; + } + list_add(&link_state->link, &parent_link_state->children); + link_state->parent = parent_link_state; + } - /* config link state to avoid BIOS error */ - state = pcie_aspm_check_state(pdev, policy_to_aspm_state(pdev)); - __pcie_aspm_config_link(pdev, state); + pdev->link_state = link_state; - pcie_check_clock_pm(pdev); + if (!blacklist) { + pcie_aspm_configure_common_clock(pdev); + pcie_aspm_cap_init(pdev); + } else { + link_state->enabled_state = PCIE_LINK_STATE_L0S|PCIE_LINK_STATE_L1; + link_state->bios_aspm_state = 0; + /* Set support state to 0, so we will disable ASPM later */ + link_state->support_state = 0; + } link_state->pdev = pdev; list_add(&link_state->sibiling, &link_list); + if (link_state->downstream_has_switch) { + /* + * If link has switch, delay the link config. The leaf link + * initialization will config the whole hierarchy. but we must + * make sure BIOS doesn't set unsupported link state + **/ + state = pcie_aspm_check_state(pdev, link_state->bios_aspm_state); + __pcie_aspm_config_link(pdev, state); + } else + __pcie_aspm_configure_link_state(pdev, + policy_to_aspm_state(pdev)); + + pcie_check_clock_pm(pdev, blacklist); + unlock_out: if (error) free_link_state(pdev); @@ -627,14 +713,15 @@ /* * All PCIe functions are in one slot, remove one function will remove - * the the whole slot, so just wait + * the whole slot, so just wait until we are the last function left. */ - if (!list_empty(&parent->subordinate->devices)) + if (!list_is_last(&pdev->bus_list, &parent->subordinate->devices)) goto out; /* All functions are removed, so just disable ASPM for the link */ __pcie_aspm_config_one_dev(parent, 0); list_del(&link_state->sibiling); + list_del(&link_state->link); /* Clock PM is for endpoint device */ free_link_state(parent); --- linux-2.6.28.orig/drivers/pci/pcie/portdrv_pci.c +++ linux-2.6.28/drivers/pci/pcie/portdrv_pci.c @@ -101,14 +101,13 @@ pcie_portdrv_save_config(dev); - pci_enable_pcie_error_reporting(dev); - return 0; } static void pcie_portdrv_remove (struct pci_dev *dev) { pcie_port_device_remove(dev); + pci_disable_device(dev); kfree(pci_get_drvdata(dev)); } --- linux-2.6.28.orig/drivers/pci/pcie/aer/aerdrv_core.c +++ linux-2.6.28/drivers/pci/pcie/aer/aerdrv_core.c @@ -108,6 +108,34 @@ } #endif /* 0 */ + +static void set_device_error_reporting(struct pci_dev *dev, void *data) +{ + bool enable = *((bool *)data); + + if (dev->pcie_type != PCIE_RC_PORT && + dev->pcie_type != PCIE_SW_UPSTREAM_PORT && + dev->pcie_type != PCIE_SW_DOWNSTREAM_PORT) + return; + + if (enable) + pci_enable_pcie_error_reporting(dev); + else + pci_disable_pcie_error_reporting(dev); +} + +/** + * set_downstream_devices_error_reporting - enable/disable the error reporting bits on the root port and its downstream ports. + * @dev: pointer to root port's pci_dev data structure + * @enable: true = enable error reporting, false = disable error reporting. + */ +static void set_downstream_devices_error_reporting(struct pci_dev *dev, + bool enable) +{ + set_device_error_reporting(dev, &enable); + pci_walk_bus(dev->subordinate, set_device_error_reporting, &enable); +} + static int find_device_iter(struct device *device, void *data) { struct pci_dev *dev; @@ -525,15 +553,11 @@ pci_read_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, ®32); pci_write_config_dword(pdev, aer_pos + PCI_ERR_UNCOR_STATUS, reg32); - /* Enable Root Port device reporting error itself */ - pci_read_config_word(pdev, pos+PCI_EXP_DEVCTL, ®16); - reg16 = reg16 | - PCI_EXP_DEVCTL_CERE | - PCI_EXP_DEVCTL_NFERE | - PCI_EXP_DEVCTL_FERE | - PCI_EXP_DEVCTL_URRE; - pci_write_config_word(pdev, pos+PCI_EXP_DEVCTL, - reg16); + /* + * Enable error reporting for the root port device and downstream port + * devices. + */ + set_downstream_devices_error_reporting(pdev, true); /* Enable Root Port's interrupt in response to error messages */ pci_write_config_dword(pdev, @@ -553,6 +577,12 @@ u32 reg32; int pos; + /* + * Disable error reporting for the root port device and downstream port + * devices. + */ + set_downstream_devices_error_reporting(pdev, false); + pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); /* Disable Root's interrupt in response to error messages */ pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, 0); --- linux-2.6.28.orig/drivers/media/video/Kconfig +++ linux-2.6.28/drivers/media/video/Kconfig @@ -531,6 +531,24 @@ Check out for more information. +config VIDEO_MXC_CAMERA + tristate "MXC Video For Linux Camera" + depends on VIDEO_DEV && ARCH_MXC + default y + ---help--- + This is the video4linux2 capture driver based on MXC IPU/eMMA module. + +source "drivers/media/video/mxc/capture/Kconfig" + +config VIDEO_MXC_OUTPUT + tristate "MXC Video For Linux Video Output" + depends on VIDEO_DEV && ARCH_MXC + default y + ---help--- + This is the video4linux2 output driver based on MXC IPU/eMMA module. + +source "drivers/media/video/mxc/output/Kconfig" + config VIDEO_CPIA tristate "CPiA Video For Linux" depends on VIDEO_V4L1 --- linux-2.6.28.orig/drivers/media/video/videobuf-dma-sg.c +++ linux-2.6.28/drivers/media/video/videobuf-dma-sg.c @@ -388,8 +388,7 @@ page = alloc_page(GFP_USER | __GFP_DMA32); if (!page) return VM_FAULT_OOM; - clear_user_page(page_address(page), (unsigned long)vmf->virtual_address, - page); + clear_user_highpage(page, (unsigned long)vmf->virtual_address); vmf->page = page; return 0; } --- linux-2.6.28.orig/drivers/media/video/v4l2-dev.c +++ linux-2.6.28/drivers/media/video/v4l2-dev.c @@ -418,6 +418,7 @@ MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab "); MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2"); MODULE_LICENSE("GPL"); +MODULE_ALIAS_CHARDEV_MAJOR(VIDEO_MAJOR); /* --- linux-2.6.28.orig/drivers/media/video/Makefile +++ linux-2.6.28/drivers/media/video/Makefile @@ -57,6 +57,8 @@ obj-$(CONFIG_VIDEO_PMS) += pms.o obj-$(CONFIG_VIDEO_VINO) += vino.o indycam.o obj-$(CONFIG_VIDEO_STRADIS) += stradis.o +obj-$(CONFIG_VIDEO_MXC_IPU_CAMERA) += mxc/capture/ +obj-$(CONFIG_VIDEO_MXC_IPU_OUTPUT) += mxc/output/ obj-$(CONFIG_VIDEO_CPIA) += cpia.o obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o --- linux-2.6.28.orig/drivers/media/video/saa7127.c +++ linux-2.6.28/drivers/media/video/saa7127.c @@ -149,7 +149,7 @@ { SAA7127_REG_COPYGEN_0, 0x77 }, { SAA7127_REG_COPYGEN_1, 0x41 }, { SAA7127_REG_COPYGEN_2, 0x00 }, /* Macrovision enable/disable */ - { SAA7127_REG_OUTPUT_PORT_CONTROL, 0x9e }, + { SAA7127_REG_OUTPUT_PORT_CONTROL, 0xbf }, { SAA7127_REG_GAIN_LUMINANCE_RGB, 0x00 }, { SAA7127_REG_GAIN_COLORDIFF_RGB, 0x00 }, { SAA7127_REG_INPUT_PORT_CONTROL_1, 0x80 }, /* for color bars */ @@ -479,12 +479,18 @@ break; case SAA7127_OUTPUT_TYPE_COMPOSITE: - state->reg_2d = 0x08; /* 00001000 CVBS only, RGB DAC's off (high impedance mode) */ + if (state->ident == V4L2_IDENT_SAA7129) + state->reg_2d = 0x20; /* CVBS only */ + else + state->reg_2d = 0x08; /* 00001000 CVBS only, RGB DAC's off (high impedance mode) */ state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */ break; case SAA7127_OUTPUT_TYPE_SVIDEO: - state->reg_2d = 0xff; /* 11111111 croma -> R, luma -> CVBS + G + B */ + if (state->ident == V4L2_IDENT_SAA7129) + state->reg_2d = 0x18; /* Y + C */ + else + state->reg_2d = 0xff; /*11111111 croma -> R, luma -> CVBS + G + B */ state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */ break; @@ -499,7 +505,10 @@ break; case SAA7127_OUTPUT_TYPE_BOTH: - state->reg_2d = 0xbf; + if (state->ident == V4L2_IDENT_SAA7129) + state->reg_2d = 0x38; + else + state->reg_2d = 0xbf; state->reg_3a = 0x13; /* by default switch YUV to RGB-matrix on */ break; @@ -691,24 +700,6 @@ i2c_set_clientdata(client, state); - /* Configure Encoder */ - - v4l_dbg(1, debug, client, "Configuring encoder\n"); - saa7127_write_inittab(client, saa7127_init_config_common); - saa7127_set_std(client, V4L2_STD_NTSC); - saa7127_set_output_type(client, SAA7127_OUTPUT_TYPE_BOTH); - saa7127_set_vps(client, &vbi); - saa7127_set_wss(client, &vbi); - saa7127_set_cc(client, &vbi); - saa7127_set_xds(client, &vbi); - if (test_image == 1) - /* The Encoder has an internal Colorbar generator */ - /* This can be used for debugging */ - saa7127_set_input_type(client, SAA7127_INPUT_TYPE_TEST_IMAGE); - else - saa7127_set_input_type(client, SAA7127_INPUT_TYPE_NORMAL); - saa7127_set_video_enable(client, 1); - if (id->driver_data) { /* Chip type is already known */ state->ident = id->driver_data; } else { /* Needs detection */ @@ -730,6 +721,23 @@ v4l_info(client, "%s found @ 0x%x (%s)\n", client->name, client->addr << 1, client->adapter->name); + + v4l_dbg(1, debug, client, "Configuring encoder\n"); + saa7127_write_inittab(client, saa7127_init_config_common); + saa7127_set_std(client, V4L2_STD_NTSC); + saa7127_set_output_type(client, SAA7127_OUTPUT_TYPE_BOTH); + saa7127_set_vps(client, &vbi); + saa7127_set_wss(client, &vbi); + saa7127_set_cc(client, &vbi); + saa7127_set_xds(client, &vbi); + if (test_image == 1) + /* The Encoder has an internal Colorbar generator */ + /* This can be used for debugging */ + saa7127_set_input_type(client, SAA7127_INPUT_TYPE_TEST_IMAGE); + else + saa7127_set_input_type(client, SAA7127_INPUT_TYPE_NORMAL); + saa7127_set_video_enable(client, 1); + if (state->ident == V4L2_IDENT_SAA7129) saa7127_write_inittab(client, saa7129_init_config_extra); return 0; --- linux-2.6.28.orig/drivers/media/video/cx88/cx88-input.c +++ linux-2.6.28/drivers/media/video/cx88/cx88-input.c @@ -231,6 +231,7 @@ ir->sampling = 1; break; case CX88_BOARD_WINFAST_DTV2000H: + case CX88_BOARD_WINFAST_DTV2000H_2: ir_codes = ir_codes_winfast; ir->gpio_addr = MO_GP0_IO; ir->mask_keycode = 0x8f8; --- linux-2.6.28.orig/drivers/media/video/cx88/cx88-dvb.c +++ linux-2.6.28/drivers/media/video/cx88/cx88-dvb.c @@ -639,6 +639,7 @@ } break; case CX88_BOARD_WINFAST_DTV2000H: + case CX88_BOARD_WINFAST_DTV2000H_2: case CX88_BOARD_HAUPPAUGE_HVR1100: case CX88_BOARD_HAUPPAUGE_HVR1100LP: case CX88_BOARD_HAUPPAUGE_HVR1300: --- linux-2.6.28.orig/drivers/media/video/cx88/cx88-mpeg.c +++ linux-2.6.28/drivers/media/video/cx88/cx88-mpeg.c @@ -126,6 +126,11 @@ cx_write(TS_VALERR_CNTRL, 0); udelay(100); break; + case CX88_BOARD_WINFAST_DTV2000H_2: + /* switch signal input to antena */ + cx_write(MO_GP0_IO, 0x00017300); + cx_write(TS_SOP_STAT, 0x00); + break; default: cx_write(TS_SOP_STAT, 0x00); break; --- linux-2.6.28.orig/drivers/media/video/cx88/cx88-cards.c +++ linux-2.6.28/drivers/media/video/cx88/cx88-cards.c @@ -1238,7 +1238,7 @@ }, [CX88_BOARD_WINFAST_DTV2000H] = { /* video inputs and radio still in testing */ - .name = "WinFast DTV2000 H", + .name = "WinFast DTV2000 H ver. I (old)", .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -1254,6 +1254,45 @@ }}, .mpeg = CX88_MPEG_DVB, }, + [CX88_BOARD_WINFAST_DTV2000H_2] = { + /* this is just a try */ + .name = "WinFast DTV2000 H ver. J (new)", + .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .input = { { + .type = CX88_VMUX_TELEVISION, + .vmux = 0, + .gpio0 = 0x00017300, + .gpio1 = 0x00008207, + .gpio2 = 0x00000000, + .gpio3 = 0x02000000, + }, { + .type = CX88_VMUX_TELEVISION, + .vmux = 0, + .gpio0 = 0x00018300, + .gpio1 = 0x0000f207, + .gpio2 = 0x00017304, + .gpio3 = 0x02000000, + }, { + .type = CX88_VMUX_COMPOSITE1, + .vmux = 1, + .gpio0 = 0x00018301, + .gpio1 = 0x0000f207, + .gpio2 = 0x00017304, + .gpio3 = 0x02000000, + }, { + .type = CX88_VMUX_SVIDEO, + .vmux = 2, + .gpio0 = 0x00018301, + .gpio1 = 0x0000f207, + .gpio2 = 0x00017304, + .gpio3 = 0x02000000, + } }, + .mpeg = CX88_MPEG_DVB, + }, [CX88_BOARD_GENIATECH_DVBS] = { .name = "Geniatech DVB-S", .tuner_type = TUNER_ABSENT, @@ -2120,6 +2159,10 @@ .subdevice = 0x665e, .card = CX88_BOARD_WINFAST_DTV2000H, },{ + .subvendor = 0x107d, + .subdevice = 0x6f2b, + .card = CX88_BOARD_WINFAST_DTV2000H_2, + },{ .subvendor = 0x18ac, .subdevice = 0xd800, /* FusionHDTV 3 Gold (original revision) */ .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q, --- linux-2.6.28.orig/drivers/media/video/cx88/cx88.h +++ linux-2.6.28/drivers/media/video/cx88/cx88.h @@ -229,6 +229,7 @@ #define CX88_BOARD_TEVII_S420 73 #define CX88_BOARD_PROLINK_PV_GLOBAL_XTREME 74 #define CX88_BOARD_PROF_7300 75 +#define CX88_BOARD_WINFAST_DTV2000H_2 76 enum cx88_itype { CX88_VMUX_COMPOSITE1 = 1, --- linux-2.6.28.orig/drivers/media/video/gspca/zc3xx.c +++ linux-2.6.28/drivers/media/video/gspca/zc3xx.c @@ -7561,9 +7561,7 @@ {USB_DEVICE(0x0ac8, 0x0301), .driver_info = SENSOR_PAS106}, {USB_DEVICE(0x0ac8, 0x0302)}, {USB_DEVICE(0x0ac8, 0x301b)}, -#if !defined CONFIG_USB_ZC0301 && !defined CONFIG_USB_ZC0301_MODULE {USB_DEVICE(0x0ac8, 0x303b)}, -#endif {USB_DEVICE(0x0ac8, 0x305b), .driver_info = SENSOR_TAS5130C_VF0250}, {USB_DEVICE(0x0ac8, 0x307b)}, {USB_DEVICE(0x10fd, 0x0128)}, --- linux-2.6.28.orig/drivers/media/video/ivtv/ivtv-ioctl.c +++ linux-2.6.28/drivers/media/video/ivtv/ivtv-ioctl.c @@ -1750,6 +1750,18 @@ break; } + case IVTV_IOC_DMA_FRAME: + case VIDEO_GET_PTS: + case VIDEO_GET_FRAME_COUNT: + case VIDEO_GET_EVENT: + case VIDEO_PLAY: + case VIDEO_STOP: + case VIDEO_FREEZE: + case VIDEO_CONTINUE: + case VIDEO_COMMAND: + case VIDEO_TRY_COMMAND: + return ivtv_decoder_ioctls(file, cmd, (void *)arg); + default: return -EINVAL; } @@ -1792,18 +1804,6 @@ ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); return 0; - case IVTV_IOC_DMA_FRAME: - case VIDEO_GET_PTS: - case VIDEO_GET_FRAME_COUNT: - case VIDEO_GET_EVENT: - case VIDEO_PLAY: - case VIDEO_STOP: - case VIDEO_FREEZE: - case VIDEO_CONTINUE: - case VIDEO_COMMAND: - case VIDEO_TRY_COMMAND: - return ivtv_decoder_ioctls(filp, cmd, (void *)arg); - default: break; } --- linux-2.6.28.orig/drivers/media/video/cx23885/cx23885-video.c +++ linux-2.6.28/drivers/media/video/cx23885/cx23885-video.c @@ -730,12 +730,13 @@ lock_kernel(); list_for_each(list, &cx23885_devlist) { h = list_entry(list, struct cx23885_dev, devlist); - if (h->video_dev->minor == minor) { + if (h->video_dev && + h->video_dev->minor == minor) { dev = h; type = V4L2_BUF_TYPE_VIDEO_CAPTURE; } if (h->vbi_dev && - h->vbi_dev->minor == minor) { + h->vbi_dev->minor == minor) { dev = h; type = V4L2_BUF_TYPE_VBI_CAPTURE; } --- linux-2.6.28.orig/drivers/media/video/cx23885/cx23885-417.c +++ linux-2.6.28/drivers/media/video/cx23885/cx23885-417.c @@ -1585,7 +1585,8 @@ lock_kernel(); list_for_each(list, &cx23885_devlist) { h = list_entry(list, struct cx23885_dev, devlist); - if (h->v4l_device->minor == minor) { + if (h->v4l_device && + h->v4l_device->minor == minor) { dev = h; break; } --- linux-2.6.28.orig/drivers/media/video/uvc/uvc_video.c +++ linux-2.6.28/drivers/media/video/uvc/uvc_video.c @@ -935,11 +935,8 @@ break; } - /* Commit the default settings. */ probe->bFormatIndex = format->index; probe->bFrameIndex = frame->bFrameIndex; - if ((ret = uvc_set_video_ctrl(video, probe, 0)) < 0) - return ret; video->streaming->cur_format = format; video->streaming->cur_frame = frame; @@ -979,6 +976,10 @@ if ((ret = uvc_queue_enable(&video->queue, 1)) < 0) return ret; + /* Commit the streaming parameters. */ + if ((ret = uvc_set_video_ctrl(video, &video->streaming->ctrl, 0)) < 0) + return ret; + return uvc_init_video(video, GFP_KERNEL); } --- linux-2.6.28.orig/drivers/media/video/uvc/uvc_driver.c +++ linux-2.6.28/drivers/media/video/uvc/uvc_driver.c @@ -1984,6 +1984,15 @@ .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_PROBE_MINMAX }, + /* COMPAL JHL90 */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x064e, + .idProduct = 0xa115, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_PROBE_MINMAX }, /* Generic USB Video Class */ { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, {} --- linux-2.6.28.orig/drivers/media/video/uvc/uvc_v4l2.c +++ linux-2.6.28/drivers/media/video/uvc/uvc_v4l2.c @@ -252,9 +252,6 @@ if (ret < 0) return ret; - if ((ret = uvc_set_video_ctrl(video, &probe, 0)) < 0) - return ret; - memcpy(&video->streaming->ctrl, &probe, sizeof probe); video->streaming->cur_format = format; video->streaming->cur_frame = frame; @@ -315,10 +312,6 @@ if ((ret = uvc_probe_video(video, &probe)) < 0) return ret; - /* Commit the new settings. */ - if ((ret = uvc_set_video_ctrl(video, &probe, 0)) < 0) - return ret; - memcpy(&video->streaming->ctrl, &probe, sizeof probe); /* Return the actual frame period. */ --- linux-2.6.28.orig/drivers/media/video/mxc/capture/ipu_still.c +++ linux-2.6.28/drivers/media/video/mxc/capture/ipu_still.c @@ -0,0 +1,251 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @file ipu_still.c + * + * @brief IPU Use case for still image capture + * + * @ingroup IPU + */ + +#include +#include +#include +#include "mxc_v4l2_capture.h" +#include "ipu_prp_sw.h" + +static int callback_eof_flag; + +#ifdef CONFIG_MXC_IPU_V1 +static int callback_flag; +/* + * Function definitions + */ +/*! + * CSI EOF callback function. + * + * @param irq int irq line + * @param dev_id void * device id + * + * @return status IRQ_HANDLED for handled + */ +static irqreturn_t prp_csi_eof_callback(int irq, void *dev_id) +{ + if (callback_flag == 2) { + ipu_select_buffer(CSI_MEM, IPU_OUTPUT_BUFFER, 0); + ipu_enable_channel(CSI_MEM); + } + + callback_flag++; + return IRQ_HANDLED; +} +#endif + +/*! + * CSI callback function. + * + * @param irq int irq line + * @param dev_id void * device id + * + * @return status IRQ_HANDLED for handled + */ +static irqreturn_t prp_still_callback(int irq, void *dev_id) +{ + cam_data *cam = (cam_data *) dev_id; + + callback_eof_flag++; + if (callback_eof_flag < 5) + ipu_select_buffer(CSI_MEM, IPU_OUTPUT_BUFFER, 0); + else { + cam->still_counter++; + wake_up_interruptible(&cam->still_queue); + } + + return IRQ_HANDLED; +} + +/*! + * start csi->mem task + * @param private struct cam_data * mxc capture instance + * + * @return status + */ +static int prp_still_start(void *private) +{ + cam_data *cam = (cam_data *) private; + u32 pixel_fmt; + int err; + ipu_channel_params_t params; + + if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420) + pixel_fmt = IPU_PIX_FMT_YUV420P; + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV422P) + pixel_fmt = IPU_PIX_FMT_YUV422P; + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY) + pixel_fmt = IPU_PIX_FMT_UYVY; + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24) + pixel_fmt = IPU_PIX_FMT_BGR24; + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) + pixel_fmt = IPU_PIX_FMT_RGB24; + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565) + pixel_fmt = IPU_PIX_FMT_RGB565; + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR32) + pixel_fmt = IPU_PIX_FMT_BGR32; + else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB32) + pixel_fmt = IPU_PIX_FMT_RGB32; + else { + printk(KERN_ERR "format not supported\n"); + return -EINVAL; + } + + ipu_csi_enable_mclk_if(CSI_MCLK_RAW, cam->csi, true, true); + + memset(¶ms, 0, sizeof(params)); + err = ipu_init_channel(CSI_MEM, ¶ms); + if (err != 0) + return err; + + err = ipu_init_channel_buffer(CSI_MEM, IPU_OUTPUT_BUFFER, + pixel_fmt, cam->v2f.fmt.pix.width, + cam->v2f.fmt.pix.height, + cam->v2f.fmt.pix.width, IPU_ROTATE_NONE, + cam->still_buf, 0, 0, 0); + if (err != 0) + return err; + +#ifdef CONFIG_MXC_IPU_V1 + err = ipu_request_irq(IPU_IRQ_SENSOR_OUT_EOF, prp_still_callback, + 0, "Mxc Camera", cam); + if (err != 0) { + printk(KERN_ERR "Error registering irq.\n"); + return err; + } + callback_flag = 0; + callback_eof_flag = 0; + err = ipu_request_irq(IPU_IRQ_SENSOR_EOF, prp_csi_eof_callback, + 0, "Mxc Camera", NULL); + if (err != 0) { + printk(KERN_ERR "Error IPU_IRQ_SENSOR_EOF \n"); + return err; + } +#else + err = ipu_request_irq(IPU_IRQ_CSI0_OUT_EOF, prp_still_callback, + 0, "Mxc Camera", cam); + if (err != 0) { + printk(KERN_ERR "Error registering irq.\n"); + return err; + } + + callback_eof_flag = 0; + + ipu_select_buffer(CSI_MEM, IPU_OUTPUT_BUFFER, 0); + ipu_enable_channel(CSI_MEM); +#endif + + return err; +} + +/*! + * stop csi->mem encoder task + * @param private struct cam_data * mxc capture instance + * + * @return status + */ +static int prp_still_stop(void *private) +{ + cam_data *cam = (cam_data *) private; + int err = 0; + +#ifdef CONFIG_MXC_IPU_V1 + ipu_free_irq(IPU_IRQ_SENSOR_EOF, NULL); + ipu_free_irq(IPU_IRQ_SENSOR_OUT_EOF, cam); +#else + ipu_free_irq(IPU_IRQ_CSI0_OUT_EOF, cam); +#endif + + ipu_disable_channel(CSI_MEM, true); + ipu_uninit_channel(CSI_MEM); + ipu_csi_enable_mclk_if(CSI_MCLK_RAW, cam->csi, false, false); + + return err; +} + +/*! + * function to select CSI_MEM as the working path + * + * @param private struct cam_data * mxc capture instance + * + * @return status + */ +int prp_still_select(void *private) +{ + cam_data *cam = (cam_data *) private; + + if (cam) { + cam->csi_start = prp_still_start; + cam->csi_stop = prp_still_stop; + } + + return 0; +} + +/*! + * function to de-select CSI_MEM as the working path + * + * @param private struct cam_data * mxc capture instance + * + * @return status + */ +int prp_still_deselect(void *private) +{ + cam_data *cam = (cam_data *) private; + int err = 0; + + err = prp_still_stop(cam); + + if (cam) { + cam->csi_start = NULL; + cam->csi_stop = NULL; + } + + return err; +} + +/*! + * Init the Encorder channels + * + * @return Error code indicating success or failure + */ +__init int prp_still_init(void) +{ + return 0; +} + +/*! + * Deinit the Encorder channels + * + */ +void __exit prp_still_exit(void) +{ +} + +module_init(prp_still_init); +module_exit(prp_still_exit); + +EXPORT_SYMBOL(prp_still_select); +EXPORT_SYMBOL(prp_still_deselect); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("IPU PRP STILL IMAGE Driver"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/media/video/mxc/capture/ipu_prp_vf_sdc_bg.c +++ linux-2.6.28/drivers/media/video/mxc/capture/ipu_prp_vf_sdc_bg.c @@ -0,0 +1,411 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @file ipu_prp_vf_sdc_bg.c + * + * @brief IPU Use case for PRP-VF back-ground + * + * @ingroup IPU + */ +#include +#include +#include +#include "mxc_v4l2_capture.h" +#include "ipu_prp_sw.h" + +static int buffer_num = 0; +static int buffer_ready = 0; + +/* + * Function definitions + */ + +/*! + * SDC V-Sync callback function. + * + * @param irq int irq line + * @param dev_id void * device id + * + * @return status IRQ_HANDLED for handled + */ +static irqreturn_t prpvf_sdc_vsync_callback(int irq, void *dev_id) +{ + pr_debug("buffer_ready %d buffer_num %d\n", buffer_ready, buffer_num); + if (buffer_ready > 0) { + ipu_select_buffer(MEM_ROT_VF_MEM, IPU_OUTPUT_BUFFER, 0); + buffer_ready--; + } + + return IRQ_HANDLED; +} + +/*! + * VF EOF callback function. + * + * @param irq int irq line + * @param dev_id void * device id + * + * @return status IRQ_HANDLED for handled + */ +static irqreturn_t prpvf_vf_eof_callback(int irq, void *dev_id) +{ + pr_debug("buffer_ready %d buffer_num %d\n", buffer_ready, buffer_num); + + ipu_select_buffer(MEM_ROT_VF_MEM, IPU_INPUT_BUFFER, buffer_num); + + buffer_num = (buffer_num == 0) ? 1 : 0; + + ipu_select_buffer(CSI_PRP_VF_MEM, IPU_OUTPUT_BUFFER, buffer_num); + buffer_ready++; + return IRQ_HANDLED; +} + +/*! + * prpvf_start - start the vf task + * + * @param private cam_data * mxc v4l2 main structure + * + */ +static int prpvf_start(void *private) +{ + cam_data *cam = (cam_data *) private; + ipu_channel_params_t vf; + u32 format; + u32 offset; + u32 bpp, size = 3; + int err = 0; + + if (!cam) { + printk(KERN_ERR "private is NULL\n"); + return -EIO; + } + + if (cam->overlay_active == true) { + pr_debug("already start.\n"); + return 0; + } + + format = cam->v4l2_fb.fmt.pixelformat; + if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_BGR24) { + bpp = 3, size = 3; + pr_info("BGR24\n"); + } else if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_RGB565) { + bpp = 2, size = 2; + pr_info("RGB565\n"); + } else if (cam->v4l2_fb.fmt.pixelformat == IPU_PIX_FMT_BGR32) { + bpp = 4, size = 4; + pr_info("BGR32\n"); + } else { + printk(KERN_ERR + "unsupported fix format from the framebuffer.\n"); + return -EINVAL; + } + + offset = cam->v4l2_fb.fmt.bytesperline * cam->win.w.top + + size * cam->win.w.left; + + if (cam->v4l2_fb.base == 0) { + printk(KERN_ERR "invalid frame buffer address.\n"); + } else { + offset += (u32) cam->v4l2_fb.base; + } + + memset(&vf, 0, sizeof(ipu_channel_params_t)); + ipu_csi_get_window_size(&vf.csi_prp_vf_mem.in_width, + &vf.csi_prp_vf_mem.in_height, cam->csi); + vf.csi_prp_vf_mem.in_pixel_fmt = IPU_PIX_FMT_UYVY; + vf.csi_prp_vf_mem.out_width = cam->win.w.width; + vf.csi_prp_vf_mem.out_height = cam->win.w.height; + vf.csi_prp_vf_mem.csi = cam->csi; + if (cam->rotation >= IPU_ROTATE_90_RIGHT) { + vf.csi_prp_vf_mem.out_width = cam->win.w.height; + vf.csi_prp_vf_mem.out_height = cam->win.w.width; + } + vf.csi_prp_vf_mem.out_pixel_fmt = format; + size = cam->win.w.width * cam->win.w.height * size; + + err = ipu_init_channel(CSI_PRP_VF_MEM, &vf); + if (err != 0) + goto out_4; + + ipu_csi_enable_mclk_if(CSI_MCLK_VF, cam->csi, true, true); + + if (cam->vf_bufs_vaddr[0]) { + dma_free_coherent(0, cam->vf_bufs_size[0], + cam->vf_bufs_vaddr[0], cam->vf_bufs[0]); + } + if (cam->vf_bufs_vaddr[1]) { + dma_free_coherent(0, cam->vf_bufs_size[1], + cam->vf_bufs_vaddr[1], cam->vf_bufs[1]); + } + cam->vf_bufs_size[0] = PAGE_ALIGN(size); + cam->vf_bufs_vaddr[0] = (void *)dma_alloc_coherent(0, + cam->vf_bufs_size[0], + &cam->vf_bufs[0], + GFP_DMA | + GFP_KERNEL); + if (cam->vf_bufs_vaddr[0] == NULL) { + printk(KERN_ERR "Error to allocate vf buffer\n"); + err = -ENOMEM; + goto out_3; + } + cam->vf_bufs_size[1] = PAGE_ALIGN(size); + cam->vf_bufs_vaddr[1] = (void *)dma_alloc_coherent(0, + cam->vf_bufs_size[1], + &cam->vf_bufs[1], + GFP_DMA | + GFP_KERNEL); + if (cam->vf_bufs_vaddr[1] == NULL) { + printk(KERN_ERR "Error to allocate vf buffer\n"); + err = -ENOMEM; + goto out_3; + } + + err = ipu_init_channel_buffer(CSI_PRP_VF_MEM, IPU_OUTPUT_BUFFER, + format, vf.csi_prp_vf_mem.out_width, + vf.csi_prp_vf_mem.out_height, + vf.csi_prp_vf_mem.out_width, + IPU_ROTATE_NONE, cam->vf_bufs[0], + cam->vf_bufs[1], 0, 0); + if (err != 0) { + printk(KERN_ERR "Error initializing CSI_PRP_VF_MEM\n"); + goto out_3; + } + err = ipu_init_channel(MEM_ROT_VF_MEM, NULL); + if (err != 0) { + printk(KERN_ERR "Error MEM_ROT_VF_MEM channel\n"); + goto out_3; + } + + err = ipu_init_channel_buffer(MEM_ROT_VF_MEM, IPU_INPUT_BUFFER, + format, vf.csi_prp_vf_mem.out_width, + vf.csi_prp_vf_mem.out_height, + vf.csi_prp_vf_mem.out_width, + cam->rotation, cam->vf_bufs[0], + cam->vf_bufs[1], 0, 0); + if (err != 0) { + printk(KERN_ERR "Error MEM_ROT_VF_MEM input buffer\n"); + goto out_2; + } + + if (cam->rotation >= IPU_ROTATE_90_RIGHT) { + err = ipu_init_channel_buffer(MEM_ROT_VF_MEM, IPU_OUTPUT_BUFFER, + format, + vf.csi_prp_vf_mem.out_height, + vf.csi_prp_vf_mem.out_width, + cam->overlay_fb->var.xres * bpp, + IPU_ROTATE_NONE, offset, 0, 0, 0); + + if (err != 0) { + printk(KERN_ERR "Error MEM_ROT_VF_MEM output buffer\n"); + goto out_2; + } + } else { + err = ipu_init_channel_buffer(MEM_ROT_VF_MEM, IPU_OUTPUT_BUFFER, + format, + vf.csi_prp_vf_mem.out_width, + vf.csi_prp_vf_mem.out_height, + cam->overlay_fb->var.xres * bpp, + IPU_ROTATE_NONE, offset, 0, 0, 0); + if (err != 0) { + printk(KERN_ERR "Error MEM_ROT_VF_MEM output buffer\n"); + goto out_2; + } + } + + err = ipu_request_irq(IPU_IRQ_PRP_VF_OUT_EOF, prpvf_vf_eof_callback, + 0, "Mxc Camera", cam); + if (err != 0) { + printk(KERN_ERR + "Error registering IPU_IRQ_PRP_VF_OUT_EOF irq.\n"); + goto out_2; + } + + err = ipu_request_irq(IPU_IRQ_BG_SF_END, prpvf_sdc_vsync_callback, + 0, "Mxc Camera", NULL); + if (err != 0) { + printk(KERN_ERR "Error registering IPU_IRQ_BG_SF_END irq.\n"); + goto out_1; + } + + ipu_enable_channel(CSI_PRP_VF_MEM); + ipu_enable_channel(MEM_ROT_VF_MEM); + + buffer_num = 0; + buffer_ready = 0; + ipu_select_buffer(CSI_PRP_VF_MEM, IPU_OUTPUT_BUFFER, 0); + + cam->overlay_active = true; + return err; + + out_1: + ipu_free_irq(IPU_IRQ_PRP_VF_OUT_EOF, NULL); + out_2: + ipu_uninit_channel(MEM_ROT_VF_MEM); + out_3: + ipu_uninit_channel(CSI_PRP_VF_MEM); + out_4: + if (cam->vf_bufs_vaddr[0]) { + dma_free_coherent(0, cam->vf_bufs_size[0], + cam->vf_bufs_vaddr[0], cam->vf_bufs[0]); + cam->vf_bufs_vaddr[0] = NULL; + cam->vf_bufs[0] = 0; + } + if (cam->vf_bufs_vaddr[1]) { + dma_free_coherent(0, cam->vf_bufs_size[1], + cam->vf_bufs_vaddr[1], cam->vf_bufs[1]); + cam->vf_bufs_vaddr[1] = NULL; + cam->vf_bufs[1] = 0; + } + if (cam->rot_vf_bufs_vaddr[0]) { + dma_free_coherent(0, cam->rot_vf_buf_size[0], + cam->rot_vf_bufs_vaddr[0], + cam->rot_vf_bufs[0]); + cam->rot_vf_bufs_vaddr[0] = NULL; + cam->rot_vf_bufs[0] = 0; + } + if (cam->rot_vf_bufs_vaddr[1]) { + dma_free_coherent(0, cam->rot_vf_buf_size[1], + cam->rot_vf_bufs_vaddr[1], + cam->rot_vf_bufs[1]); + cam->rot_vf_bufs_vaddr[1] = NULL; + cam->rot_vf_bufs[1] = 0; + } + return err; +} + +/*! + * prpvf_stop - stop the vf task + * + * @param private cam_data * mxc v4l2 main structure + * + */ +static int prpvf_stop(void *private) +{ + cam_data *cam = (cam_data *) private; + + if (cam->overlay_active == false) + return 0; + + ipu_free_irq(IPU_IRQ_BG_SF_END, NULL); + + ipu_free_irq(IPU_IRQ_PRP_VF_OUT_EOF, cam); + + ipu_disable_channel(CSI_PRP_VF_MEM, true); + ipu_disable_channel(MEM_ROT_VF_MEM, true); + ipu_uninit_channel(CSI_PRP_VF_MEM); + ipu_uninit_channel(MEM_ROT_VF_MEM); + ipu_csi_enable_mclk_if(CSI_MCLK_VF, cam->csi, false, false); + + if (cam->vf_bufs_vaddr[0]) { + dma_free_coherent(0, cam->vf_bufs_size[0], + cam->vf_bufs_vaddr[0], cam->vf_bufs[0]); + cam->vf_bufs_vaddr[0] = NULL; + cam->vf_bufs[0] = 0; + } + if (cam->vf_bufs_vaddr[1]) { + dma_free_coherent(0, cam->vf_bufs_size[1], + cam->vf_bufs_vaddr[1], cam->vf_bufs[1]); + cam->vf_bufs_vaddr[1] = NULL; + cam->vf_bufs[1] = 0; + } + if (cam->rot_vf_bufs_vaddr[0]) { + dma_free_coherent(0, cam->rot_vf_buf_size[0], + cam->rot_vf_bufs_vaddr[0], + cam->rot_vf_bufs[0]); + cam->rot_vf_bufs_vaddr[0] = NULL; + cam->rot_vf_bufs[0] = 0; + } + if (cam->rot_vf_bufs_vaddr[1]) { + dma_free_coherent(0, cam->rot_vf_buf_size[1], + cam->rot_vf_bufs_vaddr[1], + cam->rot_vf_bufs[1]); + cam->rot_vf_bufs_vaddr[1] = NULL; + cam->rot_vf_bufs[1] = 0; + } + + buffer_num = 0; + buffer_ready = 0; + cam->overlay_active = false; + return 0; +} + +/*! + * function to select PRP-VF as the working path + * + * @param private cam_data * mxc v4l2 main structure + * + * @return status + */ +int prp_vf_sdc_select_bg(void *private) +{ + cam_data *cam = (cam_data *) private; + + if (cam) { + cam->vf_start_sdc = prpvf_start; + cam->vf_stop_sdc = prpvf_stop; + cam->overlay_active = false; + } + + return 0; +} + +/*! + * function to de-select PRP-VF as the working path + * + * @param private cam_data * mxc v4l2 main structure + * + * @return status + */ +int prp_vf_sdc_deselect_bg(void *private) +{ + cam_data *cam = (cam_data *) private; + int err = 0; + err = prpvf_stop(private); + + if (cam) { + cam->vf_start_sdc = NULL; + cam->vf_stop_sdc = NULL; + } + return err; +} + +/*! + * Init viewfinder task. + * + * @return Error code indicating success or failure + */ +__init int prp_vf_sdc_init_bg(void) +{ + return 0; +} + +/*! + * Deinit viewfinder task. + * + * @return Error code indicating success or failure + */ +void __exit prp_vf_sdc_exit_bg(void) +{ +} + +module_init(prp_vf_sdc_init_bg); +module_exit(prp_vf_sdc_exit_bg); + +EXPORT_SYMBOL(prp_vf_sdc_select_bg); +EXPORT_SYMBOL(prp_vf_sdc_deselect_bg); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("IPU PRP VF SDC Backgroud Driver"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/media/video/mxc/capture/ipu_prp_sw.h +++ linux-2.6.28/drivers/media/video/mxc/capture/ipu_prp_sw.h @@ -0,0 +1,36 @@ +/* + * Copyright 2004-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 + */ + +/*! + * @file ipu_prp_sw.h + * + * @brief This file contains the IPU PRP use case driver header. + * + * @ingroup IPU + */ + +#ifndef _INCLUDE_IPU__PRP_SW_H_ +#define _INCLUDE_IPU__PRP_SW_H_ + +int prp_enc_select(void *private); +int prp_enc_deselect(void *private); +int prp_vf_adc_select(void *private); +int prp_vf_sdc_select(void *private); +int prp_vf_sdc_select_bg(void *private); +int prp_vf_adc_deselect(void *private); +int prp_vf_sdc_deselect(void *private); +int prp_vf_sdc_deselect_bg(void *private); +int prp_still_select(void *private); +int prp_still_deselect(void *private); + +#endif --- linux-2.6.28.orig/drivers/media/video/mxc/capture/ov3640.c +++ linux-2.6.28/drivers/media/video/mxc/capture/ov3640.c @@ -0,0 +1,1112 @@ +/* + * Copyright 2005-2009 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 + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mxc_v4l2_capture.h" + +#define CAMERA_DBG + +#ifdef CAMERA_DBG + #define CAMERA_TRACE(x) (printk)x +#else + #define CAMERA_TRACE(x) +#endif + +#define OV3640_VOLTAGE_ANALOG 2800000 +#define OV3640_VOLTAGE_DIGITAL_CORE 1500000 +#define OV3640_VOLTAGE_DIGITAL_IO 1800000 + + +/* Check these values! */ +#define MIN_FPS 15 +#define MAX_FPS 30 +#define DEFAULT_FPS 30 + +#define OV3640_XCLK_MIN 6000000 +#define OV3640_XCLK_MAX 24000000 + +enum ov3640_mode { + ov3640_mode_MIN = 0, + ov3640_mode_VGA_640_480 = 0, + ov3640_mode_QVGA_320_240 = 1, + ov3640_mode_QXGA_2048_1536 = 2, + ov3640_mode_XGA_1024_768 = 3, + ov3640_mode_MAX = 3 +}; + +enum ov3640_frame_rate { + ov3640_15_fps, + ov3640_30_fps +}; + +struct reg_value { + u16 u16RegAddr; + u8 u8Val; + u8 u8Mask; + u32 u32Delay_ms; +}; + +struct ov3640_mode_info { + enum ov3640_mode mode; + u32 width; + u32 height; + struct reg_value *init_data_ptr; + u32 init_data_size; +}; + +/*! + * Maintains the information on the current state of the sesor. + */ +struct sensor { + const struct ov3640_platform_data *platform_data; + struct v4l2_int_device *v4l2_int_device; + struct i2c_client *i2c_client; + struct v4l2_pix_format pix; + struct v4l2_captureparm streamcap; + bool on; + + /* control settings */ + int brightness; + int hue; + int contrast; + int saturation; + int red; + int green; + int blue; + int ae_mode; + + u32 mclk; + int csi; +} ov3640_data; + +static struct reg_value ov3640_setting_15fps_QXGA_2048_1536[] = { + {0x3012, 0x80, 0, 0}, {0x304d, 0x45, 0, 0}, {0x30a7, 0x5e, 0, 0}, + {0x3087, 0x16, 0, 0}, {0x309c, 0x1a, 0, 0}, {0x30a2, 0xe4, 0, 0}, + {0x30aa, 0x42, 0, 0}, {0x30b0, 0xff, 0, 0}, {0x30b1, 0xff, 0, 0}, + {0x30b2, 0x10, 0, 0}, {0x300e, 0x32, 0, 0}, {0x300f, 0x21, 0, 0}, + {0x3010, 0x20, 0, 0}, {0x3011, 0x00, 0, 0}, {0x304c, 0x81, 0, 0}, + {0x30d7, 0x10, 0, 0}, {0x30d9, 0x0d, 0, 0}, {0x30db, 0x08, 0, 0}, + {0x3016, 0x82, 0, 0}, {0x3018, 0x38, 0, 0}, {0x3019, 0x30, 0, 0}, + {0x301a, 0x61, 0, 0}, {0x307d, 0x00, 0, 0}, {0x3087, 0x02, 0, 0}, + {0x3082, 0x20, 0, 0}, {0x3015, 0x12, 0, 0}, {0x3014, 0x04, 0, 0}, + {0x3013, 0xf7, 0, 0}, {0x303c, 0x08, 0, 0}, {0x303d, 0x18, 0, 0}, + {0x303e, 0x06, 0, 0}, {0x303f, 0x0c, 0, 0}, {0x3030, 0x62, 0, 0}, + {0x3031, 0x26, 0, 0}, {0x3032, 0xe6, 0, 0}, {0x3033, 0x6e, 0, 0}, + {0x3034, 0xea, 0, 0}, {0x3035, 0xae, 0, 0}, {0x3036, 0xa6, 0, 0}, + {0x3037, 0x6a, 0, 0}, {0x3104, 0x02, 0, 0}, {0x3105, 0xfd, 0, 0}, + {0x3106, 0x00, 0, 0}, {0x3107, 0xff, 0, 0}, {0x3300, 0x12, 0, 0}, + {0x3301, 0xde, 0, 0}, {0x3302, 0xcf, 0, 0}, {0x3312, 0x26, 0, 0}, + {0x3314, 0x42, 0, 0}, {0x3313, 0x2b, 0, 0}, {0x3315, 0x42, 0, 0}, + {0x3310, 0xd0, 0, 0}, {0x3311, 0xbd, 0, 0}, {0x330c, 0x18, 0, 0}, + {0x330d, 0x18, 0, 0}, {0x330e, 0x56, 0, 0}, {0x330f, 0x5c, 0, 0}, + {0x330b, 0x1c, 0, 0}, {0x3306, 0x5c, 0, 0}, {0x3307, 0x11, 0, 0}, + {0x336a, 0x52, 0, 0}, {0x3370, 0x46, 0, 0}, {0x3376, 0x38, 0, 0}, + {0x30b8, 0x20, 0, 0}, {0x30b9, 0x17, 0, 0}, {0x30ba, 0x04, 0, 0}, + {0x30bb, 0x08, 0, 0}, {0x3507, 0x06, 0, 0}, {0x350a, 0x4f, 0, 0}, + {0x3100, 0x02, 0, 0}, {0x3301, 0xde, 0, 0}, {0x3304, 0x00, 0, 0}, + {0x3400, 0x00, 0, 0}, {0x3404, 0x02, 0, 0}, {0x3600, 0xc4, 0, 0}, + {0x3302, 0xef, 0, 0}, {0x3020, 0x01, 0, 0}, {0x3021, 0x1d, 0, 0}, + {0x3022, 0x00, 0, 0}, {0x3023, 0x0a, 0, 0}, {0x3024, 0x08, 0, 0}, + {0x3025, 0x00, 0, 0}, {0x3026, 0x06, 0, 0}, {0x3027, 0x00, 0, 0}, + {0x335f, 0x68, 0, 0}, {0x3360, 0x00, 0, 0}, {0x3361, 0x00, 0, 0}, + {0x3362, 0x68, 0, 0}, {0x3363, 0x00, 0, 0}, {0x3364, 0x00, 0, 0}, + {0x3403, 0x00, 0, 0}, {0x3088, 0x08, 0, 0}, {0x3089, 0x00, 0, 0}, + {0x308a, 0x06, 0, 0}, {0x308b, 0x00, 0, 0}, {0x307c, 0x10, 0, 0}, + {0x3090, 0xc0, 0, 0}, {0x304c, 0x84, 0, 0}, {0x308d, 0x04, 0, 0}, + {0x3086, 0x03, 0, 0}, {0x3086, 0x00, 0, 0}, {0x3012, 0x00, 0, 0}, + {0x3020, 0x01, 0, 0}, {0x3021, 0x1d, 0, 0}, {0x3022, 0x00, 0, 0}, + {0x3023, 0x0a, 0, 0}, {0x3024, 0x08, 0, 0}, {0x3025, 0x18, 0, 0}, + {0x3026, 0x06, 0, 0}, {0x3027, 0x0c, 0, 0}, {0x302a, 0x06, 0, 0}, + {0x302b, 0x20, 0, 0}, {0x3075, 0x44, 0, 0}, {0x300d, 0x00, 0, 0}, + {0x30d7, 0x00, 0, 0}, {0x3069, 0x40, 0, 0}, {0x303e, 0x01, 0, 0}, + {0x303f, 0x80, 0, 0}, {0x3302, 0x20, 0, 0}, {0x335f, 0x68, 0, 0}, + {0x3360, 0x18, 0, 0}, {0x3361, 0x0c, 0, 0}, {0x3362, 0x68, 0, 0}, + {0x3363, 0x08, 0, 0}, {0x3364, 0x04, 0, 0}, {0x3403, 0x42, 0, 0}, + {0x3088, 0x08, 0, 0}, {0x3089, 0x00, 0, 0}, {0x308a, 0x06, 0, 0}, + {0x308b, 0x00, 0, 0}, +}; + +static struct reg_value ov3640_setting_15fps_XGA_1024_768[] = { + {0x3012, 0x80, 0, 0}, {0x304d, 0x45, 0, 0}, {0x30a7, 0x5e, 0, 0}, + {0x3087, 0x16, 0, 0}, {0x309c, 0x1a, 0, 0}, {0x30a2, 0xe4, 0, 0}, + {0x30aa, 0x42, 0, 0}, {0x30b0, 0xff, 0, 0}, {0x30b1, 0xff, 0, 0}, + {0x30b2, 0x10, 0, 0}, {0x300e, 0x32, 0, 0}, {0x300f, 0x21, 0, 0}, + {0x3010, 0x20, 0, 0}, {0x3011, 0x00, 0, 0}, {0x304c, 0x81, 0, 0}, + {0x3016, 0x82, 0, 0}, {0x3018, 0x38, 0, 0}, {0x3019, 0x30, 0, 0}, + {0x301a, 0x61, 0, 0}, {0x307d, 0x00, 0, 0}, {0x3087, 0x02, 0, 0}, + {0x3082, 0x20, 0, 0}, {0x3015, 0x12, 0, 0}, {0x3014, 0x04, 0, 0}, + {0x3013, 0xf7, 0, 0}, {0x303c, 0x08, 0, 0}, {0x303d, 0x18, 0, 0}, + {0x303e, 0x06, 0, 0}, {0x303f, 0x0c, 0, 0}, {0x3030, 0x62, 0, 0}, + {0x3031, 0x26, 0, 0}, {0x3032, 0xe6, 0, 0}, {0x3033, 0x6e, 0, 0}, + {0x3034, 0xea, 0, 0}, {0x3035, 0xae, 0, 0}, {0x3036, 0xa6, 0, 0}, + {0x3037, 0x6a, 0, 0}, {0x3104, 0x02, 0, 0}, {0x3105, 0xfd, 0, 0}, + {0x3106, 0x00, 0, 0}, {0x3107, 0xff, 0, 0}, {0x3300, 0x12, 0, 0}, + {0x3301, 0xde, 0, 0}, {0x3302, 0xcf, 0, 0}, {0x3312, 0x26, 0, 0}, + {0x3314, 0x42, 0, 0}, {0x3313, 0x2b, 0, 0}, {0x3315, 0x42, 0, 0}, + {0x3310, 0xd0, 0, 0}, {0x3311, 0xbd, 0, 0}, {0x330c, 0x18, 0, 0}, + {0x330d, 0x18, 0, 0}, {0x330e, 0x56, 0, 0}, {0x330f, 0x5c, 0, 0}, + {0x330b, 0x1c, 0, 0}, {0x3306, 0x5c, 0, 0}, {0x3307, 0x11, 0, 0}, + {0x336a, 0x52, 0, 0}, {0x3370, 0x46, 0, 0}, {0x3376, 0x38, 0, 0}, + {0x30b8, 0x20, 0, 0}, {0x30b9, 0x17, 0, 0}, {0x30ba, 0x04, 0, 0}, + {0x30bb, 0x08, 0, 0}, {0x3507, 0x06, 0, 0}, {0x350a, 0x4f, 0, 0}, + {0x3100, 0x02, 0, 0}, {0x3301, 0xde, 0, 0}, {0x3304, 0x00, 0, 0}, + {0x3400, 0x01, 0, 0}, {0x3404, 0x1d, 0, 0}, {0x3600, 0xc4, 0, 0}, + {0x3302, 0xef, 0, 0}, {0x3020, 0x01, 0, 0}, {0x3021, 0x1d, 0, 0}, + {0x3022, 0x00, 0, 0}, {0x3023, 0x0a, 0, 0}, {0x3024, 0x08, 0, 0}, + {0x3025, 0x00, 0, 0}, {0x3026, 0x06, 0, 0}, {0x3027, 0x00, 0, 0}, + {0x335f, 0x68, 0, 0}, {0x3360, 0x00, 0, 0}, {0x3361, 0x00, 0, 0}, + {0x3362, 0x34, 0, 0}, {0x3363, 0x00, 0, 0}, {0x3364, 0x00, 0, 0}, + {0x3403, 0x00, 0, 0}, {0x3088, 0x04, 0, 0}, {0x3089, 0x00, 0, 0}, + {0x308a, 0x03, 0, 0}, {0x308b, 0x00, 0, 0}, {0x307c, 0x10, 0, 0}, + {0x3090, 0xc0, 0, 0}, {0x304c, 0x84, 0, 0}, {0x308d, 0x04, 0, 0}, + {0x3086, 0x03, 0, 0}, {0x3086, 0x00, 0, 0}, {0x3011, 0x01, 0, 0}, +}; + +static struct reg_value ov3640_setting_30fps_XGA_1024_768[] = { + {0x0, 0x0, 0} +}; + +static struct reg_value ov3640_setting_15fps_VGA_640_480[] = { + {0x3012, 0x80, 0, 0}, {0x304d, 0x45, 0, 0}, {0x30a7, 0x5e, 0, 0}, + {0x3087, 0x16, 0, 0}, {0x309c, 0x1a, 0, 0}, {0x30a2, 0xe4, 0, 0}, + {0x30aa, 0x42, 0, 0}, {0x30b0, 0xff, 0, 0}, {0x30b1, 0xff, 0, 0}, + {0x30b2, 0x10, 0, 0}, {0x300e, 0x32, 0, 0}, {0x300f, 0x21, 0, 0}, + {0x3010, 0x20, 0, 0}, {0x3011, 0x00, 0, 0}, {0x304c, 0x81, 0, 0}, + {0x30d7, 0x10, 0, 0}, {0x30d9, 0x0d, 0, 0}, {0x30db, 0x08, 0, 0}, + {0x3016, 0x82, 0, 0}, {0x3018, 0x38, 0, 0}, {0x3019, 0x30, 0, 0}, + {0x301a, 0x61, 0, 0}, {0x307d, 0x00, 0, 0}, {0x3087, 0x02, 0, 0}, + {0x3082, 0x20, 0, 0}, {0x3015, 0x12, 0, 0}, {0x3014, 0x04, 0, 0}, + {0x3013, 0xf7, 0, 0}, {0x303c, 0x08, 0, 0}, {0x303d, 0x18, 0, 0}, + {0x303e, 0x06, 0, 0}, {0x303f, 0x0c, 0, 0}, {0x3030, 0x62, 0, 0}, + {0x3031, 0x26, 0, 0}, {0x3032, 0xe6, 0, 0}, {0x3033, 0x6e, 0, 0}, + {0x3034, 0xea, 0, 0}, {0x3035, 0xae, 0, 0}, {0x3036, 0xa6, 0, 0}, + {0x3037, 0x6a, 0, 0}, {0x3104, 0x02, 0, 0}, {0x3105, 0xfd, 0, 0}, + {0x3106, 0x00, 0, 0}, {0x3107, 0xff, 0, 0}, {0x3300, 0x12, 0, 0}, + {0x3301, 0xde, 0, 0}, {0x3302, 0xcf, 0, 0}, {0x3312, 0x26, 0, 0}, + {0x3314, 0x42, 0, 0}, {0x3313, 0x2b, 0, 0}, {0x3315, 0x42, 0, 0}, + {0x3310, 0xd0, 0, 0}, {0x3311, 0xbd, 0, 0}, {0x330c, 0x18, 0, 0}, + {0x330d, 0x18, 0, 0}, {0x330e, 0x56, 0, 0}, {0x330f, 0x5c, 0, 0}, + {0x330b, 0x1c, 0, 0}, {0x3306, 0x5c, 0, 0}, {0x3307, 0x11, 0, 0}, + {0x336a, 0x52, 0, 0}, {0x3370, 0x46, 0, 0}, {0x3376, 0x38, 0, 0}, + {0x30b8, 0x20, 0, 0}, {0x30b9, 0x17, 0, 0}, {0x30ba, 0x04, 0, 0}, + {0x30bb, 0x08, 0, 0}, {0x3507, 0x06, 0, 0}, {0x350a, 0x4f, 0, 0}, + {0x3100, 0x02, 0, 0}, {0x3301, 0xde, 0, 0}, {0x3304, 0x00, 0, 0}, + {0x3400, 0x00, 0, 0}, {0x3404, 0x42, 0, 0}, {0x3600, 0xc4, 0, 0}, + {0x3302, 0xef, 0, 0}, {0x3020, 0x01, 0, 0}, {0x3021, 0x1d, 0, 0}, + {0x3022, 0x00, 0, 0}, {0x3023, 0x0a, 0, 0}, {0x3024, 0x08, 0, 0}, + {0x3025, 0x00, 0, 0}, {0x3026, 0x06, 0, 0}, {0x3027, 0x00, 0, 0}, + {0x335f, 0x68, 0, 0}, {0x3360, 0x00, 0, 0}, {0x3361, 0x00, 0, 0}, + {0x3362, 0x12, 0, 0}, {0x3363, 0x80, 0, 0}, {0x3364, 0xe0, 0, 0}, + {0x3403, 0x00, 0, 0}, {0x3088, 0x02, 0, 0}, {0x3089, 0x80, 0, 0}, + {0x308a, 0x01, 0, 0}, {0x308b, 0xe0, 0, 0}, {0x307c, 0x10, 0, 0}, + {0x3090, 0xc0, 0, 0}, {0x304c, 0x84, 0, 0}, {0x308d, 0x04, 0, 0}, + {0x3086, 0x03, 0, 0}, {0x3086, 0x00, 0, 0}, {0x3011, 0x00, 0, 0}, +}; + +static struct reg_value ov3640_setting_30fps_VGA_640_480[] = { + {0x3012, 0x80, 0, 0}, {0x304d, 0x45, 0, 0}, {0x30a7, 0x5e, 0, 0}, + {0x3087, 0x16, 0, 0}, {0x309c, 0x1a, 0, 0}, {0x30a2, 0xe4, 0, 0}, + {0x30aa, 0x42, 0, 0}, {0x30b0, 0xff, 0, 0}, {0x30b1, 0xff, 0, 0}, + {0x30b2, 0x10, 0, 0}, {0x300e, 0x32, 0, 0}, {0x300f, 0x21, 0, 0}, + {0x3010, 0x20, 0, 0}, {0x3011, 0x01, 0, 0}, {0x304c, 0x82, 0, 0}, + {0x30d7, 0x10, 0, 0}, {0x30d9, 0x0d, 0, 0}, {0x30db, 0x08, 0, 0}, + {0x3016, 0x82, 0, 0}, {0x3018, 0x38, 0, 0}, {0x3019, 0x30, 0, 0}, + {0x301a, 0x61, 0, 0}, {0x307d, 0x00, 0, 0}, {0x3087, 0x02, 0, 0}, + {0x3082, 0x20, 0, 0}, {0x3015, 0x12, 0, 0}, {0x3014, 0x0c, 0, 0}, + {0x3013, 0xf7, 0, 0}, {0x303c, 0x08, 0, 0}, {0x303d, 0x18, 0, 0}, + {0x303e, 0x06, 0, 0}, {0x303f, 0x0c, 0, 0}, {0x3030, 0x62, 0, 0}, + {0x3031, 0x26, 0, 0}, {0x3032, 0xe6, 0, 0}, {0x3033, 0x6e, 0, 0}, + {0x3034, 0xea, 0, 0}, {0x3035, 0xae, 0, 0}, {0x3036, 0xa6, 0, 0}, + {0x3037, 0x6a, 0, 0}, {0x3104, 0x02, 0, 0}, {0x3105, 0xfd, 0, 0}, + {0x3106, 0x00, 0, 0}, {0x3107, 0xff, 0, 0}, {0x3300, 0x12, 0, 0}, + {0x3301, 0xde, 0, 0}, {0x3302, 0xcf, 0, 0}, {0x3312, 0x26, 0, 0}, + {0x3314, 0x42, 0, 0}, {0x3313, 0x2b, 0, 0}, {0x3315, 0x42, 0, 0}, + {0x3310, 0xd0, 0, 0}, {0x3311, 0xbd, 0, 0}, {0x330c, 0x18, 0, 0}, + {0x330d, 0x18, 0, 0}, {0x330e, 0x56, 0, 0}, {0x330f, 0x5c, 0, 0}, + {0x330b, 0x1c, 0, 0}, {0x3306, 0x5c, 0, 0}, {0x3307, 0x11, 0, 0}, + {0x336a, 0x52, 0, 0}, {0x3370, 0x46, 0, 0}, {0x3376, 0x38, 0, 0}, + {0x3300, 0x13, 0, 0}, {0x30b8, 0x20, 0, 0}, {0x30b9, 0x17, 0, 0}, + {0x30ba, 0x04, 0, 0}, {0x30bb, 0x08, 0, 0}, {0x3100, 0x02, 0, 0}, + {0x3301, 0x10, 0x30, 0}, {0x3304, 0x00, 0x03, 0}, {0x3400, 0x00, 0, 0}, + {0x3404, 0x02, 0, 0}, {0x3600, 0xc0, 0, 0}, {0x308d, 0x04, 0, 0}, + {0x3086, 0x03, 0, 0}, {0x3086, 0x00, 0, 0}, {0x3012, 0x10, 0, 0}, + {0x3023, 0x06, 0, 0}, {0x3026, 0x03, 0, 0}, {0x3027, 0x04, 0, 0}, + {0x302a, 0x03, 0, 0}, {0x302b, 0x10, 0, 0}, {0x3075, 0x24, 0, 0}, + {0x300d, 0x01, 0, 0}, {0x30d7, 0x80, 0x80, 0}, {0x3069, 0x00, 0x40, 0}, + {0x303e, 0x00, 0, 0}, {0x303f, 0xc0, 0, 0}, {0x3302, 0x20, 0x20, 0}, + {0x335f, 0x34, 0, 0}, {0x3360, 0x0c, 0, 0}, {0x3361, 0x04, 0, 0}, + {0x3362, 0x12, 0, 0}, {0x3363, 0x88, 0, 0}, {0x3364, 0xe4, 0, 0}, + {0x3403, 0x42, 0, 0}, {0x3088, 0x02, 0, 0}, {0x3089, 0x80, 0, 0}, + {0x308a, 0x01, 0, 0}, {0x308b, 0xe0, 0, 0}, {0x3362, 0x12, 0, 0}, + {0x3363, 0x88, 0, 0}, {0x3364, 0xe4, 0, 0}, {0x3403, 0x42, 0, 0}, + {0x3088, 0x02, 0, 0}, {0x3089, 0x80, 0, 0}, {0x308a, 0x01, 0, 0}, + {0x308b, 0xe0, 0, 0}, {0x300e, 0x37, 0, 0}, {0x300f, 0xe1, 0, 0}, + {0x3010, 0x22, 0, 0}, {0x3011, 0x01, 0, 0}, {0x304c, 0x84, 0, 0}, + {0x3014, 0x04, 0, 0}, {0x3015, 0x02, 0, 0}, {0x302e, 0x00, 0, 0}, + {0x302d, 0x00, 0, 0}, +}; + +static struct reg_value ov3640_setting_15fps_QVGA_320_240[] = { + {0x3012, 0x80, 0, 0}, {0x304d, 0x45, 0, 0}, {0x30a7, 0x5e, 0, 0}, + {0x3087, 0x16, 0, 0}, {0x309c, 0x1a, 0, 0}, {0x30a2, 0xe4, 0, 0}, + {0x30aa, 0x42, 0, 0}, {0x30b0, 0xff, 0, 0}, {0x30b1, 0xff, 0, 0}, + {0x30b2, 0x10, 0, 0}, {0x300e, 0x32, 0, 0}, {0x300f, 0x21, 0, 0}, + {0x3010, 0x20, 0, 0}, {0x3011, 0x00, 0, 0}, {0x304c, 0x81, 0, 0}, + {0x30d7, 0x10, 0, 0}, {0x30d9, 0x0d, 0, 0}, {0x30db, 0x08, 0, 0}, + {0x3016, 0x82, 0, 0}, {0x3018, 0x38, 0, 0}, {0x3019, 0x30, 0, 0}, + {0x301a, 0x61, 0, 0}, {0x307d, 0x00, 0, 0}, {0x3087, 0x02, 0, 0}, + {0x3082, 0x20, 0, 0}, {0x3015, 0x12, 0, 0}, {0x3014, 0x04, 0, 0}, + {0x3013, 0xf7, 0, 0}, {0x303c, 0x08, 0, 0}, {0x303d, 0x18, 0, 0}, + {0x303e, 0x06, 0, 0}, {0x303f, 0x0c, 0, 0}, {0x3030, 0x62, 0, 0}, + {0x3031, 0x26, 0, 0}, {0x3032, 0xe6, 0, 0}, {0x3033, 0x6e, 0, 0}, + {0x3034, 0xea, 0, 0}, {0x3035, 0xae, 0, 0}, {0x3036, 0xa6, 0, 0}, + {0x3037, 0x6a, 0, 0}, {0x3104, 0x02, 0, 0}, {0x3105, 0xfd, 0, 0}, + {0x3106, 0x00, 0, 0}, {0x3107, 0xff, 0, 0}, {0x3300, 0x12, 0, 0}, + {0x3301, 0xde, 0, 0}, {0x3302, 0xcf, 0, 0}, {0x3312, 0x26, 0, 0}, + {0x3314, 0x42, 0, 0}, {0x3313, 0x2b, 0, 0}, {0x3315, 0x42, 0, 0}, + {0x3310, 0xd0, 0, 0}, {0x3311, 0xbd, 0, 0}, {0x330c, 0x18, 0, 0}, + {0x330d, 0x18, 0, 0}, {0x330e, 0x56, 0, 0}, {0x330f, 0x5c, 0, 0}, + {0x330b, 0x1c, 0, 0}, {0x3306, 0x5c, 0, 0}, {0x3307, 0x11, 0, 0}, + {0x336a, 0x52, 0, 0}, {0x3370, 0x46, 0, 0}, {0x3376, 0x38, 0, 0}, + {0x30b8, 0x20, 0, 0}, {0x30b9, 0x17, 0, 0}, {0x30ba, 0x04, 0, 0}, + {0x30bb, 0x08, 0, 0}, {0x3507, 0x06, 0, 0}, {0x350a, 0x4f, 0, 0}, + {0x3100, 0x02, 0, 0}, {0x3301, 0xde, 0, 0}, {0x3304, 0x00, 0, 0}, + {0x3400, 0x00, 0, 0}, {0x3404, 0x42, 0, 0}, {0x3600, 0xc4, 0, 0}, + {0x3302, 0xef, 0, 0}, {0x3020, 0x01, 0, 0}, {0x3021, 0x1d, 0, 0}, + {0x3022, 0x00, 0, 0}, {0x3023, 0x0a, 0, 0}, {0x3024, 0x08, 0, 0}, + {0x3025, 0x00, 0, 0}, {0x3026, 0x06, 0, 0}, {0x3027, 0x00, 0, 0}, + {0x335f, 0x68, 0, 0}, {0x3360, 0x00, 0, 0}, {0x3361, 0x00, 0, 0}, + {0x3362, 0x01, 0, 0}, {0x3363, 0x40, 0, 0}, {0x3364, 0xf0, 0, 0}, + {0x3403, 0x00, 0, 0}, {0x3088, 0x01, 0, 0}, {0x3089, 0x40, 0, 0}, + {0x308a, 0x00, 0, 0}, {0x308b, 0xf0, 0, 0}, {0x307c, 0x10, 0, 0}, + {0x3090, 0xc0, 0, 0}, {0x304c, 0x84, 0, 0}, {0x308d, 0x04, 0, 0}, + {0x3086, 0x03, 0, 0}, {0x3086, 0x00, 0, 0}, {0x3011, 0x01, 0, 0}, +}; + +static struct reg_value ov3640_setting_30fps_QVGA_320_240[] = { + {0x3012, 0x80, 0, 0}, {0x304d, 0x45, 0, 0}, {0x30a7, 0x5e, 0, 0}, + {0x3087, 0x16, 0, 0}, {0x309c, 0x1a, 0, 0}, {0x30a2, 0xe4, 0, 0}, + {0x30aa, 0x42, 0, 0}, {0x30b0, 0xff, 0, 0}, {0x30b1, 0xff, 0, 0}, + {0x30b2, 0x10, 0, 0}, {0x300e, 0x32, 0, 0}, {0x300f, 0x21, 0, 0}, + {0x3010, 0x20, 0, 0}, {0x3011, 0x01, 0, 0}, {0x304c, 0x82, 0, 0}, + {0x30d7, 0x10, 0, 0}, {0x30d9, 0x0d, 0, 0}, {0x30db, 0x08, 0, 0}, + {0x3016, 0x82, 0, 0}, {0x3018, 0x38, 0, 0}, {0x3019, 0x30, 0, 0}, + {0x301a, 0x61, 0, 0}, {0x307d, 0x00, 0, 0}, {0x3087, 0x02, 0, 0}, + {0x3082, 0x20, 0, 0}, {0x3015, 0x12, 0, 0}, {0x3014, 0x0c, 0, 0}, + {0x3013, 0xf7, 0, 0}, {0x303c, 0x08, 0, 0}, {0x303d, 0x18, 0, 0}, + {0x303e, 0x06, 0, 0}, {0x303f, 0x0c, 0, 0}, {0x3030, 0x62, 0, 0}, + {0x3031, 0x26, 0, 0}, {0x3032, 0xe6, 0, 0}, {0x3033, 0x6e, 0, 0}, + {0x3034, 0xea, 0, 0}, {0x3035, 0xae, 0, 0}, {0x3036, 0xa6, 0, 0}, + {0x3037, 0x6a, 0, 0}, {0x3104, 0x02, 0, 0}, {0x3105, 0xfd, 0, 0}, + {0x3106, 0x00, 0, 0}, {0x3107, 0xff, 0, 0}, {0x3300, 0x12, 0, 0}, + {0x3301, 0xde, 0, 0}, {0x3302, 0xcf, 0, 0}, {0x3312, 0x26, 0, 0}, + {0x3314, 0x42, 0, 0}, {0x3313, 0x2b, 0, 0}, {0x3315, 0x42, 0, 0}, + {0x3310, 0xd0, 0, 0}, {0x3311, 0xbd, 0, 0}, {0x330c, 0x18, 0, 0}, + {0x330d, 0x18, 0, 0}, {0x330e, 0x56, 0, 0}, {0x330f, 0x5c, 0, 0}, + {0x330b, 0x1c, 0, 0}, {0x3306, 0x5c, 0, 0}, {0x3307, 0x11, 0, 0}, + {0x336a, 0x52, 0, 0}, {0x3370, 0x46, 0, 0}, {0x3376, 0x38, 0, 0}, + {0x3300, 0x13, 0, 0}, {0x30b8, 0x20, 0, 0}, {0x30b9, 0x17, 0, 0}, + {0x30ba, 0x04, 0, 0}, {0x30bb, 0x08, 0, 0}, {0x3100, 0x02, 0, 0}, + {0x3301, 0x10, 0x30, 0}, {0x3304, 0x00, 0x03, 0}, {0x3400, 0x00, 0, 0}, + {0x3404, 0x02, 0, 0}, {0x3600, 0xc0, 0, 0}, {0x308d, 0x04, 0, 0}, + {0x3086, 0x03, 0, 0}, {0x3086, 0x00, 0, 0}, {0x3012, 0x10, 0, 0}, + {0x3023, 0x06, 0, 0}, {0x3026, 0x03, 0, 0}, {0x3027, 0x04, 0, 0}, + {0x302a, 0x03, 0, 0}, {0x302b, 0x10, 0, 0}, {0x3075, 0x24, 0, 0}, + {0x300d, 0x01, 0, 0}, {0x30d7, 0x80, 0x80, 0}, {0x3069, 0x00, 0x40, 0}, + {0x303e, 0x00, 0, 0}, {0x303f, 0xc0, 0, 0}, {0x3302, 0x20, 0x20, 0}, + {0x335f, 0x34, 0, 0}, {0x3360, 0x0c, 0, 0}, {0x3361, 0x04, 0, 0}, + {0x3362, 0x34, 0, 0}, {0x3363, 0x08, 0, 0}, {0x3364, 0x04, 0, 0}, + {0x3403, 0x42, 0, 0}, {0x3088, 0x04, 0, 0}, {0x3089, 0x00, 0, 0}, + {0x308a, 0x03, 0, 0}, {0x308b, 0x00, 0, 0}, {0x3362, 0x12, 0, 0}, + {0x3363, 0x88, 0, 0}, {0x3364, 0xe4, 0, 0}, {0x3403, 0x42, 0, 0}, + {0x3088, 0x02, 0, 0}, {0x3089, 0x80, 0, 0}, {0x308a, 0x01, 0, 0}, + {0x308b, 0xe0, 0, 0}, {0x300e, 0x37, 0, 0}, {0x300f, 0xe1, 0, 0}, + {0x3010, 0x22, 0, 0}, {0x3011, 0x01, 0, 0}, {0x304c, 0x84, 0, 0}, +}; + +static struct ov3640_mode_info ov3640_mode_info_data[2][ov3640_mode_MAX + 1] = { + { + {ov3640_mode_VGA_640_480, 640, 480, + ov3640_setting_15fps_VGA_640_480, + ARRAY_SIZE(ov3640_setting_15fps_VGA_640_480)}, + {ov3640_mode_QVGA_320_240, 320, 240, + ov3640_setting_15fps_QVGA_320_240, + ARRAY_SIZE(ov3640_setting_15fps_QVGA_320_240)}, + {ov3640_mode_XGA_1024_768, 1024, 768, + ov3640_setting_15fps_XGA_1024_768, + ARRAY_SIZE(ov3640_setting_15fps_XGA_1024_768)}, + {ov3640_mode_QXGA_2048_1536, 2048, 1536, + ov3640_setting_15fps_QXGA_2048_1536, + ARRAY_SIZE(ov3640_setting_15fps_QXGA_2048_1536)}, + }, + { + {ov3640_mode_VGA_640_480, 640, 480, + ov3640_setting_30fps_VGA_640_480, + ARRAY_SIZE(ov3640_setting_30fps_VGA_640_480)}, + {ov3640_mode_QVGA_320_240, 320, 240, + ov3640_setting_30fps_QVGA_320_240, + ARRAY_SIZE(ov3640_setting_30fps_QVGA_320_240)}, + {ov3640_mode_XGA_1024_768, 1024, 768, + ov3640_setting_30fps_XGA_1024_768, + ARRAY_SIZE(ov3640_setting_30fps_XGA_1024_768)}, + {ov3640_mode_QXGA_2048_1536, 0, 0, NULL, 0}, + }, +}; + +static struct regulator *io_regulator; +static struct regulator *core_regulator; +static struct regulator *analog_regulator; +static struct regulator *gpo_regulator; + +static int ov3640_probe(struct i2c_client *adapter, + const struct i2c_device_id *device_id); +static int ov3640_remove(struct i2c_client *client); + +static s32 ov3640_read_reg(u16 reg, u8 *val); +static s32 ov3640_write_reg(u16 reg, u8 val); + +static const struct i2c_device_id ov3640_id[] = { + {"ov3640", 0}, + {}, +}; + +MODULE_DEVICE_TABLE(i2c, ov3640_id); + +static struct i2c_driver ov3640_i2c_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "ov3640", + }, + .probe = ov3640_probe, + .remove = ov3640_remove, + .id_table = ov3640_id, +}; + +extern void gpio_sensor_active(unsigned int csi_index); +extern void gpio_sensor_inactive(unsigned int csi); + +static s32 ov3640_write_reg(u16 reg, u8 val) +{ + u8 au8Buf[3] = {0}; + + au8Buf[0] = reg >> 8; + au8Buf[1] = reg & 0xff; + au8Buf[2] = val; + + if (i2c_master_send(ov3640_data.i2c_client, au8Buf, 3) < 0) { + pr_err("%s:write reg error:reg=%x,val=%x\n", + __func__, reg, val); + return -1; + } + + return 0; +} + +static s32 ov3640_read_reg(u16 reg, u8 *val) +{ + u8 au8RegBuf[2] = {0}; + u8 u8RdVal = 0; + + au8RegBuf[0] = reg >> 8; + au8RegBuf[1] = reg & 0xff; + + if (2 != i2c_master_send(ov3640_data.i2c_client, au8RegBuf, 2)) { + pr_err("%s:write reg error:reg=%x\n", + __func__, reg); + return -1; + } + + if (1 != i2c_master_recv(ov3640_data.i2c_client, &u8RdVal, 1)) { + pr_err("%s:read reg error:reg=%x,val=%x\n", + __func__, reg, u8RdVal); + return -1; + } + + *val = u8RdVal; + + return u8RdVal; +} + +static int ov3640_init_mode(enum ov3640_frame_rate frame_rate, + enum ov3640_mode mode) +{ + struct reg_value *pModeSetting = NULL; + s32 i = 0; + s32 iModeSettingArySize = 0; + register u32 Delay_ms = 0; + register u16 RegAddr = 0; + register u8 Mask = 0; + register u8 Val = 0; + u8 RegVal = 0; + int retval = 0; + + CAMERA_TRACE(("CAMERA_DBG Entry: ov3640_init_mode\n")); + + if (mode > ov3640_mode_MAX || mode < ov3640_mode_MIN) { + pr_err("Wrong ov3640 mode detected!\n"); + return -1; + } + + pModeSetting = ov3640_mode_info_data[frame_rate][mode].init_data_ptr; + iModeSettingArySize = + ov3640_mode_info_data[frame_rate][mode].init_data_size; + + ov3640_data.pix.width = ov3640_mode_info_data[frame_rate][mode].width; + ov3640_data.pix.height = ov3640_mode_info_data[frame_rate][mode].height; + + for (i = 0; i < iModeSettingArySize; ++i, ++pModeSetting) { + Delay_ms = pModeSetting->u32Delay_ms; + RegAddr = pModeSetting->u16RegAddr; + Val = pModeSetting->u8Val; + Mask = pModeSetting->u8Mask; + + if (Mask) { + retval = ov3640_read_reg(RegAddr, &RegVal); + if (retval < 0) + goto err; + + RegVal &= ~(u8)Mask; + Val &= Mask; + Val |= RegVal; + } + + retval = ov3640_write_reg(RegAddr, Val); + if (retval < 0) + goto err; + + if (Delay_ms) + msleep(Delay_ms); + } +err: + CAMERA_TRACE(("CAMERA_DBG Exit: ov3640_init_mode\n")); + + return retval; +} + +/* --------------- IOCTL functions from v4l2_int_ioctl_desc --------------- */ + +static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p) +{ + CAMERA_TRACE(("In ov3640:ioctl_g_ifparm\n")); + if (s == NULL) { + pr_err(" ERROR!! no slave device set!\n"); + return -1; + } + + memset(p, 0, sizeof(*p)); + p->u.bt656.clock_curr = ov3640_data.mclk; + pr_debug(" clock_curr=mclk=%d\n", ov3640_data.mclk); + p->if_type = V4L2_IF_TYPE_BT656; + p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT; + p->u.bt656.clock_min = OV3640_XCLK_MIN; + p->u.bt656.clock_max = OV3640_XCLK_MAX; + p->u.bt656.bt_sync_correct = 1; /* Indicate external vsync */ + + return 0; +} + +/*! + * ioctl_s_power - V4L2 sensor interface handler for VIDIOC_S_POWER ioctl + * @s: pointer to standard V4L2 device structure + * @on: indicates power mode (on or off) + * + * Turns the power on or off, depending on the value of on and returns the + * appropriate error code. + */ +static int ioctl_s_power(struct v4l2_int_device *s, int on) +{ + struct sensor *sensor = s->priv; + + CAMERA_TRACE(("In ov3640:ioctl_s_power\n")); + + if (on && !sensor->on) { + gpio_sensor_active(ov3640_data.csi); + if (!IS_ERR_VALUE((unsigned long)io_regulator)) + if (regulator_enable(io_regulator) != 0) + return -EIO; + if (!IS_ERR_VALUE((unsigned long)core_regulator)) + if (regulator_enable(core_regulator) != 0) + return -EIO; + if (!IS_ERR_VALUE((unsigned long)gpo_regulator)) + if (regulator_enable(gpo_regulator) != 0) + return -EIO; + if (!IS_ERR_VALUE((unsigned long)analog_regulator)) + if (regulator_enable(analog_regulator) != 0) + return -EIO; + } else if (!on && sensor->on) { + if (!IS_ERR_VALUE((unsigned long)analog_regulator)) + regulator_disable(analog_regulator); + if (!IS_ERR_VALUE((unsigned long)core_regulator)) + regulator_disable(core_regulator); + if (!IS_ERR_VALUE((unsigned long)io_regulator)) + regulator_disable(io_regulator); + if (!IS_ERR_VALUE((unsigned long)gpo_regulator)) + regulator_disable(gpo_regulator); + gpio_sensor_inactive(ov3640_data.csi); + } + + sensor->on = on; + + return 0; +} + +/*! + * ioctl_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl + * @s: pointer to standard V4L2 device structure + * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure + * + * Returns the sensor's video CAPTURE parameters. + */ +static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a) +{ + struct sensor *sensor = s->priv; + struct v4l2_captureparm *cparm = &a->parm.capture; + int ret = 0; + + CAMERA_TRACE(("In ov3640:ioctl_g_parm\n")); + switch (a->type) { + /* This is the only case currently handled. */ + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + CAMERA_TRACE((" type is V4L2_BUF_TYPE_VIDEO_CAPTURE\n")); + memset(a, 0, sizeof(*a)); + a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + cparm->capability = sensor->streamcap.capability; + cparm->timeperframe = sensor->streamcap.timeperframe; + cparm->capturemode = sensor->streamcap.capturemode; + ret = 0; + break; + + /* These are all the possible cases. */ + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + case V4L2_BUF_TYPE_VBI_CAPTURE: + case V4L2_BUF_TYPE_VBI_OUTPUT: + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: + CAMERA_TRACE((" type is not " \ + "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n", + a->type)); + ret = -EINVAL; + break; + + default: + pr_debug(" type is unknown - %d\n", a->type); + ret = -EINVAL; + break; + } + + return ret; +} + +/*! + * ioctl_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl + * @s: pointer to standard V4L2 device structure + * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure + * + * Configures the sensor to use the input parameters, if possible. If + * not possible, reverts to the old parameters and returns the + * appropriate error code. + */ +static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a) +{ + struct sensor *sensor = s->priv; + struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe; + u32 tgt_fps; /* target frames per secound */ + enum ov3640_frame_rate frame_rate; + int ret = 0; + + CAMERA_TRACE(("In ov3640:ioctl_s_parm\n")); + switch (a->type) { + /* This is the only case currently handled. */ + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + CAMERA_TRACE((" type is V4L2_BUF_TYPE_VIDEO_CAPTURE\n")); + + /* Check that the new frame rate is allowed. */ + if ((timeperframe->numerator == 0) || + (timeperframe->denominator == 0)) { + timeperframe->denominator = DEFAULT_FPS; + timeperframe->numerator = 1; + } + + tgt_fps = timeperframe->denominator / + timeperframe->numerator; + + if (tgt_fps > MAX_FPS) { + timeperframe->denominator = MAX_FPS; + timeperframe->numerator = 1; + } else if (tgt_fps < MIN_FPS) { + timeperframe->denominator = MIN_FPS; + timeperframe->numerator = 1; + } + + /* Actual frame rate we use */ + tgt_fps = timeperframe->denominator / + timeperframe->numerator; + + if (tgt_fps == 15) + frame_rate = ov3640_15_fps; + else if (tgt_fps == 30) + frame_rate = ov3640_30_fps; + else { + pr_err(" The camera frame rate is not supported!\n"); + return -EINVAL; + } + + sensor->streamcap.timeperframe = *timeperframe; + sensor->streamcap.capturemode = + (u32)a->parm.capture.capturemode; + + ret = ov3640_init_mode(frame_rate, + sensor->streamcap.capturemode); + break; + + /* These are all the possible cases. */ + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + case V4L2_BUF_TYPE_VBI_CAPTURE: + case V4L2_BUF_TYPE_VBI_OUTPUT: + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: + pr_debug(" type is not " \ + "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n", + a->type); + ret = -EINVAL; + break; + + default: + pr_debug(" type is unknown - %d\n", a->type); + ret = -EINVAL; + break; + } + + return ret; +} + +/*! + * ioctl_g_fmt_cap - V4L2 sensor interface handler for ioctl_g_fmt_cap + * @s: pointer to standard V4L2 device structure + * @f: pointer to standard V4L2 v4l2_format structure + * + * Returns the sensor's current pixel format in the v4l2_format + * parameter. + */ +static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f) +{ + struct sensor *sensor = s->priv; + + CAMERA_TRACE(("In ov3640:ioctl_g_fmt_cap.\n")); + + f->fmt.pix = sensor->pix; + + return 0; +} + +/*! + * ioctl_g_ctrl - V4L2 sensor interface handler for VIDIOC_G_CTRL ioctl + * @s: pointer to standard V4L2 device structure + * @vc: standard V4L2 VIDIOC_G_CTRL ioctl structure + * + * If the requested control is supported, returns the control's current + * value from the video_control[] array. Otherwise, returns -EINVAL + * if the control is not supported. + */ +static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc) +{ + int ret = 0; + + CAMERA_TRACE(("In ov3640:ioctl_g_ctrl\n")); + switch (vc->id) { + case V4L2_CID_BRIGHTNESS: + vc->value = ov3640_data.brightness; + break; + case V4L2_CID_HUE: + vc->value = ov3640_data.hue; + break; + case V4L2_CID_CONTRAST: + vc->value = ov3640_data.contrast; + break; + case V4L2_CID_SATURATION: + vc->value = ov3640_data.saturation; + break; + case V4L2_CID_RED_BALANCE: + vc->value = ov3640_data.red; + break; + case V4L2_CID_BLUE_BALANCE: + vc->value = ov3640_data.blue; + break; + case V4L2_CID_EXPOSURE: + vc->value = ov3640_data.ae_mode; + break; + default: + ret = -EINVAL; + } + + return ret; +} + +/*! + * ioctl_s_ctrl - V4L2 sensor interface handler for VIDIOC_S_CTRL ioctl + * @s: pointer to standard V4L2 device structure + * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure + * + * If the requested control is supported, sets the control's current + * value in HW (and updates the video_control[] array). Otherwise, + * returns -EINVAL if the control is not supported. + */ +static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc) +{ + int retval = 0; + + pr_debug("In ov3640:ioctl_s_ctrl %d\n", + vc->id); + + switch (vc->id) { + case V4L2_CID_BRIGHTNESS: + CAMERA_TRACE((" V4L2_CID_BRIGHTNESS\n")); + break; + case V4L2_CID_CONTRAST: + CAMERA_TRACE((" V4L2_CID_CONTRAST\n")); + break; + case V4L2_CID_SATURATION: + CAMERA_TRACE((" V4L2_CID_SATURATION\n")); + break; + case V4L2_CID_HUE: + CAMERA_TRACE((" V4L2_CID_HUE\n")); + break; + case V4L2_CID_AUTO_WHITE_BALANCE: + CAMERA_TRACE((" V4L2_CID_AUTO_WHITE_BALANCE\n")); + break; + case V4L2_CID_DO_WHITE_BALANCE: + CAMERA_TRACE((" V4L2_CID_DO_WHITE_BALANCE\n")); + break; + case V4L2_CID_RED_BALANCE: + CAMERA_TRACE((" V4L2_CID_RED_BALANCE\n")); + break; + case V4L2_CID_BLUE_BALANCE: + CAMERA_TRACE((" V4L2_CID_BLUE_BALANCE\n")); + break; + case V4L2_CID_GAMMA: + CAMERA_TRACE((" V4L2_CID_GAMMA\n")); + break; + case V4L2_CID_EXPOSURE: + CAMERA_TRACE((" V4L2_CID_EXPOSURE\n")); + break; + case V4L2_CID_AUTOGAIN: + CAMERA_TRACE((" V4L2_CID_AUTOGAIN\n")); + break; + case V4L2_CID_GAIN: + CAMERA_TRACE((" V4L2_CID_GAIN\n")); + break; + case V4L2_CID_HFLIP: + CAMERA_TRACE((" V4L2_CID_HFLIP\n")); + break; + case V4L2_CID_VFLIP: + CAMERA_TRACE((" V4L2_CID_VFLIP\n")); + break; + default: + CAMERA_TRACE((" Default case\n")); + retval = -EPERM; + break; + } + + return retval; +} + +/*! + * ioctl_init - V4L2 sensor interface handler for VIDIOC_INT_INIT + * @s: pointer to standard V4L2 device structure + */ +static int ioctl_init(struct v4l2_int_device *s) +{ + CAMERA_TRACE(("In ov3640:ioctl_init\n")); + + return 0; +} + +/*! + * ioctl_dev_init - V4L2 sensor interface handler for vidioc_int_dev_init_num + * @s: pointer to standard V4L2 device structure + * + * Initialise the device when slave attaches to the master. + */ +static int ioctl_dev_init(struct v4l2_int_device *s) +{ + struct sensor *sensor = s->priv; + u32 tgt_xclk; /* target xclk */ + u32 tgt_fps; /* target frames per secound */ + enum ov3640_frame_rate frame_rate; + + CAMERA_TRACE(("In ov3640:ioctl_dev_init\n")); + + gpio_sensor_active(ov3640_data.csi); + ov3640_data.on = true; + + /* mclk */ + tgt_xclk = ov3640_data.mclk; + tgt_xclk = min(tgt_xclk, (u32)OV3640_XCLK_MAX); + tgt_xclk = max(tgt_xclk, (u32)OV3640_XCLK_MIN); + ov3640_data.mclk = tgt_xclk; + + pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000); + set_mclk_rate(&ov3640_data.mclk, ov3640_data.csi); + + /* Default camera frame rate is set in probe */ + tgt_fps = sensor->streamcap.timeperframe.denominator / + sensor->streamcap.timeperframe.numerator; + + if (tgt_fps == 15) + frame_rate = ov3640_15_fps; + else if (tgt_fps == 30) + frame_rate = ov3640_30_fps; + else + return -EINVAL; /* Only support 15fps or 30fps now. */ + + return ov3640_init_mode(frame_rate, + sensor->streamcap.capturemode); +} + +/*! + * This structure defines all the ioctls for this module and links them to the + * enumeration. + */ +static struct v4l2_int_ioctl_desc ov3640_ioctl_desc[] = { + {vidioc_int_dev_init_num, (v4l2_int_ioctl_func *)ioctl_dev_init}, +/* {vidioc_int_dev_exit_num, (v4l2_int_ioctl_func *)ioctl_dev_exit}, */ + {vidioc_int_s_power_num, (v4l2_int_ioctl_func *)ioctl_s_power}, + {vidioc_int_g_ifparm_num, (v4l2_int_ioctl_func *)ioctl_g_ifparm}, +/* {vidioc_int_g_needs_reset_num, + (v4l2_int_ioctl_func *)ioctl_g_needs_reset}, */ +/* {vidioc_int_reset_num, (v4l2_int_ioctl_func *)ioctl_reset}, */ + {vidioc_int_init_num, (v4l2_int_ioctl_func *)ioctl_init}, +/* {vidioc_int_enum_fmt_cap_num, + (v4l2_int_ioctl_func *)ioctl_enum_fmt_cap}, */ +/* {vidioc_int_try_fmt_cap_num, + (v4l2_int_ioctl_func *)ioctl_try_fmt_cap}, */ + {vidioc_int_g_fmt_cap_num, (v4l2_int_ioctl_func *)ioctl_g_fmt_cap}, +/* {vidioc_int_s_fmt_cap_num, (v4l2_int_ioctl_func *)ioctl_s_fmt_cap}, */ + {vidioc_int_g_parm_num, (v4l2_int_ioctl_func *)ioctl_g_parm}, + {vidioc_int_s_parm_num, (v4l2_int_ioctl_func *)ioctl_s_parm}, +/* {vidioc_int_queryctrl_num, (v4l2_int_ioctl_func *)ioctl_queryctrl}, */ + {vidioc_int_g_ctrl_num, (v4l2_int_ioctl_func *)ioctl_g_ctrl}, + {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func *)ioctl_s_ctrl}, +}; + +static struct v4l2_int_slave ov3640_slave = { + .ioctls = ov3640_ioctl_desc, + .num_ioctls = ARRAY_SIZE(ov3640_ioctl_desc), +}; + +static struct v4l2_int_device ov3640_int_device = { + .module = THIS_MODULE, + .name = "ov3640", + .type = v4l2_int_type_slave, + .u = { + .slave = &ov3640_slave, + }, +}; + +/*! + * ov3640 I2C probe function + * + * @param adapter struct i2c_adapter * + * @return Error code indicating success or failure + */ +static int ov3640_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int retval; + struct mxc_camera_platform_data *plat_data = client->dev.platform_data; + + CAMERA_TRACE(("CAMERA_DBG Entry: ov3640_probe\n")); + + /* Set initial values for the sensor struct. */ + memset(&ov3640_data, 0, sizeof(ov3640_data)); + ov3640_data.mclk = 24000000; /* 6 - 54 MHz, typical 24MHz */ + ov3640_data.mclk = plat_data->mclk; + ov3640_data.csi = plat_data->csi; + + ov3640_data.i2c_client = client; + ov3640_data.pix.pixelformat = V4L2_PIX_FMT_UYVY; + ov3640_data.pix.width = 640; + ov3640_data.pix.height = 480; + ov3640_data.streamcap.capability = V4L2_MODE_HIGHQUALITY | + V4L2_CAP_TIMEPERFRAME; + ov3640_data.streamcap.capturemode = 0; + ov3640_data.streamcap.timeperframe.denominator = DEFAULT_FPS; + ov3640_data.streamcap.timeperframe.numerator = 1; + + io_regulator = regulator_get(&client->dev, plat_data->io_regulator); + if (!IS_ERR_VALUE((u32)io_regulator)) { + regulator_set_voltage(io_regulator, OV3640_VOLTAGE_DIGITAL_IO, + OV3640_VOLTAGE_DIGITAL_IO); + if (regulator_enable(io_regulator) != 0) { + pr_err("%s:io set voltage error\n", __func__); + goto err1; + } else { + dev_dbg(&client->dev, + "%s:io set voltage ok\n", __func__); + } + } + + core_regulator = regulator_get(&client->dev, plat_data->core_regulator); + if (!IS_ERR_VALUE((u32)core_regulator)) { + regulator_set_voltage(core_regulator, + OV3640_VOLTAGE_DIGITAL_CORE, + OV3640_VOLTAGE_DIGITAL_CORE); + if (regulator_enable(core_regulator) != 0) { + pr_err("%s:core set voltage error\n", __func__); + goto err2; + } else { + dev_dbg(&client->dev, + "%s:core set voltage ok\n", __func__); + } + } + + analog_regulator = + regulator_get(&client->dev, plat_data->analog_regulator); + if (!IS_ERR_VALUE((u32)analog_regulator)) { + regulator_set_voltage(analog_regulator, OV3640_VOLTAGE_ANALOG, + OV3640_VOLTAGE_ANALOG); + if (regulator_enable(analog_regulator) != 0) { + pr_err("%s:analog set voltage error\n", __func__); + goto err3; + } else { + dev_dbg(&client->dev, + "%s:analog set voltage ok\n", __func__); + } + } + + gpo_regulator = regulator_get(&client->dev, plat_data->gpo_regulator); + if (!IS_ERR_VALUE((u32)gpo_regulator)) { + if (regulator_enable(gpo_regulator) != 0) { + pr_err("%s:gpo3 enable error\n", __func__); + goto err4; + } else { + dev_dbg(&client->dev, + "%s:gpo3 enable ok\n", __func__); + } + } + + ov3640_int_device.priv = &ov3640_data; + retval = v4l2_int_device_register(&ov3640_int_device); + + return retval; + +err4: + if (!IS_ERR_VALUE((u32)analog_regulator)) { + regulator_disable(analog_regulator); + regulator_put(analog_regulator); + } +err3: + if (!IS_ERR_VALUE((u32)core_regulator)) { + regulator_disable(core_regulator); + regulator_put(core_regulator); + } +err2: + if (!IS_ERR_VALUE((u32)io_regulator)) { + regulator_disable(io_regulator); + regulator_put(io_regulator); + } +err1: + return -1; +} + +/*! + * ov3640 I2C detach function + * + * @param client struct i2c_client * + * @return Error code indicating success or failure + */ +static int ov3640_remove(struct i2c_client *client) +{ + CAMERA_TRACE(("In ov3640_remove\n")); + + v4l2_int_device_unregister(&ov3640_int_device); + + if (!IS_ERR_VALUE((unsigned long)gpo_regulator)) { + regulator_disable(gpo_regulator); + regulator_put(gpo_regulator); + } + + if (!IS_ERR_VALUE((unsigned long)analog_regulator)) { + regulator_disable(analog_regulator); + regulator_put(analog_regulator); + } + + if (!IS_ERR_VALUE((unsigned long)core_regulator)) { + regulator_disable(core_regulator); + regulator_put(core_regulator); + } + + if (!IS_ERR_VALUE((unsigned long)io_regulator)) { + regulator_disable(io_regulator); + regulator_put(io_regulator); + } + + return 0; +} + +/*! + * ov3640 init function + * Called by insmod ov3640_camera.ko. + * + * @return Error code indicating success or failure + */ +static __init int ov3640_init(void) +{ + u8 err; + + CAMERA_TRACE(("CAMERA_DBG Entry: ov3640_init\n")); + + err = i2c_add_driver(&ov3640_i2c_driver); + if (err != 0) + pr_err("%s:driver registration failed, error=%d \n", + __func__, err); + + CAMERA_TRACE(("CAMERA_DBG Exit: ov3640_init\n")); + + return err; +} + +/*! + * OV3640 cleanup function + * Called on rmmod ov3640_camera.ko + * + * @return Error code indicating success or failure + */ +static void __exit ov3640_clean(void) +{ + CAMERA_TRACE(("CAMERA_DBG Entry: ov3640_clean\n")); + + i2c_del_driver(&ov3640_i2c_driver); + gpio_sensor_inactive(ov3640_data.csi); + + CAMERA_TRACE(("CAMERA_DBG Exit: ov3640_clean\n")); +} + +module_init(ov3640_init); +module_exit(ov3640_clean); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("OV3640 Camera Driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("1.0"); +MODULE_ALIAS("CSI"); --- linux-2.6.28.orig/drivers/media/video/mxc/capture/Kconfig +++ linux-2.6.28/drivers/media/video/mxc/capture/Kconfig @@ -0,0 +1,56 @@ +if VIDEO_MXC_CAMERA + +menu "MXC Camera/V4L2 PRP Features support" +config VIDEO_MXC_IPU_CAMERA + bool + depends on VIDEO_MXC_CAMERA && MXC_IPU + default y + +choice + prompt "Select Camera/TV Decoder" + default MXC_CAMERA_OV3640 + depends on VIDEO_MXC_CAMERA + +config MXC_CAMERA_OV3640 + tristate "OmniVision ov3640 camera support" + depends on !VIDEO_MXC_EMMA_CAMERA + ---help--- + If you plan to use the ov3640 Camera with your MXC system, say Y here. + +endchoice + +config MXC_IPU_PRP_VF_SDC + tristate "Pre-Processor VF SDC library" + depends on VIDEO_MXC_IPU_CAMERA && FB_MXC_SYNC_PANEL + default y + ---help--- + Use case PRP_VF_SDC: + Preprocessing image from smart sensor for viewfinder and + displaying it on synchronous display with SDC use case. + If SDC BG is selected, Rotation will not be supported. + CSI -> IC (PRP VF) -> MEM + MEM -> IC (ROT) -> MEM + MEM -> SDC (FG/BG) + +config MXC_IPU_PRP_VF_ADC + tristate "Pre-Processor VF ADC library" + depends on VIDEO_MXC_IPU_CAMERA && FB_MXC_ASYNC_PANEL + default y + ---help--- + Use case PRP_VF_ADC: + Preprocessing image from smart sensor for viewfinder and + displaying it on asynchronous display. + CSI -> IC (PRP VF) -> ADC2 + +config MXC_IPU_PRP_ENC + tristate "Pre-processor Encoder library" + depends on VIDEO_MXC_IPU_CAMERA + default y + ---help--- + Use case PRP_ENC: + Preprocessing image from smart sensor for encoder. + CSI -> IC (PRP ENC) -> MEM + +endmenu + +endif --- linux-2.6.28.orig/drivers/media/video/mxc/capture/sensor_clock.c +++ linux-2.6.28/drivers/media/video/mxc/capture/sensor_clock.c @@ -0,0 +1,85 @@ +/* + * Copyright 2004-2008 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 + */ + +/*! + * @file sensor_clock.c + * + * @brief camera clock function + * + * @ingroup Camera + */ +#include +#include +#include +#include +#include + +#if defined(CONFIG_MXC_IPU_V1) || defined(CONFIG_VIDEO_MXC_EMMA_CAMERA) +/* + * set_mclk_rate + * + * @param p_mclk_freq mclk frequence + * + */ +void set_mclk_rate(uint32_t * p_mclk_freq) +{ + struct clk *clk; + uint32_t freq = 0; + + clk = clk_get(NULL, "csi_clk"); + + freq = clk_round_rate(clk, *p_mclk_freq); + clk_set_rate(clk, freq); + + *p_mclk_freq = freq; + + clk_put(clk); + pr_debug("mclk frequency = %d\n", *p_mclk_freq); +} +#else +/* + * set_mclk_rate + * + * @param p_mclk_freq mclk frequence + * @param csi csi 0 or csi 1 + * + */ +void set_mclk_rate(uint32_t *p_mclk_freq, uint32_t csi) +{ + struct clk *clk; + uint32_t freq = 0; + char *mclk; + + if (csi == 0) { + mclk = "csi_mclk1"; + } else if (csi == 1) { + mclk = "csi_mclk2"; + } else { + pr_debug("invalid csi num %d\n", csi); + return; + } + + clk = clk_get(NULL, mclk); + + freq = clk_round_rate(clk, *p_mclk_freq); + clk_set_rate(clk, freq); + + *p_mclk_freq = freq; + + clk_put(clk); + pr_debug("%s frequency = %d\n", mclk, *p_mclk_freq); +} +#endif + +/* Exported symbols for modules. */ +EXPORT_SYMBOL(set_mclk_rate); --- linux-2.6.28.orig/drivers/media/video/mxc/capture/ipu_prp_enc.c +++ linux-2.6.28/drivers/media/video/mxc/capture/ipu_prp_enc.c @@ -0,0 +1,455 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @file ipu_prp_enc.c + * + * @brief IPU Use case for PRP-ENC + * + * @ingroup IPU + */ + +#include +#include +#include "mxc_v4l2_capture.h" +#include "ipu_prp_sw.h" + +#ifdef CAMERA_DBG + #define CAMERA_TRACE(x) (printk)x +#else + #define CAMERA_TRACE(x) +#endif + +static ipu_rotate_mode_t grotation = IPU_ROTATE_NONE; + +/* + * Function definitions + */ + +/*! + * IPU ENC callback function. + * + * @param irq int irq line + * @param dev_id void * device id + * + * @return status IRQ_HANDLED for handled + */ +static irqreturn_t prp_enc_callback(int irq, void *dev_id) +{ + cam_data *cam = (cam_data *) dev_id; + + if (cam->enc_callback == NULL) + return IRQ_HANDLED; + + cam->enc_callback(irq, dev_id); + + return IRQ_HANDLED; +} + +/*! + * PrpENC enable channel setup function + * + * @param cam struct cam_data * mxc capture instance + * + * @return status + */ +static int prp_enc_setup(cam_data * cam) +{ + ipu_channel_params_t enc; + int err = 0; + dma_addr_t dummy = 0xdeadbeaf; + + CAMERA_TRACE("In prp_enc_setup\n"); + if (!cam) { + printk(KERN_ERR "cam private is NULL\n"); + return -ENXIO; + } + memset(&enc, 0, sizeof(ipu_channel_params_t)); + + ipu_csi_get_window_size(&enc.csi_prp_enc_mem.in_width, + &enc.csi_prp_enc_mem.in_height, cam->csi); + + enc.csi_prp_enc_mem.in_pixel_fmt = IPU_PIX_FMT_UYVY; + enc.csi_prp_enc_mem.out_width = cam->v2f.fmt.pix.width; + enc.csi_prp_enc_mem.out_height = cam->v2f.fmt.pix.height; + enc.csi_prp_enc_mem.csi = cam->csi; + if (cam->rotation >= IPU_ROTATE_90_RIGHT) { + enc.csi_prp_enc_mem.out_width = cam->v2f.fmt.pix.height; + enc.csi_prp_enc_mem.out_height = cam->v2f.fmt.pix.width; + } + + if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV420) { + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_YUV420P; + pr_info("YUV420\n"); + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_YUV422P) { + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_YUV422P; + pr_info("YUV422P\n"); + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_NV12) { + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_NV12; + pr_info("NV12\n"); + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR24) { + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_BGR24; + pr_info("BGR24\n"); + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) { + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_RGB24; + pr_info("RGB24\n"); + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565) { + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_RGB565; + pr_info("RGB565\n"); + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_BGR32) { + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_BGR32; + pr_info("BGR32\n"); + } else if (cam->v2f.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB32) { + enc.csi_prp_enc_mem.out_pixel_fmt = IPU_PIX_FMT_RGB32; + pr_info("RGB32\n"); + } else { + printk(KERN_ERR "format not supported\n"); + return -EINVAL; + } + + err = ipu_init_channel(CSI_PRP_ENC_MEM, &enc); + if (err != 0) { + printk(KERN_ERR "ipu_init_channel %d\n", err); + return err; + } + + ipu_csi_enable_mclk_if(CSI_MCLK_ENC, cam->csi, true, true); + + grotation = cam->rotation; + if (cam->rotation >= IPU_ROTATE_90_RIGHT) { + if (cam->rot_enc_bufs_vaddr[0]) { + dma_free_coherent(0, cam->rot_enc_buf_size[0], + cam->rot_enc_bufs_vaddr[0], + cam->rot_enc_bufs[0]); + } + if (cam->rot_enc_bufs_vaddr[1]) { + dma_free_coherent(0, cam->rot_enc_buf_size[1], + cam->rot_enc_bufs_vaddr[1], + cam->rot_enc_bufs[1]); + } + cam->rot_enc_buf_size[0] = + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage); + cam->rot_enc_bufs_vaddr[0] = + (void *)dma_alloc_coherent(0, cam->rot_enc_buf_size[0], + &cam->rot_enc_bufs[0], + GFP_DMA | GFP_KERNEL); + if (!cam->rot_enc_bufs_vaddr[0]) { + printk(KERN_ERR "alloc enc_bufs0\n"); + return -ENOMEM; + } + cam->rot_enc_buf_size[1] = + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage); + cam->rot_enc_bufs_vaddr[1] = + (void *)dma_alloc_coherent(0, cam->rot_enc_buf_size[1], + &cam->rot_enc_bufs[1], + GFP_DMA | GFP_KERNEL); + if (!cam->rot_enc_bufs_vaddr[1]) { + dma_free_coherent(0, cam->rot_enc_buf_size[0], + cam->rot_enc_bufs_vaddr[0], + cam->rot_enc_bufs[0]); + cam->rot_enc_bufs_vaddr[0] = NULL; + cam->rot_enc_bufs[0] = 0; + printk(KERN_ERR "alloc enc_bufs1\n"); + return -ENOMEM; + } + + err = ipu_init_channel_buffer(CSI_PRP_ENC_MEM, + IPU_OUTPUT_BUFFER, + enc.csi_prp_enc_mem.out_pixel_fmt, + enc.csi_prp_enc_mem.out_width, + enc.csi_prp_enc_mem.out_height, + enc.csi_prp_enc_mem.out_width, + IPU_ROTATE_NONE, + cam->rot_enc_bufs[0], + cam->rot_enc_bufs[1], 0, 0); + if (err != 0) { + printk(KERN_ERR "CSI_PRP_ENC_MEM err\n"); + return err; + } + + err = ipu_init_channel(MEM_ROT_ENC_MEM, NULL); + if (err != 0) { + printk(KERN_ERR "MEM_ROT_ENC_MEM channel err\n"); + return err; + } + + err = ipu_init_channel_buffer(MEM_ROT_ENC_MEM, IPU_INPUT_BUFFER, + enc.csi_prp_enc_mem.out_pixel_fmt, + enc.csi_prp_enc_mem.out_width, + enc.csi_prp_enc_mem.out_height, + enc.csi_prp_enc_mem.out_width, + cam->rotation, + cam->rot_enc_bufs[0], + cam->rot_enc_bufs[1], 0, 0); + if (err != 0) { + printk(KERN_ERR "MEM_ROT_ENC_MEM input buffer\n"); + return err; + } + + err = + ipu_init_channel_buffer(MEM_ROT_ENC_MEM, IPU_OUTPUT_BUFFER, + enc.csi_prp_enc_mem.out_pixel_fmt, + enc.csi_prp_enc_mem.out_height, + enc.csi_prp_enc_mem.out_width, + cam->v2f.fmt.pix.bytesperline / + bytes_per_pixel(enc.csi_prp_enc_mem. + out_pixel_fmt), + IPU_ROTATE_NONE, dummy, dummy, + cam->offset.u_offset, + cam->offset.v_offset); + if (err != 0) { + printk(KERN_ERR "MEM_ROT_ENC_MEM output buffer\n"); + return err; + } + + err = ipu_link_channels(CSI_PRP_ENC_MEM, MEM_ROT_ENC_MEM); + if (err < 0) { + printk(KERN_ERR + "link CSI_PRP_ENC_MEM-MEM_ROT_ENC_MEM\n"); + return err; + } + + err = ipu_enable_channel(CSI_PRP_ENC_MEM); + if (err < 0) { + printk(KERN_ERR "ipu_enable_channel CSI_PRP_ENC_MEM\n"); + return err; + } + err = ipu_enable_channel(MEM_ROT_ENC_MEM); + if (err < 0) { + printk(KERN_ERR "ipu_enable_channel MEM_ROT_ENC_MEM\n"); + return err; + } + + ipu_select_buffer(CSI_PRP_ENC_MEM, IPU_OUTPUT_BUFFER, 0); + ipu_select_buffer(CSI_PRP_ENC_MEM, IPU_OUTPUT_BUFFER, 1); + } else { + err = + ipu_init_channel_buffer(CSI_PRP_ENC_MEM, IPU_OUTPUT_BUFFER, + enc.csi_prp_enc_mem.out_pixel_fmt, + enc.csi_prp_enc_mem.out_width, + enc.csi_prp_enc_mem.out_height, + cam->v2f.fmt.pix.bytesperline / + bytes_per_pixel(enc.csi_prp_enc_mem. + out_pixel_fmt), + cam->rotation, dummy, dummy, + cam->offset.u_offset, + cam->offset.v_offset); + if (err != 0) { + printk(KERN_ERR "CSI_PRP_ENC_MEM output buffer\n"); + return err; + } + err = ipu_enable_channel(CSI_PRP_ENC_MEM); + if (err < 0) { + printk(KERN_ERR "ipu_enable_channel CSI_PRP_ENC_MEM\n"); + return err; + } + } + + return err; +} + +/*! + * function to update physical buffer address for encorder IDMA channel + * + * @param eba physical buffer address for encorder IDMA channel + * @param buffer_num int buffer 0 or buffer 1 + * + * @return status + */ +static int prp_enc_eba_update(dma_addr_t eba, int *buffer_num) +{ + int err = 0; + + pr_debug("eba %x\n", eba); + if (grotation >= IPU_ROTATE_90_RIGHT) { + err = ipu_update_channel_buffer(MEM_ROT_ENC_MEM, + IPU_OUTPUT_BUFFER, *buffer_num, + eba); + } else { + err = ipu_update_channel_buffer(CSI_PRP_ENC_MEM, + IPU_OUTPUT_BUFFER, *buffer_num, + eba); + } + if (err != 0) { + printk(KERN_ERR "err %d buffer_num %d\n", err, *buffer_num); + return err; + } + + if (grotation >= IPU_ROTATE_90_RIGHT) { + ipu_select_buffer(MEM_ROT_ENC_MEM, IPU_OUTPUT_BUFFER, + *buffer_num); + } else { + ipu_select_buffer(CSI_PRP_ENC_MEM, IPU_OUTPUT_BUFFER, + *buffer_num); + } + + *buffer_num = (*buffer_num == 0) ? 1 : 0; + return 0; +} + +/*! + * Enable encoder task + * @param private struct cam_data * mxc capture instance + * + * @return status + */ +static int prp_enc_enabling_tasks(void *private) +{ + cam_data *cam = (cam_data *) private; + int err = 0; + CAMERA_TRACE("IPU:In prp_enc_enabling_tasks\n"); + + if (cam->rotation >= IPU_ROTATE_90_RIGHT) { + err = ipu_request_irq(IPU_IRQ_PRP_ENC_ROT_OUT_EOF, + prp_enc_callback, 0, "Mxc Camera", cam); + } else { + err = ipu_request_irq(IPU_IRQ_PRP_ENC_OUT_EOF, + prp_enc_callback, 0, "Mxc Camera", cam); + } + if (err != 0) { + printk(KERN_ERR "Error registering rot irq\n"); + return err; + } + + err = prp_enc_setup(cam); + if (err != 0) { + printk(KERN_ERR "prp_enc_setup %d\n", err); + return err; + } + + return err; +} + +/*! + * Disable encoder task + * @param private struct cam_data * mxc capture instance + * + * @return int + */ +static int prp_enc_disabling_tasks(void *private) +{ + cam_data *cam = (cam_data *) private; + int err = 0; + + if (cam->rotation >= IPU_ROTATE_90_RIGHT) { + ipu_free_irq(IPU_IRQ_PRP_ENC_ROT_OUT_EOF, cam); + } else { + ipu_free_irq(IPU_IRQ_PRP_ENC_OUT_EOF, cam); + } + + if (cam->rotation >= IPU_ROTATE_90_RIGHT) { + ipu_unlink_channels(CSI_PRP_ENC_MEM, MEM_ROT_ENC_MEM); + } + + err = ipu_disable_channel(CSI_PRP_ENC_MEM, true); + if (cam->rotation >= IPU_ROTATE_90_RIGHT) { + err |= ipu_disable_channel(MEM_ROT_ENC_MEM, true); + } + + ipu_uninit_channel(CSI_PRP_ENC_MEM); + if (cam->rotation >= IPU_ROTATE_90_RIGHT) { + ipu_uninit_channel(MEM_ROT_ENC_MEM); + } + + ipu_csi_enable_mclk_if(CSI_MCLK_ENC, cam->csi, false, false); + + return err; +} + +/*! + * function to select PRP-ENC as the working path + * + * @param private struct cam_data * mxc capture instance + * + * @return int + */ +int prp_enc_select(void *private) +{ + cam_data *cam = (cam_data *) private; + int err = 0; + + if (cam) { + cam->enc_update_eba = prp_enc_eba_update; + cam->enc_enable = prp_enc_enabling_tasks; + cam->enc_disable = prp_enc_disabling_tasks; + } else { + err = -EIO; + } + + return err; +} + +/*! + * function to de-select PRP-ENC as the working path + * + * @param private struct cam_data * mxc capture instance + * + * @return int + */ +int prp_enc_deselect(void *private) +{ + cam_data *cam = (cam_data *) private; + int err = 0; + + //err = prp_enc_disabling_tasks(cam); + + if (cam) { + cam->enc_update_eba = NULL; + cam->enc_enable = NULL; + cam->enc_disable = NULL; + if (cam->rot_enc_bufs_vaddr[0]) { + dma_free_coherent(0, cam->rot_enc_buf_size[0], + cam->rot_enc_bufs_vaddr[0], + cam->rot_enc_bufs[0]); + cam->rot_enc_bufs_vaddr[0] = NULL; + cam->rot_enc_bufs[0] = 0; + } + if (cam->rot_enc_bufs_vaddr[1]) { + dma_free_coherent(0, cam->rot_enc_buf_size[1], + cam->rot_enc_bufs_vaddr[1], + cam->rot_enc_bufs[1]); + cam->rot_enc_bufs_vaddr[1] = NULL; + cam->rot_enc_bufs[1] = 0; + } + } + + return err; +} + +/*! + * Init the Encorder channels + * + * @return Error code indicating success or failure + */ +__init int prp_enc_init(void) +{ + return 0; +} + +/*! + * Deinit the Encorder channels + * + */ +void __exit prp_enc_exit(void) +{ +} + +module_init(prp_enc_init); +module_exit(prp_enc_exit); + +EXPORT_SYMBOL(prp_enc_select); +EXPORT_SYMBOL(prp_enc_deselect); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("IPU PRP ENC Driver"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/media/video/mxc/capture/Makefile +++ linux-2.6.28/drivers/media/video/mxc/capture/Makefile @@ -0,0 +1,10 @@ +ifeq ($(CONFIG_VIDEO_MXC_IPU_CAMERA),y) + obj-$(CONFIG_VIDEO_MXC_CAMERA) += mxc_v4l2_capture.o + obj-$(CONFIG_MXC_IPU_PRP_VF_ADC) += ipu_prp_vf_adc.o + obj-$(CONFIG_MXC_IPU_PRP_VF_SDC) += ipu_prp_vf_sdc.o ipu_prp_vf_sdc_bg.o + obj-$(CONFIG_MXC_IPU_PRP_ENC) += ipu_prp_enc.o ipu_still.o +endif + +ov3640_camera-objs := ov3640.o sensor_clock.o +obj-$(CONFIG_MXC_CAMERA_OV3640) += ov3640_camera.o + --- linux-2.6.28.orig/drivers/media/video/mxc/capture/mxc_v4l2_capture.c +++ linux-2.6.28/drivers/media/video/mxc/capture/mxc_v4l2_capture.c @@ -0,0 +1,2442 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @file drivers/media/video/mxc/capture/mxc_v4l2_capture.c + * + * @brief Mxc Video For Linux 2 driver + * + * @ingroup MXC_V4L2_CAPTURE + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mxc_v4l2_capture.h" +#include "ipu_prp_sw.h" + +static int video_nr = -1; +static cam_data *g_cam; + +/*! This data is used for the output to the display. */ +#define MXC_V4L2_CAPTURE_NUM_OUTPUTS 2 +static struct v4l2_output mxc_capture_outputs[MXC_V4L2_CAPTURE_NUM_OUTPUTS] = { + { + .index = 0, + .name = "DISP3", + .type = V4L2_OUTPUT_TYPE_ANALOG, + .audioset = 0, + .modulator = 0, + .std = V4L2_STD_UNKNOWN, + }, + { + .index = 1, + .name = "DISP0", + .type = V4L2_OUTPUT_TYPE_ANALOG, + .audioset = 0, + .modulator = 0, + .std = V4L2_STD_UNKNOWN, + } +}; + +/*! List of TV input video formats supported. The video formats is corresponding + * to the v4l2_id in video_fmt_t. + * Currently, only PAL and NTSC is supported. Needs to be expanded in the + * future. + */ +typedef enum { + TV_NTSC = 0, /*!< Locked on (M) NTSC video signal. */ + TV_PAL, /*!< (B, G, H, I, N)PAL video signal. */ + TV_NOT_LOCKED, /*!< Not locked on a signal. */ +} video_fmt_idx; + +/*! Number of video standards supported (including 'not locked' signal). */ +#define TV_STD_MAX (TV_NOT_LOCKED + 1) + +/*! Video format structure. */ +typedef struct { + int v4l2_id; /*!< Video for linux ID. */ + char name[16]; /*!< Name (e.g., "NTSC", "PAL", etc.) */ + u16 raw_width; /*!< Raw width. */ + u16 raw_height; /*!< Raw height. */ + u16 active_width; /*!< Active width. */ + u16 active_height; /*!< Active height. */ + u16 active_top; /*!< Active top. */ + u16 active_left; /*!< Active left. */ +} video_fmt_t; + +/*! + * Description of video formats supported. + * + * PAL: raw=720x625, active=720x576. + * NTSC: raw=720x525, active=720x480. + */ +static video_fmt_t video_fmts[] = { + { /*! NTSC */ + .v4l2_id = V4L2_STD_NTSC, + .name = "NTSC", + .raw_width = 720, /* SENS_FRM_WIDTH */ + .raw_height = 288, /* SENS_FRM_HEIGHT */ + .active_width = 720, /* ACT_FRM_WIDTH */ + .active_height = (480 / 2), /* ACT_FRM_HEIGHT */ + .active_top = 12, + .active_left = 0, + }, + { /*! (B, G, H, I, N) PAL */ + .v4l2_id = V4L2_STD_PAL, + .name = "PAL", + .raw_width = 720, + .raw_height = (576 / 2) + 24 * 2, + .active_width = 720, + .active_height = (576 / 2), + .active_top = 0, + .active_left = 0, + }, + { /*! Unlocked standard */ + .v4l2_id = V4L2_STD_ALL, + .name = "Autodetect", + .raw_width = 720, + .raw_height = (576 / 2) + 24 * 2, + .active_width = 720, + .active_height = (576 / 2), + .active_top = 0, + .active_left = 0, + }, +}; + +/*!* Standard index of TV. */ +static video_fmt_idx video_index = TV_NOT_LOCKED; + +static int mxc_v4l2_master_attach(struct v4l2_int_device *slave); +static void mxc_v4l2_master_detach(struct v4l2_int_device *slave); +static u8 camera_power(cam_data *cam, bool cameraOn); + +/*! Information about this driver. */ +static struct v4l2_int_master mxc_v4l2_master = { + .attach = mxc_v4l2_master_attach, + .detach = mxc_v4l2_master_detach, +}; + +static struct v4l2_int_device mxc_v4l2_int_device = { + .module = THIS_MODULE, + .name = "mxc_v4l2_cap", + .type = v4l2_int_type_master, + .u = { + .master = &mxc_v4l2_master, + }, +}; + +/*************************************************************************** + * Functions for handling Frame buffers. + **************************************************************************/ + +/*! + * Free frame buffers + * + * @param cam Structure cam_data * + * + * @return status 0 success. + */ +static int mxc_free_frame_buf(cam_data *cam) +{ + int i; + + pr_debug("MVC: In mxc_free_frame_buf\n"); + + for (i = 0; i < FRAME_NUM; i++) { + if (cam->frame[i].vaddress != 0) { + dma_free_coherent(0, cam->frame[i].buffer.length, + cam->frame[i].vaddress, + cam->frame[i].paddress); + cam->frame[i].vaddress = 0; + } + } + + return 0; +} + +/*! + * Allocate frame buffers + * + * @param cam Structure cam_data* + * @param count int number of buffer need to allocated + * + * @return status -0 Successfully allocated a buffer, -ENOBUFS failed. + */ +static int mxc_allocate_frame_buf(cam_data *cam, int count) +{ + int i; + + pr_debug("In MVC:mxc_allocate_frame_buf - size=%d\n", + cam->v2f.fmt.pix.sizeimage); + + for (i = 0; i < count; i++) { + cam->frame[i].vaddress = + dma_alloc_coherent(0, + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage), + &cam->frame[i].paddress, + GFP_DMA | GFP_KERNEL); + if (cam->frame[i].vaddress == 0) { + pr_err("ERROR: v4l2 capture: " + "mxc_allocate_frame_buf failed.\n"); + mxc_free_frame_buf(cam); + return -ENOBUFS; + } + cam->frame[i].buffer.index = i; + cam->frame[i].buffer.flags = V4L2_BUF_FLAG_MAPPED; + cam->frame[i].buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + cam->frame[i].buffer.length = + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage); + cam->frame[i].buffer.memory = V4L2_MEMORY_MMAP; + cam->frame[i].buffer.m.offset = cam->frame[i].paddress; + cam->frame[i].index = i; + } + + return 0; +} + +/*! + * Free frame buffers status + * + * @param cam Structure cam_data * + * + * @return none + */ +static void mxc_free_frames(cam_data *cam) +{ + int i; + + pr_debug("In MVC:mxc_free_frames\n"); + + for (i = 0; i < FRAME_NUM; i++) { + cam->frame[i].buffer.flags = V4L2_BUF_FLAG_MAPPED; + } + + cam->enc_counter = 0; + cam->skip_frame = 0; + INIT_LIST_HEAD(&cam->ready_q); + INIT_LIST_HEAD(&cam->working_q); + INIT_LIST_HEAD(&cam->done_q); +} + +/*! + * Return the buffer status + * + * @param cam Structure cam_data * + * @param buf Structure v4l2_buffer * + * + * @return status 0 success, EINVAL failed. + */ +static int mxc_v4l2_buffer_status(cam_data *cam, struct v4l2_buffer *buf) +{ + pr_debug("In MVC:mxc_v4l2_buffer_status\n"); + + if (buf->index < 0 || buf->index >= FRAME_NUM) { + pr_err("ERROR: v4l2 capture: mxc_v4l2_buffer_status buffers " + "not allocated\n"); + return -EINVAL; + } + + memcpy(buf, &(cam->frame[buf->index].buffer), sizeof(*buf)); + return 0; +} + +/*************************************************************************** + * Functions for handling the video stream. + **************************************************************************/ + +/*! + * Indicates whether the palette is supported. + * + * @param palette V4L2_PIX_FMT_RGB565, V4L2_PIX_FMT_BGR24 or V4L2_PIX_FMT_BGR32 + * + * @return 0 if failed + */ +static inline int valid_mode(u32 palette) +{ + return ((palette == V4L2_PIX_FMT_RGB565) || + (palette == V4L2_PIX_FMT_BGR24) || + (palette == V4L2_PIX_FMT_RGB24) || + (palette == V4L2_PIX_FMT_BGR32) || + (palette == V4L2_PIX_FMT_RGB32) || + (palette == V4L2_PIX_FMT_YUV422P) || + (palette == V4L2_PIX_FMT_UYVY) || + (palette == V4L2_PIX_FMT_YUV420) || + (palette == V4L2_PIX_FMT_NV12)); +} + +/*! + * Start the encoder job + * + * @param cam structure cam_data * + * + * @return status 0 Success + */ +static int mxc_streamon(cam_data *cam) +{ + struct mxc_v4l_frame *frame; + int err = 0; + + pr_debug("In MVC:mxc_streamon\n"); + + if (NULL == cam) { + pr_err("ERROR! cam parameter is NULL\n"); + return -1; + } + + if (list_empty(&cam->ready_q)) { + pr_err("ERROR: v4l2 capture: mxc_streamon buffer has not been " + "queued yet\n"); + return -EINVAL; + } + + cam->capture_pid = current->pid; + + if (cam->enc_enable) { + err = cam->enc_enable(cam); + if (err != 0) { + return err; + } + } + + cam->ping_pong_csi = 0; + if (cam->enc_update_eba) { + frame = + list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue); + list_del(cam->ready_q.next); + list_add_tail(&frame->queue, &cam->working_q); + err = cam->enc_update_eba(frame->buffer.m.offset, + &cam->ping_pong_csi); + + frame = + list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue); + list_del(cam->ready_q.next); + list_add_tail(&frame->queue, &cam->working_q); + err |= cam->enc_update_eba(frame->buffer.m.offset, + &cam->ping_pong_csi); + } else { + return -EINVAL; + } + + cam->capture_on = true; + + return err; +} + +/*! + * Shut down the encoder job + * + * @param cam structure cam_data * + * + * @return status 0 Success + */ +static int mxc_streamoff(cam_data *cam) +{ + int err = 0; + + pr_debug("In MVC:mxc_streamoff\n"); + + if (cam->capture_on == false) + return 0; + + if (cam->enc_disable) { + err = cam->enc_disable(cam); + } + mxc_free_frames(cam); + cam->capture_on = false; + return err; +} + +/*! + * Valid and adjust the overlay window size, position + * + * @param cam structure cam_data * + * @param win struct v4l2_window * + * + * @return 0 + */ +static int verify_preview(cam_data *cam, struct v4l2_window *win) +{ + int i = 0; + int *width, *height; + + pr_debug("In MVC: verify_preview\n"); + + do { + cam->overlay_fb = (struct fb_info *)registered_fb[i]; + if (cam->overlay_fb == NULL) { + pr_err("ERROR: verify_preview frame buffer NULL.\n"); + return -1; + } + if (strncmp(cam->overlay_fb->fix.id, + mxc_capture_outputs[cam->output].name, 5) == 0) { + break; + } + } while (++i < FB_MAX); + + /* 4 bytes alignment for both FG and BG */ + if (cam->overlay_fb->var.bits_per_pixel == 24) { + win->w.left -= win->w.left % 4; + } else if (cam->overlay_fb->var.bits_per_pixel == 16) { + win->w.left -= win->w.left % 2; + } + + if (win->w.width + win->w.left > cam->overlay_fb->var.xres) + win->w.width = cam->overlay_fb->var.xres - win->w.left; + if (win->w.height + win->w.top > cam->overlay_fb->var.yres) + win->w.height = cam->overlay_fb->var.yres - win->w.top; + + /* stride line limitation */ + win->w.height -= win->w.height % 8; + win->w.width -= win->w.width % 8; + + if (cam->rotation >= IPU_ROTATE_90_RIGHT) { + height = &win->w.width; + width = &win->w.height; + } else { + width = &win->w.width; + height = &win->w.height; + } + + if ((cam->crop_bounds.width / *width > 8) || + ((cam->crop_bounds.width / *width == 8) && + (cam->crop_bounds.width % *width))) { + *width = cam->crop_bounds.width / 8; + if (*width % 8) + *width += 8 - *width % 8; + if (*width + win->w.left > cam->overlay_fb->var.xres) { + pr_err("ERROR: v4l2 capture: width exceeds " + "resize limit.\n"); + return -1; + } + pr_err("ERROR: v4l2 capture: width exceeds limit. " + "Resize to %d.\n", + *width); + } + + if ((cam->crop_bounds.height / *height > 8) || + ((cam->crop_bounds.height / *height == 8) && + (cam->crop_bounds.height % *height))) { + *height = cam->crop_bounds.height / 8; + if (*height % 8) + *height += 8 - *height % 8; + if (*height + win->w.top > cam->overlay_fb->var.yres) { + pr_err("ERROR: v4l2 capture: height exceeds " + "resize limit.\n"); + return -1; + } + pr_err("ERROR: v4l2 capture: height exceeds limit " + "resize to %d.\n", + *height); + } + + return 0; +} + +/*! + * start the viewfinder job + * + * @param cam structure cam_data * + * + * @return status 0 Success + */ +static int start_preview(cam_data *cam) +{ + int err = 0; + + pr_debug("MVC: start_preview\n"); + +#if defined(CONFIG_MXC_IPU_PRP_VF_SDC) || defined(CONFIG_MXC_IPU_PRP_VF_SDC_MODULE) + pr_debug(" This is an SDC display\n"); + if (cam->output == 0) { + if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_OVERLAY) + err = prp_vf_sdc_select(cam); + else if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_PRIMARY) + err = prp_vf_sdc_select_bg(cam); + if (err != 0) + return err; + + err = cam->vf_start_sdc(cam); + } +#endif + +#if defined(CONFIG_MXC_IPU_PRP_VF_ADC) || defined(CONFIG_MXC_IPU_PRP_VF_ADC_MODULE) + pr_debug(" This is an ADC display\n"); + if (cam->output == 1) { + err = prp_vf_adc_select(cam); + if (err != 0) + return err; + + err = cam->vf_start_adc(cam); + } +#endif + + pr_debug("End of %s: v2f pix widthxheight %d x %d\n", + __func__, + cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height); + pr_debug("End of %s: crop_bounds widthxheight %d x %d\n", + __func__, + cam->crop_bounds.width, cam->crop_bounds.height); + pr_debug("End of %s: crop_defrect widthxheight %d x %d\n", + __func__, + cam->crop_defrect.width, cam->crop_defrect.height); + pr_debug("End of %s: crop_current widthxheight %d x %d\n", + __func__, + cam->crop_current.width, cam->crop_current.height); + + return err; +} + +/*! + * shut down the viewfinder job + * + * @param cam structure cam_data * + * + * @return status 0 Success + */ +static int stop_preview(cam_data *cam) +{ + int err = 0; + + pr_debug("MVC: stop preview\n"); + +#if defined(CONFIG_MXC_IPU_PRP_VF_ADC) || defined(CONFIG_MXC_IPU_PRP_VF_ADC_MODULE) + if (cam->output == 1) { + err = prp_vf_adc_deselect(cam); + } +#endif + +#if defined(CONFIG_MXC_IPU_PRP_VF_SDC) || defined(CONFIG_MXC_IPU_PRP_VF_SDC_MODULE) + if (cam->output == 0) { + if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_OVERLAY) + err = prp_vf_sdc_deselect(cam); + else if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_PRIMARY) + err = prp_vf_sdc_deselect_bg(cam); + } +#endif + + return err; +} + +/*************************************************************************** + * VIDIOC Functions. + **************************************************************************/ + +/*! + * V4L2 - mxc_v4l2_g_fmt function + * + * @param cam structure cam_data * + * + * @param f structure v4l2_format * + * + * @return status 0 success, EINVAL failed + */ +static int mxc_v4l2_g_fmt(cam_data *cam, struct v4l2_format *f) +{ + int retval = 0; + + pr_debug("In MVC: mxc_v4l2_g_fmt type=%d\n", f->type); + + switch (f->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + pr_debug(" type is V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); + f->fmt.pix = cam->v2f.fmt.pix; + break; + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + pr_debug(" type is V4L2_BUF_TYPE_VIDEO_OVERLAY\n"); + f->fmt.win = cam->win; + break; + default: + pr_debug(" type is invalid\n"); + retval = -EINVAL; + } + + pr_debug("End of %s: v2f pix widthxheight %d x %d\n", + __func__, + cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height); + pr_debug("End of %s: crop_bounds widthxheight %d x %d\n", + __func__, + cam->crop_bounds.width, cam->crop_bounds.height); + pr_debug("End of %s: crop_defrect widthxheight %d x %d\n", + __func__, + cam->crop_defrect.width, cam->crop_defrect.height); + pr_debug("End of %s: crop_current widthxheight %d x %d\n", + __func__, + cam->crop_current.width, cam->crop_current.height); + + return retval; +} + +/*! + * V4L2 - mxc_v4l2_s_fmt function + * + * @param cam structure cam_data * + * + * @param f structure v4l2_format * + * + * @return status 0 success, EINVAL failed + */ +static int mxc_v4l2_s_fmt(cam_data *cam, struct v4l2_format *f) +{ + int retval = 0; + int size = 0; + int bytesperline = 0; + int *width, *height; + + pr_debug("In MVC: mxc_v4l2_s_fmt\n"); + + switch (f->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + pr_debug(" type=V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); + if (!valid_mode(f->fmt.pix.pixelformat)) { + pr_err("ERROR: v4l2 capture: mxc_v4l2_s_fmt: format " + "not supported\n"); + return -EINVAL; + } + + /* Handle case where size requested is larger than cuurent + * camera setting. */ + if ((f->fmt.pix.width > cam->crop_bounds.width) + || (f->fmt.pix.height > cam->crop_bounds.height)) { + /* Need the logic here, calling vidioc_s_param if + * camera can change. */ + /* For the moment, just return an error. */ + return -EINVAL; + } + + if (cam->rotation >= IPU_ROTATE_90_RIGHT) { + height = &f->fmt.pix.width; + width = &f->fmt.pix.height; + } else { + width = &f->fmt.pix.width; + height = &f->fmt.pix.height; + } + + /* stride line limitation */ + *width -= *width % 8; + *height -= *height % 8; + + if ((cam->crop_bounds.width / *width > 8) || + ((cam->crop_bounds.width / *width == 8) && + (cam->crop_bounds.width % *width))) { + *width = cam->crop_bounds.width / 8; + if (*width % 8) + *width += 8 - *width % 8; + pr_err("ERROR: v4l2 capture: width exceeds limit " + "resize to %d.\n", + *width); + } + + if ((cam->crop_bounds.height / *height > 8) || + ((cam->crop_bounds.height / *height == 8) && + (cam->crop_bounds.height % *height))) { + *height = cam->crop_bounds.height / 8; + if (*height % 8) + *height += 8 - *height % 8; + pr_err("ERROR: v4l2 capture: height exceeds limit " + "resize to %d.\n", + *height); + } + + switch (f->fmt.pix.pixelformat) { + case V4L2_PIX_FMT_RGB565: + size = f->fmt.pix.width * f->fmt.pix.height * 2; + bytesperline = f->fmt.pix.width * 2; + break; + case V4L2_PIX_FMT_BGR24: + size = f->fmt.pix.width * f->fmt.pix.height * 3; + bytesperline = f->fmt.pix.width * 3; + break; + case V4L2_PIX_FMT_RGB24: + size = f->fmt.pix.width * f->fmt.pix.height * 3; + bytesperline = f->fmt.pix.width * 3; + break; + case V4L2_PIX_FMT_BGR32: + size = f->fmt.pix.width * f->fmt.pix.height * 4; + bytesperline = f->fmt.pix.width * 4; + break; + case V4L2_PIX_FMT_RGB32: + size = f->fmt.pix.width * f->fmt.pix.height * 4; + bytesperline = f->fmt.pix.width * 4; + break; + case V4L2_PIX_FMT_YUV422P: + size = f->fmt.pix.width * f->fmt.pix.height * 2; + bytesperline = f->fmt.pix.width; + break; + case V4L2_PIX_FMT_UYVY: + size = f->fmt.pix.width * f->fmt.pix.height * 2; + bytesperline = f->fmt.pix.width * 2; + break; + case V4L2_PIX_FMT_YUV420: + size = f->fmt.pix.width * f->fmt.pix.height * 3 / 2; + bytesperline = f->fmt.pix.width; + break; + case V4L2_PIX_FMT_NV12: + size = f->fmt.pix.width * f->fmt.pix.height * 3 / 2; + bytesperline = f->fmt.pix.width; + break; + default: + break; + } + + if (f->fmt.pix.bytesperline < bytesperline) { + f->fmt.pix.bytesperline = bytesperline; + } else { + bytesperline = f->fmt.pix.bytesperline; + } + + if (f->fmt.pix.sizeimage < size) { + f->fmt.pix.sizeimage = size; + } else { + size = f->fmt.pix.sizeimage; + } + + cam->v2f.fmt.pix = f->fmt.pix; + + if (cam->v2f.fmt.pix.priv != 0) { + if (copy_from_user(&cam->offset, + (void *)cam->v2f.fmt.pix.priv, + sizeof(cam->offset))) { + retval = -EFAULT; + break; + } + } + break; + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + pr_debug(" type=V4L2_BUF_TYPE_VIDEO_OVERLAY\n"); + retval = verify_preview(cam, &f->fmt.win); + cam->win = f->fmt.win; + break; + default: + retval = -EINVAL; + } + + pr_debug("End of %s: v2f pix widthxheight %d x %d\n", + __func__, + cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height); + pr_debug("End of %s: crop_bounds widthxheight %d x %d\n", + __func__, + cam->crop_bounds.width, cam->crop_bounds.height); + pr_debug("End of %s: crop_defrect widthxheight %d x %d\n", + __func__, + cam->crop_defrect.width, cam->crop_defrect.height); + pr_debug("End of %s: crop_current widthxheight %d x %d\n", + __func__, + cam->crop_current.width, cam->crop_current.height); + + return retval; +} + +/*! + * get control param + * + * @param cam structure cam_data * + * + * @param c structure v4l2_control * + * + * @return status 0 success, EINVAL failed + */ +static int mxc_v4l2_g_ctrl(cam_data *cam, struct v4l2_control *c) +{ + int status = 0; + + pr_debug("In MVC:mxc_v4l2_g_ctrl\n"); + + /* probably don't need to store the values that can be retrieved, + * locally, but they are for now. */ + switch (c->id) { + case V4L2_CID_HFLIP: + /* This is handled in the ipu. */ + if (cam->rotation == IPU_ROTATE_HORIZ_FLIP) + c->value = 1; + break; + case V4L2_CID_VFLIP: + /* This is handled in the ipu. */ + if (cam->rotation == IPU_ROTATE_VERT_FLIP) + c->value = 1; + break; + case V4L2_CID_MXC_ROT: + /* This is handled in the ipu. */ + c->value = cam->rotation; + break; + case V4L2_CID_BRIGHTNESS: + c->value = cam->bright; + status = vidioc_int_g_ctrl(cam->sensor, c); + cam->bright = c->value; + break; + case V4L2_CID_HUE: + c->value = cam->hue; + status = vidioc_int_g_ctrl(cam->sensor, c); + cam->hue = c->value; + break; + case V4L2_CID_CONTRAST: + c->value = cam->contrast; + status = vidioc_int_g_ctrl(cam->sensor, c); + cam->contrast = c->value; + break; + case V4L2_CID_SATURATION: + c->value = cam->saturation; + status = vidioc_int_g_ctrl(cam->sensor, c); + cam->saturation = c->value; + break; + case V4L2_CID_RED_BALANCE: + c->value = cam->red; + status = vidioc_int_g_ctrl(cam->sensor, c); + cam->red = c->value; + break; + case V4L2_CID_BLUE_BALANCE: + c->value = cam->blue; + status = vidioc_int_g_ctrl(cam->sensor, c); + cam->blue = c->value; + break; + case V4L2_CID_BLACK_LEVEL: + c->value = cam->ae_mode; + status = vidioc_int_g_ctrl(cam->sensor, c); + cam->ae_mode = c->value; + break; + default: + status = vidioc_int_g_ctrl(cam->sensor, c); + } + + return status; +} + +/*! + * V4L2 - set_control function + * V4L2_CID_PRIVATE_BASE is the extention for IPU preprocessing. + * 0 for normal operation + * 1 for vertical flip + * 2 for horizontal flip + * 3 for horizontal and vertical flip + * 4 for 90 degree rotation + * @param cam structure cam_data * + * + * @param c structure v4l2_control * + * + * @return status 0 success, EINVAL failed + */ +static int mxc_v4l2_s_ctrl(cam_data *cam, struct v4l2_control *c) +{ + int ret = 0; + + pr_debug("In MVC:mxc_v4l2_s_ctrl\n"); + + switch (c->id) { + case V4L2_CID_HFLIP: + /* This is done by the IPU */ + if (c->value == 1) { + if ((cam->rotation != IPU_ROTATE_VERT_FLIP) && + (cam->rotation != IPU_ROTATE_180)) + cam->rotation = IPU_ROTATE_HORIZ_FLIP; + else + cam->rotation = IPU_ROTATE_180; + } else { + if (cam->rotation == IPU_ROTATE_HORIZ_FLIP) + cam->rotation = IPU_ROTATE_NONE; + if (cam->rotation == IPU_ROTATE_180) + cam->rotation = IPU_ROTATE_VERT_FLIP; + } + break; + case V4L2_CID_VFLIP: + /* This is done by the IPU */ + if (c->value == 1) { + if ((cam->rotation != IPU_ROTATE_HORIZ_FLIP) && + (cam->rotation != IPU_ROTATE_180)) + cam->rotation = IPU_ROTATE_VERT_FLIP; + else + cam->rotation = IPU_ROTATE_180; + } else { + if (cam->rotation == IPU_ROTATE_VERT_FLIP) + cam->rotation = IPU_ROTATE_NONE; + if (cam->rotation == IPU_ROTATE_180) + cam->rotation = IPU_ROTATE_HORIZ_FLIP; + } + break; + case V4L2_CID_MXC_ROT: + /* This is done by the IPU */ + switch (c->value) { + case V4L2_MXC_ROTATE_NONE: + cam->rotation = IPU_ROTATE_NONE; + break; + case V4L2_MXC_ROTATE_VERT_FLIP: + cam->rotation = IPU_ROTATE_VERT_FLIP; + break; + case V4L2_MXC_ROTATE_HORIZ_FLIP: + cam->rotation = IPU_ROTATE_HORIZ_FLIP; + break; + case V4L2_MXC_ROTATE_180: + cam->rotation = IPU_ROTATE_180; + break; + case V4L2_MXC_ROTATE_90_RIGHT: + cam->rotation = IPU_ROTATE_90_RIGHT; + break; + case V4L2_MXC_ROTATE_90_RIGHT_VFLIP: + cam->rotation = IPU_ROTATE_90_RIGHT_VFLIP; + break; + case V4L2_MXC_ROTATE_90_RIGHT_HFLIP: + cam->rotation = IPU_ROTATE_90_RIGHT_HFLIP; + break; + case V4L2_MXC_ROTATE_90_LEFT: + cam->rotation = IPU_ROTATE_90_LEFT; + break; + default: + ret = -EINVAL; + } + break; + case V4L2_CID_HUE: + cam->hue = c->value; + ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, true, true); + ret = vidioc_int_s_ctrl(cam->sensor, c); + ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, false, false); + break; + case V4L2_CID_CONTRAST: + cam->contrast = c->value; + ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, true, true); + ret = vidioc_int_s_ctrl(cam->sensor, c); + ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, false, false); + break; + case V4L2_CID_BRIGHTNESS: + cam->bright = c->value; + ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, true, true); + ret = vidioc_int_s_ctrl(cam->sensor, c); + ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, false, false); + break; + case V4L2_CID_SATURATION: + cam->saturation = c->value; + ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, true, true); + ret = vidioc_int_s_ctrl(cam->sensor, c); + ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, false, false); + break; + case V4L2_CID_RED_BALANCE: + cam->red = c->value; + ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, true, true); + ret = vidioc_int_s_ctrl(cam->sensor, c); + ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, false, false); + break; + case V4L2_CID_BLUE_BALANCE: + cam->blue = c->value; + ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, true, true); + ret = vidioc_int_s_ctrl(cam->sensor, c); + ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, false, false); + break; + case V4L2_CID_EXPOSURE: + cam->ae_mode = c->value; + ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, true, true); + ret = vidioc_int_s_ctrl(cam->sensor, c); + ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, false, false); + break; + case V4L2_CID_MXC_FLASH: +#ifdef CONFIG_MXC_IPU_V1 + ipu_csi_flash_strobe(true); +#endif + break; + default: + pr_debug(" default case\n"); + ret = -EINVAL; + break; + } + + return ret; +} + +/*! + * V4L2 - mxc_v4l2_s_param function + * Allows setting of capturemode and frame rate. + * + * @param cam structure cam_data * + * @param parm structure v4l2_streamparm * + * + * @return status 0 success, EINVAL failed + */ +static int mxc_v4l2_s_param(cam_data *cam, struct v4l2_streamparm *parm) +{ + struct v4l2_ifparm ifparm; + struct v4l2_format cam_fmt; + struct v4l2_streamparm currentparm; + ipu_csi_signal_cfg_t csi_param; + int err = 0; + + pr_debug("In mxc_v4l2_s_param\n"); + + if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + pr_err(KERN_ERR "mxc_v4l2_s_param invalid type\n"); + return -EINVAL; + } + + /* Stop the viewfinder */ + if (cam->overlay_on == true) { + stop_preview(cam); + } + + currentparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + /* First check that this device can support the changes requested. */ + err = vidioc_int_g_parm(cam->sensor, ¤tparm); + if (err) { + pr_err("%s: vidioc_int_g_parm returned an error %d\n", + __func__, err); + goto exit; + } + + pr_debug(" Current capabilities are %x\n", + currentparm.parm.capture.capability); + pr_debug(" Current capturemode is %d change to %d\n", + currentparm.parm.capture.capturemode, + parm->parm.capture.capturemode); + pr_debug(" Current framerate is %d change to %d\n", + currentparm.parm.capture.timeperframe.denominator, + parm->parm.capture.timeperframe.denominator); + + /* This will change any camera settings needed. */ + ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, true, true); + err = vidioc_int_s_parm(cam->sensor, parm); + ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, false, false); + if (err) { + pr_err("%s: vidioc_int_s_parm returned an error %d\n", + __func__, err); + goto exit; + } + + /* If resolution changed, need to re-program the CSI */ + /* Get new values. */ + vidioc_int_g_ifparm(cam->sensor, &ifparm); + + csi_param.data_width = 0; + csi_param.clk_mode = 0; + csi_param.ext_vsync = 0; + csi_param.Vsync_pol = 0; + csi_param.Hsync_pol = 0; + csi_param.pixclk_pol = 0; + csi_param.data_pol = 0; + csi_param.sens_clksrc = 0; + csi_param.pack_tight = 0; + csi_param.force_eof = 0; + csi_param.data_en_pol = 0; + csi_param.data_fmt = 0; + csi_param.csi = 0; + csi_param.mclk = 0; + + /* This may not work on other platforms. Check when adding a new one.*/ + pr_debug(" clock_curr=mclk=%d\n", ifparm.u.bt656.clock_curr); + if (ifparm.u.bt656.clock_curr == 0) { + csi_param.clk_mode = IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE; + } else { + csi_param.clk_mode = IPU_CSI_CLK_MODE_GATED_CLK; + } + + csi_param.pixclk_pol = ifparm.u.bt656.latch_clk_inv; + + if (ifparm.u.bt656.mode == V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT) { + csi_param.data_width = IPU_CSI_DATA_WIDTH_8; + } else if (ifparm.u.bt656.mode + == V4L2_IF_TYPE_BT656_MODE_NOBT_10BIT) { + csi_param.data_width = IPU_CSI_DATA_WIDTH_10; + } else { + csi_param.data_width = IPU_CSI_DATA_WIDTH_8; + } + + csi_param.Vsync_pol = ifparm.u.bt656.nobt_vs_inv; + csi_param.Hsync_pol = ifparm.u.bt656.nobt_hs_inv; + csi_param.ext_vsync = ifparm.u.bt656.bt_sync_correct; + + /* if the capturemode changed, the size bounds will have changed. */ + cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt); + pr_debug(" g_fmt_cap returns widthxheight of input as %d x %d\n", + cam_fmt.fmt.pix.width, cam_fmt.fmt.pix.height); + + csi_param.data_fmt = cam_fmt.fmt.pix.pixelformat; + + cam->crop_bounds.top = cam->crop_bounds.left = 0; + cam->crop_bounds.width = cam_fmt.fmt.pix.width; + cam->crop_bounds.height = cam_fmt.fmt.pix.height; + + /* This essentially loses the data at the left and bottom of the image + * giving a digital zoom image, if crop_current is less than the full + * size of the image. */ + ipu_csi_set_window_size(cam->crop_current.width, + cam->crop_current.height, cam->csi); + ipu_csi_set_window_pos(cam->crop_current.left, + cam->crop_current.top, + cam->csi); + ipu_csi_init_interface(cam->crop_bounds.width, + cam->crop_bounds.height, + cam_fmt.fmt.pix.pixelformat, csi_param); + + +exit: + if (cam->overlay_on == true) + start_preview(cam); + + return err; +} + +/*! + * V4L2 - mxc_v4l2_s_std function + * + * Sets the TV standard to be used. + * + * @param cam structure cam_data * + * @param parm structure v4l2_streamparm * + * + * @return status 0 success, EINVAL failed + */ +static int mxc_v4l2_s_std(cam_data *cam, v4l2_std_id e) +{ + bool change = false; + + if (e != cam->standard.id) { + change = true; + } + + pr_debug("In mxc_v4l2_s_std %Lx\n", e); + if (e == V4L2_STD_PAL) { + pr_debug(" Setting standard to PAL %Lx\n", V4L2_STD_PAL); + cam->standard.id = V4L2_STD_PAL; + video_index = TV_PAL; + cam->crop_current.top = 0; + } else if (e == V4L2_STD_NTSC) { + pr_debug(" Setting standard to NTSC %Lx\n", + V4L2_STD_NTSC); + /* Get rid of the white dot line in NTSC signal input */ + cam->standard.id = V4L2_STD_NTSC; + video_index = TV_NTSC; + cam->crop_current.top = 12; + } else { + cam->standard.id = V4L2_STD_ALL; + video_index = TV_NOT_LOCKED; + cam->crop_current.top = 0; + pr_err("ERROR: unrecognized std! %Lx (PAL=%Lx, NTSC=%Lx\n", + e, V4L2_STD_PAL, V4L2_STD_NTSC); + } + + cam->standard.index = video_index; + strcpy(cam->standard.name, video_fmts[video_index].name); + cam->crop_bounds.width = video_fmts[video_index].raw_width; + cam->crop_bounds.height = video_fmts[video_index].raw_height; + cam->crop_current.width = video_fmts[video_index].active_width; + cam->crop_current.height = video_fmts[video_index].active_height; + cam->crop_current.left = 0; + + return 0; +} + +/*! + * V4L2 - mxc_v4l2_g_std function + * + * Gets the TV standard from the TV input device. + * + * @param cam structure cam_data * + * + * @param e structure v4l2_streamparm * + * + * @return status 0 success, EINVAL failed + */ +static int mxc_v4l2_g_std(cam_data *cam, v4l2_std_id *e) +{ + struct v4l2_format tv_fmt; + + pr_debug("In mxc_v4l2_g_std\n"); + + if (cam->device_type == 1) { + /* Use this function to get what the TV-In device detects the + * format to be. pixelformat is used to return the std value + * since the interface has no vidioc_g_std.*/ + tv_fmt.type = V4L2_BUF_TYPE_PRIVATE; + vidioc_int_g_fmt_cap(cam->sensor, &tv_fmt); + + /* If the TV-in automatically detects the standard, then if it + * changes, the settings need to change. */ + if (cam->standard_autodetect) { + if (cam->standard.id != tv_fmt.fmt.pix.pixelformat) { + pr_debug("MVC: mxc_v4l2_g_std: " + "Changing standard\n"); + mxc_v4l2_s_std(cam, tv_fmt.fmt.pix.pixelformat); + } + } + + *e = tv_fmt.fmt.pix.pixelformat; + } + + return 0; +} + +/*! + * Dequeue one V4L capture buffer + * + * @param cam structure cam_data * + * @param buf structure v4l2_buffer * + * + * @return status 0 success, EINVAL invalid frame number, + * ETIME timeout, ERESTARTSYS interrupted by user + */ +static int mxc_v4l_dqueue(cam_data *cam, struct v4l2_buffer *buf) +{ + int retval = 0; + struct mxc_v4l_frame *frame; + + pr_debug("In MVC:mxc_v4l_dqueue\n"); + + if (!wait_event_interruptible_timeout(cam->enc_queue, + cam->enc_counter != 0, 10 * HZ)) { + pr_err("ERROR: v4l2 capture: mxc_v4l_dqueue timeout " + "enc_counter %x\n", + cam->enc_counter); + return -ETIME; + } else if (signal_pending(current)) { + pr_err("ERROR: v4l2 capture: mxc_v4l_dqueue() " + "interrupt received\n"); + return -ERESTARTSYS; + } + + cam->enc_counter--; + + frame = list_entry(cam->done_q.next, struct mxc_v4l_frame, queue); + list_del(cam->done_q.next); + if (frame->buffer.flags & V4L2_BUF_FLAG_DONE) { + frame->buffer.flags &= ~V4L2_BUF_FLAG_DONE; + } else if (frame->buffer.flags & V4L2_BUF_FLAG_QUEUED) { + pr_err("ERROR: v4l2 capture: VIDIOC_DQBUF: " + "Buffer not filled.\n"); + frame->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED; + retval = -EINVAL; + } else if ((frame->buffer.flags & 0x7) == V4L2_BUF_FLAG_MAPPED) { + pr_err("ERROR: v4l2 capture: VIDIOC_DQBUF: " + "Buffer not queued.\n"); + retval = -EINVAL; + } + + buf->bytesused = cam->v2f.fmt.pix.sizeimage; + buf->index = frame->index; + buf->flags = frame->buffer.flags; + buf->m = cam->frame[frame->index].buffer.m; + + return retval; +} + +/*! + * V4L interface - open function + * + * @param inode structure inode * + * @param file structure file * + * + * @return status 0 success, ENODEV invalid device instance, + * ENODEV timeout, ERESTARTSYS interrupted by user + */ +static int mxc_v4l_open(struct inode *inode, struct file *file) +{ + struct v4l2_ifparm ifparm; + struct v4l2_format cam_fmt; + ipu_csi_signal_cfg_t csi_param; + struct video_device *dev = video_devdata(file); + cam_data *cam = video_get_drvdata(dev); + int err = 0; + + pr_debug("\nIn MVC: mxc_v4l_open\n"); + pr_debug(" device name is %s\n", dev->name); + + if (!cam) { + pr_err("ERROR: v4l2 capture: Internal error, " + "cam_data not found!\n"); + return -EBADF; + } + + down(&cam->busy_lock); + err = 0; + if (signal_pending(current)) + goto oops; + + if (cam->open_count++ == 0) { + wait_event_interruptible(cam->power_queue, + cam->low_power == false); + +#if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_PRP_ENC_MODULE) + err = prp_enc_select(cam); +#endif + + cam->enc_counter = 0; + cam->skip_frame = 0; + INIT_LIST_HEAD(&cam->ready_q); + INIT_LIST_HEAD(&cam->working_q); + INIT_LIST_HEAD(&cam->done_q); + + vidioc_int_g_ifparm(cam->sensor, &ifparm); + + csi_param.sens_clksrc = 0; + + csi_param.clk_mode = 0; + csi_param.data_pol = 0; + csi_param.ext_vsync = 0; + + csi_param.pack_tight = 0; + csi_param.force_eof = 0; + csi_param.data_en_pol = 0; + csi_param.mclk = ifparm.u.bt656.clock_curr; + + csi_param.pixclk_pol = ifparm.u.bt656.latch_clk_inv; + + /* Once we handle multiple inputs this will need to change. */ + csi_param.csi = 0; + + if (ifparm.u.bt656.mode + == V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT) + csi_param.data_width = IPU_CSI_DATA_WIDTH_8; + else if (ifparm.u.bt656.mode + == V4L2_IF_TYPE_BT656_MODE_NOBT_10BIT) + csi_param.data_width = IPU_CSI_DATA_WIDTH_10; + else + csi_param.data_width = IPU_CSI_DATA_WIDTH_8; + + + csi_param.Vsync_pol = ifparm.u.bt656.nobt_vs_inv; + csi_param.Hsync_pol = ifparm.u.bt656.nobt_hs_inv; + + csi_param.csi = cam->csi; + + cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt); + + /* Reset the sizes. Needed to prevent carryover of last + * operation.*/ + cam->crop_bounds.top = cam->crop_bounds.left = 0; + cam->crop_bounds.width = cam_fmt.fmt.pix.width; + cam->crop_bounds.height = cam_fmt.fmt.pix.height; + + /* This also is the max crop size for this device. */ + cam->crop_defrect.top = cam->crop_defrect.left = 0; + cam->crop_defrect.width = cam_fmt.fmt.pix.width; + cam->crop_defrect.height = cam_fmt.fmt.pix.height; + + /* At this point, this is also the current image size. */ + cam->crop_current.top = cam->crop_current.left = 0; + cam->crop_current.width = cam_fmt.fmt.pix.width; + cam->crop_current.height = cam_fmt.fmt.pix.height; + + pr_debug("End of %s: v2f pix widthxheight %d x %d\n", + __func__, + cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height); + pr_debug("End of %s: crop_bounds widthxheight %d x %d\n", + __func__, + cam->crop_bounds.width, cam->crop_bounds.height); + pr_debug("End of %s: crop_defrect widthxheight %d x %d\n", + __func__, + cam->crop_defrect.width, cam->crop_defrect.height); + pr_debug("End of %s: crop_current widthxheight %d x %d\n", + __func__, + cam->crop_current.width, cam->crop_current.height); + + csi_param.data_fmt = cam_fmt.fmt.pix.pixelformat; + pr_debug("On Open: Input to ipu size is %d x %d\n", + cam_fmt.fmt.pix.width, cam_fmt.fmt.pix.height); + ipu_csi_set_window_size(cam->crop_current.width, + cam->crop_current.width, + cam->csi); + ipu_csi_set_window_pos(cam->crop_current.left, + cam->crop_current.top, + cam->csi); + ipu_csi_init_interface(cam->crop_bounds.width, + cam->crop_bounds.height, + cam_fmt.fmt.pix.pixelformat, + csi_param); + + ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, + true, true); + vidioc_int_init(cam->sensor); + + ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, + false, false); +} + + file->private_data = dev; + + oops: + up(&cam->busy_lock); + return err; +} + +/*! + * V4L interface - close function + * + * @param inode struct inode * + * @param file struct file * + * + * @return 0 success + */ +static int mxc_v4l_close(struct inode *inode, struct file *file) +{ + struct video_device *dev = video_devdata(file); + int err = 0; + cam_data *cam = video_get_drvdata(dev); + + pr_debug("In MVC:mxc_v4l_close\n"); + + if (!cam) { + pr_err("ERROR: v4l2 capture: Internal error, " + "cam_data not found!\n"); + return -EBADF; + } + + /* for the case somebody hit the ctrl C */ + if (cam->overlay_pid == current->pid) { + err = stop_preview(cam); + cam->overlay_on = false; + } + if (cam->capture_pid == current->pid) { + err |= mxc_streamoff(cam); + wake_up_interruptible(&cam->enc_queue); + } + + if (--cam->open_count == 0) { + wait_event_interruptible(cam->power_queue, + cam->low_power == false); + pr_info("mxc_v4l_close: release resource\n"); + +#if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_PRP_ENC_MODULE) + err |= prp_enc_deselect(cam); +#endif + mxc_free_frame_buf(cam); + file->private_data = NULL; + + /* capture off */ + wake_up_interruptible(&cam->enc_queue); + mxc_free_frames(cam); + cam->enc_counter++; + } + + return err; +} + +#if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_PRP_ENC_MODULE) +/* + * V4L interface - read function + * + * @param file struct file * + * @param read buf char * + * @param count size_t + * @param ppos structure loff_t * + * + * @return bytes read + */ +static ssize_t mxc_v4l_read(struct file *file, char *buf, size_t count, + loff_t *ppos) +{ + int err = 0; + u8 *v_address; + struct video_device *dev = video_devdata(file); + cam_data *cam = video_get_drvdata(dev); + + if (down_interruptible(&cam->busy_lock)) + return -EINTR; + + /* Stop the viewfinder */ + if (cam->overlay_on == true) + stop_preview(cam); + + v_address = dma_alloc_coherent(0, + PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage), + &cam->still_buf, GFP_DMA | GFP_KERNEL); + + if (!v_address) { + err = -ENOBUFS; + goto exit0; + } + + err = prp_still_select(cam); + if (err != 0) { + err = -EIO; + goto exit1; + } + + cam->still_counter = 0; + err = cam->csi_start(cam); + if (err != 0) { + err = -EIO; + goto exit2; + } + + if (!wait_event_interruptible_timeout(cam->still_queue, + cam->still_counter != 0, + 10 * HZ)) { + pr_err("ERROR: v4l2 capture: mxc_v4l_read timeout counter %x\n", + cam->still_counter); + err = -ETIME; + goto exit2; + } + err = copy_to_user(buf, v_address, cam->v2f.fmt.pix.sizeimage); + + exit2: + prp_still_deselect(cam); + + exit1: + dma_free_coherent(0, cam->v2f.fmt.pix.sizeimage, v_address, + cam->still_buf); + cam->still_buf = 0; + + exit0: + if (cam->overlay_on == true) { + start_preview(cam); + } + + up(&cam->busy_lock); + if (err < 0) + return err; + + return (cam->v2f.fmt.pix.sizeimage - err); +} +#endif + +/*! + * V4L interface - ioctl function + * + * @param inode struct inode* + * + * @param file struct file* + * + * @param ioctlnr unsigned int + * + * @param arg void* + * + * @return 0 success, ENODEV for invalid device instance, + * -1 for other errors. + */ +static int mxc_v4l_do_ioctl(struct inode *inode, struct file *file, + unsigned int ioctlnr, void *arg) +{ + struct video_device *dev = video_devdata(file); + cam_data *cam = video_get_drvdata(dev); + int retval = 0; + unsigned long lock_flags; + + pr_debug("In MVC: mxc_v4l_do_ioctl %x\n", ioctlnr); + wait_event_interruptible(cam->power_queue, cam->low_power == false); + /* make this _really_ smp-safe */ + if (down_interruptible(&cam->busy_lock)) + return -EBUSY; + + switch (ioctlnr) { + /*! + * V4l2 VIDIOC_QUERYCAP ioctl + */ + case VIDIOC_QUERYCAP: { + struct v4l2_capability *cap = arg; + pr_debug(" case VIDIOC_QUERYCAP\n"); + strcpy(cap->driver, "mxc_v4l2"); + cap->version = KERNEL_VERSION(0, 1, 11); + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_VIDEO_OVERLAY | + V4L2_CAP_STREAMING | + V4L2_CAP_READWRITE; + cap->card[0] = '\0'; + cap->bus_info[0] = '\0'; + break; + } + + /*! + * V4l2 VIDIOC_G_FMT ioctl + */ + case VIDIOC_G_FMT: { + struct v4l2_format *gf = arg; + pr_debug(" case VIDIOC_G_FMT\n"); + retval = mxc_v4l2_g_fmt(cam, gf); + break; + } + + /*! + * V4l2 VIDIOC_S_FMT ioctl + */ + case VIDIOC_S_FMT: { + struct v4l2_format *sf = arg; + pr_debug(" case VIDIOC_S_FMT\n"); + retval = mxc_v4l2_s_fmt(cam, sf); + break; + } + + /*! + * V4l2 VIDIOC_REQBUFS ioctl + */ + case VIDIOC_REQBUFS: { + struct v4l2_requestbuffers *req = arg; + pr_debug(" case VIDIOC_REQBUFS\n"); + + if (req->count > FRAME_NUM) { + pr_err("ERROR: v4l2 capture: VIDIOC_REQBUFS: " + "not enough buffers\n"); + req->count = FRAME_NUM; + } + + if ((req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) || + (req->memory != V4L2_MEMORY_MMAP)) { + pr_err("ERROR: v4l2 capture: VIDIOC_REQBUFS: " + "wrong buffer type\n"); + retval = -EINVAL; + break; + } + + mxc_streamoff(cam); + mxc_free_frame_buf(cam); + cam->enc_counter = 0; + cam->skip_frame = 0; + INIT_LIST_HEAD(&cam->ready_q); + INIT_LIST_HEAD(&cam->working_q); + INIT_LIST_HEAD(&cam->done_q); + + retval = mxc_allocate_frame_buf(cam, req->count); + break; + } + + /*! + * V4l2 VIDIOC_QUERYBUF ioctl + */ + case VIDIOC_QUERYBUF: { + struct v4l2_buffer *buf = arg; + int index = buf->index; + pr_debug(" case VIDIOC_QUERYBUF\n"); + + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + pr_err("ERROR: v4l2 capture: " + "VIDIOC_QUERYBUFS: " + "wrong buffer type\n"); + retval = -EINVAL; + break; + } + + memset(buf, 0, sizeof(buf)); + buf->index = index; + + down(&cam->param_lock); + retval = mxc_v4l2_buffer_status(cam, buf); + up(&cam->param_lock); + break; + } + + /*! + * V4l2 VIDIOC_QBUF ioctl + */ + case VIDIOC_QBUF: { + struct v4l2_buffer *buf = arg; + int index = buf->index; + pr_debug(" case VIDIOC_QBUF\n"); + + spin_lock_irqsave(&cam->int_lock, lock_flags); + cam->frame[index].buffer.m.offset = buf->m.offset; + if ((cam->frame[index].buffer.flags & 0x7) == + V4L2_BUF_FLAG_MAPPED) { + cam->frame[index].buffer.flags |= + V4L2_BUF_FLAG_QUEUED; + if (cam->skip_frame > 0) { + list_add_tail(&cam->frame[index].queue, + &cam->working_q); + retval = + cam->enc_update_eba(cam-> + frame[index]. + buffer.m.offset, + &cam-> + ping_pong_csi); + cam->skip_frame = 0; + } else { + list_add_tail(&cam->frame[index].queue, + &cam->ready_q); + } + } else if (cam->frame[index].buffer. + flags & V4L2_BUF_FLAG_QUEUED) { + pr_err("ERROR: v4l2 capture: VIDIOC_QBUF: " + "buffer already queued\n"); + } else if (cam->frame[index].buffer. + flags & V4L2_BUF_FLAG_DONE) { + pr_err("ERROR: v4l2 capture: VIDIOC_QBUF: " + "overwrite done buffer.\n"); + cam->frame[index].buffer.flags &= + ~V4L2_BUF_FLAG_DONE; + cam->frame[index].buffer.flags |= + V4L2_BUF_FLAG_QUEUED; + } + + buf->flags = cam->frame[index].buffer.flags; + spin_unlock_irqrestore(&cam->int_lock, lock_flags); + break; + } + + /*! + * V4l2 VIDIOC_DQBUF ioctl + */ + case VIDIOC_DQBUF: { + struct v4l2_buffer *buf = arg; + pr_debug(" case VIDIOC_DQBUF\n"); + + retval = mxc_v4l_dqueue(cam, buf); + + break; + } + + /*! + * V4l2 VIDIOC_STREAMON ioctl + */ + case VIDIOC_STREAMON: { + pr_debug(" case VIDIOC_STREAMON\n"); + retval = mxc_streamon(cam); + break; + } + + /*! + * V4l2 VIDIOC_STREAMOFF ioctl + */ + case VIDIOC_STREAMOFF: { + pr_debug(" case VIDIOC_STREAMOFF\n"); + retval = mxc_streamoff(cam); + break; + } + + /*! + * V4l2 VIDIOC_G_CTRL ioctl + */ + case VIDIOC_G_CTRL: { + pr_debug(" case VIDIOC_G_CTRL\n"); + retval = mxc_v4l2_g_ctrl(cam, arg); + break; + } + + /*! + * V4l2 VIDIOC_S_CTRL ioctl + */ + case VIDIOC_S_CTRL: { + pr_debug(" case VIDIOC_S_CTRL\n"); + retval = mxc_v4l2_s_ctrl(cam, arg); + break; + } + + /*! + * V4l2 VIDIOC_CROPCAP ioctl + */ + case VIDIOC_CROPCAP: { + struct v4l2_cropcap *cap = arg; + pr_debug(" case VIDIOC_CROPCAP\n"); + if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && + cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) { + retval = -EINVAL; + break; + } + cap->bounds = cam->crop_bounds; + cap->defrect = cam->crop_defrect; + break; + } + + /*! + * V4l2 VIDIOC_G_CROP ioctl + */ + case VIDIOC_G_CROP: { + struct v4l2_crop *crop = arg; + pr_debug(" case VIDIOC_G_CROP\n"); + + if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && + crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) { + retval = -EINVAL; + break; + } + crop->c = cam->crop_current; + break; + } + + /*! + * V4l2 VIDIOC_S_CROP ioctl + */ + case VIDIOC_S_CROP: { + struct v4l2_crop *crop = arg; + struct v4l2_rect *b = &cam->crop_bounds; + pr_debug(" case VIDIOC_S_CROP\n"); + + if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && + crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) { + retval = -EINVAL; + break; + } + + crop->c.top = (crop->c.top < b->top) ? b->top + : crop->c.top; + if (crop->c.top > b->top + b->height) + crop->c.top = b->top + b->height - 1; + if (crop->c.height > b->top + b->height - crop->c.top) + crop->c.height = + b->top + b->height - crop->c.top; + + crop->c.left = (crop->c.left < b->left) ? b->left + : crop->c.left; + if (crop->c.left > b->left + b->width) + crop->c.left = b->left + b->width - 1; + if (crop->c.width > b->left - crop->c.left + b->width) + crop->c.width = + b->left - crop->c.left + b->width; + + crop->c.width -= crop->c.width % 8; + crop->c.left -= crop->c.left % 4; + cam->crop_current = crop->c; + + pr_debug(" Cropping Input to ipu size %d x %d\n", + cam->crop_current.width, + cam->crop_current.height); + ipu_csi_set_window_size(cam->crop_current.width, + cam->crop_current.height, + cam->csi); + ipu_csi_set_window_pos(cam->crop_current.left, + cam->crop_current.top, + cam->csi); + break; + } + + /*! + * V4l2 VIDIOC_OVERLAY ioctl + */ + case VIDIOC_OVERLAY: { + int *on = arg; + pr_debug(" VIDIOC_OVERLAY on=%d\n", *on); + if (*on) { + cam->overlay_on = true; + cam->overlay_pid = current->pid; + retval = start_preview(cam); + } + if (!*on) { + retval = stop_preview(cam); + cam->overlay_on = false; + } + break; + } + + /*! + * V4l2 VIDIOC_G_FBUF ioctl + */ + case VIDIOC_G_FBUF: { + struct v4l2_framebuffer *fb = arg; + pr_debug(" case VIDIOC_G_FBUF\n"); + *fb = cam->v4l2_fb; + fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY; + break; + } + + /*! + * V4l2 VIDIOC_S_FBUF ioctl + */ + case VIDIOC_S_FBUF: { + struct v4l2_framebuffer *fb = arg; + pr_debug(" case VIDIOC_S_FBUF\n"); + cam->v4l2_fb = *fb; + break; + } + + case VIDIOC_G_PARM: { + struct v4l2_streamparm *parm = arg; + pr_debug(" case VIDIOC_G_PARM\n"); + vidioc_int_g_parm(cam->sensor, parm); + break; + } + + case VIDIOC_S_PARM: { + struct v4l2_streamparm *parm = arg; + pr_debug(" case VIDIOC_S_PARM\n"); + retval = mxc_v4l2_s_param(cam, parm); + break; + } + + /* linux v4l2 bug, kernel c0485619 user c0405619 */ + case VIDIOC_ENUMSTD: { + struct v4l2_standard *e = arg; + pr_debug(" case VIDIOC_ENUMSTD\n"); + *e = cam->standard; + break; + } + + case VIDIOC_G_STD: { + v4l2_std_id *e = arg; + pr_debug(" case VIDIOC_G_STD\n"); + retval = mxc_v4l2_g_std(cam, e); + break; + } + + case VIDIOC_S_STD: { + v4l2_std_id *e = arg; + pr_debug(" case VIDIOC_S_STD\n"); + retval = mxc_v4l2_s_std(cam, *e); + + break; + } + + case VIDIOC_ENUMOUTPUT: { + struct v4l2_output *output = arg; + pr_debug(" case VIDIOC_ENUMOUTPUT\n"); + if (output->index >= MXC_V4L2_CAPTURE_NUM_OUTPUTS) { + retval = -EINVAL; + break; + } + *output = mxc_capture_outputs[output->index]; + + break; + } + case VIDIOC_G_OUTPUT: { + int *p_output_num = arg; + pr_debug(" case VIDIOC_G_OUTPUT\n"); + *p_output_num = cam->output; + break; + } + + case VIDIOC_S_OUTPUT: { + int *p_output_num = arg; + pr_debug(" case VIDIOC_S_OUTPUT\n"); + if (*p_output_num >= MXC_V4L2_CAPTURE_NUM_OUTPUTS) { + retval = -EINVAL; + break; + } + cam->output = *p_output_num; + break; + } + + case VIDIOC_ENUM_FMT: + case VIDIOC_TRY_FMT: + case VIDIOC_QUERYCTRL: + case VIDIOC_ENUMINPUT: + case VIDIOC_G_INPUT: + case VIDIOC_S_INPUT: + case VIDIOC_G_TUNER: + case VIDIOC_S_TUNER: + case VIDIOC_G_FREQUENCY: + case VIDIOC_S_FREQUENCY: + default: + pr_debug(" case default or not supported\n"); + retval = -EINVAL; + break; + } + + up(&cam->busy_lock); + return retval; +} + +/* + * V4L interface - ioctl function + * + * @return None + */ +static int mxc_v4l_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + pr_debug("In MVC:mxc_v4l_ioctl\n"); + return video_usercopy(inode, file, cmd, arg, mxc_v4l_do_ioctl); +} + +/*! + * V4L interface - mmap function + * + * @param file structure file * + * + * @param vma structure vm_area_struct * + * + * @return status 0 Success, EINTR busy lock error, ENOBUFS remap_page error + */ +static int mxc_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct video_device *dev = video_devdata(file); + unsigned long size; + int res = 0; + cam_data *cam = video_get_drvdata(dev); + + pr_debug("In MVC:mxc_mmap\n"); + pr_debug(" pgoff=0x%lx, start=0x%lx, end=0x%lx\n", + vma->vm_pgoff, vma->vm_start, vma->vm_end); + + /* make this _really_ smp-safe */ + if (down_interruptible(&cam->busy_lock)) + return -EINTR; + + size = vma->vm_end - vma->vm_start; + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + if (remap_pfn_range(vma, vma->vm_start, + vma->vm_pgoff, size, vma->vm_page_prot)) { + pr_err("ERROR: v4l2 capture: mxc_mmap: " + "remap_pfn_range failed\n"); + res = -ENOBUFS; + goto mxc_mmap_exit; + } + + vma->vm_flags &= ~VM_IO; /* using shared anonymous pages */ + + mxc_mmap_exit: + up(&cam->busy_lock); + return res; +} + +/*! + * V4L interface - poll function + * + * @param file structure file * + * + * @param wait structure poll_table * + * + * @return status POLLIN | POLLRDNORM + */ +static unsigned int mxc_poll(struct file *file, poll_table *wait) +{ + struct video_device *dev = video_devdata(file); + cam_data *cam = video_get_drvdata(dev); + wait_queue_head_t *queue = NULL; + int res = POLLIN | POLLRDNORM; + + pr_debug("In MVC:mxc_poll\n"); + + if (down_interruptible(&cam->busy_lock)) + return -EINTR; + + queue = &cam->enc_queue; + poll_wait(file, queue, wait); + + up(&cam->busy_lock); + + return res; +} + +/*! + * This structure defines the functions to be called in this driver. + */ +static struct file_operations mxc_v4l_fops = { + .owner = THIS_MODULE, + .open = mxc_v4l_open, + .release = mxc_v4l_close, + .read = mxc_v4l_read, + .ioctl = mxc_v4l_ioctl, + .mmap = mxc_mmap, + .poll = mxc_poll, +}; + +static struct video_device mxc_v4l_template = { + .name = "Mxc Camera", + .vfl_type = VID_TYPE_CAPTURE, + .fops = &mxc_v4l_fops, + .release = video_device_release, +}; + +/*! + * This function can be used to release any platform data on closing. + */ +static void camera_platform_release(struct device *device) +{ +} + +/*! Device Definition for Mt9v111 devices */ +static struct platform_device mxc_v4l2_devices = { + .name = "mxc_v4l2", + .dev = { + .release = camera_platform_release, + }, + .id = 0, +}; + +/*! + * Camera V4l2 callback function. + * + * @param mask u32 + * + * @param dev void device structure + * + * @return status + */ +static void camera_callback(u32 mask, void *dev) +{ + struct mxc_v4l_frame *done_frame; + struct mxc_v4l_frame *ready_frame; + + cam_data *cam = (cam_data *) dev; + if (cam == NULL) + return; + + pr_debug("In MVC:camera_callback\n"); + + if (list_empty(&cam->working_q)) { + pr_err("ERROR: v4l2 capture: camera_callback: " + "working queue empty\n"); + return; + } + + done_frame = + list_entry(cam->working_q.next, struct mxc_v4l_frame, queue); + if (done_frame->buffer.flags & V4L2_BUF_FLAG_QUEUED) { + done_frame->buffer.flags |= V4L2_BUF_FLAG_DONE; + done_frame->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED; + + if (list_empty(&cam->ready_q)) { + cam->skip_frame++; + } else { + ready_frame = list_entry(cam->ready_q.next, + struct mxc_v4l_frame, + queue); + list_del(cam->ready_q.next); + list_add_tail(&ready_frame->queue, &cam->working_q); + cam->enc_update_eba(ready_frame->buffer.m.offset, + &cam->ping_pong_csi); + } + + /* Added to the done queue */ + list_del(cam->working_q.next); + list_add_tail(&done_frame->queue, &cam->done_q); + + /* Wake up the queue */ + cam->enc_counter++; + wake_up_interruptible(&cam->enc_queue); + } else { + pr_err("ERROR: v4l2 capture: camera_callback: " + "buffer not queued\n"); + } +} + +/*! + * initialize cam_data structure + * + * @param cam structure cam_data * + * + * @return status 0 Success + */ +static void init_camera_struct(cam_data *cam) +{ + pr_debug("In MVC: init_camera_struct\n"); + + /* Default everything to 0 */ + memset(cam, 0, sizeof(cam_data)); + + init_MUTEX(&cam->param_lock); + init_MUTEX(&cam->busy_lock); + + cam->video_dev = video_device_alloc(); + if (cam->video_dev == NULL) + return; + + *(cam->video_dev) = mxc_v4l_template; + + video_set_drvdata(cam->video_dev, cam); + dev_set_drvdata(&mxc_v4l2_devices.dev, (void *)cam); + cam->video_dev->minor = -1; + + init_waitqueue_head(&cam->enc_queue); + init_waitqueue_head(&cam->still_queue); + + /* setup cropping */ + cam->crop_bounds.left = 0; + cam->crop_bounds.width = 640; + cam->crop_bounds.top = 0; + cam->crop_bounds.height = 480; + cam->crop_current = cam->crop_defrect = cam->crop_bounds; + ipu_csi_set_window_size(cam->crop_current.width, + cam->crop_current.height, cam->csi); + ipu_csi_set_window_pos(cam->crop_current.left, + cam->crop_current.top, cam->csi); + cam->streamparm.parm.capture.capturemode = 0; + + cam->standard.index = 0; + cam->standard.id = V4L2_STD_UNKNOWN; + cam->standard.frameperiod.denominator = 30; + cam->standard.frameperiod.numerator = 1; + cam->standard.framelines = 480; + cam->standard_autodetect = true; + cam->streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + cam->streamparm.parm.capture.timeperframe = cam->standard.frameperiod; + cam->streamparm.parm.capture.capability = V4L2_CAP_TIMEPERFRAME; + cam->overlay_on = false; + cam->capture_on = false; + cam->skip_frame = 0; + cam->v4l2_fb.flags = V4L2_FBUF_FLAG_OVERLAY; + + cam->v2f.fmt.pix.sizeimage = 352 * 288 * 3 / 2; + cam->v2f.fmt.pix.bytesperline = 288 * 3 / 2; + cam->v2f.fmt.pix.width = 288; + cam->v2f.fmt.pix.height = 352; + cam->v2f.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420; + cam->win.w.width = 160; + cam->win.w.height = 160; + cam->win.w.left = 0; + cam->win.w.top = 0; + + cam->csi = 0; /* Need to determine how to set this correctly with + * multiple video input devices. */ + + cam->enc_callback = camera_callback; + init_waitqueue_head(&cam->power_queue); + spin_lock_init(&cam->int_lock); +} + +/*! + * camera_power function + * Turns Sensor power On/Off + * + * @param cam cam data struct + * @param cameraOn true to turn camera on, false to turn off power. + * + * @return status + */ +static u8 camera_power(cam_data *cam, bool cameraOn) +{ + pr_debug("In MVC:camera_power on=%d\n", cameraOn); + + if (cameraOn == true) { + ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, true, true); + vidioc_int_s_power(cam->sensor, 1); + } else { + ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, false, false); + vidioc_int_s_power(cam->sensor, 0); + } + return 0; +} + +/*! + * This function is called to put the sensor in a low power state. + * Refer to the document driver-model/driver.txt in the kernel source tree + * for more information. + * + * @param pdev the device structure used to give information on which I2C + * to suspend + * @param state the power state the device is entering + * + * @return The function returns 0 on success and -1 on failure. + */ +static int mxc_v4l2_suspend(struct platform_device *pdev, pm_message_t state) +{ + cam_data *cam = platform_get_drvdata(pdev); + + pr_debug("In MVC:mxc_v4l2_suspend\n"); + + if (cam == NULL) { + return -1; + } + + cam->low_power = true; + + if (cam->overlay_on == true) + stop_preview(cam); + if ((cam->capture_on == true) && cam->enc_disable) { + cam->enc_disable(cam); + } + camera_power(cam, false); + + return 0; +} + +/*! + * This function is called to bring the sensor back from a low power state. + * Refer to the document driver-model/driver.txt in the kernel source tree + * for more information. + * + * @param pdev the device structure + * + * @return The function returns 0 on success and -1 on failure + */ +static int mxc_v4l2_resume(struct platform_device *pdev) +{ + cam_data *cam = platform_get_drvdata(pdev); + + pr_debug("In MVC:mxc_v4l2_resume\n"); + + if (cam == NULL) { + return -1; + } + + cam->low_power = false; + wake_up_interruptible(&cam->power_queue); + + if (cam->overlay_on == true) + start_preview(cam); + if (cam->capture_on == true) + mxc_streamon(cam); + camera_power(cam, true); + + return 0; +} + +/*! + * This structure contains pointers to the power management callback functions. + */ +static struct platform_driver mxc_v4l2_driver = { + .driver = { + .name = "mxc_v4l2", + }, + .probe = NULL, + .remove = NULL, + .suspend = mxc_v4l2_suspend, + .resume = mxc_v4l2_resume, + .shutdown = NULL, +}; + +/*! + * Initializes the camera driver. + */ +static int mxc_v4l2_master_attach(struct v4l2_int_device *slave) +{ + cam_data *cam = slave->u.slave->master->priv; + struct v4l2_format cam_fmt; + + pr_debug("In MVC: mxc_v4l2_master_attach\n"); + pr_debug(" slave.name = %s\n", slave->name); + pr_debug(" master.name = %s\n", slave->u.slave->master->name); + + cam->sensor = slave; + if (slave == NULL) { + pr_err("ERROR: v4l2 capture: slave parameter not valid.\n"); + return -1; + } + + ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, true, true); + vidioc_int_dev_init(slave); + ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, false, false); + cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt); + + /* Used to detect TV in (type 1) vs. camera (type 0)*/ + cam->device_type = cam_fmt.fmt.pix.priv; + + /* Set the input size to the ipu for this device */ + cam->crop_bounds.top = cam->crop_bounds.left = 0; + cam->crop_bounds.width = cam_fmt.fmt.pix.width; + cam->crop_bounds.height = cam_fmt.fmt.pix.height; + + /* This also is the max crop size for this device. */ + cam->crop_defrect.top = cam->crop_defrect.left = 0; + cam->crop_defrect.width = cam_fmt.fmt.pix.width; + cam->crop_defrect.height = cam_fmt.fmt.pix.height; + + /* At this point, this is also the current image size. */ + cam->crop_current.top = cam->crop_current.left = 0; + cam->crop_current.width = cam_fmt.fmt.pix.width; + cam->crop_current.height = cam_fmt.fmt.pix.height; + + pr_debug("End of %s: v2f pix widthxheight %d x %d\n", + __func__, + cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height); + pr_debug("End of %s: crop_bounds widthxheight %d x %d\n", + __func__, + cam->crop_bounds.width, cam->crop_bounds.height); + pr_debug("End of %s: crop_defrect widthxheight %d x %d\n", + __func__, + cam->crop_defrect.width, cam->crop_defrect.height); + pr_debug("End of %s: crop_current widthxheight %d x %d\n", + __func__, + cam->crop_current.width, cam->crop_current.height); + + return 0; +} + +/*! + * Disconnects the camera driver. + */ +static void mxc_v4l2_master_detach(struct v4l2_int_device *slave) +{ + pr_debug("In MVC:mxc_v4l2_master_detach\n"); + /* vidioc_int_dev_exit(slave); */ +} + +/*! + * Entry point for the V4L2 + * + * @return Error code indicating success or failure + */ +static __init int camera_init(void) +{ + u8 err = 0; + + pr_debug("In MVC:camera_init\n"); + + /* Register the device driver structure. */ + err = platform_driver_register(&mxc_v4l2_driver); + if (err != 0) { + pr_err("ERROR: v4l2 capture:camera_init: " + "platform_driver_register failed.\n"); + return err; + } + + /* Create g_cam and initialize it. */ + if ((g_cam = kmalloc(sizeof(cam_data), GFP_KERNEL)) == NULL) { + pr_err("ERROR: v4l2 capture: failed to register camera\n"); + platform_driver_unregister(&mxc_v4l2_driver); + return -1; + } + init_camera_struct(g_cam); + + /* Set up the v4l2 device and register it*/ + mxc_v4l2_int_device.priv = g_cam; + /* This function contains a bug that won't let this be rmmod'd. */ + v4l2_int_device_register(&mxc_v4l2_int_device); + + /* Register the I2C device */ + err = platform_device_register(&mxc_v4l2_devices); + if (err != 0) { + pr_err("ERROR: v4l2 capture: camera_init: " + "platform_device_register failed.\n"); + platform_driver_unregister(&mxc_v4l2_driver); + kfree(g_cam); + g_cam = NULL; + return err; + } + + /* register v4l video device */ + if (video_register_device(g_cam->video_dev, VFL_TYPE_GRABBER, video_nr) + == -1) { + platform_device_unregister(&mxc_v4l2_devices); + platform_driver_unregister(&mxc_v4l2_driver); + kfree(g_cam); + g_cam = NULL; + pr_err("ERROR: v4l2 capture: video_register_device failed\n"); + return -1; + } + pr_debug(" Video device registered: %s #%d\n", + g_cam->video_dev->name, g_cam->video_dev->minor); + + return err; +} + +/*! + * Exit and cleanup for the V4L2 + */ +static void __exit camera_exit(void) +{ + pr_debug("In MVC: camera_exit\n"); + + pr_info("V4L2 unregistering video\n"); + + if (g_cam->open_count) { + pr_err("ERROR: v4l2 capture:camera open " + "-- setting ops to NULL\n"); + } else { + pr_info("V4L2 freeing image input device\n"); + v4l2_int_device_unregister(&mxc_v4l2_int_device); + video_unregister_device(g_cam->video_dev); + platform_driver_unregister(&mxc_v4l2_driver); + platform_device_unregister(&mxc_v4l2_devices); + + mxc_free_frame_buf(g_cam); + kfree(g_cam); + g_cam = NULL; + } +} + +module_init(camera_init); +module_exit(camera_exit); + +module_param(video_nr, int, 0444); +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("V4L2 capture driver for Mxc based cameras"); +MODULE_LICENSE("GPL"); +MODULE_SUPPORTED_DEVICE("video"); --- linux-2.6.28.orig/drivers/media/video/mxc/capture/mxc_v4l2_capture.h +++ linux-2.6.28/drivers/media/video/mxc/capture/mxc_v4l2_capture.h @@ -0,0 +1,195 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @defgroup MXC_V4L2_CAPTURE MXC V4L2 Video Capture Driver + */ +/*! + * @file mxc_v4l2_capture.h + * + * @brief mxc V4L2 capture device API Header file + * + * It include all the defines for frame operations, also three structure defines + * use case ops structure, common v4l2 driver structure and frame structure. + * + * @ingroup MXC_V4L2_CAPTURE + */ +#ifndef __MXC_V4L2_CAPTURE_H__ +#define __MXC_V4L2_CAPTURE_H__ + +#include +#include +#include +#include +#include + +#include + +#define FRAME_NUM 3 + +/*! + * v4l2 frame structure. + */ +struct mxc_v4l_frame { + u32 paddress; + void *vaddress; + int count; + int width; + int height; + + struct v4l2_buffer buffer; + struct list_head queue; + int index; +}; + +/* Only for old version. Will go away soon. */ +typedef struct { + u8 clk_mode; + u8 ext_vsync; + u8 Vsync_pol; + u8 Hsync_pol; + u8 pixclk_pol; + u8 data_pol; + u8 data_width; + u8 pack_tight; + u8 force_eof; + u8 data_en_pol; + u16 width; + u16 height; + u32 pixel_fmt; + u32 mclk; + u16 active_width; + u16 active_height; +} sensor_interface; + +/* Sensor control function */ +/* Only for old version. Will go away soon. */ +struct camera_sensor { + void (*set_color) (int bright, int saturation, int red, int green, + int blue); + void (*get_color) (int *bright, int *saturation, int *red, int *green, + int *blue); + void (*set_ae_mode) (int ae_mode); + void (*get_ae_mode) (int *ae_mode); + sensor_interface *(*config) (int *frame_rate, int high_quality); + sensor_interface *(*reset) (void); + void (*get_std) (v4l2_std_id *std); + void (*set_std) (v4l2_std_id std); + unsigned int csi; +}; + +/*! + * common v4l2 driver structure. + */ +typedef struct _cam_data { + struct video_device *video_dev; + int device_type; + + /* semaphore guard against SMP multithreading */ + struct semaphore busy_lock; + + int open_count; + + /* params lock for this camera */ + struct semaphore param_lock; + + /* Encoder */ + struct list_head ready_q; + struct list_head done_q; + struct list_head working_q; + int ping_pong_csi; + spinlock_t int_lock; + struct mxc_v4l_frame frame[FRAME_NUM]; + int skip_frame; + wait_queue_head_t enc_queue; + int enc_counter; + dma_addr_t rot_enc_bufs[2]; + void *rot_enc_bufs_vaddr[2]; + int rot_enc_buf_size[2]; + enum v4l2_buf_type type; + + /* still image capture */ + wait_queue_head_t still_queue; + int still_counter; + dma_addr_t still_buf; + void *still_buf_vaddr; + + /* overlay */ + struct v4l2_window win; + struct v4l2_framebuffer v4l2_fb; + dma_addr_t vf_bufs[2]; + void *vf_bufs_vaddr[2]; + int vf_bufs_size[2]; + dma_addr_t rot_vf_bufs[2]; + void *rot_vf_bufs_vaddr[2]; + int rot_vf_buf_size[2]; + bool overlay_active; + int output; + struct fb_info *overlay_fb; + + /* v4l2 format */ + struct v4l2_format v2f; + int rotation; + struct v4l2_mxc_offset offset; + + /* V4l2 control bit */ + int bright; + int hue; + int contrast; + int saturation; + int red; + int green; + int blue; + int ae_mode; + + /* standard */ + struct v4l2_streamparm streamparm; + struct v4l2_standard standard; + bool standard_autodetect; + + /* crop */ + struct v4l2_rect crop_bounds; + struct v4l2_rect crop_defrect; + struct v4l2_rect crop_current; + + int (*enc_update_eba) (dma_addr_t eba, int *bufferNum); + int (*enc_enable) (void *private); + int (*enc_disable) (void *private); + void (*enc_callback) (u32 mask, void *dev); + int (*vf_start_adc) (void *private); + int (*vf_stop_adc) (void *private); + int (*vf_start_sdc) (void *private); + int (*vf_stop_sdc) (void *private); + int (*csi_start) (void *private); + int (*csi_stop) (void *private); + + /* misc status flag */ + bool overlay_on; + bool capture_on; + int overlay_pid; + int capture_pid; + bool low_power; + wait_queue_head_t power_queue; + unsigned int csi; + + /* camera sensor interface */ + struct camera_sensor *cam_sensor; /* old version */ + struct v4l2_int_device *sensor; +} cam_data; + +#if defined(CONFIG_MXC_IPU_V1) || defined(CONFIG_VIDEO_MXC_EMMA_CAMERA) +void set_mclk_rate(uint32_t *p_mclk_freq); +#else +void set_mclk_rate(uint32_t *p_mclk_freq, uint32_t csi); +#endif +#endif /* __MXC_V4L2_CAPTURE_H__ */ --- linux-2.6.28.orig/drivers/media/video/mxc/capture/ipu_prp_vf_sdc.c +++ linux-2.6.28/drivers/media/video/mxc/capture/ipu_prp_vf_sdc.c @@ -0,0 +1,472 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @file ipu_prp_vf_sdc.c + * + * @brief IPU Use case for PRP-VF + * + * @ingroup IPU + */ + +#include +#include +#include "mxc_v4l2_capture.h" +#include "ipu_prp_sw.h" + +/* + * Function definitions + */ + +/*! + * prpvf_start - start the vf task + * + * @param private cam_data * mxc v4l2 main structure + * + */ +static int prpvf_start(void *private) +{ + cam_data *cam = (cam_data *) private; + ipu_channel_params_t vf, params; + u32 format = IPU_PIX_FMT_RGB565; + u32 size = 2; + int err = 0; + + if (!cam) { + printk(KERN_ERR "private is NULL\n"); + return -EIO; + } + + if (cam->overlay_active == true) { + pr_debug("already started.\n"); + return 0; + } + + memset(&vf, 0, sizeof(ipu_channel_params_t)); + ipu_csi_get_window_size(&vf.csi_prp_vf_mem.in_width, + &vf.csi_prp_vf_mem.in_height, cam->csi); + vf.csi_prp_vf_mem.in_pixel_fmt = IPU_PIX_FMT_UYVY; + vf.csi_prp_vf_mem.out_width = cam->win.w.width; + vf.csi_prp_vf_mem.out_height = cam->win.w.height; + vf.csi_prp_vf_mem.csi = cam->csi; + if (cam->rotation >= IPU_ROTATE_90_RIGHT) { + vf.csi_prp_vf_mem.out_width = cam->win.w.height; + vf.csi_prp_vf_mem.out_height = cam->win.w.width; + } + vf.csi_prp_vf_mem.out_pixel_fmt = format; + size = cam->win.w.width * cam->win.w.height * size; + + err = ipu_init_channel(CSI_PRP_VF_MEM, &vf); + if (err != 0) + goto out_4; + + ipu_csi_enable_mclk_if(CSI_MCLK_VF, cam->csi, true, true); + + if (cam->vf_bufs_vaddr[0]) { + dma_free_coherent(0, cam->vf_bufs_size[0], + cam->vf_bufs_vaddr[0], + (dma_addr_t) cam->vf_bufs[0]); + } + if (cam->vf_bufs_vaddr[1]) { + dma_free_coherent(0, cam->vf_bufs_size[1], + cam->vf_bufs_vaddr[1], + (dma_addr_t) cam->vf_bufs[1]); + } + cam->vf_bufs_size[0] = PAGE_ALIGN(size); + cam->vf_bufs_vaddr[0] = (void *)dma_alloc_coherent(0, + cam->vf_bufs_size[0], + (dma_addr_t *) & + cam->vf_bufs[0], + GFP_DMA | + GFP_KERNEL); + if (cam->vf_bufs_vaddr[0] == NULL) { + printk(KERN_ERR "Error to allocate vf buffer\n"); + err = -ENOMEM; + goto out_3; + } + cam->vf_bufs_size[1] = PAGE_ALIGN(size); + cam->vf_bufs_vaddr[1] = (void *)dma_alloc_coherent(0, + cam->vf_bufs_size[1], + (dma_addr_t *) & + cam->vf_bufs[1], + GFP_DMA | + GFP_KERNEL); + if (cam->vf_bufs_vaddr[1] == NULL) { + printk(KERN_ERR "Error to allocate vf buffer\n"); + err = -ENOMEM; + goto out_3; + } + pr_debug("vf_bufs %x %x\n", cam->vf_bufs[0], cam->vf_bufs[1]); + + if (cam->rotation >= IPU_ROTATE_90_RIGHT) { + err = ipu_init_channel_buffer(CSI_PRP_VF_MEM, IPU_OUTPUT_BUFFER, + format, + vf.csi_prp_vf_mem.out_width, + vf.csi_prp_vf_mem.out_height, + vf.csi_prp_vf_mem.out_width, + IPU_ROTATE_NONE, cam->vf_bufs[0], + cam->vf_bufs[1], 0, 0); + if (err != 0) { + goto out_3; + } + + if (cam->rot_vf_bufs[0]) { + dma_free_coherent(0, cam->rot_vf_buf_size[0], + cam->rot_vf_bufs_vaddr[0], + (dma_addr_t) cam->rot_vf_bufs[0]); + cam->rot_vf_bufs_vaddr[0] = NULL; + cam->rot_vf_bufs[0] = 0; + } + if (cam->rot_vf_bufs[1]) { + dma_free_coherent(0, cam->rot_vf_buf_size[1], + cam->rot_vf_bufs_vaddr[1], + (dma_addr_t) cam->rot_vf_bufs[1]); + cam->rot_vf_bufs_vaddr[1] = NULL; + cam->rot_vf_bufs[1] = 0; + } + cam->rot_vf_buf_size[0] = PAGE_ALIGN(size); + cam->rot_vf_bufs_vaddr[0] = (void *)dma_alloc_coherent(0, + cam-> + rot_vf_buf_size + [0], + &cam-> + rot_vf_bufs + [0], + GFP_DMA | + GFP_KERNEL); + if (cam->rot_vf_bufs_vaddr[0] == NULL) { + printk(KERN_ERR "alloc rot_vf_bufs.\n"); + err = -ENOMEM; + goto out_3; + } + cam->rot_vf_buf_size[1] = PAGE_ALIGN(size); + cam->rot_vf_bufs_vaddr[1] = (void *)dma_alloc_coherent(0, + cam-> + rot_vf_buf_size + [0], + &cam-> + rot_vf_bufs + [1], + GFP_DMA | + GFP_KERNEL); + if (cam->rot_vf_bufs_vaddr[1] == NULL) { + printk(KERN_ERR "alloc rot_vf_bufs.\n"); + err = -ENOMEM; + goto out_3; + } + pr_debug("rot_vf_bufs %x %x\n", cam->rot_vf_bufs[0], + cam->rot_vf_bufs[1]); + + err = ipu_init_channel(MEM_ROT_VF_MEM, NULL); + if (err != 0) { + printk(KERN_ERR "Error MEM_ROT_VF_MEM channel\n"); + goto out_3; + } + + err = ipu_init_channel_buffer(MEM_ROT_VF_MEM, IPU_INPUT_BUFFER, + format, + vf.csi_prp_vf_mem.out_width, + vf.csi_prp_vf_mem.out_height, + vf.csi_prp_vf_mem.out_width, + cam->rotation, cam->vf_bufs[0], + cam->vf_bufs[1], 0, 0); + if (err != 0) { + printk(KERN_ERR "Error MEM_ROT_VF_MEM input buffer\n"); + goto out_3; + } + + err = ipu_init_channel_buffer(MEM_ROT_VF_MEM, IPU_OUTPUT_BUFFER, + format, + vf.csi_prp_vf_mem.out_height, + vf.csi_prp_vf_mem.out_width, + vf.csi_prp_vf_mem.out_height, + IPU_ROTATE_NONE, + cam->rot_vf_bufs[0], + cam->rot_vf_bufs[1], 0, 0); + if (err != 0) { + printk(KERN_ERR "Error MEM_ROT_VF_MEM output buffer\n"); + goto out_2; + } + + err = ipu_link_channels(CSI_PRP_VF_MEM, MEM_ROT_VF_MEM); + if (err < 0) { + printk(KERN_ERR + "Error link CSI_PRP_VF_MEM-MEM_ROT_VF_MEM\n"); + goto out_2; + } + + memset(¶ms, 0, sizeof(ipu_channel_params_t)); + params.mem_dp_fg_sync.in_pixel_fmt = format; + params.mem_dp_fg_sync.out_pixel_fmt = IPU_PIX_FMT_RGB24; + err = ipu_init_channel(MEM_FG_SYNC, ¶ms); + if (err != 0) + goto out_2; + + ipu_disp_set_window_pos(MEM_FG_SYNC, cam->win.w.left, + cam->win.w.top); + + err = ipu_init_channel_buffer(MEM_FG_SYNC, IPU_INPUT_BUFFER, + format, + vf.csi_prp_vf_mem.out_height, + vf.csi_prp_vf_mem.out_width, + vf.csi_prp_vf_mem.out_height, + IPU_ROTATE_NONE, + cam->rot_vf_bufs[0], + cam->rot_vf_bufs[1], 0, 0); + if (err != 0) { + printk(KERN_ERR "Error initializing SDC FG buffer\n"); + goto out_2; + } + + err = ipu_link_channels(MEM_ROT_VF_MEM, MEM_FG_SYNC); + if (err < 0) { + printk(KERN_ERR + "Error link MEM_ROT_VF_MEM-MEM_FG_SYNC\n"); + goto out_1; + } + + ipu_enable_channel(CSI_PRP_VF_MEM); + ipu_enable_channel(MEM_ROT_VF_MEM); + ipu_enable_channel(MEM_FG_SYNC); + + ipu_select_buffer(CSI_PRP_VF_MEM, IPU_OUTPUT_BUFFER, 0); + ipu_select_buffer(CSI_PRP_VF_MEM, IPU_OUTPUT_BUFFER, 1); + ipu_select_buffer(MEM_ROT_VF_MEM, IPU_OUTPUT_BUFFER, 0); + ipu_select_buffer(MEM_ROT_VF_MEM, IPU_OUTPUT_BUFFER, 1); + } else { + err = ipu_init_channel_buffer(CSI_PRP_VF_MEM, IPU_OUTPUT_BUFFER, + format, cam->win.w.width, + cam->win.w.height, + cam->win.w.width, cam->rotation, + cam->vf_bufs[0], cam->vf_bufs[1], + 0, 0); + if (err != 0) { + printk(KERN_ERR "Error initializing CSI_PRP_VF_MEM\n"); + goto out_4; + } + memset(¶ms, 0, sizeof(ipu_channel_params_t)); + params.mem_dp_fg_sync.in_pixel_fmt = format; + params.mem_dp_fg_sync.out_pixel_fmt = IPU_PIX_FMT_RGB24; + err = ipu_init_channel(MEM_FG_SYNC, ¶ms); + if (err != 0) + goto out_3; + + ipu_disp_set_window_pos(MEM_FG_SYNC, cam->win.w.left, + cam->win.w.top); + err = ipu_init_channel_buffer(MEM_FG_SYNC, + IPU_INPUT_BUFFER, format, + cam->win.w.width, + cam->win.w.height, + cam->win.w.width, IPU_ROTATE_NONE, + cam->vf_bufs[0], cam->vf_bufs[1], + 0, 0); + if (err != 0) { + printk(KERN_ERR "Error initializing SDC FG buffer\n"); + goto out_1; + } + + err = ipu_link_channels(CSI_PRP_VF_MEM, MEM_FG_SYNC); + if (err < 0) { + printk(KERN_ERR "Error linking ipu channels\n"); + goto out_1; + } + + ipu_enable_channel(CSI_PRP_VF_MEM); + ipu_enable_channel(MEM_FG_SYNC); + + ipu_select_buffer(CSI_PRP_VF_MEM, IPU_OUTPUT_BUFFER, 0); + ipu_select_buffer(CSI_PRP_VF_MEM, IPU_OUTPUT_BUFFER, 1); + } + + cam->overlay_active = true; + return err; + + out_1: + ipu_uninit_channel(MEM_FG_SYNC); + out_2: + if (cam->rotation >= IPU_ROTATE_90_RIGHT) { + ipu_uninit_channel(MEM_ROT_VF_MEM); + } + out_3: + ipu_uninit_channel(CSI_PRP_VF_MEM); + out_4: + if (cam->vf_bufs_vaddr[0]) { + dma_free_coherent(0, cam->vf_bufs_size[0], + cam->vf_bufs_vaddr[0], + (dma_addr_t) cam->vf_bufs[0]); + cam->vf_bufs_vaddr[0] = NULL; + cam->vf_bufs[0] = 0; + } + if (cam->vf_bufs_vaddr[1]) { + dma_free_coherent(0, cam->vf_bufs_size[1], + cam->vf_bufs_vaddr[1], + (dma_addr_t) cam->vf_bufs[1]); + cam->vf_bufs_vaddr[1] = NULL; + cam->vf_bufs[1] = 0; + } + if (cam->rot_vf_bufs_vaddr[0]) { + dma_free_coherent(0, cam->rot_vf_buf_size[0], + cam->rot_vf_bufs_vaddr[0], + (dma_addr_t) cam->rot_vf_bufs[0]); + cam->rot_vf_bufs_vaddr[0] = NULL; + cam->rot_vf_bufs[0] = 0; + } + if (cam->rot_vf_bufs_vaddr[1]) { + dma_free_coherent(0, cam->rot_vf_buf_size[1], + cam->rot_vf_bufs_vaddr[1], + (dma_addr_t) cam->rot_vf_bufs[1]); + cam->rot_vf_bufs_vaddr[1] = NULL; + cam->rot_vf_bufs[1] = 0; + } + return err; +} + +/*! + * prpvf_stop - stop the vf task + * + * @param private cam_data * mxc v4l2 main structure + * + */ +static int prpvf_stop(void *private) +{ + cam_data *cam = (cam_data *) private; + int err = 0; + + if (cam->overlay_active == false) + return 0; + + ipu_disp_set_window_pos(MEM_FG_SYNC, 0, 0); + + if (cam->rotation >= IPU_ROTATE_90_RIGHT) { + ipu_unlink_channels(CSI_PRP_VF_MEM, MEM_ROT_VF_MEM); + ipu_unlink_channels(MEM_ROT_VF_MEM, MEM_FG_SYNC); + } else { + ipu_unlink_channels(CSI_PRP_VF_MEM, MEM_FG_SYNC); + } + + ipu_disable_channel(MEM_FG_SYNC, true); + ipu_disable_channel(CSI_PRP_VF_MEM, true); + + if (cam->rotation >= IPU_ROTATE_90_RIGHT) { + ipu_disable_channel(MEM_ROT_VF_MEM, true); + ipu_uninit_channel(MEM_ROT_VF_MEM); + } + ipu_uninit_channel(MEM_FG_SYNC); + ipu_uninit_channel(CSI_PRP_VF_MEM); + + ipu_csi_enable_mclk_if(CSI_MCLK_VF, cam->csi, false, false); + + if (cam->vf_bufs_vaddr[0]) { + dma_free_coherent(0, cam->vf_bufs_size[0], + cam->vf_bufs_vaddr[0], + (dma_addr_t) cam->vf_bufs[0]); + cam->vf_bufs_vaddr[0] = NULL; + cam->vf_bufs[0] = 0; + } + if (cam->vf_bufs_vaddr[1]) { + dma_free_coherent(0, cam->vf_bufs_size[1], + cam->vf_bufs_vaddr[1], + (dma_addr_t) cam->vf_bufs[1]); + cam->vf_bufs_vaddr[1] = NULL; + cam->vf_bufs[1] = 0; + } + if (cam->rot_vf_bufs_vaddr[0]) { + dma_free_coherent(0, cam->rot_vf_buf_size[0], + cam->rot_vf_bufs_vaddr[0], + (dma_addr_t) cam->rot_vf_bufs[0]); + cam->rot_vf_bufs_vaddr[0] = NULL; + cam->rot_vf_bufs[0] = 0; + } + if (cam->rot_vf_bufs_vaddr[1]) { + dma_free_coherent(0, cam->rot_vf_buf_size[1], + cam->rot_vf_bufs_vaddr[1], + (dma_addr_t) cam->rot_vf_bufs[1]); + cam->rot_vf_bufs_vaddr[1] = NULL; + cam->rot_vf_bufs[1] = 0; + } + + cam->overlay_active = false; + return err; +} + +/*! + * function to select PRP-VF as the working path + * + * @param private cam_data * mxc v4l2 main structure + * + * @return status + */ +int prp_vf_sdc_select(void *private) +{ + cam_data *cam; + int err = 0; + if (private) { + cam = (cam_data *) private; + cam->vf_start_sdc = prpvf_start; + cam->vf_stop_sdc = prpvf_stop; + cam->overlay_active = false; + } else + err = -EIO; + + return err; +} + +/*! + * function to de-select PRP-VF as the working path + * + * @param private cam_data * mxc v4l2 main structure + * + * @return int + */ +int prp_vf_sdc_deselect(void *private) +{ + cam_data *cam; + int err = 0; + err = prpvf_stop(private); + + if (private) { + cam = (cam_data *) private; + cam->vf_start_sdc = NULL; + cam->vf_stop_sdc = NULL; + } + return err; +} + +/*! + * Init viewfinder task. + * + * @return Error code indicating success or failure + */ +__init int prp_vf_sdc_init(void) +{ + return 0; +} + +/*! + * Deinit viewfinder task. + * + * @return Error code indicating success or failure + */ +void __exit prp_vf_sdc_exit(void) +{ +} + +module_init(prp_vf_sdc_init); +module_exit(prp_vf_sdc_exit); + +EXPORT_SYMBOL(prp_vf_sdc_select); +EXPORT_SYMBOL(prp_vf_sdc_deselect); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("IPU PRP VF SDC Driver"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/media/video/mxc/output/mxc_v4l2_output.c +++ linux-2.6.28/drivers/media/video/mxc/output/mxc_v4l2_output.c @@ -0,0 +1,1881 @@ +/* + * Copyright 2005-2009 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 + */ + +/*! + * @file drivers/media/video/mxc/output/mxc_v4l2_output.c + * + * @brief MXC V4L2 Video Output Driver + * + * Video4Linux2 Output Device using MXC IPU Post-processing functionality. + * + * @ingroup MXC_V4L2_OUTPUT + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mxc_v4l2_output.h" + +vout_data *g_vout; +#define SDC_FG_FB_FORMAT IPU_PIX_FMT_RGB565 + +struct v4l2_output mxc_outputs[2] = { + { + .index = MXC_V4L2_OUT_2_SDC, + .name = "DISP3 Video Out", + .type = V4L2_OUTPUT_TYPE_ANALOG, /* not really correct, + but no other choice */ + .audioset = 0, + .modulator = 0, + .std = V4L2_STD_UNKNOWN}, + { + .index = MXC_V4L2_OUT_2_ADC, + .name = "DISPx Video Out", + .type = V4L2_OUTPUT_TYPE_ANALOG, /* not really correct, + but no other choice */ + .audioset = 0, + .modulator = 0, + .std = V4L2_STD_UNKNOWN} +}; + +static int video_nr = 16; +static spinlock_t g_lock = SPIN_LOCK_UNLOCKED; + +/* debug counters */ +uint32_t g_irq_cnt; +uint32_t g_buf_output_cnt; +uint32_t g_buf_q_cnt; +uint32_t g_buf_dq_cnt; + +#define QUEUE_SIZE (MAX_FRAME_NUM + 1) +static __inline int queue_size(v4l_queue * q) +{ + if (q->tail >= q->head) + return (q->tail - q->head); + else + return ((q->tail + QUEUE_SIZE) - q->head); +} + +static __inline int queue_buf(v4l_queue * q, int idx) +{ + if (((q->tail + 1) % QUEUE_SIZE) == q->head) + return -1; /* queue full */ + q->list[q->tail] = idx; + q->tail = (q->tail + 1) % QUEUE_SIZE; + return 0; +} + +static __inline int dequeue_buf(v4l_queue * q) +{ + int ret; + if (q->tail == q->head) + return -1; /* queue empty */ + ret = q->list[q->head]; + q->head = (q->head + 1) % QUEUE_SIZE; + return ret; +} + +static __inline int peek_next_buf(v4l_queue * q) +{ + if (q->tail == q->head) + return -1; /* queue empty */ + return q->list[q->head]; +} + +static __inline unsigned long get_jiffies(struct timeval *t) +{ + struct timeval cur; + + if (t->tv_usec >= 1000000) { + t->tv_sec += t->tv_usec / 1000000; + t->tv_usec = t->tv_usec % 1000000; + } + + do_gettimeofday(&cur); + if ((t->tv_sec < cur.tv_sec) + || ((t->tv_sec == cur.tv_sec) && (t->tv_usec < cur.tv_usec))) + return jiffies; + + if (t->tv_usec < cur.tv_usec) { + cur.tv_sec = t->tv_sec - cur.tv_sec - 1; + cur.tv_usec = t->tv_usec + 1000000 - cur.tv_usec; + } else { + cur.tv_sec = t->tv_sec - cur.tv_sec; + cur.tv_usec = t->tv_usec - cur.tv_usec; + } + + return jiffies + timeval_to_jiffies(&cur); +} + +/*! + * Private function to free buffers + * + * @param bufs_paddr Array of physical address of buffers to be freed + * + * @param bufs_vaddr Array of virtual address of buffers to be freed + * + * @param num_buf Number of buffers to be freed + * + * @param size Size for each buffer to be free + * + * @return status 0 success. + */ +static int mxc_free_buffers(dma_addr_t bufs_paddr[], void *bufs_vaddr[], + int num_buf, int size) +{ + int i; + + for (i = 0; i < num_buf; i++) { + if (bufs_vaddr[i] != 0) { + dma_free_coherent(0, size, bufs_vaddr[i], + bufs_paddr[i]); + pr_debug("freed @ paddr=0x%08X\n", (u32) bufs_paddr[i]); + bufs_paddr[i] = 0; + bufs_vaddr[i] = NULL; + } + } + return 0; +} + +/*! + * Private function to allocate buffers + * + * @param bufs_paddr Output array of physical address of buffers allocated + * + * @param bufs_vaddr Output array of virtual address of buffers allocated + * + * @param num_buf Input number of buffers to allocate + * + * @param size Input size for each buffer to allocate + * + * @return status -0 Successfully allocated a buffer, -ENOBUFS failed. + */ +static int mxc_allocate_buffers(dma_addr_t bufs_paddr[], void *bufs_vaddr[], + int num_buf, int size) +{ + int i; + + for (i = 0; i < num_buf; i++) { + bufs_vaddr[i] = dma_alloc_coherent(0, size, + &bufs_paddr[i], + GFP_DMA | GFP_KERNEL); + + if (bufs_vaddr[i] == 0) { + mxc_free_buffers(bufs_paddr, bufs_vaddr, i, size); + printk(KERN_ERR "dma_alloc_coherent failed.\n"); + return -ENOBUFS; + } + pr_debug("allocated @ paddr=0x%08X, size=%d.\n", + (u32) bufs_paddr[i], size); + } + + return 0; +} + +/* + * Returns bits per pixel for given pixel format + * + * @param pixelformat V4L2_PIX_FMT_RGB565, V4L2_PIX_FMT_BGR24 or V4L2_PIX_FMT_BGR32 + * + * @return bits per pixel of pixelformat + */ +static u32 fmt_to_bpp(u32 pixelformat) +{ + u32 bpp; + + switch (pixelformat) { + case V4L2_PIX_FMT_RGB565: + bpp = 16; + break; + case V4L2_PIX_FMT_BGR24: + case V4L2_PIX_FMT_RGB24: + bpp = 24; + break; + case V4L2_PIX_FMT_BGR32: + case V4L2_PIX_FMT_RGB32: + bpp = 32; + break; + default: + bpp = 8; + break; + } + return bpp; +} + +static bool format_is_yuv(u32 pixelformat) +{ + u32 bpp; + + switch (pixelformat) { + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YUV422P: + case V4L2_PIX_FMT_YVU420: + case V4L2_PIX_FMT_NV12: + return true; + break; + } + return false; +} + +static u32 bpp_to_fmt(struct fb_info *fbi) +{ + if (fbi->var.nonstd) + return fbi->var.nonstd; + + if (fbi->var.bits_per_pixel == 24) + return V4L2_PIX_FMT_BGR24; + else if (fbi->var.bits_per_pixel == 32) + return V4L2_PIX_FMT_BGR32; + else if (fbi->var.bits_per_pixel == 16) + return V4L2_PIX_FMT_RGB565; + + return 0; +} + +static irqreturn_t mxc_v4l2out_disp_refresh_irq_handler(int irq, void *dev_id) +{ + struct completion *comp = dev_id; + + complete(comp); + return IRQ_HANDLED; +} + +static void timer_work_func(struct work_struct *work) +{ + int index, ret, disp_irq = 0; + unsigned long timeout; + unsigned long lock_flags = 0; + vout_data *vout = + container_of(work, vout_data, timer_work); + DECLARE_COMPLETION_ONSTACK(disp_comp); + + switch (vout->display_ch) { + case MEM_FG_SYNC: + case MEM_BG_SYNC: + disp_irq = IPU_IRQ_BG_SF_END; + break; + case MEM_DC_SYNC: + disp_irq = IPU_IRQ_DC_FC_1; + break; + default: + dev_err(&vout->video_dev->dev, + "not support display channel\n"); + } + + ipu_clear_irq(disp_irq); + ret = ipu_request_irq(disp_irq, mxc_v4l2out_disp_refresh_irq_handler, 0, NULL, &disp_comp); + if (ret < 0) { + dev_err(&vout->video_dev->dev, + "Disp irq %d in use\n", disp_irq); + return; + } + wait_for_completion_timeout(&disp_comp, msecs_to_jiffies(40)); + ipu_free_irq(disp_irq, &disp_comp); + + spin_lock_irqsave(&g_lock, lock_flags); + + if (ipu_select_buffer(vout->post_proc_ch, IPU_INPUT_BUFFER, + vout->next_rdy_ipu_buf) < 0) { + dev_err(&vout->video_dev->dev, + "unable to set IPU buffer ready\n"); + } + vout->next_rdy_ipu_buf = !vout->next_rdy_ipu_buf; + + /* Setup timer for next buffer */ + index = peek_next_buf(&vout->ready_q); + if (index != -1) { + /* if timestamp is 0, then default to 30fps */ + if ((vout->v4l2_bufs[index].timestamp.tv_sec == 0) + && (vout->v4l2_bufs[index].timestamp.tv_usec == 0)) + timeout = + vout->start_jiffies + vout->frame_count * HZ / 30; + else + timeout = + get_jiffies(&vout->v4l2_bufs[index].timestamp); + + if (jiffies >= timeout) { + dev_dbg(&vout->video_dev->dev, + "warning: timer timeout already expired.\n"); + } + if (mod_timer(&vout->output_timer, timeout)) + dev_dbg(&vout->video_dev->dev, + "warning: timer was already set\n"); + + dev_dbg(&vout->video_dev->dev, + "timer handler next schedule: %lu\n", timeout); + } else { + vout->state = STATE_STREAM_PAUSED; + } + + spin_unlock_irqrestore(&g_lock, lock_flags); +} + +static void mxc_v4l2out_timer_handler(unsigned long arg) +{ + int index; + unsigned long lock_flags = 0; + vout_data *vout = (vout_data *) arg; + + dev_dbg(&vout->video_dev->dev, "timer handler: %lu\n", jiffies); + + spin_lock_irqsave(&g_lock, lock_flags); + + if ((vout->state == STATE_STREAM_STOPPING) + || (vout->state == STATE_STREAM_OFF)) + goto exit0; + /* + * If timer occurs before IPU h/w is ready, then set the state to + * paused and the timer will be set again when next buffer is queued + * or PP comletes + */ + if (vout->ipu_buf[vout->next_rdy_ipu_buf] != -1) { + dev_dbg(&vout->video_dev->dev, "IPU buffer busy\n"); + vout->state = STATE_STREAM_PAUSED; + goto exit0; + } + + /* Dequeue buffer and pass to IPU */ + index = dequeue_buf(&vout->ready_q); + if (index == -1) { /* no buffers ready, should never occur */ + dev_err(&vout->video_dev->dev, + "mxc_v4l2out: timer - no queued buffers ready\n"); + goto exit0; + } + + g_buf_dq_cnt++; + vout->frame_count++; + vout->ipu_buf[vout->next_rdy_ipu_buf] = index; + if (ipu_update_channel_buffer(vout->post_proc_ch, IPU_INPUT_BUFFER, + vout->next_rdy_ipu_buf, + vout->v4l2_bufs[index].m.offset) < 0) { + dev_err(&vout->video_dev->dev, + "unable to update buffer %d address\n", + vout->next_rdy_ipu_buf); + goto exit0; + } + + spin_unlock_irqrestore(&g_lock, lock_flags); + schedule_work(&vout->timer_work); + return; + + exit0: + spin_unlock_irqrestore(&g_lock, lock_flags); +} + +static irqreturn_t mxc_v4l2out_pp_in_irq_handler(int irq, void *dev_id) +{ + int last_buf; + int index; + unsigned long timeout; + unsigned long lock_flags = 0; + vout_data *vout = dev_id; + + spin_lock_irqsave(&g_lock, lock_flags); + + g_irq_cnt++; + + /* Process previous buffer */ + last_buf = vout->ipu_buf[vout->next_done_ipu_buf]; + if (last_buf != -1) { + g_buf_output_cnt++; + vout->v4l2_bufs[last_buf].flags = V4L2_BUF_FLAG_DONE; + queue_buf(&vout->done_q, last_buf); + vout->ipu_buf[vout->next_done_ipu_buf] = -1; + wake_up_interruptible(&vout->v4l_bufq); + /* printk("pp_irq: buf %d done\n", vout->next_done_ipu_buf); */ + vout->next_done_ipu_buf = !vout->next_done_ipu_buf; + } + + if (vout->state == STATE_STREAM_STOPPING) { + if ((vout->ipu_buf[0] == -1) && (vout->ipu_buf[1] == -1)) { + vout->state = STATE_STREAM_OFF; + } + } else if ((vout->state == STATE_STREAM_PAUSED) + && ((index = peek_next_buf(&vout->ready_q)) != -1)) { + /* Setup timer for next buffer, when stream has been paused */ + pr_debug("next index %d\n", index); + + /* if timestamp is 0, then default to 30fps */ + if ((vout->v4l2_bufs[index].timestamp.tv_sec == 0) + && (vout->v4l2_bufs[index].timestamp.tv_usec == 0)) + timeout = + vout->start_jiffies + vout->frame_count * HZ / 30; + else + timeout = + get_jiffies(&vout->v4l2_bufs[index].timestamp); + + if (jiffies >= timeout) { + pr_debug("warning: timer timeout already expired.\n"); + } + + vout->state = STATE_STREAM_ON; + + if (mod_timer(&vout->output_timer, timeout)) + pr_debug("warning: timer was already set\n"); + + pr_debug("timer handler next schedule: %lu\n", timeout); + } + + spin_unlock_irqrestore(&g_lock, lock_flags); + + return IRQ_HANDLED; +} + +/*! + * Start the output stream + * + * @param vout structure vout_data * + * + * @return status 0 Success + */ +static int mxc_v4l2out_streamon(vout_data * vout) +{ + struct device *dev = &vout->video_dev->dev; + ipu_channel_params_t params; + struct mxcfb_pos fb_pos; + struct fb_var_screeninfo fbvar; + struct fb_info *fbi = + registered_fb[vout->output_fb_num[vout->cur_disp_output]]; + int pp_in_buf[2]; + u16 out_width; + u16 out_height; + ipu_channel_t display_input_ch = MEM_PP_MEM; + bool use_direct_adc = false; + mm_segment_t old_fs; + + if (!vout) + return -EINVAL; + + if (vout->state != STATE_STREAM_OFF) + return -EBUSY; + + if (queue_size(&vout->ready_q) < 2) { + dev_err(dev, "2 buffers not been queued yet!\n"); + return -EINVAL; + } + + out_width = vout->crop_current.width; + out_height = vout->crop_current.height; + + vout->next_done_ipu_buf = vout->next_rdy_ipu_buf = 0; + vout->ipu_buf[0] = pp_in_buf[0] = dequeue_buf(&vout->ready_q); + vout->ipu_buf[1] = pp_in_buf[1] = dequeue_buf(&vout->ready_q); + vout->frame_count = 2; + + ipu_enable_irq(IPU_IRQ_PP_IN_EOF); + + /* Init Display Channel */ +#ifdef CONFIG_FB_MXC_ASYNC_PANEL + if (vout->cur_disp_output < DISP3) { + mxcfb_set_refresh_mode(fbi, MXCFB_REFRESH_OFF, 0); + fbi = NULL; + if (ipu_can_rotate_in_place(vout->rotate)) { + dev_dbg(dev, "Using PP direct to ADC channel\n"); + use_direct_adc = true; + vout->display_ch = MEM_PP_ADC; + vout->post_proc_ch = MEM_PP_ADC; + + memset(¶ms, 0, sizeof(params)); + params.mem_pp_adc.in_width = vout->v2f.fmt.pix.width; + params.mem_pp_adc.in_height = vout->v2f.fmt.pix.height; + params.mem_pp_adc.in_pixel_fmt = + vout->v2f.fmt.pix.pixelformat; + params.mem_pp_adc.out_width = out_width; + params.mem_pp_adc.out_height = out_height; + params.mem_pp_adc.out_pixel_fmt = SDC_FG_FB_FORMAT; +#ifdef CONFIG_FB_MXC_EPSON_PANEL + params.mem_pp_adc.out_left = + 2 + vout->crop_current.left; +#else + params.mem_pp_adc.out_left = + 12 + vout->crop_current.left; +#endif + params.mem_pp_adc.out_top = vout->crop_current.top; + if (ipu_init_channel(vout->post_proc_ch, ¶ms) != 0) { + dev_err(dev, "Error initializing PP chan\n"); + return -EINVAL; + } + + if (ipu_init_channel_buffer(vout->post_proc_ch, + IPU_INPUT_BUFFER, + params.mem_pp_adc. + in_pixel_fmt, + params.mem_pp_adc.in_width, + params.mem_pp_adc.in_height, + vout->v2f.fmt.pix. + bytesperline / + bytes_per_pixel(params. + mem_pp_adc. + in_pixel_fmt), + vout->rotate, + vout-> + v4l2_bufs[pp_in_buf[0]].m. + offset, + vout-> + v4l2_bufs[pp_in_buf[1]].m. + offset, + vout->offset.u_offset, + vout->offset.v_offset) != + 0) { + dev_err(dev, "Error initializing PP in buf\n"); + return -EINVAL; + } + + if (ipu_init_channel_buffer(vout->post_proc_ch, + IPU_OUTPUT_BUFFER, + params.mem_pp_adc. + out_pixel_fmt, out_width, + out_height, out_width, + vout->rotate, 0, 0, 0, + 0) != 0) { + dev_err(dev, + "Error initializing PP output buffer\n"); + return -EINVAL; + } + + } else { + dev_dbg(dev, "Using ADC SYS2 channel\n"); + vout->display_ch = ADC_SYS2; + vout->post_proc_ch = MEM_PP_MEM; + + if (vout->display_bufs[0]) { + mxc_free_buffers(vout->display_bufs, + vout->display_bufs_vaddr, + 2, vout->display_buf_size); + } + + vout->display_buf_size = vout->crop_current.width * + vout->crop_current.height * + fmt_to_bpp(SDC_FG_FB_FORMAT) / 8; + mxc_allocate_buffers(vout->display_bufs, + vout->display_bufs_vaddr, + 2, vout->display_buf_size); + + memset(¶ms, 0, sizeof(params)); + params.adc_sys2.disp = vout->cur_disp_output; + params.adc_sys2.ch_mode = WriteTemplateNonSeq; +#ifdef CONFIG_FB_MXC_EPSON_PANEL + params.adc_sys2.out_left = 2 + vout->crop_current.left; +#else + params.adc_sys2.out_left = 12 + vout->crop_current.left; +#endif + params.adc_sys2.out_top = vout->crop_current.top; + if (ipu_init_channel(ADC_SYS2, ¶ms) < 0) + return -EINVAL; + + if (ipu_init_channel_buffer(vout->display_ch, + IPU_INPUT_BUFFER, + SDC_FG_FB_FORMAT, + out_width, out_height, + out_width, IPU_ROTATE_NONE, + vout->display_bufs[0], + vout->display_bufs[1], 0, + 0) != 0) { + dev_err(dev, + "Error initializing SDC FG buffer\n"); + return -EINVAL; + } + } + } else +#endif + { /* Use SDC */ + dev_dbg(dev, "Using SDC channel\n"); + + fbvar = fbi->var; + + if (vout->cur_disp_output == 3) { + vout->display_ch = MEM_FG_SYNC; + fbvar.bits_per_pixel = 16; + if (format_is_yuv(vout->v2f.fmt.pix.pixelformat)) + fbvar.nonstd = IPU_PIX_FMT_UYVY; + else + fbvar.nonstd = 0; + + fbvar.xres = fbvar.xres_virtual = out_width; + fbvar.yres = out_height; + fbvar.yres_virtual = out_height * 2; + } else if (vout->cur_disp_output == 5) { + vout->display_ch = MEM_DC_SYNC; + fbvar.bits_per_pixel = 16; + fbvar.nonstd = IPU_PIX_FMT_UYVY; + + fbvar.xres = fbvar.xres_virtual = out_width; + fbvar.yres = out_height; + fbvar.yres_virtual = out_height * 2; + } else { + vout->display_ch = MEM_BG_SYNC; + } + + fbvar.activate |= FB_ACTIVATE_FORCE; + fb_set_var(fbi, &fbvar); + + fb_pos.x = vout->crop_current.left; + fb_pos.y = vout->crop_current.top; + if (fbi->fbops->fb_ioctl) { + old_fs = get_fs(); + set_fs(KERNEL_DS); + fbi->fbops->fb_ioctl(fbi, MXCFB_SET_OVERLAY_POS, + (unsigned long)&fb_pos); + set_fs(old_fs); + } + + vout->display_bufs[1] = fbi->fix.smem_start; + vout->display_bufs[0] = fbi->fix.smem_start + + (fbi->fix.line_length * fbi->var.yres); + vout->display_buf_size = vout->crop_current.width * + vout->crop_current.height * fbi->var.bits_per_pixel / 8; + + vout->post_proc_ch = MEM_PP_MEM; + } + + /* Init PP */ + if (use_direct_adc == false) { + if (vout->rotate >= IPU_ROTATE_90_RIGHT) { + out_width = vout->crop_current.height; + out_height = vout->crop_current.width; + } + memset(¶ms, 0, sizeof(params)); + params.mem_pp_mem.in_width = vout->v2f.fmt.pix.width; + params.mem_pp_mem.in_height = vout->v2f.fmt.pix.height; + params.mem_pp_mem.in_pixel_fmt = vout->v2f.fmt.pix.pixelformat; + params.mem_pp_mem.out_width = out_width; + params.mem_pp_mem.out_height = out_height; + if (vout->display_ch == ADC_SYS2) + params.mem_pp_mem.out_pixel_fmt = SDC_FG_FB_FORMAT; + else + params.mem_pp_mem.out_pixel_fmt = bpp_to_fmt(fbi); + if (ipu_init_channel(vout->post_proc_ch, ¶ms) != 0) { + dev_err(dev, "Error initializing PP channel\n"); + return -EINVAL; + } + + if (ipu_init_channel_buffer(vout->post_proc_ch, + IPU_INPUT_BUFFER, + params.mem_pp_mem.in_pixel_fmt, + params.mem_pp_mem.in_width, + params.mem_pp_mem.in_height, + vout->v2f.fmt.pix.bytesperline / + bytes_per_pixel(params.mem_pp_mem. + in_pixel_fmt), + IPU_ROTATE_NONE, + vout->v4l2_bufs[pp_in_buf[0]].m. + offset, + vout->v4l2_bufs[pp_in_buf[1]].m. + offset, vout->offset.u_offset, + vout->offset.v_offset) != 0) { + dev_err(dev, "Error initializing PP input buffer\n"); + return -EINVAL; + } + + if (!ipu_can_rotate_in_place(vout->rotate)) { + if (vout->rot_pp_bufs[0]) { + mxc_free_buffers(vout->rot_pp_bufs, + vout->rot_pp_bufs_vaddr, 2, + vout->display_buf_size); + } + if (mxc_allocate_buffers + (vout->rot_pp_bufs, vout->rot_pp_bufs_vaddr, 2, + vout->display_buf_size) < 0) { + return -ENOBUFS; + } + + if (ipu_init_channel_buffer(vout->post_proc_ch, + IPU_OUTPUT_BUFFER, + params.mem_pp_mem. + out_pixel_fmt, out_width, + out_height, out_width, + IPU_ROTATE_NONE, + vout->rot_pp_bufs[0], + vout->rot_pp_bufs[1], 0, + 0) != 0) { + dev_err(dev, + "Error initializing PP output buffer\n"); + return -EINVAL; + } + + if (ipu_init_channel(MEM_ROT_PP_MEM, NULL) != 0) { + dev_err(dev, + "Error initializing PP ROT channel\n"); + return -EINVAL; + } + + if (ipu_init_channel_buffer(MEM_ROT_PP_MEM, + IPU_INPUT_BUFFER, + params.mem_pp_mem. + out_pixel_fmt, out_width, + out_height, out_width, + vout->rotate, + vout->rot_pp_bufs[0], + vout->rot_pp_bufs[1], 0, + 0) != 0) { + dev_err(dev, + "Error initializing PP ROT input buffer\n"); + return -EINVAL; + } + + /* swap width and height */ + if (vout->rotate >= IPU_ROTATE_90_RIGHT) { + out_width = vout->crop_current.width; + out_height = vout->crop_current.height; + } + + if (ipu_init_channel_buffer(MEM_ROT_PP_MEM, + IPU_OUTPUT_BUFFER, + params.mem_pp_mem. + out_pixel_fmt, out_width, + out_height, out_width, + IPU_ROTATE_NONE, + vout->display_bufs[0], + vout->display_bufs[1], 0, + 0) != 0) { + dev_err(dev, + "Error initializing PP output buffer\n"); + return -EINVAL; + } + + if (ipu_link_channels(vout->post_proc_ch, + MEM_ROT_PP_MEM) < 0) { + return -EINVAL; + } + ipu_select_buffer(MEM_ROT_PP_MEM, IPU_OUTPUT_BUFFER, 0); + ipu_select_buffer(MEM_ROT_PP_MEM, IPU_OUTPUT_BUFFER, 1); + + ipu_enable_channel(MEM_ROT_PP_MEM); + + display_input_ch = MEM_ROT_PP_MEM; + } else { + if (ipu_init_channel_buffer(vout->post_proc_ch, + IPU_OUTPUT_BUFFER, + params.mem_pp_mem. + out_pixel_fmt, out_width, + out_height, out_width, + vout->rotate, + vout->display_bufs[0], + vout->display_bufs[1], 0, + 0) != 0) { + dev_err(dev, + "Error initializing PP output buffer\n"); + return -EINVAL; + } + } + if (ipu_link_channels(display_input_ch, vout->display_ch) < 0) { + dev_err(dev, "Error linking ipu channels\n"); + return -EINVAL; + } + } + + vout->state = STATE_STREAM_PAUSED; + + ipu_select_buffer(vout->post_proc_ch, IPU_INPUT_BUFFER, 0); + ipu_select_buffer(vout->post_proc_ch, IPU_INPUT_BUFFER, 1); + + if (use_direct_adc == false) { + ipu_select_buffer(vout->post_proc_ch, IPU_OUTPUT_BUFFER, 0); + ipu_select_buffer(vout->post_proc_ch, IPU_OUTPUT_BUFFER, 1); + + ipu_enable_channel(vout->post_proc_ch); + + if (fbi) { + acquire_console_sem(); + fb_blank(fbi, FB_BLANK_UNBLANK); + release_console_sem(); + } else { + ipu_enable_channel(vout->display_ch); + } + } else { + ipu_enable_channel(vout->post_proc_ch); + } + + vout->start_jiffies = jiffies; + dev_dbg(dev, + "streamon: start time = %lu jiffies\n", vout->start_jiffies); + + return 0; +} + +/*! + * Shut down the voutera + * + * @param vout structure vout_data * + * + * @return status 0 Success + */ +static int mxc_v4l2out_streamoff(vout_data * vout) +{ + struct fb_info *fbi = + registered_fb[vout->output_fb_num[vout->cur_disp_output]]; + int i, retval = 0; + unsigned long lockflag = 0; + + if (!vout) + return -EINVAL; + + if (vout->state == STATE_STREAM_OFF) { + return 0; + } + + cancel_work_sync(&vout->timer_work); + + spin_lock_irqsave(&g_lock, lockflag); + + del_timer(&vout->output_timer); + + if (vout->state == STATE_STREAM_ON) { + vout->state = STATE_STREAM_STOPPING; + } + + ipu_disable_irq(IPU_IRQ_PP_IN_EOF); + + spin_unlock_irqrestore(&g_lock, lockflag); + + if (vout->display_ch == MEM_FG_SYNC) { + struct mxcfb_pos fb_pos; + mm_segment_t old_fs; + + fb_pos.x = 0; + fb_pos.y = 0; + if (fbi->fbops->fb_ioctl) { + old_fs = get_fs(); + set_fs(KERNEL_DS); + fbi->fbops->fb_ioctl(fbi, MXCFB_SET_OVERLAY_POS, + (unsigned long)&fb_pos); + set_fs(old_fs); + } + } + + if (vout->post_proc_ch == MEM_PP_MEM) { /* SDC or ADC with Rotation */ + if (!ipu_can_rotate_in_place(vout->rotate)) { + ipu_unlink_channels(MEM_PP_MEM, MEM_ROT_PP_MEM); + ipu_unlink_channels(MEM_ROT_PP_MEM, vout->display_ch); + ipu_disable_channel(MEM_ROT_PP_MEM, true); + + if (vout->rot_pp_bufs[0]) { + mxc_free_buffers(vout->rot_pp_bufs, + vout->rot_pp_bufs_vaddr, 2, + vout->display_buf_size); + } + } else { + ipu_unlink_channels(MEM_PP_MEM, vout->display_ch); + } + ipu_disable_channel(MEM_PP_MEM, true); + + if (vout->display_ch == ADC_SYS2) { + ipu_disable_channel(vout->display_ch, true); + ipu_uninit_channel(vout->display_ch); + } else { + fbi->var.activate |= FB_ACTIVATE_FORCE; + fb_set_var(fbi, &fbi->var); + + if (vout->display_ch == MEM_FG_SYNC) { + acquire_console_sem(); + fb_blank(fbi, FB_BLANK_POWERDOWN); + release_console_sem(); + } + + vout->display_bufs[0] = 0; + vout->display_bufs[1] = 0; + } + + ipu_uninit_channel(MEM_PP_MEM); + if (!ipu_can_rotate_in_place(vout->rotate)) + ipu_uninit_channel(MEM_ROT_PP_MEM); + } else { /* ADC Direct */ + ipu_disable_channel(MEM_PP_ADC, true); + ipu_uninit_channel(MEM_PP_ADC); + } + vout->ready_q.head = vout->ready_q.tail = 0; + vout->done_q.head = vout->done_q.tail = 0; + for (i = 0; i < vout->buffer_cnt; i++) { + vout->v4l2_bufs[i].flags = 0; + vout->v4l2_bufs[i].timestamp.tv_sec = 0; + vout->v4l2_bufs[i].timestamp.tv_usec = 0; + } + + vout->state = STATE_STREAM_OFF; + +#ifdef CONFIG_FB_MXC_ASYNC_PANEL + if (vout->cur_disp_output < DISP3) { + if (vout->display_bufs[0] != 0) { + mxc_free_buffers(vout->display_bufs, + vout->display_bufs_vaddr, 2, + vout->display_buf_size); + } + + mxcfb_set_refresh_mode(registered_fb + [vout-> + output_fb_num[vout->cur_disp_output]], + MXCFB_REFRESH_PARTIAL, 0); + } +#endif + + return retval; +} + +/* + * Valid whether the palette is supported + * + * @param palette V4L2_PIX_FMT_RGB565, V4L2_PIX_FMT_BGR24 or V4L2_PIX_FMT_BGR32 + * + * @return 1 if supported, 0 if failed + */ +static inline int valid_mode(u32 palette) +{ + return ((palette == V4L2_PIX_FMT_RGB565) || + (palette == V4L2_PIX_FMT_BGR24) || + (palette == V4L2_PIX_FMT_RGB24) || + (palette == V4L2_PIX_FMT_BGR32) || + (palette == V4L2_PIX_FMT_RGB32) || + (palette == V4L2_PIX_FMT_NV12) || + (palette == V4L2_PIX_FMT_YUV422P) || + (palette == V4L2_PIX_FMT_YUV420)); +} + +/* + * V4L2 - Handles VIDIOC_G_FMT Ioctl + * + * @param vout structure vout_data * + * + * @param v4l2_format structure v4l2_format * + * + * @return status 0 success, EINVAL failed + */ +static int mxc_v4l2out_g_fmt(vout_data * vout, struct v4l2_format *f) +{ + if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) { + return -EINVAL; + } + *f = vout->v2f; + return 0; +} + +/* + * V4L2 - Handles VIDIOC_S_FMT Ioctl + * + * @param vout structure vout_data * + * + * @param v4l2_format structure v4l2_format * + * + * @return status 0 success, EINVAL failed + */ +static int mxc_v4l2out_s_fmt(vout_data * vout, struct v4l2_format *f) +{ + int retval = 0; + u32 size = 0; + u32 bytesperline; + + if (f->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) { + retval = -EINVAL; + goto err0; + } + if (!valid_mode(f->fmt.pix.pixelformat)) { + dev_err(&vout->video_dev->dev, "pixel format not supported\n"); + retval = -EINVAL; + goto err0; + } + + bytesperline = (f->fmt.pix.width * fmt_to_bpp(f->fmt.pix.pixelformat)) / + 8; + if (f->fmt.pix.bytesperline < bytesperline) { + f->fmt.pix.bytesperline = bytesperline; + } else { + bytesperline = f->fmt.pix.bytesperline; + } + + switch (f->fmt.pix.pixelformat) { + case V4L2_PIX_FMT_YUV422P: + /* byteperline for YUV planar formats is for + Y plane only */ + size = bytesperline * f->fmt.pix.height * 2; + break; + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_NV12: + size = (bytesperline * f->fmt.pix.height * 3) / 2; + break; + default: + size = bytesperline * f->fmt.pix.height; + break; + } + + /* Return the actual size of the image to the app */ + if (f->fmt.pix.sizeimage < size) { + f->fmt.pix.sizeimage = size; + } else { + size = f->fmt.pix.sizeimage; + } + + vout->v2f.fmt.pix = f->fmt.pix; + if (vout->v2f.fmt.pix.priv != 0) { + if (copy_from_user(&vout->offset, + (void *)vout->v2f.fmt.pix.priv, + sizeof(vout->offset))) { + retval = -EFAULT; + goto err0; + } + } else { + vout->offset.u_offset = 0; + vout->offset.v_offset = 0; + } + + retval = 0; + err0: + return retval; +} + +/* + * V4L2 - Handles VIDIOC_G_CTRL Ioctl + * + * @param vout structure vout_data * + * + * @param c structure v4l2_control * + * + * @return status 0 success, EINVAL failed + */ +static int mxc_get_v42lout_control(vout_data * vout, struct v4l2_control *c) +{ + switch (c->id) { + case V4L2_CID_HFLIP: + return (vout->rotate & IPU_ROTATE_HORIZ_FLIP) ? 1 : 0; + case V4L2_CID_VFLIP: + return (vout->rotate & IPU_ROTATE_VERT_FLIP) ? 1 : 0; + case (V4L2_CID_PRIVATE_BASE + 1): + return vout->rotate; + default: + return -EINVAL; + } +} + +/* + * V4L2 - Handles VIDIOC_S_CTRL Ioctl + * + * @param vout structure vout_data * + * + * @param c structure v4l2_control * + * + * @return status 0 success, EINVAL failed + */ +static int mxc_set_v42lout_control(vout_data * vout, struct v4l2_control *c) +{ + switch (c->id) { + case V4L2_CID_HFLIP: + vout->rotate |= c->value ? IPU_ROTATE_HORIZ_FLIP : + IPU_ROTATE_NONE; + break; + case V4L2_CID_VFLIP: + vout->rotate |= c->value ? IPU_ROTATE_VERT_FLIP : + IPU_ROTATE_NONE; + break; + case V4L2_CID_MXC_ROT: + vout->rotate = c->value; + break; + default: + return -EINVAL; + } + return 0; +} + +/*! + * V4L2 interface - open function + * + * @param inode structure inode * + * + * @param file structure file * + * + * @return status 0 success, ENODEV invalid device instance, + * ENODEV timeout, ERESTARTSYS interrupted by user + */ +static int mxc_v4l2out_open(struct inode *inode, struct file *file) +{ + struct video_device *dev = video_devdata(file); + vout_data *vout = video_get_drvdata(dev); + int err; + + if (!vout) { + return -ENODEV; + } + + down(&vout->busy_lock); + + err = -EINTR; + if (signal_pending(current)) + goto oops; + + if (vout->open_count++ == 0) { + ipu_request_irq(IPU_IRQ_PP_IN_EOF, + mxc_v4l2out_pp_in_irq_handler, + 0, dev->name, vout); + + init_waitqueue_head(&vout->v4l_bufq); + + init_timer(&vout->output_timer); + vout->output_timer.function = mxc_v4l2out_timer_handler; + vout->output_timer.data = (unsigned long)vout; + + vout->state = STATE_STREAM_OFF; + vout->rotate = IPU_ROTATE_NONE; + g_irq_cnt = g_buf_output_cnt = g_buf_q_cnt = g_buf_dq_cnt = 0; + + INIT_WORK(&vout->timer_work, timer_work_func); + + } + + file->private_data = dev; + + up(&vout->busy_lock); + + return 0; + + oops: + up(&vout->busy_lock); + return err; +} + +/*! + * V4L2 interface - close function + * + * @param inode struct inode * + * + * @param file struct file * + * + * @return 0 success + */ +static int mxc_v4l2out_close(struct inode *inode, struct file *file) +{ + struct video_device *dev = video_devdata(file); + vout_data *vout = video_get_drvdata(dev); + + if (--vout->open_count == 0) { + if (vout->state != STATE_STREAM_OFF) + mxc_v4l2out_streamoff(vout); + + ipu_free_irq(IPU_IRQ_PP_IN_EOF, vout); + + file->private_data = NULL; + + mxc_free_buffers(vout->queue_buf_paddr, vout->queue_buf_vaddr, + vout->buffer_cnt, vout->queue_buf_size); + vout->buffer_cnt = 0; + mxc_free_buffers(vout->rot_pp_bufs, vout->rot_pp_bufs_vaddr, 2, + vout->display_buf_size); + + /* capture off */ + wake_up_interruptible(&vout->v4l_bufq); + + schedule_work(&vout->timer_work); + flush_scheduled_work(); + } + + return 0; +} + +/*! + * V4L2 interface - ioctl function + * + * @param inode struct inode * + * + * @param file struct file * + * + * @param ioctlnr unsigned int + * + * @param arg void * + * + * @return 0 success, ENODEV for invalid device instance, + * -1 for other errors. + */ +static int +mxc_v4l2out_do_ioctl(struct inode *inode, struct file *file, + unsigned int ioctlnr, void *arg) +{ + struct video_device *vdev = file->private_data; + vout_data *vout = video_get_drvdata(vdev); + int retval = 0; + int i = 0; + + if (!vout) + return -EBADF; + + /* make this _really_ smp-safe */ + if (down_interruptible(&vout->busy_lock)) + return -EBUSY; + + switch (ioctlnr) { + case VIDIOC_QUERYCAP: + { + struct v4l2_capability *cap = arg; + strcpy(cap->driver, "mxc_v4l2_output"); + cap->version = 0; + cap->capabilities = + V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; + cap->card[0] = '\0'; + cap->bus_info[0] = '\0'; + retval = 0; + break; + } + case VIDIOC_G_FMT: + { + struct v4l2_format *gf = arg; + retval = mxc_v4l2out_g_fmt(vout, gf); + break; + } + case VIDIOC_S_FMT: + { + struct v4l2_format *sf = arg; + if (vout->state != STATE_STREAM_OFF) { + retval = -EBUSY; + break; + } + retval = mxc_v4l2out_s_fmt(vout, sf); + break; + } + case VIDIOC_REQBUFS: + { + struct v4l2_requestbuffers *req = arg; + if ((req->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) || + (req->memory != V4L2_MEMORY_MMAP)) { + dev_dbg(&vdev->dev, + "VIDIOC_REQBUFS: incorrect buffer type\n"); + retval = -EINVAL; + break; + } + + if (req->count == 0) + mxc_v4l2out_streamoff(vout); + + if (vout->state == STATE_STREAM_OFF) { + if (vout->queue_buf_paddr[0] != 0) { + mxc_free_buffers(vout->queue_buf_paddr, + vout->queue_buf_vaddr, + vout->buffer_cnt, + vout->queue_buf_size); + dev_dbg(&vdev->dev, + "VIDIOC_REQBUFS: freed buffers\n"); + } + vout->buffer_cnt = 0; + } else { + dev_dbg(&vdev->dev, + "VIDIOC_REQBUFS: Buffer is in use\n"); + retval = -EBUSY; + break; + } + + if (req->count == 0) + break; + + if (req->count < MIN_FRAME_NUM) { + req->count = MIN_FRAME_NUM; + } else if (req->count > MAX_FRAME_NUM) { + req->count = MAX_FRAME_NUM; + } + vout->buffer_cnt = req->count; + vout->queue_buf_size = + PAGE_ALIGN(vout->v2f.fmt.pix.sizeimage); + + retval = mxc_allocate_buffers(vout->queue_buf_paddr, + vout->queue_buf_vaddr, + vout->buffer_cnt, + vout->queue_buf_size); + if (retval < 0) + break; + + /* Init buffer queues */ + vout->done_q.head = 0; + vout->done_q.tail = 0; + vout->ready_q.head = 0; + vout->ready_q.tail = 0; + + for (i = 0; i < vout->buffer_cnt; i++) { + memset(&(vout->v4l2_bufs[i]), 0, + sizeof(vout->v4l2_bufs[i])); + vout->v4l2_bufs[i].flags = 0; + vout->v4l2_bufs[i].memory = V4L2_MEMORY_MMAP; + vout->v4l2_bufs[i].index = i; + vout->v4l2_bufs[i].type = + V4L2_BUF_TYPE_VIDEO_OUTPUT; + vout->v4l2_bufs[i].length = + PAGE_ALIGN(vout->v2f.fmt.pix.sizeimage); + vout->v4l2_bufs[i].m.offset = + (unsigned long)vout->queue_buf_paddr[i]; + vout->v4l2_bufs[i].timestamp.tv_sec = 0; + vout->v4l2_bufs[i].timestamp.tv_usec = 0; + } + break; + } + case VIDIOC_QUERYBUF: + { + struct v4l2_buffer *buf = arg; + u32 type = buf->type; + int index = buf->index; + + if ((type != V4L2_BUF_TYPE_VIDEO_OUTPUT) || + (index >= vout->buffer_cnt)) { + dev_dbg(&vdev->dev, + "VIDIOC_QUERYBUFS: incorrect buffer type\n"); + retval = -EINVAL; + break; + } + down(&vout->param_lock); + memcpy(buf, &(vout->v4l2_bufs[index]), sizeof(*buf)); + up(&vout->param_lock); + break; + } + case VIDIOC_QBUF: + { + struct v4l2_buffer *buf = arg; + int index = buf->index; + unsigned long lock_flags; + int param[5][3]; + + if ((buf->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) || + (index >= vout->buffer_cnt)) { + retval = -EINVAL; + break; + } + + dev_dbg(&vdev->dev, "VIDIOC_QBUF: %d\n", buf->index); + + /* mmapped buffers are L1 WB cached, + * so we need to clean them */ + if (buf->memory & V4L2_MEMORY_MMAP) { + flush_cache_all(); + } + + spin_lock_irqsave(&g_lock, lock_flags); + + memcpy(&(vout->v4l2_bufs[index]), buf, sizeof(*buf)); + vout->v4l2_bufs[index].flags |= V4L2_BUF_FLAG_QUEUED; + + g_buf_q_cnt++; + if (vout->v4l2_bufs[index].reserved) + if (!copy_from_user(¶m[0][0], + (void *)vout-> + v4l2_bufs[index] + .reserved, sizeof(param))) + ipu_set_csc_coefficients(vout-> + display_ch, + param); + queue_buf(&vout->ready_q, index); + if (vout->state == STATE_STREAM_PAUSED) { + unsigned long timeout; + + index = peek_next_buf(&vout->ready_q); + + /* if timestamp is 0, then default to 30fps */ + if ((vout->v4l2_bufs[index].timestamp.tv_sec == + 0) + && (vout->v4l2_bufs[index].timestamp. + tv_usec == 0)) + timeout = + vout->start_jiffies + + vout->frame_count * HZ / 30; + else + timeout = + get_jiffies(&vout->v4l2_bufs[index]. + timestamp); + + if (jiffies >= timeout) { + dev_dbg(&vout->video_dev->dev, + "warning: timer timeout already expired.\n"); + } + vout->output_timer.expires = timeout; + dev_dbg(&vdev->dev, + "QBUF: frame #%u timeout @ %lu jiffies, current = %lu\n", + vout->frame_count, timeout, jiffies); + add_timer(&vout->output_timer); + vout->state = STATE_STREAM_ON; + } + + spin_unlock_irqrestore(&g_lock, lock_flags); + break; + } + case VIDIOC_DQBUF: + { + struct v4l2_buffer *buf = arg; + int idx; + + if ((queue_size(&vout->done_q) == 0) && + (file->f_flags & O_NONBLOCK)) { + retval = -EAGAIN; + break; + } + + if (!wait_event_interruptible_timeout(vout->v4l_bufq, + queue_size(&vout-> + done_q) + != 0, 10 * HZ)) { + dev_dbg(&vdev->dev, "VIDIOC_DQBUF: timeout\n"); + retval = -ETIME; + break; + } else if (signal_pending(current)) { + dev_dbg(&vdev->dev, + "VIDIOC_DQBUF: interrupt received\n"); + retval = -ERESTARTSYS; + break; + } + idx = dequeue_buf(&vout->done_q); + if (idx == -1) { /* No frame free */ + dev_dbg(&vdev->dev, + "VIDIOC_DQBUF: no free buffers, returning\n"); + retval = -EAGAIN; + break; + } + if ((vout->v4l2_bufs[idx].flags & V4L2_BUF_FLAG_DONE) == + 0) + dev_dbg(&vdev->dev, + "VIDIOC_DQBUF: buffer in done q, but not " + "flagged as done\n"); + + vout->v4l2_bufs[idx].flags = 0; + memcpy(buf, &(vout->v4l2_bufs[idx]), sizeof(*buf)); + dev_dbg(&vdev->dev, "VIDIOC_DQBUF: %d\n", buf->index); + break; + } + case VIDIOC_STREAMON: + { + retval = mxc_v4l2out_streamon(vout); + break; + } + case VIDIOC_STREAMOFF: + { + retval = mxc_v4l2out_streamoff(vout); + break; + } + case VIDIOC_G_CTRL: + { + retval = mxc_get_v42lout_control(vout, arg); + break; + } + case VIDIOC_S_CTRL: + { + retval = mxc_set_v42lout_control(vout, arg); + break; + } + case VIDIOC_CROPCAP: + { + struct v4l2_cropcap *cap = arg; + + if (cap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) { + retval = -EINVAL; + break; + } + + cap->bounds = vout->crop_bounds[vout->cur_disp_output]; + cap->defrect = vout->crop_bounds[vout->cur_disp_output]; + retval = 0; + break; + } + case VIDIOC_G_CROP: + { + struct v4l2_crop *crop = arg; + + if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) { + retval = -EINVAL; + break; + } + crop->c = vout->crop_current; + break; + } + case VIDIOC_S_CROP: + { + struct v4l2_crop *crop = arg; + struct v4l2_rect *b = + &(vout->crop_bounds[vout->cur_disp_output]); + + if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) { + retval = -EINVAL; + break; + } + if (crop->c.height < 0) { + retval = -EINVAL; + break; + } + if (crop->c.width < 0) { + retval = -EINVAL; + break; + } + + /* only full screen supported for SDC BG */ + if (vout->cur_disp_output == 4) { + crop->c = vout->crop_current; + break; + } + + if (crop->c.top < b->top) + crop->c.top = b->top; + if (crop->c.top >= b->top + b->height) + crop->c.top = b->top + b->height - 1; + if (crop->c.height > b->top - crop->c.top + b->height) + crop->c.height = + b->top - crop->c.top + b->height; + + if (crop->c.left < b->left) + crop->c.left = b->left; + if (crop->c.left >= b->left + b->width) + crop->c.left = b->left + b->width - 1; + if (crop->c.width > b->left - crop->c.left + b->width) + crop->c.width = + b->left - crop->c.left + b->width; + + /* stride line limitation */ + crop->c.height -= crop->c.height % 8; + crop->c.width -= crop->c.width % 8; + + vout->crop_current = crop->c; + break; + } + case VIDIOC_ENUMOUTPUT: + { + struct v4l2_output *output = arg; + + if ((output->index >= 5) || + (vout->output_enabled[output->index] == false)) { + retval = -EINVAL; + break; + } + + if (output->index < 3) { + *output = mxc_outputs[MXC_V4L2_OUT_2_ADC]; + output->name[4] = '0' + output->index; + } else { + *output = mxc_outputs[MXC_V4L2_OUT_2_SDC]; + } + break; + } + case VIDIOC_G_OUTPUT: + { + int *p_output_num = arg; + + *p_output_num = vout->cur_disp_output; + break; + } + case VIDIOC_S_OUTPUT: + { + int *p_output_num = arg; + int fbnum; + struct v4l2_rect *b; + + if ((*p_output_num >= MXC_V4L2_OUT_NUM_OUTPUTS) || + (vout->output_enabled[*p_output_num] == false)) { + retval = -EINVAL; + break; + } + + if (vout->state != STATE_STREAM_OFF) { + retval = -EBUSY; + break; + } + + vout->cur_disp_output = *p_output_num; + + /* Update bounds in case they have changed */ + b = &vout->crop_bounds[vout->cur_disp_output]; + + fbnum = vout->output_fb_num[vout->cur_disp_output]; + if (vout->cur_disp_output == 3) + fbnum = vout->output_fb_num[4]; + + b->width = registered_fb[fbnum]->var.xres; + b->height = registered_fb[fbnum]->var.yres; + + vout->crop_current = *b; + break; + } + case VIDIOC_ENUM_FMT: + case VIDIOC_TRY_FMT: + case VIDIOC_QUERYCTRL: + case VIDIOC_G_PARM: + case VIDIOC_ENUMSTD: + case VIDIOC_G_STD: + case VIDIOC_S_STD: + case VIDIOC_G_TUNER: + case VIDIOC_S_TUNER: + case VIDIOC_G_FREQUENCY: + case VIDIOC_S_FREQUENCY: + default: + retval = -EINVAL; + break; + } + + up(&vout->busy_lock); + return retval; +} + +/* + * V4L2 interface - ioctl function + * + * @return None + */ +static int +mxc_v4l2out_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + return video_usercopy(inode, file, cmd, arg, mxc_v4l2out_do_ioctl); +} + +/*! + * V4L2 interface - mmap function + * + * @param file structure file * + * + * @param vma structure vm_area_struct * + * + * @return status 0 Success, EINTR busy lock error, + * ENOBUFS remap_page error + */ +static int mxc_v4l2out_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct video_device *vdev = video_devdata(file); + unsigned long size = vma->vm_end - vma->vm_start; + int res = 0; + int i; + vout_data *vout = video_get_drvdata(vdev); + + dev_dbg(&vdev->dev, "pgoff=0x%lx, start=0x%lx, end=0x%lx\n", + vma->vm_pgoff, vma->vm_start, vma->vm_end); + + /* make this _really_ smp-safe */ + if (down_interruptible(&vout->busy_lock)) + return -EINTR; + + for (i = 0; i < vout->buffer_cnt; i++) { + if ((vout->v4l2_bufs[i].m.offset == + (vma->vm_pgoff << PAGE_SHIFT)) && + (vout->v4l2_bufs[i].length >= size)) { + vout->v4l2_bufs[i].flags |= V4L2_BUF_FLAG_MAPPED; + break; + } + } + if (i == vout->buffer_cnt) { + res = -ENOBUFS; + goto mxc_mmap_exit; + } + + /* make buffers inner write-back, outer write-thru cacheable */ +// vma->vm_page_prot = pgprot_outer_wrthru(vma->vm_page_prot); + + if (remap_pfn_range(vma, vma->vm_start, + vma->vm_pgoff, size, vma->vm_page_prot)) { + dev_dbg(&vdev->dev, "mmap remap_pfn_range failed\n"); + res = -ENOBUFS; + goto mxc_mmap_exit; + } + + vma->vm_flags &= ~VM_IO; /* using shared anonymous pages */ + + mxc_mmap_exit: + up(&vout->busy_lock); + return res; +} + +/*! + * V4L2 interface - poll function + * + * @param file structure file * + * + * @param wait structure poll_table * + * + * @return status POLLIN | POLLRDNORM + */ +static unsigned int mxc_v4l2out_poll(struct file *file, poll_table * wait) +{ + struct video_device *dev = video_devdata(file); + vout_data *vout = video_get_drvdata(dev); + + wait_queue_head_t *queue = NULL; + int res = POLLIN | POLLRDNORM; + + if (down_interruptible(&vout->busy_lock)) + return -EINTR; + + queue = &vout->v4l_bufq; + poll_wait(file, queue, wait); + + up(&vout->busy_lock); + return res; +} + +static struct +file_operations mxc_v4l2out_fops = { + .owner = THIS_MODULE, + .open = mxc_v4l2out_open, + .release = mxc_v4l2out_close, + .ioctl = mxc_v4l2out_ioctl, + .mmap = mxc_v4l2out_mmap, + .poll = mxc_v4l2out_poll, +}; + +static struct video_device mxc_v4l2out_template = { + .name = "MXC Video Output", + .vfl_type = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING, + .fops = &mxc_v4l2out_fops, + .release = video_device_release, +}; + +/*! + * Probe routine for the framebuffer driver. It is called during the + * driver binding process. The following functions are performed in + * this routine: Framebuffer initialization, Memory allocation and + * mapping, Framebuffer registration, IPU initialization. + * + * @return Appropriate error code to the kernel common code + */ +static int mxc_v4l2out_probe(struct platform_device *pdev) +{ + int i; + vout_data *vout; + + /* + * Allocate sufficient memory for the fb structure + */ + g_vout = vout = kmalloc(sizeof(vout_data), GFP_KERNEL); + + if (!vout) + return 0; + + memset(vout, 0, sizeof(vout_data)); + + vout->video_dev = video_device_alloc(); + if (vout->video_dev == NULL) + return -1; + vout->video_dev->minor = -1; + + *(vout->video_dev) = mxc_v4l2out_template; + + /* register v4l device */ + if (video_register_device(vout->video_dev, + VFL_TYPE_GRABBER, video_nr) == -1) { + dev_dbg(&pdev->dev, "video_register_device failed\n"); + return 0; + } + dev_info(&pdev->dev, "Registered device video%d\n", + vout->video_dev->minor & 0x1f); +// vout->video_dev->dev = &pdev->dev; + + video_set_drvdata(vout->video_dev, vout); + + init_MUTEX(&vout->param_lock); + init_MUTEX(&vout->busy_lock); + + /* setup outputs and cropping */ + vout->cur_disp_output = -1; + for (i = 0; i < num_registered_fb; i++) { + char *idstr = registered_fb[i]->fix.id; + if (strncmp(idstr, "DISP", 4) == 0) { + int disp_num = idstr[4] - '0'; + if (disp_num == 3) { + if (strcmp(idstr, "DISP3 BG - DI1") == 0) + disp_num = 5; + else if (strncmp(idstr, "DISP3 BG", 8) == 0) + disp_num = 4; + } + vout->crop_bounds[disp_num].left = 0; + vout->crop_bounds[disp_num].top = 0; + vout->crop_bounds[disp_num].width = + registered_fb[i]->var.xres; + vout->crop_bounds[disp_num].height = + registered_fb[i]->var.yres; + vout->output_enabled[disp_num] = true; + vout->output_fb_num[disp_num] = i; + if (vout->cur_disp_output == -1) { + vout->cur_disp_output = disp_num; + } + } + + } + vout->crop_current = vout->crop_bounds[vout->cur_disp_output]; + + platform_set_drvdata(pdev, vout); + + return 0; +} + +static int mxc_v4l2out_remove(struct platform_device *pdev) +{ + vout_data *vout = platform_get_drvdata(pdev); + + if (vout->video_dev) { + if (-1 != vout->video_dev->minor) + video_unregister_device(vout->video_dev); + else + video_device_release(vout->video_dev); + vout->video_dev = NULL; + } + + platform_set_drvdata(pdev, NULL); + + kfree(vout); + + return 0; +} + +/*! + * This structure contains pointers to the power management callback functions. + */ +static struct platform_driver mxc_v4l2out_driver = { + .driver = { + .name = "MXC Video Output", + }, + .probe = mxc_v4l2out_probe, + .remove = mxc_v4l2out_remove, +}; + +static struct platform_device mxc_v4l2out_device = { + .name = "MXC Video Output", + .id = 0, +}; + +/*! + * mxc v4l2 init function + * + */ +static int mxc_v4l2out_init(void) +{ + u8 err = 0; + + err = platform_driver_register(&mxc_v4l2out_driver); + if (err == 0) { + platform_device_register(&mxc_v4l2out_device); + } + return err; +} + +/*! + * mxc v4l2 cleanup function + * + */ +static void mxc_v4l2out_clean(void) +{ + video_unregister_device(g_vout->video_dev); + + platform_driver_unregister(&mxc_v4l2out_driver); + platform_device_unregister(&mxc_v4l2out_device); + kfree(g_vout); + g_vout = NULL; +} + +module_init(mxc_v4l2out_init); +module_exit(mxc_v4l2out_clean); + +module_param(video_nr, int, 0444); +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("V4L2-driver for MXC video output"); +MODULE_LICENSE("GPL"); +MODULE_SUPPORTED_DEVICE("video"); --- linux-2.6.28.orig/drivers/media/video/mxc/output/Kconfig +++ linux-2.6.28/drivers/media/video/mxc/output/Kconfig @@ -0,0 +1,7 @@ +config VIDEO_MXC_IPU_OUTPUT + bool "IPU v4l2 support" + depends on VIDEO_MXC_OUTPUT && MXC_IPU + default y + ---help--- + This is the video4linux2 driver for IPU post processing video output. + --- linux-2.6.28.orig/drivers/media/video/mxc/output/Makefile +++ linux-2.6.28/drivers/media/video/mxc/output/Makefile @@ -0,0 +1,4 @@ +ifeq ($(CONFIG_VIDEO_MXC_IPU_OUTPUT),y) + obj-$(CONFIG_VIDEO_MXC_OUTPUT) += mxc_v4l2_output.o +endif + --- linux-2.6.28.orig/drivers/media/video/mxc/output/mxc_v4l2_output.h +++ linux-2.6.28/drivers/media/video/mxc/output/mxc_v4l2_output.h @@ -0,0 +1,132 @@ +/* + * Copyright 2005-2009 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 + */ + +/*! + * @defgroup MXC_V4L2_OUTPUT MXC V4L2 Video Output Driver + */ +/*! + * @file mxc_v4l2_output.h + * + * @brief MXC V4L2 Video Output Driver Header file + * + * Video4Linux2 Output Device using MXC IPU Post-processing functionality. + * + * @ingroup MXC_V4L2_OUTPUT + */ +#ifndef __MXC_V4L2_OUTPUT_H__ +#define __MXC_V4L2_OUTPUT_H__ + +#include + +#ifdef __KERNEL__ + +#include +#include + +#define MIN_FRAME_NUM 2 +#define MAX_FRAME_NUM 30 + +#define MXC_V4L2_OUT_NUM_OUTPUTS 6 +#define MXC_V4L2_OUT_2_SDC 0 +#define MXC_V4L2_OUT_2_ADC 1 + +typedef struct { + int list[MAX_FRAME_NUM + 1]; + int head; + int tail; +} v4l_queue; + +/*! + * States for the video stream + */ +typedef enum { + STATE_STREAM_OFF, + STATE_STREAM_ON, + STATE_STREAM_PAUSED, + STATE_STREAM_STOPPING, +} v4lout_state; + +/*! + * common v4l2 driver structure. + */ +typedef struct _vout_data { + struct video_device *video_dev; + /*! + * semaphore guard against SMP multithreading + */ + struct semaphore busy_lock; + + /*! + * number of process that have device open + */ + int open_count; + + /*! + * params lock for this camera + */ + struct semaphore param_lock; + + struct timer_list output_timer; + unsigned long start_jiffies; + u32 frame_count; + + v4l_queue ready_q; + v4l_queue done_q; + + s8 next_rdy_ipu_buf; + s8 next_done_ipu_buf; + s8 ipu_buf[2]; + volatile v4lout_state state; + + int cur_disp_output; + int output_fb_num[MXC_V4L2_OUT_NUM_OUTPUTS]; + int output_enabled[MXC_V4L2_OUT_NUM_OUTPUTS]; + struct v4l2_framebuffer v4l2_fb; + ipu_channel_t display_ch; + ipu_channel_t post_proc_ch; + + /*! + * FRAME_NUM-buffering, so we need a array + */ + int buffer_cnt; + dma_addr_t queue_buf_paddr[MAX_FRAME_NUM]; + void *queue_buf_vaddr[MAX_FRAME_NUM]; + u32 queue_buf_size; + struct v4l2_buffer v4l2_bufs[MAX_FRAME_NUM]; + u32 display_buf_size; + dma_addr_t display_bufs[2]; + void *display_bufs_vaddr[2]; + dma_addr_t rot_pp_bufs[2]; + void *rot_pp_bufs_vaddr[2]; + + /*! + * Poll wait queue + */ + wait_queue_head_t v4l_bufq; + + /*! + * v4l2 format + */ + struct v4l2_format v2f; + struct v4l2_mxc_offset offset; + ipu_rotate_mode_t rotate; + + /* crop */ + struct v4l2_rect crop_bounds[MXC_V4L2_OUT_NUM_OUTPUTS]; + struct v4l2_rect crop_current; + + struct work_struct timer_work; +} vout_data; + +#endif +#endif /* __MXC_V4L2_OUTPUT_H__ */ --- linux-2.6.28.orig/drivers/media/video/zc0301/zc0301_sensor.h +++ linux-2.6.28/drivers/media/video/zc0301/zc0301_sensor.h @@ -61,7 +61,6 @@ #define ZC0301_ID_TABLE \ static const struct usb_device_id zc0301_id_table[] = { \ { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \ - { ZC0301_USB_DEVICE(0x0ac8, 0x303b, 0xff), }, /* PB-0330 */ \ { } \ }; --- linux-2.6.28.orig/drivers/media/common/tuners/tda8290.c +++ linux-2.6.28/drivers/media/common/tuners/tda8290.c @@ -724,7 +724,8 @@ fe->ops.analog_ops.info.name = name; if (priv->ver & TDA8290) { - tda8290_init_tuner(fe); + if (priv->ver & (TDA8275 | TDA8275A)) + tda8290_init_tuner(fe); tda8290_init_if(fe); } else if (priv->ver & TDA8295) tda8295_init_if(fe); --- linux-2.6.28.orig/drivers/media/dvb/frontends/s5h1409.c +++ linux-2.6.28/drivers/media/dvb/frontends/s5h1409.c @@ -545,9 +545,6 @@ s5h1409_enable_modulation(fe, p->u.vsb.modulation); - /* Allow the demod to settle */ - msleep(100); - if (fe->ops.tuner_ops.set_params) { if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); @@ -562,6 +559,10 @@ s5h1409_set_qam_interleave_mode(fe); } + /* Issue a reset to the demod so it knows to resync against the + newly tuned frequency */ + s5h1409_softreset(fe); + return 0; } --- linux-2.6.28.orig/drivers/mmc/card/Kconfig +++ linux-2.6.28/drivers/mmc/card/Kconfig @@ -50,3 +50,15 @@ This driver is only of interest to those developing or testing a host driver. Most people should say N here. + +config SDIO_UNIFI_FS + tristate "UniFi SDIO glue for Freescale MMC/SDIO" + depends on (MMC_MXC || MMC_IMX_ESDHCI) + depends on (MACH_MX31_3DS || MACH_MX35_3DS || MACH_MX37_3DS || MACH_MX51_3DS) + help + This provides an interface between the CSR UniFi WiFi + driver and the Freescale MMC/SDIO interface. + If you have a MXC platform with a UniFi WiFi chip, + say M here. + + If unsure, say N. --- linux-2.6.28.orig/drivers/mmc/card/block.c +++ linux-2.6.28/drivers/mmc/card/block.c @@ -41,6 +41,8 @@ #include "queue.h" +MODULE_ALIAS("mmc:block"); + /* * max 8 partitions per card */ @@ -514,7 +516,7 @@ if (err) goto out; - string_get_size(get_capacity(md->disk) << 9, STRING_UNITS_2, + string_get_size((u64)get_capacity(md->disk) << 9, STRING_UNITS_2, cap_str, sizeof(cap_str)); printk(KERN_INFO "%s: %s %s %s %s\n", md->disk->disk_name, mmc_card_id(card), mmc_card_name(card), --- linux-2.6.28.orig/drivers/mmc/card/mmc_test.c +++ linux-2.6.28/drivers/mmc/card/mmc_test.c @@ -494,7 +494,7 @@ sg_init_one(&sg, test->buffer, 512); - ret = mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 1); + ret = mmc_test_simple_transfer(test, &sg, 1, 0, 1, 512, 0); if (ret) return ret; --- linux-2.6.28.orig/drivers/mmc/card/Makefile +++ linux-2.6.28/drivers/mmc/card/Makefile @@ -12,3 +12,4 @@ obj-$(CONFIG_SDIO_UART) += sdio_uart.o +obj-$(CONFIG_SDIO_UNIFI_FS) += unifi_fs/ --- linux-2.6.28.orig/drivers/mmc/card/unifi_fs/fs_sdio_api.h +++ linux-2.6.28/drivers/mmc/card/unifi_fs/fs_sdio_api.h @@ -0,0 +1,68 @@ +/* + *fs_sdio_api.h - Freescale SDIO glue module API for UniFi. + * + * Copyright (C) 2008 Cambridge Silicon Radio Ltd. + * + */ +/* + * Copyright 2008 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 _FS_SDIO_API_H +#define _FS_SDIO_API_H + +struct sdio_dev; + +struct fs_driver { + const char *name; + int (*probe)(struct sdio_dev *fdev); + void (*remove)(struct sdio_dev *fdev); + void (*card_int_handler)(struct sdio_dev *fdev); + void (*suspend)(struct sdio_dev *fdev, pm_message_t state); + void (*resume)(struct sdio_dev *fdev); +}; + +int fs_sdio_readb(struct sdio_dev *fdev, int funcnum, + unsigned long addr, unsigned char *pdata); +int fs_sdio_writeb(struct sdio_dev *fdev, int funcnum, + unsigned long addr, unsigned char data); +int fs_sdio_block_rw(struct sdio_dev *fdev, int funcnum, + unsigned long addr, unsigned char *pdata, + unsigned int count, int direction); + +int fs_sdio_register_driver(struct fs_driver *driver); +void fs_sdio_unregister_driver(struct fs_driver *driver); +int fs_sdio_set_block_size(struct sdio_dev *fdev, int blksz); +int fs_sdio_set_max_clock_speed(struct sdio_dev *fdev, int max_khz); +int fs_sdio_enable_interrupt(struct sdio_dev *fdev, int enable); +int fs_sdio_enable(struct sdio_dev *fdev); +int fs_sdio_hard_reset(struct sdio_dev *fdev); + +struct sdio_dev { + /**< Device driver for this module. */ + struct fs_driver *driver; + + struct sdio_func *func; + + /**< Data private to the device driver. */ + void *drv_data; + + int int_enabled; + spinlock_t lock; + + uint16_t vendor_id; /**< Vendor ID of the card. */ + uint16_t device_id; /**< Device ID of the card. */ + + /**< Maximum block size supported. */ + int max_blocksize; +}; + + +#endif /* #ifndef _FS_SDIO_API_H */ --- linux-2.6.28.orig/drivers/mmc/card/unifi_fs/fs_lx.c +++ linux-2.6.28/drivers/mmc/card/unifi_fs/fs_lx.c @@ -0,0 +1,686 @@ +/* + * fs_lx.c - Freescale SDIO glue module for UniFi. + * + * Copyright (C) 2008 Cambridge Silicon Radio Ltd. + * + * Important: + * This module does not support more than one device driver instances. + * + */ +/* + * Copyright 2008-2009 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 + */ +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include "fs_sdio_api.h" + +struct regulator_unifi { + struct regulator *reg_gpo1; + struct regulator *reg_gpo2; + struct regulator *reg_1v5_ana_bb; + struct regulator *reg_vdd_vpa; + struct regulator *reg_1v5_dd; +}; + +static struct sdio_driver sdio_unifi_driver; + +static int fs_sdio_probe(struct sdio_func *func, + const struct sdio_device_id *id); +static void fs_sdio_remove(struct sdio_func *func); +static void fs_sdio_irq(struct sdio_func *func); +static int fs_sdio_suspend(struct device *dev, pm_message_t state); +static int fs_sdio_resume(struct device *dev); +static int do_sdio_hard_reset(struct sdio_dev *fdev); + +/* Globals to store the context to this module and the device driver */ +static struct sdio_dev *available_sdio_dev; +static struct fs_driver *available_driver; +struct mxc_unifi_platform_data *plat_data; + +extern void mxc_mmc_force_detect(int id); + +enum sdio_cmd_direction { + CMD_READ, + CMD_WRITE, +}; + +static int fsl_io_rw_direct(struct mmc_card *card, int write, unsigned fn, + unsigned addr, u8 in, u8 *out) +{ + struct mmc_command cmd; + int err; + + BUG_ON(!card); + BUG_ON(fn > 7); + + memset(&cmd, 0, sizeof(struct mmc_command)); + + cmd.opcode = SD_IO_RW_DIRECT; + cmd.arg = write ? 0x80000000 : 0x00000000; + cmd.arg |= fn << 28; + cmd.arg |= (write && out) ? 0x08000000 : 0x00000000; + cmd.arg |= addr << 9; + cmd.arg |= in; + cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_AC; + + err = mmc_wait_for_cmd(card->host, &cmd, 0); + if (err) + return err; + + if (mmc_host_is_spi(card->host)) { + /* host driver already reported errors */ + } else { + if (cmd.resp[0] & R5_ERROR) + return -EIO; + if (cmd.resp[0] & R5_FUNCTION_NUMBER) + return -EINVAL; + if (cmd.resp[0] & R5_OUT_OF_RANGE) + return -ERANGE; + } + + if (out) { + if (mmc_host_is_spi(card->host)) + *out = (cmd.resp[0] >> 8) & 0xFF; + else + *out = cmd.resp[0] & 0xFF; + } + + return 0; +} + + +int fs_sdio_readb(struct sdio_dev *fdev, int funcnum, unsigned long addr, + unsigned char *pdata) +{ + int err; + char val; + + sdio_claim_host(fdev->func); + if (funcnum == 0) + val = sdio_f0_readb(fdev->func, (unsigned int)addr, &err); + else + val = sdio_readb(fdev->func, (unsigned int)addr, &err); + sdio_release_host(fdev->func); + if (!err) + *pdata = val; + else + printk(KERN_ERR "fs_lx: readb error,fun=%d,addr=%d,data=%d," + "err=%d\n", funcnum, (int)addr, *pdata, err); + + return err; +} +EXPORT_SYMBOL(fs_sdio_readb); + +int fs_sdio_writeb(struct sdio_dev *fdev, int funcnum, unsigned long addr, + unsigned char data) +{ + int err; + + sdio_claim_host(fdev->func); + if (funcnum == 0) + err = fsl_io_rw_direct(fdev->func->card, 1, 0, addr, + data, NULL); + else + sdio_writeb(fdev->func, data, (unsigned int)addr, &err); + sdio_release_host(fdev->func); + + if (err) + printk(KERN_ERR "fs_lx: writeb error,fun=%d,addr=%d,data=%d," + "err=%d\n", funcnum, (int)addr, data, err); + return err; +} +EXPORT_SYMBOL(fs_sdio_writeb); + +int fs_sdio_block_rw(struct sdio_dev *fdev, int funcnum, unsigned long addr, + unsigned char *pdata, unsigned int count, int direction) +{ + int err; + + sdio_claim_host(fdev->func); + if (direction == CMD_READ) + err = sdio_memcpy_fromio(fdev->func, pdata, addr, count); + else + err = sdio_memcpy_toio(fdev->func, addr, pdata, count); + sdio_release_host(fdev->func); + + return err; +} +EXPORT_SYMBOL(fs_sdio_block_rw); + +int fs_sdio_enable_interrupt(struct sdio_dev *fdev, int enable) +{ + struct mmc_host *host = fdev->func->card->host; + unsigned long flags; + + spin_lock_irqsave(&fdev->lock, flags); + if (enable) { + if (!fdev->int_enabled) { + fdev->int_enabled = 1; + host->ops->enable_sdio_irq(host, 1); + } + } else { + if (fdev->int_enabled) { + host->ops->enable_sdio_irq(host, 0); + fdev->int_enabled = 0; + } + } + spin_unlock_irqrestore(&fdev->lock, flags); + + return 0; +} +EXPORT_SYMBOL(fs_sdio_enable_interrupt); + +int fs_sdio_enable(struct sdio_dev *fdev) +{ + int err = 0; + + sdio_claim_host(fdev->func); + err = sdio_disable_func(fdev->func); + err = sdio_enable_func(fdev->func); + sdio_release_host(fdev->func); + if (err) + printk(KERN_ERR "fs_lx:fs_sdio_enable error,err=%d\n", err); + return err; +} +EXPORT_SYMBOL(fs_sdio_enable); + +int fs_sdio_set_max_clock_speed(struct sdio_dev *fdev, int max_khz) +{ + struct mmc_card *card = fdev->func->card; + + /* Respect the host controller's min-max. */ + max_khz *= 1000; + if (max_khz < card->host->f_min) + max_khz = card->host->f_min; + if (max_khz > card->host->f_max) + max_khz = card->host->f_max; + + card->host->ios.clock = max_khz; + card->host->ops->set_ios(card->host, &card->host->ios); + + return max_khz / 1000; +} +EXPORT_SYMBOL(fs_sdio_set_max_clock_speed); + +int fs_sdio_set_block_size(struct sdio_dev *fdev, int blksz) +{ + return 0; +} +EXPORT_SYMBOL(fs_sdio_set_block_size); + +/* + * --------------------------------------------------------------------------- + * + * Turn on the power of WIFI card + * + * --------------------------------------------------------------------------- + */ +static void fs_unifi_power_on(int check_card) +{ + struct regulator_unifi *reg_unifi; + unsigned int tmp; + + reg_unifi = plat_data->priv; + + if (reg_unifi->reg_gpo1) + regulator_enable(reg_unifi->reg_gpo1); + if (reg_unifi->reg_gpo2) + regulator_enable(reg_unifi->reg_gpo2); + + if (plat_data->enable) + plat_data->enable(1); + + if (reg_unifi->reg_1v5_ana_bb) { + tmp = regulator_get_voltage(reg_unifi->reg_1v5_ana_bb); + if (tmp < 1500000) + regulator_set_voltage(reg_unifi->reg_1v5_ana_bb, + 1500000, 1500000); + regulator_enable(reg_unifi->reg_1v5_ana_bb); + } + if (reg_unifi->reg_vdd_vpa) { + tmp = regulator_get_voltage(reg_unifi->reg_vdd_vpa); + if (tmp < 3000000) + regulator_set_voltage(reg_unifi->reg_vdd_vpa, + 3000000, 3000000); + regulator_enable(reg_unifi->reg_vdd_vpa); + } + /* WL_1V5DD should come on last, 10ms after other supplies */ + msleep(10); + if (reg_unifi->reg_1v5_dd) { + tmp = regulator_get_voltage(reg_unifi->reg_1v5_dd); + if (tmp < 1500000) + regulator_set_voltage(reg_unifi->reg_1v5_dd, + 1500000, 1500000); + regulator_enable(reg_unifi->reg_1v5_dd); + } + msleep(10); + if (check_card) { + do_sdio_hard_reset(NULL); + msleep(500); + mxc_mmc_force_detect(plat_data->host_id); + } +} + +/* + * --------------------------------------------------------------------------- + * + * Turn off the power of WIFI card + * + * --------------------------------------------------------------------------- + */ +static void fs_unifi_power_off(int check_card) +{ + struct regulator_unifi *reg_unifi; + + reg_unifi = plat_data->priv; + if (reg_unifi->reg_1v5_dd) + regulator_disable(reg_unifi->reg_1v5_dd); + if (reg_unifi->reg_vdd_vpa) + regulator_disable(reg_unifi->reg_vdd_vpa); + + if (reg_unifi->reg_1v5_ana_bb) + regulator_disable(reg_unifi->reg_1v5_ana_bb); + + if (plat_data->enable) + plat_data->enable(0); + + if (reg_unifi->reg_gpo2) + regulator_disable(reg_unifi->reg_gpo2); + + if (reg_unifi->reg_gpo1) + regulator_disable(reg_unifi->reg_gpo1); + + if (check_card) + mxc_mmc_force_detect(plat_data->host_id); + +} + +/* This should be made conditional on being slot 2 too - so we can + * use a plug in card in slot 1 + */ +int fs_sdio_hard_reset(struct sdio_dev *fdev) +{ + return 0; +} +EXPORT_SYMBOL(fs_sdio_hard_reset); + +static int do_sdio_hard_reset(struct sdio_dev *fdev) +{ + plat_data->hardreset(); + return 0; +} + +static const struct sdio_device_id fs_sdio_ids[] = { + {SDIO_DEVICE(0x032a, 0x0001)}, + { /* end: all zeroes */ }, +}; + +static struct sdio_driver sdio_unifi_driver = { + .name = "fs_unifi", + .probe = fs_sdio_probe, + .remove = fs_sdio_remove, + .id_table = fs_sdio_ids, + .drv = { + .suspend = fs_sdio_suspend, + .resume = fs_sdio_resume, + } +}; + +int fs_sdio_register_driver(struct fs_driver *driver) +{ + int ret; + + /* Switch us on */ + fs_unifi_power_on(-1); + + /* Store the context to the device driver to the global */ + available_driver = driver; + + /* + * If available_sdio_dev is not NULL, probe has been called, + * so pass the probe to the registered driver + */ + if (available_sdio_dev) { + /* Store the context to the new device driver */ + available_sdio_dev->driver = driver; + + printk(KERN_INFO "fs_sdio_register_driver: Glue exists, add " + "device driver and register IRQ\n"); + driver->probe(available_sdio_dev); + + /* Register the IRQ handler to the SDIO IRQ. */ + sdio_claim_host(available_sdio_dev->func); + ret = sdio_claim_irq(available_sdio_dev->func, fs_sdio_irq); + sdio_release_host(available_sdio_dev->func); + if (ret) + return ret; + } + + return 0; +} +EXPORT_SYMBOL(fs_sdio_register_driver); + +void fs_sdio_unregister_driver(struct fs_driver *driver) +{ + /* + * If available_sdio_dev is not NULL, probe has been called, + * so pass the remove to the registered driver to clean up. + */ + if (available_sdio_dev) { + struct mmc_host *host = available_sdio_dev->func->card->host; + + printk(KERN_INFO "fs_sdio_unregister_driver: Glue exists, " + "unregister IRQ and remove device driver\n"); + + /* Unregister the IRQ handler first. */ + sdio_claim_host(available_sdio_dev->func); + sdio_release_irq(available_sdio_dev->func); + sdio_release_host(available_sdio_dev->func); + + driver->remove(available_sdio_dev); + + if (!available_sdio_dev->int_enabled) { + available_sdio_dev->int_enabled = 1; + host->ops->enable_sdio_irq(host, 1); + } + + /* Invalidate the context to the device driver */ + available_sdio_dev->driver = NULL; + } + + /* invalidate the context to the device driver to the global */ + available_driver = NULL; + /* Power down the UniFi */ + fs_unifi_power_off(-1); + /* Wait for card removed */ + msleep(100); +} +EXPORT_SYMBOL(fs_sdio_unregister_driver); + +static void fs_sdio_irq(struct sdio_func *func) +{ + struct sdio_dev *fdev = (struct sdio_dev *)sdio_get_drvdata(func); + if (fdev->driver) { + if (fdev->driver->card_int_handler) + fdev->driver->card_int_handler(fdev); + } +} + +#ifdef CONFIG_PM +static int fs_sdio_suspend(struct device *dev, pm_message_t state) +{ + struct sdio_dev *fdev = available_sdio_dev; + + /* Pass event to the registered driver. */ + if (fdev->driver) + if (fdev->driver->suspend) + fdev->driver->suspend(fdev, state); + + return 0; +} + +static int fs_sdio_resume(struct device *dev) +{ + struct sdio_dev *fdev = available_sdio_dev; + + /* Pass event to the registered driver. */ + if (fdev->driver) + if (fdev->driver->resume) + fdev->driver->resume(fdev); + + return 0; +} +#else +#define fs_sdio_suspend NULL +#define fs_sdio_resume NULL +#endif + +static int fs_sdio_probe(struct sdio_func *func, + const struct sdio_device_id *id) +{ + struct sdio_dev *fdev; + int ret = 0; + + /* Allocate our private context */ + fdev = kmalloc(sizeof(struct sdio_dev), GFP_KERNEL); + if (!fdev) + return -ENOMEM; + available_sdio_dev = fdev; + memset(fdev, 0, sizeof(struct sdio_dev)); + fdev->func = func; + fdev->vendor_id = id->vendor; + fdev->device_id = id->device; + fdev->max_blocksize = func->max_blksize; + fdev->int_enabled = 1; + spin_lock_init(&fdev->lock); + + /* Store our context in the MMC driver */ + printk(KERN_INFO "fs_sdio_probe: Add glue driver\n"); + sdio_set_drvdata(func, fdev); + + /* TODO: If a device driver is registered, call it's probe here */ + if (available_driver) { + /* Store the context to the device driver */ + fdev->driver = available_driver; + + printk(KERN_INFO "fs_sdio_probe: Add device driver and " + "register IRQ\n"); + available_driver->probe(fdev); + + /* Register the IRQ handler to the SDIO IRQ. */ + sdio_claim_host(fdev->func); + ret = sdio_claim_irq(func, fs_sdio_irq); + sdio_release_host(fdev->func); + if (ret) + return ret; + } + + return 0; +} + +static void fs_sdio_remove(struct sdio_func *func) +{ + struct sdio_dev *fdev = (struct sdio_dev *)sdio_get_drvdata(func); + struct mmc_host *host = func->card->host; + + /* If there is a registered device driver, pass on the remove */ + if (fdev->driver) { + printk(KERN_INFO "fs_sdio_remove: Free IRQ and remove device " + "driver\n"); + /* Unregister the IRQ handler first. */ + sdio_claim_host(fdev->func); + sdio_release_irq(func); + sdio_release_host(fdev->func); + + fdev->driver->remove(fdev); + + if (!fdev->int_enabled) { + fdev->int_enabled = 1; + host->ops->enable_sdio_irq(host, 1); + } + } + + /* Unregister the card context from the MMC driver. */ + sdio_set_drvdata(func, NULL); + + /* Invalidate the global to our context. */ + available_sdio_dev = NULL; + kfree(fdev); +} + +static int fs_unifi_init(void) +{ + struct regulator_unifi *reg_unifi; + struct regulator *reg; + int err = 0; + + plat_data = get_unifi_plat_data(); + + if (!plat_data) + return -ENOENT; + + reg_unifi = kzalloc(sizeof(struct regulator_unifi), GFP_KERNEL); + if (!reg_unifi) + return -ENOMEM; + + if (plat_data->reg_gpo1) { + reg = regulator_get(NULL, plat_data->reg_gpo1); + if (!IS_ERR(reg)) + reg_unifi->reg_gpo1 = reg; + else { + err = -EINVAL; + goto err_reg_gpo1; + } + } + + if (plat_data->reg_gpo2) { + reg = regulator_get(NULL, plat_data->reg_gpo2); + if (!IS_ERR(reg)) + reg_unifi->reg_gpo2 = reg; + else { + err = -EINVAL; + goto err_reg_gpo2; + } + } + + if (plat_data->reg_1v5_ana_bb) { + reg = regulator_get(NULL, plat_data->reg_1v5_ana_bb); + if (!IS_ERR(reg)) + reg_unifi->reg_1v5_ana_bb = reg; + else { + err = -EINVAL; + goto err_reg_1v5_ana_bb; + } + } + + if (plat_data->reg_vdd_vpa) { + reg = regulator_get(NULL, plat_data->reg_vdd_vpa); + if (!IS_ERR(reg)) + reg_unifi->reg_vdd_vpa = reg; + else { + err = -EINVAL; + goto err_reg_vdd_vpa; + } + } + + if (plat_data->reg_1v5_dd) { + reg = regulator_get(NULL, plat_data->reg_1v5_dd); + if (!IS_ERR(reg)) + reg_unifi->reg_1v5_dd = reg; + else { + err = -EINVAL; + goto err_reg_1v5_dd; + } + } + plat_data->priv = reg_unifi; + return 0; + +err_reg_1v5_dd: + if (reg_unifi->reg_vdd_vpa) + regulator_put(reg_unifi->reg_vdd_vpa); +err_reg_vdd_vpa: + if (reg_unifi->reg_1v5_ana_bb) + regulator_put(reg_unifi->reg_1v5_ana_bb); +err_reg_1v5_ana_bb: + if (reg_unifi->reg_gpo2) + regulator_put(reg_unifi->reg_gpo2); +err_reg_gpo2: + if (reg_unifi->reg_gpo1) + regulator_put(reg_unifi->reg_gpo1); +err_reg_gpo1: + kfree(reg_unifi); + return err; +} + +int fs_unifi_remove(void) +{ + struct regulator_unifi *reg_unifi; + + reg_unifi = plat_data->priv; + plat_data->priv = NULL; + + if (reg_unifi->reg_1v5_dd) + regulator_put(reg_unifi->reg_1v5_dd); + if (reg_unifi->reg_vdd_vpa) + regulator_put(reg_unifi->reg_vdd_vpa); + + if (reg_unifi->reg_1v5_ana_bb) + regulator_put(reg_unifi->reg_1v5_ana_bb); + + if (reg_unifi->reg_gpo2) + regulator_put(reg_unifi->reg_gpo2); + + if (reg_unifi->reg_gpo1) + regulator_put(reg_unifi->reg_gpo1); + + kfree(reg_unifi); + return 0; +} + +/* Module init and exit, register and unregister to the SDIO/MMC driver */ +static int __init fs_sdio_init(void) +{ + int err; + + printk(KERN_INFO "Freescale: Register to MMC/SDIO driver\n"); + /* Sleep a bit - otherwise if the mmc subsystem has just started, it + * will allow us to register, then immediatly remove us! + */ + msleep(10); + err = fs_unifi_init(); + if (err) { + printk(KERN_ERR "Error: fs_unifi_init failed!\n"); + return err; + } + err = sdio_register_driver(&sdio_unifi_driver); + if (err) { + printk(KERN_ERR "Error: register sdio_unifi_driver failed!\n"); + fs_unifi_remove(); + } + return err; +} + +module_init(fs_sdio_init); + +static void __exit fs_sdio_exit(void) +{ + printk(KERN_INFO "Freescale: Unregister from MMC/SDIO driver\n"); + sdio_unregister_driver(&sdio_unifi_driver); + fs_unifi_remove(); +} + +module_exit(fs_sdio_exit); + +MODULE_DESCRIPTION("Freescale SDIO glue driver"); +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/mmc/card/unifi_fs/Makefile +++ linux-2.6.28/drivers/mmc/card/unifi_fs/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_SDIO_UNIFI_FS) = unifi_fs.o +unifi_fs-objs = fs_lx.o --- linux-2.6.28.orig/drivers/mmc/core/core.c +++ linux-2.6.28/drivers/mmc/core/core.c @@ -524,7 +524,7 @@ * This delay must be at least 74 clock sizes, or 1 ms, or the * time required to reach a stable voltage. */ - mmc_delay(2); + mmc_delay(10); } static void mmc_power_off(struct mmc_host *host) --- linux-2.6.28.orig/drivers/mmc/core/mmc.c +++ linux-2.6.28/drivers/mmc/core/mmc.c @@ -208,7 +208,7 @@ } ext_csd_struct = ext_csd[EXT_CSD_REV]; - if (ext_csd_struct > 2) { + if (ext_csd_struct > 3) { printk(KERN_ERR "%s: unrecognised EXT_CSD structure " "version %d\n", mmc_hostname(card->host), ext_csd_struct); @@ -434,6 +434,16 @@ * Activate wide bus (if supported). */ if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && +#ifdef CONFIG_ARCH_MXC_CANONICAL + (host->caps & MMC_CAP_8_BIT_DATA)) { + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_8); + if (err) + goto free_card; + + mmc_set_bus_width(card->host, MMC_BUS_WIDTH_8); + } else if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && +#endif (host->caps & MMC_CAP_4_BIT_DATA)) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4); --- linux-2.6.28.orig/drivers/mmc/core/mmc_ops.c +++ linux-2.6.28/drivers/mmc/core/mmc_ops.c @@ -248,12 +248,15 @@ sg_init_one(&sg, data_buf, len); - /* - * The spec states that CSR and CID accesses have a timeout - * of 64 clock cycles. - */ - data.timeout_ns = 0; - data.timeout_clks = 64; + if (opcode == MMC_SEND_CSD || opcode == MMC_SEND_CID) { + /* + * The spec states that CSR and CID accesses have a timeout + * of 64 clock cycles. + */ + data.timeout_ns = 0; + data.timeout_clks = 64; + } else + mmc_set_data_timeout(&data, card); mmc_wait_for_req(host, &mrq); --- linux-2.6.28.orig/drivers/mmc/core/bus.c +++ linux-2.6.28/drivers/mmc/core/bus.c @@ -84,6 +84,14 @@ } retval = add_uevent_var(env, "MMC_NAME=%s", mmc_card_name(card)); + if (retval) + return retval; + + /* + * Request the mmc_block device. Note: that this is a direct request + * for the module it carries no information as to what is inserted. + */ + retval = add_uevent_var(env, "MODALIAS=mmc:block"); return retval; } --- linux-2.6.28.orig/drivers/mmc/host/mx_sdhci.c +++ linux-2.6.28/drivers/mmc/host/mx_sdhci.c @@ -0,0 +1,2100 @@ +/* + * Copyright 2008-2009 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 + */ + +/*! + * @file mx_sdhci.c + * + * @brief Driver for the Freescale Semiconductor MXC eSDHC modules. + * + * This driver code is based on sdhci.c, by Pierre Ossman "); + * This driver supports Enhanced Secure Digital Host Controller + * modules eSDHC of MXC. eSDHC is also referred as enhanced MMC/SD + * controller. + * + * @ingroup MMC_SD + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "mx_sdhci.h" + +#define DRIVER_NAME "mxsdhci" + +#define DBG(f, x...) \ + pr_debug(DRIVER_NAME " [%s()]: " f, __func__, ## x) + +static unsigned int debug_quirks; +static int last_op_dir; + +/* + * 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) +/* Controller only support the PIO */ +#define SDHCI_QUIRK_ONLY_PIO (1<<16) +/* Controller support the External DMA */ +#define SDHCI_QUIRK_EXTERNAL_DMA_MODE (1<<17) +/* Controller support the Internal Simple DMA */ +#define SDHCI_QUIRK_INTERNAL_SIMPLE_DMA (1<<18) +/* Controller support the Internal Advanced DMA */ +#define SDHCI_QUIRK_INTERNAL_ADVANCED_DMA (1<<19) + +/* + * defines the mxc flags refer to the special hw pre-conditons and behavior + */ +static unsigned int mxc_quirks; +#ifdef CONFIG_MMC_IMX_ESDHCI_PIO_MODE +static unsigned int debug_quirks = SDHCI_QUIRK_ONLY_PIO; +#else +static unsigned int debug_quirks; +#endif +static unsigned int mxc_wml_value = 512; +static unsigned int *adma_des_table; + +#ifndef MXC_SDHCI_NUM +#define MXC_SDHCI_NUM 4 +#endif + +static struct sdhci_chip *mxc_fix_chips[MXC_SDHCI_NUM]; + +static void sdhci_prepare_data(struct sdhci_host *, struct mmc_data *); +static void sdhci_finish_data(struct sdhci_host *); + +static void sdhci_send_command(struct sdhci_host *, struct mmc_command *); +static void sdhci_finish_command(struct sdhci_host *); + +/* Used to active the SD bus */ +extern void gpio_sdhc_active(int module); +extern void gpio_sdhc_inactive(int module); +static void sdhci_dma_irq(void *devid, int error, unsigned int cnt); + +void mxc_mmc_force_detect(int id) +{ + struct sdhci_host *host; + if ((id < 0) || (id >= MXC_SDHCI_NUM)) + return; + if (!mxc_fix_chips[id]) + return; + host = mxc_fix_chips[id]->hosts[0]; + if (host->flags & SDHCI_CD_PRESENT) + return; + if (host->detect_irq) + return; + + schedule_work(&host->cd_wq); + return; +} + +EXPORT_SYMBOL(mxc_mmc_force_detect); + +static void sdhci_dumpregs(struct sdhci_host *host) +{ + printk(KERN_DEBUG DRIVER_NAME + ": ============== REGISTER DUMP ==============\n"); + + printk(KERN_DEBUG DRIVER_NAME ": Sys addr: 0x%08x | Version: 0x%08x\n", + readl(host->ioaddr + SDHCI_DMA_ADDRESS), + readl(host->ioaddr + SDHCI_HOST_VERSION)); + printk(KERN_DEBUG DRIVER_NAME ": Blk size: 0x%08x | Blk cnt: 0x%08x\n", + (readl(host->ioaddr + SDHCI_BLOCK_SIZE) & 0xFFFF), + (readl(host->ioaddr + SDHCI_BLOCK_COUNT) >> 16)); + printk(KERN_DEBUG DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n", + readl(host->ioaddr + SDHCI_ARGUMENT), + readl(host->ioaddr + SDHCI_TRANSFER_MODE)); + printk(KERN_DEBUG DRIVER_NAME ": Present: 0x%08x | Host ctl: 0x%08x\n", + readl(host->ioaddr + SDHCI_PRESENT_STATE), + readl(host->ioaddr + SDHCI_HOST_CONTROL)); + printk(KERN_DEBUG DRIVER_NAME ": Clock: 0x%08x\n", + readl(host->ioaddr + SDHCI_CLOCK_CONTROL)); + printk(KERN_DEBUG DRIVER_NAME ": Int stat: 0x%08x\n", + readl(host->ioaddr + SDHCI_INT_STATUS)); + printk(KERN_DEBUG DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n", + readl(host->ioaddr + SDHCI_INT_ENABLE), + readl(host->ioaddr + SDHCI_SIGNAL_ENABLE)); + printk(KERN_DEBUG DRIVER_NAME ": Caps: 0x%08x\n", + readl(host->ioaddr + SDHCI_CAPABILITIES)); + + printk(KERN_DEBUG DRIVER_NAME + ": ===========================================\n"); +} + +/*****************************************************************************\ + * * + * Low level functions * + * * +\*****************************************************************************/ + +static void sdhci_reset(struct sdhci_host *host, u8 mask) +{ + unsigned long tmp; + unsigned long mask_u32; + unsigned long reg_save = 0; + + if (host->chip->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) { + if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & + SDHCI_CARD_PRESENT)) + return; + } + + if (mask & SDHCI_RESET_ALL) + host->clock = 0; + else if (host->flags & SDHCI_CD_PRESENT) + reg_save = readl(host->ioaddr + SDHCI_HOST_CONTROL); + + tmp = readl(host->ioaddr + SDHCI_CLOCK_CONTROL) | (mask << 24); + mask_u32 = readl(host->ioaddr + SDHCI_SIGNAL_ENABLE); + writel(tmp, host->ioaddr + SDHCI_CLOCK_CONTROL); + + /* Wait max 100 ms */ + tmp = 5000; + + /* hw clears the bit when it's done */ + while ((readl(host->ioaddr + SDHCI_CLOCK_CONTROL) >> 24) & mask) { + if (tmp == 0) { + printk(KERN_ERR "%s: Reset 0x%x never completed.\n", + mmc_hostname(host->mmc), (int)mask); + sdhci_dumpregs(host); + return; + } + tmp--; + udelay(20); + } + /* + * The INT_EN SIG_EN regs have been modified after reset. + * re-configure them ag. + */ + if (!(mask & SDHCI_RESET_ALL) && (host->flags & SDHCI_CD_PRESENT)) + writel(reg_save, host->ioaddr + SDHCI_HOST_CONTROL); + if (host->flags & SDHCI_USE_DMA) + mask_u32 &= ~(SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL); + if (mxc_wml_value == 512) + writel(SDHCI_WML_128_WORDS, host->ioaddr + SDHCI_WML); + else + writel(SDHCI_WML_16_WORDS, host->ioaddr + SDHCI_WML); + writel(mask_u32 | SDHCI_INT_CARD_INT, host->ioaddr + SDHCI_INT_ENABLE); + writel(mask_u32, host->ioaddr + SDHCI_SIGNAL_ENABLE); + last_op_dir = 0; +} + +static void sdhci_init(struct sdhci_host *host) +{ + u32 intmask; + + sdhci_reset(host, SDHCI_RESET_ALL); + + intmask = SDHCI_INT_ADMA_ERROR | + SDHCI_INT_DATA_END_BIT | SDHCI_INT_DATA_CRC | + SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX | + SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT | + SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | + SDHCI_INT_DMA_END | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE; + + if (host->flags & SDHCI_USE_DMA) + intmask &= ~(SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL); + /* Configure the WML rege */ + if (mxc_wml_value == 512) + writel(SDHCI_WML_128_WORDS, host->ioaddr + SDHCI_WML); + else + writel(SDHCI_WML_16_WORDS, host->ioaddr + SDHCI_WML); + writel(intmask | SDHCI_INT_CARD_INT, host->ioaddr + SDHCI_INT_ENABLE); + writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE); +} + +static void sdhci_activate_led(struct sdhci_host *host) +{ + u32 ctrl; + + ctrl = readl(host->ioaddr + SDHCI_HOST_CONTROL); + ctrl |= SDHCI_CTRL_LED; + writel(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); +} + +static void sdhci_deactivate_led(struct sdhci_host *host) +{ + u32 ctrl; + + ctrl = readl(host->ioaddr + SDHCI_HOST_CONTROL); + ctrl &= ~SDHCI_CTRL_LED; + writel(ctrl, host->ioaddr + SDHCI_HOST_CONTROL); +} + +/*****************************************************************************\ + * * + * Core functions * + * * +\*****************************************************************************/ + +static inline char *sdhci_sg_to_buffer(struct sdhci_host *host) +{ + return sg_virt(host->cur_sg); +} + +static inline int sdhci_next_sg(struct sdhci_host *host) +{ + /* + * Skip to next SG entry. + */ + host->cur_sg++; + host->num_sg--; + + /* + * Any entries left? + */ + if (host->num_sg > 0) { + host->offset = 0; + host->remain = host->cur_sg->length; + } + + return host->num_sg; +} + +static void sdhci_read_block_pio(struct sdhci_host *host) +{ + int blksize, chunk_remain; + u32 data; + char *buffer; + int size; + + DBG("PIO reading\n"); + + blksize = host->data->blksz; + chunk_remain = 0; + data = 0; + + buffer = sdhci_sg_to_buffer(host) + host->offset; + + while (blksize) { + if (chunk_remain == 0) { + data = readl(host->ioaddr + SDHCI_BUFFER); + chunk_remain = min(blksize, 4); + } + + size = min(host->remain, chunk_remain); + + chunk_remain -= size; + blksize -= size; + host->offset += size; + host->remain -= size; + + while (size) { + *buffer = data & 0xFF; + buffer++; + data >>= 8; + size--; + } + + if (host->remain == 0) { + if (sdhci_next_sg(host) == 0) { + BUG_ON(blksize != 0); + return; + } + buffer = sdhci_sg_to_buffer(host); + } + } +} + +static void sdhci_write_block_pio(struct sdhci_host *host) +{ + int blksize, chunk_remain; + u32 data; + char *buffer; + int bytes, size; + + DBG("PIO writing\n"); + + blksize = host->data->blksz; + chunk_remain = 4; + data = 0; + + bytes = 0; + buffer = sdhci_sg_to_buffer(host) + host->offset; + + while (blksize) { + size = min(host->remain, chunk_remain); + + chunk_remain -= size; + blksize -= size; + host->offset += size; + host->remain -= size; + + while (size) { + data >>= 8; + data |= (u32) *buffer << 24; + buffer++; + size--; + } + + if (chunk_remain == 0) { + writel(data, host->ioaddr + SDHCI_BUFFER); + chunk_remain = min(blksize, 4); + } + + if (host->remain == 0) { + if (sdhci_next_sg(host) == 0) { + BUG_ON(blksize != 0); + return; + } + buffer = sdhci_sg_to_buffer(host); + } + } +} + +static void sdhci_transfer_pio(struct sdhci_host *host) +{ + u32 mask; + + BUG_ON(!host->data); + + if (host->num_sg == 0) + return; + + if (host->data->flags & MMC_DATA_READ) + mask = SDHCI_DATA_AVAILABLE; + else + mask = SDHCI_SPACE_AVAILABLE; + + while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) { + if (host->data->flags & MMC_DATA_READ) + sdhci_read_block_pio(host); + else + sdhci_write_block_pio(host); + + if (host->num_sg == 0) + break; + } + + DBG("PIO transfer complete.\n"); +} + +static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) +{ + u32 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 (host->data->flags & MMC_DATA_READ) + writel(readl(host->ioaddr + SDHCI_CLOCK_CONTROL) | + SDHCI_CLOCK_HLK_EN, host->ioaddr + SDHCI_CLOCK_CONTROL); + + /* timeout in us */ + target_timeout = data->timeout_ns / 1000 + + data->timeout_clks / host->clock; + + /* + * Figure out needed cycles. + * We do this in steps in order to fit inside a 32 bit int. + * The first step is the minimum timeout, which will have a + * minimum resolution of 6 bits: + * (1) 2^13*1000 > 2^22, + * (2) host->timeout_clk < 2^16 + * => + * (1) / (2) > 2^6 + */ + count = 0; + current_timeout = (1 << 13) * 1000 / host->timeout_clk; + while (current_timeout < target_timeout) { + count++; + current_timeout <<= 1; + if (count >= 0xF) + break; + } + + /* + * 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)) + count++; + + if (count >= 0xF) { + DBG(KERN_WARNING "%s: Too large timeout requested!\n", + mmc_hostname(host->mmc)); + count = 0xE; + } + + /* Set the max time-out value to level up the compatibility */ + count = 0xE; + + count = + (count << 16) | (readl(host->ioaddr + SDHCI_CLOCK_CONTROL) & + 0xFFF0FFFF); + writel(count, host->ioaddr + SDHCI_CLOCK_CONTROL); + + if (host->flags & SDHCI_USE_DMA) + host->flags |= SDHCI_REQ_USE_DMA; + + if (unlikely((host->flags & SDHCI_REQ_USE_DMA) && + (host->chip->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; + } + + /* + * The assumption here being that alignment is the same after + * translation to device address space. + */ + if (unlikely((host->flags & SDHCI_REQ_USE_DMA) && + (host->chip->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 i; + struct scatterlist *tsg; + + DBG("Configure the sg DMA, %s, len is 0x%x\n", + (data->flags & MMC_DATA_READ) + ? "DMA_FROM_DEIVCE" : "DMA_TO_DEVICE", data->sg_len); + count = + dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, + (data-> + flags & MMC_DATA_READ) ? DMA_FROM_DEVICE : + DMA_TO_DEVICE); + BUG_ON(count != data->sg_len); + + /* Make sure the ADMA mode is selected. */ + i = readl(host->ioaddr + SDHCI_HOST_CONTROL); + i |= SDHCI_CTRL_ADMA; + writel(i, host->ioaddr + SDHCI_HOST_CONTROL); + + tsg = data->sg; + /* ADMA mode is used, create the descriptor table */ + for (i = 0; i < count; i++) { + if (tsg->dma_address & 0xFFF) { + DBG(KERN_ERR "ADMA addr isn't 4K aligned.\n"); + DBG(KERN_ERR "0x%x\n", tsg->dma_address); + DBG(KERN_ERR "Changed to Single DMA mode.\n"); + goto Single_DMA; + } + adma_des_table[2 * i] = tsg->length << 12; + adma_des_table[2 * i] |= FSL_ADMA_DES_ATTR_SET; + adma_des_table[2 * i] |= FSL_ADMA_DES_ATTR_VALID; + adma_des_table[2 * i + 1] = tsg->dma_address; + adma_des_table[2 * i + 1] |= FSL_ADMA_DES_ATTR_TRAN; + adma_des_table[2 * i + 1] |= FSL_ADMA_DES_ATTR_VALID; + if (count == (i + 1)) + adma_des_table[2 * i + 1] |= + FSL_ADMA_DES_ATTR_END; + tsg++; + } + + /* Write the physical address to ADMA address reg */ + writel(virt_to_phys(adma_des_table), + host->ioaddr + SDHCI_ADMA_ADDRESS); + Single_DMA: + /* Rollback to the Single DMA mode */ + i = readl(host->ioaddr + SDHCI_HOST_CONTROL); + i &= ~SDHCI_CTRL_ADMA; + writel(i, host->ioaddr + SDHCI_HOST_CONTROL); + /* Single DMA mode is used */ + writel(sg_dma_address(data->sg), + host->ioaddr + SDHCI_DMA_ADDRESS); + } else if ((host->flags & SDHCI_USE_EXTERNAL_DMA) && + (data->blocks * data->blksz >= mxc_wml_value)) { + host->dma_size = data->blocks * data->blksz; + DBG("Configure the External DMA, %s, len is 0x%x\n", + (data->flags & MMC_DATA_READ) + ? "DMA_FROM_DEIVCE" : "DMA_TO_DEVICE", host->dma_size); + + if (data->blksz & 0x3) { + printk(KERN_ERR + "mxc_mci: block size not multiple of 4 bytes\n"); + } + + if (data->flags & MMC_DATA_READ) + host->dma_dir = DMA_FROM_DEVICE; + else + host->dma_dir = DMA_TO_DEVICE; + + host->dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, + data->sg_len, host->dma_dir); + + if (data->flags & MMC_DATA_READ) { + mxc_dma_sg_config(host->dma, data->sg, data->sg_len, + host->dma_size, MXC_DMA_MODE_READ); + } else { + mxc_dma_sg_config(host->dma, data->sg, data->sg_len, + host->dma_size, MXC_DMA_MODE_WRITE); + } + } else { + host->cur_sg = data->sg; + host->num_sg = data->sg_len; + + host->offset = 0; + host->remain = host->cur_sg->length; + } + + /* We do not handle DMA boundaries, so set it to max (512 KiB) */ + writel((data->blocks << 16) | SDHCI_MAKE_BLKSZ(7, data->blksz), + host->ioaddr + SDHCI_BLOCK_SIZE); +} + +static void sdhci_finish_data(struct sdhci_host *host) +{ + struct mmc_data *data; + u16 blocks; + + BUG_ON(!host->data); + + data = host->data; + host->data = NULL; + + if (host->flags & SDHCI_REQ_USE_DMA) { + dma_unmap_sg(&(host->chip->pdev)->dev, data->sg, data->sg_len, + (data->flags & MMC_DATA_READ) ? DMA_FROM_DEVICE : + DMA_TO_DEVICE); + } + if ((host->flags & SDHCI_USE_EXTERNAL_DMA) && + (host->dma_size >= mxc_wml_value)) { + dma_unmap_sg(mmc_dev(host->mmc), data->sg, + host->dma_len, host->dma_dir); + host->dma_size = 0; + } + + /* + * Controller doesn't count down when in single block mode. + */ + if (data->blocks == 1) + blocks = (data->error == 0) ? 0 : 1; + else + blocks = readl(host->ioaddr + SDHCI_BLOCK_COUNT) >> 16; + data->bytes_xfered = data->blksz * data->blocks; + + if (data->stop) { + /* + * The controller needs a reset of internal state machines + * upon error conditions. + */ + if (data->error) { + sdhci_reset(host, SDHCI_RESET_CMD); + sdhci_reset(host, SDHCI_RESET_DATA); + } + + sdhci_send_command(host, data->stop); + } else + tasklet_schedule(&host->finish_tasklet); +} + +static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) +{ + int flags; + u32 mask; + u32 mode = 0; + unsigned long timeout; + + DBG("sdhci_send_command 0x%x is starting...\n", cmd->opcode); + WARN_ON(host->cmd); + + /* Wait max 10 ms */ + timeout = 10; + + mask = SDHCI_CMD_INHIBIT; + if ((cmd->data != NULL) || (cmd->flags & MMC_RSP_BUSY)) + mask |= SDHCI_DATA_INHIBIT; + + /* We shouldn't wait for data inihibit for stop commands, even + though they might use busy signaling */ + if (host->mrq->data && (cmd == host->mrq->data->stop)) + mask &= ~SDHCI_DATA_INHIBIT; + + while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) { + if (timeout == 0) { + printk(KERN_ERR "%s: Controller never released " + "inhibit bit(s).\n", mmc_hostname(host->mmc)); + sdhci_dumpregs(host); + cmd->error = -EIO; + tasklet_schedule(&host->finish_tasklet); + return; + } + timeout--; + mdelay(1); + } + + mod_timer(&host->timer, jiffies + 10 * HZ); + + host->cmd = cmd; + + sdhci_prepare_data(host, cmd->data); + + writel(cmd->arg, host->ioaddr + SDHCI_ARGUMENT); + + /* Set up the transfer mode */ + if (cmd->data != NULL) { + mode = SDHCI_TRNS_BLK_CNT_EN | SDHCI_TRNS_DPSEL; + if (cmd->data->blocks > 1) + mode |= SDHCI_TRNS_MULTI; + if (cmd->data->flags & MMC_DATA_READ) + mode |= SDHCI_TRNS_READ; + else + mode &= ~SDHCI_TRNS_READ; + if (host->flags & SDHCI_USE_DMA) + mode |= SDHCI_TRNS_DMA; + if (host->flags & SDHCI_USE_EXTERNAL_DMA) + DBG("Prepare data completely in %s transfer mode.\n", + "EXTTERNAL DMA"); + } + + if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) { + printk(KERN_ERR "%s: Unsupported response type!\n", + mmc_hostname(host->mmc)); + cmd->error = -EINVAL; + tasklet_schedule(&host->finish_tasklet); + return; + } + + if (!(cmd->flags & MMC_RSP_PRESENT)) + flags = SDHCI_CMD_RESP_NONE; + else if (cmd->flags & MMC_RSP_136) + flags = SDHCI_CMD_RESP_LONG; + else if (cmd->flags & MMC_RSP_BUSY) + flags = SDHCI_CMD_RESP_SHORT_BUSY; + else + flags = SDHCI_CMD_RESP_SHORT; + + if (cmd->flags & MMC_RSP_CRC) + flags |= SDHCI_CMD_CRC; + if (cmd->flags & MMC_RSP_OPCODE) + flags |= SDHCI_CMD_INDEX; + if (cmd->data) + flags |= SDHCI_CMD_DATA; + + mode |= SDHCI_MAKE_CMD(cmd->opcode, flags); + DBG("Complete sending cmd, transfer mode would be 0x%x.\n", mode); + writel(mode, host->ioaddr + SDHCI_TRANSFER_MODE); +} + +static void sdhci_finish_command(struct sdhci_host *host) +{ + int i; + + BUG_ON(host->cmd == NULL); + + if (host->cmd->flags & MMC_RSP_PRESENT) { + if (host->cmd->flags & MMC_RSP_136) { + /* CRC is stripped so we need to do some shifting. */ + for (i = 0; i < 4; i++) { + host->cmd->resp[i] = readl(host->ioaddr + + SDHCI_RESPONSE + (3 - + i) + * 4) << 8; + if (i != 3) + host->cmd->resp[i] |= + readb(host->ioaddr + + SDHCI_RESPONSE + (3 - i) * 4 - + 1); + } + } else { + host->cmd->resp[0] = + readl(host->ioaddr + SDHCI_RESPONSE); + } + } + + host->cmd->error = 0; + + if (host->data && host->data_early) + sdhci_finish_data(host); + + if (!host->cmd->data) + tasklet_schedule(&host->finish_tasklet); + + host->cmd = NULL; +} + +static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) +{ + /*This variable holds the value of clock divider, prescaler */ + int div = 0, prescaler = 0; + int clk_rate; + u32 clk; + unsigned long timeout; + + if (clock == 0) { + goto out; + } else { + if (!host->plat_data->clk_flg) { + clk_enable(host->clk); + host->plat_data->clk_flg = 1; + } + } + if (clock == host->clock) + return; + + clk_rate = clk_get_rate(host->clk); + clk = readl(host->ioaddr + SDHCI_CLOCK_CONTROL) & ~SDHCI_CLOCK_MASK; + writel(clk, host->ioaddr + SDHCI_CLOCK_CONTROL); + + if (clock == host->min_clk) + prescaler = 16; + else + prescaler = 0; + while (prescaler <= 0x80) { + for (div = 0; div <= 0xF; div++) { + int x; + if (prescaler != 0) + x = (clk_rate / (div + 1)) / (prescaler * 2); + else + x = clk_rate / (div + 1); + + DBG("x=%d, clock=%d %d\n", x, clock, div); + if (x <= clock) + break; + } + if (div < 0x10) + break; + if (prescaler == 0) + prescaler = 1; + else + prescaler <<= 1; + } + DBG("prescaler = 0x%x, divider = 0x%x\n", prescaler, div); + clk |= (prescaler << 8) | (div << 4); + + /* Configure the clock control register */ + clk |= + (readl(host->ioaddr + SDHCI_CLOCK_CONTROL) & (~SDHCI_CLOCK_MASK)); + if (host->plat_data->vendor_ver < ESDHC_VENDOR_V22) + writel(clk, host->ioaddr + SDHCI_CLOCK_CONTROL); + else + writel(clk | SDHCI_CLOCK_SD_EN, + host->ioaddr + SDHCI_CLOCK_CONTROL); + + /* Wait max 10 ms */ + timeout = 10; + while (timeout > 0) { + timeout--; + mdelay(1); + } + + out: + host->clock = clock; +} + +static void sdhci_set_power(struct sdhci_host *host, unsigned short power) +{ + int voltage = 0; + + /* There is no PWR CTL REG */ + if (host->power == power) + return; + + if (host->regulator_mmc) { + if (power == (unsigned short)-1) { + regulator_disable(host->regulator_mmc); + DBG("mmc power off\n"); + } else { + if (power == 7) + voltage = 1800000; + else if (power >= 8) + voltage = 2000000 + (power - 8) * 100000; + regulator_set_voltage(host->regulator_mmc, + voltage, voltage); + + if (regulator_enable(host->regulator_mmc) == 0) { + DBG("mmc power on\n"); + msleep(1); + } + } + } + + host->power = power; +} + +/*****************************************************************************\ + * * + * MMC callbacks * + * * +\*****************************************************************************/ + +static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) +{ + struct sdhci_host *host; + unsigned long flags; + + host = mmc_priv(mmc); + + /* Enable the clock */ + if (!host->plat_data->clk_flg) { + clk_enable(host->clk); + host->plat_data->clk_flg = 1; + } + + spin_lock_irqsave(&host->lock, flags); + + WARN_ON(host->mrq != NULL); + + sdhci_activate_led(host); + if (cpu_is_mx35_rev(CHIP_REV_2_0) < 0) { + if (mrq->cmd && mrq->data) { + if (mrq->data->flags & MMC_DATA_READ) + last_op_dir = 1; + else { + if (last_op_dir) + sdhci_reset(host, + SDHCI_RESET_CMD | + SDHCI_RESET_DATA); + } + } + } + spin_unlock_irqrestore(&host->lock, flags); + host->mrq = mrq; + if (!(host->flags & SDHCI_CD_PRESENT)) { + host->mrq->cmd->error = -ENOMEDIUM; + tasklet_schedule(&host->finish_tasklet); + } else + sdhci_send_command(host, mrq->cmd); + + mmiowb(); +} + +static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +{ + struct sdhci_host *host; + unsigned long flags; + u32 tmp; + mxc_dma_device_t dev_id = 0; + + DBG("%s: clock %u, bus %lu, power %u, vdd %u\n", DRIVER_NAME, + ios->clock, 1UL << ios->bus_width, ios->power_mode, ios->vdd); + + host = mmc_priv(mmc); + + /* Configure the External DMA mode */ + if (host->flags & SDHCI_USE_EXTERNAL_DMA) { + host->dma_dir = DMA_NONE; + if (mmc->ios.bus_width != host->mode) { + mxc_dma_free(host->dma); + if (mmc->ios.bus_width == MMC_BUS_WIDTH_4) { + if (host->id == 0) + dev_id = MXC_DMA_MMC1_WIDTH_4; + else + dev_id = MXC_DMA_MMC2_WIDTH_4; + } else { + if (host->id == 0) + dev_id = MXC_DMA_MMC1_WIDTH_1; + else + dev_id = MXC_DMA_MMC2_WIDTH_1; + } + host->dma = mxc_dma_request(dev_id, "MXC MMC"); + if (host->dma < 0) + DBG("Cannot allocate MMC DMA channel\n"); + mxc_dma_callback_set(host->dma, sdhci_dma_irq, + (void *)host); + /* Configure the WML rege */ + if (mxc_wml_value == 512) + writel(SDHCI_WML_128_WORDS, + host->ioaddr + SDHCI_WML); + else + writel(SDHCI_WML_16_WORDS, + host->ioaddr + SDHCI_WML); + } + } + + host->mode = mmc->ios.bus_width; + + spin_lock_irqsave(&host->lock, flags); + + /* + * Reset the chip on each power off. + * Should clear out any weird states. + */ + if (ios->power_mode == MMC_POWER_OFF) { + writel(0, host->ioaddr + SDHCI_SIGNAL_ENABLE); + sdhci_init(host); + } + + sdhci_set_clock(host, ios->clock); + + if (ios->power_mode == MMC_POWER_OFF) + sdhci_set_power(host, -1); + else { + sdhci_set_power(host, ios->vdd); + if (!readl(host->ioaddr + SDHCI_SIGNAL_ENABLE)) { + tmp = readl(host->ioaddr + SDHCI_INT_ENABLE); + if (host->sdio_enable) + writel(tmp, host->ioaddr + SDHCI_SIGNAL_ENABLE); + else + writel(tmp & ~SDHCI_INT_CARD_INT, + host->ioaddr + SDHCI_SIGNAL_ENABLE); + } + } + + tmp = readl(host->ioaddr + SDHCI_HOST_CONTROL); + + if (ios->bus_width == MMC_BUS_WIDTH_4) { + tmp &= ~SDHCI_CTRL_8BITBUS; + tmp |= SDHCI_CTRL_4BITBUS; + } else if (ios->bus_width == MMC_BUS_WIDTH_8) { + tmp &= ~SDHCI_CTRL_4BITBUS; + tmp |= SDHCI_CTRL_8BITBUS; + } else if (ios->bus_width == MMC_BUS_WIDTH_1) { + tmp &= ~SDHCI_CTRL_4BITBUS; + tmp &= ~SDHCI_CTRL_8BITBUS; + } + + if (host->flags & SDHCI_USE_DMA) + tmp |= SDHCI_CTRL_ADMA; + + writel(tmp, host->ioaddr + SDHCI_HOST_CONTROL); + + /* + * Some (ENE) controllers go apeshit on some ios operation, + * 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) + sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); + + mmiowb(); + spin_unlock_irqrestore(&host->lock, flags); +} + +static int sdhci_get_ro(struct mmc_host *mmc) +{ + struct sdhci_host *host; + + host = mmc_priv(mmc); + + if (host->plat_data->wp_status) + return host->plat_data->wp_status(mmc->parent); + else + return 0; +} + +static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable) +{ + struct sdhci_host *host; + unsigned long flags; + u32 ier, prot, clk, present; + + host = mmc_priv(mmc); + + spin_lock_irqsave(&host->lock, flags); + + if (enable) { + if (host->sdio_enable++) + goto exit_unlock; + } else { + if (--(host->sdio_enable)) + goto exit_unlock; + } + /* Enable the clock */ + if (!host->plat_data->clk_flg) { + clk_enable(host->clk); + host->plat_data->clk_flg = 1; + } + ier = readl(host->ioaddr + SDHCI_SIGNAL_ENABLE); + prot = readl(host->ioaddr + SDHCI_HOST_CONTROL); + clk = readl(host->ioaddr + SDHCI_CLOCK_CONTROL); + + if (enable) { + ier |= SDHCI_INT_CARD_INT; + prot |= SDHCI_CTRL_D3CD; + clk |= SDHCI_CLOCK_PER_EN | SDHCI_CLOCK_IPG_EN; + present = readl(host->ioaddr + SDHCI_PRESENT_STATE); + if ((present & SDHCI_CARD_INT_MASK) != SDHCI_CARD_INT_ID) + writel(SDHCI_INT_CARD_INT, + host->ioaddr + SDHCI_INT_STATUS); + } else { + ier &= ~SDHCI_INT_CARD_INT; + prot &= ~SDHCI_CTRL_D3CD; + clk &= ~(SDHCI_CLOCK_PER_EN | SDHCI_CLOCK_IPG_EN); + } + + writel(prot, host->ioaddr + SDHCI_HOST_CONTROL); + writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE); + writel(clk, host->ioaddr + SDHCI_CLOCK_CONTROL); + + mmiowb(); + exit_unlock: + spin_unlock_irqrestore(&host->lock, flags); +} + +static const struct mmc_host_ops sdhci_ops = { + .request = sdhci_request, + .set_ios = sdhci_set_ios, + .get_ro = sdhci_get_ro, + .enable_sdio_irq = sdhci_enable_sdio_irq, +}; + +/*****************************************************************************\ + * * + * Tasklets * + * * +\*****************************************************************************/ + +static void sdhci_tasklet_card(unsigned long param) +{ + struct sdhci_host *host; + unsigned long flags; + unsigned int cd_status = 0; + + host = (struct sdhci_host *)param; + + if (host->flags & SDHCI_CD_PRESENT) + host->flags &= ~SDHCI_CD_PRESENT; + else + host->flags |= SDHCI_CD_PRESENT; + /* Detect there is a card in slot or not */ + DBG("cd_status=%d %s\n", cd_status, + (host->flags & SDHCI_CD_PRESENT) ? "inserted" : "removed"); + + spin_lock_irqsave(&host->lock, flags); + + if (!(host->flags & SDHCI_CD_PRESENT)) { + if (host->mrq) { + printk(KERN_ERR "%s: Card removed during transfer!\n", + mmc_hostname(host->mmc)); + printk(KERN_ERR "%s: Resetting controller.\n", + mmc_hostname(host->mmc)); + + sdhci_reset(host, SDHCI_RESET_CMD); + sdhci_reset(host, SDHCI_RESET_DATA); + + host->mrq->cmd->error = -ENOMEDIUM; + tasklet_schedule(&host->finish_tasklet); + } + } + + spin_unlock_irqrestore(&host->lock, flags); + + mmc_detect_change(host->mmc, msecs_to_jiffies(500)); +} + +static void sdhci_tasklet_finish(unsigned long param) +{ + struct sdhci_host *host; + unsigned long flags; + struct mmc_request *mrq; + + host = (struct sdhci_host *)param; + + spin_lock_irqsave(&host->lock, flags); + + del_timer(&host->timer); + + mrq = host->mrq; + + /* + * 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->chip->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) { + unsigned int clock; + + /* This is to force an update */ + clock = host->clock; + host->clock = 0; + sdhci_set_clock(host, clock); + } + + /* Spec says we should do both at the same time, but Ricoh + controllers do not like that. */ + sdhci_reset(host, SDHCI_RESET_CMD); + sdhci_reset(host, SDHCI_RESET_DATA); + } + + host->mrq = NULL; + host->cmd = NULL; + host->data = NULL; + + sdhci_deactivate_led(host); + + mmiowb(); + spin_unlock_irqrestore(&host->lock, flags); + + /* Stop the clock when the req is done */ + flags = SDHCI_DATA_ACTIVE | SDHCI_DOING_WRITE | SDHCI_DOING_READ; + if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & flags)) { + if (host->plat_data->clk_flg) { + clk_disable(host->clk); + host->plat_data->clk_flg = 0; + } + } + + mmc_request_done(host->mmc, mrq); +} + +static void sdhci_timeout_timer(unsigned long data) +{ + struct sdhci_host *host; + unsigned long flags; + + host = (struct sdhci_host *)data; + + spin_lock_irqsave(&host->lock, flags); + + if (host->mrq) { + printk(KERN_ERR "%s: Timeout waiting for hardware " + "interrupt.\n", mmc_hostname(host->mmc)); + sdhci_dumpregs(host); + + if (host->data) { + host->data->error = -ETIMEDOUT; + sdhci_finish_data(host); + } else { + if (host->cmd) + host->cmd->error = -ETIMEDOUT; + else + host->mrq->cmd->error = -ETIMEDOUT; + + tasklet_schedule(&host->finish_tasklet); + } + } + + mmiowb(); + spin_unlock_irqrestore(&host->lock, flags); +} + +/*****************************************************************************\ + * * + * Interrupt handling * + * * +\*****************************************************************************/ + +static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) +{ + BUG_ON(intmask == 0); + + if (!host->cmd) { + printk(KERN_ERR "%s: Got command interrupt 0x%08x even " + "though no command operation was in progress.\n", + mmc_hostname(host->mmc), (unsigned)intmask); + sdhci_dumpregs(host); + return; + } + + if (intmask & SDHCI_INT_TIMEOUT) + host->cmd->error = -ETIMEDOUT; + else if (intmask & (SDHCI_INT_CRC | SDHCI_INT_END_BIT | + SDHCI_INT_INDEX)) + host->cmd->error = -EILSEQ; + + if (host->cmd->error) + tasklet_schedule(&host->finish_tasklet); + else if (intmask & SDHCI_INT_RESPONSE) + sdhci_finish_command(host); +} + +static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) +{ + u32 intsave = 0; + + BUG_ON(intmask == 0); + + if (!host->data) { + /* + * A data end interrupt is sent together with the response + * for the stop command. + */ + if (intmask & SDHCI_INT_DATA_END) + return; + + printk(KERN_ERR "%s: Got data interrupt 0x%08x even " + "though no data operation was in progress.\n", + mmc_hostname(host->mmc), (unsigned)intmask); + sdhci_dumpregs(host); + return; + } + + /* Mask the INT */ + intsave = readl(host->ioaddr + SDHCI_INT_ENABLE); + writel(intsave & (~(intmask & SDHCI_INT_DATA_RE_MASK)), + host->ioaddr + SDHCI_INT_ENABLE); + + if (intmask & SDHCI_INT_DATA_TIMEOUT) + host->data->error = -ETIMEDOUT; + else if (intmask & (SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_END_BIT)) + host->data->error = -EILSEQ; + + if (host->data->error) + sdhci_finish_data(host); + else { + if ((host->flags & SDHCI_USE_EXTERNAL_DMA) && + (host->dma_size >= mxc_wml_value)) { + /* Use DMA if transfer size is greater than fifo size */ + if (intmask & (SDHCI_INT_DATA_AVAIL | + SDHCI_INT_SPACE_AVAIL)) { + intsave &= ~SDHCI_INT_DATA_RE_MASK; + if (mxc_dma_enable(host->dma) < 0) { + printk(KERN_ERR "ENABLE SDMA ERR.\n"); + intsave |= SDHCI_INT_DATA_RE_MASK; + } + } + } else { + if (intmask & (SDHCI_INT_DATA_AVAIL | + SDHCI_INT_SPACE_AVAIL)) + sdhci_transfer_pio(host); + } + + /* + * We currently don't do anything fancy with DMA + * boundaries, but as we can't disable the feature + * we need to at least restart the transfer. + */ + if ((intmask & SDHCI_INT_DMA_END) && + (!(intmask & SDHCI_INT_DATA_END))) + writel(readl(host->ioaddr + SDHCI_DMA_ADDRESS), + host->ioaddr + SDHCI_DMA_ADDRESS); + + if (intmask & SDHCI_INT_DATA_END) { + if (host->data->flags & MMC_DATA_READ) + writel(readl(host->ioaddr + SDHCI_CLOCK_CONTROL) + & ~SDHCI_CLOCK_HLK_EN, + host->ioaddr + SDHCI_CLOCK_CONTROL); + if (host->cmd) { + /* + * Data managed to finish before the + * command completed. Make sure we do + * things in the proper order. + */ + host->data_early = 1; + } else { + + if (host->plat_data->vendor_ver + < ESDHC_VENDOR_V22) { + /* + * There are the DATA END INT when + * writing is not complete. Double + * check on it. TO2 has been fixed it. + */ + intmask = readl(host->ioaddr + + SDHCI_PRESENT_STATE); + if (intmask & SDHCI_DATA_ACTIVE) + goto data_irq_out; + } + sdhci_finish_data(host); + } + } + } + data_irq_out: + /* Enable the INT */ + writel(intsave, host->ioaddr + SDHCI_INT_ENABLE); +} + +/*! +* This function is called by DMA Interrupt Service Routine to indicate +* requested DMA transfer is completed. +* +* @param devid pointer to device specific structure +* @param error any DMA error +* @param cnt amount of data that was transferred +*/ +static void sdhci_dma_irq(void *devid, int error, unsigned int cnt) +{ + u32 intsave = 0; + int ret; + struct sdhci_host *host = devid; + + DBG("%s: error: %d Transferred bytes:%d\n", DRIVER_NAME, error, cnt); + if (host->flags & SDHCI_USE_EXTERNAL_DMA) { + /* + * Stop the DMA transfer here, the data_irq would be called + * to process the others + */ + ret = mxc_dma_disable(host->dma); + if (ret < 0) + printk(KERN_ERR "Disable dma channel err %d\n", ret); + + if (error) { + DBG("Error in DMA transfer\n"); + return; + } + intsave = readl(host->ioaddr + SDHCI_INT_ENABLE); + intsave |= SDHCI_INT_DATA_RE_MASK; + writel(intsave, host->ioaddr + SDHCI_INT_ENABLE); + } +} + +/* woke queue handler func */ +static void esdhc_cd_callback(struct work_struct *work) +{ + unsigned long flags; + unsigned int cd_status = 0; + struct sdhci_host *host = container_of(work, struct sdhci_host, cd_wq); + + cd_status = host->plat_data->status(host->mmc->parent); + if (cd_status) + host->flags &= ~SDHCI_CD_PRESENT; + else + host->flags |= SDHCI_CD_PRESENT; + /* Detect there is a card in slot or not */ + DBG("cd_status=%d %s\n", cd_status, + (host->flags & SDHCI_CD_PRESENT) ? "inserted" : "removed"); + + spin_lock_irqsave(&host->lock, flags); + + if (!(host->flags & SDHCI_CD_PRESENT)) { + printk(KERN_INFO + "%s: Card removed and resetting controller.\n", + mmc_hostname(host->mmc)); + sdhci_init(host); + if (host->mrq) { + printk(KERN_ERR + "%s: Card removed during transfer!\n", + mmc_hostname(host->mmc)); + printk(KERN_ERR + "%s: Resetting controller.\n", + mmc_hostname(host->mmc)); + + sdhci_reset(host, SDHCI_RESET_CMD); + sdhci_reset(host, SDHCI_RESET_DATA); + + host->mrq->cmd->error = -ENOMEDIUM; + tasklet_schedule(&host->finish_tasklet); + } + } + + spin_unlock_irqrestore(&host->lock, flags); + + mmc_detect_change(host->mmc, msecs_to_jiffies(500)); + + if (!host->detect_irq) + return; + do { + cd_status = host->plat_data->status(host->mmc->parent); + if (cd_status) + set_irq_type(host->detect_irq, IRQF_TRIGGER_FALLING); + else + set_irq_type(host->detect_irq, IRQF_TRIGGER_RISING); + } while (cd_status != host->plat_data->status(host->mmc->parent)); +} + +/*! +* Card detection interrupt service routine registered to handle +* the SDHC interrupts. This interrupt routine handles card +* insertion and card removal interrupts. +* +* @param irq the interrupt number +* @param devid driver private data +* +* @return The function returns \b IRQ_RETVAL(1) +*/ +static irqreturn_t sdhci_cd_irq(int irq, void *dev_id) +{ + struct sdhci_host *host = dev_id; + + schedule_work(&host->cd_wq); + return IRQ_HANDLED; +} + +static irqreturn_t sdhci_irq(int irq, void *dev_id) +{ + irqreturn_t result; + struct sdhci_host *host = dev_id; + u32 intmask; + int cardint = 0; + + spin_lock(&host->lock); + + intmask = readl(host->ioaddr + SDHCI_INT_STATUS); + + if (!intmask || intmask == 0xffffffff) { + result = IRQ_NONE; + goto out; + } + + DBG("*** %s got interrupt: 0x%08x\n", mmc_hostname(host->mmc), intmask); + + if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) { + writel(intmask & + (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE), + host->ioaddr + SDHCI_INT_STATUS); + tasklet_schedule(&host->card_tasklet); + } + + intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE); + + if (intmask & SDHCI_INT_CMD_MASK) { + writel(intmask & SDHCI_INT_CMD_MASK, + host->ioaddr + SDHCI_INT_STATUS); + sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK); + } + + if (intmask & SDHCI_INT_DATA_MASK) { + writel(intmask & SDHCI_INT_DATA_MASK, + host->ioaddr + SDHCI_INT_STATUS); + if (cpu_is_mx35_rev(CHIP_REV_2_0) < 0) { + if (! + (readl(host->ioaddr + SDHCI_TRANSFER_MODE) & + SDHCI_TRNS_READ)) + intmask &= ~SDHCI_INT_DATA_END_BIT; + } + sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK); + } + + intmask &= ~(SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK); + + intmask &= ~SDHCI_INT_ERROR; + + if (intmask & SDHCI_INT_BUS_POWER) { + printk(KERN_ERR "%s: Card is consuming too much power!\n", + mmc_hostname(host->mmc)); + writel(SDHCI_INT_BUS_POWER, host->ioaddr + SDHCI_INT_STATUS); + } + + intmask &= ~SDHCI_INT_BUS_POWER; + + if (intmask & SDHCI_INT_CARD_INT) + cardint = readl(host->ioaddr + SDHCI_SIGNAL_ENABLE) & + SDHCI_INT_CARD_INT; + + intmask &= ~SDHCI_INT_CARD_INT; + + if (intmask) { + printk(KERN_ERR "%s: Unexpected interrupt 0x%08x.\n", + mmc_hostname(host->mmc), intmask); + sdhci_dumpregs(host); + + writel(intmask, host->ioaddr + SDHCI_INT_STATUS); + } + + result = IRQ_HANDLED; + + mmiowb(); + out: + spin_unlock(&host->lock); + + /* + * We have to delay this as it calls back into the driver. + */ + if (cardint) + mmc_signal_sdio_irq(host->mmc); + + return result; +} + +/*****************************************************************************\ + * * + * Suspend/resume * + * * +\*****************************************************************************/ + +#ifdef CONFIG_PM + +static int sdhci_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct sdhci_chip *chip; + int i, ret; + + chip = dev_get_drvdata(&pdev->dev); + 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; + } + } + + for (i = 0; i < chip->num_slots; i++) { + if (!chip->hosts[i]) + continue; + free_irq(chip->hosts[i]->irq, chip->hosts[i]); + } + + gpio_sdhc_inactive(pdev->id); + + return 0; +} + +static int sdhci_resume(struct platform_device *pdev) +{ + struct sdhci_chip *chip; + int i, ret; + unsigned int cd_status = 0; + + chip = dev_get_drvdata(&pdev->dev); + if (!chip) + return 0; + + DBG("Resuming...\n"); + + gpio_sdhc_active(pdev->id); + + for (i = 0; i < chip->num_slots; i++) { + if (!chip->hosts[i]) + continue; + 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(); + + cd_status = chip->hosts[i]->plat_data->status(chip->hosts[i]-> + mmc->parent); + if (cd_status) + chip->hosts[i]->flags &= ~SDHCI_CD_PRESENT; + else + chip->hosts[i]->flags |= SDHCI_CD_PRESENT; + + ret = mmc_resume_host(chip->hosts[i]->mmc); + if (ret) + return ret; + } + + return 0; +} + +#else /* CONFIG_PM */ + +#define sdhci_suspend NULL +#define sdhci_resume NULL + +#endif /* CONFIG_PM */ + +/*****************************************************************************\ + * * + * Device probing/removal * + * * +\*****************************************************************************/ + +static int __devinit sdhci_probe_slot(struct platform_device + *pdev, int slot) +{ + struct mxc_mmc_platform_data *mmc_plat = pdev->dev.platform_data; + int ret = 0; + unsigned int version, caps; + struct sdhci_chip *chip; + struct mmc_host *mmc; + struct sdhci_host *host; + mxc_dma_device_t dev_id = 0; + + if (!mmc_plat) + return -EINVAL; + + chip = dev_get_drvdata(&pdev->dev); + BUG_ON(!chip); + + mmc = mmc_alloc_host(sizeof(struct sdhci_host), &pdev->dev); + if (!mmc) + return -ENOMEM; + + host = mmc_priv(mmc); + host->mmc = mmc; + host->id = pdev->id; + host->dma = -1; + host->plat_data = mmc_plat; + if (!host->plat_data) { + ret = -EINVAL; + goto out0; + } + + host->chip = chip; + chip->hosts[slot] = host; + + /* Get pwr supply for eSDHC */ + if (NULL != mmc_plat->power_mmc) { + host->regulator_mmc = + regulator_get(&pdev->dev, mmc_plat->power_mmc); + if (IS_ERR(host->regulator_mmc)) { + ret = PTR_ERR(host->regulator_mmc); + goto out1; + } + if (regulator_enable(host->regulator_mmc) == 0) { + DBG("mmc power on\n"); + msleep(1); + } + } + + /* Active the eSDHC bus */ + gpio_sdhc_active(pdev->id); + + /* Get the SDHC clock from clock system APIs */ + host->clk = clk_get(&pdev->dev, mmc_plat->clock_mmc); + if (NULL == host->clk) + printk(KERN_ERR "MXC MMC can't get clock.\n"); + DBG("SDHC:%d clock:%lu\n", pdev->id, clk_get_rate(host->clk)); + + host->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!host->res) { + ret = -ENOMEM; + goto out2; + } + host->irq = platform_get_irq(pdev, 0); + if (!host->irq) { + ret = -ENOMEM; + goto out2; + } + host->detect_irq = platform_get_irq(pdev, 1); + if (!host->detect_irq) { + host->flags &= ~SDHCI_CD_PRESENT; + if ((pdev->id >= 0) && (pdev->id < MXC_SDHCI_NUM)) + mxc_fix_chips[pdev->id] = chip; + goto no_detect_irq; + } + + do { + ret = host->plat_data->status(host->mmc->parent); + if (ret) + set_irq_type(host->detect_irq, IRQF_TRIGGER_FALLING); + else + set_irq_type(host->detect_irq, IRQF_TRIGGER_RISING); + } while (ret != host->plat_data->status(host->mmc->parent)); + + ret = host->plat_data->status(host->mmc->parent); + if (ret) + host->flags &= ~SDHCI_CD_PRESENT; + else + host->flags |= SDHCI_CD_PRESENT; + + DBG("slot %d at 0x%x, irq %d\n", slot, host->res->start, host->irq); + no_detect_irq: + if (!request_mem_region(host->res->start, + host->res->end - + host->res->start + 1, pdev->name)) { + printk(KERN_ERR "request_mem_region failed\n"); + ret = -ENOMEM; + goto out2; + } + host->ioaddr = (void *)ioremap(host->res->start, host->res->end - + host->res->start + 1); + if (!host->ioaddr) { + ret = -ENOMEM; + goto out3; + } + + sdhci_reset(host, SDHCI_RESET_ALL); + + version = readl(host->ioaddr + SDHCI_HOST_VERSION); + host->plat_data->vendor_ver = (version & SDHCI_VENDOR_VER_MASK) >> + SDHCI_VENDOR_VER_SHIFT; + version = (version & SDHCI_SPEC_VER_MASK) >> SDHCI_SPEC_VER_SHIFT; + if (version != 1) { + printk(KERN_ERR "%s: Unknown controller version (%d). " + "You may experience problems.\n", mmc_hostname(mmc), + version); + } + + caps = readl(host->ioaddr + SDHCI_CAPABILITIES); + + if (chip->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 if (chip-> + quirks & (SDHCI_QUIRK_INTERNAL_ADVANCED_DMA | + SDHCI_QUIRK_INTERNAL_SIMPLE_DMA)) + host->flags |= SDHCI_USE_DMA; + else if (chip->quirks & (SDHCI_QUIRK_EXTERNAL_DMA_MODE)) + host->flags |= SDHCI_USE_EXTERNAL_DMA; + else + host->flags &= ~SDHCI_USE_DMA; + + /* + * These definitions of eSDHC are not compatible with the SD Host + * Controller Spec v2.0 + */ + host->min_clk = mmc_plat->min_clk; + host->max_clk = mmc_plat->max_clk; + host->timeout_clk = 1024 * 1000; /* Just set the value temply. */ + + /* + * Set host parameters. + */ + mmc->ops = &sdhci_ops; + mmc->f_min = host->min_clk; + mmc->f_max = host->max_clk; + mmc->caps = MMC_CAP_SDIO_IRQ; + mmc->caps |= mmc_plat->caps; + + if (caps & SDHCI_CAN_DO_HISPD) + mmc->caps |= MMC_CAP_SD_HIGHSPEED; + + mmc->ocr_avail = mmc_plat->ocr_mask; + if (caps & SDHCI_CAN_VDD_330) + mmc->ocr_avail |= MMC_VDD_32_33 | MMC_VDD_33_34; + if (caps & SDHCI_CAN_VDD_300) + mmc->ocr_avail |= MMC_VDD_29_30 | MMC_VDD_30_31; + if (caps & SDHCI_CAN_VDD_180) + mmc->ocr_avail |= MMC_VDD_165_195; + + if (mmc->ocr_avail == 0) { + printk(KERN_ERR "%s: Hardware doesn't report any " + "support voltages.\n", mmc_hostname(mmc)); + ret = -ENODEV; + goto out3; + } + + spin_lock_init(&host->lock); + + /* + * Maximum number of segments. Hardware cannot do scatter lists. + */ + if (host->flags & SDHCI_USE_DMA) + mmc->max_hw_segs = 1; + else + mmc->max_hw_segs = 16; + mmc->max_phys_segs = 16; + + /* + * Maximum number of sectors in one transfer. Limited by DMA boundary + * size (512KiB). + */ + if (host->flags & SDHCI_USE_EXTERNAL_DMA) + mmc->max_req_size = 32 * 1024; + else + mmc->max_req_size = 524288; + + /* + * Maximum segment size. Could be one segment with the maximum number + * of bytes. + */ + mmc->max_seg_size = mmc->max_req_size; + + /* + * Maximum block size. This varies from controller to controller and + * is specified in the capabilities register. + */ + mmc->max_blk_size = + (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT; + if (mmc->max_blk_size > 3) { + printk(KERN_WARNING "%s: Invalid maximum block size, " + "assuming 512 bytes\n", mmc_hostname(mmc)); + mmc->max_blk_size = 512; + } else + mmc->max_blk_size = 512 << mmc->max_blk_size; + + /* + * Maximum block count. + */ + mmc->max_blk_count = 65535; + + /* + * Apply a continous physical memory used for storing the ADMA + * descriptor table. + */ + if (host->flags & SDHCI_USE_DMA) { + adma_des_table = kcalloc((2 * (mmc->max_phys_segs) + 1), + sizeof(unsigned int), GFP_DMA); + if (adma_des_table == NULL) { + printk(KERN_ERR "Cannot allocate ADMA memory\n"); + ret = -ENOMEM; + goto out3; + } + } + + /* + * Init tasklets. + */ + tasklet_init(&host->card_tasklet, + sdhci_tasklet_card, (unsigned long)host); + tasklet_init(&host->finish_tasklet, + sdhci_tasklet_finish, (unsigned long)host); + + /* initialize the work queue */ + INIT_WORK(&host->cd_wq, esdhc_cd_callback); + + setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host); + + if (host->detect_irq) { + ret = request_irq(host->detect_irq, sdhci_cd_irq, 0, + pdev->name, host); + if (ret) + goto out4; + } + + ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED, pdev->name, host); + if (ret) + goto out5; + + sdhci_init(host); + + if (host->flags & SDHCI_USE_EXTERNAL_DMA) { + /* Apply the 1-bit SDMA channel. */ + if (host->id == 0) + dev_id = MXC_DMA_MMC1_WIDTH_1; + else + dev_id = MXC_DMA_MMC2_WIDTH_1; + host->dma = mxc_dma_request(dev_id, "MXC MMC"); + if (host->dma < 0) { + DBG("Cannot allocate MMC DMA channel\n"); + goto out6; + } + mxc_dma_callback_set(host->dma, sdhci_dma_irq, (void *)host); + } +#ifdef CONFIG_MMC_DEBUG + sdhci_dumpregs(host); +#endif + + mmiowb(); + + if (mmc_add_host(mmc) < 0) + goto out6; + if (host->flags & SDHCI_USE_EXTERNAL_DMA) + printk(KERN_INFO "%s: SDHCI detect irq %d irq %d %s\n", + mmc_hostname(mmc), host->detect_irq, host->irq, + "EXTERNAL DMA"); + else + printk(KERN_INFO "%s: SDHCI detect irq %d irq %d %s\n", + mmc_hostname(mmc), host->detect_irq, host->irq, + (host->flags & SDHCI_USE_DMA) ? "INTERNAL DMA" : "PIO"); + + return 0; + + out6: + free_irq(host->irq, host); + out5: + if (host->detect_irq) + free_irq(host->detect_irq, host); + else { + if ((pdev->id >= 0) && (pdev->id < MXC_SDHCI_NUM)) + mxc_fix_chips[pdev->id] = chip; + } + out4: + del_timer_sync(&host->timer); + tasklet_kill(&host->card_tasklet); + tasklet_kill(&host->finish_tasklet); + out3: + if (host->flags & SDHCI_USE_DMA) + kfree(adma_des_table); + release_mem_region(host->res->start, + host->res->end - host->res->start + 1); + out2: + clk_disable(host->clk); + host->plat_data->clk_flg = 0; + clk_put(host->clk); + out1: + gpio_sdhc_inactive(pdev->id); + out0: + mmc_free_host(mmc); + return ret; +} + +static void sdhci_remove_slot(struct platform_device *pdev, int slot) +{ + struct sdhci_chip *chip; + struct mmc_host *mmc; + struct sdhci_host *host; + + chip = dev_get_drvdata(&pdev->dev); + host = chip->hosts[slot]; + mmc = host->mmc; + + chip->hosts[slot] = NULL; + + mmc_remove_host(mmc); + + sdhci_reset(host, SDHCI_RESET_ALL); + + if (host->detect_irq) + free_irq(host->detect_irq, host); + else { + if ((pdev->id >= 0) && (pdev->id < MXC_SDHCI_NUM)) + mxc_fix_chips[pdev->id] = NULL; + } + free_irq(host->irq, host); + if (chip->quirks & SDHCI_QUIRK_EXTERNAL_DMA_MODE) { + host->flags &= ~SDHCI_USE_EXTERNAL_DMA; + mxc_dma_free(host->dma); + } + + del_timer_sync(&host->timer); + + tasklet_kill(&host->card_tasklet); + tasklet_kill(&host->finish_tasklet); + + if (host->flags & SDHCI_USE_DMA) + kfree(adma_des_table); + release_mem_region(host->res->start, + host->res->end - host->res->start + 1); + clk_disable(host->clk); + host->plat_data->clk_flg = 0; + clk_put(host->clk); + mmc_free_host(mmc); + gpio_sdhc_inactive(pdev->id); +} + +static int sdhci_probe(struct platform_device *pdev) +{ + int ret = 0, i; + u8 slots = 1; + struct sdhci_chip *chip; + + printk(KERN_INFO DRIVER_NAME ": MXC SDHCI Controller Driver. \n"); + BUG_ON(pdev == NULL); + + chip = kzalloc(sizeof(struct sdhci_chip) + + sizeof(struct sdhci_host *) * slots, GFP_KERNEL); + if (!chip) { + ret = -ENOMEM; + goto err; + } + + /* Distinguish different platform */ + if (machine_is_mx37_3ds()) { + mxc_quirks = SDHCI_QUIRK_EXTERNAL_DMA_MODE; + } else { + mxc_quirks = SDHCI_QUIRK_INTERNAL_ADVANCED_DMA | + SDHCI_QUIRK_INTERNAL_SIMPLE_DMA; + } + chip->pdev = pdev; + chip->quirks = mxc_quirks; + + if (debug_quirks) + chip->quirks = debug_quirks; + + chip->num_slots = slots; + dev_set_drvdata(&pdev->dev, 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: + dev_set_drvdata(&pdev->dev, NULL); + kfree(chip); + + err: + return ret; +} + +static int sdhci_remove(struct platform_device *pdev) +{ + int i; + struct sdhci_chip *chip; + + chip = dev_get_drvdata(&pdev->dev); + + if (chip) { + for (i = 0; i < chip->num_slots; i++) + sdhci_remove_slot(pdev, i); + + dev_set_drvdata(&pdev->dev, NULL); + + kfree(chip); + } + + return 0; +} + +static struct platform_driver sdhci_driver = { + .driver = { + .name = DRIVER_NAME, + }, + .probe = sdhci_probe, + .remove = sdhci_remove, + .suspend = sdhci_suspend, + .resume = sdhci_resume, +}; + +/*****************************************************************************\ + * * + * Driver init/exit * + * * +\*****************************************************************************/ + +static int __init sdhci_drv_init(void) +{ + printk(KERN_INFO DRIVER_NAME + ": MXC Secure Digital Host Controller Interface driver\n"); + return platform_driver_register(&sdhci_driver); +} + +static void __exit sdhci_drv_exit(void) +{ + DBG("Exiting\n"); + + platform_driver_unregister(&sdhci_driver); +} + +module_init(sdhci_drv_init); +module_exit(sdhci_drv_exit); + +module_param(debug_quirks, uint, 0444); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("MXC Secure Digital Host Controller Interface driver"); +MODULE_LICENSE("GPL"); + +MODULE_PARM_DESC(debug_quirks, "Force certain quirks."); --- linux-2.6.28.orig/drivers/mmc/host/ricoh_mmc.c +++ linux-2.6.28/drivers/mmc/host/ricoh_mmc.c @@ -11,9 +11,10 @@ /* * This is a conceptually ridiculous driver, but it is required by the way - * the Ricoh multi-function R5C832 works. This chip implements firewire - * and four different memory card controllers. Two of those controllers are - * an SDHCI controller and a proprietary MMC controller. The linux SDHCI + * the Ricoh multi-function chips (R5CXXX) work. These chips implement + * the four main memory card controllers (SD, MMC, MS, xD) and one or both + * of cardbus or firewire. It happens that they implement SD and MMC + * support as separate controllers (and PCI functions). The linux SDHCI * driver supports MMC cards but the chip detects MMC cards in hardware * and directs them to the MMC controller - so the SDHCI driver never sees * them. To get around this, we must disable the useless MMC controller. @@ -21,8 +22,10 @@ * a detection event occurs immediately, even if the MMC card is already * in the reader. * - * The relevant registers live on the firewire function, so this is unavoidably - * ugly. Such is life. + * It seems to be the case that the relevant PCI registers to deactivate the + * MMC controller live on PCI function 0, which might be the cardbus controller + * or the firewire controller, depending on the particular chip in question. As + * such, it makes what this driver has to do unavoidably ugly. Such is life. */ #include @@ -143,6 +146,7 @@ pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, fw_dev))) { if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && + PCI_FUNC(fw_dev->devfn) == 0 && pdev->bus == fw_dev->bus) { if (ricoh_mmc_disable(fw_dev) != 0) return -ENODEV; @@ -160,6 +164,7 @@ (fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) { if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && + PCI_FUNC(fw_dev->devfn) == 0 && pdev->bus == fw_dev->bus) { if (ricoh_mmc_disable(fw_dev) != 0) return -ENODEV; @@ -172,7 +177,7 @@ if (!ctrlfound) { printk(KERN_WARNING DRIVER_NAME - ": Main firewire function not found. Cannot disable controller.\n"); + ": Main Ricoh function not found. Cannot disable controller.\n"); return -ENODEV; } --- linux-2.6.28.orig/drivers/mmc/host/sdhci-pci.c +++ linux-2.6.28/drivers/mmc/host/sdhci-pci.c @@ -107,6 +107,7 @@ static const struct sdhci_pci_fixes sdhci_cafe = { .quirks = SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER | + SDHCI_QUIRK_NO_BUSY_IRQ | SDHCI_QUIRK_BROKEN_TIMEOUT_VAL, }; --- linux-2.6.28.orig/drivers/mmc/host/sdhci.h +++ linux-2.6.28/drivers/mmc/host/sdhci.h @@ -210,6 +210,8 @@ #define SDHCI_QUIRK_BROKEN_SMALL_PIO (1<<13) /* Controller supports high speed but doesn't have the caps bit set */ #define SDHCI_QUIRK_FORCE_HIGHSPEED (1<<14) +/* Controller does not provide transfer-complete interrupt when not busy */ +#define SDHCI_QUIRK_NO_BUSY_IRQ (1<<15) int irq; /* Device IRQ */ void __iomem * ioaddr; /* Mapped address */ @@ -222,6 +224,7 @@ #ifdef CONFIG_LEDS_CLASS struct led_classdev led; /* LED control */ + char led_name[32]; #endif spinlock_t lock; /* Mutex */ --- linux-2.6.28.orig/drivers/mmc/host/Kconfig +++ linux-2.6.28/drivers/mmc/host/Kconfig @@ -165,6 +165,28 @@ If unsure, or if your system has no SPI master driver, say N. +config MMC_IMX_ESDHCI + tristate "Freescale i.MX Secure Digital Host Controller Interface support" + depends on ARCH_MXC && MMC + help + This selects the Freescale i.MX Multimedia card Interface. + If you have a i.MX platform with a Multimedia Card slot, + say Y or M here. + + If unsure, say N. + +config MMC_IMX_ESDHCI_PIO_MODE + bool "Freescale i.MX Secure Digital Host Controller Interface PIO mode" + depends on MMC_IMX_ESDHCI + default n + help + This set the Freescale i.MX Multimedia card Interface to PIO mode. + If you have a i.MX platform with a Multimedia Card slot, + and want test it with PIO mode. + say Y here. + + If unsure, say N. + config MMC_S3C tristate "Samsung S3C SD/MMC Card Interface support" depends on ARCH_S3C2410 @@ -182,6 +204,7 @@ 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. + say Y or M here. To compile this driver as a module, choose M here: the module will be called sdricoh_cs. --- linux-2.6.28.orig/drivers/mmc/host/sdhci.c +++ linux-2.6.28/drivers/mmc/host/sdhci.c @@ -1286,8 +1286,11 @@ if (host->cmd->data) DBG("Cannot wait for busy signal when also " "doing a data transfer"); - else + else if (!(host->quirks & SDHCI_QUIRK_NO_BUSY_IRQ)) return; + + /* The controller does not support the end-of-busy IRQ, + * fall through and take the SDHCI_INT_RESPONSE */ } if (intmask & SDHCI_INT_RESPONSE) @@ -1718,7 +1721,9 @@ #endif #ifdef CONFIG_LEDS_CLASS - host->led.name = mmc_hostname(mmc); + snprintf(host->led_name, sizeof(host->led_name), + "%s::", mmc_hostname(mmc)); + host->led.name = host->led_name; host->led.brightness = LED_OFF; host->led.default_trigger = mmc_hostname(mmc); host->led.brightness_set = sdhci_led_control; --- linux-2.6.28.orig/drivers/mmc/host/Makefile +++ linux-2.6.28/drivers/mmc/host/Makefile @@ -12,6 +12,7 @@ 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_IMX_ESDHCI) += mx_sdhci.o obj-$(CONFIG_MMC_WBSD) += wbsd.o obj-$(CONFIG_MMC_AU1X) += au1xmmc.o obj-$(CONFIG_MMC_OMAP) += omap.o --- linux-2.6.28.orig/drivers/mmc/host/s3cmci.c +++ linux-2.6.28/drivers/mmc/host/s3cmci.c @@ -329,7 +329,7 @@ to_ptr = host->base + host->sdidata; - while ((fifo = fifo_free(host))) { + while ((fifo = fifo_free(host)) > 3) { if (!host->pio_bytes) { res = get_data_buffer(host, &host->pio_bytes, &host->pio_ptr); @@ -793,8 +793,7 @@ host->mem->start + host->sdidata); if (!setup_ok) { - s3c2410_dma_config(host->dma, 4, - (S3C2410_DCON_HWTRIG | S3C2410_DCON_CH0_SDI)); + s3c2410_dma_config(host->dma, 4, 0); s3c2410_dma_set_buffdone_fn(host->dma, s3cmci_dma_done_callback); s3c2410_dma_setflags(host->dma, S3C2410_DMAF_AUTOSTART); --- linux-2.6.28.orig/drivers/mmc/host/mx_sdhci.h +++ linux-2.6.28/drivers/mmc/host/mx_sdhci.h @@ -0,0 +1,273 @@ +/* + * linux/drivers/mmc/host/mx_sdhci.h - Secure Digital Host + * Controller Interface driver + * + * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. + * Copyright 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. + */ + +/* + * Controller registers + */ + +#define SDHCI_DMA_ADDRESS 0x00 + +#define SDHCI_BLOCK_SIZE 0x04 +#define SDHCI_MAKE_BLKSZ(dma, blksz) (((dma & 0x7) << 13) | (blksz & 0x1FFF)) + +#define SDHCI_BLOCK_COUNT 0x04 + +#define SDHCI_ARGUMENT 0x08 + +#define SDHCI_TRANSFER_MODE 0x0C +#define SDHCI_TRNS_DMA 0x00000001 +#define SDHCI_TRNS_BLK_CNT_EN 0x00000002 +#define SDHCI_TRNS_ACMD12 0x00000004 +#define SDHCI_TRNS_READ 0x00000010 +#define SDHCI_TRNS_MULTI 0x00000020 +#define SDHCI_TRNS_DPSEL 0x00200000 +#define SDHCI_TRNS_MASK 0xFFFF0000 + +#define SDHCI_COMMAND 0x0E +#define SDHCI_CMD_RESP_MASK 0x03 +#define SDHCI_CMD_CRC 0x08 +#define SDHCI_CMD_INDEX 0x10 +#define SDHCI_CMD_DATA 0x20 + +#define SDHCI_CMD_RESP_NONE 0x00 +#define SDHCI_CMD_RESP_LONG 0x01 +#define SDHCI_CMD_RESP_SHORT 0x02 +#define SDHCI_CMD_RESP_SHORT_BUSY 0x03 + +#define SDHCI_MAKE_CMD(c, f) (((c & 0xff) << 8) | (f & 0xff)) << 16 + +#define SDHCI_RESPONSE 0x10 + +#define SDHCI_BUFFER 0x20 + +#define SDHCI_PRESENT_STATE 0x24 +#define SDHCI_CMD_INHIBIT 0x00000001 +#define SDHCI_DATA_INHIBIT 0x00000002 +#define SDHCI_DATA_ACTIVE 0x00000004 +#define SDHCI_DOING_WRITE 0x00000100 +#define SDHCI_DOING_READ 0x00000200 +#define SDHCI_SPACE_AVAILABLE 0x00000400 +#define SDHCI_DATA_AVAILABLE 0x00000800 +#define SDHCI_CARD_PRESENT 0x00010000 +#define SDHCI_WRITE_PROTECT 0x00080000 +#define SDHCI_DAT0_IDLE 0x01000000 +#define SDHCI_CARD_INT_MASK 0x0E000000 +#define SDHCI_CARD_INT_ID 0x0C000000 + +#define SDHCI_HOST_CONTROL 0x28 +#define SDHCI_CTRL_LED 0x00000001 +#define SDHCI_CTRL_4BITBUS 0x00000002 +#define SDHCI_CTRL_8BITBUS 0x00000004 +#define SDHCI_CTRL_HISPD 0x00000004 +#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_CTRL_D3CD 0x00000008 +#define SDHCI_CTRL_ADMA 0x00000100 +/* wake up control */ +#define SDHCI_CTRL_WECINS 0x04000000 + +#define SDHCI_POWER_CONTROL 0x29 +#define SDHCI_POWER_ON 0x01 +#define SDHCI_POWER_180 0x0A +#define SDHCI_POWER_300 0x0C +#define SDHCI_POWER_330 0x0E + +#define SDHCI_BLOCK_GAP_CONTROL 0x2A + +#define SDHCI_WAKE_UP_CONTROL 0x2B + +#define SDHCI_CLOCK_CONTROL 0x2C +#define SDHCI_DIVIDER_SHIFT 8 +#define SDHCI_CLOCK_SD_EN 0x00000008 +#define SDHCI_CLOCK_PER_EN 0x00000004 +#define SDHCI_CLOCK_HLK_EN 0x00000002 +#define SDHCI_CLOCK_IPG_EN 0x00000001 +#define SDHCI_CLOCK_MASK 0x0000FFFF + +#define SDHCI_TIMEOUT_CONTROL 0x2E + +#define SDHCI_SOFTWARE_RESET 0x2F +#define SDHCI_RESET_ALL 0x01 +#define SDHCI_RESET_CMD 0x02 +#define SDHCI_RESET_DATA 0x04 + +#define SDHCI_INT_STATUS 0x30 +#define SDHCI_INT_ENABLE 0x34 +#define SDHCI_SIGNAL_ENABLE 0x38 +#define SDHCI_INT_RESPONSE 0x00000001 +#define SDHCI_INT_DATA_END 0x00000002 +#define SDHCI_INT_DMA_END 0x00000008 +#define SDHCI_INT_SPACE_AVAIL 0x00000010 +#define SDHCI_INT_DATA_AVAIL 0x00000020 +#define SDHCI_INT_CARD_INSERT 0x00000040 +#define SDHCI_INT_CARD_REMOVE 0x00000080 +#define SDHCI_INT_CARD_INT 0x00000100 +#define SDHCI_INT_ERROR 0x00008000 +#define SDHCI_INT_TIMEOUT 0x00010000 +#define SDHCI_INT_CRC 0x00020000 +#define SDHCI_INT_END_BIT 0x00040000 +#define SDHCI_INT_INDEX 0x00080000 +#define SDHCI_INT_DATA_TIMEOUT 0x00100000 +#define SDHCI_INT_DATA_CRC 0x00200000 +#define SDHCI_INT_DATA_END_BIT 0x00400000 +#define SDHCI_INT_BUS_POWER 0x00800000 +#define SDHCI_INT_ACMD12ERR 0x01000000 +#define SDHCI_INT_ADMA_ERROR 0x10000000 + +#define SDHCI_INT_NORMAL_MASK 0x00007FFF +#define SDHCI_INT_ERROR_MASK 0xFFFF8000 + +#define SDHCI_INT_CMD_MASK (SDHCI_INT_RESPONSE | SDHCI_INT_TIMEOUT | \ + SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX) +#define SDHCI_INT_DATA_MASK (SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \ + SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \ + SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \ + SDHCI_INT_DATA_END_BIT | SDHCI_INT_ADMA_ERROR) +#define SDHCI_INT_DATA_RE_MASK (SDHCI_INT_DMA_END | \ + SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL) + +#define SDHCI_ACMD12_ERR 0x3C + +/* 3E-3F reserved */ + +#define SDHCI_CAPABILITIES 0x40 +#define SDHCI_TIMEOUT_CLK_MASK 0x0000003F +#define SDHCI_TIMEOUT_CLK_SHIFT 0 +#define SDHCI_TIMEOUT_CLK_UNIT 0x00000080 +#define SDHCI_CLOCK_BASE_MASK 0x00003F00 +#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 */ +#define SDHCI_WML 0x44 +#define SDHCI_WML_4_WORDS 0x00040004 +#define SDHCI_WML_16_WORDS 0x00100010 +#define SDHCI_WML_64_WORDS 0x00400040 +#define SDHCI_WML_128_WORDS 0x00800080 + +#define SDHCI_MAX_CURRENT 0x48 + +/* 4C-4F reserved for more max current */ + +#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 */ + +/* ADMA Addr Descriptor Attribute Filed */ +enum { + FSL_ADMA_DES_ATTR_VALID = 0x01, + FSL_ADMA_DES_ATTR_END = 0x02, + FSL_ADMA_DES_ATTR_INT = 0x04, + FSL_ADMA_DES_ATTR_SET = 0x10, + FSL_ADMA_DES_ATTR_TRAN = 0x20, + FSL_ADMA_DES_ATTR_LINK = 0x30, +}; + +#define SDHCI_HOST_VERSION 0xFC +#define SDHCI_VENDOR_VER_MASK 0xFF00 +#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 +#define ESDHC_VENDOR_V22 0x12 + +struct sdhci_chip; + +struct sdhci_host { + struct sdhci_chip *chip; + struct mmc_host *mmc; /* MMC structure */ + +#ifdef CONFIG_LEDS_CLASS + struct led_classdev led; /* LED control */ +#endif + + spinlock_t lock; /* Mutex */ + + 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_USE_EXTERNAL_DMA (1<<2) /* Use the External DMA */ +#define SDHCI_CD_PRESENT (1<<8) /* CD present */ +#define SDHCI_WP_ENABLED (1<<9) /* Write protect */ + + unsigned int max_clk; /* Max possible freq (MHz) */ + unsigned int min_clk; /* Min possible freq (MHz) */ + unsigned int timeout_clk; /* Timeout freq (KHz) */ + + unsigned int clock; /* Current clock (MHz) */ + unsigned short power; /* Current voltage */ + struct regulator *regulator_mmc; /*! Regulator */ + + struct mmc_request *mrq; /* Current request */ + struct mmc_command *cmd; /* Current command */ + struct mmc_data *data; /* Current data request */ + unsigned int data_early:1; /* Data finished before cmd */ + + unsigned int id; /* Id for SD/MMC block */ + int mode; /* SD/MMC mode */ + int dma; /* DMA channel number. */ + unsigned int dma_size; /* Number of Bytes in DMA */ + unsigned int dma_len; /* Length of the s-g list */ + unsigned int dma_dir; /* DMA transfer direction */ + + struct scatterlist *cur_sg; /* We're working on this */ + int num_sg; /* Entries left */ + int offset; /* Offset into current sg */ + int remain; /* Bytes left in current */ + + struct resource *res; /* IO map memory */ + int irq; /* Device IRQ */ + int detect_irq; /* Card Detect IRQ number. */ + int sdio_enable; /* sdio interrupt enable number. */ + struct clk *clk; /* Clock id */ + 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 work_struct cd_wq; /* card detection work queue */ + /* Platform specific data */ + struct mxc_mmc_platform_data *plat_data; + + struct timer_list timer; /* Timer for timeouts */ +}; + +struct sdhci_chip { + struct platform_device *pdev; + + unsigned long quirks; + + int num_slots; /* Slots on controller */ + struct sdhci_host *hosts[0]; /* Pointers to hosts */ +}; --- linux-2.6.28.orig/drivers/connector/connector.c +++ linux-2.6.28/drivers/connector/connector.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -35,6 +36,7 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Evgeniy Polyakov "); MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector."); +MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_CONNECTOR); static u32 cn_idx = CN_IDX_CONNECTOR; static u32 cn_val = CN_VAL_CONNECTOR; --- linux-2.6.28.orig/drivers/xen/balloon.c +++ linux-2.6.28/drivers/xen/balloon.c @@ -488,7 +488,7 @@ if (!capable(CAP_SYS_ADMIN)) return -EPERM; - target_bytes = memparse(buf, &endchar); + target_bytes = simple_strtoull(buf, &endchar, 0) * 1024; balloon_set_new_target(target_bytes >> PAGE_SHIFT); @@ -498,8 +498,39 @@ static SYSDEV_ATTR(target_kb, S_IRUGO | S_IWUSR, show_target_kb, store_target_kb); + +static ssize_t show_target(struct sys_device *dev, struct sysdev_attribute *attr, + char *buf) +{ + return sprintf(buf, "%llu\n", + (u64)balloon_stats.target_pages << PAGE_SHIFT); +} + +static ssize_t store_target(struct sys_device *dev, + struct sysdev_attribute *attr, + const char *buf, + size_t count) +{ + char *endchar; + unsigned long long target_bytes; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + target_bytes = memparse(buf, &endchar); + + balloon_set_new_target(target_bytes >> PAGE_SHIFT); + + return count; +} + +static SYSDEV_ATTR(target, S_IRUGO | S_IWUSR, + show_target, store_target); + + static struct sysdev_attribute *balloon_attrs[] = { &attr_target_kb, + &attr_target, }; static struct attribute *balloon_info_attrs[] = { --- linux-2.6.28.orig/drivers/input/mousedev.c +++ linux-2.6.28/drivers/input/mousedev.c @@ -29,6 +29,7 @@ MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("Mouse (ExplorerPS/2) device interfaces"); MODULE_LICENSE("GPL"); +MODULE_ALIAS_CHARDEV(INPUT_MAJOR, MOUSEDEV_MIX); #ifndef CONFIG_INPUT_MOUSEDEV_SCREEN_X #define CONFIG_INPUT_MOUSEDEV_SCREEN_X 1024 @@ -1066,6 +1067,8 @@ PSMOUSE_MINOR, "psaux", &mousedev_fops }; static int psaux_registered; + +MODULE_ALIAS_MISCDEV(PSMOUSE_MINOR); #endif static int __init mousedev_init(void) --- linux-2.6.28.orig/drivers/input/mouse/elantech.c +++ linux-2.6.28/drivers/input/mouse/elantech.c @@ -542,7 +542,7 @@ ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) { - pr_err("elantech.c: sending Elantech magic knock failed.\n"); + pr_debug("elantech.c: sending Elantech magic knock failed.\n"); return -1; } @@ -551,8 +551,27 @@ * set of magic numbers */ if (param[0] != 0x3c || param[1] != 0x03 || param[2] != 0xc8) { - pr_info("elantech.c: unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n", - param[0], param[1], param[2]); + pr_debug("elantech.c: " + "unexpected magic knock result 0x%02x, 0x%02x, 0x%02x.\n", + param[0], param[1], param[2]); + return -1; + } + + /* + * Query touchpad's firmware version and see if it reports known + * value to avoid mis-detection. Logitech mice are known to respond + * to Elantech magic knock and there might be more. + */ + if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { + pr_debug("elantech.c: failed to query firmware version.\n"); + return -1; + } + + pr_debug("elantech.c: Elantech version query result 0x%02x, 0x%02x, 0x%02x.\n", + param[0], param[1], param[2]); + + if (param[0] == 0 || param[1] != 0) { + pr_debug("elantech.c: Probably not a real Elantech touchpad. Aborting.\n"); return -1; } @@ -600,8 +619,7 @@ int i, error; unsigned char param[3]; - etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL); - psmouse->private = etd; + psmouse->private = etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL); if (!etd) return -1; @@ -610,14 +628,12 @@ etd->parity[i] = etd->parity[i & (i - 1)] ^ 1; /* - * Find out what version hardware this is + * Do the version query again so we can store the result */ if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { pr_err("elantech.c: failed to query firmware version.\n"); goto init_fail; } - pr_info("elantech.c: Elantech version query result 0x%02x, 0x%02x, 0x%02x.\n", - param[0], param[1], param[2]); etd->fw_version_maj = param[0]; etd->fw_version_min = param[2]; --- linux-2.6.28.orig/drivers/input/mouse/synaptics.c +++ linux-2.6.28/drivers/input/mouse/synaptics.c @@ -60,11 +60,21 @@ return 0; } +static int synaptics_resume_reset = 1; +module_param(synaptics_resume_reset, bool, 0); +MODULE_PARM_DESC(synaptics_resume_reset, + "Enable reset on resume for Synaptics"); + int synaptics_detect(struct psmouse *psmouse, int set_properties) { struct ps2dev *ps2dev = &psmouse->ps2dev; unsigned char param[4]; + if (synaptics_resume_reset) { + printk(KERN_INFO "synaptics was reset on resume, see synaptics_resume_reset if you have trouble on resume\n"); + psmouse_reset(psmouse); + } + param[0] = 0; ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); --- linux-2.6.28.orig/drivers/input/mouse/alps.c +++ linux-2.6.28/drivers/input/mouse/alps.c @@ -422,7 +422,8 @@ static int alps_reconnect(struct psmouse *psmouse) { - psmouse_reset(psmouse); + /* UBUNTU: Causes lockups on resume */ + /* psmouse_reset(psmouse); */ if (alps_hw_init(psmouse, NULL)) return -1; --- linux-2.6.28.orig/drivers/input/keyboard/Kconfig +++ linux-2.6.28/drivers/input/keyboard/Kconfig @@ -268,6 +268,13 @@ To compile this driver as a module, choose M here: the module will be called pxa27x_keypad. +config KEYBOARD_MXC + tristate "MXC Keypad Driver" + depends on ARCH_MXC + help + This is the Keypad driver for the Freescale MXC application + processors. + config KEYBOARD_AAED2000 tristate "AAED-2000 keyboard" depends on MACH_AAED2000 --- linux-2.6.28.orig/drivers/input/keyboard/Makefile +++ linux-2.6.28/drivers/input/keyboard/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_KEYBOARD_TOSA) += tosakbd.o obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o +obj-$(CONFIG_KEYBOARD_MXC) += mxc_keyb.o obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o --- linux-2.6.28.orig/drivers/input/keyboard/mxc_keyb.c +++ linux-2.6.28/drivers/input/keyboard/mxc_keyb.c @@ -0,0 +1,1036 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @file mxc_keyb.c + * + * @brief Driver for the Freescale Semiconductor MXC keypad port. + * + * The keypad driver is designed as a standard Input driver which interacts + * with low level keypad port hardware. Upon opening, the Keypad driver + * initializes the keypad port. When the keypad interrupt happens the driver + * calles keypad polling timer and scans the keypad matrix for key + * press/release. If all key press/release happened it comes out of timer and + * waits for key press interrupt. The scancode for key press and release events + * are passed to Input subsytem. + * + * @ingroup keypad + */ + +/*! + * Comment KPP_DEBUG to disable debug messages + */ +#define KPP_DEBUG 0 + +#if KPP_DEBUG +#define DEBUG +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Module header file + */ +#include "mxc_keyb.h" + +/*! + * This structure holds the keypad private data structure. + */ +static struct keypad_priv kpp_dev; + +/*! Indicates if the key pad device is enabled. */ +static unsigned int key_pad_enabled; + +/*! Input device structure. */ +static struct input_dev *mxckbd_dev = NULL; + +/*! KPP clock handle. */ +static struct clk *kpp_clk; + +/*! This static variable indicates whether a key event is pressed/released. */ +static unsigned short KPress; + +/*! cur_rcmap and prev_rcmap array is used to detect key press and release. */ +static unsigned short *cur_rcmap; /* max 64 bits (8x8 matrix) */ +static unsigned short *prev_rcmap; + +/*! + * Debounce polling period(10ms) in system ticks. + */ +static unsigned short KScanRate = (10 * HZ) / 1000; + +static struct keypad_data *keypad; + +static int has_leaning_key; +/*! + * These arrays are used to store press and release scancodes. + */ +static short **press_scancode; +static short **release_scancode; + +static const unsigned short *mxckpd_keycodes; +static unsigned short mxckpd_keycodes_size; + +#define press_left_code 30 +#define press_right_code 29 +#define press_up_code 28 +#define press_down_code 27 + +#define rel_left_code 158 +#define rel_right_code 157 +#define rel_up_code 156 +#define rel_down_code 155 +/*! + * These functions are used to configure and the GPIO pins for keypad to + * activate and deactivate it. + */ +extern void gpio_keypad_active(void); +extern void gpio_keypad_inactive(void); + +/*! + * This function is called for generating scancodes for key press and + * release on keypad for the board. + * + * @param row Keypad row pressed on the keypad matrix. + * @param col Keypad col pressed on the keypad matrix. + * @param press Indicated key press/release. + * + * @return Key press/release Scancode. + */ +static signed short mxc_scan_matrix_leaning_key(int row, int col, int press) +{ + static unsigned first_row; + static unsigned first_set = 0, flag = 0; + signed short scancode = -1; + + if (press) { + if ((3 == col) && ((3 == row) || + (4 == row) || (5 == row) || (6 == row))) { + if (first_set == 0) { + first_set = 1; + first_row = row; + } else { + first_set = 0; + if (((first_row == 6) || (first_row == 3)) + && ((row == 6) || (row == 3))) + scancode = press_down_code; + else if (((first_row == 3) || (first_row == 5)) + && ((row == 3) || (row == 5))) + scancode = press_left_code; + else if (((first_row == 6) || (first_row == 4)) + && ((row == 6) || (row == 4))) + scancode = press_right_code; + else if (((first_row == 4) || (first_row == 5)) + && ((row == 4) || (row == 5))) + scancode = press_up_code; + KPress = 1; + kpp_dev.iKeyState = KStateUp; + pr_debug("Press (%d, %d) scan=%d Kpress=%d\n", + row, col, scancode, KPress); + } + } else { + /* + * check for other keys only + * if the cursor key presses + * are not detected may be + * this needs better logic + */ + if ((0 == (cur_rcmap[3] & BITSET(0, 3))) && + (0 == (cur_rcmap[4] & BITSET(0, 3))) && + (0 == (cur_rcmap[5] & BITSET(0, 3))) && + (0 == (cur_rcmap[6] & BITSET(0, 3)))) { + scancode = ((col * kpp_dev.kpp_rows) + row); + KPress = 1; + kpp_dev.iKeyState = KStateUp; + flag = 1; + pr_debug("Press (%d, %d) scan=%d Kpress=%d\n", + row, col, scancode, KPress); + } + } + } else { + if ((flag == 0) && (3 == col) + && ((3 == row) || (4 == row) || (5 == row) + || (6 == row))) { + if (first_set == 0) { + first_set = 1; + first_row = row; + } else { + first_set = 0; + if (((first_row == 6) || (first_row == 3)) + && ((row == 6) || (row == 3))) + scancode = rel_down_code; + else if (((first_row == 3) || (first_row == 5)) + && ((row == 3) || (row == 5))) + scancode = rel_left_code; + else if (((first_row == 6) || (first_row == 4)) + && ((row == 6) || (row == 4))) + scancode = rel_right_code; + else if (((first_row == 4) || (first_row == 5)) + && ((row == 4) || (row == 5))) + scancode = rel_up_code; + KPress = 0; + kpp_dev.iKeyState = KStateDown; + pr_debug("Release (%d, %d) scan=%d Kpress=%d\n", + row, col, scancode, KPress); + } + } else { + /* + * check for other keys only + * if the cursor key presses + * are not detected may be + * this needs better logic + */ + if ((0 == (prev_rcmap[3] & BITSET(0, 3))) && + (0 == (prev_rcmap[4] & BITSET(0, 3))) && + (0 == (cur_rcmap[5] & BITSET(0, 3))) && + (0 == (cur_rcmap[6] & BITSET(0, 3)))) { + scancode = ((col * kpp_dev.kpp_rows) + row) + + MXC_KEYRELEASE; + KPress = 0; + flag = 0; + kpp_dev.iKeyState = KStateDown; + pr_debug("Release (%d, %d) scan=%d Kpress=%d\n", + row, col, scancode, KPress); + } + } + } + return scancode; +} + +/*! + * This function is called to scan the keypad matrix to find out the key press + * and key release events. Make scancode and break scancode are generated for + * key press and key release events. + * + * The following scanning sequence are done for + * keypad row and column scanning, + * -# Write 1's to KPDR[15:8], setting column data to 1's + * -# Configure columns as totem pole outputs(for quick discharging of keypad + * capacitance) + * -# Configure columns as open-drain + * -# Write a single column to 0, others to 1. + * -# Sample row inputs and save data. Multiple key presses can be detected on + * a single column. + * -# Repeat steps the above steps for remaining columns. + * -# Return all columns to 0 in preparation for standby mode. + * -# Clear KPKD and KPKR status bit(s) by writing to a 1, + * Set the KPKR synchronizer chain by writing "1" to KRSS register, + * Clear the KPKD synchronizer chain by writing "1" to KDSC register + * + * @result Number of key pressed/released. + */ +static int mxc_kpp_scan_matrix(void) +{ + unsigned short reg_val; + int col, row; + short scancode = 0; + int keycnt = 0; /* How many keys are still pressed */ + + /* + * wmb() linux kernel function which guarantees orderings in write + * operations + */ + wmb(); + + /* save cur keypad matrix to prev */ + + memcpy(prev_rcmap, cur_rcmap, kpp_dev.kpp_rows * sizeof(prev_rcmap[0])); + memset(cur_rcmap, 0, kpp_dev.kpp_rows * sizeof(cur_rcmap[0])); + + for (col = 0; col < kpp_dev.kpp_cols; col++) { /* Col */ + /* 2. Write 1.s to KPDR[15:8] setting column data to 1.s */ + reg_val = __raw_readw(KPDR); + reg_val |= 0xff00; + __raw_writew(reg_val, KPDR); + + /* + * 3. Configure columns as totem pole outputs(for quick + * discharging of keypad capacitance) + */ + reg_val = __raw_readw(KPCR); + reg_val &= 0x00ff; + __raw_writew(reg_val, KPCR); + + udelay(2); + + /* + * 4. Configure columns as open-drain + */ + reg_val = __raw_readw(KPCR); + reg_val |= ((1 << kpp_dev.kpp_cols) - 1) << 8; + __raw_writew(reg_val, KPCR); + + /* + * 5. Write a single column to 0, others to 1. + * 6. Sample row inputs and save data. Multiple key presses + * can be detected on a single column. + * 7. Repeat steps 2 - 6 for remaining columns. + */ + + /* Col bit starts at 8th bit in KPDR */ + reg_val = __raw_readw(KPDR); + reg_val &= ~(1 << (8 + col)); + __raw_writew(reg_val, KPDR); + + /* Delay added to avoid propagating the 0 from column to row + * when scanning. */ + + udelay(5); + + /* Read row input */ + reg_val = __raw_readw(KPDR); + for (row = 0; row < kpp_dev.kpp_rows; row++) { /* sample row */ + if (TEST_BIT(reg_val, row) == 0) { + cur_rcmap[row] = BITSET(cur_rcmap[row], col); + keycnt++; + } + } + } + + /* + * 8. Return all columns to 0 in preparation for standby mode. + * 9. Clear KPKD and KPKR status bit(s) by writing to a .1., + * set the KPKR synchronizer chain by writing "1" to KRSS register, + * clear the KPKD synchronizer chain by writing "1" to KDSC register + */ + reg_val = 0x00; + __raw_writew(reg_val, KPDR); + reg_val = __raw_readw(KPDR); + reg_val = __raw_readw(KPSR); + reg_val |= KBD_STAT_KPKD | KBD_STAT_KPKR | KBD_STAT_KRSS | + KBD_STAT_KDSC; + __raw_writew(reg_val, KPSR); + + /* Check key press status change */ + + /* + * prev_rcmap array will contain the previous status of the keypad + * matrix. cur_rcmap array will contains the present status of the + * keypad matrix. If a bit is set in the array, that (row, col) bit is + * pressed, else it is not pressed. + * + * XORing these two variables will give us the change in bit for + * particular row and column. If a bit is set in XOR output, then that + * (row, col) has a change of status from the previous state. From + * the diff variable the key press and key release of row and column + * are found out. + * + * If the key press is determined then scancode for key pressed + * can be generated using the following statement: + * scancode = ((row * 8) + col); + * + * If the key release is determined then scancode for key release + * can be generated using the following statement: + * scancode = ((row * 8) + col) + MXC_KEYRELEASE; + */ + for (row = 0; row < kpp_dev.kpp_rows; row++) { + unsigned char diff; + + /* + * Calculate the change in the keypad row status + */ + diff = prev_rcmap[row] ^ cur_rcmap[row]; + + for (col = 0; col < kpp_dev.kpp_cols; col++) { + if ((diff >> col) & 0x1) { + /* There is a status change on col */ + if ((prev_rcmap[row] & BITSET(0, col)) == 0) { + /* + * Previous state is 0, so now + * a key is pressed + */ + if (has_leaning_key) { + scancode = + mxc_scan_matrix_leaning_key + (row, col, 1); + } else { + scancode = + ((row * kpp_dev.kpp_cols) + + col); + KPress = 1; + kpp_dev.iKeyState = KStateUp; + } + pr_debug("Press (%d, %d) scan=%d " + "Kpress=%d\n", + row, col, scancode, KPress); + press_scancode[row][col] = + (short)scancode; + } else { + /* + * Previous state is not 0, so + * now a key is released + */ + if (has_leaning_key) { + scancode = + mxc_scan_matrix_leaning_key + (row, col, 0); + } else { + scancode = + (row * kpp_dev.kpp_cols) + + col + MXC_KEYRELEASE; + KPress = 0; + kpp_dev.iKeyState = KStateDown; + } + + pr_debug + ("Release (%d, %d) scan=%d Kpress=%d\n", + row, col, scancode, KPress); + release_scancode[row][col] = + (short)scancode; + keycnt++; + } + } + } + } + + /* + * This switch case statement is the + * implementation of state machine of debounce + * logic for key press/release. + * The explaination of state machine is as + * follows: + * + * KStateUp State: + * This is in intial state of the state machine + * this state it checks for any key presses. + * The key press can be checked using the + * variable KPress. If KPress is set, then key + * press is identified and switches the to + * KStateFirstDown state for key press to + * debounce. + * + * KStateFirstDown: + * After debounce delay(10ms), if the KPress is + * still set then pass scancode generated to + * input device and change the state to + * KStateDown, else key press debounce is not + * satisfied so change the state to KStateUp. + * + * KStateDown: + * In this state it checks for any key release. + * If KPress variable is cleared, then key + * release is indicated and so, switch the + * state to KStateFirstUp else to state + * KStateDown. + * + * KStateFirstUp: + * After debounce delay(10ms), if the KPress is + * still reset then pass the key release + * scancode to input device and change + * the state to KStateUp else key release is + * not satisfied so change the state to + * KStateDown. + */ + switch (kpp_dev.iKeyState) { + case KStateUp: + if (KPress) { + /* First Down (must debounce). */ + kpp_dev.iKeyState = KStateFirstDown; + } else { + /* Still UP.(NO Changes) */ + kpp_dev.iKeyState = KStateUp; + } + break; + + case KStateFirstDown: + if (KPress) { + for (row = 0; row < kpp_dev.kpp_rows; row++) { + for (col = 0; col < kpp_dev.kpp_cols; col++) { + if ((press_scancode[row][col] != -1)) { + /* Still Down, so add scancode */ + scancode = + press_scancode[row][col]; + input_event(mxckbd_dev, EV_KEY, + mxckpd_keycodes + [scancode], 1); + if (mxckpd_keycodes[scancode] == + KEY_LEFTSHIFT) { + input_event(mxckbd_dev, + EV_KEY, + KEY_3, 1); + } + kpp_dev.iKeyState = KStateDown; + press_scancode[row][col] = -1; + } + } + } + } else { + /* Just a bounce */ + kpp_dev.iKeyState = KStateUp; + } + break; + + case KStateDown: + if (KPress) { + /* Still down (no change) */ + kpp_dev.iKeyState = KStateDown; + } else { + /* First Up. Must debounce */ + kpp_dev.iKeyState = KStateFirstUp; + } + break; + + case KStateFirstUp: + if (KPress) { + /* Just a bounce */ + kpp_dev.iKeyState = KStateDown; + } else { + for (row = 0; row < kpp_dev.kpp_rows; row++) { + for (col = 0; col < kpp_dev.kpp_cols; col++) { + if ((release_scancode[row][col] != -1)) { + scancode = + release_scancode[row][col]; + scancode = + scancode - MXC_KEYRELEASE; + input_event(mxckbd_dev, EV_KEY, + mxckpd_keycodes + [scancode], 0); + if (mxckpd_keycodes[scancode] == + KEY_LEFTSHIFT) { + input_event(mxckbd_dev, + EV_KEY, + KEY_3, 0); + } + kpp_dev.iKeyState = KStateUp; + release_scancode[row][col] = -1; + } + } + } + } + break; + + default: + return -EBADRQC; + break; + } + + return keycnt; +} + +/*! + * This function is called to start the timer for scanning the keypad if there + * is any key press. Currently this interval is set to 10 ms. When there are + * no keys pressed on the keypad we return back, waiting for a keypad key + * press interrupt. + * + * @param data Opaque data passed back by kernel. Not used. + */ +static void mxc_kpp_handle_timer(unsigned long data) +{ + unsigned short reg_val; + int i; + + if (key_pad_enabled == 0) { + return; + } + if (mxc_kpp_scan_matrix() == 0) { + /* + * Stop scanning and wait for interrupt. + * Enable press interrupt and disable release interrupt. + */ + __raw_writew(0x00FF, KPDR); + reg_val = __raw_readw(KPSR); + reg_val |= (KBD_STAT_KPKR | KBD_STAT_KPKD); + reg_val |= KBD_STAT_KRSS | KBD_STAT_KDSC; + __raw_writew(reg_val, KPSR); + reg_val |= KBD_STAT_KDIE; + reg_val &= ~KBD_STAT_KRIE; + __raw_writew(reg_val, KPSR); + + /* + * No more keys pressed... make sure unwanted key codes are + * not given upstairs + */ + for (i = 0; i < kpp_dev.kpp_rows; i++) { + memset(press_scancode[i], -1, + sizeof(press_scancode[0][0]) * kpp_dev.kpp_cols); + memset(release_scancode[i], -1, + sizeof(release_scancode[0][0]) * + kpp_dev.kpp_cols); + } + return; + } + + /* + * There are still some keys pressed, continue to scan. + * We shall scan again in 10 ms. This has to be tuned according + * to the requirement. + */ + kpp_dev.poll_timer.expires = jiffies + KScanRate; + kpp_dev.poll_timer.function = mxc_kpp_handle_timer; + add_timer(&kpp_dev.poll_timer); +} + +/*! + * This function is the keypad Interrupt handler. + * This function checks for keypad status register (KPSR) for key press + * and interrupt. If key press interrupt has occurred, then the key + * press interrupt in the KPSR are disabled. + * It then calls mxc_kpp_scan_matrix to check for any key pressed/released. + * If any key is found to be pressed, then a timer is set to call + * mxc_kpp_scan_matrix function for every 10 ms. + * + * @param irq The Interrupt number + * @param dev_id Driver private data + * + * @result The function returns \b IRQ_RETVAL(1) if interrupt was handled, + * returns \b IRQ_RETVAL(0) if the interrupt was not handled. + * \b IRQ_RETVAL is defined in include/linux/interrupt.h. + */ +static irqreturn_t mxc_kpp_interrupt(int irq, void *dev_id) +{ + unsigned short reg_val; + + /* Delete the polling timer */ + del_timer(&kpp_dev.poll_timer); + reg_val = __raw_readw(KPSR); + + /* Check if it is key press interrupt */ + if (reg_val & KBD_STAT_KPKD) { + /* + * Disable key press(KDIE status bit) interrupt + */ + reg_val &= ~KBD_STAT_KDIE; + __raw_writew(reg_val, KPSR); + } else { + /* spurious interrupt */ + return IRQ_RETVAL(0); + } + /* + * Check if any keys are pressed, if so start polling. + */ + mxc_kpp_handle_timer(0); + + return IRQ_RETVAL(1); +} + +/*! + * This function is called when the keypad driver is opened. + * Since keypad initialization is done in __init, nothing is done in open. + * + * @param dev Pointer to device inode + * + * @result The function always return 0 + */ +static int mxc_kpp_open(struct input_dev *dev) +{ + return 0; +} + +/*! + * This function is called close the keypad device. + * Nothing is done in this function, since every thing is taken care in + * __exit function. + * + * @param dev Pointer to device inode + * + */ +static void mxc_kpp_close(struct input_dev *dev) +{ +} + +#ifdef CONFIG_PM +/*! + * This function puts the Keypad controller in low-power mode/state. + * If Keypad is enabled as a wake source(i.e. it can resume the system + * from suspend mode), the Keypad controller doesn't enter low-power state. + * + * @param pdev the device structure used to give information on Keypad + * to suspend + * @param state the power state the device is entering + * + * @return The function always returns 0. + */ +static int mxc_kpp_suspend(struct platform_device *pdev, pm_message_t state) +{ + del_timer(&kpp_dev.poll_timer); + + if (device_may_wakeup(&pdev->dev)) { + enable_irq_wake(keypad->irq); + } else { + disable_irq(keypad->irq); + key_pad_enabled = 0; + clk_disable(kpp_clk); + gpio_keypad_inactive(); + } + + return 0; +} + +/*! + * This function brings the Keypad controller back from low-power state. + * If Keypad is enabled as a wake source(i.e. it can resume the system + * from suspend mode), the Keypad controller doesn't enter low-power state. + * + * @param pdev the device structure used to give information on Keypad + * to resume + * + * @return The function always returns 0. + */ +static int mxc_kpp_resume(struct platform_device *pdev) +{ + if (device_may_wakeup(&pdev->dev)) { + disable_irq_wake(keypad->irq); + } else { + gpio_keypad_active(); + clk_enable(kpp_clk); + key_pad_enabled = 1; + enable_irq(keypad->irq); + } + + init_timer(&kpp_dev.poll_timer); + + return 0; +} + +#else +#define mxc_kpp_suspend NULL +#define mxc_kpp_resume NULL +#endif /* CONFIG_PM */ + +/*! + * This function is called to free the allocated memory for local arrays + */ +static void mxc_kpp_free_allocated(void) +{ + + int i; + + if (press_scancode) { + for (i = 0; i < kpp_dev.kpp_rows; i++) { + if (press_scancode[i]) + kfree(press_scancode[i]); + } + kfree(press_scancode); + } + + if (release_scancode) { + for (i = 0; i < kpp_dev.kpp_rows; i++) { + if (release_scancode[i]) + kfree(release_scancode[i]); + } + kfree(release_scancode); + } + + if (cur_rcmap) + kfree(cur_rcmap); + + if (prev_rcmap) + kfree(prev_rcmap); + + if (mxckbd_dev) + input_free_device(mxckbd_dev); +} + +/*! + * This function is called during the driver binding process. + * + * @param pdev the device structure used to store device specific + * information that is used by the suspend, resume and remove + * functions. + * + * @return The function returns 0 on successful registration. Otherwise returns + * specific error code. + */ +static int mxc_kpp_probe(struct platform_device *pdev) +{ + int i, irq; + int retval; + unsigned int reg_val; + + keypad = (struct keypad_data *)pdev->dev.platform_data; + + kpp_dev.kpp_cols = keypad->colmax; + kpp_dev.kpp_rows = keypad->rowmax; + key_pad_enabled = 0; + + /* + * Request for IRQ number for keypad port. The Interrupt handler + * function (mxc_kpp_interrupt) is called when ever interrupt occurs on + * keypad port. + */ + irq = platform_get_irq(pdev, 0); + keypad->irq = irq; + retval = request_irq(irq, mxc_kpp_interrupt, 0, MOD_NAME, MOD_NAME); + if (retval) { + pr_debug("KPP: request_irq(%d) returned error %d\n", + MXC_INT_KPP, retval); + return retval; + } + + /* Enable keypad clock */ + kpp_clk = clk_get(&pdev->dev, "kpp_clk"); + clk_enable(kpp_clk); + + /* IOMUX configuration for keypad */ + gpio_keypad_active(); + + /* Configure keypad */ + + /* Enable number of rows in keypad (KPCR[7:0]) + * Configure keypad columns as open-drain (KPCR[15:8]) + * + * Configure the rows/cols in KPP + * LSB nibble in KPP is for 8 rows + * MSB nibble in KPP is for 8 cols + */ + reg_val = __raw_readw(KPCR); + reg_val |= (1 << keypad->rowmax) - 1; /* LSB */ + reg_val |= ((1 << keypad->colmax) - 1) << 8; /* MSB */ + __raw_writew(reg_val, KPCR); + + /* Write 0's to KPDR[15:8] */ + reg_val = __raw_readw(KPDR); + reg_val &= 0x00ff; + __raw_writew(reg_val, KPDR); + + /* Configure columns as output, rows as input (KDDR[15:0]) */ + reg_val = __raw_readw(KDDR); + reg_val |= 0xff00; + reg_val &= 0xff00; + __raw_writew(reg_val, KDDR); + + reg_val = __raw_readw(KPSR); + reg_val &= ~(KBD_STAT_KPKR | KBD_STAT_KPKD); + reg_val |= KBD_STAT_KPKD; + reg_val |= KBD_STAT_KRSS | KBD_STAT_KDSC; + __raw_writew(reg_val, KPSR); + reg_val |= KBD_STAT_KDIE; + reg_val &= ~KBD_STAT_KRIE; + __raw_writew(reg_val, KPSR); + + has_leaning_key = keypad->learning; + mxckpd_keycodes = keypad->matrix; + mxckpd_keycodes_size = keypad->rowmax * keypad->colmax; + + if ((keypad->matrix == (void *)0) + || (mxckpd_keycodes_size == 0)) { + retval = -ENODEV; + goto err1; + } + + mxckbd_dev = input_allocate_device(); + if (!mxckbd_dev) { + printk(KERN_ERR + "mxckbd_dev: not enough memory for input device\n"); + retval = -ENOMEM; + goto err1; + } + + mxckbd_dev->keycode = (void *)mxckpd_keycodes; + mxckbd_dev->keycodesize = sizeof(mxckpd_keycodes[0]); + mxckbd_dev->keycodemax = mxckpd_keycodes_size; + mxckbd_dev->name = "mxckpd"; + mxckbd_dev->id.bustype = BUS_HOST; + mxckbd_dev->open = mxc_kpp_open; + mxckbd_dev->close = mxc_kpp_close; + + retval = input_register_device(mxckbd_dev); + if (retval < 0) { + printk(KERN_ERR + "mxckbd_dev: failed to register input device\n"); + goto err2; + } + + /* allocate required memory */ + press_scancode = kmalloc(kpp_dev.kpp_rows * sizeof(press_scancode[0]), + GFP_KERNEL); + release_scancode = + kmalloc(kpp_dev.kpp_rows * sizeof(release_scancode[0]), GFP_KERNEL); + + if (!press_scancode || !release_scancode) { + retval = -ENOMEM; + goto err3; + } + + for (i = 0; i < kpp_dev.kpp_rows; i++) { + press_scancode[i] = kmalloc(kpp_dev.kpp_cols + * sizeof(press_scancode[0][0]), + GFP_KERNEL); + release_scancode[i] = + kmalloc(kpp_dev.kpp_cols * sizeof(release_scancode[0][0]), + GFP_KERNEL); + + if (!press_scancode[i] || !release_scancode[i]) { + retval = -ENOMEM; + goto err3; + } + } + + cur_rcmap = + kmalloc(kpp_dev.kpp_rows * sizeof(cur_rcmap[0]), GFP_KERNEL); + prev_rcmap = + kmalloc(kpp_dev.kpp_rows * sizeof(prev_rcmap[0]), GFP_KERNEL); + + if (!cur_rcmap || !prev_rcmap) { + retval = -ENOMEM; + goto err3; + } + + __set_bit(EV_KEY, mxckbd_dev->evbit); + + for (i = 0; i < mxckpd_keycodes_size; i++) + __set_bit(mxckpd_keycodes[i], mxckbd_dev->keybit); + + for (i = 0; i < kpp_dev.kpp_rows; i++) { + memset(press_scancode[i], -1, + sizeof(press_scancode[0][0]) * kpp_dev.kpp_cols); + memset(release_scancode[i], -1, + sizeof(release_scancode[0][0]) * kpp_dev.kpp_cols); + } + memset(cur_rcmap, 0, kpp_dev.kpp_rows * sizeof(cur_rcmap[0])); + memset(prev_rcmap, 0, kpp_dev.kpp_rows * sizeof(prev_rcmap[0])); + + key_pad_enabled = 1; + /* Initialize the polling timer */ + init_timer(&kpp_dev.poll_timer); + + /* By default, devices should wakeup if they can */ + /* So keypad is set as "should wakeup" as it can */ + device_init_wakeup(&pdev->dev, 1); + + return 0; + + err3: + mxc_kpp_free_allocated(); + err2: + input_free_device(mxckbd_dev); + err1: + free_irq(irq, MOD_NAME); + clk_disable(kpp_clk); + clk_put(kpp_clk); + return retval; +} + +/*! + * Dissociates the driver from the kpp device. + * + * @param pdev the device structure used to give information on which SDHC + * to remove + * + * @return The function always returns 0. + */ +static int mxc_kpp_remove(struct platform_device *pdev) +{ + unsigned short reg_val; + + /* + * Clear the KPKD status flag (write 1 to it) and synchronizer chain. + * Set KDIE control bit, clear KRIE control bit (avoid false release + * events. Disable the keypad GPIO pins. + */ + __raw_writew(0x00, KPCR); + __raw_writew(0x00, KPDR); + __raw_writew(0x00, KDDR); + + reg_val = __raw_readw(KPSR); + reg_val |= KBD_STAT_KPKD; + reg_val &= ~KBD_STAT_KRSS; + reg_val |= KBD_STAT_KDIE; + reg_val &= ~KBD_STAT_KRIE; + __raw_writew(reg_val, KPSR); + + gpio_keypad_inactive(); + clk_disable(kpp_clk); + clk_put(kpp_clk); + + KPress = 0; + + del_timer(&kpp_dev.poll_timer); + + free_irq(keypad->irq, MOD_NAME); + input_unregister_device(mxckbd_dev); + + mxc_kpp_free_allocated(); + + return 0; +} + +/*! + * This structure contains pointers to the power management callback functions. + */ +static struct platform_driver mxc_kpd_driver = { + .driver = { + .name = "mxc_keypad", + .bus = &platform_bus_type, + }, + .suspend = mxc_kpp_suspend, + .resume = mxc_kpp_resume, + .probe = mxc_kpp_probe, + .remove = mxc_kpp_remove +}; + +/*! + * This function is called for module initialization. + * It registers keypad char driver and requests for KPP irq number. This + * function does the initialization of the keypad device. + * + * The following steps are used for keypad configuration,\n + * -# Enable number of rows in the keypad control register (KPCR[7:0}).\n + * -# Write 0's to KPDR[15:8]\n + * -# Configure keypad columns as open-drain (KPCR[15:8])\n + * -# Configure columns as output, rows as input (KDDR[15:0])\n + * -# Clear the KPKD status flag (write 1 to it) and synchronizer chain\n + * -# Set KDIE control bit, clear KRIE control bit\n + * In this function the keypad queue initialization is done. + * The keypad IOMUX configuration are done here.* + + * + * @return 0 on success and a non-zero value on failure. + */ +static int __init mxc_kpp_init(void) +{ + printk(KERN_INFO "MXC keypad loaded\n"); + platform_driver_register(&mxc_kpd_driver); + return 0; +} + +/*! + * This function is called whenever the module is removed from the kernel. It + * unregisters the keypad driver from kernel and frees the irq number. + * This function puts the keypad to standby mode. The keypad interrupts are + * disabled. It calls gpio_keypad_inactive function to switch gpio + * configuration into default state. + * + */ +static void __exit mxc_kpp_cleanup(void) +{ + platform_driver_unregister(&mxc_kpd_driver); +} + +module_init(mxc_kpp_init); +module_exit(mxc_kpp_cleanup); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("MXC Keypad Controller Driver"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/input/keyboard/mxc_keyb.h +++ linux-2.6.28/drivers/input/keyboard/mxc_keyb.h @@ -0,0 +1,191 @@ +/* + * Copyright 2004-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 + */ + +/*! + * @defgroup keypad Keypad Driver + */ + +/*! + * @file mxc_keyb.h + * + * @brief MXC keypad header file. + * + * @ingroup keypad + */ +#ifndef __MXC_KEYB_H__ +#define __MXC_KEYB_H__ + +/*! + * Keypad Module Name + */ +#define MOD_NAME "mxckpd" + +/*! + * Keypad irq number + */ +#define KPP_IRQ MXC_INT_KPP + +/*! + * XLATE mode selection + */ +#define KEYPAD_XLATE 0 + +/*! + * RAW mode selection + */ +#define KEYPAD_RAW 1 + +/*! + * Maximum number of keys. + */ +#define MAXROW 8 +#define MAXCOL 8 +#define MXC_MAXKEY (MAXROW * MAXCOL) + +/*! + * This define indicates break scancode for every key release. A constant + * of 128 is added to the key press scancode. + */ +#define MXC_KEYRELEASE 128 + +/* + * _reg_KPP_KPCR _reg_KPP_KPSR _reg_KPP_KDDR _reg_KPP_KPDR + * Keypad Control Register Address + */ +#define KPCR IO_ADDRESS(KPP_BASE_ADDR + 0x00) + +/* + * Keypad Status Register Address + */ +#define KPSR IO_ADDRESS(KPP_BASE_ADDR + 0x02) + +/* + * Keypad Data Direction Address + */ +#define KDDR IO_ADDRESS(KPP_BASE_ADDR + 0x04) + +/* + * Keypad Data Register + */ +#define KPDR IO_ADDRESS(KPP_BASE_ADDR + 0x06) + +/* + * Key Press Interrupt Status bit + */ +#define KBD_STAT_KPKD 0x01 + +/* + * Key Release Interrupt Status bit + */ +#define KBD_STAT_KPKR 0x02 + +/* + * Key Depress Synchronizer Chain Status bit + */ +#define KBD_STAT_KDSC 0x04 + +/* + * Key Release Synchronizer Status bit + */ +#define KBD_STAT_KRSS 0x08 + +/* + * Key Depress Interrupt Enable Status bit + */ +#define KBD_STAT_KDIE 0x100 + +/* + * Key Release Interrupt Enable + */ +#define KBD_STAT_KRIE 0x200 + +/* + * Keypad Clock Enable + */ +#define KBD_STAT_KPPEN 0x400 + +/*! + * Buffer size of keypad queue. Should be a power of 2. + */ +#define KPP_BUF_SIZE 128 + +/*! + * Test whether bit is set for integer c + */ +#define TEST_BIT(c, n) ((c) & (0x1 << (n))) + +/*! + * Set nth bit in the integer c + */ +#define BITSET(c, n) ((c) | (1 << (n))) + +/*! + * Reset nth bit in the integer c + */ +#define BITRESET(c, n) ((c) & ~(1 << (n))) + +/*! + * This enum represents the keypad state machine to maintain debounce logic + * for key press/release. + */ +enum KeyState { + + /*! + * Key press state. + */ + KStateUp, + + /*! + * Key press debounce state. + */ + KStateFirstDown, + + /*! + * Key release state. + */ + KStateDown, + + /*! + * Key release debounce state. + */ + KStateFirstUp +}; + +/*! + * Keypad Private Data Structure + */ +typedef struct keypad_priv { + + /*! + * Keypad state machine. + */ + enum KeyState iKeyState; + + /*! + * Number of rows configured in the keypad matrix + */ + unsigned long kpp_rows; + + /*! + * Number of Columns configured in the keypad matrix + */ + unsigned long kpp_cols; + + /*! + * Timer used for Keypad polling. + */ + struct timer_list poll_timer; + +} keypad_priv; + +#endif /* __MXC_KEYB_H__ */ --- linux-2.6.28.orig/drivers/input/keyboard/atkbd.c +++ linux-2.6.28/drivers/input/keyboard/atkbd.c @@ -884,6 +884,55 @@ } /* + * Perform fixup for HP Pavilion ZV6100 laptop that doesn't generate release + * for its volume buttons + */ +static void atkbd_hp_zv6100_keymap_fixup(struct atkbd *atkbd) +{ + const unsigned int forced_release_keys[] = { + 0xae, 0xb0, + }; + int i; + + if (atkbd->set == 2) + for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) + __set_bit(forced_release_keys[i], + atkbd->force_release_mask); +} + +/* + * Samsung NC10 with Fn+F? key release not working + */ +static void atkbd_samsung_keymap_fixup(struct atkbd *atkbd) +{ + const unsigned int forced_release_keys[] = { + 0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9, + }; + int i; + + if (atkbd->set == 2) + for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) + __set_bit(forced_release_keys[i], + atkbd->force_release_mask); +} + +/* + * Fujitsu Siemens system with broken key release on volume keys and mute key + */ +static void atkbd_amilo_xi_2428_keymap_fixup(struct atkbd *atkbd) +{ + const unsigned int forced_release_keys[] = { + 0xa0, 0xae, 0xb0, + }; + int i; + + if (atkbd->set == 2) + for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++) + __set_bit(forced_release_keys[i], + atkbd->force_release_mask); +} + +/* * atkbd_set_keycode_table() initializes keyboard's keycode table * according to the selected scancode set */ @@ -1476,6 +1525,15 @@ .driver_data = atkbd_dell_laptop_keymap_fixup, }, { + .ident = "Dell Laptop", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), + DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ + }, + .callback = atkbd_setup_fixup, + .driver_data = atkbd_dell_laptop_keymap_fixup, + }, + { .ident = "HP 2133", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), @@ -1485,6 +1543,15 @@ .driver_data = atkbd_hp_keymap_fixup, }, { + .ident = "HP Pavilion ZV6100", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"), + }, + .callback = atkbd_setup_fixup, + .driver_data = atkbd_hp_zv6100_keymap_fixup, + }, + { .ident = "Inventec Symphony", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"), @@ -1493,6 +1560,43 @@ .callback = atkbd_setup_fixup, .driver_data = atkbd_inventec_keymap_fixup, }, + { + .ident = "Samsung NC10", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), + DMI_MATCH(DMI_PRODUCT_NAME, "NC10"), + }, + .callback = atkbd_setup_fixup, + .driver_data = atkbd_samsung_keymap_fixup, + }, + { + .ident = "Znote 6615WD", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Zepto"), + DMI_MATCH(DMI_PRODUCT_NAME, "Znote 6615WD"), + }, + .callback = atkbd_setup_fixup, + .driver_data = atkbd_inventec_keymap_fixup, + }, + { + .ident = "Znote 6625WD", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Zepto"), + DMI_MATCH(DMI_PRODUCT_NAME, "Znote"), + DMI_MATCH(DMI_PRODUCT_VERSION, "6625WD"), + }, + .callback = atkbd_setup_fixup, + .driver_data = atkbd_inventec_keymap_fixup, + }, + { + .ident = "AMILO Xi 2428", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), + DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2428"), + }, + .callback = atkbd_setup_fixup, + .driver_data = atkbd_amilo_xi_2428_keymap_fixup, + }, { } }; --- linux-2.6.28.orig/drivers/input/touchscreen/Kconfig +++ linux-2.6.28/drivers/input/touchscreen/Kconfig @@ -150,6 +150,18 @@ To compile this driver as a module, choose M here: the module will be called jornada720_ts. +config TOUCHSCREEN_MXC + tristate "MXC touchscreen input driver" + depends on MXC_MC13783_ADC || MXC_MC13892_ADC + help + Say Y here if you have an MXC based board with touchscreen + attached to it. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called mxc_ts. + config TOUCHSCREEN_HTCPEN tristate "HTC Shift X9500 touchscreen" depends on ISA --- linux-2.6.28.orig/drivers/input/touchscreen/Makefile +++ linux-2.6.28/drivers/input/touchscreen/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o obj-$(CONFIG_TOUCHSCREEN_HP7XX) += jornada720_ts.o obj-$(CONFIG_TOUCHSCREEN_HTCPEN) += htcpen.o +obj-$(CONFIG_TOUCHSCREEN_MXC) += mxc_ts.o obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o obj-$(CONFIG_TOUCHSCREEN_TOUCHIT213) += touchit213.o --- linux-2.6.28.orig/drivers/input/touchscreen/mxc_ts.c +++ linux-2.6.28/drivers/input/touchscreen/mxc_ts.c @@ -0,0 +1,118 @@ +/* + * Copyright 2007-2009 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 + */ + +/*! + * @file mxc_ts.c + * + * @brief Driver for the Freescale Semiconductor MXC touchscreen. + * + * The touchscreen driver is designed as a standard input driver which is a + * wrapper over low level PMIC driver. Most of the hardware configuration and + * touchscreen functionality is implemented in the low level PMIC driver. During + * initialization, this driver creates a kernel thread. This thread then calls + * PMIC driver to obtain touchscreen values continously. These values are then + * passed to the input susbsystem. + * + * @ingroup touchscreen + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MXC_TS_NAME "mxc_ts" + +static struct input_dev *mxc_inputdev = NULL; +static u32 input_ts_installed; + +static int ts_thread(void *arg) +{ + t_touch_screen ts_sample; + s32 wait = 0; + + daemonize("mxc_ts"); + while (input_ts_installed) { + try_to_freeze(); + memset(&ts_sample, 0, sizeof(t_touch_screen)); + if (0 != pmic_adc_get_touch_sample(&ts_sample, !wait)) + continue; + if (!(ts_sample.contact_resistance || wait)) + continue; + + input_report_abs(mxc_inputdev, ABS_X, ts_sample.x_position); + input_report_abs(mxc_inputdev, ABS_Y, ts_sample.y_position); + input_report_abs(mxc_inputdev, ABS_PRESSURE, + ts_sample.contact_resistance); + input_sync(mxc_inputdev); + + wait = ts_sample.contact_resistance; + msleep(20); + } + + return 0; +} + +static int __init mxc_ts_init(void) +{ + int retval; + + if (!is_pmic_adc_ready()) + return -ENODEV; + + mxc_inputdev = input_allocate_device(); + if (!mxc_inputdev) { + printk(KERN_ERR + "mxc_ts_init: not enough memory for input device\n"); + return -ENOMEM; + } + + mxc_inputdev->name = MXC_TS_NAME; + mxc_inputdev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + mxc_inputdev->keybit[BIT_WORD(BTN_TOUCH)] |= BIT_MASK(BTN_TOUCH); + mxc_inputdev->absbit[0] = + BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | BIT_MASK(ABS_PRESSURE); + retval = input_register_device(mxc_inputdev); + if (retval < 0) { + input_free_device(mxc_inputdev); + return retval; + } + + input_ts_installed = 1; + kernel_thread(ts_thread, NULL, CLONE_VM | CLONE_FS); + printk("mxc input touchscreen loaded\n"); + return 0; +} + +static void __exit mxc_ts_exit(void) +{ + input_ts_installed = 0; + input_unregister_device(mxc_inputdev); + + if (mxc_inputdev) { + input_free_device(mxc_inputdev); + mxc_inputdev = NULL; + } +} + +late_initcall(mxc_ts_init); +module_exit(mxc_ts_exit); + +MODULE_DESCRIPTION("MXC input touchscreen driver"); +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/input/misc/wistron_btns.c +++ linux-2.6.28/drivers/input/misc/wistron_btns.c @@ -611,6 +611,20 @@ { KE_END, 0 } }; +static struct key_entry keymap_prestigio[] __initdata = { + { KE_KEY, 0x11, {KEY_PROG1} }, + { KE_KEY, 0x12, {KEY_PROG2} }, + { KE_WIFI, 0x30 }, + { KE_KEY, 0x22, {KEY_REWIND} }, + { KE_KEY, 0x23, {KEY_FORWARD} }, + { KE_KEY, 0x24, {KEY_PLAYPAUSE} }, + { KE_KEY, 0x25, {KEY_STOPCD} }, + { KE_KEY, 0x31, {KEY_MAIL} }, + { KE_KEY, 0x36, {KEY_WWW} }, + { KE_END, 0 } +}; + + /* * If your machine is not here (which is currently rather likely), please send * a list of buttons and their key codes (reported when loading this module @@ -964,6 +978,10 @@ keymap = keymap_wistron_ms2141; else if (strcmp (keymap_name, "generic") == 0) keymap = keymap_wistron_generic; + else if (strcmp (keymap_name, "prestigio") == 0) { + keymap = keymap_prestigio; + have_wifi = 1; + } else { printk(KERN_ERR "wistron_btns: Keymap unknown\n"); return -EINVAL; --- linux-2.6.28.orig/drivers/acpi/processor_idle.c +++ linux-2.6.28/drivers/acpi/processor_idle.c @@ -128,52 +128,7 @@ static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = { { set_max_cstate, "IBM ThinkPad R40e", { DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET70WW")}, (void *)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW")}, (void *)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET43WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET45WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET47WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET50WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET52WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET55WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET56WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET59WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET61WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET62WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET64WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET65WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET68WW") }, (void*)1}, + DMI_MATCH(DMI_BIOS_VERSION,"1SET")}, (void *)1}, { set_max_cstate, "Medion 41700", { DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J")}, (void *)1}, --- linux-2.6.28.orig/drivers/acpi/video.c +++ linux-2.6.28/drivers/acpi/video.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -481,6 +482,7 @@ int status = AE_OK; union acpi_object arg0 = { ACPI_TYPE_INTEGER }; struct acpi_object_list args = { 1, &arg0 }; + int state; arg0.integer.value = level; @@ -489,6 +491,10 @@ status = acpi_evaluate_object(device->dev->handle, "_BCM", &args, NULL); device->brightness->curr = level; + for (state = 2; state < device->brightness->count; state++) + if (level == device->brightness->levels[state]) + device->backlight->props.brightness = state - 2; + return status; } @@ -626,6 +632,16 @@ } /* + * Simple comparison function used to sort backlight levels. + */ + +static int +acpi_video_cmp_level(const void *a, const void *b) +{ + return *(int *)a - *(int *)b; +} + +/* * Arg: * device : video output device (LCD, CRT, ..) * @@ -676,6 +692,10 @@ count++; } + /* don't sort the first two brightness levels */ + sort(&br->levels[2], count - 2, sizeof(br->levels[2]), + acpi_video_cmp_level, NULL); + if (count < 2) goto out_free_levels; @@ -1000,7 +1020,7 @@ } seq_printf(seq, "levels: "); - for (i = 0; i < dev->brightness->count; i++) + for (i = 2; i < dev->brightness->count; i++) seq_printf(seq, " %d", dev->brightness->levels[i]); seq_printf(seq, "\ncurrent: %d\n", dev->brightness->curr); @@ -1039,7 +1059,7 @@ return -EFAULT; /* validate through the list of available levels */ - for (i = 0; i < dev->brightness->count; i++) + for (i = 2; i < dev->brightness->count; i++) if (level == dev->brightness->levels[i]) { if (ACPI_SUCCESS (acpi_video_device_lcd_set_level(dev, level))) @@ -1692,7 +1712,7 @@ max = max_below = 0; min = min_above = 255; /* Find closest level to level_current */ - for (i = 0; i < device->brightness->count; i++) { + for (i = 2; i < device->brightness->count; i++) { l = device->brightness->levels[i]; if (abs(l - level_current) < abs(delta)) { delta = l - level_current; @@ -1702,7 +1722,7 @@ } /* Ajust level_current to closest available level */ level_current += delta; - for (i = 0; i < device->brightness->count; i++) { + for (i = 2; i < device->brightness->count; i++) { l = device->brightness->levels[i]; if (l < min) min = l; @@ -1986,6 +2006,12 @@ device->pnp.bus_id[3] = '0' + instance; instance ++; } + /* a hack to fix the duplicate name "VGA" problem on Pa 3553 */ + if (!strcmp(device->pnp.bus_id, "VGA")) { + if (instance) + device->pnp.bus_id[3] = '0' + instance; + instance++; + } video->device = device; strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); --- linux-2.6.28.orig/drivers/acpi/dock.c +++ linux-2.6.28/drivers/acpi/dock.c @@ -855,10 +855,14 @@ static ssize_t show_docked(struct device *dev, struct device_attribute *attr, char *buf) { + struct acpi_device *tmp; + struct dock_station *dock_station = *((struct dock_station **) dev->platform_data); - return snprintf(buf, PAGE_SIZE, "%d\n", dock_present(dock_station)); + if (ACPI_SUCCESS(acpi_bus_get_device(dock_station->handle, &tmp))) + return snprintf(buf, PAGE_SIZE, "1\n"); + return snprintf(buf, PAGE_SIZE, "0\n"); } static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); --- linux-2.6.28.orig/drivers/acpi/power.c +++ linux-2.6.28/drivers/acpi/power.c @@ -151,7 +151,7 @@ *state = (sta & 0x01)?ACPI_POWER_RESOURCE_STATE_ON: ACPI_POWER_RESOURCE_STATE_OFF; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n", + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%4.4s] is %s\n", acpi_ut_get_node_name(handle), *state ? "on" : "off")); --- linux-2.6.28.orig/drivers/acpi/tables.c +++ linux-2.6.28/drivers/acpi/tables.c @@ -293,7 +293,12 @@ int __init acpi_table_init(void) { - acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); + acpi_status status; + + status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); + if (ACPI_FAILURE(status)) + return 1; + check_multiple_madt(); return 0; } --- linux-2.6.28.orig/drivers/acpi/toshiba_acpi.c +++ linux-2.6.28/drivers/acpi/toshiba_acpi.c @@ -28,13 +28,28 @@ * engineering the Windows drivers * Yasushi Nagato - changes for linux kernel 2.4 -> 2.5 * Rob Miller - TV out and hotkeys help + * Daniel Silverstone - Punting of hotkeys via acpi using a thread * + * PLEASE NOTE + * + * This is an experimental version of toshiba_acpi which includes emulation + * of the original toshiba driver's /proc/toshiba and /dev/toshiba, + * allowing Toshiba userspace utilities to work. The relevant code was + * based on toshiba.c (copyright 1996-2001 Jonathan A. Buzzard) and + * incorporated into this driver with help from Gintautas Miliauskas, + * Charles Schwieters, and Christoph Burger-Scheidlin. + * + * Caveats: + * * hotkey status in /proc/toshiba is not implemented + * * to make accesses to /dev/toshiba load this driver instead of + * the original driver, you will have to modify your module + * auto-loading configuration * * TODO * */ -#define TOSHIBA_ACPI_VERSION "0.19" +#define TOSHIBA_ACPI_VERSION "0.19-dev-acpikeys" #define PROC_INTERFACE_VERSION 1 #include @@ -42,10 +57,15 @@ #include #include #include +#include +#include +#include +#include #include #include #include #include +#include #include @@ -380,6 +400,11 @@ static int force_fan; static int last_key_event; static int key_event_valid; +static int hotkeys_over_acpi = 1; +static int hotkeys_check_per_sec = 2; + +module_param(hotkeys_over_acpi, uint, 0400); +module_param(hotkeys_check_per_sec, uint, 0400); typedef struct _ProcItem { const char *name; @@ -607,27 +632,34 @@ u32 hci_result; u32 value; - if (!key_event_valid) { - hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result); - if (hci_result == HCI_SUCCESS) { - key_event_valid = 1; - last_key_event = value; - } else if (hci_result == HCI_EMPTY) { - /* better luck next time */ - } else if (hci_result == HCI_NOT_SUPPORTED) { - /* This is a workaround for an unresolved issue on - * some machines where system events sporadically - * become disabled. */ - hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); - printk(MY_NOTICE "Re-enabled hotkeys\n"); - } else { - printk(MY_ERR "Error reading hotkey status\n"); - goto end; + if (!hotkeys_over_acpi) { + if (!key_event_valid) { + hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result); + if (hci_result == HCI_SUCCESS) { + key_event_valid = 1; + last_key_event = value; + } else if (hci_result == HCI_EMPTY) { + /* better luck next time */ + } else if (hci_result == HCI_NOT_SUPPORTED) { + /* This is a workaround for an + * unresolved issue on some machines + * where system events sporadically + * become disabled. */ + hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); + printk(MY_NOTICE "Re-enabled hotkeys\n"); + } else { + printk(MY_ERR "Error reading hotkey status\n"); + goto end; + } } + } else { + key_event_valid = 0; + last_key_event = 0; } p += sprintf(p, "hotkey_ready: %d\n", key_event_valid); p += sprintf(p, "hotkey: 0x%04x\n", last_key_event); + p += sprintf(p, "hotkeys_via_acpi: %d\n", hotkeys_over_acpi); end: return p; @@ -654,6 +686,191 @@ return p; } +/* /dev/toshiba and /proc/toshiba handlers {{{ + * + * ISSUE: lots of magic numbers and mysterious code + */ + +#define TOSH_MINOR_DEV 181 +#define OLD_PROC_TOSHIBA "toshiba" + +static int +tosh_acpi_bridge(SMMRegisters* regs) +{ + acpi_status status; + + /* assert(sizeof(SMMRegisters) == sizeof(u32)*HCI_WORDS); */ + status = hci_raw((u32*)regs, (u32*)regs); + if (status == AE_OK && (regs->eax & 0xff00) == HCI_SUCCESS) + return 0; + + return -EINVAL; +} + +static int +tosh_ioctl(struct inode* ip, struct file* fp, unsigned int cmd, + unsigned long arg) +{ + SMMRegisters regs; + unsigned short ax,bx; + int err; + + if ((!arg) || (cmd != TOSH_SMM)) + return -EINVAL; + + if (copy_from_user(®s, (SMMRegisters*)arg, sizeof(SMMRegisters))) + return -EFAULT; + + ax = regs.eax & 0xff00; + bx = regs.ebx & 0xffff; + + /* block HCI calls to read/write memory & PCI devices */ + if (((ax==HCI_SET) || (ax==HCI_GET)) && (bx>0x0069)) + return -EINVAL; + + err = tosh_acpi_bridge(®s); + + if (copy_to_user((SMMRegisters*)arg, ®s, sizeof(SMMRegisters))) + return -EFAULT; + + return err; +} + +static int +tosh_get_machine_id(void __iomem *bios) +{ + int id; + unsigned short bx,cx; + unsigned long address; + + id = (0x100*(int) readb(bios+0xfffe))+((int) readb(bios+0xfffa)); + + /* do we have a SCTTable machine identication number on our hands */ + if (id==0xfc2f) { + bx = 0xe6f5; /* cheat */ + /* now twiddle with our pointer a bit */ + address = 0x00000000 + bx; + cx = readw(bios + address); + address = 0x00000009 + bx + cx; + cx = readw(bios + address); + address = 0x0000000a + cx; + cx = readw(bios + address); + /* now construct our machine identification number */ + id = ((cx & 0xff)<<8)+((cx & 0xff00)>>8); + } + + return id; +} + +static int tosh_id; +static int tosh_bios; +static int tosh_date; +static int tosh_sci; + +static struct file_operations tosh_fops = { + .owner = THIS_MODULE, + .ioctl = tosh_ioctl +}; + +static struct miscdevice tosh_device = { + TOSH_MINOR_DEV, + "toshiba", + &tosh_fops +}; + +static void +setup_tosh_info(void __iomem *bios) +{ + int major, minor; + int day, month, year; + + tosh_id = tosh_get_machine_id(bios); + + /* get the BIOS version */ + major = readb(bios + 0xe009)-'0'; + minor = ((readb(bios + 0xe00b)-'0')*10)+(readb(bios + 0xe00c)-'0'); + tosh_bios = (major*0x100)+minor; + + /* get the BIOS date */ + day = ((readb(bios + 0xfff5)-'0')*10)+(readb(bios + 0xfff6)-'0'); + month = ((readb(bios + 0xfff8)-'0')*10)+(readb(bios + 0xfff9)-'0'); + year = ((readb(bios + 0xfffb)-'0')*10)+(readb(bios + 0xfffc)-'0'); + tosh_date = (((year-90) & 0x1f)<<10) | ((month & 0xf)<<6) + | ((day & 0x1f)<<1); +} + +/* /proc/toshiba read handler */ +static int +tosh_proc_show(struct seq_file *m, void *v) +{ + /* TODO: tosh_fn_status() */ + int key = 0; + + /* Format: + * 0) Linux driver version (this will change if format changes) + * 1) Machine ID + * 2) SCI version + * 3) BIOS version (major, minor) + * 4) BIOS date (in SCI date format) + * 5) Fn Key status + */ + + seq_printf(m, "1.1 0x%04x %d.%d %d.%d 0x%04x 0x%02x\n", + tosh_id, + (tosh_sci & 0xff00)>>8, + tosh_sci & 0xff, + (tosh_bios & 0xff00)>>8, + tosh_bios & 0xff, + tosh_date, + key); + + return 0; +} + +static int tosh_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, tosh_proc_show, NULL); +} + +static const struct file_operations tosh_proc_fops = { + .owner = THIS_MODULE, + .open = tosh_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init +old_driver_emulation_init(void) +{ + int status; + void __iomem *bios = ioremap(0xf0000, 0x10000); + if (!bios) + return -ENOMEM; + + if ((status = misc_register(&tosh_device))) { + printk(MY_ERR "failed to register misc device %d (\"%s\")\n", + tosh_device.minor, tosh_device.name); + return status; + } + + setup_tosh_info(bios); + proc_create(OLD_PROC_TOSHIBA, 0, NULL, &tosh_proc_fops); + + iounmap(bios); + + return 0; +} + +static void __exit +old_driver_emulation_exit(void) +{ + remove_proc_entry(OLD_PROC_TOSHIBA, NULL); + misc_deregister(&tosh_device); +} + +/* }}} end of /dev/toshiba and /proc/toshiba handlers */ + /* proc and module init */ @@ -702,6 +919,133 @@ .update_status = set_lcd_status, }; +static struct semaphore thread_sem; +static int thread_should_die; + +static struct acpi_device *threaded_device = 0; + +static void thread_deliver_button_event(u32 value) +{ + if (!threaded_device) return; + if( value == 0x0100 ) { + /* Ignore FN on its own */ + } else if( value & 0x80 ) { + acpi_bus_generate_proc_event( threaded_device, 1, value & ~0x80 ); + } else { + acpi_bus_generate_proc_event( threaded_device, 0, value ); + } +} + +static int toshiba_acpi_thread(void *data) +{ + int dropped = 0; + u32 hci_result, value; + + daemonize("ktoshkeyd"); + set_user_nice(current, 4); + thread_should_die = 0; + + up(&thread_sem); + + do { + /* In case we get stuck; we can rmmod the module here */ + if (thread_should_die) + break; + + hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result); + if (hci_result == HCI_SUCCESS) { + dropped++; + } else if (hci_result == HCI_EMPTY) { + /* better luck next time */ + } else if (hci_result == HCI_NOT_SUPPORTED) { + /* This is a workaround for an unresolved issue on + * some machines where system events sporadically + * become disabled. */ + hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); + printk(MY_NOTICE "Re-enabled hotkeys\n"); + } + } while (hci_result != HCI_EMPTY); + + printk(MY_INFO "Dropped %d keys from the queue on startup\n", dropped); + + for (;;) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ / hotkeys_check_per_sec); + + if (thread_should_die) + break; + + if (try_to_freeze()) + continue; + + do { + hci_read1(HCI_SYSTEM_EVENT, &value, &hci_result); + if (hci_result == HCI_SUCCESS) { + thread_deliver_button_event(value); + } else if (hci_result == HCI_EMPTY) { + /* better luck next time */ + } else if (hci_result == HCI_NOT_SUPPORTED) { + /* This is a workaround for an + * unresolved issue on some machines + * where system events sporadically + * become disabled. */ + hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); + printk(MY_NOTICE "Re-enabled hotkeys\n"); + } + } while (hci_result == HCI_SUCCESS); + } + set_user_nice(current, -20); /* Become nasty so we are cleaned up + * before the module exits making us oops */ + up(&thread_sem); + return 0; +} + +static int acpi_toshkeys_add (struct acpi_device *device) +{ + threaded_device = device; + strcpy(acpi_device_name(device), "Toshiba laptop hotkeys"); + strcpy(acpi_device_class(device), "hkey"); + return 0; +} + +static int acpi_toshkeys_remove (struct acpi_device *device, int type) +{ + if (threaded_device == device) + threaded_device = 0; + return 0; +} + +static const struct acpi_device_id acpi_toshkeys_ids[] = { + { "TOS6200", 0 }, + { "TOS6207", 0 }, + { "TOS6208", 0 }, + {"", 0} +}; + +static struct acpi_driver acpi_threaded_toshkeys = { + .name = "Toshiba laptop hotkeys driver", + .class = "hkey", + .ids = acpi_toshkeys_ids, + .ops = { + .add = acpi_toshkeys_add, + .remove = acpi_toshkeys_remove, + }, +}; + +static int __init init_threaded_acpi(void) +{ + acpi_status result = AE_OK; + result = acpi_bus_register_driver(&acpi_threaded_toshkeys); + if( result < 0 ) + printk(MY_ERR "Registration of toshkeys acpi device failed\n"); + return result; +} + +static void kill_threaded_acpi(void) +{ + acpi_bus_unregister_driver(&acpi_threaded_toshkeys); +} + static void toshiba_acpi_exit(void) { if (toshiba_acpi.poll_dev) { @@ -715,11 +1059,19 @@ if (toshiba_backlight_device) backlight_device_unregister(toshiba_backlight_device); + if (hotkeys_over_acpi) { + thread_should_die = 1; + down(&thread_sem); + kill_threaded_acpi(); + } + remove_device(); if (toshiba_proc_dir) remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); + old_driver_emulation_exit(); + platform_device_unregister(toshiba_acpi.p_dev); return; @@ -761,6 +1113,9 @@ return ret; } + if ((ret = old_driver_emulation_init())) + return ret; + force_fan = 0; key_event_valid = 0; @@ -794,6 +1149,26 @@ } toshiba_backlight_device->props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; + if (hotkeys_over_acpi && ACPI_SUCCESS(status)) { + printk(MY_INFO "Toshiba hotkeys are sent as ACPI events\n"); + if (hotkeys_check_per_sec < 1) + hotkeys_check_per_sec = 1; + if (hotkeys_check_per_sec > 10) + hotkeys_check_per_sec = 10; + printk(MY_INFO "ktoshkeyd will check %d time%s per second\n", + hotkeys_check_per_sec, hotkeys_check_per_sec==1?"":"s"); + if (init_threaded_acpi() >= 0) { + init_MUTEX_LOCKED(&thread_sem); + kernel_thread(toshiba_acpi_thread, NULL, CLONE_KERNEL); + down(&thread_sem); + } else { + remove_device(); + remove_proc_entry(PROC_TOSHIBA, acpi_root_dir); + status = AE_ERROR; + printk(MY_INFO "ktoshkeyd initialisation failed. Refusing to load module\n"); + } + } + /* Register rfkill switch for Bluetooth */ if (hci_get_bt_present(&bt_present) == HCI_SUCCESS && bt_present) { toshiba_acpi.rfk_dev = rfkill_allocate(&toshiba_acpi.p_dev->dev, --- linux-2.6.28.orig/drivers/acpi/Kconfig +++ linux-2.6.28/drivers/acpi/Kconfig @@ -297,6 +297,17 @@ bool default ACPI_CUSTOM_DSDT_FILE != "" +config ACPI_CUSTOM_DSDT_INITRD + bool "Read Custom DSDT from initramfs" + depends on BLK_DEV_INITRD + default n + help + This option supports a custom DSDT by optionally loading it from initrd. + See Documentation/acpi/dsdt-override.txt + + If you are not using this feature now, but may use it later, + it is safe to say Y here. + config ACPI_BLACKLIST_YEAR int "Disable ACPI for systems before Jan 1st this year" if X86_32 default 0 --- linux-2.6.28.orig/drivers/acpi/pci_link.c +++ linux-2.6.28/drivers/acpi/pci_link.c @@ -796,10 +796,6 @@ struct list_head *node = NULL; struct acpi_pci_link *link = NULL; - - /* Make sure SCI is enabled again (Apple firmware bug?) */ - acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1); - list_for_each(node, &acpi_link.entries) { link = list_entry(node, struct acpi_pci_link, node); if (!link) { --- linux-2.6.28.orig/drivers/acpi/battery.c +++ linux-2.6.28/drivers/acpi/battery.c @@ -471,7 +471,7 @@ static int acpi_battery_update(struct acpi_battery *battery) { - int result; + int result, old_present = acpi_battery_present(battery); result = acpi_battery_get_status(battery); if (result) return result; @@ -482,7 +482,8 @@ return 0; } #endif - if (!battery->update_time) { + if (!battery->update_time || + old_present != acpi_battery_present(battery)) { result = acpi_battery_get_info(battery); if (result) return result; --- linux-2.6.28.orig/drivers/acpi/ec.c +++ linux-2.6.28/drivers/acpi/ec.c @@ -759,9 +759,10 @@ struct acpi_namespace_node *node = handle; struct acpi_ec *ec = context; int value = 0; - if (sscanf(node->name.ascii, "_Q%x", &value) == 1) { + + if (sscanf(node->name.ascii, "_Q%2x", &value) == 1) acpi_ec_add_query_handler(ec, value, handle, NULL, NULL); - } + return AE_OK; } @@ -1009,7 +1010,7 @@ } else { /* This workaround is needed only on some broken machines, * which require early EC, but fail to provide ECDT */ - acpi_handle x; + acpi_handle dummy; printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, boot_ec, NULL); @@ -1020,7 +1021,9 @@ * which needs it, has fake EC._INI method, so use it as flag. * Keep boot_ec struct as it will be needed soon. */ - if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &x))) + if (!dmi_name_in_vendors("ASUS") || + ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", + &dummy))) return -ENODEV; } --- linux-2.6.28.orig/drivers/acpi/osl.c +++ linux-2.6.28/drivers/acpi/osl.c @@ -95,6 +95,11 @@ #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ static char osi_additional_string[OSI_STRING_LENGTH_MAX]; +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD +static __initdata int acpi_no_initrd_override; +extern struct acpi_table_header *acpi_find_dsdt_initrd(void); +#endif + /* * The story of _OSI(Linux) * @@ -327,6 +332,16 @@ if (strncmp(existing_table->signature, "DSDT", 4) == 0) *new_table = (struct acpi_table_header *)AmlCode; #endif +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD + if ((strncmp(existing_table->signature, "DSDT", 4) == 0) && + !acpi_no_initrd_override) { + struct acpi_table_header *initrd_table; + + initrd_table = acpi_find_dsdt_initrd(); + if (initrd_table) + *new_table = initrd_table; + } +#endif if (*new_table != NULL) { printk(KERN_WARNING PREFIX "Override [%4.4s-%8.8s], " "this is unsafe: tainting kernel\n", @@ -337,6 +352,15 @@ return AE_OK; } +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD +static int __init acpi_no_initrd_override_setup(char *s) +{ + acpi_no_initrd_override = 1; + return 1; +} +__setup("acpi_no_initrd_override", acpi_no_initrd_override_setup); +#endif + static irqreturn_t acpi_irq(int irq, void *dev_id) { u32 handled; --- linux-2.6.28.orig/drivers/acpi/asus_acpi.c +++ linux-2.6.28/drivers/acpi/asus_acpi.c @@ -143,6 +143,7 @@ S1300N, S5200N*/ A4S, /* Z81sp */ F3Sa, /* (Centrino) */ + R1F, END_MODEL } model; /* Models currently supported */ u16 event_count[128]; /* Count for each event TODO make this better */ @@ -420,7 +421,18 @@ .display_get = "\\ADVG", .display_set = "SDSP", }, - + { + .name = "R1F", + .mt_bt_switch = "BLED", + .mt_mled = "MLED", + .mt_wled = "WLED", + .mt_lcd_switch = "\\Q10", + .lcd_status = "\\GP06", + .brightness_set = "SPLV", + .brightness_get = "GPLV", + .display_set = "SDSP", + .display_get = "\\INFB" + } }; /* procdir we use */ @@ -1165,6 +1177,8 @@ return W3V; else if (strncmp(model, "W5A", 3) == 0) return W5A; + else if (strncmp(model, "R1F", 3) == 0) + return R1F; else if (strncmp(model, "A4S", 3) == 0) return A4S; else if (strncmp(model, "F3Sa", 4) == 0) --- linux-2.6.28.orig/drivers/acpi/sleep/main.c +++ linux-2.6.28/drivers/acpi/sleep/main.c @@ -378,6 +378,14 @@ DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"), }, }, + { + .callback = init_old_suspend_ordering, + .ident = "Asus Pundit P1-AH2 (M2N8L motherboard)", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTek Computer INC."), + DMI_MATCH(DMI_BOARD_NAME, "M2N8L"), + }, + }, {}, }; #endif /* CONFIG_SUSPEND */ --- linux-2.6.28.orig/drivers/acpi/tables/tbutils.c +++ linux-2.6.28/drivers/acpi/tables/tbutils.c @@ -512,10 +512,9 @@ if (ACPI_FAILURE(status)) { ACPI_WARNING((AE_INFO, "Truncating %u table entries!", - (unsigned) - (acpi_gbl_root_table_list.size - - acpi_gbl_root_table_list. - count))); + (unsigned) (table_count - + (acpi_gbl_root_table_list. + count - 2)))); break; } } --- linux-2.6.28.orig/drivers/acpi/namespace/nsutils.c +++ linux-2.6.28/drivers/acpi/namespace/nsutils.c @@ -314,9 +314,15 @@ * * strlen() + 1 covers the first name_seg, which has no path separator */ - if (acpi_ns_valid_root_prefix(next_external_char[0])) { + if (acpi_ns_valid_root_prefix(*next_external_char)) { info->fully_qualified = TRUE; next_external_char++; + + /* Skip redundant root_prefix, like \\_SB.PCI0.SBRG.EC0 */ + + while (acpi_ns_valid_root_prefix(*next_external_char)) { + next_external_char++; + } } else { /* * Handle Carat prefixes --- linux-2.6.28.orig/drivers/ata/libata-sff.c +++ linux-2.6.28/drivers/ata/libata-sff.c @@ -1281,6 +1281,16 @@ qc->err_mask |= AC_ERR_HSM; } + /* There are oddball controllers with + * status register stuck at 0x7f and + * lbal/m/h at zero which makes it + * pass all other presence detection + * mechanisms we have. Set NODEV_HINT + * for it. Kernel bz#7241. + */ + if (status == 0x7f) + qc->err_mask |= AC_ERR_NODEV_HINT; + /* ata_pio_sectors() might change the * state to HSM_ST_LAST. so, the state * is changed after ata_pio_sectors(). --- linux-2.6.28.orig/drivers/ata/libata-eh.c +++ linux-2.6.28/drivers/ata/libata-eh.c @@ -2366,11 +2366,14 @@ } /* prereset() might have cleared ATA_EH_RESET. If so, - * bang classes and return. + * bang classes, thaw and return. */ if (reset && !(ehc->i.action & ATA_EH_RESET)) { ata_link_for_each_dev(dev, link) classes[dev->devno] = ATA_DEV_NONE; + if ((ap->pflags & ATA_PFLAG_FROZEN) && + ata_is_host_link(link)) + ata_eh_thaw_port(ap); rc = 0; goto out; } @@ -2959,12 +2962,13 @@ /* give it just one more chance */ ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1); case -EIO: - if (ehc->tries[dev->devno] == 1 && dev->pio_mode > XFER_PIO_0) { + if (ehc->tries[dev->devno] == 1) { /* This is the last chance, better to slow * down than lose it. */ sata_down_spd_limit(ata_dev_phys_link(dev)); - ata_down_xfermask_limit(dev, ATA_DNXFER_PIO); + if (dev->pio_mode > XFER_PIO_0) + ata_down_xfermask_limit(dev, ATA_DNXFER_PIO); } } --- linux-2.6.28.orig/drivers/ata/libata-core.c +++ linux-2.6.28/drivers/ata/libata-core.c @@ -137,7 +137,7 @@ module_param_named(fua, libata_fua, int, 0444); MODULE_PARM_DESC(fua, "FUA support (0=off, 1=on)"); -static int ata_ignore_hpa; +static int ata_ignore_hpa = 1; module_param_named(ignore_hpa, ata_ignore_hpa, int, 0644); MODULE_PARM_DESC(ignore_hpa, "Ignore HPA limit (0=keep BIOS limits, 1=ignore limits, using full disk)"); @@ -1251,14 +1251,16 @@ { if (ata_id_has_lba(id)) { if (ata_id_has_lba48(id)) - return ata_id_u64(id, 100); + return ata_id_u64(id, ATA_ID_LBA_CAPACITY_2); else - return ata_id_u32(id, 60); + return ata_id_u32(id, ATA_ID_LBA_CAPACITY); } else { if (ata_id_current_chs_valid(id)) - return ata_id_u32(id, 57); + return id[ATA_ID_CUR_CYLS] * id[ATA_ID_CUR_HEADS] * + id[ATA_ID_CUR_SECTORS]; else - return id[1] * id[3] * id[6]; + return id[ATA_ID_CYLS] * id[ATA_ID_HEADS] * + id[ATA_ID_SECTORS]; } } @@ -4121,6 +4123,7 @@ { "HTS541060G9SA00", "MB3OC60D", ATA_HORKAGE_NONCQ, }, { "HTS541080G9SA00", "MB4OC60D", ATA_HORKAGE_NONCQ, }, { "HTS541010G9SA00", "MBZOC60D", ATA_HORKAGE_NONCQ, }, + { "FUJITSU MHW2160BH PL", "0084001E", ATA_HORKAGE_NONCQ, }, /* devices which puke on READ_NATIVE_MAX */ { "HDS724040KLSA80", "KFAOA20N", ATA_HORKAGE_BROKEN_HPA, }, --- linux-2.6.28.orig/drivers/ata/pata_via.c +++ linux-2.6.28/drivers/ata/pata_via.c @@ -86,6 +86,10 @@ VIA_SATA_PATA = 0x800, /* SATA/PATA combined configuration */ }; +enum { + VIA_IDFLAG_SINGLE = (1 << 0), /* single channel controller) */ +}; + /* * VIA SouthBridge chips. */ @@ -97,12 +101,17 @@ u8 rev_max; u16 flags; } via_isa_bridges[] = { + { "vx855", PCI_DEVICE_ID_VIA_VX855, 0x00, 0x2f, + VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA }, { "vx800", PCI_DEVICE_ID_VIA_VX800, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA }, + { "vt8261", PCI_DEVICE_ID_VIA_8261, 0x00, 0x2f, + VIA_UDMA_133 | VIA_BAD_AST }, { "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA }, - { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES}, + { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES }, + { "vt6415", PCI_DEVICE_ID_VIA_6415, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES }, { "vt8237a", PCI_DEVICE_ID_VIA_8237A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, @@ -122,6 +131,8 @@ { "vt82c586", PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, VIA_UDMA_NONE | VIA_SET_FIFO }, { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK }, { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID }, + { "vtxxxx", PCI_DEVICE_ID_VIA_ANON, 0x00, 0x2f, + VIA_UDMA_133 | VIA_BAD_AST }, { NULL } }; @@ -460,6 +471,7 @@ static int printed_version; u8 enable; u32 timing; + unsigned long flags = id->driver_data; int rc; if (!printed_version++) @@ -469,9 +481,13 @@ if (rc) return rc; + if (flags & VIA_IDFLAG_SINGLE) + ppi[1] = &ata_dummy_port_info; + /* To find out how the IDE will behave and what features we actually have to look at the bridge not the IDE controller */ - for (config = via_isa_bridges; config->id; config++) + for (config = via_isa_bridges; config->id != PCI_DEVICE_ID_VIA_ANON; + config++) if ((isa = pci_get_device(PCI_VENDOR_ID_VIA + !!(config->flags & VIA_BAD_ID), config->id, NULL))) { @@ -482,10 +498,6 @@ pci_dev_put(isa); } - if (!config->id) { - printk(KERN_WARNING "via: Unknown VIA SouthBridge, disabling.\n"); - return -ENODEV; - } pci_dev_put(isa); if (!(config->flags & VIA_NO_ENABLES)) { @@ -582,11 +594,13 @@ #endif static const struct pci_device_id via[] = { + { PCI_VDEVICE(VIA, 0x0415), }, { PCI_VDEVICE(VIA, 0x0571), }, { PCI_VDEVICE(VIA, 0x0581), }, { PCI_VDEVICE(VIA, 0x1571), }, { PCI_VDEVICE(VIA, 0x3164), }, { PCI_VDEVICE(VIA, 0x5324), }, + { PCI_VDEVICE(VIA, 0xC409), VIA_IDFLAG_SINGLE }, { }, }; --- linux-2.6.28.orig/drivers/ata/sata_nv.c +++ linux-2.6.28/drivers/ata/sata_nv.c @@ -305,10 +305,10 @@ static int nv_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val); +static int nv_noclassify_hardreset(struct ata_link *link, unsigned int *class, + unsigned long deadline); static void nv_nf2_freeze(struct ata_port *ap); static void nv_nf2_thaw(struct ata_port *ap); -static int nv_nf2_hardreset(struct ata_link *link, unsigned int *class, - unsigned long deadline); static void nv_ck804_freeze(struct ata_port *ap); static void nv_ck804_thaw(struct ata_port *ap); static int nv_adma_slave_config(struct scsi_device *sdev); @@ -352,6 +352,7 @@ NFORCE3 = NFORCE2, /* NF2 == NF3 as far as sata_nv is concerned */ CK804, ADMA, + MCP5x, SWNCQ, }; @@ -363,10 +364,10 @@ { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2), CK804 }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA), CK804 }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2), CK804 }, - { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA), SWNCQ }, - { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2), SWNCQ }, - { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA), SWNCQ }, - { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2), SWNCQ }, + { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA), MCP5x }, + { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2), MCP5x }, + { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA), MCP5x }, + { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2), MCP5x }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC }, { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC }, @@ -420,26 +421,33 @@ .hardreset = ATA_OP_NULL, }; -/* OSDL bz3352 reports that nf2/3 controllers can't determine device - * signature reliably. Also, the following thread reports detection - * failure on cold boot with the standard debouncing timing. +/* nf2 is ripe with hardreset related problems. + * + * kernel bz#3352 reports nf2/3 controllers can't determine device + * signature reliably. The following thread reports detection failure + * on cold boot with the standard debouncing timing. * * http://thread.gmane.org/gmane.linux.ide/34098 * - * Debounce with hotplug timing and request follow-up SRST. + * And bz#12176 reports that hardreset simply doesn't work on nf2. + * Give up on it and just don't do hardreset. */ static struct ata_port_operations nv_nf2_ops = { - .inherits = &nv_common_ops, + .inherits = &nv_generic_ops, .freeze = nv_nf2_freeze, .thaw = nv_nf2_thaw, - .hardreset = nv_nf2_hardreset, }; -/* CK804 finally gets hardreset right */ +/* For initial probing after boot and hot plugging, hardreset mostly + * works fine on CK804 but curiously, reprobing on the initial port by + * rescanning or rmmod/insmod fails to acquire the initial D2H Reg FIS + * in somewhat undeterministic way. Use noclassify hardreset. + */ static struct ata_port_operations nv_ck804_ops = { .inherits = &nv_common_ops, .freeze = nv_ck804_freeze, .thaw = nv_ck804_thaw, + .hardreset = nv_noclassify_hardreset, .host_stop = nv_ck804_host_stop, }; @@ -467,8 +475,19 @@ .host_stop = nv_adma_host_stop, }; +/* Kernel bz#12351 reports that when SWNCQ is enabled, for hotplug to + * work, hardreset should be used and hardreset can't report proper + * signature, which suggests that mcp5x is closer to nf2 as long as + * reset quirkiness is concerned. Define separate ops for mcp5x with + * nv_noclassify_hardreset(). + */ +static struct ata_port_operations nv_mcp5x_ops = { + .inherits = &nv_common_ops, + .hardreset = nv_noclassify_hardreset, +}; + static struct ata_port_operations nv_swncq_ops = { - .inherits = &nv_generic_ops, + .inherits = &nv_mcp5x_ops, .qc_defer = ata_std_qc_defer, .qc_prep = nv_swncq_qc_prep, @@ -531,6 +550,15 @@ .port_ops = &nv_adma_ops, .private_data = NV_PI_PRIV(nv_adma_interrupt, &nv_adma_sht), }, + /* MCP5x */ + { + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, + .pio_mask = NV_PIO_MASK, + .mwdma_mask = NV_MWDMA_MASK, + .udma_mask = NV_UDMA_MASK, + .port_ops = &nv_mcp5x_ops, + .private_data = NV_PI_PRIV(nv_generic_interrupt, &nv_sht), + }, /* SWNCQ */ { .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | @@ -1530,6 +1558,17 @@ return 0; } +static int nv_noclassify_hardreset(struct ata_link *link, unsigned int *class, + unsigned long deadline) +{ + bool online; + int rc; + + rc = sata_link_hardreset(link, sata_deb_timing_hotplug, deadline, + &online, NULL); + return online ? -EAGAIN : rc; +} + static void nv_nf2_freeze(struct ata_port *ap) { void __iomem *scr_addr = ap->host->ports[0]->ioaddr.scr_addr; @@ -1554,17 +1593,6 @@ iowrite8(mask, scr_addr + NV_INT_ENABLE); } -static int nv_nf2_hardreset(struct ata_link *link, unsigned int *class, - unsigned long deadline) -{ - bool online; - int rc; - - rc = sata_link_hardreset(link, sata_deb_timing_hotplug, deadline, - &online, NULL); - return online ? -EAGAIN : rc; -} - static void nv_ck804_freeze(struct ata_port *ap) { void __iomem *mmio_base = ap->host->iomap[NV_MMIO_BAR]; @@ -2355,14 +2383,9 @@ if (type == CK804 && adma_enabled) { dev_printk(KERN_NOTICE, &pdev->dev, "Using ADMA mode\n"); type = ADMA; - } - - if (type == SWNCQ) { - if (swncq_enabled) - dev_printk(KERN_NOTICE, &pdev->dev, - "Using SWNCQ mode\n"); - else - type = GENERIC; + } else if (type == MCP5x && swncq_enabled) { + dev_printk(KERN_NOTICE, &pdev->dev, "Using SWNCQ mode\n"); + type = SWNCQ; } ppi[0] = &nv_port_info[type]; --- linux-2.6.28.orig/drivers/ata/Kconfig +++ linux-2.6.28/drivers/ata/Kconfig @@ -724,5 +724,14 @@ If unsure, say N. +config PATA_FSL + tristate "Freescale on-chip PATA support" + depends on (ARCH_MX51 || ARCH_MX37 || ARCH_MX35 || ARCH_MX3 || ARCH_MX27) + help + On Freescale processors, say Y here if you wish to use the on-chip + ATA interface. + If you are unsure, say N to this. + endif # ATA_SFF + endif # ATA --- linux-2.6.28.orig/drivers/ata/sata_mv.c +++ linux-2.6.28/drivers/ata/sata_mv.c @@ -669,8 +669,8 @@ { PCI_VDEVICE(MARVELL, 0x5081), chip_508x }, /* RocketRAID 1720/174x have different identifiers */ { PCI_VDEVICE(TTI, 0x1720), chip_6042 }, - { PCI_VDEVICE(TTI, 0x1740), chip_508x }, - { PCI_VDEVICE(TTI, 0x1742), chip_508x }, + { PCI_VDEVICE(TTI, 0x1740), chip_6042 }, + { PCI_VDEVICE(TTI, 0x1742), chip_6042 }, { PCI_VDEVICE(MARVELL, 0x6040), chip_604x }, { PCI_VDEVICE(MARVELL, 0x6041), chip_604x }, @@ -883,7 +883,7 @@ struct mv_host_priv *hpriv = ap->host->private_data; int hardport = mv_hardport_from_port(ap->port_no); void __iomem *hc_mmio = mv_hc_base_from_port( - mv_host_base(ap->host), hardport); + mv_host_base(ap->host), ap->port_no); u32 hc_irq_cause, ipending; /* clear EDMA event indicators, if any */ --- linux-2.6.28.orig/drivers/ata/sata_via.c +++ linux-2.6.28/drivers/ata/sata_via.c @@ -92,6 +92,8 @@ { PCI_VDEVICE(VIA, 0x5372), vt6420 }, { PCI_VDEVICE(VIA, 0x7372), vt6420 }, { PCI_VDEVICE(VIA, 0x5287), vt8251 }, /* 2 sata chnls (Master/Slave) */ + { PCI_VDEVICE(VIA, 0x9000), vt8251 }, + { PCI_VDEVICE(VIA, 0x9040), vt8251 }, { } /* terminate list */ }; --- linux-2.6.28.orig/drivers/ata/Makefile +++ linux-2.6.28/drivers/ata/Makefile @@ -72,6 +72,7 @@ obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o obj-$(CONFIG_PATA_OF_PLATFORM) += pata_of_platform.o obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o +obj-$(CONFIG_PATA_FSL) += pata_fsl.o # Should be last but two libata driver obj-$(CONFIG_PATA_ACPI) += pata_acpi.o # Should be last but one libata driver --- linux-2.6.28.orig/drivers/ata/ata_piix.c +++ linux-2.6.28/drivers/ata/ata_piix.c @@ -1294,6 +1294,39 @@ return map; } +static bool piix_no_sidpr(struct ata_host *host) +{ + struct pci_dev *pdev = to_pci_dev(host->dev); + + /* + * Samsung DB-P70 only has three ATA ports exposed and + * curiously the unconnected first port reports link online + * while not responding to SRST protocol causing excessive + * detection delay. + * + * Unfortunately, the system doesn't carry enough DMI + * information to identify the machine but does have subsystem + * vendor and device set. As it's unclear whether the + * subsystem vendor/device is used only for this specific + * board, the port can't be disabled solely with the + * information; however, turning off SIDPR access works around + * the problem. Turn it off. + * + * This problem is reported in bnc#441240. + * + * https://bugzilla.novell.com/show_bug.cgi?id=441420 + */ + if (pdev->vendor == PCI_VENDOR_ID_INTEL && pdev->device == 0x2920 && + pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG && + pdev->subsystem_device == 0xb049) { + dev_printk(KERN_WARNING, host->dev, + "Samsung DB-P70 detected, disabling SIDPR\n"); + return true; + } + + return false; +} + static int __devinit piix_init_sidpr(struct ata_host *host) { struct pci_dev *pdev = to_pci_dev(host->dev); @@ -1307,6 +1340,10 @@ if (hpriv->map[i] == IDE) return 0; + /* is it blacklisted? */ + if (piix_no_sidpr(host)) + return 0; + if (!(host->ports[0]->flags & PIIX_FLAG_SIDPR)) return 0; --- linux-2.6.28.orig/drivers/ata/pata_fsl.c +++ linux-2.6.28/drivers/ata/pata_fsl.c @@ -0,0 +1,1038 @@ +/* + * Freescale integrated PATA driver + */ + +/* + * Copyright 2007-2009 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "pata_fsl" + +struct pata_fsl_priv { + int ultra; + u8 *fsl_ata_regs; + struct clk *clk; + int dma_rchan; + int dma_wchan; + int dma_done; + int dma_dir; + unsigned int adma_des_paddr; + unsigned int *adma_des_tp; +}; + +struct adma_bd { + unsigned char *sg_buf; + unsigned char *work_buf; + unsigned int dma_address; + int length; +}; + +struct adma_bulk { + struct adma_bd adma_bd_table[MXC_IDE_DMA_BD_NR]; + struct ata_queued_cmd *qc; + int sg_ents; + int reserved[2]; +}; + +enum { + /* various constants */ + FSL_ATA_MAX_SG_LEN = ATA_DMA_BOUNDARY << 1, + + /* offsets to registers */ + FSL_ATA_TIMING_REGS = 0x00, + FSL_ATA_FIFO_FILL = 0x20, + FSL_ATA_CONTROL = 0x24, + FSL_ATA_INT_PEND = 0x28, + FSL_ATA_INT_EN = 0x2C, + FSL_ATA_INT_CLEAR = 0x30, + FSL_ATA_FIFO_ALARM = 0x34, + FSL_ATA_ADMA_ERROR_STATUS = 0x38, + FSL_ATA_SYS_DMA_BADDR = 0x3C, + FSL_ATA_ADMA_SYS_ADDR = 0x40, + FSL_ATA_BLOCK_COUNT = 0x48, + FSL_ATA_BURST_LENGTH = 0x4C, + FSL_ATA_SECTOR_SIZE = 0x50, + FSL_ATA_DRIVE_DATA = 0xA0, + FSL_ATA_DRIVE_CONTROL = 0xD8, + + /* bits within FSL_ATA_CONTROL */ + FSL_ATA_CTRL_DMA_SRST = 0x1000, + FSL_ATA_CTRL_DMA_64ADMA = 0x800, + FSL_ATA_CTRL_DMA_32ADMA = 0x400, + FSL_ATA_CTRL_DMA_STAT_STOP = 0x200, + FSL_ATA_CTRL_DMA_ENABLE = 0x100, + FSL_ATA_CTRL_FIFO_RST_B = 0x80, + FSL_ATA_CTRL_ATA_RST_B = 0x40, + FSL_ATA_CTRL_FIFO_TX_EN = 0x20, + FSL_ATA_CTRL_FIFO_RCV_EN = 0x10, + FSL_ATA_CTRL_DMA_PENDING = 0x08, + FSL_ATA_CTRL_DMA_ULTRA = 0x04, + FSL_ATA_CTRL_DMA_WRITE = 0x02, + FSL_ATA_CTRL_IORDY_EN = 0x01, + + /* bits within the interrupt control registers */ + FSL_ATA_INTR_ATA_INTRQ1 = 0x80, + FSL_ATA_INTR_FIFO_UNDERFLOW = 0x40, + FSL_ATA_INTR_FIFO_OVERFLOW = 0x20, + FSL_ATA_INTR_CTRL_IDLE = 0x10, + FSL_ATA_INTR_ATA_INTRQ2 = 0x08, + FSL_ATA_INTR_DMA_ERR = 0x04, + FSL_ATA_INTR_DMA_TRANS_OVER = 0x02, + + /* ADMA Addr Descriptor Attribute Filed */ + FSL_ADMA_DES_ATTR_VALID = 0x01, + FSL_ADMA_DES_ATTR_END = 0x02, + FSL_ADMA_DES_ATTR_INT = 0x04, + FSL_ADMA_DES_ATTR_SET = 0x10, + FSL_ADMA_DES_ATTR_TRAN = 0x20, + FSL_ADMA_DES_ATTR_LINK = 0x30, +}; + +/* + * This structure contains the timing parameters for + * ATA bus timing in the 5 PIO modes. The timings + * are in nanoseconds, and are converted to clock + * cycles before being stored in the ATA controller + * timing registers. + */ +static struct { + short t0, t1, t2_8, t2_16, t2i, t4, t9, tA; +} pio_specs[] = { + [0] = { + .t0 = 600, .t1 = 70, .t2_8 = 290, .t2_16 = 165, .t2i = 0, .t4 = + 30, .t9 = 20, .tA = 50,}, + [1] = { + .t0 = 383, .t1 = 50, .t2_8 = 290, .t2_16 = 125, .t2i = 0, .t4 = + 20, .t9 = 15, .tA = 50,}, + [2] = { + .t0 = 240, .t1 = 30, .t2_8 = 290, .t2_16 = 100, .t2i = 0, .t4 = + 15, .t9 = 10, .tA = 50,}, + [3] = { + .t0 = 180, .t1 = 30, .t2_8 = 80, .t2_16 = 80, .t2i = 0, .t4 = + 10, .t9 = 10, .tA = 50,}, + [4] = { + .t0 = 120, .t1 = 25, .t2_8 = 70, .t2_16 = 70, .t2i = 0, .t4 = + 10, .t9 = 10, .tA = 50,}, + }; + +#define NR_PIO_SPECS (sizeof pio_specs / sizeof pio_specs[0]) + +/* + * This structure contains the timing parameters for + * ATA bus timing in the 3 MDMA modes. The timings + * are in nanoseconds, and are converted to clock + * cycles before being stored in the ATA controller + * timing registers. + */ +static struct { + short t0M, tD, tH, tJ, tKW, tM, tN, tJNH; +} mdma_specs[] = { + [0] = { + .t0M = 480, .tD = 215, .tH = 20, .tJ = 20, .tKW = 215, .tM = 50, .tN = + 15, .tJNH = 20,}, + [1] = { + .t0M = 150, .tD = 80, .tH = 15, .tJ = 5, .tKW = 50, .tM = 30, .tN = + 10, .tJNH = 15,}, + [2] = { + .t0M = 120, .tD = 70, .tH = 10, .tJ = 5, .tKW = 25, .tM = 25, .tN = + 10, .tJNH = 10,}, + }; + +#define NR_MDMA_SPECS (sizeof mdma_specs / sizeof mdma_specs[0]) + +/* + * This structure contains the timing parameters for + * ATA bus timing in the 6 UDMA modes. The timings + * are in nanoseconds, and are converted to clock + * cycles before being stored in the ATA controller + * timing registers. + */ +static struct { + short t2CYC, tCYC, tDS, tDH, tDVS, tDVH, tCVS, tCVH, tFS_min, tLI_max, + tMLI, tAZ, tZAH, tENV_min, tSR, tRFS, tRP, tACK, tSS, tDZFS; +} udma_specs[] = { + [0] = { + .t2CYC = 235, .tCYC = 114, .tDS = 15, .tDH = 5, .tDVS = 70, .tDVH = + 6, .tCVS = 70, .tCVH = 6, .tFS_min = 0, .tLI_max = + 100, .tMLI = 20, .tAZ = 10, .tZAH = 20, .tENV_min = + 20, .tSR = 50, .tRFS = 75, .tRP = 160, .tACK = 20, .tSS = + 50, .tDZFS = 80,}, + [1] = { + .t2CYC = 156, .tCYC = 75, .tDS = 10, .tDH = 5, .tDVS = 48, .tDVH = + 6, .tCVS = 48, .tCVH = 6, .tFS_min = 0, .tLI_max = + 100, .tMLI = 20, .tAZ = 10, .tZAH = 20, .tENV_min = + 20, .tSR = 30, .tRFS = 70, .tRP = 125, .tACK = 20, .tSS = + 50, .tDZFS = 63,}, + [2] = { + .t2CYC = 117, .tCYC = 55, .tDS = 7, .tDH = 5, .tDVS = 34, .tDVH = + 6, .tCVS = 34, .tCVH = 6, .tFS_min = 0, .tLI_max = + 100, .tMLI = 20, .tAZ = 10, .tZAH = 20, .tENV_min = + 20, .tSR = 20, .tRFS = 60, .tRP = 100, .tACK = 20, .tSS = + 50, .tDZFS = 47,}, + [3] = { + .t2CYC = 86, .tCYC = 39, .tDS = 7, .tDH = 5, .tDVS = 20, .tDVH = + 6, .tCVS = 20, .tCVH = 6, .tFS_min = 0, .tLI_max = + 100, .tMLI = 20, .tAZ = 10, .tZAH = 20, .tENV_min = + 20, .tSR = 20, .tRFS = 60, .tRP = 100, .tACK = 20, .tSS = + 50, .tDZFS = 35,}, + [4] = { + .t2CYC = 57, .tCYC = 25, .tDS = 5, .tDH = 5, .tDVS = 7, .tDVH = + 6, .tCVS = 7, .tCVH = 6, .tFS_min = 0, .tLI_max = + 100, .tMLI = 20, .tAZ = 10, .tZAH = 20, .tENV_min = + 20, .tSR = 50, .tRFS = 60, .tRP = 100, .tACK = 20, .tSS = + 50, .tDZFS = 25,}, + [5] = { + .t2CYC = 38, .tCYC = 17, .tDS = 4, .tDH = 5, .tDVS = 5, .tDVH = + 6, .tCVS = 10, .tCVH = 10, .tFS_min = + 0, .tLI_max = 75, .tMLI = 20, .tAZ = 10, .tZAH = + 20, .tENV_min = 20, .tSR = 20, .tRFS = + 50, .tRP = 85, .tACK = 20, .tSS = 50, .tDZFS = 40,}, +}; + +#define NR_UDMA_SPECS (sizeof udma_specs / sizeof udma_specs[0]) + +struct fsl_ata_time_regs { + u8 time_off, time_on, time_1, time_2w; + u8 time_2r, time_ax, time_pio_rdx, time_4; + u8 time_9, time_m, time_jn, time_d; + u8 time_k, time_ack, time_env, time_rpx; + u8 time_zah, time_mlix, time_dvh, time_dzfs; + u8 time_dvs, time_cvh, time_ss, time_cyc; +}; + +static struct regulator *io_reg; +static struct regulator *core_reg; +static struct adma_bulk adma_info; + +static void +update_timing_config(struct fsl_ata_time_regs *tp, struct ata_host *host) +{ + u32 *lp = (u32 *) tp; + struct pata_fsl_priv *priv = host->private_data; + u32 *ctlp = (u32 *) priv->fsl_ata_regs; + int i; + + for (i = 0; i < 5; i++) { + __raw_writel(*lp, ctlp); + lp++; + ctlp++; + } +} + +/*! + * Calculate values for the ATA bus timing registers and store + * them into the hardware. + * + * @param xfer_mode specifies XFER xfer_mode + * @param pdev specifies platform_device + * + * @return EINVAL speed out of range, or illegal mode + */ +static int set_ata_bus_timing(u8 xfer_mode, struct platform_device *pdev) +{ + struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct pata_fsl_priv *priv = host->private_data; + + /* get the bus clock cycle time, in ns */ + int T = 1 * 1000 * 1000 * 1000 / clk_get_rate(priv->clk); + struct fsl_ata_time_regs tr = { 0 }; + + /* + * every mode gets the same t_off and t_on + */ + tr.time_off = 3; + tr.time_on = 3; + + if (xfer_mode >= XFER_UDMA_0) { + int speed = xfer_mode - XFER_UDMA_0; + if (speed >= NR_UDMA_SPECS) + return -EINVAL; + + tr.time_ack = (udma_specs[speed].tACK + T) / T; + tr.time_env = (udma_specs[speed].tENV_min + T) / T; + tr.time_rpx = (udma_specs[speed].tRP + T) / T + 2; + tr.time_zah = (udma_specs[speed].tZAH + T) / T; + tr.time_mlix = (udma_specs[speed].tMLI + T) / T; + tr.time_dvh = (udma_specs[speed].tDVH + T) / T + 1; + tr.time_dzfs = (udma_specs[speed].tDZFS + T) / T; + + tr.time_dvs = (udma_specs[speed].tDVS + T) / T; + tr.time_cvh = (udma_specs[speed].tCVH + T) / T; + tr.time_ss = (udma_specs[speed].tSS + T) / T; + tr.time_cyc = (udma_specs[speed].tCYC + T) / T; + } else if (xfer_mode >= XFER_MW_DMA_0) { + int speed = xfer_mode - XFER_MW_DMA_0; + if (speed >= NR_MDMA_SPECS) + return -EINVAL; + + tr.time_m = (mdma_specs[speed].tM + T) / T; + tr.time_jn = (mdma_specs[speed].tJNH + T) / T; + tr.time_d = (mdma_specs[speed].tD + T) / T; + + tr.time_k = (mdma_specs[speed].tKW + T) / T; + } else { + int speed = xfer_mode - XFER_PIO_0; + if (speed >= NR_PIO_SPECS) + return -EINVAL; + + tr.time_1 = (pio_specs[speed].t1 + T) / T; + tr.time_2w = (pio_specs[speed].t2_8 + T) / T; + + tr.time_2r = (pio_specs[speed].t2_8 + T) / T; + tr.time_ax = (pio_specs[speed].tA + T) / T + 2; + tr.time_pio_rdx = 1; + tr.time_4 = (pio_specs[speed].t4 + T) / T; + + tr.time_9 = (pio_specs[speed].t9 + T) / T; + } + + update_timing_config(&tr, host); + + return 0; +} + +static void pata_fsl_set_piomode(struct ata_port *ap, struct ata_device *adev) +{ + set_ata_bus_timing(adev->pio_mode, to_platform_device(ap->dev)); +} + +static void pata_fsl_set_dmamode(struct ata_port *ap, struct ata_device *adev) +{ + struct pata_fsl_priv *priv = ap->host->private_data; + + priv->ultra = adev->dma_mode >= XFER_UDMA_0; + + set_ata_bus_timing(adev->dma_mode, to_platform_device(ap->dev)); +} + +static int pata_fsl_port_start(struct ata_port *ap) +{ + return 0; +} + +static void pata_adma_bulk_unmap(struct ata_queued_cmd *qc) +{ + int i; + struct adma_bd *bdp = adma_info.adma_bd_table; + if (adma_info.qc == NULL) + return; + BUG_ON(adma_info.qc != qc); + + adma_info.qc = NULL; + + for (i = 0; i < adma_info.sg_ents; i++) { + if (bdp->work_buf != bdp->sg_buf) { + if (qc->dma_dir == DMA_FROM_DEVICE) { + memcpy(bdp->sg_buf, bdp->work_buf, bdp->length); + dma_cache_maint(bdp->sg_buf, bdp->length, + DMA_FROM_DEVICE); + } + dma_free_coherent(qc->ap->dev, bdp->length, + bdp->work_buf, bdp->dma_address); + } + bdp->work_buf = bdp->sg_buf = NULL; + bdp++; + } +} + +static int pata_adma_bulk_map(struct ata_queued_cmd *qc) +{ + unsigned int si; + struct scatterlist *sg; + struct adma_bd *bdp = adma_info.adma_bd_table; + + BUG_ON(adma_info.qc); + + adma_info.qc = qc; + adma_info.sg_ents = 0; + + for_each_sg(qc->sg, sg, qc->n_elem, si) { + /* + * The ADMA mode is used setup the ADMA descriptor table + */ + bdp->sg_buf = sg_virt(sg); + bdp->length = sg->length; + if (sg->dma_address & 0xFFF) { + bdp->work_buf = + dma_alloc_coherent(qc->ap->dev, bdp->length, + &bdp->dma_address, GFP_KERNEL); + if (!bdp->work_buf) { + printk(KERN_WARNING + "can not allocate aligned buffer\n"); + goto fail; + } + if (qc->dma_dir == DMA_TO_DEVICE) + memcpy(bdp->work_buf, bdp->sg_buf, bdp->length); + } else { + bdp->work_buf = bdp->sg_buf; + bdp->dma_address = sg->dma_address; + } + + adma_info.sg_ents++; + bdp++; + } + return 0; + fail: + pata_adma_bulk_unmap(qc); + return -1; +} + +static void dma_callback(void *arg, int error_status, unsigned int count) +{ + struct ata_port *ap = arg; + struct pata_fsl_priv *priv = ap->host->private_data; + u8 *ata_regs = priv->fsl_ata_regs; + + priv->dma_done = 1; + /* + * DMA is finished, so unmask INTRQ from the drive to allow the + * normal ISR to fire. + */ + __raw_writel(FSL_ATA_INTR_ATA_INTRQ2, ata_regs + FSL_ATA_INT_EN); +} + +static irqreturn_t pata_fsl_adma_intr(int irq, void *dev_instance) +{ + struct ata_host *host = dev_instance; + struct pata_fsl_priv *priv = host->private_data; + u8 *ata_regs = priv->fsl_ata_regs; + unsigned int handled = 0; + unsigned int i; + unsigned long flags; + unsigned int pending = __raw_readl(ata_regs + FSL_ATA_INT_PEND); + + if (FSL_ATA_INTR_DMA_TRANS_OVER & pending) { + priv->dma_done = 1; + __raw_writel(pending, ata_regs + FSL_ATA_INT_CLEAR); + handled = 1; + } else if (FSL_ATA_INTR_DMA_ERR & pending) { + printk(KERN_ERR "dma err status 0x%x ...\n", + __raw_readl(ata_regs + FSL_ATA_ADMA_ERROR_STATUS)); + __raw_writel(pending, ata_regs + FSL_ATA_INT_CLEAR); + handled = 1; + i = __raw_readl(ata_regs + FSL_ATA_CONTROL) && 0xFF; + i |= FSL_ATA_CTRL_DMA_SRST | FSL_ATA_CTRL_DMA_32ADMA | + FSL_ATA_CTRL_DMA_ENABLE; + __raw_writel(i, ata_regs + FSL_ATA_CONTROL); + } + + spin_lock_irqsave(&host->lock, flags); + + for (i = 0; i < host->n_ports; i++) { + struct ata_port *ap; + + ap = host->ports[i]; + if (ap && !(ap->flags & ATA_FLAG_DISABLED)) { + struct ata_queued_cmd *qc; + + qc = ata_qc_from_tag(ap, ap->link.active_tag); + raw_local_irq_restore(flags); + pata_adma_bulk_unmap(qc); + raw_local_irq_save(flags); + if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)) && + (qc->flags & ATA_QCFLAG_ACTIVE)) + handled |= ata_sff_host_intr(ap, qc); + } + } + + spin_unlock_irqrestore(&host->lock, flags); + + return IRQ_RETVAL(handled); +} + +static int pata_fsl_check_atapi_dma(struct ata_queued_cmd *qc) +{ + return 1; /* ATAPI DMA not yet supported */ +} + +unsigned long pata_fsl_bmdma_mode_filter(struct ata_device *adev, + unsigned long xfer_mask) +{ + /* Capability of the controller has been specified in the + * platform data. Do not filter any modes, just return + * the xfer_mask */ + return xfer_mask; +} + +static void pata_fsl_bmdma_setup(struct ata_queued_cmd *qc) +{ + int chan, i; + int dma_mode = 0, dma_ultra; + u32 ata_control; + struct ata_port *ap = qc->ap; + struct pata_fsl_priv *priv = ap->host->private_data; + u8 *ata_regs = priv->fsl_ata_regs; + struct fsl_ata_platform_data *plat = ap->dev->platform_data; + int err; + unsigned int si; + + priv->dma_dir = qc->dma_dir; + + /* + * Configure the on-chip ATA interface hardware. + */ + dma_ultra = priv->ultra ? FSL_ATA_CTRL_DMA_ULTRA : 0; + + ata_control = FSL_ATA_CTRL_FIFO_RST_B | + FSL_ATA_CTRL_ATA_RST_B | FSL_ATA_CTRL_DMA_PENDING | dma_ultra; + if (plat->adma_flag) + ata_control |= FSL_ATA_CTRL_DMA_32ADMA | + FSL_ATA_CTRL_DMA_ENABLE; + + if (qc->dma_dir == DMA_TO_DEVICE) { + chan = priv->dma_wchan; + ata_control |= FSL_ATA_CTRL_FIFO_TX_EN | FSL_ATA_CTRL_DMA_WRITE; + dma_mode = DMA_MODE_WRITE; + } else { + chan = priv->dma_rchan; + ata_control |= FSL_ATA_CTRL_FIFO_RCV_EN; + dma_mode = DMA_MODE_READ; + } + + __raw_writel(ata_control, ata_regs + FSL_ATA_CONTROL); + __raw_writel(plat->fifo_alarm, ata_regs + FSL_ATA_FIFO_ALARM); + + if (plat->adma_flag) { + i = FSL_ATA_INTR_DMA_TRANS_OVER | FSL_ATA_INTR_DMA_ERR; + __raw_writel(FSL_ATA_INTR_ATA_INTRQ2 | i, + ata_regs + FSL_ATA_INT_EN); + } else { + __raw_writel(FSL_ATA_INTR_ATA_INTRQ1, + ata_regs + FSL_ATA_INT_EN); + /* + * Set up the DMA completion callback. + */ + mxc_dma_callback_set(chan, dma_callback, (void *)ap); + } + + /* + * Copy the sg list to an array. + */ + if (plat->adma_flag) { + struct adma_bd *bdp = adma_info.adma_bd_table; + pata_adma_bulk_map(qc); + for (i = 0; i < adma_info.sg_ents; i++) { + priv->adma_des_tp[i << 1] = bdp->length << 12; + priv->adma_des_tp[i << 1] |= FSL_ADMA_DES_ATTR_SET; + priv->adma_des_tp[i << 1] |= FSL_ADMA_DES_ATTR_VALID; + priv->adma_des_tp[(i << 1) + 1] = bdp->dma_address; + priv->adma_des_tp[(i << 1) + 1] |= + FSL_ADMA_DES_ATTR_TRAN; + priv->adma_des_tp[(i << 1) + 1] |= + FSL_ADMA_DES_ATTR_VALID; + if (adma_info.sg_ents == (i + 1)) + priv->adma_des_tp[(i << 1) + 1] |= + FSL_ADMA_DES_ATTR_END; + bdp++; + } + __raw_writel((qc->nbytes / qc->sect_size), ata_regs + + FSL_ATA_BLOCK_COUNT); + __raw_writel(plat->fifo_alarm, ata_regs + FSL_ATA_BURST_LENGTH); + __raw_writel(priv->adma_des_paddr, + ata_regs + FSL_ATA_ADMA_SYS_ADDR); + } else { + int nr_sg = 0; + struct scatterlist tmp[MXC_IDE_DMA_BD_NR], *tsg, *sg; + tsg = tmp; + for_each_sg(qc->sg, sg, qc->n_elem, si) { + memcpy(tsg, sg, sizeof(*sg)); + tsg++; + nr_sg++; + } + err = mxc_dma_sg_config(chan, tmp, nr_sg, 0, dma_mode); + if (err) + printk(KERN_ERR "pata_fsl_bmdma_setup: error %d\n", + err); + } +} + +static void pata_fsl_bmdma_start(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + struct pata_fsl_priv *priv = ap->host->private_data; + u8 *ata_regs = priv->fsl_ata_regs; + struct fsl_ata_platform_data *plat = ap->dev->platform_data; + int chan; + int err; + unsigned i; + + if (1 == plat->adma_flag) { + i = FSL_ATA_CTRL_DMA_32ADMA | FSL_ATA_CTRL_DMA_ENABLE; + /* The adma mode is used, set dma_start_stop to 1 */ + __raw_writel(i | __raw_readl(ata_regs + FSL_ATA_CONTROL) | + FSL_ATA_CTRL_DMA_STAT_STOP, + ata_regs + FSL_ATA_CONTROL); + } else { + /* + * Start the channel. + */ + chan = qc->dma_dir == DMA_TO_DEVICE ? priv->dma_wchan : + priv->dma_rchan; + + err = mxc_dma_enable(chan); + if (err) + printk(KERN_ERR "%s: : error %d\n", __func__, err); + } + + priv->dma_done = 0; + + ata_sff_exec_command(ap, &qc->tf); +} + +static void pata_fsl_bmdma_stop(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + struct pata_fsl_priv *priv = ap->host->private_data; + u8 *ata_regs = priv->fsl_ata_regs; + struct fsl_ata_platform_data *plat = ap->dev->platform_data; + unsigned i; + + if (plat->adma_flag) { + /* The adma mode is used, set dma_start_stop to 0 */ + i = FSL_ATA_CTRL_DMA_32ADMA | FSL_ATA_CTRL_DMA_ENABLE; + __raw_writel((i | __raw_readl(ata_regs + FSL_ATA_CONTROL)) & + (~FSL_ATA_CTRL_DMA_STAT_STOP), + ata_regs + FSL_ATA_CONTROL); + } + + /* do a dummy read as in ata_bmdma_stop */ +#if 0 + ata_sff_dma_pause(ap); +#endif +} + +static u8 pata_fsl_bmdma_status(struct ata_port *ap) +{ + struct pata_fsl_priv *priv = ap->host->private_data; + + return priv->dma_done ? ATA_DMA_INTR : 0; +} + +static void pata_fsl_dma_init(struct ata_port *ap) +{ + struct pata_fsl_priv *priv = ap->host->private_data; + + priv->dma_rchan = -1; + priv->dma_wchan = -1; + + priv->dma_rchan = mxc_dma_request(MXC_DMA_ATA_RX, "MXC ATA RX"); + if (priv->dma_rchan < 0) { + dev_printk(KERN_ERR, ap->dev, "couldn't get RX DMA channel\n"); + goto err_out; + } + + priv->dma_wchan = mxc_dma_request(MXC_DMA_ATA_TX, "MXC ATA TX"); + if (priv->dma_wchan < 0) { + dev_printk(KERN_ERR, ap->dev, "couldn't get TX DMA channel\n"); + goto err_out; + } + + dev_printk(KERN_ERR, ap->dev, "rchan=%d wchan=%d\n", priv->dma_rchan, + priv->dma_wchan); + return; + + err_out: + ap->mwdma_mask = 0; + ap->udma_mask = 0; + mxc_dma_free(priv->dma_rchan); + mxc_dma_free(priv->dma_wchan); + kfree(priv); +} + +#if 0 +static u8 pata_fsl_irq_ack(struct ata_port *ap, unsigned int chk_drq) +{ + unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY; + u8 status; + + status = ata_sff_busy_wait(ap, bits, 1000); + if (status & bits) + if (ata_msg_err(ap)) + printk(KERN_ERR "abnormal status 0x%X\n", status); + + return status; +} +#endif + +static void ata_dummy_noret(struct ata_port *ap) +{ + return; +} + +static struct scsi_host_template pata_fsl_sht = { + .module = THIS_MODULE, + .name = DRV_NAME, + .ioctl = ata_scsi_ioctl, + .queuecommand = ata_scsi_queuecmd, + .can_queue = ATA_DEF_QUEUE, + .this_id = ATA_SHT_THIS_ID, + .sg_tablesize = LIBATA_MAX_PRD, + .cmd_per_lun = ATA_SHT_CMD_PER_LUN, + .emulated = ATA_SHT_EMULATED, + .use_clustering = ATA_SHT_USE_CLUSTERING, + .proc_name = DRV_NAME, + .dma_boundary = FSL_ATA_MAX_SG_LEN, + .slave_configure = ata_scsi_slave_config, + .slave_destroy = ata_scsi_slave_destroy, + .bios_param = ata_std_bios_param, +}; + +static struct ata_port_operations pata_fsl_port_ops = { + .inherits = &ata_bmdma_port_ops, + .set_piomode = pata_fsl_set_piomode, + .set_dmamode = pata_fsl_set_dmamode, + + .check_atapi_dma = pata_fsl_check_atapi_dma, + .cable_detect = ata_cable_unknown, + .mode_filter = pata_fsl_bmdma_mode_filter, + + .bmdma_setup = pata_fsl_bmdma_setup, + .bmdma_start = pata_fsl_bmdma_start, + .bmdma_stop = pata_fsl_bmdma_stop, + .bmdma_status = pata_fsl_bmdma_status, + + .qc_prep = ata_noop_qc_prep, + + .sff_data_xfer = ata_sff_data_xfer_noirq, + .sff_irq_clear = ata_dummy_noret, + .sff_irq_on = ata_sff_irq_on, + + .port_start = pata_fsl_port_start, +}; + +static void fsl_setup_port(struct ata_ioports *ioaddr) +{ + unsigned int shift = 2; + + ioaddr->data_addr = ioaddr->cmd_addr + (ATA_REG_DATA << shift); + ioaddr->error_addr = ioaddr->cmd_addr + (ATA_REG_ERR << shift); + ioaddr->feature_addr = ioaddr->cmd_addr + (ATA_REG_FEATURE << shift); + ioaddr->nsect_addr = ioaddr->cmd_addr + (ATA_REG_NSECT << shift); + ioaddr->lbal_addr = ioaddr->cmd_addr + (ATA_REG_LBAL << shift); + ioaddr->lbam_addr = ioaddr->cmd_addr + (ATA_REG_LBAM << shift); + ioaddr->lbah_addr = ioaddr->cmd_addr + (ATA_REG_LBAH << shift); + ioaddr->device_addr = ioaddr->cmd_addr + (ATA_REG_DEVICE << shift); + ioaddr->status_addr = ioaddr->cmd_addr + (ATA_REG_STATUS << shift); + ioaddr->command_addr = ioaddr->cmd_addr + (ATA_REG_CMD << shift); +} + +/** + * pata_fsl_probe - attach a platform interface + * @pdev: platform device + * + * Register a platform bus integrated ATA host controller + * + * The 3 platform device resources are used as follows: + * + * - I/O Base (IORESOURCE_MEM) virt. addr. of ATA controller regs + * - CTL Base (IORESOURCE_MEM) unused + * - IRQ (IORESOURCE_IRQ) platform IRQ assigned to ATA + * + */ +static int __devinit pata_fsl_probe(struct platform_device *pdev) +{ + int ret = 0; + struct resource *io_res; + struct ata_host *host; + struct ata_port *ap; + struct fsl_ata_platform_data *plat = (struct fsl_ata_platform_data *) + pdev->dev.platform_data; + struct pata_fsl_priv *priv; + u8 *ata_regs; + unsigned int int_enable; + + /* + * Set up resources + */ + if (unlikely(pdev->num_resources != 3)) { + dev_err(&pdev->dev, "invalid number of resources\n"); + return -EINVAL; + } + /* + * Get an ata_host structure for this device + */ + host = ata_host_alloc(&pdev->dev, 1); + if (!host) + return -ENOMEM; + ap = host->ports[0]; + + /* + * Allocate private data + */ + priv = kzalloc(sizeof(struct pata_fsl_priv), GFP_KERNEL); + if (priv == NULL) { + ret = -ENOMEM; + goto err0; + } + host->private_data = priv; + + /* + * Set up resources + */ + io_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + ata_regs = + (u8 *) ioremap(io_res->start, io_res->end - io_res->start + 1); + priv->fsl_ata_regs = ata_regs; + ap->ioaddr.cmd_addr = (void *)(ata_regs + FSL_ATA_DRIVE_DATA); + ap->ioaddr.ctl_addr = (void *)(ata_regs + FSL_ATA_DRIVE_CONTROL); + ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr; + ap->ops = &pata_fsl_port_ops; + ap->pio_mask = plat->pio_mask; /* support pio 0~4 */ + ap->mwdma_mask = plat->mwdma_mask; /* support mdma 0~2 */ + ap->udma_mask = plat->udma_mask; + pata_fsl_sht.sg_tablesize = plat->max_sg; + fsl_setup_port(&ap->ioaddr); + + if (plat->adma_flag) { + priv->adma_des_tp = + dma_alloc_coherent(&(pdev->dev), + (2 * MXC_IDE_DMA_BD_NR) * + sizeof(unsigned int), + &(priv->adma_des_paddr), GFP_DMA); + if (priv->adma_des_tp == NULL) { + ret = -ENOMEM; + goto err1; + } + } + /* + * Do platform-specific initialization (e.g. allocate pins, + * turn on clock). After this call it is assumed that + * plat->get_clk_rate() can be called to calculate + * timing. + */ + if (plat->init && plat->init(pdev)) { + ret = -ENODEV; + goto err2; + } + + priv->clk = clk_get(&pdev->dev, "ata_clk"); + clk_enable(priv->clk); + + /* Deassert the reset bit to enable the interface */ + __raw_writel(FSL_ATA_CTRL_ATA_RST_B, ata_regs + FSL_ATA_CONTROL); + + /* Enable Core regulator & IO Regulator */ + if (plat->core_reg != NULL) { + core_reg = regulator_get(&pdev->dev, plat->core_reg); + if (regulator_enable(core_reg)) + printk(KERN_INFO "enable core regulator error.\n"); + msleep(100); + + } else + core_reg = NULL; + + if (plat->io_reg != NULL) { + io_reg = regulator_get(&pdev->dev, plat->io_reg); + if (regulator_enable(io_reg)) + printk(KERN_INFO "enable io regulator error.\n"); + msleep(100); + + } else + io_reg = NULL; + + /* Set initial timing and mode */ + set_ata_bus_timing(XFER_PIO_4, pdev); + + /* get DMA ready */ + if (plat->adma_flag == 0) + pata_fsl_dma_init(ap); + + /* + * Enable the ATA INTRQ interrupt from the bus, but + * only allow the CPU to see it (INTRQ2) at this point. + * INTRQ1, which goes to the DMA, will be enabled later. + */ + int_enable = FSL_ATA_INTR_DMA_TRANS_OVER | FSL_ATA_INTR_DMA_ERR | + FSL_ATA_INTR_ATA_INTRQ2; + if (plat->adma_flag) + __raw_writel(int_enable, ata_regs + FSL_ATA_INT_EN); + else + __raw_writel(FSL_ATA_INTR_ATA_INTRQ2, + ata_regs + FSL_ATA_INT_EN); + + /* activate */ + if (plat->adma_flag) + ret = ata_host_activate(host, platform_get_irq(pdev, 0), + pata_fsl_adma_intr, 0, &pata_fsl_sht); + else + ret = ata_host_activate(host, platform_get_irq(pdev, 0), + ata_sff_interrupt, 0, &pata_fsl_sht); + + if (!ret) + return ret; + + clk_disable(priv->clk); + regulator_disable(core_reg); + regulator_disable(io_reg); + err2: + if (plat->adma_flag && priv->adma_des_tp) + dma_free_coherent(&(pdev->dev), + (2 * MXC_IDE_DMA_BD_NR + + 1) * sizeof(unsigned int), priv->adma_des_tp, + priv->adma_des_paddr); + err1: + iounmap(ata_regs); + kfree(priv); + err0: + ata_host_detach(host); + return ret; + +} + +/** + * pata_fsl_remove - unplug a platform interface + * @pdev: platform device + * + * A platform bus ATA device has been unplugged. Perform the needed + * cleanup. Also called on module unload for any active devices. + */ +static int __devexit pata_fsl_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct ata_host *host = dev_get_drvdata(dev); + struct pata_fsl_priv *priv = host->private_data; + struct fsl_ata_platform_data *plat = (struct fsl_ata_platform_data *) + pdev->dev.platform_data; + u8 *ata_regs = priv->fsl_ata_regs; + + __raw_writel(0, ata_regs + FSL_ATA_INT_EN); /* Disable interrupts */ + + ata_host_detach(host); + + clk_disable(priv->clk); + clk_put(priv->clk); + priv->clk = NULL; + + /* Disable Core regulator & IO Regulator */ + if (plat->core_reg != NULL) { + regulator_disable(core_reg); + regulator_put(core_reg); + } + if (plat->io_reg != NULL) { + regulator_disable(io_reg); + regulator_put(io_reg); + } + + if (plat->exit) + plat->exit(); + + if (plat->adma_flag && priv->adma_des_tp) + dma_free_coherent(&(pdev->dev), + (2 * MXC_IDE_DMA_BD_NR) * + sizeof(unsigned int), priv->adma_des_tp, + priv->adma_des_paddr); + iounmap(ata_regs); + + kfree(priv); + + return 0; +} + +#ifdef CONFIG_PM +static int pata_fsl_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct pata_fsl_priv *priv = host->private_data; + struct fsl_ata_platform_data *plat = (struct fsl_ata_platform_data *) + pdev->dev.platform_data; + u8 *ata_regs = priv->fsl_ata_regs; + + /* Disable interrupts. */ + __raw_writel(0, ata_regs + FSL_ATA_INT_EN); + + clk_disable(priv->clk); + + if (plat->exit) + plat->exit(); + + return 0; +} + +static int pata_fsl_resume(struct platform_device *pdev) +{ + struct ata_host *host = dev_get_drvdata(&pdev->dev); + struct pata_fsl_priv *priv = host->private_data; + struct fsl_ata_platform_data *plat = (struct fsl_ata_platform_data *) + pdev->dev.platform_data; + u8 *ata_regs = priv->fsl_ata_regs; + unsigned char int_enable; + + if (plat->init && plat->init(pdev)) + return -ENODEV; + + clk_enable(priv->clk); + + /* Deassert the reset bit to enable the interface */ + __raw_writel(FSL_ATA_CTRL_ATA_RST_B, ata_regs + FSL_ATA_CONTROL); + + /* Set initial timing and mode */ + set_ata_bus_timing(XFER_PIO_4, pdev); + + /* + * Enable hardware interrupts. + */ + int_enable = FSL_ATA_INTR_DMA_TRANS_OVER | FSL_ATA_INTR_DMA_ERR | + FSL_ATA_INTR_ATA_INTRQ2; + if (1 == plat->adma_flag) + __raw_writel(int_enable, ata_regs + FSL_ATA_INT_EN); + else + __raw_writel(FSL_ATA_INTR_ATA_INTRQ2, + ata_regs + FSL_ATA_INT_EN); + + return 0; +} +#endif + +static struct platform_driver pata_fsl_driver = { + .probe = pata_fsl_probe, + .remove = __devexit_p(pata_fsl_remove), +#ifdef CONFIG_PM + .suspend = pata_fsl_suspend, + .resume = pata_fsl_resume, +#endif + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, +}; + +static int __init pata_fsl_init(void) +{ + return platform_driver_register(&pata_fsl_driver); + + return 0; +} + +static void __exit pata_fsl_exit(void) +{ + platform_driver_unregister(&pata_fsl_driver); +} + +module_init(pata_fsl_init); +module_exit(pata_fsl_exit); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("low-level driver for Freescale ATA"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/firmware/dell_rbu.c +++ linux-2.6.28/drivers/firmware/dell_rbu.c @@ -576,7 +576,7 @@ { int size = 0; if (!pos) - size = sprintf(buffer, "%s\n", image_type); + size = scnprintf(buffer, count, "%s\n", image_type); return size; } @@ -648,7 +648,7 @@ int size = 0; if (!pos) { spin_lock(&rbu_data.lock); - size = sprintf(buffer, "%lu\n", rbu_data.packetsize); + size = scnprintf(buffer, count, "%lu\n", rbu_data.packetsize); spin_unlock(&rbu_data.lock); } return size; --- linux-2.6.28.orig/drivers/firmware/dmi_scan.c +++ linux-2.6.28/drivers/firmware/dmi_scan.c @@ -467,6 +467,17 @@ } EXPORT_SYMBOL(dmi_get_system_info); +/** + * dmi_name_in_serial - Check if string is in the DMI product serial + * information. + */ +int dmi_name_in_serial(const char *str) +{ + int f = DMI_PRODUCT_SERIAL; + if (dmi_ident[f] && strstr(dmi_ident[f], str)) + return 1; + return 0; +} /** * dmi_name_in_vendors - Check if string is anywhere in the DMI vendor information. --- linux-2.6.28.orig/drivers/scsi/eata.c +++ linux-2.6.28/drivers/scsi/eata.c @@ -1626,8 +1626,15 @@ cpp->sense_len = SCSI_SENSE_BUFFERSIZE; - count = scsi_dma_map(SCpnt); - BUG_ON(count < 0); + if (!scsi_sg_count(SCpnt)) { + cpp->data_len = 0; + return; + } + + count = pci_map_sg(ha->pdev, scsi_sglist(SCpnt), scsi_sg_count(SCpnt), + pci_dir); + BUG_ON(!count); + scsi_for_each_sg(SCpnt, sg, count, k) { cpp->sglist[k].address = H2DEV(sg_dma_address(sg)); cpp->sglist[k].num_bytes = H2DEV(sg_dma_len(sg)); @@ -1655,7 +1662,9 @@ pci_unmap_single(ha->pdev, DEV2H(cpp->sense_addr), DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE); - scsi_dma_unmap(SCpnt); + if (scsi_sg_count(SCpnt)) + pci_unmap_sg(ha->pdev, scsi_sglist(SCpnt), scsi_sg_count(SCpnt), + pci_dir); if (!DEV2H(cpp->data_len)) pci_dir = PCI_DMA_BIDIRECTIONAL; --- linux-2.6.28.orig/drivers/scsi/hptiop.c +++ linux-2.6.28/drivers/scsi/hptiop.c @@ -1251,6 +1251,7 @@ { PCI_VDEVICE(TTI, 0x3530), (kernel_ulong_t)&hptiop_itl_ops }, { PCI_VDEVICE(TTI, 0x3560), (kernel_ulong_t)&hptiop_itl_ops }, { PCI_VDEVICE(TTI, 0x4322), (kernel_ulong_t)&hptiop_itl_ops }, + { PCI_VDEVICE(TTI, 0x4321), (kernel_ulong_t)&hptiop_itl_ops }, { PCI_VDEVICE(TTI, 0x4210), (kernel_ulong_t)&hptiop_itl_ops }, { PCI_VDEVICE(TTI, 0x4211), (kernel_ulong_t)&hptiop_itl_ops }, { PCI_VDEVICE(TTI, 0x4310), (kernel_ulong_t)&hptiop_itl_ops }, --- linux-2.6.28.orig/drivers/scsi/libiscsi.c +++ linux-2.6.28/drivers/scsi/libiscsi.c @@ -1899,6 +1899,7 @@ kfree(q->pool[i]); if (q->pool) kfree(q->pool); + kfree(q->queue); } EXPORT_SYMBOL_GPL(iscsi_pool_free); --- linux-2.6.28.orig/drivers/scsi/mvsas.c +++ linux-2.6.28/drivers/scsi/mvsas.c @@ -2959,7 +2959,7 @@ /* enable auto port detection */ mw32(GBL_PORT_TYPE, MODE_AUTO_DET_EN); - msleep(100); + msleep(1100); /* init and reset phys */ for (i = 0; i < mvi->chip->n_phy; i++) { u32 lo = be32_to_cpu(*(u32 *)&mvi->sas_addr[4]); --- linux-2.6.28.orig/drivers/scsi/scsi_transport_fc.c +++ linux-2.6.28/drivers/scsi/scsi_transport_fc.c @@ -455,10 +455,30 @@ 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. Value should be" + " exceeded, the scsi target may be removed. Reference the" + " remove_on_dev_loss module parameter. Value should be" " between 1 and SCSI_DEVICE_BLOCK_MAX_TIMEOUT."); /* + * remove_on_dev_loss: controls whether the transport will + * remove a scsi target after the device loss timer expires. + * Removal on disconnect is modeled after the USB subsystem + * and expects subsystems layered on SCSI to be aware of + * potential device loss and handle it appropriately. However, + * many subsystems do not support device removal, leaving situations + * where structure references may remain, causing new device + * name assignments, etc., if the target returns. + */ +static unsigned int fc_remove_on_dev_loss = 0; +module_param_named(remove_on_dev_loss, fc_remove_on_dev_loss, + int, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(remove_on_dev_loss, + "Boolean. When the device loss timer fires, this variable" + " controls whether the scsi infrastructure for the target" + " device is removed. Values: zero means do not remove," + " non-zero means remove. Default is zero."); + +/** * Netlink Infrastructure */ @@ -2357,7 +2377,8 @@ container_of(work, struct fc_rport, stgt_delete_work); fc_terminate_rport_io(rport); - scsi_remove_target(&rport->dev); + if (fc_remove_on_dev_loss) + scsi_remove_target(&rport->dev); } @@ -2991,9 +3012,13 @@ return; } - dev_printk(KERN_ERR, &rport->dev, - "blocked FC remote port time out: removing target and " - "saving binding\n"); + if (fc_remove_on_dev_loss) + dev_printk(KERN_ERR, &rport->dev, + "blocked FC remote port time out: removing target and " + "saving binding\n"); + else + dev_printk(KERN_ERR, &rport->dev, + "blocked FC remote port time out: saving binding\n"); list_move_tail(&rport->peers, &fc_host->rport_bindings); --- linux-2.6.28.orig/drivers/scsi/scsi_transport_iscsi.c +++ linux-2.6.28/drivers/scsi/scsi_transport_iscsi.c @@ -22,6 +22,8 @@ */ #include #include +#include +#include #include #include #include @@ -2016,3 +2018,4 @@ MODULE_DESCRIPTION("iSCSI Transport Interface"); MODULE_LICENSE("GPL"); MODULE_VERSION(ISCSI_TRANSPORT_VERSION); +MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_ISCSI); --- linux-2.6.28.orig/drivers/scsi/sd.c +++ linux-2.6.28/drivers/scsi/sd.c @@ -106,6 +106,7 @@ static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); static void sd_print_result(struct scsi_disk *, int); +static DEFINE_SPINLOCK(sd_index_lock); static DEFINE_IDA(sd_index_ida); /* This semaphore is used to mediate the 0->1 reference get in the @@ -1847,7 +1848,9 @@ if (!ida_pre_get(&sd_index_ida, GFP_KERNEL)) goto out_put; + spin_lock(&sd_index_lock); error = ida_get_new(&sd_index_ida, &index); + spin_unlock(&sd_index_lock); } while (error == -EAGAIN); if (error) @@ -1910,7 +1913,9 @@ return 0; out_free_index: + spin_lock(&sd_index_lock); ida_remove(&sd_index_ida, index); + spin_unlock(&sd_index_lock); out_put: put_disk(gd); out_free: @@ -1960,7 +1965,9 @@ struct scsi_disk *sdkp = to_scsi_disk(dev); struct gendisk *disk = sdkp->disk; + spin_lock(&sd_index_lock); ida_remove(&sd_index_ida, sdkp->index); + spin_unlock(&sd_index_lock); disk->private_data = NULL; put_disk(disk); --- linux-2.6.28.orig/drivers/scsi/ibmvscsi/ibmvfc.h +++ linux-2.6.28/drivers/scsi/ibmvscsi/ibmvfc.h @@ -33,7 +33,7 @@ #define IBMVFC_DRIVER_DATE "(August 14, 2008)" #define IBMVFC_DEFAULT_TIMEOUT 15 -#define IBMVFC_INIT_TIMEOUT 30 +#define IBMVFC_INIT_TIMEOUT 120 #define IBMVFC_MAX_REQUESTS_DEFAULT 100 #define IBMVFC_DEBUG 0 @@ -43,7 +43,8 @@ #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_MAX_HOST_INIT_RETRIES 6 +#define IBMVFC_MAX_TGT_INIT_RETRIES 3 #define IBMVFC_DEV_LOSS_TMO (5 * 60) #define IBMVFC_DEFAULT_LOG_LEVEL 2 #define IBMVFC_MAX_CDB_LEN 16 @@ -671,6 +672,7 @@ int discovery_threads; int client_migrated; int reinit; + int delay_init; int events_to_log; #define IBMVFC_AE_LINKUP 0x0001 #define IBMVFC_AE_LINKDOWN 0x0002 --- linux-2.6.28.orig/drivers/scsi/ibmvscsi/ibmvfc.c +++ linux-2.6.28/drivers/scsi/ibmvscsi/ibmvfc.c @@ -566,7 +566,7 @@ struct ibmvfc_target *tgt; if (vhost->action == IBMVFC_HOST_ACTION_INIT_WAIT) { - if (++vhost->init_retries > IBMVFC_MAX_INIT_RETRIES) { + if (++vhost->init_retries > IBMVFC_MAX_HOST_INIT_RETRIES) { dev_err(vhost->dev, "Host initialization retries exceeded. Taking adapter offline\n"); ibmvfc_link_down(vhost, IBMVFC_HOST_OFFLINE); @@ -847,11 +847,12 @@ 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) { + vhost->delay_init = 1; + if (++vhost->init_retries > IBMVFC_MAX_HOST_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) + } else if (vhost->init_retries == IBMVFC_MAX_HOST_INIT_RETRIES) __ibmvfc_reset_host(vhost); else ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_INIT); @@ -2089,15 +2090,17 @@ case IBMVFC_AE_LINK_UP: case IBMVFC_AE_RESUME: vhost->events_to_log |= IBMVFC_AE_LINKUP; - ibmvfc_init_host(vhost, 1); + vhost->delay_init = 1; + __ibmvfc_reset_host(vhost); break; case IBMVFC_AE_SCN_FABRIC: + case IBMVFC_AE_SCN_DOMAIN: vhost->events_to_log |= IBMVFC_AE_RSCN; - ibmvfc_init_host(vhost, 1); + vhost->delay_init = 1; + __ibmvfc_reset_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: @@ -2669,7 +2672,7 @@ static void ibmvfc_retry_tgt_init(struct ibmvfc_target *tgt, void (*job_step) (struct ibmvfc_target *)) { - if (++tgt->init_retries > IBMVFC_MAX_INIT_RETRIES) { + if (++tgt->init_retries > IBMVFC_MAX_TGT_INIT_RETRIES) { ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT); wake_up(&tgt->vhost->work_wait_q); } else @@ -3519,7 +3522,13 @@ break; case IBMVFC_HOST_ACTION_INIT: BUG_ON(vhost->state != IBMVFC_INITIALIZING); - vhost->job_step(vhost); + if (vhost->delay_init) { + vhost->delay_init = 0; + spin_unlock_irqrestore(vhost->host->host_lock, flags); + ssleep(15); + return; + } else + vhost->job_step(vhost); break; case IBMVFC_HOST_ACTION_QUERY: list_for_each_entry(tgt, &vhost->targets, queue) --- linux-2.6.28.orig/drivers/scsi/pcmcia/aha152x_stub.c +++ linux-2.6.28/drivers/scsi/pcmcia/aha152x_stub.c @@ -114,7 +114,7 @@ link->io.NumPorts1 = 0x20; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.IOAddrLines = 10; - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->conf.Attributes = CONF_ENABLE_IRQ; link->conf.IntType = INT_MEMORY_AND_IO; --- linux-2.6.28.orig/drivers/mxc/Kconfig +++ linux-2.6.28/drivers/mxc/Kconfig @@ -0,0 +1,23 @@ +# drivers/video/mxc/Kconfig + +if ARCH_MXC + +menu "MXC support drivers" + +config MXC_IPU + bool "Image Processing Unit Driver" + select MXC_IPU_V3 if ARCH_MX51 + help + If you plan to use the Image Processing unit, say + Y here. IPU is needed by Framebuffer and V4L2 drivers. + +source "drivers/mxc/ipu3/Kconfig" + +source "drivers/mxc/pmic/Kconfig" +source "drivers/mxc/security/Kconfig" +source "drivers/mxc/vpu/Kconfig" +source "drivers/mxc/bt/Kconfig" + +endmenu + +endif --- linux-2.6.28.orig/drivers/mxc/Makefile +++ linux-2.6.28/drivers/mxc/Makefile @@ -0,0 +1,7 @@ +obj-$(CONFIG_MXC_IPU_V3) += ipu3/ +obj-$(CONFIG_MXC_PMIC) += pmic/ + +obj-y += security/ +obj-$(CONFIG_MXC_VPU) += vpu/ +obj-$(CONFIG_MXC_BLUETOOTH) += bt/ + --- linux-2.6.28.orig/drivers/mxc/ipu3/ipu_common.c +++ linux-2.6.28/drivers/mxc/ipu3/ipu_common.c @@ -0,0 +1,1791 @@ +/* + * Copyright 2005-2009 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 + */ + +/*! + * @file ipu_common.c + * + * @brief This file contains the IPU driver common API functions. + * + * @ingroup IPU + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ipu_prv.h" +#include "ipu_regs.h" +#include "ipu_param_mem.h" + +struct ipu_irq_node { + irqreturn_t(*handler) (int, void *); /*!< the ISR */ + const char *name; /*!< device associated with the interrupt */ + void *dev_id; /*!< some unique information for the ISR */ + __u32 flags; /*!< not used */ +}; + +/* Globals */ +struct clk *g_ipu_clk; +bool g_ipu_clk_enabled; +struct clk *g_di_clk[2]; +struct clk *g_csi_clk[2]; +unsigned char g_dc_di_assignment[10]; +ipu_channel_t g_ipu_csi_channel[2]; +int g_ipu_irq[2]; +int g_ipu_hw_rev; +bool g_sec_chan_en[21]; +uint32_t g_channel_init_mask; +DEFINE_SPINLOCK(ipu_lock); +struct device *g_ipu_dev; + +static struct ipu_irq_node ipu_irq_list[IPU_IRQ_COUNT]; +static const char driver_name[] = "mxc_ipu"; + +static int ipu_dc_use_count; +static int ipu_dp_use_count; +static int ipu_dmfc_use_count; +static int ipu_smfc_use_count; +static int ipu_ic_use_count; +static int ipu_rot_use_count; +static int ipu_di_use_count[2]; +static int ipu_csi_use_count[2]; + +u32 *ipu_cm_reg; +u32 *ipu_idmac_reg; +u32 *ipu_dp_reg; +u32 *ipu_ic_reg; +u32 *ipu_dc_reg; +u32 *ipu_dc_tmpl_reg; +u32 *ipu_dmfc_reg; +u32 *ipu_di_reg[2]; +u32 *ipu_smfc_reg; +u32 *ipu_csi_reg[2]; +u32 *ipu_cpmem_base; +u32 *ipu_tpmem_base; +u32 *ipu_disp_base[2]; + +/* Static functions */ +static irqreturn_t ipu_irq_handler(int irq, void *desc); + +static inline uint32_t channel_2_dma(ipu_channel_t ch, ipu_buffer_t type) +{ + return ((uint32_t) ch >> (6 * type)) & 0x3F; +}; + +static inline int _ipu_is_ic_chan(uint32_t dma_chan) +{ + return ((dma_chan >= 11) && (dma_chan <= 22)); +} + +static inline int _ipu_is_irt_chan(uint32_t dma_chan) +{ + return ((dma_chan >= 45) && (dma_chan <= 50)); +} + +static inline int _ipu_is_dmfc_chan(uint32_t dma_chan) +{ + return ((dma_chan >= 23) && (dma_chan <= 29)); +} + +static inline int _ipu_is_smfc_chan(uint32_t dma_chan) +{ + return ((dma_chan >= 0) && (dma_chan <= 3)); +} + +#define idma_is_valid(ch) (ch != NO_DMA) +#define idma_mask(ch) (idma_is_valid(ch) ? (1UL << (ch & 0x1F)) : 0) +#define idma_is_set(reg, dma) (__raw_readl(reg(dma)) & idma_mask(dma)) + +/*! + * This function is called by the driver framework to initialize the IPU + * hardware. + * + * @param dev The device structure for the IPU passed in by the + * driver framework. + * + * @return Returns 0 on success or negative error code on error + */ +static int ipu_probe(struct platform_device *pdev) +{ + struct resource *res; + struct mxc_ipu_config *plat_data = pdev->dev.platform_data; + unsigned long ipu_base; + + spin_lock_init(&ipu_lock); + + g_ipu_hw_rev = plat_data->rev; + + g_ipu_dev = &pdev->dev; + + /* Register IPU interrupts */ + g_ipu_irq[0] = platform_get_irq(pdev, 0); + if (g_ipu_irq[0] < 0) + return -EINVAL; + + if (request_irq(g_ipu_irq[0], ipu_irq_handler, 0, pdev->name, 0) != 0) { + dev_err(g_ipu_dev, "request SYNC interrupt failed\n"); + return -EBUSY; + } + /* Some platforms have 2 IPU interrupts */ + g_ipu_irq[1] = platform_get_irq(pdev, 1); + if (g_ipu_irq[1] >= 0) { + if (request_irq + (g_ipu_irq[1], ipu_irq_handler, 0, pdev->name, 0) != 0) { + dev_err(g_ipu_dev, "request ERR interrupt failed\n"); + return -EBUSY; + } + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (IS_ERR(res)) + return -ENODEV; + + ipu_base = res->start; + ipu_cm_reg = ioremap(ipu_base + IPU_CM_REG_BASE, PAGE_SIZE); + ipu_ic_reg = ioremap(ipu_base + IPU_IC_REG_BASE, PAGE_SIZE); + ipu_idmac_reg = ioremap(ipu_base + IPU_IDMAC_REG_BASE, PAGE_SIZE); + /* DP Registers are accessed thru the SRM */ + ipu_dp_reg = ioremap(ipu_base + IPU_SRM_REG_BASE, PAGE_SIZE); + ipu_dc_reg = ioremap(ipu_base + IPU_DC_REG_BASE, PAGE_SIZE); + ipu_dmfc_reg = ioremap(ipu_base + IPU_DMFC_REG_BASE, PAGE_SIZE); + ipu_di_reg[0] = ioremap(ipu_base + IPU_DI0_REG_BASE, PAGE_SIZE); + ipu_di_reg[1] = ioremap(ipu_base + IPU_DI1_REG_BASE, PAGE_SIZE); + ipu_smfc_reg = ioremap(ipu_base + IPU_SMFC_REG_BASE, PAGE_SIZE); + ipu_csi_reg[0] = ioremap(ipu_base + IPU_CSI0_REG_BASE, PAGE_SIZE); + ipu_csi_reg[1] = ioremap(ipu_base + IPU_CSI1_REG_BASE, PAGE_SIZE); + ipu_cpmem_base = ioremap(ipu_base + IPU_CPMEM_REG_BASE, PAGE_SIZE); + ipu_tpmem_base = ioremap(ipu_base + IPU_TPM_REG_BASE, SZ_64K); + ipu_dc_tmpl_reg = ioremap(ipu_base + IPU_DC_TMPL_REG_BASE, SZ_128K); + ipu_disp_base[1] = ioremap(ipu_base + IPU_DISP1_BASE, SZ_4K); + + dev_dbg(g_ipu_dev, "IPU CM Regs = %p\n", ipu_cm_reg); + dev_dbg(g_ipu_dev, "IPU IC Regs = %p\n", ipu_ic_reg); + dev_dbg(g_ipu_dev, "IPU IDMAC Regs = %p\n", ipu_idmac_reg); + dev_dbg(g_ipu_dev, "IPU DP Regs = %p\n", ipu_dp_reg); + dev_dbg(g_ipu_dev, "IPU DC Regs = %p\n", ipu_dc_reg); + dev_dbg(g_ipu_dev, "IPU DMFC Regs = %p\n", ipu_dmfc_reg); + dev_dbg(g_ipu_dev, "IPU DI0 Regs = %p\n", ipu_di_reg[0]); + dev_dbg(g_ipu_dev, "IPU DI1 Regs = %p\n", ipu_di_reg[1]); + dev_dbg(g_ipu_dev, "IPU SMFC Regs = %p\n", ipu_smfc_reg); + dev_dbg(g_ipu_dev, "IPU CSI0 Regs = %p\n", ipu_csi_reg[0]); + dev_dbg(g_ipu_dev, "IPU CSI1 Regs = %p\n", ipu_csi_reg[1]); + dev_dbg(g_ipu_dev, "IPU CPMem = %p\n", ipu_cpmem_base); + dev_dbg(g_ipu_dev, "IPU TPMem = %p\n", ipu_tpmem_base); + dev_dbg(g_ipu_dev, "IPU DC Template Mem = %p\n", ipu_dc_tmpl_reg); + dev_dbg(g_ipu_dev, "IPU Display Region 1 Mem = %p\n", ipu_disp_base[1]); + + /* Enable IPU and CSI clocks */ + /* Get IPU clock freq */ + g_ipu_clk = clk_get(&pdev->dev, "ipu_clk"); + dev_dbg(g_ipu_dev, "ipu_clk = %lu\n", clk_get_rate(g_ipu_clk)); + + clk_enable(g_ipu_clk); + + g_di_clk[0] = plat_data->di_clk[0]; + g_di_clk[1] = plat_data->di_clk[1]; + + g_csi_clk[0] = clk_get(&pdev->dev, "csi_mclk1"); + g_csi_clk[1] = clk_get(&pdev->dev, "csi_mclk2"); + + __raw_writel(0x807FFFFF, IPU_MEM_RST); + while (__raw_readl(IPU_MEM_RST) & 0x80000000) ; + + _ipu_init_dc_mappings(); + + /* Enable error interrupts by default */ + __raw_writel(0xFFFFFFFF, IPU_INT_CTRL(5)); + __raw_writel(0xFFFFFFFF, IPU_INT_CTRL(6)); + __raw_writel(0xFFFFFFFF, IPU_INT_CTRL(9)); + __raw_writel(0xFFFFFFFF, IPU_INT_CTRL(10)); + + /* DMFC Init */ + _ipu_dmfc_init(); + + /* Set sync refresh channels as high priority */ + __raw_writel(0x18800000L, IDMAC_CHA_PRI(0)); + + /* Set MCU_T to divide MCU access window into 2 */ + __raw_writel(0x00400000L | (IPU_MCU_T_DEFAULT << 18), IPU_DISP_GEN); + + clk_disable(g_ipu_clk); + + register_ipu_device(); + + return 0; +} + +int ipu_remove(struct platform_device *pdev) +{ + if (g_ipu_irq[0]) + free_irq(g_ipu_irq[0], 0); + if (g_ipu_irq[1]) + free_irq(g_ipu_irq[1], 0); + + clk_put(g_ipu_clk); + + iounmap(ipu_cm_reg); + iounmap(ipu_ic_reg); + iounmap(ipu_idmac_reg); + iounmap(ipu_dc_reg); + iounmap(ipu_dp_reg); + iounmap(ipu_dmfc_reg); + iounmap(ipu_di_reg[0]); + iounmap(ipu_di_reg[1]); + iounmap(ipu_smfc_reg); + iounmap(ipu_csi_reg[0]); + iounmap(ipu_csi_reg[1]); + iounmap(ipu_cpmem_base); + iounmap(ipu_tpmem_base); + iounmap(ipu_dc_tmpl_reg); + iounmap(ipu_disp_base[1]); + + return 0; +} + +void ipu_dump_registers(void) +{ + printk(KERN_DEBUG "IPU_CONF = \t0x%08X\n", __raw_readl(IPU_CONF)); + printk(KERN_DEBUG "IDMAC_CONF = \t0x%08X\n", __raw_readl(IDMAC_CONF)); + printk(KERN_DEBUG "IDMAC_CHA_EN1 = \t0x%08X\n", + __raw_readl(IDMAC_CHA_EN(0))); + printk(KERN_DEBUG "IDMAC_CHA_EN2 = \t0x%08X\n", + __raw_readl(IDMAC_CHA_EN(32))); + printk(KERN_DEBUG "IDMAC_CHA_PRI1 = \t0x%08X\n", + __raw_readl(IDMAC_CHA_PRI(0))); + printk(KERN_DEBUG "IDMAC_CHA_PRI2 = \t0x%08X\n", + __raw_readl(IDMAC_CHA_PRI(32))); + printk(KERN_DEBUG "IDMAC_BAND_EN1 = \t0x%08X\n", + __raw_readl(IDMAC_BAND_EN(0))); + printk(KERN_DEBUG "IDMAC_BAND_EN2 = \t0x%08X\n", + __raw_readl(IDMAC_BAND_EN(32))); + printk(KERN_DEBUG "IPU_CHA_DB_MODE_SEL0 = \t0x%08X\n", + __raw_readl(IPU_CHA_DB_MODE_SEL(0))); + printk(KERN_DEBUG "IPU_CHA_DB_MODE_SEL1 = \t0x%08X\n", + __raw_readl(IPU_CHA_DB_MODE_SEL(32))); + printk(KERN_DEBUG "DMFC_WR_CHAN = \t0x%08X\n", + __raw_readl(DMFC_WR_CHAN)); + printk(KERN_DEBUG "DMFC_WR_CHAN_DEF = \t0x%08X\n", + __raw_readl(DMFC_WR_CHAN_DEF)); + printk(KERN_DEBUG "DMFC_DP_CHAN = \t0x%08X\n", + __raw_readl(DMFC_DP_CHAN)); + printk(KERN_DEBUG "DMFC_DP_CHAN_DEF = \t0x%08X\n", + __raw_readl(DMFC_DP_CHAN_DEF)); + printk(KERN_DEBUG "DMFC_IC_CTRL = \t0x%08X\n", + __raw_readl(DMFC_IC_CTRL)); + printk(KERN_DEBUG "IPU_FS_PROC_FLOW1 = \t0x%08X\n", + __raw_readl(IPU_FS_PROC_FLOW1)); + printk(KERN_DEBUG "IPU_FS_PROC_FLOW2 = \t0x%08X\n", + __raw_readl(IPU_FS_PROC_FLOW2)); + printk(KERN_DEBUG "IPU_FS_PROC_FLOW3 = \t0x%08X\n", + __raw_readl(IPU_FS_PROC_FLOW3)); + printk(KERN_DEBUG "IPU_FS_DISP_FLOW1 = \t0x%08X\n", + __raw_readl(IPU_FS_DISP_FLOW1)); +} + +/*! + * This function is called to initialize a logical IPU channel. + * + * @param channel Input parameter for the logical channel ID to init. + * + * @param params Input parameter containing union of channel + * initialization parameters. + * + * @return Returns 0 on success or negative error code on fail + */ +int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params) +{ + int ret = 0; + uint32_t ipu_conf; + uint32_t reg; + unsigned long lock_flags; + + dev_dbg(g_ipu_dev, "init channel = %d\n", IPU_CHAN_ID(channel)); + + /* re-enable error interrupts every time a channel is initialized */ + __raw_writel(0xFFFFFFFF, IPU_INT_CTRL(5)); + __raw_writel(0xFFFFFFFF, IPU_INT_CTRL(6)); + __raw_writel(0xFFFFFFFF, IPU_INT_CTRL(9)); + __raw_writel(0xFFFFFFFF, IPU_INT_CTRL(10)); + + if (g_ipu_clk_enabled == false) { + g_ipu_clk_enabled = true; + clk_enable(g_ipu_clk); + } + + spin_lock_irqsave(&ipu_lock, lock_flags); + + if (g_channel_init_mask & (1L << IPU_CHAN_ID(channel))) { + dev_err(g_ipu_dev, "Warning: channel already initialized %d\n", + IPU_CHAN_ID(channel)); + } + + switch (channel) { + case CSI_MEM0: + case CSI_MEM1: + case CSI_MEM2: + case CSI_MEM3: + if (params->csi_mem.csi > 1) { + ret = -EINVAL; + goto err; + } + + ipu_smfc_use_count++; + ipu_csi_use_count[params->csi_mem.csi]++; + g_ipu_csi_channel[params->csi_mem.csi] = channel; + + /*SMFC setting*/ + if (params->csi_mem.mipi_en) { + ipu_conf |= (1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET + + params->csi_mem.csi)); + _ipu_smfc_init(channel, params->csi_mem.mipi_id, + params->csi_mem.csi); + } else { + ipu_conf &= ~(1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET + + params->csi_mem.csi)); + _ipu_smfc_init(channel, 0, params->csi_mem.csi); + } + + /*CSI data (include compander) dest*/ + _ipu_csi_init(channel, params->csi_mem.csi); + break; + case CSI_PRP_ENC_MEM: + if (params->csi_prp_enc_mem.csi > 1) { + ret = -EINVAL; + goto err; + } + + ipu_ic_use_count++; + ipu_csi_use_count[params->csi_prp_enc_mem.csi]++; + g_ipu_csi_channel[params->csi_prp_enc_mem.csi] = channel; + + /*Without SMFC, CSI only support parallel data source*/ + ipu_conf &= ~(1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET + + params->csi_prp_enc_mem.csi)); + + /*CSI0/1 feed into IC*/ + ipu_conf &= ~IPU_CONF_IC_INPUT; + if (params->csi_prp_enc_mem.csi) + ipu_conf |= IPU_CONF_CSI_SEL; + else + ipu_conf &= ~IPU_CONF_CSI_SEL; + + /*PRP skip buffer in memory, only valid when RWS_EN is true*/ + reg = __raw_readl(IPU_FS_PROC_FLOW1); + __raw_writel(reg & ~FS_ENC_IN_VALID, IPU_FS_PROC_FLOW1); + + /*CSI data (include compander) dest*/ + _ipu_csi_init(channel, params->csi_prp_enc_mem.csi); + _ipu_ic_init_prpenc(params, true); + break; + case CSI_PRP_VF_MEM: + if (params->csi_prp_vf_mem.csi > 1) { + ret = -EINVAL; + goto err; + } + + ipu_ic_use_count++; + ipu_csi_use_count[params->csi_prp_vf_mem.csi]++; + g_ipu_csi_channel[params->csi_prp_vf_mem.csi] = channel; + + /*Without SMFC, CSI only support parallel data source*/ + ipu_conf &= ~(1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET + + params->csi_prp_vf_mem.csi)); + + /*CSI0/1 feed into IC*/ + ipu_conf &= ~IPU_CONF_IC_INPUT; + if (params->csi_prp_vf_mem.csi) + ipu_conf |= IPU_CONF_CSI_SEL; + else + ipu_conf &= ~IPU_CONF_CSI_SEL; + + /*PRP skip buffer in memory, only valid when RWS_EN is true*/ + reg = __raw_readl(IPU_FS_PROC_FLOW1); + __raw_writel(reg & ~FS_VF_IN_VALID, IPU_FS_PROC_FLOW1); + + /*CSI data (include compander) dest*/ + _ipu_csi_init(channel, params->csi_prp_vf_mem.csi); + _ipu_ic_init_prpvf(params, true); + break; + case MEM_PRP_VF_MEM: + ipu_ic_use_count++; + reg = __raw_readl(IPU_FS_PROC_FLOW1); + __raw_writel(reg | FS_VF_IN_VALID, IPU_FS_PROC_FLOW1); + + if (params->mem_prp_vf_mem.graphics_combine_en) + g_sec_chan_en[IPU_CHAN_ID(channel)] = true; + + _ipu_ic_init_prpvf(params, false); + break; + case MEM_ROT_VF_MEM: + ipu_ic_use_count++; + ipu_rot_use_count++; + _ipu_ic_init_rotate_vf(params); + break; + case MEM_PRP_ENC_MEM: + ipu_ic_use_count++; + reg = __raw_readl(IPU_FS_PROC_FLOW1); + __raw_writel(reg | FS_ENC_IN_VALID, IPU_FS_PROC_FLOW1); + _ipu_ic_init_prpenc(params, false); + break; + case MEM_ROT_ENC_MEM: + ipu_ic_use_count++; + ipu_rot_use_count++; + _ipu_ic_init_rotate_enc(params); + break; + case MEM_PP_MEM: + if (params->mem_pp_mem.graphics_combine_en) + g_sec_chan_en[IPU_CHAN_ID(channel)] = true; + _ipu_ic_init_pp(params); + ipu_ic_use_count++; + break; + case MEM_ROT_PP_MEM: + _ipu_ic_init_rotate_pp(params); + ipu_ic_use_count++; + ipu_rot_use_count++; + break; + case MEM_DC_SYNC: + if (params->mem_dc_sync.di > 1) { + ret = -EINVAL; + goto err; + } + + g_dc_di_assignment[1] = params->mem_dc_sync.di; + _ipu_dc_init(1, params->mem_dc_sync.di, + params->mem_dc_sync.interlaced); + ipu_di_use_count[params->mem_dc_sync.di]++; + ipu_dc_use_count++; + ipu_dmfc_use_count++; + break; + case MEM_BG_SYNC: + if (params->mem_dp_bg_sync.di > 1) { + ret = -EINVAL; + goto err; + } + + g_dc_di_assignment[5] = params->mem_dp_bg_sync.di; + _ipu_dp_init(channel, params->mem_dp_bg_sync.in_pixel_fmt, + params->mem_dp_bg_sync.out_pixel_fmt); + _ipu_dc_init(5, params->mem_dp_bg_sync.di, + params->mem_dp_bg_sync.interlaced); + ipu_di_use_count[params->mem_dp_bg_sync.di]++; + ipu_dc_use_count++; + ipu_dp_use_count++; + ipu_dmfc_use_count++; + break; + case MEM_FG_SYNC: + _ipu_dp_init(channel, params->mem_dp_fg_sync.in_pixel_fmt, + params->mem_dp_fg_sync.out_pixel_fmt); + ipu_dc_use_count++; + ipu_dp_use_count++; + ipu_dmfc_use_count++; + break; + case DIRECT_ASYNC0: + if (params->direct_async.di > 1) { + ret = -EINVAL; + goto err; + } + + g_dc_di_assignment[8] = params->direct_async.di; + _ipu_dc_init(8, params->direct_async.di, false); + ipu_di_use_count[params->direct_async.di]++; + ipu_dc_use_count++; + break; + case DIRECT_ASYNC1: + if (params->direct_async.di > 1) { + ret = -EINVAL; + goto err; + } + + g_dc_di_assignment[9] = params->direct_async.di; + _ipu_dc_init(9, params->direct_async.di, false); + ipu_di_use_count[params->direct_async.di]++; + ipu_dc_use_count++; + break; + default: + dev_err(g_ipu_dev, "Missing channel initialization\n"); + break; + } + + /* Enable IPU sub module */ + g_channel_init_mask |= 1L << IPU_CHAN_ID(channel); + ipu_conf = __raw_readl(IPU_CONF); + if (ipu_ic_use_count == 1) + ipu_conf |= IPU_CONF_IC_EN; + if (ipu_rot_use_count == 1) + ipu_conf |= IPU_CONF_ROT_EN; + if (ipu_dc_use_count == 1) + ipu_conf |= IPU_CONF_DC_EN; + if (ipu_dp_use_count == 1) + ipu_conf |= IPU_CONF_DP_EN; + if (ipu_dmfc_use_count == 1) + ipu_conf |= IPU_CONF_DMFC_EN; + if (ipu_di_use_count[0] == 1) { + ipu_conf |= IPU_CONF_DI0_EN; + clk_enable(g_di_clk[0]); + } + if (ipu_di_use_count[1] == 1) { + ipu_conf |= IPU_CONF_DI1_EN; + clk_enable(g_di_clk[1]); + } + if (ipu_smfc_use_count == 1) + ipu_conf |= IPU_CONF_SMFC_EN; + if (ipu_csi_use_count[0] == 1) + ipu_conf |= IPU_CONF_CSI0_EN; + if (ipu_csi_use_count[1] == 1) + ipu_conf |= IPU_CONF_CSI1_EN; + + __raw_writel(ipu_conf, IPU_CONF); + +err: + spin_unlock_irqrestore(&ipu_lock, lock_flags); + return ret; +} +EXPORT_SYMBOL(ipu_init_channel); + +/*! + * This function is called to uninitialize a logical IPU channel. + * + * @param channel Input parameter for the logical channel ID to uninit. + */ +void ipu_uninit_channel(ipu_channel_t channel) +{ + unsigned long lock_flags; + uint32_t reg; + uint32_t in_dma, out_dma = 0; + uint32_t ipu_conf; + + if ((g_channel_init_mask & (1L << IPU_CHAN_ID(channel))) == 0) { + dev_err(g_ipu_dev, "Channel already uninitialized %d\n", + IPU_CHAN_ID(channel)); + return; + } + + /* Make sure channel is disabled */ + /* Get input and output dma channels */ + in_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER); + out_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER); + + if (idma_is_set(IDMAC_CHA_EN, in_dma) || + idma_is_set(IDMAC_CHA_EN, out_dma)) { + dev_err(g_ipu_dev, + "Channel %d is not disabled, disable first\n", + IPU_CHAN_ID(channel)); + return; + } + + spin_lock_irqsave(&ipu_lock, lock_flags); + + /* Reset the double buffer */ + reg = __raw_readl(IPU_CHA_DB_MODE_SEL(in_dma)); + __raw_writel(reg & ~idma_mask(in_dma), IPU_CHA_DB_MODE_SEL(in_dma)); + reg = __raw_readl(IPU_CHA_DB_MODE_SEL(out_dma)); + __raw_writel(reg & ~idma_mask(out_dma), IPU_CHA_DB_MODE_SEL(out_dma)); + + g_sec_chan_en[IPU_CHAN_ID(channel)] = false; + + switch (channel) { + case CSI_MEM0: + case CSI_MEM1: + case CSI_MEM2: + case CSI_MEM3: + ipu_smfc_use_count--; + if (g_ipu_csi_channel[0] == channel) { + g_ipu_csi_channel[0] = CHAN_NONE; + ipu_csi_use_count[0]--; + } else if (g_ipu_csi_channel[1] == channel) { + g_ipu_csi_channel[1] = CHAN_NONE; + ipu_csi_use_count[1]--; + } + break; + case CSI_PRP_ENC_MEM: + ipu_ic_use_count--; + _ipu_ic_uninit_prpenc(); + if (g_ipu_csi_channel[0] == channel) { + g_ipu_csi_channel[0] = CHAN_NONE; + ipu_csi_use_count[0]--; + } else if (g_ipu_csi_channel[1] == channel) { + g_ipu_csi_channel[1] = CHAN_NONE; + ipu_csi_use_count[1]--; + } + break; + case CSI_PRP_VF_MEM: + ipu_ic_use_count--; + _ipu_ic_uninit_prpvf(); + if (g_ipu_csi_channel[0] == channel) { + g_ipu_csi_channel[0] = CHAN_NONE; + ipu_csi_use_count[0]--; + } else if (g_ipu_csi_channel[1] == channel) { + g_ipu_csi_channel[1] = CHAN_NONE; + ipu_csi_use_count[1]--; + } + break; + case MEM_PRP_VF_MEM: + ipu_ic_use_count--; + _ipu_ic_uninit_prpvf(); + reg = __raw_readl(IPU_FS_PROC_FLOW1); + __raw_writel(reg & ~FS_VF_IN_VALID, IPU_FS_PROC_FLOW1); + break; + case MEM_ROT_VF_MEM: + ipu_rot_use_count--; + ipu_ic_use_count--; + _ipu_ic_uninit_rotate_vf(); + break; + case MEM_PRP_ENC_MEM: + ipu_ic_use_count--; + _ipu_ic_uninit_prpenc(); + reg = __raw_readl(IPU_FS_PROC_FLOW1); + __raw_writel(reg & ~FS_ENC_IN_VALID, IPU_FS_PROC_FLOW1); + break; + case MEM_ROT_ENC_MEM: + ipu_rot_use_count--; + ipu_ic_use_count--; + _ipu_ic_uninit_rotate_enc(); + break; + case MEM_PP_MEM: + ipu_ic_use_count--; + _ipu_ic_uninit_pp(); + break; + case MEM_ROT_PP_MEM: + ipu_rot_use_count--; + ipu_ic_use_count--; + _ipu_ic_uninit_rotate_pp(); + break; + case MEM_DC_SYNC: + _ipu_dc_uninit(1); + ipu_di_use_count[g_dc_di_assignment[1]]--; + ipu_dc_use_count--; + ipu_dmfc_use_count--; + break; + case MEM_BG_SYNC: + _ipu_dp_uninit(channel); + _ipu_dc_uninit(5); + ipu_di_use_count[g_dc_di_assignment[5]]--; + ipu_dc_use_count--; + ipu_dp_use_count--; + ipu_dmfc_use_count--; + break; + case MEM_FG_SYNC: + _ipu_dp_uninit(channel); + ipu_dc_use_count--; + ipu_dp_use_count--; + ipu_dmfc_use_count--; + break; + case DIRECT_ASYNC0: + _ipu_dc_uninit(8); + ipu_di_use_count[g_dc_di_assignment[8]]--; + ipu_dc_use_count--; + break; + case DIRECT_ASYNC1: + _ipu_dc_uninit(9); + ipu_di_use_count[g_dc_di_assignment[9]]--; + ipu_dc_use_count--; + break; + default: + break; + } + + g_channel_init_mask &= ~(1L << IPU_CHAN_ID(channel)); + + ipu_conf = __raw_readl(IPU_CONF); + + if (ipu_ic_use_count == 0) + ipu_conf &= ~IPU_CONF_IC_EN; + if (ipu_rot_use_count == 0) + ipu_conf &= ~IPU_CONF_ROT_EN; + if (ipu_dc_use_count == 0) + ipu_conf &= ~IPU_CONF_DC_EN; + if (ipu_dp_use_count == 0) + ipu_conf &= ~IPU_CONF_DP_EN; + if (ipu_dmfc_use_count == 0) + ipu_conf &= ~IPU_CONF_DMFC_EN; + if (ipu_di_use_count[0] == 0) { + ipu_conf &= ~IPU_CONF_DI0_EN; + clk_disable(g_di_clk[0]); + } + if (ipu_di_use_count[1] == 0) { + ipu_conf &= ~IPU_CONF_DI1_EN; + clk_disable(g_di_clk[1]); + } + if (ipu_smfc_use_count == 0) + ipu_conf &= ~IPU_CONF_SMFC_EN; + if (ipu_csi_use_count[0] == 0) + ipu_conf &= ~IPU_CONF_CSI0_EN; + if (ipu_csi_use_count[1] == 0) + ipu_conf &= ~IPU_CONF_CSI1_EN; + + __raw_writel(ipu_conf, IPU_CONF); + + spin_unlock_irqrestore(&ipu_lock, lock_flags); + + if (ipu_conf == 0) { + clk_disable(g_ipu_clk); + g_ipu_clk_enabled = false; + } + + WARN_ON(ipu_ic_use_count < 0); + WARN_ON(ipu_rot_use_count < 0); + WARN_ON(ipu_dc_use_count < 0); + WARN_ON(ipu_dp_use_count < 0); + WARN_ON(ipu_dmfc_use_count < 0); + WARN_ON(ipu_smfc_use_count < 0); +} +EXPORT_SYMBOL(ipu_uninit_channel); + +/*! + * This function is called to initialize a buffer for logical IPU channel. + * + * @param channel Input parameter for the logical channel ID. + * + * @param type Input parameter which buffer to initialize. + * + * @param pixel_fmt Input parameter for pixel format of buffer. + * Pixel format is a FOURCC ASCII code. + * + * @param width Input parameter for width of buffer in pixels. + * + * @param height Input parameter for height of buffer in pixels. + * + * @param stride Input parameter for stride length of buffer + * in pixels. + * + * @param rot_mode Input parameter for rotation setting of buffer. + * A rotation setting other than + * IPU_ROTATE_VERT_FLIP + * should only be used for input buffers of + * rotation channels. + * + * @param phyaddr_0 Input parameter buffer 0 physical address. + * + * @param phyaddr_1 Input parameter buffer 1 physical address. + * Setting this to a value other than NULL enables + * double buffering mode. + * + * @param u private u offset for additional cropping, + * zero if not used. + * + * @param v private v offset for additional cropping, + * zero if not used. + * + * @return Returns 0 on success or negative error code on fail + */ +int32_t ipu_init_channel_buffer(ipu_channel_t channel, ipu_buffer_t type, + uint32_t pixel_fmt, + uint16_t width, uint16_t height, + uint32_t stride, + ipu_rotate_mode_t rot_mode, + dma_addr_t phyaddr_0, dma_addr_t phyaddr_1, + uint32_t u, uint32_t v) +{ + unsigned long lock_flags; + uint32_t reg; + uint32_t dma_chan; + uint32_t burst_size; + + dma_chan = channel_2_dma(channel, type); + if (!idma_is_valid(dma_chan)) + return -EINVAL; + + if (stride < width * bytes_per_pixel(pixel_fmt)) + stride = width * bytes_per_pixel(pixel_fmt); + + if (stride % 4) { + dev_err(g_ipu_dev, + "Stride not 32-bit aligned, stride = %d\n", stride); + return -EINVAL; + } + /* IC & IRT channels' width must be multiple of 8 pixels */ + if ((_ipu_is_ic_chan(dma_chan) || _ipu_is_irt_chan(dma_chan)) + && (width % 8)) { + dev_err(g_ipu_dev, "Width must be 8 pixel multiple\n"); + return -EINVAL; + } + + /* Build parameter memory data for DMA channel */ + _ipu_ch_param_init(dma_chan, pixel_fmt, width, height, stride, u, v, 0, + phyaddr_0, phyaddr_1); + if (rot_mode) + _ipu_ch_param_set_rotation(dma_chan, rot_mode); + + /* IC and ROT channels have restriction of 8 or 16 pix burst length */ + if (_ipu_is_ic_chan(dma_chan)) { + if ((width % 16) == 0) + _ipu_ch_param_set_burst_size(dma_chan, 16); + else + _ipu_ch_param_set_burst_size(dma_chan, 8); + } else if (_ipu_is_irt_chan(dma_chan)) { + _ipu_ch_param_set_burst_size(dma_chan, 8); + _ipu_ch_param_set_block_mode(dma_chan); + } else if (_ipu_is_dmfc_chan(dma_chan)) + _ipu_dmfc_set_wait4eot(dma_chan, width); + + if (_ipu_chan_is_interlaced(channel)) + _ipu_ch_param_set_interlaced_scan(dma_chan); + + if (_ipu_is_ic_chan(dma_chan) || _ipu_is_irt_chan(dma_chan)) { + burst_size = _ipu_ch_param_get_burst_size(dma_chan); + _ipu_ic_idma_init(dma_chan, width, height, burst_size, + rot_mode); + } else if (_ipu_is_smfc_chan(dma_chan)) { + burst_size = _ipu_ch_param_get_burst_size(dma_chan); + if ((pixel_fmt == IPU_PIX_FMT_GENERIC) && + ((_ipu_ch_param_get_bpp(dma_chan) == 5) || + (_ipu_ch_param_get_bpp(dma_chan) == 3))) + burst_size = burst_size >> 4; + else + burst_size = burst_size >> 2; + _ipu_smfc_set_burst_size(channel, burst_size-1); + } + + if (idma_is_set(IDMAC_CHA_PRI, dma_chan)) + _ipu_ch_param_set_high_priority(dma_chan); + + _ipu_ch_param_dump(dma_chan); + + spin_lock_irqsave(&ipu_lock, lock_flags); + + reg = __raw_readl(IPU_CHA_DB_MODE_SEL(dma_chan)); + if (phyaddr_1) + reg |= idma_mask(dma_chan); + else + reg &= ~idma_mask(dma_chan); + __raw_writel(reg, IPU_CHA_DB_MODE_SEL(dma_chan)); + + /* Reset to buffer 0 */ + __raw_writel(idma_mask(dma_chan), IPU_CHA_CUR_BUF(dma_chan)); + + spin_unlock_irqrestore(&ipu_lock, lock_flags); + + return 0; +} +EXPORT_SYMBOL(ipu_init_channel_buffer); + +/*! + * This function is called to update the physical address of a buffer for + * a logical IPU channel. + * + * @param channel Input parameter for the logical channel ID. + * + * @param type Input parameter which buffer to initialize. + * + * @param bufNum Input parameter for buffer number to update. + * 0 or 1 are the only valid values. + * + * @param phyaddr Input parameter buffer physical address. + * + * @return This function returns 0 on success or negative error code on + * fail. This function will fail if the buffer is set to ready. + */ +int32_t ipu_update_channel_buffer(ipu_channel_t channel, ipu_buffer_t type, + uint32_t bufNum, dma_addr_t phyaddr) +{ + uint32_t reg; + int ret = 0; + unsigned long lock_flags; + uint32_t dma_chan = channel_2_dma(channel, type); + + if (dma_chan == IDMA_CHAN_INVALID) + return -EINVAL; + + spin_lock_irqsave(&ipu_lock, lock_flags); + + if (bufNum == 0) + reg = __raw_readl(IPU_CHA_BUF0_RDY(dma_chan)); + else + reg = __raw_readl(IPU_CHA_BUF1_RDY(dma_chan)); + + if ((reg & idma_mask(dma_chan)) == 0) + _ipu_ch_param_set_buffer(dma_chan, bufNum, phyaddr); + else + ret = -EACCES; + + spin_unlock_irqrestore(&ipu_lock, lock_flags); + return ret; +} +EXPORT_SYMBOL(ipu_update_channel_buffer); + +/*! + * This function is called to set a channel's buffer as ready. + * + * @param channel Input parameter for the logical channel ID. + * + * @param type Input parameter which buffer to initialize. + * + * @param bufNum Input parameter for which buffer number set to + * ready state. + * + * @return Returns 0 on success or negative error code on fail + */ +int32_t ipu_select_buffer(ipu_channel_t channel, ipu_buffer_t type, + uint32_t bufNum) +{ + uint32_t dma_chan = channel_2_dma(channel, type); + + if (dma_chan == IDMA_CHAN_INVALID) + return -EINVAL; + + if (bufNum == 0) { + /*Mark buffer 0 as ready. */ + __raw_writel(idma_mask(dma_chan), IPU_CHA_BUF0_RDY(dma_chan)); + } else { + /*Mark buffer 1 as ready. */ + __raw_writel(idma_mask(dma_chan), IPU_CHA_BUF1_RDY(dma_chan)); + } + return 0; +} +EXPORT_SYMBOL(ipu_select_buffer); + +#define NA -1 +static int proc_dest_sel[] = + { 0, 1, 1, 3, 5, 5, 4, 7, 8, 9, 10, 11, 12, 14, 15 }; +static int proc_src_sel[] = { 0, 6, 7, 6, 7, 8, 5, NA, NA, NA, +NA, NA, NA, NA, NA, 1, 2, 3, 4, 7, 8 }; +static int disp_src_sel[] = { 0, 6, 7, 8, 3, 4, 5, NA, NA, NA, +NA, NA, NA, NA, NA, 1, NA, 2, NA, 3, 4 }; + +/*! + * This function links 2 channels together for automatic frame + * synchronization. The output of the source channel is linked to the input of + * the destination channel. + * + * @param src_ch Input parameter for the logical channel ID of + * the source channel. + * + * @param dest_ch Input parameter for the logical channel ID of + * the destination channel. + * + * @return This function returns 0 on success or negative error code on + * fail. + */ +int32_t ipu_link_channels(ipu_channel_t src_ch, ipu_channel_t dest_ch) +{ + int retval = 0; + unsigned long lock_flags; + uint32_t fs_proc_flow1; + uint32_t fs_proc_flow2; + uint32_t fs_proc_flow3; + uint32_t fs_disp_flow1; + + spin_lock_irqsave(&ipu_lock, lock_flags); + + fs_proc_flow1 = __raw_readl(IPU_FS_PROC_FLOW1); + fs_proc_flow2 = __raw_readl(IPU_FS_PROC_FLOW2); + fs_proc_flow3 = __raw_readl(IPU_FS_PROC_FLOW3); + fs_disp_flow1 = __raw_readl(IPU_FS_DISP_FLOW1); + + switch (src_ch) { + case CSI_MEM0: + fs_proc_flow3 &= ~FS_SMFC0_DEST_SEL_MASK; + fs_proc_flow3 |= + proc_dest_sel[IPU_CHAN_ID(dest_ch)] << + FS_SMFC0_DEST_SEL_OFFSET; + break; + case CSI_MEM1: + fs_proc_flow3 &= ~FS_SMFC1_DEST_SEL_MASK; + fs_proc_flow3 |= + proc_dest_sel[IPU_CHAN_ID(dest_ch)] << + FS_SMFC1_DEST_SEL_OFFSET; + break; + case CSI_MEM2: + fs_proc_flow3 &= ~FS_SMFC2_DEST_SEL_MASK; + fs_proc_flow3 |= + proc_dest_sel[IPU_CHAN_ID(dest_ch)] << + FS_SMFC2_DEST_SEL_OFFSET; + break; + case CSI_MEM3: + fs_proc_flow3 &= ~FS_SMFC3_DEST_SEL_MASK; + fs_proc_flow3 |= + proc_dest_sel[IPU_CHAN_ID(dest_ch)] << + FS_SMFC3_DEST_SEL_OFFSET; + break; + case CSI_PRP_ENC_MEM: + fs_proc_flow2 &= ~FS_PRPENC_DEST_SEL_MASK; + fs_proc_flow2 |= + proc_dest_sel[IPU_CHAN_ID(dest_ch)] << + FS_PRPENC_DEST_SEL_OFFSET; + break; + case CSI_PRP_VF_MEM: + fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK; + fs_proc_flow2 |= + proc_dest_sel[IPU_CHAN_ID(dest_ch)] << + FS_PRPVF_DEST_SEL_OFFSET; + break; + case MEM_PP_MEM: + fs_proc_flow2 &= ~FS_PP_DEST_SEL_MASK; + fs_proc_flow2 |= + proc_dest_sel[IPU_CHAN_ID(dest_ch)] << + FS_PP_DEST_SEL_OFFSET; + break; + case MEM_ROT_PP_MEM: + fs_proc_flow2 &= ~FS_PP_ROT_DEST_SEL_MASK; + fs_proc_flow2 |= + proc_dest_sel[IPU_CHAN_ID(dest_ch)] << + FS_PP_ROT_DEST_SEL_OFFSET; + break; + case MEM_PRP_ENC_MEM: + fs_proc_flow2 &= ~FS_PRPENC_DEST_SEL_MASK; + fs_proc_flow2 |= + proc_dest_sel[IPU_CHAN_ID(dest_ch)] << + FS_PRPENC_DEST_SEL_OFFSET; + break; + case MEM_ROT_ENC_MEM: + fs_proc_flow2 &= ~FS_PRPENC_ROT_DEST_SEL_MASK; + fs_proc_flow2 |= + proc_dest_sel[IPU_CHAN_ID(dest_ch)] << + FS_PRPENC_ROT_DEST_SEL_OFFSET; + break; + case MEM_PRP_VF_MEM: + fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK; + fs_proc_flow2 |= + proc_dest_sel[IPU_CHAN_ID(dest_ch)] << + FS_PRPVF_DEST_SEL_OFFSET; + break; + case MEM_ROT_VF_MEM: + fs_proc_flow2 &= ~FS_PRPVF_ROT_DEST_SEL_MASK; + fs_proc_flow2 |= + proc_dest_sel[IPU_CHAN_ID(dest_ch)] << + FS_PRPVF_ROT_DEST_SEL_OFFSET; + break; + default: + retval = -EINVAL; + goto err; + } + + switch (dest_ch) { + case MEM_PP_MEM: + fs_proc_flow1 &= ~FS_PP_SRC_SEL_MASK; + fs_proc_flow1 |= + proc_src_sel[IPU_CHAN_ID(src_ch)] << FS_PP_SRC_SEL_OFFSET; + break; + case MEM_ROT_PP_MEM: + fs_proc_flow1 &= ~FS_PP_ROT_SRC_SEL_MASK; + fs_proc_flow1 |= + proc_src_sel[IPU_CHAN_ID(src_ch)] << + FS_PP_ROT_SRC_SEL_OFFSET; + break; + case MEM_PRP_ENC_MEM: + fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK; + fs_proc_flow1 |= + proc_src_sel[IPU_CHAN_ID(src_ch)] << FS_PRP_SRC_SEL_OFFSET; + break; + case MEM_ROT_ENC_MEM: + fs_proc_flow1 &= ~FS_PRPENC_ROT_SRC_SEL_MASK; + fs_proc_flow1 |= + proc_src_sel[IPU_CHAN_ID(src_ch)] << + FS_PRPENC_ROT_SRC_SEL_OFFSET; + break; + case MEM_PRP_VF_MEM: + fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK; + fs_proc_flow1 |= + proc_src_sel[IPU_CHAN_ID(src_ch)] << FS_PRP_SRC_SEL_OFFSET; + break; + case MEM_ROT_VF_MEM: + fs_proc_flow1 &= ~FS_PRPVF_ROT_SRC_SEL_MASK; + fs_proc_flow1 |= + proc_src_sel[IPU_CHAN_ID(src_ch)] << + FS_PRPVF_ROT_SRC_SEL_OFFSET; + break; + case MEM_DC_SYNC: + fs_disp_flow1 &= ~FS_DC1_SRC_SEL_MASK; + fs_disp_flow1 |= + disp_src_sel[IPU_CHAN_ID(src_ch)] << FS_DC1_SRC_SEL_OFFSET; + break; + case MEM_BG_SYNC: + fs_disp_flow1 &= ~FS_DP_SYNC0_SRC_SEL_MASK; + fs_disp_flow1 |= + disp_src_sel[IPU_CHAN_ID(src_ch)] << + FS_DP_SYNC0_SRC_SEL_OFFSET; + break; + case MEM_FG_SYNC: + fs_disp_flow1 &= ~FS_DP_SYNC1_SRC_SEL_MASK; + fs_disp_flow1 |= + disp_src_sel[IPU_CHAN_ID(src_ch)] << + FS_DP_SYNC1_SRC_SEL_OFFSET; + break; + case MEM_DC_ASYNC: + fs_disp_flow1 &= ~FS_DC2_SRC_SEL_MASK; + fs_disp_flow1 |= + disp_src_sel[IPU_CHAN_ID(src_ch)] << FS_DC2_SRC_SEL_OFFSET; + break; + case MEM_BG_ASYNC0: + fs_disp_flow1 &= ~FS_DP_ASYNC0_SRC_SEL_MASK; + fs_disp_flow1 |= + disp_src_sel[IPU_CHAN_ID(src_ch)] << + FS_DP_ASYNC0_SRC_SEL_OFFSET; + break; + case MEM_FG_ASYNC0: + fs_disp_flow1 &= ~FS_DP_ASYNC1_SRC_SEL_MASK; + fs_disp_flow1 |= + disp_src_sel[IPU_CHAN_ID(src_ch)] << + FS_DP_ASYNC1_SRC_SEL_OFFSET; + break; + default: + retval = -EINVAL; + goto err; + } + + __raw_writel(fs_proc_flow1, IPU_FS_PROC_FLOW1); + __raw_writel(fs_proc_flow2, IPU_FS_PROC_FLOW2); + __raw_writel(fs_proc_flow3, IPU_FS_PROC_FLOW3); + __raw_writel(fs_disp_flow1, IPU_FS_DISP_FLOW1); + +err: + spin_unlock_irqrestore(&ipu_lock, lock_flags); + return retval; +} +EXPORT_SYMBOL(ipu_link_channels); + +/*! + * This function unlinks 2 channels and disables automatic frame + * synchronization. + * + * @param src_ch Input parameter for the logical channel ID of + * the source channel. + * + * @param dest_ch Input parameter for the logical channel ID of + * the destination channel. + * + * @return This function returns 0 on success or negative error code on + * fail. + */ +int32_t ipu_unlink_channels(ipu_channel_t src_ch, ipu_channel_t dest_ch) +{ + int retval = 0; + unsigned long lock_flags; + uint32_t fs_proc_flow1; + uint32_t fs_proc_flow2; + uint32_t fs_proc_flow3; + uint32_t fs_disp_flow1; + + spin_lock_irqsave(&ipu_lock, lock_flags); + + fs_proc_flow1 = __raw_readl(IPU_FS_PROC_FLOW1); + fs_proc_flow2 = __raw_readl(IPU_FS_PROC_FLOW2); + fs_proc_flow3 = __raw_readl(IPU_FS_PROC_FLOW3); + fs_disp_flow1 = __raw_readl(IPU_FS_DISP_FLOW1); + + switch (src_ch) { + case CSI_MEM0: + fs_proc_flow3 &= ~FS_SMFC0_DEST_SEL_MASK; + break; + case CSI_MEM1: + fs_proc_flow3 &= ~FS_SMFC1_DEST_SEL_MASK; + break; + case CSI_MEM2: + fs_proc_flow3 &= ~FS_SMFC2_DEST_SEL_MASK; + break; + case CSI_MEM3: + fs_proc_flow3 &= ~FS_SMFC3_DEST_SEL_MASK; + break; + case CSI_PRP_ENC_MEM: + fs_proc_flow2 &= ~FS_PRPENC_DEST_SEL_MASK; + break; + case CSI_PRP_VF_MEM: + fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK; + break; + case MEM_PP_MEM: + fs_proc_flow2 &= ~FS_PP_DEST_SEL_MASK; + break; + case MEM_ROT_PP_MEM: + fs_proc_flow2 &= ~FS_PP_ROT_DEST_SEL_MASK; + break; + case MEM_PRP_ENC_MEM: + fs_proc_flow2 &= ~FS_PRPENC_DEST_SEL_MASK; + break; + case MEM_ROT_ENC_MEM: + fs_proc_flow2 &= ~FS_PRPENC_ROT_DEST_SEL_MASK; + break; + case MEM_PRP_VF_MEM: + fs_proc_flow2 &= ~FS_PRPVF_DEST_SEL_MASK; + break; + case MEM_ROT_VF_MEM: + fs_proc_flow2 &= ~FS_PRPVF_ROT_DEST_SEL_MASK; + break; + default: + retval = -EINVAL; + goto err; + } + + switch (dest_ch) { + case MEM_PP_MEM: + fs_proc_flow1 &= ~FS_PP_SRC_SEL_MASK; + break; + case MEM_ROT_PP_MEM: + fs_proc_flow1 &= ~FS_PP_ROT_SRC_SEL_MASK; + break; + case MEM_PRP_ENC_MEM: + fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK; + break; + case MEM_ROT_ENC_MEM: + fs_proc_flow1 &= ~FS_PRPENC_ROT_SRC_SEL_MASK; + break; + case MEM_PRP_VF_MEM: + fs_proc_flow1 &= ~FS_PRP_SRC_SEL_MASK; + break; + case MEM_ROT_VF_MEM: + fs_proc_flow1 &= ~FS_PRPVF_ROT_SRC_SEL_MASK; + break; + case MEM_DC_SYNC: + fs_disp_flow1 &= ~FS_DC1_SRC_SEL_MASK; + break; + case MEM_BG_SYNC: + fs_disp_flow1 &= ~FS_DP_SYNC0_SRC_SEL_MASK; + break; + case MEM_FG_SYNC: + fs_disp_flow1 &= ~FS_DP_SYNC1_SRC_SEL_MASK; + break; + case MEM_DC_ASYNC: + fs_disp_flow1 &= ~FS_DC2_SRC_SEL_MASK; + break; + case MEM_BG_ASYNC0: + fs_disp_flow1 &= ~FS_DP_ASYNC0_SRC_SEL_MASK; + break; + case MEM_FG_ASYNC0: + fs_disp_flow1 &= ~FS_DP_ASYNC1_SRC_SEL_MASK; + break; + default: + retval = -EINVAL; + goto err; + } + + __raw_writel(fs_proc_flow1, IPU_FS_PROC_FLOW1); + __raw_writel(fs_proc_flow2, IPU_FS_PROC_FLOW2); + __raw_writel(fs_proc_flow3, IPU_FS_PROC_FLOW3); + __raw_writel(fs_disp_flow1, IPU_FS_DISP_FLOW1); + +err: + spin_unlock_irqrestore(&ipu_lock, lock_flags); + return retval; +} +EXPORT_SYMBOL(ipu_unlink_channels); + +/*! + * This function enables a logical channel. + * + * @param channel Input parameter for the logical channel ID. + * + * @return This function returns 0 on success or negative error code on + * fail. + */ +int32_t ipu_enable_channel(ipu_channel_t channel) +{ + uint32_t reg; + unsigned long lock_flags; + uint32_t in_dma; + uint32_t out_dma; + + /* Get input and output dma channels */ + out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER); + in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER); + + spin_lock_irqsave(&ipu_lock, lock_flags); + + if (idma_is_valid(in_dma)) { + reg = __raw_readl(IDMAC_CHA_EN(in_dma)); + __raw_writel(reg | idma_mask(in_dma), IDMAC_CHA_EN(in_dma)); + } + if (idma_is_valid(out_dma)) { + reg = __raw_readl(IDMAC_CHA_EN(out_dma)); + __raw_writel(reg | idma_mask(out_dma), IDMAC_CHA_EN(out_dma)); + } + + if ((channel == MEM_DC_SYNC) || (channel == MEM_BG_SYNC) || + (channel == MEM_FG_SYNC)) + _ipu_dp_dc_enable(channel); + + if (_ipu_is_ic_chan(in_dma) || _ipu_is_ic_chan(out_dma) || + _ipu_is_irt_chan(in_dma) || _ipu_is_irt_chan(out_dma)) + _ipu_ic_enable_task(channel); + + spin_unlock_irqrestore(&ipu_lock, lock_flags); + return 0; +} +EXPORT_SYMBOL(ipu_enable_channel); + +/*! + * This function disables a logical channel. + * + * @param channel Input parameter for the logical channel ID. + * + * @param wait_for_stop Flag to set whether to wait for channel end + * of frame or return immediately. + * + * @return This function returns 0 on success or negative error code on + * fail. + */ +int32_t ipu_disable_channel(ipu_channel_t channel, bool wait_for_stop) +{ + uint32_t reg; + unsigned long lock_flags; + uint32_t in_dma; + uint32_t out_dma; + uint32_t timeout; + + /* Get input and output dma channels */ + out_dma = channel_2_dma(channel, IPU_OUTPUT_BUFFER); + in_dma = channel_2_dma(channel, IPU_VIDEO_IN_BUFFER); + + if (idma_is_valid(in_dma) && !idma_is_set(IDMAC_CHA_EN, in_dma)) + return -EINVAL; + if (idma_is_valid(out_dma) && !idma_is_set(IDMAC_CHA_EN, out_dma)) + return -EINVAL; + + if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC) || + (channel == MEM_DC_SYNC)) { + _ipu_dp_dc_disable(channel); + } else if (wait_for_stop) { + timeout = 40; + while (idma_is_set(IDMAC_CHA_BUSY, in_dma) || + idma_is_set(IDMAC_CHA_BUSY, out_dma) || + (_ipu_channel_status(channel) == TASK_STAT_ACTIVE)) { + timeout--; + msleep(10); + if (timeout == 0) { + ipu_dump_registers(); + break; + } + } + dev_dbg(g_ipu_dev, "timeout = %d * 10ms\n", 40 - timeout); + } + + spin_lock_irqsave(&ipu_lock, lock_flags); + + /* Disable IC task */ + if (_ipu_is_ic_chan(in_dma) || _ipu_is_ic_chan(out_dma) || + _ipu_is_irt_chan(in_dma) || _ipu_is_irt_chan(out_dma)) + _ipu_ic_disable_task(channel); + + /* Disable DMA channel(s) */ + if (idma_is_valid(in_dma)) { + reg = __raw_readl(IDMAC_CHA_EN(in_dma)); + __raw_writel(reg & ~idma_mask(in_dma), IDMAC_CHA_EN(in_dma)); + __raw_writel(idma_mask(in_dma), IPU_CHA_CUR_BUF(in_dma)); + } + if (idma_is_valid(out_dma)) { + reg = __raw_readl(IDMAC_CHA_EN(out_dma)); + __raw_writel(reg & ~idma_mask(out_dma), IDMAC_CHA_EN(out_dma)); + __raw_writel(idma_mask(out_dma), IPU_CHA_CUR_BUF(out_dma)); + } + + /* Set channel buffers NOT to be ready */ + __raw_writel(0xF0000000, IPU_GPR); /* write one to clear */ + if (idma_is_valid(in_dma)) { + if (idma_is_set(IPU_CHA_BUF0_RDY, in_dma)) { + __raw_writel(idma_mask(in_dma), + IPU_CHA_BUF0_RDY(in_dma)); + } + if (idma_is_set(IPU_CHA_BUF1_RDY, in_dma)) { + __raw_writel(idma_mask(in_dma), + IPU_CHA_BUF1_RDY(in_dma)); + } + } + if (idma_is_valid(out_dma)) { + if (idma_is_set(IPU_CHA_BUF0_RDY, out_dma)) { + __raw_writel(idma_mask(out_dma), + IPU_CHA_BUF0_RDY(out_dma)); + } + if (idma_is_set(IPU_CHA_BUF1_RDY, out_dma)) { + __raw_writel(idma_mask(out_dma), + IPU_CHA_BUF1_RDY(out_dma)); + } + } + __raw_writel(0x0, IPU_GPR); /* write one to set */ + + spin_unlock_irqrestore(&ipu_lock, lock_flags); + + return 0; +} +EXPORT_SYMBOL(ipu_disable_channel); + +static irqreturn_t ipu_irq_handler(int irq, void *desc) +{ + int i; + uint32_t line; + irqreturn_t result = IRQ_NONE; + uint32_t int_stat; + const int err_reg[] = { 5, 6, 9, 10, 0 }; + const int int_reg[] = { 1, 2, 3, 4, 11, 12, 13, 14, 15, 0 }; + + if (g_ipu_irq[1]) { + disable_irq(g_ipu_irq[0]); + disable_irq(g_ipu_irq[1]); + } + + for (i = 0;; i++) { + if (err_reg[i] == 0) + break; + int_stat = __raw_readl(IPU_INT_STAT(err_reg[i])); + int_stat &= __raw_readl(IPU_INT_CTRL(err_reg[i])); + if (int_stat) { + __raw_writel(int_stat, IPU_INT_STAT(err_reg[i])); + dev_err(g_ipu_dev, + "IPU Error - IPU_INT_STAT_%d = 0x%08X\n", + err_reg[i], int_stat); + + /* Disable interrupts so we only get error once */ + int_stat = + __raw_readl(IPU_INT_CTRL(err_reg[i])) & ~int_stat; + __raw_writel(int_stat, IPU_INT_CTRL(err_reg[i])); + } + } + + for (i = 0;; i++) { + if (int_reg[i] == 0) + break; + int_stat = __raw_readl(IPU_INT_STAT(int_reg[i])); + int_stat &= __raw_readl(IPU_INT_CTRL(int_reg[i])); + __raw_writel(int_stat, IPU_INT_STAT(int_reg[i])); + while ((line = ffs(int_stat)) != 0) { + line--; + int_stat &= ~(1UL << line); + line += (int_reg[i] - 1) * 32; + result |= + ipu_irq_list[line].handler(line, + ipu_irq_list[line]. + dev_id); + } + } + + if (g_ipu_irq[1]) { + enable_irq(g_ipu_irq[0]); + enable_irq(g_ipu_irq[1]); + } + return result; +} + +/*! + * This function enables the interrupt for the specified interrupt line. + * The interrupt lines are defined in \b ipu_irq_line enum. + * + * @param irq Interrupt line to enable interrupt for. + * + */ +void ipu_enable_irq(uint32_t irq) +{ + uint32_t reg; + unsigned long lock_flags; + + if (!g_ipu_clk_enabled) + clk_enable(g_ipu_clk); + + spin_lock_irqsave(&ipu_lock, lock_flags); + + reg = __raw_readl(IPUIRQ_2_CTRLREG(irq)); + reg |= IPUIRQ_2_MASK(irq); + __raw_writel(reg, IPUIRQ_2_CTRLREG(irq)); + + spin_unlock_irqrestore(&ipu_lock, lock_flags); + if (!g_ipu_clk_enabled) + clk_disable(g_ipu_clk); +} +EXPORT_SYMBOL(ipu_enable_irq); + +/*! + * This function disables the interrupt for the specified interrupt line. + * The interrupt lines are defined in \b ipu_irq_line enum. + * + * @param irq Interrupt line to disable interrupt for. + * + */ +void ipu_disable_irq(uint32_t irq) +{ + uint32_t reg; + unsigned long lock_flags; + + if (!g_ipu_clk_enabled) + clk_enable(g_ipu_clk); + spin_lock_irqsave(&ipu_lock, lock_flags); + + reg = __raw_readl(IPUIRQ_2_CTRLREG(irq)); + reg &= ~IPUIRQ_2_MASK(irq); + __raw_writel(reg, IPUIRQ_2_CTRLREG(irq)); + + spin_unlock_irqrestore(&ipu_lock, lock_flags); + if (!g_ipu_clk_enabled) + clk_disable(g_ipu_clk); +} +EXPORT_SYMBOL(ipu_disable_irq); + +/*! + * This function clears the interrupt for the specified interrupt line. + * The interrupt lines are defined in \b ipu_irq_line enum. + * + * @param irq Interrupt line to clear interrupt for. + * + */ +void ipu_clear_irq(uint32_t irq) +{ + if (!g_ipu_clk_enabled) + clk_enable(g_ipu_clk); + + __raw_writel(IPUIRQ_2_MASK(irq), IPUIRQ_2_STATREG(irq)); + + if (!g_ipu_clk_enabled) + clk_disable(g_ipu_clk); +} +EXPORT_SYMBOL(ipu_clear_irq); + +/*! + * This function returns the current interrupt status for the specified + * interrupt line. The interrupt lines are defined in \b ipu_irq_line enum. + * + * @param irq Interrupt line to get status for. + * + * @return Returns true if the interrupt is pending/asserted or false if + * the interrupt is not pending. + */ +bool ipu_get_irq_status(uint32_t irq) +{ + uint32_t reg; + + if (!g_ipu_clk_enabled) + clk_enable(g_ipu_clk); + + reg = __raw_readl(IPUIRQ_2_STATREG(irq)); + + if (!g_ipu_clk_enabled) + clk_disable(g_ipu_clk); + + if (reg & IPUIRQ_2_MASK(irq)) + return true; + else + return false; +} +EXPORT_SYMBOL(ipu_get_irq_status); + +/*! + * This function registers an interrupt handler function for the specified + * interrupt line. The interrupt lines are defined in \b ipu_irq_line enum. + * + * @param irq Interrupt line to get status for. + * + * @param handler Input parameter for address of the handler + * function. + * + * @param irq_flags Flags for interrupt mode. Currently not used. + * + * @param devname Input parameter for string name of driver + * registering the handler. + * + * @param dev_id Input parameter for pointer of data to be + * passed to the handler. + * + * @return This function returns 0 on success or negative error code on + * fail. + */ +int ipu_request_irq(uint32_t irq, + irqreturn_t(*handler) (int, void *), + uint32_t irq_flags, const char *devname, void *dev_id) +{ + unsigned long lock_flags; + + BUG_ON(irq >= IPU_IRQ_COUNT); + + spin_lock_irqsave(&ipu_lock, lock_flags); + + if (ipu_irq_list[irq].handler != NULL) { + dev_err(g_ipu_dev, + "handler already installed on irq %d\n", irq); + spin_unlock_irqrestore(&ipu_lock, lock_flags); + return -EINVAL; + } + + ipu_irq_list[irq].handler = handler; + ipu_irq_list[irq].flags = irq_flags; + ipu_irq_list[irq].dev_id = dev_id; + ipu_irq_list[irq].name = devname; + + spin_unlock_irqrestore(&ipu_lock, lock_flags); + + ipu_enable_irq(irq); /* enable the interrupt */ + + return 0; +} +EXPORT_SYMBOL(ipu_request_irq); + +/*! + * This function unregisters an interrupt handler for the specified interrupt + * line. The interrupt lines are defined in \b ipu_irq_line enum. + * + * @param irq Interrupt line to get status for. + * + * @param dev_id Input parameter for pointer of data to be passed + * to the handler. This must match value passed to + * ipu_request_irq(). + * + */ +void ipu_free_irq(uint32_t irq, void *dev_id) +{ + ipu_disable_irq(irq); /* disable the interrupt */ + + if (ipu_irq_list[irq].dev_id == dev_id) + ipu_irq_list[irq].handler = NULL; +} +EXPORT_SYMBOL(ipu_free_irq); + +uint32_t _ipu_channel_status(ipu_channel_t channel) +{ + uint32_t stat = 0; + uint32_t task_stat_reg = __raw_readl(IPU_PROC_TASK_STAT); + + switch (channel) { + case MEM_PRP_VF_MEM: + stat = (task_stat_reg & TSTAT_VF_MASK) >> TSTAT_VF_OFFSET; + break; + case MEM_ROT_VF_MEM: + stat = + (task_stat_reg & TSTAT_VF_ROT_MASK) >> TSTAT_VF_ROT_OFFSET; + break; + case MEM_PRP_ENC_MEM: + stat = (task_stat_reg & TSTAT_ENC_MASK) >> TSTAT_ENC_OFFSET; + break; + case MEM_ROT_ENC_MEM: + stat = + (task_stat_reg & TSTAT_ENC_ROT_MASK) >> + TSTAT_ENC_ROT_OFFSET; + break; + case MEM_PP_MEM: + stat = (task_stat_reg & TSTAT_PP_MASK) >> TSTAT_PP_OFFSET; + break; + case MEM_ROT_PP_MEM: + stat = + (task_stat_reg & TSTAT_PP_ROT_MASK) >> TSTAT_PP_ROT_OFFSET; + break; + + default: + stat = TASK_STAT_IDLE; + break; + } + return stat; +} + +uint32_t bytes_per_pixel(uint32_t fmt) +{ + switch (fmt) { + case IPU_PIX_FMT_GENERIC: /*generic data */ + case IPU_PIX_FMT_RGB332: + case IPU_PIX_FMT_YUV420P: + case IPU_PIX_FMT_YUV422P: + return 1; + break; + case IPU_PIX_FMT_RGB565: + case IPU_PIX_FMT_YUYV: + case IPU_PIX_FMT_UYVY: + return 2; + break; + case IPU_PIX_FMT_BGR24: + case IPU_PIX_FMT_RGB24: + return 3; + break; + case IPU_PIX_FMT_GENERIC_32: /*generic data */ + case IPU_PIX_FMT_BGR32: + case IPU_PIX_FMT_BGRA32: + case IPU_PIX_FMT_RGB32: + case IPU_PIX_FMT_RGBA32: + case IPU_PIX_FMT_ABGR32: + return 4; + break; + default: + return 1; + break; + } + return 0; +} +EXPORT_SYMBOL(bytes_per_pixel); + +ipu_color_space_t format_to_colorspace(uint32_t fmt) +{ + switch (fmt) { + case IPU_PIX_FMT_RGB666: + case IPU_PIX_FMT_RGB565: + case IPU_PIX_FMT_BGR24: + case IPU_PIX_FMT_RGB24: + case IPU_PIX_FMT_BGR32: + case IPU_PIX_FMT_BGRA32: + case IPU_PIX_FMT_RGB32: + case IPU_PIX_FMT_RGBA32: + case IPU_PIX_FMT_ABGR32: + case IPU_PIX_FMT_LVDS666: + case IPU_PIX_FMT_LVDS888: + return RGB; + break; + + default: + return YCbCr; + break; + } + return RGB; +} + +void ipu_set_csc_coefficients(ipu_channel_t channel, int32_t param[][3]) +{ + _ipu_dp_set_csc_coefficients(channel, param); +} +EXPORT_SYMBOL(ipu_set_csc_coefficients); + +static int ipu_suspend(struct platform_device *pdev, pm_message_t state) +{ + mxc_pg_enable(pdev); + return 0; +} + +static int ipu_resume(struct platform_device *pdev) +{ + mxc_pg_disable(pdev); + + clk_enable(g_ipu_clk); + + _ipu_dmfc_init(); + _ipu_init_dc_mappings(); + + /* Set sync refresh channels as high priority */ + __raw_writel(0x18800000L, IDMAC_CHA_PRI(0)); + + clk_disable(g_ipu_clk); + return 0; +} + +/*! + * This structure contains pointers to the power management callback functions. + */ +static struct platform_driver mxcipu_driver = { + .driver = { + .name = "mxc_ipu", + }, + .probe = ipu_probe, + .remove = ipu_remove, + .suspend_late = ipu_suspend, + .resume_early = ipu_resume, +}; + +int32_t __init ipu_gen_init(void) +{ + int32_t ret; + + ret = platform_driver_register(&mxcipu_driver); + return 0; +} + +subsys_initcall(ipu_gen_init); + +static void __exit ipu_gen_uninit(void) +{ + platform_driver_unregister(&mxcipu_driver); +} + +module_exit(ipu_gen_uninit); --- linux-2.6.28.orig/drivers/mxc/ipu3/ipu_param_mem.h +++ linux-2.6.28/drivers/mxc/ipu3/ipu_param_mem.h @@ -0,0 +1,332 @@ +/* + * Copyright 2005-2008 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 __INCLUDE_IPU_PARAM_MEM_H__ +#define __INCLUDE_IPU_PARAM_MEM_H__ + +#include +#include + +extern u32 *ipu_cpmem_base; + +struct ipu_ch_param_word { + uint32_t data[5]; + uint32_t res[3]; +}; + +struct ipu_ch_param { + struct ipu_ch_param_word word[2]; +}; + +#define ipu_ch_param_addr(ch) (((struct ipu_ch_param *)ipu_cpmem_base) + (ch)) + +#define _param_word(base, w) \ + (((struct ipu_ch_param *)(base))->word[(w)].data) + +#define ipu_ch_param_set_field(base, w, bit, size, v) { \ + int i = (bit) / 32; \ + int off = (bit) % 32; \ + _param_word(base, w)[i] |= (v) << off; \ + if (((bit)+(size)-1)/32 > i) { \ + _param_word(base, w)[i + 1] |= (v) >> (off ? (32 - off) : 0); \ + } \ +} + +#define ipu_ch_param_mod_field(base, w, bit, size, v) { \ + int i = (bit) / 32; \ + int off = (bit) % 32; \ + u32 mask = (1UL << size) - 1; \ + u32 temp = _param_word(base, w)[i]; \ + temp &= ~(mask << off); \ + _param_word(base, w)[i] = temp | (v) << off; \ + if (((bit)+(size)-1)/32 > i) { \ + temp = _param_word(base, w)[i + 1]; \ + temp &= ~(mask >> (32 - off)); \ + _param_word(base, w)[i + 1] = \ + temp | ((v) >> (off ? (32 - off) : 0)); \ + } \ +} + +#define ipu_ch_param_read_field(base, w, bit, size) ({ \ + u32 temp2; \ + int i = (bit) / 32; \ + int off = (bit) % 32; \ + u32 mask = (1UL << size) - 1; \ + u32 temp1 = _param_word(base, w)[i]; \ + temp1 = mask & (temp1 >> off); \ + if (((bit)+(size)-1)/32 > i) { \ + temp2 = _param_word(base, w)[i + 1]; \ + temp2 &= mask >> (off ? (32 - off) : 0); \ + temp1 |= temp2 << (off ? (32 - off) : 0); \ + } \ + temp1; \ +}) + +static inline void _ipu_ch_params_set_packing(struct ipu_ch_param *p, + int red_width, int red_offset, + int green_width, int green_offset, + int blue_width, int blue_offset, + int alpha_width, int alpha_offset) +{ + /* Setup red width and offset */ + ipu_ch_param_set_field(p, 1, 116, 3, red_width - 1); + ipu_ch_param_set_field(p, 1, 128, 5, red_offset); + /* Setup green width and offset */ + ipu_ch_param_set_field(p, 1, 119, 3, green_width - 1); + ipu_ch_param_set_field(p, 1, 133, 5, green_offset); + /* Setup blue width and offset */ + ipu_ch_param_set_field(p, 1, 122, 3, blue_width - 1); + ipu_ch_param_set_field(p, 1, 138, 5, blue_offset); + /* Setup alpha width and offset */ + ipu_ch_param_set_field(p, 1, 125, 3, alpha_width - 1); + ipu_ch_param_set_field(p, 1, 143, 5, alpha_offset); +} + +static inline void _ipu_ch_param_dump(int ch) +{ + struct ipu_ch_param *p = ipu_ch_param_addr(ch); + pr_debug("ch %d word 0 - %08X %08X %08X %08X %08X\n", ch, + p->word[0].data[0], p->word[0].data[1], p->word[0].data[2], + p->word[0].data[3], p->word[0].data[4]); + pr_debug("ch %d word 1 - %08X %08X %08X %08X %08X\n", ch, + p->word[1].data[0], p->word[1].data[1], p->word[1].data[2], + p->word[1].data[3], p->word[1].data[4]); + pr_debug("PFS 0x%x, ", + ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 85, 4)); + pr_debug("BPP 0x%x, ", + ipu_ch_param_read_field(ipu_ch_param_addr(ch), 0, 107, 3)); + pr_debug("NPB 0x%x\n", + ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 78, 7)); + + pr_debug("FW %d, ", + ipu_ch_param_read_field(ipu_ch_param_addr(ch), 0, 125, 13)); + pr_debug("FH %d, ", + ipu_ch_param_read_field(ipu_ch_param_addr(ch), 0, 138, 12)); + pr_debug("Stride %d\n", + ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 102, 14)); + + pr_debug("Width0 %d+1, ", + ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 116, 3)); + pr_debug("Width1 %d+1, ", + ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 119, 3)); + pr_debug("Width2 %d+1, ", + ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 122, 3)); + pr_debug("Width3 %d+1, ", + ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 125, 3)); + pr_debug("Offset0 %d, ", + ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 128, 5)); + pr_debug("Offset1 %d, ", + ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 133, 5)); + pr_debug("Offset2 %d, ", + ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 138, 5)); + pr_debug("Offset3 %d\n", + ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 143, 5)); +} + +static inline void _ipu_ch_param_init(int ch, + uint32_t pixel_fmt, uint32_t width, + uint32_t height, uint32_t stride, + uint32_t u, uint32_t v, + uint32_t uv_stride, dma_addr_t addr0, + dma_addr_t addr1) +{ + uint32_t u_offset = 0; + uint32_t v_offset = 0; + struct ipu_ch_param params; + + memset(¶ms, 0, sizeof(params)); + + ipu_ch_param_set_field(¶ms, 0, 125, 13, width - 1); + ipu_ch_param_set_field(¶ms, 0, 138, 12, height - 1); + ipu_ch_param_set_field(¶ms, 1, 102, 14, stride - 1); + + ipu_ch_param_set_field(¶ms, 1, 0, 29, addr0 >> 3); + ipu_ch_param_set_field(¶ms, 1, 29, 29, addr1 >> 3); + + switch (pixel_fmt) { + case IPU_PIX_FMT_GENERIC: + /*Represents 8-bit Generic data */ + ipu_ch_param_set_field(¶ms, 0, 107, 3, 5); /* bits/pixel */ + ipu_ch_param_set_field(¶ms, 1, 85, 4, 6); /* pix format */ + ipu_ch_param_set_field(¶ms, 1, 78, 7, 63); /* burst size */ + break; + case IPU_PIX_FMT_GENERIC_32: + /*Represents 32-bit Generic data */ + break; + case IPU_PIX_FMT_RGB565: + ipu_ch_param_set_field(¶ms, 0, 107, 3, 3); /* bits/pixel */ + ipu_ch_param_set_field(¶ms, 1, 85, 4, 7); /* pix format */ + ipu_ch_param_set_field(¶ms, 1, 78, 7, 31); /* burst size */ + + _ipu_ch_params_set_packing(¶ms, 5, 0, 6, 5, 5, 11, 1, 16); + break; + case IPU_PIX_FMT_BGR24: + ipu_ch_param_set_field(¶ms, 0, 107, 3, 1); /* bits/pixel */ + ipu_ch_param_set_field(¶ms, 1, 85, 4, 7); /* pix format */ + ipu_ch_param_set_field(¶ms, 1, 78, 7, 19); /* burst size */ + + _ipu_ch_params_set_packing(¶ms, 8, 0, 8, 8, 8, 16, 1, 24); + break; + case IPU_PIX_FMT_RGB24: + case IPU_PIX_FMT_YUV444: + ipu_ch_param_set_field(¶ms, 0, 107, 3, 1); /* bits/pixel */ + ipu_ch_param_set_field(¶ms, 1, 85, 4, 7); /* pix format */ + ipu_ch_param_set_field(¶ms, 1, 78, 7, 19); /* burst size */ + + _ipu_ch_params_set_packing(¶ms, 8, 16, 8, 8, 8, 0, 1, 24); + break; + case IPU_PIX_FMT_BGRA32: + case IPU_PIX_FMT_BGR32: + ipu_ch_param_set_field(¶ms, 0, 107, 3, 0); /* bits/pixel */ + ipu_ch_param_set_field(¶ms, 1, 85, 4, 7); /* pix format */ + ipu_ch_param_set_field(¶ms, 1, 78, 7, 15); /* burst size */ + + _ipu_ch_params_set_packing(¶ms, 8, 8, 8, 16, 8, 24, 8, 0); + break; + case IPU_PIX_FMT_RGBA32: + case IPU_PIX_FMT_RGB32: + ipu_ch_param_set_field(¶ms, 0, 107, 3, 0); /* bits/pixel */ + ipu_ch_param_set_field(¶ms, 1, 85, 4, 7); /* pix format */ + ipu_ch_param_set_field(¶ms, 1, 78, 7, 15); /* burst size */ + + _ipu_ch_params_set_packing(¶ms, 8, 24, 8, 16, 8, 8, 8, 0); + break; + case IPU_PIX_FMT_ABGR32: + ipu_ch_param_set_field(¶ms, 0, 107, 3, 0); /* bits/pixel */ + ipu_ch_param_set_field(¶ms, 1, 85, 4, 7); /* pix format */ + ipu_ch_param_set_field(¶ms, 1, 78, 7, 15); /* burst size */ + + _ipu_ch_params_set_packing(¶ms, 8, 0, 8, 8, 8, 16, 8, 24); + break; + case IPU_PIX_FMT_UYVY: + ipu_ch_param_set_field(¶ms, 0, 107, 3, 3); /* bits/pixel */ + ipu_ch_param_set_field(¶ms, 1, 85, 4, 0xA); /* pix format */ + ipu_ch_param_set_field(¶ms, 1, 78, 7, 31); /* burst size */ + break; + case IPU_PIX_FMT_YUYV: + ipu_ch_param_set_field(¶ms, 0, 107, 3, 3); /* bits/pixel */ + ipu_ch_param_set_field(¶ms, 1, 85, 4, 0x8); /* pix format */ + ipu_ch_param_set_field(¶ms, 1, 78, 7, 31); /* burst size */ + break; + case IPU_PIX_FMT_YUV420P2: + case IPU_PIX_FMT_YUV420P: + ipu_ch_param_set_field(¶ms, 1, 85, 4, 2); /* pix format */ + ipu_ch_param_set_field(¶ms, 1, 78, 7, 31); /* burst size */ + + if (uv_stride < stride / 2) + uv_stride = stride / 2; + + u_offset = stride * height; + v_offset = u_offset + (uv_stride * height / 2); + break; + case IPU_PIX_FMT_YVU422P: + /* BPP & pixel format */ + ipu_ch_param_set_field(¶ms, 1, 85, 4, 1); /* pix format */ + ipu_ch_param_set_field(¶ms, 1, 78, 7, 31); /* burst size */ + + if (uv_stride < stride / 2) + uv_stride = stride / 2; + + v_offset = (v == 0) ? stride * height : v; + u_offset = (u == 0) ? v_offset + v_offset / 2 : u; + break; + case IPU_PIX_FMT_YUV422P: + /* BPP & pixel format */ + ipu_ch_param_set_field(¶ms, 1, 85, 4, 1); /* pix format */ + ipu_ch_param_set_field(¶ms, 1, 78, 7, 31); /* burst size */ + + if (uv_stride < stride / 2) + uv_stride = stride / 2; + + u_offset = (u == 0) ? stride * height : u; + v_offset = (v == 0) ? u_offset + u_offset / 2 : v; + break; + case IPU_PIX_FMT_NV12: + /* BPP & pixel format */ + ipu_ch_param_set_field(¶ms, 1, 85, 4, 4); /* pix format */ + ipu_ch_param_set_field(¶ms, 1, 78, 7, 31); /* burst size */ + uv_stride = stride; + u_offset = (u == 0) ? stride * height : u; + break; + default: + dev_err(g_ipu_dev, "mxc ipu: unimplemented pixel format\n"); + break; + } + + if (uv_stride) + ipu_ch_param_set_field(¶ms, 1, 128, 14, uv_stride - 1); + + if (u > u_offset) + u_offset = u; + + if (v > v_offset) + v_offset = v; + + ipu_ch_param_set_field(¶ms, 0, 46, 22, u_offset / 8); + ipu_ch_param_set_field(¶ms, 0, 68, 22, v_offset / 8); + + pr_debug("initializing idma ch %d @ %p\n", ch, ipu_ch_param_addr(ch)); + memcpy(ipu_ch_param_addr(ch), ¶ms, sizeof(params)); +}; + +static inline void _ipu_ch_param_set_burst_size(uint32_t ch, + uint16_t burst_pixels) +{ + ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 78, 7, + burst_pixels - 1); +}; + +static inline int _ipu_ch_param_get_burst_size(uint32_t ch) +{ + return ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 78, 7) + 1; +}; + +static inline int _ipu_ch_param_get_bpp(uint32_t ch) +{ + return ipu_ch_param_read_field(ipu_ch_param_addr(ch), 0, 107, 3); +}; + +static inline void _ipu_ch_param_set_buffer(uint32_t ch, int bufNum, + dma_addr_t phyaddr) +{ + ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 29 * bufNum, 29, + phyaddr / 8); +}; + +static inline void _ipu_ch_param_set_rotation(uint32_t ch, + ipu_rotate_mode_t rot) +{ + u32 temp_rot = bitrev8(rot) >> 5; + ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 0, 119, 3, temp_rot); +}; + +static inline void _ipu_ch_param_set_block_mode(uint32_t ch) +{ + ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 0, 117, 2, 1); +}; + +static inline void _ipu_ch_param_set_interlaced_scan(uint32_t ch) +{ + u32 stride; + ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 113, 1, 1); + stride = ipu_ch_param_read_field(ipu_ch_param_addr(ch), 1, 102, 14) + 1; + ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 58, 20, stride / 8); + stride *= 2; + ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 102, 14, stride - 1); +}; + +static inline void _ipu_ch_param_set_high_priority(uint32_t ch) +{ + ipu_ch_param_mod_field(ipu_ch_param_addr(ch), 1, 93, 2, 1); +}; + +#endif --- linux-2.6.28.orig/drivers/mxc/ipu3/ipu_device.c +++ linux-2.6.28/drivers/mxc/ipu3/ipu_device.c @@ -0,0 +1,445 @@ +/* + * Copyright 2005-2009 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 + */ + +/*! + * @file ipu_device.c + * + * @brief This file contains the IPUv3 driver device interface and fops functions. + * + * @ingroup IPU + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ipu_prv.h" +#include "ipu_regs.h" +#include "ipu_param_mem.h" + +/* Strucutures and variables for exporting MXC IPU as device*/ + +#define MAX_Q_SIZE 10 + +static int mxc_ipu_major; +static struct class *mxc_ipu_class; + +DEFINE_SPINLOCK(queue_lock); +static DECLARE_MUTEX(user_mutex); + +static wait_queue_head_t waitq; +static int pending_events; +int read_ptr; +int write_ptr; + +typedef struct _event_type { + int irq; + void *dev; +} event_type; + +event_type events[MAX_Q_SIZE]; + +int register_ipu_device(void); + +/* Static functions */ + +int get_events(event_type *p) +{ + unsigned long flags; + int ret = 0; + spin_lock_irqsave(&queue_lock, flags); + if (pending_events != 0) { + *p = events[read_ptr]; + read_ptr++; + pending_events--; + if (read_ptr >= MAX_Q_SIZE) + read_ptr = 0; + } else { + ret = -1; + } + + spin_unlock_irqrestore(&queue_lock, flags); + return ret; +} + +static irqreturn_t mxc_ipu_generic_handler(int irq, void *dev_id) +{ + event_type e; + + e.irq = irq; + e.dev = dev_id; + events[write_ptr] = e; + write_ptr++; + if (write_ptr >= MAX_Q_SIZE) + write_ptr = 0; + pending_events++; + /* Wakeup any blocking user context */ + wake_up_interruptible(&waitq); + return IRQ_HANDLED; +} + +static int mxc_ipu_open(struct inode *inode, struct file *file) +{ + int ret = 0; + return ret; +} +static int mxc_ipu_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + int ret = 0; + + switch (cmd) { + case IPU_INIT_CHANNEL: + { + ipu_channel_parm parm; + + if (copy_from_user + (&parm, (ipu_channel_parm *) arg, + sizeof(ipu_channel_parm))) + return -EFAULT; + + if (!parm.flag) { + ret = + ipu_init_channel(parm.channel, + &parm.params); + } else { + ret = ipu_init_channel(parm.channel, NULL); + } + } + break; + case IPU_UNINIT_CHANNEL: + { + ipu_channel_t ch; + int __user *argp = (void __user *)arg; + if (get_user(ch, argp)) + return -EFAULT; + ipu_uninit_channel(ch); + } + break; + case IPU_INIT_CHANNEL_BUFFER: + { + ipu_channel_buf_parm parm; + if (copy_from_user + (&parm, (ipu_channel_buf_parm *) arg, + sizeof(ipu_channel_buf_parm))) + return -EFAULT; + + ret = + ipu_init_channel_buffer( + parm.channel, parm.type, + parm.pixel_fmt, + parm.width, parm.height, + parm.stride, + parm.rot_mode, + parm.phyaddr_0, + parm.phyaddr_1, + parm.u_offset, + parm.v_offset); + + } + break; + case IPU_UPDATE_CHANNEL_BUFFER: + { + ipu_channel_buf_parm parm; + if (copy_from_user + (&parm, (ipu_channel_buf_parm *) arg, + sizeof(ipu_channel_buf_parm))) + return -EFAULT; + + if ((parm.phyaddr_0 != (dma_addr_t) NULL) + && (parm.phyaddr_1 == (dma_addr_t) NULL)) { + ret = + ipu_update_channel_buffer( + parm.channel, + parm.type, + parm.bufNum, + parm.phyaddr_0); + } else if ((parm.phyaddr_0 == (dma_addr_t) NULL) + && (parm.phyaddr_1 != (dma_addr_t) NULL)) { + ret = + ipu_update_channel_buffer( + parm.channel, + parm.type, + parm.bufNum, + parm.phyaddr_1); + } else { + ret = -1; + } + + } + break; + case IPU_SELECT_CHANNEL_BUFFER: + { + ipu_channel_buf_parm parm; + if (copy_from_user + (&parm, (ipu_channel_buf_parm *) arg, + sizeof(ipu_channel_buf_parm))) + return -EFAULT; + + ret = + ipu_select_buffer(parm.channel, + parm.type, parm.bufNum); + + } + break; + case IPU_LINK_CHANNELS: + { + ipu_channel_link link; + if (copy_from_user + (&link, (ipu_channel_link *) arg, + sizeof(ipu_channel_link))) + return -EFAULT; + + ret = ipu_link_channels(link.src_ch, + link.dest_ch); + + } + break; + case IPU_UNLINK_CHANNELS: + { + ipu_channel_link link; + if (copy_from_user + (&link, (ipu_channel_link *) arg, + sizeof(ipu_channel_link))) + return -EFAULT; + + ret = ipu_unlink_channels(link.src_ch, + link.dest_ch); + + } + break; + case IPU_ENABLE_CHANNEL: + { + ipu_channel_t ch; + int __user *argp = (void __user *)arg; + if (get_user(ch, argp)) + return -EFAULT; + ipu_enable_channel(ch); + } + break; + case IPU_DISABLE_CHANNEL: + { + ipu_channel_info info; + if (copy_from_user + (&info, (ipu_channel_info *) arg, + sizeof(ipu_channel_info))) + return -EFAULT; + + ret = ipu_disable_channel(info.channel, + info.stop); + } + break; + case IPU_ENABLE_IRQ: + { + uint32_t irq; + int __user *argp = (void __user *)arg; + if (get_user(irq, argp)) + return -EFAULT; + ipu_enable_irq(irq); + } + break; + case IPU_DISABLE_IRQ: + { + uint32_t irq; + int __user *argp = (void __user *)arg; + if (get_user(irq, argp)) + return -EFAULT; + ipu_disable_irq(irq); + } + break; + case IPU_CLEAR_IRQ: + { + uint32_t irq; + int __user *argp = (void __user *)arg; + if (get_user(irq, argp)) + return -EFAULT; + ipu_clear_irq(irq); + } + break; + case IPU_FREE_IRQ: + { + ipu_irq_info info; + if (copy_from_user + (&info, (ipu_irq_info *) arg, + sizeof(ipu_irq_info))) + return -EFAULT; + + ipu_free_irq(info.irq, info.dev_id); + } + break; + case IPU_REQUEST_IRQ_STATUS: + { + uint32_t irq; + int __user *argp = (void __user *)arg; + if (get_user(irq, argp)) + return -EFAULT; + ret = ipu_get_irq_status(irq); + } + break; + case IPU_REGISTER_GENERIC_ISR: + { + ipu_event_info info; + if (copy_from_user + (&info, (ipu_event_info *) arg, + sizeof(ipu_event_info))) + return -EFAULT; + + ret = + ipu_request_irq(info.irq, + mxc_ipu_generic_handler, + 0, "video_sink", info.dev); + } + break; + case IPU_GET_EVENT: + /* User will have to allocate event_type + structure and pass the pointer in arg */ + { + event_type ev; + int r = -1; + r = get_events(&ev); + if (r == -1) { + wait_event_interruptible(waitq, + (pending_events != 0)); + r = get_events(&ev); + } + ret = -1; + if (r == 0) { + if (!copy_to_user((event_type *) arg, + &ev, sizeof(event_type))) + ret = 0; + } + } + break; + case IPU_ALOC_MEM: + { + ipu_mem_info info; + if (copy_from_user + (&info, (ipu_mem_info *) arg, + sizeof(ipu_mem_info))) + return -EFAULT; + + info.vaddr = dma_alloc_coherent(0, + PAGE_ALIGN(info.size), + &info.paddr, + GFP_DMA | GFP_KERNEL); + if (info.vaddr == 0) { + printk(KERN_ERR "dma alloc failed!\n"); + return -ENOBUFS; + } + if (copy_to_user((ipu_mem_info *) arg, &info, + sizeof(ipu_mem_info)) > 0) + return -EFAULT; + } + break; + case IPU_FREE_MEM: + { + ipu_mem_info info; + if (copy_from_user + (&info, (ipu_mem_info *) arg, + sizeof(ipu_mem_info))) + return -EFAULT; + + if (info.vaddr != 0) + dma_free_coherent(0, PAGE_ALIGN(info.size), + info.vaddr, info.paddr); + else + return -EFAULT; + } + break; + default: + break; + } + return ret; +} + +static int mxc_ipu_mmap(struct file *file, struct vm_area_struct *vma) +{ +// vma->vm_page_prot = pgprot_writethru(vma->vm_page_prot); + + if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) { + printk(KERN_ERR + "mmap failed!\n"); + return -ENOBUFS; + } + return 0; +} + +static int mxc_ipu_release(struct inode *inode, struct file *file) +{ + return 0; +} + +static struct file_operations mxc_ipu_fops = { + .owner = THIS_MODULE, + .open = mxc_ipu_open, + .mmap = mxc_ipu_mmap, + .release = mxc_ipu_release, + .ioctl = mxc_ipu_ioctl +}; + +int register_ipu_device() +{ + int ret = 0; + struct device *temp; + mxc_ipu_major = register_chrdev(0, "mxc_ipu", &mxc_ipu_fops); + if (mxc_ipu_major < 0) { + printk(KERN_ERR + "Unable to register Mxc Ipu as a char device\n"); + return mxc_ipu_major; + } + + mxc_ipu_class = class_create(THIS_MODULE, "mxc_ipu"); + if (IS_ERR(mxc_ipu_class)) { + printk(KERN_ERR "Unable to create class for Mxc Ipu\n"); + ret = PTR_ERR(mxc_ipu_class); + goto err1; + } + + temp = device_create(mxc_ipu_class, NULL, MKDEV(mxc_ipu_major, 0), + NULL, "mxc_ipu"); + + if (IS_ERR(temp)) { + printk(KERN_ERR "Unable to create class device for Mxc Ipu\n"); + ret = PTR_ERR(temp); + goto err2; + } + spin_lock_init(&queue_lock); + init_waitqueue_head(&waitq); + + pending_events = 0; + read_ptr = 0; + write_ptr = 0; + + return ret; + +err2: + class_destroy(mxc_ipu_class); +err1: + unregister_chrdev(mxc_ipu_major, "mxc_ipu"); + return ret; + +} --- linux-2.6.28.orig/drivers/mxc/ipu3/ipu_ic.c +++ linux-2.6.28/drivers/mxc/ipu3/ipu_ic.c @@ -0,0 +1,632 @@ +/* + * Copyright 2005-2009 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 + */ + +/* + * @file ipu_ic.c + * + * @brief IPU IC functions + * + * @ingroup IPU + */ +#include +#include +#include +#include +#include +#include + +#include "ipu_prv.h" +#include "ipu_regs.h" +#include "ipu_param_mem.h" + +enum { + IC_TASK_VIEWFINDER, + IC_TASK_ENCODER, + IC_TASK_POST_PROCESSOR +}; + +static void _init_csc(uint8_t ic_task, ipu_color_space_t in_format, + ipu_color_space_t out_format); +static bool _calc_resize_coeffs(uint32_t inSize, uint32_t outSize, + uint32_t *resizeCoeff, + uint32_t *downsizeCoeff); + +void ic_dump_register(void) +{ + printk(KERN_DEBUG "IC_CONF = \t0x%08X\n", __raw_readl(IC_CONF)); + printk(KERN_DEBUG "IC_PRP_ENC_RSC = \t0x%08X\n", + __raw_readl(IC_PRP_ENC_RSC)); + printk(KERN_DEBUG "IC_PRP_VF_RSC = \t0x%08X\n", + __raw_readl(IC_PRP_VF_RSC)); + printk(KERN_DEBUG "IC_PP_RSC = \t0x%08X\n", __raw_readl(IC_PP_RSC)); + printk(KERN_DEBUG "IC_IDMAC_1 = \t0x%08X\n", __raw_readl(IC_IDMAC_1)); + printk(KERN_DEBUG "IC_IDMAC_2 = \t0x%08X\n", __raw_readl(IC_IDMAC_2)); + printk(KERN_DEBUG "IC_IDMAC_3 = \t0x%08X\n", __raw_readl(IC_IDMAC_3)); +} + +void _ipu_ic_enable_task(ipu_channel_t channel) +{ + uint32_t ic_conf; + + ic_conf = __raw_readl(IC_CONF); + switch (channel) { + case CSI_PRP_VF_MEM: + case MEM_PRP_VF_MEM: + ic_conf |= IC_CONF_PRPVF_EN; + break; + case MEM_ROT_VF_MEM: + ic_conf |= IC_CONF_PRPVF_ROT_EN; + break; + case CSI_PRP_ENC_MEM: + case MEM_PRP_ENC_MEM: + ic_conf |= IC_CONF_PRPENC_EN; + break; + case MEM_ROT_ENC_MEM: + ic_conf |= IC_CONF_PRPENC_ROT_EN; + break; + case MEM_PP_MEM: + ic_conf |= IC_CONF_PP_EN; + break; + case MEM_ROT_PP_MEM: + ic_conf |= IC_CONF_PP_ROT_EN; + break; + default: + break; + } + __raw_writel(ic_conf, IC_CONF); +} + +void _ipu_ic_disable_task(ipu_channel_t channel) +{ + uint32_t ic_conf; + + ic_conf = __raw_readl(IC_CONF); + switch (channel) { + case CSI_PRP_VF_MEM: + case MEM_PRP_VF_MEM: + ic_conf &= ~IC_CONF_PRPVF_EN; + break; + case MEM_ROT_VF_MEM: + ic_conf &= ~IC_CONF_PRPVF_ROT_EN; + break; + case CSI_PRP_ENC_MEM: + case MEM_PRP_ENC_MEM: + ic_conf &= ~IC_CONF_PRPENC_EN; + break; + case MEM_ROT_ENC_MEM: + ic_conf &= ~IC_CONF_PRPENC_ROT_EN; + break; + case MEM_PP_MEM: + ic_conf &= ~IC_CONF_PP_EN; + break; + case MEM_ROT_PP_MEM: + ic_conf &= ~IC_CONF_PP_ROT_EN; + break; + default: + break; + } + __raw_writel(ic_conf, IC_CONF); +} + +void _ipu_ic_init_prpvf(ipu_channel_params_t *params, bool src_is_csi) +{ + uint32_t reg, ic_conf; + uint32_t downsizeCoeff, resizeCoeff; + ipu_color_space_t in_fmt, out_fmt; + + /* Setup vertical resizing */ + _calc_resize_coeffs(params->mem_prp_vf_mem.in_height, + params->mem_prp_vf_mem.out_height, + &resizeCoeff, &downsizeCoeff); + reg = (downsizeCoeff << 30) | (resizeCoeff << 16); + + /* Setup horizontal resizing */ + _calc_resize_coeffs(params->mem_prp_vf_mem.in_width, + params->mem_prp_vf_mem.out_width, + &resizeCoeff, &downsizeCoeff); + reg |= (downsizeCoeff << 14) | resizeCoeff; + + __raw_writel(reg, IC_PRP_VF_RSC); + + ic_conf = __raw_readl(IC_CONF); + + /* Setup color space conversion */ + in_fmt = format_to_colorspace(params->mem_prp_vf_mem.in_pixel_fmt); + out_fmt = format_to_colorspace(params->mem_prp_vf_mem.out_pixel_fmt); + if (in_fmt == RGB) { + if ((out_fmt == YCbCr) || (out_fmt == YUV)) { + /* Enable RGB->YCBCR CSC */ + _init_csc(IC_TASK_VIEWFINDER, RGB, out_fmt); + ic_conf |= IC_CONF_PRPVF_CSC1; + } + } + if ((in_fmt == YCbCr) || (in_fmt == YUV)) { + if (out_fmt == RGB) { + /* Enable YCBCR->RGB CSC */ + _init_csc(IC_TASK_VIEWFINDER, YCbCr, RGB); + ic_conf |= IC_CONF_PRPVF_CSC1; + } else { + /* TODO: Support YUV<->YCbCr conversion? */ + } + } + + if (params->mem_prp_vf_mem.graphics_combine_en) { + ic_conf |= IC_CONF_PRPVF_CMB; + + /* need transparent CSC1 conversion */ + _init_csc(IC_TASK_POST_PROCESSOR, RGB, RGB); + ic_conf |= IC_CONF_PRPVF_CSC1; /* Enable RGB->RGB CSC */ + + if (params->mem_prp_vf_mem.global_alpha_en) + ic_conf |= IC_CONF_IC_GLB_LOC_A; + else + ic_conf &= ~IC_CONF_IC_GLB_LOC_A; + + if (params->mem_prp_vf_mem.key_color_en) + ic_conf |= IC_CONF_KEY_COLOR_EN; + else + ic_conf &= ~IC_CONF_KEY_COLOR_EN; + } else { + ic_conf &= ~IC_CONF_PRPVF_CMB; + } + + if (src_is_csi) + ic_conf &= ~IC_CONF_RWS_EN; + else + ic_conf |= IC_CONF_RWS_EN; + + __raw_writel(ic_conf, IC_CONF); +} + +void _ipu_ic_uninit_prpvf(void) +{ + uint32_t reg; + + reg = __raw_readl(IC_CONF); + reg &= ~(IC_CONF_PRPVF_EN | IC_CONF_PRPVF_CMB | + IC_CONF_PRPVF_CSC2 | IC_CONF_PRPVF_CSC1); + __raw_writel(reg, IC_CONF); +} + +void _ipu_ic_init_rotate_vf(ipu_channel_params_t *params) +{ +} + +void _ipu_ic_uninit_rotate_vf(void) +{ + uint32_t reg; + reg = __raw_readl(IC_CONF); + reg &= ~IC_CONF_PRPVF_ROT_EN; + __raw_writel(reg, IC_CONF); +} + +void _ipu_ic_init_prpenc(ipu_channel_params_t *params, bool src_is_csi) +{ + uint32_t reg, ic_conf; + uint32_t downsizeCoeff, resizeCoeff; + ipu_color_space_t in_fmt, out_fmt; + + /* Setup vertical resizing */ + _calc_resize_coeffs(params->mem_prp_enc_mem.in_height, + params->mem_prp_enc_mem.out_height, + &resizeCoeff, &downsizeCoeff); + reg = (downsizeCoeff << 30) | (resizeCoeff << 16); + + /* Setup horizontal resizing */ + _calc_resize_coeffs(params->mem_prp_enc_mem.in_width, + params->mem_prp_enc_mem.out_width, + &resizeCoeff, &downsizeCoeff); + reg |= (downsizeCoeff << 14) | resizeCoeff; + + __raw_writel(reg, IC_PRP_ENC_RSC); + + ic_conf = __raw_readl(IC_CONF); + + /* Setup color space conversion */ + in_fmt = format_to_colorspace(params->mem_prp_enc_mem.in_pixel_fmt); + out_fmt = format_to_colorspace(params->mem_prp_enc_mem.out_pixel_fmt); + if (in_fmt == RGB) { + if ((out_fmt == YCbCr) || (out_fmt == YUV)) { + /* Enable RGB->YCBCR CSC */ + _init_csc(IC_TASK_ENCODER, RGB, out_fmt); + ic_conf |= IC_CONF_PRPENC_CSC1; + } + } + if ((in_fmt == YCbCr) || (in_fmt == YUV)) { + if (out_fmt == RGB) { + /* Enable YCBCR->RGB CSC */ + _init_csc(IC_TASK_ENCODER, YCbCr, RGB); + ic_conf |= IC_CONF_PRPENC_CSC1; + } else { + /* TODO: Support YUV<->YCbCr conversion? */ + } + } + + if (src_is_csi) + ic_conf &= ~IC_CONF_RWS_EN; + else + ic_conf |= IC_CONF_RWS_EN; + + __raw_writel(ic_conf, IC_CONF); +} + +void _ipu_ic_uninit_prpenc(void) +{ + uint32_t reg; + + reg = __raw_readl(IC_CONF); + reg &= ~(IC_CONF_PRPENC_EN | IC_CONF_PRPENC_CSC1); + __raw_writel(reg, IC_CONF); +} + +void _ipu_ic_init_rotate_enc(ipu_channel_params_t *params) +{ +} + +void _ipu_ic_uninit_rotate_enc(void) +{ + uint32_t reg; + + reg = __raw_readl(IC_CONF); + reg &= ~(IC_CONF_PRPENC_ROT_EN); + __raw_writel(reg, IC_CONF); +} + +void _ipu_ic_init_pp(ipu_channel_params_t *params) +{ + uint32_t reg, ic_conf; + uint32_t downsizeCoeff, resizeCoeff; + ipu_color_space_t in_fmt, out_fmt; + + /* Setup vertical resizing */ + _calc_resize_coeffs(params->mem_pp_mem.in_height, + params->mem_pp_mem.out_height, + &resizeCoeff, &downsizeCoeff); + reg = (downsizeCoeff << 30) | (resizeCoeff << 16); + + /* Setup horizontal resizing */ + _calc_resize_coeffs(params->mem_pp_mem.in_width, + params->mem_pp_mem.out_width, + &resizeCoeff, &downsizeCoeff); + reg |= (downsizeCoeff << 14) | resizeCoeff; + + __raw_writel(reg, IC_PP_RSC); + + ic_conf = __raw_readl(IC_CONF); + + /* Setup color space conversion */ + in_fmt = format_to_colorspace(params->mem_pp_mem.in_pixel_fmt); + out_fmt = format_to_colorspace(params->mem_pp_mem.out_pixel_fmt); + if (in_fmt == RGB) { + if ((out_fmt == YCbCr) || (out_fmt == YUV)) { + /* Enable RGB->YCBCR CSC */ + _init_csc(IC_TASK_POST_PROCESSOR, RGB, out_fmt); + ic_conf |= IC_CONF_PP_CSC2; + } + } + if ((in_fmt == YCbCr) || (in_fmt == YUV)) { + if (out_fmt == RGB) { + /* Enable YCBCR->RGB CSC */ + _init_csc(IC_TASK_POST_PROCESSOR, YCbCr, RGB); + ic_conf |= IC_CONF_PP_CSC1; + } else { + /* TODO: Support YUV<->YCbCr conversion? */ + } + } + + if (params->mem_pp_mem.graphics_combine_en) { + ic_conf |= IC_CONF_PP_CMB; + + /* need transparent CSC1 conversion */ + _init_csc(IC_TASK_POST_PROCESSOR, RGB, RGB); + ic_conf |= IC_CONF_PP_CSC1; /* Enable RGB->RGB CSC */ + + if (params->mem_pp_mem.global_alpha_en) + ic_conf |= IC_CONF_IC_GLB_LOC_A; + else + ic_conf &= ~IC_CONF_IC_GLB_LOC_A; + + if (params->mem_pp_mem.key_color_en) + ic_conf |= IC_CONF_KEY_COLOR_EN; + else + ic_conf &= ~IC_CONF_KEY_COLOR_EN; + } else { + ic_conf &= ~IC_CONF_PP_CMB; + } + + __raw_writel(ic_conf, IC_CONF); +} + +void _ipu_ic_uninit_pp(void) +{ + uint32_t reg; + + reg = __raw_readl(IC_CONF); + reg &= ~(IC_CONF_PP_EN | IC_CONF_PP_CSC1 | IC_CONF_PP_CSC2 | + IC_CONF_PP_CMB); + __raw_writel(reg, IC_CONF); +} + +void _ipu_ic_init_rotate_pp(ipu_channel_params_t *params) +{ +} + +void _ipu_ic_uninit_rotate_pp(void) +{ + uint32_t reg; + reg = __raw_readl(IC_CONF); + reg &= ~IC_CONF_PP_ROT_EN; + __raw_writel(reg, IC_CONF); +} + +int _ipu_ic_idma_init(int dma_chan, uint16_t width, uint16_t height, + int burst_size, ipu_rotate_mode_t rot) +{ + u32 ic_idmac_1, ic_idmac_2, ic_idmac_3; + u32 temp_rot = bitrev8(rot) >> 5; + bool need_hor_flip = false; + + if ((burst_size != 8) && (burst_size != 16)) { + dev_dbg(g_ipu_dev, "Illegal burst length for IC\n"); + return -EINVAL; + } + + width--; + height--; + + if (temp_rot & 0x2) /* Need horizontal flip */ + need_hor_flip = true; + + ic_idmac_1 = __raw_readl(IC_IDMAC_1); + ic_idmac_2 = __raw_readl(IC_IDMAC_2); + ic_idmac_3 = __raw_readl(IC_IDMAC_3); + if (dma_chan == 22) { /* PP output - CB2 */ + if (burst_size == 16) + ic_idmac_1 |= IC_IDMAC_1_CB2_BURST_16; + else + ic_idmac_1 &= ~IC_IDMAC_1_CB2_BURST_16; + + if (need_hor_flip) + ic_idmac_1 |= IC_IDMAC_1_PP_FLIP_RS; + else + ic_idmac_1 &= ~IC_IDMAC_1_PP_FLIP_RS; + + ic_idmac_2 &= ~IC_IDMAC_2_PP_HEIGHT_MASK; + ic_idmac_2 |= height << IC_IDMAC_2_PP_HEIGHT_OFFSET; + + ic_idmac_3 &= ~IC_IDMAC_3_PP_WIDTH_MASK; + ic_idmac_3 |= width << IC_IDMAC_3_PP_WIDTH_OFFSET; + + } else if (dma_chan == 11) { /* PP Input - CB5 */ + if (burst_size == 16) + ic_idmac_1 |= IC_IDMAC_1_CB5_BURST_16; + else + ic_idmac_1 &= ~IC_IDMAC_1_CB5_BURST_16; + } else if (dma_chan == 47) { /* PP Rot input */ + ic_idmac_1 &= ~IC_IDMAC_1_PP_ROT_MASK; + ic_idmac_1 |= temp_rot << IC_IDMAC_1_PP_ROT_OFFSET; + } + + if (dma_chan == 12) { /* PRP Input - CB6 */ + if (burst_size == 16) + ic_idmac_1 |= IC_IDMAC_1_CB6_BURST_16; + else + ic_idmac_1 &= ~IC_IDMAC_1_CB6_BURST_16; + } + + if (dma_chan == 20) { /* PRP ENC output - CB0 */ + if (burst_size == 16) + ic_idmac_1 |= IC_IDMAC_1_CB0_BURST_16; + else + ic_idmac_1 &= ~IC_IDMAC_1_CB0_BURST_16; + + if (need_hor_flip) + ic_idmac_1 |= IC_IDMAC_1_PRPENC_FLIP_RS; + else + ic_idmac_1 &= ~IC_IDMAC_1_PRPENC_FLIP_RS; + + ic_idmac_2 &= ~IC_IDMAC_2_PRPENC_HEIGHT_MASK; + ic_idmac_2 |= height << IC_IDMAC_2_PRPENC_HEIGHT_OFFSET; + + ic_idmac_3 &= ~IC_IDMAC_3_PRPENC_WIDTH_MASK; + ic_idmac_3 |= width << IC_IDMAC_3_PRPENC_WIDTH_OFFSET; + + } else if (dma_chan == 45) { /* PRP ENC Rot input */ + ic_idmac_1 &= ~IC_IDMAC_1_PRPENC_ROT_MASK; + ic_idmac_1 |= temp_rot << IC_IDMAC_1_PRPENC_ROT_OFFSET; + } + + if (dma_chan == 21) { /* PRP VF output - CB1 */ + if (burst_size == 16) + ic_idmac_1 |= IC_IDMAC_1_CB1_BURST_16; + else + ic_idmac_1 &= ~IC_IDMAC_1_CB1_BURST_16; + + if (need_hor_flip) + ic_idmac_1 |= IC_IDMAC_1_PRPVF_FLIP_RS; + else + ic_idmac_1 &= ~IC_IDMAC_1_PRPVF_FLIP_RS; + + ic_idmac_2 &= ~IC_IDMAC_2_PRPVF_HEIGHT_MASK; + ic_idmac_2 |= height << IC_IDMAC_2_PRPVF_HEIGHT_OFFSET; + + ic_idmac_3 &= ~IC_IDMAC_3_PRPVF_WIDTH_MASK; + ic_idmac_3 |= width << IC_IDMAC_3_PRPVF_WIDTH_OFFSET; + + } else if (dma_chan == 46) { /* PRP VF Rot input */ + ic_idmac_1 &= ~IC_IDMAC_1_PRPVF_ROT_MASK; + ic_idmac_1 |= temp_rot << IC_IDMAC_1_PRPVF_ROT_OFFSET; + } + __raw_writel(ic_idmac_1, IC_IDMAC_1); + __raw_writel(ic_idmac_2, IC_IDMAC_2); + __raw_writel(ic_idmac_3, IC_IDMAC_3); + + return 0; +} + +static void _init_csc(uint8_t ic_task, ipu_color_space_t in_format, + ipu_color_space_t out_format) +{ + +/* Y = R * .299 + G * .587 + B * .114; + U = R * -.169 + G * -.332 + B * .500 + 128.; + V = R * .500 + G * -.419 + B * -.0813 + 128.;*/ + static const uint32_t rgb2ycbcr_coeff[4][3] = { + {0x004D, 0x0096, 0x001D}, + {0x01D5, 0x01AB, 0x0080}, + {0x0080, 0x0195, 0x01EB}, + {0x0000, 0x0200, 0x0200}, /* A0, A1, A2 */ + }; + + /* transparent RGB->RGB matrix for combining + */ + static const uint32_t rgb2rgb_coeff[4][3] = { + {0x0080, 0x0000, 0x0000}, + {0x0000, 0x0080, 0x0000}, + {0x0000, 0x0000, 0x0080}, + {0x0000, 0x0000, 0x0000}, /* A0, A1, A2 */ + }; + +/* R = (1.164 * (Y - 16)) + (1.596 * (Cr - 128)); + G = (1.164 * (Y - 16)) - (0.392 * (Cb - 128)) - (0.813 * (Cr - 128)); + B = (1.164 * (Y - 16)) + (2.017 * (Cb - 128); */ + static const uint32_t ycbcr2rgb_coeff[4][3] = { + {149, 0, 204}, + {149, 462, 408}, + {149, 255, 0}, + {8192 - 446, 266, 8192 - 554}, /* A0, A1, A2 */ + }; + + uint32_t param; + uint32_t *base = NULL; + + if (ic_task == IC_TASK_ENCODER) { + base = ipu_tpmem_base + 0x2008 / 4; + } else if (ic_task == IC_TASK_VIEWFINDER) { + base = ipu_tpmem_base + 0x4028 / 4; + } else if (ic_task == IC_TASK_POST_PROCESSOR) { + base = ipu_tpmem_base + 0x6060 / 4; + } else { + BUG(); + } + + if ((in_format == YCbCr) && (out_format == RGB)) { + /* Init CSC1 (YCbCr->RGB) */ + param = (ycbcr2rgb_coeff[3][0] << 27) | + (ycbcr2rgb_coeff[0][0] << 18) | + (ycbcr2rgb_coeff[1][1] << 9) | ycbcr2rgb_coeff[2][2]; + __raw_writel(param, base++); + /* scale = 2, sat = 0 */ + param = (ycbcr2rgb_coeff[3][0] >> 5) | (2L << (40 - 32)); + __raw_writel(param, base++); + + param = (ycbcr2rgb_coeff[3][1] << 27) | + (ycbcr2rgb_coeff[0][1] << 18) | + (ycbcr2rgb_coeff[1][0] << 9) | ycbcr2rgb_coeff[2][0]; + __raw_writel(param, base++); + param = (ycbcr2rgb_coeff[3][1] >> 5); + __raw_writel(param, base++); + + param = (ycbcr2rgb_coeff[3][2] << 27) | + (ycbcr2rgb_coeff[0][2] << 18) | + (ycbcr2rgb_coeff[1][2] << 9) | ycbcr2rgb_coeff[2][1]; + __raw_writel(param, base++); + param = (ycbcr2rgb_coeff[3][2] >> 5); + __raw_writel(param, base++); + } else if ((in_format == RGB) && (out_format == YCbCr)) { + /* Init CSC1 (RGB->YCbCr) */ + param = (rgb2ycbcr_coeff[3][0] << 27) | + (rgb2ycbcr_coeff[0][0] << 18) | + (rgb2ycbcr_coeff[1][1] << 9) | rgb2ycbcr_coeff[2][2]; + __raw_writel(param, base++); + /* scale = 1, sat = 0 */ + param = (rgb2ycbcr_coeff[3][0] >> 5) | (1UL << 8); + __raw_writel(param, base++); + + param = (rgb2ycbcr_coeff[3][1] << 27) | + (rgb2ycbcr_coeff[0][1] << 18) | + (rgb2ycbcr_coeff[1][0] << 9) | rgb2ycbcr_coeff[2][0]; + __raw_writel(param, base++); + param = (rgb2ycbcr_coeff[3][1] >> 5); + __raw_writel(param, base++); + + param = (rgb2ycbcr_coeff[3][2] << 27) | + (rgb2ycbcr_coeff[0][2] << 18) | + (rgb2ycbcr_coeff[1][2] << 9) | rgb2ycbcr_coeff[2][1]; + __raw_writel(param, base++); + param = (rgb2ycbcr_coeff[3][2] >> 5); + __raw_writel(param, base++); + } else if ((in_format == RGB) && (out_format == RGB)) { + /* Init CSC1 */ + param = + (rgb2rgb_coeff[3][0] << 27) | (rgb2rgb_coeff[0][0] << 18) | + (rgb2rgb_coeff[1][1] << 9) | rgb2rgb_coeff[2][2]; + __raw_writel(param, base++); + /* scale = 2, sat = 0 */ + param = (rgb2rgb_coeff[3][0] >> 5) | (2UL << 8); + __raw_writel(param, base++); + + param = + (rgb2rgb_coeff[3][1] << 27) | (rgb2rgb_coeff[0][1] << 18) | + (rgb2rgb_coeff[1][0] << 9) | rgb2rgb_coeff[2][0]; + __raw_writel(param, base++); + param = (rgb2rgb_coeff[3][1] >> 5); + __raw_writel(param, base++); + + param = + (rgb2rgb_coeff[3][2] << 27) | (rgb2rgb_coeff[0][2] << 18) | + (rgb2rgb_coeff[1][2] << 9) | rgb2rgb_coeff[2][1]; + __raw_writel(param, base++); + param = (rgb2rgb_coeff[3][2] >> 5); + __raw_writel(param, base++); + } else { + dev_err(g_ipu_dev, "Unsupported color space conversion\n"); + } +} + +static bool _calc_resize_coeffs(uint32_t inSize, uint32_t outSize, + uint32_t *resizeCoeff, + uint32_t *downsizeCoeff) +{ + uint32_t tempSize; + uint32_t tempDownsize; + + /* Cannot downsize more than 8:1 */ + if ((outSize << 3) < inSize) + return false; + + /* compute downsizing coefficient */ + tempDownsize = 0; + tempSize = inSize; + while ((tempSize >= outSize * 2) && (tempDownsize < 2)) { + tempSize >>= 1; + tempDownsize++; + } + *downsizeCoeff = tempDownsize; + + /* compute resizing coefficient using the following equation: + resizeCoeff = M*(SI -1)/(SO - 1) + where M = 2^13, SI - input size, SO - output size */ + *resizeCoeff = (8192L * (tempSize - 1)) / (outSize - 1); + if (*resizeCoeff >= 16384L) { + dev_err(g_ipu_dev, "Warning! Overflow on resize coeff.\n"); + *resizeCoeff = 0x3FFF; + } + + dev_dbg(g_ipu_dev, "resizing from %u -> %u pixels, " + "downsize=%u, resize=%u.%lu (reg=%u)\n", inSize, outSize, + *downsizeCoeff, (*resizeCoeff >= 8192L) ? 1 : 0, + ((*resizeCoeff & 0x1FFF) * 10000L) / 8192L, *resizeCoeff); + + return true; +} --- linux-2.6.28.orig/drivers/mxc/ipu3/ipu_regs.h +++ linux-2.6.28/drivers/mxc/ipu3/ipu_regs.h @@ -0,0 +1,625 @@ +/* + * Copyright 2005-2009 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 + */ + +/* + * @file ipu_regs.h + * + * @brief IPU Register definitions + * + * @ingroup IPU + */ +#ifndef __IPU_REGS_INCLUDED__ +#define __IPU_REGS_INCLUDED__ + +#define IPU_DISP0_BASE 0x00000000 +#define IPU_MCU_T_DEFAULT 8 +#define IPU_DISP1_BASE (IPU_MCU_T_DEFAULT << 25) +#define IPU_CM_REG_BASE 0x1E000000 +#define IPU_IDMAC_REG_BASE 0x1E008000 +#define IPU_ISP_REG_BASE 0x1E010000 +#define IPU_DP_REG_BASE 0x1E018000 +#define IPU_IC_REG_BASE 0x1E020000 +#define IPU_IRT_REG_BASE 0x1E028000 +#define IPU_CSI0_REG_BASE 0x1E030000 +#define IPU_CSI1_REG_BASE 0x1E038000 +#define IPU_DI0_REG_BASE 0x1E040000 +#define IPU_DI1_REG_BASE 0x1E048000 +#define IPU_SMFC_REG_BASE 0x1E050000 +#define IPU_DC_REG_BASE 0x1E058000 +#define IPU_DMFC_REG_BASE 0x1E060000 +#define IPU_CPMEM_REG_BASE 0x1F000000 +#define IPU_LUT_REG_BASE 0x1F020000 +#define IPU_SRM_REG_BASE 0x1F040000 +#define IPU_TPM_REG_BASE 0x1F060000 +#define IPU_DC_TMPL_REG_BASE 0x1F080000 +#define IPU_ISP_TBPR_REG_BASE 0x1F0C0000 + +extern u32 *ipu_cm_reg; +extern u32 *ipu_idmac_reg; +extern u32 *ipu_dp_reg; +extern u32 *ipu_ic_reg; +extern u32 *ipu_dc_reg; +extern u32 *ipu_dc_tmpl_reg; +extern u32 *ipu_dmfc_reg; +extern u32 *ipu_di_reg[]; +extern u32 *ipu_smfc_reg; +extern u32 *ipu_csi_reg[]; +extern u32 *ipu_tpmem_base; +extern u32 *ipu_disp_base[]; + +/* Register addresses */ +/* IPU Common registers */ +#define IPU_CONF (ipu_cm_reg) + +#define IPU_SRM_PRI1 (ipu_cm_reg + 0x00A0/4) +#define IPU_SRM_PRI2 (ipu_cm_reg + 0x00A4/4) +#define IPU_FS_PROC_FLOW1 (ipu_cm_reg + 0x00A8/4) +#define IPU_FS_PROC_FLOW2 (ipu_cm_reg + 0x00AC/4) +#define IPU_FS_PROC_FLOW3 (ipu_cm_reg + 0x00B0/4) +#define IPU_FS_DISP_FLOW1 (ipu_cm_reg + 0x00B4/4) +#define IPU_FS_DISP_FLOW2 (ipu_cm_reg + 0x00B8/4) +#define IPU_SKIP (ipu_cm_reg + 0x00BC/4) +#define IPU_DISP_ALT_CONF (ipu_cm_reg + 0x00C0/4) +#define IPU_DISP_GEN (ipu_cm_reg + 0x00C4/4) +#define IPU_DISP_ALT1 (ipu_cm_reg + 0x00C8/4) +#define IPU_DISP_ALT2 (ipu_cm_reg + 0x00CC/4) +#define IPU_DISP_ALT3 (ipu_cm_reg + 0x00D0/4) +#define IPU_DISP_ALT4 (ipu_cm_reg + 0x00D4/4) +#define IPU_SNOOP (ipu_cm_reg + 0x00D8/4) +#define IPU_MEM_RST (ipu_cm_reg + 0x00DC/4) +#define IPU_PM (ipu_cm_reg + 0x00E0/4) +#define IPU_GPR (ipu_cm_reg + 0x00E4/4) +#define IPU_CHA_DB_MODE_SEL(ch) (ipu_cm_reg + 0x0150/4 + (ch / 32)) +#define IPU_ALT_CHA_DB_MODE_SEL(ch) (ipu_cm_reg + 0x0168/4 + (ch / 32)) +#define IPU_CHA_CUR_BUF(ch) ({g_ipu_hw_rev == 2 ? \ + (ipu_cm_reg + 0x023C/4 + (ch / 32)) : \ + (ipu_cm_reg + 0x0124/4 + (ch / 32)); }) +#define IPU_ALT_CUR_BUF0 ({g_ipu_hw_rev == 2 ? \ + (ipu_cm_reg + 0x0244/4) : \ + (ipu_cm_reg + 0x012C/4); }) +#define IPU_ALT_CUR_BUF1 ({g_ipu_hw_rev == 2 ? \ + (ipu_cm_reg + 0x0248/4) : \ + (ipu_cm_reg + 0x0130/4); }) +#define IPU_SRM_STAT ({g_ipu_hw_rev == 2 ? \ + (ipu_cm_reg + 0x024C/4) : \ + (ipu_cm_reg + 0x0134/4); }) +#define IPU_PROC_TASK_STAT ({g_ipu_hw_rev == 2 ? \ + (ipu_cm_reg + 0x0250/4) : \ + (ipu_cm_reg + 0x0138/4); }) +#define IPU_DISP_TASK_STAT ({g_ipu_hw_rev == 2 ? \ + (ipu_cm_reg + 0x0254/4) : \ + (ipu_cm_reg + 0x013C/4); }) +#define IPU_CHA_BUF0_RDY(ch) ({g_ipu_hw_rev == 2 ? \ + (ipu_cm_reg + 0x0268/4 + (ch / 32)) : \ + (ipu_cm_reg + 0x0140/4 + (ch / 32)); }) +#define IPU_CHA_BUF1_RDY(ch) ({g_ipu_hw_rev == 2 ? \ + (ipu_cm_reg + 0x0270/4 + (ch / 32)) : \ + (ipu_cm_reg + 0x0148/4 + (ch / 32)); }) +#define IPU_ALT_CHA_BUF0_RDY(ch) ({g_ipu_hw_rev == 2 ? \ + (ipu_cm_reg + 0x0278/4 + (ch / 32)) : \ + (ipu_cm_reg + 0x0158/4 + (ch / 32)); }) +#define IPU_ALT_CHA_BUF1_RDY(ch) ({g_ipu_hw_rev == 2 ? \ + (ipu_cm_reg + 0x0280/4 + (ch / 32)) : \ + (ipu_cm_reg + 0x0160/4 + (ch / 32)); }) + +#define IPU_INT_CTRL(n) (ipu_cm_reg + 0x003C/4 + ((n) - 1)) +#define IPU_INT_CTRL_IRQ(irq) IPU_INT_CTRL(((irq) / 32)) +#define IPU_INT_STAT_IRQ(irq) IPU_INT_STAT(((irq) / 32)) +#define IPU_INT_STAT(n) ({g_ipu_hw_rev == 2 ? \ + (ipu_cm_reg + 0x0200/4 + ((n) - 1)) : \ + (ipu_cm_reg + 0x00E8/4 + ((n) - 1)); }) + +#define IPUIRQ_2_STATREG(irq) (IPU_INT_STAT(1) + ((irq) / 32)) +#define IPUIRQ_2_CTRLREG(irq) (IPU_INT_CTRL(1) + ((irq) / 32)) +#define IPUIRQ_2_MASK(irq) (1UL << ((irq) & 0x1F)) + +/* CMOS Sensor Interface Registers */ +#define CSI_SENS_CONF(csi) (ipu_csi_reg[csi]) +#define CSI_SENS_FRM_SIZE(csi) (ipu_csi_reg[csi] + 0x0004/4) +#define CSI_ACT_FRM_SIZE(csi) (ipu_csi_reg[csi] + 0x0008/4) +#define CSI_OUT_FRM_CTRL(csi) (ipu_csi_reg[csi] + 0x000C/4) +#define CSI_TST_CTRL(csi) (ipu_csi_reg[csi] + 0x0010/4) +#define CSI_CCIR_CODE_1(csi) (ipu_csi_reg[csi] + 0x0014/4) +#define CSI_CCIR_CODE_2(csi) (ipu_csi_reg[csi] + 0x0018/4) +#define CSI_CCIR_CODE_3(csi) (ipu_csi_reg[csi] + 0x001C/4) +#define CSI_MIPI_DI(csi) (ipu_csi_reg[csi] + 0x0020/4) +#define CSI_SKIP(csi) (ipu_csi_reg[csi] + 0x0024/4) +#define CSI_CPD_CTRL(csi) (ipu_csi_reg[csi] + 0x0028/4) +#define CSI_CPD_RC(csi, n) (ipu_csi_reg[csi] + 0x002C/4 + n) +#define CSI_CPD_RS(csi, n) (ipu_csi_reg[csi] + 0x004C/4 + n) +#define CSI_CPD_GRC(csi, n) (ipu_csi_reg[csi] + 0x005C/4 + n) +#define CSI_CPD_GRS(csi, n) (ipu_csi_reg[csi] + 0x007C/4 + n) +#define CSI_CPD_GBC(csi, n) (ipu_csi_reg[csi] + 0x008C/4 + n) +#define CSI_CPD_GBS(csi, n) (ipu_csi_reg[csi] + 0x00AC/4 + n) +#define CSI_CPD_BC(csi, n) (ipu_csi_reg[csi] + 0x00BC/4 + n) +#define CSI_CPD_BS(csi, n) (ipu_csi_reg[csi] + 0x00DC/4 + n) +#define CSI_CPD_OFFSET1(csi) (ipu_csi_reg[csi] + 0x00EC/4) +#define CSI_CPD_OFFSET2(csi) (ipu_csi_reg[csi] + 0x00F0/4) + +/*SMFC Registers */ +#define SMFC_MAP (ipu_smfc_reg) +#define SMFC_WMC (ipu_smfc_reg + 0x0004/4) +#define SMFC_BS (ipu_smfc_reg + 0x0008/4) + +/* Image Converter Registers */ +#define IC_CONF (ipu_ic_reg) +#define IC_PRP_ENC_RSC (ipu_ic_reg + 0x0004/4) +#define IC_PRP_VF_RSC (ipu_ic_reg + 0x0008/4) +#define IC_PP_RSC (ipu_ic_reg + 0x000C/4) +#define IC_CMBP_1 (ipu_ic_reg + 0x0010/4) +#define IC_CMBP_2 (ipu_ic_reg + 0x0014/4) +#define IC_IDMAC_1 (ipu_ic_reg + 0x0018/4) +#define IC_IDMAC_2 (ipu_ic_reg + 0x001C/4) +#define IC_IDMAC_3 (ipu_ic_reg + 0x0020/4) +#define IC_IDMAC_4 (ipu_ic_reg + 0x0024/4) + +#define IDMAC_CONF (ipu_idmac_reg + 0x0000) +#define IDMAC_CHA_EN(ch) (ipu_idmac_reg + 0x0004/4 + (ch/32)) +#define IDMAC_SEP_ALPHA (ipu_idmac_reg + 0x000C/4) +#define IDMAC_ALT_SEP_ALPHA (ipu_idmac_reg + 0x0010/4) +#define IDMAC_CHA_PRI(ch) (ipu_idmac_reg + 0x0014/4 + (ch/32)) +#define IDMAC_WM_EN(ch) (ipu_idmac_reg + 0x001C/4 + (ch/32)) +#define IDMAC_CH_LOCK_EN_1 ({g_ipu_hw_rev == 2 ? \ + (ipu_idmac_reg + 0x0024/4) : 0; }) +#define IDMAC_CH_LOCK_EN_2 ({g_ipu_hw_rev == 2 ? \ + (ipu_idmac_reg + 0x0028/4) : \ + (ipu_idmac_reg + 0x0024/4); }) +#define IDMAC_SUB_ADDR_0 ({g_ipu_hw_rev == 2 ? \ + (ipu_idmac_reg + 0x002C/4) : \ + (ipu_idmac_reg + 0x0028/4); }) +#define IDMAC_SUB_ADDR_1 ({g_ipu_hw_rev == 2 ? \ + (ipu_idmac_reg + 0x0030/4) : \ + (ipu_idmac_reg + 0x002C/4); }) +#define IDMAC_SUB_ADDR_2 ({g_ipu_hw_rev == 2 ? \ + (ipu_idmac_reg + 0x0034/4) : \ + (ipu_idmac_reg + 0x0030/4); }) +#define IDMAC_BAND_EN(ch) ({g_ipu_hw_rev == 2 ? \ + (ipu_idmac_reg + 0x0040/4 + (ch/32)) : \ + (ipu_idmac_reg + 0x0034/4 + (ch/32)); }) +#define IDMAC_CHA_BUSY(ch) ({g_ipu_hw_rev == 2 ? \ + (ipu_idmac_reg + 0x0100/4 + (ch/32)) : \ + (ipu_idmac_reg + 0x0040/4 + (ch/32)); }) + +#define DI_GENERAL(di) (ipu_di_reg[di]) +#define DI_BS_CLKGEN0(di) (ipu_di_reg[di] + 0x0004/4) +#define DI_BS_CLKGEN1(di) (ipu_di_reg[di] + 0x0008/4) + +#define DI_SW_GEN0(di, gen) (ipu_di_reg[di] + 0x000C/4 + (gen - 1)) +#define DI_SW_GEN1(di, gen) (ipu_di_reg[di] + 0x0030/4 + (gen - 1)) +#define DI_STP_REP(di, gen) (ipu_di_reg[di] + 0x0148/4 + (gen - 1)/2) +#define DI_SYNC_AS_GEN(di) (ipu_di_reg[di] + 0x0054/4) +#define DI_DW_GEN(di, gen) (ipu_di_reg[di] + 0x0058/4 + gen) +#define DI_DW_SET(di, gen, set) (ipu_di_reg[di] + 0x0088/4 + gen + 0xC*set) +#define DI_SER_CONF(di) (ipu_di_reg[di] + 0x015C/4) +#define DI_SSC(di) (ipu_di_reg[di] + 0x0160/4) +#define DI_POL(di) (ipu_di_reg[di] + 0x0164/4) +#define DI_AW0(di) (ipu_di_reg[di] + 0x0168/4) +#define DI_AW1(di) (ipu_di_reg[di] + 0x016C/4) +#define DI_SCR_CONF(di) (ipu_di_reg[di] + 0x0170/4) +#define DI_STAT(di) (ipu_di_reg[di] + 0x0174/4) + +#define DMFC_RD_CHAN (ipu_dmfc_reg) +#define DMFC_WR_CHAN (ipu_dmfc_reg + 0x0004/4) +#define DMFC_WR_CHAN_DEF (ipu_dmfc_reg + 0x0008/4) +#define DMFC_DP_CHAN (ipu_dmfc_reg + 0x000C/4) +#define DMFC_DP_CHAN_DEF (ipu_dmfc_reg + 0x0010/4) +#define DMFC_GENERAL1 (ipu_dmfc_reg + 0x0014/4) +#define DMFC_GENERAL2 (ipu_dmfc_reg + 0x0018/4) +#define DMFC_IC_CTRL (ipu_dmfc_reg + 0x001C/4) + +#define DC_MAP_CONF_PTR(n) (ipu_dc_reg + 0x0108/4 + n/2) +#define DC_MAP_CONF_VAL(n) (ipu_dc_reg + 0x0144/4 + n/2) + +#define _RL_CH_2_OFFSET(ch) ((ch == 0) ? 8 : ( \ + (ch == 1) ? 0x24 : ( \ + (ch == 2) ? 0x40 : ( \ + (ch == 5) ? 0x64 : ( \ + (ch == 6) ? 0x80 : ( \ + (ch == 8) ? 0x9C : ( \ + (ch == 9) ? 0xBC : (-1)))))))) +#define DC_RL_CH(ch, evt) (ipu_dc_reg + _RL_CH_2_OFFSET(ch)/4 + evt/2) + +#define DC_EVT_NF 0 +#define DC_EVT_NL 1 +#define DC_EVT_EOF 2 +#define DC_EVT_NFIELD 3 +#define DC_EVT_EOL 4 +#define DC_EVT_EOFIELD 5 +#define DC_EVT_NEW_ADDR 6 +#define DC_EVT_NEW_CHAN 7 +#define DC_EVT_NEW_DATA 8 + +#define DC_EVT_NEW_ADDR_W_0 0 +#define DC_EVT_NEW_ADDR_W_1 1 +#define DC_EVT_NEW_CHAN_W_0 2 +#define DC_EVT_NEW_CHAN_W_1 3 +#define DC_EVT_NEW_DATA_W_0 4 +#define DC_EVT_NEW_DATA_W_1 5 +#define DC_EVT_NEW_ADDR_R_0 6 +#define DC_EVT_NEW_ADDR_R_1 7 +#define DC_EVT_NEW_CHAN_R_0 8 +#define DC_EVT_NEW_CHAN_R_1 9 +#define DC_EVT_NEW_DATA_R_0 10 +#define DC_EVT_NEW_DATA_R_1 11 + +#define dc_ch_offset(ch) \ +({ \ + const u8 _offset[] = { \ + 0, 0x1C, 0x38, 0x54, 0x58, 0x5C, 0x78, 0, 0x94, 0xB4}; \ + _offset[ch]; \ +}) +#define DC_WR_CH_CONF(ch) (ipu_dc_reg + dc_ch_offset(ch)/4) +#define DC_WR_CH_ADDR(ch) (ipu_dc_reg + dc_ch_offset(ch)/4 + 4/4) + +#define DC_WR_CH_CONF_1 (ipu_dc_reg + 0x001C/4) +#define DC_WR_CH_ADDR_1 (ipu_dc_reg + 0x0020/4) +#define DC_WR_CH_CONF_5 (ipu_dc_reg + 0x005C/4) +#define DC_WR_CH_ADDR_5 (ipu_dc_reg + 0x0060/4) +#define DC_GEN (ipu_dc_reg + 0x00D4/4) +#define DC_DISP_CONF1(disp) (ipu_dc_reg + 0x00D8/4 + disp) +#define DC_DISP_CONF2(disp) (ipu_dc_reg + 0x00E8/4 + disp) +#define DC_STAT (ipu_dc_reg + 0x01C8/4) +#define DC_UGDE_0(evt) (ipu_dc_reg + 0x0174/4 + evt*4) +#define DC_UGDE_1(evt) (ipu_dc_reg + 0x0178/4 + evt*4) +#define DC_UGDE_2(evt) (ipu_dc_reg + 0x017C/4 + evt*4) +#define DC_UGDE_3(evt) (ipu_dc_reg + 0x0180/4 + evt*4) + +#define DP_SYNC 0 +#define DP_ASYNC0 0x60 +#define DP_ASYNC1 0xBC +#define DP_COM_CONF(flow) (ipu_dp_reg + flow/4) +#define DP_GRAPH_WIND_CTRL(flow) (ipu_dp_reg + 0x0004/4 + flow/4) +#define DP_FG_POS(flow) (ipu_dp_reg + 0x0008/4 + flow/4) +#define DP_CSC_A_0(flow) (ipu_dp_reg + 0x0044/4 + flow/4) +#define DP_CSC_A_1(flow) (ipu_dp_reg + 0x0048/4 + flow/4) +#define DP_CSC_A_2(flow) (ipu_dp_reg + 0x004C/4 + flow/4) +#define DP_CSC_A_3(flow) (ipu_dp_reg + 0x0050/4 + flow/4) +#define DP_CSC_0(flow) (ipu_dp_reg + 0x0054/4 + flow/4) +#define DP_CSC_1(flow) (ipu_dp_reg + 0x0058/4 + flow/4) + +enum { + IPU_CONF_CSI0_EN = 0x00000001, + IPU_CONF_CSI1_EN = 0x00000002, + IPU_CONF_IC_EN = 0x00000004, + IPU_CONF_ROT_EN = 0x00000008, + IPU_CONF_ISP_EN = 0x00000010, + IPU_CONF_DP_EN = 0x00000020, + IPU_CONF_DI0_EN = 0x00000040, + IPU_CONF_DI1_EN = 0x00000080, + IPU_CONF_DMFC_EN = 0x00000400, + IPU_CONF_SMFC_EN = 0x00000100, + IPU_CONF_DC_EN = 0x00000200, + IPU_CONF_IDMAC_DIS = 0x00400000, + IPU_CONF_IC_DMFC_SEL = 0x02000000, + IPU_CONF_IC_DMFC_SYNC = 0x04000000, + IPU_CONF_VDI_DMFC_SYNC = 0x08000000, + IPU_CONF_CSI0_DATA_SOURCE = 0x10000000, + IPU_CONF_CSI0_DATA_SOURCE_OFFSET = 28, + IPU_CONF_CSI1_DATA_SOURCE = 0x20000000, + IPU_CONF_IC_INPUT = 0x40000000, + IPU_CONF_CSI_SEL = 0x80000000, + + DI0_COUNTER_RELEASE = 0x01000000, + DI1_COUNTER_RELEASE = 0x02000000, + + FS_PRPVF_ROT_SRC_SEL_MASK = 0x00000F00, + FS_PRPVF_ROT_SRC_SEL_OFFSET = 8, + FS_PRPENC_ROT_SRC_SEL_MASK = 0x0000000F, + FS_PRPENC_ROT_SRC_SEL_OFFSET = 0, + FS_PP_ROT_SRC_SEL_MASK = 0x000F0000, + FS_PP_ROT_SRC_SEL_OFFSET = 16, + FS_PP_SRC_SEL_MASK = 0x0000F000, + FS_PP_SRC_SEL_OFFSET = 12, + FS_PRP_SRC_SEL_MASK = 0x0F000000, + FS_PRP_SRC_SEL_OFFSET = 24, + FS_VF_IN_VALID = 0x80000000, + FS_ENC_IN_VALID = 0x40000000, + + FS_PRPENC_DEST_SEL_MASK = 0x0000000F, + FS_PRPENC_DEST_SEL_OFFSET = 0, + FS_PRPVF_DEST_SEL_MASK = 0x000000F0, + FS_PRPVF_DEST_SEL_OFFSET = 4, + FS_PRPVF_ROT_DEST_SEL_MASK = 0x00000F00, + FS_PRPVF_ROT_DEST_SEL_OFFSET = 8, + FS_PP_DEST_SEL_MASK = 0x0000F000, + FS_PP_DEST_SEL_OFFSET = 12, + FS_PP_ROT_DEST_SEL_MASK = 0x000F0000, + FS_PP_ROT_DEST_SEL_OFFSET = 16, + FS_PRPENC_ROT_DEST_SEL_MASK = 0x00F00000, + FS_PRPENC_ROT_DEST_SEL_OFFSET = 20, + + FS_SMFC0_DEST_SEL_MASK = 0x0000000F, + FS_SMFC0_DEST_SEL_OFFSET = 0, + FS_SMFC1_DEST_SEL_MASK = 0x00000070, + FS_SMFC1_DEST_SEL_OFFSET = 4, + FS_SMFC2_DEST_SEL_MASK = 0x00000780, + FS_SMFC2_DEST_SEL_OFFSET = 7, + FS_SMFC3_DEST_SEL_MASK = 0x00003800, + FS_SMFC3_DEST_SEL_OFFSET = 11, + + FS_DC1_SRC_SEL_MASK = 0x00F00000, + FS_DC1_SRC_SEL_OFFSET = 20, + FS_DC2_SRC_SEL_MASK = 0x000F0000, + FS_DC2_SRC_SEL_OFFSET = 16, + FS_DP_SYNC0_SRC_SEL_MASK = 0x0000000F, + FS_DP_SYNC0_SRC_SEL_OFFSET = 0, + FS_DP_SYNC1_SRC_SEL_MASK = 0x000000F0, + FS_DP_SYNC1_SRC_SEL_OFFSET = 4, + FS_DP_ASYNC0_SRC_SEL_MASK = 0x00000F00, + FS_DP_ASYNC0_SRC_SEL_OFFSET = 8, + FS_DP_ASYNC1_SRC_SEL_MASK = 0x0000F000, + FS_DP_ASYNC1_SRC_SEL_OFFSET = 12, + + FS_AUTO_REF_PER_MASK = 0, + FS_AUTO_REF_PER_OFFSET = 16, + + TSTAT_VF_MASK = 0x0000000C, + TSTAT_VF_OFFSET = 2, + TSTAT_VF_ROT_MASK = 0x00000300, + TSTAT_VF_ROT_OFFSET = 8, + TSTAT_ENC_MASK = 0x00000003, + TSTAT_ENC_OFFSET = 0, + TSTAT_ENC_ROT_MASK = 0x000000C0, + TSTAT_ENC_ROT_OFFSET = 6, + TSTAT_PP_MASK = 0x00000030, + TSTAT_PP_OFFSET = 4, + TSTAT_PP_ROT_MASK = 0x00000C00, + TSTAT_PP_ROT_OFFSET = 10, + + TASK_STAT_IDLE = 0, + TASK_STAT_ACTIVE = 1, + TASK_STAT_WAIT4READY = 2, + + /* Image Converter Register bits */ + IC_CONF_PRPENC_EN = 0x00000001, + IC_CONF_PRPENC_CSC1 = 0x00000002, + IC_CONF_PRPENC_ROT_EN = 0x00000004, + IC_CONF_PRPVF_EN = 0x00000100, + IC_CONF_PRPVF_CSC1 = 0x00000200, + IC_CONF_PRPVF_CSC2 = 0x00000400, + IC_CONF_PRPVF_CMB = 0x00000800, + IC_CONF_PRPVF_ROT_EN = 0x00001000, + IC_CONF_PP_EN = 0x00010000, + IC_CONF_PP_CSC1 = 0x00020000, + IC_CONF_PP_CSC2 = 0x00040000, + IC_CONF_PP_CMB = 0x00080000, + IC_CONF_PP_ROT_EN = 0x00100000, + IC_CONF_IC_GLB_LOC_A = 0x10000000, + IC_CONF_KEY_COLOR_EN = 0x20000000, + IC_CONF_RWS_EN = 0x40000000, + IC_CONF_CSI_MEM_WR_EN = 0x80000000, + + IC_IDMAC_1_CB0_BURST_16 = 0x00000001, + IC_IDMAC_1_CB1_BURST_16 = 0x00000002, + IC_IDMAC_1_CB2_BURST_16 = 0x00000004, + IC_IDMAC_1_CB3_BURST_16 = 0x00000008, + IC_IDMAC_1_CB4_BURST_16 = 0x00000010, + IC_IDMAC_1_CB5_BURST_16 = 0x00000020, + IC_IDMAC_1_CB6_BURST_16 = 0x00000040, + IC_IDMAC_1_CB7_BURST_16 = 0x00000080, + IC_IDMAC_1_PRPENC_ROT_MASK = 0x00003800, + IC_IDMAC_1_PRPENC_ROT_OFFSET = 11, + IC_IDMAC_1_PRPVF_ROT_MASK = 0x0001C000, + IC_IDMAC_1_PRPVF_ROT_OFFSET = 14, + IC_IDMAC_1_PP_ROT_MASK = 0x000E0000, + IC_IDMAC_1_PP_ROT_OFFSET = 17, + IC_IDMAC_1_PP_FLIP_RS = 0x00400000, + IC_IDMAC_1_PRPVF_FLIP_RS = 0x00200000, + IC_IDMAC_1_PRPENC_FLIP_RS = 0x00100000, + + IC_IDMAC_2_PRPENC_HEIGHT_MASK = 0x000003FF, + IC_IDMAC_2_PRPENC_HEIGHT_OFFSET = 0, + IC_IDMAC_2_PRPVF_HEIGHT_MASK = 0x000FFC00, + IC_IDMAC_2_PRPVF_HEIGHT_OFFSET = 10, + IC_IDMAC_2_PP_HEIGHT_MASK = 0x3FF00000, + IC_IDMAC_2_PP_HEIGHT_OFFSET = 20, + + IC_IDMAC_3_PRPENC_WIDTH_MASK = 0x000003FF, + IC_IDMAC_3_PRPENC_WIDTH_OFFSET = 0, + IC_IDMAC_3_PRPVF_WIDTH_MASK = 0x000FFC00, + IC_IDMAC_3_PRPVF_WIDTH_OFFSET = 10, + IC_IDMAC_3_PP_WIDTH_MASK = 0x3FF00000, + IC_IDMAC_3_PP_WIDTH_OFFSET = 20, + + CSI_SENS_CONF_DATA_FMT_SHIFT = 8, + CSI_SENS_CONF_DATA_FMT_MASK = 0x00000700, + CSI_SENS_CONF_DATA_FMT_RGB_YUV444 = 0L, + CSI_SENS_CONF_DATA_FMT_YUV422_YUYV = 1L, + CSI_SENS_CONF_DATA_FMT_YUV422_UYVY = 2L, + CSI_SENS_CONF_DATA_FMT_BAYER = 3L, + CSI_SENS_CONF_DATA_FMT_RGB565 = 4L, + CSI_SENS_CONF_DATA_FMT_RGB555 = 5L, + CSI_SENS_CONF_DATA_FMT_RGB444 = 6L, + CSI_SENS_CONF_DATA_FMT_JPEG = 7L, + + CSI_SENS_CONF_VSYNC_POL_SHIFT = 0, + CSI_SENS_CONF_HSYNC_POL_SHIFT = 1, + CSI_SENS_CONF_DATA_POL_SHIFT = 2, + CSI_SENS_CONF_PIX_CLK_POL_SHIFT = 3, + CSI_SENS_CONF_SENS_PRTCL_SHIFT = 4, + CSI_SENS_CONF_PACK_TIGHT_SHIFT = 7, + CSI_SENS_CONF_DATA_WIDTH_SHIFT = 11, + CSI_SENS_CONF_EXT_VSYNC_SHIFT = 15, + CSI_SENS_CONF_DIVRATIO_SHIFT = 16, + + CSI_SENS_CONF_DIVRATIO_MASK = 0x00FF0000L, + CSI_SENS_CONF_DATA_DEST_SHIFT = 24, + CSI_SENS_CONF_DATA_DEST_MASK = 0x07000000L, + CSI_SENS_CONF_JPEG8_EN_SHIFT = 27, + CSI_SENS_CONF_JPEG_EN_SHIFT = 28, + CSI_SENS_CONF_FORCE_EOF_SHIFT = 29, + CSI_SENS_CONF_DATA_EN_POL_SHIFT = 31, + + CSI_DATA_DEST_ISP = 1L, + CSI_DATA_DEST_IC = 2L, + CSI_DATA_DEST_IDMAC = 4L, + + CSI_CCIR_ERR_DET_EN = 0x01000000L, + CSI_HORI_DOWNSIZE_EN = 0x80000000L, + CSI_VERT_DOWNSIZE_EN = 0x40000000L, + CSI_TEST_GEN_MODE_EN = 0x01000000L, + + CSI_HSC_MASK = 0x1FFF0000, + CSI_HSC_SHIFT = 16, + CSI_VSC_MASK = 0x00000FFF, + CSI_VSC_SHIFT = 0, + + CSI_TEST_GEN_R_MASK = 0x000000FFL, + CSI_TEST_GEN_R_SHIFT = 0, + CSI_TEST_GEN_G_MASK = 0x0000FF00L, + CSI_TEST_GEN_G_SHIFT = 8, + CSI_TEST_GEN_B_MASK = 0x00FF0000L, + CSI_TEST_GEN_B_SHIFT = 16, + + CSI_MIPI_DI0_MASK = 0x000000FFL, + CSI_MIPI_DI0_SHIFT = 0, + CSI_MIPI_DI1_MASK = 0x0000FF00L, + CSI_MIPI_DI1_SHIFT = 8, + CSI_MIPI_DI2_MASK = 0x00FF0000L, + CSI_MIPI_DI2_SHIFT = 16, + CSI_MIPI_DI3_MASK = 0xFF000000L, + CSI_MIPI_DI3_SHIFT = 24, + + CSI_MAX_RATIO_SKIP_ISP_MASK = 0x00070000L, + CSI_MAX_RATIO_SKIP_ISP_SHIFT = 16, + CSI_SKIP_ISP_MASK = 0x00F80000L, + CSI_SKIP_ISP_SHIFT = 19, + CSI_MAX_RATIO_SKIP_SMFC_MASK = 0x00000007L, + CSI_MAX_RATIO_SKIP_SMFC_SHIFT = 0, + CSI_SKIP_SMFC_MASK = 0x000000F8L, + CSI_SKIP_SMFC_SHIFT = 3, + CSI_ID_2_SKIP_MASK = 0x00000300L, + CSI_ID_2_SKIP_SHIFT = 8, + + CSI_COLOR_FIRST_ROW_MASK = 0x00000002L, + CSI_COLOR_FIRST_COMP_MASK = 0x00000001L, + + SMFC_MAP_CH0_MASK = 0x00000007L, + SMFC_MAP_CH0_SHIFT = 0, + SMFC_MAP_CH1_MASK = 0x00000038L, + SMFC_MAP_CH1_SHIFT = 3, + SMFC_MAP_CH2_MASK = 0x000001C0L, + SMFC_MAP_CH2_SHIFT = 6, + SMFC_MAP_CH3_MASK = 0x00000E00L, + SMFC_MAP_CH3_SHIFT = 9, + + SMFC_WM0_SET_MASK = 0x00000007L, + SMFC_WM0_SET_SHIFT = 0, + SMFC_WM1_SET_MASK = 0x000001C0L, + SMFC_WM1_SET_SHIFT = 6, + SMFC_WM2_SET_MASK = 0x00070000L, + SMFC_WM2_SET_SHIFT = 16, + SMFC_WM3_SET_MASK = 0x01C00000L, + SMFC_WM3_SET_SHIFT = 22, + + SMFC_WM0_CLR_MASK = 0x00000038L, + SMFC_WM0_CLR_SHIFT = 3, + SMFC_WM1_CLR_MASK = 0x00000E00L, + SMFC_WM1_CLR_SHIFT = 9, + SMFC_WM2_CLR_MASK = 0x00380000L, + SMFC_WM2_CLR_SHIFT = 19, + SMFC_WM3_CLR_MASK = 0x0E000000L, + SMFC_WM3_CLR_SHIFT = 25, + + SMFC_BS0_MASK = 0x0000000FL, + SMFC_BS0_SHIFT = 0, + SMFC_BS1_MASK = 0x000000F0L, + SMFC_BS1_SHIFT = 4, + SMFC_BS2_MASK = 0x00000F00L, + SMFC_BS2_SHIFT = 8, + SMFC_BS3_MASK = 0x0000F000L, + SMFC_BS3_SHIFT = 12, + + PF_CONF_TYPE_MASK = 0x00000007, + PF_CONF_TYPE_SHIFT = 0, + PF_CONF_PAUSE_EN = 0x00000010, + PF_CONF_RESET = 0x00008000, + PF_CONF_PAUSE_ROW_MASK = 0x00FF0000, + PF_CONF_PAUSE_ROW_SHIFT = 16, + + DI_DW_GEN_ACCESS_SIZE_OFFSET = 24, + DI_DW_GEN_COMPONENT_SIZE_OFFSET = 16, + + DI_GEN_DI_CLK_EXT = 0x100000, + DI_GEN_POLARITY_1 = 0x00000001, + DI_GEN_POLARITY_2 = 0x00000002, + DI_GEN_POLARITY_3 = 0x00000004, + DI_GEN_POLARITY_4 = 0x00000008, + DI_GEN_POLARITY_5 = 0x00000008, + DI_GEN_POLARITY_6 = 0x00000008, + DI_GEN_POLARITY_7 = 0x00000008, + DI_GEN_POLARITY_8 = 0x00000008, + + DI_POL_DRDY_DATA_POLARITY = 0x00000080, + DI_POL_DRDY_POLARITY_15 = 0x00000010, + + DI_VSYNC_SEL_OFFSET = 13, + + DC_WR_CH_CONF_FIELD_MODE = 0x00000200, + DC_WR_CH_CONF_PROG_TYPE_OFFSET = 5, + DC_WR_CH_CONF_PROG_TYPE_MASK = 0x000000E0, + DC_WR_CH_CONF_PROG_DI_ID = 0x00000004, + DC_WR_CH_CONF_PROG_DISP_ID_OFFSET = 3, + DC_WR_CH_CONF_PROG_DISP_ID_MASK = 0x00000018, + + DC_UGDE_0_ODD_EN = 0x02000000, + DC_UGDE_0_ID_CODED_MASK = 0x00000007, + DC_UGDE_0_ID_CODED_OFFSET = 0, + DC_UGDE_0_EV_PRIORITY_MASK = 0x00000078, + DC_UGDE_0_EV_PRIORITY_OFFSET = 3, + + DP_COM_CONF_FG_EN = 0x00000001, + DP_COM_CONF_GWSEL = 0x00000002, + DP_COM_CONF_GWAM = 0x00000004, + DP_COM_CONF_GWCKE = 0x00000008, + DP_COM_CONF_CSC_DEF_MASK = 0x00000300, + DP_COM_CONF_CSC_DEF_OFFSET = 8, + DP_COM_CONF_CSC_DEF_FG = 0x00000300, + DP_COM_CONF_CSC_DEF_BG = 0x00000200, + DP_COM_CONF_CSC_DEF_BOTH = 0x00000100, + + DI_SER_CONF_LLA_SER_ACCESS = 0x00000020, + DI_SER_CONF_SERIAL_CLK_POL = 0x00000010, + DI_SER_CONF_SERIAL_DATA_POL = 0x00000008, + DI_SER_CONF_SERIAL_RS_POL = 0x00000004, + DI_SER_CONF_SERIAL_CS_POL = 0x00000002, + DI_SER_CONF_WAIT4SERIAL = 0x00000001, +}; + +enum di_pins { + DI_PIN11 = 0, + DI_PIN12 = 1, + DI_PIN13 = 2, + DI_PIN14 = 3, + DI_PIN15 = 4, + DI_PIN16 = 5, + DI_PIN17 = 6, + DI_PIN_CS = 7, + + DI_PIN_SER_CLK = 0, + DI_PIN_SER_RS = 1, +}; + +enum di_sync_wave { + DI_SYNC_NONE = -1, + DI_SYNC_CLK = 0, + DI_SYNC_INT_HSYNC = 1, + DI_SYNC_HSYNC = 2, + DI_SYNC_VSYNC = 3, + DI_SYNC_DE = 5, +}; + +/* DC template opcodes */ +#define WROD(lf) (0x18 | (lf << 1)) + +#endif --- linux-2.6.28.orig/drivers/mxc/ipu3/ipu_prv.h +++ linux-2.6.28/drivers/mxc/ipu3/ipu_prv.h @@ -0,0 +1,88 @@ +/* + * Copyright 2005-2009 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 __INCLUDE_IPU_PRV_H__ +#define __INCLUDE_IPU_PRV_H__ + +#include +#include +#include +#include +#include + +/* Globals */ +extern struct device *g_ipu_dev; +extern spinlock_t ipu_lock; +extern bool g_ipu_clk_enabled; +extern struct clk *g_ipu_clk; +extern struct clk *g_di_clk[2]; +extern struct clk *g_csi_clk[2]; +extern unsigned char g_dc_di_assignment[]; +extern int g_ipu_hw_rev; + +#define IDMA_CHAN_INVALID 0xFF + +struct ipu_channel { + u8 video_in_dma; + u8 alpha_in_dma; + u8 graph_in_dma; + u8 out_dma; +}; + +int register_ipu_device(void); +ipu_color_space_t format_to_colorspace(uint32_t fmt); + +void ipu_dump_registers(void); + +uint32_t _ipu_channel_status(ipu_channel_t channel); + +void _ipu_init_dc_mappings(void); +int _ipu_dp_init(ipu_channel_t channel, uint32_t in_pixel_fmt, + uint32_t out_pixel_fmt); +void _ipu_dp_uninit(ipu_channel_t channel); +void _ipu_dc_init(int dc_chan, int di, bool interlaced); +void _ipu_dc_uninit(int dc_chan); +void _ipu_dp_dc_enable(ipu_channel_t channel); +void _ipu_dp_dc_disable(ipu_channel_t channel); +void _ipu_dmfc_init(void); +void _ipu_dmfc_set_wait4eot(int dma_chan, int width); +int _ipu_chan_is_interlaced(ipu_channel_t channel); + +void _ipu_ic_enable_task(ipu_channel_t channel); +void _ipu_ic_disable_task(ipu_channel_t channel); +void _ipu_ic_init_prpvf(ipu_channel_params_t *params, bool src_is_csi); +void _ipu_ic_uninit_prpvf(void); +void _ipu_ic_init_rotate_vf(ipu_channel_params_t *params); +void _ipu_ic_uninit_rotate_vf(void); +void _ipu_ic_init_csi(ipu_channel_params_t *params); +void _ipu_ic_uninit_csi(void); +void _ipu_ic_init_prpenc(ipu_channel_params_t *params, bool src_is_csi); +void _ipu_ic_uninit_prpenc(void); +void _ipu_ic_init_rotate_enc(ipu_channel_params_t *params); +void _ipu_ic_uninit_rotate_enc(void); +void _ipu_ic_init_pp(ipu_channel_params_t *params); +void _ipu_ic_uninit_pp(void); +void _ipu_ic_init_rotate_pp(ipu_channel_params_t *params); +void _ipu_ic_uninit_rotate_pp(void); +int _ipu_ic_idma_init(int dma_chan, uint16_t width, uint16_t height, + int burst_size, ipu_rotate_mode_t rot); +int _ipu_csi_init(ipu_channel_t channel, uint32_t csi); +void ipu_csi_set_test_generator(bool active, uint32_t r_value, + uint32_t g_value, uint32_t b_value, + uint32_t pix_clk, uint32_t csi); +void _ipu_csi_ccir_err_detection_enable(uint32_t csi); +void _ipu_csi_ccir_err_detection_disable(uint32_t csi); +void _ipu_smfc_init(ipu_channel_t channel, uint32_t mipi_id, uint32_t csi); +void _ipu_smfc_set_burst_size(ipu_channel_t channel, uint32_t bs); +void _ipu_dp_set_csc_coefficients(ipu_channel_t channel, int32_t param[][3]); + +#endif /* __INCLUDE_IPU_PRV_H__ */ --- linux-2.6.28.orig/drivers/mxc/ipu3/Kconfig +++ linux-2.6.28/drivers/mxc/ipu3/Kconfig @@ -0,0 +1,5 @@ +config MXC_IPU_V3 + bool + +config MXC_IPU_V3D + bool --- linux-2.6.28.orig/drivers/mxc/ipu3/ipu_capture.c +++ linux-2.6.28/drivers/mxc/ipu3/ipu_capture.c @@ -0,0 +1,726 @@ +/* + * Copyright 2008-2009 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 + */ + +/*! + * @file ipu_capture.c + * + * @brief IPU capture dase functions + * + * @ingroup IPU + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ipu_prv.h" +#include "ipu_regs.h" + +static bool gipu_csi_get_mclk_flag[2] = {false, false}; + +/*! + * ipu_csi_init_interface + * Sets initial values for the CSI registers. + * The width and height of the sensor and the actual frame size will be + * set to the same values. + * @param width Sensor width + * @param height Sensor height + * @param pixel_fmt pixel format + * @param cfg_param ipu_csi_signal_cfg_t structure + * @param csi csi 0 or csi 1 + * + * @return 0 for success, -EINVAL for error + */ +int32_t +ipu_csi_init_interface(uint16_t width, uint16_t height, uint32_t pixel_fmt, + ipu_csi_signal_cfg_t cfg_param) +{ + uint32_t data = 0; + uint32_t csi = cfg_param.csi; + unsigned long lock_flags; + + /* Set SENS_DATA_FORMAT bits (8, 9 and 10) + RGB or YUV444 is 0 which is current value in data so not set + explicitly + This is also the default value if attempts are made to set it to + something invalid. */ + switch (pixel_fmt) { + case IPU_PIX_FMT_YUYV: + cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_YUYV; + break; + case IPU_PIX_FMT_UYVY: + cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_UYVY; + break; + case IPU_PIX_FMT_RGB24: + case IPU_PIX_FMT_BGR24: + cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_RGB_YUV444; + break; + case IPU_PIX_FMT_GENERIC: + cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER; + break; + case IPU_PIX_FMT_RGB565: + cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_RGB565; + break; + case IPU_PIX_FMT_RGB555: + cfg_param.data_fmt = CSI_SENS_CONF_DATA_FMT_RGB555; + break; + default: + return -EINVAL; + } + + /* Set the CSI_SENS_CONF register remaining fields */ + data |= cfg_param.data_width << CSI_SENS_CONF_DATA_WIDTH_SHIFT | + cfg_param.data_fmt << CSI_SENS_CONF_DATA_FMT_SHIFT | + cfg_param.data_pol << CSI_SENS_CONF_DATA_POL_SHIFT | + cfg_param.Vsync_pol << CSI_SENS_CONF_VSYNC_POL_SHIFT | + cfg_param.Hsync_pol << CSI_SENS_CONF_HSYNC_POL_SHIFT | + cfg_param.pixclk_pol << CSI_SENS_CONF_PIX_CLK_POL_SHIFT | + cfg_param.ext_vsync << CSI_SENS_CONF_EXT_VSYNC_SHIFT | + cfg_param.clk_mode << CSI_SENS_CONF_SENS_PRTCL_SHIFT | + cfg_param.pack_tight << CSI_SENS_CONF_PACK_TIGHT_SHIFT | + cfg_param.force_eof << CSI_SENS_CONF_FORCE_EOF_SHIFT | + cfg_param.data_en_pol << CSI_SENS_CONF_DATA_EN_POL_SHIFT; + + spin_lock_irqsave(&ipu_lock, lock_flags); + + __raw_writel(data, CSI_SENS_CONF(csi)); + + /* Setup sensor frame size */ + __raw_writel((width - 1) | (height - 1) << 16, CSI_SENS_FRM_SIZE(csi)); + + /* Set CCIR registers */ + if ((cfg_param.clk_mode == IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE) || + (cfg_param.clk_mode == IPU_CSI_CLK_MODE_CCIR656_INTERLACED)) { + _ipu_csi_ccir_err_detection_enable(csi); + __raw_writel(0x40030, CSI_CCIR_CODE_1(csi)); + __raw_writel(0xFF0000, CSI_CCIR_CODE_3(csi)); + } else if ((cfg_param.clk_mode == + IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR) || + (cfg_param.clk_mode == + IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR) || + (cfg_param.clk_mode == + IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR) || + (cfg_param.clk_mode == + IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR)) { + _ipu_csi_ccir_err_detection_enable(csi); + __raw_writel(0x40030, CSI_CCIR_CODE_1(csi)); + __raw_writel(0xFF0000, CSI_CCIR_CODE_3(csi)); + } else if ((cfg_param.clk_mode == IPU_CSI_CLK_MODE_GATED_CLK) || + (cfg_param.clk_mode == IPU_CSI_CLK_MODE_NONGATED_CLK)) { + _ipu_csi_ccir_err_detection_disable(csi); + } + + dev_dbg(g_ipu_dev, "CSI_SENS_CONF = 0x%08X\n", + __raw_readl(CSI_SENS_CONF(csi))); + dev_dbg(g_ipu_dev, "CSI_ACT_FRM_SIZE = 0x%08X\n", + __raw_readl(CSI_ACT_FRM_SIZE(csi))); + + spin_unlock_irqrestore(&ipu_lock, lock_flags); + + return 0; +} +EXPORT_SYMBOL(ipu_csi_init_interface); + +/*! _ipu_csi_mclk_set + * + * @param pixel_clk desired pixel clock frequency in Hz + * @param csi csi 0 or csi 1 + * + * @return Returns 0 on success or negative error code on fail + */ +int _ipu_csi_mclk_set(uint32_t pixel_clk, uint32_t csi) +{ + uint32_t temp; + uint32_t div_ratio; + + div_ratio = (clk_get_rate(g_ipu_clk) / pixel_clk) - 1; + + if (div_ratio > 0xFF || div_ratio < 0) { + dev_dbg(g_ipu_dev, "The value of pixel_clk extends normal range\n"); + return -EINVAL; + } + + temp = __raw_readl(CSI_SENS_CONF(csi)); + temp &= ~CSI_SENS_CONF_DIVRATIO_MASK; + __raw_writel(temp | (div_ratio << CSI_SENS_CONF_DIVRATIO_SHIFT), + CSI_SENS_CONF(csi)); + + return 0; +} + +/*! + * ipu_csi_enable_mclk + * + * @param csi csi 0 or csi 1 + * @param flag true to enable mclk, false to disable mclk + * @param wait true to wait 100ms make clock stable, false not wait + * + * @return Returns 0 on success + */ +int ipu_csi_enable_mclk(int csi, bool flag, bool wait) +{ + if (flag) { + if (gipu_csi_get_mclk_flag[csi] == true) { + printk(KERN_WARNING "The clock of CSI%d has been enabled\n", csi); + return 0; + } + + clk_enable(g_csi_clk[csi]); + if (wait == true) + msleep(10); + gipu_csi_get_mclk_flag[csi] = true; + } else { + if (gipu_csi_get_mclk_flag[csi] == false) { + printk(KERN_WARNING "The clock of CSI%d has been disabled\n", csi); + return 0; + } + + clk_disable(g_csi_clk[csi]); + gipu_csi_get_mclk_flag[csi] = false; + } + + return 0; +} +EXPORT_SYMBOL(ipu_csi_enable_mclk); + +/*! + * ipu_csi_get_window_size + * + * @param width pointer to window width + * @param height pointer to window height + * @param csi csi 0 or csi 1 + */ +void ipu_csi_get_window_size(uint32_t *width, uint32_t *height, uint32_t csi) +{ + uint32_t reg; + unsigned long lock_flags; + + spin_lock_irqsave(&ipu_lock, lock_flags); + + reg = __raw_readl(CSI_ACT_FRM_SIZE(csi)); + *width = (reg & 0xFFFF) + 1; + *height = (reg >> 16 & 0xFFFF) + 1; + + spin_unlock_irqrestore(&ipu_lock, lock_flags); +} +EXPORT_SYMBOL(ipu_csi_get_window_size); + +/*! + * ipu_csi_set_window_size + * + * @param width window width + * @param height window height + * @param csi csi 0 or csi 1 + */ +void ipu_csi_set_window_size(uint32_t width, uint32_t height, uint32_t csi) +{ + unsigned long lock_flags; + + spin_lock_irqsave(&ipu_lock, lock_flags); + + __raw_writel((width - 1) | (height - 1) << 16, CSI_ACT_FRM_SIZE(csi)); + + spin_unlock_irqrestore(&ipu_lock, lock_flags); +} +EXPORT_SYMBOL(ipu_csi_set_window_size); + +/*! + * ipu_csi_set_window_pos + * + * @param left uint32 window x start + * @param top uint32 window y start + * @param csi csi 0 or csi 1 + */ +void ipu_csi_set_window_pos(uint32_t left, uint32_t top, uint32_t csi) +{ + uint32_t temp; + unsigned long lock_flags; + + spin_lock_irqsave(&ipu_lock, lock_flags); + + temp = __raw_readl(CSI_OUT_FRM_CTRL(csi)); + temp &= ~(CSI_HSC_MASK | CSI_VSC_MASK); + temp |= ((top << CSI_VSC_SHIFT) | (left << CSI_HSC_SHIFT)); + __raw_writel(temp, CSI_OUT_FRM_CTRL(csi)); + + spin_unlock_irqrestore(&ipu_lock, lock_flags); +} +EXPORT_SYMBOL(ipu_csi_set_window_pos); + +/*! + * _ipu_csi_horizontal_downsize_enable + * Enable horizontal downsizing(decimation) by 2. + * + * @param csi csi 0 or csi 1 + */ +void _ipu_csi_horizontal_downsize_enable(uint32_t csi) +{ + uint32_t temp; + unsigned long lock_flags; + + spin_lock_irqsave(&ipu_lock, lock_flags); + + temp = __raw_readl(CSI_OUT_FRM_CTRL(csi)); + temp |= CSI_HORI_DOWNSIZE_EN; + __raw_writel(temp, CSI_OUT_FRM_CTRL(csi)); + + spin_unlock_irqrestore(&ipu_lock, lock_flags); +} + +/*! + * _ipu_csi_horizontal_downsize_disable + * Disable horizontal downsizing(decimation) by 2. + * + * @param csi csi 0 or csi 1 + */ +void _ipu_csi_horizontal_downsize_disable(uint32_t csi) +{ + uint32_t temp; + unsigned long lock_flags; + + spin_lock_irqsave(&ipu_lock, lock_flags); + + temp = __raw_readl(CSI_OUT_FRM_CTRL(csi)); + temp &= ~CSI_HORI_DOWNSIZE_EN; + __raw_writel(temp, CSI_OUT_FRM_CTRL(csi)); + + spin_unlock_irqrestore(&ipu_lock, lock_flags); +} + +/*! + * _ipu_csi_vertical_downsize_enable + * Enable vertical downsizing(decimation) by 2. + * + * @param csi csi 0 or csi 1 + */ +void _ipu_csi_vertical_downsize_enable(uint32_t csi) +{ + uint32_t temp; + unsigned long lock_flags; + + spin_lock_irqsave(&ipu_lock, lock_flags); + + temp = __raw_readl(CSI_OUT_FRM_CTRL(csi)); + temp |= CSI_VERT_DOWNSIZE_EN; + __raw_writel(temp, CSI_OUT_FRM_CTRL(csi)); + + spin_unlock_irqrestore(&ipu_lock, lock_flags); +} + +/*! + * _ipu_csi_vertical_downsize_disable + * Disable vertical downsizing(decimation) by 2. + * + * @param csi csi 0 or csi 1 + */ +void _ipu_csi_vertical_downsize_disable(uint32_t csi) +{ + uint32_t temp; + unsigned long lock_flags; + + spin_lock_irqsave(&ipu_lock, lock_flags); + + temp = __raw_readl(CSI_OUT_FRM_CTRL(csi)); + temp &= ~CSI_VERT_DOWNSIZE_EN; + __raw_writel(temp, CSI_OUT_FRM_CTRL(csi)); + + spin_unlock_irqrestore(&ipu_lock, lock_flags); +} + +/*! + * ipu_csi_set_test_generator + * + * @param active 1 for active and 0 for inactive + * @param r_value red value for the generated pattern of even pixel + * @param g_value green value for the generated pattern of even + * pixel + * @param b_value blue value for the generated pattern of even pixel + * @param pixel_clk desired pixel clock frequency in Hz + * @param csi csi 0 or csi 1 + */ +void ipu_csi_set_test_generator(bool active, uint32_t r_value, + uint32_t g_value, uint32_t b_value, uint32_t pix_clk, uint32_t csi) +{ + uint32_t temp; + unsigned long lock_flags; + + spin_lock_irqsave(&ipu_lock, lock_flags); + + temp = __raw_readl(CSI_TST_CTRL(csi)); + + if (active == false) { + temp &= ~CSI_TEST_GEN_MODE_EN; + __raw_writel(temp, CSI_TST_CTRL(csi)); + } else { + /* Set sensb_mclk div_ratio*/ + _ipu_csi_mclk_set(pix_clk, csi); + + temp &= ~(CSI_TEST_GEN_R_MASK | CSI_TEST_GEN_G_MASK | + CSI_TEST_GEN_B_MASK); + temp |= CSI_TEST_GEN_MODE_EN; + temp |= (r_value << CSI_TEST_GEN_R_SHIFT) | + (g_value << CSI_TEST_GEN_G_SHIFT) | + (b_value << CSI_TEST_GEN_B_SHIFT); + __raw_writel(temp, CSI_TST_CTRL(csi)); + } + + spin_unlock_irqrestore(&ipu_lock, lock_flags); +} +EXPORT_SYMBOL(ipu_csi_set_test_generator); + +/*! + * _ipu_csi_ccir_err_detection_en + * Enable error detection and correction for + * CCIR interlaced mode with protection bit. + * + * @param csi csi 0 or csi 1 + */ +void _ipu_csi_ccir_err_detection_enable(uint32_t csi) +{ + uint32_t temp; + + temp = __raw_readl(CSI_CCIR_CODE_1(csi)); + temp |= CSI_CCIR_ERR_DET_EN; + __raw_writel(temp, CSI_CCIR_CODE_1(csi)); +} + +/*! + * _ipu_csi_ccir_err_detection_disable + * Disable error detection and correction for + * CCIR interlaced mode with protection bit. + * + * @param csi csi 0 or csi 1 + */ +void _ipu_csi_ccir_err_detection_disable(uint32_t csi) +{ + uint32_t temp; + + temp = __raw_readl(CSI_CCIR_CODE_1(csi)); + temp &= ~CSI_CCIR_ERR_DET_EN; + __raw_writel(temp, CSI_CCIR_CODE_1(csi)); +} + +/*! + * _ipu_csi_set_mipi_di + * + * @param num MIPI data identifier 0-3 handled by CSI + * @param di_val data identifier value + * @param csi csi 0 or csi 1 + * + * @return Returns 0 on success or negative error code on fail + */ +int _ipu_csi_set_mipi_di(uint32_t num, uint32_t di_val, uint32_t csi) +{ + uint32_t temp; + int retval = 0; + unsigned long lock_flags; + + if (di_val > 0xFFL) { + retval = -EINVAL; + goto err; + } + + spin_lock_irqsave(&ipu_lock, lock_flags); + + temp = __raw_readl(CSI_MIPI_DI(csi)); + + switch (num) { + case IPU_CSI_MIPI_DI0: + temp &= ~CSI_MIPI_DI0_MASK; + temp |= (di_val << CSI_MIPI_DI0_SHIFT); + __raw_writel(temp, CSI_MIPI_DI(csi)); + break; + case IPU_CSI_MIPI_DI1: + temp &= ~CSI_MIPI_DI1_MASK; + temp |= (di_val << CSI_MIPI_DI1_SHIFT); + __raw_writel(temp, CSI_MIPI_DI(csi)); + break; + case IPU_CSI_MIPI_DI2: + temp &= ~CSI_MIPI_DI2_MASK; + temp |= (di_val << CSI_MIPI_DI2_SHIFT); + __raw_writel(temp, CSI_MIPI_DI(csi)); + break; + case IPU_CSI_MIPI_DI3: + temp &= ~CSI_MIPI_DI3_MASK; + temp |= (di_val << CSI_MIPI_DI3_SHIFT); + __raw_writel(temp, CSI_MIPI_DI(csi)); + break; + default: + retval = -EINVAL; + goto err; + } + + spin_unlock_irqrestore(&ipu_lock, lock_flags); +err: + return retval; +} + +/*! + * _ipu_csi_set_skip_isp + * + * @param skip select frames to be skipped and set the + * correspond bits to 1 + * @param max_ratio number of frames in a skipping set and the + * maximum value of max_ratio is 5 + * @param csi csi 0 or csi 1 + * + * @return Returns 0 on success or negative error code on fail + */ +int _ipu_csi_set_skip_isp(uint32_t skip, uint32_t max_ratio, uint32_t csi) +{ + uint32_t temp; + int retval = 0; + unsigned long lock_flags; + + if (max_ratio > 5) { + retval = -EINVAL; + goto err; + } + + spin_lock_irqsave(&ipu_lock, lock_flags); + + temp = __raw_readl(CSI_SKIP(csi)); + temp &= ~(CSI_MAX_RATIO_SKIP_ISP_MASK | CSI_SKIP_ISP_MASK); + temp |= (max_ratio << CSI_MAX_RATIO_SKIP_ISP_SHIFT) | + (skip << CSI_SKIP_ISP_SHIFT); + __raw_writel(temp, CSI_SKIP(csi)); + + spin_unlock_irqrestore(&ipu_lock, lock_flags); +err: + return retval; +} + +/*! + * _ipu_csi_set_skip_smfc + * + * @param skip select frames to be skipped and set the + * correspond bits to 1 + * @param max_ratio number of frames in a skipping set and the + * maximum value of max_ratio is 5 + * @param id csi to smfc skipping id + * @param csi csi 0 or csi 1 + * + * @return Returns 0 on success or negative error code on fail + */ +int _ipu_csi_set_skip_smfc(uint32_t skip, uint32_t max_ratio, + uint32_t id, uint32_t csi) +{ + uint32_t temp; + int retval = 0; + unsigned long lock_flags; + + if (max_ratio > 5 || id > 3) { + retval = -EINVAL; + goto err; + } + + spin_lock_irqsave(&ipu_lock, lock_flags); + + temp = __raw_readl(CSI_SKIP(csi)); + temp &= ~(CSI_MAX_RATIO_SKIP_SMFC_MASK | CSI_ID_2_SKIP_MASK | + CSI_SKIP_SMFC_MASK); + temp |= (max_ratio << CSI_MAX_RATIO_SKIP_SMFC_SHIFT) | + (id << CSI_ID_2_SKIP_SHIFT) | + (skip << CSI_SKIP_SMFC_SHIFT); + __raw_writel(temp, CSI_SKIP(csi)); + + spin_unlock_irqrestore(&ipu_lock, lock_flags); +err: + return retval; +} + +/*! + * _ipu_smfc_init + * Map CSI frames to IDMAC channels. + * + * @param channel IDMAC channel 0-3 + * @param mipi_id mipi id number 0-3 + * @param csi csi0 or csi1 + */ +void _ipu_smfc_init(ipu_channel_t channel, uint32_t mipi_id, uint32_t csi) +{ + uint32_t temp; + + temp = __raw_readl(SMFC_MAP); + + switch (channel) { + case CSI_MEM0: + temp &= ~SMFC_MAP_CH0_MASK; + temp |= ((csi << 2) | mipi_id) << SMFC_MAP_CH0_SHIFT; + break; + case CSI_MEM1: + temp &= ~SMFC_MAP_CH1_MASK; + temp |= ((csi << 2) | mipi_id) << SMFC_MAP_CH1_SHIFT; + break; + case CSI_MEM2: + temp &= ~SMFC_MAP_CH2_MASK; + temp |= ((csi << 2) | mipi_id) << SMFC_MAP_CH2_SHIFT; + break; + case CSI_MEM3: + temp &= ~SMFC_MAP_CH3_MASK; + temp |= ((csi << 2) | mipi_id) << SMFC_MAP_CH3_SHIFT; + break; + default: + return; + } + + __raw_writel(temp, SMFC_MAP); +} + +/*! + * _ipu_smfc_set_wmc + * Caution: The number of required channels, the enabled channels + * and the FIFO size per channel are configured restrictedly. + * + * @param channel IDMAC channel 0-3 + * @param set set 1 or clear 0 + * @param level water mark level when FIFO is on the + * relative size + */ +void _ipu_smfc_set_wmc(ipu_channel_t channel, bool set, uint32_t level) +{ + uint32_t temp; + unsigned long lock_flags; + + spin_lock_irqsave(&ipu_lock, lock_flags); + + temp = __raw_readl(SMFC_WMC); + + switch (channel) { + case CSI_MEM0: + if (set == true) { + temp &= ~SMFC_WM0_SET_MASK; + temp |= level << SMFC_WM0_SET_SHIFT; + } else { + temp &= ~SMFC_WM0_CLR_MASK; + temp |= level << SMFC_WM0_CLR_SHIFT; + } + break; + case CSI_MEM1: + if (set == true) { + temp &= ~SMFC_WM1_SET_MASK; + temp |= level << SMFC_WM1_SET_SHIFT; + } else { + temp &= ~SMFC_WM1_CLR_MASK; + temp |= level << SMFC_WM1_CLR_SHIFT; + } + break; + case CSI_MEM2: + if (set == true) { + temp &= ~SMFC_WM2_SET_MASK; + temp |= level << SMFC_WM2_SET_SHIFT; + } else { + temp &= ~SMFC_WM2_CLR_MASK; + temp |= level << SMFC_WM2_CLR_SHIFT; + } + break; + case CSI_MEM3: + if (set == true) { + temp &= ~SMFC_WM3_SET_MASK; + temp |= level << SMFC_WM3_SET_SHIFT; + } else { + temp &= ~SMFC_WM3_CLR_MASK; + temp |= level << SMFC_WM3_CLR_SHIFT; + } + break; + default: + return; + } + + __raw_writel(temp, SMFC_WMC); + + spin_unlock_irqrestore(&ipu_lock, lock_flags); +} + +/*! + * _ipu_smfc_set_burst_size + * + * @param channel IDMAC channel 0-3 + * @param bs burst size of IDMAC channel, + * the value programmed here shoud be BURST_SIZE-1 + */ +void _ipu_smfc_set_burst_size(ipu_channel_t channel, uint32_t bs) +{ + uint32_t temp; + unsigned long lock_flags; + + spin_lock_irqsave(&ipu_lock, lock_flags); + + temp = __raw_readl(SMFC_BS); + + switch (channel) { + case CSI_MEM0: + temp &= ~SMFC_BS0_MASK; + temp |= bs << SMFC_BS0_SHIFT; + break; + case CSI_MEM1: + temp &= ~SMFC_BS1_MASK; + temp |= bs << SMFC_BS1_SHIFT; + break; + case CSI_MEM2: + temp &= ~SMFC_BS2_MASK; + temp |= bs << SMFC_BS2_SHIFT; + break; + case CSI_MEM3: + temp &= ~SMFC_BS3_MASK; + temp |= bs << SMFC_BS3_SHIFT; + break; + default: + return; + } + + __raw_writel(temp, SMFC_BS); + + spin_unlock_irqrestore(&ipu_lock, lock_flags); +} + +/*! + * _ipu_csi_init + * + * @param channel IDMAC channel + * @param csi csi 0 or csi 1 + * + * @return Returns 0 on success or negative error code on fail + */ +int _ipu_csi_init(ipu_channel_t channel, uint32_t csi) +{ + uint32_t csi_sens_conf, csi_dest; + int retval = 0; + + switch (channel) { + case CSI_MEM0: + case CSI_MEM1: + case CSI_MEM2: + case CSI_MEM3: + csi_dest = CSI_DATA_DEST_IDMAC; + break; + case CSI_PRP_ENC_MEM: + case CSI_PRP_VF_MEM: + csi_dest = CSI_DATA_DEST_IC; + break; + default: + retval = -EINVAL; + goto err; + } + + csi_sens_conf = __raw_readl(CSI_SENS_CONF(csi)); + csi_sens_conf &= ~CSI_SENS_CONF_DATA_DEST_MASK; + __raw_writel(csi_sens_conf | (csi_dest << + CSI_SENS_CONF_DATA_DEST_SHIFT), CSI_SENS_CONF(csi)); +err: + return retval; +} --- linux-2.6.28.orig/drivers/mxc/ipu3/Makefile +++ linux-2.6.28/drivers/mxc/ipu3/Makefile @@ -0,0 +1,4 @@ +obj-$(CONFIG_MXC_IPU_V3) = mxc_ipu.o + +mxc_ipu-objs := ipu_common.o ipu_ic.o ipu_disp.o ipu_capture.o ipu_device.o + --- linux-2.6.28.orig/drivers/mxc/ipu3/ipu_disp.c +++ linux-2.6.28/drivers/mxc/ipu3/ipu_disp.c @@ -0,0 +1,1183 @@ +/* + * Copyright 2005-2009 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 + */ + +/*! + * @file ipu_disp.c + * + * @brief IPU display submodule API functions + * + * @ingroup IPU + */ +#include +#include +#include +#include +#include +#include +#include +#include "ipu_prv.h" +#include "ipu_regs.h" +#include "ipu_param_mem.h" + +enum csc_type_t { + RGB2YUV = 0, + YUV2RGB, + RGB2RGB, + YUV2YUV, + CSC_NONE, + CSC_NUM +}; + +struct dp_csc_param_t { + int mode; + void *coeff; +}; + +#define SYNC_WAVE 0 +#define ASYNC_SER_WAVE 6 + +/* DC display ID assignments */ +#define DC_DISP_ID_SYNC(di) (di) +#define DC_DISP_ID_SERIAL 2 +#define DC_DISP_ID_ASYNC 3 + + +/* all value below is determined by fix reg setting in _ipu_dmfc_init*/ +#define DMFC_FIFO_SIZE_28 (128*4) +#define DMFC_FIFO_SIZE_29 (64*4) +#define DMFC_FIFO_SIZE_24 (64*4) +#define DMFC_FIFO_SIZE_27 (128*4) +#define DMFC_FIFO_SIZE_23 (128*4) + +void _ipu_dmfc_init(void) +{ + /* disable DMFC-IC channel*/ + __raw_writel(0x2, DMFC_IC_CTRL); + /* 1 - segment 0 and 1; 2, 1C and 2C unused */ + __raw_writel(0x00000090, DMFC_WR_CHAN); + __raw_writel(0x20202000, DMFC_WR_CHAN_DEF); + /* 5B - segment 2 and 3; 5F - segment 4 and 5; */ + /* 6B - segment 6; 6F - segment 7 */ + __raw_writel(0x1F1E9492, DMFC_DP_CHAN); +} + +void _ipu_dmfc_set_wait4eot(int dma_chan, int width) +{ + u32 dmfc_gen1 = __raw_readl(DMFC_GENERAL1); + + if (dma_chan == 23) { /*5B*/ + if (DMFC_FIFO_SIZE_23/width > 3) + dmfc_gen1 |= 1UL << 20; + else + dmfc_gen1 &= ~(1UL << 20); + } else if (dma_chan == 24) { /*6B*/ + if (DMFC_FIFO_SIZE_24/width > 1) + dmfc_gen1 |= 1UL << 22; + else + dmfc_gen1 &= ~(1UL << 22); + } else if (dma_chan == 27) { /*5F*/ + if (DMFC_FIFO_SIZE_27/width > 2) + dmfc_gen1 |= 1UL << 21; + else + dmfc_gen1 &= ~(1UL << 21); + } else if (dma_chan == 28) { /*1*/ + if (DMFC_FIFO_SIZE_28/width > 2) + dmfc_gen1 |= 1UL << 16; + else + dmfc_gen1 &= ~(1UL << 16); + } else if (dma_chan == 29) { /*6F*/ + if (DMFC_FIFO_SIZE_29/width > 1) + dmfc_gen1 |= 1UL << 23; + else + dmfc_gen1 &= ~(1UL << 23); + } + + __raw_writel(dmfc_gen1, DMFC_GENERAL1); +} + +static void _ipu_di_data_wave_config(int di, + int wave_gen, + int access_size, int component_size) +{ + u32 reg; + reg = (access_size << DI_DW_GEN_ACCESS_SIZE_OFFSET) | + (component_size << DI_DW_GEN_COMPONENT_SIZE_OFFSET); + __raw_writel(reg, DI_DW_GEN(di, wave_gen)); +} + +static void _ipu_di_data_pin_config(int di, int wave_gen, int di_pin, int set, + int up, int down) +{ + u32 reg; + + reg = __raw_readl(DI_DW_GEN(di, wave_gen)); + reg &= ~(0x3 << (di_pin * 2)); + reg |= set << (di_pin * 2); + __raw_writel(reg, DI_DW_GEN(di, wave_gen)); + + __raw_writel((down << 16) | up, DI_DW_SET(di, wave_gen, set)); +} + +static void _ipu_di_sync_config(int di, int wave_gen, + int run_count, int run_src, + int offset_count, int offset_src, + int repeat_count, int cnt_clr_src, + int cnt_polarity_gen_en, + int cnt_polarity_clr_src, + int cnt_polarity_trigger_src, + int cnt_up, int cnt_down) +{ + if ((run_count >= 0x1000) || (offset_count >= 0x1000) || (repeat_count >= 0x1000) || + (cnt_up >= 0x400) || (cnt_down >= 0x400)) { + dev_err(g_ipu_dev, "DI%d counters out of range.\n", di); + return; + } + + u32 reg; + reg = (run_count << 19) | (++run_src << 16) | + (offset_count << 3) | ++offset_src; + __raw_writel(reg, DI_SW_GEN0(di, wave_gen)); + reg = (cnt_polarity_gen_en << 29) | (++cnt_clr_src << 25) | + (++cnt_polarity_trigger_src << 12) | (++cnt_polarity_clr_src << 9); + reg |= (cnt_down << 16) | cnt_up; + if (repeat_count == 0) { + /* Enable auto reload */ + reg |= 0x10000000; + } + __raw_writel(reg, DI_SW_GEN1(di, wave_gen)); + reg = __raw_readl(DI_STP_REP(di, wave_gen)); + reg &= ~(0xFFFF << (16 * ((wave_gen - 1) & 0x1))); + reg |= repeat_count << (16 * ((wave_gen - 1) & 0x1)); + __raw_writel(reg, DI_STP_REP(di, wave_gen)); +} + +static void _ipu_dc_map_config(int map, int byte_num, int offset, int mask) +{ + int ptr = map * 3 + byte_num; + u32 reg; + + reg = __raw_readl(DC_MAP_CONF_VAL(ptr)); + reg &= ~(0xFFFF << (16 * (ptr & 0x1))); + reg |= ((offset << 8) | mask) << (16 * (ptr & 0x1)); + __raw_writel(reg, DC_MAP_CONF_VAL(ptr)); + + reg = __raw_readl(DC_MAP_CONF_PTR(map)); + reg &= ~(0x1F << ((16 * (map & 0x1)) + (5 * byte_num))); + reg |= ptr << ((16 * (map & 0x1)) + (5 * byte_num)); + __raw_writel(reg, DC_MAP_CONF_PTR(map)); +} + +static void _ipu_dc_map_clear(int map) +{ + u32 reg = __raw_readl(DC_MAP_CONF_PTR(map)); + __raw_writel(reg & ~(0xFFFF << (16 * (map & 0x1))), + DC_MAP_CONF_PTR(map)); +} + +static void _ipu_dc_write_tmpl(int word, u32 opcode, u32 operand, int map, + int wave, int glue, int sync) +{ + u32 reg; + int stop = 1; + + reg = sync; + reg |= (glue << 4); + reg |= (++wave << 11); + reg |= (++map << 15); + reg |= (operand << 20) & 0xFFF00000; + __raw_writel(reg, ipu_dc_tmpl_reg + word * 2); + + reg = (operand >> 12); + reg |= opcode << 4; + reg |= (stop << 9); + __raw_writel(reg, ipu_dc_tmpl_reg + word * 2 + 1); +} + +static void _ipu_dc_link_event(int chan, int event, int addr, int priority) +{ + u32 reg; + + reg = __raw_readl(DC_RL_CH(chan, event)); + reg &= ~(0xFFFF << (16 * (event & 0x1))); + reg |= ((addr << 8) | priority) << (16 * (event & 0x1)); + __raw_writel(reg, DC_RL_CH(chan, event)); +} + +/* Y = R * .299 + G * .587 + B * .114; + U = R * -.169 + G * -.332 + B * .500 + 128.; + V = R * .500 + G * -.419 + B * -.0813 + 128.;*/ +static const int rgb2ycbcr_coeff[5][3] = { + {153, 301, 58}, + {-87, -170, 0x0100}, + {0x100, -215, -42}, + {0x0000, 0x0200, 0x0200}, /* B0, B1, B2 */ + {0x2, 0x2, 0x2}, /* S0, S1, S2 */ +}; + +/* R = (1.164 * (Y - 16)) + (1.596 * (Cr - 128)); + G = (1.164 * (Y - 16)) - (0.392 * (Cb - 128)) - (0.813 * (Cr - 128)); + B = (1.164 * (Y - 16)) + (2.017 * (Cb - 128); */ +static const int ycbcr2rgb_coeff[5][3] = { + {0x095, 0x000, 0x0CC}, + {0x095, 0x3CE, 0x398}, + {0x095, 0x0FF, 0x000}, + {0x3E42, 0x010A, 0x3DD6}, /*B0,B1,B2 */ + {0x1, 0x1, 0x1}, /*S0,S1,S2 */ +}; + +#define mask_a(a) ((u32)(a) & 0x3FF) +#define mask_b(b) ((u32)(b) & 0x3FFF) + +static int _rgb_to_yuv(int n, int red, int green, int blue) +{ + int c; + c = red * rgb2ycbcr_coeff[n][0]; + c += green * rgb2ycbcr_coeff[n][1]; + c += blue * rgb2ycbcr_coeff[n][2]; + c /= 16; + c += rgb2ycbcr_coeff[3][n] * 4; + c += 8; + c /= 16; + if (c < 0) + c = 0; + if (c > 255) + c = 255; + return c; +} + +/* + * Row is for BG: RGB2YUV YUV2RGB RGB2RGB YUV2YUV CSC_NONE + * Column is for FG: RGB2YUV YUV2RGB RGB2RGB YUV2YUV CSC_NONE + */ +static struct dp_csc_param_t dp_csc_array[CSC_NUM][CSC_NUM] = { +{{DP_COM_CONF_CSC_DEF_BOTH, &rgb2ycbcr_coeff}, {0, 0}, {0, 0}, {DP_COM_CONF_CSC_DEF_BG, &rgb2ycbcr_coeff}, {DP_COM_CONF_CSC_DEF_BG, &rgb2ycbcr_coeff} }, +{{0, 0}, {DP_COM_CONF_CSC_DEF_BOTH, &ycbcr2rgb_coeff}, {DP_COM_CONF_CSC_DEF_BG, &ycbcr2rgb_coeff}, {0, 0}, {DP_COM_CONF_CSC_DEF_BG, &ycbcr2rgb_coeff} }, +{{0, 0}, {DP_COM_CONF_CSC_DEF_FG, &ycbcr2rgb_coeff}, {0, 0}, {0, 0}, {0, 0} }, +{{DP_COM_CONF_CSC_DEF_FG, &rgb2ycbcr_coeff}, {0, 0}, {0, 0}, {0, 0}, {0, 0} }, +{{DP_COM_CONF_CSC_DEF_FG, &rgb2ycbcr_coeff}, {DP_COM_CONF_CSC_DEF_FG, &ycbcr2rgb_coeff}, {0, 0}, {0, 0}, {0, 0} } +}; + +static enum csc_type_t fg_csc_type = CSC_NONE, bg_csc_type = CSC_NONE; + +void __ipu_dp_csc_setup(int dp, struct dp_csc_param_t dp_csc_param, + bool srm_mode_update) +{ + u32 reg; + const int (*coeff)[5][3]; + + if (dp_csc_param.mode >= 0) { + reg = __raw_readl(DP_COM_CONF(dp)); + reg &= ~DP_COM_CONF_CSC_DEF_MASK; + reg |= dp_csc_param.mode; + __raw_writel(reg, DP_COM_CONF(dp)); + } + + coeff = dp_csc_param.coeff; + + if (coeff) { + __raw_writel(mask_a((*coeff)[0][0]) | + (mask_a((*coeff)[0][1]) << 16), DP_CSC_A_0(dp)); + __raw_writel(mask_a((*coeff)[0][2]) | + (mask_a((*coeff)[1][0]) << 16), DP_CSC_A_1(dp)); + __raw_writel(mask_a((*coeff)[1][1]) | + (mask_a((*coeff)[1][2]) << 16), DP_CSC_A_2(dp)); + __raw_writel(mask_a((*coeff)[2][0]) | + (mask_a((*coeff)[2][1]) << 16), DP_CSC_A_3(dp)); + __raw_writel(mask_a((*coeff)[2][2]) | + (mask_b((*coeff)[3][0]) << 16) | + ((*coeff)[4][0] << 30), DP_CSC_0(dp)); + __raw_writel(mask_b((*coeff)[3][1]) | ((*coeff)[4][1] << 14) | + (mask_b((*coeff)[3][2]) << 16) | + ((*coeff)[4][2] << 30), DP_CSC_1(dp)); + } + + if (srm_mode_update) { + reg = __raw_readl(IPU_SRM_PRI2) | 0x8; + __raw_writel(reg, IPU_SRM_PRI2); + } +} + +int _ipu_dp_init(ipu_channel_t channel, uint32_t in_pixel_fmt, + uint32_t out_pixel_fmt) +{ + int in_fmt, out_fmt; + int dp; + int partial = false; + + if (channel == MEM_FG_SYNC) { + dp = DP_SYNC; + partial = true; + } else if (channel == MEM_BG_SYNC) { + dp = DP_SYNC; + partial = false; + } else if (channel == MEM_BG_ASYNC0) { + dp = DP_ASYNC0; + partial = false; + } else { + return -EINVAL; + } + + in_fmt = format_to_colorspace(in_pixel_fmt); + out_fmt = format_to_colorspace(out_pixel_fmt); + + if (partial) { + if (in_fmt == RGB) { + if (out_fmt == RGB) + fg_csc_type = RGB2RGB; + else + fg_csc_type = RGB2YUV; + } else { + if (out_fmt == RGB) + fg_csc_type = YUV2RGB; + else + fg_csc_type = YUV2YUV; + } + } else { + if (in_fmt == RGB) { + if (out_fmt == RGB) + bg_csc_type = RGB2RGB; + else + bg_csc_type = RGB2YUV; + } else { + if (out_fmt == RGB) + bg_csc_type = YUV2RGB; + else + bg_csc_type = YUV2YUV; + } + } + + __ipu_dp_csc_setup(dp, dp_csc_array[bg_csc_type][fg_csc_type], true); + + return 0; +} + +void _ipu_dp_uninit(ipu_channel_t channel) +{ + int dp; + int partial = false; + + if (channel == MEM_FG_SYNC) { + dp = DP_SYNC; + partial = true; + } else if (channel == MEM_BG_SYNC) { + dp = DP_SYNC; + partial = false; + } else if (channel == MEM_BG_ASYNC0) { + dp = DP_ASYNC0; + partial = false; + } else { + return; + } + + if (partial) + fg_csc_type = CSC_NONE; + else + bg_csc_type = CSC_NONE; + + __ipu_dp_csc_setup(dp, dp_csc_array[bg_csc_type][fg_csc_type], false); +} + +void _ipu_dc_init(int dc_chan, int di, bool interlaced) +{ + u32 reg = 0; + + if ((dc_chan == 1) || (dc_chan == 5)) { + if (interlaced) { + _ipu_dc_link_event(dc_chan, DC_EVT_NL, 0, 3); + _ipu_dc_link_event(dc_chan, DC_EVT_EOL, 0, 2); + _ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA, 0, 1); + } else { + _ipu_dc_link_event(dc_chan, DC_EVT_NL, 2, 3); + _ipu_dc_link_event(dc_chan, DC_EVT_EOL, 3, 2); + _ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA, 4, 1); + } + _ipu_dc_link_event(dc_chan, DC_EVT_NF, 0, 0); + _ipu_dc_link_event(dc_chan, DC_EVT_NFIELD, 0, 0); + _ipu_dc_link_event(dc_chan, DC_EVT_EOF, 0, 0); + _ipu_dc_link_event(dc_chan, DC_EVT_EOFIELD, 0, 0); + _ipu_dc_link_event(dc_chan, DC_EVT_NEW_CHAN, 0, 0); + _ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR, 0, 0); + + /* Make sure other DC sync channel is not assigned same DI */ + reg = __raw_readl(DC_WR_CH_CONF(6 - dc_chan)); + if ((di << 2) == (reg & DC_WR_CH_CONF_PROG_DI_ID)) { + reg &= ~DC_WR_CH_CONF_PROG_DI_ID; + reg |= di ? 0 : DC_WR_CH_CONF_PROG_DI_ID; + __raw_writel(reg, DC_WR_CH_CONF(6 - dc_chan)); + } + + reg = 0x2; + reg |= DC_DISP_ID_SYNC(di) << DC_WR_CH_CONF_PROG_DISP_ID_OFFSET; + reg |= di << 2; + if (interlaced) + reg |= DC_WR_CH_CONF_FIELD_MODE; + } else if ((dc_chan == 8) || (dc_chan == 9)) { + /* async channels */ + _ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA_W_0, 0x64, 1); + _ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA_W_1, 0x64, 1); + + reg = 0x3; + reg |= DC_DISP_ID_SERIAL << DC_WR_CH_CONF_PROG_DISP_ID_OFFSET; + } + __raw_writel(reg, DC_WR_CH_CONF(dc_chan)); + + __raw_writel(0x00000000, DC_WR_CH_ADDR(dc_chan)); + + __raw_writel(0x00000084, DC_GEN); +} + +void _ipu_dc_uninit(int dc_chan) +{ + if ((dc_chan == 1) || (dc_chan == 5)) { + _ipu_dc_link_event(dc_chan, DC_EVT_NL, 0, 0); + _ipu_dc_link_event(dc_chan, DC_EVT_EOL, 0, 0); + _ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA, 0, 0); + _ipu_dc_link_event(dc_chan, DC_EVT_NF, 0, 0); + _ipu_dc_link_event(dc_chan, DC_EVT_NFIELD, 0, 0); + _ipu_dc_link_event(dc_chan, DC_EVT_EOF, 0, 0); + _ipu_dc_link_event(dc_chan, DC_EVT_EOFIELD, 0, 0); + _ipu_dc_link_event(dc_chan, DC_EVT_NEW_CHAN, 0, 0); + _ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR, 0, 0); + } else if ((dc_chan == 8) || (dc_chan == 9)) { + _ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR_W_0, 0, 0); + _ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR_W_1, 0, 0); + _ipu_dc_link_event(dc_chan, DC_EVT_NEW_CHAN_W_0, 0, 0); + _ipu_dc_link_event(dc_chan, DC_EVT_NEW_CHAN_W_1, 0, 0); + _ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA_W_0, 0, 0); + _ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA_W_1, 0, 0); + _ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR_R_0, 0, 0); + _ipu_dc_link_event(dc_chan, DC_EVT_NEW_ADDR_R_1, 0, 0); + _ipu_dc_link_event(dc_chan, DC_EVT_NEW_CHAN_R_0, 0, 0); + _ipu_dc_link_event(dc_chan, DC_EVT_NEW_CHAN_R_1, 0, 0); + _ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA_R_0, 0, 0); + _ipu_dc_link_event(dc_chan, DC_EVT_NEW_DATA_R_1, 0, 0); + } +} + +int _ipu_chan_is_interlaced(ipu_channel_t channel) +{ + if (channel == MEM_DC_SYNC) + return !!(__raw_readl(DC_WR_CH_CONF_1) & + DC_WR_CH_CONF_FIELD_MODE); + else if ((channel == MEM_BG_SYNC) || (channel == MEM_FG_SYNC)) + return !!(__raw_readl(DC_WR_CH_CONF_5) & + DC_WR_CH_CONF_FIELD_MODE); + return 0; +} + +void _ipu_dp_dc_enable(ipu_channel_t channel) +{ + uint32_t reg; + uint32_t dc_chan; + int irq = 0; + + if (channel == MEM_FG_SYNC) + irq = IPU_IRQ_DP_SF_END; + else if (channel == MEM_DC_SYNC) + dc_chan = 1; + else if (channel == MEM_BG_SYNC) + dc_chan = 5; + else + return; + + if (channel == MEM_FG_SYNC) { + /* Enable FG channel */ + reg = __raw_readl(DP_COM_CONF(DP_SYNC)); + __raw_writel(reg | DP_COM_CONF_FG_EN, DP_COM_CONF(DP_SYNC)); + + return; + } + + reg = __raw_readl(DC_WR_CH_CONF(dc_chan)); + reg |= 4 << DC_WR_CH_CONF_PROG_TYPE_OFFSET; + __raw_writel(reg, DC_WR_CH_CONF(dc_chan)); + + reg = __raw_readl(IPU_DISP_GEN); + if (g_dc_di_assignment[dc_chan]) + reg |= DI1_COUNTER_RELEASE; + else + reg |= DI0_COUNTER_RELEASE; + __raw_writel(reg, IPU_DISP_GEN); +} + +static irqreturn_t dc_irq_handler(int irq, void *dev_id) +{ + u32 reg; + uint32_t dc_chan; + ipu_channel_t channel; + struct completion *comp = dev_id; + + if (irq == IPU_IRQ_DP_SF_END) { + channel = MEM_BG_SYNC; + dc_chan = 5; + } else if (irq == IPU_IRQ_DC_FC_1) { + channel = MEM_DC_SYNC; + dc_chan = 1; + } else { + return IRQ_HANDLED; + } + + reg = __raw_readl(IPU_DISP_GEN); + if (g_dc_di_assignment[dc_chan]) + reg &= ~DI1_COUNTER_RELEASE; + else + reg &= ~DI0_COUNTER_RELEASE; + __raw_writel(reg, IPU_DISP_GEN); + + reg = __raw_readl(DC_WR_CH_CONF(dc_chan)); + reg &= ~DC_WR_CH_CONF_PROG_TYPE_MASK; + __raw_writel(reg, DC_WR_CH_CONF(dc_chan)); + + if (__raw_readl(IPUIRQ_2_STATREG(IPU_IRQ_VSYNC_PRE_0 + g_dc_di_assignment[dc_chan])) & + IPUIRQ_2_MASK(IPU_IRQ_VSYNC_PRE_0 + g_dc_di_assignment[dc_chan])) + dev_err(g_ipu_dev, "VSyncPre occurred before DI%d disable\n", g_dc_di_assignment[dc_chan]); + + complete(comp); + return IRQ_HANDLED; +} + +void _ipu_dp_dc_disable(ipu_channel_t channel) +{ + int ret; + unsigned long lock_flags; + uint32_t reg; + uint32_t csc; + uint32_t dc_chan; + int irq = 0; + int timeout = 50; + DECLARE_COMPLETION_ONSTACK(dc_comp); + + if (channel == MEM_DC_SYNC) { + dc_chan = 1; + irq = IPU_IRQ_DC_FC_1; + } else if (channel == MEM_BG_SYNC) { + dc_chan = 5; + irq = IPU_IRQ_DP_SF_END; + } else if (channel == MEM_FG_SYNC) { + /* Disable FG channel */ + + spin_lock_irqsave(&ipu_lock, lock_flags); + + reg = __raw_readl(DP_COM_CONF(DP_SYNC)); + csc = reg & DP_COM_CONF_CSC_DEF_MASK; + if (csc == DP_COM_CONF_CSC_DEF_FG) + reg &= ~DP_COM_CONF_CSC_DEF_MASK; + + reg &= ~DP_COM_CONF_FG_EN; + __raw_writel(reg, DP_COM_CONF(DP_SYNC)); + + spin_unlock_irqrestore(&ipu_lock, lock_flags); + + __raw_writel(IPUIRQ_2_MASK(IPU_IRQ_DP_SF_END), + IPUIRQ_2_STATREG(IPU_IRQ_DP_SF_END)); + while ((__raw_readl(IPUIRQ_2_STATREG(IPU_IRQ_DP_SF_END)) & + IPUIRQ_2_MASK(IPU_IRQ_DP_SF_END)) == 0) { + msleep(2); + timeout -= 2; + if (timeout <= 0) + break; + } + return; + } else { + return; + } + + __raw_writel(IPUIRQ_2_MASK(IPU_IRQ_VSYNC_PRE_0 + g_dc_di_assignment[dc_chan]), + IPUIRQ_2_STATREG(IPU_IRQ_VSYNC_PRE_0 + g_dc_di_assignment[dc_chan])); + ipu_clear_irq(irq); + ret = ipu_request_irq(irq, dc_irq_handler, 0, NULL, &dc_comp); + if (ret < 0) { + dev_err(g_ipu_dev, "DC irq %d in use\n", irq); + return; + } + ret = wait_for_completion_timeout(&dc_comp, msecs_to_jiffies(50)); + + dev_dbg(g_ipu_dev, "DC stop timeout - %d * 10ms\n", 5 - ret); + ipu_free_irq(irq, &dc_comp); +} + +void _ipu_init_dc_mappings(void) +{ + /* IPU_PIX_FMT_RGB24 */ + _ipu_dc_map_clear(0); + _ipu_dc_map_config(0, 0, 7, 0xFF); + _ipu_dc_map_config(0, 1, 15, 0xFF); + _ipu_dc_map_config(0, 2, 23, 0xFF); + + /* IPU_PIX_FMT_RGB666 */ + _ipu_dc_map_clear(1); + _ipu_dc_map_config(1, 0, 5, 0xFC); + _ipu_dc_map_config(1, 1, 11, 0xFC); + _ipu_dc_map_config(1, 2, 17, 0xFC); + + /* IPU_PIX_FMT_YUV444 */ + _ipu_dc_map_clear(2); + _ipu_dc_map_config(2, 0, 15, 0xFF); + _ipu_dc_map_config(2, 1, 23, 0xFF); + _ipu_dc_map_config(2, 2, 7, 0xFF); + + /* IPU_PIX_FMT_RGB565 */ + _ipu_dc_map_clear(3); + _ipu_dc_map_config(3, 0, 4, 0xF8); + _ipu_dc_map_config(3, 1, 10, 0xFC); + _ipu_dc_map_config(3, 2, 15, 0xF8); + + /* IPU_PIX_FMT_LVDS666 */ + _ipu_dc_map_clear(4); + _ipu_dc_map_config(4, 0, 5, 0xFC); + _ipu_dc_map_config(4, 1, 13, 0xFC); + _ipu_dc_map_config(4, 2, 21, 0xFC); +} + +int _ipu_pixfmt_to_map(uint32_t fmt) +{ + switch (fmt) { + case IPU_PIX_FMT_GENERIC: + case IPU_PIX_FMT_RGB24: + return 0; + case IPU_PIX_FMT_RGB666: + return 1; + case IPU_PIX_FMT_YUV444: + return 2; + case IPU_PIX_FMT_RGB565: + return 3; + case IPU_PIX_FMT_LVDS666: + return 4; + } + + return -1; +} + +/*! + * This function sets the colorspace for of dp. + * modes. + * + * @param channel Input parameter for the logical channel ID. + * + * @param param If it's not NULL, update the csc table + * with this parameter. + * + * @return N/A + */ +void _ipu_dp_set_csc_coefficients(ipu_channel_t channel, int32_t param[][3]) +{ + int dp; + struct dp_csc_param_t dp_csc_param; + + if (channel == MEM_FG_SYNC) + dp = DP_SYNC; + else if (channel == MEM_BG_SYNC) + dp = DP_SYNC; + else if (channel == MEM_BG_ASYNC0) + dp = DP_ASYNC0; + else + return; + + dp_csc_param.mode = -1; + dp_csc_param.coeff = ¶m; + __ipu_dp_csc_setup(dp, dp_csc_param, true); +} + +/*! + * This function is called to initialize a synchronous LCD panel. + * + * @param disp The DI the panel is attached to. + * + * @param pixel_clk Desired pixel clock frequency in Hz. + * + * @param pixel_fmt Input parameter for pixel format of buffer. + * Pixel format is a FOURCC ASCII code. + * + * @param width The width of panel in pixels. + * + * @param height The height of panel in pixels. + * + * @param hStartWidth The number of pixel clocks between the HSYNC + * signal pulse and the start of valid data. + * + * @param hSyncWidth The width of the HSYNC signal in units of pixel + * clocks. + * + * @param hEndWidth The number of pixel clocks between the end of + * valid data and the HSYNC signal for next line. + * + * @param vStartWidth The number of lines between the VSYNC + * signal pulse and the start of valid data. + * + * @param vSyncWidth The width of the VSYNC signal in units of lines + * + * @param vEndWidth The number of lines between the end of valid + * data and the VSYNC signal for next frame. + * + * @param sig Bitfield of signal polarities for LCD interface. + * + * @return This function returns 0 on success or negative error code on + * fail. + */ +int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk, + uint16_t width, uint16_t height, + uint32_t pixel_fmt, + uint16_t h_start_width, uint16_t h_sync_width, + uint16_t h_end_width, uint16_t v_start_width, + uint16_t v_sync_width, uint16_t v_end_width, + uint32_t v_to_h_sync, ipu_di_signal_cfg_t sig) +{ + unsigned long lock_flags; + uint32_t field0_offset = 0; + uint32_t field1_offset; + uint32_t reg; + uint32_t disp_gen, di_gen, vsync_cnt; + uint32_t div; + uint32_t h_total, v_total; + int map; + struct clk *di_clk; + + dev_dbg(g_ipu_dev, "panel size = %d x %d\n", width, height); + + if ((v_sync_width == 0) || (h_sync_width == 0)) + return EINVAL; + + h_total = width + h_sync_width + h_start_width + h_end_width; + v_total = height + v_sync_width + v_start_width + v_end_width; + + /* Init clocking */ + dev_dbg(g_ipu_dev, "pixel clk = %d\n", pixel_clk); + if (sig.ext_clk) + di_clk = g_di_clk[disp]; + else + di_clk = g_ipu_clk; + + /* + * Calculate divider + * Fractional part is 4 bits, + * so simply multiply by 2^4 to get fractional part. + */ + div = (clk_get_rate(di_clk) * 16) / pixel_clk; + if (div < 0x10) /* Min DI disp clock divider is 1 */ + div = 0x10; + /* + * DI disp clock offset is zero, + * and fractional part is rounded off to 0.5. + */ + div &= 0xFF8; + + reg = __raw_readl(DI_GENERAL(disp)); + if (sig.ext_clk) + __raw_writel(reg | DI_GEN_DI_CLK_EXT, DI_GENERAL(disp)); + else + __raw_writel(reg & ~DI_GEN_DI_CLK_EXT, DI_GENERAL(disp)); + + spin_lock_irqsave(&ipu_lock, lock_flags); + + disp_gen = __raw_readl(IPU_DISP_GEN); + disp_gen &= disp ? ~DI1_COUNTER_RELEASE : ~DI0_COUNTER_RELEASE; + __raw_writel(disp_gen, IPU_DISP_GEN); + + __raw_writel(div, DI_BS_CLKGEN0(disp)); + + /* Setup pixel clock timing */ + /* FIXME: needs to be more flexible */ + /* Down time is half of period */ + __raw_writel((div / 16) << 16, DI_BS_CLKGEN1(disp)); + + _ipu_di_data_wave_config(disp, SYNC_WAVE, div / 16 - 1, div / 16 - 1); + _ipu_di_data_pin_config(disp, SYNC_WAVE, DI_PIN15, 3, 0, div / 16 * 2); + + div = div / 16; /* Now divider is integer portion */ + + map = _ipu_pixfmt_to_map(pixel_fmt); + if (map < 0) { + spin_unlock_irqrestore(&ipu_lock, lock_flags); + return -EINVAL; + } + + di_gen = 0; + if (sig.ext_clk) + di_gen |= DI_GEN_DI_CLK_EXT; + + /* Setup internal HSYNC waveform */ + _ipu_di_sync_config(disp, 1, h_total - 1, DI_SYNC_CLK, + 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, + DI_SYNC_NONE, 0, 0); + if (sig.interlaced) { + field1_offset = v_sync_width + v_start_width + height / 2 + + v_end_width; + if (sig.odd_field_first) { + field0_offset = field1_offset - 1; + field1_offset = 0; + } + v_total += v_start_width + v_end_width; + + /* Field 1 VSYNC waveform */ + _ipu_di_sync_config(disp, 2, v_total - 1, 1, + field0_offset, + field0_offset ? 1 : DI_SYNC_NONE, + 0, DI_SYNC_NONE, 0, + DI_SYNC_NONE, DI_SYNC_NONE, 0, 4); + + /* Setup internal HSYNC waveform */ + _ipu_di_sync_config(disp, 3, h_total - 1, DI_SYNC_CLK, + 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, 0, + DI_SYNC_NONE, DI_SYNC_NONE, 0, 4); + + /* Active Field ? */ + _ipu_di_sync_config(disp, 4, + field0_offset ? + field0_offset : field1_offset - 2, + 1, v_start_width + v_sync_width, 1, 2, 2, + 0, DI_SYNC_NONE, DI_SYNC_NONE, 0, 0); + + /* Active Line */ + _ipu_di_sync_config(disp, 5, 0, 1, + 0, DI_SYNC_NONE, + height / 2, 4, 0, DI_SYNC_NONE, + DI_SYNC_NONE, 0, 0); + + /* Field 0 VSYNC waveform */ + _ipu_di_sync_config(disp, 6, v_total - 1, 1, + 0, DI_SYNC_NONE, + 0, DI_SYNC_NONE, 0, DI_SYNC_NONE, + DI_SYNC_NONE, 0, 0); + + /* DC VSYNC waveform */ + vsync_cnt = 7; + _ipu_di_sync_config(disp, 7, 0, 1, + field1_offset, + field1_offset ? 1 : DI_SYNC_NONE, + 1, 2, 0, DI_SYNC_NONE, DI_SYNC_NONE, 0, 0); + + /* active pixel waveform */ + _ipu_di_sync_config(disp, 8, 0, DI_SYNC_CLK, + h_sync_width + h_start_width, DI_SYNC_CLK, + width, 5, 0, DI_SYNC_NONE, DI_SYNC_NONE, + 0, 0); + + /* ??? */ + _ipu_di_sync_config(disp, 9, v_total - 1, 2, + 0, DI_SYNC_NONE, + 0, DI_SYNC_NONE, 6, DI_SYNC_NONE, + DI_SYNC_NONE, 0, 0); + reg = __raw_readl(DI_SW_GEN1(disp, 9)); + reg |= 0x8000; + __raw_writel(reg, DI_SW_GEN1(disp, 9)); + + /* Init template microcode */ + _ipu_dc_write_tmpl(0, WROD(0), 0, map, SYNC_WAVE, 0, 8); + + __raw_writel(v_sync_width + v_start_width + + v_end_width + height / 2 - 1, DI_SCR_CONF(disp)); + + if (sig.Hsync_pol) + di_gen |= DI_GEN_POLARITY_3; + if (sig.Vsync_pol) + di_gen |= DI_GEN_POLARITY_2; + } else { + /* Setup external (delayed) HSYNC waveform */ + _ipu_di_sync_config(disp, DI_SYNC_HSYNC, h_total - 1, + DI_SYNC_CLK, div * v_to_h_sync, DI_SYNC_CLK, + 0, DI_SYNC_NONE, 1, DI_SYNC_NONE, + DI_SYNC_CLK, 0, h_sync_width * 2); + /* Setup VSYNC waveform */ + vsync_cnt = DI_SYNC_VSYNC; + _ipu_di_sync_config(disp, DI_SYNC_VSYNC, v_total - 1, + DI_SYNC_INT_HSYNC, 0, DI_SYNC_NONE, 0, + DI_SYNC_NONE, 1, DI_SYNC_NONE, + DI_SYNC_INT_HSYNC, 0, v_sync_width * 2); + __raw_writel(v_total - 1, DI_SCR_CONF(disp)); + + /* Setup active data waveform to sync with DC */ + _ipu_di_sync_config(disp, 4, 0, DI_SYNC_HSYNC, + v_start_width, DI_SYNC_HSYNC, height, + DI_SYNC_VSYNC, 0, DI_SYNC_NONE, + DI_SYNC_NONE, 0, 0); + _ipu_di_sync_config(disp, 5, 0, DI_SYNC_CLK, + h_sync_width + h_start_width, DI_SYNC_CLK, + width, 4, 0, DI_SYNC_NONE, DI_SYNC_NONE, 0, + 0); + + /* Init template microcode */ + _ipu_dc_write_tmpl(2, WROD(0), 0, map, SYNC_WAVE, 8, 5); + _ipu_dc_write_tmpl(3, WROD(0), 0, map, SYNC_WAVE, 4, 5); + _ipu_dc_write_tmpl(4, WROD(0), 0, map, SYNC_WAVE, 0, 5); + + if (sig.Hsync_pol) + di_gen |= DI_GEN_POLARITY_2; + if (sig.Vsync_pol) + di_gen |= DI_GEN_POLARITY_3; + } + + __raw_writel(di_gen, DI_GENERAL(disp)); + __raw_writel((--vsync_cnt << DI_VSYNC_SEL_OFFSET) | 0x00000002, + DI_SYNC_AS_GEN(disp)); + + reg = __raw_readl(DI_POL(disp)); + reg &= ~(DI_POL_DRDY_DATA_POLARITY | DI_POL_DRDY_POLARITY_15); + if (sig.enable_pol) + reg |= DI_POL_DRDY_POLARITY_15; + if (sig.data_pol) + reg |= DI_POL_DRDY_DATA_POLARITY; + __raw_writel(reg, DI_POL(disp)); + + __raw_writel(width, DC_DISP_CONF2(DC_DISP_ID_SYNC(disp))); + + spin_unlock_irqrestore(&ipu_lock, lock_flags); + + return 0; +} +EXPORT_SYMBOL(ipu_init_sync_panel); + + +int ipu_init_async_panel(int disp, int type, uint32_t cycle_time, + uint32_t pixel_fmt, ipu_adc_sig_cfg_t sig) +{ + unsigned long lock_flags; + int map; + u32 ser_conf = 0; + u32 div; + u32 di_clk = clk_get_rate(g_ipu_clk); + + /* round up cycle_time, then calcalate the divider using scaled math */ + cycle_time += (1000000000UL / di_clk) - 1; + div = (cycle_time * (di_clk / 256UL)) / (1000000000UL / 256UL); + + map = _ipu_pixfmt_to_map(pixel_fmt); + if (map < 0) + return -EINVAL; + + spin_lock_irqsave(&ipu_lock, lock_flags); + + if (type == IPU_PANEL_SERIAL) { + __raw_writel((div << 24) | ((sig.ifc_width - 1) << 4), + DI_DW_GEN(disp, ASYNC_SER_WAVE)); + + _ipu_di_data_pin_config(disp, ASYNC_SER_WAVE, DI_PIN_CS, + 0, 0, (div * 2) + 1); + _ipu_di_data_pin_config(disp, ASYNC_SER_WAVE, DI_PIN_SER_CLK, + 1, div, div * 2); + _ipu_di_data_pin_config(disp, ASYNC_SER_WAVE, DI_PIN_SER_RS, + 2, 0, 0); + + _ipu_dc_write_tmpl(0x64, WROD(0), 0, map, ASYNC_SER_WAVE, 0, 0); + + /* Configure DC for serial panel */ + __raw_writel(0x14, DC_DISP_CONF1(DC_DISP_ID_SERIAL)); + + if (sig.clk_pol) + ser_conf |= DI_SER_CONF_SERIAL_CLK_POL; + if (sig.data_pol) + ser_conf |= DI_SER_CONF_SERIAL_DATA_POL; + if (sig.rs_pol) + ser_conf |= DI_SER_CONF_SERIAL_RS_POL; + if (sig.cs_pol) + ser_conf |= DI_SER_CONF_SERIAL_CS_POL; + __raw_writel(ser_conf, DI_SER_CONF(disp)); + } + + spin_unlock_irqrestore(&ipu_lock, lock_flags); + return 0; +} +EXPORT_SYMBOL(ipu_init_async_panel); + +/*! + * This function sets the foreground and background plane global alpha blending + * modes. + * + * @param enable Boolean to enable or disable global alpha + * blending. If disabled, local blending is used. + * + * @param alpha Global alpha value. + * + * @return Returns 0 on success or negative error code on fail + */ +int32_t ipu_disp_set_global_alpha(ipu_channel_t channel, bool enable, + uint8_t alpha) +{ + uint32_t reg; + uint32_t flow; + unsigned long lock_flags; + + if (channel == MEM_BG_SYNC) + flow = DP_SYNC; + else if (channel == MEM_BG_ASYNC0) + flow = DP_ASYNC0; + else if (channel == MEM_BG_ASYNC1) + flow = DP_ASYNC1; + else + return -EINVAL; + + if (!g_ipu_clk_enabled) + clk_enable(g_ipu_clk); + spin_lock_irqsave(&ipu_lock, lock_flags); + + if (enable) { + reg = __raw_readl(DP_GRAPH_WIND_CTRL(flow)) & 0x00FFFFFFL; + __raw_writel(reg | ((uint32_t) alpha << 24), + DP_GRAPH_WIND_CTRL(flow)); + + reg = __raw_readl(DP_COM_CONF(flow)); + __raw_writel(reg | DP_COM_CONF_GWAM, DP_COM_CONF(flow)); + } else { + reg = __raw_readl(DP_COM_CONF(flow)); + __raw_writel(reg & ~DP_COM_CONF_GWAM, DP_COM_CONF(flow)); + } + + reg = __raw_readl(IPU_SRM_PRI2) | 0x8; + __raw_writel(reg, IPU_SRM_PRI2); + + spin_unlock_irqrestore(&ipu_lock, lock_flags); + if (!g_ipu_clk_enabled) + clk_disable(g_ipu_clk); + + return 0; +} +EXPORT_SYMBOL(ipu_disp_set_global_alpha); + +/*! + * This function sets the transparent color key for SDC graphic plane. + * + * @param channel Input parameter for the logical channel ID. + * + * @param enable Boolean to enable or disable color key + * + * @param colorKey 24-bit RGB color for transparent color key. + * + * @return Returns 0 on success or negative error code on fail + */ +int32_t ipu_disp_set_color_key(ipu_channel_t channel, bool enable, + uint32_t color_key) +{ + uint32_t reg, flow; + int y, u, v; + int red, green, blue; + unsigned long lock_flags; + + if (channel == MEM_BG_SYNC) + flow = DP_SYNC; + else if (channel == MEM_BG_ASYNC0) + flow = DP_ASYNC0; + else if (channel == MEM_BG_ASYNC1) + flow = DP_ASYNC1; + else + return -EINVAL; + + if (!g_ipu_clk_enabled) + clk_enable(g_ipu_clk); + + /* Transform color key from rgb to yuv if CSC is enabled */ + reg = __raw_readl(DP_COM_CONF(flow)); + if ((reg & DP_COM_CONF_CSC_DEF_MASK) == DP_COM_CONF_CSC_DEF_BG) { + red = (color_key >> 16) & 0xFF; + green = (color_key >> 8) & 0xFF; + blue = color_key & 0xFF; + + y = _rgb_to_yuv(0, red, green, blue); + u = _rgb_to_yuv(0, red, green, blue); + v = _rgb_to_yuv(0, red, green, blue); + color_key = (y << 16) | (u << 8) | v; + } + + spin_lock_irqsave(&ipu_lock, lock_flags); + + if (enable) { + reg = __raw_readl(DP_GRAPH_WIND_CTRL(flow)) & 0xFF000000L; + __raw_writel(reg | color_key, DP_GRAPH_WIND_CTRL(flow)); + + reg = __raw_readl(DP_COM_CONF(flow)); + __raw_writel(reg | DP_COM_CONF_GWCKE, DP_COM_CONF(flow)); + } else { + reg = __raw_readl(DP_COM_CONF(flow)); + __raw_writel(reg & ~DP_COM_CONF_GWCKE, DP_COM_CONF(flow)); + } + + reg = __raw_readl(IPU_SRM_PRI2) | 0x8; + __raw_writel(reg, IPU_SRM_PRI2); + + spin_unlock_irqrestore(&ipu_lock, lock_flags); + if (!g_ipu_clk_enabled) + clk_disable(g_ipu_clk); + + return 0; +} +EXPORT_SYMBOL(ipu_disp_set_color_key); + +/*! + * This function sets the window position of the foreground or background plane. + * modes. + * + * @param channel Input parameter for the logical channel ID. + * + * @param x_pos The X coordinate position to place window at. + * The position is relative to the top left corner. + * + * @param y_pos The Y coordinate position to place window at. + * The position is relative to the top left corner. + * + * @return Returns 0 on success or negative error code on fail + */ +int32_t ipu_disp_set_window_pos(ipu_channel_t channel, int16_t x_pos, + int16_t y_pos) +{ + u32 reg; + unsigned long lock_flags; + uint32_t flow = 0; + + if (channel == MEM_FG_SYNC) + flow = DP_SYNC; + else if (channel == MEM_FG_ASYNC0) + flow = DP_ASYNC0; + else if (channel == MEM_FG_ASYNC1) + flow = DP_ASYNC1; + else + return -EINVAL; + + if (!g_ipu_clk_enabled) + clk_enable(g_ipu_clk); + + spin_lock_irqsave(&ipu_lock, lock_flags); + + __raw_writel((x_pos << 16) | y_pos, DP_FG_POS(flow)); + + reg = __raw_readl(IPU_SRM_PRI2) | 0x8; + __raw_writel(reg, IPU_SRM_PRI2); + + spin_unlock_irqrestore(&ipu_lock, lock_flags); + if (!g_ipu_clk_enabled) + clk_disable(g_ipu_clk); + + return 0; +} +EXPORT_SYMBOL(ipu_disp_set_window_pos); + +void ipu_disp_direct_write(ipu_channel_t channel, u32 value, u32 offset) +{ + if (channel == DIRECT_ASYNC0) + __raw_writel(value, ipu_disp_base[0] + offset); + else if (channel == DIRECT_ASYNC1) + __raw_writel(value, ipu_disp_base[1] + offset); +} +EXPORT_SYMBOL(ipu_disp_direct_write); + +void ipu_reset_disp_panel(void) +{ + uint32_t tmp; + + tmp = __raw_readl(DI_GENERAL(1)); + __raw_writel(tmp | 0x08, DI_GENERAL(1)); + msleep(10); /* tRES >= 100us */ + tmp = __raw_readl(DI_GENERAL(1)); + __raw_writel(tmp & ~0x08, DI_GENERAL(1)); + msleep(60); + + return; +} +EXPORT_SYMBOL(ipu_reset_disp_panel); --- linux-2.6.28.orig/drivers/mxc/security/scc2_internals.h +++ linux-2.6.28/drivers/mxc/security/scc2_internals.h @@ -0,0 +1,527 @@ +/* + * Copyright 2004-2009 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 SCC_INTERNALS_H +#define SCC_INTERNALS_H + +/** @file scc2_internals.h + * + * @brief This is intended to be the file which contains most or all of the + * code or changes need to port the driver. It also includes other definitions + * needed by the driver. + * + * This header file should only ever be included by scc2_driver.c + * + * Compile-time flags minimally needed: + * + * @li Some sort of platform flag. Currently TAHITI and MXC are understood. + * @li Some start-of-SCC consideration, such as SCC_BASE_ADDR + * + * Some changes which could be made when porting this driver: + * #SCC_SPIN_COUNT + * + */ + +#include /* Current version Linux kernel */ +#include /* Basic support for loadable modules, + printk */ +#include /* module_init, module_exit */ +#include /* General kernel system calls */ +#include /* for interrupt.h */ +#include + +#include /* ioremap() */ +#include /* IRQ / interrupt definitions */ + + +#include + +#if defined(MXC) + +#include +#include + + +/** + * This macro is used to determine whether the SCC is enabled/available + * on the platform. This macro may need to be ported. + */ +#define SCC_FUSE IO_ADDRESS(IIM_BASE_ADDR + MXC_IIMHWV1) +#define SCC_ENABLED() ((SCC_FUSE & MXC_IIMHWV1_SCC_DISABLE) == 0) + +#else /* neither TAHITI nor MXC */ + +#error Do not understand target architecture + +#endif /* TAHITI */ +/** + * Define the number of Stored Keys which the SCC driver will make available. + * Value shall be from 0 to 20. Default is zero (0). + */ +/*#define SCC_KEY_SLOTS 20*/ + + +/* Temporarily define compile-time flags to make Doxygen happy. */ +#ifdef DOXYGEN_HACK +/** @addtogroup scccompileflags */ +/** @{ */ + + +/** @def NO_SMN_INTERRUPT + * The SMN interrupt is not wired to the CPU at all. + */ +#define NO_SMN_INTERRUPT + + +/** + * Register an interrupt handler for the SMN as well as + * the SCM. In some implementations, the SMN is not connected at all (see + * #NO_SMN_INTERRUPT), and in others, it is on the same interrupt line as the + * SCM. When defining this flag, the SMN interrupt should be on a separate + * line from the SCM interrupt. + */ + +#define USE_SMN_INTERRUPT + + +/** + * Turn on generation of run-time operational, debug, and error messages + */ +#define SCC_DEBUG + + +/** + * Turn on generation of run-time logging of access to the SCM and SMN + * registers. + */ +#define SCC_REGISTER_DEBUG + + +/** + * Turn on generation of run-time logging of access to the SCM Red and + * Black memories. Will only work if #SCC_REGISTER_DEBUG is also defined. + */ +#define SCC_RAM_DEBUG + + +/** + * If the driver finds the SCC in HEALTH_CHECK state, go ahead and + * run a quick ASC to bring it to SECURE state. + */ +#define SCC_BRINGUP + + +/** + * Expected to come from platform header files or compile command line. + * This symbol must be the address of the SCC + */ +#define SCC_BASE + +/** + * This must be the interrupt line number of the SCM interrupt. + */ +#define INT_SCM + +/** + * if #USE_SMN_INTERRUPT is defined, this must be the interrupt line number of + * the SMN interrupt. + */ +#define INT_SMN + +/** + * Define the number of Stored Keys which the SCC driver will make available. + * Value shall be from 0 to 20. Default is zero (0). + */ +#define SCC_KEY_SLOTS + +/** + * Make sure that this flag is defined if compiling for a Little-Endian + * platform. Linux Kernel builds provide this flag. + */ +#define __LITTLE_ENDIAN + +/** + * Make sure that this flag is defined if compiling for a Big-Endian platform. + * Linux Kernel builds provide this flag. + */ +#define __BIG_ENDIAN + +/** + * Read a 32-bit register value from a 'peripheral'. Standard Linux/Unix + * macro. + * + * @param offset Bus address of register to be read + * + * @return The value of the register + */ +#define readl(offset) + + +/** + * Write a 32-bit value to a register in a 'peripheral'. Standard Linux/Unix + * macro. + * + * @param value The 32-bit value to store + * @param offset Bus address of register to be written + * + * return (none) + */ +#define writel(value,offset) + + +/** @} */ /* end group scccompileflags */ + +#endif /* DOXYGEN_HACK */ + + +#ifndef SCC_KEY_SLOTS +#define SCC_KEY_SLOTS 0 + +#else + +#if (SCC_KEY_SLOTS < 0) || (SCC_KEY_SLOTS > 20) +#error Bad value for SCC_KEY_SLOTS +#endif + +#endif + + +/** + * Maximum length of key/secret value which can be stored in SCC. + */ +#define SCC_MAX_KEY_SIZE 256 + + +/** + * This is the size, in bytes, of each key slot, and therefore the maximum size + * of the wrapped key. + */ +#define SCC_KEY_SLOT_SIZE 32 + + +/* These come for free with Linux, but may need to be set in a port. */ +#ifndef __BIG_ENDIAN +#ifndef __LITTLE_ENDIAN +#error One of __LITTLE_ENDIAN or __BIG_ENDIAN must be #defined +#endif +#else +#ifdef __LITTLE_ENDIAN +#error Exactly one of __LITTLE_ENDIAN or __BIG_ENDIAN must be #defined +#endif +#endif + + +#ifndef SCC_CALLBACK_SIZE +/** The number of function pointers which can be stored in #scc_callbacks. + * Defaults to 4, can be overridden with compile-line argument. + */ +#define SCC_CALLBACK_SIZE 4 +#endif + + +/** Initial CRC value for CCITT-CRC calculation. */ +#define CRC_CCITT_START 0xFFFF + + +#ifdef TAHITI + +/** + * The SCC_BASE has to be SMN_BASE_ADDR on TAHITI, as the banks of + * registers are swapped in place. + */ +#define SCC_BASE SMN_BASE_ADDR + + +/** The interrupt number for the SCC (SCM only!) on Tahiti */ +#define INT_SCC_SCM 62 + + +/** Tahiti does not have the SMN interrupt wired to the CPU. */ +#define NO_SMN_INTERRUPT + + +#endif /* TAHITI */ + + +/** Number of times to spin between polling of SCC while waiting for cipher + * or zeroizing function to complete. See also #SCC_CIPHER_MAX_POLL_COUNT. */ +#define SCC_SPIN_COUNT 1000 + + +/** Number of times to polling SCC while waiting for cipher + * or zeroizing function to complete. See also #SCC_SPIN_COUNT. */ +#define SCC_CIPHER_MAX_POLL_COUNT 100 + + +/** + * @def SCC_READ_REGISTER + * Read a 32-bit value from an SCC register. Macro which depends upon + * #scc_base. Linux readl()/writel() macros operate on 32-bit quantities, as + * do SCC register reads/writes. + * + * @param offset Register offset within SCC. + * + * @return The value from the SCC's register. + */ +#ifndef SCC_REGISTER_DEBUG +#define SCC_READ_REGISTER(offset) __raw_readl(scc_base+(offset)) +#else +#define SCC_READ_REGISTER(offset) dbg_scc_read_register(offset) +#endif + + +/** + * Write a 32-bit value to an SCC register. Macro depends upon #scc_base. + * Linux readl()/writel() macros operate on 32-bit quantities, as do SCC + * register reads/writes. + * + * @param offset Register offset within SCC. + * @param value 32-bit value to store into the register + * + * @return (void) + */ +#ifndef SCC_REGISTER_DEBUG +#define SCC_WRITE_REGISTER(offset,value) \ + (void)__raw_writel(value, scc_base+(offset)) +#else +#define SCC_WRITE_REGISTER(offset,value) \ + dbg_scc_write_register(offset, value) +#endif + +/** + * Calculate the physical address of a partition from the partition number. + */ +#define SCM_PART_PHYS_ADDRESS(part) \ + ((uint32_t)scm_ram_phys_base + (part*scc_configuration.partition_size_bytes)) + +/** + * Calculate the kernel virtual address of a partition from the partition number. + */ +#define SCM_PART_ADDRESS(part) \ + (scm_ram_base + (part*scc_configuration.partition_size_bytes)) + +/** + * Calculate the partition number from the kernel virtual address. + */ +#define SCM_PART_NUMBER(address) \ + ((address - (uint32_t)scm_ram_base)/scc_configuration.partition_size_bytes) + +/** + * Calculates the byte offset into a word + * @param bp The byte (char*) pointer + * @return The offset (0, 1, 2, or 3) + */ +#define SCC_BYTE_OFFSET(bp) ((uint32_t)(bp) % sizeof(uint32_t)) + + +/** + * Converts (by rounding down) a byte pointer into a word pointer + * @param bp The byte (char*) pointer + * @return The word (uint32_t) as though it were an aligned (uint32_t*) + */ +#define SCC_WORD_PTR(bp) (((uint32_t)(bp)) & ~(sizeof(uint32_t)-1)) + + +/** + * Determine number of bytes in an SCC block + * + * @return Bytes / block + */ +#define SCC_BLOCK_SIZE_BYTES() scc_configuration.block_size_bytes + + +/** + * Maximum number of additional bytes which may be added in CRC+padding mode. + */ +#define PADDING_BUFFER_MAX_BYTES (CRC_SIZE_BYTES + sizeof(scc_block_padding)) + +/** + * Shorthand (clearer, anyway) for number of bytes in a CRC. + */ +#define CRC_SIZE_BYTES (sizeof(crc_t)) + +/** + * The polynomial used in CCITT-CRC calculation + */ +#define CRC_POLYNOMIAL 0x1021 + +/** + * Calculate CRC on one byte of data + * + * @param[in,out] running_crc A value of type crc_t where CRC is kept. This + * must be an rvalue and an lvalue. + * @param[in] byte_value The byte (uint8_t, char) to be put in the CRC + * + * @return none + */ +#define CALC_CRC(byte_value,running_crc) { \ + uint8_t data; \ + data = (0xff&(byte_value)) ^ (running_crc >> 8); \ + running_crc = scc_crc_lookup_table[data] ^ (running_crc << 8); \ +} + +/** Value of 'beginning of padding' marker in driver-provided padding */ +#define SCC_DRIVER_PAD_CHAR 0x80 + + +/** Name of the driver. Used (on Linux, anyway) when registering interrupts */ +#define SCC_DRIVER_NAME "scc" + + +/* Port -- these symbols are defined in Linux 2.6 and later. They are defined + * here for backwards compatibility because this started life as a 2.4 + * driver, and as a guide to portation to other platforms. + */ + +#if !defined(LINUX_VERSION_CODE) || LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + +#define irqreturn_t void /* Return type of an interrupt handler */ + +#define IRQ_HANDLED /* Would be '1' for handled -- as in return IRQ_HANDLED; */ + +#define IRQ_NONE /* would be '0' for not handled -- as in return IRQ_NONE; */ + +#define IRQ_RETVAL(x) /* Return x==0 (not handled) or non-zero (handled) */ + +#endif /* LINUX earlier than 2.5 */ + + +/* These are nice to have around */ +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + + +/** Provide a typedef for the CRC which can be used in encrypt/decrypt */ +typedef uint16_t crc_t; + + +/** Gives high-level view of state of the SCC */ +enum scc_status { + SCC_STATUS_INITIAL, /**< State of driver before ever checking */ + SCC_STATUS_CHECKING, /**< Transient state while driver loading */ + SCC_STATUS_UNIMPLEMENTED, /**< SCC is non-existent or unuseable */ + SCC_STATUS_OK, /**< SCC is in Secure or Default state */ + SCC_STATUS_FAILED /**< In Failed state */ +}; + +/** + * Information about a key slot. + */ +struct scc_key_slot +{ + uint64_t owner_id; /**< Access control value. */ + uint32_t length; /**< Length of value in slot. */ + uint32_t offset; /**< Offset of value from start of RAM. */ + uint32_t status; /**< 0 = unassigned, 1 = assigned. */ + uint32_t part_ctl; /**< for the CCMD register */ +}; + +/* Forward-declare a number routines which are not part of user api */ +static int scc_init(void); +static void scc_cleanup(void); + +/* Forward defines of internal functions */ +OS_DEV_ISR(scc_irq); +/*static irqreturn_t scc_irq(int irq, void *dev_id);*/ +/** Perform callbacks registered by #scc_monitor_security_failure(). + * + * Make sure callbacks only happen once... Since there may be some reason why + * the interrupt isn't generated, this routine could be called from base(task) + * level. + * + * One at a time, go through #scc_callbacks[] and call any non-null pointers. + */ +static void scc_perform_callbacks(void); +/*static uint32_t copy_to_scc(const uint8_t* from, uint32_t to, unsigned long count_bytes, uint16_t* crc); +static uint32_t copy_from_scc(const uint32_t from, uint8_t* to,unsigned long count_bytes, uint16_t* crc); +static scc_return_t scc_strip_padding(uint8_t* from,unsigned* count_bytes_stripped);*/ +static uint32_t scc_update_state(void); +static void scc_init_ccitt_crc(void); +static uint32_t scc_grab_config_values(void); +static int setup_interrupt_handling(void); +/** + * Perform an encryption on the input. If @c verify_crc is true, a CRC must be + * calculated on the plaintext, and appended, with padding, before computing + * the ciphertext. + * + * @param[in] count_in_bytes Count of bytes of plaintext + * @param[in] data_in Pointer to the plaintext + * @param[in] scm_control Bit values for the SCM_CONTROL register + * @param[in,out] data_out Pointer for storing ciphertext + * @param[in] add_crc Flag for computing CRC - 0 no, else yes + * @param[in,out] count_out_bytes Number of bytes available at @c data_out + */ +/*static scc_return_t scc_encrypt(uint32_t count_in_bytes, uint8_t* data_in, uint32_t scm_control, uint8_t* data_out,int add_crc, unsigned long* count_out_bytes);*/ +/** + * Perform a decryption on the input. If @c verify_crc is true, the last block + * (maybe the two last blocks) is special - it should contain a CRC and + * padding. These must be stripped and verified. + * + * @param[in] count_in_bytes Count of bytes of ciphertext + * @param[in] data_in Pointer to the ciphertext + * @param[in] scm_control Bit values for the SCM_CONTROL register + * @param[in,out] data_out Pointer for storing plaintext + * @param[in] verify_crc Flag for running CRC - 0 no, else yes + * @param[in,out] count_out_bytes Number of bytes available at @c data_out + + */ +/*static scc_return_t scc_decrypt(uint32_t count_in_bytes, uint8_t* data_in, uint32_t scm_control, uint8_t* data_out, int verify_crc, unsigned long* count_out_bytes);*/ +static uint32_t host_owns_partition(uint32_t part_no); +static uint32_t partition_engaged(uint32_t part_no); + +static scc_return_t scc_wait_completion(uint32_t* scm_status); +static int is_cipher_done(uint32_t* scm_status); +static scc_return_t check_register_accessible (uint32_t offset, + uint32_t smn_status, + uint32_t scm_status); +static scc_return_t check_register_offset(uint32_t offset); +/*uint8_t make_vpu_partition(void);*/ + +#ifdef SCC_REGISTER_DEBUG +static uint32_t dbg_scc_read_register(uint32_t offset); +static void dbg_scc_write_register(uint32_t offset, uint32_t value); +#endif + + +/* For Linux kernel, export the API functions to other kernel modules */ +EXPORT_SYMBOL(scc_get_configuration); +EXPORT_SYMBOL(scc_zeroize_memories); +/*EXPORT_SYMBOL(scc_crypt);*/ +EXPORT_SYMBOL(scc_set_sw_alarm); +EXPORT_SYMBOL(scc_monitor_security_failure); +EXPORT_SYMBOL(scc_stop_monitoring_security_failure); +EXPORT_SYMBOL(scc_read_register); +EXPORT_SYMBOL(scc_write_register); +EXPORT_SYMBOL(scc_allocate_partition); +EXPORT_SYMBOL(scc_engage_partition); +EXPORT_SYMBOL(scc_release_partition); +EXPORT_SYMBOL(scc_diminish_permissions); +EXPORT_SYMBOL(scc_encrypt_region); +EXPORT_SYMBOL(scc_decrypt_region); +/*EXPORT_SYMBOL(make_vpu_partition);*/ +/* Tell Linux where to invoke driver at boot/module load time */ +module_init(scc_init); +/* Tell Linux where to invoke driver on module unload */ +module_exit(scc_cleanup); + + +/* Tell Linux this is not GPL code */ +MODULE_LICENSE("Proprietary"); +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("Device Driver for SCC (SMN/SCM)"); + + +#endif /* SCC_INTERNALS_H */ --- linux-2.6.28.orig/drivers/mxc/security/scc2_driver.c +++ linux-2.6.28/drivers/mxc/security/scc2_driver.c @@ -0,0 +1,2261 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! @file scc2_driver.c + * + * This is the driver code for the Security Controller version 2 (SCC2). It's + * interaction with the Linux kernel is from calls to #scc_init() when the + * driver is loaded, and #scc_cleanup() should the driver be unloaded. The + * driver uses locking and (task-sleep/task-wakeup) functions from the kernel. + * It also registers itself to handle the interrupt line(s) from the SCC. New + * to this version of the driver is an interface providing access to the secure + * partitions. This is in turn exposed to the API user through the + * fsl_shw_smalloc() series of functions. Other drivers in the kernel may use + * the remaining API functions to get at the services of the SCC. The main + * service provided is the Secure Memory, which allows encoding and decoding of + * secrets with a per-chip secret key. + * + * The SCC is single-threaded, and so is this module. When the scc_crypt() + * routine is called, it will lock out other accesses to the function. If + * another task is already in the module, the subsequent caller will spin on a + * lock waiting for the other access to finish. + * + * Note that long crypto operations could cause a task to spin for a while, + * preventing other kernel work (other than interrupt processing) to get done. + * + * The external (kernel module) interface is through the following functions: + * @li scc_get_configuration() @li scc_crypt() @li scc_zeroize_memories() @li + * scc_monitor_security_failure() @li scc_stop_monitoring_security_failure() + * @li scc_set_sw_alarm() @li scc_read_register() @li scc_write_register() @li + * scc_allocate_partition() @li scc_initialize_partition @li + * scc_release_partition() @li scc_diminish_permissions @li + * scc_encrypt_region() @li scc_decrypt_region() @li scc_virt_to_phys + * + * All other functions are internal to the driver. + */ + +#include "scc2_internals.h" +#include "sahara2/include/portable_os.h" +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) + +#include +#include +#include + +#else + +#include +#include +#include + +#endif + +#include + +/** + * This is the set of errors which signal that access to the SCM RAM has + * failed or will fail. + */ +#define SCM_ACCESS_ERRORS \ + (SCM_ERRSTAT_ILM | SCM_ERRSTAT_SUP | SCM_ERRSTAT_ERC_MASK) + +/****************************************************************************** + * + * Global / Static Variables + * + *****************************************************************************/ + +#ifdef SCC_REGISTER_DEBUG + +#define REG_PRINT_BUFFER_SIZE 200 + +static char reg_print_buffer[REG_PRINT_BUFFER_SIZE]; + +typedef char *(*reg_print_routine_t) (uint32_t value, char *print_buffer, + int buf_size); + +#endif + +/** + * This is type void* so that a) it cannot directly be dereferenced, + * and b) pointer arithmetic on it will function in a 'normal way' for + * the offsets in scc_defines.h + * + * scc_base is the location in the iomap where the SCC's registers + * (and memory) start. + * + * The referenced data is declared volatile so that the compiler will + * not make any assumptions about the value of registers in the SCC, + * and thus will always reload the register into CPU memory before + * using it (i.e. wherever it is referenced in the driver). + * + * This value should only be referenced by the #SCC_READ_REGISTER and + * #SCC_WRITE_REGISTER macros and their ilk. All dereferences must be + * 32 bits wide. + */ +static volatile void *scc_base; + +/** Array to hold function pointers registered by + #scc_monitor_security_failure() and processed by + #scc_perform_callbacks() */ +static void (*scc_callbacks[SCC_CALLBACK_SIZE]) (void); +/*SCC need IRAM's base address but use only the partitions allocated for it.*/ +uint32_t scm_ram_phys_base = IRAM_BASE_ADDR; + +void *scm_ram_base = NULL; + +/** Calculated once for quick reference to size of the unreserved space in + * RAM in SCM. + */ +uint32_t scm_memory_size_bytes; + +/** Structure returned by #scc_get_configuration() */ +static scc_config_t scc_configuration = { + .driver_major_version = SCC_DRIVER_MAJOR_VERSION, + .driver_minor_version = SCC_DRIVER_MINOR_VERSION_2, + .scm_version = -1, + .smn_version = -1, + .block_size_bytes = -1, + .partition_size_bytes = -1, + .partition_count = -1, +}; + +/** Internal flag to know whether SCC is in Failed state (and thus many + * registers are unavailable). Once it goes failed, it never leaves it. */ +static volatile enum scc_status scc_availability = SCC_STATUS_INITIAL; + +/** Flag to say whether interrupt handler has been registered for + * SMN interrupt */ +static int smn_irq_set = 0; + +/** Flag to say whether interrupt handler has been registered for + * SCM interrupt */ +static int scm_irq_set = 0; + +/** This lock protects the #scc_callbacks list as well as the @c + * callbacks_performed flag in #scc_perform_callbacks. Since the data this + * protects may be read or written from either interrupt or base level, all + * operations should use the irqsave/irqrestore or similar to make sure that + * interrupts are inhibited when locking from base level. + */ +static os_lock_t scc_callbacks_lock = NULL; + +/** + * Ownership of this lock prevents conflicts on the crypto operation in the + * SCC. + */ +static os_lock_t scc_crypto_lock = NULL; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)) +/** Pointer to SCC's clock information. Initialized during scc_init(). */ +static struct clk *scc_clk = NULL; +#endif + +/** The lookup table for an 8-bit value. Calculated once + * by #scc_init_ccitt_crc(). + */ +static uint16_t scc_crc_lookup_table[256]; + +/****************************************************************************** + * + * Function Implementations - Externally Accessible + * + *****************************************************************************/ + +/** + * Allocate a partition of secure memory + * + * @param smid_value Value to use for the SMID register. Must be 0 for + * kernel mode access. + * @param[out] part_no (If successful) Assigned partition number. + * @param[out] part_base Kernel virtual address of the partition. + * @param[out] part_phys Physical address of the partition. + * + * @return + */ +scc_return_t scc_allocate_partition(uint32_t smid_value, + int *part_no, + void **part_base, uint32_t *part_phys) +{ + uint32_t i; + os_lock_context_t irq_flags = 0; /* for IRQ save/restore */ + int local_part; + scc_return_t retval = SCC_RET_FAIL; + void *base_addr = NULL; + uint32_t reg_value; + + local_part = -1; + + if (scc_availability == SCC_STATUS_INITIAL) { + scc_init(); + } + if (scc_availability == SCC_STATUS_UNIMPLEMENTED) { + goto out; + } + + /* ACQUIRE LOCK to prevent others from using crypto or acquiring a + * partition. Note that crypto operations could take a long time, so the + * calling process could potentially spin for some time. + */ + os_lock_save_context(scc_crypto_lock, irq_flags); + + do { + /* Find current state of partition ownership */ + reg_value = SCC_READ_REGISTER(SCM_PART_OWNERS_REG); + + /* Search for a free one */ + for (i = 0; i < scc_configuration.partition_count; i++) { + if (((reg_value >> (SCM_POWN_SHIFT * i)) + & SCM_POWN_MASK) == SCM_POWN_PART_FREE) { + break; /* found a free one */ + } + } + if (i == local_part) { + /* found this one last time, and failed to allocated it */ + pr_debug(KERN_ERR "Partition %d cannot be allocated\n", + i); + goto out; + } + if (i >= scc_configuration.partition_count) { + retval = SCC_RET_INSUFFICIENT_SPACE; /* all used up */ + goto out; + } + + pr_debug + ("SCC2: Attempting to allocate partition %i, owners:%08x\n", + i, SCC_READ_REGISTER(SCM_PART_OWNERS_REG)); + + local_part = i; + /* Store SMID to grab a partition */ + SCC_WRITE_REGISTER(SCM_SMID0_REG + + SCM_SMID_WIDTH * (local_part), smid_value); + mdelay(2); + + /* Now make sure it is ours... ? */ + reg_value = SCC_READ_REGISTER(SCM_PART_OWNERS_REG); + + if (((reg_value >> (SCM_POWN_SHIFT * (local_part))) + & SCM_POWN_MASK) != SCM_POWN_PART_OWNED) { + continue; /* try for another */ + } + base_addr = scm_ram_base + + (local_part * scc_configuration.partition_size_bytes); + break; + } while (1); + +out: + + /* Free the lock */ + os_unlock_restore_context(scc_callbacks_lock, irq_flags); + + /* If the base address was assigned, then a partition was successfully + * acquired. + */ + if (base_addr != NULL) { + pr_debug("SCC2 Part owners: %08x, engaged: %08x\n", + reg_value, SCC_READ_REGISTER(SCM_PART_ENGAGED_REG)); + pr_debug("SCC2 MAP for part %d: %08x\n", + local_part, + SCC_READ_REGISTER(SCM_ACC0_REG + 8 * local_part)); + + /* Copy the partition information to the data structures passed by the + * user. + */ + *part_no = local_part; + *part_base = base_addr; + *part_phys = (uint32_t) scm_ram_phys_base + + (local_part * scc_configuration.partition_size_bytes); + retval = SCC_RET_OK; + + pr_debug + ("SCC2 partition engaged. Kernel address: %p. Physical " + "address: %p, pfn: %08x\n", *part_base, (void *)*part_phys, + __phys_to_pfn(*part_phys)); + } + + return retval; +} /* allocate_partition() */ + +/** + * Release a partition of secure memory + * + * @param part_base Kernel virtual address of the partition to be released. + * + * @return SCC_RET_OK if successful. + */ +scc_return_t scc_release_partition(void *part_base) +{ + uint32_t partition_no; + + if (part_base == NULL) { + return SCC_RET_FAIL; + } + + /* Ensure that this is a proper partition location */ + partition_no = SCM_PART_NUMBER((uint32_t) part_base); + + pr_debug("SCC2: Attempting to release partition %i, owners:%08x\n", + partition_no, SCC_READ_REGISTER(SCM_PART_OWNERS_REG)); + + /* check that the partition is ours to de-establish */ + if (!host_owns_partition(partition_no)) { + return SCC_RET_FAIL; + } + + /* TODO: The state of the zeroize engine (SRS field in the Command Status + * Register) should be examined before issuing the zeroize command here. + * To make the driver thread-safe, a lock should be taken out before + * issuing the check and released after the zeroize command has been + * issued. + */ + + /* Zero the partition to release it */ + scc_write_register(SCM_ZCMD_REG, + (partition_no << SCM_ZCMD_PART_SHIFT) | + (ZCMD_DEALLOC_PART << SCM_ZCMD_CCMD_SHIFT)); + mdelay(2); + + pr_debug("SCC2: done releasing partition %i, owners:%08x\n", + partition_no, SCC_READ_REGISTER(SCM_PART_OWNERS_REG)); + + /* Check that the de-assignment went correctly */ + if (host_owns_partition(partition_no)) { + return SCC_RET_FAIL; + } + + return SCC_RET_OK; +} + +/** + * Diminish the permissions on a partition of secure memory + * + * @param part_base Kernel virtual address of the partition. + * @param permissions ORed values of the type SCM_PERM_* which will be used as + * initial partition permissions. SHW API users should use + * the FSL_PERM_* definitions instead. + * + * @return SCC_RET_OK if successful. + */ +scc_return_t scc_diminish_permissions(void *part_base, uint32_t permissions) +{ + uint32_t partition_no; + uint32_t permissions_requested; + permissions_requested = permissions; + + /* ensure that this is a proper partition location */ + partition_no = SCM_PART_NUMBER((uint32_t) part_base); + + /* invert the permissions, masking out unused bits */ + permissions = (~permissions) & SCM_PERM_MASK; + + /* attempt to diminish the permissions */ + scc_write_register(SCM_ACC0_REG + 8 * partition_no, permissions); + mdelay(2); + + /* Reading it back puts it into the original form */ + permissions = SCC_READ_REGISTER(SCM_ACC0_REG + 8 * partition_no); + if (permissions == permissions_requested) { + pr_debug("scc_partition_diminish_perms: successful\n"); + pr_debug("scc_partition_diminish_perms: successful\n"); + return SCC_RET_OK; + } + pr_debug("scc_partition_diminish_perms: not successful\n"); + + return SCC_RET_FAIL; +} + +extern scc_partition_status_t scc_partition_status(void *part_base) +{ + uint32_t part_no; + uint32_t part_owner; + + /* Determine the partition number from the address */ + part_no = SCM_PART_NUMBER((uint32_t) part_base); + + /* Check if the partition is implemented */ + if (part_no >= scc_configuration.partition_count) { + return SCC_PART_S_UNUSABLE; + } + + /* Determine the value of the partition owners register */ + part_owner = (SCC_READ_REGISTER(SCM_PART_OWNERS_REG) + >> (part_no * SCM_POWN_SHIFT)) & SCM_POWN_MASK; + + switch (part_owner) { + case SCM_POWN_PART_OTHER: + return SCC_PART_S_UNAVAILABLE; + break; + case SCM_POWN_PART_FREE: + return SCC_PART_S_AVAILABLE; + break; + case SCM_POWN_PART_OWNED: + /* could be allocated or engaged*/ + if (partition_engaged(part_no)) { + return SCC_PART_S_ENGAGED; + } else { + return SCC_PART_S_ALLOCATED; + } + break; + case SCM_POWN_PART_UNUSABLE: + default: + return SCC_PART_S_UNUSABLE; + break; + } +} + +/** + * Calculate the physical address from the kernel virtual address. + * + * @param address Kernel virtual address of data in an Secure Partition. + * @return Physical address of said data. + */ +uint32_t scc_virt_to_phys(void *address) +{ + return (uint32_t) address - (uint32_t) scm_ram_base + + (uint32_t) scm_ram_phys_base; +} + +/** + * Engage partition of secure memory + * + * @param part_base (kernel) Virtual + * @param UMID NULL, or 16-byte UMID for partition security + * @param permissions ORed values from fsl_shw_permission_t which + * will be used as initial partiition permissions. + * + * @return SCC_RET_OK if successful. + */ + +scc_return_t +scc_engage_partition(void *part_base, + const uint8_t *UMID, uint32_t permissions) +{ + uint32_t partition_no; + uint8_t *UMID_base = part_base + 0x10; + uint32_t *MAP_base = part_base; + uint8_t i; + + partition_no = SCM_PART_NUMBER((uint32_t) part_base); + + if (!host_owns_partition(partition_no) || + partition_engaged(partition_no) || + !(SCC_READ_REGISTER(SCM_SMID0_REG + (partition_no * 8)) == 0)) { + + return SCC_RET_FAIL; + } + + if (UMID != NULL) { + for (i = 0; i < 16; i++) { + UMID_base[i] = UMID[i]; + } + } + + MAP_base[0] = permissions; + + udelay(20); + + /* Check that the partition was engaged correctly, and that it has the + * proper permissions. + */ + + if ((!partition_engaged(partition_no)) || + (permissions != + SCC_READ_REGISTER(SCM_ACC0_REG + 8 * partition_no))) { + return SCC_RET_FAIL; + } + + return SCC_RET_OK; +} + +/*****************************************************************************/ +/* fn scc_init() */ +/*****************************************************************************/ +/** + * Initialize the driver at boot time or module load time. + * + * Register with the kernel as the interrupt handler for the SCC interrupt + * line(s). + * + * Map the SCC's register space into the driver's memory space. + * + * Query the SCC for its configuration and status. Save the configuration in + * #scc_configuration and save the status in #scc_availability. Called by the + * kernel. + * + * Do any locking/wait queue initialization which may be necessary. + * + * The availability fuse may be checked, depending on platform. + */ +static int scc_init(void) +{ + uint32_t smn_status; + int i; + int return_value = -EIO; /* assume error */ + + if (scc_availability == SCC_STATUS_INITIAL) { + + /* Set this until we get an initial reading */ + scc_availability = SCC_STATUS_CHECKING; + + /* Initialize the constant for the CRC function */ + scc_init_ccitt_crc(); + + /* initialize the callback table */ + for (i = 0; i < SCC_CALLBACK_SIZE; i++) { + scc_callbacks[i] = 0; + } + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) + mxc_clks_enable(SCC_CLK); +#else + scc_clk = clk_get(NULL, "scc_clk"); + if (scc_clk != ERR_PTR(ENOENT)) { + clk_enable(scc_clk); + } +#endif + + /* Set up the hardware access locks */ + scc_callbacks_lock = os_lock_alloc_init(); + scc_crypto_lock = os_lock_alloc_init(); + if (scc_callbacks_lock == NULL || scc_crypto_lock == NULL) { + os_printk(KERN_ERR + "SCC2: Failed to allocate context locks. Exiting.\n"); + goto out; + } + + /* See whether there is an SCC available */ + if (0 && !SCC_ENABLED()) { + os_printk(KERN_ERR + "SCC2: Fuse for SCC is set to disabled. Exiting.\n"); + goto out; + } + /* Map the SCC (SCM and SMN) memory on the internal bus into + kernel address space */ + scc_base = (void *)IO_ADDRESS(SCC_BASE); + if (scc_base == NULL) { + os_printk(KERN_ERR + "SCC2: Register mapping failed. Exiting.\n"); + goto out; + } + + /* If that worked, we can try to use the SCC */ + /* Get SCM into 'clean' condition w/interrupts cleared & + disabled */ + SCC_WRITE_REGISTER(SCM_INT_CTL_REG, 0); + + /* Clear error status register */ + (void)SCC_READ_REGISTER(SCM_ERR_STATUS_REG); + + /* + * There is an SCC. Determine its current state. Side effect + * is to populate scc_config and scc_availability + */ + smn_status = scc_grab_config_values(); + + /* Try to set up interrupt handler(s) */ + if (scc_availability != SCC_STATUS_OK) { + goto out; + } + + if (cpu_is_mx51_rev(CHIP_REV_2_0) < 0) + scm_ram_phys_base += 0x8000; + + scm_ram_base = (void *)ioremap_nocache(scm_ram_phys_base, + scc_configuration. + partition_count * + scc_configuration. + partition_size_bytes); + if (scm_ram_base == NULL) { + os_printk(KERN_ERR + "SCC2: RAM failed to remap: %p for %d bytes\n", + (void *)scm_ram_phys_base, + scc_configuration.partition_count * + scc_configuration.partition_size_bytes); + goto out; + } + pr_debug("SCC2: RAM at Physical %p / Virtual %p\n", + (void *)scm_ram_phys_base, scm_ram_base); + + pr_debug("Secure Partition Table: Found %i partitions\n", + scc_configuration.partition_count); + + if (setup_interrupt_handling() != 0) { + unsigned err_cond; + /** + * The error could be only that the SCM interrupt was + * not set up. This interrupt is always masked, so + * that is not an issue. + * The SMN's interrupt may be shared on that line, it + * may be separate, or it may not be wired. Do what + * is necessary to check its status. + * Although the driver is coded for possibility of not + * having SMN interrupt, the fact that there is one + * means it should be available and used. + */ +#ifdef USE_SMN_INTERRUPT + err_cond = !smn_irq_set; /* Separate. Check SMN binding */ +#elif !defined(NO_SMN_INTERRUPT) + err_cond = !scm_irq_set; /* Shared. Check SCM binding */ +#else + err_cond = FALSE; /* SMN not wired at all. Ignore. */ +#endif + if (err_cond) { + /* setup was not able to set up SMN interrupt */ + scc_availability = SCC_STATUS_UNIMPLEMENTED; + goto out; + } + } + + /* interrupt handling returned non-zero */ + /* Get SMN into 'clean' condition w/interrupts cleared & + enabled */ + SCC_WRITE_REGISTER(SMN_COMMAND_REG, + SMN_COMMAND_CLEAR_INTERRUPT + | SMN_COMMAND_ENABLE_INTERRUPT); + + out: + /* + * If status is SCC_STATUS_UNIMPLEMENTED or is still + * SCC_STATUS_CHECKING, could be leaving here with the driver partially + * initialized. In either case, cleanup (which will mark the SCC as + * UNIMPLEMENTED). + */ + if (scc_availability == SCC_STATUS_CHECKING || + scc_availability == SCC_STATUS_UNIMPLEMENTED) { + scc_cleanup(); + } else { + return_value = 0; /* All is well */ + } + } + /* ! STATUS_INITIAL */ + os_printk(KERN_ALERT "SCC2: Driver Status is %s\n", + (scc_availability == SCC_STATUS_INITIAL) ? "INITIAL" : + (scc_availability == SCC_STATUS_CHECKING) ? "CHECKING" : + (scc_availability == + SCC_STATUS_UNIMPLEMENTED) ? "UNIMPLEMENTED" + : (scc_availability == + SCC_STATUS_OK) ? "OK" : (scc_availability == + SCC_STATUS_FAILED) ? "FAILED" : + "UNKNOWN"); + + return return_value; +} /* scc_init */ + +/*****************************************************************************/ +/* fn scc_cleanup() */ +/*****************************************************************************/ +/** + * Perform cleanup before driver/module is unloaded by setting the machine + * state close to what it was when the driver was loaded. This function is + * called when the kernel is shutting down or when this driver is being + * unloaded. + * + * A driver like this should probably never be unloaded, especially if there + * are other module relying upon the callback feature for monitoring the SCC + * status. + * + * In any case, cleanup the callback table (by clearing out all of the + * pointers). Deregister the interrupt handler(s). Unmap SCC registers. + * + * Note that this will not release any partitions that have been allocated. + * + */ +static void scc_cleanup(void) +{ + int i; + + /******************************************************/ + + /* Mark the driver / SCC as unusable. */ + scc_availability = SCC_STATUS_UNIMPLEMENTED; + + /* Clear out callback table */ + for (i = 0; i < SCC_CALLBACK_SIZE; i++) { + scc_callbacks[i] = 0; + } + + /* If SCC has been mapped in, clean it up and unmap it */ + if (scc_base) { + /* For the SCM, disable interrupts. */ + SCC_WRITE_REGISTER(SCM_INT_CTL_REG, 0); + + /* For the SMN, clear and disable interrupts */ + SCC_WRITE_REGISTER(SMN_COMMAND_REG, + SMN_COMMAND_CLEAR_INTERRUPT); + } + + /* Now that interrupts cannot occur, disassociate driver from the interrupt + * lines. + */ + + /* Deregister SCM interrupt handler */ + if (scm_irq_set) { + os_deregister_interrupt(INT_SCC_SCM); + } + + /* Deregister SMN interrupt handler */ + if (smn_irq_set) { +#ifdef USE_SMN_INTERRUPT + os_deregister_interrupt(INT_SCC_SMN); +#endif + } + + /* Finally, release the mapped memory */ + iounmap(scm_ram_base); + + if (scc_callbacks_lock != NULL) + os_lock_deallocate(scc_callbacks_lock); + + if (scc_crypto_lock != NULL) + os_lock_deallocate(scc_crypto_lock); + + pr_debug("SCC2 driver cleaned up.\n"); + +} /* scc_cleanup */ + +/*****************************************************************************/ +/* fn scc_get_configuration() */ +/*****************************************************************************/ +scc_config_t *scc_get_configuration(void) +{ + /* + * If some other driver calls scc before the kernel does, make sure that + * this driver's initialization is performed. + */ + if (scc_availability == SCC_STATUS_INITIAL) { + scc_init(); + } + + /** + * If there is no SCC, yet the driver exists, the value -1 will be in + * the #scc_config_t fields for other than the driver versions. + */ + return &scc_configuration; +} /* scc_get_configuration */ + +/*****************************************************************************/ +/* fn scc_zeroize_memories() */ +/*****************************************************************************/ +scc_return_t scc_zeroize_memories(void) +{ + scc_return_t return_status = SCC_RET_FAIL; + + return return_status; +} /* scc_zeroize_memories */ + +/*****************************************************************************/ +/* fn scc_set_sw_alarm() */ +/*****************************************************************************/ +void scc_set_sw_alarm(void) +{ + + if (scc_availability == SCC_STATUS_INITIAL) { + scc_init(); + } + + /* Update scc_availability based on current SMN status. This might + * perform callbacks. + */ + (void)scc_update_state(); + + /* if everything is OK, make it fail */ + if (scc_availability == SCC_STATUS_OK) { + + /* sound the alarm (and disable SMN interrupts */ + SCC_WRITE_REGISTER(SMN_COMMAND_REG, + SMN_COMMAND_SET_SOFTWARE_ALARM); + + scc_availability = SCC_STATUS_FAILED; /* Remember what we've done */ + + /* In case SMN interrupt is not available, tell the world */ + scc_perform_callbacks(); + } + + return; +} /* scc_set_sw_alarm */ + +/*****************************************************************************/ +/* fn scc_monitor_security_failure() */ +/*****************************************************************************/ +scc_return_t scc_monitor_security_failure(void callback_func(void)) +{ + int i; + os_lock_context_t irq_flags; /* for IRQ save/restore */ + scc_return_t return_status = SCC_RET_TOO_MANY_FUNCTIONS; + int function_stored = FALSE; + + if (scc_availability == SCC_STATUS_INITIAL) { + scc_init(); + } + + /* Acquire lock of callbacks table. Could be spin_lock_irq() if this + * routine were just called from base (not interrupt) level + */ + os_lock_save_context(scc_callbacks_lock, irq_flags); + + /* Search through table looking for empty slot */ + for (i = 0; i < SCC_CALLBACK_SIZE; i++) { + if (scc_callbacks[i] == callback_func) { + if (function_stored) { + /* Saved duplicate earlier. Clear this later one. */ + scc_callbacks[i] = NULL; + } + /* Exactly one copy is now stored */ + return_status = SCC_RET_OK; + break; + } else if (scc_callbacks[i] == NULL && !function_stored) { + /* Found open slot. Save it and remember */ + scc_callbacks[i] = callback_func; + return_status = SCC_RET_OK; + function_stored = TRUE; + } + } + + /* Free the lock */ + os_unlock_restore_context(scc_callbacks_lock, irq_flags); + + return return_status; +} /* scc_monitor_security_failure */ + +/*****************************************************************************/ +/* fn scc_stop_monitoring_security_failure() */ +/*****************************************************************************/ +void scc_stop_monitoring_security_failure(void callback_func(void)) +{ + os_lock_context_t irq_flags; /* for IRQ save/restore */ + int i; + + if (scc_availability == SCC_STATUS_INITIAL) { + scc_init(); + } + + /* Acquire lock of callbacks table. Could be spin_lock_irq() if this + * routine were just called from base (not interrupt) level + */ + os_lock_save_context(scc_callbacks_lock, irq_flags); + + /* Search every entry of the table for this function */ + for (i = 0; i < SCC_CALLBACK_SIZE; i++) { + if (scc_callbacks[i] == callback_func) { + scc_callbacks[i] = NULL; /* found instance - clear it out */ + break; + } + } + + /* Free the lock */ + os_unlock_restore_context(scc_callbacks_lock, irq_flags); + + return; +} /* scc_stop_monitoring_security_failure */ + +/*****************************************************************************/ +/* fn scc_read_register() */ +/*****************************************************************************/ +scc_return_t scc_read_register(int register_offset, uint32_t * value) +{ + scc_return_t return_status = SCC_RET_FAIL; + uint32_t smn_status; + uint32_t scm_status; + + if (scc_availability == SCC_STATUS_INITIAL) { + scc_init(); + } + + /* First layer of protection -- completely unaccessible SCC */ + if (scc_availability != SCC_STATUS_UNIMPLEMENTED) { + + /* Second layer -- that offset is valid */ + if (register_offset != SMN_BB_DEC_REG && /* write only! */ + check_register_offset(register_offset) == SCC_RET_OK) { + + /* Get current status / update local state */ + smn_status = scc_update_state(); + scm_status = SCC_READ_REGISTER(SCM_STATUS_REG); + + /* + * Third layer - verify that the register being requested is + * available in the current state of the SCC. + */ + if ((return_status = + check_register_accessible(register_offset, + smn_status, + scm_status)) == + SCC_RET_OK) { + *value = SCC_READ_REGISTER(register_offset); + } + } + } + + return return_status; +} /* scc_read_register */ + +/*****************************************************************************/ +/* fn scc_write_register() */ +/*****************************************************************************/ +scc_return_t scc_write_register(int register_offset, uint32_t value) +{ + scc_return_t return_status = SCC_RET_FAIL; + uint32_t smn_status; + uint32_t scm_status; + + if (scc_availability == SCC_STATUS_INITIAL) { + scc_init(); + } + + /* First layer of protection -- completely unaccessible SCC */ + if (scc_availability != SCC_STATUS_UNIMPLEMENTED) { + + /* Second layer -- that offset is valid */ + if (!((register_offset == SCM_STATUS_REG) || /* These registers are */ + (register_offset == SCM_VERSION_REG) || /* Read Only */ + (register_offset == SMN_BB_CNT_REG) || + (register_offset == SMN_TIMER_REG)) && + check_register_offset(register_offset) == SCC_RET_OK) { + + /* Get current status / update local state */ + smn_status = scc_update_state(); + scm_status = SCC_READ_REGISTER(SCM_STATUS_REG); + + /* + * Third layer - verify that the register being requested is + * available in the current state of the SCC. + */ + if (check_register_accessible + (register_offset, smn_status, scm_status) == 0) { + SCC_WRITE_REGISTER(register_offset, value); + return_status = SCC_RET_OK; + } + } + } + + return return_status; +} /* scc_write_register() */ + +/****************************************************************************** + * + * Function Implementations - Internal + * + *****************************************************************************/ + +/*****************************************************************************/ +/* fn scc_irq() */ +/*****************************************************************************/ +/** + * This is the interrupt handler for the SCC. + * + * This function checks the SMN Status register to see whether it + * generated the interrupt, then it checks the SCM Status register to + * see whether it needs attention. + * + * If an SMN Interrupt is active, then the SCC state set to failure, and + * #scc_perform_callbacks() is invoked to notify any interested parties. + * + * The SCM Interrupt should be masked, as this driver uses polling to determine + * when the SCM has completed a crypto or zeroing operation. Therefore, if the + * interrupt is active, the driver will just clear the interrupt and (re)mask. + */ +OS_DEV_ISR(scc_irq) +{ + uint32_t smn_status; + uint32_t scm_status; + int handled = 0; /* assume interrupt isn't from SMN */ +#if defined(USE_SMN_INTERRUPT) + int smn_irq = INT_SCC_SMN; /* SMN interrupt is on a line by itself */ +#elif defined (NO_SMN_INTERRUPT) + int smn_irq = -1; /* not wired to CPU at all */ +#else + int smn_irq = INT_SCC_SCM; /* SMN interrupt shares a line with SCM */ +#endif + + /* Update current state... This will perform callbacks... */ + smn_status = scc_update_state(); + + /* SMN is on its own interrupt line. Verify the IRQ was triggered + * before clearing the interrupt and marking it handled. */ + if ((os_dev_get_irq() == smn_irq) && + (smn_status & SMN_STATUS_SMN_STATUS_IRQ)) { + SCC_WRITE_REGISTER(SMN_COMMAND_REG, + SMN_COMMAND_CLEAR_INTERRUPT); + handled++; /* tell kernel that interrupt was handled */ + } + + /* Check on the health of the SCM */ + scm_status = SCC_READ_REGISTER(SCM_STATUS_REG); + + /* The driver masks interrupts, so this should never happen. */ + if (os_dev_get_irq() == INT_SCC_SCM) { + /* but if it does, try to prevent it in the future */ + SCC_WRITE_REGISTER(SCM_INT_CTL_REG, 0); + handled++; + } + + /* Any non-zero value of handled lets kernel know we got something */ + os_dev_isr_return(handled); +} + +/*****************************************************************************/ +/* fn scc_perform_callbacks() */ +/*****************************************************************************/ +/** Perform callbacks registered by #scc_monitor_security_failure(). + * + * Make sure callbacks only happen once... Since there may be some reason why + * the interrupt isn't generated, this routine could be called from base(task) + * level. + * + * One at a time, go through #scc_callbacks[] and call any non-null pointers. + */ +static void scc_perform_callbacks(void) +{ + static int callbacks_performed = 0; + unsigned long irq_flags; /* for IRQ save/restore */ + int i; + + /* Acquire lock of callbacks table and callbacks_performed flag */ + os_lock_save_context(scc_callbacks_lock, irq_flags); + + if (!callbacks_performed) { + callbacks_performed = 1; + + /* Loop over all of the entries in the table */ + for (i = 0; i < SCC_CALLBACK_SIZE; i++) { + /* If not null, ... */ + if (scc_callbacks[i]) { + scc_callbacks[i] (); /* invoke the callback routine */ + } + } + } + + os_unlock_restore_context(scc_callbacks_lock, irq_flags); + + return; +} + +/*****************************************************************************/ +/* fn scc_update_state() */ +/*****************************************************************************/ +/** + * Make certain SCC is still running. + * + * Side effect is to update #scc_availability and, if the state goes to failed, + * run #scc_perform_callbacks(). + * + * (If #SCC_BRINGUP is defined, bring SCC to secure state if it is found to be + * in health check state) + * + * @return Current value of #SMN_STATUS_REG register. + */ +static uint32_t scc_update_state(void) +{ + uint32_t smn_status_register = SMN_STATE_FAIL; + int smn_state; + + /* if FAIL or UNIMPLEMENTED, don't bother */ + if (scc_availability == SCC_STATUS_CHECKING || + scc_availability == SCC_STATUS_OK) { + + smn_status_register = SCC_READ_REGISTER(SMN_STATUS_REG); + smn_state = smn_status_register & SMN_STATUS_STATE_MASK; + +#ifdef SCC_BRINGUP + /* If in Health Check while booting, try to 'bringup' to Secure mode */ + if (scc_availability == SCC_STATUS_CHECKING && + smn_state == SMN_STATE_HEALTH_CHECK) { + /* Code up a simple algorithm for the ASC */ + SCC_WRITE_REGISTER(SMN_SEQ_START_REG, 0xaaaa); + SCC_WRITE_REGISTER(SMN_SEQ_END_REG, 0x5555); + SCC_WRITE_REGISTER(SMN_SEQ_CHECK_REG, 0x5555); + /* State should be SECURE now */ + smn_status_register = SCC_READ_REGISTER(SMN_STATUS); + smn_state = smn_status_register & SMN_STATUS_STATE_MASK; + } +#endif + + /* + * State should be SECURE or NON_SECURE for operation of the part. If + * FAIL, mark failed (i.e. limited access to registers). Any other + * state, mark unimplemented, as the SCC is unuseable. + */ + if (smn_state == SMN_STATE_SECURE + || smn_state == SMN_STATE_NON_SECURE) { + /* Healthy */ + scc_availability = SCC_STATUS_OK; + } else if (smn_state == SMN_STATE_FAIL) { + scc_availability = SCC_STATUS_FAILED; /* uh oh - unhealthy */ + scc_perform_callbacks(); + os_printk(KERN_ERR "SCC2: SCC went into FAILED mode\n"); + } else { + /* START, ZEROIZE RAM, HEALTH CHECK, or unknown */ + scc_availability = SCC_STATUS_UNIMPLEMENTED; /* unuseable */ + os_printk(KERN_ERR + "SCC2: SCC declared UNIMPLEMENTED\n"); + } + } + /* if availability is initial or ok */ + return smn_status_register; +} + +/*****************************************************************************/ +/* fn scc_init_ccitt_crc() */ +/*****************************************************************************/ +/** + * Populate the partial CRC lookup table. + * + * @return none + * + */ +static void scc_init_ccitt_crc(void) +{ + int dividend; /* index for lookup table */ + uint16_t remainder; /* partial value for a given dividend */ + int bit; /* index into bits of a byte */ + + /* + * Compute the remainder of each possible dividend. + */ + for (dividend = 0; dividend < 256; ++dividend) { + /* + * Start with the dividend followed by zeros. + */ + remainder = dividend << (8); + + /* + * Perform modulo-2 division, a bit at a time. + */ + for (bit = 8; bit > 0; --bit) { + /* + * Try to divide the current data bit. + */ + if (remainder & 0x8000) { + remainder = (remainder << 1) ^ CRC_POLYNOMIAL; + } else { + remainder = (remainder << 1); + } + } + + /* + * Store the result into the table. + */ + scc_crc_lookup_table[dividend] = remainder; + } + +} /* scc_init_ccitt_crc() */ + +/*****************************************************************************/ +/* fn grab_config_values() */ +/*****************************************************************************/ +/** + * grab_config_values() will read the SCM Configuration and SMN Status + * registers and store away version and size information for later use. + * + * @return The current value of the SMN Status register. + */ +static uint32_t scc_grab_config_values(void) +{ + uint32_t scm_version_register; + uint32_t smn_status_register = SMN_STATE_FAIL; + + if (scc_availability != SCC_STATUS_CHECKING) { + goto out; + } + scm_version_register = SCC_READ_REGISTER(SCM_VERSION_REG); + pr_debug("SCC2 Driver: SCM version is 0x%08x\n", scm_version_register); + + /* Get SMN status and update scc_availability */ + smn_status_register = scc_update_state(); + pr_debug("SCC2 Driver: SMN status is 0x%08x\n", smn_status_register); + + /* save sizes and versions information for later use */ + scc_configuration.block_size_bytes = 16; /* BPCP ? */ + scc_configuration.partition_count = + 1 + ((scm_version_register & SCM_VER_NP_MASK) >> SCM_VER_NP_SHIFT); + scc_configuration.partition_size_bytes = + 1 << ((scm_version_register & SCM_VER_BPP_MASK) >> + SCM_VER_BPP_SHIFT); + scc_configuration.scm_version = + (scm_version_register & SCM_VER_MAJ_MASK) >> SCM_VER_MAJ_SHIFT; + scc_configuration.smn_version = + (smn_status_register & SMN_STATUS_VERSION_ID_MASK) + >> SMN_STATUS_VERSION_ID_SHIFT; + if (scc_configuration.scm_version != SCM_MAJOR_VERSION_2) { + scc_availability = SCC_STATUS_UNIMPLEMENTED; /* Unknown version */ + } + + out: + return smn_status_register; +} /* grab_config_values */ + +/*****************************************************************************/ +/* fn setup_interrupt_handling() */ +/*****************************************************************************/ +/** + * Register the SCM and SMN interrupt handlers. + * + * Called from #scc_init() + * + * @return 0 on success + */ +static int setup_interrupt_handling(void) +{ + int smn_error_code = -1; + int scm_error_code = -1; + + /* Disnable SCM interrupts */ + SCC_WRITE_REGISTER(SCM_INT_CTL_REG, 0); + +#ifdef USE_SMN_INTERRUPT + /* Install interrupt service routine for SMN. */ + smn_error_code = os_register_interrupt(SCC_DRIVER_NAME, + INT_SCC_SMN, scc_irq); + if (smn_error_code != 0) { + os_printk(KERN_ERR + "SCC2 Driver: Error installing SMN Interrupt Handler: %d\n", + smn_error_code); + } else { + smn_irq_set = 1; /* remember this for cleanup */ + /* Enable SMN interrupts */ + SCC_WRITE_REGISTER(SMN_COMMAND_REG, + SMN_COMMAND_CLEAR_INTERRUPT | + SMN_COMMAND_ENABLE_INTERRUPT); + } +#else + smn_error_code = 0; /* no problems... will handle later */ +#endif + + /* + * Install interrupt service routine for SCM (or both together). + */ + scm_error_code = os_register_interrupt(SCC_DRIVER_NAME, + INT_SCC_SCM, scc_irq); + if (scm_error_code != 0) { +#ifndef MXC + os_printk(KERN_ERR + "SCC2 Driver: Error installing SCM Interrupt Handler: %d\n", + scm_error_code); +#else + os_printk(KERN_ERR + "SCC2 Driver: Error installing SCC Interrupt Handler: %d\n", + scm_error_code); +#endif + } else { + scm_irq_set = 1; /* remember this for cleanup */ +#if defined(USE_SMN_INTERRUPT) && !defined(NO_SMN_INTERRUPT) + /* Enable SMN interrupts */ + SCC_WRITE_REGISTER(SMN_COMMAND_REG, + SMN_COMMAND_CLEAR_INTERRUPT | + SMN_COMMAND_ENABLE_INTERRUPT); +#endif + } + + /* Return an error if one was encountered */ + return scm_error_code ? scm_error_code : smn_error_code; +} /* setup_interrupt_handling */ + +/*****************************************************************************/ +/* fn scc_do_crypto() */ +/*****************************************************************************/ +/** Have the SCM perform the crypto function. + * + * Set up length register, and the store @c scm_control into control register + * to kick off the operation. Wait for completion, gather status, clear + * interrupt / status. + * + * @param byte_count number of bytes to perform in this operation + * @param scm_command Bit values to be set in @c SCM_CCMD_REG register + * + * @return 0 on success, value of #SCM_ERR_STATUS_REG on failure + */ +static uint32_t scc_do_crypto(int byte_count, uint32_t scm_command) +{ + int block_count = byte_count / SCC_BLOCK_SIZE_BYTES(); + uint32_t crypto_status; + scc_return_t ret; + + /* This seems to be necessary in order to allow subsequent cipher + * operations to succeed when a partition is deallocated/reallocated! + */ + (void)SCC_READ_REGISTER(SCM_STATUS_REG); + + /* In length register, 0 means 1, etc. */ + scm_command |= (block_count - 1) << SCM_CCMD_LENGTH_SHIFT; + + /* set modes and kick off the operation */ + SCC_WRITE_REGISTER(SCM_CCMD_REG, scm_command); + + ret = scc_wait_completion(&crypto_status); + + /* Only done bit should be on */ + if (crypto_status & SCM_STATUS_ERR) { + /* Replace with error status instead */ + crypto_status = SCC_READ_REGISTER(SCM_ERR_STATUS_REG); + pr_debug("SCM Failure: 0x%x\n", crypto_status); + if (crypto_status == 0) { + /* That came up 0. Turn on arbitrary bit to signal error. */ + crypto_status = SCM_ERRSTAT_ILM; + } + } else { + crypto_status = 0; + } + pr_debug("SCC2: Done waiting.\n"); + + return crypto_status; +} + +/** + * Encrypt a region of secure memory. + * + * @param part_base Kernel virtual address of the partition. + * @param offset_bytes Offset from the start of the partition to the plaintext + * data. + * @param byte_count Length of the region (octets). + * @param black_data Physical location to store the encrypted data. + * @param IV Value to use for the IV. + * @param cypher_mode Cyphering mode to use, specified by type + * #scc_cypher_mode_t + * + * @return SCC_RET_OK if successful. + */ +scc_return_t +scc_encrypt_region(uint32_t part_base, uint32_t offset_bytes, + uint32_t byte_count, uint8_t *black_data, + uint32_t *IV, scc_cypher_mode_t cypher_mode) +{ + os_lock_context_t irq_flags; /* for IRQ save/restore */ + scc_return_t status = SCC_RET_OK; + uint32_t crypto_status; + uint32_t scm_command; + int offset_blocks = offset_bytes / SCC_BLOCK_SIZE_BYTES(); + + scm_command = ((offset_blocks << SCM_CCMD_OFFSET_SHIFT) | + (SCM_PART_NUMBER(part_base) << SCM_CCMD_PART_SHIFT)); + + switch (cypher_mode) { + case SCC_CYPHER_MODE_CBC: + scm_command |= SCM_CCMD_AES_ENC_CBC; + break; + case SCC_CYPHER_MODE_ECB: + scm_command |= SCM_CCMD_AES_ENC_ECB; + break; + default: + status = SCC_RET_FAIL; + break; + } + + pr_debug("Received encrypt request. SCM_C_BLACK_ST_REG: %p, " + "scm_Command: %08x, length: %i (part_base: %08x, " + "offset: %i)\n", + black_data, scm_command, byte_count, part_base, offset_blocks); + + if (status != SCC_RET_OK) + goto out; + + /* ACQUIRE LOCK to prevent others from using crypto or releasing slot */ + os_lock_save_context(scc_crypto_lock, irq_flags); + + if (status == SCC_RET_OK) { + SCC_WRITE_REGISTER(SCM_C_BLACK_ST_REG, (uint32_t) black_data); + + /* Only write the IV if it will actually be used */ + if (cypher_mode == SCC_CYPHER_MODE_CBC) { + /* Write the IV register */ + SCC_WRITE_REGISTER(SCM_AES_CBC_IV0_REG, *(IV)); + SCC_WRITE_REGISTER(SCM_AES_CBC_IV1_REG, *(IV + 1)); + SCC_WRITE_REGISTER(SCM_AES_CBC_IV2_REG, *(IV + 2)); + SCC_WRITE_REGISTER(SCM_AES_CBC_IV3_REG, *(IV + 3)); + } + + /* Set modes and kick off the encryption */ + crypto_status = scc_do_crypto(byte_count, scm_command); + + if (crypto_status != 0) { + pr_debug("SCM encrypt red crypto failure: 0x%x\n", + crypto_status); + } else { + status = SCC_RET_OK; + pr_debug("SCC2: Encrypted %d bytes\n", byte_count); + } + } + + os_unlock_restore_context(scc_crypto_lock, irq_flags); +out: + return status; +} + +/* Decrypt a region into secure memory + * + * @param part_base Kernel virtual address of the partition. + * @param offset_bytes Offset from the start of the partition to store the + * plaintext data. + * @param byte_counts Length of the region (octets). + * @param black_data Physical location of the encrypted data. + * @param IV Value to use for the IV. + * @param cypher_mode Cyphering mode to use, specified by type + * #scc_cypher_mode_t + * + * @return SCC_RET_OK if successful. + */ +scc_return_t +scc_decrypt_region(uint32_t part_base, uint32_t offset_bytes, + uint32_t byte_count, uint8_t *black_data, + uint32_t *IV, scc_cypher_mode_t cypher_mode) +{ + os_lock_context_t irq_flags; /* for IRQ save/restore */ + scc_return_t status = SCC_RET_OK; + uint32_t crypto_status; + uint32_t scm_command; + int offset_blocks = offset_bytes / SCC_BLOCK_SIZE_BYTES(); + + scm_command = ((offset_blocks << SCM_CCMD_OFFSET_SHIFT) | + (SCM_PART_NUMBER(part_base) << SCM_CCMD_PART_SHIFT)); + + switch (cypher_mode) { + case SCC_CYPHER_MODE_CBC: + scm_command |= SCM_CCMD_AES_DEC_CBC; + break; + case SCC_CYPHER_MODE_ECB: + scm_command |= SCM_CCMD_AES_DEC_ECB; + break; + default: + status = SCC_RET_FAIL; + break; + } + + pr_debug("Received decrypt request. SCM_C_BLACK_ST_REG: %p, " + "scm_Command: %08x, length: %i (part_base: %08x, " + "offset: %i)\n", + black_data, scm_command, byte_count, part_base, offset_blocks); + + if (status != SCC_RET_OK) + goto out; + + /* ACQUIRE LOCK to prevent others from using crypto or releasing slot */ + os_lock_save_context(scc_crypto_lock, irq_flags); + + if (status == SCC_RET_OK) { + status = SCC_RET_FAIL; /* reset expectations */ + SCC_WRITE_REGISTER(SCM_C_BLACK_ST_REG, (uint32_t) black_data); + + /* Write the IV register */ + SCC_WRITE_REGISTER(SCM_AES_CBC_IV0_REG, *(IV)); + SCC_WRITE_REGISTER(SCM_AES_CBC_IV1_REG, *(IV + 1)); + SCC_WRITE_REGISTER(SCM_AES_CBC_IV2_REG, *(IV + 2)); + SCC_WRITE_REGISTER(SCM_AES_CBC_IV3_REG, *(IV + 3)); + + /* Set modes and kick off the decryption */ + crypto_status = scc_do_crypto(byte_count, scm_command); + + if (crypto_status != 0) { + pr_debug("SCM decrypt black crypto failure: 0x%x\n", + crypto_status); + } else { + status = SCC_RET_OK; + pr_debug("SCC2: Decrypted %d bytes\n", byte_count); + } + } + + os_unlock_restore_context(scc_crypto_lock, irq_flags); +out: + return status; +} + +/*****************************************************************************/ +/* fn host_owns_partition() */ +/*****************************************************************************/ +/** + * Determine if the host owns a given partition. + * + * @internal + * + * @param part_no Partition number to query + * + * @return TRUE if the host owns the partition, FALSE otherwise. + */ + +static uint32_t host_owns_partition(uint32_t part_no) +{ + uint32_t value; + + if (part_no < scc_configuration.partition_count) { + + /* Check the partition owners register */ + value = SCC_READ_REGISTER(SCM_PART_OWNERS_REG); + if (((value >> (part_no * SCM_POWN_SHIFT)) & SCM_POWN_MASK) + == SCM_POWN_PART_OWNED) + return TRUE; + } + return FALSE; +} + +/*****************************************************************************/ +/* fn partition_engaged() */ +/*****************************************************************************/ +/** + * Determine if the given partition is engaged. + * + * @internal + * + * @param part_no Partition number to query + * + * @return TRUE if the partition is engaged, FALSE otherwise. + */ + +static uint32_t partition_engaged(uint32_t part_no) +{ + uint32_t value; + + if (part_no < scc_configuration.partition_count) { + + /* Check the partition engaged register */ + value = SCC_READ_REGISTER(SCM_PART_ENGAGED_REG); + if (((value >> (part_no * SCM_PENG_SHIFT)) & 0x1) + == SCM_PENG_ENGAGED) + return TRUE; + } + return FALSE; +} + +/*****************************************************************************/ +/* fn scc_wait_completion() */ +/*****************************************************************************/ +/** + * Poll looking for end-of-cipher indication. Only used + * if @c SCC_SCM_SLEEP is not defined. + * + * @internal + * + * On a Tahiti, crypto under 230 or so bytes is done after the first loop, all + * the way up to five sets of spins for 1024 bytes. (8- and 16-byte functions + * are done when we first look. Zeroizing takes one pass around. + * + * @param scm_status Address of the SCM_STATUS register + * + * @return A return code of type #scc_return_t + */ +static scc_return_t scc_wait_completion(uint32_t * scm_status) +{ + scc_return_t ret; + int done; + int i = 0; + + /* check for completion by polling */ + do { + done = is_cipher_done(scm_status); + if (done) + break; + /* TODO: shorten this delay */ + udelay(1000); + } while (i++ < SCC_CIPHER_MAX_POLL_COUNT); + + pr_debug("SCC2: Polled DONE %d times\n", i); + if (!done) { + ret = SCC_RET_FAIL; + } + + return ret; +} /* scc_wait_completion() */ + +/*****************************************************************************/ +/* fn is_cipher_done() */ +/*****************************************************************************/ +/** + * This function returns non-zero if SCM Status register indicates + * that a cipher has terminated or some other interrupt-generating + * condition has occurred. + * + * @param scm_status Address of the SCM STATUS register + * + * @return 0 if cipher operations are finished + */ +static int is_cipher_done(uint32_t * scm_status) +{ + register unsigned status; + register int cipher_done; + + *scm_status = SCC_READ_REGISTER(SCM_STATUS_REG); + status = (*scm_status & SCM_STATUS_SRS_MASK) >> SCM_STATUS_SRS_SHIFT; + + /* + * Done when SCM is not in 'currently performing a function' states. + */ + cipher_done = ((status != SCM_STATUS_SRS_ZBUSY) + && (status != SCM_STATUS_SRS_CBUSY) + && (status != SCM_STATUS_SRS_ABUSY)); + + return cipher_done; +} /* is_cipher_done() */ + +/*****************************************************************************/ +/* fn offset_within_smn() */ +/*****************************************************************************/ +/*! + * Check that the offset is with the bounds of the SMN register set. + * + * @param[in] register_offset register offset of SMN. + * + * @return 1 if true, 0 if false (not within SMN) + */ +static inline int offset_within_smn(uint32_t register_offset) +{ + return ((register_offset >= SMN_STATUS_REG) + && (register_offset <= SMN_HAC_REG)); +} + +/*****************************************************************************/ +/* fn offset_within_scm() */ +/*****************************************************************************/ +/*! + * Check that the offset is with the bounds of the SCM register set. + * + * @param[in] register_offset Register offset of SCM + * + * @return 1 if true, 0 if false (not within SCM) + */ +static inline int offset_within_scm(uint32_t register_offset) +{ + return 1; /* (register_offset >= SCM_RED_START) + && (register_offset < scm_highest_memory_address); */ +/* Although this would cause trouble for zeroize testing, this change would + * close a security hole which currently allows any kernel program to access + * any location in RED RAM. Perhaps enforce in non-SCC_DEBUG compiles? + && (register_offset <= SCM_INIT_VECTOR_1); */ +} + +/*****************************************************************************/ +/* fn check_register_accessible() */ +/*****************************************************************************/ +/** + * Given the current SCM and SMN status, verify that access to the requested + * register should be OK. + * + * @param[in] register_offset register offset within SCC + * @param[in] smn_status recent value from #SMN_STATUS_REG + * @param[in] scm_status recent value from #SCM_STATUS_REG + * + * @return #SCC_RET_OK if ok, #SCC_RET_FAIL if not + */ +static scc_return_t +check_register_accessible(uint32_t register_offset, uint32_t smn_status, + uint32_t scm_status) +{ + int error_code = SCC_RET_FAIL; + + /* Verify that the register offset passed in is not among the verboten set + * if the SMN is in Fail mode. + */ + if (offset_within_smn(register_offset)) { + if ((smn_status & SMN_STATUS_STATE_MASK) == SMN_STATE_FAIL) { + if (!((register_offset == SMN_STATUS_REG) || + (register_offset == SMN_COMMAND_REG) || + (register_offset == SMN_SEC_VIO_REG))) { + pr_debug + ("SCC2 Driver: Note: Security State is in FAIL state.\n"); + } /* register not a safe one */ + else { + /* SMN is in FAIL, but register is a safe one */ + error_code = SCC_RET_OK; + } + } /* State is FAIL */ + else { + /* State is not fail. All registers accessible. */ + error_code = SCC_RET_OK; + } + } + /* offset within SMN */ + /* Not SCM register. Check for SCM busy. */ + else if (offset_within_scm(register_offset)) { + /* This is the 'cannot access' condition in the SCM */ + if (0 /* (scm_status & SCM_STATUS_BUSY) */ + /* these are always available - rest fail on busy */ + && !((register_offset == SCM_STATUS_REG) || + (register_offset == SCM_ERR_STATUS_REG) || + (register_offset == SCM_INT_CTL_REG) || + (register_offset == SCM_VERSION_REG))) { + pr_debug + ("SCC2 Driver: Note: Secure Memory is in BUSY state.\n"); + } /* status is busy & register inaccessible */ + else { + error_code = SCC_RET_OK; + } + } + /* offset within SCM */ + return error_code; + +} /* check_register_accessible() */ + +/*****************************************************************************/ +/* fn check_register_offset() */ +/*****************************************************************************/ +/** + * Check that the offset is with the bounds of the SCC register set. + * + * @param[in] register_offset register offset of SMN. + * + * #SCC_RET_OK if ok, #SCC_RET_FAIL if not + */ +static scc_return_t check_register_offset(uint32_t register_offset) +{ + int return_value = SCC_RET_FAIL; + + /* Is it valid word offset ? */ + if (SCC_BYTE_OFFSET(register_offset) == 0) { + /* Yes. Is register within SCM? */ + if (offset_within_scm(register_offset)) { + return_value = SCC_RET_OK; /* yes, all ok */ + } + /* Not in SCM. Now look within the SMN */ + else if (offset_within_smn(register_offset)) { + return_value = SCC_RET_OK; /* yes, all ok */ + } + } + + return return_value; +} + +#ifdef SCC_REGISTER_DEBUG + +/** + * Names of the SCC Registers, indexed by register number + */ +static char *scc_regnames[] = { + "SCM_VERSION_REG", + "0x04", + "SCM_INT_CTL_REG", + "SCM_STATUS_REG", + "SCM_ERR_STATUS_REG", + "SCM_FAULT_ADR_REG", + "SCM_PART_OWNERS_REG", + "SCM_PART_ENGAGED_REG", + "SCM_UNIQUE_ID0_REG", + "SCM_UNIQUE_ID1_REG", + "SCM_UNIQUE_ID2_REG", + "SCM_UNIQUE_ID3_REG", + "0x30", + "0x34", + "0x38", + "0x3C", + "0x40", + "0x44", + "0x48", + "0x4C", + "SCM_ZCMD_REG", + "SCM_CCMD_REG", + "SCM_C_BLACK_ST_REG", + "SCM_DBG_STATUS_REG", + "SCM_AES_CBC_IV0_REG", + "SCM_AES_CBC_IV1_REG", + "SCM_AES_CBC_IV2_REG", + "SCM_AES_CBC_IV3_REG", + "0x70", + "0x74", + "0x78", + "0x7C", + "SCM_SMID0_REG", + "SCM_ACC0_REG", + "SCM_SMID1_REG", + "SCM_ACC1_REG", + "SCM_SMID2_REG", + "SCM_ACC2_REG", + "SCM_SMID3_REG", + "SCM_ACC3_REG", + "SCM_SMID4_REG", + "SCM_ACC4_REG", + "SCM_SMID5_REG", + "SCM_ACC5_REG", + "SCM_SMID6_REG", + "SCM_ACC6_REG", + "SCM_SMID7_REG", + "SCM_ACC7_REG", + "SCM_SMID8_REG", + "SCM_ACC8_REG", + "SCM_SMID9_REG", + "SCM_ACC9_REG", + "SCM_SMID10_REG", + "SCM_ACC10_REG", + "SCM_SMID11_REG", + "SCM_ACC11_REG", + "SCM_SMID12_REG", + "SCM_ACC12_REG", + "SCM_SMID13_REG", + "SCM_ACC13_REG", + "SCM_SMID14_REG", + "SCM_ACC14_REG", + "SCM_SMID15_REG", + "SCM_ACC15_REG", + "SMN_STATUS_REG", + "SMN_COMMAND_REG", + "SMN_SEQ_START_REG", + "SMN_SEQ_END_REG", + "SMN_SEQ_CHECK_REG", + "SMN_BB_CNT_REG", + "SMN_BB_INC_REG", + "SMN_BB_DEC_REG", + "SMN_COMPARE_REG", + "SMN_PT_CHK_REG", + "SMN_CT_CHK_REG", + "SMN_TIMER_IV_REG", + "SMN_TIMER_CTL_REG", + "SMN_SEC_VIO_REG", + "SMN_TIMER_REG", + "SMN_HAC_REG" +}; + +/** + * Names of the Secure RAM States + */ +static char *srs_names[] = { + "SRS_Reset", + "SRS_All_Ready", + "SRS_ZeroizeBusy", + "SRS_CipherBusy", + "SRS_AllBusy", + "SRS_ZeroizeDoneCipherReady", + "SRS_CipherDoneZeroizeReady", + "SRS_ZeroizeDoneCipherBusy", + "SRS_CipherDoneZeroizeBusy", + "SRS_UNKNOWN_STATE_9", + "SRS_TransitionalA", + "SRS_TransitionalB", + "SRS_TransitionalC", + "SRS_TransitionalD", + "SRS_AllDone", + "SRS_UNKNOWN_STATE_E", + "SRS_FAIL" +}; + +/** + * Create a text interpretation of the SCM Version Register + * + * @param value The value of the register + * @param[out] print_buffer Place to store the interpretation + * @param buf_size Number of bytes available at print_buffer + * + * @return The print_buffer + */ +static +char *scm_print_version_reg(uint32_t value, char *print_buffer, int buf_size) +{ + snprintf(print_buffer, buf_size, + "Bpp: %u, Bpcb: %u, np: %u, maj: %u, min: %u", + (value & SCM_VER_BPP_MASK) >> SCM_VER_BPP_SHIFT, + ((value & SCM_VER_BPCB_MASK) >> SCM_VER_BPCB_SHIFT) + 1, + ((value & SCM_VER_NP_MASK) >> SCM_VER_NP_SHIFT) + 1, + (value & SCM_VER_MAJ_MASK) >> SCM_VER_MAJ_SHIFT, + (value & SCM_VER_MIN_MASK) >> SCM_VER_MIN_SHIFT); + + return print_buffer; +} + +/** + * Create a text interpretation of the SCM Status Register + * + * @param value The value of the register + * @param[out] print_buffer Place to store the interpretation + * @param buf_size Number of bytes available at print_buffer + * + * @return The print_buffer + */ +static +char *scm_print_status_reg(uint32_t value, char *print_buffer, int buf_size) +{ + + snprintf(print_buffer, buf_size, "%s%s%s%s%s%s%s%s%s%s%s%s%s", + (value & SCM_STATUS_KST_DEFAULT_KEY) ? "KST_DefaultKey " : "", + /* reserved */ + (value & SCM_STATUS_KST_WRONG_KEY) ? "KST_WrongKey " : "", + (value & SCM_STATUS_KST_BAD_KEY) ? "KST_BadKey " : "", + (value & SCM_STATUS_ERR) ? "Error " : "", + (value & SCM_STATUS_MSS_FAIL) ? "MSS_FailState " : "", + (value & SCM_STATUS_MSS_SEC) ? "MSS_SecureState " : "", + (value & SCM_STATUS_RSS_FAIL) ? "RSS_FailState " : "", + (value & SCM_STATUS_RSS_SEC) ? "RSS_SecureState " : "", + (value & SCM_STATUS_RSS_INIT) ? "RSS_Initializing " : "", + (value & SCM_STATUS_UNV) ? "UID_Invalid " : "", + (value & SCM_STATUS_BIG) ? "BigEndian " : "", + (value & SCM_STATUS_USK) ? "SecretKey " : "", + srs_names[(value & SCM_STATUS_SRS_MASK) >> + SCM_STATUS_SRS_SHIFT]); + + return print_buffer; +} + +/** + * Names of the SCM Error Codes + */ +static +char *scm_err_code[] = { + "Unknown_0", + "UnknownAddress", + "UnknownCommand", + "ReadPermErr", + "WritePermErr", + "DMAErr", + "EncBlockLenOvfl", + "KeyNotEngaged", + "ZeroizeCmdQOvfl", + "CipherCmdQOvfl", + "ProcessIntr", + "WrongKey", + "DeviceBusy", + "DMAUnalignedAddr", + "Unknown_E", + "Unknown_F", +}; + +/** + * Names of the SMN States + */ +static char *smn_state_name[] = { + "Start", + "Invalid_01", + "Invalid_02", + "Invalid_03", + "Zeroizing_04", + "Zeroizing", + "HealthCheck", + "HealthCheck_07", + "Invalid_08", + "Fail", + "Secure", + "Invalid_0B", + "NonSecure", + "Invalid_0D", + "Invalid_0E", + "Invalid_0F", + "Invalid_10", + "Invalid_11", + "Invalid_12", + "Invalid_13", + "Invalid_14", + "Invalid_15", + "Invalid_16", + "Invalid_17", + "Invalid_18", + "FailHard", + "Invalid_1A", + "Invalid_1B", + "Invalid_1C", + "Invalid_1D", + "Invalid_1E", + "Invalid_1F" +}; + +/** + * Create a text interpretation of the SCM Error Status Register + * + * @param value The value of the register + * @param[out] print_buffer Place to store the interpretation + * @param buf_size Number of bytes available at print_buffer + * + * @return The print_buffer + */ +static +char *scm_print_err_status_reg(uint32_t value, char *print_buffer, int buf_size) +{ + snprintf(print_buffer, buf_size, + "MID: 0x%x, %s%s ErrorCode: %s, SMSState: %s, SCMState: %s", + (value & SCM_ERRSTAT_MID_MASK) >> SCM_ERRSTAT_MID_SHIFT, + (value & SCM_ERRSTAT_ILM) ? "ILM, " : "", + (value & SCM_ERRSTAT_SUP) ? "SUP, " : "", + scm_err_code[(value & SCM_ERRSTAT_ERC_MASK) >> + SCM_ERRSTAT_ERC_SHIFT], + smn_state_name[(value & SCM_ERRSTAT_SMS_MASK) >> + SCM_ERRSTAT_SMS_SHIFT], + srs_names[(value & SCM_ERRSTAT_SRS_MASK) >> + SCM_ERRSTAT_SRS_SHIFT]); + return print_buffer; +} + +/** + * Create a text interpretation of the SCM Zeroize Command Register + * + * @param value The value of the register + * @param[out] print_buffer Place to store the interpretation + * @param buf_size Number of bytes available at print_buffer + * + * @return The print_buffer + */ +static +char *scm_print_zcmd_reg(uint32_t value, char *print_buffer, int buf_size) +{ + unsigned cmd = (value & SCM_ZCMD_CCMD_MASK) >> SCM_CCMD_CCMD_SHIFT; + + snprintf(print_buffer, buf_size, "%s %u", + (cmd == + ZCMD_DEALLOC_PART) ? "DeallocPartition" : + "(unknown function)", + (value & SCM_ZCMD_PART_MASK) >> SCM_ZCMD_PART_SHIFT); + + return print_buffer; +} + +/** + * Create a text interpretation of the SCM Cipher Command Register + * + * @param value The value of the register + * @param[out] print_buffer Place to store the interpretation + * @param buf_size Number of bytes available at print_buffer + * + * @return The print_buffer + */ +static +char *scm_print_ccmd_reg(uint32_t value, char *print_buffer, int buf_size) +{ + unsigned cmd = (value & SCM_CCMD_CCMD_MASK) >> SCM_CCMD_CCMD_SHIFT; + + snprintf(print_buffer, buf_size, + "%s %u bytes, %s offset 0x%x, in partition %u", + (cmd == SCM_CCMD_AES_DEC_ECB) ? "ECB Decrypt" : (cmd == + SCM_CCMD_AES_ENC_ECB) + ? "ECB Encrypt" : (cmd == + SCM_CCMD_AES_DEC_CBC) ? "CBC Decrypt" : (cmd + == + SCM_CCMD_AES_ENC_CBC) + ? "CBC Encrypt" : "(unknown function)", + 16 + + 16 * ((value & SCM_CCMD_LENGTH_MASK) >> SCM_CCMD_LENGTH_SHIFT), + ((cmd == SCM_CCMD_AES_ENC_CBC) + || (cmd == SCM_CCMD_AES_ENC_ECB)) ? "at" : "to", + 16 * ((value & SCM_CCMD_OFFSET_MASK) >> SCM_CCMD_OFFSET_SHIFT), + (value & SCM_CCMD_PART_MASK) >> SCM_CCMD_PART_SHIFT); + + return print_buffer; +} + +/** + * Create a text interpretation of an SCM Access Permissions Register + * + * @param value The value of the register + * @param[out] print_buffer Place to store the interpretation + * @param buf_size Number of bytes available at print_buffer + * + * @return The print_buffer + */ +static +char *scm_print_acc_reg(uint32_t value, char *print_buffer, int buf_size) +{ + snprintf(print_buffer, buf_size, "%s%s%s%s%s%s%s%s%s%s", + (value & SCM_PERM_NO_ZEROIZE) ? "NO_ZERO " : "", + (value & SCM_PERM_HD_SUP_DISABLE) ? "SUP_DIS " : "", + (value & SCM_PERM_HD_READ) ? "HD_RD " : "", + (value & SCM_PERM_HD_WRITE) ? "HD_WR " : "", + (value & SCM_PERM_HD_EXECUTE) ? "HD_EX " : "", + (value & SCM_PERM_TH_READ) ? "TH_RD " : "", + (value & SCM_PERM_TH_WRITE) ? "TH_WR " : "", + (value & SCM_PERM_OT_READ) ? "OT_RD " : "", + (value & SCM_PERM_OT_WRITE) ? "OT_WR " : "", + (value & SCM_PERM_OT_EXECUTE) ? "OT_EX" : ""); + + return print_buffer; +} + +/** + * Create a text interpretation of the SCM Partitions Engaged Register + * + * @param value The value of the register + * @param[out] print_buffer Place to store the interpretation + * @param buf_size Number of bytes available at print_buffer + * + * @return The print_buffer + */ +static +char *scm_print_part_eng_reg(uint32_t value, char *print_buffer, int buf_size) +{ + snprintf(print_buffer, buf_size, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + (value & 0x8000) ? "15 " : "", + (value & 0x4000) ? "14 " : "", + (value & 0x2000) ? "13 " : "", + (value & 0x1000) ? "12 " : "", + (value & 0x0800) ? "11 " : "", + (value & 0x0400) ? "10 " : "", + (value & 0x0200) ? "9 " : "", + (value & 0x0100) ? "8 " : "", + (value & 0x0080) ? "7 " : "", + (value & 0x0040) ? "6 " : "", + (value & 0x0020) ? "5 " : "", + (value & 0x0010) ? "4 " : "", + (value & 0x0008) ? "3 " : "", + (value & 0x0004) ? "2 " : "", + (value & 0x0002) ? "1 " : "", (value & 0x0001) ? "0" : ""); + + return print_buffer; +} + +/** + * Create a text interpretation of the SMN Status Register + * + * @param value The value of the register + * @param[out] print_buffer Place to store the interpretation + * @param buf_size Number of bytes available at print_buffer + * + * @return The print_buffer + */ +static +char *smn_print_status_reg(uint32_t value, char *print_buffer, int buf_size) +{ + snprintf(print_buffer, buf_size, + "Version %d %s%s%s%s%s%s%s%s%s%s%s%s%s", + (value & SMN_STATUS_VERSION_ID_MASK) >> + SMN_STATUS_VERSION_ID_SHIFT, + (value & SMN_STATUS_ILLEGAL_MASTER) ? "IllMaster " : "", + (value & SMN_STATUS_SCAN_EXIT) ? "ScanExit " : "", + (value & SMN_STATUS_PERIP_INIT) ? "PeripInit " : "", + (value & SMN_STATUS_SMN_ERROR) ? "SMNError " : "", + (value & SMN_STATUS_SOFTWARE_ALARM) ? "SWAlarm " : "", + (value & SMN_STATUS_TIMER_ERROR) ? "TimerErr " : "", + (value & SMN_STATUS_PC_ERROR) ? "PTCTErr " : "", + (value & SMN_STATUS_BITBANK_ERROR) ? "BitbankErr " : "", + (value & SMN_STATUS_ASC_ERROR) ? "ASCErr " : "", + (value & SMN_STATUS_SECURITY_POLICY_ERROR) ? "SecPlcyErr " : + "", + (value & SMN_STATUS_SEC_VIO_ACTIVE_ERROR) ? "SecVioAct " : "", + (value & SMN_STATUS_INTERNAL_BOOT) ? "IntBoot " : "", + smn_state_name[(value & SMN_STATUS_STATE_MASK) >> + SMN_STATUS_STATE_SHIFT]); + + return print_buffer; +} + +/** + * The array, indexed by register number (byte-offset / 4), of print routines + * for the SCC (SCM and SMN) registers. + */ +static reg_print_routine_t reg_printers[] = { + scm_print_version_reg, + NULL, /* 0x04 */ + NULL, /* SCM_INT_CTL_REG */ + scm_print_status_reg, + scm_print_err_status_reg, + NULL, /* SCM_FAULT_ADR_REG */ + NULL, /* SCM_PART_OWNERS_REG */ + scm_print_part_eng_reg, + NULL, /* SCM_UNIQUE_ID0_REG */ + NULL, /* SCM_UNIQUE_ID1_REG */ + NULL, /* SCM_UNIQUE_ID2_REG */ + NULL, /* SCM_UNIQUE_ID3_REG */ + NULL, /* 0x30 */ + NULL, /* 0x34 */ + NULL, /* 0x38 */ + NULL, /* 0x3C */ + NULL, /* 0x40 */ + NULL, /* 0x44 */ + NULL, /* 0x48 */ + NULL, /* 0x4C */ + scm_print_zcmd_reg, + scm_print_ccmd_reg, + NULL, /* SCM_C_BLACK_ST_REG */ + NULL, /* SCM_DBG_STATUS_REG */ + NULL, /* SCM_AES_CBC_IV0_REG */ + NULL, /* SCM_AES_CBC_IV1_REG */ + NULL, /* SCM_AES_CBC_IV2_REG */ + NULL, /* SCM_AES_CBC_IV3_REG */ + NULL, /* 0x70 */ + NULL, /* 0x74 */ + NULL, /* 0x78 */ + NULL, /* 0x7C */ + NULL, /* SCM_SMID0_REG */ + scm_print_acc_reg, /* ACC0 */ + NULL, /* SCM_SMID1_REG */ + scm_print_acc_reg, /* ACC1 */ + NULL, /* SCM_SMID2_REG */ + scm_print_acc_reg, /* ACC2 */ + NULL, /* SCM_SMID3_REG */ + scm_print_acc_reg, /* ACC3 */ + NULL, /* SCM_SMID4_REG */ + scm_print_acc_reg, /* ACC4 */ + NULL, /* SCM_SMID5_REG */ + scm_print_acc_reg, /* ACC5 */ + NULL, /* SCM_SMID6_REG */ + scm_print_acc_reg, /* ACC6 */ + NULL, /* SCM_SMID7_REG */ + scm_print_acc_reg, /* ACC7 */ + NULL, /* SCM_SMID8_REG */ + scm_print_acc_reg, /* ACC8 */ + NULL, /* SCM_SMID9_REG */ + scm_print_acc_reg, /* ACC9 */ + NULL, /* SCM_SMID10_REG */ + scm_print_acc_reg, /* ACC10 */ + NULL, /* SCM_SMID11_REG */ + scm_print_acc_reg, /* ACC11 */ + NULL, /* SCM_SMID12_REG */ + scm_print_acc_reg, /* ACC12 */ + NULL, /* SCM_SMID13_REG */ + scm_print_acc_reg, /* ACC13 */ + NULL, /* SCM_SMID14_REG */ + scm_print_acc_reg, /* ACC14 */ + NULL, /* SCM_SMID15_REG */ + scm_print_acc_reg, /* ACC15 */ + smn_print_status_reg, + NULL, /* SMN_COMMAND_REG */ + NULL, /* SMN_SEQ_START_REG */ + NULL, /* SMN_SEQ_END_REG */ + NULL, /* SMN_SEQ_CHECK_REG */ + NULL, /* SMN_BB_CNT_REG */ + NULL, /* SMN_BB_INC_REG */ + NULL, /* SMN_BB_DEC_REG */ + NULL, /* SMN_COMPARE_REG */ + NULL, /* SMN_PT_CHK_REG */ + NULL, /* SMN_CT_CHK_REG */ + NULL, /* SMN_TIMER_IV_REG */ + NULL, /* SMN_TIMER_CTL_REG */ + NULL, /* SMN_SEC_VIO_REG */ + NULL, /* SMN_TIMER_REG */ + NULL, /* SMN_HAC_REG */ +}; + +/*****************************************************************************/ +/* fn dbg_scc_read_register() */ +/*****************************************************************************/ +/** + * Noisily read a 32-bit value to an SCC register. + * @param offset The address of the register to read. + * + * @return The register value + * */ +uint32_t dbg_scc_read_register(uint32_t offset) +{ + uint32_t value; + char *regname = scc_regnames[offset / 4]; + + value = __raw_readl(scc_base + offset); + pr_debug("SCC2 RD: 0x%03x : 0x%08x (%s) %s\n", offset, value, regname, + reg_printers[offset / 4] + ? reg_printers[offset / 4] (value, reg_print_buffer, + REG_PRINT_BUFFER_SIZE) + : ""); + + return value; +} + +/*****************************************************************************/ +/* fn dbg_scc_write_register() */ +/*****************************************************************************/ +/* + * Noisily read a 32-bit value to an SCC register. + * @param offset The address of the register to written. + * + * @param value The new register value + */ +void dbg_scc_write_register(uint32_t offset, uint32_t value) +{ + char *regname = scc_regnames[offset / 4]; + + pr_debug("SCC2 WR: 0x%03x : 0x%08x (%s) %s\n", offset, value, regname, + reg_printers[offset / 4] + ? reg_printers[offset / 4] (value, reg_print_buffer, + REG_PRINT_BUFFER_SIZE) + : ""); + (void)__raw_writel(value, scc_base + offset); +} + +#endif /* SCC_REGISTER_DEBUG */ --- linux-2.6.28.orig/drivers/mxc/security/Kconfig +++ linux-2.6.28/drivers/mxc/security/Kconfig @@ -0,0 +1,22 @@ +menu "MXC Security Drivers" + +config MXC_SECURITY_SCC2 + tristate "MXC SCC2 Driver" + depends on ARCH_MX51 + default n + ---help--- + This module contains the core API's for accessing the SCC2 module. + If you are unsure about this, say N here. + +config SCC_DEBUG + bool "MXC SCC Module debugging" + depends on MXC_SECURITY_SCC || MXC_SECURITY_SCC2 + ---help--- + This is an option for use by developers; most people should + say N here. This enables SCC module debugging. + +if (ARCH_MX51) +source "drivers/mxc/security/sahara2/Kconfig" +endif + +endmenu --- linux-2.6.28.orig/drivers/mxc/security/Makefile +++ linux-2.6.28/drivers/mxc/security/Makefile @@ -0,0 +1,9 @@ +# Makefile for the Linux MXC Security API +ifeq ($( SCC_DEBUG),y) +EXTRA_CFLAGS += -DDEBUG +endif +EXTRA_CFLAGS += -DMXC -DLINUX_KERNEL + +obj-$(CONFIG_MXC_SECURITY_SCC2) += scc2_driver.o +obj-$(CONFIG_MXC_SAHARA) += sahara2/ + --- linux-2.6.28.orig/drivers/mxc/security/sahara2/sf_util.c +++ linux-2.6.28/drivers/mxc/security/sahara2/sf_util.c @@ -0,0 +1,1396 @@ +/* + * Copyright 2004-2008 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 + */ + +/** +* @file sf_util.c +* +* @brief Security Functions component API - Utility functions +* +* These are the 'Sahara api' functions which are used by the higher-level +* FSL SHW API to build and then execute descriptor chains. +*/ + + +#include "sf_util.h" +#include + +#ifdef DIAG_SECURITY_FUNC +#include +#endif /*DIAG_SECURITY_FUNC*/ + + +#ifdef __KERNEL__ +EXPORT_SYMBOL(sah_Append_Desc); +EXPORT_SYMBOL(sah_Append_Link); +EXPORT_SYMBOL(sah_Create_Link); +EXPORT_SYMBOL(sah_Create_Key_Link); +EXPORT_SYMBOL(sah_Destroy_Link); +EXPORT_SYMBOL(sah_Descriptor_Chain_Execute); +EXPORT_SYMBOL(sah_insert_mdha_algorithm); +EXPORT_SYMBOL(sah_insert_skha_algorithm); +EXPORT_SYMBOL(sah_insert_skha_mode); +EXPORT_SYMBOL(sah_insert_skha_modulus); +EXPORT_SYMBOL(sah_Descriptor_Chain_Destroy); +EXPORT_SYMBOL(sah_add_two_in_desc); +EXPORT_SYMBOL(sah_add_in_key_desc); +EXPORT_SYMBOL(sah_add_two_out_desc); +EXPORT_SYMBOL(sah_add_in_out_desc); +EXPORT_SYMBOL(sah_add_key_out_desc); +#endif + +#ifdef DEBUG_REWORK +#ifndef __KERNEL__ +#include +#define os_printk printf +#endif +#endif + +/** + * Convert fsl_shw_hash_alg_t to mdha mode bits. + * + * Index must be maintained in order of fsl_shw_hash_alg_t enumeration!!! + */ +const uint32_t sah_insert_mdha_algorithm[] = +{ + [FSL_HASH_ALG_MD5] = sah_insert_mdha_algorithm_md5, + [FSL_HASH_ALG_SHA1] = sah_insert_mdha_algorithm_sha1, + [FSL_HASH_ALG_SHA224] = sah_insert_mdha_algorithm_sha224, + [FSL_HASH_ALG_SHA256] = sah_insert_mdha_algorithm_sha256, +}; + +/** + * Header bits for Algorithm field of SKHA header + * + * Index value must be kept in sync with fsl_shw_key_alg_t + */ +const uint32_t sah_insert_skha_algorithm[] = +{ + [FSL_KEY_ALG_HMAC] = 0x00000040, + [FSL_KEY_ALG_AES] = sah_insert_skha_algorithm_aes, + [FSL_KEY_ALG_DES] = sah_insert_skha_algorithm_des, + [FSL_KEY_ALG_TDES] = sah_insert_skha_algorithm_tdes, + [FSL_KEY_ALG_ARC4] = sah_insert_skha_algorithm_arc4, +}; + + +/** + * Header bits for MODE field of SKHA header + * + * Index value must be kept in sync with fsl_shw_sym_mod_t + */ +const uint32_t sah_insert_skha_mode[] = +{ + [FSL_SYM_MODE_STREAM] = sah_insert_skha_mode_ecb, + [FSL_SYM_MODE_ECB] = sah_insert_skha_mode_ecb, + [FSL_SYM_MODE_CBC] = sah_insert_skha_mode_cbc, + [FSL_SYM_MODE_CTR] = sah_insert_skha_mode_ctr, +}; + + +/** + * Header bits to set CTR modulus size. These have parity + * included to allow XOR insertion of values. + * + * @note Must be kept in sync with fsl_shw_ctr_mod_t + */ +const uint32_t sah_insert_skha_modulus[] = +{ + [FSL_CTR_MOD_8] = 0x00000000, /**< 2**8 */ + [FSL_CTR_MOD_16] = 0x80000200, /**< 2**16 */ + [FSL_CTR_MOD_24] = 0x80000400, /**< 2**24 */ + [FSL_CTR_MOD_32] = 0x00000600, /**< 2**32 */ + [FSL_CTR_MOD_40] = 0x80000800, /**< 2**40 */ + [FSL_CTR_MOD_48] = 0x00000a00, /**< 2**48 */ + [FSL_CTR_MOD_56] = 0x00000c00, /**< 2**56 */ + [FSL_CTR_MOD_64] = 0x80000e00, /**< 2**64 */ + [FSL_CTR_MOD_72] = 0x80001000, /**< 2**72 */ + [FSL_CTR_MOD_80] = 0x00001200, /**< 2**80 */ + [FSL_CTR_MOD_88] = 0x00001400, /**< 2**88 */ + [FSL_CTR_MOD_96] = 0x80001600, /**< 2**96 */ + [FSL_CTR_MOD_104] = 0x00001800, /**< 2**104 */ + [FSL_CTR_MOD_112] = 0x80001a00, /**< 2**112 */ + [FSL_CTR_MOD_120] = 0x80001c00, /**< 2**120 */ + [FSL_CTR_MOD_128] = 0x00001e00 /**< 2**128 */ +}; + + +/****************************************************************************** +* Internal function declarations +******************************************************************************/ +static fsl_shw_return_t sah_Create_Desc( + const sah_Mem_Util *mu, + sah_Desc ** desc, + int head, + uint32_t header, + sah_Link * link1, + sah_Link * link2); + + +/** + * Create a descriptor chain using the the header and links passed in as + * parameters. The newly created descriptor will be added to the end of + * the descriptor chain passed. + * + * If @a desc_head points to a NULL value, then a sah_Head_Desc will be created + * as the first descriptor. Otherwise a sah_Desc will be created and appended. + * + * @pre + * + * - None + * + * @post + * + * - A descriptor has been created from the header, link1 and link2. + * + * - The newly created descriptor has been appended to the end of + * desc_head, or its location stored into the location pointed to by + * @a desc_head. + * + * - On allocation failure, @a link1 and @a link2 will be destroyed., and + * @a desc_head will be untouched. + * + * @brief Create and append descriptor chain, inserting header and links + * pointing to link1 and link2 + * + * @param mu Memory functions + * @param header Value of descriptor header to be added + * @param desc_head Pointer to head of descriptor chain to append new desc + * @param link1 Pointer to sah_Link 1 (or NULL) + * @param link2 Pointer to sah_Link 2 (or NULL) + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t sah_Append_Desc( + const sah_Mem_Util *mu, + sah_Head_Desc **desc_head, + const uint32_t header, + sah_Link *link1, + sah_Link *link2) +{ + fsl_shw_return_t status; + sah_Desc *desc; + sah_Desc *desc_ptr; + + + status = sah_Create_Desc(mu, (sah_Desc**)&desc, (*desc_head == NULL), + header, link1, link2); + /* append newly created descriptor to end of current chain */ + if (status == FSL_RETURN_OK_S) { + if (*desc_head == NULL) { + (*desc_head) = (sah_Head_Desc*)desc; + (*desc_head)->out1_ptr = NULL; + (*desc_head)->out2_ptr = NULL; + + } else { + desc_ptr = (sah_Desc*)*desc_head; + while (desc_ptr->next != NULL) { + desc_ptr = desc_ptr->next; + } + desc_ptr->next = desc; + } + } + + return status; +} + + +/** + * Releases the memory allocated by the Security Function library for + * descriptors, links and any internally allocated memory referenced in the + * given chain. Note that memory allocated by user applications is not + * released. + * + * @post The @a desc_head pointer will be set to NULL to prevent further use. + * + * @brief Destroy a descriptor chain and free memory of associated links + * + * @param mu Memory functions + * @param desc_head Pointer to head of descriptor chain to be freed + * + * @return none + */ +void sah_Descriptor_Chain_Destroy ( + const sah_Mem_Util *mu, + sah_Head_Desc **desc_head) +{ + sah_Desc *desc_ptr = &(*desc_head)->desc; + sah_Head_Desc *desc_head_ptr = (sah_Head_Desc *)desc_ptr; + + while (desc_ptr != NULL) { + register sah_Desc *next_desc_ptr; + + if (desc_ptr->ptr1 != NULL) { + sah_Destroy_Link(mu, desc_ptr->ptr1); + } + if (desc_ptr->ptr2 != NULL) { + sah_Destroy_Link(mu, desc_ptr->ptr2); + } + + next_desc_ptr = desc_ptr->next; + + /* Be sure to free head descriptor as such */ + if (desc_ptr == (sah_Desc*)desc_head_ptr) { + mu->mu_free_head_desc(mu->mu_ref, desc_head_ptr); + } else { + mu->mu_free_desc(mu->mu_ref, desc_ptr); + } + + desc_ptr = next_desc_ptr; + } + + *desc_head = NULL; +} + + +#ifndef NO_INPUT_WORKAROUND +/** + * Reworks the link chain + * + * @brief Reworks the link chain + * + * @param mu Memory functions + * @param link Pointer to head of link chain to be reworked + * + * @return none + */ +static fsl_shw_return_t sah_rework_link_chain( + const sah_Mem_Util *mu, + sah_Link* link) +{ + fsl_shw_return_t status = FSL_RETURN_OK_S; + int found_potential_problem = 0; + uint32_t total_data = 0; +#ifdef DEBUG_REWORK + sah_Link* first_link = link; +#endif + + if ((link->flags & SAH_OUTPUT_LINK)) { + return status; + } + + while (link != NULL) { + total_data += link->len; + + /* Only non-key Input Links are affected by the DMA flush-to-FIFO + * problem */ + + /* If have seen problem and at end of chain... */ + if (found_potential_problem && (link->next == NULL) && + (total_data > 16)) { + /* insert new 1-byte link */ + sah_Link* new_tail_link = mu->mu_alloc_link(mu->mu_ref); + if (new_tail_link == NULL) { + status = FSL_RETURN_NO_RESOURCE_S; + } else { +#ifdef DEBUG_REWORK + sah_Link* dump_link = first_link; + while (dump_link != NULL) { + uint32_t i; + unsigned bytes_to_dump = (dump_link->len > 32) ? + 32 : dump_link->len; + os_printk("(rework)Link %p: %p/%u/%p\n", dump_link, + dump_link->data, dump_link->len, + dump_link->next); + if (!(dump_link->flags & SAH_STORED_KEY_INFO)) { + os_printk("(rework)Data %p: ", dump_link->data); + for (i = 0; i < bytes_to_dump; i++) { + os_printk("%02X ", dump_link->data[i]); + } + os_printk("\n"); + } + else { + os_printk("rework)Data %p: Red key data\n", dump_link); + } + dump_link = dump_link->next; + } +#endif + link->len--; + link->next = new_tail_link; + new_tail_link->len = 1; + new_tail_link->data = link->data+link->len; + new_tail_link->flags = link->flags & ~(SAH_OWNS_LINK_DATA); + new_tail_link->next = NULL; + link = new_tail_link; +#ifdef DEBUG_REWORK + os_printk("(rework)New link chain:\n"); + dump_link = first_link; + while (dump_link != NULL) { + uint32_t i; + unsigned bytes_to_dump = (dump_link->len > 32) ? + 32 : dump_link->len; + + os_printk("Link %p: %p/%u/%p\n", dump_link, + dump_link->data, dump_link->len, + dump_link->next); + if (!(dump_link->flags & SAH_STORED_KEY_INFO)) { + os_printk("Data %p: ", dump_link->data); + for (i = 0; i < bytes_to_dump; i++) { + os_printk("%02X ", dump_link->data[i]); + } + os_printk("\n"); + } + else { + os_printk("Data %p: Red key data\n", dump_link); + } + dump_link = dump_link->next; + } +#endif + } + } else if ((link->len % 4) || ((uint32_t)link->data % 4)) { + found_potential_problem = 1; + } + + link = link->next; + } + + return status; +} + + +/** + * Rework links to avoid H/W bug + * + * @param head Beginning of descriptor chain + * + * @return A return code of type #fsl_shw_return_t. + */ +static fsl_shw_return_t sah_rework_links( + const sah_Mem_Util *mu, + sah_Head_Desc *head) +{ + fsl_shw_return_t status = FSL_RETURN_OK_S; + sah_Desc* desc = &head->desc; + + while ((status == FSL_RETURN_OK_S) && (desc != NULL)) { + if (desc->header & SAH_HDR_LLO) { + status = FSL_RETURN_ERROR_S; + break; + } + if (desc->ptr1 != NULL) { + status = sah_rework_link_chain(mu, desc->ptr1); + } + if ((status == FSL_RETURN_OK_S) && (desc->ptr2 != NULL)) { + status = sah_rework_link_chain(mu, desc->ptr2); + } + desc = desc->next; + } + + return status; +} +#endif /* NO_INPUT_WORKAROUND */ + + +/** + * Send a descriptor chain to the SAHARA driver for processing. + * + * Note that SAHARA will read the input data from and write the output data + * directly to the locations indicated during construction of the chain. + * + * @pre + * + * - None + * + * @post + * + * - @a head will have been executed on SAHARA + * - @a head Will be freed unless a SAVE flag is set + * + * @brief Execute a descriptor chain + * + * @param head Pointer to head of descriptor chain to be executed + * @param user_ctx The user context on which to execute the descriptor chain. + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t sah_Descriptor_Chain_Execute( + sah_Head_Desc *head, + fsl_shw_uco_t *user_ctx) +{ + fsl_shw_return_t status; + + /* Check for null pointer or non-multiple-of-four value */ + if ((head == NULL) || ((uint32_t)head & 0x3)) { + status = FSL_RETURN_ERROR_S; + goto out; + } + +#ifndef NO_INPUT_WORKAROUND + status = sah_rework_links(user_ctx->mem_util, head); + if (status != FSL_RETURN_OK_S) { + goto out; + } +#endif + + /* complete the information in the descriptor chain head node */ + head->user_ref = user_ctx->user_ref; + head->uco_flags = user_ctx->flags; + head->next = NULL; /* driver will use this to link chain heads */ + + status = adaptor_Exec_Descriptor_Chain(head, user_ctx); + +#ifdef DIAG_SECURITY_FUNC + if (status == FSL_RETURN_OK_S) + LOG_DIAG("after exec desc chain: status is ok\n"); + else + LOG_DIAG("after exec desc chain: status is not ok\n"); +#endif + + out: + return status; +} + + +/** + * Create Link + * + * @brief Allocate Memory for Link structure and populate using input + * parameters + * + * @post On allocation failure, @a p will be freed if #SAH_OWNS_LINK_DATA is + * p set in @a flags. + + * @param mu Memory functions + * @param link Pointer to link to be created + * @param p Pointer to data to use in link + * @param length Length of buffer 'p' in bytes + * @param flags Indicates whether memory has been allocated by the calling + * function or the security function + * + * @return FSL_RETURN_OK_S or FSL_RETURN_NO_RESOURCE_S + */ +fsl_shw_return_t sah_Create_Link( + const sah_Mem_Util *mu, + sah_Link **link, + uint8_t *p, + const size_t length, + const sah_Link_Flags flags) +{ + +#ifdef DIAG_SECURITY_FUNC + + char diag[50]; +#endif /*DIAG_SECURITY_FUNC_UGLY*/ + fsl_shw_return_t status = FSL_RETURN_NO_RESOURCE_S; + + + *link = mu->mu_alloc_link(mu->mu_ref); + + /* populate link if memory allocation successful */ + if (*link != NULL) { + (*link)->len = length; + (*link)->data = p; + (*link)->next = NULL; + (*link)->flags = flags; + status = FSL_RETURN_OK_S; + +#ifdef DIAG_SECURITY_FUNC + + LOG_DIAG("Created Link"); + LOG_DIAG("------------"); + sprintf(diag," address = 0x%x", (int) *link); + LOG_DIAG(diag); + sprintf(diag," link->len = %d",(*link)->len); + LOG_DIAG(diag); + sprintf(diag," link->data = 0x%x",(int) (*link)->data); + LOG_DIAG(diag); + sprintf(diag," link->flags = 0x%x",(*link)->flags); + LOG_DIAG(diag); + LOG_DIAG(" link->next = NULL"); +#endif /*DIAG_SECURITY_FUNC_UGLY*/ + + } else { +#ifdef DIAG_SECURITY_FUNC + LOG_DIAG("Allocation of memory for sah_Link failed!\n"); +#endif /*DIAG_SECURITY_FUNC*/ + + /* Free memory previously allocated by the security function layer for + link data. Note that the memory being pointed to will be zeroed before + being freed, for security reasons. */ + if (flags & SAH_OWNS_LINK_DATA) { + mu->mu_memset(mu->mu_ref, p, 0x00, length); + mu->mu_free(mu->mu_ref, p); + } + } + + return status; +} + + +/** + * Create Key Link + * + * @brief Allocate Memory for Link structure and populate using key info + * object + * + * @param mu Memory functions + * @param link Pointer to store address of link to be created + * @param key_info Pointer to Key Info object to be referenced + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t sah_Create_Key_Link( + const sah_Mem_Util *mu, + sah_Link **link, + fsl_shw_sko_t *key_info) +{ +#ifdef DIAG_SECURITY_FUNC_UGLY + char diag[50]; +#endif /*DIAG_SECURITY_FUNC_UGLY*/ + fsl_shw_return_t status = FSL_RETURN_NO_RESOURCE_S; + sah_Link_Flags flags = 0; + + + *link = mu->mu_alloc_link(mu->mu_ref); + + /* populate link if memory allocation successful */ + if (*link != NULL) { + (*link)->len = key_info->key_length; + + if (key_info->flags & FSL_SKO_KEY_PRESENT) { + (*link)->data = key_info->key; + status = FSL_RETURN_OK_S; + } else { + if (key_info->flags & FSL_SKO_KEY_ESTABLISHED) { + + if (key_info->keystore == NULL) { + /* System Keystore */ + (*link)->slot = key_info->handle; + (*link)->ownerid = key_info->userid; + (*link)->data = 0; + flags |= SAH_STORED_KEY_INFO; + status = FSL_RETURN_OK_S; + } else { +#ifdef FSL_HAVE_SCC2 + /* User Keystore */ + fsl_shw_kso_t *keystore = key_info->keystore; + /* Note: the key data is stored here, but the address has to + * be converted to a partition and offset in the kernel. + * This will be calculated in kernel space, based on the + * list of partitions held by the users context. + */ + (*link)->data = + keystore->slot_get_address(keystore->user_data, + key_info->handle); + + flags |= SAH_IN_USER_KEYSTORE; + status = FSL_RETURN_OK_S; +#else + /* User keystores only supported in SCC2 */ + status = FSL_RETURN_BAD_FLAG_S; +#endif /* FSL_HAVE_SCC2 */ + + } + } else { + /* the flag is bad. Should never get here */ + status = FSL_RETURN_BAD_FLAG_S; + } + } + + (*link)->next = NULL; + (*link)->flags = flags; + +#ifdef DIAG_SECURITY_FUNC_UGLY + if (status == FSL_RETURN_OK_S) { + LOG_DIAG("Created Link"); + LOG_DIAG("------------"); + sprintf(diag," address = 0x%x", (int) *link); + LOG_DIAG(diag); + sprintf(diag," link->len = %d", (*link)->len); + LOG_DIAG(diag); + if (key_info->flags & FSL_SKO_KEY_ESTABLISHED) { + sprintf(diag," link->slot = 0x%x", (*link)->slot); + LOG_DIAG(diag); + } else { + sprintf(diag," link->data = 0x%x", (int)(*link)->data); + LOG_DIAG(diag); + } + sprintf(diag," link->flags = 0x%x", (*link)->flags); + LOG_DIAG(diag); + LOG_DIAG(" link->next = NULL"); + } +#endif /*DIAG_SECURITY_FUNC_UGLY*/ + + if (status == FSL_RETURN_BAD_FLAG_S) { + mu->mu_free_link(mu->mu_ref, *link); + *link = NULL; +#ifdef DIAG_SECURITY_FUNC + LOG_DIAG("Creation of sah_Key_Link failed due to bad key flag!\n"); +#endif /*DIAG_SECURITY_FUNC*/ + } + + } else { +#ifdef DIAG_SECURITY_FUNC + LOG_DIAG("Allocation of memory for sah_Key_Link failed!\n"); +#endif /*DIAG_SECURITY_FUNC*/ + } + + return status; +} + + +/** + * Append Link + * + * @brief Allocate Memory for Link structure and append it to the end of + * the link chain. + * + * @post On allocation failure, @a p will be freed if #SAH_OWNS_LINK_DATA is + * p set in @a flags. + * + * @param mu Memory functions + * @param link_head Pointer to (head of) existing link chain + * @param p Pointer to data to use in link + * @param length Length of buffer 'p' in bytes + * @param flags Indicates whether memory has been allocated by the calling + * function or the security function + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t sah_Append_Link( + const sah_Mem_Util *mu, + sah_Link *link_head, + uint8_t *p, + const size_t length, + const sah_Link_Flags flags) +{ + sah_Link* new_link; + fsl_shw_return_t status; + + + status = sah_Create_Link(mu, &new_link, p, length, flags); + + if (status == FSL_RETURN_OK_S) { + /* chase for the tail */ + while (link_head->next != NULL) { + link_head = link_head->next; + } + + /* and add new tail */ + link_head->next = new_link; + } + + return status; +} + + +/** + * Create and populate a single descriptor + * + * The pointer and length fields will be be set based on the chains passed in + * as @a link1 and @a link2. + * + * @param mu Memory utility suite + * @param desc Location to store pointer of new descriptor + * @param head_desc Non-zero if this will be first in chain; zero otherwise + * @param header The Sahara header value to store in the descriptor + * @param link1 A value (or NULL) for the first ptr + * @param link2 A value (or NULL) for the second ptr + * + * @post If allocation succeeded, the @a link1 and @link2 will be linked into + * the descriptor. If allocation failed, those link structues will be + * freed, and the @a desc will be unchanged. + * + * @return A return code of type #fsl_shw_return_t. + */ +static fsl_shw_return_t sah_Create_Desc( + const sah_Mem_Util *mu, + sah_Desc ** desc, + int head_desc, + uint32_t header, + sah_Link * link1, + sah_Link * link2) +{ + fsl_shw_return_t status = FSL_RETURN_NO_RESOURCE_S; +#ifdef DIAG_SECURITY_FUNC_UGLY + char diag[50]; +#endif /*DIAG_SECURITY_FUNC_UGLY*/ + + + if (head_desc != 0) { + *desc = (sah_Desc *)mu->mu_alloc_head_desc(mu->mu_ref); + } else { + *desc = mu->mu_alloc_desc(mu->mu_ref); + } + + /* populate descriptor if memory allocation successful */ + if ((*desc) != NULL) { + sah_Link* temp_link; + + status = FSL_RETURN_OK_S; + (*desc)->header = header; + + temp_link = (*desc)->ptr1 = link1; + (*desc)->len1 = 0; + while (temp_link != NULL) { + (*desc)->len1 += temp_link->len; + temp_link = temp_link->next; + } + + temp_link = (*desc)->ptr2 = link2; + (*desc)->len2 = 0; + while (temp_link != NULL) { + (*desc)->len2 += temp_link->len; + temp_link = temp_link->next; + } + + (*desc)->next = NULL; + +#ifdef DIAG_SECURITY_FUNC_UGLY + LOG_DIAG("Created Desc"); + LOG_DIAG("------------"); + sprintf(diag," address = 0x%x",(int) *desc); + LOG_DIAG(diag); + sprintf(diag," desc->header = 0x%x",(*desc)->header); + LOG_DIAG(diag); + sprintf(diag," desc->len1 = %d",(*desc)->len1); + LOG_DIAG(diag); + sprintf(diag," desc->ptr1 = 0x%x",(int) ((*desc)->ptr1)); + LOG_DIAG(diag); + sprintf(diag," desc->len2 = %d",(*desc)->len2); + LOG_DIAG(diag); + sprintf(diag," desc->ptr2 = 0x%x",(int) ((*desc)->ptr2)); + LOG_DIAG(diag); + sprintf(diag," desc->next = 0x%x",(int) ((*desc)->next)); + LOG_DIAG(diag); +#endif /*DIAG_SECURITY_FUNC_UGLY*/ + } else { +#ifdef DIAG_SECURITY_FUNC + LOG_DIAG("Allocation of memory for sah_Desc failed!\n"); +#endif /*DIAG_SECURITY_FUNC*/ + + /* Destroy the links, otherwise the memory allocated by the Security + Function layer for the links (and possibly the data within the links) + will be lost */ + if (link1 != NULL) { + sah_Destroy_Link(mu, link1); + } + if (link2 != NULL) { + sah_Destroy_Link(mu, link2); + } + } + + return status; +} + + +/** + * Destroy a link (chain) and free memory + * + * @param mu memory utility suite + * @param link The Link to destroy + * + * @return none + */ +void sah_Destroy_Link( + const sah_Mem_Util *mu, + sah_Link * link) +{ + + while (link != NULL) { + sah_Link * next_link = link->next; + + if (link->flags & SAH_OWNS_LINK_DATA) { + /* zero data for security purposes */ + mu->mu_memset(mu->mu_ref, link->data, 0x00, link->len); + mu->mu_free(mu->mu_ref, link->data); + } + + link->data = NULL; + link->next = NULL; + mu->mu_free_link(mu->mu_ref, link); + + link = next_link; + } +} + + +/** + * Add descriptor where both links are inputs. + * + * @param header The Sahara header value for the descriptor. + * @param in1 The first input buffer (or NULL) + * @param in1_length Size of @a in1 + * @param[out] in2 The second input buffer (or NULL) + * @param in2_length Size of @a in2 + * @param mu Memory functions + * @param[in,out] desc_chain Chain to start or append to + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t sah_add_two_in_desc(uint32_t header, + const uint8_t* in1, + uint32_t in1_length, + const uint8_t* in2, + uint32_t in2_length, + const sah_Mem_Util* mu, + sah_Head_Desc** desc_chain) +{ + fsl_shw_return_t status = FSL_RETURN_OK_S; + sah_Link* link1 = NULL; + sah_Link* link2 = NULL; + + printk("Entering sah_add_two_in_desc \n"); + + if (in1 != NULL) { + status = sah_Create_Link(mu, &link1, + (sah_Oct_Str) in1, in1_length, + SAH_USES_LINK_DATA); + } + + if ( (in2 != NULL) && (status == FSL_RETURN_OK_S) ) { + status = sah_Create_Link(mu, &link2, + (sah_Oct_Str) in2, in2_length, + SAH_USES_LINK_DATA); + } + + if (status != FSL_RETURN_OK_S) { + if (link1 != NULL) { + sah_Destroy_Link(mu, link1); + } + if (link2 != NULL) { + sah_Destroy_Link(mu, link2); + } + } else { + status = sah_Append_Desc(mu, desc_chain, header, link1, link2); + } + + return status; +} + +/*! + * Add descriptor where neither link needs sync + * + * @param header The Sahara header value for the descriptor. + * @param in1 The first input buffer (or NULL) + * @param in1_length Size of @a in1 + * @param[out] in2 The second input buffer (or NULL) + * @param in2_length Size of @a in2 + * @param mu Memory functions + * @param[in,out] desc_chain Chain to start or append to + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t sah_add_two_d_desc(uint32_t header, + const uint8_t * in1, + uint32_t in1_length, + const uint8_t * in2, + uint32_t in2_length, + const sah_Mem_Util * mu, + sah_Head_Desc ** desc_chain) +{ + fsl_shw_return_t status = FSL_RETURN_OK_S; + sah_Link *link1 = NULL; + sah_Link *link2 = NULL; + + printk("Entering sah_add_two_d_desc \n"); + + if (in1 != NULL) { + status = sah_Create_Link(mu, &link1, + (sah_Oct_Str) in1, in1_length, + SAH_USES_LINK_DATA); + } + + if ((in2 != NULL) && (status == FSL_RETURN_OK_S)) { + status = sah_Create_Link(mu, &link2, + (sah_Oct_Str) in2, in2_length, + SAH_USES_LINK_DATA); + } + + if (status != FSL_RETURN_OK_S) { + if (link1 != NULL) { + sah_Destroy_Link(mu, link1); + } + if (link2 != NULL) { + sah_Destroy_Link(mu, link2); + } + } else { + status = sah_Append_Desc(mu, desc_chain, header, link1, link2); + } + + return status; +} /* sah_add_two_d_desc() */ + +/** + * Add descriptor where both links are inputs, the second one being a key. + * + * @param header The Sahara header value for the descriptor. + * @param in1 The first input buffer (or NULL) + * @param in1_length Size of @a in1 + * @param[out] in2 The second input buffer (or NULL) + * @param in2_length Size of @a in2 + * @param mu Memory functions + * @param[in,out] desc_chain Chain to start or append to + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t sah_add_in_key_desc(uint32_t header, + const uint8_t* in1, + uint32_t in1_length, + fsl_shw_sko_t* key_info, + const sah_Mem_Util* mu, + sah_Head_Desc** desc_chain) +{ + fsl_shw_return_t status = FSL_RETURN_OK_S; + sah_Link *link1 = NULL; + sah_Link *link2 = NULL; + + if (in1 != NULL) { + status = sah_Create_Link(mu, &link1, + (sah_Oct_Str) in1, in1_length, + SAH_USES_LINK_DATA); + } + + if (status != FSL_RETURN_OK_S) { + goto out; + } + + status = sah_Create_Key_Link(mu, &link2, key_info); + + + if (status != FSL_RETURN_OK_S) { + goto out; + } + + status = sah_Append_Desc(mu, desc_chain, header, link1, link2); + +out: + if (status != FSL_RETURN_OK_S) { + if (link1 != NULL) { + sah_Destroy_Link(mu, link1); + } + if (link2 != NULL) { + sah_Destroy_Link(mu, link2); + } + } + + return status; +} + + +/** + * Create two links using keys allocated in the scc + * + * @param header The Sahara header value for the descriptor. + * @param in1 The first input buffer (or NULL) + * @param in1_length Size of @a in1 + * @param[out] in2 The second input buffer (or NULL) + * @param in2_length Size of @a in2 + * @param mu Memory functions + * @param[in,out] desc_chain Chain to start or append to + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t sah_add_key_key_desc(uint32_t header, + fsl_shw_sko_t *key_info1, + fsl_shw_sko_t *key_info2, + const sah_Mem_Util *mu, + sah_Head_Desc **desc_chain) +{ + fsl_shw_return_t status; + sah_Link *link1 = NULL; + sah_Link *link2 = NULL; + + + status = sah_Create_Key_Link(mu, &link1, key_info1); + + if (status == FSL_RETURN_OK_S) { + status = sah_Create_Key_Link(mu, &link2, key_info2); + } + + if (status != FSL_RETURN_OK_S) { + if (link1 != NULL) { + sah_Destroy_Link(mu, link1); + } + if (link2 != NULL) { + sah_Destroy_Link(mu, link2); + } + } else { + status = sah_Append_Desc(mu, desc_chain, header, link1, link2); + } + + return status; +} + + +/** + * Add descriptor where first link is input, the second is a changing key + * + * @param header The Sahara header value for the descriptor. + * @param in1 The first input buffer (or NULL) + * @param in1_length Size of @a in1 + * @param[out] in2 The key for output + * @param mu Memory functions + * @param[in,out] desc_chain Chain to start or append to + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t sah_add_in_keyout_desc(uint32_t header, + const uint8_t* in1, + uint32_t in1_length, + fsl_shw_sko_t* key_info, + const sah_Mem_Util* mu, + sah_Head_Desc** desc_chain) +{ + fsl_shw_return_t status = FSL_RETURN_OK_S; + sah_Link *link1 = NULL; + sah_Link *link2 = NULL; + + if (in1 != NULL) { + status = sah_Create_Link(mu, &link1, + (sah_Oct_Str) in1, in1_length, + SAH_USES_LINK_DATA); + } + + if (status != FSL_RETURN_OK_S) { + goto out; + } + + status = sah_Create_Key_Link(mu, &link2, key_info); + + if (status != FSL_RETURN_OK_S) { + goto out; + } + +link2->flags |= SAH_OUTPUT_LINK; /* mark key for output */ +status = sah_Append_Desc(mu, desc_chain, header, link1, link2); + +out: + + if (status != FSL_RETURN_OK_S) { + if (link1 != NULL) { + sah_Destroy_Link(mu, link1); + } + if (link2 != NULL) { + sah_Destroy_Link(mu, link2); + } + } + + return status; +} + +/** + * Add descriptor where both links are outputs. + * + * @param header The Sahara header value for the descriptor. + * @param out1 The first output buffer (or NULL) + * @param out1_length Size of @a out1 + * @param[out] out2 The second output buffer (or NULL) + * @param out2_length Size of @a out2 + * @param mu Memory functions + * @param[in,out] desc_chain Chain to start or append to + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t sah_add_two_out_desc(uint32_t header, + uint8_t* out1, + uint32_t out1_length, + uint8_t* out2, + uint32_t out2_length, + const sah_Mem_Util* mu, + sah_Head_Desc** desc_chain) +{ + fsl_shw_return_t status = FSL_RETURN_OK_S; + sah_Link *link1 = NULL; + sah_Link *link2 = NULL; + + + printk("Entering sah_add_two_out_desc \n"); + + if (out1 != NULL) { + status = sah_Create_Link(mu, &link1, + (sah_Oct_Str) out1, out1_length, + SAH_OUTPUT_LINK | + SAH_USES_LINK_DATA); + } + + if ( (out2 != NULL) && (status == FSL_RETURN_OK_S) ) { + status = sah_Create_Link(mu, &link2, + (sah_Oct_Str) out2, out2_length, + SAH_OUTPUT_LINK | + SAH_USES_LINK_DATA); + } + + if (status != FSL_RETURN_OK_S) { + if (link1 != NULL) { + sah_Destroy_Link(mu, link1); + } + if (link2 != NULL) { + sah_Destroy_Link(mu, link2); + } + } else { + status = sah_Append_Desc(mu, desc_chain, header, link1, link2); + } + + return status; +} + + +/** + * Add descriptor where first link is output, second is output + * + * @param header The Sahara header value for the descriptor. + * @param out1 The first output buffer (or NULL) + * @param out1_length Size of @a out1 + * @param[out] in2 The input buffer (or NULL) + * @param in2_length Size of @a in2 + * @param mu Memory functions + * @param[in,out] desc_chain Chain to start or append to + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t sah_add_out_in_desc(uint32_t header, + uint8_t* out1, + uint32_t out1_length, + const uint8_t* in2, + uint32_t in2_length, + const sah_Mem_Util* mu, + sah_Head_Desc** desc_chain) +{ + fsl_shw_return_t status = FSL_RETURN_OK_S; + sah_Link *link1 = NULL; + sah_Link *link2 = NULL; + + + if (out1 != NULL) { + status = sah_Create_Link(mu, &link1, + (sah_Oct_Str) out1, out1_length, + SAH_OUTPUT_LINK | + SAH_USES_LINK_DATA); + } + + if ( (in2 != NULL) && (status == FSL_RETURN_OK_S) ) { + status = sah_Create_Link(mu, &link2, + (sah_Oct_Str) in2, in2_length, + SAH_USES_LINK_DATA); + } + + if (status != FSL_RETURN_OK_S) { + if (link1 != NULL) { + sah_Destroy_Link(mu, link1); + } + if (link2 != NULL) { + sah_Destroy_Link(mu, link2); + } + } else { + status = sah_Append_Desc(mu, desc_chain, header, link1, link2); + } + + return status; +} + + +/** + * Add descriptor where link1 is input buffer, link2 is output buffer. + * + * @param header The Sahara header value for the descriptor. + * @param in The input buffer + * @param in_length Size of the input buffer + * @param[out] out The output buffer + * @param out_length Size of the output buffer + * @param mu Memory functions + * @param[in,out] desc_chain Chain to start or append to + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t sah_add_in_out_desc(uint32_t header, + const uint8_t* in, uint32_t in_length, + uint8_t* out, uint32_t out_length, + const sah_Mem_Util* mu, + sah_Head_Desc** desc_chain) +{ + fsl_shw_return_t status = FSL_RETURN_OK_S; + sah_Link *link1 = NULL; + sah_Link *link2 = NULL; + + if (in != NULL) { + status = sah_Create_Link(mu, &link1, + (sah_Oct_Str) in, in_length, + SAH_USES_LINK_DATA); + } + + if ((status == FSL_RETURN_OK_S) && (out != NULL)) { + status = sah_Create_Link(mu, &link2, + (sah_Oct_Str) out, out_length, + SAH_OUTPUT_LINK | + SAH_USES_LINK_DATA); + } + + if (status != FSL_RETURN_OK_S) { + if (link1 != NULL) { + sah_Destroy_Link(mu, link1); + } + if (link2 != NULL) { + sah_Destroy_Link(mu, link2); + } + } else { + status = sah_Append_Desc(mu, desc_chain, header, link1, link2); + } + + return status; +} + + +/** + * Add descriptor where link1 is a key, link2 is output buffer. + * + * @param header The Sahara header value for the descriptor. + * @param key_info Key information + * @param[out] out The output buffer + * @param out_length Size of the output buffer + * @param mu Memory functions + * @param[in,out] desc_chain Chain to start or append to + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t sah_add_key_out_desc(uint32_t header, + const fsl_shw_sko_t *key_info, + uint8_t* out, uint32_t out_length, + const sah_Mem_Util *mu, + sah_Head_Desc **desc_chain) +{ + fsl_shw_return_t status; + sah_Link *link1 = NULL; + sah_Link *link2 = NULL; + + status = sah_Create_Key_Link(mu, &link1, (fsl_shw_sko_t *) key_info); + if (status != FSL_RETURN_OK_S) { + goto out; + } + + + if (out != NULL) { + status = sah_Create_Link(mu, &link2, + (sah_Oct_Str) out, out_length, + SAH_OUTPUT_LINK | + SAH_USES_LINK_DATA); + if (status != FSL_RETURN_OK_S) { + goto out; + } + } +status = sah_Append_Desc(mu, desc_chain, header, link1, link2); + +out: + if (status != FSL_RETURN_OK_S) { + if (link1 != NULL) { + sah_Destroy_Link(mu, link1); + } + if (link2 != NULL) { + sah_Destroy_Link(mu, link2); + } + } + + return status; +} + + +/** + * Sanity checks the user context object fields to ensure that they make some + * sense before passing the uco as a parameter + * + * @brief Verify the user context object + * + * @param uco user context object + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t sah_validate_uco(fsl_shw_uco_t *uco) +{ + fsl_shw_return_t status = FSL_RETURN_OK_S; + + + /* check if file is opened */ + if (uco->sahara_openfd < 0) { + status = FSL_RETURN_NO_RESOURCE_S; + } else { + /* check flag combination: the only invalid setting of the + * blocking and callback flags is blocking with callback. So check + * for that + */ + if ((uco->flags & (FSL_UCO_BLOCKING_MODE | FSL_UCO_CALLBACK_MODE)) == + (FSL_UCO_BLOCKING_MODE | FSL_UCO_CALLBACK_MODE)) { + status = FSL_RETURN_BAD_FLAG_S; + } else { + /* check that memory utilities have been attached */ + if (uco->mem_util == NULL) { + status = FSL_RETURN_MEMORY_ERROR_S; + } else { + /* must have pool of at least 1, even for blocking mode */ + if (uco->pool_size == 0) { + status = FSL_RETURN_ERROR_S; + } else { + /* if callback flag is set, it better have a callback + * routine */ + if (uco->flags & FSL_UCO_CALLBACK_MODE) { + if (uco->callback == NULL) { + status = FSL_RETURN_INTERNAL_ERROR_S; + } + } + } + } + } + } + + return status; +} + + +/** + * Perform any post-processing on non-blocking results. + * + * For instance, free descriptor chains, compare authentication codes, ... + * + * @param user_ctx User context object + * @param result_info A set of results + */ +void sah_Postprocess_Results(fsl_shw_uco_t* user_ctx, sah_results* result_info) +{ + unsigned i; + + /* for each result returned */ + for (i = 0; i < *result_info->actual; i++) { + sah_Head_Desc* desc = result_info->results[i].user_desc; + uint8_t* out1 = desc->out1_ptr; + uint8_t* out2 = desc->out2_ptr; + uint32_t len = desc->out_len; + + /* + * For now, tne only post-processing besides freeing the + * chain is the need to check the auth code for fsl_shw_auth_decrypt(). + * + * If other uses are required in the future, this code will probably + * need a flag in the sah_Head_Desc (or a function pointer!) to + * determine what needs to be done. + */ + if ((out1 != NULL) && (out2 != NULL)) { + unsigned j; + for (j = 0; j < len; j++) { + if (out1[j] != out2[j]) { + /* Problem detected. Change result. */ + result_info->results[i].code = FSL_RETURN_AUTH_FAILED_S; + break; + } + } + /* free allocated 'calced_auth' */ + user_ctx->mem_util-> + mu_free(user_ctx->mem_util->mu_ref, out1); + } + + /* Free the API-created chain, unless tagged as not-from-API */ + if (! (desc->uco_flags & FSL_UCO_SAVE_DESC_CHAIN)) { + sah_Descriptor_Chain_Destroy(user_ctx->mem_util, &desc); + } + } +} + + +/* End of sf_util.c */ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/sah_queue.c +++ linux-2.6.28/drivers/mxc/security/sahara2/sah_queue.c @@ -0,0 +1,249 @@ +/* + * Copyright 2004-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 + */ + +/*! +* @file sah_queue.c +* +* @brief This file provides a FIFO Queue implementation. +* +*/ +/****************************************************************************** +* +* CAUTION: +******************************************************************* +*/ + +/* SAHARA Includes */ +#include +#ifdef DIAG_DRV_QUEUE +#include +#endif + +/****************************************************************************** +* Queue Functions +******************************************************************************/ + +/*! +******************************************************************************* +* This function constructs a new sah_Queue. +* +* @brief sah_Queue Constructor +* +* @return A pointer to a newly allocated sah_Queue. +* @return NULL if allocation of memory failed. +*/ +/****************************************************************************** +* +* CAUTION: This function may sleep in low-memory situations, as it uses +* kmalloc ( ..., GFP_KERNEL). +******************************************************************************/ +sah_Queue *sah_Queue_Construct(void) +{ + sah_Queue *q = (sah_Queue *) os_alloc_memory(sizeof(sah_Queue), + GFP_KERNEL); + + if (q != NULL) { + /* Initialise the queue to an empty state. */ + q->head = NULL; + q->tail = NULL; + q->count = 0; + } +#ifdef DIAG_DRV_QUEUE + else { + LOG_KDIAG("kmalloc() failed."); + } +#endif + + return q; +} + +/*! +******************************************************************************* +* This function destroys a sah_Queue. +* +* @brief sah_Queue Destructor +* +* @param q A pointer to a sah_Queue. +* +* @return void +*/ +/****************************************************************************** +* +* CAUTION: This function does not free any queue entries. +* +******************************************************************************/ +void sah_Queue_Destroy(sah_Queue * q) +{ +#ifdef DIAG_DRV_QUEUE + if (q == NULL) { + LOG_KDIAG("Trying to kfree() a NULL pointer."); + } else { + if (q->count != 0) { + LOG_KDIAG + ("Trying to destroy a queue that is not empty."); + } + } +#endif + + if (q != NULL) { + os_free_memory(q); + q = NULL; + } +} + +/*! +******************************************************************************* +* This function appends a sah_Head_Desc to the tail of a sah_Queue. +* +* @brief Appends a sah_Head_Desc to a sah_Queue. +* +* @param q A pointer to a sah_Queue to append to. +* @param entry A pointer to a sah_Head_Desc to append. +* +* @pre The #desc_queue_lock must be held before calling this function. +* +* @return void +*/ +/****************************************************************************** +* +* CAUTION: NONE +******************************************************************************/ +void sah_Queue_Append_Entry(sah_Queue * q, sah_Head_Desc * entry) +{ + sah_Head_Desc *tail_entry = NULL; + + if ((q == NULL) || (entry == NULL)) { +#ifdef DIAG_DRV_QUEUE + LOG_KDIAG("Null pointer input."); +#endif + return; + } + + if (q->count == 0) { + /* The queue is empty */ + q->head = entry; + q->tail = entry; + entry->next = NULL; + entry->prev = NULL; + } else { + /* The queue is not empty */ + tail_entry = q->tail; + tail_entry->next = entry; + entry->next = NULL; + entry->prev = tail_entry; + q->tail = entry; + } + q->count++; +} + +/*! +******************************************************************************* +* This function a removes a sah_Head_Desc from the head of a sah_Queue. +* +* @brief Removes a sah_Head_Desc from a the head of a sah_Queue. +* +* @param q A pointer to a sah_Queue to remove from. +* +* @pre The #desc_queue_lock must be held before calling this function. +* +* @return void +*/ +/****************************************************************************** +* +* CAUTION: This does not kfree() the entry. +******************************************************************************/ +void sah_Queue_Remove_Entry(sah_Queue * q) +{ + sah_Queue_Remove_Any_Entry(q, q->head); +} + +/*! +******************************************************************************* +* This function a removes a sah_Head_Desc from anywhere in a sah_Queue. +* +* @brief Removes a sah_Head_Desc from anywhere in a sah_Queue. +* +* @param qq A pointer to a sah_Queue to remove from. +* @param entry A pointer to a sah_Head_Desc to remove. +* +* @pre The #desc_queue_lock must be held before calling this function. +* +* @return void +*/ +/****************************************************************************** +* +* CAUTION: This does not kfree() the entry. Does not check to see if the entry +* actually belongs to the queue. +******************************************************************************/ +void sah_Queue_Remove_Any_Entry(sah_Queue * q, sah_Head_Desc * entry) +{ + sah_Head_Desc *prev_entry = NULL; + sah_Head_Desc *next_entry = NULL; + + if ((q == NULL) || (entry == NULL)) { +#if defined DIAG_DRV_QUEUE && defined DIAG_DURING_INTERRUPT + LOG_KDIAG("Null pointer input."); +#endif + return; + } + + if (q->count == 1) { + /* If q is the only entry in the queue. */ + q->tail = NULL; + q->head = NULL; + q->count = 0; + } else if (q->count > 1) { + /* There are 2 or more entries in the queue. */ + +#if defined DIAG_DRV_QUEUE && defined DIAG_DURING_INTERRUPT + if ((entry->next == NULL) && (entry->prev == NULL)) { + LOG_KDIAG + ("Queue is not empty yet both next and prev pointers" + " are NULL"); + } +#endif + + if (entry->next == NULL) { + /* If this is the end of the queue */ + prev_entry = entry->prev; + prev_entry->next = NULL; + q->tail = prev_entry; + } else if (entry->prev == NULL) { + /* If this is the head of the queue */ + next_entry = entry->next; + next_entry->prev = NULL; + q->head = next_entry; + } else { + /* If this is somewhere in the middle of the queue */ + prev_entry = entry->prev; + next_entry = entry->next; + prev_entry->next = next_entry; + next_entry->prev = prev_entry; + } + q->count--; + } + /* + * Otherwise we are removing an entry from an empty queue. + * Don't do anything in the product code + */ +#if defined DIAG_DRV_QUEUE && defined DIAG_DURING_INTERRUPT + else { + LOG_KDIAG("Trying to remove an entry from an empty queue."); + } +#endif + + entry->next = NULL; + entry->prev = NULL; +} + +/* End of sah_queue.c */ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/fsl_shw_hash.c +++ linux-2.6.28/drivers/mxc/security/sahara2/fsl_shw_hash.c @@ -0,0 +1,186 @@ +/* + * Copyright 2004-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 + */ + +/*! + * @file fsl_shw_hash.c + * + * This file implements Cryptographic Hashing functions of the FSL SHW API + * for Sahara. This does not include HMAC. + */ + +#include "sahara.h" +#include "sf_util.h" + +#ifdef LINUX_KERNEL +EXPORT_SYMBOL(fsl_shw_hash); +#endif + +/* REQ-S2LRD-PINTFC-API-BASIC-HASH-005 */ +/*! + * Hash a stream of data with a cryptographic hash algorithm. + * + * The flags in the @a hash_ctx control the operation of this function. + * + * Hashing functions work on 64 octets of message at a time. Therefore, when + * any partial hashing of a long message is performed, the message @a length of + * each segment must be a multiple of 64. When ready to + * #FSL_HASH_FLAGS_FINALIZE the hash, the @a length may be any value. + * + * With the #FSL_HASH_FLAGS_INIT and #FSL_HASH_FLAGS_FINALIZE flags on, a + * one-shot complete hash, including padding, will be performed. The @a length + * may be any value. + * + * The first octets of a data stream can be hashed by setting the + * #FSL_HASH_FLAGS_INIT and #FSL_HASH_FLAGS_SAVE flags. The @a length must be + * a multiple of 64. + * + * The flag #FSL_HASH_FLAGS_LOAD is used to load a context previously saved by + * #FSL_HASH_FLAGS_SAVE. The two in combination will allow a (multiple-of-64 + * octets) 'middle sequence' of the data stream to be hashed with the + * beginning. The @a length must again be a multiple of 64. + * + * Since the flag #FSL_HASH_FLAGS_LOAD is used to load a context previously + * saved by #FSL_HASH_FLAGS_SAVE, the #FSL_HASH_FLAGS_LOAD and + * #FSL_HASH_FLAGS_FINALIZE flags, used together, can be used to finish the + * stream. The @a length may be any value. + * + * If the user program wants to do the padding for the hash, it can leave off + * the #FSL_HASH_FLAGS_FINALIZE flag. The @a length must then be a multiple of + * 64 octets. + * + * @param user_ctx A user context from #fsl_shw_register_user(). + * @param[in,out] hash_ctx Hashing algorithm and state of the cipher. + * @param msg Pointer to the data to be hashed. + * @param length Length, in octets, of the @a msg. + * @param[out] result If not null, pointer to where to store the hash + * digest. + * @param result_len Number of octets to store in @a result. + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t fsl_shw_hash(fsl_shw_uco_t * user_ctx, + fsl_shw_hco_t * hash_ctx, + const uint8_t * msg, + uint32_t length, + uint8_t * result, uint32_t result_len) +{ + SAH_SF_DCLS; + unsigned ctx_flags = (hash_ctx->flags & (FSL_HASH_FLAGS_INIT + | FSL_HASH_FLAGS_LOAD + | FSL_HASH_FLAGS_SAVE + | FSL_HASH_FLAGS_FINALIZE)); + + SAH_SF_USER_CHECK(); + + /* Reset expectations if user gets overly zealous. */ + if (result_len > hash_ctx->digest_length) { + result_len = hash_ctx->digest_length; + } + + /* Validate hash ctx flags. + * Need INIT or LOAD but not both. + * Need SAVE or digest ptr (both is ok). + */ + if (((ctx_flags & (FSL_HASH_FLAGS_INIT | FSL_HASH_FLAGS_LOAD)) + == (FSL_HASH_FLAGS_INIT | FSL_HASH_FLAGS_LOAD)) + || ((ctx_flags & (FSL_HASH_FLAGS_INIT | FSL_HASH_FLAGS_LOAD)) == 0) + || (!(ctx_flags & FSL_HASH_FLAGS_SAVE) && (result == NULL))) { + ret = FSL_RETURN_BAD_FLAG_S; + goto out; + } + + if (ctx_flags & FSL_HASH_FLAGS_INIT) { + sah_Oct_Str out_ptr; + unsigned out_len; + + /* Create desc to perform the initial hashing operation */ + /* Desc. #8 w/INIT and algorithm */ + header = SAH_HDR_MDHA_SET_MODE_HASH + ^ sah_insert_mdha_init + ^ sah_insert_mdha_algorithm[hash_ctx->algorithm]; + + /* If user wants one-shot, set padding operation. */ + if (ctx_flags & FSL_HASH_FLAGS_FINALIZE) { + header ^= sah_insert_mdha_pdata; + } + + /* Determine where Digest will go - hash_ctx or result */ + if (ctx_flags & FSL_HASH_FLAGS_SAVE) { + out_ptr = (sah_Oct_Str) hash_ctx->context; + out_len = hash_ctx->context_register_length; + } else { + out_ptr = result; + out_len = (result_len > hash_ctx->digest_length) + ? hash_ctx->digest_length : result_len; + } + + DESC_IN_OUT(header, length, (sah_Oct_Str) msg, out_len, + out_ptr); + } else { /* not doing hash INIT */ + void *out_ptr; + unsigned out_len; + + /* + * Build two descriptors -- one to load in context/set mode, the + * other to compute & retrieve hash/context value. + * + * First up - Desc. #6 to load context. + */ + /* Desc. #8 w/algorithm */ + header = SAH_HDR_MDHA_SET_MODE_MD_KEY + ^ sah_insert_mdha_algorithm[hash_ctx->algorithm]; + + if (ctx_flags & FSL_HASH_FLAGS_FINALIZE) { + header ^= sah_insert_mdha_pdata; + } + + /* Message Digest (in) */ + DESC_IN_IN(header, + hash_ctx->context_register_length, + (sah_Oct_Str) hash_ctx->context, 0, NULL); + + if (ctx_flags & FSL_HASH_FLAGS_SAVE) { + out_ptr = hash_ctx->context; + out_len = hash_ctx->context_register_length; + } else { + out_ptr = result; + out_len = result_len; + } + + /* Second -- run data through and retrieve ctx regs */ + /* Desc. #10 - no mode register with this. */ + header = SAH_HDR_MDHA_HASH; + DESC_IN_OUT(header, length, (sah_Oct_Str) msg, out_len, + out_ptr); + } /* else not INIT */ + + /* Now that execution is rejoined, we can append another descriptor + to extract the digest/context a second time, into the result. */ + if ((ctx_flags & FSL_HASH_FLAGS_SAVE) + && (result != NULL) && (result_len != 0)) { + + header = SAH_HDR_MDHA_STORE_DIGEST; + + /* Message Digest (out) */ + DESC_IN_OUT(header, 0, NULL, + (result_len > hash_ctx->digest_length) + ? hash_ctx->digest_length : result_len, result); + } + + SAH_SF_EXECUTE(); + + out: + SAH_SF_DESC_CLEAN(); + + return ret; +} /* fsl_shw_hash() */ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/sah_hardware_interface.c +++ linux-2.6.28/drivers/mxc/security/sahara2/sah_hardware_interface.c @@ -0,0 +1,854 @@ +/* + * Copyright 2004-2008 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 + */ + +/*! + * @file sah_hardware_interface.c + * + * @brief Provides an interface to the SAHARA hardware registers. + * + */ + +/* SAHARA Includes */ +#include +#include +#include +#include + +#if defined DIAG_DRV_IF || defined(DO_DBG) +#include +#ifndef LOG_KDIAG +#define LOG_KDIAG(x) os_printk("%s\n", x) +#endif + +static void sah_Dump_Link(const char *prefix, const sah_Link * link, + dma_addr_t addr); + +/* This is for sprintf() to use when constructing output. */ +#define DIAG_MSG_SIZE 1024 +/* was 200 */ +#define MAX_DUMP 200 +static char Diag_msg[DIAG_MSG_SIZE]; + +#endif /* DIAG_DRV_IF */ + +/*! + * Number of descriptors sent to Sahara. This value should only be updated + * with the main queue lock held. + */ +uint32_t dar_count; + +/*! The "link-list optimize" bit in the Header of a Descriptor */ +#define SAH_HDR_LLO 0x01000000 + +/* IO_ADDRESS() is Linux macro -- need portable equivalent */ +#define SAHARA_BASE_ADDRESS IO_ADDRESS(SAHA_BASE_ADDR) +#define SAHARA_VERSION_REGISTER_OFFSET 0x000 +#define SAHARA_DAR_REGISTER_OFFSET 0x004 +#define SAHARA_CONTROL_REGISTER_OFFSET 0x008 +#define SAHARA_COMMAND_REGISTER_OFFSET 0x00C +#define SAHARA_STATUS_REGISTER_OFFSET 0x010 +#define SAHARA_ESTATUS_REGISTER_OFFSET 0x014 +#define SAHARA_FLT_ADD_REGISTER_OFFSET 0x018 +#define SAHARA_CDAR_REGISTER_OFFSET 0x01C +#define SAHARA_IDAR_REGISTER_OFFSET 0x020 +#define SAHARA_OSTATUS_REGISTER_OFFSET 0x028 +#define SAHARA_CONFIG_REGISTER_OFFSET 0x02C +#define SAHARA_MM_STAT_REGISTER_OFFSET 0x030 + +/*! Register within Sahara which contains hardware version. (1 or 2). */ +#define SAHARA_VERSION_REGISTER (SAHARA_BASE_ADDRESS + \ + SAHARA_VERSION_REGISTER_OFFSET) + +/*! Register within Sahara which is used to provide new work to the block. */ +#define SAHARA_DAR_REGISTER (SAHARA_BASE_ADDRESS + \ + SAHARA_DAR_REGISTER_OFFSET) + +/*! Register with Sahara which is used for configuration. */ +#define SAHARA_CONTROL_REGISTER (SAHARA_BASE_ADDRESS + \ + SAHARA_CONTROL_REGISTER_OFFSET) + +/*! Register with Sahara which is used for changing status. */ +#define SAHARA_COMMAND_REGISTER (SAHARA_BASE_ADDRESS + \ + SAHARA_COMMAND_REGISTER_OFFSET) + +/*! Register with Sahara which is contains status and state. */ +#define SAHARA_STATUS_REGISTER (SAHARA_BASE_ADDRESS + \ + SAHARA_STATUS_REGISTER_OFFSET) + +/*! Register with Sahara which is contains error status information. */ +#define SAHARA_ESTATUS_REGISTER (SAHARA_BASE_ADDRESS + \ + SAHARA_ESTATUS_REGISTER_OFFSET) + +/*! Register with Sahara which is contains faulting address information. */ +#define SAHARA_FLT_ADD_REGISTER (SAHARA_BASE_ADDRESS + \ + SAHARA_FLT_ADD_REGISTER_OFFSET) + +/*! Register with Sahara which is contains current descriptor address. */ +#define SAHARA_CDAR_REGISTER (SAHARA_BASE_ADDRESS + \ + SAHARA_CDAR_REGISTER_OFFSET) + +/*! Register with Sahara which is contains initial descriptor address (of a + chain). */ +#define SAHARA_IDAR_REGISTER (SAHARA_BASE_ADDRESS + \ + SAHARA_IDAR_REGISTER_OFFSET) + +/*! Register with Sahara which is contains op status information. */ +#define SAHARA_OSTATUS_REGISTER (SAHARA_BASE_ADDRESS + \ + SAHARA_OSTATUS_REGISTER_OFFSET) + +/*! Register with Sahara which is contains configuration information. */ +#define SAHARA_CONFIG_REGISTER (SAHARA_BASE_ADDRESS + \ + SAHARA_CONFIG_REGISTER_OFFSET) + +/*! Register with Sahara which is contains configuration information. */ +#define SAHARA_MM_STAT_REGISTER (SAHARA_BASE_ADDRESS + \ + SAHARA_MM_STAT_REGISTER_OFFSET) + +/* Local Functions */ +#if defined DIAG_DRV_IF || defined DO_DBG +void sah_Dump_Region(const char *prefix, const unsigned char *data, + dma_addr_t addr, unsigned length); + +#endif /* DIAG_DRV_IF */ + +/* time out value when polling SAHARA status register for completion */ +static uint32_t sah_poll_timeout = 0xFFFFFFFF; + +/*! + * Polls Sahara to determine when its current operation is complete + * + * @return last value found in Sahara's status register + */ +sah_Execute_Status sah_Wait_On_Sahara() +{ + uint32_t count = 0; /* ensure we don't get stuck in the loop forever */ + sah_Execute_Status status; /* Sahara's status register */ + uint32_t stat_reg; + + pr_debug("Entered sah_Wait_On_Sahara\n"); + + do { + /* get current status register from Sahara */ + stat_reg = sah_HW_Read_Status(); + status = stat_reg & SAH_EXEC_STATE_MASK; + + /* timeout if SAHARA takes too long to complete */ + if (++count == sah_poll_timeout) { + status = SAH_EXEC_FAULT; + printk("sah_Wait_On_Sahara timed out\n"); + } + + /* stay in loop as long as Sahara is still busy */ + } while ((status == SAH_EXEC_BUSY) || (status == SAH_EXEC_DONE1_BUSY2)); + + if (status == SAH_EXEC_ERROR1) { + if (stat_reg & OP_STATUS) { + status = SAH_EXEC_OPSTAT1; + } + } + + return status; +} /* sah_Wait_on_Sahara() */ + +/*! + * This function resets the SAHARA hardware. The following operations are + * performed: + * 1. Resets SAHARA. + * 2. Requests BATCH mode. + * 3. Enables interrupts. + * 4. Requests Little Endian mode. + * + * @brief SAHARA hardware reset function. + * + * @return void + */ +int sah_HW_Reset(void) +{ + sah_Execute_Status sah_state; + int status; /* this is the value to return to the calling routine */ + uint32_t saha_control = 0; + +#ifndef USE_3WORD_BURST +#ifdef FSL_HAVE_SAHARA2 + saha_control |= (8 << 16); /* Allow 8-word burst */ +#endif +#else +/***************** HARDWARE BUG WORK AROUND ******************/ +/* A burst size of > 4 can cause Sahara DMA to issue invalid AHB transactions + * when crossing 1KB boundaries. By limiting the 'burst size' to 3, these + * invalid transactions will not be generated, but Sahara will still transfer + * data more efficiently than if the burst size were set to 1. + */ + saha_control |= (3 << 16); /* Limit DMA burst size. For versions 2/3 */ +#endif /* USE_3WORD_BURST */ + +#ifdef DIAG_DRV_IF + snprintf(Diag_msg, DIAG_MSG_SIZE, + "Address of SAHARA_BASE_ADDRESS = 0x%08x\n", + SAHARA_BASE_ADDRESS); + LOG_KDIAG(Diag_msg); + snprintf(Diag_msg, DIAG_MSG_SIZE, + "Sahara Status register before reset: %08x", + sah_HW_Read_Status()); + LOG_KDIAG(Diag_msg); +#endif + + /* Write the Reset & BATCH mode command to the SAHARA Command register. */ + sah_HW_Write_Command(CMD_BATCH | CMD_RESET); +#ifdef SAHARA4_NO_USE_SQUIB + { + uint32_t cfg = sah_HW_Read_Config(); + cfg &= ~0x10000; + sah_HW_Write_Config(cfg); + } +#endif + + sah_poll_timeout = 0x0FFFFFFF; + sah_state = sah_Wait_On_Sahara(); +#ifdef DIAG_DRV_IF + snprintf(Diag_msg, DIAG_MSG_SIZE, + "Sahara Status register after reset: %08x", + sah_HW_Read_Status()); + LOG_KDIAG(Diag_msg); +#endif + /* on reset completion, check that Sahara is in the idle state */ + status = (sah_state == SAH_EXEC_IDLE) ? 0 : OS_ERROR_FAIL_S; + + /* Set initial value out of reset */ + sah_HW_Write_Control(saha_control); + +#ifndef NO_RESEED_WORKAROUND +/***************** HARDWARE BUG WORK AROUND ******************/ +/* In order to set the 'auto reseed' bit, must first acquire a random value. */ + /* + * to solve a hardware bug, a random number must be generated before + * the 'RNG Auto Reseed' bit can be set. So this generates a random + * number that is thrown away. + * + * Note that the interrupt bit has not been set at this point so + * the result can be polled. + */ +#ifdef DIAG_DRV_IF + LOG_KDIAG("Create and submit Random Number Descriptor"); +#endif + + if (status == OS_ERROR_OK_S) { + /* place to put random number */ + volatile uint32_t *random_data_ptr; + sah_Head_Desc *random_desc; + dma_addr_t desc_dma; + dma_addr_t rand_dma; + const int rnd_cnt = 3; /* how many random 32-bit values to get */ + + /* Get space for data -- assume at least 32-bit aligned! */ + random_data_ptr = os_alloc_memory(rnd_cnt * sizeof(uint32_t), + GFP_ATOMIC); + + random_desc = sah_Alloc_Head_Descriptor(); + + if ((random_data_ptr == NULL) || (random_desc == NULL)) { + status = OS_ERROR_FAIL_S; + } else { + int i; + + /* Clear out values */ + for (i = 0; i < rnd_cnt; i++) { + random_data_ptr[i] = 0; + } + + rand_dma = os_pa(random_data_ptr); + + random_desc->desc.header = 0xB18C0000; /* LLO get random number */ + random_desc->desc.len1 = + rnd_cnt * sizeof(*random_data_ptr); + random_desc->desc.ptr1 = (void *)rand_dma; + random_desc->desc.original_ptr1 = + (void *)random_data_ptr; + + random_desc->desc.len2 = 0; /* not used */ + random_desc->desc.ptr2 = 0; /* not used */ + + random_desc->desc.next = 0; /* chain terminates here */ + random_desc->desc.original_next = 0; /* chain terminates here */ + + desc_dma = random_desc->desc.dma_addr; + + /* Force in-cache data out to RAM */ + os_cache_clean_range(random_data_ptr, + rnd_cnt * + sizeof(*random_data_ptr)); + + /* pass descriptor to Sahara */ + sah_HW_Write_DAR(desc_dma); + + /* + * Wait for RNG to complete (interrupts are disabled at this point + * due to sahara being reset previously) then check for error + */ + sah_state = sah_Wait_On_Sahara(); + /* Force CPU to ignore in-cache and reload from RAM */ + os_cache_inv_range(random_data_ptr, + rnd_cnt * sizeof(*random_data_ptr)); + + /* if it didn't move to done state, an error occured */ + if ( +#ifndef SUBMIT_MULTIPLE_DARS + (sah_state != SAH_EXEC_IDLE) && +#endif + (sah_state != SAH_EXEC_DONE1) + ) { + status = OS_ERROR_FAIL_S; + os_printk + ("(sahara) Failure: state is %08x; random_data is" + " %08x\n", sah_state, *random_data_ptr); + os_printk + ("(sahara) CDAR: %08x, IDAR: %08x, FADR: %08x," + " ESTAT: %08x\n", sah_HW_Read_CDAR(), + sah_HW_Read_IDAR(), + sah_HW_Read_Fault_Address(), + sah_HW_Read_Error_Status()); + } else { + int i; + int seen_rand = 0; + + for (i = 0; i < rnd_cnt; i++) { + if (*random_data_ptr != 0) { + seen_rand = 1; + break; + } + } + if (!seen_rand) { + status = OS_ERROR_FAIL_S; + os_printk + ("(sahara) Error: Random number is zero!\n"); + } + } + } + + if (random_data_ptr) { + os_free_memory((void *)random_data_ptr); + } + if (random_desc) { + sah_Free_Head_Descriptor(random_desc); + } + } +/***************** END HARDWARE BUG WORK AROUND ******************/ +#endif + + if (status == 0) { +#ifdef FSL_HAVE_SAHARA2 + saha_control |= CTRL_RNG_RESEED; +#endif + +#ifndef SAHARA_POLL_MODE + saha_control |= CTRL_INT_EN; /* enable interrupts */ +#else + sah_poll_timeout = SAHARA_POLL_MODE_TIMEOUT; +#endif + +#ifdef DIAG_DRV_IF + snprintf(Diag_msg, DIAG_MSG_SIZE, + "Setting up Sahara's Control Register: %08x\n", + saha_control); + LOG_KDIAG(Diag_msg); +#endif + + /* Rewrite the setup to the SAHARA Control register */ + sah_HW_Write_Control(saha_control); +#ifdef DIAG_DRV_IF + snprintf(Diag_msg, DIAG_MSG_SIZE, + "Sahara Status register after control write: %08x", + sah_HW_Read_Status()); + LOG_KDIAG(Diag_msg); +#endif + +#ifdef FSL_HAVE_SAHARA4 + { + uint32_t cfg = sah_HW_Read_Config(); + sah_HW_Write_Config(cfg | 0x100); /* Add RNG auto-reseed */ + } +#endif + } else { +#ifdef DIAG_DRV_IF + LOG_KDIAG("Reset failed\n"); +#endif + } + + return status; +} /* sah_HW_Reset() */ + +/*! + * This function enables High Assurance mode. + * + * @brief SAHARA hardware enable High Assurance mode. + * + * @return FSL_RETURN_OK_S - if HA was set successfully + * @return FSL_RETURN_INTERNAL_ERROR_S - if HA was not set due to SAHARA + * being busy. + */ +fsl_shw_return_t sah_HW_Set_HA(void) +{ + /* This is the value to write to the register */ + uint32_t value; + + /* Read from the control register. */ + value = sah_HW_Read_Control(); + + /* Set the HA bit */ + value |= CTRL_HA; + + /* Write to the control register. */ + sah_HW_Write_Control(value); + + /* Read from the control register. */ + value = sah_HW_Read_Control(); + + return (value & CTRL_HA) ? FSL_RETURN_OK_S : + FSL_RETURN_INTERNAL_ERROR_S; +} + +/*! + * This function reads the SAHARA hardware Version Register. + * + * @brief Read SAHARA hardware Version Register. + * + * @return uint32_t Register value. + */ +uint32_t sah_HW_Read_Version(void) +{ + return os_read32(SAHARA_VERSION_REGISTER); +} + +/*! + * This function reads the SAHARA hardware Control Register. + * + * @brief Read SAHARA hardware Control Register. + * + * @return uint32_t Register value. + */ +uint32_t sah_HW_Read_Control(void) +{ + return os_read32(SAHARA_CONTROL_REGISTER); +} + +/*! + * This function reads the SAHARA hardware Status Register. + * + * @brief Read SAHARA hardware Status Register. + * + * @return uint32_t Register value. + */ +uint32_t sah_HW_Read_Status(void) +{ + return os_read32(SAHARA_STATUS_REGISTER); +} + +/*! + * This function reads the SAHARA hardware Error Status Register. + * + * @brief Read SAHARA hardware Error Status Register. + * + * @return uint32_t Error Status value. + */ +uint32_t sah_HW_Read_Error_Status(void) +{ + return os_read32(SAHARA_ESTATUS_REGISTER); +} + +/*! + * This function reads the SAHARA hardware Op Status Register. + * + * @brief Read SAHARA hardware Op Status Register. + * + * @return uint32_t Op Status value. + */ +uint32_t sah_HW_Read_Op_Status(void) +{ + return os_read32(SAHARA_OSTATUS_REGISTER); +} + +/*! + * This function reads the SAHARA hardware Descriptor Address Register. + * + * @brief Read SAHARA hardware DAR Register. + * + * @return uint32_t DAR value. + */ +uint32_t sah_HW_Read_DAR(void) +{ + return os_read32(SAHARA_DAR_REGISTER); +} + +/*! + * This function reads the SAHARA hardware Current Descriptor Address Register. + * + * @brief Read SAHARA hardware CDAR Register. + * + * @return uint32_t CDAR value. + */ +uint32_t sah_HW_Read_CDAR(void) +{ + return os_read32(SAHARA_CDAR_REGISTER); +} + +/*! + * This function reads the SAHARA hardware Initial Descriptor Address Register. + * + * @brief Read SAHARA hardware IDAR Register. + * + * @return uint32_t IDAR value. + */ +uint32_t sah_HW_Read_IDAR(void) +{ + return os_read32(SAHARA_IDAR_REGISTER); +} + +/*! + * This function reads the SAHARA hardware Fault Address Register. + * + * @brief Read SAHARA Fault Address Register. + * + * @return uint32_t Fault Address value. + */ +uint32_t sah_HW_Read_Fault_Address(void) +{ + return os_read32(SAHARA_FLT_ADD_REGISTER); +} + +/*! + * This function reads the SAHARA hardware Multiple Master Status Register. + * + * @brief Read SAHARA hardware MM Stat Register. + * + * @return uint32_t MM Stat value. + */ +uint32_t sah_HW_Read_MM_Status(void) +{ + return os_read32(SAHARA_MM_STAT_REGISTER); +} + +/*! + * This function reads the SAHARA hardware Configuration Register. + * + * @brief Read SAHARA Configuration Register. + * + * @return uint32_t Configuration value. + */ +uint32_t sah_HW_Read_Config(void) +{ + return os_read32(SAHARA_CONFIG_REGISTER); +} + +/*! + * This function writes a command to the SAHARA hardware Command Register. + * + * @brief Write to SAHARA hardware Command Register. + * + * @param command An unsigned 32bit command value. + * + * @return void + */ +void sah_HW_Write_Command(uint32_t command) +{ + os_write32(SAHARA_COMMAND_REGISTER, command); +} + +/*! + * This function writes a control value to the SAHARA hardware Control + * Register. + * + * @brief Write to SAHARA hardware Control Register. + * + * @param control An unsigned 32bit control value. + * + * @return void + */ +void sah_HW_Write_Control(uint32_t control) +{ + os_write32(SAHARA_CONTROL_REGISTER, control); +} + +/*! + * This function writes a configuration value to the SAHARA hardware Configuration + * Register. + * + * @brief Write to SAHARA hardware Configuration Register. + * + * @param configuration An unsigned 32bit configuration value. + * + * @return void + */ +void sah_HW_Write_Config(uint32_t configuration) +{ + os_write32(SAHARA_CONFIG_REGISTER, configuration); +} + +/*! + * This function writes a descriptor address to the SAHARA Descriptor Address + * Register. + * + * @brief Write to SAHARA Descriptor Address Register. + * + * @param pointer An unsigned 32bit descriptor address value. + * + * @return void + */ +void sah_HW_Write_DAR(uint32_t pointer) +{ + os_write32(SAHARA_DAR_REGISTER, pointer); + dar_count++; +} + +#if defined DIAG_DRV_IF || defined DO_DBG + +static char *interpret_header(uint32_t header) +{ + unsigned desc_type = ((header >> 24) & 0x70) | ((header >> 16) & 0xF); + + switch (desc_type) { + case 0x12: + return "5/SKHA_ST_CTX"; + case 0x13: + return "35/SKHA_LD_MODE_KEY"; + case 0x14: + return "38/SKHA_LD_MODE_IN_CPHR_ST_CTX"; + case 0x15: + return "4/SKHA_IN_CPHR_OUT"; + case 0x16: + return "34/SKHA_ST_SBOX"; + case 0x18: + return "1/SKHA_LD_MODE_IV_KEY"; + case 0x19: + return "33/SKHA_ST_SBOX"; + case 0x1D: + return "2/SKHA_LD_MODE_IN_CPHR_OUT"; + case 0x22: + return "11/MDHA_ST_MD"; + case 0x25: + return "10/MDHA_HASH_ST_MD"; + case 0x28: + return "6/MDHA_LD_MODE_MD_KEY"; + case 0x2A: + return "39/MDHA_ICV"; + case 0x2D: + return "8/MDHA_LD_MODE_HASH_ST_MD"; + case 0x3C: + return "18/RNG_GEN"; + case 0x40: + return "19/PKHA_LD_N_E"; + case 0x41: + return "36/PKHA_LD_A3_B0"; + case 0x42: + return "27/PKHA_ST_A_B"; + case 0x43: + return "22/PKHA_LD_A_B"; + case 0x44: + return "23/PKHA_LD_A0_A1"; + case 0x45: + return "24/PKHA_LD_A2_A3"; + case 0x46: + return "25/PKHA_LD_B0_B1"; + case 0x47: + return "26/PKHA_LD_B2_B3"; + case 0x48: + return "28/PKHA_ST_A0_A1"; + case 0x49: + return "29/PKHA_ST_A2_A3"; + case 0x4A: + return "30/PKHA_ST_B0_B1"; + case 0x4B: + return "31/PKHA_ST_B2_B3"; + case 0x4C: + return "32/PKHA_EX_ST_B1"; + case 0x4D: + return "20/PKHA_LD_A_EX_ST_B"; + case 0x4E: + return "21/PKHA_LD_N_EX_ST_B"; + case 0x4F: + return "37/PKHA_ST_B1_B2"; + default: + return "??/UNKNOWN"; + } +} /* cvt_desc_name() */ + +/*! + * Dump chain of descriptors to the log. + * + * @brief Dump descriptor chain + * + * @param chain Kernel virtual address of start of chain of descriptors + * + * @return void + */ +void sah_Dump_Chain(const sah_Desc * chain, dma_addr_t addr) +{ + int desc_no = 1; + + pr_debug("Chain for Sahara\n"); + + while (chain != NULL) { + char desc_name[50]; + + sprintf(desc_name, "Desc %02d (%s)\n" KERN_DEBUG "Desc ", + desc_no++, interpret_header(chain->header)); + + sah_Dump_Words(desc_name, (unsigned *)chain, addr, + 6 /* #words in h/w link */ ); + if (chain->original_ptr1) { + if (chain->header & SAH_HDR_LLO) { + sah_Dump_Region(" Data1", + (unsigned char *)chain-> + original_ptr1, + (dma_addr_t) chain->ptr1, + chain->len1); + } else { + sah_Dump_Link(" Link1", chain->original_ptr1, + (dma_addr_t) chain->ptr1); + } + } + if (chain->ptr2) { + if (chain->header & SAH_HDR_LLO) { + sah_Dump_Region(" Data2", + (unsigned char *)chain-> + original_ptr2, + (dma_addr_t) chain->ptr2, + chain->len2); + } else { + sah_Dump_Link(" Link2", chain->original_ptr2, + (dma_addr_t) chain->ptr2); + } + } + + addr = (dma_addr_t) chain->next; + chain = (chain->next) ? (chain->original_next) : NULL; + } +} + +/*! + * Dump chain of links to the log. + * + * @brief Dump chain of links + * + * @param prefix Text to put in front of dumped data + * @param link Kernel virtual address of start of chain of links + * + * @return void + */ +static void sah_Dump_Link(const char *prefix, const sah_Link * link, + dma_addr_t addr) +{ +#ifdef DUMP_SCC_DATA + extern uint8_t *sahara_partition_base; + extern dma_addr_t sahara_partition_phys; +#endif + + while (link != NULL) { + sah_Dump_Words(prefix, (unsigned *)link, addr, + 3 /* # words in h/w link */ ); + if (link->flags & SAH_STORED_KEY_INFO) { +#ifdef SAH_DUMP_DATA +#ifdef DUMP_SCC_DATA + sah_Dump_Region(" Data", + (uint8_t *) link->data - + (uint8_t *) sahara_partition_phys + + sahara_partition_base, + (dma_addr_t) link->data, link->len); +#else + pr_debug(" Key Slot %d\n", link->slot); +#endif +#endif + } else { +#ifdef SAH_DUMP_DATA + sah_Dump_Region(" Data", link->original_data, + (dma_addr_t) link->data, link->len); +#endif + } + addr = (dma_addr_t) link->next; + link = link->original_next; + } +} + +/*! + * Dump given region of data to the log. + * + * @brief Dump data + * + * @param prefix Text to put in front of dumped data + * @param data Kernel virtual address of start of region to dump + * @param length Amount of data to dump + * + * @return void + */ +void sah_Dump_Region(const char *prefix, const unsigned char *data, + dma_addr_t addr, unsigned length) +{ + unsigned count; + char *output; + unsigned data_len; + + sprintf(Diag_msg, "%s (%08X,%u):", prefix, addr, length); + + /* Restrict amount of data to dump */ + if (length > MAX_DUMP) { + data_len = MAX_DUMP; + } else { + data_len = length; + } + + /* We've already printed some text in output buffer, skip over it */ + output = Diag_msg + strlen(Diag_msg); + + for (count = 0; count < data_len; count++) { + if ((count % 4) == 0) { + *output++ = ' '; + } + sprintf(output, "%02X", *data++); + output += 2; + } + + pr_debug("%s\n", Diag_msg); +} + +/*! + * Dump given word of data to the log. + * + * @brief Dump data + * + * @param prefix Text to put in front of dumped data + * @param data Kernel virtual address of start of region to dump + * @param word_count Amount of data to dump + * + * @return void + */ +void sah_Dump_Words(const char *prefix, const unsigned *data, dma_addr_t addr, + unsigned word_count) +{ + char *output; + + sprintf(Diag_msg, "%s (%08X,%uw): ", prefix, addr, word_count); + + /* We've already printed some text in output buffer, skip over it */ + output = Diag_msg + strlen(Diag_msg); + + while (word_count--) { + sprintf(output, "%08X ", *data++); + output += 9; + } + + pr_debug("%s\n", Diag_msg); + +} + +#endif /* DIAG_DRV_IF */ + +/* End of sah_hardware_interface.c */ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/fsl_shw_wrap.c +++ linux-2.6.28/drivers/mxc/security/sahara2/fsl_shw_wrap.c @@ -0,0 +1,967 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @file fsl_shw_wrap.c + * + * This file implements Key-Wrap (Black Key) functions of the FSL SHW API for + * Sahara. + * + * - Ownerid is an 8-byte, user-supplied, value to keep KEY confidential. + * - KEY is a 1-32 byte value which starts in SCC RED RAM before + * wrapping, and ends up there on unwrap. Length is limited because of + * size of SCC1 RAM. + * - KEY' is the encrypted KEY + * - LEN is a 1-byte (for now) byte-length of KEY + * - ALG is a 1-byte value for the algorithm which which the key is + * associated. Values are defined by the FSL SHW API + * - Ownerid, LEN, and ALG come from the user's "key_info" object, as does the + * slot number where KEY already is/will be. + * - T is a Nonce + * - T' is the encrypted T + * - KEK is a Key-Encryption Key for the user's Key + * - ICV is the "Integrity Check Value" for the wrapped key + * - Black Key is the string of bytes returned as the wrapped key + + + + + + + + + + + + + + + + + + +
BLACK_KEY =ICV | T' | LEN | ALG | + KEY'
 
To Wrap
T = RND()16 +
KEK=HASHsha256(T | + Ownerid)16
KEY'= + AESctr-enc(Key=KEK, CTR=0, Data=KEY)
ICV=HMACsha256 + (Key=T, Data=Ownerid | LEN | ALG | KEY')16
T'=TDEScbc-enc + (Key=SLID, IV=Ownerid, Data=T)
 
To Unwrap
T=TDESecb-dec + (Key=SLID, IV=Ownerid, Data=T')
ICV=HMACsha256 + (Key=T, Data=Ownerid | LEN | ALG | KEY')16
KEK=HASHsha256 + (T | Ownerid)16
KEY=AESctr-dec + (Key=KEK, CTR=0, Data=KEY')
+ + */ + +#include "sahara.h" +#include "fsl_platform.h" +#include "fsl_shw_keystore.h" + +#include "sf_util.h" +#include "adaptor.h" + +#if defined(DIAG_SECURITY_FUNC) +#include +#endif + +#if defined(NEED_CTR_WORKAROUND) +/* CTR mode needs block-multiple data in/out */ +#define LENGTH_PATCH 16 +#define LENGTH_PATCH_MASK 0xF +#else +#define LENGTH_PATCH 4 +#define LENGTH_PATCH_MASK 3 +#endif + +#if LENGTH_PATCH +#define ROUND_LENGTH(len) \ +({ \ + uint32_t orig_len = len; \ + uint32_t new_len; \ + \ + if ((orig_len & LENGTH_PATCH_MASK) != 0) { \ + new_len = (orig_len + LENGTH_PATCH \ + - (orig_len & LENGTH_PATCH_MASK)); \ + } \ + else { \ + new_len = orig_len; \ + } \ + new_len; \ +}) +#else +#define ROUND_LENGTH(len) (len) +#endif + +#ifdef __KERNEL__ +EXPORT_SYMBOL(fsl_shw_establish_key); +EXPORT_SYMBOL(fsl_shw_extract_key); +EXPORT_SYMBOL(fsl_shw_release_key); +EXPORT_SYMBOL(fsl_shw_read_key); +#endif + +#define ICV_LENGTH 16 +#define T_LENGTH 16 +#define KEK_LENGTH 16 +#define LENGTH_LENGTH 1 +#define ALGORITHM_LENGTH 1 +#define FLAGS_LENGTH 1 + +/* ICV | T' | LEN | ALG | KEY' */ +#define ICV_OFFSET 0 +#define T_PRIME_OFFSET (ICV_OFFSET + ICV_LENGTH) +#define LENGTH_OFFSET (T_PRIME_OFFSET + T_LENGTH) +#define ALGORITHM_OFFSET (LENGTH_OFFSET + LENGTH_LENGTH) +#define FLAGS_OFFSET (ALGORITHM_OFFSET + ALGORITHM_LENGTH) +#define KEY_PRIME_OFFSET (FLAGS_OFFSET + FLAGS_LENGTH) +#define FLAGS_SW_KEY 0x01 + +/* + * For testing of the algorithm implementation,, the DO_REPEATABLE_WRAP flag + * causes the T_block to go into the T field during a wrap operation. This + * will make the black key value repeatable (for a given SCC secret key, or + * always if the default key is in use). + * + * Normally, a random sequence is used. + */ +#ifdef DO_REPEATABLE_WRAP +/*! + * Block of zeroes which is maximum Symmetric block size, used for + * initializing context register, etc. + */ +static uint8_t T_block_[16] = { + 0x42, 0, 0, 0x42, 0x42, 0, 0, 0x42, + 0x42, 0, 0, 0x42, 0x42, 0, 0, 0x42 +}; +#endif + +/*! + * Insert descriptors to calculate ICV = HMAC(key=T, data=LEN|ALG|KEY') + * + * @param user_ctx User's context for this operation + * @param desc_chain Descriptor chain to append to + * @param t_key_info T's key object + * @param black_key Beginning of Black Key region + * @param key_length Number of bytes of key' there are in @c black_key + * @param[out] hmac Location to store ICV. Will be tagged "USES" so + * sf routines will not try to free it. + * + * @return A return code of type #fsl_shw_return_t. + */ +static inline fsl_shw_return_t create_icv_calc(fsl_shw_uco_t * user_ctx, + sah_Head_Desc ** desc_chain, + fsl_shw_sko_t * t_key_info, + const uint8_t * black_key, + uint32_t key_length, + uint8_t * hmac) +{ + fsl_shw_return_t sah_code; + uint32_t header; + sah_Link *link1 = NULL; + sah_Link *link2 = NULL; + + /* Load up T as key for the HMAC */ + header = (SAH_HDR_MDHA_SET_MODE_MD_KEY /* #6 */ + ^ sah_insert_mdha_algorithm_sha256 + ^ sah_insert_mdha_init ^ sah_insert_mdha_hmac ^ + sah_insert_mdha_pdata ^ sah_insert_mdha_mac_full); + sah_code = sah_add_in_key_desc(header, NULL, 0, t_key_info, /* Reference T in RED */ + user_ctx->mem_util, desc_chain); + if (sah_code != FSL_RETURN_OK_S) { + goto out; + } + + /* Previous step loaded key; Now set up to hash the data */ + header = SAH_HDR_MDHA_HASH; /* #10 */ + + /* Input - start with ownerid */ + sah_code = sah_Create_Link(user_ctx->mem_util, &link1, + (void *)&t_key_info->userid, + sizeof(t_key_info->userid), + SAH_USES_LINK_DATA); + if (sah_code != FSL_RETURN_OK_S) { + goto out; + } + + /* Still input - Append black-key fields len, alg, key' */ + sah_code = sah_Append_Link(user_ctx->mem_util, link1, + (void *)black_key + LENGTH_OFFSET, + (LENGTH_LENGTH + + ALGORITHM_LENGTH + + key_length), SAH_USES_LINK_DATA); + + if (sah_code != FSL_RETURN_OK_S) { + goto out; + } + /* Output - computed ICV/HMAC */ + sah_code = sah_Create_Link(user_ctx->mem_util, &link2, + hmac, ICV_LENGTH, + SAH_USES_LINK_DATA | SAH_OUTPUT_LINK); + if (sah_code != FSL_RETURN_OK_S) { + goto out; + } + + sah_code = sah_Append_Desc(user_ctx->mem_util, desc_chain, + header, link1, link2); + + out: + if (sah_code != FSL_RETURN_OK_S) { + (void)sah_Destroy_Link(user_ctx->mem_util, link1); + (void)sah_Destroy_Link(user_ctx->mem_util, link2); + } + + return sah_code; +} /* create_icv_calc */ + +/*! + * Perform unwrapping of a black key into a RED slot + * + * @param user_ctx A user context from #fsl_shw_register_user(). + * @param[in,out] key_info The information about the key to be which will + * be unwrapped... key length, slot info, etc. + * @param black_key Encrypted key + * + * @return A return code of type #fsl_shw_return_t. + */ +static fsl_shw_return_t unwrap(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info, + const uint8_t * black_key) +{ + SAH_SF_DCLS; + uint8_t *hmac = NULL; + fsl_shw_sko_t t_key_info; + sah_Link *link1 = NULL; + sah_Link *link2 = NULL; + unsigned i; + unsigned rounded_key_length; + unsigned original_key_length = key_info->key_length; + + hmac = DESC_TEMP_ALLOC(ICV_LENGTH); + + /* Set up key_info for "T" - use same slot as eventual key */ + fsl_shw_sko_init(&t_key_info, FSL_KEY_ALG_AES); + t_key_info.userid = key_info->userid; + t_key_info.handle = key_info->handle; + t_key_info.flags = key_info->flags; + t_key_info.key_length = T_LENGTH; + t_key_info.keystore = key_info->keystore; + + /* Validate SW flags to prevent misuse */ + if ((key_info->flags & FSL_SKO_KEY_SW_KEY) + && !(black_key[FLAGS_OFFSET] & FLAGS_SW_KEY)) { + ret = FSL_RETURN_BAD_FLAG_S; + goto out; + } + + /* Compute T = SLID_decrypt(T'); leave in RED slot */ + if (key_info->keystore == NULL) { + /* Key goes in system keystore */ + ret = do_system_keystore_slot_decrypt(user_ctx, + key_info->userid, + t_key_info.handle, + T_LENGTH, + black_key + T_PRIME_OFFSET); + + } else { + /* Key goes in user keystore */ + ret = keystore_slot_decrypt(user_ctx, + key_info->keystore, + key_info->userid, + t_key_info.handle, + T_LENGTH, + black_key + T_PRIME_OFFSET); + } + if (ret != FSL_RETURN_OK_S) { + goto out; + } + + /* Compute ICV = HMAC(T, ownerid | len | alg | key' */ + ret = create_icv_calc(user_ctx, &desc_chain, &t_key_info, + black_key, original_key_length, hmac); + if (ret != FSL_RETURN_OK_S) { +#ifdef DIAG_SECURITY_FUNC + LOG_DIAG("Creation of sah_Key_Link failed due to bad key" + " flag!\n"); +#endif /*DIAG_SECURITY_FUNC */ + goto out; + } +#ifdef DIAG_SECURITY_FUNC + LOG_DIAG("Validating MAC of wrapped key"); +#endif + SAH_SF_EXECUTE(); + if (ret != FSL_RETURN_OK_S) { + goto out; + } + SAH_SF_DESC_CLEAN(); + + /* Check computed ICV against value in Black Key */ + for (i = 0; i < ICV_LENGTH; i++) { + if (black_key[ICV_OFFSET + i] != hmac[i]) { +#ifdef DIAG_SECURITY_FUNC + LOG_DIAG_ARGS("computed ICV fails at offset %i\n", i); + + { + char buff[300]; + int a; + for (a = 0; a < ICV_LENGTH; a++) + sprintf(&(buff[a * 2]), "%02x", + black_key[ICV_OFFSET + a]); + buff[a * 2 + 1] = 0; + LOG_DIAG_ARGS("black key: %s", buff); + + for (a = 0; a < ICV_LENGTH; a++) + sprintf(&(buff[a * 2]), "%02x", + hmac[a]); + buff[a * 2 + 1] = 0; + LOG_DIAG_ARGS("hmac: %s", buff); + } +#endif + ret = FSL_RETURN_AUTH_FAILED_S; + goto out; + } + } + + /* This is no longer needed. */ + DESC_TEMP_FREE(hmac); + + /* Compute KEK = SHA256(T | ownerid). Rewrite slot with value */ + header = (SAH_HDR_MDHA_SET_MODE_HASH /* #8 */ + ^ sah_insert_mdha_init + ^ sah_insert_mdha_algorithm_sha256 ^ sah_insert_mdha_pdata); + + /* Input - Start with T */ + ret = sah_Create_Key_Link(user_ctx->mem_util, &link1, &t_key_info); + if (ret != FSL_RETURN_OK_S) { + goto out; + } + + /* Still input - append ownerid */ + ret = sah_Append_Link(user_ctx->mem_util, link1, + (void *)&key_info->userid, + sizeof(key_info->userid), SAH_USES_LINK_DATA); + if (ret != FSL_RETURN_OK_S) { + goto out; + } + + /* Output - KEK goes into RED slot */ + ret = sah_Create_Key_Link(user_ctx->mem_util, &link2, &t_key_info); + if (ret != FSL_RETURN_OK_S) { + goto out; + } + + /* Put the Hash calculation into the chain. */ + ret = sah_Append_Desc(user_ctx->mem_util, &desc_chain, + header, link1, link2); + if (ret != FSL_RETURN_OK_S) { + goto out; + } + + /* Compute KEY = AES-decrypt(KEK, KEY') */ + header = (SAH_HDR_SKHA_SET_MODE_IV_KEY /* #1 */ + ^ sah_insert_skha_mode_ctr + ^ sah_insert_skha_algorithm_aes + ^ sah_insert_skha_modulus_128); + /* Load KEK in as the key to use */ + DESC_IN_KEY(header, 0, NULL, &t_key_info); + + rounded_key_length = ROUND_LENGTH(original_key_length); + key_info->key_length = rounded_key_length; + + /* Now set up for computation. Result in RED */ + header = SAH_HDR_SKHA_ENC_DEC; /* #4 */ + DESC_IN_KEY(header, rounded_key_length, black_key + KEY_PRIME_OFFSET, + key_info); + + /* Perform the operation */ +#ifdef DIAG_SECURITY_FUNC + LOG_DIAG("Decrypting key with KEK"); +#endif + SAH_SF_EXECUTE(); + + out: + key_info->key_length = original_key_length; + SAH_SF_DESC_CLEAN(); + + DESC_TEMP_FREE(hmac); + + /* Erase tracks */ + t_key_info.userid = 0xdeadbeef; + t_key_info.handle = 0xdeadbeef; + + return ret; +} /* unwrap */ + +/*! + * Perform wrapping of a black key from a RED slot + * + * @param user_ctx A user context from #fsl_shw_register_user(). + * @param[in,out] key_info The information about the key to be which will + * be wrapped... key length, slot info, etc. + * @param black_key Place to store encrypted key + * + * @return A return code of type #fsl_shw_return_t. + */ +static fsl_shw_return_t wrap(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info, uint8_t * black_key) +{ + SAH_SF_DCLS; + unsigned slots_allocated = 0; /* boolean */ + fsl_shw_sko_t T_key_info; /* for holding T */ + fsl_shw_sko_t KEK_key_info; /* for holding KEK */ + unsigned original_key_length = key_info->key_length; + unsigned rounded_key_length; + sah_Link *link1; + sah_Link *link2; + + black_key[LENGTH_OFFSET] = key_info->key_length; + black_key[ALGORITHM_OFFSET] = key_info->algorithm; + + memcpy(&T_key_info, key_info, sizeof(T_key_info)); + fsl_shw_sko_set_key_length(&T_key_info, T_LENGTH); + T_key_info.algorithm = FSL_KEY_ALG_HMAC; + + memcpy(&KEK_key_info, &T_key_info, sizeof(KEK_key_info)); + KEK_key_info.algorithm = FSL_KEY_ALG_AES; + + if (key_info->keystore == NULL) { + /* Key goes in system keystore */ + ret = do_system_keystore_slot_alloc(user_ctx, + T_LENGTH, key_info->userid, + &T_key_info.handle); + + } else { + /* Key goes in user keystore */ + ret = keystore_slot_alloc(key_info->keystore, + T_LENGTH, + key_info->userid, &T_key_info.handle); + } + if (ret != FSL_RETURN_OK_S) { + goto out; + } + + if (key_info->keystore == NULL) { + /* Key goes in system keystore */ + ret = do_system_keystore_slot_alloc(user_ctx, + KEK_LENGTH, key_info->userid, + &KEK_key_info.handle); + + } else { + /* Key goes in user keystore */ + ret = keystore_slot_alloc(key_info->keystore, + KEK_LENGTH, key_info->userid, + &KEK_key_info.handle); + } + + if (ret != FSL_RETURN_OK_S) { +#ifdef DIAG_SECURITY_FUNC + LOG_DIAG("do_scc_slot_alloc() failed"); +#endif + if (key_info->keystore == NULL) { + /* Key goes in system keystore */ + (void)do_system_keystore_slot_dealloc(user_ctx, + key_info->userid, T_key_info.handle); + + } else { + /* Key goes in user keystore */ + (void)keystore_slot_dealloc(key_info->keystore, + key_info->userid, T_key_info.handle); + } + } else { + slots_allocated = 1; + } + + /* Set up to compute everything except T' ... */ +#ifndef DO_REPEATABLE_WRAP + /* Compute T = RND() */ + header = SAH_HDR_RNG_GENERATE; /* Desc. #18 */ + DESC_KEY_OUT(header, &T_key_info, 0, NULL); +#else + if (key_info->keystore == NULL) { + /* Key goes in system keystore */ + ret = do_system_keystore_slot_load(user_ctx, + T_key_info.userid, + T_key_info.handle, T_block, + T_key_info.key_length); + } else { + /* Key goes in user keystore */ + ret = keystore_slot_load(key_info->keystore, + T_key_info.userid, + T_key_info.handle, + T_block, T_key_info.key_length); + } + + if (ret != FSL_RETURN_OK_S) { + goto out; + } +#endif + + /* Compute KEK = SHA256(T | Ownerid) */ + header = (SAH_HDR_MDHA_SET_MODE_HASH /* #8 */ + ^ sah_insert_mdha_init + ^ sah_insert_mdha_algorithm[FSL_HASH_ALG_SHA256] + ^ sah_insert_mdha_pdata); + /* Input - Start with T */ + ret = sah_Create_Key_Link(user_ctx->mem_util, &link1, &T_key_info); + if (ret != FSL_RETURN_OK_S) { + goto out; + } + /* Still input - append ownerid */ + ret = sah_Append_Link(user_ctx->mem_util, link1, + (void *)&key_info->userid, + sizeof(key_info->userid), SAH_USES_LINK_DATA); + if (ret != FSL_RETURN_OK_S) { + goto out; + } + /* Output - KEK goes into RED slot */ + ret = sah_Create_Key_Link(user_ctx->mem_util, &link2, &KEK_key_info); + if (ret != FSL_RETURN_OK_S) { + goto out; + } + /* Put the Hash calculation into the chain. */ + ret = sah_Append_Desc(user_ctx->mem_util, &desc_chain, + header, link1, link2); + if (ret != FSL_RETURN_OK_S) { + goto out; + } +#if defined(NEED_CTR_WORKAROUND) + rounded_key_length = ROUND_LENGTH(original_key_length); + key_info->key_length = rounded_key_length; +#else + rounded_key_length = original_key_length; +#endif + /* Compute KEY' = AES-encrypt(KEK, KEY) */ + header = (SAH_HDR_SKHA_SET_MODE_IV_KEY /* #1 */ + ^ sah_insert_skha_mode[FSL_SYM_MODE_CTR] + ^ sah_insert_skha_algorithm[FSL_KEY_ALG_AES] + ^ sah_insert_skha_modulus[FSL_CTR_MOD_128]); + /* Set up KEK as key to use */ + DESC_IN_KEY(header, 0, NULL, &KEK_key_info); + header = SAH_HDR_SKHA_ENC_DEC; + DESC_KEY_OUT(header, key_info, + key_info->key_length, black_key + KEY_PRIME_OFFSET); + + /* Set up flags info */ + black_key[FLAGS_OFFSET] = 0; + if (key_info->flags & FSL_SKO_KEY_SW_KEY) { + black_key[FLAGS_OFFSET] |= FLAGS_SW_KEY; + } + + /* Compute and store ICV into Black Key */ + ret = create_icv_calc(user_ctx, &desc_chain, &T_key_info, + black_key, original_key_length, + black_key + ICV_OFFSET); + if (ret != FSL_RETURN_OK_S) { +#ifdef DIAG_SECURITY_FUNC + LOG_DIAG("Creation of sah_Key_Link failed due to bad key" + " flag!\n"); +#endif /*DIAG_SECURITY_FUNC */ + goto out; + } + + /* Now get Sahara to do the work. */ +#ifdef DIAG_SECURITY_FUNC + LOG_DIAG("Encrypting key with KEK"); +#endif + SAH_SF_EXECUTE(); + if (ret != FSL_RETURN_OK_S) { +#ifdef DIAG_SECURITY_FUNC + LOG_DIAG("sah_Descriptor_Chain_Execute() failed"); +#endif + goto out; + } + + /* Compute T' = SLID_encrypt(T); Result goes to Black Key */ + if (key_info->keystore == NULL) { + /* Key goes in system keystore */ + ret = do_system_keystore_slot_encrypt(user_ctx, + T_key_info.userid, T_key_info.handle, + T_LENGTH, black_key + T_PRIME_OFFSET); + } else { + /* Key goes in user keystore */ + ret = keystore_slot_encrypt(user_ctx, + key_info->keystore, + T_key_info.userid, + T_key_info.handle, + T_LENGTH, + black_key + T_PRIME_OFFSET); + } + + if (ret != FSL_RETURN_OK_S) { +#ifdef DIAG_SECURITY_FUNC + LOG_DIAG("do_scc_slot_encrypt() failed"); +#endif + goto out; + } + + out: + key_info->key_length = original_key_length; + + SAH_SF_DESC_CLEAN(); + if (slots_allocated) { + if (key_info->keystore == NULL) { + /* Key goes in system keystore */ + (void)do_system_keystore_slot_dealloc(user_ctx, + key_info->userid, + T_key_info. + handle); + (void)do_system_keystore_slot_dealloc(user_ctx, + key_info->userid, + KEK_key_info. + handle); + } else { + /* Key goes in user keystore */ + (void)keystore_slot_dealloc(key_info->keystore, + key_info->userid, + T_key_info.handle); + (void)keystore_slot_dealloc(key_info->keystore, + key_info->userid, + KEK_key_info.handle); + } + } + + return ret; +} /* wrap */ + +/*! + * Place a key into a protected location for use only by cryptographic + * algorithms. + * + * This only needs to be used to a) unwrap a key, or b) set up a key which + * could be wrapped with a later call to #fsl_shw_extract_key(). Normal + * cleartext keys can simply be placed into #fsl_shw_sko_t key objects with + * #fsl_shw_sko_set_key() and used directly. + * + * The maximum key size supported for wrapped/unwrapped keys is 32 octets. + * (This is the maximum reasonable key length on Sahara - 32 octets for an HMAC + * key based on SHA-256.) The key size is determined by the @a key_info. The + * expected length of @a key can be determined by + * #fsl_shw_sko_calculate_wrapped_size() + * + * The protected key will not be available for use until this operation + * successfully completes. + * + * This feature is not available for all platforms, nor for all algorithms and + * modes. + * + * @param user_ctx A user context from #fsl_shw_register_user(). + * @param[in,out] key_info The information about the key to be which will + * be established. In the create case, the key + * length must be set. + * @param establish_type How @a key will be interpreted to establish a + * key for use. + * @param key If @a establish_type is #FSL_KEY_WRAP_UNWRAP, + * this is the location of a wrapped key. If + * @a establish_type is #FSL_KEY_WRAP_CREATE, this + * parameter can be @a NULL. If @a establish_type + * is #FSL_KEY_WRAP_ACCEPT, this is the location + * of a plaintext key. + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t fsl_shw_establish_key(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info, + fsl_shw_key_wrap_t establish_type, + const uint8_t * key) +{ + SAH_SF_DCLS; + unsigned original_key_length = key_info->key_length; + unsigned rounded_key_length; + unsigned slot_allocated = 0; + uint32_t old_flags; + + header = SAH_HDR_RNG_GENERATE; /* Desc. #18 for rand */ + + /* TODO: THIS STILL NEEDS TO BE REFACTORED */ + + /* Write operations into SCC memory require word-multiple number of + * bytes. For ACCEPT and CREATE functions, the key length may need + * to be rounded up. Calculate. */ + if (LENGTH_PATCH && (original_key_length & LENGTH_PATCH_MASK) != 0) { + rounded_key_length = original_key_length + LENGTH_PATCH + - (original_key_length & LENGTH_PATCH_MASK); + } else { + rounded_key_length = original_key_length; + } + + SAH_SF_USER_CHECK(); + + if (key_info->flags & FSL_SKO_KEY_ESTABLISHED) { +#ifdef DIAG_SECURITY_FUNC + ret = FSL_RETURN_BAD_FLAG_S; + LOG_DIAG("Key already established\n"); +#endif + } + + + if (key_info->keystore == NULL) { + /* Key goes in system keystore */ + ret = do_system_keystore_slot_alloc(user_ctx, + key_info->key_length, + key_info->userid, + &(key_info->handle)); +#ifdef DIAG_SECURITY_FUNC + LOG_DIAG_ARGS + ("key length: %i, handle: %i, rounded key length: %i", + key_info->key_length, key_info->handle, + rounded_key_length); +#endif + + } else { + /* Key goes in user keystore */ + ret = keystore_slot_alloc(key_info->keystore, + key_info->key_length, + key_info->userid, + &(key_info->handle)); + } + if (ret != FSL_RETURN_OK_S) { +#ifdef DIAG_SECURITY_FUNC + LOG_DIAG("Slot allocation failed\n"); +#endif + goto out; + } + slot_allocated = 1; + + key_info->flags |= FSL_SKO_KEY_ESTABLISHED; + switch (establish_type) { + case FSL_KEY_WRAP_CREATE: +#ifdef DIAG_SECURITY_FUNC + LOG_DIAG("Creating random key\n"); +#endif + /* Use safe version of key length */ + key_info->key_length = rounded_key_length; + /* Generate descriptor to put random value into */ + DESC_KEY_OUT(header, key_info, 0, NULL); + /* Restore actual, desired key length */ + key_info->key_length = original_key_length; + + old_flags = user_ctx->flags; + /* Now put random value into key */ + SAH_SF_EXECUTE(); + /* Restore user's old flag value */ + user_ctx->flags = old_flags; +#ifdef DIAG_SECURITY_FUNC + if (ret == FSL_RETURN_OK_S) { + LOG_DIAG("ret is ok"); + } else { + LOG_DIAG("ret is not ok"); + } +#endif + break; + + case FSL_KEY_WRAP_ACCEPT: +#ifdef DIAG_SECURITY_FUNC + LOG_DIAG("Accepting plaintext key\n"); +#endif + if (key == NULL) { +#ifdef DIAG_SECURITY_FUNC + LOG_DIAG("ACCEPT: Red Key is NULL"); +#endif + ret = FSL_RETURN_ERROR_S; + goto out; + } + /* Copy in safe number of bytes of Red key */ + if (key_info->keystore == NULL) { + /* Key goes in system keystore */ + ret = do_system_keystore_slot_load(user_ctx, + key_info->userid, + key_info->handle, key, + rounded_key_length); + } else { + /* Key goes in user keystore */ + ret = keystore_slot_load(key_info->keystore, + key_info->userid, + key_info->handle, key, + key_info->key_length); + } + break; + + case FSL_KEY_WRAP_UNWRAP: +#ifdef DIAG_SECURITY_FUNC + LOG_DIAG("Unwrapping wrapped key\n"); +#endif + /* For now, disallow non-blocking calls. */ + if (!(user_ctx->flags & FSL_UCO_BLOCKING_MODE)) { + ret = FSL_RETURN_BAD_FLAG_S; + } else if (key == NULL) { + ret = FSL_RETURN_ERROR_S; + } else { + ret = unwrap(user_ctx, key_info, key); + } + break; + + default: + ret = FSL_RETURN_BAD_FLAG_S; + break; + } /* switch */ + + out: + if (slot_allocated && (ret != FSL_RETURN_OK_S)) { + fsl_shw_return_t scc_err; + + if (key_info->keystore == NULL) { + /* Key goes in system keystore */ + scc_err = do_system_keystore_slot_dealloc(user_ctx, + key_info->userid, + key_info->handle); + } else { + /* Key goes in user keystore */ + scc_err = keystore_slot_dealloc(key_info->keystore, + key_info->userid, key_info->handle); + } + + key_info->flags &= ~FSL_SKO_KEY_ESTABLISHED; + } + + SAH_SF_DESC_CLEAN(); + + return ret; +} /* fsl_shw_establish_key() */ + +/*! + * Wrap a key and retrieve the wrapped value. + * + * A wrapped key is a key that has been cryptographically obscured. It is + * only able to be used with #fsl_shw_establish_key(). + * + * This function will also release the key (see #fsl_shw_release_key()) so + * that it must be re-established before reuse. + * + * This feature is not available for all platforms, nor for all algorithms and + * modes. + * + * @param user_ctx A user context from #fsl_shw_register_user(). + * @param key_info The information about the key to be deleted. + * @param[out] covered_key The location to store the 48-octet wrapped key. + * (This size is based upon the maximum key size + * of 32 octets). + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t fsl_shw_extract_key(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info, + uint8_t * covered_key) +{ + SAH_SF_DCLS; + + SAH_SF_USER_CHECK(); + + /* For now, only blocking mode calls are supported */ + if (user_ctx->flags & FSL_UCO_BLOCKING_MODE) { + if (key_info->flags & FSL_SKO_KEY_ESTABLISHED) { + ret = wrap(user_ctx, key_info, covered_key); + if (ret != FSL_RETURN_OK_S) { + goto out; + } + + /* Verify that a SW key info really belongs to a SW key */ + if (key_info->flags & FSL_SKO_KEY_SW_KEY) { + /* ret = FSL_RETURN_BAD_FLAG_S; + goto out;*/ + } + + /* Need to deallocate on successful extraction */ + if (key_info->keystore == NULL) { + /* Key goes in system keystore */ + ret = do_system_keystore_slot_dealloc(user_ctx, + key_info->userid, key_info->handle); + } else { + /* Key goes in user keystore */ + ret = keystore_slot_dealloc(key_info->keystore, + key_info->userid, key_info->handle); + } + /* Mark key not available in the flags */ + key_info->flags &= + ~(FSL_SKO_KEY_ESTABLISHED | FSL_SKO_KEY_PRESENT); + } + } + +out: + SAH_SF_DESC_CLEAN(); + + return ret; +} + +/*! + * De-establish a key so that it can no longer be accessed. + * + * The key will need to be re-established before it can again be used. + * + * This feature is not available for all platforms, nor for all algorithms and + * modes. + * + * @param user_ctx A user context from #fsl_shw_register_user(). + * @param key_info The information about the key to be deleted. + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t fsl_shw_release_key(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info) +{ + SAH_SF_DCLS; + + SAH_SF_USER_CHECK(); + + if (key_info->flags & FSL_SKO_KEY_ESTABLISHED) { + if (key_info->keystore == NULL) { + /* Key goes in system keystore */ + do_system_keystore_slot_dealloc(user_ctx, + key_info->userid, + key_info->handle); + } else { + /* Key goes in user keystore */ + keystore_slot_dealloc(key_info->keystore, + key_info->userid, + key_info->handle); + } + key_info->flags &= ~(FSL_SKO_KEY_ESTABLISHED | + FSL_SKO_KEY_PRESENT); + } + +out: + SAH_SF_DESC_CLEAN(); + + return ret; +} + +fsl_shw_return_t fsl_shw_read_key(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info, uint8_t * key) +{ + SAH_SF_DCLS; + + SAH_SF_USER_CHECK(); + + if (!(key_info->flags & FSL_SKO_KEY_ESTABLISHED) + || !(key_info->flags & FSL_SKO_KEY_SW_KEY)) { + ret = FSL_RETURN_BAD_FLAG_S; + goto out; + } + + if (key_info->keystore == NULL) { + /* Key lives in system keystore */ + ret = do_system_keystore_slot_read(user_ctx, + key_info->userid, + key_info->handle, + key_info->key_length, key); + } else { + /* Key lives in user keystore */ + ret = keystore_slot_read(key_info->keystore, + key_info->userid, + key_info->handle, + key_info->key_length, key); + } + + out: + SAH_SF_DESC_CLEAN(); + + return ret; +} --- linux-2.6.28.orig/drivers/mxc/security/sahara2/sah_interrupt_handler.c +++ linux-2.6.28/drivers/mxc/security/sahara2/sah_interrupt_handler.c @@ -0,0 +1,216 @@ +/* + * Copyright 2004-2008 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 + */ + +/*! +* @file sah_interrupt_handler.c +* +* @brief Provides a hardware interrupt handling mechanism for device driver. +* +* This file needs to be ported for a non-Linux OS. +* +* It gets a call at #sah_Intr_Init() during initialization. +* +* #sah_Intr_Top_Half() is intended to be the Interrupt Service Routine. It +* calls a portable function in another file to process the Sahara status. +* +* #sah_Intr_Bottom_Half() is a 'background' task scheduled by the top half to +* take care of the expensive tasks of the interrupt processing. +* +* The driver shutdown code calls #sah_Intr_Release(). +* +*/ + +#include + +/* SAHARA Includes */ +#include +#include +#include +#include +#include + +/*Enable this flag for debugging*/ +#if 0 +#define DIAG_DRV_INTERRUPT +#endif + +#ifdef DIAG_DRV_INTERRUPT +#include +#endif + +/*! + * Number of interrupts received. This value should only be updated during + * interrupt processing. + */ +uint32_t interrupt_count; + +#ifndef SAHARA_POLL_MODE + +#if !defined(LINUX_VERSION_CODE) || LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +#define irqreturn_t void +#define IRQ_HANDLED +#define IRQ_RETVAL(x) +#endif + +/* Internal Prototypes */ +static irqreturn_t sah_Intr_Top_Half(int irq, void *dev_id); + +#ifdef KERNEL_TEST +extern void (*SAHARA_INT_PTR) (int, void *); +#endif + +unsigned long reset_flag; +static void sah_Intr_Bottom_Half(unsigned long reset_flag); + +/* This is the Bottom Half Task, (reset flag set to false) */ +DECLARE_TASKLET(BH_task, sah_Intr_Bottom_Half, (unsigned long)&reset_flag); + +/*! This is set by the Initialisation function */ +wait_queue_head_t *int_queue = NULL; + +/*! +******************************************************************************* +* This function registers the Top Half of the interrupt handler with the Kernel +* and the SAHARA IRQ number. +* +* @brief SAHARA Interrupt Handler Initialisation +* +* @param wait_queue Pointer to the wait queue used by driver interface +* +* @return int A return of Zero indicates successful initialisation. +*/ +/****************************************************************************** +* +* CAUTION: NONE +* +* MODIFICATION HISTORY: +* +* Date Person Change +* 30/07/2003 MW Initial Creation +******************************************************************************/ +int sah_Intr_Init(wait_queue_head_t * wait_queue) +{ + +#ifdef DIAG_DRV_INTERRUPT + char err_string[200]; +#endif + + int result; + +#ifdef KERNEL_TEST + SAHARA_INT_PTR = sah_Intr_Top_Half; +#endif + + /* Set queue used by the interrupt handler to match the driver interface */ + int_queue = wait_queue; + + /* Request use of the Interrupt line. */ + result = request_irq(SAHARA_IRQ, + sah_Intr_Top_Half, 0, SAHARA_NAME, NULL); + +#ifdef DIAG_DRV_INTERRUPT + if (result != 0) { + sprintf(err_string, "Cannot use SAHARA interrupt line %d. " + "request_irq() return code is %i.", SAHARA_IRQ, result); + LOG_KDIAG(err_string); + } else { + sprintf(err_string, + "SAHARA driver registered for interrupt %d. ", + SAHARA_IRQ); + LOG_KDIAG(err_string); + } +#endif + + return result; +} + +/*! +******************************************************************************* +* This function releases the Top Half of the interrupt handler. The driver will +* not receive any more interrupts after calling this functions. +* +* @brief SAHARA Interrupt Handler Release +* +* @return void +*/ +/****************************************************************************** +* +* CAUTION: NONE +* +* MODIFICATION HISTORY: +* +* Date Person Change +* 30/07/2003 MW Initial Creation +******************************************************************************/ +void sah_Intr_Release(void) +{ + /* Release the Interrupt. */ + free_irq(SAHARA_IRQ, NULL); +} + +/*! +******************************************************************************* +* This function is the Top Half of the interrupt handler. It updates the +* status of any finished descriptor chains and then tries to add any pending +* requests into the hardware. It then queues the bottom half to complete +* operations on the finished chains. +* +* @brief SAHARA Interrupt Handler Top Half +* +* @param irq Part of the kernel prototype. +* @param dev_id Part of the kernel prototype. +* +* @return An IRQ_RETVAL() -- non-zero to that function means 'handled' +*/ +static irqreturn_t sah_Intr_Top_Half(int irq, void *dev_id) +{ +#if defined(DIAG_DRV_INTERRUPT) && defined(DIAG_DURING_INTERRUPT) + LOG_KDIAG("Top half of Sahara's interrupt handler called."); +#endif + + interrupt_count++; + reset_flag = sah_Handle_Interrupt(sah_HW_Read_Status()); + + /* Schedule the Bottom Half of the Interrupt. */ + tasklet_schedule(&BH_task); + + /* To get rid of the unused parameter warnings. */ + irq = 0; + dev_id = NULL; + return IRQ_RETVAL(1); +} + +/*! +******************************************************************************* +* This function is the Bottom Half of the interrupt handler. It calls +* #sah_postprocess_queue() to complete the processing of the Descriptor Chains +* which were finished by the hardware. +* +* @brief SAHARA Interrupt Handler Bottom Half +* +* @param data Part of the kernel prototype. +* +* @return void +*/ +static void sah_Intr_Bottom_Half(unsigned long reset_flag) +{ +#if defined(DIAG_DRV_INTERRUPT) && defined(DIAG_DURING_INTERRUPT) + LOG_KDIAG("Bottom half of Sahara's interrupt handler called."); +#endif + sah_postprocess_queue(*(unsigned long *)reset_flag); + + return; +} + +/* end of sah_interrupt_handler.c */ +#endif /* ifndef SAHARA_POLL_MODE */ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/fsl_shw_sym.c +++ linux-2.6.28/drivers/mxc/security/sahara2/fsl_shw_sym.c @@ -0,0 +1,281 @@ +/* + * Copyright 2004-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 + */ + +/*! + * @file fsl_shw_sym.c + * + * This file implements Symmetric Cipher functions of the FSL SHW API for + * Sahara. This does not include CCM. + */ + +#include "sahara.h" +#include "fsl_platform.h" + +#include "sf_util.h" +#include "adaptor.h" + +#ifdef LINUX_KERNEL +EXPORT_SYMBOL(fsl_shw_symmetric_encrypt); +EXPORT_SYMBOL(fsl_shw_symmetric_decrypt); +#endif + +#if defined(NEED_CTR_WORKAROUND) +/* CTR mode needs block-multiple data in/out */ +#define LENGTH_PATCH (sym_ctx->block_size_bytes) +#define LENGTH_PATCH_MASK (sym_ctx->block_size_bytes-1) +#else +#define LENGTH_PATCH 0 +#define LENGTH_PATCH_MASK 0 /* du not use! */ +#endif + +/*! + * Block of zeroes which is maximum Symmetric block size, used for + * initializing context register, etc. + */ +static uint32_t block_zeros[4] = { + 0, 0, 0, 0 +}; + +typedef enum cipher_direction { + SYM_DECRYPT, + SYM_ENCRYPT +} cipher_direction_t; + +/*! + * Create and run the chain for a symmetric-key operation. + * + * @param user_ctx Who the user is + * @param key_info What key is to be used + * @param sym_ctx Info details about algorithm + * @param encrypt 0 = decrypt, non-zero = encrypt + * @param length Number of octets at @a in and @a out + * @param in Pointer to input data + * @param out Location to store output data + * + * @return The status of handing chain to driver, + * or an earlier argument/flag or allocation + * error. + */ +static fsl_shw_return_t do_symmetric(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info, + fsl_shw_scco_t * sym_ctx, + cipher_direction_t encrypt, + uint32_t length, + const uint8_t * in, uint8_t * out) +{ + SAH_SF_DCLS; + uint8_t *sink = NULL; + sah_Link *link1 = NULL; + sah_Link *link2 = NULL; + sah_Oct_Str ptr1; + uint32_t size1 = sym_ctx->block_size_bytes; + + SAH_SF_USER_CHECK(); + + /* Two different sets of chains, depending on algorithm */ + if (key_info->algorithm == FSL_KEY_ALG_ARC4) { + if (sym_ctx->flags & FSL_SYM_CTX_INIT) { + /* Desc. #35 w/ARC4 - start from key */ + header = SAH_HDR_ARC4_SET_MODE_KEY + ^ sah_insert_skha_algorithm_arc4; + + DESC_IN_KEY(header, 0, NULL, key_info); + } else { /* load SBox */ + /* Desc. #33 w/ARC4 and NO PERMUTE */ + header = SAH_HDR_ARC4_SET_MODE_SBOX + ^ sah_insert_skha_no_permute + ^ sah_insert_skha_algorithm_arc4; + DESC_IN_IN(header, 256, sym_ctx->context, + 3, sym_ctx->context + 256); + } /* load SBox */ + + /* Add in-out data descriptor to process the data */ + if (length != 0) { + DESC_IN_OUT(SAH_HDR_SKHA_ENC_DEC, length, in, length, + out); + } + + /* Operation is done ... save what came out? */ + if (sym_ctx->flags & FSL_SYM_CTX_SAVE) { + /* Desc. #34 - Read SBox, pointers */ + header = SAH_HDR_ARC4_READ_SBOX; + DESC_OUT_OUT(header, 256, sym_ctx->context, + 3, sym_ctx->context + 256); + } + } else { /* not ARC4 */ + /* Doing 1- or 2- descriptor chain. */ + /* Desc. #1 and algorithm and mode */ + header = SAH_HDR_SKHA_SET_MODE_IV_KEY + ^ sah_insert_skha_mode[sym_ctx->mode] + ^ sah_insert_skha_algorithm[key_info->algorithm]; + + /* Honor 'no key parity checking' for DES and TDES */ + if ((key_info->flags & FSL_SKO_KEY_IGNORE_PARITY) && + ((key_info->algorithm == FSL_KEY_ALG_DES) || + (key_info->algorithm == FSL_KEY_ALG_TDES))) { + header ^= sah_insert_skha_no_key_parity; + } + + /* Header by default is decrypting, so... */ + if (encrypt == SYM_ENCRYPT) { + header ^= sah_insert_skha_encrypt; + } + + if (sym_ctx->mode == FSL_SYM_MODE_CTR) { + header ^= sah_insert_skha_modulus[sym_ctx->modulus_exp]; + } + + if (sym_ctx->mode == FSL_SYM_MODE_ECB) { + ptr1 = NULL; + size1 = 0; + } else if (sym_ctx->flags & FSL_SYM_CTX_INIT) { + ptr1 = (uint8_t *) block_zeros; + } else { + ptr1 = sym_ctx->context; + } + + DESC_IN_KEY(header, sym_ctx->block_size_bytes, ptr1, key_info); + + /* Add in-out data descriptor */ + if (length != 0) { + header = SAH_HDR_SKHA_ENC_DEC; + if (LENGTH_PATCH && (sym_ctx->mode == FSL_SYM_MODE_CTR) + && ((length & LENGTH_PATCH_MASK) != 0)) { + sink = DESC_TEMP_ALLOC(LENGTH_PATCH); + ret = + sah_Create_Link(user_ctx->mem_util, &link1, + (uint8_t *) in, length, + SAH_USES_LINK_DATA); + ret = + sah_Append_Link(user_ctx->mem_util, link1, + (uint8_t *) sink, + LENGTH_PATCH - + (length & + LENGTH_PATCH_MASK), + SAH_USES_LINK_DATA); + if (ret != FSL_RETURN_OK_S) { + goto out; + } + ret = + sah_Create_Link(user_ctx->mem_util, &link2, + out, length, + SAH_USES_LINK_DATA | + SAH_OUTPUT_LINK); + if (ret != FSL_RETURN_OK_S) { + goto out; + } + ret = sah_Append_Link(user_ctx->mem_util, link2, + sink, + LENGTH_PATCH - + (length & + LENGTH_PATCH_MASK), + SAH_USES_LINK_DATA); + if (ret != FSL_RETURN_OK_S) { + goto out; + } + ret = + sah_Append_Desc(user_ctx->mem_util, + &desc_chain, header, link1, + link2); + if (ret != FSL_RETURN_OK_S) { + goto out; + } + link1 = link2 = NULL; + } else { + DESC_IN_OUT(header, length, in, length, out); + } + } + + /* Unload any desired context */ + if (sym_ctx->flags & FSL_SYM_CTX_SAVE) { + DESC_OUT_OUT(SAH_HDR_SKHA_READ_CONTEXT_IV, 0, NULL, + sym_ctx->block_size_bytes, + sym_ctx->context); + } + + } /* not ARC4 */ + + SAH_SF_EXECUTE(); + + out: + SAH_SF_DESC_CLEAN(); + DESC_TEMP_FREE(sink); + if (LENGTH_PATCH) { + sah_Destroy_Link(user_ctx->mem_util, link1); + sah_Destroy_Link(user_ctx->mem_util, link2); + } + + return ret; +} + +/* REQ-S2LRD-PINTFC-API-BASIC-SYM-002 */ +/* PINTFC-API-BASIC-SYM-ARC4-001 */ +/* PINTFC-API-BASIC-SYM-ARC4-002 */ + +/*! + * Compute symmetric encryption + * + * + * @param user_ctx + * @param key_info + * @param sym_ctx + * @param length + * @param pt + * @param ct + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t fsl_shw_symmetric_encrypt(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info, + fsl_shw_scco_t * sym_ctx, + uint32_t length, + const uint8_t * pt, uint8_t * ct) +{ + fsl_shw_return_t ret; + + ret = do_symmetric(user_ctx, key_info, sym_ctx, SYM_ENCRYPT, + length, pt, ct); + + return ret; +} + +/* PINTFC-API-BASIC-SYM-002 */ +/* PINTFC-API-BASIC-SYM-ARC4-001 */ +/* PINTFC-API-BASIC-SYM-ARC4-002 */ + +/*! + * Compute symmetric decryption + * + * + * @param user_ctx + * @param key_info + * @param sym_ctx + * @param length + * @param pt + * @param ct + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t fsl_shw_symmetric_decrypt(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info, + fsl_shw_scco_t * sym_ctx, + uint32_t length, + const uint8_t * ct, uint8_t * pt) +{ + fsl_shw_return_t ret; + + ret = do_symmetric(user_ctx, key_info, sym_ctx, SYM_DECRYPT, + length, ct, pt); + + return ret; +} --- linux-2.6.28.orig/drivers/mxc/security/sahara2/Kconfig +++ linux-2.6.28/drivers/mxc/security/sahara2/Kconfig @@ -0,0 +1,35 @@ +menu "SAHARA2 Security Hardware Support" + +config MXC_SAHARA + tristate "Security Hardware Support (FSL SHW)" + ---help--- + Provides driver and kernel mode API for using cryptographic + accelerators. + +config MXC_SAHARA_USER_MODE + tristate "User Mode API for FSL SHW" + depends on MXC_SAHARA + ---help--- + Provides kernel driver for User Mode API. + +config MXC_SAHARA_POLL_MODE + bool "Force driver to POLL for hardware completion." + depends on MXC_SAHARA + default n + ---help--- + When this flag is yes, the driver will not use interrupts to + determine when the hardware has completed a task, but instead + will hold onto the CPU and continually poll the hardware until + it completes. + +config MXC_SAHARA_POLL_MODE_TIMEOUT + hex "Poll loop timeout" + depends on MXC_SAHARA_POLL_MODE + default "0xFFFFFFFF" + help + To avoid infinite polling, a timeout is provided. Should the + timeout be reached, a fault is reported, indicating there must + be something wrong with SAHARA, and SAHARA is reset. The loop + will exit after the given number of iterations. + +endmenu --- linux-2.6.28.orig/drivers/mxc/security/sahara2/fsl_shw_rand.c +++ linux-2.6.28/drivers/mxc/security/sahara2/fsl_shw_rand.c @@ -0,0 +1,96 @@ +/* + * Copyright 2004-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 + */ + +/*! + * @file fsl_shw_rand.c + * + * This file implements Random Number Generation functions of the FSL SHW API + * for Sahara. + */ + +#include "sahara.h" +#include "sf_util.h" + +#ifdef __KERNEL__ +EXPORT_SYMBOL(fsl_shw_get_random); +#endif + +/* REQ-S2LRD-PINTFC-API-BASIC-RNG-002 */ +/*! + * Get a random number + * + * + * @param user_ctx + * @param length + * @param data + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t fsl_shw_get_random(fsl_shw_uco_t * user_ctx, + uint32_t length, uint8_t * data) +{ + SAH_SF_DCLS; + + /* perform a sanity check on the uco */ + ret = sah_validate_uco(user_ctx); + if (ret != FSL_RETURN_OK_S) { + goto out; + } + + header = SAH_HDR_RNG_GENERATE; /* Desc. #18 */ + DESC_OUT_OUT(header, length, data, 0, NULL); + + SAH_SF_EXECUTE(); + + out: + SAH_SF_DESC_CLEAN(); + + return ret; +} + +#ifdef __KERNEL__ +EXPORT_SYMBOL(fsl_shw_add_entropy); +#endif + +/*! + * Add entropy to a random number generator + + * @param user_ctx + * @param length + * @param data + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t fsl_shw_add_entropy(fsl_shw_uco_t * user_ctx, + uint32_t length, uint8_t * data) +{ + SAH_SF_DCLS; + + /* perform a sanity check on the uco */ + ret = sah_validate_uco(user_ctx); + if (ret != FSL_RETURN_OK_S) { + goto out; + } + + header = SAH_HDR_RNG_GENERATE; /* Desc. #18 */ + + /* create descriptor #18. Generate random data */ + DESC_IN_IN(header, 0, NULL, length, data) + + SAH_SF_EXECUTE(); + + out: + SAH_SF_DESC_CLEAN(); + + return ret; +} --- linux-2.6.28.orig/drivers/mxc/security/sahara2/sah_memory_mapper.c +++ linux-2.6.28/drivers/mxc/security/sahara2/sah_memory_mapper.c @@ -0,0 +1,2349 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! +* @file sah_memory_mapper.c +* +* @brief Re-creates SAHARA data structures in Kernel memory such that they are +* suitable for DMA. Provides support for kernel API. +* +* This file needs to be ported. +* +* The memory mapper gets a call at #sah_Init_Mem_Map() during driver +* initialization. +* +* The routine #sah_Copy_Descriptors() is used to bring descriptor chains from +* user memory down to kernel memory, relink using physical addresses, and make +* sure that all user data will be accessible by the Sahara DMA. +* #sah_Destroy_Descriptors() does the inverse. +* +* The #sah_Alloc_Block(), #sah_Free_Block(), and #sah_Block_Add_Page() routines +* implement a cache of free blocks used when allocating descriptors and links +* within the kernel. +* +* The memory mapper gets a call at #sah_Stop_Mem_Map() during driver shutdown. +* +*/ + +#include +#include +#include +#include +#ifdef FSL_HAVE_SCC2 +#include +#else +#include +#endif + +#if defined(DIAG_DRV_IF) || defined(DIAG_MEM) || defined(DO_DBG) +#include +#include +#endif + +#include /* get_user_pages() */ +#include +#include + +#include +#include + +#if defined(DIAG_MEM) || defined(DIAG_DRV_IF) +#define DIAG_MSG_SIZE 1024 +static char Diag_msg[DIAG_MSG_SIZE]; +#endif + +#ifdef LINUX_VERSION_CODE +#define FLUSH_SPECIFIC_DATA_ONLY +#else +#define SELF_MANAGED_POOL +#endif + +#if defined(LINUX_VERSION_CODE) +EXPORT_SYMBOL(sah_Alloc_Link); +EXPORT_SYMBOL(sah_Free_Link); +EXPORT_SYMBOL(sah_Alloc_Descriptor); +EXPORT_SYMBOL(sah_Free_Descriptor); +EXPORT_SYMBOL(sah_Alloc_Head_Descriptor); +EXPORT_SYMBOL(sah_Free_Head_Descriptor); +EXPORT_SYMBOL(sah_Physicalise_Descriptors); +EXPORT_SYMBOL(sah_DePhysicalise_Descriptors); +#endif + +/* Determine if L2 cache support should be built in. */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) +#ifdef CONFIG_OUTER_CACHE +#define HAS_L2_CACHE +#endif +#else +#ifdef CONFIG_CPU_CACHE_L210 +#define HAS_L2_CACHE +#endif +#endif + +/* Number of bytes the hardware uses out of sah_Link and sah_*Desc structs */ +#define SAH_HW_LINK_LEN 1 +#define SAH_HW_DESC_LEN 24 + +/* Macros for Descriptors */ +#define SAH_LLO_BIT 0x01000000 +#define sah_Desc_Get_LLO(desc) (desc->header & SAH_LLO_BIT) +#define sah_Desc_Set_Header(desc, h) (desc->header = (h)) + +#define sah_Desc_Get_Next(desc) (desc->next) +#define sah_Desc_Set_Next(desc, n) (desc->next = (n)) + +#define sah_Desc_Get_Ptr1(desc) (desc->ptr1) +#define sah_Desc_Get_Ptr2(desc) (desc->ptr2) +#define sah_Desc_Set_Ptr1(desc,p1) (desc->ptr1 = (p1)) +#define sah_Desc_Set_Ptr2(desc,p2) (desc->ptr2 = (p2)) + +#define sah_Desc_Get_Len1(desc) (desc->len1) +#define sah_Desc_Get_Len2(desc) (desc->len2) +#define sah_Desc_Set_Len1(desc,l1) (desc->len1 = (l1)) +#define sah_Desc_Set_Len2(desc,l2) (desc->len2 = (l2)) + +/* Macros for Links */ +#define sah_Link_Get_Next(link) (link->next) +#define sah_Link_Set_Next(link, n) (link->next = (n)) + +#define sah_Link_Get_Data(link) (link->data) +#define sah_Link_Set_Data(link,d) (link->data = (d)) + +#define sah_Link_Get_Len(link) (link->len) +#define sah_Link_Set_Len(link, l) (link->len = (l)) + +#define sah_Link_Get_Flags(link) (link->flags) + +/* Memory block defines */ +/* Warning! This assumes that kernel version of sah_Link + * is larger than kernel version of sah_Desc. + */ +#define MEM_BLOCK_SIZE sizeof(sah_Link) + +/*! Structure for link/descriptor memory blocks in internal pool */ +typedef struct mem_block { + uint8_t data[MEM_BLOCK_SIZE]; /*!< the actual buffer area */ + struct mem_block *next; /*!< next block when in free chain */ + dma_addr_t dma_addr; /*!< physical address of @a data */ +} Mem_Block; + +#define MEM_BLOCK_ENTRIES (PAGE_SIZE / sizeof(Mem_Block)) + +#define MEM_BIG_BLOCK_SIZE sizeof(sah_Head_Desc) + +/*! Structure for head descriptor memory blocks in internal pool */ +typedef struct mem_big_block { + uint8_t data[MEM_BIG_BLOCK_SIZE]; /*!< the actual buffer area */ + struct mem_big_block *next; /*!< next block when in free chain */ + uint32_t dma_addr; /*!< physical address of @a data */ +} Mem_Big_Block; + +#define MEM_BIG_BLOCK_ENTRIES (PAGE_SIZE / sizeof(Mem_Big_Block)) + +/* Shared variables */ + +/*! + * Lock to protect the memory chain composed of #block_free_head and + * #block_free_tail. + */ +static os_lock_t mem_lock; + +#ifndef SELF_MANAGED_POOL +static struct dma_pool *big_dma_pool = NULL; +static struct dma_pool *small_dma_pool = NULL; +#endif + +#ifdef SELF_MANAGED_POOL +/*! + * Memory block free pool - pointer to first block. Chain is protected by + * #mem_lock. + */ +static Mem_Block *block_free_head = NULL; +/*! + * Memory block free pool - pointer to last block. Chain is protected by + * #mem_lock. + */ +static Mem_Block *block_free_tail = NULL; +/*! + * Memory block free pool - pointer to first block. Chain is protected by + * #mem_lock. + */ +static Mem_Big_Block *big_block_free_head = NULL; +/*! + * Memory block free pool - pointer to last block. Chain is protected by + * #mem_lock. +a */ +static Mem_Big_Block *big_block_free_tail = NULL; +#endif /* SELF_MANAGED_POOL */ + +static Mem_Block *sah_Alloc_Block(void); +static void sah_Free_Block(Mem_Block * block); +static Mem_Big_Block *sah_Alloc_Big_Block(void); +static void sah_Free_Big_Block(Mem_Big_Block * block); +#ifdef SELF_MANAGED_POOL +static void sah_Append_Block(Mem_Block * block); +static void sah_Append_Big_Block(Mem_Big_Block * block); +#endif /* SELF_MANAGED_POOL */ + +/* Page context structure. Used by wire_user_memory and unwire_user_memory */ +typedef struct page_ctx_t { + uint32_t count; + struct page **local_pages; +} page_ctx_t; + +/*! +******************************************************************************* +* Map and wire down a region of user memory. +* +* +* @param address Userspace address of the memory to wire +* @param length Length of the memory region to wire +* @param page_ctx Page context, to be passed to unwire_user_memory +* +* @return (if successful) Kernel virtual address of the wired pages +*/ +void *wire_user_memory(void *address, uint32_t length, void **page_ctx) +{ + void *kernel_black_addr = NULL; + int result = -1; + int page_index = 0; + page_ctx_t *page_context; + int nr_pages = 0; + unsigned long start_page; + fsl_shw_return_t status; + + /* Determine the number of pages being used for this link */ + nr_pages = (((unsigned long)(address) & ~PAGE_MASK) + + length + ~PAGE_MASK) >> PAGE_SHIFT; + + start_page = (unsigned long)(address) & PAGE_MASK; + + /* Allocate some memory to keep track of the wired user pages, so that + * they can be deallocated later. The block of memory will contain both + * the structure and the array of pages. + */ + page_context = kmalloc(sizeof(page_ctx_t) + + nr_pages * sizeof(struct page *), GFP_KERNEL); + + if (page_context == NULL) { + status = FSL_RETURN_NO_RESOURCE_S; /* no memory! */ +#ifdef DIAG_DRV_IF + LOG_KDIAG("kmalloc() failed."); +#endif + return NULL; + } + + /* Set the page pointer to point to the allocated region of memory */ + page_context->local_pages = (void *)page_context + sizeof(page_ctx_t); + +#ifdef DIAG_DRV_IF + LOG_KDIAG_ARGS("page_context at: %p, local_pages at: %p", + (void *)page_context, + (void *)(page_context->local_pages)); +#endif + + /* Wire down the pages from user space */ + down_read(¤t->mm->mmap_sem); + result = get_user_pages(current, current->mm, + start_page, nr_pages, WRITE, 0 /* noforce */ , + (page_context->local_pages), NULL); + up_read(¤t->mm->mmap_sem); + + if (result < nr_pages) { +#ifdef DIAG_DRV_IF + LOG_KDIAG("get_user_pages() failed."); +#endif + if (result > 0) { + for (page_index = 0; page_index < result; page_index++) { + page_cache_release((page_context-> + local_pages[page_index])); + } + + kfree(page_context); + } + return NULL; + } + + kernel_black_addr = page_address(page_context->local_pages[0]) + + ((unsigned long)address & ~PAGE_MASK); + + page_context->count = nr_pages; + *page_ctx = page_context; + + return kernel_black_addr; +} + +/*! +******************************************************************************* +* Release and unmap a region of user memory. +* +* @param page_ctx Page context from wire_user_memory +*/ +void unwire_user_memory(void **page_ctx) +{ + int page_index = 0; + struct page_ctx_t *page_context = *page_ctx; + +#ifdef DIAG_DRV_IF + LOG_KDIAG_ARGS("page_context at: %p, first page at:%p, count: %i", + (void *)page_context, + (void *)(page_context->local_pages), + page_context->count); +#endif + + if ((page_context != NULL) && (page_context->local_pages != NULL)) { + for (page_index = 0; page_index < page_context->count; + page_index++) { + page_cache_release(page_context-> + local_pages[page_index]); + } + + kfree(page_context); + *page_ctx = NULL; + } +} + +/*! +******************************************************************************* +* Map some physical memory into a users memory space +* +* @param vma Memory structure to map to +* @param physical_addr Physical address of the memory to be mapped in +* @param size Size of the memory to map (bytes) +* +* @return +*/ +os_error_code +map_user_memory(struct vm_area_struct *vma, uint32_t physical_addr, + uint32_t size) +{ + os_error_code retval; + + /* Map the acquired partition into the user's memory space */ + vma->vm_end = vma->vm_start + size; + + /* set cache policy to uncached so that each write of the UMID and + * permissions get directly to the SCC2 in order to engage it + * properly. Once the permissions have been written, it may be + * useful to provide a service for the user to request a different + * cache policy + */ + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + /* Make sure that the user cannot fork() a child which will inherit + * this mapping, as it creates a security hole. Likewise, do not + * allow the user to 'expand' his mapping beyond this partition. + */ + vma->vm_flags |= VM_IO | VM_RESERVED | VM_DONTCOPY | VM_DONTEXPAND; + + retval = remap_pfn_range(vma, + vma->vm_start, + __phys_to_pfn(physical_addr), + size, vma->vm_page_prot); + + return retval; +} + +/*! +******************************************************************************* +* Remove some memory from a user's memory space +* +* @param user_addr Userspace address of the memory to be unmapped +* @param size Size of the memory to map (bytes) +* +* @return +*/ +os_error_code unmap_user_memory(uint32_t user_addr, uint32_t size) +{ + os_error_code retval; + struct mm_struct *mm = current->mm; + + /* Unmap the memory region (see sys_munmap in mmap.c) */ + down_write(&mm->mmap_sem); + retval = do_munmap(mm, (unsigned long)user_addr, size); + up_write(&mm->mmap_sem); + + return retval; +} + +/*! +******************************************************************************* +* Free descriptor back to free pool +* +* @brief Free descriptor +* +* @param desc A descriptor allocated with sah_Alloc_Descriptor(). +* +* @return none +* +*/ +void sah_Free_Descriptor(sah_Desc * desc) +{ + memset(desc, 0x45, sizeof(*desc)); + sah_Free_Block((Mem_Block *) desc); +} + +/*! +******************************************************************************* +* Free Head descriptor back to free pool +* +* @brief Free Head descriptor +* +* @param desc A Head descriptor allocated with sah_Alloc_Head_Descriptor(). +* +* @return none +* +*/ +void sah_Free_Head_Descriptor(sah_Head_Desc * desc) +{ + memset(desc, 0x43, sizeof(*desc)); + sah_Free_Big_Block((Mem_Big_Block *) desc); +} + +/*! +******************************************************************************* +* Free link back to free pool +* +* @brief Free link +* +* @param link A link allocated with sah_Alloc_Link(). +* +* @return none +* +*/ +void sah_Free_Link(sah_Link * link) +{ + memset(link, 0x41, sizeof(*link)); + sah_Free_Block((Mem_Block *) link); +} + +/*! +******************************************************************************* +* This function runs through a descriptor chain pointed to by a user-space +* address. It duplicates each descriptor in Kernel space memory and calls +* sah_Copy_Links() to handle any links attached to the descriptors. This +* function cleans-up everything that it created in the case of a failure. +* +* @brief Kernel Descriptor Chain Copier +* +* @param fsl_shw_uco_t The user context to act under +* @param user_head_desc A Head Descriptor pointer from user-space. +* +* @return sah_Head_Desc * - A virtual address of the first descriptor in the +* chain. +* @return NULL - If there was some error. +* +*/ +sah_Head_Desc *sah_Copy_Descriptors(fsl_shw_uco_t * user_ctx, + sah_Head_Desc * user_head_desc) +{ + sah_Desc *curr_desc = NULL; + sah_Desc *prev_desc = NULL; + sah_Desc *next_desc = NULL; + sah_Head_Desc *head_desc = NULL; + sah_Desc *user_desc = NULL; + unsigned long result; + + /* Internal status variable to be used in this function */ + fsl_shw_return_t status = FSL_RETURN_OK_S; + sah_Head_Desc *ret_val = NULL; + + /* This will be set to True when we have finished processing our + * descriptor chain. + */ + int drv_if_done = FALSE; + int is_this_the_head = TRUE; + + do { + /* Allocate memory for this descriptor */ + if (is_this_the_head) { + head_desc = + (sah_Head_Desc *) sah_Alloc_Head_Descriptor(); + +#ifdef DIAG_MEM + sprintf(Diag_msg, + "Alloc_Head_Descriptor returned %p\n", + head_desc); + LOG_KDIAG(Diag_msg); +#endif + if (head_desc == NULL) { +#ifdef DIAG_DRV_IF + LOG_KDIAG + ("sah_Alloc_Head_Descriptor() failed."); +#endif + drv_if_done = TRUE; + status = FSL_RETURN_NO_RESOURCE_S; + } else { + void *virt_addr = head_desc->desc.virt_addr; + dma_addr_t dma_addr = head_desc->desc.dma_addr; + + /* Copy the head descriptor from user-space */ + /* Instead of copying the whole structure, + * unneeded bits at the end are left off. + * The user space version is missing virt/dma addrs, which + * means that the copy will be off for flags... */ + result = copy_from_user(head_desc, + user_head_desc, + (sizeof(*head_desc) - + sizeof(head_desc->desc. + dma_addr) - + sizeof(head_desc->desc. + virt_addr) - + sizeof(head_desc->desc. + original_ptr1) - +/* sizeof(head_desc->desc.original_ptr2) - + sizeof(head_desc->status) - + sizeof(head_desc->error_status) - + sizeof(head_desc->fault_address) - + sizeof(head_desc->current_dar) - + sizeof(head_desc->result) - + sizeof(head_desc->next) - + sizeof(head_desc->prev) - + sizeof(head_desc->user_desc) - +*/ sizeof(head_desc->out1_ptr) - + sizeof(head_desc-> + out2_ptr) - + sizeof(head_desc-> + out_len))); + /* there really isn't a 'next' descriptor at this point, so + * set that pointer to NULL, but remember it for if/when there + * is a next */ + next_desc = head_desc->desc.next; + head_desc->desc.next = NULL; + + if (result != 0) { +#ifdef DIAG_DRV_IF + LOG_KDIAG("copy_from_user() failed."); +#endif + drv_if_done = TRUE; + status = FSL_RETURN_INTERNAL_ERROR_S; + /* when destroying the descriptor, skip these links. + * They've not been copied down, so don't exist */ + head_desc->desc.ptr1 = NULL; + head_desc->desc.ptr2 = NULL; + + } else { + /* The kernel DESC has five more words than user DESC, so + * the missing values are in the middle of the HEAD DESC, + * causing values after the missing ones to be at different + * offsets in kernel and user space. + * + * Patch up the problem by moving field two spots. + * This assumes sizeof(pointer) == sizeof(uint32_t). + * Note that 'user_info' is not needed, so not copied. + */ + head_desc->user_ref = + (uint32_t) head_desc->desc.dma_addr; + head_desc->uco_flags = + (uint32_t) head_desc->desc. + original_ptr1; +#ifdef DIAG_DRV_IF + LOG_KDIAG_ARGS( + "User flags: %x; User Reference: %x", + head_desc->uco_flags, + head_desc->user_ref); +#endif + /* These values were destroyed by the copy. */ + head_desc->desc.virt_addr = virt_addr; + head_desc->desc.dma_addr = dma_addr; + + /* ensure that the save descriptor chain bit is not set. + * the copy of the user space descriptor chain should + * always be deleted */ + head_desc->uco_flags &= + ~FSL_UCO_SAVE_DESC_CHAIN; + + curr_desc = (sah_Desc *) head_desc; + is_this_the_head = FALSE; + } + } + } else { /* not head */ + curr_desc = sah_Alloc_Descriptor(); +#ifdef DIAG_MEM + LOG_KDIAG_ARGS("Alloc_Descriptor returned %p\n", + curr_desc); +#endif + if (curr_desc == NULL) { +#ifdef DIAG_DRV_IF + LOG_KDIAG("sah_Alloc_Descriptor() failed."); +#endif + drv_if_done = TRUE; + status = FSL_RETURN_NO_RESOURCE_S; + } else { + /* need to update the previous descriptors' next field to + * pointer to the current descriptor. */ + prev_desc->original_next = curr_desc; + prev_desc->next = + (sah_Desc *) curr_desc->dma_addr; + + /* Copy the current descriptor from user-space */ + /* The virtual address and DMA address part of the sah_Desc + * struct are not copied to user space */ + result = copy_from_user(curr_desc, user_desc, (sizeof(sah_Desc) - sizeof(dma_addr_t) - /* dma_addr */ + sizeof(uint32_t) - /* virt_addr */ + sizeof(void *) - /* original_ptr1 */ + sizeof(void *) - /* original_ptr2 */ + sizeof(sah_Desc **))); /* original_next */ + /* there really isn't a 'next' descriptor at this point, so + * set that pointer to NULL, but remember it for if/when there + * is a next */ + next_desc = curr_desc->next; + curr_desc->next = NULL; + curr_desc->original_next = NULL; + + if (result != 0) { +#ifdef DIAG_DRV_IF + LOG_KDIAG("copy_from_user() failed."); +#endif + drv_if_done = TRUE; + status = FSL_RETURN_INTERNAL_ERROR_S; + /* when destroying the descriptor chain, skip these links. + * They've not been copied down, so don't exist */ + curr_desc->ptr1 = NULL; + curr_desc->ptr2 = NULL; + } + } + } /* end if (is_this_the_head) */ + + if (status == FSL_RETURN_OK_S) { + if (!(curr_desc->header & SAH_LLO_BIT)) { + /* One or both pointer fields being NULL is a valid + * configuration. */ + if (curr_desc->ptr1 == NULL) { + curr_desc->original_ptr1 = NULL; + } else { + /* pointer fields point to sah_Link structures */ + curr_desc->original_ptr1 = + sah_Copy_Links(user_ctx, curr_desc->ptr1); + if (curr_desc->original_ptr1 == NULL) { + /* This descriptor and any links created successfully + * are cleaned-up at the bottom of this function. */ + drv_if_done = TRUE; + status = + FSL_RETURN_INTERNAL_ERROR_S; + /* mark that link 2 doesn't exist */ + curr_desc->ptr2 = NULL; +#ifdef DIAG_DRV_IF + LOG_KDIAG + ("sah_Copy_Links() failed."); +#endif + } else { + curr_desc->ptr1 = (void *) + ((sah_Link *) curr_desc-> + original_ptr1)->dma_addr; + } + } + + if (status == FSL_RETURN_OK_S) { + if (curr_desc->ptr2 == NULL) { + curr_desc->original_ptr2 = NULL; + } else { + /* pointer fields point to sah_Link structures */ + curr_desc->original_ptr2 = + sah_Copy_Links(user_ctx, curr_desc->ptr2); + if (curr_desc->original_ptr2 == + NULL) { + /* This descriptor and any links created + * successfully are cleaned-up at the bottom of + * this function. */ + drv_if_done = TRUE; + status = + FSL_RETURN_INTERNAL_ERROR_S; +#ifdef DIAG_DRV_IF + LOG_KDIAG + ("sah_Copy_Links() failed."); +#endif + } else { + curr_desc->ptr2 = + (void + *)(((sah_Link *) + curr_desc-> + original_ptr2) + ->dma_addr); + } + } + } + } else { + /* Pointer fields point directly to user buffers. We don't + * support this mode. + */ +#ifdef DIAG_DRV_IF + LOG_KDIAG + ("The LLO bit in the Descriptor Header field was " + "set. This an invalid configuration."); +#endif + drv_if_done = TRUE; + status = FSL_RETURN_INTERNAL_ERROR_S; + } + } + + if (status == FSL_RETURN_OK_S) { + user_desc = next_desc; + prev_desc = curr_desc; + if (user_desc == NULL) { + /* We have reached the end our our descriptor chain */ + drv_if_done = TRUE; + } + } + + } while (drv_if_done == FALSE); + + if (status != FSL_RETURN_OK_S) { + /* Clean-up if failed */ + if (head_desc != NULL) { +#ifdef DIAG_DRV_IF + LOG_KDIAG("Error! Calling destroy descriptors!\n"); +#endif + sah_Destroy_Descriptors(head_desc); + } + ret_val = NULL; + } else { + /* Flush the caches */ +#ifndef FLUSH_SPECIFIC_DATA_ONLY + os_flush_cache_all(); +#endif + + /* Success. Return the DMA'able head descriptor. */ + ret_val = head_desc; + + } + + return ret_val; +} /* sah_Copy_Descriptors() */ + +/*! +******************************************************************************* +* This function runs through a sah_Link chain pointed to by a kernel-space +* address. It computes the physical address for each pointer, and converts +* the chain to use these physical addresses. +* +****** +* This function needs to return some indication that the chain could not be +* converted. It also needs to back out any conversion already taken place on +* this chain of links. +* +* Then, of course, sah_Physicalise_Descriptors() will need to recognize that +* an error occured, and then be able to back out any physicalization of the +* chain which had taken place up to that point! +****** +* +* @brief Convert kernel Link chain +* +* @param first_link A sah_Link pointer from kernel space; must not be +* NULL, so error case can be distinguished. +* +* @return sah_Link * A dma'able address of the first descriptor in the +* chain. +* @return NULL If Link chain could not be physicalised, i.e. ERROR +* +*/ +sah_Link *sah_Physicalise_Links(sah_Link * first_link) +{ + sah_Link *link = first_link; + + while (link != NULL) { +#ifdef DO_DBG + sah_Dump_Words("Link", (unsigned *)link, link->dma_addr, 3); +#endif + link->vm_info = NULL; + + /* need to retrieve stored key? */ + if (link->flags & SAH_STORED_KEY_INFO) { + uint32_t max_len = 0; /* max slot length */ + fsl_shw_return_t ret_status; + + /* get length and physical address of stored key */ + ret_status = system_keystore_get_slot_info(link->ownerid, link->slot, (uint32_t *) & link->data, /* RED key address */ + &max_len); + if ((ret_status != FSL_RETURN_OK_S) || (link->len > max_len)) { + /* trying to illegally/incorrectly access a key. Cause the + * error status register to show a Link Length Error by + * putting a zero in the links length. */ + link->len = 0; /* Cause error. Somebody is up to no good. */ + } + } else if (link->flags & SAH_IN_USER_KEYSTORE) { + +#ifdef FSL_HAVE_SCC2 + /* The data field points to the virtual address of the key. Convert + * this to a physical address by modifying the address based + * on where the secure memory was mapped to the kernel. Note: In + * kernel mode, no attempt is made to track or control who owns what + * memory partition. + */ + link->data = (uint8_t *) scc_virt_to_phys(link->data); + + /* Do bounds checking to ensure that the user is not overstepping + * the bounds of their partition. This is a simple implementation + * that assumes the user only owns one partition. It only checks + * to see if the address of the last byte of data steps over a + * page boundary. + */ + +#ifdef DO_DBG + LOG_KDIAG_ARGS("start page: %08x, end page: %08x" + "first addr: %p, last addr: %p, len; %i", + ((uint32_t) (link->data) >> PAGE_SHIFT), + (((uint32_t) link->data + + link->len) >> PAGE_SHIFT), link->data, + link->data + link->len, link->len); +#endif + + if ((((uint32_t) link->data + + link->len) >> PAGE_SHIFT) != + ((uint32_t) link->data >> PAGE_SHIFT)) { + link->len = 0; /* Cause error. Somebody is up to no good. */ + } +#else /* FSL_HAVE_SCC2 */ + + /* User keystores are not valid on non-SCC2 platforms */ + link->len = 0; /* Cause error. Somebody is up to no good. */ + +#endif /* FSL_HAVE_SCC2 */ + + } else { + if (!(link->flags & SAH_PREPHYS_DATA)) { + link->original_data = link->data; + + /* All pointers are virtual right now */ + link->data = (void *)os_pa(link->data); +#ifdef DO_DBG + os_printk("%sput: %p (%d)\n", + (link-> + flags & SAH_OUTPUT_LINK) ? "out" : + "in", link->data, link->len); +#endif + + if (link->flags & SAH_OUTPUT_LINK) { + /* clean and invalidate */ + os_cache_flush_range(link-> + original_data, + link->len); + } else { + os_cache_clean_range(link->original_data, + link->len); + } + } /* not prephys */ + } /* else not key reference */ + +#if defined(NO_OUTPUT_1K_CROSSING) || defined(NO_1K_CROSSING) + if ( +#ifdef NO_OUTPUT_1K_CROSSING + /* Insert extra link if 1k boundary on output pointer + * crossed not at an 8-word boundary */ + (link->flags & SAH_OUTPUT_LINK) && + (((uint32_t) link->data % 32) != 0) && +#endif + ((((uint32_t) link->data & 1023) + link->len) > + 1024)) { + uint32_t full_length = link->len; + sah_Link *new_link = sah_Alloc_Link(); + link->len = 1024 - ((uint32_t) link->data % 1024); + new_link->len = full_length - link->len; + new_link->data = link->data + link->len; + new_link->original_data = + link->original_data + link->len; + new_link->flags = link->flags & ~(SAH_OWNS_LINK_DATA); + new_link->flags |= SAH_LINK_INSERTED_LINK; + new_link->next = link->next; + + link->next = (sah_Link *) new_link->dma_addr; + link->original_next = new_link; + link = new_link; + } +#endif /* ALLOW_OUTPUT_1K_CROSSING */ + + link->original_next = link->next; + if (link->next != NULL) { + link->next = (sah_Link *) link->next->dma_addr; + } +#ifdef DO_DBG + sah_Dump_Words("Link", link, link->dma_addr, 3); +#endif + + link = link->original_next; + } + + return (sah_Link *) first_link->dma_addr; +} /* sah_Physicalise_Links */ + +/*! + * Run through descriptors and links created by KM-API and set the + * dma addresses and 'do not free' flags. + * + * @param first_desc KERNEL VIRTUAL address of first descriptor in chain. + * + * Warning! This ONLY works without LLO flags in headers!!! + * + * @return Virtual address of @a first_desc. + * @return NULL if Descriptor Chain could not be physicalised + */ +sah_Head_Desc *sah_Physicalise_Descriptors(sah_Head_Desc * first_desc) +{ + sah_Desc *desc = &first_desc->desc; + + if (!(first_desc->uco_flags & FSL_UCO_CHAIN_PREPHYSICALIZED)) { + while (desc != NULL) { + sah_Desc *next_desc; + +#ifdef DO_DBG + + sah_Dump_Words("Desc", (unsigned *)desc, desc->dma_addr, 6); +#endif + + desc->original_ptr1 = desc->ptr1; + if (desc->ptr1 != NULL) { + if ((desc->ptr1 = + sah_Physicalise_Links(desc->ptr1)) == + NULL) { + /* Clean up ... */ + sah_DePhysicalise_Descriptors + (first_desc); + first_desc = NULL; + break; + } + } + desc->original_ptr2 = desc->ptr2; + if (desc->ptr2 != NULL) { + if ((desc->ptr2 = + sah_Physicalise_Links(desc->ptr2)) == + NULL) { + /* Clean up ... */ + sah_DePhysicalise_Descriptors + (first_desc); + first_desc = NULL; + break; + } + } + + desc->original_next = desc->next; + next_desc = desc->next; /* save for bottom of while loop */ + if (desc->next != NULL) { + desc->next = (sah_Desc *) desc->next->dma_addr; + } + + desc = next_desc; + } + } + /* not prephysicalized */ +#ifdef DO_DBG + os_printk("Physicalise finished\n"); +#endif + + return first_desc; +} /* sah_Physicalise_Descriptors() */ + +/*! +******************************************************************************* +* This function runs through a sah_Link chain pointed to by a physical address. +* It computes the virtual address for each pointer +* +* @brief Convert physical Link chain +* +* @param first_link A kernel address of a sah_Link +* +* @return sah_Link * A kernal address for the link chain of @c first_link +* @return NULL If there was some error. +* +* @post All links will be chained together by original virtual addresses, +* data pointers will point to virtual addresses. Appropriate cache +* lines will be flushed, memory unwired, etc. +*/ +sah_Link *sah_DePhysicalise_Links(sah_Link * first_link) +{ + sah_Link *link = first_link; + sah_Link *prev_link = NULL; + + /* Loop on virtual link pointer */ + while (link != NULL) { + +#ifdef DO_DBG + sah_Dump_Words("Link", (unsigned *)link, link->dma_addr, 3); +#endif + + /* if this references stored keys, don't want to dephysicalize them */ + if (!(link->flags & SAH_STORED_KEY_INFO) + && !(link->flags & SAH_PREPHYS_DATA) + && !(link->flags & SAH_IN_USER_KEYSTORE)) { + + /* */ + if (link->flags & SAH_OUTPUT_LINK) { + os_cache_inv_range(link->original_data, + link->len); + } + + /* determine if there is a page in user space associated with this + * link */ + if (link->vm_info != NULL) { + /* check that this isn't reserved and contains output */ + if (!PageReserved(link->vm_info) && + (link->flags & SAH_OUTPUT_LINK)) { + + /* Mark to force page eventually to backing store */ + SetPageDirty(link->vm_info); + } + + /* Untie this page from physical memory */ + page_cache_release(link->vm_info); + } else { + /* kernel-mode data */ +#ifdef DO_DBG + os_printk("%sput: %p (%d)\n", + (link-> + flags & SAH_OUTPUT_LINK) ? "out" : + "in", link->original_data, link->len); +#endif + } + link->data = link->original_data; + } +#ifndef ALLOW_OUTPUT_1K_CROSSING + if (link->flags & SAH_LINK_INSERTED_LINK) { + /* Reconsolidate data by merging this link with previous */ + prev_link->len += link->len; + prev_link->next = link->next; + prev_link->original_next = link->original_next; + sah_Free_Link(link); + link = prev_link; + + } +#endif + + if (link->next != NULL) { + link->next = link->original_next; + } + prev_link = link; + link = link->next; + } + + return first_link; +} /* sah_DePhysicalise_Links() */ + +/*! + * Run through descriptors and links that have been Physicalised + * (sah_Physicalise_Descriptors function) and set the dma addresses back + * to KM virtual addresses + * + * @param first_desc Kernel virtual address of first descriptor in chain. + * + * Warning! This ONLY works without LLO flags in headers!!! + */ +sah_Head_Desc *sah_DePhysicalise_Descriptors(sah_Head_Desc * first_desc) +{ + sah_Desc *desc = &first_desc->desc; + + if (!(first_desc->uco_flags & FSL_UCO_CHAIN_PREPHYSICALIZED)) { + while (desc != NULL) { +#ifdef DO_DBG + sah_Dump_Words("Desc", (unsigned *)desc, desc->dma_addr, 6); +#endif + + if (desc->ptr1 != NULL) { + desc->ptr1 = + sah_DePhysicalise_Links(desc-> + original_ptr1); + } + if (desc->ptr2 != NULL) { + desc->ptr2 = + sah_DePhysicalise_Links(desc-> + original_ptr2); + } + if (desc->next != NULL) { + desc->next = desc->original_next; + } + desc = desc->next; + } + } + /* not prephysicalized */ + return first_desc; +} /* sah_DePhysicalise_Descriptors() */ + +/*! +******************************************************************************* +* This walks through a SAHARA descriptor chain and free()'s everything +* that is not NULL. Finally it also unmaps all of the physical memory and +* frees the kiobuf_list Queue. +* +* @brief Kernel Descriptor Chain Destructor +* +* @param head_desc A Descriptor pointer from kernel-space. +* +* @return void +* +*/ +void sah_Free_Chained_Descriptors(sah_Head_Desc * head_desc) +{ + sah_Desc *desc = NULL; + sah_Desc *next_desc = NULL; + int this_is_head = 1; + + desc = &head_desc->desc; + + while (desc != NULL) { + + sah_Free_Chained_Links(desc->ptr1); + sah_Free_Chained_Links(desc->ptr2); + + /* Get a bus pointer to the next Descriptor */ + next_desc = desc->next; + + /* Zero the header and Length fields for security reasons. */ + desc->header = 0; + desc->len1 = 0; + desc->len2 = 0; + + if (this_is_head) { + sah_Free_Head_Descriptor(head_desc); + this_is_head = 0; +#ifdef DIAG_MEM + sprintf(Diag_msg, "Free_Head_Descriptor: %p\n", + head_desc); + LOG_KDIAG(Diag_msg); +#endif + } else { + /* free this descriptor */ + sah_Free_Descriptor(desc); +#ifdef DIAG_MEM + sprintf(Diag_msg, "Free_Descriptor: %p\n", desc); + LOG_KDIAG(Diag_msg); +#endif + } + + /* Look at the next Descriptor */ + desc = next_desc; + } +} /* sah_Free_Chained_Descriptors() */ + +/*! +******************************************************************************* +* This walks through a SAHARA link chain and frees everything that is +* not NULL, excluding user-space buffers. +* +* @brief Kernel Link Chain Destructor +* +* @param link A Link pointer from kernel-space. This is in bus address +* space. +* +* @return void +* +*/ +void sah_Free_Chained_Links(sah_Link * link) +{ + sah_Link *next_link = NULL; + + while (link != NULL) { + /* Get a bus pointer to the next Link */ + next_link = link->next; + + /* Zero some fields for security reasons. */ + link->data = NULL; + link->len = 0; + link->ownerid = 0; + + /* Free this Link */ +#ifdef DIAG_MEM + sprintf(Diag_msg, "Free_Link: %p(->%p)\n", link, link->next); + LOG_KDIAG(Diag_msg); +#endif + sah_Free_Link(link); + + /* Move on to the next Link */ + link = next_link; + } +} + +/*! +******************************************************************************* +* This function runs through a link chain pointed to by a user-space +* address. It makes a temporary kernel-space copy of each link in the +* chain and calls sah_Make_Links() to create a set of kernel-side links +* to replace it. +* +* @brief Kernel Link Chain Copier +* +* @param ptr A link pointer from user-space. +* +* @return sah_Link * - The virtual address of the first link in the +* chain. +* @return NULL - If there was some error. +*/ +sah_Link *sah_Copy_Links(fsl_shw_uco_t * user_ctx, sah_Link * ptr) +{ + sah_Link *head_link = NULL; + sah_Link *new_head_link = NULL; + sah_Link *new_tail_link = NULL; + sah_Link *prev_tail_link = NULL; + sah_Link *user_link = ptr; + sah_Link link_copy; + int link_data_length = 0; + + /* Internal status variable to be used in this function */ + fsl_shw_return_t status = FSL_RETURN_OK_S; + sah_Link *ret_val = NULL; + + /* This will be set to True when we have finished processing our + * link chain. */ + int drv_if_done = FALSE; + int is_this_the_head = TRUE; + int result; + + /* transfer all links, on this link chain, from user space */ + while (drv_if_done == FALSE) { + /* Copy the current link from user-space. The virtual address, DMA + * address, and vm_info fields of the sah_Link struct are not part + * of the user-space structure. They must be the last elements and + * should not be copied. */ + result = copy_from_user(&link_copy, + user_link, (sizeof(sah_Link) - +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) + sizeof(struct page *) - /* vm_info */ +#endif + sizeof(dma_addr_t) - /* dma_addr */ + sizeof(uint32_t) - /* virt_addr */ + sizeof(uint8_t *) - /* original_data */ + sizeof(sah_Link *))); /* original_next */ + + if (result != 0) { +#ifdef DIAG_DRV_IF + LOG_KDIAG("copy_from_user() failed."); +#endif + drv_if_done = TRUE; + status = FSL_RETURN_INTERNAL_ERROR_S; + } + + if (status == FSL_RETURN_OK_S) { + /* This will create new links which can be used to replace tmp_link + * in the chain. This will return a new head and tail link. */ + link_data_length = link_data_length + link_copy.len; + new_head_link = + sah_Make_Links(user_ctx, &link_copy, &new_tail_link); + + if (new_head_link == NULL) { + /* If we ran out of memory or a user pointer was invalid */ + drv_if_done = TRUE; + status = FSL_RETURN_INTERNAL_ERROR_S; +#ifdef DIAG_DRV_IF + LOG_KDIAG("sah_Make_Links() failed."); +#endif + } else { + if (is_this_the_head == TRUE) { + /* Keep a reference to the head link */ + head_link = new_head_link; + is_this_the_head = FALSE; + } else { + /* Need to update the previous links' next field to point + * to the current link. */ + prev_tail_link->next = + (void *)new_head_link->dma_addr; + prev_tail_link->original_next = + new_head_link; + } + } + } + + if (status == FSL_RETURN_OK_S) { + /* Get to the next link in the chain. */ + user_link = link_copy.next; + prev_tail_link = new_tail_link; + + /* Check if the end of the link chain was reached (TRUE) or if + * there is another linked to this one (FALSE) */ + drv_if_done = (user_link == NULL) ? TRUE : FALSE; + } + } /* end while */ + + if (status != FSL_RETURN_OK_S) { + ret_val = NULL; + /* There could be clean-up to do here because we may have made some + * successful iterations through the while loop and as a result, the + * links created by sah_Make_Links() need to be destroyed. + */ + if (head_link != NULL) { + /* Failed somewhere in the while loop and need to clean-up. */ + sah_Destroy_Links(head_link); + } + } else { + /* Success. Return the head link. */ + ret_val = head_link; + } + + return ret_val; +} /* sah_Copy_Links() */ + +/*! +******************************************************************************* +* This function takes an input link pointed to by a user-space address +* and returns a chain of links that span the physical pages pointed +* to by the input link. +* +* @brief Kernel Link Chain Constructor +* +* @param ptr A link pointer from user-space. +* @param tail The address of a link pointer. This is used to return +* the tail link created by this function. +* +* @return sah_Link * - A virtual address of the first link in the +* chain. +* @return NULL - If there was some error. +* +*/ +sah_Link *sah_Make_Links(fsl_shw_uco_t * user_ctx, + sah_Link * ptr, sah_Link ** tail) +{ + int result = -1; + int page_index = 0; + fsl_shw_return_t status = FSL_RETURN_OK_S; + int is_this_the_head = TRUE; + void *buffer_start = NULL; + sah_Link *link = NULL; + sah_Link *prev_link = NULL; + sah_Link *head_link = NULL; + sah_Link *ret_val = NULL; + int buffer_length = 0; + struct page **local_pages = NULL; + int nr_pages = 0; + int write = (sah_Link_Get_Flags(ptr) & SAH_OUTPUT_LINK) ? WRITE : READ; + + /* need to retrieve stored key? */ + if (ptr->flags & SAH_STORED_KEY_INFO) { + fsl_shw_return_t ret_status; + + /* allocate space for this link */ + link = sah_Alloc_Link(); +#ifdef DIAG_MEM + sprintf(Diag_msg, "Alloc_Link returned %p/%p\n", link, + (void *)link->dma_addr); + LOG_KDIAG(Diag_msg); +#endif + + if (link == NULL) { + status = FSL_RETURN_NO_RESOURCE_S; +#ifdef DIAG_DRV_IF + LOG_KDIAG("sah_Alloc_Link() failed!"); +#endif + return link; + } else { + uint32_t max_len = 0; /* max slot length */ + + /* get length and physical address of stored key */ + ret_status = system_keystore_get_slot_info(ptr->ownerid, ptr->slot, (uint32_t *) & link->data, /* RED key address */ + &max_len); +#ifdef DIAG_DRV_IF + LOG_KDIAG_ARGS + ("ret_status==SCC_RET_OK? %s. slot: %i. data: %p" + ". len: %i, key length: %i", + (ret_status == FSL_RETURN_OK_S ? "yes" : "no"), + ptr->slot, link->data, max_len, ptr->len); +#endif + + if ((ret_status == FSL_RETURN_OK_S) && (ptr->len <= max_len)) { + /* finish populating the link */ + link->len = ptr->len; + link->flags = ptr->flags & ~SAH_PREPHYS_DATA; + *tail = link; + } else { +#ifdef DIAG_DRV_IF + if (ret_status == FSL_RETURN_OK_S) { + LOG_KDIAG + ("SCC sah_Link key slot reference is too long"); + } else { + LOG_KDIAG + ("SCC sah_Link slot slot reference is invalid"); + } +#endif + sah_Free_Link(link); + status = FSL_RETURN_INTERNAL_ERROR_S; + return NULL; + } + return link; + } + } else if (ptr->flags & SAH_IN_USER_KEYSTORE) { + +#ifdef FSL_HAVE_SCC2 + + void *kernel_base; + + /* allocate space for this link */ + link = sah_Alloc_Link(); +#ifdef DIAG_MEM + sprintf(Diag_msg, "Alloc_Link returned %p/%p\n", link, + (void *)link->dma_addr); + LOG_KDIAG(Diag_msg); +#endif /* DIAG_MEM */ + + if (link == NULL) { + status = FSL_RETURN_NO_RESOURCE_S; +#ifdef DIAG_DRV_IF + LOG_KDIAG("sah_Alloc_Link() failed!"); +#endif + return link; + } else { + /* link->data points to the virtual address of the key data, however + * this memory does not need to be locked down. + */ + kernel_base = lookup_user_partition(user_ctx, + (uint32_t) ptr-> + data & PAGE_MASK); + + link->data = (uint8_t *) scc_virt_to_phys(kernel_base + + ((unsigned + long)ptr-> + data & + ~PAGE_MASK)); + + /* Do bounds checking to ensure that the user is not overstepping + * the bounds of their partition. This is a simple implementation + * that assumes the user only owns one partition. It only checks + * to see if the address of the last byte of data steps over a + * page boundary. + */ + if ((kernel_base != NULL) && + ((((uint32_t) link->data + + link->len) >> PAGE_SHIFT) == + ((uint32_t) link->data >> PAGE_SHIFT))) { + /* finish populating the link */ + link->len = ptr->len; + link->flags = ptr->flags & ~SAH_PREPHYS_DATA; + *tail = link; + } else { +#ifdef DIAG_DRV_IF + if (kernel_base != NULL) { + LOG_KDIAG + ("SCC sah_Link key slot reference is too long"); + } else { + LOG_KDIAG + ("SCC sah_Link slot slot reference is invalid"); + } +#endif + sah_Free_Link(link); + status = FSL_RETURN_INTERNAL_ERROR_S; + return NULL; + } + return link; + } + +#else /* FSL_HAVE_SCC2 */ + + return NULL; + +#endif /* FSL_HAVE_SCC2 */ + } + + if (ptr->data == NULL) { + /* The user buffer must not be NULL because map_user_kiobuf() cannot + * handle NULL pointer input. + */ + status = FSL_RETURN_BAD_DATA_LENGTH_S; +#ifdef DIAG_DRV_IF + LOG_KDIAG("sah_Link data pointer is NULL."); +#endif + } + + if (status == FSL_RETURN_OK_S) { + unsigned long start_page = (unsigned long)ptr->data & PAGE_MASK; + + /* determine number of pages being used for this link */ + nr_pages = (((unsigned long)(ptr->data) & ~PAGE_MASK) + + ptr->len + ~PAGE_MASK) >> PAGE_SHIFT; + + /* ptr contains all the 'user space' information, add the pages + * to it also just so everything is in one place */ + local_pages = + kmalloc(nr_pages * sizeof(struct page *), GFP_KERNEL); + + if (local_pages == NULL) { + status = FSL_RETURN_NO_RESOURCE_S; /* no memory! */ +#ifdef DIAG_DRV_IF + LOG_KDIAG("kmalloc() failed."); +#endif + } else { + /* get the actual pages being used in 'user space' */ + + down_read(¤t->mm->mmap_sem); + result = get_user_pages(current, current->mm, + start_page, nr_pages, + write, 0 /* noforce */ , + local_pages, NULL); + up_read(¤t->mm->mmap_sem); + + if (result < nr_pages) { +#ifdef DIAG_DRV_IF + LOG_KDIAG("get_user_pages() failed."); +#endif + if (result > 0) { + for (page_index = 0; + page_index < result; + page_index++) { + page_cache_release(local_pages + [page_index]); + } + } + status = FSL_RETURN_INTERNAL_ERROR_S; + } + } + } + + /* Now we can walk through the list of pages in the buffer */ + if (status == FSL_RETURN_OK_S) { + +#if defined(FLUSH_SPECIFIC_DATA_ONLY) && !defined(HAS_L2_CACHE) + /* + * Now that pages are wired, clear user data from cache lines. When + * there is just an L1 cache, clean based on user virtual for ARM. + */ + if (write == WRITE) { + os_cache_flush_range(ptr->data, ptr->len); + } else { + os_cache_clean_range(ptr->data, ptr->len); + } +#endif + + for (page_index = 0; page_index < nr_pages; page_index++) { + /* Allocate a new link structure */ + link = sah_Alloc_Link(); +#ifdef DIAG_MEM + sprintf(Diag_msg, "Alloc_Link returned %p/%p\n", link, + (void *)link->dma_addr); + LOG_KDIAG(Diag_msg); +#endif + if (link == NULL) { +#ifdef DIAG_DRV_IF + LOG_KDIAG("sah_Alloc_Link() failed."); +#endif + status = FSL_RETURN_NO_RESOURCE_S; + + /* need to free the rest of the pages. Destroy_Links will take + * care of the ones already assigned to a link */ + for (; page_index < nr_pages; page_index++) { + page_cache_release(local_pages + [page_index]); + } + break; /* exit 'for page_index' loop */ + } + + if (status == FSL_RETURN_OK_S) { + if (is_this_the_head == TRUE) { + /* keep a reference to the head link */ + head_link = link; + /* remember that we have seen the head link */ + is_this_the_head = FALSE; + } else { + /* If this is not the head link then set the previous + * link's next pointer to point to this link */ + prev_link->original_next = link; + prev_link->next = + (sah_Link *) link->dma_addr; + } + + buffer_start = + page_address(local_pages[page_index]); + + if (page_index == 0) { + /* If this is the first page, there might be an + * offset. We need to increment the address by this offset + * so we don't just get the start of the page. + */ + buffer_start += + (unsigned long) + sah_Link_Get_Data(ptr) + & ~PAGE_MASK; + buffer_length = PAGE_SIZE + - + ((unsigned long) + sah_Link_Get_Data(ptr) + & ~PAGE_MASK); + } else { + buffer_length = PAGE_SIZE; + } + + if (page_index == nr_pages - 1) { + /* if this is the last page, we need to adjust + * the buffer_length to account for the last page being + * partially used. + */ + buffer_length -= + nr_pages * PAGE_SIZE - + sah_Link_Get_Len(ptr) - + ((unsigned long) + sah_Link_Get_Data(ptr) & + ~PAGE_MASK); + } +#if defined(FLUSH_SPECIFIC_DATA_ONLY) && defined(HAS_L2_CACHE) + /* + * When there is an L2 cache, clean based on kernel + * virtual.. + */ + if (write == WRITE) { + os_cache_flush_range(buffer_start, + buffer_length); + } else { + os_cache_clean_range(buffer_start, + buffer_length); + } +#endif + + /* Fill in link information */ + link->len = buffer_length; +#if !defined(HAS_L2_CACHE) + /* use original virtual */ + link->original_data = ptr->data; +#else + /* use kernel virtual */ + link->original_data = buffer_start; +#endif + link->data = (void *)os_pa(buffer_start); + link->flags = ptr->flags & ~SAH_PREPHYS_DATA; + link->vm_info = local_pages[page_index]; + prev_link = link; + +#if defined(NO_OUTPUT_1K_CROSSING) || defined(NO_1K_CROSSING) + if ( +#ifdef NO_OUTPUT_1K_CROSSING + /* Insert extra link if 1k boundary on output pointer + * crossed not at an 8-word boundary */ + (link->flags & SAH_OUTPUT_LINK) && + (((uint32_t) buffer_start % 32) != 0) + && +#endif + ((((uint32_t) buffer_start & 1023) + + buffer_length) > 1024)) { + + /* Shorten current link to 1k boundary */ + link->len = + 1024 - + ((uint32_t) buffer_start % 1024); + + /* Get new link to follow it */ + link = sah_Alloc_Link(); + prev_link->len = + 1024 - + ((uint32_t) buffer_start % 1024); + prev_link->original_next = link; + prev_link->next = + (sah_Link *) link->dma_addr; + buffer_length -= prev_link->len; + buffer_start += prev_link->len; + +#if !defined(HAS_L2_CACHE) + /* use original virtual */ + link->original_data = ptr->data; +#else + /* use kernel virtual */ + link->original_data = buffer_start; +#endif + link->data = + (void *)os_pa(buffer_start); + link->vm_info = prev_link->vm_info; + prev_link->vm_info = NULL; /* delay release */ + link->flags = ptr->flags; + link->len = buffer_length; + prev_link = link; + } /* while link would cross 1K boundary */ +#endif /* 1K_CROSSING */ + } + } /* for each page */ + } + + if (local_pages != NULL) { + kfree(local_pages); + } + + if (status != FSL_RETURN_OK_S) { + /* De-allocated any links created, this routine first looks if + * head_link is NULL */ + sah_Destroy_Links(head_link); + + /* Clean-up of the KIOBUF will occur in the * sah_Copy_Descriptors() + * function. + * Clean-up of the Queue entry must occur in the function called + * sah_Copy_Descriptors(). + */ + } else { + + /* Success. Return the head link. */ + ret_val = head_link; + link->original_next = NULL; + /* return the tail link as well */ + *tail = link; + } + + return ret_val; +} /* sah_Make_Links() */ + +/*! +******************************************************************************* +* This walks through a SAHARA descriptor chain and frees everything +* that is not NULL. Finally it also unmaps all of the physical memory and +* frees the kiobuf_list Queue. +* +* @brief Kernel Descriptor Chain Destructor +* +* @param desc A Descriptor pointer from kernel-space. This should be +* in bus address space. +* +* @return void +* +*/ +void sah_Destroy_Descriptors(sah_Head_Desc * head_desc) +{ + sah_Desc *this_desc = (sah_Desc *) head_desc; + sah_Desc *next_desc = NULL; + int this_is_head = 1; + + /* + * Flush the D-cache. This flush is here because the hardware has finished + * processing this descriptor and probably has changed the contents of + * some linked user buffers as a result. This flush will enable + * user-space applications to see the correct data rather than the + * out-of-date cached version. + */ +#ifndef FLUSH_SPECIFIC_DATA_ONLY + os_flush_cache_all(); +#endif + + head_desc = (sah_Head_Desc *) this_desc->virt_addr; + + while (this_desc != NULL) { + if (this_desc->ptr1 != NULL) { + sah_Destroy_Links(this_desc->original_ptr1 + ? this_desc-> + original_ptr1 : this_desc->ptr1); + } + if (this_desc->ptr2 != NULL) { + sah_Destroy_Links(this_desc->original_ptr2 + ? this_desc-> + original_ptr2 : this_desc->ptr2); + } + + /* Get a bus pointer to the next Descriptor */ + next_desc = (this_desc->original_next + ? this_desc->original_next : this_desc->next); + + /* Zero the header and Length fields for security reasons. */ + this_desc->header = 0; + this_desc->len1 = 0; + this_desc->len2 = 0; + + if (this_is_head) { + sah_Free_Head_Descriptor(head_desc); +#ifdef DIAG_MEM + sprintf(Diag_msg, "Free_Head_Descriptor: %p\n", + head_desc); + LOG_KDIAG(Diag_msg); +#endif + this_is_head = 0; + } else { + /* free this descriptor */ + sah_Free_Descriptor(this_desc); +#ifdef DIAG_MEM + sprintf(Diag_msg, "Free_Descriptor: %p\n", this_desc); + LOG_KDIAG(Diag_msg); +#endif + } + + /* Set up for next round. */ + this_desc = (sah_Desc *) next_desc; + } +} + +/*! +******************************************************************************* +* This walks through a SAHARA link chain and frees everything that is +* not NULL excluding user-space buffers. +* +* @brief Kernel Link Chain Destructor +* +* @param link A Link pointer from kernel-space. +* +* @return void +* +*/ +void sah_Destroy_Links(sah_Link * link) +{ + sah_Link *this_link = link; + sah_Link *next_link = NULL; + + while (this_link != NULL) { + + /* if this link indicates an associated page, process it */ + if (this_link->vm_info != NULL) { + /* since this function is only called from the routine that + * creates a kernel copy of the user space descriptor chain, + * there are no pages to dirty. All that is needed is to release + * the page from cache */ + page_cache_release(this_link->vm_info); + } + + /* Get a bus pointer to the next Link */ + next_link = (this_link->original_next + ? this_link->original_next : this_link->next); + + /* Zero the Pointer and Length fields for security reasons. */ + this_link->data = NULL; + this_link->len = 0; + + /* Free this Link */ + sah_Free_Link(this_link); +#ifdef DIAG_MEM + sprintf(Diag_msg, "Free_Link: %p\n", this_link); + LOG_KDIAG(Diag_msg); +#endif + + /* Look at the next Link */ + this_link = next_link; + } +} + +/*! +******************************************************************************* +* @brief Initialize memory manager/mapper. +* +* In 2.4, this function also allocates a kiovec to be used when mapping user +* data to kernel space +* +* @return 0 for success, OS error code on failure +* +*/ +int sah_Init_Mem_Map(void) +{ + int ret = OS_ERROR_FAIL_S; + + mem_lock = os_lock_alloc_init(); + + /* + * If one of these fails, change the calculation in the #define earlier in + * the file to be the other one. + */ + if (sizeof(sah_Link) > MEM_BLOCK_SIZE) { + os_printk("Sahara Driver: sah_Link structure is too large\n"); + } else if (sizeof(sah_Desc) > MEM_BLOCK_SIZE) { + os_printk("Sahara Driver: sah_Desc structure is too large\n"); + } else { + ret = OS_ERROR_OK_S; + } + +#ifndef SELF_MANAGED_POOL + + big_dma_pool = dma_pool_create("sah_big_blocks", NULL, + sizeof(Mem_Big_Block), sizeof(uint32_t), + PAGE_SIZE); + small_dma_pool = dma_pool_create("sah_small_blocks", NULL, + sizeof(Mem_Block), sizeof(uint32_t), + PAGE_SIZE); +#else + +#endif + return ret; +} + +/*! +******************************************************************************* +* @brief Clean up memory manager/mapper. +* +* In 2.4, this function also frees the kiovec used when mapping user data to +* kernel space. +* +* @return none +* +*/ +void sah_Stop_Mem_Map(void) +{ + os_lock_deallocate(mem_lock); + +#ifndef SELF_MANAGED_POOL + if (big_dma_pool != NULL) { + dma_pool_destroy(big_dma_pool); + } + if (small_dma_pool != NULL) { + dma_pool_destroy(small_dma_pool); + } +#endif +} + +/*! +******************************************************************************* +* Allocate Head descriptor from free pool. +* +* @brief Allocate Head descriptor +* +* @return sah_Head_Desc Free descriptor, NULL if no free descriptors available. +* +*/ +sah_Head_Desc *sah_Alloc_Head_Descriptor(void) +{ + Mem_Big_Block *block; + sah_Head_Desc *desc; + + block = sah_Alloc_Big_Block(); + if (block != NULL) { + /* initialize everything */ + desc = (sah_Head_Desc *) block->data; + + desc->desc.virt_addr = (sah_Desc *) desc; + desc->desc.dma_addr = block->dma_addr; + desc->desc.original_ptr1 = NULL; + desc->desc.original_ptr2 = NULL; + desc->desc.original_next = NULL; + + desc->desc.ptr1 = NULL; + desc->desc.ptr2 = NULL; + desc->desc.next = NULL; + } else { + desc = NULL; + } + + return desc; +} + +/*! +******************************************************************************* +* Allocate descriptor from free pool. +* +* @brief Allocate descriptor +* +* @return sah_Desc Free descriptor, NULL if no free descriptors available. +* +*/ +sah_Desc *sah_Alloc_Descriptor(void) +{ + Mem_Block *block; + sah_Desc *desc; + + block = sah_Alloc_Block(); + if (block != NULL) { + /* initialize everything */ + desc = (sah_Desc *) block->data; + + desc->virt_addr = desc; + desc->dma_addr = block->dma_addr; + desc->original_ptr1 = NULL; + desc->original_ptr2 = NULL; + desc->original_next = NULL; + + desc->ptr1 = NULL; + desc->ptr2 = NULL; + desc->next = NULL; + } else { + desc = NULL; + } + + return (desc); +} + +/*! +******************************************************************************* +* Allocate link from free pool. +* +* @brief Allocate link +* +* @return sah_Link Free link, NULL if no free links available. +* +*/ +sah_Link *sah_Alloc_Link(void) +{ + Mem_Block *block; + sah_Link *link; + + block = sah_Alloc_Block(); + if (block != NULL) { + /* initialize everything */ + link = (sah_Link *) block->data; + + link->virt_addr = link; + link->original_next = NULL; + link->original_data = NULL; + /* information found in allocated block */ + link->dma_addr = block->dma_addr; + + /* Sahara link fields */ + link->len = 0; + link->data = NULL; + link->next = NULL; + + /* driver required fields */ + link->flags = 0; + link->vm_info = NULL; + } else { + link = NULL; + } + + return link; +} + +#ifdef SELF_MANAGED_POOL +/*! +******************************************************************************* +* Add a new page to end of block free pool. This will allocate one page and +* fill the pool with entries, appending to the end. +* +* @brief Add page of blocks to block free pool. +* +* @pre This function must be called with the #mem_lock held. +* +* @param big 0 - make blocks big enough for sah_Desc +* non-zero - make blocks big enough for sah_Head_Desc +* +* @return int TRUE if blocks added succeesfully, FALSE otherwise +* +*/ +int sah_Block_Add_Page(int big) +{ + void *page; + int success; + dma_addr_t dma_addr; + unsigned block_index; + uint32_t dma_offset; + unsigned block_entries = + big ? MEM_BIG_BLOCK_ENTRIES : MEM_BLOCK_ENTRIES; + unsigned block_size = big ? sizeof(Mem_Big_Block) : sizeof(Mem_Block); + void *block; + + /* Allocate page of memory */ +#ifndef USE_COHERENT_MEMORY + page = os_alloc_memory(PAGE_SIZE, GFP_ATOMIC | __GFP_DMA); + dma_addr = os_pa(page); +#else + page = os_alloc_coherent(PAGE_SIZE, &dma_addr, GFP_ATOMIC); +#endif + if (page != NULL) { + /* + * Find the difference between the virtual address and the DMA + * address of the page. This is used later to determine the DMA + * address of each individual block. + */ + dma_offset = page - (void *)dma_addr; + + /* Split page into blocks and add to free pool */ + block = page; + for (block_index = 0; block_index < block_entries; + block_index++) { + if (big) { + register Mem_Big_Block *blockp = block; + blockp->dma_addr = + (uint32_t) (block - dma_offset); + sah_Append_Big_Block(blockp); + } else { + register Mem_Block *blockp = block; + blockp->dma_addr = + (uint32_t) (block - dma_offset); + /* sah_Append_Block must be protected with spin locks. This is + * done in sah_Alloc_Block(), which calls + * sah_Block_Add_Page() */ + sah_Append_Block(blockp); + } + block += block_size; + } + success = TRUE; +#ifdef DIAG_MEM + LOG_KDIAG("Succeeded in allocating new page"); +#endif + } else { + success = FALSE; +#ifdef DIAG_MEM + LOG_KDIAG("Failed in allocating new page"); +#endif + } + + return success; +} +#endif /* SELF_MANAGED_POOL */ + +#ifdef SELF_MANAGED_POOL +/*! +******************************************************************************* +* Allocate block from free pool. A block is large enough to fit either a link +* or descriptor. +* +* @brief Allocate memory block +* +* @return Mem_Block Free block, NULL if no free blocks available. +* +*/ +static Mem_Big_Block *sah_Alloc_Big_Block(void) +{ + Mem_Big_Block *block; + os_lock_context_t lock_flags; + + os_lock_save_context(mem_lock, lock_flags); + + /* If the pool is empty, try to allocate more entries */ + if (big_block_free_head == NULL) { + (void)sah_Block_Add_Page(1); + } + + /* Check that the pool now has some free entries */ + if (big_block_free_head != NULL) { + /* Return the head of the free pool */ + block = big_block_free_head; + + big_block_free_head = big_block_free_head->next; + if (big_block_free_head == NULL) { + /* Allocated last entry in pool */ + big_block_free_tail = NULL; + } + } else { + block = NULL; + } + os_unlock_restore_context(mem_lock, lock_flags); + + return block; +} +#else +/*! +******************************************************************************* +* Allocate block from free pool. A block is large enough to fit either a link +* or descriptor. +* +* @brief Allocate memory block +* +* @return Mem_Block Free block, NULL if no free blocks available. +* +*/ +static Mem_Big_Block *sah_Alloc_Big_Block(void) +{ + dma_addr_t dma_addr; + Mem_Big_Block *block = + dma_pool_alloc(big_dma_pool, GFP_ATOMIC, &dma_addr); + + if (block == NULL) { + } else { + block->dma_addr = dma_addr; + } + + return block; +} +#endif + +#ifdef SELF_MANAGED_POOL +/*! +******************************************************************************* +* Allocate block from free pool. A block is large enough to fit either a link +* or descriptor. +* +* @brief Allocate memory block +* +* @return Mem_Block Free block, NULL if no free blocks available. +* +*/ +/****************************************************************************** +* +* MODIFICATION HISTORY: +* +* Date Person Change +* 31/10/2003 RWK PR52734 - Implement functions to allocate +* descriptors and links. Replace +* consistent_alloc() calls. Initial creation. +* +******************************************************************************/ +static Mem_Block *sah_Alloc_Block(void) +{ + Mem_Block *block; + os_lock_context_t lock_flags; + + os_lock_save_context(mem_lock, lock_flags); + + /* If the pool is empty, try to allocate more entries */ + if (block_free_head == NULL) { + (void)sah_Block_Add_Page(0); + } + + /* Check that the pool now has some free entries */ + if (block_free_head != NULL) { + /* Return the head of the free pool */ + block = block_free_head; + + block_free_head = block_free_head->next; + if (block_free_head == NULL) { + /* Allocated last entry in pool */ + block_free_tail = NULL; + } + } else { + block = NULL; + } + os_unlock_restore_context(mem_lock, lock_flags); + + return block; +} +#else +/*! +******************************************************************************* +* Allocate block from free pool. A block is large enough to fit either a link +* or descriptor. +* +* @brief Allocate memory block +* +* @return Mem_Block Free block, NULL if no free blocks available. +* +*/ +/****************************************************************************** +* +* MODIFICATION HISTORY: +* +* Date Person Change +* 31/10/2003 RWK PR52734 - Implement functions to allocate +* descriptors and links. Replace +* consistent_alloc() calls. Initial creation. +* +******************************************************************************/ +static Mem_Block *sah_Alloc_Block(void) +{ + + dma_addr_t dma_addr; + Mem_Block *block = + dma_pool_alloc(small_dma_pool, GFP_ATOMIC, &dma_addr); + + if (block == NULL) { + } else { + block->dma_addr = dma_addr; + } + + return block; +} +#endif + +#ifdef SELF_MANAGED_POOL +/*! +******************************************************************************* +* Free memory block back to free pool +* +* @brief Free memory block +* +* @param block A block allocated with sah_Alloc_Block(). +* +* @return none +* +*/ +static void sah_Free_Block(Mem_Block * block) +{ + os_lock_context_t lock_flags; + + os_lock_save_context(mem_lock, lock_flags); + sah_Append_Block(block); + os_unlock_restore_context(mem_lock, lock_flags); +} +#else +/*! +******************************************************************************* +* Free memory block back to free pool +* +* @brief Free memory block +* +* @param block A block allocated with sah_Alloc_Block(). +* +* @return none +* +*/ +static void sah_Free_Block(Mem_Block * block) +{ + dma_pool_free(small_dma_pool, block, block->dma_addr); +} +#endif + +#ifdef SELF_MANAGED_POOL +/*! +******************************************************************************* +* Free memory block back to free pool +* +* @brief Free memory block +* +* @param block A block allocated with sah_Alloc_Block(). +* +* @return none +* +*/ +static void sah_Free_Big_Block(Mem_Big_Block * block) +{ + os_lock_context_t lock_flags; + + os_lock_save_context(mem_lock, lock_flags); + sah_Append_Big_Block(block); + os_unlock_restore_context(mem_lock, lock_flags); +} +#else +/*! +******************************************************************************* +* Free memory block back to free pool +* +* @brief Free memory block +* +* @param block A block allocated with sah_Alloc_Block(). +* +* @return none +* +*/ +static void sah_Free_Big_Block(Mem_Big_Block * block) +{ + dma_pool_free(big_dma_pool, block, block->dma_addr); +} +#endif + +#ifdef SELF_MANAGED_POOL +/*! +******************************************************************************* +* Append memory block to end of free pool. +* +* @param block A block entry +* +* @return none +* +* @pre This function must be called with the #mem_lock held. +* +* @brief Append memory block to free pool +*/ +static void sah_Append_Big_Block(Mem_Big_Block * block) +{ + + /* Initialise block */ + block->next = NULL; + + /* Remember that block may be the first in the pool */ + if (big_block_free_tail != NULL) { + big_block_free_tail->next = block; + } else { + /* Pool is empty */ + big_block_free_head = block; + } + + big_block_free_tail = block; +} + +/*! +******************************************************************************* +* Append memory block to end of free pool. +* +* @brief Append memory block to free pool +* +* @param block A block entry +* +* @return none +* +* @pre #mem_lock must be held +* +*/ +static void sah_Append_Block(Mem_Block * block) +{ + + /* Initialise block */ + block->next = NULL; + + /* Remember that block may be the first in the pool */ + if (block_free_tail != NULL) { + block_free_tail->next = block; + } else { + /* Pool is empty */ + block_free_head = block; + } + + block_free_tail = block; +} +#endif /* SELF_MANAGED_POOL */ + +/* End of sah_memory_mapper.c */ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/Makefile +++ linux-2.6.28/drivers/mxc/security/sahara2/Makefile @@ -0,0 +1,47 @@ +# Makefile for the Linux Sahara2 driver +# +# This makefile works within a kernel driver tree + +# Need to augment this to support optionally building user-mode support +API_SOURCES = fsl_shw_sym.c fsl_shw_user.c fsl_shw_hash.c fsl_shw_auth.c \ + fsl_shw_hmac.c fsl_shw_rand.c sf_util.c km_adaptor.c fsl_shw_keystore.c \ + fsl_shw_wrap.c \ + + +SOURCES = sah_driver_interface.c sah_hardware_interface.c \ + sah_interrupt_handler.c sah_queue.c sah_queue_manager.c \ + sah_status_manager.c sah_memory_mapper.c + + +# Turn on for mostly full debugging +# DIAGS = -DDIAG_DRV_STATUS -DDIAG_DRV_QUEUE -DDIAG_DRV_INTERRUPT -DDIAG_DRV_IF +# DIAGS += -DDIAG_DURING_INTERRUPT + +# Turn on for lint-type checking +#EXTRA_CFLAGS = -Wall -W -Wstrict-prototypes -Wmissing-prototypes +EXTRA_CFLAGS += -DLINUX_KERNEL $(DIAGS) + + +ifeq ($(CONFIG_MXC_SAHARA_POLL_MODE),y) +EXTRA_CFLAGS += -DSAHARA_POLL_MODE +EXTRA_CFLAGS += -DSAHARA_POLL_MODE_TIMEOUT=$(CONFIG_SAHARA_POLL_MODE_TIMEOUT) +endif + +ifeq ($(CONFIG_MXC_SAHARA_USER_MODE),y) +EXTRA_CFLAGS += -DSAHARA_USER_MODE +SOURCES += +endif + +ifeq ($(CONFIG_PM),y) +EXTRA_CFLAGS += -DSAHARA_POWER_MANAGMENT +endif + +EXTRA_CFLAGS += -Idrivers/mxc/security/sahara2/include + +# handle buggy BSP -- uncomment if these are undefined during build +#EXTRA_CFLAGS += -DSAHARA_BASE_ADDR=HAC_BASE_ADDR -DINT_SAHARA=INT_HAC_RTIC + + +obj-$(CONFIG_MXC_SAHARA) += sahara.o + +sahara-objs := $(SOURCES:.c=.o) $(API_SOURCES:.c=.o) --- linux-2.6.28.orig/drivers/mxc/security/sahara2/sah_status_manager.c +++ linux-2.6.28/drivers/mxc/security/sahara2/sah_status_manager.c @@ -0,0 +1,710 @@ +/* + * Copyright 2004-2008 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 + */ + +/*! +* @file sah_status_manager.c +* +* @brief Status Manager Function +* +* This file contains the function which processes the Sahara status register +* during an interrupt. +* +* This file does not need porting. +*/ + +#include "portable_os.h" + +#include +#include +#include +#include +#include + +#if defined(DIAG_DRV_INTERRUPT) && defined(DIAG_DURING_INTERRUPT) +#include +#endif + +/*! Compile-time flag to count various interrupt types. */ +#define DIAG_INT_COUNT + +/*! + * Number of interrupts processed with Done1Done2 status. Updates to this + * value should only be done in interrupt processing. + */ +uint32_t done1_count; + +/*! + * Number of interrupts processed with Done1Busy2 status. Updates to this + * value should only be done in interrupt processing. + */ +uint32_t done1busy2_count; + +/*! + * Number of interrupts processed with Done1Done2 status. Updates to this + * value should only be done in interrupt processing. + */ +uint32_t done1done2_count; + +/*! + * the dynameic power management flag is false when power management is not + * asserted and true when dpm is. + */ +#ifdef SAHARA_POWER_MANAGEMENT +bool sah_dpm_flag = FALSE; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) +static int sah_dpm_suspend(struct device *dev, uint32_t state, uint32_t level); +static int sah_dpm_resume(struct device *dev, uint32_t level); +#else +static int sah_dpm_suspend(struct platform_device *dev, pm_message_t state); +static int sah_dpm_resume(struct platform_device *dev); +#endif +#endif + +#ifndef SAHARA_POLL_MODE +/*! +******************************************************************************* +* This functionx processes the status register of the Sahara, updates the state +* of the finished queue entry, and then tries to find more work for Sahara to +* do. +* +* @brief The bulk of the interrupt handling code. +* +* @param hw_status The status register of Sahara at time of interrupt. +* The Clear interrupt bit is already handled by this +* register read prior to entry into this function. +* @return void +*/ +unsigned long sah_Handle_Interrupt(sah_Execute_Status hw_status) +{ + unsigned long reset_flag = 0; /* assume no SAHARA reset needed */ + os_lock_context_t lock_flags; + + /* HW status at time of interrupt */ + sah_Execute_Status state = hw_status & SAH_EXEC_STATE_MASK; + + do { + sah_Head_Desc *current_entry; + uint32_t dar; + +#ifdef DIAG_INT_COUNT + if (state == SAH_EXEC_DONE1) { + done1_count++; + } else if (state == SAH_EXEC_DONE1_BUSY2) { + done1busy2_count++; + } else if (state == SAH_EXEC_DONE1_DONE2) { + done1done2_count++; + } +#endif + + /* if the first entry on sahara has completed... */ + if ((state & SAH_EXEC_DONE1_BIT) || + (state == SAH_EXEC_ERROR1)) { + /* lock queue while searching */ + os_lock_save_context(desc_queue_lock, lock_flags); + current_entry = + sah_Find_With_State(SAH_STATE_ON_SAHARA); + os_unlock_restore_context(desc_queue_lock, lock_flags); + + /* an active descriptor was not found */ + if (current_entry == NULL) { + /* change state to avoid an infinite loop (possible if + * state is SAH_EXEC_DONE1_BUSY2 first time into loop) */ + hw_status = SAH_EXEC_IDLE; +#if defined(DIAG_DRV_INTERRUPT) && defined(DIAG_DURING_INTERRUPT) + LOG_KDIAG + ("Interrupt received with nothing on queue."); +#endif + } else { + /* SAHARA has completed its work on this descriptor chain */ + current_entry->status = SAH_STATE_OFF_SAHARA; + + if (state == SAH_EXEC_ERROR1) { + if (hw_status & STATUS_ERROR) { + /* Gather extra diagnostic information */ + current_entry->fault_address = + sah_HW_Read_Fault_Address(); + /* Read this last - it clears the error */ + current_entry->error_status = + sah_HW_Read_Error_Status(); + current_entry->op_status = 0; +#ifdef FSL_HAVE_SAHARA4 + } else { + current_entry->op_status = + sah_HW_Read_Op_Status(); + current_entry->error_status = 0; +#endif + } + + } else { + /* indicate that no errors were found with descriptor + * chain 1 */ + current_entry->error_status = 0; + current_entry->op_status = 0; + + /* is there a second, successfully, completed descriptor + * chain? (done1/error2 processing is handled later) */ + if (state == SAH_EXEC_DONE1_DONE2) { + os_lock_save_context + (desc_queue_lock, + lock_flags); + current_entry = + sah_Find_With_State + (SAH_STATE_ON_SAHARA); + os_unlock_restore_context + (desc_queue_lock, + lock_flags); + + if (current_entry == NULL) { +#if defined(DIAG_DRV_INTERRUPT) && defined(DIAG_DURING_INTERRUPT) + LOG_KDIAG + ("Done1_Done2 Interrupt received with " + "one entry on queue."); +#endif + } else { + /* indicate no errors in descriptor chain 2 */ + current_entry-> + error_status = 0; + current_entry->status = + SAH_STATE_OFF_SAHARA; + } + } + } + } + +#ifdef SAHARA_POWER_MANAGEMENT + /* check dynamic power management is not asserted */ + if (!sah_dpm_flag) { +#endif + do { + /* protect DAR and main_queue */ + os_lock_save_context(desc_queue_lock, + lock_flags); + dar = sah_HW_Read_DAR(); + /* check if SAHARA has space for another descriptor. SAHARA + * only accepts up to the DAR queue size number of DAR + * entries, after that 'dar' will not be zero until the + * pending interrupt is serviced */ + if (dar == 0) { + current_entry = + sah_Find_With_State + (SAH_STATE_PENDING); + if (current_entry != NULL) { +#ifndef SUBMIT_MULTIPLE_DARS + /* BUG FIX: state machine can transition from Done1 + * Busy2 directly to Idle. To fix that problem, + * only one DAR is being allowed on SAHARA at a + * time. If a high level interrupt has happened, + * there could * be an active descriptor chain */ + if (sah_Find_With_State + (SAH_STATE_ON_SAHARA) + == NULL) { +#endif +#if defined(DIAG_DRV_IF) && defined(DIAG_DURING_INTERRUPT) + sah_Dump_Chain + (¤t_entry-> + desc, + current_entry-> + desc. + dma_addr); +#endif /* DIAG_DRV_IF */ + sah_HW_Write_DAR + (current_entry-> + desc. + dma_addr); + current_entry-> + status = + SAH_STATE_ON_SAHARA; +#ifndef SUBMIT_MULTIPLE_DARS + } + current_entry = NULL; /* exit loop */ +#endif + } + } + os_unlock_restore_context + (desc_queue_lock, lock_flags); + } while ((dar == 0) && (current_entry != NULL)); +#ifdef SAHARA_POWER_MANAGEMENT + } /* sah_device_power_manager */ +#endif + } else { + if (state == SAH_EXEC_FAULT) { + sah_Head_Desc *previous_entry; /* point to chain 1 */ + /* Address of request when fault occured */ + uint32_t bad_dar = sah_HW_Read_IDAR(); + + reset_flag = 1; /* SAHARA needs to be reset */ + + /* get first of possible two descriptor chain that was + * on SAHARA */ + os_lock_save_context(desc_queue_lock, + lock_flags); + previous_entry = + sah_Find_With_State(SAH_STATE_ON_SAHARA); + os_unlock_restore_context(desc_queue_lock, + lock_flags); + + /* if it exists, continue processing the fault */ + if (previous_entry) { + /* assume this chain didn't complete correctly */ + previous_entry->error_status = -1; + previous_entry->status = + SAH_STATE_OFF_SAHARA; + + /* get the second descriptor chain */ + os_lock_save_context(desc_queue_lock, + lock_flags); + current_entry = + sah_Find_With_State + (SAH_STATE_ON_SAHARA); + os_unlock_restore_context + (desc_queue_lock, lock_flags); + + /* if it exists, continue processing both chains */ + if (current_entry) { + /* assume this chain didn't complete correctly */ + current_entry->error_status = + -1; + current_entry->status = + SAH_STATE_OFF_SAHARA; + + /* now see if either can be identified as the one + * in progress when the fault occured */ + if (current_entry->desc. + dma_addr == bad_dar) { + /* the second descriptor chain was active when the + * fault occured, so the first descriptor chain + * was successfull */ + previous_entry-> + error_status = 0; + } else { + if (previous_entry-> + desc.dma_addr == + bad_dar) { + /* if the first chain was in progress when the + * fault occured, the second has not yet been + * touched, so reset it to PENDING */ + current_entry-> + status = + SAH_STATE_PENDING; + } + } + } + } +#if defined(DIAG_DRV_INTERRUPT) && defined(DIAG_DURING_INTERRUPT) + } else { + /* shouldn't ever get here */ + if (state == SAH_EXEC_BUSY) { + LOG_KDIAG + ("Got Sahara interrupt in Busy state"); + } else { + if (state == SAH_EXEC_IDLE) { + LOG_KDIAG + ("Got Sahara interrupt in Idle state"); + } else { + LOG_KDIAG + ("Got Sahara interrupt in unknown state"); + } + } +#endif + } + } + + /* haven't handled the done1/error2 (the error 2 part), so setup to + * do that now. Otherwise, exit loop */ + state = (state == SAH_EXEC_DONE1_ERROR2) ? + SAH_EXEC_ERROR1 : SAH_EXEC_IDLE; + + /* Keep going while further status is available. */ + } while (state == SAH_EXEC_ERROR1); + + return reset_flag; +} + +#endif /* ifndef SAHARA_POLL_MODE */ + +#ifdef SAHARA_POLL_MODE +/*! +******************************************************************************* +* Submits descriptor chain to SAHARA, polls on SAHARA for completion, process +* results, and dephysicalizes chain +* +* @brief Handle poll mode. +* +* @param entry Virtual address of a physicalized chain +* +* @return 0 this function is always successful +*/ + +unsigned long sah_Handle_Poll(sah_Head_Desc * entry) +{ + sah_Execute_Status hw_status; /* Sahara's status register */ + os_lock_context_t lock_flags; + + /* lock SARAHA */ + os_lock_save_context(desc_queue_lock, lock_flags); + +#ifdef SAHARA_POWER_MANAGEMENT + /* check if the dynamic power management is asserted */ + if (sah_dpm_flag) { + /* return that request failed to be processed */ + entry->result = FSL_RETURN_ERROR_S; + entry->fault_address = 0xBAD; + entry->op_status= 0xBAD; + entry->error_status = 0xBAD; + } else { +#endif /* SAHARA_POWER_MANAGEMENT */ + +#if defined(DIAG_DRV_IF) + sah_Dump_Chain(&entry->desc, entry->desc.dma_addr); +#endif /* DIAG_DRV_IF */ + /* Nothing can be in the dar if we got the lock */ + sah_HW_Write_DAR((uint32_t) (entry->desc.dma_addr)); + + /* Wait for SAHARA to finish with this entry */ + hw_status = sah_Wait_On_Sahara(); + + /* if entry completed successfully, mark it as such */ + /**** HARDWARE ERROR WORK AROUND (hw_status == SAH_EXEC_IDLE) *****/ + if ( +#ifndef SUBMIT_MULTIPLE_DARS + (hw_status == SAH_EXEC_IDLE) || (hw_status == SAH_EXEC_DONE1_BUSY2) || /* should not happen */ +#endif + (hw_status == SAH_EXEC_DONE1) + ) { + entry->error_status = 0; + entry->result = FSL_RETURN_OK_S; + } else { + /* SAHARA is reporting an error with entry */ + if (hw_status == SAH_EXEC_ERROR1) { + /* Gather extra diagnostic information */ + entry->fault_address = + sah_HW_Read_Fault_Address(); + /* Read this register last - it clears the error */ + entry->error_status = + sah_HW_Read_Error_Status(); + entry->op_status = 0; + /* translate from SAHARA error status to fsl_shw return values */ + entry->result = + sah_convert_error_status(entry-> + error_status); +#ifdef DIAG_DRV_STATUS + sah_Log_Error(entry->op_status, + entry->error_status, + entry->fault_address); +#endif + } else if (hw_status == SAH_EXEC_OPSTAT1) { + entry->op_status = sah_HW_Read_Op_Status(); + entry->error_status = 0; + entry->result = + sah_convert_op_status(op_status); + } else { + /* SAHARA entered FAULT state (or something bazaar has + * happened) */ + pr_debug + ("Sahara: hw_status = 0x%x; Stat: 0x%08x; IDAR: 0x%08x; " + "CDAR: 0x%08x; FltAdr: 0x%08x; Estat: 0x%08x\n", + hw_status, sah_HW_Read_Status(), + sah_HW_Read_IDAR(), sah_HW_Read_CDAR(), + sah_HW_Read_Fault_Address(), + sah_HW_Read_Error_Status()); +#ifdef DIAG_DRV_IF + { + int old_level = console_loglevel; + console_loglevel = 8; + sah_Dump_Chain(&(entry->desc), + entry->desc.dma_addr); + console_loglevel = old_level; + } +#endif + + entry->error_status = -1; + entry->result = FSL_RETURN_ERROR_S; + sah_HW_Reset(); + } + } +#ifdef SAHARA_POWER_MANAGEMENT + } +#endif + + if (!(entry->uco_flags & FSL_UCO_BLOCKING_MODE)) { + /* put it in results pool to allow get_results to work */ + sah_Queue_Append_Entry(&entry->user_info->result_pool, entry); + if (entry->uco_flags & FSL_UCO_CALLBACK_MODE) { + /* invoke callback */ + entry->user_info->callback(entry->user_info); + } + } else { + /* convert the descriptor link back to virtual memory, mark dirty pages + * if they are from user mode, and release the page cache for user + * pages + */ + entry = sah_DePhysicalise_Descriptors(entry); + } + + os_unlock_restore_context(desc_queue_lock, lock_flags); + + return 0; +} + +#endif /* SAHARA_POLL_MODE */ + +/****************************************************************************** +* The following is the implementation of the Dynamic Power Management +* functionality. +******************************************************************************/ +#ifdef SAHARA_POWER_MANAGEMENT + +static bool sah_dpm_init_flag; + +/* dynamic power management information for the sahara driver */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) +static struct device_driver sah_dpm_driver = { + .name = "sahara_", + .bus = &platform_bus_type, +#else +static struct platform_driver sah_dpm_driver = { + .driver.name = "sahara_", + .driver.bus = &platform_bus_type, +#endif + .suspend = sah_dpm_suspend, + .resume = sah_dpm_resume +}; + +/* dynamic power management information for the sahara HW device */ +static struct platform_device sah_dpm_device = { + .name = "sahara_", + .id = 1, +}; + +/*! +******************************************************************************* +* Initilaizes the dynamic power managment functionality +* +* @brief Initialization of the Dynamic Power Management functionality +* +* @return 0 = success; failed otherwise +*/ +int sah_dpm_init() +{ + int status; + + /* dpm is not asserted */ + sah_dpm_flag = FALSE; + + /* register the driver to the kernel */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) + status = os_register_to_driver(&sah_dpm_driver); +#else + status = os_register_to_driver(&sah_dpm_driver.driver); +#endif + + if (status == 0) { + /* register a single sahara chip */ + /*status = platform_device_register(&sah_dpm_device); */ + status = os_register_a_device(&sah_dpm_device); + + /* if something went awry, unregister the driver */ + if (status != 0) { + /*driver_unregister(&sah_dpm_driver); */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) + os_unregister_from_driver(&sah_dpm_driver); +#else + os_unregister_from_driver(&sah_dpm_driver.driver); +#endif + sah_dpm_init_flag = FALSE; + } else { + /* if everything went okay, flag that life is good */ + sah_dpm_init_flag = TRUE; + } + } + + /* let the kernel know how it went */ + return status; + +} + +/*! +******************************************************************************* +* Unregister the dynamic power managment functionality +* +* @brief Unregister the Dynamic Power Management functionality +* +*/ +void sah_dpm_close() +{ + /* if dynamic power management was initilaized, kill it */ + if (sah_dpm_init_flag == TRUE) { + /*driver_unregister(&sah_dpm_driver); */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) + os_unregister_from_driver(&sah_dpm_driver); +#else + os_unregister_from_driver(&sah_dpm_driver.driver); +#endif + /*platform_device_register(&sah_dpm_device); */ + os_unregister_a_device(&sah_dpm_device); + } +} + +/*! +******************************************************************************* +* Callback routine defined by the Linux Device Model / Dynamic Power management +* extension. It sets a global flag to disallow the driver to enter queued items +* into Sahara's DAR. +* +* It allows the current active descriptor chains to complete before it returns +* +* @brief Suspends the driver +* +* @param dev contains device information +* @param state contains state information +* @param level level of shutdown +* +* @return 0 = success; failed otherwise +*/ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) +static int sah_dpm_suspend(struct device *dev, uint32_t state, uint32_t level) +#else +static int sah_dpm_suspend(struct platform_device *dev, pm_message_t state) +#endif +{ + sah_Head_Desc *entry = NULL; + os_lock_context_t lock_flags; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) + switch (level) { + case SUSPEND_DISABLE: + /* Assert dynamic power management. This stops the driver from + * entering queued requests to Sahara */ + sah_dpm_flag = TRUE; + break; + + case SUSPEND_SAVE_STATE: + break; + + case SUSPEND_POWER_DOWN: + /* hopefully between the DISABLE call and this one, the outstanding + * work Sahara was doing complete. this checks (and waits) for + * those entries that were already active on Sahara to complete */ + /* lock queue while searching */ + os_lock_save_context(desc_queue_lock, lock_flags); + do { + entry = sah_Find_With_State(SAH_STATE_ON_SAHARA); + } while (entry != NULL); + os_unlock_restore_context(desc_queue_lock, lock_flags); + + /* now we kill the clock so the control circuitry isn't sucking + * any power */ + mxc_clks_disable(SAHARA2_CLK); + break; + } +#else + /* Assert dynamic power management. This stops the driver from + * entering queued requests to Sahara */ + sah_dpm_flag = TRUE; + + /* Now wait for any outstanding work Sahara was doing to complete. + * this checks (and waits) for + * those entries that were already active on Sahara to complete */ + do { + /* lock queue while searching */ + os_lock_save_context(desc_queue_lock, lock_flags); + entry = sah_Find_With_State(SAH_STATE_ON_SAHARA); + os_unlock_restore_context(desc_queue_lock, lock_flags); + } while (entry != NULL); + + /* now we kill the clock so the control circuitry isn't sucking + * any power */ + { + struct clk *clk = clk_get(NULL, "sahara_clk"); + if (clk != ERR_PTR(ENOENT)) { + clk_disable(clk); + } + } +#endif + + return 0; +} + +/*! +******************************************************************************* +* Callback routine defined by the Linux Device Model / Dynamic Power management +* extension. It cleears a global flag to allow the driver to enter queued items +* into Sahara's DAR. +* +* It primes the mechanism to start depleting the queue +* +* @brief Resumes the driver +* +* @param dev contains device information +* @param level level of resumption +* +* @return 0 = success; failed otherwise +*/ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) +static int sah_dpm_resume(struct device *dev, uint32_t level) +#else +static int sah_dpm_resume(struct platform_device *dev) +#endif +{ + sah_Head_Desc *entry = NULL; + os_lock_context_t lock_flags; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) + switch (level) { + case RESUME_POWER_ON: + /* enable Sahara's clock */ + mxc_clks_enable(SAHARA2_CLK); + break; + + case RESUME_RESTORE_STATE: + break; + + case RESUME_ENABLE: + /* Disable dynamic power managment. This allows the driver to put + * entries into Sahara's DAR */ + sah_dpm_flag = FALSE; + + /* find a pending entry to prime the pump */ + os_lock_save_context(desc_queue_lock, lock_flags); + entry = sah_Find_With_State(SAH_STATE_PENDING); + if (entry != NULL) { + sah_Queue_Manager_Prime(entry); + } + os_unlock_restore_context(desc_queue_lock, lock_flags); + break; + } +#else + { + /* enable Sahara's clock */ + struct clk *clk = clk_get(NULL, "sahara_clk"); + + if (clk != ERR_PTR(ENOENT)) { + clk_enable(clk); + } + } + sah_dpm_flag = FALSE; + + /* find a pending entry to prime the pump */ + os_lock_save_context(desc_queue_lock, lock_flags); + entry = sah_Find_With_State(SAH_STATE_PENDING); + if (entry != NULL) { + sah_Queue_Manager_Prime(entry); + } + os_unlock_restore_context(desc_queue_lock, lock_flags); +#endif + return 0; +} + +#endif /* SAHARA_POWER_MANAGEMENT */ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/fsl_shw_auth.c +++ linux-2.6.28/drivers/mxc/security/sahara2/fsl_shw_auth.c @@ -0,0 +1,706 @@ +/* + * Copyright 2004-2009 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 + */ +/*! + * @file fsl_shw_auth.c + * + * This file contains the routines which do the combined encrypt+authentication + * functions. For now, only AES-CCM is supported. + */ + +#include "sahara.h" +#include "adaptor.h" +#include "sf_util.h" + +#ifdef __KERNEL__ +EXPORT_SYMBOL(fsl_shw_gen_encrypt); +EXPORT_SYMBOL(fsl_shw_auth_decrypt); +#endif + + +/*! Size of buffer to repetively sink useless CBC output */ +#define CBC_BUF_LEN 4096 + +/*! + * Compute the size, in bytes, of the encoded auth length + * + * @param l The actual associated data length + * + * @return The encoded length + */ +#define COMPUTE_NIST_AUTH_LEN_SIZE(l) \ +({ \ + unsigned val; \ + uint32_t len = l; \ + if (len == 0) { \ + val = 0; \ + } else if (len < 65280) { \ + val = 2; \ + } else { /* cannot handle >= 2^32 */ \ + val = 6; \ + } \ + val; \ +}) + +/*! + * Store the encoded Auth Length into the Auth Data + * + * @param l The actual Auth Length + * @param p Location to store encoding (must be uint8_t*) + * + * @return void + */ +#define STORE_NIST_AUTH_LEN(l, p) \ +{ \ + register uint32_t L = l; \ + if ((uint32_t)(l) < 65280) { \ + (p)[1] = L & 0xff; \ + L >>= 8; \ + (p)[0] = L & 0xff; \ + } else { /* cannot handle >= 2^32 */ \ + int i; \ + for (i = 5; i > 1; i--) { \ + (p)[i] = L & 0xff; \ + L >>= 8; \ + } \ + (p)[1] = 0xfe; /* Markers */ \ + (p)[0] = 0xff; \ + } \ +} + +#if defined (FSL_HAVE_SAHARA2) || defined (USE_S2_CCM_DECRYPT_CHAIN) \ + || defined (USE_S2_CCM_ENCRYPT_CHAIN) +/*! Buffer to repetively sink useless CBC output */ +static uint8_t cbc_buffer[CBC_BUF_LEN]; +#endif + +/*! + * Place to store useless output (while bumping CTR0 to CTR1, for instance. + * Must be maximum Symmetric block size + */ +static uint8_t garbage_output[16]; + +/*! + * Block of zeroes which is maximum Symmetric block size, used for + * initializing context register, etc. + */ +static uint8_t block_zeros[16] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/*! + * Append a descriptor chain which will compute CBC over the + * formatted associated data blocks. + * + * @param[in,out] link1 Where to append the new link + * @param[in,out] data_len Location of current/updated auth-only data length + * @param user_ctx Info for acquiring memory + * @param auth_ctx Location of block0 value + * @param auth_data Unformatted associated data + * @param auth_data_length Length in octets of @a auth_data + * @param[in,out] temp_buf Location of in-process data. + * + * @return A return code of type #fsl_shw_return_t. + */ +static inline fsl_shw_return_t process_assoc_from_nist_params(sah_Link ** link1, + uint32_t * + data_len, + fsl_shw_uco_t * + user_ctx, + fsl_shw_acco_t * + auth_ctx, + const uint8_t * + auth_data, + uint32_t + auth_data_length, + uint8_t ** + temp_buf) +{ + fsl_shw_return_t status; + uint32_t auth_size_length = + COMPUTE_NIST_AUTH_LEN_SIZE(auth_data_length); + uint32_t auth_pad_length = + auth_ctx->auth_info.CCM_ctx_info.block_size_bytes - + (auth_data_length + + auth_size_length) % + auth_ctx->auth_info.CCM_ctx_info.block_size_bytes; + + if (auth_pad_length == + auth_ctx->auth_info.CCM_ctx_info.block_size_bytes) { + auth_pad_length = 0; + } + + /* Put in Block0 */ + status = sah_Create_Link(user_ctx->mem_util, link1, + auth_ctx->auth_info.CCM_ctx_info.context, + auth_ctx->auth_info.CCM_ctx_info. + block_size_bytes, SAH_USES_LINK_DATA); + + if (auth_data_length != 0) { + if (status == FSL_RETURN_OK_S) { + /* Add on length preamble to auth data */ + STORE_NIST_AUTH_LEN(auth_data_length, *temp_buf); + status = sah_Append_Link(user_ctx->mem_util, *link1, + *temp_buf, auth_size_length, + SAH_OWNS_LINK_DATA); + *temp_buf += auth_size_length; /* 2, 6, or 10 bytes */ + } + + if (status == FSL_RETURN_OK_S) { + /* Add in auth data */ + status = sah_Append_Link(user_ctx->mem_util, *link1, + (uint8_t *) auth_data, + auth_data_length, + SAH_USES_LINK_DATA); + } + + if ((status == FSL_RETURN_OK_S) && (auth_pad_length > 0)) { + status = sah_Append_Link(user_ctx->mem_util, *link1, + block_zeros, auth_pad_length, + SAH_USES_LINK_DATA); + } + } + /* ... if auth_data_length != 0 */ + *data_len = auth_ctx->auth_info.CCM_ctx_info.block_size_bytes + + auth_data_length + auth_size_length + auth_pad_length; + + return status; +} /* end fn process_assoc_from_nist_params */ + +/*! + * Add a Descriptor which will process with CBC the NIST preamble data + * + * @param desc_chain Current chain + * @param user_ctx User's context + * @param auth_ctx Inf + * @pararm encrypt 0 => decrypt, non-zero => encrypt + * @param auth_data Additional auth data for this call + * @param auth_data_length Length in bytes of @a auth_data + * + * @return A return code of type #fsl_shw_return_t. + */ +static inline fsl_shw_return_t add_assoc_preamble(sah_Head_Desc ** desc_chain, + fsl_shw_uco_t * user_ctx, + fsl_shw_acco_t * auth_ctx, + int encrypt, + const uint8_t * auth_data, + uint32_t auth_data_length) +{ + uint8_t *temp_buf; + sah_Link *link1 = NULL; + sah_Link *link2 = NULL; + fsl_shw_return_t status = FSL_RETURN_OK_S; + uint32_t cbc_data_length = 0; + /* Assume AES */ + uint32_t header = SAH_HDR_SKHA_ENC_DEC; + uint32_t temp_buf_flag; + unsigned chain_s2 = 1; + +#if defined (FSL_HAVE_SAHARA4) && !defined (USE_S2_CCM_DECRYPT_CHAIN) + if (!encrypt) { + chain_s2 = 0; + } +#endif +#if defined (FSL_HAVE_SAHARA4) && !defined (USE_S2_CCM_ENCRYPT_CHAIN) + if (encrypt) { + chain_s2 = 0; + } +#endif + /* Grab a block big enough for multiple uses so that only one allocate + * request needs to be made. + */ + temp_buf = + user_ctx->mem_util->mu_malloc(user_ctx->mem_util->mu_ref, + 3 * + auth_ctx->auth_info.CCM_ctx_info. + block_size_bytes); + + if (temp_buf == NULL) { + status = FSL_RETURN_NO_RESOURCE_S; + goto out; + } + + if (auth_ctx->flags & FSL_ACCO_NIST_CCM) { + status = process_assoc_from_nist_params(&link1, + &cbc_data_length, + user_ctx, + auth_ctx, + auth_data, + auth_data_length, + &temp_buf); + if (status != FSL_RETURN_OK_S) { + goto out; + } + /* temp_buf has been referenced (and incremented). Only 'own' it + * once, at its first value. Since the nist routine called above + * bumps it... + */ + temp_buf_flag = SAH_USES_LINK_DATA; + } else { /* if NIST */ + status = sah_Create_Link(user_ctx->mem_util, &link1, + (uint8_t *) auth_data, + auth_data_length, SAH_USES_LINK_DATA); + if (status != FSL_RETURN_OK_S) { + goto out; + } + /* for next/first use of temp_buf */ + temp_buf_flag = SAH_OWNS_LINK_DATA; + cbc_data_length = auth_data_length; + } /* else not NIST */ + +#if defined (FSL_HAVE_SAHARA2) || defined (USE_S2_CCM_ENCRYPT_CHAIN) \ + || defined (USE_S2_CCM_DECRYPT_CHAIN) + + if (!chain_s2) { + header = SAH_HDR_SKHA_CBC_ICV + ^ sah_insert_skha_mode_cbc ^ sah_insert_skha_aux0 + ^ sah_insert_skha_encrypt; + } else { + /* + * Auth data links have been created. Now create link for the + * useless output of the CBC calculation. + */ + status = sah_Create_Link(user_ctx->mem_util, &link2, + temp_buf, + auth_ctx->auth_info.CCM_ctx_info. + block_size_bytes, + temp_buf_flag | SAH_OUTPUT_LINK); + if (status != FSL_RETURN_OK_S) { + goto out; + } + + temp_buf += auth_ctx->auth_info.CCM_ctx_info.block_size_bytes; + + cbc_data_length -= + auth_ctx->auth_info.CCM_ctx_info.block_size_bytes; + if (cbc_data_length != 0) { + while ((status == FSL_RETURN_OK_S) + && (cbc_data_length != 0)) { + uint32_t linklen = + (cbc_data_length > + CBC_BUF_LEN) ? CBC_BUF_LEN : + cbc_data_length; + + status = + sah_Append_Link(user_ctx->mem_util, link2, + cbc_buffer, linklen, + SAH_USES_LINK_DATA | + SAH_OUTPUT_LINK); + if (status != FSL_RETURN_OK_S) { + goto out; + } + cbc_data_length -= linklen; + } + } + } +#else + header = SAH_HDR_SKHA_CBC_ICV + ^ sah_insert_skha_mode_cbc ^ sah_insert_skha_aux0 + ^ sah_insert_skha_encrypt; +#endif + /* Crank through auth data */ + status = sah_Append_Desc(user_ctx->mem_util, desc_chain, + header, link1, link2); + + out: + if (status != FSL_RETURN_OK_S) { + if (link1 != NULL) { + sah_Destroy_Link(user_ctx->mem_util, link1); + } + if (link2 != NULL) { + sah_Destroy_Link(user_ctx->mem_util, link2); + } + } + + (void)encrypt; + return status; +} /* add_assoc_preamble() */ + +#if SUPPORT_SSL +/*! + * Generate an SSL value + * + * @param user_ctx Info for acquiring memory + * @param auth_ctx Info for CTR0, size of MAC + * @param cipher_key_info + * @param auth_key_info + * @param auth_data_length + * @param auth_data + * @param payload_length + * @param payload + * @param ct + * @param auth_value + * + * @return A return code of type #fsl_shw_return_t. + */ +static fsl_shw_return_t do_ssl_gen(fsl_shw_uco_t * user_ctx, + fsl_shw_acco_t * auth_ctx, + fsl_shw_sko_t * cipher_key_info, + fsl_shw_sko_t * auth_key_info, + uint32_t auth_data_length, + const uint8_t * auth_data, + uint32_t payload_length, + const uint8_t * payload, + uint8_t * ct, uint8_t * auth_value) +{ + SAH_SF_DCLS; + uint8_t *ptr1 = NULL; + + /* Assume one-shot init-finalize... no precomputes */ + header = SAH_HDR_MDHA_SET_MODE_MD_KEY ^ + sah_insert_mdha_algorithm[auth_ctx->auth_info.hash_ctx_info. + algorithm] ^ sah_insert_mdha_init ^ + sah_insert_mdha_ssl ^ sah_insert_mdha_pdata ^ + sah_insert_mdha_mac_full; + + /* set up hmac */ + DESC_IN_KEY(header, 0, NULL, auth_key_info); + + /* This is wrong -- need to find 16 extra bytes of data from + * somewhere */ + DESC_IN_OUT(SAH_HDR_MDHA_HASH, payload_length, payload, 1, auth_value); + + /* set up encrypt */ + header = SAH_HDR_SKHA_SET_MODE_IV_KEY + ^ sah_insert_skha_mode[auth_ctx->cipher_ctx_info.mode] + ^ sah_insert_skha_encrypt + ^ sah_insert_skha_algorithm[cipher_key_info->algorithm]; + + /* Honor 'no key parity checking' for DES and TDES */ + if ((cipher_key_info->flags & FSL_SKO_KEY_IGNORE_PARITY) && + ((cipher_key_info->algorithm == FSL_KEY_ALG_DES) || + (cipher_key_info->algorithm == FSL_KEY_ALG_TDES))) { + header ^= sah_insert_skha_no_key_parity; + } + + if (auth_ctx->cipher_ctx_info.mode == FSL_SYM_MODE_CTR) { + header ^= + sah_insert_skha_modulus[auth_ctx->cipher_ctx_info. + modulus_exp]; + } + + if ((auth_ctx->cipher_ctx_info.mode == FSL_SYM_MODE_ECB) + || (auth_ctx->cipher_ctx_info.flags & FSL_SYM_CTX_INIT)) { + ptr1 = block_zeros; + } else { + ptr1 = auth_ctx->cipher_ctx_info.context; + } + + DESC_IN_KEY(header, auth_ctx->cipher_ctx_info.block_size_bytes, ptr1, + cipher_key_info); + + /* This is wrong -- need to find 16 extra bytes of data from + * somewhere... + */ + if (payload_length != 0) { + DESC_IN_OUT(SAH_HDR_SKHA_ENC_DEC, + payload_length, payload, payload_length, ct); + } + + SAH_SF_EXECUTE(); + + out: + SAH_SF_DESC_CLEAN(); + + /* Eliminate compiler warnings until full implementation... */ + (void)auth_data; + (void)auth_data_length; + + return ret; +} /* do_ssl_gen() */ +#endif + +/*! + * @brief Generate a (CCM) auth code and encrypt the payload. + * + * This is a very complicated function. Seven (or eight) descriptors are + * required to perform a CCM calculation. + * + * First: Load CTR0 and key. + * + * Second: Run an octet of data through to bump to CTR1. (This could be + * done in software, but software will have to bump and later decrement - + * or copy and bump. + * + * Third: (in Virtio) Load a descriptor with data of zeros for CBC IV. + * + * Fourth: Run any (optional) "additional data" through the CBC-mode + * portion of the algorithm. + * + * Fifth: Run the payload through in CCM mode. + * + * Sixth: Extract the unencrypted MAC. + * + * Seventh: Load CTR0. + * + * Eighth: Encrypt the MAC. + * + * @param user_ctx The user's context + * @param auth_ctx Info on this Auth operation + * @param cipher_key_info Key to encrypt payload + * @param auth_key_info (unused - same key in CCM) + * @param auth_data_length Length in bytes of @a auth_data + * @param auth_data Any auth-only data + * @param payload_length Length in bytes of @a payload + * @param payload The data to encrypt + * @param[out] ct The location to store encrypted data + * @param[out] auth_value The location to store authentication code + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t fsl_shw_gen_encrypt(fsl_shw_uco_t * user_ctx, + fsl_shw_acco_t * auth_ctx, + fsl_shw_sko_t * cipher_key_info, + fsl_shw_sko_t * auth_key_info, + uint32_t auth_data_length, + const uint8_t * auth_data, + uint32_t payload_length, + const uint8_t * payload, + uint8_t * ct, uint8_t * auth_value) +{ + SAH_SF_DCLS; + + SAH_SF_USER_CHECK(); + + if (auth_ctx->mode == FSL_ACC_MODE_SSL) { +#if SUPPORT_SSL + ret = do_ssl_gen(user_ctx, auth_ctx, cipher_key_info, + auth_key_info, auth_data_length, auth_data, + payload_length, payload, ct, auth_value); +#else + ret = FSL_RETURN_BAD_MODE_S; +#endif + goto out; + } + + if (auth_ctx->mode != FSL_ACC_MODE_CCM) { + ret = FSL_RETURN_BAD_MODE_S; + goto out; + } + + /* Only support INIT and FINALIZE flags right now. */ + if ((auth_ctx->flags & (FSL_ACCO_CTX_INIT | FSL_ACCO_CTX_LOAD | + FSL_ACCO_CTX_SAVE | FSL_ACCO_CTX_FINALIZE)) + != (FSL_ACCO_CTX_INIT | FSL_ACCO_CTX_FINALIZE)) { + ret = FSL_RETURN_BAD_FLAG_S; + goto out; + } + + /* Load CTR0 and Key */ + header = (SAH_HDR_SKHA_SET_MODE_IV_KEY + ^ sah_insert_skha_mode_ctr + ^ sah_insert_skha_modulus_128 ^ sah_insert_skha_encrypt); + DESC_IN_KEY(header, + auth_ctx->cipher_ctx_info.block_size_bytes, + auth_ctx->cipher_ctx_info.context, cipher_key_info); + + /* Encrypt dummy data to bump to CTR1 */ + header = SAH_HDR_SKHA_ENC_DEC; + DESC_IN_OUT(header, auth_ctx->mac_length, garbage_output, + auth_ctx->mac_length, garbage_output); + +#if defined(FSL_HAVE_SAHARA2) || defined(USE_S2_CCM_ENCRYPT_CHAIN) +#ifndef NO_ZERO_IV_LOAD + header = (SAH_HDR_SKHA_SET_MODE_IV_KEY + ^ sah_insert_skha_encrypt ^ sah_insert_skha_mode_cbc); + DESC_IN_IN(header, + auth_ctx->auth_info.CCM_ctx_info.block_size_bytes, + block_zeros, 0, NULL); +#endif +#endif + + ret = add_assoc_preamble(&desc_chain, user_ctx, + auth_ctx, 1, auth_data, auth_data_length); + if (ret != FSL_RETURN_OK_S) { + goto out; + } + + /* Process the payload */ + header = (SAH_HDR_SKHA_SET_MODE_ENC_DEC + ^ sah_insert_skha_mode_ccm + ^ sah_insert_skha_modulus_128 ^ sah_insert_skha_encrypt); +#if defined (FSL_HAVE_SAHARA4) && !defined (USE_S2_CCM_ENCRYPT_CHAIN) + header ^= sah_insert_skha_aux0; +#endif + if (payload_length != 0) { + DESC_IN_OUT(header, payload_length, payload, payload_length, + ct); + } else { + DESC_IN_OUT(header, 0, NULL, 0, NULL); + } /* if payload_length */ + +#if defined (FSL_HAVE_SAHARA4) && !defined (USE_S2_CCM_ENCRYPT_CHAIN) + /* Pull out the CBC-MAC value. */ + DESC_OUT_OUT(SAH_HDR_SKHA_READ_CONTEXT_IV, 0, NULL, + auth_ctx->mac_length, auth_value); +#else + /* Pull out the unencrypted CBC-MAC value. */ + DESC_OUT_OUT(SAH_HDR_SKHA_READ_CONTEXT_IV, + 0, NULL, auth_ctx->mac_length, auth_ctx->unencrypted_mac); + + /* Now load CTR0 in, and encrypt the MAC */ + header = SAH_HDR_SKHA_SET_MODE_IV_KEY + ^ sah_insert_skha_encrypt + ^ sah_insert_skha_mode_ctr ^ sah_insert_skha_modulus_128; + DESC_IN_IN(header, + auth_ctx->cipher_ctx_info.block_size_bytes, + auth_ctx->cipher_ctx_info.context, 0, NULL); + + header = SAH_HDR_SKHA_ENC_DEC; /* Desc. #4 SKHA Enc/Dec */ + DESC_IN_OUT(header, + auth_ctx->mac_length, auth_ctx->unencrypted_mac, + auth_ctx->mac_length, auth_value); +#endif + + SAH_SF_EXECUTE(); + + out: + SAH_SF_DESC_CLEAN(); + + (void)auth_key_info; + return ret; +} /* fsl_shw_gen_encrypt() */ + +/*! + * @brief Authenticate and decrypt a (CCM) stream. + * + * @param user_ctx The user's context + * @param auth_ctx Info on this Auth operation + * @param cipher_key_info Key to encrypt payload + * @param auth_key_info (unused - same key in CCM) + * @param auth_data_length Length in bytes of @a auth_data + * @param auth_data Any auth-only data + * @param payload_length Length in bytes of @a payload + * @param ct The encrypted data + * @param auth_value The authentication code to validate + * @param[out] payload The location to store decrypted data + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t fsl_shw_auth_decrypt(fsl_shw_uco_t * user_ctx, + fsl_shw_acco_t * auth_ctx, + fsl_shw_sko_t * cipher_key_info, + fsl_shw_sko_t * auth_key_info, + uint32_t auth_data_length, + const uint8_t * auth_data, + uint32_t payload_length, + const uint8_t * ct, + const uint8_t * auth_value, + uint8_t * payload) +{ + SAH_SF_DCLS; +#if defined(FSL_HAVE_SAHARA2) || defined(USE_S2_CCM_DECRYPT_CHAIN) + uint8_t *calced_auth = NULL; + unsigned blocking = user_ctx->flags & FSL_UCO_BLOCKING_MODE; +#endif + + SAH_SF_USER_CHECK(); + + /* Only support CCM */ + if (auth_ctx->mode != FSL_ACC_MODE_CCM) { + ret = FSL_RETURN_BAD_MODE_S; + goto out; + } + /* Only support INIT and FINALIZE flags right now. */ + if ((auth_ctx->flags & (FSL_ACCO_CTX_INIT | FSL_ACCO_CTX_LOAD | + FSL_ACCO_CTX_SAVE | FSL_ACCO_CTX_FINALIZE)) + != (FSL_ACCO_CTX_INIT | FSL_ACCO_CTX_FINALIZE)) { + ret = FSL_RETURN_BAD_FLAG_S; + goto out; + } + + /* Load CTR0 and Key */ + header = SAH_HDR_SKHA_SET_MODE_IV_KEY + ^ sah_insert_skha_mode_ctr ^ sah_insert_skha_modulus_128; +#if defined (FSL_HAVE_SAHARA4) && !defined (USE_S2_CCM_DECRYPT_CHAIN) + header ^= sah_insert_skha_aux0; +#endif + DESC_IN_KEY(header, + auth_ctx->cipher_ctx_info.block_size_bytes, + auth_ctx->cipher_ctx_info.context, cipher_key_info); + + /* Decrypt the MAC which the user passed in */ + header = SAH_HDR_SKHA_ENC_DEC; + DESC_IN_OUT(header, + auth_ctx->mac_length, auth_value, + auth_ctx->mac_length, auth_ctx->unencrypted_mac); + +#if defined(FSL_HAVE_SAHARA2) || defined(USE_S2_CCM_DECRYPT_CHAIN) +#ifndef NO_ZERO_IV_LOAD + header = (SAH_HDR_SKHA_SET_MODE_IV_KEY + ^ sah_insert_skha_encrypt ^ sah_insert_skha_mode_cbc); + DESC_IN_IN(header, + auth_ctx->auth_info.CCM_ctx_info.block_size_bytes, + block_zeros, 0, NULL); +#endif +#endif + + ret = add_assoc_preamble(&desc_chain, user_ctx, + auth_ctx, 0, auth_data, auth_data_length); + if (ret != FSL_RETURN_OK_S) { + goto out; + } + + /* Process the payload */ + header = (SAH_HDR_SKHA_SET_MODE_ENC_DEC + ^ sah_insert_skha_mode_ccm ^ sah_insert_skha_modulus_128); +#if defined (FSL_HAVE_SAHARA4) && !defined (USE_S2_CCM_DECRYPT_CHAIN) + header ^= sah_insert_skha_aux0; +#endif + if (payload_length != 0) { + DESC_IN_OUT(header, payload_length, ct, payload_length, + payload); + } else { + DESC_IN_OUT(header, 0, NULL, 0, NULL); + } + +#if defined (FSL_HAVE_SAHARA2) || defined (USE_S2_CCM_DECRYPT_CHAIN) + /* Now pull CBC context (unencrypted MAC) out for comparison. */ + /* Need to allocate a place for it, to handle non-blocking mode + * when this stack frame will disappear! + */ + calced_auth = DESC_TEMP_ALLOC(auth_ctx->mac_length); + header = SAH_HDR_SKHA_READ_CONTEXT_IV; + DESC_OUT_OUT(header, 0, NULL, auth_ctx->mac_length, calced_auth); + if (!blocking) { + /* get_results will need this for comparison */ + desc_chain->out1_ptr = calced_auth; + desc_chain->out2_ptr = auth_ctx->unencrypted_mac; + desc_chain->out_len = auth_ctx->mac_length; + } +#endif + + SAH_SF_EXECUTE(); + +#if defined (FSL_HAVE_SAHARA2) || defined (USE_S2_CCM_DECRYPT_CHAIN) + if (blocking && (ret == FSL_RETURN_OK_S)) { + unsigned i; + /* Validate the auth code */ + for (i = 0; i < auth_ctx->mac_length; i++) { + if (calced_auth[i] != auth_ctx->unencrypted_mac[i]) { + ret = FSL_RETURN_AUTH_FAILED_S; + break; + } + } + } +#endif + + out: + SAH_SF_DESC_CLEAN(); +#if defined (FSL_HAVE_SAHARA2) || defined (USE_S2_CCM_DECRYPT_CHAIN) + DESC_TEMP_FREE(calced_auth); +#endif + + (void)auth_key_info; + return ret; +} /* fsl_shw_gen_decrypt() */ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/km_adaptor.c +++ linux-2.6.28/drivers/mxc/security/sahara2/km_adaptor.c @@ -0,0 +1,849 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! +* @file km_adaptor.c +* +* @brief The Adaptor component provides an interface to the +* driver for a kernel user. +*/ + +#include +#include +#include +#include +#include +#ifdef FSL_HAVE_SCC +#include +#elif defined (FSL_HAVE_SCC2) +#include +#endif + + +EXPORT_SYMBOL(adaptor_Exec_Descriptor_Chain); +EXPORT_SYMBOL(sah_register); +EXPORT_SYMBOL(sah_deregister); +EXPORT_SYMBOL(sah_get_results); +EXPORT_SYMBOL(fsl_shw_smalloc); +EXPORT_SYMBOL(fsl_shw_sfree); +EXPORT_SYMBOL(fsl_shw_sstatus); +EXPORT_SYMBOL(fsl_shw_diminish_perms); +EXPORT_SYMBOL(do_scc_encrypt_region); +EXPORT_SYMBOL(do_scc_decrypt_region); +EXPORT_SYMBOL(do_system_keystore_slot_alloc); +EXPORT_SYMBOL(do_system_keystore_slot_dealloc); +EXPORT_SYMBOL(do_system_keystore_slot_load); +EXPORT_SYMBOL(do_system_keystore_slot_read); +EXPORT_SYMBOL(do_system_keystore_slot_encrypt); +EXPORT_SYMBOL(do_system_keystore_slot_decrypt); + + +#if defined(DIAG_DRV_IF) || defined(DIAG_MEM) || defined(DIAG_ADAPTOR) +#include +#endif + +#if defined(DIAG_DRV_IF) || defined(DIAG_MEM) || defined(DIAG_ADAPTOR) +#define MAX_DUMP 16 + +#define DIAG_MSG_SIZE 300 +static char Diag_msg[DIAG_MSG_SIZE]; +#endif + +/* This is the wait queue to this mode of driver */ +DECLARE_WAIT_QUEUE_HEAD(Wait_queue_km); + +/*! This matches Sahara2 capabilities... */ +fsl_shw_pco_t sahara2_capabilities = { + 1, 3, /* api version number - major & minor */ + 1, 6, /* driver version number - major & minor */ + { + FSL_KEY_ALG_AES, + FSL_KEY_ALG_DES, + FSL_KEY_ALG_TDES, + FSL_KEY_ALG_ARC4}, + { + FSL_SYM_MODE_STREAM, + FSL_SYM_MODE_ECB, + FSL_SYM_MODE_CBC, + FSL_SYM_MODE_CTR}, + { + FSL_HASH_ALG_MD5, + FSL_HASH_ALG_SHA1, + FSL_HASH_ALG_SHA224, + FSL_HASH_ALG_SHA256}, + /* + * The following table must be set to handle all values of key algorithm + * and sym mode, and be in the correct order.. + */ + { /* Stream, ECB, CBC, CTR */ + {0, 0, 0, 0}, /* HMAC */ + {0, 1, 1, 1}, /* AES */ + {0, 1, 1, 0}, /* DES */ + {0, 1, 1, 0}, /* 3DES */ + {1, 0, 0, 0} /* ARC4 */ + }, + 0, 0, + 0, 0, 0, + {{0, 0}} +}; + +#ifdef DIAG_ADAPTOR +void km_Dump_Chain(const sah_Desc * chain); + +void km_Dump_Region(const char *prefix, const unsigned char *data, + unsigned length); + +static void km_Dump_Link(const char *prefix, const sah_Link * link); + +void km_Dump_Words(const char *prefix, const unsigned *data, unsigned length); +#endif + +/**** Memory routines ****/ + +static void *my_malloc(void *ref, size_t n) +{ + register void *mem; + +#ifndef DIAG_MEM_ERRORS + mem = os_alloc_memory(n, GFP_KERNEL); + +#else + { + uint32_t rand; + /* are we feeling lucky ? */ + os_get_random_bytes(&rand, sizeof(rand)); + if ((rand % DIAG_MEM_CONST) == 0) { + mem = 0; + } else { + mem = os_alloc_memory(n, GFP_ATOMIC); + } + } +#endif /* DIAG_MEM_ERRORS */ + +#ifdef DIAG_MEM + sprintf(Diag_msg, "API kmalloc: %p for %d\n", mem, n); + LOG_KDIAG(Diag_msg); +#endif + ref = 0; /* unused param warning */ + return mem; +} + +static sah_Head_Desc *my_alloc_head_desc(void *ref) +{ + register sah_Head_Desc *ptr; + +#ifndef DIAG_MEM_ERRORS + ptr = sah_Alloc_Head_Descriptor(); + +#else + { + uint32_t rand; + /* are we feeling lucky ? */ + os_get_random_bytes(&rand, sizeof(rand)); + if ((rand % DIAG_MEM_CONST) == 0) { + ptr = 0; + } else { + ptr = sah_Alloc_Head_Descriptor(); + } + } +#endif + ref = 0; + return ptr; +} + +static sah_Desc *my_alloc_desc(void *ref) +{ + register sah_Desc *ptr; + +#ifndef DIAG_MEM_ERRORS + ptr = sah_Alloc_Descriptor(); + +#else + { + uint32_t rand; + /* are we feeling lucky ? */ + os_get_random_bytes(&rand, sizeof(rand)); + if ((rand % DIAG_MEM_CONST) == 0) { + ptr = 0; + } else { + ptr = sah_Alloc_Descriptor(); + } + } +#endif + ref = 0; + return ptr; +} + +static sah_Link *my_alloc_link(void *ref) +{ + register sah_Link *ptr; + +#ifndef DIAG_MEM_ERRORS + ptr = sah_Alloc_Link(); + +#else + { + uint32_t rand; + /* are we feeling lucky ? */ + os_get_random_bytes(&rand, sizeof(rand)); + if ((rand % DIAG_MEM_CONST) == 0) { + ptr = 0; + } else { + ptr = sah_Alloc_Link(); + } + } +#endif + ref = 0; + return ptr; +} + +static void my_free(void *ref, void *ptr) +{ + ref = 0; /* unused param warning */ +#ifdef DIAG_MEM + sprintf(Diag_msg, "API kfree: %p\n", ptr); + LOG_KDIAG(Diag_msg); +#endif + os_free_memory(ptr); +} + +static void my_free_head_desc(void *ref, sah_Head_Desc * ptr) +{ + sah_Free_Head_Descriptor(ptr); +} + +static void my_free_desc(void *ref, sah_Desc * ptr) +{ + sah_Free_Descriptor(ptr); +} + +static void my_free_link(void *ref, sah_Link * ptr) +{ + sah_Free_Link(ptr); +} + +static void *my_memcpy(void *ref, void *dest, const void *src, size_t n) +{ + ref = 0; /* unused param warning */ + return memcpy(dest, src, n); +} + +static void *my_memset(void *ref, void *ptr, int ch, size_t n) +{ + ref = 0; /* unused param warning */ + return memset(ptr, ch, n); +} + +/*! Standard memory manipulation routines for kernel API. */ +static sah_Mem_Util std_kernelmode_mem_util = { + .mu_ref = 0, + .mu_malloc = my_malloc, + .mu_alloc_head_desc = my_alloc_head_desc, + .mu_alloc_desc = my_alloc_desc, + .mu_alloc_link = my_alloc_link, + .mu_free = my_free, + .mu_free_head_desc = my_free_head_desc, + .mu_free_desc = my_free_desc, + .mu_free_link = my_free_link, + .mu_memcpy = my_memcpy, + .mu_memset = my_memset +}; + +fsl_shw_return_t get_capabilities(fsl_shw_uco_t * user_ctx, + fsl_shw_pco_t * capabilities) +{ + scc_config_t *scc_capabilities; + + /* Fill in the Sahara2 capabilities. */ + memcpy(capabilities, &sahara2_capabilities, sizeof(fsl_shw_pco_t)); + + /* Fill in the SCC portion of the capabilities object */ + scc_capabilities = scc_get_configuration(); + capabilities->scc_driver_major = scc_capabilities->driver_major_version; + capabilities->scc_driver_minor = scc_capabilities->driver_minor_version; + capabilities->scm_version = scc_capabilities->scm_version; + capabilities->smn_version = scc_capabilities->smn_version; + capabilities->block_size_bytes = scc_capabilities->block_size_bytes; + +#ifdef FSL_HAVE_SCC + capabilities->scc_info.black_ram_size_blocks = + scc_capabilities->black_ram_size_blocks; + capabilities->scc_info.red_ram_size_blocks = + scc_capabilities->red_ram_size_blocks; +#elif defined(FSL_HAVE_SCC2) + capabilities->scc2_info.partition_size_bytes = + scc_capabilities->partition_size_bytes; + capabilities->scc2_info.partition_count = + scc_capabilities->partition_count; +#endif + + return FSL_RETURN_OK_S; +} + +/*! + * Sends a request to register this user + * + * @brief Sends a request to register this user + * + * @param[in,out] user_ctx part of the structure contains input parameters and + * part is filled in by the driver + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t sah_register(fsl_shw_uco_t * user_ctx) +{ + fsl_shw_return_t status; + + /* this field is used in user mode to indicate a file open has occured. + * it is used here, in kernel mode, to indicate that the uco is registered + */ + user_ctx->sahara_openfd = 0; /* set to 'registered' */ + user_ctx->mem_util = &std_kernelmode_mem_util; + + /* check that uco is valid */ + status = sah_validate_uco(user_ctx); + + /* If life is good, register this user */ + if (status == FSL_RETURN_OK_S) { + status = sah_handle_registration(user_ctx); + } + + if (status != FSL_RETURN_OK_S) { + user_ctx->sahara_openfd = -1; /* set to 'not registered' */ + } + + return status; +} + +/*! + * Sends a request to deregister this user + * + * @brief Sends a request to deregister this user + * + * @param[in,out] user_ctx Info on user being deregistered. + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t sah_deregister(fsl_shw_uco_t * user_ctx) +{ + fsl_shw_return_t status = FSL_RETURN_OK_S; + + if (user_ctx->sahara_openfd == 0) { + status = sah_handle_deregistration(user_ctx); + user_ctx->sahara_openfd = -1; /* set to 'no registered */ + } + + return status; +} + +/*! + * Sends a request to get results for this user + * + * @brief Sends a request to get results for this user + * + * @param[in,out] arg Pointer to structure to collect results + * @param uco User's context + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t sah_get_results(sah_results * arg, fsl_shw_uco_t * uco) +{ + fsl_shw_return_t code = sah_get_results_from_pool(uco, arg); + + if ((code == FSL_RETURN_OK_S) && (arg->actual != 0)) { + sah_Postprocess_Results(uco, arg); + } + + return code; +} + +/*! + * This function writes the Descriptor Chain to the kernel driver. + * + * @brief Writes the Descriptor Chain to the kernel driver. + * + * @param dar A pointer to a Descriptor Chain of type sah_Head_Desc + * @param uco The user context object + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t adaptor_Exec_Descriptor_Chain(sah_Head_Desc * dar, + fsl_shw_uco_t * uco) +{ + sah_Head_Desc *kernel_space_desc = NULL; + fsl_shw_return_t code = FSL_RETURN_OK_S; + int os_error_code = 0; + unsigned blocking_mode = dar->uco_flags & FSL_UCO_BLOCKING_MODE; + +#ifdef DIAG_ADAPTOR + km_Dump_Chain(&dar->desc); +#endif + + dar->user_info = uco; + dar->user_desc = dar; + + /* This code has been shamelessly copied from sah_driver_interface.c */ + /* It needs to be moved somewhere common ... */ + kernel_space_desc = sah_Physicalise_Descriptors(dar); + + if (kernel_space_desc == NULL) { + /* We may have failed due to a -EFAULT as well, but we will return + * -ENOMEM since either way it is a memory related failure. */ + code = FSL_RETURN_NO_RESOURCE_S; +#ifdef DIAG_DRV_IF + LOG_KDIAG("sah_Physicalise_Descriptors() failed\n"); +#endif + } else { + if (blocking_mode) { +#ifdef SAHARA_POLL_MODE + os_error_code = sah_Handle_Poll(dar); +#else + os_error_code = sah_blocking_mode(dar); +#endif + if (os_error_code != 0) { + code = FSL_RETURN_ERROR_S; + } else { /* status of actual operation */ + code = dar->result; + } + } else { +#ifdef SAHARA_POLL_MODE + sah_Handle_Poll(dar); +#else + /* just put someting in the DAR */ + sah_Queue_Manager_Append_Entry(dar); +#endif /* SAHARA_POLL_MODE */ + } + } + + return code; +} + + +/* System keystore context, defined in sah_driver_interface.c */ +extern fsl_shw_kso_t system_keystore; + +fsl_shw_return_t do_system_keystore_slot_alloc(fsl_shw_uco_t * user_ctx, + uint32_t key_length, + uint64_t ownerid, + uint32_t * slot) +{ + (void)user_ctx; + return keystore_slot_alloc(&system_keystore, key_length, ownerid, slot); +} + +fsl_shw_return_t do_system_keystore_slot_dealloc(fsl_shw_uco_t * user_ctx, + uint64_t ownerid, + uint32_t slot) +{ + (void)user_ctx; + return keystore_slot_dealloc(&system_keystore, ownerid, slot); +} + +fsl_shw_return_t do_system_keystore_slot_load(fsl_shw_uco_t * user_ctx, + uint64_t ownerid, + uint32_t slot, + const uint8_t * key, + uint32_t key_length) +{ + (void)user_ctx; + return keystore_slot_load(&system_keystore, ownerid, slot, + (void *)key, key_length); +} + +fsl_shw_return_t do_system_keystore_slot_read(fsl_shw_uco_t * user_ctx, + uint64_t ownerid, + uint32_t slot, + uint32_t key_length, + const uint8_t * key) +{ + (void)user_ctx; + return keystore_slot_read(&system_keystore, ownerid, slot, + key_length, (void *)key); +} + +fsl_shw_return_t do_system_keystore_slot_encrypt(fsl_shw_uco_t * user_ctx, + uint64_t ownerid, + uint32_t slot, + uint32_t key_length, + uint8_t * black_data) +{ + (void)user_ctx; + return keystore_slot_encrypt(NULL, &system_keystore, ownerid, + slot, key_length, black_data); +} + +fsl_shw_return_t do_system_keystore_slot_decrypt(fsl_shw_uco_t * user_ctx, + uint64_t ownerid, + uint32_t slot, + uint32_t key_length, + const uint8_t * black_data) +{ + (void)user_ctx; + return keystore_slot_decrypt(NULL, &system_keystore, ownerid, + slot, key_length, black_data); +} + +void *fsl_shw_smalloc(fsl_shw_uco_t * user_ctx, + uint32_t size, const uint8_t * UMID, uint32_t permissions) +{ +#ifdef FSL_HAVE_SCC2 + int part_no; + void *part_base; + uint32_t part_phys; + scc_config_t *scc_configuration; + + /* Check that the memory size requested is correct */ + scc_configuration = scc_get_configuration(); + if (size != scc_configuration->partition_size_bytes) { + return NULL; + } + + /* Attempt to grab a partition. */ + if (scc_allocate_partition(0, &part_no, &part_base, &part_phys) + != SCC_RET_OK) { + return NULL; + } + printk(KERN_ALERT "In fsh_shw_smalloc (km): partition_base:%p " + "partition_base_phys: %p\n", part_base, (void *)part_phys); + + /* these bits should be in a separate function */ + printk(KERN_ALERT "writing UMID and MAP to secure the partition\n"); + + scc_engage_partition(part_base, UMID, permissions); + + (void)user_ctx; /* unused param warning */ + + return part_base; +#else /* FSL_HAVE_SCC2 */ + (void)user_ctx; + (void)size; + (void)UMID; + (void)permissions; + return NULL; +#endif /* FSL_HAVE_SCC2 */ + +} + +fsl_shw_return_t fsl_shw_sfree(fsl_shw_uco_t * user_ctx, void *address) +{ + (void)user_ctx; + +#ifdef FSL_HAVE_SCC2 + if (scc_release_partition(address) == SCC_RET_OK) { + return FSL_RETURN_OK_S; + } +#endif + + return FSL_RETURN_ERROR_S; +} + +fsl_shw_return_t fsl_shw_sstatus(fsl_shw_uco_t * user_ctx, + void *address, + fsl_shw_partition_status_t * status) +{ + (void)user_ctx; + +#ifdef FSL_HAVE_SCC2 + *status = scc_partition_status(address); + return FSL_RETURN_OK_S; +#endif + + return FSL_RETURN_ERROR_S; +} + +/* Diminish permissions on some secure memory */ +fsl_shw_return_t fsl_shw_diminish_perms(fsl_shw_uco_t * user_ctx, + void *address, uint32_t permissions) +{ + + (void)user_ctx; /* unused parameter warning */ + +#ifdef FSL_HAVE_SCC2 + if (scc_diminish_permissions(address, permissions) == SCC_RET_OK) { + return FSL_RETURN_OK_S; + } +#endif + return FSL_RETURN_ERROR_S; +} + +/* + * partition_base - physical address of the partition + * offset - offset, in blocks, of the data from the start of the partition + * length - length, in bytes, of the data to be encrypted (multiple of 4) + * black_data - virtual address that the encrypted data should be stored at + * Note that this virtual address must be translatable using the __virt_to_phys + * macro; ie, it can't be a specially mapped address. To do encryption with those + * addresses, use the scc_encrypt_region function directly. This is to make + * this function compatible with the user mode declaration, which does not know + * the physical addresses of the data it is using. + */ +fsl_shw_return_t +do_scc_encrypt_region(fsl_shw_uco_t * user_ctx, + void *partition_base, uint32_t offset_bytes, + uint32_t byte_count, uint8_t * black_data, + uint32_t * IV, fsl_shw_cypher_mode_t cypher_mode) +{ + scc_return_t scc_ret; + fsl_shw_return_t retval = FSL_RETURN_ERROR_S; + +#ifdef FSL_HAVE_SCC2 + +#ifdef DIAG_ADAPTOR + uint32_t *owner_32 = (uint32_t *) & (owner_id); + + LOG_KDIAG_ARGS + ("partition base: %p, offset: %i, count: %i, black data: %p\n", + partition_base, offset_bytes, byte_count, (void *)black_data); +#endif + (void)user_ctx; + + os_cache_flush_range(black_data, byte_count); + + scc_ret = + scc_encrypt_region((uint32_t) partition_base, offset_bytes, + byte_count, __virt_to_phys(black_data), IV, + cypher_mode); + + if (scc_ret == SCC_RET_OK) { + retval = FSL_RETURN_OK_S; + } else { + retval = FSL_RETURN_ERROR_S; + } + + /* The SCC2 DMA engine should have written to the black ram, so we need to + * invalidate that region of memory. Note that the red ram is not an + * because it is mapped with the cache disabled. + */ + os_cache_inv_range(black_data, byte_count); + +#else + (void)scc_ret; +#endif /* FSL_HAVE_SCC2 */ + + return retval; +} + +/*! + * Call the proper function to decrypt a region of encrypted secure memory + * + * @brief + * + * @param user_ctx User context of the partition owner (NULL in kernel) + * @param partition_base Base address (physical) of the partition + * @param offset_bytes Offset from base address that the decrypted data + * shall be placed + * @param byte_count Length of the message (bytes) + * @param black_data Pointer to where the encrypted data is stored + * @param owner_id + * + * @return status + */ + +fsl_shw_return_t +do_scc_decrypt_region(fsl_shw_uco_t * user_ctx, + void *partition_base, uint32_t offset_bytes, + uint32_t byte_count, const uint8_t * black_data, + uint32_t * IV, fsl_shw_cypher_mode_t cypher_mode) +{ + scc_return_t scc_ret; + fsl_shw_return_t retval = FSL_RETURN_ERROR_S; + +#ifdef FSL_HAVE_SCC2 + +#ifdef DIAG_ADAPTOR + uint32_t *owner_32 = (uint32_t *) & (owner_id); + + LOG_KDIAG_ARGS + ("partition base: %p, offset: %i, count: %i, black data: %p\n", + partition_base, offset_bytes, byte_count, (void *)black_data); +#endif + + (void)user_ctx; + + /* The SCC2 DMA engine will be reading from the black ram, so we need to + * make sure that the data is pushed out of the cache. Note that the red + * ram is not an issue because it is mapped with the cache disabled. + */ + os_cache_flush_range(black_data, byte_count); + + scc_ret = + scc_decrypt_region((uint32_t) partition_base, offset_bytes, + byte_count, + (uint8_t *) __virt_to_phys(black_data), IV, + cypher_mode); + + if (scc_ret == SCC_RET_OK) { + retval = FSL_RETURN_OK_S; + } else { + retval = FSL_RETURN_ERROR_S; + } + +#else + (void)scc_ret; +#endif /* FSL_HAVE_SCC2 */ + + return retval; +} + +#ifdef DIAG_ADAPTOR +/*! + * Dump chain of descriptors to the log. + * + * @brief Dump descriptor chain + * + * @param chain Kernel virtual address of start of chain of descriptors + * + * @return void + */ +void km_Dump_Chain(const sah_Desc * chain) +{ + while (chain != NULL) { + km_Dump_Words("Desc", (unsigned *)chain, + 6 /*sizeof(*chain)/sizeof(unsigned) */ ); + /* place this definition elsewhere */ + if (chain->ptr1) { + if (chain->header & SAH_HDR_LLO) { + km_Dump_Region(" Data1", chain->ptr1, + chain->len1); + } else { + km_Dump_Link(" Link1", chain->ptr1); + } + } + if (chain->ptr2) { + if (chain->header & SAH_HDR_LLO) { + km_Dump_Region(" Data2", chain->ptr2, + chain->len2); + } else { + km_Dump_Link(" Link2", chain->ptr2); + } + } + + chain = chain->next; + } +} + +/*! + * Dump chain of links to the log. + * + * @brief Dump chain of links + * + * @param prefix Text to put in front of dumped data + * @param link Kernel virtual address of start of chain of links + * + * @return void + */ +static void km_Dump_Link(const char *prefix, const sah_Link * link) +{ + while (link != NULL) { + km_Dump_Words(prefix, (unsigned *)link, + 3 /* # words in h/w link */ ); + if (link->flags & SAH_STORED_KEY_INFO) { +#ifdef CAN_DUMP_SCC_DATA + uint32_t len; +#endif + +#ifdef CAN_DUMP_SCC_DATA + { + char buf[50]; + + scc_get_slot_info(link->ownerid, link->slot, (uint32_t *) & link->data, /* RED key address */ + &len); /* key length */ + sprintf(buf, " SCC slot %d: ", link->slot); + km_Dump_Words(buf, + (void *)IO_ADDRESS((uint32_t) + link->data), + link->len / 4); + } +#else + sprintf(Diag_msg, " SCC slot %d", link->slot); + LOG_KDIAG(Diag_msg); +#endif + } else if (link->data != NULL) { + km_Dump_Region(" Data", link->data, link->len); + } + + link = link->next; + } +} + +/*! + * Dump given region of data to the log. + * + * @brief Dump data + * + * @param prefix Text to put in front of dumped data + * @param data Kernel virtual address of start of region to dump + * @param length Amount of data to dump + * + * @return void +*/ +void km_Dump_Region(const char *prefix, const unsigned char *data, + unsigned length) +{ + unsigned count; + char *output; + unsigned data_len; + + sprintf(Diag_msg, "%s (%08X,%u):", prefix, (uint32_t) data, length); + + /* Restrict amount of data to dump */ + if (length > MAX_DUMP) { + data_len = MAX_DUMP; + } else { + data_len = length; + } + + /* We've already printed some text in output buffer, skip over it */ + output = Diag_msg + strlen(Diag_msg); + + for (count = 0; count < data_len; count++) { + if (count % 4 == 0) { + *output++ = ' '; + } + sprintf(output, "%02X", *data++); + output += 2; + } + + LOG_KDIAG(Diag_msg); +} + +/*! + * Dump given wors of data to the log. + * + * @brief Dump data + * + * @param prefix Text to put in front of dumped data + * @param data Kernel virtual address of start of region to dump + * @param word_count Amount of data to dump + * + * @return void +*/ +void km_Dump_Words(const char *prefix, const unsigned *data, + unsigned word_count) +{ + char *output; + + sprintf(Diag_msg, "%s (%08X,%uw): ", prefix, (uint32_t) data, + word_count); + + /* We've already printed some text in output buffer, skip over it */ + output = Diag_msg + strlen(Diag_msg); + + while (word_count--) { + sprintf(output, "%08X ", *data++); + output += 9; + } + + LOG_KDIAG(Diag_msg); +} +#endif --- linux-2.6.28.orig/drivers/mxc/security/sahara2/sah_driver_interface.c +++ linux-2.6.28/drivers/mxc/security/sahara2/sah_driver_interface.c @@ -0,0 +1,2162 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! +* @file sah_driver_interface.c +* +* @brief Provides a Linux Kernel Module interface to the SAHARA h/w device. +* +*/ + +/* SAHARA Includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef FSL_HAVE_SCC +#include +#else +#include +#endif + +#ifdef DIAG_DRV_IF +#include +#endif + +#if defined(CONFIG_DEVFS_FS) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) +#include +#else +#include +#endif + +#include + +#ifdef PERF_TEST +#define interruptible_sleep_on(x) sah_Handle_Interrupt() +#endif + +#define TEST_MODE_OFF 1 +#define TEST_MODE_ON 2 + +/*! Version register on first deployments */ +#define SAHARA_VERSION2 2 +/*! Version register on MX27 */ +#define SAHARA_VERSION3 3 +/*! Version register on MXC92323 */ +#define SAHARA_VERSION4 4 + +/****************************************************************************** +* Module function declarations +******************************************************************************/ + +OS_DEV_INIT_DCL(sah_init); +OS_DEV_SHUTDOWN_DCL(sah_cleanup); +OS_DEV_OPEN_DCL(sah_open); +OS_DEV_CLOSE_DCL(sah_release); +OS_DEV_IOCTL_DCL(sah_ioctl); +OS_DEV_MMAP_DCL(sah_mmap); + +static os_error_code sah_handle_get_capabilities(fsl_shw_uco_t* user_ctx, + uint32_t info); + +static void sah_user_callback(fsl_shw_uco_t * user_ctx); +static os_error_code sah_handle_scc_sfree(fsl_shw_uco_t* user_ctx, + uint32_t info); +static os_error_code sah_handle_scc_sstatus(fsl_shw_uco_t* user_ctx, + uint32_t info); +static os_error_code sah_handle_scc_drop_perms(fsl_shw_uco_t* user_ctx, + uint32_t info); +static os_error_code sah_handle_scc_encrypt(fsl_shw_uco_t* user_ctx, + uint32_t info); +static os_error_code sah_handle_scc_decrypt(fsl_shw_uco_t* user_ctx, + uint32_t info); + +#ifdef FSL_HAVE_SCC2 +static fsl_shw_return_t register_user_partition(fsl_shw_uco_t * user_ctx, + uint32_t user_base, + void *kernel_base); +static fsl_shw_return_t deregister_user_partition(fsl_shw_uco_t * user_ctx, + uint32_t user_base); +#endif + +static os_error_code sah_handle_sk_slot_alloc(uint32_t info); +static os_error_code sah_handle_sk_slot_dealloc(uint32_t info); +static os_error_code sah_handle_sk_slot_load(uint32_t info); +static os_error_code sah_handle_sk_slot_read(uint32_t info); +static os_error_code sah_handle_sk_slot_decrypt(uint32_t info); +static os_error_code sah_handle_sk_slot_encrypt(uint32_t info); + +/*! Boolean flag for whether interrupt handler needs to be released on exit */ +static unsigned interrupt_registered; + +static int handle_sah_ioctl_dar(fsl_shw_uco_t * filp, uint32_t user_space_desc); + +#if !defined(CONFIG_DEVFS_FS) || (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +static int sah_read_procfs(char *buf, + char **start, + off_t offset, int count, int *eof, void *data); + +static int sah_write_procfs(struct file *file, const char __user * buffer, + unsigned long count, void *data); +#endif + +#if defined(CONFIG_DEVFS_FS) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) + +/* This is a handle to the sahara DEVFS entry. */ +static devfs_handle_t Sahara_devfs_handle; + +#else + +/* Major number assigned to our device driver */ +static int Major; + +/* This is a handle to the sahara PROCFS entry */ +static struct proc_dir_entry *Sahara_procfs_handle; + +#endif + +uint32_t sah_hw_version; + +/* This is the wait queue to this driver. Linux declaration. */ +DECLARE_WAIT_QUEUE_HEAD(Wait_queue); + +/* This is a global variable that is used to track how many times the device + * has been opened simultaneously. */ +#ifdef DIAG_DRV_IF +static int Device_in_use = 0; +#endif + +/* This is the system keystore object */ +fsl_shw_kso_t system_keystore; + +/*! + * OS-dependent handle used for registering user interface of a driver. + */ +static os_driver_reg_t reg_handle; + +#ifdef DIAG_DRV_IF +/* This is for sprintf() to use when constructing output. */ +#define DIAG_MSG_SIZE 1024 +static char Diag_msg[DIAG_MSG_SIZE]; +#endif + +/*! +******************************************************************************* +* This function gets called when the module is inserted (insmod) into the +* running kernel. +* +* @brief SAHARA device initialisation function. +* +* @return 0 on success +* @return -EBUSY if the device or proc file entry cannot be created. +* @return OS_ERROR_NO_MEMORY_S if kernel memory could not be allocated. +* @return OS_ERROR_FAIL_S if initialisation of proc entry failed +*/ +OS_DEV_INIT(sah_init) +{ + /* Status variable */ + int os_error_code = 0; + + interrupt_registered = 0; + + /* Enable the SAHARA Clocks */ +#ifdef DIAG_DRV_IF + LOG_KDIAG("SAHARA : Enabling the IPG and AHB clocks\n") +#endif /*DIAG_DRV_IF */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) + mxc_clks_enable(SAHARA2_CLK); +#else + { + struct clk *clk = clk_get(NULL, "sahara_clk"); + if (clk != ERR_PTR(ENOENT)) { + clk_enable(clk); + } + } +#endif + + /* Check for SPBA need */ +#if defined(CONFIG_ARCH_MXC91231) || defined(CONFIG_ARCH_MXC91321) + /* This needs to be a PLATFORM abstraction */ + if (spba_take_ownership(SPBA_SAHARA, SPBA_MASTER_A)) { +#ifdef DIAG_DRV_IF + LOG_KDIAG("Sahara driver could not take ownership of Sahara\n"); +#endif + os_error_code = OS_ERROR_FAIL_S; + } +#endif /* SPBA */ + + if (os_error_code == OS_ERROR_OK_S) { + sah_hw_version = sah_HW_Read_Version(); + os_printk("Sahara HW Version is 0x%08x\n", sah_hw_version); + + /* verify code and hardware are version compatible */ + if ((sah_hw_version != SAHARA_VERSION2) + && (sah_hw_version != SAHARA_VERSION3)) { + if (((sah_hw_version >> 8) & 0xff) != SAHARA_VERSION4) { + os_printk + ("Sahara HW Version was not expected value.\n"); + os_error_code = OS_ERROR_FAIL_S; + } + } + } + + if (os_error_code == OS_ERROR_OK_S) { +#ifdef DIAG_DRV_IF + LOG_KDIAG("Calling sah_Init_Mem_Map to initialise " + "memory subsystem."); +#endif + /* Do any memory-routine initialization */ + os_error_code = sah_Init_Mem_Map(); + } + + if (os_error_code == OS_ERROR_OK_S) { +#ifdef DIAG_DRV_IF + LOG_KDIAG("Calling sah_HW_Reset() to Initialise the Hardware."); +#endif + /* Initialise the hardware */ + os_error_code = sah_HW_Reset(); + if (os_error_code != OS_ERROR_OK_S) { + os_printk + ("sah_HW_Reset() failed to Initialise the Hardware.\n"); + } + + } + + if (os_error_code == OS_ERROR_OK_S) { +#if defined(CONFIG_DEVFS_FS) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) + /* Register the DEVFS entry */ + Sahara_devfs_handle = devfs_register(NULL, + SAHARA_DEVICE_SHORT, + DEVFS_FL_AUTO_DEVNUM, + 0, 0, + SAHARA_DEVICE_MODE, + &Fops, NULL); + if (Sahara_devfs_handle == NULL) { +#ifdef DIAG_DRV_IF + LOG_KDIAG + ("Registering the DEVFS character device failed."); +#endif /* DIAG_DRV_IF */ + os_error_code = -EBUSY; + } +#else /* CONFIG_DEVFS_FS */ + /* Create the PROCFS entry. This is used to report the assigned device + * major number back to user-space. */ +#if 1 + Sahara_procfs_handle = create_proc_entry(SAHARA_DEVICE_SHORT, 0700, /* default mode */ + NULL); /* parent dir */ + if (Sahara_procfs_handle == NULL) { +#ifdef DIAG_DRV_IF + LOG_KDIAG("Registering the PROCFS interface failed."); +#endif /* DIAG_DRV_IF */ + os_error_code = OS_ERROR_FAIL_S; + } else { + Sahara_procfs_handle->nlink = 1; + Sahara_procfs_handle->data = 0; + Sahara_procfs_handle->read_proc = sah_read_procfs; + Sahara_procfs_handle->write_proc = sah_write_procfs; + } +#endif /* #if 1 */ + } + + if (os_error_code == OS_ERROR_OK_S) { +#ifdef DIAG_DRV_IF + LOG_KDIAG + ("Calling sah_Queue_Manager_Init() to Initialise the Queue " + "Manager."); +#endif + /* Initialise the Queue Manager */ + if (sah_Queue_Manager_Init() != FSL_RETURN_OK_S) { + os_error_code = -ENOMEM; + } + } +#ifndef SAHARA_POLL_MODE + if (os_error_code == OS_ERROR_OK_S) { +#ifdef DIAG_DRV_IF + LOG_KDIAG("Calling sah_Intr_Init() to Initialise the Interrupt " + "Handler."); +#endif + /* Initialise the Interrupt Handler */ + os_error_code = sah_Intr_Init(&Wait_queue); + if (os_error_code == OS_ERROR_OK_S) { + interrupt_registered = 1; + } + } +#endif /* ifndef SAHARA_POLL_MODE */ + +#ifdef SAHARA_POWER_MANAGEMENT + if (os_error_code == OS_ERROR_OK_S) { + /* set up dynamic power management (dmp) */ + os_error_code = sah_dpm_init(); + } +#endif + + if (os_error_code == OS_ERROR_OK_S) { + os_driver_init_registration(reg_handle); + os_driver_add_registration(reg_handle, OS_FN_OPEN, + OS_DEV_OPEN_REF(sah_open)); + os_driver_add_registration(reg_handle, OS_FN_IOCTL, + OS_DEV_IOCTL_REF(sah_ioctl)); + os_driver_add_registration(reg_handle, OS_FN_CLOSE, + OS_DEV_CLOSE_REF(sah_release)); + os_driver_add_registration(reg_handle, OS_FN_MMAP, + OS_DEV_MMAP_REF(sah_mmap)); + + os_error_code = + os_driver_complete_registration(reg_handle, Major, + "sahara"); + + if (os_error_code < OS_ERROR_OK_S) { +#ifdef DIAG_DRV_IF + snprintf(Diag_msg, DIAG_MSG_SIZE, + "Registering the regular " + "character device failed with error code: %d\n", + os_error_code); + LOG_KDIAG(Diag_msg); +#endif + } + } +#endif /* CONFIG_DEVFS_FS */ + + if (os_error_code == OS_ERROR_OK_S) { + /* set up the system keystore, using the default keystore handler */ + fsl_shw_init_keystore_default(&system_keystore); + + if (fsl_shw_establish_keystore(NULL, &system_keystore) + == FSL_RETURN_OK_S) { + os_error_code = OS_ERROR_OK_S; + } else { + os_error_code = OS_ERROR_FAIL_S; + } + + if (os_error_code != OS_ERROR_OK_S) { +#ifdef DIAG_DRV_IF + snprintf(Diag_msg, DIAG_MSG_SIZE, + "Registering the system keystore " + "failed with error code: %d\n", os_error_code); + LOG_KDIAG(Diag_msg); +#endif + } + } + + if (os_error_code != OS_ERROR_OK_S) { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) + cleanup_module(); +#else + sah_cleanup(); +#endif + } +#ifdef DIAG_DRV_IF + else { + LOG_KDIAG_ARGS("Sahara major node is %d\n", Major); + } +#endif + + os_dev_init_return(os_error_code); +} + +/*! +******************************************************************************* +* This function gets called when the module is removed (rmmod) from the running +* kernel. +* +* @brief SAHARA device clean-up function. +* +* @return void +*/ +OS_DEV_SHUTDOWN(sah_cleanup) +{ + int ret_val = 0; + + printk(KERN_ALERT "Sahara going into cleanup\n"); + + /* clear out the system keystore */ + fsl_shw_release_keystore(NULL, &system_keystore); + + /* Unregister the device */ +#if defined(CONFIG_DEVFS_FS) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) + devfs_unregister(Sahara_devfs_handle); +#else + + if (Sahara_procfs_handle != NULL) { + remove_proc_entry(SAHARA_DEVICE_SHORT, NULL); + } + + if (Major >= 0) { + ret_val = os_driver_remove_registration(reg_handle); + } +#ifdef DIAG_DRV_IF + if (ret_val < 0) { + snprintf(Diag_msg, DIAG_MSG_SIZE, "Error while attempting to " + "unregister the device: %d\n", ret_val); + LOG_KDIAG(Diag_msg); + } +#endif + +#endif /* CONFIG_DEVFS_FS */ + sah_Queue_Manager_Close(); + +#ifndef SAHARA_POLL_MODE + if (interrupt_registered) { + sah_Intr_Release(); + interrupt_registered = 0; + } +#endif + sah_Stop_Mem_Map(); +#ifdef SAHARA_POWER_MANAGEMENT + sah_dpm_close(); +#endif + +#ifdef DIAG_DRV_IF + LOG_KDIAG("SAHARA : Disabling the clocks\n") +#endif /* DIAG_DRV_IF */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) + mxc_clks_disable(SAHARA2_CLK); +#else + { + struct clk *clk = clk_get(NULL, "sahara_clk"); + if (clk != ERR_PTR(ENOENT)) { + clk_disable(clk); + } + } +#endif + + os_dev_shutdown_return(OS_ERROR_OK_S); +} + +/*! +******************************************************************************* +* This function simply increments the module usage count. +* +* @brief SAHARA device open function. +* +* @param inode Part of the kernel prototype. +* @param file Part of the kernel prototype. +* +* @return 0 - Always returns 0 since any number of calls to this function are +* allowed. +* +*/ +OS_DEV_OPEN(sah_open) +{ + +#if defined(LINUX_VERSION) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)) + MOD_INC_USE_COUNT; +#endif + +#ifdef DIAG_DRV_IF + Device_in_use++; + snprintf(Diag_msg, DIAG_MSG_SIZE, + "Incrementing module use count to: %d ", Device_in_use); + LOG_KDIAG(Diag_msg); +#endif + + os_dev_set_user_private(NULL); + + /* Return 0 to indicate success */ + os_dev_open_return(0); +} + +/*! +******************************************************************************* +* This function simply decrements the module usage count. +* +* @brief SAHARA device release function. +* +* @param inode Part of the kernel prototype. +* @param file Part of the kernel prototype. +* +* @return 0 - Always returns 0 since this function does not fail. +*/ +OS_DEV_CLOSE(sah_release) +{ + fsl_shw_uco_t *user_ctx = os_dev_get_user_private(); + +#if defined(LINUX_VERSION) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)) + MOD_DEC_USE_COUNT; +#endif + +#ifdef DIAG_DRV_IF + Device_in_use--; + snprintf(Diag_msg, DIAG_MSG_SIZE, + "Decrementing module use count to: %d ", Device_in_use); + LOG_KDIAG(Diag_msg); +#endif + + if (user_ctx != NULL) { + sah_handle_deregistration(user_ctx); + os_free_memory(user_ctx); + os_dev_set_user_private(NULL); + } + + /* Return 0 to indicate success */ + os_dev_close_return(OS_ERROR_OK_S); +} + +/*! +******************************************************************************* +* This function provides the IO Controls for the SAHARA driver. Three IO +* Controls are supported: +* +* SAHARA_HWRESET and +* SAHARA_SET_HA +* SAHARA_CHK_TEST_MODE +* +* @brief SAHARA device IO Control function. +* +* @param inode Part of the kernel prototype. +* @param filp Part of the kernel prototype. +* @param cmd Part of the kernel prototype. +* @param arg Part of the kernel prototype. +* +* @return 0 on success +* @return -EBUSY if the HA bit could not be set due to busy hardware. +* @return -ENOTTY if an unsupported IOCTL was attempted on the device. +* @return -EFAULT if put_user() fails +*/ +OS_DEV_IOCTL(sah_ioctl) +{ + int status = 0; + int test_mode; + + switch (os_dev_get_ioctl_op()) { + case SAHARA_HWRESET: +#ifdef DIAG_DRV_IF + LOG_KDIAG("SAHARA_HWRESET IOCTL."); +#endif + /* We need to reset the hardware. */ + sah_HW_Reset(); + + /* Mark all the entries in the Queue Manager's queue with state + * SAH_STATE_RESET. + */ + sah_Queue_Manager_Reset_Entries(); + + /* Wake up all sleeping write() calls. */ + wake_up_interruptible(&Wait_queue); + break; +#ifdef SAHARA_HA_ENABLED + case SAHARA_SET_HA: +#ifdef DIAG_DRV_IF + LOG_KDIAG("SAHARA_SET_HA IOCTL."); +#endif /* DIAG_DRV_IF */ + if (sah_HW_Set_HA() == ERR_INTERNAL) { + status = -EBUSY; + } + break; +#endif /* SAHARA_HA_ENABLED */ + + case SAHARA_CHK_TEST_MODE: + /* load test_mode */ + test_mode = TEST_MODE_OFF; +#ifdef DIAG_DRV_IF + LOG_KDIAG("SAHARA_CHECK_TEST_MODE IOCTL."); + test_mode = TEST_MODE_ON; +#endif /* DIAG_DRV_IF */ +#if defined(KERNEL_TEST) || defined(PERF_TEST) + test_mode = TEST_MODE_ON; +#endif /* KERNEL_TEST || PERF_TEST */ + /* copy test_mode back to user space. put_user() is Linux fn */ + /* compiler warning `register': no problem found so ignored */ + status = put_user(test_mode, (int *)os_dev_get_ioctl_arg()); + break; + + case SAHARA_DAR: +#ifdef DIAG_DRV_IF + LOG_KDIAG("SAHARA_DAR IOCTL."); +#endif /* DIAG_DRV_IF */ + { + fsl_shw_uco_t *user_ctx = os_dev_get_user_private(); + + if (user_ctx != NULL) { + status = + handle_sah_ioctl_dar(user_ctx, + os_dev_get_ioctl_arg + ()); + } else { + status = OS_ERROR_FAIL_S; + } + + } + break; + + case SAHARA_GET_RESULTS: +#ifdef DIAG_DRV_IF + LOG_KDIAG("SAHARA_GET_RESULTS IOCTL."); +#endif /* DIAG_DRV_IF */ + { + fsl_shw_uco_t *user_ctx = os_dev_get_user_private(); + + if (user_ctx != NULL) { + status = + sah_get_results_pointers(user_ctx, + os_dev_get_ioctl_arg + ()); + } else { + status = OS_ERROR_FAIL_S; + } + } + break; + + case SAHARA_REGISTER: +#ifdef DIAG_DRV_IF + LOG_KDIAG("SAHARA_REGISTER IOCTL."); +#endif /* DIAG_DRV_IF */ + { + fsl_shw_uco_t *user_ctx = os_dev_get_user_private(); + + if (user_ctx != NULL) { + status = OS_ERROR_FAIL_S; /* already registered */ + } else { + user_ctx = + os_alloc_memory(sizeof(fsl_shw_uco_t), + GFP_KERNEL); + if (user_ctx == NULL) { + status = OS_ERROR_NO_MEMORY_S; + } else { + /* Copy UCO from user, but only as big as the common UCO */ + if (os_copy_from_user(user_ctx, + (void *) + os_dev_get_ioctl_arg + (), + offsetof + (fsl_shw_uco_t, + result_pool))) { + status = OS_ERROR_FAIL_S; + } else { + os_dev_set_user_private + (user_ctx); + status = + sah_handle_registration + (user_ctx); + } + } + } + } + break; + + /* This ioctl cmd should disappear in favor of a close() routine. */ + case SAHARA_DEREGISTER: +#ifdef DIAG_DRV_IF + LOG_KDIAG("SAHARA_DEREGISTER IOCTL."); +#endif /* DIAG_DRV_IF */ + { + fsl_shw_uco_t *user_ctx = os_dev_get_user_private(); + + if (user_ctx == NULL) { + status = OS_ERROR_FAIL_S; + } else { + status = sah_handle_deregistration(user_ctx); + os_free_memory(user_ctx); + os_dev_set_user_private(NULL); + } + } + break; + case SAHARA_SCC_DROP_PERMS: +#ifdef DIAG_DRV_IF + LOG_KDIAG("SAHARA_SCC_DROP_PERMS IOCTL."); +#endif /* DIAG_DRV_IF */ + { + /* drop permissions on the specified partition */ + fsl_shw_uco_t *user_ctx = os_dev_get_user_private(); + + status = + sah_handle_scc_drop_perms(user_ctx, + os_dev_get_ioctl_arg()); + } + break; + + case SAHARA_SCC_SFREE: + /* Unmap the specified partition from the users space, and then + * free it for use by someone else. + */ +#ifdef DIAG_DRV_IF + LOG_KDIAG("SAHARA_SCC_SFREE IOCTL."); +#endif /* DIAG_DRV_IF */ + { + fsl_shw_uco_t *user_ctx = os_dev_get_user_private(); + + status = + sah_handle_scc_sfree(user_ctx, + os_dev_get_ioctl_arg()); + } + break; + + case SAHARA_SCC_SSTATUS: + /* Unmap the specified partition from the users space, and then + * free it for use by someone else. + */ +#ifdef DIAG_DRV_IF + LOG_KDIAG("SAHARA_SCC_SSTATUS IOCTL."); +#endif /* DIAG_DRV_IF */ + { + fsl_shw_uco_t *user_ctx = os_dev_get_user_private(); + + status = + sah_handle_scc_sstatus(user_ctx, + os_dev_get_ioctl_arg()); + } + break; + + case SAHARA_SCC_ENCRYPT: +#ifdef DIAG_DRV_IF + LOG_KDIAG("SAHARA_SCC_ENCRYPT IOCTL."); +#endif /* DIAG_DRV_IF */ + { + fsl_shw_uco_t *user_ctx = os_dev_get_user_private(); + + status = + sah_handle_scc_encrypt(user_ctx, + os_dev_get_ioctl_arg()); + } + break; + + case SAHARA_SCC_DECRYPT: +#ifdef DIAG_DRV_IF + LOG_KDIAG("SAHARA_SCC_DECRYPT IOCTL."); +#endif /* DIAG_DRV_IF */ + { + fsl_shw_uco_t *user_ctx = os_dev_get_user_private(); + + status = + sah_handle_scc_decrypt(user_ctx, + os_dev_get_ioctl_arg()); + } + break; + + case SAHARA_SK_ALLOC: +#ifdef DIAG_DRV_IF + LOG_KDIAG("SAHARA_SK_ALLOC IOCTL."); +#endif /* DIAG_DRV_IF */ + status = sah_handle_sk_slot_alloc(os_dev_get_ioctl_arg()); + break; + + case SAHARA_SK_DEALLOC: +#ifdef DIAG_DRV_IF + LOG_KDIAG("SAHARA_SK_DEALLOC IOCTL."); +#endif /* DIAG_DRV_IF */ + status = sah_handle_sk_slot_dealloc(os_dev_get_ioctl_arg()); + break; + + case SAHARA_SK_LOAD: +#ifdef DIAG_DRV_IF + LOG_KDIAG("SAHARA_SK_LOAD IOCTL."); +#endif /* DIAG_DRV_IF */ + status = sah_handle_sk_slot_load(os_dev_get_ioctl_arg()); + break; + case SAHARA_SK_READ: +#ifdef DIAG_DRV_IF + LOG_KDIAG("SAHARA_SK_READ IOCTL."); +#endif /* DIAG_DRV_IF */ + status = sah_handle_sk_slot_read(os_dev_get_ioctl_arg()); + break; + + case SAHARA_SK_SLOT_DEC: +#ifdef DIAG_DRV_IF + LOG_KDIAG("SAHARA_SK_SLOT_DECRYPT IOCTL."); +#endif /* DIAG_DRV_IF */ + status = sah_handle_sk_slot_decrypt(os_dev_get_ioctl_arg()); + break; + + case SAHARA_SK_SLOT_ENC: +#ifdef DIAG_DRV_IF + LOG_KDIAG("SAHARA_SK_SLOT_ENCRYPT IOCTL."); +#endif /* DIAG_DRV_IF */ + status = sah_handle_sk_slot_encrypt(os_dev_get_ioctl_arg()); + break; + case SAHARA_GET_CAPS: +#ifdef DIAG_DRV_IF + LOG_KDIAG("SAHARA_GET_CAPS IOCTL."); +#endif /* DIAG_DRV_IF */ + { + fsl_shw_uco_t *user_ctx = os_dev_get_user_private(); + + status = + sah_handle_get_capabilities(user_ctx, + os_dev_get_ioctl_arg()); + } + break; + + default: +#ifdef DIAG_DRV_IF + LOG_KDIAG("Unknown SAHARA IOCTL."); +#endif /* DIAG_DRV_IF */ + status = OS_ERROR_FAIL_S; + } + + os_dev_ioctl_return(status); +} + +/* Fill in the user's capabilities structure */ +static os_error_code sah_handle_get_capabilities(fsl_shw_uco_t * user_ctx, + uint32_t info) +{ + os_error_code status = OS_ERROR_FAIL_S; + fsl_shw_pco_t capabilities; + + status = os_copy_from_user(&capabilities, (void *)info, + sizeof(fsl_shw_pco_t)); + + if (status != OS_ERROR_OK_S) { + goto out; + } + + if (get_capabilities(user_ctx, &capabilities) == FSL_RETURN_OK_S) { + status = os_copy_to_user((void *)info, &capabilities, + sizeof(fsl_shw_pco_t)); + } + + out: + return status; +} + +#ifdef FSL_HAVE_SCC2 + +/* Find the kernel-mode address of the partition. + * This can then be passed to the SCC functions. + */ +void *lookup_user_partition(fsl_shw_uco_t * user_ctx, uint32_t user_base) +{ + /* search through the partition chain to find one that matches the user base + * address. + */ + fsl_shw_spo_t *curr = (fsl_shw_spo_t *) user_ctx->partition; + + while (curr != NULL) { + if (curr->user_base == user_base) { + return curr->kernel_base; + } + curr = (fsl_shw_spo_t *) curr->next; + } + return NULL; +} + +/* user_base: userspace base address of the partition + * kernel_base: kernel mode base address of the partition + */ +static fsl_shw_return_t register_user_partition(fsl_shw_uco_t * user_ctx, + uint32_t user_base, + void *kernel_base) +{ + fsl_shw_spo_t *partition_info; + fsl_shw_return_t ret = FSL_RETURN_ERROR_S; + + if (user_ctx == NULL) { + goto out; + } + + partition_info = os_alloc_memory(sizeof(fsl_shw_spo_t), GFP_KERNEL); + + if (partition_info == NULL) { + goto out; + } + + /* stuff the partition info, then put it at the front of the chain */ + partition_info->user_base = user_base; + partition_info->kernel_base = kernel_base; + partition_info->next = user_ctx->partition; + + user_ctx->partition = (struct fsl_shw_spo_t *)partition_info; + +#ifdef DIAG_DRV_IF + LOG_KDIAG_ARGS + ("partition with user_base=%p, kernel_base=%p registered.", + (void *)user_base, kernel_base); +#endif + + ret = FSL_RETURN_OK_S; + + out: + + return ret; +} + +/* if the partition is in the users list, remove it */ +static fsl_shw_return_t deregister_user_partition(fsl_shw_uco_t * user_ctx, + uint32_t user_base) +{ + fsl_shw_spo_t *curr = (fsl_shw_spo_t *) user_ctx->partition; + fsl_shw_spo_t *last = (fsl_shw_spo_t *) user_ctx->partition; + + while (curr != NULL) { + if (curr->user_base == user_base) { + +#ifdef DIAG_DRV_IF + LOG_KDIAG_ARGS + ("deregister_user_partition: partition with " + "user_base=%p, kernel_base=%p deregistered.\n", + (void *)curr->user_base, curr->kernel_base); +#endif + + if (last == curr) { + user_ctx->partition = curr->next; + os_free_memory(curr); + return FSL_RETURN_OK_S; + } else { + last->next = curr->next; + os_free_memory(curr); + return FSL_RETURN_OK_S; + } + } + last = curr; + curr = (fsl_shw_spo_t *) curr->next; + } + + return FSL_RETURN_ERROR_S; +} + +#endif /* FSL_HAVE_SCC2 */ + +static os_error_code sah_handle_scc_drop_perms(fsl_shw_uco_t * user_ctx, + uint32_t info) +{ + os_error_code status = OS_ERROR_NO_MEMORY_S; +#ifdef FSL_HAVE_SCC2 + scc_return_t scc_ret; + scc_partition_info_t partition_info; + void *kernel_base; + + status = + os_copy_from_user(&partition_info, (void *)info, + sizeof(partition_info)); + + if (status != OS_ERROR_OK_S) { + goto out; + } + + /* validate that the user owns this partition, and look up its handle */ + kernel_base = lookup_user_partition(user_ctx, partition_info.user_base); + + if (kernel_base == NULL) { + status = OS_ERROR_FAIL_S; +#ifdef DIAG_DRV_IF + LOG_KDIAG("_scc_drop_perms(): failed to find partition\n"); +#endif + goto out; + } + + /* call scc driver to perform the drop */ + scc_ret = scc_diminish_permissions(kernel_base, + partition_info.permissions); + if (scc_ret == SCC_RET_OK) { + status = OS_ERROR_OK_S; + } else { + status = OS_ERROR_FAIL_S; + } + + out: +#endif /* FSL_HAVE_SCC2 */ + return status; +} + +static os_error_code sah_handle_scc_sfree(fsl_shw_uco_t * user_ctx, + uint32_t info) +{ + os_error_code status = OS_ERROR_NO_MEMORY_S; +#ifdef FSL_HAVE_SCC2 + { + scc_partition_info_t partition_info; + void *kernel_base; + int ret; + + status = + os_copy_from_user(&partition_info, (void *)info, + sizeof(partition_info)); + + /* check that the copy was successful */ + if (status != OS_ERROR_OK_S) { + goto out; + } + + /* validate that the user owns this partition, and look up its handle */ + kernel_base = + lookup_user_partition(user_ctx, partition_info.user_base); + + if (kernel_base == NULL) { + status = OS_ERROR_FAIL_S; +#ifdef DIAG_DRV_IF + LOG_KDIAG("failed to find partition\n"); +#endif /*DIAG_DRV_IF */ + goto out; + } + + /* Unmap the memory region (see sys_munmap in mmap.c) */ + ret = unmap_user_memory(partition_info.user_base, 8192); + + /* If the memory was successfully released */ + if (ret == OS_ERROR_OK_S) { + + /* release the partition */ + scc_release_partition(kernel_base); + + /* and remove it from the users context */ + deregister_user_partition(user_ctx, + partition_info.user_base); + + status = OS_ERROR_OK_S; + } + } + out: +#endif /* FSL_HAVE_SCC2 */ + return status; +} + +static os_error_code sah_handle_scc_sstatus(fsl_shw_uco_t * user_ctx, + uint32_t info) +{ + os_error_code status = OS_ERROR_NO_MEMORY_S; +#ifdef FSL_HAVE_SCC2 + { + scc_partition_info_t partition_info; + void *kernel_base; + + status = + os_copy_from_user(&partition_info, (void *)info, + sizeof(partition_info)); + + /* check that the copy was successful */ + if (status != OS_ERROR_OK_S) { + goto out; + } + + /* validate that the user owns this partition, and look up its handle */ + kernel_base = + lookup_user_partition(user_ctx, partition_info.user_base); + + if (kernel_base == NULL) { + status = OS_ERROR_FAIL_S; +#ifdef DIAG_DRV_IF + LOG_KDIAG("failed to find partition\n"); +#endif /*DIAG_DRV_IF */ + goto out; + } + + partition_info.status = scc_partition_status(kernel_base); + + status = + os_copy_to_user((void *)info, &partition_info, + sizeof(partition_info)); + } + out: +#endif /* FSL_HAVE_SCC2 */ + return status; +} + +static os_error_code sah_handle_scc_encrypt(fsl_shw_uco_t * user_ctx, + uint32_t info) +{ + os_error_code os_err = OS_ERROR_FAIL_S; +#ifdef FSL_HAVE_SCC2 + { + fsl_shw_return_t retval; + scc_region_t region_info; + void *page_ctx = NULL; + void *black_addr = NULL; + void *partition_base = NULL; + scc_config_t *scc_configuration; + + os_err = + os_copy_from_user(®ion_info, (void *)info, + sizeof(region_info)); + + if (os_err != OS_ERROR_OK_S) { + goto out; + } +#ifdef DIAG_DRV_IF + LOG_KDIAG_ARGS + ("partition_base: %p, offset: %i, length: %i, black data: %p", + (void *)region_info.partition_base, region_info.offset, + region_info.length, (void *)region_info.black_data); +#endif + + /* validate that the user owns this partition, and look up its handle */ + partition_base = lookup_user_partition(user_ctx, + region_info. + partition_base); + + if (partition_base == NULL) { + retval = FSL_RETURN_ERROR_S; +#ifdef DIAG_DRV_IF + LOG_KDIAG("failed to find secure partition\n"); +#endif + goto out; + } + + /* Check that the memory size requested is correct */ + scc_configuration = scc_get_configuration(); + if (region_info.offset + region_info.length > + scc_configuration->partition_size_bytes) { + retval = FSL_RETURN_ERROR_S; + goto out; + } + + /* wire down black data */ + black_addr = wire_user_memory(region_info.black_data, + region_info.length, &page_ctx); + + if (black_addr == NULL) { + retval = FSL_RETURN_ERROR_S; + goto out; + } + + retval = + do_scc_encrypt_region(NULL, partition_base, + region_info.offset, + region_info.length, black_addr, + region_info.IV, + region_info.cypher_mode); + + /* release black data */ + unwire_user_memory(&page_ctx); + + out: + if (os_err == OS_ERROR_OK_S) { + /* Return error code */ + region_info.code = retval; + os_err = + os_copy_to_user((void *)info, ®ion_info, + sizeof(region_info)); + } + } + +#endif + return os_err; +} + +static os_error_code sah_handle_scc_decrypt(fsl_shw_uco_t * user_ctx, + uint32_t info) +{ + os_error_code os_err = OS_ERROR_FAIL_S; +#ifdef FSL_HAVE_SCC2 + { + fsl_shw_return_t retval; + scc_region_t region_info; + void *page_ctx = NULL; + void *black_addr; + void *partition_base; + scc_config_t *scc_configuration; + + os_err = + os_copy_from_user(®ion_info, (void *)info, + sizeof(region_info)); + + if (os_err != OS_ERROR_OK_S) { + goto out; + } +#ifdef DIAG_DRV_IF + LOG_KDIAG_ARGS + ("partition_base: %p, offset: %i, length: %i, black data: %p", + (void *)region_info.partition_base, region_info.offset, + region_info.length, (void *)region_info.black_data); +#endif + + /* validate that the user owns this partition, and look up its handle */ + partition_base = lookup_user_partition(user_ctx, + region_info. + partition_base); + + if (partition_base == NULL) { + retval = FSL_RETURN_ERROR_S; +#ifdef DIAG_DRV_IF + LOG_KDIAG("failed to find partition\n"); +#endif + goto out; + } + + /* Check that the memory size requested is correct */ + scc_configuration = scc_get_configuration(); + if (region_info.offset + region_info.length > + scc_configuration->partition_size_bytes) { + retval = FSL_RETURN_ERROR_S; + goto out; + } + + /* wire down black data */ + black_addr = wire_user_memory(region_info.black_data, + region_info.length, &page_ctx); + + if (black_addr == NULL) { + retval = FSL_RETURN_ERROR_S; + goto out; + } + + retval = + do_scc_decrypt_region(NULL, partition_base, + region_info.offset, + region_info.length, black_addr, + region_info.IV, + region_info.cypher_mode); + + /* release black data */ + unwire_user_memory(&page_ctx); + + out: + if (os_err == OS_ERROR_OK_S) { + /* Return error code */ + region_info.code = retval; + os_err = + os_copy_to_user((void *)info, ®ion_info, + sizeof(region_info)); + } + } + +#endif /* FSL_HAVE_SCC2 */ + return os_err; +} + +/*****************************************************************************/ +/* fn get_user_smid() */ +/*****************************************************************************/ +uint32_t get_user_smid(void *proc) +{ + /* + * A real implementation would have some way to handle signed applications + * which wouild be assigned distinct SMIDs. For the reference + * implementation, we show where this would be determined (here), but + * always provide a fixed answer, thus not separating users at all. + */ + + return 0x42eaae42; +} + +/*! +******************************************************************************* +* This function implements the smalloc() function for userspace programs, by +* making a call to the SCC2 mmap() function that acquires a region of secure +* memory on behalf of the user, and then maps it into the users memory space. +* Currently, the only memory size supported is that of a single SCC2 partition. +* Requests for other sized memory regions will fail. +*/ +OS_DEV_MMAP(sah_mmap) +{ + os_error_code status = OS_ERROR_NO_MEMORY_S; + +#ifdef FSL_HAVE_SCC2 + { + scc_return_t scc_ret; + fsl_shw_return_t fsl_ret; + uint32_t partition_registered = FALSE; + + uint32_t user_base; + void *partition_base; + uint32_t smid; + scc_config_t *scc_configuration; + + int part_no = -1; + uint32_t part_phys; + + fsl_shw_uco_t *user_ctx = + (fsl_shw_uco_t *) os_dev_get_user_private(); + + /* Make sure that the user context is valid */ + if (user_ctx == NULL) { + user_ctx = + os_alloc_memory(sizeof(*user_ctx), GFP_KERNEL); + + if (user_ctx == NULL) { + status = OS_ERROR_NO_MEMORY_S; + goto out; + } + + sah_handle_registration(user_ctx); + os_dev_set_user_private(user_ctx); + } + + /* Determine the size of a secure partition */ + scc_configuration = scc_get_configuration(); + + /* Check that the memory size requested is equal to the partition + * size, and that the requested destination is on a page boundary. + */ + if (((os_mmap_user_base() % PAGE_SIZE) != 0) || + (os_mmap_memory_size() != + scc_configuration->partition_size_bytes)) { + status = OS_ERROR_BAD_ARG_S; + goto out; + } + + /* Retrieve the SMID associated with the user */ + smid = get_user_smid(user_ctx->process); + + /* Attempt to allocate a secure partition */ + scc_ret = + scc_allocate_partition(smid, &part_no, &partition_base, + &part_phys); + if (scc_ret != SCC_RET_OK) { + pr_debug + ("SCC mmap() request failed to allocate partition;" + " error %d\n", status); + status = OS_ERROR_FAIL_S; + goto out; + } + + pr_debug("scc_mmap() acquired partition %d at %08x\n", + part_no, part_phys); + + /* Record partition info in the user context */ + user_base = os_mmap_user_base(); + fsl_ret = + register_user_partition(user_ctx, user_base, + partition_base); + + if (fsl_ret != FSL_RETURN_OK_S) { + pr_debug + ("SCC mmap() request failed to register partition with user" + " context, error: %d\n", fsl_ret); + status = OS_ERROR_FAIL_S; + } + + partition_registered = TRUE; + + status = map_user_memory(os_mmap_memory_ctx(), part_phys, + os_mmap_memory_size()); + +#ifdef SHW_DEBUG + if (status == OS_ERROR_OK_S) { + LOG_KDIAG_ARGS + ("Partition allocated: user_base=%p, partition_base=%p.", + (void *)user_base, partition_base); + } +#endif + + out: + /* If there is an error it has to be handled here */ + if (status != OS_ERROR_OK_S) { + /* if the partition was registered with the user, unregister it. */ + if (partition_registered == TRUE) { + deregister_user_partition(user_ctx, user_base); + } + + /* if the partition was allocated, deallocate it */ + if (partition_base != NULL) { + scc_release_partition(partition_base); + } + } + } +#endif /* FSL_HAVE_SCC2 */ + + return status; +} + +/* Find the physical address of a key stored in the system keystore */ +fsl_shw_return_t +system_keystore_get_slot_info(uint64_t owner_id, uint32_t slot, + uint32_t * address, uint32_t * slot_size_bytes) +{ + fsl_shw_return_t retval; + void *kernel_address; + + /* First verify that the key access is valid */ + retval = system_keystore.slot_verify_access(system_keystore.user_data, + owner_id, slot); + + if (retval != FSL_RETURN_OK_S) { +#ifdef DIAG_DRV_IF + LOG_KDIAG("verification failed"); +#endif + return retval; + } + + if (address != NULL) { +#ifdef FSL_HAVE_SCC2 + kernel_address = + system_keystore.slot_get_address(system_keystore.user_data, + slot); + (*address) = scc_virt_to_phys(kernel_address); +#else + kernel_address = + system_keystore.slot_get_address((void *)&owner_id, slot); + (*address) = (uint32_t) kernel_address; +#endif + } + + if (slot_size_bytes != NULL) { +#ifdef FSL_HAVE_SCC2 + *slot_size_bytes = + system_keystore.slot_get_slot_size(system_keystore. + user_data, slot); +#else + *slot_size_bytes = + system_keystore.slot_get_slot_size((void *)&owner_id, slot); +#endif + } + + return retval; +} + +static os_error_code sah_handle_sk_slot_alloc(uint32_t info) +{ + scc_slot_t slot_info; + os_error_code os_err; + scc_return_t scc_ret; + + os_err = os_copy_from_user(&slot_info, (void *)info, sizeof(slot_info)); + if (os_err == OS_ERROR_OK_S) { + scc_ret = keystore_slot_alloc(&system_keystore, + slot_info.key_length, + slot_info.ownerid, + &slot_info.slot); + if (scc_ret == SCC_RET_OK) { + slot_info.code = FSL_RETURN_OK_S; + } else if (scc_ret == SCC_RET_INSUFFICIENT_SPACE) { + slot_info.code = FSL_RETURN_NO_RESOURCE_S; + } else { + slot_info.code = FSL_RETURN_ERROR_S; + } + +#ifdef DIAG_DRV_IF + LOG_KDIAG_ARGS("key length: %i, handle: %i\n", + slot_info.key_length, slot_info.slot); +#endif + + /* Return error code and slot info */ + os_err = + os_copy_to_user((void *)info, &slot_info, + sizeof(slot_info)); + + if (os_err != OS_ERROR_OK_S) { + (void)keystore_slot_dealloc(&system_keystore, + slot_info.ownerid, + slot_info.slot); + } + } + + return os_err; +} + +static os_error_code sah_handle_sk_slot_dealloc(uint32_t info) +{ + fsl_shw_return_t ret = FSL_RETURN_INTERNAL_ERROR_S; + scc_slot_t slot_info; + os_error_code os_err; + scc_return_t scc_ret; + + os_err = os_copy_from_user(&slot_info, (void *)info, sizeof(slot_info)); + + if (os_err == OS_ERROR_OK_S) { + scc_ret = keystore_slot_dealloc(&system_keystore, + slot_info.ownerid, + slot_info.slot); + + if (scc_ret == SCC_RET_OK) { + ret = FSL_RETURN_OK_S; + } else { + ret = FSL_RETURN_ERROR_S; + } + slot_info.code = ret; + + os_err = + os_copy_to_user((void *)info, &slot_info, + sizeof(slot_info)); + } + + return os_err; +} + +static os_error_code sah_handle_sk_slot_load(uint32_t info) +{ + fsl_shw_return_t ret = FSL_RETURN_INTERNAL_ERROR_S; + scc_slot_t slot_info; + os_error_code os_err; + uint8_t *key = NULL; + + os_err = os_copy_from_user(&slot_info, (void *)info, sizeof(slot_info)); + + if (os_err == OS_ERROR_OK_S) { + /* Allow slop in alloc in case we are rounding up to word multiple */ + key = os_alloc_memory(slot_info.key_length + 3, GFP_KERNEL); + if (key == NULL) { + ret = FSL_RETURN_NO_RESOURCE_S; + os_err = OS_ERROR_NO_MEMORY_S; + } else { + os_err = os_copy_from_user(key, slot_info.key, + slot_info.key_length); + } + } + + if (os_err == OS_ERROR_OK_S) { + unsigned key_length = slot_info.key_length; + + /* Round up if necessary, as SCC call wants a multiple of 32-bit + * values for the full object being loaded. */ + if ((key_length & 3) != 0) { + key_length += 4 - (key_length & 3); + } + ret = keystore_slot_load(&system_keystore, + slot_info.ownerid, slot_info.slot, key, + key_length); + + slot_info.code = ret; + os_err = + os_copy_to_user((void *)info, &slot_info, + sizeof(slot_info)); + } + + if (key != NULL) { + memset(key, 0, slot_info.key_length); + os_free_memory(key); + } + + return os_err; +} + +static os_error_code sah_handle_sk_slot_read(uint32_t info) +{ + fsl_shw_return_t ret = FSL_RETURN_INTERNAL_ERROR_S; + scc_slot_t slot_info; + os_error_code os_err; + uint8_t *key = NULL; + + os_err = os_copy_from_user(&slot_info, (void *)info, sizeof(slot_info)); + + if (os_err == OS_ERROR_OK_S) { + + /* This operation is not allowed for user keys */ + slot_info.code = FSL_RETURN_NO_RESOURCE_S; + os_err = + os_copy_to_user((void *)info, &slot_info, + sizeof(slot_info)); + + return os_err; + } + + if (os_err == OS_ERROR_OK_S) { + /* Allow slop in alloc in case we are rounding up to word multiple */ + key = os_alloc_memory(slot_info.key_length + 3, GFP_KERNEL); + if (key == NULL) { + ret = FSL_RETURN_NO_RESOURCE_S; + os_err = OS_ERROR_NO_MEMORY_S; + } + } + + if (os_err == OS_ERROR_OK_S) { + unsigned key_length = slot_info.key_length; + + /* @bug Do some PERMISSIONS checking - make sure this is SW key */ + + /* Round up if necessary, as SCC call wants a multiple of 32-bit + * values for the full object being loaded. */ + if ((key_length & 3) != 0) { + key_length += 4 - (key_length & 3); + } + ret = keystore_slot_read(&system_keystore, + slot_info.ownerid, slot_info.slot, + key_length, key); + + /* @bug do some error checking */ + + /* Send key back to user */ + os_err = os_copy_to_user(slot_info.key, key, + slot_info.key_length); + + slot_info.code = ret; + os_err = + os_copy_to_user((void *)info, &slot_info, + sizeof(slot_info)); + } + + if (key != NULL) { + memset(key, 0, slot_info.key_length); + os_free_memory(key); + } + + return os_err; +} + +static os_error_code sah_handle_sk_slot_encrypt(uint32_t info) +{ + fsl_shw_return_t ret = FSL_RETURN_INTERNAL_ERROR_S; + scc_slot_t slot_info; + os_error_code os_err; + scc_return_t scc_ret; + uint8_t *key = NULL; + + os_err = os_copy_from_user(&slot_info, (void *)info, sizeof(slot_info)); + + if (os_err == OS_ERROR_OK_S) { + key = os_alloc_memory(slot_info.key_length, GFP_KERNEL); + if (key == NULL) { + ret = FSL_RETURN_NO_RESOURCE_S; + } + } + + if (key != NULL) { + + scc_ret = keystore_slot_encrypt(NULL, &system_keystore, + slot_info.ownerid, + slot_info.slot, + slot_info.key_length, key); + + if (scc_ret != SCC_RET_OK) { + ret = FSL_RETURN_ERROR_S; + } else { + os_err = + os_copy_to_user(slot_info.key, key, + slot_info.key_length); + if (os_err != OS_ERROR_OK_S) { + ret = FSL_RETURN_INTERNAL_ERROR_S; + } else { + ret = FSL_RETURN_OK_S; + } + } + + slot_info.code = ret; + os_err = + os_copy_to_user((void *)info, &slot_info, + sizeof(slot_info)); + + memset(key, 0, slot_info.key_length); + os_free_memory(key); + } + + return os_err; +} + +static os_error_code sah_handle_sk_slot_decrypt(uint32_t info) +{ + fsl_shw_return_t ret = FSL_RETURN_INTERNAL_ERROR_S; + scc_slot_t slot_info; /*!< decrypt request fields */ + os_error_code os_err; + scc_return_t scc_ret; + uint8_t *key = NULL; + + os_err = os_copy_from_user(&slot_info, (void *)info, sizeof(slot_info)); + + if (os_err == OS_ERROR_OK_S) { + key = os_alloc_memory(slot_info.key_length, GFP_KERNEL); + if (key == NULL) { + ret = FSL_RETURN_NO_RESOURCE_S; + os_err = OS_ERROR_OK_S; + } else { + os_err = os_copy_from_user(key, slot_info.key, + slot_info.key_length); + } + } + + if (os_err == OS_ERROR_OK_S) { + scc_ret = keystore_slot_decrypt(NULL, &system_keystore, + slot_info.ownerid, + slot_info.slot, + slot_info.key_length, key); + if (scc_ret == SCC_RET_OK) { + ret = FSL_RETURN_OK_S; + } else { + ret = FSL_RETURN_ERROR_S; + } + + slot_info.code = ret; + os_err = + os_copy_to_user((void *)info, &slot_info, + sizeof(slot_info)); + } + + if (key != NULL) { + memset(key, 0, slot_info.key_length); + os_free_memory(key); + } + + return os_err; +} + +/*! + * Register a user + * + * @brief Register a user + * + * @param user_ctx information about this user + * + * @return status code + */ +fsl_shw_return_t sah_handle_registration(fsl_shw_uco_t * user_ctx) +{ + /* Initialize the user's result pool (like sah_Queue_Construct() */ + user_ctx->result_pool.head = NULL; + user_ctx->result_pool.tail = NULL; + user_ctx->result_pool.count = 0; + + /* initialize the user's partition chain */ + user_ctx->partition = NULL; + + return FSL_RETURN_OK_S; +} + +/*! + * Deregister a user + * + * @brief Deregister a user + * + * @param user_ctx information about this user + * + * @return status code + */ +fsl_shw_return_t sah_handle_deregistration(fsl_shw_uco_t * user_ctx) +{ + /* NOTE: + * This will release any secure partitions that are held by the user. + * Encryption keys that were placed in the system keystore by the user + * should not be removed here, because they might have been shared with + * another process. The user must be careful to release any that are no + * longer in use. + */ + fsl_shw_return_t ret = FSL_RETURN_OK_S; + +#ifdef FSL_HAVE_SCC2 + fsl_shw_spo_t *partition; + struct mm_struct *mm = current->mm; + + while ((user_ctx->partition != NULL) && (ret == FSL_RETURN_OK_S)) { + + partition = user_ctx->partition; + +#ifdef DIAG_DRV_IF + LOG_KDIAG_ARGS + ("Found an abandoned secure partition at %p, releasing", + partition); +#endif + + /* It appears that current->mm is not valid if this is called from a + * close routine (perhaps only if the program raised an exception that + * caused it to close?) If that is the case, then still free the + * partition, but do not remove it from the memory space (dangerous?) + */ + + if (mm == NULL) { +#ifdef DIAG_DRV_IF + LOG_KDIAG + ("Warning: no mm structure found, not unmapping " + "partition from user memory\n"); +#endif + } else { + /* Unmap the memory region (see sys_munmap in mmap.c) */ + /* Note that this assumes a single memory partition */ + unmap_user_memory(partition->user_base, 8192); + } + + /* If the memory was successfully released */ + if (ret == OS_ERROR_OK_S) { + /* release the partition */ + scc_release_partition(partition->kernel_base); + + /* and remove it from the users context */ + deregister_user_partition(user_ctx, + partition->user_base); + + ret = FSL_RETURN_OK_S; + } else { + ret = FSL_RETURN_ERROR_S; + + goto out; + } + } + out: +#endif /* FSL_HAVE_SCC2 */ + + return ret; +} + +/*! + * Sets up memory to extract results from results pool + * + * @brief Sets up memory to extract results from results pool + * + * @param user_ctx information about this user + * @param[in,out] arg contains input parameters and fields that the driver + * fills in + * + * @return os error code or 0 on success + */ +int sah_get_results_pointers(fsl_shw_uco_t * user_ctx, uint32_t arg) +{ + sah_results results_arg; /* kernel mode usable version of 'arg' */ + fsl_shw_result_t *user_results; /* user mode address of results */ + unsigned *user_actual; /* user mode address of actual number of results */ + unsigned actual; /* local memory of actual number of results */ + int ret_val = OS_ERROR_FAIL_S; + sah_Head_Desc *finished_request; + unsigned int loop; + + /* copy structure from user to kernel space */ + if (!os_copy_from_user(&results_arg, (void *)arg, sizeof(sah_results))) { + /* save user space pointers */ + user_actual = results_arg.actual; /* where count goes */ + user_results = results_arg.results; /* where results goe */ + + /* Set pointer for actual value to temporary kernel memory location */ + results_arg.actual = &actual; + + /* Allocate kernel memory to hold temporary copy of the results */ + results_arg.results = + os_alloc_memory(sizeof(fsl_shw_result_t) * + results_arg.requested, GFP_KERNEL); + + /* if memory allocated, continue */ + if (results_arg.results == NULL) { + ret_val = OS_ERROR_NO_MEMORY_S; + } else { + fsl_shw_return_t get_status; + + /* get the results */ + get_status = + sah_get_results_from_pool(user_ctx, &results_arg); + + /* free the copy of the user space descriptor chain */ + for (loop = 0; loop < actual; ++loop) { + /* get sah_Head_Desc from results and put user address into + * the return structure */ + finished_request = + results_arg.results[loop].user_desc; + results_arg.results[loop].user_desc = + finished_request->user_desc; + /* return the descriptor chain memory to the block free pool */ + sah_Free_Chained_Descriptors(finished_request); + } + + /* if no errors, copy results and then the actual number of results + * back to user space + */ + if (get_status == FSL_RETURN_OK_S) { + if (os_copy_to_user + (user_results, results_arg.results, + actual * sizeof(fsl_shw_result_t)) + || os_copy_to_user(user_actual, &actual, + sizeof(user_actual))) { + ret_val = OS_ERROR_FAIL_S; + } else { + ret_val = 0; /* no error */ + } + } + /* free the allocated memory */ + os_free_memory(results_arg.results); + } + } + + return ret_val; +} + +/*! + * Extracts results from results pool + * + * @brief Extract results from results pool + * + * @param user_ctx information about this user + * @param[in,out] arg contains input parameters and fields that the + * driver fills in + * + * @return status code + */ +fsl_shw_return_t sah_get_results_from_pool(volatile fsl_shw_uco_t * user_ctx, + sah_results * arg) +{ + sah_Head_Desc *finished_request; + unsigned int loop = 0; + os_lock_context_t int_flags; + + /* Get the number of results requested, up to total number of results + * available + */ + do { + /* Protect state of user's result pool until we have retrieved and + * remove the first entry, or determined that the pool is empty. */ + os_lock_save_context(desc_queue_lock, int_flags); + finished_request = user_ctx->result_pool.head; + + if (finished_request != NULL) { + sah_Queue_Remove_Entry((sah_Queue *) & user_ctx-> + result_pool); + os_unlock_restore_context(desc_queue_lock, int_flags); + + /* Prepare to free. */ + (void)sah_DePhysicalise_Descriptors(finished_request); + + arg->results[loop].user_ref = + finished_request->user_ref; + arg->results[loop].code = finished_request->result; + arg->results[loop].detail1 = + finished_request->fault_address; + arg->results[loop].detail2 = 0; + arg->results[loop].user_desc = finished_request; + + loop++; + } else { /* finished_request is NULL */ + /* pool is empty */ + os_unlock_restore_context(desc_queue_lock, int_flags); + } + + } while ((loop < arg->requested) && (finished_request != NULL)); + + /* record number of results actually obtained */ + *arg->actual = loop; + + return FSL_RETURN_OK_S; +} + +/*! + * Converts descriptor chain to kernel space (from user space) and submits + * chain to Sahara for processing + * + * @brief Submits converted descriptor chain to sahara + * + * @param user_ctx Pointer to Kernel version of user's ctx + * @param user_space_desc user space address of descriptor chain that is + * in user space + * + * @return OS status code + */ +static int handle_sah_ioctl_dar(fsl_shw_uco_t * user_ctx, + uint32_t user_space_desc) +{ + int os_error_code = OS_ERROR_FAIL_S; + sah_Head_Desc *desc_chain_head; /* chain in kernel - virtual address */ + + /* This will re-create the linked list so that the SAHARA hardware can + * DMA on it. + */ + desc_chain_head = sah_Copy_Descriptors(user_ctx, + (sah_Head_Desc *) + user_space_desc); + + if (desc_chain_head == NULL) { + /* We may have failed due to a -EFAULT as well, but we will return + * OS_ERROR_NO_MEMORY_S since either way it is a memory related + * failure. + */ + os_error_code = OS_ERROR_NO_MEMORY_S; + } else { + fsl_shw_return_t stat; + + desc_chain_head->user_info = user_ctx; + desc_chain_head->user_desc = (sah_Head_Desc *) user_space_desc; + + if (desc_chain_head->uco_flags & FSL_UCO_BLOCKING_MODE) { +#ifdef SAHARA_POLL_MODE + sah_Handle_Poll(desc_chain_head); +#else + sah_blocking_mode(desc_chain_head); +#endif + stat = desc_chain_head->result; + /* return the descriptor chain memory to the block free pool */ + sah_Free_Chained_Descriptors(desc_chain_head); + /* Tell user how the call turned out */ + + /* Copy 'result' back up to the result member. + * + * The dereference of the different member will cause correct the + * arithmetic to occur on the user-space address because of the + * missing dma/bus locations in the user mode version of the + * sah_Desc structure. */ + os_error_code = + os_copy_to_user((void *)(user_space_desc + + offsetof(sah_Head_Desc, + uco_flags)), + &stat, sizeof(fsl_shw_return_t)); + + } else { /* not blocking mode - queue and forget */ + + if (desc_chain_head->uco_flags & FSL_UCO_CALLBACK_MODE) { + user_ctx->process = os_get_process_handle(); + user_ctx->callback = sah_user_callback; + } +#ifdef SAHARA_POLL_MODE + /* will put results in result pool */ + sah_Handle_Poll(desc_chain_head); +#else + /* just put someting in the DAR */ + sah_Queue_Manager_Append_Entry(desc_chain_head); +#endif + /* assume all went well */ + os_error_code = OS_ERROR_OK_S; + } + } + + return os_error_code; +} + +static void sah_user_callback(fsl_shw_uco_t * user_ctx) +{ + os_send_signal(user_ctx->process, SIGUSR2); +} + +/*! + * This function is called when a thread attempts to read from the /proc/sahara + * file. Upon read, statistics and information about the state of the driver + * are returned in nthe supplied buffer. + * + * @brief SAHARA PROCFS read function. + * + * @param buf Anything written to this buffer will be returned to the + * user-space process that is reading from this proc entry. + * @param start Part of the kernel prototype. + * @param offset Part of the kernel prototype. + * @param count The size of the buf argument. + * @param eof An integer which is set to one to tell the user-space + * process that there is no more data to read. + * @param data Part of the kernel prototype. + * + * @return The number of bytes written to the proc entry. + */ +#if !defined(CONFIG_DEVFS_FS) || (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +static int sah_read_procfs(char *buf, + char **start, + off_t offset, int count, int *eof, void *data) +{ + int output_bytes = 0; + int in_queue_count = 0; + os_lock_context_t lock_context; + + os_lock_save_context(desc_queue_lock, lock_context); + in_queue_count = sah_Queue_Manager_Count_Entries(TRUE, 0); + os_unlock_restore_context(desc_queue_lock, lock_context); + output_bytes += snprintf(buf, count - output_bytes, "queued: %d\n", + in_queue_count); + output_bytes += snprintf(buf + output_bytes, count - output_bytes, + "Descriptors: %d, " + "Interrupts %d (%d Done1Done2, %d Done1Busy2, " + " %d Done1)\n", + dar_count, interrupt_count, done1done2_count, + done1busy2_count, done1_count); + output_bytes += snprintf(buf + output_bytes, count - output_bytes, + "Control: %08x\n", sah_HW_Read_Control()); +#if !defined(FSL_HAVE_SAHARA4) || defined(SAHARA4_NO_USE_SQUIB) + output_bytes += snprintf(buf + output_bytes, count - output_bytes, + "IDAR: %08x; CDAR: %08x\n", + sah_HW_Read_IDAR(), sah_HW_Read_CDAR()); +#endif +#ifdef DIAG_DRV_STATUS + output_bytes += snprintf(buf + output_bytes, count - output_bytes, + "Status: %08x; Error Status: %08x; Op Status: %08x\n", + sah_HW_Read_Status(), + sah_HW_Read_Error_Status(), + sah_HW_Read_Op_Status()); +#endif +#ifdef FSL_HAVE_SAHARA4 + output_bytes += snprintf(buf + output_bytes, count - output_bytes, + "MMStat: %08x; Config: %08x\n", + sah_HW_Read_MM_Status(), sah_HW_Read_Config()); +#endif + + /* Signal the end of the file */ + *eof = 1; + + /* To get rid of the unused parameter warnings */ + (void)start; + (void)data; + (void)offset; + + return output_bytes; +} + +static int sah_write_procfs(struct file *file, const char __user * buffer, + unsigned long count, void *data) +{ + + /* Any write to this file will reset all counts. */ + dar_count = interrupt_count = done1done2_count = + done1busy2_count = done1_count = 0; + + (void)file; + (void)buffer; + (void)data; + + return count; +} + +#endif + +#ifndef SAHARA_POLL_MODE +/*! + * Block user call until processing is complete. + * + * @param entry The user's request. + * + * @return An OS error code, or 0 if no error + */ +int sah_blocking_mode(sah_Head_Desc * entry) +{ + int os_error_code = 0; + sah_Queue_Status status; + + /* queue entry, put something in the DAR, if nothing is there currently */ + sah_Queue_Manager_Append_Entry(entry); + + /* get this descriptor chain's current status */ + status = ((volatile sah_Head_Desc *)entry)->status; + + while (!SAH_DESC_PROCESSED(status)) { + extern sah_Queue *main_queue; + + DEFINE_WAIT(sahara_wait); /* create a wait queue entry. Linux */ + + /* enter the wait queue entry into the queue */ + prepare_to_wait(&Wait_queue, &sahara_wait, TASK_INTERRUPTIBLE); + + /* check if this entry has been processed */ + status = ((volatile sah_Head_Desc *)entry)->status; + + if (!SAH_DESC_PROCESSED(status)) { + /* go to sleep - Linux */ + schedule(); + } + + /* un-queue the 'prepare to wait' queue? - Linux */ + finish_wait(&Wait_queue, &sahara_wait); + + /* signal belongs to this thread? */ + if (signal_pending(current)) { /* Linux */ + os_lock_context_t lock_flags; + + /* don't allow access during this check and operation */ + os_lock_save_context(desc_queue_lock, lock_flags); + status = ((volatile sah_Head_Desc *)entry)->status; + if (status == SAH_STATE_PENDING) { + sah_Queue_Remove_Any_Entry(main_queue, entry); + entry->result = FSL_RETURN_INTERNAL_ERROR_S; + ((volatile sah_Head_Desc *)entry)->status = + SAH_STATE_FAILED; + } + os_unlock_restore_context(desc_queue_lock, lock_flags); + } + + status = ((volatile sah_Head_Desc *)entry)->status; + } /* while ... */ + + /* Do this so that caller can free */ + (void)sah_DePhysicalise_Descriptors(entry); + + return os_error_code; +} + +/*! + * If interrupt does not return in a reasonable time, time out, trigger + * interrupt, and continue with process + * + * @param data ignored + */ +void sahara_timeout_handler(unsigned long data) +{ + /* Sahara has not issuing an interrupt, so timed out */ +#ifdef DIAG_DRV_IF + LOG_KDIAG("Sahara HW did not respond. Resetting.\n"); +#endif + /* assume hardware needs resetting */ + sah_Handle_Interrupt(SAH_EXEC_FAULT); + /* wake up sleeping thread to try again */ + wake_up_interruptible(&Wait_queue); +} + +#endif /* ifndef SAHARA_POLL_MODE */ + +/* End of sah_driver_interface.c */ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/fsl_shw_user.c +++ linux-2.6.28/drivers/mxc/security/sahara2/fsl_shw_user.c @@ -0,0 +1,137 @@ +/* + * Copyright 2004-2008 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 + */ + +/*! + * @file fsl_shw_user.c + * + * This file implements user and platform capabilities functions of the FSL SHW + * API for Sahara + */ +#include "sahara.h" +#include +#include + +#ifdef __KERNEL__ +EXPORT_SYMBOL(fsl_shw_get_capabilities); +EXPORT_SYMBOL(fsl_shw_register_user); +EXPORT_SYMBOL(fsl_shw_deregister_user); +EXPORT_SYMBOL(fsl_shw_get_results); +#endif /* __KERNEL__ */ + +struct cap_t { + unsigned populated; + union { + uint32_t buffer[sizeof(fsl_shw_pco_t)]; + fsl_shw_pco_t pco; + }; +}; + +static struct cap_t cap = { + 0, + {} +}; + +/* REQ-S2LRD-PINTFC-API-GEN-003 */ +/*! + * Determine the hardware security capabilities of this platform. + * + * Though a user context object is passed into this function, it will always + * act in a non-blocking manner. + * + * @param user_ctx The user context which will be used for the query. + * + * @return A pointer to the capabilities object. + */ +fsl_shw_pco_t *fsl_shw_get_capabilities(fsl_shw_uco_t * user_ctx) +{ + fsl_shw_pco_t *retval = NULL; + + if (cap.populated) { + retval = &cap.pco; + } else { + if (get_capabilities(user_ctx, &cap.pco) == FSL_RETURN_OK_S) { + cap.populated = 1; + retval = &cap.pco; + } + } + return retval; +} + +/* REQ-S2LRD-PINTFC-API-GEN-004 */ + +/*! + * Create an association between the the user and the provider of the API. + * + * @param user_ctx The user context which will be used for this association. + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t fsl_shw_register_user(fsl_shw_uco_t * user_ctx) +{ + return sah_register(user_ctx); +} + +/* REQ-S2LRD-PINTFC-API-GEN-005 */ + +/*! + * Destroy the association between the the user and the provider of the API. + * + * @param user_ctx The user context which is no longer needed. + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t fsl_shw_deregister_user(fsl_shw_uco_t * user_ctx) +{ + return sah_deregister(user_ctx); +} + +/* REQ-S2LRD-PINTFC-API-GEN-006 */ + +/*! + * Retrieve results from earlier operations. + * + * @param user_ctx The user's context. + * @param result_size The number of array elements of @a results. + * @param[in,out] results Pointer to first of the (array of) locations to + * store results. + * @param[out] result_count Pointer to store the number of results which + * were returned. + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t fsl_shw_get_results(fsl_shw_uco_t * user_ctx, + unsigned result_size, + fsl_shw_result_t results[], + unsigned *result_count) +{ + fsl_shw_return_t status; + + /* perform a sanity check on the uco */ + status = sah_validate_uco(user_ctx); + + /* if uco appears ok, build structure and pass to get results */ + if (status == FSL_RETURN_OK_S) { + sah_results arg; + + /* if requested is zero, it's done before it started */ + if (result_size > 0) { + arg.requested = result_size; + arg.actual = result_count; + arg.results = results; + /* get the results */ + status = sah_get_results(&arg, user_ctx); + } + } + + return status; +} --- linux-2.6.28.orig/drivers/mxc/security/sahara2/sah_queue_manager.c +++ linux-2.6.28/drivers/mxc/security/sahara2/sah_queue_manager.c @@ -0,0 +1,1033 @@ +/* + * Copyright 2004-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 + */ + +/*! + * @file sah_queue_manager.c + * + * @brief This file provides a Queue Manager implementation. + * + * The Queue Manager manages additions and removal from the queue and updates + * the status of queue entries. It also calls sah_HW_* functions to interract + * with the hardware. +*/ + +#include "portable_os.h" + +/* SAHARA Includes */ +#include +#include +#include +#include +#if defined(DIAG_DRV_QUEUE) || defined(DIAG_DRV_STATUS) +#include +#endif +#include + +#ifdef DIAG_DRV_STATUS + +#define FSL_INVALID_RETURN 13 +#define MAX_RETURN_STRING_LEN 22 +#endif + +/* Defines for parsing value from Error Status register */ +#define SAH_STATUS_MASK 0x07 +#define SAH_ERROR_MASK 0x0F +#define SAH_CHA_ERR_SOURCE_MASK 0x07 +#define SAH_CHA_ERR_STATUS_MASK 0x0FFF +#define SAH_DMA_ERR_STATUS_MASK 0x0F +#define SAH_DMA_ERR_SIZE_MASK 0x03 +#define SAH_DMA_ERR_DIR_MASK 0x01 + +#define SHA_ERROR_STATUS_CONTINUE 0xFFFFFFFF +#define SHA_CHA_ERROR_STATUS_DONE 0xFFFFFFFF + +/* this maps the error status register's error source 4 bit field to the API + * return values. A 0xFFFFFFFF indicates additional fields must be checked to + * determine an appropriate return value */ +static sah_Execute_Error sah_Execute_Error_Array[] = { + FSL_RETURN_ERROR_S, /* SAH_ERR_NONE */ + FSL_RETURN_BAD_FLAG_S, /* SAH_ERR_HEADER */ + FSL_RETURN_BAD_DATA_LENGTH_S, /* SAH_ERR_DESC_LENGTH */ + FSL_RETURN_BAD_DATA_LENGTH_S, /* SAH_ERR_DESC_POINTER */ + FSL_RETURN_BAD_DATA_LENGTH_S, /* SAH_ERR_LINK_LENGTH */ + FSL_RETURN_BAD_DATA_LENGTH_S, /* SAH_ERR_LINK_POINTER */ + FSL_RETURN_INTERNAL_ERROR_S, /* SAH_ERR_INPUT_BUFFER */ + FSL_RETURN_INTERNAL_ERROR_S, /* SAH_ERR_OUTPUT_BUFFER */ + FSL_RETURN_BAD_DATA_LENGTH_S, /* SAH_ERR_OUTPUT_BUFFER_STARVATION */ + FSL_RETURN_INTERNAL_ERROR_S, /* SAH_ERR_INTERNAL_STATE */ + FSL_RETURN_ERROR_S, /* SAH_ERR_GENERAL_DESCRIPTOR */ + FSL_RETURN_INTERNAL_ERROR_S, /* SAH_ERR_RESERVED_FIELDS */ + FSL_RETURN_MEMORY_ERROR_S, /* SAH_ERR_DESCRIPTOR_ADDRESS */ + FSL_RETURN_MEMORY_ERROR_S, /* SAH_ERR_LINK_ADDRESS */ + SHA_ERROR_STATUS_CONTINUE, /* SAH_ERR_CHA */ + SHA_ERROR_STATUS_CONTINUE /* SAH_ERR_DMA */ +}; + +static sah_DMA_Error_Status sah_DMA_Error_Status_Array[] = { + FSL_RETURN_INTERNAL_ERROR_S, /* SAH_DMA_NO_ERR */ + FSL_RETURN_INTERNAL_ERROR_S, /* SAH_DMA_AHB_ERR */ + FSL_RETURN_INTERNAL_ERROR_S, /* SAH_DMA_IP_ERR */ + FSL_RETURN_INTERNAL_ERROR_S, /* SAH_DMA_PARITY_ERR */ + FSL_RETURN_BAD_DATA_LENGTH_S, /* SAH_DMA_BOUNDRY_ERR */ + FSL_RETURN_INTERNAL_ERROR_S, /* SAH_DMA_BUSY_ERR */ + FSL_RETURN_INTERNAL_ERROR_S, /* SAH_DMA_RESERVED_ERR */ + FSL_RETURN_INTERNAL_ERROR_S /* SAH_DMA_INT_ERR */ +}; + +static sah_CHA_Error_Status sah_CHA_Error_Status_Array[] = { + FSL_RETURN_INTERNAL_ERROR_S, /* SAH_CHA_NO_ERR */ + FSL_RETURN_BAD_DATA_LENGTH_S, /* SAH_CHA_IP_BUF */ + FSL_RETURN_INTERNAL_ERROR_S, /* SAH_CHA_ADD_ERR */ + FSL_RETURN_BAD_MODE_S, /* SAH_CHA_MODE_ERR */ + FSL_RETURN_BAD_DATA_LENGTH_S, /* SAH_CHA_DATA_SIZE_ERR */ + FSL_RETURN_BAD_KEY_LENGTH_S, /* SAH_CHA_KEY_SIZE_ERR */ + FSL_RETURN_BAD_MODE_S, /* SAH_CHA_PROC_ERR */ + FSL_RETURN_ERROR_S, /* SAH_CHA_CTX_READ_ERR */ + FSL_RETURN_INTERNAL_ERROR_S, /* SAH_CHA_INTERNAL_HW_ERR */ + FSL_RETURN_MEMORY_ERROR_S, /* SAH_CHA_IP_BUFF_ERR */ + FSL_RETURN_MEMORY_ERROR_S, /* SAH_CHA_OP_BUFF_ERR */ + FSL_RETURN_BAD_KEY_PARITY_S, /* SAH_CHA_DES_KEY_ERR */ + FSL_RETURN_INTERNAL_ERROR_S, /* SAH_CHA_RES */ +}; + +#ifdef DIAG_DRV_STATUS + +char sah_return_text[FSL_INVALID_RETURN][MAX_RETURN_STRING_LEN] = { + "No error", /* FSL_RETURN_OK_S */ + "Error", /* FSL_RETURN_ERROR_S */ + "No resource", /* FSL_RETURN_NO_RESOURCE_S */ + "Bad algorithm", /* FSL_RETURN_BAD_ALGORITHM_S */ + "Bad mode", /* FSL_RETURN_BAD_MODE_S */ + "Bad flag", /* FSL_RETURN_BAD_FLAG_S */ + "Bad key length", /* FSL_RETURN_BAD_KEY_LENGTH_S */ + "Bad key parity", /* FSL_RETURN_BAD_KEY_PARITY_S */ + "Bad data length", /* FSL_RETURN_BAD_DATA_LENGTH_S */ + "Authentication failed", /* FSL_RETURN_AUTH_FAILED_S */ + "Memory error", /* FSL_RETURN_MEMORY_ERROR_S */ + "Internal error", /* FSL_RETURN_INTERNAL_ERROR_S */ + "unknown value", /* default */ +}; + +#endif /* DIAG_DRV_STATUS */ + +/*! + * This lock must be held while performing any queuing or unqueuing functions, + * including reading the first pointer on the queue. It also protects reading + * and writing the Sahara DAR register. It must be held during a read-write + * operation on the DAR so that the 'test-and-set' is atomic. + */ +os_lock_t desc_queue_lock; + +/*! This is the main queue for the driver. This is shared between all threads + * and is not protected by mutexes since the kernel is non-preemptable. */ +sah_Queue *main_queue = NULL; + +/* Internal Prototypes */ +sah_Head_Desc *sah_Find_With_State(sah_Queue_Status state); + +#ifdef DIAG_DRV_STATUS +void sah_Log_Error(uint32_t descriptor, uint32_t error, uint32_t fault_address); +#endif + +extern wait_queue_head_t *int_queue; + +/*! + * This function initialises the Queue Manager + * + * @brief Initialise the Queue Manager + * + * @return FSL_RETURN_OK_S on success; FSL_RETURN_MEMORY_ERROR_S if not + */ +fsl_shw_return_t sah_Queue_Manager_Init(void) +{ + fsl_shw_return_t ret_val = FSL_RETURN_OK_S; + + desc_queue_lock = os_lock_alloc_init(); + + if (main_queue == NULL) { + /* Construct the main queue. */ + main_queue = sah_Queue_Construct(); + + if (main_queue == NULL) { + ret_val = FSL_RETURN_MEMORY_ERROR_S; + } + } else { +#ifdef DIAG_DRV_QUEUE + LOG_KDIAG + ("Trying to initialise the queue manager more than once."); +#endif + } + + return ret_val; +} + +/*! + * This function closes the Queue Manager + * + * @brief Close the Queue Manager + * + * @return void + */ +void sah_Queue_Manager_Close(void) +{ +#ifdef DIAG_DRV_QUEUE + if (main_queue && main_queue->count != 0) { + LOG_KDIAG + ("Trying to close the main queue when it is not empty."); + } +#endif + + if (main_queue) { + /* There is no error checking here because there is no way to handle + it. */ + sah_Queue_Destroy(main_queue); + main_queue = NULL; + } +} + +/*! + * Count the number of entries on the Queue Manager's queue + * + * @param ignore_state If non-zero, the @a state parameter is ignored. + * If zero, only entries matching @a state are counted. + * @param state State of entry to match for counting. + * + * @return Number of entries which matched criteria + */ +int sah_Queue_Manager_Count_Entries(int ignore_state, sah_Queue_Status state) +{ + int count = 0; + sah_Head_Desc *current_entry; + + /* Start at the head */ + current_entry = main_queue->head; + while (current_entry != NULL) { + if (ignore_state || (current_entry->status == state)) { + count++; + } + /* Jump to the next entry. */ + current_entry = current_entry->next; + } + + return count; +} + +/*! + * This function removes an entry from the Queue Manager's queue. The entry to + * be removed can be anywhere in the queue. + * + * @brief Remove an entry from the Queue Manager's queue. + * + * @param entry A pointer to a sah_Head_Desc to remove from the Queue + * Manager's queue. + * + * @pre The #desc_queue_lock must be held before calling this function. + * + * @return void + */ +void sah_Queue_Manager_Remove_Entry(sah_Head_Desc * entry) +{ + if (entry == NULL) { +#ifdef DIAG_DRV_QUEUE + LOG_KDIAG("NULL pointer input."); +#endif + } else { + sah_Queue_Remove_Any_Entry(main_queue, entry); + } +} + +/*! + * This function appends an entry to the Queue Managers queue. It primes SAHARA + * if this entry is the first PENDING entry in the Queue Manager's Queue. + * + * @brief Appends an entry to the Queue Manager's queue. + * + * @param entry A pointer to a sah_Head_Desc to append to the Queue + * Manager's queue. + * + * @pre The #desc_queue_lock may not may be held when calling this function. + * + * @return void + */ +void sah_Queue_Manager_Append_Entry(sah_Head_Desc * entry) +{ + sah_Head_Desc *current_entry; + os_lock_context_t int_flags; + +#ifdef DIAG_DRV_QUEUE + if (entry == NULL) { + LOG_KDIAG("NULL pointer input."); + } +#endif + entry->status = SAH_STATE_PENDING; + os_lock_save_context(desc_queue_lock, int_flags); + sah_Queue_Append_Entry(main_queue, entry); + + /* Prime SAHARA if the operation that was just appended is the only PENDING + * operation in the queue. + */ + current_entry = sah_Find_With_State(SAH_STATE_PENDING); + if (current_entry != NULL) { + if (current_entry == entry) { + sah_Queue_Manager_Prime(entry); + } + } + + os_unlock_restore_context(desc_queue_lock, int_flags); +} + +/*! + * This function marks all entries in the Queue Manager's queue with state + * SAH_STATE_RESET. + * + * @brief Mark all entries with state SAH_STATE_RESET + * + * @return void + * + * @note This feature needs re-visiting + */ +void sah_Queue_Manager_Reset_Entries(void) +{ + sah_Head_Desc *current_entry = NULL; + + /* Start at the head */ + current_entry = main_queue->head; + + while (current_entry != NULL) { + /* Set the state. */ + current_entry->status = SAH_STATE_RESET; + /* Jump to the next entry. */ + current_entry = current_entry->next; + } +} + +/*! + * This function primes SAHARA for the first time or after the queue becomes + * empty. Queue lock must have been set by the caller of this routine. + * + * @brief Prime SAHARA. + * + * @param entry A pointer to a sah_Head_Desc to Prime SAHARA with. + * + * @return void + */ +void sah_Queue_Manager_Prime(sah_Head_Desc * entry) +{ +#ifdef DIAG_DRV_QUEUE + LOG_KDIAG("Priming SAHARA"); + if (entry == NULL) { + LOG_KDIAG("Trying to prime SAHARA with a NULL entry pointer."); + } +#endif + +#ifndef SUBMIT_MULTIPLE_DARS + /* BUG FIX: state machine can transition from Done1 Busy2 directly + * to Idle. To fix that problem, only one DAR is being allowed on + * SAHARA at a time */ + if (sah_Find_With_State(SAH_STATE_ON_SAHARA) != NULL) { + return; + } +#endif + +#ifdef SAHARA_POWER_MANAGEMENT + /* check that dynamic power management is not asserted */ + if (!sah_dpm_flag) { +#endif + /* Make sure nothing is in the DAR */ + if (sah_HW_Read_DAR() == 0) { +#if defined(DIAG_DRV_IF) + sah_Dump_Chain(&entry->desc, entry->desc.dma_addr); +#endif /* DIAG_DRV_IF */ + + sah_HW_Write_DAR((entry->desc.dma_addr)); + entry->status = SAH_STATE_ON_SAHARA; + } +#ifdef DIAG_DRV_QUEUE + else { + LOG_KDIAG("DAR should be empty when Priming SAHARA"); + } +#endif +#ifdef SAHARA_POWER_MANAGEMENT + } +#endif +} + +#ifndef SAHARA_POLL_MODE + +/*! + * Reset SAHARA, then load the next descriptor on it, if one exists + */ +void sah_reset_sahara_request(void) +{ + sah_Head_Desc *desc; + os_lock_context_t lock_flags; + +#ifdef DIAG_DRV_STATUS + LOG_KDIAG("Sahara required reset from tasklet, replace chip"); +#endif + sah_HW_Reset(); + + /* Now stick in a waiting request */ + os_lock_save_context(desc_queue_lock, lock_flags); + if ((desc = sah_Find_With_State(SAH_STATE_PENDING))) { + sah_Queue_Manager_Prime(desc); + } + os_unlock_restore_context(desc_queue_lock, lock_flags); +} + +/*! + * Post-process a descriptor chain after the hardware has finished with it. + * + * The status of the descriptor could also be checked. (for FATAL or IGNORED). + * + * @param desc_head The finished chain + * @param error A boolean to mark whether hardware reported error + * + * @pre The #desc_queue_lock may not be held when calling this function. + */ +void sah_process_finished_request(sah_Head_Desc * desc_head, unsigned error) +{ + os_lock_context_t lock_flags; + + if (!error) { + desc_head->result = FSL_RETURN_OK_S; + } else if (desc_head->error_status == -1) { + /* Disaster! Sahara has faulted */ + desc_head->result = FSL_RETURN_ERROR_S; + } else { + /* translate from SAHARA error status to fsl_shw return values */ + desc_head->result = + sah_convert_error_status(desc_head->error_status); +#ifdef DIAG_DRV_STATUS + sah_Log_Error(desc_head->current_dar, desc_head->error_status, + desc_head->fault_address); +#endif + } + + /* Show that the request has been processd */ + desc_head->status = error ? SAH_STATE_FAILED : SAH_STATE_COMPLETE; + + if (desc_head->uco_flags & FSL_UCO_BLOCKING_MODE) { + + /* Wake up all processes on Sahara queue */ + wake_up_interruptible(int_queue); + + } else { + os_lock_save_context(desc_queue_lock, lock_flags); + sah_Queue_Append_Entry(&desc_head->user_info->result_pool, + desc_head); + os_unlock_restore_context(desc_queue_lock, lock_flags); + + /* perform callback */ + if (desc_head->uco_flags & FSL_UCO_CALLBACK_MODE) { + desc_head->user_info->callback(desc_head->user_info); + } + } +} /* sah_process_finished_request */ + +/*! Called from bottom half. + * + * @pre The #desc_queue_lock may not be held when calling this function. + */ +void sah_postprocess_queue(unsigned long reset_flag) +{ + + /* if SAHARA needs to be reset, do it here. This starts a descriptor chain + * if one is ready also */ + if (reset_flag) { + sah_reset_sahara_request(); + } + + /* now handle the descriptor chain(s) that has/have completed */ + do { + sah_Head_Desc *first_entry; + os_lock_context_t lock_flags; + + os_lock_save_context(desc_queue_lock, lock_flags); + + first_entry = main_queue->head; + if ((first_entry != NULL) && + (first_entry->status == SAH_STATE_OFF_SAHARA)) { + sah_Queue_Remove_Entry(main_queue); + os_unlock_restore_context(desc_queue_lock, lock_flags); + + sah_process_finished_request(first_entry, + (first_entry-> + error_status != 0)); + } else { + os_unlock_restore_context(desc_queue_lock, lock_flags); + break; + } + } while (1); + + return; +} + +#endif /* ifndef SAHARA_POLL_MODE */ + +/*! + * This is a helper function for Queue Manager. This function finds the first + * entry in the Queue Manager's queue whose state matches the given input + * state. This function starts at the head of the queue and works towards the + * tail. If a matching entry was found, the address of the entry is returned. + * + * @brief Handle the IDLE state. + * + * @param state A sah_Queue_Status value. + * + * @pre The #desc_queue_lock must be held before calling this function. + * + * @return A pointer to a sah_Head_Desc that matches the given state. + * @return NULL otherwise. + */ +sah_Head_Desc *sah_Find_With_State(sah_Queue_Status state) +{ + sah_Head_Desc *current_entry = NULL; + sah_Head_Desc *ret_val = NULL; + int done_looping = FALSE; + + /* Start at the head */ + current_entry = main_queue->head; + + while ((current_entry != NULL) && (done_looping == FALSE)) { + if (current_entry->status == state) { + done_looping = TRUE; + ret_val = current_entry; + } + /* Jump to the next entry. */ + current_entry = current_entry->next; + } + + return ret_val; +} /* sah_postprocess_queue */ + +/*! + * Process the value from the Sahara error status register and convert it into + * an FSL SHW API error code. + * + * Warning, this routine must only be called if an error exists. + * + * @param error_status The value from the error status register. + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t sah_convert_error_status(uint32_t error_status) +{ + fsl_shw_return_t ret = FSL_RETURN_ERROR_S; /* catchall */ + uint8_t error_source; + uint8_t DMA_error_status; + uint8_t DMA_error_size; + + /* get the error source from the error status register */ + error_source = error_status & SAH_ERROR_MASK; + + /* array size is maximum allowed by mask, so no boundary checking is + * needed here */ + ret = sah_Execute_Error_Array[error_source]; + + /* is this one that needs additional fields checked to determine the + * error condition? */ + if (ret == SHA_ERROR_STATUS_CONTINUE) { + /* check the DMA fields */ + if (error_source == SAH_ERR_DMA) { + /* get the DMA transfer error size. If this indicates that no + * error was detected, something is seriously wrong */ + DMA_error_size = + (error_status >> 9) & SAH_DMA_ERR_SIZE_MASK; + if (DMA_error_size == SAH_DMA_NO_ERR) { + ret = FSL_RETURN_INTERNAL_ERROR_S; + } else { + /* get DMA error status */ + DMA_error_status = (error_status >> 12) & + SAH_DMA_ERR_STATUS_MASK; + + /* the DMA error bits cover all the even numbers. By dividing + * by 2 it can be used as an index into the error array */ + ret = + sah_DMA_Error_Status_Array[DMA_error_status + >> 1]; + } + } else { /* not SAH_ERR_DMA, so must be SAH_ERR_CHA */ + uint16_t CHA_error_status; + uint8_t CHA_error_source; + + /* get CHA Error Source. If this indicates that no error was + * detected, something is seriously wrong */ + CHA_error_source = + (error_status >> 28) & SAH_CHA_ERR_SOURCE_MASK; + if (CHA_error_source == SAH_CHA_NO_ERROR) { + ret = FSL_RETURN_INTERNAL_ERROR_S; + } else { + uint32_t mask = 1; + uint32_t count = 0; + + /* get CHA Error Status */ + CHA_error_status = (error_status >> 16) & + SAH_CHA_ERR_STATUS_MASK; + + /* If more than one bit is set (which shouldn't happen), only + * the first will be captured */ + if (CHA_error_status != 0) { + count = 1; + while (CHA_error_status != mask) { + ++count; + mask <<= 1; + } + } + + ret = sah_CHA_Error_Status_Array[count]; + } + } + } + + return ret; +} + +fsl_shw_return_t sah_convert_op_status(uint32_t op_status) +{ + unsigned op_source = (op_status >> 28) & 0x7; + unsigned op_detail = op_status & 0x3f; + fsl_shw_return_t ret = FSL_RETURN_ERROR_S; + + switch (op_source) { + case 1: /* SKHA */ + /* Can't this have "ICV" error from CCM ?? */ + break; + case 2: /* MDHA */ + if (op_detail == 1) { + ret = FSL_RETURN_AUTH_FAILED_S; + } + break; + case 3: /* RNGA */ + /* Self-test and Compare errors... what to do? */ + break; + case 4: /* PKHA */ + switch (op_detail) { + case 0x01: + ret = FSL_RETURN_PRIME_S; + break; + case 0x02: + ret = FSL_RETURN_NOT_PRIME_S; + break; + case 0x04: + ret = FSL_RETURN_POINT_AT_INFINITY_S; + break; + case 0x08: + ret = FSL_RETURN_POINT_NOT_AT_INFINITY_S; + break; + case 0x10: + ret = FSL_RETURN_GCD_IS_ONE_S; + break; + case 0x20: + ret = FSL_RETURN_GCD_IS_NOT_ONE_S; + break; + default: + break; + } + break; + default: + break; + } + return ret; +} + +#ifdef DIAG_DRV_STATUS + +/*! + * This function logs the diagnostic information for the given error and + * descriptor address. Only used for diagnostic purposes. + * + * @brief (debug only) Log a description of hardware-detected error. + * + * @param descriptor The descriptor address that caused the error + * @param error The SAHARA error code + * @param fault_address Value from the Fault address register + * + * @return void + */ +void sah_Log_Error(uint32_t descriptor, uint32_t error, uint32_t fault_address) +{ + char *source_text; /* verbose error source from register */ + char *address; /* string buffer for descriptor address */ + char *error_log; /* the complete logging message */ + char *cha_log = NULL; /* string buffer for descriptor address */ + char *dma_log = NULL; /* string buffer for descriptor address */ + + uint16_t cha_error = 0; + uint16_t dma_error = 0; + + uint8_t error_source; + sah_Execute_Error return_code; + + /* log error code and descriptor address */ + error_source = error & SAH_ERROR_MASK; + return_code = sah_Execute_Error_Array[error_source]; + + source_text = os_alloc_memory(64, GFP_KERNEL); + + switch (error_source) { + case SAH_ERR_HEADER: + sprintf(source_text, "%s", "Header is not valid"); + break; + + case SAH_ERR_DESC_LENGTH: + sprintf(source_text, "%s", + "Descriptor length not equal to sum of link lengths"); + break; + + case SAH_ERR_DESC_POINTER: + sprintf(source_text, "%s", "Length or pointer " + "field is zero while the other is non-zero"); + break; + + case SAH_ERR_LINK_LENGTH: + /* note that the Sahara Block Guide 2.7 has an invalid explaination + * of this. It only happens when a link length is zero */ + sprintf(source_text, "%s", "A data length is a link is zero"); + break; + + case SAH_ERR_LINK_POINTER: + sprintf(source_text, "%s", + "The data pointer in a link is zero"); + break; + + case SAH_ERR_INPUT_BUFFER: + sprintf(source_text, "%s", "Input Buffer reported an overflow"); + break; + + case SAH_ERR_OUTPUT_BUFFER: + sprintf(source_text, "%s", + "Output Buffer reported an underflow"); + break; + + case SAH_ERR_OUTPUT_BUFFER_STARVATION: + sprintf(source_text, "%s", "Incorrect data in output " + "buffer after CHA has signalled 'done'"); + break; + + case SAH_ERR_INTERNAL_STATE: + sprintf(source_text, "%s", "Internal Hardware Failure"); + break; + + case SAH_ERR_GENERAL_DESCRIPTOR: + sprintf(source_text, "%s", + "Current Descriptor was not legal, but cause is unknown"); + break; + + case SAH_ERR_RESERVED_FIELDS: + sprintf(source_text, "%s", + "Reserved pointer field is non-zero"); + break; + + case SAH_ERR_DESCRIPTOR_ADDRESS: + sprintf(source_text, "%s", + "Descriptor address not word aligned"); + break; + + case SAH_ERR_LINK_ADDRESS: + sprintf(source_text, "%s", "Link address not word aligned"); + break; + + case SAH_ERR_CHA: + sprintf(source_text, "%s", "CHA Error"); + { + char *cha_module = os_alloc_memory(5, GFP_KERNEL); + char *cha_text = os_alloc_memory(45, GFP_KERNEL); + + cha_error = (error >> 28) & SAH_CHA_ERR_SOURCE_MASK; + + switch (cha_error) { + case SAH_CHA_SKHA_ERROR: + sprintf(cha_module, "%s", "SKHA"); + break; + + case SAH_CHA_MDHA_ERROR: + sprintf(cha_module, "%s", "MDHA"); + break; + + case SAH_CHA_RNG_ERROR: + sprintf(cha_module, "%s", "RNG "); + break; + + case SAH_CHA_PKHA_ERROR: + sprintf(cha_module, "%s", "PKHA"); + break; + + case SAH_CHA_NO_ERROR: + /* can't happen */ + /* no break */ + default: + sprintf(cha_module, "%s", "????"); + break; + } + + cha_error = (error >> 16) & SAH_CHA_ERR_STATUS_MASK; + + /* Log CHA Error Status */ + switch (cha_error) { + case SAH_CHA_IP_BUF: + sprintf(cha_text, "%s", + "Non-empty input buffer when done"); + break; + + case SAH_CHA_ADD_ERR: + sprintf(cha_text, "%s", "Illegal address"); + break; + + case SAH_CHA_MODE_ERR: + sprintf(cha_text, "%s", "Illegal mode"); + break; + + case SAH_CHA_DATA_SIZE_ERR: + sprintf(cha_text, "%s", "Illegal data size"); + break; + + case SAH_CHA_KEY_SIZE_ERR: + sprintf(cha_text, "%s", "Illegal key size"); + break; + + case SAH_CHA_PROC_ERR: + sprintf(cha_text, "%s", + "Mode/Context/Key written during processing"); + break; + + case SAH_CHA_CTX_READ_ERR: + sprintf(cha_text, "%s", + "Context read during processing"); + break; + + case SAH_CHA_INTERNAL_HW_ERR: + sprintf(cha_text, "%s", "Internal hardware"); + break; + + case SAH_CHA_IP_BUFF_ERR: + sprintf(cha_text, "%s", + "Input buffer not enabled or underflow"); + break; + + case SAH_CHA_OP_BUFF_ERR: + sprintf(cha_text, "%s", + "Output buffer not enabled or overflow"); + break; + + case SAH_CHA_DES_KEY_ERR: + sprintf(cha_text, "%s", "DES key parity error"); + break; + + case SAH_CHA_RES: + sprintf(cha_text, "%s", "Reserved"); + break; + + case SAH_CHA_NO_ERR: + /* can't happen */ + /* no break */ + default: + sprintf(cha_text, "%s", "Unknown error"); + break; + } + + cha_log = os_alloc_memory(90, GFP_KERNEL); + sprintf(cha_log, + " Module %s encountered the error: %s.", + cha_module, cha_text); + + os_free_memory(cha_module); + os_free_memory(cha_text); + + { + uint32_t mask = 1; + uint32_t count = 0; + + if (cha_error != 0) { + count = 1; + while (cha_error != mask) { + ++count; + mask <<= 1; + } + } + + return_code = sah_CHA_Error_Status_Array[count]; + } + cha_error = 1; + } + break; + + case SAH_ERR_DMA: + sprintf(source_text, "%s", "DMA Error"); + { + char *dma_direction = os_alloc_memory(6, GFP_KERNEL); + char *dma_size = os_alloc_memory(14, GFP_KERNEL); + char *dma_text = os_alloc_memory(250, GFP_KERNEL); + + if ((dma_direction == NULL) || (dma_size == NULL) || + (dma_text == NULL)) { + LOG_KDIAG + ("No memory allocated for DMA debug messages\n"); + } + + /* log DMA error direction */ + sprintf(dma_direction, "%s", + (((error >> 8) & SAH_DMA_ERR_DIR_MASK) == 1) ? + "read" : "write"); + + /* log the size of the DMA transfer error */ + dma_error = (error >> 9) & SAH_DMA_ERR_SIZE_MASK; + switch (dma_error) { + case SAH_DMA_SIZE_BYTE: + sprintf(dma_size, "%s", "byte"); + break; + + case SAH_DMA_SIZE_HALF_WORD: + sprintf(dma_size, "%s", "half-word"); + break; + + case SAH_DMA_SIZE_WORD: + sprintf(dma_size, "%s", "word"); + break; + + case SAH_DMA_SIZE_RES: + sprintf(dma_size, "%s", "reserved size"); + break; + + default: + sprintf(dma_size, "%s", "unknown size"); + break; + } + + /* log DMA error status */ + dma_error = (error >> 12) & SAH_DMA_ERR_STATUS_MASK; + switch (dma_error) { + case SAH_DMA_NO_ERR: + sprintf(dma_text, "%s", "No DMA Error Code"); + break; + + case SAH_DMA_AHB_ERR: + sprintf(dma_text, "%s", + "AHB terminated a bus cycle with an error"); + break; + + case SAH_DMA_IP_ERR: + sprintf(dma_text, "%s", + "Internal IP bus cycle was terminated with an " + "error termination. This would likely be " + "caused by a descriptor length being too " + "large, and thus accessing an illegal " + "internal address. Verify the length field " + "of the current descriptor"); + break; + + case SAH_DMA_PARITY_ERR: + sprintf(dma_text, "%s", + "Parity error detected on DMA command from " + "Descriptor Decoder. Cause is likely to be " + "internal hardware fault"); + break; + + case SAH_DMA_BOUNDRY_ERR: + sprintf(dma_text, "%s", + "DMA was requested to cross a 256 byte " + "internal address boundary. Cause is likely a " + "descriptor length being too large, thus " + "accessing two different internal hardware " + "blocks"); + break; + + case SAH_DMA_BUSY_ERR: + sprintf(dma_text, "%s", + "Descriptor Decoder has made a DMA request " + "while the DMA controller is busy. Cause is " + "likely due to hardware fault"); + break; + + case SAH_DMA_RESERVED_ERR: + sprintf(dma_text, "%s", "Reserved"); + break; + + case SAH_DMA_INT_ERR: + sprintf(dma_text, "%s", + "Internal DMA hardware error detected. The " + "DMA controller has detected an internal " + "condition which should never occur"); + break; + + default: + sprintf(dma_text, "%s", + "Unknown DMA Error Status Code"); + break; + } + + return_code = + sah_DMA_Error_Status_Array[dma_error >> 1]; + dma_error = 1; + + dma_log = os_alloc_memory(320, GFP_KERNEL); + sprintf(dma_log, + " Occurred during a %s operation of a %s transfer: %s.", + dma_direction, dma_size, dma_text); + + os_free_memory(dma_direction); + os_free_memory(dma_size); + os_free_memory(dma_text); + } + break; + + case SAH_ERR_NONE: + default: + sprintf(source_text, "%s", "Unknown Error Code"); + break; + } + + address = os_alloc_memory(35, GFP_KERNEL); + + /* convert error & descriptor address to strings */ + if (dma_error) { + sprintf(address, "Fault address is 0x%08x", fault_address); + } else { + sprintf(address, "Descriptor bus address is 0x%08x", + descriptor); + } + + if (return_code > FSL_INVALID_RETURN) { + return_code = FSL_INVALID_RETURN; + } + + error_log = os_alloc_memory(250, GFP_KERNEL); + + /* construct final log message */ + sprintf(error_log, "Error source = 0x%08x. Return = %s. %s. %s.", + error, sah_return_text[return_code], address, source_text); + + os_free_memory(source_text); + os_free_memory(address); + + /* log standard messages */ + LOG_KDIAG(error_log); + os_free_memory(error_log); + + /* add additional information if available */ + if (cha_error) { + LOG_KDIAG(cha_log); + os_free_memory(cha_log); + } + + if (dma_error) { + LOG_KDIAG(dma_log); + os_free_memory(dma_log); + } + + return; +} /* sah_Log_Error */ + +#endif /* DIAG_DRV_STATUS */ + +/* End of sah_queue_manager.c */ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/fsl_shw_hmac.c +++ linux-2.6.28/drivers/mxc/security/sahara2/fsl_shw_hmac.c @@ -0,0 +1,266 @@ +/* + * Copyright 2004-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 + */ + +/*! + * @file fsl_shw_hmac.c + * + * This file implements Hashed Message Authentication Code functions of the FSL + * SHW API for Sahara. + */ + +#include "sahara.h" +#include "sf_util.h" + +#ifdef __KERNEL__ +EXPORT_SYMBOL(fsl_shw_hmac_precompute); +EXPORT_SYMBOL(fsl_shw_hmac); +#endif + +/* REQ-S2LRD-PINTFC-API-BASIC-HMAC-001 */ +/*! + * Get the precompute information + * + * + * @param user_ctx + * @param key_info + * @param hmac_ctx + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t fsl_shw_hmac_precompute(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info, + fsl_shw_hmco_t * hmac_ctx) +{ + SAH_SF_DCLS; + + SAH_SF_USER_CHECK(); + + if ((key_info->algorithm != FSL_KEY_ALG_HMAC) || + (key_info->key_length > 64)) { + return FSL_RETURN_BAD_ALGORITHM_S; + } else if (key_info->key_length == 0) { + return FSL_RETURN_BAD_KEY_LENGTH_S; + } + + /* Set up to start the Inner Calculation */ + /* Desc. #8 w/IPAD, & INIT */ + header = SAH_HDR_MDHA_SET_MODE_HASH + ^ sah_insert_mdha_ipad + ^ sah_insert_mdha_init + ^ sah_insert_mdha_algorithm[hmac_ctx->algorithm]; + + DESC_KEY_OUT(header, key_info, + hmac_ctx->context_register_length, + (uint8_t *) hmac_ctx->inner_precompute); + + /* Set up for starting Outer calculation */ + /* exchange IPAD bit for OPAD bit */ + header ^= (sah_insert_mdha_ipad ^ sah_insert_mdha_opad); + + /* Theoretically, we can leave this link out and use the key which is + * already in the register... however, if we do, the resulting opad + * hash does not have the correct value when using the model. */ + DESC_KEY_OUT(header, key_info, + hmac_ctx->context_register_length, + (uint8_t *) hmac_ctx->outer_precompute); + + SAH_SF_EXECUTE(); + if (ret == FSL_RETURN_OK_S) { + /* flag that precomputes have been entered in this hco + * assume it'll first be used for initilizing */ + hmac_ctx->flags |= (FSL_HMAC_FLAGS_INIT | + FSL_HMAC_FLAGS_PRECOMPUTES_PRESENT); + } + + out: + SAH_SF_DESC_CLEAN(); + + return ret; +} + +/* REQ-S2LRD-PINTFC-API-BASIC-HMAC-002 */ +/*! + * Get the hmac + * + * + * @param user_ctx Info for acquiring memory + * @param key_info + * @param hmac_ctx + * @param msg + * @param length + * @param result + * @param result_len + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t fsl_shw_hmac(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info, + fsl_shw_hmco_t * hmac_ctx, + const uint8_t * msg, + uint32_t length, + uint8_t * result, uint32_t result_len) +{ + SAH_SF_DCLS; + + SAH_SF_USER_CHECK(); + + /* check flag consistency */ + /* Note that Final, Init, and Save are an illegal combination when a key + * is being used. Because of the logic flow of this routine, that is + * taken care of without being explict */ + if ( + /* nothing to work on */ + (((hmac_ctx->flags & FSL_HMAC_FLAGS_INIT) == 0) && + ((hmac_ctx->flags & FSL_HMAC_FLAGS_LOAD) == 0)) || + /* can't do both */ + ((hmac_ctx->flags & FSL_HMAC_FLAGS_INIT) && + (hmac_ctx->flags & FSL_HMAC_FLAGS_LOAD)) || + /* must be some output */ + (((hmac_ctx->flags & FSL_HMAC_FLAGS_SAVE) == 0) && + ((hmac_ctx->flags & FSL_HMAC_FLAGS_FINALIZE) == 0))) { + ret = FSL_RETURN_BAD_FLAG_S; + goto out; + } + + /* build descriptor #6 */ + + /* start building descriptor header */ + header = SAH_HDR_MDHA_SET_MODE_MD_KEY ^ + sah_insert_mdha_algorithm[hmac_ctx->algorithm] ^ + sah_insert_mdha_init; + + /* if this is to finalize the digest, mark to pad last block */ + if (hmac_ctx->flags & FSL_HMAC_FLAGS_FINALIZE) { + header ^= sah_insert_mdha_pdata; + } + + /* Check if this is a one shot */ + if ((hmac_ctx->flags & FSL_HMAC_FLAGS_INIT) && + (hmac_ctx->flags & FSL_HMAC_FLAGS_FINALIZE)) { + + header ^= sah_insert_mdha_hmac; + + /* See if this uses Precomputes */ + if (hmac_ctx->flags & FSL_HMAC_FLAGS_PRECOMPUTES_PRESENT) { + DESC_IN_IN(header, + hmac_ctx->context_register_length, + (uint8_t *) hmac_ctx->inner_precompute, + hmac_ctx->context_length, + (uint8_t *) hmac_ctx->outer_precompute); + } else { /* Precomputes not requested, try using Key */ + if (key_info->key != NULL) { + /* first, validate the key fields and related flag */ + if ((key_info->key_length == 0) + || (key_info->key_length > 64)) { + ret = FSL_RETURN_BAD_KEY_LENGTH_S; + goto out; + } else { + if (key_info->algorithm != + FSL_KEY_ALG_HMAC) { + ret = + FSL_RETURN_BAD_ALGORITHM_S; + goto out; + } + } + + /* finish building descriptor header (Key specific) */ + header ^= sah_insert_mdha_mac_full; + DESC_IN_KEY(header, 0, NULL, key_info); + } else { /* not using Key or Precomputes, so die */ + ret = FSL_RETURN_BAD_FLAG_S; + goto out; + } + } + } else { /* it's not a one shot, must be multi-step */ + /* this the last chunk? */ + if (hmac_ctx->flags & FSL_HMAC_FLAGS_FINALIZE) { + header ^= sah_insert_mdha_hmac; + DESC_IN_IN(header, + hmac_ctx->context_register_length, + (uint8_t *) hmac_ctx->ongoing_context, + hmac_ctx->context_length, + (uint8_t *) hmac_ctx->outer_precompute); + } else { /* not last chunk */ + uint8_t *ptr1; + + if (hmac_ctx->flags & FSL_HMAC_FLAGS_INIT) { + /* must be using precomputes, cannot 'chunk' message + * starting with a key */ + if (hmac_ctx-> + flags & FSL_HMAC_FLAGS_PRECOMPUTES_PRESENT) + { + ptr1 = + (uint8_t *) hmac_ctx-> + inner_precompute; + } else { + ret = FSL_RETURN_NO_RESOURCE_S; + goto out; + } + } else { + ptr1 = (uint8_t *) hmac_ctx->ongoing_context; + } + + if (ret != FSL_RETURN_OK_S) { + goto out; + } + DESC_IN_IN(header, + hmac_ctx->context_register_length, ptr1, + 0, NULL); + } + } /* multi-step */ + + /* build descriptor #10 & maybe 11 */ + header = SAH_HDR_MDHA_HASH; + + if (hmac_ctx->flags & FSL_HMAC_FLAGS_FINALIZE) { + /* check that the results parameters seem reasonable */ + if ((result_len != 0) && (result != NULL)) { + if (result_len > hmac_ctx->context_register_length) { + result_len = hmac_ctx->context_register_length; + } + + /* message in / digest out (descriptor #10) */ + DESC_IN_OUT(header, length, msg, result_len, result); + + /* see if descriptor #11 needs to be built */ + if (hmac_ctx->flags & FSL_HMAC_FLAGS_SAVE) { + header = SAH_HDR_MDHA_STORE_DIGEST; + /* nothing in / context out */ + DESC_IN_IN(header, 0, NULL, + hmac_ctx->context_register_length, + (uint8_t *) hmac_ctx-> + ongoing_context); + } + } else { + /* something wrong with result or its length */ + ret = FSL_RETURN_BAD_DATA_LENGTH_S; + } + } else { /* finalize not set, so store in ongoing context field */ + if ((length % 64) == 0) { /* this will change for 384/512 support */ + /* message in / context out */ + DESC_IN_OUT(header, length, msg, + hmac_ctx->context_register_length, + (uint8_t *) hmac_ctx->ongoing_context); + } else { + /* not final data, and not multiple of block length */ + ret = FSL_RETURN_BAD_DATA_LENGTH_S; + } + } + + SAH_SF_EXECUTE(); + + out: + SAH_SF_DESC_CLEAN(); + + return ret; +} /* fsl_shw_hmac() */ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/fsl_shw_keystore.c +++ linux-2.6.28/drivers/mxc/security/sahara2/fsl_shw_keystore.c @@ -0,0 +1,837 @@ +/* + * Copyright 2008-2009 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 + */ + +/** + * @file fsl_shw_keystore.c + * + * File which implements a default keystore policy, for use as the system + * keystore. + */ +#include "fsl_platform.h" +#include "fsl_shw.h" +#include "fsl_shw_keystore.h" + +#if defined(DIAG_DRV_IF) +#include +#endif + +#if !defined(FSL_HAVE_SCC2) && defined(__KERNEL__) +#include +#endif + +/* Define a semaphore to protect the keystore data */ +#ifdef __KERNEL__ +#define LOCK_INCLUDES os_lock_context_t context +#define ACQUIRE_LOCK os_lock_save_context(keystore->lock, context) +#define RELEASE_LOCK os_unlock_restore_context(keystore->lock, context); +#else +#define LOCK_INCLUDES +#define ACQUIRE_LOCK +#define RELEASE_LOCK +#endif /* __KERNEL__ */ + +/*! + * Calculates the byte offset into a word + * @param bp The byte (char*) pointer + * @return The offset (0, 1, 2, or 3) + */ +#define SCC_BYTE_OFFSET(bp) ((uint32_t)(bp) % sizeof(uint32_t)) + +/*! + * Converts (by rounding down) a byte pointer into a word pointer + * @param bp The byte (char*) pointer + * @return The word (uint32_t) as though it were an aligned (uint32_t*) + */ +#define SCC_WORD_PTR(bp) (((uint32_t)(bp)) & ~(sizeof(uint32_t)-1)) + +/* Depending on the architecture, these functions should be defined + * differently. On Platforms with SCC2, the functions use the secure + * partition interface and should be available in both user and kernel space. + * On platforms with SCC, they use the SCC keystore interface. This is only + * available in kernel mode, so they should be stubbed out in user mode. + */ +#if defined(FSL_HAVE_SCC2) || (defined(FSL_HAVE_SCC) && defined(__KERNEL__)) +EXPORT_SYMBOL(fsl_shw_init_keystore); +void fsl_shw_init_keystore( + fsl_shw_kso_t *keystore, + fsl_shw_return_t(*data_init) (fsl_shw_uco_t *user_ctx, + void **user_data), + void (*data_cleanup) (fsl_shw_uco_t *user_ctx, + void **user_data), + fsl_shw_return_t(*slot_alloc) (void *user_data, + uint32_t size, + uint64_t owner_id, + uint32_t *slot), + fsl_shw_return_t(*slot_dealloc) (void *user_data, + uint64_t + owner_id, + uint32_t slot), + fsl_shw_return_t(*slot_verify_access) (void + *user_data, + uint64_t + owner_id, + uint32_t + slot), + void *(*slot_get_address) (void *user_data, + uint32_t handle), + uint32_t(*slot_get_base) (void *user_data, + uint32_t handle), + uint32_t(*slot_get_offset) (void *user_data, + uint32_t handle), + uint32_t(*slot_get_slot_size) (void *user_data, + uint32_t handle)) +{ + keystore->data_init = data_init; + keystore->data_cleanup = data_cleanup; + keystore->slot_alloc = slot_alloc; + keystore->slot_dealloc = slot_dealloc; + keystore->slot_verify_access = slot_verify_access; + keystore->slot_get_address = slot_get_address; + keystore->slot_get_base = slot_get_base; + keystore->slot_get_offset = slot_get_offset; + keystore->slot_get_slot_size = slot_get_slot_size; +} + +EXPORT_SYMBOL(fsl_shw_init_keystore_default); +void fsl_shw_init_keystore_default(fsl_shw_kso_t *keystore) +{ + keystore->data_init = shw_kso_init_data; + keystore->data_cleanup = shw_kso_cleanup_data; + keystore->slot_alloc = shw_slot_alloc; + keystore->slot_dealloc = shw_slot_dealloc; + keystore->slot_verify_access = shw_slot_verify_access; + keystore->slot_get_address = shw_slot_get_address; + keystore->slot_get_base = shw_slot_get_base; + keystore->slot_get_offset = shw_slot_get_offset; + keystore->slot_get_slot_size = shw_slot_get_slot_size; +} + +/*! + * Do any keystore specific initializations + */ +EXPORT_SYMBOL(fsl_shw_establish_keystore); +fsl_shw_return_t fsl_shw_establish_keystore(fsl_shw_uco_t *user_ctx, + fsl_shw_kso_t *keystore) +{ + if (keystore->data_init == NULL) { + return FSL_RETURN_ERROR_S; + } + + /* Call the data_init function for any user setup */ + return keystore->data_init(user_ctx, &(keystore->user_data)); +} + +EXPORT_SYMBOL(fsl_shw_release_keystore); +void fsl_shw_release_keystore(fsl_shw_uco_t *user_ctx, + fsl_shw_kso_t *keystore) +{ + + /* Call the data_cleanup function for any keystore cleanup. + * NOTE: The keystore doesn't have any way of telling which keys are using + * it, so it is up to the user program to manage their key objects + * correctly. + */ + if ((keystore != NULL) && (keystore->data_cleanup != NULL)) { + keystore->data_cleanup(user_ctx, &(keystore->user_data)); + } + return; +} + +fsl_shw_return_t keystore_slot_alloc(fsl_shw_kso_t *keystore, uint32_t size, + uint64_t owner_id, uint32_t *slot) +{ + LOCK_INCLUDES; + fsl_shw_return_t retval = FSL_RETURN_ERROR_S; + +#ifdef DIAG_DRV_IF + LOG_DIAG("In keystore_slot_alloc."); + +#endif + ACQUIRE_LOCK; + if ((keystore->slot_alloc == NULL) || (keystore->user_data == NULL)) { + goto out; + } + +#ifdef DIAG_DRV_IF + LOG_DIAG_ARGS("key length: %i, handle: %i\n", size, *slot); + +#endif +retval = keystore->slot_alloc(keystore->user_data, size, owner_id, slot); +out:RELEASE_LOCK; + return retval; +} + +fsl_shw_return_t keystore_slot_dealloc(fsl_shw_kso_t *keystore, + uint64_t owner_id, uint32_t slot) +{ + LOCK_INCLUDES; + fsl_shw_return_t retval = FSL_RETURN_ERROR_S; + ACQUIRE_LOCK; + if ((keystore->slot_alloc == NULL) || (keystore->user_data == NULL)) { + goto out; + } + retval = + keystore->slot_dealloc(keystore->user_data, owner_id, slot); +out:RELEASE_LOCK; + return retval; +} + +fsl_shw_return_t +keystore_slot_load(fsl_shw_kso_t * keystore, uint64_t owner_id, uint32_t slot, + const uint8_t * key_data, uint32_t key_length) +{ + +#ifdef FSL_HAVE_SCC2 + LOCK_INCLUDES; + fsl_shw_return_t retval = FSL_RETURN_ERROR_S; + uint32_t slot_size; + uint32_t i; + uint8_t * slot_location; + ACQUIRE_LOCK; + if ((keystore->slot_verify_access == NULL) || + (keystore->user_data == NULL)) + goto out; + if (keystore-> + slot_verify_access(keystore->user_data, owner_id, + slot) !=FSL_RETURN_OK_S) { + retval = FSL_RETURN_AUTH_FAILED_S; + goto out; + } + slot_size = keystore->slot_get_slot_size(keystore->user_data, slot); + if (key_length > slot_size) { + retval = FSL_RETURN_BAD_DATA_LENGTH_S; + goto out; + } + slot_location = keystore->slot_get_address(keystore->user_data, slot); + for (i = 0; i < key_length; i++) { + slot_location[i] = key_data[i]; + } + retval = FSL_RETURN_OK_S; +out:RELEASE_LOCK; + return retval; + +#else /* FSL_HAVE_SCC2 */ + fsl_shw_return_t retval; + scc_return_t scc_ret; + scc_ret = + scc_load_slot(owner_id, slot, (uint8_t *) key_data, key_length); + switch (scc_ret) { + case SCC_RET_OK: + retval = FSL_RETURN_OK_S; + break; + case SCC_RET_VERIFICATION_FAILED: + retval = FSL_RETURN_AUTH_FAILED_S; + break; + case SCC_RET_INSUFFICIENT_SPACE: + retval = FSL_RETURN_BAD_DATA_LENGTH_S; + break; + default: + retval = FSL_RETURN_ERROR_S; + } + return retval; + +#endif /* FSL_HAVE_SCC2 */ +} + +fsl_shw_return_t +keystore_slot_read(fsl_shw_kso_t * keystore, uint64_t owner_id, uint32_t slot, + uint32_t key_length, uint8_t * key_data) +{ +#ifdef FSL_HAVE_SCC2 + fsl_shw_return_t retval = FSL_RETURN_ERROR_S; + uint8_t *slot_addr; + uint32_t slot_size; + + slot_addr = keystore->slot_get_address(keystore->user_data, slot); + slot_size = keystore->slot_get_slot_size(keystore->user_data, slot); + + if (key_length > slot_size) { + retval = FSL_RETURN_BAD_KEY_LENGTH_S; + goto out; + } + + memcpy(key_data, slot_addr, key_length); + retval = FSL_RETURN_OK_S; + + out: + return retval; + +#else /* Have SCC2 */ + fsl_shw_return_t retval = FSL_RETURN_ERROR_S; + scc_return_t scc_ret; + printk("keystore SCC \n"); + + scc_ret = + scc_read_slot(owner_id, slot, key_length, (uint8_t *) key_data); + printk("keystore SCC Ret value: %d \n", scc_ret); + switch (scc_ret) { + case SCC_RET_OK: + retval = FSL_RETURN_OK_S; + break; + case SCC_RET_VERIFICATION_FAILED: + retval = FSL_RETURN_AUTH_FAILED_S; + break; + case SCC_RET_INSUFFICIENT_SPACE: + retval = FSL_RETURN_BAD_DATA_LENGTH_S; + break; + default: + retval = FSL_RETURN_ERROR_S; + } + + return retval; + +#endif /* FSL_HAVE_SCC2 */ +}/* end fn keystore_slot_read */ + +fsl_shw_return_t +keystore_slot_encrypt(fsl_shw_uco_t *user_ctx, fsl_shw_kso_t *keystore, + uint64_t owner_id, uint32_t slot, uint32_t length, + uint8_t *destination) +{ + +#ifdef FSL_HAVE_SCC2 + LOCK_INCLUDES; + fsl_shw_return_t retval = FSL_RETURN_ERROR_S; + uint32_t slot_length; + uint32_t IV[4]; + uint32_t * iv_ptr = (uint32_t *) & (owner_id); + + /* Build the IV */ + IV[0] = iv_ptr[0]; + IV[1] = iv_ptr[1]; + IV[2] = 0; + IV[3] = 0; + ACQUIRE_LOCK; + + /* Ensure that the data will fit in the key slot */ + slot_length = + keystore->slot_get_slot_size(keystore->user_data, slot); + if (length > slot_length) { + goto out; + } + + /* Call scc encrypt function to encrypt the data. */ + retval = do_scc_encrypt_region(user_ctx, + (void *)keystore-> + slot_get_base(keystore->user_data, + slot), + keystore->slot_get_offset(keystore-> + user_data, + slot), + length, destination, IV, + FSL_SHW_CYPHER_MODE_CBC); + goto out; +out:RELEASE_LOCK; + return retval; + +#else + scc_return_t retval; + retval = scc_encrypt_slot(owner_id, slot, length, destination); + if (retval == SCC_RET_OK) + return FSL_RETURN_OK_S; + return FSL_RETURN_ERROR_S; + +#endif /* FSL_HAVE_SCC2 */ +} + +fsl_shw_return_t +keystore_slot_decrypt(fsl_shw_uco_t *user_ctx, fsl_shw_kso_t *keystore, + uint64_t owner_id, uint32_t slot, uint32_t length, + const uint8_t *source) +{ + +#ifdef FSL_HAVE_SCC2 + LOCK_INCLUDES; + fsl_shw_return_t retval = FSL_RETURN_ERROR_S; + uint32_t slot_length; + uint32_t IV[4]; + uint32_t *iv_ptr = (uint32_t *) & (owner_id); + + /* Build the IV */ + IV[0] = iv_ptr[0]; + IV[1] = iv_ptr[1]; + IV[2] = 0; + IV[3] = 0; + ACQUIRE_LOCK; + + /* Call scc decrypt function to decrypt the data. */ + + /* Ensure that the data will fit in the key slot */ + slot_length = + keystore->slot_get_slot_size(keystore->user_data, slot); + if (length > slot_length) + goto out; + + /* Call scc decrypt function to encrypt the data. */ + retval = do_scc_decrypt_region(user_ctx, + (void *)keystore-> + slot_get_base(keystore->user_data, + slot), + keystore->slot_get_offset(keystore-> + user_data, + slot), + length, source, IV, + FSL_SHW_CYPHER_MODE_CBC); + goto out; +out:RELEASE_LOCK; + return retval; + +#else + scc_return_t retval; + retval = scc_decrypt_slot(owner_id, slot, length, source); + if (retval == SCC_RET_OK) + return FSL_RETURN_OK_S; + return FSL_RETURN_ERROR_S; + +#endif /* FSL_HAVE_SCC2 */ +} + +#else /* SCC in userspace */ +void fsl_shw_init_keystore( + fsl_shw_kso_t *keystore, + fsl_shw_return_t(*data_init) (fsl_shw_uco_t *user_ctx, + void **user_data), + void (*data_cleanup) (fsl_shw_uco_t *user_ctx, + void **user_data), + fsl_shw_return_t(*slot_alloc) (void *user_data, + uint32_t size, + uint64_t owner_id, + uint32_t *slot), + fsl_shw_return_t(*slot_dealloc) (void *user_data, + uint64_t + owner_id, + uint32_t slot), + fsl_shw_return_t(*slot_verify_access) (void + *user_data, + uint64_t + owner_id, + uint32_t + slot), + void *(*slot_get_address) (void *user_data, + uint32_t handle), + uint32_t(*slot_get_base) (void *user_data, + uint32_t handle), + uint32_t(*slot_get_offset) (void *user_data, + uint32_t handle), + uint32_t(*slot_get_slot_size) (void *user_data, + uint32_t handle)) +{ + (void)keystore; + (void)data_init; + (void)data_cleanup; + (void)slot_alloc; + (void)slot_dealloc; + (void)slot_verify_access; + (void)slot_get_address; + (void)slot_get_base; + (void)slot_get_offset; + (void)slot_get_slot_size; +} + +void fsl_shw_init_keystore_default(fsl_shw_kso_t * keystore) +{ + (void)keystore; +} +fsl_shw_return_t fsl_shw_establish_keystore(fsl_shw_uco_t *user_ctx, + fsl_shw_kso_t *keystore) +{ + (void)user_ctx; + (void)keystore; + return FSL_RETURN_NO_RESOURCE_S; +} +void fsl_shw_release_keystore(fsl_shw_uco_t *user_ctx, + fsl_shw_kso_t *keystore) +{ + (void)user_ctx; + (void)keystore; + return; +} + +fsl_shw_return_t keystore_slot_alloc(fsl_shw_kso_t *keystore, uint32_t size, + uint64_t owner_id, uint32_t *slot) +{ + (void)keystore; + (void)size; + (void)owner_id; + (void)slot; + return FSL_RETURN_NO_RESOURCE_S; +} + +fsl_shw_return_t keystore_slot_dealloc(fsl_shw_kso_t *keystore, + uint64_t owner_id, uint32_t slot) +{ + (void)keystore; + (void)owner_id; + (void)slot; + return FSL_RETURN_NO_RESOURCE_S; +} + +fsl_shw_return_t +keystore_slot_load(fsl_shw_kso_t *keystore, uint64_t owner_id, uint32_t slot, + const uint8_t *key_data, uint32_t key_length) +{ + (void)keystore; + (void)owner_id; + (void)slot; + (void)key_data; + (void)key_length; + return FSL_RETURN_NO_RESOURCE_S; +} + +fsl_shw_return_t +keystore_slot_read(fsl_shw_kso_t * keystore, uint64_t owner_id, uint32_t slot, + uint32_t key_length, uint8_t * key_data) +{ + (void)keystore; + (void)owner_id; + (void)slot; + (void)key_length; + (void)key_data; + + return FSL_RETURN_NO_RESOURCE_S; +} + +fsl_shw_return_t +keystore_slot_decrypt(fsl_shw_uco_t *user_ctx, fsl_shw_kso_t *keystore, + uint64_t owner_id, uint32_t slot, uint32_t length, + const uint8_t *source) +{ + (void)user_ctx; + (void)keystore; + (void)owner_id; + (void)slot; + (void)length; + (void)source; + return FSL_RETURN_NO_RESOURCE_S; +} + +fsl_shw_return_t +keystore_slot_encrypt(fsl_shw_uco_t *user_ctx, fsl_shw_kso_t *keystore, + uint64_t owner_id, uint32_t slot, uint32_t length, + uint8_t *destination) +{ + (void)user_ctx; + (void)keystore; + (void)owner_id; + (void)slot; + (void)length; + (void)destination; + return FSL_RETURN_NO_RESOURCE_S; +} + + +#endif /* FSL_HAVE_SCC2 */ + +/***** Default keystore implementation **************************************/ + +#ifdef FSL_HAVE_SCC2 + fsl_shw_return_t shw_kso_init_data(fsl_shw_uco_t *user_ctx, + void **user_data) +{ + int retval = FSL_RETURN_ERROR_S; + keystore_data_t *keystore_data = NULL; + fsl_shw_pco_t *capabilities = fsl_shw_get_capabilities(user_ctx); + uint32_t partition_size; + uint32_t slot_count; + uint32_t keystore_data_size; + uint8_t UMID[16] = { + 0x42, 0, 0, 0, 0x43, 0, 0, 0, 0x19, 0, 0, 0, 0x59, 0, 0, 0}; + uint32_t permissions = + FSL_PERM_TH_R | FSL_PERM_TH_W | FSL_PERM_HD_R | FSL_PERM_HD_W | + FSL_PERM_HD_X; + + /* Look up the size of a partition to see how big to make the keystore */ + partition_size = fsl_shw_pco_get_spo_size_bytes(capabilities); + + /* Calculate the required size of the keystore data structure, based on the + * number of keys that can fit in the partition. + */ + slot_count = partition_size / KEYSTORE_SLOT_SIZE; + keystore_data_size = + sizeof(keystore_data_t) + + slot_count * sizeof(keystore_data_slot_info_t); + +#ifdef __KERNEL__ + keystore_data = os_alloc_memory(keystore_data_size, GFP_KERNEL); + +#else + keystore_data = malloc(keystore_data_size); + +#endif + if (keystore_data == NULL) { + retval = FSL_RETURN_NO_RESOURCE_S; + goto out; + } + + /* Clear the memory (effectively clear all key assignments) */ + memset(keystore_data, 0, keystore_data_size); + + /* Place the slot information structure directly after the keystore data + * structure. + */ + keystore_data->slot = + (keystore_data_slot_info_t *) (keystore_data + 1); + keystore_data->slot_count = slot_count; + + /* Retrieve a secure partition to put the keystore in. */ + keystore_data->base_address = + fsl_shw_smalloc(user_ctx, partition_size, UMID, permissions); + if (keystore_data->base_address == NULL) { + retval = FSL_RETURN_NO_RESOURCE_S; + goto out; + } + *user_data = keystore_data; + retval = FSL_RETURN_OK_S; +out:if (retval != FSL_RETURN_OK_S) { + if (keystore_data != NULL) { + if (keystore_data->base_address != NULL) + fsl_shw_sfree(NULL, + keystore_data->base_address); + +#ifdef __KERNEL__ + os_free_memory(keystore_data); + +#else + free(keystore_data); + +#endif + } + } + return retval; +} +void shw_kso_cleanup_data(fsl_shw_uco_t *user_ctx, void **user_data) +{ + if (user_data != NULL) { + keystore_data_t * keystore_data = + (keystore_data_t *) (*user_data); + fsl_shw_sfree(user_ctx, keystore_data->base_address); + +#ifdef __KERNEL__ + os_free_memory(*user_data); + +#else + free(*user_data); + +#endif + } + return; +} + +fsl_shw_return_t shw_slot_verify_access(void *user_data, uint64_t owner_id, + uint32_t slot) +{ + keystore_data_t * data = user_data; + if (data->slot[slot].owner == owner_id) { + return FSL_RETURN_OK_S; + } else { + +#ifdef DIAG_DRV_IF + LOG_DIAG_ARGS("Access to slot %i fails.\n", slot); + +#endif + return FSL_RETURN_AUTH_FAILED_S; + } +} + +fsl_shw_return_t shw_slot_alloc(void *user_data, uint32_t size, + uint64_t owner_id, uint32_t *slot) +{ + keystore_data_t *data = user_data; + uint32_t i; + if (size > KEYSTORE_SLOT_SIZE) + return FSL_RETURN_BAD_KEY_LENGTH_S; + for (i = 0; i < data->slot_count; i++) { + if (data->slot[i].allocated == 0) { + data->slot[i].allocated = 1; + data->slot[i].owner = owner_id; + (*slot) = i; + +#ifdef DIAG_DRV_IF + LOG_DIAG_ARGS("Keystore: allocated slot %i. Slot " + "address: %p\n", + (*slot), + data->base_address + + (*slot) * KEYSTORE_SLOT_SIZE); + +#endif + return FSL_RETURN_OK_S; + } + } + return FSL_RETURN_NO_RESOURCE_S; +} + +fsl_shw_return_t shw_slot_dealloc(void *user_data, uint64_t owner_id, + uint32_t slot) +{ + keystore_data_t * data = user_data; + (void)owner_id; + (void)slot; + if (slot >= data->slot_count) + return FSL_RETURN_ERROR_S; + if (data->slot[slot].allocated == 1) { + /* Forcibly remove the data from the keystore */ + memset(shw_slot_get_address(user_data, slot), 0, + KEYSTORE_SLOT_SIZE); + data->slot[slot].allocated = 0; + return FSL_RETURN_OK_S; + } + return FSL_RETURN_ERROR_S; +} + +void *shw_slot_get_address(void *user_data, uint32_t slot) +{ + keystore_data_t * data = user_data; + if (slot >= data->slot_count) + return NULL; + return data->base_address + slot * KEYSTORE_SLOT_SIZE; +} + +uint32_t shw_slot_get_base(void *user_data, uint32_t slot) +{ + keystore_data_t * data = user_data; + + /* There could potentially be more than one secure partition object + * associated with this keystore. For now, there is just one. + */ + (void)slot; + return (uint32_t) (data->base_address); +} + +uint32_t shw_slot_get_offset(void *user_data, uint32_t slot) +{ + keystore_data_t *data = user_data; + if (slot >= data->slot_count) + return FSL_RETURN_ERROR_S; + return (slot * KEYSTORE_SLOT_SIZE); +} + +uint32_t shw_slot_get_slot_size(void *user_data, uint32_t slot) +{ + (void)user_data; + (void)slot; + + /* All slots are the same size in the default implementation */ + return KEYSTORE_SLOT_SIZE; +} + +#else /* FSL_HAVE_SCC2 */ + +#ifdef __KERNEL__ + fsl_shw_return_t shw_kso_init_data(fsl_shw_uco_t *user_ctx, + void **user_data) +{ + + /* The SCC does its own initialization. All that needs to be done here is + * make sure an SCC exists. + */ + *user_data = (void *)0xFEEDFEED; + return FSL_RETURN_OK_S; +} +void shw_kso_cleanup_data(fsl_shw_uco_t *user_ctx, void **user_data) +{ + + /* The SCC does its own cleanup. */ + *user_data = NULL; + return; +} + +fsl_shw_return_t shw_slot_verify_access(void *user_data, uint64_t owner_id, + uint32_t slot) +{ + + /* Zero is used for the size because the newer interface does bounds + * checking later. + */ + scc_return_t retval; + retval = scc_verify_slot_access(owner_id, slot, 0); + if (retval == SCC_RET_OK) { + return FSL_RETURN_OK_S; + } + return FSL_RETURN_AUTH_FAILED_S; +} + +fsl_shw_return_t shw_slot_alloc(void *user_data, uint32_t size, + uint64_t owner_id, uint32_t *slot) +{ + scc_return_t retval; + +#ifdef DIAG_DRV_IF + LOG_DIAG_ARGS("key length: %i, handle: %i\n", size, *slot); + +#endif + retval = scc_alloc_slot(size, owner_id, slot); + if (retval == SCC_RET_OK) + return FSL_RETURN_OK_S; + + return FSL_RETURN_NO_RESOURCE_S; +} + +fsl_shw_return_t shw_slot_dealloc(void *user_data, uint64_t owner_id, + uint32_t slot) +{ + scc_return_t retval; + retval = scc_dealloc_slot(owner_id, slot); + if (retval == SCC_RET_OK) + return FSL_RETURN_OK_S; + + return FSL_RETURN_ERROR_S; +} +void *shw_slot_get_address(void *user_data, uint32_t slot) +{ + uint64_t owner_id = *((uint64_t *) user_data); + uint32_t address; + uint32_t value_size_bytes; + uint32_t slot_size_bytes; + scc_return_t scc_ret; + scc_ret = + scc_get_slot_info(owner_id, slot, &address, &value_size_bytes, + &slot_size_bytes); + if (scc_ret == SCC_RET_OK) { + return (void *)address; + } + return NULL; +} + +uint32_t shw_slot_get_base(void *user_data, uint32_t slot) +{ + return 0; +} + +uint32_t shw_slot_get_offset(void *user_data, uint32_t slot) +{ + return 0; +} + + +/* Return the size of the key slot, in octets */ +uint32_t shw_slot_get_slot_size(void *user_data, uint32_t slot) +{ + uint64_t owner_id = *((uint64_t *) user_data); + uint32_t address; + uint32_t value_size_bytes; + uint32_t slot_size_bytes; + scc_return_t scc_ret; + scc_ret = + scc_get_slot_info(owner_id, slot, &address, &value_size_bytes, + &slot_size_bytes); + if (scc_ret == SCC_RET_OK) + return slot_size_bytes; + return 0; +} + + +#endif /* __KERNEL__ */ + +#endif /* FSL_HAVE_SCC2 */ + +/*****************************************************************************/ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/include/sah_hardware_interface.h +++ linux-2.6.28/drivers/mxc/security/sahara2/include/sah_hardware_interface.h @@ -0,0 +1,99 @@ +/* + * Copyright 2004-2008 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 + */ + +/** +* @file sah_hardware_interface.h +* +* @brief Provides an interface to the SAHARA hardware registers. +* +*/ + +#ifndef SAH_HARDWARE_INTERFACE_H +#define SAH_HARDWARE_INTERFACE_H + +#include +#include + +/* These values can be used with sah_HW_Write_Control(). */ +#ifdef SAHARA1 +/** Define platform as Little-Endian */ +#define CTRL_LITTLE_END 0x00000002 +/** Bit to cause endian change in transfers */ +#define CTRL_INT_EN 0x00000004 +/** Set High Assurance mode */ +#define CTRL_HA 0x00000008 +#else +/** Bit to cause byte swapping in (data?) transfers */ +#define CTRL_BYTE_SWAP 0x00000001 +/** Bit to cause halfword swapping in (data?) transfers */ +#define CTRL_HALFWORD_SWAP 0x00000002 +/** Bit to cause endian change in (data?) transfers */ +#define CTRL_INT_EN 0x00000010 +/** Set High Assurance mode */ +#define CTRL_HA 0x00000020 +/** Disable High Assurance */ +#define CTRL_HA_DISABLE 0x00000040 +/** Reseed the RNG CHA */ +#define CTRL_RNG_RESEED 0x00000080 +#endif + + +/* These values can be used with sah_HW_Write_Command(). */ +/** Reset the Sahara */ +#define CMD_RESET 0x00000001 +/** Set Sahara into Batch mode. */ +#define CMD_BATCH 0x00010000 +/** Clear the Sahara interrupt */ +#define CMD_CLR_INT_BIT 0x00000100 +/** Clear the Sahara error */ +#define CMD_CLR_ERROR_BIT 0x00000200 + + +/** error status register contains error */ +#define STATUS_ERROR 0x00000010 + +/** Op status register contains op status */ +#define OP_STATUS 0x00000020 + + +/* High Level functions */ +int sah_HW_Reset(void); +fsl_shw_return_t sah_HW_Set_HA(void); +sah_Execute_Status sah_Wait_On_Sahara(void); + +/* Low Level functions */ +uint32_t sah_HW_Read_Version(void); +uint32_t sah_HW_Read_Control(void); +uint32_t sah_HW_Read_Status(void); +uint32_t sah_HW_Read_Error_Status(void); +uint32_t sah_HW_Read_Op_Status(void); +uint32_t sah_HW_Read_DAR(void); +uint32_t sah_HW_Read_CDAR(void); +uint32_t sah_HW_Read_IDAR(void); +uint32_t sah_HW_Read_Fault_Address(void); +uint32_t sah_HW_Read_MM_Status(void); +uint32_t sah_HW_Read_Config(void); +void sah_HW_Write_Command(uint32_t command); +void sah_HW_Write_Control(uint32_t control); +void sah_HW_Write_DAR(uint32_t pointer); +void sah_HW_Write_Config(uint32_t configuration); + +#if defined DIAG_DRV_IF || defined(DO_DBG) + +void sah_Dump_Words(const char *prefix, const unsigned *data, dma_addr_t addr, + unsigned length); +#endif + +#endif /* SAH_HARDWARE_INTERFACE_H */ + +/* End of sah_hardware_interface.c */ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/include/portable_os.h +++ linux-2.6.28/drivers/mxc/security/sahara2/include/portable_os.h @@ -0,0 +1,1453 @@ +/* + * Copyright 2004-2009 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 PORTABLE_OS_H +#define PORTABLE_OS_H + +/***************************************************************************/ + +/* + * Add support for your target OS by checking appropriate flags and then + * including the appropriate file. Don't forget to document the conditions + * in the later documentation section at the beginning of the + * DOXYGEN_PORTABLE_OS_DOC. + */ + +#if defined(LINUX_KERNEL) + +#include "linux_port.h" + +#elif defined(PORTABLE_OS) + +#include "check_portability.h" + +#else + +#error Target OS unsupported or unspecified + +#endif + + +/***************************************************************************/ + +/*! + * @file portable_os.h + * + * This file should be included by portable driver code in order to gain access + * to the OS-specific header files. It is the only OS-related header file that + * the writer of a portable driver should need. + * + * This file also contains the documentation for the common API. + * + * Begin reading the documentation for this file at the @ref index "main page". + * + */ + +/*! + * @if USE_MAINPAGE + * @mainpage Generic OS API for STC Drivers + * @endif + * + * @section intro_sec Introduction + * + * This defines the API / kernel programming environment for portable drivers. + * + * This API is broken up into several functional areas. It greatly limits the + * choices of a device-driver author, but at the same time should allow for + * greater portability of the resulting code. + * + * Each kernel-to-driver function (initialization function, interrupt service + * routine, etc.) has a 'portable signature' which must be used, and a specific + * function which must be called to generate the return statement. There is + * one exception, a background task or "bottom half" routine, which instead has + * a specific structure which must be followed. These signatures and function + * definitions are found in @ref drsigs. + * + * None of these kernel-to-driver functions seem to get any arguments passed to + * them. Instead, there are @ref drsigargs which allow one of these functions + * to get at fairly generic parts of its calling arguments, if there are any. + * + * Almost every driver will have some need to call the operating system + * @ref dkops is the list of services which are available to the driver. + * + * + * @subsection warn_sec Warning + * + * The specifics of the types, values of the various enumerations + * (unless specifically stated, like = 0), etc., are only here for illustrative + * purposes. No attempts should be made to make use of any specific knowledge + * gleaned from this documentation. These types are only meant to be passed in + * and out of the API, and their contents are to be handled only by the + * provided OS-specific functions. + * + * Also, note that the function may be provided as macros in some + * implementations, or vice versa. + * + * + * @section dev_sec Writing a Portable Driver + * + * First off, writing a portable driver means calling no function in an OS + * except what is available through this header file. + * + * Secondly, all OS-called functions in your driver must be invoked and + * referenced through the signature routines. + * + * Thirdly, there might be some rules which you can get away with ignoring or + * violating on one OS, yet will cause your code not to be portable to a + * different OS. + * + * + * @section limit_sec Limitations + * + * This API is not expected to handle every type of driver which may be found + * in an operating system. For example, it will not be able to handle the + * usual design for something like a UART driver, where there are multiple + * logical devices to access, because the design usually calls for some sort of + * indication to the #OS_DEV_TASK() function or OS_DEV_ISR() to indicate which + * channel is to be serviced by that instance of the task/function. This sort + * of argument is missing in this API for functions like os_dev_schedule_task() and + * os_register_interrupt(). + * + * + * @section port_guide Porting Guidelines + * + * This section is intended for a developer who needs to port the header file + * to an operating system which is not yet supported. + * + * This interface allows for a lot of flexibility when it comes to porting to + * an operating systems device driver interface. There are three main areas to + * examine: The use of Driver Routine Signatures, the use of Driver Argument + * Access functions, the Calls to Kernel Functions, and Data Types. + * + * + * @subsection port_sig Porting Driver Routine Signatures + * + * The three macros for each function (e.g. #OS_DEV_INIT(), #OS_DEV_INIT_DCL(), + * and #OS_DEV_INIT_REF()) allow the flexibility of having a 'wrapper' function + * with the OS-required signature, which would then call the user's function + * with some different signature. + * + * The first form would lay down the wrapper function, followed by the + * signature for the user function. The second form would lay down just the + * signatures for both functions, and the last function would reference the + * wrapper function, since that is the interface function called by the OS. + * + * Note that the driver author has no visibility at all to the signature of the + * routines. The author can access arguments only through a limited set of + * functions, and must return via another function. + * + * The Return Functions allow a lot of flexibility in converting the return + * value, or not returning a value at all. These will likely be implemented as + * macros. + * + * + * @subsection port_arg Porting Driver Argument Access Functions + * + * The signatures defined by the guide will usually be replaced with macro + * definitions. + * + * + * @subsection port_dki Porting Calls to Kernel Functions + * + * The signatures defined by the guide may be replaced with macro definitions, + * if that makes more sense. + * + * Implementors are free to ignore arguments which are not applicable to their + * OS. + * + * @subsection port_datatypes Porting Data Types + * + * + */ + +/*************************************************************************** + * Compile flags + **************************************************************************/ + +/* + * This compile flag should only be turned on when running doxygen to generate + * the API documentation. + */ +#ifdef DOXYGEN_PORTABLE_OS_DOC + +/*! + * @todo module_init()/module_cleanup() for Linux need to be added to OS + * abstractions. Also need EXPORT_SYMBOL() equivalent?? + * + */ + +/* Drop OS differentation documentation here */ + +/*! + * \#define this flag to build your driver as a Linux driver + */ +#define LINUX + +/* end OS differentation documentation */ + +/*! + * Symbol to give version number of the implementation file. Earliest + * definition is in version 1.1, with value 101 (to mean version 1.1) + */ +#define PORTABLE_OS_VERSION 101 + +/* + * NOTICE: The following definitions (the rest of the file) are not meant ever + * to be compiled. Instead, they are the documentation for the portable OS + * API, to be used by driver writers. + * + * Each individual OS port will define each of these types, functions, or + * macros as appropriate to the target OS. This is why they are under the + * DOXYGEN_PORTABLE_OS_DOC flag. + */ + +/*************************************************************************** + * Type definitions + **************************************************************************/ + +/*! + * Type used for registering and deregistering interrupts. + * + * This is typically an interrupt channel number. + */ +typedef int os_interrupt_id_t; + +/*! + * Type used as handle for a process + * + * See #os_get_process_handle() and #os_send_signal(). + */ +typedef int os_process_handle_t; + +/*! + * Generic return code for functions which need such a thing. + * + * No knowledge should be assumed of the value of any of these symbols except + * that @c OS_ERROR_OK_S is guaranteed to be zero. + * + * @todo Any other named values? What about (-EAGAIN? -ERESTARTSYS? Are they + * too Linux/Unix-specific read()/write() return values) ? + */ +typedef enum { + OS_ERROR_OK_S = 0, /*!< Success */ + OS_ERROR_FAIL_S, /*!< Generic driver failure */ + OS_ERROR_NO_MEMORY_S, /*!< Failure to acquire/use memory */ + OS_ERROR_BAD_ADDRESS_S, /*!< Bad address */ + OS_ERROR_BAD_ARG_S /*!< Bad input argument */ +} os_error_code; + +/*! + * Handle to a lock. + */ +typedef int *os_lock_t; + +/*! + * Context while locking. + */ +typedef int os_lock_context_t; + +/*! + * An object which can be slept on and later used to wake any/all sleepers. + */ +typedef int os_sleep_object_t; + +/*! + * Driver registration handle + */ +typedef void *os_driver_reg_t; + +/*! + * Function signature for an #OS_DEV_INIT() function. + * + * @return A call to os_dev_init_return() function. + */ +typedef void (*os_init_function_t) (void); + +/*! + * Function signature for an #OS_DEV_SHUTDOWN() function. + * + * @return A call to os_dev_shutdown_return() function. + */ +typedef void (*os_shutdown_function_t) (void); + +/*! + * Function signature for a user-driver function. + * + * @return A call to the appropriate os_dev_xxx_return() function. + */ +typedef void (*os_user_function_t) (void); + +/*! + * Function signature for the portable interrupt handler + * + * While it would be nice to know which interrupt is being serviced, the + * Least Common Denominator rule says that no arguments get passed in. + * + * @return A call to #os_dev_isr_return() + */ +typedef void (*os_interrupt_handler_t) (void); + +/*! + * Function signature for a task function + * + * Many task function definitions get some sort of generic argument so that the + * same function can run across many (queues, channels, ...) as separate task + * instances. This has been left out of this API. + * + * This function must be structured as documented by #OS_DEV_TASK(). + * + */ +typedef void (*os_task_fn_t) (void); + +/*! + * Function types which can be associated with driver entry points. These are + * used in os_driver_add_registration(). + * + * Note that init and shutdown are absent. + */ +typedef enum { + OS_FN_OPEN, /*!< open() operation handler. */ + OS_FN_CLOSE, /*!< close() operation handler. */ + OS_FN_READ, /*!< read() operation handler. */ + OS_FN_WRITE, /*!< write() operation handler. */ + OS_FN_IOCTL, /*!< ioctl() operation handler. */ + OS_FN_MMAP /*!< mmap() operation handler. */ +} os_driver_fn_t; + +/*************************************************************************** + * Driver-to-Kernel Operations + **************************************************************************/ + +/*! + * @defgroup dkops Driver-to-Kernel Operations + * + * These are the operations which drivers should call to get the OS to perform + * services. + */ + +/*! @addtogroup dkops */ +/*! @{ */ + +/*! + * Register an interrupt handler. + * + * @param driver_name The name of the driver + * @param interrupt_id The interrupt line to monitor (type + * #os_interrupt_id_t) + * @param function The function to be called to handle an interrupt + * + * @return #os_error_code + */ +os_error_code os_register_interrupt(char *driver_name, + os_interrupt_id_t interrupt_id, + os_interrupt_handler_t function); + +/*! + * Deregister an interrupt handler. + * + * @param interrupt_id The interrupt line to stop monitoring + * + * @return #os_error_code + */ +os_error_code os_deregister_interrupt(os_interrupt_id_t interrupt_id); + +/*! + * Initialize driver registration. + * + * If the driver handles open(), close(), ioctl(), read(), write(), or mmap() + * calls, then it needs to register their location with the kernel so that they + * get associated with the device. + * + * @param handle The handle object to be used with this registration. The + * object must live (be in memory somewhere) at least until + * os_driver_remove_registration() is called. + * + * @return An os error code. + */ +os_error_code os_driver_init_registration(os_driver_reg_t handle); + +/*! + * Add a function registration to driver registration. + * + * @param handle The handle used with #os_driver_init_registration(). + * @param name Which function is being supported. + * @param function The result of a call to a @c _REF version of one of the + * driver function signature macros + * driver function signature macros + * @return void + */ +void os_driver_add_registration(os_driver_reg_t handle, os_driver_fn_t name, + void *function); + +/*! + * Finalize the driver registration with the kernel. + * + * Upon return from this call, the driver may begin receiving calls at the + * defined entry points. + * + * @param handle The handle used with #os_driver_init_registration(). + * @param major The major device number to be associated with the driver. + * If this value is zero, a major number may be assigned. + * See #os_driver_get_major() to determine final value. + * #os_driver_remove_registration(). + * @param driver_name The driver name. Can be used as part of 'device node' + * name on platforms which support such a feature. + * + * @return An error code + */ +os_error_code os_driver_complete_registration(os_driver_reg_t handle, + int major, char *driver_name); + +/*! + * Get driver Major Number from handle after a successful registration. + * + * @param handle A handle which has completed registration. + * + * @return The major number (if any) associated with the handle. + */ +uint32_t os_driver_get_major(os_driver_reg_t handle); + +/*! + * Remove the driver's registration with the kernel. + * + * Upon return from this call, the driver not receive any more calls at the + * defined entry points (other than ISR and shutdown). + * + * @param major The major device number to be associated with the driver. + * @param driver_name The driver name + * + * @return An error code. + */ +os_error_code os_driver_remove_registration(int major, char *driver_name); + +/*! + * Print a message to console / into log file. After the @c msg argument a + * number of printf-style arguments may be added. Types should be limited to + * printf string, char, octal, decimal, and hexadecimal types. (This excludes + * pointers, and floating point). + * + * @param msg The message to print to console / system log + * + * @return (void) + */ +void os_printk(char *msg, ...); + +/*! + * Allocate some kernel memory + * + * @param amount Number of 8-bit bytes to allocate + * @param flags Some indication of purpose of memory (needs definition) + * + * @return Pointer to allocated memory, or NULL if failed. + */ +void *os_alloc_memory(unsigned amount, int flags); + +/*! + * Free some kernel memory + * + * @param location The beginning of the region to be freed. + * + * Do some OSes have separate free() functions which should be + * distinguished by passing in @c flags here, too? Don't some also require the + * size of the buffer being freed? Perhaps separate routines for each + * alloc/free pair (DMAable, etc.)? + */ +void os_free_memory(void *location); + +/*! + * Allocate cache-coherent memory + * + * @param amount Number of bytes to allocate + * @param[out] dma_addrp Location to store physical address of allocated + * memory. + * @param flags Some indication of purpose of memory (needs + * definition). + * + * @return (virtual space) pointer to allocated memory, or NULL if failed. + * + */ +void *os_alloc_coherent(unsigned amount, uint32_t * dma_addrp, int flags); + +/*! + * Free cache-coherent memory + * + * @param size Number of bytes which were allocated. + * @param[out] virt_addr Virtual(kernel) address of memory.to be freed, as + * returned by #os_alloc_coherent(). + * @param[out] dma_addr Physical address of memory.to be freed, as returned + * by #os_alloc_coherent(). + * + * @return void + * + */ +void os_free_coherent(unsigned size, void *virt_addr, uint32_t dma_addr); + +/*! + * Map an I/O space into kernel memory space + * + * @param start The starting address of the (physical / io space) region + * @param range_bytes The number of bytes to map + * + * @return A pointer to the mapped area, or NULL on failure + */ +void *os_map_device(uint32_t start, unsigned range_bytes); + +/*! + * Unmap an I/O space from kernel memory space + * + * @param start The starting address of the (virtual) region + * @param range_bytes The number of bytes to unmap + * + * @return None + */ +void os_unmap_device(void *start, unsigned range_bytes); + +/*! + * Copy data from Kernel space to User space + * + * @param to The target location in user memory + * @param from The source location in kernel memory + * @param size The number of bytes to be copied + * + * @return #os_error_code + */ +os_error_code os_copy_to_user(void *to, void *from, unsigned size); + +/*! + * Copy data from User space to Kernel space + * + * @param to The target location in kernel memory + * @param from The source location in user memory + * @param size The number of bytes to be copied + * + * @return #os_error_code + */ +os_error_code os_copy_from_user(void *to, void *from, unsigned size); + +/*! + * Read an 8-bit device register + * + * @param register_address The (bus) address of the register to write to + * @return The value in the register + */ +uint8_t os_read8(uint8_t * register_address); + +/*! + * Write an 8-bit device register + * + * @param register_address The (bus) address of the register to write to + * @param value The value to write into the register + */ +void os_write8(uint8_t * register_address, uint8_t value); + +/*! + * Read a 16-bit device register + * + * @param register_address The (bus) address of the register to write to + * @return The value in the register + */ +uint16_t os_read16(uint16_t * register_address); + +/*! + * Write a 16-bit device register + * + * @param register_address The (bus) address of the register to write to + * @param value The value to write into the register + */ +void os_write16(uint16_t * register_address, uint16_t value); + +/*! + * Read a 32-bit device register + * + * @param register_address The (bus) address of the register to write to + * @return The value in the register + */ +uint32_t os_read32(uint32_t * register_address); + +/*! + * Write a 32-bit device register + * + * @param register_address The (bus) address of the register to write to + * @param value The value to write into the register + */ +void os_write32(uint32_t * register_address, uint32_t value); + +/*! + * Read a 64-bit device register + * + * @param register_address The (bus) address of the register to write to + * @return The value in the register + */ +uint64_t os_read64(uint64_t * register_address); + +/*! + * Write a 64-bit device register + * + * @param register_address The (bus) address of the register to write to + * @param value The value to write into the register + */ +void os_write64(uint64_t * register_address, uint64_t value); + +/*! + * Prepare a task to execute the given function. This should only be done once + * per task, during the driver's initialization routine. + * + * @param task_fn Name of the OS_DEV_TASK() function to be created. + * + * @return an OS ERROR code. + */ +os_error os_create_task(os_task_fn_t * task_fn); + +/*! + * Run the task associated with an #OS_DEV_TASK() function + * + * The task will begin execution sometime after or during this call. + * + * @param task_fn Name of the OS_DEV_TASK() function to be scheduled. + * + * @return void + */ +void os_dev_schedule_task(os_task_fn_t * task_fn); + +/*! + * Make sure that task is no longer running and will no longer run. + * + * This function will not return until both are true. This is useful when + * shutting down a driver. + * + * @param task_fn Name of the OS_DEV_TASK() funciton to be stopped. + * + */ +void os_stop_task(os_task_fn_t * task_fn); + +/*! + * Delay some number of microseconds + * + * Note that this is a busy-loop, not a suspension of the task/process. + * + * @param msecs The number of microseconds to delay + * + * @return void + */ +void os_mdelay(unsigned long msecs); + +/*! + * Calculate virtual address from physical address + * + * @param pa Physical address + * + * @return virtual address + * + * @note this assumes that addresses are 32 bits wide + */ +void *os_va(uint32_t pa); + +/*! + * Calculate physical address from virtual address + * + * + * @param va Virtual address + * + * @return physical address + * + * @note this assumes that addresses are 32 bits wide + */ +uint32_t os_pa(void *va); + +/*! + * Allocate and initialize a lock, returning a lock handle. + * + * The lock state will be initialized to 'unlocked'. + * + * @return A lock handle, or NULL if an error occurred. + */ +os_lock_t os_lock_alloc_init(void); + +/*! + * Acquire a lock. + * + * This function should only be called from an interrupt service routine. + * + * @param lock_handle A handle to the lock to acquire. + * + * @return void + */ +void os_lock(os_lock_t lock_handle); + +/*! + * Unlock a lock. Lock must have been acquired by #os_lock(). + * + * @param lock_handle A handle to the lock to unlock. + * + * @return void + */ +void os_unlock(os_lock_t lock_handle); + +/*! + * Acquire a lock in non-ISR context + * + * This function will spin until the lock is available. + * + * @param lock_handle A handle of the lock to acquire. + * @param context Place to save the before-lock context + * + * @return void + */ +void os_lock_save_context(os_lock_t lock_handle, os_lock_context_t context); + +/*! + * Release a lock in non-ISR context + * + * @param lock_handle A handle of the lock to release. + * @param context Place where before-lock context was saved. + * + * @return void + */ +void os_unlock_restore_context(os_lock_t lock_handle, + os_lock_context_t context); + +/*! + * Deallocate a lock handle. + * + * @param lock_handle An #os_lock_t that has been allocated. + * + * @return void + */ +void os_lock_deallocate(os_lock_t lock_handle); + +/*! + * Determine process handle + * + * The process handle of the current user is returned. + * + * @return A handle on the current process. + */ +os_process_handle_t os_get_process_handle(); + +/*! + * Send a signal to a process + * + * @param proc A handle to the target process. + * @param sig The POSIX signal to send to that process. + */ +void os_send_signal(os_process_handle_t proc, int sig); + +/*! + * Get some random bytes + * + * @param buf The location to store the random data. + * @param count The number of bytes to store. + * + * @return void + */ +void os_get_random_bytes(void *buf, unsigned count); + +/*! + * Go to sleep on an object. + * + * Example: code = os_sleep(my_queue, available_count == 0, 0); + * + * @param object The object on which to sleep + * @param condition An expression to check for sleep completion. Must be + * coded so that it can be referenced more than once inside + * macro, i.e., no ++ or other modifying expressions. + * @param atomic Non-zero if sleep must not return until condition. + * + * @return error code -- OK or sleep interrupted?? + */ +os_error_code os_sleep(os_sleep_object_t object, unsigned condition, + unsigned atomic); + +/*! + * Wake up whatever is sleeping on sleep object + * + * @param object The object on which things might be sleeping + * + * @return none + */ +void os_wake_sleepers(os_sleep_object_t object); + + /*! @} *//* dkops */ + +/***************************************************************************** + * Function-signature-generating macros + *****************************************************************************/ + +/*! + * @defgroup drsigs Driver Function Signatures + * + * These macros will define the entry point signatures for interrupt handlers; + * driver initialization and shutdown; device open/close; etc. They are to be + * used whenever the Kernel will call into the Driver. They are not + * appropriate for driver calls to other routines in the driver. + * + * There are three versions of each macro for a given Driver Entry Point. The + * first version is used to define a function and its implementation in the + * driver.c file, e.g. #OS_DEV_INIT(). + * + * The second form is used whenever a forward declaration (prototype) is + * needed. It has the letters @c _DCL appended to the name of the definition + * function. These are not otherwise mentioned in this documenation. + * + * There is a third form used when a reference to a function is required, for + * instance when passing the routine as a pointer to a function. It has the + * letters @c _REF appended to the name of the definition function + * (e.g. DEV_IOCTL_REF). + * + * Note that these two extra forms are required because of the possibility of + * having an invisible 'wrapper function' created by the os-specific header + * file which would need to be invoked by the operating system, and which in + * turn would invoke the generic function. + * + * Example: + * + * (in a header file) + * @code + * OS_DEV_INIT_DCL(widget_init); + * OS_DEV_ISR_DCL(widget_isr); + * @endcode + * + * (in an implementation file) + * @code + * OS_DEV_INIT(widget, widget_init) + * { + * + * os_register_interrupt("widget", WIDGET_IRQ, OS_DEV_ISR_REF(widget_isr)); + * + * os_dev_init_return(OS_RETURN_NO_ERROR_S); + * } + * + * OS_DEV_ISR(widget_isr) + * { + * os_dev_isr_return(TRUE); + * } + * @endcode + */ + +/*! @addtogroup drsigs */ +/*! @{ */ + +/*! + * Define a function which will handle device initialization + * + * This is tne driver initialization routine. This is normally where the + * part would be initialized; queues, locks, interrupts handlers defined; + * long-term dynamic memory allocated for driver use; etc. + * + * @param function_name The name of the portable initialization function. + * + * @return A call to #os_dev_init_return() + * + */ +#define OS_DEV_INIT(function_name) + +/*! + * Define a function which will handle device shutdown + * + * This is the reverse of the #OS_DEV_INIT() routine. + * + * @param function_name The name of the portable driver shutdown routine. + * + * @return A call to #os_dev_shutdown_return() + */ +#define OS_DEV_SHUTDOWN(function_name) + +/*! + * Define a function which will open the device for a user. + * + * @param function_name The name of the driver open() function + * + * @return A call to #os_dev_open_return() + */ +#define OS_DEV_OPEN(function_name) + +/*! + * Define a function which will handle a user's ioctl() request + * + * @param function_name The name of the driver ioctl() function + * + * @return A call to #os_dev_ioctl_return() + */ +#define OS_DEV_IOCTL(function_name) + +/*! + * Define a function which will handle a user's read() request + * + * @param function_name The name of the driver read() function + * + * @return A call to #os_dev_read_return() + */ +#define OS_DEV_READ(function_name) + +/*! + * Define a function which will handle a user's write() request + * + * @param function_name The name of the driver write() function + * + * @return A call to #os_dev_write_return() + */ +#define OS_DEV_WRITE(function_name) + +/*! + * Define a function which will handle a user's mmap() request + * + * The mmap() function requests the driver to map some memory into user space. + * + * @todo Determine what support functions are needed for mmap() handling. + * + * @param function_name The name of the driver mmap() function + * + * @return A call to #os_dev_mmap_return() + */ +#define OS_DEV_MMAP(function_name) + +/*! + * Define a function which will close the device - opposite of OS_DEV_OPEN() + * + * @param function_name The name of the driver close() function + * + * @return A call to #os_dev_close_return() + */ +#define OS_DEV_CLOSE(function_name) + +/*! + * Define a function which will handle an interrupt + * + * No arguments are available to the generic function. It must not invoke any + * OS functions which are illegal in a ISR. It gets no parameters, and must + * have a call to #os_dev_isr_return() instead of any/all return statements. + * + * Example: + * @code + * OS_DEV_ISR(widget, widget_isr, WIDGET_IRQ_NUMBER) + * { + * os_dev_isr_return(1); + * } + * @endcode + * + * @param function_name The name of the driver ISR function + * + * @return A call to #os_dev_isr_return() + */ +#define OS_DEV_ISR(function_name) + +/*! + * Define a function which will operate as a background task / bottom half. + * + * The function implementation must be structured in the following manner: + * @code + * OS_DEV_TASK(widget_task) + * { + * OS_DEV_TASK_SETUP(widget_task); + * + * while OS_DEV_TASK_CONDITION(widget_task) } + * + * }; + * } + * @endcode + * + * @todo In some systems the OS_DEV_TASK_CONDITION() will be an action which + * will cause the task to sleep on some event triggered by os_run_task(). In + * others, the macro will reference a variable laid down by + * OS_DEV_TASK_SETUP() to make sure that the loop is only performed once. + * + * @param function_name The name of this background task function + */ +#define OS_DEV_TASK(function_name) + + /*! @} *//* drsigs */ + +/*! @defgroup dclsigs Routines to declare Driver Signature routines + * + * These macros drop prototypes suitable for forward-declaration of + * @ref drsigs "function signatures". + */ + +/*! @addtogroup dclsigs */ +/*! @{ */ + +/*! + * Declare prototype for the device initialization function + * + * @param function_name The name of the portable initialization function. + */ +#define OS_DEV_INIT_DCL(function_name) + +/*! + * Declare prototype for the device shutdown function + * + * @param function_name The name of the portable driver shutdown routine. + * + * @return A call to #os_dev_shutdown_return() + */ +#define OS_DEV_SHUTDOWN_DCL(function_name) + +/*! + * Declare prototype for the open() function. + * + * @param function_name The name of the driver open() function + * + * @return A call to #os_dev_open_return() + */ +#define OS_DEV_OPEN_DCL(function_name) + +/*! + * Declare prototype for the user's ioctl() request function + * + * @param function_name The name of the driver ioctl() function + * + * @return A call to #os_dev_ioctl_return() + */ +#define OS_DEV_IOCTL_DCL(function_name) + +/*! + * Declare prototype for the function a user's read() request + * + * @param function_name The name of the driver read() function + */ +#define OS_DEV_READ_DCL(function_name) + +/*! + * Declare prototype for the user's write() request function + * + * @param function_name The name of the driver write() function + */ +#define OS_DEV_WRITE_DCL(function_name) + +/*! + * Declare prototype for the user's mmap() request function + * + * @param function_name The name of the driver mmap() function + */ +#define OS_DEV_MMAP_DCL(function_name) + +/*! + * Declare prototype for the close function + * + * @param function_name The name of the driver close() function + * + * @return A call to #os_dev_close_return() + */ +#define OS_DEV_CLOSE_DCL(function_name) + +/*! + * Declare prototype for the interrupt handling function + * + * @param function_name The name of the driver ISR function + */ +#define OS_DEV_ISR_DCL(function_name) + +/*! + * Declare prototype for a background task / bottom half function + * + * @param function_name The name of this background task function + */ +#define OS_DEV_TASK_DCL(function_name) + + /*! @} *//* dclsigs */ + +/***************************************************************************** + * Functions for Returning Values from Driver Signature routines + *****************************************************************************/ + +/*! + * @defgroup retfns Functions to Return Values from Driver Signature routines + */ + +/*! @addtogroup retfns */ +/*! @{ */ + +/*! + * Return from the #OS_DEV_INIT() function + * + * @param code An error code to report success or failure. + * + */ +void os_dev_init_return(os_error_code code); + +/*! + * Return from the #OS_DEV_SHUTDOWN() function + * + * @param code An error code to report success or failure. + * + */ +void os_dev_shutdown_return(os_error_code code); + +/*! + * Return from the #OS_DEV_ISR() function + * + * The function should verify that it really was supposed to be called, + * and that its device needed attention, in order to properly set the + * return code. + * + * @param code non-zero if interrupt handled, zero otherwise. + * + */ +void os_dev_isr_return(int code); + +/*! + * Return from the #OS_DEV_OPEN() function + * + * @param code An error code to report success or failure. + * + */ +void os_dev_open_return(os_error_code code); + +/*! + * Return from the #OS_DEV_IOCTL() function + * + * @param code An error code to report success or failure. + * + */ +void os_dev_ioctl_return(os_error_code code); + +/*! + * Return from the #OS_DEV_READ() function + * + * @param code Number of bytes read, or an error code to report failure. + * + */ +void os_dev_read_return(os_error_code code); + +/*! + * Return from the #OS_DEV_WRITE() function + * + * @param code Number of bytes written, or an error code to report failure. + * + */ +void os_dev_write_return(os_error_code code); + +/*! + * Return from the #OS_DEV_MMAP() function + * + * @param code Number of bytes written, or an error code to report failure. + * + */ +void os_dev_mmap_return(os_error_code code); + +/*! + * Return from the #OS_DEV_CLOSE() function + * + * @param code An error code to report success or failure. + * + */ +void os_dev_close_return(os_error_code code); + +/*! + * Start the #OS_DEV_TASK() function + * + * In some implementations, this could be turned into a label for + * the os_dev_task_return() call. + * + * For a more portable interface, should this take the sleep object as an + * argument??? + * + * @return none + */ +void os_dev_task_begin(void); + +/*! + * Return from the #OS_DEV_TASK() function + * + * In some implementations, this could be turned into a sleep followed + * by a jump back to the os_dev_task_begin() call. + * + * @param code An error code to report success or failure. + * + */ +void os_dev_task_return(os_error_code code); + + /*! @} *//* retfns */ + +/***************************************************************************** + * Functions/Macros for accessing arguments from Driver Signature routines + *****************************************************************************/ + +/*! @defgroup drsigargs Functions for Getting Arguments in Signature functions + * + */ +/* @addtogroup @drsigargs */ +/*! @{ */ + +/*! + * Check whether user is requesting read (permission) on the file/device. + * Usable in #OS_DEV_OPEN(), #OS_DEV_CLOSE(), #OS_DEV_IOCTL(), #OS_DEV_READ() + * and #OS_DEV_WRITE() routines. + */ +int os_dev_is_flag_read(void); + +/*! + * Check whether user is requesting write (permission) on the file/device. + * Usable in #OS_DEV_OPEN(), #OS_DEV_CLOSE(), #OS_DEV_IOCTL(), #OS_DEV_READ() + * and #OS_DEV_WRITE() routines. + */ +int os_dev_is_flag_write(void); + +/*! + * Check whether user is requesting non-blocking I/O. Usable in + * #OS_DEV_OPEN(), #OS_DEV_CLOSE(), #OS_DEV_IOCTL(), #OS_DEV_READ() and + * #OS_DEV_WRITE() routines. + * + * @todo Specify required behavior when nonblock is requested and (sufficient?) + * data are not available to fulfill the request. + * + */ +int os_dev_is_flag_nonblock(void); + +/*! + * Determine which major device is being accessed. Usable in #OS_DEV_OPEN() + * and #OS_DEV_CLOSE(). + */ +int os_dev_get_major(void); + +/*! + * Determine which minor device is being accessed. Usable in #OS_DEV_OPEN() + * and #OS_DEV_CLOSE(). + */ +int os_dev_get_minor(void); + +/*! + * Determine which operation the user wants performed. Usable in + * #OS_DEV_IOCTL(). + * + * @return Value of the operation. + * + * @todo Define some generic way to define the individual operations. + */ +unsigned os_dev_get_ioctl_op(void); + +/*! + * Retrieve the associated argument for the desired operation. Usable in + * #OS_DEV_IOCTL(). + * + * @return A value which can be cast to a struct pointer or used as + * int/long. + */ +os_dev_ioctl_arg_t os_dev_get_ioctl_arg(void); + +/*! + * Determine the requested byte count. This should be the size of buffer at + * #os_dev_get_user_buffer(). Usable in OS_DEV_READ() and OS_DEV_WRITE() + * routines. + * + * @return A count of bytes + */ +unsigned os_dev_get_count(void); + +/*! + * Get the pointer to the user's data buffer. Usable in OS_DEV_READ(), + * OS_DEV_WRITE(), and OS_DEV_MMAP() routines. + * + * @return Pointer to user buffer (in user space). See #os_copy_to_user() + * and #os_copy_from_user(). + */ +void *os_dev_get_user_buffer(void); + +/*! + * Get the POSIX flags field for the associated open file. Usable in + * OS_DEV_READ(), OS_DEV_WRITE(), and OS_DEV_IOCTL() routines. + * + * @return The flags associated with the file. + */ +unsigned os_dev_get_file_flags(void); + +/*! + * Set the driver's private structure associated with this file/open. + * + * Generally used during #OS_DEV_OPEN(). May also be used during + * #OS_DEV_READ(), #OS_DEV_WRITE(), #OS_DEV_IOCTL(), #OS_DEV_MMAP(), and + * #OS_DEV_CLOSE(). See also #os_dev_get_user_private(). + * + * @param struct_p The driver data structure to associate with this user. + */ +void os_dev_set_user_private(void *struct_p); + +/*! + * Get the driver's private structure associated with this file. + * + * May be used during #OS_DEV_OPEN(), #OS_DEV_READ(), #OS_DEV_WRITE(), + * #OS_DEV_IOCTL(), #OS_DEV_MMAP(), and #OS_DEV_CLOSE(). See + * also #os_dev_set_user_private(). + * + * @return The driver data structure to associate with this user. + */ +void *os_dev_get_user_private(void); + +/*! + * Get the IRQ associated with this call to the #OS_DEV_ISR() function. + * + * @return The IRQ (integer) interrupt number. + */ +int os_dev_get_irq(void); + + /*! @} *//* drsigargs */ + +/***************************************************************************** + * Functions for Generating References to Driver Routines + *****************************************************************************/ + +/*! + * @defgroup drref Functions for Generating References to Driver Routines + * + * These functions will most likely be implemented as macros. They are a + * necessary part of the portable API to guarantee portability. The @c symbol + * type in here is the same symbol passed to the associated + * signature-generating macro. + * + * These macros must be used whenever referring to a + * @ref drsigs "driver signature function", for instance when storing or + * passing a pointer to the function. + */ + +/*! @addtogroup drref */ +/*! @{ */ + +/*! + * Generate a reference to an #OS_DEV_INIT() function + * + * @param function_name The name of the init function being referenced. + * + * @return A reference to the function + */ +os_init_function_t OS_DEV_INIT_REF(symbol function_name); + +/*! + * Generate a reference to an #OS_DEV_SHUTDOWN() function + * + * @param function_name The name of the shutdown function being referenced. + * + * @return A reference to the function + */ +os_shutdown_function_t OS_DEV_SHUTDOWN_REF(symbol function_name); + +/*! + * Generate a reference to an #OS_DEV_OPEN() function + * + * @param function_name The name of the open function being referenced. + * + * @return A reference to the function + */ +os_user_function_t OS_DEV_OPEN_REF(symbol function_name); + +/*! + * Generate a reference to an #OS_DEV_CLOSE() function + * + * @param function_name The name of the close function being referenced. + * + * @return A reference to the function + */ +os_user_function_t OS_DEV_CLOSE_REF(symbol function_name); + +/*! + * Generate a reference to an #OS_DEV_READ() function + * + * @param function_name The name of the read function being referenced. + * + * @return A reference to the function + */ +os_user_function_t OS_DEV_READ_REF(symbol function_name); + +/*! + * Generate a reference to an #OS_DEV_WRITE() function + * + * @param function_name The name of the write function being referenced. + * + * @return A reference to the function + */ +os_user_function_t OS_DEV_WRITE_REF(symbol function_name); + +/*! + * Generate a reference to an #OS_DEV_IOCTL() function + * + * @param function_name The name of the ioctl function being referenced. + * + * @return A reference to the function + */ +os_user_function_t OS_DEV_IOCTL_REF(symbol function_name); + +/*! + * Generate a reference to an #OS_DEV_MMAP() function + * + * @param function_name The name of the mmap function being referenced. + * + * @return A reference to the function + */ +os_user_function_t OS_DEV_MMAP_REF(symbol function_name); + +/*! + * Generate a reference to an #OS_DEV_ISR() function + * + * @param function_name The name of the isr being referenced. + * + * @return a reference to the function + */ +os_interrupt_handler_t OS_DEV_ISR_REF(symbol function_name); + + /*! @} *//* drref */ + +/*! + * Flush and invalidate all cache lines. + */ +void os_flush_cache_all(void); + +/*! + * Flush a range of addresses from the cache + * + * @param start Starting virtual address + * @param len Number of bytes to flush + */ +void os_cache_flush_range(void *start, uint32_t len); + +/*! + * Invalidate a range of addresses in the cache + * + * @param start Starting virtual address + * @param len Number of bytes to flush + */ +void os_cache_inv_range(void *start, uint32_t len); + +/*! + * Clean a range of addresses from the cache + * + * @param start Starting virtual address + * @param len Number of bytes to flush + */ +void os_cache_clean_range(void *start, uint32_t len); + +/*! + * @example widget.h + */ + +/*! + * @example widget.c + */ + +/*! + * @example rng_driver.h + */ + +/*! + * @example rng_driver.c + */ + +/*! + * @example shw_driver.h + */ + +/*! + * @example shw_driver.c + */ + +#endif /* DOXYGEN_PORTABLE_OS_DOC */ + +#endif /* PORTABLE_OS_H */ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/include/adaptor.h +++ linux-2.6.28/drivers/mxc/security/sahara2/include/adaptor.h @@ -0,0 +1,113 @@ +/* + * Copyright 2004-2008 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 + */ + +/*! +* @file adaptor.h +* +* @brief The Adaptor component provides an interface to the device +* driver. +* +* Intended to be used by the FSL SHW API, this can also be called directly +*/ + +#ifndef ADAPTOR_H +#define ADAPTOR_H + +#include + +/*! + * Structure passed during user ioctl() call to submit request. + */ +typedef struct sah_dar { + sah_Desc *desc_addr; /*!< head of descriptor chain */ + uint32_t uco_flags; /*!< copy of fsl_shw_uco flags field */ + uint32_t uco_user_ref; /*!< copy of fsl_shw_uco user_ref */ + uint32_t result; /*!< result of descriptor chain request */ + struct sah_dar *next; /*!< for driver use */ +} sah_dar_t; + +/*! + * Structure passed during user ioctl() call to Register a user + */ +typedef struct sah_register { + uint32_t pool_size; /*!< max number of outstanding requests possible */ + uint32_t result; /*!< result of registration request */ +} sah_register_t; + +/*! + * Structure passed during ioctl() call to request SCC operation + */ +typedef struct scc_data { + uint32_t length; /*!< length of data */ + uint8_t *in; /*!< input data */ + uint8_t *out; /*!< output data */ + unsigned direction; /*!< encrypt or decrypt */ + fsl_shw_sym_mode_t crypto_mode; /*!< CBC or EBC */ + uint8_t *init_vector; /*!< initialization vector or NULL */ +} scc_data_t; + +/*! + * Structure passed during user ioctl() calls to manage stored keys and + * stored-key slots. + */ +typedef struct scc_slot_t { + uint64_t ownerid; /*!< Owner's id to check/set permissions */ + uint32_t key_length; /*!< Length of key */ + uint32_t slot; /*!< Slot to operation on, or returned slot + number. */ + uint8_t *key; /*!< User-memory pointer to key value */ + fsl_shw_return_t code; /*!< API return code from operation */ +} scc_slot_t; + +/* + * Structure passed during user ioctl() calls to manage data stored in secure + * partitions. + */ +typedef struct scc_region_t { + uint32_t partition_base; /*!< User virtual address of the + partition base. */ + uint32_t offset; /*!< Offset from the start of the + partition where the cleartext data + is located. */ + uint32_t length; /*!< Length of the region to be + operated on */ + uint8_t *black_data; /*!< User virtual address of any black + (encrypted) data. */ + fsl_shw_cypher_mode_t cypher_mode; /*!< Cypher mode to use in an encryt/ + decrypt operation. */ + uint32_t IV[4]; /*!< Intialization vector to use in an + encrypt/decrypt operation. */ + fsl_shw_return_t code; /*!< API return code from operation */ +} scc_region_t; + +/* + * Structure passed during user ioctl() calls to manage secure partitions. + */ +typedef struct scc_partition_info_t { + uint32_t user_base; /**< Userspace pointer to base of partition */ + uint32_t permissions; /**< Permissions to give the partition (only + used in call to _DROP_PERMS) */ + fsl_shw_partition_status_t status; /*!< Status of the partition */ +} scc_partition_info_t; + +fsl_shw_return_t adaptor_Exec_Descriptor_Chain(sah_Head_Desc * dar, + fsl_shw_uco_t * uco); +fsl_shw_return_t sah_get_results(sah_results * arg, fsl_shw_uco_t * uco); +fsl_shw_return_t sah_register(fsl_shw_uco_t * user_ctx); +fsl_shw_return_t sah_deregister(fsl_shw_uco_t * user_ctx); +fsl_shw_return_t get_capabilities(fsl_shw_uco_t * user_ctx, + fsl_shw_pco_t *capabilities); + +#endif /* ADAPTOR_H */ + +/* End of adaptor.h */ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/include/linux_port.h +++ linux-2.6.28/drivers/mxc/security/sahara2/include/linux_port.h @@ -0,0 +1,1804 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @file linux_port.h + * + * OS_PORT ported to Linux (2.6.9+ for now) + * + */ + + /*! + * @if USE_MAINPAGE + * @mainpage ==Linux version of== Generic OS API for STC Drivers + * @endif + * + * @section intro_sec Introduction + * + * This API / kernel programming environment blah blah. + * + * See @ref dkops "Driver-to-Kernel Operations" as a good place to start. + */ + +#ifndef LINUX_PORT_H +#define LINUX_PORT_H + +#define PORTABLE_OS_VERSION 101 + +/* Linux Kernel Includes */ +#include /* Current version Linux kernel */ + +#if defined(CONFIG_MODVERSIONS) && ! defined(MODVERSIONS) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) +#include +#endif +#define MODVERSIONS +#endif +/*! + * __NO_VERSION__ defined due to Kernel module possibly spanning multiple + * files. + */ +#define __NO_VERSION__ + +#include /* Basic support for loadable modules, + printk */ +#include /* module_init, module_exit */ +#include /* General kernel system calls */ +#include /* for interrupt.h */ +#include /* for inode */ +#include +#include +#include +#include +#include /* kmalloc */ + +#include + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) +#include /* used in dynamic power management */ +#else +#include /* used in dynamic power management */ +#endif + +#include +#include + +#include /* clock en/disable for DPM */ + +#include +#include + +#include /* copy_to_user(), copy_from_user() */ +#include /* ioremap() */ +#include +#include + +#ifndef TRUE +/*! Useful symbol for unsigned values used as flags. */ +#define TRUE 1 +#endif + +#ifndef FALSE +/*! Useful symbol for unsigned values used as flags. */ +#define FALSE 0 +#endif + +/* These symbols are defined in Linux 2.6 and later. Include here for minimal + * support of 2.4 kernel. + **/ +#if !defined(LINUX_VERSION_CODE) || LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +/*! + * Symbol defined somewhere in 2.5/2.6. It is the return signature of an ISR. + */ +#define irqreturn_t void +/*! Possible return value of 'modern' ISR routine. */ +#define IRQ_HANDLED +/*! Method of generating value of 'modern' ISR routine. */ +#define IRQ_RETVAL(x) +#endif + +/*! + * Type used for registering and deregistering interrupts. + */ +typedef int os_interrupt_id_t; + +/*! + * Type used as handle for a process + * + * See #os_get_process_handle() and #os_send_signal(). + */ +/* + * The following should be defined this way, but it gets compiler errors + * on the current tool chain. + * + * typedef task_t *os_process_handle_t; + */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) +typedef task_t *os_process_handle_t; +#else +typedef struct task_struct *os_process_handle_t; +#endif + +/*! + * Generic return code for functions which need such a thing. + * + * No knowledge should be assumed of the value of any of these symbols except + * that @c OS_ERROR_OK_S is guaranteed to be zero. + */ +typedef enum { + OS_ERROR_OK_S = 0, /*!< Success */ + OS_ERROR_FAIL_S = -EIO, /*!< Generic driver failure */ + OS_ERROR_NO_MEMORY_S = -ENOMEM, /*!< Failure to acquire/use memory */ + OS_ERROR_BAD_ADDRESS_S = -EFAULT, /*!< Bad address */ + OS_ERROR_BAD_ARG_S = -EINVAL, /*!< Bad input argument */ +} os_error_code; + +/*! + * Handle to a lock. + */ +#ifdef CONFIG_PREEMPT_RT +typedef raw_spinlock_t *os_lock_t; +#else +typedef spinlock_t *os_lock_t; +#endif + +/*! + * Context while locking. + */ +typedef unsigned long os_lock_context_t; + +/*! + * Declare a wait object for sleeping/waking processes. + */ +#define OS_WAIT_OBJECT(name) \ + DECLARE_WAIT_QUEUE_HEAD(name##_qh) + +/*! + * Driver registration handle + * + * Used with #os_driver_init_registration(), #os_driver_add_registration(), + * and #os_driver_complete_registration(). + */ +typedef struct { + unsigned reg_complete; /*!< TRUE if next inits succeeded. */ + dev_t dev; /*!< dev_t for register_chrdev() */ + struct file_operations fops; /*!< struct for register_chrdev() */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) + struct class_simple *cs; /*!< results of class_simple_create() */ +#else + struct class *cs; /*!< results of class_create() */ +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) + struct class_device *cd; /*!< Result of class_device_create() */ +#else + struct device *cd; /*!< Result of device_create() */ +#endif + unsigned power_complete; /*!< TRUE if next inits succeeded */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) + struct device_driver dd; /*!< struct for register_driver() */ +#else + struct platform_driver dd; /*!< struct for register_driver() */ +#endif + struct platform_device pd; /*!< struct for platform_register_device() */ +} os_driver_reg_t; + +/* + * Function types which can be associated with driver entry points. + * + * Note that init and shutdown are absent. + */ +/*! @{ */ +/*! Keyword for registering open() operation handler. */ +#define OS_FN_OPEN open +/*! Keyword for registering close() operation handler. */ +#define OS_FN_CLOSE release +/*! Keyword for registering read() operation handler. */ +#define OS_FN_READ read +/*! Keyword for registering write() operation handler. */ +#define OS_FN_WRITE write +/*! Keyword for registering ioctl() operation handler. */ +#define OS_FN_IOCTL ioctl +/*! Keyword for registering mmap() operation handler. */ +#define OS_FN_MMAP mmap +/*! @} */ + +/*! + * Function signature for the portable interrupt handler + * + * While it would be nice to know which interrupt is being serviced, the + * Least Common Denominator rule says that no arguments get passed in. + * + * @return Zero if not handled, non-zero if handled. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) +typedef int (*os_interrupt_handler_t) (int, void *, struct pt_regs *); +#else +typedef int (*os_interrupt_handler_t) (int, void *); +#endif + +/*! + * @defgroup dkops Driver-to-Kernel Operations + * + * These are the operations which drivers should call to get the OS to perform + * services. + */ + +/*! @addtogroup dkops */ +/*! @{ */ + +/*! + * Register an interrupt handler. + * + * @param driver_name The name of the driver + * @param interrupt_id The interrupt line to monitor (type + * #os_interrupt_id_t) + * @param function The function to be called to handle an interrupt + * + * @return #os_error_code + */ +#define os_register_interrupt(driver_name, interrupt_id, function) \ + request_irq(interrupt_id, function, 0, driver_name, NULL) + +/*! + * Deregister an interrupt handler. + * + * @param interrupt_id The interrupt line to stop monitoring + * + * @return #os_error_code + */ +#define os_deregister_interrupt(interrupt_id) \ + free_irq(interrupt_id, NULL) + +/*! + * INTERNAL implementation of os_driver_init_registration() + * + * @return An os error code. + */ +inline static int os_drv_do_init_reg(os_driver_reg_t * handle) +{ + memset(handle, 0, sizeof(*handle)); + handle->fops.owner = THIS_MODULE; + handle->power_complete = FALSE; + handle->reg_complete = FALSE; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) + handle->dd.name = NULL; +#else + handle->dd.driver.name = NULL; +#endif + + return OS_ERROR_OK_S; +} + +/*! + * Initialize driver registration. + * + * If the driver handles open(), close(), ioctl(), read(), write(), or mmap() + * calls, then it needs to register their location with the kernel so that they + * get associated with the device. + * + * @param handle The handle object to be used with this registration. The + * object must live (be in memory somewhere) at least until + * os_driver_remove_registration() is called. + * + * @return A handle for further driver registration, or NULL if failed. + */ +#define os_driver_init_registration(handle) \ + os_drv_do_init_reg(&handle) + +/*! + * Add a function registration to driver registration. + * + * @param handle A handle initialized by #os_driver_init_registration(). + * @param name Which function is being supported. + * @param function The result of a call to a @c _REF version of one of the + * driver function signature macros + * @return void + */ +#define os_driver_add_registration(handle, name, function) \ + do {handle.fops.name = (void*)(function); } while (0) + +/*! + * Record 'power suspend' function for the device. + * + * @param handle A handle initialized by #os_driver_init_registration(). + * @param function Name of function to call on power suspend request + * + * Status: Provisional + * + * @return void + */ +#define os_driver_register_power_suspend(handle, function) \ + handle.dd.suspend = function + +/*! + * Record 'power resume' function for the device. + * + * @param handle A handle initialized by #os_driver_init_registration(). + * @param function Name of function to call on power resume request + * + * Status: Provisional + * + * @return void + */ +#define os_driver_register_resume(handle, function) \ + handle.dd.resume = function + +/*! + * INTERNAL function of the Linux port of the OS API. Implements the + * os_driver_complete_registration() function. + * + * @param handle The handle used with #os_driver_init_registration(). + * @param major The major device number to be associated with the driver. + * If this value is zero, a major number may be assigned. + * See #os_driver_get_major() to determine final value. + * #os_driver_remove_registration(). + * @param driver_name The driver name. Can be used as part of 'device node' + * name on platforms which support such a feature. + * + * @return An error code + */ +inline static int os_drv_do_reg(os_driver_reg_t * handle, + unsigned major, char *driver_name) +{ + os_error_code code = OS_ERROR_NO_MEMORY_S; + char *name = kmalloc(strlen(driver_name) + 1, 0); + + if (name != NULL) { + memcpy(name, driver_name, strlen(driver_name) + 1); + code = OS_ERROR_OK_S; /* OK so far */ + /* If any chardev/POSIX routines were added, then do chrdev part */ + if (handle->fops.open || handle->fops.release + || handle->fops.read || handle->fops.write + || handle->fops.ioctl || handle->fops.mmap) { + + printk("ioctl pointer: %p. mmap pointer: %p\n", + handle->fops.ioctl, handle->fops.mmap); + + /* this method is depricated, see: + * http://lwn.net/Articles/126808/ + */ + code = + register_chrdev(major, driver_name, &handle->fops); + + /* instead something like this: */ +#if 0 + handle->dev = MKDEV(major, 0); + code = + register_chrdev_region(handle->dev, 1, driver_name); + if (code < 0) { + code = OS_ERROR_FAIL_S; + } else { + cdev_init(&handle->cdev, &handle->fops); + code = cdev_add(&handle->cdev, major, 1); + } +#endif + + if (code < 0) { + code = OS_ERROR_FAIL_S; + } else { + if (code != 0) { + /* Zero was passed in for major; code is actual value */ + handle->dev = MKDEV(code, 0); + } else { + handle->dev = MKDEV(major, 0); + } + code = OS_ERROR_OK_S; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) + handle->cs = + class_simple_create(THIS_MODULE, + driver_name); + if (IS_ERR(handle->cs)) { + code = (os_error_code) handle->cs; + handle->cs = NULL; + } else { + handle->cd = + class_simple_device_add(handle->cs, + handle->dev, + NULL, + driver_name); + if (IS_ERR(handle->cd)) { + class_simple_device_remove + (handle->dev); + unregister_chrdev(MAJOR + (handle->dev), + driver_name); + code = + (os_error_code) handle->cs; + handle->cs = NULL; + } else { + handle->reg_complete = TRUE; + } + } +#else + handle->cs = + class_create(THIS_MODULE, driver_name); + if (IS_ERR(handle->cs)) { + code = (os_error_code) handle->cs; + handle->cs = NULL; + } else { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) + handle->cd = + class_device_create(handle->cs, + NULL, + handle->dev, + NULL, + driver_name); +#else + handle->cd = + device_create(handle->cs, NULL, + handle->dev, NULL, + driver_name); +#endif + if (IS_ERR(handle->cd)) { + class_destroy(handle->cs); + unregister_chrdev(MAJOR + (handle->dev), + driver_name); + code = + (os_error_code) handle->cs; + handle->cs = NULL; + } else { + handle->reg_complete = TRUE; + } + } +#endif + } + } + /* ... fops routine registered */ + /* Handle power management fns through separate interface */ + if ((code == OS_ERROR_OK_S) && + (handle->dd.suspend || handle->dd.resume)) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) + handle->dd.name = name; + handle->dd.bus = &platform_bus_type; + code = driver_register(&handle->dd); +#else + handle->dd.driver.name = name; + handle->dd.driver.bus = &platform_bus_type; + code = driver_register(&handle->dd.driver); +#endif + if (code == OS_ERROR_OK_S) { + handle->pd.name = name; + handle->pd.id = 0; + code = platform_device_register(&handle->pd); + if (code != OS_ERROR_OK_S) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) + driver_unregister(&handle->dd); +#else + driver_unregister(&handle->dd.driver); +#endif + } else { + handle->power_complete = TRUE; + } + } + } /* ... suspend or resume */ + } /* name != NULL */ + return code; +} + +/*! + * Finalize the driver registration with the kernel. + * + * Upon return from this call, the driver may begin receiving calls at the + * defined entry points. + * + * @param handle The handle used with #os_driver_init_registration(). + * @param major The major device number to be associated with the driver. + * If this value is zero, a major number may be assigned. + * See #os_driver_get_major() to determine final value. + * #os_driver_remove_registration(). + * @param driver_name The driver name. Can be used as part of 'device node' + * name on platforms which support such a feature. + * + * @return An error code + */ +#define os_driver_complete_registration(handle, major, driver_name) \ + os_drv_do_reg(&handle, major, driver_name) + +/*! + * Get driver Major Number from handle after a successful registration. + * + * @param handle A handle which has completed registration. + * + * @return The major number (if any) associated with the handle. + */ +#define os_driver_get_major(handle) \ + (handle.reg_complete ? MAJOR(handle.dev) : -1) + +/*! + * INTERNAL implemention of os_driver_remove_registration. + * + * @param handle A handle initialized by #os_driver_init_registration(). + * + * @return An error code. + */ +inline static int os_drv_rmv_reg(os_driver_reg_t * handle) +{ + if (handle->reg_complete) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) + if (handle->cd != NULL) { + class_simple_device_remove(handle->dev); + handle->cd = NULL; + } + if (handle->cs != NULL) { + class_simple_destroy(handle->cs); + handle->cs = NULL; + } + unregister_chrdev(MAJOR(handle->dev), handle->dd.name); +#else + if (handle->cd != NULL) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) + class_device_destroy(handle->cs, handle->dev); +#else + device_destroy(handle->cs, handle->dev); +#endif + handle->cd = NULL; + } + if (handle->cs != NULL) { + class_destroy(handle->cs); + handle->cs = NULL; + } + unregister_chrdev(MAJOR(handle->dev), handle->dd.driver.name); +#endif + handle->reg_complete = FALSE; + } + if (handle->power_complete) { + platform_device_unregister(&handle->pd); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) + driver_unregister(&handle->dd); +#else + driver_unregister(&handle->dd.driver); +#endif + handle->power_complete = FALSE; + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) + if (handle->dd.name != NULL) { + kfree(handle->dd.name); + handle->dd.name = NULL; + } +#else + if (handle->dd.driver.name != NULL) { + kfree(handle->dd.driver.name); + handle->dd.driver.name = NULL; + } +#endif + return OS_ERROR_OK_S; +} + +/*! + * Remove the driver's registration with the kernel. + * + * Upon return from this call, the driver not receive any more calls at the + * defined entry points (other than ISR and shutdown). + * + * @param handle A handle initialized by #os_driver_init_registration(). + * + * @return An error code. + */ +#define os_driver_remove_registration(handle) \ + os_drv_rmv_reg(&handle) + +/*! + * Register a driver with the Linux Device Model. + * + * @param driver_information The device_driver structure information + * + * @return An error code. + * + * Status: denigrated in favor of #os_driver_complete_registration() + */ +#define os_register_to_driver(driver_information) \ + driver_register(driver_information) + +/*! + * Unregister a driver from the Linux Device Model + * + * this routine unregisters from the Linux Device Model + * + * @param driver_information The device_driver structure information + * + * @return An error code. + * + * Status: Denigrated. See #os_register_to_driver(). + */ +#define os_unregister_from_driver(driver_information) \ + driver_unregister(driver_information) + +/*! + * register a device to a driver + * + * this routine registers a drivers devices to the Linux Device Model + * + * @param device_information The platform_device structure information + * + * @return An error code. + * + * Status: denigrated in favor of #os_driver_complete_registration() + */ +#define os_register_a_device(device_information) \ + platform_device_register(device_information) + +/*! + * unregister a device from a driver + * + * this routine unregisters a drivers devices from the Linux Device Model + * + * @param device_information The platform_device structure information + * + * @return An error code. + * + * Status: Denigrated. See #os_register_a_device(). + */ +#define os_unregister_a_device(device_information) \ + platform_device_unregister(device_information) + +/*! + * Print a message to console / into log file. After the @c msg argument a + * number of printf-style arguments may be added. Types should be limited to + * printf string, char, octal, decimal, and hexadecimal types. (This excludes + * pointers, and floating point). + * + * @param msg The main text of the message to be logged + * @param s The printf-style arguments which go with msg, if any + * + * @return (void) + */ +#define os_printk(...) \ + (void) printk(__VA_ARGS__) + +/*! + * Prepare a task to execute the given function. This should only be done once + * per function,, during the driver's initialization routine. + * + * @param task_fn Name of the OS_DEV_TASK() function to be created. + * + * @return an OS ERROR code. + */ +#define os_create_task(function_name) \ + OS_ERROR_OK_S + +/*! + * Schedule execution of a task. + * + * @param function_name The function associated with the task. + * + * @return (void) + */ +#define os_dev_schedule_task(function_name) \ + tasklet_schedule(&(function_name ## let)) + +/*! + * Make sure that task is no longer running and will no longer run. + * + * This function will not return until both are true. This is useful when + * shutting down a driver. + */ +#define os_dev_stop_task(function_name) \ +do { \ + tasklet_disable(&(function_name ## let)); \ + tasklet_kill(&(function_name ## let)); \ +} while (0) + +/*! + * Allocate some kernel memory + * + * @param amount Number of 8-bit bytes to allocate + * @param flags Some indication of purpose of memory (needs definition) + * + * @return Pointer to allocated memory, or NULL if failed. + */ +#define os_alloc_memory(amount, flags) \ + (void*)kmalloc(amount, flags) + +/*! + * Free some kernel memory + * + * @param location The beginning of the region to be freed. + * + * Do some OSes have separate free() functions which should be + * distinguished by passing in @c flags here, too? Don't some also require the + * size of the buffer being freed? + */ +#define os_free_memory(location) \ + kfree(location) + +/*! + * Allocate cache-coherent memory + * + * @param amount Number of bytes to allocate + * @param[out] dma_addrp Location to store physical address of allocated + * memory. + * @param flags Some indication of purpose of memory (needs + * definition). + * + * @return (virtual space) pointer to allocated memory, or NULL if failed. + * + */ +#define os_alloc_coherent(amount, dma_addrp, flags) \ + (void*)dma_alloc_coherent(NULL, amount, dma_addrp, flags) + +/*! + * Free cache-coherent memory + * + * @param size Number of bytes which were allocated. + * @param virt_addr Virtual(kernel) address of memory.to be freed, as + * returned by #os_alloc_coherent(). + * @param dma_addr Physical address of memory.to be freed, as returned + * by #os_alloc_coherent(). + * + * @return void + * + */ +#define os_free_coherent(size, virt_addr, dma_addr) \ + dma_free_coherent(NULL, size, virt_addr, dma_addr + +/*! + * Map an I/O space into kernel memory space + * + * @param start The starting address of the (physical / io space) region + * @param range_bytes The number of bytes to map + * + * @return A pointer to the mapped area, or NULL on failure + */ +#define os_map_device(start, range_bytes) \ + (void*)ioremap_nocache((start), range_bytes) + +/*! + * Unmap an I/O space from kernel memory space + * + * @param start The starting address of the (virtual) region + * @param range_bytes The number of bytes to unmap + * + * @return None + */ +#define os_unmap_device(start, range_bytes) \ + iounmap((void*)(start)) + +/*! + * Copy data from Kernel space to User space + * + * @param to The target location in user memory + * @param from The source location in kernel memory + * @param size The number of bytes to be copied + * + * @return #os_error_code + */ +#define os_copy_to_user(to, from, size) \ + ((copy_to_user(to, from, size) == 0) ? 0 : OS_ERROR_BAD_ADDRESS_S) + +/*! + * Copy data from User space to Kernel space + * + * @param to The target location in kernel memory + * @param from The source location in user memory + * @param size The number of bytes to be copied + * + * @return #os_error_code + */ +#define os_copy_from_user(to, from, size) \ + ((copy_from_user(to, from, size) == 0) ? 0 : OS_ERROR_BAD_ADDRESS_S) + +/*! + * Read a 8-bit device register + * + * @param register_address The (bus) address of the register to write to + * @return The value in the register + */ +#define os_read8(register_address) \ + __raw_readb(register_address) + +/*! + * Write a 8-bit device register + * + * @param register_address The (bus) address of the register to write to + * @param value The value to write into the register + */ +#define os_write8(register_address, value) \ + __raw_writeb(value, register_address) + +/*! + * Read a 16-bit device register + * + * @param register_address The (bus) address of the register to write to + * @return The value in the register + */ +#define os_read16(register_address) \ + __raw_readw(register_address) + +/*! + * Write a 16-bit device register + * + * @param register_address The (bus) address of the register to write to + * @param value The value to write into the register + */ +#define os_write16(register_address, value) \ + __raw_writew(value, (uint32_t*)(register_address)) + +/*! + * Read a 32-bit device register + * + * @param register_address The (bus) address of the register to write to + * @return The value in the register + */ +#define os_read32(register_address) \ + __raw_readl((uint32_t*)(register_address)) + +/*! + * Write a 32-bit device register + * + * @param register_address The (bus) address of the register to write to + * @param value The value to write into the register + */ +#define os_write32(register_address, value) \ + __raw_writel(value, register_address) + +/*! + * Read a 64-bit device register + * + * @param register_address The (bus) address of the register to write to + * @return The value in the register + */ +#define os_read64(register_address) \ + ERROR_UNIMPLEMENTED + +/*! + * Write a 64-bit device register + * + * @param register_address The (bus) address of the register to write to + * @param value The value to write into the register + */ +#define os_write64(register_address, value) \ + ERROR_UNIMPLEMENTED + +/*! + * Delay some number of microseconds + * + * Note that this is a busy-loop, not a suspension of the task/process. + * + * @param msecs The number of microseconds to delay + * + * @return void + */ +#define os_mdelay mdelay + +/*! + * Calculate virtual address from physical address + * + * @param pa Physical address + * + * @return virtual address + * + * @note this assumes that addresses are 32 bits wide + */ +#define os_va __va + +/*! + * Calculate physical address from virtual address + * + * + * @param va Virtual address + * + * @return physical address + * + * @note this assumes that addresses are 32 bits wide + */ +#define os_pa __pa + +#ifdef CONFIG_PREEMPT_RT +/*! + * Allocate and initialize a lock, returning a lock handle. + * + * The lock state will be initialized to 'unlocked'. + * + * @return A lock handle, or NULL if an error occurred. + */ +inline static os_lock_t os_lock_alloc_init(void) +{ + raw_spinlock_t *lockp; + lockp = (raw_spinlock_t *) kmalloc(sizeof(raw_spinlock_t), 0); + if (lockp) { + _raw_spin_lock_init(lockp); + } else { + printk("OS: lock init failed\n"); + } + + return lockp; +} +#else +/*! + * Allocate and initialize a lock, returning a lock handle. + * + * The lock state will be initialized to 'unlocked'. + * + * @return A lock handle, or NULL if an error occurred. + */ +inline static os_lock_t os_lock_alloc_init(void) +{ + spinlock_t *lockp; + lockp = (spinlock_t *) kmalloc(sizeof(spinlock_t), 0); + if (lockp) { + spin_lock_init(lockp); + } else { + printk("OS: lock init failed\n"); + } + + return lockp; +} +#endif /* CONFIG_PREEMPT_RT */ + +/*! + * Acquire a lock. + * + * This function should only be called from an interrupt service routine. + * + * @param lock_handle A handle to the lock to acquire. + * + * @return void + */ +#define os_lock(lock_handle) \ + spin_lock(lock_handle) + +/*! + * Unlock a lock. Lock must have been acquired by #os_lock(). + * + * @param lock_handle A handle to the lock to unlock. + * + * @return void + */ +#define os_unlock(lock_handle) \ + spin_unlock(lock_handle) + +/*! + * Acquire a lock in non-ISR context + * + * This function will spin until the lock is available. + * + * @param lock_handle A handle of the lock to acquire. + * @param context Place to save the before-lock context + * + * @return void + */ +#define os_lock_save_context(lock_handle, context) \ + spin_lock_irqsave(lock_handle, context) + +/*! + * Release a lock in non-ISR context + * + * @param lock_handle A handle of the lock to release. + * @param context Place where before-lock context was saved. + * + * @return void + */ +#define os_unlock_restore_context(lock_handle, context) \ + spin_unlock_irqrestore(lock_handle, context) + +/*! + * Deallocate a lock handle. + * + * @param lock_handle An #os_lock_t that has been allocated. + * + * @return void + */ +#define os_lock_deallocate(lock_handle) \ + kfree(lock_handle) + +/*! + * Determine process handle + * + * The process handle of the current user is returned. + * + * @return A handle on the current process. + */ +#define os_get_process_handle() \ + current + +/*! + * Send a signal to a process + * + * @param proc A handle to the target process. + * @param sig The POSIX signal to send to that process. + */ +#define os_send_signal(proc, sig) \ + send_sig(sig, proc, 0); + +/*! + * Get some random bytes + * + * @param buf The location to store the random data. + * @param count The number of bytes to store. + * + * @return void + */ +#define os_get_random_bytes(buf, count) \ + get_random_bytes(buf, count) + +/*! + * Go to sleep on an object. + * + * @param object The object on which to sleep + * @param condition An expression to check for sleep completion. Must be + * coded so that it can be referenced more than once inside + * macro, i.e., no ++ or other modifying expressions. + * @param atomic Non-zero if sleep must not return until condition. + * + * @return error code -- OK or sleep interrupted?? + */ +#define os_sleep(object, condition, atomic) \ +({ \ + DEFINE_WAIT(_waitentry_); \ + os_error_code code = OS_ERROR_OK_S; \ + \ + while (!(condition)) { \ + prepare_to_wait(&(object##_qh), &_waitentry_, \ + atomic ? 0 : TASK_INTERRUPTIBLE); \ + if (!(condition)) { \ + schedule(); \ + } \ + \ + finish_wait(&(object##_qh), &_waitentry_); \ + \ + if (!atomic && signal_pending(current)) { \ + code = OS_ERROR_FAIL_S; /* NEED SOMETHING BETTER */ \ + break; \ + } \ + }; \ + \ + code; \ +}) + +/*! + * Wake up whatever is sleeping on sleep object + * + * @param object The object on which things might be sleeping + * + * @return none + */ +#define os_wake_sleepers(object) \ + wake_up_interruptible(&(object##_qh)); + + /*! @} *//* dkops */ + +/****************************************************************************** + * Function signature-generating macros + *****************************************************************************/ + +/*! + * @defgroup drsigs Driver Signatures + * + * These macros will define the entry point signatures for interrupt handlers; + * driver initialization and shutdown; device open/close; etc. + * + * There are two versions of each macro for a given Driver Entry Point. The + * first version is used to define a function and its implementation in the + * driver.c file, e.g. #OS_DEV_INIT(). + * + * The second form is used whenever a forward declaration (prototype) is + * needed. It has the letters @c _DCL appended to the name of the defintion + * function, and takes only the first two arguments (driver_name and + * function_name). These are not otherwise mentioned in this documenation. + * + * There is a third form used when a reference to a function is required, for + * instance when passing the routine as a pointer to a function. It has the + * letters @c _REF appended to it, and takes only the first two arguments + * (driver_name and function_name). These functions are not otherwise + * mentioned in this documentation. + * + * (Note that these two extra forms are required because of the + * possibility/likelihood of having a 'wrapper function' which invokes the + * generic function with expected arguments. An alternative would be to have a + * generic function which isn't able to get at any arguments directly, but + * would be equipped with macros which could get at information passed in. + * + * Example: + * + * (in a header file) + * @code + * OS_DEV_INIT_DCL(widget, widget_init); + * @endcode + * + * (in an implementation file) + * @code + * OS_DEV_INIT(widget, widget_init) + * { + * os_dev_init_return(TRUE); + * } + * @endcode + * + */ + +/*! @addtogroup drsigs */ +/*! @{ */ + +/*! + * Define a function which will handle device initialization + * + * This is tne driver initialization routine. This is normally where the + * part would be initialized; queues, locks, interrupts handlers defined; + * long-term dynamic memory allocated for driver use; etc. + * + * @param function_name The name of the portable initialization function. + * + * @return A call to #os_dev_init_return() + * + */ +#define OS_DEV_INIT(function_name) \ +module_init(function_name); \ +static int __init function_name (void) + +/*! Make declaration for driver init function. + * @param function_name foo + */ +#define OS_DEV_INIT_DCL(function_name) \ +static int __init function_name (void); + +/*! + * Generate a function reference to the driver's init function. + * @param function_name Name of the OS_DEV_INIT() function. + * + * @return A function pointer. + */ +#define OS_DEV_INIT_REF(function_name) \ +function_name + +/*! + * Define a function which will handle device shutdown + * + * This is the inverse of the #OS_DEV_INIT() routine. + * + * @param function_name The name of the portable driver shutdown routine. + * + * @return A call to #os_dev_shutdown_return() + * + */ +#define OS_DEV_SHUTDOWN(function_name) \ +module_exit(function_name); \ +static void function_name(void) + +/*! + * Generate a function reference to the driver's shutdown function. + * @param function_name Name of the OS_DEV_HUSTDOWN() function. + * + * @return A function pointer. + */ +#define OS_DEV_SHUTDOWN_DCL(function_name) \ +static void function_name(void); + +/*! + * Generate a reference to driver's shutdown function + * @param function_name Name of the OS_DEV_HUSTDOWN() function. +*/ + +#define OS_DEV_SHUTDOWN_REF(function_name) \ +function_name + +/*! + * Define a function which will open the device for a user. + * + * @param function_name The name of the driver open() function + * + * @return A call to #os_dev_open_return() + */ +#define OS_DEV_OPEN(function_name) \ +static int function_name(struct inode* inode_p_, struct file* file_p_) + +/*! + * Declare prototype for an open() function. + * + * @param function_name The name of the OS_DEV_OPEN() function. + */ +#define OS_DEV_OPEN_DCL(function_name) \ +OS_DEV_OPEN(function_name); + +/*! + * Generate a function reference to the driver's open() function. + * @param function_name Name of the OS_DEV_OPEN() function. + * + * @return A function pointer. + */ +#define OS_DEV_OPEN_REF(function_name) \ +function_name + +/*! + * Define a function which will handle a user's ioctl() request + * + * @param function_name The name of the driver ioctl() function + * + * @return A call to #os_dev_ioctl_return() + */ +#define OS_DEV_IOCTL(function_name) \ +static int function_name(struct inode* inode_p_, struct file* file_p_, \ + unsigned int cmd_, unsigned long data_) + +/*! Boo. */ +#define OS_DEV_IOCTL_DCL(function_name) \ +OS_DEV_IOCTL(function_name); + +/*! + * Generate a function reference to the driver's ioctl() function. + * @param function_name Name of the OS_DEV_IOCTL() function. + * + * @return A function pointer. + */ +#define OS_DEV_IOCTL_REF(function_name) \ +function_name + +/*! + * Define a function which will handle a user's mmap() request + * + * @param function_name The name of the driver mmap() function + * + * @return A call to #os_dev_ioctl_return() + */ +#define OS_DEV_MMAP(function_name) \ +int function_name(struct file* file_p_, struct vm_area_struct* vma_) + +#define OS_DEV_MMAP_DCL(function_name) \ +OS_DEV_MMAP(function_name); + +#define OS_DEV_MMAP_REF(function_name) \ +function_name + +/* Retrieve the context to the memory structure that is to be MMAPed */ +#define os_mmap_memory_ctx() (vma_) + +/* Determine the size of the requested MMAP region*/ +#define os_mmap_memory_size() (vma_->vm_end - vma_->vm_start) + +/* Determine the base address of the requested MMAP region*/ +#define os_mmap_user_base() (vma_->vm_start) + +/*! + * Declare prototype for an read() function. + * + * @param function_name The name of the driver read function. + */ +#define OS_DEV_READ_DCL(function_name) \ +OS_DEV_READ(function_name); + +/*! + * Generate a function reference to the driver's read() routine + * @param function_name Name of the OS_DEV_READ() function. + * + * @return A function pointer. + */ +#define OS_DEV_READ_REF(function_name) \ +function_name + +/*! + * Define a function which will handle a user's write() request + * + * @param function_name The name of the driver write() function + * + * @return A call to #os_dev_write_return() + */ +#define OS_DEV_WRITE(function_name) \ +static ssize_t function_name(struct file* file_p_, char* user_buffer_, \ + size_t count_bytes_, loff_t* file_position_) + +/*! + * Declare prototype for an write() function. + * + * @param function_name The name of the driver write function. + */ +#define OS_DEV_WRITE_DCL(function_name) \ +OS_DEV_WRITE(function_name); + +/*! + * Generate a function reference to the driver's write() routine + * @param function_name Name of the OS_DEV_WRITE() function. + * + * @return A function pointer. + */ +#define OS_DEV_WRITE_REF(function_name) \ +function_name + +/*! + * Define a function which will close the device - opposite of OS_DEV_OPEN() + * + * @param function_name The name of the driver close() function + * + * @return A call to #os_dev_close_return() + */ +#define OS_DEV_CLOSE(function_name) \ +static int function_name(struct inode* inode_p_, struct file* file_p_) + +/*! + * Declare prototype for an close() function + * + * @param function_name The name of the driver close() function. + */ +#define OS_DEV_CLOSE_DCL(function_name) \ +OS_DEV_CLOSE(function_name); + +/*! + * Generate a function reference to the driver's close function. + * @param function_name Name of the OS_DEV_CLOSE() function. + * + * @return A function pointer. + */ +#define OS_DEV_CLOSE_REF(function_name) \ +function_name + +/*! + * Define a function which will handle an interrupt + * + * No arguments are available to the generic function. It must not invoke any + * OS functions which are illegal in a ISR. It gets no parameters, and must + * have a call to #os_dev_isr_return() instead of any/all return statements. + * + * Example: + * @code + * OS_DEV_ISR(widget) + * { + * os_dev_isr_return(1); + * } + * @endcode + * + * @param function_name The name of the driver ISR function + * + * @return A call to #os_dev_isr_return() + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) +#define OS_DEV_ISR(function_name) \ +static irqreturn_t function_name(int N1_, void* N2_, struct pt_regs* N3_) +#else +#define OS_DEV_ISR(function_name) \ +static irqreturn_t function_name(int N1_, void* N2_) +#endif + +/*! + * Declare prototype for an ISR function. + * + * @param function_name The name of the driver ISR function. + */ +#define OS_DEV_ISR_DCL(function_name) \ +OS_DEV_ISR(function_name); + +/*! + * Generate a function reference to the driver's interrupt service routine + * @param function_name Name of the OS_DEV_ISR() function. + * + * @return A function pointer. + */ +#define OS_DEV_ISR_REF(function_name) \ +function_name + +/*! + * Define a function which will operate as a background task / bottom half. + * + * Tasklet stuff isn't strictly limited to 'Device drivers', but leave it + * this namespace anyway. + * + * @param function_name The name of this background task function + * + * @return A call to #os_dev_task_return() + */ +#define OS_DEV_TASK(function_name) \ +static void function_name(unsigned long data_) + +/*! + * Declare prototype for a background task / bottom half function + * + * @param function_name The name of this background task function + */ +#define OS_DEV_TASK_DCL(function_name) \ +OS_DEV_TASK(function_name); \ +DECLARE_TASKLET(function_name ## let, function_name, 0); + +/*! + * Generate a reference to an #OS_DEV_TASK() function + * + * @param function_name The name of the task being referenced. + */ +#define OS_DEV_TASK_REF(function_name) \ + (function_name ## let) + + /*! @} *//* drsigs */ + +/***************************************************************************** + * Functions/Macros for returning values from Driver Signature routines + *****************************************************************************/ + +/*! + * Return from the #OS_DEV_INIT() function + * + * @param code An error code to report success or failure. + * + */ +#define os_dev_init_return(code) \ + return code + +/*! + * Return from the #OS_DEV_SHUTDOWN() function + * + * @param code An error code to report success or failure. + * + */ +#define os_dev_shutdown_return(code) \ + return + +/*! + * Return from the #OS_DEV_ISR() function + * + * The function should verify that it really was supposed to be called, + * and that its device needed attention, in order to properly set the + * return code. + * + * @param code non-zero if interrupt handled, zero otherwise. + * + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) +#define os_dev_isr_return(code) \ +do { \ + /* Unused warnings */ \ + (void)N1_; \ + (void)N2_; \ + (void)N3_; \ + \ + return IRQ_RETVAL(code); \ +} while (0) +#else +#define os_dev_isr_return(code) \ +do { \ + /* Unused warnings */ \ + (void)N1_; \ + (void)N2_; \ + \ + return IRQ_RETVAL(code); \ +} while (0) +#endif + +/*! + * Return from the #OS_DEV_OPEN() function + * + * @param code An error code to report success or failure. + * + */ +#define os_dev_open_return(code) \ +do { \ + int retcode = code; \ + \ + /* get rid of 'unused parameter' warnings */ \ + (void)inode_p_; \ + (void)file_p_; \ + \ + return retcode; \ +} while (0) + +/*! + * Return from the #OS_DEV_IOCTL() function + * + * @param code An error code to report success or failure. + * + */ +#define os_dev_ioctl_return(code) \ +do { \ + int retcode = code; \ + \ + /* get rid of 'unused parameter' warnings */ \ + (void)inode_p_; \ + (void)file_p_; \ + (void)cmd_; \ + (void)data_; \ + \ + return retcode; \ +} while (0) + +/*! + * Return from the #OS_DEV_READ() function + * + * @param code Number of bytes read, or an error code to report failure. + * + */ +#define os_dev_read_return(code) \ +do { \ + ssize_t retcode = code; \ + \ + /* get rid of 'unused parameter' warnings */ \ + (void)file_p_; \ + (void)user_buffer_; \ + (void)count_bytes_; \ + (void)file_position_; \ + \ + return retcode; \ +} while (0) + +/*! + * Return from the #OS_DEV_WRITE() function + * + * @param code Number of bytes written, or an error code to report failure. + * + */ +#define os_dev_write_return(code) \ +do { \ + ssize_t retcode = code; \ + \ + /* get rid of 'unused parameter' warnings */ \ + (void)file_p_; \ + (void)user_buffer_; \ + (void)count_bytes_; \ + (void)file_position_; \ + \ + return retcode; \ +} while (0) + +/*! + * Return from the #OS_DEV_CLOSE() function + * + * @param code An error code to report success or failure. + * + */ +#define os_dev_close_return(code) \ +do { \ + ssize_t retcode = code; \ + \ + /* get rid of 'unused parameter' warnings */ \ + (void)inode_p_; \ + (void)file_p_; \ + \ + return retcode; \ +} while (0) + +/*! + * Start the #OS_DEV_TASK() function + * + * In some implementations, this could be turned into a label for + * the os_dev_task_return() call. + * + * @return none + */ +#define os_dev_task_begin() + +/*! + * Return from the #OS_DEV_TASK() function + * + * In some implementations, this could be turned into a sleep followed + * by a jump back to the os_dev_task_begin() call. + * + * @param code An error code to report success or failure. + * + */ +#define os_dev_task_return(code) \ +do { \ + /* Unused warnings */ \ + (void)data_; \ + \ + return; \ +} while (0) + +/***************************************************************************** + * Functions/Macros for accessing arguments from Driver Signature routines + *****************************************************************************/ + +/*! @defgroup drsigargs Functions for Getting Arguments in Signature functions + * + */ +/* @addtogroup @drsigargs */ +/*! @{ */ +/*! + * Used in #OS_DEV_OPEN(), #OS_DEV_CLOSE(), #OS_DEV_IOCTL(), #OS_DEV_READ() and + * #OS_DEV_WRITE() routines to check whether user is requesting read + * (permission) + */ +#define os_dev_is_flag_read() \ + (file_p_->f_mode & FMODE_READ) + +/*! + * Used in #OS_DEV_OPEN(), #OS_DEV_CLOSE(), #OS_DEV_IOCTL(), #OS_DEV_READ() and + * #OS_DEV_WRITE() routines to check whether user is requesting write + * (permission) + */ +#define os_dev_is_flag_write() \ + (file_p_->f_mode & FMODE_WRITE) + +/*! + * Used in #OS_DEV_OPEN(), #OS_DEV_CLOSE(), #OS_DEV_IOCTL(), #OS_DEV_READ() and + * #OS_DEV_WRITE() routines to check whether user is requesting non-blocking + * I/O. + */ +#define os_dev_is_flag_nonblock() \ + (file_p_->f_flags & (O_NONBLOCK | O_NDELAY)) + +/*! + * Used in #OS_DEV_OPEN() and #OS_DEV_CLOSE() to determine major device being + * accessed. + */ +#define os_dev_get_major() \ + (imajor(inode_p_)) + +/*! + * Used in #OS_DEV_OPEN() and #OS_DEV_CLOSE() to determine minor device being + * accessed. + */ +#define os_dev_get_minor() \ + (iminor(inode_p_)) + +/*! + * Used in #OS_DEV_IOCTL() to determine which operation the user wants + * performed. + * + * @return Value of the operation. + */ +#define os_dev_get_ioctl_op() \ + (cmd_) + +/*! + * Used in #OS_DEV_IOCTL() to return the associated argument for the desired + * operation. + * + * @return A value which can be cast to a struct pointer or used as + * int/long. + */ +#define os_dev_get_ioctl_arg() \ + (data_) + +/*! + * Used in OS_DEV_READ() and OS_DEV_WRITE() routines to access the requested + * byte count. + * + * @return (unsigned) a count of bytes + */ +#define os_dev_get_count() \ + ((unsigned)count_bytes_) + +/*! + * Used in OS_DEV_READ() and OS_DEV_WRITE() routines to return the pointer + * byte count. + * + * @return char* pointer to user buffer + */ +#define os_dev_get_user_buffer() \ + ((void*)user_buffer_) + +/*! + * Used in OS_DEV_READ(), OS_DEV_WRITE(), and OS_DEV_IOCTL() routines to + * get the POSIX flags field for the associated open file). + * + * @return The flags associated with the file. + */ +#define os_dev_get_file_flags() \ + (file_p_->f_flags) + +/*! + * Set the driver's private structure associated with this file/open. + * + * Generally used during #OS_DEV_OPEN(). See #os_dev_get_user_private(). + * + * @param struct_p The driver data structure to associate with this user. + */ +#define os_dev_set_user_private(struct_p) \ + file_p_->private_data = (void*)(struct_p) + +/*! + * Get the driver's private structure associated with this file. + * + * May be used during #OS_DEV_OPEN(), #OS_DEV_READ(), #OS_DEV_WRITE(), + * #OS_DEV_IOCTL(), and #OS_DEV_CLOSE(). See #os_dev_set_user_private(). + * + * @return The driver data structure to associate with this user. + */ +#define os_dev_get_user_private() \ + ((void*)file_p_->private_data) + +/*! + * Get the IRQ associated with this call to the #OS_DEV_ISR() function. + * + * @return The IRQ (integer) interrupt number. + */ +#define os_dev_get_irq() \ + N1_ + + /*! @} *//* drsigargs */ + +/*! + * @defgroup cacheops Cache Operations + * + * These functions are for synchronizing processor cache with RAM. + */ +/*! @addtogroup cacheops */ +/*! @{ */ + +/*! + * Flush and invalidate all cache lines. + */ +#if 0 +#define os_flush_cache_all() \ + flush_cache_all() +#else +/* Call ARM fn directly, in case L2cache=on3 not set */ +#define os_flush_cache_all() \ + v6_flush_kern_cache_all_L2() + +/*! + * ARM-routine to flush all cache. Defined here, because it exists in no + * easy-access header file. ARM-11 with L210 cache only! + */ +extern void v6_flush_kern_cache_all_L2(void); +#endif + +/* + * These macros are using part of the Linux DMA API. They rely on the + * map function to do nothing more than the equivalent clean/inv/flush + * operation at the time of the mapping, and do nothing at an unmapping + * call, which the Sahara driver code will never invoke. + */ + +/*! + * Clean a range of addresses from the cache. That is, write updates back + * to (RAM, next layer). + * + * @param start Starting virtual address + * @param len Number of bytes to flush + * + * @return void + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) +#define os_cache_clean_range(start,len) \ + dma_map_single(NULL, (void*)start, len, DMA_TO_DEVICE) +#else +#define os_cache_clean_range(start,len) \ +{ \ + void *s = (void*)start; \ + void *e = s + len; \ + dmac_clean_range(s, e); \ + outer_clean_range(__pa(s), __pa(e)); \ +} +#endif + +/*! + * Invalidate a range of addresses in the cache + * + * @param start Starting virtual address + * @param len Number of bytes to flush + * + * @return void + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) +#define os_cache_inv_range(start,len) \ + dma_map_single(NULL, (void*)start, len, DMA_FROM_DEVICE) +#else +#define os_cache_inv_range(start,len) \ +{ \ + void *s = (void*)start; \ + void *e = s + len; \ + dmac_inv_range(s, e); \ + outer_inv_range(__pa(s), __pa(e)); \ +} +#endif + +/*! + * Flush a range of addresses from the cache. That is, perform clean + * and invalidate + * + * @param start Starting virtual address + * @param len Number of bytes to flush + * + * @return void + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) +#define os_cache_flush_range(start,len) \ + dma_map_single(NULL, (void*)start, len, DMA_BIDIRECTIONAL) +#else +#define os_cache_flush_range(start,len) \ +{ \ + void *s = (void*)start; \ + void *e = s + len; \ + dmac_flush_range(s, e); \ + outer_flush_range(__pa(s), __pa(e)); \ +} +#endif + + /*! @} *//* cacheops */ + +#endif /* LINUX_PORT_H */ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/include/fsl_shw.h +++ linux-2.6.28/drivers/mxc/security/sahara2/include/fsl_shw.h @@ -0,0 +1,2515 @@ +/* + * Copyright 2004-2009 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 + */ + +/* + * NOTE TO MAINTAINERS: Although this header file is *the* header file to be + * #include'd by FSL SHW programs, it does not itself make any definitions for + * the API. Instead, it uses the fsl_platform.h file and / or compiler + * environment variables to determine which actual driver header file to + * include. This allows different implementations to contain different + * implementations of the various objects, macros, etc., or even to change + * which functions are macros and which are not. + */ + +/*! + * @file fsl_shw.h + * + * @brief Definition of the Freescale Security Hardware API. + * + * See @ref index for an overview of the API. + */ + +/*! + * @if USE_MAINPAGE + * @mainpage Common API for Freescale Security Hardware (FSL SHW API) + * @endif + * + * @section intro_sec Introduction + * + * This is the interface definition for the Freescale Security Hardware API + * (FSL SHW API) for User Mode and Kernel Mode to access Freescale Security + * Hardware components for cryptographic acceleration. The API is intended to + * provide cross-platform access to security hardware components of Freescale. + * + * This documentation has not been approved, and should not be taken to + * mean anything definite about future direction. + * + * Some example code is provided to give some idea of usage of this API. + * + * Note: This first version has been defined around the capabilities of the + * Sahara2 cryptographic accelerator, and may be expanded in the future to + * provide support for other platforms. The Platform Capabilities Object is + * intended as a way to allow programs to adapt to different platforms. + * + * The i.MX25 is an example of a platform without a SAHARA but yet has + * capabilities supported by this API. These include #fsl_shw_get_random() and + * #fsl_shw_add_entropy(), and the use of Triple-DES (TDEA) cipher algorithm + * (with no checking of key parity supported) in ECB and CBC modes with @ref + * sym_sec. See also the @ref di_sec for information on key handling, and @ref + * td_sec for detection of Tamper Events. Only the random functions are + * available from user space on this platform. + * + * @section usr_ctx The User Context + * + * The User Context Object (#fsl_shw_uco_t) controls the interaction between + * the user program and the API. It is initialized as part of user + * registration (#fsl_shw_register_user()), and is part of every interaction + * thereafter. + * + * @section pf_sec Platform Capabilities + * + * Since this API is not tied to one specific type of hardware or even one + * given version of a given type of hardware, the platform capabilities object + * could be used by a portable program to make choices about using software + * instead of hardware for certain operations. + * + * See the #fsl_shw_pco_t, returned by #fsl_shw_get_capabilities(). + * + * @ref pcoops are provided to query its contents. + * + * + * @section sym_sec Symmetric-Key Encryption and Decryption + * + * Symmetric-Key encryption support is provided for the block cipher algorithms + * AES, DES, and Triple DES. Modes supported are #FSL_SYM_MODE_ECB, + * #FSL_SYM_MODE_CBC, and #FSL_SYM_MODE_CTR, though not necessarily all modes + * for all algorithms. There is also support for the stream cipher algorithm + * commonly known as ARC4. + * + * Encryption and decryption are performed by using the functions + * #fsl_shw_symmetric_encrypt() and #fsl_shw_symmetric_decrypt(), respectively. + * There are two objects which provide information about the operation of these + * functions. They are the #fsl_shw_sko_t, to provide key and algorithm + * information; and the #fsl_shw_scco_t, to provide (and store) initial context + * or counter value information. + * + * CCM is not supported by these functions. For information CCM support, see + * @ref cmb_sec. + * + * + * @section hash_sec Cryptographic Hashing + * + * Hashing is performed by fsl_shw_hash(). Control of the function is through + * flags in the #fsl_shw_hco_t. The algorithms which are + * supported are listed in #fsl_shw_hash_alg_t. + * + * The hashing function works on octet streams. If a user application needs to + * hash a bitstream, it will need to do its own padding of the last block. + * + * + * @section hmac_sec Hashed Message Authentication Codes + * + * An HMAC is a method of combining a hash and a key so that a message cannot + * be faked by a third party. + * + * The #fsl_shw_hmac() can be used by itself for one-shot or multi-step + * operations, or in combination with #fsl_shw_hmac_precompute() to provide the + * ability to compute and save the beginning hashes from a key one time, and + * then use #fsl_shw_hmac() to calculate an HMAC on each message as it is + * processed. + * + * The maximum key length which is directly supported by this API is 64 octets. + * If a longer key size is needed for HMAC, the user will have to hash the key + * and present the digest value as the key to be used by the HMAC functions. + * + * + * @section rnd_sec Random Numbers + * + * Support is available for acquiring random values from a + * cryptographically-strong random number generator. See + * #fsl_shw_get_random(). The function #fsl_shw_add_entropy() may be used to + * add entropy to the random number generator. + * + * + * @section cmb_sec Combined Cipher and Authentication + * + * Some schemes require that messages be encrypted and that they also have an + * authentication code associated with the message. The function + * #fsl_shw_gen_encrypt() will generate the authentication code and encrypt the + * message. + * + * Upon receipt of such a message, the message must be decrypted and the + * authentication code validated. The function + * #fsl_shw_auth_decrypt() will perform these steps. + * + * Only AES-CCM is supported. + * + * + * @section wrap_sec Wrapped Keys + * + * On platforms with a Secure Memory, the function #fsl_shw_establish_key() can + * be used to place a key into the System Keystore. This key then can be used + * directly by the cryptographic hardware. It later then be wrapped + * (cryptographically obscured) by #fsl_shw_extract_key() and stored for later + * use. If a software key (#FSL_SKO_KEY_SW_KEY) was established, then its + * value can be retrieved with a call to #fsl_shw_read_key(). + * + * The wrapping and unwrapping functions provide security against unauthorized + * use and detection of tampering. + * + * The functions can also be used with a User Keystore. + * + * @section smalloc_sec Secure Memory Allocation + * + * On platforms with multiple partitions of Secure Memory, the function + * #fsl_shw_smalloc() can be used to acquire a partition for private use. The + * function #fsl_shw_diminish_perms() can then be used to revoke specific + * permissions on the partition, and #fsl_shw_sfree() can be used to release the + * partition. + * + * @section keystore_sec User Keystore + * + * User Keystore functionality is defined in fsl_shw_keystore.h. See @ref + * user_keystore for details. This is not supported on platforms without SCC2. + * + * @section di_sec Hardware key-select extensions - DryIce + * + * Some platforms have a component called DryIce which allows the software to + * control which key will be used by the secure memory encryption hardware. + * The choices are the secret per-chip Fused (IIM) Key, an unknown, hardware- + * generated Random Key, a software-written Programmed Key, or the IIM Key in + * combination with one of the others. #fsl_shw_pco_check_pk_supported() can + * be used to determine whether this feature is available on the platform. + * The rest of this section will explain the symmetric ciphering and key + * operations which are available on such a platform. + * + * The function #fsl_shw_sko_init_pf_key() will set up a Secret Key Object to + * refer to one of the system's platform keys. All keys which reference a + * platform key must use this initialization function, including a user- + * provided key value. Keys which are intended for software encryption must + * use #fsl_shw_sko_init(). + * + * To change the setting of the Programmed Key of the DryIce module, + * #fsl_shw_establish_key() must be called with a platform key object of type + * #FSL_SHW_PF_KEY_PRG or #FSL_SHW_PF_KEY_IIM_PRG. The key will be go + * into the PK register of DryIce and not to the keystore. Any symmetric + * operation which references either #FSL_SHW_PF_KEY_PRG or + * #FSL_SHW_PF_KEY_IIM_PRG will use the current PK value (possibly modified by + * the secret fused IIM key). Before the Flatform Key can be changed, a call to + * #fsl_shw_release_key() or #fsl_shw_extract_key() must be made. Neither + * function will change the value in the PK registers, and further ciphering + * can take place. + * + * When #fsl_shw_establish_key() is called to change the PK value, a plaintext + * key can be passed in with the #FSL_KEY_WRAP_ACCEPT argument or a previously + * wrapped key can be passed in with the #FSL_KEY_WRAP_UNWRAP argument. If + * #FSL_KEY_WRAP_CREATE is passed in, then a random value will be loaded into + * the PK register. The PK value can be wrapped by a call to + * #fsl_shw_extract_key() for later use with the #FSL_KEY_WRAP_UNWRAP argument. + * + * As an alternative to using only the fused key for @ref wrap_sec, + * #fsl_shw_uco_set_wrap_key() can be used to select either the random key or + * the random key with the fused key as the key which will be used to protect + * the one-time value used to wrap the key. This allows for these + * wrapped keys to be dependent upon and therefore unrecoverable after a tamper + * event causes the erasure of the DryIce Random Key register. + * + * The software can request that the hardware generate a (new) Random Key for + * DryIce by calling #fsl_shw_gen_random_pf_key(). + * + * + * @section td_sec Device Tamper-Detection + * + * Some platforms have a component which can detect certain types of tampering + * with the hardware. #fsl_shw_read_tamper_event() API will allow the + * retrieval of the type of event which caused a tamper-detection failure. + * + */ + +/*! @defgroup glossary Glossary + * + * @li @b AES - Advanced Encryption Standard - An NIST-created block cipher + * originally knowns as Rijndael. + * @li @b ARC4 - ARCFOUR - An S-Box-based OFB mode stream cipher. + * @li @b CBC - Cipher-Block Chaining - Each encrypted block is XORed with the + * result of the previous block's encryption. + * @li @b CCM - A way of combining CBC and CTR to perform cipher and + * authentication. + * @li @b ciphertext - @a plaintext which has been encrypted in some fashion. + * @li @b context - Information on the state of a cryptographic operation, + * excluding any key. This could include IV, Counter Value, or SBox. + * @li @b CTR - A mode where a counter value is encrypted and then XORed with + * the data. After each block, the counter value is incremented. + * @li @b DES - Data Encryption Standard - An 8-octet-block cipher. + * @li @b ECB - Electronic Codebook - A straight encryption/decryption of the + * data. + * @li @b hash - A cryptographically strong one-way function performed on data. + * @li @b HMAC - Hashed Message Authentication Code - A key-dependent one-way + * hash result, used to verify authenticity of a message. The equation + * for an HMAC is hash((K + A) || hash((K + B) || msg)), where K is the + * key, A is the constant for the outer hash, B is the constant for the + * inner hash, and hash is the hashing function (MD5, SHA256, etc). + * @li @b IPAD - In an HMAC operation, the context generated by XORing the key + * with a constant and then hashing that value as the first block of the + * inner hash. + * @li @b IV - An "Initial Vector" or @a context for modes like CBC. + * @li @b MAC - A Message Authentication Code. HMAC, hashing, and CCM all + * produce a MAC. + * @li @b mode - A way of using a cryptographic algorithm. See ECB, CBC, etc. + * @li @b MD5 - Message Digest 5 - A one-way hash function. + * @li @b plaintext - Data which has not been encrypted, or has been decrypted + * from @a ciphertext. + * @li @b OPAD - In an HMAC operation, the context generated by XORing the key + * with a constant and then hashing that value as the first block of the + * outer hash. + * @li @b SHA - Secure Hash Algorithm - A one-way hash function. + * @li @b TDES - AKA @b 3DES - Triple Data Encryption Standard - A method of + * using two or three keys and DES to perform three operations (encrypt + * decrypt encrypt) to create a new algorithm. + * @li @b XOR - Exclusive-OR. A Boolean arithmetic function. + * @li @b Wrapped value - A (key) which has been encrypted into an opaque datum + * which cannot be unwrapped (decrypted) for use except by an authorized + * user. Once created, the key is never visible, but may be used for + * other cryptographic operations. + */ + +#ifndef FSL_SHW_H +#define FSL_SHW_H + +/* Set FSL_HAVE_* flags */ + +#include "fsl_platform.h" + +#ifndef API_DOC + +#if defined(FSL_HAVE_SAHARA2) || defined(FSL_HAVE_SAHARA4) + +#include "sahara.h" + +#else + +#if defined(FSL_HAVE_RNGA) || defined(FSL_HAVE_RNGB) || defined(FSL_HAVE_RNGC) + +#include "rng_driver.h" + +#else + +#error FSL_SHW_API_platform_not_recognized + +#endif + +#endif /* HAVE SAHARA */ + +#else /* API_DOC */ + +#include /* for uint32_t, etc. */ +#include /* Mainly for definition of NULL !! */ + +/* These groups will appear in the order in which they are defined. */ + +/*! + * @defgroup strgrp Objects + * + * These objects are used to pass information into and out of the API. Through + * flags and other settings, they control the behavior of the @ref opfuns. + * + * They are manipulated and queried by use of the various access functions. + * There are different sets defined for each object. See @ref objman. + */ + +/*! + * @defgroup consgrp Enumerations and other Constants + * + * This collection of symbols comprise the values which can be passed into + * various functions to control how the API will work. + */ + +/*! @defgroup opfuns Operational Functions + * + * These functions request that the underlying hardware perform cryptographic + * operations. They are the heart of the API. + */ + +/****** Organization the Object Operations under one group ! **********/ +/*! @defgroup objman Object-Manipulation Operations + * + */ +/*! @addtogroup objman + @{ */ +/*! + * @defgroup pcoops Platform Context Object Operations + * + * The Platform Context object is "read-only", so only query operations are + * provided for it. It is returned by the #fsl_shw_get_capabilities() + * function. + */ + +/*! @defgroup ucoops User Context Operations + * + * These operations should be the only access to the #fsl_shw_uco_t + * type/struct, as the internal members of the object are subject to change. + * The #fsl_shw_uco_init() function must be called before any other use of the + * object. + */ + +/*! + * @defgroup rops Result Object Operations + * + * As the Result Object contains the result of one of the @ref opfuns. The + * manipulations provided are query-only. No initialization is needed for this + * object. + */ + +/*! + * @defgroup skoops Secret Key Object Operations + * + * These operations should be the only access to the #fsl_shw_sko_t + * type/struct, as the internal members of that object are subject to change. + */ + +/*! + * @defgroup ksoops Keystore Object Operations + * + * These operations should be the only access to the #fsl_shw_kso_t + * type/struct, as the internal members of that object are subject to change. + */ + +/*! + * @defgroup hcops Hash Context Object Operations + * + * These operations should be the only access to the #fsl_shw_hco_t + * type/struct, as the internal members of that object are subject to change. + */ + +/*! + * @defgroup hmcops HMAC Context Object Operations + * + * These operations should be the only access to the #fsl_shw_hmco_t + * type/struct, as the internal members of that object are subject to change. + */ + +/*! + * @defgroup sccops Symmetric Cipher Context Operations + * + * These operations should be the only access to the #fsl_shw_scco_t + * type/struct, as the internal members of that object are subject to change + */ + +/*! @defgroup accoops Authentication-Cipher Context Object Operations + * + * These functions operate on a #fsl_shw_acco_t. Their purpose is to set + * flags, fields, etc., in order to control the operation of + * #fsl_shw_gen_encrypt() and #fsl_shw_auth_decrypt(). + */ + + /* @} *//************ END GROUPING of Object Manipulations *****************/ + +/*! @defgroup miscfuns Miscellaneous Functions + * + * These functions are neither @ref opfuns nor @ref objman. Their behavior + * does not depend upon the flags in the #fsl_shw_uco_t, yet they may involve + * more interaction with the library and the kernel than simply querying an + * object. + */ + +/****************************************************************************** + * Enumerations + *****************************************************************************/ +/*! @addtogroup consgrp + @{ */ + +/*! + * Flags for the state of the User Context Object (#fsl_shw_uco_t). + * + * These flags describe how the @ref opfuns will operate. + */ +typedef enum fsl_shw_user_ctx_flags_t { + /*! + * API will block the caller until operation completes. The result will be + * available in the return code. If this is not set, user will have to get + * results using #fsl_shw_get_results(). + */ + FSL_UCO_BLOCKING_MODE, + /*! + * User wants callback (at the function specified with + * #fsl_shw_uco_set_callback()) when the operation completes. This flag is + * valid only if #FSL_UCO_BLOCKING_MODE is not set. + */ + FSL_UCO_CALLBACK_MODE, + /*! Do not free descriptor chain after driver (adaptor) finishes */ + FSL_UCO_SAVE_DESC_CHAIN, + /*! + * User has made at least one request with callbacks requested, so API is + * ready to handle others. + */ + FSL_UCO_CALLBACK_SETUP_COMPLETE, + /*! + * (virtual) pointer to descriptor chain is completely linked with physical + * (DMA) addresses, ready for the hardware. This flag should not be used + * by FSL SHW API programs. + */ + FSL_UCO_CHAIN_PREPHYSICALIZED, + /*! + * The user has changed the context but the changes have not been copied to + * the kernel driver. + */ + FSL_UCO_CONTEXT_CHANGED, + /*! Internal Use. This context belongs to a user-mode API user. */ + FSL_UCO_USERMODE_USER, +} fsl_shw_user_ctx_flags_t; + +/*! + * Return code for FSL_SHW library. + * + * These codes may be returned from a function call. In non-blocking mode, + * they will appear as the status in a Result Object. + */ +typedef enum fsl_shw_return_t { + /*! + * No error. As a function return code in Non-blocking mode, this may + * simply mean that the operation was accepted for eventual execution. + */ + FSL_RETURN_OK_S = 0, + /*! Failure for non-specific reason. */ + FSL_RETURN_ERROR_S, + /*! + * Operation failed because some resource was not able to be allocated. + */ + FSL_RETURN_NO_RESOURCE_S, + /*! Crypto algorithm unrecognized or improper. */ + FSL_RETURN_BAD_ALGORITHM_S, + /*! Crypto mode unrecognized or improper. */ + FSL_RETURN_BAD_MODE_S, + /*! Flag setting unrecognized or inconsistent. */ + FSL_RETURN_BAD_FLAG_S, + /*! Improper or unsupported key length for algorithm. */ + FSL_RETURN_BAD_KEY_LENGTH_S, + /*! Improper parity in a (DES, TDES) key. */ + FSL_RETURN_BAD_KEY_PARITY_S, + /*! + * Improper or unsupported data length for algorithm or internal buffer. + */ + FSL_RETURN_BAD_DATA_LENGTH_S, + /*! Authentication / Integrity Check code check failed. */ + FSL_RETURN_AUTH_FAILED_S, + /*! A memory error occurred. */ + FSL_RETURN_MEMORY_ERROR_S, + /*! An error internal to the hardware occurred. */ + FSL_RETURN_INTERNAL_ERROR_S, + /*! ECC detected Point at Infinity */ + FSL_RETURN_POINT_AT_INFINITY_S, + /*! ECC detected No Point at Infinity */ + FSL_RETURN_POINT_NOT_AT_INFINITY_S, + /*! GCD is One */ + FSL_RETURN_GCD_IS_ONE_S, + /*! GCD is not One */ + FSL_RETURN_GCD_IS_NOT_ONE_S, + /*! Candidate is Prime */ + FSL_RETURN_PRIME_S, + /*! Candidate is not Prime */ + FSL_RETURN_NOT_PRIME_S, + /*! N register loaded improperly with even value */ + FSL_RETURN_EVEN_MODULUS_ERROR_S, + /*! Divisor is zero. */ + FSL_RETURN_DIVIDE_BY_ZERO_ERROR_S, + /*! Bad Exponent or Scalar value for Point Multiply */ + FSL_RETURN_BAD_EXPONENT_ERROR_S, + /*! RNG hardware problem. */ + FSL_RETURN_OSCILLATOR_ERROR_S, + /*! RNG hardware problem. */ + FSL_RETURN_STATISTICS_ERROR_S, +} fsl_shw_return_t; + +/*! + * Algorithm Identifier. + * + * Selection of algorithm will determine how large the block size of the + * algorithm is. Context size is the same length unless otherwise specified. + * Selection of algorithm also affects the allowable key length. + */ +typedef enum fsl_shw_key_alg_t { + FSL_KEY_ALG_HMAC, /*!< Key will be used to perform an HMAC. Key + size is 1 to 64 octets. Block size is 64 + octets. */ + FSL_KEY_ALG_AES, /*!< Advanced Encryption Standard (Rijndael). + Block size is 16 octets. Key size is 16 + octets. (The single choice of key size is a + Sahara platform limitation.) */ + FSL_KEY_ALG_DES, /*!< Data Encryption Standard. Block size is + 8 octets. Key size is 8 octets. */ + FSL_KEY_ALG_TDES, /*!< 2- or 3-key Triple DES. Block size is 8 + octets. Key size is 16 octets for 2-key + Triple DES, and 24 octets for 3-key. */ + FSL_KEY_ALG_ARC4 /*!< ARC4. No block size. Context size is 259 + octets. Allowed key size is 1-16 octets. + (The choices for key size are a Sahara + platform limitation.) */ +} fsl_shw_key_alg_t; + +/*! + * Mode selector for Symmetric Ciphers. + * + * The selection of mode determines how a cryptographic algorithm will be + * used to process the plaintext or ciphertext. + * + * For all modes which are run block-by-block (that is, all but + * #FSL_SYM_MODE_STREAM), any partial operations must be performed on a text + * length which is multiple of the block size. Except for #FSL_SYM_MODE_CTR, + * these block-by-block algorithms must also be passed a total number of octets + * which is a multiple of the block size. + * + * In modes which require that the total number of octets of data be a multiple + * of the block size (#FSL_SYM_MODE_ECB and #FSL_SYM_MODE_CBC), and the user + * has a total number of octets which are not a multiple of the block size, the + * user must perform any necessary padding to get to the correct data length. + */ +typedef enum fsl_shw_sym_mode_t { + /*! + * Stream. There is no associated block size. Any request to process data + * may be of any length. This mode is only for ARC4 operations, and is + * also the only mode used for ARC4. + */ + FSL_SYM_MODE_STREAM, + + /*! + * Electronic Codebook. Each block of data is encrypted/decrypted. The + * length of the data stream must be a multiple of the block size. This + * mode may be used for DES, 3DES, and AES. The block size is determined + * by the algorithm. + */ + FSL_SYM_MODE_ECB, + /*! + * Cipher-Block Chaining. Each block of data is encrypted/decrypted and + * then "chained" with the previous block by an XOR function. Requires + * context to start the XOR (previous block). This mode may be used for + * DES, 3DES, and AES. The block size is determined by the algorithm. + */ + FSL_SYM_MODE_CBC, + /*! + * Counter. The counter is encrypted, then XORed with a block of data. + * The counter is then incremented (using modulus arithmetic) for the next + * block. The final operation may be non-multiple of block size. This mode + * may be used for AES. The block size is determined by the algorithm. + */ + FSL_SYM_MODE_CTR, +} fsl_shw_sym_mode_t; + +/*! + * Algorithm selector for Cryptographic Hash functions. + * + * Selection of algorithm determines how large the context and digest will be. + * Context is the same size as the digest (resulting hash), unless otherwise + * specified. + */ +typedef enum fsl_shw_hash_alg_t { + FSL_HASH_ALG_MD5, /*!< MD5 algorithm. Digest is 16 octets. */ + FSL_HASH_ALG_SHA1, /*!< SHA-1 (aka SHA or SHA-160) algorithm. + Digest is 20 octets. */ + FSL_HASH_ALG_SHA224, /*!< SHA-224 algorithm. Digest is 28 octets, + though context is 32 octets. */ + FSL_HASH_ALG_SHA256 /*!< SHA-256 algorithm. Digest is 32 + octets. */ +} fsl_shw_hash_alg_t; + +/*! + * The type of Authentication-Cipher function which will be performed. + */ +typedef enum fsl_shw_acc_mode_t { + /*! + * CBC-MAC for Counter. Requires context and modulus. Final operation may + * be non-multiple of block size. This mode may be used for AES. + */ + FSL_ACC_MODE_CCM, + /*! + * SSL mode. Not supported. Combines HMAC and encrypt (or decrypt). + * Needs one key object for encryption, another for the HMAC. The usual + * hashing and symmetric encryption algorithms are supported. + */ + FSL_ACC_MODE_SSL, +} fsl_shw_acc_mode_t; + +/*! + * The operation which controls the behavior of #fsl_shw_establish_key(). + * + * These values are passed to #fsl_shw_establish_key(). + */ +typedef enum fsl_shw_key_wrap_t { + FSL_KEY_WRAP_CREATE, /*!< Generate a key from random values. */ + FSL_KEY_WRAP_ACCEPT, /*!< Use the provided clear key. */ + FSL_KEY_WRAP_UNWRAP /*!< Unwrap a previously wrapped key. */ +} fsl_shw_key_wrap_t; + +/* REQ-S2LRD-PINTFC-COA-HCO-001 */ +/*! + * Flags which control a Hash operation. + * + * These may be combined by ORing them together. See #fsl_shw_hco_set_flags() + * and #fsl_shw_hco_clear_flags(). + */ +typedef enum fsl_shw_hash_ctx_flags_t { + FSL_HASH_FLAGS_INIT = 1, /*!< Context is empty. Hash is started + from scratch, with a message-processed + count of zero. */ + FSL_HASH_FLAGS_SAVE = 2, /*!< Retrieve context from hardware after + hashing. If used with the + #FSL_HASH_FLAGS_FINALIZE flag, the final + digest value will be saved in the + object. */ + FSL_HASH_FLAGS_LOAD = 4, /*!< Place context into hardware before + hashing. */ + FSL_HASH_FLAGS_FINALIZE = 8, /*!< PAD message and perform final digest + operation. If user message is + pre-padded, this flag should not be + used. */ +} fsl_shw_hash_ctx_flags_t; + +/*! + * Flags which control an HMAC operation. + * + * These may be combined by ORing them together. See #fsl_shw_hmco_set_flags() + * and #fsl_shw_hmco_clear_flags(). + */ +typedef enum fsl_shw_hmac_ctx_flags_t { + FSL_HMAC_FLAGS_INIT = 1, /*!< Message context is empty. HMAC is + started from scratch (with key) or from + precompute of inner hash, depending on + whether + #FSL_HMAC_FLAGS_PRECOMPUTES_PRESENT is + set. */ + FSL_HMAC_FLAGS_SAVE = 2, /*!< Retrieve ongoing context from hardware + after hashing. If used with the + #FSL_HMAC_FLAGS_FINALIZE flag, the final + digest value (HMAC) will be saved in the + object. */ + FSL_HMAC_FLAGS_LOAD = 4, /*!< Place ongoing context into hardware + before hashing. */ + FSL_HMAC_FLAGS_FINALIZE = 8, /*!< PAD message and perform final HMAC + operations of inner and outer hashes. */ + FSL_HMAC_FLAGS_PRECOMPUTES_PRESENT = 16 /*!< This means that the context + contains precomputed inner and outer + hash values. */ +} fsl_shw_hmac_ctx_flags_t; + +/*! + * Flags to control use of the #fsl_shw_scco_t. + * + * These may be ORed together to get the desired effect. + * See #fsl_shw_scco_set_flags() and #fsl_shw_scco_clear_flags() + */ +typedef enum fsl_shw_sym_ctx_flags_t { + /*! + * Context is empty. In ARC4, this means that the S-Box needs to be + * generated from the key. In #FSL_SYM_MODE_CBC mode, this allows an IV of + * zero to be specified. In #FSL_SYM_MODE_CTR mode, it means that an + * initial CTR value of zero is desired. + */ + FSL_SYM_CTX_INIT = 1, + /*! + * Load context from object into hardware before running cipher. In + * #FSL_SYM_MODE_CTR mode, this would refer to the Counter Value. + */ + FSL_SYM_CTX_LOAD = 2, + /*! + * Save context from hardware into object after running cipher. In + * #FSL_SYM_MODE_CTR mode, this would refer to the Counter Value. + */ + FSL_SYM_CTX_SAVE = 4, + /*! + * Context (SBox) is to be unwrapped and wrapped on each use. + * This flag is unsupported. + * */ + FSL_SYM_CTX_PROTECT = 8, +} fsl_shw_sym_ctx_flags_t; + +/*! + * Flags which describe the state of the #fsl_shw_sko_t. + * + * These may be ORed together to get the desired effect. + * See #fsl_shw_sko_set_flags() and #fsl_shw_sko_clear_flags() + */ +typedef enum fsl_shw_key_flags_t { + FSL_SKO_KEY_IGNORE_PARITY = 1, /*!< If algorithm is DES or 3DES, do not + validate the key parity bits. */ + FSL_SKO_KEY_PRESENT = 2, /*!< Clear key is present in the object. */ + FSL_SKO_KEY_ESTABLISHED = 4, /*!< Key has been established for use. This + feature is not available for all + platforms, nor for all algorithms and + modes. */ + FSL_SKO_KEY_SW_KEY = 8, /*!< This key is for software use, and can + be copied out of a keystore by its owner. + The default is that they key is available + only for hardware (or security driver) + use. */ +} fsl_shw_key_flags_t; + +/*! + * Type of value which is associated with an established key. + */ +typedef uint64_t key_userid_t; + +/*! + * Flags which describe the state of the #fsl_shw_acco_t. + * + * The @a FSL_ACCO_CTX_INIT and @a FSL_ACCO_CTX_FINALIZE flags, when used + * together, provide for a one-shot operation. + */ +typedef enum fsl_shw_auth_ctx_flags_t { + FSL_ACCO_CTX_INIT = 1, /*!< Initialize Context(s) */ + FSL_ACCO_CTX_LOAD = 2, /*!< Load intermediate context(s). + This flag is unsupported. */ + FSL_ACCO_CTX_SAVE = 4, /*!< Save intermediate context(s). + This flag is unsupported. */ + FSL_ACCO_CTX_FINALIZE = 8, /*!< Create MAC during this operation. */ + FSL_ACCO_NIST_CCM = 16, /*!< Formatting of CCM input data is + performed by calls to + #fsl_shw_ccm_nist_format_ctr_and_iv() and + #fsl_shw_ccm_nist_update_ctr_and_iv(). */ +} fsl_shw_auth_ctx_flags_t; + +/*! + * Modulus Selector for CTR modes. + * + * The incrementing of the Counter value may be modified by a modulus. If no + * modulus is needed or desired for AES, use #FSL_CTR_MOD_128. + */ +typedef enum fsl_shw_ctr_mod_t { + FSL_CTR_MOD_8, /*!< Run counter with modulus of 2^8. */ + FSL_CTR_MOD_16, /*!< Run counter with modulus of 2^16. */ + FSL_CTR_MOD_24, /*!< Run counter with modulus of 2^24. */ + FSL_CTR_MOD_32, /*!< Run counter with modulus of 2^32. */ + FSL_CTR_MOD_40, /*!< Run counter with modulus of 2^40. */ + FSL_CTR_MOD_48, /*!< Run counter with modulus of 2^48. */ + FSL_CTR_MOD_56, /*!< Run counter with modulus of 2^56. */ + FSL_CTR_MOD_64, /*!< Run counter with modulus of 2^64. */ + FSL_CTR_MOD_72, /*!< Run counter with modulus of 2^72. */ + FSL_CTR_MOD_80, /*!< Run counter with modulus of 2^80. */ + FSL_CTR_MOD_88, /*!< Run counter with modulus of 2^88. */ + FSL_CTR_MOD_96, /*!< Run counter with modulus of 2^96. */ + FSL_CTR_MOD_104, /*!< Run counter with modulus of 2^104. */ + FSL_CTR_MOD_112, /*!< Run counter with modulus of 2^112. */ + FSL_CTR_MOD_120, /*!< Run counter with modulus of 2^120. */ + FSL_CTR_MOD_128 /*!< Run counter with modulus of 2^128. */ +} fsl_shw_ctr_mod_t; + +/*! + * Permissions flags for Secure Partitions + * + * They currently map directly to the SCC2 hardware values, but this is not + * guarinteed behavior. + */ +typedef enum fsl_shw_permission_t { +/*! SCM Access Permission: Do not zeroize/deallocate partition on SMN Fail state */ + FSL_PERM_NO_ZEROIZE, +/*! SCM Access Permission: Enforce trusted key read in */ + FSL_PERM_TRUSTED_KEY_READ, +/*! SCM Access Permission: Ignore Supervisor/User mode in permission determination */ + FSL_PERM_HD_S, +/*! SCM Access Permission: Allow Read Access to Host Domain */ + FSL_PERM_HD_R, +/*! SCM Access Permission: Allow Write Access to Host Domain */ + FSL_PERM_HD_W, +/*! SCM Access Permission: Allow Execute Access to Host Domain */ + FSL_PERM_HD_X, +/*! SCM Access Permission: Allow Read Access to Trusted Host Domain */ + FSL_PERM_TH_R, +/*! SCM Access Permission: Allow Write Access to Trusted Host Domain */ + FSL_PERM_TH_W, +/*! SCM Access Permission: Allow Read Access to Other/World Domain */ + FSL_PERM_OT_R, +/*! SCM Access Permission: Allow Write Access to Other/World Domain */ + FSL_PERM_OT_W, +/*! SCM Access Permission: Allow Execute Access to Other/World Domain */ + FSL_PERM_OT_X, +} fsl_shw_permission_t; + +/*! + * Select the cypher mode to use for partition cover/uncover operations. + * + * They currently map directly to the values used in the SCC2 driver, but this + * is not guarinteed behavior. + */ +typedef enum fsl_shw_cypher_mode_t { + FSL_SHW_CYPHER_MODE_ECB, /*!< ECB mode */ + FSL_SHW_CYPHER_MODE_CBC, /*!< CBC mode */ +} fsl_shw_cypher_mode_t; + +/*! + * Which platform key should be presented for cryptographic use. + */ +typedef enum fsl_shw_pf_key_t { + FSL_SHW_PF_KEY_IIM, /*!< Present fused IIM key */ + FSL_SHW_PF_KEY_PRG, /*!< Present Program key */ + FSL_SHW_PF_KEY_IIM_PRG, /*!< Present IIM ^ Program key */ + FSL_SHW_PF_KEY_IIM_RND, /*!< Present Random key */ + FSL_SHW_PF_KEY_RND, /*!< Present IIM ^ Random key */ +} fsl_shw_pf_key_t; + +/*! + * The various security tamper events + */ +typedef enum fsl_shw_tamper_t { + FSL_SHW_TAMPER_NONE, /*!< No error detected */ + FSL_SHW_TAMPER_WTD, /*!< wire-mesh tampering det */ + FSL_SHW_TAMPER_ETBD, /*!< ext tampering det: input B */ + FSL_SHW_TAMPER_ETAD, /*!< ext tampering det: input A */ + FSL_SHW_TAMPER_EBD, /*!< external boot detected */ + FSL_SHW_TAMPER_SAD, /*!< security alarm detected */ + FSL_SHW_TAMPER_TTD, /*!< temperature tampering det */ + FSL_SHW_TAMPER_CTD, /*!< clock tampering det */ + FSL_SHW_TAMPER_VTD, /*!< voltage tampering det */ + FSL_SHW_TAMPER_MCO, /*!< monotonic counter overflow */ + FSL_SHW_TAMPER_TCO, /*!< time counter overflow */ +} fsl_shw_tamper_t; + +/*! @} *//* consgrp */ + +/****************************************************************************** + * Data Structures + *****************************************************************************/ +/*! @addtogroup strgrp + @{ */ + +/* REQ-S2LRD-PINTFC-COA-IBO-001 */ +/*! + * Application Initialization Object + * + * This object, the operations on it, and its interaction with the driver are + * TBD. + */ +typedef struct fsl_sho_ibo_t { +} fsl_sho_ibo_t; + +/* REQ-S2LRD-PINTFC-COA-UCO-001 */ +/*! + * User Context Object + * + * This object must be initialized by a call to #fsl_shw_uco_init(). It must + * then be passed to #fsl_shw_register_user() before it can be used in any + * calls besides those in @ref ucoops. + * + * It contains the user's configuration for the API, for instance whether an + * operation should block, or instead should call back the user upon completion + * of the operation. + * + * See @ref ucoops for further information. + */ +typedef struct fsl_shw_uco_t { /* fsl_shw_user_context_object */ +} fsl_shw_uco_t; + +/* REQ-S2LRD-PINTFC-API-GEN-006 ?? */ +/*! + * Result Object + * + * This object will contain success and failure information about a specific + * cryptographic request which has been made. + * + * No direct access to its members should be made by programs. Instead, the + * object should be manipulated using the provided functions. See @ref rops. + */ +typedef struct fsl_shw_result_t { /* fsl_shw_result */ +} fsl_shw_result_t; + +/*! + * Keystore Object + * + * This object holds the context of a user keystore, including the functions + * that define the interface and pointers to where the key data is stored. The + * user must supply a set of functions to handle keystore management, including + * slot allocation, deallocation, etc. A default keystore manager is provided + * as part of the API. + * + * No direct access to its members should be made by programs. Instead, the + * object should be manipulated using the provided functions. See @ref ksoops. + */ +typedef struct fsl_shw_kso_t { /* fsl_shw_keystore_object */ +} fsl_shw_kso_t; + +/* REQ-S2LRD-PINTFC-COA-SKO-001 */ +/*! + * Secret Key Object + * + * This object contains a key for a cryptographic operation, and information + * about its current state, its intended usage, etc. It may instead contain + * information about a protected key, or an indication to use a platform- + * specific secret key. + * + * No direct access to its members should be made by programs. Instead, the + * object should be manipulated using the provided functions. See @ref skoops. + */ +typedef struct fsl_shw_sko_t { /* fsl_shw_secret_key_object */ +} fsl_shw_sko_t; + +/* REQ-S2LRD-PINTFC-COA-CO-001 */ +/*! + * Platform Capabilities Object + * + * This object will contain information about the cryptographic features of the + * platform which the program is running on. + * + * No direct access to its members should be made by programs. Instead, the + * object should be manipulated using the provided functions. + * + * See @ref pcoops. + */ +typedef struct fsl_shw_pco_t { /* fsl_shw_platform_capabilities_object */ +} fsl_shw_pco_t; + +/* REQ-S2LRD-PINTFC-COA-HCO-001 */ +/*! + * Hash Context Object + * + * This object contains information to control hashing functions. + + * No direct access to its members should be made by programs. Instead, the + * object should be manipulated using the provided functions. See @ref hcops. + */ +typedef struct fsl_shw_hco_t { /* fsl_shw_hash_context_object */ +} fsl_shw_hco_t; + +/*! + * HMAC Context Object + * + * This object contains information to control HMAC functions. + + * No direct access to its members should be made by programs. Instead, the + * object should be manipulated using the provided functions. See @ref hmcops. + */ +typedef struct fsl_shw_hmco_t { /* fsl_shw_hmac_context_object */ +} fsl_shw_hmco_t; + +/* REQ-S2LRD-PINTFC-COA-SCCO-001 */ +/*! + * Symmetric Cipher Context Object + * + * This object contains information to control Symmetric Ciphering encrypt and + * decrypt functions in #FSL_SYM_MODE_STREAM (ARC4), #FSL_SYM_MODE_ECB, + * #FSL_SYM_MODE_CBC, and #FSL_SYM_MODE_CTR modes and the + * #fsl_shw_symmetric_encrypt() and #fsl_shw_symmetric_decrypt() functions. + * CCM mode is controlled with the #fsl_shw_acco_t object. + * + * No direct access to its members should be made by programs. Instead, the + * object should be manipulated using the provided functions. See @ref sccops. + */ +typedef struct fsl_shw_scco_t { /* fsl_shw_symmetric_cipher_context_object */ +} fsl_shw_scco_t; + +/*! + * Authenticate-Cipher Context Object + + * An object for controlling the function of, and holding information about, + * data for the authenticate-cipher functions, #fsl_shw_gen_encrypt() and + * #fsl_shw_auth_decrypt(). + * + * No direct access to its members should be made by programs. Instead, the + * object should be manipulated using the provided functions. See @ref + * accoops. + */ +typedef struct fsl_shw_acco_t { /* fsl_shw_authenticate_cipher_context_object */ +} fsl_shw_acco_t; + /*! @} *//* strgrp */ + +/****************************************************************************** + * Access Macros for Objects + *****************************************************************************/ +/*! @addtogroup pcoops + @{ */ + +/*! + * Get FSL SHW API version + * + * @param pc_info The Platform Capabilities Object to query. + * @param[out] major A pointer to where the major version + * of the API is to be stored. + * @param[out] minor A pointer to where the minor version + * of the API is to be stored. + */ +void fsl_shw_pco_get_version(const fsl_shw_pco_t * pc_info, + uint32_t * major, uint32_t * minor); + +/*! + * Get underlying driver version. + * + * @param pc_info The Platform Capabilities Object to query. + * @param[out] major A pointer to where the major version + * of the driver is to be stored. + * @param[out] minor A pointer to where the minor version + * of the driver is to be stored. + */ +void fsl_shw_pco_get_driver_version(const fsl_shw_pco_t * pc_info, + uint32_t * major, uint32_t * minor); + +/*! + * Get list of symmetric algorithms supported. + * + * @param pc_info The Platform Capabilities Object to query. + * @param[out] algorithms A pointer to where to store the location of + * the list of algorithms. + * @param[out] algorithm_count A pointer to where to store the number of + * algorithms in the list at @a algorithms. + */ +void fsl_shw_pco_get_sym_algorithms(const fsl_shw_pco_t * pc_info, + fsl_shw_key_alg_t * algorithms[], + uint8_t * algorithm_count); + +/*! + * Get list of symmetric modes supported. + * + * @param pc_info The Platform Capabilities Object to query. + * @param[out] modes A pointer to where to store the location of + * the list of modes. + * @param[out] mode_count A pointer to where to store the number of + * algorithms in the list at @a modes. + */ +void fsl_shw_pco_get_sym_modes(const fsl_shw_pco_t * pc_info, + fsl_shw_sym_mode_t * modes[], + uint8_t * mode_count); + +/*! + * Get list of hash algorithms supported. + * + * @param pc_info The Platform Capabilities Object to query. + * @param[out] algorithms A pointer which will be set to the list of + * algorithms. + * @param[out] algorithm_count The number of algorithms in the list at @a + * algorithms. + */ +void fsl_shw_pco_get_hash_algorithms(const fsl_shw_pco_t * pc_info, + fsl_shw_hash_alg_t * algorithms[], + uint8_t * algorithm_count); + +/*! + * Determine whether the combination of a given symmetric algorithm and a given + * mode is supported. + * + * @param pc_info The Platform Capabilities Object to query. + * @param algorithm A Symmetric Cipher algorithm. + * @param mode A Symmetric Cipher mode. + * + * @return 0 if combination is not supported, non-zero if supported. + */ +int fsl_shw_pco_check_sym_supported(const fsl_shw_pco_t * pc_info, + fsl_shw_key_alg_t algorithm, + fsl_shw_sym_mode_t mode); + +/*! + * Determine whether a given Encryption-Authentication mode is supported. + * + * @param pc_info The Platform Capabilities Object to query. + * @param mode The Authentication mode. + * + * @return 0 if mode is not supported, non-zero if supported. + */ +int fsl_shw_pco_check_auth_supported(const fsl_shw_pco_t * pc_info, + fsl_shw_acc_mode_t mode); + +/*! + * Determine whether Black Keys (key establishment / wrapping) is supported. + * + * @param pc_info The Platform Capabilities Object to query. + * + * @return 0 if wrapping is not supported, non-zero if supported. + */ +int fsl_shw_pco_check_black_key_supported(const fsl_shw_pco_t * pc_info); + +/*! + * Get FSL SHW SCC driver version + * + * @param pc_info The Platform Capabilities Object to query. + * @param[out] major A pointer to where the major version + * of the SCC driver is to be stored. + * @param[out] minor A pointer to where the minor version + * of the SCC driver is to be stored. + */ +void fsl_shw_pco_get_scc_driver_version(const fsl_shw_pco_t * pc_info, + uint32_t * major, uint32_t * minor); + +/*! + * Get SCM hardware version + * + * @param pc_info The Platform Capabilities Object to query. + * @return The SCM hardware version + */ +uint32_t fsl_shw_pco_get_scm_version(const fsl_shw_pco_t * pc_info); + +/*! + * Get SMN hardware version + * + * @param pc_info The Platform Capabilities Object to query. + * @return The SMN hardware version + */ +uint32_t fsl_shw_pco_get_smn_version(const fsl_shw_pco_t * pc_info); + +/*! + * Get the size of an SCM block, in bytes + * + * @param pc_info The Platform Capabilities Object to query. + * @return The size of an SCM block, in bytes. + */ +uint32_t fsl_shw_pco_get_scm_block_size(const fsl_shw_pco_t * pc_info); + +/*! + * Get size of Black and Red RAM memory + * + * @param pc_info The Platform Capabilities Object to query. + * @param[out] black_size A pointer to where the size of the Black RAM, in + * blocks, is to be placed. + * @param[out] red_size A pointer to where the size of the Red RAM, in + * blocks, is to be placed. + */ +void fsl_shw_pco_get_smn_size(const fsl_shw_pco_t * pc_info, + uint32_t * black_size, uint32_t * red_size); + +/*! + * Determine whether Secure Partitions are supported + * + * @param pc_info The Platform Capabilities Object to query. + * + * @return 0 if secure partitions are not supported, non-zero if supported. + */ +int fsl_shw_pco_check_spo_supported(const fsl_shw_pco_t * pc_info); + +/*! + * Get the size of a Secure Partitions + * + * @param pc_info The Platform Capabilities Object to query. + * + * @return Partition size, in bytes. 0 if Secure Partitions not supported. + */ +uint32_t fsl_shw_pco_get_spo_size_bytes(const fsl_shw_pco_t * pc_info); + +/*! + * Get the number of Secure Partitions on this platform + * + * @param pc_info The Platform Capabilities Object to query. + * + * @return Number of partitions. 0 if Secure Partitions not supported. Note + * that this returns the total number of partitions, though + * not all may be available to the user. + */ +uint32_t fsl_shw_pco_get_spo_count(const fsl_shw_pco_t * pc_info); + +/*! + * Determine whether Platform Key features are available + * + * @param pc_info The Platform Capabilities Object to query. + * + * @return 1 if Programmed Key features are available, otherwise zero. + */ +int fsl_shw_pco_check_pk_supported(const fsl_shw_pco_t * pc_info); + +/*! + * Determine whether Software Key features are available + * + * @param pc_info The Platform Capabilities Object to query. + * + * @return 1 if Software key features are available, otherwise zero. + */ +int fsl_shw_pco_check_sw_keys_supported(const fsl_shw_pco_t * pc_info); + +/*! @} *//* pcoops */ + +/*! @addtogroup ucoops + @{ */ + +/*! + * Initialize a User Context Object. + * + * This function must be called before performing any other operation with the + * Object. It sets the User Context Object to initial values, and set the size + * of the results pool. The mode will be set to a default of + * #FSL_UCO_BLOCKING_MODE. + * + * When using non-blocking operations, this sets the maximum number of + * operations which can be outstanding. This number includes the counts of + * operations waiting to start, operation(s) being performed, and results which + * have not been retrieved. + * + * Changes to this value are ignored once user registration has completed. It + * should be set to 1 if only blocking operations will ever be performed. + * + * @param user_ctx The User Context object to operate on. + * @param pool_size The maximum number of operations which can be + * outstanding. + */ +void fsl_shw_uco_init(fsl_shw_uco_t * user_ctx, uint16_t pool_size); + +/*! + * Set the User Reference for the User Context. + * + * @param user_ctx The User Context object to operate on. + * @param reference A value which will be passed back with a result. + */ +void fsl_shw_uco_set_reference(fsl_shw_uco_t * user_ctx, uint32_t reference); + +/*! + * Set the callback routine for the User Context. + * + * Note that the callback routine may be called when no results are available, + * and possibly even when no requests are outstanding. + * + * + * @param user_ctx The User Context object to operate on. + * @param callback_fn The function the API will invoke when an operation + * completes. + */ +void fsl_shw_uco_set_callback(fsl_shw_uco_t * user_ctx, + void (*callback_fn) (fsl_shw_uco_t * uco)); + +/*! + * Set flags in the User Context. + * + * Turns on the flags specified in @a flags. Other flags are untouched. + * + * @param user_ctx The User Context object to operate on. + * @param flags ORed values from #fsl_shw_user_ctx_flags_t. + */ +void fsl_shw_uco_set_flags(fsl_shw_uco_t * user_ctx, uint32_t flags); + +/*! + * Clear flags in the User Context. + * + * Turns off the flags specified in @a flags. Other flags are untouched. + * + * @param user_ctx The User Context object to operate on. + * @param flags ORed values from #fsl_shw_user_ctx_flags_t. + */ +void fsl_shw_uco_clear_flags(fsl_shw_uco_t * user_ctx, uint32_t flags); + +/*! + * Select a key for the key-wrap key for key wrapping/unwrapping + * + * Without a call to this function, default is FSL_SHW_PF_KEY_IIM. The wrap + * key is used to encrypt and decrypt the per-key random secret which is used + * to calculate the key which will encrypt/decrypt the user's key. + * + * @param user_ctx The User Context object to operate on. + * @param pf_key Which key to use. Valid choices are + * #FSL_SHW_PF_KEY_IIM, #FSL_SHW_PF_KEY_RND, and + * #FSL_SHW_PF_KEY_IIM_RND. + */ +void fsl_shw_uco_set_wrap_key(fsl_shw_uco_t * user_ctx, + fsl_shw_pf_key_t pf_key); + + /*! @} *//* ucoops */ + +/*! @addtogroup rops + @{ */ + +/*! + * Retrieve the status code from a Result Object. + * + * @param result The result object to query. + * + * @return The status of the request. + */ +fsl_shw_return_t fsl_shw_ro_get_status(fsl_shw_result_t * result); + +/*! + * Retrieve the reference value from a Result Object. + * + * @param result The result object to query. + * + * @return The reference associated with the request. + */ +uint32_t fsl_shw_ro_get_reference(fsl_shw_result_t * result); + + /* @} *//* rops */ + +/*! @addtogroup skoops + @{ */ + +/*! + * Initialize a Secret Key Object. + * + * This function or #fsl_shw_sko_init_pf_key() must be called before performing + * any other operation with the Object. + * + * @param key_info The Secret Key Object to be initialized. + * @param algorithm DES, AES, etc. + * + */ +void fsl_shw_sko_init(fsl_shw_sko_t * key_info, fsl_shw_key_alg_t algorithm); + +/*! + * Initialize a Secret Key Object to use a Platform Key register. + * + * This function or #fsl_shw_sko_init() must be called before performing any + * other operation with the Object. #fsl_shw_sko_set_key() does not work on + * a key object initialized in this way. + * + * If this function is used to initialize the key object, but no key is + * established with the key object, then the object will refer strictly to the + * key value specified by the @c pf_key selection. + * + * If the pf key is #FSL_SHW_PF_KEY_PRG or #FSL_SHW_PF_KEY_IIM_PRG, then the + * key object may be used with #fsl_shw_establish_key() to change the Program + * Key value. When the pf key is neither #FSL_SHW_PF_KEY_PRG nor + * #FSL_SHW_PF_KEY_IIM_PRG, it is an error to call #fsl_shw_establish_key(). + * + * @param key_info The Secret Key Object to be initialized. + * @param algorithm DES, AES, etc. + * @param pf_key Which platform key is referenced. + */ +void fsl_shw_sko_init_pf_key(fsl_shw_sko_t * key_info, + fsl_shw_key_alg_t algorithm, + fsl_shw_pf_key_t pf_key); + +/*! + * Store a cleartext key in the key object. + * + * This has the side effect of setting the #FSL_SKO_KEY_PRESENT flag. It should + * not be used if there is a key established with the key object. If there is, + * a call to #fsl_shw_release_key() should be made first. + * + * @param key_object A variable of type #fsl_shw_sko_t. + * @param key A pointer to the beginning of the key. + * @param key_length The length, in octets, of the key. The value should be + * appropriate to the key size supported by the algorithm. + * 64 octets is the absolute maximum value allowed for this + * call. + */ +void fsl_shw_sko_set_key(fsl_shw_sko_t * key_object, + const uint8_t * key, uint16_t key_length); + +/*! + * Set a size for the key. + * + * This function would normally be used when the user wants the key to be + * generated from a random source. + * + * @param key_object A variable of type #fsl_shw_sko_t. + * @param key_length The length, in octets, of the key. The value should be + * appropriate to the key size supported by the algorithm. + * 64 octets is the absolute maximum value allowed for this + * call. + */ +void fsl_shw_sko_set_key_length(fsl_shw_sko_t * key_object, + uint16_t key_length); + +/*! + * Set the User ID associated with the key. + * + * @param key_object A variable of type #fsl_shw_sko_t. + * @param userid The User ID to identify authorized users of the key. + */ +void fsl_shw_sko_set_user_id(fsl_shw_sko_t * key_object, key_userid_t userid); + +/*! + * Set the keystore that the key will be stored in. + * + * @param key_object A variable of type #fsl_shw_sko_t. + * @param keystore The keystore to place the key in. This is a variable of + * type #fsl_shw_kso_t. + */ +void fsl_shw_sko_set_keystore(fsl_shw_sko_t * key_object, + fsl_shw_kso_t * keystore); + +/*! + * Set the establish key handle into a key object. + * + * The @a userid field will be used to validate the access to the unwrapped + * key. This feature is not available for all platforms, nor for all + * algorithms and modes. + * + * The #FSL_SKO_KEY_ESTABLISHED will be set (and the #FSL_SKO_KEY_PRESENT + * flag will be cleared). + * + * @param key_object A variable of type #fsl_shw_sko_t. + * @param userid The User ID to verify this user is an authorized user of + * the key. + * @param handle A @a handle from #fsl_shw_sko_get_established_info. + */ +void fsl_shw_sko_set_established_info(fsl_shw_sko_t * key_object, + key_userid_t userid, uint32_t handle); + +/*! + * Extract the algorithm from a key object. + * + * @param key_info The Key Object to be queried. + * @param[out] algorithm A pointer to the location to store the algorithm. + */ +void fsl_shw_sko_get_algorithm(const fsl_shw_sko_t * key_info, + fsl_shw_key_alg_t * algorithm); + +/*! + * Retrieve the cleartext key from a key object that is stored in a user + * keystore. + * + * @param skobject The Key Object to be queried. + * @param[out] skkey A pointer to the location to store the key. NULL + * if the key is not stored in a user keystore. + */ +void fsl_shw_sko_get_key(const fsl_shw_sko_t * skobject, void *skkey); + +/*! + * Retrieve the established-key handle from a key object. + * + * @param key_object A variable of type #fsl_shw_sko_t. + * @param handle The location to store the @a handle of the unwrapped + * key. + */ +void fsl_shw_sko_get_established_info(fsl_shw_sko_t * key_object, + uint32_t * handle); + +/*! + * Determine the size of a wrapped key based upon the cleartext key's length. + * + * This function can be used to calculate the number of octets that + * #fsl_shw_extract_key() will write into the location at @a covered_key. + * + * If zero is returned at @a length, this means that the key length in + * @a key_info is not supported. + * + * @param key_info Information about a key to be wrapped. + * @param length Location to store the length of a wrapped + * version of the key in @a key_info. + */ +void fsl_shw_sko_calculate_wrapped_size(const fsl_shw_sko_t * key_info, + uint32_t * length); + +/*! + * Set some flags in the key object. + * + * Turns on the flags specified in @a flags. Other flags are untouched. + * + * @param key_object A variable of type #fsl_shw_sko_t. + * @param flags (One or more) ORed members of #fsl_shw_key_flags_t which + * are to be set. + */ +void fsl_shw_sko_set_flags(fsl_shw_sko_t * key_object, uint32_t flags); + +/*! + * Clear some flags in the key object. + * + * Turns off the flags specified in @a flags. Other flags are untouched. + * + * @param key_object A variable of type #fsl_shw_sko_t. + * @param flags (One or more) ORed members of #fsl_shw_key_flags_t which + * are to be reset. + */ +void fsl_shw_sko_clear_flags(fsl_shw_sko_t * key_object, uint32_t flags); + + /*! @} *//* end skoops */ + +/*****************************************************************************/ + +/*! @addtogroup hcops + @{ */ + +/*****************************************************************************/ +/* REQ-S2LRD-PINTFC-API-BASIC-HASH-004 - partially */ +/*! + * Initialize a Hash Context Object. + * + * This function must be called before performing any other operation with the + * Object. It sets the current message length and hash algorithm in the hash + * context object. + * + * @param hash_ctx The hash context to operate upon. + * @param algorithm The hash algorithm to be used (#FSL_HASH_ALG_MD5, + * #FSL_HASH_ALG_SHA256, etc). + * + */ +void fsl_shw_hco_init(fsl_shw_hco_t * hash_ctx, fsl_shw_hash_alg_t algorithm); + +/*****************************************************************************/ +/* REQ-S2LRD-PINTFC-API-BASIC-HASH-001 */ +/* REQ-S2LRD-PINTFC-API-BASIC-HASH-002 */ +/*! + * Get the current hash value and message length from the hash context object. + * + * The algorithm must have already been specified. See #fsl_shw_hco_init(). + * + * @param hash_ctx The hash context to query. + * @param[out] digest Pointer to the location of @a length octets where to + * store a copy of the current value of the digest. + * @param length Number of octets of hash value to copy. + * @param[out] msg_length Pointer to the location to store the number of octets + * already hashed. + */ +void fsl_shw_hco_get_digest(const fsl_shw_hco_t * hash_ctx, uint8_t * digest, + uint8_t length, uint32_t * msg_length); + +/*****************************************************************************/ +/* REQ-S2LRD-PINTFC-API-BASIC-HASH-002 - partially */ +/*! + * Get the hash algorithm from the hash context object. + * + * @param hash_ctx The hash context to query. + * @param[out] algorithm Pointer to where the algorithm is to be stored. + */ +void fsl_shw_hco_get_info(const fsl_shw_hco_t * hash_ctx, + fsl_shw_hash_alg_t * algorithm); + +/*****************************************************************************/ +/* REQ-S2LRD-PINTFC-API-BASIC-HASH-003 */ +/* REQ-S2LRD-PINTFC-API-BASIC-HASH-004 */ +/*! + * Set the current hash value and message length in the hash context object. + * + * The algorithm must have already been specified. See #fsl_shw_hco_init(). + * + * @param hash_ctx The hash context to operate upon. + * @param context Pointer to buffer of appropriate length to copy into + * the hash context object. + * @param msg_length The number of octets of the message which have + * already been hashed. + * + */ +void fsl_shw_hco_set_digest(fsl_shw_hco_t * hash_ctx, const uint8_t * context, + uint32_t msg_length); + +/*! + * Set flags in a Hash Context Object. + * + * Turns on the flags specified in @a flags. Other flags are untouched. + * + * @param hash_ctx The hash context to be operated on. + * @param flags The flags to be set in the context. These can be ORed + * members of #fsl_shw_hash_ctx_flags_t. + */ +void fsl_shw_hco_set_flags(fsl_shw_hco_t * hash_ctx, uint32_t flags); + +/*! + * Clear flags in a Hash Context Object. + * + * Turns off the flags specified in @a flags. Other flags are untouched. + * + * @param hash_ctx The hash context to be operated on. + * @param flags The flags to be reset in the context. These can be ORed + * members of #fsl_shw_hash_ctx_flags_t. + */ +void fsl_shw_hco_clear_flags(fsl_shw_hco_t * hash_ctx, uint32_t flags); + + /*! @} *//* end hcops */ + +/*****************************************************************************/ + +/*! @addtogroup hmcops + @{ */ + +/*! + * Initialize an HMAC Context Object. + * + * This function must be called before performing any other operation with the + * Object. It sets the current message length and hash algorithm in the HMAC + * context object. + * + * @param hmac_ctx The HMAC context to operate upon. + * @param algorithm The hash algorithm to be used (#FSL_HASH_ALG_MD5, + * #FSL_HASH_ALG_SHA256, etc). + * + */ +void fsl_shw_hmco_init(fsl_shw_hmco_t * hmac_ctx, fsl_shw_hash_alg_t algorithm); + +/*! + * Set flags in an HMAC Context Object. + * + * Turns on the flags specified in @a flags. Other flags are untouched. + * + * @param hmac_ctx The HMAC context to be operated on. + * @param flags The flags to be set in the context. These can be ORed + * members of #fsl_shw_hmac_ctx_flags_t. + */ +void fsl_shw_hmco_set_flags(fsl_shw_hmco_t * hmac_ctx, uint32_t flags); + +/*! + * Clear flags in an HMAC Context Object. + * + * Turns off the flags specified in @a flags. Other flags are untouched. + * + * @param hmac_ctx The HMAC context to be operated on. + * @param flags The flags to be reset in the context. These can be ORed + * members of #fsl_shw_hmac_ctx_flags_t. + */ +void fsl_shw_hmco_clear_flags(fsl_shw_hmco_t * hmac_ctx, uint32_t flags); + +/*! @} */ + +/*****************************************************************************/ + +/*! @addtogroup sccops + @{ */ + +/*! + * Initialize a Symmetric Cipher Context Object. + * + * This function must be called before performing any other operation with the + * Object. This will set the @a mode and @a algorithm and initialize the + * Object. + * + * @param sym_ctx The context object to operate on. + * @param algorithm The cipher algorithm this context will be used with. + * @param mode #FSL_SYM_MODE_CBC, #FSL_SYM_MODE_ECB, etc. + * + */ +void fsl_shw_scco_init(fsl_shw_scco_t * sym_ctx, + fsl_shw_key_alg_t algorithm, fsl_shw_sym_mode_t mode); + +/*! + * Set the flags for a Symmetric Cipher Context. + * + * Turns on the flags specified in @a flags. Other flags are untouched. + * + * @param sym_ctx The context object to operate on. + * @param flags The flags to reset (one or more values from + * #fsl_shw_sym_ctx_flags_t ORed together). + * + */ +void fsl_shw_scco_set_flags(fsl_shw_scco_t * sym_ctx, uint32_t flags); + +/*! + * Clear some flags in a Symmetric Cipher Context Object. + * + * Turns off the flags specified in @a flags. Other flags are untouched. + * + * @param sym_ctx The context object to operate on. + * @param flags The flags to reset (one or more values from + * #fsl_shw_sym_ctx_flags_t ORed together). + * + */ +void fsl_shw_scco_clear_flags(fsl_shw_scco_t * sym_ctx, uint32_t flags); + +/*! + * Set the Context (IV) for a Symmetric Cipher Context. + * + * This is to set the context/IV for #FSL_SYM_MODE_CBC mode, or to set the + * context (the S-Box and pointers) for ARC4. The full context size will + * be copied. + * + * @param sym_ctx The context object to operate on. + * @param context A pointer to the buffer which contains the context. + * + */ +void fsl_shw_scco_set_context(fsl_shw_scco_t * sym_ctx, uint8_t * context); + +/*! + * Get the Context for a Symmetric Cipher Context. + * + * This is to retrieve the context/IV for #FSL_SYM_MODE_CBC mode, or to + * retrieve context (the S-Box and pointers) for ARC4. The full context + * will be copied. + * + * @param sym_ctx The context object to operate on. + * @param[out] context Pointer to location where context will be stored. + */ +void fsl_shw_scco_get_context(const fsl_shw_scco_t * sym_ctx, + uint8_t * context); + +/*! + * Set the Counter Value for a Symmetric Cipher Context. + * + * This will set the Counter Value for CTR mode. + * + * @param sym_ctx The context object to operate on. + * @param counter The starting counter value. The number of octets. + * copied will be the block size for the algorithm. + * @param modulus The modulus for controlling the incrementing of the counter. + * + */ +void fsl_shw_scco_set_counter_info(fsl_shw_scco_t * sym_ctx, + const uint8_t * counter, + fsl_shw_ctr_mod_t modulus); + +/*! + * Get the Counter Value for a Symmetric Cipher Context. + * + * This will retrieve the Counter Value is for CTR mode. + * + * @param sym_ctx The context object to query. + * @param[out] counter Pointer to location to store the current counter + * value. The number of octets copied will be the + * block size for the algorithm. + * @param[out] modulus Pointer to location to store the modulus. + * + */ +void fsl_shw_scco_get_counter_info(const fsl_shw_scco_t * sym_ctx, + uint8_t * counter, + fsl_shw_ctr_mod_t * modulus); + + /*! @} *//* end sccops */ + +/*****************************************************************************/ + +/*! @addtogroup accoops + @{ */ + +/*! + * Initialize a Authentication-Cipher Context. + * + * @param auth_object Pointer to object to operate on. + * @param mode The mode for this object (only #FSL_ACC_MODE_CCM + * supported). + */ +void fsl_shw_acco_init(fsl_shw_acco_t * auth_object, fsl_shw_acc_mode_t mode); + +/*! + * Set the flags for a Authentication-Cipher Context. + * + * Turns on the flags specified in @a flags. Other flags are untouched. + * + * @param auth_object Pointer to object to operate on. + * @param flags The flags to set (one or more from + * #fsl_shw_auth_ctx_flags_t ORed together). + * + */ +void fsl_shw_acco_set_flags(fsl_shw_acco_t * auth_object, uint32_t flags); + +/*! + * Clear some flags in a Authentication-Cipher Context Object. + * + * Turns off the flags specified in @a flags. Other flags are untouched. + * + * @param auth_object Pointer to object to operate on. + * @param flags The flags to reset (one or more from + * #fsl_shw_auth_ctx_flags_t ORed together). + * + */ +void fsl_shw_acco_clear_flags(fsl_shw_acco_t * auth_object, uint32_t flags); + +/*! + * Set up the Authentication-Cipher Object for CCM mode. + * + * This will set the @a auth_object for CCM mode and save the @a ctr, + * and @a mac_length. This function can be called instead of + * #fsl_shw_acco_init(). + * + * The parameter @a ctr is Counter Block 0, (counter value 0), which is for the + * MAC. + * + * @param auth_object Pointer to object to operate on. + * @param algorithm Cipher algorithm. Only AES is supported. + * @param ctr The initial counter value. + * @param mac_length The number of octets used for the MAC. Valid values are + * 4, 6, 8, 10, 12, 14, and 16. + */ +void fsl_shw_acco_set_ccm(fsl_shw_acco_t * auth_object, + fsl_shw_key_alg_t algorithm, + const uint8_t * ctr, uint8_t mac_length); + +/*! + * Format the First Block (IV) & Initial Counter Value per NIST CCM. + * + * This function will also set the IV and CTR values per Appendix A of NIST + * Special Publication 800-38C (May 2004). It will also perform the + * #fsl_shw_acco_set_ccm() operation with information derived from this set of + * parameters. + * + * Note this function assumes the algorithm is AES. It initializes the + * @a auth_object by setting the mode to #FSL_ACC_MODE_CCM and setting the + * flags to be #FSL_ACCO_NIST_CCM. + * + * @param auth_object Pointer to object to operate on. + * @param t_length The number of octets used for the MAC. Valid values are + * 4, 6, 8, 10, 12, 14, and 16. + * @param ad_length Number of octets of Associated Data (may be zero). + * @param q_length A value for the size of the length of @a q field. Valid + * values are 1-8. + * @param n The Nonce (packet number or other changing value). Must + * be (15 - @a q_length) octets long. + * @param q The value of Q (size of the payload in octets). + * + */ +void fsl_shw_ccm_nist_format_ctr_and_iv(fsl_shw_acco_t * auth_object, + uint8_t t_length, + uint32_t ad_length, + uint8_t q_length, + const uint8_t * n, uint32_t q); + +/*! + * Update the First Block (IV) & Initial Counter Value per NIST CCM. + * + * This function will set the IV and CTR values per Appendix A of NIST Special + * Publication 800-38C (May 2004). + * + * Note this function assumes that #fsl_shw_ccm_nist_format_ctr_and_iv() has + * previously been called on the @a auth_object. + * + * @param auth_object Pointer to object to operate on. + * @param n The Nonce (packet number or other changing value). Must + * be (15 - @a q_length) octets long. + * @param q The value of Q (size of the payload in octets). + * + */ +void fsl_shw_ccm_nist_update_ctr_and_iv(fsl_shw_acco_t * auth_object, + const uint8_t * n, uint32_t q); + + /* @} *//* accoops */ + +/****************************************************************************** + * Library functions + *****************************************************************************/ + +/*! @addtogroup miscfuns + @{ */ + +/* REQ-S2LRD-PINTFC-API-GEN-003 */ +/*! + * Determine the hardware security capabilities of this platform. + * + * Though a user context object is passed into this function, it will always + * act in a non-blocking manner. + * + * @param user_ctx The user context which will be used for the query. + * + * @return A pointer to the capabilities object. + */ +extern fsl_shw_pco_t *fsl_shw_get_capabilities(fsl_shw_uco_t * user_ctx); + +/* REQ-S2LRD-PINTFC-API-GEN-004 */ +/*! + * Create an association between the user and the provider of the API. + * + * @param user_ctx The user context which will be used for this association. + * + * @return A return code of type #fsl_shw_return_t. + */ +extern fsl_shw_return_t fsl_shw_register_user(fsl_shw_uco_t * user_ctx); + +/* REQ-S2LRD-PINTFC-API-GEN-005 */ +/*! + * Destroy the association between the user and the provider of the API. + * + * @param user_ctx The user context which is no longer needed. + * + * @return A return code of type #fsl_shw_return_t. + */ +extern fsl_shw_return_t fsl_shw_deregister_user(fsl_shw_uco_t * user_ctx); + +/* REQ-S2LRD-PINTFC-API-GEN-006 */ +/*! + * Retrieve results from earlier operations. + * + * @param user_ctx The user's context. + * @param result_size The number of array elements of @a results. + * @param[in,out] results Pointer to first of the (array of) locations to + * store results. + * @param[out] result_count Pointer to store the number of results which + * were returned. + * + * @return A return code of type #fsl_shw_return_t. + */ +extern fsl_shw_return_t fsl_shw_get_results(fsl_shw_uco_t * user_ctx, + uint16_t result_size, + fsl_shw_result_t results[], + uint16_t * result_count); + +/*! + * Allocate a block of secure memory + * + * @param user_ctx User context + * @param size Memory size (octets). Note: currently only + * supports only single-partition sized blocks. + * @param UMID User Mode ID to use when registering the + * partition. + * @param permissions Permissions to initialize the partition with. + * Can be made by ORing flags from the + * #fsl_shw_permission_t. + * + * @return Address of the allocated memory. NULL if the + * call was not successful. + */ +extern void *fsl_shw_smalloc(fsl_shw_uco_t * user_ctx, + uint32_t size, + const uint8_t * UMID, uint32_t permissions); + +/*! + * Free a block of secure memory that was allocated with #fsl_shw_smalloc + * + * @param user_ctx User context + * @param address Address of the block of secure memory to be + * released. + * + * @return A return code of type #fsl_shw_return_t. + */ +extern fsl_shw_return_t fsl_shw_sfree(fsl_shw_uco_t * user_ctx, void *address); + +/*! + * Diminish the permissions of a block of secure memory. Note that permissions + * can only be revoked. + * + * @param user_ctx User context + * @param address Base address of the secure memory to work with + * @param permissions Permissions to initialize the partition with. + * Can be made by ORing flags from the + * #fsl_shw_permission_t. + * + * @return A return code of type #fsl_shw_return_t. + */ +extern fsl_shw_return_t fsl_shw_diminish_perms(fsl_shw_uco_t * user_ctx, + void *address, + uint32_t permissions); + +/*! + * @brief Encrypt a region of secure memory using the hardware secret key + * + * @param user_ctx User context + * @param partition_base Base address of the partition + * @param offset_bytes Offset of data from the partition base + * @param byte_count Length of the data to encrypt + * @param black_data Location to store the encrypted data + * @param IV IV to use for the encryption routine + * @param cypher_mode Cyphering mode to use, specified by type + * #fsl_shw_cypher_mode_t + * + * @return A return code of type #fsl_shw_return_t. + */ +extern fsl_shw_return_t +do_scc_encrypt_region(fsl_shw_uco_t * user_ctx, + void *partition_base, uint32_t offset_bytes, + uint32_t byte_count, uint8_t * black_data, + uint32_t * IV, fsl_shw_cypher_mode_t cypher_mode); + +/*! + * @brief Decrypt a region of secure memory using the hardware secret key + * + * @param user_ctx User context + * @param partition_base Base address of the partition + * @param offset_bytes Offset of data from the partition base + * @param byte_count Length of the data to encrypt + * @param black_data Location to store the encrypted data + * @param IV IV to use for the encryption routine + * @param cypher_mode Cyphering mode to use, specified by type + * #fsl_shw_cypher_mode_t + * + * @return A return code of type #fsl_shw_return_t. + */ +extern fsl_shw_return_t +do_scc_decrypt_region(fsl_shw_uco_t * user_ctx, + void *partition_base, uint32_t offset_bytes, + uint32_t byte_count, const uint8_t * black_data, + uint32_t * IV, fsl_shw_cypher_mode_t cypher_mode); + + /*! @} *//* miscfuns */ + +/*! @addtogroup opfuns + @{ */ + +/* REQ-S2LRD-PINTFC-API-BASIC-SYM-002 */ +/* PINTFC-API-BASIC-SYM-ARC4-001 */ +/* PINTFC-API-BASIC-SYM-ARC4-002 */ +/*! + * Encrypt a stream of data with a symmetric-key algorithm. + * + * In ARC4, and also in #FSL_SYM_MODE_CBC and #FSL_SYM_MODE_CTR modes, the + * flags of the @a sym_ctx object will control part of the operation of this + * function. The #FSL_SYM_CTX_INIT flag means that there is no context info in + * the object. The #FSL_SYM_CTX_LOAD means to use information in the + * @a sym_ctx at the start of the operation, and the #FSL_SYM_CTX_SAVE flag + * means to update the object's context information after the operation has + * been performed. + * + * All of the data for an operation can be run through at once using the + * #FSL_SYM_CTX_INIT or #FSL_SYM_CTX_LOAD flags, as appropriate, and then using + * a @a length for the whole of the data. + * + * If a #FSL_SYM_CTX_SAVE flag were added, an additional call to the function + * would "pick up" where the previous call left off, allowing the user to + * perform the larger function in smaller steps. + * + * In #FSL_SYM_MODE_CBC and #FSL_SYM_MODE_ECB modes, the @a length must always + * be a multiple of the block size for the algorithm being used. For proper + * operation in #FSL_SYM_MODE_CTR mode, the @a length must be a multiple of the + * block size until the last operation on the total octet stream. + * + * Some users of ARC4 may want to compute the context (S-Box and pointers) from + * the key before any data is available. This may be done by running this + * function with a @a length of zero, with the init & save flags flags on in + * the @a sym_ctx. Subsequent operations would then run as normal with the + * load and save flags. Note that they key object is still required. + * + * @param user_ctx A user context from #fsl_shw_register_user(). + * @param key_info Key and algorithm being used for this operation. + * @param[in,out] sym_ctx Info on cipher mode, state of the cipher. + * @param length Length, in octets, of the pt (and ct). + * @param pt pointer to plaintext to be encrypted. + * @param[out] ct pointer to where to store the resulting ciphertext. + * + * @return A return code of type #fsl_shw_return_t. + * + */ +extern fsl_shw_return_t fsl_shw_symmetric_encrypt(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info, + fsl_shw_scco_t * sym_ctx, + uint32_t length, + const uint8_t * pt, + uint8_t * ct); + +/* PINTFC-API-BASIC-SYM-002 */ +/* PINTFC-API-BASIC-SYM-ARC4-001 */ +/* PINTFC-API-BASIC-SYM-ARC4-002 */ +/*! + * Decrypt a stream of data with a symmetric-key algorithm. + * + * In ARC4, and also in #FSL_SYM_MODE_CBC and #FSL_SYM_MODE_CTR modes, the + * flags of the @a sym_ctx object will control part of the operation of this + * function. The #FSL_SYM_CTX_INIT flag means that there is no context info in + * the object. The #FSL_SYM_CTX_LOAD means to use information in the + * @a sym_ctx at the start of the operation, and the #FSL_SYM_CTX_SAVE flag + * means to update the object's context information after the operation has + * been performed. + * + * All of the data for an operation can be run through at once using the + * #FSL_SYM_CTX_INIT or #FSL_SYM_CTX_LOAD flags, as appropriate, and then using + * a @a length for the whole of the data. + * + * If a #FSL_SYM_CTX_SAVE flag were added, an additional call to the function + * would "pick up" where the previous call left off, allowing the user to + * perform the larger function in smaller steps. + * + * In #FSL_SYM_MODE_CBC and #FSL_SYM_MODE_ECB modes, the @a length must always + * be a multiple of the block size for the algorithm being used. For proper + * operation in #FSL_SYM_MODE_CTR mode, the @a length must be a multiple of the + * block size until the last operation on the total octet stream. + * + * Some users of ARC4 may want to compute the context (S-Box and pointers) from + * the key before any data is available. This may be done by running this + * function with a @a length of zero, with the #FSL_SYM_CTX_INIT & + * #FSL_SYM_CTX_SAVE flags on in the @a sym_ctx. Subsequent operations would + * then run as normal with the load & save flags. Note that they key object is + * still required. + * + * @param user_ctx A user context from #fsl_shw_register_user(). + * @param key_info The key and algorithm being used in this operation. + * @param[in,out] sym_ctx Info on cipher mode, state of the cipher. + * @param length Length, in octets, of the ct (and pt). + * @param ct pointer to ciphertext to be decrypted. + * @param[out] pt pointer to where to store the resulting plaintext. + * + * @return A return code of type #fsl_shw_return_t + * + */ +extern fsl_shw_return_t fsl_shw_symmetric_decrypt(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info, + fsl_shw_scco_t * sym_ctx, + uint32_t length, + const uint8_t * ct, + uint8_t * pt); + +/* REQ-S2LRD-PINTFC-API-BASIC-HASH-005 */ +/*! + * Hash a stream of data with a cryptographic hash algorithm. + * + * The flags in the @a hash_ctx control the operation of this function. + * + * Hashing functions work on 64 octets of message at a time. Therefore, when + * any partial hashing of a long message is performed, the message @a length of + * each segment must be a multiple of 64. When ready to + * #FSL_HASH_FLAGS_FINALIZE the hash, the @a length may be any value. + * + * With the #FSL_HASH_FLAGS_INIT and #FSL_HASH_FLAGS_FINALIZE flags on, a + * one-shot complete hash, including padding, will be performed. The @a length + * may be any value. + * + * The first octets of a data stream can be hashed by setting the + * #FSL_HASH_FLAGS_INIT and #FSL_HASH_FLAGS_SAVE flags. The @a length must be + * a multiple of 64. + * + * The flag #FSL_HASH_FLAGS_LOAD is used to load a context previously saved by + * #FSL_HASH_FLAGS_SAVE. The two in combination will allow a (multiple-of-64 + * octets) 'middle sequence' of the data stream to be hashed with the + * beginning. The @a length must again be a multiple of 64. + * + * Since the flag #FSL_HASH_FLAGS_LOAD is used to load a context previously + * saved by #FSL_HASH_FLAGS_SAVE, the #FSL_HASH_FLAGS_LOAD and + * #FSL_HASH_FLAGS_FINALIZE flags, used together, can be used to finish the + * stream. The @a length may be any value. + * + * If the user program wants to do the padding for the hash, it can leave off + * the #FSL_HASH_FLAGS_FINALIZE flag. The @a length must then be a multiple of + * 64 octets. + * + * @param user_ctx A user context from #fsl_shw_register_user(). + * @param[in,out] hash_ctx Hashing algorithm and state of the cipher. + * @param msg Pointer to the data to be hashed. + * @param length Length, in octets, of the @a msg. + * @param[out] result If not null, pointer to where to store the hash + * digest. + * @param result_len Number of octets to store in @a result. + * + * @return A return code of type #fsl_shw_return_t. + */ +extern fsl_shw_return_t fsl_shw_hash(fsl_shw_uco_t * user_ctx, + fsl_shw_hco_t * hash_ctx, + const uint8_t * msg, + uint32_t length, + uint8_t * result, uint32_t result_len); + +/* REQ-S2LRD-PINTFC-API-BASIC-HMAC-001 */ +/*! + * Precompute the Key hashes for an HMAC operation. + * + * This function may be used to calculate the inner and outer precomputes, + * which are the hash contexts resulting from hashing the XORed key for the + * 'inner hash' and the 'outer hash', respectively, of the HMAC function. + * + * After execution of this function, the @a hmac_ctx will contain the + * precomputed inner and outer contexts, so that they may be used by + * #fsl_shw_hmac(). The flags of @a hmac_ctx will be updated with + * #FSL_HMAC_FLAGS_PRECOMPUTES_PRESENT to mark their presence. In addition, the + * #FSL_HMAC_FLAGS_INIT flag will be set. + * + * @param user_ctx A user context from #fsl_shw_register_user(). + * @param key_info The key being used in this operation. Key must be + * 1 to 64 octets long. + * @param[in,out] hmac_ctx The context which controls, by its flags and + * algorithm, the operation of this function. + * @return A return code of type #fsl_shw_return_t. + */ +extern fsl_shw_return_t fsl_shw_hmac_precompute(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info, + fsl_shw_hmco_t * hmac_ctx); + +/* REQ-S2LRD-PINTFC-API-BASIC-HMAC-002 */ +/*! + * Continue, finalize, or one-shot an HMAC operation. + * + * There are a number of ways to use this function. The flags in the + * @a hmac_ctx object will determine what operations occur. + * + * If #FSL_HMAC_FLAGS_INIT is set, then the hash will be started either from + * the @a key_info, or from the precomputed inner hash value in the + * @a hmac_ctx, depending on the value of #FSL_HMAC_FLAGS_PRECOMPUTES_PRESENT. + * + * If, instead, #FSL_HMAC_FLAGS_LOAD is set, then the hash will be continued + * from the ongoing inner hash computation in the @a hmac_ctx. + * + * If #FSL_HMAC_FLAGS_FINALIZE are set, then the @a msg will be padded, hashed, + * the outer hash will be performed, and the @a result will be generated. + * + * If the #FSL_HMAC_FLAGS_SAVE flag is set, then the (ongoing or final) digest + * value will be stored in the ongoing inner hash computation field of the @a + * hmac_ctx. + * + * @param user_ctx A user context from #fsl_shw_register_user(). + * @param key_info If #FSL_HMAC_FLAGS_INIT is set in the @a hmac_ctx, + * this is the key being used in this operation, and the + * IPAD. If #FSL_HMAC_FLAGS_INIT is set in the @a + * hmac_ctx and @a key_info is NULL, then + * #fsl_shw_hmac_precompute() has been used to populate + * the @a inner_precompute and @a outer_precompute + * contexts. If #FSL_HMAC_FLAGS_INIT is not set, this + * parameter is ignored. + + * @param[in,out] hmac_ctx The context which controls, by its flags and + * algorithm, the operation of this function. + * @param msg Pointer to the message to be hashed. + * @param length Length, in octets, of the @a msg. + * @param[out] result Pointer, of @a result_len octets, to where to + * store the HMAC. + * @param result_len Length of @a result buffer. + * + * @return A return code of type #fsl_shw_return_t. + */ +extern fsl_shw_return_t fsl_shw_hmac(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info, + fsl_shw_hmco_t * hmac_ctx, + const uint8_t * msg, + uint32_t length, + uint8_t * result, uint32_t result_len); + +/* REQ-S2LRD-PINTFC-API-BASIC-RNG-002 */ +/*! + * Get random data. + * + * @param user_ctx A user context from #fsl_shw_register_user(). + * @param length The number of octets of @a data being requested. + * @param[out] data A pointer to a location of @a length octets to where + * random data will be returned. + * + * @return A return code of type #fsl_shw_return_t. + */ +extern fsl_shw_return_t fsl_shw_get_random(fsl_shw_uco_t * user_ctx, + uint32_t length, uint8_t * data); + +/* REQ-S2LRD-PINTFC-API-BASIC-RNG-002 */ +/*! + * Add entropy to random number generator. + * + * @param user_ctx A user context from #fsl_shw_register_user(). + * @param length Number of bytes at @a data. + * @param data Entropy to add to random number generator. + * + * @return A return code of type #fsl_shw_return_t. + */ +extern fsl_shw_return_t fsl_shw_add_entropy(fsl_shw_uco_t * user_ctx, + uint32_t length, uint8_t * data); + +/*! + * Perform Generation-Encryption by doing a Cipher and a Hash. + * + * Generate the authentication value @a auth_value as well as encrypt the @a + * payload into @a ct (the ciphertext). This is a one-shot function, so all of + * the @a auth_data and the total message @a payload must passed in one call. + * This also means that the flags in the @a auth_ctx must be #FSL_ACCO_CTX_INIT + * and #FSL_ACCO_CTX_FINALIZE. + * + * @param user_ctx A user context from #fsl_shw_register_user(). + * @param auth_ctx Controlling object for Authenticate-decrypt. + * @param cipher_key_info The key being used for the cipher part of this + * operation. In CCM mode, this key is used for + * both parts. + * @param auth_key_info The key being used for the authentication part + * of this operation. In CCM mode, this key is + * ignored and may be NULL. + * @param auth_data_length Length, in octets, of @a auth_data. + * @param auth_data Data to be authenticated but not encrypted. + * @param payload_length Length, in octets, of @a payload. + * @param payload Pointer to the plaintext to be encrypted. + * @param[out] ct Pointer to the where the encrypted @a payload + * will be stored. Must be @a payload_length + * octets long. + * @param[out] auth_value Pointer to where the generated authentication + * field will be stored. Must be as many octets as + * indicated by MAC length in the @a function_ctx. + * @return A return code of type #fsl_shw_return_t. + */ +extern fsl_shw_return_t fsl_shw_gen_encrypt(fsl_shw_uco_t * user_ctx, + fsl_shw_acco_t * auth_ctx, + fsl_shw_sko_t * cipher_key_info, + fsl_shw_sko_t * auth_key_info, + uint32_t auth_data_length, + const uint8_t * auth_data, + uint32_t payload_length, + const uint8_t * payload, + uint8_t * ct, uint8_t * auth_value); + +/*! + * Perform Authentication-Decryption in Cipher + Hash. + * + * This function will perform a one-shot decryption of a data stream as well as + * authenticate the authentication value. This is a one-shot function, so all + * of the @a auth_data and the total message @a payload must passed in one + * call. This also means that the flags in the @a auth_ctx must be + * #FSL_ACCO_CTX_INIT and #FSL_ACCO_CTX_FINALIZE. + * + * @param user_ctx A user context from #fsl_shw_register_user(). + * @param auth_ctx Controlling object for Authenticate-decrypt. + * @param cipher_key_info The key being used for the cipher part of this + * operation. In CCM mode, this key is used for + * both parts. + * @param auth_key_info The key being used for the authentication part + * of this operation. In CCM mode, this key is + * ignored and may be NULL. + * @param auth_data_length Length, in octets, of @a auth_data. + * @param auth_data Data to be authenticated but not decrypted. + * @param payload_length Length, in octets, of @a ct and @a pt. + * @param ct Pointer to the encrypted input stream. + * @param auth_value The (encrypted) authentication value which will + * be authenticated. This is the same data as the + * (output) @a auth_value argument to + * #fsl_shw_gen_encrypt(). + * @param[out] payload Pointer to where the plaintext resulting from + * the decryption will be stored. + * + * @return A return code of type #fsl_shw_return_t. + */ +extern fsl_shw_return_t fsl_shw_auth_decrypt(fsl_shw_uco_t * user_ctx, + fsl_shw_acco_t * auth_ctx, + fsl_shw_sko_t * cipher_key_info, + fsl_shw_sko_t * auth_key_info, + uint32_t auth_data_length, + const uint8_t * auth_data, + uint32_t payload_length, + const uint8_t * ct, + const uint8_t * auth_value, + uint8_t * payload); + +/*! + * Establish the key in a protected location, which can be the system keystore, + * user keystore, or (on platforms that support it) as a Platform Key. + * + * By default, keys initialized with #fsl_shw_sko_init() will be placed into + * the system keystore. The user can cause the key to be established in a + * user keystore by first calling #fsl_shw_sko_set_keystore() on the key. + * Normally, keys in the system keystore can only be used for hardware + * encrypt or decrypt operations, however if the #FSL_SKO_KEY_SW_KEY flag is + * applied using #fsl_shw_sko_set_flags(), the key will be established as a + * software key, which can then be read out using #fsl_shw_read_key(). + * + * Keys initialized with #fsl_shw_sko_init_pf_key() are established as a + * Platform Key. Their use is covered in @ref di_sec. + * + * This function only needs to be used when unwrapping a key, setting up a key + * which could be wrapped with a later call to #fsl_shw_extract_key(), or + * setting up a key as a Platform Key. Normal cleartext keys can simply be + * placed into #fsl_shw_sko_t key objects with #fsl_shw_sko_set_key() and used + * directly. + * + * The maximum key size supported for wrapped/unwrapped keys is 32 octets. + * (This is the maximum reasonable key length on Sahara - 32 octets for an HMAC + * key based on SHA-256.) The key size is determined by the @a key_info. The + * expected length of @a key can be determined by + * #fsl_shw_sko_calculate_wrapped_size() + * + * The protected key will not be available for use until this operation + * successfully completes. + * + * This feature is not available for all platforms, nor for all algorithms and + * modes. + * + * @param user_ctx A user context from #fsl_shw_register_user(). + * @param[in,out] key_info The information about the key to be which will + * be established. In the create case, the key + * length must be set. + * @param establish_type How @a key will be interpreted to establish a + * key for use. + * @param key If @a establish_type is #FSL_KEY_WRAP_UNWRAP, + * this is the location of a wrapped key. If + * @a establish_type is #FSL_KEY_WRAP_CREATE, this + * parameter can be @a NULL. If @a establish_type + * is #FSL_KEY_WRAP_ACCEPT, this is the location + * of a plaintext key. + */ +extern fsl_shw_return_t fsl_shw_establish_key(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info, + fsl_shw_key_wrap_t establish_type, + const uint8_t * key); + +/*! + * Read the key value from a key object. + * + * Only a key marked as a software key (#FSL_SKO_KEY_SW_KEY) can be read with + * this call. It has no effect on the status of the key store. + * + * @param user_ctx A user context from #fsl_shw_register_user(). + * @param key_info The referenced key. + * @param[out] key The location to store the key value. + * + * @return A return code of type #fsl_shw_return_t. + */ +extern fsl_shw_return_t fsl_shw_read_key(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info, + uint8_t * key); + +/*! + * Wrap a key and retrieve the wrapped value. + * + * A wrapped key is a key that has been cryptographically obscured. It is + * only able to be used with keys that have been established by + * #fsl_shw_establish_key(). + * + * For keys established in the system or user keystore, this function will + * also release the key (see #fsl_shw_release_key()) so that it must be re- + * established before reuse. This function will not release keys that are + * established as a Platform Key, so a call to #fsl_shw_release_key() is + * necessary to release those keys. + * + * This feature is not available for all platforms, nor for all algorithms and + * modes. + * + * @param user_ctx A user context from #fsl_shw_register_user(). + * @param key_info The information about the key to be deleted. + * @param[out] covered_key The location to store the wrapped key. + * (This size is based upon the maximum key size + * of 32 octets). + * + * @return A return code of type #fsl_shw_return_t. + */ +extern fsl_shw_return_t fsl_shw_extract_key(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info, + uint8_t * covered_key); + +/*! + * De-establish a key so that it can no longer be accessed. + * + * The key will need to be re-established before it can again be used. + * + * This feature is not available for all platforms, nor for all algorithms and + * modes. + * + * @param user_ctx A user context from #fsl_shw_register_user(). + * @param key_info The information about the key to be deleted. + * + * @return A return code of type #fsl_shw_return_t. + */ +extern fsl_shw_return_t fsl_shw_release_key(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info); + +/*! + * Cause the hardware to create a new random key for use by the secure memory + * encryption hardware. + * + * Have the hardware use the secure hardware random number generator to load a + * new secret key into the system's Random Key register. + * + * @param user_ctx A user context from #fsl_shw_register_user(). + * + * @return A return code of type #fsl_shw_return_t. + */ +extern fsl_shw_return_t fsl_shw_gen_random_pf_key(fsl_shw_uco_t * user_ctx); + +/*! + * Retrieve the detected tamper event. + * + * Note that if more than one event was detected, this routine will only ever + * return one of them. + * + * @param[in] user_ctx A user context from #fsl_shw_register_user(). + * @param[out] tamperp Location to store the tamper information. + * @param[out] timestampp Locate to store timestamp from hardwhare when + * an event was detected. + * + * + * @return A return code of type #fsl_shw_return_t (for instance, if the platform + * is not in a fail state. + */ +extern fsl_shw_return_t fsl_shw_read_tamper_event(fsl_shw_uco_t * user_ctx, + fsl_shw_tamper_t * tamperp, + uint64_t * timestampp); + +/*! @} *//* opfuns */ + +/* Insert example code into the API documentation. */ + +/*! + * @example apitest.c + */ + +/*! + * @example sym.c + */ + +/*! + * @example rand.c + */ + +/*! + * @example hash.c + */ + +/*! + * @example hmac1.c + */ + +/*! + * @example hmac2.c + */ + +/*! + * @example gen_encrypt.c + */ + +/*! + * @example auth_decrypt.c + */ + +/*! + * @example wrapped_key.c + */ + +/*! + * @example smalloc.c + */ + +/*! + * @example user_keystore.c + */ + +/*! + * @example dryice.c + */ + +#endif /* API_DOC */ + +#endif /* FSL_SHW_H */ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/include/sahara.h +++ linux-2.6.28/drivers/mxc/security/sahara2/include/sahara.h @@ -0,0 +1,2266 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @file sahara.h + * + * File which implements the FSL_SHW API when used on Sahara + */ +/*! + * @if USE_MAINPAGE + * @mainpage Sahara2 implemtation of FSL Security Hardware API + * @endif + * + */ + +#define _DIAG_DRV_IF +#define _DIAG_SECURITY_FUNC +#define _DIAG_ADAPTOR + +#ifndef SAHARA2_API_H +#define SAHARA2_API_H + +#ifdef DIAG_SECURITY_FUNC +#include +#endif /* DIAG_SECURITY_FUNC */ + +/* This is a Linux flag... ? */ +#ifndef __KERNEL__ +#include +#include +#include +#else +#include "portable_os.h" +#endif + +/* This definition may need a new name, and needs to go somewhere which + * can determine platform, kernel vs. user, os, etc. + */ +#define copy_bytes(out, in, len) memcpy(out, in, len) + +/* Does this belong here? */ +#ifndef SAHARA_DEVICE +#define SAHARA_DEVICE "/dev/sahara" +#endif + +/*! +******************************************************************************* +* @defgroup lnkflags Link Flags +* +* @brief Flags to show information about link data and link segments +* +******************************************************************************/ +/*! @addtogroup lnkflags + * @{ + */ + +/*! +******************************************************************************* +* This flag indicates that the data in a link is owned by the security +* function component and this memory will be freed by the security function +* component. To be used as part of the flag field of the sah_Link structure. +******************************************************************************/ +#define SAH_OWNS_LINK_DATA 0x01 + +/*! +******************************************************************************* +* The data in a link is not owned by the security function component and +* therefore it will not attempt to free this memory. To be used as part of the +* flag field of the sah_Link structure. +******************************************************************************/ +#define SAH_USES_LINK_DATA 0x02 + +/*! +******************************************************************************* +* The data in this link will change when the descriptor gets executed. +******************************************************************************/ +#define SAH_OUTPUT_LINK 0x04 + +/*! +******************************************************************************* +* The ptr and length in this link are really 'established key' info. They +* are to be converted to ptr/length before putting on request queue. +******************************************************************************/ +#define SAH_KEY_IS_HIDDEN 0x08 + +/*! +******************************************************************************* +* The link structure has been appended to the previous one by the driver. It +* needs to be removed before leaving the driver (and returning to API). +******************************************************************************/ +#define SAH_REWORKED_LINK 0x10 + +/*! +******************************************************************************* +* The length and data fields of this link contain the slot and user id +* used to access the SCC stored key +******************************************************************************/ +#define SAH_STORED_KEY_INFO 0x20 + +/*! +******************************************************************************* +* The Data field points to a physical address, and does not need to be +* processed by the driver. Honored only in Kernel API. +******************************************************************************/ +#define SAH_PREPHYS_DATA 0x40 + +/*! +******************************************************************************* +* The link was inserted during the Physicalise procedure. It is tagged so +* it can be removed during DePhysicalise, thereby returning to the caller an +* intact chain. +******************************************************************************/ +#define SAH_LINK_INSERTED_LINK 0x80 + +/*! +******************************************************************************* +* The Data field points to the location of the key, which is in a secure +* partition held by the user. The memory address needs to be converted to +* kernel space manually, by looking through the partitions that the user holds. +******************************************************************************/ +#define SAH_IN_USER_KEYSTORE 0x100 + +/*! +******************************************************************************* +* sah_Link_Flags +* +* Type to be used for flags associated with a Link in security function. +* These flags are used internally by the security function component only. +* +* Values defined at @ref lnkflags +* +* @brief typedef for flags field of sah_Link +******************************************************************************/ +typedef uint32_t sah_Link_Flags; + +/* +******************************************************************************* +* Security Parameters Related Structures +* +* All of structures associated with API parameters +* +******************************************************************************/ + +/* +******************************************************************************* +* Common Types +* +* All of structures used across several classes of crytography +******************************************************************************/ + +/*! +******************************************************************************* +* @brief Indefinite precision integer used for security operations on SAHARA +* accelerator. The data will always be in little Endian format. +******************************************************************************/ +typedef uint8_t *sah_Int; + +/*! +******************************************************************************* +* @brief Byte array used for block cipher and hash digest/MAC operations on +* SAHARA accelerator. The Endian format will be as specified by the function +* using the sah_Oct_Str. +******************************************************************************/ +typedef uint8_t *sah_Oct_Str; + +/*! + * A queue of descriptor heads -- used to hold requests waiting for user to + * pick up the results. */ +typedef struct sah_Queue { + int count; /*!< # entries in queue */ + struct sah_Head_Desc *head; /*!< first entry in queue */ + struct sah_Head_Desc *tail; /*!< last entry in queue */ +} sah_Queue; + +/****************************************************************************** + * Enumerations + *****************************************************************************/ +/*! + * Flags for the state of the User Context Object (#fsl_shw_uco_t). + */ +typedef enum fsl_shw_user_ctx_flags_t { + /*! + * API will block the caller until operation completes. The result will be + * available in the return code. If this is not set, user will have to get + * results using #fsl_shw_get_results(). + */ + FSL_UCO_BLOCKING_MODE = 0x01, + /*! + * User wants callback (at the function specified with + * #fsl_shw_uco_set_callback()) when the operation completes. This flag is + * valid only if #FSL_UCO_BLOCKING_MODE is not set. + */ + FSL_UCO_CALLBACK_MODE = 0x02, + /*! Do not free descriptor chain after driver (adaptor) finishes */ + FSL_UCO_SAVE_DESC_CHAIN = 0x04, + /*! + * User has made at least one request with callbacks requested, so API is + * ready to handle others. + */ + FSL_UCO_CALLBACK_SETUP_COMPLETE = 0x08, + /*! + * (virtual) pointer to descriptor chain is completely linked with physical + * (DMA) addresses, ready for the hardware. This flag should not be used + * by FSL SHW API programs. + */ + FSL_UCO_CHAIN_PREPHYSICALIZED = 0x10, + /*! + * The user has changed the context but the changes have not been copied to + * the kernel driver. + */ + FSL_UCO_CONTEXT_CHANGED = 0x20, + /*! Internal Use. This context belongs to a user-mode API user. */ + FSL_UCO_USERMODE_USER = 0x40, +} fsl_shw_user_ctx_flags_t; + +/*! + * Return code for FSL_SHW library. + * + * These codes may be returned from a function call. In non-blocking mode, + * they will appear as the status in a Result Object. + */ +typedef enum fsl_shw_return_t { + /*! + * No error. As a function return code in Non-blocking mode, this may + * simply mean that the operation was accepted for eventual execution. + */ + FSL_RETURN_OK_S = 0, + /*! Failure for non-specific reason. */ + FSL_RETURN_ERROR_S, + /*! + * Operation failed because some resource was not able to be allocated. + */ + FSL_RETURN_NO_RESOURCE_S, + /*! Crypto algorithm unrecognized or improper. */ + FSL_RETURN_BAD_ALGORITHM_S, + /*! Crypto mode unrecognized or improper. */ + FSL_RETURN_BAD_MODE_S, + /*! Flag setting unrecognized or inconsistent. */ + FSL_RETURN_BAD_FLAG_S, + /*! Improper or unsupported key length for algorithm. */ + FSL_RETURN_BAD_KEY_LENGTH_S, + /*! Improper parity in a (DES, TDES) key. */ + FSL_RETURN_BAD_KEY_PARITY_S, + /*! + * Improper or unsupported data length for algorithm or internal buffer. + */ + FSL_RETURN_BAD_DATA_LENGTH_S, + /*! Authentication / Integrity Check code check failed. */ + FSL_RETURN_AUTH_FAILED_S, + /*! A memory error occurred. */ + FSL_RETURN_MEMORY_ERROR_S, + /*! An error internal to the hardware occurred. */ + FSL_RETURN_INTERNAL_ERROR_S, + /*! ECC detected Point at Infinity */ + FSL_RETURN_POINT_AT_INFINITY_S, + /*! ECC detected No Point at Infinity */ + FSL_RETURN_POINT_NOT_AT_INFINITY_S, + /*! GCD is One */ + FSL_RETURN_GCD_IS_ONE_S, + /*! GCD is not One */ + FSL_RETURN_GCD_IS_NOT_ONE_S, + /*! Candidate is Prime */ + FSL_RETURN_PRIME_S, + /*! Candidate is not Prime */ + FSL_RETURN_NOT_PRIME_S, + /*! N register loaded improperly with even value */ + FSL_RETURN_EVEN_MODULUS_ERROR_S, + /*! Divisor is zero. */ + FSL_RETURN_DIVIDE_BY_ZERO_ERROR_S, + /*! Bad Exponent or Scalar value for Point Multiply */ + FSL_RETURN_BAD_EXPONENT_ERROR_S, + /*! RNG hardware problem. */ + FSL_RETURN_OSCILLATOR_ERROR_S, + /*! RNG hardware problem. */ + FSL_RETURN_STATISTICS_ERROR_S, +} fsl_shw_return_t; + +/*! + * Algorithm Identifier. + * + * Selection of algorithm will determine how large the block size of the + * algorithm is. Context size is the same length unless otherwise specified. + * Selection of algorithm also affects the allowable key length. + */ +typedef enum fsl_shw_key_alg_t { + /*! + * Key will be used to perform an HMAC. Key size is 1 to 64 octets. Block + * size is 64 octets. + */ + FSL_KEY_ALG_HMAC, + /*! + * Advanced Encryption Standard (Rijndael). Block size is 16 octets. Key + * size is 16 octets. (The single choice of key size is a Sahara platform + * limitation.) + */ + FSL_KEY_ALG_AES, + /*! + * Data Encryption Standard. Block size is 8 octets. Key size is 8 + * octets. + */ + FSL_KEY_ALG_DES, + /*! + * 2- or 3-key Triple DES. Block size is 8 octets. Key size is 16 octets + * for 2-key Triple DES, and 24 octets for 3-key. + */ + FSL_KEY_ALG_TDES, + /*! + * ARC4. No block size. Context size is 259 octets. Allowed key size is + * 1-16 octets. (The choices for key size are a Sahara platform + * limitation.) + */ + FSL_KEY_ALG_ARC4, + /*! + * Private key of a public-private key-pair. Max is 512 bits... + */ + FSL_KEY_PK_PRIVATE, +} fsl_shw_key_alg_t; + +/*! + * Mode selector for Symmetric Ciphers. + * + * The selection of mode determines how a cryptographic algorithm will be + * used to process the plaintext or ciphertext. + * + * For all modes which are run block-by-block (that is, all but + * #FSL_SYM_MODE_STREAM), any partial operations must be performed on a text + * length which is multiple of the block size. Except for #FSL_SYM_MODE_CTR, + * these block-by-block algorithms must also be passed a total number of octets + * which is a multiple of the block size. + * + * In modes which require that the total number of octets of data be a multiple + * of the block size (#FSL_SYM_MODE_ECB and #FSL_SYM_MODE_CBC), and the user + * has a total number of octets which are not a multiple of the block size, the + * user must perform any necessary padding to get to the correct data length. + */ +typedef enum fsl_shw_sym_mode_t { + /*! + * Stream. There is no associated block size. Any request to process data + * may be of any length. This mode is only for ARC4 operations, and is + * also the only mode used for ARC4. + */ + FSL_SYM_MODE_STREAM, + + /*! + * Electronic Codebook. Each block of data is encrypted/decrypted. The + * length of the data stream must be a multiple of the block size. This + * mode may be used for DES, 3DES, and AES. The block size is determined + * by the algorithm. + */ + FSL_SYM_MODE_ECB, + /*! + * Cipher-Block Chaining. Each block of data is encrypted/decrypted and + * then "chained" with the previous block by an XOR function. Requires + * context to start the XOR (previous block). This mode may be used for + * DES, 3DES, and AES. The block size is determined by the algorithm. + */ + FSL_SYM_MODE_CBC, + /*! + * Counter. The counter is encrypted, then XORed with a block of data. + * The counter is then incremented (using modulus arithmetic) for the next + * block. The final operation may be non-multiple of block size. This mode + * may be used for AES. The block size is determined by the algorithm. + */ + FSL_SYM_MODE_CTR, +} fsl_shw_sym_mode_t; + +/*! + * Algorithm selector for Cryptographic Hash functions. + * + * Selection of algorithm determines how large the context and digest will be. + * Context is the same size as the digest (resulting hash), unless otherwise + * specified. + */ +typedef enum fsl_shw_hash_alg_t { + /*! MD5 algorithm. Digest is 16 octets. */ + FSL_HASH_ALG_MD5, + /*! SHA-1 (aka SHA or SHA-160) algorithm. Digest is 20 octets. */ + FSL_HASH_ALG_SHA1, + /*! + * SHA-224 algorithm. Digest is 28 octets, though context is 32 octets. + */ + FSL_HASH_ALG_SHA224, + /*! SHA-256 algorithm. Digest is 32 octets. */ + FSL_HASH_ALG_SHA256 +} fsl_shw_hash_alg_t; + +/*! + * The type of Authentication-Cipher function which will be performed. + */ +typedef enum fsl_shw_acc_mode_t { + /*! + * CBC-MAC for Counter. Requires context and modulus. Final operation may + * be non-multiple of block size. This mode may be used for AES. + */ + FSL_ACC_MODE_CCM, + /*! + * SSL mode. Not supported. Combines HMAC and encrypt (or decrypt). + * Needs one key object for encryption, another for the HMAC. The usual + * hashing and symmetric encryption algorithms are supported. + */ + FSL_ACC_MODE_SSL, +} fsl_shw_acc_mode_t; + +/* REQ-S2LRD-PINTFC-COA-HCO-001 */ +/*! + * Flags which control a Hash operation. + */ +typedef enum fsl_shw_hash_ctx_flags_t { + /*! + * Context is empty. Hash is started from scratch, with a + * message-processed count of zero. + */ + FSL_HASH_FLAGS_INIT = 0x01, + /*! + * Retrieve context from hardware after hashing. If used with the + * #FSL_HASH_FLAGS_FINALIZE flag, the final digest value will be saved in + * the object. + */ + FSL_HASH_FLAGS_SAVE = 0x02, + /*! Place context into hardware before hashing. */ + FSL_HASH_FLAGS_LOAD = 0x04, + /*! + * PAD message and perform final digest operation. If user message is + * pre-padded, this flag should not be used. + */ + FSL_HASH_FLAGS_FINALIZE = 0x08, +} fsl_shw_hash_ctx_flags_t; + +/*! + * Flags which control an HMAC operation. + * + * These may be combined by ORing them together. See #fsl_shw_hmco_set_flags() + * and #fsl_shw_hmco_clear_flags(). + */ +typedef enum fsl_shw_hmac_ctx_flags_t { + /*! + * Message context is empty. HMAC is started from scratch (with key) or + * from precompute of inner hash, depending on whether + * #FSL_HMAC_FLAGS_PRECOMPUTES_PRESENT is set. + */ + FSL_HMAC_FLAGS_INIT = 1, + /*! + * Retrieve ongoing context from hardware after hashing. If used with the + * #FSL_HMAC_FLAGS_FINALIZE flag, the final digest value (HMAC) will be + * saved in the object. + */ + FSL_HMAC_FLAGS_SAVE = 2, + /*! Place ongoing context into hardware before hashing. */ + FSL_HMAC_FLAGS_LOAD = 4, + /*! + * PAD message and perform final HMAC operations of inner and outer + * hashes. + */ + FSL_HMAC_FLAGS_FINALIZE = 8, + /*! + * This means that the context contains precomputed inner and outer hash + * values. + */ + FSL_HMAC_FLAGS_PRECOMPUTES_PRESENT = 16, +} fsl_shw_hmac_ctx_flags_t; + +/*! + * Flags to control use of the #fsl_shw_scco_t. + * + * These may be ORed together to get the desired effect. + * See #fsl_shw_scco_set_flags() and #fsl_shw_scco_clear_flags() + */ +typedef enum fsl_shw_sym_ctx_flags_t { + /*! + * Context is empty. In ARC4, this means that the S-Box needs to be + * generated from the key. In #FSL_SYM_MODE_CBC mode, this allows an IV of + * zero to be specified. In #FSL_SYM_MODE_CTR mode, it means that an + * initial CTR value of zero is desired. + */ + FSL_SYM_CTX_INIT = 1, + /*! + * Load context from object into hardware before running cipher. In + * #FSL_SYM_MODE_CTR mode, this would refer to the Counter Value. + */ + FSL_SYM_CTX_LOAD = 2, + /*! + * Save context from hardware into object after running cipher. In + * #FSL_SYM_MODE_CTR mode, this would refer to the Counter Value. + */ + FSL_SYM_CTX_SAVE = 4, + /*! + * Context (SBox) is to be unwrapped and wrapped on each use. + * This flag is unsupported. + * */ + FSL_SYM_CTX_PROTECT = 8, +} fsl_shw_sym_ctx_flags_t; + +/*! + * Flags which describe the state of the #fsl_shw_sko_t. + * + * These may be ORed together to get the desired effect. + * See #fsl_shw_sko_set_flags() and #fsl_shw_sko_clear_flags() + */ +typedef enum fsl_shw_key_flags_t { + /*! If algorithm is DES or 3DES, do not validate the key parity bits. */ + FSL_SKO_KEY_IGNORE_PARITY = 1, + /*! Clear key is present in the object. */ + FSL_SKO_KEY_PRESENT = 2, + /*! + * Key has been established for use. This feature is not available for all + * platforms, nor for all algorithms and modes. + */ + FSL_SKO_KEY_ESTABLISHED = 4, + /*! + * Key intended for user (software) use; can be read cleartext from the + * keystore. + */ + FSL_SKO_KEY_SW_KEY = 8, +} fsl_shw_key_flags_t; + +/*! + * Type of value which is associated with an established key. + */ +typedef uint64_t key_userid_t; + +/*! + * Flags which describe the state of the #fsl_shw_acco_t. + * + * The @a FSL_ACCO_CTX_INIT and @a FSL_ACCO_CTX_FINALIZE flags, when used + * together, provide for a one-shot operation. + */ +typedef enum fsl_shw_auth_ctx_flags_t { + /*! Initialize Context(s) */ + FSL_ACCO_CTX_INIT = 1, + /*! Load intermediate context(s). This flag is unsupported. */ + FSL_ACCO_CTX_LOAD = 2, + /*! Save intermediate context(s). This flag is unsupported. */ + FSL_ACCO_CTX_SAVE = 4, + /*! Create MAC during this operation. */ + FSL_ACCO_CTX_FINALIZE = 8, + /*! + * Formatting of CCM input data is performed by calls to + * #fsl_shw_ccm_nist_format_ctr_and_iv() and + * #fsl_shw_ccm_nist_update_ctr_and_iv(). + */ + FSL_ACCO_NIST_CCM = 0x10, +} fsl_shw_auth_ctx_flags_t; + +/*! + * The operation which controls the behavior of #fsl_shw_establish_key(). + * + * These values are passed to #fsl_shw_establish_key(). + */ +typedef enum fsl_shw_key_wrap_t { + /*! Generate a key from random values. */ + FSL_KEY_WRAP_CREATE, + /*! Use the provided clear key. */ + FSL_KEY_WRAP_ACCEPT, + /*! Unwrap a previously wrapped key. */ + FSL_KEY_WRAP_UNWRAP +} fsl_shw_key_wrap_t; + +/*! + * Modulus Selector for CTR modes. + * + * The incrementing of the Counter value may be modified by a modulus. If no + * modulus is needed or desired for AES, use #FSL_CTR_MOD_128. + */ +typedef enum fsl_shw_ctr_mod_t { + FSL_CTR_MOD_8, /*!< Run counter with modulus of 2^8. */ + FSL_CTR_MOD_16, /*!< Run counter with modulus of 2^16. */ + FSL_CTR_MOD_24, /*!< Run counter with modulus of 2^24. */ + FSL_CTR_MOD_32, /*!< Run counter with modulus of 2^32. */ + FSL_CTR_MOD_40, /*!< Run counter with modulus of 2^40. */ + FSL_CTR_MOD_48, /*!< Run counter with modulus of 2^48. */ + FSL_CTR_MOD_56, /*!< Run counter with modulus of 2^56. */ + FSL_CTR_MOD_64, /*!< Run counter with modulus of 2^64. */ + FSL_CTR_MOD_72, /*!< Run counter with modulus of 2^72. */ + FSL_CTR_MOD_80, /*!< Run counter with modulus of 2^80. */ + FSL_CTR_MOD_88, /*!< Run counter with modulus of 2^88. */ + FSL_CTR_MOD_96, /*!< Run counter with modulus of 2^96. */ + FSL_CTR_MOD_104, /*!< Run counter with modulus of 2^104. */ + FSL_CTR_MOD_112, /*!< Run counter with modulus of 2^112. */ + FSL_CTR_MOD_120, /*!< Run counter with modulus of 2^120. */ + FSL_CTR_MOD_128 /*!< Run counter with modulus of 2^128. */ +} fsl_shw_ctr_mod_t; + +/*! + * Permissions flags for Secure Partitions + */ +typedef enum fsl_shw_permission_t { +/*! SCM Access Permission: Do not zeroize/deallocate partition on SMN Fail state */ + FSL_PERM_NO_ZEROIZE = 0x80000000, +/*! SCM Access Permission: Enforce trusted key read in */ + FSL_PERM_TRUSTED_KEY_READ = 0x40000000, +/*! SCM Access Permission: Ignore Supervisor/User mode in permission determination */ + FSL_PERM_HD_S = 0x00000800, +/*! SCM Access Permission: Allow Read Access to Host Domain */ + FSL_PERM_HD_R = 0x00000400, +/*! SCM Access Permission: Allow Write Access to Host Domain */ + FSL_PERM_HD_W = 0x00000200, +/*! SCM Access Permission: Allow Execute Access to Host Domain */ + FSL_PERM_HD_X = 0x00000100, +/*! SCM Access Permission: Allow Read Access to Trusted Host Domain */ + FSL_PERM_TH_R = 0x00000040, +/*! SCM Access Permission: Allow Write Access to Trusted Host Domain */ + FSL_PERM_TH_W = 0x00000020, +/*! SCM Access Permission: Allow Read Access to Other/World Domain */ + FSL_PERM_OT_R = 0x00000004, +/*! SCM Access Permission: Allow Write Access to Other/World Domain */ + FSL_PERM_OT_W = 0x00000002, +/*! SCM Access Permission: Allow Execute Access to Other/World Domain */ + FSL_PERM_OT_X = 0x00000001, +} fsl_shw_permission_t; + +typedef enum fsl_shw_cypher_mode_t { + FSL_SHW_CYPHER_MODE_ECB = 1, /*!< ECB mode */ + FSL_SHW_CYPHER_MODE_CBC = 2, /*!< CBC mode */ +} fsl_shw_cypher_mode_t; + +typedef enum fsl_shw_pf_key_t { + FSL_SHW_PF_KEY_IIM, /*!< Present fused IIM key */ + FSL_SHW_PF_KEY_PRG, /*!< Present Program key */ + FSL_SHW_PF_KEY_IIM_PRG, /*!< Present IIM ^ Program key */ + FSL_SHW_PF_KEY_IIM_RND, /*!< Present Random key */ + FSL_SHW_PF_KEY_RND, /*!< Present IIM ^ Random key */ +} fsl_shw_pf_key_t; + +typedef enum fsl_shw_tamper_t { + FSL_SHW_TAMPER_NONE, /*!< No error detected */ + FSL_SHW_TAMPER_WTD, /*!< wire-mesh tampering det */ + FSL_SHW_TAMPER_ETBD, /*!< ext tampering det: input B */ + FSL_SHW_TAMPER_ETAD, /*!< ext tampering det: input A */ + FSL_SHW_TAMPER_EBD, /*!< external boot detected */ + FSL_SHW_TAMPER_SAD, /*!< security alarm detected */ + FSL_SHW_TAMPER_TTD, /*!< temperature tampering det */ + FSL_SHW_TAMPER_CTD, /*!< clock tampering det */ + FSL_SHW_TAMPER_VTD, /*!< voltage tampering det */ + FSL_SHW_TAMPER_MCO, /*!< monotonic counter overflow */ + FSL_SHW_TAMPER_TCO, /*!< time counter overflow */ +} fsl_shw_tamper_t; + +/****************************************************************************** + * Data Structures + *****************************************************************************/ + +/*! + * + * @brief Structure type for descriptors + * + * The first five fields are passed to the hardware. + * + *****************************************************************************/ +#ifndef USE_NEW_PTRS /* Experimental */ + +typedef struct sah_Desc { + uint32_t header; /*!< descriptor header value */ + uint32_t len1; /*!< number of data bytes in 'ptr1' buffer */ + void *ptr1; /*!< pointer to first sah_Link structure */ + uint32_t len2; /*!< number of data bytes in 'ptr2' buffer */ + void *ptr2; /*!< pointer to second sah_Link structure */ + struct sah_Desc *next; /*!< pointer to next descriptor */ +#ifdef __KERNEL__ /* This needs a better test */ + /* These two must be last. See sah_Copy_Descriptors */ + struct sah_Desc *virt_addr; /*!< Virtual (kernel) address of this + descriptor. */ + dma_addr_t dma_addr; /*!< Physical (bus) address of this + descriptor. */ + void *original_ptr1; /*!< user's pointer to ptr1 */ + void *original_ptr2; /*!< user's pointer to ptr2 */ + struct sah_Desc *original_next; /*!< user's pointer to next */ +#endif +} sah_Desc; + +#else + +typedef struct sah_Desc { + uint32_t header; /*!< descriptor header value */ + uint32_t len1; /*!< number of data bytes in 'ptr1' buffer */ + uint32_t hw_ptr1; /*!< pointer to first sah_Link structure */ + uint32_t len2; /*!< number of data bytes in 'ptr2' buffer */ + uint32_t hw_ptr2; /*!< pointer to second sah_Link structure */ + uint32_t hw_next; /*!< pointer to next descriptor */ + struct sah_Link *ptr1; /*!< (virtual) pointer to first sah_Link structure */ + struct sah_Link *ptr2; /*!< (virtual) pointer to first sah_Link structure */ + struct sah_Desc *next; /*!< (virtual) pointer to next descriptor */ +#ifdef __KERNEL__ /* This needs a better test */ + /* These two must be last. See sah_Copy_Descriptors */ + struct sah_Desc *virt_addr; /*!< Virtual (kernel) address of this + descriptor. */ + dma_addr_t dma_addr; /*!< Physical (bus) address of this + descriptor. */ +#endif +} sah_Desc; + +#endif + +/*! +******************************************************************************* +* @brief The first descriptor in a chain +******************************************************************************/ +typedef struct sah_Head_Desc { + sah_Desc desc; /*!< whole struct - must be first */ + struct fsl_shw_uco_t *user_info; /*!< where result pool lives */ + uint32_t user_ref; /*!< at time of request */ + uint32_t uco_flags; /*!< at time of request */ + uint32_t status; /*!< Status of queue entry */ + uint32_t error_status; /*!< If error, register from Sahara */ + uint32_t fault_address; /*!< If error, register from Sahara */ + uint32_t op_status; /*!< If error, register from Sahara */ + fsl_shw_return_t result; /*!< Result of running descriptor */ + struct sah_Head_Desc *next; /*!< Next in queue */ + struct sah_Head_Desc *prev; /*!< previous in queue */ + struct sah_Head_Desc *user_desc; /*!< For API async get_results */ + void *out1_ptr; /*!< For async post-processing */ + void *out2_ptr; /*!< For async post-processing */ + uint32_t out_len; /*!< For async post-processing */ +} sah_Head_Desc; + +/*! + * @brief Structure type for links + * + * The first three fields are used by hardware. + *****************************************************************************/ +#ifndef USE_NEW_PTRS + +typedef struct sah_Link { + size_t len; /*!< len of 'data' buffer in bytes */ + uint8_t *data; /*!< buffer to store data */ + struct sah_Link *next; /*!< pointer to the next sah_Link storing + * data */ + sah_Link_Flags flags; /*!< indicates the component that created the + * data buffer. Security Function internal + * information */ + key_userid_t ownerid; /*!< Auth code for established key */ + uint32_t slot; /*!< Location of the the established key */ +#ifdef __KERNEL__ /* This needs a better test */ + /* These two elements must be last. See sah_Copy_Links() */ + struct sah_Link *virt_addr; + dma_addr_t dma_addr; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) + struct page *vm_info; +#endif + uint8_t *original_data; /*!< user's version of data pointer */ + struct sah_Link *original_next; /*!< user's version of next pointer */ +#ifdef SAH_COPY_DATA + uint8_t *copy_data; /*!< Virtual address of acquired buffer */ +#endif +#endif /* kernel-only */ +} sah_Link; + +#else + +typedef struct sah_Link { + /*! len of 'data' buffer in bytes */ + size_t len; + /*! buffer to store data */ + uint32_t hw_data; + /*! Physical address */ + uint32_t hw_next; + /*! + * indicates the component that created the data buffer. Security Function + * internal information + */ + sah_Link_Flags flags; + /*! (virtual) pointer to data */ + uint8_t *data; + /*! (virtual) pointer to the next sah_Link storing data */ + struct sah_Link *next; + /*! Auth code for established key */ + key_userid_t ownerid; + /*! Location of the the established key */ + uint32_t slot; +#ifdef __KERNEL__ /* This needs a better test */ + /* These two elements must be last. See sah_Copy_Links() */ + struct sah_Link *virt_addr; + dma_addr_t dma_addr; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) + struct page *vm_info; +#endif +#endif /* kernel-only */ +} sah_Link; + +#endif + +/*! + * Initialization Object + */ +typedef struct fsl_sho_ibo_t { +} fsl_sho_ibo_t; + +/* Imported from Sahara1 driver -- is it needed forever? */ +/*! +******************************************************************************* +* FIELDS +* +* void * ref - parameter to be passed into the memory function calls +* +* void * (*malloc)(void *ref, size_t n) - pointer to user's malloc function +* +* void (*free)(void *ref, void *ptr) - pointer to user's free function +* +* void * (*memcpy)(void *ref, void *dest, const void *src, size_t n) - +* pointer to user's memcpy function +* +* void * (*memset)(void *ref, void *ptr, int ch, size_t n) - pointer to +* user's memset function +* +* @brief Structure for API memory utilities +******************************************************************************/ +typedef struct sah_Mem_Util { + /*! Who knows. Vestigial. */ + void *mu_ref; + /*! Acquire buffer of size n bytes */ + void *(*mu_malloc) (void *ref, size_t n); + /*! Acquire a sah_Head_Desc */ + sah_Head_Desc *(*mu_alloc_head_desc) (void *ref); + /* Acquire a sah_Desc */ + sah_Desc *(*mu_alloc_desc) (void *ref); + /* Acquire a sah_Link */ + sah_Link *(*mu_alloc_link) (void *ref); + /*! Free buffer at ptr */ + void (*mu_free) (void *ref, void *ptr); + /*! Free sah_Head_Desc at ptr */ + void (*mu_free_head_desc) (void *ref, sah_Head_Desc * ptr); + /*! Free sah_Desc at ptr */ + void (*mu_free_desc) (void *ref, sah_Desc * ptr); + /*! Free sah_Link at ptr */ + void (*mu_free_link) (void *ref, sah_Link * ptr); + /*! Funciton which will copy n bytes from src to dest */ + void *(*mu_memcpy) (void *ref, void *dest, const void *src, size_t n); + /*! Set all n bytes of ptr to ch */ + void *(*mu_memset) (void *ref, void *ptr, int ch, size_t n); +} sah_Mem_Util; + +/*! + * Secure Partition information + * + * This holds the context to a single secure partition owned by the user. It + * is only available in the kernel version of the User Context Object. + */ +typedef struct fsl_shw_spo_t { + uint32_t user_base; /*!< Base address (user virtual) */ + void *kernel_base; /*!< Base address (kernel virtual) */ + struct fsl_shw_spo_t *next; /*!< Pointer to the next partition + owned by the user. NULL if this + is the last partition. */ +} fsl_shw_spo_t; + +/* REQ-S2LRD-PINTFC-COA-UCO-001 */ +/*! + * User Context Object + */ +typedef struct fsl_shw_uco_t { + int sahara_openfd; /*!< this should be kernel-only?? */ + sah_Mem_Util *mem_util; /*!< Memory utility fns */ + uint32_t user_ref; /*!< User's reference */ + void (*callback) (struct fsl_shw_uco_t * uco); /*!< User's callback fn */ + uint32_t flags; /*!< from fsl_shw_user_ctx_flags_t */ + unsigned pool_size; /*!< maximum size of user pool */ +#ifdef __KERNEL__ + sah_Queue result_pool; /*!< where non-blocking results go */ + os_process_handle_t process; /*!< remember for signalling User mode */ + fsl_shw_spo_t *partition; /*!< chain of secure partitions owned by + the user */ +#else + struct fsl_shw_uco_t *next; /*!< To allow user-mode chaining of contexts, + for signalling. */ +#endif +} fsl_shw_uco_t; + +/* REQ-S2LRD-PINTFC-API-GEN-006 ?? */ +/*! + * Result object + */ +typedef struct fsl_shw_result_t { + uint32_t user_ref; + fsl_shw_return_t code; + uint32_t detail1; + uint32_t detail2; + sah_Head_Desc *user_desc; +} fsl_shw_result_t; + +/*! + * Keystore Object + */ +typedef struct fsl_shw_kso_t { +#ifdef __KERNEL__ + os_lock_t lock; /*!< Pointer to lock that controls access to + the keystore. */ +#endif + void *user_data; /*!< Pointer to user structure that handles + the internals of the keystore. */ + fsl_shw_return_t(*data_init) (fsl_shw_uco_t * user_ctx, + void **user_data); + void (*data_cleanup) (fsl_shw_uco_t * user_ctx, void **user_data); + fsl_shw_return_t(*slot_verify_access) (void *user_data, + uint64_t owner_id, + uint32_t slot); + fsl_shw_return_t(*slot_alloc) (void *user_data, uint32_t size_bytes, + uint64_t owner_id, uint32_t * slot); + fsl_shw_return_t(*slot_dealloc) (void *user_data, uint64_t owner_id, + uint32_t slot); + void *(*slot_get_address) (void *user_data, uint32_t slot); + uint32_t(*slot_get_base) (void *user_data, uint32_t slot); + uint32_t(*slot_get_offset) (void *user_data, uint32_t slot); + uint32_t(*slot_get_slot_size) (void *user_data, uint32_t slot); +} fsl_shw_kso_t; + +/* REQ-S2LRD-PINTFC-COA-SKO-001 */ +/*! + * Secret Key Context Object + */ +typedef struct fsl_shw_sko_t { + uint32_t flags; + fsl_shw_key_alg_t algorithm; + key_userid_t userid; + uint32_t handle; + uint16_t key_length; + uint8_t key[64]; + struct fsl_shw_kso_t *keystore; /*!< If present, key is in keystore */ +} fsl_shw_sko_t; + +/* REQ-S2LRD-PINTFC-COA-CO-001 */ +/*! + * @brief Platform Capability Object + */ +typedef struct fsl_shw_pco_t { /* Consider turning these constants into symbols */ + int api_major; + int api_minor; + int driver_major; + int driver_minor; + fsl_shw_key_alg_t sym_algorithms[4]; + fsl_shw_sym_mode_t sym_modes[4]; + fsl_shw_hash_alg_t hash_algorithms[4]; + uint8_t sym_support[5][4]; /* indexed by key alg then mode */ + + int scc_driver_major; + int scc_driver_minor; + int scm_version; /*!< Version from SCM Configuration register */ + int smn_version; /*!< Version from SMN Status register */ + int block_size_bytes; /*!< Number of bytes per block of RAM; also + block size of the crypto algorithm. */ + union { + struct { + int black_ram_size_blocks; /*!< Number of blocks of Black RAM */ + int red_ram_size_blocks; /*!< Number of blocks of Red RAM */ + } scc_info; + struct { + int partition_size_bytes; /*!< Number of bytes in each partition */ + int partition_count; /*!< Number of partitions on this platform */ + } scc2_info; + }; +} fsl_shw_pco_t; + +/* REQ-S2LRD-PINTFC-COA-HCO-001 */ +/*! + * Hash Context Object + */ +typedef struct fsl_shw_hco_t { /* fsl_shw_hash_context_object */ + fsl_shw_hash_alg_t algorithm; + uint32_t flags; + uint8_t digest_length; /* in bytes */ + uint8_t context_length; /* in bytes */ + uint8_t context_register_length; /* in bytes */ + uint32_t context[9]; /* largest digest + msg size */ +} fsl_shw_hco_t; + +/*! + * HMAC Context Object + */ +typedef struct fsl_shw_hmco_t { /* fsl_shw_hmac_context_object */ + fsl_shw_hash_alg_t algorithm; + uint32_t flags; + uint8_t digest_length; /*!< in bytes */ + uint8_t context_length; /*!< in bytes */ + uint8_t context_register_length; /*!< in bytes */ + uint32_t ongoing_context[9]; /*!< largest digest + msg + size */ + uint32_t inner_precompute[9]; /*!< largest digest + msg + size */ + uint32_t outer_precompute[9]; /*!< largest digest + msg + size */ +} fsl_shw_hmco_t; + +/* REQ-S2LRD-PINTFC-COA-SCCO-001 */ +/*! + * Symmetric Crypto Context Object Context Object + */ +typedef struct fsl_shw_scco_t { + uint32_t flags; + unsigned block_size_bytes; /* double duty block&ctx size */ + fsl_shw_sym_mode_t mode; + /* Could put modulus plus 16-octet context in union with arc4 + sbox+ptrs... */ + fsl_shw_ctr_mod_t modulus_exp; + uint8_t context[259]; +} fsl_shw_scco_t; + +/*! + * Authenticate-Cipher Context Object + + * An object for controlling the function of, and holding information about, + * data for the authenticate-cipher functions, #fsl_shw_gen_encrypt() and + * #fsl_shw_auth_decrypt(). + */ +typedef struct fsl_shw_acco_t { + uint32_t flags; /*!< See #fsl_shw_auth_ctx_flags_t for + meanings */ + fsl_shw_acc_mode_t mode; /*!< CCM only */ + uint8_t mac_length; /*!< User's value for length */ + unsigned q_length; /*!< NIST parameter - */ + fsl_shw_scco_t cipher_ctx_info; /*!< For running + encrypt/decrypt. */ + union { + fsl_shw_scco_t CCM_ctx_info; /*!< For running the CBC in + AES-CCM. */ + fsl_shw_hco_t hash_ctx_info; /*!< For running the hash */ + } auth_info; /*!< "auth" info struct */ + uint8_t unencrypted_mac[16]; /*!< max block size... */ +} fsl_shw_acco_t; + +/*! + * Used by Sahara API to retrieve completed non-blocking results. + */ +typedef struct sah_results { + unsigned requested; /*!< number of results requested */ + unsigned *actual; /*!< number of results obtained */ + fsl_shw_result_t *results; /*!< pointer to memory to hold results */ +} sah_results; + +/*! + * @typedef scc_partition_status_t + */ +/*! Partition status information. */ +typedef enum fsl_shw_partition_status_t { + FSL_PART_S_UNUSABLE, /*!< Partition not implemented */ + FSL_PART_S_UNAVAILABLE, /*!< Partition owned by other host */ + FSL_PART_S_AVAILABLE, /*!< Partition available */ + FSL_PART_S_ALLOCATED, /*!< Partition owned by host but not engaged + */ + FSL_PART_S_ENGAGED, /*!< Partition owned by host and engaged */ +} fsl_shw_partition_status_t; + +/****************************************************************************** + * Access Macros for Objects + *****************************************************************************/ +/*! + * Get FSL SHW API version + * + * @param pcobject The Platform Capababilities Object to query. + * @param[out] pcmajor A pointer to where the major version + * of the API is to be stored. + * @param[out] pcminor A pointer to where the minor version + * of the API is to be stored. + */ +#define fsl_shw_pco_get_version(pcobject, pcmajor, pcminor) \ +{ \ + *(pcmajor) = (pcobject)->api_major; \ + *(pcminor) = (pcobject)->api_minor; \ +} + +/*! + * Get underlying driver version. + * + * @param pcobject The Platform Capababilities Object to query. + * @param[out] pcmajor A pointer to where the major version + * of the driver is to be stored. + * @param[out] pcminor A pointer to where the minor version + * of the driver is to be stored. + */ +#define fsl_shw_pco_get_driver_version(pcobject, pcmajor, pcminor) \ +{ \ + *(pcmajor) = (pcobject)->driver_major; \ + *(pcminor) = (pcobject)->driver_minor; \ +} + +/*! + * Get list of symmetric algorithms supported. + * + * @param pcobject The Platform Capababilities Object to query. + * @param[out] pcalgorithms A pointer to where to store the location of + * the list of algorithms. + * @param[out] pcacount A pointer to where to store the number of + * algorithms in the list at @a algorithms. + */ +#define fsl_shw_pco_get_sym_algorithms(pcobject, pcalgorithms, pcacount) \ +{ \ + *(pcalgorithms) = (pcobject)->sym_algorithms; \ + *(pcacount) = sizeof((pcobject)->sym_algorithms)/4; \ +} + +/*! + * Get list of symmetric modes supported. + * + * @param pcobject The Platform Capababilities Object to query. + * @param[out] gsmodes A pointer to where to store the location of + * the list of modes. + * @param[out] gsacount A pointer to where to store the number of + * algorithms in the list at @a modes. + */ +#define fsl_shw_pco_get_sym_modes(pcobject, gsmodes, gsacount) \ +{ \ + *(gsmodes) = (pcobject)->sym_modes; \ + *(gsacount) = sizeof((pcobject)->sym_modes)/4; \ +} + +/*! + * Get list of hash algorithms supported. + * + * @param pcobject The Platform Capababilities Object to query. + * @param[out] gsalgorithms A pointer which will be set to the list of + * algorithms. + * @param[out] gsacount The number of algorithms in the list at @a + * algorithms. + */ +#define fsl_shw_pco_get_hash_algorithms(pcobject, gsalgorithms, gsacount) \ +{ \ + *(gsalgorithms) = (pcobject)->hash_algorithms; \ + *(gsacount) = sizeof((pcobject)->hash_algorithms)/4; \ +} + +/*! + * Determine whether the combination of a given symmetric algorithm and a given + * mode is supported. + * + * @param pcobject The Platform Capababilities Object to query. + * @param pcalg A Symmetric Cipher algorithm. + * @param pcmode A Symmetric Cipher mode. + * + * @return 0 if combination is not supported, non-zero if supported. + */ +#define fsl_shw_pco_check_sym_supported(pcobject, pcalg, pcmode) \ + ((pcobject)->sym_support[pcalg][pcmode]) + +/*! + * Determine whether a given Encryption-Authentication mode is supported. + * + * @param pcobject The Platform Capababilities Object to query. + * @param pcmode The Authentication mode. + * + * @return 0 if mode is not supported, non-zero if supported. + */ +#define fsl_shw_pco_check_auth_supported(pcobject, pcmode) \ + ((pcmode == FSL_ACC_MODE_CCM) ? 1 : 0) + +/*! + * Determine whether Black Keys (key establishment / wrapping) is supported. + * + * @param pcobject The Platform Capababilities Object to query. + * + * @return 0 if wrapping is not supported, non-zero if supported. + */ +#define fsl_shw_pco_check_black_key_supported(pcobject) \ + 1 + +/*! + * Determine whether Programmed Key features are available + * + * @param pc_info The Platform Capabilities Object to query. + * + * @return 1 if Programmed Key features are available, otherwise zero. + */ +#define fsl_shw_pco_check_pk_supported(pcobject) \ + 0 + +/*! + * Determine whether Software Key features are available + * + * @param pc_info The Platform Capabilities Object to query. + * + * @return 1 if Software key features are available, otherwise zero. + */ +#define fsl_shw_pco_check_sw_keys_supported(pcobject) \ + 0 + +/*! + * Get FSL SHW SCC driver version + * + * @param pcobject The Platform Capabilities Object to query. + * @param[out] pcmajor A pointer to where the major version + * of the SCC driver is to be stored. + * @param[out] pcminor A pointer to where the minor version + * of the SCC driver is to be stored. + */ +#define fsl_shw_pco_get_scc_driver_version(pcobject, pcmajor, pcminor) \ +{ \ + *(pcmajor) = (pcobject)->scc_driver_major; \ + *(pcminor) = (pcobject)->scc_driver_minor; \ +} + +/*! + * Get SCM hardware version + * + * @param pcobject The Platform Capabilities Object to query. + * @return The SCM hardware version + */ +#define fsl_shw_pco_get_scm_version(pcobject) \ + ((pcobject)->scm_version) + +/*! + * Get SMN hardware version + * + * @param pcobject The Platform Capabilities Object to query. + * @return The SMN hardware version + */ +#define fsl_shw_pco_get_smn_version(pcobject) \ + ((pcobject)->smn_version) + +/*! + * Get the size of an SCM block, in bytes + * + * @param pcobject The Platform Capabilities Object to query. + * @return The size of an SCM block, in bytes. + */ +#define fsl_shw_pco_get_scm_block_size(pcobject) \ + ((pcobject)->block_size_bytes) + +/*! + * Get size of Black and Red RAM memory + * + * @param pcobject The Platform Capabilities Object to query. + * @param[out] black_size A pointer to where the size of the Black RAM, in + * blocks, is to be placed. + * @param[out] red_size A pointer to where the size of the Red RAM, in + * blocks, is to be placed. + */ +#define fsl_shw_pco_get_smn_size(pcobject, black_size, red_size) \ +{ \ + if ((pcobject)->scm_version == 1) { \ + *(black_size) = (pcobject)->scc_info.black_ram_size_blocks; \ + *(red_size) = (pcobject)->scc_info.red_ram_size_blocks; \ + } else { \ + *(black_size) = 0; \ + *(red_size) = 0; \ + } \ +} + +/*! + * Determine whether Secure Partitions are supported + * + * @param pcobject The Platform Capabilities Object to query. + * + * @return 0 if secure partitions are not supported, non-zero if supported. + */ +#define fsl_shw_pco_check_spo_supported(pcobject) \ + ((pcobject)->scm_version == 2) + +/*! + * Get the size of a Secure Partitions + * + * @param pcobject The Platform Capabilities Object to query. + * + * @return Partition size, in bytes. 0 if Secure Partitions not supported. + */ +#define fsl_shw_pco_get_spo_size_bytes(pcobject) \ + (((pcobject)->scm_version == 2) ? \ + ((pcobject)->scc2_info.partition_size_bytes) : 0 ) + +/*! + * Get the number of Secure Partitions on this platform + * + * @param pcobject The Platform Capabilities Object to query. + * + * @return Number of partitions. 0 if Secure Paritions not supported. Note + * that this returns the total number of partitions, not all may be + * available to the user. + */ +#define fsl_shw_pco_get_spo_count(pcobject) \ + (((pcobject)->scm_version == 2) ? \ + ((pcobject)->scc2_info.partition_count) : 0 ) + +/*! + * Initialize a User Context Object. + * + * This function must be called before performing any other operation with the + * Object. It sets the User Context Object to initial values, and set the size + * of the results pool. The mode will be set to a default of + * #FSL_UCO_BLOCKING_MODE. + * + * When using non-blocking operations, this sets the maximum number of + * operations which can be outstanding. This number includes the counts of + * operations waiting to start, operation(s) being performed, and results which + * have not been retrieved. + * + * Changes to this value are ignored once user registration has completed. It + * should be set to 1 if only blocking operations will ever be performed. + * + * @param ucontext The User Context object to operate on. + * @param usize The maximum number of operations which can be + * outstanding. + */ +#ifdef __KERNEL__ +#define fsl_shw_uco_init(ucontext, usize) \ +{ \ + (ucontext)->pool_size = usize; \ + (ucontext)->flags = FSL_UCO_BLOCKING_MODE; \ + (ucontext)->sahara_openfd = -1; \ + (ucontext)->mem_util = NULL; \ + (ucontext)->partition = NULL; \ + (ucontext)->callback = NULL; \ +} +#else +#define fsl_shw_uco_init(ucontext, usize) \ +{ \ + (ucontext)->pool_size = usize; \ + (ucontext)->flags = FSL_UCO_BLOCKING_MODE; \ + (ucontext)->sahara_openfd = -1; \ + (ucontext)->mem_util = NULL; \ + (ucontext)->callback = NULL; \ +} +#endif + +/*! + * Set the User Reference for the User Context. + * + * @param ucontext The User Context object to operate on. + * @param uref A value which will be passed back with a result. + */ +#define fsl_shw_uco_set_reference(ucontext, uref) \ + (ucontext)->user_ref = uref + +/*! + * Set the User Reference for the User Context. + * + * @param ucontext The User Context object to operate on. + * @param ucallback The function the API will invoke when an operation + * completes. + */ +#define fsl_shw_uco_set_callback(ucontext, ucallback) \ + (ucontext)->callback = ucallback + +/*! + * Set flags in the User Context. + * + * Turns on the flags specified in @a flags. Other flags are untouched. + * + * @param ucontext The User Context object to operate on. + * @param uflags ORed values from #fsl_shw_user_ctx_flags_t. + */ +#define fsl_shw_uco_set_flags(ucontext, uflags) \ + (ucontext)->flags |= (uflags) + +/*! + * Clear flags in the User Context. + * + * Turns off the flags specified in @a flags. Other flags are untouched. + * + * @param ucontext The User Context object to operate on. + * @param uflags ORed values from #fsl_shw_user_ctx_flags_t. + */ +#define fsl_shw_uco_clear_flags(ucontext, uflags) \ + (ucontext)->flags &= ~(uflags) + +/*! + * Retrieve the reference value from a Result Object. + * + * @param robject The result object to query. + * + * @return The reference associated with the request. + */ +#define fsl_shw_ro_get_reference(robject) \ + (robject)->user_ref + +/*! + * Retrieve the status code from a Result Object. + * + * @param robject The result object to query. + * + * @return The status of the request. + */ +#define fsl_shw_ro_get_status(robject) \ + (robject)->code + +/*! + * Initialize a Secret Key Object. + * + * This function must be called before performing any other operation with + * the Object. + * + * @param skobject The Secret Key Object to be initialized. + * @param skalgorithm DES, AES, etc. + * + */ +#define fsl_shw_sko_init(skobject,skalgorithm) \ +{ \ + (skobject)->algorithm = skalgorithm; \ + (skobject)->flags = 0; \ + (skobject)->keystore = NULL; \ +} + +/*! + * Initialize a Secret Key Object to use a Platform Key register. + * + * This function must be called before performing any other operation with + * the Object. INVALID on this platform. + * + * @param skobject The Secret Key Object to be initialized. + * @param skalgorithm DES, AES, etc. + * @param skhwkey one of the fsl_shw_pf_key_t values. + * + */ +#define fsl_shw_sko_init_pf_key(skobject,skalgorithm,skhwkey) \ +{ \ + (skobject)->algorithm = -1; \ + (skobject)->flags = -1; \ + (skobject)->keystore = NULL; \ +} + +/*! + * Store a cleartext key in the key object. + * + * This has the side effect of setting the #FSL_SKO_KEY_PRESENT flag and + * resetting the #FSL_SKO_KEY_ESTABLISHED flag. + * + * @param skobject A variable of type #fsl_shw_sko_t. + * @param skkey A pointer to the beginning of the key. + * @param skkeylen The length, in octets, of the key. The value should be + * appropriate to the key size supported by the algorithm. + * 64 octets is the absolute maximum value allowed for this + * call. + */ +#define fsl_shw_sko_set_key(skobject, skkey, skkeylen) \ +{ \ + (skobject)->key_length = skkeylen; \ + copy_bytes((skobject)->key, skkey, skkeylen); \ + (skobject)->flags |= FSL_SKO_KEY_PRESENT; \ + (skobject)->flags &= ~FSL_SKO_KEY_ESTABLISHED; \ +} + +/*! + * Set a size for the key. + * + * This function would normally be used when the user wants the key to be + * generated from a random source. + * + * @param skobject A variable of type #fsl_shw_sko_t. + * @param skkeylen The length, in octets, of the key. The value should be + * appropriate to the key size supported by the algorithm. + * 64 octets is the absolute maximum value allowed for this + * call. + */ +#define fsl_shw_sko_set_key_length(skobject, skkeylen) \ + (skobject)->key_length = skkeylen; + +/*! + * Set the User ID associated with the key. + * + * @param skobject A variable of type #fsl_shw_sko_t. + * @param skuserid The User ID to identify authorized users of the key. + */ +#define fsl_shw_sko_set_user_id(skobject, skuserid) \ + (skobject)->userid = (skuserid) + +/*! + * Establish a user Keystore to hold the key. + */ +#define fsl_shw_sko_set_keystore(skobject, user_keystore) \ + (skobject)->keystore = (user_keystore) + +/*! + * Set the establish key handle into a key object. + * + * The @a userid field will be used to validate the access to the unwrapped + * key. This feature is not available for all platforms, nor for all + * algorithms and modes. + * + * The #FSL_SKO_KEY_ESTABLISHED will be set (and the #FSL_SKO_KEY_PRESENT flag + * will be cleared). + * + * @param skobject A variable of type #fsl_shw_sko_t. + * @param skuserid The User ID to verify this user is an authorized user of + * the key. + * @param skhandle A @a handle from #fsl_shw_sko_get_established_info. + */ +#define fsl_shw_sko_set_established_info(skobject, skuserid, skhandle) \ +{ \ + (skobject)->userid = (skuserid); \ + (skobject)->handle = (skhandle); \ + (skobject)->flags |= FSL_SKO_KEY_ESTABLISHED; \ + (skobject)->flags &= \ + ~(FSL_SKO_KEY_PRESENT); \ +} + +/*! + * Retrieve the established-key handle from a key object. + * + * @param skobject A variable of type #fsl_shw_sko_t. + * @param skhandle The location to store the @a handle of the unwrapped + * key. + */ +#define fsl_shw_sko_get_established_info(skobject, skhandle) \ + *(skhandle) = (skobject)->handle + +/*! + * Extract the algorithm from a key object. + * + * @param skobject The Key Object to be queried. + * @param[out] skalgorithm A pointer to the location to store the algorithm. + */ +#define fsl_shw_sko_get_algorithm(skobject, skalgorithm) \ + *(skalgorithm) = (skobject)->algorithm + +/*! + * Retrieve the cleartext key from a key object that is stored in a user + * keystore. + * + * @param skobject The Key Object to be queried. + * @param[out] skkey A pointer to the location to store the key. NULL + * if the key is not stored in a user keystore. + */ +#define fsl_shw_sko_get_key(skobject, skkey) \ +{ \ + fsl_shw_kso_t* keystore = (skobject)->keystore; \ + if (keystore != NULL) { \ + *(skkey) = keystore->slot_get_address(keystore->user_data, \ + (skobject)->handle); \ + } else { \ + *(skkey) = NULL; \ + } \ +} + +/*! + * Determine the size of a wrapped key based upon the cleartext key's length. + * + * This function can be used to calculate the number of octets that + * #fsl_shw_extract_key() will write into the location at @a covered_key. + * + * If zero is returned at @a length, this means that the key length in + * @a key_info is not supported. + * + * @param wkeyinfo Information about a key to be wrapped. + * @param wkeylen Location to store the length of a wrapped + * version of the key in @a key_info. + */ +#define fsl_shw_sko_calculate_wrapped_size(wkeyinfo, wkeylen) \ +{ \ + register fsl_shw_sko_t* kp = wkeyinfo; \ + register uint32_t kl = kp->key_length; \ + int key_blocks = (kl + 15) / 16; \ + int base_size = 35; /* ICV + T' + ALG + LEN + FLAGS */ \ + \ + *(wkeylen) = base_size + 16 * key_blocks; \ +} + +/*! + * Set some flags in the key object. + * + * Turns on the flags specified in @a flags. Other flags are untouched. + * + * @param skobject A variable of type #fsl_shw_sko_t. + * @param skflags (One or more) ORed members of #fsl_shw_key_flags_t which + * are to be set. + */ +#define fsl_shw_sko_set_flags(skobject, skflags) \ + (skobject)->flags |= (skflags) + +/*! + * Clear some flags in the key object. + * + * Turns off the flags specified in @a flags. Other flags are untouched. + * + * @param skobject A variable of type #fsl_shw_sko_t. + * @param skflags (One or more) ORed members of #fsl_shw_key_flags_t + * which are to be reset. + */ +#define fsl_shw_sko_clear_flags(skobject, skflags) \ + (skobject)->flags &= ~(skflags) + +/*! + * Initialize a Hash Context Object. + * + * This function must be called before performing any other operation with the + * Object. It sets the current message length and hash algorithm in the hash + * context object. + * + * @param hcobject The hash context to operate upon. + * @param hcalgorithm The hash algorithm to be used (#FSL_HASH_ALG_MD5, + * #FSL_HASH_ALG_SHA256, etc). + * + */ +#define fsl_shw_hco_init(hcobject, hcalgorithm) \ +{ \ + (hcobject)->algorithm = hcalgorithm; \ + (hcobject)->flags = 0; \ + switch (hcalgorithm) { \ + case FSL_HASH_ALG_MD5: \ + (hcobject)->digest_length = 16; \ + (hcobject)->context_length = 16; \ + (hcobject)->context_register_length = 24; \ + break; \ + case FSL_HASH_ALG_SHA1: \ + (hcobject)->digest_length = 20; \ + (hcobject)->context_length = 20; \ + (hcobject)->context_register_length = 24; \ + break; \ + case FSL_HASH_ALG_SHA224: \ + (hcobject)->digest_length = 28; \ + (hcobject)->context_length = 32; \ + (hcobject)->context_register_length = 36; \ + break; \ + case FSL_HASH_ALG_SHA256: \ + (hcobject)->digest_length = 32; \ + (hcobject)->context_length = 32; \ + (hcobject)->context_register_length = 36; \ + break; \ + default: \ + /* error ! */ \ + (hcobject)->digest_length = 1; \ + (hcobject)->context_length = 1; \ + (hcobject)->context_register_length = 1; \ + break; \ + } \ +} + +/*! + * Get the current hash value and message length from the hash context object. + * + * The algorithm must have already been specified. See #fsl_shw_hco_init(). + * + * @param hcobject The hash context to query. + * @param[out] hccontext Pointer to the location of @a length octets where to + * store a copy of the current value of the digest. + * @param hcclength Number of octets of hash value to copy. + * @param[out] hcmsglen Pointer to the location to store the number of octets + * already hashed. + */ +#define fsl_shw_hco_get_digest(hcobject, hccontext, hcclength, hcmsglen) \ +{ \ + copy_bytes(hccontext, (hcobject)->context, hcclength); \ + if ((hcobject)->algorithm == FSL_HASH_ALG_SHA224 \ + || (hcobject)->algorithm == FSL_HASH_ALG_SHA256) { \ + *(hcmsglen) = (hcobject)->context[8]; \ + } else { \ + *(hcmsglen) = (hcobject)->context[5]; \ + } \ +} + +/*! + * Get the hash algorithm from the hash context object. + * + * @param hcobject The hash context to query. + * @param[out] hcalgorithm Pointer to where the algorithm is to be stored. + */ +#define fsl_shw_hco_get_info(hcobject, hcalgorithm) \ +{ \ + *(hcalgorithm) = (hcobject)->algorithm; \ +} + +/*! + * Set the current hash value and message length in the hash context object. + * + * The algorithm must have already been specified. See #fsl_shw_hco_init(). + * + * @param hcobject The hash context to operate upon. + * @param hccontext Pointer to buffer of appropriate length to copy into + * the hash context object. + * @param hcmsglen The number of octets of the message which have + * already been hashed. + * + */ +#define fsl_shw_hco_set_digest(hcobject, hccontext, hcmsglen) \ +{ \ + copy_bytes((hcobject)->context, hccontext, (hcobject)->context_length); \ + if (((hcobject)->algorithm == FSL_HASH_ALG_SHA224) \ + || ((hcobject)->algorithm == FSL_HASH_ALG_SHA256)) { \ + (hcobject)->context[8] = hcmsglen; \ + } else { \ + (hcobject)->context[5] = hcmsglen; \ + } \ +} + +/*! + * Set flags in a Hash Context Object. + * + * Turns on the flags specified in @a flags. Other flags are untouched. + * + * @param hcobject The hash context to be operated on. + * @param hcflags The flags to be set in the context. These can be ORed + * members of #fsl_shw_hash_ctx_flags_t. + */ +#define fsl_shw_hco_set_flags(hcobject, hcflags) \ + (hcobject)->flags |= (hcflags) + +/*! + * Clear flags in a Hash Context Object. + * + * Turns off the flags specified in @a flags. Other flags are untouched. + * + * @param hcobject The hash context to be operated on. + * @param hcflags The flags to be reset in the context. These can be ORed + * members of #fsl_shw_hash_ctx_flags_t. + */ +#define fsl_shw_hco_clear_flags(hcobject, hcflags) \ + (hcobject)->flags &= ~(hcflags) + +/*! + * Initialize an HMAC Context Object. + * + * This function must be called before performing any other operation with the + * Object. It sets the current message length and hash algorithm in the HMAC + * context object. + * + * @param hcobject The HMAC context to operate upon. + * @param hcalgorithm The hash algorithm to be used (#FSL_HASH_ALG_MD5, + * #FSL_HASH_ALG_SHA256, etc). + * + */ +#define fsl_shw_hmco_init(hcobject, hcalgorithm) \ + fsl_shw_hco_init(hcobject, hcalgorithm) + +/*! + * Set flags in an HMAC Context Object. + * + * Turns on the flags specified in @a flags. Other flags are untouched. + * + * @param hcobject The HMAC context to be operated on. + * @param hcflags The flags to be set in the context. These can be ORed + * members of #fsl_shw_hmac_ctx_flags_t. + */ +#define fsl_shw_hmco_set_flags(hcobject, hcflags) \ + (hcobject)->flags |= (hcflags) + +/*! + * Clear flags in an HMAC Context Object. + * + * Turns off the flags specified in @a flags. Other flags are untouched. + * + * @param hcobject The HMAC context to be operated on. + * @param hcflags The flags to be reset in the context. These can be ORed + * members of #fsl_shw_hmac_ctx_flags_t. + */ +#define fsl_shw_hmco_clear_flags(hcobject, hcflags) \ + (hcobject)->flags &= ~(hcflags) + +/*! + * Initialize a Symmetric Cipher Context Object. + * + * This function must be called before performing any other operation with the + * Object. This will set the @a mode and @a algorithm and initialize the + * Object. + * + * @param scobject The context object to operate on. + * @param scalg The cipher algorithm this context will be used with. + * @param scmode #FSL_SYM_MODE_CBC, #FSL_SYM_MODE_ECB, etc. + * + */ +#define fsl_shw_scco_init(scobject, scalg, scmode) \ +{ \ + register uint32_t bsb; /* block-size bytes */ \ + \ + switch (scalg) { \ + case FSL_KEY_ALG_AES: \ + bsb = 16; \ + break; \ + case FSL_KEY_ALG_DES: \ + /* fall through */ \ + case FSL_KEY_ALG_TDES: \ + bsb = 8; \ + break; \ + case FSL_KEY_ALG_ARC4: \ + bsb = 259; \ + break; \ + case FSL_KEY_ALG_HMAC: \ + bsb = 1; /* meaningless */ \ + break; \ + default: \ + bsb = 00; \ + } \ + (scobject)->block_size_bytes = bsb; \ + (scobject)->mode = scmode; \ + (scobject)->flags = 0; \ +} + +/*! + * Set the flags for a Symmetric Cipher Context. + * + * Turns on the flags specified in @a flags. Other flags are untouched. + * + * @param scobject The context object to operate on. + * @param scflags The flags to reset (one or more values from + * #fsl_shw_sym_ctx_flags_t ORed together). + * + */ +#define fsl_shw_scco_set_flags(scobject, scflags) \ + (scobject)->flags |= (scflags) + +/*! + * Clear some flags in a Symmetric Cipher Context Object. + * + * Turns off the flags specified in @a flags. Other flags are untouched. + * + * @param scobject The context object to operate on. + * @param scflags The flags to reset (one or more values from + * #fsl_shw_sym_ctx_flags_t ORed together). + * + */ +#define fsl_shw_scco_clear_flags(scobject, scflags) \ + (scobject)->flags &= ~(scflags) + +/*! + * Set the Context (IV) for a Symmetric Cipher Context. + * + * This is to set the context/IV for #FSL_SYM_MODE_CBC mode, or to set the + * context (the S-Box and pointers) for ARC4. The full context size will + * be copied. + * + * @param scobject The context object to operate on. + * @param sccontext A pointer to the buffer which contains the context. + * + */ +#define fsl_shw_scco_set_context(scobject, sccontext) \ + copy_bytes((scobject)->context, sccontext, \ + (scobject)->block_size_bytes) + +/*! + * Get the Context for a Symmetric Cipher Context. + * + * This is to retrieve the context/IV for #FSL_SYM_MODE_CBC mode, or to + * retrieve context (the S-Box and pointers) for ARC4. The full context + * will be copied. + * + * @param scobject The context object to operate on. + * @param[out] sccontext Pointer to location where context will be stored. + */ +#define fsl_shw_scco_get_context(scobject, sccontext) \ + copy_bytes(sccontext, (scobject)->context, (scobject)->block_size_bytes) + +/*! + * Set the Counter Value for a Symmetric Cipher Context. + * + * This will set the Counter Value for CTR mode. + * + * @param scobject The context object to operate on. + * @param sccounter The starting counter value. The number of octets. + * copied will be the block size for the algorithm. + * @param scmodulus The modulus for controlling the incrementing of the + * counter. + * + */ +#define fsl_shw_scco_set_counter_info(scobject, sccounter, scmodulus) \ + { \ + if ((sccounter) != NULL) { \ + copy_bytes((scobject)->context, sccounter, \ + (scobject)->block_size_bytes); \ + } \ + (scobject)->modulus_exp = scmodulus; \ + } + +/*! + * Get the Counter Value for a Symmetric Cipher Context. + * + * This will retrieve the Counter Value is for CTR mode. + * + * @param scobject The context object to query. + * @param[out] sccounter Pointer to location to store the current counter + * value. The number of octets copied will be the + * block size for the algorithm. + * @param[out] scmodulus Pointer to location to store the modulus. + * + */ +#define fsl_shw_scco_get_counter_info(scobject, sccounter, scmodulus) \ + { \ + if ((sccounter) != NULL) { \ + copy_bytes(sccounter, (scobject)->context, \ + (scobject)->block_size_bytes); \ + } \ + if ((scmodulus) != NULL) { \ + *(scmodulus) = (scobject)->modulus_exp; \ + } \ + } + +/*! + * Initialize a Authentication-Cipher Context. + * + * @param acobject Pointer to object to operate on. + * @param acmode The mode for this object (only #FSL_ACC_MODE_CCM + * supported). + */ +#define fsl_shw_acco_init(acobject, acmode) \ + { \ + (acobject)->flags = 0; \ + (acobject)->mode = (acmode); \ + } + +/*! + * Set the flags for a Authentication-Cipher Context. + * + * Turns on the flags specified in @a flags. Other flags are untouched. + * + * @param acobject Pointer to object to operate on. + * @param acflags The flags to set (one or more from + * #fsl_shw_auth_ctx_flags_t ORed together). + * + */ +#define fsl_shw_acco_set_flags(acobject, acflags) \ + (acobject)->flags |= (acflags) + +/*! + * Clear some flags in a Authentication-Cipher Context Object. + * + * Turns off the flags specified in @a flags. Other flags are untouched. + * + * @param acobject Pointer to object to operate on. + * @param acflags The flags to reset (one or more from + * #fsl_shw_auth_ctx_flags_t ORed together). + * + */ +#define fsl_shw_acco_clear_flags(acobject, acflags) \ + (acobject)->flags &= ~(acflags) + +/*! + * Set up the Authentication-Cipher Object for CCM mode. + * + * This will set the @a auth_object for CCM mode and save the @a ctr, + * and @a mac_length. This function can be called instead of + * #fsl_shw_acco_init(). + * + * The paramater @a ctr is Counter Block 0, (counter value 0), which is for the + * MAC. + * + * @param acobject Pointer to object to operate on. + * @param acalg Cipher algorithm. Only AES is supported. + * @param accounter The initial counter value. + * @param acmaclen The number of octets used for the MAC. Valid values are + * 4, 6, 8, 10, 12, 14, and 16. + */ +/* Do we need to stash the +1 value of the CTR somewhere? */ +#define fsl_shw_acco_set_ccm(acobject, acalg, accounter, acmaclen) \ +{ \ + (acobject)->flags = 0; \ + (acobject)->mode = FSL_ACC_MODE_CCM; \ + (acobject)->auth_info.CCM_ctx_info.block_size_bytes = 16; \ + (acobject)->cipher_ctx_info.block_size_bytes = 16; \ + (acobject)->mac_length = acmaclen; \ + fsl_shw_scco_set_counter_info(&(acobject)->cipher_ctx_info, accounter, \ + FSL_CTR_MOD_128); \ +} + +/*! + * Format the First Block (IV) & Initial Counter Value per NIST CCM. + * + * This function will also set the IV and CTR values per Appendix A of NIST + * Special Publication 800-38C (May 2004). It will also perform the + * #fsl_shw_acco_set_ccm() operation with information derived from this set of + * parameters. + * + * Note this function assumes the algorithm is AES. It initializes the + * @a auth_object by setting the mode to #FSL_ACC_MODE_CCM and setting the + * flags to be #FSL_ACCO_NIST_CCM. + * + * @param acobject Pointer to object to operate on. + * @param act The number of octets used for the MAC. Valid values are + * 4, 6, 8, 10, 12, 14, and 16. + * @param acad Number of octets of Associated Data (may be zero). + * @param acq A value for the size of the length of @a q field. Valid + * values are 1-8. + * @param acN The Nonce (packet number or other changing value). Must + * be (15 - @a q_length) octets long. + * @param acQ The value of Q (size of the payload in octets). + * + */ +/* Do we need to stash the +1 value of the CTR somewhere? */ +#define fsl_shw_ccm_nist_format_ctr_and_iv(acobject, act, acad, acq, acN, acQ)\ + { \ + uint64_t Q = acQ; \ + uint8_t bflag = ((acad)?0x40:0) | ((((act)-2)/2)<<3) | ((acq)-1); \ + unsigned i; \ + uint8_t* qptr = (acobject)->auth_info.CCM_ctx_info.context + 15; \ + (acobject)->auth_info.CCM_ctx_info.block_size_bytes = 16; \ + (acobject)->cipher_ctx_info.block_size_bytes = 16; \ + (acobject)->mode = FSL_ACC_MODE_CCM; \ + (acobject)->flags = FSL_ACCO_NIST_CCM; \ + \ + /* Store away the MAC length (after calculating actual value */ \ + (acobject)->mac_length = (act); \ + /* Set Flag field in Block 0 */ \ + *((acobject)->auth_info.CCM_ctx_info.context) = bflag; \ + /* Set Nonce field in Block 0 */ \ + copy_bytes((acobject)->auth_info.CCM_ctx_info.context+1, acN, \ + 15-(acq)); \ + /* Set Flag field in ctr */ \ + *((acobject)->cipher_ctx_info.context) = (acq)-1; \ + /* Update the Q (payload length) field of Block0 */ \ + (acobject)->q_length = acq; \ + for (i = 0; i < (acq); i++) { \ + *qptr-- = Q & 0xFF; \ + Q >>= 8; \ + } \ + /* Set the Nonce field of the ctr */ \ + copy_bytes((acobject)->cipher_ctx_info.context+1, acN, 15-(acq)); \ + /* Clear the block counter field of the ctr */ \ + memset((acobject)->cipher_ctx_info.context+16-(acq), 0, (acq)+1); \ + } + +/*! + * Update the First Block (IV) & Initial Counter Value per NIST CCM. + * + * This function will set the IV and CTR values per Appendix A of NIST Special + * Publication 800-38C (May 2004). + * + * Note this function assumes that #fsl_shw_ccm_nist_format_ctr_and_iv() has + * previously been called on the @a auth_object. + * + * @param acobject Pointer to object to operate on. + * @param acN The Nonce (packet number or other changing value). Must + * be (15 - @a q_length) octets long. + * @param acQ The value of Q (size of the payload in octets). + * + */ +/* Do we need to stash the +1 value of the CTR somewhere? */ +#define fsl_shw_ccm_nist_update_ctr_and_iv(acobject, acN, acQ) \ + { \ + uint64_t Q = acQ; \ + unsigned i; \ + uint8_t* qptr = (acobject)->auth_info.CCM_ctx_info.context + 15; \ + \ + /* Update the Nonce field field of Block0 */ \ + copy_bytes((acobject)->auth_info.CCM_ctx_info.context+1, acN, \ + 15 - (acobject)->q_length); \ + /* Update the Q (payload length) field of Block0 */ \ + for (i = 0; i < (acobject)->q_length; i++) { \ + *qptr-- = Q & 0xFF; \ + Q >>= 8; \ + } \ + /* Update the Nonce field of the ctr */ \ + copy_bytes((acobject)->cipher_ctx_info.context+1, acN, \ + 15 - (acobject)->q_length); \ + } + +/****************************************************************************** + * Library functions + *****************************************************************************/ +/* REQ-S2LRD-PINTFC-API-GEN-003 */ +extern fsl_shw_pco_t *fsl_shw_get_capabilities(fsl_shw_uco_t * user_ctx); + +/* REQ-S2LRD-PINTFC-API-GEN-004 */ +extern fsl_shw_return_t fsl_shw_register_user(fsl_shw_uco_t * user_ctx); + +/* REQ-S2LRD-PINTFC-API-GEN-005 */ +extern fsl_shw_return_t fsl_shw_deregister_user(fsl_shw_uco_t * user_ctx); + +/* REQ-S2LRD-PINTFC-API-GEN-006 */ +extern fsl_shw_return_t fsl_shw_get_results(fsl_shw_uco_t * user_ctx, + unsigned result_size, + fsl_shw_result_t results[], + unsigned *result_count); + +extern fsl_shw_return_t fsl_shw_establish_key(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info, + fsl_shw_key_wrap_t establish_type, + const uint8_t * key); + +extern fsl_shw_return_t fsl_shw_extract_key(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info, + uint8_t * covered_key); + +extern fsl_shw_return_t fsl_shw_release_key(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info); + +extern void *fsl_shw_smalloc(fsl_shw_uco_t * user_ctx, + uint32_t size, + const uint8_t * UMID, uint32_t permissions); + +extern fsl_shw_return_t fsl_shw_sfree(fsl_shw_uco_t * user_ctx, void *address); + +extern fsl_shw_return_t fsl_shw_sstatus(fsl_shw_uco_t * user_ctx, + void *address, + fsl_shw_partition_status_t * status); + +extern fsl_shw_return_t fsl_shw_diminish_perms(fsl_shw_uco_t * user_ctx, + void *address, + uint32_t permissions); + +extern fsl_shw_return_t do_scc_engage_partition(fsl_shw_uco_t * user_ctx, + void *address, + const uint8_t * UMID, + uint32_t permissions); + +extern fsl_shw_return_t do_system_keystore_slot_alloc(fsl_shw_uco_t * user_ctx, + uint32_t key_lenth, + uint64_t ownerid, + uint32_t * slot); + +extern fsl_shw_return_t do_system_keystore_slot_dealloc(fsl_shw_uco_t * + user_ctx, + uint64_t ownerid, + uint32_t slot); + +extern fsl_shw_return_t do_system_keystore_slot_load(fsl_shw_uco_t * user_ctx, + uint64_t ownerid, + uint32_t slot, + const uint8_t * key, + uint32_t key_length); + +extern fsl_shw_return_t do_system_keystore_slot_read(fsl_shw_uco_t * user_ctx, + uint64_t ownerid, + uint32_t slot, + uint32_t key_length, + const uint8_t * key); + +extern fsl_shw_return_t do_system_keystore_slot_encrypt(fsl_shw_uco_t * + user_ctx, + uint64_t ownerid, + uint32_t slot, + uint32_t key_length, + uint8_t * black_data); + +extern fsl_shw_return_t do_system_keystore_slot_decrypt(fsl_shw_uco_t * + user_ctx, + uint64_t ownerid, + uint32_t slot, + uint32_t key_length, + const uint8_t * + black_data); + +extern fsl_shw_return_t +do_scc_encrypt_region(fsl_shw_uco_t * user_ctx, + void *partition_base, uint32_t offset_bytes, + uint32_t byte_count, uint8_t * black_data, + uint32_t * IV, fsl_shw_cypher_mode_t cypher_mode); + +extern fsl_shw_return_t +do_scc_decrypt_region(fsl_shw_uco_t * user_ctx, + void *partition_base, uint32_t offset_bytes, + uint32_t byte_count, const uint8_t * black_data, + uint32_t * IV, fsl_shw_cypher_mode_t cypher_mode); + +extern fsl_shw_return_t +system_keystore_get_slot_info(uint64_t owner_id, uint32_t slot, + uint32_t * address, uint32_t * slot_size_bytes); + +/* REQ-S2LRD-PINTFC-API-BASIC-SYM-002 */ +/* PINTFC-API-BASIC-SYM-ARC4-001 */ +/* PINTFC-API-BASIC-SYM-ARC4-002 */ +extern fsl_shw_return_t fsl_shw_symmetric_encrypt(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info, + fsl_shw_scco_t * sym_ctx, + uint32_t length, + const uint8_t * pt, + uint8_t * ct); + +/* PINTFC-API-BASIC-SYM-002 */ +/* PINTFC-API-BASIC-SYM-ARC4-001 */ +/* PINTFC-API-BASIC-SYM-ARC4-002 */ +extern fsl_shw_return_t fsl_shw_symmetric_decrypt(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info, + fsl_shw_scco_t * sym_ctx, + uint32_t length, + const uint8_t * ct, + uint8_t * pt); + +/* REQ-S2LRD-PINTFC-API-BASIC-HASH-005 */ +extern fsl_shw_return_t fsl_shw_hash(fsl_shw_uco_t * user_ctx, + fsl_shw_hco_t * hash_ctx, + const uint8_t * msg, + uint32_t length, + uint8_t * result, uint32_t result_len); + +/* REQ-S2LRD-PINTFC-API-BASIC-HMAC-001 */ +extern fsl_shw_return_t fsl_shw_hmac_precompute(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info, + fsl_shw_hmco_t * hmac_ctx); + +/* REQ-S2LRD-PINTFC-API-BASIC-HMAC-002 */ +extern fsl_shw_return_t fsl_shw_hmac(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info, + fsl_shw_hmco_t * hmac_ctx, + const uint8_t * msg, + uint32_t length, + uint8_t * result, uint32_t result_len); + +/* REQ-S2LRD-PINTFC-API-BASIC-RNG-002 */ +extern fsl_shw_return_t fsl_shw_get_random(fsl_shw_uco_t * user_ctx, + uint32_t length, uint8_t * data); + +extern fsl_shw_return_t fsl_shw_add_entropy(fsl_shw_uco_t * user_ctx, + uint32_t length, uint8_t * data); + +extern fsl_shw_return_t fsl_shw_gen_encrypt(fsl_shw_uco_t * user_ctx, + fsl_shw_acco_t * auth_ctx, + fsl_shw_sko_t * cipher_key_info, + fsl_shw_sko_t * auth_key_info, + uint32_t auth_data_length, + const uint8_t * auth_data, + uint32_t payload_length, + const uint8_t * payload, + uint8_t * ct, uint8_t * auth_value); + +extern fsl_shw_return_t fsl_shw_auth_decrypt(fsl_shw_uco_t * user_ctx, + fsl_shw_acco_t * auth_ctx, + fsl_shw_sko_t * cipher_key_info, + fsl_shw_sko_t * auth_key_info, + uint32_t auth_data_length, + const uint8_t * auth_data, + uint32_t payload_length, + const uint8_t * ct, + const uint8_t * auth_value, + uint8_t * payload); + +extern fsl_shw_return_t fsl_shw_read_key(fsl_shw_uco_t * user_ctx, + fsl_shw_sko_t * key_info, + uint8_t * key); + +static inline fsl_shw_return_t fsl_shw_gen_random_pf_key(fsl_shw_uco_t * + user_ctx) +{ + (void)user_ctx; + + return FSL_RETURN_NO_RESOURCE_S; +} + +static inline fsl_shw_return_t fsl_shw_read_tamper_event(fsl_shw_uco_t * + user_ctx, + fsl_shw_tamper_t * + tamperp, + uint64_t * timestampp) +{ + (void)user_ctx; + (void)tamperp; + (void)timestampp; + + return FSL_RETURN_NO_RESOURCE_S; +} + +fsl_shw_return_t sah_Append_Desc(const sah_Mem_Util * mu, + sah_Head_Desc ** desc_head, + const uint32_t header, + sah_Link * link1, sah_Link * link2); + +/* Utility Function leftover from sahara1 API */ +void sah_Descriptor_Chain_Destroy(const sah_Mem_Util * mu, + sah_Head_Desc ** desc_chain); + +/* Utility Function leftover from sahara1 API */ +fsl_shw_return_t sah_Descriptor_Chain_Execute(sah_Head_Desc * desc_chain, + fsl_shw_uco_t * user_ctx); + +fsl_shw_return_t sah_Append_Link(const sah_Mem_Util * mu, + sah_Link * link, + uint8_t * p, + const size_t length, + const sah_Link_Flags flags); + +fsl_shw_return_t sah_Create_Link(const sah_Mem_Util * mu, + sah_Link ** link, + uint8_t * p, + const size_t length, + const sah_Link_Flags flags); + +fsl_shw_return_t sah_Create_Key_Link(const sah_Mem_Util * mu, + sah_Link ** link, + fsl_shw_sko_t * key_info); + +void sah_Destroy_Link(const sah_Mem_Util * mu, sah_Link * link); + +void sah_Postprocess_Results(fsl_shw_uco_t * user_ctx, + sah_results * result_info); + +#endif /* SAHARA2_API_H */ + --- linux-2.6.28.orig/drivers/mxc/security/sahara2/include/sah_status_manager.h +++ linux-2.6.28/drivers/mxc/security/sahara2/include/sah_status_manager.h @@ -0,0 +1,228 @@ +/* + * Copyright 2004-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 + */ + +/** +* @file sah_status_manager.h +* +* @brief SAHARA Status Manager Types and Function Prototypes +* +* @author Stuart Holloway (SH) +* +*/ + +#ifndef STATUS_MANAGER_H +#define STATUS_MANAGER_H +#include "sah_driver_common.h" +#include "sahara.h" + + +/****************************************************************************** +* User defined data types +******************************************************************************/ +/** +****************************************************************************** +* sah_Execute_Status +* Types read from SAHARA Status Register, with additional state for Op Status +******************************************************************************/ +typedef enum sah_Execute_Status +{ + /** Sahara is Idle. */ + SAH_EXEC_IDLE = 0, + /** SAHARA is busy performing a resest or processing a decriptor chain. */ + SAH_EXEC_BUSY = 1, + /** An error occurred while SAHARA executed the first descriptor. */ + SAH_EXEC_ERROR1 = 2, + /** SAHARA has failed internally. */ + SAH_EXEC_FAULT = 3, + /** SAHARA has finished processing a descriptor chain and is idle. */ + SAH_EXEC_DONE1 = 4, + /** SAHARA has finished processing a descriptor chain, and is processing a + * second chain. */ + SAH_EXEC_DONE1_BUSY2 = 5, + /** SAHARA has finished processing a descriptor chain, but has generated an + * error while processing a second descriptor chain. */ + SAH_EXEC_DONE1_ERROR2 = 6, + /** SAHARA has finished two descriptors. */ + SAH_EXEC_DONE1_DONE2 = 7, + /** SAHARA has stopped, and first descriptor has Op Status, not Err */ + SAH_EXEC_OPSTAT1 = 0x20, +} sah_Execute_Status; + +/** + * When this bit is on in a #sah_Execute_Status, it means that DONE1 is true. + */ +#define SAH_EXEC_DONE1_BIT 4 + +/** + * Bits which make up the Sahara State + */ +#define SAH_EXEC_STATE_MASK 0x00000007 + +/** +******************************************************************************* +* sah_Execute_Error +* Types read from SAHARA Error Status Register +******************************************************************************/ +typedef enum sah_Execute_Error +{ + /** No Error */ + SAH_ERR_NONE = 0, + /** Header is not valid. */ + SAH_ERR_HEADER = 1, + /** Descriptor length is not correct. */ + SAH_ERR_DESC_LENGTH = 2, + /** Length or pointer field is zero while the other is non-zero. */ + SAH_ERR_DESC_POINTER = 3, + /** Length of the link is not a multiple of 4 and is not the last link */ + SAH_ERR_LINK_LENGTH = 4, + /** The data pointer in a link is zero */ + SAH_ERR_LINK_POINTER = 5, + /** Input Buffer reported an overflow */ + SAH_ERR_INPUT_BUFFER = 6, + /** Output Buffer reported an underflow */ + SAH_ERR_OUTPUT_BUFFER = 7, + /** Incorrect data in output buffer after CHA's has signalled 'done'. */ + SAH_ERR_OUTPUT_BUFFER_STARVATION = 8, + /** Internal Hardware Failure. */ + SAH_ERR_INTERNAL_STATE = 9, + /** Current Descriptor was not legal, but cause is unknown. */ + SAH_ERR_GENERAL_DESCRIPTOR = 10, + /** Reserved pointer fields have been set to 1. */ + SAH_ERR_RESERVED_FIELDS = 11, + /** Descriptor address error */ + SAH_ERR_DESCRIPTOR_ADDRESS = 12, + /** Link address error */ + SAH_ERR_LINK_ADDRESS = 13, + /** Processing error in CHA module */ + SAH_ERR_CHA = 14, + /** Processing error during DMA */ + SAH_ERR_DMA = 15 +} sah_Execute_Error; + + +/** +******************************************************************************* +* sah_CHA_Error_Source +* Types read from SAHARA Error Status Register for CHA Error Source +* +******************************************************************************/ +typedef enum sah_CHA_Error_Source +{ + /** No Error indicated in Source CHA Error. */ + SAH_CHA_NO_ERROR = 0, + /** Error in SKHA module. */ + SAH_CHA_SKHA_ERROR = 1, + /** Error in MDHA module. */ + SAH_CHA_MDHA_ERROR = 2, + /** Error in RNG module. */ + SAH_CHA_RNG_ERROR = 3, + /** Error in PKHA module. */ + SAH_CHA_PKHA_ERROR = 4, +} sah_CHA_Error_Source; + +/** +****************************************************************************** +* sah_CHA_Error_Status +* Types read from SAHARA Error Status Register for CHA Error Status +* +******************************************************************************/ +typedef enum sah_CHA_Error_Status +{ + /** No CHA error detected */ + SAH_CHA_NO_ERR = 0x000, + /** Non-empty input buffer when complete. */ + SAH_CHA_IP_BUF = 0x001, + /** Illegal Address Error. */ + SAH_CHA_ADD_ERR = 0x002, + /** Illegal Mode Error. */ + SAH_CHA_MODE_ERR = 0x004, + /** Illegal Data Size Error. */ + SAH_CHA_DATA_SIZE_ERR = 0x008, + /** Illegal Key Size Error. */ + SAH_CHA_KEY_SIZE_ERR = 0x010, + /** Mode/Context/Key written during processing. */ + SAH_CHA_PROC_ERR = 0x020, + /** Context Read During Processing. */ + SAH_CHA_CTX_READ_ERR = 0x040, + /** Internal Hardware Error. */ + SAH_CHA_INTERNAL_HW_ERR = 0x080, + /** Input Buffer not enabled or underflow. */ + SAH_CHA_IP_BUFF_ERR = 0x100, + /** Output Buffer not enabled or overflow. */ + SAH_CHA_OP_BUFF_ERR = 0x200, + /** DES key parity error (SKHA) */ + SAH_CHA_DES_KEY_ERR = 0x400, + /** Reserved error code. */ + SAH_CHA_RES = 0x800 +} sah_CHA_Error_Status; + +/** +***************************************************************************** +* sah_DMA_Error_Status +* Types read from SAHARA Error Status Register for DMA Error Status +******************************************************************************/ +typedef enum sah_DMA_Error_Status +{ + /** No DMA Error Code. */ + SAH_DMA_NO_ERR = 0, + /** AHB terminated a bus cycle with an error. */ + SAH_DMA_AHB_ERR = 2, + /** Internal IP bus cycle was terminated with an error termination. */ + SAH_DMA_IP_ERR = 4, + /** Parity error detected on DMA command. */ + SAH_DMA_PARITY_ERR = 6, + /** DMA was requested to cross a 256 byte internal address boundary. */ + SAH_DMA_BOUNDRY_ERR = 8, + /** DMA controller is busy */ + SAH_DMA_BUSY_ERR = 10, + /** Memory Bounds Error */ + SAH_DMA_RESERVED_ERR = 12, + /** Internal DMA hardware error detected */ + SAH_DMA_INT_ERR = 14 +} sah_DMA_Error_Status; + +/** +***************************************************************************** +* sah_DMA_Error_Size +* Types read from SAHARA Error Status Register for DMA Error Size +* +******************************************************************************/ +typedef enum sah_DMA_Error_Size +{ + /** Error during Byte transfer. */ + SAH_DMA_SIZE_BYTE = 0, + /** Error during Half-word transfer. */ + SAH_DMA_SIZE_HALF_WORD = 1, + /** Error during Word transfer. */ + SAH_DMA_SIZE_WORD = 2, + /** Reserved DMA word size. */ + SAH_DMA_SIZE_RES = 3 +} sah_DMA_Error_Size; + + + + +extern bool sah_dpm_flag; + +/************************* +* Status Manager Functions +*************************/ + +unsigned long sah_Handle_Interrupt(sah_Execute_Status hw_status); +sah_Head_Desc *sah_Find_With_State (sah_Queue_Status status); +int sah_dpm_init(void); +void sah_dpm_close(void); +void sah_Queue_Manager_Prime (sah_Head_Desc *entry); + + +#endif /* STATUS_MANAGER_H */ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/include/sah_interrupt_handler.h +++ linux-2.6.28/drivers/mxc/security/sahara2/include/sah_interrupt_handler.h @@ -0,0 +1,42 @@ +/* + * Copyright 2004-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 + */ + +/** +* @file sah_interrupt_handler.h +* +* @brief Provides a hardware interrupt handling mechanism for device driver. +* +*/ +/****************************************************************************** +* +* CAUTION: +* +* MODIFICATION HISTORY: +* +* Date Person Change +* 30/07/03 MW Initial Creation +******************************************************************* +*/ + +#ifndef SAH_INTERRUPT_HANDLER_H +#define SAH_INTERRUPT_HANDLER_H + +#include + +/****************************************************************************** +* External function declarations +******************************************************************************/ +int sah_Intr_Init (wait_queue_head_t *wait_queue); +void sah_Intr_Release (void); + +#endif /* SAH_INTERRUPT_HANDLER_H */ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/include/sah_queue_manager.h +++ linux-2.6.28/drivers/mxc/security/sahara2/include/sah_queue_manager.h @@ -0,0 +1,63 @@ +/* + * Copyright 2004-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 + */ + +/** +* @file sah_queue_manager.h +* +* @brief This file definitions for the Queue Manager. + +* The Queue Manager manages additions and removal from the queue and updates +* the status of queue entries. It also calls sah_HW_* functions to interact +* with the hardware. +* +*/ + +#ifndef SAH_QUEUE_MANAGER_H +#define SAH_QUEUE_MANAGER_H + +#include +#include + + +/************************* +* Queue Manager Functions +*************************/ +fsl_shw_return_t sah_Queue_Manager_Init(void); +void sah_Queue_Manager_Close(void); +void sah_Queue_Manager_Reset_Entries(void); +void sah_Queue_Manager_Append_Entry(sah_Head_Desc *entry); +void sah_Queue_Manager_Remove_Entry(sah_Head_Desc *entry); + + +/************************* +* Queue Functions +*************************/ +sah_Queue *sah_Queue_Construct(void); +void sah_Queue_Destroy(sah_Queue *this); +void sah_Queue_Append_Entry(sah_Queue *this, sah_Head_Desc *entry); +void sah_Queue_Remove_Entry(sah_Queue *this); +void sah_Queue_Remove_Any_Entry(sah_Queue *this, sah_Head_Desc *entry); +void sah_postprocess_queue(unsigned long reset_flag); + + +/************************* +* Misc Releated Functions +*************************/ + +int sah_blocking_mode(struct sah_Head_Desc *entry); +fsl_shw_return_t sah_convert_error_status(uint32_t error_status); + + +#endif /* SAH_QUEUE_MANAGER_H */ + +/* End of sah_queue_manager.h */ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/include/fsl_platform.h +++ linux-2.6.28/drivers/mxc/security/sahara2/include/fsl_platform.h @@ -0,0 +1,161 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @file fsl_platform.h + * + * Header file to isolate code which might be platform-dependent + */ + +#ifndef FSL_PLATFORM_H +#define FSL_PLATFORM_H + +#ifdef __KERNEL__ +#include "portable_os.h" +#endif + +#if defined(FSL_PLATFORM_OTHER) + +/* Have Makefile or other method of setting FSL_HAVE_* flags */ + +#elif defined(CONFIG_ARCH_MX3) /* i.MX31 */ + +#define FSL_HAVE_SCC +#define FSL_HAVE_RTIC +#define FSL_HAVE_RNGA + +#elif defined(CONFIG_ARCH_MX21) + +#define FSL_HAVE_HAC +#define FSL_HAVE_RNGA +#define FSL_HAVE_SCC + +#elif defined(CONFIG_ARCH_MX25) + +#define FSL_HAVE_SCC +#define FSL_HAVE_RNGB +#define FSL_HAVE_RTIC3 +#define FSL_HAVE_DRYICE + +#elif defined(CONFIG_ARCH_MX27) + +#define FSL_HAVE_SAHARA2 +#define SUBMIT_MULTIPLE_DARS +#define FSL_HAVE_RTIC +#define FSL_HAVE_SCC +#define ALLOW_LLO_DESCRIPTORS + +#elif defined(CONFIG_ARCH_MX35) + +#define FSL_HAVE_SCC +#define FSL_HAVE_RNGC +#define FSL_HAVE_RTIC + +#elif defined(CONFIG_ARCH_MX37) + +#define FSL_HAVE_SCC2 +#define FSL_HAVE_RNGC +#define FSL_HAVE_RTIC2 +#define FSL_HAVE_SRTC + +#elif defined(CONFIG_ARCH_MX51) + +#define FSL_HAVE_SCC2 +#define FSL_HAVE_SAHARA4 +#define FSL_HAVE_RTIC3 +#define FSL_HAVE_SRTC +#define NO_RESEED_WORKAROUND +#define NEED_CTR_WORKAROUND +#define USE_S2_CCM_ENCRYPT_CHAIN +#define USE_S2_CCM_DECRYPT_CHAIN +#define ALLOW_LLO_DESCRIPTORS + +#elif defined(CONFIG_ARCH_MXC91131) + +#define FSL_HAVE_SCC +#define FSL_HAVE_RNGC +#define FSL_HAVE_HAC + +#elif defined(CONFIG_ARCH_MXC91221) + +#define FSL_HAVE_SCC +#define FSL_HAVE_RNGC +#define FSL_HAVE_RTIC2 + +#elif defined(CONFIG_ARCH_MXC91231) + +#define FSL_HAVE_SAHARA2 +#define FSL_HAVE_RTIC +#define FSL_HAVE_SCC +#define NO_OUTPUT_1K_CROSSING + +#elif defined(CONFIG_ARCH_MXC91311) + +#define FSL_HAVE_SCC +#define FSL_HAVE_RNGC + +#elif defined(CONFIG_ARCH_MXC91314) + +#define FSL_HAVE_SCC +#define FSL_HAVE_SAHAR4 +#define FSL_HAVE_RTIC3 +#define NO_RESEED_WORKAROUND +#define NEED_CTR_WORKAROUND +#define USE_S2_CCM_ENCRYPT_CHAIN +#define USE_S2_CCM_DECRYPT_CHAIN +#define ALLOW_LLO_DESCRIPTORS + +#elif defined(CONFIG_ARCH_MXC91321) + +#define FSL_HAVE_SAHARA2 +#define FSL_HAVE_RTIC +#define FSL_HAVE_SCC +#define SCC_CLOCK_NOT_GATED +#define NO_OUTPUT_1K_CROSSING + +#elif defined(CONFIG_ARCH_MXC92323) + +#define FSL_HAVE_SCC2 +#define FSL_HAVE_SAHARA4 +#define FSL_HAVE_PKHA +#define FSL_HAVE_RTIC2 +#define NO_1K_CROSSING +#define NO_RESEED_WORKAROUND +#define NEED_CTR_WORKAROUND +#define USE_S2_CCM_ENCRYPT_CHAIN +#define USE_S2_CCM_DECRYPT_CHAIN +#define ALLOW_LLO_DESCRIPTORS + + +#elif defined(CONFIG_ARCH_MXC91331) + +#define FSL_HAVE_SCC +#define FSL_HAVE_RNGA +#define FSL_HAVE_HAC +#define FSL_HAVE_RTIC + +#elif defined(CONFIG_8548) + +#define FSL_HAVE_SEC2x + +#elif defined(CONFIG_MPC8374) + +#define FSL_HAVE_SEC3x + +#else + +#error UNKNOWN_PLATFORM + +#endif /* platform checks */ + +#endif /* FSL_PLATFORM_H */ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/include/fsl_shw_keystore.h +++ linux-2.6.28/drivers/mxc/security/sahara2/include/fsl_shw_keystore.h @@ -0,0 +1,475 @@ +/* + * Copyright 2008-2009 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 FSL_SHW_KEYSTORE_H +#define FSL_SHW_KEYSTORE_H + +/*! + * @file fsl_shw_keystore.h + * + * @brief Definition of the User Keystore API. + * + */ + +/*! \page user_keystore User Keystore API + * + * Definition of the User Keystore API. + * + * On platforms with multiple partitions of Secure Memory, the Keystore Object + * (#fsl_shw_kso_t) is provided to allow users to manage a private keystore for + * use in software cryptographic routines. The user can define a custom set of + * methods for managing their keystore, or use a default keystore handler. The + * keystore is established by #fsl_shw_establish_keystore(), and released by + * #fsl_shw_release_keystore(). The intent of this design is to make the + * keystore implementation as flexible as possible. + * + * See @ref keystore_api for the generic keystore API, and @ref + * default_keystore for the default keystore implementation. + * + */ + +/*! + * @defgroup keystore_api User Keystore API + * + * Keystore API + * + * These functions define the generic keystore API, which can be used in + * conjunction with a keystore implementation backend to support a user + * keystore. + */ + +/*! + * @defgroup default_keystore Default Keystore Implementation + * + * Default Keystore Implementation + * + * These functions define the default keystore implementation, which is used + * for the system keystore and for user keystores initialized by + * #fsl_shw_init_keystore_default(). They can be used as-is or as a reference + * for creating a custom keystore handler. It uses an entire Secure Memory + * partition, divided in to equal slots of length #KEYSTORE_SLOT_SIZE. These + * functions are not intended to be used directly- all user interaction with + * the keystore should be through the @ref keystore_api and the Wrapped Key + * interface. + * + * The current implementation is designed to work with both SCC and SCC2. + * Differences between the two versions are noted below. + */ + +/*! @addtogroup keystore_api + @{ */ + +#ifndef KEYSTORE_SLOT_SIZE +/*! Size of each key slot, in octets. This sets an upper bound on the size + * of a key that can placed in the keystore. + */ +#define KEYSTORE_SLOT_SIZE 32 +#endif + +/*! + * Initialize a Keystore Object. + * + * This function must be called before performing any other operation with the + * Object. It allows the user to associate a custom keystore interface by + * specifying the correct set of functions that will be used to perform actions + * on the keystore object. To use the default keystore handler, the function + * #fsl_shw_init_keystore_default() can be used instead. + * + * @param keystore The Keystore object to operate on. + * @param data_init Keystore initialization function. This function is + * responsible for initializing the keystore. A + * user-defined object can be assigned to the user_data + * pointer, and will be passed to any function acting on + * that keystore. It is called during + * #fsl_shw_establish_keystore(). + * @param data_cleanup Keystore cleanup function. This function cleans up + * any data structures associated with the keyboard. It + * is called by #fsl_shw_release_keystore(). + * @param slot_alloc Slot allocation function. This function allocates a + * key slot, potentially based on size and owner id. It + * is called by #fsl_shw_establish_key(). + * @param slot_dealloc Slot deallocation function. + * @param slot_verify_access Function to verify that a given Owner ID + * credential matches the given slot. + * @param slot_get_address For SCC2: Get the virtual address (kernel or + * userspace) of the data stored in the slot. + * For SCC: Get the physical address of the data + * stored in the slot. + * @param slot_get_base For SCC2: Get the (virtual) base address of the + * partition that the slot is located on. + * For SCC: Not implemented. + * @param slot_get_offset For SCC2: Get the offset from the start of the + * partition that the slot data is located at (in + * octets) + * For SCC: Not implemented. + * @param slot_get_slot_size Get the size of the key slot, in octets. + */ +extern void fsl_shw_init_keystore(fsl_shw_kso_t * keystore, + fsl_shw_return_t(*data_init) (fsl_shw_uco_t * + user_ctx, + void + **user_data), + void (*data_cleanup) (fsl_shw_uco_t * + user_ctx, + void **user_data), + fsl_shw_return_t(*slot_alloc) (void + *user_data, + uint32_t size, + uint64_t + owner_id, + uint32_t * + slot), + fsl_shw_return_t(*slot_dealloc) (void + *user_data, + uint64_t + owner_id, + uint32_t + slot), + fsl_shw_return_t(*slot_verify_access) (void + *user_data, + uint64_t + owner_id, + uint32_t + slot), + void *(*slot_get_address) (void *user_data, + uint32_t handle), + uint32_t(*slot_get_base) (void *user_data, + uint32_t handle), + uint32_t(*slot_get_offset) (void *user_data, + uint32_t handle), + uint32_t(*slot_get_slot_size) (void + *user_data, + uint32_t + handle)); + +/*! + * Initialize a Keystore Object. + * + * This function must be called before performing any other operation with the + * Object. It sets the user keystore object up to use the default keystore + * handler. If a custom keystore handler is desired, the function + * #fsl_shw_init_keystore() can be used instead. + * + * @param keystore The Keystore object to operate on. + */ +extern void fsl_shw_init_keystore_default(fsl_shw_kso_t * keystore); + +/*! + * Establish a Keystore Object. + * + * This function establishes a keystore object that has been set up by a call + * to #fsl_shw_init_keystore(). It is a wrapper for the user-defined + * data_init() function, which is specified during keystore initialization. + * + * @param user_ctx The user context that this keystore should be attached + * to + * @param keystore The Keystore object to operate on. + * + * @return A return code of type #fsl_shw_return_t. + */ +extern fsl_shw_return_t fsl_shw_establish_keystore(fsl_shw_uco_t * user_ctx, + fsl_shw_kso_t * keystore); + +/*! + * Release a Keystore Object. + * + * This function releases an established keystore object. It is a wrapper for + * the user-defined data_cleanup() function, which is specified during keystore + * initialization. + * + * @param user_ctx The user context that this keystore should be attached + * to. + * @param keystore The Keystore object to operate on. + */ +extern void fsl_shw_release_keystore(fsl_shw_uco_t * user_ctx, + fsl_shw_kso_t * keystore); + +/*! + * Allocate a slot in the Keystore. + * + * This function attempts to allocate a slot to hold a key in the keystore. It + * is called by #fsl_shw_establish_key() when establishing a Secure Key Object, + * if the key has been flagged to be stored in a user keystore by the + * #fsl_shw_sko_set_keystore() function. It is a wrapper for the + * implementation-specific function slot_alloc(). + * + * @param keystore The Keystore object to operate on. + * @param[in] size Size of the key to be stored (octets). + * @param[in] owner_id ID of the key owner. + * @param[out] slot If successful, assigned slot ID + * + * @return A return code of type #fsl_shw_return_t. + */ +extern fsl_shw_return_t keystore_slot_alloc(fsl_shw_kso_t * keystore, + uint32_t size, + uint64_t owner_id, uint32_t * slot); + +/*! + * Deallocate a slot in the Keystore. + * + * This function attempts to allocate a slot to hold a key in the keystore. + * It is called by #fsl_shw_extract_key() and #fsl_shw_release_key() when the + * key that it contains is to be released. It is a wrapper for the + * implmentation-specific function slot_dealloc(). + + * @param keystore The Keystore object to operate on. + * @param[in] owner_id ID of the key owner. + * @param[in] slot If successful, assigned slot ID. + * + * @return A return code of type #fsl_shw_return_t. + */ +extern fsl_shw_return_t keystore_slot_dealloc(fsl_shw_kso_t * keystore, + uint64_t owner_id, uint32_t slot); + +/*! + * Load cleartext key data into a key slot + * + * This function loads a key slot with cleartext data. + * + * @param keystore The Keystore object to operate on. + * @param[in] owner_id ID of the key owner. + * @param[in] slot If successful, assigned slot ID. + * @param[in] key_data Pointer to the location of the cleartext key data. + * @param[in] key_length Length of the key data (octets). + * + * @return A return code of type #fsl_shw_return_t. + */ +extern fsl_shw_return_t +keystore_slot_load(fsl_shw_kso_t * keystore, uint64_t owner_id, uint32_t slot, + const uint8_t * key_data, uint32_t key_length); + +/*! + * Read cleartext key data from a key slot + * + * This function returns the key in a key slot. + * + * @param keystore The Keystore object to operate on. + * @param[in] owner_id ID of the key owner. + * @param[in] slot ID of slot where key resides. + * @param[in] key_length Length of the key data (octets). + * @param[out] key_data Pointer to the location of the cleartext key data. + * + * @return A return code of type #fsl_shw_return_t. + */ +extern fsl_shw_return_t +keystore_slot_read(fsl_shw_kso_t * keystore, uint64_t owner_id, uint32_t slot, + uint32_t key_length, uint8_t * key_data); + +/*! + * Encrypt a keyslot + * + * This function encrypts a key using the hardware secret key. + * + * @param user_ctx User context + * @param keystore The Keystore object to operate on. + * @param[in] owner_id ID of the key owner. + * @param[in] slot Slot ID of the key to encrypt. + * @param[in] length Length of the key + * @param[out] destination Pointer to the location where the encrypted data + * is to be stored. + * + * @return A return code of type #fsl_shw_return_t. + */ +extern fsl_shw_return_t +keystore_slot_encrypt(fsl_shw_uco_t * user_ctx, + fsl_shw_kso_t * keystore, uint64_t owner_id, + uint32_t slot, uint32_t length, uint8_t * destination); + +/*! + * Decrypt a keyslot + * + * This function decrypts a key using the hardware secret key. + * + * @param user_ctx User context + * @param keystore The Keystore object to operate on. + * @param[in] owner_id ID of the key owner. + * @param[in] slot Slot ID of the key to encrypt. + * @param[in] length Length of the key + * @param[in] source Pointer to the location where the encrypted data + * is stored. + * + * @return A return code of type #fsl_shw_return_t. + */ +extern fsl_shw_return_t +keystore_slot_decrypt(fsl_shw_uco_t * user_ctx, + fsl_shw_kso_t * keystore, uint64_t owner_id, + uint32_t slot, uint32_t length, const uint8_t * source); + +/* @} */ + +/*! @addtogroup default_keystore + @{ */ + +/*! + * Data structure to hold per-slot information + */ +typedef struct keystore_data_slot_info_t { + uint8_t allocated; /*!< Track slot assignments */ + uint64_t owner; /*!< Owner IDs */ + uint32_t key_length; /*!< Size of the key */ +} keystore_data_slot_info_t; + +/*! + * Data structure to hold keystore information. + */ +typedef struct keystore_data_t { + void *base_address; /*!< Base of the Secure Partition */ + uint32_t slot_count; /*!< Number of slots in the keystore */ + struct keystore_data_slot_info_t *slot; /*!< Per-slot information */ +} keystore_data_t; + +/*! + * Default keystore initialization routine. + * + * This function acquires a Secure Partition Object to store the keystore, + * divides it into slots of length #KEYSTORE_SLOT_SIZE, and builds a data + * structure to hold key information. + * + * @param user_ctx User context + * @param[out] user_data Pointer to the location where the keystore data + * structure is to be stored. + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t shw_kso_init_data(fsl_shw_uco_t * user_ctx, void **user_data); + +/*! + * Default keystore cleanup routine. + * + * This function releases the Secure Partition Object and the memory holding + * the keystore data structure, that obtained by the shw_kso_init_data + * function. + * + * @param user_ctx User context + * @param[in,out] user_data Pointer to the location where the keystore data + * structure is stored. + */ +void shw_kso_cleanup_data(fsl_shw_uco_t * user_ctx, void **user_data); + +/*! + * Default keystore slot access verification + * + * This function compares the supplied Owner ID to the registered owner of + * the key slot, to see if the supplied ID is correct. + * + * @param[in] user_data Pointer to the location where the keystore data + * structure stored. + * @param[in] owner_id Owner ID supplied as a credential. + * @param[in] slot Requested slot + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t shw_slot_verify_access(void *user_data, uint64_t owner_id, + uint32_t slot); + +/*! + * Default keystore slot allocation + * + * This function first checks that the requested size is equal to or less than + * the maximum keystore slot size. If so, it searches the keystore for a free + * key slot, and if found, marks it as used and returns a slot reference to the + * user. + * + * @param[in] user_data Pointer to the location where the keystore data + * structure stored. + * @param[in] size Size of the key data that will be stored in this slot + * (octets) + * @param[in] owner_id Owner ID supplied as a credential. + * @param[out] slot Requested slot + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t shw_slot_alloc(void *user_data, uint32_t size, + uint64_t owner_id, uint32_t * slot); + +/*! + * Default keystore slot deallocation + * + * This function releases the given key slot in the keystore, making it + * available to store a new key. + * + * @param[in] user_data Pointer to the location where the keystore data + * structure stored. + * @param[in] owner_id Owner ID supplied as a credential. + * @param[in] slot Requested slot + * + * @return A return code of type #fsl_shw_return_t. + */ +fsl_shw_return_t shw_slot_dealloc(void *user_data, + uint64_t owner_id, uint32_t slot); + +/*! + * Default keystore slot address lookup + * + * This function calculates the address where the key data is stored. + * + * @param[in] user_data Pointer to the location where the keystore data + * structure stored. + * @param[in] slot Requested slot + * + * @return SCC2: Virtual address (kernel or userspace) of the key data. + * SCC: Physical address of the key data. + */ +void *shw_slot_get_address(void *user_data, uint32_t slot); + +/*! + * Default keystore slot base address lookup + * + * This function calculates the base address of the Secure Partition on which + * the key data is located. For the reference design, only one Secure + * Partition is used per Keystore, however in general, any number may be used. + * + * @param[in] user_data Pointer to the location where the keystore data + * structure stored. + * @param[in] slot Requested slot + * + * @return SCC2: Secure Partition virtual (kernel or userspace) base address. + * SCC: Secure Partition physical base address. + */ +uint32_t shw_slot_get_base(void *user_data, uint32_t slot); + +/*! + * Default keystore slot offset lookup + * + * This function calculates the offset from the base of the Secure Partition + * where the key data is located. + * + * @param[in] user_data Pointer to the location where the keystore data + * structure stored. + * @param[in] slot Requested slot + * + * @return SCC2: Key data offset (octets) + * SCC: Not implemented + */ +uint32_t shw_slot_get_offset(void *user_data, uint32_t slot); + +/*! + * Default keystore slot offset lookup + * + * This function returns the size of the given key slot. In the reference + * implementation, all key slots are of the same size, however in general, + * the keystore slot sizes can be made variable. + * + * @param[in] user_data Pointer to the location where the keystore data + * structure stored. + * @param[in] slot Requested slot + * + * @return SCC2: Keystore slot size. + * SCC: Not implemented + */ +uint32_t shw_slot_get_slot_size(void *user_data, uint32_t slot); + +/* @} */ + +#endif /* FSL_SHW_KEYSTORE_H */ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/include/sah_memory_mapper.h +++ linux-2.6.28/drivers/mxc/security/sahara2/include/sah_memory_mapper.h @@ -0,0 +1,79 @@ +/* + * Copyright 2004-2008 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 + */ + +/** +* @file sah_memory_mapper.h +* +* @brief Re-creates SAHARA data structures in Kernel memory such that they are +* suitable for DMA. +* +*/ + +#ifndef SAH_MEMORY_MAPPER_H +#define SAH_MEMORY_MAPPER_H + +#include +#include + + +/****************************************************************************** +* External function declarations +******************************************************************************/ +sah_Head_Desc *sah_Copy_Descriptors(fsl_shw_uco_t * user_ctx, + sah_Head_Desc * desc); + +sah_Link *sah_Copy_Links(fsl_shw_uco_t * user_ctx, sah_Link * ptr); + +sah_Head_Desc *sah_Physicalise_Descriptors(sah_Head_Desc * desc); + +sah_Link *sah_Physicalise_Links (sah_Link *ptr); + +sah_Head_Desc *sah_DePhysicalise_Descriptors (sah_Head_Desc *desc); + +sah_Link *sah_DePhysicalise_Links (sah_Link *ptr); + +sah_Link *sah_Make_Links(fsl_shw_uco_t * user_ctx, + sah_Link * ptr, sah_Link ** tail); + + +void sah_Destroy_Descriptors (sah_Head_Desc *desc); + +void sah_Destroy_Links (sah_Link *link); + +void sah_Free_Chained_Descriptors (sah_Head_Desc *desc); + +void sah_Free_Chained_Links (sah_Link *link); + +int sah_Init_Mem_Map (void); + +void sah_Stop_Mem_Map (void); + +int sah_Block_Add_Page (int big); + +sah_Desc *sah_Alloc_Descriptor (void); +sah_Head_Desc *sah_Alloc_Head_Descriptor (void); +void sah_Free_Descriptor (sah_Desc *desc); +void sah_Free_Head_Descriptor (sah_Head_Desc *desc); +sah_Link *sah_Alloc_Link (void); +void sah_Free_Link (sah_Link *link); + +void *wire_user_memory(void *address, uint32_t length, void **page_ctx); +void unwire_user_memory(void **page_ctx); + +os_error_code map_user_memory(struct vm_area_struct *vma, + uint32_t physical_addr, uint32_t size); +os_error_code unmap_user_memory(uint32_t user_addr, uint32_t size); + +#endif /* SAH_MEMORY_MAPPER_H */ + +/* End of sah_memory_mapper.h */ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/include/sf_util.h +++ linux-2.6.28/drivers/mxc/security/sahara2/include/sf_util.h @@ -0,0 +1,466 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! +* @file sf_util.h +* +* @brief Header for Sahara Descriptor-chain building Functions +*/ +#ifndef SF_UTIL_H +#define SF_UTIL_H + +#include +#include + +/*! Header value for Sahara Descriptor 1 */ +#define SAH_HDR_SKHA_SET_MODE_IV_KEY 0x10880000 +/*! Header value for Sahara Descriptor 2 */ +#define SAH_HDR_SKHA_SET_MODE_ENC_DEC 0x108D0000 +/*! Header value for Sahara Descriptor 4 */ +#define SAH_HDR_SKHA_ENC_DEC 0x90850000 +/*! Header value for Sahara Descriptor 5 */ +#define SAH_HDR_SKHA_READ_CONTEXT_IV 0x10820000 +/*! Header value for Sahara Descriptor 6 */ +#define SAH_HDR_MDHA_SET_MODE_MD_KEY 0x20880000 +/*! Header value for Sahara Descriptor 8 */ +#define SAH_HDR_MDHA_SET_MODE_HASH 0x208D0000 +/*! Header value for Sahara Descriptor 10 */ +#define SAH_HDR_MDHA_HASH 0xA0850000 +/*! Header value for Sahara Descriptor 11 */ +#define SAH_HDR_MDHA_STORE_DIGEST 0x20820000 +/*! Header value for Sahara Descriptor 18 */ +#define SAH_HDR_RNG_GENERATE 0x308C0000 +/*! Header value for Sahara Descriptor 19 */ +#define SAH_HDR_PKHA_LD_N_E 0xC0800000 +/*! Header value for Sahara Descriptor 20 */ +#define SAH_HDR_PKHA_LD_A_EX_ST_B 0x408D0000 +/*! Header value for Sahara Descriptor 21 */ +#define SAH_HDR_PKHA_LD_N_EX_ST_B 0x408E0000 +/*! Header value for Sahara Descriptor 22 */ +#define SAH_HDR_PKHA_LD_A_B 0xC0830000 +/*! Header value for Sahara Descriptor 23 */ +#define SAH_HDR_PKHA_LD_A0_A1 0x40840000 +/*! Header value for Sahara Descriptor 24 */ +#define SAH_HDR_PKHA_LD_A2_A3 0xC0850000 +/*! Header value for Sahara Descriptor 25 */ +#define SAH_HDR_PKHA_LD_B0_B1 0xC0860000 +/*! Header value for Sahara Descriptor 26 */ +#define SAH_HDR_PKHA_LD_B2_B3 0x40870000 +/*! Header value for Sahara Descriptor 27 */ +#define SAH_HDR_PKHA_ST_A_B 0x40820000 +/*! Header value for Sahara Descriptor 28 */ +#define SAH_HDR_PKHA_ST_A0_A1 0x40880000 +/*! Header value for Sahara Descriptor 29 */ +#define SAH_HDR_PKHA_ST_A2_A3 0xC0890000 +/*! Header value for Sahara Descriptor 30 */ +#define SAH_HDR_PKHA_ST_B0_B1 0xC08A0000 +/*! Header value for Sahara Descriptor 31 */ +#define SAH_HDR_PKHA_ST_B2_B3 0x408B0000 +/*! Header value for Sahara Descriptor 32 */ +#define SAH_HDR_PKHA_EX_ST_B1 0xC08C0000 +/*! Header value for Sahara Descriptor 33 */ +#define SAH_HDR_ARC4_SET_MODE_SBOX 0x90890000 +/*! Header value for Sahara Descriptor 34 */ +#define SAH_HDR_ARC4_READ_SBOX 0x90860000 +/*! Header value for Sahara Descriptor 35 */ +#define SAH_HDR_ARC4_SET_MODE_KEY 0x90830000 +/*! Header value for Sahara Descriptor 36 */ +#define SAH_HDR_PKHA_LD_A3_B0 0x40810000 +/*! Header value for Sahara Descriptor 37 */ +#define SAH_HDR_PKHA_ST_B1_B2 0xC08F0000 +/*! Header value for Sahara Descriptor 38 */ +#define SAH_HDR_SKHA_CBC_ICV 0x10840000 +/*! Header value for Sahara Descriptor 39 */ +#define SAH_HDR_MDHA_ICV_CHECK 0xA08A0000 + +/*! Header bit indicating "Link-List optimization" */ +#define SAH_HDR_LLO 0x01000000 + +#define SAH_SF_DCLS \ + fsl_shw_return_t ret; \ + unsigned sf_executed = 0; \ + sah_Head_Desc* desc_chain = NULL; \ + uint32_t header + +#define SAH_SF_USER_CHECK() \ +do { \ + ret = sah_validate_uco(user_ctx); \ + if (ret != FSL_RETURN_OK_S) { \ + goto out; \ + } \ +} while (0) + +#define SAH_SF_EXECUTE() \ +do { \ + sf_executed = 1; \ + ret = sah_Descriptor_Chain_Execute(desc_chain, user_ctx); \ +} while (0) + +#define SAH_SF_DESC_CLEAN() \ +do { \ + if (!sf_executed || (user_ctx->flags & FSL_UCO_BLOCKING_MODE)) { \ + sah_Descriptor_Chain_Destroy(user_ctx->mem_util, &desc_chain); \ + } \ + (void) header; \ +} while (0) + +/*! Add Descriptor with two inputs */ +#define DESC_IN_IN(hdr, len1, ptr1, len2, ptr2) \ +{ \ + ret = sah_add_two_in_desc(hdr, ptr1, len1, ptr2, len2, \ + user_ctx->mem_util, &desc_chain); \ + if (ret != FSL_RETURN_OK_S) { \ + goto out; \ + } \ +} + +/*! Add Descriptor with two vectors */ +#define DESC_D_D(hdr, len1, ptr1, len2, ptr2) \ +{ \ + ret = sah_add_two_d_desc(hdr, ptr1, len1, ptr2, len2, \ + user_ctx->mem_util, &desc_chain); \ + if (ret != FSL_RETURN_OK_S) { \ + goto out; \ + } \ +} + +/*! Add Descriptor with input and a key */ +#define DESC_IN_KEY(hdr, len1, ptr1, key2) \ +{ \ + ret = sah_add_in_key_desc(hdr, ptr1, len1, key2, \ + user_ctx->mem_util, &desc_chain); \ + if (ret != FSL_RETURN_OK_S) { \ + goto out; \ + } \ +} + +/*! Add Descriptor with input and an output */ +#define DESC_IN_OUT(hdr, len1, ptr1, len2, ptr2) \ +{ \ + ret = sah_add_in_out_desc(hdr, ptr1, len1, ptr2, len2, \ + user_ctx->mem_util, &desc_chain); \ + if (ret != FSL_RETURN_OK_S) { \ + goto out; \ + } \ +} + +/*! Add Descriptor with input and a key output */ +#define DESC_IN_KEYOUT(hdr, len1, ptr1, key2) \ +{ \ + ret = sah_add_in_keyout_desc(hdr, ptr1, len1, key2, \ + user_ctx->mem_util, &desc_chain); \ + if (ret != FSL_RETURN_OK_S) { \ + goto out; \ + } \ +} + +/*! Add Descriptor with a key and an output */ +#define DESC_KEY_OUT(hdr, key1, len2, ptr2) \ +{ \ + ret = sah_add_key_out_desc(hdr, key1, ptr2, len2, \ + user_ctx->mem_util, &desc_chain); \ + if (ret != FSL_RETURN_OK_S) { \ + goto out; \ + } \ +} + +/*! Add Descriptor with two outputs */ +#define DESC_OUT_OUT(hdr, len1, ptr1, len2, ptr2) \ +{ \ + ret = sah_add_two_out_desc(hdr, ptr1, len1, ptr2, len2, \ + user_ctx->mem_util, &desc_chain); \ + if (ret != FSL_RETURN_OK_S) { \ + goto out; \ + } \ +} + +/*! Add Descriptor with output then input pointers */ +#define DESC_OUT_IN(hdr, len1, ptr1, len2, ptr2) \ +{ \ + ret = sah_add_out_in_desc(hdr, ptr1, len1, ptr2, len2, \ + user_ctx->mem_util, &desc_chain); \ + if (ret != FSL_RETURN_OK_S) { \ + goto out; \ + } \ +} + +#ifdef SAH_SF_DEBUG +/*! Add Descriptor with two outputs */ +#define DBG_DESC(hdr, len1, ptr1, len2, ptr2) \ +{ \ + ret = sah_add_two_out_desc(hdr, ptr1, len1, ptr2, len2, \ + user_ctx->mem_util, &desc_chain); \ + if (ret != FSL_RETURN_OK_S) { \ + goto out; \ + } \ +} +#else +#define DBG_DESC(hdr, len1, ptr1, len2, ptr2) +#endif + +#ifdef __KERNEL__ +#define DESC_DBG_ON ({console_loglevel = 8;}) +#define DESC_DBG_OFF ({console_loglevel = 7;}) +#else +#define DESC_DBG_ON system("echo 8 > /proc/sys/kernel/printk") +#define DESC_DBG_OFF system("echo 7 > /proc/sys/kernel/printk") +#endif + +#define DESC_TEMP_ALLOC(size) \ +({ \ + uint8_t* ptr; \ + ptr = user_ctx->mem_util->mu_malloc(user_ctx->mem_util->mu_ref, \ + size); \ + if (ptr == NULL) { \ + ret = FSL_RETURN_NO_RESOURCE_S; \ + goto out; \ + } \ + \ + ptr; \ +}) + +#define DESC_TEMP_FREE(ptr) \ +({ \ + if ((ptr != NULL) && \ + (!sf_executed || (user_ctx->flags & FSL_UCO_BLOCKING_MODE))) { \ + user_ctx->mem_util-> \ + mu_free(user_ctx->mem_util->mu_ref, ptr); \ + ptr = NULL; \ + } \ +}) + +/* Temporary implementation. This needs to be in internal/secure RAM */ +#define DESC_TEMP_SECURE_ALLOC(size) \ +({ \ + uint8_t* ptr; \ + ptr = user_ctx->mem_util->mu_malloc(user_ctx->mem_util->mu_ref, \ + size); \ + if (ptr == NULL) { \ + ret = FSL_RETURN_NO_RESOURCE_S; \ + goto out; \ + } \ + \ + ptr; \ +}) + +#define DESC_TEMP_SECURE_FREE(ptr, size) \ +({ \ + if ((ptr != NULL) && \ + (!sf_executed || (user_ctx->flags & FSL_UCO_BLOCKING_MODE))) { \ + user_ctx->mem_util->mu_memset(user_ctx->mem_util->mu_ref, \ + ptr, 0, size); \ + \ + user_ctx->mem_util-> \ + mu_free(user_ctx->mem_util->mu_ref, ptr); \ + ptr = NULL; \ + } \ +}) + +extern const uint32_t sah_insert_mdha_algorithm[]; + +/*! @defgroup mdhaflags MDHA Mode Register Values + * + * These are bit fields and combinations of bit fields for setting the Mode + * Register portion of a Sahara Descriptor Header field. + * + * The parity bit has been set to ensure that these values have even parity, + * therefore using an Exclusive-OR operation against an existing header will + * preserve its parity. + * + * @addtogroup mdhaflags + @{ + */ +#define sah_insert_mdha_icv_check 0x80001000 +#define sah_insert_mdha_ssl 0x80000400 +#define sah_insert_mdha_mac_full 0x80000200 +#define sah_insert_mdha_opad 0x80000080 +#define sah_insert_mdha_ipad 0x80000040 +#define sah_insert_mdha_init 0x80000020 +#define sah_insert_mdha_hmac 0x80000008 +#define sah_insert_mdha_pdata 0x80000004 +#define sah_insert_mdha_algorithm_sha224 0x00000003 +#define sah_insert_mdha_algorithm_sha256 0x80000002 +#define sah_insert_mdha_algorithm_md5 0x80000001 +#define sah_insert_mdha_algorithm_sha1 0x00000000 +/*! @} */ + +extern const uint32_t sah_insert_skha_algorithm[]; +extern const uint32_t sah_insert_skha_mode[]; +extern const uint32_t sah_insert_skha_modulus[]; + +/*! @defgroup skhaflags SKHA Mode Register Values + * + * These are bit fields and combinations of bit fields for setting the Mode + * Register portion of a Sahara Descriptor Header field. + * + * The parity bit has been set to ensure that these values have even parity, + * therefore using an Exclusive-OR operation against an existing header will + * preserve its parity. + * + * @addtogroup skhaflags + @{ + */ +/*! */ +#define sah_insert_skha_modulus_128 0x00001e00 +#define sah_insert_skha_no_key_parity 0x80000100 +#define sah_insert_skha_ctr_last_block 0x80000020 +#define sah_insert_skha_suppress_cbc 0x80000020 +#define sah_insert_skha_no_permute 0x80000020 +#define sah_insert_skha_algorithm_arc4 0x00000003 +#define sah_insert_skha_algorithm_tdes 0x80000002 +#define sah_insert_skha_algorithm_des 0x80000001 +#define sah_insert_skha_algorithm_aes 0x00000000 +#define sah_insert_skha_aux0 0x80000020 +#define sah_insert_skha_mode_ctr 0x00000018 +#define sah_insert_skha_mode_ccm 0x80000010 +#define sah_insert_skha_mode_cbc 0x80000008 +#define sah_insert_skha_mode_ecb 0x00000000 +#define sah_insert_skha_encrypt 0x80000004 +#define sah_insert_skha_decrypt 0x00000000 +/*! @} */ + +/*! @defgroup rngflags RNG Mode Register Values + * + */ +/*! */ +#define sah_insert_rng_gen_seed 0x80000001 + +/*! @} */ + +/*! @defgroup pkhaflags PKHA Mode Register Values + * + */ +/*! */ +#define sah_insert_pkha_soft_err_false 0x80000200 +#define sah_insert_pkha_soft_err_true 0x80000100 + +#define sah_insert_pkha_rtn_clr_mem 0x80000001 +#define sah_insert_pkha_rtn_clr_eram 0x80000002 +#define sah_insert_pkha_rtn_mod_exp 0x00000003 +#define sah_insert_pkha_rtn_mod_r2modn 0x80000004 +#define sah_insert_pkha_rtn_mod_rrmodp 0x00000005 +#define sah_insert_pkha_rtn_ec_fp_aff_ptmul 0x00000006 +#define sah_insert_pkha_rtn_ec_f2m_aff_ptmul 0x80000007 +#define sah_insert_pkha_rtn_ec_fp_proj_ptmul 0x80000008 +#define sah_insert_pkha_rtn_ec_f2m_proj_ptmul 0x00000009 +#define sah_insert_pkha_rtn_ec_fp_add 0x0000000A +#define sah_insert_pkha_rtn_ec_fp_double 0x8000000B +#define sah_insert_pkha_rtn_ec_f2m_add 0x0000000C +#define sah_insert_pkha_rtn_ec_f2m_double 0x8000000D +#define sah_insert_pkha_rtn_f2m_r2modn 0x8000000E +#define sah_insert_pkha_rtn_f2m_inv 0x0000000F +#define sah_insert_pkha_rtn_mod_inv 0x80000010 +#define sah_insert_pkha_rtn_rsa_sstep 0x00000011 +#define sah_insert_pkha_rtn_mod_emodn 0x00000012 +#define sah_insert_pkha_rtn_f2m_emodn 0x80000013 +#define sah_insert_pkha_rtn_ec_fp_ptmul 0x00000014 +#define sah_insert_pkha_rtn_ec_f2m_ptmul 0x80000015 +#define sah_insert_pkha_rtn_f2m_gcd 0x80000016 +#define sah_insert_pkha_rtn_mod_gcd 0x00000017 +#define sah_insert_pkha_rtn_f2m_dbl_aff 0x00000018 +#define sah_insert_pkha_rtn_fp_dbl_aff 0x80000019 +#define sah_insert_pkha_rtn_f2m_add_aff 0x8000001A +#define sah_insert_pkha_rtn_fp_add_aff 0x0000001B +#define sah_insert_pkha_rtn_f2m_exp 0x8000001C +#define sah_insert_pkha_rtn_mod_exp_teq 0x0000001D +#define sah_insert_pkha_rtn_rsa_sstep_teq 0x0000001E +#define sah_insert_pkha_rtn_f2m_multn 0x8000001F +#define sah_insert_pkha_rtn_mod_multn 0x80000020 +#define sah_insert_pkha_rtn_mod_add 0x00000021 +#define sah_insert_pkha_rtn_mod_sub 0x00000022 +#define sah_insert_pkha_rtn_mod_mult1_mont 0x80000023 +#define sah_insert_pkha_rtn_mod_mult2_deconv 0x00000024 +#define sah_insert_pkha_rtn_f2m_add 0x80000025 +#define sah_insert_pkha_rtn_f2m_mult1_mont 0x80000026 +#define sah_insert_pkha_rtn_f2m_mult2_deconv 0x00000027 +#define sah_insert_pkha_rtn_miller_rabin 0x00000028 +#define sah_insert_pkha_rtn_mod_amodn 0x00000029 +#define sah_insert_pkha_rtn_f2m_amodn 0x8000002A +/*! @} */ + +/*! Add a descriptor with two input pointers */ +fsl_shw_return_t sah_add_two_in_desc(uint32_t header, + const uint8_t * in1, + uint32_t in1_length, + const uint8_t * in2, + uint32_t in2_length, + const sah_Mem_Util * mu, + sah_Head_Desc ** desc_chain); + +/*! Add a descriptor with two 'data' pointers */ +fsl_shw_return_t sah_add_two_d_desc(uint32_t header, + const uint8_t * in1, + uint32_t in1_length, + const uint8_t * in2, + uint32_t in2_length, + const sah_Mem_Util * mu, + sah_Head_Desc ** desc_chain); + +/*! Add a descriptor with an input and key pointer */ +fsl_shw_return_t sah_add_in_key_desc(uint32_t header, + const uint8_t * in1, + uint32_t in1_length, + fsl_shw_sko_t * key_info, + const sah_Mem_Util * mu, + sah_Head_Desc ** desc_chain); + +/*! Add a descriptor with two key pointers */ +fsl_shw_return_t sah_add_key_key_desc(uint32_t header, + fsl_shw_sko_t * key_info1, + fsl_shw_sko_t * key_info2, + const sah_Mem_Util * mu, + sah_Head_Desc ** desc_chain); + +/*! Add a descriptor with two output pointers */ +fsl_shw_return_t sah_add_two_out_desc(uint32_t header, + uint8_t * out1, + uint32_t out1_length, + uint8_t * out2, + uint32_t out2_length, + const sah_Mem_Util * mu, + sah_Head_Desc ** desc_chain); + +/*! Add a descriptor with an input and output pointer */ +fsl_shw_return_t sah_add_in_out_desc(uint32_t header, + const uint8_t * in, uint32_t in_length, + uint8_t * out, uint32_t out_length, + const sah_Mem_Util * mu, + sah_Head_Desc ** desc_chain); + +/*! Add a descriptor with an input and key output pointer */ +fsl_shw_return_t sah_add_in_keyout_desc(uint32_t header, + const uint8_t * in, uint32_t in_length, + fsl_shw_sko_t * key_info, + const sah_Mem_Util * mu, + sah_Head_Desc ** desc_chain); + +/*! Add a descriptor with a key and an output pointer */ +fsl_shw_return_t sah_add_key_out_desc(uint32_t header, + const fsl_shw_sko_t * key_info, + uint8_t * out, uint32_t out_length, + const sah_Mem_Util * mu, + sah_Head_Desc ** desc_chain); + +/*! Add a descriptor with an output and input pointer */ +fsl_shw_return_t sah_add_out_in_desc(uint32_t header, + uint8_t * out, uint32_t out_length, + const uint8_t * in, uint32_t in_length, + const sah_Mem_Util * mu, + sah_Head_Desc ** desc_chain); + +/*! Verify that supplied User Context Object is valid */ +fsl_shw_return_t sah_validate_uco(fsl_shw_uco_t * uco); + +#endif /* SF_UTIL_H */ + +/* End of sf_util.h */ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/include/sah_driver_common.h +++ linux-2.6.28/drivers/mxc/security/sahara2/include/sah_driver_common.h @@ -0,0 +1,102 @@ +/* + * Copyright 2004-2008 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 + */ + +/** +* @file sah_driver_common.h +* +* @brief Provides types and defined values for use in the Driver Interface. +* +*/ + +#ifndef SAH_DRIVER_COMMON_H +#define SAH_DRIVER_COMMON_H + +#include "fsl_platform.h" +#include +#include + +/** This specifies the permissions for the device file. It is equivalent to + * chmod 666. + */ +#define SAHARA_DEVICE_MODE S_IFCHR | S_IRUGO | S_IWUGO + +/** +* The status of entries in the Queue. +* +******************************************************************************/ +typedef enum +{ + /** This state indicates that the entry is in the queue and awaits + * execution on SAHARA. */ + SAH_STATE_PENDING, + /** This state indicates that the entry has been written to the SAHARA + * DAR. */ + SAH_STATE_ON_SAHARA, + /** This state indicates that the entry is off of SAHARA, and is awaiting + post-processing. */ + SAH_STATE_OFF_SAHARA, + /** This state indicates that the entry is successfully executed on SAHARA, + and it is finished with post-processing. */ + SAH_STATE_COMPLETE, + /** This state indicates that the entry caused an error or fault on SAHARA, + * and it is finished with post-processing. */ + SAH_STATE_FAILED, + /** This state indicates that the entry was reset via the Reset IO + * Control, and it is finished with post-processing. */ + SAH_STATE_RESET, + /** This state indicates that the entry was signalled from user-space and + * either in the DAR, IDAR or has finished executing pending Bottom Half + * processing. */ + SAH_STATE_IGNORE, + /** This state indicates that the entry was signalled from user-space and + * has been processed by the bottom half. */ + SAH_STATE_IGNORED +} sah_Queue_Status; + +/* any of these conditions being true indicates the descriptor's processing + * is complete */ +#define SAH_DESC_PROCESSED(status) \ + (((status) == SAH_STATE_COMPLETE) || \ + ((status) == SAH_STATE_FAILED ) || \ + ((status) == SAH_STATE_RESET )) + +extern os_lock_t desc_queue_lock; + +extern uint32_t dar_count; +extern uint32_t interrupt_count; +extern uint32_t done1done2_count; +extern uint32_t done1busy2_count; +extern uint32_t done1_count; + +#ifdef FSL_HAVE_SCC2 +extern void *lookup_user_partition(fsl_shw_uco_t * user_ctx, + uint32_t user_base); +#endif + +int sah_get_results_pointers(fsl_shw_uco_t* user_ctx, uint32_t arg); +fsl_shw_return_t sah_get_results_from_pool(volatile fsl_shw_uco_t* user_ctx, + sah_results *arg); +fsl_shw_return_t sah_handle_registration(fsl_shw_uco_t *user_cts); +fsl_shw_return_t sah_handle_deregistration(fsl_shw_uco_t *user_cts); + +int sah_Queue_Manager_Count_Entries(int ignore_state, sah_Queue_Status state); +unsigned long sah_Handle_Poll(sah_Head_Desc *entry); + +#ifdef DIAG_DRV_IF +/****************************************************************************** +* Descriptor and Link dumping functions. +******************************************************************************/ +void sah_Dump_Chain(const sah_Desc *chain, dma_addr_t addr); +#endif /* DIAG_DRV_IF */ + +#endif /* SAH_DRIVER_COMMON_H */ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/include/sah_kernel.h +++ linux-2.6.28/drivers/mxc/security/sahara2/include/sah_kernel.h @@ -0,0 +1,113 @@ +/* + * Copyright 2004-2009 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 + */ + +/* +* @file sah_kernel.h +* +* @brief Provides definitions for items that user-space and kernel-space share. +*/ +/****************************************************************************** +* +* This file needs to be PORTED to a non-Linux platform +*/ + +#ifndef SAH_KERNEL_H +#define SAH_KERNEL_H + +#if defined(__KERNEL__) + +#if defined(CONFIG_ARCH_MXC91321) || defined(CONFIG_ARCH_MXC91231) \ + || defined(CONFIG_ARCH_MX27) || defined(CONFIG_ARCH_MXC92323) +#include +#define SAHA_BASE_ADDR SAHARA_BASE_ADDR +#define SAHARA_IRQ MXC_INT_SAHARA +#elif defined(CONFIG_ARCH_MX51) +#include +#define SAHA_BASE_ADDR SAHARA_BASE_ADDR +#define SAHARA_IRQ MXC_INT_SAHARA_H0 +#else +#include +#endif + +#endif /* KERNEL */ + +/* IO Controls */ +/* The magic number 'k' is reserved for the SPARC architecture. (See /Documentation/ioctl-number.txt. + * + * Note: Numbers 8-13 were used in a previous version of the API and should + * be avoided. + */ +#define SAH_IOC_MAGIC 'k' +#define SAHARA_HWRESET _IO(SAH_IOC_MAGIC, 0) +#define SAHARA_SET_HA _IO(SAH_IOC_MAGIC, 1) +#define SAHARA_CHK_TEST_MODE _IOR(SAH_IOC_MAGIC,2, int) +#define SAHARA_DAR _IO(SAH_IOC_MAGIC, 3) +#define SAHARA_GET_RESULTS _IO(SAH_IOC_MAGIC, 4) +#define SAHARA_REGISTER _IO(SAH_IOC_MAGIC, 5) +#define SAHARA_DEREGISTER _IO(SAH_IOC_MAGIC, 6) +/* 7 */ +/* 8 */ +/* 9 */ +/* 10 */ +/* 11 */ +/* 12 */ +/* 13 */ + +#define SAHARA_SCC_DROP_PERMS _IOWR(SAH_IOC_MAGIC, 14, scc_partition_info_t) +#define SAHARA_SCC_SFREE _IOWR(SAH_IOC_MAGIC, 15, scc_partition_info_t) + +#define SAHARA_SK_ALLOC _IOWR(SAH_IOC_MAGIC, 16, scc_slot_t) +#define SAHARA_SK_DEALLOC _IOWR(SAH_IOC_MAGIC, 17, scc_slot_t) +#define SAHARA_SK_LOAD _IOWR(SAH_IOC_MAGIC, 18, scc_slot_t) +#define SAHARA_SK_UNLOAD _IOWR(SAH_IOC_MAGIC, 19, scc_slot_t) +#define SAHARA_SK_SLOT_ENC _IOWR(SAH_IOC_MAGIC, 20, scc_slot_t) +#define SAHARA_SK_SLOT_DEC _IOWR(SAH_IOC_MAGIC, 21, scc_slot_t) + +#define SAHARA_SCC_ENCRYPT _IOWR(SAH_IOC_MAGIC, 22, scc_region_t) +#define SAHARA_SCC_DECRYPT _IOWR(SAH_IOC_MAGIC, 23, scc_region_t) +#define SAHARA_GET_CAPS _IOWR(SAH_IOC_MAGIC, 24, fsl_shw_pco_t) + +#define SAHARA_SCC_SSTATUS _IOWR(SAH_IOC_MAGIC, 25, scc_partition_info_t) + +#define SAHARA_SK_READ _IOWR(SAH_IOC_MAGIC, 29, scc_slot_t) + +/*! This is the name that will appear in /proc/interrupts */ +#define SAHARA_NAME "SAHARA" + +/*! + * SAHARA IRQ number. See page 9-239 of TLICS - Motorola Semiconductors H.K. + * TAHITI-Lite IC Specification, Rev 1.1, Feb 2003. + * + * TAHITI has two blocks of 32 interrupts. The SAHARA IRQ is number 27 + * in the second block. This means that the SAHARA IRQ is 27 + 32 = 59. + */ +#ifndef SAHARA_IRQ +#define SAHARA_IRQ (27+32) +#endif + +/*! + * Device file definition. The #ifndef is here to support the unit test code + * by allowing it to specify a different test device. + */ +#ifndef SAHARA_DEVICE_SHORT +#define SAHARA_DEVICE_SHORT "sahara" +#endif + +#ifndef SAHARA_DEVICE +#define SAHARA_DEVICE "/dev/"SAHARA_DEVICE_SHORT +#endif + +#endif /* SAH_KERNEL_H */ + +/* End of sah_kernel.h */ --- linux-2.6.28.orig/drivers/mxc/security/sahara2/include/diagnostic.h +++ linux-2.6.28/drivers/mxc/security/sahara2/include/diagnostic.h @@ -0,0 +1,116 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! +* @file diagnostic.h +* +* @brief Macros for outputting kernel and user space diagnostics. +*/ + +#ifndef DIAGNOSTIC_H +#define DIAGNOSTIC_H + +#ifndef __KERNEL__ /* linux flag */ +#include +#endif +#include "fsl_platform.h" + +#if defined(FSL_HAVE_SAHARA2) || defined(FSL_HAVE_SAHARA4) +#define DEV_NAME "sahara" +#elif defined(FSL_HAVE_RNGA) || defined(FSL_HAVE_RNGB) || \ + defined(FSL_HAVE_RNGC) +#define DEV_NAME "shw" +#endif + +/*! +******************************************************************** +* @brief This macro logs diagnostic messages to stderr. +* +* @param diag String that must be logged, char *. +* +* @return void +* +*/ +//#if defined DIAG_SECURITY_FUNC || defined DIAG_ADAPTOR +#define LOG_DIAG(diag) \ +({ \ + const char* fname = strrchr(__FILE__, '/'); \ + \ + sah_Log_Diag(fname ? fname+1 : __FILE__, __LINE__, diag); \ +}) + +#ifdef __KERNEL__ + +#define LOG_DIAG_ARGS(fmt, ...) \ +({ \ + const char* fname = strrchr(__FILE__, '/'); \ + os_printk(KERN_ALERT "%s:%i: " fmt "\n", \ + fname ? fname+1 : __FILE__, \ + __LINE__, \ + __VA_ARGS__); \ +}) + +#else + +#define LOG_DIAG_ARGS(fmt, ...) \ +({ \ + const char* fname = strrchr(__FILE__, '/'); \ + printf("%s:%i: " fmt "\n", \ + fname ? fname+1 : __FILE__, \ + __LINE__, \ + __VA_ARGS__); \ +}) + +#ifndef __KERNEL__ +void sah_Log_Diag(char *source_name, int source_line, char *diag); +#endif +#endif /* if define DIAG_SECURITY_FUNC ... */ + +#ifdef __KERNEL__ +/*! +******************************************************************** +* @brief This macro logs kernel diagnostic messages to the kernel +* log. +* +* @param diag String that must be logged, char *. +* +* @return As for printf() +*/ +#if 0 +#if defined(DIAG_DRV_IF) || defined(DIAG_DRV_QUEUE) || \ + defined(DIAG_DRV_STATUS) || defined(DIAG_DRV_INTERRUPT) || \ + defined(DIAG_MEM) || defined(DIAG_SECURITY_FUNC) || defined(DIAG_ADAPTOR) +#endif +#endif + +#define LOG_KDIAG_ARGS(fmt, ...) \ +({ \ + os_printk (KERN_ALERT "%s (%s:%i): " fmt "\n", \ + DEV_NAME, strrchr(__FILE__, '/')+1, __LINE__, __VA_ARGS__); \ +}) + +#define LOG_KDIAG(diag) \ + os_printk (KERN_ALERT "%s (%s:%i): %s\n", \ + DEV_NAME, strrchr(__FILE__, '/')+1, __LINE__, diag); + +#define sah_Log_Diag(n, l, d) \ + os_printk(KERN_ALERT "%s:%i: %s\n", n, l, d) + +#else /* not KERNEL */ + +#define sah_Log_Diag(n, l, d) \ + printf("%s:%i: %s\n", n, l, d) + +#endif /* __KERNEL__ */ + +#endif /* DIAGNOSTIC_H */ --- linux-2.6.28.orig/drivers/mxc/bt/mxc_bt.c +++ linux-2.6.28/drivers/mxc/bt/mxc_bt.c @@ -0,0 +1,127 @@ +/* + * Copyright 2008-2009 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 + */ + +/*! + * @file mxc_bt.c + * + * @brief MXC Thirty party Bluetooth + * + */ + +#include +#include +#include +#include +#include + +static struct regulator *bt_vdd; +static struct regulator *bt_vdd_parent; +static struct regulator *bt_vusb; +static struct regulator *bt_vusb_parent; + +/*! + * This function poweron the bluetooth hardware module + * + * @param pdev Pointer to the platform device + * @return 0 on success, -1 otherwise. + */ +static int mxc_bt_probe(struct platform_device *pdev) +{ + struct mxc_bt_platform_data *platform_data; + platform_data = (struct mxc_bt_platform_data *)pdev->dev.platform_data; + if (platform_data->bt_vdd) { + bt_vdd = regulator_get(&pdev->dev, platform_data->bt_vdd); + regulator_enable(bt_vdd); + } + if (platform_data->bt_vdd_parent) { + bt_vdd_parent = + regulator_get(&pdev->dev, platform_data->bt_vdd_parent); + regulator_enable(bt_vdd_parent); + } + if (platform_data->bt_vusb) { + bt_vusb = regulator_get(&pdev->dev, platform_data->bt_vusb); + regulator_enable(bt_vusb); + } + if (platform_data->bt_vusb_parent) { + bt_vusb_parent = + regulator_get(&pdev->dev, platform_data->bt_vusb_parent); + regulator_enable(bt_vusb_parent); + } + + if (platform_data->bt_reset != NULL) + platform_data->bt_reset(); + return 0; + +} + +/*! + * This function poweroff the bluetooth hardware module + * + * @param pdev Pointer to the platform device + * @return 0 on success, -1 otherwise. + */ +static int mxc_bt_remove(struct platform_device *pdev) +{ + struct mxc_bt_platform_data *platform_data; + platform_data = (struct mxc_bt_platform_data *)pdev->dev.platform_data; + if (bt_vdd) { + regulator_disable(bt_vdd); + regulator_put(bt_vdd); + } + if (bt_vdd_parent) { + regulator_disable(bt_vdd_parent); + regulator_put(bt_vdd_parent); + } + if (bt_vusb) { + regulator_disable(bt_vusb); + regulator_put(bt_vusb); + } + if (bt_vusb_parent) { + regulator_disable(bt_vusb_parent); + regulator_put(bt_vusb_parent); + } + return 0; + +} + +static struct platform_driver bluetooth_driver = { + .driver = { + .name = "mxc_bt", + }, + .probe = mxc_bt_probe, + .remove = mxc_bt_remove, +}; + +/*! + * Register bluetooth driver module + * + */ +static __init int bluetooth_init(void) +{ + return platform_driver_register(&bluetooth_driver); +} + +/*! + * Exit and free the bluetooth module + * + */ +static void __exit bluetooth_exit(void) +{ + platform_driver_unregister(&bluetooth_driver); +} + +module_init(bluetooth_init); +module_exit(bluetooth_exit); +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("MXC Thirty party Bluetooth"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/mxc/bt/Kconfig +++ linux-2.6.28/drivers/mxc/bt/Kconfig @@ -0,0 +1,13 @@ +# +# Bluetooth configuration +# + +menu "MXC Bluetooth support" + +config MXC_BLUETOOTH + tristate "MXC Bluetooth support" + depends on MACH_MX31_3DS || MACH_MX35_3DS || MACH_MX37_3DS || MACH_MX51_3DS + ---help--- + Say Y to get the third party Bluetooth service. + +endmenu --- linux-2.6.28.orig/drivers/mxc/bt/Makefile +++ linux-2.6.28/drivers/mxc/bt/Makefile @@ -0,0 +1,4 @@ +# +# Makefile for the kernel Bluetooth power-on/reset +# +obj-$(CONFIG_MXC_BLUETOOTH) += mxc_bt.o --- linux-2.6.28.orig/drivers/mxc/vpu/Kconfig +++ linux-2.6.28/drivers/mxc/vpu/Kconfig @@ -0,0 +1,30 @@ +# +# Codec configuration +# + +menu "MXC VPU(Video Processing Unit) support" + +config MXC_VPU + tristate "Support for MXC VPU(Video Processing Unit)" + depends on (ARCH_MX3 || ARCH_MX27 || ARCH_MXC92323 || ARCH_MX37 || ARCH_MX51) + default y + ---help--- + The VPU codec device provides codec function for H.264/MPEG4/H.263, + as well as MPEG2/VC-1/DivX on some platforms. + +config MXC_VPU_IRAM + tristate "Use IRAM as temporary buffer for VPU to enhance performace" + depends on (ARCH_MX37 || ARCH_MX51) + default y + ---help--- + The VPU can use internal RAM as temporary buffer to save external + memroy bandwith, thus to enhance video performance. + +config MXC_VPU_DEBUG + bool "MXC VPU debugging" + depends on MXC_VPU != n + help + This is an option for the developers; most people should + say N here. This enables MXC VPU driver debugging. + +endmenu --- linux-2.6.28.orig/drivers/mxc/vpu/mxc_vpu.c +++ linux-2.6.28/drivers/mxc/vpu/mxc_vpu.c @@ -0,0 +1,762 @@ +/* + * Copyright 2006-2009 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 + */ + +/*! + * @file mxc_vpu.c + * + * @brief VPU system initialization and file operation implementation + * + * @ingroup VPU + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +struct vpu_priv { + struct fasync_struct *async_queue; +}; + +/* To track the allocated memory buffer */ +typedef struct memalloc_record { + struct list_head list; + struct vpu_mem_desc mem; +} memalloc_record; + +struct iram_setting { + u32 start; + u32 end; +}; + +static DEFINE_SPINLOCK(vpu_lock); +static LIST_HEAD(head); + +static int vpu_major = 0; +static struct class *vpu_class; +static struct vpu_priv vpu_data; +static u8 open_count = 0; +static struct clk *vpu_clk; +static struct vpu_mem_desc bitwork_mem = { 0 }; +static struct vpu_mem_desc pic_para_mem = { 0 }; +static struct vpu_mem_desc user_data_mem = { 0 }; + +/* IRAM setting */ +static struct iram_setting iram; + +/* implement the blocking ioctl */ +static int codec_done = 0; +static wait_queue_head_t vpu_queue; + +static u32 workctrl_regsave[6]; +static u32 rd_ptr_regsave[4]; +static u32 wr_ptr_regsave[4]; +static u32 dis_flag_regsave[4]; + +#define READ_REG(x) __raw_readl(IO_ADDRESS(VPU_BASE_ADDR+(x))) +#define WRITE_REG(val, x) \ + __raw_writel((val), IO_ADDRESS(VPU_BASE_ADDR+(x))) + +#define SAVE_WORK_REGS do { \ + int i; \ + for (i = 0; i < ARRAY_SIZE(workctrl_regsave)/2; i++) \ + workctrl_regsave[i] = READ_REG(BIT_WORK_CTRL_BUF_REG(i));\ +} while (0) +#define RESTORE_WORK_REGS do { \ + int i; \ + for (i = 0; i < ARRAY_SIZE(workctrl_regsave)/2; i++) \ + WRITE_REG(workctrl_regsave[i], BIT_WORK_CTRL_BUF_REG(i));\ +} while (0) +#define SAVE_CTRL_REGS do { \ + int i; \ + for (i = ARRAY_SIZE(workctrl_regsave)/2; \ + i < ARRAY_SIZE(workctrl_regsave); i++) \ + workctrl_regsave[i] = READ_REG(BIT_WORK_CTRL_BUF_REG(i));\ +} while (0) +#define RESTORE_CTRL_REGS do { \ + int i; \ + for (i = ARRAY_SIZE(workctrl_regsave)/2; \ + i < ARRAY_SIZE(workctrl_regsave); i++) \ + WRITE_REG(workctrl_regsave[i], BIT_WORK_CTRL_BUF_REG(i));\ +} while (0) +#define SAVE_RDWR_PTR_REGS do { \ + int i; \ + for (i = 0; i < ARRAY_SIZE(rd_ptr_regsave); i++) \ + rd_ptr_regsave[i] = READ_REG(BIT_RD_PTR_REG(i)); \ + for (i = 0; i < ARRAY_SIZE(wr_ptr_regsave); i++) \ + wr_ptr_regsave[i] = READ_REG(BIT_WR_PTR_REG(i)); \ +} while (0) +#define RESTORE_RDWR_PTR_REGS do { \ + int i; \ + for (i = 0; i < ARRAY_SIZE(rd_ptr_regsave); i++) \ + WRITE_REG(rd_ptr_regsave[i], BIT_RD_PTR_REG(i)); \ + for (i = 0; i < ARRAY_SIZE(wr_ptr_regsave); i++) \ + WRITE_REG(wr_ptr_regsave[i], BIT_WR_PTR_REG(i)); \ +} while (0) +#define SAVE_DIS_FLAG_REGS do { \ + int i; \ + for (i = 0; i < ARRAY_SIZE(dis_flag_regsave); i++) \ + dis_flag_regsave[i] = READ_REG(BIT_FRM_DIS_FLG_REG(i)); \ +} while (0) +#define RESTORE_DIS_FLAG_REGS do { \ + int i; \ + for (i = 0; i < ARRAY_SIZE(dis_flag_regsave); i++) \ + WRITE_REG(dis_flag_regsave[i], BIT_FRM_DIS_FLG_REG(i)); \ +} while (0) + +/*! + * Private function to alloc dma buffer + * @return status 0 success. + */ +static int vpu_alloc_dma_buffer(struct vpu_mem_desc *mem) +{ + mem->cpu_addr = (unsigned long) + dma_alloc_coherent(NULL, PAGE_ALIGN(mem->size), + (dma_addr_t *) (&mem->phy_addr), + GFP_DMA | GFP_KERNEL); + pr_debug("[ALLOC] mem alloc cpu_addr = 0x%x\n", mem->cpu_addr); + if ((void *)(mem->cpu_addr) == NULL) { + printk(KERN_ERR "Physical memory allocation error!\n"); + return -1; + } + return 0; +} + +/*! + * Private function to free dma buffer + */ +static void vpu_free_dma_buffer(struct vpu_mem_desc *mem) +{ + if (mem->cpu_addr != 0) { + dma_free_coherent(0, PAGE_ALIGN(mem->size), + (void *)mem->cpu_addr, mem->phy_addr); + } +} + +/*! + * Private function to free buffers + * @return status 0 success. + */ +static int vpu_free_buffers(void) +{ + struct memalloc_record *rec, *n; + struct vpu_mem_desc mem; + + list_for_each_entry_safe(rec, n, &head, list) { + mem = rec->mem; + if (mem.cpu_addr != 0) { + vpu_free_dma_buffer(&mem); + pr_debug("[FREE] freed paddr=0x%08X\n", mem.phy_addr); + /* delete from list */ + list_del(&rec->list); + kfree(rec); + } + } + + return 0; +} + +/*! + * @brief vpu interrupt handler + */ +static irqreturn_t vpu_irq_handler(int irq, void *dev_id) +{ + struct vpu_priv *dev = dev_id; + + READ_REG(BIT_INT_STATUS); + WRITE_REG(0x1, BIT_INT_CLEAR); + + if (dev->async_queue) + kill_fasync(&dev->async_queue, SIGIO, POLL_IN); + + /* + * Clock is gated on when dec/enc started, gate it off when + * interrupt is received. + */ + clk_disable(vpu_clk); + + codec_done = 1; + wake_up_interruptible(&vpu_queue); + + return IRQ_HANDLED; +} + +/*! + * @brief open function for vpu file operation + * + * @return 0 on success or negative error code on error + */ +static int vpu_open(struct inode *inode, struct file *filp) +{ + spin_lock(&vpu_lock); + if ((open_count++ == 0) && cpu_is_mx32()) + vl2cc_enable(); + filp->private_data = (void *)(&vpu_data); + spin_unlock(&vpu_lock); + return 0; +} + +/*! + * @brief IO ctrl function for vpu file operation + * @param cmd IO ctrl command + * @return 0 on success or negative error code on error + */ +static int vpu_ioctl(struct inode *inode, struct file *filp, u_int cmd, + u_long arg) +{ + int ret = 0; + + switch (cmd) { + case VPU_IOC_PHYMEM_ALLOC: + { + struct memalloc_record *rec; + + rec = kzalloc(sizeof(*rec), GFP_KERNEL); + if (!rec) + return -ENOMEM; + + ret = copy_from_user(&(rec->mem), + (struct vpu_mem_desc *)arg, + sizeof(struct vpu_mem_desc)); + if (ret) { + kfree(rec); + return -EFAULT; + } + + pr_debug("[ALLOC] mem alloc size = 0x%x\n", + rec->mem.size); + + ret = vpu_alloc_dma_buffer(&(rec->mem)); + if (ret == -1) { + kfree(rec); + printk(KERN_ERR + "Physical memory allocation error!\n"); + break; + } + ret = copy_to_user((void __user *)arg, &(rec->mem), + sizeof(struct vpu_mem_desc)); + if (ret) { + kfree(rec); + ret = -EFAULT; + break; + } + + spin_lock(&vpu_lock); + list_add(&rec->list, &head); + spin_unlock(&vpu_lock); + + break; + } + case VPU_IOC_PHYMEM_FREE: + { + struct memalloc_record *rec, *n; + struct vpu_mem_desc vpu_mem; + + ret = copy_from_user(&vpu_mem, + (struct vpu_mem_desc *)arg, + sizeof(struct vpu_mem_desc)); + if (ret) + return -EACCES; + + pr_debug("[FREE] mem freed cpu_addr = 0x%x\n", + vpu_mem.cpu_addr); + if ((void *)vpu_mem.cpu_addr != NULL) { + vpu_free_dma_buffer(&vpu_mem); + } + + spin_lock(&vpu_lock); + list_for_each_entry_safe(rec, n, &head, list) { + if (rec->mem.cpu_addr == vpu_mem.cpu_addr) { + /* delete from list */ + list_del(&rec->list); + kfree(rec); + break; + } + } + spin_unlock(&vpu_lock); + + break; + } + case VPU_IOC_WAIT4INT: + { + u_long timeout = (u_long) arg; + if (!wait_event_interruptible_timeout + (vpu_queue, codec_done != 0, + msecs_to_jiffies(timeout))) { + printk(KERN_WARNING "VPU blocking: timeout.\n"); + ret = -ETIME; + } else if (signal_pending(current)) { + printk(KERN_WARNING + "VPU interrupt received.\n"); + ret = -ERESTARTSYS; + } + + codec_done = 0; + break; + } + case VPU_IOC_VL2CC_FLUSH: + if (cpu_is_mx32()) { + vl2cc_flush(); + } + break; + case VPU_IOC_IRAM_SETTING: + { + ret = copy_to_user((void __user *)arg, &iram, + sizeof(struct iram_setting)); + if (ret) + ret = -EFAULT; + + break; + } + case VPU_IOC_CLKGATE_SETTING: + { + u32 clkgate_en; + + if (get_user(clkgate_en, (u32 __user *) arg)) + return -EFAULT; + + if (clkgate_en) { + clk_enable(vpu_clk); + } else { + clk_disable(vpu_clk); + } + + break; + } + case VPU_IOC_GET_WORK_ADDR: + { + if (bitwork_mem.cpu_addr != 0) { + ret = + copy_to_user((void __user *)arg, + &bitwork_mem, + sizeof(struct vpu_mem_desc)); + break; + } else { + if (copy_from_user(&bitwork_mem, + (struct vpu_mem_desc *)arg, + sizeof(struct vpu_mem_desc))) + return -EFAULT; + + if (vpu_alloc_dma_buffer(&bitwork_mem) == -1) + ret = -EFAULT; + else if (copy_to_user((void __user *)arg, + &bitwork_mem, + sizeof(struct + vpu_mem_desc))) + ret = -EFAULT; + } + break; + } + case VPU_IOC_GET_PIC_PARA_ADDR: + { + if (pic_para_mem.cpu_addr != 0) { + ret = + copy_to_user((void __user *)arg, + &pic_para_mem, + sizeof(struct vpu_mem_desc)); + break; + } else { + if (copy_from_user(&pic_para_mem, + (struct vpu_mem_desc *)arg, + sizeof(struct vpu_mem_desc))) + return -EFAULT; + + if (vpu_alloc_dma_buffer(&pic_para_mem) == -1) + ret = -EFAULT; + else if (copy_to_user((void __user *)arg, + &pic_para_mem, + sizeof(struct + vpu_mem_desc))) + ret = -EFAULT; + } + break; + } + case VPU_IOC_GET_USER_DATA_ADDR: + { + if (user_data_mem.cpu_addr != 0) { + ret = + copy_to_user((void __user *)arg, + &user_data_mem, + sizeof(struct vpu_mem_desc)); + break; + } else { + if (copy_from_user(&user_data_mem, + (struct vpu_mem_desc *)arg, + sizeof(struct vpu_mem_desc))) + return -EFAULT; + + if (vpu_alloc_dma_buffer(&user_data_mem) == -1) + ret = -EFAULT; + else if (copy_to_user((void __user *)arg, + &user_data_mem, + sizeof(struct + vpu_mem_desc))) + ret = -EFAULT; + } + break; + } + case VPU_IOC_REG_DUMP: + break; + case VPU_IOC_PHYMEM_DUMP: + break; + default: + { + printk(KERN_ERR "No such IOCTL, cmd is %d\n", cmd); + break; + } + } + return ret; +} + +/*! + * @brief Release function for vpu file operation + * @return 0 on success or negative error code on error + */ +static int vpu_release(struct inode *inode, struct file *filp) +{ + spin_lock(&vpu_lock); + if (open_count > 0 && !(--open_count)) { + vpu_free_buffers(); + + if (cpu_is_mx32()) + vl2cc_disable(); + + } + spin_unlock(&vpu_lock); + + return 0; +} + +/*! + * @brief fasync function for vpu file operation + * @return 0 on success or negative error code on error + */ +static int vpu_fasync(int fd, struct file *filp, int mode) +{ + struct vpu_priv *dev = (struct vpu_priv *)filp->private_data; + return fasync_helper(fd, filp, mode, &dev->async_queue); +} + +/*! + * @brief memory map function of harware registers for vpu file operation + * @return 0 on success or negative error code on error + */ +static int vpu_map_hwregs(struct file *fp, struct vm_area_struct *vm) +{ + unsigned long pfn; + + vm->vm_flags |= VM_IO | VM_RESERVED; + vm->vm_page_prot = pgprot_noncached(vm->vm_page_prot); + pfn = VPU_BASE_ADDR >> PAGE_SHIFT; + pr_debug("size=0x%x, page no.=0x%x\n", + (int)(vm->vm_end - vm->vm_start), (int)pfn); + return remap_pfn_range(vm, vm->vm_start, pfn, vm->vm_end - vm->vm_start, + vm->vm_page_prot) ? -EAGAIN : 0; +} + +/*! + * @brief memory map function of memory for vpu file operation + * @return 0 on success or negative error code on error + */ +static int vpu_map_mem(struct file *fp, struct vm_area_struct *vm) +{ + int request_size; + request_size = vm->vm_end - vm->vm_start; + + pr_debug(" start=0x%x, pgoff=0x%x, size=0x%x\n", + (unsigned int)(vm->vm_start), (unsigned int)(vm->vm_pgoff), + request_size); + + vm->vm_flags |= VM_IO | VM_RESERVED; + vm->vm_page_prot = pgprot_noncached(vm->vm_page_prot); + + return remap_pfn_range(vm, vm->vm_start, vm->vm_pgoff, + request_size, vm->vm_page_prot) ? -EAGAIN : 0; + +} + +/*! + * @brief memory map interface for vpu file operation + * @return 0 on success or negative error code on error + */ +static int vpu_mmap(struct file *fp, struct vm_area_struct *vm) +{ + if (vm->vm_pgoff) + return vpu_map_mem(fp, vm); + else + return vpu_map_hwregs(fp, vm); +} + +struct file_operations vpu_fops = { + .owner = THIS_MODULE, + .open = vpu_open, + .ioctl = vpu_ioctl, + .release = vpu_release, + .fasync = vpu_fasync, + .mmap = vpu_mmap, +}; + +/*! + * This function is called by the driver framework to initialize the vpu device. + * @param dev The device structure for the vpu passed in by the framework. + * @return 0 on success or negative error code on error + */ +static int vpu_dev_probe(struct platform_device *pdev) +{ + int err = 0; + struct device *temp_class; + struct resource *res; + + if (cpu_is_mx32()) { + /* Obtain VL2CC base address */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + printk(KERN_ERR "vpu: unable to get VL2CC base\n"); + return -ENOENT; + } + + err = vl2cc_init(res->start); + if (err != 0) + return err; + } + + if (cpu_is_mx37() || cpu_is_mx51()) { + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + printk(KERN_ERR "vpu: unable to get VPU IRAM base\n"); + return -ENOENT; + } + iram.start = res->start; + iram.end = res->end; + } + + vpu_major = register_chrdev(vpu_major, "mxc_vpu", &vpu_fops); + if (vpu_major < 0) { + printk(KERN_ERR "vpu: unable to get a major for VPU\n"); + err = -EBUSY; + goto error; + } + + vpu_class = class_create(THIS_MODULE, "mxc_vpu"); + if (IS_ERR(vpu_class)) { + err = PTR_ERR(vpu_class); + goto err_out_chrdev; + } + + temp_class = device_create(vpu_class, NULL, MKDEV(vpu_major, 0), + NULL, "mxc_vpu"); + if (IS_ERR(temp_class)) { + err = PTR_ERR(temp_class); + goto err_out_class; + } + + vpu_clk = clk_get(&pdev->dev, "vpu_clk"); + if (IS_ERR(vpu_clk)) { + err = -ENOENT; + goto err_out_class; + } + + err = request_irq(MXC_INT_VPU, vpu_irq_handler, 0, "VPU_CODEC_IRQ", + (void *)(&vpu_data)); + if (err) + goto err_out_class; + + printk(KERN_INFO "VPU initialized\n"); + goto out; + + err_out_class: + device_destroy(vpu_class, MKDEV(vpu_major, 0)); + class_destroy(vpu_class); + err_out_chrdev: + unregister_chrdev(vpu_major, "mxc_vpu"); + error: + if (cpu_is_mx32()) { + vl2cc_cleanup(); + } + out: + return err; +} + +#ifdef CONFIG_PM +static int vpu_suspend(struct platform_device *pdev, pm_message_t state) +{ + if (codec_done == 1) + return -EAGAIN; + + clk_enable(vpu_clk); + if (bitwork_mem.cpu_addr != 0) { + SAVE_WORK_REGS; + SAVE_CTRL_REGS; + SAVE_RDWR_PTR_REGS; + SAVE_DIS_FLAG_REGS; + + WRITE_REG(0x1, BIT_BUSY_FLAG); + WRITE_REG(VPU_SLEEP_REG_VALUE, BIT_RUN_COMMAND); + while (READ_REG(BIT_BUSY_FLAG)) ; + } + + clk_disable(vpu_clk); + + if (cpu_is_mx37() || cpu_is_mx51()) + mxc_pg_enable(pdev); + + return 0; +} + +static int vpu_resume(struct platform_device *pdev) +{ + if (cpu_is_mx37() || cpu_is_mx51()) + mxc_pg_disable(pdev); + + clk_enable(vpu_clk); + + if (bitwork_mem.cpu_addr != 0) { + u32 *p = (u32 *) bitwork_mem.cpu_addr; + u32 data; + u16 data_hi; + u16 data_lo; + int i; + + RESTORE_WORK_REGS; + + WRITE_REG(0x0, BIT_RESET_CTRL); + WRITE_REG(0x0, BIT_CODE_RUN); + + /* + * Re-load boot code, from the codebuffer in external RAM. + * Thankfully, we only need 4096 bytes, same for all platforms. + */ + if (cpu_is_mx51()) { + for (i = 0; i < 2048; i += 4) { + data = p[(i / 2) + 1]; + data_hi = (data >> 16) & 0xFFFF; + data_lo = data & 0xFFFF; + WRITE_REG((i << 16) | data_hi, BIT_CODE_DOWN); + WRITE_REG(((i + 1) << 16) | data_lo, + BIT_CODE_DOWN); + + data = p[i / 2]; + data_hi = (data >> 16) & 0xFFFF; + data_lo = data & 0xFFFF; + WRITE_REG(((i + 2) << 16) | data_hi, + BIT_CODE_DOWN); + WRITE_REG(((i + 3) << 16) | data_lo, + BIT_CODE_DOWN); + } + } else { + for (i = 0; i < 2048; i += 2) { + if (cpu_is_mx37()) + data = swab32(p[i / 2]); + else + data = p[i / 2]; + data_hi = (data >> 16) & 0xFFFF; + data_lo = data & 0xFFFF; + + WRITE_REG((i << 16) | data_hi, BIT_CODE_DOWN); + WRITE_REG(((i + 1) << 16) | data_lo, + BIT_CODE_DOWN); + } + } + + RESTORE_CTRL_REGS; + + WRITE_REG(BITVAL_PIC_RUN, BIT_INT_ENABLE); + + WRITE_REG(0x1, BIT_BUSY_FLAG); + WRITE_REG(0x1, BIT_CODE_RUN); + while (READ_REG(BIT_BUSY_FLAG)) ; + + RESTORE_RDWR_PTR_REGS; + RESTORE_DIS_FLAG_REGS; + + WRITE_REG(0x1, BIT_BUSY_FLAG); + WRITE_REG(VPU_WAKE_REG_VALUE, BIT_RUN_COMMAND); + while (READ_REG(BIT_BUSY_FLAG)) ; + } + + clk_disable(vpu_clk); + + return 0; +} +#else +#define vpu_suspend NULL +#define vpu_resume NULL +#endif /* !CONFIG_PM */ + +/*! Driver definition + * + */ +static struct platform_driver mxcvpu_driver = { + .driver = { + .name = "mxc_vpu", + }, + .probe = vpu_dev_probe, + .suspend = vpu_suspend, + .resume = vpu_resume, +}; + +static int __init vpu_init(void) +{ + int ret = platform_driver_register(&mxcvpu_driver); + + init_waitqueue_head(&vpu_queue); + + return ret; +} + +static void __exit vpu_exit(void) +{ + free_irq(MXC_INT_VPU, (void *)(&vpu_data)); + if (vpu_major > 0) { + device_destroy(vpu_class, MKDEV(vpu_major, 0)); + class_destroy(vpu_class); + unregister_chrdev(vpu_major, "mxc_vpu"); + vpu_major = 0; + } + + if (cpu_is_mx32()) { + vl2cc_cleanup(); + } + + vpu_free_dma_buffer(&bitwork_mem); + vpu_free_dma_buffer(&pic_para_mem); + vpu_free_dma_buffer(&user_data_mem); + + clk_put(vpu_clk); + + platform_driver_unregister(&mxcvpu_driver); + return; +} + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("Linux VPU driver for Freescale i.MX27"); +MODULE_LICENSE("GPL"); + +module_init(vpu_init); +module_exit(vpu_exit); --- linux-2.6.28.orig/drivers/mxc/vpu/Makefile +++ linux-2.6.28/drivers/mxc/vpu/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for the VPU drivers. +# + +obj-$(CONFIG_MXC_VPU) += vpu.o +vpu-objs := mxc_vpu.o mxc_vl2cc.o + +ifeq ($(CONFIG_MXC_VPU_DEBUG),y) +EXTRA_CFLAGS += -DDEBUG +endif --- linux-2.6.28.orig/drivers/mxc/vpu/mxc_vl2cc.c +++ linux-2.6.28/drivers/mxc/vpu/mxc_vl2cc.c @@ -0,0 +1,123 @@ +/* + * Copyright 2007-2009 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 + */ + +/*! + * @file mxc_vl2cc.c + * + * @brief VL2CC initialization and flush operation implementation + * + * @ingroup VL2CC + */ + +#include +#include +#include +#include +#include +#include +#include + +#define VL2CC_CTRL_OFFSET (0x100) +#define VL2CC_AUXCTRL_OFFSET (0x104) +#define VL2CC_INVWAY_OFFSET (0x77C) +#define VL2CC_CLEANWAY_OFFSET (0x7BC) + +/*! VL2CC clock handle. */ +static struct clk *vl2cc_clk; +static u32 *vl2cc_base; + +/*! + * Initialization function of VL2CC. Remap the VL2CC base address. + * + * @return status 0 success. + */ +int vl2cc_init(u32 vl2cc_hw_base) +{ + vl2cc_base = ioremap(vl2cc_hw_base, SZ_8K - 1); + if (vl2cc_base == NULL) { + printk(KERN_INFO "vl2cc: Unable to ioremap\n"); + return -ENOMEM; + } + + vl2cc_clk = clk_get(NULL, "vl2cc_clk"); + if (IS_ERR(vl2cc_clk)) { + printk(KERN_INFO "vl2cc: Unable to get clock\n"); + iounmap(vl2cc_base); + return -EIO; + } + + printk(KERN_INFO "VL2CC initialized\n"); + return 0; +} + +/*! + * Enable VL2CC hardware + */ +void vl2cc_enable(void) +{ + volatile u32 reg; + + clk_enable(vl2cc_clk); + + /* Disable VL2CC */ + reg = __raw_readl(vl2cc_base + VL2CC_CTRL_OFFSET); + reg &= 0xFFFFFFFE; + __raw_writel(reg, vl2cc_base + VL2CC_CTRL_OFFSET); + + /* Set the latency for data RAM reads, data RAM writes, tag RAM and + * dirty RAM to 1 cycle - write 0x0 to AUX CTRL [11:0] and also + * configure the number of ways to 8 - write 8 to AUX CTRL [16:13] + */ + reg = __raw_readl(vl2cc_base + VL2CC_AUXCTRL_OFFSET); + reg &= 0xFFFE1000; /* Clear [16:13] too */ + reg |= (0x8 << 13); /* [16:13] = 8; */ + __raw_writel(reg, vl2cc_base + VL2CC_AUXCTRL_OFFSET); + + /* Invalidate the VL2CC ways - write 0xff to INV BY WAY and poll the + * register until its value is 0x0 + */ + __raw_writel(0xff, vl2cc_base + VL2CC_INVWAY_OFFSET); + while (__raw_readl(vl2cc_base + VL2CC_INVWAY_OFFSET) != 0x0) ; + + /* Enable VL2CC */ + reg = __raw_readl(vl2cc_base + VL2CC_CTRL_OFFSET); + reg |= 0x1; + __raw_writel(reg, vl2cc_base + VL2CC_CTRL_OFFSET); +} + +/*! + * Flush VL2CC + */ +void vl2cc_flush(void) +{ + __raw_writel(0xff, vl2cc_base + VL2CC_CLEANWAY_OFFSET); + while (__raw_readl(vl2cc_base + VL2CC_CLEANWAY_OFFSET) != 0x0) ; +} + +/*! + * Disable VL2CC + */ +void vl2cc_disable(void) +{ + __raw_writel(0, vl2cc_base + VL2CC_CTRL_OFFSET); + clk_disable(vl2cc_clk); +} + +/*! + * Cleanup VL2CC + */ +void vl2cc_cleanup(void) +{ + clk_put(vl2cc_clk); + iounmap(vl2cc_base); +} --- linux-2.6.28.orig/drivers/mxc/pmic/Kconfig +++ linux-2.6.28/drivers/mxc/pmic/Kconfig @@ -0,0 +1,31 @@ +# +# PMIC device driver configuration +# + +menu "MXC PMIC support" + +config MXC_PMIC + boolean + +config MXC_PMIC_MC13892 + tristate "MC13892 PMIC" + depends on ARCH_MXC && (I2C || SPI) + select MXC_PMIC + ---help--- + This is the MXC MC13892(PMIC) support. It include + ADC, Battery, Connectivity, Light, Power and RTC. + +config MXC_PMIC_I2C + bool "Support PMIC I2C Interface" + depends on MXC_PMIC_MC13892 && I2C + +config MXC_PMIC_SPI + bool "Support PMIC SPI Interface" + depends on (MXC_PMIC_MC13892 || MXC_PMIC_MC13783) && SPI + +comment "MXC PMIC Client Drivers" + depends on MXC_PMIC + +source "drivers/mxc/pmic/mc13892/Kconfig" + +endmenu --- linux-2.6.28.orig/drivers/mxc/pmic/Makefile +++ linux-2.6.28/drivers/mxc/pmic/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for the MXC PMIC drivers. +# + +obj-y += core/ +obj-$(CONFIG_MXC_PMIC_MC13892) += mc13892/ + --- linux-2.6.28.orig/drivers/mxc/pmic/core/pmic.h +++ linux-2.6.28/drivers/mxc/pmic/core/pmic.h @@ -0,0 +1,132 @@ +/* + * Copyright 2004-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 __PMIC_H__ +#define __PMIC_H__ + + /*! + * @file pmic.h + * @brief This file contains prototypes of all the functions to be + * defined for each PMIC chip. The implementation of these may differ + * from PMIC chip to PMIC chip. + * + * @ingroup PMIC_CORE + */ + +#include + +#define MAX_ACTIVE_EVENTS 10 + +/*! + * This structure is a way for the PMIC core driver to define their own + * \b spi_device structure. This structure includes the core \b spi_device + * structure that is provided by Linux SPI Framework/driver as an + * element and may contain other elements that are required by core driver. + */ +struct mxc_pmic { + /*! + * Master side proxy for an SPI slave device(PMIC) + */ + struct spi_device *spi; +}; + +/*! + * This function is called to transfer data to PMIC on SPI. + * + * @param spi the SPI slave device(PMIC) + * @param buf the pointer to the data buffer + * @param len the length of the data to be transferred + * + * @return Returns 0 on success -1 on failure. + */ +static inline int spi_rw(struct spi_device *spi, u8 * buf, size_t len) +{ + struct spi_transfer t = { + .tx_buf = (const void *)buf, + .rx_buf = buf, + .len = len, + .cs_change = 0, + .delay_usecs = 0, + }; + struct spi_message m; + + spi_message_init(&m); + spi_message_add_tail(&t, &m); + if (spi_sync(spi, &m) != 0 || m.status != 0) + return PMIC_ERROR; + return (len - m.actual_length); +} + +/*! + * This function returns the PMIC version in system. + * + * @param ver pointer to the pmic_version_t structure + * + * @return This function returns PMIC version. + */ +void pmic_get_revision(pmic_version_t * ver); + +/*! + * This function initializes the SPI device parameters for this PMIC. + * + * @param spi the SPI slave device(PMIC) + * + * @return None + */ +int pmic_spi_setup(struct spi_device *spi); + +/*! + * This function initializes the PMIC registers. + * + * @return None + */ +int pmic_init_registers(void); + +/*! + * This function reads the interrupt status registers of PMIC + * and determine the current active events. + * + * @param active_events array pointer to be used to return active + * event numbers. + * + * @return This function returns PMIC version. + */ +unsigned int pmic_get_active_events(unsigned int *active_events); + +/*! + * This function sets a bit in mask register of pmic to disable an event IT. + * + * @param event the event to be masked + * + * @return This function returns PMIC_SUCCESS on SUCCESS, error on FAILURE. + */ +int pmic_event_mask(type_event event); + +/*! + * This function unsets a bit in mask register of pmic to unmask an event IT. + * + * @param event the event to be unmasked + * + * @return This function returns PMIC_SUCCESS on SUCCESS, error on FAILURE. + */ +int pmic_event_unmask(type_event event); + +#ifdef CONFIG_MXC_PMIC_FIXARB +extern PMIC_STATUS pmic_fix_arbitration(struct spi_device *spi); +#else +static inline PMIC_STATUS pmic_fix_arbitration(struct spi_device *spi) +{ + return PMIC_SUCCESS; +} +#endif + +#endif /* __PMIC_H__ */ --- linux-2.6.28.orig/drivers/mxc/pmic/core/pmic_core_spi.c +++ linux-2.6.28/drivers/mxc/pmic/core/pmic_core_spi.c @@ -0,0 +1,312 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @file pmic_core_spi.c + * @brief This is the main file for the PMIC Core/Protocol driver. SPI + * should be providing the interface between the PMIC and the MCU. + * + * @ingroup PMIC_CORE + */ + +/* + * Includes + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "pmic.h" + +/* + * Static functions + */ +static void pmic_pdev_register(void); +static void pmic_pdev_unregister(void); + +/* + * Platform device structure for PMIC client drivers + */ +static struct platform_device adc_ldm = { + .name = "pmic_adc", + .id = 1, +}; +static struct platform_device battery_ldm = { + .name = "pmic_battery", + .id = 1, +}; +static struct platform_device power_ldm = { + .name = "pmic_power", + .id = 1, +}; +static struct platform_device rtc_ldm = { + .name = "pmic_rtc", + .id = 1, +}; +static struct platform_device light_ldm = { + .name = "pmic_light", + .id = 1, +}; +static struct platform_device rleds_ldm = { + .name = "pmic_leds", + .id = 'r', +}; +static struct platform_device gleds_ldm = { + .name = "pmic_leds", + .id = 'g', +}; +static struct platform_device bleds_ldm = { + .name = "pmic_leds", + .id = 'b', +}; + +/* + * External functions + */ +extern void pmic_event_list_init(void); +extern void pmic_event_callback(type_event event); +extern void gpio_pmic_active(void); +extern irqreturn_t pmic_irq_handler(int irq, void *dev_id); +extern pmic_version_t mxc_pmic_version; +extern struct workqueue_struct *pmic_event_wq; + +/*! + * This function registers platform device structures for + * PMIC client drivers. + */ +static void pmic_pdev_register(void) +{ + platform_device_register(&adc_ldm); + platform_device_register(&battery_ldm); + platform_device_register(&rtc_ldm); + platform_device_register(&power_ldm); + platform_device_register(&light_ldm); + platform_device_register(&rleds_ldm); + platform_device_register(&gleds_ldm); + platform_device_register(&bleds_ldm); +} + +/*! + * This function unregisters platform device structures for + * PMIC client drivers. + */ +static void pmic_pdev_unregister(void) +{ + platform_device_unregister(&adc_ldm); + platform_device_unregister(&battery_ldm); + platform_device_unregister(&rtc_ldm); + platform_device_unregister(&power_ldm); + platform_device_unregister(&light_ldm); +} + +/*! + * This function puts the SPI slave device in low-power mode/state. + * + * @param spi the SPI slave device + * @param message the power state to enter + * + * @return Returns 0 on SUCCESS and error on FAILURE. + */ +static int pmic_suspend(struct spi_device *spi, pm_message_t message) +{ + return PMIC_SUCCESS; +} + +/*! + * This function brings the SPI slave device back from low-power mode/state. + * + * @param spi the SPI slave device + * + * @return Returns 0 on SUCCESS and error on FAILURE. + */ +static int pmic_resume(struct spi_device *spi) +{ + return PMIC_SUCCESS; +} + +static struct spi_driver pmic_driver; + +/*! + * This function is called whenever the SPI slave device is detected. + * + * @param spi the SPI slave device + * + * @return Returns 0 on SUCCESS and error on FAILURE. + */ +static int __devinit pmic_probe(struct spi_device *spi) +{ + int ret = 0; + struct mc13892 *mc13892; + struct mc13892_platform_data *plat_data = spi->dev.platform_data; + + if (!strcmp(spi->dev.bus_id, PMIC_ARBITRATION)) { + if (PMIC_SUCCESS != pmic_fix_arbitration(spi)) { + dev_err((struct device *)spi, + "Unable to fix arbitration!! Access Failed\n"); + return -EACCES; + } + return PMIC_SUCCESS; + } + + /* Initialize the PMIC parameters */ + ret = pmic_spi_setup(spi); + if (ret != PMIC_SUCCESS) { + return PMIC_ERROR; + } + + /* Initialize the PMIC event handling */ + pmic_event_list_init(); + + /* Initialize GPIO for PMIC Interrupt */ + gpio_pmic_active(); + + /* Get the PMIC Version */ + pmic_get_revision(&mxc_pmic_version); + if (mxc_pmic_version.revision < 0) { + dev_err((struct device *)spi, + "PMIC not detected!!! Access Failed\n"); + return -ENODEV; + } else { + dev_dbg((struct device *)spi, + "Detected pmic core IC version number is %d\n", + mxc_pmic_version.revision); + } + + mc13892 = kzalloc(sizeof(struct mc13892), GFP_KERNEL); + if (mc13892 == NULL) + return -ENOMEM; + + spi_set_drvdata(spi, mc13892); + mc13892->dev = &spi->dev; + mc13892->spi_device = spi; + + /* Initialize the PMIC parameters */ + ret = pmic_init_registers(); + if (ret != PMIC_SUCCESS) { + return PMIC_ERROR; + } + + pmic_event_wq = create_workqueue("pmic_spi"); + if (!pmic_event_wq) { + pr_err("mc13892 pmic driver init: fail to create work queue"); + return -EFAULT; + } + + /* Set and install PMIC IRQ handler */ + set_irq_type(spi->irq, IRQF_TRIGGER_RISING); + ret = request_irq(spi->irq, pmic_irq_handler, 0, "PMIC_IRQ", 0); + if (ret) { + dev_err((struct device *)spi, "gpio1: irq%d error.", spi->irq); + return ret; + } + + if (plat_data && plat_data->init) { + ret = plat_data->init(mc13892); + if (ret != 0) + return PMIC_ERROR; + } + + power_ldm.dev.platform_data = spi->dev.platform_data; + + pmic_pdev_register(); + + printk(KERN_INFO "Device %s probed\n", spi->dev.bus_id); + + return PMIC_SUCCESS; +} + +/*! + * This function is called whenever the SPI slave device is removed. + * + * @param spi the SPI slave device + * + * @return Returns 0 on SUCCESS and error on FAILURE. + */ +static int __devexit pmic_remove(struct spi_device *spi) +{ + if (pmic_event_wq) + destroy_workqueue(pmic_event_wq); + + free_irq(spi->irq, 0); + + pmic_pdev_unregister(); + + printk(KERN_INFO "Device %s removed\n", spi->dev.bus_id); + + return PMIC_SUCCESS; +} + +/*! + * This structure contains pointers to the power management callback functions. + */ +static struct spi_driver pmic_driver = { + .driver = { + .name = "pmic_spi", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = pmic_probe, + .remove = __devexit_p(pmic_remove), + .suspend = pmic_suspend, + .resume = pmic_resume, +}; + +/* + * Initialization and Exit + */ + +/*! + * This function implements the init function of the PMIC device. + * This function is called when the module is loaded. It registers + * the PMIC Protocol driver. + * + * @return This function returns 0. + */ +static int __init pmic_init(void) +{ + pr_debug("Registering the PMIC Protocol Driver\n"); + return spi_register_driver(&pmic_driver); +} + +/*! + * This function implements the exit function of the PMIC device. + * This function is called when the module is unloaded. It unregisters + * the PMIC Protocol driver. + * + */ +static void __exit pmic_exit(void) +{ + pr_debug("Unregistering the PMIC Protocol Driver\n"); + spi_unregister_driver(&pmic_driver); +} + +/* + * Module entry points + */ +subsys_initcall_sync(pmic_init); +module_exit(pmic_exit); + +MODULE_DESCRIPTION("Core/Protocol driver for PMIC"); +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/mxc/pmic/core/pmic_common.c +++ linux-2.6.28/drivers/mxc/pmic/core/pmic_common.c @@ -0,0 +1,98 @@ +/* + * Copyright 2009 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 + */ + +/*! + * @file pmic_common.c + * @brief This is the common file for the PMIC Core/Protocol driver. + * + * @ingroup PMIC_CORE + */ + +/* + * Includes + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "pmic.h" + +/* + * Global variables + */ +pmic_version_t mxc_pmic_version; +unsigned int active_events[MAX_ACTIVE_EVENTS]; +struct workqueue_struct *pmic_event_wq; + +void pmic_bh_handler(struct work_struct *work); +/*! + * Bottom half handler of PMIC event handling. + */ +DECLARE_WORK(pmic_ws, pmic_bh_handler); + +/*! + * This function is the bottom half handler of the PMIC interrupt. + * It checks for active events and launches callback for the + * active events. + */ +void pmic_bh_handler(struct work_struct *work) +{ + unsigned int loop; + unsigned int count = 0; + + count = pmic_get_active_events(active_events); + pr_debug("active events number %d\n", count); + + for (loop = 0; loop < count; loop++) + pmic_event_callback(active_events[loop]); + + return; +} + +/*! + * This function is called when pmic interrupt occurs on the processor. + * It is the interrupt handler for the pmic module. + * + * @param irq the irq number + * @param dev_id the pointer on the device + * + * @return The function returns IRQ_HANDLED when handled. + */ +irqreturn_t pmic_irq_handler(int irq, void *dev_id) +{ + /* prepare a task */ + queue_work(pmic_event_wq, &pmic_ws); + + return IRQ_HANDLED; +} + +/*! + * This function is used to determine the PMIC type and its revision. + * + * @return Returns the PMIC type and its revision. + */ + +pmic_version_t pmic_get_version(void) +{ + return mxc_pmic_version; +} +EXPORT_SYMBOL(pmic_get_version); --- linux-2.6.28.orig/drivers/mxc/pmic/core/pmic_external.c +++ linux-2.6.28/drivers/mxc/pmic/core/pmic_external.c @@ -0,0 +1,100 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @file pmic_external.c + * @brief This file contains all external functions of PMIC drivers. + * + * @ingroup PMIC_CORE + */ + +/* + * Includes + */ +#include +#include +#include +#include +#include + +#include +#include + +/* + * External Functions + */ +extern int pmic_read(int reg_num, unsigned int *reg_val); +extern int pmic_write(int reg_num, const unsigned int reg_val); + +/*! + * This function is called by PMIC clients to read a register on PMIC. + * + * @param reg number of register + * @param reg_value return value of register + * @param reg_mask Bitmap mask indicating which bits to modify + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_read_reg(int reg, unsigned int *reg_value, + unsigned int reg_mask) +{ + int ret = 0; + unsigned int temp = 0; + + ret = pmic_read(reg, &temp); + if (ret != PMIC_SUCCESS) { + return PMIC_ERROR; + } + *reg_value = (temp & reg_mask); + + pr_debug("Read REG[ %d ] = 0x%x\n", reg, *reg_value); + + return ret; +} + +/*! + * This function is called by PMIC clients to write a register on PMIC. + * + * @param reg number of register + * @param reg_value New value of register + * @param reg_mask Bitmap mask indicating which bits to modify + * + * @return This function returns PMIC_SUCCESS if successful. + */ +PMIC_STATUS pmic_write_reg(int reg, unsigned int reg_value, + unsigned int reg_mask) +{ + int ret = 0; + unsigned int temp = 0; + + ret = pmic_read(reg, &temp); + if (ret != PMIC_SUCCESS) { + return PMIC_ERROR; + } + temp = (temp & (~reg_mask)) | reg_value; +#ifdef CONFIG_MXC_PMIC_MC13783 + if (reg == REG_POWER_MISCELLANEOUS) + temp &= 0xFFFE7FFF; +#endif + ret = pmic_write(reg, temp); + if (ret != PMIC_SUCCESS) { + return PMIC_ERROR; + } + + pr_debug("Write REG[ %d ] = 0x%x\n", reg, reg_value); + + return ret; +} + +EXPORT_SYMBOL(pmic_read_reg); +EXPORT_SYMBOL(pmic_write_reg); --- linux-2.6.28.orig/drivers/mxc/pmic/core/pmic_event.c +++ linux-2.6.28/drivers/mxc/pmic/core/pmic_event.c @@ -0,0 +1,235 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @file pmic_event.c + * @brief This file manage all event of PMIC component. + * + * It contains event subscription, unsubscription and callback + * launch methods implemeted. + * + * @ingroup PMIC_CORE + */ + +/* + * Includes + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pmic.h" + +/*! + * This structure is used to keep a list of subscribed + * callbacks for an event. + */ +typedef struct { + /*! + * Keeps a list of subscribed clients to an event. + */ + struct list_head list; + + /*! + * Callback function with parameter, called when event occurs + */ + pmic_event_callback_t callback; +} pmic_event_callback_list_t; + +/* Create a mutex to be used to prevent concurrent access to the event list */ +static DECLARE_MUTEX(event_mutex); + +/* This is a pointer to the event handler array. It defines the currently + * active set of events and user-defined callback functions. + */ +static struct list_head pmic_events[PMIC_MAX_EVENTS]; + +/*! + * This function initializes event list for PMIC event handling. + * + */ +void pmic_event_list_init(void) +{ + int i; + + for (i = 0; i < PMIC_MAX_EVENTS; i++) { + INIT_LIST_HEAD(&pmic_events[i]); + } + + sema_init(&event_mutex, 1); + return; +} + +/*! + * This function is used to subscribe on an event. + * + * @param event the event number to be subscribed + * @param callback the callback funtion to be subscribed + * + * @return This function returns 0 on SUCCESS, error on FAILURE. + */ +PMIC_STATUS pmic_event_subscribe(type_event event, + pmic_event_callback_t callback) +{ + pmic_event_callback_list_t *new = NULL; + + pr_debug("Event:%d Subscribe\n", event); + + /* Check whether the event & callback are valid? */ + if (event >= PMIC_MAX_EVENTS) { + pr_debug("Invalid Event:%d\n", event); + return -EINVAL; + } + if (NULL == callback.func) { + pr_debug("Null or Invalid Callback\n"); + return -EINVAL; + } + + /* Create a new linked list entry */ + new = kmalloc(sizeof(pmic_event_callback_list_t), GFP_KERNEL); + if (NULL == new) { + return -ENOMEM; + } + /* Initialize the list node fields */ + new->callback.func = callback.func; + new->callback.param = callback.param; + INIT_LIST_HEAD(&new->list); + + /* Obtain the lock to access the list */ + if (down_interruptible(&event_mutex)) { + kfree(new); + return PMIC_SYSTEM_ERROR_EINTR; + } + + /* Unmask the requested event */ + if (list_empty(&pmic_events[event])) { + if (pmic_event_unmask(event) != PMIC_SUCCESS) { + kfree(new); + up(&event_mutex); + return PMIC_ERROR; + } + } + + /* Add this entry to the event list */ + list_add_tail(&new->list, &pmic_events[event]); + + /* Release the lock */ + up(&event_mutex); + + return PMIC_SUCCESS; +} + +/*! + * This function is used to unsubscribe on an event. + * + * @param event the event number to be unsubscribed + * @param callback the callback funtion to be unsubscribed + * + * @return This function returns 0 on SUCCESS, error on FAILURE. + */ +PMIC_STATUS pmic_event_unsubscribe(type_event event, + pmic_event_callback_t callback) +{ + struct list_head *p; + struct list_head *n; + pmic_event_callback_list_t *temp = NULL; + int ret = PMIC_EVENT_NOT_SUBSCRIBED; + + pr_debug("Event:%d Unsubscribe\n", event); + + /* Check whether the event & callback are valid? */ + if (event >= PMIC_MAX_EVENTS) { + pr_debug("Invalid Event:%d\n", event); + return -EINVAL; + } + + if (NULL == callback.func) { + pr_debug("Null or Invalid Callback\n"); + return -EINVAL; + } + + /* Obtain the lock to access the list */ + if (down_interruptible(&event_mutex)) { + return PMIC_SYSTEM_ERROR_EINTR; + } + + /* Find the entry in the list */ + list_for_each_safe(p, n, &pmic_events[event]) { + temp = list_entry(p, pmic_event_callback_list_t, list); + if (temp->callback.func == callback.func + && temp->callback.param == callback.param) { + /* Remove the entry from the list */ + list_del(p); + kfree(temp); + ret = PMIC_SUCCESS; + break; + } + } + + /* Unmask the requested event */ + if (list_empty(&pmic_events[event])) { + if (pmic_event_mask(event) != PMIC_SUCCESS) { + ret = PMIC_UNSUBSCRIBE_ERROR; + } + } + + /* Release the lock */ + up(&event_mutex); + + return ret; +} + +/*! + * This function calls all callback of a specific event. + * + * @param event the active event number + * + * @return None + */ +void pmic_event_callback(type_event event) +{ + struct list_head *p; + pmic_event_callback_list_t *temp = NULL; + + /* Obtain the lock to access the list */ + if (down_interruptible(&event_mutex)) { + return; + } + + if (list_empty(&pmic_events[event])) { + pr_debug("PMIC Event:%d detected. No callback subscribed\n", + event); + up(&event_mutex); + return; + } + + list_for_each(p, &pmic_events[event]) { + temp = list_entry(p, pmic_event_callback_list_t, list); + temp->callback.func(temp->callback.param); + } + + /* Release the lock */ + up(&event_mutex); + + return; + +} + +EXPORT_SYMBOL(pmic_event_subscribe); +EXPORT_SYMBOL(pmic_event_unsubscribe); --- linux-2.6.28.orig/drivers/mxc/pmic/core/Makefile +++ linux-2.6.28/drivers/mxc/pmic/core/Makefile @@ -0,0 +1,14 @@ +# +# Makefile for the PMIC core drivers. +# +obj-$(CONFIG_MXC_PMIC_MC13892) += pmic_mc13892_mod.o +pmic_mc13892_mod-objs := pmic_external.o pmic_event.o pmic_common.o mc13892.o + +ifneq ($(CONFIG_MXC_PMIC_SPI),) +pmic_mc13892_mod-objs += pmic_core_spi.o +endif + +ifneq ($(CONFIG_MXC_PMIC_I2C),) +pmic_mc13892_mod-objs += pmic_core_i2c.o +endif + --- linux-2.6.28.orig/drivers/mxc/pmic/core/pmic_core_i2c.c +++ linux-2.6.28/drivers/mxc/pmic/core/pmic_core_i2c.c @@ -0,0 +1,334 @@ +/* + * Copyright 2008-2009 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 + */ + +/*! + * @file pmic_core_i2c.c + * @brief This is the main file for the PMIC Core/Protocol driver. i2c + * should be providing the interface between the PMIC and the MCU. + * + * @ingroup PMIC_CORE + */ + +/* + * Includes + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "pmic.h" + +#define MC13892_GENERATION_ID_LSH 6 +#define MC13892_IC_ID_LSH 13 + +#define MC13892_GENERATION_ID_WID 3 +#define MC13892_IC_ID_WID 6 + +#define MC13892_GEN_ID_VALUE 0x7 +#define MC13892_IC_ID_VALUE 1 + +/* + * Global variables + */ +struct i2c_client *mc13892_client; + +extern struct workqueue_struct *pmic_event_wq; +extern pmic_version_t mxc_pmic_version; +extern irqreturn_t pmic_irq_handler(int irq, void *dev_id); + +/* + * Platform device structure for PMIC client drivers + */ +static struct platform_device adc_ldm = { + .name = "pmic_adc", + .id = 1, +}; +static struct platform_device battery_ldm = { + .name = "pmic_battery", + .id = 1, +}; +static struct platform_device power_ldm = { + .name = "pmic_power", + .id = 1, +}; +static struct platform_device rtc_ldm = { + .name = "pmic_rtc", + .id = 1, +}; +static struct platform_device light_ldm = { + .name = "pmic_light", + .id = 1, +}; +static struct platform_device rleds_ldm = { + .name = "pmic_leds", + .id = 'r', +}; +static struct platform_device gleds_ldm = { + .name = "pmic_leds", + .id = 'g', +}; +static struct platform_device bleds_ldm = { + .name = "pmic_leds", + .id = 'b', +}; + +static void pmic_pdev_register(struct device *dev) +{ + platform_device_register(&adc_ldm); + platform_device_register(&battery_ldm); + platform_device_register(&rtc_ldm); + platform_device_register(&power_ldm); + platform_device_register(&light_ldm); + platform_device_register(&rleds_ldm); + platform_device_register(&gleds_ldm); + platform_device_register(&bleds_ldm); +} + +/*! + * This function unregisters platform device structures for + * PMIC client drivers. + */ +static void pmic_pdev_unregister(void) +{ + platform_device_unregister(&adc_ldm); + platform_device_unregister(&battery_ldm); + platform_device_unregister(&rtc_ldm); + platform_device_unregister(&power_ldm); + platform_device_unregister(&light_ldm); +} + +static int __devinit is_chip_onboard(struct i2c_client *client) +{ + unsigned int ret = 0; + + /*bind the right device to the driver */ + if (pmic_i2c_24bit_read(client, REG_IDENTIFICATION, &ret) == -1) + return -1; + + if (MC13892_GEN_ID_VALUE != BITFEXT(ret, MC13892_GENERATION_ID)) { + /*compare the address value */ + dev_err(&client->dev, + "read generation ID 0x%x is not equal to 0x%x!\n", + BITFEXT(ret, MC13892_GENERATION_ID), + MC13892_GEN_ID_VALUE); + return -1; + } + + return 0; +} + +static ssize_t mc13892_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int i, value; + int offset = (REG_TEST4 + 1) / 4; + + for (i = 0; i < offset; i++) { + pmic_read(i, &value); + pr_info("reg%02d: %06x\t\t", i, value); + pmic_read(i + offset, &value); + pr_info("reg%02d: %06x\t\t", i + offset, value); + pmic_read(i + offset * 2, &value); + pr_info("reg%02d: %06x\t\t", i + offset * 2, value); + pmic_read(i + offset * 3, &value); + pr_info("reg%02d: %06x\n", i + offset * 3, value); + } + + return 0; +} + +static ssize_t mc13892_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + int reg, value, ret; + char *p; + + reg = simple_strtoul(buf, NULL, 10); + + p = NULL; + p = memchr(buf, ' ', count); + + if (p == NULL) { + pmic_read(reg, &value); + pr_debug("reg%02d: %06x\n", reg, value); + return count; + } + + p += 1; + + value = simple_strtoul(p, NULL, 16); + + ret = pmic_write(reg, value); + if (ret == 0) + pr_debug("write reg%02d: %06x\n", reg, value); + else + pr_debug("register update failed\n"); + + return count; +} + +static struct device_attribute mc13892_dev_attr = { + .attr = { + .name = "mc13892_ctl", + .mode = S_IRUSR | S_IWUSR, + }, + .show = mc13892_show, + .store = mc13892_store, +}; + +static int __devinit pmic_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret = 0; + int pmic_irq; + struct mc13892 *mc13892; + struct mc13892_platform_data *plat_data = client->dev.platform_data; + + ret = is_chip_onboard(client); + if (ret == -1) + return -ENODEV; + + mc13892 = kzalloc(sizeof(struct mc13892), GFP_KERNEL); + if (mc13892 == NULL) + return -ENOMEM; + + i2c_set_clientdata(client, mc13892); + mc13892->dev = &client->dev; + mc13892->i2c_client = client; + + /* so far, we got matched chip on board */ + + mc13892_client = client; + + /* Initialize the PMIC event handling */ + pmic_event_list_init(); + + /* Initialize GPIO for PMIC Interrupt */ + gpio_pmic_active(); + + /* Initialize the PMIC parameters */ + ret = pmic_init_registers(); + if (ret != PMIC_SUCCESS) + return PMIC_ERROR; + + pmic_event_wq = create_workqueue("mc13892"); + if (!pmic_event_wq) { + pr_err("mc13892 pmic driver init: fail to create work queue"); + return -EFAULT; + } + + /* Set and install PMIC IRQ handler */ + pmic_irq = (int)(client->irq); + if (pmic_irq == 0) + return PMIC_ERROR; + + set_irq_type(IOMUX_TO_IRQ(pmic_irq), IRQF_TRIGGER_RISING); + ret = + request_irq(IOMUX_TO_IRQ(pmic_irq), pmic_irq_handler, 0, "PMIC_IRQ", + 0); + + if (ret) { + dev_err(&client->dev, "request irq %d error!\n", pmic_irq); + return ret; + } + enable_irq_wake(IOMUX_TO_IRQ(pmic_irq)); + + if (plat_data && plat_data->init) { + ret = plat_data->init(mc13892); + if (ret != 0) + return PMIC_ERROR; + } + + ret = device_create_file(&client->dev, &mc13892_dev_attr); + if (ret) + dev_err(&client->dev, "create device file failed!\n"); + + pmic_pdev_register(&client->dev); + + dev_info(&client->dev, "Loaded\n"); + + return PMIC_SUCCESS; +} + +static int pmic_remove(struct i2c_client *client) +{ + int pmic_irq = (int)(client->dev.platform_data); + + if (pmic_event_wq) + destroy_workqueue(pmic_event_wq); + + free_irq(pmic_irq, 0); + pmic_pdev_unregister(); + return 0; +} + +static int pmic_suspend(struct i2c_client *client, pm_message_t state) +{ + return 0; +} + +static int pmic_resume(struct i2c_client *client) +{ + return 0; +} + +static const struct i2c_device_id mc13892_id[] = { + {"mc13892", 0}, + {}, +}; + +MODULE_DEVICE_TABLE(i2c, mc13892_id); + +static struct i2c_driver pmic_driver = { + .driver = { + .name = "mc13892", + .bus = NULL, + }, + .probe = pmic_probe, + .remove = pmic_remove, + .suspend = pmic_suspend, + .resume = pmic_resume, + .id_table = mc13892_id, +}; + +static int __init pmic_init(void) +{ + return i2c_add_driver(&pmic_driver); +} + +static void __exit pmic_exit(void) +{ + i2c_del_driver(&pmic_driver); +} + +/* + * Module entry points + */ +subsys_initcall_sync(pmic_init); +module_exit(pmic_exit); + +MODULE_DESCRIPTION("Core/Protocol driver for PMIC"); +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/mxc/pmic/core/mc13892.c +++ linux-2.6.28/drivers/mxc/pmic/core/mc13892.c @@ -0,0 +1,319 @@ +/* + * Copyright 2008-2009 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 + */ + +/*! + * @file pmic/core/mc13892.c + * @brief This file contains MC13892 specific PMIC code. This implementaion + * may differ for each PMIC chip. + * + * @ingroup PMIC_CORE + */ + +/* + * Includes + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "pmic.h" + +/* + * Defines + */ +#define MC13892_I2C_RETRY_TIMES 10 +#define MXC_PMIC_FRAME_MASK 0x00FFFFFF +#define MXC_PMIC_MAX_REG_NUM 0x3F +#define MXC_PMIC_REG_NUM_SHIFT 0x19 +#define MXC_PMIC_WRITE_BIT_SHIFT 31 + +static unsigned int events_enabled0; +static unsigned int events_enabled1; +static struct mxc_pmic pmic_drv_data; +#ifndef CONFIG_MXC_PMIC_I2C +struct i2c_client *mc13892_client; +#endif + +int pmic_i2c_24bit_read(struct i2c_client *client, unsigned int reg_num, + unsigned int *value) +{ + unsigned char buf[3]; + int ret; + int i; + + memset(buf, 0, 3); + for (i = 0; i < MC13892_I2C_RETRY_TIMES; i++) { + ret = i2c_smbus_read_i2c_block_data(client, reg_num, 3, buf); + if (ret == 3) + break; + msleep(1); + } + + if (ret == 3) { + *value = buf[0] << 16 | buf[1] << 8 | buf[2]; + return ret; + } else { + pr_debug("24bit read error, ret = %d\n", ret); + return -1; /* return -1 on failure */ + } +} + +int pmic_i2c_24bit_write(struct i2c_client *client, + unsigned int reg_num, unsigned int reg_val) +{ + char buf[3]; + int ret; + int i; + + buf[0] = (reg_val >> 16) & 0xff; + buf[1] = (reg_val >> 8) & 0xff; + buf[2] = (reg_val) & 0xff; + + for (i = 0; i < MC13892_I2C_RETRY_TIMES; i++) { + ret = i2c_smbus_write_i2c_block_data(client, reg_num, 3, buf); + if (ret == 0) + break; + msleep(1); + } + + return ret; +} + +int pmic_read(int reg_num, unsigned int *reg_val) +{ + unsigned int frame = 0; + int ret = 0; + + if (pmic_drv_data.spi != NULL) { + if (reg_num > MXC_PMIC_MAX_REG_NUM) + return PMIC_ERROR; + + frame |= reg_num << MXC_PMIC_REG_NUM_SHIFT; + + ret = spi_rw(pmic_drv_data.spi, (u8 *) &frame, 1); + + *reg_val = frame & MXC_PMIC_FRAME_MASK; + } else { + if (mc13892_client == NULL) + return PMIC_ERROR; + + if (pmic_i2c_24bit_read(mc13892_client, reg_num, reg_val) == -1) + return PMIC_ERROR; + } + + return PMIC_SUCCESS; +} + +int pmic_write(int reg_num, const unsigned int reg_val) +{ + unsigned int frame = 0; + int ret = 0; + + if (pmic_drv_data.spi != NULL) { + if (reg_num > MXC_PMIC_MAX_REG_NUM) + return PMIC_ERROR; + + frame |= (1 << MXC_PMIC_WRITE_BIT_SHIFT); + + frame |= reg_num << MXC_PMIC_REG_NUM_SHIFT; + + frame |= reg_val & MXC_PMIC_FRAME_MASK; + + ret = spi_rw(pmic_drv_data.spi, (u8 *) &frame, 1); + + return ret; + } else { + if (mc13892_client == NULL) + return PMIC_ERROR; + + return pmic_i2c_24bit_write(mc13892_client, reg_num, reg_val); + } +} + +/*! + * This function initializes the SPI device parameters for this PMIC. + * + * @param spi the SPI slave device(PMIC) + * + * @return None + */ +int pmic_spi_setup(struct spi_device *spi) +{ + /* Setup the SPI slave i.e.PMIC */ + pmic_drv_data.spi = spi; + + spi->mode = SPI_MODE_0 | SPI_CS_HIGH; + spi->bits_per_word = 32; + + return spi_setup(spi); +} + +int pmic_init_registers(void) +{ + CHECK_ERROR(pmic_write(REG_INT_MASK0, 0xFFFFFF)); + CHECK_ERROR(pmic_write(REG_INT_MASK0, 0xFFFFFF)); + CHECK_ERROR(pmic_write(REG_INT_STATUS0, 0xFFFFFF)); + CHECK_ERROR(pmic_write(REG_INT_STATUS1, 0xFFFFFF)); + /* disable auto charge */ + if (machine_is_mx51_3ds()) + CHECK_ERROR(pmic_write(REG_CHARGE, 0xB40003)); + + pm_power_off = mc13892_power_off; + + return PMIC_SUCCESS; +} + +unsigned int pmic_get_active_events(unsigned int *active_events) +{ + unsigned int count = 0; + unsigned int status0, status1; + int bit_set; + + pmic_read(REG_INT_STATUS0, &status0); + pmic_read(REG_INT_STATUS1, &status1); + pmic_write(REG_INT_STATUS0, status0); + pmic_write(REG_INT_STATUS1, status1); + status0 &= events_enabled0; + status1 &= events_enabled1; + + while (status0) { + bit_set = ffs(status0) - 1; + *(active_events + count) = bit_set; + count++; + status0 ^= (1 << bit_set); + } + while (status1) { + bit_set = ffs(status1) - 1; + *(active_events + count) = bit_set + 24; + count++; + status1 ^= (1 << bit_set); + } + + return count; +} + +#define EVENT_MASK_0 0x387fff +#define EVENT_MASK_1 0x1177eb + +int pmic_event_unmask(type_event event) +{ + unsigned int event_mask = 0; + unsigned int mask_reg = 0; + unsigned int event_bit = 0; + int ret; + + if (event < EVENT_1HZI) { + mask_reg = REG_INT_MASK0; + event_mask = EVENT_MASK_0; + event_bit = (1 << event); + events_enabled0 |= event_bit; + } else { + event -= 24; + mask_reg = REG_INT_MASK1; + event_mask = EVENT_MASK_1; + event_bit = (1 << event); + events_enabled1 |= event_bit; + } + + if ((event_bit & event_mask) == 0) { + pr_debug("Error: unmasking a reserved/unused event\n"); + return PMIC_ERROR; + } + + ret = pmic_write_reg(mask_reg, 0, event_bit); + + pr_debug("Enable Event : %d\n", event); + + return ret; +} + +int pmic_event_mask(type_event event) +{ + unsigned int event_mask = 0; + unsigned int mask_reg = 0; + unsigned int event_bit = 0; + int ret; + + if (event < EVENT_1HZI) { + mask_reg = REG_INT_MASK0; + event_mask = EVENT_MASK_0; + event_bit = (1 << event); + events_enabled0 &= ~event_bit; + } else { + event -= 24; + mask_reg = REG_INT_MASK1; + event_mask = EVENT_MASK_1; + event_bit = (1 << event); + events_enabled1 &= ~event_bit; + } + + if ((event_bit & event_mask) == 0) { + pr_debug("Error: masking a reserved/unused event\n"); + return PMIC_ERROR; + } + + ret = pmic_write_reg(mask_reg, event_bit, event_bit); + + pr_debug("Disable Event : %d\n", event); + + return ret; +} + +/*! + * This function returns the PMIC version in system. + * + * @param ver pointer to the pmic_version_t structure + * + * @return This function returns PMIC version. + */ +void pmic_get_revision(pmic_version_t *ver) +{ + int rev_id = 0; + int rev1 = 0; + int rev2 = 0; + int finid = 0; + int icid = 0; + + ver->id = PMIC_MC13892; + pmic_read(REG_IDENTIFICATION, &rev_id); + + rev1 = (rev_id & 0x018) >> 3; + rev2 = (rev_id & 0x007); + icid = (rev_id & 0x01C0) >> 6; + finid = (rev_id & 0x01E00) >> 9; + + ver->revision = ((rev1 * 10) + rev2); + printk(KERN_INFO "mc13892 Rev %d.%d FinVer %x detected\n", rev1, + rev2, finid); +} + +void mc13892_power_off(void) +{ + unsigned int value; + + pmic_read_reg(REG_POWER_CTL0, &value, 0xffffff); + + value |= 0x000008; + + pmic_write_reg(REG_POWER_CTL0, value, 0xffffff); +} --- linux-2.6.28.orig/drivers/mxc/pmic/mc13892/Kconfig +++ linux-2.6.28/drivers/mxc/pmic/mc13892/Kconfig @@ -0,0 +1,48 @@ +# +# PMIC Modules configuration +# + +config MXC_MC13892_ADC + tristate "MC13892 ADC support" + depends on MXC_PMIC_MC13892 + ---help--- + This is the MC13892 ADC module driver. This module provides kernel API + for the ADC system of MC13892. + It controls also the touch screen interface. + If you want MC13892 ADC support, you should say Y here + +config MXC_MC13892_RTC + tristate "MC13892 Real Time Clock (RTC) support" + depends on MXC_PMIC_MC13892 + ---help--- + This is the MC13892 RTC module driver. This module provides kernel API + for RTC part of MC13892. + If you want MC13892 RTC support, you should say Y here +config MXC_MC13892_LIGHT + tristate "MC13892 Light and Backlight support" + depends on MXC_PMIC_MC13892 + ---help--- + This is the MC13892 Light module driver. This module provides kernel API + for led and backlight control part of MC13892. + If you want MC13892 Light support, you should say Y here +config MXC_MC13892_BATTERY + tristate "MC13892 Battery API support" + depends on MXC_PMIC_MC13892 + ---help--- + This is the MC13892 battery module driver. This module provides kernel API + for battery control part of MC13892. + If you want MC13892 battery support, you should say Y here +config MXC_MC13892_CONNECTIVITY + tristate "MC13892 Connectivity API support" + depends on MXC_PMIC_MC13892 + ---help--- + This is the MC13892 connectivity module driver. This module provides kernel API + for USB/RS232 connectivity control part of MC13892. + If you want MC13892 connectivity support, you should say Y here +config MXC_MC13892_POWER + tristate "MC13892 Power API support" + depends on MXC_PMIC_MC13892 + ---help--- + This is the MC13892 power and supplies module driver. This module provides kernel API + for power and regulator control part of MC13892. + If you want MC13892 power support, you should say Y here --- linux-2.6.28.orig/drivers/mxc/pmic/mc13892/Makefile +++ linux-2.6.28/drivers/mxc/pmic/mc13892/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for the mc13783 pmic drivers. +# + +obj-$(CONFIG_MXC_MC13892_ADC) += pmic_adc.o +#obj-$(CONFIG_MXC_MC13892_RTC) += pmic_rtc.o +obj-$(CONFIG_MXC_MC13892_LIGHT) += pmic_light.o +#obj-$(CONFIG_MXC_MC13892_BATTERY) += pmic_battery.o +#obj-$(CONFIG_MXC_MC13892_CONNECTIVITY) += pmic_convity.o +#obj-$(CONFIG_MXC_MC13892_POWER) += pmic_power.o --- linux-2.6.28.orig/drivers/mxc/pmic/mc13892/pmic_adc.c +++ linux-2.6.28/drivers/mxc/pmic/mc13892/pmic_adc.c @@ -0,0 +1,982 @@ +/* + * Copyright 2008-2009 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 + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../core/pmic.h" + +#define DEF_ADC_0 0x008000 +#define DEF_ADC_3 0x0001c0 + +#define ADC_NB_AVAILABLE 2 + +#define MAX_CHANNEL 7 + +#define MC13892_ADC0_TS_M_LSH 14 +#define MC13892_ADC0_TS_M_WID 3 + +/* + * Maximun allowed variation in the three X/Y co-ordinates acquired from + * touch-screen + */ +#define DELTA_Y_MAX 50 +#define DELTA_X_MAX 50 + +/* + * ADC 0 + */ +#define ADC_WAIT_TSI_0 0x001400 + +#define ADC_INC 0x030000 +#define ADC_BIS 0x800000 +#define ADC_CHRGRAW_D5 0x008000 + +/* + * ADC 1 + */ + +#define ADC_EN 0x000001 +#define ADC_SGL_CH 0x000002 +#define ADC_ADSEL 0x000008 +#define ADC_CH_0_POS 5 +#define ADC_CH_0_MASK 0x0000E0 +#define ADC_CH_1_POS 8 +#define ADC_CH_1_MASK 0x000700 +#define ADC_DELAY_POS 11 +#define ADC_DELAY_MASK 0x07F800 +#define ADC_ATO 0x080000 +#define ASC_ADC 0x100000 +#define ADC_WAIT_TSI_1 0x300001 +#define ADC_NO_ADTRIG 0x200000 + +/* + * ADC 2 - 4 + */ +#define ADD1_RESULT_MASK 0x00000FFC +#define ADD2_RESULT_MASK 0x00FFC000 +#define ADC_TS_MASK 0x00FFCFFC + +#define ADC_WCOMP 0x040000 +#define ADC_WCOMP_H_POS 0 +#define ADC_WCOMP_L_POS 9 +#define ADC_WCOMP_H_MASK 0x00003F +#define ADC_WCOMP_L_MASK 0x007E00 + +#define ADC_MODE_MASK 0x00003F + +#define ADC_INT_BISDONEI 0x02 + +typedef enum adc_state { + ADC_FREE, + ADC_USED, + ADC_MONITORING, +} t_adc_state; + +typedef enum reading_mode { + /*! + * Enables lithium cell reading + */ + M_LITHIUM_CELL = 0x000001, + /*! + * Enables charge current reading + */ + M_CHARGE_CURRENT = 0x000002, + /*! + * Enables battery current reading + */ + M_BATTERY_CURRENT = 0x000004, +} t_reading_mode; + +typedef struct { + /*! + * Delay before first conversion + */ + unsigned int delay; + /*! + * sets the ATX bit for delay on all conversion + */ + bool conv_delay; + /*! + * Sets the single channel mode + */ + bool single_channel; + /*! + * Channel selection 1 + */ + t_channel channel_0; + /*! + * Channel selection 2 + */ + t_channel channel_1; + /*! + * Used to configure ADC mode with t_reading_mode + */ + t_reading_mode read_mode; + /*! + * Sets the Touch screen mode + */ + bool read_ts; + /*! + * Wait TSI event before touch screen reading + */ + bool wait_tsi; + /*! + * Sets CHRGRAW scaling to divide by 5 + * Only supported on 2.0 and higher + */ + bool chrgraw_devide_5; + /*! + * Return ADC values + */ + unsigned int value[8]; + /*! + * Return touch screen values + */ + t_touch_screen ts_value; +} t_adc_param; + +static int pmic_adc_filter(t_touch_screen *ts_curr); +int mc13892_adc_request(bool read_ts); +int mc13892_adc_release(int adc_index); +t_reading_mode mc13892_set_read_mode(t_channel channel); +PMIC_STATUS mc13892_adc_read_ts(t_touch_screen *touch_sample, int wait_tsi); + +/* internal function */ +static void callback_tsi(void *); +static void callback_adcdone(void *); +static void callback_adcbisdone(void *); + +static int swait; + +static int suspend_flag; + +static wait_queue_head_t suspendq; + +/* EXPORTED FUNCTIONS */ +EXPORT_SYMBOL(pmic_adc_init); +EXPORT_SYMBOL(pmic_adc_deinit); +EXPORT_SYMBOL(pmic_adc_convert); +EXPORT_SYMBOL(pmic_adc_convert_8x); +EXPORT_SYMBOL(pmic_adc_set_touch_mode); +EXPORT_SYMBOL(pmic_adc_get_touch_mode); +EXPORT_SYMBOL(pmic_adc_get_touch_sample); + +static DECLARE_COMPLETION(adcdone_it); +static DECLARE_COMPLETION(adcbisdone_it); +static DECLARE_COMPLETION(adc_tsi); +static pmic_event_callback_t tsi_event; +static pmic_event_callback_t event_adc; +static pmic_event_callback_t event_adc_bis; +static bool data_ready_adc_1; +static bool data_ready_adc_2; +static bool adc_ts; +static bool wait_ts; +static bool monitor_en; +static bool monitor_adc; +static DECLARE_MUTEX(convert_mutex); + +static DECLARE_WAIT_QUEUE_HEAD(queue_adc_busy); +static t_adc_state adc_dev[2]; + +static unsigned channel_num[] = { + 0, + 1, + 3, + 4, + 2, + 0, + 1, + 3, + 4, + -1, + 5, + 6, + 7, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 +}; + +static bool pmic_adc_ready; + +int is_pmic_adc_ready() +{ + return pmic_adc_ready; +} +EXPORT_SYMBOL(is_pmic_adc_ready); + + +static int pmic_adc_suspend(struct platform_device *pdev, pm_message_t state) +{ + suspend_flag = 1; + CHECK_ERROR(pmic_write_reg(REG_ADC0, DEF_ADC_0, PMIC_ALL_BITS)); + CHECK_ERROR(pmic_write_reg(REG_ADC1, 0, PMIC_ALL_BITS)); + CHECK_ERROR(pmic_write_reg(REG_ADC2, 0, PMIC_ALL_BITS)); + CHECK_ERROR(pmic_write_reg(REG_ADC3, DEF_ADC_3, PMIC_ALL_BITS)); + CHECK_ERROR(pmic_write_reg(REG_ADC4, 0, PMIC_ALL_BITS)); + + return 0; +}; + +static int pmic_adc_resume(struct platform_device *pdev) +{ + /* nothing for mc13892 adc */ + unsigned int adc_0_reg, adc_1_reg; + suspend_flag = 0; + + /* let interrupt of TSI again */ + adc_0_reg = ADC_WAIT_TSI_0; + CHECK_ERROR(pmic_write_reg(REG_ADC0, adc_0_reg, PMIC_ALL_BITS)); + adc_1_reg = ADC_WAIT_TSI_1 | (ADC_BIS * adc_ts); + CHECK_ERROR(pmic_write_reg(REG_ADC1, adc_1_reg, PMIC_ALL_BITS)); + + while (swait > 0) { + swait--; + wake_up_interruptible(&suspendq); + } + + return 0; +}; + +static void callback_tsi(void *unused) +{ + pr_debug("*** TSI IT mc13892 PMIC_ADC_GET_TOUCH_SAMPLE ***\n"); + if (wait_ts) { + complete(&adc_tsi); + pmic_event_mask(EVENT_TSI); + } +} + +static void callback_adcdone(void *unused) +{ + if (data_ready_adc_1) + complete(&adcdone_it); +} + +static void callback_adcbisdone(void *unused) +{ + pr_debug("* adcdone bis it callback *\n"); + if (data_ready_adc_2) + complete(&adcbisdone_it); +} + +static int pmic_adc_filter(t_touch_screen *ts_curr) +{ + unsigned int ydiff, xdiff; + unsigned int sample_sumx, sample_sumy; + + if (ts_curr->contact_resistance == 0) { + ts_curr->x_position = 0; + ts_curr->y_position = 0; + return 0; + } + + ydiff = abs(ts_curr->y_position1 - ts_curr->y_position2); + if (ydiff > DELTA_Y_MAX) { + pr_debug("pmic_adc_filter: Ret pos y\n"); + return -1; + } + + xdiff = abs(ts_curr->x_position1 - ts_curr->x_position2); + if (xdiff > DELTA_X_MAX) { + pr_debug("mc13892_adc_filter: Ret pos x\n"); + return -1; + } + + sample_sumx = ts_curr->x_position1 + ts_curr->x_position2; + sample_sumy = ts_curr->y_position1 + ts_curr->y_position2; + + ts_curr->y_position = sample_sumy / 2; + ts_curr->x_position = sample_sumx / 2; + + return 0; +} + +int pmic_adc_init(void) +{ + unsigned int reg_value = 0, i = 0; + + if (suspend_flag == 1) + return -EBUSY; + + for (i = 0; i < ADC_NB_AVAILABLE; i++) + adc_dev[i] = ADC_FREE; + + CHECK_ERROR(pmic_write_reg(REG_ADC0, DEF_ADC_0, PMIC_ALL_BITS)); + CHECK_ERROR(pmic_write_reg(REG_ADC1, 0, PMIC_ALL_BITS)); + CHECK_ERROR(pmic_write_reg(REG_ADC2, 0, PMIC_ALL_BITS)); + CHECK_ERROR(pmic_write_reg(REG_ADC3, DEF_ADC_3, PMIC_ALL_BITS)); + CHECK_ERROR(pmic_write_reg(REG_ADC4, 0, PMIC_ALL_BITS)); + reg_value = 0x001000; + + data_ready_adc_1 = false; + data_ready_adc_2 = false; + adc_ts = false; + wait_ts = false; + monitor_en = false; + monitor_adc = false; + + /* sub to ADCDone IT */ + event_adc.param = NULL; + event_adc.func = callback_adcdone; + CHECK_ERROR(pmic_event_subscribe(EVENT_ADCDONEI, event_adc)); + + /* sub to ADCDoneBis IT */ + event_adc_bis.param = NULL; + event_adc_bis.func = callback_adcbisdone; + CHECK_ERROR(pmic_event_subscribe(EVENT_ADCBISDONEI, event_adc_bis)); + + /* sub to Touch Screen IT */ + tsi_event.param = NULL; + tsi_event.func = callback_tsi; + CHECK_ERROR(pmic_event_subscribe(EVENT_TSI, tsi_event)); + + return PMIC_SUCCESS; +} + +PMIC_STATUS pmic_adc_deinit(void) +{ + CHECK_ERROR(pmic_event_unsubscribe(EVENT_ADCDONEI, event_adc)); + CHECK_ERROR(pmic_event_unsubscribe(EVENT_ADCBISDONEI, event_adc_bis)); + CHECK_ERROR(pmic_event_unsubscribe(EVENT_TSI, tsi_event)); + + return PMIC_SUCCESS; +} + +int mc13892_adc_init_param(t_adc_param * adc_param) +{ + int i = 0; + + if (suspend_flag == 1) + return -EBUSY; + + adc_param->delay = 0; + adc_param->conv_delay = false; + adc_param->single_channel = false; + adc_param->channel_0 = BATTERY_VOLTAGE; + adc_param->channel_1 = BATTERY_VOLTAGE; + adc_param->read_mode = 0; + adc_param->wait_tsi = 0; + adc_param->chrgraw_devide_5 = true; + adc_param->read_ts = false; + adc_param->ts_value.x_position = 0; + adc_param->ts_value.y_position = 0; + adc_param->ts_value.contact_resistance = 0; + for (i = 0; i <= MAX_CHANNEL; i++) + adc_param->value[i] = 0; + + return 0; +} + +PMIC_STATUS mc13892_adc_convert(t_adc_param * adc_param) +{ + bool use_bis = false; + unsigned int adc_0_reg = 0, adc_1_reg = 0, reg_1 = 0, result_reg = + 0, i = 0; + unsigned int result = 0, temp = 0; + pmic_version_t mc13892_ver; + pr_debug("mc13892 ADC - mc13892_adc_convert ....\n"); + if (suspend_flag == 1) + return -EBUSY; + + if (adc_param->wait_tsi) { + /* configure adc to wait tsi interrupt */ + INIT_COMPLETION(adc_tsi); + + /*for ts don't use bis */ + /*put ts in interrupt mode */ + /* still kep reference? */ + adc_0_reg = 0x001400 | (ADC_BIS * 0); + pmic_event_unmask(EVENT_TSI); + CHECK_ERROR(pmic_write_reg(REG_ADC0, adc_0_reg, PMIC_ALL_BITS)); + /*for ts don't use bis */ + adc_1_reg = 0x200001 | (ADC_BIS * 0); + CHECK_ERROR(pmic_write_reg(REG_ADC1, adc_1_reg, PMIC_ALL_BITS)); + pr_debug("wait tsi ....\n"); + wait_ts = true; + wait_for_completion_interruptible(&adc_tsi); + wait_ts = false; + } + if (adc_param->read_ts == false) + down(&convert_mutex); + use_bis = mc13892_adc_request(adc_param->read_ts); + if (use_bis < 0) { + pr_debug("process has received a signal and got interrupted\n"); + return -EINTR; + } + + /* CONFIGURE ADC REG 0 */ + adc_0_reg = 0; + adc_1_reg = 0; + if (adc_param->read_ts == false) { + adc_0_reg = adc_param->read_mode & 0x00003F; + /* add auto inc */ + adc_0_reg |= ADC_INC; + if (use_bis) { + /* add adc bis */ + adc_0_reg |= ADC_BIS; + } + mc13892_ver = pmic_get_version(); + if (mc13892_ver.revision >= 20) + if (adc_param->chrgraw_devide_5) + adc_0_reg |= ADC_CHRGRAW_D5; + + if (adc_param->single_channel) + adc_1_reg |= ADC_SGL_CH; + + if (adc_param->conv_delay) + adc_1_reg |= ADC_ATO; + + if (adc_param->single_channel) + adc_1_reg |= ADC_SGL_CH; + + adc_1_reg |= (adc_param->channel_0 << ADC_CH_0_POS) & + ADC_CH_0_MASK; + adc_1_reg |= (adc_param->channel_1 << ADC_CH_1_POS) & + ADC_CH_1_MASK; + } else { + adc_0_reg = 0x002400 | (ADC_BIS * use_bis) | ADC_INC; + } + pr_debug("Write Reg %i = %x\n", REG_ADC0, adc_0_reg); + /*Change has been made here */ + CHECK_ERROR(pmic_write_reg(REG_ADC0, adc_0_reg, + ADC_INC | ADC_BIS | ADC_CHRGRAW_D5 | + 0xfff00ff)); + /* CONFIGURE ADC REG 1 */ + if (adc_param->read_ts == false) { + adc_1_reg |= ADC_NO_ADTRIG; + adc_1_reg |= ADC_EN; + adc_1_reg |= (adc_param->delay << ADC_DELAY_POS) & + ADC_DELAY_MASK; + if (use_bis) + adc_1_reg |= ADC_BIS; + } else { + /* configure and start convert to read x and y position */ + /* configure to read 2 value in channel selection 1 & 2 */ + adc_1_reg = 0x100409 | (ADC_BIS * use_bis) | ADC_NO_ADTRIG; + /* set ATOx = 5, it could be better for ts ADC */ + adc_1_reg |= 0x002800; + } + reg_1 = adc_1_reg; + if (use_bis == 0) { + data_ready_adc_1 = false; + adc_1_reg |= ASC_ADC; + data_ready_adc_1 = true; + pr_debug("Write Reg %i = %x\n", REG_ADC1, adc_1_reg); + INIT_COMPLETION(adcdone_it); + CHECK_ERROR(pmic_write_reg(REG_ADC1, adc_1_reg, + ADC_SGL_CH | ADC_ATO | ADC_ADSEL + | ADC_CH_0_MASK | ADC_CH_1_MASK | + ADC_NO_ADTRIG | ADC_EN | + ADC_DELAY_MASK | ASC_ADC | ADC_BIS)); + pr_debug("wait adc done \n"); + wait_for_completion_interruptible(&adcdone_it); + data_ready_adc_1 = false; + } else { + data_ready_adc_2 = false; + adc_1_reg |= ASC_ADC; + data_ready_adc_2 = true; + INIT_COMPLETION(adcbisdone_it); + CHECK_ERROR(pmic_write_reg(REG_ADC1, adc_1_reg, 0xFFFFFF)); + temp = 0x800000; + CHECK_ERROR(pmic_write_reg(REG_ADC3, temp, 0xFFFFFF)); + pr_debug("wait adc done bis\n"); + wait_for_completion_interruptible(&adcbisdone_it); + data_ready_adc_2 = false; + } + /* read result and store in adc_param */ + result = 0; + if (use_bis == 0) + result_reg = REG_ADC2; + else + result_reg = REG_ADC4; + + CHECK_ERROR(pmic_write_reg(REG_ADC1, 4 << ADC_CH_1_POS, + ADC_CH_0_MASK | ADC_CH_1_MASK)); + + for (i = 0; i <= 3; i++) { + CHECK_ERROR(pmic_read_reg(result_reg, &result, PMIC_ALL_BITS)); + adc_param->value[i] = ((result & ADD1_RESULT_MASK) >> 2); + adc_param->value[i + 4] = ((result & ADD2_RESULT_MASK) >> 14); + pr_debug("value[%d] = %d, value[%d] = %d\n", + i, adc_param->value[i], + i + 4, adc_param->value[i + 4]); + } + if (adc_param->read_ts) { + adc_param->ts_value.x_position = adc_param->value[0]; + adc_param->ts_value.x_position1 = adc_param->value[0]; + adc_param->ts_value.x_position2 = adc_param->value[1]; + adc_param->ts_value.y_position = adc_param->value[3]; + adc_param->ts_value.y_position1 = adc_param->value[3]; + adc_param->ts_value.y_position2 = adc_param->value[4]; + adc_param->ts_value.contact_resistance = adc_param->value[6]; + } + + /*if (adc_param->read_ts) { + adc_param->ts_value.x_position = adc_param->value[2]; + adc_param->ts_value.y_position = adc_param->value[5]; + adc_param->ts_value.contact_resistance = adc_param->value[6]; + } */ + mc13892_adc_release(use_bis); + if (adc_param->read_ts == false) + up(&convert_mutex); + + return PMIC_SUCCESS; +} + +t_reading_mode mc13892_set_read_mode(t_channel channel) +{ + t_reading_mode read_mode = 0; + + switch (channel) { + case CHARGE_CURRENT: + read_mode = M_CHARGE_CURRENT; + break; + case BATTERY_CURRENT: + read_mode = M_BATTERY_CURRENT; + break; + default: + read_mode = 0; + } + + return read_mode; +} + +PMIC_STATUS pmic_adc_convert(t_channel channel, unsigned short *result) +{ + t_adc_param adc_param; + PMIC_STATUS ret; + + if (suspend_flag == 1) + return -EBUSY; + + channel = channel_num[channel]; + if (channel == -1) { + pr_debug("Wrong channel ID\n"); + return PMIC_PARAMETER_ERROR; + } + mc13892_adc_init_param(&adc_param); + pr_debug("pmic_adc_convert\n"); + adc_param.read_ts = false; + adc_param.single_channel = true; + adc_param.read_mode = mc13892_set_read_mode(channel); + + /* Find the group */ + if (channel <= 7) + adc_param.channel_0 = channel; + else + return PMIC_PARAMETER_ERROR; + + ret = mc13892_adc_convert(&adc_param); + *result = adc_param.value[0]; + return ret; +} + +PMIC_STATUS pmic_adc_convert_8x(t_channel channel, unsigned short *result) +{ + t_adc_param adc_param; + int i; + PMIC_STATUS ret; + if (suspend_flag == 1) + return -EBUSY; + + channel = channel_num[channel]; + + if (channel == -1) { + pr_debug("Wrong channel ID\n"); + return PMIC_PARAMETER_ERROR; + } + mc13892_adc_init_param(&adc_param); + pr_debug("pmic_adc_convert_8x\n"); + adc_param.read_ts = false; + adc_param.single_channel = true; + adc_param.read_mode = mc13892_set_read_mode(channel); + + if (channel <= 7) { + adc_param.channel_0 = channel; + adc_param.channel_1 = channel; + } else + return PMIC_PARAMETER_ERROR; + + ret = mc13892_adc_convert(&adc_param); + for (i = 0; i <= 7; i++) + result[i] = adc_param.value[i]; + + return ret; +} + +PMIC_STATUS pmic_adc_set_touch_mode(t_touch_mode touch_mode) +{ + if (suspend_flag == 1) + return -EBUSY; + + CHECK_ERROR(pmic_write_reg(REG_ADC0, + BITFVAL(MC13892_ADC0_TS_M, touch_mode), + BITFMASK(MC13892_ADC0_TS_M))); + return PMIC_SUCCESS; +} + +PMIC_STATUS pmic_adc_get_touch_mode(t_touch_mode * touch_mode) +{ + unsigned int value; + if (suspend_flag == 1) + return -EBUSY; + + CHECK_ERROR(pmic_read_reg(REG_ADC0, &value, PMIC_ALL_BITS)); + + *touch_mode = BITFEXT(value, MC13892_ADC0_TS_M); + + return PMIC_SUCCESS; +} + +PMIC_STATUS pmic_adc_get_touch_sample(t_touch_screen *touch_sample, int wait) +{ + if (mc13892_adc_read_ts(touch_sample, wait) != 0) + return PMIC_ERROR; + if (0 == pmic_adc_filter(touch_sample)) + return PMIC_SUCCESS; + else + return PMIC_ERROR; +} + +PMIC_STATUS mc13892_adc_read_ts(t_touch_screen *ts_value, int wait_tsi) +{ + t_adc_param param; + pr_debug("mc13892_adc : mc13892_adc_read_ts\n"); + if (suspend_flag == 1) + return -EBUSY; + + if (wait_ts) { + pr_debug("mc13892_adc : error TS busy \n"); + return PMIC_ERROR; + } + mc13892_adc_init_param(¶m); + param.wait_tsi = wait_tsi; + param.read_ts = true; + if (mc13892_adc_convert(¶m) != 0) + return PMIC_ERROR; + /* check if x-y is ok */ + if (param.ts_value.contact_resistance < 1000) { + ts_value->x_position = param.ts_value.x_position; + ts_value->x_position1 = param.ts_value.x_position1; + ts_value->x_position2 = param.ts_value.x_position2; + + ts_value->y_position = param.ts_value.y_position; + ts_value->y_position1 = param.ts_value.y_position1; + ts_value->y_position2 = param.ts_value.y_position2; + + ts_value->contact_resistance = + param.ts_value.contact_resistance + 1; + + } else { + ts_value->x_position = 0; + ts_value->y_position = 0; + ts_value->contact_resistance = 0; + + } + return PMIC_SUCCESS; +} + +int mc13892_adc_request(bool read_ts) +{ + int adc_index = -1; + if (read_ts != 0) { + /*for ts we use bis=0 */ + if (adc_dev[0] == ADC_USED) + return -1; + /*no wait here */ + adc_dev[0] = ADC_USED; + adc_index = 0; + } else { + /*for other adc use bis = 1 */ + if (adc_dev[1] == ADC_USED) { + return -1; + /*no wait here */ + } + adc_dev[1] = ADC_USED; + adc_index = 1; + } + pr_debug("mc13892_adc : request ADC %d\n", adc_index); + return adc_index; +} + +int mc13892_adc_release(int adc_index) +{ + while (suspend_flag == 1) { + swait++; + /* Block if the device is suspended */ + if (wait_event_interruptible(suspendq, (suspend_flag == 0))) + return -ERESTARTSYS; + } + + pr_debug("mc13892_adc : release ADC %d\n", adc_index); + if ((adc_dev[adc_index] == ADC_MONITORING) || + (adc_dev[adc_index] == ADC_USED)) { + adc_dev[adc_index] = ADC_FREE; + wake_up(&queue_adc_busy); + return 0; + } + return -1; +} + +#ifdef DEBUG +static t_adc_param adc_param_db; + +static ssize_t adc_info(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int *value = adc_param_db.value; + + pr_debug("adc_info\n"); + + pr_debug("ch0\t\t%d\n", adc_param_db.channel_0); + pr_debug("ch1\t\t%d\n", adc_param_db.channel_1); + pr_debug("d5\t\t%d\n", adc_param_db.chrgraw_devide_5); + pr_debug("conv delay\t%d\n", adc_param_db.conv_delay); + pr_debug("delay\t\t%d\n", adc_param_db.delay); + pr_debug("read mode\t%d\n", adc_param_db.read_mode); + pr_debug("read ts\t\t%d\n", adc_param_db.read_ts); + pr_debug("single ch\t%d\n", adc_param_db.single_channel); + pr_debug("wait ts int\t%d\n", adc_param_db.wait_tsi); + pr_debug("value0-3:\t%d\t%d\t%d\t%d\n", value[0], value[1], + value[2], value[3]); + pr_debug("value4-7:\t%d\t%d\t%d\t%d\n", value[4], value[5], + value[6], value[7]); + + return 0; +} + +enum { + ADC_SET_CH0 = 0, + ADC_SET_CH1, + ADC_SET_DV5, + ADC_SET_CON_DELAY, + ADC_SET_DELAY, + ADC_SET_RM, + ADC_SET_RT, + ADC_SET_S_CH, + ADC_SET_WAIT_TS, + ADC_INIT_P, + ADC_START, + ADC_TS, + ADC_TS_READ, + ADC_TS_CAL, + ADC_CMD_MAX +}; + +static const char *const adc_cmd[ADC_CMD_MAX] = { + [ADC_SET_CH0] = "ch0", + [ADC_SET_CH1] = "ch1", + [ADC_SET_DV5] = "dv5", + [ADC_SET_CON_DELAY] = "cd", + [ADC_SET_DELAY] = "dl", + [ADC_SET_RM] = "rm", + [ADC_SET_RT] = "rt", + [ADC_SET_S_CH] = "sch", + [ADC_SET_WAIT_TS] = "wt", + [ADC_INIT_P] = "init", + [ADC_START] = "start", + [ADC_TS] = "touch", + [ADC_TS_READ] = "touchr", + [ADC_TS_CAL] = "cal" +}; + +static int cmd(unsigned int index, int value) +{ + t_touch_screen ts; + + switch (index) { + case ADC_SET_CH0: + adc_param_db.channel_0 = value; + break; + case ADC_SET_CH1: + adc_param_db.channel_1 = value; + break; + case ADC_SET_DV5: + adc_param_db.chrgraw_devide_5 = value; + break; + case ADC_SET_CON_DELAY: + adc_param_db.conv_delay = value; + break; + case ADC_SET_RM: + adc_param_db.read_mode = value; + break; + case ADC_SET_RT: + adc_param_db.read_ts = value; + break; + case ADC_SET_S_CH: + adc_param_db.single_channel = value; + break; + case ADC_SET_WAIT_TS: + adc_param_db.wait_tsi = value; + break; + case ADC_INIT_P: + mc13892_adc_init_param(&adc_param_db); + break; + case ADC_START: + mc13892_adc_convert(&adc_param_db); + break; + case ADC_TS: + pmic_adc_get_touch_sample(&ts, 1); + pr_debug("x = %d\n", ts.x_position); + pr_debug("y = %d\n", ts.y_position); + pr_debug("p = %d\n", ts.contact_resistance); + break; + case ADC_TS_READ: + pmic_adc_get_touch_sample(&ts, 0); + pr_debug("x = %d\n", ts.x_position); + pr_debug("y = %d\n", ts.y_position); + pr_debug("p = %d\n", ts.contact_resistance); + break; + case ADC_TS_CAL: + break; + default: + pr_debug("error command\n"); + break; + } + return 0; +} + +static ssize_t adc_ctl(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + int state = 0; + const char *const *s; + char *p, *q; + int error; + int len, value = 0; + + pr_debug("adc_ctl\n"); + + q = NULL; + q = memchr(buf, ' ', count); + + if (q != NULL) { + len = q - buf; + q += 1; + value = simple_strtoul(q, NULL, 10); + } else { + p = memchr(buf, '\n', count); + len = p ? p - buf : count; + } + + for (s = &adc_cmd[state]; state < ADC_CMD_MAX; s++, state++) { + if (*s && !strncmp(buf, *s, len)) + break; + } + if (state < ADC_CMD_MAX && *s) + error = cmd(state, value); + else + error = -EINVAL; + + return count; +} + +#else +static ssize_t adc_info(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return 0; +} + +static ssize_t adc_ctl(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + return count; +} + +#endif + +static DEVICE_ATTR(adc, 0644, adc_info, adc_ctl); + +static int pmic_adc_module_probe(struct platform_device *pdev) +{ + int ret = 0; + + pr_debug("PMIC ADC start probe\n"); + ret = device_create_file(&(pdev->dev), &dev_attr_adc); + if (ret) { + pr_debug("Can't create device file!\n"); + return -ENODEV; + } + + init_waitqueue_head(&suspendq); + + ret = pmic_adc_init(); + if (ret != PMIC_SUCCESS) { + pr_debug("Error in pmic_adc_init.\n"); + goto rm_dev_file; + } + + pmic_adc_ready = 1; + pr_debug("PMIC ADC successfully probed\n"); + return 0; + + rm_dev_file: + device_remove_file(&(pdev->dev), &dev_attr_adc); + return ret; +} + +static int pmic_adc_module_remove(struct platform_device *pdev) +{ + pmic_adc_deinit(); + pmic_adc_ready = 0; + pr_debug("PMIC ADC successfully removed\n"); + return 0; +} + +static struct platform_driver pmic_adc_driver_ldm = { + .driver = { + .name = "pmic_adc", + }, + .suspend = pmic_adc_suspend, + .resume = pmic_adc_resume, + .probe = pmic_adc_module_probe, + .remove = pmic_adc_module_remove, +}; + +static int __init pmic_adc_module_init(void) +{ + pr_debug("PMIC ADC driver loading...\n"); + return platform_driver_register(&pmic_adc_driver_ldm); +} + +static void __exit pmic_adc_module_exit(void) +{ + platform_driver_unregister(&pmic_adc_driver_ldm); + pr_debug("PMIC ADC driver successfully unloaded\n"); +} + +module_init(pmic_adc_module_init); +module_exit(pmic_adc_module_exit); + +MODULE_DESCRIPTION("PMIC ADC device driver"); +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/mxc/pmic/mc13892/pmic_light.c +++ linux-2.6.28/drivers/mxc/pmic/mc13892/pmic_light.c @@ -0,0 +1,685 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @file mc13892/pmic_light.c + * @brief This is the main file of PMIC(mc13783) Light and Backlight driver. + * + * @ingroup PMIC_LIGHT + */ + +/* + * Includes + */ +#define DEBUG +#include +#include +#include +#include +#include + +#define BIT_CL_MAIN_LSH 9 +#define BIT_CL_AUX_LSH 21 +#define BIT_CL_KEY_LSH 9 +#define BIT_CL_RED_LSH 9 +#define BIT_CL_GREEN_LSH 21 +#define BIT_CL_BLUE_LSH 9 + +#define BIT_CL_MAIN_WID 3 +#define BIT_CL_AUX_WID 3 +#define BIT_CL_KEY_WID 3 +#define BIT_CL_RED_WID 3 +#define BIT_CL_GREEN_WID 3 +#define BIT_CL_BLUE_WID 3 + +#define BIT_DC_MAIN_LSH 3 +#define BIT_DC_AUX_LSH 15 +#define BIT_DC_KEY_LSH 3 +#define BIT_DC_RED_LSH 3 +#define BIT_DC_GREEN_LSH 15 +#define BIT_DC_BLUE_LSH 3 + +#define BIT_DC_MAIN_WID 6 +#define BIT_DC_AUX_WID 6 +#define BIT_DC_KEY_WID 6 +#define BIT_DC_RED_WID 6 +#define BIT_DC_GREEN_WID 6 +#define BIT_DC_BLUE_WID 6 + +#define BIT_RP_MAIN_LSH 2 +#define BIT_RP_AUX_LSH 14 +#define BIT_RP_KEY_LSH 2 +#define BIT_RP_RED_LSH 2 +#define BIT_RP_GREEN_LSH 14 +#define BIT_RP_BLUE_LSH 2 + +#define BIT_RP_MAIN_WID 1 +#define BIT_RP_AUX_WID 1 +#define BIT_RP_KEY_WID 1 +#define BIT_RP_RED_WID 1 +#define BIT_RP_GREEN_WID 1 +#define BIT_RP_BLUE_WID 1 + +#define BIT_HC_MAIN_LSH 1 +#define BIT_HC_AUX_LSH 13 +#define BIT_HC_KEY_LSH 1 + +#define BIT_HC_MAIN_WID 1 +#define BIT_HC_AUX_WID 1 +#define BIT_HC_KEY_WID 1 + +#define BIT_BP_RED_LSH 0 +#define BIT_BP_GREEN_LSH 12 +#define BIT_BP_BLUE_LSH 0 + +#define BIT_BP_RED_WID 2 +#define BIT_BP_GREEN_WID 2 +#define BIT_BP_BLUE_WID 2 + +int pmic_light_init_reg(void) +{ + CHECK_ERROR(pmic_write_reg(REG_LED_CTL0, 0, PMIC_ALL_BITS)); + CHECK_ERROR(pmic_write_reg(REG_LED_CTL1, 0, PMIC_ALL_BITS)); + CHECK_ERROR(pmic_write_reg(REG_LED_CTL2, 0, PMIC_ALL_BITS)); + CHECK_ERROR(pmic_write_reg(REG_LED_CTL3, 0, PMIC_ALL_BITS)); + + return 0; +} + +static int pmic_light_suspend(struct platform_device *dev, pm_message_t state) +{ + return 0; +}; + +static int pmic_light_resume(struct platform_device *pdev) +{ + return 0; +}; + +PMIC_STATUS mc13892_bklit_set_hi_current(enum lit_channel channel, int mode) +{ + unsigned int mask; + unsigned int value; + int reg; + + switch (channel) { + case LIT_MAIN: + value = BITFVAL(BIT_HC_MAIN, mode); + mask = BITFMASK(BIT_HC_MAIN); + reg = REG_LED_CTL0; + break; + case LIT_AUX: + value = BITFVAL(BIT_HC_AUX, mode); + mask = BITFMASK(BIT_HC_AUX); + reg = REG_LED_CTL0; + break; + case LIT_KEY: + value = BITFVAL(BIT_HC_KEY, mode); + mask = BITFMASK(BIT_HC_KEY); + reg = REG_LED_CTL1; + break; + default: + return PMIC_PARAMETER_ERROR; + } + CHECK_ERROR(pmic_write_reg(reg, value, mask)); + return PMIC_SUCCESS; +} + +PMIC_STATUS mc13892_bklit_get_hi_current(enum lit_channel channel, int *mode) +{ + unsigned int mask; + int reg; + + switch (channel) { + case LIT_MAIN: + mask = BITFMASK(BIT_HC_MAIN); + reg = REG_LED_CTL0; + break; + case LIT_AUX: + mask = BITFMASK(BIT_HC_AUX); + reg = REG_LED_CTL0; + break; + case LIT_KEY: + mask = BITFMASK(BIT_HC_KEY); + reg = REG_LED_CTL1; + break; + default: + return PMIC_PARAMETER_ERROR; + } + + CHECK_ERROR(pmic_read_reg(reg, mode, mask)); + return PMIC_SUCCESS; +} + +PMIC_STATUS mc13892_bklit_set_current(enum lit_channel channel, + unsigned char level) +{ + unsigned int mask; + unsigned int value; + int reg; + + if (level > LIT_CURR_HI_42) + return PMIC_PARAMETER_ERROR; + else if (level >= LIT_CURR_HI_0) { + CHECK_ERROR(mc13892_bklit_set_hi_current(channel, 1)); + level -= LIT_CURR_HI_0; + } + + switch (channel) { + case LIT_MAIN: + value = BITFVAL(BIT_CL_MAIN, level); + mask = BITFMASK(BIT_CL_MAIN); + reg = REG_LED_CTL0; + break; + case LIT_AUX: + value = BITFVAL(BIT_CL_AUX, level); + mask = BITFMASK(BIT_CL_AUX); + reg = REG_LED_CTL0; + break; + case LIT_KEY: + value = BITFVAL(BIT_CL_KEY, level); + mask = BITFMASK(BIT_CL_KEY); + reg = REG_LED_CTL1; + break; + case LIT_RED: + value = BITFVAL(BIT_CL_RED, level); + mask = BITFMASK(BIT_CL_RED); + reg = REG_LED_CTL2; + break; + case LIT_GREEN: + value = BITFVAL(BIT_CL_GREEN, level); + mask = BITFMASK(BIT_CL_GREEN); + reg = REG_LED_CTL2; + break; + case LIT_BLUE: + value = BITFVAL(BIT_CL_BLUE, level); + mask = BITFMASK(BIT_CL_BLUE); + reg = REG_LED_CTL3; + break; + default: + return PMIC_PARAMETER_ERROR; + } + CHECK_ERROR(pmic_write_reg(reg, value, mask)); + + return PMIC_SUCCESS; +} + +PMIC_STATUS mc13892_bklit_get_current(enum lit_channel channel, + unsigned char *level) +{ + unsigned int reg_value = 0; + unsigned int mask = 0; + int reg, mode; + + CHECK_ERROR(mc13892_bklit_get_hi_current(channel, &mode)); + + switch (channel) { + case LIT_MAIN: + mask = BITFMASK(BIT_CL_MAIN); + reg = REG_LED_CTL0; + break; + case LIT_AUX: + mask = BITFMASK(BIT_CL_AUX); + reg = REG_LED_CTL0; + break; + case LIT_KEY: + mask = BITFMASK(BIT_CL_KEY); + reg = REG_LED_CTL1; + break; + case LIT_RED: + mask = BITFMASK(BIT_CL_RED); + reg = REG_LED_CTL2; + break; + case LIT_GREEN: + mask = BITFMASK(BIT_CL_GREEN); + reg = REG_LED_CTL2; + break; + case LIT_BLUE: + mask = BITFMASK(BIT_CL_BLUE); + reg = REG_LED_CTL3; + break; + default: + return PMIC_PARAMETER_ERROR; + } + + CHECK_ERROR(pmic_read_reg(reg, ®_value, mask)); + + switch (channel) { + case LIT_MAIN: + *level = BITFEXT(reg_value, BIT_CL_MAIN); + break; + case LIT_AUX: + *level = BITFEXT(reg_value, BIT_CL_AUX); + break; + case LIT_KEY: + *level = BITFEXT(reg_value, BIT_CL_KEY); + break; + case LIT_RED: + *level = BITFEXT(reg_value, BIT_CL_RED); + break; + case LIT_GREEN: + *level = BITFEXT(reg_value, BIT_CL_GREEN); + break; + case LIT_BLUE: + *level = BITFEXT(reg_value, BIT_CL_BLUE); + break; + default: + return PMIC_PARAMETER_ERROR; + } + + if (mode == 1) + *level += LIT_CURR_HI_0; + + return PMIC_SUCCESS; +} + +PMIC_STATUS mc13892_bklit_set_dutycycle(enum lit_channel channel, + unsigned char dc) +{ + unsigned int mask; + unsigned int value; + int reg; + + switch (channel) { + case LIT_MAIN: + value = BITFVAL(BIT_DC_MAIN, dc); + mask = BITFMASK(BIT_DC_MAIN); + reg = REG_LED_CTL0; + break; + case LIT_AUX: + value = BITFVAL(BIT_DC_AUX, dc); + mask = BITFMASK(BIT_DC_AUX); + reg = REG_LED_CTL0; + break; + case LIT_KEY: + value = BITFVAL(BIT_DC_KEY, dc); + mask = BITFMASK(BIT_DC_KEY); + reg = REG_LED_CTL1; + break; + case LIT_RED: + value = BITFVAL(BIT_DC_RED, dc); + mask = BITFMASK(BIT_DC_RED); + reg = REG_LED_CTL2; + break; + case LIT_GREEN: + value = BITFVAL(BIT_DC_GREEN, dc); + mask = BITFMASK(BIT_DC_GREEN); + reg = REG_LED_CTL2; + break; + case LIT_BLUE: + value = BITFVAL(BIT_DC_BLUE, dc); + mask = BITFMASK(BIT_DC_BLUE); + reg = REG_LED_CTL3; + break; + default: + return PMIC_PARAMETER_ERROR; + } + CHECK_ERROR(pmic_write_reg(reg, value, mask)); + return PMIC_SUCCESS; +} + +PMIC_STATUS mc13892_bklit_get_dutycycle(enum lit_channel channel, + unsigned char *dc) +{ + unsigned int mask; + int reg; + unsigned int reg_value = 0; + + switch (channel) { + case LIT_MAIN: + mask = BITFMASK(BIT_DC_MAIN); + reg = REG_LED_CTL0; + break; + case LIT_AUX: + mask = BITFMASK(BIT_DC_AUX); + reg = REG_LED_CTL0; + break; + case LIT_KEY: + mask = BITFMASK(BIT_DC_KEY); + reg = REG_LED_CTL1; + break; + case LIT_RED: + mask = BITFMASK(BIT_DC_RED); + reg = REG_LED_CTL2; + break; + case LIT_GREEN: + mask = BITFMASK(BIT_DC_GREEN); + reg = REG_LED_CTL2; + break; + case LIT_BLUE: + mask = BITFMASK(BIT_DC_BLUE); + reg = REG_LED_CTL3; + break; + default: + return PMIC_PARAMETER_ERROR; + } + + CHECK_ERROR(pmic_read_reg(reg, ®_value, mask)); + return PMIC_SUCCESS; +} + +PMIC_STATUS mc13892_bklit_set_ramp(enum lit_channel channel, int flag) +{ + unsigned int mask; + unsigned int value; + int reg; + + switch (channel) { + case LIT_MAIN: + value = BITFVAL(BIT_RP_MAIN, flag); + mask = BITFMASK(BIT_RP_MAIN); + reg = REG_LED_CTL0; + break; + case LIT_AUX: + value = BITFVAL(BIT_RP_AUX, flag); + mask = BITFMASK(BIT_RP_AUX); + reg = REG_LED_CTL0; + break; + case LIT_KEY: + value = BITFVAL(BIT_RP_KEY, flag); + mask = BITFMASK(BIT_RP_KEY); + reg = REG_LED_CTL1; + break; + case LIT_RED: + value = BITFVAL(BIT_RP_RED, flag); + mask = BITFMASK(BIT_RP_RED); + reg = REG_LED_CTL2; + break; + case LIT_GREEN: + value = BITFVAL(BIT_RP_GREEN, flag); + mask = BITFMASK(BIT_RP_GREEN); + reg = REG_LED_CTL2; + break; + case LIT_BLUE: + value = BITFVAL(BIT_RP_BLUE, flag); + mask = BITFMASK(BIT_RP_BLUE); + reg = REG_LED_CTL3; + break; + default: + return PMIC_PARAMETER_ERROR; + } + CHECK_ERROR(pmic_write_reg(reg, value, mask)); + return PMIC_SUCCESS; +} + +PMIC_STATUS mc13892_bklit_get_ramp(enum lit_channel channel, int *flag) +{ + unsigned int mask; + int reg; + + switch (channel) { + case LIT_MAIN: + mask = BITFMASK(BIT_RP_MAIN); + reg = REG_LED_CTL0; + break; + case LIT_AUX: + mask = BITFMASK(BIT_RP_AUX); + reg = REG_LED_CTL0; + break; + case LIT_KEY: + mask = BITFMASK(BIT_RP_KEY); + reg = REG_LED_CTL1; + break; + case LIT_RED: + mask = BITFMASK(BIT_RP_RED); + reg = REG_LED_CTL2; + break; + case LIT_GREEN: + mask = BITFMASK(BIT_RP_GREEN); + reg = REG_LED_CTL2; + break; + case LIT_BLUE: + mask = BITFMASK(BIT_RP_BLUE); + reg = REG_LED_CTL3; + break; + default: + return PMIC_PARAMETER_ERROR; + } + + CHECK_ERROR(pmic_read_reg(reg, flag, mask)); + return PMIC_SUCCESS; +} + +PMIC_STATUS mc13892_bklit_set_blink_p(enum lit_channel channel, int period) +{ + unsigned int mask; + unsigned int value; + int reg; + + switch (channel) { + case LIT_RED: + value = BITFVAL(BIT_BP_RED, period); + mask = BITFMASK(BIT_BP_RED); + reg = REG_LED_CTL2; + break; + case LIT_GREEN: + value = BITFVAL(BIT_BP_GREEN, period); + mask = BITFMASK(BIT_BP_GREEN); + reg = REG_LED_CTL2; + break; + case LIT_BLUE: + value = BITFVAL(BIT_BP_BLUE, period); + mask = BITFMASK(BIT_BP_BLUE); + reg = REG_LED_CTL3; + break; + default: + return PMIC_PARAMETER_ERROR; + } + CHECK_ERROR(pmic_write_reg(reg, value, mask)); + return PMIC_SUCCESS; +} + +PMIC_STATUS mc13892_bklit_get_blink_p(enum lit_channel channel, int *period) +{ + unsigned int mask; + int reg; + + switch (channel) { + case LIT_RED: + mask = BITFMASK(BIT_BP_RED); + reg = REG_LED_CTL2; + break; + case LIT_GREEN: + mask = BITFMASK(BIT_BP_GREEN); + reg = REG_LED_CTL2; + break; + case LIT_BLUE: + mask = BITFMASK(BIT_BP_BLUE); + reg = REG_LED_CTL3; + break; + default: + return PMIC_PARAMETER_ERROR; + } + + CHECK_ERROR(pmic_read_reg(reg, period, mask)); + return PMIC_SUCCESS; +} + +EXPORT_SYMBOL(mc13892_bklit_set_current); +EXPORT_SYMBOL(mc13892_bklit_get_current); +EXPORT_SYMBOL(mc13892_bklit_set_dutycycle); +EXPORT_SYMBOL(mc13892_bklit_get_dutycycle); +EXPORT_SYMBOL(mc13892_bklit_set_ramp); +EXPORT_SYMBOL(mc13892_bklit_get_ramp); +EXPORT_SYMBOL(mc13892_bklit_set_blink_p); +EXPORT_SYMBOL(mc13892_bklit_get_blink_p); + +static int pmic_light_remove(struct platform_device *pdev) +{ + return 0; +} + +#ifdef DEBUG +static ssize_t lit_info(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return 0; +} + +enum { + SET_CURR = 0, + SET_DC, + SET_RAMP, + SET_BP, + SET_CH, + LIT_CMD_MAX +}; + +static const char *const lit_cmd[LIT_CMD_MAX] = { + [SET_CURR] = "cur", + [SET_DC] = "dc", + [SET_RAMP] = "ra", + [SET_BP] = "bp", + [SET_CH] = "ch" +}; + +static int cmd(unsigned int index, int value) +{ + static int ch = LIT_MAIN; + int ret = 0; + + switch (index) { + case SET_CH: + ch = value; + break; + case SET_CURR: + pr_debug("set %d cur %d\n", ch, value); + ret = mc13892_bklit_set_current(ch, value); + break; + case SET_DC: + pr_debug("set %d dc %d\n", ch, value); + ret = mc13892_bklit_set_dutycycle(ch, value); + break; + case SET_RAMP: + pr_debug("set %d ramp %d\n", ch, value); + ret = mc13892_bklit_set_ramp(ch, value); + break; + case SET_BP: + pr_debug("set %d bp %d\n", ch, value); + ret = mc13892_bklit_set_blink_p(ch, value); + break; + default: + pr_debug("error command\n"); + break; + } + + if (ret == PMIC_SUCCESS) + pr_debug("command exec successfully!\n"); + + return 0; +} + +static ssize_t lit_ctl(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + int state = 0; + const char *const *s; + char *p, *q; + int error; + int len, value = 0; + + pr_debug("lit_ctl\n"); + + q = NULL; + q = memchr(buf, ' ', count); + + if (q != NULL) { + len = q - buf; + q += 1; + value = simple_strtoul(q, NULL, 10); + } else { + p = memchr(buf, '\n', count); + len = p ? p - buf : count; + } + + for (s = &lit_cmd[state]; state < LIT_CMD_MAX; s++, state++) { + if (*s && !strncmp(buf, *s, len)) + break; + } + if (state < LIT_CMD_MAX && *s) + error = cmd(state, value); + else + error = -EINVAL; + + return count; +} + +#else +static ssize_t lit_info(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return 0; +} + +static ssize_t lit_ctl(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + return count; +} + +#endif + +static DEVICE_ATTR(lit, 0644, lit_info, lit_ctl); + +static int pmic_light_probe(struct platform_device *pdev) +{ + int ret = 0; + + pr_debug("PMIC ADC start probe\n"); + ret = device_create_file(&(pdev->dev), &dev_attr_lit); + if (ret) { + pr_debug("Can't create device file!\n"); + return -ENODEV; + } + + pmic_light_init_reg(); + + pr_debug("PMIC Light successfully loaded\n"); + return 0; +} + +static struct platform_driver pmic_light_driver_ldm = { + .driver = { + .name = "pmic_light", + }, + .suspend = pmic_light_suspend, + .resume = pmic_light_resume, + .probe = pmic_light_probe, + .remove = pmic_light_remove, +}; + +/* + * Initialization and Exit + */ + +static int __init pmic_light_init(void) +{ + pr_debug("PMIC Light driver loading...\n"); + return platform_driver_register(&pmic_light_driver_ldm); +} +static void __exit pmic_light_exit(void) +{ + platform_driver_unregister(&pmic_light_driver_ldm); + pr_debug("PMIC Light driver successfully unloaded\n"); +} + +/* + * Module entry points + */ + +subsys_initcall(pmic_light_init); +module_exit(pmic_light_exit); + +MODULE_DESCRIPTION("PMIC_LIGHT"); +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/gpu/drm/drm_agpsupport.c +++ linux-2.6.28/drivers/gpu/drm/drm_agpsupport.c @@ -33,10 +33,11 @@ #include "drmP.h" #include -#include #if __OS_HAS_AGP +#include + /** * Get AGP information. * --- linux-2.6.28.orig/drivers/gpu/drm/drm_irq.c +++ linux-2.6.28/drivers/gpu/drm/drm_irq.c @@ -259,7 +259,8 @@ */ int drm_irq_uninstall(struct drm_device * dev) { - int irq_enabled; + unsigned long irqflags; + int irq_enabled, i; if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) return -EINVAL; @@ -269,6 +270,17 @@ dev->irq_enabled = 0; mutex_unlock(&dev->struct_mutex); + /* + * Wake up any waiters so they don't hang. + */ + spin_lock_irqsave(&dev->vbl_lock, irqflags); + for (i = 0; i < dev->num_crtcs; i++) { + DRM_WAKEUP(&dev->vbl_queue[i]); + dev->vblank_enabled[i] = 0; + dev->last_vblank[i] = dev->driver->get_vblank_counter(dev, i); + } + spin_unlock_irqrestore(&dev->vbl_lock, irqflags); + if (!irq_enabled) return -EINVAL; @@ -617,8 +629,9 @@ DRM_DEBUG("waiting on vblank count %d, crtc %d\n", vblwait->request.sequence, crtc); DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ, - ((drm_vblank_count(dev, crtc) - - vblwait->request.sequence) <= (1 << 23))); + (((drm_vblank_count(dev, crtc) - + vblwait->request.sequence) <= (1 << 23)) || + !dev->irq_enabled)); if (ret != -EINTR) { struct timeval now; --- linux-2.6.28.orig/drivers/gpu/drm/radeon/radeon_cp.c +++ linux-2.6.28/drivers/gpu/drm/radeon/radeon_cp.c @@ -42,6 +42,20 @@ static int radeon_do_cleanup_cp(struct drm_device * dev); static void radeon_do_cp_start(drm_radeon_private_t * dev_priv); +u32 RADEON_READ_MM(drm_radeon_private_t *dev_priv, int addr) +{ + u32 ret; + + if (addr < 0x10000) + ret = DRM_READ32(dev_priv->mmio, addr); + else { + DRM_WRITE32(dev_priv->mmio, RADEON_MM_INDEX, addr); + ret = DRM_READ32(dev_priv->mmio, RADEON_MM_DATA); + } + + return ret; +} + static u32 R500_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) { u32 ret; @@ -69,67 +83,107 @@ return ret; } +static u32 RS600_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) +{ + u32 ret; + RADEON_WRITE(RS600_MC_INDEX, ((addr & RS600_MC_ADDR_MASK) | + RS600_MC_IND_CITF_ARB0)); + ret = RADEON_READ(RS600_MC_DATA); + return ret; +} + static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) { if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) return RS690_READ_MCIND(dev_priv, addr); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) + return RS600_READ_MCIND(dev_priv, addr); else return RS480_READ_MCIND(dev_priv, addr); } u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) { - - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) + return RADEON_READ(R700_MC_VM_FB_LOCATION); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + return RADEON_READ(R600_MC_VM_FB_LOCATION); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION); else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) + return RS600_READ_MCIND(dev_priv, RS600_MC_FB_LOCATION); else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) return R500_READ_MCIND(dev_priv, R520_MC_FB_LOCATION); else return RADEON_READ(RADEON_MC_FB_LOCATION); } -static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) +void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) { - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) + RADEON_WRITE(R700_MC_VM_FB_LOCATION, fb_loc); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + RADEON_WRITE(R600_MC_VM_FB_LOCATION, fb_loc); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc); else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) + RS600_WRITE_MCIND(RS600_MC_FB_LOCATION, fb_loc); else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) R500_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc); else RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc); } -static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc) +void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc) { - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) + /*R6xx/R7xx: AGP_TOP and BOT are actually 18 bits each */ + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) { + RADEON_WRITE(R700_MC_VM_AGP_BOT, agp_loc & 0xffff); /* FIX ME */ + RADEON_WRITE(R700_MC_VM_AGP_TOP, (agp_loc >> 16) & 0xffff); + } else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { + RADEON_WRITE(R600_MC_VM_AGP_BOT, agp_loc & 0xffff); /* FIX ME */ + RADEON_WRITE(R600_MC_VM_AGP_TOP, (agp_loc >> 16) & 0xffff); + } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc); else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc); + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) + RS600_WRITE_MCIND(RS600_MC_AGP_LOCATION, agp_loc); else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) R500_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc); else RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc); } -static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base) +void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base) { u32 agp_base_hi = upper_32_bits(agp_base); u32 agp_base_lo = agp_base & 0xffffffff; + u32 r6xx_agp_base = (agp_base >> 22) & 0x3ffff; - if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) { + /* R6xx/R7xx must be aligned to a 4MB boundry */ + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) + RADEON_WRITE(R700_MC_VM_AGP_BASE, r6xx_agp_base); /* FIX ME */ + else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + RADEON_WRITE(R600_MC_VM_AGP_BASE, r6xx_agp_base); /* FIX ME */ + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) { R500_WRITE_MCIND(RV515_MC_AGP_BASE, agp_base_lo); R500_WRITE_MCIND(RV515_MC_AGP_BASE_2, agp_base_hi); } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { RS690_WRITE_MCIND(RS690_MC_AGP_BASE, agp_base_lo); RS690_WRITE_MCIND(RS690_MC_AGP_BASE_2, agp_base_hi); + } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { + RS690_WRITE_MCIND(RS600_AGP_BASE, agp_base_lo); + RS690_WRITE_MCIND(RS600_AGP_BASE_2, agp_base_hi); } else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) { R500_WRITE_MCIND(R520_MC_AGP_BASE, agp_base_lo); R500_WRITE_MCIND(R520_MC_AGP_BASE_2, agp_base_hi); @@ -326,6 +380,7 @@ radeon_do_wait_for_idle(dev_priv); RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0); + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R100) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV100) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV200) || @@ -381,6 +436,14 @@ RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, RS690_cp_microcode[i][0]); } + } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { + DRM_INFO("Loading RS600 Microcode\n"); + for (i = 0; i < 256; i++) { + RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, + RS600_cp_microcode[i][1]); + RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, + RS600_cp_microcode[i][0]); + } } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R520) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) || @@ -608,17 +671,10 @@ } else #endif { - struct drm_sg_mem *entry = dev->sg; - unsigned long tmp_ofs, page_ofs; - - tmp_ofs = dev_priv->ring_rptr->offset - - (unsigned long)dev->sg->virtual; - page_ofs = tmp_ofs >> PAGE_SHIFT; - - RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, entry->busaddr[page_ofs]); - DRM_DEBUG("ring rptr: offset=0x%08lx handle=0x%08lx\n", - (unsigned long)entry->busaddr[page_ofs], - entry->handle + tmp_ofs); + RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, + dev_priv->ring_rptr->offset + - ((unsigned long) dev->sg->virtual) + + dev_priv->gart_vm_start); } /* Set ring buffer size */ @@ -740,6 +796,7 @@ dev_priv->gart_size); temp = IGP_READ_MCIND(dev_priv, RS480_MC_MISC_CNTL); + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) IGP_WRITE_MCIND(RS480_MC_MISC_CNTL, (RS480_GART_INDEX_REG_EN | @@ -799,6 +856,82 @@ } } +/* Enable or disable IGP GART on the chip */ +static void rs600_set_igpgart(drm_radeon_private_t *dev_priv, int on) +{ + u32 temp; + int i; + + if (on) { + DRM_DEBUG("programming igp gart %08X %08lX %08X\n", + dev_priv->gart_vm_start, + (long)dev_priv->gart_info.bus_addr, + dev_priv->gart_size); + + IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (RS600_EFFECTIVE_L2_CACHE_SIZE(6) | + RS600_EFFECTIVE_L2_QUEUE_SIZE(6))); + + for (i = 0; i < 19; i++) + IGP_WRITE_MCIND(RS600_MC_PT0_CLIENT0_CNTL + i, + (RS600_ENABLE_TRANSLATION_MODE_OVERRIDE | + RS600_SYSTEM_ACCESS_MODE_IN_SYS | + RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASSTHROUGH | + RS600_EFFECTIVE_L1_CACHE_SIZE(3) | + RS600_ENABLE_FRAGMENT_PROCESSING | + RS600_EFFECTIVE_L1_QUEUE_SIZE(3))); + + IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL, (RS600_ENABLE_PAGE_TABLE | + RS600_PAGE_TABLE_TYPE_FLAT)); + + /* disable all other contexts */ + for (i = 1; i < 8; i++) + IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL + i, 0); + + /* setup the page table aperture */ + IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR, + dev_priv->gart_info.bus_addr); + IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR, + dev_priv->gart_vm_start); + IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR, + (dev_priv->gart_vm_start + dev_priv->gart_size - 1)); + IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0); + + /* setup the system aperture */ + IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, + dev_priv->gart_vm_start); + IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, + (dev_priv->gart_vm_start + dev_priv->gart_size - 1)); + + /* enable page tables */ + temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); + IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (temp | RS600_ENABLE_PT)); + + temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1); + IGP_WRITE_MCIND(RS600_MC_CNTL1, (temp | RS600_ENABLE_PAGE_TABLES)); + + /* invalidate the cache */ + temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); + + temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE); + IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); + temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); + + temp |= RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE; + IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); + temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); + + temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE); + IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); + temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); + + } else { + IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, 0); + temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1); + temp &= ~RS600_ENABLE_PAGE_TABLES; + IGP_WRITE_MCIND(RS600_MC_CNTL1, temp); + } +} + static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) { u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); @@ -840,6 +973,11 @@ return; } + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { + rs600_set_igpgart(dev_priv, on); + return; + } + if (dev_priv->flags & RADEON_IS_PCIE) { radeon_set_pciegart(dev_priv, on); return; @@ -874,6 +1012,7 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init) { drm_radeon_private_t *dev_priv = dev->dev_private; + int ret; DRM_DEBUG("\n"); @@ -1041,9 +1180,9 @@ #if __OS_HAS_AGP if (dev_priv->flags & RADEON_IS_AGP) { - drm_core_ioremap(dev_priv->cp_ring, dev); - drm_core_ioremap(dev_priv->ring_rptr, dev); - drm_core_ioremap(dev->agp_buffer_map, dev); + drm_core_ioremap_wc(dev_priv->cp_ring, dev); + drm_core_ioremap_wc(dev_priv->ring_rptr, dev); + drm_core_ioremap_wc(dev->agp_buffer_map, dev); if (!dev_priv->cp_ring->handle || !dev_priv->ring_rptr->handle || !dev->agp_buffer_map->handle) { @@ -1176,6 +1315,12 @@ dev_priv->gart_info.table_size; drm_core_ioremap_wc(&dev_priv->gart_info.mapping, dev); + if (!dev_priv->gart_info.mapping.handle) { + DRM_ERROR("ioremap failed.\n"); + radeon_do_cleanup_cp(dev); + return -EINVAL; + } + dev_priv->gart_info.addr = dev_priv->gart_info.mapping.handle; @@ -1206,7 +1351,12 @@ } } - if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) + ret = r600_page_table_init(dev); + else + ret = drm_ati_pcigart_init(dev, &dev_priv->gart_info); + + if (!ret) { DRM_ERROR("failed to init PCI GART!\n"); radeon_do_cleanup_cp(dev); return -ENOMEM; @@ -1260,8 +1410,13 @@ if (dev_priv->gart_info.bus_addr) { /* Turn off PCI GART */ radeon_set_pcigart(dev_priv, 0); - if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) - DRM_ERROR("failed to cleanup PCI GART!\n"); + + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) + r600_page_table_cleanup(dev, &dev_priv->gart_info); + else { + if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) + DRM_ERROR("failed to cleanup PCI GART!\n"); + } } if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) @@ -1318,6 +1473,7 @@ int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv) { + drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_init_t *init = data; LOCK_TEST_WITH_RETURN(dev, file_priv); @@ -1330,8 +1486,13 @@ case RADEON_INIT_R200_CP: case RADEON_INIT_R300_CP: return radeon_do_init_cp(dev, init); + case RADEON_INIT_R600_CP: + return r600_do_init_cp(dev, init); case RADEON_CLEANUP_CP: - return radeon_do_cleanup_cp(dev); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + return r600_do_cleanup_cp(dev); + else + return radeon_do_cleanup_cp(dev); } return -EINVAL; @@ -1354,7 +1515,10 @@ return 0; } - radeon_do_cp_start(dev_priv); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + r600_do_cp_start(dev_priv); + else + radeon_do_cp_start(dev_priv); return 0; } @@ -1385,7 +1549,10 @@ * code so that the DRM ioctl wrapper can try again. */ if (stop->idle) { - ret = radeon_do_cp_idle(dev_priv); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + ret = r600_do_cp_idle(dev_priv); + else + ret = radeon_do_cp_idle(dev_priv); if (ret) return ret; } @@ -1394,10 +1561,16 @@ * we will get some dropped triangles as they won't be fully * rendered before the CP is shut down. */ - radeon_do_cp_stop(dev_priv); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + r600_do_cp_stop(dev_priv); + else + radeon_do_cp_stop(dev_priv); /* Reset the engine */ - radeon_do_engine_reset(dev); + if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_R600) + radeon_do_engine_reset(dev); + else + r600_do_engine_reset(dev); return 0; } @@ -1410,29 +1583,44 @@ if (dev_priv) { if (dev_priv->cp_running) { /* Stop the cp */ - while ((ret = radeon_do_cp_idle(dev_priv)) != 0) { - DRM_DEBUG("radeon_do_cp_idle %d\n", ret); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { + while ((ret = r600_do_cp_idle(dev_priv)) != 0) { + DRM_DEBUG("r600_do_cp_idle %d\n", ret); +#ifdef __linux__ + schedule(); +#else + tsleep(&ret, PZERO, "rdnrel", 1); +#endif + } + r600_do_cp_stop(dev_priv); + r600_do_engine_reset(dev); + } else { + while ((ret = radeon_do_cp_idle(dev_priv)) != 0) { + DRM_DEBUG("radeon_do_cp_idle %d\n", ret); #ifdef __linux__ - schedule(); + schedule(); #else - tsleep(&ret, PZERO, "rdnrel", 1); + tsleep(&ret, PZERO, "rdnrel", 1); #endif + } + radeon_do_cp_stop(dev_priv); + radeon_do_engine_reset(dev); } - radeon_do_cp_stop(dev_priv); - radeon_do_engine_reset(dev); } - /* Disable *all* interrupts */ - if (dev_priv->mmio) /* remove this after permanent addmaps */ - RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); - - if (dev_priv->mmio) { /* remove all surfaces */ - for (i = 0; i < RADEON_MAX_SURFACES; i++) { - RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0); - RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + - 16 * i, 0); - RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + - 16 * i, 0); + if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_R600) { + /* Disable *all* interrupts */ + if (dev_priv->mmio) /* remove this after permanent addmaps */ + RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); + + if (dev_priv->mmio) { /* remove all surfaces */ + for (i = 0; i < RADEON_MAX_SURFACES; i++) { + RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0); + RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + + 16 * i, 0); + RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + + 16 * i, 0); + } } } @@ -1441,7 +1629,10 @@ radeon_mem_takedown(&(dev_priv->fb_heap)); /* deallocate kernel resources */ - radeon_do_cleanup_cp(dev); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + r600_do_cleanup_cp(dev); + else + radeon_do_cleanup_cp(dev); } } @@ -1459,7 +1650,10 @@ return -EINVAL; } - radeon_do_cp_reset(dev_priv); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + r600_do_cp_reset(dev_priv); + else + radeon_do_cp_reset(dev_priv); /* The CP is no longer running after an engine reset */ dev_priv->cp_running = 0; @@ -1474,24 +1668,35 @@ LOCK_TEST_WITH_RETURN(dev, file_priv); - return radeon_do_cp_idle(dev_priv); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + return r600_do_cp_idle(dev_priv); + else + return radeon_do_cp_idle(dev_priv); } /* Added by Charl P. Botha to call radeon_do_resume_cp(). */ int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv) { + drm_radeon_private_t *dev_priv = dev->dev_private; - return radeon_do_resume_cp(dev); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + return r600_do_resume_cp(dev); + else + return radeon_do_resume_cp(dev); } int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) { + drm_radeon_private_t *dev_priv = dev->dev_private; DRM_DEBUG("\n"); LOCK_TEST_WITH_RETURN(dev, file_priv); - return radeon_do_engine_reset(dev); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + return r600_do_engine_reset(dev); + else + return radeon_do_engine_reset(dev); } /* ================================================================ @@ -1541,7 +1746,11 @@ start = dev_priv->last_buf; for (t = 0; t < dev_priv->usec_timeout; t++) { - u32 done_age = GET_SCRATCH(1); + u32 done_age; + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + done_age = GET_R600_SCRATCH(1); + else + done_age = GET_SCRATCH(1); DRM_DEBUG("done_age = %d\n", done_age); for (i = start; i < dma->buf_count; i++) { buf = dma->buflist[i]; @@ -1624,10 +1833,20 @@ { drm_radeon_ring_buffer_t *ring = &dev_priv->ring; int i; - u32 last_head = GET_RING_HEAD(dev_priv); + u32 last_head; + + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + last_head = R600_GET_RING_HEAD(dev_priv); + else + last_head = GET_RING_HEAD(dev_priv); for (i = 0; i < dev_priv->usec_timeout; i++) { - u32 head = GET_RING_HEAD(dev_priv); + u32 head; + + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + head = R600_GET_RING_HEAD(dev_priv); + else + head = GET_RING_HEAD(dev_priv); ring->space = (head - ring->tail) * sizeof(u32); if (ring->space <= 0) @@ -1711,6 +1930,47 @@ return ret; } +void radeon_commit_ring(drm_radeon_private_t *dev_priv) +{ + int i; + u32 *ring; + int tail_aligned; + + /* check if the ring is padded out to 16-dword alignment */ + + tail_aligned = dev_priv->ring.tail & 0xf; + if (tail_aligned) { + int num_p2 = 16 - tail_aligned; + + ring = dev_priv->ring.start; + /* pad with some CP_PACKET2 */ + for (i = 0; i < num_p2; i++) + ring[dev_priv->ring.tail + i] = CP_PACKET2(); + + dev_priv->ring.tail += i; + + dev_priv->ring.space -= num_p2 * sizeof(u32); + } + + dev_priv->ring.tail &= dev_priv->ring.tail_mask; + + DRM_MEMORYBARRIER(); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + R600_GET_RING_HEAD(dev_priv); + else + GET_RING_HEAD(dev_priv); + + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { + RADEON_WRITE(R600_CP_RB_WPTR, dev_priv->ring.tail); + /* read from PCI bus to ensure correct posting */ + RADEON_READ(R600_CP_RB_RPTR); + } else { + RADEON_WRITE(RADEON_CP_RB_WPTR, dev_priv->ring.tail); + /* read from PCI bus to ensure correct posting */ + RADEON_READ(RADEON_CP_RB_RPTR); + } +} + int radeon_driver_load(struct drm_device *dev, unsigned long flags) { drm_radeon_private_t *dev_priv; --- linux-2.6.28.orig/drivers/gpu/drm/radeon/radeon_irq.c +++ linux-2.6.28/drivers/gpu/drm/radeon/radeon_irq.c @@ -65,7 +65,7 @@ { drm_radeon_private_t *dev_priv = dev->dev_private; - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { switch (crtc) { case 0: r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 1); @@ -100,7 +100,7 @@ { drm_radeon_private_t *dev_priv = dev->dev_private; - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { switch (crtc) { case 0: r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 0); @@ -135,7 +135,7 @@ u32 irq_mask = RADEON_SW_INT_TEST; *r500_disp_int = 0; - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { /* vbl interrupts in a different place */ if (irqs & R500_DISPLAY_INT_STATUS) { @@ -202,7 +202,7 @@ DRM_WAKEUP(&dev_priv->swi_queue); /* VBLANK interrupt */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { if (r500_disp_int & R500_D1_VBLANK_INTERRUPT) drm_handle_vblank(dev, 0); if (r500_disp_int & R500_D2_VBLANK_INTERRUPT) @@ -265,7 +265,7 @@ return -EINVAL; } - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) { + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) { if (crtc == 0) return RADEON_READ(R500_D1CRTC_FRAME_COUNT); else @@ -327,7 +327,7 @@ u32 dummy; /* Disable *all* interrupts */ - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) RADEON_WRITE(R500_DxMODE_INT_MASK, 0); RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); @@ -357,7 +357,7 @@ if (!dev_priv) return; - if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) RADEON_WRITE(R500_DxMODE_INT_MASK, 0); /* Disable *all* interrupts */ RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); --- linux-2.6.28.orig/drivers/gpu/drm/radeon/r600_microcode.h +++ linux-2.6.28/drivers/gpu/drm/radeon/r600_microcode.h @@ -0,0 +1,23297 @@ +/* + * Copyright 2008-2009 Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef R600_MICROCODE_H +#define R600_MICROCODE_H + +static const int ME_JUMP_TABLE_START = 1764; +static const int ME_JUMP_TABLE_END = 1792; + +#define PFP_UCODE_SIZE 576 +#define PM4_UCODE_SIZE 1792 +#define R700_PFP_UCODE_SIZE 848 +#define R700_PM4_UCODE_SIZE 1360 + +static const u32 R600_cp_microcode[][3] = { + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0000ffff, 0x00284621, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x00000000, 0x00e00000, 0x000 }, + { 0x00010000, 0xc0294620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00042004, 0x00604411, 0x614 }, + { 0x00000000, 0x00600000, 0x5b2 }, + { 0x00000000, 0x00600000, 0x5c5 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000f00, 0x00281622, 0x000 }, + { 0x00000008, 0x00211625, 0x000 }, + { 0x00000020, 0x00203625, 0x000 }, + { 0x8d000000, 0x00204411, 0x000 }, + { 0x00000004, 0x002f0225, 0x000 }, + { 0x00000000, 0x0ce00000, 0x018 }, + { 0x00412000, 0x00404811, 0x019 }, + { 0x00422000, 0x00204811, 0x000 }, + { 0x8e000000, 0x00204411, 0x000 }, + { 0x00000031, 0x00204a2d, 0x000 }, + { 0x90000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204805, 0x000 }, + { 0x0000000c, 0x00211622, 0x000 }, + { 0x00000003, 0x00281625, 0x000 }, + { 0x00000019, 0x00211a22, 0x000 }, + { 0x00000004, 0x00281a26, 0x000 }, + { 0x00000000, 0x002914c5, 0x000 }, + { 0x00000021, 0x00203625, 0x000 }, + { 0x00000000, 0x003a1402, 0x000 }, + { 0x00000016, 0x00211625, 0x000 }, + { 0x00000003, 0x00281625, 0x000 }, + { 0x0000001d, 0x00200e2d, 0x000 }, + { 0xfffffffc, 0x00280e23, 0x000 }, + { 0x00000000, 0x002914a3, 0x000 }, + { 0x0000001d, 0x00203625, 0x000 }, + { 0x00008000, 0x00280e22, 0x000 }, + { 0x00000007, 0x00220e23, 0x000 }, + { 0x00000000, 0x0029386e, 0x000 }, + { 0x20000000, 0x00280e22, 0x000 }, + { 0x00000006, 0x00210e23, 0x000 }, + { 0x00000000, 0x0029386e, 0x000 }, + { 0x00000000, 0x00220222, 0x000 }, + { 0x00000000, 0x14e00000, 0x038 }, + { 0x00000000, 0x2ee00000, 0x035 }, + { 0x00000000, 0x2ce00000, 0x037 }, + { 0x00000000, 0x00400e2d, 0x039 }, + { 0x00000008, 0x00200e2d, 0x000 }, + { 0x00000009, 0x0040122d, 0x046 }, + { 0x00000001, 0x00400e2d, 0x039 }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x003ffffc, 0x00281223, 0x000 }, + { 0x00000002, 0x00221224, 0x000 }, + { 0x0000001f, 0x00211e23, 0x000 }, + { 0x00000000, 0x14e00000, 0x03e }, + { 0x00000008, 0x00401c11, 0x041 }, + { 0x0000000d, 0x00201e2d, 0x000 }, + { 0x0000000f, 0x00281e27, 0x000 }, + { 0x00000003, 0x00221e27, 0x000 }, + { 0x7fc00000, 0x00281a23, 0x000 }, + { 0x00000014, 0x00211a26, 0x000 }, + { 0x00000001, 0x00331a26, 0x000 }, + { 0x00000008, 0x00221a26, 0x000 }, + { 0x00000000, 0x00290cc7, 0x000 }, + { 0x00000030, 0x00203624, 0x000 }, + { 0x00007f00, 0x00281221, 0x000 }, + { 0x00001400, 0x002f0224, 0x000 }, + { 0x00000000, 0x0ce00000, 0x04b }, + { 0x00000001, 0x00290e23, 0x000 }, + { 0x00000010, 0x00203623, 0x000 }, + { 0x0000e000, 0x00204411, 0x000 }, + { 0xfff80000, 0x00294a23, 0x000 }, + { 0x00000000, 0x003a2c02, 0x000 }, + { 0x00000002, 0x00220e2b, 0x000 }, + { 0xfc000000, 0x00280e23, 0x000 }, + { 0x00000011, 0x00203623, 0x000 }, + { 0x00001fff, 0x00294a23, 0x000 }, + { 0x00000030, 0x00204a2d, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000032, 0x00200e2d, 0x000 }, + { 0x060a0200, 0x00294a23, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000001, 0x00210222, 0x000 }, + { 0x00000000, 0x14e00000, 0x061 }, + { 0x00000000, 0x2ee00000, 0x05f }, + { 0x00000000, 0x2ce00000, 0x05e }, + { 0x00000000, 0x00400e2d, 0x062 }, + { 0x00000001, 0x00400e2d, 0x062 }, + { 0x0000000a, 0x00200e2d, 0x000 }, + { 0x0000000b, 0x0040122d, 0x06a }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x003ffffc, 0x00281223, 0x000 }, + { 0x00000002, 0x00221224, 0x000 }, + { 0x7fc00000, 0x00281623, 0x000 }, + { 0x00000014, 0x00211625, 0x000 }, + { 0x00000001, 0x00331625, 0x000 }, + { 0x80000000, 0x00280e23, 0x000 }, + { 0x00000000, 0x00290ca3, 0x000 }, + { 0x3ffffc00, 0x00290e23, 0x000 }, + { 0x0000001f, 0x00211e23, 0x000 }, + { 0x00000000, 0x14e00000, 0x06d }, + { 0x00000100, 0x00401c11, 0x070 }, + { 0x0000000d, 0x00201e2d, 0x000 }, + { 0x000000f0, 0x00281e27, 0x000 }, + { 0x00000004, 0x00221e27, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000d, 0x00204811, 0x000 }, + { 0xfffff0ff, 0x00281a30, 0x000 }, + { 0x0000a028, 0x00204411, 0x000 }, + { 0x00000000, 0x002948e6, 0x000 }, + { 0x0000a018, 0x00204411, 0x000 }, + { 0x3fffffff, 0x00284a23, 0x000 }, + { 0x0000a010, 0x00204411, 0x000 }, + { 0x00000000, 0x00204804, 0x000 }, + { 0x0000002d, 0x0020162d, 0x000 }, + { 0x00000000, 0x002f00a3, 0x000 }, + { 0x00000000, 0x0cc00000, 0x080 }, + { 0x0000002e, 0x0020162d, 0x000 }, + { 0x00000000, 0x002f00a4, 0x000 }, + { 0x00000000, 0x0cc00000, 0x081 }, + { 0x00000000, 0x00400000, 0x087 }, + { 0x0000002d, 0x00203623, 0x000 }, + { 0x0000002e, 0x00203624, 0x000 }, + { 0x0000001d, 0x00201e2d, 0x000 }, + { 0x00000002, 0x00210227, 0x000 }, + { 0x00000000, 0x14e00000, 0x087 }, + { 0x00000000, 0x00600000, 0x5ed }, + { 0x00000000, 0x00600000, 0x5e1 }, + { 0x00000002, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x08a }, + { 0x00000018, 0xc0403620, 0x090 }, + { 0x00000000, 0x2ee00000, 0x08e }, + { 0x00000000, 0x2ce00000, 0x08d }, + { 0x00000002, 0x00400e2d, 0x08f }, + { 0x00000003, 0x00400e2d, 0x08f }, + { 0x0000000c, 0x00200e2d, 0x000 }, + { 0x00000018, 0x00203623, 0x000 }, + { 0x00000003, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x095 }, + { 0x0000a00c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x09d }, + { 0x0000a00c, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x2ee00000, 0x09b }, + { 0x00000000, 0x2ce00000, 0x09a }, + { 0x00000002, 0x00400e2d, 0x09c }, + { 0x00000003, 0x00400e2d, 0x09c }, + { 0x0000000c, 0x00200e2d, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000000, 0x003a0c02, 0x000 }, + { 0x003f0000, 0x00280e23, 0x000 }, + { 0x00000010, 0x00210e23, 0x000 }, + { 0x00000013, 0x00203623, 0x000 }, + { 0x0000001e, 0x0021022b, 0x000 }, + { 0x00000000, 0x14c00000, 0x0a4 }, + { 0x0000001c, 0xc0203620, 0x000 }, + { 0x0000001f, 0x0021022b, 0x000 }, + { 0x00000000, 0x14c00000, 0x0a7 }, + { 0x0000001b, 0xc0203620, 0x000 }, + { 0x00000008, 0x00210e2b, 0x000 }, + { 0x0000007f, 0x00280e23, 0x000 }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0db }, + { 0x00000000, 0x27000000, 0x000 }, + { 0x00000000, 0x00600000, 0x28c }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x0000000c, 0x00221e30, 0x000 }, + { 0x99800000, 0x00204411, 0x000 }, + { 0x00000004, 0x0020122d, 0x000 }, + { 0x00000008, 0x00221224, 0x000 }, + { 0x00000010, 0x00201811, 0x000 }, + { 0x00000000, 0x00291ce4, 0x000 }, + { 0x00000000, 0x00604807, 0x128 }, + { 0x9b000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x9c000000, 0x00204411, 0x000 }, + { 0x00000000, 0x0033146f, 0x000 }, + { 0x00000001, 0x00333e23, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0x00203c05, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000e, 0x00204811, 0x000 }, + { 0x00000000, 0x00201010, 0x000 }, + { 0x0000e007, 0x00204411, 0x000 }, + { 0x0000000f, 0x0021022b, 0x000 }, + { 0x00000000, 0x14c00000, 0x0c5 }, + { 0x00f8ff08, 0x00204811, 0x000 }, + { 0x98000000, 0x00404811, 0x0d6 }, + { 0x000000f0, 0x00280e22, 0x000 }, + { 0x000000a0, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x0d4 }, + { 0x00000013, 0x00200e2d, 0x000 }, + { 0x00000001, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0cf }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0ce }, + { 0x00003f00, 0x00400c11, 0x0d0 }, + { 0x00001f00, 0x00400c11, 0x0d0 }, + { 0x00000f00, 0x00200c11, 0x000 }, + { 0x00380009, 0x00294a23, 0x000 }, + { 0x3f000000, 0x00280e2b, 0x000 }, + { 0x00000002, 0x00220e23, 0x000 }, + { 0x00000007, 0x00494a23, 0x0d6 }, + { 0x00380f09, 0x00204811, 0x000 }, + { 0x68000007, 0x00204811, 0x000 }, + { 0x00000008, 0x00214a27, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00294a24, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000a202, 0x00204411, 0x000 }, + { 0x00ff0000, 0x00284a22, 0x000 }, + { 0x00000030, 0x00200e2d, 0x000 }, + { 0x0000002e, 0x0020122d, 0x000 }, + { 0x00000000, 0x002f0083, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0e3 }, + { 0x00000000, 0x00600000, 0x5e7 }, + { 0x00000000, 0x00400000, 0x0e4 }, + { 0x00000000, 0x00600000, 0x5ea }, + { 0x00000007, 0x0020222d, 0x000 }, + { 0x00000005, 0x00220e22, 0x000 }, + { 0x00100000, 0x00280e23, 0x000 }, + { 0x00000000, 0x00292068, 0x000 }, + { 0x00000000, 0x003a0c02, 0x000 }, + { 0x000000ef, 0x00280e23, 0x000 }, + { 0x00000000, 0x00292068, 0x000 }, + { 0x0000001d, 0x00200e2d, 0x000 }, + { 0x00000003, 0x00210223, 0x000 }, + { 0x00000000, 0x14e00000, 0x0f1 }, + { 0x0000000b, 0x00210228, 0x000 }, + { 0x00000000, 0x14c00000, 0x0f1 }, + { 0x00000400, 0x00292228, 0x000 }, + { 0x0000001a, 0x00203628, 0x000 }, + { 0x0000001c, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x0f6 }, + { 0x0000a30c, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000001e, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x104 }, + { 0x0000a30f, 0x00204411, 0x000 }, + { 0x00000013, 0x00200e2d, 0x000 }, + { 0x00000001, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x0fd }, + { 0xffffffff, 0x00404811, 0x104 }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x100 }, + { 0x0000ffff, 0x00404811, 0x104 }, + { 0x00000004, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x103 }, + { 0x000000ff, 0x00404811, 0x104 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0002c400, 0x00204411, 0x000 }, + { 0x0000001f, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x10b }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x00000019, 0x00203623, 0x000 }, + { 0x00000018, 0x40224a20, 0x000 }, + { 0x00000010, 0xc0424a20, 0x10d }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x00000019, 0x00203623, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000000a, 0x00201011, 0x000 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0ce00000, 0x114 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000001, 0x00531224, 0x110 }, + { 0xffbfffff, 0x00283a2e, 0x000 }, + { 0x0000001b, 0x00210222, 0x000 }, + { 0x00000000, 0x14c00000, 0x127 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000d, 0x00204811, 0x000 }, + { 0x00000018, 0x00220e30, 0x000 }, + { 0xfc000000, 0x00280e23, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000e, 0x00204811, 0x000 }, + { 0x00000000, 0x00201010, 0x000 }, + { 0x0000e00e, 0x00204411, 0x000 }, + { 0x07f8ff08, 0x00204811, 0x000 }, + { 0x00000000, 0x00294a23, 0x000 }, + { 0x00000024, 0x00201e2d, 0x000 }, + { 0x00000008, 0x00214a27, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00294a24, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x00800000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204806, 0x000 }, + { 0x00000008, 0x00214a27, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x0004217f, 0x00604411, 0x614 }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x613 }, + { 0x00000004, 0x00404c11, 0x12e }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600411, 0x2fe }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x19f }, + { 0x00000000, 0x00600000, 0x151 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x00000010, 0xc0211220, 0x000 }, + { 0x0000ffff, 0x40280620, 0x000 }, + { 0x00000010, 0xc0210a20, 0x000 }, + { 0x00000000, 0x00341461, 0x000 }, + { 0x00000000, 0x00741882, 0x2a4 }, + { 0x0001a1fd, 0x00604411, 0x2c9 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x138 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600411, 0x2fe }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x19f }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00600000, 0x151 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x0000ffff, 0xc0281220, 0x000 }, + { 0x00000010, 0x40211620, 0x000 }, + { 0x0000ffff, 0xc0681a20, 0x2a4 }, + { 0x0001a1fd, 0x00604411, 0x2c9 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x149 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000001, 0x00300a2f, 0x000 }, + { 0x00000001, 0x00210a22, 0x000 }, + { 0x00000003, 0x00384a22, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001a, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00804811, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600000, 0x17c }, + { 0x00000000, 0x00600000, 0x18d }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00202c08, 0x000 }, + { 0x00000000, 0x00202411, 0x000 }, + { 0x00000000, 0x00202811, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x00000016, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x93800000, 0x00204411, 0x000 }, + { 0x00000002, 0x00221e29, 0x000 }, + { 0x00000000, 0x007048eb, 0x189 }, + { 0x00000000, 0x00600000, 0x2a4 }, + { 0x00000001, 0x40330620, 0x000 }, + { 0x00000000, 0xc0302409, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00600000, 0x28c }, + { 0x95000000, 0x00204411, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x173 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000001, 0x00530621, 0x16f }, + { 0x92000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0604800, 0x184 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000013, 0x0020062d, 0x000 }, + { 0x00000000, 0x0078042a, 0x2e4 }, + { 0x00000000, 0x00202809, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x165 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000210, 0x00600411, 0x2fe }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x181 }, + { 0x0000001b, 0xc0203620, 0x000 }, + { 0x0000001c, 0xc0203620, 0x000 }, + { 0x3f800000, 0x00200411, 0x000 }, + { 0x46000000, 0x00600811, 0x19f }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x188 }, + { 0x00000001, 0x00804811, 0x000 }, + { 0x00000021, 0x00804811, 0x000 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x00000010, 0xc0211220, 0x000 }, + { 0x0000ffff, 0x40281620, 0x000 }, + { 0x00000010, 0xc0811a20, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x00000008, 0x00221e30, 0x000 }, + { 0x00000032, 0x00201a2d, 0x000 }, + { 0x0000e000, 0x00204411, 0x000 }, + { 0xfffbff09, 0x00204811, 0x000 }, + { 0x00000011, 0x0020222d, 0x000 }, + { 0x00001fff, 0x00294a28, 0x000 }, + { 0x00000006, 0x0020222d, 0x000 }, + { 0x00000000, 0x002920e8, 0x000 }, + { 0x00000000, 0x00204808, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00294a26, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000100, 0x00201811, 0x000 }, + { 0x00000008, 0x00621e28, 0x128 }, + { 0x00000008, 0x00822228, 0x000 }, + { 0x0002c000, 0x00204411, 0x000 }, + { 0x0000001b, 0x00600e2d, 0x1aa }, + { 0x0000001c, 0x00600e2d, 0x1aa }, + { 0x0000c008, 0x00204411, 0x000 }, + { 0x0000001d, 0x00200e2d, 0x000 }, + { 0x00000000, 0x14c00000, 0x1a6 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00204801, 0x000 }, + { 0x39000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00804802, 0x000 }, + { 0x00000020, 0x00202e2d, 0x000 }, + { 0x00000000, 0x003b0d63, 0x000 }, + { 0x00000008, 0x00224a23, 0x000 }, + { 0x00000010, 0x00224a23, 0x000 }, + { 0x00000018, 0x00224a23, 0x000 }, + { 0x00000000, 0x00804803, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00001000, 0x00600411, 0x2fe }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x19f }, + { 0x00000007, 0x0021062f, 0x000 }, + { 0x00000019, 0x00200a2d, 0x000 }, + { 0x00000001, 0x00202c11, 0x000 }, + { 0x0000ffff, 0x40282220, 0x000 }, + { 0x0000000f, 0x00262228, 0x000 }, + { 0x00000010, 0x40212620, 0x000 }, + { 0x0000000f, 0x00262629, 0x000 }, + { 0x00000000, 0x00202802, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001b, 0x00204811, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x1cd }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000081, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000080, 0x00201c11, 0x000 }, + { 0x00000000, 0x002f0227, 0x000 }, + { 0x00000000, 0x0ce00000, 0x1c9 }, + { 0x00000000, 0x00600000, 0x1d6 }, + { 0x00000001, 0x00531e27, 0x1c5 }, + { 0x00000001, 0x00202c11, 0x000 }, + { 0x0000001f, 0x00280a22, 0x000 }, + { 0x0000001f, 0x00282a2a, 0x000 }, + { 0x00000001, 0x00530621, 0x1be }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000002, 0x00304a2f, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000001, 0x00301e2f, 0x000 }, + { 0x00000000, 0x002f0227, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00600000, 0x1d6 }, + { 0x00000001, 0x00531e27, 0x1d2 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x0000000f, 0x00260e23, 0x000 }, + { 0x00000010, 0xc0211220, 0x000 }, + { 0x0000000f, 0x00261224, 0x000 }, + { 0x00000000, 0x00201411, 0x000 }, + { 0x00000000, 0x00601811, 0x2a4 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0x002f022b, 0x000 }, + { 0x00000000, 0x0ce00000, 0x1e5 }, + { 0x00000010, 0x00221628, 0x000 }, + { 0xffff0000, 0x00281625, 0x000 }, + { 0x0000ffff, 0x00281a29, 0x000 }, + { 0x00000000, 0x002948c5, 0x000 }, + { 0x00000000, 0x0020480a, 0x000 }, + { 0x00000000, 0x00202c11, 0x000 }, + { 0x00000010, 0x00221623, 0x000 }, + { 0xffff0000, 0x00281625, 0x000 }, + { 0x0000ffff, 0x00281a24, 0x000 }, + { 0x00000000, 0x002948c5, 0x000 }, + { 0x00000000, 0x00731503, 0x1f2 }, + { 0x00000000, 0x00201805, 0x000 }, + { 0x00000000, 0x00731524, 0x1f2 }, + { 0x00000000, 0x002d14c5, 0x000 }, + { 0x00000000, 0x003008a2, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00202802, 0x000 }, + { 0x00000000, 0x00202003, 0x000 }, + { 0x00000000, 0x00802404, 0x000 }, + { 0x0000000f, 0x00210225, 0x000 }, + { 0x00000000, 0x14c00000, 0x613 }, + { 0x00000000, 0x002b1405, 0x000 }, + { 0x00000001, 0x00901625, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600411, 0x2fe }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x19f }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001a, 0x00294a22, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00384a21, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0000ffff, 0x40281220, 0x000 }, + { 0x00000010, 0xc0211a20, 0x000 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x00000010, 0xc0211620, 0x000 }, + { 0x00000000, 0x00741465, 0x2a4 }, + { 0x0001a1fd, 0x00604411, 0x2c9 }, + { 0x00000001, 0x00330621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0cc00000, 0x206 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x1ff }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000000, 0x00600000, 0x5c5 }, + { 0x00000000, 0x0040040f, 0x200 }, + { 0x00000000, 0x00600000, 0x5b2 }, + { 0x00000000, 0x00600000, 0x5c5 }, + { 0x00000210, 0x00600411, 0x2fe }, + { 0x00000000, 0x00600000, 0x18d }, + { 0x00000000, 0x00600000, 0x189 }, + { 0x00000000, 0x00600000, 0x2a4 }, + { 0x00000000, 0x00600000, 0x28c }, + { 0x93800000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204808, 0x000 }, + { 0x95000000, 0x00204411, 0x000 }, + { 0x00000000, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x21f }, + { 0x00000000, 0xc0404800, 0x21c }, + { 0x92000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x00000016, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0x00600411, 0x2e4 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000000, 0x00600000, 0x5b2 }, + { 0x0000a00c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000018, 0x40210a20, 0x000 }, + { 0x00000003, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x235 }, + { 0x0000001a, 0x0020222d, 0x000 }, + { 0x00080101, 0x00292228, 0x000 }, + { 0x0000001a, 0x00203628, 0x000 }, + { 0x0000a30c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x23a }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000010, 0x00600411, 0x2fe }, + { 0x3f800000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x19f }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x00000000, 0x00600000, 0x265 }, + { 0x0000001d, 0x00201e2d, 0x000 }, + { 0x00000001, 0x00211e27, 0x000 }, + { 0x00000000, 0x14e00000, 0x253 }, + { 0x00000018, 0x00201e2d, 0x000 }, + { 0x0000ffff, 0x00281e27, 0x000 }, + { 0x00000000, 0x00341c27, 0x000 }, + { 0x00000000, 0x12c00000, 0x248 }, + { 0x00000000, 0x00201c11, 0x000 }, + { 0x00000000, 0x002f00e5, 0x000 }, + { 0x00000000, 0x08c00000, 0x24b }, + { 0x00000000, 0x00201407, 0x000 }, + { 0x00000018, 0x00201e2d, 0x000 }, + { 0x00000010, 0x00211e27, 0x000 }, + { 0x00000000, 0x00341c47, 0x000 }, + { 0x00000000, 0x12c00000, 0x250 }, + { 0x00000000, 0x00201c11, 0x000 }, + { 0x00000000, 0x002f00e6, 0x000 }, + { 0x00000000, 0x08c00000, 0x253 }, + { 0x00000000, 0x00201807, 0x000 }, + { 0x00000000, 0x00600000, 0x2aa }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x00000000, 0x00342023, 0x000 }, + { 0x00000000, 0x12c00000, 0x25b }, + { 0x00000000, 0x00342044, 0x000 }, + { 0x00000000, 0x12c00000, 0x25a }, + { 0x00000016, 0x00404811, 0x25f }, + { 0x00000018, 0x00404811, 0x25f }, + { 0x00000000, 0x00342044, 0x000 }, + { 0x00000000, 0x12c00000, 0x25e }, + { 0x00000017, 0x00404811, 0x25f }, + { 0x00000019, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0001a1fd, 0x00604411, 0x2d2 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x23f }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000010, 0x40210620, 0x000 }, + { 0x0000ffff, 0xc0280a20, 0x000 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x0000ffff, 0xc0281220, 0x000 }, + { 0x00000010, 0x40211620, 0x000 }, + { 0x0000ffff, 0xc0881a20, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00042004, 0x00604411, 0x614 }, + { 0x00000000, 0x00600000, 0x5b2 }, + { 0x00000000, 0xc0600000, 0x28c }, + { 0x00000005, 0x00200a2d, 0x000 }, + { 0x00000008, 0x00220a22, 0x000 }, + { 0x00000034, 0x00201a2d, 0x000 }, + { 0x00000024, 0x00201e2d, 0x000 }, + { 0x00007000, 0x00281e27, 0x000 }, + { 0x00000000, 0x00311ce6, 0x000 }, + { 0x00000033, 0x00201a2d, 0x000 }, + { 0x0000000c, 0x00221a26, 0x000 }, + { 0x00000000, 0x002f00e6, 0x000 }, + { 0x00000000, 0x06e00000, 0x27b }, + { 0x00000000, 0x00201c11, 0x000 }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x00000034, 0x00203623, 0x000 }, + { 0x00000010, 0x00201811, 0x000 }, + { 0x00000000, 0x00691ce2, 0x128 }, + { 0x93800000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x95000000, 0x00204411, 0x000 }, + { 0x00000000, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x286 }, + { 0x00000001, 0x00333e2f, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x92000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000024, 0x00403627, 0x000 }, + { 0x0000000c, 0xc0220a20, 0x000 }, + { 0x00000032, 0x00203622, 0x000 }, + { 0x00000031, 0xc0403620, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000009, 0x00204811, 0x000 }, + { 0xa1000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00804811, 0x000 }, + { 0x00000029, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002c1ce3, 0x000 }, + { 0x00000029, 0x00203627, 0x000 }, + { 0x0000002a, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002c1ce4, 0x000 }, + { 0x0000002a, 0x00203627, 0x000 }, + { 0x0000002b, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120a3, 0x000 }, + { 0x00000000, 0x002d1d07, 0x000 }, + { 0x0000002b, 0x00203627, 0x000 }, + { 0x0000002c, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x00000000, 0x002d1d07, 0x000 }, + { 0x0000002c, 0x00803627, 0x000 }, + { 0x00000029, 0x00203623, 0x000 }, + { 0x0000002a, 0x00203624, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x0000002b, 0x00203627, 0x000 }, + { 0x00000000, 0x00311cc4, 0x000 }, + { 0x0000002c, 0x00803627, 0x000 }, + { 0x00000022, 0x00203627, 0x000 }, + { 0x00000023, 0x00203628, 0x000 }, + { 0x0000001d, 0x00201e2d, 0x000 }, + { 0x00000002, 0x00210227, 0x000 }, + { 0x00000000, 0x14c00000, 0x2c5 }, + { 0x00000000, 0x00400000, 0x2c2 }, + { 0x00000022, 0x00203627, 0x000 }, + { 0x00000023, 0x00203628, 0x000 }, + { 0x0000001d, 0x00201e2d, 0x000 }, + { 0x00000002, 0x00210227, 0x000 }, + { 0x00000000, 0x14e00000, 0x2c2 }, + { 0x00000003, 0x00210227, 0x000 }, + { 0x00000000, 0x14e00000, 0x2c5 }, + { 0x0000002b, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002e00e1, 0x000 }, + { 0x00000000, 0x02c00000, 0x2c5 }, + { 0x00000029, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120a1, 0x000 }, + { 0x00000000, 0x002e00e8, 0x000 }, + { 0x00000000, 0x06c00000, 0x2c5 }, + { 0x0000002c, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002e00e2, 0x000 }, + { 0x00000000, 0x02c00000, 0x2c5 }, + { 0x0000002a, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120c2, 0x000 }, + { 0x00000000, 0x002e00e8, 0x000 }, + { 0x00000000, 0x06c00000, 0x2c5 }, + { 0x00000000, 0x00600000, 0x5ed }, + { 0x00000000, 0x00600000, 0x29e }, + { 0x00000000, 0x00400000, 0x2c7 }, + { 0x00000000, 0x00600000, 0x29e }, + { 0x00000000, 0x00600000, 0x5e4 }, + { 0x00000000, 0x00400000, 0x2c7 }, + { 0x00000000, 0x00600000, 0x290 }, + { 0x00000000, 0x00400000, 0x2c7 }, + { 0x00000022, 0x00201e2d, 0x000 }, + { 0x00000023, 0x0080222d, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00894907, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000010, 0x00221e21, 0x000 }, + { 0x00000000, 0x00294847, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000000, 0x00311ca1, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294847, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000010, 0x00221e21, 0x000 }, + { 0x00000000, 0x003120c2, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00894907, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000001, 0x00220a21, 0x000 }, + { 0x00000000, 0x003308a2, 0x000 }, + { 0x00000010, 0x00221e22, 0x000 }, + { 0x00000010, 0x00212222, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000001, 0x00220a21, 0x000 }, + { 0x00000000, 0x003008a2, 0x000 }, + { 0x00000010, 0x00221e22, 0x000 }, + { 0x00000010, 0x00212222, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x003808c5, 0x000 }, + { 0x00000000, 0x00300841, 0x000 }, + { 0x00000001, 0x00220a22, 0x000 }, + { 0x00000000, 0x003308a2, 0x000 }, + { 0x00000010, 0x00221e22, 0x000 }, + { 0x00000010, 0x00212222, 0x000 }, + { 0x00000000, 0x00894907, 0x000 }, + { 0x0000001d, 0x0020222d, 0x000 }, + { 0x00000000, 0x14c00000, 0x301 }, + { 0xffffffef, 0x00280621, 0x000 }, + { 0x0000001a, 0x0020222d, 0x000 }, + { 0x0000f8e0, 0x00204411, 0x000 }, + { 0x00000000, 0x00294901, 0x000 }, + { 0x00000000, 0x00894901, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00804811, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x97000000, 0xc0204411, 0x000 }, + { 0x00000000, 0xc0204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x97000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x97000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x00002257, 0x00204411, 0x000 }, + { 0x00000003, 0xc0484a20, 0x000 }, + { 0x0000225d, 0x00204411, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000000, 0x00600000, 0x5c5 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00384a22, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x40204800, 0x000 }, + { 0x00000001, 0x40304a20, 0x000 }, + { 0x00000002, 0xc0304a20, 0x000 }, + { 0x00000001, 0x00530a22, 0x334 }, + { 0x0000003f, 0xc0280a20, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000017, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x614 }, + { 0x00000011, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x33d }, + { 0x00000014, 0x002f0222, 0x000 }, + { 0x00000000, 0x0cc00000, 0x351 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000016, 0x00604811, 0x35e }, + { 0x00002100, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00404802, 0x000 }, + { 0x00000004, 0x002f0222, 0x000 }, + { 0x00000000, 0x0cc00000, 0x355 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00404811, 0x349 }, + { 0x00000028, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x349 }, + { 0x00002104, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x000 }, + { 0x00000035, 0x00203626, 0x000 }, + { 0x00000049, 0x00201811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000001, 0x00331a26, 0x000 }, + { 0x00000000, 0x002f0226, 0x000 }, + { 0x00000000, 0x0cc00000, 0x360 }, + { 0x00000035, 0x00801a2d, 0x000 }, + { 0x0000003f, 0xc0280a20, 0x000 }, + { 0x00000015, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x376 }, + { 0x0000001e, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x380 }, + { 0x00000020, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x38c }, + { 0x0000000f, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x398 }, + { 0x00000010, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x398 }, + { 0x00000006, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x39a }, + { 0x00000016, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x39f }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x000 }, + { 0x08000000, 0x00290a22, 0x000 }, + { 0x00000003, 0x40210e20, 0x000 }, + { 0x0000000c, 0xc0211220, 0x000 }, + { 0x00080000, 0x00281224, 0x000 }, + { 0x00000014, 0xc0221620, 0x000 }, + { 0x00000000, 0x002914a4, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x002948a2, 0x000 }, + { 0x0000a1fe, 0x00204411, 0x000 }, + { 0x00000000, 0x00404803, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000015, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x614 }, + { 0x00000015, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x382 }, + { 0x0000210e, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000016, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x614 }, + { 0x00000003, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x38e }, + { 0x00002108, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x000 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00404811, 0x000 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000006, 0x00404811, 0x000 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000016, 0x00604811, 0x35e }, + { 0x00000016, 0x00404811, 0x000 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x0000001d, 0x00210223, 0x000 }, + { 0x00000000, 0x14e00000, 0x3b9 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000017, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x614 }, + { 0x00000011, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x3ab }, + { 0x00002100, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0xbabecafe, 0x00204811, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000004, 0x00404811, 0x000 }, + { 0x00002170, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000a, 0x00204811, 0x000 }, + { 0x00000000, 0x00200010, 0x000 }, + { 0x00000000, 0x14c00000, 0x3be }, + { 0x8c000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00003fff, 0x40280a20, 0x000 }, + { 0x80000000, 0x40280e20, 0x000 }, + { 0x40000000, 0xc0281220, 0x000 }, + { 0x00040000, 0x00694622, 0x614 }, + { 0x00000000, 0x00201410, 0x000 }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x3cc }, + { 0x00000000, 0xc0401800, 0x3cf }, + { 0x00003fff, 0xc0281a20, 0x000 }, + { 0x00040000, 0x00694626, 0x614 }, + { 0x00000000, 0x00201810, 0x000 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x3d2 }, + { 0x00000000, 0xc0401c00, 0x3d5 }, + { 0x00003fff, 0xc0281e20, 0x000 }, + { 0x00040000, 0x00694627, 0x614 }, + { 0x00000000, 0x00201c10, 0x000 }, + { 0x00000000, 0x00204402, 0x000 }, + { 0x00000000, 0x002820c5, 0x000 }, + { 0x00000000, 0x004948e8, 0x000 }, + { 0xa5800000, 0x00200811, 0x000 }, + { 0x00002000, 0x00200c11, 0x000 }, + { 0x83000000, 0x00604411, 0x3fd }, + { 0x00000000, 0x00204402, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x40204800, 0x000 }, + { 0x0000001f, 0xc0210220, 0x000 }, + { 0x00000000, 0x14c00000, 0x3e2 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0000ffff, 0xc0481220, 0x3ea }, + { 0xa7800000, 0x00200811, 0x000 }, + { 0x0000a000, 0x00200c11, 0x000 }, + { 0x83000000, 0x00604411, 0x3fd }, + { 0x00000000, 0x00204402, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000ffff, 0xc0281220, 0x000 }, + { 0x83000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00304883, 0x000 }, + { 0x84000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x1d000000, 0x000 }, + { 0x83000000, 0x00604411, 0x3fd }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0xa9800000, 0x00200811, 0x000 }, + { 0x0000c000, 0x00400c11, 0x3e5 }, + { 0xab800000, 0x00200811, 0x000 }, + { 0x0000f8e0, 0x00400c11, 0x3e5 }, + { 0xad800000, 0x00200811, 0x000 }, + { 0x0000f880, 0x00400c11, 0x3e5 }, + { 0xb3800000, 0x00200811, 0x000 }, + { 0x0000f3fc, 0x00400c11, 0x3e5 }, + { 0xaf800000, 0x00200811, 0x000 }, + { 0x0000e000, 0x00400c11, 0x3e5 }, + { 0xb1800000, 0x00200811, 0x000 }, + { 0x0000f000, 0x00400c11, 0x3e5 }, + { 0x83000000, 0x00204411, 0x000 }, + { 0x00002148, 0x00204811, 0x000 }, + { 0x84000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x1d000000, 0x000 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00182000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0018a000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0018c000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0018f8e0, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0018f880, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0018e000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0018f000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0018f3fc, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x86000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00404801, 0x000 }, + { 0x85000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00404801, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x0004217f, 0x00604411, 0x614 }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x00000000, 0x00404c02, 0x42e }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x00000000, 0xc0201000, 0x000 }, + { 0x00000000, 0xc0201400, 0x000 }, + { 0x00000000, 0xc0201800, 0x000 }, + { 0x00000000, 0xc0201c00, 0x000 }, + { 0x00007f00, 0x00280a21, 0x000 }, + { 0x00004500, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x43c }, + { 0x00000000, 0xc0202000, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x00000010, 0x00280a23, 0x000 }, + { 0x00000010, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x444 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00040000, 0x00694624, 0x614 }, + { 0x00000000, 0x00400000, 0x44d }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000216d, 0x00204411, 0x000 }, + { 0x00000000, 0x00204804, 0x000 }, + { 0x00000000, 0x00204805, 0x000 }, + { 0x00000000, 0x1ac00000, 0x449 }, + { 0x9e000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000000, 0x1ae00000, 0x44c }, + { 0x00000000, 0x002824f0, 0x000 }, + { 0x00000007, 0x00280a23, 0x000 }, + { 0x00000001, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x454 }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x04e00000, 0x46d }, + { 0x00000000, 0x00400000, 0x47a }, + { 0x00000002, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x459 }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x02e00000, 0x46d }, + { 0x00000000, 0x00400000, 0x47a }, + { 0x00000003, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x45e }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x0ce00000, 0x46d }, + { 0x00000000, 0x00400000, 0x47a }, + { 0x00000004, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x463 }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x0ae00000, 0x46d }, + { 0x00000000, 0x00400000, 0x47a }, + { 0x00000005, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x468 }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x06e00000, 0x46d }, + { 0x00000000, 0x00400000, 0x47a }, + { 0x00000006, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x46d }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x08e00000, 0x46d }, + { 0x00000000, 0x00400000, 0x47a }, + { 0x00007f00, 0x00280a21, 0x000 }, + { 0x00004500, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x000 }, + { 0x00000008, 0x00210a23, 0x000 }, + { 0x00000000, 0x14c00000, 0x477 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x00000000, 0xc0204400, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00007f00, 0x00280a21, 0x000 }, + { 0x00004500, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x480 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0400000, 0x000 }, + { 0x00000000, 0x00404c08, 0x43c }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x00000011, 0x40211220, 0x000 }, + { 0x00000012, 0x40211620, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00210225, 0x000 }, + { 0x00000000, 0x14e00000, 0x48a }, + { 0x00040000, 0xc0494a20, 0x48b }, + { 0xfffbffff, 0xc0284a20, 0x000 }, + { 0x00000000, 0x00210223, 0x000 }, + { 0x00000000, 0x14e00000, 0x497 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x00210224, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000c, 0x00204811, 0x000 }, + { 0x00000000, 0x00200010, 0x000 }, + { 0x00000000, 0x14c00000, 0x493 }, + { 0xa0000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000004, 0x00204811, 0x000 }, + { 0x0000216b, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204810, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000005, 0x00204811, 0x000 }, + { 0x0000216c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204810, 0x000 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00400000, 0x491 }, + { 0x00000000, 0xc0210a20, 0x000 }, + { 0x00000000, 0x14c00000, 0x4ae }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000216d, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x1ac00000, 0x4a9 }, + { 0x9e000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000000, 0x1ae00000, 0x4ac }, + { 0x00000000, 0x00400000, 0x4b2 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00040000, 0xc0294620, 0x000 }, + { 0x00000000, 0xc0600000, 0x614 }, + { 0x00000001, 0x00210222, 0x000 }, + { 0x00000000, 0x14c00000, 0x4b9 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x00000000, 0xc0204400, 0x000 }, + { 0x00000000, 0xc0404810, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x0000000d, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x614 }, + { 0x00000000, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x4bb }, + { 0x00002180, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000003, 0x00333e2f, 0x000 }, + { 0x00000001, 0x00210221, 0x000 }, + { 0x00000000, 0x14e00000, 0x4eb }, + { 0x00000035, 0x00200a2d, 0x000 }, + { 0x00040000, 0x18e00c11, 0x4da }, + { 0x00000001, 0x00333e2f, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xd8c04800, 0x4ce }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000036, 0x0020122d, 0x000 }, + { 0x00000000, 0x00290c83, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000011, 0x00210224, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x00000000, 0x00400000, 0x491 }, + { 0x00000035, 0xc0203620, 0x000 }, + { 0x00000036, 0xc0403620, 0x000 }, + { 0x0000304a, 0x00204411, 0x000 }, + { 0xe0000000, 0xc0484a20, 0x000 }, + { 0x0000000f, 0x00210221, 0x000 }, + { 0x00000000, 0x14c00000, 0x4f2 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0xd9000000, 0x000 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000002, 0x00204811, 0x000 }, + { 0x000000ff, 0x00280e30, 0x000 }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x4f6 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000000, 0x14c00000, 0x50b }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x00000024, 0x00203623, 0x000 }, + { 0x00000034, 0x00203623, 0x000 }, + { 0x00000032, 0x00203623, 0x000 }, + { 0x00000031, 0x00203623, 0x000 }, + { 0x0000001d, 0x00203623, 0x000 }, + { 0x0000002d, 0x00203623, 0x000 }, + { 0x0000002e, 0x00203623, 0x000 }, + { 0x0000001b, 0x00203623, 0x000 }, + { 0x0000001c, 0x00203623, 0x000 }, + { 0xffffe000, 0x00200c11, 0x000 }, + { 0x00000029, 0x00203623, 0x000 }, + { 0x0000002a, 0x00203623, 0x000 }, + { 0x00001fff, 0x00200c11, 0x000 }, + { 0x0000002b, 0x00203623, 0x000 }, + { 0x0000002c, 0x00203623, 0x000 }, + { 0xf1ffffff, 0x00283a2e, 0x000 }, + { 0x0000001a, 0xc0220e20, 0x000 }, + { 0x00000000, 0x0029386e, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x00000033, 0x40203620, 0x000 }, + { 0x87000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1f4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x9d000000, 0x00204411, 0x000 }, + { 0x0000001f, 0x40214a20, 0x000 }, + { 0x96000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x00000000, 0xc0201000, 0x000 }, + { 0x0000001f, 0x00211624, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x00000025, 0x00203623, 0x000 }, + { 0x00000003, 0x00281e23, 0x000 }, + { 0x00000008, 0x00222223, 0x000 }, + { 0xfffff000, 0x00282228, 0x000 }, + { 0x00000000, 0x002920e8, 0x000 }, + { 0x00000027, 0x00203628, 0x000 }, + { 0x00000018, 0x00211e23, 0x000 }, + { 0x00000028, 0x00203627, 0x000 }, + { 0x00000002, 0x00221624, 0x000 }, + { 0x00000000, 0x003014a8, 0x000 }, + { 0x00000026, 0x00203625, 0x000 }, + { 0x00000003, 0x00211a24, 0x000 }, + { 0x10000000, 0x00281a26, 0x000 }, + { 0xefffffff, 0x00283a2e, 0x000 }, + { 0x00000000, 0x004938ce, 0x602 }, + { 0x00000001, 0x40280a20, 0x000 }, + { 0x00000006, 0x40280e20, 0x000 }, + { 0x00000300, 0xc0281220, 0x000 }, + { 0x00000008, 0x00211224, 0x000 }, + { 0x00000000, 0xc0201620, 0x000 }, + { 0x00000000, 0xc0201a20, 0x000 }, + { 0x00000000, 0x00210222, 0x000 }, + { 0x00000000, 0x14c00000, 0x541 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00002258, 0x00300a24, 0x000 }, + { 0x00040000, 0x00694622, 0x614 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204805, 0x000 }, + { 0x00020000, 0x00294a26, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x549 }, + { 0x00000000, 0xc0201c10, 0x000 }, + { 0x00000000, 0xc0400000, 0x55b }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x549 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00002258, 0x00300a24, 0x000 }, + { 0x00040000, 0x00694622, 0x614 }, + { 0x00000000, 0xc0201c10, 0x000 }, + { 0x00000000, 0xc0400000, 0x55b }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x54d }, + { 0x00000000, 0xc0201c00, 0x000 }, + { 0x00000000, 0xc0400000, 0x55b }, + { 0x00000004, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x559 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000216d, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x1ac00000, 0x554 }, + { 0x9e000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000000, 0x1ae00000, 0x557 }, + { 0x00000000, 0x00401c10, 0x55b }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0400000, 0x000 }, + { 0x00000000, 0x0ee00000, 0x55d }, + { 0x00000000, 0x00600000, 0x5a4 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x56d }, + { 0x0000a2b7, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a2b6, 0x00604411, 0x614 }, + { 0x0000001a, 0x00212230, 0x000 }, + { 0x00000006, 0x00222630, 0x000 }, + { 0x0000a2c4, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x56b }, + { 0x0000a2d1, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d1, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x00000001, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x57d }, + { 0x0000a2bb, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a2ba, 0x00604411, 0x614 }, + { 0x0000001a, 0x00212230, 0x000 }, + { 0x00000006, 0x00222630, 0x000 }, + { 0x0000a2c5, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x57b }, + { 0x0000a2d2, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d2, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x00000002, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x58d }, + { 0x0000a2bf, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a2be, 0x00604411, 0x614 }, + { 0x0000001a, 0x00212230, 0x000 }, + { 0x00000006, 0x00222630, 0x000 }, + { 0x0000a2c6, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x58b }, + { 0x0000a2d3, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d3, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x0000a2c3, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a2c2, 0x00604411, 0x614 }, + { 0x0000001a, 0x00212230, 0x000 }, + { 0x00000006, 0x00222630, 0x000 }, + { 0x0000a2c7, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x599 }, + { 0x0000a2d4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d4, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x85000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204801, 0x000 }, + { 0x0000304a, 0x00204411, 0x000 }, + { 0x01000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00400000, 0x59f }, + { 0xa4000000, 0xc0204411, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000000, 0xc0600000, 0x5a4 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000005, 0x00204811, 0x000 }, + { 0x0000a1f4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x88000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0xff000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000002, 0x00804811, 0x000 }, + { 0x00000000, 0x0ee00000, 0x5b7 }, + { 0x00001000, 0x00200811, 0x000 }, + { 0x00000034, 0x00203622, 0x000 }, + { 0x00000000, 0x00600000, 0x5bb }, + { 0x00000000, 0x00600000, 0x5a4 }, + { 0x98000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00804811, 0x000 }, + { 0x00000000, 0xc0600000, 0x5bb }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000022, 0x00204811, 0x000 }, + { 0x89000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0xff000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000002, 0x00804811, 0x000 }, + { 0x0000217a, 0xc0204411, 0x000 }, + { 0x00000000, 0x00404811, 0x000 }, + { 0x97000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0xff000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000002, 0x00804811, 0x000 }, + { 0x00000000, 0x00600000, 0x5e1 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0xc0204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000016, 0x00604811, 0x35e }, + { 0x00000016, 0x00204811, 0x000 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00010000, 0x00204811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x09800000, 0x00204811, 0x000 }, + { 0xffffffff, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x0004217f, 0x00604411, 0x614 }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x00000004, 0x00404c11, 0x5dc }, + { 0x0000001d, 0x00201e2d, 0x000 }, + { 0x00000004, 0x00291e27, 0x000 }, + { 0x0000001d, 0x00803627, 0x000 }, + { 0x0000001d, 0x00201e2d, 0x000 }, + { 0xfffffffb, 0x00281e27, 0x000 }, + { 0x0000001d, 0x00803627, 0x000 }, + { 0x0000001d, 0x00201e2d, 0x000 }, + { 0x00000008, 0x00291e27, 0x000 }, + { 0x0000001d, 0x00803627, 0x000 }, + { 0x0000001d, 0x00201e2d, 0x000 }, + { 0xfffffff7, 0x00281e27, 0x000 }, + { 0x0000001d, 0x00803627, 0x000 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000016, 0x00604811, 0x35e }, + { 0x00000016, 0x00204811, 0x000 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00010000, 0x00204811, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x01800000, 0x00204811, 0x000 }, + { 0x00ffffff, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004217f, 0x00604411, 0x614 }, + { 0x00000000, 0x00200010, 0x000 }, + { 0x00000000, 0x14c00000, 0x613 }, + { 0x00000010, 0x00404c11, 0x5f9 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x38c00000, 0x000 }, + { 0x00000025, 0x00200a2d, 0x000 }, + { 0x00000026, 0x00200e2d, 0x000 }, + { 0x00000027, 0x0020122d, 0x000 }, + { 0x00000028, 0x0020162d, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204804, 0x000 }, + { 0x00000000, 0x00204805, 0x000 }, + { 0x00000000, 0x00204801, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000004, 0x00301224, 0x000 }, + { 0x00000000, 0x002f0064, 0x000 }, + { 0x00000000, 0x0cc00000, 0x612 }, + { 0x00000003, 0x00281a22, 0x000 }, + { 0x00000008, 0x00221222, 0x000 }, + { 0xfffff000, 0x00281224, 0x000 }, + { 0x00000000, 0x002910c4, 0x000 }, + { 0x00000027, 0x00403624, 0x000 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x1ac00000, 0x614 }, + { 0x9f000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000000, 0x1ae00000, 0x617 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00001000, 0x00600411, 0x2fe }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x19f }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001b, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0001a1fd, 0xc0204411, 0x000 }, + { 0x00000029, 0x00201e2d, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x0000002c, 0x0020222d, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000002a, 0x0020222d, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000002b, 0x00201e2d, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00404811, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x013304ef, 0x059b0239, 0x000 }, + { 0x01b00159, 0x0425059b, 0x000 }, + { 0x021201f6, 0x02390142, 0x000 }, + { 0x0210022e, 0x0289022a, 0x000 }, + { 0x03c2059b, 0x059b059b, 0x000 }, + { 0x05cd05ce, 0x0308059b, 0x000 }, + { 0x059b05a0, 0x03090329, 0x000 }, + { 0x0313026b, 0x032b031d, 0x000 }, + { 0x059b059b, 0x059b059b, 0x000 }, + { 0x059b052c, 0x059b059b, 0x000 }, + { 0x03a5059b, 0x04a2032d, 0x000 }, + { 0x04810433, 0x0423059b, 0x000 }, + { 0x04bb04ed, 0x042704c8, 0x000 }, + { 0x043304f4, 0x033a0365, 0x000 }, + { 0x059b059b, 0x059b059b, 0x000 }, + { 0x059b059b, 0x059b059b, 0x000 }, + { 0x059b059b, 0x05b905a2, 0x000 }, + { 0x059b059b, 0x0007059b, 0x000 }, + { 0x059b059b, 0x059b059b, 0x000 }, + { 0x059b059b, 0x059b059b, 0x000 }, + { 0x03e303d8, 0x03f303f1, 0x000 }, + { 0x03f903f5, 0x03f703fb, 0x000 }, + { 0x04070403, 0x040f040b, 0x000 }, + { 0x04170413, 0x041f041b, 0x000 }, + { 0x059b059b, 0x059b059b, 0x000 }, + { 0x059b059b, 0x059b059b, 0x000 }, + { 0x059b059b, 0x059b059b, 0x000 }, + { 0x00020600, 0x06190006, 0x000 }, +}; + +static const u32 R600_pfp_microcode[] = { +0xd40071, +0xd40072, +0xca0400, +0xa00000, +0x7e828b, +0x800003, +0xca0400, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xc41838, +0xca2400, +0xca2800, +0x9581a8, +0xc41c3a, +0xc3c000, +0xca0800, +0xca0c00, +0x7c744b, +0xc20005, +0x99c000, +0xc41c3a, +0x7c744c, +0xc0fff0, +0x042c04, +0x309002, +0x7d2500, +0x351402, +0x7d350b, +0x255403, +0x7cd580, +0x259c03, +0x95c004, +0xd5001b, +0x7eddc1, +0x7d9d80, +0xd6801b, +0xd5801b, +0xd4401e, +0xd5401e, +0xd6401e, +0xd6801e, +0xd4801e, +0xd4c01e, +0x9783d4, +0xd5c01e, +0xca0800, +0x80001b, +0xca0c00, +0xe4011e, +0xd4001e, +0x80000d, +0xc41838, +0xe4013e, +0xd4001e, +0x80000d, +0xc41838, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xe4011e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xe4013e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xca1800, +0xd4401e, +0xd5801e, +0x800054, +0xd40073, +0xd4401e, +0xca0800, +0xca0c00, +0xca1000, +0xd48019, +0xd4c018, +0xd50017, +0xd4801e, +0xd4c01e, +0xd5001e, +0xe2001e, +0xca0400, +0xa00000, +0x7e828b, +0xca0800, +0xd48060, +0xd4401e, +0x800002, +0xd4801e, +0xca0800, +0xd48061, +0xd4401e, +0x800002, +0xd4801e, +0xca0800, +0xca0c00, +0xd4401e, +0xd48016, +0xd4c016, +0xd4801e, +0x8001b9, +0xd4c01e, +0xc6083e, +0xca0c00, +0xca1000, +0x948004, +0xca1400, +0xe420f3, +0xd42013, +0xd56065, +0xd4e01c, +0xd5201c, +0xd5601c, +0x800002, +0x062001, +0xc6083e, +0xca0c00, +0xca1000, +0x9483f7, +0xca1400, +0xe420f3, +0x80007a, +0xd42013, +0xc6083e, +0xca0c00, +0xca1000, +0x9883ef, +0xca1400, +0xd40064, +0x80008e, +0x000000, +0xc41432, +0xc6183e, +0xc4082f, +0x954005, +0xc40c30, +0xd4401e, +0x800002, +0xee001e, +0x9583f5, +0xc41031, +0xd44033, +0xd52065, +0xd4a01c, +0xd4e01c, +0xd5201c, +0xd40073, +0xe4015e, +0xd4001e, +0x8001b9, +0x062001, +0x0a2001, +0xd60074, +0xc40836, +0xc61040, +0x988007, +0xcc3835, +0x95010f, +0xd4001f, +0xd46062, +0x800002, +0xd42062, +0xcc1433, +0x8401bc, +0xd40070, +0xd5401e, +0x800002, +0xee001e, +0xca0c00, +0xca1000, +0xd4c01a, +0x8401bc, +0xd5001a, +0xcc0443, +0x35101f, +0x2c9401, +0x7d098b, +0x984005, +0x7d15cb, +0xd4001a, +0x8001b9, +0xd4006d, +0x344401, +0xcc0c44, +0x98403a, +0xcc2c46, +0x958004, +0xcc0445, +0x8001b9, +0xd4001a, +0xd4c01a, +0x282801, +0x8400f3, +0xcc1003, +0x98801b, +0x04380c, +0x8400f3, +0xcc1003, +0x988017, +0x043808, +0x8400f3, +0xcc1003, +0x988013, +0x043804, +0x8400f3, +0xcc1003, +0x988014, +0xcc1047, +0x9a8009, +0xcc1448, +0x9840da, +0xd4006d, +0xcc1844, +0xd5001a, +0xd5401a, +0x8000cc, +0xd5801a, +0x96c0d3, +0xd4006d, +0x8001b9, +0xd4006e, +0x9ac003, +0xd4006d, +0xd4006e, +0x800002, +0xec007f, +0x9ac0ca, +0xd4006d, +0x8001b9, +0xd4006e, +0xcc1403, +0xcc1803, +0xcc1c03, +0x7d9103, +0x7dd583, +0x7d190c, +0x35cc1f, +0x35701f, +0x7cf0cb, +0x7cd08b, +0x880000, +0x7e8e8b, +0x95c004, +0xd4006e, +0x8001b9, +0xd4001a, +0xd4c01a, +0xcc0803, +0xcc0c03, +0xcc1003, +0xcc1403, +0xcc1803, +0xcc1c03, +0xcc2403, +0xcc2803, +0x35c41f, +0x36b01f, +0x7c704b, +0x34f01f, +0x7c704b, +0x35701f, +0x7c704b, +0x7d8881, +0x7dccc1, +0x7e5101, +0x7e9541, +0x7c9082, +0x7cd4c2, +0x7c848b, +0x9ac003, +0x7c8c8b, +0x2c8801, +0x98809c, +0xd4006d, +0x98409a, +0xd4006e, +0xcc0847, +0xcc0c48, +0xcc1044, +0xd4801a, +0xd4c01a, +0x800104, +0xd5001a, +0xcc0832, +0xd40032, +0x9482d8, +0xca0c00, +0xd4401e, +0x800002, +0xd4001e, +0xe4011e, +0xd4001e, +0xca0800, +0xca0c00, +0xca1000, +0xd4401e, +0xca1400, +0xd4801e, +0xd4c01e, +0xd5001e, +0xd5401e, +0xd54034, +0x800002, +0xee001e, +0x280404, +0xe2001a, +0xe2001a, +0xd4401a, +0xca3800, +0xcc0803, +0xcc0c03, +0xcc0c03, +0xcc0c03, +0x9882bc, +0x000000, +0x8401bc, +0xd7806f, +0x800002, +0xee001f, +0xca0400, +0xc2ff00, +0xcc0834, +0xc13fff, +0x7c74cb, +0x7cc90b, +0x7d010f, +0x9902af, +0x7c738b, +0x8401bc, +0xd7806f, +0x800002, +0xee001f, +0xca0800, +0x281900, +0x7d898b, +0x958014, +0x281404, +0xca0c00, +0xca1000, +0xca1c00, +0xca2400, +0xe2001f, +0xd4c01a, +0xd5001a, +0xd5401a, +0xcc1803, +0xcc2c03, +0xcc2c03, +0xcc2c03, +0x7da58b, +0x7d9c47, +0x984296, +0x000000, +0x800164, +0xd4c01a, +0xd4401e, +0xd4801e, +0x800002, +0xee001e, +0xe4011e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xe4013e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xca0800, +0x248c06, +0x0ccc06, +0x98c006, +0xcc1049, +0x990004, +0xd40071, +0xe4011e, +0xd4001e, +0xd4401e, +0xd4801e, +0x800002, +0xee001e, +0xca0800, +0xca0c00, +0x34d018, +0x251001, +0x95001f, +0xc17fff, +0xca1000, +0xca1400, +0xca1800, +0xd4801d, +0xd4c01d, +0x7db18b, +0xc14202, +0xc2c001, +0xd5801d, +0x34dc0e, +0x7d5d4c, +0x7f734c, +0xd7401e, +0xd5001e, +0xd5401e, +0xc14200, +0xc2c000, +0x099c01, +0x31dc10, +0x7f5f4c, +0x7f734c, +0x7d8380, +0xd5806f, +0xd58066, +0xd7401e, +0xec005e, +0xc82402, +0x8001b9, +0xd60074, +0xd4401e, +0xd4801e, +0xd4c01e, +0x800002, +0xee001e, +0x800002, +0xee001f, +0xd4001f, +0x800002, +0xd4001f, +0xd4001f, +0x880000, +0xd4001f, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x010174, +0x02017b, +0x030090, +0x040080, +0x050005, +0x060040, +0x070033, +0x08012f, +0x090047, +0x0a0037, +0x1001b7, +0x1700a4, +0x22013d, +0x23014c, +0x2000b5, +0x240128, +0x27004e, +0x28006b, +0x2a0061, +0x2b0053, +0x2f0066, +0x320088, +0x340182, +0x3c0159, +0x3f0073, +0x41018f, +0x440131, +0x550176, +0x56017d, +0x60000c, +0x610035, +0x620039, +0x630039, +0x640039, +0x650039, +0x660039, +0x670039, +0x68003b, +0x690042, +0x6a0049, +0x6b0049, +0x6c0049, +0x6d0049, +0x6e0049, +0x6f0049, +0x7301b7, +0x000007, +0x000007, +0x000007, +0x000007, +0x000007, +0x000007, +0x000007, +0x000007, +0x000007, +0x000007, +0x000007, +0x000007, +0x000007, +0x000007, +0x000007, +0x000007, +0x000007, +0x000007, +}; + +static const u32 RV610_cp_microcode[][3] = { + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0000ffff, 0x00284621, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x00000000, 0x00e00000, 0x000 }, + { 0x00010000, 0xc0294620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00042004, 0x00604411, 0x68d }, + { 0x00000000, 0x00600000, 0x631 }, + { 0x00000000, 0x00600000, 0x645 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000f00, 0x00281622, 0x000 }, + { 0x00000008, 0x00211625, 0x000 }, + { 0x00000018, 0x00203625, 0x000 }, + { 0x8d000000, 0x00204411, 0x000 }, + { 0x00000004, 0x002f0225, 0x000 }, + { 0x00000000, 0x0ce00000, 0x018 }, + { 0x00412000, 0x00404811, 0x019 }, + { 0x00422000, 0x00204811, 0x000 }, + { 0x8e000000, 0x00204411, 0x000 }, + { 0x00000028, 0x00204a2d, 0x000 }, + { 0x90000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204805, 0x000 }, + { 0x0000000c, 0x00211622, 0x000 }, + { 0x00000003, 0x00281625, 0x000 }, + { 0x00000019, 0x00211a22, 0x000 }, + { 0x00000004, 0x00281a26, 0x000 }, + { 0x00000000, 0x002914c5, 0x000 }, + { 0x00000019, 0x00203625, 0x000 }, + { 0x00000000, 0x003a1402, 0x000 }, + { 0x00000016, 0x00211625, 0x000 }, + { 0x00000003, 0x00281625, 0x000 }, + { 0x00000017, 0x00200e2d, 0x000 }, + { 0xfffffffc, 0x00280e23, 0x000 }, + { 0x00000000, 0x002914a3, 0x000 }, + { 0x00000017, 0x00203625, 0x000 }, + { 0x00008000, 0x00280e22, 0x000 }, + { 0x00000007, 0x00220e23, 0x000 }, + { 0x00000000, 0x0029386e, 0x000 }, + { 0x20000000, 0x00280e22, 0x000 }, + { 0x00000006, 0x00210e23, 0x000 }, + { 0x00000000, 0x0029386e, 0x000 }, + { 0x00000000, 0x00220222, 0x000 }, + { 0x00000000, 0x14e00000, 0x038 }, + { 0x00000000, 0x2ee00000, 0x035 }, + { 0x00000000, 0x2ce00000, 0x037 }, + { 0x00000000, 0x00400e2d, 0x039 }, + { 0x00000008, 0x00200e2d, 0x000 }, + { 0x00000009, 0x0040122d, 0x046 }, + { 0x00000001, 0x00400e2d, 0x039 }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x003ffffc, 0x00281223, 0x000 }, + { 0x00000002, 0x00221224, 0x000 }, + { 0x0000001f, 0x00211e23, 0x000 }, + { 0x00000000, 0x14e00000, 0x03e }, + { 0x00000008, 0x00401c11, 0x041 }, + { 0x0000000d, 0x00201e2d, 0x000 }, + { 0x0000000f, 0x00281e27, 0x000 }, + { 0x00000003, 0x00221e27, 0x000 }, + { 0x7fc00000, 0x00281a23, 0x000 }, + { 0x00000014, 0x00211a26, 0x000 }, + { 0x00000001, 0x00331a26, 0x000 }, + { 0x00000008, 0x00221a26, 0x000 }, + { 0x00000000, 0x00290cc7, 0x000 }, + { 0x00000027, 0x00203624, 0x000 }, + { 0x00007f00, 0x00281221, 0x000 }, + { 0x00001400, 0x002f0224, 0x000 }, + { 0x00000000, 0x0ce00000, 0x04b }, + { 0x00000001, 0x00290e23, 0x000 }, + { 0x0000000e, 0x00203623, 0x000 }, + { 0x0000e000, 0x00204411, 0x000 }, + { 0xfff80000, 0x00294a23, 0x000 }, + { 0x00000000, 0x003a2c02, 0x000 }, + { 0x00000002, 0x00220e2b, 0x000 }, + { 0xfc000000, 0x00280e23, 0x000 }, + { 0x0000000f, 0x00203623, 0x000 }, + { 0x00001fff, 0x00294a23, 0x000 }, + { 0x00000027, 0x00204a2d, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000029, 0x00200e2d, 0x000 }, + { 0x060a0200, 0x00294a23, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000001, 0x00210222, 0x000 }, + { 0x00000000, 0x14e00000, 0x061 }, + { 0x00000000, 0x2ee00000, 0x05f }, + { 0x00000000, 0x2ce00000, 0x05e }, + { 0x00000000, 0x00400e2d, 0x062 }, + { 0x00000001, 0x00400e2d, 0x062 }, + { 0x0000000a, 0x00200e2d, 0x000 }, + { 0x0000000b, 0x0040122d, 0x06a }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x003ffffc, 0x00281223, 0x000 }, + { 0x00000002, 0x00221224, 0x000 }, + { 0x7fc00000, 0x00281623, 0x000 }, + { 0x00000014, 0x00211625, 0x000 }, + { 0x00000001, 0x00331625, 0x000 }, + { 0x80000000, 0x00280e23, 0x000 }, + { 0x00000000, 0x00290ca3, 0x000 }, + { 0x3ffffc00, 0x00290e23, 0x000 }, + { 0x0000001f, 0x00211e23, 0x000 }, + { 0x00000000, 0x14e00000, 0x06d }, + { 0x00000100, 0x00401c11, 0x070 }, + { 0x0000000d, 0x00201e2d, 0x000 }, + { 0x000000f0, 0x00281e27, 0x000 }, + { 0x00000004, 0x00221e27, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000d, 0x00204811, 0x000 }, + { 0xfffff0ff, 0x00281a30, 0x000 }, + { 0x0000a028, 0x00204411, 0x000 }, + { 0x00000000, 0x002948e6, 0x000 }, + { 0x0000a018, 0x00204411, 0x000 }, + { 0x3fffffff, 0x00284a23, 0x000 }, + { 0x0000a010, 0x00204411, 0x000 }, + { 0x00000000, 0x00204804, 0x000 }, + { 0x00000030, 0x0020162d, 0x000 }, + { 0x00000002, 0x00291625, 0x000 }, + { 0x00000030, 0x00203625, 0x000 }, + { 0x00000025, 0x0020162d, 0x000 }, + { 0x00000000, 0x002f00a3, 0x000 }, + { 0x00000000, 0x0cc00000, 0x083 }, + { 0x00000026, 0x0020162d, 0x000 }, + { 0x00000000, 0x002f00a4, 0x000 }, + { 0x00000000, 0x0cc00000, 0x084 }, + { 0x00000000, 0x00400000, 0x08a }, + { 0x00000025, 0x00203623, 0x000 }, + { 0x00000026, 0x00203624, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000002, 0x00210227, 0x000 }, + { 0x00000000, 0x14e00000, 0x08a }, + { 0x00000000, 0x00600000, 0x668 }, + { 0x00000000, 0x00600000, 0x65c }, + { 0x00000002, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x08d }, + { 0x00000012, 0xc0403620, 0x093 }, + { 0x00000000, 0x2ee00000, 0x091 }, + { 0x00000000, 0x2ce00000, 0x090 }, + { 0x00000002, 0x00400e2d, 0x092 }, + { 0x00000003, 0x00400e2d, 0x092 }, + { 0x0000000c, 0x00200e2d, 0x000 }, + { 0x00000012, 0x00203623, 0x000 }, + { 0x00000003, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x098 }, + { 0x0000a00c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x0a0 }, + { 0x0000a00c, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x2ee00000, 0x09e }, + { 0x00000000, 0x2ce00000, 0x09d }, + { 0x00000002, 0x00400e2d, 0x09f }, + { 0x00000003, 0x00400e2d, 0x09f }, + { 0x0000000c, 0x00200e2d, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000000, 0x003a0c02, 0x000 }, + { 0x003f0000, 0x00280e23, 0x000 }, + { 0x00000010, 0x00210e23, 0x000 }, + { 0x00000011, 0x00203623, 0x000 }, + { 0x0000001e, 0x0021022b, 0x000 }, + { 0x00000000, 0x14c00000, 0x0a7 }, + { 0x00000016, 0xc0203620, 0x000 }, + { 0x0000001f, 0x0021022b, 0x000 }, + { 0x00000000, 0x14c00000, 0x0aa }, + { 0x00000015, 0xc0203620, 0x000 }, + { 0x00000008, 0x00210e2b, 0x000 }, + { 0x0000007f, 0x00280e23, 0x000 }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0e1 }, + { 0x00000000, 0x27000000, 0x000 }, + { 0x00000000, 0x00600000, 0x2a3 }, + { 0x00000001, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ae00000, 0x0b3 }, + { 0x00000000, 0x00600000, 0x13a }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x0000000c, 0x00221e30, 0x000 }, + { 0x99800000, 0x00204411, 0x000 }, + { 0x00000004, 0x0020122d, 0x000 }, + { 0x00000008, 0x00221224, 0x000 }, + { 0x00000010, 0x00201811, 0x000 }, + { 0x00000000, 0x00291ce4, 0x000 }, + { 0x00000000, 0x00604807, 0x12f }, + { 0x9b000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x9c000000, 0x00204411, 0x000 }, + { 0x00000000, 0x0033146f, 0x000 }, + { 0x00000001, 0x00333e23, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0x00203c05, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000e, 0x00204811, 0x000 }, + { 0x00000000, 0x00201010, 0x000 }, + { 0x0000e007, 0x00204411, 0x000 }, + { 0x0000000f, 0x0021022b, 0x000 }, + { 0x00000000, 0x14c00000, 0x0cb }, + { 0x00f8ff08, 0x00204811, 0x000 }, + { 0x98000000, 0x00404811, 0x0dc }, + { 0x000000f0, 0x00280e22, 0x000 }, + { 0x000000a0, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x0da }, + { 0x00000011, 0x00200e2d, 0x000 }, + { 0x00000001, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0d5 }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0d4 }, + { 0x00003f00, 0x00400c11, 0x0d6 }, + { 0x00001f00, 0x00400c11, 0x0d6 }, + { 0x00000f00, 0x00200c11, 0x000 }, + { 0x00380009, 0x00294a23, 0x000 }, + { 0x3f000000, 0x00280e2b, 0x000 }, + { 0x00000002, 0x00220e23, 0x000 }, + { 0x00000007, 0x00494a23, 0x0dc }, + { 0x00380f09, 0x00204811, 0x000 }, + { 0x68000007, 0x00204811, 0x000 }, + { 0x00000008, 0x00214a27, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00294a24, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000a202, 0x00204411, 0x000 }, + { 0x00ff0000, 0x00280e22, 0x000 }, + { 0x00000080, 0x00294a23, 0x000 }, + { 0x00000027, 0x00200e2d, 0x000 }, + { 0x00000026, 0x0020122d, 0x000 }, + { 0x00000000, 0x002f0083, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0ea }, + { 0x00000000, 0x00600000, 0x662 }, + { 0x00000000, 0x00400000, 0x0eb }, + { 0x00000000, 0x00600000, 0x665 }, + { 0x00000007, 0x0020222d, 0x000 }, + { 0x00000005, 0x00220e22, 0x000 }, + { 0x00100000, 0x00280e23, 0x000 }, + { 0x00000000, 0x00292068, 0x000 }, + { 0x00000000, 0x003a0c02, 0x000 }, + { 0x000000ef, 0x00280e23, 0x000 }, + { 0x00000000, 0x00292068, 0x000 }, + { 0x00000017, 0x00200e2d, 0x000 }, + { 0x00000003, 0x00210223, 0x000 }, + { 0x00000000, 0x14e00000, 0x0f8 }, + { 0x0000000b, 0x00210228, 0x000 }, + { 0x00000000, 0x14c00000, 0x0f8 }, + { 0x00000400, 0x00292228, 0x000 }, + { 0x00000014, 0x00203628, 0x000 }, + { 0x0000001c, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x0fd }, + { 0x0000a30c, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000001e, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x10b }, + { 0x0000a30f, 0x00204411, 0x000 }, + { 0x00000011, 0x00200e2d, 0x000 }, + { 0x00000001, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x104 }, + { 0xffffffff, 0x00404811, 0x10b }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x107 }, + { 0x0000ffff, 0x00404811, 0x10b }, + { 0x00000004, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x10a }, + { 0x000000ff, 0x00404811, 0x10b }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0002c400, 0x00204411, 0x000 }, + { 0x0000001f, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x112 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x00000013, 0x00203623, 0x000 }, + { 0x00000018, 0x40224a20, 0x000 }, + { 0x00000010, 0xc0424a20, 0x114 }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x00000013, 0x00203623, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000000a, 0x00201011, 0x000 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0ce00000, 0x11b }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000001, 0x00531224, 0x117 }, + { 0xffbfffff, 0x00283a2e, 0x000 }, + { 0x0000001b, 0x00210222, 0x000 }, + { 0x00000000, 0x14c00000, 0x12e }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000d, 0x00204811, 0x000 }, + { 0x00000018, 0x00220e30, 0x000 }, + { 0xfc000000, 0x00280e23, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000e, 0x00204811, 0x000 }, + { 0x00000000, 0x00201010, 0x000 }, + { 0x0000e00e, 0x00204411, 0x000 }, + { 0x07f8ff08, 0x00204811, 0x000 }, + { 0x00000000, 0x00294a23, 0x000 }, + { 0x0000001c, 0x00201e2d, 0x000 }, + { 0x00000008, 0x00214a27, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00294a24, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x00800000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204806, 0x000 }, + { 0x00000008, 0x00214a27, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x0004217f, 0x00604411, 0x68d }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x68c }, + { 0x00000004, 0x00404c11, 0x135 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x0000001c, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x68d }, + { 0x00000011, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x13c }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x00000000, 0x00600000, 0x160 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x00000010, 0xc0211220, 0x000 }, + { 0x0000ffff, 0x40280620, 0x000 }, + { 0x00000010, 0xc0210a20, 0x000 }, + { 0x00000000, 0x00341461, 0x000 }, + { 0x00000000, 0x00741882, 0x2bb }, + { 0x0001a1fd, 0x00604411, 0x2e0 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x147 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00600000, 0x160 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x0000ffff, 0xc0281220, 0x000 }, + { 0x00000010, 0x40211620, 0x000 }, + { 0x0000ffff, 0xc0681a20, 0x2bb }, + { 0x0001a1fd, 0x00604411, 0x2e0 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x158 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000001, 0x00300a2f, 0x000 }, + { 0x00000001, 0x00210a22, 0x000 }, + { 0x00000003, 0x00384a22, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001a, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00804811, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600000, 0x18f }, + { 0x00000000, 0x00600000, 0x1a0 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00202c08, 0x000 }, + { 0x00000000, 0x00202411, 0x000 }, + { 0x00000000, 0x00202811, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x00000016, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x93800000, 0x00204411, 0x000 }, + { 0x00000002, 0x00221e29, 0x000 }, + { 0x00000000, 0x007048eb, 0x19c }, + { 0x00000000, 0x00600000, 0x2bb }, + { 0x00000001, 0x40330620, 0x000 }, + { 0x00000000, 0xc0302409, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00600000, 0x2a3 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ae00000, 0x181 }, + { 0x00000000, 0x00600000, 0x13a }, + { 0x00000000, 0x00400000, 0x186 }, + { 0x95000000, 0x00204411, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x186 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000001, 0x00530621, 0x182 }, + { 0x92000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0604800, 0x197 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000011, 0x0020062d, 0x000 }, + { 0x00000000, 0x0078042a, 0x2fb }, + { 0x00000000, 0x00202809, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x174 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000210, 0x00600411, 0x315 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x194 }, + { 0x00000015, 0xc0203620, 0x000 }, + { 0x00000016, 0xc0203620, 0x000 }, + { 0x3f800000, 0x00200411, 0x000 }, + { 0x46000000, 0x00600811, 0x1b2 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x19b }, + { 0x00000001, 0x00804811, 0x000 }, + { 0x00000021, 0x00804811, 0x000 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x00000010, 0xc0211220, 0x000 }, + { 0x0000ffff, 0x40281620, 0x000 }, + { 0x00000010, 0xc0811a20, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x00000008, 0x00221e30, 0x000 }, + { 0x00000029, 0x00201a2d, 0x000 }, + { 0x0000e000, 0x00204411, 0x000 }, + { 0xfffbff09, 0x00204811, 0x000 }, + { 0x0000000f, 0x0020222d, 0x000 }, + { 0x00001fff, 0x00294a28, 0x000 }, + { 0x00000006, 0x0020222d, 0x000 }, + { 0x00000000, 0x002920e8, 0x000 }, + { 0x00000000, 0x00204808, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00294a26, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000100, 0x00201811, 0x000 }, + { 0x00000008, 0x00621e28, 0x12f }, + { 0x00000008, 0x00822228, 0x000 }, + { 0x0002c000, 0x00204411, 0x000 }, + { 0x00000015, 0x00600e2d, 0x1bd }, + { 0x00000016, 0x00600e2d, 0x1bd }, + { 0x0000c008, 0x00204411, 0x000 }, + { 0x00000017, 0x00200e2d, 0x000 }, + { 0x00000000, 0x14c00000, 0x1b9 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00204801, 0x000 }, + { 0x39000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00804802, 0x000 }, + { 0x00000018, 0x00202e2d, 0x000 }, + { 0x00000000, 0x003b0d63, 0x000 }, + { 0x00000008, 0x00224a23, 0x000 }, + { 0x00000010, 0x00224a23, 0x000 }, + { 0x00000018, 0x00224a23, 0x000 }, + { 0x00000000, 0x00804803, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00001000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x00000007, 0x0021062f, 0x000 }, + { 0x00000013, 0x00200a2d, 0x000 }, + { 0x00000001, 0x00202c11, 0x000 }, + { 0x0000ffff, 0x40282220, 0x000 }, + { 0x0000000f, 0x00262228, 0x000 }, + { 0x00000010, 0x40212620, 0x000 }, + { 0x0000000f, 0x00262629, 0x000 }, + { 0x00000000, 0x00202802, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001b, 0x00204811, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x1e0 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000081, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000080, 0x00201c11, 0x000 }, + { 0x00000000, 0x002f0227, 0x000 }, + { 0x00000000, 0x0ce00000, 0x1dc }, + { 0x00000000, 0x00600000, 0x1e9 }, + { 0x00000001, 0x00531e27, 0x1d8 }, + { 0x00000001, 0x00202c11, 0x000 }, + { 0x0000001f, 0x00280a22, 0x000 }, + { 0x0000001f, 0x00282a2a, 0x000 }, + { 0x00000001, 0x00530621, 0x1d1 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000002, 0x00304a2f, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000001, 0x00301e2f, 0x000 }, + { 0x00000000, 0x002f0227, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00600000, 0x1e9 }, + { 0x00000001, 0x00531e27, 0x1e5 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x0000000f, 0x00260e23, 0x000 }, + { 0x00000010, 0xc0211220, 0x000 }, + { 0x0000000f, 0x00261224, 0x000 }, + { 0x00000000, 0x00201411, 0x000 }, + { 0x00000000, 0x00601811, 0x2bb }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0x002f022b, 0x000 }, + { 0x00000000, 0x0ce00000, 0x1f8 }, + { 0x00000010, 0x00221628, 0x000 }, + { 0xffff0000, 0x00281625, 0x000 }, + { 0x0000ffff, 0x00281a29, 0x000 }, + { 0x00000000, 0x002948c5, 0x000 }, + { 0x00000000, 0x0020480a, 0x000 }, + { 0x00000000, 0x00202c11, 0x000 }, + { 0x00000010, 0x00221623, 0x000 }, + { 0xffff0000, 0x00281625, 0x000 }, + { 0x0000ffff, 0x00281a24, 0x000 }, + { 0x00000000, 0x002948c5, 0x000 }, + { 0x00000000, 0x00731503, 0x205 }, + { 0x00000000, 0x00201805, 0x000 }, + { 0x00000000, 0x00731524, 0x205 }, + { 0x00000000, 0x002d14c5, 0x000 }, + { 0x00000000, 0x003008a2, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00202802, 0x000 }, + { 0x00000000, 0x00202003, 0x000 }, + { 0x00000000, 0x00802404, 0x000 }, + { 0x0000000f, 0x00210225, 0x000 }, + { 0x00000000, 0x14c00000, 0x68c }, + { 0x00000000, 0x002b1405, 0x000 }, + { 0x00000001, 0x00901625, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001a, 0x00294a22, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00384a21, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0000ffff, 0x40281220, 0x000 }, + { 0x00000010, 0xc0211a20, 0x000 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x00000010, 0xc0211620, 0x000 }, + { 0x00000000, 0x00741465, 0x2bb }, + { 0x0001a1fd, 0x00604411, 0x2e0 }, + { 0x00000001, 0x00330621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0cc00000, 0x219 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x212 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000000, 0x00600000, 0x645 }, + { 0x00000000, 0x0040040f, 0x213 }, + { 0x00000000, 0x00600000, 0x631 }, + { 0x00000000, 0x00600000, 0x645 }, + { 0x00000210, 0x00600411, 0x315 }, + { 0x00000000, 0x00600000, 0x1a0 }, + { 0x00000000, 0x00600000, 0x19c }, + { 0x00000000, 0x00600000, 0x2bb }, + { 0x00000000, 0x00600000, 0x2a3 }, + { 0x93800000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204808, 0x000 }, + { 0x00000000, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ae00000, 0x232 }, + { 0x00000000, 0x00600000, 0x13a }, + { 0x00000000, 0x00400000, 0x236 }, + { 0x95000000, 0x00204411, 0x000 }, + { 0x00000000, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x236 }, + { 0x00000000, 0xc0404800, 0x233 }, + { 0x92000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x00000016, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0x00600411, 0x2fb }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000000, 0x00600000, 0x631 }, + { 0x0000a00c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000018, 0x40210a20, 0x000 }, + { 0x00000003, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x24c }, + { 0x00000014, 0x0020222d, 0x000 }, + { 0x00080101, 0x00292228, 0x000 }, + { 0x00000014, 0x00203628, 0x000 }, + { 0x0000a30c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x251 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000010, 0x00600411, 0x315 }, + { 0x3f800000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x00000000, 0x00600000, 0x27c }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000001, 0x00211e27, 0x000 }, + { 0x00000000, 0x14e00000, 0x26a }, + { 0x00000012, 0x00201e2d, 0x000 }, + { 0x0000ffff, 0x00281e27, 0x000 }, + { 0x00000000, 0x00341c27, 0x000 }, + { 0x00000000, 0x12c00000, 0x25f }, + { 0x00000000, 0x00201c11, 0x000 }, + { 0x00000000, 0x002f00e5, 0x000 }, + { 0x00000000, 0x08c00000, 0x262 }, + { 0x00000000, 0x00201407, 0x000 }, + { 0x00000012, 0x00201e2d, 0x000 }, + { 0x00000010, 0x00211e27, 0x000 }, + { 0x00000000, 0x00341c47, 0x000 }, + { 0x00000000, 0x12c00000, 0x267 }, + { 0x00000000, 0x00201c11, 0x000 }, + { 0x00000000, 0x002f00e6, 0x000 }, + { 0x00000000, 0x08c00000, 0x26a }, + { 0x00000000, 0x00201807, 0x000 }, + { 0x00000000, 0x00600000, 0x2c1 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x00000000, 0x00342023, 0x000 }, + { 0x00000000, 0x12c00000, 0x272 }, + { 0x00000000, 0x00342044, 0x000 }, + { 0x00000000, 0x12c00000, 0x271 }, + { 0x00000016, 0x00404811, 0x276 }, + { 0x00000018, 0x00404811, 0x276 }, + { 0x00000000, 0x00342044, 0x000 }, + { 0x00000000, 0x12c00000, 0x275 }, + { 0x00000017, 0x00404811, 0x276 }, + { 0x00000019, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0001a1fd, 0x00604411, 0x2e9 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x256 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000010, 0x40210620, 0x000 }, + { 0x0000ffff, 0xc0280a20, 0x000 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x0000ffff, 0xc0281220, 0x000 }, + { 0x00000010, 0x40211620, 0x000 }, + { 0x0000ffff, 0xc0881a20, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00042004, 0x00604411, 0x68d }, + { 0x00000000, 0x00600000, 0x631 }, + { 0x00000000, 0xc0600000, 0x2a3 }, + { 0x00000005, 0x00200a2d, 0x000 }, + { 0x00000008, 0x00220a22, 0x000 }, + { 0x0000002b, 0x00201a2d, 0x000 }, + { 0x0000001c, 0x00201e2d, 0x000 }, + { 0x00007000, 0x00281e27, 0x000 }, + { 0x00000000, 0x00311ce6, 0x000 }, + { 0x0000002a, 0x00201a2d, 0x000 }, + { 0x0000000c, 0x00221a26, 0x000 }, + { 0x00000000, 0x002f00e6, 0x000 }, + { 0x00000000, 0x06e00000, 0x292 }, + { 0x00000000, 0x00201c11, 0x000 }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x0000002b, 0x00203623, 0x000 }, + { 0x00000010, 0x00201811, 0x000 }, + { 0x00000000, 0x00691ce2, 0x12f }, + { 0x93800000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x95000000, 0x00204411, 0x000 }, + { 0x00000000, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x29d }, + { 0x00000001, 0x00333e2f, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x92000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000001c, 0x00403627, 0x000 }, + { 0x0000000c, 0xc0220a20, 0x000 }, + { 0x00000029, 0x00203622, 0x000 }, + { 0x00000028, 0xc0403620, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000009, 0x00204811, 0x000 }, + { 0xa1000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00804811, 0x000 }, + { 0x00000021, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002c1ce3, 0x000 }, + { 0x00000021, 0x00203627, 0x000 }, + { 0x00000022, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002c1ce4, 0x000 }, + { 0x00000022, 0x00203627, 0x000 }, + { 0x00000023, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120a3, 0x000 }, + { 0x00000000, 0x002d1d07, 0x000 }, + { 0x00000023, 0x00203627, 0x000 }, + { 0x00000024, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x00000000, 0x002d1d07, 0x000 }, + { 0x00000024, 0x00803627, 0x000 }, + { 0x00000021, 0x00203623, 0x000 }, + { 0x00000022, 0x00203624, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000023, 0x00203627, 0x000 }, + { 0x00000000, 0x00311cc4, 0x000 }, + { 0x00000024, 0x00803627, 0x000 }, + { 0x0000001a, 0x00203627, 0x000 }, + { 0x0000001b, 0x00203628, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000002, 0x00210227, 0x000 }, + { 0x00000000, 0x14c00000, 0x2dc }, + { 0x00000000, 0x00400000, 0x2d9 }, + { 0x0000001a, 0x00203627, 0x000 }, + { 0x0000001b, 0x00203628, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000002, 0x00210227, 0x000 }, + { 0x00000000, 0x14e00000, 0x2d9 }, + { 0x00000003, 0x00210227, 0x000 }, + { 0x00000000, 0x14e00000, 0x2dc }, + { 0x00000023, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002e00e1, 0x000 }, + { 0x00000000, 0x02c00000, 0x2dc }, + { 0x00000021, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120a1, 0x000 }, + { 0x00000000, 0x002e00e8, 0x000 }, + { 0x00000000, 0x06c00000, 0x2dc }, + { 0x00000024, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002e00e2, 0x000 }, + { 0x00000000, 0x02c00000, 0x2dc }, + { 0x00000022, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120c2, 0x000 }, + { 0x00000000, 0x002e00e8, 0x000 }, + { 0x00000000, 0x06c00000, 0x2dc }, + { 0x00000000, 0x00600000, 0x668 }, + { 0x00000000, 0x00600000, 0x2b5 }, + { 0x00000000, 0x00400000, 0x2de }, + { 0x00000000, 0x00600000, 0x2b5 }, + { 0x00000000, 0x00600000, 0x65f }, + { 0x00000000, 0x00400000, 0x2de }, + { 0x00000000, 0x00600000, 0x2a7 }, + { 0x00000000, 0x00400000, 0x2de }, + { 0x0000001a, 0x00201e2d, 0x000 }, + { 0x0000001b, 0x0080222d, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00894907, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000010, 0x00221e21, 0x000 }, + { 0x00000000, 0x00294847, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000000, 0x00311ca1, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294847, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000010, 0x00221e21, 0x000 }, + { 0x00000000, 0x003120c2, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00894907, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000001, 0x00220a21, 0x000 }, + { 0x00000000, 0x003308a2, 0x000 }, + { 0x00000010, 0x00221e22, 0x000 }, + { 0x00000010, 0x00212222, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000001, 0x00220a21, 0x000 }, + { 0x00000000, 0x003008a2, 0x000 }, + { 0x00000010, 0x00221e22, 0x000 }, + { 0x00000010, 0x00212222, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x003808c5, 0x000 }, + { 0x00000000, 0x00300841, 0x000 }, + { 0x00000001, 0x00220a22, 0x000 }, + { 0x00000000, 0x003308a2, 0x000 }, + { 0x00000010, 0x00221e22, 0x000 }, + { 0x00000010, 0x00212222, 0x000 }, + { 0x00000000, 0x00894907, 0x000 }, + { 0x00000017, 0x0020222d, 0x000 }, + { 0x00000000, 0x14c00000, 0x318 }, + { 0xffffffef, 0x00280621, 0x000 }, + { 0x00000014, 0x0020222d, 0x000 }, + { 0x0000f8e0, 0x00204411, 0x000 }, + { 0x00000000, 0x00294901, 0x000 }, + { 0x00000000, 0x00894901, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00804811, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x97000000, 0xc0204411, 0x000 }, + { 0x00000000, 0xc0204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x97000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x97000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x00002257, 0x00204411, 0x000 }, + { 0x00000003, 0xc0484a20, 0x000 }, + { 0x0000225d, 0x00204411, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000000, 0x00600000, 0x645 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00384a22, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x40204800, 0x000 }, + { 0x00000001, 0x40304a20, 0x000 }, + { 0x00000002, 0xc0304a20, 0x000 }, + { 0x00000001, 0x00530a22, 0x34b }, + { 0x0000003f, 0xc0280a20, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000018, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x68d }, + { 0x00000011, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x354 }, + { 0x00000014, 0x002f0222, 0x000 }, + { 0x00000000, 0x0cc00000, 0x364 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00604802, 0x36e }, + { 0x00002100, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000004, 0x002f0222, 0x000 }, + { 0x00000000, 0x0cc00000, 0x36a }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x35f }, + { 0x00000028, 0x002f0222, 0x000 }, + { 0x00000000, 0x0cc00000, 0x5c0 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x35f }, + { 0x0000002c, 0x00203626, 0x000 }, + { 0x00000049, 0x00201811, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x00000001, 0x00331a26, 0x000 }, + { 0x00000000, 0x002f0226, 0x000 }, + { 0x00000000, 0x0cc00000, 0x370 }, + { 0x0000002c, 0x00801a2d, 0x000 }, + { 0x0000003f, 0xc0280a20, 0x000 }, + { 0x00000015, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x386 }, + { 0x00000006, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x3b1 }, + { 0x00000016, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x3b5 }, + { 0x00000020, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x39c }, + { 0x0000000f, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x3a8 }, + { 0x00000010, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x3a8 }, + { 0x0000001e, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x390 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x000 }, + { 0x08000000, 0x00290a22, 0x000 }, + { 0x00000003, 0x40210e20, 0x000 }, + { 0x0000000c, 0xc0211220, 0x000 }, + { 0x00080000, 0x00281224, 0x000 }, + { 0x00000014, 0xc0221620, 0x000 }, + { 0x00000000, 0x002914a4, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x002948a2, 0x000 }, + { 0x0000a1fe, 0x00204411, 0x000 }, + { 0x00000000, 0x00404803, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000016, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x68d }, + { 0x00000015, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x392 }, + { 0x0000210e, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000017, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x68d }, + { 0x00000003, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x39e }, + { 0x00002108, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x80000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000010, 0x00204811, 0x000 }, + { 0x00000000, 0x00200010, 0x000 }, + { 0x00000000, 0x14c00000, 0x3ae }, + { 0x00000000, 0x00400000, 0x000 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000006, 0x00404811, 0x000 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000016, 0x00604811, 0x36e }, + { 0x00000000, 0x00400000, 0x000 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x0000001d, 0x00210223, 0x000 }, + { 0x00000000, 0x14e00000, 0x3ce }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000018, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x68d }, + { 0x00000011, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x3c0 }, + { 0x00002100, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0xbabecafe, 0x00204811, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000004, 0x00404811, 0x000 }, + { 0x00002170, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000a, 0x00204811, 0x000 }, + { 0x00000000, 0x00200010, 0x000 }, + { 0x00000000, 0x14c00000, 0x3d3 }, + { 0x8c000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00003fff, 0x40280a20, 0x000 }, + { 0x80000000, 0x40280e20, 0x000 }, + { 0x40000000, 0xc0281220, 0x000 }, + { 0x00040000, 0x00694622, 0x68d }, + { 0x00000000, 0x00201410, 0x000 }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x3e1 }, + { 0x00000000, 0xc0401800, 0x3e4 }, + { 0x00003fff, 0xc0281a20, 0x000 }, + { 0x00040000, 0x00694626, 0x68d }, + { 0x00000000, 0x00201810, 0x000 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x3e7 }, + { 0x00000000, 0xc0401c00, 0x3ea }, + { 0x00003fff, 0xc0281e20, 0x000 }, + { 0x00040000, 0x00694627, 0x68d }, + { 0x00000000, 0x00201c10, 0x000 }, + { 0x00000000, 0x00204402, 0x000 }, + { 0x00000000, 0x002820c5, 0x000 }, + { 0x00000000, 0x004948e8, 0x000 }, + { 0xa5800000, 0x00200811, 0x000 }, + { 0x00002000, 0x00200c11, 0x000 }, + { 0x83000000, 0x00604411, 0x412 }, + { 0x00000000, 0x00204402, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x40204800, 0x000 }, + { 0x0000001f, 0xc0210220, 0x000 }, + { 0x00000000, 0x14c00000, 0x3f7 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0000ffff, 0xc0481220, 0x3ff }, + { 0xa7800000, 0x00200811, 0x000 }, + { 0x0000a000, 0x00200c11, 0x000 }, + { 0x83000000, 0x00604411, 0x412 }, + { 0x00000000, 0x00204402, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000ffff, 0xc0281220, 0x000 }, + { 0x83000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00304883, 0x000 }, + { 0x84000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x1d000000, 0x000 }, + { 0x83000000, 0x00604411, 0x412 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0xa9800000, 0x00200811, 0x000 }, + { 0x0000c000, 0x00400c11, 0x3fa }, + { 0xab800000, 0x00200811, 0x000 }, + { 0x0000f8e0, 0x00400c11, 0x3fa }, + { 0xad800000, 0x00200811, 0x000 }, + { 0x0000f880, 0x00400c11, 0x3fa }, + { 0xb3800000, 0x00200811, 0x000 }, + { 0x0000f3fc, 0x00400c11, 0x3fa }, + { 0xaf800000, 0x00200811, 0x000 }, + { 0x0000e000, 0x00400c11, 0x3fa }, + { 0xb1800000, 0x00200811, 0x000 }, + { 0x0000f000, 0x00400c11, 0x3fa }, + { 0x83000000, 0x00204411, 0x000 }, + { 0x00002148, 0x00204811, 0x000 }, + { 0x84000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x1d000000, 0x000 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x01182000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0218a000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0318c000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0418f8e0, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0518f880, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0618e000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0718f000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0818f3fc, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x00000030, 0x00200a2d, 0x000 }, + { 0x00000000, 0xc0290c40, 0x000 }, + { 0x00000030, 0x00203623, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x86000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00404801, 0x000 }, + { 0x85000000, 0xc0204411, 0x000 }, + { 0x00000000, 0x00404801, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x00000018, 0x40210220, 0x000 }, + { 0x00000000, 0x14c00000, 0x445 }, + { 0x00800000, 0xc0494a20, 0x446 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x0004217f, 0x00604411, 0x68d }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x00000000, 0x00404c02, 0x44b }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x00000000, 0xc0201000, 0x000 }, + { 0x00000000, 0xc0201400, 0x000 }, + { 0x00000000, 0xc0201800, 0x000 }, + { 0x00000000, 0xc0201c00, 0x000 }, + { 0x00007f00, 0x00280a21, 0x000 }, + { 0x00004500, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x459 }, + { 0x00000000, 0xc0202000, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x00000010, 0x00280a23, 0x000 }, + { 0x00000010, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x461 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00040000, 0x00694624, 0x68d }, + { 0x00000000, 0x00400000, 0x466 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000216d, 0x00204411, 0x000 }, + { 0x00000000, 0x00204804, 0x000 }, + { 0x00000000, 0x00604805, 0x692 }, + { 0x00000000, 0x002824f0, 0x000 }, + { 0x00000007, 0x00280a23, 0x000 }, + { 0x00000001, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x46d }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x04e00000, 0x486 }, + { 0x00000000, 0x00400000, 0x493 }, + { 0x00000002, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x472 }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x02e00000, 0x486 }, + { 0x00000000, 0x00400000, 0x493 }, + { 0x00000003, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x477 }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x0ce00000, 0x486 }, + { 0x00000000, 0x00400000, 0x493 }, + { 0x00000004, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x47c }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x0ae00000, 0x486 }, + { 0x00000000, 0x00400000, 0x493 }, + { 0x00000005, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x481 }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x06e00000, 0x486 }, + { 0x00000000, 0x00400000, 0x493 }, + { 0x00000006, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x486 }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x08e00000, 0x486 }, + { 0x00000000, 0x00400000, 0x493 }, + { 0x00007f00, 0x00280a21, 0x000 }, + { 0x00004500, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x000 }, + { 0x00000008, 0x00210a23, 0x000 }, + { 0x00000000, 0x14c00000, 0x490 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x00000000, 0xc0204400, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00007f00, 0x00280a21, 0x000 }, + { 0x00004500, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x499 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0400000, 0x000 }, + { 0x00000000, 0x00404c08, 0x459 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x00000011, 0x40211220, 0x000 }, + { 0x00000012, 0x40211620, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00210225, 0x000 }, + { 0x00000000, 0x14e00000, 0x4a3 }, + { 0x00040000, 0xc0494a20, 0x4a4 }, + { 0xfffbffff, 0xc0284a20, 0x000 }, + { 0x00000000, 0x00210223, 0x000 }, + { 0x00000000, 0x14e00000, 0x4b0 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x00210224, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000c, 0x00204811, 0x000 }, + { 0x00000000, 0x00200010, 0x000 }, + { 0x00000000, 0x14c00000, 0x4ac }, + { 0xa0000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000004, 0x00204811, 0x000 }, + { 0x0000216b, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204810, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000005, 0x00204811, 0x000 }, + { 0x0000216c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204810, 0x000 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00400000, 0x4aa }, + { 0x00000000, 0xc0210a20, 0x000 }, + { 0x00000000, 0x14c00000, 0x4c3 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000216d, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0604800, 0x692 }, + { 0x00000000, 0x00400000, 0x4c7 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00040000, 0xc0294620, 0x000 }, + { 0x00000000, 0xc0600000, 0x68d }, + { 0x00000001, 0x00210222, 0x000 }, + { 0x00000000, 0x14c00000, 0x4ce }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x00000000, 0xc0204400, 0x000 }, + { 0x00000000, 0xc0404810, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x0000000e, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x68d }, + { 0x00000000, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x4d0 }, + { 0x00002180, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000003, 0x00333e2f, 0x000 }, + { 0x00000001, 0x00210221, 0x000 }, + { 0x00000000, 0x14e00000, 0x500 }, + { 0x0000002c, 0x00200a2d, 0x000 }, + { 0x00040000, 0x18e00c11, 0x4ef }, + { 0x00000001, 0x00333e2f, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xd8c04800, 0x4e3 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000002d, 0x0020122d, 0x000 }, + { 0x00000000, 0x00290c83, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000011, 0x00210224, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x00000000, 0x00400000, 0x4aa }, + { 0x0000002c, 0xc0203620, 0x000 }, + { 0x0000002d, 0xc0403620, 0x000 }, + { 0x0000000f, 0x00210221, 0x000 }, + { 0x00000000, 0x14c00000, 0x505 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0xd9000000, 0x000 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0xb5000000, 0x00204411, 0x000 }, + { 0x00002000, 0x00204811, 0x000 }, + { 0xb6000000, 0x00204411, 0x000 }, + { 0x0000a000, 0x00204811, 0x000 }, + { 0xb7000000, 0x00204411, 0x000 }, + { 0x0000c000, 0x00204811, 0x000 }, + { 0xb8000000, 0x00204411, 0x000 }, + { 0x0000f8e0, 0x00204811, 0x000 }, + { 0xb9000000, 0x00204411, 0x000 }, + { 0x0000f880, 0x00204811, 0x000 }, + { 0xba000000, 0x00204411, 0x000 }, + { 0x0000e000, 0x00204811, 0x000 }, + { 0xbb000000, 0x00204411, 0x000 }, + { 0x0000f000, 0x00204811, 0x000 }, + { 0xbc000000, 0x00204411, 0x000 }, + { 0x0000f3fc, 0x00204811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000002, 0x00204811, 0x000 }, + { 0x000000ff, 0x00280e30, 0x000 }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x519 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000000, 0x14c00000, 0x52e }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x0000001c, 0x00203623, 0x000 }, + { 0x0000002b, 0x00203623, 0x000 }, + { 0x00000029, 0x00203623, 0x000 }, + { 0x00000028, 0x00203623, 0x000 }, + { 0x00000017, 0x00203623, 0x000 }, + { 0x00000025, 0x00203623, 0x000 }, + { 0x00000026, 0x00203623, 0x000 }, + { 0x00000015, 0x00203623, 0x000 }, + { 0x00000016, 0x00203623, 0x000 }, + { 0xffffe000, 0x00200c11, 0x000 }, + { 0x00000021, 0x00203623, 0x000 }, + { 0x00000022, 0x00203623, 0x000 }, + { 0x00001fff, 0x00200c11, 0x000 }, + { 0x00000023, 0x00203623, 0x000 }, + { 0x00000024, 0x00203623, 0x000 }, + { 0xf1ffffff, 0x00283a2e, 0x000 }, + { 0x0000001a, 0xc0220e20, 0x000 }, + { 0x00000000, 0x0029386e, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x0000002a, 0x40203620, 0x000 }, + { 0x87000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1f4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x00000030, 0x00203623, 0x000 }, + { 0x9d000000, 0x00204411, 0x000 }, + { 0x0000001f, 0x40214a20, 0x000 }, + { 0x96000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x00000000, 0xc0201000, 0x000 }, + { 0x0000001f, 0x00211624, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x0000001d, 0x00203623, 0x000 }, + { 0x00000003, 0x00281e23, 0x000 }, + { 0x00000008, 0x00222223, 0x000 }, + { 0xfffff000, 0x00282228, 0x000 }, + { 0x00000000, 0x002920e8, 0x000 }, + { 0x0000001f, 0x00203628, 0x000 }, + { 0x00000018, 0x00211e23, 0x000 }, + { 0x00000020, 0x00203627, 0x000 }, + { 0x00000002, 0x00221624, 0x000 }, + { 0x00000000, 0x003014a8, 0x000 }, + { 0x0000001e, 0x00203625, 0x000 }, + { 0x00000003, 0x00211a24, 0x000 }, + { 0x10000000, 0x00281a26, 0x000 }, + { 0xefffffff, 0x00283a2e, 0x000 }, + { 0x00000000, 0x004938ce, 0x67b }, + { 0x00000001, 0x40280a20, 0x000 }, + { 0x00000006, 0x40280e20, 0x000 }, + { 0x00000300, 0xc0281220, 0x000 }, + { 0x00000008, 0x00211224, 0x000 }, + { 0x00000000, 0xc0201620, 0x000 }, + { 0x00000000, 0xc0201a20, 0x000 }, + { 0x00000000, 0x00210222, 0x000 }, + { 0x00000000, 0x14c00000, 0x566 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00002258, 0x00300a24, 0x000 }, + { 0x00040000, 0x00694622, 0x68d }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204805, 0x000 }, + { 0x00020000, 0x00294a26, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x56e }, + { 0x00000000, 0xc0201c10, 0x000 }, + { 0x00000000, 0xc0400000, 0x57c }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x56e }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00002258, 0x00300a24, 0x000 }, + { 0x00040000, 0x00694622, 0x68d }, + { 0x00000000, 0xc0201c10, 0x000 }, + { 0x00000000, 0xc0400000, 0x57c }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x572 }, + { 0x00000000, 0xc0201c00, 0x000 }, + { 0x00000000, 0xc0400000, 0x57c }, + { 0x00000004, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x57a }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000216d, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0604800, 0x692 }, + { 0x00000000, 0x00401c10, 0x57c }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0400000, 0x000 }, + { 0x00000000, 0x0ee00000, 0x57e }, + { 0x00000000, 0x00600000, 0x5c9 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x58f }, + { 0x0000a2b7, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a2b6, 0x00604411, 0x68d }, + { 0x0000001a, 0x00212230, 0x000 }, + { 0x00000006, 0x00222630, 0x000 }, + { 0x00042004, 0x00604411, 0x68d }, + { 0x0000a2c4, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x58d }, + { 0x0000a2d1, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d1, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x00000001, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x5a0 }, + { 0x0000a2bb, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a2ba, 0x00604411, 0x68d }, + { 0x0000001a, 0x00212230, 0x000 }, + { 0x00000006, 0x00222630, 0x000 }, + { 0x00042004, 0x00604411, 0x68d }, + { 0x0000a2c5, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x59e }, + { 0x0000a2d2, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d2, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x00000002, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x5b1 }, + { 0x0000a2bf, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a2be, 0x00604411, 0x68d }, + { 0x0000001a, 0x00212230, 0x000 }, + { 0x00000006, 0x00222630, 0x000 }, + { 0x00042004, 0x00604411, 0x68d }, + { 0x0000a2c6, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x5af }, + { 0x0000a2d3, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d3, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x0000a2c3, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a2c2, 0x00604411, 0x68d }, + { 0x0000001a, 0x00212230, 0x000 }, + { 0x00000006, 0x00222630, 0x000 }, + { 0x00042004, 0x00604411, 0x68d }, + { 0x0000a2c7, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x5be }, + { 0x0000a2d4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d4, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x85000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204801, 0x000 }, + { 0x0000304a, 0x00204411, 0x000 }, + { 0x01000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00400000, 0x5c4 }, + { 0xa4000000, 0xc0204411, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000000, 0xc0600000, 0x5c9 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x0000002c, 0x00203621, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x00000000, 0x002f0230, 0x000 }, + { 0x00000000, 0x0cc00000, 0x5d0 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000030, 0x00403621, 0x5e3 }, + { 0x00000030, 0x0020062d, 0x000 }, + { 0x00007e00, 0x00280621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x5e3 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a092, 0x00604411, 0x68d }, + { 0x00000031, 0x00203630, 0x000 }, + { 0x0004a093, 0x00604411, 0x68d }, + { 0x00000032, 0x00203630, 0x000 }, + { 0x0004a2b6, 0x00604411, 0x68d }, + { 0x00000033, 0x00203630, 0x000 }, + { 0x0004a2ba, 0x00604411, 0x68d }, + { 0x00000034, 0x00203630, 0x000 }, + { 0x0004a2be, 0x00604411, 0x68d }, + { 0x00000035, 0x00203630, 0x000 }, + { 0x0004a2c2, 0x00604411, 0x68d }, + { 0x00000036, 0x00203630, 0x000 }, + { 0x00042004, 0x00604411, 0x68d }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x00000005, 0x00204811, 0x000 }, + { 0x0000a1f4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x88000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x00000001, 0x002f0230, 0x000 }, + { 0x00000000, 0x0ce00000, 0x62c }, + { 0x00000030, 0x0020062d, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x62c }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00007e00, 0x00280621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x605 }, + { 0x0000a092, 0x00204411, 0x000 }, + { 0x00000031, 0x00204a2d, 0x000 }, + { 0x0000a093, 0x00204411, 0x000 }, + { 0x00000032, 0x00204a2d, 0x000 }, + { 0x0000a2b6, 0x00204411, 0x000 }, + { 0x00000033, 0x00204a2d, 0x000 }, + { 0x0000a2ba, 0x00204411, 0x000 }, + { 0x00000034, 0x00204a2d, 0x000 }, + { 0x0000a2be, 0x00204411, 0x000 }, + { 0x00000035, 0x00204a2d, 0x000 }, + { 0x0000a2c2, 0x00204411, 0x000 }, + { 0x00000036, 0x00204a2d, 0x000 }, + { 0x00000030, 0x0020062d, 0x000 }, + { 0x000001ff, 0x00280621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x62b }, + { 0x00000000, 0x00210221, 0x000 }, + { 0x00000000, 0x14c00000, 0x60e }, + { 0x0004a003, 0x00604411, 0x68d }, + { 0x0000a003, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x00000001, 0x00210621, 0x000 }, + { 0x00000000, 0x14c00000, 0x613 }, + { 0x0004a010, 0x00604411, 0x68d }, + { 0x0000a010, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x00000001, 0x00210621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x62b }, + { 0x0004a011, 0x00604411, 0x68d }, + { 0x0000a011, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a012, 0x00604411, 0x68d }, + { 0x0000a012, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a013, 0x00604411, 0x68d }, + { 0x0000a013, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a014, 0x00604411, 0x68d }, + { 0x0000a014, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a015, 0x00604411, 0x68d }, + { 0x0000a015, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a016, 0x00604411, 0x68d }, + { 0x0000a016, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a017, 0x00604411, 0x68d }, + { 0x0000a017, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x00042004, 0x00604411, 0x68d }, + { 0x0000002c, 0x0080062d, 0x000 }, + { 0xff000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000002, 0x00804811, 0x000 }, + { 0x00000000, 0x0ee00000, 0x63d }, + { 0x00000030, 0x0020062d, 0x000 }, + { 0x00000002, 0x00280621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x63b }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00042004, 0x00604411, 0x68d }, + { 0x00001000, 0x00200811, 0x000 }, + { 0x0000002b, 0x00203622, 0x000 }, + { 0x00000000, 0x00600000, 0x641 }, + { 0x00000000, 0x00600000, 0x5c9 }, + { 0x98000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00804811, 0x000 }, + { 0x00000000, 0xc0600000, 0x641 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000022, 0x00204811, 0x000 }, + { 0x89000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00404811, 0x62d }, + { 0x97000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00404811, 0x62d }, + { 0x00000000, 0x00600000, 0x65c }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0xc0204411, 0x000 }, + { 0x00000016, 0x00604811, 0x36e }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00010000, 0x00204811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x09800000, 0x00204811, 0x000 }, + { 0xffffffff, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x0004217f, 0x00604411, 0x68d }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x00000004, 0x00404c11, 0x656 }, + { 0x00000000, 0x00400000, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000004, 0x00291e27, 0x000 }, + { 0x00000017, 0x00803627, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0xfffffffb, 0x00281e27, 0x000 }, + { 0x00000017, 0x00803627, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000008, 0x00291e27, 0x000 }, + { 0x00000017, 0x00803627, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0xfffffff7, 0x00281e27, 0x000 }, + { 0x00000017, 0x00803627, 0x000 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000016, 0x00604811, 0x36e }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00010000, 0x00204811, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x01800000, 0x00204811, 0x000 }, + { 0xffffffff, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004217f, 0x00604411, 0x68d }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x68c }, + { 0x00000010, 0x00404c11, 0x672 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x38c00000, 0x000 }, + { 0x0000001d, 0x00200a2d, 0x000 }, + { 0x0000001e, 0x00200e2d, 0x000 }, + { 0x0000001f, 0x0020122d, 0x000 }, + { 0x00000020, 0x0020162d, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204804, 0x000 }, + { 0x00000000, 0x00204805, 0x000 }, + { 0x00000000, 0x00204801, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000004, 0x00301224, 0x000 }, + { 0x00000000, 0x002f0064, 0x000 }, + { 0x00000000, 0x0cc00000, 0x68b }, + { 0x00000003, 0x00281a22, 0x000 }, + { 0x00000008, 0x00221222, 0x000 }, + { 0xfffff000, 0x00281224, 0x000 }, + { 0x00000000, 0x002910c4, 0x000 }, + { 0x0000001f, 0x00403624, 0x000 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x1ac00000, 0x68d }, + { 0x9f000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000000, 0x1ae00000, 0x690 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x1ac00000, 0x692 }, + { 0x9e000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000000, 0x1ae00000, 0x695 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00001000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001b, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0001a1fd, 0xc0204411, 0x000 }, + { 0x00000021, 0x00201e2d, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000024, 0x0020222d, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000022, 0x0020222d, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000023, 0x00201e2d, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00404811, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x01420502, 0x05c00250, 0x000 }, + { 0x01c30168, 0x043f05c0, 0x000 }, + { 0x02250209, 0x02500151, 0x000 }, + { 0x02230245, 0x02a00241, 0x000 }, + { 0x03d705c0, 0x05c005c0, 0x000 }, + { 0x0649064a, 0x031f05c0, 0x000 }, + { 0x05c005c5, 0x03200340, 0x000 }, + { 0x032a0282, 0x03420334, 0x000 }, + { 0x05c005c0, 0x05c005c0, 0x000 }, + { 0x05c00551, 0x05c005c0, 0x000 }, + { 0x03ba05c0, 0x04bb0344, 0x000 }, + { 0x049a0450, 0x043d05c0, 0x000 }, + { 0x04d005c0, 0x044104dd, 0x000 }, + { 0x04500507, 0x03510375, 0x000 }, + { 0x05c005c0, 0x05c005c0, 0x000 }, + { 0x05c005c0, 0x05c005c0, 0x000 }, + { 0x05c005c0, 0x063f05c7, 0x000 }, + { 0x05c005c0, 0x000705c0, 0x000 }, + { 0x05c005c0, 0x05c005c0, 0x000 }, + { 0x05c005c0, 0x05c005c0, 0x000 }, + { 0x03f803ed, 0x04080406, 0x000 }, + { 0x040e040a, 0x040c0410, 0x000 }, + { 0x041c0418, 0x04240420, 0x000 }, + { 0x042c0428, 0x04340430, 0x000 }, + { 0x05c005c0, 0x043805c0, 0x000 }, + { 0x05c005c0, 0x05c005c0, 0x000 }, + { 0x05c005c0, 0x05c005c0, 0x000 }, + { 0x00020679, 0x06970006, 0x000 }, +}; + +static const u32 RV610_pfp_microcode[] = { +0xca0400, +0xa00000, +0x7e828b, +0x7c038b, +0x8001b8, +0x7c038b, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xc41838, +0xca2400, +0xca2800, +0x9581a8, +0xc41c3a, +0xc3c000, +0xca0800, +0xca0c00, +0x7c744b, +0xc20005, +0x99c000, +0xc41c3a, +0x7c744c, +0xc0fff0, +0x042c04, +0x309002, +0x7d2500, +0x351402, +0x7d350b, +0x255403, +0x7cd580, +0x259c03, +0x95c004, +0xd5001b, +0x7eddc1, +0x7d9d80, +0xd6801b, +0xd5801b, +0xd4401e, +0xd5401e, +0xd6401e, +0xd6801e, +0xd4801e, +0xd4c01e, +0x9783d3, +0xd5c01e, +0xca0800, +0x80001a, +0xca0c00, +0xe4011e, +0xd4001e, +0x80000c, +0xc41838, +0xe4013e, +0xd4001e, +0x80000c, +0xc41838, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xe4011e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xe4013e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xca1800, +0xd4401e, +0xd5801e, +0x800053, +0xd40075, +0xd4401e, +0xca0800, +0xca0c00, +0xca1000, +0xd48019, +0xd4c018, +0xd50017, +0xd4801e, +0xd4c01e, +0xd5001e, +0xe2001e, +0xca0400, +0xa00000, +0x7e828b, +0xca0800, +0xd48060, +0xd4401e, +0x800000, +0xd4801e, +0xca0800, +0xd48061, +0xd4401e, +0x800000, +0xd4801e, +0xca0800, +0xca0c00, +0xd4401e, +0xd48016, +0xd4c016, +0xd4801e, +0x8001b8, +0xd4c01e, +0xc60843, +0xca0c00, +0xca1000, +0x948004, +0xca1400, +0xe420f3, +0xd42013, +0xd56065, +0xd4e01c, +0xd5201c, +0xd5601c, +0x800000, +0x062001, +0xc60843, +0xca0c00, +0xca1000, +0x9483f7, +0xca1400, +0xe420f3, +0x800079, +0xd42013, +0xc60843, +0xca0c00, +0xca1000, +0x9883ef, +0xca1400, +0xd40064, +0x80008d, +0x000000, +0xc41432, +0xc61843, +0xc4082f, +0x954005, +0xc40c30, +0xd4401e, +0x800000, +0xee001e, +0x9583f5, +0xc41031, +0xd44033, +0xd52065, +0xd4a01c, +0xd4e01c, +0xd5201c, +0xe4015e, +0xd4001e, +0x800000, +0x062001, +0xca1800, +0x0a2001, +0xd60076, +0xc40836, +0x988007, +0xc61045, +0x950110, +0xd4001f, +0xd46062, +0x800000, +0xd42062, +0xcc3835, +0xcc1433, +0x8401bb, +0xd40072, +0xd5401e, +0x800000, +0xee001e, +0xe2001a, +0x8401bb, +0xe2001a, +0xcc104b, +0xcc0447, +0x2c9401, +0x7d098b, +0x984005, +0x7d15cb, +0xd4001a, +0x8001b8, +0xd4006d, +0x344401, +0xcc0c48, +0x98403a, +0xcc2c4a, +0x958004, +0xcc0449, +0x8001b8, +0xd4001a, +0xd4c01a, +0x282801, +0x8400f0, +0xcc1003, +0x98801b, +0x04380c, +0x8400f0, +0xcc1003, +0x988017, +0x043808, +0x8400f0, +0xcc1003, +0x988013, +0x043804, +0x8400f0, +0xcc1003, +0x988014, +0xcc104c, +0x9a8009, +0xcc144d, +0x9840dc, +0xd4006d, +0xcc1848, +0xd5001a, +0xd5401a, +0x8000c9, +0xd5801a, +0x96c0d5, +0xd4006d, +0x8001b8, +0xd4006e, +0x9ac003, +0xd4006d, +0xd4006e, +0x800000, +0xec007f, +0x9ac0cc, +0xd4006d, +0x8001b8, +0xd4006e, +0xcc1403, +0xcc1803, +0xcc1c03, +0x7d9103, +0x7dd583, +0x7d190c, +0x35cc1f, +0x35701f, +0x7cf0cb, +0x7cd08b, +0x880000, +0x7e8e8b, +0x95c004, +0xd4006e, +0x8001b8, +0xd4001a, +0xd4c01a, +0xcc0803, +0xcc0c03, +0xcc1003, +0xcc1403, +0xcc1803, +0xcc1c03, +0xcc2403, +0xcc2803, +0x35c41f, +0x36b01f, +0x7c704b, +0x34f01f, +0x7c704b, +0x35701f, +0x7c704b, +0x7d8881, +0x7dccc1, +0x7e5101, +0x7e9541, +0x7c9082, +0x7cd4c2, +0x7c848b, +0x9ac003, +0x7c8c8b, +0x2c8801, +0x98809e, +0xd4006d, +0x98409c, +0xd4006e, +0xcc084c, +0xcc0c4d, +0xcc1048, +0xd4801a, +0xd4c01a, +0x800101, +0xd5001a, +0xcc0832, +0xd40032, +0x9482d9, +0xca0c00, +0xd4401e, +0x800000, +0xd4001e, +0xe4011e, +0xd4001e, +0xca0800, +0xca0c00, +0xca1000, +0xd4401e, +0xca1400, +0xd4801e, +0xd4c01e, +0xd5001e, +0xd5401e, +0xd54034, +0x800000, +0xee001e, +0x280404, +0xe2001a, +0xe2001a, +0xd4401a, +0xca3800, +0xcc0803, +0xcc0c03, +0xcc0c03, +0xcc0c03, +0x9882bd, +0x000000, +0x8401bb, +0xd7a06f, +0x800000, +0xee001f, +0xca0400, +0xc2ff00, +0xcc0834, +0xc13fff, +0x7c74cb, +0x7cc90b, +0x7d010f, +0x9902b0, +0x7c738b, +0x8401bb, +0xd7a06f, +0x800000, +0xee001f, +0xca0800, +0x281900, +0x7d898b, +0x958014, +0x281404, +0xca0c00, +0xca1000, +0xca1c00, +0xca2400, +0xe2001f, +0xd4c01a, +0xd5001a, +0xd5401a, +0xcc1803, +0xcc2c03, +0xcc2c03, +0xcc2c03, +0x7da58b, +0x7d9c47, +0x984297, +0x000000, +0x800161, +0xd4c01a, +0xd4401e, +0xd4801e, +0x800000, +0xee001e, +0xe4011e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xe4013e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xca0800, +0x248c06, +0x0ccc06, +0x98c006, +0xcc104e, +0x990004, +0xd40073, +0xe4011e, +0xd4001e, +0xd4401e, +0xd4801e, +0x800000, +0xee001e, +0xca0800, +0xca0c00, +0x34d018, +0x251001, +0x950021, +0xc17fff, +0xca1000, +0xca1400, +0xca1800, +0xd4801d, +0xd4c01d, +0x7db18b, +0xc14202, +0xc2c001, +0xd5801d, +0x34dc0e, +0x7d5d4c, +0x7f734c, +0xd7401e, +0xd5001e, +0xd5401e, +0xc14200, +0xc2c000, +0x099c01, +0x31dc10, +0x7f5f4c, +0x7f734c, +0x042802, +0x7d8380, +0xd5a86f, +0xd58066, +0xd7401e, +0xec005e, +0xc82402, +0xc82402, +0x8001b8, +0xd60076, +0xd4401e, +0xd4801e, +0xd4c01e, +0x800000, +0xee001e, +0x800000, +0xee001f, +0xd4001f, +0x800000, +0xd4001f, +0xd4001f, +0x880000, +0xd4001f, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x010171, +0x020178, +0x03008f, +0x04007f, +0x050003, +0x06003f, +0x070032, +0x08012c, +0x090046, +0x0a0036, +0x1001b6, +0x1700a2, +0x22013a, +0x230149, +0x2000b4, +0x240125, +0x27004d, +0x28006a, +0x2a0060, +0x2b0052, +0x2f0065, +0x320087, +0x34017f, +0x3c0156, +0x3f0072, +0x41018c, +0x44012e, +0x550173, +0x56017a, +0x60000b, +0x610034, +0x620038, +0x630038, +0x640038, +0x650038, +0x660038, +0x670038, +0x68003a, +0x690041, +0x6a0048, +0x6b0048, +0x6c0048, +0x6d0048, +0x6e0048, +0x6f0048, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +}; + +static const u32 RV620_cp_microcode[][3] = { + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0000ffff, 0x00284621, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x00000000, 0x00e00000, 0x000 }, + { 0x00010000, 0xc0294620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00042004, 0x00604411, 0x68d }, + { 0x00000000, 0x00600000, 0x631 }, + { 0x00000000, 0x00600000, 0x645 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000f00, 0x00281622, 0x000 }, + { 0x00000008, 0x00211625, 0x000 }, + { 0x00000018, 0x00203625, 0x000 }, + { 0x8d000000, 0x00204411, 0x000 }, + { 0x00000004, 0x002f0225, 0x000 }, + { 0x00000000, 0x0ce00000, 0x018 }, + { 0x00412000, 0x00404811, 0x019 }, + { 0x00422000, 0x00204811, 0x000 }, + { 0x8e000000, 0x00204411, 0x000 }, + { 0x00000028, 0x00204a2d, 0x000 }, + { 0x90000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204805, 0x000 }, + { 0x0000000c, 0x00211622, 0x000 }, + { 0x00000003, 0x00281625, 0x000 }, + { 0x00000019, 0x00211a22, 0x000 }, + { 0x00000004, 0x00281a26, 0x000 }, + { 0x00000000, 0x002914c5, 0x000 }, + { 0x00000019, 0x00203625, 0x000 }, + { 0x00000000, 0x003a1402, 0x000 }, + { 0x00000016, 0x00211625, 0x000 }, + { 0x00000003, 0x00281625, 0x000 }, + { 0x00000017, 0x00200e2d, 0x000 }, + { 0xfffffffc, 0x00280e23, 0x000 }, + { 0x00000000, 0x002914a3, 0x000 }, + { 0x00000017, 0x00203625, 0x000 }, + { 0x00008000, 0x00280e22, 0x000 }, + { 0x00000007, 0x00220e23, 0x000 }, + { 0x00000000, 0x0029386e, 0x000 }, + { 0x20000000, 0x00280e22, 0x000 }, + { 0x00000006, 0x00210e23, 0x000 }, + { 0x00000000, 0x0029386e, 0x000 }, + { 0x00000000, 0x00220222, 0x000 }, + { 0x00000000, 0x14e00000, 0x038 }, + { 0x00000000, 0x2ee00000, 0x035 }, + { 0x00000000, 0x2ce00000, 0x037 }, + { 0x00000000, 0x00400e2d, 0x039 }, + { 0x00000008, 0x00200e2d, 0x000 }, + { 0x00000009, 0x0040122d, 0x046 }, + { 0x00000001, 0x00400e2d, 0x039 }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x003ffffc, 0x00281223, 0x000 }, + { 0x00000002, 0x00221224, 0x000 }, + { 0x0000001f, 0x00211e23, 0x000 }, + { 0x00000000, 0x14e00000, 0x03e }, + { 0x00000008, 0x00401c11, 0x041 }, + { 0x0000000d, 0x00201e2d, 0x000 }, + { 0x0000000f, 0x00281e27, 0x000 }, + { 0x00000003, 0x00221e27, 0x000 }, + { 0x7fc00000, 0x00281a23, 0x000 }, + { 0x00000014, 0x00211a26, 0x000 }, + { 0x00000001, 0x00331a26, 0x000 }, + { 0x00000008, 0x00221a26, 0x000 }, + { 0x00000000, 0x00290cc7, 0x000 }, + { 0x00000027, 0x00203624, 0x000 }, + { 0x00007f00, 0x00281221, 0x000 }, + { 0x00001400, 0x002f0224, 0x000 }, + { 0x00000000, 0x0ce00000, 0x04b }, + { 0x00000001, 0x00290e23, 0x000 }, + { 0x0000000e, 0x00203623, 0x000 }, + { 0x0000e000, 0x00204411, 0x000 }, + { 0xfff80000, 0x00294a23, 0x000 }, + { 0x00000000, 0x003a2c02, 0x000 }, + { 0x00000002, 0x00220e2b, 0x000 }, + { 0xfc000000, 0x00280e23, 0x000 }, + { 0x0000000f, 0x00203623, 0x000 }, + { 0x00001fff, 0x00294a23, 0x000 }, + { 0x00000027, 0x00204a2d, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000029, 0x00200e2d, 0x000 }, + { 0x060a0200, 0x00294a23, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000001, 0x00210222, 0x000 }, + { 0x00000000, 0x14e00000, 0x061 }, + { 0x00000000, 0x2ee00000, 0x05f }, + { 0x00000000, 0x2ce00000, 0x05e }, + { 0x00000000, 0x00400e2d, 0x062 }, + { 0x00000001, 0x00400e2d, 0x062 }, + { 0x0000000a, 0x00200e2d, 0x000 }, + { 0x0000000b, 0x0040122d, 0x06a }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x003ffffc, 0x00281223, 0x000 }, + { 0x00000002, 0x00221224, 0x000 }, + { 0x7fc00000, 0x00281623, 0x000 }, + { 0x00000014, 0x00211625, 0x000 }, + { 0x00000001, 0x00331625, 0x000 }, + { 0x80000000, 0x00280e23, 0x000 }, + { 0x00000000, 0x00290ca3, 0x000 }, + { 0x3ffffc00, 0x00290e23, 0x000 }, + { 0x0000001f, 0x00211e23, 0x000 }, + { 0x00000000, 0x14e00000, 0x06d }, + { 0x00000100, 0x00401c11, 0x070 }, + { 0x0000000d, 0x00201e2d, 0x000 }, + { 0x000000f0, 0x00281e27, 0x000 }, + { 0x00000004, 0x00221e27, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000d, 0x00204811, 0x000 }, + { 0xfffff0ff, 0x00281a30, 0x000 }, + { 0x0000a028, 0x00204411, 0x000 }, + { 0x00000000, 0x002948e6, 0x000 }, + { 0x0000a018, 0x00204411, 0x000 }, + { 0x3fffffff, 0x00284a23, 0x000 }, + { 0x0000a010, 0x00204411, 0x000 }, + { 0x00000000, 0x00204804, 0x000 }, + { 0x00000030, 0x0020162d, 0x000 }, + { 0x00000002, 0x00291625, 0x000 }, + { 0x00000030, 0x00203625, 0x000 }, + { 0x00000025, 0x0020162d, 0x000 }, + { 0x00000000, 0x002f00a3, 0x000 }, + { 0x00000000, 0x0cc00000, 0x083 }, + { 0x00000026, 0x0020162d, 0x000 }, + { 0x00000000, 0x002f00a4, 0x000 }, + { 0x00000000, 0x0cc00000, 0x084 }, + { 0x00000000, 0x00400000, 0x08a }, + { 0x00000025, 0x00203623, 0x000 }, + { 0x00000026, 0x00203624, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000002, 0x00210227, 0x000 }, + { 0x00000000, 0x14e00000, 0x08a }, + { 0x00000000, 0x00600000, 0x668 }, + { 0x00000000, 0x00600000, 0x65c }, + { 0x00000002, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x08d }, + { 0x00000012, 0xc0403620, 0x093 }, + { 0x00000000, 0x2ee00000, 0x091 }, + { 0x00000000, 0x2ce00000, 0x090 }, + { 0x00000002, 0x00400e2d, 0x092 }, + { 0x00000003, 0x00400e2d, 0x092 }, + { 0x0000000c, 0x00200e2d, 0x000 }, + { 0x00000012, 0x00203623, 0x000 }, + { 0x00000003, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x098 }, + { 0x0000a00c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x0a0 }, + { 0x0000a00c, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x2ee00000, 0x09e }, + { 0x00000000, 0x2ce00000, 0x09d }, + { 0x00000002, 0x00400e2d, 0x09f }, + { 0x00000003, 0x00400e2d, 0x09f }, + { 0x0000000c, 0x00200e2d, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000000, 0x003a0c02, 0x000 }, + { 0x003f0000, 0x00280e23, 0x000 }, + { 0x00000010, 0x00210e23, 0x000 }, + { 0x00000011, 0x00203623, 0x000 }, + { 0x0000001e, 0x0021022b, 0x000 }, + { 0x00000000, 0x14c00000, 0x0a7 }, + { 0x00000016, 0xc0203620, 0x000 }, + { 0x0000001f, 0x0021022b, 0x000 }, + { 0x00000000, 0x14c00000, 0x0aa }, + { 0x00000015, 0xc0203620, 0x000 }, + { 0x00000008, 0x00210e2b, 0x000 }, + { 0x0000007f, 0x00280e23, 0x000 }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0e1 }, + { 0x00000000, 0x27000000, 0x000 }, + { 0x00000000, 0x00600000, 0x2a3 }, + { 0x00000001, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ae00000, 0x0b3 }, + { 0x00000000, 0x00600000, 0x13a }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x0000000c, 0x00221e30, 0x000 }, + { 0x99800000, 0x00204411, 0x000 }, + { 0x00000004, 0x0020122d, 0x000 }, + { 0x00000008, 0x00221224, 0x000 }, + { 0x00000010, 0x00201811, 0x000 }, + { 0x00000000, 0x00291ce4, 0x000 }, + { 0x00000000, 0x00604807, 0x12f }, + { 0x9b000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x9c000000, 0x00204411, 0x000 }, + { 0x00000000, 0x0033146f, 0x000 }, + { 0x00000001, 0x00333e23, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0x00203c05, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000e, 0x00204811, 0x000 }, + { 0x00000000, 0x00201010, 0x000 }, + { 0x0000e007, 0x00204411, 0x000 }, + { 0x0000000f, 0x0021022b, 0x000 }, + { 0x00000000, 0x14c00000, 0x0cb }, + { 0x00f8ff08, 0x00204811, 0x000 }, + { 0x98000000, 0x00404811, 0x0dc }, + { 0x000000f0, 0x00280e22, 0x000 }, + { 0x000000a0, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x0da }, + { 0x00000011, 0x00200e2d, 0x000 }, + { 0x00000001, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0d5 }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0d4 }, + { 0x00003f00, 0x00400c11, 0x0d6 }, + { 0x00001f00, 0x00400c11, 0x0d6 }, + { 0x00000f00, 0x00200c11, 0x000 }, + { 0x00380009, 0x00294a23, 0x000 }, + { 0x3f000000, 0x00280e2b, 0x000 }, + { 0x00000002, 0x00220e23, 0x000 }, + { 0x00000007, 0x00494a23, 0x0dc }, + { 0x00380f09, 0x00204811, 0x000 }, + { 0x68000007, 0x00204811, 0x000 }, + { 0x00000008, 0x00214a27, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00294a24, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000a202, 0x00204411, 0x000 }, + { 0x00ff0000, 0x00280e22, 0x000 }, + { 0x00000080, 0x00294a23, 0x000 }, + { 0x00000027, 0x00200e2d, 0x000 }, + { 0x00000026, 0x0020122d, 0x000 }, + { 0x00000000, 0x002f0083, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0ea }, + { 0x00000000, 0x00600000, 0x662 }, + { 0x00000000, 0x00400000, 0x0eb }, + { 0x00000000, 0x00600000, 0x665 }, + { 0x00000007, 0x0020222d, 0x000 }, + { 0x00000005, 0x00220e22, 0x000 }, + { 0x00100000, 0x00280e23, 0x000 }, + { 0x00000000, 0x00292068, 0x000 }, + { 0x00000000, 0x003a0c02, 0x000 }, + { 0x000000ef, 0x00280e23, 0x000 }, + { 0x00000000, 0x00292068, 0x000 }, + { 0x00000017, 0x00200e2d, 0x000 }, + { 0x00000003, 0x00210223, 0x000 }, + { 0x00000000, 0x14e00000, 0x0f8 }, + { 0x0000000b, 0x00210228, 0x000 }, + { 0x00000000, 0x14c00000, 0x0f8 }, + { 0x00000400, 0x00292228, 0x000 }, + { 0x00000014, 0x00203628, 0x000 }, + { 0x0000001c, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x0fd }, + { 0x0000a30c, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000001e, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x10b }, + { 0x0000a30f, 0x00204411, 0x000 }, + { 0x00000011, 0x00200e2d, 0x000 }, + { 0x00000001, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x104 }, + { 0xffffffff, 0x00404811, 0x10b }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x107 }, + { 0x0000ffff, 0x00404811, 0x10b }, + { 0x00000004, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x10a }, + { 0x000000ff, 0x00404811, 0x10b }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0002c400, 0x00204411, 0x000 }, + { 0x0000001f, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x112 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x00000013, 0x00203623, 0x000 }, + { 0x00000018, 0x40224a20, 0x000 }, + { 0x00000010, 0xc0424a20, 0x114 }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x00000013, 0x00203623, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000000a, 0x00201011, 0x000 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0ce00000, 0x11b }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000001, 0x00531224, 0x117 }, + { 0xffbfffff, 0x00283a2e, 0x000 }, + { 0x0000001b, 0x00210222, 0x000 }, + { 0x00000000, 0x14c00000, 0x12e }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000d, 0x00204811, 0x000 }, + { 0x00000018, 0x00220e30, 0x000 }, + { 0xfc000000, 0x00280e23, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000e, 0x00204811, 0x000 }, + { 0x00000000, 0x00201010, 0x000 }, + { 0x0000e00e, 0x00204411, 0x000 }, + { 0x07f8ff08, 0x00204811, 0x000 }, + { 0x00000000, 0x00294a23, 0x000 }, + { 0x0000001c, 0x00201e2d, 0x000 }, + { 0x00000008, 0x00214a27, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00294a24, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x00800000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204806, 0x000 }, + { 0x00000008, 0x00214a27, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x0004217f, 0x00604411, 0x68d }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x68c }, + { 0x00000004, 0x00404c11, 0x135 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x0000001c, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x68d }, + { 0x00000011, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x13c }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x00000000, 0x00600000, 0x160 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x00000010, 0xc0211220, 0x000 }, + { 0x0000ffff, 0x40280620, 0x000 }, + { 0x00000010, 0xc0210a20, 0x000 }, + { 0x00000000, 0x00341461, 0x000 }, + { 0x00000000, 0x00741882, 0x2bb }, + { 0x0001a1fd, 0x00604411, 0x2e0 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x147 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00600000, 0x160 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x0000ffff, 0xc0281220, 0x000 }, + { 0x00000010, 0x40211620, 0x000 }, + { 0x0000ffff, 0xc0681a20, 0x2bb }, + { 0x0001a1fd, 0x00604411, 0x2e0 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x158 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000001, 0x00300a2f, 0x000 }, + { 0x00000001, 0x00210a22, 0x000 }, + { 0x00000003, 0x00384a22, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001a, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00804811, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600000, 0x18f }, + { 0x00000000, 0x00600000, 0x1a0 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00202c08, 0x000 }, + { 0x00000000, 0x00202411, 0x000 }, + { 0x00000000, 0x00202811, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x00000016, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x93800000, 0x00204411, 0x000 }, + { 0x00000002, 0x00221e29, 0x000 }, + { 0x00000000, 0x007048eb, 0x19c }, + { 0x00000000, 0x00600000, 0x2bb }, + { 0x00000001, 0x40330620, 0x000 }, + { 0x00000000, 0xc0302409, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00600000, 0x2a3 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ae00000, 0x181 }, + { 0x00000000, 0x00600000, 0x13a }, + { 0x00000000, 0x00400000, 0x186 }, + { 0x95000000, 0x00204411, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x186 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000001, 0x00530621, 0x182 }, + { 0x92000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0604800, 0x197 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000011, 0x0020062d, 0x000 }, + { 0x00000000, 0x0078042a, 0x2fb }, + { 0x00000000, 0x00202809, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x174 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000210, 0x00600411, 0x315 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x194 }, + { 0x00000015, 0xc0203620, 0x000 }, + { 0x00000016, 0xc0203620, 0x000 }, + { 0x3f800000, 0x00200411, 0x000 }, + { 0x46000000, 0x00600811, 0x1b2 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x19b }, + { 0x00000001, 0x00804811, 0x000 }, + { 0x00000021, 0x00804811, 0x000 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x00000010, 0xc0211220, 0x000 }, + { 0x0000ffff, 0x40281620, 0x000 }, + { 0x00000010, 0xc0811a20, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x00000008, 0x00221e30, 0x000 }, + { 0x00000029, 0x00201a2d, 0x000 }, + { 0x0000e000, 0x00204411, 0x000 }, + { 0xfffbff09, 0x00204811, 0x000 }, + { 0x0000000f, 0x0020222d, 0x000 }, + { 0x00001fff, 0x00294a28, 0x000 }, + { 0x00000006, 0x0020222d, 0x000 }, + { 0x00000000, 0x002920e8, 0x000 }, + { 0x00000000, 0x00204808, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00294a26, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000100, 0x00201811, 0x000 }, + { 0x00000008, 0x00621e28, 0x12f }, + { 0x00000008, 0x00822228, 0x000 }, + { 0x0002c000, 0x00204411, 0x000 }, + { 0x00000015, 0x00600e2d, 0x1bd }, + { 0x00000016, 0x00600e2d, 0x1bd }, + { 0x0000c008, 0x00204411, 0x000 }, + { 0x00000017, 0x00200e2d, 0x000 }, + { 0x00000000, 0x14c00000, 0x1b9 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00204801, 0x000 }, + { 0x39000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00804802, 0x000 }, + { 0x00000018, 0x00202e2d, 0x000 }, + { 0x00000000, 0x003b0d63, 0x000 }, + { 0x00000008, 0x00224a23, 0x000 }, + { 0x00000010, 0x00224a23, 0x000 }, + { 0x00000018, 0x00224a23, 0x000 }, + { 0x00000000, 0x00804803, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00001000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x00000007, 0x0021062f, 0x000 }, + { 0x00000013, 0x00200a2d, 0x000 }, + { 0x00000001, 0x00202c11, 0x000 }, + { 0x0000ffff, 0x40282220, 0x000 }, + { 0x0000000f, 0x00262228, 0x000 }, + { 0x00000010, 0x40212620, 0x000 }, + { 0x0000000f, 0x00262629, 0x000 }, + { 0x00000000, 0x00202802, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001b, 0x00204811, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x1e0 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000081, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000080, 0x00201c11, 0x000 }, + { 0x00000000, 0x002f0227, 0x000 }, + { 0x00000000, 0x0ce00000, 0x1dc }, + { 0x00000000, 0x00600000, 0x1e9 }, + { 0x00000001, 0x00531e27, 0x1d8 }, + { 0x00000001, 0x00202c11, 0x000 }, + { 0x0000001f, 0x00280a22, 0x000 }, + { 0x0000001f, 0x00282a2a, 0x000 }, + { 0x00000001, 0x00530621, 0x1d1 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000002, 0x00304a2f, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000001, 0x00301e2f, 0x000 }, + { 0x00000000, 0x002f0227, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00600000, 0x1e9 }, + { 0x00000001, 0x00531e27, 0x1e5 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x0000000f, 0x00260e23, 0x000 }, + { 0x00000010, 0xc0211220, 0x000 }, + { 0x0000000f, 0x00261224, 0x000 }, + { 0x00000000, 0x00201411, 0x000 }, + { 0x00000000, 0x00601811, 0x2bb }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0x002f022b, 0x000 }, + { 0x00000000, 0x0ce00000, 0x1f8 }, + { 0x00000010, 0x00221628, 0x000 }, + { 0xffff0000, 0x00281625, 0x000 }, + { 0x0000ffff, 0x00281a29, 0x000 }, + { 0x00000000, 0x002948c5, 0x000 }, + { 0x00000000, 0x0020480a, 0x000 }, + { 0x00000000, 0x00202c11, 0x000 }, + { 0x00000010, 0x00221623, 0x000 }, + { 0xffff0000, 0x00281625, 0x000 }, + { 0x0000ffff, 0x00281a24, 0x000 }, + { 0x00000000, 0x002948c5, 0x000 }, + { 0x00000000, 0x00731503, 0x205 }, + { 0x00000000, 0x00201805, 0x000 }, + { 0x00000000, 0x00731524, 0x205 }, + { 0x00000000, 0x002d14c5, 0x000 }, + { 0x00000000, 0x003008a2, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00202802, 0x000 }, + { 0x00000000, 0x00202003, 0x000 }, + { 0x00000000, 0x00802404, 0x000 }, + { 0x0000000f, 0x00210225, 0x000 }, + { 0x00000000, 0x14c00000, 0x68c }, + { 0x00000000, 0x002b1405, 0x000 }, + { 0x00000001, 0x00901625, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001a, 0x00294a22, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00384a21, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0000ffff, 0x40281220, 0x000 }, + { 0x00000010, 0xc0211a20, 0x000 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x00000010, 0xc0211620, 0x000 }, + { 0x00000000, 0x00741465, 0x2bb }, + { 0x0001a1fd, 0x00604411, 0x2e0 }, + { 0x00000001, 0x00330621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0cc00000, 0x219 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x212 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000000, 0x00600000, 0x645 }, + { 0x00000000, 0x0040040f, 0x213 }, + { 0x00000000, 0x00600000, 0x631 }, + { 0x00000000, 0x00600000, 0x645 }, + { 0x00000210, 0x00600411, 0x315 }, + { 0x00000000, 0x00600000, 0x1a0 }, + { 0x00000000, 0x00600000, 0x19c }, + { 0x00000000, 0x00600000, 0x2bb }, + { 0x00000000, 0x00600000, 0x2a3 }, + { 0x93800000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204808, 0x000 }, + { 0x00000000, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ae00000, 0x232 }, + { 0x00000000, 0x00600000, 0x13a }, + { 0x00000000, 0x00400000, 0x236 }, + { 0x95000000, 0x00204411, 0x000 }, + { 0x00000000, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x236 }, + { 0x00000000, 0xc0404800, 0x233 }, + { 0x92000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x00000016, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0x00600411, 0x2fb }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000000, 0x00600000, 0x631 }, + { 0x0000a00c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000018, 0x40210a20, 0x000 }, + { 0x00000003, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x24c }, + { 0x00000014, 0x0020222d, 0x000 }, + { 0x00080101, 0x00292228, 0x000 }, + { 0x00000014, 0x00203628, 0x000 }, + { 0x0000a30c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x251 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000010, 0x00600411, 0x315 }, + { 0x3f800000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x00000000, 0x00600000, 0x27c }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000001, 0x00211e27, 0x000 }, + { 0x00000000, 0x14e00000, 0x26a }, + { 0x00000012, 0x00201e2d, 0x000 }, + { 0x0000ffff, 0x00281e27, 0x000 }, + { 0x00000000, 0x00341c27, 0x000 }, + { 0x00000000, 0x12c00000, 0x25f }, + { 0x00000000, 0x00201c11, 0x000 }, + { 0x00000000, 0x002f00e5, 0x000 }, + { 0x00000000, 0x08c00000, 0x262 }, + { 0x00000000, 0x00201407, 0x000 }, + { 0x00000012, 0x00201e2d, 0x000 }, + { 0x00000010, 0x00211e27, 0x000 }, + { 0x00000000, 0x00341c47, 0x000 }, + { 0x00000000, 0x12c00000, 0x267 }, + { 0x00000000, 0x00201c11, 0x000 }, + { 0x00000000, 0x002f00e6, 0x000 }, + { 0x00000000, 0x08c00000, 0x26a }, + { 0x00000000, 0x00201807, 0x000 }, + { 0x00000000, 0x00600000, 0x2c1 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x00000000, 0x00342023, 0x000 }, + { 0x00000000, 0x12c00000, 0x272 }, + { 0x00000000, 0x00342044, 0x000 }, + { 0x00000000, 0x12c00000, 0x271 }, + { 0x00000016, 0x00404811, 0x276 }, + { 0x00000018, 0x00404811, 0x276 }, + { 0x00000000, 0x00342044, 0x000 }, + { 0x00000000, 0x12c00000, 0x275 }, + { 0x00000017, 0x00404811, 0x276 }, + { 0x00000019, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0001a1fd, 0x00604411, 0x2e9 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x256 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000010, 0x40210620, 0x000 }, + { 0x0000ffff, 0xc0280a20, 0x000 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x0000ffff, 0xc0281220, 0x000 }, + { 0x00000010, 0x40211620, 0x000 }, + { 0x0000ffff, 0xc0881a20, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00042004, 0x00604411, 0x68d }, + { 0x00000000, 0x00600000, 0x631 }, + { 0x00000000, 0xc0600000, 0x2a3 }, + { 0x00000005, 0x00200a2d, 0x000 }, + { 0x00000008, 0x00220a22, 0x000 }, + { 0x0000002b, 0x00201a2d, 0x000 }, + { 0x0000001c, 0x00201e2d, 0x000 }, + { 0x00007000, 0x00281e27, 0x000 }, + { 0x00000000, 0x00311ce6, 0x000 }, + { 0x0000002a, 0x00201a2d, 0x000 }, + { 0x0000000c, 0x00221a26, 0x000 }, + { 0x00000000, 0x002f00e6, 0x000 }, + { 0x00000000, 0x06e00000, 0x292 }, + { 0x00000000, 0x00201c11, 0x000 }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x0000002b, 0x00203623, 0x000 }, + { 0x00000010, 0x00201811, 0x000 }, + { 0x00000000, 0x00691ce2, 0x12f }, + { 0x93800000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x95000000, 0x00204411, 0x000 }, + { 0x00000000, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x29d }, + { 0x00000001, 0x00333e2f, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x92000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000001c, 0x00403627, 0x000 }, + { 0x0000000c, 0xc0220a20, 0x000 }, + { 0x00000029, 0x00203622, 0x000 }, + { 0x00000028, 0xc0403620, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000009, 0x00204811, 0x000 }, + { 0xa1000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00804811, 0x000 }, + { 0x00000021, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002c1ce3, 0x000 }, + { 0x00000021, 0x00203627, 0x000 }, + { 0x00000022, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002c1ce4, 0x000 }, + { 0x00000022, 0x00203627, 0x000 }, + { 0x00000023, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120a3, 0x000 }, + { 0x00000000, 0x002d1d07, 0x000 }, + { 0x00000023, 0x00203627, 0x000 }, + { 0x00000024, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x00000000, 0x002d1d07, 0x000 }, + { 0x00000024, 0x00803627, 0x000 }, + { 0x00000021, 0x00203623, 0x000 }, + { 0x00000022, 0x00203624, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000023, 0x00203627, 0x000 }, + { 0x00000000, 0x00311cc4, 0x000 }, + { 0x00000024, 0x00803627, 0x000 }, + { 0x0000001a, 0x00203627, 0x000 }, + { 0x0000001b, 0x00203628, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000002, 0x00210227, 0x000 }, + { 0x00000000, 0x14c00000, 0x2dc }, + { 0x00000000, 0x00400000, 0x2d9 }, + { 0x0000001a, 0x00203627, 0x000 }, + { 0x0000001b, 0x00203628, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000002, 0x00210227, 0x000 }, + { 0x00000000, 0x14e00000, 0x2d9 }, + { 0x00000003, 0x00210227, 0x000 }, + { 0x00000000, 0x14e00000, 0x2dc }, + { 0x00000023, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002e00e1, 0x000 }, + { 0x00000000, 0x02c00000, 0x2dc }, + { 0x00000021, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120a1, 0x000 }, + { 0x00000000, 0x002e00e8, 0x000 }, + { 0x00000000, 0x06c00000, 0x2dc }, + { 0x00000024, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002e00e2, 0x000 }, + { 0x00000000, 0x02c00000, 0x2dc }, + { 0x00000022, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120c2, 0x000 }, + { 0x00000000, 0x002e00e8, 0x000 }, + { 0x00000000, 0x06c00000, 0x2dc }, + { 0x00000000, 0x00600000, 0x668 }, + { 0x00000000, 0x00600000, 0x2b5 }, + { 0x00000000, 0x00400000, 0x2de }, + { 0x00000000, 0x00600000, 0x2b5 }, + { 0x00000000, 0x00600000, 0x65f }, + { 0x00000000, 0x00400000, 0x2de }, + { 0x00000000, 0x00600000, 0x2a7 }, + { 0x00000000, 0x00400000, 0x2de }, + { 0x0000001a, 0x00201e2d, 0x000 }, + { 0x0000001b, 0x0080222d, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00894907, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000010, 0x00221e21, 0x000 }, + { 0x00000000, 0x00294847, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000000, 0x00311ca1, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294847, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000010, 0x00221e21, 0x000 }, + { 0x00000000, 0x003120c2, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00894907, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000001, 0x00220a21, 0x000 }, + { 0x00000000, 0x003308a2, 0x000 }, + { 0x00000010, 0x00221e22, 0x000 }, + { 0x00000010, 0x00212222, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000001, 0x00220a21, 0x000 }, + { 0x00000000, 0x003008a2, 0x000 }, + { 0x00000010, 0x00221e22, 0x000 }, + { 0x00000010, 0x00212222, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x003808c5, 0x000 }, + { 0x00000000, 0x00300841, 0x000 }, + { 0x00000001, 0x00220a22, 0x000 }, + { 0x00000000, 0x003308a2, 0x000 }, + { 0x00000010, 0x00221e22, 0x000 }, + { 0x00000010, 0x00212222, 0x000 }, + { 0x00000000, 0x00894907, 0x000 }, + { 0x00000017, 0x0020222d, 0x000 }, + { 0x00000000, 0x14c00000, 0x318 }, + { 0xffffffef, 0x00280621, 0x000 }, + { 0x00000014, 0x0020222d, 0x000 }, + { 0x0000f8e0, 0x00204411, 0x000 }, + { 0x00000000, 0x00294901, 0x000 }, + { 0x00000000, 0x00894901, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00804811, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x97000000, 0xc0204411, 0x000 }, + { 0x00000000, 0xc0204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x97000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x97000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x00002257, 0x00204411, 0x000 }, + { 0x00000003, 0xc0484a20, 0x000 }, + { 0x0000225d, 0x00204411, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000000, 0x00600000, 0x645 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00384a22, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x40204800, 0x000 }, + { 0x00000001, 0x40304a20, 0x000 }, + { 0x00000002, 0xc0304a20, 0x000 }, + { 0x00000001, 0x00530a22, 0x34b }, + { 0x0000003f, 0xc0280a20, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000018, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x68d }, + { 0x00000011, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x354 }, + { 0x00000014, 0x002f0222, 0x000 }, + { 0x00000000, 0x0cc00000, 0x364 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00604802, 0x36e }, + { 0x00002100, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000004, 0x002f0222, 0x000 }, + { 0x00000000, 0x0cc00000, 0x36a }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x35f }, + { 0x00000028, 0x002f0222, 0x000 }, + { 0x00000000, 0x0cc00000, 0x5c0 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x35f }, + { 0x0000002c, 0x00203626, 0x000 }, + { 0x00000049, 0x00201811, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x00000001, 0x00331a26, 0x000 }, + { 0x00000000, 0x002f0226, 0x000 }, + { 0x00000000, 0x0cc00000, 0x370 }, + { 0x0000002c, 0x00801a2d, 0x000 }, + { 0x0000003f, 0xc0280a20, 0x000 }, + { 0x00000015, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x386 }, + { 0x00000006, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x3b1 }, + { 0x00000016, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x3b5 }, + { 0x00000020, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x39c }, + { 0x0000000f, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x3a8 }, + { 0x00000010, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x3a8 }, + { 0x0000001e, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x390 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x000 }, + { 0x08000000, 0x00290a22, 0x000 }, + { 0x00000003, 0x40210e20, 0x000 }, + { 0x0000000c, 0xc0211220, 0x000 }, + { 0x00080000, 0x00281224, 0x000 }, + { 0x00000014, 0xc0221620, 0x000 }, + { 0x00000000, 0x002914a4, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x002948a2, 0x000 }, + { 0x0000a1fe, 0x00204411, 0x000 }, + { 0x00000000, 0x00404803, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000016, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x68d }, + { 0x00000015, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x392 }, + { 0x0000210e, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000017, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x68d }, + { 0x00000003, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x39e }, + { 0x00002108, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x80000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000010, 0x00204811, 0x000 }, + { 0x00000000, 0x00200010, 0x000 }, + { 0x00000000, 0x14c00000, 0x3ae }, + { 0x00000000, 0x00400000, 0x000 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000006, 0x00404811, 0x000 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000016, 0x00604811, 0x36e }, + { 0x00000000, 0x00400000, 0x000 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x0000001d, 0x00210223, 0x000 }, + { 0x00000000, 0x14e00000, 0x3ce }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000018, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x68d }, + { 0x00000011, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x3c0 }, + { 0x00002100, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0xbabecafe, 0x00204811, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000004, 0x00404811, 0x000 }, + { 0x00002170, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000a, 0x00204811, 0x000 }, + { 0x00000000, 0x00200010, 0x000 }, + { 0x00000000, 0x14c00000, 0x3d3 }, + { 0x8c000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00003fff, 0x40280a20, 0x000 }, + { 0x80000000, 0x40280e20, 0x000 }, + { 0x40000000, 0xc0281220, 0x000 }, + { 0x00040000, 0x00694622, 0x68d }, + { 0x00000000, 0x00201410, 0x000 }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x3e1 }, + { 0x00000000, 0xc0401800, 0x3e4 }, + { 0x00003fff, 0xc0281a20, 0x000 }, + { 0x00040000, 0x00694626, 0x68d }, + { 0x00000000, 0x00201810, 0x000 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x3e7 }, + { 0x00000000, 0xc0401c00, 0x3ea }, + { 0x00003fff, 0xc0281e20, 0x000 }, + { 0x00040000, 0x00694627, 0x68d }, + { 0x00000000, 0x00201c10, 0x000 }, + { 0x00000000, 0x00204402, 0x000 }, + { 0x00000000, 0x002820c5, 0x000 }, + { 0x00000000, 0x004948e8, 0x000 }, + { 0xa5800000, 0x00200811, 0x000 }, + { 0x00002000, 0x00200c11, 0x000 }, + { 0x83000000, 0x00604411, 0x412 }, + { 0x00000000, 0x00204402, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x40204800, 0x000 }, + { 0x0000001f, 0xc0210220, 0x000 }, + { 0x00000000, 0x14c00000, 0x3f7 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0000ffff, 0xc0481220, 0x3ff }, + { 0xa7800000, 0x00200811, 0x000 }, + { 0x0000a000, 0x00200c11, 0x000 }, + { 0x83000000, 0x00604411, 0x412 }, + { 0x00000000, 0x00204402, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000ffff, 0xc0281220, 0x000 }, + { 0x83000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00304883, 0x000 }, + { 0x84000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x1d000000, 0x000 }, + { 0x83000000, 0x00604411, 0x412 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0xa9800000, 0x00200811, 0x000 }, + { 0x0000c000, 0x00400c11, 0x3fa }, + { 0xab800000, 0x00200811, 0x000 }, + { 0x0000f8e0, 0x00400c11, 0x3fa }, + { 0xad800000, 0x00200811, 0x000 }, + { 0x0000f880, 0x00400c11, 0x3fa }, + { 0xb3800000, 0x00200811, 0x000 }, + { 0x0000f3fc, 0x00400c11, 0x3fa }, + { 0xaf800000, 0x00200811, 0x000 }, + { 0x0000e000, 0x00400c11, 0x3fa }, + { 0xb1800000, 0x00200811, 0x000 }, + { 0x0000f000, 0x00400c11, 0x3fa }, + { 0x83000000, 0x00204411, 0x000 }, + { 0x00002148, 0x00204811, 0x000 }, + { 0x84000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x1d000000, 0x000 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x01182000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0218a000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0318c000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0418f8e0, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0518f880, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0618e000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0718f000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0818f3fc, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x00000030, 0x00200a2d, 0x000 }, + { 0x00000000, 0xc0290c40, 0x000 }, + { 0x00000030, 0x00203623, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x86000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00404801, 0x000 }, + { 0x85000000, 0xc0204411, 0x000 }, + { 0x00000000, 0x00404801, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x00000018, 0x40210220, 0x000 }, + { 0x00000000, 0x14c00000, 0x445 }, + { 0x00800000, 0xc0494a20, 0x446 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x0004217f, 0x00604411, 0x68d }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x00000000, 0x00404c02, 0x44b }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x00000000, 0xc0201000, 0x000 }, + { 0x00000000, 0xc0201400, 0x000 }, + { 0x00000000, 0xc0201800, 0x000 }, + { 0x00000000, 0xc0201c00, 0x000 }, + { 0x00007f00, 0x00280a21, 0x000 }, + { 0x00004500, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x459 }, + { 0x00000000, 0xc0202000, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x00000010, 0x00280a23, 0x000 }, + { 0x00000010, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x461 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00040000, 0x00694624, 0x68d }, + { 0x00000000, 0x00400000, 0x466 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000216d, 0x00204411, 0x000 }, + { 0x00000000, 0x00204804, 0x000 }, + { 0x00000000, 0x00604805, 0x692 }, + { 0x00000000, 0x002824f0, 0x000 }, + { 0x00000007, 0x00280a23, 0x000 }, + { 0x00000001, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x46d }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x04e00000, 0x486 }, + { 0x00000000, 0x00400000, 0x493 }, + { 0x00000002, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x472 }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x02e00000, 0x486 }, + { 0x00000000, 0x00400000, 0x493 }, + { 0x00000003, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x477 }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x0ce00000, 0x486 }, + { 0x00000000, 0x00400000, 0x493 }, + { 0x00000004, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x47c }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x0ae00000, 0x486 }, + { 0x00000000, 0x00400000, 0x493 }, + { 0x00000005, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x481 }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x06e00000, 0x486 }, + { 0x00000000, 0x00400000, 0x493 }, + { 0x00000006, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x486 }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x08e00000, 0x486 }, + { 0x00000000, 0x00400000, 0x493 }, + { 0x00007f00, 0x00280a21, 0x000 }, + { 0x00004500, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x000 }, + { 0x00000008, 0x00210a23, 0x000 }, + { 0x00000000, 0x14c00000, 0x490 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x00000000, 0xc0204400, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00007f00, 0x00280a21, 0x000 }, + { 0x00004500, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x499 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0400000, 0x000 }, + { 0x00000000, 0x00404c08, 0x459 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x00000011, 0x40211220, 0x000 }, + { 0x00000012, 0x40211620, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00210225, 0x000 }, + { 0x00000000, 0x14e00000, 0x4a3 }, + { 0x00040000, 0xc0494a20, 0x4a4 }, + { 0xfffbffff, 0xc0284a20, 0x000 }, + { 0x00000000, 0x00210223, 0x000 }, + { 0x00000000, 0x14e00000, 0x4b0 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x00210224, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000c, 0x00204811, 0x000 }, + { 0x00000000, 0x00200010, 0x000 }, + { 0x00000000, 0x14c00000, 0x4ac }, + { 0xa0000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000004, 0x00204811, 0x000 }, + { 0x0000216b, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204810, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000005, 0x00204811, 0x000 }, + { 0x0000216c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204810, 0x000 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00400000, 0x4aa }, + { 0x00000000, 0xc0210a20, 0x000 }, + { 0x00000000, 0x14c00000, 0x4c3 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000216d, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0604800, 0x692 }, + { 0x00000000, 0x00400000, 0x4c7 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00040000, 0xc0294620, 0x000 }, + { 0x00000000, 0xc0600000, 0x68d }, + { 0x00000001, 0x00210222, 0x000 }, + { 0x00000000, 0x14c00000, 0x4ce }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x00000000, 0xc0204400, 0x000 }, + { 0x00000000, 0xc0404810, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x0000000e, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x68d }, + { 0x00000000, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x4d0 }, + { 0x00002180, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000003, 0x00333e2f, 0x000 }, + { 0x00000001, 0x00210221, 0x000 }, + { 0x00000000, 0x14e00000, 0x500 }, + { 0x0000002c, 0x00200a2d, 0x000 }, + { 0x00040000, 0x18e00c11, 0x4ef }, + { 0x00000001, 0x00333e2f, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xd8c04800, 0x4e3 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000002d, 0x0020122d, 0x000 }, + { 0x00000000, 0x00290c83, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000011, 0x00210224, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x00000000, 0x00400000, 0x4aa }, + { 0x0000002c, 0xc0203620, 0x000 }, + { 0x0000002d, 0xc0403620, 0x000 }, + { 0x0000000f, 0x00210221, 0x000 }, + { 0x00000000, 0x14c00000, 0x505 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0xd9000000, 0x000 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0xb5000000, 0x00204411, 0x000 }, + { 0x00002000, 0x00204811, 0x000 }, + { 0xb6000000, 0x00204411, 0x000 }, + { 0x0000a000, 0x00204811, 0x000 }, + { 0xb7000000, 0x00204411, 0x000 }, + { 0x0000c000, 0x00204811, 0x000 }, + { 0xb8000000, 0x00204411, 0x000 }, + { 0x0000f8e0, 0x00204811, 0x000 }, + { 0xb9000000, 0x00204411, 0x000 }, + { 0x0000f880, 0x00204811, 0x000 }, + { 0xba000000, 0x00204411, 0x000 }, + { 0x0000e000, 0x00204811, 0x000 }, + { 0xbb000000, 0x00204411, 0x000 }, + { 0x0000f000, 0x00204811, 0x000 }, + { 0xbc000000, 0x00204411, 0x000 }, + { 0x0000f3fc, 0x00204811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000002, 0x00204811, 0x000 }, + { 0x000000ff, 0x00280e30, 0x000 }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x519 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000000, 0x14c00000, 0x52e }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x0000001c, 0x00203623, 0x000 }, + { 0x0000002b, 0x00203623, 0x000 }, + { 0x00000029, 0x00203623, 0x000 }, + { 0x00000028, 0x00203623, 0x000 }, + { 0x00000017, 0x00203623, 0x000 }, + { 0x00000025, 0x00203623, 0x000 }, + { 0x00000026, 0x00203623, 0x000 }, + { 0x00000015, 0x00203623, 0x000 }, + { 0x00000016, 0x00203623, 0x000 }, + { 0xffffe000, 0x00200c11, 0x000 }, + { 0x00000021, 0x00203623, 0x000 }, + { 0x00000022, 0x00203623, 0x000 }, + { 0x00001fff, 0x00200c11, 0x000 }, + { 0x00000023, 0x00203623, 0x000 }, + { 0x00000024, 0x00203623, 0x000 }, + { 0xf1ffffff, 0x00283a2e, 0x000 }, + { 0x0000001a, 0xc0220e20, 0x000 }, + { 0x00000000, 0x0029386e, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x0000002a, 0x40203620, 0x000 }, + { 0x87000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1f4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x00000030, 0x00203623, 0x000 }, + { 0x9d000000, 0x00204411, 0x000 }, + { 0x0000001f, 0x40214a20, 0x000 }, + { 0x96000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x00000000, 0xc0201000, 0x000 }, + { 0x0000001f, 0x00211624, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x0000001d, 0x00203623, 0x000 }, + { 0x00000003, 0x00281e23, 0x000 }, + { 0x00000008, 0x00222223, 0x000 }, + { 0xfffff000, 0x00282228, 0x000 }, + { 0x00000000, 0x002920e8, 0x000 }, + { 0x0000001f, 0x00203628, 0x000 }, + { 0x00000018, 0x00211e23, 0x000 }, + { 0x00000020, 0x00203627, 0x000 }, + { 0x00000002, 0x00221624, 0x000 }, + { 0x00000000, 0x003014a8, 0x000 }, + { 0x0000001e, 0x00203625, 0x000 }, + { 0x00000003, 0x00211a24, 0x000 }, + { 0x10000000, 0x00281a26, 0x000 }, + { 0xefffffff, 0x00283a2e, 0x000 }, + { 0x00000000, 0x004938ce, 0x67b }, + { 0x00000001, 0x40280a20, 0x000 }, + { 0x00000006, 0x40280e20, 0x000 }, + { 0x00000300, 0xc0281220, 0x000 }, + { 0x00000008, 0x00211224, 0x000 }, + { 0x00000000, 0xc0201620, 0x000 }, + { 0x00000000, 0xc0201a20, 0x000 }, + { 0x00000000, 0x00210222, 0x000 }, + { 0x00000000, 0x14c00000, 0x566 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00002258, 0x00300a24, 0x000 }, + { 0x00040000, 0x00694622, 0x68d }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204805, 0x000 }, + { 0x00020000, 0x00294a26, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x56e }, + { 0x00000000, 0xc0201c10, 0x000 }, + { 0x00000000, 0xc0400000, 0x57c }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x56e }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00002258, 0x00300a24, 0x000 }, + { 0x00040000, 0x00694622, 0x68d }, + { 0x00000000, 0xc0201c10, 0x000 }, + { 0x00000000, 0xc0400000, 0x57c }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x572 }, + { 0x00000000, 0xc0201c00, 0x000 }, + { 0x00000000, 0xc0400000, 0x57c }, + { 0x00000004, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x57a }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000216d, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0604800, 0x692 }, + { 0x00000000, 0x00401c10, 0x57c }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0400000, 0x000 }, + { 0x00000000, 0x0ee00000, 0x57e }, + { 0x00000000, 0x00600000, 0x5c9 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x58f }, + { 0x0000a2b7, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a2b6, 0x00604411, 0x68d }, + { 0x0000001a, 0x00212230, 0x000 }, + { 0x00000006, 0x00222630, 0x000 }, + { 0x00042004, 0x00604411, 0x68d }, + { 0x0000a2c4, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x58d }, + { 0x0000a2d1, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d1, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x00000001, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x5a0 }, + { 0x0000a2bb, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a2ba, 0x00604411, 0x68d }, + { 0x0000001a, 0x00212230, 0x000 }, + { 0x00000006, 0x00222630, 0x000 }, + { 0x00042004, 0x00604411, 0x68d }, + { 0x0000a2c5, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x59e }, + { 0x0000a2d2, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d2, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x00000002, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x5b1 }, + { 0x0000a2bf, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a2be, 0x00604411, 0x68d }, + { 0x0000001a, 0x00212230, 0x000 }, + { 0x00000006, 0x00222630, 0x000 }, + { 0x00042004, 0x00604411, 0x68d }, + { 0x0000a2c6, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x5af }, + { 0x0000a2d3, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d3, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x0000a2c3, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a2c2, 0x00604411, 0x68d }, + { 0x0000001a, 0x00212230, 0x000 }, + { 0x00000006, 0x00222630, 0x000 }, + { 0x00042004, 0x00604411, 0x68d }, + { 0x0000a2c7, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x5be }, + { 0x0000a2d4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d4, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x85000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204801, 0x000 }, + { 0x0000304a, 0x00204411, 0x000 }, + { 0x01000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00400000, 0x5c4 }, + { 0xa4000000, 0xc0204411, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000000, 0xc0600000, 0x5c9 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x0000002c, 0x00203621, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x00000000, 0x002f0230, 0x000 }, + { 0x00000000, 0x0cc00000, 0x5d0 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000030, 0x00403621, 0x5e3 }, + { 0x00000030, 0x0020062d, 0x000 }, + { 0x00007e00, 0x00280621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x5e3 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a092, 0x00604411, 0x68d }, + { 0x00000031, 0x00203630, 0x000 }, + { 0x0004a093, 0x00604411, 0x68d }, + { 0x00000032, 0x00203630, 0x000 }, + { 0x0004a2b6, 0x00604411, 0x68d }, + { 0x00000033, 0x00203630, 0x000 }, + { 0x0004a2ba, 0x00604411, 0x68d }, + { 0x00000034, 0x00203630, 0x000 }, + { 0x0004a2be, 0x00604411, 0x68d }, + { 0x00000035, 0x00203630, 0x000 }, + { 0x0004a2c2, 0x00604411, 0x68d }, + { 0x00000036, 0x00203630, 0x000 }, + { 0x00042004, 0x00604411, 0x68d }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x00000005, 0x00204811, 0x000 }, + { 0x0000a1f4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x88000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x00000001, 0x002f0230, 0x000 }, + { 0x00000000, 0x0ce00000, 0x62c }, + { 0x00000030, 0x0020062d, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x62c }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00007e00, 0x00280621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x605 }, + { 0x0000a092, 0x00204411, 0x000 }, + { 0x00000031, 0x00204a2d, 0x000 }, + { 0x0000a093, 0x00204411, 0x000 }, + { 0x00000032, 0x00204a2d, 0x000 }, + { 0x0000a2b6, 0x00204411, 0x000 }, + { 0x00000033, 0x00204a2d, 0x000 }, + { 0x0000a2ba, 0x00204411, 0x000 }, + { 0x00000034, 0x00204a2d, 0x000 }, + { 0x0000a2be, 0x00204411, 0x000 }, + { 0x00000035, 0x00204a2d, 0x000 }, + { 0x0000a2c2, 0x00204411, 0x000 }, + { 0x00000036, 0x00204a2d, 0x000 }, + { 0x00000030, 0x0020062d, 0x000 }, + { 0x000001ff, 0x00280621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x62b }, + { 0x00000000, 0x00210221, 0x000 }, + { 0x00000000, 0x14c00000, 0x60e }, + { 0x0004a003, 0x00604411, 0x68d }, + { 0x0000a003, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x00000001, 0x00210621, 0x000 }, + { 0x00000000, 0x14c00000, 0x613 }, + { 0x0004a010, 0x00604411, 0x68d }, + { 0x0000a010, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x00000001, 0x00210621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x62b }, + { 0x0004a011, 0x00604411, 0x68d }, + { 0x0000a011, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a012, 0x00604411, 0x68d }, + { 0x0000a012, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a013, 0x00604411, 0x68d }, + { 0x0000a013, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a014, 0x00604411, 0x68d }, + { 0x0000a014, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a015, 0x00604411, 0x68d }, + { 0x0000a015, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a016, 0x00604411, 0x68d }, + { 0x0000a016, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a017, 0x00604411, 0x68d }, + { 0x0000a017, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x00042004, 0x00604411, 0x68d }, + { 0x0000002c, 0x0080062d, 0x000 }, + { 0xff000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000002, 0x00804811, 0x000 }, + { 0x00000000, 0x0ee00000, 0x63d }, + { 0x00000030, 0x0020062d, 0x000 }, + { 0x00000002, 0x00280621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x63b }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00042004, 0x00604411, 0x68d }, + { 0x00001000, 0x00200811, 0x000 }, + { 0x0000002b, 0x00203622, 0x000 }, + { 0x00000000, 0x00600000, 0x641 }, + { 0x00000000, 0x00600000, 0x5c9 }, + { 0x98000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00804811, 0x000 }, + { 0x00000000, 0xc0600000, 0x641 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000022, 0x00204811, 0x000 }, + { 0x89000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00404811, 0x62d }, + { 0x97000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00404811, 0x62d }, + { 0x00000000, 0x00600000, 0x65c }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0xc0204411, 0x000 }, + { 0x00000016, 0x00604811, 0x36e }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00010000, 0x00204811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x09800000, 0x00204811, 0x000 }, + { 0xffffffff, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x0004217f, 0x00604411, 0x68d }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x00000004, 0x00404c11, 0x656 }, + { 0x00000000, 0x00400000, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000004, 0x00291e27, 0x000 }, + { 0x00000017, 0x00803627, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0xfffffffb, 0x00281e27, 0x000 }, + { 0x00000017, 0x00803627, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000008, 0x00291e27, 0x000 }, + { 0x00000017, 0x00803627, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0xfffffff7, 0x00281e27, 0x000 }, + { 0x00000017, 0x00803627, 0x000 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000016, 0x00604811, 0x36e }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00010000, 0x00204811, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x01800000, 0x00204811, 0x000 }, + { 0xffffffff, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004217f, 0x00604411, 0x68d }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x68c }, + { 0x00000010, 0x00404c11, 0x672 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x38c00000, 0x000 }, + { 0x0000001d, 0x00200a2d, 0x000 }, + { 0x0000001e, 0x00200e2d, 0x000 }, + { 0x0000001f, 0x0020122d, 0x000 }, + { 0x00000020, 0x0020162d, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204804, 0x000 }, + { 0x00000000, 0x00204805, 0x000 }, + { 0x00000000, 0x00204801, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000004, 0x00301224, 0x000 }, + { 0x00000000, 0x002f0064, 0x000 }, + { 0x00000000, 0x0cc00000, 0x68b }, + { 0x00000003, 0x00281a22, 0x000 }, + { 0x00000008, 0x00221222, 0x000 }, + { 0xfffff000, 0x00281224, 0x000 }, + { 0x00000000, 0x002910c4, 0x000 }, + { 0x0000001f, 0x00403624, 0x000 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x1ac00000, 0x68d }, + { 0x9f000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000000, 0x1ae00000, 0x690 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x1ac00000, 0x692 }, + { 0x9e000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000000, 0x1ae00000, 0x695 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00001000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001b, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0001a1fd, 0xc0204411, 0x000 }, + { 0x00000021, 0x00201e2d, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000024, 0x0020222d, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000022, 0x0020222d, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000023, 0x00201e2d, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00404811, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x01420502, 0x05c00250, 0x000 }, + { 0x01c30168, 0x043f05c0, 0x000 }, + { 0x02250209, 0x02500151, 0x000 }, + { 0x02230245, 0x02a00241, 0x000 }, + { 0x03d705c0, 0x05c005c0, 0x000 }, + { 0x0649064a, 0x031f05c0, 0x000 }, + { 0x05c005c5, 0x03200340, 0x000 }, + { 0x032a0282, 0x03420334, 0x000 }, + { 0x05c005c0, 0x05c005c0, 0x000 }, + { 0x05c00551, 0x05c005c0, 0x000 }, + { 0x03ba05c0, 0x04bb0344, 0x000 }, + { 0x049a0450, 0x043d05c0, 0x000 }, + { 0x04d005c0, 0x044104dd, 0x000 }, + { 0x04500507, 0x03510375, 0x000 }, + { 0x05c005c0, 0x05c005c0, 0x000 }, + { 0x05c005c0, 0x05c005c0, 0x000 }, + { 0x05c005c0, 0x063f05c7, 0x000 }, + { 0x05c005c0, 0x000705c0, 0x000 }, + { 0x05c005c0, 0x05c005c0, 0x000 }, + { 0x05c005c0, 0x05c005c0, 0x000 }, + { 0x03f803ed, 0x04080406, 0x000 }, + { 0x040e040a, 0x040c0410, 0x000 }, + { 0x041c0418, 0x04240420, 0x000 }, + { 0x042c0428, 0x04340430, 0x000 }, + { 0x05c005c0, 0x043805c0, 0x000 }, + { 0x05c005c0, 0x05c005c0, 0x000 }, + { 0x05c005c0, 0x05c005c0, 0x000 }, + { 0x00020679, 0x06970006, 0x000 }, +}; + +static const u32 RV620_pfp_microcode[] = { +0xca0400, +0xa00000, +0x7e828b, +0x7c038b, +0x8001b8, +0x7c038b, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xc41838, +0xca2400, +0xca2800, +0x9581a8, +0xc41c3a, +0xc3c000, +0xca0800, +0xca0c00, +0x7c744b, +0xc20005, +0x99c000, +0xc41c3a, +0x7c744c, +0xc0fff0, +0x042c04, +0x309002, +0x7d2500, +0x351402, +0x7d350b, +0x255403, +0x7cd580, +0x259c03, +0x95c004, +0xd5001b, +0x7eddc1, +0x7d9d80, +0xd6801b, +0xd5801b, +0xd4401e, +0xd5401e, +0xd6401e, +0xd6801e, +0xd4801e, +0xd4c01e, +0x9783d3, +0xd5c01e, +0xca0800, +0x80001a, +0xca0c00, +0xe4011e, +0xd4001e, +0x80000c, +0xc41838, +0xe4013e, +0xd4001e, +0x80000c, +0xc41838, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xe4011e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xe4013e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xca1800, +0xd4401e, +0xd5801e, +0x800053, +0xd40075, +0xd4401e, +0xca0800, +0xca0c00, +0xca1000, +0xd48019, +0xd4c018, +0xd50017, +0xd4801e, +0xd4c01e, +0xd5001e, +0xe2001e, +0xca0400, +0xa00000, +0x7e828b, +0xca0800, +0xd48060, +0xd4401e, +0x800000, +0xd4801e, +0xca0800, +0xd48061, +0xd4401e, +0x800000, +0xd4801e, +0xca0800, +0xca0c00, +0xd4401e, +0xd48016, +0xd4c016, +0xd4801e, +0x8001b8, +0xd4c01e, +0xc60843, +0xca0c00, +0xca1000, +0x948004, +0xca1400, +0xe420f3, +0xd42013, +0xd56065, +0xd4e01c, +0xd5201c, +0xd5601c, +0x800000, +0x062001, +0xc60843, +0xca0c00, +0xca1000, +0x9483f7, +0xca1400, +0xe420f3, +0x800079, +0xd42013, +0xc60843, +0xca0c00, +0xca1000, +0x9883ef, +0xca1400, +0xd40064, +0x80008d, +0x000000, +0xc41432, +0xc61843, +0xc4082f, +0x954005, +0xc40c30, +0xd4401e, +0x800000, +0xee001e, +0x9583f5, +0xc41031, +0xd44033, +0xd52065, +0xd4a01c, +0xd4e01c, +0xd5201c, +0xe4015e, +0xd4001e, +0x800000, +0x062001, +0xca1800, +0x0a2001, +0xd60076, +0xc40836, +0x988007, +0xc61045, +0x950110, +0xd4001f, +0xd46062, +0x800000, +0xd42062, +0xcc3835, +0xcc1433, +0x8401bb, +0xd40072, +0xd5401e, +0x800000, +0xee001e, +0xe2001a, +0x8401bb, +0xe2001a, +0xcc104b, +0xcc0447, +0x2c9401, +0x7d098b, +0x984005, +0x7d15cb, +0xd4001a, +0x8001b8, +0xd4006d, +0x344401, +0xcc0c48, +0x98403a, +0xcc2c4a, +0x958004, +0xcc0449, +0x8001b8, +0xd4001a, +0xd4c01a, +0x282801, +0x8400f0, +0xcc1003, +0x98801b, +0x04380c, +0x8400f0, +0xcc1003, +0x988017, +0x043808, +0x8400f0, +0xcc1003, +0x988013, +0x043804, +0x8400f0, +0xcc1003, +0x988014, +0xcc104c, +0x9a8009, +0xcc144d, +0x9840dc, +0xd4006d, +0xcc1848, +0xd5001a, +0xd5401a, +0x8000c9, +0xd5801a, +0x96c0d5, +0xd4006d, +0x8001b8, +0xd4006e, +0x9ac003, +0xd4006d, +0xd4006e, +0x800000, +0xec007f, +0x9ac0cc, +0xd4006d, +0x8001b8, +0xd4006e, +0xcc1403, +0xcc1803, +0xcc1c03, +0x7d9103, +0x7dd583, +0x7d190c, +0x35cc1f, +0x35701f, +0x7cf0cb, +0x7cd08b, +0x880000, +0x7e8e8b, +0x95c004, +0xd4006e, +0x8001b8, +0xd4001a, +0xd4c01a, +0xcc0803, +0xcc0c03, +0xcc1003, +0xcc1403, +0xcc1803, +0xcc1c03, +0xcc2403, +0xcc2803, +0x35c41f, +0x36b01f, +0x7c704b, +0x34f01f, +0x7c704b, +0x35701f, +0x7c704b, +0x7d8881, +0x7dccc1, +0x7e5101, +0x7e9541, +0x7c9082, +0x7cd4c2, +0x7c848b, +0x9ac003, +0x7c8c8b, +0x2c8801, +0x98809e, +0xd4006d, +0x98409c, +0xd4006e, +0xcc084c, +0xcc0c4d, +0xcc1048, +0xd4801a, +0xd4c01a, +0x800101, +0xd5001a, +0xcc0832, +0xd40032, +0x9482d9, +0xca0c00, +0xd4401e, +0x800000, +0xd4001e, +0xe4011e, +0xd4001e, +0xca0800, +0xca0c00, +0xca1000, +0xd4401e, +0xca1400, +0xd4801e, +0xd4c01e, +0xd5001e, +0xd5401e, +0xd54034, +0x800000, +0xee001e, +0x280404, +0xe2001a, +0xe2001a, +0xd4401a, +0xca3800, +0xcc0803, +0xcc0c03, +0xcc0c03, +0xcc0c03, +0x9882bd, +0x000000, +0x8401bb, +0xd7a06f, +0x800000, +0xee001f, +0xca0400, +0xc2ff00, +0xcc0834, +0xc13fff, +0x7c74cb, +0x7cc90b, +0x7d010f, +0x9902b0, +0x7c738b, +0x8401bb, +0xd7a06f, +0x800000, +0xee001f, +0xca0800, +0x281900, +0x7d898b, +0x958014, +0x281404, +0xca0c00, +0xca1000, +0xca1c00, +0xca2400, +0xe2001f, +0xd4c01a, +0xd5001a, +0xd5401a, +0xcc1803, +0xcc2c03, +0xcc2c03, +0xcc2c03, +0x7da58b, +0x7d9c47, +0x984297, +0x000000, +0x800161, +0xd4c01a, +0xd4401e, +0xd4801e, +0x800000, +0xee001e, +0xe4011e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xe4013e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xca0800, +0x248c06, +0x0ccc06, +0x98c006, +0xcc104e, +0x990004, +0xd40073, +0xe4011e, +0xd4001e, +0xd4401e, +0xd4801e, +0x800000, +0xee001e, +0xca0800, +0xca0c00, +0x34d018, +0x251001, +0x950021, +0xc17fff, +0xca1000, +0xca1400, +0xca1800, +0xd4801d, +0xd4c01d, +0x7db18b, +0xc14202, +0xc2c001, +0xd5801d, +0x34dc0e, +0x7d5d4c, +0x7f734c, +0xd7401e, +0xd5001e, +0xd5401e, +0xc14200, +0xc2c000, +0x099c01, +0x31dc10, +0x7f5f4c, +0x7f734c, +0x042802, +0x7d8380, +0xd5a86f, +0xd58066, +0xd7401e, +0xec005e, +0xc82402, +0xc82402, +0x8001b8, +0xd60076, +0xd4401e, +0xd4801e, +0xd4c01e, +0x800000, +0xee001e, +0x800000, +0xee001f, +0xd4001f, +0x800000, +0xd4001f, +0xd4001f, +0x880000, +0xd4001f, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x010171, +0x020178, +0x03008f, +0x04007f, +0x050003, +0x06003f, +0x070032, +0x08012c, +0x090046, +0x0a0036, +0x1001b6, +0x1700a2, +0x22013a, +0x230149, +0x2000b4, +0x240125, +0x27004d, +0x28006a, +0x2a0060, +0x2b0052, +0x2f0065, +0x320087, +0x34017f, +0x3c0156, +0x3f0072, +0x41018c, +0x44012e, +0x550173, +0x56017a, +0x60000b, +0x610034, +0x620038, +0x630038, +0x640038, +0x650038, +0x660038, +0x670038, +0x68003a, +0x690041, +0x6a0048, +0x6b0048, +0x6c0048, +0x6d0048, +0x6e0048, +0x6f0048, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +}; + +static const u32 RV630_cp_microcode[][3] = { + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0000ffff, 0x00284621, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x00000000, 0x00e00000, 0x000 }, + { 0x00010000, 0xc0294620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00042004, 0x00604411, 0x68a }, + { 0x00000000, 0x00600000, 0x62e }, + { 0x00000000, 0x00600000, 0x642 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000f00, 0x00281622, 0x000 }, + { 0x00000008, 0x00211625, 0x000 }, + { 0x00000018, 0x00203625, 0x000 }, + { 0x8d000000, 0x00204411, 0x000 }, + { 0x00000004, 0x002f0225, 0x000 }, + { 0x00000000, 0x0ce00000, 0x018 }, + { 0x00412000, 0x00404811, 0x019 }, + { 0x00422000, 0x00204811, 0x000 }, + { 0x8e000000, 0x00204411, 0x000 }, + { 0x00000028, 0x00204a2d, 0x000 }, + { 0x90000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204805, 0x000 }, + { 0x0000000c, 0x00211622, 0x000 }, + { 0x00000003, 0x00281625, 0x000 }, + { 0x00000019, 0x00211a22, 0x000 }, + { 0x00000004, 0x00281a26, 0x000 }, + { 0x00000000, 0x002914c5, 0x000 }, + { 0x00000019, 0x00203625, 0x000 }, + { 0x00000000, 0x003a1402, 0x000 }, + { 0x00000016, 0x00211625, 0x000 }, + { 0x00000003, 0x00281625, 0x000 }, + { 0x00000017, 0x00200e2d, 0x000 }, + { 0xfffffffc, 0x00280e23, 0x000 }, + { 0x00000000, 0x002914a3, 0x000 }, + { 0x00000017, 0x00203625, 0x000 }, + { 0x00008000, 0x00280e22, 0x000 }, + { 0x00000007, 0x00220e23, 0x000 }, + { 0x00000000, 0x0029386e, 0x000 }, + { 0x20000000, 0x00280e22, 0x000 }, + { 0x00000006, 0x00210e23, 0x000 }, + { 0x00000000, 0x0029386e, 0x000 }, + { 0x00000000, 0x00220222, 0x000 }, + { 0x00000000, 0x14e00000, 0x038 }, + { 0x00000000, 0x2ee00000, 0x035 }, + { 0x00000000, 0x2ce00000, 0x037 }, + { 0x00000000, 0x00400e2d, 0x039 }, + { 0x00000008, 0x00200e2d, 0x000 }, + { 0x00000009, 0x0040122d, 0x046 }, + { 0x00000001, 0x00400e2d, 0x039 }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x003ffffc, 0x00281223, 0x000 }, + { 0x00000002, 0x00221224, 0x000 }, + { 0x0000001f, 0x00211e23, 0x000 }, + { 0x00000000, 0x14e00000, 0x03e }, + { 0x00000008, 0x00401c11, 0x041 }, + { 0x0000000d, 0x00201e2d, 0x000 }, + { 0x0000000f, 0x00281e27, 0x000 }, + { 0x00000003, 0x00221e27, 0x000 }, + { 0x7fc00000, 0x00281a23, 0x000 }, + { 0x00000014, 0x00211a26, 0x000 }, + { 0x00000001, 0x00331a26, 0x000 }, + { 0x00000008, 0x00221a26, 0x000 }, + { 0x00000000, 0x00290cc7, 0x000 }, + { 0x00000027, 0x00203624, 0x000 }, + { 0x00007f00, 0x00281221, 0x000 }, + { 0x00001400, 0x002f0224, 0x000 }, + { 0x00000000, 0x0ce00000, 0x04b }, + { 0x00000001, 0x00290e23, 0x000 }, + { 0x0000000e, 0x00203623, 0x000 }, + { 0x0000e000, 0x00204411, 0x000 }, + { 0xfff80000, 0x00294a23, 0x000 }, + { 0x00000000, 0x003a2c02, 0x000 }, + { 0x00000002, 0x00220e2b, 0x000 }, + { 0xfc000000, 0x00280e23, 0x000 }, + { 0x0000000f, 0x00203623, 0x000 }, + { 0x00001fff, 0x00294a23, 0x000 }, + { 0x00000027, 0x00204a2d, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000029, 0x00200e2d, 0x000 }, + { 0x060a0200, 0x00294a23, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000001, 0x00210222, 0x000 }, + { 0x00000000, 0x14e00000, 0x061 }, + { 0x00000000, 0x2ee00000, 0x05f }, + { 0x00000000, 0x2ce00000, 0x05e }, + { 0x00000000, 0x00400e2d, 0x062 }, + { 0x00000001, 0x00400e2d, 0x062 }, + { 0x0000000a, 0x00200e2d, 0x000 }, + { 0x0000000b, 0x0040122d, 0x06a }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x003ffffc, 0x00281223, 0x000 }, + { 0x00000002, 0x00221224, 0x000 }, + { 0x7fc00000, 0x00281623, 0x000 }, + { 0x00000014, 0x00211625, 0x000 }, + { 0x00000001, 0x00331625, 0x000 }, + { 0x80000000, 0x00280e23, 0x000 }, + { 0x00000000, 0x00290ca3, 0x000 }, + { 0x3ffffc00, 0x00290e23, 0x000 }, + { 0x0000001f, 0x00211e23, 0x000 }, + { 0x00000000, 0x14e00000, 0x06d }, + { 0x00000100, 0x00401c11, 0x070 }, + { 0x0000000d, 0x00201e2d, 0x000 }, + { 0x000000f0, 0x00281e27, 0x000 }, + { 0x00000004, 0x00221e27, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000d, 0x00204811, 0x000 }, + { 0xfffff0ff, 0x00281a30, 0x000 }, + { 0x0000a028, 0x00204411, 0x000 }, + { 0x00000000, 0x002948e6, 0x000 }, + { 0x0000a018, 0x00204411, 0x000 }, + { 0x3fffffff, 0x00284a23, 0x000 }, + { 0x0000a010, 0x00204411, 0x000 }, + { 0x00000000, 0x00204804, 0x000 }, + { 0x00000030, 0x0020162d, 0x000 }, + { 0x00000002, 0x00291625, 0x000 }, + { 0x00000030, 0x00203625, 0x000 }, + { 0x00000025, 0x0020162d, 0x000 }, + { 0x00000000, 0x002f00a3, 0x000 }, + { 0x00000000, 0x0cc00000, 0x083 }, + { 0x00000026, 0x0020162d, 0x000 }, + { 0x00000000, 0x002f00a4, 0x000 }, + { 0x00000000, 0x0cc00000, 0x084 }, + { 0x00000000, 0x00400000, 0x08a }, + { 0x00000025, 0x00203623, 0x000 }, + { 0x00000026, 0x00203624, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000002, 0x00210227, 0x000 }, + { 0x00000000, 0x14e00000, 0x08a }, + { 0x00000000, 0x00600000, 0x665 }, + { 0x00000000, 0x00600000, 0x659 }, + { 0x00000002, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x08d }, + { 0x00000012, 0xc0403620, 0x093 }, + { 0x00000000, 0x2ee00000, 0x091 }, + { 0x00000000, 0x2ce00000, 0x090 }, + { 0x00000002, 0x00400e2d, 0x092 }, + { 0x00000003, 0x00400e2d, 0x092 }, + { 0x0000000c, 0x00200e2d, 0x000 }, + { 0x00000012, 0x00203623, 0x000 }, + { 0x00000003, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x098 }, + { 0x0000a00c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x0a0 }, + { 0x0000a00c, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x2ee00000, 0x09e }, + { 0x00000000, 0x2ce00000, 0x09d }, + { 0x00000002, 0x00400e2d, 0x09f }, + { 0x00000003, 0x00400e2d, 0x09f }, + { 0x0000000c, 0x00200e2d, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000000, 0x003a0c02, 0x000 }, + { 0x003f0000, 0x00280e23, 0x000 }, + { 0x00000010, 0x00210e23, 0x000 }, + { 0x00000011, 0x00203623, 0x000 }, + { 0x0000001e, 0x0021022b, 0x000 }, + { 0x00000000, 0x14c00000, 0x0a7 }, + { 0x00000016, 0xc0203620, 0x000 }, + { 0x0000001f, 0x0021022b, 0x000 }, + { 0x00000000, 0x14c00000, 0x0aa }, + { 0x00000015, 0xc0203620, 0x000 }, + { 0x00000008, 0x00210e2b, 0x000 }, + { 0x0000007f, 0x00280e23, 0x000 }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0e1 }, + { 0x00000000, 0x27000000, 0x000 }, + { 0x00000000, 0x00600000, 0x2a3 }, + { 0x00000001, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ae00000, 0x0b3 }, + { 0x00000000, 0x00600000, 0x13a }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x0000000c, 0x00221e30, 0x000 }, + { 0x99800000, 0x00204411, 0x000 }, + { 0x00000004, 0x0020122d, 0x000 }, + { 0x00000008, 0x00221224, 0x000 }, + { 0x00000010, 0x00201811, 0x000 }, + { 0x00000000, 0x00291ce4, 0x000 }, + { 0x00000000, 0x00604807, 0x12f }, + { 0x9b000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x9c000000, 0x00204411, 0x000 }, + { 0x00000000, 0x0033146f, 0x000 }, + { 0x00000001, 0x00333e23, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0x00203c05, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000e, 0x00204811, 0x000 }, + { 0x00000000, 0x00201010, 0x000 }, + { 0x0000e007, 0x00204411, 0x000 }, + { 0x0000000f, 0x0021022b, 0x000 }, + { 0x00000000, 0x14c00000, 0x0cb }, + { 0x00f8ff08, 0x00204811, 0x000 }, + { 0x98000000, 0x00404811, 0x0dc }, + { 0x000000f0, 0x00280e22, 0x000 }, + { 0x000000a0, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x0da }, + { 0x00000011, 0x00200e2d, 0x000 }, + { 0x00000001, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0d5 }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0d4 }, + { 0x00003f00, 0x00400c11, 0x0d6 }, + { 0x00001f00, 0x00400c11, 0x0d6 }, + { 0x00000f00, 0x00200c11, 0x000 }, + { 0x00380009, 0x00294a23, 0x000 }, + { 0x3f000000, 0x00280e2b, 0x000 }, + { 0x00000002, 0x00220e23, 0x000 }, + { 0x00000007, 0x00494a23, 0x0dc }, + { 0x00380f09, 0x00204811, 0x000 }, + { 0x68000007, 0x00204811, 0x000 }, + { 0x00000008, 0x00214a27, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00294a24, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000a202, 0x00204411, 0x000 }, + { 0x00ff0000, 0x00280e22, 0x000 }, + { 0x00000080, 0x00294a23, 0x000 }, + { 0x00000027, 0x00200e2d, 0x000 }, + { 0x00000026, 0x0020122d, 0x000 }, + { 0x00000000, 0x002f0083, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0ea }, + { 0x00000000, 0x00600000, 0x65f }, + { 0x00000000, 0x00400000, 0x0eb }, + { 0x00000000, 0x00600000, 0x662 }, + { 0x00000007, 0x0020222d, 0x000 }, + { 0x00000005, 0x00220e22, 0x000 }, + { 0x00100000, 0x00280e23, 0x000 }, + { 0x00000000, 0x00292068, 0x000 }, + { 0x00000000, 0x003a0c02, 0x000 }, + { 0x000000ef, 0x00280e23, 0x000 }, + { 0x00000000, 0x00292068, 0x000 }, + { 0x00000017, 0x00200e2d, 0x000 }, + { 0x00000003, 0x00210223, 0x000 }, + { 0x00000000, 0x14e00000, 0x0f8 }, + { 0x0000000b, 0x00210228, 0x000 }, + { 0x00000000, 0x14c00000, 0x0f8 }, + { 0x00000400, 0x00292228, 0x000 }, + { 0x00000014, 0x00203628, 0x000 }, + { 0x0000001c, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x0fd }, + { 0x0000a30c, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000001e, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x10b }, + { 0x0000a30f, 0x00204411, 0x000 }, + { 0x00000011, 0x00200e2d, 0x000 }, + { 0x00000001, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x104 }, + { 0xffffffff, 0x00404811, 0x10b }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x107 }, + { 0x0000ffff, 0x00404811, 0x10b }, + { 0x00000004, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x10a }, + { 0x000000ff, 0x00404811, 0x10b }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0002c400, 0x00204411, 0x000 }, + { 0x0000001f, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x112 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x00000013, 0x00203623, 0x000 }, + { 0x00000018, 0x40224a20, 0x000 }, + { 0x00000010, 0xc0424a20, 0x114 }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x00000013, 0x00203623, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000000a, 0x00201011, 0x000 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0ce00000, 0x11b }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000001, 0x00531224, 0x117 }, + { 0xffbfffff, 0x00283a2e, 0x000 }, + { 0x0000001b, 0x00210222, 0x000 }, + { 0x00000000, 0x14c00000, 0x12e }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000d, 0x00204811, 0x000 }, + { 0x00000018, 0x00220e30, 0x000 }, + { 0xfc000000, 0x00280e23, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000e, 0x00204811, 0x000 }, + { 0x00000000, 0x00201010, 0x000 }, + { 0x0000e00e, 0x00204411, 0x000 }, + { 0x07f8ff08, 0x00204811, 0x000 }, + { 0x00000000, 0x00294a23, 0x000 }, + { 0x0000001c, 0x00201e2d, 0x000 }, + { 0x00000008, 0x00214a27, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00294a24, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x00800000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204806, 0x000 }, + { 0x00000008, 0x00214a27, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x0004217f, 0x00604411, 0x68a }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x689 }, + { 0x00000004, 0x00404c11, 0x135 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x0000001c, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x68a }, + { 0x00000011, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x13c }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x00000000, 0x00600000, 0x160 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x00000010, 0xc0211220, 0x000 }, + { 0x0000ffff, 0x40280620, 0x000 }, + { 0x00000010, 0xc0210a20, 0x000 }, + { 0x00000000, 0x00341461, 0x000 }, + { 0x00000000, 0x00741882, 0x2bb }, + { 0x0001a1fd, 0x00604411, 0x2e0 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x147 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00600000, 0x160 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x0000ffff, 0xc0281220, 0x000 }, + { 0x00000010, 0x40211620, 0x000 }, + { 0x0000ffff, 0xc0681a20, 0x2bb }, + { 0x0001a1fd, 0x00604411, 0x2e0 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x158 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000001, 0x00300a2f, 0x000 }, + { 0x00000001, 0x00210a22, 0x000 }, + { 0x00000003, 0x00384a22, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001a, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00804811, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600000, 0x18f }, + { 0x00000000, 0x00600000, 0x1a0 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00202c08, 0x000 }, + { 0x00000000, 0x00202411, 0x000 }, + { 0x00000000, 0x00202811, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x00000016, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x93800000, 0x00204411, 0x000 }, + { 0x00000002, 0x00221e29, 0x000 }, + { 0x00000000, 0x007048eb, 0x19c }, + { 0x00000000, 0x00600000, 0x2bb }, + { 0x00000001, 0x40330620, 0x000 }, + { 0x00000000, 0xc0302409, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00600000, 0x2a3 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ae00000, 0x181 }, + { 0x00000000, 0x00600000, 0x13a }, + { 0x00000000, 0x00400000, 0x186 }, + { 0x95000000, 0x00204411, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x186 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000001, 0x00530621, 0x182 }, + { 0x92000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0604800, 0x197 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000011, 0x0020062d, 0x000 }, + { 0x00000000, 0x0078042a, 0x2fb }, + { 0x00000000, 0x00202809, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x174 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000210, 0x00600411, 0x315 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x194 }, + { 0x00000015, 0xc0203620, 0x000 }, + { 0x00000016, 0xc0203620, 0x000 }, + { 0x3f800000, 0x00200411, 0x000 }, + { 0x46000000, 0x00600811, 0x1b2 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x19b }, + { 0x00000001, 0x00804811, 0x000 }, + { 0x00000021, 0x00804811, 0x000 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x00000010, 0xc0211220, 0x000 }, + { 0x0000ffff, 0x40281620, 0x000 }, + { 0x00000010, 0xc0811a20, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x00000008, 0x00221e30, 0x000 }, + { 0x00000029, 0x00201a2d, 0x000 }, + { 0x0000e000, 0x00204411, 0x000 }, + { 0xfffbff09, 0x00204811, 0x000 }, + { 0x0000000f, 0x0020222d, 0x000 }, + { 0x00001fff, 0x00294a28, 0x000 }, + { 0x00000006, 0x0020222d, 0x000 }, + { 0x00000000, 0x002920e8, 0x000 }, + { 0x00000000, 0x00204808, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00294a26, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000100, 0x00201811, 0x000 }, + { 0x00000008, 0x00621e28, 0x12f }, + { 0x00000008, 0x00822228, 0x000 }, + { 0x0002c000, 0x00204411, 0x000 }, + { 0x00000015, 0x00600e2d, 0x1bd }, + { 0x00000016, 0x00600e2d, 0x1bd }, + { 0x0000c008, 0x00204411, 0x000 }, + { 0x00000017, 0x00200e2d, 0x000 }, + { 0x00000000, 0x14c00000, 0x1b9 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00204801, 0x000 }, + { 0x39000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00804802, 0x000 }, + { 0x00000018, 0x00202e2d, 0x000 }, + { 0x00000000, 0x003b0d63, 0x000 }, + { 0x00000008, 0x00224a23, 0x000 }, + { 0x00000010, 0x00224a23, 0x000 }, + { 0x00000018, 0x00224a23, 0x000 }, + { 0x00000000, 0x00804803, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00001000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x00000007, 0x0021062f, 0x000 }, + { 0x00000013, 0x00200a2d, 0x000 }, + { 0x00000001, 0x00202c11, 0x000 }, + { 0x0000ffff, 0x40282220, 0x000 }, + { 0x0000000f, 0x00262228, 0x000 }, + { 0x00000010, 0x40212620, 0x000 }, + { 0x0000000f, 0x00262629, 0x000 }, + { 0x00000000, 0x00202802, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001b, 0x00204811, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x1e0 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000081, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000080, 0x00201c11, 0x000 }, + { 0x00000000, 0x002f0227, 0x000 }, + { 0x00000000, 0x0ce00000, 0x1dc }, + { 0x00000000, 0x00600000, 0x1e9 }, + { 0x00000001, 0x00531e27, 0x1d8 }, + { 0x00000001, 0x00202c11, 0x000 }, + { 0x0000001f, 0x00280a22, 0x000 }, + { 0x0000001f, 0x00282a2a, 0x000 }, + { 0x00000001, 0x00530621, 0x1d1 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000002, 0x00304a2f, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000001, 0x00301e2f, 0x000 }, + { 0x00000000, 0x002f0227, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00600000, 0x1e9 }, + { 0x00000001, 0x00531e27, 0x1e5 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x0000000f, 0x00260e23, 0x000 }, + { 0x00000010, 0xc0211220, 0x000 }, + { 0x0000000f, 0x00261224, 0x000 }, + { 0x00000000, 0x00201411, 0x000 }, + { 0x00000000, 0x00601811, 0x2bb }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0x002f022b, 0x000 }, + { 0x00000000, 0x0ce00000, 0x1f8 }, + { 0x00000010, 0x00221628, 0x000 }, + { 0xffff0000, 0x00281625, 0x000 }, + { 0x0000ffff, 0x00281a29, 0x000 }, + { 0x00000000, 0x002948c5, 0x000 }, + { 0x00000000, 0x0020480a, 0x000 }, + { 0x00000000, 0x00202c11, 0x000 }, + { 0x00000010, 0x00221623, 0x000 }, + { 0xffff0000, 0x00281625, 0x000 }, + { 0x0000ffff, 0x00281a24, 0x000 }, + { 0x00000000, 0x002948c5, 0x000 }, + { 0x00000000, 0x00731503, 0x205 }, + { 0x00000000, 0x00201805, 0x000 }, + { 0x00000000, 0x00731524, 0x205 }, + { 0x00000000, 0x002d14c5, 0x000 }, + { 0x00000000, 0x003008a2, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00202802, 0x000 }, + { 0x00000000, 0x00202003, 0x000 }, + { 0x00000000, 0x00802404, 0x000 }, + { 0x0000000f, 0x00210225, 0x000 }, + { 0x00000000, 0x14c00000, 0x689 }, + { 0x00000000, 0x002b1405, 0x000 }, + { 0x00000001, 0x00901625, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001a, 0x00294a22, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00384a21, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0000ffff, 0x40281220, 0x000 }, + { 0x00000010, 0xc0211a20, 0x000 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x00000010, 0xc0211620, 0x000 }, + { 0x00000000, 0x00741465, 0x2bb }, + { 0x0001a1fd, 0x00604411, 0x2e0 }, + { 0x00000001, 0x00330621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0cc00000, 0x219 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x212 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000000, 0x00600000, 0x642 }, + { 0x00000000, 0x0040040f, 0x213 }, + { 0x00000000, 0x00600000, 0x62e }, + { 0x00000000, 0x00600000, 0x642 }, + { 0x00000210, 0x00600411, 0x315 }, + { 0x00000000, 0x00600000, 0x1a0 }, + { 0x00000000, 0x00600000, 0x19c }, + { 0x00000000, 0x00600000, 0x2bb }, + { 0x00000000, 0x00600000, 0x2a3 }, + { 0x93800000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204808, 0x000 }, + { 0x00000000, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ae00000, 0x232 }, + { 0x00000000, 0x00600000, 0x13a }, + { 0x00000000, 0x00400000, 0x236 }, + { 0x95000000, 0x00204411, 0x000 }, + { 0x00000000, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x236 }, + { 0x00000000, 0xc0404800, 0x233 }, + { 0x92000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x00000016, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0x00600411, 0x2fb }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000000, 0x00600000, 0x62e }, + { 0x0000a00c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000018, 0x40210a20, 0x000 }, + { 0x00000003, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x24c }, + { 0x00000014, 0x0020222d, 0x000 }, + { 0x00080101, 0x00292228, 0x000 }, + { 0x00000014, 0x00203628, 0x000 }, + { 0x0000a30c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x251 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000010, 0x00600411, 0x315 }, + { 0x3f800000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x00000000, 0x00600000, 0x27c }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000001, 0x00211e27, 0x000 }, + { 0x00000000, 0x14e00000, 0x26a }, + { 0x00000012, 0x00201e2d, 0x000 }, + { 0x0000ffff, 0x00281e27, 0x000 }, + { 0x00000000, 0x00341c27, 0x000 }, + { 0x00000000, 0x12c00000, 0x25f }, + { 0x00000000, 0x00201c11, 0x000 }, + { 0x00000000, 0x002f00e5, 0x000 }, + { 0x00000000, 0x08c00000, 0x262 }, + { 0x00000000, 0x00201407, 0x000 }, + { 0x00000012, 0x00201e2d, 0x000 }, + { 0x00000010, 0x00211e27, 0x000 }, + { 0x00000000, 0x00341c47, 0x000 }, + { 0x00000000, 0x12c00000, 0x267 }, + { 0x00000000, 0x00201c11, 0x000 }, + { 0x00000000, 0x002f00e6, 0x000 }, + { 0x00000000, 0x08c00000, 0x26a }, + { 0x00000000, 0x00201807, 0x000 }, + { 0x00000000, 0x00600000, 0x2c1 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x00000000, 0x00342023, 0x000 }, + { 0x00000000, 0x12c00000, 0x272 }, + { 0x00000000, 0x00342044, 0x000 }, + { 0x00000000, 0x12c00000, 0x271 }, + { 0x00000016, 0x00404811, 0x276 }, + { 0x00000018, 0x00404811, 0x276 }, + { 0x00000000, 0x00342044, 0x000 }, + { 0x00000000, 0x12c00000, 0x275 }, + { 0x00000017, 0x00404811, 0x276 }, + { 0x00000019, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0001a1fd, 0x00604411, 0x2e9 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x256 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000010, 0x40210620, 0x000 }, + { 0x0000ffff, 0xc0280a20, 0x000 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x0000ffff, 0xc0281220, 0x000 }, + { 0x00000010, 0x40211620, 0x000 }, + { 0x0000ffff, 0xc0881a20, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00042004, 0x00604411, 0x68a }, + { 0x00000000, 0x00600000, 0x62e }, + { 0x00000000, 0xc0600000, 0x2a3 }, + { 0x00000005, 0x00200a2d, 0x000 }, + { 0x00000008, 0x00220a22, 0x000 }, + { 0x0000002b, 0x00201a2d, 0x000 }, + { 0x0000001c, 0x00201e2d, 0x000 }, + { 0x00007000, 0x00281e27, 0x000 }, + { 0x00000000, 0x00311ce6, 0x000 }, + { 0x0000002a, 0x00201a2d, 0x000 }, + { 0x0000000c, 0x00221a26, 0x000 }, + { 0x00000000, 0x002f00e6, 0x000 }, + { 0x00000000, 0x06e00000, 0x292 }, + { 0x00000000, 0x00201c11, 0x000 }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x0000002b, 0x00203623, 0x000 }, + { 0x00000010, 0x00201811, 0x000 }, + { 0x00000000, 0x00691ce2, 0x12f }, + { 0x93800000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x95000000, 0x00204411, 0x000 }, + { 0x00000000, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x29d }, + { 0x00000001, 0x00333e2f, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x92000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000001c, 0x00403627, 0x000 }, + { 0x0000000c, 0xc0220a20, 0x000 }, + { 0x00000029, 0x00203622, 0x000 }, + { 0x00000028, 0xc0403620, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000009, 0x00204811, 0x000 }, + { 0xa1000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00804811, 0x000 }, + { 0x00000021, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002c1ce3, 0x000 }, + { 0x00000021, 0x00203627, 0x000 }, + { 0x00000022, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002c1ce4, 0x000 }, + { 0x00000022, 0x00203627, 0x000 }, + { 0x00000023, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120a3, 0x000 }, + { 0x00000000, 0x002d1d07, 0x000 }, + { 0x00000023, 0x00203627, 0x000 }, + { 0x00000024, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x00000000, 0x002d1d07, 0x000 }, + { 0x00000024, 0x00803627, 0x000 }, + { 0x00000021, 0x00203623, 0x000 }, + { 0x00000022, 0x00203624, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000023, 0x00203627, 0x000 }, + { 0x00000000, 0x00311cc4, 0x000 }, + { 0x00000024, 0x00803627, 0x000 }, + { 0x0000001a, 0x00203627, 0x000 }, + { 0x0000001b, 0x00203628, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000002, 0x00210227, 0x000 }, + { 0x00000000, 0x14c00000, 0x2dc }, + { 0x00000000, 0x00400000, 0x2d9 }, + { 0x0000001a, 0x00203627, 0x000 }, + { 0x0000001b, 0x00203628, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000002, 0x00210227, 0x000 }, + { 0x00000000, 0x14e00000, 0x2d9 }, + { 0x00000003, 0x00210227, 0x000 }, + { 0x00000000, 0x14e00000, 0x2dc }, + { 0x00000023, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002e00e1, 0x000 }, + { 0x00000000, 0x02c00000, 0x2dc }, + { 0x00000021, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120a1, 0x000 }, + { 0x00000000, 0x002e00e8, 0x000 }, + { 0x00000000, 0x06c00000, 0x2dc }, + { 0x00000024, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002e00e2, 0x000 }, + { 0x00000000, 0x02c00000, 0x2dc }, + { 0x00000022, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120c2, 0x000 }, + { 0x00000000, 0x002e00e8, 0x000 }, + { 0x00000000, 0x06c00000, 0x2dc }, + { 0x00000000, 0x00600000, 0x665 }, + { 0x00000000, 0x00600000, 0x2b5 }, + { 0x00000000, 0x00400000, 0x2de }, + { 0x00000000, 0x00600000, 0x2b5 }, + { 0x00000000, 0x00600000, 0x65c }, + { 0x00000000, 0x00400000, 0x2de }, + { 0x00000000, 0x00600000, 0x2a7 }, + { 0x00000000, 0x00400000, 0x2de }, + { 0x0000001a, 0x00201e2d, 0x000 }, + { 0x0000001b, 0x0080222d, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00894907, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000010, 0x00221e21, 0x000 }, + { 0x00000000, 0x00294847, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000000, 0x00311ca1, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294847, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000010, 0x00221e21, 0x000 }, + { 0x00000000, 0x003120c2, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00894907, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000001, 0x00220a21, 0x000 }, + { 0x00000000, 0x003308a2, 0x000 }, + { 0x00000010, 0x00221e22, 0x000 }, + { 0x00000010, 0x00212222, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000001, 0x00220a21, 0x000 }, + { 0x00000000, 0x003008a2, 0x000 }, + { 0x00000010, 0x00221e22, 0x000 }, + { 0x00000010, 0x00212222, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x003808c5, 0x000 }, + { 0x00000000, 0x00300841, 0x000 }, + { 0x00000001, 0x00220a22, 0x000 }, + { 0x00000000, 0x003308a2, 0x000 }, + { 0x00000010, 0x00221e22, 0x000 }, + { 0x00000010, 0x00212222, 0x000 }, + { 0x00000000, 0x00894907, 0x000 }, + { 0x00000017, 0x0020222d, 0x000 }, + { 0x00000000, 0x14c00000, 0x318 }, + { 0xffffffef, 0x00280621, 0x000 }, + { 0x00000014, 0x0020222d, 0x000 }, + { 0x0000f8e0, 0x00204411, 0x000 }, + { 0x00000000, 0x00294901, 0x000 }, + { 0x00000000, 0x00894901, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00804811, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x97000000, 0xc0204411, 0x000 }, + { 0x00000000, 0xc0204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x97000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x97000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x00002257, 0x00204411, 0x000 }, + { 0x00000003, 0xc0484a20, 0x000 }, + { 0x0000225d, 0x00204411, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000000, 0x00600000, 0x642 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00384a22, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x40204800, 0x000 }, + { 0x00000001, 0x40304a20, 0x000 }, + { 0x00000002, 0xc0304a20, 0x000 }, + { 0x00000001, 0x00530a22, 0x34b }, + { 0x0000003f, 0xc0280a20, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000018, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x68a }, + { 0x00000011, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x354 }, + { 0x00000014, 0x002f0222, 0x000 }, + { 0x00000000, 0x0cc00000, 0x364 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00604802, 0x36e }, + { 0x00002100, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000004, 0x002f0222, 0x000 }, + { 0x00000000, 0x0cc00000, 0x36a }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x35f }, + { 0x00000028, 0x002f0222, 0x000 }, + { 0x00000000, 0x0cc00000, 0x5bd }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x35f }, + { 0x0000002c, 0x00203626, 0x000 }, + { 0x00000049, 0x00201811, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x00000001, 0x00331a26, 0x000 }, + { 0x00000000, 0x002f0226, 0x000 }, + { 0x00000000, 0x0cc00000, 0x370 }, + { 0x0000002c, 0x00801a2d, 0x000 }, + { 0x0000003f, 0xc0280a20, 0x000 }, + { 0x00000015, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x386 }, + { 0x00000006, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x3b1 }, + { 0x00000016, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x3b5 }, + { 0x00000020, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x39c }, + { 0x0000000f, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x3a8 }, + { 0x00000010, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x3a8 }, + { 0x0000001e, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x390 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x000 }, + { 0x08000000, 0x00290a22, 0x000 }, + { 0x00000003, 0x40210e20, 0x000 }, + { 0x0000000c, 0xc0211220, 0x000 }, + { 0x00080000, 0x00281224, 0x000 }, + { 0x00000014, 0xc0221620, 0x000 }, + { 0x00000000, 0x002914a4, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x002948a2, 0x000 }, + { 0x0000a1fe, 0x00204411, 0x000 }, + { 0x00000000, 0x00404803, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000016, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x68a }, + { 0x00000015, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x392 }, + { 0x0000210e, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000017, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x68a }, + { 0x00000003, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x39e }, + { 0x00002108, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x80000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000010, 0x00204811, 0x000 }, + { 0x00000000, 0x00200010, 0x000 }, + { 0x00000000, 0x14c00000, 0x3ae }, + { 0x00000000, 0x00400000, 0x000 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000006, 0x00404811, 0x000 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000016, 0x00604811, 0x36e }, + { 0x00000000, 0x00400000, 0x000 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x0000001d, 0x00210223, 0x000 }, + { 0x00000000, 0x14e00000, 0x3ce }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000018, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x68a }, + { 0x00000011, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x3c0 }, + { 0x00002100, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0xbabecafe, 0x00204811, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000004, 0x00404811, 0x000 }, + { 0x00002170, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000a, 0x00204811, 0x000 }, + { 0x00000000, 0x00200010, 0x000 }, + { 0x00000000, 0x14c00000, 0x3d3 }, + { 0x8c000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00003fff, 0x40280a20, 0x000 }, + { 0x80000000, 0x40280e20, 0x000 }, + { 0x40000000, 0xc0281220, 0x000 }, + { 0x00040000, 0x00694622, 0x68a }, + { 0x00000000, 0x00201410, 0x000 }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x3e1 }, + { 0x00000000, 0xc0401800, 0x3e4 }, + { 0x00003fff, 0xc0281a20, 0x000 }, + { 0x00040000, 0x00694626, 0x68a }, + { 0x00000000, 0x00201810, 0x000 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x3e7 }, + { 0x00000000, 0xc0401c00, 0x3ea }, + { 0x00003fff, 0xc0281e20, 0x000 }, + { 0x00040000, 0x00694627, 0x68a }, + { 0x00000000, 0x00201c10, 0x000 }, + { 0x00000000, 0x00204402, 0x000 }, + { 0x00000000, 0x002820c5, 0x000 }, + { 0x00000000, 0x004948e8, 0x000 }, + { 0xa5800000, 0x00200811, 0x000 }, + { 0x00002000, 0x00200c11, 0x000 }, + { 0x83000000, 0x00604411, 0x412 }, + { 0x00000000, 0x00204402, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x40204800, 0x000 }, + { 0x0000001f, 0xc0210220, 0x000 }, + { 0x00000000, 0x14c00000, 0x3f7 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0000ffff, 0xc0481220, 0x3ff }, + { 0xa7800000, 0x00200811, 0x000 }, + { 0x0000a000, 0x00200c11, 0x000 }, + { 0x83000000, 0x00604411, 0x412 }, + { 0x00000000, 0x00204402, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000ffff, 0xc0281220, 0x000 }, + { 0x83000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00304883, 0x000 }, + { 0x84000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x1d000000, 0x000 }, + { 0x83000000, 0x00604411, 0x412 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0xa9800000, 0x00200811, 0x000 }, + { 0x0000c000, 0x00400c11, 0x3fa }, + { 0xab800000, 0x00200811, 0x000 }, + { 0x0000f8e0, 0x00400c11, 0x3fa }, + { 0xad800000, 0x00200811, 0x000 }, + { 0x0000f880, 0x00400c11, 0x3fa }, + { 0xb3800000, 0x00200811, 0x000 }, + { 0x0000f3fc, 0x00400c11, 0x3fa }, + { 0xaf800000, 0x00200811, 0x000 }, + { 0x0000e000, 0x00400c11, 0x3fa }, + { 0xb1800000, 0x00200811, 0x000 }, + { 0x0000f000, 0x00400c11, 0x3fa }, + { 0x83000000, 0x00204411, 0x000 }, + { 0x00002148, 0x00204811, 0x000 }, + { 0x84000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x1d000000, 0x000 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x01182000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0218a000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0318c000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0418f8e0, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0518f880, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0618e000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0718f000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0818f3fc, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x00000030, 0x00200a2d, 0x000 }, + { 0x00000000, 0xc0290c40, 0x000 }, + { 0x00000030, 0x00203623, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x86000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00404801, 0x000 }, + { 0x85000000, 0xc0204411, 0x000 }, + { 0x00000000, 0x00404801, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x0004217f, 0x00604411, 0x68a }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x00000000, 0x00404c02, 0x448 }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x00000000, 0xc0201000, 0x000 }, + { 0x00000000, 0xc0201400, 0x000 }, + { 0x00000000, 0xc0201800, 0x000 }, + { 0x00000000, 0xc0201c00, 0x000 }, + { 0x00007f00, 0x00280a21, 0x000 }, + { 0x00004500, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x456 }, + { 0x00000000, 0xc0202000, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x00000010, 0x00280a23, 0x000 }, + { 0x00000010, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x45e }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00040000, 0x00694624, 0x68a }, + { 0x00000000, 0x00400000, 0x463 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000216d, 0x00204411, 0x000 }, + { 0x00000000, 0x00204804, 0x000 }, + { 0x00000000, 0x00604805, 0x68f }, + { 0x00000000, 0x002824f0, 0x000 }, + { 0x00000007, 0x00280a23, 0x000 }, + { 0x00000001, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x46a }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x04e00000, 0x483 }, + { 0x00000000, 0x00400000, 0x490 }, + { 0x00000002, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x46f }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x02e00000, 0x483 }, + { 0x00000000, 0x00400000, 0x490 }, + { 0x00000003, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x474 }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x0ce00000, 0x483 }, + { 0x00000000, 0x00400000, 0x490 }, + { 0x00000004, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x479 }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x0ae00000, 0x483 }, + { 0x00000000, 0x00400000, 0x490 }, + { 0x00000005, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x47e }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x06e00000, 0x483 }, + { 0x00000000, 0x00400000, 0x490 }, + { 0x00000006, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x483 }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x08e00000, 0x483 }, + { 0x00000000, 0x00400000, 0x490 }, + { 0x00007f00, 0x00280a21, 0x000 }, + { 0x00004500, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x000 }, + { 0x00000008, 0x00210a23, 0x000 }, + { 0x00000000, 0x14c00000, 0x48d }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x00000000, 0xc0204400, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00007f00, 0x00280a21, 0x000 }, + { 0x00004500, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x496 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0400000, 0x000 }, + { 0x00000000, 0x00404c08, 0x456 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x00000011, 0x40211220, 0x000 }, + { 0x00000012, 0x40211620, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00210225, 0x000 }, + { 0x00000000, 0x14e00000, 0x4a0 }, + { 0x00040000, 0xc0494a20, 0x4a1 }, + { 0xfffbffff, 0xc0284a20, 0x000 }, + { 0x00000000, 0x00210223, 0x000 }, + { 0x00000000, 0x14e00000, 0x4ad }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x00210224, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000c, 0x00204811, 0x000 }, + { 0x00000000, 0x00200010, 0x000 }, + { 0x00000000, 0x14c00000, 0x4a9 }, + { 0xa0000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000004, 0x00204811, 0x000 }, + { 0x0000216b, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204810, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000005, 0x00204811, 0x000 }, + { 0x0000216c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204810, 0x000 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00400000, 0x4a7 }, + { 0x00000000, 0xc0210a20, 0x000 }, + { 0x00000000, 0x14c00000, 0x4c0 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000216d, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0604800, 0x68f }, + { 0x00000000, 0x00400000, 0x4c4 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00040000, 0xc0294620, 0x000 }, + { 0x00000000, 0xc0600000, 0x68a }, + { 0x00000001, 0x00210222, 0x000 }, + { 0x00000000, 0x14c00000, 0x4cb }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x00000000, 0xc0204400, 0x000 }, + { 0x00000000, 0xc0404810, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x0000000e, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x68a }, + { 0x00000000, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x4cd }, + { 0x00002180, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000003, 0x00333e2f, 0x000 }, + { 0x00000001, 0x00210221, 0x000 }, + { 0x00000000, 0x14e00000, 0x4fd }, + { 0x0000002c, 0x00200a2d, 0x000 }, + { 0x00040000, 0x18e00c11, 0x4ec }, + { 0x00000001, 0x00333e2f, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xd8c04800, 0x4e0 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000002d, 0x0020122d, 0x000 }, + { 0x00000000, 0x00290c83, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000011, 0x00210224, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x00000000, 0x00400000, 0x4a7 }, + { 0x0000002c, 0xc0203620, 0x000 }, + { 0x0000002d, 0xc0403620, 0x000 }, + { 0x0000000f, 0x00210221, 0x000 }, + { 0x00000000, 0x14c00000, 0x502 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0xd9000000, 0x000 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0xb5000000, 0x00204411, 0x000 }, + { 0x00002000, 0x00204811, 0x000 }, + { 0xb6000000, 0x00204411, 0x000 }, + { 0x0000a000, 0x00204811, 0x000 }, + { 0xb7000000, 0x00204411, 0x000 }, + { 0x0000c000, 0x00204811, 0x000 }, + { 0xb8000000, 0x00204411, 0x000 }, + { 0x0000f8e0, 0x00204811, 0x000 }, + { 0xb9000000, 0x00204411, 0x000 }, + { 0x0000f880, 0x00204811, 0x000 }, + { 0xba000000, 0x00204411, 0x000 }, + { 0x0000e000, 0x00204811, 0x000 }, + { 0xbb000000, 0x00204411, 0x000 }, + { 0x0000f000, 0x00204811, 0x000 }, + { 0xbc000000, 0x00204411, 0x000 }, + { 0x0000f3fc, 0x00204811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000002, 0x00204811, 0x000 }, + { 0x000000ff, 0x00280e30, 0x000 }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x516 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000000, 0x14c00000, 0x52b }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x0000001c, 0x00203623, 0x000 }, + { 0x0000002b, 0x00203623, 0x000 }, + { 0x00000029, 0x00203623, 0x000 }, + { 0x00000028, 0x00203623, 0x000 }, + { 0x00000017, 0x00203623, 0x000 }, + { 0x00000025, 0x00203623, 0x000 }, + { 0x00000026, 0x00203623, 0x000 }, + { 0x00000015, 0x00203623, 0x000 }, + { 0x00000016, 0x00203623, 0x000 }, + { 0xffffe000, 0x00200c11, 0x000 }, + { 0x00000021, 0x00203623, 0x000 }, + { 0x00000022, 0x00203623, 0x000 }, + { 0x00001fff, 0x00200c11, 0x000 }, + { 0x00000023, 0x00203623, 0x000 }, + { 0x00000024, 0x00203623, 0x000 }, + { 0xf1ffffff, 0x00283a2e, 0x000 }, + { 0x0000001a, 0xc0220e20, 0x000 }, + { 0x00000000, 0x0029386e, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x0000002a, 0x40203620, 0x000 }, + { 0x87000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1f4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x00000030, 0x00203623, 0x000 }, + { 0x9d000000, 0x00204411, 0x000 }, + { 0x0000001f, 0x40214a20, 0x000 }, + { 0x96000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x00000000, 0xc0201000, 0x000 }, + { 0x0000001f, 0x00211624, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x0000001d, 0x00203623, 0x000 }, + { 0x00000003, 0x00281e23, 0x000 }, + { 0x00000008, 0x00222223, 0x000 }, + { 0xfffff000, 0x00282228, 0x000 }, + { 0x00000000, 0x002920e8, 0x000 }, + { 0x0000001f, 0x00203628, 0x000 }, + { 0x00000018, 0x00211e23, 0x000 }, + { 0x00000020, 0x00203627, 0x000 }, + { 0x00000002, 0x00221624, 0x000 }, + { 0x00000000, 0x003014a8, 0x000 }, + { 0x0000001e, 0x00203625, 0x000 }, + { 0x00000003, 0x00211a24, 0x000 }, + { 0x10000000, 0x00281a26, 0x000 }, + { 0xefffffff, 0x00283a2e, 0x000 }, + { 0x00000000, 0x004938ce, 0x678 }, + { 0x00000001, 0x40280a20, 0x000 }, + { 0x00000006, 0x40280e20, 0x000 }, + { 0x00000300, 0xc0281220, 0x000 }, + { 0x00000008, 0x00211224, 0x000 }, + { 0x00000000, 0xc0201620, 0x000 }, + { 0x00000000, 0xc0201a20, 0x000 }, + { 0x00000000, 0x00210222, 0x000 }, + { 0x00000000, 0x14c00000, 0x563 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00002258, 0x00300a24, 0x000 }, + { 0x00040000, 0x00694622, 0x68a }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204805, 0x000 }, + { 0x00020000, 0x00294a26, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x56b }, + { 0x00000000, 0xc0201c10, 0x000 }, + { 0x00000000, 0xc0400000, 0x579 }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x56b }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00002258, 0x00300a24, 0x000 }, + { 0x00040000, 0x00694622, 0x68a }, + { 0x00000000, 0xc0201c10, 0x000 }, + { 0x00000000, 0xc0400000, 0x579 }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x56f }, + { 0x00000000, 0xc0201c00, 0x000 }, + { 0x00000000, 0xc0400000, 0x579 }, + { 0x00000004, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x577 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000216d, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0604800, 0x68f }, + { 0x00000000, 0x00401c10, 0x579 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0400000, 0x000 }, + { 0x00000000, 0x0ee00000, 0x57b }, + { 0x00000000, 0x00600000, 0x5c6 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x58c }, + { 0x0000a2b7, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a2b6, 0x00604411, 0x68a }, + { 0x0000001a, 0x00212230, 0x000 }, + { 0x00000006, 0x00222630, 0x000 }, + { 0x00042004, 0x00604411, 0x68a }, + { 0x0000a2c4, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x58a }, + { 0x0000a2d1, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d1, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x00000001, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x59d }, + { 0x0000a2bb, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a2ba, 0x00604411, 0x68a }, + { 0x0000001a, 0x00212230, 0x000 }, + { 0x00000006, 0x00222630, 0x000 }, + { 0x00042004, 0x00604411, 0x68a }, + { 0x0000a2c5, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x59b }, + { 0x0000a2d2, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d2, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x00000002, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x5ae }, + { 0x0000a2bf, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a2be, 0x00604411, 0x68a }, + { 0x0000001a, 0x00212230, 0x000 }, + { 0x00000006, 0x00222630, 0x000 }, + { 0x00042004, 0x00604411, 0x68a }, + { 0x0000a2c6, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x5ac }, + { 0x0000a2d3, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d3, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x0000a2c3, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a2c2, 0x00604411, 0x68a }, + { 0x0000001a, 0x00212230, 0x000 }, + { 0x00000006, 0x00222630, 0x000 }, + { 0x00042004, 0x00604411, 0x68a }, + { 0x0000a2c7, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x5bb }, + { 0x0000a2d4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d4, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x85000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204801, 0x000 }, + { 0x0000304a, 0x00204411, 0x000 }, + { 0x01000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00400000, 0x5c1 }, + { 0xa4000000, 0xc0204411, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000000, 0xc0600000, 0x5c6 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x0000002c, 0x00203621, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x00000000, 0x002f0230, 0x000 }, + { 0x00000000, 0x0cc00000, 0x5cd }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000030, 0x00403621, 0x5e0 }, + { 0x00000030, 0x0020062d, 0x000 }, + { 0x00007e00, 0x00280621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x5e0 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a092, 0x00604411, 0x68a }, + { 0x00000031, 0x00203630, 0x000 }, + { 0x0004a093, 0x00604411, 0x68a }, + { 0x00000032, 0x00203630, 0x000 }, + { 0x0004a2b6, 0x00604411, 0x68a }, + { 0x00000033, 0x00203630, 0x000 }, + { 0x0004a2ba, 0x00604411, 0x68a }, + { 0x00000034, 0x00203630, 0x000 }, + { 0x0004a2be, 0x00604411, 0x68a }, + { 0x00000035, 0x00203630, 0x000 }, + { 0x0004a2c2, 0x00604411, 0x68a }, + { 0x00000036, 0x00203630, 0x000 }, + { 0x00042004, 0x00604411, 0x68a }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x00000005, 0x00204811, 0x000 }, + { 0x0000a1f4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x88000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x00000001, 0x002f0230, 0x000 }, + { 0x00000000, 0x0ce00000, 0x629 }, + { 0x00000030, 0x0020062d, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x629 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00007e00, 0x00280621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x602 }, + { 0x0000a092, 0x00204411, 0x000 }, + { 0x00000031, 0x00204a2d, 0x000 }, + { 0x0000a093, 0x00204411, 0x000 }, + { 0x00000032, 0x00204a2d, 0x000 }, + { 0x0000a2b6, 0x00204411, 0x000 }, + { 0x00000033, 0x00204a2d, 0x000 }, + { 0x0000a2ba, 0x00204411, 0x000 }, + { 0x00000034, 0x00204a2d, 0x000 }, + { 0x0000a2be, 0x00204411, 0x000 }, + { 0x00000035, 0x00204a2d, 0x000 }, + { 0x0000a2c2, 0x00204411, 0x000 }, + { 0x00000036, 0x00204a2d, 0x000 }, + { 0x00000030, 0x0020062d, 0x000 }, + { 0x000001ff, 0x00280621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x628 }, + { 0x00000000, 0x00210221, 0x000 }, + { 0x00000000, 0x14c00000, 0x60b }, + { 0x0004a003, 0x00604411, 0x68a }, + { 0x0000a003, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x00000001, 0x00210621, 0x000 }, + { 0x00000000, 0x14c00000, 0x610 }, + { 0x0004a010, 0x00604411, 0x68a }, + { 0x0000a010, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x00000001, 0x00210621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x628 }, + { 0x0004a011, 0x00604411, 0x68a }, + { 0x0000a011, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a012, 0x00604411, 0x68a }, + { 0x0000a012, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a013, 0x00604411, 0x68a }, + { 0x0000a013, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a014, 0x00604411, 0x68a }, + { 0x0000a014, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a015, 0x00604411, 0x68a }, + { 0x0000a015, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a016, 0x00604411, 0x68a }, + { 0x0000a016, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a017, 0x00604411, 0x68a }, + { 0x0000a017, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x00042004, 0x00604411, 0x68a }, + { 0x0000002c, 0x0080062d, 0x000 }, + { 0xff000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000002, 0x00804811, 0x000 }, + { 0x00000000, 0x0ee00000, 0x63a }, + { 0x00000030, 0x0020062d, 0x000 }, + { 0x00000002, 0x00280621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x638 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00042004, 0x00604411, 0x68a }, + { 0x00001000, 0x00200811, 0x000 }, + { 0x0000002b, 0x00203622, 0x000 }, + { 0x00000000, 0x00600000, 0x63e }, + { 0x00000000, 0x00600000, 0x5c6 }, + { 0x98000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00804811, 0x000 }, + { 0x00000000, 0xc0600000, 0x63e }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000022, 0x00204811, 0x000 }, + { 0x89000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00404811, 0x62a }, + { 0x97000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00404811, 0x62a }, + { 0x00000000, 0x00600000, 0x659 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0xc0204411, 0x000 }, + { 0x00000016, 0x00604811, 0x36e }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00010000, 0x00204811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x09800000, 0x00204811, 0x000 }, + { 0xffffffff, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x0004217f, 0x00604411, 0x68a }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x00000004, 0x00404c11, 0x653 }, + { 0x00000000, 0x00400000, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000004, 0x00291e27, 0x000 }, + { 0x00000017, 0x00803627, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0xfffffffb, 0x00281e27, 0x000 }, + { 0x00000017, 0x00803627, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000008, 0x00291e27, 0x000 }, + { 0x00000017, 0x00803627, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0xfffffff7, 0x00281e27, 0x000 }, + { 0x00000017, 0x00803627, 0x000 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000016, 0x00604811, 0x36e }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00010000, 0x00204811, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x01800000, 0x00204811, 0x000 }, + { 0xffffffff, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004217f, 0x00604411, 0x68a }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x689 }, + { 0x00000010, 0x00404c11, 0x66f }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x38c00000, 0x000 }, + { 0x0000001d, 0x00200a2d, 0x000 }, + { 0x0000001e, 0x00200e2d, 0x000 }, + { 0x0000001f, 0x0020122d, 0x000 }, + { 0x00000020, 0x0020162d, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204804, 0x000 }, + { 0x00000000, 0x00204805, 0x000 }, + { 0x00000000, 0x00204801, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000004, 0x00301224, 0x000 }, + { 0x00000000, 0x002f0064, 0x000 }, + { 0x00000000, 0x0cc00000, 0x688 }, + { 0x00000003, 0x00281a22, 0x000 }, + { 0x00000008, 0x00221222, 0x000 }, + { 0xfffff000, 0x00281224, 0x000 }, + { 0x00000000, 0x002910c4, 0x000 }, + { 0x0000001f, 0x00403624, 0x000 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x1ac00000, 0x68a }, + { 0x9f000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000000, 0x1ae00000, 0x68d }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x1ac00000, 0x68f }, + { 0x9e000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000000, 0x1ae00000, 0x692 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00001000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001b, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0001a1fd, 0xc0204411, 0x000 }, + { 0x00000021, 0x00201e2d, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000024, 0x0020222d, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000022, 0x0020222d, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000023, 0x00201e2d, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00404811, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x014204ff, 0x05bd0250, 0x000 }, + { 0x01c30168, 0x043f05bd, 0x000 }, + { 0x02250209, 0x02500151, 0x000 }, + { 0x02230245, 0x02a00241, 0x000 }, + { 0x03d705bd, 0x05bd05bd, 0x000 }, + { 0x06460647, 0x031f05bd, 0x000 }, + { 0x05bd05c2, 0x03200340, 0x000 }, + { 0x032a0282, 0x03420334, 0x000 }, + { 0x05bd05bd, 0x05bd05bd, 0x000 }, + { 0x05bd054e, 0x05bd05bd, 0x000 }, + { 0x03ba05bd, 0x04b80344, 0x000 }, + { 0x0497044d, 0x043d05bd, 0x000 }, + { 0x04cd05bd, 0x044104da, 0x000 }, + { 0x044d0504, 0x03510375, 0x000 }, + { 0x05bd05bd, 0x05bd05bd, 0x000 }, + { 0x05bd05bd, 0x05bd05bd, 0x000 }, + { 0x05bd05bd, 0x063c05c4, 0x000 }, + { 0x05bd05bd, 0x000705bd, 0x000 }, + { 0x05bd05bd, 0x05bd05bd, 0x000 }, + { 0x05bd05bd, 0x05bd05bd, 0x000 }, + { 0x03f803ed, 0x04080406, 0x000 }, + { 0x040e040a, 0x040c0410, 0x000 }, + { 0x041c0418, 0x04240420, 0x000 }, + { 0x042c0428, 0x04340430, 0x000 }, + { 0x05bd05bd, 0x043805bd, 0x000 }, + { 0x05bd05bd, 0x05bd05bd, 0x000 }, + { 0x05bd05bd, 0x05bd05bd, 0x000 }, + { 0x00020676, 0x06940006, 0x000 }, +}; + +static const u32 RV630_pfp_microcode[] = { +0xca0400, +0xa00000, +0x7e828b, +0x7c038b, +0x8001b8, +0x7c038b, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xc41838, +0xca2400, +0xca2800, +0x9581a8, +0xc41c3a, +0xc3c000, +0xca0800, +0xca0c00, +0x7c744b, +0xc20005, +0x99c000, +0xc41c3a, +0x7c744c, +0xc0fff0, +0x042c04, +0x309002, +0x7d2500, +0x351402, +0x7d350b, +0x255403, +0x7cd580, +0x259c03, +0x95c004, +0xd5001b, +0x7eddc1, +0x7d9d80, +0xd6801b, +0xd5801b, +0xd4401e, +0xd5401e, +0xd6401e, +0xd6801e, +0xd4801e, +0xd4c01e, +0x9783d3, +0xd5c01e, +0xca0800, +0x80001a, +0xca0c00, +0xe4011e, +0xd4001e, +0x80000c, +0xc41838, +0xe4013e, +0xd4001e, +0x80000c, +0xc41838, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xe4011e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xe4013e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xca1800, +0xd4401e, +0xd5801e, +0x800053, +0xd40075, +0xd4401e, +0xca0800, +0xca0c00, +0xca1000, +0xd48019, +0xd4c018, +0xd50017, +0xd4801e, +0xd4c01e, +0xd5001e, +0xe2001e, +0xca0400, +0xa00000, +0x7e828b, +0xca0800, +0xd48060, +0xd4401e, +0x800000, +0xd4801e, +0xca0800, +0xd48061, +0xd4401e, +0x800000, +0xd4801e, +0xca0800, +0xca0c00, +0xd4401e, +0xd48016, +0xd4c016, +0xd4801e, +0x8001b8, +0xd4c01e, +0xc60843, +0xca0c00, +0xca1000, +0x948004, +0xca1400, +0xe420f3, +0xd42013, +0xd56065, +0xd4e01c, +0xd5201c, +0xd5601c, +0x800000, +0x062001, +0xc60843, +0xca0c00, +0xca1000, +0x9483f7, +0xca1400, +0xe420f3, +0x800079, +0xd42013, +0xc60843, +0xca0c00, +0xca1000, +0x9883ef, +0xca1400, +0xd40064, +0x80008d, +0x000000, +0xc41432, +0xc61843, +0xc4082f, +0x954005, +0xc40c30, +0xd4401e, +0x800000, +0xee001e, +0x9583f5, +0xc41031, +0xd44033, +0xd52065, +0xd4a01c, +0xd4e01c, +0xd5201c, +0xe4015e, +0xd4001e, +0x800000, +0x062001, +0xca1800, +0x0a2001, +0xd60076, +0xc40836, +0x988007, +0xc61045, +0x950110, +0xd4001f, +0xd46062, +0x800000, +0xd42062, +0xcc3835, +0xcc1433, +0x8401bb, +0xd40072, +0xd5401e, +0x800000, +0xee001e, +0xe2001a, +0x8401bb, +0xe2001a, +0xcc104b, +0xcc0447, +0x2c9401, +0x7d098b, +0x984005, +0x7d15cb, +0xd4001a, +0x8001b8, +0xd4006d, +0x344401, +0xcc0c48, +0x98403a, +0xcc2c4a, +0x958004, +0xcc0449, +0x8001b8, +0xd4001a, +0xd4c01a, +0x282801, +0x8400f0, +0xcc1003, +0x98801b, +0x04380c, +0x8400f0, +0xcc1003, +0x988017, +0x043808, +0x8400f0, +0xcc1003, +0x988013, +0x043804, +0x8400f0, +0xcc1003, +0x988014, +0xcc104c, +0x9a8009, +0xcc144d, +0x9840dc, +0xd4006d, +0xcc1848, +0xd5001a, +0xd5401a, +0x8000c9, +0xd5801a, +0x96c0d5, +0xd4006d, +0x8001b8, +0xd4006e, +0x9ac003, +0xd4006d, +0xd4006e, +0x800000, +0xec007f, +0x9ac0cc, +0xd4006d, +0x8001b8, +0xd4006e, +0xcc1403, +0xcc1803, +0xcc1c03, +0x7d9103, +0x7dd583, +0x7d190c, +0x35cc1f, +0x35701f, +0x7cf0cb, +0x7cd08b, +0x880000, +0x7e8e8b, +0x95c004, +0xd4006e, +0x8001b8, +0xd4001a, +0xd4c01a, +0xcc0803, +0xcc0c03, +0xcc1003, +0xcc1403, +0xcc1803, +0xcc1c03, +0xcc2403, +0xcc2803, +0x35c41f, +0x36b01f, +0x7c704b, +0x34f01f, +0x7c704b, +0x35701f, +0x7c704b, +0x7d8881, +0x7dccc1, +0x7e5101, +0x7e9541, +0x7c9082, +0x7cd4c2, +0x7c848b, +0x9ac003, +0x7c8c8b, +0x2c8801, +0x98809e, +0xd4006d, +0x98409c, +0xd4006e, +0xcc084c, +0xcc0c4d, +0xcc1048, +0xd4801a, +0xd4c01a, +0x800101, +0xd5001a, +0xcc0832, +0xd40032, +0x9482d9, +0xca0c00, +0xd4401e, +0x800000, +0xd4001e, +0xe4011e, +0xd4001e, +0xca0800, +0xca0c00, +0xca1000, +0xd4401e, +0xca1400, +0xd4801e, +0xd4c01e, +0xd5001e, +0xd5401e, +0xd54034, +0x800000, +0xee001e, +0x280404, +0xe2001a, +0xe2001a, +0xd4401a, +0xca3800, +0xcc0803, +0xcc0c03, +0xcc0c03, +0xcc0c03, +0x9882bd, +0x000000, +0x8401bb, +0xd7a06f, +0x800000, +0xee001f, +0xca0400, +0xc2ff00, +0xcc0834, +0xc13fff, +0x7c74cb, +0x7cc90b, +0x7d010f, +0x9902b0, +0x7c738b, +0x8401bb, +0xd7a06f, +0x800000, +0xee001f, +0xca0800, +0x281900, +0x7d898b, +0x958014, +0x281404, +0xca0c00, +0xca1000, +0xca1c00, +0xca2400, +0xe2001f, +0xd4c01a, +0xd5001a, +0xd5401a, +0xcc1803, +0xcc2c03, +0xcc2c03, +0xcc2c03, +0x7da58b, +0x7d9c47, +0x984297, +0x000000, +0x800161, +0xd4c01a, +0xd4401e, +0xd4801e, +0x800000, +0xee001e, +0xe4011e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xe4013e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xca0800, +0x248c06, +0x0ccc06, +0x98c006, +0xcc104e, +0x990004, +0xd40073, +0xe4011e, +0xd4001e, +0xd4401e, +0xd4801e, +0x800000, +0xee001e, +0xca0800, +0xca0c00, +0x34d018, +0x251001, +0x950021, +0xc17fff, +0xca1000, +0xca1400, +0xca1800, +0xd4801d, +0xd4c01d, +0x7db18b, +0xc14202, +0xc2c001, +0xd5801d, +0x34dc0e, +0x7d5d4c, +0x7f734c, +0xd7401e, +0xd5001e, +0xd5401e, +0xc14200, +0xc2c000, +0x099c01, +0x31dc10, +0x7f5f4c, +0x7f734c, +0x042802, +0x7d8380, +0xd5a86f, +0xd58066, +0xd7401e, +0xec005e, +0xc82402, +0xc82402, +0x8001b8, +0xd60076, +0xd4401e, +0xd4801e, +0xd4c01e, +0x800000, +0xee001e, +0x800000, +0xee001f, +0xd4001f, +0x800000, +0xd4001f, +0xd4001f, +0x880000, +0xd4001f, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x010171, +0x020178, +0x03008f, +0x04007f, +0x050003, +0x06003f, +0x070032, +0x08012c, +0x090046, +0x0a0036, +0x1001b6, +0x1700a2, +0x22013a, +0x230149, +0x2000b4, +0x240125, +0x27004d, +0x28006a, +0x2a0060, +0x2b0052, +0x2f0065, +0x320087, +0x34017f, +0x3c0156, +0x3f0072, +0x41018c, +0x44012e, +0x550173, +0x56017a, +0x60000b, +0x610034, +0x620038, +0x630038, +0x640038, +0x650038, +0x660038, +0x670038, +0x68003a, +0x690041, +0x6a0048, +0x6b0048, +0x6c0048, +0x6d0048, +0x6e0048, +0x6f0048, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +}; + +static const u32 RV635_cp_microcode[][3] = { + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0000ffff, 0x00284621, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x00000000, 0x00e00000, 0x000 }, + { 0x00010000, 0xc0294620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00042004, 0x00604411, 0x68a }, + { 0x00000000, 0x00600000, 0x62e }, + { 0x00000000, 0x00600000, 0x642 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000f00, 0x00281622, 0x000 }, + { 0x00000008, 0x00211625, 0x000 }, + { 0x00000018, 0x00203625, 0x000 }, + { 0x8d000000, 0x00204411, 0x000 }, + { 0x00000004, 0x002f0225, 0x000 }, + { 0x00000000, 0x0ce00000, 0x018 }, + { 0x00412000, 0x00404811, 0x019 }, + { 0x00422000, 0x00204811, 0x000 }, + { 0x8e000000, 0x00204411, 0x000 }, + { 0x00000028, 0x00204a2d, 0x000 }, + { 0x90000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204805, 0x000 }, + { 0x0000000c, 0x00211622, 0x000 }, + { 0x00000003, 0x00281625, 0x000 }, + { 0x00000019, 0x00211a22, 0x000 }, + { 0x00000004, 0x00281a26, 0x000 }, + { 0x00000000, 0x002914c5, 0x000 }, + { 0x00000019, 0x00203625, 0x000 }, + { 0x00000000, 0x003a1402, 0x000 }, + { 0x00000016, 0x00211625, 0x000 }, + { 0x00000003, 0x00281625, 0x000 }, + { 0x00000017, 0x00200e2d, 0x000 }, + { 0xfffffffc, 0x00280e23, 0x000 }, + { 0x00000000, 0x002914a3, 0x000 }, + { 0x00000017, 0x00203625, 0x000 }, + { 0x00008000, 0x00280e22, 0x000 }, + { 0x00000007, 0x00220e23, 0x000 }, + { 0x00000000, 0x0029386e, 0x000 }, + { 0x20000000, 0x00280e22, 0x000 }, + { 0x00000006, 0x00210e23, 0x000 }, + { 0x00000000, 0x0029386e, 0x000 }, + { 0x00000000, 0x00220222, 0x000 }, + { 0x00000000, 0x14e00000, 0x038 }, + { 0x00000000, 0x2ee00000, 0x035 }, + { 0x00000000, 0x2ce00000, 0x037 }, + { 0x00000000, 0x00400e2d, 0x039 }, + { 0x00000008, 0x00200e2d, 0x000 }, + { 0x00000009, 0x0040122d, 0x046 }, + { 0x00000001, 0x00400e2d, 0x039 }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x003ffffc, 0x00281223, 0x000 }, + { 0x00000002, 0x00221224, 0x000 }, + { 0x0000001f, 0x00211e23, 0x000 }, + { 0x00000000, 0x14e00000, 0x03e }, + { 0x00000008, 0x00401c11, 0x041 }, + { 0x0000000d, 0x00201e2d, 0x000 }, + { 0x0000000f, 0x00281e27, 0x000 }, + { 0x00000003, 0x00221e27, 0x000 }, + { 0x7fc00000, 0x00281a23, 0x000 }, + { 0x00000014, 0x00211a26, 0x000 }, + { 0x00000001, 0x00331a26, 0x000 }, + { 0x00000008, 0x00221a26, 0x000 }, + { 0x00000000, 0x00290cc7, 0x000 }, + { 0x00000027, 0x00203624, 0x000 }, + { 0x00007f00, 0x00281221, 0x000 }, + { 0x00001400, 0x002f0224, 0x000 }, + { 0x00000000, 0x0ce00000, 0x04b }, + { 0x00000001, 0x00290e23, 0x000 }, + { 0x0000000e, 0x00203623, 0x000 }, + { 0x0000e000, 0x00204411, 0x000 }, + { 0xfff80000, 0x00294a23, 0x000 }, + { 0x00000000, 0x003a2c02, 0x000 }, + { 0x00000002, 0x00220e2b, 0x000 }, + { 0xfc000000, 0x00280e23, 0x000 }, + { 0x0000000f, 0x00203623, 0x000 }, + { 0x00001fff, 0x00294a23, 0x000 }, + { 0x00000027, 0x00204a2d, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000029, 0x00200e2d, 0x000 }, + { 0x060a0200, 0x00294a23, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000001, 0x00210222, 0x000 }, + { 0x00000000, 0x14e00000, 0x061 }, + { 0x00000000, 0x2ee00000, 0x05f }, + { 0x00000000, 0x2ce00000, 0x05e }, + { 0x00000000, 0x00400e2d, 0x062 }, + { 0x00000001, 0x00400e2d, 0x062 }, + { 0x0000000a, 0x00200e2d, 0x000 }, + { 0x0000000b, 0x0040122d, 0x06a }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x003ffffc, 0x00281223, 0x000 }, + { 0x00000002, 0x00221224, 0x000 }, + { 0x7fc00000, 0x00281623, 0x000 }, + { 0x00000014, 0x00211625, 0x000 }, + { 0x00000001, 0x00331625, 0x000 }, + { 0x80000000, 0x00280e23, 0x000 }, + { 0x00000000, 0x00290ca3, 0x000 }, + { 0x3ffffc00, 0x00290e23, 0x000 }, + { 0x0000001f, 0x00211e23, 0x000 }, + { 0x00000000, 0x14e00000, 0x06d }, + { 0x00000100, 0x00401c11, 0x070 }, + { 0x0000000d, 0x00201e2d, 0x000 }, + { 0x000000f0, 0x00281e27, 0x000 }, + { 0x00000004, 0x00221e27, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000d, 0x00204811, 0x000 }, + { 0xfffff0ff, 0x00281a30, 0x000 }, + { 0x0000a028, 0x00204411, 0x000 }, + { 0x00000000, 0x002948e6, 0x000 }, + { 0x0000a018, 0x00204411, 0x000 }, + { 0x3fffffff, 0x00284a23, 0x000 }, + { 0x0000a010, 0x00204411, 0x000 }, + { 0x00000000, 0x00204804, 0x000 }, + { 0x00000030, 0x0020162d, 0x000 }, + { 0x00000002, 0x00291625, 0x000 }, + { 0x00000030, 0x00203625, 0x000 }, + { 0x00000025, 0x0020162d, 0x000 }, + { 0x00000000, 0x002f00a3, 0x000 }, + { 0x00000000, 0x0cc00000, 0x083 }, + { 0x00000026, 0x0020162d, 0x000 }, + { 0x00000000, 0x002f00a4, 0x000 }, + { 0x00000000, 0x0cc00000, 0x084 }, + { 0x00000000, 0x00400000, 0x08a }, + { 0x00000025, 0x00203623, 0x000 }, + { 0x00000026, 0x00203624, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000002, 0x00210227, 0x000 }, + { 0x00000000, 0x14e00000, 0x08a }, + { 0x00000000, 0x00600000, 0x665 }, + { 0x00000000, 0x00600000, 0x659 }, + { 0x00000002, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x08d }, + { 0x00000012, 0xc0403620, 0x093 }, + { 0x00000000, 0x2ee00000, 0x091 }, + { 0x00000000, 0x2ce00000, 0x090 }, + { 0x00000002, 0x00400e2d, 0x092 }, + { 0x00000003, 0x00400e2d, 0x092 }, + { 0x0000000c, 0x00200e2d, 0x000 }, + { 0x00000012, 0x00203623, 0x000 }, + { 0x00000003, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x098 }, + { 0x0000a00c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x0a0 }, + { 0x0000a00c, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x2ee00000, 0x09e }, + { 0x00000000, 0x2ce00000, 0x09d }, + { 0x00000002, 0x00400e2d, 0x09f }, + { 0x00000003, 0x00400e2d, 0x09f }, + { 0x0000000c, 0x00200e2d, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000000, 0x003a0c02, 0x000 }, + { 0x003f0000, 0x00280e23, 0x000 }, + { 0x00000010, 0x00210e23, 0x000 }, + { 0x00000011, 0x00203623, 0x000 }, + { 0x0000001e, 0x0021022b, 0x000 }, + { 0x00000000, 0x14c00000, 0x0a7 }, + { 0x00000016, 0xc0203620, 0x000 }, + { 0x0000001f, 0x0021022b, 0x000 }, + { 0x00000000, 0x14c00000, 0x0aa }, + { 0x00000015, 0xc0203620, 0x000 }, + { 0x00000008, 0x00210e2b, 0x000 }, + { 0x0000007f, 0x00280e23, 0x000 }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0e1 }, + { 0x00000000, 0x27000000, 0x000 }, + { 0x00000000, 0x00600000, 0x2a3 }, + { 0x00000001, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ae00000, 0x0b3 }, + { 0x00000000, 0x00600000, 0x13a }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x0000000c, 0x00221e30, 0x000 }, + { 0x99800000, 0x00204411, 0x000 }, + { 0x00000004, 0x0020122d, 0x000 }, + { 0x00000008, 0x00221224, 0x000 }, + { 0x00000010, 0x00201811, 0x000 }, + { 0x00000000, 0x00291ce4, 0x000 }, + { 0x00000000, 0x00604807, 0x12f }, + { 0x9b000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x9c000000, 0x00204411, 0x000 }, + { 0x00000000, 0x0033146f, 0x000 }, + { 0x00000001, 0x00333e23, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0x00203c05, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000e, 0x00204811, 0x000 }, + { 0x00000000, 0x00201010, 0x000 }, + { 0x0000e007, 0x00204411, 0x000 }, + { 0x0000000f, 0x0021022b, 0x000 }, + { 0x00000000, 0x14c00000, 0x0cb }, + { 0x00f8ff08, 0x00204811, 0x000 }, + { 0x98000000, 0x00404811, 0x0dc }, + { 0x000000f0, 0x00280e22, 0x000 }, + { 0x000000a0, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x0da }, + { 0x00000011, 0x00200e2d, 0x000 }, + { 0x00000001, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0d5 }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0d4 }, + { 0x00003f00, 0x00400c11, 0x0d6 }, + { 0x00001f00, 0x00400c11, 0x0d6 }, + { 0x00000f00, 0x00200c11, 0x000 }, + { 0x00380009, 0x00294a23, 0x000 }, + { 0x3f000000, 0x00280e2b, 0x000 }, + { 0x00000002, 0x00220e23, 0x000 }, + { 0x00000007, 0x00494a23, 0x0dc }, + { 0x00380f09, 0x00204811, 0x000 }, + { 0x68000007, 0x00204811, 0x000 }, + { 0x00000008, 0x00214a27, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00294a24, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000a202, 0x00204411, 0x000 }, + { 0x00ff0000, 0x00280e22, 0x000 }, + { 0x00000080, 0x00294a23, 0x000 }, + { 0x00000027, 0x00200e2d, 0x000 }, + { 0x00000026, 0x0020122d, 0x000 }, + { 0x00000000, 0x002f0083, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0ea }, + { 0x00000000, 0x00600000, 0x65f }, + { 0x00000000, 0x00400000, 0x0eb }, + { 0x00000000, 0x00600000, 0x662 }, + { 0x00000007, 0x0020222d, 0x000 }, + { 0x00000005, 0x00220e22, 0x000 }, + { 0x00100000, 0x00280e23, 0x000 }, + { 0x00000000, 0x00292068, 0x000 }, + { 0x00000000, 0x003a0c02, 0x000 }, + { 0x000000ef, 0x00280e23, 0x000 }, + { 0x00000000, 0x00292068, 0x000 }, + { 0x00000017, 0x00200e2d, 0x000 }, + { 0x00000003, 0x00210223, 0x000 }, + { 0x00000000, 0x14e00000, 0x0f8 }, + { 0x0000000b, 0x00210228, 0x000 }, + { 0x00000000, 0x14c00000, 0x0f8 }, + { 0x00000400, 0x00292228, 0x000 }, + { 0x00000014, 0x00203628, 0x000 }, + { 0x0000001c, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x0fd }, + { 0x0000a30c, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000001e, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x10b }, + { 0x0000a30f, 0x00204411, 0x000 }, + { 0x00000011, 0x00200e2d, 0x000 }, + { 0x00000001, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x104 }, + { 0xffffffff, 0x00404811, 0x10b }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x107 }, + { 0x0000ffff, 0x00404811, 0x10b }, + { 0x00000004, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x10a }, + { 0x000000ff, 0x00404811, 0x10b }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0002c400, 0x00204411, 0x000 }, + { 0x0000001f, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x112 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x00000013, 0x00203623, 0x000 }, + { 0x00000018, 0x40224a20, 0x000 }, + { 0x00000010, 0xc0424a20, 0x114 }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x00000013, 0x00203623, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000000a, 0x00201011, 0x000 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0ce00000, 0x11b }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000001, 0x00531224, 0x117 }, + { 0xffbfffff, 0x00283a2e, 0x000 }, + { 0x0000001b, 0x00210222, 0x000 }, + { 0x00000000, 0x14c00000, 0x12e }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000d, 0x00204811, 0x000 }, + { 0x00000018, 0x00220e30, 0x000 }, + { 0xfc000000, 0x00280e23, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000e, 0x00204811, 0x000 }, + { 0x00000000, 0x00201010, 0x000 }, + { 0x0000e00e, 0x00204411, 0x000 }, + { 0x07f8ff08, 0x00204811, 0x000 }, + { 0x00000000, 0x00294a23, 0x000 }, + { 0x0000001c, 0x00201e2d, 0x000 }, + { 0x00000008, 0x00214a27, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00294a24, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x00800000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204806, 0x000 }, + { 0x00000008, 0x00214a27, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x0004217f, 0x00604411, 0x68a }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x689 }, + { 0x00000004, 0x00404c11, 0x135 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x0000001c, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x68a }, + { 0x00000011, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x13c }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x00000000, 0x00600000, 0x160 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x00000010, 0xc0211220, 0x000 }, + { 0x0000ffff, 0x40280620, 0x000 }, + { 0x00000010, 0xc0210a20, 0x000 }, + { 0x00000000, 0x00341461, 0x000 }, + { 0x00000000, 0x00741882, 0x2bb }, + { 0x0001a1fd, 0x00604411, 0x2e0 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x147 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00600000, 0x160 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x0000ffff, 0xc0281220, 0x000 }, + { 0x00000010, 0x40211620, 0x000 }, + { 0x0000ffff, 0xc0681a20, 0x2bb }, + { 0x0001a1fd, 0x00604411, 0x2e0 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x158 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000001, 0x00300a2f, 0x000 }, + { 0x00000001, 0x00210a22, 0x000 }, + { 0x00000003, 0x00384a22, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001a, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00804811, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600000, 0x18f }, + { 0x00000000, 0x00600000, 0x1a0 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00202c08, 0x000 }, + { 0x00000000, 0x00202411, 0x000 }, + { 0x00000000, 0x00202811, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x00000016, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x93800000, 0x00204411, 0x000 }, + { 0x00000002, 0x00221e29, 0x000 }, + { 0x00000000, 0x007048eb, 0x19c }, + { 0x00000000, 0x00600000, 0x2bb }, + { 0x00000001, 0x40330620, 0x000 }, + { 0x00000000, 0xc0302409, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00600000, 0x2a3 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ae00000, 0x181 }, + { 0x00000000, 0x00600000, 0x13a }, + { 0x00000000, 0x00400000, 0x186 }, + { 0x95000000, 0x00204411, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x186 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000001, 0x00530621, 0x182 }, + { 0x92000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0604800, 0x197 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000011, 0x0020062d, 0x000 }, + { 0x00000000, 0x0078042a, 0x2fb }, + { 0x00000000, 0x00202809, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x174 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000210, 0x00600411, 0x315 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x194 }, + { 0x00000015, 0xc0203620, 0x000 }, + { 0x00000016, 0xc0203620, 0x000 }, + { 0x3f800000, 0x00200411, 0x000 }, + { 0x46000000, 0x00600811, 0x1b2 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x19b }, + { 0x00000001, 0x00804811, 0x000 }, + { 0x00000021, 0x00804811, 0x000 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x00000010, 0xc0211220, 0x000 }, + { 0x0000ffff, 0x40281620, 0x000 }, + { 0x00000010, 0xc0811a20, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x00000008, 0x00221e30, 0x000 }, + { 0x00000029, 0x00201a2d, 0x000 }, + { 0x0000e000, 0x00204411, 0x000 }, + { 0xfffbff09, 0x00204811, 0x000 }, + { 0x0000000f, 0x0020222d, 0x000 }, + { 0x00001fff, 0x00294a28, 0x000 }, + { 0x00000006, 0x0020222d, 0x000 }, + { 0x00000000, 0x002920e8, 0x000 }, + { 0x00000000, 0x00204808, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00294a26, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000100, 0x00201811, 0x000 }, + { 0x00000008, 0x00621e28, 0x12f }, + { 0x00000008, 0x00822228, 0x000 }, + { 0x0002c000, 0x00204411, 0x000 }, + { 0x00000015, 0x00600e2d, 0x1bd }, + { 0x00000016, 0x00600e2d, 0x1bd }, + { 0x0000c008, 0x00204411, 0x000 }, + { 0x00000017, 0x00200e2d, 0x000 }, + { 0x00000000, 0x14c00000, 0x1b9 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00204801, 0x000 }, + { 0x39000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00804802, 0x000 }, + { 0x00000018, 0x00202e2d, 0x000 }, + { 0x00000000, 0x003b0d63, 0x000 }, + { 0x00000008, 0x00224a23, 0x000 }, + { 0x00000010, 0x00224a23, 0x000 }, + { 0x00000018, 0x00224a23, 0x000 }, + { 0x00000000, 0x00804803, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00001000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x00000007, 0x0021062f, 0x000 }, + { 0x00000013, 0x00200a2d, 0x000 }, + { 0x00000001, 0x00202c11, 0x000 }, + { 0x0000ffff, 0x40282220, 0x000 }, + { 0x0000000f, 0x00262228, 0x000 }, + { 0x00000010, 0x40212620, 0x000 }, + { 0x0000000f, 0x00262629, 0x000 }, + { 0x00000000, 0x00202802, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001b, 0x00204811, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x1e0 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000081, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000080, 0x00201c11, 0x000 }, + { 0x00000000, 0x002f0227, 0x000 }, + { 0x00000000, 0x0ce00000, 0x1dc }, + { 0x00000000, 0x00600000, 0x1e9 }, + { 0x00000001, 0x00531e27, 0x1d8 }, + { 0x00000001, 0x00202c11, 0x000 }, + { 0x0000001f, 0x00280a22, 0x000 }, + { 0x0000001f, 0x00282a2a, 0x000 }, + { 0x00000001, 0x00530621, 0x1d1 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000002, 0x00304a2f, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000001, 0x00301e2f, 0x000 }, + { 0x00000000, 0x002f0227, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00600000, 0x1e9 }, + { 0x00000001, 0x00531e27, 0x1e5 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x0000000f, 0x00260e23, 0x000 }, + { 0x00000010, 0xc0211220, 0x000 }, + { 0x0000000f, 0x00261224, 0x000 }, + { 0x00000000, 0x00201411, 0x000 }, + { 0x00000000, 0x00601811, 0x2bb }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0x002f022b, 0x000 }, + { 0x00000000, 0x0ce00000, 0x1f8 }, + { 0x00000010, 0x00221628, 0x000 }, + { 0xffff0000, 0x00281625, 0x000 }, + { 0x0000ffff, 0x00281a29, 0x000 }, + { 0x00000000, 0x002948c5, 0x000 }, + { 0x00000000, 0x0020480a, 0x000 }, + { 0x00000000, 0x00202c11, 0x000 }, + { 0x00000010, 0x00221623, 0x000 }, + { 0xffff0000, 0x00281625, 0x000 }, + { 0x0000ffff, 0x00281a24, 0x000 }, + { 0x00000000, 0x002948c5, 0x000 }, + { 0x00000000, 0x00731503, 0x205 }, + { 0x00000000, 0x00201805, 0x000 }, + { 0x00000000, 0x00731524, 0x205 }, + { 0x00000000, 0x002d14c5, 0x000 }, + { 0x00000000, 0x003008a2, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00202802, 0x000 }, + { 0x00000000, 0x00202003, 0x000 }, + { 0x00000000, 0x00802404, 0x000 }, + { 0x0000000f, 0x00210225, 0x000 }, + { 0x00000000, 0x14c00000, 0x689 }, + { 0x00000000, 0x002b1405, 0x000 }, + { 0x00000001, 0x00901625, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001a, 0x00294a22, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00384a21, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0000ffff, 0x40281220, 0x000 }, + { 0x00000010, 0xc0211a20, 0x000 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x00000010, 0xc0211620, 0x000 }, + { 0x00000000, 0x00741465, 0x2bb }, + { 0x0001a1fd, 0x00604411, 0x2e0 }, + { 0x00000001, 0x00330621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0cc00000, 0x219 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x212 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000000, 0x00600000, 0x642 }, + { 0x00000000, 0x0040040f, 0x213 }, + { 0x00000000, 0x00600000, 0x62e }, + { 0x00000000, 0x00600000, 0x642 }, + { 0x00000210, 0x00600411, 0x315 }, + { 0x00000000, 0x00600000, 0x1a0 }, + { 0x00000000, 0x00600000, 0x19c }, + { 0x00000000, 0x00600000, 0x2bb }, + { 0x00000000, 0x00600000, 0x2a3 }, + { 0x93800000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204808, 0x000 }, + { 0x00000000, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ae00000, 0x232 }, + { 0x00000000, 0x00600000, 0x13a }, + { 0x00000000, 0x00400000, 0x236 }, + { 0x95000000, 0x00204411, 0x000 }, + { 0x00000000, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x236 }, + { 0x00000000, 0xc0404800, 0x233 }, + { 0x92000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x00000016, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0x00600411, 0x2fb }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000000, 0x00600000, 0x62e }, + { 0x0000a00c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000018, 0x40210a20, 0x000 }, + { 0x00000003, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x24c }, + { 0x00000014, 0x0020222d, 0x000 }, + { 0x00080101, 0x00292228, 0x000 }, + { 0x00000014, 0x00203628, 0x000 }, + { 0x0000a30c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x251 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000010, 0x00600411, 0x315 }, + { 0x3f800000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x00000000, 0x00600000, 0x27c }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000001, 0x00211e27, 0x000 }, + { 0x00000000, 0x14e00000, 0x26a }, + { 0x00000012, 0x00201e2d, 0x000 }, + { 0x0000ffff, 0x00281e27, 0x000 }, + { 0x00000000, 0x00341c27, 0x000 }, + { 0x00000000, 0x12c00000, 0x25f }, + { 0x00000000, 0x00201c11, 0x000 }, + { 0x00000000, 0x002f00e5, 0x000 }, + { 0x00000000, 0x08c00000, 0x262 }, + { 0x00000000, 0x00201407, 0x000 }, + { 0x00000012, 0x00201e2d, 0x000 }, + { 0x00000010, 0x00211e27, 0x000 }, + { 0x00000000, 0x00341c47, 0x000 }, + { 0x00000000, 0x12c00000, 0x267 }, + { 0x00000000, 0x00201c11, 0x000 }, + { 0x00000000, 0x002f00e6, 0x000 }, + { 0x00000000, 0x08c00000, 0x26a }, + { 0x00000000, 0x00201807, 0x000 }, + { 0x00000000, 0x00600000, 0x2c1 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x00000000, 0x00342023, 0x000 }, + { 0x00000000, 0x12c00000, 0x272 }, + { 0x00000000, 0x00342044, 0x000 }, + { 0x00000000, 0x12c00000, 0x271 }, + { 0x00000016, 0x00404811, 0x276 }, + { 0x00000018, 0x00404811, 0x276 }, + { 0x00000000, 0x00342044, 0x000 }, + { 0x00000000, 0x12c00000, 0x275 }, + { 0x00000017, 0x00404811, 0x276 }, + { 0x00000019, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0001a1fd, 0x00604411, 0x2e9 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x256 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000010, 0x40210620, 0x000 }, + { 0x0000ffff, 0xc0280a20, 0x000 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x0000ffff, 0xc0281220, 0x000 }, + { 0x00000010, 0x40211620, 0x000 }, + { 0x0000ffff, 0xc0881a20, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00042004, 0x00604411, 0x68a }, + { 0x00000000, 0x00600000, 0x62e }, + { 0x00000000, 0xc0600000, 0x2a3 }, + { 0x00000005, 0x00200a2d, 0x000 }, + { 0x00000008, 0x00220a22, 0x000 }, + { 0x0000002b, 0x00201a2d, 0x000 }, + { 0x0000001c, 0x00201e2d, 0x000 }, + { 0x00007000, 0x00281e27, 0x000 }, + { 0x00000000, 0x00311ce6, 0x000 }, + { 0x0000002a, 0x00201a2d, 0x000 }, + { 0x0000000c, 0x00221a26, 0x000 }, + { 0x00000000, 0x002f00e6, 0x000 }, + { 0x00000000, 0x06e00000, 0x292 }, + { 0x00000000, 0x00201c11, 0x000 }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x0000002b, 0x00203623, 0x000 }, + { 0x00000010, 0x00201811, 0x000 }, + { 0x00000000, 0x00691ce2, 0x12f }, + { 0x93800000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x95000000, 0x00204411, 0x000 }, + { 0x00000000, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x29d }, + { 0x00000001, 0x00333e2f, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x92000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000001c, 0x00403627, 0x000 }, + { 0x0000000c, 0xc0220a20, 0x000 }, + { 0x00000029, 0x00203622, 0x000 }, + { 0x00000028, 0xc0403620, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000009, 0x00204811, 0x000 }, + { 0xa1000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00804811, 0x000 }, + { 0x00000021, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002c1ce3, 0x000 }, + { 0x00000021, 0x00203627, 0x000 }, + { 0x00000022, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002c1ce4, 0x000 }, + { 0x00000022, 0x00203627, 0x000 }, + { 0x00000023, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120a3, 0x000 }, + { 0x00000000, 0x002d1d07, 0x000 }, + { 0x00000023, 0x00203627, 0x000 }, + { 0x00000024, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x00000000, 0x002d1d07, 0x000 }, + { 0x00000024, 0x00803627, 0x000 }, + { 0x00000021, 0x00203623, 0x000 }, + { 0x00000022, 0x00203624, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000023, 0x00203627, 0x000 }, + { 0x00000000, 0x00311cc4, 0x000 }, + { 0x00000024, 0x00803627, 0x000 }, + { 0x0000001a, 0x00203627, 0x000 }, + { 0x0000001b, 0x00203628, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000002, 0x00210227, 0x000 }, + { 0x00000000, 0x14c00000, 0x2dc }, + { 0x00000000, 0x00400000, 0x2d9 }, + { 0x0000001a, 0x00203627, 0x000 }, + { 0x0000001b, 0x00203628, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000002, 0x00210227, 0x000 }, + { 0x00000000, 0x14e00000, 0x2d9 }, + { 0x00000003, 0x00210227, 0x000 }, + { 0x00000000, 0x14e00000, 0x2dc }, + { 0x00000023, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002e00e1, 0x000 }, + { 0x00000000, 0x02c00000, 0x2dc }, + { 0x00000021, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120a1, 0x000 }, + { 0x00000000, 0x002e00e8, 0x000 }, + { 0x00000000, 0x06c00000, 0x2dc }, + { 0x00000024, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002e00e2, 0x000 }, + { 0x00000000, 0x02c00000, 0x2dc }, + { 0x00000022, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120c2, 0x000 }, + { 0x00000000, 0x002e00e8, 0x000 }, + { 0x00000000, 0x06c00000, 0x2dc }, + { 0x00000000, 0x00600000, 0x665 }, + { 0x00000000, 0x00600000, 0x2b5 }, + { 0x00000000, 0x00400000, 0x2de }, + { 0x00000000, 0x00600000, 0x2b5 }, + { 0x00000000, 0x00600000, 0x65c }, + { 0x00000000, 0x00400000, 0x2de }, + { 0x00000000, 0x00600000, 0x2a7 }, + { 0x00000000, 0x00400000, 0x2de }, + { 0x0000001a, 0x00201e2d, 0x000 }, + { 0x0000001b, 0x0080222d, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00894907, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000010, 0x00221e21, 0x000 }, + { 0x00000000, 0x00294847, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000000, 0x00311ca1, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294847, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000010, 0x00221e21, 0x000 }, + { 0x00000000, 0x003120c2, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00894907, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000001, 0x00220a21, 0x000 }, + { 0x00000000, 0x003308a2, 0x000 }, + { 0x00000010, 0x00221e22, 0x000 }, + { 0x00000010, 0x00212222, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000001, 0x00220a21, 0x000 }, + { 0x00000000, 0x003008a2, 0x000 }, + { 0x00000010, 0x00221e22, 0x000 }, + { 0x00000010, 0x00212222, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x003808c5, 0x000 }, + { 0x00000000, 0x00300841, 0x000 }, + { 0x00000001, 0x00220a22, 0x000 }, + { 0x00000000, 0x003308a2, 0x000 }, + { 0x00000010, 0x00221e22, 0x000 }, + { 0x00000010, 0x00212222, 0x000 }, + { 0x00000000, 0x00894907, 0x000 }, + { 0x00000017, 0x0020222d, 0x000 }, + { 0x00000000, 0x14c00000, 0x318 }, + { 0xffffffef, 0x00280621, 0x000 }, + { 0x00000014, 0x0020222d, 0x000 }, + { 0x0000f8e0, 0x00204411, 0x000 }, + { 0x00000000, 0x00294901, 0x000 }, + { 0x00000000, 0x00894901, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00804811, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x97000000, 0xc0204411, 0x000 }, + { 0x00000000, 0xc0204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x97000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x97000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x00002257, 0x00204411, 0x000 }, + { 0x00000003, 0xc0484a20, 0x000 }, + { 0x0000225d, 0x00204411, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000000, 0x00600000, 0x642 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00384a22, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x40204800, 0x000 }, + { 0x00000001, 0x40304a20, 0x000 }, + { 0x00000002, 0xc0304a20, 0x000 }, + { 0x00000001, 0x00530a22, 0x34b }, + { 0x0000003f, 0xc0280a20, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000018, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x68a }, + { 0x00000011, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x354 }, + { 0x00000014, 0x002f0222, 0x000 }, + { 0x00000000, 0x0cc00000, 0x364 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00604802, 0x36e }, + { 0x00002100, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000004, 0x002f0222, 0x000 }, + { 0x00000000, 0x0cc00000, 0x36a }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x35f }, + { 0x00000028, 0x002f0222, 0x000 }, + { 0x00000000, 0x0cc00000, 0x5bd }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x35f }, + { 0x0000002c, 0x00203626, 0x000 }, + { 0x00000049, 0x00201811, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x00000001, 0x00331a26, 0x000 }, + { 0x00000000, 0x002f0226, 0x000 }, + { 0x00000000, 0x0cc00000, 0x370 }, + { 0x0000002c, 0x00801a2d, 0x000 }, + { 0x0000003f, 0xc0280a20, 0x000 }, + { 0x00000015, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x386 }, + { 0x00000006, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x3b1 }, + { 0x00000016, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x3b5 }, + { 0x00000020, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x39c }, + { 0x0000000f, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x3a8 }, + { 0x00000010, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x3a8 }, + { 0x0000001e, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x390 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x000 }, + { 0x08000000, 0x00290a22, 0x000 }, + { 0x00000003, 0x40210e20, 0x000 }, + { 0x0000000c, 0xc0211220, 0x000 }, + { 0x00080000, 0x00281224, 0x000 }, + { 0x00000014, 0xc0221620, 0x000 }, + { 0x00000000, 0x002914a4, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x002948a2, 0x000 }, + { 0x0000a1fe, 0x00204411, 0x000 }, + { 0x00000000, 0x00404803, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000016, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x68a }, + { 0x00000015, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x392 }, + { 0x0000210e, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000017, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x68a }, + { 0x00000003, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x39e }, + { 0x00002108, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x80000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000010, 0x00204811, 0x000 }, + { 0x00000000, 0x00200010, 0x000 }, + { 0x00000000, 0x14c00000, 0x3ae }, + { 0x00000000, 0x00400000, 0x000 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000006, 0x00404811, 0x000 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000016, 0x00604811, 0x36e }, + { 0x00000000, 0x00400000, 0x000 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x0000001d, 0x00210223, 0x000 }, + { 0x00000000, 0x14e00000, 0x3ce }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000018, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x68a }, + { 0x00000011, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x3c0 }, + { 0x00002100, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0xbabecafe, 0x00204811, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000004, 0x00404811, 0x000 }, + { 0x00002170, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000a, 0x00204811, 0x000 }, + { 0x00000000, 0x00200010, 0x000 }, + { 0x00000000, 0x14c00000, 0x3d3 }, + { 0x8c000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00003fff, 0x40280a20, 0x000 }, + { 0x80000000, 0x40280e20, 0x000 }, + { 0x40000000, 0xc0281220, 0x000 }, + { 0x00040000, 0x00694622, 0x68a }, + { 0x00000000, 0x00201410, 0x000 }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x3e1 }, + { 0x00000000, 0xc0401800, 0x3e4 }, + { 0x00003fff, 0xc0281a20, 0x000 }, + { 0x00040000, 0x00694626, 0x68a }, + { 0x00000000, 0x00201810, 0x000 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x3e7 }, + { 0x00000000, 0xc0401c00, 0x3ea }, + { 0x00003fff, 0xc0281e20, 0x000 }, + { 0x00040000, 0x00694627, 0x68a }, + { 0x00000000, 0x00201c10, 0x000 }, + { 0x00000000, 0x00204402, 0x000 }, + { 0x00000000, 0x002820c5, 0x000 }, + { 0x00000000, 0x004948e8, 0x000 }, + { 0xa5800000, 0x00200811, 0x000 }, + { 0x00002000, 0x00200c11, 0x000 }, + { 0x83000000, 0x00604411, 0x412 }, + { 0x00000000, 0x00204402, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x40204800, 0x000 }, + { 0x0000001f, 0xc0210220, 0x000 }, + { 0x00000000, 0x14c00000, 0x3f7 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0000ffff, 0xc0481220, 0x3ff }, + { 0xa7800000, 0x00200811, 0x000 }, + { 0x0000a000, 0x00200c11, 0x000 }, + { 0x83000000, 0x00604411, 0x412 }, + { 0x00000000, 0x00204402, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000ffff, 0xc0281220, 0x000 }, + { 0x83000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00304883, 0x000 }, + { 0x84000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x1d000000, 0x000 }, + { 0x83000000, 0x00604411, 0x412 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0xa9800000, 0x00200811, 0x000 }, + { 0x0000c000, 0x00400c11, 0x3fa }, + { 0xab800000, 0x00200811, 0x000 }, + { 0x0000f8e0, 0x00400c11, 0x3fa }, + { 0xad800000, 0x00200811, 0x000 }, + { 0x0000f880, 0x00400c11, 0x3fa }, + { 0xb3800000, 0x00200811, 0x000 }, + { 0x0000f3fc, 0x00400c11, 0x3fa }, + { 0xaf800000, 0x00200811, 0x000 }, + { 0x0000e000, 0x00400c11, 0x3fa }, + { 0xb1800000, 0x00200811, 0x000 }, + { 0x0000f000, 0x00400c11, 0x3fa }, + { 0x83000000, 0x00204411, 0x000 }, + { 0x00002148, 0x00204811, 0x000 }, + { 0x84000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x1d000000, 0x000 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x01182000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0218a000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0318c000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0418f8e0, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0518f880, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0618e000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0718f000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0818f3fc, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x00000030, 0x00200a2d, 0x000 }, + { 0x00000000, 0xc0290c40, 0x000 }, + { 0x00000030, 0x00203623, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x86000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00404801, 0x000 }, + { 0x85000000, 0xc0204411, 0x000 }, + { 0x00000000, 0x00404801, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x0004217f, 0x00604411, 0x68a }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x00000000, 0x00404c02, 0x448 }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x00000000, 0xc0201000, 0x000 }, + { 0x00000000, 0xc0201400, 0x000 }, + { 0x00000000, 0xc0201800, 0x000 }, + { 0x00000000, 0xc0201c00, 0x000 }, + { 0x00007f00, 0x00280a21, 0x000 }, + { 0x00004500, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x456 }, + { 0x00000000, 0xc0202000, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x00000010, 0x00280a23, 0x000 }, + { 0x00000010, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x45e }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00040000, 0x00694624, 0x68a }, + { 0x00000000, 0x00400000, 0x463 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000216d, 0x00204411, 0x000 }, + { 0x00000000, 0x00204804, 0x000 }, + { 0x00000000, 0x00604805, 0x68f }, + { 0x00000000, 0x002824f0, 0x000 }, + { 0x00000007, 0x00280a23, 0x000 }, + { 0x00000001, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x46a }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x04e00000, 0x483 }, + { 0x00000000, 0x00400000, 0x490 }, + { 0x00000002, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x46f }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x02e00000, 0x483 }, + { 0x00000000, 0x00400000, 0x490 }, + { 0x00000003, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x474 }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x0ce00000, 0x483 }, + { 0x00000000, 0x00400000, 0x490 }, + { 0x00000004, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x479 }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x0ae00000, 0x483 }, + { 0x00000000, 0x00400000, 0x490 }, + { 0x00000005, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x47e }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x06e00000, 0x483 }, + { 0x00000000, 0x00400000, 0x490 }, + { 0x00000006, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x483 }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x08e00000, 0x483 }, + { 0x00000000, 0x00400000, 0x490 }, + { 0x00007f00, 0x00280a21, 0x000 }, + { 0x00004500, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x000 }, + { 0x00000008, 0x00210a23, 0x000 }, + { 0x00000000, 0x14c00000, 0x48d }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x00000000, 0xc0204400, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00007f00, 0x00280a21, 0x000 }, + { 0x00004500, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x496 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0400000, 0x000 }, + { 0x00000000, 0x00404c08, 0x456 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x00000011, 0x40211220, 0x000 }, + { 0x00000012, 0x40211620, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00210225, 0x000 }, + { 0x00000000, 0x14e00000, 0x4a0 }, + { 0x00040000, 0xc0494a20, 0x4a1 }, + { 0xfffbffff, 0xc0284a20, 0x000 }, + { 0x00000000, 0x00210223, 0x000 }, + { 0x00000000, 0x14e00000, 0x4ad }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x00210224, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000c, 0x00204811, 0x000 }, + { 0x00000000, 0x00200010, 0x000 }, + { 0x00000000, 0x14c00000, 0x4a9 }, + { 0xa0000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000004, 0x00204811, 0x000 }, + { 0x0000216b, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204810, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000005, 0x00204811, 0x000 }, + { 0x0000216c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204810, 0x000 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00400000, 0x4a7 }, + { 0x00000000, 0xc0210a20, 0x000 }, + { 0x00000000, 0x14c00000, 0x4c0 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000216d, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0604800, 0x68f }, + { 0x00000000, 0x00400000, 0x4c4 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00040000, 0xc0294620, 0x000 }, + { 0x00000000, 0xc0600000, 0x68a }, + { 0x00000001, 0x00210222, 0x000 }, + { 0x00000000, 0x14c00000, 0x4cb }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x00000000, 0xc0204400, 0x000 }, + { 0x00000000, 0xc0404810, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x0000000e, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x68a }, + { 0x00000000, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x4cd }, + { 0x00002180, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000003, 0x00333e2f, 0x000 }, + { 0x00000001, 0x00210221, 0x000 }, + { 0x00000000, 0x14e00000, 0x4fd }, + { 0x0000002c, 0x00200a2d, 0x000 }, + { 0x00040000, 0x18e00c11, 0x4ec }, + { 0x00000001, 0x00333e2f, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xd8c04800, 0x4e0 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000002d, 0x0020122d, 0x000 }, + { 0x00000000, 0x00290c83, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000011, 0x00210224, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x00000000, 0x00400000, 0x4a7 }, + { 0x0000002c, 0xc0203620, 0x000 }, + { 0x0000002d, 0xc0403620, 0x000 }, + { 0x0000000f, 0x00210221, 0x000 }, + { 0x00000000, 0x14c00000, 0x502 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0xd9000000, 0x000 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0xb5000000, 0x00204411, 0x000 }, + { 0x00002000, 0x00204811, 0x000 }, + { 0xb6000000, 0x00204411, 0x000 }, + { 0x0000a000, 0x00204811, 0x000 }, + { 0xb7000000, 0x00204411, 0x000 }, + { 0x0000c000, 0x00204811, 0x000 }, + { 0xb8000000, 0x00204411, 0x000 }, + { 0x0000f8e0, 0x00204811, 0x000 }, + { 0xb9000000, 0x00204411, 0x000 }, + { 0x0000f880, 0x00204811, 0x000 }, + { 0xba000000, 0x00204411, 0x000 }, + { 0x0000e000, 0x00204811, 0x000 }, + { 0xbb000000, 0x00204411, 0x000 }, + { 0x0000f000, 0x00204811, 0x000 }, + { 0xbc000000, 0x00204411, 0x000 }, + { 0x0000f3fc, 0x00204811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000002, 0x00204811, 0x000 }, + { 0x000000ff, 0x00280e30, 0x000 }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x516 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000000, 0x14c00000, 0x52b }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x0000001c, 0x00203623, 0x000 }, + { 0x0000002b, 0x00203623, 0x000 }, + { 0x00000029, 0x00203623, 0x000 }, + { 0x00000028, 0x00203623, 0x000 }, + { 0x00000017, 0x00203623, 0x000 }, + { 0x00000025, 0x00203623, 0x000 }, + { 0x00000026, 0x00203623, 0x000 }, + { 0x00000015, 0x00203623, 0x000 }, + { 0x00000016, 0x00203623, 0x000 }, + { 0xffffe000, 0x00200c11, 0x000 }, + { 0x00000021, 0x00203623, 0x000 }, + { 0x00000022, 0x00203623, 0x000 }, + { 0x00001fff, 0x00200c11, 0x000 }, + { 0x00000023, 0x00203623, 0x000 }, + { 0x00000024, 0x00203623, 0x000 }, + { 0xf1ffffff, 0x00283a2e, 0x000 }, + { 0x0000001a, 0xc0220e20, 0x000 }, + { 0x00000000, 0x0029386e, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x0000002a, 0x40203620, 0x000 }, + { 0x87000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1f4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x00000030, 0x00203623, 0x000 }, + { 0x9d000000, 0x00204411, 0x000 }, + { 0x0000001f, 0x40214a20, 0x000 }, + { 0x96000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x00000000, 0xc0201000, 0x000 }, + { 0x0000001f, 0x00211624, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x0000001d, 0x00203623, 0x000 }, + { 0x00000003, 0x00281e23, 0x000 }, + { 0x00000008, 0x00222223, 0x000 }, + { 0xfffff000, 0x00282228, 0x000 }, + { 0x00000000, 0x002920e8, 0x000 }, + { 0x0000001f, 0x00203628, 0x000 }, + { 0x00000018, 0x00211e23, 0x000 }, + { 0x00000020, 0x00203627, 0x000 }, + { 0x00000002, 0x00221624, 0x000 }, + { 0x00000000, 0x003014a8, 0x000 }, + { 0x0000001e, 0x00203625, 0x000 }, + { 0x00000003, 0x00211a24, 0x000 }, + { 0x10000000, 0x00281a26, 0x000 }, + { 0xefffffff, 0x00283a2e, 0x000 }, + { 0x00000000, 0x004938ce, 0x678 }, + { 0x00000001, 0x40280a20, 0x000 }, + { 0x00000006, 0x40280e20, 0x000 }, + { 0x00000300, 0xc0281220, 0x000 }, + { 0x00000008, 0x00211224, 0x000 }, + { 0x00000000, 0xc0201620, 0x000 }, + { 0x00000000, 0xc0201a20, 0x000 }, + { 0x00000000, 0x00210222, 0x000 }, + { 0x00000000, 0x14c00000, 0x563 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00002258, 0x00300a24, 0x000 }, + { 0x00040000, 0x00694622, 0x68a }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204805, 0x000 }, + { 0x00020000, 0x00294a26, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x56b }, + { 0x00000000, 0xc0201c10, 0x000 }, + { 0x00000000, 0xc0400000, 0x579 }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x56b }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00002258, 0x00300a24, 0x000 }, + { 0x00040000, 0x00694622, 0x68a }, + { 0x00000000, 0xc0201c10, 0x000 }, + { 0x00000000, 0xc0400000, 0x579 }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x56f }, + { 0x00000000, 0xc0201c00, 0x000 }, + { 0x00000000, 0xc0400000, 0x579 }, + { 0x00000004, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x577 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000216d, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0604800, 0x68f }, + { 0x00000000, 0x00401c10, 0x579 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0400000, 0x000 }, + { 0x00000000, 0x0ee00000, 0x57b }, + { 0x00000000, 0x00600000, 0x5c6 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x58c }, + { 0x0000a2b7, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a2b6, 0x00604411, 0x68a }, + { 0x0000001a, 0x00212230, 0x000 }, + { 0x00000006, 0x00222630, 0x000 }, + { 0x00042004, 0x00604411, 0x68a }, + { 0x0000a2c4, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x58a }, + { 0x0000a2d1, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d1, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x00000001, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x59d }, + { 0x0000a2bb, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a2ba, 0x00604411, 0x68a }, + { 0x0000001a, 0x00212230, 0x000 }, + { 0x00000006, 0x00222630, 0x000 }, + { 0x00042004, 0x00604411, 0x68a }, + { 0x0000a2c5, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x59b }, + { 0x0000a2d2, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d2, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x00000002, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x5ae }, + { 0x0000a2bf, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a2be, 0x00604411, 0x68a }, + { 0x0000001a, 0x00212230, 0x000 }, + { 0x00000006, 0x00222630, 0x000 }, + { 0x00042004, 0x00604411, 0x68a }, + { 0x0000a2c6, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x5ac }, + { 0x0000a2d3, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d3, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x0000a2c3, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a2c2, 0x00604411, 0x68a }, + { 0x0000001a, 0x00212230, 0x000 }, + { 0x00000006, 0x00222630, 0x000 }, + { 0x00042004, 0x00604411, 0x68a }, + { 0x0000a2c7, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x5bb }, + { 0x0000a2d4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d4, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x85000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204801, 0x000 }, + { 0x0000304a, 0x00204411, 0x000 }, + { 0x01000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00400000, 0x5c1 }, + { 0xa4000000, 0xc0204411, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000000, 0xc0600000, 0x5c6 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x0000002c, 0x00203621, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x00000000, 0x002f0230, 0x000 }, + { 0x00000000, 0x0cc00000, 0x5cd }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000030, 0x00403621, 0x5e0 }, + { 0x00000030, 0x0020062d, 0x000 }, + { 0x00007e00, 0x00280621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x5e0 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a092, 0x00604411, 0x68a }, + { 0x00000031, 0x00203630, 0x000 }, + { 0x0004a093, 0x00604411, 0x68a }, + { 0x00000032, 0x00203630, 0x000 }, + { 0x0004a2b6, 0x00604411, 0x68a }, + { 0x00000033, 0x00203630, 0x000 }, + { 0x0004a2ba, 0x00604411, 0x68a }, + { 0x00000034, 0x00203630, 0x000 }, + { 0x0004a2be, 0x00604411, 0x68a }, + { 0x00000035, 0x00203630, 0x000 }, + { 0x0004a2c2, 0x00604411, 0x68a }, + { 0x00000036, 0x00203630, 0x000 }, + { 0x00042004, 0x00604411, 0x68a }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x00000005, 0x00204811, 0x000 }, + { 0x0000a1f4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x88000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x00000001, 0x002f0230, 0x000 }, + { 0x00000000, 0x0ce00000, 0x629 }, + { 0x00000030, 0x0020062d, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x629 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00007e00, 0x00280621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x602 }, + { 0x0000a092, 0x00204411, 0x000 }, + { 0x00000031, 0x00204a2d, 0x000 }, + { 0x0000a093, 0x00204411, 0x000 }, + { 0x00000032, 0x00204a2d, 0x000 }, + { 0x0000a2b6, 0x00204411, 0x000 }, + { 0x00000033, 0x00204a2d, 0x000 }, + { 0x0000a2ba, 0x00204411, 0x000 }, + { 0x00000034, 0x00204a2d, 0x000 }, + { 0x0000a2be, 0x00204411, 0x000 }, + { 0x00000035, 0x00204a2d, 0x000 }, + { 0x0000a2c2, 0x00204411, 0x000 }, + { 0x00000036, 0x00204a2d, 0x000 }, + { 0x00000030, 0x0020062d, 0x000 }, + { 0x000001ff, 0x00280621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x628 }, + { 0x00000000, 0x00210221, 0x000 }, + { 0x00000000, 0x14c00000, 0x60b }, + { 0x0004a003, 0x00604411, 0x68a }, + { 0x0000a003, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x00000001, 0x00210621, 0x000 }, + { 0x00000000, 0x14c00000, 0x610 }, + { 0x0004a010, 0x00604411, 0x68a }, + { 0x0000a010, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x00000001, 0x00210621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x628 }, + { 0x0004a011, 0x00604411, 0x68a }, + { 0x0000a011, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a012, 0x00604411, 0x68a }, + { 0x0000a012, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a013, 0x00604411, 0x68a }, + { 0x0000a013, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a014, 0x00604411, 0x68a }, + { 0x0000a014, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a015, 0x00604411, 0x68a }, + { 0x0000a015, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a016, 0x00604411, 0x68a }, + { 0x0000a016, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a017, 0x00604411, 0x68a }, + { 0x0000a017, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x00042004, 0x00604411, 0x68a }, + { 0x0000002c, 0x0080062d, 0x000 }, + { 0xff000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000002, 0x00804811, 0x000 }, + { 0x00000000, 0x0ee00000, 0x63a }, + { 0x00000030, 0x0020062d, 0x000 }, + { 0x00000002, 0x00280621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x638 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00042004, 0x00604411, 0x68a }, + { 0x00001000, 0x00200811, 0x000 }, + { 0x0000002b, 0x00203622, 0x000 }, + { 0x00000000, 0x00600000, 0x63e }, + { 0x00000000, 0x00600000, 0x5c6 }, + { 0x98000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00804811, 0x000 }, + { 0x00000000, 0xc0600000, 0x63e }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000022, 0x00204811, 0x000 }, + { 0x89000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00404811, 0x62a }, + { 0x97000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00404811, 0x62a }, + { 0x00000000, 0x00600000, 0x659 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0xc0204411, 0x000 }, + { 0x00000016, 0x00604811, 0x36e }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00010000, 0x00204811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x09800000, 0x00204811, 0x000 }, + { 0xffffffff, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x0004217f, 0x00604411, 0x68a }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x00000004, 0x00404c11, 0x653 }, + { 0x00000000, 0x00400000, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000004, 0x00291e27, 0x000 }, + { 0x00000017, 0x00803627, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0xfffffffb, 0x00281e27, 0x000 }, + { 0x00000017, 0x00803627, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000008, 0x00291e27, 0x000 }, + { 0x00000017, 0x00803627, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0xfffffff7, 0x00281e27, 0x000 }, + { 0x00000017, 0x00803627, 0x000 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000016, 0x00604811, 0x36e }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00010000, 0x00204811, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x01800000, 0x00204811, 0x000 }, + { 0xffffffff, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004217f, 0x00604411, 0x68a }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x689 }, + { 0x00000010, 0x00404c11, 0x66f }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x38c00000, 0x000 }, + { 0x0000001d, 0x00200a2d, 0x000 }, + { 0x0000001e, 0x00200e2d, 0x000 }, + { 0x0000001f, 0x0020122d, 0x000 }, + { 0x00000020, 0x0020162d, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204804, 0x000 }, + { 0x00000000, 0x00204805, 0x000 }, + { 0x00000000, 0x00204801, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000004, 0x00301224, 0x000 }, + { 0x00000000, 0x002f0064, 0x000 }, + { 0x00000000, 0x0cc00000, 0x688 }, + { 0x00000003, 0x00281a22, 0x000 }, + { 0x00000008, 0x00221222, 0x000 }, + { 0xfffff000, 0x00281224, 0x000 }, + { 0x00000000, 0x002910c4, 0x000 }, + { 0x0000001f, 0x00403624, 0x000 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x1ac00000, 0x68a }, + { 0x9f000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000000, 0x1ae00000, 0x68d }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x1ac00000, 0x68f }, + { 0x9e000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000000, 0x1ae00000, 0x692 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00001000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001b, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0001a1fd, 0xc0204411, 0x000 }, + { 0x00000021, 0x00201e2d, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000024, 0x0020222d, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000022, 0x0020222d, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000023, 0x00201e2d, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00404811, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x014204ff, 0x05bd0250, 0x000 }, + { 0x01c30168, 0x043f05bd, 0x000 }, + { 0x02250209, 0x02500151, 0x000 }, + { 0x02230245, 0x02a00241, 0x000 }, + { 0x03d705bd, 0x05bd05bd, 0x000 }, + { 0x06460647, 0x031f05bd, 0x000 }, + { 0x05bd05c2, 0x03200340, 0x000 }, + { 0x032a0282, 0x03420334, 0x000 }, + { 0x05bd05bd, 0x05bd05bd, 0x000 }, + { 0x05bd054e, 0x05bd05bd, 0x000 }, + { 0x03ba05bd, 0x04b80344, 0x000 }, + { 0x0497044d, 0x043d05bd, 0x000 }, + { 0x04cd05bd, 0x044104da, 0x000 }, + { 0x044d0504, 0x03510375, 0x000 }, + { 0x05bd05bd, 0x05bd05bd, 0x000 }, + { 0x05bd05bd, 0x05bd05bd, 0x000 }, + { 0x05bd05bd, 0x063c05c4, 0x000 }, + { 0x05bd05bd, 0x000705bd, 0x000 }, + { 0x05bd05bd, 0x05bd05bd, 0x000 }, + { 0x05bd05bd, 0x05bd05bd, 0x000 }, + { 0x03f803ed, 0x04080406, 0x000 }, + { 0x040e040a, 0x040c0410, 0x000 }, + { 0x041c0418, 0x04240420, 0x000 }, + { 0x042c0428, 0x04340430, 0x000 }, + { 0x05bd05bd, 0x043805bd, 0x000 }, + { 0x05bd05bd, 0x05bd05bd, 0x000 }, + { 0x05bd05bd, 0x05bd05bd, 0x000 }, + { 0x00020676, 0x06940006, 0x000 }, +}; + +static const u32 RV635_pfp_microcode[] = { +0xca0400, +0xa00000, +0x7e828b, +0x7c038b, +0x8001b8, +0x7c038b, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xc41838, +0xca2400, +0xca2800, +0x9581a8, +0xc41c3a, +0xc3c000, +0xca0800, +0xca0c00, +0x7c744b, +0xc20005, +0x99c000, +0xc41c3a, +0x7c744c, +0xc0fff0, +0x042c04, +0x309002, +0x7d2500, +0x351402, +0x7d350b, +0x255403, +0x7cd580, +0x259c03, +0x95c004, +0xd5001b, +0x7eddc1, +0x7d9d80, +0xd6801b, +0xd5801b, +0xd4401e, +0xd5401e, +0xd6401e, +0xd6801e, +0xd4801e, +0xd4c01e, +0x9783d3, +0xd5c01e, +0xca0800, +0x80001a, +0xca0c00, +0xe4011e, +0xd4001e, +0x80000c, +0xc41838, +0xe4013e, +0xd4001e, +0x80000c, +0xc41838, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xe4011e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xe4013e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xca1800, +0xd4401e, +0xd5801e, +0x800053, +0xd40075, +0xd4401e, +0xca0800, +0xca0c00, +0xca1000, +0xd48019, +0xd4c018, +0xd50017, +0xd4801e, +0xd4c01e, +0xd5001e, +0xe2001e, +0xca0400, +0xa00000, +0x7e828b, +0xca0800, +0xd48060, +0xd4401e, +0x800000, +0xd4801e, +0xca0800, +0xd48061, +0xd4401e, +0x800000, +0xd4801e, +0xca0800, +0xca0c00, +0xd4401e, +0xd48016, +0xd4c016, +0xd4801e, +0x8001b8, +0xd4c01e, +0xc60843, +0xca0c00, +0xca1000, +0x948004, +0xca1400, +0xe420f3, +0xd42013, +0xd56065, +0xd4e01c, +0xd5201c, +0xd5601c, +0x800000, +0x062001, +0xc60843, +0xca0c00, +0xca1000, +0x9483f7, +0xca1400, +0xe420f3, +0x800079, +0xd42013, +0xc60843, +0xca0c00, +0xca1000, +0x9883ef, +0xca1400, +0xd40064, +0x80008d, +0x000000, +0xc41432, +0xc61843, +0xc4082f, +0x954005, +0xc40c30, +0xd4401e, +0x800000, +0xee001e, +0x9583f5, +0xc41031, +0xd44033, +0xd52065, +0xd4a01c, +0xd4e01c, +0xd5201c, +0xe4015e, +0xd4001e, +0x800000, +0x062001, +0xca1800, +0x0a2001, +0xd60076, +0xc40836, +0x988007, +0xc61045, +0x950110, +0xd4001f, +0xd46062, +0x800000, +0xd42062, +0xcc3835, +0xcc1433, +0x8401bb, +0xd40072, +0xd5401e, +0x800000, +0xee001e, +0xe2001a, +0x8401bb, +0xe2001a, +0xcc104b, +0xcc0447, +0x2c9401, +0x7d098b, +0x984005, +0x7d15cb, +0xd4001a, +0x8001b8, +0xd4006d, +0x344401, +0xcc0c48, +0x98403a, +0xcc2c4a, +0x958004, +0xcc0449, +0x8001b8, +0xd4001a, +0xd4c01a, +0x282801, +0x8400f0, +0xcc1003, +0x98801b, +0x04380c, +0x8400f0, +0xcc1003, +0x988017, +0x043808, +0x8400f0, +0xcc1003, +0x988013, +0x043804, +0x8400f0, +0xcc1003, +0x988014, +0xcc104c, +0x9a8009, +0xcc144d, +0x9840dc, +0xd4006d, +0xcc1848, +0xd5001a, +0xd5401a, +0x8000c9, +0xd5801a, +0x96c0d5, +0xd4006d, +0x8001b8, +0xd4006e, +0x9ac003, +0xd4006d, +0xd4006e, +0x800000, +0xec007f, +0x9ac0cc, +0xd4006d, +0x8001b8, +0xd4006e, +0xcc1403, +0xcc1803, +0xcc1c03, +0x7d9103, +0x7dd583, +0x7d190c, +0x35cc1f, +0x35701f, +0x7cf0cb, +0x7cd08b, +0x880000, +0x7e8e8b, +0x95c004, +0xd4006e, +0x8001b8, +0xd4001a, +0xd4c01a, +0xcc0803, +0xcc0c03, +0xcc1003, +0xcc1403, +0xcc1803, +0xcc1c03, +0xcc2403, +0xcc2803, +0x35c41f, +0x36b01f, +0x7c704b, +0x34f01f, +0x7c704b, +0x35701f, +0x7c704b, +0x7d8881, +0x7dccc1, +0x7e5101, +0x7e9541, +0x7c9082, +0x7cd4c2, +0x7c848b, +0x9ac003, +0x7c8c8b, +0x2c8801, +0x98809e, +0xd4006d, +0x98409c, +0xd4006e, +0xcc084c, +0xcc0c4d, +0xcc1048, +0xd4801a, +0xd4c01a, +0x800101, +0xd5001a, +0xcc0832, +0xd40032, +0x9482d9, +0xca0c00, +0xd4401e, +0x800000, +0xd4001e, +0xe4011e, +0xd4001e, +0xca0800, +0xca0c00, +0xca1000, +0xd4401e, +0xca1400, +0xd4801e, +0xd4c01e, +0xd5001e, +0xd5401e, +0xd54034, +0x800000, +0xee001e, +0x280404, +0xe2001a, +0xe2001a, +0xd4401a, +0xca3800, +0xcc0803, +0xcc0c03, +0xcc0c03, +0xcc0c03, +0x9882bd, +0x000000, +0x8401bb, +0xd7a06f, +0x800000, +0xee001f, +0xca0400, +0xc2ff00, +0xcc0834, +0xc13fff, +0x7c74cb, +0x7cc90b, +0x7d010f, +0x9902b0, +0x7c738b, +0x8401bb, +0xd7a06f, +0x800000, +0xee001f, +0xca0800, +0x281900, +0x7d898b, +0x958014, +0x281404, +0xca0c00, +0xca1000, +0xca1c00, +0xca2400, +0xe2001f, +0xd4c01a, +0xd5001a, +0xd5401a, +0xcc1803, +0xcc2c03, +0xcc2c03, +0xcc2c03, +0x7da58b, +0x7d9c47, +0x984297, +0x000000, +0x800161, +0xd4c01a, +0xd4401e, +0xd4801e, +0x800000, +0xee001e, +0xe4011e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xe4013e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xca0800, +0x248c06, +0x0ccc06, +0x98c006, +0xcc104e, +0x990004, +0xd40073, +0xe4011e, +0xd4001e, +0xd4401e, +0xd4801e, +0x800000, +0xee001e, +0xca0800, +0xca0c00, +0x34d018, +0x251001, +0x950021, +0xc17fff, +0xca1000, +0xca1400, +0xca1800, +0xd4801d, +0xd4c01d, +0x7db18b, +0xc14202, +0xc2c001, +0xd5801d, +0x34dc0e, +0x7d5d4c, +0x7f734c, +0xd7401e, +0xd5001e, +0xd5401e, +0xc14200, +0xc2c000, +0x099c01, +0x31dc10, +0x7f5f4c, +0x7f734c, +0x042802, +0x7d8380, +0xd5a86f, +0xd58066, +0xd7401e, +0xec005e, +0xc82402, +0xc82402, +0x8001b8, +0xd60076, +0xd4401e, +0xd4801e, +0xd4c01e, +0x800000, +0xee001e, +0x800000, +0xee001f, +0xd4001f, +0x800000, +0xd4001f, +0xd4001f, +0x880000, +0xd4001f, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x010171, +0x020178, +0x03008f, +0x04007f, +0x050003, +0x06003f, +0x070032, +0x08012c, +0x090046, +0x0a0036, +0x1001b6, +0x1700a2, +0x22013a, +0x230149, +0x2000b4, +0x240125, +0x27004d, +0x28006a, +0x2a0060, +0x2b0052, +0x2f0065, +0x320087, +0x34017f, +0x3c0156, +0x3f0072, +0x41018c, +0x44012e, +0x550173, +0x56017a, +0x60000b, +0x610034, +0x620038, +0x630038, +0x640038, +0x650038, +0x660038, +0x670038, +0x68003a, +0x690041, +0x6a0048, +0x6b0048, +0x6c0048, +0x6d0048, +0x6e0048, +0x6f0048, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +}; + +static const u32 RV670_cp_microcode[][3] = { + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0000ffff, 0x00284621, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x00000000, 0x00e00000, 0x000 }, + { 0x00010000, 0xc0294620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00042004, 0x00604411, 0x67c }, + { 0x00000000, 0x00600000, 0x624 }, + { 0x00000000, 0x00600000, 0x638 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000f00, 0x00281622, 0x000 }, + { 0x00000008, 0x00211625, 0x000 }, + { 0x00000018, 0x00203625, 0x000 }, + { 0x8d000000, 0x00204411, 0x000 }, + { 0x00000004, 0x002f0225, 0x000 }, + { 0x00000000, 0x0ce00000, 0x018 }, + { 0x00412000, 0x00404811, 0x019 }, + { 0x00422000, 0x00204811, 0x000 }, + { 0x8e000000, 0x00204411, 0x000 }, + { 0x00000028, 0x00204a2d, 0x000 }, + { 0x90000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204805, 0x000 }, + { 0x0000000c, 0x00211622, 0x000 }, + { 0x00000003, 0x00281625, 0x000 }, + { 0x00000019, 0x00211a22, 0x000 }, + { 0x00000004, 0x00281a26, 0x000 }, + { 0x00000000, 0x002914c5, 0x000 }, + { 0x00000019, 0x00203625, 0x000 }, + { 0x00000000, 0x003a1402, 0x000 }, + { 0x00000016, 0x00211625, 0x000 }, + { 0x00000003, 0x00281625, 0x000 }, + { 0x00000017, 0x00200e2d, 0x000 }, + { 0xfffffffc, 0x00280e23, 0x000 }, + { 0x00000000, 0x002914a3, 0x000 }, + { 0x00000017, 0x00203625, 0x000 }, + { 0x00008000, 0x00280e22, 0x000 }, + { 0x00000007, 0x00220e23, 0x000 }, + { 0x00000000, 0x0029386e, 0x000 }, + { 0x20000000, 0x00280e22, 0x000 }, + { 0x00000006, 0x00210e23, 0x000 }, + { 0x00000000, 0x0029386e, 0x000 }, + { 0x00000000, 0x00220222, 0x000 }, + { 0x00000000, 0x14e00000, 0x038 }, + { 0x00000000, 0x2ee00000, 0x035 }, + { 0x00000000, 0x2ce00000, 0x037 }, + { 0x00000000, 0x00400e2d, 0x039 }, + { 0x00000008, 0x00200e2d, 0x000 }, + { 0x00000009, 0x0040122d, 0x046 }, + { 0x00000001, 0x00400e2d, 0x039 }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x003ffffc, 0x00281223, 0x000 }, + { 0x00000002, 0x00221224, 0x000 }, + { 0x0000001f, 0x00211e23, 0x000 }, + { 0x00000000, 0x14e00000, 0x03e }, + { 0x00000008, 0x00401c11, 0x041 }, + { 0x0000000d, 0x00201e2d, 0x000 }, + { 0x0000000f, 0x00281e27, 0x000 }, + { 0x00000003, 0x00221e27, 0x000 }, + { 0x7fc00000, 0x00281a23, 0x000 }, + { 0x00000014, 0x00211a26, 0x000 }, + { 0x00000001, 0x00331a26, 0x000 }, + { 0x00000008, 0x00221a26, 0x000 }, + { 0x00000000, 0x00290cc7, 0x000 }, + { 0x00000027, 0x00203624, 0x000 }, + { 0x00007f00, 0x00281221, 0x000 }, + { 0x00001400, 0x002f0224, 0x000 }, + { 0x00000000, 0x0ce00000, 0x04b }, + { 0x00000001, 0x00290e23, 0x000 }, + { 0x0000000e, 0x00203623, 0x000 }, + { 0x0000e000, 0x00204411, 0x000 }, + { 0xfff80000, 0x00294a23, 0x000 }, + { 0x00000000, 0x003a2c02, 0x000 }, + { 0x00000002, 0x00220e2b, 0x000 }, + { 0xfc000000, 0x00280e23, 0x000 }, + { 0x0000000f, 0x00203623, 0x000 }, + { 0x00001fff, 0x00294a23, 0x000 }, + { 0x00000027, 0x00204a2d, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000029, 0x00200e2d, 0x000 }, + { 0x060a0200, 0x00294a23, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000001, 0x00210222, 0x000 }, + { 0x00000000, 0x14e00000, 0x061 }, + { 0x00000000, 0x2ee00000, 0x05f }, + { 0x00000000, 0x2ce00000, 0x05e }, + { 0x00000000, 0x00400e2d, 0x062 }, + { 0x00000001, 0x00400e2d, 0x062 }, + { 0x0000000a, 0x00200e2d, 0x000 }, + { 0x0000000b, 0x0040122d, 0x06a }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x003ffffc, 0x00281223, 0x000 }, + { 0x00000002, 0x00221224, 0x000 }, + { 0x7fc00000, 0x00281623, 0x000 }, + { 0x00000014, 0x00211625, 0x000 }, + { 0x00000001, 0x00331625, 0x000 }, + { 0x80000000, 0x00280e23, 0x000 }, + { 0x00000000, 0x00290ca3, 0x000 }, + { 0x3ffffc00, 0x00290e23, 0x000 }, + { 0x0000001f, 0x00211e23, 0x000 }, + { 0x00000000, 0x14e00000, 0x06d }, + { 0x00000100, 0x00401c11, 0x070 }, + { 0x0000000d, 0x00201e2d, 0x000 }, + { 0x000000f0, 0x00281e27, 0x000 }, + { 0x00000004, 0x00221e27, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000d, 0x00204811, 0x000 }, + { 0xfffff0ff, 0x00281a30, 0x000 }, + { 0x0000a028, 0x00204411, 0x000 }, + { 0x00000000, 0x002948e6, 0x000 }, + { 0x0000a018, 0x00204411, 0x000 }, + { 0x3fffffff, 0x00284a23, 0x000 }, + { 0x0000a010, 0x00204411, 0x000 }, + { 0x00000000, 0x00204804, 0x000 }, + { 0x00000030, 0x0020162d, 0x000 }, + { 0x00000002, 0x00291625, 0x000 }, + { 0x00000030, 0x00203625, 0x000 }, + { 0x00000025, 0x0020162d, 0x000 }, + { 0x00000000, 0x002f00a3, 0x000 }, + { 0x00000000, 0x0cc00000, 0x083 }, + { 0x00000026, 0x0020162d, 0x000 }, + { 0x00000000, 0x002f00a4, 0x000 }, + { 0x00000000, 0x0cc00000, 0x084 }, + { 0x00000000, 0x00400000, 0x08a }, + { 0x00000025, 0x00203623, 0x000 }, + { 0x00000026, 0x00203624, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000002, 0x00210227, 0x000 }, + { 0x00000000, 0x14e00000, 0x08a }, + { 0x00000000, 0x00600000, 0x659 }, + { 0x00000000, 0x00600000, 0x64d }, + { 0x00000002, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x08d }, + { 0x00000012, 0xc0403620, 0x093 }, + { 0x00000000, 0x2ee00000, 0x091 }, + { 0x00000000, 0x2ce00000, 0x090 }, + { 0x00000002, 0x00400e2d, 0x092 }, + { 0x00000003, 0x00400e2d, 0x092 }, + { 0x0000000c, 0x00200e2d, 0x000 }, + { 0x00000012, 0x00203623, 0x000 }, + { 0x00000003, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x098 }, + { 0x0000a00c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x0a0 }, + { 0x0000a00c, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x2ee00000, 0x09e }, + { 0x00000000, 0x2ce00000, 0x09d }, + { 0x00000002, 0x00400e2d, 0x09f }, + { 0x00000003, 0x00400e2d, 0x09f }, + { 0x0000000c, 0x00200e2d, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000000, 0x003a0c02, 0x000 }, + { 0x003f0000, 0x00280e23, 0x000 }, + { 0x00000010, 0x00210e23, 0x000 }, + { 0x00000011, 0x00203623, 0x000 }, + { 0x0000001e, 0x0021022b, 0x000 }, + { 0x00000000, 0x14c00000, 0x0a7 }, + { 0x00000016, 0xc0203620, 0x000 }, + { 0x0000001f, 0x0021022b, 0x000 }, + { 0x00000000, 0x14c00000, 0x0aa }, + { 0x00000015, 0xc0203620, 0x000 }, + { 0x00000008, 0x00210e2b, 0x000 }, + { 0x0000007f, 0x00280e23, 0x000 }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0e1 }, + { 0x00000000, 0x27000000, 0x000 }, + { 0x00000000, 0x00600000, 0x2a3 }, + { 0x00000001, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ae00000, 0x0b3 }, + { 0x00000000, 0x00600000, 0x13a }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x0000000c, 0x00221e30, 0x000 }, + { 0x99800000, 0x00204411, 0x000 }, + { 0x00000004, 0x0020122d, 0x000 }, + { 0x00000008, 0x00221224, 0x000 }, + { 0x00000010, 0x00201811, 0x000 }, + { 0x00000000, 0x00291ce4, 0x000 }, + { 0x00000000, 0x00604807, 0x12f }, + { 0x9b000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x9c000000, 0x00204411, 0x000 }, + { 0x00000000, 0x0033146f, 0x000 }, + { 0x00000001, 0x00333e23, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0x00203c05, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000e, 0x00204811, 0x000 }, + { 0x00000000, 0x00201010, 0x000 }, + { 0x0000e007, 0x00204411, 0x000 }, + { 0x0000000f, 0x0021022b, 0x000 }, + { 0x00000000, 0x14c00000, 0x0cb }, + { 0x00f8ff08, 0x00204811, 0x000 }, + { 0x98000000, 0x00404811, 0x0dc }, + { 0x000000f0, 0x00280e22, 0x000 }, + { 0x000000a0, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x0da }, + { 0x00000011, 0x00200e2d, 0x000 }, + { 0x00000001, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0d5 }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0d4 }, + { 0x00003f00, 0x00400c11, 0x0d6 }, + { 0x00001f00, 0x00400c11, 0x0d6 }, + { 0x00000f00, 0x00200c11, 0x000 }, + { 0x00380009, 0x00294a23, 0x000 }, + { 0x3f000000, 0x00280e2b, 0x000 }, + { 0x00000002, 0x00220e23, 0x000 }, + { 0x00000007, 0x00494a23, 0x0dc }, + { 0x00380f09, 0x00204811, 0x000 }, + { 0x68000007, 0x00204811, 0x000 }, + { 0x00000008, 0x00214a27, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00294a24, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000a202, 0x00204411, 0x000 }, + { 0x00ff0000, 0x00280e22, 0x000 }, + { 0x00000080, 0x00294a23, 0x000 }, + { 0x00000027, 0x00200e2d, 0x000 }, + { 0x00000026, 0x0020122d, 0x000 }, + { 0x00000000, 0x002f0083, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0ea }, + { 0x00000000, 0x00600000, 0x653 }, + { 0x00000000, 0x00400000, 0x0eb }, + { 0x00000000, 0x00600000, 0x656 }, + { 0x00000007, 0x0020222d, 0x000 }, + { 0x00000005, 0x00220e22, 0x000 }, + { 0x00100000, 0x00280e23, 0x000 }, + { 0x00000000, 0x00292068, 0x000 }, + { 0x00000000, 0x003a0c02, 0x000 }, + { 0x000000ef, 0x00280e23, 0x000 }, + { 0x00000000, 0x00292068, 0x000 }, + { 0x00000017, 0x00200e2d, 0x000 }, + { 0x00000003, 0x00210223, 0x000 }, + { 0x00000000, 0x14e00000, 0x0f8 }, + { 0x0000000b, 0x00210228, 0x000 }, + { 0x00000000, 0x14c00000, 0x0f8 }, + { 0x00000400, 0x00292228, 0x000 }, + { 0x00000014, 0x00203628, 0x000 }, + { 0x0000001c, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x0fd }, + { 0x0000a30c, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000001e, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x10b }, + { 0x0000a30f, 0x00204411, 0x000 }, + { 0x00000011, 0x00200e2d, 0x000 }, + { 0x00000001, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x104 }, + { 0xffffffff, 0x00404811, 0x10b }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x107 }, + { 0x0000ffff, 0x00404811, 0x10b }, + { 0x00000004, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x10a }, + { 0x000000ff, 0x00404811, 0x10b }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0002c400, 0x00204411, 0x000 }, + { 0x0000001f, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x112 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x00000013, 0x00203623, 0x000 }, + { 0x00000018, 0x40224a20, 0x000 }, + { 0x00000010, 0xc0424a20, 0x114 }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x00000013, 0x00203623, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000000a, 0x00201011, 0x000 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0ce00000, 0x11b }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000001, 0x00531224, 0x117 }, + { 0xffbfffff, 0x00283a2e, 0x000 }, + { 0x0000001b, 0x00210222, 0x000 }, + { 0x00000000, 0x14c00000, 0x12e }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000d, 0x00204811, 0x000 }, + { 0x00000018, 0x00220e30, 0x000 }, + { 0xfc000000, 0x00280e23, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000e, 0x00204811, 0x000 }, + { 0x00000000, 0x00201010, 0x000 }, + { 0x0000e00e, 0x00204411, 0x000 }, + { 0x07f8ff08, 0x00204811, 0x000 }, + { 0x00000000, 0x00294a23, 0x000 }, + { 0x0000001c, 0x00201e2d, 0x000 }, + { 0x00000008, 0x00214a27, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00294a24, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x00800000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204806, 0x000 }, + { 0x00000008, 0x00214a27, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x0004217f, 0x00604411, 0x67c }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x67b }, + { 0x00000004, 0x00404c11, 0x135 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x0000001c, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x67c }, + { 0x00000011, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x13c }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x00000000, 0x00600000, 0x160 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x00000010, 0xc0211220, 0x000 }, + { 0x0000ffff, 0x40280620, 0x000 }, + { 0x00000010, 0xc0210a20, 0x000 }, + { 0x00000000, 0x00341461, 0x000 }, + { 0x00000000, 0x00741882, 0x2bb }, + { 0x0001a1fd, 0x00604411, 0x2e0 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x147 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00600000, 0x160 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x0000ffff, 0xc0281220, 0x000 }, + { 0x00000010, 0x40211620, 0x000 }, + { 0x0000ffff, 0xc0681a20, 0x2bb }, + { 0x0001a1fd, 0x00604411, 0x2e0 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x158 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000001, 0x00300a2f, 0x000 }, + { 0x00000001, 0x00210a22, 0x000 }, + { 0x00000003, 0x00384a22, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001a, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00804811, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600000, 0x18f }, + { 0x00000000, 0x00600000, 0x1a0 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00202c08, 0x000 }, + { 0x00000000, 0x00202411, 0x000 }, + { 0x00000000, 0x00202811, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x00000016, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x93800000, 0x00204411, 0x000 }, + { 0x00000002, 0x00221e29, 0x000 }, + { 0x00000000, 0x007048eb, 0x19c }, + { 0x00000000, 0x00600000, 0x2bb }, + { 0x00000001, 0x40330620, 0x000 }, + { 0x00000000, 0xc0302409, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00600000, 0x2a3 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ae00000, 0x181 }, + { 0x00000000, 0x00600000, 0x13a }, + { 0x00000000, 0x00400000, 0x186 }, + { 0x95000000, 0x00204411, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x186 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000001, 0x00530621, 0x182 }, + { 0x92000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0604800, 0x197 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000011, 0x0020062d, 0x000 }, + { 0x00000000, 0x0078042a, 0x2fb }, + { 0x00000000, 0x00202809, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x174 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000210, 0x00600411, 0x315 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x194 }, + { 0x00000015, 0xc0203620, 0x000 }, + { 0x00000016, 0xc0203620, 0x000 }, + { 0x3f800000, 0x00200411, 0x000 }, + { 0x46000000, 0x00600811, 0x1b2 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x19b }, + { 0x00000001, 0x00804811, 0x000 }, + { 0x00000021, 0x00804811, 0x000 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x00000010, 0xc0211220, 0x000 }, + { 0x0000ffff, 0x40281620, 0x000 }, + { 0x00000010, 0xc0811a20, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x00000008, 0x00221e30, 0x000 }, + { 0x00000029, 0x00201a2d, 0x000 }, + { 0x0000e000, 0x00204411, 0x000 }, + { 0xfffbff09, 0x00204811, 0x000 }, + { 0x0000000f, 0x0020222d, 0x000 }, + { 0x00001fff, 0x00294a28, 0x000 }, + { 0x00000006, 0x0020222d, 0x000 }, + { 0x00000000, 0x002920e8, 0x000 }, + { 0x00000000, 0x00204808, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00294a26, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000100, 0x00201811, 0x000 }, + { 0x00000008, 0x00621e28, 0x12f }, + { 0x00000008, 0x00822228, 0x000 }, + { 0x0002c000, 0x00204411, 0x000 }, + { 0x00000015, 0x00600e2d, 0x1bd }, + { 0x00000016, 0x00600e2d, 0x1bd }, + { 0x0000c008, 0x00204411, 0x000 }, + { 0x00000017, 0x00200e2d, 0x000 }, + { 0x00000000, 0x14c00000, 0x1b9 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00204801, 0x000 }, + { 0x39000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00804802, 0x000 }, + { 0x00000018, 0x00202e2d, 0x000 }, + { 0x00000000, 0x003b0d63, 0x000 }, + { 0x00000008, 0x00224a23, 0x000 }, + { 0x00000010, 0x00224a23, 0x000 }, + { 0x00000018, 0x00224a23, 0x000 }, + { 0x00000000, 0x00804803, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00001000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x00000007, 0x0021062f, 0x000 }, + { 0x00000013, 0x00200a2d, 0x000 }, + { 0x00000001, 0x00202c11, 0x000 }, + { 0x0000ffff, 0x40282220, 0x000 }, + { 0x0000000f, 0x00262228, 0x000 }, + { 0x00000010, 0x40212620, 0x000 }, + { 0x0000000f, 0x00262629, 0x000 }, + { 0x00000000, 0x00202802, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001b, 0x00204811, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x1e0 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000081, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000080, 0x00201c11, 0x000 }, + { 0x00000000, 0x002f0227, 0x000 }, + { 0x00000000, 0x0ce00000, 0x1dc }, + { 0x00000000, 0x00600000, 0x1e9 }, + { 0x00000001, 0x00531e27, 0x1d8 }, + { 0x00000001, 0x00202c11, 0x000 }, + { 0x0000001f, 0x00280a22, 0x000 }, + { 0x0000001f, 0x00282a2a, 0x000 }, + { 0x00000001, 0x00530621, 0x1d1 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000002, 0x00304a2f, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000001, 0x00301e2f, 0x000 }, + { 0x00000000, 0x002f0227, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00600000, 0x1e9 }, + { 0x00000001, 0x00531e27, 0x1e5 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x0000000f, 0x00260e23, 0x000 }, + { 0x00000010, 0xc0211220, 0x000 }, + { 0x0000000f, 0x00261224, 0x000 }, + { 0x00000000, 0x00201411, 0x000 }, + { 0x00000000, 0x00601811, 0x2bb }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0x002f022b, 0x000 }, + { 0x00000000, 0x0ce00000, 0x1f8 }, + { 0x00000010, 0x00221628, 0x000 }, + { 0xffff0000, 0x00281625, 0x000 }, + { 0x0000ffff, 0x00281a29, 0x000 }, + { 0x00000000, 0x002948c5, 0x000 }, + { 0x00000000, 0x0020480a, 0x000 }, + { 0x00000000, 0x00202c11, 0x000 }, + { 0x00000010, 0x00221623, 0x000 }, + { 0xffff0000, 0x00281625, 0x000 }, + { 0x0000ffff, 0x00281a24, 0x000 }, + { 0x00000000, 0x002948c5, 0x000 }, + { 0x00000000, 0x00731503, 0x205 }, + { 0x00000000, 0x00201805, 0x000 }, + { 0x00000000, 0x00731524, 0x205 }, + { 0x00000000, 0x002d14c5, 0x000 }, + { 0x00000000, 0x003008a2, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00202802, 0x000 }, + { 0x00000000, 0x00202003, 0x000 }, + { 0x00000000, 0x00802404, 0x000 }, + { 0x0000000f, 0x00210225, 0x000 }, + { 0x00000000, 0x14c00000, 0x67b }, + { 0x00000000, 0x002b1405, 0x000 }, + { 0x00000001, 0x00901625, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001a, 0x00294a22, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00384a21, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0000ffff, 0x40281220, 0x000 }, + { 0x00000010, 0xc0211a20, 0x000 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x00000010, 0xc0211620, 0x000 }, + { 0x00000000, 0x00741465, 0x2bb }, + { 0x0001a1fd, 0x00604411, 0x2e0 }, + { 0x00000001, 0x00330621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0cc00000, 0x219 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x212 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000000, 0x00600000, 0x638 }, + { 0x00000000, 0x0040040f, 0x213 }, + { 0x00000000, 0x00600000, 0x624 }, + { 0x00000000, 0x00600000, 0x638 }, + { 0x00000210, 0x00600411, 0x315 }, + { 0x00000000, 0x00600000, 0x1a0 }, + { 0x00000000, 0x00600000, 0x19c }, + { 0x00000000, 0x00600000, 0x2bb }, + { 0x00000000, 0x00600000, 0x2a3 }, + { 0x93800000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204808, 0x000 }, + { 0x00000000, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ae00000, 0x232 }, + { 0x00000000, 0x00600000, 0x13a }, + { 0x00000000, 0x00400000, 0x236 }, + { 0x95000000, 0x00204411, 0x000 }, + { 0x00000000, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x236 }, + { 0x00000000, 0xc0404800, 0x233 }, + { 0x92000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x00000016, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0x00600411, 0x2fb }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000000, 0x00600000, 0x624 }, + { 0x0000a00c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000018, 0x40210a20, 0x000 }, + { 0x00000003, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x24c }, + { 0x00000014, 0x0020222d, 0x000 }, + { 0x00080101, 0x00292228, 0x000 }, + { 0x00000014, 0x00203628, 0x000 }, + { 0x0000a30c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x251 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000010, 0x00600411, 0x315 }, + { 0x3f800000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x00000000, 0x00600000, 0x27c }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000001, 0x00211e27, 0x000 }, + { 0x00000000, 0x14e00000, 0x26a }, + { 0x00000012, 0x00201e2d, 0x000 }, + { 0x0000ffff, 0x00281e27, 0x000 }, + { 0x00000000, 0x00341c27, 0x000 }, + { 0x00000000, 0x12c00000, 0x25f }, + { 0x00000000, 0x00201c11, 0x000 }, + { 0x00000000, 0x002f00e5, 0x000 }, + { 0x00000000, 0x08c00000, 0x262 }, + { 0x00000000, 0x00201407, 0x000 }, + { 0x00000012, 0x00201e2d, 0x000 }, + { 0x00000010, 0x00211e27, 0x000 }, + { 0x00000000, 0x00341c47, 0x000 }, + { 0x00000000, 0x12c00000, 0x267 }, + { 0x00000000, 0x00201c11, 0x000 }, + { 0x00000000, 0x002f00e6, 0x000 }, + { 0x00000000, 0x08c00000, 0x26a }, + { 0x00000000, 0x00201807, 0x000 }, + { 0x00000000, 0x00600000, 0x2c1 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x00000000, 0x00342023, 0x000 }, + { 0x00000000, 0x12c00000, 0x272 }, + { 0x00000000, 0x00342044, 0x000 }, + { 0x00000000, 0x12c00000, 0x271 }, + { 0x00000016, 0x00404811, 0x276 }, + { 0x00000018, 0x00404811, 0x276 }, + { 0x00000000, 0x00342044, 0x000 }, + { 0x00000000, 0x12c00000, 0x275 }, + { 0x00000017, 0x00404811, 0x276 }, + { 0x00000019, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0001a1fd, 0x00604411, 0x2e9 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x256 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000010, 0x40210620, 0x000 }, + { 0x0000ffff, 0xc0280a20, 0x000 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x0000ffff, 0xc0281220, 0x000 }, + { 0x00000010, 0x40211620, 0x000 }, + { 0x0000ffff, 0xc0881a20, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00042004, 0x00604411, 0x67c }, + { 0x00000000, 0x00600000, 0x624 }, + { 0x00000000, 0xc0600000, 0x2a3 }, + { 0x00000005, 0x00200a2d, 0x000 }, + { 0x00000008, 0x00220a22, 0x000 }, + { 0x0000002b, 0x00201a2d, 0x000 }, + { 0x0000001c, 0x00201e2d, 0x000 }, + { 0x00007000, 0x00281e27, 0x000 }, + { 0x00000000, 0x00311ce6, 0x000 }, + { 0x0000002a, 0x00201a2d, 0x000 }, + { 0x0000000c, 0x00221a26, 0x000 }, + { 0x00000000, 0x002f00e6, 0x000 }, + { 0x00000000, 0x06e00000, 0x292 }, + { 0x00000000, 0x00201c11, 0x000 }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x0000002b, 0x00203623, 0x000 }, + { 0x00000010, 0x00201811, 0x000 }, + { 0x00000000, 0x00691ce2, 0x12f }, + { 0x93800000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x95000000, 0x00204411, 0x000 }, + { 0x00000000, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x29d }, + { 0x00000001, 0x00333e2f, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x92000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000001c, 0x00403627, 0x000 }, + { 0x0000000c, 0xc0220a20, 0x000 }, + { 0x00000029, 0x00203622, 0x000 }, + { 0x00000028, 0xc0403620, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000009, 0x00204811, 0x000 }, + { 0xa1000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00804811, 0x000 }, + { 0x00000021, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002c1ce3, 0x000 }, + { 0x00000021, 0x00203627, 0x000 }, + { 0x00000022, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002c1ce4, 0x000 }, + { 0x00000022, 0x00203627, 0x000 }, + { 0x00000023, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120a3, 0x000 }, + { 0x00000000, 0x002d1d07, 0x000 }, + { 0x00000023, 0x00203627, 0x000 }, + { 0x00000024, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x00000000, 0x002d1d07, 0x000 }, + { 0x00000024, 0x00803627, 0x000 }, + { 0x00000021, 0x00203623, 0x000 }, + { 0x00000022, 0x00203624, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000023, 0x00203627, 0x000 }, + { 0x00000000, 0x00311cc4, 0x000 }, + { 0x00000024, 0x00803627, 0x000 }, + { 0x0000001a, 0x00203627, 0x000 }, + { 0x0000001b, 0x00203628, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000002, 0x00210227, 0x000 }, + { 0x00000000, 0x14c00000, 0x2dc }, + { 0x00000000, 0x00400000, 0x2d9 }, + { 0x0000001a, 0x00203627, 0x000 }, + { 0x0000001b, 0x00203628, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000002, 0x00210227, 0x000 }, + { 0x00000000, 0x14e00000, 0x2d9 }, + { 0x00000003, 0x00210227, 0x000 }, + { 0x00000000, 0x14e00000, 0x2dc }, + { 0x00000023, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002e00e1, 0x000 }, + { 0x00000000, 0x02c00000, 0x2dc }, + { 0x00000021, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120a1, 0x000 }, + { 0x00000000, 0x002e00e8, 0x000 }, + { 0x00000000, 0x06c00000, 0x2dc }, + { 0x00000024, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002e00e2, 0x000 }, + { 0x00000000, 0x02c00000, 0x2dc }, + { 0x00000022, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120c2, 0x000 }, + { 0x00000000, 0x002e00e8, 0x000 }, + { 0x00000000, 0x06c00000, 0x2dc }, + { 0x00000000, 0x00600000, 0x659 }, + { 0x00000000, 0x00600000, 0x2b5 }, + { 0x00000000, 0x00400000, 0x2de }, + { 0x00000000, 0x00600000, 0x2b5 }, + { 0x00000000, 0x00600000, 0x650 }, + { 0x00000000, 0x00400000, 0x2de }, + { 0x00000000, 0x00600000, 0x2a7 }, + { 0x00000000, 0x00400000, 0x2de }, + { 0x0000001a, 0x00201e2d, 0x000 }, + { 0x0000001b, 0x0080222d, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00894907, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000010, 0x00221e21, 0x000 }, + { 0x00000000, 0x00294847, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000000, 0x00311ca1, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294847, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000010, 0x00221e21, 0x000 }, + { 0x00000000, 0x003120c2, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00894907, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000001, 0x00220a21, 0x000 }, + { 0x00000000, 0x003308a2, 0x000 }, + { 0x00000010, 0x00221e22, 0x000 }, + { 0x00000010, 0x00212222, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000001, 0x00220a21, 0x000 }, + { 0x00000000, 0x003008a2, 0x000 }, + { 0x00000010, 0x00221e22, 0x000 }, + { 0x00000010, 0x00212222, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x003808c5, 0x000 }, + { 0x00000000, 0x00300841, 0x000 }, + { 0x00000001, 0x00220a22, 0x000 }, + { 0x00000000, 0x003308a2, 0x000 }, + { 0x00000010, 0x00221e22, 0x000 }, + { 0x00000010, 0x00212222, 0x000 }, + { 0x00000000, 0x00894907, 0x000 }, + { 0x00000017, 0x0020222d, 0x000 }, + { 0x00000000, 0x14c00000, 0x318 }, + { 0xffffffef, 0x00280621, 0x000 }, + { 0x00000014, 0x0020222d, 0x000 }, + { 0x0000f8e0, 0x00204411, 0x000 }, + { 0x00000000, 0x00294901, 0x000 }, + { 0x00000000, 0x00894901, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00804811, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x97000000, 0xc0204411, 0x000 }, + { 0x00000000, 0xc0204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x97000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x97000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x00002257, 0x00204411, 0x000 }, + { 0x00000003, 0xc0484a20, 0x000 }, + { 0x0000225d, 0x00204411, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000000, 0x00600000, 0x638 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00384a22, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x40204800, 0x000 }, + { 0x00000001, 0x40304a20, 0x000 }, + { 0x00000002, 0xc0304a20, 0x000 }, + { 0x00000001, 0x00530a22, 0x34b }, + { 0x0000003f, 0xc0280a20, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000018, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x67c }, + { 0x00000011, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x354 }, + { 0x00000014, 0x002f0222, 0x000 }, + { 0x00000000, 0x0cc00000, 0x362 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00604802, 0x36a }, + { 0x00002100, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000004, 0x002f0222, 0x000 }, + { 0x00000000, 0x0cc00000, 0x366 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x35d }, + { 0x00000028, 0x002f0222, 0x000 }, + { 0x00000000, 0x0cc00000, 0x5b3 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x35d }, + { 0x0000002c, 0x00203626, 0x000 }, + { 0x00000049, 0x00201811, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x00000001, 0x00331a26, 0x000 }, + { 0x00000000, 0x002f0226, 0x000 }, + { 0x00000000, 0x0cc00000, 0x36c }, + { 0x0000002c, 0x00801a2d, 0x000 }, + { 0x0000003f, 0xc0280a20, 0x000 }, + { 0x00000015, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x382 }, + { 0x00000006, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x3ad }, + { 0x00000016, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x3af }, + { 0x00000020, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x398 }, + { 0x0000000f, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x3a4 }, + { 0x00000010, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x3a4 }, + { 0x0000001e, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x38c }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x000 }, + { 0x08000000, 0x00290a22, 0x000 }, + { 0x00000003, 0x40210e20, 0x000 }, + { 0x0000000c, 0xc0211220, 0x000 }, + { 0x00080000, 0x00281224, 0x000 }, + { 0x00000014, 0xc0221620, 0x000 }, + { 0x00000000, 0x002914a4, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x002948a2, 0x000 }, + { 0x0000a1fe, 0x00204411, 0x000 }, + { 0x00000000, 0x00404803, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000016, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x67c }, + { 0x00000015, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x38e }, + { 0x0000210e, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000017, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x67c }, + { 0x00000003, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x39a }, + { 0x00002108, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x80000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000010, 0x00204811, 0x000 }, + { 0x00000000, 0x00200010, 0x000 }, + { 0x00000000, 0x14c00000, 0x3aa }, + { 0x00000000, 0x00400000, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000006, 0x00404811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000016, 0x00604811, 0x36a }, + { 0x00000000, 0x00400000, 0x000 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x0000001d, 0x00210223, 0x000 }, + { 0x00000000, 0x14e00000, 0x3c4 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000018, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x67c }, + { 0x00000011, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x3b8 }, + { 0x00002100, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0xbabecafe, 0x00204811, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000004, 0x00404811, 0x000 }, + { 0x00002170, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000a, 0x00204811, 0x000 }, + { 0x00000000, 0x00200010, 0x000 }, + { 0x00000000, 0x14c00000, 0x3c9 }, + { 0x8c000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00003fff, 0x40280a20, 0x000 }, + { 0x80000000, 0x40280e20, 0x000 }, + { 0x40000000, 0xc0281220, 0x000 }, + { 0x00040000, 0x00694622, 0x67c }, + { 0x00000000, 0x00201410, 0x000 }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x3d7 }, + { 0x00000000, 0xc0401800, 0x3da }, + { 0x00003fff, 0xc0281a20, 0x000 }, + { 0x00040000, 0x00694626, 0x67c }, + { 0x00000000, 0x00201810, 0x000 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x3dd }, + { 0x00000000, 0xc0401c00, 0x3e0 }, + { 0x00003fff, 0xc0281e20, 0x000 }, + { 0x00040000, 0x00694627, 0x67c }, + { 0x00000000, 0x00201c10, 0x000 }, + { 0x00000000, 0x00204402, 0x000 }, + { 0x00000000, 0x002820c5, 0x000 }, + { 0x00000000, 0x004948e8, 0x000 }, + { 0xa5800000, 0x00200811, 0x000 }, + { 0x00002000, 0x00200c11, 0x000 }, + { 0x83000000, 0x00604411, 0x408 }, + { 0x00000000, 0x00204402, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x40204800, 0x000 }, + { 0x0000001f, 0xc0210220, 0x000 }, + { 0x00000000, 0x14c00000, 0x3ed }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0000ffff, 0xc0481220, 0x3f5 }, + { 0xa7800000, 0x00200811, 0x000 }, + { 0x0000a000, 0x00200c11, 0x000 }, + { 0x83000000, 0x00604411, 0x408 }, + { 0x00000000, 0x00204402, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000ffff, 0xc0281220, 0x000 }, + { 0x83000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00304883, 0x000 }, + { 0x84000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x1d000000, 0x000 }, + { 0x83000000, 0x00604411, 0x408 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0xa9800000, 0x00200811, 0x000 }, + { 0x0000c000, 0x00400c11, 0x3f0 }, + { 0xab800000, 0x00200811, 0x000 }, + { 0x0000f8e0, 0x00400c11, 0x3f0 }, + { 0xad800000, 0x00200811, 0x000 }, + { 0x0000f880, 0x00400c11, 0x3f0 }, + { 0xb3800000, 0x00200811, 0x000 }, + { 0x0000f3fc, 0x00400c11, 0x3f0 }, + { 0xaf800000, 0x00200811, 0x000 }, + { 0x0000e000, 0x00400c11, 0x3f0 }, + { 0xb1800000, 0x00200811, 0x000 }, + { 0x0000f000, 0x00400c11, 0x3f0 }, + { 0x83000000, 0x00204411, 0x000 }, + { 0x00002148, 0x00204811, 0x000 }, + { 0x84000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x1d000000, 0x000 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x01182000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0218a000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0318c000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0418f8e0, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0518f880, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0618e000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0718f000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0818f3fc, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x00000030, 0x00200a2d, 0x000 }, + { 0x00000000, 0xc0290c40, 0x000 }, + { 0x00000030, 0x00203623, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x86000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00404801, 0x000 }, + { 0x85000000, 0xc0204411, 0x000 }, + { 0x00000000, 0x00404801, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x0004217f, 0x00604411, 0x67c }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x00000000, 0x00404c02, 0x43e }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x00000000, 0xc0201000, 0x000 }, + { 0x00000000, 0xc0201400, 0x000 }, + { 0x00000000, 0xc0201800, 0x000 }, + { 0x00000000, 0xc0201c00, 0x000 }, + { 0x00007f00, 0x00280a21, 0x000 }, + { 0x00004500, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x44c }, + { 0x00000000, 0xc0202000, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x00000010, 0x00280a23, 0x000 }, + { 0x00000010, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x454 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00040000, 0x00694624, 0x67c }, + { 0x00000000, 0x00400000, 0x459 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000216d, 0x00204411, 0x000 }, + { 0x00000000, 0x00204804, 0x000 }, + { 0x00000000, 0x00604805, 0x681 }, + { 0x00000000, 0x002824f0, 0x000 }, + { 0x00000007, 0x00280a23, 0x000 }, + { 0x00000001, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x460 }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x04e00000, 0x479 }, + { 0x00000000, 0x00400000, 0x486 }, + { 0x00000002, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x465 }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x02e00000, 0x479 }, + { 0x00000000, 0x00400000, 0x486 }, + { 0x00000003, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x46a }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x0ce00000, 0x479 }, + { 0x00000000, 0x00400000, 0x486 }, + { 0x00000004, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x46f }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x0ae00000, 0x479 }, + { 0x00000000, 0x00400000, 0x486 }, + { 0x00000005, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x474 }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x06e00000, 0x479 }, + { 0x00000000, 0x00400000, 0x486 }, + { 0x00000006, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x479 }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x08e00000, 0x479 }, + { 0x00000000, 0x00400000, 0x486 }, + { 0x00007f00, 0x00280a21, 0x000 }, + { 0x00004500, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x000 }, + { 0x00000008, 0x00210a23, 0x000 }, + { 0x00000000, 0x14c00000, 0x483 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x00000000, 0xc0204400, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00007f00, 0x00280a21, 0x000 }, + { 0x00004500, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x48c }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0400000, 0x000 }, + { 0x00000000, 0x00404c08, 0x44c }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x00000011, 0x40211220, 0x000 }, + { 0x00000012, 0x40211620, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00210225, 0x000 }, + { 0x00000000, 0x14e00000, 0x496 }, + { 0x00040000, 0xc0494a20, 0x497 }, + { 0xfffbffff, 0xc0284a20, 0x000 }, + { 0x00000000, 0x00210223, 0x000 }, + { 0x00000000, 0x14e00000, 0x4a3 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x00210224, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000c, 0x00204811, 0x000 }, + { 0x00000000, 0x00200010, 0x000 }, + { 0x00000000, 0x14c00000, 0x49f }, + { 0xa0000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000004, 0x00204811, 0x000 }, + { 0x0000216b, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204810, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000005, 0x00204811, 0x000 }, + { 0x0000216c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204810, 0x000 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00400000, 0x49d }, + { 0x00000000, 0xc0210a20, 0x000 }, + { 0x00000000, 0x14c00000, 0x4b6 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000216d, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0604800, 0x681 }, + { 0x00000000, 0x00400000, 0x4ba }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00040000, 0xc0294620, 0x000 }, + { 0x00000000, 0xc0600000, 0x67c }, + { 0x00000001, 0x00210222, 0x000 }, + { 0x00000000, 0x14c00000, 0x4c1 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x00000000, 0xc0204400, 0x000 }, + { 0x00000000, 0xc0404810, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x0000000e, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x67c }, + { 0x00000000, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x4c3 }, + { 0x00002180, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000003, 0x00333e2f, 0x000 }, + { 0x00000001, 0x00210221, 0x000 }, + { 0x00000000, 0x14e00000, 0x4f3 }, + { 0x0000002c, 0x00200a2d, 0x000 }, + { 0x00040000, 0x18e00c11, 0x4e2 }, + { 0x00000001, 0x00333e2f, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xd8c04800, 0x4d6 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000002d, 0x0020122d, 0x000 }, + { 0x00000000, 0x00290c83, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000011, 0x00210224, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x00000000, 0x00400000, 0x49d }, + { 0x0000002c, 0xc0203620, 0x000 }, + { 0x0000002d, 0xc0403620, 0x000 }, + { 0x0000000f, 0x00210221, 0x000 }, + { 0x00000000, 0x14c00000, 0x4f8 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0xd9000000, 0x000 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0xb5000000, 0x00204411, 0x000 }, + { 0x00002000, 0x00204811, 0x000 }, + { 0xb6000000, 0x00204411, 0x000 }, + { 0x0000a000, 0x00204811, 0x000 }, + { 0xb7000000, 0x00204411, 0x000 }, + { 0x0000c000, 0x00204811, 0x000 }, + { 0xb8000000, 0x00204411, 0x000 }, + { 0x0000f8e0, 0x00204811, 0x000 }, + { 0xb9000000, 0x00204411, 0x000 }, + { 0x0000f880, 0x00204811, 0x000 }, + { 0xba000000, 0x00204411, 0x000 }, + { 0x0000e000, 0x00204811, 0x000 }, + { 0xbb000000, 0x00204411, 0x000 }, + { 0x0000f000, 0x00204811, 0x000 }, + { 0xbc000000, 0x00204411, 0x000 }, + { 0x0000f3fc, 0x00204811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000002, 0x00204811, 0x000 }, + { 0x000000ff, 0x00280e30, 0x000 }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x50c }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000000, 0x14c00000, 0x521 }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x0000001c, 0x00203623, 0x000 }, + { 0x0000002b, 0x00203623, 0x000 }, + { 0x00000029, 0x00203623, 0x000 }, + { 0x00000028, 0x00203623, 0x000 }, + { 0x00000017, 0x00203623, 0x000 }, + { 0x00000025, 0x00203623, 0x000 }, + { 0x00000026, 0x00203623, 0x000 }, + { 0x00000015, 0x00203623, 0x000 }, + { 0x00000016, 0x00203623, 0x000 }, + { 0xffffe000, 0x00200c11, 0x000 }, + { 0x00000021, 0x00203623, 0x000 }, + { 0x00000022, 0x00203623, 0x000 }, + { 0x00001fff, 0x00200c11, 0x000 }, + { 0x00000023, 0x00203623, 0x000 }, + { 0x00000024, 0x00203623, 0x000 }, + { 0xf1ffffff, 0x00283a2e, 0x000 }, + { 0x0000001a, 0xc0220e20, 0x000 }, + { 0x00000000, 0x0029386e, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x0000002a, 0x40203620, 0x000 }, + { 0x87000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1f4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x00000030, 0x00203623, 0x000 }, + { 0x9d000000, 0x00204411, 0x000 }, + { 0x0000001f, 0x40214a20, 0x000 }, + { 0x96000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x00000000, 0xc0201000, 0x000 }, + { 0x0000001f, 0x00211624, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x0000001d, 0x00203623, 0x000 }, + { 0x00000003, 0x00281e23, 0x000 }, + { 0x00000008, 0x00222223, 0x000 }, + { 0xfffff000, 0x00282228, 0x000 }, + { 0x00000000, 0x002920e8, 0x000 }, + { 0x0000001f, 0x00203628, 0x000 }, + { 0x00000018, 0x00211e23, 0x000 }, + { 0x00000020, 0x00203627, 0x000 }, + { 0x00000002, 0x00221624, 0x000 }, + { 0x00000000, 0x003014a8, 0x000 }, + { 0x0000001e, 0x00203625, 0x000 }, + { 0x00000003, 0x00211a24, 0x000 }, + { 0x10000000, 0x00281a26, 0x000 }, + { 0xefffffff, 0x00283a2e, 0x000 }, + { 0x00000000, 0x004938ce, 0x66a }, + { 0x00000001, 0x40280a20, 0x000 }, + { 0x00000006, 0x40280e20, 0x000 }, + { 0x00000300, 0xc0281220, 0x000 }, + { 0x00000008, 0x00211224, 0x000 }, + { 0x00000000, 0xc0201620, 0x000 }, + { 0x00000000, 0xc0201a20, 0x000 }, + { 0x00000000, 0x00210222, 0x000 }, + { 0x00000000, 0x14c00000, 0x559 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00002258, 0x00300a24, 0x000 }, + { 0x00040000, 0x00694622, 0x67c }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204805, 0x000 }, + { 0x00020000, 0x00294a26, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x561 }, + { 0x00000000, 0xc0201c10, 0x000 }, + { 0x00000000, 0xc0400000, 0x56f }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x561 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00002258, 0x00300a24, 0x000 }, + { 0x00040000, 0x00694622, 0x67c }, + { 0x00000000, 0xc0201c10, 0x000 }, + { 0x00000000, 0xc0400000, 0x56f }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x565 }, + { 0x00000000, 0xc0201c00, 0x000 }, + { 0x00000000, 0xc0400000, 0x56f }, + { 0x00000004, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x56d }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000216d, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0604800, 0x681 }, + { 0x00000000, 0x00401c10, 0x56f }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0400000, 0x000 }, + { 0x00000000, 0x0ee00000, 0x571 }, + { 0x00000000, 0x00600000, 0x5bc }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x582 }, + { 0x0000a2b7, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a2b6, 0x00604411, 0x67c }, + { 0x0000001a, 0x00212230, 0x000 }, + { 0x00000006, 0x00222630, 0x000 }, + { 0x00042004, 0x00604411, 0x67c }, + { 0x0000a2c4, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x580 }, + { 0x0000a2d1, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d1, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x00000001, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x593 }, + { 0x0000a2bb, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a2ba, 0x00604411, 0x67c }, + { 0x0000001a, 0x00212230, 0x000 }, + { 0x00000006, 0x00222630, 0x000 }, + { 0x00042004, 0x00604411, 0x67c }, + { 0x0000a2c5, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x591 }, + { 0x0000a2d2, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d2, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x00000002, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x5a4 }, + { 0x0000a2bf, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a2be, 0x00604411, 0x67c }, + { 0x0000001a, 0x00212230, 0x000 }, + { 0x00000006, 0x00222630, 0x000 }, + { 0x00042004, 0x00604411, 0x67c }, + { 0x0000a2c6, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x5a2 }, + { 0x0000a2d3, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d3, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x0000a2c3, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a2c2, 0x00604411, 0x67c }, + { 0x0000001a, 0x00212230, 0x000 }, + { 0x00000006, 0x00222630, 0x000 }, + { 0x00042004, 0x00604411, 0x67c }, + { 0x0000a2c7, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x5b1 }, + { 0x0000a2d4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d4, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x85000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204801, 0x000 }, + { 0x0000304a, 0x00204411, 0x000 }, + { 0x01000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00400000, 0x5b7 }, + { 0xa4000000, 0xc0204411, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000000, 0xc0600000, 0x5bc }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x0000002c, 0x00203621, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x00000000, 0x002f0230, 0x000 }, + { 0x00000000, 0x0cc00000, 0x5c3 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000030, 0x00403621, 0x5d6 }, + { 0x00000030, 0x0020062d, 0x000 }, + { 0x00007e00, 0x00280621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x5d6 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004a092, 0x00604411, 0x67c }, + { 0x00000031, 0x00203630, 0x000 }, + { 0x0004a093, 0x00604411, 0x67c }, + { 0x00000032, 0x00203630, 0x000 }, + { 0x0004a2b6, 0x00604411, 0x67c }, + { 0x00000033, 0x00203630, 0x000 }, + { 0x0004a2ba, 0x00604411, 0x67c }, + { 0x00000034, 0x00203630, 0x000 }, + { 0x0004a2be, 0x00604411, 0x67c }, + { 0x00000035, 0x00203630, 0x000 }, + { 0x0004a2c2, 0x00604411, 0x67c }, + { 0x00000036, 0x00203630, 0x000 }, + { 0x00042004, 0x00604411, 0x67c }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x00000005, 0x00204811, 0x000 }, + { 0x0000a1f4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x88000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x00000001, 0x002f0230, 0x000 }, + { 0x00000000, 0x0ce00000, 0x61f }, + { 0x00000030, 0x0020062d, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x61f }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00007e00, 0x00280621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x5f8 }, + { 0x0000a092, 0x00204411, 0x000 }, + { 0x00000031, 0x00204a2d, 0x000 }, + { 0x0000a093, 0x00204411, 0x000 }, + { 0x00000032, 0x00204a2d, 0x000 }, + { 0x0000a2b6, 0x00204411, 0x000 }, + { 0x00000033, 0x00204a2d, 0x000 }, + { 0x0000a2ba, 0x00204411, 0x000 }, + { 0x00000034, 0x00204a2d, 0x000 }, + { 0x0000a2be, 0x00204411, 0x000 }, + { 0x00000035, 0x00204a2d, 0x000 }, + { 0x0000a2c2, 0x00204411, 0x000 }, + { 0x00000036, 0x00204a2d, 0x000 }, + { 0x00000030, 0x0020062d, 0x000 }, + { 0x000001ff, 0x00280621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x61e }, + { 0x00000000, 0x00210221, 0x000 }, + { 0x00000000, 0x14c00000, 0x601 }, + { 0x0004a003, 0x00604411, 0x67c }, + { 0x0000a003, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x00000001, 0x00210621, 0x000 }, + { 0x00000000, 0x14c00000, 0x606 }, + { 0x0004a010, 0x00604411, 0x67c }, + { 0x0000a010, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x00000001, 0x00210621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x61e }, + { 0x0004a011, 0x00604411, 0x67c }, + { 0x0000a011, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a012, 0x00604411, 0x67c }, + { 0x0000a012, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a013, 0x00604411, 0x67c }, + { 0x0000a013, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a014, 0x00604411, 0x67c }, + { 0x0000a014, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a015, 0x00604411, 0x67c }, + { 0x0000a015, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a016, 0x00604411, 0x67c }, + { 0x0000a016, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x0004a017, 0x00604411, 0x67c }, + { 0x0000a017, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x00042004, 0x00604411, 0x67c }, + { 0x0000002c, 0x0080062d, 0x000 }, + { 0xff000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000002, 0x00804811, 0x000 }, + { 0x00000000, 0x0ee00000, 0x630 }, + { 0x00000030, 0x0020062d, 0x000 }, + { 0x00000002, 0x00280621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x62e }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00042004, 0x00604411, 0x67c }, + { 0x00001000, 0x00200811, 0x000 }, + { 0x0000002b, 0x00203622, 0x000 }, + { 0x00000000, 0x00600000, 0x634 }, + { 0x00000000, 0x00600000, 0x5bc }, + { 0x98000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00804811, 0x000 }, + { 0x00000000, 0xc0600000, 0x634 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000022, 0x00204811, 0x000 }, + { 0x89000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00404811, 0x620 }, + { 0x97000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00404811, 0x620 }, + { 0x00000000, 0x00600000, 0x64d }, + { 0x0001a2a4, 0xc0204411, 0x000 }, + { 0x00000016, 0x00604811, 0x36a }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00010000, 0x00204811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x09800000, 0x00204811, 0x000 }, + { 0xffffffff, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x0004217f, 0x00604411, 0x67c }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x00000004, 0x00404c11, 0x647 }, + { 0x00000000, 0x00400000, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000004, 0x00291e27, 0x000 }, + { 0x00000017, 0x00803627, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0xfffffffb, 0x00281e27, 0x000 }, + { 0x00000017, 0x00803627, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000008, 0x00291e27, 0x000 }, + { 0x00000017, 0x00803627, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0xfffffff7, 0x00281e27, 0x000 }, + { 0x00000017, 0x00803627, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000016, 0x00604811, 0x36a }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00010000, 0x00204811, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x01800000, 0x00204811, 0x000 }, + { 0xffffffff, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004217f, 0x00604411, 0x67c }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x67b }, + { 0x00000010, 0x00404c11, 0x661 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x38c00000, 0x000 }, + { 0x0000001d, 0x00200a2d, 0x000 }, + { 0x0000001e, 0x00200e2d, 0x000 }, + { 0x0000001f, 0x0020122d, 0x000 }, + { 0x00000020, 0x0020162d, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204804, 0x000 }, + { 0x00000000, 0x00204805, 0x000 }, + { 0x00000000, 0x00204801, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000004, 0x00301224, 0x000 }, + { 0x00000000, 0x002f0064, 0x000 }, + { 0x00000000, 0x0cc00000, 0x67a }, + { 0x00000003, 0x00281a22, 0x000 }, + { 0x00000008, 0x00221222, 0x000 }, + { 0xfffff000, 0x00281224, 0x000 }, + { 0x00000000, 0x002910c4, 0x000 }, + { 0x0000001f, 0x00403624, 0x000 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x1ac00000, 0x67c }, + { 0x9f000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000000, 0x1ae00000, 0x67f }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x1ac00000, 0x681 }, + { 0x9e000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000000, 0x1ae00000, 0x684 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00001000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001b, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0001a1fd, 0xc0204411, 0x000 }, + { 0x00000021, 0x00201e2d, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000024, 0x0020222d, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000022, 0x0020222d, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000023, 0x00201e2d, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00404811, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x014204f5, 0x05b30250, 0x000 }, + { 0x01c30168, 0x043505b3, 0x000 }, + { 0x02250209, 0x02500151, 0x000 }, + { 0x02230245, 0x02a00241, 0x000 }, + { 0x03cd05b3, 0x05b305b3, 0x000 }, + { 0x063c063d, 0x031f05b3, 0x000 }, + { 0x05b305b8, 0x03200340, 0x000 }, + { 0x032a0282, 0x03420334, 0x000 }, + { 0x05b305b3, 0x05b305b3, 0x000 }, + { 0x05b30544, 0x05b305b3, 0x000 }, + { 0x03b205b3, 0x04ae0344, 0x000 }, + { 0x048d0443, 0x043305b3, 0x000 }, + { 0x04c305b3, 0x043704d0, 0x000 }, + { 0x044304fa, 0x03510371, 0x000 }, + { 0x05b305b3, 0x05b305b3, 0x000 }, + { 0x05b305b3, 0x05b305b3, 0x000 }, + { 0x05b305b3, 0x063205ba, 0x000 }, + { 0x05b305b3, 0x000705b3, 0x000 }, + { 0x05b305b3, 0x05b305b3, 0x000 }, + { 0x05b305b3, 0x05b305b3, 0x000 }, + { 0x03ee03e3, 0x03fe03fc, 0x000 }, + { 0x04040400, 0x04020406, 0x000 }, + { 0x0412040e, 0x041a0416, 0x000 }, + { 0x0422041e, 0x042a0426, 0x000 }, + { 0x05b305b3, 0x042e05b3, 0x000 }, + { 0x05b305b3, 0x05b305b3, 0x000 }, + { 0x05b305b3, 0x05b305b3, 0x000 }, + { 0x00020668, 0x06860006, 0x000 }, +}; + +static const u32 RV670_pfp_microcode[] = { +0xca0400, +0xa00000, +0x7e828b, +0x7c038b, +0x8001b8, +0x7c038b, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xc41838, +0xca2400, +0xca2800, +0x9581a8, +0xc41c3a, +0xc3c000, +0xca0800, +0xca0c00, +0x7c744b, +0xc20005, +0x99c000, +0xc41c3a, +0x7c744c, +0xc0fff0, +0x042c04, +0x309002, +0x7d2500, +0x351402, +0x7d350b, +0x255403, +0x7cd580, +0x259c03, +0x95c004, +0xd5001b, +0x7eddc1, +0x7d9d80, +0xd6801b, +0xd5801b, +0xd4401e, +0xd5401e, +0xd6401e, +0xd6801e, +0xd4801e, +0xd4c01e, +0x9783d3, +0xd5c01e, +0xca0800, +0x80001a, +0xca0c00, +0xe4011e, +0xd4001e, +0x80000c, +0xc41838, +0xe4013e, +0xd4001e, +0x80000c, +0xc41838, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xe4011e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xe4013e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xca1800, +0xd4401e, +0xd5801e, +0x800053, +0xd40075, +0xd4401e, +0xca0800, +0xca0c00, +0xca1000, +0xd48019, +0xd4c018, +0xd50017, +0xd4801e, +0xd4c01e, +0xd5001e, +0xe2001e, +0xca0400, +0xa00000, +0x7e828b, +0xca0800, +0xd48060, +0xd4401e, +0x800000, +0xd4801e, +0xca0800, +0xd48061, +0xd4401e, +0x800000, +0xd4801e, +0xca0800, +0xca0c00, +0xd4401e, +0xd48016, +0xd4c016, +0xd4801e, +0x8001b8, +0xd4c01e, +0xc60843, +0xca0c00, +0xca1000, +0x948004, +0xca1400, +0xe420f3, +0xd42013, +0xd56065, +0xd4e01c, +0xd5201c, +0xd5601c, +0x800000, +0x062001, +0xc60843, +0xca0c00, +0xca1000, +0x9483f7, +0xca1400, +0xe420f3, +0x800079, +0xd42013, +0xc60843, +0xca0c00, +0xca1000, +0x9883ef, +0xca1400, +0xd40064, +0x80008d, +0x000000, +0xc41432, +0xc61843, +0xc4082f, +0x954005, +0xc40c30, +0xd4401e, +0x800000, +0xee001e, +0x9583f5, +0xc41031, +0xd44033, +0xd52065, +0xd4a01c, +0xd4e01c, +0xd5201c, +0xe4015e, +0xd4001e, +0x800000, +0x062001, +0xca1800, +0x0a2001, +0xd60076, +0xc40836, +0x988007, +0xc61045, +0x950110, +0xd4001f, +0xd46062, +0x800000, +0xd42062, +0xcc3835, +0xcc1433, +0x8401bb, +0xd40072, +0xd5401e, +0x800000, +0xee001e, +0xe2001a, +0x8401bb, +0xe2001a, +0xcc104b, +0xcc0447, +0x2c9401, +0x7d098b, +0x984005, +0x7d15cb, +0xd4001a, +0x8001b8, +0xd4006d, +0x344401, +0xcc0c48, +0x98403a, +0xcc2c4a, +0x958004, +0xcc0449, +0x8001b8, +0xd4001a, +0xd4c01a, +0x282801, +0x8400f0, +0xcc1003, +0x98801b, +0x04380c, +0x8400f0, +0xcc1003, +0x988017, +0x043808, +0x8400f0, +0xcc1003, +0x988013, +0x043804, +0x8400f0, +0xcc1003, +0x988014, +0xcc104c, +0x9a8009, +0xcc144d, +0x9840dc, +0xd4006d, +0xcc1848, +0xd5001a, +0xd5401a, +0x8000c9, +0xd5801a, +0x96c0d5, +0xd4006d, +0x8001b8, +0xd4006e, +0x9ac003, +0xd4006d, +0xd4006e, +0x800000, +0xec007f, +0x9ac0cc, +0xd4006d, +0x8001b8, +0xd4006e, +0xcc1403, +0xcc1803, +0xcc1c03, +0x7d9103, +0x7dd583, +0x7d190c, +0x35cc1f, +0x35701f, +0x7cf0cb, +0x7cd08b, +0x880000, +0x7e8e8b, +0x95c004, +0xd4006e, +0x8001b8, +0xd4001a, +0xd4c01a, +0xcc0803, +0xcc0c03, +0xcc1003, +0xcc1403, +0xcc1803, +0xcc1c03, +0xcc2403, +0xcc2803, +0x35c41f, +0x36b01f, +0x7c704b, +0x34f01f, +0x7c704b, +0x35701f, +0x7c704b, +0x7d8881, +0x7dccc1, +0x7e5101, +0x7e9541, +0x7c9082, +0x7cd4c2, +0x7c848b, +0x9ac003, +0x7c8c8b, +0x2c8801, +0x98809e, +0xd4006d, +0x98409c, +0xd4006e, +0xcc084c, +0xcc0c4d, +0xcc1048, +0xd4801a, +0xd4c01a, +0x800101, +0xd5001a, +0xcc0832, +0xd40032, +0x9482d9, +0xca0c00, +0xd4401e, +0x800000, +0xd4001e, +0xe4011e, +0xd4001e, +0xca0800, +0xca0c00, +0xca1000, +0xd4401e, +0xca1400, +0xd4801e, +0xd4c01e, +0xd5001e, +0xd5401e, +0xd54034, +0x800000, +0xee001e, +0x280404, +0xe2001a, +0xe2001a, +0xd4401a, +0xca3800, +0xcc0803, +0xcc0c03, +0xcc0c03, +0xcc0c03, +0x9882bd, +0x000000, +0x8401bb, +0xd7a06f, +0x800000, +0xee001f, +0xca0400, +0xc2ff00, +0xcc0834, +0xc13fff, +0x7c74cb, +0x7cc90b, +0x7d010f, +0x9902b0, +0x7c738b, +0x8401bb, +0xd7a06f, +0x800000, +0xee001f, +0xca0800, +0x281900, +0x7d898b, +0x958014, +0x281404, +0xca0c00, +0xca1000, +0xca1c00, +0xca2400, +0xe2001f, +0xd4c01a, +0xd5001a, +0xd5401a, +0xcc1803, +0xcc2c03, +0xcc2c03, +0xcc2c03, +0x7da58b, +0x7d9c47, +0x984297, +0x000000, +0x800161, +0xd4c01a, +0xd4401e, +0xd4801e, +0x800000, +0xee001e, +0xe4011e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xe4013e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xca0800, +0x248c06, +0x0ccc06, +0x98c006, +0xcc104e, +0x990004, +0xd40073, +0xe4011e, +0xd4001e, +0xd4401e, +0xd4801e, +0x800000, +0xee001e, +0xca0800, +0xca0c00, +0x34d018, +0x251001, +0x950021, +0xc17fff, +0xca1000, +0xca1400, +0xca1800, +0xd4801d, +0xd4c01d, +0x7db18b, +0xc14202, +0xc2c001, +0xd5801d, +0x34dc0e, +0x7d5d4c, +0x7f734c, +0xd7401e, +0xd5001e, +0xd5401e, +0xc14200, +0xc2c000, +0x099c01, +0x31dc10, +0x7f5f4c, +0x7f734c, +0x042802, +0x7d8380, +0xd5a86f, +0xd58066, +0xd7401e, +0xec005e, +0xc82402, +0xc82402, +0x8001b8, +0xd60076, +0xd4401e, +0xd4801e, +0xd4c01e, +0x800000, +0xee001e, +0x800000, +0xee001f, +0xd4001f, +0x800000, +0xd4001f, +0xd4001f, +0x880000, +0xd4001f, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x010171, +0x020178, +0x03008f, +0x04007f, +0x050003, +0x06003f, +0x070032, +0x08012c, +0x090046, +0x0a0036, +0x1001b6, +0x1700a2, +0x22013a, +0x230149, +0x2000b4, +0x240125, +0x27004d, +0x28006a, +0x2a0060, +0x2b0052, +0x2f0065, +0x320087, +0x34017f, +0x3c0156, +0x3f0072, +0x41018c, +0x44012e, +0x550173, +0x56017a, +0x60000b, +0x610034, +0x620038, +0x630038, +0x640038, +0x650038, +0x660038, +0x670038, +0x68003a, +0x690041, +0x6a0048, +0x6b0048, +0x6c0048, +0x6d0048, +0x6e0048, +0x6f0048, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +}; + +static const u32 RS780_cp_microcode[][3] = { + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0000ffff, 0x00284621, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x00000000, 0x00e00000, 0x000 }, + { 0x00010000, 0xc0294620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00042004, 0x00604411, 0x622 }, + { 0x00000000, 0x00600000, 0x5d1 }, + { 0x00000000, 0x00600000, 0x5de }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000f00, 0x00281622, 0x000 }, + { 0x00000008, 0x00211625, 0x000 }, + { 0x00000018, 0x00203625, 0x000 }, + { 0x8d000000, 0x00204411, 0x000 }, + { 0x00000004, 0x002f0225, 0x000 }, + { 0x00000000, 0x0ce00000, 0x018 }, + { 0x00412000, 0x00404811, 0x019 }, + { 0x00422000, 0x00204811, 0x000 }, + { 0x8e000000, 0x00204411, 0x000 }, + { 0x00000028, 0x00204a2d, 0x000 }, + { 0x90000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204805, 0x000 }, + { 0x0000000c, 0x00211622, 0x000 }, + { 0x00000003, 0x00281625, 0x000 }, + { 0x00000019, 0x00211a22, 0x000 }, + { 0x00000004, 0x00281a26, 0x000 }, + { 0x00000000, 0x002914c5, 0x000 }, + { 0x00000019, 0x00203625, 0x000 }, + { 0x00000000, 0x003a1402, 0x000 }, + { 0x00000016, 0x00211625, 0x000 }, + { 0x00000003, 0x00281625, 0x000 }, + { 0x00000017, 0x00200e2d, 0x000 }, + { 0xfffffffc, 0x00280e23, 0x000 }, + { 0x00000000, 0x002914a3, 0x000 }, + { 0x00000017, 0x00203625, 0x000 }, + { 0x00008000, 0x00280e22, 0x000 }, + { 0x00000007, 0x00220e23, 0x000 }, + { 0x00000000, 0x0029386e, 0x000 }, + { 0x20000000, 0x00280e22, 0x000 }, + { 0x00000006, 0x00210e23, 0x000 }, + { 0x00000000, 0x0029386e, 0x000 }, + { 0x00000000, 0x00220222, 0x000 }, + { 0x00000000, 0x14e00000, 0x038 }, + { 0x00000000, 0x2ee00000, 0x035 }, + { 0x00000000, 0x2ce00000, 0x037 }, + { 0x00000000, 0x00400e2d, 0x039 }, + { 0x00000008, 0x00200e2d, 0x000 }, + { 0x00000009, 0x0040122d, 0x046 }, + { 0x00000001, 0x00400e2d, 0x039 }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x003ffffc, 0x00281223, 0x000 }, + { 0x00000002, 0x00221224, 0x000 }, + { 0x0000001f, 0x00211e23, 0x000 }, + { 0x00000000, 0x14e00000, 0x03e }, + { 0x00000008, 0x00401c11, 0x041 }, + { 0x0000000d, 0x00201e2d, 0x000 }, + { 0x0000000f, 0x00281e27, 0x000 }, + { 0x00000003, 0x00221e27, 0x000 }, + { 0x7fc00000, 0x00281a23, 0x000 }, + { 0x00000014, 0x00211a26, 0x000 }, + { 0x00000001, 0x00331a26, 0x000 }, + { 0x00000008, 0x00221a26, 0x000 }, + { 0x00000000, 0x00290cc7, 0x000 }, + { 0x00000027, 0x00203624, 0x000 }, + { 0x00007f00, 0x00281221, 0x000 }, + { 0x00001400, 0x002f0224, 0x000 }, + { 0x00000000, 0x0ce00000, 0x04b }, + { 0x00000001, 0x00290e23, 0x000 }, + { 0x0000000e, 0x00203623, 0x000 }, + { 0x0000e000, 0x00204411, 0x000 }, + { 0xfff80000, 0x00294a23, 0x000 }, + { 0x00000000, 0x003a2c02, 0x000 }, + { 0x00000002, 0x00220e2b, 0x000 }, + { 0xfc000000, 0x00280e23, 0x000 }, + { 0x0000000f, 0x00203623, 0x000 }, + { 0x00001fff, 0x00294a23, 0x000 }, + { 0x00000027, 0x00204a2d, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000029, 0x00200e2d, 0x000 }, + { 0x060a0200, 0x00294a23, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000001, 0x00210222, 0x000 }, + { 0x00000000, 0x14e00000, 0x061 }, + { 0x00000000, 0x2ee00000, 0x05f }, + { 0x00000000, 0x2ce00000, 0x05e }, + { 0x00000000, 0x00400e2d, 0x062 }, + { 0x00000001, 0x00400e2d, 0x062 }, + { 0x0000000a, 0x00200e2d, 0x000 }, + { 0x0000000b, 0x0040122d, 0x06a }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x003ffffc, 0x00281223, 0x000 }, + { 0x00000002, 0x00221224, 0x000 }, + { 0x7fc00000, 0x00281623, 0x000 }, + { 0x00000014, 0x00211625, 0x000 }, + { 0x00000001, 0x00331625, 0x000 }, + { 0x80000000, 0x00280e23, 0x000 }, + { 0x00000000, 0x00290ca3, 0x000 }, + { 0x3ffffc00, 0x00290e23, 0x000 }, + { 0x0000001f, 0x00211e23, 0x000 }, + { 0x00000000, 0x14e00000, 0x06d }, + { 0x00000100, 0x00401c11, 0x070 }, + { 0x0000000d, 0x00201e2d, 0x000 }, + { 0x000000f0, 0x00281e27, 0x000 }, + { 0x00000004, 0x00221e27, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000d, 0x00204811, 0x000 }, + { 0xfffff0ff, 0x00281a30, 0x000 }, + { 0x0000a028, 0x00204411, 0x000 }, + { 0x00000000, 0x002948e6, 0x000 }, + { 0x0000a018, 0x00204411, 0x000 }, + { 0x3fffffff, 0x00284a23, 0x000 }, + { 0x0000a010, 0x00204411, 0x000 }, + { 0x00000000, 0x00204804, 0x000 }, + { 0x00000030, 0x0020162d, 0x000 }, + { 0x00000002, 0x00291625, 0x000 }, + { 0x00000030, 0x00203625, 0x000 }, + { 0x00000025, 0x0020162d, 0x000 }, + { 0x00000000, 0x002f00a3, 0x000 }, + { 0x00000000, 0x0cc00000, 0x083 }, + { 0x00000026, 0x0020162d, 0x000 }, + { 0x00000000, 0x002f00a4, 0x000 }, + { 0x00000000, 0x0cc00000, 0x084 }, + { 0x00000000, 0x00400000, 0x08a }, + { 0x00000025, 0x00203623, 0x000 }, + { 0x00000026, 0x00203624, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000002, 0x00210227, 0x000 }, + { 0x00000000, 0x14e00000, 0x08a }, + { 0x00000000, 0x00600000, 0x5ff }, + { 0x00000000, 0x00600000, 0x5f3 }, + { 0x00000002, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x08d }, + { 0x00000012, 0xc0403620, 0x093 }, + { 0x00000000, 0x2ee00000, 0x091 }, + { 0x00000000, 0x2ce00000, 0x090 }, + { 0x00000002, 0x00400e2d, 0x092 }, + { 0x00000003, 0x00400e2d, 0x092 }, + { 0x0000000c, 0x00200e2d, 0x000 }, + { 0x00000012, 0x00203623, 0x000 }, + { 0x00000003, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x098 }, + { 0x0000a00c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x0a0 }, + { 0x0000a00c, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x2ee00000, 0x09e }, + { 0x00000000, 0x2ce00000, 0x09d }, + { 0x00000002, 0x00400e2d, 0x09f }, + { 0x00000003, 0x00400e2d, 0x09f }, + { 0x0000000c, 0x00200e2d, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000000, 0x003a0c02, 0x000 }, + { 0x003f0000, 0x00280e23, 0x000 }, + { 0x00000010, 0x00210e23, 0x000 }, + { 0x00000011, 0x00203623, 0x000 }, + { 0x0000001e, 0x0021022b, 0x000 }, + { 0x00000000, 0x14c00000, 0x0a7 }, + { 0x00000016, 0xc0203620, 0x000 }, + { 0x0000001f, 0x0021022b, 0x000 }, + { 0x00000000, 0x14c00000, 0x0aa }, + { 0x00000015, 0xc0203620, 0x000 }, + { 0x00000008, 0x00210e2b, 0x000 }, + { 0x0000007f, 0x00280e23, 0x000 }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0e1 }, + { 0x00000000, 0x27000000, 0x000 }, + { 0x00000000, 0x00600000, 0x2a3 }, + { 0x00000001, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ae00000, 0x0b3 }, + { 0x00000000, 0x00600000, 0x13a }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x0000000c, 0x00221e30, 0x000 }, + { 0x99800000, 0x00204411, 0x000 }, + { 0x00000004, 0x0020122d, 0x000 }, + { 0x00000008, 0x00221224, 0x000 }, + { 0x00000010, 0x00201811, 0x000 }, + { 0x00000000, 0x00291ce4, 0x000 }, + { 0x00000000, 0x00604807, 0x12f }, + { 0x9b000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x9c000000, 0x00204411, 0x000 }, + { 0x00000000, 0x0033146f, 0x000 }, + { 0x00000001, 0x00333e23, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0x00203c05, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000e, 0x00204811, 0x000 }, + { 0x00000000, 0x00201010, 0x000 }, + { 0x0000e007, 0x00204411, 0x000 }, + { 0x0000000f, 0x0021022b, 0x000 }, + { 0x00000000, 0x14c00000, 0x0cb }, + { 0x00f8ff08, 0x00204811, 0x000 }, + { 0x98000000, 0x00404811, 0x0dc }, + { 0x000000f0, 0x00280e22, 0x000 }, + { 0x000000a0, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x0da }, + { 0x00000011, 0x00200e2d, 0x000 }, + { 0x00000001, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0d5 }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0d4 }, + { 0x00003f00, 0x00400c11, 0x0d6 }, + { 0x00001f00, 0x00400c11, 0x0d6 }, + { 0x00000f00, 0x00200c11, 0x000 }, + { 0x00380009, 0x00294a23, 0x000 }, + { 0x3f000000, 0x00280e2b, 0x000 }, + { 0x00000002, 0x00220e23, 0x000 }, + { 0x00000007, 0x00494a23, 0x0dc }, + { 0x00380f09, 0x00204811, 0x000 }, + { 0x68000007, 0x00204811, 0x000 }, + { 0x00000008, 0x00214a27, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00294a24, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000a202, 0x00204411, 0x000 }, + { 0x00ff0000, 0x00280e22, 0x000 }, + { 0x00000080, 0x00294a23, 0x000 }, + { 0x00000027, 0x00200e2d, 0x000 }, + { 0x00000026, 0x0020122d, 0x000 }, + { 0x00000000, 0x002f0083, 0x000 }, + { 0x00000000, 0x0ce00000, 0x0ea }, + { 0x00000000, 0x00600000, 0x5f9 }, + { 0x00000000, 0x00400000, 0x0eb }, + { 0x00000000, 0x00600000, 0x5fc }, + { 0x00000007, 0x0020222d, 0x000 }, + { 0x00000005, 0x00220e22, 0x000 }, + { 0x00100000, 0x00280e23, 0x000 }, + { 0x00000000, 0x00292068, 0x000 }, + { 0x00000000, 0x003a0c02, 0x000 }, + { 0x000000ef, 0x00280e23, 0x000 }, + { 0x00000000, 0x00292068, 0x000 }, + { 0x00000017, 0x00200e2d, 0x000 }, + { 0x00000003, 0x00210223, 0x000 }, + { 0x00000000, 0x14e00000, 0x0f8 }, + { 0x0000000b, 0x00210228, 0x000 }, + { 0x00000000, 0x14c00000, 0x0f8 }, + { 0x00000400, 0x00292228, 0x000 }, + { 0x00000014, 0x00203628, 0x000 }, + { 0x0000001c, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x0fd }, + { 0x0000a30c, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000001e, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x10b }, + { 0x0000a30f, 0x00204411, 0x000 }, + { 0x00000011, 0x00200e2d, 0x000 }, + { 0x00000001, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x104 }, + { 0xffffffff, 0x00404811, 0x10b }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x107 }, + { 0x0000ffff, 0x00404811, 0x10b }, + { 0x00000004, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x10a }, + { 0x000000ff, 0x00404811, 0x10b }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0002c400, 0x00204411, 0x000 }, + { 0x0000001f, 0x00210e22, 0x000 }, + { 0x00000000, 0x14c00000, 0x112 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x00000013, 0x00203623, 0x000 }, + { 0x00000018, 0x40224a20, 0x000 }, + { 0x00000010, 0xc0424a20, 0x114 }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x00000013, 0x00203623, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000000a, 0x00201011, 0x000 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0ce00000, 0x11b }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000001, 0x00531224, 0x117 }, + { 0xffbfffff, 0x00283a2e, 0x000 }, + { 0x0000001b, 0x00210222, 0x000 }, + { 0x00000000, 0x14c00000, 0x12e }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000d, 0x00204811, 0x000 }, + { 0x00000018, 0x00220e30, 0x000 }, + { 0xfc000000, 0x00280e23, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000e, 0x00204811, 0x000 }, + { 0x00000000, 0x00201010, 0x000 }, + { 0x0000e00e, 0x00204411, 0x000 }, + { 0x07f8ff08, 0x00204811, 0x000 }, + { 0x00000000, 0x00294a23, 0x000 }, + { 0x0000001c, 0x00201e2d, 0x000 }, + { 0x00000008, 0x00214a27, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00294a24, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x00800000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204806, 0x000 }, + { 0x00000008, 0x00214a27, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x0004217f, 0x00604411, 0x622 }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x621 }, + { 0x00000004, 0x00404c11, 0x135 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x0000001c, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x622 }, + { 0x00000011, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x13c }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x00000000, 0x00600000, 0x160 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x00000010, 0xc0211220, 0x000 }, + { 0x0000ffff, 0x40280620, 0x000 }, + { 0x00000010, 0xc0210a20, 0x000 }, + { 0x00000000, 0x00341461, 0x000 }, + { 0x00000000, 0x00741882, 0x2bb }, + { 0x0001a1fd, 0x00604411, 0x2e0 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x147 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00600000, 0x160 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x0000ffff, 0xc0281220, 0x000 }, + { 0x00000010, 0x40211620, 0x000 }, + { 0x0000ffff, 0xc0681a20, 0x2bb }, + { 0x0001a1fd, 0x00604411, 0x2e0 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x158 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000001, 0x00300a2f, 0x000 }, + { 0x00000001, 0x00210a22, 0x000 }, + { 0x00000003, 0x00384a22, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001a, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00804811, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600000, 0x18f }, + { 0x00000000, 0x00600000, 0x1a0 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00202c08, 0x000 }, + { 0x00000000, 0x00202411, 0x000 }, + { 0x00000000, 0x00202811, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x00000016, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x93800000, 0x00204411, 0x000 }, + { 0x00000002, 0x00221e29, 0x000 }, + { 0x00000000, 0x007048eb, 0x19c }, + { 0x00000000, 0x00600000, 0x2bb }, + { 0x00000001, 0x40330620, 0x000 }, + { 0x00000000, 0xc0302409, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00600000, 0x2a3 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ae00000, 0x181 }, + { 0x00000000, 0x00600000, 0x13a }, + { 0x00000000, 0x00400000, 0x186 }, + { 0x95000000, 0x00204411, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x186 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000001, 0x00530621, 0x182 }, + { 0x92000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0604800, 0x197 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000011, 0x0020062d, 0x000 }, + { 0x00000000, 0x0078042a, 0x2fb }, + { 0x00000000, 0x00202809, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x174 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000210, 0x00600411, 0x315 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x194 }, + { 0x00000015, 0xc0203620, 0x000 }, + { 0x00000016, 0xc0203620, 0x000 }, + { 0x3f800000, 0x00200411, 0x000 }, + { 0x46000000, 0x00600811, 0x1b2 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x19b }, + { 0x00000001, 0x00804811, 0x000 }, + { 0x00000021, 0x00804811, 0x000 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x00000010, 0xc0211220, 0x000 }, + { 0x0000ffff, 0x40281620, 0x000 }, + { 0x00000010, 0xc0811a20, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x00000008, 0x00221e30, 0x000 }, + { 0x00000029, 0x00201a2d, 0x000 }, + { 0x0000e000, 0x00204411, 0x000 }, + { 0xfffbff09, 0x00204811, 0x000 }, + { 0x0000000f, 0x0020222d, 0x000 }, + { 0x00001fff, 0x00294a28, 0x000 }, + { 0x00000006, 0x0020222d, 0x000 }, + { 0x00000000, 0x002920e8, 0x000 }, + { 0x00000000, 0x00204808, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00294a26, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000100, 0x00201811, 0x000 }, + { 0x00000008, 0x00621e28, 0x12f }, + { 0x00000008, 0x00822228, 0x000 }, + { 0x0002c000, 0x00204411, 0x000 }, + { 0x00000015, 0x00600e2d, 0x1bd }, + { 0x00000016, 0x00600e2d, 0x1bd }, + { 0x0000c008, 0x00204411, 0x000 }, + { 0x00000017, 0x00200e2d, 0x000 }, + { 0x00000000, 0x14c00000, 0x1b9 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00204801, 0x000 }, + { 0x39000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00804802, 0x000 }, + { 0x00000018, 0x00202e2d, 0x000 }, + { 0x00000000, 0x003b0d63, 0x000 }, + { 0x00000008, 0x00224a23, 0x000 }, + { 0x00000010, 0x00224a23, 0x000 }, + { 0x00000018, 0x00224a23, 0x000 }, + { 0x00000000, 0x00804803, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00001000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x00000007, 0x0021062f, 0x000 }, + { 0x00000013, 0x00200a2d, 0x000 }, + { 0x00000001, 0x00202c11, 0x000 }, + { 0x0000ffff, 0x40282220, 0x000 }, + { 0x0000000f, 0x00262228, 0x000 }, + { 0x00000010, 0x40212620, 0x000 }, + { 0x0000000f, 0x00262629, 0x000 }, + { 0x00000000, 0x00202802, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001b, 0x00204811, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0ce00000, 0x1e0 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000081, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000080, 0x00201c11, 0x000 }, + { 0x00000000, 0x002f0227, 0x000 }, + { 0x00000000, 0x0ce00000, 0x1dc }, + { 0x00000000, 0x00600000, 0x1e9 }, + { 0x00000001, 0x00531e27, 0x1d8 }, + { 0x00000001, 0x00202c11, 0x000 }, + { 0x0000001f, 0x00280a22, 0x000 }, + { 0x0000001f, 0x00282a2a, 0x000 }, + { 0x00000001, 0x00530621, 0x1d1 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000002, 0x00304a2f, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000001, 0x00301e2f, 0x000 }, + { 0x00000000, 0x002f0227, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00600000, 0x1e9 }, + { 0x00000001, 0x00531e27, 0x1e5 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x0000000f, 0x00260e23, 0x000 }, + { 0x00000010, 0xc0211220, 0x000 }, + { 0x0000000f, 0x00261224, 0x000 }, + { 0x00000000, 0x00201411, 0x000 }, + { 0x00000000, 0x00601811, 0x2bb }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0x002f022b, 0x000 }, + { 0x00000000, 0x0ce00000, 0x1f8 }, + { 0x00000010, 0x00221628, 0x000 }, + { 0xffff0000, 0x00281625, 0x000 }, + { 0x0000ffff, 0x00281a29, 0x000 }, + { 0x00000000, 0x002948c5, 0x000 }, + { 0x00000000, 0x0020480a, 0x000 }, + { 0x00000000, 0x00202c11, 0x000 }, + { 0x00000010, 0x00221623, 0x000 }, + { 0xffff0000, 0x00281625, 0x000 }, + { 0x0000ffff, 0x00281a24, 0x000 }, + { 0x00000000, 0x002948c5, 0x000 }, + { 0x00000000, 0x00731503, 0x205 }, + { 0x00000000, 0x00201805, 0x000 }, + { 0x00000000, 0x00731524, 0x205 }, + { 0x00000000, 0x002d14c5, 0x000 }, + { 0x00000000, 0x003008a2, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00202802, 0x000 }, + { 0x00000000, 0x00202003, 0x000 }, + { 0x00000000, 0x00802404, 0x000 }, + { 0x0000000f, 0x00210225, 0x000 }, + { 0x00000000, 0x14c00000, 0x621 }, + { 0x00000000, 0x002b1405, 0x000 }, + { 0x00000001, 0x00901625, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001a, 0x00294a22, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00384a21, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0000ffff, 0x40281220, 0x000 }, + { 0x00000010, 0xc0211a20, 0x000 }, + { 0x0000ffff, 0x40280e20, 0x000 }, + { 0x00000010, 0xc0211620, 0x000 }, + { 0x00000000, 0x00741465, 0x2bb }, + { 0x0001a1fd, 0x00604411, 0x2e0 }, + { 0x00000001, 0x00330621, 0x000 }, + { 0x00000000, 0x002f0221, 0x000 }, + { 0x00000000, 0x0cc00000, 0x219 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x212 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000000, 0x00600000, 0x5de }, + { 0x00000000, 0x0040040f, 0x213 }, + { 0x00000000, 0x00600000, 0x5d1 }, + { 0x00000000, 0x00600000, 0x5de }, + { 0x00000210, 0x00600411, 0x315 }, + { 0x00000000, 0x00600000, 0x1a0 }, + { 0x00000000, 0x00600000, 0x19c }, + { 0x00000000, 0x00600000, 0x2bb }, + { 0x00000000, 0x00600000, 0x2a3 }, + { 0x93800000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204808, 0x000 }, + { 0x00000000, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ae00000, 0x232 }, + { 0x00000000, 0x00600000, 0x13a }, + { 0x00000000, 0x00400000, 0x236 }, + { 0x95000000, 0x00204411, 0x000 }, + { 0x00000000, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x236 }, + { 0x00000000, 0xc0404800, 0x233 }, + { 0x92000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x00000016, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0x00600411, 0x2fb }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000000, 0x00600000, 0x5d1 }, + { 0x0000a00c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000018, 0x40210a20, 0x000 }, + { 0x00000003, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x24c }, + { 0x00000014, 0x0020222d, 0x000 }, + { 0x00080101, 0x00292228, 0x000 }, + { 0x00000014, 0x00203628, 0x000 }, + { 0x0000a30c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x251 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000010, 0x00600411, 0x315 }, + { 0x3f800000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x00000000, 0x00600000, 0x27c }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000001, 0x00211e27, 0x000 }, + { 0x00000000, 0x14e00000, 0x26a }, + { 0x00000012, 0x00201e2d, 0x000 }, + { 0x0000ffff, 0x00281e27, 0x000 }, + { 0x00000000, 0x00341c27, 0x000 }, + { 0x00000000, 0x12c00000, 0x25f }, + { 0x00000000, 0x00201c11, 0x000 }, + { 0x00000000, 0x002f00e5, 0x000 }, + { 0x00000000, 0x08c00000, 0x262 }, + { 0x00000000, 0x00201407, 0x000 }, + { 0x00000012, 0x00201e2d, 0x000 }, + { 0x00000010, 0x00211e27, 0x000 }, + { 0x00000000, 0x00341c47, 0x000 }, + { 0x00000000, 0x12c00000, 0x267 }, + { 0x00000000, 0x00201c11, 0x000 }, + { 0x00000000, 0x002f00e6, 0x000 }, + { 0x00000000, 0x08c00000, 0x26a }, + { 0x00000000, 0x00201807, 0x000 }, + { 0x00000000, 0x00600000, 0x2c1 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x00000000, 0x00342023, 0x000 }, + { 0x00000000, 0x12c00000, 0x272 }, + { 0x00000000, 0x00342044, 0x000 }, + { 0x00000000, 0x12c00000, 0x271 }, + { 0x00000016, 0x00404811, 0x276 }, + { 0x00000018, 0x00404811, 0x276 }, + { 0x00000000, 0x00342044, 0x000 }, + { 0x00000000, 0x12c00000, 0x275 }, + { 0x00000017, 0x00404811, 0x276 }, + { 0x00000019, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0001a1fd, 0x00604411, 0x2e9 }, + { 0x00003fff, 0x002f022f, 0x000 }, + { 0x00000000, 0x0cc00000, 0x256 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x00000010, 0x40210620, 0x000 }, + { 0x0000ffff, 0xc0280a20, 0x000 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x0000ffff, 0xc0281220, 0x000 }, + { 0x00000010, 0x40211620, 0x000 }, + { 0x0000ffff, 0xc0881a20, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00042004, 0x00604411, 0x622 }, + { 0x00000000, 0x00600000, 0x5d1 }, + { 0x00000000, 0xc0600000, 0x2a3 }, + { 0x00000005, 0x00200a2d, 0x000 }, + { 0x00000008, 0x00220a22, 0x000 }, + { 0x0000002b, 0x00201a2d, 0x000 }, + { 0x0000001c, 0x00201e2d, 0x000 }, + { 0x00007000, 0x00281e27, 0x000 }, + { 0x00000000, 0x00311ce6, 0x000 }, + { 0x0000002a, 0x00201a2d, 0x000 }, + { 0x0000000c, 0x00221a26, 0x000 }, + { 0x00000000, 0x002f00e6, 0x000 }, + { 0x00000000, 0x06e00000, 0x292 }, + { 0x00000000, 0x00201c11, 0x000 }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x0000002b, 0x00203623, 0x000 }, + { 0x00000010, 0x00201811, 0x000 }, + { 0x00000000, 0x00691ce2, 0x12f }, + { 0x93800000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x95000000, 0x00204411, 0x000 }, + { 0x00000000, 0x002f022f, 0x000 }, + { 0x00000000, 0x0ce00000, 0x29d }, + { 0x00000001, 0x00333e2f, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x92000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000001c, 0x00403627, 0x000 }, + { 0x0000000c, 0xc0220a20, 0x000 }, + { 0x00000029, 0x00203622, 0x000 }, + { 0x00000028, 0xc0403620, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000009, 0x00204811, 0x000 }, + { 0xa1000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00804811, 0x000 }, + { 0x00000021, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002c1ce3, 0x000 }, + { 0x00000021, 0x00203627, 0x000 }, + { 0x00000022, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002c1ce4, 0x000 }, + { 0x00000022, 0x00203627, 0x000 }, + { 0x00000023, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120a3, 0x000 }, + { 0x00000000, 0x002d1d07, 0x000 }, + { 0x00000023, 0x00203627, 0x000 }, + { 0x00000024, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x00000000, 0x002d1d07, 0x000 }, + { 0x00000024, 0x00803627, 0x000 }, + { 0x00000021, 0x00203623, 0x000 }, + { 0x00000022, 0x00203624, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000023, 0x00203627, 0x000 }, + { 0x00000000, 0x00311cc4, 0x000 }, + { 0x00000024, 0x00803627, 0x000 }, + { 0x0000001a, 0x00203627, 0x000 }, + { 0x0000001b, 0x00203628, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000002, 0x00210227, 0x000 }, + { 0x00000000, 0x14c00000, 0x2dc }, + { 0x00000000, 0x00400000, 0x2d9 }, + { 0x0000001a, 0x00203627, 0x000 }, + { 0x0000001b, 0x00203628, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000002, 0x00210227, 0x000 }, + { 0x00000000, 0x14e00000, 0x2d9 }, + { 0x00000003, 0x00210227, 0x000 }, + { 0x00000000, 0x14e00000, 0x2dc }, + { 0x00000023, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002e00e1, 0x000 }, + { 0x00000000, 0x02c00000, 0x2dc }, + { 0x00000021, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120a1, 0x000 }, + { 0x00000000, 0x002e00e8, 0x000 }, + { 0x00000000, 0x06c00000, 0x2dc }, + { 0x00000024, 0x00201e2d, 0x000 }, + { 0x00000000, 0x002e00e2, 0x000 }, + { 0x00000000, 0x02c00000, 0x2dc }, + { 0x00000022, 0x00201e2d, 0x000 }, + { 0x00000000, 0x003120c2, 0x000 }, + { 0x00000000, 0x002e00e8, 0x000 }, + { 0x00000000, 0x06c00000, 0x2dc }, + { 0x00000000, 0x00600000, 0x5ff }, + { 0x00000000, 0x00600000, 0x2b5 }, + { 0x00000000, 0x00400000, 0x2de }, + { 0x00000000, 0x00600000, 0x2b5 }, + { 0x00000000, 0x00600000, 0x5f6 }, + { 0x00000000, 0x00400000, 0x2de }, + { 0x00000000, 0x00600000, 0x2a7 }, + { 0x00000000, 0x00400000, 0x2de }, + { 0x0000001a, 0x00201e2d, 0x000 }, + { 0x0000001b, 0x0080222d, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00894907, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000010, 0x00221e21, 0x000 }, + { 0x00000000, 0x00294847, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000000, 0x00311ca1, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294847, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000010, 0x00221e21, 0x000 }, + { 0x00000000, 0x003120c2, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00894907, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000001, 0x00220a21, 0x000 }, + { 0x00000000, 0x003308a2, 0x000 }, + { 0x00000010, 0x00221e22, 0x000 }, + { 0x00000010, 0x00212222, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00311ca3, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294887, 0x000 }, + { 0x00000001, 0x00220a21, 0x000 }, + { 0x00000000, 0x003008a2, 0x000 }, + { 0x00000010, 0x00221e22, 0x000 }, + { 0x00000010, 0x00212222, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000010, 0x00221e23, 0x000 }, + { 0x00000000, 0x003120c4, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x003808c5, 0x000 }, + { 0x00000000, 0x00300841, 0x000 }, + { 0x00000001, 0x00220a22, 0x000 }, + { 0x00000000, 0x003308a2, 0x000 }, + { 0x00000010, 0x00221e22, 0x000 }, + { 0x00000010, 0x00212222, 0x000 }, + { 0x00000000, 0x00894907, 0x000 }, + { 0x00000017, 0x0020222d, 0x000 }, + { 0x00000000, 0x14c00000, 0x318 }, + { 0xffffffef, 0x00280621, 0x000 }, + { 0x00000014, 0x0020222d, 0x000 }, + { 0x0000f8e0, 0x00204411, 0x000 }, + { 0x00000000, 0x00294901, 0x000 }, + { 0x00000000, 0x00894901, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x060a0200, 0x00804811, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x97000000, 0xc0204411, 0x000 }, + { 0x00000000, 0xc0204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x97000000, 0xc0204411, 0x000 }, + { 0x00000000, 0xc0204811, 0x000 }, + { 0x8a000000, 0xc0204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x97000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x97000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x00002257, 0x00204411, 0x000 }, + { 0x00000003, 0xc0484a20, 0x000 }, + { 0x0000225d, 0x00204411, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000000, 0x00600000, 0x5de }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00384a22, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0001a1fd, 0x00204411, 0x000 }, + { 0x00000000, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x40204800, 0x000 }, + { 0x00000001, 0x40304a20, 0x000 }, + { 0x00000002, 0xc0304a20, 0x000 }, + { 0x00000001, 0x00530a22, 0x355 }, + { 0x0000003f, 0xc0280a20, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000018, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x622 }, + { 0x00000011, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x35e }, + { 0x00000014, 0x002f0222, 0x000 }, + { 0x00000000, 0x0cc00000, 0x36c }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00604802, 0x374 }, + { 0x00002100, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000004, 0x002f0222, 0x000 }, + { 0x00000000, 0x0cc00000, 0x370 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x367 }, + { 0x00000028, 0x002f0222, 0x000 }, + { 0x00000000, 0x0cc00000, 0x5ba }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x367 }, + { 0x0000002c, 0x00203626, 0x000 }, + { 0x00000049, 0x00201811, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x00000001, 0x00331a26, 0x000 }, + { 0x00000000, 0x002f0226, 0x000 }, + { 0x00000000, 0x0cc00000, 0x376 }, + { 0x0000002c, 0x00801a2d, 0x000 }, + { 0x0000003f, 0xc0280a20, 0x000 }, + { 0x00000015, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x38c }, + { 0x00000006, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x3b7 }, + { 0x00000016, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x3b9 }, + { 0x00000020, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x3a2 }, + { 0x0000000f, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x3ae }, + { 0x00000010, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x3ae }, + { 0x0000001e, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x396 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x000 }, + { 0x08000000, 0x00290a22, 0x000 }, + { 0x00000003, 0x40210e20, 0x000 }, + { 0x0000000c, 0xc0211220, 0x000 }, + { 0x00080000, 0x00281224, 0x000 }, + { 0x00000014, 0xc0221620, 0x000 }, + { 0x00000000, 0x002914a4, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x002948a2, 0x000 }, + { 0x0000a1fe, 0x00204411, 0x000 }, + { 0x00000000, 0x00404803, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000016, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x622 }, + { 0x00000015, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x398 }, + { 0x0000210e, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000017, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x622 }, + { 0x00000003, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x3a4 }, + { 0x00002108, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404802, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x80000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000010, 0x00204811, 0x000 }, + { 0x00000000, 0x00200010, 0x000 }, + { 0x00000000, 0x14c00000, 0x3b4 }, + { 0x00000000, 0x00400000, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000006, 0x00404811, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000016, 0x00604811, 0x374 }, + { 0x00000000, 0x00400000, 0x000 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x0000001d, 0x00210223, 0x000 }, + { 0x00000000, 0x14e00000, 0x3ce }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x00000018, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x622 }, + { 0x00000011, 0x00210230, 0x000 }, + { 0x00000000, 0x14e00000, 0x3c2 }, + { 0x00002100, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0xbabecafe, 0x00204811, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000004, 0x00404811, 0x000 }, + { 0x00002170, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000a, 0x00204811, 0x000 }, + { 0x00000000, 0x00200010, 0x000 }, + { 0x00000000, 0x14c00000, 0x3d3 }, + { 0x8c000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00003fff, 0x40280a20, 0x000 }, + { 0x80000000, 0x40280e20, 0x000 }, + { 0x40000000, 0xc0281220, 0x000 }, + { 0x00040000, 0x00694622, 0x622 }, + { 0x00000000, 0x00201410, 0x000 }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x3e1 }, + { 0x00000000, 0xc0401800, 0x3e4 }, + { 0x00003fff, 0xc0281a20, 0x000 }, + { 0x00040000, 0x00694626, 0x622 }, + { 0x00000000, 0x00201810, 0x000 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x3e7 }, + { 0x00000000, 0xc0401c00, 0x3ea }, + { 0x00003fff, 0xc0281e20, 0x000 }, + { 0x00040000, 0x00694627, 0x622 }, + { 0x00000000, 0x00201c10, 0x000 }, + { 0x00000000, 0x00204402, 0x000 }, + { 0x00000000, 0x002820c5, 0x000 }, + { 0x00000000, 0x004948e8, 0x000 }, + { 0xa5800000, 0x00200811, 0x000 }, + { 0x00002000, 0x00200c11, 0x000 }, + { 0x83000000, 0x00604411, 0x412 }, + { 0x00000000, 0x00204402, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x40204800, 0x000 }, + { 0x0000001f, 0xc0210220, 0x000 }, + { 0x00000000, 0x14c00000, 0x3f7 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00008000, 0x00204811, 0x000 }, + { 0x0000ffff, 0xc0481220, 0x3ff }, + { 0xa7800000, 0x00200811, 0x000 }, + { 0x0000a000, 0x00200c11, 0x000 }, + { 0x83000000, 0x00604411, 0x412 }, + { 0x00000000, 0x00204402, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000ffff, 0xc0281220, 0x000 }, + { 0x83000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00304883, 0x000 }, + { 0x84000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x1d000000, 0x000 }, + { 0x83000000, 0x00604411, 0x412 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0xa9800000, 0x00200811, 0x000 }, + { 0x0000c000, 0x00400c11, 0x3fa }, + { 0xab800000, 0x00200811, 0x000 }, + { 0x0000f8e0, 0x00400c11, 0x3fa }, + { 0xad800000, 0x00200811, 0x000 }, + { 0x0000f880, 0x00400c11, 0x3fa }, + { 0xb3800000, 0x00200811, 0x000 }, + { 0x0000f3fc, 0x00400c11, 0x3fa }, + { 0xaf800000, 0x00200811, 0x000 }, + { 0x0000e000, 0x00400c11, 0x3fa }, + { 0xb1800000, 0x00200811, 0x000 }, + { 0x0000f000, 0x00400c11, 0x3fa }, + { 0x83000000, 0x00204411, 0x000 }, + { 0x00002148, 0x00204811, 0x000 }, + { 0x84000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x1d000000, 0x000 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x01182000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0218a000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0318c000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0418f8e0, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0518f880, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0618e000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0718f000, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x0818f3fc, 0xc0304620, 0x000 }, + { 0x00000000, 0xd9004800, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x00000033, 0xc0300a20, 0x000 }, + { 0x00000000, 0xc0403440, 0x000 }, + { 0x00000030, 0x00200a2d, 0x000 }, + { 0x00000000, 0xc0290c40, 0x000 }, + { 0x00000030, 0x00203623, 0x000 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x00a0000a, 0x000 }, + { 0x86000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00404801, 0x000 }, + { 0x85000000, 0xc0204411, 0x000 }, + { 0x00000000, 0x00404801, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x00000018, 0x40210220, 0x000 }, + { 0x00000000, 0x14c00000, 0x447 }, + { 0x00800000, 0xc0494a20, 0x448 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000004, 0x002f0222, 0x000 }, + { 0x00000000, 0x06e00000, 0x450 }, + { 0x00000004, 0x00200811, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x0004217f, 0x00604411, 0x622 }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x00000000, 0x00404c02, 0x450 }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x00000000, 0xc0201000, 0x000 }, + { 0x00000000, 0xc0201400, 0x000 }, + { 0x00000000, 0xc0201800, 0x000 }, + { 0x00000000, 0xc0201c00, 0x000 }, + { 0x00007f00, 0x00280a21, 0x000 }, + { 0x00004500, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x461 }, + { 0x00000000, 0xc0202000, 0x000 }, + { 0x00000004, 0x002f0228, 0x000 }, + { 0x00000000, 0x06e00000, 0x461 }, + { 0x00000004, 0x00202011, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x00000010, 0x00280a23, 0x000 }, + { 0x00000010, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ce00000, 0x469 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00040000, 0x00694624, 0x622 }, + { 0x00000000, 0x00400000, 0x46e }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000216d, 0x00204411, 0x000 }, + { 0x00000000, 0x00204804, 0x000 }, + { 0x00000000, 0x00604805, 0x627 }, + { 0x00000000, 0x002824f0, 0x000 }, + { 0x00000007, 0x00280a23, 0x000 }, + { 0x00000001, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x475 }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x04e00000, 0x48e }, + { 0x00000000, 0x00400000, 0x49b }, + { 0x00000002, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x47a }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x02e00000, 0x48e }, + { 0x00000000, 0x00400000, 0x49b }, + { 0x00000003, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x47f }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x0ce00000, 0x48e }, + { 0x00000000, 0x00400000, 0x49b }, + { 0x00000004, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x484 }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x0ae00000, 0x48e }, + { 0x00000000, 0x00400000, 0x49b }, + { 0x00000005, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x489 }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x06e00000, 0x48e }, + { 0x00000000, 0x00400000, 0x49b }, + { 0x00000006, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x48e }, + { 0x00000000, 0x002f00c9, 0x000 }, + { 0x00000000, 0x08e00000, 0x48e }, + { 0x00000000, 0x00400000, 0x49b }, + { 0x00007f00, 0x00280a21, 0x000 }, + { 0x00004500, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x000 }, + { 0x00000008, 0x00210a23, 0x000 }, + { 0x00000000, 0x14c00000, 0x498 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x00000000, 0xc0204400, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00007f00, 0x00280a21, 0x000 }, + { 0x00004500, 0x002f0222, 0x000 }, + { 0x00000000, 0x0ae00000, 0x4a1 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0400000, 0x000 }, + { 0x00000000, 0x00404c08, 0x461 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000010, 0x40210e20, 0x000 }, + { 0x00000011, 0x40211220, 0x000 }, + { 0x00000012, 0x40211620, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00210225, 0x000 }, + { 0x00000000, 0x14e00000, 0x4ab }, + { 0x00040000, 0xc0494a20, 0x4ac }, + { 0xfffbffff, 0xc0284a20, 0x000 }, + { 0x00000000, 0x00210223, 0x000 }, + { 0x00000000, 0x14e00000, 0x4b8 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x00210224, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x0000000c, 0x00204811, 0x000 }, + { 0x00000000, 0x00200010, 0x000 }, + { 0x00000000, 0x14c00000, 0x4b4 }, + { 0xa0000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000004, 0x00204811, 0x000 }, + { 0x0000216b, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204810, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000005, 0x00204811, 0x000 }, + { 0x0000216c, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204810, 0x000 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0ce00000, 0x000 }, + { 0x00000000, 0x00400000, 0x4b2 }, + { 0x00000000, 0xc0210a20, 0x000 }, + { 0x00000000, 0x14c00000, 0x4cb }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000216d, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0604800, 0x627 }, + { 0x00000000, 0x00400000, 0x4cf }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00040000, 0xc0294620, 0x000 }, + { 0x00000000, 0xc0600000, 0x622 }, + { 0x00000001, 0x00210222, 0x000 }, + { 0x00000000, 0x14c00000, 0x4d6 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0xcafebabe, 0x00404811, 0x000 }, + { 0x00000000, 0xc0204400, 0x000 }, + { 0x00000000, 0xc0404810, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x000021f8, 0x00204411, 0x000 }, + { 0x0000000e, 0x00204811, 0x000 }, + { 0x000421f9, 0x00604411, 0x622 }, + { 0x00000000, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x4d8 }, + { 0x00002180, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000003, 0x00333e2f, 0x000 }, + { 0x00000001, 0x00210221, 0x000 }, + { 0x00000000, 0x14e00000, 0x508 }, + { 0x0000002c, 0x00200a2d, 0x000 }, + { 0x00040000, 0x18e00c11, 0x4f7 }, + { 0x00000001, 0x00333e2f, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xd8c04800, 0x4eb }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000002d, 0x0020122d, 0x000 }, + { 0x00000000, 0x00290c83, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204802, 0x000 }, + { 0x00000000, 0x00204803, 0x000 }, + { 0x00000008, 0x00300a22, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000011, 0x00210224, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x00000000, 0x00400000, 0x4b2 }, + { 0x0000002c, 0xc0203620, 0x000 }, + { 0x0000002d, 0xc0403620, 0x000 }, + { 0x0000000f, 0x00210221, 0x000 }, + { 0x00000000, 0x14c00000, 0x50d }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00000000, 0xd9000000, 0x000 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0xb5000000, 0x00204411, 0x000 }, + { 0x00002000, 0x00204811, 0x000 }, + { 0xb6000000, 0x00204411, 0x000 }, + { 0x0000a000, 0x00204811, 0x000 }, + { 0xb7000000, 0x00204411, 0x000 }, + { 0x0000c000, 0x00204811, 0x000 }, + { 0xb8000000, 0x00204411, 0x000 }, + { 0x0000f8e0, 0x00204811, 0x000 }, + { 0xb9000000, 0x00204411, 0x000 }, + { 0x0000f880, 0x00204811, 0x000 }, + { 0xba000000, 0x00204411, 0x000 }, + { 0x0000e000, 0x00204811, 0x000 }, + { 0xbb000000, 0x00204411, 0x000 }, + { 0x0000f000, 0x00204811, 0x000 }, + { 0xbc000000, 0x00204411, 0x000 }, + { 0x0000f3fc, 0x00204811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000002, 0x00204811, 0x000 }, + { 0x000000ff, 0x00280e30, 0x000 }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x521 }, + { 0x00000000, 0xc0200800, 0x000 }, + { 0x00000000, 0x14c00000, 0x536 }, + { 0x00000000, 0x00200c11, 0x000 }, + { 0x0000001c, 0x00203623, 0x000 }, + { 0x0000002b, 0x00203623, 0x000 }, + { 0x00000029, 0x00203623, 0x000 }, + { 0x00000028, 0x00203623, 0x000 }, + { 0x00000017, 0x00203623, 0x000 }, + { 0x00000025, 0x00203623, 0x000 }, + { 0x00000026, 0x00203623, 0x000 }, + { 0x00000015, 0x00203623, 0x000 }, + { 0x00000016, 0x00203623, 0x000 }, + { 0xffffe000, 0x00200c11, 0x000 }, + { 0x00000021, 0x00203623, 0x000 }, + { 0x00000022, 0x00203623, 0x000 }, + { 0x00001fff, 0x00200c11, 0x000 }, + { 0x00000023, 0x00203623, 0x000 }, + { 0x00000024, 0x00203623, 0x000 }, + { 0xf1ffffff, 0x00283a2e, 0x000 }, + { 0x0000001a, 0xc0220e20, 0x000 }, + { 0x00000000, 0x0029386e, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000006, 0x00204811, 0x000 }, + { 0x0000002a, 0x40203620, 0x000 }, + { 0x87000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x0000a1f4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0x9d000000, 0x00204411, 0x000 }, + { 0x0000001f, 0x40214a20, 0x000 }, + { 0x96000000, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0200c00, 0x000 }, + { 0x00000000, 0xc0201000, 0x000 }, + { 0x0000001f, 0x00211624, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x0000001d, 0x00203623, 0x000 }, + { 0x00000003, 0x00281e23, 0x000 }, + { 0x00000008, 0x00222223, 0x000 }, + { 0xfffff000, 0x00282228, 0x000 }, + { 0x00000000, 0x002920e8, 0x000 }, + { 0x0000001f, 0x00203628, 0x000 }, + { 0x00000018, 0x00211e23, 0x000 }, + { 0x00000020, 0x00203627, 0x000 }, + { 0x00000002, 0x00221624, 0x000 }, + { 0x00000000, 0x003014a8, 0x000 }, + { 0x0000001e, 0x00203625, 0x000 }, + { 0x00000003, 0x00211a24, 0x000 }, + { 0x10000000, 0x00281a26, 0x000 }, + { 0xefffffff, 0x00283a2e, 0x000 }, + { 0x00000000, 0x004938ce, 0x610 }, + { 0x00000001, 0x40280a20, 0x000 }, + { 0x00000006, 0x40280e20, 0x000 }, + { 0x00000300, 0xc0281220, 0x000 }, + { 0x00000008, 0x00211224, 0x000 }, + { 0x00000000, 0xc0201620, 0x000 }, + { 0x00000000, 0xc0201a20, 0x000 }, + { 0x00000000, 0x00210222, 0x000 }, + { 0x00000000, 0x14c00000, 0x56c }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00002258, 0x00300a24, 0x000 }, + { 0x00040000, 0x00694622, 0x622 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204805, 0x000 }, + { 0x00020000, 0x00294a26, 0x000 }, + { 0x00000000, 0x00204810, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x574 }, + { 0x00000000, 0xc0201c10, 0x000 }, + { 0x00000000, 0xc0400000, 0x582 }, + { 0x00000002, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x574 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00002258, 0x00300a24, 0x000 }, + { 0x00040000, 0x00694622, 0x622 }, + { 0x00000000, 0xc0201c10, 0x000 }, + { 0x00000000, 0xc0400000, 0x582 }, + { 0x00000000, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x578 }, + { 0x00000000, 0xc0201c00, 0x000 }, + { 0x00000000, 0xc0400000, 0x582 }, + { 0x00000004, 0x002f0223, 0x000 }, + { 0x00000000, 0x0cc00000, 0x580 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x0000216d, 0x00204411, 0x000 }, + { 0x00000000, 0xc0204800, 0x000 }, + { 0x00000000, 0xc0604800, 0x627 }, + { 0x00000000, 0x00401c10, 0x582 }, + { 0x00000000, 0xc0200000, 0x000 }, + { 0x00000000, 0xc0400000, 0x000 }, + { 0x00000000, 0x0ee00000, 0x584 }, + { 0x00000000, 0x00600000, 0x5c3 }, + { 0x00000000, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x592 }, + { 0x0000a2b7, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x00000033, 0x0020262d, 0x000 }, + { 0x0000001a, 0x00212229, 0x000 }, + { 0x00000006, 0x00222629, 0x000 }, + { 0x0000a2c4, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x590 }, + { 0x0000a2d1, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d1, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x00000001, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x5a0 }, + { 0x0000a2bb, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x00000034, 0x0020262d, 0x000 }, + { 0x0000001a, 0x00212229, 0x000 }, + { 0x00000006, 0x00222629, 0x000 }, + { 0x0000a2c5, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x59e }, + { 0x0000a2d2, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d2, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x00000002, 0x002f0224, 0x000 }, + { 0x00000000, 0x0cc00000, 0x5ae }, + { 0x0000a2bf, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x00000035, 0x0020262d, 0x000 }, + { 0x0000001a, 0x00212229, 0x000 }, + { 0x00000006, 0x00222629, 0x000 }, + { 0x0000a2c6, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x5ac }, + { 0x0000a2d3, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d3, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x0000a2c3, 0x00204411, 0x000 }, + { 0x00000000, 0x00204807, 0x000 }, + { 0x00000036, 0x0020262d, 0x000 }, + { 0x0000001a, 0x00212229, 0x000 }, + { 0x00000006, 0x00222629, 0x000 }, + { 0x0000a2c7, 0x00204411, 0x000 }, + { 0x00000000, 0x003048e9, 0x000 }, + { 0x00000000, 0x00e00000, 0x5b8 }, + { 0x0000a2d4, 0x00204411, 0x000 }, + { 0x00000000, 0x00404808, 0x000 }, + { 0x0000a2d4, 0x00204411, 0x000 }, + { 0x00000001, 0x00504a28, 0x000 }, + { 0x85000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204801, 0x000 }, + { 0x0000304a, 0x00204411, 0x000 }, + { 0x01000000, 0x00204811, 0x000 }, + { 0x00000000, 0x00400000, 0x5be }, + { 0xa4000000, 0xc0204411, 0x000 }, + { 0x00000000, 0xc0404800, 0x000 }, + { 0x00000000, 0xc0600000, 0x5c3 }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x0000003f, 0x00204811, 0x000 }, + { 0x00000005, 0x00204811, 0x000 }, + { 0x0000a1f4, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x88000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0xff000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x00000002, 0x00804811, 0x000 }, + { 0x00000000, 0x0ee00000, 0x5d6 }, + { 0x00001000, 0x00200811, 0x000 }, + { 0x0000002b, 0x00203622, 0x000 }, + { 0x00000000, 0x00600000, 0x5da }, + { 0x00000000, 0x00600000, 0x5c3 }, + { 0x98000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00804811, 0x000 }, + { 0x00000000, 0xc0600000, 0x5da }, + { 0x00000000, 0xc0400400, 0x001 }, + { 0x0000a2a4, 0x00204411, 0x000 }, + { 0x00000022, 0x00204811, 0x000 }, + { 0x89000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00404811, 0x5cd }, + { 0x97000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x8a000000, 0x00204411, 0x000 }, + { 0x00000000, 0x00404811, 0x5cd }, + { 0x00000000, 0x00600000, 0x5f3 }, + { 0x0001a2a4, 0xc0204411, 0x000 }, + { 0x00000016, 0x00604811, 0x374 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00010000, 0x00204811, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x09800000, 0x00204811, 0x000 }, + { 0xffffffff, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x0004217f, 0x00604411, 0x622 }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x000 }, + { 0x00000004, 0x00404c11, 0x5ed }, + { 0x00000000, 0x00400000, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000004, 0x00291e27, 0x000 }, + { 0x00000017, 0x00803627, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0xfffffffb, 0x00281e27, 0x000 }, + { 0x00000017, 0x00803627, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0x00000008, 0x00291e27, 0x000 }, + { 0x00000017, 0x00803627, 0x000 }, + { 0x00000017, 0x00201e2d, 0x000 }, + { 0xfffffff7, 0x00281e27, 0x000 }, + { 0x00000017, 0x00803627, 0x000 }, + { 0x0001a2a4, 0x00204411, 0x000 }, + { 0x00000016, 0x00604811, 0x374 }, + { 0x00002010, 0x00204411, 0x000 }, + { 0x00010000, 0x00204811, 0x000 }, + { 0x0000217c, 0x00204411, 0x000 }, + { 0x01800000, 0x00204811, 0x000 }, + { 0xffffffff, 0x00204811, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000000, 0x17000000, 0x000 }, + { 0x81000000, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0004217f, 0x00604411, 0x622 }, + { 0x0000001f, 0x00210230, 0x000 }, + { 0x00000000, 0x14c00000, 0x621 }, + { 0x00000010, 0x00404c11, 0x607 }, + { 0x00000000, 0xc0200400, 0x000 }, + { 0x00000000, 0x38c00000, 0x000 }, + { 0x0000001d, 0x00200a2d, 0x000 }, + { 0x0000001e, 0x00200e2d, 0x000 }, + { 0x0000001f, 0x0020122d, 0x000 }, + { 0x00000020, 0x0020162d, 0x000 }, + { 0x00002169, 0x00204411, 0x000 }, + { 0x00000000, 0x00204804, 0x000 }, + { 0x00000000, 0x00204805, 0x000 }, + { 0x00000000, 0x00204801, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000004, 0x00301224, 0x000 }, + { 0x00000000, 0x002f0064, 0x000 }, + { 0x00000000, 0x0cc00000, 0x620 }, + { 0x00000003, 0x00281a22, 0x000 }, + { 0x00000008, 0x00221222, 0x000 }, + { 0xfffff000, 0x00281224, 0x000 }, + { 0x00000000, 0x002910c4, 0x000 }, + { 0x0000001f, 0x00403624, 0x000 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x1ac00000, 0x622 }, + { 0x9f000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000000, 0x1ae00000, 0x625 }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x1ac00000, 0x627 }, + { 0x9e000000, 0x00204411, 0x000 }, + { 0xcafebabe, 0x00204811, 0x000 }, + { 0x00000000, 0x1ae00000, 0x62a }, + { 0x00000000, 0x00800000, 0x000 }, + { 0x00000000, 0x00600000, 0x00b }, + { 0x00001000, 0x00600411, 0x315 }, + { 0x00000000, 0x00200411, 0x000 }, + { 0x00000000, 0x00600811, 0x1b2 }, + { 0x0000225c, 0x00204411, 0x000 }, + { 0x00000003, 0x00204811, 0x000 }, + { 0x00002256, 0x00204411, 0x000 }, + { 0x0000001b, 0x00204811, 0x000 }, + { 0x0000a1fc, 0x00204411, 0x000 }, + { 0x00000001, 0x00204811, 0x000 }, + { 0x0001a1fd, 0xc0204411, 0x000 }, + { 0x00000021, 0x00201e2d, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000024, 0x0020222d, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000022, 0x0020222d, 0x000 }, + { 0x0000ffff, 0x00282228, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00204811, 0x000 }, + { 0x00000023, 0x00201e2d, 0x000 }, + { 0x00000010, 0x00221e27, 0x000 }, + { 0x00000000, 0x00294907, 0x000 }, + { 0x00000000, 0x00404811, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x00000000, 0x00000000, 0x000 }, + { 0x0142050a, 0x05ba0250, 0x000 }, + { 0x01c30168, 0x044105ba, 0x000 }, + { 0x02250209, 0x02500151, 0x000 }, + { 0x02230245, 0x02a00241, 0x000 }, + { 0x03d705ba, 0x05ba05ba, 0x000 }, + { 0x05e205e3, 0x031f05ba, 0x000 }, + { 0x032005bf, 0x0320034a, 0x000 }, + { 0x03340282, 0x034c033e, 0x000 }, + { 0x05ba05ba, 0x05ba05ba, 0x000 }, + { 0x05ba0557, 0x05ba032a, 0x000 }, + { 0x03bc05ba, 0x04c3034e, 0x000 }, + { 0x04a20455, 0x043f05ba, 0x000 }, + { 0x04d805ba, 0x044304e5, 0x000 }, + { 0x0455050f, 0x035b037b, 0x000 }, + { 0x05ba05ba, 0x05ba05ba, 0x000 }, + { 0x05ba05ba, 0x05ba05ba, 0x000 }, + { 0x05ba05ba, 0x05d805c1, 0x000 }, + { 0x05ba05ba, 0x000705ba, 0x000 }, + { 0x05ba05ba, 0x05ba05ba, 0x000 }, + { 0x05ba05ba, 0x05ba05ba, 0x000 }, + { 0x03f803ed, 0x04080406, 0x000 }, + { 0x040e040a, 0x040c0410, 0x000 }, + { 0x041c0418, 0x04240420, 0x000 }, + { 0x042c0428, 0x04340430, 0x000 }, + { 0x05ba05ba, 0x043a0438, 0x000 }, + { 0x05ba05ba, 0x05ba05ba, 0x000 }, + { 0x05ba05ba, 0x05ba05ba, 0x000 }, + { 0x0002060e, 0x062c0006, 0x000 }, +}; + +static const u32 RS780_pfp_microcode[] = { +0xca0400, +0xa00000, +0x7e828b, +0x7c038b, +0x8001db, +0x7c038b, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xc41838, +0xca2400, +0xca2800, +0x9581cb, +0xc41c3a, +0xc3c000, +0xca0800, +0xca0c00, +0x7c744b, +0xc20005, +0x99c000, +0xc41c3a, +0x7c744c, +0xc0ffe0, +0x042c08, +0x309002, +0x7d2500, +0x351402, +0x7d350b, +0x255407, +0x7cd580, +0x259c07, +0x95c004, +0xd5001b, +0x7eddc1, +0x7d9d80, +0xd6801b, +0xd5801b, +0xd4401e, +0xd5401e, +0xd6401e, +0xd6801e, +0xd4801e, +0xd4c01e, +0x9783d3, +0xd5c01e, +0xca0800, +0x80001a, +0xca0c00, +0xe4011e, +0xd4001e, +0x80000c, +0xc41838, +0xe4013e, +0xd4001e, +0x80000c, +0xc41838, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xe4011e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xe4013e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xca0800, +0xca0c00, +0x8001db, +0xd48024, +0xca0800, +0x7c00c0, +0xc81425, +0xc81824, +0x7c9488, +0x7c9880, +0xc20003, +0xd40075, +0x7c744c, +0x800064, +0xd4401e, +0xca1800, +0xd4401e, +0xd5801e, +0x800062, +0xd40075, +0xd4401e, +0xca0800, +0xca0c00, +0xca1000, +0xd48019, +0xd4c018, +0xd50017, +0xd4801e, +0xd4c01e, +0xd5001e, +0xe2001e, +0xca0400, +0xa00000, +0x7e828b, +0xd40075, +0xd4401e, +0xca0800, +0xca0c00, +0xca1000, +0xd48019, +0xd4c018, +0xd50017, +0xd4801e, +0xd4c01e, +0xd5001e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xca0800, +0x248c01, +0xd48060, +0x94c003, +0x041001, +0x041002, +0xd50025, +0xd4401e, +0x800000, +0xd4801e, +0xca0800, +0xd48061, +0xd4401e, +0x800000, +0xd4801e, +0xca0800, +0xca0c00, +0xd4401e, +0xd48016, +0xd4c016, +0xd4801e, +0x8001db, +0xd4c01e, +0xc60843, +0xca0c00, +0xca1000, +0x948004, +0xca1400, +0xe420f3, +0xd42013, +0xd56065, +0xd4e01c, +0xd5201c, +0xd5601c, +0x800000, +0x062001, +0xc60843, +0xca0c00, +0xca1000, +0x9483f7, +0xca1400, +0xe420f3, +0x80009c, +0xd42013, +0xc60843, +0xca0c00, +0xca1000, +0x9883ef, +0xca1400, +0xd40064, +0x8000b0, +0x000000, +0xc41432, +0xc61843, +0xc4082f, +0x954005, +0xc40c30, +0xd4401e, +0x800000, +0xee001e, +0x9583f5, +0xc41031, +0xd44033, +0xd52065, +0xd4a01c, +0xd4e01c, +0xd5201c, +0xe4015e, +0xd4001e, +0x800000, +0x062001, +0xca1800, +0x0a2001, +0xd60076, +0xc40836, +0x988007, +0xc61045, +0x950110, +0xd4001f, +0xd46062, +0x800000, +0xd42062, +0xcc3835, +0xcc1433, +0x8401de, +0xd40072, +0xd5401e, +0x800000, +0xee001e, +0xe2001a, +0x8401de, +0xe2001a, +0xcc104b, +0xcc0447, +0x2c9401, +0x7d098b, +0x984005, +0x7d15cb, +0xd4001a, +0x8001db, +0xd4006d, +0x344401, +0xcc0c48, +0x98403a, +0xcc2c4a, +0x958004, +0xcc0449, +0x8001db, +0xd4001a, +0xd4c01a, +0x282801, +0x840113, +0xcc1003, +0x98801b, +0x04380c, +0x840113, +0xcc1003, +0x988017, +0x043808, +0x840113, +0xcc1003, +0x988013, +0x043804, +0x840113, +0xcc1003, +0x988014, +0xcc104c, +0x9a8009, +0xcc144d, +0x9840dc, +0xd4006d, +0xcc1848, +0xd5001a, +0xd5401a, +0x8000ec, +0xd5801a, +0x96c0d5, +0xd4006d, +0x8001db, +0xd4006e, +0x9ac003, +0xd4006d, +0xd4006e, +0x800000, +0xec007f, +0x9ac0cc, +0xd4006d, +0x8001db, +0xd4006e, +0xcc1403, +0xcc1803, +0xcc1c03, +0x7d9103, +0x7dd583, +0x7d190c, +0x35cc1f, +0x35701f, +0x7cf0cb, +0x7cd08b, +0x880000, +0x7e8e8b, +0x95c004, +0xd4006e, +0x8001db, +0xd4001a, +0xd4c01a, +0xcc0803, +0xcc0c03, +0xcc1003, +0xcc1403, +0xcc1803, +0xcc1c03, +0xcc2403, +0xcc2803, +0x35c41f, +0x36b01f, +0x7c704b, +0x34f01f, +0x7c704b, +0x35701f, +0x7c704b, +0x7d8881, +0x7dccc1, +0x7e5101, +0x7e9541, +0x7c9082, +0x7cd4c2, +0x7c848b, +0x9ac003, +0x7c8c8b, +0x2c8801, +0x98809e, +0xd4006d, +0x98409c, +0xd4006e, +0xcc084c, +0xcc0c4d, +0xcc1048, +0xd4801a, +0xd4c01a, +0x800124, +0xd5001a, +0xcc0832, +0xd40032, +0x9482b6, +0xca0c00, +0xd4401e, +0x800000, +0xd4001e, +0xe4011e, +0xd4001e, +0xca0800, +0xca0c00, +0xca1000, +0xd4401e, +0xca1400, +0xd4801e, +0xd4c01e, +0xd5001e, +0xd5401e, +0xd54034, +0x800000, +0xee001e, +0x280404, +0xe2001a, +0xe2001a, +0xd4401a, +0xca3800, +0xcc0803, +0xcc0c03, +0xcc0c03, +0xcc0c03, +0x98829a, +0x000000, +0x8401de, +0xd7a06f, +0x800000, +0xee001f, +0xca0400, +0xc2ff00, +0xcc0834, +0xc13fff, +0x7c74cb, +0x7cc90b, +0x7d010f, +0x99028d, +0x7c738b, +0x8401de, +0xd7a06f, +0x800000, +0xee001f, +0xca0800, +0x281900, +0x7d898b, +0x958014, +0x281404, +0xca0c00, +0xca1000, +0xca1c00, +0xca2400, +0xe2001f, +0xd4c01a, +0xd5001a, +0xd5401a, +0xcc1803, +0xcc2c03, +0xcc2c03, +0xcc2c03, +0x7da58b, +0x7d9c47, +0x984274, +0x000000, +0x800184, +0xd4c01a, +0xd4401e, +0xd4801e, +0x800000, +0xee001e, +0xe4011e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xe4013e, +0xd4001e, +0xd4401e, +0xee001e, +0xca0400, +0xa00000, +0x7e828b, +0xca0800, +0x248c06, +0x0ccc06, +0x98c006, +0xcc104e, +0x990004, +0xd40073, +0xe4011e, +0xd4001e, +0xd4401e, +0xd4801e, +0x800000, +0xee001e, +0xca0800, +0xca0c00, +0x34d018, +0x251001, +0x950021, +0xc17fff, +0xca1000, +0xca1400, +0xca1800, +0xd4801d, +0xd4c01d, +0x7db18b, +0xc14202, +0xc2c001, +0xd5801d, +0x34dc0e, +0x7d5d4c, +0x7f734c, +0xd7401e, +0xd5001e, +0xd5401e, +0xc14200, +0xc2c000, +0x099c01, +0x31dc10, +0x7f5f4c, +0x7f734c, +0x042802, +0x7d8380, +0xd5a86f, +0xd58066, +0xd7401e, +0xec005e, +0xc82402, +0xc82402, +0x8001db, +0xd60076, +0xd4401e, +0xd4801e, +0xd4c01e, +0x800000, +0xee001e, +0x800000, +0xee001f, +0xd4001f, +0x800000, +0xd4001f, +0xd4001f, +0x880000, +0xd4001f, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x000000, +0x010194, +0x02019b, +0x0300b2, +0x0400a2, +0x050003, +0x06003f, +0x070032, +0x08014f, +0x090046, +0x0a0036, +0x1001d9, +0x1700c5, +0x22015d, +0x23016c, +0x2000d7, +0x240148, +0x26004d, +0x27005c, +0x28008d, +0x290051, +0x2a007e, +0x2b0061, +0x2f0088, +0x3200aa, +0x3401a2, +0x36006f, +0x3c0179, +0x3f0095, +0x4101af, +0x440151, +0x550196, +0x56019d, +0x60000b, +0x610034, +0x620038, +0x630038, +0x640038, +0x650038, +0x660038, +0x670038, +0x68003a, +0x690041, +0x6a0048, +0x6b0048, +0x6c0048, +0x6d0048, +0x6e0048, +0x6f0048, +0x7301d9, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +0x000006, +}; + +static const u32 RV770_cp_microcode[] = { +0xcc0003ea, +0x7c408000, +0xa0000000, +0xcc800062, +0x80000001, +0xd040007f, +0x80000001, +0xcc400041, +0x7c40c000, +0xc0160004, +0x30d03fff, +0x7d15000c, +0xcc110000, +0x28d8001e, +0x31980001, +0x28dc001f, +0xc8200004, +0x95c00006, +0x7c424000, +0xcc000062, +0x7e56800c, +0xcc290000, +0xc8240004, +0x7e26000b, +0x95800006, +0x7c42c000, +0xcc000062, +0x7ed7000c, +0xcc310000, +0xc82c0004, +0x7e2e000c, +0xcc000062, +0x31103fff, +0x80000001, +0xce110000, +0x7c40c000, +0x80000001, +0xcc400040, +0x80000001, +0xcc412257, +0x7c418000, +0xcc400045, +0xcc400048, +0xcc41225c, +0xcc41a1fc, +0x7c408000, +0xa0000000, +0xcc800062, +0xcc400045, +0xcc400048, +0x7c40c000, +0xcc41225c, +0xcc41a1fc, +0x7c408000, +0xa0000000, +0xcc800062, +0xcc000045, +0xcc000048, +0xcc41225c, +0xcc41a1fc, +0x7c408000, +0xa0000000, +0xcc800062, +0x040ca1fd, +0xc0120001, +0xcc000045, +0xcc000048, +0x7cd0c00c, +0xcc41225c, +0xcc41a1fc, +0xd04d0000, +0x7c408000, +0xa0000000, +0xcc800062, +0x80000001, +0xcc41225d, +0x7c408000, +0x7c40c000, +0xc02a0002, +0x7c410000, +0x7d29000c, +0x30940001, +0x30980006, +0x309c0300, +0x29dc0008, +0x7c420000, +0x7c424000, +0x9540000f, +0xc02e0004, +0x05f02258, +0x7f2f000c, +0xcc310000, +0xc8280004, +0xccc12169, +0xcd01216a, +0xce81216b, +0x0db40002, +0xcc01216c, +0x9740000e, +0x0db40000, +0x8000007b, +0xc834000a, +0x0db40002, +0x97400009, +0x0db40000, +0xc02e0004, +0x05f02258, +0x7f2f000c, +0xcc310000, +0xc8280004, +0x8000007b, +0xc834000a, +0x97400004, +0x7e028000, +0x8000007b, +0xc834000a, +0x0db40004, +0x9740ff8c, +0x00000000, +0xce01216d, +0xce41216e, +0xc8280003, +0xc834000a, +0x9b400004, +0x043c0005, +0x8400026d, +0xcc000062, +0x0df40000, +0x9740000b, +0xc82c03e6, +0xce81a2b7, +0xc0300006, +0x7ef34028, +0xc0300020, +0x7f6b8020, +0x7fb3c029, +0xcf81a2c4, +0x80000001, +0xcfc1a2d1, +0x0df40001, +0x9740000b, +0xc82c03e7, +0xce81a2bb, +0xc0300006, +0x7ef34028, +0xc0300020, +0x7f6b8020, +0x7fb3c029, +0xcf81a2c5, +0x80000001, +0xcfc1a2d2, +0x0df40002, +0x9740000b, +0xc82c03e8, +0xce81a2bf, +0xc0300006, +0x7ef34028, +0xc0300020, +0x7f6b8020, +0x7fb3c029, +0xcf81a2c6, +0x80000001, +0xcfc1a2d3, +0xc82c03e9, +0xce81a2c3, +0xc0300006, +0x7ef34028, +0xc0300020, +0x7f6b8020, +0x7fb3c029, +0xcf81a2c7, +0x80000001, +0xcfc1a2d4, +0x80000001, +0xcc400042, +0x7c40c000, +0x7c410000, +0x2914001d, +0x31540001, +0x9940000d, +0x31181000, +0xc81c0011, +0x09dc0001, +0x95c0ffff, +0xc81c0011, +0xccc12100, +0xcd012101, +0xccc12102, +0xcd012103, +0x04180004, +0x8000039f, +0xcd81a2a4, +0xc02a0004, +0x95800008, +0x36a821a3, +0xcc290000, +0xc8280004, +0xc81c0011, +0x0de40040, +0x9640ffff, +0xc81c0011, +0xccc12170, +0xcd012171, +0xc8200012, +0x96000000, +0xc8200012, +0x8000039f, +0xcc000064, +0x7c40c000, +0x7c410000, +0xcc000045, +0xcc000048, +0x40d40003, +0xcd41225c, +0xcd01a1fc, +0xc01a0001, +0x041ca1fd, +0x7dd9c00c, +0x7c420000, +0x08cc0001, +0x06240001, +0x06280002, +0xce1d0000, +0xce5d0000, +0x98c0fffa, +0xce9d0000, +0x7c408000, +0xa0000000, +0xcc800062, +0x7c40c000, +0x30d00001, +0x28cc0001, +0x7c414000, +0x95000006, +0x7c418000, +0xcd41216d, +0xcd81216e, +0x800000f3, +0xc81c0003, +0xc0220004, +0x7e16000c, +0xcc210000, +0xc81c0004, +0x7c424000, +0x98c00004, +0x7c428000, +0x80000001, +0xcde50000, +0xce412169, +0xce81216a, +0xcdc1216b, +0x80000001, +0xcc01216c, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0x7c41c000, +0x28a40008, +0x326400ff, +0x0e68003c, +0x9680000a, +0x7c020000, +0x7c420000, +0x1e300003, +0xcc00006a, +0x9b000003, +0x42200005, +0x04200040, +0x80000110, +0x7c024000, +0x7e024000, +0x9a400000, +0x0a640001, +0x30ec0010, +0x9ac0000a, +0xcc000062, +0xc02a0004, +0xc82c0021, +0x7e92800c, +0xcc000041, +0xcc290000, +0xcec00021, +0x80000120, +0xc8300004, +0xcd01216d, +0xcd41216e, +0xc8300003, +0x7f1f000b, +0x30f40007, +0x27780001, +0x9740002a, +0x07b80125, +0x9f800000, +0x00000000, +0x80000135, +0x7f1b8004, +0x80000139, +0x7f1b8005, +0x8000013d, +0x7f1b8002, +0x80000141, +0x7f1b8003, +0x80000145, +0x7f1b8007, +0x80000149, +0x7f1b8006, +0x8000014e, +0x28a40008, +0x9b800019, +0x28a40008, +0x8000015e, +0x326400ff, +0x9b800015, +0x28a40008, +0x8000015e, +0x326400ff, +0x9b800011, +0x28a40008, +0x8000015e, +0x326400ff, +0x9b80000d, +0x28a40008, +0x8000015e, +0x326400ff, +0x9b800009, +0x28a40008, +0x8000015e, +0x326400ff, +0x9b800005, +0x28a40008, +0x8000015e, +0x326400ff, +0x28a40008, +0x326400ff, +0x0e68003c, +0x9a80feb1, +0x28ec0008, +0x7c434000, +0x7c438000, +0x7c43c000, +0x96c00007, +0xcc000062, +0xcf412169, +0xcf81216a, +0xcfc1216b, +0x80000001, +0xcc01216c, +0x80000001, +0xcff50000, +0xcc00006b, +0x840003a2, +0x0e68003c, +0x9a800004, +0xc8280015, +0x80000001, +0xd040007f, +0x9680ffab, +0x7e024000, +0x8400023b, +0xc00e0002, +0xcc000041, +0x80000239, +0xccc1304a, +0x7c40c000, +0x7c410000, +0xc01e0001, +0x29240012, +0xc0220002, +0x96400005, +0xc0260004, +0xc027fffb, +0x7d25000b, +0xc0260000, +0x7dd2800b, +0x7e12c00b, +0x7d25000c, +0x7c414000, +0x7c418000, +0xccc12169, +0x9a80000a, +0xcd01216a, +0xcd41216b, +0x96c0fe82, +0xcd81216c, +0xc8300018, +0x97000000, +0xc8300018, +0x80000001, +0xcc000018, +0x840003a2, +0xcc00007f, +0xc8140013, +0xc8180014, +0xcd41216b, +0x96c0fe76, +0xcd81216c, +0x80000182, +0xc8300018, +0xc80c0008, +0x98c00000, +0xc80c0008, +0x7c410000, +0x95000002, +0x00000000, +0x7c414000, +0xc8200009, +0xcc400043, +0xce01a1f4, +0xcc400044, +0xc00e8000, +0x7c424000, +0x7c428000, +0x2aac001f, +0x96c0fe63, +0xc035f000, +0xce4003e2, +0x32780003, +0x267c0008, +0x7ff7c00b, +0x7ffbc00c, +0x2a780018, +0xcfc003e3, +0xcf8003e4, +0x26b00002, +0x7f3f0000, +0xcf0003e5, +0x8000031f, +0x7c80c000, +0x7c40c000, +0x28d00008, +0x3110000f, +0x9500000f, +0x25280001, +0x06a801b3, +0x9e800000, +0x00000000, +0x800001d4, +0xc0120800, +0x800001e2, +0xc814000f, +0x800001e9, +0xc8140010, +0x800001f0, +0xccc1a2a4, +0x800001f9, +0xc8140011, +0x30d0003f, +0x0d280015, +0x9a800012, +0x0d28001e, +0x9a80001e, +0x0d280020, +0x9a800023, +0x0d24000f, +0x0d280010, +0x7e6a800c, +0x9a800026, +0x0d200004, +0x0d240014, +0x0d280028, +0x7e62400c, +0x7ea6800c, +0x9a80002a, +0xc8140011, +0x80000001, +0xccc1a2a4, +0xc0120800, +0x7c414000, +0x7d0cc00c, +0xc0120008, +0x29580003, +0x295c000c, +0x7c420000, +0x7dd1c00b, +0x26200014, +0x7e1e400c, +0x7e4e800c, +0xce81a2a4, +0x80000001, +0xcd81a1fe, +0xc814000f, +0x0410210e, +0x95400000, +0xc814000f, +0xd0510000, +0x80000001, +0xccc1a2a4, +0xc8140010, +0x04102108, +0x95400000, +0xc8140010, +0xd0510000, +0x80000001, +0xccc1a2a4, +0xccc1a2a4, +0x04100001, +0xcd000019, +0x840003a2, +0xcc00007f, +0xc8100019, +0x99000000, +0xc8100019, +0x80000002, +0x7c408000, +0x04102100, +0x09540001, +0x9540ffff, +0xc8140011, +0xd0510000, +0x8000039f, +0xccc1a2a4, +0x7c40c000, +0xcc40000d, +0x94c0fdff, +0xcc40000e, +0x7c410000, +0x95000005, +0x08cc0001, +0xc8140005, +0x99400014, +0x00000000, +0x98c0fffb, +0x7c410000, +0x80000002, +0x7d008000, +0xc8140005, +0x7c40c000, +0x9940000c, +0xc818000c, +0x7c410000, +0x9580fdee, +0xc820000e, +0xc81c000d, +0x66200020, +0x7e1e002c, +0x25240002, +0x7e624020, +0x80000001, +0xcce60000, +0x7c410000, +0xcc00006c, +0xcc00006d, +0xc818001f, +0xc81c001e, +0x65980020, +0x7dd9c02c, +0x7cd4c00c, +0xccde0000, +0x45dc0004, +0xc8280017, +0x9680000f, +0xc00e0001, +0x28680008, +0x2aac0016, +0x32a800ff, +0x0eb00049, +0x7f2f000b, +0x97000006, +0x00000000, +0xc8140005, +0x7c40c000, +0x80000223, +0x7c410000, +0x80000226, +0xd040007f, +0x8400023b, +0xcc000041, +0xccc1304a, +0x94000000, +0xc83c001a, +0x043c0005, +0xcfc1a2a4, +0xc0361f90, +0xc0387fff, +0x7c03c010, +0x7f7b400c, +0xcf41217c, +0xcfc1217d, +0xcc01217e, +0xc03a0004, +0x0434217f, +0x7f7b400c, +0xcc350000, +0xc83c0004, +0x2bfc001f, +0x04380020, +0x97c00005, +0xcc000062, +0x9b800000, +0x0bb80001, +0x80000247, +0xcc000071, +0xcc01a1f4, +0x04380016, +0xc0360002, +0xcf81a2a4, +0x88000000, +0xcf412010, +0x7c40c000, +0x28d0001c, +0x95000005, +0x04d40001, +0xcd400065, +0x80000001, +0xcd400068, +0x09540002, +0x80000001, +0xcd400066, +0x8400026c, +0xc81803ea, +0x7c40c000, +0x9980fd9d, +0xc8140016, +0x08d00001, +0x9940002b, +0xcd000068, +0x7c408000, +0xa0000000, +0xcc800062, +0x043c0005, +0xcfc1a2a4, +0xcc01a1f4, +0x840003a2, +0xcc000046, +0x88000000, +0xcc00007f, +0x8400027e, +0xc81803ea, +0x7c40c000, +0x9980fd8b, +0xc8140016, +0x08d00001, +0x99400019, +0xcd000068, +0x7c408000, +0xa0000000, +0xcc800062, +0x043c0022, +0xcfc1a2a4, +0x840003a2, +0xcc000047, +0x88000000, +0xcc00007f, +0xc8100016, +0x9900000d, +0xcc400067, +0x80000002, +0x7c408000, +0xc81803ea, +0x9980fd77, +0x7c40c000, +0x94c00003, +0xc8100016, +0x99000004, +0xccc00068, +0x80000002, +0x7c408000, +0x8400023b, +0xc0148000, +0xcc000041, +0xcd41304a, +0xc0148000, +0x99000000, +0xc8100016, +0x80000002, +0x7c408000, +0xc0120001, +0x7c51400c, +0x80000001, +0xd0550000, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0x291c001f, +0xccc0004a, +0xcd00004b, +0x95c00003, +0xc01c8000, +0xcdc12010, +0xdd830000, +0x055c2000, +0xcc000062, +0x80000001, +0xd81f4100, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0xccc0004c, +0xcd00004d, +0xdd830000, +0x055ca000, +0x80000001, +0xd81f4100, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0xccc0004e, +0xcd00004f, +0xdd830000, +0x055cc000, +0x80000001, +0xd81f4100, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0xccc00050, +0xcd000051, +0xdd830000, +0x055cf8e0, +0x80000001, +0xd81f4100, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0xccc00052, +0xcd000053, +0xdd830000, +0x055cf880, +0x80000001, +0xd81f4100, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0xccc00054, +0xcd000055, +0xdd830000, +0x055ce000, +0x80000001, +0xd81f4100, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0xccc00056, +0xcd000057, +0xdd830000, +0x055cf000, +0x80000001, +0xd81f4100, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0xccc00058, +0xcd000059, +0xdd830000, +0x055cf3fc, +0x80000001, +0xd81f4100, +0xd0432000, +0x7c408000, +0xa0000000, +0xcc800062, +0xd043a000, +0x7c408000, +0xa0000000, +0xcc800062, +0xd043c000, +0x7c408000, +0xa0000000, +0xcc800062, +0xd043f8e0, +0x7c408000, +0xa0000000, +0xcc800062, +0xd043f880, +0x7c408000, +0xa0000000, +0xcc800062, +0xd043e000, +0x7c408000, +0xa0000000, +0xcc800062, +0xd043f000, +0x7c408000, +0xa0000000, +0xcc800062, +0xd043f3fc, +0x7c408000, +0xa0000000, +0xcc800062, +0xc81403e0, +0xcc430000, +0xcc430000, +0xcc430000, +0x7d45c000, +0xcdc30000, +0xd0430000, +0x7c408000, +0xa0000000, +0xcc800062, +0x7c40c000, +0xc81003e2, +0xc81403e5, +0xc81803e3, +0xc81c03e4, +0xcd812169, +0xcdc1216a, +0xccc1216b, +0xcc01216c, +0x04200004, +0x7da18000, +0x7d964002, +0x9640fcd7, +0xcd8003e3, +0x31280003, +0xc02df000, +0x25180008, +0x7dad800b, +0x7da9800c, +0x80000001, +0xcd8003e3, +0x308cffff, +0xd04d0000, +0x7c408000, +0xa0000000, +0xcc800062, +0x7c40c000, +0x7c410000, +0x29240018, +0x32640001, +0x9a400013, +0xc8140020, +0x15580002, +0x9580ffff, +0xc8140020, +0xcc00006e, +0xccc12180, +0xcd01218d, +0xcc412181, +0x2914001f, +0x34588000, +0xcd81218c, +0x9540fcb9, +0xcc412182, +0xc8140020, +0x9940ffff, +0xc8140020, +0x80000002, +0x7c408000, +0x7c414000, +0x7c418000, +0x7c41c000, +0x65b40020, +0x7f57402c, +0xd4378100, +0x47740004, +0xd4378100, +0x47740004, +0xd4378100, +0x47740004, +0x09dc0004, +0xd4378100, +0x99c0fff8, +0x47740004, +0x2924001f, +0xc0380019, +0x9640fca1, +0xc03e0004, +0xcf8121f8, +0x37e021f9, +0xcc210000, +0xc8200004, +0x2a200018, +0x32200001, +0x9a00fffb, +0xcf8121f8, +0x80000002, +0x7c408000, +0x7c40c000, +0x28d00018, +0x31100001, +0xc0160080, +0x95000003, +0xc02a0004, +0x7cd4c00c, +0xccc1217c, +0xcc41217d, +0xcc41217e, +0x7c418000, +0x1db00003, +0x36a0217f, +0x9b000003, +0x419c0005, +0x041c0040, +0x99c00000, +0x09dc0001, +0xcc210000, +0xc8240004, +0x2a6c001f, +0x419c0005, +0x9ac0fffa, +0xcc800062, +0x80000002, +0x7c408000, +0x7c40c000, +0x04d403e6, +0x80000001, +0xcc540000, +0x8000039f, +0xcc4003ea, +0xc01c8000, +0x044ca000, +0xcdc12010, +0x7c410000, +0xc8140009, +0x04180000, +0x041c0008, +0xcd800071, +0x09dc0001, +0x05980001, +0xcd0d0000, +0x99c0fffc, +0xcc800062, +0x8000039f, +0xcd400071, +0xc00e0100, +0xcc000041, +0xccc1304a, +0xc83c007f, +0xcc00007f, +0x80000001, +0xcc00007f, +0xcc00007f, +0x88000000, +0xcc00007f, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00010333, +0x00100004, +0x00170006, +0x00210008, +0x00270028, +0x00280023, +0x00290029, +0x002a0026, +0x002b0029, +0x002d0038, +0x002e003f, +0x002f004a, +0x0034004c, +0x00360030, +0x003900af, +0x003a00d0, +0x003b00e5, +0x003c00fd, +0x003d016c, +0x003f00ad, +0x00410338, +0x0043036c, +0x0044018f, +0x004500fd, +0x004601ad, +0x004701ad, +0x00480200, +0x0049020e, +0x004a0257, +0x004b0284, +0x00520261, +0x00530273, +0x00540289, +0x0057029b, +0x0060029f, +0x006102ae, +0x006202b8, +0x006302c2, +0x006402cc, +0x006502d6, +0x006602e0, +0x006702ea, +0x006802f4, +0x006902f8, +0x006a02fc, +0x006b0300, +0x006c0304, +0x006d0308, +0x006e030c, +0x006f0310, +0x00700314, +0x00720386, +0x0074038c, +0x0079038a, +0x007c031e, +0x000f039b, +0x000f039b, +0x000f039b, +0x000f039b, +0x000f039b, +0x000f039b, +0x000f039b, +0x000f039b, +0x000f039b, +0x000f039b, +0x000f039b, +0x000f039b, +0x000f039b, +0x000f039b, +0x000f039b, +0x000f039b, +0x000f039b, +0x000f039b, +0x000f039b, +0x000f039b, +0x000f039b, +0x000f039b, +0x000f039b, +0x000f039b, +0x000f039b, +}; + +static const u32 RV770_pfp_microcode[] = { +0x7c408000, +0xa0000000, +0x7e82800b, +0x80000000, +0xdc030000, +0xcc800040, +0xd0400040, +0x7c408000, +0xa0000000, +0x7e82800b, +0xc818000e, +0x31980001, +0x7c424000, +0x95800252, +0x7c428000, +0xc81c001c, +0xc037c000, +0x7c40c000, +0x7c410000, +0x7cb4800b, +0xc0360003, +0x99c00000, +0xc81c001c, +0x7cb4800c, +0x24d40002, +0x7d654000, +0xcd400043, +0xce800043, +0xcd000043, +0xcc800040, +0xce400040, +0xce800040, +0xccc00040, +0xdc3a0000, +0x9780ffde, +0xcd000040, +0x7c40c000, +0x80000018, +0x7c410000, +0xd4000340, +0xd4000fc0, +0xd4000fa2, +0xc818000e, +0x8000000c, +0x31980002, +0xd40003c0, +0xd4000fc0, +0xd4000fa2, +0xc818000e, +0x288c0008, +0x30cc000f, +0x34100001, +0x7d0d0008, +0x8000000c, +0x7d91800b, +0xcc800040, +0xd0400040, +0x7c408000, +0xa0000000, +0x7e82800b, +0xd4000340, +0xd4000fc0, +0xd4000fa2, +0xcc800040, +0xd0400040, +0x7c408000, +0xa0000000, +0x7e82800b, +0xd40003c0, +0xd4000fc0, +0xd4000fa2, +0xcc800040, +0xd0400040, +0x7c408000, +0xa0000000, +0x7e82800b, +0xcc4003f9, +0x80000261, +0xcc4003f8, +0xc82003f8, +0xc81c03f9, +0xc81803fb, +0xc037ffff, +0x7c414000, +0xcf41a29e, +0x66200020, +0x7de1c02c, +0x7d58c008, +0x7cdcc020, +0x68d00020, +0xc0360003, +0xcc000054, +0x7cb4800c, +0x8000006a, +0xcc800040, +0x7c418000, +0xcd81a29e, +0xcc800040, +0xcd800040, +0x80000068, +0xcc000054, +0xc019ffff, +0xcc800040, +0xcd81a29e, +0x7c40c000, +0x7c410000, +0x7c414000, +0xccc1a1fa, +0xcd01a1f9, +0xcd41a29d, +0xccc00040, +0xcd000040, +0xcd400040, +0xcc400040, +0x7c408000, +0xa0000000, +0x7e82800b, +0xcc000054, +0xcc800040, +0x7c40c000, +0x7c410000, +0x7c414000, +0xccc1a1fa, +0xcd01a1f9, +0xcd41a29d, +0xccc00040, +0xcd000040, +0xcd400040, +0xd0400040, +0x7c408000, +0xa0000000, +0x7e82800b, +0x7c40c000, +0x30d00001, +0xccc1a29f, +0x95000003, +0x04140001, +0x04140002, +0xcd4003fb, +0xcc800040, +0x80000000, +0xccc00040, +0x7c40c000, +0xcc800040, +0xccc1a2a2, +0x80000000, +0xccc00040, +0x7c40c000, +0x28d4001f, +0xcc800040, +0x95400003, +0x7c410000, +0xccc00057, +0x2918001f, +0xccc00040, +0x95800003, +0xcd000040, +0xcd000058, +0x80000261, +0xcc00007f, +0xc8200017, +0xc8300022, +0x9a000006, +0x0e280001, +0xc824001e, +0x0a640001, +0xd4001240, +0xce400040, +0xc036c000, +0x96800007, +0x37747900, +0x041c0001, +0xcf400040, +0xcdc00040, +0xcf0003fa, +0x7c030000, +0xca0c0010, +0x7c410000, +0x94c00004, +0x7c414000, +0xd42002c4, +0xcde00044, +0x9b00000b, +0x7c418000, +0xcc00004b, +0xcda00049, +0xcd200041, +0xcd600041, +0xcda00041, +0x06200001, +0xce000056, +0x80000261, +0xcc00007f, +0xc8280020, +0xc82c0021, +0xcc000063, +0x7eea4001, +0x65740020, +0x7f53402c, +0x269c0002, +0x7df5c020, +0x69f80020, +0xce80004b, +0xce600049, +0xcde00041, +0xcfa00041, +0xce600041, +0x271c0002, +0x7df5c020, +0x69f80020, +0x7db24001, +0xcf00004b, +0xce600049, +0xcde00041, +0xcfa00041, +0x800000bd, +0xce600041, +0xc8200017, +0xc8300022, +0x9a000006, +0x0e280001, +0xc824001e, +0x0a640001, +0xd4001240, +0xce400040, +0xca0c0010, +0x7c410000, +0x94c0000b, +0xc036c000, +0x96800007, +0x37747900, +0x041c0001, +0xcf400040, +0xcdc00040, +0xcf0003fa, +0x7c030000, +0x800000b6, +0x7c414000, +0xcc000048, +0x800000ef, +0x00000000, +0xc8200017, +0xc81c0023, +0x0e240002, +0x99c00015, +0x7c418000, +0x0a200001, +0xce000056, +0xd4000440, +0xcc000040, +0xc036c000, +0xca140013, +0x96400007, +0x37747900, +0xcf400040, +0xcc000040, +0xc83003fa, +0x80000104, +0xcf000022, +0xcc000022, +0x9540015d, +0xcc00007f, +0xcca00046, +0x80000000, +0xcc200046, +0x80000261, +0xcc000064, +0xc8200017, +0xc810001f, +0x96000005, +0x09100001, +0xd4000440, +0xcd000040, +0xcd000022, +0xcc800040, +0xd0400040, +0xc80c0025, +0x94c0feeb, +0xc8100008, +0xcd000040, +0xd4000fc0, +0x80000000, +0xd4000fa2, +0x7c40c000, +0x7c410000, +0xccc003fd, +0xcd0003fc, +0xccc00042, +0xcd000042, +0x2914001f, +0x29180010, +0x31980007, +0x3b5c0001, +0x7d76000b, +0x99800005, +0x7d5e400b, +0xcc000042, +0x80000261, +0xcc00004d, +0x29980001, +0x292c0008, +0x9980003d, +0x32ec0001, +0x96000004, +0x2930000c, +0x80000261, +0xcc000042, +0x04140010, +0xcd400042, +0x33300001, +0x34280001, +0x8400015e, +0xc8140003, +0x9b40001b, +0x0438000c, +0x8400015e, +0xc8140003, +0x9b400017, +0x04380008, +0x8400015e, +0xc8140003, +0x9b400013, +0x04380004, +0x8400015e, +0xc8140003, +0x9b400015, +0xc80c03fd, +0x9a800009, +0xc81003fc, +0x9b000118, +0xcc00004d, +0x04140010, +0xccc00042, +0xcd000042, +0x80000136, +0xcd400042, +0x96c00111, +0xcc00004d, +0x80000261, +0xcc00004e, +0x9ac00003, +0xcc00004d, +0xcc00004e, +0xdf830000, +0x80000000, +0xd80301ff, +0x9ac00107, +0xcc00004d, +0x80000261, +0xcc00004e, +0xc8180003, +0xc81c0003, +0xc8200003, +0x7d5d4003, +0x7da1c003, +0x7d5d400c, +0x2a10001f, +0x299c001f, +0x7d1d000b, +0x7d17400b, +0x88000000, +0x7e92800b, +0x96400004, +0xcc00004e, +0x80000261, +0xcc000042, +0x04380008, +0xcf800042, +0xc8080003, +0xc80c0003, +0xc8100003, +0xc8140003, +0xc8180003, +0xc81c0003, +0xc8240003, +0xc8280003, +0x29fc001f, +0x2ab0001f, +0x7ff3c00b, +0x28f0001f, +0x7ff3c00b, +0x2970001f, +0x7ff3c00b, +0x7d888001, +0x7dccc001, +0x7e510001, +0x7e954001, +0x7c908002, +0x7cd4c002, +0x7cbc800b, +0x9ac00003, +0x7c8f400b, +0x38b40001, +0x9b4000d8, +0xcc00004d, +0x9bc000d6, +0xcc00004e, +0xc80c03fd, +0xc81003fc, +0xccc00042, +0x8000016f, +0xcd000042, +0xd4000340, +0xd4000fc0, +0xd4000fa2, +0xcc800040, +0xcc400040, +0xcc400040, +0xcc400040, +0x7c40c000, +0xccc00040, +0xccc0000d, +0x80000000, +0xd0400040, +0x7c40c000, +0x7c410000, +0x65140020, +0x7d4d402c, +0x24580002, +0x7d598020, +0x7c41c000, +0xcd800042, +0x69980020, +0xcd800042, +0xcdc00042, +0xc023c000, +0x05e40002, +0x7ca0800b, +0x26640010, +0x7ca4800c, +0xcc800040, +0xcdc00040, +0xccc00040, +0x95c0000e, +0xcd000040, +0x09dc0001, +0xc8280003, +0x96800008, +0xce800040, +0xc834001d, +0x97400000, +0xc834001d, +0x26a80008, +0x84000264, +0xcc2b0000, +0x99c0fff7, +0x09dc0001, +0xdc3a0000, +0x97800004, +0x7c418000, +0x800001a3, +0x25980002, +0xa0000000, +0x7d808000, +0xc818001d, +0x7c40c000, +0x64d00008, +0x95800000, +0xc818001d, +0xcc130000, +0xcc800040, +0xccc00040, +0x80000000, +0xcc400040, +0xc810001f, +0x7c40c000, +0xcc800040, +0x7cd1400c, +0xcd400040, +0x05180001, +0x80000000, +0xcd800022, +0x7c40c000, +0x64500020, +0x84000264, +0xcc000061, +0x7cd0c02c, +0xc8200017, +0xc8d60000, +0x99400008, +0x7c438000, +0xdf830000, +0xcfa0004f, +0x84000264, +0xcc000062, +0x80000000, +0xd040007f, +0x80000261, +0xcc000062, +0x84000264, +0xcc000061, +0xc8200017, +0x7c40c000, +0xc036ff00, +0xc810000d, +0xc0303fff, +0x7cf5400b, +0x7d51800b, +0x7d81800f, +0x99800008, +0x7cf3800b, +0xdf830000, +0xcfa0004f, +0x84000264, +0xcc000062, +0x80000000, +0xd040007f, +0x80000261, +0xcc000062, +0x84000264, +0x7c40c000, +0x28dc0008, +0x95c00019, +0x30dc0010, +0x7c410000, +0x99c00004, +0x64540020, +0x80000209, +0xc91d0000, +0x7d15002c, +0xc91e0000, +0x7c420000, +0x7c424000, +0x7c418000, +0x7de5c00b, +0x7de28007, +0x9a80000e, +0x41ac0005, +0x9ac00000, +0x0aec0001, +0x30dc0010, +0x99c00004, +0x00000000, +0x8000020c, +0xc91d0000, +0x8000020c, +0xc91e0000, +0xcc800040, +0xccc00040, +0xd0400040, +0xc80c0025, +0x94c0fde3, +0xc8100008, +0xcd000040, +0xd4000fc0, +0x80000000, +0xd4000fa2, +0xd4000340, +0xd4000fc0, +0xd4000fa2, +0xcc800040, +0xd0400040, +0x7c408000, +0xa0000000, +0x7e82800b, +0xd40003c0, +0xd4000fc0, +0xd4000fa2, +0xcc800040, +0xd0400040, +0x7c408000, +0xa0000000, +0x7e82800b, +0x7c40c000, +0x30d00006, +0x0d100006, +0x99000007, +0xc8140015, +0x99400005, +0xcc000052, +0xd4000340, +0xd4000fc0, +0xd4000fa2, +0xcc800040, +0xccc00040, +0x80000000, +0xd0400040, +0x7c40c000, +0xcc4d0000, +0xdc3a0000, +0x9780fdbc, +0x04cc0001, +0x80000243, +0xcc4d0000, +0x7c40c000, +0x7c410000, +0x29240018, +0x32640001, +0x9640000f, +0xcc800040, +0x7c414000, +0x7c418000, +0x7c41c000, +0xccc00043, +0xcd000043, +0x31dc7fff, +0xcdc00043, +0xccc00040, +0xcd000040, +0xcd400040, +0xcd800040, +0x80000000, +0xcdc00040, +0xccc00040, +0xcd000040, +0x80000000, +0xd0400040, +0x80000000, +0xd040007f, +0xcc00007f, +0x80000000, +0xcc00007f, +0xcc00007f, +0x88000000, +0xcc00007f, +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, +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, +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, +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, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00030223, +0x0004022b, +0x000500a0, +0x00020003, +0x0006003c, +0x00070027, +0x00080192, +0x00090044, +0x000a002d, +0x0010025f, +0x001700f1, +0x002201d8, +0x002301e9, +0x0026004c, +0x0027005f, +0x0020011b, +0x00280093, +0x0029004f, +0x002a0084, +0x002b0065, +0x002f008e, +0x003200d9, +0x00340233, +0x00360075, +0x0039010b, +0x003c01fd, +0x003f00a0, +0x00410248, +0x00440195, +0x0048019e, +0x004901c6, +0x004a01d0, +0x00550226, +0x0056022e, +0x0060000a, +0x0061002a, +0x00620030, +0x00630030, +0x00640030, +0x00650030, +0x00660030, +0x00670030, +0x00680037, +0x0069003f, +0x006a0047, +0x006b0047, +0x006c0047, +0x006d0047, +0x006e0047, +0x006f0047, +0x00700047, +0x0073025f, +0x007b0241, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +}; + +static const u32 RV730_pfp_microcode[] = { +0x7c408000, +0xa0000000, +0x7e82800b, +0x80000000, +0xdc030000, +0xcc800040, +0xd0400040, +0x7c408000, +0xa0000000, +0x7e82800b, +0xc818000e, +0x31980001, +0x7c424000, +0x9580023a, +0x7c428000, +0xc81c001c, +0xc037c000, +0x7c40c000, +0x7c410000, +0x7cb4800b, +0xc0360003, +0x99c00000, +0xc81c001c, +0x7cb4800c, +0x24d40002, +0x7d654000, +0xcd400043, +0xce800043, +0xcd000043, +0xcc800040, +0xce400040, +0xce800040, +0xccc00040, +0xdc3a0000, +0x9780ffde, +0xcd000040, +0x7c40c000, +0x80000018, +0x7c410000, +0xd4000340, +0xd4000fc0, +0xd4000fa2, +0xc818000e, +0x8000000c, +0x31980002, +0xd40003c0, +0xd4000fc0, +0xd4000fa2, +0xc818000e, +0x288c0008, +0x30cc000f, +0x34100001, +0x7d0d0008, +0x8000000c, +0x7d91800b, +0xcc800040, +0xd0400040, +0x7c408000, +0xa0000000, +0x7e82800b, +0xd4000340, +0xd4000fc0, +0xd4000fa2, +0xcc800040, +0xd0400040, +0x7c408000, +0xa0000000, +0x7e82800b, +0xd40003c0, +0xd4000fc0, +0xd4000fa2, +0xcc800040, +0xd0400040, +0x7c408000, +0xa0000000, +0x7e82800b, +0xcc4003f9, +0x80000249, +0xcc4003f8, +0xc037ffff, +0x7c414000, +0xcf41a29e, +0xc82003f8, +0xc81c03f9, +0x66200020, +0xc81803fb, +0x7de1c02c, +0x7d58c008, +0x7cdcc020, +0x69100020, +0xc0360003, +0xcc000054, +0x7cb4800c, +0x80000069, +0xcc800040, +0x7c418000, +0xcd81a29e, +0xcc800040, +0x80000067, +0xcd800040, +0xc019ffff, +0xcc800040, +0xcd81a29e, +0x7c40c000, +0x7c410000, +0x7c414000, +0xccc1a1fa, +0xcd01a1f9, +0xcd41a29d, +0xccc00040, +0xcd000040, +0xcd400040, +0xcc400040, +0x7c408000, +0xa0000000, +0x7e82800b, +0xcc000054, +0xcc800040, +0x7c40c000, +0x7c410000, +0x7c414000, +0xccc1a1fa, +0xcd01a1f9, +0xcd41a29d, +0xccc00040, +0xcd000040, +0xcd400040, +0xd0400040, +0x7c408000, +0xa0000000, +0x7e82800b, +0x7c40c000, +0x30d00001, +0xccc1a29f, +0x95000003, +0x04140001, +0x04140002, +0xcd4003fb, +0xcc800040, +0x80000000, +0xccc00040, +0x7c40c000, +0xcc800040, +0xccc1a2a2, +0x80000000, +0xccc00040, +0x7c40c000, +0x28d4001f, +0xcc800040, +0x95400003, +0x7c410000, +0xccc00057, +0x2918001f, +0xccc00040, +0x95800003, +0xcd000040, +0xcd000058, +0x80000249, +0xcc00007f, +0xc8200017, +0xc8300022, +0x9a000006, +0x0e280001, +0xc824001e, +0x0a640001, +0xd4001240, +0xce400040, +0xc036c000, +0x96800007, +0x37747900, +0x041c0001, +0xcf400040, +0xcdc00040, +0xcf0003fa, +0x7c030000, +0xca0c0010, +0x7c410000, +0x94c00004, +0x7c414000, +0xd42002c4, +0xcde00044, +0x9b00000b, +0x7c418000, +0xcc00004b, +0xcda00049, +0xcd200041, +0xcd600041, +0xcda00041, +0x06200001, +0xce000056, +0x80000249, +0xcc00007f, +0xc8280020, +0xc82c0021, +0xcc000063, +0x7eea4001, +0x65740020, +0x7f53402c, +0x269c0002, +0x7df5c020, +0x69f80020, +0xce80004b, +0xce600049, +0xcde00041, +0xcfa00041, +0xce600041, +0x271c0002, +0x7df5c020, +0x69f80020, +0x7db24001, +0xcf00004b, +0xce600049, +0xcde00041, +0xcfa00041, +0x800000bc, +0xce600041, +0xc8200017, +0xc8300022, +0x9a000006, +0x0e280001, +0xc824001e, +0x0a640001, +0xd4001240, +0xce400040, +0xca0c0010, +0x7c410000, +0x94c0000b, +0xc036c000, +0x96800007, +0x37747900, +0x041c0001, +0xcf400040, +0xcdc00040, +0xcf0003fa, +0x7c030000, +0x800000b5, +0x7c414000, +0xcc000048, +0x800000ee, +0x00000000, +0xc8200017, +0xc81c0023, +0x0e240002, +0x99c00015, +0x7c418000, +0x0a200001, +0xce000056, +0xd4000440, +0xcc000040, +0xc036c000, +0xca140013, +0x96400007, +0x37747900, +0xcf400040, +0xcc000040, +0xc83003fa, +0x80000103, +0xcf000022, +0xcc000022, +0x95400146, +0xcc00007f, +0xcca00046, +0x80000000, +0xcc200046, +0x80000249, +0xcc000064, +0xc8200017, +0xc810001f, +0x96000005, +0x09100001, +0xd4000440, +0xcd000040, +0xcd000022, +0xcc800040, +0xd0400040, +0xc80c0025, +0x94c0feec, +0xc8100008, +0xcd000040, +0xd4000fc0, +0x80000000, +0xd4000fa2, +0x7c40c000, +0x7c410000, +0xccc003fd, +0xcd0003fc, +0xccc00042, +0xcd000042, +0x2914001f, +0x29180010, +0x31980007, +0x3b5c0001, +0x7d76000b, +0x99800005, +0x7d5e400b, +0xcc000042, +0x80000249, +0xcc00004d, +0x29980001, +0x292c0008, +0x9980003d, +0x32ec0001, +0x96000004, +0x2930000c, +0x80000249, +0xcc000042, +0x04140010, +0xcd400042, +0x33300001, +0x34280001, +0x8400015d, +0xc8140003, +0x9b40001b, +0x0438000c, +0x8400015d, +0xc8140003, +0x9b400017, +0x04380008, +0x8400015d, +0xc8140003, +0x9b400013, +0x04380004, +0x8400015d, +0xc8140003, +0x9b400015, +0xc80c03fd, +0x9a800009, +0xc81003fc, +0x9b000101, +0xcc00004d, +0x04140010, +0xccc00042, +0xcd000042, +0x80000135, +0xcd400042, +0x96c000fa, +0xcc00004d, +0x80000249, +0xcc00004e, +0x9ac00003, +0xcc00004d, +0xcc00004e, +0xdf830000, +0x80000000, +0xd80301ff, +0x9ac000f0, +0xcc00004d, +0x80000249, +0xcc00004e, +0xc8180003, +0xc81c0003, +0xc8200003, +0x7d5d4003, +0x7da1c003, +0x7d5d400c, +0x2a10001f, +0x299c001f, +0x7d1d000b, +0x7d17400b, +0x88000000, +0x7e92800b, +0x96400004, +0xcc00004e, +0x80000249, +0xcc000042, +0x04380008, +0xcf800042, +0xc8080003, +0xc80c0003, +0xc8100003, +0xc8140003, +0xc8180003, +0xc81c0003, +0xc8240003, +0xc8280003, +0x29fc001f, +0x2ab0001f, +0x7ff3c00b, +0x28f0001f, +0x7ff3c00b, +0x2970001f, +0x7ff3c00b, +0x7d888001, +0x7dccc001, +0x7e510001, +0x7e954001, +0x7c908002, +0x7cd4c002, +0x7cbc800b, +0x9ac00003, +0x7c8f400b, +0x38b40001, +0x9b4000c1, +0xcc00004d, +0x9bc000bf, +0xcc00004e, +0xc80c03fd, +0xc81003fc, +0xccc00042, +0x8000016e, +0xcd000042, +0xd4000340, +0xd4000fc0, +0xd4000fa2, +0xcc800040, +0xcc400040, +0xcc400040, +0xcc400040, +0x7c40c000, +0xccc00040, +0xccc0000d, +0x80000000, +0xd0400040, +0x7c40c000, +0x7c410000, +0x65140020, +0x7d4d402c, +0x24580002, +0x7d598020, +0x7c41c000, +0xcd800042, +0x69980020, +0xcd800042, +0xcdc00042, +0xc023c000, +0x05e40002, +0x7ca0800b, +0x26640010, +0x7ca4800c, +0xcc800040, +0xcdc00040, +0xccc00040, +0x95c0000e, +0xcd000040, +0x09dc0001, +0xc8280003, +0x96800008, +0xce800040, +0xc834001d, +0x97400000, +0xc834001d, +0x26a80008, +0x8400024c, +0xcc2b0000, +0x99c0fff7, +0x09dc0001, +0xdc3a0000, +0x97800004, +0x7c418000, +0x800001a2, +0x25980002, +0xa0000000, +0x7d808000, +0xc818001d, +0x7c40c000, +0x64d00008, +0x95800000, +0xc818001d, +0xcc130000, +0xcc800040, +0xccc00040, +0x80000000, +0xcc400040, +0xc810001f, +0x7c40c000, +0xcc800040, +0x7cd1400c, +0xcd400040, +0x05180001, +0x80000000, +0xcd800022, +0x7c40c000, +0x64500020, +0x8400024c, +0xcc000061, +0x7cd0c02c, +0xc8200017, +0xc8d60000, +0x99400008, +0x7c438000, +0xdf830000, +0xcfa0004f, +0x8400024c, +0xcc000062, +0x80000000, +0xd040007f, +0x80000249, +0xcc000062, +0x8400024c, +0xcc000061, +0xc8200017, +0x7c40c000, +0xc036ff00, +0xc810000d, +0xc0303fff, +0x7cf5400b, +0x7d51800b, +0x7d81800f, +0x99800008, +0x7cf3800b, +0xdf830000, +0xcfa0004f, +0x8400024c, +0xcc000062, +0x80000000, +0xd040007f, +0x80000249, +0xcc000062, +0x8400024c, +0x7c40c000, +0x28dc0008, +0x95c00019, +0x30dc0010, +0x7c410000, +0x99c00004, +0x64540020, +0x80000208, +0xc91d0000, +0x7d15002c, +0xc91e0000, +0x7c420000, +0x7c424000, +0x7c418000, +0x7de5c00b, +0x7de28007, +0x9a80000e, +0x41ac0005, +0x9ac00000, +0x0aec0001, +0x30dc0010, +0x99c00004, +0x00000000, +0x8000020b, +0xc91d0000, +0x8000020b, +0xc91e0000, +0xcc800040, +0xccc00040, +0xd0400040, +0xc80c0025, +0x94c0fde4, +0xc8100008, +0xcd000040, +0xd4000fc0, +0x80000000, +0xd4000fa2, +0xd4000340, +0xd4000fc0, +0xd4000fa2, +0xcc800040, +0xd0400040, +0x7c408000, +0xa0000000, +0x7e82800b, +0xd40003c0, +0xd4000fc0, +0xd4000fa2, +0xcc800040, +0xd0400040, +0x7c408000, +0xa0000000, +0x7e82800b, +0x7c40c000, +0x30d00006, +0x0d100006, +0x99000007, +0xc8140015, +0x99400005, +0xcc000052, +0xd4000340, +0xd4000fc0, +0xd4000fa2, +0xcc800040, +0xccc00040, +0x80000000, +0xd0400040, +0x7c40c000, +0xcc4d0000, +0xdc3a0000, +0x9780fdbd, +0x04cc0001, +0x80000242, +0xcc4d0000, +0x80000000, +0xd040007f, +0xcc00007f, +0x80000000, +0xcc00007f, +0xcc00007f, +0x88000000, +0xcc00007f, +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, +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, +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, +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, +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, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00030222, +0x0004022a, +0x0005009f, +0x00020003, +0x0006003c, +0x00070027, +0x00080191, +0x00090044, +0x000a002d, +0x00100247, +0x001700f0, +0x002201d7, +0x002301e8, +0x0026004c, +0x0027005f, +0x0020011a, +0x00280092, +0x0029004f, +0x002a0083, +0x002b0064, +0x002f008d, +0x003200d8, +0x00340232, +0x00360074, +0x0039010a, +0x003c01fc, +0x003f009f, +0x00410005, +0x00440194, +0x0048019d, +0x004901c5, +0x004a01cf, +0x00550225, +0x0056022d, +0x0060000a, +0x0061002a, +0x00620030, +0x00630030, +0x00640030, +0x00650030, +0x00660030, +0x00670030, +0x00680037, +0x0069003f, +0x006a0047, +0x006b0047, +0x006c0047, +0x006d0047, +0x006e0047, +0x006f0047, +0x00700047, +0x00730247, +0x007b0240, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +}; + +static const u32 RV730_cp_microcode[] = { +0xcc0003ea, +0x7c408000, +0xa0000000, +0xcc800062, +0x80000001, +0xd040007f, +0x80000001, +0xcc400041, +0x7c40c000, +0xc0160004, +0x30d03fff, +0x7d15000c, +0xcc110000, +0x28d8001e, +0x31980001, +0x28dc001f, +0xc8200004, +0x95c00006, +0x7c424000, +0xcc000062, +0x7e56800c, +0xcc290000, +0xc8240004, +0x7e26000b, +0x95800006, +0x7c42c000, +0xcc000062, +0x7ed7000c, +0xcc310000, +0xc82c0004, +0x7e2e000c, +0xcc000062, +0x31103fff, +0x80000001, +0xce110000, +0x7c40c000, +0x80000001, +0xcc400040, +0x80000001, +0xcc412257, +0x7c418000, +0xcc400045, +0xcc400048, +0xcc41225c, +0xcc41a1fc, +0x7c408000, +0xa0000000, +0xcc800062, +0xcc400045, +0xcc400048, +0x7c40c000, +0xcc41225c, +0xcc41a1fc, +0x7c408000, +0xa0000000, +0xcc800062, +0xcc000045, +0xcc000048, +0xcc41225c, +0xcc41a1fc, +0x7c408000, +0xa0000000, +0xcc800062, +0x040ca1fd, +0xc0120001, +0xcc000045, +0xcc000048, +0x7cd0c00c, +0xcc41225c, +0xcc41a1fc, +0xd04d0000, +0x7c408000, +0xa0000000, +0xcc800062, +0x80000001, +0xcc41225d, +0x7c408000, +0x7c40c000, +0xc02a0002, +0x7c410000, +0x7d29000c, +0x30940001, +0x30980006, +0x309c0300, +0x29dc0008, +0x7c420000, +0x7c424000, +0x9540000f, +0xc02e0004, +0x05f02258, +0x7f2f000c, +0xcc310000, +0xc8280004, +0xccc12169, +0xcd01216a, +0xce81216b, +0x0db40002, +0xcc01216c, +0x9740000e, +0x0db40000, +0x8000007b, +0xc834000a, +0x0db40002, +0x97400009, +0x0db40000, +0xc02e0004, +0x05f02258, +0x7f2f000c, +0xcc310000, +0xc8280004, +0x8000007b, +0xc834000a, +0x97400004, +0x7e028000, +0x8000007b, +0xc834000a, +0x0db40004, +0x9740ff8c, +0x00000000, +0xce01216d, +0xce41216e, +0xc8280003, +0xc834000a, +0x9b400004, +0x043c0005, +0x8400026b, +0xcc000062, +0x0df40000, +0x9740000b, +0xc82c03e6, +0xce81a2b7, +0xc0300006, +0x7ef34028, +0xc0300020, +0x7f6b8020, +0x7fb3c029, +0xcf81a2c4, +0x80000001, +0xcfc1a2d1, +0x0df40001, +0x9740000b, +0xc82c03e7, +0xce81a2bb, +0xc0300006, +0x7ef34028, +0xc0300020, +0x7f6b8020, +0x7fb3c029, +0xcf81a2c5, +0x80000001, +0xcfc1a2d2, +0x0df40002, +0x9740000b, +0xc82c03e8, +0xce81a2bf, +0xc0300006, +0x7ef34028, +0xc0300020, +0x7f6b8020, +0x7fb3c029, +0xcf81a2c6, +0x80000001, +0xcfc1a2d3, +0xc82c03e9, +0xce81a2c3, +0xc0300006, +0x7ef34028, +0xc0300020, +0x7f6b8020, +0x7fb3c029, +0xcf81a2c7, +0x80000001, +0xcfc1a2d4, +0x80000001, +0xcc400042, +0x7c40c000, +0x7c410000, +0x2914001d, +0x31540001, +0x9940000c, +0x31181000, +0xc81c0011, +0x95c00000, +0xc81c0011, +0xccc12100, +0xcd012101, +0xccc12102, +0xcd012103, +0x04180004, +0x8000037c, +0xcd81a2a4, +0xc02a0004, +0x95800008, +0x36a821a3, +0xcc290000, +0xc8280004, +0xc81c0011, +0x0de40040, +0x9640ffff, +0xc81c0011, +0xccc12170, +0xcd012171, +0xc8200012, +0x96000000, +0xc8200012, +0x8000037c, +0xcc000064, +0x7c40c000, +0x7c410000, +0xcc000045, +0xcc000048, +0x40d40003, +0xcd41225c, +0xcd01a1fc, +0xc01a0001, +0x041ca1fd, +0x7dd9c00c, +0x7c420000, +0x08cc0001, +0x06240001, +0x06280002, +0xce1d0000, +0xce5d0000, +0x98c0fffa, +0xce9d0000, +0x7c408000, +0xa0000000, +0xcc800062, +0x7c40c000, +0x30d00001, +0x28cc0001, +0x7c414000, +0x95000006, +0x7c418000, +0xcd41216d, +0xcd81216e, +0x800000f2, +0xc81c0003, +0xc0220004, +0x7e16000c, +0xcc210000, +0xc81c0004, +0x7c424000, +0x98c00004, +0x7c428000, +0x80000001, +0xcde50000, +0xce412169, +0xce81216a, +0xcdc1216b, +0x80000001, +0xcc01216c, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0x7c41c000, +0x28a40008, +0x326400ff, +0x0e68003c, +0x9680000a, +0x7c020000, +0x7c420000, +0x1e300003, +0xcc00006a, +0x9b000003, +0x42200005, +0x04200040, +0x8000010f, +0x7c024000, +0x7e024000, +0x9a400000, +0x0a640001, +0x30ec0010, +0x9ac0000a, +0xcc000062, +0xc02a0004, +0xc82c0021, +0x7e92800c, +0xcc000041, +0xcc290000, +0xcec00021, +0x8000011f, +0xc8300004, +0xcd01216d, +0xcd41216e, +0xc8300003, +0x7f1f000b, +0x30f40007, +0x27780001, +0x9740002a, +0x07b80124, +0x9f800000, +0x00000000, +0x80000134, +0x7f1b8004, +0x80000138, +0x7f1b8005, +0x8000013c, +0x7f1b8002, +0x80000140, +0x7f1b8003, +0x80000144, +0x7f1b8007, +0x80000148, +0x7f1b8006, +0x8000014d, +0x28a40008, +0x9b800019, +0x28a40008, +0x8000015d, +0x326400ff, +0x9b800015, +0x28a40008, +0x8000015d, +0x326400ff, +0x9b800011, +0x28a40008, +0x8000015d, +0x326400ff, +0x9b80000d, +0x28a40008, +0x8000015d, +0x326400ff, +0x9b800009, +0x28a40008, +0x8000015d, +0x326400ff, +0x9b800005, +0x28a40008, +0x8000015d, +0x326400ff, +0x28a40008, +0x326400ff, +0x0e68003c, +0x9a80feb2, +0x28ec0008, +0x7c434000, +0x7c438000, +0x7c43c000, +0x96c00007, +0xcc000062, +0xcf412169, +0xcf81216a, +0xcfc1216b, +0x80000001, +0xcc01216c, +0x80000001, +0xcff50000, +0xcc00006b, +0x8400037f, +0x0e68003c, +0x9a800004, +0xc8280015, +0x80000001, +0xd040007f, +0x9680ffab, +0x7e024000, +0x84000239, +0xc00e0002, +0xcc000041, +0x80000237, +0xccc1304a, +0x7c40c000, +0x7c410000, +0xc01e0001, +0x29240012, +0xc0220002, +0x96400005, +0xc0260004, +0xc027fffb, +0x7d25000b, +0xc0260000, +0x7dd2800b, +0x7e12c00b, +0x7d25000c, +0x7c414000, +0x7c418000, +0xccc12169, +0x9a80000a, +0xcd01216a, +0xcd41216b, +0x96c0fe83, +0xcd81216c, +0xc8300018, +0x97000000, +0xc8300018, +0x80000001, +0xcc000018, +0x8400037f, +0xcc00007f, +0xc8140013, +0xc8180014, +0xcd41216b, +0x96c0fe77, +0xcd81216c, +0x80000181, +0xc8300018, +0xc80c0008, +0x98c00000, +0xc80c0008, +0x7c410000, +0x95000002, +0x00000000, +0x7c414000, +0xc8200009, +0xcc400043, +0xce01a1f4, +0xcc400044, +0xc00e8000, +0x7c424000, +0x7c428000, +0x2aac001f, +0x96c0fe64, +0xc035f000, +0xce4003e2, +0x32780003, +0x267c0008, +0x7ff7c00b, +0x7ffbc00c, +0x2a780018, +0xcfc003e3, +0xcf8003e4, +0x26b00002, +0x7f3f0000, +0xcf0003e5, +0x8000031d, +0x7c80c000, +0x7c40c000, +0x28d00008, +0x3110000f, +0x9500000f, +0x25280001, +0x06a801b2, +0x9e800000, +0x00000000, +0x800001d3, +0xc0120800, +0x800001e1, +0xc814000f, +0x800001e8, +0xc8140010, +0x800001ef, +0xccc1a2a4, +0x800001f8, +0xc8140011, +0x30d0003f, +0x0d280015, +0x9a800012, +0x0d28001e, +0x9a80001e, +0x0d280020, +0x9a800023, +0x0d24000f, +0x0d280010, +0x7e6a800c, +0x9a800026, +0x0d200004, +0x0d240014, +0x0d280028, +0x7e62400c, +0x7ea6800c, +0x9a80002a, +0xc8140011, +0x80000001, +0xccc1a2a4, +0xc0120800, +0x7c414000, +0x7d0cc00c, +0xc0120008, +0x29580003, +0x295c000c, +0x7c420000, +0x7dd1c00b, +0x26200014, +0x7e1e400c, +0x7e4e800c, +0xce81a2a4, +0x80000001, +0xcd81a1fe, +0xc814000f, +0x0410210e, +0x95400000, +0xc814000f, +0xd0510000, +0x80000001, +0xccc1a2a4, +0xc8140010, +0x04102108, +0x95400000, +0xc8140010, +0xd0510000, +0x80000001, +0xccc1a2a4, +0xccc1a2a4, +0x04100001, +0xcd000019, +0x8400037f, +0xcc00007f, +0xc8100019, +0x99000000, +0xc8100019, +0x80000002, +0x7c408000, +0x04102100, +0x95400000, +0xc8140011, +0xd0510000, +0x8000037c, +0xccc1a2a4, +0x7c40c000, +0xcc40000d, +0x94c0fe01, +0xcc40000e, +0x7c410000, +0x95000005, +0x08cc0001, +0xc8140005, +0x99400014, +0x00000000, +0x98c0fffb, +0x7c410000, +0x80000002, +0x7d008000, +0xc8140005, +0x7c40c000, +0x9940000c, +0xc818000c, +0x7c410000, +0x9580fdf0, +0xc820000e, +0xc81c000d, +0x66200020, +0x7e1e002c, +0x25240002, +0x7e624020, +0x80000001, +0xcce60000, +0x7c410000, +0xcc00006c, +0xcc00006d, +0xc818001f, +0xc81c001e, +0x65980020, +0x7dd9c02c, +0x7cd4c00c, +0xccde0000, +0x45dc0004, +0xc8280017, +0x9680000f, +0xc00e0001, +0x28680008, +0x2aac0016, +0x32a800ff, +0x0eb00049, +0x7f2f000b, +0x97000006, +0x00000000, +0xc8140005, +0x7c40c000, +0x80000221, +0x7c410000, +0x80000224, +0xd040007f, +0x84000239, +0xcc000041, +0xccc1304a, +0x94000000, +0xc83c001a, +0x043c0005, +0xcfc1a2a4, +0xc0361f90, +0xc0387fff, +0x7c03c010, +0x7f7b400c, +0xcf41217c, +0xcfc1217d, +0xcc01217e, +0xc03a0004, +0x0434217f, +0x7f7b400c, +0xcc350000, +0xc83c0004, +0x2bfc001f, +0x04380020, +0x97c00005, +0xcc000062, +0x9b800000, +0x0bb80001, +0x80000245, +0xcc000071, +0xcc01a1f4, +0x04380016, +0xc0360002, +0xcf81a2a4, +0x88000000, +0xcf412010, +0x7c40c000, +0x28d0001c, +0x95000005, +0x04d40001, +0xcd400065, +0x80000001, +0xcd400068, +0x09540002, +0x80000001, +0xcd400066, +0x8400026a, +0xc81803ea, +0x7c40c000, +0x9980fd9f, +0xc8140016, +0x08d00001, +0x9940002b, +0xcd000068, +0x7c408000, +0xa0000000, +0xcc800062, +0x043c0005, +0xcfc1a2a4, +0xcc01a1f4, +0x8400037f, +0xcc000046, +0x88000000, +0xcc00007f, +0x8400027c, +0xc81803ea, +0x7c40c000, +0x9980fd8d, +0xc8140016, +0x08d00001, +0x99400019, +0xcd000068, +0x7c408000, +0xa0000000, +0xcc800062, +0x043c0022, +0xcfc1a2a4, +0x8400037f, +0xcc000047, +0x88000000, +0xcc00007f, +0xc8100016, +0x9900000d, +0xcc400067, +0x80000002, +0x7c408000, +0xc81803ea, +0x9980fd79, +0x7c40c000, +0x94c00003, +0xc8100016, +0x99000004, +0xccc00068, +0x80000002, +0x7c408000, +0x84000239, +0xc0148000, +0xcc000041, +0xcd41304a, +0xc0148000, +0x99000000, +0xc8100016, +0x80000002, +0x7c408000, +0xc0120001, +0x7c51400c, +0x80000001, +0xd0550000, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0x291c001f, +0xccc0004a, +0xcd00004b, +0x95c00003, +0xc01c8000, +0xcdc12010, +0xdd830000, +0x055c2000, +0xcc000062, +0x80000001, +0xd81f4100, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0xccc0004c, +0xcd00004d, +0xdd830000, +0x055ca000, +0x80000001, +0xd81f4100, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0xccc0004e, +0xcd00004f, +0xdd830000, +0x055cc000, +0x80000001, +0xd81f4100, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0xccc00050, +0xcd000051, +0xdd830000, +0x055cf8e0, +0x80000001, +0xd81f4100, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0xccc00052, +0xcd000053, +0xdd830000, +0x055cf880, +0x80000001, +0xd81f4100, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0xccc00054, +0xcd000055, +0xdd830000, +0x055ce000, +0x80000001, +0xd81f4100, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0xccc00056, +0xcd000057, +0xdd830000, +0x055cf000, +0x80000001, +0xd81f4100, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0xccc00058, +0xcd000059, +0xdd830000, +0x055cf3fc, +0x80000001, +0xd81f4100, +0xd0432000, +0x7c408000, +0xa0000000, +0xcc800062, +0xd043a000, +0x7c408000, +0xa0000000, +0xcc800062, +0xd043c000, +0x7c408000, +0xa0000000, +0xcc800062, +0xd043f8e0, +0x7c408000, +0xa0000000, +0xcc800062, +0xd043f880, +0x7c408000, +0xa0000000, +0xcc800062, +0xd043e000, +0x7c408000, +0xa0000000, +0xcc800062, +0xd043f000, +0x7c408000, +0xa0000000, +0xcc800062, +0xd043f3fc, +0x7c408000, +0xa0000000, +0xcc800062, +0xc81403e0, +0xcc430000, +0xcc430000, +0xcc430000, +0x7d45c000, +0xcdc30000, +0xd0430000, +0x7c408000, +0xa0000000, +0xcc800062, +0x7c40c000, +0xc81003e2, +0xc81403e5, +0xc81803e3, +0xc81c03e4, +0xcd812169, +0xcdc1216a, +0xccc1216b, +0xcc01216c, +0x04200004, +0x7da18000, +0x7d964002, +0x9640fcd9, +0xcd8003e3, +0x31280003, +0xc02df000, +0x25180008, +0x7dad800b, +0x7da9800c, +0x80000001, +0xcd8003e3, +0x308cffff, +0xd04d0000, +0x7c408000, +0xa0000000, +0xcc800062, +0xc8140020, +0x15580002, +0x9580ffff, +0xc8140020, +0xcc00006e, +0xcc412180, +0x7c40c000, +0xccc1218d, +0xcc412181, +0x28d0001f, +0x34588000, +0xcd81218c, +0x9500fcbf, +0xcc412182, +0xc8140020, +0x9940ffff, +0xc8140020, +0x80000002, +0x7c408000, +0x7c40c000, +0x28d00018, +0x31100001, +0xc0160080, +0x95000003, +0xc02a0004, +0x7cd4c00c, +0xccc1217c, +0xcc41217d, +0xcc41217e, +0x7c418000, +0x1db00003, +0x36a0217f, +0x9b000003, +0x419c0005, +0x041c0040, +0x99c00000, +0x09dc0001, +0xcc210000, +0xc8240004, +0x2a6c001f, +0x419c0005, +0x9ac0fffa, +0xcc800062, +0x80000002, +0x7c408000, +0x7c40c000, +0x04d403e6, +0x80000001, +0xcc540000, +0x8000037c, +0xcc4003ea, +0xc01c8000, +0x044ca000, +0xcdc12010, +0x7c410000, +0xc8140009, +0x04180000, +0x041c0008, +0xcd800071, +0x09dc0001, +0x05980001, +0xcd0d0000, +0x99c0fffc, +0xcc800062, +0x8000037c, +0xcd400071, +0xc00e0100, +0xcc000041, +0xccc1304a, +0xc83c007f, +0xcc00007f, +0x80000001, +0xcc00007f, +0xcc00007f, +0x88000000, +0xcc00007f, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00010331, +0x00100004, +0x00170006, +0x00210008, +0x00270028, +0x00280023, +0x00290029, +0x002a0026, +0x002b0029, +0x002d0038, +0x002e003f, +0x002f004a, +0x0034004c, +0x00360030, +0x003900af, +0x003a00cf, +0x003b00e4, +0x003c00fc, +0x003d016b, +0x003f00ad, +0x00410336, +0x00430349, +0x0044018e, +0x004500fc, +0x004601ac, +0x004701ac, +0x004801fe, +0x0049020c, +0x004a0255, +0x004b0282, +0x0052025f, +0x00530271, +0x00540287, +0x00570299, +0x0060029d, +0x006102ac, +0x006202b6, +0x006302c0, +0x006402ca, +0x006502d4, +0x006602de, +0x006702e8, +0x006802f2, +0x006902f6, +0x006a02fa, +0x006b02fe, +0x006c0302, +0x006d0306, +0x006e030a, +0x006f030e, +0x00700312, +0x00720363, +0x00740369, +0x00790367, +0x007c031c, +0x000f0378, +0x000f0378, +0x000f0378, +0x000f0378, +0x000f0378, +0x000f0378, +0x000f0378, +0x000f0378, +0x000f0378, +0x000f0378, +0x000f0378, +0x000f0378, +0x000f0378, +0x000f0378, +0x000f0378, +0x000f0378, +0x000f0378, +0x000f0378, +0x000f0378, +0x000f0378, +0x000f0378, +0x000f0378, +0x000f0378, +0x000f0378, +0x000f0378, +}; + +static const u32 RV710_pfp_microcode[] = { +0x7c408000, +0xa0000000, +0x7e82800b, +0x80000000, +0xdc030000, +0xcc800040, +0xd0400040, +0x7c408000, +0xa0000000, +0x7e82800b, +0xc818000e, +0x31980001, +0x7c424000, +0x9580023a, +0x7c428000, +0xc81c001c, +0xc037c000, +0x7c40c000, +0x7c410000, +0x7cb4800b, +0xc0360003, +0x99c00000, +0xc81c001c, +0x7cb4800c, +0x24d40002, +0x7d654000, +0xcd400043, +0xce800043, +0xcd000043, +0xcc800040, +0xce400040, +0xce800040, +0xccc00040, +0xdc3a0000, +0x9780ffde, +0xcd000040, +0x7c40c000, +0x80000018, +0x7c410000, +0xd4000340, +0xd4000fc0, +0xd4000fa2, +0xc818000e, +0x8000000c, +0x31980002, +0xd40003c0, +0xd4000fc0, +0xd4000fa2, +0xc818000e, +0x288c0008, +0x30cc000f, +0x34100001, +0x7d0d0008, +0x8000000c, +0x7d91800b, +0xcc800040, +0xd0400040, +0x7c408000, +0xa0000000, +0x7e82800b, +0xd4000340, +0xd4000fc0, +0xd4000fa2, +0xcc800040, +0xd0400040, +0x7c408000, +0xa0000000, +0x7e82800b, +0xd40003c0, +0xd4000fc0, +0xd4000fa2, +0xcc800040, +0xd0400040, +0x7c408000, +0xa0000000, +0x7e82800b, +0xcc4003f9, +0x80000249, +0xcc4003f8, +0xc037ffff, +0x7c414000, +0xcf41a29e, +0xc82003f8, +0xc81c03f9, +0x66200020, +0xc81803fb, +0x7de1c02c, +0x7d58c008, +0x7cdcc020, +0x69100020, +0xc0360003, +0xcc000054, +0x7cb4800c, +0x80000069, +0xcc800040, +0x7c418000, +0xcd81a29e, +0xcc800040, +0x80000067, +0xcd800040, +0xc019ffff, +0xcc800040, +0xcd81a29e, +0x7c40c000, +0x7c410000, +0x7c414000, +0xccc1a1fa, +0xcd01a1f9, +0xcd41a29d, +0xccc00040, +0xcd000040, +0xcd400040, +0xcc400040, +0x7c408000, +0xa0000000, +0x7e82800b, +0xcc000054, +0xcc800040, +0x7c40c000, +0x7c410000, +0x7c414000, +0xccc1a1fa, +0xcd01a1f9, +0xcd41a29d, +0xccc00040, +0xcd000040, +0xcd400040, +0xd0400040, +0x7c408000, +0xa0000000, +0x7e82800b, +0x7c40c000, +0x30d00001, +0xccc1a29f, +0x95000003, +0x04140001, +0x04140002, +0xcd4003fb, +0xcc800040, +0x80000000, +0xccc00040, +0x7c40c000, +0xcc800040, +0xccc1a2a2, +0x80000000, +0xccc00040, +0x7c40c000, +0x28d4001f, +0xcc800040, +0x95400003, +0x7c410000, +0xccc00057, +0x2918001f, +0xccc00040, +0x95800003, +0xcd000040, +0xcd000058, +0x80000249, +0xcc00007f, +0xc8200017, +0xc8300022, +0x9a000006, +0x0e280001, +0xc824001e, +0x0a640001, +0xd4001240, +0xce400040, +0xc036c000, +0x96800007, +0x37747900, +0x041c0001, +0xcf400040, +0xcdc00040, +0xcf0003fa, +0x7c030000, +0xca0c0010, +0x7c410000, +0x94c00004, +0x7c414000, +0xd42002c4, +0xcde00044, +0x9b00000b, +0x7c418000, +0xcc00004b, +0xcda00049, +0xcd200041, +0xcd600041, +0xcda00041, +0x06200001, +0xce000056, +0x80000249, +0xcc00007f, +0xc8280020, +0xc82c0021, +0xcc000063, +0x7eea4001, +0x65740020, +0x7f53402c, +0x269c0002, +0x7df5c020, +0x69f80020, +0xce80004b, +0xce600049, +0xcde00041, +0xcfa00041, +0xce600041, +0x271c0002, +0x7df5c020, +0x69f80020, +0x7db24001, +0xcf00004b, +0xce600049, +0xcde00041, +0xcfa00041, +0x800000bc, +0xce600041, +0xc8200017, +0xc8300022, +0x9a000006, +0x0e280001, +0xc824001e, +0x0a640001, +0xd4001240, +0xce400040, +0xca0c0010, +0x7c410000, +0x94c0000b, +0xc036c000, +0x96800007, +0x37747900, +0x041c0001, +0xcf400040, +0xcdc00040, +0xcf0003fa, +0x7c030000, +0x800000b5, +0x7c414000, +0xcc000048, +0x800000ee, +0x00000000, +0xc8200017, +0xc81c0023, +0x0e240002, +0x99c00015, +0x7c418000, +0x0a200001, +0xce000056, +0xd4000440, +0xcc000040, +0xc036c000, +0xca140013, +0x96400007, +0x37747900, +0xcf400040, +0xcc000040, +0xc83003fa, +0x80000103, +0xcf000022, +0xcc000022, +0x95400146, +0xcc00007f, +0xcca00046, +0x80000000, +0xcc200046, +0x80000249, +0xcc000064, +0xc8200017, +0xc810001f, +0x96000005, +0x09100001, +0xd4000440, +0xcd000040, +0xcd000022, +0xcc800040, +0xd0400040, +0xc80c0025, +0x94c0feec, +0xc8100008, +0xcd000040, +0xd4000fc0, +0x80000000, +0xd4000fa2, +0x7c40c000, +0x7c410000, +0xccc003fd, +0xcd0003fc, +0xccc00042, +0xcd000042, +0x2914001f, +0x29180010, +0x31980007, +0x3b5c0001, +0x7d76000b, +0x99800005, +0x7d5e400b, +0xcc000042, +0x80000249, +0xcc00004d, +0x29980001, +0x292c0008, +0x9980003d, +0x32ec0001, +0x96000004, +0x2930000c, +0x80000249, +0xcc000042, +0x04140010, +0xcd400042, +0x33300001, +0x34280001, +0x8400015d, +0xc8140003, +0x9b40001b, +0x0438000c, +0x8400015d, +0xc8140003, +0x9b400017, +0x04380008, +0x8400015d, +0xc8140003, +0x9b400013, +0x04380004, +0x8400015d, +0xc8140003, +0x9b400015, +0xc80c03fd, +0x9a800009, +0xc81003fc, +0x9b000101, +0xcc00004d, +0x04140010, +0xccc00042, +0xcd000042, +0x80000135, +0xcd400042, +0x96c000fa, +0xcc00004d, +0x80000249, +0xcc00004e, +0x9ac00003, +0xcc00004d, +0xcc00004e, +0xdf830000, +0x80000000, +0xd80301ff, +0x9ac000f0, +0xcc00004d, +0x80000249, +0xcc00004e, +0xc8180003, +0xc81c0003, +0xc8200003, +0x7d5d4003, +0x7da1c003, +0x7d5d400c, +0x2a10001f, +0x299c001f, +0x7d1d000b, +0x7d17400b, +0x88000000, +0x7e92800b, +0x96400004, +0xcc00004e, +0x80000249, +0xcc000042, +0x04380008, +0xcf800042, +0xc8080003, +0xc80c0003, +0xc8100003, +0xc8140003, +0xc8180003, +0xc81c0003, +0xc8240003, +0xc8280003, +0x29fc001f, +0x2ab0001f, +0x7ff3c00b, +0x28f0001f, +0x7ff3c00b, +0x2970001f, +0x7ff3c00b, +0x7d888001, +0x7dccc001, +0x7e510001, +0x7e954001, +0x7c908002, +0x7cd4c002, +0x7cbc800b, +0x9ac00003, +0x7c8f400b, +0x38b40001, +0x9b4000c1, +0xcc00004d, +0x9bc000bf, +0xcc00004e, +0xc80c03fd, +0xc81003fc, +0xccc00042, +0x8000016e, +0xcd000042, +0xd4000340, +0xd4000fc0, +0xd4000fa2, +0xcc800040, +0xcc400040, +0xcc400040, +0xcc400040, +0x7c40c000, +0xccc00040, +0xccc0000d, +0x80000000, +0xd0400040, +0x7c40c000, +0x7c410000, +0x65140020, +0x7d4d402c, +0x24580002, +0x7d598020, +0x7c41c000, +0xcd800042, +0x69980020, +0xcd800042, +0xcdc00042, +0xc023c000, +0x05e40002, +0x7ca0800b, +0x26640010, +0x7ca4800c, +0xcc800040, +0xcdc00040, +0xccc00040, +0x95c0000e, +0xcd000040, +0x09dc0001, +0xc8280003, +0x96800008, +0xce800040, +0xc834001d, +0x97400000, +0xc834001d, +0x26a80008, +0x8400024c, +0xcc2b0000, +0x99c0fff7, +0x09dc0001, +0xdc3a0000, +0x97800004, +0x7c418000, +0x800001a2, +0x25980002, +0xa0000000, +0x7d808000, +0xc818001d, +0x7c40c000, +0x64d00008, +0x95800000, +0xc818001d, +0xcc130000, +0xcc800040, +0xccc00040, +0x80000000, +0xcc400040, +0xc810001f, +0x7c40c000, +0xcc800040, +0x7cd1400c, +0xcd400040, +0x05180001, +0x80000000, +0xcd800022, +0x7c40c000, +0x64500020, +0x8400024c, +0xcc000061, +0x7cd0c02c, +0xc8200017, +0xc8d60000, +0x99400008, +0x7c438000, +0xdf830000, +0xcfa0004f, +0x8400024c, +0xcc000062, +0x80000000, +0xd040007f, +0x80000249, +0xcc000062, +0x8400024c, +0xcc000061, +0xc8200017, +0x7c40c000, +0xc036ff00, +0xc810000d, +0xc0303fff, +0x7cf5400b, +0x7d51800b, +0x7d81800f, +0x99800008, +0x7cf3800b, +0xdf830000, +0xcfa0004f, +0x8400024c, +0xcc000062, +0x80000000, +0xd040007f, +0x80000249, +0xcc000062, +0x8400024c, +0x7c40c000, +0x28dc0008, +0x95c00019, +0x30dc0010, +0x7c410000, +0x99c00004, +0x64540020, +0x80000208, +0xc91d0000, +0x7d15002c, +0xc91e0000, +0x7c420000, +0x7c424000, +0x7c418000, +0x7de5c00b, +0x7de28007, +0x9a80000e, +0x41ac0005, +0x9ac00000, +0x0aec0001, +0x30dc0010, +0x99c00004, +0x00000000, +0x8000020b, +0xc91d0000, +0x8000020b, +0xc91e0000, +0xcc800040, +0xccc00040, +0xd0400040, +0xc80c0025, +0x94c0fde4, +0xc8100008, +0xcd000040, +0xd4000fc0, +0x80000000, +0xd4000fa2, +0xd4000340, +0xd4000fc0, +0xd4000fa2, +0xcc800040, +0xd0400040, +0x7c408000, +0xa0000000, +0x7e82800b, +0xd40003c0, +0xd4000fc0, +0xd4000fa2, +0xcc800040, +0xd0400040, +0x7c408000, +0xa0000000, +0x7e82800b, +0x7c40c000, +0x30d00006, +0x0d100006, +0x99000007, +0xc8140015, +0x99400005, +0xcc000052, +0xd4000340, +0xd4000fc0, +0xd4000fa2, +0xcc800040, +0xccc00040, +0x80000000, +0xd0400040, +0x7c40c000, +0xcc4d0000, +0xdc3a0000, +0x9780fdbd, +0x04cc0001, +0x80000242, +0xcc4d0000, +0x80000000, +0xd040007f, +0xcc00007f, +0x80000000, +0xcc00007f, +0xcc00007f, +0x88000000, +0xcc00007f, +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, +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, +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, +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, +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, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00030222, +0x0004022a, +0x0005009f, +0x00020003, +0x0006003c, +0x00070027, +0x00080191, +0x00090044, +0x000a002d, +0x00100247, +0x001700f0, +0x002201d7, +0x002301e8, +0x0026004c, +0x0027005f, +0x0020011a, +0x00280092, +0x0029004f, +0x002a0083, +0x002b0064, +0x002f008d, +0x003200d8, +0x00340232, +0x00360074, +0x0039010a, +0x003c01fc, +0x003f009f, +0x00410005, +0x00440194, +0x0048019d, +0x004901c5, +0x004a01cf, +0x00550225, +0x0056022d, +0x0060000a, +0x0061002a, +0x00620030, +0x00630030, +0x00640030, +0x00650030, +0x00660030, +0x00670030, +0x00680037, +0x0069003f, +0x006a0047, +0x006b0047, +0x006c0047, +0x006d0047, +0x006e0047, +0x006f0047, +0x00700047, +0x00730247, +0x007b0240, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +0x00000005, +}; + +static const u32 RV710_cp_microcode[] = { +0xcc0003ea, +0x04080003, +0xcc800043, +0x7c408000, +0xa0000000, +0xcc800062, +0x80000003, +0xd040007f, +0x80000003, +0xcc400041, +0x7c40c000, +0xc0160004, +0x30d03fff, +0x7d15000c, +0xcc110000, +0x28d8001e, +0x31980001, +0x28dc001f, +0xc8200004, +0x95c00006, +0x7c424000, +0xcc000062, +0x7e56800c, +0xcc290000, +0xc8240004, +0x7e26000b, +0x95800006, +0x7c42c000, +0xcc000062, +0x7ed7000c, +0xcc310000, +0xc82c0004, +0x7e2e000c, +0xcc000062, +0x31103fff, +0x80000003, +0xce110000, +0x7c40c000, +0x80000003, +0xcc400040, +0x80000003, +0xcc412257, +0x7c418000, +0xcc400045, +0xcc400048, +0xcc41225c, +0xcc41a1fc, +0x7c408000, +0xa0000000, +0xcc800062, +0xcc400045, +0xcc400048, +0x7c40c000, +0xcc41225c, +0xcc41a1fc, +0x7c408000, +0xa0000000, +0xcc800062, +0xcc000045, +0xcc000048, +0xcc41225c, +0xcc41a1fc, +0x7c408000, +0xa0000000, +0xcc800062, +0x040ca1fd, +0xc0120001, +0xcc000045, +0xcc000048, +0x7cd0c00c, +0xcc41225c, +0xcc41a1fc, +0xd04d0000, +0x7c408000, +0xa0000000, +0xcc800062, +0x80000003, +0xcc41225d, +0x7c408000, +0x7c40c000, +0xc02a0002, +0x7c410000, +0x7d29000c, +0x30940001, +0x30980006, +0x309c0300, +0x29dc0008, +0x7c420000, +0x7c424000, +0x9540000f, +0xc02e0004, +0x05f02258, +0x7f2f000c, +0xcc310000, +0xc8280004, +0xccc12169, +0xcd01216a, +0xce81216b, +0x0db40002, +0xcc01216c, +0x9740000e, +0x0db40000, +0x8000007d, +0xc834000a, +0x0db40002, +0x97400009, +0x0db40000, +0xc02e0004, +0x05f02258, +0x7f2f000c, +0xcc310000, +0xc8280004, +0x8000007d, +0xc834000a, +0x97400004, +0x7e028000, +0x8000007d, +0xc834000a, +0x0db40004, +0x9740ff8c, +0x00000000, +0xce01216d, +0xce41216e, +0xc8280003, +0xc834000a, +0x9b400004, +0x043c0005, +0x8400026d, +0xcc000062, +0x0df40000, +0x9740000b, +0xc82c03e6, +0xce81a2b7, +0xc0300006, +0x7ef34028, +0xc0300020, +0x7f6b8020, +0x7fb3c029, +0xcf81a2c4, +0x80000003, +0xcfc1a2d1, +0x0df40001, +0x9740000b, +0xc82c03e7, +0xce81a2bb, +0xc0300006, +0x7ef34028, +0xc0300020, +0x7f6b8020, +0x7fb3c029, +0xcf81a2c5, +0x80000003, +0xcfc1a2d2, +0x0df40002, +0x9740000b, +0xc82c03e8, +0xce81a2bf, +0xc0300006, +0x7ef34028, +0xc0300020, +0x7f6b8020, +0x7fb3c029, +0xcf81a2c6, +0x80000003, +0xcfc1a2d3, +0xc82c03e9, +0xce81a2c3, +0xc0300006, +0x7ef34028, +0xc0300020, +0x7f6b8020, +0x7fb3c029, +0xcf81a2c7, +0x80000003, +0xcfc1a2d4, +0x80000003, +0xcc400042, +0x7c40c000, +0x7c410000, +0x2914001d, +0x31540001, +0x9940000c, +0x31181000, +0xc81c0011, +0x95c00000, +0xc81c0011, +0xccc12100, +0xcd012101, +0xccc12102, +0xcd012103, +0x04180004, +0x8000037e, +0xcd81a2a4, +0xc02a0004, +0x95800008, +0x36a821a3, +0xcc290000, +0xc8280004, +0xc81c0011, +0x0de40040, +0x9640ffff, +0xc81c0011, +0xccc12170, +0xcd012171, +0xc8200012, +0x96000000, +0xc8200012, +0x8000037e, +0xcc000064, +0x7c40c000, +0x7c410000, +0xcc000045, +0xcc000048, +0x40d40003, +0xcd41225c, +0xcd01a1fc, +0xc01a0001, +0x041ca1fd, +0x7dd9c00c, +0x7c420000, +0x08cc0001, +0x06240001, +0x06280002, +0xce1d0000, +0xce5d0000, +0x98c0fffa, +0xce9d0000, +0x7c408000, +0xa0000000, +0xcc800062, +0x7c40c000, +0x30d00001, +0x28cc0001, +0x7c414000, +0x95000006, +0x7c418000, +0xcd41216d, +0xcd81216e, +0x800000f4, +0xc81c0003, +0xc0220004, +0x7e16000c, +0xcc210000, +0xc81c0004, +0x7c424000, +0x98c00004, +0x7c428000, +0x80000003, +0xcde50000, +0xce412169, +0xce81216a, +0xcdc1216b, +0x80000003, +0xcc01216c, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0x7c41c000, +0x28a40008, +0x326400ff, +0x0e68003c, +0x9680000a, +0x7c020000, +0x7c420000, +0x1e300003, +0xcc00006a, +0x9b000003, +0x42200005, +0x04200040, +0x80000111, +0x7c024000, +0x7e024000, +0x9a400000, +0x0a640001, +0x30ec0010, +0x9ac0000a, +0xcc000062, +0xc02a0004, +0xc82c0021, +0x7e92800c, +0xcc000041, +0xcc290000, +0xcec00021, +0x80000121, +0xc8300004, +0xcd01216d, +0xcd41216e, +0xc8300003, +0x7f1f000b, +0x30f40007, +0x27780001, +0x9740002a, +0x07b80126, +0x9f800000, +0x00000000, +0x80000136, +0x7f1b8004, +0x8000013a, +0x7f1b8005, +0x8000013e, +0x7f1b8002, +0x80000142, +0x7f1b8003, +0x80000146, +0x7f1b8007, +0x8000014a, +0x7f1b8006, +0x8000014f, +0x28a40008, +0x9b800019, +0x28a40008, +0x8000015f, +0x326400ff, +0x9b800015, +0x28a40008, +0x8000015f, +0x326400ff, +0x9b800011, +0x28a40008, +0x8000015f, +0x326400ff, +0x9b80000d, +0x28a40008, +0x8000015f, +0x326400ff, +0x9b800009, +0x28a40008, +0x8000015f, +0x326400ff, +0x9b800005, +0x28a40008, +0x8000015f, +0x326400ff, +0x28a40008, +0x326400ff, +0x0e68003c, +0x9a80feb2, +0x28ec0008, +0x7c434000, +0x7c438000, +0x7c43c000, +0x96c00007, +0xcc000062, +0xcf412169, +0xcf81216a, +0xcfc1216b, +0x80000003, +0xcc01216c, +0x80000003, +0xcff50000, +0xcc00006b, +0x84000381, +0x0e68003c, +0x9a800004, +0xc8280015, +0x80000003, +0xd040007f, +0x9680ffab, +0x7e024000, +0x8400023b, +0xc00e0002, +0xcc000041, +0x80000239, +0xccc1304a, +0x7c40c000, +0x7c410000, +0xc01e0001, +0x29240012, +0xc0220002, +0x96400005, +0xc0260004, +0xc027fffb, +0x7d25000b, +0xc0260000, +0x7dd2800b, +0x7e12c00b, +0x7d25000c, +0x7c414000, +0x7c418000, +0xccc12169, +0x9a80000a, +0xcd01216a, +0xcd41216b, +0x96c0fe83, +0xcd81216c, +0xc8300018, +0x97000000, +0xc8300018, +0x80000003, +0xcc000018, +0x84000381, +0xcc00007f, +0xc8140013, +0xc8180014, +0xcd41216b, +0x96c0fe77, +0xcd81216c, +0x80000183, +0xc8300018, +0xc80c0008, +0x98c00000, +0xc80c0008, +0x7c410000, +0x95000002, +0x00000000, +0x7c414000, +0xc8200009, +0xcc400043, +0xce01a1f4, +0xcc400044, +0xc00e8000, +0x7c424000, +0x7c428000, +0x2aac001f, +0x96c0fe64, +0xc035f000, +0xce4003e2, +0x32780003, +0x267c0008, +0x7ff7c00b, +0x7ffbc00c, +0x2a780018, +0xcfc003e3, +0xcf8003e4, +0x26b00002, +0x7f3f0000, +0xcf0003e5, +0x8000031f, +0x7c80c000, +0x7c40c000, +0x28d00008, +0x3110000f, +0x9500000f, +0x25280001, +0x06a801b4, +0x9e800000, +0x00000000, +0x800001d5, +0xc0120800, +0x800001e3, +0xc814000f, +0x800001ea, +0xc8140010, +0x800001f1, +0xccc1a2a4, +0x800001fa, +0xc8140011, +0x30d0003f, +0x0d280015, +0x9a800012, +0x0d28001e, +0x9a80001e, +0x0d280020, +0x9a800023, +0x0d24000f, +0x0d280010, +0x7e6a800c, +0x9a800026, +0x0d200004, +0x0d240014, +0x0d280028, +0x7e62400c, +0x7ea6800c, +0x9a80002a, +0xc8140011, +0x80000003, +0xccc1a2a4, +0xc0120800, +0x7c414000, +0x7d0cc00c, +0xc0120008, +0x29580003, +0x295c000c, +0x7c420000, +0x7dd1c00b, +0x26200014, +0x7e1e400c, +0x7e4e800c, +0xce81a2a4, +0x80000003, +0xcd81a1fe, +0xc814000f, +0x0410210e, +0x95400000, +0xc814000f, +0xd0510000, +0x80000003, +0xccc1a2a4, +0xc8140010, +0x04102108, +0x95400000, +0xc8140010, +0xd0510000, +0x80000003, +0xccc1a2a4, +0xccc1a2a4, +0x04100001, +0xcd000019, +0x84000381, +0xcc00007f, +0xc8100019, +0x99000000, +0xc8100019, +0x80000004, +0x7c408000, +0x04102100, +0x95400000, +0xc8140011, +0xd0510000, +0x8000037e, +0xccc1a2a4, +0x7c40c000, +0xcc40000d, +0x94c0fe01, +0xcc40000e, +0x7c410000, +0x95000005, +0x08cc0001, +0xc8140005, +0x99400014, +0x00000000, +0x98c0fffb, +0x7c410000, +0x80000004, +0x7d008000, +0xc8140005, +0x7c40c000, +0x9940000c, +0xc818000c, +0x7c410000, +0x9580fdf0, +0xc820000e, +0xc81c000d, +0x66200020, +0x7e1e002c, +0x25240002, +0x7e624020, +0x80000003, +0xcce60000, +0x7c410000, +0xcc00006c, +0xcc00006d, +0xc818001f, +0xc81c001e, +0x65980020, +0x7dd9c02c, +0x7cd4c00c, +0xccde0000, +0x45dc0004, +0xc8280017, +0x9680000f, +0xc00e0001, +0x28680008, +0x2aac0016, +0x32a800ff, +0x0eb00049, +0x7f2f000b, +0x97000006, +0x00000000, +0xc8140005, +0x7c40c000, +0x80000223, +0x7c410000, +0x80000226, +0xd040007f, +0x8400023b, +0xcc000041, +0xccc1304a, +0x94000000, +0xc83c001a, +0x043c0005, +0xcfc1a2a4, +0xc0361f90, +0xc0387fff, +0x7c03c010, +0x7f7b400c, +0xcf41217c, +0xcfc1217d, +0xcc01217e, +0xc03a0004, +0x0434217f, +0x7f7b400c, +0xcc350000, +0xc83c0004, +0x2bfc001f, +0x04380020, +0x97c00005, +0xcc000062, +0x9b800000, +0x0bb80001, +0x80000247, +0xcc000071, +0xcc01a1f4, +0x04380016, +0xc0360002, +0xcf81a2a4, +0x88000000, +0xcf412010, +0x7c40c000, +0x28d0001c, +0x95000005, +0x04d40001, +0xcd400065, +0x80000003, +0xcd400068, +0x09540002, +0x80000003, +0xcd400066, +0x8400026c, +0xc81803ea, +0x7c40c000, +0x9980fd9f, +0xc8140016, +0x08d00001, +0x9940002b, +0xcd000068, +0x7c408000, +0xa0000000, +0xcc800062, +0x043c0005, +0xcfc1a2a4, +0xcc01a1f4, +0x84000381, +0xcc000046, +0x88000000, +0xcc00007f, +0x8400027e, +0xc81803ea, +0x7c40c000, +0x9980fd8d, +0xc8140016, +0x08d00001, +0x99400019, +0xcd000068, +0x7c408000, +0xa0000000, +0xcc800062, +0x043c0022, +0xcfc1a2a4, +0x84000381, +0xcc000047, +0x88000000, +0xcc00007f, +0xc8100016, +0x9900000d, +0xcc400067, +0x80000004, +0x7c408000, +0xc81803ea, +0x9980fd79, +0x7c40c000, +0x94c00003, +0xc8100016, +0x99000004, +0xccc00068, +0x80000004, +0x7c408000, +0x8400023b, +0xc0148000, +0xcc000041, +0xcd41304a, +0xc0148000, +0x99000000, +0xc8100016, +0x80000004, +0x7c408000, +0xc0120001, +0x7c51400c, +0x80000003, +0xd0550000, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0x291c001f, +0xccc0004a, +0xcd00004b, +0x95c00003, +0xc01c8000, +0xcdc12010, +0xdd830000, +0x055c2000, +0xcc000062, +0x80000003, +0xd81f4100, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0xccc0004c, +0xcd00004d, +0xdd830000, +0x055ca000, +0x80000003, +0xd81f4100, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0xccc0004e, +0xcd00004f, +0xdd830000, +0x055cc000, +0x80000003, +0xd81f4100, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0xccc00050, +0xcd000051, +0xdd830000, +0x055cf8e0, +0x80000003, +0xd81f4100, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0xccc00052, +0xcd000053, +0xdd830000, +0x055cf880, +0x80000003, +0xd81f4100, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0xccc00054, +0xcd000055, +0xdd830000, +0x055ce000, +0x80000003, +0xd81f4100, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0xccc00056, +0xcd000057, +0xdd830000, +0x055cf000, +0x80000003, +0xd81f4100, +0x7c40c000, +0x7c410000, +0x7c414000, +0x7c418000, +0xccc00058, +0xcd000059, +0xdd830000, +0x055cf3fc, +0x80000003, +0xd81f4100, +0xd0432000, +0x7c408000, +0xa0000000, +0xcc800062, +0xd043a000, +0x7c408000, +0xa0000000, +0xcc800062, +0xd043c000, +0x7c408000, +0xa0000000, +0xcc800062, +0xd043f8e0, +0x7c408000, +0xa0000000, +0xcc800062, +0xd043f880, +0x7c408000, +0xa0000000, +0xcc800062, +0xd043e000, +0x7c408000, +0xa0000000, +0xcc800062, +0xd043f000, +0x7c408000, +0xa0000000, +0xcc800062, +0xd043f3fc, +0x7c408000, +0xa0000000, +0xcc800062, +0xc81403e0, +0xcc430000, +0xcc430000, +0xcc430000, +0x7d45c000, +0xcdc30000, +0xd0430000, +0x7c408000, +0xa0000000, +0xcc800062, +0x7c40c000, +0xc81003e2, +0xc81403e5, +0xc81803e3, +0xc81c03e4, +0xcd812169, +0xcdc1216a, +0xccc1216b, +0xcc01216c, +0x04200004, +0x7da18000, +0x7d964002, +0x9640fcd9, +0xcd8003e3, +0x31280003, +0xc02df000, +0x25180008, +0x7dad800b, +0x7da9800c, +0x80000003, +0xcd8003e3, +0x308cffff, +0xd04d0000, +0x7c408000, +0xa0000000, +0xcc800062, +0xc8140020, +0x15580002, +0x9580ffff, +0xc8140020, +0xcc00006e, +0xcc412180, +0x7c40c000, +0xccc1218d, +0xcc412181, +0x28d0001f, +0x34588000, +0xcd81218c, +0x9500fcbf, +0xcc412182, +0xc8140020, +0x9940ffff, +0xc8140020, +0x80000004, +0x7c408000, +0x7c40c000, +0x28d00018, +0x31100001, +0xc0160080, +0x95000003, +0xc02a0004, +0x7cd4c00c, +0xccc1217c, +0xcc41217d, +0xcc41217e, +0x7c418000, +0x1db00003, +0x36a0217f, +0x9b000003, +0x419c0005, +0x041c0040, +0x99c00000, +0x09dc0001, +0xcc210000, +0xc8240004, +0x2a6c001f, +0x419c0005, +0x9ac0fffa, +0xcc800062, +0x80000004, +0x7c408000, +0x7c40c000, +0x04d403e6, +0x80000003, +0xcc540000, +0x8000037e, +0xcc4003ea, +0xc01c8000, +0x044ca000, +0xcdc12010, +0x7c410000, +0xc8140009, +0x04180000, +0x041c0008, +0xcd800071, +0x09dc0001, +0x05980001, +0xcd0d0000, +0x99c0fffc, +0xcc800062, +0x8000037e, +0xcd400071, +0xc00e0100, +0xcc000041, +0xccc1304a, +0xc83c007f, +0xcc00007f, +0x80000003, +0xcc00007f, +0xcc00007f, +0x88000000, +0xcc00007f, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +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, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00000000, +0x00010333, +0x00100006, +0x00170008, +0x0021000a, +0x0027002a, +0x00280025, +0x0029002b, +0x002a0028, +0x002b002b, +0x002d003a, +0x002e0041, +0x002f004c, +0x0034004e, +0x00360032, +0x003900b1, +0x003a00d1, +0x003b00e6, +0x003c00fe, +0x003d016d, +0x003f00af, +0x00410338, +0x0043034b, +0x00440190, +0x004500fe, +0x004601ae, +0x004701ae, +0x00480200, +0x0049020e, +0x004a0257, +0x004b0284, +0x00520261, +0x00530273, +0x00540289, +0x0057029b, +0x0060029f, +0x006102ae, +0x006202b8, +0x006302c2, +0x006402cc, +0x006502d6, +0x006602e0, +0x006702ea, +0x006802f4, +0x006902f8, +0x006a02fc, +0x006b0300, +0x006c0304, +0x006d0308, +0x006e030c, +0x006f0310, +0x00700314, +0x00720365, +0x0074036b, +0x00790369, +0x007c031e, +0x000f037a, +0x000f037a, +0x000f037a, +0x000f037a, +0x000f037a, +0x000f037a, +0x000f037a, +0x000f037a, +0x000f037a, +0x000f037a, +0x000f037a, +0x000f037a, +0x000f037a, +0x000f037a, +0x000f037a, +0x000f037a, +0x000f037a, +0x000f037a, +0x000f037a, +0x000f037a, +0x000f037a, +0x000f037a, +0x000f037a, +0x000f037a, +0x000f037a, +}; + +#endif --- linux-2.6.28.orig/drivers/gpu/drm/radeon/r600_cp.c +++ linux-2.6.28/drivers/gpu/drm/radeon/r600_cp.c @@ -0,0 +1,2286 @@ +/* r600_cp.c -- CP support for Radeon -*- linux-c -*- */ +/* + * Copyright 2008 Advanced Micro Devices, Inc. + * Copyright 2008 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Dave Airlie + * Alex Deucher + */ + +#include "drmP.h" +#include "drm.h" +#include "radeon_drm.h" +#include "radeon_drv.h" +#include "r300_reg.h" + +#include "r600_microcode.h" + +# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ +# define ATI_PCIGART_PAGE_MASK (~(ATI_PCIGART_PAGE_SIZE-1)) + +#define R600_PTE_VALID (1 << 0) +#define R600_PTE_SYSTEM (1 << 1) +#define R600_PTE_SNOOPED (1 << 2) +#define R600_PTE_READABLE (1 << 5) +#define R600_PTE_WRITEABLE (1 << 6) + +/* MAX values used for gfx init */ +#define R6XX_MAX_SH_GPRS 256 +#define R6XX_MAX_TEMP_GPRS 16 +#define R6XX_MAX_SH_THREADS 256 +#define R6XX_MAX_SH_STACK_ENTRIES 4096 +#define R6XX_MAX_BACKENDS 8 +#define R6XX_MAX_BACKENDS_MASK 0xff +#define R6XX_MAX_SIMDS 8 +#define R6XX_MAX_SIMDS_MASK 0xff +#define R6XX_MAX_PIPES 8 +#define R6XX_MAX_PIPES_MASK 0xff + +#define R7XX_MAX_SH_GPRS 256 +#define R7XX_MAX_TEMP_GPRS 16 +#define R7XX_MAX_SH_THREADS 256 +#define R7XX_MAX_SH_STACK_ENTRIES 4096 +#define R7XX_MAX_BACKENDS 8 +#define R7XX_MAX_BACKENDS_MASK 0xff +#define R7XX_MAX_SIMDS 16 +#define R7XX_MAX_SIMDS_MASK 0xffff +#define R7XX_MAX_PIPES 8 +#define R7XX_MAX_PIPES_MASK 0xff + +static int r600_do_wait_for_fifo(drm_radeon_private_t *dev_priv, int entries) +{ + int i; + + dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; + + for (i = 0; i < dev_priv->usec_timeout; i++) { + int slots; + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) + slots = (RADEON_READ(R600_GRBM_STATUS) + & R700_CMDFIFO_AVAIL_MASK); + else + slots = (RADEON_READ(R600_GRBM_STATUS) + & R600_CMDFIFO_AVAIL_MASK); + if (slots >= entries) + return 0; + DRM_UDELAY(1); + } + DRM_INFO("wait for fifo failed status : 0x%08X 0x%08X\n", + RADEON_READ(R600_GRBM_STATUS), + RADEON_READ(R600_GRBM_STATUS2)); + + return -EBUSY; +} + +static int r600_do_wait_for_idle(drm_radeon_private_t *dev_priv) +{ + int i, ret; + + dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; + + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) + ret = r600_do_wait_for_fifo(dev_priv, 8); + else + ret = r600_do_wait_for_fifo(dev_priv, 16); + if (ret) + return ret; + for (i = 0; i < dev_priv->usec_timeout; i++) { + if (!(RADEON_READ(R600_GRBM_STATUS) & R600_GUI_ACTIVE)) + return 0; + DRM_UDELAY(1); + } + DRM_INFO("wait idle failed status : 0x%08X 0x%08X\n", + RADEON_READ(R600_GRBM_STATUS), + RADEON_READ(R600_GRBM_STATUS2)); + + return -EBUSY; +} + +void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info) +{ +#ifdef __linux__ + struct drm_sg_mem *entry = dev->sg; + int max_pages; + int pages; + int i; + + if (!entry) + return; + +#endif + if (gart_info->bus_addr) { +#ifdef __linux__ + max_pages = (gart_info->table_size / sizeof(u64)); + pages = (entry->pages <= max_pages) + ? entry->pages : max_pages; + + for (i = 0; i < pages; i++) { + if (!entry->busaddr[i]) + break; + pci_unmap_page(dev->pdev, entry->busaddr[i], + PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); + } +#endif + if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) + gart_info->bus_addr = 0; + } +} + +/* R600 has page table setup */ +int r600_page_table_init(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + struct drm_ati_pcigart_info *gart_info = &dev_priv->gart_info; + struct drm_sg_mem *entry = dev->sg; + int ret = 0; + int i, j; + int max_pages, pages; + u64 *pci_gart, page_base; + dma_addr_t entry_addr; + + /* okay page table is available - lets rock */ + + /* PTEs are 64-bits */ + pci_gart = (u64 *)gart_info->addr; + + max_pages = (gart_info->table_size / sizeof(u64)); + pages = (entry->pages <= max_pages) ? entry->pages : max_pages; + + memset(pci_gart, 0, max_pages * sizeof(u64)); + + for (i = 0; i < pages; i++) { +#ifdef __linux__ + entry->busaddr[i] = pci_map_page(dev->pdev, + entry->pagelist[i], 0, + PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); + if (entry->busaddr[i] == 0) { + DRM_ERROR("unable to map PCIGART pages!\n"); + r600_page_table_cleanup(dev, gart_info); + goto done; + } +#endif + entry_addr = entry->busaddr[i]; + for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { + page_base = (u64) entry_addr & ATI_PCIGART_PAGE_MASK; + page_base |= R600_PTE_VALID | R600_PTE_SYSTEM | R600_PTE_SNOOPED; + page_base |= R600_PTE_READABLE | R600_PTE_WRITEABLE; + + *pci_gart = page_base; + + if ((i % 128) == 0) + DRM_DEBUG("page entry %d: 0x%016llx\n", + i, (unsigned long long)page_base); + pci_gart++; + entry_addr += ATI_PCIGART_PAGE_SIZE; + } + } + ret = 1; +#ifdef __linux__ +done: +#endif + return ret; +} + +static void r600_vm_flush_gart_range(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + u32 resp, countdown = 1000; + RADEON_WRITE(R600_VM_CONTEXT0_INVALIDATION_LOW_ADDR, dev_priv->gart_vm_start >> 12); + RADEON_WRITE(R600_VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); + RADEON_WRITE(R600_VM_CONTEXT0_REQUEST_RESPONSE, 2); + + do { + resp = RADEON_READ(R600_VM_CONTEXT0_REQUEST_RESPONSE); + countdown--; + DRM_UDELAY(1); + } while (((resp & 0xf0) == 0) && countdown); +} + +static void r600_vm_init(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + /* initialise the VM to use the page table we constructed up there */ + u32 vm_c0, i; + u32 mc_rd_a; + u32 vm_l2_cntl, vm_l2_cntl3; + /* okay set up the PCIE aperture type thingo */ + RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR, dev_priv->gart_vm_start >> 12); + RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); + RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); + + /* setup MC RD a */ + mc_rd_a = R600_MCD_L1_TLB | R600_MCD_L1_FRAG_PROC | R600_MCD_SYSTEM_ACCESS_MODE_IN_SYS | + R600_MCD_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | R600_MCD_EFFECTIVE_L1_TLB_SIZE(5) | + R600_MCD_EFFECTIVE_L1_QUEUE_SIZE(5) | R600_MCD_WAIT_L2_QUERY; + + RADEON_WRITE(R600_MCD_RD_A_CNTL, mc_rd_a); + RADEON_WRITE(R600_MCD_RD_B_CNTL, mc_rd_a); + + RADEON_WRITE(R600_MCD_WR_A_CNTL, mc_rd_a); + RADEON_WRITE(R600_MCD_WR_B_CNTL, mc_rd_a); + + RADEON_WRITE(R600_MCD_RD_GFX_CNTL, mc_rd_a); + RADEON_WRITE(R600_MCD_WR_GFX_CNTL, mc_rd_a); + + RADEON_WRITE(R600_MCD_RD_SYS_CNTL, mc_rd_a); + RADEON_WRITE(R600_MCD_WR_SYS_CNTL, mc_rd_a); + + RADEON_WRITE(R600_MCD_RD_HDP_CNTL, mc_rd_a | R600_MCD_L1_STRICT_ORDERING); + RADEON_WRITE(R600_MCD_WR_HDP_CNTL, mc_rd_a /*| R600_MCD_L1_STRICT_ORDERING*/); + + RADEON_WRITE(R600_MCD_RD_PDMA_CNTL, mc_rd_a); + RADEON_WRITE(R600_MCD_WR_PDMA_CNTL, mc_rd_a); + + RADEON_WRITE(R600_MCD_RD_SEM_CNTL, mc_rd_a | R600_MCD_SEMAPHORE_MODE); + RADEON_WRITE(R600_MCD_WR_SEM_CNTL, mc_rd_a); + + vm_l2_cntl = R600_VM_L2_CACHE_EN | R600_VM_L2_FRAG_PROC | R600_VM_ENABLE_PTE_CACHE_LRU_W; + vm_l2_cntl |= R600_VM_L2_CNTL_QUEUE_SIZE(7); + RADEON_WRITE(R600_VM_L2_CNTL, vm_l2_cntl); + + RADEON_WRITE(R600_VM_L2_CNTL2, 0); + vm_l2_cntl3 = R600_VM_L2_CNTL3_BANK_SELECT_0(0) | + R600_VM_L2_CNTL3_BANK_SELECT_1(1) | + R600_VM_L2_CNTL3_CACHE_UPDATE_MODE(2); + RADEON_WRITE(R600_VM_L2_CNTL3, vm_l2_cntl3); + + vm_c0 = R600_VM_ENABLE_CONTEXT | R600_VM_PAGE_TABLE_DEPTH_FLAT; + + RADEON_WRITE(R600_VM_CONTEXT0_CNTL, vm_c0); + + vm_c0 &= ~R600_VM_ENABLE_CONTEXT; + + /* disable all other contexts */ + for (i = 1; i < 8; i++) + RADEON_WRITE(R600_VM_CONTEXT0_CNTL + (i * 4), vm_c0); + + RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, dev_priv->gart_info.bus_addr >> 12); + RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_START_ADDR, dev_priv->gart_vm_start >> 12); + RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_END_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); + + r600_vm_flush_gart_range(dev); +} + +/* load r600 microcode */ +static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv) +{ + int i; + + r600_do_cp_stop(dev_priv); + + RADEON_WRITE(R600_CP_RB_CNTL, + R600_RB_NO_UPDATE | + R600_RB_BLKSZ(15) | + R600_RB_BUFSZ(3)); + + RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); + RADEON_READ(R600_GRBM_SOFT_RESET); + DRM_UDELAY(15000); + RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); + + + RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); + + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600)) { + + DRM_INFO("Loading R600 CP Microcode\n"); + for (i = 0; i < PM4_UCODE_SIZE; i++) { + RADEON_WRITE(R600_CP_ME_RAM_DATA, + R600_cp_microcode[i][0]); + RADEON_WRITE(R600_CP_ME_RAM_DATA, + R600_cp_microcode[i][1]); + RADEON_WRITE(R600_CP_ME_RAM_DATA, + R600_cp_microcode[i][2]); + } + + RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); + + DRM_INFO("Loading R600 PFP Microcode\n"); + for (i = 0; i < PFP_UCODE_SIZE; i++) + RADEON_WRITE(R600_CP_PFP_UCODE_DATA, R600_pfp_microcode[i]); + } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610)) { + + DRM_INFO("Loading RV610 CP Microcode\n"); + for (i = 0; i < PM4_UCODE_SIZE; i++) { + RADEON_WRITE(R600_CP_ME_RAM_DATA, + RV610_cp_microcode[i][0]); + RADEON_WRITE(R600_CP_ME_RAM_DATA, + RV610_cp_microcode[i][1]); + RADEON_WRITE(R600_CP_ME_RAM_DATA, + RV610_cp_microcode[i][2]); + } + + RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); + + DRM_INFO("Loading RV610 PFP Microcode\n"); + for (i = 0; i < PFP_UCODE_SIZE; i++) + RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV610_pfp_microcode[i]); + } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630)) { + + DRM_INFO("Loading RV630 CP Microcode\n"); + for (i = 0; i < PM4_UCODE_SIZE; i++) { + RADEON_WRITE(R600_CP_ME_RAM_DATA, + RV630_cp_microcode[i][0]); + RADEON_WRITE(R600_CP_ME_RAM_DATA, + RV630_cp_microcode[i][1]); + RADEON_WRITE(R600_CP_ME_RAM_DATA, + RV630_cp_microcode[i][2]); + } + + RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); + + DRM_INFO("Loading RV630 PFP Microcode\n"); + for (i = 0; i < PFP_UCODE_SIZE; i++) + RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV630_pfp_microcode[i]); + } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620)) { + + DRM_INFO("Loading RV620 CP Microcode\n"); + for (i = 0; i < PM4_UCODE_SIZE; i++) { + RADEON_WRITE(R600_CP_ME_RAM_DATA, + RV620_cp_microcode[i][0]); + RADEON_WRITE(R600_CP_ME_RAM_DATA, + RV620_cp_microcode[i][1]); + RADEON_WRITE(R600_CP_ME_RAM_DATA, + RV620_cp_microcode[i][2]); + } + + RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); + + DRM_INFO("Loading RV620 PFP Microcode\n"); + for (i = 0; i < PFP_UCODE_SIZE; i++) + RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV620_pfp_microcode[i]); + } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV635)) { + + DRM_INFO("Loading RV635 CP Microcode\n"); + for (i = 0; i < PM4_UCODE_SIZE; i++) { + RADEON_WRITE(R600_CP_ME_RAM_DATA, + RV635_cp_microcode[i][0]); + RADEON_WRITE(R600_CP_ME_RAM_DATA, + RV635_cp_microcode[i][1]); + RADEON_WRITE(R600_CP_ME_RAM_DATA, + RV635_cp_microcode[i][2]); + } + + RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); + + DRM_INFO("Loading RV635 PFP Microcode\n"); + for (i = 0; i < PFP_UCODE_SIZE; i++) + RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV635_pfp_microcode[i]); + } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670)) { + + DRM_INFO("Loading RV670 CP Microcode\n"); + for (i = 0; i < PM4_UCODE_SIZE; i++) { + RADEON_WRITE(R600_CP_ME_RAM_DATA, + RV670_cp_microcode[i][0]); + RADEON_WRITE(R600_CP_ME_RAM_DATA, + RV670_cp_microcode[i][1]); + RADEON_WRITE(R600_CP_ME_RAM_DATA, + RV670_cp_microcode[i][2]); + } + + RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); + + DRM_INFO("Loading RV670 PFP Microcode\n"); + for (i = 0; i < PFP_UCODE_SIZE; i++) + RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV670_pfp_microcode[i]); + } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) { + + DRM_INFO("Loading RS780 CP Microcode\n"); + for (i = 0; i < PM4_UCODE_SIZE; i++) { + RADEON_WRITE(R600_CP_ME_RAM_DATA, + RV670_cp_microcode[i][0]); + RADEON_WRITE(R600_CP_ME_RAM_DATA, + RV670_cp_microcode[i][1]); + RADEON_WRITE(R600_CP_ME_RAM_DATA, + RV670_cp_microcode[i][2]); + } + + RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); + + DRM_INFO("Loading RS780 PFP Microcode\n"); + for (i = 0; i < PFP_UCODE_SIZE; i++) + RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV670_pfp_microcode[i]); + } + RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); + RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); + RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0); + +} + +static void r700_vm_init(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + /* initialise the VM to use the page table we constructed up there */ + u32 vm_c0, i; + u32 mc_vm_md_l1; + u32 vm_l2_cntl, vm_l2_cntl3; + /* okay set up the PCIE aperture type thingo */ + RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_LOW_ADDR, dev_priv->gart_vm_start >> 12); + RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); + RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); + + mc_vm_md_l1 = R700_ENABLE_L1_TLB | + R700_ENABLE_L1_FRAGMENT_PROCESSING | + R700_SYSTEM_ACCESS_MODE_IN_SYS | + R700_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | + R700_EFFECTIVE_L1_TLB_SIZE(5) | + R700_EFFECTIVE_L1_QUEUE_SIZE(5); + + RADEON_WRITE(R700_MC_VM_MD_L1_TLB0_CNTL, mc_vm_md_l1); + RADEON_WRITE(R700_MC_VM_MD_L1_TLB1_CNTL, mc_vm_md_l1); + RADEON_WRITE(R700_MC_VM_MD_L1_TLB2_CNTL, mc_vm_md_l1); + RADEON_WRITE(R700_MC_VM_MB_L1_TLB0_CNTL, mc_vm_md_l1); + RADEON_WRITE(R700_MC_VM_MB_L1_TLB1_CNTL, mc_vm_md_l1); + RADEON_WRITE(R700_MC_VM_MB_L1_TLB2_CNTL, mc_vm_md_l1); + RADEON_WRITE(R700_MC_VM_MB_L1_TLB3_CNTL, mc_vm_md_l1); + + vm_l2_cntl = R600_VM_L2_CACHE_EN | R600_VM_L2_FRAG_PROC | R600_VM_ENABLE_PTE_CACHE_LRU_W; + vm_l2_cntl |= R700_VM_L2_CNTL_QUEUE_SIZE(7); + RADEON_WRITE(R600_VM_L2_CNTL, vm_l2_cntl); + + RADEON_WRITE(R600_VM_L2_CNTL2, 0); + vm_l2_cntl3 = R700_VM_L2_CNTL3_BANK_SELECT(0) | + R700_VM_L2_CNTL3_CACHE_UPDATE_MODE(2); + RADEON_WRITE(R600_VM_L2_CNTL3, vm_l2_cntl3); + + vm_c0 = R600_VM_ENABLE_CONTEXT | R600_VM_PAGE_TABLE_DEPTH_FLAT; + + RADEON_WRITE(R600_VM_CONTEXT0_CNTL, vm_c0); + + vm_c0 &= ~R600_VM_ENABLE_CONTEXT; + + /* disable all other contexts */ + for (i = 1; i < 8; i++) + RADEON_WRITE(R600_VM_CONTEXT0_CNTL + (i * 4), vm_c0); + + RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, dev_priv->gart_info.bus_addr >> 12); + RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_START_ADDR, dev_priv->gart_vm_start >> 12); + RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_END_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12); + + r600_vm_flush_gart_range(dev); +} + +/* load r600 microcode */ +static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv) +{ + int i; + + r600_do_cp_stop(dev_priv); + + RADEON_WRITE(R600_CP_RB_CNTL, + R600_RB_NO_UPDATE | + R600_RB_BLKSZ(15) | + R600_RB_BUFSZ(3)); + + RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); + RADEON_READ(R600_GRBM_SOFT_RESET); + DRM_UDELAY(15000); + RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); + + + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770)) { + + RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); + + DRM_INFO("Loading RV770 PFP Microcode\n"); + for (i = 0; i < R700_PFP_UCODE_SIZE; i++) + RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV770_pfp_microcode[i]); + RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); + + RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); + + DRM_INFO("Loading RV770 CP Microcode\n"); + for (i = 0; i < R700_PM4_UCODE_SIZE; i++) + RADEON_WRITE(R600_CP_ME_RAM_DATA, RV770_cp_microcode[i]); + RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); + + } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV730)) { + + RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); + + DRM_INFO("Loading RV730 PFP Microcode\n"); + for (i = 0; i < R700_PFP_UCODE_SIZE; i++) + RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV730_pfp_microcode[i]); + RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); + + RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); + + DRM_INFO("Loading RV730 CP Microcode\n"); + for (i = 0; i < R700_PM4_UCODE_SIZE; i++) + RADEON_WRITE(R600_CP_ME_RAM_DATA, RV730_cp_microcode[i]); + RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); + + } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)) { + + RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); + + DRM_INFO("Loading RV710 PFP Microcode\n"); + for (i = 0; i < R700_PFP_UCODE_SIZE; i++) + RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV710_pfp_microcode[i]); + RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); + + RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); + + DRM_INFO("Loading RV710 CP Microcode\n"); + for (i = 0; i < R700_PM4_UCODE_SIZE; i++) + RADEON_WRITE(R600_CP_ME_RAM_DATA, RV710_cp_microcode[i]); + RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); + + } + RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0); + RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0); + RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0); + +} + +static void r600_test_writeback(drm_radeon_private_t *dev_priv) +{ + u32 tmp; + + /* Start with assuming that writeback doesn't work */ + dev_priv->writeback_works = 0; + + /* Writeback doesn't seem to work everywhere, test it here and possibly + * enable it if it appears to work + */ + DRM_WRITE32(dev_priv->ring_rptr, R600_SCRATCHOFF(1), 0); + RADEON_WRITE(R600_SCRATCH_REG1, 0xdeadbeef); + + for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) { + if (DRM_READ32(dev_priv->ring_rptr, R600_SCRATCHOFF(1)) == + 0xdeadbeef) + break; + DRM_UDELAY(1); + } + + if (tmp < dev_priv->usec_timeout) { + dev_priv->writeback_works = 1; + DRM_INFO("writeback test succeeded in %d usecs\n", tmp); + } else { + dev_priv->writeback_works = 0; + + for (tmp = 0; tmp < 512; tmp += 16) + DRM_DEBUG("%d %x %x %x %x\n", tmp, DRM_READ32(dev_priv->ring_rptr, tmp), + DRM_READ32(dev_priv->ring_rptr, tmp + 4), + DRM_READ32(dev_priv->ring_rptr, tmp + 8), + DRM_READ32(dev_priv->ring_rptr, tmp + 16)); + + DRM_INFO("writeback test failed %x %x\n", DRM_READ32(dev_priv->ring_rptr, R600_SCRATCHOFF(1)), RADEON_READ(R600_SCRATCH_REG1)); + } + if (radeon_no_wb == 1) { + dev_priv->writeback_works = 0; + DRM_INFO("writeback forced off\n"); + } + + if (!dev_priv->writeback_works) { + /* Disable writeback to avoid unnecessary bus master transfers */ + RADEON_WRITE(R600_CP_RB_CNTL, RADEON_READ(R600_CP_RB_CNTL) | RADEON_RB_NO_UPDATE); + RADEON_WRITE(R600_SCRATCH_UMSK, 0); + } +} + +int r600_do_engine_reset(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + u32 cp_ptr, cp_me_cntl, cp_rb_cntl; + + DRM_INFO("Resetting GPU\n"); + + cp_ptr = RADEON_READ(R600_CP_RB_WPTR); + cp_me_cntl = RADEON_READ(R600_CP_ME_CNTL); + RADEON_WRITE(R600_CP_ME_CNTL, R600_CP_ME_HALT); + + RADEON_WRITE(R600_GRBM_SOFT_RESET, 0x7fff); + RADEON_READ(R600_GRBM_SOFT_RESET); + DRM_UDELAY(50); + RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); + RADEON_READ(R600_GRBM_SOFT_RESET); + + RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0); + cp_rb_cntl = RADEON_READ(R600_CP_RB_CNTL); + RADEON_WRITE(R600_CP_RB_CNTL, R600_RB_RPTR_WR_ENA); + + RADEON_WRITE(R600_CP_RB_RPTR_WR, cp_ptr); + RADEON_WRITE(R600_CP_RB_WPTR, cp_ptr); + RADEON_WRITE(R600_CP_RB_CNTL, cp_rb_cntl); + RADEON_WRITE(R600_CP_ME_CNTL, cp_me_cntl); + + /* Reset the CP ring */ + r600_do_cp_reset(dev_priv); + + /* The CP is no longer running after an engine reset */ + dev_priv->cp_running = 0; + + /* Reset any pending vertex, indirect buffers */ + radeon_freelist_reset(dev); + + return 0; + +} + +static u32 r600_get_tile_pipe_to_backend_map(u32 num_tile_pipes, + u32 num_backends, + u32 backend_disable_mask) +{ + u32 backend_map = 0; + u32 enabled_backends_mask; + u32 enabled_backends_count; + u32 cur_pipe; + u32 swizzle_pipe[R6XX_MAX_PIPES]; + u32 cur_backend; + u32 i; + + if (num_tile_pipes > R6XX_MAX_PIPES) + num_tile_pipes = R6XX_MAX_PIPES; + if (num_tile_pipes < 1) + num_tile_pipes = 1; + if (num_backends > R6XX_MAX_BACKENDS) + num_backends = R6XX_MAX_BACKENDS; + if (num_backends < 1) + num_backends = 1; + + enabled_backends_mask = 0; + enabled_backends_count = 0; + for (i = 0; i < R6XX_MAX_BACKENDS; ++i) { + if (((backend_disable_mask >> i) & 1) == 0) { + enabled_backends_mask |= (1 << i); + ++enabled_backends_count; + } + if (enabled_backends_count == num_backends) + break; + } + + if (enabled_backends_count == 0) { + enabled_backends_mask = 1; + enabled_backends_count = 1; + } + + if (enabled_backends_count != num_backends) + num_backends = enabled_backends_count; + + memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R6XX_MAX_PIPES); + switch (num_tile_pipes) { + case 1: + swizzle_pipe[0] = 0; + break; + case 2: + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 1; + break; + case 3: + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 1; + swizzle_pipe[2] = 2; + break; + case 4: + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 1; + swizzle_pipe[2] = 2; + swizzle_pipe[3] = 3; + break; + case 5: + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 1; + swizzle_pipe[2] = 2; + swizzle_pipe[3] = 3; + swizzle_pipe[4] = 4; + break; + case 6: + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 2; + swizzle_pipe[2] = 4; + swizzle_pipe[3] = 5; + swizzle_pipe[4] = 1; + swizzle_pipe[5] = 3; + break; + case 7: + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 2; + swizzle_pipe[2] = 4; + swizzle_pipe[3] = 6; + swizzle_pipe[4] = 1; + swizzle_pipe[5] = 3; + swizzle_pipe[6] = 5; + break; + case 8: + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 2; + swizzle_pipe[2] = 4; + swizzle_pipe[3] = 6; + swizzle_pipe[4] = 1; + swizzle_pipe[5] = 3; + swizzle_pipe[6] = 5; + swizzle_pipe[7] = 7; + break; + } + + cur_backend = 0; + for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { + while (((1 << cur_backend) & enabled_backends_mask) == 0) + cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS; + + backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2))); + + cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS; + } + + return backend_map; +} + +static int r600_count_pipe_bits(uint32_t val) +{ + int i, ret = 0; + for (i = 0; i < 32; i++) { + ret += val & 1; + val >>= 1; + } + return ret; +} + +static void r600_gfx_init(struct drm_device *dev, + drm_radeon_private_t *dev_priv) +{ + int i, j, num_qd_pipes; + u32 sx_debug_1; + u32 tc_cntl; + u32 arb_pop; + u32 num_gs_verts_per_thread; + u32 vgt_gs_per_es; + u32 gs_prim_buffer_depth = 0; + u32 sq_ms_fifo_sizes; + u32 sq_config; + u32 sq_gpr_resource_mgmt_1 = 0; + u32 sq_gpr_resource_mgmt_2 = 0; + u32 sq_thread_resource_mgmt = 0; + u32 sq_stack_resource_mgmt_1 = 0; + u32 sq_stack_resource_mgmt_2 = 0; + u32 hdp_host_path_cntl; + u32 backend_map; + u32 gb_tiling_config = 0; + u32 cc_rb_backend_disable = 0; + u32 cc_gc_shader_pipe_config = 0; + u32 ramcfg; + + /* setup chip specs */ + switch (dev_priv->flags & RADEON_FAMILY_MASK) { + case CHIP_R600: + dev_priv->r600_max_pipes = 4; + dev_priv->r600_max_tile_pipes = 8; + dev_priv->r600_max_simds = 4; + dev_priv->r600_max_backends = 4; + dev_priv->r600_max_gprs = 256; + dev_priv->r600_max_threads = 192; + dev_priv->r600_max_stack_entries = 256; + dev_priv->r600_max_hw_contexts = 8; + dev_priv->r600_max_gs_threads = 16; + dev_priv->r600_sx_max_export_size = 128; + dev_priv->r600_sx_max_export_pos_size = 16; + dev_priv->r600_sx_max_export_smx_size = 128; + dev_priv->r600_sq_num_cf_insts = 2; + break; + case CHIP_RV630: + case CHIP_RV635: + dev_priv->r600_max_pipes = 2; + dev_priv->r600_max_tile_pipes = 2; + dev_priv->r600_max_simds = 3; + dev_priv->r600_max_backends = 1; + dev_priv->r600_max_gprs = 128; + dev_priv->r600_max_threads = 192; + dev_priv->r600_max_stack_entries = 128; + dev_priv->r600_max_hw_contexts = 8; + dev_priv->r600_max_gs_threads = 4; + dev_priv->r600_sx_max_export_size = 128; + dev_priv->r600_sx_max_export_pos_size = 16; + dev_priv->r600_sx_max_export_smx_size = 128; + dev_priv->r600_sq_num_cf_insts = 2; + break; + case CHIP_RV610: + case CHIP_RS780: + case CHIP_RV620: + dev_priv->r600_max_pipes = 1; + dev_priv->r600_max_tile_pipes = 1; + dev_priv->r600_max_simds = 2; + dev_priv->r600_max_backends = 1; + dev_priv->r600_max_gprs = 128; + dev_priv->r600_max_threads = 192; + dev_priv->r600_max_stack_entries = 128; + dev_priv->r600_max_hw_contexts = 4; + dev_priv->r600_max_gs_threads = 4; + dev_priv->r600_sx_max_export_size = 128; + dev_priv->r600_sx_max_export_pos_size = 16; + dev_priv->r600_sx_max_export_smx_size = 128; + dev_priv->r600_sq_num_cf_insts = 1; + break; + case CHIP_RV670: + dev_priv->r600_max_pipes = 4; + dev_priv->r600_max_tile_pipes = 4; + dev_priv->r600_max_simds = 4; + dev_priv->r600_max_backends = 4; + dev_priv->r600_max_gprs = 192; + dev_priv->r600_max_threads = 192; + dev_priv->r600_max_stack_entries = 256; + dev_priv->r600_max_hw_contexts = 8; + dev_priv->r600_max_gs_threads = 16; + dev_priv->r600_sx_max_export_size = 128; + dev_priv->r600_sx_max_export_pos_size = 16; + dev_priv->r600_sx_max_export_smx_size = 128; + dev_priv->r600_sq_num_cf_insts = 2; + break; + default: + break; + } + + /* Initialize HDP */ + j = 0; + for (i = 0; i < 32; i++) { + RADEON_WRITE((0x2c14 + j), 0x00000000); + RADEON_WRITE((0x2c18 + j), 0x00000000); + RADEON_WRITE((0x2c1c + j), 0x00000000); + RADEON_WRITE((0x2c20 + j), 0x00000000); + RADEON_WRITE((0x2c24 + j), 0x00000000); + j += 0x18; + } + + RADEON_WRITE(R600_GRBM_CNTL, R600_GRBM_READ_TIMEOUT(0xff)); + + /* setup tiling, simd, pipe config */ + ramcfg = RADEON_READ(R600_RAMCFG); + + switch (dev_priv->r600_max_tile_pipes) { + case 1: + gb_tiling_config |= R600_PIPE_TILING(0); + break; + case 2: + gb_tiling_config |= R600_PIPE_TILING(1); + break; + case 4: + gb_tiling_config |= R600_PIPE_TILING(2); + break; + case 8: + gb_tiling_config |= R600_PIPE_TILING(3); + break; + default: + break; + } + + gb_tiling_config |= R600_BANK_TILING((ramcfg >> R600_NOOFBANK_SHIFT) & R600_NOOFBANK_MASK); + + gb_tiling_config |= R600_GROUP_SIZE(0); + + if (((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK) > 3) { + gb_tiling_config |= R600_ROW_TILING(3); + gb_tiling_config |= R600_SAMPLE_SPLIT(3); + } else { + gb_tiling_config |= + R600_ROW_TILING(((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK)); + gb_tiling_config |= + R600_SAMPLE_SPLIT(((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK)); + } + + gb_tiling_config |= R600_BANK_SWAPS(1); + + backend_map = r600_get_tile_pipe_to_backend_map(dev_priv->r600_max_tile_pipes, + dev_priv->r600_max_backends, + (0xff << dev_priv->r600_max_backends) & 0xff); + gb_tiling_config |= R600_BACKEND_MAP(backend_map); + + cc_gc_shader_pipe_config = + R600_INACTIVE_QD_PIPES((R6XX_MAX_PIPES_MASK << dev_priv->r600_max_pipes) & R6XX_MAX_PIPES_MASK); + cc_gc_shader_pipe_config |= + R600_INACTIVE_SIMDS((R6XX_MAX_SIMDS_MASK << dev_priv->r600_max_simds) & R6XX_MAX_SIMDS_MASK); + + cc_rb_backend_disable = + R600_BACKEND_DISABLE((R6XX_MAX_BACKENDS_MASK << dev_priv->r600_max_backends) & R6XX_MAX_BACKENDS_MASK); + + RADEON_WRITE(R600_GB_TILING_CONFIG, gb_tiling_config); + RADEON_WRITE(R600_DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); + RADEON_WRITE(R600_HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); + + RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); + RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); + RADEON_WRITE(R600_GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); + + num_qd_pipes = + R6XX_MAX_BACKENDS - r600_count_pipe_bits(cc_gc_shader_pipe_config & R600_INACTIVE_QD_PIPES_MASK); + RADEON_WRITE(R600_VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & R600_DEALLOC_DIST_MASK); + RADEON_WRITE(R600_VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & R600_VTX_REUSE_DEPTH_MASK); + + /* set HW defaults for 3D engine */ + RADEON_WRITE(R600_CP_QUEUE_THRESHOLDS, (R600_ROQ_IB1_START(0x16) | + R600_ROQ_IB2_START(0x2b))); + + RADEON_WRITE(R600_CP_MEQ_THRESHOLDS, (R600_MEQ_END(0x40) | + R600_ROQ_END(0x40))); + + RADEON_WRITE(R600_TA_CNTL_AUX, (R600_DISABLE_CUBE_ANISO | + R600_SYNC_GRADIENT | + R600_SYNC_WALKER | + R600_SYNC_ALIGNER)); + + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670) + RADEON_WRITE(R600_ARB_GDEC_RD_CNTL, 0x00000021); + + sx_debug_1 = RADEON_READ(R600_SX_DEBUG_1); + sx_debug_1 |= R600_SMX_EVENT_RELEASE; + if (((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_R600)) + sx_debug_1 |= R600_ENABLE_NEW_SMX_ADDRESS; + RADEON_WRITE(R600_SX_DEBUG_1, sx_debug_1); + + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) + RADEON_WRITE(R600_DB_DEBUG, R600_PREZ_MUST_WAIT_FOR_POSTZ_DONE); + else + RADEON_WRITE(R600_DB_DEBUG, 0); + + RADEON_WRITE(R600_DB_WATERMARKS, (R600_DEPTH_FREE(4) | + R600_DEPTH_FLUSH(16) | + R600_DEPTH_PENDING_FREE(4) | + R600_DEPTH_CACHELINE_FREE(16))); + RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0); + RADEON_WRITE(R600_VGT_NUM_INSTANCES, 0); + + RADEON_WRITE(R600_SPI_CONFIG_CNTL, R600_GPR_WRITE_PRIORITY(0)); + RADEON_WRITE(R600_SPI_CONFIG_CNTL_1, R600_VTX_DONE_DELAY(0)); + + sq_ms_fifo_sizes = RADEON_READ(R600_SQ_MS_FIFO_SIZES); + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) { + sq_ms_fifo_sizes = (R600_CACHE_FIFO_SIZE(0xa) | + R600_FETCH_FIFO_HIWATER(0xa) | + R600_DONE_FIFO_HIWATER(0xe0) | + R600_ALU_UPDATE_FIFO_HIWATER(0x8)); + } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630)) { + sq_ms_fifo_sizes &= ~R600_DONE_FIFO_HIWATER(0xff); + sq_ms_fifo_sizes |= R600_DONE_FIFO_HIWATER(0x4); + } + RADEON_WRITE(R600_SQ_MS_FIFO_SIZES, sq_ms_fifo_sizes); + + /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT + * should be adjusted as needed by the 2D/3D drivers. This just sets default values + */ + sq_config = RADEON_READ(R600_SQ_CONFIG); + sq_config &= ~(R600_PS_PRIO(3) | + R600_VS_PRIO(3) | + R600_GS_PRIO(3) | + R600_ES_PRIO(3)); + sq_config |= (R600_DX9_CONSTS | + R600_VC_ENABLE | + R600_PS_PRIO(0) | + R600_VS_PRIO(1) | + R600_GS_PRIO(2) | + R600_ES_PRIO(3)); + + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) { + sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(124) | + R600_NUM_VS_GPRS(124) | + R600_NUM_CLAUSE_TEMP_GPRS(4)); + sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(0) | + R600_NUM_ES_GPRS(0)); + sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(136) | + R600_NUM_VS_THREADS(48) | + R600_NUM_GS_THREADS(4) | + R600_NUM_ES_THREADS(4)); + sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(128) | + R600_NUM_VS_STACK_ENTRIES(128)); + sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(0) | + R600_NUM_ES_STACK_ENTRIES(0)); + } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) { + /* no vertex cache */ + sq_config &= ~R600_VC_ENABLE; + + sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) | + R600_NUM_VS_GPRS(44) | + R600_NUM_CLAUSE_TEMP_GPRS(2)); + sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(17) | + R600_NUM_ES_GPRS(17)); + sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) | + R600_NUM_VS_THREADS(78) | + R600_NUM_GS_THREADS(4) | + R600_NUM_ES_THREADS(31)); + sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(40) | + R600_NUM_VS_STACK_ENTRIES(40)); + sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(32) | + R600_NUM_ES_STACK_ENTRIES(16)); + } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV635)) { + sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) | + R600_NUM_VS_GPRS(44) | + R600_NUM_CLAUSE_TEMP_GPRS(2)); + sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(18) | + R600_NUM_ES_GPRS(18)); + sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) | + R600_NUM_VS_THREADS(78) | + R600_NUM_GS_THREADS(4) | + R600_NUM_ES_THREADS(31)); + sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(40) | + R600_NUM_VS_STACK_ENTRIES(40)); + sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(32) | + R600_NUM_ES_STACK_ENTRIES(16)); + } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670) { + sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) | + R600_NUM_VS_GPRS(44) | + R600_NUM_CLAUSE_TEMP_GPRS(2)); + sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(17) | + R600_NUM_ES_GPRS(17)); + sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) | + R600_NUM_VS_THREADS(78) | + R600_NUM_GS_THREADS(4) | + R600_NUM_ES_THREADS(31)); + sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(64) | + R600_NUM_VS_STACK_ENTRIES(64)); + sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(64) | + R600_NUM_ES_STACK_ENTRIES(64)); + } + + RADEON_WRITE(R600_SQ_CONFIG, sq_config); + RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_1, sq_gpr_resource_mgmt_1); + RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_2, sq_gpr_resource_mgmt_2); + RADEON_WRITE(R600_SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt); + RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_1, sq_stack_resource_mgmt_1); + RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_2, sq_stack_resource_mgmt_2); + + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) || + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) + RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, R600_CACHE_INVALIDATION(R600_TC_ONLY)); + else + RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, R600_CACHE_INVALIDATION(R600_VC_AND_TC)); + + RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_2S, (R600_S0_X(0xc) | + R600_S0_Y(0x4) | + R600_S1_X(0x4) | + R600_S1_Y(0xc))); + RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_4S, (R600_S0_X(0xe) | + R600_S0_Y(0xe) | + R600_S1_X(0x2) | + R600_S1_Y(0x2) | + R600_S2_X(0xa) | + R600_S2_Y(0x6) | + R600_S3_X(0x6) | + R600_S3_Y(0xa))); + RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_8S_WD0, (R600_S0_X(0xe) | + R600_S0_Y(0xb) | + R600_S1_X(0x4) | + R600_S1_Y(0xc) | + R600_S2_X(0x1) | + R600_S2_Y(0x6) | + R600_S3_X(0xa) | + R600_S3_Y(0xe))); + RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_8S_WD1, (R600_S4_X(0x6) | + R600_S4_Y(0x1) | + R600_S5_X(0x0) | + R600_S5_Y(0x0) | + R600_S6_X(0xb) | + R600_S6_Y(0x4) | + R600_S7_X(0x7) | + R600_S7_Y(0x8))); + + switch (dev_priv->flags & RADEON_FAMILY_MASK) { + case CHIP_R600: + case CHIP_RV630: + case CHIP_RV635: + gs_prim_buffer_depth = 0; + break; + case CHIP_RV610: + case CHIP_RS780: + case CHIP_RV620: + gs_prim_buffer_depth = 32; + break; + case CHIP_RV670: + gs_prim_buffer_depth = 128; + break; + default: + break; + } + + num_gs_verts_per_thread = dev_priv->r600_max_pipes * 16; + vgt_gs_per_es = gs_prim_buffer_depth + num_gs_verts_per_thread; + /* Max value for this is 256 */ + if (vgt_gs_per_es > 256) + vgt_gs_per_es = 256; + + RADEON_WRITE(R600_VGT_ES_PER_GS, 128); + RADEON_WRITE(R600_VGT_GS_PER_ES, vgt_gs_per_es); + RADEON_WRITE(R600_VGT_GS_PER_VS, 2); + RADEON_WRITE(R600_VGT_GS_VERTEX_REUSE, 16); + + /* more default values. 2D/3D driver should adjust as needed */ + RADEON_WRITE(R600_PA_SC_LINE_STIPPLE_STATE, 0); + RADEON_WRITE(R600_VGT_STRMOUT_EN, 0); + RADEON_WRITE(R600_SX_MISC, 0); + RADEON_WRITE(R600_PA_SC_MODE_CNTL, 0); + RADEON_WRITE(R600_PA_SC_AA_CONFIG, 0); + RADEON_WRITE(R600_PA_SC_LINE_STIPPLE, 0); + RADEON_WRITE(R600_SPI_INPUT_Z, 0); + RADEON_WRITE(R600_SPI_PS_IN_CONTROL_0, R600_NUM_INTERP(2)); + RADEON_WRITE(R600_CB_COLOR7_FRAG, 0); + + /* clear render buffer base addresses */ + RADEON_WRITE(R600_CB_COLOR0_BASE, 0); + RADEON_WRITE(R600_CB_COLOR1_BASE, 0); + RADEON_WRITE(R600_CB_COLOR2_BASE, 0); + RADEON_WRITE(R600_CB_COLOR3_BASE, 0); + RADEON_WRITE(R600_CB_COLOR4_BASE, 0); + RADEON_WRITE(R600_CB_COLOR5_BASE, 0); + RADEON_WRITE(R600_CB_COLOR6_BASE, 0); + RADEON_WRITE(R600_CB_COLOR7_BASE, 0); + + switch (dev_priv->flags & RADEON_FAMILY_MASK) { + case CHIP_RV610: + case CHIP_RS780: + case CHIP_RV620: + tc_cntl = R600_TC_L2_SIZE(8); + break; + case CHIP_RV630: + case CHIP_RV635: + tc_cntl = R600_TC_L2_SIZE(4); + break; + case CHIP_R600: + tc_cntl = R600_TC_L2_SIZE(0) | R600_L2_DISABLE_LATE_HIT; + break; + default: + tc_cntl = R600_TC_L2_SIZE(0); + break; + } + + RADEON_WRITE(R600_TC_CNTL, tc_cntl); + + hdp_host_path_cntl = RADEON_READ(R600_HDP_HOST_PATH_CNTL); + RADEON_WRITE(R600_HDP_HOST_PATH_CNTL, hdp_host_path_cntl); + + arb_pop = RADEON_READ(R600_ARB_POP); + arb_pop |= R600_ENABLE_TC128; + RADEON_WRITE(R600_ARB_POP, arb_pop); + + RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0); + RADEON_WRITE(R600_PA_CL_ENHANCE, (R600_CLIP_VTX_REORDER_ENA | + R600_NUM_CLIP_SEQ(3))); + RADEON_WRITE(R600_PA_SC_ENHANCE, R600_FORCE_EOV_MAX_CLK_CNT(4095)); + +} + +static u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes, + u32 num_backends, + u32 backend_disable_mask) +{ + u32 backend_map = 0; + u32 enabled_backends_mask; + u32 enabled_backends_count; + u32 cur_pipe; + u32 swizzle_pipe[R7XX_MAX_PIPES]; + u32 cur_backend; + u32 i; + + if (num_tile_pipes > R7XX_MAX_PIPES) + num_tile_pipes = R7XX_MAX_PIPES; + if (num_tile_pipes < 1) + num_tile_pipes = 1; + if (num_backends > R7XX_MAX_BACKENDS) + num_backends = R7XX_MAX_BACKENDS; + if (num_backends < 1) + num_backends = 1; + + enabled_backends_mask = 0; + enabled_backends_count = 0; + for (i = 0; i < R7XX_MAX_BACKENDS; ++i) { + if (((backend_disable_mask >> i) & 1) == 0) { + enabled_backends_mask |= (1 << i); + ++enabled_backends_count; + } + if (enabled_backends_count == num_backends) + break; + } + + if (enabled_backends_count == 0) { + enabled_backends_mask = 1; + enabled_backends_count = 1; + } + + if (enabled_backends_count != num_backends) + num_backends = enabled_backends_count; + + memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R7XX_MAX_PIPES); + switch (num_tile_pipes) { + case 1: + swizzle_pipe[0] = 0; + break; + case 2: + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 1; + break; + case 3: + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 2; + swizzle_pipe[2] = 1; + break; + case 4: + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 2; + swizzle_pipe[2] = 3; + swizzle_pipe[3] = 1; + break; + case 5: + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 2; + swizzle_pipe[2] = 4; + swizzle_pipe[3] = 1; + swizzle_pipe[4] = 3; + break; + case 6: + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 2; + swizzle_pipe[2] = 4; + swizzle_pipe[3] = 5; + swizzle_pipe[4] = 3; + swizzle_pipe[5] = 1; + break; + case 7: + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 2; + swizzle_pipe[2] = 4; + swizzle_pipe[3] = 6; + swizzle_pipe[4] = 3; + swizzle_pipe[5] = 1; + swizzle_pipe[6] = 5; + break; + case 8: + swizzle_pipe[0] = 0; + swizzle_pipe[1] = 2; + swizzle_pipe[2] = 4; + swizzle_pipe[3] = 6; + swizzle_pipe[4] = 3; + swizzle_pipe[5] = 1; + swizzle_pipe[6] = 7; + swizzle_pipe[7] = 5; + break; + } + + cur_backend = 0; + for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) { + while (((1 << cur_backend) & enabled_backends_mask) == 0) + cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS; + + backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2))); + + cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS; + } + + return backend_map; +} + +static void r700_gfx_init(struct drm_device *dev, + drm_radeon_private_t *dev_priv) +{ + int i, j, num_qd_pipes; + u32 sx_debug_1; + u32 smx_dc_ctl0; + u32 num_gs_verts_per_thread; + u32 vgt_gs_per_es; + u32 gs_prim_buffer_depth = 0; + u32 sq_ms_fifo_sizes; + u32 sq_config; + u32 sq_thread_resource_mgmt; + u32 hdp_host_path_cntl; + u32 sq_dyn_gpr_size_simd_ab_0; + u32 backend_map; + u32 gb_tiling_config = 0; + u32 cc_rb_backend_disable = 0; + u32 cc_gc_shader_pipe_config = 0; + u32 mc_arb_ramcfg; + u32 db_debug4; + + /* setup chip specs */ + switch (dev_priv->flags & RADEON_FAMILY_MASK) { + case CHIP_RV770: + dev_priv->r600_max_pipes = 4; + dev_priv->r600_max_tile_pipes = 8; + dev_priv->r600_max_simds = 10; + dev_priv->r600_max_backends = 4; + dev_priv->r600_max_gprs = 256; + dev_priv->r600_max_threads = 248; + dev_priv->r600_max_stack_entries = 512; + dev_priv->r600_max_hw_contexts = 8; + dev_priv->r600_max_gs_threads = 16 * 2; + dev_priv->r600_sx_max_export_size = 128; + dev_priv->r600_sx_max_export_pos_size = 16; + dev_priv->r600_sx_max_export_smx_size = 112; + dev_priv->r600_sq_num_cf_insts = 2; + + dev_priv->r700_sx_num_of_sets = 7; + dev_priv->r700_sc_prim_fifo_size = 0xF9; + dev_priv->r700_sc_hiz_tile_fifo_size = 0x30; + dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130; + break; + case CHIP_RV730: + dev_priv->r600_max_pipes = 2; + dev_priv->r600_max_tile_pipes = 4; + dev_priv->r600_max_simds = 8; + dev_priv->r600_max_backends = 2; + dev_priv->r600_max_gprs = 128; + dev_priv->r600_max_threads = 248; + dev_priv->r600_max_stack_entries = 256; + dev_priv->r600_max_hw_contexts = 8; + dev_priv->r600_max_gs_threads = 16 * 2; + dev_priv->r600_sx_max_export_size = 256; + dev_priv->r600_sx_max_export_pos_size = 32; + dev_priv->r600_sx_max_export_smx_size = 224; + dev_priv->r600_sq_num_cf_insts = 2; + + dev_priv->r700_sx_num_of_sets = 7; + dev_priv->r700_sc_prim_fifo_size = 0xf9; + dev_priv->r700_sc_hiz_tile_fifo_size = 0x30; + dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130; + break; + case CHIP_RV710: + dev_priv->r600_max_pipes = 2; + dev_priv->r600_max_tile_pipes = 2; + dev_priv->r600_max_simds = 2; + dev_priv->r600_max_backends = 1; + dev_priv->r600_max_gprs = 256; + dev_priv->r600_max_threads = 192; + dev_priv->r600_max_stack_entries = 256; + dev_priv->r600_max_hw_contexts = 4; + dev_priv->r600_max_gs_threads = 8 * 2; + dev_priv->r600_sx_max_export_size = 128; + dev_priv->r600_sx_max_export_pos_size = 16; + dev_priv->r600_sx_max_export_smx_size = 112; + dev_priv->r600_sq_num_cf_insts = 1; + + dev_priv->r700_sx_num_of_sets = 7; + dev_priv->r700_sc_prim_fifo_size = 0x40; + dev_priv->r700_sc_hiz_tile_fifo_size = 0x30; + dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130; + break; + default: + break; + } + + /* Initialize HDP */ + j = 0; + for (i = 0; i < 32; i++) { + RADEON_WRITE((0x2c14 + j), 0x00000000); + RADEON_WRITE((0x2c18 + j), 0x00000000); + RADEON_WRITE((0x2c1c + j), 0x00000000); + RADEON_WRITE((0x2c20 + j), 0x00000000); + RADEON_WRITE((0x2c24 + j), 0x00000000); + j += 0x18; + } + + RADEON_WRITE(R600_GRBM_CNTL, R600_GRBM_READ_TIMEOUT(0xff)); + + /* setup tiling, simd, pipe config */ + mc_arb_ramcfg = RADEON_READ(R700_MC_ARB_RAMCFG); + + switch (dev_priv->r600_max_tile_pipes) { + case 1: + gb_tiling_config |= R600_PIPE_TILING(0); + break; + case 2: + gb_tiling_config |= R600_PIPE_TILING(1); + break; + case 4: + gb_tiling_config |= R600_PIPE_TILING(2); + break; + case 8: + gb_tiling_config |= R600_PIPE_TILING(3); + break; + default: + break; + } + + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770) + gb_tiling_config |= R600_BANK_TILING(1); + else + gb_tiling_config |= R600_BANK_TILING((mc_arb_ramcfg >> R700_NOOFBANK_SHIFT) & R700_NOOFBANK_MASK); + + gb_tiling_config |= R600_GROUP_SIZE(0); + + if (((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK) > 3) { + gb_tiling_config |= R600_ROW_TILING(3); + gb_tiling_config |= R600_SAMPLE_SPLIT(3); + } else { + gb_tiling_config |= + R600_ROW_TILING(((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK)); + gb_tiling_config |= + R600_SAMPLE_SPLIT(((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK)); + } + + gb_tiling_config |= R600_BANK_SWAPS(1); + + backend_map = r700_get_tile_pipe_to_backend_map(dev_priv->r600_max_tile_pipes, + dev_priv->r600_max_backends, + (0xff << dev_priv->r600_max_backends) & 0xff); + gb_tiling_config |= R600_BACKEND_MAP(backend_map); + + cc_gc_shader_pipe_config = + R600_INACTIVE_QD_PIPES((R7XX_MAX_PIPES_MASK << dev_priv->r600_max_pipes) & R7XX_MAX_PIPES_MASK); + cc_gc_shader_pipe_config |= + R600_INACTIVE_SIMDS((R7XX_MAX_SIMDS_MASK << dev_priv->r600_max_simds) & R7XX_MAX_SIMDS_MASK); + + cc_rb_backend_disable = + R600_BACKEND_DISABLE((R7XX_MAX_BACKENDS_MASK << dev_priv->r600_max_backends) & R7XX_MAX_BACKENDS_MASK); + + RADEON_WRITE(R600_GB_TILING_CONFIG, gb_tiling_config); + RADEON_WRITE(R600_DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); + RADEON_WRITE(R600_HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); + + RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); + RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); + RADEON_WRITE(R600_GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); + + RADEON_WRITE(R700_CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); + RADEON_WRITE(R700_CGTS_SYS_TCC_DISABLE, 0); + RADEON_WRITE(R700_CGTS_TCC_DISABLE, 0); + RADEON_WRITE(R700_CGTS_USER_SYS_TCC_DISABLE, 0); + RADEON_WRITE(R700_CGTS_USER_TCC_DISABLE, 0); + + num_qd_pipes = + R7XX_MAX_BACKENDS - r600_count_pipe_bits(cc_gc_shader_pipe_config & R600_INACTIVE_QD_PIPES_MASK); + RADEON_WRITE(R600_VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & R600_DEALLOC_DIST_MASK); + RADEON_WRITE(R600_VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & R600_VTX_REUSE_DEPTH_MASK); + + /* set HW defaults for 3D engine */ + RADEON_WRITE(R600_CP_QUEUE_THRESHOLDS, (R600_ROQ_IB1_START(0x16) | + R600_ROQ_IB2_START(0x2b))); + + RADEON_WRITE(R600_CP_MEQ_THRESHOLDS, R700_STQ_SPLIT(0x30)); + + RADEON_WRITE(R600_TA_CNTL_AUX, (R600_DISABLE_CUBE_ANISO | + R600_SYNC_GRADIENT | + R600_SYNC_WALKER | + R600_SYNC_ALIGNER)); + + sx_debug_1 = RADEON_READ(R700_SX_DEBUG_1); + sx_debug_1 |= R700_ENABLE_NEW_SMX_ADDRESS; + RADEON_WRITE(R700_SX_DEBUG_1, sx_debug_1); + + smx_dc_ctl0 = RADEON_READ(R600_SMX_DC_CTL0); + smx_dc_ctl0 &= ~R700_CACHE_DEPTH(0x1ff); + smx_dc_ctl0 |= R700_CACHE_DEPTH((dev_priv->r700_sx_num_of_sets * 64) - 1); + RADEON_WRITE(R600_SMX_DC_CTL0, smx_dc_ctl0); + + RADEON_WRITE(R700_SMX_EVENT_CTL, (R700_ES_FLUSH_CTL(4) | + R700_GS_FLUSH_CTL(4) | + R700_ACK_FLUSH_CTL(3) | + R700_SYNC_FLUSH_CTL)); + + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770) + RADEON_WRITE(R700_DB_DEBUG3, R700_DB_CLK_OFF_DELAY(0x1f)); + else { + db_debug4 = RADEON_READ(RV700_DB_DEBUG4); + db_debug4 |= RV700_DISABLE_TILE_COVERED_FOR_PS_ITER; + RADEON_WRITE(RV700_DB_DEBUG4, db_debug4); + } + + RADEON_WRITE(R600_SX_EXPORT_BUFFER_SIZES, (R600_COLOR_BUFFER_SIZE((dev_priv->r600_sx_max_export_size / 4) - 1) | + R600_POSITION_BUFFER_SIZE((dev_priv->r600_sx_max_export_pos_size / 4) - 1) | + R600_SMX_BUFFER_SIZE((dev_priv->r600_sx_max_export_smx_size / 4) - 1))); + + RADEON_WRITE(R700_PA_SC_FIFO_SIZE_R7XX, (R700_SC_PRIM_FIFO_SIZE(dev_priv->r700_sc_prim_fifo_size) | + R700_SC_HIZ_TILE_FIFO_SIZE(dev_priv->r700_sc_hiz_tile_fifo_size) | + R700_SC_EARLYZ_TILE_FIFO_SIZE(dev_priv->r700_sc_earlyz_tile_fifo_fize))); + + RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0); + + RADEON_WRITE(R600_VGT_NUM_INSTANCES, 1); + + RADEON_WRITE(R600_SPI_CONFIG_CNTL, R600_GPR_WRITE_PRIORITY(0)); + + RADEON_WRITE(R600_SPI_CONFIG_CNTL_1, R600_VTX_DONE_DELAY(4)); + + RADEON_WRITE(R600_CP_PERFMON_CNTL, 0); + + sq_ms_fifo_sizes = (R600_CACHE_FIFO_SIZE(16 * dev_priv->r600_sq_num_cf_insts) | + R600_DONE_FIFO_HIWATER(0xe0) | + R600_ALU_UPDATE_FIFO_HIWATER(0x8)); + switch (dev_priv->flags & RADEON_FAMILY_MASK) { + case CHIP_RV770: + sq_ms_fifo_sizes |= R600_FETCH_FIFO_HIWATER(0x1); + break; + case CHIP_RV730: + case CHIP_RV710: + default: + sq_ms_fifo_sizes |= R600_FETCH_FIFO_HIWATER(0x4); + break; + } + RADEON_WRITE(R600_SQ_MS_FIFO_SIZES, sq_ms_fifo_sizes); + + /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT + * should be adjusted as needed by the 2D/3D drivers. This just sets default values + */ + sq_config = RADEON_READ(R600_SQ_CONFIG); + sq_config &= ~(R600_PS_PRIO(3) | + R600_VS_PRIO(3) | + R600_GS_PRIO(3) | + R600_ES_PRIO(3)); + sq_config |= (R600_DX9_CONSTS | + R600_VC_ENABLE | + R600_EXPORT_SRC_C | + R600_PS_PRIO(0) | + R600_VS_PRIO(1) | + R600_GS_PRIO(2) | + R600_ES_PRIO(3)); + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710) + /* no vertex cache */ + sq_config &= ~R600_VC_ENABLE; + + RADEON_WRITE(R600_SQ_CONFIG, sq_config); + + RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_1, (R600_NUM_PS_GPRS((dev_priv->r600_max_gprs * 24)/64) | + R600_NUM_VS_GPRS((dev_priv->r600_max_gprs * 24)/64) | + R600_NUM_CLAUSE_TEMP_GPRS(((dev_priv->r600_max_gprs * 24)/64)/2))); + + RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_2, (R600_NUM_GS_GPRS((dev_priv->r600_max_gprs * 7)/64) | + R600_NUM_ES_GPRS((dev_priv->r600_max_gprs * 7)/64))); + + sq_thread_resource_mgmt = (R600_NUM_PS_THREADS((dev_priv->r600_max_threads * 4)/8) | + R600_NUM_VS_THREADS((dev_priv->r600_max_threads * 2)/8) | + R600_NUM_ES_THREADS((dev_priv->r600_max_threads * 1)/8)); + if (((dev_priv->r600_max_threads * 1) / 8) > dev_priv->r600_max_gs_threads) + sq_thread_resource_mgmt |= R600_NUM_GS_THREADS(dev_priv->r600_max_gs_threads); + else + sq_thread_resource_mgmt |= R600_NUM_GS_THREADS((dev_priv->r600_max_gs_threads * 1)/8); + RADEON_WRITE(R600_SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt); + + RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_1, (R600_NUM_PS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4) | + R600_NUM_VS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4))); + + RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_2, (R600_NUM_GS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4) | + R600_NUM_ES_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4))); + + sq_dyn_gpr_size_simd_ab_0 = (R700_SIMDA_RING0((dev_priv->r600_max_gprs * 38)/64) | + R700_SIMDA_RING1((dev_priv->r600_max_gprs * 38)/64) | + R700_SIMDB_RING0((dev_priv->r600_max_gprs * 38)/64) | + R700_SIMDB_RING1((dev_priv->r600_max_gprs * 38)/64)); + + RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_0, sq_dyn_gpr_size_simd_ab_0); + RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_1, sq_dyn_gpr_size_simd_ab_0); + RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_2, sq_dyn_gpr_size_simd_ab_0); + RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_3, sq_dyn_gpr_size_simd_ab_0); + RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_4, sq_dyn_gpr_size_simd_ab_0); + RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_5, sq_dyn_gpr_size_simd_ab_0); + RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_6, sq_dyn_gpr_size_simd_ab_0); + RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_7, sq_dyn_gpr_size_simd_ab_0); + + RADEON_WRITE(R700_PA_SC_FORCE_EOV_MAX_CNTS, (R700_FORCE_EOV_MAX_CLK_CNT(4095) | + R700_FORCE_EOV_MAX_REZ_CNT(255))); + + if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710) + RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, (R600_CACHE_INVALIDATION(R600_TC_ONLY) | + R700_AUTO_INVLD_EN(R700_ES_AND_GS_AUTO))); + else + RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, (R600_CACHE_INVALIDATION(R600_VC_AND_TC) | + R700_AUTO_INVLD_EN(R700_ES_AND_GS_AUTO))); + + switch (dev_priv->flags & RADEON_FAMILY_MASK) { + case CHIP_RV770: + case CHIP_RV730: + gs_prim_buffer_depth = 384; + break; + case CHIP_RV710: + gs_prim_buffer_depth = 128; + break; + default: + break; + } + + num_gs_verts_per_thread = dev_priv->r600_max_pipes * 16; + vgt_gs_per_es = gs_prim_buffer_depth + num_gs_verts_per_thread; + /* Max value for this is 256 */ + if (vgt_gs_per_es > 256) + vgt_gs_per_es = 256; + + RADEON_WRITE(R600_VGT_ES_PER_GS, 128); + RADEON_WRITE(R600_VGT_GS_PER_ES, vgt_gs_per_es); + RADEON_WRITE(R600_VGT_GS_PER_VS, 2); + + /* more default values. 2D/3D driver should adjust as needed */ + RADEON_WRITE(R600_VGT_GS_VERTEX_REUSE, 16); + RADEON_WRITE(R600_PA_SC_LINE_STIPPLE_STATE, 0); + RADEON_WRITE(R600_VGT_STRMOUT_EN, 0); + RADEON_WRITE(R600_SX_MISC, 0); + RADEON_WRITE(R600_PA_SC_MODE_CNTL, 0); + RADEON_WRITE(R700_PA_SC_EDGERULE, 0xaaaaaaaa); + RADEON_WRITE(R600_PA_SC_AA_CONFIG, 0); + RADEON_WRITE(R600_PA_SC_CLIPRECT_RULE, 0xffff); + RADEON_WRITE(R600_PA_SC_LINE_STIPPLE, 0); + RADEON_WRITE(R600_SPI_INPUT_Z, 0); + RADEON_WRITE(R600_SPI_PS_IN_CONTROL_0, R600_NUM_INTERP(2)); + RADEON_WRITE(R600_CB_COLOR7_FRAG, 0); + + /* clear render buffer base addresses */ + RADEON_WRITE(R600_CB_COLOR0_BASE, 0); + RADEON_WRITE(R600_CB_COLOR1_BASE, 0); + RADEON_WRITE(R600_CB_COLOR2_BASE, 0); + RADEON_WRITE(R600_CB_COLOR3_BASE, 0); + RADEON_WRITE(R600_CB_COLOR4_BASE, 0); + RADEON_WRITE(R600_CB_COLOR5_BASE, 0); + RADEON_WRITE(R600_CB_COLOR6_BASE, 0); + RADEON_WRITE(R600_CB_COLOR7_BASE, 0); + + RADEON_WRITE(R700_TCP_CNTL, 0); + + hdp_host_path_cntl = RADEON_READ(R600_HDP_HOST_PATH_CNTL); + RADEON_WRITE(R600_HDP_HOST_PATH_CNTL, hdp_host_path_cntl); + + RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0); + + RADEON_WRITE(R600_PA_CL_ENHANCE, (R600_CLIP_VTX_REORDER_ENA | + R600_NUM_CLIP_SEQ(3))); + +} + +static void r600_cp_init_ring_buffer(struct drm_device *dev, + drm_radeon_private_t *dev_priv) +{ + u32 ring_start; + u64 rptr_addr; + /*u32 cur_read_ptr;*/ + + if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) + r700_gfx_init(dev, dev_priv); + else + r600_gfx_init(dev, dev_priv); + + RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP); + RADEON_READ(R600_GRBM_SOFT_RESET); + DRM_UDELAY(15000); + RADEON_WRITE(R600_GRBM_SOFT_RESET, 0); + + + /* Set ring buffer size */ +#ifdef __BIG_ENDIAN + RADEON_WRITE(R600_CP_RB_CNTL, + RADEON_BUF_SWAP_32BIT | + RADEON_RB_NO_UPDATE | + (dev_priv->ring.rptr_update_l2qw << 8) | + dev_priv->ring.size_l2qw); +#else + RADEON_WRITE(R600_CP_RB_CNTL, + RADEON_RB_NO_UPDATE | + (dev_priv->ring.rptr_update_l2qw << 8) | + dev_priv->ring.size_l2qw); +#endif + + RADEON_WRITE(R600_CP_SEM_WAIT_TIMER, 0x4); + + /* Set the write pointer delay */ + RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0); + +#ifdef __BIG_ENDIAN + RADEON_WRITE(R600_CP_RB_CNTL, + RADEON_BUF_SWAP_32BIT | + RADEON_RB_NO_UPDATE | + RADEON_RB_RPTR_WR_ENA | + (dev_priv->ring.rptr_update_l2qw << 8) | + dev_priv->ring.size_l2qw); +#else + RADEON_WRITE(R600_CP_RB_CNTL, + RADEON_RB_NO_UPDATE | + RADEON_RB_RPTR_WR_ENA | + (dev_priv->ring.rptr_update_l2qw << 8) | + dev_priv->ring.size_l2qw); +#endif + + /* Initialize the ring buffer's read and write pointers */ +#if 0 + cur_read_ptr = RADEON_READ(R600_CP_RB_RPTR); + RADEON_WRITE(R600_CP_RB_WPTR, cur_read_ptr); + SET_RING_HEAD(dev_priv, cur_read_ptr); + dev_priv->ring.tail = cur_read_ptr; + +#endif + + RADEON_WRITE(R600_CP_RB_RPTR_WR, 0); + RADEON_WRITE(R600_CP_RB_WPTR, 0); + SET_RING_HEAD(dev_priv, 0); + dev_priv->ring.tail = 0; + +#if __OS_HAS_AGP + if (dev_priv->flags & RADEON_IS_AGP) { + rptr_addr = dev_priv->ring_rptr->offset + - dev->agp->base + + dev_priv->gart_vm_start; + } else +#endif + { + rptr_addr = dev_priv->ring_rptr->offset + - ((unsigned long) dev->sg->virtual) + + dev_priv->gart_vm_start; + } + + RADEON_WRITE(R600_CP_RB_RPTR_ADDR, + rptr_addr & 0xffffffff); + RADEON_WRITE(R600_CP_RB_RPTR_ADDR_HI, + upper_32_bits(rptr_addr)); + +#ifdef __BIG_ENDIAN + RADEON_WRITE(R600_CP_RB_CNTL, + RADEON_BUF_SWAP_32BIT | + (dev_priv->ring.rptr_update_l2qw << 8) | + dev_priv->ring.size_l2qw); +#else + RADEON_WRITE(R600_CP_RB_CNTL, + (dev_priv->ring.rptr_update_l2qw << 8) | + dev_priv->ring.size_l2qw); +#endif + +#if __OS_HAS_AGP + if (dev_priv->flags & RADEON_IS_AGP) { + radeon_write_agp_base(dev_priv, dev->agp->base); + + radeon_write_agp_location(dev_priv, + (((dev_priv->gart_vm_start - 1 + + dev_priv->gart_size) & 0xffff0000) | + (dev_priv->gart_vm_start >> 16))); + + ring_start = (dev_priv->cp_ring->offset + - dev->agp->base + + dev_priv->gart_vm_start); + } else +#endif + ring_start = (dev_priv->cp_ring->offset + - (unsigned long)dev->sg->virtual + + dev_priv->gart_vm_start); + + RADEON_WRITE(R600_CP_RB_BASE, ring_start >> 8); + + RADEON_WRITE(R600_CP_ME_CNTL, 0xff); + + RADEON_WRITE(R600_CP_DEBUG, (1 << 27) | (1 << 28)); + + /* Initialize the scratch register pointer. This will cause + * the scratch register values to be written out to memory + * whenever they are updated. + * + * We simply put this behind the ring read pointer, this works + * with PCI GART as well as (whatever kind of) AGP GART + */ + + { + u64 scratch_addr; + + scratch_addr = RADEON_READ(R600_CP_RB_RPTR_ADDR); + scratch_addr |= ((u64)RADEON_READ(R600_CP_RB_RPTR_ADDR_HI)) << 32; + scratch_addr += R600_SCRATCH_REG_OFFSET; + scratch_addr >>= 8; + scratch_addr &= 0xffffffff; + + RADEON_WRITE(R600_SCRATCH_ADDR, (uint32_t)scratch_addr); + } + + dev_priv->scratch = ((__volatile__ u32 *) + dev_priv->ring_rptr->handle + + (R600_SCRATCH_REG_OFFSET / sizeof(u32))); + + RADEON_WRITE(R600_SCRATCH_UMSK, 0x7); + + dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0; + RADEON_WRITE(R600_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame); + + dev_priv->sarea_priv->last_dispatch = dev_priv->scratch[1] = 0; + RADEON_WRITE(R600_LAST_DISPATCH_REG, + dev_priv->sarea_priv->last_dispatch); + + dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0; + RADEON_WRITE(R600_LAST_CLEAR_REG, dev_priv->sarea_priv->last_clear); + + r600_do_wait_for_idle(dev_priv); + +} + +int r600_do_cleanup_cp(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + DRM_DEBUG("\n"); + + /* Make sure interrupts are disabled here because the uninstall ioctl + * may not have been called from userspace and after dev_private + * is freed, it's too late. + */ + if (dev->irq_enabled) + drm_irq_uninstall(dev); + +#if __OS_HAS_AGP + if (dev_priv->flags & RADEON_IS_AGP) { + if (dev_priv->cp_ring != NULL) { + drm_core_ioremapfree(dev_priv->cp_ring, dev); + dev_priv->cp_ring = NULL; + } + if (dev_priv->ring_rptr != NULL) { + drm_core_ioremapfree(dev_priv->ring_rptr, dev); + dev_priv->ring_rptr = NULL; + } + if (dev->agp_buffer_map != NULL) { + drm_core_ioremapfree(dev->agp_buffer_map, dev); + dev->agp_buffer_map = NULL; + } + } else +#endif + { + + if (dev_priv->gart_info.bus_addr) + r600_page_table_cleanup(dev, &dev_priv->gart_info); + + if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) { + drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); + dev_priv->gart_info.addr = 0; + } + } + /* only clear to the start of flags */ + memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags)); + + return 0; +} + +int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + + DRM_DEBUG("\n"); + + /* if we require new memory map but we don't have it fail */ + if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) { + DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n"); + r600_do_cleanup_cp(dev); + return -EINVAL; + } + + if (init->is_pci && (dev_priv->flags & RADEON_IS_AGP)) { + DRM_DEBUG("Forcing AGP card to PCI mode\n"); + dev_priv->flags &= ~RADEON_IS_AGP; + /* The writeback test succeeds, but when writeback is enabled, + * the ring buffer read ptr update fails after first 128 bytes. + */ + radeon_no_wb = 1; + } else if (!(dev_priv->flags & (RADEON_IS_AGP | RADEON_IS_PCI | RADEON_IS_PCIE)) + && !init->is_pci) { + DRM_DEBUG("Restoring AGP flag\n"); + dev_priv->flags |= RADEON_IS_AGP; + } + + dev_priv->usec_timeout = init->usec_timeout; + if (dev_priv->usec_timeout < 1 || + dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) { + DRM_DEBUG("TIMEOUT problem!\n"); + r600_do_cleanup_cp(dev); + return -EINVAL; + } + + /* Enable vblank on CRTC1 for older X servers + */ + dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1; + + dev_priv->cp_mode = init->cp_mode; + + /* We don't support anything other than bus-mastering ring mode, + * but the ring can be in either AGP or PCI space for the ring + * read pointer. + */ + if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) && + (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) { + DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode); + r600_do_cleanup_cp(dev); + return -EINVAL; + } + + switch (init->fb_bpp) { + case 16: + dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565; + break; + case 32: + default: + dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888; + break; + } + dev_priv->front_offset = init->front_offset; + dev_priv->front_pitch = init->front_pitch; + dev_priv->back_offset = init->back_offset; + dev_priv->back_pitch = init->back_pitch; + + dev_priv->ring_offset = init->ring_offset; + dev_priv->ring_rptr_offset = init->ring_rptr_offset; + dev_priv->buffers_offset = init->buffers_offset; + dev_priv->gart_textures_offset = init->gart_textures_offset; + + dev_priv->sarea = drm_getsarea(dev); + if (!dev_priv->sarea) { + DRM_ERROR("could not find sarea!\n"); + r600_do_cleanup_cp(dev); + return -EINVAL; + } + + dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset); + if (!dev_priv->cp_ring) { + DRM_ERROR("could not find cp ring region!\n"); + r600_do_cleanup_cp(dev); + return -EINVAL; + } + dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset); + if (!dev_priv->ring_rptr) { + DRM_ERROR("could not find ring read pointer!\n"); + r600_do_cleanup_cp(dev); + return -EINVAL; + } + dev->agp_buffer_token = init->buffers_offset; + dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); + if (!dev->agp_buffer_map) { + DRM_ERROR("could not find dma buffer region!\n"); + r600_do_cleanup_cp(dev); + return -EINVAL; + } + + if (init->gart_textures_offset) { + dev_priv->gart_textures = + drm_core_findmap(dev, init->gart_textures_offset); + if (!dev_priv->gart_textures) { + DRM_ERROR("could not find GART texture region!\n"); + r600_do_cleanup_cp(dev); + return -EINVAL; + } + } + + dev_priv->sarea_priv = + (drm_radeon_sarea_t *) ((u8 *) dev_priv->sarea->handle + + init->sarea_priv_offset); + +#if __OS_HAS_AGP + if (dev_priv->flags & RADEON_IS_AGP) { + drm_core_ioremap_wc(dev_priv->cp_ring, dev); + drm_core_ioremap_wc(dev_priv->ring_rptr, dev); + drm_core_ioremap_wc(dev->agp_buffer_map, dev); + if (!dev_priv->cp_ring->handle || + !dev_priv->ring_rptr->handle || + !dev->agp_buffer_map->handle) { + DRM_ERROR("could not find ioremap agp regions!\n"); + r600_do_cleanup_cp(dev); + return -EINVAL; + } + } else +#endif + { + dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset; + dev_priv->ring_rptr->handle = + (void *)dev_priv->ring_rptr->offset; + dev->agp_buffer_map->handle = + (void *)dev->agp_buffer_map->offset; + + DRM_DEBUG("dev_priv->cp_ring->handle %p\n", + dev_priv->cp_ring->handle); + DRM_DEBUG("dev_priv->ring_rptr->handle %p\n", + dev_priv->ring_rptr->handle); + DRM_DEBUG("dev->agp_buffer_map->handle %p\n", + dev->agp_buffer_map->handle); + } + + dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 24; + dev_priv->fb_size = + (((radeon_read_fb_location(dev_priv) & 0xffff0000u) << 8) + 0x1000000) + - dev_priv->fb_location; + + dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) | + ((dev_priv->front_offset + + dev_priv->fb_location) >> 10)); + + dev_priv->back_pitch_offset = (((dev_priv->back_pitch / 64) << 22) | + ((dev_priv->back_offset + + dev_priv->fb_location) >> 10)); + + dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch / 64) << 22) | + ((dev_priv->depth_offset + + dev_priv->fb_location) >> 10)); + + dev_priv->gart_size = init->gart_size; + + /* New let's set the memory map ... */ + if (dev_priv->new_memmap) { + u32 base = 0; + + DRM_INFO("Setting GART location based on new memory map\n"); + + /* If using AGP, try to locate the AGP aperture at the same + * location in the card and on the bus, though we have to + * align it down. + */ +#if __OS_HAS_AGP + if (dev_priv->flags & RADEON_IS_AGP) { + base = dev->agp->base; + /* Check if valid */ + if ((base + dev_priv->gart_size - 1) >= dev_priv->fb_location && + base < (dev_priv->fb_location + dev_priv->fb_size - 1)) { + DRM_INFO("Can't use AGP base @0x%08lx, won't fit\n", + dev->agp->base); + base = 0; + } + } +#endif + /* If not or if AGP is at 0 (Macs), try to put it elsewhere */ + if (base == 0) { + base = dev_priv->fb_location + dev_priv->fb_size; + if (base < dev_priv->fb_location || + ((base + dev_priv->gart_size) & 0xfffffffful) < base) + base = dev_priv->fb_location + - dev_priv->gart_size; + } + dev_priv->gart_vm_start = base & 0xffc00000u; + if (dev_priv->gart_vm_start != base) + DRM_INFO("GART aligned down from 0x%08x to 0x%08x\n", + base, dev_priv->gart_vm_start); + } + +#if __OS_HAS_AGP + if (dev_priv->flags & RADEON_IS_AGP) + dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset + - dev->agp->base + + dev_priv->gart_vm_start); + else +#endif + dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset + - (unsigned long)dev->sg->virtual + + dev_priv->gart_vm_start); + + DRM_DEBUG("fb 0x%08x size %d\n", + (unsigned int) dev_priv->fb_location, + (unsigned int) dev_priv->fb_size); + DRM_DEBUG("dev_priv->gart_size %d\n", dev_priv->gart_size); + DRM_DEBUG("dev_priv->gart_vm_start 0x%08x\n", + (unsigned int) dev_priv->gart_vm_start); + DRM_DEBUG("dev_priv->gart_buffers_offset 0x%08lx\n", + dev_priv->gart_buffers_offset); + + dev_priv->ring.start = (u32 *) dev_priv->cp_ring->handle; + dev_priv->ring.end = ((u32 *) dev_priv->cp_ring->handle + + init->ring_size / sizeof(u32)); + dev_priv->ring.size = init->ring_size; + dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8); + + dev_priv->ring.rptr_update = /* init->rptr_update */ 4096; + dev_priv->ring.rptr_update_l2qw = drm_order(/* init->rptr_update */ 4096 / 8); + + dev_priv->ring.fetch_size = /* init->fetch_size */ 32; + dev_priv->ring.fetch_size_l2ow = drm_order(/* init->fetch_size */ 32 / 16); + + dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1; + + dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; + +#if __OS_HAS_AGP + if (dev_priv->flags & RADEON_IS_AGP) { + /* XXX turn off pcie gart */ + } else +#endif + { + dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); + /* if we have an offset set from userspace */ + if (!dev_priv->pcigart_offset_set) { + DRM_ERROR("Need gart offset from userspace\n"); + r600_do_cleanup_cp(dev); + return -EINVAL; + } + + DRM_DEBUG("Using gart offset 0x%08lx\n", dev_priv->pcigart_offset); + + dev_priv->gart_info.bus_addr = + dev_priv->pcigart_offset + dev_priv->fb_location; + dev_priv->gart_info.mapping.offset = + dev_priv->pcigart_offset + dev_priv->fb_aper_offset; + dev_priv->gart_info.mapping.size = + dev_priv->gart_info.table_size; + + drm_core_ioremap_wc(&dev_priv->gart_info.mapping, dev); + if (!dev_priv->gart_info.mapping.handle) { + DRM_ERROR("ioremap failed.\n"); + r600_do_cleanup_cp(dev); + return -EINVAL; + } + + dev_priv->gart_info.addr = + dev_priv->gart_info.mapping.handle; + + DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n", + dev_priv->gart_info.addr, + dev_priv->pcigart_offset); + + if (!r600_page_table_init(dev)) { + DRM_ERROR("Failed to init GART table\n"); + r600_do_cleanup_cp(dev); + return -EINVAL; + } + + if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) + r700_vm_init(dev); + else + r600_vm_init(dev); + } + + if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) + r700_cp_load_microcode(dev_priv); + else + r600_cp_load_microcode(dev_priv); + + r600_cp_init_ring_buffer(dev, dev_priv); + + dev_priv->last_buf = 0; + + r600_do_engine_reset(dev); + r600_test_writeback(dev_priv); + + return 0; +} + +int r600_do_resume_cp(struct drm_device *dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + + DRM_DEBUG("\n"); + if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) { + r700_vm_init(dev); + r700_cp_load_microcode(dev_priv); + } else { + r600_vm_init(dev); + r600_cp_load_microcode(dev_priv); + } + r600_cp_init_ring_buffer(dev, dev_priv); + r600_do_engine_reset(dev); + + return 0; +} + +/* Wait for the CP to go idle. + */ +int r600_do_cp_idle(drm_radeon_private_t *dev_priv) +{ + RING_LOCALS; + DRM_DEBUG("\n"); + + BEGIN_RING(5); + OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0)); + OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT); + /* wait for 3D idle clean */ + OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); + OUT_RING((R600_WAIT_UNTIL - R600_SET_CONFIG_REG_OFFSET) >> 2); + OUT_RING(RADEON_WAIT_3D_IDLE | RADEON_WAIT_3D_IDLECLEAN); + + ADVANCE_RING(); + COMMIT_RING(); + + return r600_do_wait_for_idle(dev_priv); +} + +/* Start the Command Processor. + */ +void r600_do_cp_start(drm_radeon_private_t *dev_priv) +{ + u32 cp_me; + RING_LOCALS; + DRM_DEBUG("\n"); + + BEGIN_RING(7); + OUT_RING(CP_PACKET3(R600_IT_ME_INITIALIZE, 5)); + OUT_RING(0x00000001); + if (((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV770)) + OUT_RING(0x00000003); + else + OUT_RING(0x00000000); + OUT_RING((dev_priv->r600_max_hw_contexts - 1)); + OUT_RING(R600_ME_INITIALIZE_DEVICE_ID(1)); + OUT_RING(0x00000000); + OUT_RING(0x00000000); + ADVANCE_RING(); + COMMIT_RING(); + + /* set the mux and reset the halt bit */ + cp_me = 0xff; + RADEON_WRITE(R600_CP_ME_CNTL, cp_me); + + dev_priv->cp_running = 1; + +} + +void r600_do_cp_reset(drm_radeon_private_t *dev_priv) +{ + u32 cur_read_ptr; + DRM_DEBUG("\n"); + + cur_read_ptr = RADEON_READ(R600_CP_RB_RPTR); + RADEON_WRITE(R600_CP_RB_WPTR, cur_read_ptr); + SET_RING_HEAD(dev_priv, cur_read_ptr); + dev_priv->ring.tail = cur_read_ptr; +} + +void r600_do_cp_stop(drm_radeon_private_t *dev_priv) +{ + uint32_t cp_me; + + DRM_DEBUG("\n"); + + cp_me = 0xff | R600_CP_ME_HALT; + + RADEON_WRITE(R600_CP_ME_CNTL, cp_me); + + dev_priv->cp_running = 0; +} + +int r600_cp_dispatch_indirect(struct drm_device *dev, + struct drm_buf *buf, int start, int end) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + if (start != end) { + unsigned long offset = (dev_priv->gart_buffers_offset + + buf->offset + start); + int dwords = (end - start + 3) / sizeof(u32); + + DRM_DEBUG("dwords:%d\n", dwords); + DRM_DEBUG("offset 0x%lx\n", offset); + + + /* Indirect buffer data must be a multiple of 16 dwords. + * pad the data with a Type-2 CP packet. + */ + while (dwords & 0xf) { + u32 *data = (u32 *) + ((char *)dev->agp_buffer_map->handle + + buf->offset + start); + data[dwords++] = RADEON_CP_PACKET2; + } + + /* Fire off the indirect buffer */ + BEGIN_RING(4); + OUT_RING(CP_PACKET3(R600_IT_INDIRECT_BUFFER, 2)); + OUT_RING((offset & 0xfffffffc)); + OUT_RING((upper_32_bits(offset) & 0xff)); + OUT_RING(dwords); + ADVANCE_RING(); + } + + return 0; +} --- linux-2.6.28.orig/drivers/gpu/drm/radeon/Makefile +++ linux-2.6.28/drivers/gpu/drm/radeon/Makefile @@ -3,7 +3,7 @@ # 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-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o r600_cp.o radeon-$(CONFIG_COMPAT) += radeon_ioc32.o --- linux-2.6.28.orig/drivers/gpu/drm/radeon/radeon_drv.h +++ linux-2.6.28/drivers/gpu/drm/radeon/radeon_drv.h @@ -126,6 +126,7 @@ CHIP_RV410, CHIP_RS400, CHIP_RS480, + CHIP_RS600, CHIP_RS690, CHIP_RS740, CHIP_RV515, @@ -134,6 +135,16 @@ CHIP_RV560, CHIP_RV570, CHIP_R580, + CHIP_R600, + CHIP_RV610, + CHIP_RV630, + CHIP_RV620, + CHIP_RV635, + CHIP_RV670, + CHIP_RS780, + CHIP_RV770, + CHIP_RV730, + CHIP_RV710, CHIP_LAST, }; @@ -161,9 +172,12 @@ }; #define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \ - DRM_READ32( (dev_priv)->ring_rptr, 0 ) : RADEON_READ(RADEON_CP_RB_RPTR)) + DRM_READ32((dev_priv)->ring_rptr, 0) : RADEON_READ(RADEON_CP_RB_RPTR)) #define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) ) +#define R600_GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \ + DRM_READ32((dev_priv)->ring_rptr, 0) : RADEON_READ(R600_CP_RB_RPTR)) + typedef struct drm_radeon_freelist { unsigned int age; struct drm_buf *buf; @@ -317,6 +331,26 @@ int num_gb_pipes; int track_flush; drm_local_map_t *mmio; + + /* r6xx/r7xx pipe/shader config */ + int r600_max_pipes; + int r600_max_tile_pipes; + int r600_max_simds; + int r600_max_backends; + int r600_max_gprs; + int r600_max_threads; + int r600_max_stack_entries; + int r600_max_hw_contexts; + int r600_max_gs_threads; + int r600_sx_max_export_size; + int r600_sx_max_export_pos_size; + int r600_sx_max_export_smx_size; + int r600_sq_num_cf_insts; + int r700_sx_num_of_sets; + int r700_sc_prim_fifo_size; + int r700_sc_hiz_tile_fifo_size; + int r700_sc_earlyz_tile_fifo_fize; + } drm_radeon_private_t; typedef struct drm_radeon_buf_priv { @@ -360,11 +394,13 @@ extern int radeon_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv); extern u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv); +extern u32 RADEON_READ_MM(drm_radeon_private_t *dev_priv, int addr); extern void radeon_freelist_reset(struct drm_device * dev); extern struct drm_buf *radeon_freelist_get(struct drm_device * dev); extern int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n); +extern void radeon_commit_ring(drm_radeon_private_t *dev_priv); extern int radeon_do_cp_idle(drm_radeon_private_t * dev_priv); @@ -409,6 +445,10 @@ extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc); +void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc); +void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base); + /* r300_cmdbuf.c */ extern void r300_init_reg_flags(struct drm_device *dev); @@ -416,6 +456,20 @@ struct drm_file *file_priv, drm_radeon_kcmd_buffer_t *cmdbuf); +/* r600 cp */ +extern int r600_do_engine_reset(struct drm_device *dev); +extern int r600_do_cleanup_cp(struct drm_device *dev); +extern int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init); +extern int r600_do_resume_cp(struct drm_device *dev); +extern int r600_do_cp_idle(drm_radeon_private_t *dev_priv); +extern void r600_do_cp_start(drm_radeon_private_t *dev_priv); +extern void r600_do_cp_reset(drm_radeon_private_t *dev_priv); +extern void r600_do_cp_stop(drm_radeon_private_t *dev_priv); +extern int r600_cp_dispatch_indirect(struct drm_device *dev, + struct drm_buf *buf, int start, int end); +extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info); +extern int r600_page_table_init(struct drm_device *dev); + /* Flags for stats.boxes */ #define RADEON_BOX_DMA_IDLE 0x1 @@ -427,6 +481,8 @@ /* Register definitions, register access macros and drmAddMap constants * for Radeon kernel driver. */ +#define RADEON_MM_INDEX 0x0000 +#define RADEON_MM_DATA 0x0004 #define RADEON_AGP_COMMAND 0x0f60 #define RADEON_AGP_COMMAND_PCI_CONFIG 0x0060 /* offset in PCI config */ @@ -549,6 +605,56 @@ #define RS690_MC_AGP_BASE 0x102 #define RS690_MC_AGP_BASE_2 0x103 +#define RS600_MC_INDEX 0x70 +# define RS600_MC_ADDR_MASK 0xffff +# define RS600_MC_IND_SEQ_RBS_0 (1 << 16) +# define RS600_MC_IND_SEQ_RBS_1 (1 << 17) +# define RS600_MC_IND_SEQ_RBS_2 (1 << 18) +# define RS600_MC_IND_SEQ_RBS_3 (1 << 19) +# define RS600_MC_IND_AIC_RBS (1 << 20) +# define RS600_MC_IND_CITF_ARB0 (1 << 21) +# define RS600_MC_IND_CITF_ARB1 (1 << 22) +# define RS600_MC_IND_WR_EN (1 << 23) +#define RS600_MC_DATA 0x74 + +#define RS600_MC_STATUS 0x0 +# define RS600_MC_IDLE (1 << 1) +#define RS600_MC_FB_LOCATION 0x4 +#define RS600_MC_AGP_LOCATION 0x5 +#define RS600_AGP_BASE 0x6 +#define RS600_AGP_BASE_2 0x7 +#define RS600_MC_CNTL1 0x9 +# define RS600_ENABLE_PAGE_TABLES (1 << 26) +#define RS600_MC_PT0_CNTL 0x100 +# define RS600_ENABLE_PT (1 << 0) +# define RS600_EFFECTIVE_L2_CACHE_SIZE(x) ((x) << 15) +# define RS600_EFFECTIVE_L2_QUEUE_SIZE(x) ((x) << 21) +# define RS600_INVALIDATE_ALL_L1_TLBS (1 << 28) +# define RS600_INVALIDATE_L2_CACHE (1 << 29) +#define RS600_MC_PT0_CONTEXT0_CNTL 0x102 +# define RS600_ENABLE_PAGE_TABLE (1 << 0) +# define RS600_PAGE_TABLE_TYPE_FLAT (0 << 1) +#define RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR 0x112 +#define RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR 0x114 +#define RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR 0x11c +#define RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR 0x12c +#define RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR 0x13c +#define RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR 0x14c +#define RS600_MC_PT0_CLIENT0_CNTL 0x16c +# define RS600_ENABLE_TRANSLATION_MODE_OVERRIDE (1 << 0) +# define RS600_TRANSLATION_MODE_OVERRIDE (1 << 1) +# define RS600_SYSTEM_ACCESS_MODE_MASK (3 << 8) +# define RS600_SYSTEM_ACCESS_MODE_PA_ONLY (0 << 8) +# define RS600_SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 8) +# define RS600_SYSTEM_ACCESS_MODE_IN_SYS (2 << 8) +# define RS600_SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 8) +# define RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASSTHROUGH (0 << 10) +# define RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE (1 << 10) +# define RS600_EFFECTIVE_L1_CACHE_SIZE(x) ((x) << 11) +# define RS600_ENABLE_FRAGMENT_PROCESSING (1 << 14) +# define RS600_EFFECTIVE_L1_QUEUE_SIZE(x) ((x) << 15) +# define RS600_INVALIDATE_L1_TLB (1 << 20) + #define R520_MC_IND_INDEX 0x70 #define R520_MC_IND_WR_EN (1 << 24) #define R520_MC_IND_DATA 0x74 @@ -630,11 +736,34 @@ #define RADEON_SCRATCH_UMSK 0x0770 #define RADEON_SCRATCH_ADDR 0x0774 -#define RADEON_SCRATCHOFF( x ) (RADEON_SCRATCH_REG_OFFSET + 4*(x)) +#define R600_SCRATCH_REG0 0x8500 +#define R600_SCRATCH_REG1 0x8504 +#define R600_SCRATCH_REG2 0x8508 +#define R600_SCRATCH_REG3 0x850c +#define R600_SCRATCH_REG4 0x8510 +#define R600_SCRATCH_REG5 0x8514 +#define R600_SCRATCH_REG6 0x8518 +#define R600_SCRATCH_REG7 0x851c +#define R600_SCRATCH_UMSK 0x8540 +#define R600_SCRATCH_ADDR 0x8544 + +#define RADEON_SCRATCHOFF(x) (RADEON_SCRATCH_REG_OFFSET + 4*(x)) + +#define R600_SCRATCHOFF(x) (R600_SCRATCH_REG_OFFSET + 4*(x)) + +#define GET_SCRATCH(x) (dev_priv->writeback_works \ + ? DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(x)) \ + : RADEON_READ(RADEON_SCRATCH_REG0 + 4*(x))) + +#define GET_R600_SCRATCH(x) (dev_priv->writeback_works \ + ? DRM_READ32(dev_priv->ring_rptr, R600_SCRATCHOFF(x)) \ + : RADEON_READ(R600_SCRATCH_REG0 + 4*(x))) -#define GET_SCRATCH( x ) (dev_priv->writeback_works \ - ? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \ - : RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) ) +#define RADEON_CRTC_CRNT_FRAME 0x0214 +#define RADEON_CRTC2_CRNT_FRAME 0x0314 + +#define RADEON_CRTC_STATUS 0x005c +#define RADEON_CRTC2_STATUS 0x03fc #define RADEON_GEN_INT_CNTL 0x0040 # define RADEON_CRTC_VBLANK_MASK (1 << 0) @@ -653,6 +782,7 @@ # define RADEON_SW_INT_FIRE (1 << 26) # define R500_DISPLAY_INT_STATUS (1 << 0) + #define RADEON_HOST_PATH_CNTL 0x0130 # define RADEON_HDP_SOFT_RESET (1 << 26) # define RADEON_HDP_WC_TIMEOUT_MASK (7 << 28) @@ -893,6 +1023,7 @@ #define RADEON_SW_SEMAPHORE 0x013c #define RADEON_WAIT_UNTIL 0x1720 +#define R600_WAIT_UNTIL 0x8040 # define RADEON_WAIT_CRTC_PFLIP (1 << 0) # define RADEON_WAIT_2D_IDLE (1 << 14) # define RADEON_WAIT_3D_IDLE (1 << 15) @@ -915,6 +1046,7 @@ #define RADEON_CP_RB_CNTL 0x0704 # define RADEON_BUF_SWAP_32BIT (2 << 16) # define RADEON_RB_NO_UPDATE (1 << 27) +# define RADEON_RB_RPTR_WR_ENA (1 << 31) #define RADEON_CP_RB_RPTR_ADDR 0x070c #define RADEON_CP_RB_RPTR 0x0710 #define RADEON_CP_RB_WPTR 0x0714 @@ -976,6 +1108,13 @@ # define RADEON_CNTL_BITBLT_MULTI 0x00009B00 # define RADEON_CNTL_SET_SCISSORS 0xC0001E00 +# define R600_IT_INDIRECT_BUFFER 0x00003200 +# define R600_IT_ME_INITIALIZE 0x00004400 +# define R600_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16) +# define R600_IT_EVENT_WRITE 0x00004600 +# define R600_IT_SET_CONFIG_REG 0x00006800 +# define R600_SET_CONFIG_REG_OFFSET 0x00008000 + #define RADEON_CP_PACKET_MASK 0xC0000000 #define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000 #define RADEON_CP_PACKET0_REG_MASK 0x000007ff @@ -1174,6 +1313,422 @@ #define R500_D1_VBLANK_INTERRUPT (1 << 4) #define R500_D2_VBLANK_INTERRUPT (1 << 5) +/* R6xx/R7xx registers */ +#define R600_MC_VM_FB_LOCATION 0x2180 +#define R600_MC_VM_AGP_TOP 0x2184 +#define R600_MC_VM_AGP_BOT 0x2188 +#define R600_MC_VM_AGP_BASE 0x218c +#define R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2190 +#define R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2194 +#define R600_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x2198 + +#define R700_MC_VM_FB_LOCATION 0x2024 +#define R700_MC_VM_AGP_TOP 0x2028 +#define R700_MC_VM_AGP_BOT 0x202c +#define R700_MC_VM_AGP_BASE 0x2030 +#define R700_MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034 +#define R700_MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038 +#define R700_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203c + +#define R600_MCD_RD_A_CNTL 0x219c +#define R600_MCD_RD_B_CNTL 0x21a0 + +#define R600_MCD_WR_A_CNTL 0x21a4 +#define R600_MCD_WR_B_CNTL 0x21a8 + +#define R600_MCD_RD_SYS_CNTL 0x2200 +#define R600_MCD_WR_SYS_CNTL 0x2214 + +#define R600_MCD_RD_GFX_CNTL 0x21fc +#define R600_MCD_RD_HDP_CNTL 0x2204 +#define R600_MCD_RD_PDMA_CNTL 0x2208 +#define R600_MCD_RD_SEM_CNTL 0x220c +#define R600_MCD_WR_GFX_CNTL 0x2210 +#define R600_MCD_WR_HDP_CNTL 0x2218 +#define R600_MCD_WR_PDMA_CNTL 0x221c +#define R600_MCD_WR_SEM_CNTL 0x2220 + +# define R600_MCD_L1_TLB (1 << 0) +# define R600_MCD_L1_FRAG_PROC (1 << 1) +# define R600_MCD_L1_STRICT_ORDERING (1 << 2) + +# define R600_MCD_SYSTEM_ACCESS_MODE_MASK (3 << 6) +# define R600_MCD_SYSTEM_ACCESS_MODE_PA_ONLY (0 << 6) +# define R600_MCD_SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 6) +# define R600_MCD_SYSTEM_ACCESS_MODE_IN_SYS (2 << 6) +# define R600_MCD_SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 6) + +# define R600_MCD_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 8) +# define R600_MCD_SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE (1 << 8) + +# define R600_MCD_SEMAPHORE_MODE (1 << 10) +# define R600_MCD_WAIT_L2_QUERY (1 << 11) +# define R600_MCD_EFFECTIVE_L1_TLB_SIZE(x) ((x) << 12) +# define R600_MCD_EFFECTIVE_L1_QUEUE_SIZE(x) ((x) << 15) + +#define R700_MC_VM_MD_L1_TLB0_CNTL 0x2654 +#define R700_MC_VM_MD_L1_TLB1_CNTL 0x2658 +#define R700_MC_VM_MD_L1_TLB2_CNTL 0x265c + +#define R700_MC_VM_MB_L1_TLB0_CNTL 0x2234 +#define R700_MC_VM_MB_L1_TLB1_CNTL 0x2238 +#define R700_MC_VM_MB_L1_TLB2_CNTL 0x223c +#define R700_MC_VM_MB_L1_TLB3_CNTL 0x2240 + +# define R700_ENABLE_L1_TLB (1 << 0) +# define R700_ENABLE_L1_FRAGMENT_PROCESSING (1 << 1) +# define R700_SYSTEM_ACCESS_MODE_IN_SYS (2 << 3) +# define R700_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 5) +# define R700_EFFECTIVE_L1_TLB_SIZE(x) ((x) << 15) +# define R700_EFFECTIVE_L1_QUEUE_SIZE(x) ((x) << 18) + +#define R700_MC_ARB_RAMCFG 0x2760 +# define R700_NOOFBANK_SHIFT 0 +# define R700_NOOFBANK_MASK 0x3 +# define R700_NOOFRANK_SHIFT 2 +# define R700_NOOFRANK_MASK 0x1 +# define R700_NOOFROWS_SHIFT 3 +# define R700_NOOFROWS_MASK 0x7 +# define R700_NOOFCOLS_SHIFT 6 +# define R700_NOOFCOLS_MASK 0x3 +# define R700_CHANSIZE_SHIFT 8 +# define R700_CHANSIZE_MASK 0x1 +# define R700_BURSTLENGTH_SHIFT 9 +# define R700_BURSTLENGTH_MASK 0x1 +#define R600_RAMCFG 0x2408 +# define R600_NOOFBANK_SHIFT 0 +# define R600_NOOFBANK_MASK 0x1 +# define R600_NOOFRANK_SHIFT 1 +# define R600_NOOFRANK_MASK 0x1 +# define R600_NOOFROWS_SHIFT 2 +# define R600_NOOFROWS_MASK 0x7 +# define R600_NOOFCOLS_SHIFT 5 +# define R600_NOOFCOLS_MASK 0x3 +# define R600_CHANSIZE_SHIFT 7 +# define R600_CHANSIZE_MASK 0x1 +# define R600_BURSTLENGTH_SHIFT 8 +# define R600_BURSTLENGTH_MASK 0x1 + +#define R600_VM_L2_CNTL 0x1400 +# define R600_VM_L2_CACHE_EN (1 << 0) +# define R600_VM_L2_FRAG_PROC (1 << 1) +# define R600_VM_ENABLE_PTE_CACHE_LRU_W (1 << 9) +# define R600_VM_L2_CNTL_QUEUE_SIZE(x) ((x) << 13) +# define R700_VM_L2_CNTL_QUEUE_SIZE(x) ((x) << 14) + +#define R600_VM_L2_CNTL2 0x1404 +# define R600_VM_L2_CNTL2_INVALIDATE_ALL_L1_TLBS (1 << 0) +# define R600_VM_L2_CNTL2_INVALIDATE_L2_CACHE (1 << 1) +#define R600_VM_L2_CNTL3 0x1408 +# define R600_VM_L2_CNTL3_BANK_SELECT_0(x) ((x) << 0) +# define R600_VM_L2_CNTL3_BANK_SELECT_1(x) ((x) << 5) +# define R600_VM_L2_CNTL3_CACHE_UPDATE_MODE(x) ((x) << 10) +# define R700_VM_L2_CNTL3_BANK_SELECT(x) ((x) << 0) +# define R700_VM_L2_CNTL3_CACHE_UPDATE_MODE(x) ((x) << 6) + +#define R600_VM_L2_STATUS 0x140c + +#define R600_VM_CONTEXT0_CNTL 0x1410 +# define R600_VM_ENABLE_CONTEXT (1 << 0) +# define R600_VM_PAGE_TABLE_DEPTH_FLAT (0 << 1) + +#define R600_VM_CONTEXT0_CNTL2 0x1430 +#define R600_VM_CONTEXT0_REQUEST_RESPONSE 0x1470 +#define R600_VM_CONTEXT0_INVALIDATION_LOW_ADDR 0x1490 +#define R600_VM_CONTEXT0_INVALIDATION_HIGH_ADDR 0x14b0 +#define R600_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x1574 +#define R600_VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x1594 +#define R600_VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x15b4 + +#define R700_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x153c +#define R700_VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x155c +#define R700_VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x157c + +#define R600_HDP_HOST_PATH_CNTL 0x2c00 + +#define R600_GRBM_CNTL 0x8000 +# define R600_GRBM_READ_TIMEOUT(x) ((x) << 0) + +#define R600_GRBM_STATUS 0x8010 +# define R600_CMDFIFO_AVAIL_MASK 0x1f +# define R700_CMDFIFO_AVAIL_MASK 0xf +# define R600_GUI_ACTIVE (1 << 31) +#define R600_GRBM_STATUS2 0x8014 +#define R600_GRBM_SOFT_RESET 0x8020 +# define R600_SOFT_RESET_CP (1 << 0) +#define R600_WAIT_UNTIL 0x8040 + +#define R600_CP_SEM_WAIT_TIMER 0x85bc +#define R600_CP_ME_CNTL 0x86d8 +# define R600_CP_ME_HALT (1 << 28) +#define R600_CP_QUEUE_THRESHOLDS 0x8760 +# define R600_ROQ_IB1_START(x) ((x) << 0) +# define R600_ROQ_IB2_START(x) ((x) << 8) +#define R600_CP_MEQ_THRESHOLDS 0x8764 +# define R700_STQ_SPLIT(x) ((x) << 0) +# define R600_MEQ_END(x) ((x) << 16) +# define R600_ROQ_END(x) ((x) << 24) +#define R600_CP_PERFMON_CNTL 0x87fc +#define R600_CP_RB_BASE 0xc100 +#define R600_CP_RB_CNTL 0xc104 +# define R600_RB_BUFSZ(x) ((x) << 0) +# define R600_RB_BLKSZ(x) ((x) << 8) +# define R600_RB_NO_UPDATE (1 << 27) +# define R600_RB_RPTR_WR_ENA (1 << 31) +#define R600_CP_RB_RPTR_WR 0xc108 +#define R600_CP_RB_RPTR_ADDR 0xc10c +#define R600_CP_RB_RPTR_ADDR_HI 0xc110 +#define R600_CP_RB_WPTR 0xc114 +#define R600_CP_RB_WPTR_ADDR 0xc118 +#define R600_CP_RB_WPTR_ADDR_HI 0xc11c +#define R600_CP_RB_RPTR 0x8700 +#define R600_CP_RB_WPTR_DELAY 0x8704 +#define R600_CP_PFP_UCODE_ADDR 0xc150 +#define R600_CP_PFP_UCODE_DATA 0xc154 +#define R600_CP_ME_RAM_RADDR 0xc158 +#define R600_CP_ME_RAM_WADDR 0xc15c +#define R600_CP_ME_RAM_DATA 0xc160 +#define R600_CP_DEBUG 0xc1fc + +#define R600_PA_CL_ENHANCE 0x8a14 +# define R600_CLIP_VTX_REORDER_ENA (1 << 0) +# define R600_NUM_CLIP_SEQ(x) ((x) << 1) +#define R600_PA_SC_LINE_STIPPLE_STATE 0x8b10 +#define R600_PA_SC_MULTI_CHIP_CNTL 0x8b20 +#define R700_PA_SC_FORCE_EOV_MAX_CNTS 0x8b24 +# define R700_FORCE_EOV_MAX_CLK_CNT(x) ((x) << 0) +# define R700_FORCE_EOV_MAX_REZ_CNT(x) ((x) << 16) +#define R600_PA_SC_AA_SAMPLE_LOCS_2S 0x8b40 +#define R600_PA_SC_AA_SAMPLE_LOCS_4S 0x8b44 +#define R600_PA_SC_AA_SAMPLE_LOCS_8S_WD0 0x8b48 +#define R600_PA_SC_AA_SAMPLE_LOCS_8S_WD1 0x8b4c +# define R600_S0_X(x) ((x) << 0) +# define R600_S0_Y(x) ((x) << 4) +# define R600_S1_X(x) ((x) << 8) +# define R600_S1_Y(x) ((x) << 12) +# define R600_S2_X(x) ((x) << 16) +# define R600_S2_Y(x) ((x) << 20) +# define R600_S3_X(x) ((x) << 24) +# define R600_S3_Y(x) ((x) << 28) +# define R600_S4_X(x) ((x) << 0) +# define R600_S4_Y(x) ((x) << 4) +# define R600_S5_X(x) ((x) << 8) +# define R600_S5_Y(x) ((x) << 12) +# define R600_S6_X(x) ((x) << 16) +# define R600_S6_Y(x) ((x) << 20) +# define R600_S7_X(x) ((x) << 24) +# define R600_S7_Y(x) ((x) << 28) +#define R600_PA_SC_FIFO_SIZE 0x8bd0 +# define R600_SC_PRIM_FIFO_SIZE(x) ((x) << 0) +# define R600_SC_HIZ_TILE_FIFO_SIZE(x) ((x) << 8) +# define R600_SC_EARLYZ_TILE_FIFO_SIZE(x) ((x) << 16) +#define R700_PA_SC_FIFO_SIZE_R7XX 0x8bcc +# define R700_SC_PRIM_FIFO_SIZE(x) ((x) << 0) +# define R700_SC_HIZ_TILE_FIFO_SIZE(x) ((x) << 12) +# define R700_SC_EARLYZ_TILE_FIFO_SIZE(x) ((x) << 20) +#define R600_PA_SC_ENHANCE 0x8bf0 +# define R600_FORCE_EOV_MAX_CLK_CNT(x) ((x) << 0) +# define R600_FORCE_EOV_MAX_TILE_CNT(x) ((x) << 12) +#define R600_PA_SC_CLIPRECT_RULE 0x2820c +#define R700_PA_SC_EDGERULE 0x28230 +#define R600_PA_SC_LINE_STIPPLE 0x28a0c +#define R600_PA_SC_MODE_CNTL 0x28a4c +#define R600_PA_SC_AA_CONFIG 0x28c04 + +#define R600_SX_EXPORT_BUFFER_SIZES 0x900c +# define R600_COLOR_BUFFER_SIZE(x) ((x) << 0) +# define R600_POSITION_BUFFER_SIZE(x) ((x) << 8) +# define R600_SMX_BUFFER_SIZE(x) ((x) << 16) +#define R600_SX_DEBUG_1 0x9054 +# define R600_SMX_EVENT_RELEASE (1 << 0) +# define R600_ENABLE_NEW_SMX_ADDRESS (1 << 16) +#define R700_SX_DEBUG_1 0x9058 +# define R700_ENABLE_NEW_SMX_ADDRESS (1 << 16) +#define R600_SX_MISC 0x28350 + +#define R600_DB_DEBUG 0x9830 +# define R600_PREZ_MUST_WAIT_FOR_POSTZ_DONE (1 << 31) +#define R600_DB_WATERMARKS 0x9838 +# define R600_DEPTH_FREE(x) ((x) << 0) +# define R600_DEPTH_FLUSH(x) ((x) << 5) +# define R600_DEPTH_PENDING_FREE(x) ((x) << 15) +# define R600_DEPTH_CACHELINE_FREE(x) ((x) << 20) +#define R700_DB_DEBUG3 0x98b0 +# define R700_DB_CLK_OFF_DELAY(x) ((x) << 11) +#define RV700_DB_DEBUG4 0x9b8c +# define RV700_DISABLE_TILE_COVERED_FOR_PS_ITER (1 << 6) + +#define R600_VGT_CACHE_INVALIDATION 0x88c4 +# define R600_CACHE_INVALIDATION(x) ((x) << 0) +# define R600_VC_ONLY 0 +# define R600_TC_ONLY 1 +# define R600_VC_AND_TC 2 +# define R700_AUTO_INVLD_EN(x) ((x) << 6) +# define R700_NO_AUTO 0 +# define R700_ES_AUTO 1 +# define R700_GS_AUTO 2 +# define R700_ES_AND_GS_AUTO 3 +#define R600_VGT_GS_PER_ES 0x88c8 +#define R600_VGT_ES_PER_GS 0x88cc +#define R600_VGT_GS_PER_VS 0x88e8 +#define R600_VGT_GS_VERTEX_REUSE 0x88d4 +#define R600_VGT_NUM_INSTANCES 0x8974 +#define R600_VGT_STRMOUT_EN 0x28ab0 +#define R600_VGT_EVENT_INITIATOR 0x28a90 +# define R600_CACHE_FLUSH_AND_INV_EVENT (0x16 << 0) +#define R600_VGT_VERTEX_REUSE_BLOCK_CNTL 0x28c58 +# define R600_VTX_REUSE_DEPTH_MASK 0xff +#define R600_VGT_OUT_DEALLOC_CNTL 0x28c5c +# define R600_DEALLOC_DIST_MASK 0x7f + +#define R600_CB_COLOR0_BASE 0x28040 +#define R600_CB_COLOR1_BASE 0x28044 +#define R600_CB_COLOR2_BASE 0x28048 +#define R600_CB_COLOR3_BASE 0x2804c +#define R600_CB_COLOR4_BASE 0x28050 +#define R600_CB_COLOR5_BASE 0x28054 +#define R600_CB_COLOR6_BASE 0x28058 +#define R600_CB_COLOR7_BASE 0x2805c +#define R600_CB_COLOR7_FRAG 0x280fc + +#define R600_TC_CNTL 0x9608 +# define R600_TC_L2_SIZE(x) ((x) << 5) +# define R600_L2_DISABLE_LATE_HIT (1 << 9) + +#define R600_ARB_POP 0x2418 +# define R600_ENABLE_TC128 (1 << 30) +#define R600_ARB_GDEC_RD_CNTL 0x246c + +#define R600_TA_CNTL_AUX 0x9508 +# define R600_DISABLE_CUBE_WRAP (1 << 0) +# define R600_DISABLE_CUBE_ANISO (1 << 1) +# define R700_GETLOD_SELECT(x) ((x) << 2) +# define R600_SYNC_GRADIENT (1 << 24) +# define R600_SYNC_WALKER (1 << 25) +# define R600_SYNC_ALIGNER (1 << 26) +# define R600_BILINEAR_PRECISION_6_BIT (0 << 31) +# define R600_BILINEAR_PRECISION_8_BIT (1 << 31) + +#define R700_TCP_CNTL 0x9610 + +#define R600_SMX_DC_CTL0 0xa020 +# define R700_USE_HASH_FUNCTION (1 << 0) +# define R700_CACHE_DEPTH(x) ((x) << 1) +# define R700_FLUSH_ALL_ON_EVENT (1 << 10) +# define R700_STALL_ON_EVENT (1 << 11) +#define R700_SMX_EVENT_CTL 0xa02c +# define R700_ES_FLUSH_CTL(x) ((x) << 0) +# define R700_GS_FLUSH_CTL(x) ((x) << 3) +# define R700_ACK_FLUSH_CTL(x) ((x) << 6) +# define R700_SYNC_FLUSH_CTL (1 << 8) + +#define R600_SQ_CONFIG 0x8c00 +# define R600_VC_ENABLE (1 << 0) +# define R600_EXPORT_SRC_C (1 << 1) +# define R600_DX9_CONSTS (1 << 2) +# define R600_ALU_INST_PREFER_VECTOR (1 << 3) +# define R600_DX10_CLAMP (1 << 4) +# define R600_CLAUSE_SEQ_PRIO(x) ((x) << 8) +# define R600_PS_PRIO(x) ((x) << 24) +# define R600_VS_PRIO(x) ((x) << 26) +# define R600_GS_PRIO(x) ((x) << 28) +# define R600_ES_PRIO(x) ((x) << 30) +#define R600_SQ_GPR_RESOURCE_MGMT_1 0x8c04 +# define R600_NUM_PS_GPRS(x) ((x) << 0) +# define R600_NUM_VS_GPRS(x) ((x) << 16) +# define R700_DYN_GPR_ENABLE (1 << 27) +# define R600_NUM_CLAUSE_TEMP_GPRS(x) ((x) << 28) +#define R600_SQ_GPR_RESOURCE_MGMT_2 0x8c08 +# define R600_NUM_GS_GPRS(x) ((x) << 0) +# define R600_NUM_ES_GPRS(x) ((x) << 16) +#define R600_SQ_THREAD_RESOURCE_MGMT 0x8c0c +# define R600_NUM_PS_THREADS(x) ((x) << 0) +# define R600_NUM_VS_THREADS(x) ((x) << 8) +# define R600_NUM_GS_THREADS(x) ((x) << 16) +# define R600_NUM_ES_THREADS(x) ((x) << 24) +#define R600_SQ_STACK_RESOURCE_MGMT_1 0x8c10 +# define R600_NUM_PS_STACK_ENTRIES(x) ((x) << 0) +# define R600_NUM_VS_STACK_ENTRIES(x) ((x) << 16) +#define R600_SQ_STACK_RESOURCE_MGMT_2 0x8c14 +# define R600_NUM_GS_STACK_ENTRIES(x) ((x) << 0) +# define R600_NUM_ES_STACK_ENTRIES(x) ((x) << 16) +#define R600_SQ_MS_FIFO_SIZES 0x8cf0 +# define R600_CACHE_FIFO_SIZE(x) ((x) << 0) +# define R600_FETCH_FIFO_HIWATER(x) ((x) << 8) +# define R600_DONE_FIFO_HIWATER(x) ((x) << 16) +# define R600_ALU_UPDATE_FIFO_HIWATER(x) ((x) << 24) +#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_0 0x8db0 +# define R700_SIMDA_RING0(x) ((x) << 0) +# define R700_SIMDA_RING1(x) ((x) << 8) +# define R700_SIMDB_RING0(x) ((x) << 16) +# define R700_SIMDB_RING1(x) ((x) << 24) +#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_1 0x8db4 +#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_2 0x8db8 +#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_3 0x8dbc +#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_4 0x8dc0 +#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_5 0x8dc4 +#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_6 0x8dc8 +#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_7 0x8dcc + +#define R600_SPI_PS_IN_CONTROL_0 0x286cc +# define R600_NUM_INTERP(x) ((x) << 0) +# define R600_POSITION_ENA (1 << 8) +# define R600_POSITION_CENTROID (1 << 9) +# define R600_POSITION_ADDR(x) ((x) << 10) +# define R600_PARAM_GEN(x) ((x) << 15) +# define R600_PARAM_GEN_ADDR(x) ((x) << 19) +# define R600_BARYC_SAMPLE_CNTL(x) ((x) << 26) +# define R600_PERSP_GRADIENT_ENA (1 << 28) +# define R600_LINEAR_GRADIENT_ENA (1 << 29) +# define R600_POSITION_SAMPLE (1 << 30) +# define R600_BARYC_AT_SAMPLE_ENA (1 << 31) +#define R600_SPI_PS_IN_CONTROL_1 0x286d0 +# define R600_GEN_INDEX_PIX (1 << 0) +# define R600_GEN_INDEX_PIX_ADDR(x) ((x) << 1) +# define R600_FRONT_FACE_ENA (1 << 8) +# define R600_FRONT_FACE_CHAN(x) ((x) << 9) +# define R600_FRONT_FACE_ALL_BITS (1 << 11) +# define R600_FRONT_FACE_ADDR(x) ((x) << 12) +# define R600_FOG_ADDR(x) ((x) << 17) +# define R600_FIXED_PT_POSITION_ENA (1 << 24) +# define R600_FIXED_PT_POSITION_ADDR(x) ((x) << 25) +# define R700_POSITION_ULC (1 << 30) +#define R600_SPI_INPUT_Z 0x286d8 + +#define R600_SPI_CONFIG_CNTL 0x9100 +# define R600_GPR_WRITE_PRIORITY(x) ((x) << 0) +# define R600_DISABLE_INTERP_1 (1 << 5) +#define R600_SPI_CONFIG_CNTL_1 0x913c +# define R600_VTX_DONE_DELAY(x) ((x) << 0) +# define R600_INTERP_ONE_PRIM_PER_ROW (1 << 4) + +#define R600_GB_TILING_CONFIG 0x98f0 +# define R600_PIPE_TILING(x) ((x) << 1) +# define R600_BANK_TILING(x) ((x) << 4) +# define R600_GROUP_SIZE(x) ((x) << 6) +# define R600_ROW_TILING(x) ((x) << 8) +# define R600_BANK_SWAPS(x) ((x) << 11) +# define R600_SAMPLE_SPLIT(x) ((x) << 14) +# define R600_BACKEND_MAP(x) ((x) << 16) +#define R600_DCP_TILING_CONFIG 0x6ca0 +#define R600_HDP_TILING_CONFIG 0x2f3c + +#define R600_CC_RB_BACKEND_DISABLE 0x98f4 +#define R700_CC_SYS_RB_BACKEND_DISABLE 0x3f88 +# define R600_BACKEND_DISABLE(x) ((x) << 16) + +#define R600_CC_GC_SHADER_PIPE_CONFIG 0x8950 +#define R600_GC_USER_SHADER_PIPE_CONFIG 0x8954 +# define R600_INACTIVE_QD_PIPES(x) ((x) << 8) +# define R600_INACTIVE_QD_PIPES_MASK (0xff << 8) +# define R600_INACTIVE_SIMDS(x) ((x) << 16) +# define R600_INACTIVE_SIMDS_MASK (0xff << 16) + +#define R700_CGTS_SYS_TCC_DISABLE 0x3f90 +#define R700_CGTS_USER_SYS_TCC_DISABLE 0x3f94 +#define R700_CGTS_TCC_DISABLE 0x9148 +#define R700_CGTS_USER_TCC_DISABLE 0x914c + /* Constants */ #define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ @@ -1183,6 +1738,12 @@ #define RADEON_LAST_SWI_REG RADEON_SCRATCH_REG3 #define RADEON_LAST_DISPATCH 1 + +#define R600_LAST_FRAME_REG R600_SCRATCH_REG0 +#define R600_LAST_DISPATCH_REG R600_SCRATCH_REG1 +#define R600_LAST_CLEAR_REG R600_SCRATCH_REG2 +#define R600_LAST_SWI_REG R600_SCRATCH_REG3 + #define RADEON_MAX_VB_AGE 0x7fffffff #define RADEON_MAX_VB_VERTS (0xffff) @@ -1190,10 +1751,18 @@ #define RADEON_PCIGART_TABLE_SIZE (32*1024) -#define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) -#define RADEON_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) -#define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) -#define RADEON_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) ) +#define RADEON_READ(reg) RADEON_READ_MM(dev_priv, reg) +#define RADEON_WRITE(reg,val) \ +do { \ + if (reg < 0x10000) { \ + DRM_WRITE32(dev_priv->mmio, (reg), (val)); \ + } else { \ + DRM_WRITE32(dev_priv->mmio, RADEON_MM_INDEX, (reg)); \ + DRM_WRITE32(dev_priv->mmio, RADEON_MM_DATA, (val)); \ + } \ +} while (0) +#define RADEON_READ8(reg) DRM_READ8(dev_priv->mmio, (reg)) +#define RADEON_WRITE8(reg, val) DRM_WRITE8(dev_priv->mmio, (reg), (val)) #define RADEON_WRITE_PLL(addr, val) \ do { \ @@ -1231,12 +1800,20 @@ RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); \ } while (0) +#define RS600_WRITE_MCIND(addr, val) \ +do { \ + RADEON_WRITE(RS600_MC_INDEX, RS600_MC_IND_WR_EN | RS600_MC_IND_CITF_ARB0 | ((addr) & RS600_MC_ADDR_MASK)); \ + RADEON_WRITE(RS600_MC_DATA, val); \ +} while (0) + #define IGP_WRITE_MCIND(addr, val) \ do { \ - if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || \ - ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) \ + if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || \ + ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) \ RS690_WRITE_MCIND(addr, val); \ - else \ + else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) \ + RS600_WRITE_MCIND(addr, val); \ + else \ RS480_WRITE_MCIND(addr, val); \ } while (0) @@ -1360,6 +1937,24 @@ OUT_RING( age ); \ } while (0) +#define R600_DISPATCH_AGE(age) do { \ + OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); \ + OUT_RING((R600_LAST_DISPATCH_REG - R600_SET_CONFIG_REG_OFFSET) >> 2); \ + OUT_RING(age); \ +} while (0) + +#define R600_FRAME_AGE(age) do { \ + OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); \ + OUT_RING((R600_LAST_FRAME_REG - R600_SET_CONFIG_REG_OFFSET) >> 2); \ + OUT_RING(age); \ +} while (0) + +#define R600_CLEAR_AGE(age) do { \ + OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); \ + OUT_RING((R600_LAST_CLEAR_REG - R600_SET_CONFIG_REG_OFFSET) >> 2); \ + OUT_RING(age); \ +} while (0) + /* ================================================================ * Ring control */ @@ -1396,14 +1991,9 @@ dev_priv->ring.tail = write; \ } while (0) -#define COMMIT_RING() do { \ - /* Flush writes to ring */ \ - DRM_MEMORYBARRIER(); \ - GET_RING_HEAD( dev_priv ); \ - RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \ - /* read from PCI bus to ensure correct posting */ \ - RADEON_READ( RADEON_CP_RB_RPTR ); \ -} while (0) + +#define COMMIT_RING() radeon_commit_ring(dev_priv) + #define OUT_RING( x ) do { \ if ( RADEON_VERBOSE ) { \ --- linux-2.6.28.orig/drivers/gpu/drm/radeon/radeon_state.c +++ linux-2.6.28/drivers/gpu/drm/radeon/radeon_state.c @@ -1548,9 +1548,15 @@ buf_priv->age = ++dev_priv->sarea_priv->last_dispatch; /* Emit the vertex buffer age */ - BEGIN_RING(2); - RADEON_DISPATCH_AGE(buf_priv->age); - ADVANCE_RING(); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { + BEGIN_RING(3); + R600_DISPATCH_AGE(buf_priv->age); + ADVANCE_RING(); + } else { + BEGIN_RING(2); + RADEON_DISPATCH_AGE(buf_priv->age); + ADVANCE_RING(); + } buf->pending = 1; buf->used = 0; @@ -2101,6 +2107,11 @@ drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_surface_free_t *memfree = data; + if (!dev_priv) { + DRM_ERROR("called with no initialization\n"); + return -EINVAL; + } + if (free_surface(file_priv, dev_priv, memfree->address)) return -EINVAL; else @@ -2453,24 +2464,25 @@ buf->used = indirect->end; - /* Wait for the 3D stream to idle before the indirect buffer - * containing 2D acceleration commands is processed. - */ - BEGIN_RING(2); - - RADEON_WAIT_UNTIL_3D_IDLE(); - - ADVANCE_RING(); - /* Dispatch the indirect buffer full of commands from the * X server. This is insecure and is thus only available to * privileged clients. */ - radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end); - if (indirect->discard) { - radeon_cp_discard_buffer(dev, buf); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + r600_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end); + else { + /* Wait for the 3D stream to idle before the indirect buffer + * containing 2D acceleration commands is processed. + */ + BEGIN_RING(2); + RADEON_WAIT_UNTIL_3D_IDLE(); + ADVANCE_RING(); + radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end); } + if (indirect->discard) + radeon_cp_discard_buffer(dev, buf); + COMMIT_RING(); return 0; } @@ -2987,14 +2999,23 @@ break; case RADEON_PARAM_LAST_FRAME: dev_priv->stats.last_frame_reads++; - value = GET_SCRATCH(0); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + value = GET_R600_SCRATCH(0); + else + value = GET_SCRATCH(0); break; case RADEON_PARAM_LAST_DISPATCH: - value = GET_SCRATCH(1); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + value = GET_R600_SCRATCH(1); + else + value = GET_SCRATCH(1); break; case RADEON_PARAM_LAST_CLEAR: dev_priv->stats.last_clear_reads++; - value = GET_SCRATCH(2); + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + value = GET_R600_SCRATCH(2); + else + value = GET_SCRATCH(2); break; case RADEON_PARAM_IRQ_NR: value = drm_dev_to_irq(dev); @@ -3029,7 +3050,10 @@ case RADEON_PARAM_SCRATCH_OFFSET: if (!dev_priv->writeback_works) return -EINVAL; - value = RADEON_SCRATCH_REG_OFFSET; + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) + value = R600_SCRATCH_REG_OFFSET; + else + value = RADEON_SCRATCH_REG_OFFSET; break; case RADEON_PARAM_CARD_TYPE: if (dev_priv->flags & RADEON_IS_PCIE) @@ -3067,6 +3091,11 @@ drm_radeon_setparam_t *sp = data; struct drm_radeon_driver_file_fields *radeon_priv; + if (!dev_priv) { + DRM_ERROR("called with no initialization\n"); + return -EINVAL; + } + switch (sp->param) { case RADEON_SETPARAM_FB_LOCATION: radeon_priv = file_priv->driver_priv; --- linux-2.6.28.orig/drivers/gpu/drm/i915/i915_irq.c +++ linux-2.6.28/drivers/gpu/drm/i915/i915_irq.c @@ -164,6 +164,19 @@ return count; } +u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) +{ + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + int reg = pipe ? PIPEB_FRMCOUNT_GM45 : PIPEA_FRMCOUNT_GM45; + + if (!i915_pipe_enabled(dev, pipe)) { + DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe); + return 0; + } + + return I915_READ(reg); +} + irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) { struct drm_device *dev = (struct drm_device *) arg; @@ -400,6 +413,12 @@ { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; unsigned long irqflags; + int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; + u32 pipeconf; + + pipeconf = I915_READ(pipeconf_reg); + if (!(pipeconf & PIPEACONF_ENABLE)) + return -EINVAL; spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); if (IS_I965G(dev)) --- linux-2.6.28.orig/drivers/gpu/drm/i915/i915_drv.c +++ linux-2.6.28/drivers/gpu/drm/i915/i915_drv.c @@ -97,7 +97,6 @@ .suspend = i915_suspend, .resume = i915_resume, .device_is_agp = i915_driver_device_is_agp, - .get_vblank_counter = i915_get_vblank_counter, .enable_vblank = i915_enable_vblank, .disable_vblank = i915_disable_vblank, .irq_preinstall = i915_driver_irq_preinstall, --- linux-2.6.28.orig/drivers/gpu/drm/i915/i915_dma.c +++ linux-2.6.28/drivers/gpu/drm/i915/i915_dma.c @@ -838,6 +838,10 @@ dev_priv->has_gem = 1; #endif + dev->driver->get_vblank_counter = i915_get_vblank_counter; + if (IS_GM45(dev)) + dev->driver->get_vblank_counter = gm45_get_vblank_counter; + i915_gem_load(dev); /* Init HWS */ --- linux-2.6.28.orig/drivers/gpu/drm/i915/i915_drv.h +++ linux-2.6.28/drivers/gpu/drm/i915/i915_drv.h @@ -453,6 +453,7 @@ extern int i915_enable_vblank(struct drm_device *dev, int crtc); extern void i915_disable_vblank(struct drm_device *dev, int crtc); extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc); +extern u32 gm45_get_vblank_counter(struct drm_device *dev, int crtc); extern int i915_vblank_swap(struct drm_device *dev, void *data, struct drm_file *file_priv); extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask); --- linux-2.6.28.orig/drivers/gpu/drm/i915/i915_gem.c +++ linux-2.6.28/drivers/gpu/drm/i915/i915_gem.c @@ -1161,6 +1161,8 @@ struct drm_mm_node *free_space; int page_count, ret; + if (dev_priv->mm.suspended) + return -EBUSY; if (alignment == 0) alignment = PAGE_SIZE; if (alignment & (PAGE_SIZE - 1)) { @@ -2029,13 +2031,15 @@ /* error other than GTT full, or we've already tried again */ if (ret != -ENOMEM || pin_tries >= 1) { - DRM_ERROR("Failed to pin buffers %d\n", ret); + if (ret != -ERESTARTSYS) + DRM_ERROR("Failed to pin buffers %d\n", ret); goto err; } /* unpin all of our buffers */ for (i = 0; i < pinned; i++) i915_gem_object_unpin(object_list[i]); + pinned = 0; /* evict everyone we can from the aperture */ ret = i915_gem_evict_everything(dev); @@ -2178,7 +2182,8 @@ if (obj_priv->gtt_space == NULL) { ret = i915_gem_object_bind_to_gtt(obj, alignment); if (ret != 0) { - DRM_ERROR("Failure to bind: %d", ret); + if (ret != -EBUSY && ret != -ERESTARTSYS) + DRM_ERROR("Failure to bind: %d", ret); return ret; } } @@ -2700,20 +2705,21 @@ dev_priv->mm.wedged = 0; } - ret = i915_gem_init_ringbuffer(dev); - if (ret != 0) - return ret; - dev_priv->mm.gtt_mapping = io_mapping_create_wc(dev->agp->base, dev->agp->agp_info.aper_size * 1024 * 1024); mutex_lock(&dev->struct_mutex); + dev_priv->mm.suspended = 0; + + ret = i915_gem_init_ringbuffer(dev); + if (ret != 0) + return ret; + BUG_ON(!list_empty(&dev_priv->mm.active_list)); BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); BUG_ON(!list_empty(&dev_priv->mm.request_list)); - dev_priv->mm.suspended = 0; mutex_unlock(&dev->struct_mutex); drm_irq_install(dev); --- linux-2.6.28.orig/drivers/gpu/drm/i915/i915_reg.h +++ linux-2.6.28/drivers/gpu/drm/i915/i915_reg.h @@ -1330,6 +1330,9 @@ #define PIPE_FRAME_LOW_SHIFT 24 #define PIPE_PIXEL_MASK 0x00ffffff #define PIPE_PIXEL_SHIFT 0 +/* GM45+ just has to be different */ +#define PIPEA_FRMCOUNT_GM45 0x70040 +#define PIPEA_FLIPCOUNT_GM45 0x70044 /* Cursor A & B regs */ #define CURACNTR 0x70080 @@ -1398,6 +1401,9 @@ #define PIPEBSTAT 0x71024 #define PIPEBFRAMEHIGH 0x71040 #define PIPEBFRAMEPIXEL 0x71044 +#define PIPEB_FRMCOUNT_GM45 0x71040 +#define PIPEB_FLIPCOUNT_GM45 0x71044 + /* Display B control */ #define DSPBCNTR 0x71180 --- linux-2.6.28.orig/drivers/infiniband/hw/nes/nes_verbs.h +++ linux-2.6.28/drivers/infiniband/hw/nes/nes_verbs.h @@ -134,6 +134,7 @@ struct ietf_mpa_frame *ietf_frame; dma_addr_t ietf_frame_pbase; wait_queue_head_t state_waitq; + struct ib_mr *lsmm_mr; unsigned long socket; struct nes_hw_qp hwqp; struct work_struct work; --- linux-2.6.28.orig/drivers/infiniband/hw/nes/nes_cm.c +++ linux-2.6.28/drivers/infiniband/hw/nes/nes_cm.c @@ -2495,12 +2495,14 @@ int ret = 0; struct nes_vnic *nesvnic; struct nes_device *nesdev; + struct nes_ib_device *nesibdev; nesvnic = to_nesvnic(nesqp->ibqp.device); if (!nesvnic) return -EINVAL; nesdev = nesvnic->nesdev; + nesibdev = nesvnic->nesibdev; nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n", atomic_read(&nesvnic->netdev->refcnt)); @@ -2512,6 +2514,8 @@ } else { /* Need to free the Last Streaming Mode Message */ if (nesqp->ietf_frame) { + if (nesqp->lsmm_mr) + nesibdev->ibdev.dereg_mr(nesqp->lsmm_mr); pci_free_consistent(nesdev->pcidev, nesqp->private_data_len+sizeof(struct ietf_mpa_frame), nesqp->ietf_frame, nesqp->ietf_frame_pbase); @@ -2545,6 +2549,10 @@ struct iw_cm_event cm_event; struct nes_hw_qp_wqe *wqe; struct nes_v4_quad nes_quad; + struct nes_ib_device *nesibdev; + struct ib_mr *ibmr = NULL; + struct ib_phys_buf ibphysbuf; + struct nes_pd *nespd; u32 crc_value; int ret; @@ -2605,6 +2613,26 @@ if (cm_id->remote_addr.sin_addr.s_addr != cm_id->local_addr.sin_addr.s_addr) { u64temp = (unsigned long)nesqp; + nesibdev = nesvnic->nesibdev; + nespd = nesqp->nespd; + ibphysbuf.addr = nesqp->ietf_frame_pbase; + ibphysbuf.size = conn_param->private_data_len + + sizeof(struct ietf_mpa_frame); + ibmr = nesibdev->ibdev.reg_phys_mr((struct ib_pd *)nespd, + &ibphysbuf, 1, + IB_ACCESS_LOCAL_WRITE, + (u64 *)&nesqp->ietf_frame); + if (!ibmr) { + nes_debug(NES_DBG_CM, "Unable to register memory region" + "for lSMM for cm_node = %p \n", + cm_node); + return -ENOMEM; + } + + ibmr->pd = &nespd->ibpd; + ibmr->device = nespd->ibpd.device; + nesqp->lsmm_mr = ibmr; + u64temp |= NES_SW_CONTEXT_ALIGN>>1; set_wqe_64bit_value(wqe->wqe_words, NES_IWARP_SQ_WQE_COMP_CTX_LOW_IDX, @@ -2615,14 +2643,13 @@ wqe->wqe_words[NES_IWARP_SQ_WQE_TOTAL_PAYLOAD_IDX] = cpu_to_le32(conn_param->private_data_len + sizeof(struct ietf_mpa_frame)); - wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_LOW_IDX] = - cpu_to_le32((u32)nesqp->ietf_frame_pbase); - wqe->wqe_words[NES_IWARP_SQ_WQE_FRAG0_HIGH_IDX] = - cpu_to_le32((u32)((u64)nesqp->ietf_frame_pbase >> 32)); + set_wqe_64bit_value(wqe->wqe_words, + NES_IWARP_SQ_WQE_FRAG0_LOW_IDX, + (u64)nesqp->ietf_frame); wqe->wqe_words[NES_IWARP_SQ_WQE_LENGTH0_IDX] = cpu_to_le32(conn_param->private_data_len + sizeof(struct ietf_mpa_frame)); - wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = 0; + wqe->wqe_words[NES_IWARP_SQ_WQE_STAG0_IDX] = ibmr->lkey; nesqp->nesqp_context->ird_ord_sizes |= cpu_to_le32(NES_QPCONTEXT_ORDIRD_LSMM_PRESENT | --- linux-2.6.28.orig/drivers/infiniband/hw/nes/nes_verbs.c +++ linux-2.6.28/drivers/infiniband/hw/nes/nes_verbs.c @@ -1360,8 +1360,10 @@ NES_QPCONTEXT_MISC_RQ_SIZE_SHIFT); nesqp->nesqp_context->misc |= cpu_to_le32((u32)nesqp->hwqp.sq_encoded_size << NES_QPCONTEXT_MISC_SQ_SIZE_SHIFT); + if (!udata) { nesqp->nesqp_context->misc |= cpu_to_le32(NES_QPCONTEXT_MISC_PRIV_EN); nesqp->nesqp_context->misc |= cpu_to_le32(NES_QPCONTEXT_MISC_FAST_REGISTER_EN); + } nesqp->nesqp_context->cqs = cpu_to_le32(nesqp->nesscq->hw_cq.cq_number + ((u32)nesqp->nesrcq->hw_cq.cq_number << 16)); u64temp = (u64)nesqp->hwqp.sq_pbase; --- linux-2.6.28.orig/drivers/ieee1394/ohci1394.h +++ linux-2.6.28/drivers/ieee1394/ohci1394.h @@ -26,7 +26,7 @@ #define OHCI1394_DRIVER_NAME "ohci1394" -#define OHCI1394_MAX_AT_REQ_RETRIES 0x2 +#define OHCI1394_MAX_AT_REQ_RETRIES 0xf #define OHCI1394_MAX_AT_RESP_RETRIES 0x2 #define OHCI1394_MAX_PHYS_RESP_RETRIES 0x8 #define OHCI1394_MAX_SELF_ID_ERRORS 16 --- linux-2.6.28.orig/drivers/ieee1394/sbp2.c +++ linux-2.6.28/drivers/ieee1394/sbp2.c @@ -395,6 +395,16 @@ .model_id = SBP2_ROM_VALUE_WILDCARD, .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS, }, + /* + * iPod 2nd generation: needs 128k max transfer size workaround + * iPod 3rd generation: needs fix capacity workaround + */ + { + .firmware_revision = 0x0a2700, + .model_id = 0x000000, + .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS | + SBP2_WORKAROUND_FIX_CAPACITY, + }, /* iPod 4th generation */ { .firmware_revision = 0x0a2700, .model_id = 0x000021, --- linux-2.6.28.orig/drivers/parisc/sba_iommu.c +++ linux-2.6.28/drivers/parisc/sba_iommu.c @@ -668,7 +668,7 @@ * @dev: instance of PCI owned by the driver that's asking * @mask: number of address bits this PCI device can handle * - * See Documentation/DMA-mapping.txt + * See Documentation/PCI/PCI-DMA-mapping.txt */ static int sba_dma_supported( struct device *dev, u64 mask) { @@ -680,8 +680,8 @@ return(0); } - /* Documentation/DMA-mapping.txt tells drivers to try 64-bit first, - * then fall back to 32-bit if that fails. + /* Documentation/PCI/PCI-DMA-mapping.txt tells drivers to try 64-bit + * first, then fall back to 32-bit if that fails. * We are just "encouraging" 32-bit DMA masks here since we can * never allow IOMMU bypass unless we add special support for ZX1. */ @@ -706,7 +706,7 @@ * @size: number of bytes to map in driver buffer. * @direction: R/W or both. * - * See Documentation/DMA-mapping.txt + * See Documentation/PCI/PCI-DMA-mapping.txt */ static dma_addr_t sba_map_single(struct device *dev, void *addr, size_t size, @@ -785,7 +785,7 @@ * @size: number of bytes mapped in driver buffer. * @direction: R/W or both. * - * See Documentation/DMA-mapping.txt + * See Documentation/PCI/PCI-DMA-mapping.txt */ static void sba_unmap_single(struct device *dev, dma_addr_t iova, size_t size, @@ -861,7 +861,7 @@ * @size: number of bytes mapped in driver buffer. * @dma_handle: IOVA of new buffer. * - * See Documentation/DMA-mapping.txt + * See Documentation/PCI/PCI-DMA-mapping.txt */ static void *sba_alloc_consistent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t gfp) @@ -892,7 +892,7 @@ * @vaddr: virtual address IOVA of "consistent" buffer. * @dma_handler: IO virtual address of "consistent" buffer. * - * See Documentation/DMA-mapping.txt + * See Documentation/PCI/PCI-DMA-mapping.txt */ static void sba_free_consistent(struct device *hwdev, size_t size, void *vaddr, @@ -927,7 +927,7 @@ * @nents: number of entries in list * @direction: R/W or both. * - * See Documentation/DMA-mapping.txt + * See Documentation/PCI/PCI-DMA-mapping.txt */ static int sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents, @@ -1011,7 +1011,7 @@ * @nents: number of entries in list * @direction: R/W or both. * - * See Documentation/DMA-mapping.txt + * See Documentation/PCI/PCI-DMA-mapping.txt */ static void sba_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents, --- linux-2.6.28.orig/drivers/watchdog/ks8695_wdt.c +++ linux-2.6.28/drivers/watchdog/ks8695_wdt.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #define WDT_DEFAULT_TIME 5 /* seconds */ --- linux-2.6.28.orig/drivers/watchdog/Kconfig +++ linux-2.6.28/drivers/watchdog/Kconfig @@ -196,6 +196,18 @@ Say N if you are unsure. +config MXC_WATCHDOG + tristate "MXC watchdog" + depends on WATCHDOG && WATCHDOG_NOWAYOUT + depends on ARCH_MXC + help + Watchdog timer embedded into MXC chips. This will + reboot your system when timeout is reached. + + NOTE: once enabled, this timer cannot be disabled. + To compile this driver as a module, choose M here: the + module will be called mxc_wdt. + config IOP_WATCHDOG tristate "IOP Watchdog" depends on PLAT_IOP @@ -399,7 +411,7 @@ ---help--- Hardware driver for the intel TCO timer based watchdog devices. These drivers are included in the Intel 82801 I/O Controller - Hub family (from ICH0 up to ICH8) and in the Intel 6300ESB + Hub family (from ICH0 up to ICH10) and in the Intel 63xxESB controller hub. The TCO (Total Cost of Ownership) timer is a watchdog timer --- linux-2.6.28.orig/drivers/watchdog/iTCO_wdt.c +++ linux-2.6.28/drivers/watchdog/iTCO_wdt.c @@ -1,7 +1,7 @@ /* - * intel TCO Watchdog Driver (Used in i82801 and i6300ESB chipsets) + * intel TCO Watchdog Driver (Used in i82801 and i63xxESB chipsets) * - * (c) Copyright 2006-2008 Wim Van Sebroeck . + * (c) Copyright 2006-2009 Wim Van Sebroeck . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -63,7 +63,7 @@ /* Module and version information */ #define DRV_NAME "iTCO_wdt" -#define DRV_VERSION "1.04" +#define DRV_VERSION "1.05" #define PFX DRV_NAME ": " /* Includes */ @@ -236,16 +236,16 @@ /* Address definitions for the TCO */ /* TCO base address */ -#define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60 +#define TCOBASE iTCO_wdt_private.ACPIBASE + 0x60 /* SMI Control and Enable Register */ -#define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30 +#define SMI_EN iTCO_wdt_private.ACPIBASE + 0x30 #define TCO_RLD TCOBASE + 0x00 /* TCO Timer Reload and Curr. Value */ #define TCOv1_TMR TCOBASE + 0x01 /* TCOv1 Timer Initial Value */ -#define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */ -#define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */ -#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */ -#define TCO2_STS TCOBASE + 0x06 /* TCO2 Status Register */ +#define TCO_DAT_IN TCOBASE + 0x02 /* TCO Data In Register */ +#define TCO_DAT_OUT TCOBASE + 0x03 /* TCO Data Out Register */ +#define TCO1_STS TCOBASE + 0x04 /* TCO1 Status Register */ +#define TCO2_STS TCOBASE + 0x06 /* TCO2 Status Register */ #define TCO1_CNT TCOBASE + 0x08 /* TCO1 Control Register */ #define TCO2_CNT TCOBASE + 0x0a /* TCO2 Control Register */ #define TCOv2_TMR TCOBASE + 0x12 /* TCOv2 Timer Initial Value */ @@ -338,7 +338,6 @@ static int iTCO_wdt_start(void) { unsigned int val; - unsigned long val32; spin_lock(&iTCO_wdt_private.io_lock); @@ -351,11 +350,6 @@ return -EIO; } - /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ - val32 = inl(SMI_EN); - val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ - outl(val32, SMI_EN); - /* Force the timer to its reload value by writing to the TCO_RLD register */ if (iTCO_wdt_private.iTCO_version == 2) @@ -378,7 +372,6 @@ static int iTCO_wdt_stop(void) { unsigned int val; - unsigned long val32; spin_lock(&iTCO_wdt_private.io_lock); @@ -390,11 +383,6 @@ outw(val, TCO1_CNT); val = inw(TCO1_CNT); - /* Bit 13: TCO_EN -> 1 = Enables the TCO logic to generate SMI# */ - val32 = inl(SMI_EN); - val32 |= 0x00002000; - outl(val32, SMI_EN); - /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ iTCO_wdt_set_NO_REBOOT_bit(); @@ -649,6 +637,7 @@ int ret; u32 base_address; unsigned long RCBA; + unsigned long val32; /* * Find the ACPI/PM base I/O address which is the base @@ -695,6 +684,10 @@ ret = -EIO; goto out; } + /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ + val32 = inl(SMI_EN); + val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ + outl(val32, SMI_EN); /* The TCO I/O registers reside in a 32-byte range pointed to by the TCOBASE value */ --- linux-2.6.28.orig/drivers/watchdog/Makefile +++ linux-2.6.28/drivers/watchdog/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o obj-$(CONFIG_MPCORE_WATCHDOG) += mpcore_wdt.o obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o +obj-$(CONFIG_MXC_WATCHDOG) += mxc_wdt.o obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o obj-$(CONFIG_IOP_WATCHDOG) += iop_wdt.o obj-$(CONFIG_DAVINCI_WATCHDOG) += davinci_wdt.o --- linux-2.6.28.orig/drivers/watchdog/mxc_wdt.c +++ linux-2.6.28/drivers/watchdog/mxc_wdt.c @@ -0,0 +1,385 @@ +/* + * linux/drivers/char/watchdog/mxc_wdt.c + * + * Watchdog driver for FSL MXC. It is based on omap1610_wdt.c + * + * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved. + * 2005 (c) MontaVista Software, 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 + * + * History: + * + * 20051207: + * Full rewrite based on + * linux-2.6.15-rc5/drivers/char/watchdog/omap_wdt.c + * Add platform resource support + * + */ + +/*! + * @defgroup WDOG Watchdog Timer (WDOG) Driver + */ +/*! + * @file mxc_wdt.c + * + * @brief Watchdog timer driver + * + * @ingroup WDOG + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include "mxc_wdt.h" +#define DVR_VER "2.0" + +#define WDOG_SEC_TO_COUNT(s) ((s * 2) << 8) +#define WDOG_COUNT_TO_SEC(c) ((c >> 8) / 2) + +static u32 wdt_base_reg; +static int mxc_wdt_users; +static struct clk *mxc_wdt_clk; + +static unsigned timer_margin = TIMER_MARGIN_DEFAULT; +module_param(timer_margin, uint, 0); +MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)"); + +static unsigned dev_num = 0; + +static void mxc_wdt_ping(u32 base) +{ + /* issue the service sequence instructions */ + __raw_writew(WDT_MAGIC_1, base + MXC_WDT_WSR); + __raw_writew(WDT_MAGIC_2, base + MXC_WDT_WSR); +} + +static void mxc_wdt_config(u32 base) +{ + u16 val; + + val = __raw_readw(base + MXC_WDT_WCR); + val |= 0xFF00 | WCR_WOE_BIT | WCR_WDA_BIT | WCR_SRS_BIT; + /* enable suspend WDT */ + val |= WCR_WDZST_BIT | WCR_WDBG_BIT; + /* generate reset if wdog times out */ + val &= ~WCR_WRE_BIT; + + __raw_writew(val, base + MXC_WDT_WCR); +} + +static void mxc_wdt_enable(u32 base) +{ + u16 val; + + val = __raw_readw(base + MXC_WDT_WCR); + val |= WCR_WDE_BIT; + __raw_writew(val, base + MXC_WDT_WCR); +} + +static void mxc_wdt_disable(u32 base) +{ + /* disable not supported by this chip */ +} + +static void mxc_wdt_adjust_timeout(unsigned new_timeout) +{ + if (new_timeout < TIMER_MARGIN_MIN) + new_timeout = TIMER_MARGIN_DEFAULT; + if (new_timeout > TIMER_MARGIN_MAX) + new_timeout = TIMER_MARGIN_MAX; + timer_margin = new_timeout; +} + +static u16 mxc_wdt_get_timeout(u32 base) +{ + u16 val; + + val = __raw_readw(base + MXC_WDT_WCR); + return WDOG_COUNT_TO_SEC(val); +} + +static u16 mxc_wdt_get_bootreason(u32 base) +{ + u16 val; + + val = __raw_readw(base + MXC_WDT_WRSR); + return val; +} + +static void mxc_wdt_set_timeout(u32 base) +{ + u16 val; + val = __raw_readw(base + MXC_WDT_WCR); + val = (val & 0x00FF) | WDOG_SEC_TO_COUNT(timer_margin); + __raw_writew(val, base + MXC_WDT_WCR); + val = __raw_readw(base + MXC_WDT_WCR); + timer_margin = WDOG_COUNT_TO_SEC(val); +} + +/* + * Allow only one task to hold it open + */ + +static int mxc_wdt_open(struct inode *inode, struct file *file) +{ + + if (test_and_set_bit(1, (unsigned long *)&mxc_wdt_users)) + return -EBUSY; + + mxc_wdt_config(wdt_base_reg); + mxc_wdt_set_timeout(wdt_base_reg); + mxc_wdt_enable(wdt_base_reg); + mxc_wdt_ping(wdt_base_reg); + + return 0; +} + +static int mxc_wdt_release(struct inode *inode, struct file *file) +{ + /* + * Shut off the timer unless NOWAYOUT is defined. + */ +#ifndef CONFIG_WATCHDOG_NOWAYOUT + mxc_wdt_disable(wdt_base_reg); + +#else + printk(KERN_CRIT "mxc_wdt: Unexpected close, not stopping!\n"); +#endif + mxc_wdt_users = 0; + return 0; +} + +static ssize_t +mxc_wdt_write(struct file *file, const char __user * data, + size_t len, loff_t * ppos) +{ + /* Refresh LOAD_TIME. */ + if (len) + mxc_wdt_ping(wdt_base_reg); + return len; +} + +static int +mxc_wdt_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + int new_margin; + int bootr; + + static struct watchdog_info ident = { + .identity = "MXC Watchdog", + .options = WDIOF_SETTIMEOUT, + .firmware_version = 0, + }; + + switch (cmd) { + default: + return -ENOIOCTLCMD; + case WDIOC_GETSUPPORT: + return copy_to_user((struct watchdog_info __user *)arg, &ident, + sizeof(ident)); + case WDIOC_GETSTATUS: + return put_user(0, (int __user *)arg); + case WDIOC_GETBOOTSTATUS: + bootr = mxc_wdt_get_bootreason(wdt_base_reg); + return put_user(bootr, (int __user *)arg); + case WDIOC_KEEPALIVE: + mxc_wdt_ping(wdt_base_reg); + return 0; + case WDIOC_SETTIMEOUT: + if (get_user(new_margin, (int __user *)arg)) + return -EFAULT; + + mxc_wdt_adjust_timeout(new_margin); + mxc_wdt_disable(wdt_base_reg); + mxc_wdt_set_timeout(wdt_base_reg); + mxc_wdt_enable(wdt_base_reg); + mxc_wdt_ping(wdt_base_reg); + return 0; + + case WDIOC_GETTIMEOUT: + mxc_wdt_ping(wdt_base_reg); + new_margin = mxc_wdt_get_timeout(wdt_base_reg); + return put_user(new_margin, (int __user *)arg); + } +} + +static struct file_operations mxc_wdt_fops = { + .owner = THIS_MODULE, + .write = mxc_wdt_write, + .ioctl = mxc_wdt_ioctl, + .open = mxc_wdt_open, + .release = mxc_wdt_release, +}; + +static struct miscdevice mxc_wdt_miscdev = { + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &mxc_wdt_fops +}; + +static int __init mxc_wdt_probe(struct platform_device *pdev) +{ + struct resource *res, *mem; + int ret; + + /* reserve static register mappings */ + res = platform_get_resource(pdev, IORESOURCE_MEM, dev_num); + if (!res) + return -ENOENT; + + mem = request_mem_region(res->start, res->end - res->start + 1, + pdev->name); + if (mem == NULL) + return -EBUSY; + + platform_set_drvdata(pdev, mem); + + wdt_base_reg = IO_ADDRESS(res->start); + mxc_wdt_disable(wdt_base_reg); + mxc_wdt_adjust_timeout(timer_margin); + + mxc_wdt_users = 0; + + mxc_wdt_miscdev.this_device = &pdev->dev; + + mxc_wdt_clk = clk_get(NULL, "wdog_clk"); + clk_enable(mxc_wdt_clk); + + ret = misc_register(&mxc_wdt_miscdev); + if (ret) + goto fail; + + pr_info("MXC Watchdog # %d Timer: initial timeout %d sec\n", dev_num, + timer_margin); + + return 0; + + fail: + release_resource(mem); + pr_info("MXC Watchdog Probe failed\n"); + return ret; +} + +static void mxc_wdt_shutdown(struct platform_device *pdev) +{ + struct resource *res = platform_get_drvdata(pdev); + mxc_wdt_disable(res->start); + pr_info("MXC Watchdog # %d shutdown\n", dev_num); +} + +static int __exit mxc_wdt_remove(struct platform_device *pdev) +{ + struct resource *mem = platform_get_drvdata(pdev); + misc_deregister(&mxc_wdt_miscdev); + release_resource(mem); + pr_info("MXC Watchdog # %d removed\n", dev_num); + return 0; +} + +#ifdef CONFIG_PM + +/* REVISIT ... not clear this is the best way to handle system suspend; and + * it's very inappropriate for selective device suspend (e.g. suspending this + * through sysfs rather than by stopping the watchdog daemon). Also, this + * may not play well enough with NOWAYOUT... + */ + +static int mxc_wdt_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct resource *res = platform_get_drvdata(pdev); + + if (mxc_wdt_users) { + mxc_wdt_disable(res->start); + } + return 0; +} + +static int mxc_wdt_resume(struct platform_device *pdev) +{ + struct resource *res = platform_get_drvdata(pdev); + if (mxc_wdt_users) { + mxc_wdt_enable(res->start); + mxc_wdt_ping(res->start); + } + return 0; +} + +#else +#define mxc_wdt_suspend NULL +#define mxc_wdt_resume NULL +#endif + +static struct platform_driver mxc_wdt_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "mxc_wdt", + }, + .probe = mxc_wdt_probe, + .shutdown = mxc_wdt_shutdown, + .remove = __exit_p(mxc_wdt_remove), + .suspend = mxc_wdt_suspend, + .resume = mxc_wdt_resume, +}; + +static int __init mxc_wdt_init(void) +{ + pr_info("MXC WatchDog Driver %s\n", DVR_VER); + + if ((timer_margin < TIMER_MARGIN_MIN) || + (timer_margin > TIMER_MARGIN_MAX)) { + pr_info("MXC watchdog error. wrong timer_margin %d\n", + timer_margin); + pr_info(" Range: %d to %d seconds\n", TIMER_MARGIN_MIN, + TIMER_MARGIN_MAX); + return -EINVAL; + } + + return platform_driver_register(&mxc_wdt_driver); +} + +static void __exit mxc_wdt_exit(void) +{ + platform_driver_unregister(&mxc_wdt_driver); + pr_info("MXC WatchDog Driver removed\n"); +} + +module_init(mxc_wdt_init); +module_exit(mxc_wdt_exit); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); --- linux-2.6.28.orig/drivers/watchdog/iTCO_vendor_support.c +++ linux-2.6.28/drivers/watchdog/iTCO_vendor_support.c @@ -1,7 +1,7 @@ /* * intel TCO vendor specific watchdog driver support * - * (c) Copyright 2006-2008 Wim Van Sebroeck . + * (c) Copyright 2006-2009 Wim Van Sebroeck . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -19,7 +19,7 @@ /* Module and version information */ #define DRV_NAME "iTCO_vendor_support" -#define DRV_VERSION "1.02" +#define DRV_VERSION "1.03" #define PFX DRV_NAME ": " /* Includes */ @@ -77,6 +77,26 @@ * 20.6 seconds. */ +static void supermicro_old_pre_start(unsigned long acpibase) +{ + unsigned long val32; + + /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ + val32 = inl(SMI_EN); + val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ + outl(val32, SMI_EN); /* Needed to activate watchdog */ +} + +static void supermicro_old_pre_stop(unsigned long acpibase) +{ + unsigned long val32; + + /* Bit 13: TCO_EN -> 1 = Enables the TCO logic to generate SMI# */ + val32 = inl(SMI_EN); + val32 |= 0x00002000; /* Turn on SMI clearing watchdog */ + outl(val32, SMI_EN); /* Needed to deactivate watchdog */ +} + static void supermicro_old_pre_keepalive(unsigned long acpibase) { /* Reload TCO Timer (done in iTCO_wdt_keepalive) + */ @@ -228,14 +248,18 @@ void iTCO_vendor_pre_start(unsigned long acpibase, unsigned int heartbeat) { - if (vendorsupport == SUPERMICRO_NEW_BOARD) + if (vendorsupport == SUPERMICRO_OLD_BOARD) + supermicro_old_pre_start(acpibase); + else if (vendorsupport == SUPERMICRO_NEW_BOARD) supermicro_new_pre_start(heartbeat); } EXPORT_SYMBOL(iTCO_vendor_pre_start); void iTCO_vendor_pre_stop(unsigned long acpibase) { - if (vendorsupport == SUPERMICRO_NEW_BOARD) + if (vendorsupport == SUPERMICRO_OLD_BOARD) + supermicro_old_pre_stop(acpibase); + else if (vendorsupport == SUPERMICRO_NEW_BOARD) supermicro_new_pre_stop(); } EXPORT_SYMBOL(iTCO_vendor_pre_stop); --- linux-2.6.28.orig/drivers/watchdog/mxc_wdt.h +++ linux-2.6.28/drivers/watchdog/mxc_wdt.h @@ -0,0 +1,37 @@ +/* + * linux/drivers/char/watchdog/mxc_wdt.h + * + * BRIEF MODULE DESCRIPTION + * MXC Watchdog timer register definitions + * + * Author: MontaVista Software, Inc. + * or + * + * 2005 (c) MontaVista Software, Inc. + * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved. + * 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 __MXC_WDT_H__ +#define __MXC_WDT_H__ + +#define MXC_WDT_WCR 0x00 +#define MXC_WDT_WSR 0x02 +#define MXC_WDT_WRSR 0x04 +#define WCR_WOE_BIT (1 << 6) +#define WCR_WDA_BIT (1 << 5) +#define WCR_SRS_BIT (1 << 4) +#define WCR_WRE_BIT (1 << 3) +#define WCR_WDE_BIT (1 << 2) +#define WCR_WDBG_BIT (1 << 1) +#define WCR_WDZST_BIT (1 << 0) +#define WDT_MAGIC_1 0x5555 +#define WDT_MAGIC_2 0xAAAA + +#define TIMER_MARGIN_MAX 127 +#define TIMER_MARGIN_DEFAULT 60 /* 60 secs */ +#define TIMER_MARGIN_MIN 1 + +#endif /* __MXC_WDT_H__ */ --- linux-2.6.28.orig/drivers/watchdog/rc32434_wdt.c +++ linux-2.6.28/drivers/watchdog/rc32434_wdt.c @@ -34,104 +34,89 @@ #include #include -#define MAX_TIMEOUT 20 -#define RC32434_WDT_INTERVAL (15 * HZ) - -#define VERSION "0.2" +#define VERSION "0.4" static struct { - struct completion stop; - int running; - struct timer_list timer; - int queue; - int default_ticks; unsigned long inuse; } rc32434_wdt_device; static struct integ __iomem *wdt_reg; -static int ticks = 100 * HZ; static int expect_close; -static int timeout; + +/* Board internal clock speed in Hz, + * the watchdog timer ticks at. */ +extern unsigned int idt_cpu_freq; + +/* translate wtcompare value to seconds and vice versa */ +#define WTCOMP2SEC(x) (x / idt_cpu_freq) +#define SEC2WTCOMP(x) (x * idt_cpu_freq) + +/* Use a default timeout of 20s. This should be + * safe for CPU clock speeds up to 400MHz, as + * ((2 ^ 32) - 1) / (400MHz / 2) = 21s. */ +#define WATCHDOG_TIMEOUT 20 + +static int timeout = WATCHDOG_TIMEOUT; static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); +/* apply or and nand masks to data read from addr and write back */ +#define SET_BITS(addr, or, nand) \ + writel((readl(&addr) | or) & ~nand, &addr) static void rc32434_wdt_start(void) { - u32 val; + u32 or, nand; - if (!rc32434_wdt_device.inuse) { - writel(0, &wdt_reg->wtcount); + /* zero the counter before enabling */ + writel(0, &wdt_reg->wtcount); - val = RC32434_ERR_WRE; - writel(readl(&wdt_reg->errcs) | val, &wdt_reg->errcs); + /* don't generate a non-maskable interrupt, + * do a warm reset instead */ + nand = 1 << RC32434_ERR_WNE; + or = 1 << RC32434_ERR_WRE; - val = RC32434_WTC_EN; - writel(readl(&wdt_reg->wtc) | val, &wdt_reg->wtc); - } - rc32434_wdt_device.running++; -} + /* reset the ERRCS timeout bit in case it's set */ + nand |= 1 << RC32434_ERR_WTO; -static void rc32434_wdt_stop(void) -{ - u32 val; - - if (rc32434_wdt_device.running) { + SET_BITS(wdt_reg->errcs, or, nand); - val = ~RC32434_WTC_EN; - writel(readl(&wdt_reg->wtc) & val, &wdt_reg->wtc); + /* reset WTC timeout bit and enable WDT */ + nand = 1 << RC32434_WTC_TO; + or = 1 << RC32434_WTC_EN; - val = ~RC32434_ERR_WRE; - writel(readl(&wdt_reg->errcs) & val, &wdt_reg->errcs); + SET_BITS(wdt_reg->wtc, or, nand); +} - rc32434_wdt_device.running = 0; - } +static void rc32434_wdt_stop(void) +{ + /* Disable WDT */ + SET_BITS(wdt_reg->wtc, 0, 1 << RC32434_WTC_EN); } -static void rc32434_wdt_set(int new_timeout) +static int rc32434_wdt_set(int new_timeout) { - u32 cmp = new_timeout * HZ; - u32 state, val; + int max_to = WTCOMP2SEC((u32)-1); + if (new_timeout < 0 || new_timeout > max_to) { + printk(KERN_ERR KBUILD_MODNAME + ": timeout value must be between 0 and %d", + max_to); + return -EINVAL; + } timeout = new_timeout; - /* - * store and disable WTC - */ - state = (u32)(readl(&wdt_reg->wtc) & RC32434_WTC_EN); - val = ~RC32434_WTC_EN; - writel(readl(&wdt_reg->wtc) & val, &wdt_reg->wtc); - - writel(0, &wdt_reg->wtcount); - writel(cmp, &wdt_reg->wtcompare); - - /* - * restore WTC - */ + writel(SEC2WTCOMP(timeout), &wdt_reg->wtcompare); - writel(readl(&wdt_reg->wtc) | state, &wdt_reg); -} - -static void rc32434_wdt_reset(void) -{ - ticks = rc32434_wdt_device.default_ticks; + return 0; } -static void rc32434_wdt_update(unsigned long unused) +static void rc32434_wdt_ping(void) { - if (rc32434_wdt_device.running) - ticks--; - writel(0, &wdt_reg->wtcount); - - if (rc32434_wdt_device.queue && ticks) - mod_timer(&rc32434_wdt_device.timer, - jiffies + RC32434_WDT_INTERVAL); - else - complete(&rc32434_wdt_device.stop); } static int rc32434_wdt_open(struct inode *inode, struct file *file) @@ -142,19 +127,23 @@ if (nowayout) __module_get(THIS_MODULE); + rc32434_wdt_start(); + rc32434_wdt_ping(); + return nonseekable_open(inode, file); } static int rc32434_wdt_release(struct inode *inode, struct file *file) { - if (expect_close && nowayout == 0) { + if (expect_close == 42) { rc32434_wdt_stop(); printk(KERN_INFO KBUILD_MODNAME ": disabling watchdog timer\n"); module_put(THIS_MODULE); - } else + } else { printk(KERN_CRIT KBUILD_MODNAME ": device closed unexpectedly. WDT will not stop !\n"); - + rc32434_wdt_ping(); + } clear_bit(0, &rc32434_wdt_device.inuse); return 0; } @@ -174,10 +163,10 @@ if (get_user(c, data + i)) return -EFAULT; if (c == 'V') - expect_close = 1; + expect_close = 42; } } - rc32434_wdt_update(0); + rc32434_wdt_ping(); return len; } return 0; @@ -197,11 +186,11 @@ }; switch (cmd) { case WDIOC_KEEPALIVE: - rc32434_wdt_reset(); + rc32434_wdt_ping(); break; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: - value = readl(&wdt_reg->wtcount); + value = 0; if (copy_to_user(argp, &value, sizeof(int))) return -EFAULT; break; @@ -218,6 +207,7 @@ break; case WDIOS_DISABLECARD: rc32434_wdt_stop(); + break; default: return -EINVAL; } @@ -225,11 +215,9 @@ case WDIOC_SETTIMEOUT: if (copy_from_user(&new_timeout, argp, sizeof(int))) return -EFAULT; - if (new_timeout < 1) + if (rc32434_wdt_set(new_timeout)) return -EINVAL; - if (new_timeout > MAX_TIMEOUT) - return -EINVAL; - rc32434_wdt_set(new_timeout); + /* Fall through */ case WDIOC_GETTIMEOUT: return copy_to_user(argp, &timeout, sizeof(int)); default: @@ -254,15 +242,15 @@ .fops = &rc32434_wdt_fops, }; -static char banner[] = KERN_INFO KBUILD_MODNAME +static char banner[] __devinitdata = KERN_INFO KBUILD_MODNAME ": Watchdog Timer version " VERSION ", timer margin: %d sec\n"; -static int rc32434_wdt_probe(struct platform_device *pdev) +static int __devinit rc32434_wdt_probe(struct platform_device *pdev) { int ret; struct resource *r; - r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rb500_wdt_res"); + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rb532_wdt_res"); if (!r) { printk(KERN_ERR KBUILD_MODNAME "failed to retrieve resources\n"); @@ -277,24 +265,12 @@ } ret = misc_register(&rc32434_wdt_miscdev); - if (ret < 0) { printk(KERN_ERR KBUILD_MODNAME "failed to register watchdog device\n"); goto unmap; } - init_completion(&rc32434_wdt_device.stop); - rc32434_wdt_device.queue = 0; - - clear_bit(0, &rc32434_wdt_device.inuse); - - setup_timer(&rc32434_wdt_device.timer, rc32434_wdt_update, 0L); - - rc32434_wdt_device.default_ticks = ticks; - - rc32434_wdt_start(); - printk(banner, timeout); return 0; @@ -304,23 +280,17 @@ return ret; } -static int rc32434_wdt_remove(struct platform_device *pdev) +static int __devexit rc32434_wdt_remove(struct platform_device *pdev) { - if (rc32434_wdt_device.queue) { - rc32434_wdt_device.queue = 0; - wait_for_completion(&rc32434_wdt_device.stop); - } misc_deregister(&rc32434_wdt_miscdev); - iounmap(wdt_reg); - return 0; } static struct platform_driver rc32434_wdt = { .probe = rc32434_wdt_probe, - .remove = rc32434_wdt_remove, - .driver = { + .remove = __devexit_p(rc32434_wdt_remove), + .driver = { .name = "rc32434_wdt", } }; --- linux-2.6.28.orig/drivers/message/fusion/mptbase.c +++ linux-2.6.28/drivers/message/fusion/mptbase.c @@ -3014,6 +3014,16 @@ pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus); pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo); pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices); + /* + * VMware emulation is broken, its PortFact's MaxDevices reports value + * programmed by IOC Init, so if you program IOC Init to 256 (which is 0, + * as that field is only 8 bit), it reports back 0 in port facts, instead + * of 256... And unfortunately using 256 triggers another bug in the + * code (parallel SCSI can have only 16 devices). + */ + if (pfacts->MaxDevices == 0) { + pfacts->MaxDevices = 16; + } pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID); pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags); pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers); --- linux-2.6.28.orig/drivers/video/Kconfig +++ linux-2.6.28/drivers/video/Kconfig @@ -381,6 +381,10 @@ Say Y to enable the Framebuffer driver for the CLPS7111 and EP7212 processors. +if ARCH_MXC +source "drivers/video/mxc/Kconfig" +endif + config FB_SA1100 bool "SA-1100 LCD support" depends on (FB = y) && ARM && ARCH_SA1100 @@ -684,8 +688,8 @@ If unsure, say N. config FB_VESA - bool "VESA VGA graphics support" - depends on (FB = y) && X86 + tristate "VESA VGA graphics support" + depends on FB && X86 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT --- linux-2.6.28.orig/drivers/video/Makefile +++ linux-2.6.28/drivers/video/Makefile @@ -114,6 +114,7 @@ obj-$(CONFIG_FB_COBALT) += cobalt_lcdfb.o obj-$(CONFIG_FB_PNX4008_DUM) += pnx4008/ obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnx4008/ +obj-$(CONFIG_FB_MXC) += mxc/ obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o obj-$(CONFIG_FB_PS3) += ps3fb.o obj-$(CONFIG_FB_SM501) += sm501fb.o --- linux-2.6.28.orig/drivers/video/vesafb.c +++ linux-2.6.28/drivers/video/vesafb.c @@ -28,6 +28,12 @@ #define dac_reg (0x3c8) #define dac_val (0x3c9) +struct vesafb_info +{ + u32 pseudo_palette[256]; + int mtrr_hdl; +}; + /* --------------------------------------------------------------------- */ static struct fb_var_screeninfo vesafb_defined __initdata = { @@ -47,16 +53,37 @@ .accel = FB_ACCEL_NONE, }; +#ifndef MODULE static int inverse __read_mostly; +#endif static int mtrr __read_mostly; /* disable mtrr */ static int vram_remap __initdata; /* Set amount of memory to be used */ static int vram_total __initdata; /* Set total amount of memory */ static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */ +static int redraw __read_mostly; static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */ +static int ywrap __read_mostly; static void (*pmi_start)(void) __read_mostly; static void (*pmi_pal) (void) __read_mostly; static int depth __read_mostly; static int vga_compat __read_mostly; + +module_param(redraw, bool, 0); +module_param(ypan, bool, 0); +module_param(ywrap, bool, 0); +module_param_named(vgapal, pmi_setpal, invbool, 0); +MODULE_PARM_DESC(vgapal, "Use VGA for setting palette (default)"); +module_param_named(pmipal, pmi_setpal, bool, 0); +MODULE_PARM_DESC(pmipal, "Use PMI for setting palette"); +module_param(mtrr, bool, 0); +MODULE_PARM_DESC(mtrr, "Enable MTRR support (default)"); +module_param_named(nomtrr, mtrr, invbool, 0); +MODULE_PARM_DESC(nomtrr, "Disable MTRR support"); +module_param(vram_remap, int, 0); +MODULE_PARM_DESC(vram_remap, "Set total amount of memory to be used"); +module_param(vram_total, int, 0); +MODULE_PARM_DESC(vram_total, "Total amount of memory"); + /* --------------------------------------------------------------------- */ static int vesafb_pan_display(struct fb_var_screeninfo *var, @@ -183,6 +210,7 @@ .fb_imageblit = cfb_imageblit, }; +#ifndef MODULE static int __init vesafb_setup(char *options) { char *this_opt; @@ -216,6 +244,7 @@ } return 0; } +#endif static int __init vesafb_probe(struct platform_device *dev) { @@ -463,8 +492,28 @@ return err; } +static int __exit vesafb_remove(struct platform_device *device) +{ + struct fb_info *info = dev_get_drvdata(&device->dev); + + unregister_framebuffer(info); +#ifdef CONFIG_MTRR + { + struct vesafb_info *vfb_info = (struct vesafb_info *) info->par; + if (vfb_info->mtrr_hdl >= 0) + mtrr_del(vfb_info->mtrr_hdl, 0, 0); + } +#endif + iounmap(info->screen_base); + framebuffer_release(info); + release_mem_region(vesafb_fix.smem_start, vesafb_fix.smem_len); + + return 0; +} + static struct platform_driver vesafb_driver = { .probe = vesafb_probe, + .remove = vesafb_remove, .driver = { .name = "vesafb", }, @@ -475,11 +524,18 @@ static int __init vesafb_init(void) { int ret; +#ifndef MODULE char *option = NULL; /* ignore error return of fb_get_options */ fb_get_options("vesafb", &option); vesafb_setup(option); +#else + if (redraw) + ypan = 0; + if (ywrap) + ypan = 2; +#endif ret = platform_driver_register(&vesafb_driver); if (!ret) { @@ -498,6 +554,14 @@ return ret; } + +static void __exit vesafb_exit(void) +{ + platform_device_unregister(vesafb_device); + platform_driver_unregister(&vesafb_driver); +} + module_init(vesafb_init); +module_exit(vesafb_exit); MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/video/mxc/mxcfb_ch7026.c +++ linux-2.6.28/drivers/video/mxc/mxcfb_ch7026.c @@ -0,0 +1,349 @@ +/* + * Copyright 2009 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 + */ + +/*! + * @defgroup Framebuffer Framebuffer Driver for SDC and ADC. + */ + +/*! + * @file mxcfb_epson_vga.c + * + * @brief MXC Frame buffer driver for SDC + * + * @ingroup Framebuffer + */ + +/*! + * Include files + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct i2c_client *ch7026_client; + +static void lcd_init(void); +static void lcd_poweron(struct fb_info *info); +static void lcd_poweroff(void); + +static void (*lcd_reset) (void); +static struct regulator *io_reg; +static struct regulator *core_reg; +static struct regulator *analog_reg; + + /* 8 800x600-60 VESA */ +static struct fb_videomode mode = { + NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA +}; + +static void lcd_init_fb(struct fb_info *info) +{ + struct fb_var_screeninfo var; + + memset(&var, 0, sizeof(var)); + + fb_videomode_to_var(&var, &mode); + + var.activate = FB_ACTIVATE_ALL; + + acquire_console_sem(); + info->flags |= FBINFO_MISC_USEREVENT; + fb_set_var(info, &var); + fb_blank(info, FB_BLANK_UNBLANK); + info->flags &= ~FBINFO_MISC_USEREVENT; + release_console_sem(); +} + +static int lcd_fb_event(struct notifier_block *nb, unsigned long val, void *v) +{ + struct fb_event *event = v; + + if (strcmp(event->info->fix.id, "DISP3 BG - DI1")) + return 0; + + switch (val) { + case FB_EVENT_FB_REGISTERED: + lcd_init_fb(event->info); + lcd_poweron(event->info); + break; + case FB_EVENT_BLANK: + if (*((int *)event->data) == FB_BLANK_UNBLANK) + lcd_poweron(event->info); + else + lcd_poweroff(); + break; + } + return 0; +} + +static struct notifier_block nb = { + .notifier_call = lcd_fb_event, +}; + +/*! + * This function is called whenever the SPI slave device is detected. + * + * @param spi the SPI slave device + * + * @return Returns 0 on SUCCESS and error on FAILURE. + */ +static int __devinit lcd_probe(struct device *dev) +{ + int i; + struct mxc_lcd_platform_data *plat = dev->platform_data; + + if (plat) { + + io_reg = regulator_get(dev, plat->io_reg); + if (!IS_ERR(io_reg)) { + regulator_set_voltage(io_reg, 1800000, 1800000); + regulator_enable(io_reg); + } + core_reg = regulator_get(dev, plat->core_reg); + if (!IS_ERR(core_reg)) { + regulator_set_voltage(core_reg, 2500000, 2500000); + regulator_enable(core_reg); + } + analog_reg = regulator_get(dev, plat->analog_reg); + if (!IS_ERR(analog_reg)) { + regulator_set_voltage(analog_reg, 2775000, 2775000); + regulator_enable(analog_reg); + } + msleep(100); + + lcd_reset = plat->reset; + if (lcd_reset) + lcd_reset(); + } + + for (i = 0; i < num_registered_fb; i++) { + if (strcmp(registered_fb[i]->fix.id, "DISP3 BG - DI1") == 0) { + lcd_init_fb(registered_fb[i]); + fb_show_logo(registered_fb[i], 0); + lcd_init(); + lcd_poweron(registered_fb[i]); + } + } + + fb_register_client(&nb); + + return 0; +} + +static int __devinit ch7026_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int id_reg; + ch7026_client = client; + + return lcd_probe(&client->dev); +} + +static int __devexit ch7026_remove(struct i2c_client *client) +{ + fb_unregister_client(&nb); + lcd_poweroff(); + regulator_put(io_reg); + regulator_put(core_reg); + regulator_put(analog_reg); + + return 0; +} + +static int ch7026_suspend(struct i2c_client *client, pm_message_t message) +{ + return 0; +} + +static int ch7026_resume(struct i2c_client *client) +{ + return 0; +} + +u8 reg_init[][2] = { + { 0x02, 0x01 }, + { 0x02, 0x03 }, + { 0x03, 0x00 }, + { 0x06, 0x6B }, + { 0x08, 0x08 }, + { 0x09, 0x80 }, + { 0x0C, 0x0A }, + { 0x0D, 0x89 }, + { 0x0F, 0x23 }, + { 0x10, 0x20 }, + { 0x11, 0x20 }, + { 0x12, 0x40 }, + { 0x13, 0x28 }, + { 0x14, 0x80 }, + { 0x15, 0x52 }, + { 0x16, 0x58 }, + { 0x17, 0x74 }, + { 0x19, 0x01 }, + { 0x1A, 0x04 }, + { 0x1B, 0x23 }, + { 0x1C, 0x20 }, + { 0x1D, 0x20 }, + { 0x1F, 0x28 }, + { 0x20, 0x80 }, + { 0x21, 0x12 }, + { 0x22, 0x58 }, + { 0x23, 0x74 }, + { 0x25, 0x01 }, + { 0x26, 0x04 }, + { 0x37, 0x20 }, + { 0x39, 0x20 }, + { 0x3B, 0x20 }, + { 0x41, 0xA2 }, + { 0x4D, 0x03 }, + { 0x4E, 0x13 }, + { 0x4F, 0xB1 }, + { 0x50, 0x3B }, + { 0x51, 0x54 }, + { 0x52, 0x12 }, + { 0x53, 0x13 }, + { 0x55, 0xE5 }, + { 0x5E, 0x80 }, + { 0x69, 0x64 }, + { 0x7D, 0x62 }, + { 0x04, 0x00 }, + { 0x06, 0x69 }, + + /* + NOTE: The following five repeated sentences are used here to wait memory initial complete, please don't remove...(you could refer to Appendix A of programming guide document (CH7025(26)B Programming Guide Rev2.03.pdf) for detailed information about memory initialization! + */ + { 0x03, 0x00 }, + { 0x03, 0x00 }, + { 0x03, 0x00 }, + { 0x03, 0x00 }, + { 0x03, 0x00 }, + + { 0x06, 0x68 }, + { 0x02, 0x02 }, + { 0x02, 0x03 }, +}; + +#define REGMAP_LENGTH (sizeof(reg_init) / (2*sizeof(u8))) + +/* + * Send init commands to L4F00242T03 + * + */ +static void lcd_init(void) +{ + int i; + int dat; + + dev_dbg(&ch7026_client->dev, "initializing CH7026\n"); + + /* read device ID */ + msleep(100); + dat = i2c_smbus_read_byte_data(ch7026_client, 0x00); + dev_dbg(&ch7026_client->dev, "read id = 0x%02X\n", dat); + if (dat != 0x54) + return; + + for (i = 0; i < REGMAP_LENGTH; ++i) { + if (i2c_smbus_write_byte_data + (ch7026_client, reg_init[i][0], reg_init[i][1]) < 0) + return; + } + +} + +static int lcd_on; +/* + * Send Power On commands to L4F00242T03 + * + */ +static void lcd_poweron(struct fb_info *info) +{ + u16 data[4]; + u32 refresh; + + if (lcd_on) + return; + + dev_dbg(&ch7026_client->dev, "turning on LCD\n"); + + data[0] = PICOS2KHZ(info->var.pixclock) / 10; + data[2] = info->var.hsync_len + info->var.left_margin + + info->var.xres + info->var.right_margin; + data[3] = info->var.vsync_len + info->var.upper_margin + + info->var.yres + info->var.lower_margin; + + refresh = data[2] * data[3]; + refresh = (PICOS2KHZ(info->var.pixclock) * 1000) / refresh; + data[1] = refresh * 100; + + lcd_on = 1; +} + +/* + * Send Power Off commands to L4F00242T03 + * + */ +static void lcd_poweroff(void) +{ + if (!lcd_on) + return; + + dev_dbg(&ch7026_client->dev, "turning off LCD\n"); + + lcd_on = 0; +} + +static const struct i2c_device_id ch7026_id[] = { + {"ch7026", 0}, + {}, +}; + +MODULE_DEVICE_TABLE(i2c, ch7026_id); + +static struct i2c_driver ch7026_driver = { + .driver = { + .name = "ch7026", + }, + .probe = ch7026_probe, + .remove = ch7026_remove, + .suspend = ch7026_suspend, + .resume = ch7026_resume, + .id_table = ch7026_id, +}; + +static int __init ch7026_init(void) +{ + return i2c_add_driver(&ch7026_driver); +} + +static void __exit ch7026_exit(void) +{ + i2c_del_driver(&ch7026_driver); +} + +module_init(ch7026_init); +module_exit(ch7026_exit); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("CH7026 VGA driver"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/video/mxc/Kconfig +++ linux-2.6.28/drivers/video/mxc/Kconfig @@ -0,0 +1,34 @@ +config FB_MXC + tristate "MXC Framebuffer support" + depends on FB && MXC_IPU + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + default y + help + This is a framebuffer device for the MXC LCD Controller. + See for information on framebuffer + devices. + + If you plan to use the LCD display with your MXC system, say + Y here. + +config FB_MXC_SYNC_PANEL + depends on FB_MXC + tristate "Synchronous Panel Framebuffer" + default y + +config FB_MXC_EPSON_VGA_SYNC_PANEL + depends on FB_MXC_SYNC_PANEL + tristate "Epson VGA Panel" + default n + +config FB_MXC_TVOUT_TVE + tristate "MXC TVE TV Out Encoder" + depends on FB_MXC_SYNC_PANEL + depends on MXC_IPU_V3 + +config FB_MXC_CH7026 + depends on FB_MXC_SYNC_PANEL + tristate "Chrontel CH7026 VGA Interface Chip" + --- linux-2.6.28.orig/drivers/video/mxc/mxc_ipuv3_fb.c +++ linux-2.6.28/drivers/video/mxc/mxc_ipuv3_fb.c @@ -0,0 +1,1061 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @defgroup Framebuffer Framebuffer Driver for SDC and ADC. + */ + +/*! + * @file mxcfb.c + * + * @brief MXC Frame buffer driver for SDC + * + * @ingroup Framebuffer + */ + +/*! + * Include files + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Driver name + */ +#define MXCFB_NAME "mxc_sdc_fb" +/*! + * Structure containing the MXC specific framebuffer information. + */ +struct mxcfb_info { + int blank; + ipu_channel_t ipu_ch; + int ipu_di; + u32 ipu_di_pix_fmt; + bool overlay; + uint32_t ipu_ch_irq; + uint32_t cur_ipu_buf; + + u32 pseudo_palette[16]; + + struct semaphore flip_sem; + struct completion vsync_complete; +}; + +struct mxcfb_alloc_list { + struct list_head list; + dma_addr_t phy_addr; + void *cpu_addr; + u32 size; +}; + +static char *fb_mode; +static unsigned long default_bpp = 16; +static bool g_dp_in_use; +LIST_HEAD(fb_alloc_list); + +static uint32_t bpp_to_pixfmt(struct fb_info *fbi) +{ + uint32_t pixfmt = 0; + + if (fbi->var.nonstd) + return fbi->var.nonstd; + + switch (fbi->var.bits_per_pixel) { + case 24: + pixfmt = IPU_PIX_FMT_BGR24; + break; + case 32: + pixfmt = IPU_PIX_FMT_BGR32; + break; + case 16: + pixfmt = IPU_PIX_FMT_RGB565; + break; + } + return pixfmt; +} + +static irqreturn_t mxcfb_irq_handler(int irq, void *dev_id); +static int mxcfb_blank(int blank, struct fb_info *info); +static int mxcfb_map_video_memory(struct fb_info *fbi); +static int mxcfb_unmap_video_memory(struct fb_info *fbi); + +/* + * Set fixed framebuffer parameters based on variable settings. + * + * @param info framebuffer information pointer + */ +static int mxcfb_set_fix(struct fb_info *info) +{ + struct fb_fix_screeninfo *fix = &info->fix; + struct fb_var_screeninfo *var = &info->var; + + fix->line_length = var->xres_virtual * var->bits_per_pixel / 8; + + fix->type = FB_TYPE_PACKED_PIXELS; + fix->accel = FB_ACCEL_NONE; + fix->visual = FB_VISUAL_TRUECOLOR; + fix->xpanstep = 1; + fix->ypanstep = 1; + + return 0; +} + +/* + * Set framebuffer parameters and change the operating mode. + * + * @param info framebuffer information pointer + */ +static int mxcfb_set_par(struct fb_info *fbi) +{ + int retval; + u32 mem_len; + ipu_di_signal_cfg_t sig_cfg; + ipu_channel_params_t params; + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par; + + dev_dbg(fbi->device, "Reconfiguring framebuffer\n"); + + ipu_disable_irq(mxc_fbi->ipu_ch_irq); + ipu_disable_channel(mxc_fbi->ipu_ch, true); + ipu_uninit_channel(mxc_fbi->ipu_ch); + ipu_clear_irq(mxc_fbi->ipu_ch_irq); + mxcfb_set_fix(fbi); + + mem_len = fbi->var.yres_virtual * fbi->fix.line_length; + if (!fbi->fix.smem_start || (mem_len > fbi->fix.smem_len)) { + if (fbi->fix.smem_start) + mxcfb_unmap_video_memory(fbi); + + if (mxcfb_map_video_memory(fbi) < 0) + return -ENOMEM; + } +#ifdef CONFIG_MXC_IPU_V1 + ipu_init_channel(mxc_fbi->ipu_ch, NULL); +#else + memset(¶ms, 0, sizeof(params)); + params.mem_dp_bg_sync.di = mxc_fbi->ipu_di; + + /* Assuming interlaced means YUV output */ + if (fbi->var.vmode & FB_VMODE_INTERLACED) { + params.mem_dp_bg_sync.interlaced = true; + params.mem_dp_bg_sync.out_pixel_fmt = IPU_PIX_FMT_YUV444; + } else { + if (mxc_fbi->ipu_di_pix_fmt) + params.mem_dp_bg_sync.out_pixel_fmt = mxc_fbi->ipu_di_pix_fmt; + else + params.mem_dp_bg_sync.out_pixel_fmt = IPU_PIX_FMT_RGB666; + } + params.mem_dp_bg_sync.in_pixel_fmt = bpp_to_pixfmt(fbi); + ipu_init_channel(mxc_fbi->ipu_ch, ¶ms); +#endif + + if (!mxc_fbi->overlay) { + memset(&sig_cfg, 0, sizeof(sig_cfg)); + if (fbi->var.vmode & FB_VMODE_INTERLACED) + sig_cfg.interlaced = true; + if (fbi->var.vmode & FB_VMODE_ODD_FLD_FIRST) /* PAL */ + sig_cfg.odd_field_first = true; + if (fbi->var.sync & FB_SYNC_EXT) + sig_cfg.ext_clk = true; + if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT) + sig_cfg.Hsync_pol = true; + if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT) + sig_cfg.Vsync_pol = true; + if (!(fbi->var.sync & FB_SYNC_CLK_LAT_FALL)) + sig_cfg.clk_pol = true; + if (fbi->var.sync & FB_SYNC_DATA_INVERT) + sig_cfg.data_pol = true; + if (!(fbi->var.sync & FB_SYNC_OE_LOW_ACT)) + sig_cfg.enable_pol = true; + if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN) + sig_cfg.clkidle_en = true; + + dev_dbg(fbi->device, "pixclock = %ul Hz\n", + (u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL)); + +#ifdef CONFIG_MXC_IPU_V1 + if (ipu_sdc_init_panel(mode, + (PICOS2KHZ(fbi->var.pixclock)) * 1000UL, + fbi->var.xres, fbi->var.yres, + (fbi->var.sync & FB_SYNC_SWAP_RGB) ? + IPU_PIX_FMT_BGR666 : IPU_PIX_FMT_RGB666, + fbi->var.left_margin, + fbi->var.hsync_len, + fbi->var.right_margin, + fbi->var.upper_margin, + fbi->var.vsync_len, + fbi->var.lower_margin, sig_cfg) != 0) { +#else + if (ipu_init_sync_panel(mxc_fbi->ipu_di, + (PICOS2KHZ(fbi->var.pixclock)) * 1000UL, + fbi->var.xres, fbi->var.yres, + params.mem_dp_bg_sync.out_pixel_fmt, + fbi->var.left_margin, + fbi->var.hsync_len, + fbi->var.right_margin, + fbi->var.upper_margin, + fbi->var.vsync_len, + fbi->var.lower_margin, + 480, sig_cfg) != 0) { +#endif + dev_err(fbi->device, + "mxcfb: Error initializing panel.\n"); + return -EINVAL; + } + + fbi->mode = + (struct fb_videomode *)fb_match_mode(&fbi->var, + &fbi->modelist); + ipu_disp_set_window_pos(mxc_fbi->ipu_ch, 0, 0); + } + + mxc_fbi->cur_ipu_buf = 1; + sema_init(&mxc_fbi->flip_sem, 1); + fbi->var.xoffset = fbi->var.yoffset = 0; + + retval = ipu_init_channel_buffer(mxc_fbi->ipu_ch, IPU_INPUT_BUFFER, + bpp_to_pixfmt(fbi), + fbi->var.xres, fbi->var.yres, + fbi->fix.line_length, + IPU_ROTATE_NONE, + fbi->fix.smem_start + + (fbi->fix.line_length * fbi->var.yres), + fbi->fix.smem_start, + 0, 0); + if (retval) { + dev_err(fbi->device, + "ipu_init_channel_buffer error %d\n", retval); + return retval; + } + + if (mxc_fbi->blank == FB_BLANK_UNBLANK) { + ipu_enable_channel(mxc_fbi->ipu_ch); + } + + return 0; +} + +/* + * Check framebuffer variable parameters and adjust to valid values. + * + * @param var framebuffer variable parameters + * + * @param info framebuffer information pointer + */ +static int mxcfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) +{ + u32 vtotal; + u32 htotal; + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)info->par; + + if (var->xres_virtual < var->xres) + var->xres_virtual = var->xres; + if (var->yres_virtual < var->yres) + var->yres_virtual = var->yres; + + if ((var->bits_per_pixel != 32) && (var->bits_per_pixel != 24) && + (var->bits_per_pixel != 16)) + var->bits_per_pixel = default_bpp; + + switch (var->bits_per_pixel) { + case 16: + var->red.length = 5; + var->red.offset = 11; + var->red.msb_right = 0; + + var->green.length = 6; + var->green.offset = 5; + var->green.msb_right = 0; + + var->blue.length = 5; + var->blue.offset = 0; + var->blue.msb_right = 0; + + var->transp.length = 0; + var->transp.offset = 0; + var->transp.msb_right = 0; + break; + case 24: + var->red.length = 8; + var->red.offset = 16; + var->red.msb_right = 0; + + var->green.length = 8; + var->green.offset = 8; + var->green.msb_right = 0; + + var->blue.length = 8; + var->blue.offset = 0; + var->blue.msb_right = 0; + + var->transp.length = 0; + var->transp.offset = 0; + var->transp.msb_right = 0; + break; + case 32: + var->red.length = 8; + var->red.offset = 16; + var->red.msb_right = 0; + + var->green.length = 8; + var->green.offset = 8; + var->green.msb_right = 0; + + var->blue.length = 8; + var->blue.offset = 0; + var->blue.msb_right = 0; + + var->transp.length = 8; + var->transp.offset = 24; + var->transp.msb_right = 0; + break; + } + + if (var->pixclock < 1000) { + htotal = var->xres + var->right_margin + var->hsync_len + + var->left_margin; + vtotal = var->yres + var->lower_margin + var->vsync_len + + var->upper_margin; + var->pixclock = (vtotal * htotal * 6UL) / 100UL; + var->pixclock = KHZ2PICOS(var->pixclock); + dev_dbg(info->device, + "pixclock set for 60Hz refresh = %u ps\n", + var->pixclock); + } + + var->height = -1; + var->width = -1; + var->grayscale = 0; + + return 0; +} + +static inline u_int _chan_to_field(u_int chan, struct fb_bitfield *bf) +{ + chan &= 0xffff; + chan >>= 16 - bf->length; + return chan << bf->offset; +} + +static int mxcfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, + u_int trans, struct fb_info *fbi) +{ + unsigned int val; + int ret = 1; + + /* + * If greyscale is true, then we convert the RGB value + * to greyscale no matter what visual we are using. + */ + if (fbi->var.grayscale) + red = green = blue = (19595 * red + 38470 * green + + 7471 * blue) >> 16; + switch (fbi->fix.visual) { + case FB_VISUAL_TRUECOLOR: + /* + * 16-bit True Colour. We encode the RGB value + * according to the RGB bitfield information. + */ + if (regno < 16) { + u32 *pal = fbi->pseudo_palette; + + val = _chan_to_field(red, &fbi->var.red); + val |= _chan_to_field(green, &fbi->var.green); + val |= _chan_to_field(blue, &fbi->var.blue); + + pal[regno] = val; + ret = 0; + } + break; + + case FB_VISUAL_STATIC_PSEUDOCOLOR: + case FB_VISUAL_PSEUDOCOLOR: + break; + } + + return ret; +} + +/* + * Function to handle custom ioctls for MXC framebuffer. + * + * @param inode inode struct + * + * @param file file struct + * + * @param cmd Ioctl command to handle + * + * @param arg User pointer to command arguments + * + * @param fbi framebuffer information pointer + */ +static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) +{ + int retval = 0; + int __user *argp = (void __user *)arg; + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par; + + switch (cmd) { + case MXCFB_SET_GBL_ALPHA: + { + struct mxcfb_gbl_alpha ga; + if (copy_from_user(&ga, (void *)arg, sizeof(ga))) { + retval = -EFAULT; + break; + } + retval = + ipu_disp_set_global_alpha(MEM_BG_SYNC, + (bool) ga.enable, + ga.alpha); + dev_dbg(fbi->device, "Set global alpha to %d\n", + ga.alpha); + break; + } + case MXCFB_SET_CLR_KEY: + { + struct mxcfb_color_key key; + if (copy_from_user(&key, (void *)arg, sizeof(key))) { + retval = -EFAULT; + break; + } + retval = ipu_disp_set_color_key(MEM_BG_SYNC, key.enable, + key.color_key); + dev_dbg(fbi->device, "Set color key to 0x%08X\n", + key.color_key); + break; + } + case MXCFB_WAIT_FOR_VSYNC: + { + if (mxc_fbi->blank != FB_BLANK_UNBLANK) + break; + + down(&mxc_fbi->flip_sem); + init_completion(&mxc_fbi->vsync_complete); + + ipu_clear_irq(mxc_fbi->ipu_ch_irq); + ipu_enable_irq(mxc_fbi->ipu_ch_irq); + retval = wait_for_completion_interruptible_timeout( + &mxc_fbi->vsync_complete, 1 * HZ); + if (retval == 0) { + dev_err(fbi->device, + "MXCFB_WAIT_FOR_VSYNC: timeout %d\n", + retval); + retval = -ETIME; + } else if (retval > 0) { + retval = 0; + } + break; + } + case FBIO_ALLOC: + { + int size; + struct mxcfb_alloc_list *mem; + + mem = kzalloc(sizeof(*mem), GFP_KERNEL); + if (mem == NULL) + return -ENOMEM; + + if (get_user(size, argp)) + return -EFAULT; + + mem->size = PAGE_ALIGN(size); + + mem->cpu_addr = dma_alloc_coherent(fbi->device, size, + &mem->phy_addr, + GFP_DMA); + if (mem->cpu_addr == NULL) { + kfree(mem); + return -ENOMEM; + } + + list_add(&mem->list, &fb_alloc_list); + + dev_dbg(fbi->device, "allocated %d bytes @ 0x%08X\n", + mem->size, mem->phy_addr); + + if (put_user(mem->phy_addr, argp)) + return -EFAULT; + + break; + } + case FBIO_FREE: + { + unsigned long offset; + struct mxcfb_alloc_list *mem; + + if (get_user(offset, argp)) + return -EFAULT; + + retval = -EINVAL; + list_for_each_entry(mem, &fb_alloc_list, list) { + if (mem->phy_addr == offset) { + list_del(&mem->list); + dma_free_coherent(fbi->device, + mem->size, + mem->cpu_addr, + mem->phy_addr); + kfree(mem); + retval = 0; + break; + } + } + + break; + } + case MXCFB_SET_OVERLAY_POS: + { + struct mxcfb_pos pos; + if (copy_from_user(&pos, (void *)arg, sizeof(pos))) { + retval = -EFAULT; + break; + } + retval = ipu_disp_set_window_pos(mxc_fbi->ipu_ch, + pos.x, pos.y); + break; + } + default: + retval = -EINVAL; + } + return retval; +} + +/* + * mxcfb_blank(): + * Blank the display. + */ +static int mxcfb_blank(int blank, struct fb_info *info) +{ + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)info->par; + + dev_dbg(info->device, "blank = %d\n", blank); + + if (mxc_fbi->blank == blank) + return 0; + + mxc_fbi->blank = blank; + + switch (blank) { + case FB_BLANK_POWERDOWN: + case FB_BLANK_VSYNC_SUSPEND: + case FB_BLANK_HSYNC_SUSPEND: + case FB_BLANK_NORMAL: + ipu_disable_channel(mxc_fbi->ipu_ch, true); + ipu_uninit_channel(mxc_fbi->ipu_ch); + break; + case FB_BLANK_UNBLANK: + mxcfb_set_par(info); + break; + } + return 0; +} + +/* + * Pan or Wrap the Display + * + * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag + * + * @param var Variable screen buffer information + * @param info Framebuffer information pointer + */ +static int +mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) +{ + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)info->par; + u_int y_bottom; + unsigned long base; + + if (var->xoffset > 0) { + dev_dbg(info->device, "x panning not supported\n"); + return -EINVAL; + } + + if ((info->var.xoffset == var->xoffset) && + (info->var.yoffset == var->yoffset)) + return 0; /* No change, do nothing */ + + y_bottom = var->yoffset; + + if (!(var->vmode & FB_VMODE_YWRAP)) + y_bottom += var->yres; + + if (y_bottom > info->var.yres_virtual) + return -EINVAL; + + base = (var->yoffset * var->xres_virtual + var->xoffset); + base *= (var->bits_per_pixel) / 8; + base += info->fix.smem_start; + + dev_dbg(info->device, "Updating SDC BG buf %d address=0x%08lX\n", + mxc_fbi->cur_ipu_buf, base); + + down(&mxc_fbi->flip_sem); + init_completion(&mxc_fbi->vsync_complete); + + mxc_fbi->cur_ipu_buf = !mxc_fbi->cur_ipu_buf; + if (ipu_update_channel_buffer(mxc_fbi->ipu_ch, IPU_INPUT_BUFFER, + mxc_fbi->cur_ipu_buf, base) == 0) { + ipu_select_buffer(mxc_fbi->ipu_ch, IPU_INPUT_BUFFER, + mxc_fbi->cur_ipu_buf); + ipu_clear_irq(mxc_fbi->ipu_ch_irq); + ipu_enable_irq(mxc_fbi->ipu_ch_irq); + } else { + dev_err(info->device, + "Error updating SDC buf %d to address=0x%08lX\n", + mxc_fbi->cur_ipu_buf, base); + } + + dev_dbg(info->device, "Update complete\n"); + + info->var.xoffset = var->xoffset; + info->var.yoffset = var->yoffset; + + if (var->vmode & FB_VMODE_YWRAP) + info->var.vmode |= FB_VMODE_YWRAP; + else + info->var.vmode &= ~FB_VMODE_YWRAP; + + return 0; +} + +/* + * Function to handle custom mmap for MXC framebuffer. + * + * @param fbi framebuffer information pointer + * + * @param vma Pointer to vm_area_struct + */ +static int mxcfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma) +{ + bool found = false; + u32 len; + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + struct mxcfb_alloc_list *mem; + + if (offset < fbi->fix.smem_len) { + /* mapping framebuffer memory */ + len = fbi->fix.smem_len - offset; + vma->vm_pgoff = (fbi->fix.smem_start + offset) >> PAGE_SHIFT; + } else { + list_for_each_entry(mem, &fb_alloc_list, list) { + if (offset == mem->phy_addr) { + found = true; + len = mem->size; + break; + } + } + if (!found) + return -EINVAL; + } + + len = PAGE_ALIGN(len); + if (vma->vm_end - vma->vm_start > len) + return -EINVAL; + + /* make buffers bufferable */ + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + + vma->vm_flags |= VM_IO | VM_RESERVED; + + if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, + vma->vm_end - vma->vm_start, vma->vm_page_prot)) { + dev_dbg(fbi->device, "mmap remap_pfn_range failed\n"); + return -ENOBUFS; + } + + return 0; +} + +/*! + * This structure contains the pointers to the control functions that are + * invoked by the core framebuffer driver to perform operations like + * blitting, rectangle filling, copy regions and cursor definition. + */ +static struct fb_ops mxcfb_ops = { + .owner = THIS_MODULE, + .fb_set_par = mxcfb_set_par, + .fb_check_var = mxcfb_check_var, + .fb_setcolreg = mxcfb_setcolreg, + .fb_pan_display = mxcfb_pan_display, + .fb_ioctl = mxcfb_ioctl, + .fb_mmap = mxcfb_mmap, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, + .fb_blank = mxcfb_blank, +}; + +static irqreturn_t mxcfb_irq_handler(int irq, void *dev_id) +{ + struct fb_info *fbi = dev_id; + struct mxcfb_info *mxc_fbi = fbi->par; + + complete(&mxc_fbi->vsync_complete); + up(&mxc_fbi->flip_sem); + ipu_disable_irq(irq); + return IRQ_HANDLED; +} + +/* + * Suspends the framebuffer and blanks the screen. Power management support + */ +static int mxcfb_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct fb_info *fbi = platform_get_drvdata(pdev); + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par; + int saved_blank; +#ifdef CONFIG_FB_MXC_LOW_PWR_DISPLAY + void *fbmem; +#endif + + acquire_console_sem(); + fb_set_suspend(fbi, 1); + saved_blank = mxc_fbi->blank; + mxcfb_blank(FB_BLANK_POWERDOWN, fbi); + mxc_fbi->blank = saved_blank; + release_console_sem(); + + return 0; +} + +/* + * Resumes the framebuffer and unblanks the screen. Power management support + */ +static int mxcfb_resume(struct platform_device *pdev) +{ + struct fb_info *fbi = platform_get_drvdata(pdev); + struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par; + int saved_blank; + + acquire_console_sem(); + saved_blank = mxc_fbi->blank; + mxc_fbi->blank = FB_BLANK_POWERDOWN; + mxcfb_blank(saved_blank, fbi); + fb_set_suspend(fbi, 0); + release_console_sem(); + + return 0; +} + +/* + * Main framebuffer functions + */ + +/*! + * Allocates the DRAM memory for the frame buffer. This buffer is remapped + * into a non-cached, non-buffered, memory region to allow palette and pixel + * writes to occur without flushing the cache. Once this area is remapped, + * all virtual memory access to the video memory should occur at the new region. + * + * @param fbi framebuffer information pointer + * + * @return Error code indicating success or failure + */ +static int mxcfb_map_video_memory(struct fb_info *fbi) +{ + if (fbi->fix.smem_len < fbi->var.yres_virtual * fbi->fix.line_length) + fbi->fix.smem_len = fbi->var.yres_virtual * + fbi->fix.line_length; + + fbi->screen_base = dma_alloc_writecombine(fbi->device, + fbi->fix.smem_len, + (dma_addr_t *)&fbi->fix.smem_start, + GFP_DMA); + if (fbi->screen_base == 0) { + dev_err(fbi->device, "Unable to allocate framebuffer memory\n"); + fbi->fix.smem_len = 0; + fbi->fix.smem_start = 0; + return -EBUSY; + } + + dev_dbg(fbi->device, "allocated fb @ paddr=0x%08X, size=%d.\n", + (uint32_t) fbi->fix.smem_start, fbi->fix.smem_len); + + fbi->screen_size = fbi->fix.smem_len; + + /* Clear the screen */ + memset((char *)fbi->screen_base, 0, fbi->fix.smem_len); + + return 0; +} + +/*! + * De-allocates the DRAM memory for the frame buffer. + * + * @param fbi framebuffer information pointer + * + * @return Error code indicating success or failure + */ +static int mxcfb_unmap_video_memory(struct fb_info *fbi) +{ + dma_free_writecombine(fbi->device, fbi->fix.smem_len, + fbi->screen_base, fbi->fix.smem_start); + fbi->screen_base = 0; + fbi->fix.smem_start = 0; + fbi->fix.smem_len = 0; + return 0; +} + +/*! + * Initializes the framebuffer information pointer. After allocating + * sufficient memory for the framebuffer structure, the fields are + * filled with custom information passed in from the configurable + * structures. This includes information such as bits per pixel, + * color maps, screen width/height and RGBA offsets. + * + * @return Framebuffer structure initialized with our information + */ +static struct fb_info *mxcfb_init_fbinfo(struct device *dev, struct fb_ops *ops) +{ + struct fb_info *fbi; + struct mxcfb_info *mxcfbi; + + /* + * Allocate sufficient memory for the fb structure + */ + fbi = framebuffer_alloc(sizeof(struct mxcfb_info), dev); + if (!fbi) + return NULL; + + mxcfbi = (struct mxcfb_info *)fbi->par; + + fbi->var.activate = FB_ACTIVATE_NOW; + + fbi->fbops = ops; + fbi->flags = FBINFO_FLAG_DEFAULT; + fbi->pseudo_palette = mxcfbi->pseudo_palette; + + /* + * Allocate colormap + */ + fb_alloc_cmap(&fbi->cmap, 16, 0); + + return fbi; +} + +/*! + * Probe routine for the framebuffer driver. It is called during the + * driver binding process. The following functions are performed in + * this routine: Framebuffer initialization, Memory allocation and + * mapping, Framebuffer registration, IPU initialization. + * + * @return Appropriate error code to the kernel common code + */ +static int mxcfb_probe(struct platform_device *pdev) +{ + struct fb_info *fbi; + struct mxcfb_info *mxcfbi; + struct mxc_fb_platform_data *plat_data = pdev->dev.platform_data; + struct resource *res; + int ret = 0; + + /* + * Initialize FB structures + */ + fbi = mxcfb_init_fbinfo(&pdev->dev, &mxcfb_ops); + if (!fbi) { + ret = -ENOMEM; + goto err0; + } + mxcfbi = (struct mxcfb_info *)fbi->par; + + if (pdev->id == 0) { + mxcfbi->ipu_ch_irq = IPU_IRQ_BG_SYNC_EOF; + mxcfbi->ipu_ch = MEM_BG_SYNC; + mxcfbi->ipu_di = pdev->id; + ipu_disp_set_global_alpha(MEM_BG_SYNC, true, 0x80); + ipu_disp_set_color_key(MEM_BG_SYNC, false, 0); + mxcfbi->blank = FB_BLANK_UNBLANK; + + strcpy(fbi->fix.id, "DISP3 BG"); + g_dp_in_use = true; + } else if (pdev->id == 1) { + if (!g_dp_in_use) { + mxcfbi->ipu_ch_irq = IPU_IRQ_BG_SYNC_EOF; + mxcfbi->ipu_ch = MEM_BG_SYNC; + } else { + mxcfbi->ipu_ch_irq = IPU_IRQ_DC_SYNC_EOF; + mxcfbi->ipu_ch = MEM_DC_SYNC; + fbi->var.nonstd = IPU_PIX_FMT_UYVY; + } + mxcfbi->ipu_di = pdev->id; + mxcfbi->blank = FB_BLANK_POWERDOWN; + + strcpy(fbi->fix.id, "DISP3 BG - DI1"); + } else if (pdev->id == 2) { /* Overlay */ + mxcfbi->ipu_ch_irq = IPU_IRQ_FG_SYNC_EOF; + mxcfbi->ipu_ch = MEM_FG_SYNC; + mxcfbi->ipu_di = -1; + mxcfbi->overlay = true; + mxcfbi->blank = FB_BLANK_POWERDOWN; + + strcpy(fbi->fix.id, "DISP3 FG"); + } + + if (ipu_request_irq(mxcfbi->ipu_ch_irq, mxcfb_irq_handler, 0, + MXCFB_NAME, fbi) != 0) { + dev_err(&pdev->dev, "Error registering BG irq handler.\n"); + ret = -EBUSY; + goto err1; + } + ipu_disable_irq(mxcfbi->ipu_ch_irq); + + /* Default Y virtual size is 2x panel size */ + fbi->var.yres_virtual = fbi->var.yres * 2; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res) { + fbi->fix.smem_len = res->end - res->start + 1; + fbi->fix.smem_start = res->start; + fbi->screen_base = ioremap(fbi->fix.smem_start, fbi->fix.smem_len); + } + + /* Need dummy values until real panel is configured */ + fbi->var.xres = 240; + fbi->var.yres = 320; + + if (plat_data) { + mxcfbi->ipu_di_pix_fmt = plat_data->interface_pix_fmt; + if (plat_data->mode) + fb_videomode_to_var(&fbi->var, plat_data->mode); + } + + mxcfb_check_var(&fbi->var, fbi); + mxcfb_set_fix(fbi); + + ret = register_framebuffer(fbi); + if (ret < 0) + goto err2; + + platform_set_drvdata(pdev, fbi); + + dev_err(&pdev->dev, "fb registered, using mode %s\n", fb_mode); + return 0; + +err2: + ipu_free_irq(mxcfbi->ipu_ch_irq, fbi); +err1: + fb_dealloc_cmap(&fbi->cmap); + framebuffer_release(fbi); +err0: + return ret; +} + +static int mxcfb_remove(struct platform_device *pdev) +{ + struct fb_info *fbi = platform_get_drvdata(pdev); + struct mxcfb_info *mxc_fbi = fbi->par; + + if (!fbi) + return 0; + + mxcfb_blank(FB_BLANK_POWERDOWN, fbi); + ipu_free_irq(mxc_fbi->ipu_ch_irq, fbi); + mxcfb_unmap_video_memory(fbi); + + if (&fbi->cmap) + fb_dealloc_cmap(&fbi->cmap); + + unregister_framebuffer(fbi); + framebuffer_release(fbi); + return 0; +} + +/*! + * This structure contains pointers to the power management callback functions. + */ +static struct platform_driver mxcfb_driver = { + .driver = { + .name = MXCFB_NAME, + }, + .probe = mxcfb_probe, + .remove = mxcfb_remove, + .suspend = mxcfb_suspend, + .resume = mxcfb_resume, +}; + +/* + * Parse user specified options (`video=trident:') + * example: + * video=trident:800x600,bpp=16,noaccel + */ +int mxcfb_setup(char *options) +{ + char *opt; + if (!options || !*options) + return 0; + while ((opt = strsep(&options, ",")) != NULL) { + if (!*opt) + continue; + if (!strncmp(opt, "bpp=", 4)) + default_bpp = simple_strtoul(opt + 4, NULL, 0); + else + fb_mode = opt; + } + return 0; +} + +/*! + * Main entry function for the framebuffer. The function registers the power + * management callback functions with the kernel and also registers the MXCFB + * callback functions with the core Linux framebuffer driver \b fbmem.c + * + * @return Error code indicating success or failure + */ +int __init mxcfb_init(void) +{ + int ret = 0; +#ifndef MODULE + char *option = NULL; +#endif + +#ifndef MODULE + if (fb_get_options("mxcfb", &option)) + return -ENODEV; + mxcfb_setup(option); +#endif + + ret = platform_driver_register(&mxcfb_driver); + return ret; +} + +void mxcfb_exit(void) +{ + platform_driver_unregister(&mxcfb_driver); +} + +module_init(mxcfb_init); +module_exit(mxcfb_exit); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("MXC framebuffer driver"); +MODULE_LICENSE("GPL"); +MODULE_SUPPORTED_DEVICE("fb"); --- linux-2.6.28.orig/drivers/video/mxc/tve.c +++ linux-2.6.28/drivers/video/mxc/tve.c @@ -0,0 +1,464 @@ +/* + * Copyright 2008-2009 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 + */ + +/*! + * @file tve.c + * @brief Driver for i.MX TV encoder + * + * @ingroup Framebuffer + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TVE_COM_CONF_REG 0 +#define TVE_CD_CONT_REG 0x14 +#define TVE_INT_CONT_REG 0x28 +#define TVE_STAT_REG 0x2C +#define TVE_MV_CONT_REG 0x48 + +#define CD_EN 0x00000001 +#define CD_TRIG_MODE 0x00000002 + +#define CD_LM_INT 0x00000001 +#define CD_SM_INT 0x00000002 +#define CD_MON_END_INT 0x00000004 +#define CD_MAN_TRIG 0x00010000 + +#define TVOUT_FMT_OFF 0 +#define TVOUT_FMT_NTSC 1 +#define TVOUT_FMT_PAL 2 + +static int enabled; /* enable power on or not */ + +static struct fb_info *tve_fbi; + +struct tve_data { + struct platform_device *pdev; + int cur_mode; + int detect; + void *base; + int irq; + struct clk *clk; + struct regulator *dac_reg; + struct regulator *dig_reg; +} tve; + +static struct fb_videomode video_modes[] = { + { + /* NTSC TV output */ + "TV-NTSC", 60, 720, 480, 74074, + 121, 16, + 17, 5, + 1, 1, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_EXT, + FB_VMODE_INTERLACED, + 0,}, + { + /* PAL TV output */ + "TV-PAL", 50, 720, 576, 74074, + 131, 12, + 21, 3, + 1, 1, + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | FB_SYNC_EXT, + FB_VMODE_INTERLACED | FB_VMODE_ODD_FLD_FIRST, + 0,}, +}; + +/** + * tve_setup + * initial the CH7024 chipset by setting register + * @param: + * vos: output video format + * @return: + * 0 successful + * otherwise failed + */ +static int tve_setup(int mode) +{ + if (tve.cur_mode == mode) + return 0; + + tve.cur_mode = mode; + + if (!enabled) + clk_enable(tve.clk); + + /* select output video format */ + if (mode == TVOUT_FMT_PAL) { + __raw_writel(0x00840328, tve.base + TVE_COM_CONF_REG); + pr_debug("TVE: change to PAL video\n"); + } else if (mode == TVOUT_FMT_NTSC) { + __raw_writel(0x00840028, tve.base + TVE_COM_CONF_REG); + pr_debug("TVE: change to NTSC video\n"); + } else if (mode == TVOUT_FMT_OFF) { + __raw_writel(0x0, tve.base + TVE_COM_CONF_REG); + } else { + pr_debug("TVE: no such video format.\n"); + if (!enabled) + clk_disable(tve.clk); + return -EINVAL; + } + + if (!enabled) + clk_disable(tve.clk); + + return 0; +} + +/** + * tve_enable + * Enable the tve Power to begin TV encoder + */ +static void tve_enable(void) +{ + u32 reg; + + if (!enabled) { + enabled = 1; + clk_enable(tve.clk); + reg = __raw_readl(tve.base + TVE_COM_CONF_REG); + __raw_writel(reg | 0x09, tve.base + TVE_COM_CONF_REG); + pr_debug("TVE power on.\n"); + } +} + +/** + * tve_disable + * Disable the tve Power to stop TV encoder + */ +static void tve_disable(void) +{ + u32 reg; + + if (enabled) { + enabled = 0; + reg = __raw_readl(tve.base + TVE_COM_CONF_REG); + __raw_writel(reg & ~0x09, tve.base + TVE_COM_CONF_REG); + clk_disable(tve.clk); + pr_debug("TVE power off.\n"); + } +} + +static int tve_update_detect_status(void) +{ + int old_detect = tve.detect; + u32 stat = __raw_readl(tve.base + TVE_STAT_REG); + + if ((stat & CD_MON_END_INT) == 0) + return tve.detect; + + if (stat & CD_LM_INT) { + if (stat & CD_SM_INT) + tve.detect = 2; + else + tve.detect = 1; + } else { + tve.detect = 0; + } + + __raw_writel(CD_SM_INT | CD_LM_INT | CD_MON_END_INT, + tve.base + TVE_STAT_REG); + + if (old_detect != tve.detect) + sysfs_notify(&tve.pdev->dev.kobj, NULL, "headphone"); + + dev_dbg(&tve.pdev->dev, "detect = %d\n", tve.detect); + return tve.detect; +} + +static int tve_man_detect(void) +{ + u32 cd_cont; + u32 int_cont; + + if (!enabled) + return -1; + + int_cont = __raw_readl(tve.base + TVE_INT_CONT_REG); + __raw_writel(int_cont & ~(CD_SM_INT | CD_LM_INT), + tve.base + TVE_INT_CONT_REG); + + cd_cont = __raw_readl(tve.base + TVE_CD_CONT_REG); + __raw_writel(cd_cont | CD_TRIG_MODE, tve.base + TVE_CD_CONT_REG); + + __raw_writel(CD_SM_INT | CD_LM_INT | CD_MON_END_INT | CD_MAN_TRIG, + tve.base + TVE_STAT_REG); + + while ((__raw_readl(tve.base + TVE_STAT_REG) & CD_MON_END_INT) == 0) + msleep(5); + + tve_update_detect_status(); + + __raw_writel(cd_cont, tve.base + TVE_CD_CONT_REG); + __raw_writel(int_cont, tve.base + TVE_INT_CONT_REG); + + return tve.detect; +} + +static irqreturn_t tve_detect_handler(int irq, void *data) +{ + u32 stat; + int old_detect = tve.detect; + + stat = __raw_readl(tve.base + TVE_STAT_REG); + stat &= __raw_readl(tve.base + TVE_INT_CONT_REG); + + tve_update_detect_status(); + + __raw_writel(stat | CD_MON_END_INT, tve.base + TVE_STAT_REG); + + if (old_detect != tve.detect) + sysfs_notify(&tve.pdev->dev.kobj, NULL, "headphone"); + + return IRQ_HANDLED; +} + +int tve_fb_event(struct notifier_block *nb, unsigned long val, void *v) +{ + struct fb_event *event = v; + struct fb_info *fbi = event->info; + + switch (val) { + case FB_EVENT_FB_REGISTERED: + pr_debug("fb registered event\n"); + if ((tve_fbi != NULL) || strcmp(fbi->fix.id, "DISP3 BG - DI1")) + break; + + tve_fbi = fbi; + fb_add_videomode(&video_modes[0], &tve_fbi->modelist); + fb_add_videomode(&video_modes[1], &tve_fbi->modelist); + break; + case FB_EVENT_MODE_CHANGE: + if (tve_fbi != fbi) + break; + + if (!fbi->mode) { + tve_disable(); + tve.cur_mode = TVOUT_FMT_OFF; + return 0; + } + + pr_debug("fb mode change event: xres=%d, yres=%d\n", + fbi->mode->xres, fbi->mode->yres); + + tve_disable(); + + if (fb_mode_is_equal(fbi->mode, &video_modes[0])) { + tve_setup(TVOUT_FMT_NTSC); + tve_enable(); + } else if (fb_mode_is_equal(fbi->mode, &video_modes[1])) { + tve_setup(TVOUT_FMT_PAL); + tve_enable(); + } else { + tve_setup(TVOUT_FMT_OFF); + } + break; + case FB_EVENT_BLANK: + if ((tve_fbi != fbi) || (tve.cur_mode == TVOUT_FMT_OFF)) + return 0; + + if (*((int *)event->data) == FB_BLANK_UNBLANK) + tve_enable(); + else + tve_disable(); + break; + } + return 0; +} + +static struct notifier_block nb = { + .notifier_call = tve_fb_event, +}; + +static ssize_t show_headphone(struct device_driver *dev, char *buf) +{ + int detect; + + if (!enabled) { + strcpy(buf, "tve power off\n"); + return strlen(buf); + } + + detect = tve_update_detect_status(); + + if (detect == 0) + strcpy(buf, "none\n"); + else if (detect == 1) + strcpy(buf, "cvbs\n"); + else + strcpy(buf, "headset\n"); + + return strlen(buf); +} + +static DRIVER_ATTR(headphone, 0644, show_headphone, NULL); + +static int tve_probe(struct platform_device *pdev) +{ + int ret, i; + struct resource *res; + struct tve_platform_data *plat_data = pdev->dev.platform_data; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) + return -ENOMEM; + + tve.pdev = pdev; + tve.base = ioremap(res->start, res->end - res->start); + + tve.irq = platform_get_irq(pdev, 0); + if (tve.irq < 0) { + ret = tve.irq; + goto err0; + } + + ret = request_irq(tve.irq, tve_detect_handler, 0, pdev->name, pdev); + if (ret < 0) + goto err0; + + ret = driver_create_file(pdev->dev.driver, &driver_attr_headphone); + if (ret < 0) + goto err1; + + for (i = 0; i < num_registered_fb; i++) { + if (strcmp(registered_fb[i]->fix.id, "DISP3 BG - DI1") == 0) { + tve_fbi = registered_fb[i]; + break; + } + } + if (tve_fbi != NULL) { + fb_add_videomode(&video_modes[0], &tve_fbi->modelist); + fb_add_videomode(&video_modes[1], &tve_fbi->modelist); + } + + tve.dac_reg = regulator_get(&pdev->dev, plat_data->dac_reg); + if (!IS_ERR(tve.dac_reg)) { + regulator_set_voltage(tve.dac_reg, 2500000, 2500000); + regulator_enable(tve.dac_reg); + } + + tve.dig_reg = regulator_get(&pdev->dev, plat_data->dig_reg); + if (!IS_ERR(tve.dig_reg)) { + regulator_set_voltage(tve.dig_reg, 1250000, 1250000); + regulator_enable(tve.dig_reg); + } + + tve.clk = clk_get(&pdev->dev, "tve_clk"); + clk_set_rate(tve.clk, 216000000); + clk_enable(tve.clk); + + /* Setup cable detect */ + __raw_writel(0x010777F1, tve.base + TVE_CD_CONT_REG); + /* tve_man_detect(); not working */ + + __raw_writel(CD_SM_INT | CD_LM_INT, tve.base + TVE_STAT_REG); + __raw_writel(CD_SM_INT | CD_LM_INT, tve.base + TVE_INT_CONT_REG); + + __raw_writel(0x00000000, tve.base + 0x34); + __raw_writel(0x00000000, tve.base + 0x38); + __raw_writel(0x00000000, tve.base + 0x3C); + __raw_writel(0x00000000, tve.base + 0x40); + __raw_writel(0x00000000, tve.base + 0x44); + __raw_writel(0x00000000, tve.base + TVE_MV_CONT_REG); + + clk_disable(tve.clk); + + ret = fb_register_client(&nb); + if (ret < 0) + goto err2; + + return 0; +err2: + driver_remove_file(pdev->dev.driver, &driver_attr_headphone); +err1: + free_irq(tve.irq, pdev); +err0: + iounmap(tve.base); + return ret; +} + +static int tve_remove(struct platform_device *pdev) +{ + if (enabled) { + clk_disable(tve.clk); + enabled = 0; + } + free_irq(tve.irq, pdev); + driver_remove_file(pdev->dev.driver, &driver_attr_headphone); + fb_unregister_client(&nb); + return 0; +} + +/*! + * PM suspend/resume routing + */ +static int tve_suspend(struct platform_device *pdev, pm_message_t state) +{ + if (enabled) { + __raw_writel(0, tve.base + TVE_INT_CONT_REG); + __raw_writel(0, tve.base + TVE_CD_CONT_REG); + __raw_writel(0, tve.base + TVE_COM_CONF_REG); + clk_disable(tve.clk); + } + return 0; +} + +static int tve_resume(struct platform_device *pdev) +{ + if (enabled) + clk_enable(tve.clk); + + return 0; +} + +static struct platform_driver tve_driver = { + .driver = { + .name = "tve", + }, + .probe = tve_probe, + .remove = tve_remove, + .suspend = tve_suspend, + .resume = tve_resume, +}; + +static int __init tve_init(void) +{ + return platform_driver_register(&tve_driver); +} + +static void __exit tve_exit(void) +{ + platform_driver_unregister(&tve_driver); +} + +module_init(tve_init); +module_exit(tve_exit); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("i.MX TV encoder driver"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/video/mxc/Makefile +++ linux-2.6.28/drivers/video/mxc/Makefile @@ -0,0 +1,6 @@ +ifeq ($(CONFIG_MXC_IPU_V3),y) + obj-$(CONFIG_FB_MXC_SYNC_PANEL) += mxc_ipuv3_fb.o +endif +obj-$(CONFIG_FB_MXC_EPSON_VGA_SYNC_PANEL) += mxcfb_epson_vga.o +obj-$(CONFIG_FB_MXC_TVOUT_TVE) += tve.o +obj-$(CONFIG_FB_MXC_CH7026) += mxcfb_ch7026.o --- linux-2.6.28.orig/drivers/video/mxc/mxcfb_epson_vga.c +++ linux-2.6.28/drivers/video/mxc/mxcfb_epson_vga.c @@ -0,0 +1,357 @@ +/* + * Copyright 2007-2009 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 + */ + +/*! + * @defgroup Framebuffer Framebuffer Driver for SDC and ADC. + */ + +/*! + * @file mxcfb_epson_vga.c + * + * @brief MXC Frame buffer driver for SDC + * + * @ingroup Framebuffer + */ + +/*! + * Include files + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct spi_device *lcd_spi; +static struct device *lcd_dev; + +static void lcd_init(void); +static void lcd_poweron(void); +static void lcd_poweroff(void); + +static void (*lcd_reset) (void); +static struct regulator *io_reg; +static struct regulator *core_reg; + +static struct fb_videomode video_modes[] = { + { + /* 480x640 @ 60 Hz */ + "Epson-VGA", 60, 480, 640, 41701, 60, 41, 10, 5, 20, 10, + 0, + FB_VMODE_NONINTERLACED, + 0,}, +}; + +static void lcd_init_fb(struct fb_info *info) +{ + struct fb_var_screeninfo var; + + memset(&var, 0, sizeof(var)); + + fb_videomode_to_var(&var, &video_modes[0]); + + if (machine_is_mx31_3ds()) { + var.upper_margin = 0; + var.left_margin = 0; + } + + var.activate = FB_ACTIVATE_ALL; + var.yres_virtual = var.yres * 2; + + acquire_console_sem(); + info->flags |= FBINFO_MISC_USEREVENT; + fb_set_var(info, &var); + info->flags &= ~FBINFO_MISC_USEREVENT; + release_console_sem(); +} + +static int lcd_fb_event(struct notifier_block *nb, unsigned long val, void *v) +{ + struct fb_event *event = v; + + if (strcmp(event->info->fix.id, "DISP3 BG")) { + return 0; + } + + switch (val) { + case FB_EVENT_FB_REGISTERED: + lcd_init_fb(event->info); + lcd_poweron(); + break; + case FB_EVENT_BLANK: + if ((event->info->var.xres != 480) || + (event->info->var.yres != 640)) { + break; + } + if (*((int *)event->data) == FB_BLANK_UNBLANK) { + lcd_poweron(); + } else { + lcd_poweroff(); + } + break; + } + return 0; +} + +static struct notifier_block nb = { + .notifier_call = lcd_fb_event, +}; + +/*! + * This function is called whenever the SPI slave device is detected. + * + * @param spi the SPI slave device + * + * @return Returns 0 on SUCCESS and error on FAILURE. + */ +static int __devinit lcd_probe(struct device *dev) +{ + int i; + struct mxc_lcd_platform_data *plat = dev->platform_data; + + lcd_dev = dev; + + if (plat) { + io_reg = regulator_get(dev, plat->io_reg); + if (!IS_ERR(io_reg)) { + regulator_set_voltage(io_reg, 1800000, 1800000); + regulator_enable(io_reg); + } + core_reg = regulator_get(dev, plat->core_reg); + if (!IS_ERR(core_reg)) { + regulator_set_voltage(core_reg, 2800000, 2800000); + regulator_enable(core_reg); + } + + lcd_reset = plat->reset; + if (lcd_reset) + lcd_reset(); + } + + lcd_init(); + + for (i = 0; i < num_registered_fb; i++) { + if (strcmp(registered_fb[i]->fix.id, "DISP3 BG") == 0) { + lcd_init_fb(registered_fb[i]); + fb_show_logo(registered_fb[i], 0); + lcd_poweron(); + } + } + + fb_register_client(&nb); + + return 0; +} + +static int __devinit lcd_plat_probe(struct platform_device *pdev) +{ + ipu_adc_sig_cfg_t sig; + ipu_channel_params_t param; + + memset(&sig, 0, sizeof(sig)); + sig.ifc_width = 9; + sig.clk_pol = 1; + ipu_init_async_panel(0, IPU_PANEL_SERIAL, 90, IPU_PIX_FMT_GENERIC, sig); + + memset(¶m, 0, sizeof(param)); + ipu_init_channel(DIRECT_ASYNC1, ¶m); + + return lcd_probe(&pdev->dev); +} + +static int __devinit lcd_spi_probe(struct spi_device *spi) +{ + lcd_spi = spi; + + spi->bits_per_word = 9; + spi_setup(spi); + + return lcd_probe(&spi->dev); +} + +static int __devexit lcd_remove(struct device *dev) +{ + fb_unregister_client(&nb); + lcd_poweroff(); + regulator_put(io_reg); + regulator_put(core_reg); + + return 0; +} + +static int __devexit lcd_spi_remove(struct spi_device *spi) +{ + int ret = lcd_remove(&spi->dev); + lcd_spi = NULL; + return ret; +} + +static int __devexit lcd_plat_remove(struct platform_device *pdev) +{ + return lcd_remove(&pdev->dev); +} + +static int lcd_suspend(struct spi_device *spi, pm_message_t message) +{ + return 0; +} + +static int lcd_resume(struct spi_device *spi) +{ + return 0; +} + +/*! + * spi driver structure for LTV350QV + */ +static struct spi_driver lcd_spi_dev_driver = { + + .driver = { + .name = "lcd_spi", + .owner = THIS_MODULE, + }, + .probe = lcd_spi_probe, + .remove = __devexit_p(lcd_spi_remove), + .suspend = lcd_suspend, + .resume = lcd_resume, +}; + +static struct platform_driver lcd_plat_driver = { + .driver = { + .name = "lcd_spi", + .owner = THIS_MODULE, + }, + .probe = lcd_plat_probe, + .remove = __devexit_p(lcd_plat_remove), +}; + +#define param(x) ((x) | 0x100) + +/* + * Send init commands to L4F00242T03 + * + */ +static void lcd_init(void) +{ + const u16 cmd[] = { 0x36, param(0), 0x3A, param(0x60) }; + + dev_dbg(lcd_dev, "initializing LCD\n"); + + if (lcd_spi) { + spi_write(lcd_spi, (const u8 *)cmd, ARRAY_SIZE(cmd)); + } else { + ipu_disp_direct_write(DIRECT_ASYNC1, 0x36, 0); + ipu_disp_direct_write(DIRECT_ASYNC1, 0x100, 0); + ipu_disp_direct_write(DIRECT_ASYNC1, 0x3A, 0); + ipu_disp_direct_write(DIRECT_ASYNC1, 0x160, 0); + msleep(1); + ipu_uninit_channel(DIRECT_ASYNC1); + } +} + +static int lcd_on; +/* + * Send Power On commands to L4F00242T03 + * + */ +static void lcd_poweron(void) +{ + const u16 slpout = 0x11; + const u16 dison = 0x29; + ipu_channel_params_t param; + + if (lcd_on) + return; + + dev_dbg(lcd_dev, "turning on LCD\n"); + + if (lcd_spi) { + msleep(60); + spi_write(lcd_spi, (const u8 *)&slpout, 1); + msleep(60); + spi_write(lcd_spi, (const u8 *)&dison, 1); + } else { + memset(¶m, 0, sizeof(param)); + ipu_init_channel(DIRECT_ASYNC1, ¶m); + ipu_disp_direct_write(DIRECT_ASYNC1, slpout, 0); + msleep(60); + ipu_disp_direct_write(DIRECT_ASYNC1, dison, 0); + msleep(1); + ipu_uninit_channel(DIRECT_ASYNC1); + } + lcd_on = 1; +} + +/* + * Send Power Off commands to L4F00242T03 + * + */ +static void lcd_poweroff(void) +{ + const u16 slpin = 0x10; + const u16 disoff = 0x28; + ipu_channel_params_t param; + + if (!lcd_on) + return; + + dev_dbg(lcd_dev, "turning off LCD\n"); + + if (lcd_spi) { + msleep(60); + spi_write(lcd_spi, (const u8 *)&disoff, 1); + msleep(60); + spi_write(lcd_spi, (const u8 *)&slpin, 1); + } else { + memset(¶m, 0, sizeof(param)); + ipu_init_channel(DIRECT_ASYNC1, ¶m); + ipu_disp_direct_write(DIRECT_ASYNC1, disoff, 0); + msleep(60); + ipu_disp_direct_write(DIRECT_ASYNC1, slpin, 0); + msleep(1); + ipu_uninit_channel(DIRECT_ASYNC1); + } + lcd_on = 0; +} + +static int __init epson_lcd_init(void) +{ + int ret; + + ret = platform_driver_register(&lcd_plat_driver); + if (ret) + return ret; + + return spi_register_driver(&lcd_spi_dev_driver); + +} + +static void __exit epson_lcd_exit(void) +{ + spi_unregister_driver(&lcd_spi_dev_driver); +} + +module_init(epson_lcd_init); +module_exit(epson_lcd_exit); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("Epson VGA LCD init driver"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/video/aty/mach64_ct.c +++ linux-2.6.28/drivers/video/aty/mach64_ct.c @@ -8,6 +8,9 @@ #include #include

] []\"\n", + prgname, prgname); + fprintf(stderr,"valid operation: read, write, mem, reg,\n"); + fprintf(stderr," : txd, rxd, rmem, wmem\n"); + fprintf(stderr," : dmat, regt, test\n"); + + fprintf(stderr," scan, Channel Scan\n"); + fprintf(stderr," rts , Set RTS Threshold\n"); + fprintf(stderr," frag , Set Fragment Threshold\n"); + fprintf(stderr," rate <0-28>, 0:AUTO, 1-4:CCK, 5-12:OFDM, 13-28:HT\n"); + fprintf(stderr," TBD mix <0 or 1>, Set 1 to enable mixed mode\n"); + fprintf(stderr," enc, <0-3>, 0=>OPEN, 1=>WEP64, 2=>WEP128, 3=>WEP256\n"); + fprintf(stderr," skey , Set WEP key\n"); + fprintf(stderr," txcnt, Get TxQ Cnt\n"); + fprintf(stderr," dagcnt, Get Deaggregate Cnt\n"); + fprintf(stderr," durmode , Set Duration Mode 0=>HW, 1=>SW\n"); + fprintf(stderr," aeskey \n"); + fprintf(stderr," aesmode \n"); + fprintf(stderr," wlanmode <0,1> 0:Station mode, 1:PIBSS mode\n"); + fprintf(stderr," tal <0,1>, Get Current Tally Info, 0=>read, 1=>read and reset\n"); + + exit(1); + } + + strcpy(req.ifr_name, argv[1]); + zdreq.addr = 0; + zdreq.value = 0; + + /* a silly raw socket just for ioctl()ling it */ + sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); + if (sock < 0) { + fprintf(stderr, "%s: socket(): %s\n", argv[0], strerror(errno)); + exit(1); + } + + if (argc >= 4) + { + sscanf(argv[3], "%x", &addr); + } + + if (argc >= 5) + { + sscanf(argv[4], "%x", &value); + } + + zdreq.addr = addr; + zdreq.value = value; + + if (!strcmp(argv[2], "read")) + { + zdreq.cmd = ZM_IOCTL_REG_READ; + } + else if (!strcmp(argv[2], "mem")) + { + zdreq.cmd = ZM_IOCTL_MEM_DUMP; + } + else if (!strcmp(argv[2], "write")) + { + zdreq.cmd = ZM_IOCTL_REG_WRITE; + } + else if (!strcmp(argv[2], "reg")) + { + zdreq.cmd = ZM_IOCTL_REG_DUMP; + } + else if (!strcmp(argv[2], "txd")) + { + zdreq.cmd = ZM_IOCTL_TXD_DUMP; + } + else if (!strcmp(argv[2], "rxd")) + { + zdreq.cmd = ZM_IOCTL_RXD_DUMP; + } + else if (!strcmp(argv[2], "rmem")) + { + zdreq.cmd = ZM_IOCTL_MEM_READ; + } + else if (!strcmp(argv[2], "wmem")) + { + zdreq.cmd = ZM_IOCTL_MEM_WRITE; + } + else if (!strcmp(argv[2], "dmat")) + { + zdreq.cmd = ZM_IOCTL_DMA_TEST; + } + else if (!strcmp(argv[2], "regt")) + { + zdreq.cmd = ZM_IOCTL_REG_TEST; + } + else if (!strcmp(argv[2], "test")) + { + zdreq.cmd = ZM_IOCTL_TEST; + } + else if (!strcmp(argv[2], "tal")) + { + sscanf(argv[3], "%d", &addr); + zdreq.addr = addr; + zdreq.cmd = ZM_IOCTL_TALLY; + } + else if (!strcmp(argv[2], "rts")) + { + sscanf(argv[3], "%d", &addr); + zdreq.addr = addr; + zdreq.cmd = ZM_IOCTL_RTS; + } + else if (!strcmp(argv[2], "mix")) + { + zdreq.cmd = ZM_IOCTL_MIX_MODE; + } + else if (!strcmp(argv[2], "frag")) + { + sscanf(argv[3], "%d", &addr); + zdreq.addr = addr; + zdreq.cmd = ZM_IOCTL_FRAG; + } + else if (!strcmp(argv[2], "scan")) + { + zdreq.cmd = ZM_IOCTL_SCAN; + } + else if (!strcmp(argv[2], "skey")) + { + zdreq.cmd = ZM_IOCTL_KEY; + + if (argc >= 4) + { + unsigned char temp[29]; + int i; + int keyLen; + int encType; + + keyLen = strlen(argv[3]); + + if (keyLen == 10) + { + sscanf(argv[3], "%02x%02x%02x%02x%02x", &temp[0], &temp[1], + &temp[2], &temp[3], &temp[4]); + } + else if (keyLen == 26) + { + sscanf(argv[3], "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + &temp[0], &temp[1], &temp[2], &temp[3], &temp[4], + &temp[5], &temp[6], &temp[7], &temp[8], &temp[9], + &temp[10], &temp[11], &temp[12]); + } + else if (keyLen == 58) + { + sscanf(argv[3], "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + &temp[0], &temp[1], &temp[2], &temp[3], &temp[4], + &temp[5], &temp[6], &temp[7], &temp[8], &temp[9], + &temp[10], &temp[11], &temp[12], &temp[13], &temp[14], + &temp[15], &temp[16], &temp[17], &temp[18], &temp[19], + &temp[20], &temp[21], &temp[22], &temp[23], &temp[24], + &temp[25], &temp[26], &temp[27], &temp[28]); + } + else + { + fprintf(stderr, "Invalid key length\n"); + exit(1); + } + zdreq.addr = keyLen/2; + + for(i=0; i 28) + { + fprintf(stderr, "Invalid rate, range:0~28\n"); + exit(1); + } + zdreq.addr = addr; + zdreq.cmd = ZM_IOCTL_RATE; + } + else if (!strcmp(argv[2], "enc")) + { + sscanf(argv[3], "%d", &addr); + + if (addr > 3) + { + fprintf(stderr, "Invalid encryption mode, range:0~3\n"); + exit(1); + } + + if (addr == 2) + { + addr = 5; + } + else if (addr == 3) + { + addr = 6; + } + + zdreq.addr = addr; + zdreq.cmd = ZM_IOCTL_ENCRYPTION_MODE; + } + else if (!strcmp(argv[2], "txcnt")) + { + zdreq.cmd = ZM_IOCTL_GET_TXCNT; + } + else if (!strcmp(argv[2], "dagcnt")) + { + sscanf(argv[3], "%d", &addr); + + if (addr != 0 && addr != 1) + { + fprintf(stderr, "The value should be 0 or 1\n"); + exit(0); + } + + zdreq.addr = addr; + zdreq.cmd = ZM_IOCTL_GET_DEAGG_CNT; + } + else if (!strcmp(argv[2], "durmode")) + { + sscanf(argv[3], "%d", &addr); + + if (addr != 0 && addr != 1) + { + fprintf(stderr, "The Duration mode should be 0 or 1\n"); + exit(0); + } + + zdreq.addr = addr; + zdreq.cmd = ZM_IOCTL_DURATION_MODE; + } + else if (!strcmp(argv[2], "aeskey")) + { + unsigned char temp[16]; + int i; + + sscanf(argv[3], "%d", &addr); + + sscanf(argv[4], "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", &temp[0], &temp[1], &temp[2], &temp[3], &temp[4], &temp[5], &temp[6], &temp[7], &temp[8], &temp[9], &temp[10], &temp[11], &temp[12], &temp[13], &temp[14], &temp[15]); + + for(i = 0; i < 16; i++) + { + zdreq.data[i] = temp[i]; + } + + zdreq.addr = addr; + zdreq.cmd = ZM_IOCTL_SET_AES_KEY; + } + else if (!strcmp(argv[2], "aesmode")) + { + sscanf(argv[3], "%d", &addr); + + zdreq.addr = addr; + zdreq.cmd = ZM_IOCTL_SET_AES_MODE; + } + else if (!strcmp(argv[2], "wlanmode")) + { + sscanf(argv[3], "%d", &addr); + + zdreq.addr = addr; + zdreq.cmd = ZM_IOCTL_SET_PIBSS_MODE; + } + else + { + fprintf(stderr, "error action\n"); + exit(1); + } + + req.ifr_data = (char *)&zdreq; + set_ioctl(sock, &req); + +fail: + exit(0); +} + +unsigned char asctohex(char *str) +{ + unsigned char value; + + value = hex(*str) & 0x0f; + value = value << 4; + str++; + value |= hex(*str) & 0x0f; + + return value; +} + +char hex(char v) +{ + if(isdigit(v)) + return v - '0'; + else if(isxdigit(v)) + return (tolower(v) - 'a' + 10); + else + return 0; +} + --- linux-2.6.28.orig/drivers/staging/otus/wrap_dbg.c +++ linux-2.6.28/drivers/staging/otus/wrap_dbg.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* Module Name : wrap_dbg.c */ +/* */ +/* Abstract */ +/* This module contains wrapper functions for debug functions */ +/* */ +/* NOTES */ +/* Platform dependent. */ +/* */ +/************************************************************************/ + +#include "oal_dt.h" +#include "usbdrv.h" + +#include + +#if WIRELESS_EXT > 12 +#include +#endif + +void zfwDumpBuf(zdev_t* dev, zbuf_t* buf) +{ + u16_t i; + + for (i=0; ilen; i++) + { + printk("%02x ", *(((u8_t*)buf->data)+i)); + if ((i&0xf)==0xf) + { + printk("\n"); + } + } + printk("\n"); +} + + +void zfwDbgReadRegDone(zdev_t* dev, u32_t addr, u32_t val) +{ + printk("Read addr:%x = %x\n", addr, val); +} + +void zfwDbgWriteRegDone(zdev_t* dev, u32_t addr, u32_t val) +{ + printk("Write addr:%x = %x\n", addr, val); +} + +void zfwDbgReadTallyDone(zdev_t* dev) +{ + //printk("Read Tall Done\n"); +} + +void zfwDbgWriteEepromDone(zdev_t* dev, u32_t addr, u32_t val) +{ +} + +void zfwDbgQueryHwTxBusyDone(zdev_t* dev, u32_t val) +{ +} + +//For Evl ++ +void zfwDbgReadFlashDone(zdev_t* dev, u32_t addr, u32_t* rspdata, u32_t datalen) +{ + printk("Read Flash addr:%x length:%x\n", addr, datalen); +} + +void zfwDbgProgrameFlashDone(zdev_t* dev) +{ + printk("Program Flash Done\n"); +} + +void zfwDbgProgrameFlashChkDone(zdev_t* dev) +{ + printk("Program Flash Done\n"); +} + +void zfwDbgGetFlashChkSumDone(zdev_t* dev, u32_t* rspdata) +{ + printk("Get Flash ChkSum Done\n"); +} + +void zfwDbgDownloadFwInitDone(zdev_t* dev) +{ + printk("Download FW Init Done\n"); +} +//For Evl -- + +/* Leave an empty line below to remove warning message on some compiler */ --- linux-2.6.28.orig/drivers/staging/otus/TODO +++ linux-2.6.28/drivers/staging/otus/TODO @@ -0,0 +1,9 @@ +TODO: + - checkpatch.pl cleanups + - sparse cleanups + - port to in-kernel 80211 stack + - proper network developer maintainer + +Please send any patches to Greg Kroah-Hartman and +Luis Rodriguez and the +otus-devel@lists.madwifi-project.org mailing list. --- linux-2.6.28.orig/drivers/staging/otus/athr_common.h +++ linux-2.6.28/drivers/staging/otus/athr_common.h @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* Module Name : athr_common.h */ +/* */ +/* Abstract */ +/* WPA related function and data structure definitions. */ +/* */ +/* NOTES */ +/* Platform dependent. */ +/* */ +/************************************************************************/ + +#ifndef _ATHR_COMMON_H +#define _ATHR_COMMON_H + +#define ZD_IOCTL_WPA (SIOCDEVPRIVATE + 1) +#define ZD_IOCTL_PARAM (SIOCDEVPRIVATE + 2) +#define ZD_IOCTL_GETWPAIE (SIOCDEVPRIVATE + 3) +#define ZD_PARAM_ROAMING 0x0001 +#define ZD_PARAM_PRIVACY 0x0002 +#define ZD_PARAM_WPA 0x0003 +#define ZD_PARAM_COUNTERMEASURES 0x0004 +#define ZD_PARAM_DROPUNENCRYPTED 0x0005 +#define ZD_PARAM_AUTH_ALGS 0x0006 + +#define ZD_CMD_SET_ENCRYPT_KEY 0x0001 +#define ZD_CMD_SET_MLME 0x0002 +#define ZD_CMD_SCAN_REQ 0x0003 +#define ZD_CMD_SET_GENERIC_ELEMENT 0x0004 +#define ZD_CMD_GET_TSC 0x0005 + +#define ZD_FLAG_SET_TX_KEY 0x0001 + +#define ZD_GENERIC_ELEMENT_HDR_LEN \ +((int) (&((struct athr_wlan_param *) 0)->u.generic_elem.data)) + +#define ZD_CRYPT_ALG_NAME_LEN 16 +#define ZD_MAX_KEY_SIZE 32 +#define ZD_MAX_GENERIC_SIZE 64 + +#define IEEE80211_ADDR_LEN 6 +#define IEEE80211_MAX_IE_SIZE 256 + +#ifdef ZM_ENALBE_WAPI +#define ZM_CMD_WAPI_SETWAPI 0x0001 +#define ZM_CMD_WAPI_GETWAPI 0x0002 +#define ZM_CMD_WAPI_SETKEY 0x0003 +#define ZM_CMD_WAPI_GETKEY 0x0004 +#define ZM_CMD_WAPI_REKEY 0x0005 + +#define ZM_WAPI_WAI_REQUEST 0x00f1 +#define ZM_WAPI_UNICAST_REKEY 0x00f2 +#define ZM_WAPI_STA_AGING 0x00f3 +#define ZM_WAPI_MULTI_REKEY 0x00f4 + +#define ZM_WAPI_KEY_SIZE 32 +#define ZM_WAPI_IV_LEN 16 +#endif //ZM_ENALBE_WAPI +/* structure definition */ + +struct athr_wlan_param { + u32 cmd; + u8 sta_addr[ETH_ALEN]; + union { + struct { + u8 alg[ZD_CRYPT_ALG_NAME_LEN]; + u32 flags; + u32 err; + u8 idx; + u8 seq[8]; /* sequence counter (set: RX, get: TX) */ + u16 key_len; + u8 key[ZD_MAX_KEY_SIZE]; + } crypt; + struct { + u32 flags_and; + u32 flags_or; + } set_flags_sta; + struct { + u8 len; + u8 data[ZD_MAX_GENERIC_SIZE]; + } generic_elem; + struct { +#define MLME_STA_DEAUTH 0 +#define MLME_STA_DISASSOC 1 + u16 cmd; + u16 reason_code; + } mlme; + struct { + u8 ssid_len; + u8 ssid[32]; + } scan_req; + } u; +}; + +struct ieee80211req_wpaie { + u8 wpa_macaddr[IEEE80211_ADDR_LEN]; + u8 wpa_ie[IEEE80211_MAX_IE_SIZE]; +}; + +#ifdef ZM_ENALBE_WAPI +struct athr_wapi_param { + u16 cmd; + u16 len; + + union { + struct { + u8 sta_addr[ETH_ALEN]; + u8 reserved; + u8 keyid; + u8 key[ZM_WAPI_KEY_SIZE]; + } crypt; + struct { + u8 wapi_policy; + } info; + } u; +}; + +struct athr_wapi_sta_info +{ + u16 msg_type; + u16 datalen; + u8 sta_mac[ETH_ALEN]; + u8 reserve_data[2]; + u8 gsn[ZM_WAPI_IV_LEN]; + u8 wie[256]; +}; +#endif //ZM_ENALBE_WAPI +#endif --- linux-2.6.28.orig/drivers/staging/otus/wrap_usb.c +++ linux-2.6.28/drivers/staging/otus/wrap_usb.c @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* */ +/* Module Name : wrap_usb.c */ +/* */ +/* Abstract */ +/* This module contains wrapper functions for USB management */ +/* */ +/* NOTES */ +/* Platform dependent. */ +/* */ +/************************************************************************/ + +#include "oal_dt.h" +#include "usbdrv.h" + +#include + +#if WIRELESS_EXT > 12 +#include +#endif + +extern void zfLnxInitUsbTxQ(zdev_t* dev); +extern void zfLnxInitUsbRxQ(zdev_t* dev); +extern u32_t zfLnxSubmitRegInUrb(zdev_t *dev); +u32_t zfLnxUsbOut(zdev_t* dev, u8_t *hdr, u16_t hdrlen, u8_t *snap, u16_t snapLen, + u8_t *tail, u16_t tailLen, zbuf_t *buf, u16_t offset); +u32_t zfLnxUsbWriteReg(zdev_t* dev, u32_t* cmd, u16_t cmdLen); + +void zfwUsbRegisterCallBack(zdev_t* dev, struct zfCbUsbFuncTbl *zfUsbFunc) { + struct usbdrv_private *macp = dev->ml_priv; + + macp->usbCbFunctions.zfcbUsbRecv = zfUsbFunc->zfcbUsbRecv; + macp->usbCbFunctions.zfcbUsbRegIn = zfUsbFunc->zfcbUsbRegIn; + macp->usbCbFunctions.zfcbUsbOutComplete = zfUsbFunc->zfcbUsbOutComplete; + + return; +} + +u32_t zfwUsbGetFreeTxQSize(zdev_t* dev) +{ + struct usbdrv_private *macp = dev->ml_priv; + u32_t freeTxQSize; + unsigned long irqFlag; + //zmw_declare_for_critical_section(); + + //zmw_enter_critical_section(dev); + spin_lock_irqsave(&macp->cs_lock, irqFlag); + + freeTxQSize = ZM_MAX_TX_BUF_NUM - macp->TxBufCnt; + + //zmw_leave_critical_section(dev); + spin_unlock_irqrestore(&macp->cs_lock, irqFlag); + + return freeTxQSize; +} + +u32_t zfwUsbGetMaxTxQSize(zdev_t* dev) +{ + return ZM_MAX_TX_BUF_NUM; +} + +u32_t zfwUsbEnableIntEpt(zdev_t *dev, u8_t endpt) +{ + /* Initialize USB TxQ */ + zfLnxInitUsbTxQ(dev); + + /* Initialize USB RxQ */ + zfLnxInitUsbRxQ(dev); + + /* Initialize USB Register In URB */ + //zfwUsbSubmitRegIn(dev); + /* Initialize USB Register In URB */ + zfLnxSubmitRegInUrb(dev); + + return 0; +} + +int zfwUsbEnableRxEpt(zdev_t* dev, u8_t endpt) +{ + return 0; +} + +u32_t zfwUsbSubmitControl(zdev_t* dev, u8_t req, u16_t value, u16_t index, void *data, u32_t size) +{ + int result = 0; + u32_t ret = 0; + struct usbdrv_private *macp = dev->ml_priv; + u8_t* buf; + + if (size > 0) + { + buf = kmalloc(size, GFP_KERNEL); + memcpy(buf, (u8_t*)data, size); + } + else + { + buf = NULL; + } + +#if 0 + printk(KERN_ERR "req = 0x%02x\n", req); + printk(KERN_ERR "value = 0x%04x\n", value); + printk(KERN_ERR "index = 0x%04x\n", index); + printk(KERN_ERR "data = 0x%lx\n", (u32_t) data); + printk(KERN_ERR "size = %ld\n", size); +#endif + + result = usb_control_msg(macp->udev, usb_sndctrlpipe(macp->udev, 0), + req, USB_DIR_OUT | 0x40, value, index, buf, size, HZ); + + if (result < 0) + { + printk("zfwUsbSubmitControl() failed, result=0x%x\n", result); + ret = 1; + } + kfree(buf); + + return ret; +} + +void zfwUsbCmd(zdev_t* dev, u8_t endpt, u32_t* cmd, u16_t cmdLen) +{ + struct usbdrv_private *macp = dev->ml_priv; + u32_t ret; + + //MPUsbCommand(dev, endpt, cmd, cmdLen); + ret = zfLnxUsbWriteReg(dev, cmd, cmdLen); + + /* if zfLnxUsbWriteReg() return error, free and allocate urb, resend again */ + if (ret != 0) + { + usb_free_urb(macp->RegOutUrb); + macp->RegOutUrb = usb_alloc_urb(0, GFP_ATOMIC); + ret = zfLnxUsbWriteReg(dev, cmd, cmdLen); + } +} + +u32_t zfwUsbSend(zdev_t* dev, u8_t endpt, u8_t *hdr, u16_t hdrlen, u8_t *snap, u16_t snapLen, + u8_t *tail, u16_t tailLen, zbuf_t *buf, u16_t offset) +{ + u32_t status; + +#ifdef ZM_CONFIG_BIG_ENDIAN + u32_t ii = 0; + u16_t *pc = NULL; + + pc = (u16_t *)hdr; + for(ii=0; ii<(hdrlen>>1); ii++) + { + pc[ii] = cpu_to_le16(pc[ii]); + } + + pc = (u16_t *)snap; + for(ii=0; ii<(snapLen>>1); ii++) + { + pc[ii] = cpu_to_le16(pc[ii]); + } + + pc = (u16_t *)tail; + for(ii=0; ii<(tailLen>>1); ii++) + { + pc[ii] = cpu_to_le16(pc[ii]); + } +#endif + + status = zfLnxUsbOut(dev, hdr, hdrlen, snap, snapLen, tail, tailLen, buf, offset); + if ( status == 0 ) + { + return 0; + } + else + { + return 1; + } +} + +/* Leave an empty line below to remove warning message on some compiler */ --- linux-2.6.28.orig/drivers/staging/otus/wrap_buf.c +++ linux-2.6.28/drivers/staging/otus/wrap_buf.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* */ +/* Module Name : wrap_buf.c */ +/* */ +/* Abstract */ +/* This module contains wrapper functions for buffer management */ +/* */ +/* NOTES */ +/* Platform dependent. */ +/* */ +/************************************************************************/ + +#include "oal_dt.h" +#include "usbdrv.h" + + +#include + +#if WIRELESS_EXT > 12 +#include +#endif + + + +/* Called to allocate buffer, must return a continue buffer space */ +zbuf_t* zfwBufAllocate(zdev_t* dev, u16_t len) +{ + zbuf_t* buf; + + /* Allocate SKB for packet*/ + buf = dev_alloc_skb(len); + + return buf; +} + + +/* Called to free buffer, replace below 3 functions */ +void zfwBufFree(zdev_t* dev, zbuf_t* buf, u16_t status) +{ + dev_kfree_skb_any(buf); +} + +/* Called to adjust buffer size and head pointer */ +u16_t zfwBufRemoveHead(zdev_t* dev, zbuf_t* buf, u16_t size) +{ + //zm_assert(buf->len > size); + + buf->data += size; + buf->len -= size; + return 0; +} + + + + +/* return tail if head==NULL, called to chain multiple buffer together */ +/* Used to chain Rx buffer to form a frame. if the prepared Rx buffer */ +/* is greater than an ethernet frame(1518+32 byte), then this function */ +/* will only be called with head=NULL. */ +u16_t zfwBufChain(zdev_t* dev, zbuf_t** head, zbuf_t* tail) +{ + + *head = tail; + return 0; +} + + +/* Called when doing infra-bss forwarding */ +u16_t zfwBufCopy(zdev_t* dev, zbuf_t* dst, zbuf_t* src) +{ + memcpy(dst->data, src->data, src->len); + dst->tail = dst->data; + skb_put(dst, src->len); + return 0; +} + + +/* Called to adjust buffer size and tail pointer */ +u16_t zfwBufSetSize(zdev_t* dev, zbuf_t* buf, u16_t size) +{ +#ifdef NET_SKBUFF_DATA_USES_OFFSET + buf->tail = 0; + buf->len = 0; +#else + buf->tail = buf->data; + buf->len = 0; +#endif + + skb_put(buf, size); + return 0; +} + +u16_t zfwBufGetSize(zdev_t* dev, zbuf_t* buf) +{ + return buf->len; +} + +void zfwCopyBufContext(zdev_t* dev, zbuf_t* source, zbuf_t* dst) +{ +} --- linux-2.6.28.orig/drivers/staging/otus/usbdrv.h +++ linux-2.6.28/drivers/staging/otus/usbdrv.h @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* */ +/* Module Name : usbdrv.h */ +/* */ +/* Abstract */ +/* This module contains network interface up/down related definition*/ +/* */ +/* NOTES */ +/* Platform dependent. */ +/* */ +/************************************************************************/ + +#ifndef _USBDRV_H +#define _USBDRV_H + +#define WLAN_USB 0 +#define WLAN_PCI 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "zdcompat.h" + +#include "oal_dt.h" +#include "oal_marc.h" +#include "80211core/pub_zfi.h" +//#include "pub_zfw.h" +#include "80211core/pub_usb.h" + +#include +/* Please include header files for device type in the beginning of this file */ +#define urb_t struct urb + +#define usb_complete_t usb_complete_t +#define pipe_t u32_t + +/* USB Endpoint definition */ +#define USB_WLAN_TX_PIPE 1 +#define USB_WLAN_RX_PIPE 2 +#define USB_REG_IN_PIPE 3 +#define USB_REG_OUT_PIPE 4 + +#if (WLAN_HOSTIF == WLAN_USB) +#include +#endif + +#ifdef ZM_HOSTAPD_SUPPORT +#include "athr_common.h" +#endif + +/************************************************************************** +** Descriptor Data Structure +***************************************************************************/ +struct driver_stats { + struct net_device_stats net_stats; +}; + +#define ZM_MAX_RX_BUFFER_SIZE 8192 + +#if ZM_USB_TX_STREAM_MODE == 1 +#define ZM_MAX_TX_AGGREGATE_NUM 4 +#define ZM_USB_TX_BUF_SIZE 8096 +#define ZM_MAX_TX_URB_NUM 4 +#else +#define ZM_USB_TX_BUF_SIZE 2048 +#define ZM_MAX_TX_URB_NUM 8 +#endif +#define ZM_USB_REG_MAX_BUF_SIZE 64 +#define ZM_MAX_RX_URB_NUM 16 +#define ZM_MAX_TX_BUF_NUM 128 + +typedef struct UsbTxQ +{ + zbuf_t *buf; + u8_t hdr[80]; + u16_t hdrlen; + u8_t snap[8]; + u16_t snapLen; + u8_t tail[16]; + u16_t tailLen; + u16_t offset; +} UsbTxQ_t; + + +struct zdap_ioctl { + u16_t cmd; /* Command to run */ + u32_t addr; /* Length of the data buffer */ + u32_t value; /* Pointer to the data buffer */ + u8_t data[0x100]; +}; + +#define ZM_OAL_MAX_STA_SUPPORT 16 + +struct usbdrv_private +{ + //linux used + struct net_device *device; +#if (WLAN_HOSTIF == WLAN_PCI) + struct pci_dev *pdev; +#endif +#if (WLAN_HOSTIF == WLAN_USB) + struct usb_device *udev; + struct usb_interface *interface; +#endif + struct driver_stats drv_stats; + char ifname[IFNAMSIZ]; + int using_dac; + u8_t rev_id; /* adapter PCI revision ID */ + rwlock_t isolate_lock; + spinlock_t cs_lock; + int driver_isolated; +#if (WLAN_HOSTIF == WLAN_PCI) + void *regp; +#endif + + /* timer for heart beat */ + struct timer_list hbTimer10ms; + + /* For driver core */ + void* wd; + +#if (WLAN_HOSTIF == WLAN_USB) + u8_t txUsbBuf[ZM_MAX_TX_URB_NUM][ZM_USB_TX_BUF_SIZE]; + u8_t regUsbReadBuf[ZM_USB_REG_MAX_BUF_SIZE]; + u8_t regUsbWriteBuf[ZM_USB_REG_MAX_BUF_SIZE]; + urb_t *WlanTxDataUrb[ZM_MAX_TX_URB_NUM]; + urb_t *WlanRxDataUrb[ZM_MAX_RX_URB_NUM]; + urb_t *RegOutUrb; + urb_t *RegInUrb; + UsbTxQ_t UsbTxBufQ[ZM_MAX_TX_BUF_NUM]; + zbuf_t *UsbRxBufQ[ZM_MAX_RX_URB_NUM]; + u16_t TxBufHead; + u16_t TxBufTail; + u16_t TxBufCnt; + u16_t TxUrbHead; + u16_t TxUrbTail; + u16_t TxUrbCnt; + u16_t RxBufHead; + u16_t RxBufTail; + u16_t RxBufCnt; +#endif + +#if ZM_USB_STREAM_MODE == 1 + zbuf_t *reamin_buf; +#endif + +#ifdef ZM_HOSTAPD_SUPPORT + struct athr_wlan_param athr_wpa_req; +#endif + struct sock *netlink_sk; + u8_t DeviceOpened; //CWYang(+) + u8_t supIe[50]; + u8_t supLen; + struct ieee80211req_wpaie stawpaie[ZM_OAL_MAX_STA_SUPPORT]; + u8_t forwardMgmt; + + struct zfCbUsbFuncTbl usbCbFunctions; + + /* For keventd */ + u32_t flags; + unsigned long kevent_flags; + u16_t kevent_ready; + + struct semaphore ioctl_sem; + struct work_struct kevent; + wait_queue_head_t wait_queue_event; +#ifdef ZM_HALPLUS_LOCK + unsigned long hal_irqFlag; +#endif + u16_t adapterState; +}; + +/* WDS */ +#define ZM_WDS_PORT_NUMBER 6 + +struct zsWdsStruct +{ + struct net_device* dev; + u16_t openFlag; +}; + +/* VAP */ +#define ZM_VAP_PORT_NUMBER 7 + +struct zsVapStruct +{ + struct net_device* dev; + u16_t openFlag; +}; + +/***************************************/ + +#define ZM_IOCTL_REG_READ 0x01 +#define ZM_IOCTL_REG_WRITE 0x02 +#define ZM_IOCTL_MEM_DUMP 0x03 +#define ZM_IOCTL_REG_DUMP 0x05 +#define ZM_IOCTL_TXD_DUMP 0x06 +#define ZM_IOCTL_RXD_DUMP 0x07 +#define ZM_IOCTL_MEM_READ 0x0B +#define ZM_IOCTL_MEM_WRITE 0x0C +#define ZM_IOCTL_DMA_TEST 0x10 +#define ZM_IOCTL_REG_TEST 0x11 +#define ZM_IOCTL_TEST 0x80 +#define ZM_IOCTL_TALLY 0x81 //CWYang(+) +#define ZM_IOCTL_RTS 0xA0 +#define ZM_IOCTL_MIX_MODE 0xA1 +#define ZM_IOCTL_FRAG 0xA2 +#define ZM_IOCTL_SCAN 0xA3 +#define ZM_IOCTL_KEY 0xA4 +#define ZM_IOCTL_RATE 0xA5 +#define ZM_IOCTL_ENCRYPTION_MODE 0xA6 +#define ZM_IOCTL_GET_TXCNT 0xA7 +#define ZM_IOCTL_GET_DEAGG_CNT 0xA8 +#define ZM_IOCTL_DURATION_MODE 0xA9 +#define ZM_IOCTL_SET_AES_KEY 0xAA +#define ZM_IOCTL_SET_AES_MODE 0xAB +#define ZM_IOCTL_SIGNAL_STRENGTH 0xAC //CWYang(+) +#define ZM_IOCTL_SIGNAL_QUALITY 0xAD //CWYang(+) +#define ZM_IOCTL_SET_PIBSS_MODE 0xAE + +#define ZDAPIOCTL SIOCDEVPRIVATE + +enum devState { + Opened, + Enabled, + Disabled, + Closed +}; + +#endif /* _USBDRV_H */ + --- linux-2.6.28.orig/drivers/staging/otus/80211core/queue.h +++ linux-2.6.28/drivers/staging/otus/80211core/queue.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _QUEUE_H +#define _QUEUE_H + +#include "../oal_dt.h" + +struct zsQueueCell +{ + u32_t tick; + zbuf_t* buf; +}; + +struct zsQueue +{ + u16_t size; + u16_t sizeMask; + u16_t head; + u16_t tail; + struct zsQueueCell cell[1]; +}; + +#endif //#ifndef _QUEUE_H --- linux-2.6.28.orig/drivers/staging/otus/80211core/ratectrl.c +++ linux-2.6.28/drivers/staging/otus/80211core/ratectrl.c @@ -0,0 +1,874 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "cprecomp.h" +#include "ratectrl.h" + +const u32_t zcRateToPhyCtrl[] = + { + /* 1M, 2M, 5M, 11M , 0 1 2 3*/ + 0x00000, 0x10000, 0x20000, 0x30000, + /* 6M 9M 12M 18M , 4 5 6 7*/ + 0xb0001, 0xf0001, 0xa0001, 0xe0001, + /* 24M 36M 48M 54M , 8 9 10 11*/ + 0x90001, 0xd0001, 0x80001, 0xc0001, + /* MCS0 MCS1 MCS2 MCS3, 12 13 14 15*/ + 0x00002, 0x10002, 0x20002, 0x30002, + /* MCS4 MCS5 MCS6 MCS7, 16 17 18 19*/ + 0x40002, 0x50002, 0x60002, 0x70002, + /* MCS8 MCS9 MCS10 MCS11, 20 21 22 23*/ + 0x80002, 0x90002, 0xa0002, 0xb0002, + /* MCS12 MCS13 MCS14 MCS15, 24 25 26 27*/ + 0xc0002, 0xd0002, 0xe0002, 0xf0002, + /* MCS14SG, MCS15SG MCS7SG , 28 29, 30*/ + 0x800e0002, 0x800f0002, 0x80070002 + }; + + +const u8_t zcHtRateTable[15][4] = + { /*[5G 20MHz] [5G 40MHz] [2.4G 20MHz] [2.4G 40MHz]*/ + { 4, 4, 0, 0}, /*OFDM6M OFDM6M CCK1M CCK1M */ + { 5, 5, 1, 1}, /*OFDM9M OFDM9M CCK2M CCK2M */ + { 13, 12, 2, 2}, /*MCS1 MCS0 CCK5M CCK5M */ + { 14, 13, 3, 3}, /*MCS2 MCS1 CCK11M CCK11M */ + { 15, 14, 13, 12}, /*MCS3 MCS2 MCS1 MCS0 */ + { 16, 15, 14, 13}, /*MCS4 MCS3 MCS2 MCS1 */ + { 23, 16, 15, 14}, /*MCS11 MCS4 MCS3 MCS2 */ + { 24, 23, 16, 15}, /*MCS12 MCS11 MCS4 MCS3 */ + { 25, 24, 23, 16}, /*MCS13 MCS12 MCS11 MCS4 */ + { 26, 25, 24, 23}, /*MCS14 MCS13 MCS12 MCS11 */ + { 27, 26, 25, 24}, /*MCS15 MCS14 MCS13 MCS12 */ + { 0, 27, 26, 25}, /*0 MCS15 MCS14 MCS13 */ + { 0, 29, 27, 26}, /*0 MCS15SG MCS15 MCS14 */ + { 0, 0, 0, 28}, /*0 0 0 MCS14SG*/ + { 0, 0, 0, 29} /*0 0 0 MCS15SG*/ + }; + +const u8_t zcHtOneTxStreamRateTable[15][4] = + { /*[5G 20MHz] [5G 40MHz] [2.4G 20MHz] [2.4G 40MHz]*/ + { 4, 4, 0, 0}, /*OFDM6M OFDM6M CCK1M CCK1M */ + { 5, 5, 1, 1}, /*OFDM9M OFDM9M CCK2M CCK2M */ + { 13, 12, 2, 2}, /*MCS1 MCS0 CCK5M CCK5M */ + { 14, 13, 3, 3}, /*MCS2 MCS1 CCK11M CCK11M */ + { 15, 14, 13, 12}, /*MCS3 MCS2 MCS1 MCS0 */ + { 16, 15, 14, 13}, /*MCS4 MCS3 MCS2 MCS1 */ + { 17, 16, 15, 14}, /*MCS5 MCS4 MCS3 MCS2 */ + { 18, 17, 16, 15}, /*MCS6 MCS5 MCS4 MCS3 */ + { 19, 18, 17, 16}, /*MCS7 MCS6 MCS5 MCS4 */ + { 0, 19, 18, 17}, /*0 MCS7 MCS6 MCS5 */ + { 0, 30, 19, 18}, /*0 MCS7SG MCS7 MCS6 */ + { 0, 0, 0, 19}, /*0 0 0 MCS7 */ + { 0, 0, 0, 30}, /*0 0 0 MCS7SG */ + { 0, 0, 0, 0 }, /*0 0 0 0 */ + { 0, 0, 0, 0 } /*0 0 0 0 */ + }; + +const u16_t zcRate[] = + { + 1, 2, 5, 11, /* 1M, 2M, 5M, 11M , 0 1 2 3*/ + 6, 9, 12, 18, /* 6M 9M 12M 18M , 4 5 6 7*/ + 24, 36, 48, 54, /* 24M 36M 48M 54M , 8 9 10 11*/ + 13, 27, 40, 54, /* MCS0 MCS1 MCS2 MCS3 , 12 13 14 15*/ + 81, 108, 121, 135, /* MCS4 MCS5 MCS6 MCS7 , 16 17 18 19*/ + 27, 54, 81, 108, /* MCS8 MCS9 MCS10 MCS11 , 20 21 22 23*/ + 162, 216, 243, 270, /* MCS12 MCS13 MCS14 MCS15 , 24 25 26 27*/ + 270, 300, 150 /* MCS14SG, MCS15SG, MCS7SG , 28 29 30*/ + }; + +const u16_t PERThreshold[] = + { + 100, 50, 50, 50, /* 1M, 2M, 5M, 11M , 0 1 2 3*/ + 50, 50, 30, 30, /* 6M 9M 12M 18M , 4 5 6 7*/ + 25, 25, 25, 20, /* 24M 36M 48M 54M , 8 9 10 11*/ + 50, 50, 50, 40, /* MCS0 MCS1 MCS2 MCS3 , 12 13 14 15*/ + 30, 30, 30, 30, /* MCS4 MCS5 MCS6 MCS7 , 16 17 18 19*/ + 30, 30, 25, 25, /* MCS8 MCS9 MCS10 MCS11 , 20 21 22 23*/ + 25, 25, 15, 15, /* MCS12 MCS13 MCS14 MCS15 , 24 25 26 27*/ + 15, 15, 10 /* MCS14SG, MCS15SG , 28 29*/ + }; + +const u16_t FailDiff[] = + { + 40, 46, 40, 0, /* 1M, 2M, 5M, 11M , 0 1 2 3*/ + 24, 17, 22, 16, /* 6M 9M 12M 18M , 4 5 6 7*/ + 19, 13, 5, 0, /* 24M 36M 48M 54M , 8 9 10 11*/ + 36, 22, 15, 19, /* MCS0 MCS1 MCS2 MCS3 , 12 13 14 15*/ + 12, 5, 4, 7, /* MCS4 MCS5 MCS6 MCS7 , 16 17 18 19*/ + 0, 0, 0, 0, /* MCS8 MCS9 MCS10 MCS11 , 20 21 22 23*/ + 9, 4, 3, 3, /* MCS12 MCS13 MCS14 MCS15 , 24 25 26 27*/ + 3, 0, 0 /* MCS14SG, MCS15SG , 28 29*/ + }; + + +#ifdef ZM_ENABLE_BA_RATECTRL +u32_t TxMPDU[29]; +u32_t BAFail[29]; +u32_t BAPER[29]; +const u16_t BADiff[] = + { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 361, 220, 151, 187, + 122, 48, 41, 65, + 0, 0, 0, 0, + 88, 33, 27, 25, + 0 + }; +#endif + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfRateCtrlInitCell */ +/* Initialize rate control cell. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* type : 0=>11b, 1=>11a/g, 2=>11n, 3=>11n one Tx stream */ +/* gBand : 1=>2.4G, 0=>5G */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Stephen Chen Atheros Communications, INC. 2007.2 */ +/* */ +/************************************************************************/ +void zfRateCtrlInitCell(zdev_t* dev, struct zsRcCell* rcCell, u8_t type, + u8_t gBand, u8_t SG40) +{ + u8_t i; + u8_t maxrate; + zmw_get_wlan_dev(dev); + + if (SG40) SG40 = 1; + + if (gBand != 0) + { + if (type == 1) //11g + { + for (i=0; i<4; i++) //1M 2M 5M 11M + { + rcCell->operationRateSet[i] = (u8_t)i; + } + for (i=4; i<10; i++) //12M 18M 24M 36M 48M 54M + { + rcCell->operationRateSet[i] = 2+i; + } + rcCell->operationRateCount = 10; + rcCell->currentRateIndex = 5; //18M + } + else if (type == 2) //11ng + { + if (wd->wlanMode == ZM_MODE_AP) //AP 11ng 40M + { + for (i=0; i<15; i++) + { + rcCell->operationRateSet[i] = zcHtRateTable[i][3]; + } + if(!SG40) rcCell->operationRateSet[13] = 27; + rcCell->operationRateCount = 14+SG40; + rcCell->currentRateIndex = 10; + } + else //STA + { + if (wd->sta.htCtrlBandwidth == ZM_BANDWIDTH_40MHZ) //11ng 40M + { + for (i=0; i<15; i++) + { + rcCell->operationRateSet[i] = zcHtRateTable[i][3]; + } + if(!SG40) rcCell->operationRateSet[13] = 27; + rcCell->operationRateCount = 14+SG40; + rcCell->currentRateIndex = 10; + } + else //11ng 20M + { + for (i=0; i<13; i++) + { + rcCell->operationRateSet[i] = zcHtRateTable[i][2]; + } + rcCell->operationRateCount = 13; + rcCell->currentRateIndex = 9; + } + } + } + else if (type == 3) //11ng one Tx stream + { + if (wd->sta.htCtrlBandwidth == ZM_BANDWIDTH_40MHZ) //11ng 40M one Tx stream + { + if(SG40 != 0) + { + maxrate = 13; + } + else + { + maxrate = 12; + } + for (i=0; ioperationRateSet[i] = zcHtOneTxStreamRateTable[i][3]; + } + rcCell->operationRateCount = i; + rcCell->currentRateIndex = ((i+1)*3)/4; + } + else //11ng 20M + { + for (i=0; i<11; i++) + { + rcCell->operationRateSet[i] = zcHtOneTxStreamRateTable[i][2]; + } + rcCell->operationRateCount = i; + rcCell->currentRateIndex = ((i+1)*3)/4; + } + } + else //if (type == 0) //11b + { + for (i=0; i<4; i++) + { + rcCell->operationRateSet[i] = (u8_t)i; + } + rcCell->operationRateCount = 4; + rcCell->currentRateIndex = rcCell->operationRateCount-1; + } + } + else + { + if (type == 2) //11na + { + if (wd->wlanMode == ZM_MODE_AP) //AP 11na 40M + { + for (i=0; i<(12+SG40); i++) + { + rcCell->operationRateSet[i] = zcHtRateTable[i][1]; + } + rcCell->operationRateCount = 12+SG40; + rcCell->currentRateIndex = 8; + } + else //STA + { + if (wd->sta.htCtrlBandwidth == ZM_BANDWIDTH_40MHZ) //11na 40M + { + for (i=0; i<(12+SG40); i++) + { + rcCell->operationRateSet[i] = zcHtRateTable[i][1]; + } + rcCell->operationRateCount = 12+SG40; + rcCell->currentRateIndex = 8; + } + else //11na 20M + { + for (i=0; i<11; i++) + { + rcCell->operationRateSet[i] = zcHtRateTable[i][0]; + } + rcCell->operationRateCount = 11; + rcCell->currentRateIndex = 7; + } + } + } + else if (type == 3) //11na one Tx stream + { + if (wd->sta.htCtrlBandwidth == ZM_BANDWIDTH_40MHZ) //11na 40M one Tx stream + { + if(SG40 != 0) + { + maxrate = 11; + } + else + { + maxrate = 10; + } + for (i=0; ioperationRateSet[i] = zcHtOneTxStreamRateTable[i][1]; + } + rcCell->operationRateCount = i; + rcCell->currentRateIndex = ((i+1)*3)/4; + } + else //11ng 20M + { + for (i=0; i<9; i++) + { + rcCell->operationRateSet[i] = zcHtOneTxStreamRateTable[i][0]; + } + rcCell->operationRateCount = i; + rcCell->currentRateIndex = ((i+1)*3)/4; + } + } + else //if (type == 1) //11a + { + for (i=0; i<8; i++) //6M 9M 12M 18M 24M 36M 48M 54M + { + rcCell->operationRateSet[i] = i+4; + } + rcCell->operationRateCount = 8; + rcCell->currentRateIndex = 4; //24M + } + } + + rcCell->flag = 0; + rcCell->txCount = 0; + rcCell->failCount = 0; + rcCell->currentRate = rcCell->operationRateSet[rcCell->currentRateIndex]; + rcCell->lasttxCount = 0; + rcCell->lastTime = wd->tick; + rcCell->probingTime = wd->tick; + for (i=0; iPER[i] = 0; + wd->txMPDU[i] = wd->txFail[i] = 0; + } + wd->probeCount = 0; + wd->probeInterval = 0; +#ifdef ZM_ENABLE_BA_RATECTRL + for (i=0; i<29; i++) { + TxMPDU[i]=0; + BAFail[i]=0; + BAPER[i]=0; + } +#endif + return; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfRateCtrlGetHigherRate */ +/* Get a higher rate. */ +/* */ +/* INPUTS */ +/* rcCell : rate control cell */ +/* */ +/* OUTPUTS */ +/* rate */ +/* */ +/* AUTHOR */ +/* Stephen Chen Atheros Communications, INC. 2007.2 */ +/* */ +/************************************************************************/ +u8_t zfRateCtrlGetHigherRate(struct zsRcCell* rcCell) +{ + u8_t rateIndex; + + rateIndex = rcCell->currentRateIndex + + (((rcCell->currentRateIndex+1) < rcCell->operationRateCount)?1:0); + return rcCell->operationRateSet[rateIndex]; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfRateCtrlNextLowerRate */ +/* Get a lower rate. */ +/* */ +/* INPUTS */ +/* rcCell : rate control cell */ +/* */ +/* OUTPUTS */ +/* rate */ +/* */ +/* AUTHOR */ +/* Stephen Chen Atheros Communications, INC. 2007.2 */ +/* */ +/************************************************************************/ +u8_t zfRateCtrlNextLowerRate(zdev_t* dev, struct zsRcCell* rcCell) +{ + zmw_get_wlan_dev(dev); + if (rcCell->currentRateIndex > 0) + { + rcCell->currentRateIndex--; + rcCell->currentRate = rcCell->operationRateSet[rcCell->currentRateIndex]; + } + zm_msg1_tx(ZM_LV_0, "Lower Tx Rate=", rcCell->currentRate); + //DbgPrint("Lower Tx Rate=%d", rcCell->currentRate); + rcCell->failCount = rcCell->txCount = 0; + rcCell->lasttxCount = 0; + rcCell->lastTime = wd->tick; + return rcCell->currentRate; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfRateCtrlRateDiff */ +/* Rate difference. */ +/* */ +/* INPUTS */ +/* rcCell : rate control cell */ +/* retryRate : retry rate */ +/* */ +/* OUTPUTS */ +/* rate difference */ +/* */ +/* AUTHOR */ +/* Stephen Chen Atheros Communications, INC. 2007.2 */ +/* */ +/************************************************************************/ +u8_t zfRateCtrlRateDiff(struct zsRcCell* rcCell, u8_t retryRate) +{ + u16_t i; + + /* Find retryRate in operationRateSet[] */ + for (i=0; ioperationRateCount; i++) + { + if (retryRate == rcCell->operationRateSet[i]) + { + if (i < rcCell->currentRateIndex) + { + return ((rcCell->currentRateIndex - i)+1)>>1; + } + else if (i == rcCell->currentRateIndex == 0) + { + return 1; + } + else + { + return 0; + } + } + } + /* TODO : retry rate not in operation rate set */ + zm_msg1_tx(ZM_LV_0, "Not in operation rate set:", retryRate); + return 1; + +} + +u32_t zfRateCtrlUDPTP(zdev_t* dev, u16_t Rate, u32_t PER) { + if ((PER < 100) && (Rate > 0) && PER) + return 1168000/(((12304/Rate)+197)*(100+100*PER/(100-PER))); + else + return 0; +} + +u8_t zfRateCtrlFindMaxUDPTP(zdev_t* dev, struct zsRcCell* rcCell) { + u8_t i, maxIndex=0, rateIndex; + u32_t max=0, UDPThroughput; + + zmw_get_wlan_dev(dev); + + rateIndex = zm_agg_min(rcCell->currentRateIndex+3, rcCell->operationRateCount-1); + for (i=rcCell->currentRateIndex; i < rateIndex; i++) { + UDPThroughput = zfRateCtrlUDPTP(dev, zcRate[rcCell->operationRateSet[i]], + wd->PER[rcCell->operationRateSet[i]]); + if (max < UDPThroughput) { + max = UDPThroughput; + maxIndex = i; + } + } + + return rcCell->operationRateSet[maxIndex]; +} +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfRateCtrlGetTxRate */ +/* Get transmission rate. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* rcCell : rate control cell */ +/* probing : rate probing flag */ +/* */ +/* OUTPUTS */ +/* Tx rate */ +/* */ +/* AUTHOR */ +/* Stephen Chen Atheros Communications, INC. 2007.2 */ +/* */ +/************************************************************************/ +u16_t zfRateCtrlGetTxRate(zdev_t* dev, struct zsRcCell* rcCell, u16_t* probing) +{ + u8_t newRate, highRate; + zmw_get_wlan_dev(dev); + + zm_msg1_tx(ZM_LV_3, "txCount=", rcCell->txCount); + zm_msg1_tx(ZM_LV_3, "probingTime=", rcCell->probingTime); + zm_msg1_tx(ZM_LV_3, "tick=", wd->tick); + *probing = 0; + newRate = rcCell->currentRate; + + if (wd->probeCount && (wd->probeCount < wd->success_probing)) + { + if (wd->probeInterval < 50) + { + wd->probeInterval++; + } + else + { + wd->probeInterval++; + if (wd->probeInterval > 52) //probe 51, 52, 53 three packets every 50 packets + { + wd->probeInterval = 0; + } + newRate=zfRateCtrlGetHigherRate(rcCell); + *probing = 1; + wd->probeCount++; + rcCell->probingTime = wd->tick; + } + } + /* Accumulate at least 1000ms and 8 packets or Accumulate over 1K packets */ + else if ((((wd->tick - rcCell->probingTime) > (ZM_RATE_CTRL_PROBING_INTERVAL_MS/ZM_MS_PER_TICK)) + && (rcCell->txCount >= ZM_RATE_CTRL_MIN_PROBING_PACKET)) + || (rcCell->txCount >= 1000)) + { +#ifndef ZM_DISABLE_RATE_CTRL + /* PER = fail/total */ + wd->probeCount = 0; + wd->probeSuccessCount = 0; + if (wd->txMPDU[rcCell->currentRate] != 0) { + wd->PER[rcCell->currentRate] = zm_agg_min(100, + (wd->txFail[rcCell->currentRate]*100)/wd->txMPDU[rcCell->currentRate]); + if (!wd->PER[rcCell->currentRate]) wd->PER[rcCell->currentRate] ++; + } + + /* if PER < threshold, do rate probing, return probing rate */ + if ((wd->PER[rcCell->currentRate] <= (ZM_RATE_PROBING_THRESHOLD+15)) || + ((rcCell->currentRate <= 16) && + ((wd->PER[rcCell->currentRate]/2) <= ZM_RATE_PROBING_THRESHOLD))) + { + if ((newRate=zfRateCtrlGetHigherRate(rcCell)) != rcCell->currentRate) + { + *probing = 1; + wd->probeCount++; + wd->probeInterval = 0; + wd->success_probing = + (rcCell->currentRate <= 16)? (ZM_RATE_SUCCESS_PROBING/2) : ZM_RATE_SUCCESS_PROBING; + //DbgPrint("Start Probing"); + zm_msg1_tx(ZM_LV_0, "Probing Rate=", newRate); + } + } +#endif + + zm_msg0_tx(ZM_LV_1, "Diminish counter"); + rcCell->failCount = rcCell->failCount>>1; + rcCell->txCount = rcCell->txCount>>1; + wd->txFail[rcCell->currentRate] = wd->txFail[rcCell->currentRate] >> 1; + wd->txMPDU[rcCell->currentRate] = wd->txMPDU[rcCell->currentRate] >> 1; + + + if (rcCell->currentRate > 15) { + highRate = zfRateCtrlGetHigherRate(rcCell); + if ((highRate != rcCell->currentRate) && wd->PER[highRate] && + ((wd->PER[rcCell->currentRate] + FailDiff[rcCell->currentRate]) > + wd->PER[highRate])) { + //DbgPrint("PER compare force raise rate to %d", highRate); + wd->probeSuccessCount = wd->probeCount = ZM_RATE_SUCCESS_PROBING; + zfRateCtrlTxSuccessEvent(dev, rcCell, highRate); + } + } + else { + highRate = zfRateCtrlFindMaxUDPTP(dev, rcCell); + if (rcCell->currentRate < highRate) { + //DbgPrint("UDP Throughput compare force raise rate to %d", highRate); + wd->probeSuccessCount = wd->probeCount = ZM_RATE_SUCCESS_PROBING; + zfRateCtrlTxSuccessEvent(dev, rcCell, highRate); + } + } + rcCell->probingTime = wd->tick; + } + + if( (wd->tick > 1000) + && ((wd->tick - rcCell->lastTime) > 3840) ) + { + if (rcCell->lasttxCount < 70) + { + rcCell->failCount = rcCell->failCount>>1; + rcCell->txCount = rcCell->txCount>>1; + wd->txFail[rcCell->currentRate] = wd->txFail[rcCell->currentRate] >> 1; + wd->txMPDU[rcCell->currentRate] = wd->txMPDU[rcCell->currentRate] >> 1; + + rcCell->failCount = (rcCell->failCount < rcCell->txCount)? + rcCell->failCount : rcCell->txCount; + wd->txFail[rcCell->currentRate] = (wd->txFail[rcCell->currentRate] < wd->txMPDU[rcCell->currentRate])? + wd->txFail[rcCell->currentRate] : wd->txMPDU[rcCell->currentRate]; + } + + rcCell->lastTime = wd->tick; + rcCell->lasttxCount = 0; + } + + rcCell->txCount++; + rcCell->lasttxCount++; + wd->txMPDU[rcCell->currentRate]++; + zm_msg1_tx(ZM_LV_1, "Get Tx Rate=", newRate); + return newRate; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfRateCtrlTxFailEvent */ +/* Tx fail event. Calculate PER and lower Tx rate if under */ +/* PER under threshold. */ +/* */ +/* INPUTS */ +/* rcCell : rate control cell */ +/* retryRate : retry rate */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Stephen Chen Atheros Communications, INC. 2007.2 */ +/* */ +/************************************************************************/ +void zfRateCtrlTxFailEvent(zdev_t* dev, struct zsRcCell* rcCell, u8_t aggRate, u32_t retryRate) +{ + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + +#ifndef ZM_DISABLE_RATE_CTRL + //DbgPrint("aggRate=%d, retryRate=%d", aggRate, retryRate); + if (aggRate && (aggRate != rcCell->currentRate)) { + wd->txFail[aggRate] += retryRate; + return; + } + + if (!aggRate) { + retryRate = (zfRateCtrlRateDiff(rcCell, (u8_t)retryRate)+1)>>1; + if (rcCell->currentRate <12) //legacy rate + { + retryRate*=2; + } + } + rcCell->failCount += retryRate; + wd->txFail[rcCell->currentRate] += retryRate; + + //DbgPrint("failCount=%d", rcCell->failCount); + if (rcCell->failCount > ZM_MIN_RATE_FAIL_COUNT) + { + if (wd->txMPDU[rcCell->currentRate] != 0) { + wd->PER[rcCell->currentRate] = zm_agg_min(100, + (wd->txFail[rcCell->currentRate]*100)/wd->txMPDU[rcCell->currentRate]); + if (!wd->PER[rcCell->currentRate]) wd->PER[rcCell->currentRate] ++; + } + //zm_msg1_tx(ZM_LV_1, "PER=", per); + //DbgPrint("PER=%d, txFail=%d, txMPDU=%d", wd->PER[rcCell->currentRate], wd->txFail[rcCell->currentRate], wd->txMPDU[rcCell->currentRate]); + if (wd->PER[rcCell->currentRate] > PERThreshold[rcCell->currentRate]) + { + /* Lower Tx Rate if PER < THRESHOLD */ + zfRateCtrlNextLowerRate(dev, rcCell); + rcCell->flag |= ZM_RC_TRAINED_BIT; + + // Resolve compatibility problem with Marvell + if(rcCell->currentRate == 15) + { + zmw_leave_critical_section(dev); + zfHpSetAggPktNum(dev, 8); + zmw_enter_critical_section(dev); + } + + wd->txFail[rcCell->currentRate] = wd->txFail[rcCell->currentRate] >> 1; + wd->txMPDU[rcCell->currentRate] = wd->txMPDU[rcCell->currentRate] >> 1; + + wd->probeCount = wd->probeSuccessCount = 0; + } + } + +#endif + return; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfRateCtrlTxSuccessEvent */ +/* Tx success event. Raise Tx rate because rate probing success. */ +/* */ +/* INPUTS */ +/* rcCell : rate control cell */ +/* successRate : success rate */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Stephen Chen Atheros Communications, INC. 2007.2 */ +/* */ +/************************************************************************/ +void zfRateCtrlTxSuccessEvent(zdev_t* dev, struct zsRcCell* rcCell, u8_t successRate) +{ + /* Raise Tx Rate */ + u16_t i, PERProbe; + u16_t pcount; + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + //DbgPrint("Probing successRate=%d", successRate); + /* Find successRate in operationRateSet[] */ + wd->probeSuccessCount++; + if (wd->probeCount < wd->success_probing) + { + return; + } + + pcount = wd->probeCount; + if (pcount != 0) + { + PERProbe = wd->probeSuccessCount * 100 / pcount; + } + else + { + PERProbe = 1; + } + + if (PERProbe < ((rcCell->currentRate < 16)? 80:100)) + { + return; + } + //DbgPrint("wd->probeCount=%d, wd->probeSuccessCount=%d", wd->probeCount, wd->probeSuccessCount); + wd->probeCount = wd->probeSuccessCount = 0; + for (i=0; ioperationRateCount; i++) + { + if (successRate == rcCell->operationRateSet[i]) + { + if (i > rcCell->currentRateIndex) + { + /* Raise current Tx rate */ + zm_msg1_tx(ZM_LV_0, "Raise Tx Rate=", successRate); + //DbgPrint("Raise Tx Rate=%d", successRate); + + // Resolve compatibility problem with Marvell + if((rcCell->currentRate <= 15) && (successRate > 15)) + { + zmw_leave_critical_section(dev); + zfHpSetAggPktNum(dev, 16); + zmw_enter_critical_section(dev); + } + + rcCell->currentRate = successRate; + rcCell->currentRateIndex = (u8_t)i; + rcCell->failCount = rcCell->txCount = 0; + rcCell->lasttxCount = 0; + rcCell->lastTime = wd->tick; + wd->txFail[rcCell->currentRate] = wd->txFail[rcCell->currentRate] >> 1; + wd->txMPDU[rcCell->currentRate] = wd->txMPDU[rcCell->currentRate] >> 1; + } + } + } + + return; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfRateCtrlRxRssiEvent */ +/* Rx RSSI event. Calculate RSSI moving average, accelarate */ +/* rate probing if RSSI variation over threshold. */ +/* */ +/* INPUTS */ +/* rcCell : rate control cell */ +/* successRate : success rate */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Stephen Chen Atheros Communications, INC. 2007.2 */ +/* */ +/************************************************************************/ +void zfRateCtrlRxRssiEvent(struct zsRcCell* rcCell, u16_t rxRssi) +{ + /* if delta(rcCell->rxRssi, rxRssi) > ZM_RATE_CTRL_RSSI_VARIATION */ + if ((rcCell->rxRssi - rxRssi) > ZM_RATE_CTRL_RSSI_VARIATION) + { + /* Accelerate rate probing via decreaing rcCell->probingTime */ + rcCell->probingTime -= ZM_RATE_CTRL_PROBING_INTERVAL_MS/ZM_MS_PER_TICK; + } + + /* Update RSSI moving average */ + rcCell->rxRssi = (((rcCell->rxRssi*7) + rxRssi)+4) >> 3; + return; +} + + +#ifdef ZM_ENABLE_BA_RATECTRL +u8_t HigherRate(u8_t Rate) { + if (Rate < 28) Rate++; //28=MCS15SG, 27=MCS15, 26=MCS14, 25=MCS13 + if (Rate > 28) Rate = 28; + while ((Rate >= 20) && (Rate <= 23)) { + Rate ++; + } + return Rate; +} + +u8_t LowerRate(u8_t Rate) { + if (Rate > 1) Rate--; + while ((Rate >= 20) && (Rate <= 23)) { + Rate --; + } + return Rate; +} + +u8_t RateMapToRateIndex(u8_t Rate, struct zsRcCell* rcCell) { + u8_t i; + for (i=0; ioperationRateCount; i++) { + if (Rate == rcCell->operationRateSet[i]) { + return i; + } + } + return 0; +} + +void zfRateCtrlAggrSta(zdev_t* dev) { + u8_t RateIndex, Rate; + u8_t HRate; + u8_t LRate; + u32_t RateCtrlTxMPDU, RateCtrlBAFail; + zmw_get_wlan_dev(dev); + + RateIndex = wd->sta.oppositeInfo[0].rcCell.currentRateIndex; + Rate = wd->sta.oppositeInfo[0].rcCell.operationRateSet[RateIndex]; + + TxMPDU[Rate] = (TxMPDU[Rate] / 5) + (wd->commTally.RateCtrlTxMPDU * 4 / 5); + BAFail[Rate] = (BAFail[Rate] / 5) + (wd->commTally.RateCtrlBAFail * 4 / 5); + RateCtrlTxMPDU = wd->commTally.RateCtrlTxMPDU; + RateCtrlBAFail = wd->commTally.RateCtrlBAFail; + wd->commTally.RateCtrlTxMPDU = 0; + wd->commTally.RateCtrlBAFail = 0; + if (TxMPDU[Rate] > 0) { + BAPER[Rate] = BAFail[Rate] * 1000 / TxMPDU[Rate]; //PER*1000 + BAPER[Rate] = (BAPER[Rate]>0)? BAPER[Rate]:1; + } + else { + return; + } + + HRate = HigherRate(Rate); + LRate = LowerRate(Rate); + if (BAPER[Rate]>200) { + if ((RateCtrlTxMPDU > 100) && (BAPER[Rate]<300) && (HRate != Rate) && BAPER[HRate] && + (BAPER[HRate] < BAPER[Rate] + BADiff[Rate])) { + Rate = HRate; + //DbgPrint("Rate improved to %d", Rate); + } + else { + Rate = LRate; + //DbgPrint("Rate decreased to %d", Rate); + } + } + else if (BAPER[Rate] && BAPER[Rate]<100) { + if (RateCtrlTxMPDU > 100) { + Rate = HRate; + //DbgPrint("Rate improved to %d", Rate); + } + } + wd->sta.oppositeInfo[0].rcCell.currentRate = Rate; + wd->sta.oppositeInfo[0].rcCell.currentRateIndex = RateMapToRateIndex(Rate, &wd->sta.oppositeInfo[0].rcCell); +} +#endif --- linux-2.6.28.orig/drivers/staging/otus/80211core/cwep.c +++ linux-2.6.28/drivers/staging/otus/80211core/cwep.c @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* */ +/* Module Name : cwep.c */ +/* */ +/* Abstract */ +/* This module contains Tx and Rx functions. */ +/* */ +/* NOTES */ +/* None */ +/* */ +/************************************************************************/ +#include "cprecomp.h" + +u32_t crc32_tab[] = +{ + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; + +void zfWEPEncrypt(zdev_t *dev, zbuf_t *buf, u8_t *snap, u16_t snapLen, u16_t offset, u8_t keyLen, u8_t* WepKey, u8_t *iv) +{ + u8_t S[256],S2[256]; + u16_t ui; + u16_t i; + u16_t j; + u8_t temp; + u8_t K; + u32_t ltemp; + u16_t len; + u32_t icv; + u8_t key[32]; + + key[0] = iv[0]; + key[1] = iv[1]; + key[2] = iv[2]; + + /* Append Wep Key after IV */ + zfMemoryCopy(&key[3], WepKey, keyLen); + + keyLen += 3; + + for(i = 0; i < 256; i++) + { + S[i] = (u8_t)i; + S2[i] = key[i&(keyLen-1)]; + } + + j = 0; + for(i = 0; i < 256; i++) + { + j = (j + S[i] + S2[i]) ; + j&=255 ; + + // Swap S[i] and S[j] + temp = S[i]; + S[i] = S[j]; + S[j] = temp; + } + + i = j = 0; + icv = -1; + + /* For Snap Header */ + for (ui = 0; ui < snapLen; ui++) + { + u8_t In; + + i++; + i &= 255; + j += S[i]; + j &= 255; + + // Swap S[i] and S[j] + temp = S[i]; + S[i] = S[j]; + S[j] = temp; +// temp = (S[i] + temp) & 255; + temp += S[i]; + temp &=255; + K = S[temp]; // Key used to Xor with input data + + In = snap[ui]; + icv = (icv>>8) ^ crc32_tab[(icv^In)&0xff]; + + snap[ui] = In ^ K; + //zmw_tx_buf_writeb(dev, buf, ui, In ^ K); + } + + len = zfwBufGetSize(dev, buf); + + for (ui = offset; ui < len; ui++) + { + u8_t In; + + i++; + i &= 255; + j += S[i]; + j &= 255; + + // Swap S[i] and S[j] + temp = S[i]; + S[i] = S[j]; + S[j] = temp; +// temp = (S[i] + temp) & 255; + temp += S[i]; + temp &=255; + K = S[temp]; // Key used to Xor with input data + + In = zmw_tx_buf_readb(dev, buf, ui); + icv = (icv>>8) ^ crc32_tab[(icv^In)&0xff]; + + zmw_tx_buf_writeb(dev, buf, ui, In ^ K); + } //End of for (ui = 0; ui < Num_Bytes; ui++) + + icv = ~(icv); + ltemp = (u32_t) icv; + + for (ui = 0; ui < 4; ui++) + { + i ++; + i &= 255; + j += S[i]; + j &= 255; + + // Swap S[i] and S[j] + temp = S[i]; + S[i] = S[j]; + S[j] = temp; + temp += S[i]; + temp &= 255; + K = S[temp]; // Key used to Xor with input data + + //*Out++ = (u8_t)(ltemp ^ K)&0xff; + zmw_tx_buf_writeb(dev, buf, len+ui, (u8_t)(ltemp ^ K)&0xff); + ltemp >>= 8; + } + + zfwBufSetSize(dev, buf, len+4); +} + +u16_t zfWEPDecrypt(zdev_t *dev, zbuf_t *buf, u16_t offset, u8_t keyLen, u8_t* WepKey, u8_t *iv) +{ + u8_t S[256]; + u8_t S2[256]; + u16_t ui; + u16_t i; + u16_t j; + u32_t icv_tmp; + u32_t *icv; + u32_t rxbuf_icv; + u8_t temp; + u8_t K; + u16_t len; + u8_t key[32]; + + /* Retrieve IV */ + key[0] = iv[0]; + key[1] = iv[1]; + key[2] = iv[2]; + + /* Append Wep Key after IV */ + zfMemoryCopy(&key[3], WepKey, keyLen); + + keyLen += 3; + + for(i = 0; i < 256; i++) + { + S[i] = (u8_t)i; + S2[i] = key[i&(keyLen-1)]; + } + + j = 0; + for(i = 0; i < 256; i++) + { + j = (j + S[i] + S2[i]); + j&=255 ; + + // Swap S[i] and S[j] + temp = S[i]; + S[i] = S[j]; + S[j] = temp; + } + + i = j = 0; + + len = zfwBufGetSize(dev, buf); + + for (ui = offset; ui < len; ui++) + { + u8_t In; + + i++; + i &= 255; + j += S[i]; + j &= 255; + + // Swap S[i] and S[j] + temp = S[i]; + S[i] = S[j]; + S[j] = temp; +// temp = (S[i] + temp) & 255; + temp += S[i]; + temp &=255; + K = S[temp]; // Key used to Xor with input data + + In = zmw_rx_buf_readb(dev, buf, ui); + + zmw_rx_buf_writeb(dev, buf, ui, In ^ K); + } //End of for (ui = 0; ui < Num_Bytes; ui++) + + icv = &icv_tmp; + *icv = -1; + + for (ui = offset; ui < len - 4; ui++) + { + u8_t In; + + In = zmw_rx_buf_readb(dev, buf, ui); + *icv = (*icv>>8) ^ crc32_tab[(*icv^In)&0xff]; + } + + *icv = ~*icv; + + rxbuf_icv = (zmw_rx_buf_readb(dev, buf, len-4) | + zmw_rx_buf_readb(dev, buf, len-3) << 8 | + zmw_rx_buf_readb(dev, buf, len-2) << 16 | + zmw_rx_buf_readb(dev, buf, len-1) << 24); + + if (*icv != rxbuf_icv) + { + return ZM_ICV_FAILURE; + } + + return ZM_ICV_SUCCESS; +} --- linux-2.6.28.orig/drivers/staging/otus/80211core/cfunc.c +++ linux-2.6.28/drivers/staging/otus/80211core/cfunc.c @@ -0,0 +1,1227 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "cprecomp.h" + +u8_t zfQueryOppositeRate(zdev_t* dev, u8_t dst_mac[6], u8_t frameType) +{ + zmw_get_wlan_dev(dev); + + /* For AP's rate adaption */ + if ( wd->wlanMode == ZM_MODE_AP ) + { + return 0; + } + + /* For STA's rate adaption */ + if ( (frameType & 0x0c) == ZM_WLAN_DATA_FRAME ) + { + if ( ZM_IS_MULTICAST(dst_mac) ) + { + return wd->sta.mTxRate; + } + else + { + return wd->sta.uTxRate; + } + } + + return wd->sta.mmTxRate; +} + +void zfCopyToIntTxBuffer(zdev_t* dev, zbuf_t* buf, u8_t* src, + u16_t offset, u16_t length) +{ + u16_t i; + + for(i=0; icommTally.Hw_UnderrunCnt += (0xFFFF & rsp[1]); + wd->commTally.Hw_TotalRxFrm += rsp[2]; + wd->commTally.Hw_CRC32Cnt += rsp[3]; + wd->commTally.Hw_CRC16Cnt += rsp[4]; + #ifdef ZM_ENABLE_NATIVE_WIFI + /* These code are here to satisfy Vista DTM */ + wd->commTally.Hw_DecrypErr_UNI += ((rsp[5]>50) && (rsp[5]<60))?50:rsp[5]; + #else + wd->commTally.Hw_DecrypErr_UNI += rsp[5]; + #endif + wd->commTally.Hw_RxFIFOOverrun += rsp[6]; + wd->commTally.Hw_DecrypErr_Mul += rsp[7]; + wd->commTally.Hw_RetryCnt += rsp[8]; + wd->commTally.Hw_TotalTxFrm += rsp[9]; + wd->commTally.Hw_RxTimeOut +=rsp[10]; + + wd->commTally.Tx_MPDU += rsp[11]; + wd->commTally.BA_Fail += rsp[12]; + wd->commTally.Hw_Tx_AMPDU += rsp[13]; + wd->commTally.Hw_Tx_MPDU += rsp[14]; + wd->commTally.RateCtrlTxMPDU += rsp[11]; + wd->commTally.RateCtrlBAFail += rsp[12]; + } + else + { + wd->commTally.Hw_RxMPDU += rsp[1]; + wd->commTally.Hw_RxDropMPDU += rsp[2]; + wd->commTally.Hw_RxDelMPDU += rsp[3]; + + wd->commTally.Hw_RxPhyMiscError += rsp[4]; + wd->commTally.Hw_RxPhyXRError += rsp[5]; + wd->commTally.Hw_RxPhyOFDMError += rsp[6]; + wd->commTally.Hw_RxPhyCCKError += rsp[7]; + wd->commTally.Hw_RxPhyHTError += rsp[8]; + wd->commTally.Hw_RxPhyTotalCount += rsp[9]; + } + + zmw_leave_critical_section(dev); + + if (id == 0) + { + zm_msg1_mm(ZM_LV_1, "rsplen =", rsp[0]); + zm_msg1_mm(ZM_LV_1, "Hw_UnderrunCnt = ", (0xFFFF & rsp[1])); + zm_msg1_mm(ZM_LV_1, "Hw_TotalRxFrm = ", rsp[2]); + zm_msg1_mm(ZM_LV_1, "Hw_CRC32Cnt = ", rsp[3]); + zm_msg1_mm(ZM_LV_1, "Hw_CRC16Cnt = ", rsp[4]); + zm_msg1_mm(ZM_LV_1, "Hw_DecrypErr_UNI = ", rsp[5]); + zm_msg1_mm(ZM_LV_1, "Hw_RxFIFOOverrun = ", rsp[6]); + zm_msg1_mm(ZM_LV_1, "Hw_DecrypErr_Mul = ", rsp[7]); + zm_msg1_mm(ZM_LV_1, "Hw_RetryCnt = ", rsp[8]); + zm_msg1_mm(ZM_LV_1, "Hw_TotalTxFrm = ", rsp[9]); + zm_msg1_mm(ZM_LV_1, "Hw_RxTimeOut = ", rsp[10]); + zm_msg1_mm(ZM_LV_1, "Tx_MPDU = ", rsp[11]); + zm_msg1_mm(ZM_LV_1, "BA_Fail = ", rsp[12]); + zm_msg1_mm(ZM_LV_1, "Hw_Tx_AMPDU = ", rsp[13]); + zm_msg1_mm(ZM_LV_1, "Hw_Tx_MPDU = ", rsp[14]); + } + else + { + zm_msg1_mm(ZM_LV_1, "rsplen = ", rsp[0]); + zm_msg1_mm(ZM_LV_1, "Hw_RxMPDU = ", (0xFFFF & rsp[1])); + zm_msg1_mm(ZM_LV_1, "Hw_RxDropMPDU = ", rsp[2]); + zm_msg1_mm(ZM_LV_1, "Hw_RxDelMPDU = ", rsp[3]); + zm_msg1_mm(ZM_LV_1, "Hw_RxPhyMiscError = ", rsp[4]); + zm_msg1_mm(ZM_LV_1, "Hw_RxPhyXRError = ", rsp[5]); + zm_msg1_mm(ZM_LV_1, "Hw_RxPhyOFDMError = ", rsp[6]); + zm_msg1_mm(ZM_LV_1, "Hw_RxPhyCCKError = ", rsp[7]); + zm_msg1_mm(ZM_LV_1, "Hw_RxPhyHTError = ", rsp[8]); + zm_msg1_mm(ZM_LV_1, "Hw_RxPhyTotalCount = ", rsp[9]); + } + +} + +/* Timer related functions */ +void zfTimerInit(zdev_t* dev) +{ + u8_t i; + + zmw_get_wlan_dev(dev); + + zm_debug_msg0(""); + + wd->timerList.freeCount = ZM_MAX_TIMER_COUNT; + wd->timerList.head = &(wd->timerList.list[0]); + wd->timerList.tail = &(wd->timerList.list[ZM_MAX_TIMER_COUNT-1]); + wd->timerList.head->pre = NULL; + wd->timerList.head->next = &(wd->timerList.list[1]); + wd->timerList.tail->pre = &(wd->timerList.list[ZM_MAX_TIMER_COUNT-2]); + wd->timerList.tail->next = NULL; + + for( i=1; i<(ZM_MAX_TIMER_COUNT-1); i++ ) + { + wd->timerList.list[i].pre = &(wd->timerList.list[i-1]); + wd->timerList.list[i].next = &(wd->timerList.list[i+1]); + } + + wd->bTimerReady = TRUE; +} + + +u16_t zfTimerSchedule(zdev_t* dev, u16_t event, u32_t tick) +{ + struct zsTimerEntry *pFreeEntry; + struct zsTimerEntry *pEntry; + u8_t i, count; + + zmw_get_wlan_dev(dev); + + if ( wd->timerList.freeCount == 0 ) + { + zm_debug_msg0("no more timer"); + return 1; + } + + //zm_debug_msg2("event = ", event); + //zm_debug_msg1("target tick = ", wd->tick + tick); + + count = ZM_MAX_TIMER_COUNT - wd->timerList.freeCount; + + if ( count == 0 ) + { + wd->timerList.freeCount--; + wd->timerList.head->event = event; + wd->timerList.head->timer = wd->tick + tick; + //zm_debug_msg1("free timer count = ", wd->timerList.freeCount); + + return 0; + } + + pFreeEntry = wd->timerList.tail; + pFreeEntry->timer = wd->tick + tick; + pFreeEntry->event = event; + wd->timerList.tail = pFreeEntry->pre; + pEntry = wd->timerList.head; + + for( i=0; itimer > pFreeEntry->timer )&& + ((pEntry->timer - pFreeEntry->timer) < 1000000000) ) + { + if ( i != 0 ) + { + pFreeEntry->pre = pEntry->pre; + pFreeEntry->pre->next = pFreeEntry; + } + else + { + pFreeEntry->pre = NULL; + } + + pEntry->pre = pFreeEntry; + pFreeEntry->next = pEntry; + break; + } + + pEntry = pEntry->next; + } + + if ( i == 0 ) + { + wd->timerList.head = pFreeEntry; + } + + if ( i == count ) + { + pFreeEntry->pre = pEntry->pre; + pFreeEntry->pre->next = pFreeEntry; + pEntry->pre = pFreeEntry; + pFreeEntry->next = pEntry; + } + + wd->timerList.freeCount--; + //zm_debug_msg1("free timer count = ", wd->timerList.freeCount); + + return 0; +} + +u16_t zfTimerCancel(zdev_t* dev, u16_t event) +{ + struct zsTimerEntry *pEntry; + u8_t i, count; + + zmw_get_wlan_dev(dev); + + //zm_debug_msg2("event = ", event); + //zm_debug_msg1("free timer count(b) = ", wd->timerList.freeCount); + + pEntry = wd->timerList.head; + count = ZM_MAX_TIMER_COUNT - wd->timerList.freeCount; + + for( i=0; ievent == event ) + { + if ( pEntry == wd->timerList.head ) + { /* remove head entry */ + wd->timerList.head = pEntry->next; + wd->timerList.tail->next = pEntry; + pEntry->pre = wd->timerList.tail; + wd->timerList.tail = pEntry; + pEntry = wd->timerList.head; + } + else + { /* remove non-head entry */ + pEntry->pre->next = pEntry->next; + pEntry->next->pre = pEntry->pre; + wd->timerList.tail->next = pEntry; + pEntry->pre = wd->timerList.tail; + wd->timerList.tail = pEntry; + pEntry = pEntry->next; + } + + wd->timerList.freeCount++; + } + else + { + pEntry = pEntry->next; + } + } + + //zm_debug_msg1("free timer count(a) = ", wd->timerList.freeCount); + + return 0; +} + +void zfTimerClear(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + wd->timerList.freeCount = ZM_MAX_TIMER_COUNT; +} + +u16_t zfTimerCheckAndHandle(zdev_t* dev) +{ + struct zsTimerEntry *pEntry; + struct zsTimerEntry *pTheLastEntry = NULL; + u16_t event[ZM_MAX_TIMER_COUNT]; + u8_t i, j=0, count; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + if ( !wd->bTimerReady ) + { + return 0; + } + + zmw_enter_critical_section(dev); + + pEntry = wd->timerList.head; + count = ZM_MAX_TIMER_COUNT - wd->timerList.freeCount; + + for( i=0; itimer > wd->tick )&& + ((pEntry->timer - wd->tick) < 1000000000) ) + { + break; + } + + event[j++] = pEntry->event; + pTheLastEntry = pEntry; + pEntry = pEntry->next; + } + + if ( j > 0 ) + { + wd->timerList.tail->next = wd->timerList.head; + wd->timerList.head->pre = wd->timerList.tail; + wd->timerList.head = pEntry; + wd->timerList.tail = pTheLastEntry; + wd->timerList.freeCount += j; + //zm_debug_msg1("free timer count = ", wd->timerList.freeCount); + } + + zmw_leave_critical_section(dev); + + zfProcessEvent(dev, event, j); + + return 0; +} + +u32_t zfCoreSetKey(zdev_t* dev, u8_t user, u8_t keyId, u8_t type, + u16_t* mac, u32_t* key) +{ + u32_t ret; + + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + wd->sta.flagKeyChanging++; + zm_debug_msg1(" zfCoreSetKey++++ ", wd->sta.flagKeyChanging); + zmw_leave_critical_section(dev); + + ret = zfHpSetKey(dev, user, keyId, type, mac, key); + return ret; +} + +void zfCoreSetKeyComplete(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + +#if 0 + wd->sta.flagKeyChanging = 0; +#else + if(wd->sta.flagKeyChanging) + { + zmw_enter_critical_section(dev); + wd->sta.flagKeyChanging--; + zmw_leave_critical_section(dev); + } +#endif + zm_debug_msg1(" zfCoreSetKeyComplete--- ", wd->sta.flagKeyChanging); + + zfPushVtxq(dev); +} + +void zfCoreHalInitComplete(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + wd->halState = ZM_HAL_STATE_RUNNING; + zmw_leave_critical_section(dev); + + zfPushVtxq(dev); +} + +void zfCoreMacAddressNotify(zdev_t* dev, u8_t* addr) +{ + zmw_get_wlan_dev(dev); + + wd->macAddr[0] = addr[0] | ((u16_t)addr[1]<<8); + wd->macAddr[1] = addr[2] | ((u16_t)addr[3]<<8); + wd->macAddr[2] = addr[4] | ((u16_t)addr[5]<<8); + + + //zfHpSetMacAddress(dev, wd->macAddr, 0); + if (wd->zfcbMacAddressNotify != NULL) + { + wd->zfcbMacAddressNotify(dev, addr); + } +} + +void zfCoreSetIsoName(zdev_t* dev, u8_t* isoName) +{ + zmw_get_wlan_dev(dev); + + wd->ws.countryIsoName[0] = isoName[0]; + wd->ws.countryIsoName[1] = isoName[1]; + wd->ws.countryIsoName[2] = '\0'; + } + + +extern void zfScanMgrScanEventStart(zdev_t* dev); +extern u8_t zfScanMgrScanEventTimeout(zdev_t* dev); +extern void zfScanMgrScanEventRetry(zdev_t* dev); + +void zfProcessEvent(zdev_t* dev, u16_t* eventArray, u8_t eventCount) +{ + u8_t i, j, bypass = FALSE; + u16_t eventBypass[32]; + u8_t eventBypassCount = 0; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zfZeroMemory((u8_t*) eventBypass, 64); + + for( i=0; ista.cmMicFailureCount = 0; + } + break; + + case ZM_EVENT_CM_DISCONNECT: + { + zm_msg0_mm(ZM_LV_0, "ZM_EVENT_CM_DISCONNECT"); + + zfChangeAdapterState(dev, ZM_STA_STATE_DISCONNECT); + + zmw_enter_critical_section(dev); + //zfTimerSchedule(dev, ZM_EVENT_CM_BLOCK_TIMER, + // ZM_TICK_CM_BLOCK_TIMEOUT); + + /* Timer Resolution on WinXP is 15/16 ms */ + /* Decrease Time offset for Counter Measure */ + zfTimerSchedule(dev, ZM_EVENT_CM_BLOCK_TIMER, + ZM_TICK_CM_BLOCK_TIMEOUT - ZM_TICK_CM_BLOCK_TIMEOUT_OFFSET); + + zmw_leave_critical_section(dev); + wd->sta.cmMicFailureCount = 0; + //zfiWlanDisable(dev); + zfHpResetKeyCache(dev); + if (wd->zfcbConnectNotify != NULL) + { + wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_DISCONNECT_MIC_FAIL, + wd->sta.bssid); + } + } + break; + + case ZM_EVENT_CM_BLOCK_TIMER: + { + zm_msg0_mm(ZM_LV_0, "ZM_EVENT_CM_BLOCK_TIMER"); + + //zmw_enter_critical_section(dev); + wd->sta.cmDisallowSsidLength = 0; + if ( wd->sta.bAutoReconnect ) + { + zm_msg0_mm(ZM_LV_0, "ZM_EVENT_CM_BLOCK_TIMER:bAutoReconnect!=0"); + zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_INTERNAL); + zfScanMgrScanStart(dev, ZM_SCAN_MGR_SCAN_INTERNAL); + } + //zmw_leave_critical_section(dev); + } + break; + + case ZM_EVENT_TIMEOUT_ADDBA: + { + if (!wd->addbaComplete && (wd->addbaCount < 5)) + { + zfAggSendAddbaRequest(dev, wd->sta.bssid, 0, 0); + wd->addbaCount++; + zfTimerSchedule(dev, ZM_EVENT_TIMEOUT_ADDBA, 100); + } + else + { + zfTimerCancel(dev, ZM_EVENT_TIMEOUT_ADDBA); + } + } + break; + + #ifdef ZM_ENABLE_PERFORMANCE_EVALUATION + case ZM_EVENT_TIMEOUT_PERFORMANCE: + { + zfiPerformanceRefresh(dev); + } + break; + #endif + case ZM_EVENT_SKIP_COUNTERMEASURE: + //enable the Countermeasure + { + zm_debug_msg0("Countermeasure : Enable MIC Check "); + wd->TKIP_Group_KeyChanging = 0x0; + } + break; + + default: + break; + } + } +} + +void zfBssInfoCreate(zdev_t* dev) +{ + u8_t i; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + wd->sta.bssList.bssCount = 0; + wd->sta.bssList.head = NULL; + wd->sta.bssList.tail = NULL; + wd->sta.bssInfoArrayHead = 0; + wd->sta.bssInfoArrayTail = 0; + wd->sta.bssInfoFreeCount = ZM_MAX_BSS; + + for( i=0; i< ZM_MAX_BSS; i++ ) + { + //wd->sta.bssInfoArray[i] = &(wd->sta.bssInfoPool[i]); + wd->sta.bssInfoArray[i] = zfwMemAllocate(dev, sizeof(struct zsBssInfo)); + + } + + zmw_leave_critical_section(dev); +} + +void zfBssInfoDestroy(zdev_t* dev) +{ + u8_t i; + zmw_get_wlan_dev(dev); + + zfBssInfoRefresh(dev, 1); + + for( i=0; i< ZM_MAX_BSS; i++ ) + { + if (wd->sta.bssInfoArray[i] != NULL) + { + zfwMemFree(dev, wd->sta.bssInfoArray[i], sizeof(struct zsBssInfo)); + } + else + { + zm_assert(0); + } + } + return; +} + +struct zsBssInfo* zfBssInfoAllocate(zdev_t* dev) +{ + struct zsBssInfo* pBssInfo; + + zmw_get_wlan_dev(dev); + + if (wd->sta.bssInfoFreeCount == 0) + return NULL; + + pBssInfo = wd->sta.bssInfoArray[wd->sta.bssInfoArrayHead]; + wd->sta.bssInfoArray[wd->sta.bssInfoArrayHead] = NULL; + wd->sta.bssInfoArrayHead = (wd->sta.bssInfoArrayHead + 1) & (ZM_MAX_BSS - 1); + wd->sta.bssInfoFreeCount--; + + zfZeroMemory((u8_t*)pBssInfo, sizeof(struct zsBssInfo)); + + return pBssInfo; +} + +void zfBssInfoFree(zdev_t* dev, struct zsBssInfo* pBssInfo) +{ + zmw_get_wlan_dev(dev); + + zm_assert(wd->sta.bssInfoArray[wd->sta.bssInfoArrayTail] == NULL); + + pBssInfo->signalStrength = pBssInfo->signalQuality = 0; + pBssInfo->sortValue = 0; + + wd->sta.bssInfoArray[wd->sta.bssInfoArrayTail] = pBssInfo; + wd->sta.bssInfoArrayTail = (wd->sta.bssInfoArrayTail + 1) & (ZM_MAX_BSS - 1); + wd->sta.bssInfoFreeCount++; +} + +void zfBssInfoReorderList(zdev_t* dev) +{ + struct zsBssInfo* pBssInfo = NULL; + struct zsBssInfo* pInsBssInfo = NULL; + struct zsBssInfo* pNextBssInfo = NULL; + struct zsBssInfo* pPreBssInfo = NULL; + u8_t i = 0; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + if (wd->sta.bssList.bssCount > 1) + { + pInsBssInfo = wd->sta.bssList.head; + wd->sta.bssList.tail = pInsBssInfo; + pBssInfo = pInsBssInfo->next; + pInsBssInfo->next = NULL; + while (pBssInfo != NULL) + { + i = 0; + while (1) + { +// if (pBssInfo->signalStrength >= pInsBssInfo->signalStrength) + if( pBssInfo->sortValue >= pInsBssInfo->sortValue) + { + if (i==0) + { + //Insert BssInfo to head + wd->sta.bssList.head = pBssInfo; + pNextBssInfo = pBssInfo->next; + pBssInfo->next = pInsBssInfo; + break; + } + else + { + //Insert BssInfo to neither head nor tail + pPreBssInfo->next = pBssInfo; + pNextBssInfo = pBssInfo->next; + pBssInfo->next = pInsBssInfo; + break; + } + } + else + { + if (pInsBssInfo->next != NULL) + { + //Signal strength smaller than current BssInfo, check next + pPreBssInfo = pInsBssInfo; + pInsBssInfo = pInsBssInfo->next; + } + else + { + //Insert BssInfo to tail + pInsBssInfo->next = pBssInfo; + pNextBssInfo = pBssInfo->next; + wd->sta.bssList.tail = pBssInfo; + pBssInfo->next = NULL; + break; + } + } + i++; + } + pBssInfo = pNextBssInfo; + pInsBssInfo = wd->sta.bssList.head; + } + } //if (wd->sta.bssList.bssCount > 1) + + zmw_leave_critical_section(dev); +} + +void zfBssInfoInsertToList(zdev_t* dev, struct zsBssInfo* pBssInfo) +{ + zmw_get_wlan_dev(dev); + + zm_assert(pBssInfo); + + //zm_debug_msg2("pBssInfo = ", pBssInfo); + + if ( wd->sta.bssList.bssCount == 0 ) + { + wd->sta.bssList.head = pBssInfo; + wd->sta.bssList.tail = pBssInfo; + } + else + { + wd->sta.bssList.tail->next = pBssInfo; + wd->sta.bssList.tail = pBssInfo; + } + + pBssInfo->next = NULL; + wd->sta.bssList.bssCount++; + + //zm_debug_msg2("bss count = ", wd->sta.bssList.bssCount); +} + +void zfBssInfoRemoveFromList(zdev_t* dev, struct zsBssInfo* pBssInfo) +{ + struct zsBssInfo* pNowBssInfo; + struct zsBssInfo* pPreBssInfo = NULL; + u8_t i; + + zmw_get_wlan_dev(dev); + + zm_assert(pBssInfo); + zm_assert(wd->sta.bssList.bssCount); + + //zm_debug_msg2("pBssInfo = ", pBssInfo); + + pNowBssInfo = wd->sta.bssList.head; + + for( i=0; ista.bssList.bssCount; i++ ) + { + if ( pNowBssInfo == pBssInfo ) + { + if ( i == 0 ) + { /* remove head */ + wd->sta.bssList.head = pBssInfo->next; + } + else + { + pPreBssInfo->next = pBssInfo->next; + } + + if ( i == (wd->sta.bssList.bssCount - 1) ) + { /* remove tail */ + wd->sta.bssList.tail = pPreBssInfo; + } + + break; + } + + pPreBssInfo = pNowBssInfo; + pNowBssInfo = pNowBssInfo->next; + } + + zm_assert(i != wd->sta.bssList.bssCount); + wd->sta.bssList.bssCount--; + + //zm_debug_msg2("bss count = ", wd->sta.bssList.bssCount); +} + +void zfBssInfoRefresh(zdev_t* dev, u16_t mode) +{ + struct zsBssInfo* pBssInfo; + struct zsBssInfo* pNextBssInfo; + u8_t i, bssCount; + + zmw_get_wlan_dev(dev); + + pBssInfo = wd->sta.bssList.head; + bssCount = wd->sta.bssList.bssCount; + + for( i=0; inext; + zfBssInfoRemoveFromList(dev, pBssInfo); + zfBssInfoFree(dev, pBssInfo); + pBssInfo = pNextBssInfo; + } + else + { + if ( pBssInfo->flag & ZM_BSS_INFO_VALID_BIT ) + { /* this one must be kept */ + pBssInfo->flag &= ~ZM_BSS_INFO_VALID_BIT; + pBssInfo = pBssInfo->next; + } + else + { + #define ZM_BSS_CACHE_TIME_IN_MS 20000 + if ((wd->tick - pBssInfo->tick) > (ZM_BSS_CACHE_TIME_IN_MS/ZM_MS_PER_TICK)) + { + pNextBssInfo = pBssInfo->next; + zfBssInfoRemoveFromList(dev, pBssInfo); + zfBssInfoFree(dev, pBssInfo); + pBssInfo = pNextBssInfo; + } + else + { + pBssInfo = pBssInfo->next; + } + } + } + } //for( i=0; i 49 ) + { + tmpLength = 49; + } + + zfMemoryCopy(buf, value, tmpLength); + buf[tmpLength] = '\0'; + //printk("SSID: %s\n", buf); + //zm_debug_msg_s("ssid = ", value); +} + +void zfCoreReinit(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + wd->sta.flagKeyChanging = 0; + wd->sta.flagFreqChanging = 0; +} + +void zfGenerateRandomBSSID(zdev_t* dev, u8_t *MACAddr, u8_t *BSSID) +{ + //ULONGLONG time; + u32_t time; + + zmw_get_wlan_dev(dev); + + time = wd->tick; + + // + // Initialize the random BSSID to be the same as MAC address. + // + + // RtlCopyMemory(BSSID, MACAddr, sizeof(DOT11_MAC_ADDRESS)); + zfMemoryCopy(BSSID, MACAddr, 6); + + // + // Get the system time in 10 millisecond. + // + + // NdisGetCurrentSystemTime((PLARGE_INTEGER)&time); + // time /= 100000; + + // + // Randomize the first 4 bytes of BSSID. + // + + BSSID[0] ^= (u8_t)(time & 0xff); + BSSID[0] &= ~0x01; // Turn off multicast bit + BSSID[0] |= 0x02; // Turn on local bit + + time >>= 8; + BSSID[1] ^= (u8_t)(time & 0xff); + + time >>= 8; + BSSID[2] ^= (u8_t)(time & 0xff); + + time >>= 8; + BSSID[3] ^= (u8_t)(time & 0xff); +} + +u8_t zfiWlanGetDestAddrFromBuf(zdev_t *dev, zbuf_t *buf, u16_t *macAddr) +{ +#ifdef ZM_ENABLE_NATIVE_WIFI + zmw_get_wlan_dev(dev); + + if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) + { + /* DA */ + macAddr[0] = zmw_tx_buf_readh(dev, buf, 16); + macAddr[1] = zmw_tx_buf_readh(dev, buf, 18); + macAddr[2] = zmw_tx_buf_readh(dev, buf, 20); + } + else if ( wd->wlanMode == ZM_MODE_IBSS ) + { + /* DA */ + macAddr[0] = zmw_tx_buf_readh(dev, buf, 4); + macAddr[1] = zmw_tx_buf_readh(dev, buf, 6); + macAddr[2] = zmw_tx_buf_readh(dev, buf, 8); + } + else if ( wd->wlanMode == ZM_MODE_AP ) + { + /* DA */ + macAddr[0] = zmw_tx_buf_readh(dev, buf, 4); + macAddr[1] = zmw_tx_buf_readh(dev, buf, 6); + macAddr[2] = zmw_tx_buf_readh(dev, buf, 8); + } + else + { + return 1; + } +#else + /* DA */ + macAddr[0] = zmw_tx_buf_readh(dev, buf, 0); + macAddr[1] = zmw_tx_buf_readh(dev, buf, 2); + macAddr[2] = zmw_tx_buf_readh(dev, buf, 4); +#endif + + return 0; +} + +/* Leave an empty line below to remove warning message on some compiler */ + +u16_t zfFindCleanFrequency(zdev_t* dev, u32_t adhocMode) +{ + u8_t i, j; + u16_t returnChannel; + u16_t count_24G = 0, min24GIndex = 0; + u16_t count_5G = 0, min5GIndex = 0; + u16_t CombinationBssNumberIn24G[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + u16_t BssNumberIn24G[17] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + u16_t Array_24G[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + u16_t BssNumberIn5G[31] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + u16_t Array_5G[31] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + struct zsBssInfo* pBssInfo; + + zmw_get_wlan_dev(dev); + + if ((pBssInfo = wd->sta.bssList.head) == NULL) + { + if( adhocMode == ZM_ADHOCBAND_B || adhocMode == ZM_ADHOCBAND_G || + adhocMode == ZM_ADHOCBAND_BG || adhocMode == ZM_ADHOCBAND_ABG ) + { + returnChannel = zfChGetFirst2GhzChannel(dev); + } + else + { + returnChannel = zfChGetFirst5GhzChannel(dev); + } + + return returnChannel; + } + + /* #1 Get Allowed Channel following Country Code ! */ + zmw_declare_for_critical_section(); + zmw_enter_critical_section(dev); + for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) + { + if (wd->regulationTable.allowChannel[i].channel < 3000) + { // 2.4GHz + Array_24G[count_24G] = wd->regulationTable.allowChannel[i].channel; + count_24G++; + } + else + { // 5GHz + count_5G++; + Array_5G[i] = wd->regulationTable.allowChannel[i].channel; + } + } + zmw_leave_critical_section(dev); + + while( pBssInfo != NULL ) + { + /* #2_1 Count BSS number in some specificed frequency in 2.4GHz band ! */ + if( adhocMode == ZM_ADHOCBAND_B || adhocMode == ZM_ADHOCBAND_G || + adhocMode == ZM_ADHOCBAND_BG || adhocMode == ZM_ADHOCBAND_ABG ) + { + for( i=0; i<=(count_24G+3); i++ ) + { + if( pBssInfo->frequency == Array_24G[i] ) + { // Array_24G[0] correspond to BssNumberIn24G[2] + BssNumberIn24G[pBssInfo->channel+1]++; + } + } + } + + /* #2_2 Count BSS number in some specificed frequency in 5GHz band ! */ + if( adhocMode == ZM_ADHOCBAND_A || adhocMode == ZM_ADHOCBAND_ABG ) + { + for( i=0; ifrequency == Array_5G[i] ) + { // Array_5G[0] correspond to BssNumberIn5G[0] + BssNumberIn5G[i]++; + } + } + } + + pBssInfo = pBssInfo->next; + } + +#if 0 + for(i=0; i<=(count_24G+3); i++) + { + printk("2.4GHz Before combin, %d BSS network : %d", i, BssNumberIn24G[i]); + } + + for(i=0; ista.bssid, 6) ) + { + return 1; + } + else + { + return 0; + } +} --- linux-2.6.28.orig/drivers/staging/otus/80211core/freqctrl.c +++ linux-2.6.28/drivers/staging/otus/80211core/freqctrl.c @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "cprecomp.h" + +/* zfAddFreqChangeReq should be called inside the critical section */ +static void zfAddFreqChangeReq(zdev_t* dev, u16_t frequency, u8_t bw40, + u8_t extOffset, zfpFreqChangeCompleteCb cb) +{ + zmw_get_wlan_dev(dev); + +//printk("zfAddFreqChangeReq freqReqQueueTail%d\n", wd->freqCtrl.freqReqQueueTail); + wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueTail] = frequency; + wd->freqCtrl.freqReqBw40[wd->freqCtrl.freqReqQueueTail] = bw40; + wd->freqCtrl.freqReqExtOffset[wd->freqCtrl.freqReqQueueTail] = extOffset; + wd->freqCtrl.freqChangeCompCb[wd->freqCtrl.freqReqQueueTail] = cb; + wd->freqCtrl.freqReqQueueTail++; + if ( wd->freqCtrl.freqReqQueueTail >= ZM_MAX_FREQ_REQ_QUEUE ) + { + wd->freqCtrl.freqReqQueueTail = 0; + } +} + +void zfCoreSetFrequencyV2(zdev_t* dev, u16_t frequency, zfpFreqChangeCompleteCb cb) +{ + zfCoreSetFrequencyEx(dev, frequency, 0, 0, cb); +} + +void zfCoreSetFrequencyExV2(zdev_t* dev, u16_t frequency, u8_t bw40, + u8_t extOffset, zfpFreqChangeCompleteCb cb, u8_t forceSetFreq) +{ + u8_t setFreqImmed = 0; + u8_t initRF = 0; + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + zm_msg1_scan(ZM_LV_1, "Freq=", frequency); + + zmw_enter_critical_section(dev); + if ((wd->sta.currentFrequency == frequency) + && (wd->sta.currentBw40 == bw40) + && (wd->sta.currentExtOffset == extOffset)) + { + if ( forceSetFreq == 0 && wd->sta.flagFreqChanging == 0 ) + { + goto done; + } + } +#ifdef ZM_FB50 + /*if(frequency!=2437) { + zmw_leave_critical_section(dev); + return; + }*/ +#endif + + zfAddFreqChangeReq(dev, frequency, bw40, extOffset, cb); + +// zm_assert( wd->sta.flagFreqChanging == 0 ); + //wd->sta.flagFreqChanging = 1; + if ( wd->sta.flagFreqChanging == 0 ) + { + if ((wd->sta.currentBw40 != bw40) || (wd->sta.currentExtOffset != extOffset)) + { + initRF = 1; + } + wd->sta.currentFrequency = frequency; + wd->sta.currentBw40 = bw40; + wd->sta.currentExtOffset = extOffset; + setFreqImmed = 1; + } + wd->sta.flagFreqChanging++; + + zmw_leave_critical_section(dev); + + if ( setFreqImmed ) + { + //zfHpSetFrequency(dev, frequency, 0); + if ( forceSetFreq ) + { // Cold reset to reset the frequency after scanning ! + zm_debug_msg0("#6_1 20070917"); + zm_debug_msg0("It is happen!!! No error message"); + zfHpSetFrequencyEx(dev, frequency, bw40, extOffset, 2); + } + else + { + zfHpSetFrequencyEx(dev, frequency, bw40, extOffset, initRF); + } + + if ( zfStaIsConnected(dev) + && (frequency == wd->frequency)) { + wd->sta.connPowerInHalfDbm = zfHpGetTransmitPower(dev); + } + } + return; + +done: + zmw_leave_critical_section(dev); + + if ( cb != NULL ) + { + cb(dev); + } + zfPushVtxq(dev); + return; +} + +void zfCoreSetFrequencyEx(zdev_t* dev, u16_t frequency, u8_t bw40, + u8_t extOffset, zfpFreqChangeCompleteCb cb) +{ + zfCoreSetFrequencyExV2(dev, frequency, bw40, extOffset, cb, 0); +} + +void zfCoreSetFrequency(zdev_t* dev, u16_t frequency) +{ + zfCoreSetFrequencyV2(dev, frequency, NULL); +} + +/* zfRemoveFreqChangeReq SHOULD NOT be called inside the critical section */ +static void zfRemoveFreqChangeReq(zdev_t* dev) +{ + zfpFreqChangeCompleteCb cb = NULL; + u16_t frequency; + u8_t bw40; + u8_t extOffset; + u16_t compFreq = 0; + u8_t compBw40 = 0; + u8_t compExtOffset = 0; + + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + if (wd->freqCtrl.freqReqQueueHead != wd->freqCtrl.freqReqQueueTail) + { + zm_msg1_scan(ZM_LV_1, "Freq=", + wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueHead]); + compFreq = wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueHead]; + compBw40 = wd->freqCtrl.freqReqBw40[wd->freqCtrl.freqReqQueueHead]; + compExtOffset = wd->freqCtrl.freqReqExtOffset[wd->freqCtrl.freqReqQueueHead]; + + wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueHead] = 0; + cb = wd->freqCtrl.freqChangeCompCb[wd->freqCtrl.freqReqQueueHead]; + wd->freqCtrl.freqReqQueueHead++; + if ( wd->freqCtrl.freqReqQueueHead >= ZM_MAX_FREQ_REQ_QUEUE ) + { + wd->freqCtrl.freqReqQueueHead = 0; + } + } + zmw_leave_critical_section(dev); + + if ( cb != NULL ) + { + cb(dev); + } + + zmw_enter_critical_section(dev); + while (wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueHead] != 0) + { + frequency = wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueHead]; + bw40 = wd->freqCtrl.freqReqBw40[wd->freqCtrl.freqReqQueueHead]; + extOffset=wd->freqCtrl.freqReqExtOffset[wd->freqCtrl.freqReqQueueHead]; + if ((compFreq == frequency) + && (compBw40 == bw40) + && (compExtOffset == extOffset)) + { + /* Duplicated frequency command */ + zm_msg1_scan(ZM_LV_1, "Duplicated Freq=", frequency); + + cb = wd->freqCtrl.freqChangeCompCb[wd->freqCtrl.freqReqQueueHead]; + wd->freqCtrl.freqReqQueue[wd->freqCtrl.freqReqQueueHead] = 0; + wd->freqCtrl.freqReqQueueHead++; + + if ( wd->freqCtrl.freqReqQueueHead >= ZM_MAX_FREQ_REQ_QUEUE ) + { + wd->freqCtrl.freqReqQueueHead = 0; + } + + if ( wd->sta.flagFreqChanging != 0 ) + { + wd->sta.flagFreqChanging--; + } + + zmw_leave_critical_section(dev); + if ( cb != NULL ) + { + cb(dev); + } + zmw_enter_critical_section(dev); + } + else + { + u8_t initRF = 0; + if ((wd->sta.currentBw40 != bw40) || (wd->sta.currentExtOffset != extOffset)) + { + initRF = 1; + } + wd->sta.currentFrequency = frequency; + wd->sta.currentBw40 = bw40; + wd->sta.currentExtOffset = extOffset; + zmw_leave_critical_section(dev); + + zfHpSetFrequencyEx(dev, frequency, bw40, extOffset, initRF); + if ( zfStaIsConnected(dev) + && (frequency == wd->frequency)) { + wd->sta.connPowerInHalfDbm = zfHpGetTransmitPower(dev); + } + + return; + } + } + zmw_leave_critical_section(dev); + + return; +} + +void zfCoreSetFrequencyComplete(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + zm_msg1_scan(ZM_LV_1, "flagFreqChanging=", wd->sta.flagFreqChanging); + + zmw_enter_critical_section(dev); + //wd->sta.flagFreqChanging = 0; + if ( wd->sta.flagFreqChanging != 0 ) + { + wd->sta.flagFreqChanging--; + } + + zmw_leave_critical_section(dev); + + zfRemoveFreqChangeReq(dev); + + zfPushVtxq(dev); + return; +} + +void zfReSetCurrentFrequency(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + zm_debug_msg0("It is happen!!! No error message"); + + zfCoreSetFrequencyExV2(dev, wd->frequency, 0, 0, NULL, 1); +} --- linux-2.6.28.orig/drivers/staging/otus/80211core/cwm.c +++ linux-2.6.28/drivers/staging/otus/80211core/cwm.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* */ +/* Module Name : cwm.c */ +/* */ +/* Abstract */ +/* This module contains channel width related functions. */ +/* */ +/* NOTES */ +/* None */ +/* */ +/************************************************************************/ + +#include "cprecomp.h" + + + +void zfCwmInit(zdev_t* dev) { + //u16_t i; + zmw_get_wlan_dev(dev); + + switch (wd->wlanMode) { + case ZM_MODE_AP: + wd->cwm.cw_mode = CWM_MODE2040; + wd->cwm.cw_width = CWM_WIDTH40; + wd->cwm.cw_enable = 1; + break; + case ZM_MODE_INFRASTRUCTURE: + case ZM_MODE_PSEUDO: + case ZM_MODE_IBSS: + default: + wd->cwm.cw_mode = CWM_MODE2040; + wd->cwm.cw_width = CWM_WIDTH20; + wd->cwm.cw_enable = 1; + break; + } +} + + +void zfCoreCwmBusy(zdev_t* dev, u16_t busy) +{ + + zmw_get_wlan_dev(dev); + + zm_msg1_mm(ZM_LV_0, "CwmBusy=", busy); + + if(wd->cwm.cw_mode == CWM_MODE20) { + wd->cwm.cw_width = CWM_WIDTH20; + return; + } + + if(wd->cwm.cw_mode == CWM_MODE40) { + wd->cwm.cw_width = CWM_WIDTH40; + return; + } + + if (busy) { + wd->cwm.cw_width = CWM_WIDTH20; + return; + } + + + if((wd->wlanMode == ZM_MODE_INFRASTRUCTURE || wd->wlanMode == ZM_MODE_PSEUDO || + wd->wlanMode == ZM_MODE_IBSS)) { + if (wd->sta.ie.HtCap.HtCapInfo && HTCAP_SupChannelWidthSet != 0 && + wd->sta.ie.HtInfo.ChannelInfo && ExtHtCap_RecomTxWidthSet != 0 && + (wd->sta.ie.HtInfo.ChannelInfo && ExtHtCap_ExtChannelOffsetAbove) == 1) { + + wd->cwm.cw_width = CWM_WIDTH40; + } + else { + wd->cwm.cw_width = CWM_WIDTH20; + } + + return; + } + + if(wd->wlanMode == ZM_MODE_AP) { + wd->cwm.cw_width = CWM_WIDTH40; + } + +} + + + + +u16_t zfCwmIsExtChanBusy(u32_t ctlBusy, u32_t extBusy) +{ + u32_t busy; /* percentage */ + u32_t cycleTime, ctlClear; + + cycleTime = 1280000; //1.28 seconds + + if (cycleTime > ctlBusy) { + ctlClear = cycleTime - ctlBusy; + } + else + { + ctlClear = 0; + } + + /* Compute ratio of extension channel busy to control channel clear + * as an approximation to extension channel cleanliness. + * + * According to the hardware folks, ext rxclear is undefined + * if the ctrl rxclear is de-asserted (i.e. busy) + */ + if (ctlClear) { + busy = (extBusy * 100) / ctlClear; + } else { + busy = 0; + } + if (busy > ATH_CWM_EXTCH_BUSY_THRESHOLD) { + return TRUE; + } + + return FALSE; +} --- linux-2.6.28.orig/drivers/staging/otus/80211core/pub_zfw.h +++ linux-2.6.28/drivers/staging/otus/80211core/pub_zfw.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _PUB_ZFW_H +#define _PUB_ZFW_H + +#include "../oal_dt.h" + + +/* Buffer management */ +#ifdef ZM_ENABLE_BUFFER_DEBUG +extern zbuf_t* zfwBufAllocateWithContext(zdev_t* dev, u16_t len, u8_t *functionName, ULONG line); +#define zfwBufAllocate(dev, len) zfwBufAllocateWithContext(dev, len, (u8_t *)__func__, __LINE__) +#else +extern zbuf_t* zfwBufAllocate(zdev_t* dev, u16_t len); +#endif +extern void zfwBufFree(zdev_t* dev, zbuf_t* buf, u16_t errCode); +extern u16_t zfwBufChain(zdev_t* dev, zbuf_t** head, zbuf_t* tail); +extern u16_t zfwBufCopy(zdev_t* dev, zbuf_t* dst, zbuf_t* src); +extern u16_t zfwBufSetSize(zdev_t* dev, zbuf_t* buf, u16_t size); +extern u16_t zfwBufRemoveHead(zdev_t* dev, zbuf_t* buf, u16_t size); +extern u16_t zfwBufGetSize(zdev_t* dev, zbuf_t* buf); +extern void zfwCopyBufContext(zdev_t* dev, zbuf_t* source, zbuf_t* dest); + +/* Memory management */ +extern void* zfwMemAllocate(zdev_t* dev, u32_t size); +extern void zfwMemFree(zdev_t* dev, void* mem, u32_t size); +extern void zfwMemoryCopy(u8_t* dst, u8_t* src, u16_t length); +extern void zfwMemoryMove(u8_t* dst, u8_t* src, u16_t length); +extern void zfwZeroMemory(u8_t* va, u16_t length); +extern u8_t zfwMemoryIsEqual(u8_t* m1, u8_t* m2, u16_t length); + +/* Others */ +extern void zfwSleep(zdev_t* dev, u32_t ms); +extern u16_t zfwGetVapId(zdev_t* dev); +extern u16_t zfwStaAddIeWpaRsn(zdev_t* dev, zbuf_t* buf, u16_t offset, u8_t frameType); +extern u32_t zfwWaitForEvent(zdev_t *dev, u32_t event, u32_t timeout); +extern void zfwSendEvent(zdev_t* dev); +extern void zfwGetActiveScanDur(zdev_t* dev, u8_t* Dur ); +extern void zfwGetShowZeroLengthSSID(zdev_t* dev, u8_t* Dur ); +/* For debugging */ +extern void zfwDumpBuf(zdev_t* dev, zbuf_t* buf); +extern void zfwDbgReadRegDone(zdev_t* dev, u32_t addr, u32_t val); +/* For Evl */ +extern void zfwDbgDownloadFwInitDone(zdev_t* dev); +extern void zfwDbgReadFlashDone(zdev_t* dev, u32_t addr, u32_t* rspdata, u32_t datalen); +extern void zfwDbgGetFlashChkSumDone(zdev_t* dev, u32_t* rspdata); +extern void zfwDbgProgrameFlashDone(zdev_t* dev); +extern void zfwDbgProgrameFlashChkDone(zdev_t* dev); +extern void zfwDbgWriteRegDone(zdev_t* dev, u32_t addr, u32_t val); +extern void zfwDbgWriteEepromDone(zdev_t* dev, u32_t addr, u32_t val); +extern void zfwDbgReadTallyDone(zdev_t* dev); +extern void zfwWlanReadRegDone(zdev_t* dev, u32_t addr, u32_t val); +extern void zfwWlanWriteRegDone(zdev_t* dev, u32_t addr, u32_t val); +extern void zfwWlanReadTallyDone(zdev_t* dev); +extern void zfwDbgQueryHwTxBusyDone(zdev_t* dev, u32_t val); +extern u32_t zfwReadReg(zdev_t* dev, u32_t offset); +extern u32_t zfwReadEeprom(zdev_t* dev, u32_t addr); + +/* Reserved for Vista, please return 0 */ +extern u8_t zfwGetPktEncExemptionActionType(zdev_t* dev, zbuf_t* buf); + +#ifdef ZM_ENABLE_CENC +/* Reserved for CENC, please return 0 */ +extern u8_t zfwCencHandleBeaconProbrespon(zdev_t* dev, u8_t *pWIEc, + u8_t *pPeerSSIDc, u8_t *pPeerAddrc); +#endif //ZM_ENABLE_CENC + +#ifdef ZM_HALPLUS_LOCK +extern asmlinkage struct zsWlanDev *zfwGetWlanDev(zdev_t* dev); +extern asmlinkage void zfwEnterCriticalSection(zdev_t* dev); +extern asmlinkage void zfwLeaveCriticalSection(zdev_t* dev); +extern asmlinkage u8_t zfwBufReadByte(zdev_t* dev, zbuf_t* buf, u16_t offset); +extern asmlinkage u16_t zfwBufReadHalfWord(zdev_t* dev, zbuf_t* buf, u16_t offset); +extern asmlinkage void zfwBufWriteByte(zdev_t* dev, zbuf_t* buf, u16_t offset, u8_t value); +extern asmlinkage void zfwBufWriteHalfWord(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t value); +extern asmlinkage u8_t *zfwGetBuffer(zdev_t* dev, zbuf_t* buf); +#endif + +#endif //_PUB_ZFW_H --- linux-2.6.28.orig/drivers/staging/otus/80211core/wlan.h +++ linux-2.6.28/drivers/staging/otus/80211core/wlan.h @@ -0,0 +1,595 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* */ +/* Module Name : wlan_defs.h */ +/* */ +/* Abstract */ +/* This module contains WLAN definitions. */ +/* */ +/* NOTES */ +/* None */ +/* */ +/************************************************************************/ + +#ifndef _WLAN_H +#define _WLAN_H + + +#define ZM_EXTERNAL_ALLOC_BUF 0 +#define ZM_INTERNAL_ALLOC_BUF 1 + +#define ZM_SIZE_OF_CTRL_SET 8 +#define ZM_SIZE_OF_IV 4 +#define ZM_SIZE_OF_EXT_IV 4 +#define ZM_SIZE_OF_MIC 8 +#define ZM_SIZE_OF_CCX_MIC 8 +#define ZM_SIZE_OF_WLAN_DATA_HEADER 24 +#define ZM_SIZE_OF_QOS_CTRL 2 + +/* Header definition */ +#define ZM_SIZE_OF_WLAN_WDS_HEADER 32 +#define ZM_SIZE_OF_SNAP_HEADER 8 + +#define ZM_WLAN_HEADER_A1_OFFSET 4 +#define ZM_WLAN_HEADER_A2_OFFSET 10 +#define ZM_WLAN_HEADER_A3_OFFSET 16 +#define ZM_WLAN_HEADER_A4_OFFSET 24 +#define ZM_WLAN_HEADER_IV_OFFSET 24 +#define ZM_SIZE_OF_WLAN_DATA_HEADER 24 + +/* Port definition */ +#define ZM_PORT_DISABLED 0 +#define ZM_PORT_ENABLED 1 + +/* Frame Type */ +#define ZM_WLAN_MANAGEMENT_FRAME 0x0 +#define ZM_WLAN_CONTROL_FRAME 0x4 +#define ZM_WLAN_DATA_FRAME 0x8 + +/* Frame Subtype */ +#define ZM_WLAN_FRAME_TYPE_ASOCREQ 0x00 +#define ZM_WLAN_FRAME_TYPE_ASOCRSP 0x10 +#define ZM_WLAN_FRAME_TYPE_REASOCREQ 0x20 +#define ZM_WLAN_FRAME_TYPE_REASOCRSP 0x30 +#define ZM_WLAN_FRAME_TYPE_PROBEREQ 0x40 +#define ZM_WLAN_FRAME_TYPE_PROBERSP 0x50 +/* 0x60, 0x70 => Reserved */ +#define ZM_WLAN_FRAME_TYPE_BEACON 0x80 +#define ZM_WLAN_FRAME_TYPE_ATIM 0x90 +#define ZM_WLAN_FRAME_TYPE_DISASOC 0xA0 +#define ZM_WLAN_FRAME_TYPE_AUTH 0xB0 +#define ZM_WLAN_FRAME_TYPE_DEAUTH 0xC0 +#define ZM_WLAN_FRAME_TYPE_ACTION 0xD0 + +/* Frame type and subtype */ +#define ZM_WLAN_FRAME_TYPE_NULL 0x48 +#define ZM_WLAN_FRAME_TYPE_BAR 0x84 +#define ZM_WLAN_FRAME_TYPE_BA 0x94 +#define ZM_WLAN_FRAME_TYPE_PSPOLL 0xA4 +#define ZM_WLAN_FRAME_TYPE_RTS 0xB4 +#define ZM_WLAN_FRAME_TYPE_CTS 0xC4 +#define ZM_WLAN_FRAME_TYPE_QOS_NULL 0xC8 + +/* action frame */ +#define ZM_WLAN_SPECTRUM_MANAGEMENT_ACTION_FRAME 0 +#define ZM_WLAN_QOS_ACTION_FRAME 1 +#define ZM_WLAN_DLS_ACTION_FRAME 2 +#define ZM_WLAN_BLOCK_ACK_ACTION_FRAME 3 +/* block ack action frame*/ +#define ZM_WLAN_ADDBA_REQUEST_FRAME 0 +#define ZM_WLAN_ADDBA_RESPONSE_FRAME 1 +#define ZM_WLAN_DELBA_FRAME 2 + +/* Element ID */ +#define ZM_WLAN_EID_SSID 0 +#define ZM_WLAN_EID_SUPPORT_RATE 1 +#define ZM_WLAN_EID_FH 2 +#define ZM_WLAN_EID_DS 3 +#define ZM_WLAN_EID_CFS 4 +#define ZM_WLAN_EID_TIM 5 +#define ZM_WLAN_EID_IBSS 6 +#define ZM_WLAN_EID_COUNTRY 7 +/* reserved 8-15 */ +#define ZM_WLAN_EID_CHALLENGE 16 +/* reserved 17-31 */ +#define ZM_WLAN_EID_POWER_CONSTRAINT 32 +#define ZM_WLAN_EID_POWER_CAPABILITY 33 +#define ZM_WLAN_EID_TPC_REQUEST 34 +#define ZM_WLAN_EID_TPC_REPORT 35 +#define ZM_WLAN_EID_SUPPORTED_CHANNELS 36 +#define ZM_WLAN_EID_CHANNEL_SWITCH_ANNOUNCE 37 +#define ZM_WLAN_EID_MEASUREMENT_REQUEST 38 +#define ZM_WLAN_EID_MEASUREMENT_REPORT 39 +#define ZM_WLAN_EID_QUIET 40 +#define ZM_WLAN_EID_IBSS_DFS 41 +#define ZM_WLAN_EID_ERP 42 +#define ZM_WLAN_PREN2_EID_HTCAPABILITY 45 +#define ZM_WLAN_EID_RSN_IE 48 +#define ZM_WLAN_EID_EXTENDED_RATE 50 +#define ZM_WLAN_EID_HT_CAPABILITY 51 +#define ZM_WLAN_EID_EXTENDED_HT_CAPABILITY 52 +#define ZM_WLAN_EID_NEW_EXT_CHANNEL_OFFSET 53 +#define ZM_WLAN_PREN2_EID_HTINFORMATION 61 +#define ZM_WLAN_PREN2_EID_SECONDCHOFFSET 62 +#ifdef ZM_ENABLE_CENC +#define ZM_WLAN_EID_CENC_IE 68 +#endif //ZM_ENABLE_CENC +#define ZM_WLAN_EID_VENDOR_PRIVATE 221 /* Vendor private space; must demux OUI */ +#define ZM_WLAN_EID_WPA_IE 221 +#define ZM_WLAN_EID_WPS_IE 221 +#define ZM_WLAN_EID_WIFI_IE 221 + +/* ERP information element */ +#define ZM_WLAN_NON_ERP_PRESENT_BIT 0x1 +#define ZM_WLAN_USE_PROTECTION_BIT 0x2 +#define ZM_WLAN_BARKER_PREAMBLE_MODE_BIT 0x4 + +/* Channel frequency, in MHz */ +#define ZM_CH_G_1 2412 +#define ZM_CH_G_2 2417 +#define ZM_CH_G_3 2422 +#define ZM_CH_G_4 2427 +#define ZM_CH_G_5 2432 +#define ZM_CH_G_6 2437 +#define ZM_CH_G_7 2442 +#define ZM_CH_G_8 2447 +#define ZM_CH_G_9 2452 +#define ZM_CH_G_10 2457 +#define ZM_CH_G_11 2462 +#define ZM_CH_G_12 2467 +#define ZM_CH_G_13 2472 +#define ZM_CH_G_14 2484 +#define ZM_CH_A_184 4920 +#define ZM_CH_A_188 4940 +#define ZM_CH_A_192 4960 +#define ZM_CH_A_196 4980 +#define ZM_CH_A_8 5040 +#define ZM_CH_A_12 5060 +#define ZM_CH_A_16 5080 +#define ZM_CH_A_36 5180 +#define ZM_CH_A_40 5200 +#define ZM_CH_A_44 5220 +#define ZM_CH_A_48 5240 +#define ZM_CH_A_52 5260 +#define ZM_CH_A_56 5280 +#define ZM_CH_A_60 5300 +#define ZM_CH_A_64 5320 +#define ZM_CH_A_100 5500 +#define ZM_CH_A_104 5520 +#define ZM_CH_A_108 5540 +#define ZM_CH_A_112 5560 +#define ZM_CH_A_116 5580 +#define ZM_CH_A_120 5600 +#define ZM_CH_A_124 5620 +#define ZM_CH_A_128 5640 +#define ZM_CH_A_132 5660 +#define ZM_CH_A_136 5680 +#define ZM_CH_A_140 5700 +#define ZM_CH_A_149 5745 +#define ZM_CH_A_153 5765 +#define ZM_CH_A_157 5785 +#define ZM_CH_A_161 5805 +#define ZM_CH_A_165 5825 + + +/* AP : STA table => STA Type */ +#define ZM_11B_STA 0x0 +#define ZM_11G_STA 0x2 +#define ZM_11N_STA 0x4 + +/* AP : timeout */ +#define ZM_MS_PER_TICK 10 +#define ZM_TICK_PER_SECOND (1000/ZM_MS_PER_TICK) +#define ZM_TICK_PER_MINUTE (60*1000/ZM_MS_PER_TICK) +#define ZM_PREAUTH_TIMEOUT_MS 1000 /* 1 sec */ +#define ZM_AUTH_TIMEOUT_MS 1000 /* 1 sec */ + +/* Error code */ +#define ZM_SUCCESS 0 +#define ZM_ERR_TX_PORT_DISABLED 1 +#define ZM_ERR_BUFFER_DMA_ADDR 2 +#define ZM_ERR_FREE_TXD_EXHAUSTED 3 +#define ZM_ERR_TX_BUFFER_UNAVAILABLE 4 +#define ZM_ERR_BCMC_PS_BUFFER_UNAVAILABLE 5 +#define ZM_ERR_UNI_PS_BUFFER_UNAVAILABLE 6 +#define ZM_ERR_EXCEED_PRIORITY_THRESHOLD 7 +#define ZM_ERR_VMMQ_FULL 8 +#define ZM_ERR_FLUSH_PS_QUEUE 9 +#define ZM_ERR_CMD_INT_MISSED 15 /* Polling cmd int timeout*/ +/* Rx */ +#define ZM_ERR_RX_FRAME_TYPE 20 +#define ZM_ERR_MIN_RX_ENCRYPT_FRAME_LENGTH 21 +#define ZM_ERR_MIN_RX_FRAME_LENGTH 22 +#define ZM_ERR_MAX_RX_FRAME_LENGTH 23 +#define ZM_ERR_RX_DUPLICATE 24 +#define ZM_ERR_RX_SRC_ADDR_IS_OWN_MAC 25 +#define ZM_ERR_MIN_RX_PROTOCOL_VERSION 26 +#define ZM_ERR_WPA_GK_NOT_INSTALLED 27 +#define ZM_ERR_STA_NOT_ASSOCIATED 28 +#define ZM_ERR_DATA_BEFORE_CONNECTED 29 +#define ZM_ERR_DATA_NOT_ENCRYPTED 30 +#define ZM_ERR_DATA_BSSID_NOT_MATCHED 31 +#define ZM_ERR_RX_BAR_FRAME 32 +#define ZM_ERR_OUT_OF_ORDER_NULL_DATA 33 + +/* ZFI */ +#define ZM_ERR_INVALID_TX_RATE 40 +#define ZM_ERR_WDS_PORT_ID 41 + +/* QUEUE */ +#define ZM_ERR_QUEUE_FULL 50 +#define ZM_ERR_STA_UAPSD_QUEUE_FULL 51 +#define ZM_ERR_AP_UAPSD_QUEUE_FULL 52 + +/* Maximum Rx frame length */ +#if ZM_LARGEPAYLOAD_TEST == 1 +#define ZM_WLAN_MAX_RX_SIZE 16384 +#else +#define ZM_WLAN_MAX_RX_SIZE 8192 +#endif + +/* PCI DMA test error code */ +#define ZM_ERR_INTERRUPT_MISSED 100 +#define ZM_ERR_OWN_BIT_NOT_CLEARED 101 +#define ZM_ERR_RX_SEQ_NUMBER 102 +#define ZM_ERR_RX_LENGTH 103 +#define ZM_ERR_RX_DATA 104 +#define ZM_ERR_RX_DESCRIPTOR_NUM 105 +/* Common register test error code */ +#define ZM_ERR_REGISTER_ACCESS 110 /* Register R/W test fail*/ +#define ZM_ERR_CLEAR_INTERRUPT_FLAG 111 +#define ZM_ERR_COMMAND_RESPONSE 112 +#define ZM_ERR_INTERRUPT_GENERATE 113 +#define ZM_ERR_INTERRUPT_ACK 114 +#define ZM_ERR_SCRATCH_ACCESS 115 +#define ZM_ERR_INTERRUPT_MASK_ACCESS 116 +#define ZM_ERR_SHARE_MEMORY_PCI_ACCESS 117 +#define ZM_ERR_SHARE_MEMORY_FW_ACCESS 118 +#define ZM_ERR_SHARE_MEMORY_DISABLE 119 +#define ZM_ERR_SHARE_MEMORY_TEST_RESPONSE 120 + +/* Firmware Download error code */ +#define ZM_ERR_FIRMWARE_DOWNLOAD_TIMEOUT 150 +#define ZM_ERR_FIRMWARE_DOWNLOAD_INT_FLAG 151 +#define ZM_ERR_FIRMWARE_READY_TIMEOUT 152 +#define ZM_ERR_FIRMWARE_WRONG_TYPE 153 + +/* Debug */ +#define ZM_LV_0 0//Debug level 0, Disable debug message +#define ZM_LV_1 1//Debug level 1, Show minimum information +#define ZM_LV_2 2//Debug level 2, Show medium message +#define ZM_LV_3 3//Debug level 3, Show all + +#define ZM_SCANMSG_LEV ZM_LV_1 +#define ZM_TXMSG_LEV ZM_LV_0//ZM_LV_0 +#define ZM_RXMSG_LEV ZM_LV_0 +#define ZM_MMMSG_LEV ZM_LV_0 +#define ZM_DESMSG_LEV ZM_LV_0//ZM_LV_0 +#define ZM_BUFMSG_LEV ZM_LV_0//ZM_LV_1 +#define ZM_INITMSG_LEV ZM_LV_0 + +#define zm_msg0_scan(lv, msg) if (ZM_SCANMSG_LEV >= lv) \ + {zm_debug_msg0(msg);} +#define zm_msg1_scan(lv, msg, val) if (ZM_SCANMSG_LEV >= lv) \ + {zm_debug_msg1(msg, val);} +#define zm_msg2_scan(lv, msg, val) if (ZM_SCANMSG_LEV >= lv) \ + {zm_debug_msg2(msg, val);} + +#define zm_msg0_tx(lv, msg) if (ZM_TXMSG_LEV >= lv) \ + {zm_debug_msg0(msg);} +#define zm_msg1_tx(lv, msg, val) if (ZM_TXMSG_LEV >= lv) \ + {zm_debug_msg1(msg, val);} +#define zm_msg2_tx(lv, msg, val) if (ZM_TXMSG_LEV >= lv) \ + {zm_debug_msg2(msg, val);} + +#define zm_msg0_rx(lv, msg) if (ZM_RXMSG_LEV >= lv) \ + {zm_debug_msg0(msg);} +#define zm_msg1_rx(lv, msg, val) if (ZM_RXMSG_LEV >= lv) \ + {zm_debug_msg1(msg, val);} +#define zm_msg2_rx(lv, msg, val) if (ZM_RXMSG_LEV >= lv) \ + {zm_debug_msg2(msg, val);} + +#define zm_msg0_mm(lv, msg) if (ZM_MMMSG_LEV >= lv) \ + {zm_debug_msg0(msg);} +#define zm_msg1_mm(lv, msg, val) if (ZM_MMMSG_LEV >= lv) \ + {zm_debug_msg1(msg, val);} +#define zm_msg2_mm(lv, msg, val) if (ZM_MMMSG_LEV >= lv) \ + {zm_debug_msg2(msg, val);} + +#define zm_msg0_des(lv, msg) if (ZM_DESMSG_LEV >= lv) \ + {zm_debug_msg0(msg);} +#define zm_msg1_des(lv, msg, val) if (ZM_DESMSG_LEV >= lv) \ + {zm_debug_msg1(msg, val);} +#define zm_msg2_des(lv, msg, val) if (ZM_DESMSG_LEV >= lv) \ + {zm_debug_msg2(msg, val);} + +#define zm_msg0_buf(lv, msg) if (ZM_BUFMSG_LEV >= lv) \ + {zm_debug_msg0(msg);} +#define zm_msg1_buf(lv, msg, val) if (ZM_BUFMSG_LEV >= lv) \ + {zm_debug_msg1(msg, val);} +#define zm_msg2_buf(lv, msg, val) if (ZM_BUFMSG_LEV >= lv) \ + {zm_debug_msg2(msg, val);} + +#define zm_msg0_init(lv, msg) if (ZM_INITMSG_LEV >= lv) \ + {zm_debug_msg0(msg);} +#define zm_msg1_init(lv, msg, val) if (ZM_INITMSG_LEV >= lv) \ + {zm_debug_msg1(msg, val);} +#define zm_msg2_init(lv, msg, val) if (ZM_INITMSG_LEV >= lv) \ + {zm_debug_msg2(msg, val);} + +#define ZM_MAX_AP_SUPPORT 2 /* Must <= 8 */ +#define ZM_MAX_WDS_SUPPORT 6 /* Must <= 6 */ +#define ZM_MAX_STA_SUPPORT 16 /* Must <= 64 */ + +/* STA table state */ +#define ZM_STATE_AUTH 1 +#define ZM_STATE_PREAUTH 2 +#define ZM_STATE_ASOC 3 + +/* Rate set */ +#define ZM_RATE_SET_CCK 0 +#define ZM_RATE_SET_OFDM 1 + +/* HT PT */ +#define ZM_PREAMBLE_TYPE_MIXED_MODE 0 +#define ZM_PREAMBLE_TYPE_GREEN_FIELD 1 + +/* HT bandwidth */ +#define ZM_BANDWIDTH_20MHZ 0 +#define ZM_BANDWIDTH_40MHZ 1 + +/* MIC status */ +#define ZM_MIC_SUCCESS 0 +#define ZM_MIC_FAILURE 1 + +/* ICV status */ +#define ZM_ICV_SUCCESS 0 +#define ZM_ICV_FAILURE 1 + +/* definition check */ +#if (ZM_MAX_AP_SUPPORT > 8) +definition error, ZM_MAX_AP_SUPPORT > 8 +#endif +#if (ZM_MAX_AP_SUPPORT > 64) +definition error, ZM_MAX_STA_SUPPORT > 64 +#endif + +/* Transmission Rate information */ + +/* WLAN frame format */ +#define ZM_PLCP_HEADER_SIZE 5 +#define ZM_ETHERNET_ADDRESS_LENGTH 6 +#define ZM_TIMESTAMP_OFFSET 0 +#define ZM_BEACON_INTERVAL_OFFSET 8 +#define ZM_CAPABILITY_OFFSET 10 + +/* Reason Code */ +/* An unsolicited notification management frame of */ +/* type Disassocation or Deauthentication was generated. */ +#ifdef ZM_REASON_CODE +#define ZM_WLAN_REASON_CODE_UNSPECIFIED 1 +#define ZM_WLAN_FRAME_DISASOC_DEAUTH_REASON_CODE 24 +#endif + +struct zsWlanManagementFrameHeader +{ + //u8_t plcpHdr[ZM_PLCP_HEADER_SIZE]; + u8_t frameCtrl[2]; + u8_t duration[2]; + u8_t da[ZM_ETHERNET_ADDRESS_LENGTH]; + u8_t sa[ZM_ETHERNET_ADDRESS_LENGTH]; + u8_t bssid[ZM_ETHERNET_ADDRESS_LENGTH]; + u8_t seqCtrl[2]; + u8_t body[1]; +}; + +struct zsWlanProbeRspFrameHeader +{ + //u8_t plcpHdr[ZM_PLCP_HEADER_SIZE]; + u8_t frameCtrl[2]; + u8_t duration[2]; + u8_t da[ZM_ETHERNET_ADDRESS_LENGTH]; + u8_t sa[ZM_ETHERNET_ADDRESS_LENGTH]; + u8_t bssid[ZM_ETHERNET_ADDRESS_LENGTH]; + u8_t seqCtrl[2]; + u8_t timeStamp[8]; + u8_t beaconInterval[2]; + u8_t capability[2]; + u8_t ssid[ZM_MAX_SSID_LENGTH + 2]; // EID(1) + Length(1) + SSID(32) +} ; + +#define zsWlanBeaconFrameHeader zsWlanProbeRspFrameHeader + +struct zsWlanAuthFrameHeader +{ + //u8_t plcpHdr[ZM_PLCP_HEADER_SIZE]; + u8_t frameCtrl[2]; + u8_t duration[2]; + u8_t address1[ZM_ETHERNET_ADDRESS_LENGTH]; + u8_t address2[ZM_ETHERNET_ADDRESS_LENGTH]; + u8_t address3[ZM_ETHERNET_ADDRESS_LENGTH]; + u8_t seqCtrl[2]; + u16_t algo; + u16_t seq; + u16_t status; + u8_t challengeText[255]; // the first 2 bytes are information ID, length +}; + +struct zsWlanAssoFrameHeader +{ + //u8_t plcpHdr[PLCP_HEADER_SIZE]; + u8_t frameCtrl[2]; + u8_t duration[2]; + u8_t address1[ZM_ETHERNET_ADDRESS_LENGTH]; + u8_t address2[ZM_ETHERNET_ADDRESS_LENGTH]; + u8_t address3[ZM_ETHERNET_ADDRESS_LENGTH]; + u8_t seqCtrl[2]; + u8_t capability[2]; + u16_t status; + u16_t aid; + //u8_t supportedRates[10]; +}; + +struct zsFrag +{ + zbuf_t* buf[16]; + u16_t bufType[16]; + u16_t seq[16]; + u8_t flag[16]; + +}; + +//================================ +// Hardware related definitions +//================================ +#define ZM_MAC_REG_BASE 0x1c3000 + +#define ZM_MAC_REG_ATIM_WINDOW (ZM_MAC_REG_BASE + 0x51C) +#define ZM_MAC_REG_BCN_PERIOD (ZM_MAC_REG_BASE + 0x520) +#define ZM_MAC_REG_PRETBTT (ZM_MAC_REG_BASE + 0x524) + +#define ZM_MAC_REG_MAC_ADDR_L (ZM_MAC_REG_BASE + 0x610) +#define ZM_MAC_REG_MAC_ADDR_H (ZM_MAC_REG_BASE + 0x614) + +#define ZM_MAC_REG_GROUP_HASH_TBL_L (ZM_MAC_REG_BASE + 0x624) +#define ZM_MAC_REG_GROUP_HASH_TBL_H (ZM_MAC_REG_BASE + 0x628) + +#define ZM_MAC_REG_BASIC_RATE (ZM_MAC_REG_BASE + 0x630) +#define ZM_MAC_REG_MANDATORY_RATE (ZM_MAC_REG_BASE + 0x634) +#define ZM_MAC_REG_RTS_CTS_RATE (ZM_MAC_REG_BASE + 0x638) +#define ZM_MAC_REG_BACKOFF_PROTECT (ZM_MAC_REG_BASE + 0x63c) +#define ZM_MAC_REG_RX_THRESHOLD (ZM_MAC_REG_BASE + 0x640) +#define ZM_MAC_REG_RX_PE_DELAY (ZM_MAC_REG_BASE + 0x64C) + +#define ZM_MAC_REG_DYNAMIC_SIFS_ACK (ZM_MAC_REG_BASE + 0x658) +#define ZM_MAC_REG_SNIFFER (ZM_MAC_REG_BASE + 0x674) +#define ZM_MAC_REG_TX_UNDERRUN (ZM_MAC_REG_BASE + 0x688) +#define ZM_MAC_REG_RX_TOTAL (ZM_MAC_REG_BASE + 0x6A0) +#define ZM_MAC_REG_RX_CRC32 (ZM_MAC_REG_BASE + 0x6A4) +#define ZM_MAC_REG_RX_CRC16 (ZM_MAC_REG_BASE + 0x6A8) +#define ZM_MAC_REG_RX_ERR_UNI (ZM_MAC_REG_BASE + 0x6AC) +#define ZM_MAC_REG_RX_OVERRUN (ZM_MAC_REG_BASE + 0x6B0) +#define ZM_MAC_REG_RX_ERR_MUL (ZM_MAC_REG_BASE + 0x6BC) +#define ZM_MAC_REG_TX_RETRY (ZM_MAC_REG_BASE + 0x6CC) +#define ZM_MAC_REG_TX_TOTAL (ZM_MAC_REG_BASE + 0x6F4) + + +#define ZM_MAC_REG_ACK_EXTENSION (ZM_MAC_REG_BASE + 0x690) +#define ZM_MAC_REG_EIFS_AND_SIFS (ZM_MAC_REG_BASE + 0x698) + +#define ZM_MAC_REG_SLOT_TIME (ZM_MAC_REG_BASE + 0x6F0) + +#define ZM_MAC_REG_ROLL_CALL_TBL_L (ZM_MAC_REG_BASE + 0x704) +#define ZM_MAC_REG_ROLL_CALL_TBL_H (ZM_MAC_REG_BASE + 0x708) + +#define ZM_MAC_REG_AC0_CW (ZM_MAC_REG_BASE + 0xB00) +#define ZM_MAC_REG_AC1_CW (ZM_MAC_REG_BASE + 0xB04) +#define ZM_MAC_REG_AC2_CW (ZM_MAC_REG_BASE + 0xB08) +#define ZM_MAC_REG_AC3_CW (ZM_MAC_REG_BASE + 0xB0C) +#define ZM_MAC_REG_AC4_CW (ZM_MAC_REG_BASE + 0xB10) +#define ZM_MAC_REG_AC1_AC0_AIFS (ZM_MAC_REG_BASE + 0xB14) +#define ZM_MAC_REG_AC3_AC2_AIFS (ZM_MAC_REG_BASE + 0xB18) + +#define ZM_MAC_REG_RETRY_MAX (ZM_MAC_REG_BASE + 0xB28) + +#define ZM_MAC_REG_TXOP_NOT_ENOUGH_INDICATION (ZM_MAC_REG_BASE + 0xB30) + +#define ZM_MAC_REG_AC1_AC0_TXOP (ZM_MAC_REG_BASE + 0xB44) +#define ZM_MAC_REG_AC3_AC2_TXOP (ZM_MAC_REG_BASE + 0xB48) + +#define ZM_MAC_REG_ACK_TABLE (ZM_MAC_REG_BASE + 0xC00) + +#define ZM_MAC_REG_BCN_ADDR (ZM_MAC_REG_BASE + 0xD84) +#define ZM_MAC_REG_BCN_LENGTH (ZM_MAC_REG_BASE + 0xD88) + +#define ZM_MAC_REG_BCN_PLCP (ZM_MAC_REG_BASE + 0xD90) +#define ZM_MAC_REG_BCN_CTRL (ZM_MAC_REG_BASE + 0xD94) + +#define ZM_MAC_REG_BCN_HT1 (ZM_MAC_REG_BASE + 0xDA0) +#define ZM_MAC_REG_BCN_HT2 (ZM_MAC_REG_BASE + 0xDA4) + + +#define ZM_RX_STATUS_IS_MIC_FAIL(rxStatus) rxStatus->Tail.Data.ErrorIndication & ZM_BIT_6 + +//================================ +//================================ + +#ifdef ZM_ENABLE_NATIVE_WIFI +#define ZM_80211_FRAME_HEADER_LEN 24 +#define ZM_80211_FRAME_TYPE_OFFSET 30 // ZM_80211_FRAME_HEADER_LEN + SNAP +#define ZM_80211_FRAME_IP_OFFSET 32 // ZM_80211_FRAME_HEADER_LEN + SNAP + TYPE +#else +#define ZM_80211_FRAME_HEADER_LEN 14 +#define ZM_80211_FRAME_TYPE_OFFSET 12 // ZM_80211_FRAME_HEADER_LEN + SNAP +#define ZM_80211_FRAME_IP_OFFSET 14 // ZM_80211_FRAME_HEADER_LEN + SNAP + TYPE +#endif + +#define ZM_BSS_INFO_VALID_BIT 0x01 +#define ZM_BSS_INFO_UPDATED_BIT 0x02 + + + + + +#define ZM_ERROR_INDICATION_RX_TIMEOUT 0x01 +#define ZM_ERROR_INDICATION_OVERRUN 0x02 +#define ZM_ERROR_INDICATION_DECRYPT_ERROR 0x04 +#define ZM_ERROR_INDICATION_CRC32_ERROR 0x08 +#define ZM_ERROR_INDICATION_ADDR_NOT_MATCH 0x10 +#define ZM_ERROR_INDICATION_CRC16_ERROR 0x20 +#define ZM_ERROR_INDICATION_MIC_ERROR 0x40 + +#define ZM_RXMAC_STATUS_MOD_TYPE_CCK 0x00 +#define ZM_RXMAC_STATUS_MOD_TYPE_OFDM 0x01 +#define ZM_RXMAC_STATUS_MOD_TYPE_HT_OFDM 0x02 +#define ZM_RXMAC_STATUS_MOD_TYPE_DL_OFDM 0x03 +#define ZM_RXMAC_STATUS_TOTAL_ERROR 0x80 + + + + + +#define ZM_MAX_LED_NUMBER 2 + +#define ZM_LED_DISABLE_MODE 0x0 +#define ZM_LED_LINK_MODE 0x1 +#define ZM_LED_LINK_TR_MODE 0x2 +#define ZM_LED_TR_ON_MODE 0x3 +#define ZM_LED_TR_OFF_MODE 0x4 + +#define ZM_LED_CTRL_FLAG_ALPHA 0x1 + +struct zsLedStruct +{ + u32_t counter; + u32_t counter100ms; + u16_t ledLinkState; + u16_t ledMode[ZM_MAX_LED_NUMBER]; + u32_t txTraffic; + u32_t rxTraffic; + u8_t LEDCtrlType; + u8_t LEDCtrlFlag; // Control Flag for vendors + u8_t LEDCtrlFlagFromReg; // Control Flag for vendors in registry +}; + + +//HAL+ capability bits definition +#define ZM_HP_CAP_11N 0x1 +#define ZM_HP_CAP_11N_ONE_TX_STREAM 0x2 +#define ZM_HP_CAP_2G 0x4 +#define ZM_HP_CAP_5G 0x8 + +#endif /* #ifndef _WLAN_H */ --- linux-2.6.28.orig/drivers/staging/otus/80211core/amsdu.c +++ linux-2.6.28/drivers/staging/otus/80211core/amsdu.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "cprecomp.h" + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfGetAmsduSubFrame */ +/* Get a subframe from a-MSDU. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : A-MSDU frame buffer */ +/* offset : offset of subframe in the A-MSDU */ +/* */ +/* OUTPUTS */ +/* NULL or subframe */ +/* */ +/* AUTHOR */ +/* Stephen Chen Atheros Communications, INC. 2007.2 */ +/* */ +/************************************************************************/ +zbuf_t* zfGetAmsduSubFrame(zdev_t* dev, zbuf_t* buf, u16_t* offset) +{ + u16_t subframeLen; + u16_t amsduLen = zfwBufGetSize(dev, buf); + zbuf_t* newBuf; + + ZM_PERFORMANCE_RX_AMSDU(dev, buf, amsduLen); + + /* Verify A-MSDU length */ + if (amsduLen < (*offset + 14)) + { + return NULL; + } + + /* Locate A-MSDU subframe by offset and verify subframe length */ + subframeLen = (zmw_buf_readb(dev, buf, *offset + 12) << 8) + + zmw_buf_readb(dev, buf, *offset + 13); + if (subframeLen == 0) + { + return NULL; + } + + /* Verify A-MSDU subframe length */ + if ((*offset+14+subframeLen) <= amsduLen) + { + /* Allocate a new buffer */ + if ((newBuf = zfwBufAllocate(dev, 24+2+subframeLen)) != NULL) + { +#ifdef ZM_ENABLE_NATIVE_WIFI + /* Copy and convert subframe to wlan frame format */ + /* SHALL NOT INCLUDE QOS and AMSDU header. Ray 20070807 For Vista */ + zfRxBufferCopy(dev, newBuf, buf, 0, 0, 24); + zfRxBufferCopy(dev, newBuf, buf, 24, *offset+14, subframeLen); + zfwBufSetSize(dev, newBuf, 24+subframeLen); +#else + /* Copy subframe to new buffer */ + zfRxBufferCopy(dev, newBuf, buf, 0, *offset, 14+subframeLen); + zfwBufSetSize(dev, newBuf, 14+subframeLen); +#endif + /* Update offset */ + *offset += (((14+subframeLen)+3) & 0xfffc); + + /* Return buffer pointer */ + return newBuf; + } + } + return NULL; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfDeAmsdu */ +/* De-AMSDU. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : A-MSDU frame buffer */ +/* vap : VAP port */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Stephen Chen Atheros Communications, INC. 2007.2 */ +/* */ +/************************************************************************/ +void zfDeAmsdu(zdev_t* dev, zbuf_t* buf, u16_t vap, u8_t encryMode) +{ + u16_t offset = ZM_SIZE_OF_WLAN_DATA_HEADER+ZM_SIZE_OF_QOS_CTRL; + zbuf_t* subframeBuf; + zmw_get_wlan_dev(dev); + + ZM_BUFFER_TRACE(dev, buf) + + if (encryMode == ZM_AES || encryMode == ZM_TKIP) + { + offset += (ZM_SIZE_OF_IV + ZM_SIZE_OF_EXT_IV); + } + else if (encryMode == ZM_WEP64 || encryMode == ZM_WEP128) + { + offset += ZM_SIZE_OF_IV; + } + + /* Repeatly calling zfGetAmsduSubFrame() until NULL returned */ + while ((subframeBuf = zfGetAmsduSubFrame(dev, buf, &offset)) != NULL) + { + wd->commTally.NotifyNDISRxFrmCnt++; + if (wd->zfcbRecvEth != NULL) + { + wd->zfcbRecvEth(dev, subframeBuf, (u8_t)vap); + ZM_PERFORMANCE_RX_MSDU(dev, wd->tick); + } + } + zfwBufFree(dev, buf, 0); + + return; +} --- linux-2.6.28.orig/drivers/staging/otus/80211core/cfunc.h +++ linux-2.6.28/drivers/staging/otus/80211core/cfunc.h @@ -0,0 +1,449 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* */ +/* Module Name : func_extr.c */ +/* */ +/* Abstract */ +/* This module contains function prototype. */ +/* */ +/* NOTES */ +/* None */ +/* */ +/************************************************************************/ + +#ifndef _CFUNC_H +#define _CFUNC_H + +#include "queue.h" + +/* amsdu.c */ +void zfDeAmsdu(zdev_t* dev, zbuf_t* buf, u16_t vap, u8_t encryMode); + +/* cscanmgr.c */ +void zfScanMgrInit(zdev_t* dev); +u8_t zfScanMgrScanStart(zdev_t* dev, u8_t scanType); +void zfScanMgrScanStop(zdev_t* dev, u8_t scanType); +void zfScanMgrScanAck(zdev_t* dev); + +/* cpsmgr.c */ +void zfPowerSavingMgrInit(zdev_t* dev); +void zfPowerSavingMgrSetMode(zdev_t* dev, u8_t mode); +void zfPowerSavingMgrMain(zdev_t* dev); +void zfPowerSavingMgrWakeup(zdev_t* dev); +u8_t zfPowerSavingMgrIsSleeping(zdev_t *dev); +void zfPowerSavingMgrProcessBeacon(zdev_t* dev, zbuf_t* buf); +void zfPowerSavingMgrAtimWinExpired(zdev_t* dev); +void zfPowerSavingMgrConnectNotify(zdev_t *dev); +void zfPowerSavingMgrPreTBTTInterrupt(zdev_t *dev); + +/* ccmd.c */ +u16_t zfWlanEnable(zdev_t* dev); + +/* cfunc.c */ +u8_t zfQueryOppositeRate(zdev_t* dev, u8_t dst_mac[6], u8_t frameType); +void zfCopyToIntTxBuffer(zdev_t* dev, zbuf_t* buf, u8_t* src, + u16_t offset, u16_t length); +void zfCopyToRxBuffer(zdev_t* dev, zbuf_t* buf, u8_t* src, + u16_t offset, u16_t length); +void zfCopyFromIntTxBuffer(zdev_t* dev, zbuf_t* buf, u8_t* dst, + u16_t offset, u16_t length); +void zfCopyFromRxBuffer(zdev_t* dev, zbuf_t* buf, u8_t* dst, + u16_t offset, u16_t length); +void zfMemoryCopy(u8_t* dst, u8_t* src, u16_t length); +void zfMemoryMove(u8_t* dst, u8_t* src, u16_t length); +void zfZeroMemory(u8_t* va, u16_t length); +u8_t zfMemoryIsEqual(u8_t* m1, u8_t* m2, u16_t length); +u8_t zfRxBufferEqualToStr(zdev_t* dev, zbuf_t* buf, const u8_t* str, + u16_t offset, u16_t length); +void zfTxBufferCopy(zdev_t*dev, zbuf_t* dst, zbuf_t* src, + u16_t dstOffset, u16_t srcOffset, u16_t length); +void zfRxBufferCopy(zdev_t*dev, zbuf_t* dst, zbuf_t* src, + u16_t dstOffset, u16_t srcOffset, u16_t length); + +void zfCollectHWTally(zdev_t*dev, u32_t* rsp, u8_t id); +void zfTimerInit(zdev_t* dev); +u16_t zfTimerSchedule(zdev_t* dev, u16_t event, u32_t tick); +u16_t zfTimerCancel(zdev_t* dev, u16_t event); +void zfTimerClear(zdev_t* dev); +u16_t zfTimerCheckAndHandle(zdev_t* dev); +void zfProcessEvent(zdev_t* dev, u16_t* eventArray, u8_t eventCount); + +void zfBssInfoCreate(zdev_t* dev); +void zfBssInfoDestroy(zdev_t* dev); + +struct zsBssInfo* zfBssInfoAllocate(zdev_t* dev); +void zfBssInfoFree(zdev_t* dev, struct zsBssInfo* pBssInfo); +void zfBssInfoReorderList(zdev_t* dev); +void zfBssInfoInsertToList(zdev_t* dev, struct zsBssInfo* pBssInfo); +void zfBssInfoRemoveFromList(zdev_t* dev, struct zsBssInfo* pBssInfo); +void zfBssInfoRefresh(zdev_t* dev, u16_t mode); +void zfCoreSetFrequencyComplete(zdev_t* dev); +void zfCoreSetFrequency(zdev_t* dev, u16_t frequency); +void zfCoreSetFrequencyV2(zdev_t* dev, u16_t frequency, + zfpFreqChangeCompleteCb cb); +void zfCoreSetFrequencyEx(zdev_t* dev, u16_t frequency, u8_t bw40, + u8_t extOffset, zfpFreqChangeCompleteCb cb); +void zfCoreSetFrequencyExV2(zdev_t* dev, u16_t frequency, u8_t bw40, + u8_t extOffset, zfpFreqChangeCompleteCb cb, u8_t forceSetFreq); +void zfReSetCurrentFrequency(zdev_t* dev); +u32_t zfCoreSetKey(zdev_t* dev, u8_t user, u8_t keyId, u8_t type, + u16_t* mac, u32_t* key); +void zfCoreSetKeyComplete(zdev_t* dev); +void zfCoreReinit(zdev_t* dev); +void zfCoreMacAddressNotify(zdev_t* dev, u8_t *addr); +void zfCoreSetIsoName(zdev_t* dev, u8_t* isoName); +void zfGenerateRandomBSSID(zdev_t* dev, u8_t *MACAddr, u8_t *BSSID); +void zfCoreHalInitComplete(zdev_t* dev); + +u16_t zfFindCleanFrequency(zdev_t* dev, u32_t adhocMode); +u16_t zfFindMinimumUtilizationChannelIndex(zdev_t* dev, u16_t* array, u16_t count); +u8_t zfCompareWithBssid(zdev_t* dev, u16_t* bssid); + +/* chb.c */ +void zfDumpBssList(zdev_t* dev); + + +u16_t zfIssueCmd(zdev_t* dev, u32_t* cmd, u16_t cmdLen, u16_t src, u8_t* buf); + + +/* cic.c */ +void zfUpdateBssid(zdev_t* dev, u8_t* bssid); +void zfResetSupportRate(zdev_t* dev, u8_t type); +void zfUpdateSupportRate(zdev_t* dev, u8_t* rateArray); +u8_t zfIsGOnlyMode(zdev_t* dev, u16_t frequency, u8_t* rateArray); +void zfGatherBMode(zdev_t* dev, u8_t* rateArray, u8_t* extrateArray); +u8_t zfPSDeviceSleep(zdev_t* dev); +u16_t zfGetRandomNumber(zdev_t* dev, u16_t initValue); +void zfCoreEvent(zdev_t* dev, u16_t event, u8_t* rsp); +void zfBeaconCfgInterrupt(zdev_t* dev, u8_t* rsp); +void zfEndOfAtimWindowInterrupt(zdev_t* dev); + +/* cinit.c */ +u16_t zfTxGenWlanHeader(zdev_t* dev, zbuf_t* buf, u16_t* header, u16_t seq, + u8_t flag, u16_t plusLen, u16_t minusLen, u16_t port, + u16_t* da, u16_t* sa, u8_t up, u16_t *micLen, + u16_t* snap, u16_t snapLen, struct aggControl *aggControl); +u16_t zfTxGenMmHeader(zdev_t* dev, u8_t frameType, u16_t* dst, + u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt); +void zfInitMacApMode(zdev_t* dev); +u16_t zfChGetNextChannel(zdev_t* dev, u16_t frequency, u8_t* pbPassive); +u16_t zfChGetFirstChannel(zdev_t* dev, u8_t* pbPassive); +u16_t zfChGetFirst2GhzChannel(zdev_t* dev); +u16_t zfChGetFirst5GhzChannel(zdev_t* dev); +u16_t zfChGetLastChannel(zdev_t* dev, u8_t* pbPassive); +u16_t zfChGetLast5GhzChannel(zdev_t* dev); +u16_t zfChNumToFreq(zdev_t* dev, u8_t ch, u8_t freqBand); +u8_t zfChFreqToNum(u16_t freq, u8_t* bIs5GBand); + +/* cmm.c */ +void zfProcessManagement(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* AddInfo); //CWYang(m) +void zfSendMmFrame(zdev_t* dev, u8_t frameType, u16_t* dst, + u32_t p1, u32_t p2, u32_t p3); +u16_t zfFindElement(zdev_t* dev, zbuf_t* buf, u8_t eid); +u16_t zfFindWifiElement(zdev_t* dev, zbuf_t* buf, u8_t type, u8_t subtype); +u16_t zfFindSuperGElement(zdev_t* dev, zbuf_t* buf, u8_t type); +u16_t zfFindXRElement(zdev_t* dev, zbuf_t* buf, u8_t type); +u16_t zfRemoveElement(zdev_t* dev, u8_t* buf, u16_t size, u8_t eid); +u16_t zfUpdateElement(zdev_t* dev, u8_t* buf, u16_t size, u8_t* updateeid); +void zfProcessProbeReq(zdev_t* dev, zbuf_t* buf, u16_t* src); +void zfProcessProbeRsp(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* AddInfo); +u16_t zfSendProbeReq(zdev_t* dev, zbuf_t* buf, u16_t offset, u8_t bWithSSID); +u16_t zfMmAddIeSupportRate(zdev_t* dev, zbuf_t* buf, + u16_t offset, u8_t eid, u8_t rateSet); +u16_t zfMmAddIeDs(zdev_t* dev, zbuf_t* buf, u16_t offset); +u16_t zfMmAddIeErp(zdev_t* dev, zbuf_t* buf, u16_t offset); +void zfUpdateDefaultQosParameter(zdev_t* dev, u8_t mode); +u16_t zfMmAddIeWpa(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t apId); +u16_t zfMmAddHTCapability(zdev_t* dev, zbuf_t* buf, u16_t offset); //CWYang(+) +u16_t zfMmAddPreNHTCapability(zdev_t* dev, zbuf_t* buf, u16_t offset); +u16_t zfMmAddExtendedHTCapability(zdev_t* dev, zbuf_t* buf, u16_t offset); //CWYang(+) +u16_t zfFindATHExtCap(zdev_t* dev, zbuf_t* buf, u8_t type, u8_t subtype); +u16_t zfFindBrdcmMrvlRlnkExtCap(zdev_t* dev, zbuf_t* buf); +u16_t zfFindMarvelExtCap(zdev_t* dev, zbuf_t* buf); +u16_t zfFindBroadcomExtCap(zdev_t* dev, zbuf_t* buf); +u16_t zfFindRlnkExtCap(zdev_t* dev, zbuf_t* buf); + +/* cmmap.c */ +void zfMmApTimeTick(zdev_t* dev); +void zfApAgingSta(zdev_t* dev); +u16_t zfApAddSta(zdev_t* dev, u16_t* addr, u16_t state, u16_t apId, u8_t type, + u8_t qosType, u8_t qosInfo); +void zfApProtctionMonitor(zdev_t* dev); +void zfApProcessBeacon(zdev_t* dev, zbuf_t* buf); +void zfApProcessAuth(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId); +void zfApProcessAsocReq(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId); +void zfApProcessAsocRsp(zdev_t* dev, zbuf_t* buf); +void zfApProcessDeauth(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId); +void zfApProcessDisasoc(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId); +void zfApProcessProbeRsp(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* AddInfo); +void zfApStoreAsocReqIe(zdev_t* dev, zbuf_t* buf, u16_t aid); +u16_t zfApAddIeSsid(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t vap); +void zfApSendBeacon(zdev_t* dev); +u16_t zfApGetSTAInfo(zdev_t* dev, u16_t* addr, u16_t* state, u8_t* vap); +u16_t zfIntrabssForward(zdev_t* dev, zbuf_t* buf, u8_t srcVap); +u16_t zfApBufferPsFrame(zdev_t* dev, zbuf_t* buf, u16_t port); +void zfApInitStaTbl(zdev_t* dev); +void zfApGetStaTxRateAndQosType(zdev_t* dev, u16_t* addr, u32_t* phyCtrl, + u8_t* qosType, u16_t* rcProbingFlag); +void zfApGetStaQosType(zdev_t* dev, u16_t* addr, u8_t* qosType); +void zfApSetStaTxRate(zdev_t* dev, u16_t* addr, u32_t phyCtrl); +struct zsMicVar* zfApGetRxMicKey(zdev_t* dev, zbuf_t* buf); +struct zsMicVar* zfApGetTxMicKey(zdev_t* dev, zbuf_t* buf, u8_t* qosType); +u16_t zfApAddIeWmePara(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t vap); +u16_t zfApUpdatePsBit(zdev_t* dev, zbuf_t* buf, u8_t* vap, u8_t* uapsdTrig); +void zfApProcessPsPoll(zdev_t* dev, zbuf_t* buf); +u16_t zfApFindSta(zdev_t* dev, u16_t* addr); +void zfApGetStaEncryType(zdev_t* dev, u16_t* addr, u8_t* encryType); +void zfApGetStaWpaIv(zdev_t* dev, u16_t* addr, u16_t* iv16, u32_t* iv32); +void zfApSetStaWpaIv(zdev_t* dev, u16_t* addr, u16_t iv16, u32_t iv32); +void zfApClearStaKey(zdev_t* dev, u16_t* addr); +#ifdef ZM_ENABLE_CENC +void zfApGetStaCencIvAndKeyIdx(zdev_t* dev, u16_t* addr, u32_t *iv, + u8_t *keyIdx); +void zfApSetStaCencIv(zdev_t* dev, u16_t* addr, u32_t *iv); +#endif //ZM_ENABLE_CENC +void zfApSetProtectionMode(zdev_t* dev, u16_t mode); +void zfApFlushBufferedPsFrame(zdev_t* dev); +void zfApSendFailure(zdev_t* dev, u8_t* addr); +u8_t zfApRemoveFromPsQueue(zdev_t* dev, u16_t id, u16_t* src); +void zfApProcessAction(zdev_t* dev, zbuf_t* buf); +/* cmmsta.c */ +void zfMmStaTimeTick(zdev_t* dev); +void zfReWriteBeaconStartAddress(zdev_t* dev); // Mxzeng +void zfStaProcessBeacon(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* AddInfo); //CWYang(m) +void zfStaProcessAuth(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId); +void zfStaProcessAsocReq(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId); +void zfStaProcessAsocRsp(zdev_t* dev, zbuf_t* buf); +void zfStaProcessDeauth(zdev_t* dev, zbuf_t* buf); +void zfStaProcessDisasoc(zdev_t* dev, zbuf_t* buf); +void zfStaProcessProbeRsp(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* AddInfo); +void zfStaProcessAtim(zdev_t* dev, zbuf_t* buf); +void zfStaStoreAsocRspIe(zdev_t* dev, zbuf_t* buf); +void zfStaChannelManagement(zdev_t* dev, u8_t scan); +void zfIbssConnectNetwork(zdev_t* dev); +void zfInfraConnectNetwork(zdev_t* dev); +u8_t zfCheckAuthentication(zdev_t* dev, struct zsBssInfo* pBssInfo); +u8_t zfChangeAdapterState(zdev_t* dev, u8_t newState); +u16_t zfStaAddIeSsid(zdev_t* dev, zbuf_t* buf, u16_t offset); +u16_t zfStaAddIeWpaRsn(zdev_t* dev, zbuf_t* buf, u16_t offset, u8_t frameType); +u16_t zfStaAddIeIbss(zdev_t* dev, zbuf_t* buf, u16_t offset); +void zfStaStartConnect(zdev_t* dev, u8_t bIsSharedKey); +u8_t zfStaIsConnected(zdev_t* dev); +u8_t zfStaIsConnecting(zdev_t* dev); +u8_t zfStaIsDisconnect(zdev_t* dev); +void zfStaSendBeacon(zdev_t* dev); +void zfSendNullData(zdev_t* dev, u8_t type); +void zfSendPSPoll(zdev_t* dev); +void zfSendBA(zdev_t* dev, u16_t start_seq, u8_t *bitmap); +void zdRateInfoCountTx(zdev_t* dev, u16_t* macAddr); +struct zsMicVar* zfStaGetRxMicKey(zdev_t* dev, zbuf_t* buf); +struct zsMicVar* zfStaGetTxMicKey(zdev_t* dev, zbuf_t* buf); +u16_t zfStaRxValidateFrame(zdev_t* dev, zbuf_t* buf); +void zfStaMicFailureHandling(zdev_t* dev, zbuf_t* buf); +u8_t zfStaBlockWlanScan(zdev_t* dev); +void zfStaIbssPSCheckState(zdev_t* dev, zbuf_t* buf); +u8_t zfStaIbssPSQueueData(zdev_t* dev, zbuf_t* buf); +void zfStaIbssPSSend(zdev_t* dev); +void zfStaResetStatus(zdev_t* dev, u8_t bInit); +u16_t zfStaAddIeWmeInfo(zdev_t* dev, zbuf_t* buf, u16_t offset, u8_t qosInfo); +void zfInitPartnerNotifyEvent(zdev_t* dev, zbuf_t* buf, struct zsPartnerNotifyEvent *event); +void zfStaInitOppositeInfo(zdev_t* dev); +void zfStaIbssMonitoring(zdev_t* dev, u8_t reset); +struct zsBssInfo* zfStaFindBssInfo(zdev_t* dev, zbuf_t* buf, struct zsWlanProbeRspFrameHeader *pProbeRspHeader); +u8_t zfStaInitBssInfo(zdev_t* dev, zbuf_t* buf, + struct zsWlanProbeRspFrameHeader *pProbeRspHeader, + struct zsBssInfo* pBssInfo, struct zsAdditionInfo* AddInfo, u8_t type); +s8_t zfStaFindFreeOpposite(zdev_t* dev, u16_t *sa, int *pFoundIdx); +s8_t zfStaFindOppositeByMACAddr(zdev_t* dev, u16_t *sa, u8_t *pFoundIdx); +void zfStaRefreshBlockList(zdev_t* dev, u16_t flushFlag); +void zfStaConnectFail(zdev_t* dev, u16_t reason, u16_t* bssid, u8_t weight); +void zfStaGetTxRate(zdev_t* dev, u16_t* macAddr, u32_t* phyCtrl, + u16_t* rcProbingFlag); +u16_t zfStaProcessAction(zdev_t* dev, zbuf_t* buf); +struct zsTkipSeed* zfStaGetRxSeed(zdev_t* dev, zbuf_t* buf); +#ifdef ZM_ENABLE_CENC +/* CENC */ +u16_t zfStaAddIeCenc(zdev_t* dev, zbuf_t* buf, u16_t offset); +#endif //ZM_ENABLE_CENC +void zfStaEnableSWEncryption(zdev_t *dev, u8_t value); +void zfStaDisableSWEncryption(zdev_t *dev); +u16_t zfComputeBssInfoWeightValue(zdev_t *dev, u8_t isBMode, u8_t isHT, u8_t isHT40, u8_t signalStrength); +u16_t zfStaAddIbssAdditionalIE(zdev_t* dev, zbuf_t* buf, u16_t offset); + +/* ctkip.c */ +void zfTkipInit(u8_t* key, u8_t* ta, struct zsTkipSeed* pSeed, u8_t* initIv); +void zfMicSetKey(u8_t* key, struct zsMicVar* pMic); +void zfMicAppendByte(u8_t b, struct zsMicVar* pMic); +void zfMicClear(struct zsMicVar* pMic); +void zfMicAppendTxBuf(zdev_t* dev, zbuf_t* buf, u8_t* da, u8_t* sa, + u16_t removeLen, u8_t* mic); +u8_t zfMicRxVerify(zdev_t* dev, zbuf_t* buf); +void zfMicGetMic(u8_t* dst, struct zsMicVar* pMic); +void zfCalTxMic(zdev_t *dev, zbuf_t *buf, u8_t *snap, u16_t snapLen, u16_t offset, u16_t *da, u16_t *sa, u8_t up, u8_t *mic); +void zfTKIPEncrypt(zdev_t *dev, zbuf_t *buf, u8_t *snap, u16_t snapLen, u16_t offset, u8_t keyLen, u8_t* key, u32_t* icv); +u16_t zfTKIPDecrypt(zdev_t *dev, zbuf_t *buf, u16_t offset, u8_t keyLen, u8_t* key); +void zfTkipGetseeds(u16_t iv16, u8_t *RC4Key, struct zsTkipSeed *Seed); +u8_t zfTkipPhase1KeyMix(u32_t iv32, struct zsTkipSeed* pSeed); +u8_t zfTkipPhase2KeyMix(u16_t iv16, struct zsTkipSeed* pSeed); +void zfWEPEncrypt(zdev_t *dev, zbuf_t *buf, u8_t *snap, u16_t snapLen, u16_t offset, u8_t keyLen, u8_t* WepKey, u8_t *iv); +u16_t zfWEPDecrypt(zdev_t *dev, zbuf_t *buf, u16_t offset, u8_t keyLen, u8_t* WepKey, u8_t *iv); + +/* ctxrx.c */ +u16_t zfSend80211Frame(zdev_t* dev, zbuf_t* buf); +void zfIsrPciTxComp(zdev_t* dev); +void zfTxPciDmaStart(zdev_t* dev); +u16_t zfTxPortControl(zdev_t* dev, zbuf_t* buf, u16_t port); +u16_t zfTxSendEth(zdev_t* dev, zbuf_t* buf, u16_t port, + u16_t bufType, u16_t flag); +u16_t zfTxGenWlanTail(zdev_t* dev, zbuf_t* buf, u16_t* snap, u16_t snaplen, + u16_t* mic); +u16_t zfTxGenWlanSnap(zdev_t* dev, zbuf_t* buf, u16_t* snap, u16_t* snaplen); +void zfTxGetIpTosAndFrag(zdev_t* dev, zbuf_t* buf, u8_t* up, u16_t* fragOff); +u16_t zfPutVtxq(zdev_t* dev, zbuf_t* buf); +void zfPushVtxq(zdev_t* dev); +u8_t zfIsVtxqEmpty(zdev_t* dev); +u16_t zfGetSeqCtrl(zdev_t* dev, zbuf_t* buf, u16_t offset); +u8_t zfGetFragNo(zdev_t* dev, zbuf_t* buf); +void zfShowRxEAPOL(zdev_t* dev, zbuf_t* buf, u16_t offset); +void zfShowTxEAPOL(zdev_t* dev, zbuf_t* buf, u16_t offset); +void zfCoreRecv(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo); +u16_t zfPutVmmq(zdev_t* dev, zbuf_t* buf); +void zfFlushVtxq(zdev_t* dev); +void zfAgingDefragList(zdev_t* dev, u16_t flushFlag); + +void zfLed100msCtrl(zdev_t* dev); +void zf80211FrameSend(zdev_t* dev, zbuf_t* buf, u16_t* header, u16_t snapLen, + u16_t* da, u16_t* sa, u8_t up, u16_t headerLen, u16_t* snap, + u16_t* tail, u16_t tailLen, u16_t offset, u16_t bufType, + u8_t ac, u8_t keyIdx); +void zfCheckIsRIFSFrame(zdev_t* dev, zbuf_t* buf, u16_t frameSubType); + +/* queue.c */ +struct zsQueue* zfQueueCreate(zdev_t* dev, u16_t size); +void zfQueueDestroy(zdev_t* dev, struct zsQueue* q); +u16_t zfQueuePutNcs(zdev_t* dev, struct zsQueue* q, zbuf_t* buf, u32_t tick); +u16_t zfQueuePut(zdev_t* dev, struct zsQueue* q, zbuf_t* buf, u32_t tick); +zbuf_t* zfQueueGet(zdev_t* dev, struct zsQueue* q); +zbuf_t* zfQueueGetWithMac(zdev_t* dev, struct zsQueue* q, u8_t* addr, u8_t* mb); +void zfQueueFlush(zdev_t* dev, struct zsQueue* q); +void zfQueueAge(zdev_t* dev, struct zsQueue* q, u32_t tick, u32_t msAge); +void zfQueueGenerateUapsdTim(zdev_t* dev, struct zsQueue* q, + u8_t* uniBitMap, u16_t* highestByte); + +/* hpmain.c */ +u16_t zfHpInit(zdev_t* dev, u32_t frequency); +u16_t zfHpRelease(zdev_t* dev); +void zfHpSetFrequencyEx(zdev_t* dev, u32_t frequency, u8_t bw40, + u8_t extOffset, u8_t initRF); +u16_t zfHpStartRecv(zdev_t* dev); +u16_t zfHpStopRecv(zdev_t* dev); +u16_t zfHpResetKeyCache(zdev_t* dev); +u16_t zfHpSetApStaMode(zdev_t* dev, u8_t mode); +u16_t zfHpSetBssid(zdev_t* dev, u8_t* bssid); +u16_t zfHpSetSnifferMode(zdev_t* dev, u16_t on); +u8_t zfHpUpdateQosParameter(zdev_t* dev, u16_t* cwminTbl, u16_t* cwmaxTbl, + u16_t* aifsTbl, u16_t* txopTbl); +void zfHpSetAtimWindow(zdev_t* dev, u16_t atimWin); +void zfHpEnableBeacon(zdev_t* dev, u16_t mode, u16_t bcnInterval, u16_t dtim, u8_t enableAtim); +void zfHpDisableBeacon(zdev_t* dev); +void zfHpSetBasicRateSet(zdev_t* dev, u16_t bRateBasic, u16_t gRateBasic); +void zfHpSetRTSCTSRate(zdev_t* dev, u32_t rate); +void zfHpSetMacAddress(zdev_t* dev, u16_t* macAddr, u16_t macAddrId); +u32_t zfHpGetMacAddress(zdev_t* dev); +u32_t zfHpGetTransmitPower(zdev_t* dev); +void zfHpSetMulticastList(zdev_t* dev, u8_t size, u8_t* pList, u8_t bAllMulticast); + +u16_t zfHpRemoveKey(zdev_t* dev, u16_t user); +u32_t zfHpSetKey(zdev_t* dev, u8_t user, u8_t keyId, u8_t type, + u16_t* mac, u32_t* key); +//u32_t zfHpSetStaPairwiseKey(zdev_t* dev, u16_t* apMacAddr, u8_t type, +// u32_t* key, u32_t* micKey); +//u32_t zfHpSetStaGroupKey(zdev_t* dev, u16_t* apMacAddr, u8_t type, +// u32_t* key, u32_t* micKey); +u32_t zfHpSetApPairwiseKey(zdev_t* dev, u16_t* staMacAddr, u8_t type, + u32_t* key, u32_t* micKey, u16_t staAid); +u32_t zfHpSetApGroupKey(zdev_t* dev, u16_t* apMacAddr, u8_t type, + u32_t* key, u32_t* micKey, u16_t vapId); +u32_t zfHpSetDefaultKey(zdev_t* dev, u8_t keyId, u8_t type, u32_t* key, u32_t* micKey); +u32_t zfHpSetPerUserKey(zdev_t* dev, u8_t user, u8_t keyId, u8_t* mac, u8_t type, u32_t* key, u32_t* micKey); + +void zfHpSendBeacon(zdev_t* dev, zbuf_t* buf, u16_t len); +u16_t zfHpGetPayloadLen(zdev_t* dev, + zbuf_t* buf, + u16_t len, + u16_t plcpHdrLen, + u32_t *rxMT, + u32_t *rxMCS, + u32_t *rxBW, + u32_t *rxSG + ); +u32_t zfHpGetFreeTxdCount(zdev_t* dev); +u32_t zfHpGetMaxTxdCount(zdev_t* dev); +u16_t zfHpSend(zdev_t* dev, u16_t* header, u16_t headerLen, + u16_t* snap, u16_t snapLen, u16_t* tail, u16_t tailLen, zbuf_t* buf, + u16_t offset, u16_t bufType, u8_t ac, u8_t keyIdx); +void zfHpGetRegulationTablefromRegionCode(zdev_t* dev, u16_t regionCode); +void zfHpGetRegulationTablefromCountry(zdev_t* dev, u16_t CountryCode); +u8_t zfHpGetRegulationTablefromISO(zdev_t* dev, u8_t *countryInfo, u8_t length); +const char* zfHpGetisoNamefromregionCode(zdev_t* dev, u16_t regionCode); +u16_t zfHpGetRegionCodeFromIsoName(zdev_t* dev, u8_t *countryIsoName); +u8_t zfHpGetRegulatoryDomain(zdev_t* dev); +void zfHpLedCtrl(zdev_t* dev, u16_t ledId, u8_t mode); +u16_t zfHpResetTxRx(zdev_t* dev); +u16_t zfHpDeleteAllowChannel(zdev_t* dev, u16_t freq); +u16_t zfHpAddAllowChannel(zdev_t* dev, u16_t freq); +u32_t zfHpCwmUpdate(zdev_t* dev); +u32_t zfHpAniUpdate(zdev_t* dev); +u32_t zfHpAniUpdateRssi(zdev_t* dev, u8_t rssi); +void zfHpAniAttach(zdev_t* dev); +void zfHpAniArPoll(zdev_t* dev, u32_t listenTime, u32_t phyCnt1, u32_t phyCnt2); +void zfHpHeartBeat(zdev_t* dev); +void zfHpPowerSaveSetState(zdev_t* dev, u8_t psState); +void zfHpPowerSaveSetMode(zdev_t* dev, u8_t staMode, u8_t psMode, u16_t bcnInterval); +u16_t zfHpIsDfsChannel(zdev_t* dev, u16_t freq); +u16_t zfHpIsDfsChannelNCS(zdev_t* dev, u16_t freq); +u16_t zfHpFindFirstNonDfsChannel(zdev_t* dev, u16_t aBand); +u16_t zfHpIsAllowedChannel(zdev_t* dev, u16_t freq); +void zfHpDisableDfsChannel(zdev_t* dev, u8_t disableFlag); +void zfHpSetTTSIFSTime(zdev_t* dev, u8_t sifs_time); + +void zfHpQueryMonHalRxInfo(zdev_t* dev, u8_t *monHalRxInfo); + +void zfDumpSSID(u8_t length, u8_t *value); +void zfHpSetAggPktNum(zdev_t* dev, u32_t num); +void zfHpSetMPDUDensity(zdev_t* dev, u8_t density); +void zfHpSetSlotTime(zdev_t* dev, u8_t type); +void zfHpSetSlotTimeRegister(zdev_t* dev, u8_t type); +void zfHpSetRifs(zdev_t* dev, u8_t ht_enable, u8_t ht2040, u8_t g_mode); +void zfHpBeginSiteSurvey(zdev_t* dev, u8_t status); +void zfHpFinishSiteSurvey(zdev_t* dev, u8_t status); +u16_t zfHpEnableHwRetry(zdev_t* dev); +u16_t zfHpDisableHwRetry(zdev_t* dev); +void zfHpSWDecrypt(zdev_t* dev, u8_t enable); +void zfHpSWEncrypt(zdev_t* dev, u8_t enable); +u32_t zfHpCapability(zdev_t* dev); +void zfHpSetRollCallTable(zdev_t* dev); +u8_t zfHpregulatoryDomain(zdev_t* dev); +u16_t zfStaAddIePowerCap(zdev_t* dev, zbuf_t* buf, u16_t offset); +u8_t zfHpGetMaxTxPower(zdev_t* dev); +u8_t zfHpGetMinTxPower(zdev_t* dev); +u16_t zfStaAddIeSupportCh(zdev_t* dev, zbuf_t* buf, u16_t offset); +void zfHpEnableRifs(zdev_t* dev, u8_t mode24g, u8_t modeHt, u8_t modeHt2040); +void zfHpDisableRifs(zdev_t* dev); +u16_t zfHpUsbReset(zdev_t* dev); + + +#endif /* #ifndef _CFUNC_H */ --- linux-2.6.28.orig/drivers/staging/otus/80211core/pub_zfi.h +++ linux-2.6.28/drivers/staging/otus/80211core/pub_zfi.h @@ -0,0 +1,821 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _PUB_DEFS_H +#define _PUB_DEFS_H + +#include "../oal_dt.h" + +/***** Section 1 : Tunable Parameters *****/ +/* The defintions in this section are tunabel parameters */ + +/* Maximum number of BSS that could be scaned */ +#define ZM_MAX_BSS 128 + +/* Maximum number of WPA2 PMKID that supported */ +#define ZM_PMKID_MAX_BSS_CNT 8 + +/* Enable aggregation and deaggregation */ +#define ZM_ENABLE_AGGREGATION + +#ifdef ZM_ENABLE_AGGREGATION + /* Enable BA failed retransmission in firmware */ + #define ZM_ENABLE_FW_BA_RETRANSMISSION + #define ZM_BYPASS_AGGR_SCHEDULING + //#define ZM_AGGR_BIT_ON +#endif + + +#ifndef ZM_FB50 +//#define ZM_FB50 +#endif + +#ifndef ZM_AP_DEBUG +//#define ZM_AP_DEBUG +#endif + +//#define ZM_ENABLE_BA_RATECTRL + +/***** End of section 1 *****/ + + +/***** Section 2 : Public Definitions, data structures and prototypes *****/ +/* function return status */ +#define ZM_STATUS_SUCCESS 0 +#define ZM_STATUS_FAILURE 1 + +// media connect status +#define ZM_STATUS_MEDIA_CONNECT 0x00 +#define ZM_STATUS_MEDIA_DISCONNECT 0x01 +#define ZM_STATUS_MEDIA_DISCONNECT_NOT_FOUND 0x02 +#define ZM_STATUS_MEDIA_DISABLED 0x03 +#define ZM_STATUS_MEDIA_CONNECTION_DISABLED 0x04 +#define ZM_STATUS_MEDIA_CONNECTION_RESET 0x05 +#define ZM_STATUS_MEDIA_RESET 0x06 +#define ZM_STATUS_MEDIA_DISCONNECT_DEAUTH 0x07 +#define ZM_STATUS_MEDIA_DISCONNECT_DISASOC 0x08 +#define ZM_STATUS_MEDIA_DISCONNECT_TIMEOUT 0x09 +#define ZM_STATUS_MEDIA_DISCONNECT_AUTH_FAILED 0x0a +#define ZM_STATUS_MEDIA_DISCONNECT_ASOC_FAILED 0x0b +#define ZM_STATUS_MEDIA_DISCONNECT_MIC_FAIL 0x0c +#define ZM_STATUS_MEDIA_DISCONNECT_UNREACHABLE 0x0d +#define ZM_STATUS_MEDIA_DISCONNECT_BEACON_MISS 0x0e + +// Packet Filter +#define ZM_PACKET_TYPE_DIRECTED 0x00000001 +#define ZM_PACKET_TYPE_MULTICAST 0x00000002 +#define ZM_PACKET_TYPE_ALL_MULTICAST 0x00000004 +#define ZM_PACKET_TYPE_BROADCAST 0x00000008 +#define ZM_PACKET_TYPE_PROMISCUOUS 0x00000020 + +/* BSS mode definition */ +/* TODO : The definitions here are coupled with XP's NDIS OID. */ +/* We can't be changed them freely, need to disarm this mine */ +#define ZM_MODE_IBSS 0 +#define ZM_MODE_INFRASTRUCTURE 1 +#define ZM_MODE_UNKNOWN 2 +#define ZM_MODE_INFRASTRUCTURE_MAX 3 +#define ZM_MODE_AP 4 +#define ZM_MODE_PSEUDO 5 + + +/* Authentication mode */ +#define ZM_AUTH_MODE_OPEN 0 +#define ZM_AUTH_MODE_SHARED_KEY 1 +#define ZM_AUTH_MODE_AUTO 2 +#define ZM_AUTH_MODE_WPA 3 +#define ZM_AUTH_MODE_WPAPSK 4 +#define ZM_AUTH_MODE_WPA_NONE 5 +#define ZM_AUTH_MODE_WPA2 6 +#define ZM_AUTH_MODE_WPA2PSK 7 +#ifdef ZM_ENABLE_CENC +#define ZM_AUTH_MODE_CENC 8 +#endif //ZM_ENABLE_CENC +#define ZM_AUTH_MODE_WPA_AUTO 9 +#define ZM_AUTH_MODE_WPAPSK_AUTO 10 + +// Encryption mode +#define ZM_NO_WEP 0x0 +#define ZM_AES 0x4 +#define ZM_TKIP 0x2 +#define ZM_WEP64 0x1 +#define ZM_WEP128 0x5 +#define ZM_WEP256 0x6 +#ifdef ZM_ENABLE_CENC +#define ZM_CENC 0x7 +#endif //ZM_ENABLE_CENC + +/* Encryption type for wep status */ +#define ZM_ENCRYPTION_WEP_DISABLED 0 +#define ZM_ENCRYPTION_WEP_ENABLED 1 +#define ZM_ENCRYPTION_WEP_KEY_ABSENT 2 +#define ZM_ENCRYPTION_NOT_SUPPORTED 3 +#define ZM_ENCRYPTION_TKIP 4 +#define ZM_ENCRYPTION_TKIP_KEY_ABSENT 5 +#define ZM_ENCRYPTION_AES 6 +#define ZM_ENCRYPTION_AES_KEY_ABSENT 7 + +#ifdef ZM_ENABLE_CENC +#define ZM_ENCRYPTION_CENC 8 +#endif //ZM_ENABLE_CENC + +/* security type */ +#define ZM_SECURITY_TYPE_NONE 0 +#define ZM_SECURITY_TYPE_WEP 1 +#define ZM_SECURITY_TYPE_WPA 2 + +#ifdef ZM_ENABLE_CENC +#define ZM_SECURITY_TYPE_CENC 3 +#endif //ZM_ENABLE_CENC + +/* Encryption Exemption Action Type */ +#define ZM_ENCRYPTION_EXEMPT_NO_EXEMPTION 0 +#define ZM_ENCRYPTION_EXEMPT_ALWAYS 1 + +/* MIC failure */ +#define ZM_MIC_PAIRWISE_ERROR 0x06 +#define ZM_MIC_GROUP_ERROR 0x0E + + +/* power save mode */ +#define ZM_STA_PS_NONE 0 +#define ZM_STA_PS_MAX 1 +#define ZM_STA_PS_FAST 2 +#define ZM_STA_PS_LIGHT 3 + +/* WME AC Type */ +#define ZM_WME_AC_BK 0 /* Background AC */ +#define ZM_WME_AC_BE 1 /* Best-effort AC */ +#define ZM_WME_AC_VIDEO 2 /* Video AC */ +#define ZM_WME_AC_VOICE 3 /* Voice AC */ + +/* Preamble type */ +#define ZM_PREAMBLE_TYPE_AUTO 0 +#define ZM_PREAMBLE_TYPE_LONG 1 +#define ZM_PREAMBLE_TYPE_SHORT 2 + +/* wireless modes constants */ +#define ZM_WIRELESS_MODE_5_54 0x01 ///< 5 GHz 54 Mbps +#define ZM_WIRELESS_MODE_5_108 0x02 ///< 5 GHz 108 Mbps +#define ZM_WIRELESS_MODE_24_11 0x04 ///< 2.4 GHz 11 Mbps +#define ZM_WIRELESS_MODE_24_54 0x08 ///< 2.4 GHz 54 Mbps +#define ZM_WIRELESS_MODE_24_108 0x10 ///< 2.4 GHz 108 Mbps +#define ZM_WIRELESS_MODE_49_13 0x100 ///< 4.9 GHz 13.5 Mbps, quarter rate chn-bandwidth = 5 +#define ZM_WIRELESS_MODE_49_27 0x200 ///< 4.9 GHz 27 Mbps, half rate chn-bandwidth = 10 +#define ZM_WIRELESS_MODE_49_54 0x400 ///< 4.9 GHz 54 Mbps, full rate chn-bandwidth = 20 +#define ZM_WIRELESS_MODE_5_300 0x1000 ///< 5 GHz 300 Mbps +#define ZM_WIRELESS_MODE_24_300 0x2000 ///< 2.4 GHz 300 Mbps +#define ZM_WIRELESS_MODE_5_130 0x4000 ///< 5 GHz 130 Mbps +#define ZM_WIRELESS_MODE_24_130 0x8000 ///< 2.4 GHz 130 Mbps + +#define ZM_WIRELESS_MODE_24_N (ZM_WIRELESS_MODE_24_130|ZM_WIRELESS_MODE_24_300) +#define ZM_WIRELESS_MODE_5_N (ZM_WIRELESS_MODE_5_130|ZM_WIRELESS_MODE_5_300) +#define ZM_WIRELESS_MODE_24 (ZM_WIRELESS_MODE_24_11|ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N) +#define ZM_WIRELESS_MODE_5 (ZM_WIRELESS_MODE_5_54|ZM_WIRELESS_MODE_5_N) + +/* AdHoc Mode with different band */ +#define ZM_ADHOCBAND_A 1 +#define ZM_ADHOCBAND_B 2 +#define ZM_ADHOCBAND_G 3 +#define ZM_ADHOCBAND_BG 4 +#define ZM_ADHOCBAND_ABG 5 + +/* Authentication algorithm in the field algNo of authentication frames */ +#define ZM_AUTH_ALGO_OPEN_SYSTEM 0x10000 /* Open system */ +#define ZM_AUTH_ALGO_SHARED_KEY 0x10001 /* Shared Key */ +#define ZM_AUTH_ALGO_LEAP 0x10080 /* Leap */ + +struct zsScanResult +{ + u32_t reserved; +}; + + +struct zsStastics +{ + u32_t reserved; +}; + +#define ZM_MAX_SUPP_RATES_IE_SIZE 12 +#define ZM_MAX_IE_SIZE 50 //100 +#define ZM_MAX_WPS_IE_SIZE 150 +#define ZM_MAX_PROBE_FRAME_BODY_SIZE 512//300 +#define ZM_MAX_COUNTRY_INFO_SIZE 20 + +#define ZM_MAX_SSID_LENGTH 32 +struct zsBssInfo +{ + u8_t macaddr[6]; + u8_t bssid[6]; + u8_t beaconInterval[2]; + u8_t capability[2]; + u8_t timeStamp[8]; + u8_t ssid[ZM_MAX_SSID_LENGTH + 2]; // EID(1) + Length(1) + SSID(32) + u8_t supportedRates[ZM_MAX_SUPP_RATES_IE_SIZE + 2]; // EID(1) + Length(1) + supported rates [12] + u8_t channel; + u16_t frequency; + u16_t atimWindow; + u8_t erp; + u8_t extSupportedRates[ZM_MAX_SUPP_RATES_IE_SIZE + 2]; // EID(1) + Length(1) + extended supported rates [12] + u8_t wpaIe[ZM_MAX_IE_SIZE + 2]; + u8_t wscIe[ZM_MAX_WPS_IE_SIZE + 2]; + u8_t rsnIe[ZM_MAX_IE_SIZE + 2]; +#ifdef ZM_ENABLE_CENC + u8_t cencIe[ZM_MAX_IE_SIZE + 2]; /* CENC */ /* half size because of memory exceed 64k boundary */ +#endif //ZM_ENABLE_CENC + u8_t securityType; + u8_t signalStrength; + u8_t signalQuality; + u16_t sortValue; + u8_t wmeSupport; + u8_t flag; + u8_t EnableHT; + u8_t enableHT40; + u8_t SG40; + u8_t extChOffset; + u8_t apCap; // bit0:11N AP + u16_t frameBodysize; + u8_t frameBody[ZM_MAX_PROBE_FRAME_BODY_SIZE]; + u8_t countryInfo[ZM_MAX_COUNTRY_INFO_SIZE + 2]; + u16_t athOwlAp; + u16_t marvelAp; + u16_t broadcomHTAp; + u32_t tick; + struct zsBssInfo* next; +}; + +struct zsBssList +{ + u8_t bssCount; + struct zsBssInfo* head; + struct zsBssInfo* tail; +}; + +struct zsBssListV1 +{ + u8_t bssCount; + struct zsBssInfo bssInfo[ZM_MAX_BSS]; +}; + +#define ZM_KEY_FLAG_GK 0x0001 +#define ZM_KEY_FLAG_PK 0X0002 +#define ZM_KEY_FLAG_AUTHENTICATOR 0x0004 +#define ZM_KEY_FLAG_INIT_IV 0x0008 +#define ZM_KEY_FLAG_DEFAULT_KEY 0x0010 + +#ifdef ZM_ENABLE_CENC +#define ZM_KEY_FLAG_CENC 0x0020 +#endif //ZM_ENABLE_CENC + +// Comment: For TKIP, key[0]~key[15] => TKIP key +// key[16]~key[23] => Tx MIC key +// key[24]~key[31] => Rx MIC key +struct zsKeyInfo +{ + u8_t* key; + u8_t keyLength; + u8_t keyIndex; + u8_t* initIv; + u16_t flag; + u8_t vapId; + u16_t vapAddr[3]; + u16_t* macAddr; +}; + + + +/* + * Channels are specified by frequency. + */ +typedef struct { + u16_t channel; /* setting in Mhz */ + u32_t channelFlags; /* see below */ + u8_t privFlags; + s8_t maxRegTxPower; /* max regulatory tx power in dBm */ + s8_t maxTxPower; /* max true tx power in 0.25 dBm */ + s8_t minTxPower; /* min true tx power in 0.25 dBm */ +} ZM_HAL_CHANNEL; + +struct zsRegulationTable +{ + u16_t regionCode; + u16_t CurChIndex; + u16_t allowChannelCnt; + ZM_HAL_CHANNEL allowChannel[60]; /* 2.4GHz: 14 channels, 5 GHz: 31 channels */ +}; + +struct zsPartnerNotifyEvent +{ + u8_t bssid[6]; // The BSSID of IBSS + u8_t peerMacAddr[6]; // The MAC address of peer station +}; + +#define ZM_RC_TRAINED_BIT 0x1 +struct zsRcCell +{ + u32_t txCount; + u32_t failCount; + u8_t currentRate; + u8_t currentRateIndex; + u32_t probingTime; + u8_t operationRateSet[24]; + u8_t operationRateCount; + u16_t rxRssi; + u8_t flag; + u32_t lasttxCount; + u32_t lastTime; +}; + +struct zsOppositeInfo +{ + u8_t macAddr[6]; + struct zsRcCell rcCell; + u8_t valid; // This indicate if this opposite is still valid + u8_t aliveCounter; + u8_t pkInstalled; + +#ifdef ZM_ENABLE_IBSS_WPA2PSK + /* For WPA2PSK ! */ + u8_t wpaState; + u8_t camIdx; + u8_t encryMode; + u16_t iv16; + u32_t iv32; +#endif +}; + +typedef void (*zfpIBSSIteratePeerStationCb)( + zdev_t* dev, struct zsOppositeInfo *peerInfo, void *ctx, u8_t index); + +typedef u16_t (*zfpStaRxSecurityCheckCb)(zdev_t* dev, zbuf_t* buf); + + +/* Communication Tally data structure */ +struct zsCommTally +{ + u32_t txUnicastFrm; // 0 txUnicastFrames + u32_t txMulticastFrm; // 1 txMulticastFrames + u32_t txUnicastOctets; // 2 txUniOctets byte size + u32_t txMulticastOctets; // 3 txMultiOctets byte size + u32_t txFrmUpperNDIS; // 4 + u32_t txFrmDrvMgt; // 5 + u32_t RetryFailCnt; // 6 + u32_t Hw_TotalTxFrm; // 7 Hardware total Tx Frame + u32_t Hw_RetryCnt; // 8 txMultipleRetriesFrames + u32_t Hw_UnderrunCnt; // 9 + + u32_t DriverRxFrmCnt; // 10 + u32_t rxUnicastFrm; // 11 rxUnicastFrames + u32_t rxMulticastFrm; // 12rxMulticastFrames + + u32_t NotifyNDISRxFrmCnt; // 14 + u32_t rxUnicastOctets; // 15 rxUniOctets byte size + u32_t rxMulticastOctets; // 16 rxMultiOctets byte size + u32_t DriverDiscardedFrm; // 17 Discard by ValidateFrame + u32_t LessThanDataMinLen; // 18 + u32_t GreaterThanMaxLen; // 19 + u32_t DriverDiscardedFrmCauseByMulticastList; + u32_t DriverDiscardedFrmCauseByFrmCtrl; + u32_t rxNeedFrgFrm; // 22 need more frg frm + u32_t DriverRxMgtFrmCnt; + u32_t rxBroadcastFrm; // 24 Receive broadcast frame count + u32_t rxBroadcastOctets; // 25 Receive broadcast frame byte size + u32_t rx11bDataFrame; // 26 Measured quality 11b data frame count + u32_t rxOFDMDataFrame; // 27 Measured quality 11g data frame count + + + u32_t Hw_TotalRxFrm; // 28 + u32_t Hw_CRC16Cnt; // 29 rxPLCPCRCErrCnt + u32_t Hw_CRC32Cnt; // 30 rxCRC32ErrCnt + u32_t Hw_DecrypErr_UNI; // 31 + u32_t Hw_DecrypErr_Mul; // 32 + + u32_t Hw_RxFIFOOverrun; // 34 + u32_t Hw_RxTimeOut; // 35 + u32_t LossAP; // 36 + + u32_t Tx_MPDU; // 37 + u32_t BA_Fail; // 38 + u32_t Hw_Tx_AMPDU; // 39 + u32_t Hw_Tx_MPDU; // 40 + + u32_t RateCtrlTxMPDU; + u32_t RateCtrlBAFail; + + u32_t txQosDropCount[5]; //41 42 43 44 45 + + u32_t Hw_RxMPDU; // 46 + u32_t Hw_RxDropMPDU; // 47 + u32_t Hw_RxDelMPDU; // 48 + + u32_t Hw_RxPhyMiscError; // 49 + u32_t Hw_RxPhyXRError; // 50 + u32_t Hw_RxPhyOFDMError; // 51 + u32_t Hw_RxPhyCCKError; // 52 + u32_t Hw_RxPhyHTError; // 53 + u32_t Hw_RxPhyTotalCount; // 54 + + u32_t swRxFragmentCount; // 55 + u32_t swRxUnicastMicFailCount; // 56 + u32_t swRxMulticastMicFailCount; // 57 + u32_t swRxDropUnencryptedCount; // 58 + + u32_t txBroadcastFrm; + u32_t txBroadcastOctets; +}; + +/* Traffic Monitor Tally data structure */ +struct zsTrafTally +{ + u32_t rxDuplicate; + u32_t rxSrcIsOwnMac; + //u32_t rxDataFrameCount; + //u32_t rxDataByteCount; + //u32_t rxDataBytesIn1000ms; + //u32_t rxDataTmpFor1000ms; + //u32_t rxDataBytesIn2000ms; + //u32_t rxDataTmpFor2000ms; + + //u32_t txDataFrameCount; + //u32_t txDataByteCount; + //u32_t txDataBytesIn1000ms; + //u32_t txDataTmpFor1000ms; + u32_t txDataBytesIn2000ms; + u32_t txDataTmpFor2000ms; +}; + +/* Hal rx packet moniter information */ +struct zsMonHalRxInfo +{ + u32_t currentRSSI[7]; + u32_t currentRxEVM[14]; + u32_t currentRxDataMT; + u32_t currentRxDataMCS; + u32_t currentRxDataBW; + u32_t currentRxDataSG; +}; + +struct zsTail +{ + u8_t SignalStrength1; + u8_t SignalStrength2; + u8_t SignalStrength3; + u8_t SignalQuality; + u8_t SAIndex; + u8_t DAIndex; + u8_t ErrorIndication; + u8_t RxMacStatus; +}; + +union zuTail +{ + struct zsTail Data; + u8_t Byte[8]; +}; + +struct zsAdditionInfo +{ + u8_t PlcpHeader[12]; + union zuTail Tail; +}; + + +struct zsPmkidBssidInfo +{ + u16_t bssid[3]; + u8_t pmkid[16]; +}; + +struct zsPmkidInfo +{ + u32_t bssidCount; + struct zsPmkidBssidInfo bssidInfo[ZM_PMKID_MAX_BSS_CNT]; +}; + + +struct zsCbFuncTbl +{ + u16_t (*zfcbAuthNotify)(zdev_t* dev, u16_t* macAddr); + u16_t (*zfcbAsocNotify)(zdev_t* dev, u16_t* macAddr, u8_t* body, + u16_t bodySize, u16_t port); + u16_t (*zfcbDisAsocNotify)(zdev_t* dev, u8_t* macAddr, u16_t port); + u16_t (*zfcbApConnectNotify)(zdev_t* dev, u8_t* macAddr, u16_t port); + void (*zfcbConnectNotify)(zdev_t* dev, u16_t status, u16_t* bssid); + void (*zfcbScanNotify)(zdev_t* dev, struct zsScanResult* result); + void (*zfcbMicFailureNotify)(zdev_t* dev, u16_t* addr, u16_t status); + void (*zfcbApMicFailureNotify)(zdev_t* dev, u8_t* addr, zbuf_t* buf); + void (*zfcbIbssPartnerNotify)(zdev_t* dev, u16_t status, + struct zsPartnerNotifyEvent *event); + void (*zfcbMacAddressNotify)(zdev_t* dev, u8_t* addr); + void (*zfcbSendCompleteIndication)(zdev_t* dev, zbuf_t* buf); + void (*zfcbRecvEth)(zdev_t* dev, zbuf_t* buf, u16_t port); + void (*zfcbRecv80211)(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo); + void (*zfcbRestoreBufData)(zdev_t* dev, zbuf_t* buf); +#ifdef ZM_ENABLE_CENC + u16_t (*zfcbCencAsocNotify)(zdev_t* dev, u16_t* macAddr, u8_t* body, + u16_t bodySize, u16_t port); +#endif //ZM_ENABLE_CENC + u8_t (*zfcbClassifyTxPacket)(zdev_t* dev, zbuf_t* buf); + + void (*zfcbHwWatchDogNotify)(zdev_t* dev); +}; + +extern void zfZeroMemory(u8_t* va, u16_t length); +#define ZM_INIT_CB_FUNC_TABLE(p) zfZeroMemory((u8_t *)p, sizeof(struct zsCbFuncTbl)); + +//extern struct zsWlanDev zgWlanDev; + +/* Initialize WLAN hardware and software, resource will be allocated */ +/* for WLAN operation, must be called first before other function. */ +extern u16_t zfiWlanOpen(zdev_t* dev, struct zsCbFuncTbl* cbFuncTbl); + +/* WLAN hardware will be shutdown and all resource will be release */ +extern u16_t zfiWlanClose(zdev_t* dev); + +/* Enable/disable Wlan operation */ +extern u16_t zfiWlanEnable(zdev_t* dev); +extern u16_t zfiWlanDisable(zdev_t* dev, u8_t ResetKeyCache); +extern u16_t zfiWlanResume(zdev_t* dev, u8_t doReconn); +extern u16_t zfiWlanSuspend(zdev_t* dev); + +/* Enable/disable ISR interrupt */ +extern u16_t zfiWlanInterruptEnable(zdev_t* dev); +extern u16_t zfiWlanInterruptDisable(zdev_t* dev); + +/* Do WLAN site survey */ +extern u16_t zfiWlanScan(zdev_t* dev); + +/* Get WLAN stastics */ +extern u16_t zfiWlanGetStatistics(zdev_t* dev); + +/* Reset WLAN */ +extern u16_t zfiWlanReset(zdev_t* dev); + +/* Deauthenticate a STA */ +extern u16_t zfiWlanDeauth(zdev_t* dev, u16_t* macAddr, u16_t reason); + +extern u16_t zfiTxSendEth(zdev_t* dev, zbuf_t* buf, u16_t port); +extern u8_t zfiIsTxQueueFull(zdev_t* dev); +extern u16_t zfiTxSend80211Mgmt(zdev_t* dev, zbuf_t* buf, u16_t port); + +extern void zfiIsrPci(zdev_t* dev); + +extern u8_t zfiWlanIBSSGetPeerStationsCount(zdev_t* dev); +extern u8_t zfiWlanIBSSIteratePeerStations(zdev_t* dev, u8_t numToIterate, zfpIBSSIteratePeerStationCb callback, void *ctx); +extern void zfiWlanFlushAllQueuedBuffers(zdev_t* dev); + +/* coid.c */ +extern void zfiWlanQueryMacAddress(zdev_t* dev, u8_t* addr); + +extern u16_t zfiGlobalDataSize(zdev_t* dev); + +extern void zfiHeartBeat(zdev_t* dev); + +extern void zfiWlanSetWlanMode(zdev_t* dev, u8_t wlanMode); +extern void zfiWlanSetAuthenticationMode(zdev_t* dev, u8_t authMode); +extern void zfiWlanSetWepStatus(zdev_t* dev, u8_t wepStatus); +extern void zfiWlanSetSSID(zdev_t* dev, u8_t* ssid, u8_t ssidLength); +extern void zfiWlanSetFragThreshold(zdev_t* dev, u16_t fragThreshold); +extern void zfiWlanSetRtsThreshold(zdev_t* dev, u16_t rtsThreshold); +extern void zfiWlanSetFrequency(zdev_t* dev, u32_t frequency, u8_t bImmediate); +extern void zfiWlanSetBssid(zdev_t* dev, u8_t* bssid); +extern void zfiWlanSetBeaconInterval(zdev_t* dev, u16_t beaconInterval, + u8_t bImmediate); +extern void zfiWlanSetDtimCount(zdev_t* dev, u8_t dtim); +extern void zfiWlanSetAtimWindow(zdev_t* dev, u16_t atimWindow, u8_t bImmediate); +extern void zfiWlanSetEncryMode(zdev_t* dev, u8_t encryMode); +extern u8_t zfiWlanSetKey(zdev_t* dev, struct zsKeyInfo keyInfo); +extern u8_t zfiWlanPSEUDOSetKey(zdev_t* dev, struct zsKeyInfo keyInfo); +extern void zfiWlanSetPowerSaveMode(zdev_t* dev, u8_t mode); +extern void zfiWlanQueryBssListV1(zdev_t* dev, struct zsBssListV1* bssListV1); +extern void zfiWlanQueryBssList(zdev_t* dev, struct zsBssList* pBssList); +extern void zfiWlanSetProtectionMode(zdev_t* dev, u8_t mode); +extern void zfiWlanFlushBssList(zdev_t* dev); + +void zfiWlanDisableDfsChannel(zdev_t* dev, u8_t disableFlag); + +extern u8_t zfiWlanQueryWlanMode(zdev_t* dev); +extern u16_t zfiWlanChannelToFrequency(zdev_t* dev, u8_t channel); +extern u8_t zfiWlanFrequencyToChannel(zdev_t* dev, u16_t freq); + +#define ZM_WLAN_STATE_OPENED 0 +#define ZM_WLAN_STATE_ENABLED 1 +#define ZM_WLAN_STATE_DISABLED 2 +#define ZM_WLAN_STATE_CLOSEDED 3 +extern u8_t zfiWlanQueryAdapterState(zdev_t* dev); +extern u8_t zfiWlanQueryAuthenticationMode(zdev_t* dev, u8_t bWrapper); +extern u8_t zfiWlanQueryWepStatus(zdev_t* dev, u8_t bWrapper); +extern void zfiWlanQuerySSID(zdev_t* dev, u8_t* ssid, u8_t* pSsidLength); +extern u16_t zfiWlanQueryFragThreshold(zdev_t* dev); +extern u16_t zfiWlanQueryRtsThreshold(zdev_t* dev); +extern u32_t zfiWlanQueryFrequency(zdev_t* dev); +extern u32_t zfiWlanQueryCurrentFrequency(zdev_t* dev, u8_t qmode); +extern u32_t zfiWlanQueryFrequencyAttribute(zdev_t* dev, u32_t frequency); +extern void zfiWlanQueryFrequencyHT(zdev_t* dev, u32_t *bandWidth, u32_t *extOffset); +extern u8_t zfiWlanQueryCWMode(zdev_t* dev); +extern u32_t zfiWlanQueryCWEnable(zdev_t* dev); +extern void zfiWlanQueryBssid(zdev_t* dev, u8_t* bssid); +extern u16_t zfiWlanQueryBeaconInterval(zdev_t* dev); +extern u32_t zfiWlanQueryRxBeaconTotal(zdev_t* dev); +extern u16_t zfiWlanQueryAtimWindow(zdev_t* dev); +extern u8_t zfiWlanQueryEncryMode(zdev_t* dev); +extern u16_t zfiWlanQueryCapability(zdev_t* dev); +extern u16_t zfiWlanQueryAid(zdev_t* dev); +extern void zfiWlanQuerySupportRate(zdev_t* dev, u8_t* rateArray, u8_t* pLength); +extern void zfiWlanQueryExtSupportRate(zdev_t* dev, u8_t* rateArray, u8_t* pLength); +extern void zfiWlanQueryRsnIe(zdev_t* dev, u8_t* ie, u8_t* pLength); +extern void zfiWlanQueryWpaIe(zdev_t* dev, u8_t* ie, u8_t* pLength); +extern u8_t zfiWlanQueryHTMode(zdev_t* dev); +extern u8_t zfiWlanQueryBandWidth40(zdev_t* dev); +extern u8_t zfiWlanQueryMulticastCipherAlgo(zdev_t *dev); +extern u16_t zfiWlanQueryRegionCode(zdev_t* dev); +extern void zfiWlanSetWpaIe(zdev_t* dev, u8_t* ie, u8_t Length); +extern void zfiWlanSetWpaSupport(zdev_t* dev, u8_t WpaSupport); +extern void zfiWlanCheckStaWpaIe(zdev_t* dev); +extern void zfiWlanSetBasicRate(zdev_t* dev, u8_t bRateSet, u8_t gRateSet, + u32_t nRateSet); +extern void zfiWlanSetBGMode(zdev_t* dev, u8_t mode); +extern void zfiWlanSetpreambleType(zdev_t* dev, u8_t type); +extern u8_t zfiWlanQuerypreambleType(zdev_t* dev); +extern u8_t zfiWlanQueryPowerSaveMode(zdev_t* dev); +extern void zfiWlanSetMacAddress(zdev_t* dev, u16_t* mac); +extern u16_t zfiWlanSetTxRate(zdev_t* dev, u16_t rate); +extern u32_t zfiWlanQueryTxRate(zdev_t* dev); +extern void zfWlanUpdateRxRate(zdev_t* dev, struct zsAdditionInfo* addInfo); +extern u32_t zfiWlanQueryRxRate(zdev_t* dev); +extern u8_t zfiWlanSetPmkidInfo(zdev_t* dev, u16_t* bssid, u8_t* pmkid); +extern u32_t zfiWlanQueryPmkidInfo(zdev_t* dev, u8_t* buf, u32_t len); +extern void zfiWlanSetAllMulticast(zdev_t* dev, u32_t setting); +extern void zfiWlanSetHTCtrl(zdev_t* dev, u32_t *setting, u32_t forceTxTPC); +extern void zfiWlanQueryHTCtrl(zdev_t* dev, u32_t *setting, u32_t *forceTxTPC); +extern void zfiWlanDbg(zdev_t* dev, u8_t setting); + +extern void zfiWlanResetTally(zdev_t* dev); +extern void zfiWlanQueryTally(zdev_t* dev, struct zsCommTally *tally); +extern void zfiWlanQueryTrafTally(zdev_t* dev, struct zsTrafTally *tally); +extern void zfiWlanQueryMonHalRxInfo(zdev_t* dev, struct zsMonHalRxInfo *halRxInfo); + +extern u32_t zfiFWConfig(zdev_t* dev, u32_t size); + +extern void zfiDKEnable(zdev_t* dev, u32_t enable); + +extern void zfiWlanSetMulticastList(zdev_t* dev, u8_t size, u8_t* pList); +extern void zfiWlanRemoveKey(zdev_t* dev, u8_t keyType, u8_t keyId); +extern u8_t zfiWlanQueryIsPKInstalled(zdev_t *dev, u8_t *staMacAddr); +extern u32_t zfiWlanQueryPacketTypePromiscuous(zdev_t* dev); +extern void zfiWlanSetPacketTypePromiscuous(zdev_t* dev, u32_t setValue); +extern void zfiSetChannelManagement(zdev_t* dev, u32_t setting); +extern void zfiSetRifs(zdev_t* dev, u16_t setting); +extern void zfiCheckRifs(zdev_t* dev); +extern void zfiSetReorder(zdev_t* dev, u16_t value); +extern void zfiSetSeqDebug(zdev_t* dev, u16_t value); + +extern u16_t zfiConfigWdsPort(zdev_t* dev, u8_t wdsPortId, u16_t flag, u16_t* wdsAddr, + u16_t encType, u32_t* wdsKey); +extern void zfiWlanQueryRegulationTable(zdev_t* dev, struct zsRegulationTable* pEntry); +extern void zfiWlanSetScanTimerPerChannel(zdev_t* dev, u16_t time); +extern void zfiWlanSetAutoReconnect(zdev_t* dev, u8_t enable); +extern u32_t zfiDebugCmd(zdev_t* dev, u32_t cmd, u32_t value); +extern void zfiWlanSetProbingHiddenSsid(zdev_t* dev, u8_t* ssid, u8_t ssidLen, + u16_t entry); +extern void zfiWlanSetDropUnencryptedPackets(zdev_t* dev, u8_t enable); +extern void zfiWlanSetIBSSJoinOnly(zdev_t* dev, u8_t joinOnly); +extern void zfiWlanSetDefaultKeyId(zdev_t* dev, u8_t keyId); +extern void zfiWlanSetDisableProbingWithSsid(zdev_t* dev, u8_t mode); +extern void zfiWlanQueryGSN(zdev_t* dev, u8_t *gsn, u16_t vapId); +extern u16_t zfiStaAddIeWpaRsn(zdev_t* dev, zbuf_t* buf, u16_t offset, u8_t frameType); +extern u8_t zfiWlanSetDot11DMode(zdev_t* dev, u8_t mode); +extern u8_t zfiWlanSetDot11HDFSMode(zdev_t* dev, u8_t mode); +extern u8_t zfiWlanSetDot11HTPCMode(zdev_t* dev, u8_t mode); +extern u8_t zfiWlanSetAniMode(zdev_t* dev, u8_t mode); +extern void zfiWlanSetStaWme(zdev_t* dev, u8_t enable, u8_t uapsdInfo); +extern void zfiWlanSetApWme(zdev_t* dev, u8_t enable); +extern u8_t zfiWlanQuerywmeEnable(zdev_t* dev); +#ifdef ZM_OS_LINUX_FUNC +extern void zfiWlanShowTally(zdev_t* dev); +#endif +#ifdef ZM_ENABLE_CENC +/* CENC */ +extern u8_t zfiWlanSetCencPairwiseKey(zdev_t* dev, u8_t keyid, u32_t *txiv, u32_t *rxiv, + u8_t *key, u8_t *mic); +extern u8_t zfiWlanSetCencGroupKey(zdev_t* dev, u8_t keyid, u32_t *rxiv, + u8_t *key, u8_t *mic); +#endif //ZM_ENABLE_CENC +extern void zfiWlanQuerySignalInfo(zdev_t* dev, u8_t *buffer); +extern void zfiWlanQueryAdHocCreatedBssDesc(zdev_t* dev, struct zsBssInfo *pBssInfo); +extern u8_t zfiWlanQueryAdHocIsCreator(zdev_t* dev); +extern u32_t zfiWlanQuerySupportMode(zdev_t* dev); +extern u32_t zfiWlanQueryTransmitPower(zdev_t* dev); +extern void zfiWlanEnableLeapConfig(zdev_t* dev, u8_t leapEnabled); + +/* returned buffer allocated by driver core */ +extern void zfiRecvEthComplete(zdev_t* dev, zbuf_t* buf); + +extern void zfiRecv80211(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo); + +extern void zfiWlanSetMaxTxPower(zdev_t* dev, u8_t power2, u8_t power5); +extern void zfiWlanQueryMaxTxPower(zdev_t* dev, u8_t *power2, u8_t *power5); +extern void zfiWlanSetConnectMode(zdev_t* dev, u8_t mode); +extern void zfiWlanSetSupportMode(zdev_t* dev, u32_t mode); +extern void zfiWlanSetAdhocMode(zdev_t* dev, u32_t mode); +extern u32_t zfiWlanQueryAdhocMode(zdev_t* dev, u8_t bWrapper); +extern u8_t zfiWlanSetCountryIsoName(zdev_t* dev, u8_t *countryIsoName, u8_t length); +extern const char* zfiWlanQueryCountryIsoName(zdev_t* dev); +extern u8_t zfiWlanQueryregulatoryDomain(zdev_t* dev); +extern u8_t zfiWlanQueryCCS(zdev_t* dev); +extern void zfiWlanSetCCS(zdev_t* dev, u8_t mode); +extern void zfiWlanSetRegulatory(zdev_t* dev, u8_t CCS, u16_t Code, u8_t bfirstChannel); +extern const char* zfiHpGetisoNamefromregionCode(zdev_t* dev, u16_t regionCode); +extern void zfiWlanSetLEDCtrlParam(zdev_t* dev, u8_t type, u8_t flag); +extern u32_t zfiWlanQueryReceivedPacket(zdev_t* dev); +extern void zfiWlanCheckSWEncryption(zdev_t* dev); +extern u16_t zfiWlanQueryAllowChannels(zdev_t *dev, u16_t *channels); +extern u16_t zfiWlanGetMulticastAddressCount(zdev_t* dev); +extern void zfiWlanGetMulticastList(zdev_t* dev, u8_t* pMCList); +extern void zfiWlanSetPacketFilter(zdev_t* dev, u32_t PacketFilter); +extern u8_t zfiCompareWithMulticastListAddress(zdev_t* dev, u16_t* dstMacAddr); +extern void zfiWlanSetSafeModeEnabled(zdev_t* dev, u8_t safeMode); +extern void zfiWlanSetIBSSAdditionalIELength(zdev_t* dev, u32_t ibssAdditionalIESize, u8_t* ibssAdditionalIE); +extern void zfiWlanSetXLinkMode(zdev_t* dev, u32_t setValue); + +/* hprw.c */ +extern u32_t zfiDbgWriteFlash(zdev_t* dev, u32_t addr, u32_t val); +extern u32_t zfiDbgWriteReg(zdev_t* dev, u32_t addr, u32_t val); +extern u32_t zfiDbgReadReg(zdev_t* dev, u32_t addr); + +extern u32_t zfiDbgWriteEeprom(zdev_t* dev, u32_t addr, u32_t val); +extern u32_t zfiDbgBlockWriteEeprom(zdev_t* dev, u32_t addr, u32_t* buf); +extern u32_t zfiDbgBlockWriteEeprom_v2(zdev_t* dev, u32_t addr, u32_t* buf, u32_t wrlen); + +extern u16_t zfiDbgChipEraseFlash(zdev_t *dev); +extern u16_t zfiDbgProgramFlash(zdev_t *dev, u32_t offset, u32_t len, u32_t *data); +extern u32_t zfiDbgGetFlashCheckSum(zdev_t *dev, u32_t addr, u32_t len); +extern u32_t zfiDbgReadFlash(zdev_t *dev, u32_t addr, u32_t len); +extern u32_t zfiDownloadFwSet(zdev_t *dev); + +extern u32_t zfiDbgDelayWriteReg(zdev_t* dev, u32_t addr, u32_t val); +extern u32_t zfiDbgFlushDelayWrite(zdev_t* dev); + +extern u32_t zfiDbgSetIFSynthesizer(zdev_t* dev, u32_t value); +extern u32_t zfiDbgReadTally(zdev_t* dev); + +extern u32_t zfiDbgQueryHwTxBusy(zdev_t* dev); + +extern u8_t zfiWlanGetDestAddrFromBuf(zdev_t *dev, zbuf_t *buf, u16_t *macAddr); + +extern u32_t zfiWlanQueryHwCapability(zdev_t* dev); + +extern void zfiWlanSetDynamicSIFSParam(zdev_t* dev, u8_t val); + +/***** End of section 2 *****/ + +/***** section 3 performace evaluation *****/ +#ifdef ZM_ENABLE_PERFORMANCE_EVALUATION +extern void zfiTxPerformanceMSDU(zdev_t* dev, u32_t tick); +extern void zfiRxPerformanceMPDU(zdev_t* dev, zbuf_t* buf); +extern void zfiRxPerformanceReg(zdev_t* dev, u32_t reg, u32_t rsp); +#define ZM_PERFORMANCE_INIT(dev) zfiPerformanceInit(dev); +#define ZM_PERFORMANCE_TX_MSDU(dev, tick) zfiTxPerformanceMSDU(dev, tick); +#define ZM_PERFORMANCE_RX_MSDU(dev, tick) zfiRxPerformanceMSDU(dev, tick); +#define ZM_PERFORMANCE_TX_MPDU(dev, tick) zfiTxPerformanceMPDU(dev, tick); +#define ZM_PERFORMANCE_RX_MPDU(dev, buf) zfiRxPerformanceMPDU(dev, buf); +#define ZM_PERFORMANCE_RX_SEQ(dev, buf) zfiRxPerformanceSeq(dev, buf); +#define ZM_PERFORMANCE_REG(dev, reg, rsp) {if(cmd[1] == reg) zfiRxPerformanceReg(dev, reg, rsp);} +#define ZM_PERFORMANCE_DUP(dev, buf1, buf2) zfiRxPerformanceDup(dev, buf1, buf2); +#define ZM_PERFORMANCE_FREE(dev, buf) zfiRxPerformanceFree(dev, buf); +#define ZM_PERFORMANCE_RX_AMSDU(dev, buf, len) zfiRxPerformanceAMSDU(dev, buf, len); +#define ZM_PERFORMANCE_RX_FLUSH(dev) zfiRxPerformanceFlush(dev); +#define ZM_PERFORMANCE_RX_CLEAR(dev) zfiRxPerformanceClear(dev); +#define ZM_SEQ_DEBUG if (wd->seq_debug) DbgPrint +#define ZM_PERFORMANCE_RX_REORDER(dev) zfiRxPerformanceReorder(dev); +#else +#define ZM_PERFORMANCE_INIT(dev) +#define ZM_PERFORMANCE_TX_MSDU(dev, tick) +#define ZM_PERFORMANCE_RX_MSDU(dev, tick) +#define ZM_PERFORMANCE_TX_MPDU(dev, tick) +#define ZM_PERFORMANCE_RX_MPDU(dev, buf) +#define ZM_PERFORMANCE_RX_SEQ(dev, buf) +#define ZM_PERFORMANCE_REG(dev, reg, rsp) +#define ZM_PERFORMANCE_DUP(dev, buf1, buf2) +#define ZM_PERFORMANCE_FREE(dev, buf) +#define ZM_PERFORMANCE_RX_AMSDU(dev, buf, len) +#define ZM_PERFORMANCE_RX_FLUSH(dev) +#define ZM_PERFORMANCE_RX_CLEAR(dev) +#define ZM_SEQ_DEBUG +#define ZM_PERFORMANCE_RX_REORDER(dev) +#endif +/***** End of section 3 *****/ +#endif --- linux-2.6.28.orig/drivers/staging/otus/80211core/cpsmgr.c +++ linux-2.6.28/drivers/staging/otus/80211core/cpsmgr.c @@ -0,0 +1,731 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * The power saving manager is to save the power as much as possible. + * Generally speaking, it controls: + * + * - when to sleep + * - + * + */ +#include "cprecomp.h" + +void zfPowerSavingMgrInit(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + wd->sta.powerSaveMode = ZM_STA_PS_NONE; + wd->sta.psMgr.state = ZM_PS_MSG_STATE_ACTIVE; + wd->sta.psMgr.isSleepAllowed = 0; + wd->sta.psMgr.maxSleepPeriods = 1; + wd->sta.psMgr.ticks = 0; + wd->sta.psMgr.sleepAllowedtick = 0; +} + +static u16_t zfPowerSavingMgrHandlePsNone(zdev_t* dev, u8_t *isWakeUpRequired) +{ + u16_t ret = 0; + zmw_get_wlan_dev(dev); + + switch(wd->sta.psMgr.state) + { + case ZM_PS_MSG_STATE_ACTIVE: + *isWakeUpRequired = 0; + break; + + case ZM_PS_MSG_STATE_T1: + case ZM_PS_MSG_STATE_T2: + case ZM_PS_MSG_STATE_SLEEP: + default: + *isWakeUpRequired = 1; +zm_debug_msg0("zfPowerSavingMgrHandlePsNone: Wake up now\n"); + if ( zfStaIsConnected(dev) ) + { + zm_debug_msg0("zfPowerSavingMgrOnHandleT1 send Null data\n"); + //zfSendNullData(dev, 0); + ret = 1; + } + + wd->sta.psMgr.state = ZM_PS_MSG_STATE_ACTIVE; + break; + } + return ret; +} + +static void zfPowerSavingMgrHandlePs(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + switch(wd->sta.psMgr.state) + { + case ZM_PS_MSG_STATE_ACTIVE: + //zm_debug_msg0("zfPowerSavingMgrHandlePs: Prepare to sleep...\n"); + //wd->sta.psMgr.state = ZM_PS_MSG_STATE_T1; + break; + + case ZM_PS_MSG_STATE_T1: + case ZM_PS_MSG_STATE_T2: + case ZM_PS_MSG_STATE_SLEEP: + default: + break; + } +} + +void zfPowerSavingMgrSetMode(zdev_t* dev, u8_t mode) +{ + u16_t sendNull = 0; + u8_t isWakeUpRequired = 0; + + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + zm_debug_msg1("mode = ", mode); + + if (mode > ZM_STA_PS_LIGHT) + { + zm_debug_msg0("return - wrong power save mode"); + return; + } + + zmw_enter_critical_section(dev); + + #if 1 + switch(mode) + { + case ZM_STA_PS_NONE: + sendNull = zfPowerSavingMgrHandlePsNone(dev, &isWakeUpRequired); + break; + + case ZM_STA_PS_FAST: + case ZM_STA_PS_LIGHT: + wd->sta.psMgr.maxSleepPeriods = 1; + zfPowerSavingMgrHandlePs(dev); + break; + + case ZM_STA_PS_MAX: + wd->sta.psMgr.maxSleepPeriods = ZM_PS_MAX_SLEEP_PERIODS; + zfPowerSavingMgrHandlePs(dev); + break; + } + #else + switch(wd->sta.psMgr.state) + { + case ZM_PS_MSG_STATE_ACTIVE: + if ( mode != ZM_STA_PS_NONE ) + { +zm_debug_msg0("zfPowerSavingMgrSetMode: switch from ZM_PS_MSG_STATE_ACTIVE to ZM_PS_MSG_STATE_T1\n"); + // Stall the TX & start to wait the pending TX to be completed + wd->sta.psMgr.state = ZM_PS_MSG_STATE_T1; + } + break; + + case ZM_PS_MSG_STATE_SLEEP: + break; + } + #endif + + wd->sta.powerSaveMode = mode; + zmw_leave_critical_section(dev); + + if ( isWakeUpRequired ) + { + zfHpPowerSaveSetState(dev, 0); + wd->sta.psMgr.tempWakeUp = 0; + } + + if ( zfStaIsConnected(dev) + && (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) ) + { + switch(mode) + { + case ZM_STA_PS_NONE: + zfHpPowerSaveSetMode(dev, 0, 0, wd->beaconInterval); + break; + + case ZM_STA_PS_FAST: + case ZM_STA_PS_MAX: + case ZM_STA_PS_LIGHT: + zfHpPowerSaveSetMode(dev, 0, 1, wd->beaconInterval); + break; + + default: + zfHpPowerSaveSetMode(dev, 0, 0, wd->beaconInterval); + break; + } + } + + if (sendNull == 1) + { + zfSendNullData(dev, 0); + } + + return; +} + +static void zfPowerSavingMgrNotifyPSToAP(zdev_t *dev) +{ + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + if ( (wd->sta.psMgr.tempWakeUp != 1)&& + (wd->sta.psMgr.lastTxUnicastFrm != wd->commTally.txUnicastFrm || + wd->sta.psMgr.lastTxBroadcastFrm != wd->commTally.txBroadcastFrm || + wd->sta.psMgr.lastTxMulticastFrm != wd->commTally.txMulticastFrm) ) + { + zmw_enter_critical_section(dev); + wd->sta.psMgr.lastTxUnicastFrm = wd->commTally.txUnicastFrm; + wd->sta.psMgr.lastTxBroadcastFrm = wd->commTally.txBroadcastFrm; + wd->sta.psMgr.lastTxMulticastFrm = wd->commTally.txMulticastFrm; + zmw_leave_critical_section(dev); + + zfSendNullData(dev, 1); + } +} + +static void zfPowerSavingMgrOnHandleT1(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + // If the tx Q is not empty...return + if ( zfIsVtxqEmpty(dev) == FALSE ) + { + return; + } + +zm_debug_msg0("VtxQ is empty now...Check if HAL TXQ is empty\n"); + + // The the HAL TX Q is not empty...return + if ( zfHpGetFreeTxdCount(dev) != zfHpGetMaxTxdCount(dev) ) + { + return; + } + +zm_debug_msg0("HAL TXQ is empty now...Could go to sleep...\n"); + + zmw_enter_critical_section(dev); + + if (wd->sta.powerSaveMode == ZM_STA_PS_LIGHT) + { + if (wd->sta.ReceivedPktRatePerSecond > 200) + { + zmw_leave_critical_section(dev); + return; + } + + if ( zfStaIsConnected(dev) + && (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) ) + { + if (wd->sta.psMgr.sleepAllowedtick) { + wd->sta.psMgr.sleepAllowedtick--; + zmw_leave_critical_section(dev); + return; + } + } + } + + wd->sta.psMgr.state = ZM_PS_MSG_STATE_T2; + + zmw_leave_critical_section(dev); + + // Send the Null pkt to AP to notify that I'm going to sleep + if ( zfStaIsConnected(dev) ) + { +zm_debug_msg0("zfPowerSavingMgrOnHandleT1 send Null data\n"); + zfPowerSavingMgrNotifyPSToAP(dev); + } + + // Stall the TX now + // zfTxEngineStop(dev); +} + +static void zfPowerSavingMgrOnHandleT2(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + // Wait until the Null pkt is transmitted + if ( zfHpGetFreeTxdCount(dev) != zfHpGetMaxTxdCount(dev) ) + { + return; + } + + zmw_enter_critical_section(dev); + wd->sta.psMgr.state = ZM_PS_MSG_STATE_SLEEP; + wd->sta.psMgr.lastTxUnicastFrm = wd->commTally.txUnicastFrm; + wd->sta.psMgr.lastTxBroadcastFrm = wd->commTally.txBroadcastFrm; + wd->sta.psMgr.lastTxMulticastFrm = wd->commTally.txMulticastFrm; + zmw_leave_critical_section(dev); + + // Let CHIP sleep now +zm_debug_msg0("zfPowerSavingMgrOnHandleT2 zzzz....\n"); + zfHpPowerSaveSetState(dev, 1); + wd->sta.psMgr.tempWakeUp = 0; +} + +u8_t zfPowerSavingMgrIsSleeping(zdev_t *dev) +{ + u8_t isSleeping = FALSE; + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + if ( wd->sta.psMgr.state == ZM_PS_MSG_STATE_SLEEP || + wd->sta.psMgr.state == ZM_PS_MSG_STATE_T2) + { + isSleeping = TRUE; + } + zmw_leave_critical_section(dev); + return isSleeping; +} + +static u8_t zfPowerSavingMgrIsIdle(zdev_t *dev) +{ + u8_t isIdle = 0; + + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + if ( zfStaIsConnected(dev) && wd->sta.psMgr.isSleepAllowed == 0 ) + { + goto done; + } + + if ( wd->sta.bChannelScan ) + { + goto done; + } + + if ( zfStaIsConnecting(dev) ) + { + goto done; + } + + if (wd->sta.powerSaveMode == ZM_STA_PS_LIGHT) + { + if (wd->sta.ReceivedPktRatePerSecond > 200) + { + goto done; + } + + if ( zfStaIsConnected(dev) + && (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) ) + { + if (wd->sta.psMgr.sleepAllowedtick) { + wd->sta.psMgr.sleepAllowedtick--; + goto done; + } + } + } + + isIdle = 1; + +done: + zmw_leave_critical_section(dev); + + if ( zfIsVtxqEmpty(dev) == FALSE ) + { + isIdle = 0; + } + + return isIdle; +} + +static void zfPowerSavingMgrSleepIfIdle(zdev_t *dev) +{ + u8_t isIdle; + + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + isIdle = zfPowerSavingMgrIsIdle(dev); + + if ( isIdle == 0 ) + { + return; + } + + zmw_enter_critical_section(dev); + + switch(wd->sta.powerSaveMode) + { + case ZM_STA_PS_NONE: + break; + + case ZM_STA_PS_MAX: + case ZM_STA_PS_FAST: + case ZM_STA_PS_LIGHT: + zm_debug_msg0("zfPowerSavingMgrSleepIfIdle: IDLE so slep now...\n"); + wd->sta.psMgr.state = ZM_PS_MSG_STATE_T1; + break; + } + + zmw_leave_critical_section(dev); +} + +static void zfPowerSavingMgrDisconnectMain(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + +#ifdef ZM_ENABLE_DISCONNECT_PS + switch(wd->sta.psMgr.state) + { + case ZM_PS_MSG_STATE_ACTIVE: + zfPowerSavingMgrSleepIfIdle(dev); + break; + + case ZM_PS_MSG_STATE_SLEEP: + break; + + case ZM_PS_MSG_STATE_T1: + zfPowerSavingMgrOnHandleT1(dev); + break; + + case ZM_PS_MSG_STATE_T2: + zfPowerSavingMgrOnHandleT2(dev); + break; + } +#else + zfPowerSavingMgrWakeup(dev); +#endif +} + +static void zfPowerSavingMgrInfraMain(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + switch(wd->sta.psMgr.state) + { + case ZM_PS_MSG_STATE_ACTIVE: + zfPowerSavingMgrSleepIfIdle(dev); + break; + + case ZM_PS_MSG_STATE_SLEEP: + break; + + case ZM_PS_MSG_STATE_T1: + zfPowerSavingMgrOnHandleT1(dev); + break; + + case ZM_PS_MSG_STATE_T2: + zfPowerSavingMgrOnHandleT2(dev); + break; + } +} + +void zfPowerSavingMgrAtimWinExpired(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + +//printk("zfPowerSavingMgrAtimWinExpired #1\n"); + if ( wd->sta.powerSaveMode == ZM_STA_PS_NONE ) + { + return; + } + +//printk("zfPowerSavingMgrAtimWinExpired #2\n"); + // if we received any ATIM window from the others to indicate we have buffered data + // at the other station, we can't go to sleep + if ( wd->sta.recvAtim ) + { + wd->sta.recvAtim = 0; + zm_debug_msg0("Can't sleep due to receving ATIM window!"); + return; + } + + // if we are the one to tx beacon during last beacon interval. we can't go to sleep + // since we need to be alive to respond the probe request! + if ( wd->sta.txBeaconInd ) + { + zm_debug_msg0("Can't sleep due to just transmit a beacon!"); + return; + } + + // If we buffer any data for the other stations. we could not go to sleep + if ( wd->sta.ibssPrevPSDataCount != 0 ) + { + zm_debug_msg0("Can't sleep due to buffering data for the others!"); + return; + } + + // before sleeping, we still need to notify the others by transmitting null + // pkt with power mgmt bit turned on. + zfPowerSavingMgrOnHandleT1(dev); +} + +static void zfPowerSavingMgrIBSSMain(zdev_t* dev) +{ + // wait for the end of + // if need to wait to know if we are the one to transmit the beacon + // during the beacon interval. If it's me, we can't go to sleep. + + zmw_get_wlan_dev(dev); + + switch(wd->sta.psMgr.state) + { + case ZM_PS_MSG_STATE_ACTIVE: + case ZM_PS_MSG_STATE_SLEEP: + case ZM_PS_MSG_STATE_T1: + break; + + case ZM_PS_MSG_STATE_T2: + zfPowerSavingMgrOnHandleT2(dev); + break; + } + + return; +} + +#if 1 +void zfPowerSavingMgrMain(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + switch (wd->sta.adapterState) + { + case ZM_STA_STATE_DISCONNECT: + zfPowerSavingMgrDisconnectMain(dev); + break; + case ZM_STA_STATE_CONNECTED: + { + if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) { + zfPowerSavingMgrInfraMain(dev); + } else if (wd->wlanMode == ZM_MODE_IBSS) { + zfPowerSavingMgrIBSSMain(dev); + } + } + break; + case ZM_STA_STATE_CONNECTING: + default: + break; + } +} +#else +void zfPowerSavingMgrMain(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + if ( wd->wlanMode != ZM_MODE_INFRASTRUCTURE ) + { + return; + } + + switch(wd->sta.psMgr.state) + { + case ZM_PS_MSG_STATE_ACTIVE: + goto check_sleep; + break; + + case ZM_PS_MSG_STATE_SLEEP: + goto sleeping; + break; + + case ZM_PS_MSG_STATE_T1: + zfPowerSavingMgrOnHandleT1(dev); + break; + + case ZM_PS_MSG_STATE_T2: + zfPowerSavingMgrOnHandleT2(dev); + break; + } + + return; + +sleeping: + return; + +check_sleep: + zfPowerSavingMgrSleepIfIdle(dev); + return; +} +#endif + +#ifdef ZM_ENABLE_POWER_SAVE +void zfPowerSavingMgrWakeup(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + +//zm_debug_msg0("zfPowerSavingMgrWakeup"); + + //if ( wd->sta.psMgr.state != ZM_PS_MSG_STATE_ACTIVE && ( zfPowerSavingMgrIsIdle(dev) == 0 )) + if ( wd->sta.psMgr.state != ZM_PS_MSG_STATE_ACTIVE ) + { + zmw_enter_critical_section(dev); + + wd->sta.psMgr.isSleepAllowed = 0; + wd->sta.psMgr.state = ZM_PS_MSG_STATE_ACTIVE; + + if ( wd->sta.powerSaveMode > ZM_STA_PS_NONE ) + wd->sta.psMgr.tempWakeUp = 1; + + zmw_leave_critical_section(dev); + + // Wake up the CHIP now!! + zfHpPowerSaveSetState(dev, 0); + } +} +#else +void zfPowerSavingMgrWakeup(zdev_t* dev) +{ +} +#endif + +void zfPowerSavingMgrProcessBeacon(zdev_t* dev, zbuf_t* buf) +{ + u8_t length, bitmap; + u16_t offset, n1, n2, q, r; + zbuf_t* psBuf; + + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + if ( wd->sta.powerSaveMode == ZM_STA_PS_NONE ) + //if ( wd->sta.psMgr.state != ZM_PS_MSG_STATE_SLEEP ) + { + return; + } + + wd->sta.psMgr.isSleepAllowed = 1; + + if ( (offset=zfFindElement(dev, buf, ZM_WLAN_EID_TIM)) != 0xffff ) + { + length = zmw_rx_buf_readb(dev, buf, offset+1); + + if ( length > 3 ) + { + n1 = zmw_rx_buf_readb(dev, buf, offset+4) & (~ZM_BIT_0); + n2 = length + n1 - 4; + q = wd->sta.aid >> 3; + r = wd->sta.aid & 7; + + if ((q >= n1) && (q <= n2)) + { + bitmap = zmw_rx_buf_readb(dev, buf, offset+5+q-n1); + + if ( (bitmap >> r) & ZM_BIT_0 ) + { + //if ( wd->sta.powerSaveMode == ZM_STA_PS_FAST ) + if ( 0 ) + { + wd->sta.psMgr.state = ZM_PS_MSG_STATE_S1; + //zfSendPSPoll(dev); + zfSendNullData(dev, 0); + } + else + { + if ((wd->sta.qosInfo&0xf) != 0xf) + { + /* send ps-poll */ + //printk("zfSendPSPoll #1\n"); + + wd->sta.psMgr.isSleepAllowed = 0; + + switch (wd->sta.powerSaveMode) + { + case ZM_STA_PS_MAX: + case ZM_STA_PS_FAST: + //zm_debug_msg0("wake up and send PS-Poll\n"); + zfSendPSPoll(dev); + break; + case ZM_STA_PS_LIGHT: + zm_debug_msg0("wake up and send null data\n"); + + zmw_enter_critical_section(dev); + wd->sta.psMgr.sleepAllowedtick = 400; + zmw_leave_critical_section(dev); + + zfSendNullData(dev, 0); + break; + } + + wd->sta.psMgr.tempWakeUp = 0; + } + } + } + } + } + } + + while ((psBuf = zfQueueGet(dev, wd->sta.uapsdQ)) != NULL) + { + zfTxSendEth(dev, psBuf, 0, ZM_EXTERNAL_ALLOC_BUF, 0); + } + + //printk("zfPowerSavingMgrProcessBeacon #1\n"); + zfPowerSavingMgrMain(dev); +} + +void zfPowerSavingMgrConnectNotify(zdev_t *dev) +{ + zmw_get_wlan_dev(dev); + + if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) + { + switch(wd->sta.powerSaveMode) + { + case ZM_STA_PS_NONE: + zfHpPowerSaveSetMode(dev, 0, 0, wd->beaconInterval); + break; + + case ZM_STA_PS_FAST: + case ZM_STA_PS_MAX: + case ZM_STA_PS_LIGHT: + zfHpPowerSaveSetMode(dev, 0, 1, wd->beaconInterval); + break; + + default: + zfHpPowerSaveSetMode(dev, 0, 0, wd->beaconInterval); + break; + } + } +} + +void zfPowerSavingMgrPreTBTTInterrupt(zdev_t *dev) +{ + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + /* disable TBTT interrupt when change from connection to disconnect */ + if (zfStaIsDisconnect(dev)) { + zfHpPowerSaveSetMode(dev, 0, 0, 0); + zfPowerSavingMgrWakeup(dev); + return; + } + + zmw_enter_critical_section(dev); + wd->sta.psMgr.ticks++; + + if ( wd->sta.psMgr.ticks < wd->sta.psMgr.maxSleepPeriods ) + { + zmw_leave_critical_section(dev); + return; + } + else + { + wd->sta.psMgr.ticks = 0; + } + + zmw_leave_critical_section(dev); + + zfPowerSavingMgrWakeup(dev); +} + +/* Leave an empty line below to remove warning message on some compiler */ + --- linux-2.6.28.orig/drivers/staging/otus/80211core/chb.c +++ linux-2.6.28/drivers/staging/otus/80211core/chb.c @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* */ +/* Module Name : hb.c */ +/* */ +/* Abstract */ +/* This module contains house keeping and timer functions. */ +/* */ +/* NOTES */ +/* None */ +/* */ +/************************************************************************/ +#include "cprecomp.h" + +/* Called by wrapper every 10 msec */ +void zfiHeartBeat(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + wd->tick++; + +#if 0 + /* => every 1.28 seconds */ + if (wd->cwm.cw_enable && ((wd->tick & 0x7f) == 0x3f)) + { + zfHpCwmUpdate(dev); + } +#endif + /* => every 2.56 seconds */ + if ((wd->tick & 0xff) == 0) + { + zfAgingDefragList(dev, 1); + } + + /* Watch Dog */ + //zfWatchDog(); + + /* LED Control (per 100ms) */ + if ((wd->tick % 10) == 9) + { + zfLed100msCtrl(dev); +#ifdef ZM_ENABLE_BA_RATECTRL + if (!wd->modeMDKEnable) + { + zfiDbgReadTally(dev); + } +#endif + } + +#ifdef ZM_ENABLE_REWRITE_BEACON_START_ADDRESS + if ( wd->wlanMode == ZM_MODE_IBSS ) + { + if ( zfStaIsConnected(dev) ) + { + zfReWriteBeaconStartAddress(dev); + } + } +#endif + + if ( wd->wlanMode == ZM_MODE_IBSS ) + { + if ( zfStaIsConnected(dev) ) + { + wd->tickIbssReceiveBeacon++; // add 10ms + + if ( (wd->sta.ibssSiteSurveyStatus == 2) && + (wd->tickIbssReceiveBeacon == 300) && + (wd->sta.ibssReceiveBeaconCount < 3) ) + { + zm_debug_msg0("It is happen!!! No error message"); + zfReSetCurrentFrequency(dev); + } + } + } + + if(wd->sta.ReceivedPacketRateCounter <= 0) + { + wd->sta.ReceivedPktRatePerSecond = wd->sta.TotalNumberOfReceivePackets; + //zm_debug_msg1("Receive Packet Per Second = ", wd->sta.ReceivedPktRatePerSecond); + if (wd->sta.TotalNumberOfReceivePackets != 0) + { + wd->sta.avgSizeOfReceivePackets = wd->sta.TotalNumberOfReceiveBytes/wd->sta.TotalNumberOfReceivePackets; + } + else + { + wd->sta.avgSizeOfReceivePackets = 640; + } + wd->sta.TotalNumberOfReceivePackets = 0; + wd->sta.TotalNumberOfReceiveBytes = 0; + wd->sta.ReceivedPacketRateCounter = 100; /*for another 1s*/ + } + else + { + wd->sta.ReceivedPacketRateCounter--; + } + + /* => every 1.28 seconds */ + if((wd->tick & 0x7f) == 0x3f) + { + if( wd->sta.NonNAPcount > 0) + { + wd->sta.RTSInAGGMode = TRUE; + wd->sta.NonNAPcount = 0; + } + else + { + wd->sta.RTSInAGGMode = FALSE; + } + } + + + + /* Maintain management time tick */ + zfMmApTimeTick(dev); + zfMmStaTimeTick(dev); + + //zfPhyCrTuning(dev); + + //zfTxPowerControl(dev); + zfHpHeartBeat(dev); + +} + + +void zfDumpBssList(zdev_t* dev) +{ + struct zsBssInfo* pBssInfo; + u8_t str[33]; + u8_t i, j; + u32_t addr1, addr2; + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + zm_debug_msg0("***** Bss scan result *****"); + zmw_enter_critical_section(dev); + + pBssInfo = wd->sta.bssList.head; + + for( i=0; ista.bssList.bssCount; i++ ) + { + if ( i ) + { + zm_debug_msg0("---------------------------"); + } + + zm_debug_msg1("BSS #", i); + for(j=0; jssid[1]; j++) + { + str[j] = pBssInfo->ssid[2+j]; + } + str[pBssInfo->ssid[1]] = 0; + zm_debug_msg0("SSID = "); + zm_debug_msg0(str); + + addr1 = (pBssInfo->bssid[0] << 16) + (pBssInfo->bssid[1] << 8 ) + + pBssInfo->bssid[2]; + addr2 = (pBssInfo->bssid[3] << 16) + (pBssInfo->bssid[4] << 8 ) + + pBssInfo->bssid[5]; + zm_debug_msg2("Bssid = ", addr1); + zm_debug_msg2(" ", addr2); + zm_debug_msg1("frequency = ", pBssInfo->frequency); + zm_debug_msg1("security type = ", pBssInfo->securityType); + zm_debug_msg1("WME = ", pBssInfo->wmeSupport); + zm_debug_msg1("beacon interval = ", pBssInfo->beaconInterval[0] + + (pBssInfo->beaconInterval[1] << 8)); + zm_debug_msg1("capability = ", pBssInfo->capability[0] + + (pBssInfo->capability[1] << 8)); + if ( pBssInfo->supportedRates[1] > 0 ) + { + for( j=0; jsupportedRates[1]; j++ ) + { + zm_debug_msg2("supported rates = ", pBssInfo->supportedRates[2+j]); + } + } + + for( j=0; jextSupportedRates[1]; j++ ) + { + zm_debug_msg2("ext supported rates = ", pBssInfo->extSupportedRates[2+j]); + } + + pBssInfo = pBssInfo->next; + } + zmw_leave_critical_section(dev); + + zm_debug_msg0("***************************"); +} + --- linux-2.6.28.orig/drivers/staging/otus/80211core/pub_usb.h +++ linux-2.6.28/drivers/staging/otus/80211core/pub_usb.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _PUB_USB_H +#define _PUB_USB_H + +#include "../oal_dt.h" + +#define ZM_HAL_80211_MODE_AP 0 +#define ZM_HAL_80211_MODE_STA 1 +#define ZM_HAL_80211_MODE_IBSS_GENERAL 2 +#define ZM_HAL_80211_MODE_IBSS_WPA2PSK 3 + +/* USB module description */ +/* Queue Management */ +/* 80211core requires OAL to implement a transmission queue in OAL's */ +/* USB module. Because there is only limited on-chip memory, so USB */ +/* data transfer may be pending until on-chip memory is available. */ +/* 80211core also requires OAL's USB module to provide two functions */ +/* zfwUsbGetFreeTxQSize() and zfwUsbGetMaxTxQSize() for 80211core to */ +/* query the status of this transmission queue. The main purpose of */ +/* this queue is for QoS/WMM. Though there are hardware priority */ +/* queues on the chip, and also software priority queues in the */ +/* 80211core. There is still one and only one USB channel. So */ +/* 80211core will use the information that zfwUsbGetFreeTxQSize() */ +/* returned to schedule the traffic from the software priority */ +/* queues to the hardware priority queues. For example, if 80211core */ +/* found that USB transmission queue is going to be full, it will */ +/* not allow packets with lower priority to enter the USB channel. */ + + +/* Structure for USB call back functions */ +struct zfCbUsbFuncTbl { + void (*zfcbUsbRecv)(zdev_t *dev, zbuf_t *buf); + void (*zfcbUsbRegIn)(zdev_t* dev, u32_t* rsp, u16_t rspLen); + void (*zfcbUsbOutComplete)(zdev_t* dev, zbuf_t *buf, u8_t status, u8_t *hdr); + void (*zfcbUsbRegOutComplete)(zdev_t* dev); +}; + +/* Call back functions */ +/* Below are the functions that should be called by the OAL */ + +/* When data is available in endpoint 3, OAL shall embed the data in */ +/* zbuf_t and supply to 80211core by calling this function */ +/* void (*zfcbUsbRecv)(zdev_t *dev, zbuf_t *buf); */ + +/* When data is available in endpoint 2, OAL shall call this function */ +/* void (*zfcbUsbRegIn)(zdev_t* dev, u32_t* rsp, u16_t rspLen); */ + +/* When USB data transfer completed in endpoint 1, OAL shall call this function */ +/* void (*zfcbUsbOutComplete)(zdev_t* dev, zbuf_t *buf, u8_t status, u8_t *hdr); */ + + +/* Call out functions */ +/* Below are the functions that supply by the OAL for 80211core to */ +/* manipulate the USB */ + +/* Return OAL's USB TxQ size */ +extern u32_t zfwUsbGetMaxTxQSize(zdev_t* dev); + +/* Return OAL's TxQ available size */ +extern u32_t zfwUsbGetFreeTxQSize(zdev_t* dev); + +/* Register call back function */ +extern void zfwUsbRegisterCallBack(zdev_t* dev, struct zfCbUsbFuncTbl *zfUsbFunc); + +/* Enable USB interrupt endpoint */ +extern u32_t zfwUsbEnableIntEpt(zdev_t *dev, u8_t endpt); + +/* Enable USB Rx endpoint */ +extern int zfwUsbEnableRxEpt(zdev_t* dev, u8_t endpt); + +/* 80211core call this function to send a USB request over endpoint 0 */ +extern u32_t zfwUsbSubmitControl(zdev_t* dev, u8_t req, u16_t value, + u16_t index, void *data, u32_t size); +extern u32_t zfwUsbSubmitControlIo(zdev_t* dev, u8_t req, u8_t reqtype, + u16_t value, u16_t index, void *data, u32_t size); + +/* 80211core call this function to transfer data out over endpoint 1 */ +extern void zfwUsbCmd(zdev_t* dev, u8_t endpt, u32_t* cmd, u16_t cmdLen); + +/* 80211core call this function to transfer data out over endpoint 4 */ +extern u32_t zfwUsbSend(zdev_t* dev, u8_t endpt, u8_t *hdr, u16_t hdrlen, u8_t *snap, u16_t snapLen, + u8_t *tail, u16_t tailLen, zbuf_t *buf, u16_t offset); + +/* 80211core call this function to set USB configuration */ +extern u32_t zfwUsbSetConfiguration(zdev_t *dev, u16_t value); + +#endif --- linux-2.6.28.orig/drivers/staging/otus/80211core/cscanmgr.c +++ linux-2.6.28/drivers/staging/otus/80211core/cscanmgr.c @@ -0,0 +1,535 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "cprecomp.h" + +void zfScanMgrInit(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + wd->sta.scanMgr.scanReqs[0] = 0; + wd->sta.scanMgr.scanReqs[1] = 0; + + wd->sta.scanMgr.currScanType = ZM_SCAN_MGR_SCAN_NONE; + wd->sta.scanMgr.scanStartDelay = 3; + //wd->sta.scanMgr.scanStartDelay = 0; +} + +u8_t zfScanMgrScanStart(zdev_t* dev, u8_t scanType) +{ + u8_t i; + + zmw_get_wlan_dev(dev); + + zm_debug_msg1("scanType = ", scanType); + + zmw_declare_for_critical_section(); + + if ( scanType != ZM_SCAN_MGR_SCAN_INTERNAL && + scanType != ZM_SCAN_MGR_SCAN_EXTERNAL ) + { + zm_debug_msg0("unknown scanType"); + return 1; + } + else if (zfStaIsConnecting(dev)) + { + zm_debug_msg0("reject scan request due to connecting"); + return 1; + } + + i = scanType - 1; + + zmw_enter_critical_section(dev); + + if ( wd->sta.scanMgr.scanReqs[i] == 1 ) + { + zm_debug_msg1("scan rescheduled", scanType); + goto scan_done; + } + + wd->sta.scanMgr.scanReqs[i] = 1; + zm_debug_msg1("scan scheduled: ", scanType); + + // If there's no scan pending, we do the scan right away. + // If there's an internal scan and the new scan request is external one, + // we will restart the scan. + if ( wd->sta.scanMgr.currScanType == ZM_SCAN_MGR_SCAN_NONE ) + { + goto schedule_scan; + } + else if ( wd->sta.scanMgr.currScanType == ZM_SCAN_MGR_SCAN_INTERNAL && + scanType == ZM_SCAN_MGR_SCAN_EXTERNAL ) + { + // Stop the internal scan & schedule external scan first + zfTimerCancel(dev, ZM_EVENT_SCAN); + + /* Fix for WHQL sendrecv => we do not apply delay time in which the device + stop transmitting packet when we already connect to some AP */ + wd->sta.bScheduleScan = FALSE; + + zfTimerCancel(dev, ZM_EVENT_TIMEOUT_SCAN); + zfTimerCancel(dev, ZM_EVENT_IN_SCAN); + + wd->sta.bChannelScan = FALSE; + goto schedule_scan; + } + else + { + zm_debug_msg0("Scan is busy...waiting later to start\n"); + } + + zmw_leave_critical_section(dev); + return 0; + +scan_done: + zmw_leave_critical_section(dev); + return 1; + +schedule_scan: + + wd->sta.bScheduleScan = TRUE; + + zfTimerSchedule(dev, ZM_EVENT_SCAN, wd->sta.scanMgr.scanStartDelay); + wd->sta.scanMgr.scanStartDelay = 3; + //wd->sta.scanMgr.scanStartDelay = 0; + wd->sta.scanMgr.currScanType = scanType; + zmw_leave_critical_section(dev); + + if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev))) + { + zfSendNullData(dev, 1); + } + return 0; +} + +void zfScanMgrScanStop(zdev_t* dev, u8_t scanType) +{ + u8_t scanNotifyRequired = 0; + u8_t theOtherScan = ZM_SCAN_MGR_SCAN_NONE; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + if ( wd->sta.scanMgr.currScanType == ZM_SCAN_MGR_SCAN_NONE ) + { + zm_assert(wd->sta.scanMgr.scanReqs[0] == 0); + zm_assert(wd->sta.scanMgr.scanReqs[1] == 0); + goto done; + } + + switch(scanType) + { + case ZM_SCAN_MGR_SCAN_EXTERNAL: + scanNotifyRequired = 1; + theOtherScan = ZM_SCAN_MGR_SCAN_INTERNAL; + break; + + case ZM_SCAN_MGR_SCAN_INTERNAL: + theOtherScan = ZM_SCAN_MGR_SCAN_EXTERNAL; + break; + + default: + goto done; + } + + if ( wd->sta.scanMgr.currScanType != scanType ) + { + goto stop_done; + } + + zfTimerCancel(dev, ZM_EVENT_SCAN); + + /* Fix for WHQL sendrecv => we do not apply delay time in which the device + stop transmitting packet when we already connect to some AP */ + wd->sta.bScheduleScan = FALSE; + + zfTimerCancel(dev, ZM_EVENT_TIMEOUT_SCAN); + zfTimerCancel(dev, ZM_EVENT_IN_SCAN); + + wd->sta.bChannelScan = FALSE; + wd->sta.scanFrequency = 0; + + if ( wd->sta.scanMgr.scanReqs[theOtherScan - 1] ) + { + wd->sta.scanMgr.currScanType = theOtherScan; + + // Schedule the other scan after 1 second later + zfTimerSchedule(dev, ZM_EVENT_SCAN, 100); + } + else + { + wd->sta.scanMgr.currScanType = ZM_SCAN_MGR_SCAN_NONE; + } + +stop_done: + wd->sta.scanMgr.scanReqs[scanType - 1] = 0; + + zmw_leave_critical_section(dev); + + /* avoid lose receive packet when site survey */ + if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev))) + { + zfSendNullData(dev, 0); + } + + if ( scanNotifyRequired ) + { + zm_debug_msg0("Scan notify after reset"); + if (wd->zfcbScanNotify != NULL) + { + wd->zfcbScanNotify(dev, NULL); + } + } + + return; + +done: + zmw_leave_critical_section(dev); + return; +} + +void zfScanMgrScanAck(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + wd->sta.scanMgr.scanStartDelay = 3; + //wd->sta.scanMgr.scanStartDelay = 0; + + zmw_leave_critical_section(dev); + return; +} + +extern void zfStaReconnect(zdev_t* dev); + +static void zfScanSendProbeRequest(zdev_t* dev) +{ + u8_t k; + u16_t dst[3] = { 0xffff, 0xffff, 0xffff }; + + zmw_get_wlan_dev(dev); + + /* Increase rxBeaconCount to prevent beacon lost */ + if (zfStaIsConnected(dev)) + { + wd->sta.rxBeaconCount++; + } + + if ( wd->sta.bPassiveScan ) + { + return; + } + /* enable 802.l11h and in DFS Band , disable sending probe request */ + if (wd->sta.DFSEnable) + { + if (zfHpIsDfsChannel(dev, wd->sta.scanFrequency)) + { + return; + } + } + + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_PROBEREQ, dst, 0, 0, 0); + + if ( wd->sta.disableProbingWithSsid ) + { + return; + } + + for (k=1; k<=ZM_MAX_PROBE_HIDDEN_SSID_SIZE; k++) + { + if ( wd->ws.probingSsidList[k-1].ssidLen != 0 ) + { + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_PROBEREQ, dst, k, 0, 0); + } + } +} + +static void zfScanMgrEventSetFreqCompleteCb(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + +//printk("zfScanMgrEventSetFreqCompleteCb #1\n"); + + zmw_enter_critical_section(dev); + zfTimerSchedule(dev, ZM_EVENT_IN_SCAN, ZM_TICK_IN_SCAN); + if (wd->sta.bPassiveScan) + { + zfTimerSchedule(dev, ZM_EVENT_TIMEOUT_SCAN, wd->sta.passiveScanTickPerChannel); + } + else + { + zfTimerSchedule(dev, ZM_EVENT_TIMEOUT_SCAN, wd->sta.activescanTickPerChannel); + } + zmw_leave_critical_section(dev); + + zfScanSendProbeRequest(dev); +} + + +static void zfScanMgrEventScanCompleteCb(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev))) + { + zfSendNullData(dev, 0); + } + return; +} + + +void zfScanMgrScanEventRetry(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + if ( !wd->sta.bChannelScan ) + { + return; + } + + if ( !wd->sta.bPassiveScan ) + { + zfScanSendProbeRequest(dev); + #if 0 + zmw_enter_critical_section(dev); + zfTimerSchedule(dev, ZM_EVENT_IN_SCAN, ZM_TICK_IN_SCAN); + zmw_leave_critical_section(dev); + #endif + } +} + +u8_t zfScanMgrScanEventTimeout(zdev_t* dev) +{ + u16_t nextScanFrequency = 0; + u8_t temp; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + if ( wd->sta.scanFrequency == 0 ) + { + zmw_leave_critical_section(dev); + return -1; + } + + nextScanFrequency = zfChGetNextChannel(dev, wd->sta.scanFrequency, + &wd->sta.bPassiveScan); + + if ( (nextScanFrequency == 0xffff) + || (wd->sta.scanFrequency == zfChGetLastChannel(dev, &temp)) ) + { + u8_t currScanType; + u8_t isExternalScan = 0; + u8_t isInternalScan = 0; + + //zm_debug_msg1("end scan = ", KeQueryInterruptTime()); + wd->sta.scanFrequency = 0; + + zm_debug_msg1("scan 1 type: ", wd->sta.scanMgr.currScanType); + zm_debug_msg1("scan channel count = ", wd->regulationTable.allowChannelCnt); + + //zfBssInfoRefresh(dev); + zfTimerCancel(dev, ZM_EVENT_TIMEOUT_SCAN); + + if ( wd->sta.bChannelScan == FALSE ) + { + zm_debug_msg0("WOW!! scan is cancelled\n"); + zmw_leave_critical_section(dev); + goto report_scan_result; + } + + + currScanType = wd->sta.scanMgr.currScanType; + switch(currScanType) + { + case ZM_SCAN_MGR_SCAN_EXTERNAL: + isExternalScan = 1; + + if ( wd->sta.scanMgr.scanReqs[ZM_SCAN_MGR_SCAN_INTERNAL - 1] ) + { + wd->sta.scanMgr.scanReqs[ZM_SCAN_MGR_SCAN_INTERNAL - 1] = 0; + isInternalScan = 1; + } + + break; + + case ZM_SCAN_MGR_SCAN_INTERNAL: + isInternalScan = 1; + + if ( wd->sta.scanMgr.scanReqs[ZM_SCAN_MGR_SCAN_EXTERNAL - 1] ) + { + // Because the external scan should pre-empts internal scan. + // So this shall not be happened!! + zm_assert(0); + } + + break; + + default: + zm_assert(0); + break; + } + + wd->sta.scanMgr.scanReqs[currScanType - 1] = 0; + wd->sta.scanMgr.scanStartDelay = 100; + wd->sta.scanMgr.currScanType = ZM_SCAN_MGR_SCAN_NONE; + zmw_leave_critical_section(dev); + + //Set channel according to AP's configuration + zfCoreSetFrequencyEx(dev, wd->frequency, wd->BandWidth40, + wd->ExtOffset, zfScanMgrEventScanCompleteCb); + + wd->sta.bChannelScan = FALSE; + + #if 1 + if (zfStaIsConnected(dev)) + { // Finish site survey, reset the variable to detect using wrong frequency ! + zfHpFinishSiteSurvey(dev, 1); + zmw_enter_critical_section(dev); + wd->sta.ibssSiteSurveyStatus = 2; + wd->tickIbssReceiveBeacon = 0; + wd->sta.ibssReceiveBeaconCount = 0; + zmw_leave_critical_section(dev); + + /* #5 Re-enable RIFS function after the site survey ! */ + /* This is because switch band will reset the BB register to initial value */ + if( wd->sta.rifsState == ZM_RIFS_STATE_DETECTED ) + { + zfHpEnableRifs(dev, ((wd->sta.currentFrequency<3000)?1:0), wd->sta.EnableHT, wd->sta.HT2040); + } + } + else + { + zfHpFinishSiteSurvey(dev, 0); + zmw_enter_critical_section(dev); + wd->sta.ibssSiteSurveyStatus = 0; + zmw_leave_critical_section(dev); + } + #endif + +report_scan_result: + /* avoid lose receive packet when site survey */ + //if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev))) + //{ + // zfSendNullData(dev, 0); + //} + + if ( isExternalScan )//Quickly reboot + { + if (wd->zfcbScanNotify != NULL) + { + wd->zfcbScanNotify(dev, NULL); + } + } + + if ( isInternalScan ) + { + //wd->sta.InternalScanReq = 0; + zfStaReconnect(dev); + } + + return 0; + } + else + { + wd->sta.scanFrequency = nextScanFrequency; + + //zmw_enter_critical_section(dev); + zfTimerCancel(dev, ZM_EVENT_IN_SCAN); + zmw_leave_critical_section(dev); + + zm_debug_msg0("scan 2"); + zfCoreSetFrequencyV2(dev, wd->sta.scanFrequency, zfScanMgrEventSetFreqCompleteCb); + + return 1; + } +} + +void zfScanMgrScanEventStart(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + if ( wd->sta.bChannelScan ) + { + return; + } + + zfPowerSavingMgrWakeup(dev); + + zmw_enter_critical_section(dev); + + if ( wd->sta.scanMgr.currScanType == ZM_SCAN_MGR_SCAN_NONE ) + { + goto no_scan; + } + + //zfBssInfoRefresh(dev); + zfBssInfoRefresh(dev, 0); + wd->sta.bChannelScan = TRUE; + wd->sta.bScheduleScan = FALSE; + zfTimerCancel(dev, ZM_EVENT_IN_SCAN); + zfTimerCancel(dev, ZM_EVENT_TIMEOUT_SCAN); + + //zm_debug_msg1("start scan = ", KeQueryInterruptTime()); + wd->sta.scanFrequency = zfChGetFirstChannel(dev, &wd->sta.bPassiveScan); + zmw_leave_critical_section(dev); + + /* avoid lose receive packet when site survey */ + //if ((zfStaIsConnected(dev)) && (!zfPowerSavingMgrIsSleeping(dev))) + //{ + // zfSendNullData(dev, 1); + //} +// zm_debug_msg0("scan 0"); +// zfCoreSetFrequencyV2(dev, wd->sta.scanFrequency, zfScanMgrEventSetFreqCompleteCb); + + #if 1 + if (zfStaIsConnected(dev)) + {// If doing site survey ! + zfHpBeginSiteSurvey(dev, 1); + zmw_enter_critical_section(dev); + wd->sta.ibssSiteSurveyStatus = 1; + zmw_leave_critical_section(dev); + } + else + { + zfHpBeginSiteSurvey(dev, 0); + zmw_enter_critical_section(dev); + wd->sta.ibssSiteSurveyStatus = 0; + zmw_leave_critical_section(dev); + } + #endif + + zm_debug_msg0("scan 0"); + zfCoreSetFrequencyV2(dev, wd->sta.scanFrequency, zfScanMgrEventSetFreqCompleteCb); + + return; + +no_scan: + zmw_leave_critical_section(dev); + return; +} --- linux-2.6.28.orig/drivers/staging/otus/80211core/cmmsta.c +++ linux-2.6.28/drivers/staging/otus/80211core/cmmsta.c @@ -0,0 +1,5782 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "cprecomp.h" +#include "ratectrl.h" +#include "../hal/hpreg.h" + +/* TODO : change global variable to constant */ +u8_t zgWpaRadiusOui[] = { 0x00, 0x50, 0xf2, 0x01 }; +u8_t zgWpaAesOui[] = { 0x00, 0x50, 0xf2, 0x04 }; +u8_t zgWpa2RadiusOui[] = { 0x00, 0x0f, 0xac, 0x01 }; +u8_t zgWpa2AesOui[] = { 0x00, 0x0f, 0xac, 0x04 }; + +const u16_t zcCwTlb[16] = { 0, 1, 3, 7, 15, 31, 63, 127, + 255, 511, 1023, 2047, 4095, 4095, 4095, 4095}; + +void zfStaStartConnectCb(zdev_t* dev); + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfStaPutApIntoBlockingList */ +/* Put AP into blocking AP list. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* bssid : AP's BSSID */ +/* weight : weight of AP */ +/* */ +/* OUTPUTS */ +/* none */ +/* */ +/* AUTHOR */ +/* Stephen Chen Atheros Communications, INC. 2006.12 */ +/* */ +/************************************************************************/ +void zfStaPutApIntoBlockingList(zdev_t* dev, u8_t* bssid, u8_t weight) +{ + u16_t i, j; + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + if (weight > 0) + { + zmw_enter_critical_section(dev); + /*Find same bssid entry first*/ + for (i=0; ista.blockingApList[i].addr[j]!= bssid[j]) + { + break; + } + } + + if(j==6) + { + break; + } + } + /*This bssid doesn't have old record.Find an empty entry*/ + if (i == ZM_MAX_BLOCKING_AP_LIST_SIZE) + { + for (i=0; ista.blockingApList[i].weight == 0) + { + break; + } + } + } + + /* If the list is full, pick one entry for replacement */ + if (i == ZM_MAX_BLOCKING_AP_LIST_SIZE) + { + i = bssid[5] & (ZM_MAX_BLOCKING_AP_LIST_SIZE-1); + } + + /* Update AP address and weight */ + for (j=0; j<6; j++) + { + wd->sta.blockingApList[i].addr[j] = bssid[j]; + } + + wd->sta.blockingApList[i].weight = weight; + zmw_leave_critical_section(dev); + } + + return; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfStaIsApInBlockingList */ +/* Is AP in blocking list. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* bssid : AP's BSSID */ +/* */ +/* OUTPUTS */ +/* TRUE : AP in blocking list */ +/* FALSE : AP not in blocking list */ +/* */ +/* AUTHOR */ +/* Stephen Chen Atheros Communications, INC. 2006.12 */ +/* */ +/************************************************************************/ +u16_t zfStaIsApInBlockingList(zdev_t* dev, u8_t* bssid) +{ + u16_t i, j; + zmw_get_wlan_dev(dev); + //zmw_declare_for_critical_section(); + + //zmw_enter_critical_section(dev); + for (i=0; ista.blockingApList[i].weight != 0) + { + for (j=0; j<6; j++) + { + if (wd->sta.blockingApList[i].addr[j] != bssid[j]) + { + break; + } + } + if (j == 6) + { + //zmw_leave_critical_section(dev); + return TRUE; + } + } + } + //zmw_leave_critical_section(dev); + return FALSE; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfStaRefreshBlockList */ +/* Is AP in blocking list. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* flushFlag : flush whole blocking list */ +/* */ +/* OUTPUTS */ +/* none */ +/* */ +/* AUTHOR */ +/* Stephen Chen Atheros Communications, INC. 2006.12 */ +/* */ +/************************************************************************/ +void zfStaRefreshBlockList(zdev_t* dev, u16_t flushFlag) +{ + u16_t i; + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + for (i=0; ista.blockingApList[i].weight != 0) + { + if (flushFlag != 0) + { + wd->sta.blockingApList[i].weight = 0; + } + else + { + wd->sta.blockingApList[i].weight--; + } + } + } + zmw_leave_critical_section(dev); + return; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfStaConnectFail */ +/* Handle Connect failure. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* bssid : BSSID */ +/* reason : reason of failure */ +/* */ +/* OUTPUTS */ +/* none */ +/* */ +/* AUTHOR */ +/* Stephen Chen Atheros Communications, INC. 2006.12 */ +/* */ +/************************************************************************/ +void zfStaConnectFail(zdev_t* dev, u16_t reason, u16_t* bssid, u8_t weight) +{ + zmw_get_wlan_dev(dev); + + /* Change internal state */ + zfChangeAdapterState(dev, ZM_STA_STATE_DISCONNECT); + + /* Improve WEP/TKIP performace with HT AP, detail information please look bug#32495 */ + //zfHpSetTTSIFSTime(dev, 0x8); + + /* Notify wrapper of connection status changes */ + if (wd->zfcbConnectNotify != NULL) + { + wd->zfcbConnectNotify(dev, reason, bssid); + } + + /* Put AP into internal blocking list */ + zfStaPutApIntoBlockingList(dev, (u8_t *)bssid, weight); + + /* Issue another SCAN */ + if ( wd->sta.bAutoReconnect ) + { + zm_debug_msg0("Start internal scan..."); + zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_INTERNAL); + zfScanMgrScanStart(dev, ZM_SCAN_MGR_SCAN_INTERNAL); + } +} + +u8_t zfiWlanIBSSGetPeerStationsCount(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + return wd->sta.oppositeCount; +} + +u8_t zfiWlanIBSSIteratePeerStations(zdev_t* dev, u8_t numToIterate, zfpIBSSIteratePeerStationCb callback, void *ctx) +{ + u8_t oppositeCount; + u8_t i; + u8_t index = 0; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + oppositeCount = wd->sta.oppositeCount; + if ( oppositeCount > numToIterate ) + { + oppositeCount = numToIterate; + } + + for(i=0; i < ZM_MAX_OPPOSITE_COUNT; i++) + { + if ( oppositeCount == 0 ) + { + break; + } + + if ( wd->sta.oppositeInfo[i].valid == 0 ) + { + continue; + } + + callback(dev, &wd->sta.oppositeInfo[i], ctx, index++); + oppositeCount--; + + } + + zmw_leave_critical_section(dev); + + return index; +} + + +s8_t zfStaFindFreeOpposite(zdev_t* dev, u16_t *sa, int *pFoundIdx) +{ + int oppositeCount; + int i; + + zmw_get_wlan_dev(dev); + + oppositeCount = wd->sta.oppositeCount; + + for(i=0; i < ZM_MAX_OPPOSITE_COUNT; i++) + { + if ( oppositeCount == 0 ) + { + break; + } + + if ( wd->sta.oppositeInfo[i].valid == 0 ) + { + continue; + } + + oppositeCount--; + if ( zfMemoryIsEqual((u8_t*) sa, wd->sta.oppositeInfo[i].macAddr, 6) ) + { + //wd->sta.oppositeInfo[i].aliveCounter++; + wd->sta.oppositeInfo[i].aliveCounter = ZM_IBSS_PEER_ALIVE_COUNTER; + + /* it is already stored */ + return 1; + } + } + + // Check if there's still space for new comer + if ( wd->sta.oppositeCount == ZM_MAX_OPPOSITE_COUNT ) + { + return -1; + } + + // Find an unused slot for new peer station + for(i=0; i < ZM_MAX_OPPOSITE_COUNT; i++) + { + if ( wd->sta.oppositeInfo[i].valid == 0 ) + { + break; + } + } + + *pFoundIdx = i; + return 0; +} + +s8_t zfStaFindOppositeByMACAddr(zdev_t* dev, u16_t *sa, u8_t *pFoundIdx) +{ + u32_t oppositeCount; + u32_t i; + + zmw_get_wlan_dev(dev); + + oppositeCount = wd->sta.oppositeCount; + + for(i=0; i < ZM_MAX_OPPOSITE_COUNT; i++) + { + if ( oppositeCount == 0 ) + { + break; + } + + if ( wd->sta.oppositeInfo[i].valid == 0 ) + { + continue; + } + + oppositeCount--; + if ( zfMemoryIsEqual((u8_t*) sa, wd->sta.oppositeInfo[i].macAddr, 6) ) + { + *pFoundIdx = (u8_t)i; + + return 0; + } + } + + *pFoundIdx = 0; + return 1; +} + +static void zfStaInitCommonOppositeInfo(zdev_t* dev, int i) +{ + zmw_get_wlan_dev(dev); + + /* set the default rate to the highest rate */ + wd->sta.oppositeInfo[i].valid = 1; + wd->sta.oppositeInfo[i].aliveCounter = ZM_IBSS_PEER_ALIVE_COUNTER; + wd->sta.oppositeCount++; + +#ifdef ZM_ENABLE_IBSS_WPA2PSK + /* Set parameters for new opposite peer station !!! */ + wd->sta.oppositeInfo[i].camIdx = 0xff; // Not set key in this location + wd->sta.oppositeInfo[i].pkInstalled = 0; + wd->sta.oppositeInfo[i].wpaState = ZM_STA_WPA_STATE_INIT ; // No encryption +#endif +} + +int zfStaSetOppositeInfoFromBSSInfo(zdev_t* dev, struct zsBssInfo* pBssInfo) +{ + int i; + u8_t* dst; + u16_t sa[3]; + int res; + u32_t oneTxStreamCap; + + zmw_get_wlan_dev(dev); + + zfMemoryCopy((u8_t*) sa, pBssInfo->macaddr, 6); + + res = zfStaFindFreeOpposite(dev, sa, &i); + if ( res != 0 ) + { + goto zlReturn; + } + + dst = wd->sta.oppositeInfo[i].macAddr; + zfMemoryCopy(dst, (u8_t *)sa, 6); + + oneTxStreamCap = (zfHpCapability(dev) & ZM_HP_CAP_11N_ONE_TX_STREAM); + + if (pBssInfo->extSupportedRates[1] != 0) + { + /* TODO : Handle 11n */ + if (pBssInfo->frequency < 3000) + { + /* 2.4GHz */ + if (pBssInfo->EnableHT == 1) + zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 1, pBssInfo->SG40); + else + zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 1, pBssInfo->SG40); + } + else + { + /* 5GHz */ + if (pBssInfo->EnableHT == 1) + zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 0, pBssInfo->SG40); + else + zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 0, pBssInfo->SG40); + } + } + else + { + /* TODO : Handle 11n */ + if (pBssInfo->frequency < 3000) + { + /* 2.4GHz */ + if (pBssInfo->EnableHT == 1) + zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 1, pBssInfo->SG40); + else + zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 0, 1, pBssInfo->SG40); + } + else + { + /* 5GHz */ + if (pBssInfo->EnableHT == 1) + zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 0, pBssInfo->SG40); + else + zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 0, pBssInfo->SG40); + } + } + + + zfStaInitCommonOppositeInfo(dev, i); +zlReturn: + return 0; +} + +int zfStaSetOppositeInfoFromRxBuf(zdev_t* dev, zbuf_t* buf) +{ + int i; + u8_t* dst; + u16_t sa[3]; + int res = 0; + u16_t offset; + u8_t bSupportExtRate; + u32_t rtsctsRate = 0xffffffff; /* CTS:OFDM 6M, RTS:OFDM 6M */ + u32_t oneTxStreamCap; + + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + sa[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET); + sa[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+2); + sa[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+4); + + zmw_enter_critical_section(dev); + + res = zfStaFindFreeOpposite(dev, sa, &i); + if ( res != 0 ) + { + goto zlReturn; + } + + dst = wd->sta.oppositeInfo[i].macAddr; + zfCopyFromRxBuffer(dev, buf, dst, ZM_WLAN_HEADER_A2_OFFSET, 6); + + if ( (wd->sta.currentFrequency < 3000) && !(wd->supportMode & (ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N)) ) + { + bSupportExtRate = 0; + } else { + bSupportExtRate = 1; + } + + if ( (bSupportExtRate == 1) + && (wd->sta.currentFrequency < 3000) + && (wd->wlanMode == ZM_MODE_IBSS) + && (wd->wfc.bIbssGMode == 0) ) + { + bSupportExtRate = 0; + } + + wd->sta.connection_11b = 0; + oneTxStreamCap = (zfHpCapability(dev) & ZM_HP_CAP_11N_ONE_TX_STREAM); + + if ( ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE)) != 0xffff) + && (bSupportExtRate == 1) ) + { + /* TODO : Handle 11n */ + if (wd->sta.currentFrequency < 3000) + { + /* 2.4GHz */ + if (wd->sta.EnableHT == 1) + { + //11ng + zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 1, wd->sta.SG40); + } + else + { + //11g + zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 1, wd->sta.SG40); + } + rtsctsRate = 0x00001bb; /* CTS:CCK 1M, RTS:OFDM 6M */ + } + else + { + /* 5GHz */ + if (wd->sta.EnableHT == 1) + { + //11na + zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 0, wd->sta.SG40); + } + else + { + //11a + zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 0, wd->sta.SG40); + } + rtsctsRate = 0x10b01bb; /* CTS:OFDM 6M, RTS:OFDM 6M */ + } + } + else + { + /* TODO : Handle 11n */ + if (wd->sta.currentFrequency < 3000) + { + /* 2.4GHz */ + if (wd->sta.EnableHT == 1) + { + //11ng + zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 1, wd->sta.SG40); + rtsctsRate = 0x00001bb; /* CTS:CCK 1M, RTS:OFDM 6M */ + } + else + { + //11b + zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 0, 1, wd->sta.SG40); + rtsctsRate = 0x0; /* CTS:CCK 1M, RTS:CCK 1M */ + wd->sta.connection_11b = 1; + } + } + else + { + /* 5GHz */ + if (wd->sta.EnableHT == 1) + { + //11na + zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, (oneTxStreamCap!=0)?3:2, 0, wd->sta.SG40); + } + else + { + //11a + zfRateCtrlInitCell(dev, &wd->sta.oppositeInfo[i].rcCell, 1, 0, wd->sta.SG40); + } + rtsctsRate = 0x10b01bb; /* CTS:OFDM 6M, RTS:OFDM 6M */ + } + } + + zfStaInitCommonOppositeInfo(dev, i); + +zlReturn: + zmw_leave_critical_section(dev); + + if (rtsctsRate != 0xffffffff) + { + zfHpSetRTSCTSRate(dev, rtsctsRate); + } + return res; +} + +void zfStaProtErpMonitor(zdev_t* dev, zbuf_t* buf) +{ + u16_t offset; + u8_t erp; + u8_t bssid[6]; + + zmw_get_wlan_dev(dev); + + if ( (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)&&(zfStaIsConnected(dev)) ) + { + ZM_MAC_WORD_TO_BYTE(wd->sta.bssid, bssid); + + if (zfRxBufferEqualToStr(dev, buf, bssid, ZM_WLAN_HEADER_A2_OFFSET, 6)) + { + if ( (offset=zfFindElement(dev, buf, ZM_WLAN_EID_ERP)) != 0xffff ) + { + erp = zmw_rx_buf_readb(dev, buf, offset+2); + + if ( erp & ZM_BIT_1 ) + { + //zm_debug_msg0("protection mode on"); + if (wd->sta.bProtectionMode == FALSE) + { + wd->sta.bProtectionMode = TRUE; + zfHpSetSlotTime(dev, 0); + } + } + else + { + //zm_debug_msg0("protection mode off"); + if (wd->sta.bProtectionMode == TRUE) + { + wd->sta.bProtectionMode = FALSE; + zfHpSetSlotTime(dev, 1); + } + } + } + } + //Check the existence of Non-N AP + //Follow the check the "pBssInfo->EnableHT" + if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY)) != 0xffff) + {} + else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTCAPABILITY)) != 0xffff) + {} + else + {wd->sta.NonNAPcount++;} + } +} + +void zfStaUpdateWmeParameter(zdev_t* dev, zbuf_t* buf) +{ + u16_t tmp; + u16_t aifs[5]; + u16_t cwmin[5]; + u16_t cwmax[5]; + u16_t txop[5]; + u8_t acm; + u8_t ac; + u16_t len; + u16_t i; + u16_t offset; + u8_t rxWmeParameterSetCount; + + zmw_get_wlan_dev(dev); + + /* Update if WME parameter set count is changed */ + /* If connect to WME AP */ + if (wd->sta.wmeConnected != 0) + { + /* Find WME parameter element */ + if ((offset = zfFindWifiElement(dev, buf, 2, 1)) != 0xffff) + { + if ((len = zmw_rx_buf_readb(dev, buf, offset+1)) >= 7) + { + rxWmeParameterSetCount=zmw_rx_buf_readb(dev, buf, offset+8); + if (rxWmeParameterSetCount != wd->sta.wmeParameterSetCount) + { + zm_msg0_mm(ZM_LV_0, "wmeParameterSetCount changed!"); + wd->sta.wmeParameterSetCount = rxWmeParameterSetCount; + /* retrieve WME parameter and update TxQ parameters */ + acm = 0xf; + for (i=0; i<4; i++) + { + if (len >= (8+(i*4)+4)) + { + tmp=zmw_rx_buf_readb(dev, buf, offset+10+i*4); + ac = (tmp >> 5) & 0x3; + if ((tmp & 0x10) == 0) + { + acm &= (~(1<> 4)]; + txop[ac]=zmw_rx_buf_readh(dev, buf, + offset+12+i*4); + } + } + + if ((acm & 0x4) != 0) + { + cwmin[2] = cwmin[0]; + cwmax[2] = cwmax[0]; + aifs[2] = aifs[0]; + txop[2] = txop[0]; + } + if ((acm & 0x8) != 0) + { + cwmin[3] = cwmin[2]; + cwmax[3] = cwmax[2]; + aifs[3] = aifs[2]; + txop[3] = txop[2]; + } + cwmin[4] = 3; + cwmax[4] = 7; + aifs[4] = 28; + + if ((cwmin[2]+aifs[2]) > ((cwmin[0]+aifs[0])+1)) + { + wd->sta.ac0PriorityHigherThanAc2 = 1; + } + else + { + wd->sta.ac0PriorityHigherThanAc2 = 0; + } + zfHpUpdateQosParameter(dev, cwmin, cwmax, aifs, txop); + } + } + } + } //if (wd->sta.wmeConnected != 0) +} +/* process 802.11h Dynamic Frequency Selection */ +void zfStaUpdateDot11HDFS(zdev_t* dev, zbuf_t* buf) +{ + zmw_get_wlan_dev(dev); + + /* + Channel Switch Announcement Element Format + +------+----------+------+-------------------+------------------+--------------------+ + |Format|Element ID|Length|Channel Switch Mode|New Channel Number|Channel Switch Count| + +------+----------+------+-------------------+------------------+--------------------+ + |Bytes | 1 | 1 | 1 | 1 | 1 | + +------+----------+------+-------------------+------------------+--------------------+ + |Value | 37 | 3 | 0 or 1 |unsigned integer |unsigned integer | + +------+----------+------+-------------------+------------------+--------------------+ + */ + //u8_t length, channel, is5G; + u16_t offset; + + /* get EID(Channel Switch Announcement) */ + if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_CHANNEL_SWITCH_ANNOUNCE)) == 0xffff ) + { + //zm_debug_msg0("EID(Channel Switch Announcement) not found"); + return; + } + else if ( zmw_rx_buf_readb(dev, buf, offset+1) == 0x3 ) + { + zm_debug_msg0("EID(Channel Switch Announcement) found"); + + //length = zmw_rx_buf_readb(dev, buf, offset+1); + //zfCopyFromRxBuffer(dev, buf, pBssInfo->supportedRates, offset, length+2); + + //Chanell Switch Mode set to 1, driver should disable transmit immediate + //we do this by poll CCA high + if (zmw_rx_buf_readb(dev, buf, offset+2) == 0x1 ) + { + //use ZM_OID_INTERNAL_WRITE,ZM_CMD_RESET to notice firmware flush quene and stop dma, + //then restart rx dma but not tx dma + if (wd->sta.DFSDisableTx != TRUE) + { + /* TODO : zfHpResetTxRx would cause Rx hang */ + //zfHpResetTxRx(dev); + wd->sta.DFSDisableTx = TRUE; + /* Trgger Rx DMA */ + zfHpStartRecv(dev); + } + //Adapter->ZD80211HSetting.DisableTxBy80211H=TRUE; + //AcquireCtrOfPhyReg(Adapter); + //ZD1205_WRITE_REGISTER(Adapter,CR24, 0x0); + //ReleaseDoNotSleep(Adapter); + } + + if (zmw_rx_buf_readb(dev, buf, offset+4) <= 0x2 ) + { + //Channel Switch + //if Channel Switch Count = 0 , STA should change channel immediately. + //if Channel Switch Count > 0 , STA should change channel after TBTT*count + //But it won't be accurate to let driver calculate TBTT*count, and the value of + //Channel Switch Count will decrease by one each when continue receving beacon + //So we change channel here when we receive count <=2. + + zfHpDeleteAllowChannel(dev, wd->sta.currentFrequency); + wd->frequency = zfChNumToFreq(dev, zmw_rx_buf_readb(dev, buf, offset+3), 0); + //zfHpAddAllowChannel(dev, wd->frequency); + zm_debug_msg1("CWY - jump to frequency = ", wd->frequency); + zfCoreSetFrequency(dev, wd->frequency); + wd->sta.DFSDisableTx = FALSE; + /* Increase rxBeaconCount to prevent beacon lost */ + if (zfStaIsConnected(dev)) + { + wd->sta.rxBeaconCount = 1 << 6; // 2 times of check would pass + } + //start tx dma to transmit packet + + //if (zmw_rx_buf_readb(dev, buf, offset+3) != wd->frequency) + //{ + // //ZDDbgPrint(("Radar Detect by AP\n")); + // zfCoreSetFrequency(); + // ProcessRadarDetectEvent(Adapter); + // Set_RF_Channel(Adapter, SwRfd->Rfd->RxBuffer[index+3], (UCHAR)Adapter->RF_Mode, 1); + // Adapter->CardSetting.Channel = SwRfd->Rfd->RxBuffer[index+3]; + // Adapter->SaveChannel = Adapter->CardSetting.Channel; + // Adapter->UtilityChannel = Adapter->CardSetting.Channel; + //} + } + } + +} +/* TODO : process 802.11h Transmission Power Control */ +void zfStaUpdateDot11HTPC(zdev_t* dev, zbuf_t* buf) +{ +} + +/* IBSS power-saving mode */ +void zfStaIbssPSCheckState(zdev_t* dev, zbuf_t* buf) +{ + u8_t i, frameCtrl; + + zmw_get_wlan_dev(dev); + + if ( !zfStaIsConnected(dev) ) + { + return; + } + + if ( wd->wlanMode != ZM_MODE_IBSS ) + { + return ; + } + + /* check BSSID */ + if ( !zfRxBufferEqualToStr(dev, buf, (u8_t*) wd->sta.bssid, + ZM_WLAN_HEADER_A3_OFFSET, 6) ) + { + return; + } + + frameCtrl = zmw_rx_buf_readb(dev, buf, 1); + + /* check power management bit */ + if ( frameCtrl & ZM_BIT_4 ) + { + for(i=1; ista.staPSList.entity[i].bUsed ) + { + continue; + } + + /* check source address */ + if ( zfRxBufferEqualToStr(dev, buf, + wd->sta.staPSList.entity[i].macAddr, + ZM_WLAN_HEADER_A2_OFFSET, 6) ) + { + return; + } + } + + for(i=1; ista.staPSList.entity[i].bUsed ) + { + wd->sta.staPSList.entity[i].bUsed = TRUE; + wd->sta.staPSList.entity[i].bDataQueued = FALSE; + break; + } + } + + if ( i == ZM_MAX_PS_STA ) + { + /* STA list is full */ + return; + } + + zfCopyFromRxBuffer(dev, buf, wd->sta.staPSList.entity[i].macAddr, + ZM_WLAN_HEADER_A2_OFFSET, 6); + + if ( wd->sta.staPSList.count == 0 ) + { + // enable ATIM window + //zfEnableAtimWindow(dev); + } + + wd->sta.staPSList.count++; + } + else if ( wd->sta.staPSList.count ) + { + for(i=1; ista.staPSList.entity[i].bUsed ) + { + if ( zfRxBufferEqualToStr(dev, buf, + wd->sta.staPSList.entity[i].macAddr, + ZM_WLAN_HEADER_A2_OFFSET, 6) ) + { + wd->sta.staPSList.entity[i].bUsed = FALSE; + wd->sta.staPSList.count--; + + if ( wd->sta.staPSList.entity[i].bDataQueued ) + { + /* send queued data */ + } + } + } + } + + if ( wd->sta.staPSList.count == 0 ) + { + /* disable ATIM window */ + //zfDisableAtimWindow(dev); + } + + } +} + +/* IBSS power-saving mode */ +u8_t zfStaIbssPSQueueData(zdev_t* dev, zbuf_t* buf) +{ + u8_t i; + u16_t da[3]; + + zmw_get_wlan_dev(dev); + + if ( !zfStaIsConnected(dev) ) + { + return 0; + } + + if ( wd->wlanMode != ZM_MODE_IBSS ) + { + return 0; + } + + if ( wd->sta.staPSList.count == 0 && wd->sta.powerSaveMode <= ZM_STA_PS_NONE ) + { + return 0; + } + + /* DA */ +#ifdef ZM_ENABLE_NATIVE_WIFI + da[0] = zmw_tx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET); + da[1] = zmw_tx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET + 2); + da[2] = zmw_tx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET + 4); +#else + da[0] = zmw_tx_buf_readh(dev, buf, 0); + da[1] = zmw_tx_buf_readh(dev, buf, 2); + da[2] = zmw_tx_buf_readh(dev, buf, 4); +#endif + + if ( ZM_IS_MULTICAST_OR_BROADCAST(da) ) + { + wd->sta.staPSList.entity[0].bDataQueued = TRUE; + wd->sta.ibssPSDataQueue[wd->sta.ibssPSDataCount++] = buf; + return 1; + } + + // Unicast packet... + + for(i=1; ista.staPSList.entity[i].macAddr, + (u8_t*) da, 6) ) + { + wd->sta.staPSList.entity[i].bDataQueued = TRUE; + wd->sta.ibssPSDataQueue[wd->sta.ibssPSDataCount++] = buf; + + return 1; + } + } + +#if 0 + if ( wd->sta.powerSaveMode > ZM_STA_PS_NONE ) + { + wd->sta.staPSDataQueue[wd->sta.staPSDataCount++] = buf; + + return 1; + } +#endif + + return 0; +} + +/* IBSS power-saving mode */ +void zfStaIbssPSSend(zdev_t* dev) +{ + u8_t i; + u16_t bcastAddr[3] = {0xffff, 0xffff, 0xffff}; + + zmw_get_wlan_dev(dev); + + if ( !zfStaIsConnected(dev) ) + { + return ; + } + + if ( wd->wlanMode != ZM_MODE_IBSS ) + { + return ; + } + + for(i=0; ista.staPSList.entity[i].bDataQueued ) + { + if ( i == 0 ) + { + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_ATIM, + bcastAddr, + 0, 0, 0); + } + else if ( wd->sta.staPSList.entity[i].bUsed ) + { + // Send ATIM to prevent the peer to go to sleep + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_ATIM, + (u16_t*) wd->sta.staPSList.entity[i].macAddr, + 0, 0, 0); + } + + wd->sta.staPSList.entity[i].bDataQueued = FALSE; + } + } + + for(i=0; ista.ibssPSDataCount; i++) + { + zfTxSendEth(dev, wd->sta.ibssPSDataQueue[i], 0, + ZM_EXTERNAL_ALLOC_BUF, 0); + } + + wd->sta.ibssPrevPSDataCount = wd->sta.ibssPSDataCount; + wd->sta.ibssPSDataCount = 0; +} + + +void zfStaReconnect(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + if ( wd->wlanMode != ZM_MODE_INFRASTRUCTURE && + wd->wlanMode != ZM_MODE_IBSS ) + { + return; + } + + if ( (zfStaIsConnected(dev))||(zfStaIsConnecting(dev)) ) + { + return; + } + + if ( wd->sta.bChannelScan ) + { + return; + } + + /* Recover zero SSID length */ + if ( (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) && (wd->ws.ssidLen == 0)) + { + zm_debug_msg0("zfStaReconnect: NOT Support!! Set SSID to any BSS"); + /* ANY BSS */ + zmw_enter_critical_section(dev); + wd->sta.ssid[0] = 0; + wd->sta.ssidLen = 0; + zmw_leave_critical_section(dev); + } + + // RAY: To ensure no TX pending before re-connecting + zfFlushVtxq(dev); + zfWlanEnable(dev); + zfScanMgrScanAck(dev); +} + +void zfStaTimer100ms(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + if ( (wd->tick % 10) == 0 ) + { + zfPushVtxq(dev); +// zfPowerSavingMgrMain(dev); + } +} + + +void zfStaCheckRxBeacon(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + if (( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) && (zfStaIsConnected(dev))) + { + if (wd->beaconInterval == 0) + { + wd->beaconInterval = 100; + } + if ( (wd->tick % ((wd->beaconInterval * 10) / ZM_MS_PER_TICK)) == 0 ) + { + /* Check rxBeaconCount */ + if (wd->sta.rxBeaconCount == 0) + { + if (wd->sta.beaconMissState == 1) + { + /*notify AP that we left*/ + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, wd->sta.bssid, 3, 0, 0); + /* Beacon Lost */ + zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_BEACON_MISS, + wd->sta.bssid, 0); + } + else + { + wd->sta.beaconMissState = 1; + /* Reset channel */ + zfCoreSetFrequencyExV2(dev, wd->frequency, wd->BandWidth40, + wd->ExtOffset, NULL, 1); + } + } + else + { + wd->sta.beaconMissState = 0; + } + wd->sta.rxBeaconCount = 0; + } + } +} + + + +void zfStaCheckConnectTimeout(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + if ( wd->wlanMode != ZM_MODE_INFRASTRUCTURE ) + { + return; + } + + if ( !zfStaIsConnecting(dev) ) + { + return; + } + + zmw_enter_critical_section(dev); + if ( (wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_OPEN)|| + (wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_SHARE_1)|| + (wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_SHARE_2)|| + (wd->sta.connectState == ZM_STA_CONN_STATE_ASSOCIATE) ) + { + if ( (wd->tick - wd->sta.connectTimer) > ZM_INTERVAL_CONNECT_TIMEOUT ) + { + if ( wd->sta.connectByReasso ) + { + wd->sta.failCntOfReasso++; + if ( wd->sta.failCntOfReasso > 2 ) + { + wd->sta.connectByReasso = FALSE; + } + } + + wd->sta.connectState = ZM_STA_CONN_STATE_NONE; + zm_debug_msg1("connect timeout, state = ", wd->sta.connectState); + //zfiWlanDisable(dev); + goto failed; + } + } + + zmw_leave_critical_section(dev); + return; + +failed: + zmw_leave_critical_section(dev); + if(wd->sta.authMode == ZM_AUTH_MODE_AUTO) + { // Fix some AP not send authentication failed message to sta and lead to connect timeout ! + wd->sta.connectTimeoutCount++; + } + zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_TIMEOUT, wd->sta.bssid, 2); + return; +} + +void zfMmStaTimeTick(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + /* airopeek */ + if (wd->wlanMode != ZM_MODE_AP && !wd->swSniffer) + { + if ( wd->tick & 1 ) + { + zfTimerCheckAndHandle(dev); + } + + zfStaCheckRxBeacon(dev); + zfStaTimer100ms(dev); + zfStaCheckConnectTimeout(dev); + zfPowerSavingMgrMain(dev); + } + +#ifdef ZM_ENABLE_AGGREGATION + /* + * add by honda + */ + zfAggScanAndClear(dev, wd->tick); +#endif +} + +void zfStaSendBeacon(zdev_t* dev) +{ + zbuf_t* buf; + u16_t offset, seq; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + //zm_debug_msg0("\n"); + + /* TBD : Maximum size of beacon */ + if ((buf = zfwBufAllocate(dev, 1024)) == NULL) + { + zm_debug_msg0("Allocate beacon buffer failed"); + return; + } + + offset = 0; + /* wlan header */ + /* Frame control */ + zmw_tx_buf_writeh(dev, buf, offset, 0x0080); + offset+=2; + /* Duration */ + zmw_tx_buf_writeh(dev, buf, offset, 0x0000); + offset+=2; + /* Address 1 */ + zmw_tx_buf_writeh(dev, buf, offset, 0xffff); + offset+=2; + zmw_tx_buf_writeh(dev, buf, offset, 0xffff); + offset+=2; + zmw_tx_buf_writeh(dev, buf, offset, 0xffff); + offset+=2; + /* Address 2 */ + zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[0]); + offset+=2; + zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[1]); + offset+=2; + zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[2]); + offset+=2; + /* Address 3 */ + zmw_tx_buf_writeh(dev, buf, offset, wd->sta.bssid[0]); + offset+=2; + zmw_tx_buf_writeh(dev, buf, offset, wd->sta.bssid[1]); + offset+=2; + zmw_tx_buf_writeh(dev, buf, offset, wd->sta.bssid[2]); + offset+=2; + + /* Sequence number */ + zmw_enter_critical_section(dev); + seq = ((wd->mmseq++)<<4); + zmw_leave_critical_section(dev); + zmw_tx_buf_writeh(dev, buf, offset, seq); + offset+=2; + + /* 24-31 Time Stamp : hardware will fill this field */ + offset+=8; + + /* Beacon Interval */ + zmw_tx_buf_writeh(dev, buf, offset, wd->beaconInterval); + offset+=2; + + /* Capability */ + zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.capability[0]); + zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.capability[1]); + + /* SSID */ + offset = zfStaAddIeSsid(dev, buf, offset); + + if(wd->frequency <= ZM_CH_G_14) // 2.4 GHz b+g + { + + /* Support Rate */ + offset = zfMmAddIeSupportRate(dev, buf, offset, + ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_CCK); + + /* DS parameter set */ + offset = zfMmAddIeDs(dev, buf, offset); + + offset = zfStaAddIeIbss(dev, buf, offset); + + if( wd->wfc.bIbssGMode + && (wd->supportMode & (ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N)) ) // Only accompany with enabling a mode . + { + /* ERP Information */ + wd->erpElement = 0; + offset = zfMmAddIeErp(dev, buf, offset); + } + + /* TODO : country information */ + /* RSN */ + if ( wd->sta.authMode == ZM_AUTH_MODE_WPA2PSK ) + { + offset = zfwStaAddIeWpaRsn(dev, buf, offset, ZM_WLAN_FRAME_TYPE_AUTH); + } + + if( wd->wfc.bIbssGMode + && (wd->supportMode & (ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N)) ) // Only accompany with enabling a mode . + { + /* Enable G Mode */ + /* Extended Supported Rates */ + offset = zfMmAddIeSupportRate(dev, buf, offset, + ZM_WLAN_EID_EXTENDED_RATE, ZM_RATE_SET_OFDM); + } + } + else // 5GHz a + { + /* Support Rate a Mode */ + offset = zfMmAddIeSupportRate(dev, buf, offset, + ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_OFDM); + + /* DS parameter set */ + offset = zfMmAddIeDs(dev, buf, offset); + + offset = zfStaAddIeIbss(dev, buf, offset); + + /* TODO : country information */ + /* RSN */ + if ( wd->sta.authMode == ZM_AUTH_MODE_WPA2PSK ) + { + offset = zfwStaAddIeWpaRsn(dev, buf, offset, ZM_WLAN_FRAME_TYPE_AUTH); + } + } + + if ( wd->wlanMode != ZM_MODE_IBSS ) + { + /* TODO : Need to check if it is ok */ + /* HT Capabilities Info */ + offset = zfMmAddHTCapability(dev, buf, offset); + + /* Extended HT Capabilities Info */ + offset = zfMmAddExtendedHTCapability(dev, buf, offset); + } + + if ( wd->sta.ibssAdditionalIESize ) + offset = zfStaAddIbssAdditionalIE(dev, buf, offset); + + /* 1212 : write to beacon fifo */ + /* 1221 : write to share memory */ + zfHpSendBeacon(dev, buf, offset); + + /* Free beacon buffer */ + //zfwBufFree(dev, buf, 0); +} + +void zfStaSignalStatistic(zdev_t* dev, u8_t SignalStrength, u8_t SignalQuality) //CWYang(+) +{ + zmw_get_wlan_dev(dev); + + /* Add Your Code to Do Works Like Moving Average Here */ + wd->SignalStrength = (wd->SignalStrength * 7 + SignalStrength * 3)/10; + wd->SignalQuality = (wd->SignalQuality * 7 + SignalQuality * 3)/10; + +} + +struct zsBssInfo* zfStaFindBssInfo(zdev_t* dev, zbuf_t* buf, struct zsWlanProbeRspFrameHeader *pProbeRspHeader) +{ + u8_t i; + u8_t j; + u8_t k; + u8_t isMatched, length, channel; + u16_t offset, frequency; + struct zsBssInfo* pBssInfo; + + zmw_get_wlan_dev(dev); + + if ((pBssInfo = wd->sta.bssList.head) == NULL) + { + return NULL; + } + + for( i=0; ista.bssList.bssCount; i++ ) + { + //zm_debug_msg2("check pBssInfo = ", pBssInfo); + + /* Check BSSID */ + for( j=0; j<6; j++ ) + { + if ( pBssInfo->bssid[j] != pProbeRspHeader->bssid[j] ) + { + break; + } + } + + /* Check SSID */ + if (j == 6) + { + if (pProbeRspHeader->ssid[1] <= 32) + { + /* compare length and ssid */ + isMatched = 1; + if((pProbeRspHeader->ssid[1] != 0) && (pBssInfo->ssid[1] != 0)) + { + for( k=1; kssid[1] + 1; k++ ) + { + if ( pBssInfo->ssid[k] != pProbeRspHeader->ssid[k] ) + { + isMatched = 0; + break; + } + } + } + } + else + { + isMatched = 0; + } + } + else + { + isMatched = 0; + } + + /* Check channel */ + /* Add check channel to solve the bug #31222 */ + if (isMatched) { + if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_DS)) != 0xffff) { + if ((length = zmw_rx_buf_readb(dev, buf, offset+1)) == 1) { + channel = zmw_rx_buf_readb(dev, buf, offset+2); + if (zfHpIsAllowedChannel(dev, zfChNumToFreq(dev, channel, 0)) == 0) { + frequency = 0; + } else { + frequency = zfChNumToFreq(dev, channel, 0);; + } + } else { + frequency = 0; + } + } else { + frequency = wd->sta.currentFrequency; + } + + if (frequency != 0) { + if ( ((frequency > 3000) && (pBssInfo->frequency > 3000)) + || ((frequency < 3000) && (pBssInfo->frequency < 3000)) ) { + /* redundant */ + break; + } + } + } + + pBssInfo = pBssInfo->next; + } + + if ( i == wd->sta.bssList.bssCount ) + { + pBssInfo = NULL; + } + + return pBssInfo; +} + +u8_t zfStaInitBssInfo(zdev_t* dev, zbuf_t* buf, + struct zsWlanProbeRspFrameHeader *pProbeRspHeader, + struct zsBssInfo* pBssInfo, struct zsAdditionInfo* AddInfo, u8_t type) +{ + u8_t length, channel, is5G; + u16_t i, offset; + u8_t apQosInfo; + u16_t eachIElength = 0; + u16_t accumulateLen = 0; + + zmw_get_wlan_dev(dev); + + if ((type == 1) && ((pBssInfo->flag & ZM_BSS_INFO_VALID_BIT) != 0)) + { + goto zlUpdateRssi; + } + + /* get SSID */ + if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID)) == 0xffff ) + { + zm_debug_msg0("EID(SSID) not found"); + goto zlError; + } + + length = zmw_rx_buf_readb(dev, buf, offset+1); + + { + u8_t Show_Flag = 0; + zfwGetShowZeroLengthSSID(dev, &Show_Flag); + + if(Show_Flag) + { + if (length > ZM_MAX_SSID_LENGTH ) + { + zm_debug_msg0("EID(SSID) is invalid"); + goto zlError; + } + } + else + { + if ( length == 0 || length > ZM_MAX_SSID_LENGTH ) + { + zm_debug_msg0("EID(SSID) is invalid"); + goto zlError; + } + + } + } + zfCopyFromRxBuffer(dev, buf, pBssInfo->ssid, offset, length+2); + + /* get DS parameter */ + if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_DS)) != 0xffff ) + { + length = zmw_rx_buf_readb(dev, buf, offset+1); + if ( length != 1 ) + { + zm_msg0_mm(ZM_LV_0, "Abnormal DS Param Set IE"); + goto zlError; + } + channel = zmw_rx_buf_readb(dev, buf, offset+2); + + if (zfHpIsAllowedChannel(dev, zfChNumToFreq(dev, channel, 0)) == 0) + { + goto zlError2; + } + + pBssInfo->frequency = zfChNumToFreq(dev, channel, 0); // auto check + pBssInfo->channel = channel; + + + } + else + { + /* DS parameter not found */ + pBssInfo->frequency = wd->sta.currentFrequency; + pBssInfo->channel = zfChFreqToNum(wd->sta.currentFrequency, &is5G); + } + + /* initialize security type */ + pBssInfo->securityType = ZM_SECURITY_TYPE_NONE; + + /* get macaddr */ + for( i=0; i<6; i++ ) + { + pBssInfo->macaddr[i] = pProbeRspHeader->sa[i]; + } + + /* get bssid */ + for( i=0; i<6; i++ ) + { + pBssInfo->bssid[i] = pProbeRspHeader->bssid[i]; + } + + /* get timestamp */ + for( i=0; i<8; i++ ) + { + pBssInfo->timeStamp[i] = pProbeRspHeader->timeStamp[i]; + } + + /* get beacon interval */ + pBssInfo->beaconInterval[0] = pProbeRspHeader->beaconInterval[0]; + pBssInfo->beaconInterval[1] = pProbeRspHeader->beaconInterval[1]; + + /* get capability */ + pBssInfo->capability[0] = pProbeRspHeader->capability[0]; + pBssInfo->capability[1] = pProbeRspHeader->capability[1]; + + /* Copy frame body */ + offset = 36; // Copy from the start of variable IE + pBssInfo->frameBodysize = zfwBufGetSize(dev, buf)-offset; + if (pBssInfo->frameBodysize > (ZM_MAX_PROBE_FRAME_BODY_SIZE-1)) + { + pBssInfo->frameBodysize = ZM_MAX_PROBE_FRAME_BODY_SIZE-1; + } + accumulateLen = 0; + do + { + eachIElength = zmw_rx_buf_readb(dev, buf, offset + accumulateLen+1) + 2; //Len+(EID+Data) + + if ( (eachIElength >= 2) + && ((accumulateLen + eachIElength) <= pBssInfo->frameBodysize) ) + { + zfCopyFromRxBuffer(dev, buf, pBssInfo->frameBody+accumulateLen, offset+accumulateLen, eachIElength); + accumulateLen+=(u16_t)eachIElength; + } + else + { + zm_msg0_mm(ZM_LV_1, "probersp frameBodysize abnormal"); + break; + } + } + while(accumulateLen < pBssInfo->frameBodysize); + pBssInfo->frameBodysize = accumulateLen; + + /* get supported rates */ + if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_SUPPORT_RATE)) == 0xffff ) + { + zm_debug_msg0("EID(supported rates) not found"); + goto zlError; + } + + length = zmw_rx_buf_readb(dev, buf, offset+1); + if ( length == 0 || length > ZM_MAX_SUPP_RATES_IE_SIZE) + { + zm_msg0_mm(ZM_LV_0, "Supported rates IE length abnormal"); + goto zlError; + } + zfCopyFromRxBuffer(dev, buf, pBssInfo->supportedRates, offset, length+2); + + + + /* get Country information */ + if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_COUNTRY)) != 0xffff ) + { + length = zmw_rx_buf_readb(dev, buf, offset+1); + if (length > ZM_MAX_COUNTRY_INFO_SIZE) + { + length = ZM_MAX_COUNTRY_INFO_SIZE; + } + zfCopyFromRxBuffer(dev, buf, pBssInfo->countryInfo, offset, length+2); + /* check 802.11d support data */ + if (wd->sta.b802_11D) + { + zfHpGetRegulationTablefromISO(dev, (u8_t *)&pBssInfo->countryInfo, 3); + /* only set regulatory one time */ + wd->sta.b802_11D = 0; + } + } + + /* get ERP information */ + if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_ERP)) != 0xffff ) + { + pBssInfo->erp = zmw_rx_buf_readb(dev, buf, offset+2); + } + + /* get extended supported rates */ + if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE)) != 0xffff ) + { + length = zmw_rx_buf_readb(dev, buf, offset+1); + if (length > ZM_MAX_SUPP_RATES_IE_SIZE) + { + zm_msg0_mm(ZM_LV_0, "Extended rates IE length abnormal"); + goto zlError; + } + zfCopyFromRxBuffer(dev, buf, pBssInfo->extSupportedRates, offset, length+2); + } + else + { + pBssInfo->extSupportedRates[0] = 0; + pBssInfo->extSupportedRates[1] = 0; + } + + /* get WPA IE */ + if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_WPA_IE)) != 0xffff ) + { + length = zmw_rx_buf_readb(dev, buf, offset+1); + if (length > ZM_MAX_IE_SIZE) + { + length = ZM_MAX_IE_SIZE; + } + zfCopyFromRxBuffer(dev, buf, pBssInfo->wpaIe, offset, length+2); + pBssInfo->securityType = ZM_SECURITY_TYPE_WPA; + } + else + { + pBssInfo->wpaIe[1] = 0; + } + + /* get WPS IE */ + if ((offset = zfFindWifiElement(dev, buf, 4, 0xff)) != 0xffff) + { + length = zmw_rx_buf_readb(dev, buf, offset+1); + if (length > ZM_MAX_WPS_IE_SIZE ) + { + length = ZM_MAX_WPS_IE_SIZE; + } + zfCopyFromRxBuffer(dev, buf, pBssInfo->wscIe, offset, length+2); + } + else + { + pBssInfo->wscIe[1] = 0; + } + + /* get SuperG IE */ + if ((offset = zfFindSuperGElement(dev, buf, ZM_WLAN_EID_VENDOR_PRIVATE)) != 0xffff) + { + pBssInfo->apCap |= ZM_SuperG_AP; + } + + /* get XR IE */ + if ((offset = zfFindXRElement(dev, buf, ZM_WLAN_EID_VENDOR_PRIVATE)) != 0xffff) + { + pBssInfo->apCap |= ZM_XR_AP; + } + + /* get RSN IE */ + if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_RSN_IE)) != 0xffff ) + { + length = zmw_rx_buf_readb(dev, buf, offset+1); + if (length > ZM_MAX_IE_SIZE) + { + length = ZM_MAX_IE_SIZE; + } + zfCopyFromRxBuffer(dev, buf, pBssInfo->rsnIe, offset, length+2); + pBssInfo->securityType = ZM_SECURITY_TYPE_WPA; + } + else + { + pBssInfo->rsnIe[1] = 0; + } +#ifdef ZM_ENABLE_CENC + /* get CENC IE */ + if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_CENC_IE)) != 0xffff ) + { + length = zmw_rx_buf_readb(dev, buf, offset+1); + if (length > ZM_MAX_IE_SIZE ) + { + length = ZM_MAX_IE_SIZE; + } + zfCopyFromRxBuffer(dev, buf, pBssInfo->cencIe, offset, length+2); + pBssInfo->securityType = ZM_SECURITY_TYPE_CENC; + pBssInfo->capability[0] &= 0xffef; + } + else + { + pBssInfo->cencIe[1] = 0; + } +#endif //ZM_ENABLE_CENC + /* get WME Parameter IE, probe rsp may contain WME parameter element */ + //if ( wd->bQoSEnable ) + { + if ((offset = zfFindWifiElement(dev, buf, 2, 1)) != 0xffff) + { + apQosInfo = zmw_rx_buf_readb(dev, buf, offset+8) & 0x80; + pBssInfo->wmeSupport = 1 | apQosInfo; + } + else if ((offset = zfFindWifiElement(dev, buf, 2, 0)) != 0xffff) + { + apQosInfo = zmw_rx_buf_readb(dev, buf, offset+8) & 0x80; + pBssInfo->wmeSupport = 1 | apQosInfo; + } + else + { + pBssInfo->wmeSupport = 0; + } + } + //CWYang(+) + if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY)) != 0xffff) + { + /* 11n AP */ + pBssInfo->EnableHT = 1; + if (zmw_rx_buf_readb(dev, buf, offset+1) & 0x02) + { + pBssInfo->enableHT40 = 1; + } + else + { + pBssInfo->enableHT40 = 0; + } + + if (zmw_rx_buf_readb(dev, buf, offset+1) & 0x40) + { + pBssInfo->SG40 = 1; + } + else + { + pBssInfo->SG40 = 0; + } + } + else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTCAPABILITY)) != 0xffff) + { + /* 11n AP */ + pBssInfo->EnableHT = 1; + pBssInfo->apCap |= ZM_All11N_AP; + if (zmw_rx_buf_readb(dev, buf, offset+2) & 0x02) + { + pBssInfo->enableHT40 = 1; + } + else + { + pBssInfo->enableHT40 = 0; + } + + if (zmw_rx_buf_readb(dev, buf, offset+2) & 0x40) + { + pBssInfo->SG40 = 1; + } + else + { + pBssInfo->SG40 = 0; + } + } + else + { + pBssInfo->EnableHT = 0; + } + /* HT information */ + if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY)) != 0xffff) + { + /* atheros pre n */ + pBssInfo->extChOffset = zmw_rx_buf_readb(dev, buf, offset+2) & 0x03; + } + else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTINFORMATION)) != 0xffff) + { + /* pre n 2.0 standard */ + pBssInfo->extChOffset = zmw_rx_buf_readb(dev, buf, offset+3) & 0x03; + } + else + { + pBssInfo->extChOffset = 0; + } + + if ( (pBssInfo->enableHT40 == 1) + && ((pBssInfo->extChOffset != 1) && (pBssInfo->extChOffset != 3)) ) + { + pBssInfo->enableHT40 = 0; + } + + if (pBssInfo->enableHT40 == 1) + { + if (zfHpIsAllowedChannel(dev, pBssInfo->frequency+((pBssInfo->extChOffset==1)?20:-20)) == 0) + { + /* if extension channel is not an allowed channel, treat AP as non-HT mode */ + pBssInfo->EnableHT = 0; + pBssInfo->enableHT40 = 0; + pBssInfo->extChOffset = 0; + } + } + + /* get ATH Extended Capability */ + if ( ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY)) != 0xffff)&& + ((offset = zfFindBrdcmMrvlRlnkExtCap(dev, buf)) == 0xffff)) + + { + pBssInfo->athOwlAp = 1; + } + else + { + pBssInfo->athOwlAp = 0; + } + + /* get Broadcom Extended Capability */ + if ( (pBssInfo->EnableHT == 1) //((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY)) != 0xffff) + && ((offset = zfFindBroadcomExtCap(dev, buf)) != 0xffff) ) + { + pBssInfo->broadcomHTAp = 1; + } + else + { + pBssInfo->broadcomHTAp = 0; + } + + /* get Marvel Extended Capability */ + if ((offset = zfFindMarvelExtCap(dev, buf)) != 0xffff) + { + pBssInfo->marvelAp = 1; + } + else + { + pBssInfo->marvelAp = 0; + } + + /* get ATIM window */ + if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_IBSS)) != 0xffff ) + { + pBssInfo->atimWindow = zmw_rx_buf_readh(dev, buf,offset+2); + } + + /* Fit for support mode */ + if (pBssInfo->frequency > 3000) { + if (wd->supportMode & ZM_WIRELESS_MODE_5_N) { +#if 0 + if (wd->supportMode & ZM_WIRELESS_MODE_5_54) { + /* support mode: a, n */ + /* do nothing */ + } else { + /* support mode: n */ + /* reject non-n bss info */ + if (!pBssInfo->EnableHT) { + goto zlError2; + } + } +#endif + } else { + if (wd->supportMode & ZM_WIRELESS_MODE_5_54) { + /* support mode: a */ + /* delete n mode information */ + pBssInfo->EnableHT = 0; + pBssInfo->enableHT40 = 0; + pBssInfo->apCap &= (~ZM_All11N_AP); + pBssInfo->extChOffset = 0; + pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody, + pBssInfo->frameBodysize, ZM_WLAN_EID_HT_CAPABILITY); + pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody, + pBssInfo->frameBodysize, ZM_WLAN_PREN2_EID_HTCAPABILITY); + pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody, + pBssInfo->frameBodysize, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY); + pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody, + pBssInfo->frameBodysize, ZM_WLAN_PREN2_EID_HTINFORMATION); + } else { + /* support mode: none */ + goto zlError2; + } + } + } else { + if (wd->supportMode & ZM_WIRELESS_MODE_24_N) { +#if 0 + if (wd->supportMode & ZM_WIRELESS_MODE_24_54) { + if (wd->supportMode & ZM_WIRELESS_MODE_24_11) { + /* support mode: b, g, n */ + /* do nothing */ + } else { + /* support mode: g, n */ + /* reject b-only bss info */ + if ( (!pBssInfo->EnableHT) + && (pBssInfo->extSupportedRates[1] == 0) ) { + goto zlError2; + } + } + } else { + if (wd->supportMode & ZM_WIRELESS_MODE_24_11) { + /* support mode: b, n */ + /* 1. reject g-only bss info + * 2. if non g-only, delete g mode information + */ + if ( !pBssInfo->EnableHT ) { + if ( zfIsGOnlyMode(dev, pBssInfo->frequency, pBssInfo->supportedRates) + || zfIsGOnlyMode(dev, pBssInfo->frequency, pBssInfo->extSupportedRates) ) { + goto zlError2; + } else { + zfGatherBMode(dev, pBssInfo->supportedRates, + pBssInfo->extSupportedRates); + pBssInfo->erp = 0; + + pBssInfo->frameBodysize = zfRemoveElement(dev, + pBssInfo->frameBody, pBssInfo->frameBodysize, + ZM_WLAN_EID_ERP); + pBssInfo->frameBodysize = zfRemoveElement(dev, + pBssInfo->frameBody, pBssInfo->frameBodysize, + ZM_WLAN_EID_EXTENDED_RATE); + + pBssInfo->frameBodysize = zfUpdateElement(dev, + pBssInfo->frameBody, pBssInfo->frameBodysize, + pBssInfo->supportedRates); + } + } + } else { + /* support mode: n */ + /* reject non-n bss info */ + if (!pBssInfo->EnableHT) { + goto zlError2; + } + } + } +#endif + } else { + /* delete n mode information */ + pBssInfo->EnableHT = 0; + pBssInfo->enableHT40 = 0; + pBssInfo->apCap &= (~ZM_All11N_AP); + pBssInfo->extChOffset = 0; + pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody, + pBssInfo->frameBodysize, ZM_WLAN_EID_HT_CAPABILITY); + pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody, + pBssInfo->frameBodysize, ZM_WLAN_PREN2_EID_HTCAPABILITY); + pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody, + pBssInfo->frameBodysize, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY); + pBssInfo->frameBodysize = zfRemoveElement(dev, pBssInfo->frameBody, + pBssInfo->frameBodysize, ZM_WLAN_PREN2_EID_HTINFORMATION); + + if (wd->supportMode & ZM_WIRELESS_MODE_24_54) { +#if 0 + if (wd->supportMode & ZM_WIRELESS_MODE_24_11) { + /* support mode: b, g */ + /* delete n mode information */ + } else { + /* support mode: g */ + /* delete n mode information */ + /* reject b-only bss info */ + if (pBssInfo->extSupportedRates[1] == 0) { + goto zlError2; + } + } +#endif + } else { + if (wd->supportMode & ZM_WIRELESS_MODE_24_11) { + /* support mode: b */ + /* delete n mode information */ + if ( zfIsGOnlyMode(dev, pBssInfo->frequency, pBssInfo->supportedRates) + || zfIsGOnlyMode(dev, pBssInfo->frequency, pBssInfo->extSupportedRates) ) { + goto zlError2; + } else { + zfGatherBMode(dev, pBssInfo->supportedRates, + pBssInfo->extSupportedRates); + pBssInfo->erp = 0; + + pBssInfo->frameBodysize = zfRemoveElement(dev, + pBssInfo->frameBody, pBssInfo->frameBodysize, + ZM_WLAN_EID_ERP); + pBssInfo->frameBodysize = zfRemoveElement(dev, + pBssInfo->frameBody, pBssInfo->frameBodysize, + ZM_WLAN_EID_EXTENDED_RATE); + + pBssInfo->frameBodysize = zfUpdateElement(dev, + pBssInfo->frameBody, pBssInfo->frameBodysize, + pBssInfo->supportedRates); + } + } else { + /* support mode: none */ + goto zlError2; + } + } + } + } + + pBssInfo->flag |= ZM_BSS_INFO_VALID_BIT; + +zlUpdateRssi: + /* Update Timer information */ + pBssInfo->tick = wd->tick; + + /* Update ERP information */ + if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_ERP)) != 0xffff ) + { + pBssInfo->erp = zmw_rx_buf_readb(dev, buf, offset+2); + } + + if( (s8_t)pBssInfo->signalStrength < (s8_t)AddInfo->Tail.Data.SignalStrength1 ) + { + /* Update signal strength */ + pBssInfo->signalStrength = (u8_t)AddInfo->Tail.Data.SignalStrength1; + /* Update signal quality */ + pBssInfo->signalQuality = (u8_t)(AddInfo->Tail.Data.SignalStrength1 * 2); + + /* Update the sorting value */ + pBssInfo->sortValue = zfComputeBssInfoWeightValue(dev, + (pBssInfo->supportedRates[6] + pBssInfo->extSupportedRates[0]), + pBssInfo->EnableHT, + pBssInfo->enableHT40, + pBssInfo->signalStrength); + } + + return 0; + +zlError: + + return 1; + +zlError2: + + return 2; +} + +void zfStaProcessBeacon(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* AddInfo) //CWYang(m) +{ + /* Parse TIM and send PS-POLL in power saving mode */ + struct zsWlanBeaconFrameHeader* pBeaconHeader; + struct zsBssInfo* pBssInfo; + u8_t pBuf[sizeof(struct zsWlanBeaconFrameHeader)]; + u8_t bssid[6]; + int res; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + /* sta routine jobs */ + zfStaProtErpMonitor(dev, buf); /* check protection mode */ + + if (zfStaIsConnected(dev)) + { + ZM_MAC_WORD_TO_BYTE(wd->sta.bssid, bssid); + + if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) + { + if ( zfRxBufferEqualToStr(dev, buf, bssid, ZM_WLAN_HEADER_A2_OFFSET, 6) ) + { + zfPowerSavingMgrProcessBeacon(dev, buf); + zfStaUpdateWmeParameter(dev, buf); + if (wd->sta.DFSEnable) + zfStaUpdateDot11HDFS(dev, buf); + if (wd->sta.TPCEnable) + zfStaUpdateDot11HTPC(dev, buf); + /* update signal strength and signal quality */ + zfStaSignalStatistic(dev, AddInfo->Tail.Data.SignalStrength1, + AddInfo->Tail.Data.SignalQuality); //CWYang(+) + wd->sta.rxBeaconCount++; + } + } + else if ( wd->wlanMode == ZM_MODE_IBSS ) + { + if ( zfRxBufferEqualToStr(dev, buf, bssid, ZM_WLAN_HEADER_A3_OFFSET, 6) ) + { + int res; + struct zsPartnerNotifyEvent event; + + zm_debug_msg0("20070916 Receive opposite Beacon!"); + zmw_enter_critical_section(dev); + wd->sta.ibssReceiveBeaconCount++; + zmw_leave_critical_section(dev); + + res = zfStaSetOppositeInfoFromRxBuf(dev, buf); + if ( res == 0 ) + { + // New peer station found. Notify the wrapper now + zfInitPartnerNotifyEvent(dev, buf, &event); + if (wd->zfcbIbssPartnerNotify != NULL) + { + wd->zfcbIbssPartnerNotify(dev, 1, &event); + } + } + /* update signal strength and signal quality */ + zfStaSignalStatistic(dev, AddInfo->Tail.Data.SignalStrength1, + AddInfo->Tail.Data.SignalQuality); //CWYang(+) + } + //else if ( wd->sta.ibssPartnerStatus == ZM_IBSS_PARTNER_LOST ) + // Why does this happen in IBSS?? The impact of Vista since + // we need to tell it the BSSID +#if 0 + else if ( wd->sta.oppositeCount == 0 ) + { /* IBSS merge if SSID matched */ + if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID)) != 0xffff ) + { + if ( (wd->sta.ssidLen == zmw_buf_readb(dev, buf, offset+1))&& + (zfRxBufferEqualToStr(dev, buf, wd->sta.ssid, + offset+2, wd->sta.ssidLen)) ) + { + capabilityInfo = zmw_buf_readh(dev, buf, 34); + + if ( capabilityInfo & ZM_BIT_1 ) + { + if ( (wd->sta.capability[0] & ZM_BIT_4) == + (capabilityInfo & ZM_BIT_4) ) + { + zm_debug_msg0("IBSS merge"); + zfCopyFromRxBuffer(dev, buf, bssid, + ZM_WLAN_HEADER_A3_OFFSET, 6); + zfUpdateBssid(dev, bssid); + } + } + } + } + } +#endif + } + } + + /* return if not channel scan */ + if ( !wd->sta.bChannelScan ) + { + goto zlReturn; + } + + zfCopyFromRxBuffer(dev, buf, pBuf, 0, sizeof(struct zsWlanBeaconFrameHeader)); + pBeaconHeader = (struct zsWlanBeaconFrameHeader*) pBuf; + + zmw_enter_critical_section(dev); + + //zm_debug_msg1("bss count = ", wd->sta.bssList.bssCount); + + pBssInfo = zfStaFindBssInfo(dev, buf, pBeaconHeader); + + if ( pBssInfo == NULL ) + { + /* Allocate a new entry if BSS not in the scan list */ + pBssInfo = zfBssInfoAllocate(dev); + if (pBssInfo != NULL) + { + res = zfStaInitBssInfo(dev, buf, pBeaconHeader, pBssInfo, AddInfo, 0); + //zfDumpSSID(pBssInfo->ssid[1], &(pBssInfo->ssid[2])); + if ( res != 0 ) + { + zfBssInfoFree(dev, pBssInfo); + } + else + { + zfBssInfoInsertToList(dev, pBssInfo); + } + } + } + else + { + res = zfStaInitBssInfo(dev, buf, pBeaconHeader, pBssInfo, AddInfo, 1); + if (res == 2) + { + zfBssInfoRemoveFromList(dev, pBssInfo); + zfBssInfoFree(dev, pBssInfo); + } + else if ( wd->wlanMode == ZM_MODE_IBSS ) + { + int idx; + + // It would reset the alive counter if the peer station is found! + zfStaFindFreeOpposite(dev, (u16_t *)pBssInfo->macaddr, &idx); + } + } + + zmw_leave_critical_section(dev); + +zlReturn: + + return; +} + + +void zfAuthFreqCompleteCb(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + if (wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_COMPLETED) + { + zm_debug_msg0("ZM_STA_CONN_STATE_ASSOCIATE"); + wd->sta.connectTimer = wd->tick; + wd->sta.connectState = ZM_STA_CONN_STATE_ASSOCIATE; + } + + zmw_leave_critical_section(dev); + return; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfProcessAuth */ +/* Process authenticate management frame. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : auth frame buffer */ +/* */ +/* OUTPUTS */ +/* none */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2005.10 */ +/* */ +/************************************************************************/ +/* Note : AP allows one authenticating STA at a time, does not */ +/* support multiple authentication process. Make sure */ +/* authentication state machine will not be blocked due */ +/* to incompleted authentication handshake. */ +void zfStaProcessAuth(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId) +{ + struct zsWlanAuthFrameHeader* pAuthFrame; + u8_t pBuf[sizeof(struct zsWlanAuthFrameHeader)]; + u32_t p1, p2; + + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + if ( !zfStaIsConnecting(dev) ) + { + return; + } + + pAuthFrame = (struct zsWlanAuthFrameHeader*) pBuf; + zfCopyFromRxBuffer(dev, buf, pBuf, 0, sizeof(struct zsWlanAuthFrameHeader)); + + if ( wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_OPEN ) + { + if ( (zmw_le16_to_cpu(pAuthFrame->seq) == 2)&& + (zmw_le16_to_cpu(pAuthFrame->algo) == 0)&& + (zmw_le16_to_cpu(pAuthFrame->status) == 0) ) + { + + zmw_enter_critical_section(dev); + wd->sta.connectTimer = wd->tick; + zm_debug_msg0("ZM_STA_CONN_STATE_AUTH_COMPLETED"); + wd->sta.connectState = ZM_STA_CONN_STATE_AUTH_COMPLETED; + zmw_leave_critical_section(dev); + + //Set channel according to AP's configuration + //Move to here because of Cisco 11n AP feature + zfCoreSetFrequencyEx(dev, wd->frequency, wd->BandWidth40, + wd->ExtOffset, zfAuthFreqCompleteCb); + + /* send association frame */ + if ( wd->sta.connectByReasso ) + { + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_REASOCREQ, + wd->sta.bssid, 0, 0, 0); + } + else + { + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_ASOCREQ, + wd->sta.bssid, 0, 0, 0); + } + + + } + else + { + zm_debug_msg1("authentication failed, status = ", + pAuthFrame->status); + + if (wd->sta.authMode == ZM_AUTH_MODE_AUTO) + { + wd->sta.bIsSharedKey = 1; + zfStaStartConnect(dev, wd->sta.bIsSharedKey); + } + else + { + zm_debug_msg0("ZM_STA_STATE_DISCONNECT"); + zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_AUTH_FAILED, wd->sta.bssid, 3); + } + } + } + else if ( wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_SHARE_1 ) + { + if ( (zmw_le16_to_cpu(pAuthFrame->algo) == 1) && + (zmw_le16_to_cpu(pAuthFrame->seq) == 2) && + (zmw_le16_to_cpu(pAuthFrame->status) == 0)) + //&& (pAuthFrame->challengeText[1] <= 255) ) + { + zfMemoryCopy(wd->sta.challengeText, pAuthFrame->challengeText, + pAuthFrame->challengeText[1]+2); + + /* send the 3rd authentication frame */ + p1 = 0x30001; + p2 = 0; + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_AUTH, + wd->sta.bssid, p1, p2, 0); + + zmw_enter_critical_section(dev); + wd->sta.connectTimer = wd->tick; + + zm_debug_msg0("ZM_STA_SUB_STATE_AUTH_SHARE_2"); + wd->sta.connectState = ZM_STA_CONN_STATE_AUTH_SHARE_2; + zmw_leave_critical_section(dev); + } + else + { + zm_debug_msg1("authentication failed, status = ", + pAuthFrame->status); + + zm_debug_msg0("ZM_STA_STATE_DISCONNECT"); + zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_AUTH_FAILED, wd->sta.bssid, 3); + } + } + else if ( wd->sta.connectState == ZM_STA_CONN_STATE_AUTH_SHARE_2 ) + { + if ( (zmw_le16_to_cpu(pAuthFrame->algo) == 1)&& + (zmw_le16_to_cpu(pAuthFrame->seq) == 4)&& + (zmw_le16_to_cpu(pAuthFrame->status) == 0) ) + { + //Set channel according to AP's configuration + //Move to here because of Cisco 11n AP feature + zfCoreSetFrequencyEx(dev, wd->frequency, wd->BandWidth40, + wd->ExtOffset, NULL); + + /* send association frame */ + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_ASOCREQ, + wd->sta.bssid, 0, 0, 0); + + zmw_enter_critical_section(dev); + wd->sta.connectTimer = wd->tick; + + zm_debug_msg0("ZM_STA_SUB_STATE_ASSOCIATE"); + wd->sta.connectState = ZM_STA_CONN_STATE_ASSOCIATE; + zmw_leave_critical_section(dev); + } + else + { + zm_debug_msg1("authentication failed, status = ", + pAuthFrame->status); + + zm_debug_msg0("ZM_STA_STATE_DISCONNECT"); + zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_AUTH_FAILED, wd->sta.bssid, 3); + } + } + else + { + zm_debug_msg0("unknown case"); + } +} + +void zfStaProcessAsocReq(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId) +{ + + return; +} + +void zfStaProcessAsocRsp(zdev_t* dev, zbuf_t* buf) +{ + struct zsWlanAssoFrameHeader* pAssoFrame; + u8_t pBuf[sizeof(struct zsWlanAssoFrameHeader)]; + u16_t offset; + u32_t i; + u32_t oneTxStreamCap; + + zmw_get_wlan_dev(dev); + + if ( !zfStaIsConnecting(dev) ) + { + return; + } + + pAssoFrame = (struct zsWlanAssoFrameHeader*) pBuf; + zfCopyFromRxBuffer(dev, buf, pBuf, 0, sizeof(struct zsWlanAssoFrameHeader)); + + if ( wd->sta.connectState == ZM_STA_CONN_STATE_ASSOCIATE ) + { + if ( pAssoFrame->status == 0 ) + { + zm_debug_msg0("ZM_STA_STATE_CONNECTED"); + + if (wd->sta.EnableHT == 1) + { + wd->sta.wmeConnected = 1; + } + if ((wd->sta.wmeEnabled & ZM_STA_WME_ENABLE_BIT) != 0) //WME enabled + { + /* Asoc rsp may contain WME parameter element */ + if ((offset = zfFindWifiElement(dev, buf, 2, 1)) != 0xffff) + { + zm_debug_msg0("WME enable"); + wd->sta.wmeConnected = 1; + if ((wd->sta.wmeEnabled & ZM_STA_UAPSD_ENABLE_BIT) != 0) + { + if ((zmw_rx_buf_readb(dev, buf, offset+8) & 0x80) != 0) + { + zm_debug_msg0("UAPSD enable"); + wd->sta.qosInfo = wd->sta.wmeQosInfo; + } + } + + zfStaUpdateWmeParameter(dev, buf); + } + } + + + //Store asoc response frame body, for VISTA only + wd->sta.asocRspFrameBodySize = zfwBufGetSize(dev, buf)-24; + if (wd->sta.asocRspFrameBodySize > ZM_CACHED_FRAMEBODY_SIZE) + { + wd->sta.asocRspFrameBodySize = ZM_CACHED_FRAMEBODY_SIZE; + } + for (i=0; ista.asocRspFrameBodySize; i++) + { + wd->sta.asocRspFrameBody[i] = zmw_rx_buf_readb(dev, buf, i+24); + } + + zfStaStoreAsocRspIe(dev, buf); + if (wd->sta.EnableHT && + ((wd->sta.ie.HtCap.HtCapInfo & HTCAP_SupChannelWidthSet) != 0) && + (wd->ExtOffset != 0)) + { + wd->sta.htCtrlBandwidth = 1; + } + else + { + wd->sta.htCtrlBandwidth = 0; + } + + //Set channel according to AP's configuration + //zfCoreSetFrequencyEx(dev, wd->frequency, wd->BandWidth40, + // wd->ExtOffset, NULL); + + if (wd->sta.EnableHT == 1) + { + wd->addbaComplete = 0; + + if ((wd->sta.SWEncryptEnable & ZM_SW_TKIP_ENCRY_EN) == 0 && + (wd->sta.SWEncryptEnable & ZM_SW_WEP_ENCRY_EN) == 0) + { + wd->addbaCount = 1; + zfAggSendAddbaRequest(dev, wd->sta.bssid, 0, 0); + zfTimerSchedule(dev, ZM_EVENT_TIMEOUT_ADDBA, 100); + } + } + + /* set RIFS support */ + if(wd->sta.ie.HtInfo.ChannelInfo & ExtHtCap_RIFSMode) + { + wd->sta.HT2040 = 1; +// zfHpSetRifs(dev, wd->sta.EnableHT, 1, (wd->sta.currentFrequency < 3000)? 1:0); + } + + wd->sta.aid = pAssoFrame->aid & 0x3fff; + wd->sta.oppositeCount = 0; /* reset opposite count */ + zfStaSetOppositeInfoFromRxBuf(dev, buf); + + wd->sta.rxBeaconCount = 16; + + zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTED); + wd->sta.connPowerInHalfDbm = zfHpGetTransmitPower(dev); + if (wd->zfcbConnectNotify != NULL) + { + if (wd->sta.EnableHT != 0) /* 11n */ + { + oneTxStreamCap = (zfHpCapability(dev) & ZM_HP_CAP_11N_ONE_TX_STREAM); + if (wd->sta.htCtrlBandwidth == 1) /* HT40*/ + { + if(oneTxStreamCap) /* one Tx stream */ + { + if (wd->sta.SG40) + { + wd->CurrentTxRateKbps = 150000; + wd->CurrentRxRateKbps = 300000; + } + else + { + wd->CurrentTxRateKbps = 135000; + wd->CurrentRxRateKbps = 270000; + } + } + else /* Two Tx streams */ + { + if (wd->sta.SG40) + { + wd->CurrentTxRateKbps = 300000; + wd->CurrentRxRateKbps = 300000; + } + else + { + wd->CurrentTxRateKbps = 270000; + wd->CurrentRxRateKbps = 270000; + } + } + } + else /* HT20 */ + { + if(oneTxStreamCap) /* one Tx stream */ + { + wd->CurrentTxRateKbps = 650000; + wd->CurrentRxRateKbps = 130000; + } + else /* Two Tx streams */ + { + wd->CurrentTxRateKbps = 130000; + wd->CurrentRxRateKbps = 130000; + } + } + } + else /* 11abg */ + { + if (wd->sta.connection_11b != 0) + { + wd->CurrentTxRateKbps = 11000; + wd->CurrentRxRateKbps = 11000; + } + else + { + wd->CurrentTxRateKbps = 54000; + wd->CurrentRxRateKbps = 54000; + } + } + + + wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_CONNECT, wd->sta.bssid); + } + wd->sta.connectByReasso = TRUE; + wd->sta.failCntOfReasso = 0; + + zfPowerSavingMgrConnectNotify(dev); + + /* Disable here because fixed rate is only for test, TBD. */ + //if (wd->sta.EnableHT) + //{ + // wd->txMCS = 7; //Rate = 65Mbps + // wd->txMT = 2; // Ht rate + // wd->enableAggregation = 2; // Enable Aggregation + //} + } + else + { + zm_debug_msg1("association failed, status = ", + pAssoFrame->status); + + zm_debug_msg0("ZM_STA_STATE_DISCONNECT"); + wd->sta.connectByReasso = FALSE; + zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_ASOC_FAILED, wd->sta.bssid, 3); + } + } + +} + +void zfStaStoreAsocRspIe(zdev_t* dev, zbuf_t* buf) +{ + u16_t offset; + u32_t i; + u16_t length; + u8_t *htcap; + u8_t asocBw40 = 0; + u8_t asocExtOffset = 0; + + zmw_get_wlan_dev(dev); + + for (i=0; ista.asocRspFrameBodySize; i++) + { + wd->sta.asocRspFrameBody[i] = zmw_rx_buf_readb(dev, buf, i+24); + } + + /* HT capabilities: 28 octets */ + if ( ((wd->sta.currentFrequency > 3000) && !(wd->supportMode & ZM_WIRELESS_MODE_5_N)) + || ((wd->sta.currentFrequency < 3000) && !(wd->supportMode & ZM_WIRELESS_MODE_24_N)) ) + { + /* not 11n AP */ + htcap = (u8_t *)&wd->sta.ie.HtCap; + for (i=0; i<28; i++) + { + htcap[i] = 0; + } + wd->BandWidth40 = 0; + wd->ExtOffset = 0; + return; + } + + if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY)) != 0xffff) + { + /* atheros pre n */ + zm_debug_msg0("atheros pre n"); + htcap = (u8_t *)&wd->sta.ie.HtCap; + htcap[0] = zmw_rx_buf_readb(dev, buf, offset); + htcap[1] = 26; + for (i=1; i<=26; i++) + { + htcap[i+1] = zmw_rx_buf_readb(dev, buf, offset + i); + zm_msg2_mm(ZM_LV_1, "ASOC: HT Capabilities, htcap=", htcap[i+1]); + } + } + else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTCAPABILITY)) != 0xffff) + { + /* pre n 2.0 standard */ + zm_debug_msg0("pre n 2.0 standard"); + htcap = (u8_t *)&wd->sta.ie.HtCap; + for (i=0; i<28; i++) + { + htcap[i] = zmw_rx_buf_readb(dev, buf, offset + i); + zm_msg2_mm(ZM_LV_1, "ASOC: HT Capabilities, htcap=", htcap[i]); + } + } + else + { + /* not 11n AP */ + htcap = (u8_t *)&wd->sta.ie.HtCap; + for (i=0; i<28; i++) + { + htcap[i] = 0; + } + wd->BandWidth40 = 0; + wd->ExtOffset = 0; + return; + } + + asocBw40 = (u8_t)((wd->sta.ie.HtCap.HtCapInfo & HTCAP_SupChannelWidthSet) >> 1); + + /* HT information */ + if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_HT_CAPABILITY)) != 0xffff) + { + /* atheros pre n */ + zm_debug_msg0("atheros pre n HTINFO"); + length = 22; + htcap = (u8_t *)&wd->sta.ie.HtInfo; + htcap[0] = zmw_rx_buf_readb(dev, buf, offset); + htcap[1] = 22; + for (i=1; i<=22; i++) + { + htcap[i+1] = zmw_rx_buf_readb(dev, buf, offset + i); + zm_msg2_mm(ZM_LV_1, "ASOC: HT Info, htinfo=", htcap[i+1]); + } + } + else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTINFORMATION)) != 0xffff) + { + /* pre n 2.0 standard */ + zm_debug_msg0("pre n 2.0 standard HTINFO"); + length = zmw_rx_buf_readb(dev, buf, offset + 1); + htcap = (u8_t *)&wd->sta.ie.HtInfo; + for (i=0; i<24; i++) + { + htcap[i] = zmw_rx_buf_readb(dev, buf, offset + i); + zm_msg2_mm(ZM_LV_1, "ASOC: HT Info, htinfo=", htcap[i]); + } + } + else + { + zm_debug_msg0("no HTINFO"); + htcap = (u8_t *)&wd->sta.ie.HtInfo; + for (i=0; i<24; i++) + { + htcap[i] = 0; + } + } + asocExtOffset = wd->sta.ie.HtInfo.ChannelInfo & ExtHtCap_ExtChannelOffsetBelow; + + if ((wd->sta.EnableHT == 1) && (asocBw40 == 1) && ((asocExtOffset == 1) || (asocExtOffset == 3))) + { + wd->BandWidth40 = asocBw40; + wd->ExtOffset = asocExtOffset; + } + else + { + wd->BandWidth40 = 0; + wd->ExtOffset = 0; + } + + return; +} + +void zfStaProcessDeauth(zdev_t* dev, zbuf_t* buf) +{ + u16_t apMacAddr[3]; + + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + /* STA : if SA=connected AP then disconnect with AP */ + if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) + { + apMacAddr[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET); + apMacAddr[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+2); + apMacAddr[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+4); + if ((apMacAddr[0] == wd->sta.bssid[0]) && (apMacAddr[1] == wd->sta.bssid[1]) && (apMacAddr[2] == wd->sta.bssid[2])) + { + if (zfwBufGetSize(dev, buf) >= 24+2) //not a malformed frame + { + if ( zfStaIsConnected(dev) ) + { + zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_DEAUTH, wd->sta.bssid, 2); + } + else if (zfStaIsConnecting(dev)) + { + zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_AUTH_FAILED, wd->sta.bssid, 3); + } + else + { + } + } + } + } + else if ( wd->wlanMode == ZM_MODE_IBSS ) + { + u16_t peerMacAddr[3]; + u8_t peerIdx; + s8_t res; + + if ( zfStaIsConnected(dev) ) + { + peerMacAddr[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET); + peerMacAddr[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+2); + peerMacAddr[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+4); + + zmw_enter_critical_section(dev); + res = zfStaFindOppositeByMACAddr(dev, peerMacAddr, &peerIdx); + if ( res == 0 ) + { + wd->sta.oppositeInfo[peerIdx].aliveCounter = 0; + } + zmw_leave_critical_section(dev); + } + } +} + +void zfStaProcessDisasoc(zdev_t* dev, zbuf_t* buf) +{ + u16_t apMacAddr[3]; + + zmw_get_wlan_dev(dev); + + /* STA : if SA=connected AP then disconnect with AP */ + if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) + { + apMacAddr[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET); + apMacAddr[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+2); + apMacAddr[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+4); + + if ((apMacAddr[0] == wd->sta.bssid[0]) && (apMacAddr[1] == wd->sta.bssid[1]) && (apMacAddr[2] == wd->sta.bssid[2])) + { + if (zfwBufGetSize(dev, buf) >= 24+2) //not a malformed frame + { + if ( zfStaIsConnected(dev) ) + { + zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_DISASOC, wd->sta.bssid, 2); + } + else + { + zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_ASOC_FAILED, wd->sta.bssid, 3); + } + } + } + } +} + + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfProcessProbeReq */ +/* Process probe request management frame. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : auth frame buffer */ +/* */ +/* OUTPUTS */ +/* none */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2005.10 */ +/* */ +/************************************************************************/ +void zfStaProcessProbeReq(zdev_t* dev, zbuf_t* buf, u16_t* src) +{ + u16_t offset; + u8_t len; + u16_t i, j; + u16_t sendFlag; + + zmw_get_wlan_dev(dev); + + /* check mode : AP/IBSS */ + if ((wd->wlanMode != ZM_MODE_AP) || (wd->wlanMode != ZM_MODE_IBSS)) + { + zm_msg0_mm(ZM_LV_3, "Ignore probe req"); + return; + } + + /* check SSID */ + if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID)) == 0xffff) + { + zm_msg0_mm(ZM_LV_3, "probe req SSID not found"); + return; + } + + len = zmw_rx_buf_readb(dev, buf, offset+1); + + for (i=0; iap.apBitmap & (i<ap.hideSsid[i] == 0)) + { + sendFlag = 1; + } + /* Not broadcast SSID */ + else if (wd->ap.ssidLen[i] == len) + { + for (j=0; jap.ssid[i][j]) + { + break; + } + } + if (j == len) + { + sendFlag = 1; + } + } + if (sendFlag == 1) + { + /* Send probe response */ + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_PROBERSP, src, i, 0, 0); + } + } + } +} + +void zfStaProcessProbeRsp(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* AddInfo) +{ + /* return if not channel scan */ + // Probe response is sent with unicast. Is this required? + // IBSS would send probe request and the code below would prevent + // the probe response from handling. + #if 0 + zmw_get_wlan_dev(dev); + + if ( !wd->sta.bChannelScan ) + { + return; + } + #endif + + zfProcessProbeRsp(dev, buf, AddInfo); +} + +void zfIBSSSetupBssDesc(zdev_t *dev) +{ +#ifdef ZM_ENABLE_IBSS_WPA2PSK + u8_t i; +#endif + struct zsBssInfo *pBssInfo; + u16_t offset = 0; + + zmw_get_wlan_dev(dev); + + pBssInfo = &wd->sta.ibssBssDesc; + zfZeroMemory((u8_t *)pBssInfo, sizeof(struct zsBssInfo)); + + pBssInfo->signalStrength = 100; + + zfMemoryCopy((u8_t *)pBssInfo->macaddr, (u8_t *)wd->macAddr,6); + zfMemoryCopy((u8_t *)pBssInfo->bssid, (u8_t *)wd->sta.bssid, 6); + + pBssInfo->beaconInterval[0] = (u8_t)(wd->beaconInterval) ; + pBssInfo->beaconInterval[1] = (u8_t)((wd->beaconInterval) >> 8) ; + + pBssInfo->capability[0] = wd->sta.capability[0]; + pBssInfo->capability[1] = wd->sta.capability[1]; + + pBssInfo->ssid[0] = ZM_WLAN_EID_SSID; + pBssInfo->ssid[1] = wd->sta.ssidLen; + zfMemoryCopy((u8_t *)&pBssInfo->ssid[2], (u8_t *)wd->sta.ssid, wd->sta.ssidLen); + zfMemoryCopy((u8_t *)&pBssInfo->frameBody[offset], (u8_t *)pBssInfo->ssid, + wd->sta.ssidLen + 2); + offset += wd->sta.ssidLen + 2; + + /* support rate */ + + /* DS parameter set */ + pBssInfo->channel = zfChFreqToNum(wd->frequency, NULL); + pBssInfo->frequency = wd->frequency; + pBssInfo->atimWindow = wd->sta.atimWindow; + +#ifdef ZM_ENABLE_IBSS_WPA2PSK + if ( wd->sta.authMode == ZM_AUTH_MODE_WPA2PSK ) + { + u8_t rsn[64]= + { + /* Element ID */ + 0x30, + /* Length */ + 0x14, + /* Version */ + 0x01, 0x00, + /* Group Cipher Suite, default=TKIP */ + 0x00, 0x0f, 0xac, 0x04, + /* Pairwise Cipher Suite Count */ + 0x01, 0x00, + /* Pairwise Cipher Suite, default=TKIP */ + 0x00, 0x0f, 0xac, 0x02, + /* Authentication and Key Management Suite Count */ + 0x01, 0x00, + /* Authentication type, default=PSK */ + 0x00, 0x0f, 0xac, 0x02, + /* RSN capability */ + 0x00, 0x00 + }; + + /* Overwrite Group Cipher Suite by AP's setting */ + zfMemoryCopy(rsn+4, zgWpa2AesOui, 4); + + if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES ) + { + /* Overwrite Pairwise Cipher Suite by AES */ + zfMemoryCopy(rsn+10, zgWpa2AesOui, 4); + } + + // RSN element id + pBssInfo->frameBody[offset++] = ZM_WLAN_EID_RSN_IE ; + + // RSN length + pBssInfo->frameBody[offset++] = rsn[1] ; + + // RSN information + for(i=0; iframeBody[offset++] = rsn[i+2] ; + } + + zfMemoryCopy(pBssInfo->rsnIe, rsn, rsn[1]+2); + } +#endif +} + +void zfIbssConnectNetwork(zdev_t* dev) +{ + struct zsBssInfo* pBssInfo; + struct zsBssInfo tmpBssInfo; + u8_t macAddr[6], bssid[6], bssNotFound = TRUE; + u16_t i, j=100; + u16_t k; + struct zsPartnerNotifyEvent event; + u32_t channelFlags; + u16_t oppositeWepStatus; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + /* change state to CONNECTING and stop the channel scanning */ + zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTING); + zfPowerSavingMgrWakeup(dev); + + /* Set TxQs CWMIN, CWMAX, AIFS and TXO to WME STA default. */ + zfUpdateDefaultQosParameter(dev, 0); + + wd->sta.bProtectionMode = FALSE; + zfHpSetSlotTime(dev, 1); + + /* ESS bit off */ + wd->sta.capability[0] &= ~ZM_BIT_0; + /* IBSS bit on */ + wd->sta.capability[0] |= ZM_BIT_1; + /* not not use short slot time */ + wd->sta.capability[1] &= ~ZM_BIT_2; + + wd->sta.wmeConnected = 0; + wd->sta.psMgr.tempWakeUp = 0; + wd->sta.qosInfo = 0; + wd->sta.EnableHT = 0; + wd->BandWidth40 = 0; + wd->ExtOffset = 0; + + if ( wd->sta.bssList.bssCount ) + { + //Reorder BssList by RSSI--CWYang(+) + zfBssInfoReorderList(dev); + + zmw_enter_critical_section(dev); + + pBssInfo = wd->sta.bssList.head; + + for(i=0; ista.bssList.bssCount; i++) + { + // 20070806 #1 Privacy bit + if ( pBssInfo->capability[0] & ZM_BIT_4 ) + { // Privacy Ibss network +// zm_debug_msg0("Privacy bit on"); + oppositeWepStatus = ZM_ENCRYPTION_WEP_ENABLED; + + if ( pBssInfo->rsnIe[1] != 0 ) + { + if ( (pBssInfo->rsnIe[7] == 0x01) || (pBssInfo->rsnIe[7] == 0x05) ) + { // WEP-40 & WEP-104 +// zm_debug_msg0("WEP40 or WEP104"); + oppositeWepStatus = ZM_ENCRYPTION_WEP_ENABLED; + } + else if ( pBssInfo->rsnIe[7] == 0x02 ) + { // TKIP +// zm_debug_msg0("TKIP"); + oppositeWepStatus = ZM_ENCRYPTION_TKIP; + } + else if ( pBssInfo->rsnIe[7] == 0x04 ) + { // AES +// zm_debug_msg0("CCMP-AES"); + oppositeWepStatus = ZM_ENCRYPTION_AES; + } + } + } + else + { +// zm_debug_msg0("Privacy bit off"); + oppositeWepStatus = ZM_ENCRYPTION_WEP_DISABLED; + } + + if ( (zfMemoryIsEqual(&(pBssInfo->ssid[2]), wd->sta.ssid, + wd->sta.ssidLen))&& + (wd->sta.ssidLen == pBssInfo->ssid[1])&& + (oppositeWepStatus == wd->sta.wepStatus) ) + { + /* Check support mode */ + if (pBssInfo->frequency > 3000) { + if ( (pBssInfo->EnableHT == 1) + || (pBssInfo->apCap & ZM_All11N_AP) ) //11n AP + { + channelFlags = CHANNEL_A_HT; + if (pBssInfo->enableHT40 == 1) { + channelFlags |= CHANNEL_HT40; + } + } else { + channelFlags = CHANNEL_A; + } + } else { + if ( (pBssInfo->EnableHT == 1) + || (pBssInfo->apCap & ZM_All11N_AP) ) //11n AP + { + channelFlags = CHANNEL_G_HT; + if(pBssInfo->enableHT40 == 1) { + channelFlags |= CHANNEL_HT40; + } + } else { + if (pBssInfo->extSupportedRates[1] == 0) { + channelFlags = CHANNEL_B; + } else { + channelFlags = CHANNEL_G; + } + } + } + + if ( ((channelFlags == CHANNEL_B) && (wd->connectMode & ZM_BIT_0)) + || ((channelFlags == CHANNEL_G) && (wd->connectMode & ZM_BIT_1)) + || ((channelFlags == CHANNEL_A) && (wd->connectMode & ZM_BIT_2)) + || ((channelFlags & CHANNEL_HT20) && (wd->connectMode & ZM_BIT_3)) ) + { + pBssInfo = pBssInfo->next; + continue; + } + + /* Bypass DFS channel */ + if (zfHpIsDfsChannelNCS(dev, pBssInfo->frequency)) + { + zm_debug_msg0("Bypass DFS channel"); + continue; + } + + /* check IBSS bit */ + if ( pBssInfo->capability[0] & ZM_BIT_1 ) + { + /* may check timestamp here */ + j = i; + break; + } + } + + pBssInfo = pBssInfo->next; + } + + if ((j < wd->sta.bssList.bssCount) && (pBssInfo != NULL)) + { + zfwMemoryCopy((u8_t*)&tmpBssInfo, (u8_t*)(pBssInfo), sizeof(struct zsBssInfo)); + pBssInfo = &tmpBssInfo; + } + else + { + pBssInfo = NULL; + } + + zmw_leave_critical_section(dev); + + //if ( j < wd->sta.bssList.bssCount ) + if (pBssInfo != NULL) + { + int res; + + zm_debug_msg0("IBSS found"); + + /* Found IBSS, reset bssNotFoundCount */ + zmw_enter_critical_section(dev); + wd->sta.bssNotFoundCount = 0; + zmw_leave_critical_section(dev); + + bssNotFound = FALSE; + wd->sta.atimWindow = pBssInfo->atimWindow; + wd->frequency = pBssInfo->frequency; + //wd->sta.flagFreqChanging = 1; + zfCoreSetFrequency(dev, wd->frequency); + zfUpdateBssid(dev, pBssInfo->bssid); + zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_ZERO); + zfUpdateSupportRate(dev, pBssInfo->supportedRates); + zfUpdateSupportRate(dev, pBssInfo->extSupportedRates); + wd->beaconInterval = pBssInfo->beaconInterval[0] + + (((u16_t) pBssInfo->beaconInterval[1]) << 8); + + if (wd->beaconInterval == 0) + { + wd->beaconInterval = 100; + } + + /* rsn information element */ + if ( pBssInfo->rsnIe[1] != 0 ) + { + zfMemoryCopy(wd->sta.rsnIe, pBssInfo->rsnIe, + pBssInfo->rsnIe[1]+2); + +#ifdef ZM_ENABLE_IBSS_WPA2PSK + /* If not use RSNA , run traditional */ + zmw_enter_critical_section(dev); + wd->sta.ibssWpa2Psk = 1; + zmw_leave_critical_section(dev); +#endif + } + else + { + wd->sta.rsnIe[1] = 0; + } + + /* privacy bit */ + if ( pBssInfo->capability[0] & ZM_BIT_4 ) + { + wd->sta.capability[0] |= ZM_BIT_4; + } + else + { + wd->sta.capability[0] &= ~ZM_BIT_4; + } + + /* preamble type */ + wd->preambleTypeInUsed = wd->preambleType; + if ( wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_AUTO ) + { + if (pBssInfo->capability[0] & ZM_BIT_5) + { + wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_SHORT; + } + else + { + wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_LONG; + } + } + + if (wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_LONG) + { + wd->sta.capability[0] &= ~ZM_BIT_5; + } + else + { + wd->sta.capability[0] |= ZM_BIT_5; + } + + wd->sta.beaconFrameBodySize = pBssInfo->frameBodysize + 12; + + if (wd->sta.beaconFrameBodySize > ZM_CACHED_FRAMEBODY_SIZE) + { + wd->sta.beaconFrameBodySize = ZM_CACHED_FRAMEBODY_SIZE; + } + + for (k=0; k<8; k++) + { + wd->sta.beaconFrameBody[k] = pBssInfo->timeStamp[k]; + } + wd->sta.beaconFrameBody[8] = pBssInfo->beaconInterval[0]; + wd->sta.beaconFrameBody[9] = pBssInfo->beaconInterval[1]; + wd->sta.beaconFrameBody[10] = pBssInfo->capability[0]; + wd->sta.beaconFrameBody[11] = pBssInfo->capability[1]; + //for (k=12; ksta.beaconFrameBodySize; k++) + for (k=0; kframeBodysize; k++) + { + wd->sta.beaconFrameBody[k+12] = pBssInfo->frameBody[k]; + } + + zmw_enter_critical_section(dev); + res = zfStaSetOppositeInfoFromBSSInfo(dev, pBssInfo); + if ( res == 0 ) + { + zfMemoryCopy(event.bssid, (u8_t *)(pBssInfo->bssid), 6); + zfMemoryCopy(event.peerMacAddr, (u8_t *)(pBssInfo->macaddr), 6); + } + zmw_leave_critical_section(dev); + + //zfwIbssPartnerNotify(dev, 1, &event); + goto connect_done; + } + } + + /* IBSS not found */ + if ( bssNotFound ) + { +#ifdef ZM_ENABLE_IBSS_WPA2PSK + u16_t offset ; +#endif + if ( wd->sta.ibssJoinOnly ) + { + zm_debug_msg0("IBSS join only...retry..."); + goto retry_ibss; + } + + if(wd->sta.bssNotFoundCount<2) + { + zmw_enter_critical_section(dev); + zm_debug_msg1("IBSS not found, do sitesurvey!! bssNotFoundCount=", wd->sta.bssNotFoundCount); + wd->sta.bssNotFoundCount++; + zmw_leave_critical_section(dev); + goto retry_ibss; + } + else + { + zmw_enter_critical_section(dev); + /* Fail IBSS found, TODO create IBSS */ + wd->sta.bssNotFoundCount = 0; + zmw_leave_critical_section(dev); + } + + + if (zfHpIsDfsChannel(dev, wd->frequency)) + { + wd->frequency = zfHpFindFirstNonDfsChannel(dev, wd->frequency > 3000); + } + + if( wd->ws.autoSetFrequency == 0 ) + { /* Auto set frequency */ + zm_debug_msg1("Create Ad Hoc Network Band ", wd->ws.adhocMode); + wd->frequency = zfFindCleanFrequency(dev, wd->ws.adhocMode); + wd->ws.autoSetFrequency = 0xff; + } + zm_debug_msg1("IBSS not found, created one in channel ", wd->frequency); + + wd->sta.ibssBssIsCreator = 1; + + //wd->sta.flagFreqChanging = 1; + zfCoreSetFrequency(dev, wd->frequency); + if (wd->sta.bDesiredBssid == TRUE) + { + for (k=0; k<6; k++) + { + bssid[k] = wd->sta.desiredBssid[k]; + } + } + else + { + #if 1 + macAddr[0] = (wd->macAddr[0] & 0xff); + macAddr[1] = (wd->macAddr[0] >> 8); + macAddr[2] = (wd->macAddr[1] & 0xff); + macAddr[3] = (wd->macAddr[1] >> 8); + macAddr[4] = (wd->macAddr[2] & 0xff); + macAddr[5] = (wd->macAddr[2] >> 8); + zfGenerateRandomBSSID(dev, (u8_t *)wd->macAddr, (u8_t *)bssid); + #else + for (k=0; k<6; k++) + { + bssid[k] = (u8_t) zfGetRandomNumber(dev, 0); + } + bssid[0] &= ~ZM_BIT_0; + bssid[0] |= ZM_BIT_1; + #endif + } + + zfUpdateBssid(dev, bssid); + //wd->sta.atimWindow = 0x0a; + + /* rate information */ + if(wd->frequency <= ZM_CH_G_14) // 2.4 GHz b+g + { + if ( wd->wfc.bIbssGMode + && (wd->supportMode & (ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N)) ) + { + zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_IBSS_AG); + } + else + { + zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_IBSS_B); + } + } else { + zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_IBSS_AG); + } + + if ( wd->sta.wepStatus == ZM_ENCRYPTION_WEP_DISABLED ) + { + wd->sta.capability[0] &= ~ZM_BIT_4; + } + else + { + wd->sta.capability[0] |= ZM_BIT_4; + } + + wd->preambleTypeInUsed = wd->preambleType; + if (wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_LONG) + { + wd->sta.capability[0] &= ~ZM_BIT_5; + } + else + { + wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_SHORT; + wd->sta.capability[0] |= ZM_BIT_5; + } + + zfIBSSSetupBssDesc(dev); + +#ifdef ZM_ENABLE_IBSS_WPA2PSK + + // 20070411 Add WPA2PSK information to its IBSS network !!! + offset = 0 ; + + /* timestamp */ + offset += 8 ; + + /* beacon interval */ + wd->sta.beaconFrameBody[offset++] = (u8_t)(wd->beaconInterval) ; + wd->sta.beaconFrameBody[offset++] = (u8_t)((wd->beaconInterval) >> 8) ; + + /* capability information */ + wd->sta.beaconFrameBody[offset++] = wd->sta.capability[0] ; + wd->sta.beaconFrameBody[offset++] = wd->sta.capability[1] ; + #if 0 + /* ssid */ + // ssid element id + wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_SSID ; + // ssid length + wd->sta.beaconFrameBody[offset++] = wd->sta.ssidLen ; + // ssid information + for(i=0; ista.ssidLen; i++) + { + wd->sta.beaconFrameBody[offset++] = wd->sta.ssid[i] ; + } + + /* support rate */ + rateSet = ZM_RATE_SET_CCK ; + if ( (rateSet == ZM_RATE_SET_OFDM)&&((wd->gRate & 0xff) == 0) ) + { + offset += 0 ; + } + else + { + // support rate element id + wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_SUPPORT_RATE ; + + // support rate length + lenOffset = offset++; + + // support rate information + for (i=0; i<4; i++) + { + if ((wd->bRate & (0x1<sta.beaconFrameBody[offset++] = + zg11bRateTbl[i]+((wd->bRateBasic & (0x1<sta.beaconFrameBody[lenOffset] = len ; + } + + /* DS parameter set */ + // DS parameter set elemet id + wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_DS ; + + // DS parameter set length + wd->sta.beaconFrameBody[offset++] = 1 ; + + // DS parameter set information + wd->sta.beaconFrameBody[offset++] = + zfChFreqToNum(wd->frequency, NULL) ; + + /* IBSS parameter set */ + // IBSS parameter set element id + wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_IBSS ; + + // IBSS parameter set length + wd->sta.beaconFrameBody[offset++] = 2 ; + + // IBSS parameter set information + wd->sta.beaconFrameBody[offset] = wd->sta.atimWindow ; + offset += 2 ; + + /* ERP Information and Extended Supported Rates */ + if ( wd->wfc.bIbssGMode + && (wd->supportMode & (ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N)) ) + { + /* ERP Information */ + wd->erpElement = 0; + // ERP element id + wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_ERP ; + + // ERP length + wd->sta.beaconFrameBody[offset++] = 1 ; + + // ERP information + wd->sta.beaconFrameBody[offset++] = wd->erpElement ; + + /* Extended Supported Rates */ + if ( (rateSet == ZM_RATE_SET_OFDM)&&((wd->gRate & 0xff) == 0) ) + { + offset += 0 ; + } + else + { + len = 0 ; + + // Extended Supported Rates element id + wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_EXTENDED_RATE ; + + // Extended Supported Rates length + lenOffset = offset++ ; + + // Extended Supported Rates information + for (i=0; i<8; i++) + { + if ((wd->gRate & (0x1<sta.beaconFrameBody[offset++] = + zg11gRateTbl[i]+((wd->gRateBasic & (0x1<sta.beaconFrameBody[lenOffset] = len ; + } + } + #endif + + /* RSN : important information influence the result of creating an IBSS network */ + if ( wd->sta.authMode == ZM_AUTH_MODE_WPA2PSK ) + { + u8_t frameType = ZM_WLAN_FRAME_TYPE_AUTH ; + u8_t rsn[64]= + { + /* Element ID */ + 0x30, + /* Length */ + 0x14, + /* Version */ + 0x01, 0x00, + /* Group Cipher Suite, default=TKIP */ + 0x00, 0x0f, 0xac, 0x04, + /* Pairwise Cipher Suite Count */ + 0x01, 0x00, + /* Pairwise Cipher Suite, default=TKIP */ + 0x00, 0x0f, 0xac, 0x02, + /* Authentication and Key Management Suite Count */ + 0x01, 0x00, + /* Authentication type, default=PSK */ + 0x00, 0x0f, 0xac, 0x02, + /* RSN capability */ + 0x00, 0x00 + }; + + /* Overwrite Group Cipher Suite by AP's setting */ + zfMemoryCopy(rsn+4, zgWpa2AesOui, 4); + + if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES ) + { + /* Overwrite Pairwise Cipher Suite by AES */ + zfMemoryCopy(rsn+10, zgWpa2AesOui, 4); + } + + // RSN element id + wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_RSN_IE ; + + // RSN length + wd->sta.beaconFrameBody[offset++] = rsn[1] ; + + // RSN information + for(i=0; ista.beaconFrameBody[offset++] = rsn[i+2] ; + + zfMemoryCopy(wd->sta.rsnIe, rsn, rsn[1]+2); + +#ifdef ZM_ENABLE_IBSS_WPA2PSK + /* If not use RSNA , run traditional */ + zmw_enter_critical_section(dev); + wd->sta.ibssWpa2Psk = 1; + zmw_leave_critical_section(dev); +#endif + } + + #if 0 + /* HT Capabilities Info */ + { + u8_t OUI[3] = { 0x0 , 0x90 , 0x4C } ; + + wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_WPA_IE ; + + wd->sta.beaconFrameBody[offset++] = wd->sta.HTCap.Data.Length + 4 ; + + for (i = 0; i < 3; i++) + { + wd->sta.beaconFrameBody[offset++] = OUI[i] ; + } + + wd->sta.beaconFrameBody[offset++] = wd->sta.HTCap.Data.ElementID ; + + for (i = 0; i < 26; i++) + { + wd->sta.beaconFrameBody[offset++] = wd->sta.HTCap.Byte[i+2] ; + } + } + + /* Extended HT Capabilities Info */ + { + u8_t OUI[3] = { 0x0 , 0x90 , 0x4C } ; + + wd->sta.beaconFrameBody[offset++] = ZM_WLAN_EID_WPA_IE ; + + wd->sta.beaconFrameBody[offset++] = wd->sta.ExtHTCap.Data.Length + 4 ; + + for (i = 0; i < 3; i++) + { + wd->sta.beaconFrameBody[offset++] = OUI[i] ; + } + + wd->sta.beaconFrameBody[offset++] = wd->sta.ExtHTCap.Data.ElementID ; + + for (i = 0; i < 22; i++) + { + wd->sta.beaconFrameBody[offset++] = wd->sta.ExtHTCap.Byte[i+2] ; + } + } + #endif + + wd->sta.beaconFrameBodySize = offset ; + + if (wd->sta.beaconFrameBodySize > ZM_CACHED_FRAMEBODY_SIZE) + { + wd->sta.beaconFrameBodySize = ZM_CACHED_FRAMEBODY_SIZE; + } + + // 20070416 Let Create IBSS network could enter the zfwIbssPartnerNotify function + // bssNotFound = FALSE ; + + printk("The capability info 1 = %02x\n", wd->sta.capability[0]) ; + printk("The capability info 2 = %02x\n", wd->sta.capability[1]) ; + for(k=0; ksta.beaconFrameBodySize; k++) + { + printk("%02x ", wd->sta.beaconFrameBody[k]) ; + } + #if 0 + zmw_enter_critical_section(dev); + zfMemoryCopy(event.bssid, (u8_t *)bssid, 6); + zfMemoryCopy(event.peerMacAddr, (u8_t *)wd->macAddr, 6); + zmw_leave_critical_section(dev); + #endif +#endif + + //zmw_enter_critical_section(dev); + //wd->sta.ibssPartnerStatus = ZM_IBSS_PARTNER_LOST; + //zmw_leave_critical_section(dev); + } + else + { + wd->sta.ibssBssIsCreator = 0; + } + +connect_done: + zfHpEnableBeacon(dev, ZM_MODE_IBSS, wd->beaconInterval, wd->dtim, (u8_t)wd->sta.atimWindow); + zfStaSendBeacon(dev); // Refresh Beacon content for ZD1211B HalPlus + zfHpSetAtimWindow(dev, wd->sta.atimWindow); + + // Start the IBSS timer to monitor for new stations + zmw_enter_critical_section(dev); + zfTimerSchedule(dev, ZM_EVENT_IBSS_MONITOR, ZM_TICK_IBSS_MONITOR); + zmw_leave_critical_section(dev); + + + if (wd->zfcbConnectNotify != NULL) + { + wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_CONNECT, wd->sta.bssid); + } + zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTED); + wd->sta.connPowerInHalfDbm = zfHpGetTransmitPower(dev); + +#ifdef ZM_ENABLE_IBSS_DELAYED_JOIN_INDICATION + if ( !bssNotFound ) + { + wd->sta.ibssDelayedInd = 1; + zfMemoryCopy((u8_t *)&wd->sta.ibssDelayedIndEvent, (u8_t *)&event, sizeof(struct zsPartnerNotifyEvent)); + } +#else + if ( !bssNotFound ) + { + if (wd->zfcbIbssPartnerNotify != NULL) + { + wd->zfcbIbssPartnerNotify(dev, 1, &event); + } + } +#endif + + return; + +retry_ibss: + zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTING); + zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_NOT_FOUND, wd->sta.bssid, 0); + return; +} + +void zfStaProcessAtim(zdev_t* dev, zbuf_t* buf) +{ + zmw_get_wlan_dev(dev); + + zm_debug_msg0("Receiving Atim window notification"); + + wd->sta.recvAtim = 1; +} + +static struct zsBssInfo* zfInfraFindAPToConnect(zdev_t* dev, + struct zsBssInfo* candidateBss) +{ + struct zsBssInfo* pBssInfo; + struct zsBssInfo* pNowBssInfo=NULL; + u16_t i; + u16_t ret, apWepStatus; + u32_t k; + u32_t channelFlags; + + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + pBssInfo = wd->sta.bssList.head; + + for(i=0; ista.bssList.bssCount; i++) + { + if ( pBssInfo->capability[0] & ZM_BIT_4 ) + { + apWepStatus = ZM_ENCRYPTION_WEP_ENABLED; + } + else + { + apWepStatus = ZM_ENCRYPTION_WEP_DISABLED; + } + + if ( ((zfMemoryIsEqual(&(pBssInfo->ssid[2]), wd->sta.ssid, + wd->sta.ssidLen))&& + (wd->sta.ssidLen == pBssInfo->ssid[1]))|| + ((wd->sta.ssidLen == 0)&& + /* connect to any BSS: AP's ans STA's WEP status must match */ + (wd->sta.wepStatus == apWepStatus )&& + (pBssInfo->securityType != ZM_SECURITY_TYPE_WPA) )) + { + if ( wd->sta.ssidLen == 0 ) + { + zm_debug_msg0("ANY BSS found"); + } + + if ( ((wd->sta.wepStatus == ZM_ENCRYPTION_WEP_DISABLED && apWepStatus == ZM_ENCRYPTION_WEP_ENABLED) || + (wd->sta.wepStatus == ZM_ENCRYPTION_WEP_ENABLED && + (apWepStatus == ZM_ENCRYPTION_WEP_DISABLED && wd->sta.dropUnencryptedPkts == 1))) && + (wd->sta.authMode >= ZM_AUTH_MODE_OPEN && wd->sta.authMode <= ZM_AUTH_MODE_AUTO) ) + { + zm_debug_msg0("Privacy policy is inconsistent"); + pBssInfo = pBssInfo->next; + continue; + } + + /* for WPA negative test */ + if ( !zfCheckAuthentication(dev, pBssInfo) ) + { + pBssInfo = pBssInfo->next; + continue; + } + + /* Check bssid */ + if (wd->sta.bDesiredBssid == TRUE) + { + for (k=0; k<6; k++) + { + if (wd->sta.desiredBssid[k] != pBssInfo->bssid[k]) + { + zm_msg0_mm(ZM_LV_1, "desired bssid not matched 1"); + break; + } + } + + if (k != 6) + { + zm_msg0_mm(ZM_LV_1, "desired bssid not matched 2"); + pBssInfo = pBssInfo->next; + continue; + } + } + + /* Check support mode */ + if (pBssInfo->frequency > 3000) { + if ( (pBssInfo->EnableHT == 1) + || (pBssInfo->apCap & ZM_All11N_AP) ) //11n AP + { + channelFlags = CHANNEL_A_HT; + if (pBssInfo->enableHT40 == 1) { + channelFlags |= CHANNEL_HT40; + } + } else { + channelFlags = CHANNEL_A; + } + } else { + if ( (pBssInfo->EnableHT == 1) + || (pBssInfo->apCap & ZM_All11N_AP) ) //11n AP + { + channelFlags = CHANNEL_G_HT; + if(pBssInfo->enableHT40 == 1) { + channelFlags |= CHANNEL_HT40; + } + } else { + if (pBssInfo->extSupportedRates[1] == 0) { + channelFlags = CHANNEL_B; + } else { + channelFlags = CHANNEL_G; + } + } + } + + if ( ((channelFlags == CHANNEL_B) && (wd->connectMode & ZM_BIT_0)) + || ((channelFlags == CHANNEL_G) && (wd->connectMode & ZM_BIT_1)) + || ((channelFlags == CHANNEL_A) && (wd->connectMode & ZM_BIT_2)) + || ((channelFlags & CHANNEL_HT20) && (wd->connectMode & ZM_BIT_3)) ) + { + pBssInfo = pBssInfo->next; + continue; + } + + /* Skip if AP in blocking list */ + if ((ret = zfStaIsApInBlockingList(dev, pBssInfo->bssid)) == TRUE) + { + zm_msg0_mm(ZM_LV_0, "Candidate AP in blocking List, skip if there's stilla choice!"); + pNowBssInfo = pBssInfo; + pBssInfo = pBssInfo->next; + continue; + } + + if ( pBssInfo->capability[0] & ZM_BIT_0 ) // check if infra-BSS + { + pNowBssInfo = pBssInfo; + wd->sta.apWmeCapability = pBssInfo->wmeSupport; + + + goto done; + } + } + + pBssInfo = pBssInfo->next; + } + +done: + if (pNowBssInfo != NULL) + { + zfwMemoryCopy((void*)candidateBss, (void*)pNowBssInfo, sizeof(struct zsBssInfo)); + pNowBssInfo = candidateBss; + } + + zmw_leave_critical_section(dev); + + return pNowBssInfo; +} + + +void zfInfraConnectNetwork(zdev_t* dev) +{ + struct zsBssInfo* pBssInfo; + struct zsBssInfo* pNowBssInfo=NULL; + struct zsBssInfo candidateBss; + //u16_t i, j=100, quality=10000; + //u8_t ret=FALSE, apWepStatus; + u8_t ret=FALSE; + u16_t k; + u8_t density = ZM_MPDU_DENSITY_NONE; + + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + /* Reset bssNotFoundCount for Ad-Hoc:IBSS */ + /* Need review : IbssConn -> InfraConn -> IbssConn etc, flag/counter reset? */ + zmw_enter_critical_section(dev); + wd->sta.bssNotFoundCount = 0; + zmw_leave_critical_section(dev); + + /* Set TxQs CWMIN, CWMAX, AIFS and TXO to WME STA default. */ + zfUpdateDefaultQosParameter(dev, 0); + + zfStaRefreshBlockList(dev, 0); + + /* change state to CONNECTING and stop the channel scanning */ + zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTING); + zfPowerSavingMgrWakeup(dev); + + wd->sta.wmeConnected = 0; + wd->sta.psMgr.tempWakeUp = 0; + wd->sta.qosInfo = 0; + zfQueueFlush(dev, wd->sta.uapsdQ); + + wd->sta.connectState = ZM_STA_CONN_STATE_NONE; + + //Reorder BssList by RSSI--CWYang(+) + zfBssInfoReorderList(dev); + + pNowBssInfo = zfInfraFindAPToConnect(dev, &candidateBss); + + if (wd->sta.SWEncryptEnable != 0) + { + if (wd->sta.bSafeMode == 0) + { + zfStaDisableSWEncryption(dev);//Quickly reboot + } + } + if ( pNowBssInfo != NULL ) + { + //zm_assert(pNowBssInfo != NULL); + + pBssInfo = pNowBssInfo; + wd->sta.ssidLen = pBssInfo->ssid[1]; + zfMemoryCopy(wd->sta.ssid, &(pBssInfo->ssid[2]), pBssInfo->ssid[1]); + wd->frequency = pBssInfo->frequency; + //wd->sta.flagFreqChanging = 1; + + //zfCoreSetFrequency(dev, wd->frequency); + zfUpdateBssid(dev, pBssInfo->bssid); + zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_ZERO); + zfUpdateSupportRate(dev, pBssInfo->supportedRates); + zfUpdateSupportRate(dev, pBssInfo->extSupportedRates); + + wd->beaconInterval = pBssInfo->beaconInterval[0] + + (((u16_t) pBssInfo->beaconInterval[1]) << 8); + if (wd->beaconInterval == 0) + { + wd->beaconInterval = 100; + } + + /* ESS bit on */ + wd->sta.capability[0] |= ZM_BIT_0; + /* IBSS bit off */ + wd->sta.capability[0] &= ~ZM_BIT_1; + + /* 11n AP flag */ + wd->sta.EnableHT = pBssInfo->EnableHT; + wd->sta.SG40 = pBssInfo->SG40; +#ifdef ZM_ENABLE_CENC + if ( pBssInfo->securityType == ZM_SECURITY_TYPE_CENC ) + { + wd->sta.wmeEnabled = 0; //Disable WMM in CENC + cencInit(dev); + cencSetCENCMode(dev, NdisCENC_PSK); + wd->sta.wpaState = ZM_STA_WPA_STATE_INIT; + /* CENC */ + if ( pBssInfo->cencIe[1] != 0 ) + { + //wd->sta.wepStatus = ZM_ENCRYPTION_CENC; + //wd->sta.encryMode = ZM_CENC; + zfwCencHandleBeaconProbrespon(dev, (u8_t *)&pBssInfo->cencIe, + (u8_t *)&pBssInfo->ssid, (u8_t *)&pBssInfo->macaddr); + zfMemoryCopy(wd->sta.cencIe, pBssInfo->cencIe, + pBssInfo->cencIe[1]+2); + } + else + { + wd->sta.cencIe[1] = 0; + } + } +#endif //ZM_ENABLE_CENC + if ( pBssInfo->securityType == ZM_SECURITY_TYPE_WPA ) + { + wd->sta.wpaState = ZM_STA_WPA_STATE_INIT; + + if ( wd->sta.wepStatus == ZM_ENCRYPTION_TKIP ) + { + wd->sta.encryMode = ZM_TKIP; + + /* Turn on software encryption/decryption for TKIP */ + if (wd->sta.EnableHT == 1) + { + zfStaEnableSWEncryption(dev, (ZM_SW_TKIP_ENCRY_EN|ZM_SW_TKIP_DECRY_EN)); + } + + /* Do not support TKIP in 11n mode */ + //wd->sta.EnableHT = 0; + //pBssInfo->enableHT40 = 0; + } + else if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES ) + { + wd->sta.encryMode = ZM_AES; + + /* If AP supports HT mode */ + if (wd->sta.EnableHT) + { + /* Set MPDU density to 8 us*/ + density = ZM_MPDU_DENSITY_8US; + } + } + + if ( pBssInfo->wpaIe[1] != 0 ) + { + zfMemoryCopy(wd->sta.wpaIe, pBssInfo->wpaIe, + pBssInfo->wpaIe[1]+2); + } + else + { + wd->sta.wpaIe[1] = 0; + } + + if ( pBssInfo->rsnIe[1] != 0 ) + { + zfMemoryCopy(wd->sta.rsnIe, pBssInfo->rsnIe, + pBssInfo->rsnIe[1]+2); + } + else + { + wd->sta.rsnIe[1] = 0; + } + } + + + + /* check preamble bit */ + wd->preambleTypeInUsed = wd->preambleType; + if ( wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_AUTO ) + { + if (pBssInfo->capability[0] & ZM_BIT_5) + { + wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_SHORT; + } + else + { + wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_LONG; + } + } + + if (wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_LONG) + { + wd->sta.capability[0] &= ~ZM_BIT_5; + } + else + { + wd->sta.capability[0] |= ZM_BIT_5; + } + + /* check 802.11n 40MHz Setting */ + if ((pBssInfo->enableHT40 == 1) && + ((pBssInfo->extChOffset == 1) || (pBssInfo->extChOffset == 3))) + { + wd->BandWidth40 = pBssInfo->enableHT40; + wd->ExtOffset = pBssInfo->extChOffset; + } + else + { + wd->BandWidth40 = 0; + wd->ExtOffset = 0; + } + + /* check 802.11H support bit */ + + /* check Owl Ap */ + if ( pBssInfo->athOwlAp & ZM_BIT_0 ) + { + /* In this function, FW retry will be enable, ZM_MAC_REG_RETRY_MAX + will be set to 0. + */ + zfHpDisableHwRetry(dev); + wd->sta.athOwlAp = 1; + /* Set MPDU density to 8 us*/ + density = ZM_MPDU_DENSITY_8US; + } + else + { + /* In this function, FW retry will be disable, ZM_MAC_REG_RETRY_MAX + will be set to 3. + */ + zfHpEnableHwRetry(dev); + wd->sta.athOwlAp = 0; + } + wd->reorder = 1; + + /* Set MPDU density */ + zfHpSetMPDUDensity(dev, density); + + /* check short slot time bit */ + if ( pBssInfo->capability[1] & ZM_BIT_2 ) + { + wd->sta.capability[1] |= ZM_BIT_2; + } + + if ( pBssInfo->erp & ZM_BIT_1 ) + { + //zm_debug_msg0("protection mode on"); + wd->sta.bProtectionMode = TRUE; + zfHpSetSlotTime(dev, 0); + } + else + { + //zm_debug_msg0("protection mode off"); + wd->sta.bProtectionMode = FALSE; + zfHpSetSlotTime(dev, 1); + } + + if (pBssInfo->marvelAp == 1) + { + wd->sta.enableDrvBA = 0; + /* + * 8701 : NetGear 3500 (MARVELL) + * Downlink issue : set slottime to 20. + */ + zfHpSetSlotTimeRegister(dev, 0); + } + else + { + wd->sta.enableDrvBA = 1; + + /* + * This is not good for here do reset slot time. + * I think it should reset when leave MARVELL ap + * or enter disconnect state etc. + */ + zfHpSetSlotTimeRegister(dev, 1); + } + + //Store probe response frame body, for VISTA only + wd->sta.beaconFrameBodySize = pBssInfo->frameBodysize + 12; + if (wd->sta.beaconFrameBodySize > ZM_CACHED_FRAMEBODY_SIZE) + { + wd->sta.beaconFrameBodySize = ZM_CACHED_FRAMEBODY_SIZE; + } + for (k=0; k<8; k++) + { + wd->sta.beaconFrameBody[k] = pBssInfo->timeStamp[k]; + } + wd->sta.beaconFrameBody[8] = pBssInfo->beaconInterval[0]; + wd->sta.beaconFrameBody[9] = pBssInfo->beaconInterval[1]; + wd->sta.beaconFrameBody[10] = pBssInfo->capability[0]; + wd->sta.beaconFrameBody[11] = pBssInfo->capability[1]; + for (k=0; k<(wd->sta.beaconFrameBodySize - 12); k++) + { + wd->sta.beaconFrameBody[k+12] = pBssInfo->frameBody[k]; + } + + if ( ( pBssInfo->capability[0] & ZM_BIT_4 )&& + (( wd->sta.authMode == ZM_AUTH_MODE_OPEN )|| + ( wd->sta.authMode == ZM_AUTH_MODE_SHARED_KEY)|| + (wd->sta.authMode == ZM_AUTH_MODE_AUTO)) ) + { /* privacy enabled */ + + if ( wd->sta.wepStatus == ZM_ENCRYPTION_WEP_DISABLED ) + { + zm_debug_msg0("Adapter is no WEP, try to connect to WEP AP"); + ret = FALSE; + } + + /* Do not support WEP in 11n mode */ + if ( wd->sta.wepStatus == ZM_ENCRYPTION_WEP_ENABLED ) + { + /* Turn on software encryption/decryption for WEP */ + if (wd->sta.EnableHT == 1) + { + zfStaEnableSWEncryption(dev, (ZM_SW_WEP_ENCRY_EN|ZM_SW_WEP_DECRY_EN)); + } + + //wd->sta.EnableHT = 0; + //wd->BandWidth40 = 0; + //wd->ExtOffset = 0; + } + + wd->sta.capability[0] |= ZM_BIT_4; + + if ( wd->sta.authMode == ZM_AUTH_MODE_AUTO ) + { /* Try to use open and shared-key authehtication alternatively */ + if ( (wd->sta.connectTimeoutCount % 2) == 0 ) + wd->sta.bIsSharedKey = 0; + else + wd->sta.bIsSharedKey = 1; + } + else if ( wd->sta.authMode != ZM_AUTH_MODE_SHARED_KEY ) + { /* open or auto */ + //zfStaStartConnect(dev, 0); + wd->sta.bIsSharedKey = 0; + } + else if ( wd->sta.authMode != ZM_AUTH_MODE_OPEN ) + { /* shared key */ + //zfStaStartConnect(dev, 1) ; + wd->sta.bIsSharedKey = 1; + } + } + else + { + if ( (pBssInfo->securityType == ZM_SECURITY_TYPE_WPA)|| + (pBssInfo->capability[0] & ZM_BIT_4) ) + { + wd->sta.capability[0] |= ZM_BIT_4; + /* initialize WPA related parameters */ + } + else + { + wd->sta.capability[0] &= (~ZM_BIT_4); + } + + /* authentication with open system */ + //zfStaStartConnect(dev, 0); + wd->sta.bIsSharedKey = 0; + } + + /* Improve WEP/TKIP performace with HT AP, detail information please look bug#32495 */ + /* + if ( (pBssInfo->broadcomHTAp == 1) + && (wd->sta.SWEncryptEnable != 0) ) + { + zfHpSetTTSIFSTime(dev, 0xa); + } + else + { + zfHpSetTTSIFSTime(dev, 0x8); + } + */ + } + else + { + zm_debug_msg0("Desired SSID not found"); + goto zlConnectFailed; + } + + + zfCoreSetFrequencyV2(dev, wd->frequency, zfStaStartConnectCb); + return; + +zlConnectFailed: + zfStaConnectFail(dev, ZM_STATUS_MEDIA_DISCONNECT_NOT_FOUND, wd->sta.bssid, 0); + return; +} + +u8_t zfCheckWPAAuth(zdev_t* dev, struct zsBssInfo* pBssInfo) +{ + u8_t ret=TRUE; + u8_t pmkCount; + u8_t i; + u16_t encAlgoType = 0; + + zmw_get_wlan_dev(dev); + + if ( wd->sta.wepStatus == ZM_ENCRYPTION_TKIP ) + { + encAlgoType = ZM_TKIP; + } + else if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES ) + { + encAlgoType = ZM_AES; + } + + switch(wd->sta.authMode) + { + case ZM_AUTH_MODE_WPA: + case ZM_AUTH_MODE_WPAPSK: + if ( pBssInfo->wpaIe[1] == 0 ) + { + ret = FALSE; + break; + } + + pmkCount = pBssInfo->wpaIe[12]; + for(i=0; i < pmkCount; i++) + { + if ( pBssInfo->wpaIe[17 + 4*i] == encAlgoType ) + { + ret = TRUE; + goto done; + } + } + + ret = FALSE; + break; + + case ZM_AUTH_MODE_WPA2: + case ZM_AUTH_MODE_WPA2PSK: + if ( pBssInfo->rsnIe[1] == 0 ) + { + ret = FALSE; + break; + } + + pmkCount = pBssInfo->rsnIe[8]; + for(i=0; i < pmkCount; i++) + { + if ( pBssInfo->rsnIe[13 + 4*i] == encAlgoType ) + { + ret = TRUE; + goto done; + } + } + + ret = FALSE; + break; + } + +done: + return ret; +} + +u8_t zfCheckAuthentication(zdev_t* dev, struct zsBssInfo* pBssInfo) +{ + u8_t ret=TRUE; + u16_t encAlgoType; + u16_t UnicastCipherNum; + + zmw_get_wlan_dev(dev); + + /* Connecting to ANY has been checked */ + if ( wd->sta.ssidLen == 0 ) + { + return ret; + } + + + switch(wd->sta.authMode) + //switch(wd->ws.authMode)//Quickly reboot + { + case ZM_AUTH_MODE_WPA_AUTO: + case ZM_AUTH_MODE_WPAPSK_AUTO: + encAlgoType = 0; + if(pBssInfo->rsnIe[1] != 0) + { + UnicastCipherNum = (pBssInfo->rsnIe[8]) + + (pBssInfo->rsnIe[9] << 8); + + /* If there is only one unicast cipher */ + if (UnicastCipherNum == 1) + { + encAlgoType = pBssInfo->rsnIe[13]; + //encAlgoType = pBssInfo->rsnIe[7]; + } + else + { + u16_t ii; + u16_t desiredCipher = 0; + u16_t IEOffSet = 13; + + /* Enumerate all the supported unicast cipher */ + for (ii = 0; ii < UnicastCipherNum; ii++) + { + if (pBssInfo->rsnIe[IEOffSet+ii*4] > desiredCipher) + { + desiredCipher = pBssInfo->rsnIe[IEOffSet+ii*4]; + } + } + + encAlgoType = desiredCipher; + } + + if ( encAlgoType == 0x02 ) + { + wd->sta.wepStatus = ZM_ENCRYPTION_TKIP; + + if ( wd->sta.authMode == ZM_AUTH_MODE_WPA_AUTO ) + { + wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA2; + } + else //ZM_AUTH_MODE_WPAPSK_AUTO + { + wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA2PSK; + } + } + else if ( encAlgoType == 0x04 ) + { + wd->sta.wepStatus = ZM_ENCRYPTION_AES; + + if ( wd->sta.authMode == ZM_AUTH_MODE_WPA_AUTO ) + { + wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA2; + } + else //ZM_AUTH_MODE_WPAPSK_AUTO + { + wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA2PSK; + } + } + else + { + ret = FALSE; + } + } + else if(pBssInfo->wpaIe[1] != 0) + { + UnicastCipherNum = (pBssInfo->wpaIe[12]) + + (pBssInfo->wpaIe[13] << 8); + + /* If there is only one unicast cipher */ + if (UnicastCipherNum == 1) + { + encAlgoType = pBssInfo->wpaIe[17]; + //encAlgoType = pBssInfo->wpaIe[11]; + } + else + { + u16_t ii; + u16_t desiredCipher = 0; + u16_t IEOffSet = 17; + + /* Enumerate all the supported unicast cipher */ + for (ii = 0; ii < UnicastCipherNum; ii++) + { + if (pBssInfo->wpaIe[IEOffSet+ii*4] > desiredCipher) + { + desiredCipher = pBssInfo->wpaIe[IEOffSet+ii*4]; + } + } + + encAlgoType = desiredCipher; + } + + if ( encAlgoType == 0x02 ) + { + wd->sta.wepStatus = ZM_ENCRYPTION_TKIP; + + if ( wd->sta.authMode == ZM_AUTH_MODE_WPA_AUTO ) + { + wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA; + } + else //ZM_AUTH_MODE_WPAPSK_AUTO + { + wd->sta.currentAuthMode = ZM_AUTH_MODE_WPAPSK; + } + } + else if ( encAlgoType == 0x04 ) + { + wd->sta.wepStatus = ZM_ENCRYPTION_AES; + + if ( wd->sta.authMode == ZM_AUTH_MODE_WPA_AUTO ) + { + wd->sta.currentAuthMode = ZM_AUTH_MODE_WPA; + } + else //ZM_AUTH_MODE_WPAPSK_AUTO + { + wd->sta.currentAuthMode = ZM_AUTH_MODE_WPAPSK; + } + } + else + { + ret = FALSE; + } + + + } + else + { + ret = FALSE; + } + + break; + + case ZM_AUTH_MODE_WPA: + case ZM_AUTH_MODE_WPAPSK: + case ZM_AUTH_MODE_WPA_NONE: + case ZM_AUTH_MODE_WPA2: + case ZM_AUTH_MODE_WPA2PSK: + { + if ( pBssInfo->securityType != ZM_SECURITY_TYPE_WPA ) + { + ret = FALSE; + } + + ret = zfCheckWPAAuth(dev, pBssInfo); + } + break; + + case ZM_AUTH_MODE_OPEN: + case ZM_AUTH_MODE_SHARED_KEY: + case ZM_AUTH_MODE_AUTO: + { + if ( pBssInfo->wscIe[1] ) + { + // If the AP is a Jumpstart AP, it's ok!! Ray + break; + } + else if ( pBssInfo->securityType == ZM_SECURITY_TYPE_WPA ) + { + ret = FALSE; + } + } + break; + + default: + break; + } + + return ret; +} + +u8_t zfStaIsConnected(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + if ( wd->sta.adapterState == ZM_STA_STATE_CONNECTED ) + { + return TRUE; + } + + return FALSE; +} + +u8_t zfStaIsConnecting(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + if ( wd->sta.adapterState == ZM_STA_STATE_CONNECTING ) + { + return TRUE; + } + + return FALSE; +} + +u8_t zfStaIsDisconnect(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + if ( wd->sta.adapterState == ZM_STA_STATE_DISCONNECT ) + { + return TRUE; + } + + return FALSE; +} + +u8_t zfChangeAdapterState(zdev_t* dev, u8_t newState) +{ + u8_t ret = TRUE; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + //if ( newState == wd->sta.adapterState ) + //{ + // return FALSE; + //} + + switch(newState) + { + case ZM_STA_STATE_DISCONNECT: + zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_DISCONNECT); + + #if 1 + zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_INTERNAL); + #else + if ( wd->sta.bChannelScan ) + { + /* stop the action of channel scanning */ + wd->sta.bChannelScan = FALSE; + ret = TRUE; + break; + } + #endif + + break; + case ZM_STA_STATE_CONNECTING: + #if 1 + zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_INTERNAL); + #else + if ( wd->sta.bChannelScan ) + { + /* stop the action of channel scanning */ + wd->sta.bChannelScan = FALSE; + ret = TRUE; + break; + } + #endif + + break; + case ZM_STA_STATE_CONNECTED: + break; + default: + break; + } + + //if ( ret ) + //{ + zmw_enter_critical_section(dev); + wd->sta.adapterState = newState; + zmw_leave_critical_section(dev); + + zm_debug_msg1("change adapter state = ", newState); + //} + + return ret; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfStaMmAddIeSsid */ +/* Add information element SSID to buffer. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : buffer to add information element */ +/* offset : add information element from this offset */ +/* */ +/* OUTPUTS */ +/* buffer offset after adding information element */ +/* */ +/* AUTHOR */ +/* Ji-Huang Lee ZyDAS Technology Corporation 2005.11 */ +/* */ +/************************************************************************/ +u16_t zfStaAddIeSsid(zdev_t* dev, zbuf_t* buf, u16_t offset) +{ + u16_t i; + + zmw_get_wlan_dev(dev); + + /* Element ID */ + zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_SSID); + + /* Element Length */ + zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.ssidLen); + + /* Information : SSID */ + for (i=0; ista.ssidLen; i++) + { + zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.ssid[i]); + } + + return offset; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfStaMmAddIeWpa */ +/* Add information element SSID to buffer. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : buffer to add information element */ +/* offset : add information element from this offset */ +/* */ +/* OUTPUTS */ +/* buffer offset after adding information element */ +/* */ +/* AUTHOR */ +/* Ji-Huang Lee ZyDAS Technology Corporation 2006.01 */ +/* */ +/************************************************************************/ +u16_t zfStaAddIeWpaRsn(zdev_t* dev, zbuf_t* buf, u16_t offset, u8_t frameType) +{ + u32_t i; + u8_t ssn[64]={ + /* Element ID */ + 0xdd, + /* Length */ + 0x18, + /* OUI type */ + 0x00, 0x50, 0xf2, 0x01, + /* Version */ + 0x01, 0x00, + /* Group Cipher Suite, default=TKIP */ + 0x00, 0x50, 0xf2, 0x02, + /* Pairwise Cipher Suite Count */ + 0x01, 0x00, + /* Pairwise Cipher Suite, default=TKIP */ + 0x00, 0x50, 0xf2, 0x02, + /* Authentication and Key Management Suite Count */ + 0x01, 0x00, + /* Authentication type, default=PSK */ + 0x00, 0x50, 0xf2, 0x02, + /* WPA capability */ + 0x00, 0x00 + }; + + u8_t rsn[64]={ + /* Element ID */ + 0x30, + /* Length */ + 0x14, + /* Version */ + 0x01, 0x00, + /* Group Cipher Suite, default=TKIP */ + 0x00, 0x0f, 0xac, 0x02, + /* Pairwise Cipher Suite Count */ + 0x01, 0x00, + /* Pairwise Cipher Suite, default=TKIP */ + 0x00, 0x0f, 0xac, 0x02, + /* Authentication and Key Management Suite Count */ + 0x01, 0x00, + /* Authentication type, default=PSK */ + 0x00, 0x0f, 0xac, 0x02, + /* RSN capability */ + 0x00, 0x00 + }; + + zmw_get_wlan_dev(dev); + + if ( wd->sta.currentAuthMode == ZM_AUTH_MODE_WPAPSK ) + { + /* Overwrite Group Cipher Suite by AP's setting */ + zfMemoryCopy(ssn+8, wd->sta.wpaIe+8, 4); + + if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES ) + { + /* Overwrite Pairwise Cipher Suite by AES */ + zfMemoryCopy(ssn+14, zgWpaAesOui, 4); + } + + zfCopyToIntTxBuffer(dev, buf, ssn, offset, ssn[1]+2); + zfMemoryCopy(wd->sta.wpaIe, ssn, ssn[1]+2); + offset += (ssn[1]+2); + } + else if ( wd->sta.currentAuthMode == ZM_AUTH_MODE_WPA ) + { + /* Overwrite Group Cipher Suite by AP's setting */ + zfMemoryCopy(ssn+8, wd->sta.wpaIe+8, 4); + /* Overwrite Key Management Suite by WPA-Radius */ + zfMemoryCopy(ssn+20, zgWpaRadiusOui, 4); + + if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES ) + { + /* Overwrite Pairwise Cipher Suite by AES */ + zfMemoryCopy(ssn+14, zgWpaAesOui, 4); + } + + zfCopyToIntTxBuffer(dev, buf, ssn, offset, ssn[1]+2); + zfMemoryCopy(wd->sta.wpaIe, ssn, ssn[1]+2); + offset += (ssn[1]+2); + } + else if ( wd->sta.currentAuthMode == ZM_AUTH_MODE_WPA2PSK ) + { + /* Overwrite Group Cipher Suite by AP's setting */ + zfMemoryCopy(rsn+4, wd->sta.rsnIe+4, 4); + + if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES ) + { + /* Overwrite Pairwise Cipher Suite by AES */ + zfMemoryCopy(rsn+10, zgWpa2AesOui, 4); + } + + if ( frameType == ZM_WLAN_FRAME_TYPE_REASOCREQ ) + { + for(i=0; ista.pmkidInfo.bssidCount; i++) + { + if ( zfMemoryIsEqual((u8_t*) wd->sta.pmkidInfo.bssidInfo[i].bssid, + (u8_t*) wd->sta.bssid, 6) ) + { + /* matched */ + break; + } + + if ( i < wd->sta.pmkidInfo.bssidCount ) + { + // Fill PMKID Count in RSN information element + rsn[22] = 0x01; + rsn[23] = 0x00; + + // Fill PMKID in RSN information element + zfMemoryCopy(rsn+24, + wd->sta.pmkidInfo.bssidInfo[i].pmkid, 16); + rsn[1] += 18; + } + } + } + + zfCopyToIntTxBuffer(dev, buf, rsn, offset, rsn[1]+2); + zfMemoryCopy(wd->sta.rsnIe, rsn, rsn[1]+2); + offset += (rsn[1]+2); + } + else if ( wd->sta.currentAuthMode == ZM_AUTH_MODE_WPA2 ) + { + /* Overwrite Group Cipher Suite by AP's setting */ + zfMemoryCopy(rsn+4, wd->sta.rsnIe+4, 4); + /* Overwrite Key Management Suite by WPA2-Radius */ + zfMemoryCopy(rsn+16, zgWpa2RadiusOui, 4); + + if ( wd->sta.wepStatus == ZM_ENCRYPTION_AES ) + { + /* Overwrite Pairwise Cipher Suite by AES */ + zfMemoryCopy(rsn+10, zgWpa2AesOui, 4); + } + + if (( frameType == ZM_WLAN_FRAME_TYPE_REASOCREQ || ( frameType == ZM_WLAN_FRAME_TYPE_ASOCREQ ))) + { + + if (wd->sta.pmkidInfo.bssidCount != 0) { + // Fill PMKID Count in RSN information element + rsn[22] = 1; + rsn[23] = 0; + /* + * The caller is respnsible to give us the relevant PMKID. + * We'll only accept 1 PMKID for now. + */ + for(i=0; ista.pmkidInfo.bssidCount; i++) + { + if ( zfMemoryIsEqual((u8_t*) wd->sta.pmkidInfo.bssidInfo[i].bssid, (u8_t*) wd->sta.bssid, 6) ) + { + zfMemoryCopy(rsn+24, wd->sta.pmkidInfo.bssidInfo[i].pmkid, 16); + break; + } + } + rsn[1] += 18; + } + + } + + zfCopyToIntTxBuffer(dev, buf, rsn, offset, rsn[1]+2); + zfMemoryCopy(wd->sta.rsnIe, rsn, rsn[1]+2); + offset += (rsn[1]+2); + } + + return offset; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfStaAddIeIbss */ +/* Add information element IBSS parameter to buffer. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : buffer to add information element */ +/* offset : add information element from this offset */ +/* */ +/* OUTPUTS */ +/* buffer offset after adding information element */ +/* */ +/* AUTHOR */ +/* Ji-Huang Lee ZyDAS Technology Corporation 2005.12 */ +/* */ +/************************************************************************/ +u16_t zfStaAddIeIbss(zdev_t* dev, zbuf_t* buf, u16_t offset) +{ + zmw_get_wlan_dev(dev); + + /* Element ID */ + zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_IBSS); + + /* Element Length */ + zmw_tx_buf_writeb(dev, buf, offset++, 2); + + /* ATIM window */ + zmw_tx_buf_writeh(dev, buf, offset, wd->sta.atimWindow); + offset += 2; + + return offset; +} + + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfStaAddIeWmeInfo */ +/* Add WME Information Element to buffer. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : buffer to add information element */ +/* offset : add information element from this offset */ +/* */ +/* OUTPUTS */ +/* buffer offset after adding information element */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2006.6 */ +/* */ +/************************************************************************/ +u16_t zfStaAddIeWmeInfo(zdev_t* dev, zbuf_t* buf, u16_t offset, u8_t qosInfo) +{ + /* Element ID */ + zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_WIFI_IE); + + /* Element Length */ + zmw_tx_buf_writeb(dev, buf, offset++, 7); + + /* OUI */ + zmw_tx_buf_writeb(dev, buf, offset++, 0x00); + zmw_tx_buf_writeb(dev, buf, offset++, 0x50); + zmw_tx_buf_writeb(dev, buf, offset++, 0xF2); + zmw_tx_buf_writeb(dev, buf, offset++, 0x02); + zmw_tx_buf_writeb(dev, buf, offset++, 0x00); + zmw_tx_buf_writeb(dev, buf, offset++, 0x01); + + /* QoS Info */ + zmw_tx_buf_writeb(dev, buf, offset++, qosInfo); + + return offset; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfStaAddIePowerCap */ +/* Add information element Power capability to buffer. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : buffer to add information element */ +/* offset : add information element from this offset */ +/* */ +/* OUTPUTS */ +/* buffer offset after adding information element */ +/* */ +/* AUTHOR */ +/* Sharon 2007.12 */ +/* */ +/************************************************************************/ +u16_t zfStaAddIePowerCap(zdev_t* dev, zbuf_t* buf, u16_t offset) +{ + u8_t MaxTxPower; + u8_t MinTxPower; + + zmw_get_wlan_dev(dev); + + /* Element ID */ + zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_POWER_CAPABILITY); + + /* Element Length */ + zmw_tx_buf_writeb(dev, buf, offset++, 2); + + MinTxPower = (u8_t)(zfHpGetMinTxPower(dev)/2); + MaxTxPower = (u8_t)(zfHpGetMaxTxPower(dev)/2); + + /* Min Transmit Power Cap */ + zmw_tx_buf_writeh(dev, buf, offset++, MinTxPower); + + /* Max Transmit Power Cap */ + zmw_tx_buf_writeh(dev, buf, offset++, MaxTxPower); + + return offset; +} +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfStaAddIeSupportCh */ +/* Add information element supported channels to buffer. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : buffer to add information element */ +/* offset : add information element from this offset */ +/* */ +/* OUTPUTS */ +/* buffer offset after adding information element */ +/* */ +/* AUTHOR */ +/* Sharon 2007.12 */ +/* */ +/************************************************************************/ +u16_t zfStaAddIeSupportCh(zdev_t* dev, zbuf_t* buf, u16_t offset) +{ + + u8_t i; + u16_t count_24G = 0; + u16_t count_5G = 0; + u16_t channelNum; + u8_t length; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + zmw_enter_critical_section(dev); + + for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) + { + if (wd->regulationTable.allowChannel[i].channel < 3000) + { // 2.4Hz + count_24G++; + } + else + { // 5GHz + count_5G++; + } + } + + length = (u8_t)(count_5G * 2 + 2); //5G fill by pair, 2,4G (continuous channels) fill 2 bytes + + /* Element ID */ + zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_SUPPORTED_CHANNELS ); + + /* Element Length */ + zmw_tx_buf_writeb(dev, buf, offset++, length); + + // 2.4GHz (continuous channels) + /* First channel number */ + zmw_tx_buf_writeh(dev, buf, offset++, 1); //Start from channle 1 + /* Number of channels */ + zmw_tx_buf_writeh(dev, buf, offset++, count_24G); + + for (i = 0; i < wd->regulationTable.allowChannelCnt ; i++) + { + if (wd->regulationTable.allowChannel[i].channel > 4000 && wd->regulationTable.allowChannel[i].channel < 5000) + { // 5GHz 4000 -5000Mhz + channelNum = (wd->regulationTable.allowChannel[i].channel-4000)/5; + /* First channel number */ + zmw_tx_buf_writeh(dev, buf, offset++, channelNum); + /* Number of channels */ + zmw_tx_buf_writeh(dev, buf, offset++, 1); + } + else if (wd->regulationTable.allowChannel[i].channel >= 5000) + { // 5GHz >5000Mhz + channelNum = (wd->regulationTable.allowChannel[i].channel-5000)/5; + /* First channel number */ + zmw_tx_buf_writeh(dev, buf, offset++, channelNum); + /* Number of channels */ + zmw_tx_buf_writeh(dev, buf, offset++, 1); + } + } + zmw_leave_critical_section(dev); + + return offset; +} + +void zfStaStartConnectCb(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + zfStaStartConnect(dev, wd->sta.bIsSharedKey); +} + +void zfStaStartConnect(zdev_t* dev, u8_t bIsSharedKey) +{ + u32_t p1, p2; + u8_t newConnState; + + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + /* p1_low = algorithm number, p1_high = transaction sequence number */ + if ( bIsSharedKey ) + { + //wd->sta.connectState = ZM_STA_CONN_STATE_AUTH_SHARE_1; + newConnState = ZM_STA_CONN_STATE_AUTH_SHARE_1; + zm_debug_msg0("ZM_STA_CONN_STATE_AUTH_SHARE_1"); + p1 = ZM_AUTH_ALGO_SHARED_KEY; + } + else + { + //wd->sta.connectState = ZM_STA_CONN_STATE_AUTH_OPEN; + newConnState = ZM_STA_CONN_STATE_AUTH_OPEN; + zm_debug_msg0("ZM_STA_CONN_STATE_AUTH_OPEN"); + if( wd->sta.leapEnabled ) + p1 = ZM_AUTH_ALGO_LEAP; + else + p1 = ZM_AUTH_ALGO_OPEN_SYSTEM; + } + + /* status code */ + p2 = 0x0; + + zmw_enter_critical_section(dev); + wd->sta.connectTimer = wd->tick; + wd->sta.connectState = newConnState; + zmw_leave_critical_section(dev); + + /* send the 1st authentication frame */ + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_AUTH, wd->sta.bssid, p1, p2, 0); + + return; +} + +void zfSendNullData(zdev_t* dev, u8_t type) +{ + zbuf_t* buf; + //u16_t addrTblSize; + //struct zsAddrTbl addrTbl; + u16_t err; + u16_t hlen; + u16_t header[(34+8+1)/2]; + u16_t bcastAddr[3] = {0xffff,0xffff,0xffff}; + u16_t *dstAddr; + + zmw_get_wlan_dev(dev); + + if ((buf = zfwBufAllocate(dev, 1024)) == NULL) + { + zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!"); + return; + } + + zfwBufSetSize(dev, buf, 0); + + //zm_msg2_mm(ZM_LV_2, "buf->len=", buf->len); + + if ( wd->wlanMode == ZM_MODE_IBSS) + { + dstAddr = bcastAddr; + } + else + { + dstAddr = wd->sta.bssid; + } + + if (wd->sta.wmeConnected != 0) + { + /* If connect to a WMM AP, Send QoS Null data */ + hlen = zfTxGenMmHeader(dev, ZM_WLAN_FRAME_TYPE_QOS_NULL, dstAddr, header, 0, buf, 0, 0); + } + else + { + hlen = zfTxGenMmHeader(dev, ZM_WLAN_FRAME_TYPE_NULL, dstAddr, header, 0, buf, 0, 0); + } + + if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) + { + header[4] |= 0x0100; //TODS bit + } + + if ( type == 1 ) + { + header[4] |= 0x1000; + } + + /* Get buffer DMA address */ + //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0) + //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0) + //{ + // goto zlError; + //} + + /*increase unicast frame counter*/ + wd->commTally.txUnicastFrm++; + + if ((err = zfHpSend(dev, header, hlen, NULL, 0, NULL, 0, buf, 0, + ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS) + { + goto zlError; + } + + + return; + +zlError: + + zfwBufFree(dev, buf, 0); + return; + +} + +void zfSendPSPoll(zdev_t* dev) +{ + zbuf_t* buf; + //u16_t addrTblSize; + //struct zsAddrTbl addrTbl; + u16_t err; + u16_t hlen; + u16_t header[(8+24+1)/2]; + + zmw_get_wlan_dev(dev); + + if ((buf = zfwBufAllocate(dev, 1024)) == NULL) + { + zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!"); + return; + } + + zfwBufSetSize(dev, buf, 0); + + //zm_msg2_mm(ZM_LV_2, "buf->len=", buf->len); + + zfTxGenMmHeader(dev, ZM_WLAN_FRAME_TYPE_PSPOLL, wd->sta.bssid, header, 0, buf, 0, 0); + + header[0] = 20; + header[4] |= 0x1000; + header[5] = wd->sta.aid | 0xc000; //Both bit-14 and bit-15 are 1 + hlen = 16 + 8; + + /* Get buffer DMA address */ + //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0) + //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0) + //{ + // goto zlError; + //} + + if ((err = zfHpSend(dev, header, hlen, NULL, 0, NULL, 0, buf, 0, + ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS) + { + goto zlError; + } + + return; + +zlError: + + zfwBufFree(dev, buf, 0); + return; + +} + +void zfSendBA(zdev_t* dev, u16_t start_seq, u8_t *bitmap) +{ + zbuf_t* buf; + //u16_t addrTblSize; + //struct zsAddrTbl addrTbl; + u16_t err; + u16_t hlen; + u16_t header[(8+24+1)/2]; + u16_t i, offset = 0; + + zmw_get_wlan_dev(dev); + + if ((buf = zfwBufAllocate(dev, 1024)) == NULL) + { + zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!"); + return; + } + + zfwBufSetSize(dev, buf, 12); // 28 = FC 2 + DU 2 + RA 6 + TA 6 + BAC 2 + SEQ 2 + BitMap 8 + // 12 = BAC 2 + SEQ 2 + BitMap 8 + + //zm_msg2_mm(ZM_LV_2, "buf->len=", buf->len); + + zfTxGenMmHeader(dev, ZM_WLAN_FRAME_TYPE_BA, wd->sta.bssid, header, 0, buf, 0, 0); + + header[0] = 32; /* MAC header 16 + BA control 2 + BA info 10 + FCS 4*/ + header[1] = 0x4; /* No ACK */ + + /* send by OFDM 6M */ + header[2] = (u16_t)(zcRateToPhyCtrl[4] & 0xffff); + header[3] = (u16_t)(zcRateToPhyCtrl[4]>>16) & 0xffff; + + hlen = 16 + 8; /* MAC header 16 + control 8*/ + offset = 0; + zmw_tx_buf_writeh(dev, buf, offset, 0x05); /*compressed bitmap on*/ + offset+=2; + zmw_tx_buf_writeh(dev, buf, offset, start_seq); + offset+=2; + + for (i=0; i<8; i++) { + zmw_tx_buf_writeb(dev, buf, offset, bitmap[i]); + offset++; + } + + if ((err = zfHpSend(dev, header, hlen, NULL, 0, NULL, 0, buf, 0, + ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS) + { + goto zlError; + } + + return; + +zlError: + + zfwBufFree(dev, buf, 0); + return; + +} + +void zfStaGetTxRate(zdev_t* dev, u16_t* macAddr, u32_t* phyCtrl, + u16_t* rcProbingFlag) +{ + u8_t addr[6], i; + u8_t rate; + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + ZM_MAC_WORD_TO_BYTE(macAddr, addr); + *phyCtrl = 0; + + if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) + { + zmw_enter_critical_section(dev); + rate = (u8_t)zfRateCtrlGetTxRate(dev, &wd->sta.oppositeInfo[0].rcCell, rcProbingFlag); +//#ifdef ZM_FB50 + //rate = 27; +//#endif + *phyCtrl = zcRateToPhyCtrl[rate]; + zmw_leave_critical_section(dev); + } + else + { + zmw_enter_critical_section(dev); + for(i=0; ista.oppositeCount; i++) + { + if ( addr[0] && 0x01 == 1 ) // The default beacon transmitted rate is CCK and 1 Mbps , but the a mode should use + // OFDM modulation and 6Mbps to transmit beacon. + { + //rate = (u8_t)zfRateCtrlGetTxRate(dev, &wd->sta.oppositeInfo[i].rcCell, rcProbingFlag); + rate = wd->sta.oppositeInfo[i].rcCell.operationRateSet[0]; + *phyCtrl = zcRateToPhyCtrl[rate]; + break; + } + else if ( zfMemoryIsEqual(addr, wd->sta.oppositeInfo[i].macAddr, 6) ) + { + rate = (u8_t)zfRateCtrlGetTxRate(dev, &wd->sta.oppositeInfo[i].rcCell, rcProbingFlag); + *phyCtrl = zcRateToPhyCtrl[rate]; + break; + } + } + zmw_leave_critical_section(dev); + } + + return; +} + +struct zsMicVar* zfStaGetRxMicKey(zdev_t* dev, zbuf_t* buf) +{ + u8_t keyIndex; + u8_t da0; + + zmw_get_wlan_dev(dev); + + /* if need not check MIC, return NULL */ + if ( ((wd->sta.encryMode != ZM_TKIP)&&(wd->sta.encryMode != ZM_AES))|| + (wd->sta.wpaState < ZM_STA_WPA_STATE_PK_OK) ) + { + return NULL; + } + + da0 = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A1_OFFSET); + + if ((zmw_rx_buf_readb(dev, buf, 0) & 0x80) == 0x80) + keyIndex = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_IV_OFFSET+5); /* Qos Packet*/ + else + keyIndex = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_IV_OFFSET+3); /* normal Packet*/ + keyIndex = (keyIndex & 0xc0) >> 6; + + return (&wd->sta.rxMicKey[keyIndex]); +} + +struct zsMicVar* zfStaGetTxMicKey(zdev_t* dev, zbuf_t* buf) +{ + zmw_get_wlan_dev(dev); + + /* if need not check MIC, return NULL */ + //if ( ((wd->sta.encryMode != ZM_TKIP)&&(wd->sta.encryMode != ZM_AES))|| + // (wd->sta.wpaState < ZM_STA_WPA_STATE_PK_OK) ) + if ( (wd->sta.encryMode != ZM_TKIP) || (wd->sta.wpaState < ZM_STA_WPA_STATE_PK_OK) ) + { + return NULL; + } + + return (&wd->sta.txMicKey); +} + +u16_t zfStaRxValidateFrame(zdev_t* dev, zbuf_t* buf) +{ + u8_t frameType, frameCtrl; + u8_t da0; + //u16_t sa[3]; + u16_t ret; + u16_t i; + //u8_t sa0; + + zmw_get_wlan_dev(dev); + + frameType = zmw_rx_buf_readb(dev, buf, 0); + da0 = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A1_OFFSET); + //sa0 = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A2_OFFSET); + + if ( (!zfStaIsConnected(dev))&&((frameType & 0xf) == ZM_WLAN_DATA_FRAME) ) + { + return ZM_ERR_DATA_BEFORE_CONNECTED; + } + + + if ( (zfStaIsConnected(dev))&&((frameType & 0xf) == ZM_WLAN_DATA_FRAME) ) + { + /* check BSSID */ + if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) + { + /* Big Endian and Little Endian Compatibility */ + u16_t mac[3]; + mac[0] = zmw_cpu_to_le16(wd->sta.bssid[0]); + mac[1] = zmw_cpu_to_le16(wd->sta.bssid[1]); + mac[2] = zmw_cpu_to_le16(wd->sta.bssid[2]); + if ( !zfRxBufferEqualToStr(dev, buf, (u8_t *)mac, + ZM_WLAN_HEADER_A2_OFFSET, 6) ) + { +/*We will get lots of garbage data, especially in AES mode.*/ +/*To avoid sending too many deauthentication frames in STA mode, mark it.*/ +#if 0 + /* If unicast frame, send deauth to the transmitter */ + if (( da0 & 0x01 ) == 0) + { + for (i=0; i<3; i++) + { + sa[i] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+(i*2)); + } + /* If mutilcast address, don't send deauthentication*/ + if (( sa0 & 0x01 ) == 0) + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, sa, 7, 0, 0); + } +#endif + return ZM_ERR_DATA_BSSID_NOT_MATCHED; + } + } + else if ( wd->wlanMode == ZM_MODE_IBSS ) + { + /* Big Endian and Little Endian Compatibility */ + u16_t mac[3]; + mac[0] = zmw_cpu_to_le16(wd->sta.bssid[0]); + mac[1] = zmw_cpu_to_le16(wd->sta.bssid[1]); + mac[2] = zmw_cpu_to_le16(wd->sta.bssid[2]); + if ( !zfRxBufferEqualToStr(dev, buf, (u8_t *)mac, + ZM_WLAN_HEADER_A3_OFFSET, 6) ) + { + return ZM_ERR_DATA_BSSID_NOT_MATCHED; + } + } + + frameCtrl = zmw_rx_buf_readb(dev, buf, 1); + + /* check security bit */ + if ( wd->sta.dropUnencryptedPkts && + (wd->sta.wepStatus != ZM_ENCRYPTION_WEP_DISABLED )&& + ( !(frameCtrl & ZM_BIT_6) ) ) + { /* security on, but got data without encryption */ + + #if 1 + ret = ZM_ERR_DATA_NOT_ENCRYPTED; + if ( wd->sta.pStaRxSecurityCheckCb != NULL ) + { + ret = wd->sta.pStaRxSecurityCheckCb(dev, buf); + } + else + { + ret = ZM_ERR_DATA_NOT_ENCRYPTED; + } + if (ret == ZM_ERR_DATA_NOT_ENCRYPTED) + { + wd->commTally.swRxDropUnencryptedCount++; + } + return ret; + #else + if ( (wd->sta.wepStatus != ZM_ENCRYPTION_TKIP)&& + (wd->sta.wepStatus != ZM_ENCRYPTION_AES) ) + { + return ZM_ERR_DATA_NOT_ENCRYPTED; + } + #endif + } + } + + return ZM_SUCCESS; +} + +void zfStaMicFailureHandling(zdev_t* dev, zbuf_t* buf) +{ + u8_t da0; + u8_t micNotify = 1; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + if ( wd->sta.wpaState < ZM_STA_WPA_STATE_PK_OK ) + { + return; + } + + zmw_enter_critical_section(dev); + + wd->sta.cmMicFailureCount++; + + if ( wd->sta.cmMicFailureCount == 1 ) + { + zm_debug_msg0("get the first MIC failure"); + //zfTimerSchedule(dev, ZM_EVENT_CM_TIMER, ZM_TICK_CM_TIMEOUT); + + /* Timer Resolution on WinXP is 15/16 ms */ + /* Decrease Time offset for Counter Measure */ + zfTimerSchedule(dev, ZM_EVENT_CM_TIMER, ZM_TICK_CM_TIMEOUT - ZM_TICK_CM_TIMEOUT_OFFSET); + } + else if ( wd->sta.cmMicFailureCount == 2 ) + { + zm_debug_msg0("get the second MIC failure"); + /* reserve 2 second for OS to send MIC failure report to AP */ + wd->sta.cmDisallowSsidLength = wd->sta.ssidLen; + zfMemoryCopy(wd->sta.cmDisallowSsid, wd->sta.ssid, wd->sta.ssidLen); + //wd->sta.cmMicFailureCount = 0; + zfTimerCancel(dev, ZM_EVENT_CM_TIMER); + //zfTimerSchedule(dev, ZM_EVENT_CM_DISCONNECT, ZM_TICK_CM_DISCONNECT); + + /* Timer Resolution on WinXP is 15/16 ms */ + /* Decrease Time offset for Counter Measure */ + zfTimerSchedule(dev, ZM_EVENT_CM_DISCONNECT, ZM_TICK_CM_DISCONNECT - ZM_TICK_CM_DISCONNECT_OFFSET); + } + else + { + micNotify = 0; + } + + zmw_leave_critical_section(dev); + + if (micNotify == 1) + { + da0 = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A1_OFFSET); + if ( da0 & 0x01 ) + { + if (wd->zfcbMicFailureNotify != NULL) + { + wd->zfcbMicFailureNotify(dev, wd->sta.bssid, ZM_MIC_GROUP_ERROR); + } + } + else + { + if (wd->zfcbMicFailureNotify != NULL) + { + wd->zfcbMicFailureNotify(dev, wd->sta.bssid, ZM_MIC_PAIRWISE_ERROR); + } + } + } +} + + +u8_t zfStaBlockWlanScan(zdev_t* dev) +{ + u8_t ret=FALSE; + + zmw_get_wlan_dev(dev); + + if ( wd->sta.bChannelScan ) + { + return TRUE; + } + + return ret; +} + +void zfStaResetStatus(zdev_t* dev, u8_t bInit) +{ + u8_t i; + + zmw_get_wlan_dev(dev); + + zfHpDisableBeacon(dev); + + wd->dtim = 1; + wd->sta.capability[0] = 0x01; + wd->sta.capability[1] = 0x00; + /* 802.11h */ + if (wd->sta.DFSEnable || wd->sta.TPCEnable) + wd->sta.capability[1] |= ZM_BIT_0; + + /* release queued packets */ + for(i=0; ista.ibssPSDataCount; i++) + { + zfwBufFree(dev, wd->sta.ibssPSDataQueue[i], 0); + } + + for(i=0; ista.staPSDataCount; i++) + { + zfwBufFree(dev, wd->sta.staPSDataQueue[i], 0); + } + + wd->sta.ibssPSDataCount = 0; + wd->sta.staPSDataCount = 0; + zfZeroMemory((u8_t*) &wd->sta.staPSList, sizeof(struct zsStaPSList)); + + wd->sta.wmeConnected = 0; + wd->sta.psMgr.tempWakeUp = 0; + wd->sta.qosInfo = 0; + zfQueueFlush(dev, wd->sta.uapsdQ); + + return; + +} + +void zfStaIbssMonitoring(zdev_t* dev, u8_t reset) +{ + u16_t i; + u16_t oppositeCount; + struct zsPartnerNotifyEvent event; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + //zm_debug_msg1("zfStaIbssMonitoring %d", wd->sta.oppositeCount); + + zmw_enter_critical_section(dev); + + if ( wd->sta.oppositeCount == 0 ) + { + goto done; + } + + if ( wd->sta.bChannelScan ) + { + goto done; + } + + oppositeCount = wd->sta.oppositeCount; + + for(i=0; i < ZM_MAX_OPPOSITE_COUNT; i++) + { + if ( oppositeCount == 0 ) + { + break; + } + + if ( reset ) + { + wd->sta.oppositeInfo[i].valid = 0; + } + + if ( wd->sta.oppositeInfo[i].valid == 0 ) + { + continue; + } + + oppositeCount--; + + if ( wd->sta.oppositeInfo[i].aliveCounter ) + { + zm_debug_msg1("Setting alive to ", wd->sta.oppositeInfo[i].aliveCounter); + + zmw_leave_critical_section(dev); + + if ( wd->sta.oppositeInfo[i].aliveCounter != ZM_IBSS_PEER_ALIVE_COUNTER ) + { + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_PROBEREQ, + (u16_t*)wd->sta.oppositeInfo[i].macAddr, 1, 0, 0); + } + + zmw_enter_critical_section(dev); + wd->sta.oppositeInfo[i].aliveCounter--; + } + else + { + zm_debug_msg0("zfStaIbssMonitoring remove the peer station"); + zfMemoryCopy(event.bssid, (u8_t *)(wd->sta.bssid), 6); + zfMemoryCopy(event.peerMacAddr, wd->sta.oppositeInfo[i].macAddr, 6); + + wd->sta.oppositeInfo[i].valid = 0; + wd->sta.oppositeCount--; + if (wd->zfcbIbssPartnerNotify != NULL) + { + zmw_leave_critical_section(dev); + wd->zfcbIbssPartnerNotify(dev, 0, &event); + zmw_enter_critical_section(dev); + } + } + } + +done: + if ( reset == 0 ) + { + zfTimerSchedule(dev, ZM_EVENT_IBSS_MONITOR, ZM_TICK_IBSS_MONITOR); + } + + zmw_leave_critical_section(dev); +} + +void zfInitPartnerNotifyEvent(zdev_t* dev, zbuf_t* buf, struct zsPartnerNotifyEvent *event) +{ + u16_t *peerMacAddr; + + zmw_get_wlan_dev(dev); + + peerMacAddr = (u16_t *)event->peerMacAddr; + + zfMemoryCopy(event->bssid, (u8_t *)(wd->sta.bssid), 6); + peerMacAddr[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET); + peerMacAddr[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET + 2); + peerMacAddr[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET + 4); +} + +void zfStaInitOppositeInfo(zdev_t* dev) +{ + int i; + + zmw_get_wlan_dev(dev); + + for(i=0; ista.oppositeInfo[i].valid = 0; + wd->sta.oppositeInfo[i].aliveCounter = ZM_IBSS_PEER_ALIVE_COUNTER; + } +} +#ifdef ZM_ENABLE_CENC +u16_t zfStaAddIeCenc(zdev_t* dev, zbuf_t* buf, u16_t offset) +{ + zmw_get_wlan_dev(dev); + + if (wd->sta.cencIe[1] != 0) + { + zfCopyToIntTxBuffer(dev, buf, wd->sta.cencIe, offset, wd->sta.cencIe[1]+2); + offset += (wd->sta.cencIe[1]+2); + } + return offset; +} +#endif //ZM_ENABLE_CENC +u16_t zfStaProcessAction(zdev_t* dev, zbuf_t* buf) +{ + u8_t category, actionDetails; + zmw_get_wlan_dev(dev); + + category = zmw_rx_buf_readb(dev, buf, 24); + actionDetails = zmw_rx_buf_readb(dev, buf, 25); + switch (category) + { + case 0: //Spectrum Management + switch(actionDetails) + { + case 0: //Measurement Request + break; + case 1: //Measurement Report + //ProcessActionSpectrumFrame_MeasurementReport(Adapter,pActionBody+3); + break; + case 2: //TPC request + //if (wd->sta.TPCEnable) + // zfStaUpdateDot11HTPC(dev, buf); + break; + case 3: //TPC report + //if (wd->sta.TPCEnable) + // zfStaUpdateDot11HTPC(dev, buf); + break; + case 4: //Channel Switch Announcement + if (wd->sta.DFSEnable) + zfStaUpdateDot11HDFS(dev, buf); + break; + default: + zm_debug_msg1("Action Frame contain not support action field ", actionDetails); + break; + } + break; + case ZM_WLAN_BLOCK_ACK_ACTION_FRAME: + zfAggBlockAckActionFrame(dev, buf); + break; + case 17: //Qos Management + break; + } + + return 0; +} + +/* Determine the time not send beacon , if more than some value , + re-write the beacon start address */ +void zfReWriteBeaconStartAddress(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + wd->tickIbssSendBeacon++; // Increase 1 per 10ms . + zmw_leave_critical_section(dev); + + if ( wd->tickIbssSendBeacon == 40 ) + { +// DbgPrint("20070727"); + zfHpEnableBeacon(dev, ZM_MODE_IBSS, wd->beaconInterval, wd->dtim, (u8_t)wd->sta.atimWindow); + zmw_enter_critical_section(dev); + wd->tickIbssSendBeacon = 0; + zmw_leave_critical_section(dev); + } +} + +struct zsTkipSeed* zfStaGetRxSeed(zdev_t* dev, zbuf_t* buf) +{ + u8_t keyIndex; + u8_t da0; + + zmw_get_wlan_dev(dev); + + /* if need not check MIC, return NULL */ + if ( ((wd->sta.encryMode != ZM_TKIP)&&(wd->sta.encryMode != ZM_AES))|| + (wd->sta.wpaState < ZM_STA_WPA_STATE_PK_OK) ) + { + return NULL; + } + + da0 = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A1_OFFSET); + + if ((zmw_rx_buf_readb(dev, buf, 0) & 0x80) == 0x80) + keyIndex = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_IV_OFFSET+5); /* Qos Packet*/ + else + keyIndex = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_IV_OFFSET+3); /* normal Packet*/ + keyIndex = (keyIndex & 0xc0) >> 6; + + return (&wd->sta.rxSeed[keyIndex]); +} + +void zfStaEnableSWEncryption(zdev_t *dev, u8_t value) +{ + zmw_get_wlan_dev(dev); + + wd->sta.SWEncryptEnable = value; + zfHpSWDecrypt(dev, 1); + zfHpSWEncrypt(dev, 1); +} + +void zfStaDisableSWEncryption(zdev_t *dev) +{ + zmw_get_wlan_dev(dev); + + wd->sta.SWEncryptEnable = 0; + zfHpSWDecrypt(dev, 0); + zfHpSWEncrypt(dev, 0); +} + +u16_t zfComputeBssInfoWeightValue(zdev_t *dev, u8_t isBMode, u8_t isHT, u8_t isHT40, u8_t signalStrength) +{ + u8_t weightOfB = 0; + u8_t weightOfAGBelowThr = 0; + u8_t weightOfAGUpThr = 15; + u8_t weightOfN20BelowThr = 15; + u8_t weightOfN20UpThr = 30; + u8_t weightOfN40BelowThr = 16; + u8_t weightOfN40UpThr = 32; + + zmw_get_wlan_dev(dev); + + if( isBMode == 0 ) + return (signalStrength + weightOfB); // pure b mode , do not add the weight value for this AP ! + else + { + if( isHT == 0 && isHT40 == 0 ) + { // a , g , b/g mode ! add the weight value 15 for this AP if it's signal strength is more than some value ! + if( signalStrength < 18 ) // -77 dBm + return signalStrength + weightOfAGBelowThr; + else + return (signalStrength + weightOfAGUpThr); + } + else if( isHT == 1 && isHT40 == 0 ) + { // 80211n mode use 20MHz + if( signalStrength < 23 ) // -72 dBm + return (signalStrength + weightOfN20BelowThr); + else + return (signalStrength + weightOfN20UpThr); + } + else // isHT == 1 && isHT40 == 1 + { // 80211n mode use 40MHz + if( signalStrength < 16 ) // -79 dBm + return (signalStrength + weightOfN40BelowThr); + else + return (signalStrength + weightOfN40UpThr); + } + } +} + +u16_t zfStaAddIbssAdditionalIE(zdev_t* dev, zbuf_t* buf, u16_t offset) +{ + u16_t i; + + zmw_get_wlan_dev(dev); + + for (i=0; ista.ibssAdditionalIESize; i++) + { + zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.ibssAdditionalIE[i]); + } + + return offset; +} --- linux-2.6.28.orig/drivers/staging/otus/80211core/ctkip.c +++ linux-2.6.28/drivers/staging/otus/80211core/ctkip.c @@ -0,0 +1,598 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* */ +/* Module Name : ctkip.c */ +/* */ +/* Abstract */ +/* This module contains Tx and Rx functions. */ +/* */ +/* NOTES */ +/* None */ +/* */ +/************************************************************************/ +#include "cprecomp.h" + +u16_t zgTkipSboxLower[256] = + { + 0xA5,0x84,0x99,0x8D,0x0D,0xBD,0xB1,0x54, + 0x50,0x03,0xA9,0x7D,0x19,0x62,0xE6,0x9A, + 0x45,0x9D,0x40,0x87,0x15,0xEB,0xC9,0x0B, + 0xEC,0x67,0xFD,0xEA,0xBF,0xF7,0x96,0x5B, + 0xC2,0x1C,0xAE,0x6A,0x5A,0x41,0x02,0x4F, + 0x5C,0xF4,0x34,0x08,0x93,0x73,0x53,0x3F, + 0x0C,0x52,0x65,0x5E,0x28,0xA1,0x0F,0xB5, + 0x09,0x36,0x9B,0x3D,0x26,0x69,0xCD,0x9F, + 0x1B,0x9E,0x74,0x2E,0x2D,0xB2,0xEE,0xFB, + 0xF6,0x4D,0x61,0xCE,0x7B,0x3E,0x71,0x97, + 0xF5,0x68,0x00,0x2C,0x60,0x1F,0xC8,0xED, + 0xBE,0x46,0xD9,0x4B,0xDE,0xD4,0xE8,0x4A, + 0x6B,0x2A,0xE5,0x16,0xC5,0xD7,0x55,0x94, + 0xCF,0x10,0x06,0x81,0xF0,0x44,0xBA,0xE3, + 0xF3,0xFE,0xC0,0x8A,0xAD,0xBC,0x48,0x04, + 0xDF,0xC1,0x75,0x63,0x30,0x1A,0x0E,0x6D, + 0x4C,0x14,0x35,0x2F,0xE1,0xA2,0xCC,0x39, + 0x57,0xF2,0x82,0x47,0xAC,0xE7,0x2B,0x95, + 0xA0,0x98,0xD1,0x7F,0x66,0x7E,0xAB,0x83, + 0xCA,0x29,0xD3,0x3C,0x79,0xE2,0x1D,0x76, + 0x3B,0x56,0x4E,0x1E,0xDB,0x0A,0x6C,0xE4, + 0x5D,0x6E,0xEF,0xA6,0xA8,0xA4,0x37,0x8B, + 0x32,0x43,0x59,0xB7,0x8C,0x64,0xD2,0xE0, + 0xB4,0xFA,0x07,0x25,0xAF,0x8E,0xE9,0x18, + 0xD5,0x88,0x6F,0x72,0x24,0xF1,0xC7,0x51, + 0x23,0x7C,0x9C,0x21,0xDD,0xDC,0x86,0x85, + 0x90,0x42,0xC4,0xAA,0xD8,0x05,0x01,0x12, + 0xA3,0x5F,0xF9,0xD0,0x91,0x58,0x27,0xB9, + 0x38,0x13,0xB3,0x33,0xBB,0x70,0x89,0xA7, + 0xB6,0x22,0x92,0x20,0x49,0xFF,0x78,0x7A, + 0x8F,0xF8,0x80,0x17,0xDA,0x31,0xC6,0xB8, + 0xC3,0xB0,0x77,0x11,0xCB,0xFC,0xD6,0x3A + }; + + +u16_t zgTkipSboxUpper[256] = + { + 0xC6,0xF8,0xEE,0xF6,0xFF,0xD6,0xDE,0x91, + 0x60,0x02,0xCE,0x56,0xE7,0xB5,0x4D,0xEC, + 0x8F,0x1F,0x89,0xFA,0xEF,0xB2,0x8E,0xFB, + 0x41,0xB3,0x5F,0x45,0x23,0x53,0xE4,0x9B, + 0x75,0xE1,0x3D,0x4C,0x6C,0x7E,0xF5,0x83, + 0x68,0x51,0xD1,0xF9,0xE2,0xAB,0x62,0x2A, + 0x08,0x95,0x46,0x9D,0x30,0x37,0x0A,0x2F, + 0x0E,0x24,0x1B,0xDF,0xCD,0x4E,0x7F,0xEA, + 0x12,0x1D,0x58,0x34,0x36,0xDC,0xB4,0x5B, + 0xA4,0x76,0xB7,0x7D,0x52,0xDD,0x5E,0x13, + 0xA6,0xB9,0x00,0xC1,0x40,0xE3,0x79,0xB6, + 0xD4,0x8D,0x67,0x72,0x94,0x98,0xB0,0x85, + 0xBB,0xC5,0x4F,0xED,0x86,0x9A,0x66,0x11, + 0x8A,0xE9,0x04,0xFE,0xA0,0x78,0x25,0x4B, + 0xA2,0x5D,0x80,0x05,0x3F,0x21,0x70,0xF1, + 0x63,0x77,0xAF,0x42,0x20,0xE5,0xFD,0xBF, + 0x81,0x18,0x26,0xC3,0xBE,0x35,0x88,0x2E, + 0x93,0x55,0xFC,0x7A,0xC8,0xBA,0x32,0xE6, + 0xC0,0x19,0x9E,0xA3,0x44,0x54,0x3B,0x0B, + 0x8C,0xC7,0x6B,0x28,0xA7,0xBC,0x16,0xAD, + 0xDB,0x64,0x74,0x14,0x92,0x0C,0x48,0xB8, + 0x9F,0xBD,0x43,0xC4,0x39,0x31,0xD3,0xF2, + 0xD5,0x8B,0x6E,0xDA,0x01,0xB1,0x9C,0x49, + 0xD8,0xAC,0xF3,0xCF,0xCA,0xF4,0x47,0x10, + 0x6F,0xF0,0x4A,0x5C,0x38,0x57,0x73,0x97, + 0xCB,0xA1,0xE8,0x3E,0x96,0x61,0x0D,0x0F, + 0xE0,0x7C,0x71,0xCC,0x90,0x06,0xF7,0x1C, + 0xC2,0x6A,0xAE,0x69,0x17,0x99,0x3A,0x27, + 0xD9,0xEB,0x2B,0x22,0xD2,0xA9,0x07,0x33, + 0x2D,0x3C,0x15,0xC9,0x87,0xAA,0x50,0xA5, + 0x03,0x59,0x09,0x1A,0x65,0xD7,0x84,0xD0, + 0x82,0x29,0x5A,0x1E,0x7B,0xA8,0x6D,0x2C + }; + +u16_t zfrotr1(u16_t a) +// rotate right by 1 bit. +{ + u16_t b; + + if (a & 0x01) + { + b = (a >> 1) | 0x8000; + } + else + { + b = (a >> 1) & 0x7fff; + } + return b; +} + +/*************************************************************/ +/* zfTkipSbox() */ +/* Returns a 16 bit value from a 64K entry table. The Table */ +/* is synthesized from two 256 entry byte wide tables. */ +/*************************************************************/ +u16_t zfTkipSbox(u16_t index) +{ + u16_t low; + u16_t high; + u16_t left, right; + + low = (index & 0xFF); + high = ((index >> 8) & 0xFF); + + left = zgTkipSboxLower[low] + (zgTkipSboxUpper[low] << 8 ); + right = zgTkipSboxUpper[high] + (zgTkipSboxLower[high] << 8 ); + + return (left ^ right); +} + +u8_t zfTkipPhase1KeyMix(u32_t iv32, struct zsTkipSeed* pSeed) +{ + u16_t tsc0; + u16_t tsc1; + u16_t i, j; +#if 0 + /* Need not proceed this function with the same iv32 */ + if ( iv32 == pSeed->iv32 ) + { + return 1; + } +#endif + tsc0 = (u16_t) ((iv32 >> 16) & 0xffff); /* msb */ + tsc1 = (u16_t) (iv32 & 0xffff); + + /* Phase 1, step 1 */ + pSeed->ttak[0] = tsc1; + pSeed->ttak[1] = tsc0; + pSeed->ttak[2] = (u16_t) (pSeed->ta[0] + (pSeed->ta[1] <<8)); + pSeed->ttak[3] = (u16_t) (pSeed->ta[2] + (pSeed->ta[3] <<8)); + pSeed->ttak[4] = (u16_t) (pSeed->ta[4] + (pSeed->ta[5] <<8)); + + /* Phase 1, step 2 */ + for (i=0; i<8; i++) + { + j = 2*(i & 1); + pSeed->ttak[0] =(pSeed->ttak[0] + zfTkipSbox(pSeed->ttak[4] + ^ ZM_BYTE_TO_WORD(pSeed->tk[1+j], pSeed->tk[j]))) + & 0xffff; + pSeed->ttak[1] =(pSeed->ttak[1] + zfTkipSbox(pSeed->ttak[0] + ^ ZM_BYTE_TO_WORD(pSeed->tk[5+j], pSeed->tk[4+j] ))) + & 0xffff; + pSeed->ttak[2] =(pSeed->ttak[2] + zfTkipSbox(pSeed->ttak[1] + ^ ZM_BYTE_TO_WORD(pSeed->tk[9+j], pSeed->tk[8+j] ))) + & 0xffff; + pSeed->ttak[3] =(pSeed->ttak[3] + zfTkipSbox(pSeed->ttak[2] + ^ ZM_BYTE_TO_WORD(pSeed->tk[13+j], pSeed->tk[12+j]))) + & 0xffff; + pSeed->ttak[4] =(pSeed->ttak[4] + zfTkipSbox(pSeed->ttak[3] + ^ ZM_BYTE_TO_WORD(pSeed->tk[1+j], pSeed->tk[j] ))) + & 0xffff; + pSeed->ttak[4] =(pSeed->ttak[4] + i) & 0xffff; + } + + if ( iv32 == (pSeed->iv32+1) ) + { + pSeed->iv32tmp = iv32; + return 1; + } + + return 0; +} + +u8_t zfTkipPhase2KeyMix(u16_t iv16, struct zsTkipSeed* pSeed) +{ + u16_t tsc2; + + tsc2 = iv16; + + /* Phase 2, Step 1 */ + pSeed->ppk[0] = pSeed->ttak[0]; + pSeed->ppk[1] = pSeed->ttak[1]; + pSeed->ppk[2] = pSeed->ttak[2]; + pSeed->ppk[3] = pSeed->ttak[3]; + pSeed->ppk[4] = pSeed->ttak[4]; + pSeed->ppk[5] = (pSeed->ttak[4] + tsc2) & 0xffff; + + /* Phase2, Step 2 */ + pSeed->ppk[0] = pSeed->ppk[0] + + zfTkipSbox(pSeed->ppk[5] ^ ZM_BYTE_TO_WORD(pSeed->tk[1],pSeed->tk[0])); + pSeed->ppk[1] = pSeed->ppk[1] + + zfTkipSbox(pSeed->ppk[0] ^ ZM_BYTE_TO_WORD(pSeed->tk[3],pSeed->tk[2])); + pSeed->ppk[2] = pSeed->ppk[2] + + zfTkipSbox(pSeed->ppk[1] ^ ZM_BYTE_TO_WORD(pSeed->tk[5],pSeed->tk[4])); + pSeed->ppk[3] = pSeed->ppk[3] + + zfTkipSbox(pSeed->ppk[2] ^ ZM_BYTE_TO_WORD(pSeed->tk[7],pSeed->tk[6])); + pSeed->ppk[4] = pSeed->ppk[4] + + zfTkipSbox(pSeed->ppk[3] ^ ZM_BYTE_TO_WORD(pSeed->tk[9],pSeed->tk[8])); + pSeed->ppk[5] = pSeed->ppk[5] + + zfTkipSbox(pSeed->ppk[4] ^ ZM_BYTE_TO_WORD(pSeed->tk[11],pSeed->tk[10])); + + pSeed->ppk[0] = pSeed->ppk[0] + + zfrotr1(pSeed->ppk[5] ^ ZM_BYTE_TO_WORD(pSeed->tk[13],pSeed->tk[12])); + pSeed->ppk[1] = pSeed->ppk[1] + + zfrotr1(pSeed->ppk[0] ^ ZM_BYTE_TO_WORD(pSeed->tk[15],pSeed->tk[14])); + pSeed->ppk[2] = pSeed->ppk[2] + zfrotr1(pSeed->ppk[1]); + pSeed->ppk[3] = pSeed->ppk[3] + zfrotr1(pSeed->ppk[2]); + pSeed->ppk[4] = pSeed->ppk[4] + zfrotr1(pSeed->ppk[3]); + pSeed->ppk[5] = pSeed->ppk[5] + zfrotr1(pSeed->ppk[4]); + + if (iv16 == 0) + { + if (pSeed->iv16 == 0xffff) + { + pSeed->iv16tmp=0; + return 1; + } + else + return 0; + } + else if (iv16 == (pSeed->iv16+1)) + { + pSeed->iv16tmp = iv16; + return 1; + } + else + return 0; +} + +void zfTkipInit(u8_t* key, u8_t* ta, struct zsTkipSeed* pSeed, u8_t* initIv) +{ + u16_t iv16; + u32_t iv32; + u16_t i; + + /* clear memory */ + zfZeroMemory((u8_t*) pSeed, sizeof(struct zsTkipSeed)); + /* set key to seed */ + zfMemoryCopy(pSeed->ta, ta, 6); + zfMemoryCopy(pSeed->tk, key, 16); + + iv16 = *initIv++; + iv16 += *initIv<<8; + initIv++; + + iv32=0; + + for(i=0; i<4; i++) // initiv is little endian + { + iv32 += *initIv<<(i*8); + *initIv++; + } + + pSeed->iv32 = iv32+1; // Force Recalculating on Tkip Phase1 + zfTkipPhase1KeyMix(iv32, pSeed); + + pSeed->iv16 = iv16; + pSeed->iv32 = iv32; +} + +u32_t zfGetU32t(u8_t* p) +{ + u32_t res=0; + u16_t i; + + for( i=0; i<4; i++ ) + { + res |= (*p++) << (8*i); + } + + return res; + +} + +void zfPutU32t(u8_t* p, u32_t value) +{ + u16_t i; + + for(i=0; i<4; i++) + { + *p++ = (u8_t) (value & 0xff); + value >>= 8; + } +} + +void zfMicClear(struct zsMicVar* pMic) +{ + pMic->left = pMic->k0; + pMic->right = pMic->k1; + pMic->nBytes = 0; + pMic->m = 0; +} + +void zfMicSetKey(u8_t* key, struct zsMicVar* pMic) +{ + pMic->k0 = zfGetU32t(key); + pMic->k1 = zfGetU32t(key+4); + zfMicClear(pMic); +} + +void zfMicAppendByte(u8_t b, struct zsMicVar* pMic) +{ + // Append the byte to our word-sized buffer + pMic->m |= b << (8* pMic->nBytes); + pMic->nBytes++; + + // Process the word if it is full. + if ( pMic->nBytes >= 4 ) + { + pMic->left ^= pMic->m; + pMic->right ^= ZM_ROL32(pMic->left, 17 ); + pMic->left += pMic->right; + pMic->right ^= ((pMic->left & 0xff00ff00) >> 8) | + ((pMic->left & 0x00ff00ff) << 8); + pMic->left += pMic->right; + pMic->right ^= ZM_ROL32( pMic->left, 3 ); + pMic->left += pMic->right; + pMic->right ^= ZM_ROR32( pMic->left, 2 ); + pMic->left += pMic->right; + // Clear the buffer + pMic->m = 0; + pMic->nBytes = 0; + } +} + +void zfMicGetMic(u8_t* dst, struct zsMicVar* pMic) +{ + // Append the minimum padding + zfMicAppendByte(0x5a, pMic); + zfMicAppendByte(0, pMic); + zfMicAppendByte(0, pMic); + zfMicAppendByte(0, pMic); + zfMicAppendByte(0, pMic); + + // and then zeroes until the length is a multiple of 4 + while( pMic->nBytes != 0 ) + { + zfMicAppendByte(0, pMic); + } + + // The appendByte function has already computed the result. + zfPutU32t(dst, pMic->left); + zfPutU32t(dst+4, pMic->right); + + // Reset to the empty message. + zfMicClear(pMic); + +} + +u8_t zfMicRxVerify(zdev_t* dev, zbuf_t* buf) +{ + struct zsMicVar* pMicKey; + struct zsMicVar MyMicKey; + u8_t mic[8]; + u8_t da[6]; + u8_t sa[6]; + u8_t bValue; + u16_t i, payloadOffset, tailOffset; + + zmw_get_wlan_dev(dev); + + /* need not check MIC if pMicKEy is equal to NULL */ + if ( wd->wlanMode == ZM_MODE_AP ) + { + pMicKey = zfApGetRxMicKey(dev, buf); + + if ( pMicKey != NULL ) + { + zfCopyFromRxBuffer(dev, buf, sa, ZM_WLAN_HEADER_A2_OFFSET, 6); + zfCopyFromRxBuffer(dev, buf, da, ZM_WLAN_HEADER_A3_OFFSET, 6); + } + else + { + return ZM_MIC_SUCCESS; + } + } + else if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) + { + pMicKey = zfStaGetRxMicKey(dev, buf); + + if ( pMicKey != NULL ) + { + zfCopyFromRxBuffer(dev, buf, sa, ZM_WLAN_HEADER_A3_OFFSET, 6); + zfCopyFromRxBuffer(dev, buf, da, ZM_WLAN_HEADER_A1_OFFSET, 6); + } + else + { + return ZM_MIC_SUCCESS; + } + } + else + { + return ZM_MIC_SUCCESS; + } + + MyMicKey.k0=pMicKey->k0; + MyMicKey.k1=pMicKey->k1; + pMicKey = &MyMicKey; + + zfMicClear(pMicKey); + tailOffset = zfwBufGetSize(dev, buf); + tailOffset -= 8; + + /* append DA */ + for(i=0; i<6; i++) + { + zfMicAppendByte(da[i], pMicKey); + } + /* append SA */ + for(i=0; i<6; i++) + { + zfMicAppendByte(sa[i], pMicKey); + } + + /* append for alignment */ + if ((zmw_rx_buf_readb(dev, buf, 0) & 0x80) != 0) + zfMicAppendByte(zmw_rx_buf_readb(dev, buf,24)&0x7, pMicKey); + else + zfMicAppendByte(0, pMicKey); + zfMicAppendByte(0, pMicKey); + zfMicAppendByte(0, pMicKey); + zfMicAppendByte(0, pMicKey); + + /* append payload */ + payloadOffset = ZM_SIZE_OF_WLAN_DATA_HEADER + + ZM_SIZE_OF_IV + + ZM_SIZE_OF_EXT_IV; + + if ((zmw_rx_buf_readb(dev, buf, 0) & 0x80) != 0) + { + /* Qos Packet, Plcpheader + 2 */ + if (wd->wlanMode == ZM_MODE_AP) + { + /* TODO : Rx Qos element offset in software MIC check */ + } + else if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) + { + if (wd->sta.wmeConnected != 0) + { + payloadOffset += 2; + } + } + } + + for(i=payloadOffset; ippk[5] ^ ZM_BYTE_TO_WORD(Seed->tk[1],Seed->tk[0]))>>1) & 0xff; + RC4Key[4] = Seed->ppk[0] & 0xff; + RC4Key[5] = Seed->ppk[0] >> 8; + RC4Key[6] = Seed->ppk[1] & 0xff; + RC4Key[7] = Seed->ppk[1] >> 8; + RC4Key[8] = Seed->ppk[2] & 0xff; + RC4Key[9] = Seed->ppk[2] >> 8; + RC4Key[10] = Seed->ppk[3] & 0xff; + RC4Key[11] = Seed->ppk[3] >> 8; + RC4Key[12] = Seed->ppk[4] & 0xff; + RC4Key[13] = Seed->ppk[4] >> 8; + RC4Key[14] = Seed->ppk[5] & 0xff; + RC4Key[15] = Seed->ppk[5] >> 8; +} + +void zfCalTxMic(zdev_t *dev, zbuf_t *buf, u8_t *snap, u16_t snapLen, u16_t offset, u16_t *da, u16_t *sa, u8_t up, u8_t *mic) +{ + struct zsMicVar* pMicKey; + u16_t i; + u16_t len; + u8_t bValue; + u8_t qosType; + u8_t *pDa = (u8_t *)da; + u8_t *pSa = (u8_t *)sa; + + zmw_get_wlan_dev(dev); + + /* need not check MIC if pMicKEy is equal to NULL */ + if ( wd->wlanMode == ZM_MODE_AP ) + { + pMicKey = zfApGetTxMicKey(dev, buf, &qosType); + + if ( pMicKey == NULL ) + return; + } + else if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) + { + pMicKey = zfStaGetTxMicKey(dev, buf); + + if ( pMicKey == NULL ) + { + zm_debug_msg0("pMicKey is NULL"); + return; + } + } + else + { + return; + } + + zfMicClear(pMicKey); + len = zfwBufGetSize(dev, buf); + + /* append DA */ + for(i = 0; i < 6; i++) + { + zfMicAppendByte(pDa[i], pMicKey); + } + + /* append SA */ + for(i = 0; i < 6; i++) + { + zfMicAppendByte(pSa[i], pMicKey); + } + + if (up != 0) + zfMicAppendByte((up&0x7), pMicKey); + else + zfMicAppendByte(0, pMicKey); + + zfMicAppendByte(0, pMicKey); + zfMicAppendByte(0, pMicKey); + zfMicAppendByte(0, pMicKey); + + /* For Snap header */ + for(i = 0; i < snapLen; i++) + { + zfMicAppendByte(snap[i], pMicKey); + } + + for(i = offset; i < len; i++) + { + bValue = zmw_tx_buf_readb(dev, buf, i); + zfMicAppendByte(bValue, pMicKey); + } + + zfMicGetMic(mic, pMicKey); +} + +void zfTKIPEncrypt(zdev_t *dev, zbuf_t *buf, u8_t *snap, u16_t snapLen, u16_t offset, u8_t keyLen, u8_t* key, u32_t* icv) +{ + u8_t iv[3]; + + iv[0] = key[0]; + iv[1] = key[1]; + iv[2] = key[2]; + + keyLen -= 3; + + zfWEPEncrypt(dev, buf, snap, snapLen, offset, keyLen, &key[3], iv); +} + +u16_t zfTKIPDecrypt(zdev_t *dev, zbuf_t *buf, u16_t offset, u8_t keyLen, u8_t* key) +{ + u16_t ret = ZM_ICV_SUCCESS; + u8_t iv[3]; + + iv[0] = key[0]; + iv[1] = key[1]; + iv[2] = key[2]; + + keyLen -= 3; + + ret = zfWEPDecrypt(dev, buf, offset, keyLen, &key[3], iv); + + return ret; +} --- linux-2.6.28.orig/drivers/staging/otus/80211core/cmmap.c +++ linux-2.6.28/drivers/staging/otus/80211core/cmmap.c @@ -0,0 +1,2402 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* */ +/* Module Name : mm.c */ +/* */ +/* Abstract */ +/* This module contains common functions for handle AP */ +/* management frame. */ +/* */ +/* NOTES */ +/* None */ +/* */ +/************************************************************************/ +#include "cprecomp.h" +#include "ratectrl.h" + +extern const u8_t zcUpToAc[]; + +void zfMmApTimeTick(zdev_t* dev) +{ + u32_t now; + zmw_get_wlan_dev(dev); + + //zm_debug_msg1("wd->wlanMode : ", wd->wlanMode); + if (wd->wlanMode == ZM_MODE_AP) + { + /* => every 1.28 seconds */ + /* AP : aging STA that does not active for wd->ap.staAgingTime */ + now = wd->tick & 0x7f; + if (now == 0x0) + { + zfApAgingSta(dev); + } + else if (now == 0x1f) + { + zfQueueAge(dev, wd->ap.uapsdQ, wd->tick, 10000); + } + /* AP : check (wd->ap.protectedObss) and (wd->ap.bStaAssociated) */ + /* to enable NonErp and Protection mode */ + else if (now == 0x3f) + { + //zfApProtctionMonitor(dev); + } + } +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfApInitStaTbl */ +/* Init AP's station table. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2005.10 */ +/* */ +/************************************************************************/ +void zfApInitStaTbl(zdev_t* dev) +{ + u16_t i; + + zmw_get_wlan_dev(dev); + + for (i=0; iap.staTable[i].valid = 0; + wd->ap.staTable[i].state = 0; + wd->ap.staTable[i].addr[0] = 0; + wd->ap.staTable[i].addr[1] = 0; + wd->ap.staTable[i].addr[2] = 0; + wd->ap.staTable[i].time = 0; + wd->ap.staTable[i].vap = 0; + wd->ap.staTable[i].encryMode = ZM_NO_WEP; + } + return; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfApFindSta */ +/* Find a STA in station table. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* addr : Target STA address */ +/* */ +/* OUTPUTS */ +/* 0xffff : fail */ +/* other : STA table index */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2005.10 */ +/* */ +/************************************************************************/ +u16_t zfApFindSta(zdev_t* dev, u16_t* addr) +{ + u16_t i; + + zmw_get_wlan_dev(dev); + + for (i=0; iap.staTable[i].valid == 1) + { + if ((wd->ap.staTable[i].addr[0] == addr[0]) + && (wd->ap.staTable[i].addr[1] == addr[1]) + && (wd->ap.staTable[i].addr[2] == addr[2])) + { + return i; + } + } + } + return 0xffff; +} + +u16_t zfApGetSTAInfo(zdev_t* dev, u16_t* addr, u16_t* state, u8_t* vap) +{ + u16_t id; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + if ((id = zfApFindSta(dev, addr)) != 0xffff) + { + *vap = wd->ap.staTable[id].vap; + *state = wd->ap.staTable[id++].state; + } + + zmw_leave_critical_section(dev); + + return id; +} + + +void zfApGetStaQosType(zdev_t* dev, u16_t* addr, u8_t* qosType) +{ + u16_t id; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + if ((id = zfApFindSta(dev, addr)) != 0xffff) + { + *qosType = wd->ap.staTable[id].qosType; + } + else + { + *qosType = 0; + } + + zmw_leave_critical_section(dev); + + return; +} + +void zfApGetStaTxRateAndQosType(zdev_t* dev, u16_t* addr, u32_t* phyCtrl, + u8_t* qosType, u16_t* rcProbingFlag) +{ + u16_t id; + u8_t rate; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + if ((id = zfApFindSta(dev, addr)) != 0xffff) + { + rate = (u8_t)zfRateCtrlGetTxRate(dev, &wd->ap.staTable[id].rcCell, rcProbingFlag); +#ifdef ZM_AP_DEBUG + //rate = 15; +#endif + *phyCtrl = zcRateToPhyCtrl[rate]; + *qosType = wd->ap.staTable[id].qosType; + } + else + { + if (wd->frequency < 3000) + { + /* CCK 1M */ + //header[2] = 0x0f00; //PHY control L + //header[3] = 0x0000; //PHY control H + *phyCtrl = 0x00000F00; + } + else + { + /* CCK 6M */ + //header[2] = 0x0f01; //PHY control L + //header[3] = 0x000B; //PHY control H + *phyCtrl = 0x000B0F01; + } + *qosType = 0; + } + + zmw_leave_critical_section(dev); + + zm_msg2_mm(ZM_LV_3, "PhyCtrl=", *phyCtrl); + return; +} + +void zfApGetStaEncryType(zdev_t* dev, u16_t* addr, u8_t* encryType) +{ + //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev); + u16_t id; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + if ((id = zfApFindSta(dev, addr)) != 0xffff) + { + *encryType = wd->ap.staTable[id].encryMode; + } + else + { + *encryType = ZM_NO_WEP; + } + + zmw_leave_critical_section(dev); + + zm_msg2_mm(ZM_LV_3, "encyrType=", *encryType); + return; +} + +void zfApGetStaWpaIv(zdev_t* dev, u16_t* addr, u16_t* iv16, u32_t* iv32) +{ + //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev); + u16_t id; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + if ((id = zfApFindSta(dev, addr)) != 0xffff) + { + *iv16 = wd->ap.staTable[id].iv16; + *iv32 = wd->ap.staTable[id].iv32; + } + else + { + *iv16 = 0; + *iv32 = 0; + } + + zmw_leave_critical_section(dev); + + zm_msg2_mm(ZM_LV_3, "iv16=", *iv16); + zm_msg2_mm(ZM_LV_3, "iv32=", *iv32); + return; +} + +void zfApSetStaWpaIv(zdev_t* dev, u16_t* addr, u16_t iv16, u32_t iv32) +{ + //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev); + u16_t id; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + if ((id = zfApFindSta(dev, addr)) != 0xffff) + { + wd->ap.staTable[id].iv16 = iv16; + wd->ap.staTable[id].iv32 = iv32; + } + + zmw_leave_critical_section(dev); + + zm_msg2_mm(ZM_LV_3, "iv16=", iv16); + zm_msg2_mm(ZM_LV_3, "iv32=", iv32); + return; +} + +void zfApClearStaKey(zdev_t* dev, u16_t* addr) +{ + //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev); + u16_t bcAddr[3] = { 0xffff, 0xffff, 0xffff }; + u16_t id; + + zmw_get_wlan_dev(dev); + + if (zfMemoryIsEqual((u8_t*)bcAddr, (u8_t*)addr, sizeof(bcAddr)) == TRUE) + { + /* Turn off group key information */ + // zfClearKey(dev, 0); + } + else + { + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + if ((id = zfApFindSta(dev, addr)) != 0xffff) + { + /* Turn off STA's key information */ + zfHpRemoveKey(dev, id+1); + + /* Update STA's Encryption Type */ + wd->ap.staTable[id].encryMode = ZM_NO_WEP; + } + else + { + zm_msg0_mm(ZM_LV_3, "Can't find STA address\n"); + } + zmw_leave_critical_section(dev); + } +} + +#ifdef ZM_ENABLE_CENC +void zfApGetStaCencIvAndKeyIdx(zdev_t* dev, u16_t* addr, u32_t *iv, u8_t *keyIdx) +{ + //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev); + u16_t id; + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + + zmw_enter_critical_section(dev); + + if ((id = zfApFindSta(dev, addr)) != 0xffff) + { + *iv++ = wd->ap.staTable[id].txiv[0]; + *iv++ = wd->ap.staTable[id].txiv[1]; + *iv++ = wd->ap.staTable[id].txiv[2]; + *iv = wd->ap.staTable[id].txiv[3]; + *keyIdx = wd->ap.staTable[id].cencKeyIdx; + } + else + { + *iv++ = 0x5c365c37; + *iv++ = 0x5c365c36; + *iv++ = 0x5c365c36; + *iv = 0x5c365c36; + *keyIdx = 0; + } + + zmw_leave_critical_section(dev); + return; +} + +void zfApSetStaCencIv(zdev_t* dev, u16_t* addr, u32_t *iv) +{ + //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev); + u16_t id; + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + + zmw_enter_critical_section(dev); + + if ((id = zfApFindSta(dev, addr)) != 0xffff) + { + wd->ap.staTable[id].txiv[0] = *iv++; + wd->ap.staTable[id].txiv[1] = *iv++; + wd->ap.staTable[id].txiv[2] = *iv++; + wd->ap.staTable[id].txiv[3] = *iv; + } + + zmw_leave_critical_section(dev); + + return; +} +#endif //ZM_ENABLE_CENC + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfApFlushBufferedPsFrame */ +/* Free buffered PS frames. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Stephen Chen Atheros Communications, INC. 2007.1 */ +/* */ +/************************************************************************/ +void zfApFlushBufferedPsFrame(zdev_t* dev) +{ + u16_t emptyFlag; + u16_t freeCount; + u16_t vap; + zbuf_t* psBuf = NULL; + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + freeCount = 0; + emptyFlag = 0; + while (1) + { + psBuf = NULL; + zmw_enter_critical_section(dev); + if (wd->ap.uniHead != wd->ap.uniTail) + { + psBuf = wd->ap.uniArray[wd->ap.uniHead]; + wd->ap.uniHead = (wd->ap.uniHead + 1) & (ZM_UNI_ARRAY_SIZE - 1); + } + else + { + emptyFlag = 1; + } + zmw_leave_critical_section(dev); + + if (psBuf != NULL) + { + zfwBufFree(dev, psBuf, ZM_ERR_FLUSH_PS_QUEUE); + } + zm_assert(freeCount++ < (ZM_UNI_ARRAY_SIZE*2)); + + if (emptyFlag != 0) + { + break; + } + } + + for (vap=0; vapap.bcmcHead[vap] != wd->ap.bcmcTail[vap]) + { + psBuf = wd->ap.bcmcArray[vap][wd->ap.bcmcHead[vap]]; + wd->ap.bcmcHead[vap] = (wd->ap.bcmcHead[vap] + 1) + & (ZM_BCMC_ARRAY_SIZE - 1); + } + else + { + emptyFlag = 1; + } + zmw_leave_critical_section(dev); + + if (psBuf != NULL) + { + zfwBufFree(dev, psBuf, ZM_ERR_FLUSH_PS_QUEUE); + } + zm_assert(freeCount++ < (ZM_BCMC_ARRAY_SIZE*2)); + + if (emptyFlag != 0) + { + break; + } + } + } + return; +} + + +u16_t zfApBufferPsFrame(zdev_t* dev, zbuf_t* buf, u16_t port) +{ + u16_t id; + u16_t addr[3]; + u16_t vap = 0; + u8_t up; + u16_t fragOff; + u8_t ac; + u16_t ret; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + if (port < ZM_MAX_AP_SUPPORT) + { + vap = port; + } + + addr[0] = zmw_rx_buf_readh(dev, buf, 0); + addr[1] = zmw_rx_buf_readh(dev, buf, 2); + addr[2] = zmw_rx_buf_readh(dev, buf, 4); + + if ((addr[0] & 0x1) == 0x1) + { + if (wd->ap.staPowerSaving > 0) + { + zmw_enter_critical_section(dev); + + /* Buffer this BC or MC frame */ + if (((wd->ap.bcmcTail[vap]+1)&(ZM_BCMC_ARRAY_SIZE-1)) + != wd->ap.bcmcHead[vap]) + { + wd->ap.bcmcArray[vap][wd->ap.bcmcTail[vap]++] = buf; + wd->ap.bcmcTail[vap] &= (ZM_BCMC_ARRAY_SIZE-1); + zmw_leave_critical_section(dev); + + zm_msg0_tx(ZM_LV_0, "Buffer BCMC"); + } + else + { + /* bcmcArray full */ + zmw_leave_critical_section(dev); + + zm_msg0_tx(ZM_LV_0, "BCMC buffer full"); + + /* free buffer according to buffer type */ + zfwBufFree(dev, buf, ZM_ERR_BCMC_PS_BUFFER_UNAVAILABLE); + } + return 1; + } + } + else + { + zmw_enter_critical_section(dev); + + if ((id = zfApFindSta(dev, addr)) != 0xffff) + { + if (wd->ap.staTable[id].psMode == 1) + { + + zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff); + ac = zcUpToAc[up&0x7] & 0x3; + + if ((wd->ap.staTable[id].qosType == 1) && + ((wd->ap.staTable[id].qosInfo & (0x8>>ac)) != 0)) + { + ret = zfQueuePutNcs(dev, wd->ap.uapsdQ, buf, wd->tick); + zmw_leave_critical_section(dev); + if (ret != ZM_SUCCESS) + { + zfwBufFree(dev, buf, ZM_ERR_AP_UAPSD_QUEUE_FULL); + } + } + else + { + /* Buffer this unicast frame */ + if (((wd->ap.uniTail+1)&(ZM_UNI_ARRAY_SIZE-1)) + != wd->ap.uniHead) + { + wd->ap.uniArray[wd->ap.uniTail++] = buf; + wd->ap.uniTail &= (ZM_UNI_ARRAY_SIZE-1); + zmw_leave_critical_section(dev); + zm_msg0_tx(ZM_LV_0, "Buffer UNI"); + + } + else + { + /* uniArray full */ + zmw_leave_critical_section(dev); + zm_msg0_tx(ZM_LV_0, "UNI buffer full"); + /* free buffer according to buffer type */ + zfwBufFree(dev, buf, ZM_ERR_UNI_PS_BUFFER_UNAVAILABLE); + } + } + return 1; + } /* if (wd->ap.staTable[id++].psMode == 1) */ + } /* if ((id = zfApFindSta(dev, addr)) != 0xffff) */ + zmw_leave_critical_section(dev); + } + + return 0; +} + +u16_t zfApGetSTAInfoAndUpdatePs(zdev_t* dev, u16_t* addr, u16_t* state, + u8_t* vap, u16_t psMode, u8_t* uapsdTrig) +{ + u16_t id; + u8_t uapsdStaAwake = 0; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + +#ifdef ZM_AP_DEBUG + //psMode=0; +#endif + + if ((id = zfApFindSta(dev, addr)) != 0xffff) + { + if (psMode != 0) + { + zm_msg0_mm(ZM_LV_0, "psMode = 1"); + if (wd->ap.staTable[id].psMode == 0) + { + wd->ap.staPowerSaving++; + } + else + { + if (wd->ap.staTable[id].qosType == 1) + { + zm_msg0_mm(ZM_LV_0, "UAPSD trigger"); + *uapsdTrig = wd->ap.staTable[id].qosInfo; + } + } + } + else + { + if (wd->ap.staTable[id].psMode != 0) + { + wd->ap.staPowerSaving--; + if ((wd->ap.staTable[id].qosType == 1) && ((wd->ap.staTable[id].qosInfo&0xf)!=0)) + { + uapsdStaAwake = 1; + } + } + } + + wd->ap.staTable[id].psMode = (u8_t) psMode; + wd->ap.staTable[id].time = wd->tick; + *vap = wd->ap.staTable[id].vap; + *state = wd->ap.staTable[id++].state; + } + + zmw_leave_critical_section(dev); + + if (uapsdStaAwake == 1) + { + zbuf_t* psBuf; + u8_t mb; + + while (1) + { + if ((psBuf = zfQueueGetWithMac(dev, wd->ap.uapsdQ, (u8_t*)addr, &mb)) != NULL) + { + zfTxSendEth(dev, psBuf, 0, ZM_EXTERNAL_ALLOC_BUF, 0); + } + else + { + break; + } + } + } + + return id; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfApGetNewSta */ +/* Get a new STA from station table. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* 0xffff : fail */ +/* other : STA table index */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2005.10 */ +/* */ +/************************************************************************/ +u16_t zfApGetNewSta(zdev_t* dev) +{ + u16_t i; + + zmw_get_wlan_dev(dev); + + for (i=0; iap.staTable[i].valid == 0) + { + zm_msg2_mm(ZM_LV_0, "zfApGetNewSta=", i); + return i; + } + } + return 0xffff; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfApAddSta */ +/* Add a STA to station table. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* addr : STA MAC address */ +/* state : STA state */ +/* apId : Virtual AP ID */ +/* type : 0=>11b, 1=>11g */ +/* */ +/* OUTPUTS */ +/* 0xffff : fail */ +/* Other : index */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2005.10 */ +/* */ +/************************************************************************/ +u16_t zfApAddSta(zdev_t* dev, u16_t* addr, u16_t state, u16_t apId, u8_t type, + u8_t qosType, u8_t qosInfo) +{ + u16_t index; + u16_t i; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zm_msg1_mm(ZM_LV_0, "STA type=", type); + + zmw_enter_critical_section(dev); + + if ((index = zfApFindSta(dev, addr)) != 0xffff) + { + zm_msg0_mm(ZM_LV_2, "found"); + /* Update STA state */ + if ((state == ZM_STATE_AUTH) || (state == ZM_STATE_PREAUTH)) + { + wd->ap.staTable[index].state = state; + wd->ap.staTable[index].time = wd->tick; + wd->ap.staTable[index].vap = (u8_t)apId; + } + else if (state == ZM_STATE_ASOC) + { + if ((wd->ap.staTable[index].state == ZM_STATE_AUTH)) + //&& (wd->ap.staTable[index].vap == apId)) + { + wd->ap.staTable[index].state = state; + wd->ap.staTable[index].time = wd->tick; + wd->ap.staTable[index].qosType = qosType; + wd->ap.staTable[index].vap = (u8_t)apId; + wd->ap.staTable[index].staType = type; + wd->ap.staTable[index].qosInfo = qosInfo; + + if (wd->frequency < 3000) + { + /* Init 11b/g */ + zfRateCtrlInitCell(dev, &wd->ap.staTable[index].rcCell, type, 1, 1); + } + else + { + /* Init 11a */ + zfRateCtrlInitCell(dev, &wd->ap.staTable[index].rcCell, type, 0, 1); + } + + if (wd->zfcbApConnectNotify != NULL) + { + wd->zfcbApConnectNotify(dev, (u8_t*)addr, apId); + } + } + else + { + index = 0xffff; + } + } + } + else + { + zm_msg0_mm(ZM_LV_2, "Not found"); + if ((state == ZM_STATE_AUTH) || (state == ZM_STATE_PREAUTH)) + { + /* Get a new STA and update state */ + index = zfApGetNewSta(dev); + zm_msg2_mm(ZM_LV_1, "new STA index=", index); + + if (index != 0xffff) + { + for (i=0; i<3; i++) + { + wd->ap.staTable[index].addr[i] = addr[i]; + } + wd->ap.staTable[index].state = state; + wd->ap.staTable[index].valid = 1; + wd->ap.staTable[index].time = wd->tick; + wd->ap.staTable[index].vap = (u8_t)apId; + wd->ap.staTable[index].encryMode = ZM_NO_WEP; + } + } + } + + zmw_leave_critical_section(dev); + + return index; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfApAgingSta */ +/* Aging STA in station table. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* number of 11b STA in STA table */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2005.10 */ +/* */ +/************************************************************************/ +void zfApAgingSta(zdev_t* dev) +{ + u16_t i; + u32_t deltaMs; + u16_t addr[3]; + u16_t txFlag; + u16_t psStaCount = 0; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + wd->ap.gStaAssociated = wd->ap.bStaAssociated = 0; + + for (i=0; iap.staTable[i].valid == 1) + { + addr[0] = wd->ap.staTable[i].addr[0]; + addr[1] = wd->ap.staTable[i].addr[1]; + addr[2] = wd->ap.staTable[i].addr[2]; + /* millisecond */ + deltaMs = (u32_t)((u32_t)wd->tick-(u32_t)wd->ap.staTable[i].time) + * ZM_MS_PER_TICK; + + /* preauth */ + if ((wd->ap.staTable[i].state == ZM_STATE_PREAUTH) + && (deltaMs > ZM_PREAUTH_TIMEOUT_MS)) + { + /* Aging STA */ + wd->ap.staTable[i].valid = 0; + wd->ap.authSharing = 0; + txFlag = 1; + } + + /* auth */ + if ((wd->ap.staTable[i].state == ZM_STATE_AUTH) + && (deltaMs > ZM_AUTH_TIMEOUT_MS)) + { + /* Aging STA */ + wd->ap.staTable[i].valid = 0; + txFlag = 1; + } + + /* asoc */ + if (wd->ap.staTable[i].state == ZM_STATE_ASOC) + { + if (wd->ap.staTable[i].psMode != 0) + { + psStaCount++; + } + + if (deltaMs > ((u32_t)wd->ap.staAgingTimeSec<<10)) + { + /* Aging STA */ + zm_msg1_mm(ZM_LV_0, "Age STA index=", i); + wd->ap.staTable[i].valid = 0; + txFlag = 1; + } + else if (deltaMs > ((u32_t)wd->ap.staProbingTimeSec<<10)) + { + if (wd->ap.staTable[i].psMode == 0) + { + /* Probing non-PS STA */ + zm_msg1_mm(ZM_LV_0, "Probing STA index=", i); + wd->ap.staTable[i].time += + (wd->ap.staProbingTimeSec * ZM_TICK_PER_SECOND); + txFlag = 2; + } + } + } + + + } + zmw_leave_critical_section(dev); + + if (txFlag == 1) + { + /* Send deauthentication management frame */ + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, addr, 4, 0, 0); + } + else if (txFlag == 2) + { + zfSendMmFrame(dev, ZM_WLAN_DATA_FRAME, addr, 0, 0, 0); + } + + } + + wd->ap.staPowerSaving = psStaCount; + + return; +} + +void zfApProtctionMonitor(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + /* 11b STA associated => nonErp, Protect */ + if (wd->ap.bStaAssociated > 0) + { + /* Enable NonErp bit in information element */ + wd->erpElement = ZM_WLAN_NON_ERP_PRESENT_BIT + | ZM_WLAN_USE_PROTECTION_BIT; + + /* Enable protection mode */ + zfApSetProtectionMode(dev, 1); + + } + /* 11b STA not associated, protection OBSS present => Protect */ + else if (wd->ap.protectedObss > 2) //Threshold + { + if (wd->disableSelfCts == 0) + { + /* Disable NonErp bit in information element */ + wd->erpElement = ZM_WLAN_USE_PROTECTION_BIT; + + /* Enable protection mode */ + zfApSetProtectionMode(dev, 1); + } + } + else + { + /* Disable NonErp bit in information element */ + wd->erpElement = 0; + + /* Disable protection mode */ + zfApSetProtectionMode(dev, 0); + } + wd->ap.protectedObss = 0; +} + + +void zfApProcessBeacon(zdev_t* dev, zbuf_t* buf) +{ + u16_t offset; + u8_t ch; + + zmw_get_wlan_dev(dev); + + zm_msg0_mm(ZM_LV_3, "Rx beacon"); + + /* update Non-ERP flag(wd->ap.nonErpObss) */ + if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_ERP)) == 0xffff) + { + /* 11b OBSS */ + wd->ap.protectedObss++; + return; + } + + ch = zmw_rx_buf_readb(dev, buf, offset+2); + if ((ch & ZM_WLAN_USE_PROTECTION_BIT) == ZM_WLAN_USE_PROTECTION_BIT) + { + /* Protected OBSS */ + wd->ap.protectedObss = 1; + } + + return; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfProcessAuth */ +/* Process authenticate management frame. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : auth frame buffer */ +/* */ +/* OUTPUTS */ +/* none */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2005.10 */ +/* */ +/************************************************************************/ +/* Note : AP allows one authenticating STA at a time, does not */ +/* support multiple authentication process. Make sure */ +/* authentication state machine will not be blocked due */ +/* to incompleted authentication handshake. */ +void zfApProcessAuth(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId) +{ + u16_t algo, seq, status; + u8_t authSharing; + u16_t ret; + u16_t i; + u8_t challengePassed = 0; + u8_t frameCtrl; + u32_t retAlgoSeq; + u32_t retStatus; + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + + frameCtrl = zmw_rx_buf_readb(dev, buf, 1); + /* AP : Auth share 3 */ + /* shift for WEP IV */ + if ((frameCtrl & 0x40) != 0) + { + algo = zmw_rx_buf_readh(dev, buf, 28); + seq = zmw_rx_buf_readh(dev, buf, 30); + status = zmw_rx_buf_readh(dev, buf, 32); + } + else + { + algo = zmw_rx_buf_readh(dev, buf, 24); + seq = zmw_rx_buf_readh(dev, buf, 26); + status = zmw_rx_buf_readh(dev, buf, 28); + } + + zm_msg2_mm(ZM_LV_0, "Rx Auth, seq=", seq); + + /* Set default to authentication algorithm not support */ + retAlgoSeq = 0x20000 | algo; + retStatus = 13; /* authentication algorithm not support */ + + /* AP : Auth open 1 */ + if (algo == 0) + { + if (wd->ap.authAlgo[apId] == 0) + { + retAlgoSeq = 0x20000; + if (seq == 1) + { + /* AP : update STA to auth */ + if ((ret = zfApAddSta(dev, src, ZM_STATE_AUTH, apId, 0, 0, 0)) != 0xffff) + { + /* AP : call zfwAuthNotify() for host to judge */ + //zfwAuthNotify(dev, src); + + /* AP : response Auth seq=2, success */ + retStatus = 0; + + } + else + { + /* AP : response Auth seq=2, unspecific error */ + retStatus = 1; + } + } + else + { + /* AP : response Auth seq=2, sequence number out of expected */ + retStatus = 14; + } + } + } + /* AP : Auth share 1 */ + else if (algo == 1) + { + if (wd->ap.authAlgo[apId] == 1) + { + if (seq == 1) + { + retAlgoSeq = 0x20001; + + /* critical section */ + zmw_enter_critical_section(dev); + if (wd->ap.authSharing == 1) + { + authSharing = 1; + } + else + { + authSharing = 0; + wd->ap.authSharing = 1; + } + /* end of critical section */ + zmw_leave_critical_section(dev); + + if (authSharing == 1) + { + /* AP : response Auth seq=2, status = fail */ + retStatus = 1; + } + else + { + /* AP : update STA to preauth */ + zfApAddSta(dev, src, ZM_STATE_PREAUTH, apId, 0, 0, 0); + + /* AP : call zfwAuthNotify() for host to judge */ + //zfwAuthNotify(dev, src); + + /* AP : response Auth seq=2 */ + retStatus = 0; + } + } + else if (seq == 3) + { + retAlgoSeq = 0x40001; + + if (wd->ap.authSharing == 1) + { + /* check challenge text */ + if (zmw_buf_readh(dev, buf, 30+4) == 0x8010) + { + for (i=0; i<128; i++) + { + if (wd->ap.challengeText[i] + != zmw_buf_readb(dev, buf, 32+i+4)) + { + break; + } + } + if (i == 128) + { + challengePassed = 1; + } + } + + if (challengePassed == 1) + { + /* AP : update STA to auth */ + zfApAddSta(dev, src, ZM_STATE_AUTH, apId, 0, 0, 0); + + /* AP : response Auth seq=2 */ + retStatus = 0; + } + else + { + /* AP : response Auth seq=2, challenge failure */ + retStatus = 15; + + /* TODO : delete STA */ + } + + wd->ap.authSharing = 0; + } + } + else + { + retAlgoSeq = 0x40001; + retStatus = 14; + } + } + } + + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_AUTH, src, retAlgoSeq, + retStatus, apId); + return; +} + +void zfApProcessAsocReq(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId) +{ + u16_t aid = 0xffff; + u8_t frameType; + u16_t offset; + u8_t staType = 0; + u8_t qosType = 0; + u8_t qosInfo = 0; + u8_t tmp; + u16_t i, j, k; + u16_t encMode = 0; + + zmw_get_wlan_dev(dev); + /* AP : check SSID */ + if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID)) != 0xffff) + { + k = 0; + for (j = 0; j < wd->ap.vapNumber; j++) + { + if ((tmp = zmw_buf_readb(dev, buf, offset+1)) + != wd->ap.ssidLen[j]) + { + k++; + } + } + if (k == wd->ap.vapNumber) + { + goto zlDeauth; + } + + k = 0; + for (j = 0; j < wd->ap.vapNumber; j++) + { + for (i=0; iap.ssidLen[j]; i++) + { + if ((tmp = zmw_buf_readb(dev, buf, offset+2+i)) + != wd->ap.ssid[j][i]) + { + break; + } + } + if (i == wd->ap.ssidLen[j]) + { + apId = j; + } + else + { + k++; + } + } + if (k == wd->ap.vapNumber) + { + goto zlDeauth; + } + } + + /* TODO : check capability */ + + /* AP : check support rate */ + if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE)) != 0xffff) + { + /* 11g STA */ + staType = 1; + } + //CWYang(+) + if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY)) != 0xffff) + { + /* 11n STA */ + staType = 2; + } + + /* TODO : do not allow 11b STA to associated in Pure G mode */ + if (wd->ap.wlanType[apId] == ZM_WLAN_TYPE_PURE_G && staType == 0) + { + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 3, 0, 0); + return; + } + + /* In pure B mode, we set G STA into B mode */ + if (wd->ap.wlanType[apId] == ZM_WLAN_TYPE_PURE_B && staType == 1) + { + staType = 0; + } + + /* AP : check 11i and WPA */ + /* AP : check 11h */ + + /* AP : check WME */ + if ((offset = zfFindWifiElement(dev, buf, 2, 0)) != 0xffff) + { + /* WME STA */ + qosType = 1; + zm_msg0_mm(ZM_LV_0, "WME STA"); + + if (wd->ap.uapsdEnabled != 0) + { + qosInfo = zmw_rx_buf_readb(dev, buf, offset+8); + } + } + + if (wd->ap.wpaSupport[apId] == 1) + { + if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_WPA_IE)) != 0xffff ) + { + /* get WPA IE */ + u8_t length = zmw_rx_buf_readb(dev, buf, offset+1); + if (length+2 < ZM_MAX_WPAIE_SIZE) + { + zfCopyFromRxBuffer(dev, buf, wd->ap.stawpaIe[apId], offset, length+2); + wd->ap.stawpaLen[apId] = length+2; + encMode = 1; + + + zm_msg1_mm(ZM_LV_0, "WPA Mode zfwAsocNotify, apId=", apId); + + /* AP : Call zfwAsocNotify() */ + if (wd->zfcbAsocNotify != NULL) + { + wd->zfcbAsocNotify(dev, src, wd->ap.stawpaIe[apId], wd->ap.stawpaLen[apId], apId); + } + } + else + { + goto zlDeauth; + } + } + else if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_RSN_IE)) != 0xffff ) + { + /* get RSN IE */ + u8_t length = zmw_rx_buf_readb(dev, buf, offset+1); + if (length+2 < ZM_MAX_WPAIE_SIZE) + { + zfCopyFromRxBuffer(dev, buf, wd->ap.stawpaIe[apId], offset, length+2); + wd->ap.stawpaLen[apId] = length+2; + encMode = 1; + + zm_msg1_mm(ZM_LV_0, "RSN Mode zfwAsocNotify, apId=", apId); + + /* AP : Call zfwAsocNotify() */ + if (wd->zfcbAsocNotify != NULL) + { + wd->zfcbAsocNotify(dev, src, wd->ap.stawpaIe[apId], wd->ap.stawpaLen[apId], apId); + } + } + else + { + goto zlDeauth; + } + } +#ifdef ZM_ENABLE_CENC + else if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_CENC_IE)) != 0xffff ) + { + /* get CENC IE */ + u8_t length = zmw_rx_buf_readb(dev, buf, offset+1); + + if (length+2 < ZM_MAX_WPAIE_SIZE) + { + zfCopyFromRxBuffer(dev, buf, wd->ap.stawpaIe[apId], offset, length+2); + wd->ap.stawpaLen[apId] = length+2; + encMode = 1; + + zm_msg1_mm(ZM_LV_0, "CENC Mode zfwAsocNotify, apId=", apId); + + /* AP : Call zfwAsocNotify() */ + if (wd->zfcbCencAsocNotify != NULL) + { + wd->zfcbCencAsocNotify(dev, src, wd->ap.stawpaIe[apId], + wd->ap.stawpaLen[apId], apId); + } + } + else + { + goto zlDeauth; + } + } +#endif //ZM_ENABLE_CENC + else + { /* ap is encryption but sta has no wpa/rsn ie */ + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 6, 0, 0); + return; + } + } + /* sta has wpa/rsn ie but ap is no encryption */ + if ((wd->ap.wpaSupport[apId] == 0) && (encMode == 1)) + { + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 6, 0, 0); + return; + } + + /* AP : update STA to asoc */ + aid = zfApAddSta(dev, src, ZM_STATE_ASOC, apId, staType, qosType, qosInfo); + + zfApStoreAsocReqIe(dev, buf, aid); + +zlDeauth: + /* AP : send asoc rsp2 */ + if (aid != 0xffff) + { + frameType = zmw_rx_buf_readb(dev, buf, 0); + + if (frameType == ZM_WLAN_FRAME_TYPE_ASOCREQ) + { + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_ASOCRSP, src, 0, aid+1, apId); + } + else + { + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_REASOCRSP, src, 0, aid+1, apId); + } + } + else + { + /* TODO : send deauthentication */ + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 6, 0, 0); + } + + return; +} + +void zfApStoreAsocReqIe(zdev_t* dev, zbuf_t* buf, u16_t aid) +{ + //struct zsWlanAssoFrameHeader* pAssoFrame; + //u8_t pBuf[sizeof(struct zsWlanAssoFrameHeader)]; + u16_t offset; + u32_t i; + u16_t length; + u8_t *htcap; + + zmw_get_wlan_dev(dev); + + for (i=0; ista.asocRspFrameBodySize; i++) + { + wd->sta.asocRspFrameBody[i] = zmw_rx_buf_readb(dev, buf, i+24); + } + /* capability: 2 octets */ + offset = 24; + + /* Listen interval: 2 octets */ + offset = 26; + + /* SSID */ + offset = 28; + + /* supported rates */ + if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_SUPPORT_RATE)) == 0xffff) + return; + length = zmw_rx_buf_readb(dev, buf, offset + 1); + + /* extended supported rates */ + if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_EXTENDED_RATE)) == 0xffff) + return; + length = zmw_rx_buf_readb(dev, buf, offset + 1); + + /* power capability:4 octets */ + offset = offset + 2 + length; + + /* supported channels: 4 octets */ + offset = offset + 2 + 4; + + /* RSN */ + + /* QoS */ + + /* HT capabilities: 28 octets */ + if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_HT_CAPABILITY)) != 0xffff) { + /* atheros pre n */ + htcap = (u8_t *)&wd->ap.ie[aid].HtCap; + htcap[0] = zmw_rx_buf_readb(dev, buf, offset); + htcap[1] = 26; + for (i=1; i<=26; i++) + { + htcap[i+1] = zmw_rx_buf_readb(dev, buf, offset + i); + zm_debug_msg2("ASOC: HT Capabilities, htcap=", htcap[i+1]); + } + return; + } + else if ((offset = zfFindElement(dev, buf, ZM_WLAN_PREN2_EID_HTCAPABILITY)) != 0xffff) { + /* pre n 2.0 standard */ + htcap = (u8_t *)&wd->ap.ie[aid].HtCap; + for (i=0; i<28; i++) + { + htcap[i] = zmw_rx_buf_readb(dev, buf, offset + i); + zm_debug_msg2("ASOC: HT Capabilities, htcap=", htcap[i]); + } + } + else { + /* not 11n AP */ + return; + } + + + /* supported regulatory classes */ + offset = offset + length; + //length = zmw_rx_buf_readb(dev, buf, offset + 1); + { + u8_t *htcap; + htcap = (u8_t *)&wd->sta.ie.HtInfo; + //zm_debug_msg2("ASOC: HT Capabilities info=", ((u16_t *)htcap)[1]); + //zm_debug_msg2("ASOC: A-MPDU parameters=", htcap[4]); + //zm_debug_msg2("ASOC: Supported MCS set=", ((u32_t *)htcap)[1]>>8); + } + +} + +void zfApProcessAsocRsp(zdev_t* dev, zbuf_t* buf) +{ + +} + +void zfApProcessDeauth(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId) +{ + u16_t aid; + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + /* AP : if SA=associated STA then deauthenticate STA */ + if ((aid = zfApFindSta(dev, src)) != 0xffff) + { + /* Clear STA table */ + wd->ap.staTable[aid].valid = 0; + if (wd->zfcbDisAsocNotify != NULL) + { + wd->zfcbDisAsocNotify(dev, (u8_t*)src, apId); + } + } + zmw_leave_critical_section(dev); + +} + +void zfApProcessDisasoc(zdev_t* dev, zbuf_t* buf, u16_t* src, u16_t apId) +{ + u16_t aid; + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + /* AP : if SA=associated STA then deauthenticate STA */ + if ((aid = zfApFindSta(dev, src)) != 0xffff) + { + /* Clear STA table */ + wd->ap.staTable[aid].valid = 0; + zmw_leave_critical_section(dev); + if (wd->zfcbDisAsocNotify != NULL) + { + wd->zfcbDisAsocNotify(dev, (u8_t*)src, apId); + } + } + zmw_leave_critical_section(dev); + +} + + +void zfApProcessProbeRsp(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* AddInfo) +{ +#if 0 + zmw_get_wlan_dev(dev); + + zm_msg0_mm(ZM_LV_0, "Rx probersp"); + + /* Gather scan result */ + + //zm_debug_msg1("bssList Count = ", wd->sta.bssList.bssCount); + /* return if not in scanning */ + if ((wd->heartBeatNotification & ZM_BSSID_LIST_SCAN) + != ZM_BSSID_LIST_SCAN) + { + return; + } + + //if ( wd->sta.pUpdateBssList->bssCount == ZM_MAX_BSS ) + if ( wd->sta.bssList.bssCount == ZM_MAX_BSS ) + { + return; + } + + zfProcessProbeRsp(dev, buf, AddInfo); + +#endif +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfApAddIeSsid */ +/* Add AP information element SSID to buffer. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : buffer to add information element */ +/* offset : add information element from this offset */ +/* vap : virtual AP ID */ +/* */ +/* OUTPUTS */ +/* buffer offset after adding information element */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2005.11 */ +/* */ +/************************************************************************/ +u16_t zfApAddIeSsid(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t vap) +{ + u16_t i; + + zmw_get_wlan_dev(dev); + + /* Element ID */ + zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_SSID); + + /* Element Length */ + zmw_tx_buf_writeb(dev, buf, offset++, wd->ap.ssidLen[vap]); + + /* Information : SSID */ + for (i=0; iap.ssidLen[vap]; i++) + { + zmw_tx_buf_writeb(dev, buf, offset++, wd->ap.ssid[vap][i]); + } + + return offset; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfApAddIeTim */ +/* Add AP information element TIM to buffer. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : buffer to add information element */ +/* offset : add information element from this offset */ +/* vap : virtual AP ID */ +/* */ +/* OUTPUTS */ +/* buffer offset after adding information element */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2005.11 */ +/* */ +/************************************************************************/ +u16_t zfApAddIeTim(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t vap) +{ + u8_t uniBitMap[9]; + u16_t highestByte; + u16_t i; + u16_t lenOffset; + u16_t id; + u16_t dst[3]; + u16_t aid; + u16_t bitPosition; + u16_t bytePosition; + zbuf_t* psBuf; + zbuf_t* tmpBufArray[ZM_UNI_ARRAY_SIZE]; + u16_t tmpBufArraySize = 0; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + /* Element ID */ + zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_TIM); + + /* offset of Element Length */ + lenOffset = offset++; + + /* Information : TIM */ + /* DTIM count */ + /* TODO : Doesn't work for Virtual AP's case */ + wd->CurrentDtimCount++; + if (wd->CurrentDtimCount >= wd->dtim) + { + wd->CurrentDtimCount = 0; + } + zmw_tx_buf_writeb(dev, buf, offset++, wd->CurrentDtimCount); + /* DTIM period */ + zmw_tx_buf_writeb(dev, buf, offset++, wd->dtim); + /* bitmap offset */ + zmw_tx_buf_writeb(dev, buf, offset++, 0); + + /* Update BCMC bit */ + if (wd->CurrentDtimCount == 0) + { + zmw_enter_critical_section(dev); + wd->ap.timBcmcBit[vap] = (wd->ap.bcmcTail[vap]!=wd->ap.bcmcHead[vap])?1:0; + zmw_leave_critical_section(dev); + } + else + { + wd->ap.timBcmcBit[vap] = 0; + } + + /* Update Unicast bitmap */ + /* reset bit map */ + for (i=0; i<9; i++) + { + uniBitMap[i] = 0; + } + highestByte = 0; +#if 1 + + zmw_enter_critical_section(dev); + + id = wd->ap.uniHead; + while (id != wd->ap.uniTail) + { + psBuf = wd->ap.uniArray[id]; + + /* TODO : Aging PS frame after queuing for more than 10 seconds */ + + /* get destination STA's aid */ + dst[0] = zmw_tx_buf_readh(dev, psBuf, 0); + dst[1] = zmw_tx_buf_readh(dev, psBuf, 2); + dst[2] = zmw_tx_buf_readh(dev, psBuf, 4); + if ((aid = zfApFindSta(dev, dst)) != 0xffff) + { + if (wd->ap.staTable[aid].psMode != 0) + { + zm_msg1_mm(ZM_LV_0, "aid=",aid); + aid++; + zm_assert(aid<=64); + bitPosition = (1 << (aid & 0x7)); + bytePosition = (aid >> 3); + uniBitMap[bytePosition] |= bitPosition; + + if (bytePosition>highestByte) + { + highestByte = bytePosition; + } + id = (id+1) & (ZM_UNI_ARRAY_SIZE-1); + } + else + { + zm_msg0_mm(ZM_LV_0, "Send PS frame which STA no longer in PS mode"); + /* Send PS frame which STA no longer in PS mode */ + zfApRemoveFromPsQueue(dev, id, dst); + tmpBufArray[tmpBufArraySize++] = psBuf; + } + } + else + { + zm_msg0_mm(ZM_LV_0, "Free garbage PS frame"); + /* Free garbage PS frame */ + zfApRemoveFromPsQueue(dev, id, dst); + zfwBufFree(dev, psBuf, 0); + } + } + + zmw_leave_critical_section(dev); +#endif + + zfQueueGenerateUapsdTim(dev, wd->ap.uapsdQ, uniBitMap, &highestByte); + + zm_msg1_mm(ZM_LV_3, "bm=",uniBitMap[0]); + zm_msg1_mm(ZM_LV_3, "highestByte=",highestByte); + zm_msg1_mm(ZM_LV_3, "timBcmcBit[]=",wd->ap.timBcmcBit[vap]); + + /* bitmap */ + zmw_tx_buf_writeb(dev, buf, offset++, + uniBitMap[0] | wd->ap.timBcmcBit[vap]); + for (i=0; iap.uniTail = (wd->ap.uniTail-1) & (ZM_UNI_ARRAY_SIZE-1); + while (id != wd->ap.uniTail) + { + nid = (id + 1) & (ZM_UNI_ARRAY_SIZE - 1); + wd->ap.uniArray[id] = wd->ap.uniArray[nid]; + + /* Search until tail to config more data bit */ + dst[0] = zmw_buf_readh(dev, wd->ap.uniArray[id], 0); + dst[1] = zmw_buf_readh(dev, wd->ap.uniArray[id], 2); + dst[2] = zmw_buf_readh(dev, wd->ap.uniArray[id], 4); + if ((addr[0] == dst[0]) && (addr[1] == dst[1]) + && (addr[2] == dst[2])) + { + moreData = 0x20; + } + + id = nid; + } + return moreData; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfApAddIeWmePara */ +/* Add WME Parameter Element to buffer. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : buffer to add information element */ +/* offset : add information element from this offset */ +/* vap : virtual AP ID */ +/* */ +/* OUTPUTS */ +/* buffer offset after adding information element */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2006.1 */ +/* */ +/************************************************************************/ +u16_t zfApAddIeWmePara(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t vap) +{ + zmw_get_wlan_dev(dev); + + /* Element ID */ + zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_WIFI_IE); + + /* Element Length */ + zmw_tx_buf_writeb(dev, buf, offset++, 24); + + /* OUI */ + zmw_tx_buf_writeb(dev, buf, offset++, 0x00); + zmw_tx_buf_writeb(dev, buf, offset++, 0x50); + zmw_tx_buf_writeb(dev, buf, offset++, 0xF2); + zmw_tx_buf_writeb(dev, buf, offset++, 0x02); + zmw_tx_buf_writeb(dev, buf, offset++, 0x01); + zmw_tx_buf_writeb(dev, buf, offset++, 0x01); + + /* QoS Info */ + if (wd->ap.uapsdEnabled) + { + zmw_tx_buf_writeb(dev, buf, offset++, 0x81); + } + else + { + zmw_tx_buf_writeb(dev, buf, offset++, 0x01); + } + + /* Reserved */ + zmw_tx_buf_writeb(dev, buf, offset++, 0x00); + + /* Best Effort AC parameters */ + zmw_tx_buf_writeb(dev, buf, offset++, 0x03); + zmw_tx_buf_writeb(dev, buf, offset++, 0xA4); + zmw_tx_buf_writeb(dev, buf, offset++, 0x00); + zmw_tx_buf_writeb(dev, buf, offset++, 0x00); + /* Backfround AC parameters */ + zmw_tx_buf_writeb(dev, buf, offset++, 0x27); + zmw_tx_buf_writeb(dev, buf, offset++, 0xA4); + zmw_tx_buf_writeb(dev, buf, offset++, 0x00); + zmw_tx_buf_writeb(dev, buf, offset++, 0x00); + /* Video AC parameters */ + zmw_tx_buf_writeb(dev, buf, offset++, 0x42); + zmw_tx_buf_writeb(dev, buf, offset++, 0x43); + zmw_tx_buf_writeb(dev, buf, offset++, 0x5E); + zmw_tx_buf_writeb(dev, buf, offset++, 0x00); + /* Voice AC parameters */ + zmw_tx_buf_writeb(dev, buf, offset++, 0x62); + zmw_tx_buf_writeb(dev, buf, offset++, 0x32); + zmw_tx_buf_writeb(dev, buf, offset++, 0x2F); + zmw_tx_buf_writeb(dev, buf, offset++, 0x00); + + return offset; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfApSendBeacon */ +/* Sned AP mode beacon. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* none */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2005.11 */ +/* */ +/************************************************************************/ +void zfApSendBeacon(zdev_t* dev) +{ + zbuf_t* buf; + u16_t offset; + u16_t vap; + u16_t seq; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + wd->ap.beaconCounter++; + if (wd->ap.beaconCounter >= wd->ap.vapNumber) + { + wd->ap.beaconCounter = 0; + } + vap = wd->ap.beaconCounter; + + + zm_msg1_mm(ZM_LV_2, "Send beacon, vap=", vap); + + /* TBD : Maximum size of beacon */ + if ((buf = zfwBufAllocate(dev, 1024)) == NULL) + { + zm_msg0_mm(ZM_LV_0, "Alloc beacon buf Fail!"); + return; + } + + offset = 0; + + /* wlan header */ + /* Frame control */ + zmw_tx_buf_writeh(dev, buf, offset, 0x0080); + offset+=2; + /* Duration */ + zmw_tx_buf_writeh(dev, buf, offset, 0x0000); + offset+=2; + /* Address 1 */ + zmw_tx_buf_writeh(dev, buf, offset, 0xffff); + offset+=2; + zmw_tx_buf_writeh(dev, buf, offset, 0xffff); + offset+=2; + zmw_tx_buf_writeh(dev, buf, offset, 0xffff); + offset+=2; + /* Address 2 */ + zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[0]); + offset+=2; + zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[1]); + offset+=2; +#ifdef ZM_VAPMODE_MULTILE_SSID + zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[2]); //Multiple SSID +#else + zmw_tx_buf_writeh(dev, buf, offset, (wd->macAddr[2]+(vap<<8))); //VAP +#endif + offset+=2; + /* Address 3 */ + zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[0]); + offset+=2; + zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[1]); + offset+=2; +#ifdef ZM_VAPMODE_MULTILE_SSID + zmw_tx_buf_writeh(dev, buf, offset, wd->macAddr[2]); //Multiple SSID +#else + zmw_tx_buf_writeh(dev, buf, offset, (wd->macAddr[2]+(vap<<8))); //VAP +#endif + offset+=2; + + /* Sequence number */ + zmw_enter_critical_section(dev); + seq = ((wd->mmseq++)<<4); + zmw_leave_critical_section(dev); + zmw_tx_buf_writeh(dev, buf, offset, seq); + offset+=2; + + /* 24-31 Time Stamp : hardware will fill this field */ + zmw_tx_buf_writeh(dev, buf, offset, 0); + zmw_tx_buf_writeh(dev, buf, offset+2, 0); + zmw_tx_buf_writeh(dev, buf, offset+4, 0); + zmw_tx_buf_writeh(dev, buf, offset+6, 0); + offset+=8; + + /* Beacon Interval */ + zmw_tx_buf_writeh(dev, buf, offset, wd->beaconInterval); + offset+=2; + + /* Capability */ + zmw_tx_buf_writeh(dev, buf, offset, wd->ap.capab[vap]); + offset+=2; + + /* SSID */ + if (wd->ap.hideSsid[vap] == 0) + { + offset = zfApAddIeSsid(dev, buf, offset, vap); + } + else + { + zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_SSID); + zmw_tx_buf_writeb(dev, buf, offset++, 0); + + } + + /* Support Rate */ + if ( wd->frequency < 3000 ) + { + offset = zfMmAddIeSupportRate(dev, buf, offset, + ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_CCK); + } + else + { + offset = zfMmAddIeSupportRate(dev, buf, offset, + ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_OFDM); + } + + /* DS parameter set */ + offset = zfMmAddIeDs(dev, buf, offset); + + /* TIM */ + offset = zfApAddIeTim(dev, buf, offset, vap); + + /* If WLAN Type is not PURE B */ + if (wd->ap.wlanType[vap] != ZM_WLAN_TYPE_PURE_B) + { + if ( wd->frequency < 3000 ) + { + /* ERP Information */ + offset = zfMmAddIeErp(dev, buf, offset); + + /* Extended Supported Rates */ + offset = zfMmAddIeSupportRate(dev, buf, offset, + ZM_WLAN_EID_EXTENDED_RATE, ZM_RATE_SET_OFDM); + } + } + + /* TODO : country information */ + /* TODO : RSN */ + if (wd->ap.wpaSupport[vap] == 1) + { + offset = zfMmAddIeWpa(dev, buf, offset, vap); + } + + /* WME Parameters */ + if (wd->ap.qosMode == 1) + { + offset = zfApAddIeWmePara(dev, buf, offset, vap); + } + + /* HT Capabilities Info */ + offset = zfMmAddHTCapability(dev, buf, offset); + + /* Extended HT Capabilities Info */ + offset = zfMmAddExtendedHTCapability(dev, buf, offset); + + /* 1212 : write to beacon fifo */ + /* 1221 : write to share memory */ + zfHpSendBeacon(dev, buf, offset); + + /* Free beacon buffer */ + /* TODO: In order to fit the madwifi beacon architecture, we need to + free beacon buffer in the HAL layer. + */ + + //zfwBufFree(dev, buf, 0); +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfIntrabssForward */ +/* Called to transmit intra-BSS frame from upper layer. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : buffer pointer */ +/* vap : virtual AP */ +/* */ +/* OUTPUTS */ +/* 1 : unicast intras-BSS frame */ +/* 0 : other frames */ +/* */ +/* AUTHOR */ +/* Stephen ZyDAS Technology Corporation 2005.11 */ +/* */ +/************************************************************************/ +u16_t zfIntrabssForward(zdev_t* dev, zbuf_t* buf, u8_t srcVap) +{ + u16_t err; + u16_t asocFlag = 0; + u16_t dst[3]; + u16_t aid; + u16_t staState; + zbuf_t* txBuf; + u16_t len; + u16_t i; + u16_t temp; + u16_t ret; + u8_t vap = 0; +#ifdef ZM_ENABLE_NATIVE_WIFI + dst[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET); + dst[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+2); + dst[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+4); +#else + dst[0] = zmw_rx_buf_readh(dev, buf, 0); + dst[1] = zmw_rx_buf_readh(dev, buf, 2); + dst[2] = zmw_rx_buf_readh(dev, buf, 4); +#endif // ZM_ENABLE_NATIVE_WIFI + + /* Do Intra-BSS forward(data copy) if necessary*/ + if ((dst[0]&0x1) != 0x1) + { + aid = zfApGetSTAInfo(dev, dst, &staState, &vap); + if ((aid != 0xffff) && (staState == ZM_STATE_ASOC) && (srcVap == vap)) + { + asocFlag = 1; + zm_msg0_rx(ZM_LV_2, "Intra-BSS forward : asoc STA"); + } + + } + else + { + vap = srcVap; + zm_msg0_rx(ZM_LV_2, "Intra-BSS forward : BCorMC"); + } + + /* destination address = associated STA or BC/MC */ + if ((asocFlag == 1) || ((dst[0]&0x1) == 0x1)) + { + /* Allocate frame */ + if ((txBuf = zfwBufAllocate(dev, ZM_RX_FRAME_SIZE)) + == NULL) + { + zm_msg0_rx(ZM_LV_1, "Alloc intra-bss buf Fail!"); + goto zlAllocError; + } + + /* Copy frame */ + len = zfwBufGetSize(dev, buf); + for (i=0; iap.staTable[id].rxMicKey); + + return NULL; +} + +struct zsMicVar* zfApGetTxMicKey(zdev_t* dev, zbuf_t* buf, u8_t* qosType) +{ + u8_t da[6]; + u16_t id = 0, macAddr[3]; + + zmw_get_wlan_dev(dev); + + zfCopyFromIntTxBuffer(dev, buf, da, 0, 6); + + macAddr[0] = da[0] + (da[1] << 8); + macAddr[1] = da[2] + (da[3] << 8); + macAddr[2] = da[4] + (da[5] << 8); + + if ((macAddr[0] & 0x1)) + { + return (&wd->ap.bcMicKey[0]); + } + else if ((id = zfApFindSta(dev, macAddr)) != 0xffff) + { + *qosType = wd->ap.staTable[id].qosType; + return (&wd->ap.staTable[id].txMicKey); + } + + return NULL; +} + +u16_t zfApUpdatePsBit(zdev_t* dev, zbuf_t* buf, u8_t* vap, u8_t* uapsdTrig) +{ + u16_t staState; + u16_t aid; + u16_t psBit; + u16_t src[3]; + u16_t dst[1]; + u16_t i; + + zmw_get_wlan_dev(dev); + + src[0] = zmw_rx_buf_readh(dev, buf, 10); + src[1] = zmw_rx_buf_readh(dev, buf, 12); + src[2] = zmw_rx_buf_readh(dev, buf, 14); + + if ((zmw_rx_buf_readb(dev, buf, 1) & 0x3) != 3) + { + /* AP */ + dst[0] = zmw_rx_buf_readh(dev, buf, 4); + + psBit = (zmw_rx_buf_readb(dev, buf, 1) & 0x10) >> 4; + /* Get AID and update STA PS mode */ + aid = zfApGetSTAInfoAndUpdatePs(dev, src, &staState, vap, psBit, uapsdTrig); + + /* if STA not associated, send deauth */ + if ((aid == 0xffff) || (staState != ZM_STATE_ASOC)) + { + if ((dst[0]&0x1)==0) + { + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, src, 0x7, + 0, 0); + } + + return ZM_ERR_STA_NOT_ASSOCIATED; + } + } /* if ((zmw_rx_buf_readb(dev, buf, 1) & 0x3) != 3) */ + else + { + /* WDS */ + for (i=0; iap.wds.wdsBitmap & (1<ap.wds.macAddr[i][0]) + && (src[1] == wd->ap.wds.macAddr[i][1]) + && (src[2] == wd->ap.wds.macAddr[i][2])) + { + *vap = 0x20 + i; + break; + } + } + } + } + return ZM_SUCCESS; +} + +void zfApProcessPsPoll(zdev_t* dev, zbuf_t* buf) +{ + u16_t src[3]; + u16_t dst[3]; + zbuf_t* psBuf = NULL; + u16_t id; + u8_t moreData = 0; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + src[0] = zmw_tx_buf_readh(dev, buf, 10); + src[1] = zmw_tx_buf_readh(dev, buf, 12); + src[2] = zmw_tx_buf_readh(dev, buf, 14); + + /* Find ps buffer for PsPoll */ + zmw_enter_critical_section(dev); + id = wd->ap.uniHead; + while (id != wd->ap.uniTail) + { + psBuf = wd->ap.uniArray[id]; + + dst[0] = zmw_tx_buf_readh(dev, psBuf, 0); + dst[1] = zmw_tx_buf_readh(dev, psBuf, 2); + dst[2] = zmw_tx_buf_readh(dev, psBuf, 4); + + if ((src[0] == dst[0]) && (src[1] == dst[1]) && (src[2] == dst[2])) + { + moreData = zfApRemoveFromPsQueue(dev, id, src); + break; + } + else + { + psBuf = NULL; + } + id = (id + 1) & (ZM_UNI_ARRAY_SIZE - 1); + } + zmw_leave_critical_section(dev); + + /* Send ps buffer */ + if (psBuf != NULL) + { + /* Send with more data bit */ + zfTxSendEth(dev, psBuf, 0, ZM_EXTERNAL_ALLOC_BUF, moreData); + } + + return; +} + +void zfApSetProtectionMode(zdev_t* dev, u16_t mode) +{ + zmw_get_wlan_dev(dev); + + if (mode == 0) + { + if (wd->ap.protectionMode != mode) + { + /* Write MAC&PHY registers to disable protection */ + + wd->ap.protectionMode = mode; + } + + } + else + { + if (wd->ap.protectionMode != mode) + { + /* Write MAC&PHY registers to enable protection */ + + wd->ap.protectionMode = mode; + } + } + return; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfApSendFailure */ +/* Send failure. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* addr : receiver address */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Stephen Chen Atheros Communications, INC. 2007.1 */ +/* */ +/************************************************************************/ +void zfApSendFailure(zdev_t* dev, u8_t* addr) +{ + u16_t id; + u16_t staAddr[3]; + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + staAddr[0] = addr[0] + (((u16_t)addr[1])<<8); + staAddr[1] = addr[2] + (((u16_t)addr[3])<<8); + staAddr[2] = addr[4] + (((u16_t)addr[5])<<8); + zmw_enter_critical_section(dev); + if ((id = zfApFindSta(dev, staAddr)) != 0xffff) + { + /* Send failture : Add 3 minutes to inactive time that will */ + /* will make STA been kicked out soon */ + wd->ap.staTable[id].time -= (3*ZM_TICK_PER_MINUTE); + } + zmw_leave_critical_section(dev); +} + + +void zfApProcessAction(zdev_t* dev, zbuf_t* buf) +{ + u8_t category; + + //zmw_get_wlan_dev(dev); + + //zmw_declare_for_critical_section(); + + category = zmw_rx_buf_readb(dev, buf, 24); + + switch (category) + { + case ZM_WLAN_BLOCK_ACK_ACTION_FRAME: + zfAggBlockAckActionFrame(dev, buf); + break; + default: + break; + } + + return; +} --- linux-2.6.28.orig/drivers/staging/otus/80211core/ccmd.c +++ linux-2.6.28/drivers/staging/otus/80211core/ccmd.c @@ -0,0 +1,1861 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* */ +/* Module Name : cmd.c */ +/* */ +/* Abstract */ +/* This module contains command interface functions. */ +/* */ +/* NOTES */ +/* None */ +/* */ +/************************************************************************/ +#include "cprecomp.h" +#include "../hal/hpreg.h" + + +u16_t zfWlanReset(zdev_t* dev); +u32_t zfUpdateRxRate(zdev_t* dev); + + +extern void zfiUsbRecv(zdev_t *dev, zbuf_t *buf); +extern void zfiUsbRegIn(zdev_t* dev, u32_t* rsp, u16_t rspLen); +extern void zfiUsbOutComplete(zdev_t* dev, zbuf_t *buf, u8_t status, u8_t *hdr); +extern void zfiUsbRegOutComplete(zdev_t* dev); +extern u16_t zfHpReinit(zdev_t* dev, u32_t frequency); + +/* Get size (byte) of driver core global data structure. */ +/* This size will be used by driver wrapper to allocate */ +/* a memory space for driver core to store global variables */ +u16_t zfiGlobalDataSize(zdev_t* dev) +{ + u32_t ret; + ret = (sizeof(struct zsWlanDev)); + zm_assert((ret>>16) == 0); + return (u16_t)ret; +} + + +/* Initialize WLAN hardware and software, resource will be allocated */ +/* for WLAN operation, must be called first before other function. */ +extern u16_t zfiWlanOpen(zdev_t* dev, struct zsCbFuncTbl* cbFuncTbl) +{ + //u16_t ret; + //u32_t i; + //u8_t* ch; + //u8_t bPassive; + u32_t devSize; + struct zfCbUsbFuncTbl cbUsbFuncTbl; + zmw_get_wlan_dev(dev); + + zm_debug_msg0("start"); + + devSize = sizeof(struct zsWlanDev); + /* Zeroize zsWlanDev struct */ + zfZeroMemory((u8_t*)wd, (u16_t)devSize); + +#ifdef ZM_ENABLE_AGGREGATION + zfAggInit(dev); +#endif + + zfCwmInit(dev); + + wd->commTally.RateCtrlTxMPDU = 0; + wd->commTally.RateCtrlBAFail = 0; + wd->preambleTypeInUsed = ZM_PREAMBLE_TYPE_SHORT; + + if (cbFuncTbl == NULL) + { + /* zfcbRecvEth() is mandatory */ + zm_assert(0); + } + else + { + if (cbFuncTbl->zfcbRecvEth == NULL) + { + /* zfcbRecvEth() is mandatory */ + zm_assert(0); + } + wd->zfcbAuthNotify = cbFuncTbl->zfcbAuthNotify; + wd->zfcbAuthNotify = cbFuncTbl->zfcbAuthNotify; + wd->zfcbAsocNotify = cbFuncTbl->zfcbAsocNotify; + wd->zfcbDisAsocNotify = cbFuncTbl->zfcbDisAsocNotify; + wd->zfcbApConnectNotify = cbFuncTbl->zfcbApConnectNotify; + wd->zfcbConnectNotify = cbFuncTbl->zfcbConnectNotify; + wd->zfcbScanNotify = cbFuncTbl->zfcbScanNotify; + wd->zfcbMicFailureNotify = cbFuncTbl->zfcbMicFailureNotify; + wd->zfcbApMicFailureNotify = cbFuncTbl->zfcbApMicFailureNotify; + wd->zfcbIbssPartnerNotify = cbFuncTbl->zfcbIbssPartnerNotify; + wd->zfcbMacAddressNotify = cbFuncTbl->zfcbMacAddressNotify; + wd->zfcbSendCompleteIndication = cbFuncTbl->zfcbSendCompleteIndication; + wd->zfcbRecvEth = cbFuncTbl->zfcbRecvEth; + wd->zfcbRestoreBufData = cbFuncTbl->zfcbRestoreBufData; + wd->zfcbRecv80211 = cbFuncTbl->zfcbRecv80211; +#ifdef ZM_ENABLE_CENC + wd->zfcbCencAsocNotify = cbFuncTbl->zfcbCencAsocNotify; +#endif //ZM_ENABLE_CENC + wd->zfcbClassifyTxPacket = cbFuncTbl->zfcbClassifyTxPacket; + wd->zfcbHwWatchDogNotify = cbFuncTbl->zfcbHwWatchDogNotify; + } + + //add by honda 0330 + cbUsbFuncTbl.zfcbUsbRecv = zfiUsbRecv; + cbUsbFuncTbl.zfcbUsbRegIn = zfiUsbRegIn; + cbUsbFuncTbl.zfcbUsbOutComplete = zfiUsbOutComplete; + cbUsbFuncTbl.zfcbUsbRegOutComplete = zfiUsbRegOutComplete; + zfwUsbRegisterCallBack(dev, &cbUsbFuncTbl); + /* Init OWN MAC address */ + wd->macAddr[0] = 0x8000; + wd->macAddr[1] = 0x0000; + wd->macAddr[2] = 0x0000; + + wd->regulationTable.regionCode = 0xffff; + + zfHpInit(dev, wd->frequency); + + /* init region code */ + //wd->regulationTable.regionCode = NULL1_WORLD; //Only 2.4g RegCode + //zfHpGetRegulationTablefromRegionCode(dev, NULL1_WORLD); + //zfiWlanSetDot11DMode(dev , 1); // Enable 802.11d + /* Get the first channel */ + //wd->frequency = zfChGetFirstChannel(dev, &bPassive); +#ifdef ZM_AP_DEBUG + //wd->frequency = 2437; +#endif + + //STA mode + wd->sta.mTxRate = 0x0; + wd->sta.uTxRate = 0x3; + wd->sta.mmTxRate = 0x0; + wd->sta.adapterState = ZM_STA_STATE_DISCONNECT; + wd->sta.capability[0] = 0x01; + wd->sta.capability[1] = 0x00; + + wd->sta.preambleTypeHT = 0; + wd->sta.htCtrlBandwidth = 0; + wd->sta.htCtrlSTBC = 0; + wd->sta.htCtrlSG = 0; + wd->sta.defaultTA = 0; + //wd->sta.activescanTickPerChannel = ZM_TIME_ACTIVE_SCAN/ZM_MS_PER_TICK; + { + u8_t Dur = ZM_TIME_ACTIVE_SCAN; + zfwGetActiveScanDur(dev, &Dur); + wd->sta.activescanTickPerChannel = Dur/ZM_MS_PER_TICK; + + } + wd->sta.passiveScanTickPerChannel = ZM_TIME_PASSIVE_SCAN/ZM_MS_PER_TICK; + wd->sta.bAutoReconnect = TRUE; + wd->sta.dropUnencryptedPkts = FALSE; + + /* set default to bypass all multicast packet for linux, window XP would set 0 by wrapper initialization */ + wd->sta.bAllMulticast = 1; + + /* Initial the RIFS Status / RIFS-like frame count / RIFS count */ + wd->sta.rifsState = ZM_RIFS_STATE_DETECTING; + wd->sta.rifsLikeFrameCnt = 0; + wd->sta.rifsCount = 0; + + wd->sta.osRxFilter = 0; + wd->sta.bSafeMode = 0; + + //Common + zfResetSupportRate(dev, ZM_DEFAULT_SUPPORT_RATE_DISCONNECT); + wd->beaconInterval = 100; + wd->rtsThreshold = 2346; + wd->fragThreshold = 32767; + wd->wlanMode = ZM_MODE_INFRASTRUCTURE; + wd->txMCS = 0xff; //AUTO + wd->dtim = 1; + //wd->txMT = 1; //OFDM + wd->tick = 1; + wd->maxTxPower2 = 0xff; + wd->maxTxPower5 = 0xff; + wd->supportMode = 0xffffffff; + wd->ws.adhocMode = ZM_ADHOCBAND_G; + wd->ws.autoSetFrequency = 0xff; + + //AP mode + //wd->bgMode = wd->ws.bgMode; + wd->ap.ssidLen[0] = 6; + wd->ap.ssid[0][0] = 'Z'; + wd->ap.ssid[0][1] = 'D'; + wd->ap.ssid[0][2] = '1'; + wd->ap.ssid[0][3] = '2'; + wd->ap.ssid[0][4] = '2'; + wd->ap.ssid[0][5] = '1'; + + // Init the country iso name as NA + wd->ws.countryIsoName[0] = 0; + wd->ws.countryIsoName[1] = 0; + wd->ws.countryIsoName[2] = '\0'; + + /* init fragmentation is disabled */ + //zfiWlanSetFragThreshold(dev, 0); + + /* airopeek : swSniffer 1=>on 0=>off */ + wd->swSniffer = 0; + wd->XLinkMode = 0; + +// jhlee HT 0 +#if 1 + /* AP Mode*/ + /* Init HT Capability Info */ + wd->ap.HTCap.Data.ElementID = ZM_WLAN_EID_HT_CAPABILITY; + wd->ap.HTCap.Data.Length = 26; + //wd->ap.HTCap.Data.SupChannelWidthSet = 0; + //wd->ap.HTCap.Data.MIMOPowerSave = 3; + //wd->ap.HTCap.Data.ShortGIfor40MHz = 0; + //wd->ap.HTCap.Data.ShortGIfor20MHz = 0; + //wd->ap.HTCap.Data.DSSSandCCKin40MHz = 0; + wd->ap.HTCap.Data.AMPDUParam |= HTCAP_MaxRxAMPDU3; + wd->ap.HTCap.Data.MCSSet[0] = 0xFF; // MCS 0 ~ 7 + wd->ap.HTCap.Data.MCSSet[1] = 0xFF; // MCS 8 ~ 15 + + /* Init Extended HT Capability Info */ + wd->ap.ExtHTCap.Data.ElementID = ZM_WLAN_EID_EXTENDED_HT_CAPABILITY; + wd->ap.ExtHTCap.Data.Length = 22; + wd->ap.ExtHTCap.Data.ControlChannel = 6; + //wd->ap.ExtHTCap.Data.ExtChannelOffset = 3; + wd->ap.ExtHTCap.Data.ChannelInfo |= ExtHtCap_RecomTxWidthSet; + //wd->ap.ExtHTCap.Data.RIFSMode = 1; + wd->ap.ExtHTCap.Data.OperatingInfo |= 1; + + /* STA Mode*/ + /* Init HT Capability Info */ + wd->sta.HTCap.Data.ElementID = ZM_WLAN_EID_HT_CAPABILITY; + wd->sta.HTCap.Data.Length = 26; + + /* Test with 5G-AP : 7603 */ + //wd->sta.HTCap.Data.SupChannelWidthSet = 1; + wd->sta.HTCap.Data.HtCapInfo |= HTCAP_SMEnabled; + wd->sta.HTCap.Data.HtCapInfo |= HTCAP_SupChannelWidthSet; + wd->sta.HTCap.Data.HtCapInfo |= HTCAP_ShortGIfor40MHz; + wd->sta.HTCap.Data.HtCapInfo |= HTCAP_DSSSandCCKin40MHz; +#ifndef ZM_DISABLE_AMSDU8K_SUPPORT + wd->sta.HTCap.Data.HtCapInfo |= HTCAP_MaxAMSDULength; +#endif + //wd->sta.HTCap.Data.MIMOPowerSave = 0; + //wd->sta.HTCap.Data.ShortGIfor40MHz = 0; + //wd->sta.HTCap.Data.ShortGIfor20MHz = 0; + //wd->sta.HTCap.Data.DSSSandCCKin40MHz = 0; + wd->sta.HTCap.Data.AMPDUParam |= HTCAP_MaxRxAMPDU3; + wd->sta.HTCap.Data.MCSSet[0] = 0xFF; // MCS 0 ~ 7 + wd->sta.HTCap.Data.MCSSet[1] = 0xFF; // MCS 8 ~ 15 + wd->sta.HTCap.Data.PCO |= HTCAP_TransmissionTime3; + //wd->sta.HTCap.Data.TransmissionTime = 0; + /* Init Extended HT Capability Info */ + wd->sta.ExtHTCap.Data.ElementID = ZM_WLAN_EID_EXTENDED_HT_CAPABILITY; + wd->sta.ExtHTCap.Data.Length = 22; + wd->sta.ExtHTCap.Data.ControlChannel = 6; + + //wd->sta.ExtHTCap.Data.ExtChannelOffset |= 3; + wd->sta.ExtHTCap.Data.ChannelInfo |= ExtHtCap_ExtChannelOffsetBelow; + + //wd->sta.ExtHTCap.Data.RecomTxWidthSet = 1; + //wd->sta.ExtHTCap.Data.RIFSMode = 1; + wd->sta.ExtHTCap.Data.OperatingInfo |= 1; +#endif + +#if 0 + /* WME test code */ + wd->ap.qosMode[0] = 1; +#endif + + wd->ledStruct.ledMode[0] = 0x2221; + wd->ledStruct.ledMode[1] = 0x2221; + + zfTimerInit(dev); + + ZM_PERFORMANCE_INIT(dev); + + zfBssInfoCreate(dev); + zfScanMgrInit(dev); + zfPowerSavingMgrInit(dev); + +#if 0 + /* Test code */ + { + u32_t key[4] = {0xffffffff, 0xff, 0, 0}; + u16_t addr[3] = {0x8000, 0x01ab, 0x0000}; + //zfSetKey(dev, 0, 0, ZM_WEP64, addr, key); + //zfSetKey(dev, 0, 0, ZM_AES, addr, key); + //zfSetKey(dev, 64, 0, 1, wd->macAddr, key); + } +#endif + + // WME settings + wd->ws.staWmeEnabled = 1; // Enable WME by default + #define ZM_UAPSD_Q_SIZE 32 //2^N + wd->ap.uapsdQ = zfQueueCreate(dev, ZM_UAPSD_Q_SIZE); + zm_assert(wd->ap.uapsdQ != NULL); + wd->sta.uapsdQ = zfQueueCreate(dev, ZM_UAPSD_Q_SIZE); + zm_assert(wd->sta.uapsdQ != NULL); + + //zfHpInit(dev, wd->frequency); + + /* MAC address */ + //zfHpSetMacAddress(dev, wd->macAddr, 0); + zfHpGetMacAddress(dev); + + zfCoreSetFrequency(dev, wd->frequency); + +#if ZM_PCI_LOOP_BACK == 1 + zfwWriteReg(dev, ZM_REG_PCI_CONTROL, 6); +#endif /* #if ZM_PCI_LOOP_BACK == 1 */ + + //zfiWlanSetDot11DMode(dev , 1); // Enable 802.11d + //zfiWlanSetDot11HDFSMode(dev , 1); // Enable 802.11h DFS + wd->sta.DFSEnable = 1; + wd->sta.capability[1] |= ZM_BIT_0; + + //zfiWlanSetFrequency(dev, 5260000, TRUE); + //zfiWlanSetAniMode(dev , 1); // Enable ANI + + /* Trgger Rx DMA */ + zfHpStartRecv(dev); + + zm_debug_msg0("end"); + + return 0; +} + +/* WLAN hardware will be shutdown and all resource will be release */ +u16_t zfiWlanClose(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + zm_msg0_init(ZM_LV_0, "enter"); + + wd->state = ZM_WLAN_STATE_CLOSEDED; + + //zfiWlanDisable(dev, 1); + zfWlanReset(dev); + + zfHpStopRecv(dev); + + /* Disable MAC */ + /* Disable PHY */ + /* Disable RF */ + + zfHpRelease(dev); + + zfQueueDestroy(dev, wd->ap.uapsdQ); + zfQueueDestroy(dev, wd->sta.uapsdQ); + + zfBssInfoDestroy(dev); + +#ifdef ZM_ENABLE_AGGREGATION + /* add by honda */ + zfAggRxFreeBuf(dev, 1); //1 for release structure memory + /* end of add by honda */ +#endif + + zm_msg0_init(ZM_LV_0, "exit"); + + return 0; +} + +void zfGetWrapperSetting(zdev_t* dev) +{ + u8_t bPassive; + u16_t vapId = 0; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); +#if 0 + if ( (wd->ws.countryIsoName[0] != 0) + || (wd->ws.countryIsoName[1] != 0) + || (wd->ws.countryIsoName[2] != '\0') ) + { + zfHpGetRegulationTablefromRegionCode( + dev, + zfHpGetRegionCodeFromIsoName(dev, wd->ws.countryIsoName) ); + } +#endif + zmw_enter_critical_section(dev); + + wd->wlanMode = wd->ws.wlanMode; + + /* set channel */ + if ( wd->ws.frequency ) + { + wd->frequency = wd->ws.frequency; + wd->ws.frequency = 0; + } + else + { + wd->frequency = zfChGetFirstChannel(dev, &bPassive); + + if ( wd->wlanMode == ZM_MODE_IBSS ) + { + if (wd->ws.adhocMode == ZM_ADHOCBAND_A) + { + wd->frequency = ZM_CH_A_36; + } + else + { + wd->frequency = ZM_CH_G_6; + } + } + } +#ifdef ZM_AP_DEBUG + /* honda add for debug, 2437 channel 6, 2452 channel 9 */ + wd->frequency = 2437; + /* end of add by honda */ +#endif + + /* set preamble type */ + switch (wd->ws.preambleType) + { + case ZM_PREAMBLE_TYPE_AUTO: + case ZM_PREAMBLE_TYPE_SHORT: + case ZM_PREAMBLE_TYPE_LONG: + wd->preambleType = wd->ws.preambleType; + break; + default: + wd->preambleType = ZM_PREAMBLE_TYPE_SHORT; + break; + } + wd->ws.preambleType = 0; + + if ( wd->wlanMode == ZM_MODE_AP ) + { + vapId = zfwGetVapId(dev); + + if (vapId == 0xffff) + { + wd->ap.authAlgo[0] = wd->ws.authMode; + wd->ap.encryMode[0] = wd->ws.encryMode; + } + else + { + wd->ap.authAlgo[vapId + 1] = wd->ws.authMode; + wd->ap.encryMode[vapId + 1] = wd->ws.encryMode; + } + wd->ws.authMode = 0; + wd->ws.encryMode = ZM_NO_WEP; + + /* Get beaconInterval from WrapperSetting */ + if ((wd->ws.beaconInterval >= 20) && (wd->ws.beaconInterval <= 1000)) + { + wd->beaconInterval = wd->ws.beaconInterval; + } + else + { + wd->beaconInterval = 100; //100ms + } + + if (wd->ws.dtim > 0) + { + wd->dtim = wd->ws.dtim; + } + else + { + wd->dtim = 1; + } + + wd->ap.qosMode = wd->ws.apWmeEnabled & 0x1; + wd->ap.uapsdEnabled = (wd->ws.apWmeEnabled & 0x2) >> 1; + } + else + { + wd->sta.authMode = wd->ws.authMode; + wd->sta.currentAuthMode = wd->ws.authMode; + wd->sta.wepStatus = wd->ws.wepStatus; + + if ( wd->ws.beaconInterval ) + { + wd->beaconInterval = wd->ws.beaconInterval; + } + else + { + wd->beaconInterval = 0x64; + } + + if ( wd->wlanMode == ZM_MODE_IBSS ) + { + /* 1. Set default channel 6 (2437MHz) */ +// wd->frequency = 2437; + + /* 2. Otus support 802.11g Mode */ + if ((wd->ws.adhocMode == ZM_ADHOCBAND_G) || + (wd->ws.adhocMode == ZM_ADHOCBAND_BG) || + (wd->ws.adhocMode == ZM_ADHOCBAND_ABG) ) { + wd->wfc.bIbssGMode = 1; + } else { + wd->wfc.bIbssGMode = 0; + } + + /* 3. set short preamble */ + //wd->sta.preambleType = ZM_PREAMBLE_TYPE_SHORT ; + } + + /* set ATIM window */ + if ( wd->ws.atimWindow ) + { + wd->sta.atimWindow = wd->ws.atimWindow; + } + else + { + //wd->sta.atimWindow = 0x0a; + wd->sta.atimWindow = 0; + } + + //wd->sta.connectingHiddenAP = 1;//wd->ws.connectingHiddenAP; + wd->sta.dropUnencryptedPkts = wd->ws.dropUnencryptedPkts; + wd->sta.ibssJoinOnly = wd->ws.ibssJoinOnly; + + if ( wd->ws.bDesiredBssid ) + { + zfMemoryCopy(wd->sta.desiredBssid, wd->ws.desiredBssid, 6); + wd->sta.bDesiredBssid = TRUE; + wd->ws.bDesiredBssid = FALSE; + } + else + { + wd->sta.bDesiredBssid = FALSE; + } + + /* check ssid */ + if ( wd->ws.ssidLen != 0 ) + { + if ( (!zfMemoryIsEqual(wd->ws.ssid, wd->sta.ssid, + wd->sta.ssidLen))|| + (wd->ws.ssidLen != wd->sta.ssidLen)|| + (wd->sta.authMode == ZM_AUTH_MODE_WPA)|| + (wd->sta.authMode == ZM_AUTH_MODE_WPAPSK) || + (wd->ws.staWmeQosInfo!= 0) ) + { + /*if u-APSD test(set QosInfo), clear connectByReasso to do association (not reassociation)*/ + wd->sta.connectByReasso = FALSE; + wd->sta.failCntOfReasso = 0; + wd->sta.pmkidInfo.bssidCount = 0; + + wd->sta.ssidLen = wd->ws.ssidLen; + zfMemoryCopy(wd->sta.ssid, wd->ws.ssid, wd->sta.ssidLen); + + if ( wd->sta.ssidLen < 32 ) + { + wd->sta.ssid[wd->sta.ssidLen] = 0; + } + } + } + else + { /* ANY BSS */ + wd->sta.ssid[0] = 0; + wd->sta.ssidLen = 0; + } + + wd->sta.wmeEnabled = wd->ws.staWmeEnabled; + wd->sta.wmeQosInfo = wd->ws.staWmeQosInfo; + + } + + zmw_leave_critical_section(dev); +} + +u16_t zfWlanEnable(zdev_t* dev) +{ + u8_t bssid[6] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; + u16_t i; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + if ( wd->wlanMode == ZM_MODE_UNKNOWN ) + { + zm_debug_msg0("Unknown Mode...Skip..."); + return 0; + } + + if (wd->wlanMode == ZM_MODE_AP) + { + u16_t vapId; + + vapId = zfwGetVapId(dev); + + if (vapId == 0xffff) + { + /* AP mode */ + zfApInitStaTbl(dev); + + /* AP default parameters */ + wd->bRate = 0xf; + wd->gRate = 0xff; + wd->bRateBasic = 0xf; + wd->gRateBasic = 0x0; + //wd->beaconInterval = 100; + wd->ap.apBitmap = 1; + wd->ap.beaconCounter = 0; + //wd->ap.vapNumber = 1; //mark by ygwei for Vap + + wd->ap.hideSsid[0] = 0; + wd->ap.staAgingTimeSec = 10*60; + wd->ap.staProbingTimeSec = 60; + + for (i=0; iap.bcmcHead[i] = wd->ap.bcmcTail[i] = 0; + } + + //wd->ap.uniHead = wd->ap.uniTail = 0; + + /* load AP parameters */ + wd->bRateBasic = wd->ws.bRateBasic; + wd->gRateBasic = wd->ws.gRateBasic; + wd->bgMode = wd->ws.bgMode; + if ((wd->ws.ssidLen <= 32) && (wd->ws.ssidLen != 0)) + { + wd->ap.ssidLen[0] = wd->ws.ssidLen; + for(i=0; iws.ssidLen; i++) + { + wd->ap.ssid[0][i] = wd->ws.ssid[i]; + } + wd->ws.ssidLen = 0; // Reset Wrapper Variable + } + + if (wd->ap.encryMode[0] == 0) + { + wd->ap.capab[0] = 0x001; + } + else + { + wd->ap.capab[0] = 0x011; + } + /* set Short Slot Time bit if not 11b */ + if (wd->ap.wlanType[0] != ZM_WLAN_TYPE_PURE_B) + { + wd->ap.capab[0] |= 0x400; + } + + // wd->ap.vapNumber = 1; // mark by ygwei for Vap Test + } + else + { +#if 0 + /* VAP Test Code */ + wd->ap.apBitmap = 0x3; + wd->ap.capab[1] = 0x401; + wd->ap.ssidLen[1] = 4; + wd->ap.ssid[1][0] = 'v'; + wd->ap.ssid[1][1] = 'a'; + wd->ap.ssid[1][2] = 'p'; + wd->ap.ssid[1][3] = '1'; + wd->ap.authAlgo[1] = wd->ws.authMode; + wd->ap.encryMode[1] = wd->ws.encryMode; + wd->ap.vapNumber = 2; +#else + /* VAP Test Code */ + wd->ap.apBitmap = 0x1 | (0x01 << (vapId+1)); + + if ((wd->ws.ssidLen <= 32) && (wd->ws.ssidLen != 0)) + { + wd->ap.ssidLen[vapId+1] = wd->ws.ssidLen; + for(i=0; iws.ssidLen; i++) + { + wd->ap.ssid[vapId+1][i] = wd->ws.ssid[i]; + } + wd->ws.ssidLen = 0; // Reset Wrapper Variable + } + + if (wd->ap.encryMode[vapId+1] == 0) + { + wd->ap.capab[vapId+1] = 0x401; + } + else + { + wd->ap.capab[vapId+1] = 0x411; + } + + wd->ap.authAlgo[vapId+1] = wd->ws.authMode; + wd->ap.encryMode[vapId+1] = wd->ws.encryMode; + + /* Need to be modified when VAP is used */ + //wd->ap.vapNumber = 2; +#endif + } + + wd->ap.vapNumber++; + + zfCoreSetFrequency(dev, wd->frequency); + + zfInitMacApMode(dev); + + /* Disable protection mode */ + zfApSetProtectionMode(dev, 0); + + zfApSendBeacon(dev); + } /*if (wd->wlanMode == ZM_MODE_AP) */ + else + { + zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_INTERNAL); + zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_EXTERNAL); + + zmw_enter_critical_section(dev); + wd->sta.oppositeCount = 0; /* reset opposite count */ + //wd->sta.bAutoReconnect = wd->sta.bAutoReconnectEnabled; + //wd->sta.scanWithSSID = 0; + zfStaInitOppositeInfo(dev); + zmw_leave_critical_section(dev); + + zfStaResetStatus(dev, 0); + + if ( (wd->sta.cmDisallowSsidLength != 0)&& + (wd->sta.ssidLen == wd->sta.cmDisallowSsidLength)&& + (zfMemoryIsEqual(wd->sta.ssid, wd->sta.cmDisallowSsid, + wd->sta.ssidLen)) && + (wd->sta.wepStatus == ZM_ENCRYPTION_TKIP)) + { /* countermeasures */ + zm_debug_msg0("countermeasures disallow association"); + + } + else + { + switch( wd->wlanMode ) + { + case ZM_MODE_IBSS: + /* some registers may be set here */ + if ( wd->sta.authMode == ZM_AUTH_MODE_WPA2PSK ) + { + zfHpSetApStaMode(dev, ZM_HAL_80211_MODE_IBSS_WPA2PSK); + } + else + { + zfHpSetApStaMode(dev, ZM_HAL_80211_MODE_IBSS_GENERAL); + } + + zm_msg0_mm(ZM_LV_0, "ZM_MODE_IBSS"); + zfIbssConnectNetwork(dev); + break; + + case ZM_MODE_INFRASTRUCTURE: + /* some registers may be set here */ + zfHpSetApStaMode(dev, ZM_HAL_80211_MODE_STA); + + zfInfraConnectNetwork(dev); + break; + + case ZM_MODE_PSEUDO: + /* some registers may be set here */ + zfHpSetApStaMode(dev, ZM_HAL_80211_MODE_STA); + + zfUpdateBssid(dev, bssid); + zfCoreSetFrequency(dev, wd->frequency); + break; + + default: + break; + } + } + + } + + + //if ( (wd->wlanMode != ZM_MODE_INFRASTRUCTURE)&& + // (wd->wlanMode != ZM_MODE_AP) ) + if ( wd->wlanMode == ZM_MODE_PSEUDO ) + { + /* Reset Wlan status */ + zfWlanReset(dev); + + if (wd->zfcbConnectNotify != NULL) + { + wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_CONNECT, wd->sta.bssid); + } + zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTED); + } + + + if(wd->wlanMode == ZM_MODE_AP) + { + if (wd->zfcbConnectNotify != NULL) + { + wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_CONNECT, wd->sta.bssid); + } + //zfChangeAdapterState(dev, ZM_STA_STATE_CONNECTED); + } + + // Assign default Tx Rate + if ( wd->sta.EnableHT ) + { + u32_t oneTxStreamCap; + oneTxStreamCap = (zfHpCapability(dev) & ZM_HP_CAP_11N_ONE_TX_STREAM); + if(oneTxStreamCap) + wd->CurrentTxRateKbps = 135000; + else + wd->CurrentTxRateKbps = 270000; + wd->CurrentRxRateKbps = 270000; + } + else + { + wd->CurrentTxRateKbps = 54000; + wd->CurrentRxRateKbps = 54000; + } + + wd->state = ZM_WLAN_STATE_ENABLED; + + return 0; +} + +/* Enable/disable Wlan operation */ +u16_t zfiWlanEnable(zdev_t* dev) +{ + u16_t ret; + + zmw_get_wlan_dev(dev); + + zm_msg0_mm(ZM_LV_1, "Enable Wlan"); + + zfGetWrapperSetting(dev); + + zfZeroMemory((u8_t*) &wd->trafTally, sizeof(struct zsTrafTally)); + + // Reset cmMicFailureCount to 0 for new association request + if ( wd->sta.cmMicFailureCount == 1 ) + { + zfTimerCancel(dev, ZM_EVENT_CM_TIMER); + wd->sta.cmMicFailureCount = 0; + } + + zfFlushVtxq(dev); + if ((wd->queueFlushed & 0x10) != 0) + { + zfHpUsbReset(dev); + } + ret = zfWlanEnable(dev); + + return ret; +} +/* Add a flag named ResetKeyCache to show if KeyCache should be cleared. + for hostapd in AP mode, if driver receives iwconfig ioctl + after setting group key, it shouldn't clear KeyCache. */ +u16_t zfiWlanDisable(zdev_t* dev, u8_t ResetKeyCache) +{ + u16_t i; + u8_t isConnected; + + zmw_get_wlan_dev(dev); + +#ifdef ZM_ENABLE_IBSS_WPA2PSK + zmw_declare_for_critical_section(); +#endif + wd->state = ZM_WLAN_STATE_DISABLED; + + zm_msg0_mm(ZM_LV_1, "Disable Wlan"); + + if ( wd->wlanMode != ZM_MODE_AP ) + { + isConnected = zfStaIsConnected(dev); + + if ( (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)&& + (wd->sta.currentAuthMode != ZM_AUTH_MODE_WPA2) ) + { + /* send deauthentication frame */ + if (isConnected) + { + //zfiWlanDeauth(dev, NULL, 0); + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, wd->sta.bssid, 3, 0, 0); + //zmw_debug_msg0("send a Deauth frame!"); + } + } + + // Remove all the connected peer stations + if ( wd->wlanMode == ZM_MODE_IBSS ) + { + wd->sta.ibssBssIsCreator = 0; + zfTimerCancel(dev, ZM_EVENT_IBSS_MONITOR); + zfStaIbssMonitoring(dev, 1); + } + +#ifdef ZM_ENABLE_IBSS_WPA2PSK + zmw_enter_critical_section(dev); + wd->sta.ibssWpa2Psk = 0; + zmw_leave_critical_section(dev); +#endif + + wd->sta.wpaState = ZM_STA_WPA_STATE_INIT; + + /* reset connect timeout counter */ + wd->sta.connectTimeoutCount = 0; + + /* reset connectState to None */ + wd->sta.connectState = ZM_STA_CONN_STATE_NONE; + + /* reset leap enable variable */ + wd->sta.leapEnabled = 0; + + /* Disable the RIFS Status / RIFS-like frame count / RIFS count */ + if( wd->sta.rifsState == ZM_RIFS_STATE_DETECTED ) + zfHpDisableRifs(dev); + wd->sta.rifsState = ZM_RIFS_STATE_DETECTING; + wd->sta.rifsLikeFrameCnt = 0; + wd->sta.rifsCount = 0; + + wd->sta.osRxFilter = 0; + wd->sta.bSafeMode = 0; + + zfChangeAdapterState(dev, ZM_STA_STATE_DISCONNECT); + if (ResetKeyCache) + zfHpResetKeyCache(dev); + + if (isConnected) + { + if (wd->zfcbConnectNotify != NULL) + { + wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_CONNECTION_DISABLED, wd->sta.bssid); + } + } + else + { + if (wd->zfcbConnectNotify != NULL) + { + wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_DISABLED, wd->sta.bssid); + } + } + } + else //if (wd->wlanMode == ZM_MODE_AP) + { + for (i=0; iap.staTable[i].valid == 1) + { + /* Reason : Sending station is leaving */ + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, + wd->ap.staTable[i].addr, 3, 0, 0); + } + } + + if (ResetKeyCache) + zfHpResetKeyCache(dev); + + wd->ap.vapNumber--; + } + + /* stop beacon */ + zfHpDisableBeacon(dev); + + /* Flush VTxQ and MmQ */ + zfFlushVtxq(dev); + /* Flush AP PS queues */ + zfApFlushBufferedPsFrame(dev); + /* Free buffer in defragment list*/ + zfAgingDefragList(dev, 1); + + #ifdef ZM_ENABLE_AGGREGATION + /* add by honda */ + zfAggRxFreeBuf(dev, 0); //1 for release structure memory + /* end of add by honda */ + #endif + + // Clear the information for the peer stations of IBSS or AP of Station mode + zfZeroMemory((u8_t*)wd->sta.oppositeInfo, sizeof(struct zsOppositeInfo) * ZM_MAX_OPPOSITE_COUNT); + + /* Turn off Software WEP/TKIP */ + if (wd->sta.SWEncryptEnable != 0) + { + zm_debug_msg0("Disable software encryption"); + zfStaDisableSWEncryption(dev); + } + + /* Improve WEP/TKIP performace with HT AP, detail information please look bug#32495 */ + //zfHpSetTTSIFSTime(dev, 0x8); + + return 0; +} + +u16_t zfiWlanSuspend(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + // Change the HAL state to init so that any packet can't be transmitted between + // resume & HAL reinit. This would cause the chip hang issue in OTUS. + zmw_enter_critical_section(dev); + wd->halState = ZM_HAL_STATE_INIT; + zmw_leave_critical_section(dev); + + return 0; +} + +u16_t zfiWlanResume(zdev_t* dev, u8_t doReconn) +{ + u16_t ret; + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + /* Redownload firmware, Reinit MAC,PHY,RF */ + zfHpReinit(dev, wd->frequency); + + //Set channel according to AP's configuration + zfCoreSetFrequencyExV2(dev, wd->frequency, wd->BandWidth40, + wd->ExtOffset, NULL, 1); + + zfHpSetMacAddress(dev, wd->macAddr, 0); + + /* Start Rx */ + zfHpStartRecv(dev); + + zfFlushVtxq(dev); + + if ( wd->wlanMode != ZM_MODE_INFRASTRUCTURE && + wd->wlanMode != ZM_MODE_IBSS ) + { + return 1; + } + + zm_msg0_mm(ZM_LV_1, "Resume Wlan"); + if ( (zfStaIsConnected(dev)) || (zfStaIsConnecting(dev)) ) + { + if (doReconn == 1) + { + zm_msg0_mm(ZM_LV_1, "Re-connect..."); + zmw_enter_critical_section(dev); + wd->sta.connectByReasso = FALSE; + zmw_leave_critical_section(dev); + + zfWlanEnable(dev); + } + else if (doReconn == 0) + { + zfHpSetRollCallTable(dev); + } + } + + ret = 0; + + return ret; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfiWlanFlushAllQueuedBuffers */ +/* Flush Virtual TxQ, MmQ, PS frames and defragment list */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Stephen Chen Atheros Communications, INC. 2007.1 */ +/* */ +/************************************************************************/ +void zfiWlanFlushAllQueuedBuffers(zdev_t* dev) +{ + /* Flush VTxQ and MmQ */ + zfFlushVtxq(dev); + /* Flush AP PS queues */ + zfApFlushBufferedPsFrame(dev); + /* Free buffer in defragment list*/ + zfAgingDefragList(dev, 1); +} + +/* Do WLAN site survey */ +u16_t zfiWlanScan(zdev_t* dev) +{ + u16_t ret = 1; + zmw_get_wlan_dev(dev); + + zm_debug_msg0(""); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + if (wd->wlanMode == ZM_MODE_AP) + { + wd->heartBeatNotification |= ZM_BSSID_LIST_SCAN; + wd->sta.scanFrequency = 0; + //wd->sta.pUpdateBssList->bssCount = 0; + ret = 0; + } + else + { + #if 0 + if ( !zfStaBlockWlanScan(dev) ) + { + zm_debug_msg0("scan request"); + //zfTimerSchedule(dev, ZM_EVENT_SCAN, ZM_TICK_ZERO); + ret = 0; + goto start_scan; + } + #else + goto start_scan; + #endif + } + + zmw_leave_critical_section(dev); + + return ret; + +start_scan: + zmw_leave_critical_section(dev); + + if(wd->ledStruct.LEDCtrlFlagFromReg & ZM_LED_CTRL_FLAG_ALPHA) // flag for Alpha + wd->ledStruct.LEDCtrlFlag |= ZM_LED_CTRL_FLAG_ALPHA; + + ret = zfScanMgrScanStart(dev, ZM_SCAN_MGR_SCAN_EXTERNAL); + + zm_debug_msg1("ret = ", ret); + + return ret; +} + + +/* rate */ +/* 0 : AUTO */ +/* 1 : CCK 1M */ +/* 2 : CCK 2M */ +/* 3 : CCK 5.5M */ +/* 4 : CCK 11M */ +/* 5 : OFDM 6M */ +/* 6 : OFDM 9M */ +/* 7 : OFDM 12M */ +/* 8 : OFDM 18M */ +/* 9 : OFDM 24M */ +/* 10 : OFDM 36M */ +/* 11 : OFDM 48M */ +/* 12 : OFDM 54M */ +/* 13 : MCS 0 */ +/* 28 : MCS 15 */ +u16_t zcRateToMCS[] = + {0xff, 0, 1, 2, 3, 0xb, 0xf, 0xa, 0xe, 0x9, 0xd, 0x8, 0xc}; +u16_t zcRateToMT[] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}; + +u16_t zfiWlanSetTxRate(zdev_t* dev, u16_t rate) +{ // jhlee HT 0 + zmw_get_wlan_dev(dev); + + if (rate <=12) + { + wd->txMCS = zcRateToMCS[rate]; + wd->txMT = zcRateToMT[rate]; + return ZM_SUCCESS; + } + else if ((rate<=28)||(rate==13+32)) + { + wd->txMCS = rate - 12 - 1; + wd->txMT = 2; + return ZM_SUCCESS; + } + + return ZM_ERR_INVALID_TX_RATE; +} + +const u32_t zcRateIdToKbps40M[] = + { + 1000, 2000, 5500, 11000, /* 1M, 2M, 5M, 11M , 0 1 2 3*/ + 6000, 9000, 12000, 18000, /* 6M 9M 12M 18M , 4 5 6 7*/ + 24000, 36000, 48000, 54000, /* 24M 36M 48M 54M , 8 9 10 11*/ + 13500, 27000, 40500, 54000, /* MCS0 MCS1 MCS2 MCS3 , 12 13 14 15*/ + 81000, 108000, 121500, 135000, /* MCS4 MCS5 MCS6 MCS7 , 16 17 18 19*/ + 27000, 54000, 81000, 108000, /* MCS8 MCS9 MCS10 MCS11 , 20 21 22 23*/ + 162000, 216000, 243000, 270000, /* MCS12 MCS13 MCS14 MCS15 , 24 25 26 27*/ + 270000, 300000, 150000 /* MCS14SG, MCS15SG, MCS7SG , 28 29 30*/ + }; + +const u32_t zcRateIdToKbps20M[] = + { + 1000, 2000, 5500, 11000, /* 1M, 2M, 5M, 11M , 0 1 2 3*/ + 6000, 9000, 12000, 18000, /* 6M 9M 12M 18M , 4 5 6 7*/ + 24000, 36000, 48000, 54000, /* 24M 36M 48M 54M , 8 9 10 11*/ + 6500, 13000, 19500, 26000, /* MCS0 MCS1 MCS2 MCS3 , 12 13 14 15*/ + 39000, 52000, 58500, 65000, /* MCS4 MCS5 MCS6 MCS7 , 16 17 18 19*/ + 13000, 26000, 39000, 52000, /* MCS8 MCS9 MCS10 MCS11 , 20 21 22 23*/ + 78000, 104000, 117000, 130000, /* MCS12 MCS13 MCS14 MCS15 , 24 25 26 27*/ + 130000, 144400, 72200 /* MCS14SG, MCS15SG, MSG7SG , 28 29 30*/ + }; + +u32_t zfiWlanQueryTxRate(zdev_t* dev) +{ + u8_t rateId = 0xff; + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + /* If Tx rate had not been trained, return maximum Tx rate instead */ + if ((wd->wlanMode == ZM_MODE_INFRASTRUCTURE) && (zfStaIsConnected(dev))) + { + zmw_enter_critical_section(dev); + //Not in fixed rate mode + if (wd->txMCS == 0xff) + { + if ((wd->sta.oppositeInfo[0].rcCell.flag & ZM_RC_TRAINED_BIT) == 0) + { + rateId = wd->sta.oppositeInfo[0].rcCell.operationRateSet[wd->sta.oppositeInfo[0].rcCell.operationRateCount-1]; + } + else + { + rateId = wd->sta.oppositeInfo[0].rcCell.operationRateSet[wd->sta.oppositeInfo[0].rcCell.currentRateIndex]; + } + } + zmw_leave_critical_section(dev); + } + if (rateId != 0xff) + { + if (wd->sta.htCtrlBandwidth) + { + return zcRateIdToKbps40M[rateId]; + } + else + { + return zcRateIdToKbps20M[rateId]; + } + } + else + { + return wd->CurrentTxRateKbps; + } +} + +void zfWlanUpdateRxRate(zdev_t* dev, struct zsAdditionInfo* addInfo) +{ + u32_t rxRateKbps; + zmw_get_wlan_dev(dev); + //zm_msg1_mm(ZM_LV_0, "addInfo->Tail.Data.RxMacStatus =", addInfo->Tail.Data.RxMacStatus & 0x03); + + /* b5~b4: MPDU indication. */ + /* 00: Single MPDU. */ + /* 10: First MPDU of A-MPDU. */ + /* 11: Middle MPDU of A-MPDU. */ + /* 01: Last MPDU of A-MPDU. */ + /* Only First MPDU and Single MPDU have PLCP header */ + /* First MPDU : (mpduInd & 0x30) == 0x00 */ + /* Single MPDU : (mpduInd & 0x30) == 0x20 */ + if ((addInfo->Tail.Data.RxMacStatus & 0x10) == 0) + { + /* Modulation type */ + wd->modulationType = addInfo->Tail.Data.RxMacStatus & 0x03; + switch(wd->modulationType) + { + case 0x0: wd->rateField = addInfo->PlcpHeader[0] & 0xff; //CCK mode + wd->rxInfo = 0; + break; + case 0x1: wd->rateField = addInfo->PlcpHeader[0] & 0x0f; //Legacy-OFDM mode + wd->rxInfo = 0; + break; + case 0x2: wd->rateField = addInfo->PlcpHeader[3]; //HT-OFDM mode + wd->rxInfo = addInfo->PlcpHeader[6]; + break; + default: break; + } + + rxRateKbps = zfUpdateRxRate(dev); + if (wd->CurrentRxRateUpdated == 1) + { + if (rxRateKbps > wd->CurrentRxRateKbps) + { + wd->CurrentRxRateKbps = rxRateKbps; + } + } + else + { + wd->CurrentRxRateKbps = rxRateKbps; + wd->CurrentRxRateUpdated = 1; + } + } +} +#if 0 +u16_t zcIndextoRateBG[16] = {1000, 2000, 5500, 11000, 0, 0, 0, 0, 48000, + 24000, 12000, 6000, 54000, 36000, 18000, 9000}; +u32_t zcIndextoRateN20L[16] = {6500, 13000, 19500, 26000, 39000, 52000, 58500, + 65000, 13000, 26000, 39000, 52000, 78000, 104000, + 117000, 130000}; +u32_t zcIndextoRateN20S[16] = {7200, 14400, 21700, 28900, 43300, 57800, 65000, + 72200, 14400, 28900, 43300, 57800, 86700, 115600, + 130000, 144400}; +u32_t zcIndextoRateN40L[16] = {13500, 27000, 40500, 54000, 81000, 108000, 121500, + 135000, 27000, 54000, 81000, 108000, 162000, 216000, + 243000, 270000}; +u32_t zcIndextoRateN40S[16] = {15000, 30000, 45000, 60000, 90000, 120000, 135000, + 150000, 30000, 60000, 90000, 120000, 180000, 240000, + 270000, 300000}; +#endif + +extern u16_t zcIndextoRateBG[16]; +extern u32_t zcIndextoRateN20L[16]; +extern u32_t zcIndextoRateN20S[16]; +extern u32_t zcIndextoRateN40L[16]; +extern u32_t zcIndextoRateN40S[16]; + +u32_t zfiWlanQueryRxRate(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + wd->CurrentRxRateUpdated = 0; + return wd->CurrentRxRateKbps; +} + +u32_t zfUpdateRxRate(zdev_t* dev) +{ + u8_t mcs, bandwidth; + u32_t rxRateKbps = 130000; + zmw_get_wlan_dev(dev); + + switch (wd->modulationType) + { + case 0x0: //CCK mode + switch (wd->rateField) + { + case 0x0a: rxRateKbps = 1000; + break; + case 0x14: rxRateKbps = 2000; + + case 0x37: rxRateKbps = 5500; + break; + case 0x6e: rxRateKbps = 11000; + break; + default: + break; + } + break; + case 0x1: //Legacy-OFDM mode + if (wd->rateField <= 15) + { + rxRateKbps = zcIndextoRateBG[wd->rateField]; + } + break; + case 0x2: //HT-OFDM mode + mcs = wd->rateField & 0x7F; + bandwidth = wd->rateField & 0x80; + if (mcs <= 15) + { + if (bandwidth != 0) + { + if((wd->rxInfo & 0x80) != 0) + { + /* Short GI 40 MHz MIMO Rate */ + rxRateKbps = zcIndextoRateN40S[mcs]; + } + else + { + /* Long GI 40 MHz MIMO Rate */ + rxRateKbps = zcIndextoRateN40L[mcs]; + } + } + else + { + if((wd->rxInfo & 0x80) != 0) + { + /* Short GI 20 MHz MIMO Rate */ + rxRateKbps = zcIndextoRateN20S[mcs]; + } + else + { + /* Long GI 20 MHz MIMO Rate */ + rxRateKbps = zcIndextoRateN20L[mcs]; + } + } + } + break; + default: + break; + } + //zm_msg1_mm(ZM_LV_0, "wd->CurrentRxRateKbps=", wd->CurrentRxRateKbps); + + // ToDo: use bandwith field to define 40MB + return rxRateKbps; +} + +/* Get WLAN stastics */ +u16_t zfiWlanGetStatistics(zdev_t* dev) +{ + /* Return link statistics */ + return 0; +} + +u16_t zfiWlanReset(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + wd->state = ZM_WLAN_STATE_DISABLED; + + return zfWlanReset(dev); +} + +/* Reset WLAN */ +u16_t zfWlanReset(zdev_t* dev) +{ + u8_t isConnected; + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zm_debug_msg0("zfWlanReset"); + + isConnected = zfStaIsConnected(dev); + + //if ( wd->wlanMode != ZM_MODE_AP ) + { + if ( (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)&& + (wd->sta.currentAuthMode != ZM_AUTH_MODE_WPA2) ) + { + /* send deauthentication frame */ + if (isConnected) + { + //zfiWlanDeauth(dev, NULL, 0); + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, wd->sta.bssid, 3, 0, 0); + //zmw_debug_msg0("send a Deauth frame!"); + } + } + } + + zfChangeAdapterState(dev, ZM_STA_STATE_DISCONNECT); + zfHpResetKeyCache(dev); + + if (isConnected) + { + //zfiWlanDisable(dev); + if (wd->zfcbConnectNotify != NULL) + { + wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_CONNECTION_RESET, wd->sta.bssid); + } + } + else + { + if (wd->zfcbConnectNotify != NULL) + { + wd->zfcbConnectNotify(dev, ZM_STATUS_MEDIA_RESET, wd->sta.bssid); + } + } + + /* stop beacon */ + zfHpDisableBeacon(dev); + + /* Free buffer in defragment list*/ + zfAgingDefragList(dev, 1); + + /* Flush VTxQ and MmQ */ + zfFlushVtxq(dev); + + #ifdef ZM_ENABLE_AGGREGATION + /* add by honda */ + zfAggRxFreeBuf(dev, 0); //1 for release structure memory + /* end of add by honda */ + #endif + + zfStaRefreshBlockList(dev, 1); + + zmw_enter_critical_section(dev); + + zfTimerCancel(dev, ZM_EVENT_IBSS_MONITOR); + zfTimerCancel(dev, ZM_EVENT_CM_BLOCK_TIMER); + zfTimerCancel(dev, ZM_EVENT_CM_DISCONNECT); + + wd->sta.connectState = ZM_STA_CONN_STATE_NONE; + wd->sta.connectByReasso = FALSE; + wd->sta.cmDisallowSsidLength = 0; + wd->sta.bAutoReconnect = 0; + wd->sta.InternalScanReq = 0; + wd->sta.encryMode = ZM_NO_WEP; + wd->sta.wepStatus = ZM_ENCRYPTION_WEP_DISABLED; + wd->sta.wpaState = ZM_STA_WPA_STATE_INIT; + wd->sta.cmMicFailureCount = 0; + wd->sta.ibssBssIsCreator = 0; +#ifdef ZM_ENABLE_IBSS_WPA2PSK + wd->sta.ibssWpa2Psk = 0; +#endif + /* reset connect timeout counter */ + wd->sta.connectTimeoutCount = 0; + + /* reset leap enable variable */ + wd->sta.leapEnabled = 0; + + /* Reset the RIFS Status / RIFS-like frame count / RIFS count */ + if( wd->sta.rifsState == ZM_RIFS_STATE_DETECTED ) + zfHpDisableRifs(dev); + wd->sta.rifsState = ZM_RIFS_STATE_DETECTING; + wd->sta.rifsLikeFrameCnt = 0; + wd->sta.rifsCount = 0; + + wd->sta.osRxFilter = 0; + wd->sta.bSafeMode = 0; + + // Clear the information for the peer stations of IBSS or AP of Station mode + zfZeroMemory((u8_t*)wd->sta.oppositeInfo, sizeof(struct zsOppositeInfo) * ZM_MAX_OPPOSITE_COUNT); + + zmw_leave_critical_section(dev); + + zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_INTERNAL); + zfScanMgrScanStop(dev, ZM_SCAN_MGR_SCAN_EXTERNAL); + + /* Turn off Software WEP/TKIP */ + if (wd->sta.SWEncryptEnable != 0) + { + zm_debug_msg0("Disable software encryption"); + zfStaDisableSWEncryption(dev); + } + + /* Improve WEP/TKIP performace with HT AP, detail information please look bug#32495 */ + //zfHpSetTTSIFSTime(dev, 0x8); + + /* Keep Pseudo mode */ + if ( wd->wlanMode != ZM_MODE_PSEUDO ) + { + wd->wlanMode = ZM_MODE_INFRASTRUCTURE; + } + return 0; +} + +/* Deauthenticate a STA */ +u16_t zfiWlanDeauth(zdev_t* dev, u16_t* macAddr, u16_t reason) +{ + zmw_get_wlan_dev(dev); + + if ( wd->wlanMode == ZM_MODE_AP ) + { + //u16_t id; + + /* + * we will reset all key in zfHpResetKeyCache() when call + * zfiWlanDisable(), if we want to reset PairwiseKey for each sta, + * need to use a nullAddr to let keyindex not match. + * otherwise hardware will still find PairwiseKey when AP change + * encryption mode from WPA to WEP + */ + + /* + if ((id = zfApFindSta(dev, macAddr)) != 0xffff) + { + u32_t key[8]; + u16_t nullAddr[3] = { 0x0, 0x0, 0x0 }; + + if (wd->ap.staTable[i].encryMode != ZM_NO_WEP) + { + zfHpSetApPairwiseKey(dev, nullAddr, + ZM_NO_WEP, &key[0], &key[4], i+1); + } + //zfHpSetApPairwiseKey(dev, (u16_t *)macAddr, + // ZM_NO_WEP, &key[0], &key[4], id+1); + wd->ap.staTable[id].encryMode = ZM_NO_WEP; + wd->ap.staTable[id].keyIdx = 0xff; + } + */ + + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, macAddr, reason, 0, 0); + } + else + { + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_DEAUTH, wd->sta.bssid, 3, 0, 0); + } + + /* Issue DEAUTH command to FW */ + return 0; +} + + +/* XP packet filter feature : */ +/* 1=>enable: All multicast address packets, not just the ones enumerated in the multicast address list. */ +/* 0=>disable */ +void zfiWlanSetAllMulticast(zdev_t* dev, u32_t setting) +{ + zmw_get_wlan_dev(dev); + zm_msg1_mm(ZM_LV_0, "sta.bAllMulticast = ", setting); + wd->sta.bAllMulticast = (u8_t)setting; +} + + +/* HT configure API */ +void zfiWlanSetHTCtrl(zdev_t* dev, u32_t *setting, u32_t forceTxTPC) +{ + zmw_get_wlan_dev(dev); + + wd->preambleType = (u8_t)setting[0]; + wd->sta.preambleTypeHT = (u8_t)setting[1]; + wd->sta.htCtrlBandwidth = (u8_t)setting[2]; + wd->sta.htCtrlSTBC = (u8_t)setting[3]; + wd->sta.htCtrlSG = (u8_t)setting[4]; + wd->sta.defaultTA = (u8_t)setting[5]; + wd->enableAggregation = (u8_t)setting[6]; + wd->enableWDS = (u8_t)setting[7]; + + wd->forceTxTPC = forceTxTPC; +} + +/* FB50 in OS XP, RD private test code */ +void zfiWlanQueryHTCtrl(zdev_t* dev, u32_t *setting, u32_t *forceTxTPC) +{ + zmw_get_wlan_dev(dev); + + setting[0] = wd->preambleType; + setting[1] = wd->sta.preambleTypeHT; + setting[2] = wd->sta.htCtrlBandwidth; + setting[3] = wd->sta.htCtrlSTBC; + setting[4] = wd->sta.htCtrlSG; + setting[5] = wd->sta.defaultTA; + setting[6] = wd->enableAggregation; + setting[7] = wd->enableWDS; + + *forceTxTPC = wd->forceTxTPC; +} + +void zfiWlanDbg(zdev_t* dev, u8_t setting) +{ + zmw_get_wlan_dev(dev); + + wd->enableHALDbgInfo = setting; +} + +/* FB50 in OS XP, RD private test code */ +void zfiWlanSetRxPacketDump(zdev_t* dev, u32_t setting) +{ + zmw_get_wlan_dev(dev); + if (setting) + { + wd->rxPacketDump = 1; /* enable */ + } + else + { + wd->rxPacketDump = 0; /* disable */ + } +} + + +/* FB50 in OS XP, RD private test code */ +/* Tally */ +void zfiWlanResetTally(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + wd->commTally.txUnicastFrm = 0; //txUnicastFrames + wd->commTally.txMulticastFrm = 0; //txMulticastFrames + wd->commTally.txUnicastOctets = 0; //txUniOctets byte size + wd->commTally.txMulticastOctets = 0; //txMultiOctets byte size + wd->commTally.txFrmUpperNDIS = 0; + wd->commTally.txFrmDrvMgt = 0; + wd->commTally.RetryFailCnt = 0; + wd->commTally.Hw_TotalTxFrm = 0; //Hardware total Tx Frame + wd->commTally.Hw_RetryCnt = 0; //txMultipleRetriesFrames + wd->commTally.Hw_UnderrunCnt = 0;// + wd->commTally.DriverRxFrmCnt = 0;// + wd->commTally.rxUnicastFrm = 0; //rxUnicastFrames + wd->commTally.rxMulticastFrm = 0; //rxMulticastFrames + wd->commTally.NotifyNDISRxFrmCnt = 0;// + wd->commTally.rxUnicastOctets = 0; //rxUniOctets byte size + wd->commTally.rxMulticastOctets = 0; //rxMultiOctets byte size + wd->commTally.DriverDiscardedFrm = 0;// Discard by ValidateFrame + wd->commTally.LessThanDataMinLen = 0;// + wd->commTally.GreaterThanMaxLen = 0;// + wd->commTally.DriverDiscardedFrmCauseByMulticastList = 0; + wd->commTally.DriverDiscardedFrmCauseByFrmCtrl = 0; + wd->commTally.rxNeedFrgFrm = 0; // need more frg frm + wd->commTally.DriverRxMgtFrmCnt = 0; + wd->commTally.rxBroadcastFrm = 0; //Receive broadcast frame count + wd->commTally.rxBroadcastOctets = 0; //Receive broadcast frame byte size + wd->commTally.Hw_TotalRxFrm = 0;// + wd->commTally.Hw_CRC16Cnt = 0; //rxPLCPCRCErrCnt + wd->commTally.Hw_CRC32Cnt = 0; //rxCRC32ErrCnt + wd->commTally.Hw_DecrypErr_UNI = 0;// + wd->commTally.Hw_DecrypErr_Mul = 0;// + wd->commTally.Hw_RxFIFOOverrun = 0;// + wd->commTally.Hw_RxTimeOut = 0; + wd->commTally.LossAP = 0;// + + wd->commTally.Tx_MPDU = 0; + wd->commTally.BA_Fail = 0; + wd->commTally.Hw_Tx_AMPDU = 0; + wd->commTally.Hw_Tx_MPDU = 0; + + wd->commTally.txQosDropCount[0] = 0; + wd->commTally.txQosDropCount[1] = 0; + wd->commTally.txQosDropCount[2] = 0; + wd->commTally.txQosDropCount[3] = 0; + wd->commTally.txQosDropCount[4] = 0; + + wd->commTally.Hw_RxMPDU = 0; + wd->commTally.Hw_RxDropMPDU = 0; + wd->commTally.Hw_RxDelMPDU = 0; + + wd->commTally.Hw_RxPhyMiscError = 0; + wd->commTally.Hw_RxPhyXRError = 0; + wd->commTally.Hw_RxPhyOFDMError = 0; + wd->commTally.Hw_RxPhyCCKError = 0; + wd->commTally.Hw_RxPhyHTError = 0; + wd->commTally.Hw_RxPhyTotalCount = 0; + +#if (defined(GCCK) && defined(OFDM)) + wd->commTally.rx11bDataFrame = 0; + wd->commTally.rxOFDMDataFrame = 0; +#endif + + zmw_leave_critical_section(dev); +} + +/* FB50 in OS XP, RD private test code */ +void zfiWlanQueryTally(zdev_t* dev, struct zsCommTally *tally) +{ + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + zfMemoryCopy((u8_t*)tally, (u8_t*)&wd->commTally, sizeof(struct zsCommTally)); + zmw_leave_critical_section(dev); +} +void zfiWlanQueryTrafTally(zdev_t* dev, struct zsTrafTally *tally) +{ + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + zfMemoryCopy((u8_t*)tally, (u8_t*)&wd->trafTally, sizeof(struct zsTrafTally)); + zmw_leave_critical_section(dev); +} + +void zfiWlanQueryMonHalRxInfo(zdev_t* dev, struct zsMonHalRxInfo *monHalRxInfo) +{ + zfHpQueryMonHalRxInfo(dev, (u8_t *)monHalRxInfo); +} + +/* parse the modeMDKEnable to DrvCore */ +void zfiDKEnable(zdev_t* dev, u32_t enable) +{ + zmw_get_wlan_dev(dev); + + wd->modeMDKEnable = enable; + zm_debug_msg1("modeMDKEnable = ", wd->modeMDKEnable); +} + +/* airoPeek */ +u32_t zfiWlanQueryPacketTypePromiscuous(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + return wd->swSniffer; +} + +/* airoPeek */ +void zfiWlanSetPacketTypePromiscuous(zdev_t* dev, u32_t setValue) +{ + zmw_get_wlan_dev(dev); + + wd->swSniffer = setValue; + zm_msg1_mm(ZM_LV_0, "wd->swSniffer ", wd->swSniffer); + if (setValue) + { + /* write register for sniffer mode */ + zfHpSetSnifferMode(dev, 1); + zm_msg0_mm(ZM_LV_1, "enalbe sniffer mode"); + } + else + { + zfHpSetSnifferMode(dev, 0); + zm_msg0_mm(ZM_LV_0, "disalbe sniffer mode"); + } +} + +void zfiWlanSetXLinkMode(zdev_t* dev, u32_t setValue) +{ + zmw_get_wlan_dev(dev); + + wd->XLinkMode = setValue; + if (setValue) + { + /* write register for sniffer mode */ + zfHpSetSnifferMode(dev, 1); + } + else + { + zfHpSetSnifferMode(dev, 0); + } +} + +extern void zfStaChannelManagement(zdev_t* dev, u8_t scan); +void zfiSetChannelManagement(zdev_t* dev, u32_t setting) +{ + zmw_get_wlan_dev(dev); + + switch (setting) + { + case 1: + wd->sta.EnableHT = 1; + wd->BandWidth40 = 1; + wd->ExtOffset = 1; + break; + case 3: + wd->sta.EnableHT = 1; + wd->BandWidth40 = 1; + wd->ExtOffset = 3; + break; + case 0: + wd->sta.EnableHT = 1; + wd->BandWidth40 = 0; + wd->ExtOffset = 0; + break; + default: + wd->BandWidth40 = 0; + wd->ExtOffset = 0; + break; + + } + zfCoreSetFrequencyEx(dev, wd->frequency, wd->BandWidth40, + wd->ExtOffset, NULL); +} + +void zfiSetRifs(zdev_t* dev, u16_t setting) +{ + zmw_get_wlan_dev(dev); + + wd->sta.ie.HtInfo.ChannelInfo |= ExtHtCap_RIFSMode; + wd->sta.EnableHT = 1; + switch (setting) + { + case 0: + wd->sta.HT2040 = 0; +// zfHpSetRifs(dev, 1, 0, (wd->sta.currentFrequency < 3000)? 1:0); + break; + case 1: + wd->sta.HT2040 = 1; +// zfHpSetRifs(dev, 1, 1, (wd->sta.currentFrequency < 3000)? 1:0); + break; + default: + wd->sta.HT2040 = 0; +// zfHpSetRifs(dev, 1, 0, (wd->sta.currentFrequency < 3000)? 1:0); + break; + } +} + +void zfiCheckRifs(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + if(wd->sta.ie.HtInfo.ChannelInfo & ExtHtCap_RIFSMode) + { +// zfHpSetRifs(dev, wd->sta.EnableHT, wd->sta.HT2040, (wd->sta.currentFrequency < 3000)? 1:0); + } +} + +void zfiSetReorder(zdev_t* dev, u16_t value) +{ + zmw_get_wlan_dev(dev); + + wd->reorder = value; +} + +void zfiSetSeqDebug(zdev_t* dev, u16_t value) +{ + zmw_get_wlan_dev(dev); + + wd->seq_debug = value; +} --- linux-2.6.28.orig/drivers/staging/otus/80211core/coid.c +++ linux-2.6.28/drivers/staging/otus/80211core/coid.c @@ -0,0 +1,2695 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* */ +/* Module Name : iod.c */ +/* */ +/* Abstract */ +/* This module contains OID functions. */ +/* */ +/* NOTES */ +/* None */ +/* */ +/************************************************************************/ +#include "cprecomp.h" +#include "../hal/hpreg.h" + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfiWlanQueryMacAddress */ +/* Query OWN MAC address. */ +/* */ +/* INPUTS */ +/* addr : for return MAC address */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2005.10 */ +/* */ +/************************************************************************/ +void zfiWlanQueryMacAddress(zdev_t* dev, u8_t* addr) +{ + u16_t vapId = 0; + zmw_get_wlan_dev(dev); + + vapId = zfwGetVapId(dev); + + addr[0] = (u8_t)(wd->macAddr[0] & 0xff); + addr[1] = (u8_t)(wd->macAddr[0] >> 8); + addr[2] = (u8_t)(wd->macAddr[1] & 0xff); + addr[3] = (u8_t)(wd->macAddr[1] >> 8); + addr[4] = (u8_t)(wd->macAddr[2] & 0xff); + if (vapId == 0xffff) + addr[5] = (u8_t)(wd->macAddr[2] >> 8); + else + { +#ifdef ZM_VAPMODE_MULTILE_SSID + addr[5] = (u8_t)(wd->macAddr[2] >> 8); // Multiple SSID +#else + addr[5] = vapId + 1 + (u8_t)(wd->macAddr[2] >> 8); //VAP +#endif + } + + return; +} + +void zfiWlanQueryBssList(zdev_t* dev, struct zsBssList* pBssList) +{ + struct zsBssInfo* pBssInfo; + struct zsBssInfo* pDstBssInfo; + u8_t i; + u8_t* pMemList; + u8_t* pMemInfo; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + pMemList = (u8_t*) pBssList; + pMemInfo = pMemList + sizeof(struct zsBssList); + pBssList->head = (struct zsBssInfo*) pMemInfo; + + zmw_enter_critical_section(dev); + + pBssInfo = wd->sta.bssList.head; + pDstBssInfo = (struct zsBssInfo*) pMemInfo; + pBssList->bssCount = wd->sta.bssList.bssCount; + + for( i=0; ista.bssList.bssCount; i++ ) + { + zfMemoryCopy((u8_t*)pDstBssInfo, (u8_t*)pBssInfo, + sizeof(struct zsBssInfo)); + + if ( pBssInfo->next != NULL ) + { + pBssInfo = pBssInfo->next; + pDstBssInfo->next = pDstBssInfo + 1; + pDstBssInfo++; + } + else + { + zm_assert(i==(wd->sta.bssList.bssCount-1)); + } + } + + zmw_leave_critical_section(dev); + + zfScanMgrScanAck(dev); +} + +void zfiWlanQueryBssListV1(zdev_t* dev, struct zsBssListV1* bssListV1) +{ + struct zsBssInfo* pBssInfo; + //struct zsBssInfo* pDstBssInfo; + u8_t i, j, bdrop = 0, k = 0, Same_Count = 0; + u8_t bssid[6]; + //u8_t* pMemList; + //u8_t* pMemInfo; + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + bssListV1->bssCount = wd->sta.bssList.bssCount; + + pBssInfo = wd->sta.bssList.head; + ZM_MAC_WORD_TO_BYTE(wd->sta.bssid, bssid); + + for( i=0; ista.bssList.bssCount; i++ ) + { + bdrop = 0; + if ( zfStaIsConnected(dev) + && (wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) ) + { + for (j = 0; j < 6; j++) + { + if ( pBssInfo->bssid[j] != bssid[j] ) + { + break; + } + } + + if ( (j == 6) + &&((pBssInfo->ssid[1] == wd->sta.ssidLen) || (pBssInfo->ssid[1] == 0) )&& (pBssInfo->frequency == wd->frequency) ) + { + if(pBssInfo->ssid[1] == 0) + pBssInfo->ssid[1] = wd->sta.ssidLen; + + if(Same_Count == 0) + {//First meet + Same_Count++; + } + else + {//same one + bdrop = 1; + bssListV1->bssCount--; + } + + } + } + + if (bdrop == 0) + { + zfMemoryCopy((u8_t*)(&bssListV1->bssInfo[k]), (u8_t*)pBssInfo, + sizeof(struct zsBssInfo)); + + if(Same_Count == 1) + { + zfMemoryCopy(&(bssListV1->bssInfo[k].ssid[2]), wd->sta.ssid, wd->sta.ssidLen); + Same_Count++; + } + + k++; + } + + if ( pBssInfo->next != NULL ) + { + pBssInfo = pBssInfo->next; + } + else + { + zm_assert(i==(wd->sta.bssList.bssCount-1)); + } + } + + zmw_leave_critical_section(dev); + + zfScanMgrScanAck(dev); +} + +void zfiWlanQueryAdHocCreatedBssDesc(zdev_t* dev, struct zsBssInfo *pBssInfo) +{ + zmw_get_wlan_dev(dev); + + zfMemoryCopy((u8_t *)pBssInfo, (u8_t *)&wd->sta.ibssBssDesc, sizeof(struct zsBssInfo)); +} + +u8_t zfiWlanQueryAdHocIsCreator(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + return wd->sta.ibssBssIsCreator; +} + +u32_t zfiWlanQuerySupportMode(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + return wd->supportMode; +} + +u32_t zfiWlanQueryTransmitPower(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + u32_t ret = 0; + + if (zfStaIsConnected(dev)) { + ret = wd->sta.connPowerInHalfDbm; + } else { + ret = zfHpGetTransmitPower(dev); + } + + return ret; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfiWlanFlushBssList */ +/* Flush BSSID List. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* none */ +/* */ +/* AUTHOR */ +/* Stephen Chen Atheros Communications, INC. 2006.12 */ +/* */ +/************************************************************************/ +void zfiWlanFlushBssList(zdev_t* dev) +{ + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + /* Call zfBssInfoRefresh() twice to remove all entry */ + zfBssInfoRefresh(dev, 1); + zmw_leave_critical_section(dev); +} + +void zfiWlanSetWlanMode(zdev_t* dev, u8_t wlanMode) +{ + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + wd->ws.wlanMode = wlanMode; + zmw_leave_critical_section(dev); +} + +void zfiWlanSetAuthenticationMode(zdev_t* dev, u8_t authMode) +{ + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + wd->ws.authMode = authMode; + zmw_leave_critical_section(dev); +} + +void zfiWlanSetWepStatus(zdev_t* dev, u8_t wepStatus) +{ + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + wd->ws.wepStatus = wepStatus; + zmw_leave_critical_section(dev); + +} + +void zfiWlanSetSSID(zdev_t* dev, u8_t* ssid, u8_t ssidLength) +{ + u16_t i; + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + if ( ssidLength <= 32 ) + { + zmw_enter_critical_section(dev); + + wd->ws.ssidLen = ssidLength; + zfMemoryCopy(wd->ws.ssid, ssid, ssidLength); + + if ( ssidLength < 32 ) + { + wd->ws.ssid[ssidLength] = 0; + } + + wd->ws.probingSsidList[0].ssidLen = ssidLength; + zfMemoryCopy(wd->ws.probingSsidList[0].ssid, ssid, ssidLength); + for (i=1; iws.probingSsidList[i].ssidLen = 0; + } + + zmw_leave_critical_section(dev); + } +} + +void zfiWlanSetFragThreshold(zdev_t* dev, u16_t fragThreshold) +{ + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + if (fragThreshold == 0) + { /* fragmentation is disabled */ + wd->fragThreshold = 32767; + } + else if (fragThreshold < 256) + { + /* Minimum fragment threshold */ + wd->fragThreshold = 256; + } + else if (fragThreshold > 2346) + { + wd->fragThreshold = 2346; + } + else + { + wd->fragThreshold = fragThreshold & 0xfffe; + } + + zmw_leave_critical_section(dev); +} + +void zfiWlanSetRtsThreshold(zdev_t* dev, u16_t rtsThreshold) +{ + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + wd->rtsThreshold = rtsThreshold; + zmw_leave_critical_section(dev); +} + +void zfiWlanSetFrequency(zdev_t* dev, u32_t frequency, u8_t bImmediate) +{ + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + if ( bImmediate ) + { + zmw_enter_critical_section(dev); + wd->frequency = (u16_t) (frequency/1000); + zmw_leave_critical_section(dev); + zfCoreSetFrequency(dev, wd->frequency); + } + else + { + zmw_enter_critical_section(dev); + if( frequency == 0 ) + { // Auto select clean channel depend on wireless environment ! + wd->ws.autoSetFrequency = 0; + } + wd->ws.frequency = (u16_t) (frequency/1000); + zmw_leave_critical_section(dev); + } +} + +void zfiWlanSetBssid(zdev_t* dev, u8_t* bssid) +{ + u16_t i; + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + for (i=0; i<6; i++) + { + wd->ws.desiredBssid[i] = bssid[i]; + } + wd->ws.bDesiredBssid = TRUE; + zmw_leave_critical_section(dev); + +} + +void zfiWlanSetBeaconInterval(zdev_t* dev, + u16_t beaconInterval, + u8_t bImmediate) +{ + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + if ( bImmediate ) + { + zmw_enter_critical_section(dev); + wd->beaconInterval = beaconInterval; + zmw_leave_critical_section(dev); + + /* update beacon interval here */ + } + else + { + zmw_enter_critical_section(dev); + wd->ws.beaconInterval = beaconInterval; + zmw_leave_critical_section(dev); + } +} + + +void zfiWlanSetDtimCount(zdev_t* dev, u8_t dtim) +{ + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + if (dtim > 0) + { + wd->ws.dtim = dtim; + } + zmw_leave_critical_section(dev); +} + + +void zfiWlanSetAtimWindow(zdev_t* dev, u16_t atimWindow, u8_t bImmediate) +{ + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + if ( bImmediate ) + { + zmw_enter_critical_section(dev); + wd->sta.atimWindow = atimWindow; + zmw_leave_critical_section(dev); + + /* atim window here */ + } + else + { + zmw_enter_critical_section(dev); + wd->ws.atimWindow = atimWindow; + zmw_leave_critical_section(dev); + } +} + + +void zfiWlanSetEncryMode(zdev_t* dev, u8_t encryMode) +{ + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + if (wd->wlanMode == ZM_MODE_AP) + { + /* Hostapd Issue */ + if ((wd->ws.encryMode != ZM_AES) && (wd->ws.encryMode != ZM_TKIP)) + wd->ws.encryMode = encryMode; + } + else + wd->ws.encryMode = encryMode; + zmw_leave_critical_section(dev); +} + +void zfiWlanSetDefaultKeyId(zdev_t* dev, u8_t keyId) +{ + zmw_get_wlan_dev(dev); + + wd->sta.keyId = keyId; +} + +u8_t zfiWlanQueryIsPKInstalled(zdev_t *dev, u8_t *staMacAddr) +{ + u8_t isInstalled = 0; + +#if 1 +//#ifdef ZM_ENABLE_IBSS_WPA2PSK + u8_t res, peerIdx; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + res = zfStaFindOppositeByMACAddr(dev, (u16_t *)staMacAddr, &peerIdx); + if( res == 0 ) + { + isInstalled = wd->sta.oppositeInfo[peerIdx].pkInstalled; + } + zmw_leave_critical_section(dev); +//#endif +#endif + + return isInstalled; +} + +u8_t zfiWlanSetKey(zdev_t* dev, struct zsKeyInfo keyInfo) +{ + u16_t broadcast[3] = {0xffff, 0xffff, 0xffff}; + u32_t* key; + u8_t encryMode = ZM_NO_WEP; +#ifdef ZM_ENABLE_IBSS_WPA2PSK + u8_t encryType = ZM_NO_WEP; +#endif + u8_t micKey[16]; + u16_t id = 0; + u8_t vapId, i, addr[6]; + u8_t userIdx=0; + +#ifdef ZM_ENABLE_IBSS_WPA2PSK + /* Determine opposite exist or not */ + u8_t res, peerIdx; +// u8_t userIdx=0; + + zmw_get_wlan_dev(dev); + + if ( wd->sta.ibssWpa2Psk == 1 ) + { + zmw_enter_critical_section(dev); + res = zfStaFindOppositeByMACAddr(dev, (u16_t*)keyInfo.macAddr, &peerIdx); + if( res == 0 ) + { + userIdx = peerIdx; + if ( wd->sta.oppositeInfo[userIdx].camIdx == 0xff ) + wd->sta.oppositeInfo[userIdx].camIdx = userIdx; + } + zmw_leave_critical_section(dev); + } +#else + zmw_get_wlan_dev(dev); +#endif + + if ( keyInfo.flag & ZM_KEY_FLAG_AUTHENTICATOR ) + { /* set key by authenticator */ + /* set pairwise key */ + if (keyInfo.flag & ZM_KEY_FLAG_PK) + { + /* Find STA's information */ + if ((id = zfApFindSta(dev, keyInfo.macAddr)) == 0xffff) + { + /* Can't STA in the staTable */ + return ZM_STATUS_FAILURE; + } + + wd->ap.staTable[id].iv16 = 0; + wd->ap.staTable[id].iv32 = 0; + + if (keyInfo.keyLength == 32) + { /* TKIP */ + //u8_t KeyRsc[6] = {0, 0, 0, 0, 0, 0}; + + /* In the current AP mode, we set KeyRsc to zero */ + //zfTkipInit(keyInfo.key, (u8_t*) wd->macAddr, + // &(wd->ap.staTable[id].txSeed), KeyRsc); + //zfTkipInit(keyInfo.key, (u8_t*) keyInfo.macAddr, + // &(wd->ap.staTable[id].rxSeed), KeyRsc); +#ifdef ZM_ENABLE_CENC + if (keyInfo.flag & ZM_KEY_FLAG_CENC) + { + zm_debug_msg0("Set CENC pairwise Key"); + + wd->ap.staTable[id].encryMode = ZM_CENC; + + /* Reset txiv and rxiv */ + wd->ap.staTable[id].txiv[0] = 0x5c365c37; + wd->ap.staTable[id].txiv[1] = 0x5c365c36; + wd->ap.staTable[id].txiv[2] = 0x5c365c36; + wd->ap.staTable[id].txiv[3] = 0x5c365c36; + + wd->ap.staTable[id].rxiv[0] = 0x5c365c36; + wd->ap.staTable[id].rxiv[1] = 0x5c365c36; + wd->ap.staTable[id].rxiv[2] = 0x5c365c36; + wd->ap.staTable[id].rxiv[3] = 0x5c365c36; + + /* Set Key Index */ + wd->ap.staTable[id].cencKeyIdx = keyInfo.keyIndex; + + //zfCoreSetKey(dev, id+1, 1, ZM_CENC, (u16_t *)keyInfo.macAddr, + // (u32_t*) &keyInfo.key[16]); + } + else +#endif //ZM_ENABLE_CENC + { + wd->ap.staTable[id].encryMode = ZM_TKIP; + + zfMemoryCopy(micKey, &keyInfo.key[16], 8); + zfMemoryCopy(&micKey[8], &keyInfo.key[24], 8); + + //zfCoreSetKey(dev, id+1, 1, ZM_TKIP, (u16_t *)keyInfo.macAddr, + // (u32_t*) micKey); + + /* For fragmentation, we use software MIC */ + zfMemoryCopy((u8_t *)&(wd->ap.staTable[id].txMicKey), &(keyInfo.key[16]), 8); + zfMemoryCopy((u8_t *)&(wd->ap.staTable[id].rxMicKey), &(keyInfo.key[24]), 8); + + } + } + else if (keyInfo.keyLength == 16) + { /* AES */ + wd->ap.staTable[id].encryMode = ZM_AES; + } + else if (keyInfo.keyLength == 0) + { + /* Clear Key Info */ + zfApClearStaKey(dev, (u16_t *)keyInfo.macAddr); + + return ZM_STATUS_SUCCESS; + } + else + { + return ZM_STATUS_FAILURE; + } + + //zfCoreSetKey(dev, id+1, 0, wd->ap.staTable[id].encryMode, + // (u16_t *)keyInfo.macAddr, (u32_t*) keyInfo.key); + zfHpSetApPairwiseKey(dev, (u16_t *)keyInfo.macAddr, + wd->ap.staTable[id].encryMode, (u32_t*) keyInfo.key, + (u32_t*) &keyInfo.key[16], id+1); + wd->ap.staTable[id].keyIdx = id + 1 + 4; + } + else if (keyInfo.flag & ZM_KEY_FLAG_GK) + { + vapId = keyInfo.vapId; + + wd->ap.iv16[vapId] = 0; + wd->ap.iv32[vapId] = 0; + + if (keyInfo.keyLength == 32) + { /* TKIP */ + //u8_t KeyRsc[6] = {0, 0, 0, 0, 0, 0}; + + //zfTkipInit(keyInfo.key, (u8_t*) wd->macAddr, + // &(wd->ap.bcSeed), KeyRsc); +#ifdef ZM_ENABLE_CENC + if (keyInfo.flag & ZM_KEY_FLAG_CENC) + { + encryMode = ZM_CENC; + zm_debug_msg0("Set CENC group Key"); + + /* Reset txiv and rxiv */ + wd->ap.txiv[vapId][0] = 0x5c365c36; + wd->ap.txiv[vapId][1] = 0x5c365c36; + wd->ap.txiv[vapId][2] = 0x5c365c36; + wd->ap.txiv[vapId][3] = 0x5c365c36; + + //zfCoreSetKey(dev, 0, 1, ZM_CENC, keyInfo.vapAddr, + // (u32_t*) &keyInfo.key[16]); + key = (u32_t*) keyInfo.key; + } + else +#endif //ZM_ENABLE_CENC + { + encryMode = ZM_TKIP; + key = (u32_t *)keyInfo.key; + + /* set MIC key to HMAC */ + //zfCoreSetKey(dev, 0, 1, ZM_TKIP, broadcast, + // (u32_t*) (&keyInfo.key[16])); + //zfCoreSetKey(dev, 0, 1, ZM_TKIP, keyInfo.vapAddr, + // (u32_t*) (&keyInfo.key[16])); + + zfMicSetKey(&(keyInfo.key[16]), &(wd->ap.bcMicKey[0])); + key = (u32_t*) keyInfo.key; + } + } + else if (keyInfo.keyLength == 16) + { /* AES */ + encryMode = ZM_AES; + key = (u32_t *)keyInfo.key; + zm_debug_msg0("CWY - Set AES Group Key"); + } + else if (keyInfo.keyLength == 0) + { + /* Clear Key Info */ + zfApClearStaKey(dev, broadcast); + + /* Turn off WEP bit in the capability field */ + wd->ap.capab[vapId] &= 0xffef; + + return ZM_STATUS_SUCCESS; + } + else + { /* WEP */ + if (keyInfo.keyLength == 5) + { + encryMode = ZM_WEP64; + } + else if (keyInfo.keyLength == 13) + { + encryMode = ZM_WEP128; + } + else if (keyInfo.keyLength == 29) + { + encryMode = ZM_WEP256; + } + + key = (u32_t*) keyInfo.key; + } + + // Modification for CAM not support VAP search + //zfCoreSetKey(dev, 0, 0, encryMode, broadcast, key); + //zfCoreSetKey(dev, 0, 0, encryMode, wd->macAddr, key); + //zfCoreSetKey(dev, 0, 0, encryMode, keyInfo.vapAddr, key); + zfHpSetApGroupKey(dev, wd->macAddr, encryMode, + key, (u32_t*) &keyInfo.key[16], vapId); + + //zfiWlanSetEncryMode(dev, encryMode); + wd->ws.encryMode = encryMode; + + /* set the multicast address encryption type */ + wd->ap.encryMode[vapId] = encryMode; + + /* set the multicast key index */ + wd->ap.bcKeyIndex[vapId] = keyInfo.keyIndex; + wd->ap.bcHalKeyIdx[vapId] = vapId + 60; + + /* Turn on WEP bit in the capability field */ + wd->ap.capab[vapId] |= 0x10; + } + } + else + { /* set by supplicant */ + + if ( keyInfo.flag & ZM_KEY_FLAG_PK ) + { /* set pairwise key */ + + //zfTkipInit(keyInfo.key, (u8_t*) wd->macAddr, + // &wd->sta.txSeed, keyInfo.initIv); + //zfTkipInit(keyInfo.key, (u8_t*) wd->sta.bssid, + // &wd->sta.rxSeed[keyInfo.keyIndex], keyInfo.initIv); + +#ifdef ZM_ENABLE_IBSS_WPA2PSK + if ( wd->sta.ibssWpa2Psk == 1 ) + { + /* unicast -- > pairwise key */ + wd->sta.oppositeInfo[userIdx].iv16 = 0; + wd->sta.oppositeInfo[userIdx].iv32 = 0; + } + else + { + wd->sta.iv16 = 0; + wd->sta.iv32 = 0; + } + + wd->sta.oppositeInfo[userIdx].pkInstalled = 1; +#else + wd->sta.iv16 = 0; + wd->sta.iv32 = 0; + + wd->sta.oppositeInfo[userIdx].pkInstalled = 1; +#endif + + if ( keyInfo.keyLength == 32 ) + { /* TKIP */ + zfTkipInit(keyInfo.key, (u8_t*) wd->macAddr, + &wd->sta.txSeed, keyInfo.initIv); + zfTkipInit(keyInfo.key, (u8_t*) wd->sta.bssid, + &wd->sta.rxSeed[keyInfo.keyIndex], keyInfo.initIv); + +#ifdef ZM_ENABLE_CENC + if (keyInfo.flag & ZM_KEY_FLAG_CENC) + { + zm_debug_msg0("Set CENC pairwise Key"); + + wd->sta.encryMode = ZM_CENC; + + /* Reset txiv and rxiv */ + wd->sta.txiv[0] = 0x5c365c36; + wd->sta.txiv[1] = 0x5c365c36; + wd->sta.txiv[2] = 0x5c365c36; + wd->sta.txiv[3] = 0x5c365c36; + + wd->sta.rxiv[0] = 0x5c365c37; + wd->sta.rxiv[1] = 0x5c365c36; + wd->sta.rxiv[2] = 0x5c365c36; + wd->sta.rxiv[3] = 0x5c365c36; + + /* Set Key Index */ + wd->sta.cencKeyId = keyInfo.keyIndex; + + //zfCoreSetKey(dev, id+1, 1, ZM_CENC, (u16_t *)keyInfo.macAddr, + // (u32_t*) &keyInfo.key[16]); + } + else +#endif //ZM_ENABLE_CENC + { + wd->sta.encryMode = ZM_TKIP; + + //zfCoreSetKey(dev, 0, 1, ZM_TKIP, wd->sta.bssid, + // (u32_t*) &keyInfo.key[16]); + + zfMicSetKey(&keyInfo.key[16], &wd->sta.txMicKey); + zfMicSetKey(&keyInfo.key[24], + &wd->sta.rxMicKey[keyInfo.keyIndex]); + } + } + else if ( keyInfo.keyLength == 16 ) + { /* AES */ +#ifdef ZM_ENABLE_IBSS_WPA2PSK + if ( wd->sta.ibssWpa2Psk == 1 ) + { + wd->sta.oppositeInfo[userIdx].encryMode = ZM_AES; + encryType = wd->sta.oppositeInfo[userIdx].encryMode; + } + else + { + wd->sta.encryMode = ZM_AES; + encryType = wd->sta.encryMode; + } +#else + wd->sta.encryMode = ZM_AES; +#endif + } + else + { + return ZM_STATUS_FAILURE; + } + + /* user 0 */ + //zfCoreSetKey(dev, 0, 0, wd->sta.encryMode, + // wd->sta.bssid, (u32_t*) keyInfo.key); + //zfHpSetStaPairwiseKey(dev, wd->sta.bssid, wd->sta.encryMode, + // (u32_t*) keyInfo.key, (u32_t*) &keyInfo.key[16]); + +#ifdef ZM_ENABLE_IBSS_WPA2PSK + if ( (keyInfo.keyLength==16) && (wd->sta.ibssWpa2Psk==1) ) + { /* If not AES-CCMP and ibss network , use traditional */ + zfHpSetPerUserKey(dev, + userIdx, + keyInfo.keyIndex, // key id == 0 ( Pairwise key = 0 ) + (u8_t*)keyInfo.macAddr, // RX need Source Address ( Address 2 ) + encryType, +// wd->sta.encryMode, + (u32_t*) keyInfo.key, (u32_t*) &keyInfo.key[16]); + + wd->sta.oppositeInfo[userIdx].wpaState = ZM_STA_WPA_STATE_PK_OK ; + } + else + {/* Big Endian and Little Endian Compatibility */ + for (i = 0; i < 3; i++) + { + addr[2 * i] = wd->sta.bssid[i] & 0xff; + addr[2 * i + 1] = wd->sta.bssid[i] >> 8; + } + zfHpSetPerUserKey(dev, + ZM_USER_KEY_PK, // user id + 0, // key id + addr,//(u8_t *)wd->sta.bssid, + wd->sta.encryMode, + (u32_t*) keyInfo.key, (u32_t*) &keyInfo.key[16]); + + wd->sta.keyId = 4; + } +#else + /* Big Endian and Little Endian Compatibility */ + for (i = 0; i < 3; i++) + { + addr[2 * i] = wd->sta.bssid[i] & 0xff; + addr[2 * i + 1] = wd->sta.bssid[i] >> 8; + } + zfHpSetPerUserKey(dev, + ZM_USER_KEY_PK, // user id + 0, // key id + addr,//(u8_t *)wd->sta.bssid, + wd->sta.encryMode, + (u32_t*) keyInfo.key, (u32_t*) &keyInfo.key[16]); + + wd->sta.keyId = 4; +#endif + + wd->sta.wpaState = ZM_STA_WPA_STATE_PK_OK; + } + else if ( keyInfo.flag & ZM_KEY_FLAG_GK ) + { /* set group key */ + + zfTkipInit(keyInfo.key, (u8_t*) wd->sta.bssid, + &wd->sta.rxSeed[keyInfo.keyIndex], keyInfo.initIv); + + if ( keyInfo.keyLength == 32 ) + { /* TKIP */ +#ifdef ZM_ENABLE_CENC + if (keyInfo.flag & ZM_KEY_FLAG_CENC) + { + encryMode = ZM_CENC; + zm_debug_msg0("Set CENC group Key"); + + /* Reset txiv and rxiv */ + wd->sta.rxivGK[0] = 0x5c365c36; + wd->sta.rxivGK[1] = 0x5c365c36; + wd->sta.rxivGK[2] = 0x5c365c36; + wd->sta.rxivGK[3] = 0x5c365c36; + + //zfCoreSetKey(dev, 0, 1, ZM_CENC, keyInfo.vapAddr, + // (u32_t*) &keyInfo.key[16]); + key = (u32_t*) keyInfo.key; + } + else +#endif //ZM_ENABLE_CENC + { + encryMode = ZM_TKIP; + key = (u32_t*) wd->sta.rxSeed[keyInfo.keyIndex].tk; + + if ( !(keyInfo.flag & ZM_KEY_FLAG_INIT_IV) ) + { + wd->sta.rxSeed[keyInfo.keyIndex].iv16 = 0; + wd->sta.rxSeed[keyInfo.keyIndex].iv32 = 0; + } + + /* set MIC key to HMAC */ + //zfCoreSetKey(dev, 8, 1, ZM_TKIP, broadcast, + // (u32_t*) (&keyInfo.key[16])); + + zfMicSetKey(&keyInfo.key[24], + &wd->sta.rxMicKey[keyInfo.keyIndex]); + } + } + else if ( keyInfo.keyLength == 16 ) + { /* AES */ + encryMode = ZM_AES; + //key = (u32_t*) wd->sta.rxSeed[keyInfo.keyIndex].tk; + } + else + { /* WEP */ + if ( keyInfo.keyLength == 5 ) + { + encryMode = ZM_WEP64; + } + else if ( keyInfo.keyLength == 13 ) + { + encryMode = ZM_WEP128; + } + else if ( keyInfo.keyLength == 29 ) + { + encryMode = ZM_WEP256; + } + + key = (u32_t*) keyInfo.key; + } + + /* user 8 */ + //zfCoreSetKey(dev, 8, 0, encryMode, broadcast, key); + //zfHpSetStaGroupKey(dev, broadcast, encryMode, + // (u32_t*) keyInfo.key, (u32_t*) (&keyInfo.key[16])); + +#ifdef ZM_ENABLE_IBSS_WPA2PSK + if ( (keyInfo.keyLength==16) && (wd->sta.ibssWpa2Psk==1) ) + {/* If not AES-CCMP and ibss network , use traditional */ + zfHpSetPerUserKey(dev, + userIdx, + keyInfo.keyIndex, // key id + // (u8_t *)broadcast, // for only 2 stations IBSS netwrl ( A2 ) + (u8_t*)keyInfo.macAddr, // for multiple ( > 2 ) stations IBSS network ( A2 ) + encryMode, + (u32_t*) keyInfo.key, (u32_t*) &keyInfo.key[16]); + } + else + { + zfHpSetPerUserKey(dev, + ZM_USER_KEY_GK, // user id + 0, // key id + (u8_t *)broadcast, + encryMode, + (u32_t*) keyInfo.key, (u32_t*) &keyInfo.key[16]); + + wd->sta.wpaState = ZM_STA_WPA_STATE_GK_OK; + } +#else + zfHpSetPerUserKey(dev, + ZM_USER_KEY_GK, // user id + 0, // key id + (u8_t *)broadcast, + encryMode, + (u32_t*) keyInfo.key, (u32_t*) &keyInfo.key[16]); + + wd->sta.wpaState = ZM_STA_WPA_STATE_GK_OK; +#endif + } + else + { /* legacy WEP */ + zm_debug_msg0("legacy WEP"); + + if ( keyInfo.keyIndex >= 4 ) + { + return ZM_STATUS_FAILURE; + } + + if ( keyInfo.keyLength == 5 ) + { + zm_debug_msg0("WEP 64"); + + encryMode = ZM_WEP64; + } + else if ( keyInfo.keyLength == 13 ) + { + zm_debug_msg0("WEP 128"); + + encryMode = ZM_WEP128; + } + else if ( keyInfo.keyLength == 32 ) + { + /* TKIP */ + #if 0 + // Don't reset the IV since some AP would fail in IV check and drop our connection + if ( wd->sta.wpaState != ZM_STA_WPA_STATE_PK_OK ) + { + wd->sta.iv16 = 0; + wd->sta.iv32 = 0; + } + #endif + + encryMode = ZM_TKIP; + + zfTkipInit(keyInfo.key, (u8_t*) wd->sta.bssid, + &wd->sta.rxSeed[keyInfo.keyIndex], keyInfo.initIv); + zfMicSetKey(&keyInfo.key[24], + &wd->sta.rxMicKey[keyInfo.keyIndex]); + } + else if ( keyInfo.keyLength == 16 ) + { + /* AES */ + #if 0 + // Don't reset the IV since some AP would fail in IV check and drop our connection + if ( wd->sta.wpaState != ZM_STA_WPA_STATE_PK_OK ) + { + /* broadcast -- > group key */ + /* Only initialize when set our default key ! */ + wd->sta.iv16 = 0; + wd->sta.iv32 = 0; + } + #endif + + encryMode = ZM_AES; + } + else if ( keyInfo.keyLength == 29 ) + { + zm_debug_msg0("WEP 256"); + + encryMode = ZM_WEP256; + //zfCoreSetKey(dev, 64, 1, wd->sta.encryMode, + // wd->sta.bssid, (u32_t*) (&keyInfo.key[16])); + } + else + { + return ZM_STATUS_FAILURE; + } + + { + u8_t i; + + zm_debug_msg0("key = "); + for(i = 0; i < keyInfo.keyLength; i++) + { + zm_debug_msg2("", keyInfo.key[i]); + } + } + + if ( keyInfo.flag & ZM_KEY_FLAG_DEFAULT_KEY ) + { + //for WEP default key 1~3 and ATOM platform--CWYang(+) + vapId = 0; + wd->ap.bcHalKeyIdx[vapId] = keyInfo.keyIndex; + wd->ap.bcKeyIndex[vapId] = keyInfo.keyIndex; + wd->sta.keyId = keyInfo.keyIndex; + } + + if(encryMode == ZM_TKIP) + { + if(wd->TKIP_Group_KeyChanging == 0x1) + { + zm_debug_msg0("Countermeasure : Cancel Old Timer "); + zfTimerCancel(dev, ZM_EVENT_SKIP_COUNTERMEASURE); + } + else + { + zm_debug_msg0("Countermeasure : Create New Timer "); + } + + wd->TKIP_Group_KeyChanging = 0x1; + zfTimerSchedule(dev, ZM_EVENT_SKIP_COUNTERMEASURE, 150); + } + + + + //------------------------------------------------------------------------ + + /* use default key */ + //zfCoreSetKey(dev, ZM_USER_KEY_DEFAULT+keyInfo.keyIndex, 0, + // wd->sta.encryMode, wd->sta.bssid, (u32_t*) keyInfo.key); + + if ( encryMode == ZM_TKIP || + encryMode == ZM_AES ) + { + zfHpSetDefaultKey(dev, keyInfo.keyIndex, encryMode, + (u32_t*) keyInfo.key, (u32_t*) &keyInfo.key[16]); + +#ifdef ZM_ENABLE_IBSS_WPA2PSK + if ( (keyInfo.keyLength==16) && (wd->sta.ibssWpa2Psk==1) ) + {/* If not AES-CCMP and ibss network , use traditional */ + wd->sta.wpaState = ZM_STA_WPA_STATE_PK_OK; + } + else + { + if (wd->sta.wpaState == ZM_STA_WPA_STATE_PK_OK) + wd->sta.wpaState = ZM_STA_WPA_STATE_GK_OK; + else + { + wd->sta.wpaState = ZM_STA_WPA_STATE_PK_OK; + wd->sta.encryMode = encryMode; + wd->ws.encryMode = encryMode; + } + } +#else + if (wd->sta.wpaState == ZM_STA_WPA_STATE_PK_OK) + wd->sta.wpaState = ZM_STA_WPA_STATE_GK_OK; + else if ( wd->sta.wpaState == ZM_STA_WPA_STATE_INIT ) + { + wd->sta.wpaState = ZM_STA_WPA_STATE_PK_OK; + wd->sta.encryMode = encryMode; + wd->ws.encryMode = encryMode; + } +#endif + } + else + { + zfHpSetDefaultKey(dev, keyInfo.keyIndex, encryMode, + (u32_t*) keyInfo.key, NULL); + + /* Save key for software WEP */ + zfMemoryCopy(wd->sta.wepKey[keyInfo.keyIndex], keyInfo.key, + keyInfo.keyLength); + + /* TODO: Check whether we need to save the SWEncryMode */ + wd->sta.SWEncryMode[keyInfo.keyIndex] = encryMode; + + wd->sta.encryMode = encryMode; + wd->ws.encryMode = encryMode; + } + } + } + +// wd->sta.flagKeyChanging = 1; + return ZM_STATUS_SUCCESS; +} + +/* PSEUDO test */ +u8_t zfiWlanPSEUDOSetKey(zdev_t* dev, struct zsKeyInfo keyInfo) +{ + //u16_t broadcast[3] = {0xffff, 0xffff, 0xffff}; + //u32_t* key; + u8_t micKey[16]; + + zmw_get_wlan_dev(dev); + + switch (keyInfo.keyLength) + { + case 5: + wd->sta.encryMode = ZM_WEP64; + /* use default key */ + zfCoreSetKey(dev, 64, 0, ZM_WEP64, (u16_t *)keyInfo.macAddr, (u32_t*) keyInfo.key); + break; + + case 13: + wd->sta.encryMode = ZM_WEP128; + /* use default key */ + zfCoreSetKey(dev, 64, 0, ZM_WEP128, (u16_t *)keyInfo.macAddr, (u32_t*) keyInfo.key); + break; + + case 29: + wd->sta.encryMode = ZM_WEP256; + /* use default key */ + zfCoreSetKey(dev, 64, 1, ZM_WEP256, (u16_t *)keyInfo.macAddr, (u32_t*) (&keyInfo.key[16])); + zfCoreSetKey(dev, 64, 0, ZM_WEP256, (u16_t *)keyInfo.macAddr, (u32_t*) keyInfo.key); + break; + + case 16: + wd->sta.encryMode = ZM_AES; + //zfCoreSetKey(dev, 0, 0, ZM_AES, (u16_t *)keyInfo.macAddr, (u32_t*) keyInfo.key); + zfCoreSetKey(dev, 64, 0, ZM_AES, (u16_t *)keyInfo.macAddr, (u32_t*) keyInfo.key); + break; + + case 32: +#ifdef ZM_ENABLE_CENC + if (keyInfo.flag & ZM_KEY_FLAG_CENC) + { + u16_t boardcastAddr[3] = {0xffff, 0xffff, 0xffff}; + u16_t Addr_a[] = { 0x0000, 0x0080, 0x0901}; + u16_t Addr_b[] = { 0x0000, 0x0080, 0x0902}; + /* CENC test: user0,1 and user2 for boardcast */ + wd->sta.encryMode = ZM_CENC; + zfCoreSetKey(dev, 0, 1, ZM_CENC, (u16_t *)Addr_a, (u32_t*) (&keyInfo.key[16])); + zfCoreSetKey(dev, 0, 0, ZM_CENC, (u16_t *)Addr_a, (u32_t*) keyInfo.key); + + zfCoreSetKey(dev, 1, 1, ZM_CENC, (u16_t *)Addr_b, (u32_t*) (&keyInfo.key[16])); + zfCoreSetKey(dev, 1, 0, ZM_CENC, (u16_t *)Addr_b, (u32_t*) keyInfo.key); + + zfCoreSetKey(dev, 2, 1, ZM_CENC, (u16_t *)boardcastAddr, (u32_t*) (&keyInfo.key[16])); + zfCoreSetKey(dev, 2, 0, ZM_CENC, (u16_t *)boardcastAddr, (u32_t*) keyInfo.key); + + /* Initialize PN sequence */ + wd->sta.txiv[0] = 0x5c365c36; + wd->sta.txiv[1] = 0x5c365c36; + wd->sta.txiv[2] = 0x5c365c36; + wd->sta.txiv[3] = 0x5c365c36; + } + else +#endif //ZM_ENABLE_CENC + { + wd->sta.encryMode = ZM_TKIP; + zfCoreSetKey(dev, 64, 1, ZM_TKIP, (u16_t *)keyInfo.macAddr, (u32_t*) micKey); + zfCoreSetKey(dev, 64, 0, ZM_TKIP, (u16_t *)keyInfo.macAddr, (u32_t*) keyInfo.key); + } + break; + default: + wd->sta.encryMode = ZM_NO_WEP; + } + + return ZM_STATUS_SUCCESS; +} + +void zfiWlanSetPowerSaveMode(zdev_t* dev, u8_t mode) +{ +#if 0 + zmw_get_wlan_dev(dev); + + wd->sta.powerSaveMode = mode; + + /* send null data with PwrBit to inform AP */ + if ( mode > ZM_STA_PS_NONE ) + { + if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) + { + zfSendNullData(dev, 1); + } + + /* device into PS mode */ + zfPSDeviceSleep(dev); + } +#endif + + zfPowerSavingMgrSetMode(dev, mode); +} + +void zfiWlanSetMacAddress(zdev_t* dev, u16_t* mac) +{ + zmw_get_wlan_dev(dev); + + wd->macAddr[0] = mac[0]; + wd->macAddr[1] = mac[1]; + wd->macAddr[2] = mac[2]; + + zfHpSetMacAddress(dev, mac, 0); +} + +u8_t zfiWlanQueryWlanMode(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + return wd->wlanMode; +} + +u8_t zfiWlanQueryAdapterState(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + return wd->state; +} + +u8_t zfiWlanQueryAuthenticationMode(zdev_t* dev, u8_t bWrapper) +{ + u8_t authMode; + + zmw_get_wlan_dev(dev); + + if ( bWrapper ) + { + authMode = wd->ws.authMode; + } + else + { + //authMode = wd->sta.authMode; + authMode = wd->sta.currentAuthMode; + } + + return authMode; +} + +u8_t zfiWlanQueryWepStatus(zdev_t* dev, u8_t bWrapper) +{ + u8_t wepStatus; + + zmw_get_wlan_dev(dev); + + if ( bWrapper ) + { + wepStatus = wd->ws.wepStatus; + } + else + { + wepStatus = wd->sta.wepStatus; + } + + return wepStatus; +} + +void zfiWlanQuerySSID(zdev_t* dev, u8_t* ssid, u8_t* pSsidLength) +{ + u16_t vapId = 0; + zmw_get_wlan_dev(dev); + + if (wd->wlanMode == ZM_MODE_AP) + { + vapId = zfwGetVapId(dev); + + if (vapId == 0xffff) + { + *pSsidLength = wd->ap.ssidLen[0]; + zfMemoryCopy(ssid, wd->ap.ssid[0], wd->ap.ssidLen[0]); + } + else + { + *pSsidLength = wd->ap.ssidLen[vapId + 1]; + zfMemoryCopy(ssid, wd->ap.ssid[vapId + 1], wd->ap.ssidLen[vapId + 1]); + } + } + else + { + *pSsidLength = wd->sta.ssidLen; + zfMemoryCopy(ssid, wd->sta.ssid, wd->sta.ssidLen); + } +} + +u16_t zfiWlanQueryFragThreshold(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + return wd->fragThreshold; +} + +u16_t zfiWlanQueryRtsThreshold(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + return wd->rtsThreshold; +} + +u32_t zfiWlanQueryFrequency(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + return (wd->frequency*1000); +} + +/*********************************************************** + * Function: zfiWlanQueryCurrentFrequency + * Return value: + * - 0 : no validate current frequency + * - (>0): current frequency depend on "qmode" + * Input: + * - qmode: + * 0: return value depend on the support mode, this + qmode is use to solve the bug #31223 + * 1: return the actually current frequency + ***********************************************************/ +u32_t zfiWlanQueryCurrentFrequency(zdev_t* dev, u8_t qmode) +{ + u32_t frequency; + + zmw_get_wlan_dev(dev); + + switch (qmode) + { + case 0: + if (wd->sta.currentFrequency > 3000) + { + if (wd->supportMode & ZM_WIRELESS_MODE_5) + { + frequency = wd->sta.currentFrequency; + } + else if (wd->supportMode & ZM_WIRELESS_MODE_24) + { + frequency = zfChGetFirst2GhzChannel(dev); + } + else + { + frequency = 0; + } + } + else + { + if (wd->supportMode & ZM_WIRELESS_MODE_24) + { + frequency = wd->sta.currentFrequency; + } + else if (wd->supportMode & ZM_WIRELESS_MODE_5) + { + frequency = zfChGetLast5GhzChannel(dev); + } + else + { + frequency = 0; + } + } + break; + + case 1: + frequency = wd->sta.currentFrequency; + break; + + default: + frequency = 0; + } + + return (frequency*1000); +} + +u32_t zfiWlanQueryFrequencyAttribute(zdev_t* dev, u32_t freq) +{ + zmw_get_wlan_dev(dev); + + u8_t i; + u16_t frequency = (u16_t) (freq/1000); + u32_t ret = 0; + + for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) + { + if ( wd->regulationTable.allowChannel[i].channel == frequency ) + { + ret = wd->regulationTable.allowChannel[i].channelFlags; + } + } + + return ret; +} + +/* BandWidth 0=>20 1=>40 */ +/* ExtOffset 0=>20 1=>high control 40 3=>low control 40 */ +void zfiWlanQueryFrequencyHT(zdev_t* dev, u32_t *bandWidth, u32_t *extOffset) +{ + zmw_get_wlan_dev(dev); + + *bandWidth = wd->BandWidth40; + *extOffset = wd->ExtOffset; +} + +u8_t zfiWlanQueryCWMode(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + return wd->cwm.cw_mode; +} + +u32_t zfiWlanQueryCWEnable(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + return wd->cwm.cw_enable; +} + +void zfiWlanQueryBssid(zdev_t* dev, u8_t* bssid) +{ + u8_t addr[6]; + + zmw_get_wlan_dev(dev); + + ZM_MAC_WORD_TO_BYTE(wd->sta.bssid, addr); + zfMemoryCopy(bssid, addr, 6); +} + +u16_t zfiWlanQueryBeaconInterval(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + return wd->beaconInterval; +} + +u32_t zfiWlanQueryRxBeaconTotal(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + wd->sta.rxBeaconTotal += wd->sta.rxBeaconCount; + + return wd->sta.rxBeaconTotal; +} + +u16_t zfiWlanQueryAtimWindow(zdev_t* dev) +{ + u16_t atimWindow; + + zmw_get_wlan_dev(dev); + + atimWindow = wd->sta.atimWindow; + + return atimWindow; +} + +u8_t zfiWlanQueryEncryMode(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + if (wd->wlanMode == ZM_MODE_AP) + return wd->ap.encryMode[0]; + else + return wd->sta.encryMode; +} + +u16_t zfiWlanQueryCapability(zdev_t* dev) +{ + u16_t capability; + + zmw_get_wlan_dev(dev); + + capability = wd->sta.capability[0] + + (((u16_t) wd->sta.capability[1]) << 8); + + return capability; + +} + +u16_t zfiWlanQueryAid(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + return wd->sta.aid; +} + +void zfiWlanQuerySupportRate(zdev_t* dev, u8_t* rateArray, u8_t* pLength) +{ + u8_t i, j=0; + + zmw_get_wlan_dev(dev); + + for( i=0; i<4; i++ ) + { + if ( wd->bRate & (0x1 << i) ) + { + rateArray[j] = zg11bRateTbl[i] + + ((wd->bRateBasic & (0x1<gRate & (0x1 << i) ) + { + rateArray[j] = zg11gRateTbl[i] + + ((wd->gRateBasic & (0x1<sta.rsnIe[1] + 2; + zfMemoryCopy(ie, wd->sta.rsnIe, len); + *pLength = len; +} + +void zfiWlanQueryWpaIe(zdev_t* dev, u8_t* ie, u8_t* pLength) +{ + u8_t len; + + zmw_get_wlan_dev(dev); + + len = wd->sta.wpaIe[1] + 2; + zfMemoryCopy(ie, wd->sta.wpaIe, len); + *pLength = len; + +} + +u8_t zfiWlanQueryMulticastCipherAlgo(zdev_t *dev) +{ + zmw_get_wlan_dev(dev); + + switch( wd->sta.currentAuthMode ) + { + case ZM_AUTH_MODE_WPA2PSK: + case ZM_AUTH_MODE_WPA2: + if ( wd->sta.rsnIe[7] == 2 ) + { + return ZM_TKIP; + } + else + { + return ZM_AES; + } + break; + + case ZM_AUTH_MODE_WPAPSK: + case ZM_AUTH_MODE_WPA: + if ( wd->sta.rsnIe[11] == 2 ) + { + return ZM_TKIP; + } + else + { + return ZM_AES; + } + break; + + default: + return wd->sta.encryMode; + } +} + +u8_t zfiWlanQueryHTMode(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + // 0:Legancy, 1:N + return wd->sta.EnableHT; +} + +u8_t zfiWlanQueryBandWidth40(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + // 0:20M, 1:40M + return wd->BandWidth40; +} + +u16_t zfiWlanQueryRegionCode(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + return wd->regulationTable.regionCode; +} +void zfiWlanSetWpaIe(zdev_t* dev, u8_t* ie, u8_t Length) +{ + u16_t vapId = 0; + zmw_get_wlan_dev(dev); + + if (wd->wlanMode == ZM_MODE_AP) // AP Mode + { + vapId = zfwGetVapId(dev); + + if (vapId == 0xffff) + vapId = 0; + else + vapId++; + + zm_assert(Length < ZM_MAX_WPAIE_SIZE); + if (Length < ZM_MAX_WPAIE_SIZE) + { + wd->ap.wpaLen[vapId] = Length; + zfMemoryCopy(wd->ap.wpaIe[vapId], ie, wd->ap.wpaLen[vapId]); + } + + } + else + { + wd->sta.wpaLen = Length; + zfMemoryCopy(wd->sta.wpaIe, ie, wd->sta.wpaLen); + } + //zfiWlanSetWpaSupport(dev, 1); + if (wd->wlanMode == ZM_MODE_AP) // AP Mode + { + wd->ap.wpaSupport[vapId] = 1; + } + else + { + wd->sta.wpaSupport = 1; + } + +} + +void zfiWlanSetWpaSupport(zdev_t* dev, u8_t WpaSupport) +{ + u16_t vapId = 0; + zmw_get_wlan_dev(dev); + + if (wd->wlanMode == ZM_MODE_AP) // AP Mode + { + vapId = zfwGetVapId(dev); + + if (vapId == 0xffff) + vapId = 0; + else + vapId++; + + wd->ap.wpaSupport[vapId] = WpaSupport; + } + else + { + wd->sta.wpaSupport = WpaSupport; + } + +} + +void zfiWlanSetProtectionMode(zdev_t* dev, u8_t mode) +{ + zmw_get_wlan_dev(dev); + + wd->sta.bProtectionMode = mode; + if (wd->sta.bProtectionMode == TRUE) + { + zfHpSetSlotTime(dev, 0); + } + else + { + zfHpSetSlotTime(dev, 1); + } + + zm_msg1_mm(ZM_LV_1, "wd->protectionMode=", wd->sta.bProtectionMode); +} + +void zfiWlanSetBasicRate(zdev_t* dev, u8_t bRateSet, u8_t gRateSet, + u32_t nRateSet) +{ + zmw_get_wlan_dev(dev); + + wd->ws.bRateBasic = bRateSet; + wd->ws.gRateBasic = gRateSet; + wd->ws.nRateBasic = nRateSet; +} + +void zfiWlanSetBGMode(zdev_t* dev, u8_t mode) +{ + zmw_get_wlan_dev(dev); + + wd->ws.bgMode = mode; +} + +void zfiWlanSetpreambleType(zdev_t* dev, u8_t type) +{ + zmw_get_wlan_dev(dev); + + wd->ws.preambleType = type; +} + +u8_t zfiWlanQuerypreambleType(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + return wd->ws.preambleType; +} + +u8_t zfiWlanQueryPowerSaveMode(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + return wd->sta.powerSaveMode; +} + +u8_t zfiWlanSetPmkidInfo(zdev_t* dev, u16_t* bssid, u8_t* pmkid) +{ + u32_t i; + + zmw_get_wlan_dev(dev); + + for(i=0; ista.pmkidInfo.bssidCount; i++) + { + if ( zfMemoryIsEqual((u8_t*) wd->sta.pmkidInfo.bssidInfo[i].bssid, + (u8_t*) bssid, 6) ) + { + /* matched */ + break; + } + } + + if ( i < wd->sta.pmkidInfo.bssidCount ) + { + /* overwrite the original one */ + zfMemoryCopy(wd->sta.pmkidInfo.bssidInfo[i].pmkid, pmkid, 16); + } + else + { + if ( i < ZM_PMKID_MAX_BSS_CNT ) + { + wd->sta.pmkidInfo.bssidInfo[i].bssid[0] = bssid[0]; + wd->sta.pmkidInfo.bssidInfo[i].bssid[1] = bssid[1]; + wd->sta.pmkidInfo.bssidInfo[i].bssid[2] = bssid[2]; + + zfMemoryCopy(wd->sta.pmkidInfo.bssidInfo[i].pmkid, pmkid, 16); + wd->sta.pmkidInfo.bssidCount++; + } + } + + return 0; +} + +u32_t zfiWlanQueryPmkidInfo(zdev_t* dev, u8_t* buf, u32_t len) +{ + //struct zsPmkidInfo* pPmkidInfo = ( struct zsPmkidInfo* ) buf; + u32_t size; + + zmw_get_wlan_dev(dev); + + size = sizeof(u32_t) + + wd->sta.pmkidInfo.bssidCount * sizeof(struct zsPmkidBssidInfo); + + if ( len < size ) + { + return wd->sta.pmkidInfo.bssidCount; + } + + zfMemoryCopy(buf, (u8_t*) &wd->sta.pmkidInfo, (u16_t) size); + + return 0; +} + +void zfiWlanSetMulticastList(zdev_t* dev, u8_t size, u8_t* pList) +{ + struct zsMulticastAddr* pMacList = (struct zsMulticastAddr*) pList; + u8_t i; + u8_t bAllMulticast = 0; + //u32_t value; + + zmw_get_wlan_dev(dev); + + wd->sta.multicastList.size = size; + for(i=0; ista.multicastList.macAddr[i].addr, + pMacList[i].addr, 6); + } + + if ( wd->sta.osRxFilter & ZM_PACKET_TYPE_ALL_MULTICAST ) + bAllMulticast = 1; + zfHpSetMulticastList(dev, size, pList, bAllMulticast); + +} + +void zfiWlanRemoveKey(zdev_t* dev, u8_t keyType, u8_t keyId) +{ + u16_t fakeMacAddr[3] = {0, 0, 0}; + u32_t fakeKey[4] = {0, 0, 0, 0}; + + zmw_get_wlan_dev(dev); + + if ( keyType == 0 ) + { + /* remove WEP key */ + zm_debug_msg0("remove WEP key"); + zfCoreSetKey(dev, ZM_USER_KEY_DEFAULT+keyId, 0, + ZM_NO_WEP, fakeMacAddr, fakeKey); + wd->sta.encryMode = ZM_NO_WEP; + } + else if ( keyType == 1 ) + { + /* remove pairwise key */ + zm_debug_msg0("remove pairwise key"); + zfHpRemoveKey(dev, ZM_USER_KEY_PK); + wd->sta.encryMode = ZM_NO_WEP; + } + else + { + /* remove group key */ + zm_debug_msg0("remove group key"); + zfHpRemoveKey(dev, ZM_USER_KEY_GK); + } +} + + +void zfiWlanQueryRegulationTable(zdev_t* dev, struct zsRegulationTable* pEntry) +{ + zmw_get_wlan_dev(dev); + + zfMemoryCopy((u8_t*) pEntry, (u8_t*) &wd->regulationTable, + sizeof(struct zsRegulationTable)); +} + +/* parameter "time" is specified in ms */ +void zfiWlanSetScanTimerPerChannel(zdev_t* dev, u16_t time) +{ + zmw_get_wlan_dev(dev); + + zm_debug_msg1("scan time (ms) = ", time); + + wd->sta.activescanTickPerChannel = time / ZM_MS_PER_TICK; +} + +void zfiWlanSetAutoReconnect(zdev_t* dev, u8_t enable) +{ + zmw_get_wlan_dev(dev); + + wd->sta.bAutoReconnect = enable; + //wd->sta.bAutoReconnectEnabled = enable; +} + +void zfiWlanSetStaWme(zdev_t* dev, u8_t enable, u8_t uapsdInfo) +{ + zmw_get_wlan_dev(dev); + + wd->ws.staWmeEnabled = enable & 0x3; + if ((enable & 0x2) != 0) + { + wd->ws.staWmeQosInfo = uapsdInfo & 0x6f; + } + else + { + wd->ws.staWmeQosInfo = 0; + } +} + +void zfiWlanSetApWme(zdev_t* dev, u8_t enable) +{ + zmw_get_wlan_dev(dev); + + wd->ws.apWmeEnabled = enable; +} + +u8_t zfiWlanQuerywmeEnable(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + return wd->ws.staWmeEnabled; +} + +void zfiWlanSetProbingHiddenSsid(zdev_t* dev, u8_t* ssid, u8_t ssidLen, + u16_t entry) +{ + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + + if ((ssidLen <= 32) && (entry < ZM_MAX_PROBE_HIDDEN_SSID_SIZE)) + { + zmw_enter_critical_section(dev); + wd->ws.probingSsidList[entry].ssidLen = ssidLen; + zfMemoryCopy(wd->ws.probingSsidList[entry].ssid, ssid, ssidLen); + zmw_leave_critical_section(dev); + } + + return; +} + +void zfiWlanSetDisableProbingWithSsid(zdev_t* dev, u8_t mode) +{ + zmw_get_wlan_dev(dev); + + wd->sta.disableProbingWithSsid = mode; + + return; +} + +void zfiWlanSetDropUnencryptedPackets(zdev_t* dev, u8_t enable) +{ + zmw_get_wlan_dev(dev); + + wd->ws.dropUnencryptedPkts = enable; +} + +void zfiWlanSetStaRxSecurityCheckCb(zdev_t* dev, zfpStaRxSecurityCheckCb pStaRxSecurityCheckCb) +{ + zmw_get_wlan_dev(dev); + + wd->sta.pStaRxSecurityCheckCb = pStaRxSecurityCheckCb; +} + +void zfiWlanSetIBSSJoinOnly(zdev_t* dev, u8_t joinOnly) +{ + zmw_get_wlan_dev(dev); + + wd->ws.ibssJoinOnly = joinOnly; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfiConfigWdsPort */ +/* Configure WDS port. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* wdsPortId : WDS port ID, start from 0 */ +/* flag : 0=>disable WDS port, 1=>enable WDS port */ +/* wdsAddr : WDS neighbor MAC address */ +/* encType : encryption type for WDS port */ +/* wdsKey : encryption key for WDS port */ +/* */ +/* OUTPUTS */ +/* Error code */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2006.6 */ +/* */ +/************************************************************************/ +u16_t zfiConfigWdsPort(zdev_t* dev, u8_t wdsPortId, u16_t flag, u16_t* wdsAddr, + u16_t encType, u32_t* wdsKey) +{ + u16_t addr[3]; + u32_t key[4]; + + zmw_get_wlan_dev(dev); + + if (wdsPortId > ZM_MAX_WDS_SUPPORT) + { + return ZM_ERR_WDS_PORT_ID; + } + + if (flag == 1) + { + /* Enable WDS port */ + wd->ap.wds.macAddr[wdsPortId][0] = wdsAddr[0]; + wd->ap.wds.macAddr[wdsPortId][1] = wdsAddr[1]; + wd->ap.wds.macAddr[wdsPortId][2] = wdsAddr[2]; + + wd->ap.wds.wdsBitmap |= (1 << wdsPortId); + wd->ap.wds.encryMode[wdsPortId] = (u8_t) encType; + + zfCoreSetKey(dev, 10+ZM_MAX_WDS_SUPPORT, 0, (u8_t) encType, wdsAddr, wdsKey); + } + else + { + /* Disable WDS port */ + addr[0] = addr[1] = addr[2] = 0; + key[0] = key[1] = key[2] = key[3] = 0; + wd->ap.wds.wdsBitmap &= (~(1 << wdsPortId)); + zfCoreSetKey(dev, 10+ZM_MAX_WDS_SUPPORT, 0, ZM_NO_WEP, addr, key); + } + + return ZM_SUCCESS; +} +#ifdef ZM_ENABLE_CENC +/* CENC */ +void zfiWlanQueryGSN(zdev_t* dev, u8_t *gsn, u16_t vapId) +{ + //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev); + u32_t txiv[4]; + zmw_get_wlan_dev(dev); + + /* convert little endian to big endian for 32 bits */ + txiv[3] = wd->ap.txiv[vapId][0]; + txiv[2] = wd->ap.txiv[vapId][1]; + txiv[1] = wd->ap.txiv[vapId][2]; + txiv[0] = wd->ap.txiv[vapId][3]; + + zfMemoryCopy(gsn, (u8_t*)txiv, 16); +} +#endif //ZM_ENABLE_CENC +//CWYang(+) +void zfiWlanQuerySignalInfo(zdev_t* dev, u8_t *buffer) +{ + zmw_get_wlan_dev(dev); + + /*Change Signal Strength/Quality Value to Human Sense Here*/ + + buffer[0] = wd->SignalStrength; + buffer[1] = wd->SignalQuality; +} + +/* OS-XP */ +u16_t zfiStaAddIeWpaRsn(zdev_t* dev, zbuf_t* buf, u16_t offset, u8_t frameType) +{ + return zfStaAddIeWpaRsn(dev, buf, offset, frameType); +} + +/* zfiDebugCmd */ +/* cmd value-description */ +/* 0 schedule timer */ +/* 1 cancel timer */ +/* 2 clear timer */ +/* 3 test timer */ +/* 4 */ +/* 5 */ +/* 6 checksum test 0/1 */ +/* 7 enableProtectionMode */ +/* 8 rx packet content dump 0/1 */ + +u32_t zfiDebugCmd(zdev_t* dev, u32_t cmd, u32_t value) +{ + u16_t event; + u32_t tick; + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + + zmw_enter_critical_section(dev); + + if ( cmd == 0 ) + { /* schedule timer */ + event = (u16_t) ((value >> 16) & 0xffff); + tick = value & 0xffff; + zfTimerSchedule(dev, event, tick); + } + else if ( cmd == 1 ) + { /* cancel timer */ + event = (u16_t) (value & 0xffff); + zfTimerCancel(dev, event); + } + else if ( cmd == 2 ) + { /* clear timer */ + zfTimerClear(dev); + } + else if ( cmd == 3 ) + { /* test timer */ + zfTimerSchedule(dev, 1, 500); + zfTimerSchedule(dev, 2, 1000); + zfTimerSchedule(dev, 3, 1000); + zfTimerSchedule(dev, 4, 1000); + zfTimerSchedule(dev, 5, 1500); + zfTimerSchedule(dev, 6, 2000); + zfTimerSchedule(dev, 7, 2200); + zfTimerSchedule(dev, 6, 2500); + zfTimerSchedule(dev, 8, 2800); + } + else if ( cmd == 4) + { + zfTimerSchedule(dev, 1, 500); + zfTimerSchedule(dev, 2, 1000); + zfTimerSchedule(dev, 3, 1000); + zfTimerSchedule(dev, 4, 1000); + zfTimerSchedule(dev, 5, 1500); + zfTimerSchedule(dev, 6, 2000); + zfTimerSchedule(dev, 7, 2200); + zfTimerSchedule(dev, 6, 2500); + zfTimerSchedule(dev, 8, 2800); + zfTimerCancel(dev, 1); + zfTimerCancel(dev, 3); + zfTimerCancel(dev, 6); + } + else if ( cmd == 5 ) + { + wd->sta.keyId = (u8_t) value; + } + else if ( cmd == 6 ) + { + /* 0: normal 1: always set TCP/UDP checksum zero */ + wd->checksumTest = value; + } + else if ( cmd == 7 ) + { + wd->enableProtectionMode = value; + zm_msg1_mm(ZM_LV_1, "wd->enableProtectionMode=", wd->enableProtectionMode); + } + else if ( cmd == 8 ) + { + /* rx packet content dump */ + if (value) + { + wd->rxPacketDump = 1; + } + else + { + wd->rxPacketDump = 0; + } + } + + + zmw_leave_critical_section(dev); + + return 0; +} + +#ifdef ZM_ENABLE_CENC +u8_t zfiWlanSetCencPairwiseKey(zdev_t* dev, u8_t keyid, u32_t *txiv, u32_t *rxiv, + u8_t *key, u8_t *mic) +{ + struct zsKeyInfo keyInfo; + u8_t cencKey[32]; + u8_t i; + u16_t macAddr[3]; + + zmw_get_wlan_dev(dev); + + for (i = 0; i < 16; i++) + cencKey[i] = key[i]; + for (i = 0; i < 16; i++) + cencKey[i + 16] = mic[i]; + keyInfo.key = cencKey; + keyInfo.keyLength = 32; + keyInfo.keyIndex = keyid; + keyInfo.flag = ZM_KEY_FLAG_CENC | ZM_KEY_FLAG_PK; + for (i = 0; i < 3; i++) + macAddr[i] = wd->sta.bssid[i]; + keyInfo.macAddr = macAddr; + + zfiWlanSetKey(dev, keyInfo); + + /* Reset txiv and rxiv */ + //wd->sta.txiv[0] = txiv[0]; + //wd->sta.txiv[1] = txiv[1]; + //wd->sta.txiv[2] = txiv[2]; + //wd->sta.txiv[3] = txiv[3]; + // + //wd->sta.rxiv[0] = rxiv[0]; + //wd->sta.rxiv[1] = rxiv[1]; + //wd->sta.rxiv[2] = rxiv[2]; + //wd->sta.rxiv[3] = rxiv[3]; + + return 0; +} + +u8_t zfiWlanSetCencGroupKey(zdev_t* dev, u8_t keyid, u32_t *rxiv, + u8_t *key, u8_t *mic) +{ + struct zsKeyInfo keyInfo; + u8_t cencKey[32]; + u8_t i; + u16_t macAddr[6] = {0xffff, 0xffff, 0xffff}; + + zmw_get_wlan_dev(dev); + + for (i = 0; i < 16; i++) + cencKey[i] = key[i]; + for (i = 0; i < 16; i++) + cencKey[i + 16] = mic[i]; + keyInfo.key = cencKey; + keyInfo.keyLength = 32; + keyInfo.keyIndex = keyid; + keyInfo.flag = ZM_KEY_FLAG_CENC | ZM_KEY_FLAG_GK; + keyInfo.vapId = 0; + for (i = 0; i < 3; i++) + keyInfo.vapAddr[i] = wd->macAddr[i]; + keyInfo.macAddr = macAddr; + + zfiWlanSetKey(dev, keyInfo); + + /* Reset txiv and rxiv */ + wd->sta.rxivGK[0] = ((rxiv[3] >> 24) & 0xFF) + + (((rxiv[3] >> 16) & 0xFF) << 8) + + (((rxiv[3] >> 8) & 0xFF) << 16) + + ((rxiv[3] & 0xFF) << 24); + wd->sta.rxivGK[1] = ((rxiv[2] >> 24) & 0xFF) + + (((rxiv[2] >> 16) & 0xFF) << 8) + + (((rxiv[2] >> 8) & 0xFF) << 16) + + ((rxiv[2] & 0xFF) << 24); + wd->sta.rxivGK[2] = ((rxiv[1] >> 24) & 0xFF) + + (((rxiv[1] >> 16) & 0xFF) << 8) + + (((rxiv[1] >> 8) & 0xFF) << 16) + + ((rxiv[1] & 0xFF) << 24); + wd->sta.rxivGK[3] = ((rxiv[0] >> 24) & 0xFF) + + (((rxiv[0] >> 16) & 0xFF) << 8) + + (((rxiv[0] >> 8) & 0xFF) << 16) + + ((rxiv[0] & 0xFF) << 24); + + wd->sta.authMode = ZM_AUTH_MODE_CENC; + wd->sta.currentAuthMode = ZM_AUTH_MODE_CENC; + + return 0; +} +#endif //ZM_ENABLE_CENC + +u8_t zfiWlanSetDot11DMode(zdev_t* dev, u8_t mode) +{ + u8_t i; + + zmw_get_wlan_dev(dev); + + wd->sta.b802_11D = mode; + if (mode) //Enable 802.11d + { + wd->regulationTable.regionCode = NO_ENUMRD; + for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) + wd->regulationTable.allowChannel[i].channelFlags |= ZM_REG_FLAG_CHANNEL_PASSIVE; + } + else //Disable + { + for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) + wd->regulationTable.allowChannel[i].channelFlags &= ~ZM_REG_FLAG_CHANNEL_PASSIVE; + } + + return 0; +} + +u8_t zfiWlanSetDot11HDFSMode(zdev_t* dev, u8_t mode) +{ + zmw_get_wlan_dev(dev); + + //zm_debug_msg0("CWY - Enable 802.11h DFS"); + + // TODO : DFS Enable in 5250 to 5350 MHz and 5470 to 5725 MHz . + //if ( Adapter->ZD80211HSupport && + // Adapter->CardSetting.NetworkTypeInUse == Ndis802_11OFDM5 && + // ((ChannelNo >=52 && ChannelNo <= 64) || //5250~5350 MHZ + // (ChannelNo >=100 && ChannelNo <= 140))) //5470~5725 MHZ + //{ + // Adapter->ZD80211HSetting.DFSEnable=TRUE; + //} + //else + //{ + // Adapter->ZD80211HSetting.DFSEnable=FALSE; + //} + + wd->sta.DFSEnable = mode; + if (mode) + wd->sta.capability[1] |= ZM_BIT_0; + else + wd->sta.capability[1] &= (~ZM_BIT_0); + + return 0; +} + +u8_t zfiWlanSetDot11HTPCMode(zdev_t* dev, u8_t mode) +{ + zmw_get_wlan_dev(dev); + + // TODO : TPC Enable in 5150~5350 MHz and 5470~5725MHz. + //if ( Adapter->ZD80211HSupport && + // Adapter->CardSetting.NetworkTypeInUse == Ndis802_11OFDM5 && + // ((ChannelNo == 36 || ChannelNo == 40 || ChannelNo == 44 || ChannelNo == 48) || //5150~5250 MHZ , Not Japan + // (ChannelNo >=52 && ChannelNo <= 64) || //5250~5350 MHZ + // (ChannelNo >=100 && ChannelNo <= 140))) //5470~5725 MHZ + //{ + // Adapter->ZD80211HSetting.TPCEnable=TRUE; + //} + //else + //{ + // Adapter->ZD80211HSetting.TPCEnable=FALSE; + //} + + wd->sta.TPCEnable = mode; + if (mode) + wd->sta.capability[1] |= ZM_BIT_0; + else + wd->sta.capability[1] &= (~ZM_BIT_0); + + return 0; +} + +u8_t zfiWlanSetAniMode(zdev_t* dev, u8_t mode) +{ + zmw_get_wlan_dev(dev); + + wd->aniEnable = mode; + if (mode) + zfHpAniAttach(dev); + + return 0; +} + +#ifdef ZM_OS_LINUX_FUNC +void zfiWlanShowTally(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + zm_msg1_mm(ZM_LV_0, "Hw_UnderrunCnt = ", wd->commTally.Hw_UnderrunCnt); + zm_msg1_mm(ZM_LV_0, "Hw_TotalRxFrm = ", wd->commTally.Hw_TotalRxFrm); + zm_msg1_mm(ZM_LV_0, "Hw_CRC32Cnt = ", wd->commTally.Hw_CRC32Cnt); + zm_msg1_mm(ZM_LV_0, "Hw_CRC16Cnt = ", wd->commTally.Hw_CRC16Cnt); + zm_msg1_mm(ZM_LV_1, "Hw_DecrypErr_UNI = ", wd->commTally.Hw_DecrypErr_UNI); + zm_msg1_mm(ZM_LV_0, "Hw_RxFIFOOverrun = ", wd->commTally.Hw_RxFIFOOverrun); + zm_msg1_mm(ZM_LV_1, "Hw_DecrypErr_Mul = ", wd->commTally.Hw_DecrypErr_Mul); + zm_msg1_mm(ZM_LV_1, "Hw_RetryCnt = ", wd->commTally.Hw_RetryCnt); + zm_msg1_mm(ZM_LV_0, "Hw_TotalTxFrm = ", wd->commTally.Hw_TotalTxFrm); + zm_msg1_mm(ZM_LV_0, "Hw_RxTimeOut = ", wd->commTally.Hw_RxTimeOut); + zm_msg1_mm(ZM_LV_0, "Tx_MPDU = ", wd->commTally.Tx_MPDU); + zm_msg1_mm(ZM_LV_0, "BA_Fail = ", wd->commTally.BA_Fail); + zm_msg1_mm(ZM_LV_0, "Hw_Tx_AMPDU = ", wd->commTally.Hw_Tx_AMPDU); + zm_msg1_mm(ZM_LV_0, "Hw_Tx_MPDU = ", wd->commTally.Hw_Tx_MPDU); + + zm_msg1_mm(ZM_LV_1, "Hw_RxMPDU = ", wd->commTally.Hw_RxMPDU); + zm_msg1_mm(ZM_LV_1, "Hw_RxDropMPDU = ", wd->commTally.Hw_RxDropMPDU); + zm_msg1_mm(ZM_LV_1, "Hw_RxDelMPDU = ", wd->commTally.Hw_RxDelMPDU); + zm_msg1_mm(ZM_LV_1, "Hw_RxPhyMiscError = ", wd->commTally.Hw_RxPhyMiscError); + zm_msg1_mm(ZM_LV_1, "Hw_RxPhyXRError = ", wd->commTally.Hw_RxPhyXRError); + zm_msg1_mm(ZM_LV_1, "Hw_RxPhyOFDMError = ", wd->commTally.Hw_RxPhyOFDMError); + zm_msg1_mm(ZM_LV_1, "Hw_RxPhyCCKError = ", wd->commTally.Hw_RxPhyCCKError); + zm_msg1_mm(ZM_LV_1, "Hw_RxPhyHTError = ", wd->commTally.Hw_RxPhyHTError); + zm_msg1_mm(ZM_LV_1, "Hw_RxPhyTotalCount = ", wd->commTally.Hw_RxPhyTotalCount); + + if (!((wd->commTally.Tx_MPDU == 0) && (wd->commTally.BA_Fail == 0))) + { + zm_debug_msg_p("BA Fail Ratio(%) = ", wd->commTally.BA_Fail * 100, + (wd->commTally.BA_Fail + wd->commTally.Tx_MPDU)); + } + + if (!((wd->commTally.Hw_Tx_MPDU == 0) && (wd->commTally.Hw_Tx_AMPDU == 0))) + { + zm_debug_msg_p("Avg Agg Number = ", + wd->commTally.Hw_Tx_MPDU, wd->commTally.Hw_Tx_AMPDU); + } +} +#endif + +void zfiWlanSetMaxTxPower(zdev_t* dev, u8_t power2, u8_t power5) +{ + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + wd->maxTxPower2 = power2; + wd->maxTxPower5 = power5; + zmw_leave_critical_section(dev); +} + +void zfiWlanQueryMaxTxPower(zdev_t* dev, u8_t *power2, u8_t *power5) +{ + zmw_get_wlan_dev(dev); + + *power2 = wd->maxTxPower2; + *power5 = wd->maxTxPower5; +} + +void zfiWlanSetConnectMode(zdev_t* dev, u8_t mode) +{ + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + wd->connectMode = mode; + zmw_leave_critical_section(dev); +} + +void zfiWlanSetSupportMode(zdev_t* dev, u32_t mode) +{ + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + wd->supportMode = mode; + zmw_leave_critical_section(dev); +} + +void zfiWlanSetAdhocMode(zdev_t* dev, u32_t mode) +{ + zmw_get_wlan_dev(dev); + + wd->ws.adhocMode = mode; +} + +u32_t zfiWlanQueryAdhocMode(zdev_t* dev, u8_t bWrapper) +{ + u32_t adhocMode; + + zmw_get_wlan_dev(dev); + + if ( bWrapper ) + { + adhocMode = wd->ws.adhocMode; + } + else + { + adhocMode = wd->wfc.bIbssGMode; + } + + return adhocMode; +} + + +u8_t zfiWlanSetCountryIsoName(zdev_t* dev, u8_t *countryIsoName, u8_t length) +{ + u8_t buf[5]; + zmw_get_wlan_dev(dev); + + if (length == 4) + { + buf[2] = wd->ws.countryIsoName[0] = countryIsoName[2]; + buf[3] = wd->ws.countryIsoName[1] = countryIsoName[1]; + buf[4] = wd->ws.countryIsoName[2] = countryIsoName[0]; + } + else if (length == 3) + { + buf[2] = wd->ws.countryIsoName[0] = countryIsoName[1]; + buf[3] = wd->ws.countryIsoName[1] = countryIsoName[0]; + buf[4] = wd->ws.countryIsoName[2] = '\0'; + } + else + { + return 1; + } + + return zfHpGetRegulationTablefromISO(dev, buf, length); +} + + +const char* zfiWlanQueryCountryIsoName(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + return wd->ws.countryIsoName; +} + + + +void zfiWlanSetRegulatory(zdev_t* dev, u8_t CCS, u16_t Code, u8_t bfirstChannel) +{ + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + if (CCS) + { + /* Reset Regulation Table by Country Code */ + zfHpGetRegulationTablefromCountry(dev, Code); + } + else + { + /* Reset Regulation Table by Region Code */ + zfHpGetRegulationTablefromRegionCode(dev, Code); + } + + if (bfirstChannel) { + zmw_enter_critical_section(dev); + wd->frequency = zfChGetFirstChannel(dev, NULL); + zmw_leave_critical_section(dev); + zfCoreSetFrequency(dev, wd->frequency); + } +} + + +const char* zfiHpGetisoNamefromregionCode(zdev_t* dev, u16_t regionCode) +{ + return zfHpGetisoNamefromregionCode(dev, regionCode); +} + +u16_t zfiWlanChannelToFrequency(zdev_t* dev, u8_t channel) +{ + return zfChNumToFreq(dev, channel, 0); +} + +u8_t zfiWlanFrequencyToChannel(zdev_t* dev, u16_t freq) +{ + u8_t is5GBand = 0; + + return zfChFreqToNum(freq, &is5GBand); +} + +void zfiWlanDisableDfsChannel(zdev_t* dev, u8_t disableFlag) +{ + zfHpDisableDfsChannel(dev, disableFlag); + return; +} + +void zfiWlanSetLEDCtrlParam(zdev_t* dev, u8_t type, u8_t flag) +{ + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + wd->ledStruct.LEDCtrlType = type; + wd->ledStruct.LEDCtrlFlagFromReg = flag; + zmw_leave_critical_section(dev); +} + +void zfiWlanEnableLeapConfig(zdev_t* dev, u8_t leapEnabled) +{ + zmw_get_wlan_dev(dev); + + wd->sta.leapEnabled = leapEnabled; +} + +u32_t zfiWlanQueryHwCapability(zdev_t* dev) +{ + return zfHpCapability(dev); +} + +u32_t zfiWlanQueryReceivedPacket(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + return wd->sta.ReceivedPktRatePerSecond; +} + +void zfiWlanCheckSWEncryption(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + if (wd->sta.SWEncryptEnable != 0) + { + zfHpSWDecrypt(dev, 1); + } +} + +u16_t zfiWlanQueryAllowChannels(zdev_t* dev, u16_t *channels) +{ + u16_t ii; + zmw_get_wlan_dev(dev); + + for (ii = 0; ii < wd->regulationTable.allowChannelCnt; ii++) + { + channels[ii] = wd->regulationTable.allowChannel[ii].channel; + } + + return wd->regulationTable.allowChannelCnt; +} + +void zfiWlanSetDynamicSIFSParam(zdev_t* dev, u8_t val) +{ + zmw_get_wlan_dev(dev); + + wd->dynamicSIFSEnable = val; + + zm_debug_msg1("wd->dynamicSIFSEnable = ", wd->dynamicSIFSEnable) +} + +u16_t zfiWlanGetMulticastAddressCount(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + return wd->sta.multicastList.size; +} + +void zfiWlanGetMulticastList(zdev_t* dev, u8_t* pMCList) +{ + struct zsMulticastAddr* pMacList = (struct zsMulticastAddr*) pMCList; + u8_t i; + + zmw_get_wlan_dev(dev); + + for ( i=0; ista.multicastList.size; i++ ) + { + zfMemoryCopy(pMacList[i].addr, wd->sta.multicastList.macAddr[i].addr, 6); + } +} + +void zfiWlanSetPacketFilter(zdev_t* dev, u32_t PacketFilter) +{ + u8_t bAllMulticast = 0; + u32_t oldFilter; + + zmw_get_wlan_dev(dev); + + oldFilter = wd->sta.osRxFilter; + + wd->sta.osRxFilter = PacketFilter; + + if ((oldFilter & ZM_PACKET_TYPE_ALL_MULTICAST) != + (wd->sta.osRxFilter & ZM_PACKET_TYPE_ALL_MULTICAST)) + { + if ( wd->sta.osRxFilter & ZM_PACKET_TYPE_ALL_MULTICAST ) + bAllMulticast = 1; + zfHpSetMulticastList(dev, wd->sta.multicastList.size, + (u8_t*)wd->sta.multicastList.macAddr, bAllMulticast); + } +} + +u8_t zfiCompareWithMulticastListAddress(zdev_t* dev, u16_t* dstMacAddr) +{ + u8_t i; + u8_t bIsInMCListAddr = 0; + + zmw_get_wlan_dev(dev); + + for ( i=0; ista.multicastList.size; i++ ) + { + if ( zfwMemoryIsEqual((u8_t*)dstMacAddr, (u8_t*)wd->sta.multicastList.macAddr[i].addr, 6) ) + { + bIsInMCListAddr = 1; + break; + } + } + + return bIsInMCListAddr; +} + +void zfiWlanSetSafeModeEnabled(zdev_t* dev, u8_t safeMode) +{ + zmw_get_wlan_dev(dev); + + wd->sta.bSafeMode = safeMode; + + if ( safeMode ) + zfStaEnableSWEncryption(dev, 1); + else + zfStaDisableSWEncryption(dev); +} + +void zfiWlanSetIBSSAdditionalIELength(zdev_t* dev, u32_t ibssAdditionalIESize, u8_t* ibssAdditionalIE) +{ + zmw_get_wlan_dev(dev); + + if ( ibssAdditionalIESize ) + { + wd->sta.ibssAdditionalIESize = ibssAdditionalIESize; + zfMemoryCopy(wd->sta.ibssAdditionalIE, ibssAdditionalIE, (u16_t)ibssAdditionalIESize); + } + else + wd->sta.ibssAdditionalIESize = 0; +} --- linux-2.6.28.orig/drivers/staging/otus/80211core/cic.c +++ linux-2.6.28/drivers/staging/otus/80211core/cic.c @@ -0,0 +1,496 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "cprecomp.h" +#include "ratectrl.h" + + +void zfUpdateBssid(zdev_t* dev, u8_t* bssid) +{ + + zmw_get_wlan_dev(dev); + + //zmw_declare_for_critical_section(); + + //zmw_enter_critical_section(dev); + wd->sta.bssid[0] = bssid[0] + (((u16_t) bssid[1]) << 8); + wd->sta.bssid[1] = bssid[2] + (((u16_t) bssid[3]) << 8); + wd->sta.bssid[2] = bssid[4] + (((u16_t) bssid[5]) << 8); + //zmw_leave_critical_section(dev); + + zfHpSetBssid(dev, bssid); + +} + +/************************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfResetSupportRate */ +/* Reset support rate to default value. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* type: ZM_DEFAULT_SUPPORT_RATE_ZERO => reset to zero */ +/* ZM_DEFAULT_SUPPORT_RATE_DISCONNECT => reset to disconnect status */ +/* ZM_DEFAULT_SUPPORT_RATE_IBSS_B => reset to IBSS creator(b mode) */ +/* ZM_DEFAULT_SUPPORT_RATE_IBSS_AG => reset to IBSS creator(a/g mode) */ +/* */ +/************************************************************************************/ +void zfResetSupportRate(zdev_t* dev, u8_t type) +{ + zmw_get_wlan_dev(dev); + + switch(type) + { + case ZM_DEFAULT_SUPPORT_RATE_ZERO: + wd->bRate = 0; + wd->bRateBasic = 0; + wd->gRate = 0; + wd->gRateBasic = 0; + break; + case ZM_DEFAULT_SUPPORT_RATE_DISCONNECT: + wd->bRate = 0xf; + wd->bRateBasic = 0xf; + wd->gRate = 0xff; + wd->gRateBasic = 0x15; + break; + case ZM_DEFAULT_SUPPORT_RATE_IBSS_B: + wd->bRate = 0xf; + wd->bRateBasic = 0xf; + wd->gRate = 0; + wd->gRateBasic = 0; + break; + case ZM_DEFAULT_SUPPORT_RATE_IBSS_AG: + wd->bRate = 0xf; + wd->bRateBasic = 0xf; + wd->gRate = 0xff; + wd->gRateBasic = 0; + break; + } +} + +void zfUpdateSupportRate(zdev_t* dev, u8_t* rateArray) +{ + u8_t bRate=0, bRateBasic=0, gRate=0, gRateBasic=0; + u8_t length = rateArray[1]; + u8_t i, j; + + zmw_get_wlan_dev(dev); + + for(i=2; ibRate |= bRate; + wd->bRateBasic |= bRateBasic; + wd->gRate |= gRate; + wd->gRateBasic |= gRateBasic; +} + +u8_t zfIsGOnlyMode(zdev_t* dev, u16_t frequency, u8_t* rateArray) +{ + u8_t length = rateArray[1]; + u8_t i, j; + + if (frequency < 3000) { + for (i = 2; i < length+2; i++) { + for (j = 0; j < 8; j++) { + if ( ((rateArray[i] & 0x7f) == zg11gRateTbl[j]) + && (rateArray[i] & 0x80) ) { + return 1; + } + } + } + } + + return 0; +} + +void zfGatherBMode(zdev_t* dev, u8_t* rateArray, u8_t* extrateArray) +{ + u8_t gatherBMode[ZM_MAX_SUPP_RATES_IE_SIZE + 2]; + u8_t i, j, k = 0; + u8_t length; + + gatherBMode[0] = ZM_WLAN_EID_SUPPORT_RATE; + gatherBMode[1] = 0; + + length = rateArray[1]; + for (i = 2; i < length+2; i++) { + for (j = 0; j < 4; j++) { + if ( (rateArray[i] & 0x7f) == zg11bRateTbl[j] ) { + gatherBMode[2+k] = rateArray[i]; + + gatherBMode[1]++; + k++; + } + } + } + + length = extrateArray[1]; + for (i = 2; i < length+2; i++) { + for (j = 0; j < 4; j++) { + if ( (extrateArray[i] & 0x7f) == zg11bRateTbl[j] ) { + gatherBMode[2+k] = extrateArray[i]; + + gatherBMode[1]++; + k++; + } + } + } + + extrateArray[0] = extrateArray[1] = 0; + zfMemoryCopy(rateArray, gatherBMode, gatherBMode[1]+2); +} + +u16_t zfGetRandomNumber(zdev_t* dev, u16_t initValue) +{ +#if 0 + /* Compiler/Linker error on Linux */ + if ( initValue ) + { + srand(initValue); + } + + return ((u16_t)rand()); +#endif + return 0; +} + +u8_t zfPSDeviceSleep(zdev_t* dev) +{ + //zmw_get_wlan_dev(dev); + + /* enter PS mode */ + + return 0; +} + +u8_t zcOfdmPhyCrtlToRate[] = +{ + /* 0x8=48M, 0x9=24M, 0xa=12M, 0xb=6M, 0xc=54M, 0xd=36M, 0xe=18M, 0xf=9M */ + 10, 8, 6, 4, 11, 9, 7, 5 +}; + +u8_t zfPhyCtrlToRate(u32_t phyCtrl) +{ + u32_t mt, mcs, sg; + u8_t rate = 0; + + mt = phyCtrl & 0x3; + mcs = (phyCtrl>>18) & 0x3f; + sg = (phyCtrl>>31) & 0x1; + + if ((mt == 0) && (mcs <=3)) + { + rate = (u8_t)mcs; + } + else if ((mt == 1) && (mcs >= 0x8) && (mcs <= 0xf)) + { + rate = zcOfdmPhyCrtlToRate[mcs-8]; + } + else if ((mt == 2) && (mcs <= 15)) + { + rate = (u8_t)mcs + 12; + if(sg) { + if (mcs != 7) + { + rate = (u8_t)mcs + 12 + 2; + } + else //MCS7-SG + { + rate = (u8_t)30; + } + } + } + + return rate; +} + + +void zfCoreEvent(zdev_t* dev, u16_t event, u8_t* rsp) +{ + u16_t i; + zbuf_t* psBuf; + u8_t moreData; + u8_t vap = 0; + u8_t peerIdx; + s8_t res; + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + + if (event == 0) //Beacon Event + { + if ( wd->wlanMode == ZM_MODE_AP ) + { + zfApSendBeacon(dev); + + if (wd->CurrentDtimCount == 0) + { + /* TODO : Send queued broadcast frames at BC/MC event */ + do + { + psBuf = NULL; + moreData = 0; + zmw_enter_critical_section(dev); + if (wd->ap.bcmcTail[vap] != wd->ap.bcmcHead[vap]) + { + //zm_msg0_mm(ZM_LV_0, "Send BCMC frames"); + psBuf = wd->ap.bcmcArray[vap][wd->ap.bcmcHead[vap]]; + wd->ap.bcmcHead[vap] = (wd->ap.bcmcHead[vap] + 1) + & (ZM_BCMC_ARRAY_SIZE - 1); + if (wd->ap.bcmcTail[vap] != wd->ap.bcmcHead[vap]) + { + moreData = 0x20; + } + } + zmw_leave_critical_section(dev); + if (psBuf != NULL) + { + /* TODO : config moreData bit */ + zfTxSendEth(dev, psBuf, 0, ZM_EXTERNAL_ALLOC_BUF, + moreData); + } + } while(psBuf != NULL); + + } + } + else + { + /* STA mode */ + if ( wd->sta.powerSaveMode > ZM_STA_PS_NONE ) + { + /* send queued packets */ + for(i=0; ista.staPSDataCount; i++) + { + zfTxSendEth(dev, wd->sta.staPSDataQueue[i], 0, + ZM_EXTERNAL_ALLOC_BUF, 0); + } + + wd->sta.staPSDataCount = 0; + } + + if ( wd->wlanMode == ZM_MODE_IBSS ) + { + zfStaSendBeacon(dev); + wd->sta.ibssAtimTimer = ZM_BIT_15 | wd->sta.atimWindow; + } + + zfPowerSavingMgrPreTBTTInterrupt(dev); + } + } //if (event == 0) //Beacon Event + else if (event == 1) //Retry completed event + { + u32_t retryRate; + + retryRate = (u32_t)(rsp[6]) + (((u32_t)(rsp[7]))<<8) + + (((u32_t)(rsp[8]))<<16) + (((u32_t)(rsp[9]))<<24); + /* Degrade Tx Rate */ + if (wd->wlanMode == ZM_MODE_AP) + { + zmw_enter_critical_section(dev); + if ((i=zfApFindSta(dev, (u16_t*)rsp)) != 0xffff) + { + zfRateCtrlTxFailEvent(dev, &wd->ap.staTable[i].rcCell, 0,(u32_t)zfPhyCtrlToRate(retryRate)); + } + zmw_leave_critical_section(dev); + } + else + { + zmw_enter_critical_section(dev); + res = zfStaFindOppositeByMACAddr(dev, (u16_t*)rsp, &peerIdx); + if ( res == 0 ) + { + zfRateCtrlTxFailEvent(dev, &wd->sta.oppositeInfo[peerIdx].rcCell, 0,(u32_t)zfPhyCtrlToRate(retryRate)); + } + zmw_leave_critical_section(dev); + } + } //else if (event == 1) //Retry completed event + else if (event == 2) //Tx Fail event + { + u32_t retryRate; + + retryRate = (u32_t)(rsp[6]) + (((u32_t)(rsp[7]))<<8) + + (((u32_t)(rsp[8]))<<16) + (((u32_t)(rsp[9]))<<24); + + /* Degrade Tx Rate */ + if (wd->wlanMode == ZM_MODE_AP) + { + zmw_enter_critical_section(dev); + if ((i=zfApFindSta(dev, (u16_t*)rsp)) != 0xffff) + { + zfRateCtrlTxFailEvent(dev, &wd->ap.staTable[i].rcCell, 0,(u32_t)zfPhyCtrlToRate(retryRate)); + } + zmw_leave_critical_section(dev); + + zfApSendFailure(dev, rsp); + } + else + { + zmw_enter_critical_section(dev); + res = zfStaFindOppositeByMACAddr(dev, (u16_t*)rsp, &peerIdx); + if ( res == 0 ) + { + zfRateCtrlTxFailEvent(dev, &wd->sta.oppositeInfo[peerIdx].rcCell, 0,(u32_t)zfPhyCtrlToRate(retryRate)); + } + zmw_leave_critical_section(dev); + } + } //else if (event == 2) //Tx Fail event + else if (event == 3) //Tx Comp event + { + u32_t retryRate; + + retryRate = (u32_t)(rsp[6]) + (((u32_t)(rsp[7]))<<8) + + (((u32_t)(rsp[8]))<<16) + (((u32_t)(rsp[9]))<<24); + + /* TODO : Tx completed, used for rate control probing */ + if (wd->wlanMode == ZM_MODE_AP) + { + zmw_enter_critical_section(dev); + if ((i=zfApFindSta(dev, (u16_t*)rsp)) != 0xffff) + { + zfRateCtrlTxSuccessEvent(dev, &wd->ap.staTable[i].rcCell, zfPhyCtrlToRate(retryRate)); + } + zmw_leave_critical_section(dev); + } + else + { + zmw_enter_critical_section(dev); + res = zfStaFindOppositeByMACAddr(dev, (u16_t*)rsp, &peerIdx); + if ( res == 0 ) + { + zfRateCtrlTxSuccessEvent(dev, &wd->sta.oppositeInfo[peerIdx].rcCell, zfPhyCtrlToRate(retryRate)); + } + zmw_leave_critical_section(dev); + } + } //else if (event == 3) //Tx Comp event + else if (event == 4) //BA failed count + { + u32_t fail; + u32_t rate; + peerIdx = 0; + + fail=((u32_t*)rsp)[0] & 0xFFFF; + rate=((u32_t*)rsp)[0] >> 16; + + if (rate > 15) { + rate = (rate & 0xF) + 12 + 2; + } + else { + rate = rate + 12; + } + + zmw_enter_critical_section(dev); + zfRateCtrlTxFailEvent(dev, &wd->sta.oppositeInfo[peerIdx].rcCell, (u8_t)rate, fail); + zmw_leave_critical_section(dev); + } +} + +void zfBeaconCfgInterrupt(zdev_t* dev, u8_t* rsp) +{ + u32_t txBeaconCounter; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + if ( wd->wlanMode == ZM_MODE_IBSS ) + { + txBeaconCounter = *((u32_t *)rsp); + if ( wd->sta.beaconTxCnt != txBeaconCounter ) + { + wd->sta.txBeaconInd = 1; + + zmw_enter_critical_section(dev); + wd->tickIbssSendBeacon = 0; + zmw_leave_critical_section(dev); + } + else + { + wd->sta.txBeaconInd = 0; + } + +#ifdef ZM_ENABLE_IBSS_DELAYED_JOIN_INDICATION + if ( wd->sta.txBeaconInd && wd->sta.ibssDelayedInd ) + { + if (wd->zfcbIbssPartnerNotify != NULL) + { + wd->zfcbIbssPartnerNotify(dev, 1, &wd->sta.ibssDelayedIndEvent); + } + + wd->sta.ibssDelayedInd = 0; + } +#endif + + wd->sta.beaconTxCnt = txBeaconCounter; + + // Need to check if the time is expired after ATIM window?? + + // Check if we have buffered any data for those stations that are sleeping + // If it's true, then transmitting ATIM pkt to notify them + +#ifdef ZM_ENABLE_IBSS_PS + // TODO: Need to check if the station receive our ATIM pkt??? + zfStaIbssPSSend(dev); + + if ( wd->sta.atimWindow == 0 ) + { + // We won't receive the end of ATIM isr so we fake it + zfPowerSavingMgrAtimWinExpired(dev); + } +#endif + } +} + +void zfEndOfAtimWindowInterrupt(zdev_t* dev) +{ +#ifdef ZM_ENABLE_IBSS_PS + zmw_get_wlan_dev(dev); + + if ( wd->wlanMode == ZM_MODE_IBSS ) + { + // Transmit any queued pkt for the stations!! + zfPowerSavingMgrAtimWinExpired(dev); + } +#endif +} --- linux-2.6.28.orig/drivers/staging/otus/80211core/ctxrx.c +++ linux-2.6.28/drivers/staging/otus/80211core/ctxrx.c @@ -0,0 +1,4096 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* */ +/* Module Name : htr.c */ +/* */ +/* Abstract */ +/* This module contains Tx and Rx functions. */ +/* */ +/* NOTES */ +/* None */ +/* */ +/************************************************************************/ +#include "cprecomp.h" + +u16_t zfWlanRxValidate(zdev_t* dev, zbuf_t* buf); +u16_t zfWlanRxFilter(zdev_t* dev, zbuf_t* buf); + + + +const u8_t zgSnapBridgeTunnel[6] = { 0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8 }; +const u8_t zgSnap8021h[6] = { 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00 }; +/* Table for converting IP DSCP P2-P0 bits to 802.11e Access Category */ +const u8_t zcUpToAc[8] = {0, 1, 1, 0, 2, 2, 3, 3}; //WMM default +//const u8_t zcUpToAc[8] = {0, 1, 1, 0, 0, 0, 0, 0}; //For 2 TxQ +//const u8_t zcUpToAc[8] = {0, 0, 0, 0, 0, 0, 0, 0}; //For single TxQ +const u8_t zcMaxspToPktNum[4] = {8, 2, 4, 6}; + +u8_t zfGetEncryModeFromRxStatus(struct zsAdditionInfo* addInfo) +{ + u8_t securityByte; + u8_t encryMode; + + securityByte = (addInfo->Tail.Data.SAIndex & 0xc0) >> 4; /* byte4 */ + securityByte |= (addInfo->Tail.Data.DAIndex & 0xc0) >> 6; /* byte5 */ + + switch( securityByte ) + { + case ZM_NO_WEP: + case ZM_WEP64: + case ZM_WEP128: + case ZM_WEP256: +#ifdef ZM_ENABLE_CENC + case ZM_CENC: +#endif //ZM_ENABLE_CENC + case ZM_TKIP: + case ZM_AES: + + encryMode = securityByte; + break; + + default: + + if ( (securityByte & 0xf8) == 0x08 ) + { + // decrypted by software + } + + encryMode = ZM_NO_WEP; + break; + } + + return encryMode; +} + +void zfGetRxIvIcvLength(zdev_t* dev, zbuf_t* buf, u8_t vap, u16_t* pIvLen, + u16_t* pIcvLen, struct zsAdditionInfo* addInfo) +{ + u16_t wdsPort; + u8_t encryMode; + + zmw_get_wlan_dev(dev); + + *pIvLen = 0; + *pIcvLen = 0; + + encryMode = zfGetEncryModeFromRxStatus(addInfo); + + if ( wd->wlanMode == ZM_MODE_AP ) + { + if (vap < ZM_MAX_AP_SUPPORT) + { + if (( wd->ap.encryMode[vap] == ZM_WEP64 ) || + ( wd->ap.encryMode[vap] == ZM_WEP128 ) || + ( wd->ap.encryMode[vap] == ZM_WEP256 )) + { + *pIvLen = 4; + *pIcvLen = 4; + } + else + { + u16_t id; + u16_t addr[3]; + + addr[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET); + addr[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+2); + addr[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+4); + + /* Find STA's information */ + if ((id = zfApFindSta(dev, addr)) != 0xffff) + { + if (wd->ap.staTable[id].encryMode == ZM_TKIP) + { + *pIvLen = 8; + *pIcvLen = 4; + } + else if (wd->ap.staTable[id].encryMode == ZM_AES) + { + *pIvLen = 8; + *pIcvLen = 8; // AES MIC + //*pIcvLen = 0; + } +#ifdef ZM_ENABLE_CENC + else if (wd->ap.staTable[id].encryMode == ZM_CENC) + { + *pIvLen = 18; + *pIcvLen= 16; + } +#endif //ZM_ENABLE_CENC + } + } + /* WDS port checking */ + if ((wdsPort = vap - 0x20) >= ZM_MAX_WDS_SUPPORT) + { + wdsPort = 0; + } + + switch (wd->ap.wds.encryMode[wdsPort]) + { + case ZM_WEP64: + case ZM_WEP128: + case ZM_WEP256: + *pIvLen = 4; + *pIcvLen = 4; + break; + case ZM_TKIP: + *pIvLen = 8; + *pIcvLen = 4; + break; + case ZM_AES: + *pIvLen = 8; + *pIcvLen = 0; + break; +#ifdef ZM_ENABLE_CENC + case ZM_CENC: + *pIvLen = 18; + *pIcvLen = 16; + break; +#endif //ZM_ENABLE_CENC + }/* end of switch */ + } + } + else if ( wd->wlanMode == ZM_MODE_PSEUDO) + { + /* test: 6518 for QA auto test */ + switch (encryMode) + { + case ZM_WEP64: + case ZM_WEP128: + case ZM_WEP256: + *pIvLen = 4; + *pIcvLen = 4; + break; + case ZM_TKIP: + *pIvLen = 8; + *pIcvLen = 4; + break; + case ZM_AES: + *pIvLen = 8; + *pIcvLen = 0; + break; +#ifdef ZM_ENABLE_CENC + case ZM_CENC: + *pIvLen = 18; + *pIcvLen = 16; +#endif //ZM_ENABLE_CENC + }/* end of switch */ + } + else + { + if ( (encryMode == ZM_WEP64)|| + (encryMode == ZM_WEP128)|| + (encryMode == ZM_WEP256) ) + { + *pIvLen = 4; + *pIcvLen = 4; + } + else if ( encryMode == ZM_TKIP ) + { + *pIvLen = 8; + *pIcvLen = 4; + } + else if ( encryMode == ZM_AES ) + { + *pIvLen = 8; + *pIcvLen = 8; // AES MIC + } +#ifdef ZM_ENABLE_CENC + else if ( encryMode == ZM_CENC) + { + *pIvLen = 18; + *pIcvLen= 16; + } +#endif //ZM_ENABLE_CENC + } +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfAgingDefragList */ +/* Force flushing whole defrag list or aging the buffer */ +/* in the defrag list. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* flushFlag : 1=>flushing, 0=>Aging */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Stephen Chen Atheros Communications, INC. 2007.1 */ +/* */ +/************************************************************************/ +void zfAgingDefragList(zdev_t* dev, u16_t flushFlag) +{ + u16_t i, j; + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + for(i=0; idefragTable.defragEntry[i].fragCount != 0 ) + { + if (((wd->tick - wd->defragTable.defragEntry[i].tick) > + (ZM_DEFRAG_AGING_TIME_SEC * ZM_TICK_PER_SECOND)) + || (flushFlag != 0)) + { + zm_msg1_rx(ZM_LV_2, "Aging defrag list :", i); + /* Free the buffers in the defrag list */ + for (j=0; jdefragTable.defragEntry[i].fragCount; j++) + { + zfwBufFree(dev, wd->defragTable.defragEntry[i].fragment[j], 0); + } + } + } + wd->defragTable.defragEntry[i].fragCount = 0; + } + + zmw_leave_critical_section(dev); + + return; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfAddFirstFragToDefragList */ +/* Add first fragment to defragment list, the first empty entry */ +/* will be selected. If the list is full, sequentially select */ +/* one entry for replacement. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : first fragment buffer */ +/* addr : address of first fragment buffer */ +/* seqNum : sequence of first fragment buffer */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Stephen Chen Atheros Communications, INC. 2007.1 */ +/* */ +/************************************************************************/ +void zfAddFirstFragToDefragList(zdev_t* dev, zbuf_t* buf, u8_t* addr, u16_t seqNum) +{ + u16_t i, j; + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + /* Find an empty one in defrag list */ + for(i=0; idefragTable.defragEntry[i].fragCount == 0 ) + { + break; + } + } + + /* If full, sequentially replace existing one */ + if (i == ZM_MAX_DEFRAG_ENTRIES) + { + i = wd->defragTable.replaceNum++ & (ZM_MAX_DEFRAG_ENTRIES-1); + /* Free the buffers in the defrag list to be replaced */ + for (j=0; jdefragTable.defragEntry[i].fragCount; j++) + { + zfwBufFree(dev, wd->defragTable.defragEntry[i].fragment[j], 0); + } + } + + wd->defragTable.defragEntry[i].fragCount = 1; + wd->defragTable.defragEntry[i].fragment[0] = buf; + wd->defragTable.defragEntry[i].seqNum = seqNum; + wd->defragTable.defragEntry[i].tick = wd->tick; + + for (j=0; j<6; j++) + { + wd->defragTable.defragEntry[i].addr[j] = addr[j]; + } + + zmw_leave_critical_section(dev); + + return; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfAddFragToDefragList */ +/* Add middle or last fragment to defragment list. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : first fragment buffer */ +/* addr : address of fragment buffer */ +/* seqNum : sequence fragment buffer */ +/* fragNum : fragment number of fragment buffer */ +/* moreFrag : more frag bit of fragment buffer */ +/* addInfo : addition info of fragment buffer */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Stephen Chen Atheros Communications, INC. 2007.1 */ +/* */ +/************************************************************************/ +zbuf_t* zfAddFragToDefragList(zdev_t* dev, zbuf_t* buf, u8_t* addr, + u16_t seqNum, u8_t fragNum, u8_t moreFrag, + struct zsAdditionInfo* addInfo) +{ + u16_t i, j, k; + zbuf_t* returnBuf = NULL; + u16_t defragDone = 0; + u16_t lenErr = 0; + u16_t startAddr, fragHead, frameLen, ivLen, icvLen; + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + /* Find frag in the defrag list */ + for(i=0; idefragTable.defragEntry[i].fragCount != 0 ) + { + /* Compare address */ + for (j=0; j<6; j++) + { + if (addr[j] != wd->defragTable.defragEntry[i].addr[j]) + { + break; + } + } + if (j == 6) + { + /* Compare sequence and fragment number */ + if (seqNum == wd->defragTable.defragEntry[i].seqNum) + { + if ((fragNum == wd->defragTable.defragEntry[i].fragCount) + && (fragNum < 8)) + { + /* Add frag frame to defrag list */ + wd->defragTable.defragEntry[i].fragment[fragNum] = buf; + wd->defragTable.defragEntry[i].fragCount++; + defragDone = 1; + + if (moreFrag == 0) + { + /* merge all fragment if more data bit is cleared */ + returnBuf = wd->defragTable.defragEntry[i].fragment[0]; + startAddr = zfwBufGetSize(dev, returnBuf); + /* skip WLAN header 24(Data) or 26(QoS Data) */ + fragHead = 24 + ((zmw_rx_buf_readh(dev, returnBuf, 0) & 0x80) >> 6); + zfGetRxIvIcvLength(dev, returnBuf, 0, &ivLen, &icvLen, addInfo); + fragHead += ivLen; /* skip IV */ + for(k=1; kdefragTable.defragEntry[i].fragCount; k++) + { + frameLen = zfwBufGetSize(dev, + wd->defragTable.defragEntry[i].fragment[k]); + if ((startAddr+frameLen-fragHead) < 1560) + { + zfRxBufferCopy(dev, returnBuf, wd->defragTable.defragEntry[i].fragment[k], + startAddr, fragHead, frameLen-fragHead); + startAddr += (frameLen-fragHead); + } + else + { + lenErr = 1; + } + zfwBufFree(dev, wd->defragTable.defragEntry[i].fragment[k], 0); + } + + wd->defragTable.defragEntry[i].fragCount = 0; + zfwBufSetSize(dev, returnBuf, startAddr); + } + break; + } + } + } + } + } + + zmw_leave_critical_section(dev); + + if (lenErr == 1) + { + zfwBufFree(dev, returnBuf, 0); + return NULL; + } + if (defragDone == 0) + { + zfwBufFree(dev, buf, 0); + return NULL; + } + + return returnBuf; +} + + +/* return value = NULL => save or free this frame */ +zbuf_t* zfDefragment(zdev_t* dev, zbuf_t* buf, u8_t* pbIsDefrag, + struct zsAdditionInfo* addInfo) +{ + u8_t fragNum; + u16_t seqNum; + u8_t moreFragBit; + u8_t addr[6]; + u16_t i; + zmw_get_wlan_dev(dev); + + ZM_BUFFER_TRACE(dev, buf) + + *pbIsDefrag = FALSE; + seqNum = zmw_buf_readh(dev, buf, 22); + fragNum = (u8_t)(seqNum & 0xf); + moreFragBit = (zmw_buf_readb(dev, buf, 1) & ZM_BIT_2) >> 2; + + if ((fragNum == 0) && (moreFragBit == 0)) + { + /* Not part of a fragmentation */ + + return buf; + } + else + { + wd->commTally.swRxFragmentCount++; + seqNum = seqNum >> 4; + for (i=0; i<6; i++) + { + addr[i] = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+i); + } + + if (fragNum == 0) + { + /* more frag = 1 */ + /* First part of a fragmentation */ + zm_msg1_rx(ZM_LV_2, "First Frag, seq=", seqNum); + zfAddFirstFragToDefragList(dev, buf, addr, seqNum); + buf = NULL; + } + else + { + /* Middle or last part of a fragmentation */ + zm_msg1_rx(ZM_LV_2, "Frag seq=", seqNum); + zm_msg1_rx(ZM_LV_2, "Frag moreFragBit=", moreFragBit); + buf = zfAddFragToDefragList(dev, buf, addr, seqNum, fragNum, moreFragBit, addInfo); + if (buf != NULL) + { + *pbIsDefrag = TRUE; + } + } + } + + return buf; +} + + +#if ZM_PROTOCOL_RESPONSE_SIMULATION +u16_t zfSwap(u16_t num) +{ + return ((num >> 8) + ((num & 0xff) << 8)); +} + + +void zfProtRspSim(zdev_t* dev, zbuf_t* buf) +{ + u16_t ethType; + u16_t arpOp; + u16_t prot; + u16_t temp; + u16_t i; + u16_t dip[2]; + u16_t dstPort; + u16_t srcPort; + + ethType = zmw_rx_buf_readh(dev, buf, 12); + zm_msg2_rx(ZM_LV_2, "ethType=", ethType); + + /* ARP */ + if (ethType == 0x0608) + { + arpOp = zmw_rx_buf_readh(dev, buf, 20); + dip[0] = zmw_rx_buf_readh(dev, buf, 38); + dip[1] = zmw_rx_buf_readh(dev, buf, 40); + zm_msg2_rx(ZM_LV_2, "arpOp=", arpOp); + zm_msg2_rx(ZM_LV_2, "ip0=", dip[0]); + zm_msg2_rx(ZM_LV_2, "ip1=", dip[1]); + + //ARP request to 192.168.1.15 + if ((arpOp == 0x0100) && (dip[0] == 0xa8c0) && (dip[1] == 0x0f01)); + { + zm_msg0_rx(ZM_LV_2, "ARP"); + /* ARP response */ + zmw_rx_buf_writeh(dev, buf, 20, 0x0200); + + /* dst hardware address */ + + /* src hardware address */ + //zmw_rx_buf_writeh(dev, buf, 6, 0xa000); + //zmw_rx_buf_writeh(dev, buf, 8, 0x0000); + //zmw_rx_buf_writeh(dev, buf, 10, 0x0000); + + /* dst ip address */ + for (i=0; i<5; i++) + { + temp = zmw_rx_buf_readh(dev, buf, 22+(i*2)); + zmw_rx_buf_writeh(dev, buf, 32+(i*2), temp); + } + + /* src hardware address */ + zmw_rx_buf_writeh(dev, buf, 22, 0xa000); + zmw_rx_buf_writeh(dev, buf, 24, 0x0000); + zmw_rx_buf_writeh(dev, buf, 26, 0x0000); + + /* src ip address */ + zmw_rx_buf_writeh(dev, buf, 28, 0xa8c0); + zmw_rx_buf_writeh(dev, buf, 30, 0x0f01); + } + } + /* ICMP */ + else if (ethType == 0x0008) + { + zm_msg0_rx(ZM_LV_2, "IP"); + prot = zmw_rx_buf_readb(dev, buf, 23); + dip[0] = zmw_rx_buf_readh(dev, buf, 30); + dip[1] = zmw_rx_buf_readh(dev, buf, 32); + zm_msg2_rx(ZM_LV_2, "prot=", prot); + zm_msg2_rx(ZM_LV_2, "ip0=", dip[0]); + zm_msg2_rx(ZM_LV_2, "ip1=", dip[1]); + + /* PING request to 192.168.1.15 */ + if ((prot == 0x1) && (dip[0] == 0xa8c0) && (dip[1] == 0x0f01)) + { + zm_msg0_rx(ZM_LV_2, "ICMP"); + /* change dst */ + for (i=0; i<3; i++) + { + temp = zmw_rx_buf_readh(dev, buf, 6+(i*2)); + zmw_rx_buf_writeh(dev, buf, i*2, temp); + } + /* change src */ + zmw_rx_buf_writeh(dev, buf, 6, 0xa000); + zmw_rx_buf_writeh(dev, buf, 8, 0x0000); + zmw_rx_buf_writeh(dev, buf, 10, 0x0000); + + /* exchange src ip and dst ip */ + for (i=0; i<2; i++) + { + temp = zmw_rx_buf_readh(dev, buf, 26+(i*2)); + zmw_rx_buf_writeh(dev, buf, 30+(i*2), temp); + } + zmw_rx_buf_writeh(dev, buf, 26, 0xa8c0); + zmw_rx_buf_writeh(dev, buf, 28, 0x0f01); + + /* change icmp type to echo reply */ + zmw_rx_buf_writeb(dev, buf, 34, 0x0); + + /* update icmp checksum */ + temp = zmw_rx_buf_readh(dev, buf, 36); + temp += 8; + zmw_rx_buf_writeh(dev, buf, 36, temp); + } + else if (prot == 0x6) + { + zm_msg0_rx(ZM_LV_2, "TCP"); + srcPort = zmw_rx_buf_readh(dev, buf, 34); + dstPort = zmw_rx_buf_readh(dev, buf, 36); + zm_msg2_rx(ZM_LV_2, "Src Port=", srcPort); + zm_msg2_rx(ZM_LV_2, "Dst Port=", dstPort); + if ((dstPort == 0x1500) || (srcPort == 0x1500)) + { + zm_msg0_rx(ZM_LV_2, "FTP"); + + /* change dst */ + for (i=0; i<3; i++) + { + temp = zmw_rx_buf_readh(dev, buf, 6+(i*2)); + zmw_rx_buf_writeh(dev, buf, i*2, temp); + } + /* change src */ + zmw_rx_buf_writeh(dev, buf, 6, 0xa000); + zmw_rx_buf_writeh(dev, buf, 8, 0x0000); + zmw_rx_buf_writeh(dev, buf, 10, 0x0000); + + /* exchange src ip and dst ip */ + for (i=0; i<2; i++) + { + temp = zmw_rx_buf_readh(dev, buf, 26+(i*2)); + zmw_rx_buf_writeh(dev, buf, 30+(i*2), temp); + } + zmw_rx_buf_writeh(dev, buf, 26, 0xa8c0); + zmw_rx_buf_writeh(dev, buf, 28, 0x0f01); +#if 0 + /* Patch src port */ + temp = zmw_rx_buf_readh(dev, buf, 34); + temp = zfSwap(zfSwap(temp) + 1); + zmw_rx_buf_writeh(dev, buf, 34, temp); + temp = zmw_rx_buf_readh(dev, buf, 38); + temp = zfSwap(zfSwap(temp) + 1); + zmw_rx_buf_writeh(dev, buf, 38, temp); + + /* Patch checksum */ + temp = zmw_rx_buf_readh(dev, buf, 50); + temp = zfSwap(temp); + temp = ~temp; + temp += 2; + temp = ~temp; + temp = zfSwap(temp); + zmw_rx_buf_writeh(dev, buf, 50, temp); +#endif + } + + } + else if (prot == 0x11) + { + /* change dst */ + for (i=0; i<3; i++) + { + temp = zmw_rx_buf_readh(dev, buf, 6+(i*2)); + zmw_rx_buf_writeh(dev, buf, i*2, temp); + } + /* change src */ + zmw_rx_buf_writeh(dev, buf, 6, 0xa000); + zmw_rx_buf_writeh(dev, buf, 8, 0x0000); + zmw_rx_buf_writeh(dev, buf, 10, 0x0000); + + zm_msg0_rx(ZM_LV_2, "UDP"); + srcPort = zmw_rx_buf_readh(dev, buf, 34); + dstPort = zmw_rx_buf_readh(dev, buf, 36); + zm_msg2_rx(ZM_LV_2, "Src Port=", srcPort); + zm_msg2_rx(ZM_LV_2, "Dst Port=", dstPort); + + /* exchange src ip and dst ip */ + for (i=0; i<2; i++) + { + temp = zmw_rx_buf_readh(dev, buf, 26+(i*2)); + zmw_rx_buf_writeh(dev, buf, 30+(i*2), temp); + } + zmw_rx_buf_writeh(dev, buf, 26, 0xa8c0); + zmw_rx_buf_writeh(dev, buf, 28, 0x0f01); + + /* exchange port */ + zmw_rx_buf_writeh(dev, buf, 34, srcPort+1); + zmw_rx_buf_writeh(dev, buf, 36, dstPort); + + /* checksum = 0 */ + zmw_rx_buf_writeh(dev, buf, 40, 0); + } + + } + else if (ethType == 0x0060) /* =>0x0060 is port */ + { + /* change src for Evl tool loop back receive */ + zmw_rx_buf_writeh(dev, buf, 6, 0xa000); + zmw_rx_buf_writeh(dev, buf, 8, 0x0000); + zmw_rx_buf_writeh(dev, buf, 10, 0x0000); + } + +} +#endif + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfiTxSendEth */ +/* Called to native 802.11 management frames */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : buffer pointer */ +/* port : WLAN port, 0=>standard, 0x1-0x7=>VAP, 0x20-0x25=>WDS */ +/* */ +/* OUTPUTS */ +/* error code */ +/* */ +/* AUTHOR */ +/* Ray ZyDAS Technology Corporation 2005.5 */ +/* */ +/************************************************************************/ +u16_t zfiTxSend80211Mgmt(zdev_t* dev, zbuf_t* buf, u16_t port) +{ + u16_t err; + //u16_t addrTblSize = 0; + //struct zsAddrTbl addrTbl; + u16_t hlen; + u16_t header[(24+25+1)/2]; + int i; + + for(i=0;i<12;i++) + { + header[i] = zmw_buf_readh(dev, buf, i); + } + hlen = 24; + + zfwBufRemoveHead(dev, buf, 24); + + if ((err = zfHpSend(dev, header, hlen, NULL, 0, NULL, 0, buf, 0, + ZM_EXTERNAL_ALLOC_BUF, 0, 0)) != ZM_SUCCESS) + { + goto zlError; + } + + return 0; + +zlError: + + zfwBufFree(dev, buf, 0); + return 0; +} + +u8_t zfiIsTxQueueFull(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + if ((((wd->vtxqHead[0] + 1) & ZM_VTXQ_SIZE_MASK) != wd->vtxqTail[0]) ) + { + zmw_leave_critical_section(dev); + return 0; + } + else + { + zmw_leave_critical_section(dev); + return 1; + } +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfiTxSendEth */ +/* Called to transmit Ethernet frame from upper layer. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : buffer pointer */ +/* port : WLAN port, 0=>standard, 0x1-0x7=>VAP, 0x20-0x25=>WDS */ +/* */ +/* OUTPUTS */ +/* error code */ +/* */ +/* AUTHOR */ +/* Stephen ZyDAS Technology Corporation 2005.5 */ +/* */ +/************************************************************************/ +u16_t zfiTxSendEth(zdev_t* dev, zbuf_t* buf, u16_t port) +{ + u16_t err, ret; + + zmw_get_wlan_dev(dev); + + ZM_PERFORMANCE_TX_MSDU(dev, wd->tick); + zm_msg1_tx(ZM_LV_2, "zfiTxSendEth(), port=", port); + /* Return error if port is disabled */ + if ((err = zfTxPortControl(dev, buf, port)) == ZM_PORT_DISABLED) + { + err = ZM_ERR_TX_PORT_DISABLED; + goto zlError; + } + +#if 1 + if ((wd->wlanMode == ZM_MODE_AP) && (port < 0x20)) + { + /* AP : Buffer frame for power saving STA */ + if ((ret = zfApBufferPsFrame(dev, buf, port)) == 1) + { + return ZM_SUCCESS; + } + } + else +#endif + if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) + { + if ( zfPowerSavingMgrIsSleeping(dev) ) + { + /*check ZM_ENABLE_POWER_SAVE flag*/ + zfPowerSavingMgrWakeup(dev); + } + } +#ifdef ZM_ENABLE_IBSS_PS + /* IBSS power-saving mode */ + else if ( wd->wlanMode == ZM_MODE_IBSS ) + { + if ( zfStaIbssPSQueueData(dev, buf) ) + { + return ZM_SUCCESS; + } + } +#endif + +#if 1 + //if ( wd->bQoSEnable ) + if (1) + { + /* Put to VTXQ[ac] */ + ret = zfPutVtxq(dev, buf); + + /* Push VTXQ[ac] */ + zfPushVtxq(dev); + } + else + { + ret = zfTxSendEth(dev, buf, port, ZM_EXTERNAL_ALLOC_BUF, 0); + } + + return ret; +#else + return zfTxSendEth(dev, buf, port, ZM_EXTERNAL_ALLOC_BUF, 0); +#endif + +zlError: + zm_msg2_tx(ZM_LV_1, "Tx Comp err=", err); + + zfwBufFree(dev, buf, err); + return err; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfTxSendEth */ +/* Called to transmit Ethernet frame from upper layer. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : buffer pointer */ +/* port : WLAN port, 0=>standard, 0x10-0x17=>VAP, 0x20-0x25=>WDS */ +/* */ +/* OUTPUTS */ +/* error code */ +/* */ +/* AUTHOR */ +/* Stephen ZyDAS Technology Corporation 2005.5 */ +/* */ +/************************************************************************/ +u16_t zfTxSendEth(zdev_t* dev, zbuf_t* buf, u16_t port, u16_t bufType, u16_t flag) +{ + u16_t err; + //u16_t addrTblSize; + //struct zsAddrTbl addrTbl; + u16_t removeLen; + u16_t header[(8+30+2+18)/2]; /* ctr+(4+a1+a2+a3+2+a4)+qos+iv */ + u16_t headerLen; + u16_t mic[8/2]; + u16_t micLen; + u16_t snap[8/2]; + u16_t snapLen; + u16_t fragLen; + u16_t frameLen; + u16_t fragNum; + struct zsFrag frag; + u16_t i, j, id; + u16_t offset; + u16_t da[3]; + u16_t sa[3]; + u8_t up; + u8_t qosType, keyIdx = 0; + u16_t fragOff; + u16_t newFlag; + struct zsMicVar* pMicKey; + u8_t tkipFrameOffset = 0; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + newFlag = flag & 0xff00; + flag = flag & 0xff; + + zm_msg1_tx(ZM_LV_2, "zfTxSendEth(), port=", port); + + /* Get IP TOS for QoS AC and IP frag offset */ + zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff); + + //EOSP bit + if (newFlag & 0x100) + { + up |= 0x10; + } + +#ifdef ZM_ENABLE_NATIVE_WIFI + if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) + { + /* DA */ + da[0] = zmw_tx_buf_readh(dev, buf, 16); + da[1] = zmw_tx_buf_readh(dev, buf, 18); + da[2] = zmw_tx_buf_readh(dev, buf, 20); + /* SA */ + sa[0] = zmw_tx_buf_readh(dev, buf, 10); + sa[1] = zmw_tx_buf_readh(dev, buf, 12); + sa[2] = zmw_tx_buf_readh(dev, buf, 14); + } + else if ( wd->wlanMode == ZM_MODE_IBSS ) + { + /* DA */ + da[0] = zmw_tx_buf_readh(dev, buf, 4); + da[1] = zmw_tx_buf_readh(dev, buf, 6); + da[2] = zmw_tx_buf_readh(dev, buf, 8); + /* SA */ + sa[0] = zmw_tx_buf_readh(dev, buf, 10); + sa[1] = zmw_tx_buf_readh(dev, buf, 12); + sa[2] = zmw_tx_buf_readh(dev, buf, 14); + } + else if ( wd->wlanMode == ZM_MODE_AP ) + { + /* DA */ + da[0] = zmw_tx_buf_readh(dev, buf, 4); + da[1] = zmw_tx_buf_readh(dev, buf, 6); + da[2] = zmw_tx_buf_readh(dev, buf, 8); + /* SA */ + sa[0] = zmw_tx_buf_readh(dev, buf, 16); + sa[1] = zmw_tx_buf_readh(dev, buf, 18); + sa[2] = zmw_tx_buf_readh(dev, buf, 20); + } + else + { + // + } +#else + /* DA */ + da[0] = zmw_tx_buf_readh(dev, buf, 0); + da[1] = zmw_tx_buf_readh(dev, buf, 2); + da[2] = zmw_tx_buf_readh(dev, buf, 4); + /* SA */ + sa[0] = zmw_tx_buf_readh(dev, buf, 6); + sa[1] = zmw_tx_buf_readh(dev, buf, 8); + sa[2] = zmw_tx_buf_readh(dev, buf, 10); +#endif + //Decide Key Index in ATOM, No meaning in OTUS--CWYang(m) + if (wd->wlanMode == ZM_MODE_AP) + { + keyIdx = wd->ap.bcHalKeyIdx[port]; + id = zfApFindSta(dev, da); + if (id != 0xffff) + { + switch (wd->ap.staTable[id].encryMode) + { + case ZM_AES: + case ZM_TKIP: +#ifdef ZM_ENABLE_CENC + case ZM_CENC: +#endif //ZM_ENABLE_CENC + keyIdx = wd->ap.staTable[id].keyIdx; + break; + } + } + } + else + { + switch (wd->sta.encryMode) + { + case ZM_WEP64: + case ZM_WEP128: + case ZM_WEP256: + keyIdx = wd->sta.keyId; + break; + case ZM_AES: + case ZM_TKIP: + if ((da[0] & 0x1)) + keyIdx = 5; + else + keyIdx = 4; + break; +#ifdef ZM_ENABLE_CENC + case ZM_CENC: + keyIdx = wd->sta.cencKeyId; + break; +#endif //ZM_ENABLE_CENC + } + } + + /* Create SNAP */ + removeLen = zfTxGenWlanSnap(dev, buf, snap, &snapLen); + //zm_msg1_tx(ZM_LV_0, "fragOff=", fragOff); + + +/* ********************************************************************************************** */ +/* Add 20071025 Mxzeng */ +/* ********************************************************************************************** */ +/* ---------------------------------------------------------------------------------------------- */ +/* Ethernet : frameLen = zfwBufGetSize(dev, buf); */ +/* ---+--6--+--6--+--2--+-----20-----+-------------------------+------ Variable -------+--------- */ +/* | DA | SA | Type| IP Header | TCP(20) UDP(12) ICMP(8) | Application Payload L | */ +/* ---+-----+-----+-----+------------+-------------------------+-----------------------+--------- */ +/* MSDU = 6 + 6 + 2 + ( Network Layer header ) + ( Transport Layer header ) + L */ +/* */ +/* MSDU - DA - SA : frameLen -= removeLen; */ +/* ---+--2--+-----20-----+-------------------------+------ Variable -------+--------------------- */ +/* | Type| IP Header | TCP(20) UDP(12) ICMP(8) | Application Payload L | */ +/* ---+-----+------------+-------------------------+-----------------------+--------------------- */ +/* */ +/* MPDU : frameLen + mpduLengthOffset ; */ +/* -+---2---+----2---+-6-+-6-+--6--+---2----+--1--+--1-+---1---+-------3------+-frameLen-+---4--+- */ +/* | frame |duration| DA|SA |BSSID|sequence|SNAP |SNAP|Control| RFC 1042 | | FCS | */ +/* |Control| | | | | number |DSAP |SSAP| | encapsulation| | | */ +/* -+-------+--------+---+---+-----+--------+-----+----+-------+--------------+----------+------+- */ +/* ----------------------------------------------------------------------------------------------- */ + + if ( wd->sta.encryMode == ZM_TKIP ) + tkipFrameOffset = 8; + + fragLen = wd->fragThreshold + tkipFrameOffset; // Fragmentation threshold for MPDU Lengths + frameLen = zfwBufGetSize(dev, buf); // MSDU Lengths + frameLen -= removeLen; // MSDU Lengths - DA - SA + + /* #1st create MIC Length manually */ + micLen = 0; + + /* Access Category */ + if (wd->wlanMode == ZM_MODE_AP) + { + zfApGetStaQosType(dev, da, &qosType); + if (qosType == 0) + { + up = 0; + } + } + else if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) + { + if (wd->sta.wmeConnected == 0) + { + up = 0; + } + } + else + { + /* TODO : STA QoS control field */ + up = 0; + } + + /* #2nd Assign sequence number */ + zmw_enter_critical_section(dev); + frag.seq[0] = ((wd->seq[zcUpToAc[up&0x7]]++) << 4); + zmw_leave_critical_section(dev); + + /* #3rd Pass the total payload to generate MPDU length ! */ + frag.buf[0] = buf; + frag.bufType[0] = bufType; + frag.flag[0] = (u8_t)flag; + fragNum = 1; + + headerLen = zfTxGenWlanHeader(dev, frag.buf[0], header, frag.seq[0], + frag.flag[0], snapLen+micLen, removeLen, port, da, sa, + up, &micLen, snap, snapLen, NULL); + + //zm_debug_msg1("#1 headerLen = ", headerLen); + + /* #4th Check the HeaderLen and determine whether the MPDU Lengths bigger than Fragmentation threshold */ + /* If MPDU Lengths large than fragmentation threshold --> headerLen = 0 */ + if( headerLen != 0 ) + { + zf80211FrameSend(dev, frag.buf[0], header, snapLen, da, sa, up, + headerLen, snap, mic, micLen, removeLen, frag.bufType[0], + zcUpToAc[up&0x7], keyIdx); + } + else //if( headerLen == 0 ) // Need to be fragmented + { + u16_t mpduLengthOffset; + u16_t pseudSnapLen = 0; + + mpduLengthOffset = header[0] - frameLen; // For fragmentation threshold ! + + micLen = zfTxGenWlanTail(dev, buf, snap, snapLen, mic); // Get snap and mic information + + fragLen = fragLen - mpduLengthOffset; + + //zm_debug_msg1("#2 frameLen = ", frameLen); + //zm_debug_msg1("#3 fragThreshold = ", fragLen); + + /* fragmentation */ + if (frameLen >= fragLen) + { + //copy fragLen to frag + i = 0; + while( frameLen > 0 ) + { + if ((frag.buf[i] = zfwBufAllocate(dev, fragLen+32)) != NULL) + { + frag.bufType[i] = ZM_INTERNAL_ALLOC_BUF; + frag.seq[i] = frag.seq[0] + i; + offset = removeLen + i*fragLen; + + /* Consider the offset if we consider snap length to the other fragmented frame */ + if ( i >= 1 ) + offset = offset + pseudSnapLen*(i-1); + + if (frameLen > fragLen + pseudSnapLen) + { + frag.flag[i] = flag | 0x4; /* More data */ + /* First fragment */ + if (i == 0) + { + /* Add SNAP */ + for (j=0; j>1)]); + } + zfTxBufferCopy(dev, frag.buf[i], buf, snapLen, offset, fragLen); + zfwBufSetSize(dev, frag.buf[i], snapLen+fragLen); + + /* Add pseud snap length to the other fragmented frame */ + pseudSnapLen = snapLen; + + frameLen -= fragLen; + } + /* Intermediate Fragment */ + else + { + //zfTxBufferCopy(dev, frag.buf[i], buf, 0, offset, fragLen); + //zfwBufSetSize(dev, frag.buf[i], fragLen); + + zfTxBufferCopy(dev, frag.buf[i], buf, 0, offset, fragLen+pseudSnapLen ); + zfwBufSetSize(dev, frag.buf[i], fragLen+pseudSnapLen); + + frameLen -= (fragLen+pseudSnapLen); + } + //frameLen -= fragLen; + } + else + { + /* Last fragment */ + zfTxBufferCopy(dev, frag.buf[i], buf, 0, offset, frameLen); + /* Add MIC if need */ + if ( micLen ) + { + zfCopyToRxBuffer(dev, frag.buf[i], (u8_t*) mic, frameLen, micLen); + } + zfwBufSetSize(dev, frag.buf[i], frameLen+micLen); + frameLen = 0; + frag.flag[i] = (u8_t)flag; /* No more data */ + } + i++; + } + else + { + break; + } + + // Please pay attention to the index of the buf !!! + // If write to null buf , the OS will crash !!! + zfwCopyBufContext(dev, buf, frag.buf[i-1]); + } + fragNum = i; + snapLen = micLen = removeLen = 0; + + zfwBufFree(dev, buf, 0); + } + + for (i=0; istandard, 10-17=>Virtual AP, 20-25=>WDS */ +/* */ +/* OUTPUTS */ +/* ZM_PORT_ENABLED or ZM_PORT_DISABLE */ +/* */ +/* AUTHOR */ +/* Signature ZyDAS Technology Corporation 2005.4 */ +/* */ +/************************************************************************/ +u16_t zfTxPortControl(zdev_t* dev, zbuf_t* buf, u16_t port) +{ + zmw_get_wlan_dev(dev); + + if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) + { + if ( wd->sta.adapterState == ZM_STA_STATE_DISCONNECT ) + { + zm_msg0_tx(ZM_LV_3, "Packets dropped due to disconnect state"); + return ZM_PORT_DISABLED; + } + } + + return ZM_PORT_ENABLED; +} + + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfIdlRecv */ +/* Do frame validation and filtering then pass to zfwRecv80211(). */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : received 802.11 frame buffer. */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Stephen ZyDAS Technology Corporation 2005.10 */ +/* */ +/************************************************************************/ +void zfCoreRecv(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo) +{ + u16_t ret = 0; + u16_t bssid[3]; + struct agg_tid_rx *tid_rx; + zmw_get_wlan_dev(dev); + + ZM_BUFFER_TRACE(dev, buf) + + /* tally */ + wd->commTally.DriverRxFrmCnt++; + + bssid[0] = zmw_buf_readh(dev, buf, 16); + bssid[1] = zmw_buf_readh(dev, buf, 18); + bssid[2] = zmw_buf_readh(dev, buf, 20); + + /* Validate Rx frame */ + if ((ret = zfWlanRxValidate(dev, buf)) != ZM_SUCCESS) + { + zm_msg1_rx(ZM_LV_1, "Rx invalid:", ret); + goto zlError; + } + +#ifdef ZM_ENABLE_AGGREGATION + //#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION + /* + * add by honda + */ + tid_rx = zfAggRxEnabled(dev, buf); + if (tid_rx && wd->reorder) + { + zfAggRx(dev, buf, addInfo, tid_rx); + + return; + } + /* + * end of add by honda + */ + //#endif +#endif + + /* Filter Rx frame */ + if ((ret = zfWlanRxFilter(dev, buf)) != ZM_SUCCESS) + { + zm_msg1_rx(ZM_LV_1, "Rx duplicated:", ret); + goto zlError; + } + + /* Discard error frame except mic failure */ + if ((addInfo->Tail.Data.ErrorIndication & 0x3f) != 0) + { + if ( wd->XLinkMode && ((addInfo->Tail.Data.ErrorIndication & 0x3f)==0x10) && + zfCompareWithBssid(dev, bssid) ) + { + // Bypass frames !!! + } + else + { + goto zlError; + } + } + + + /* OTUS command-8212 dump rx packet */ + if (wd->rxPacketDump) + { + zfwDumpBuf(dev, buf); + } + + /* Call zfwRecv80211() wrapper function to deliver Rx packet */ + /* to driver framework. */ + + if (wd->zfcbRecv80211 != NULL) + { + wd->zfcbRecv80211(dev, buf, addInfo); //CWYang(m) + } + else + { + zfiRecv80211(dev, buf, addInfo); + } + return; + +zlError: + zm_msg1_rx(ZM_LV_1, "Free packet, error code:", ret); + + wd->commTally.DriverDiscardedFrm++; + + /* Free Rx buffer */ + zfwBufFree(dev, buf, 0); + + return; +} + + +void zfShowRxEAPOL(zdev_t* dev, zbuf_t* buf, u16_t offset) +{ + u8_t packetType, keyType, code, identifier, type, flags; + u16_t packetLen, keyInfo, keyLen, keyDataLen, length, Op_Code; + u32_t replayCounterH, replayCounterL, vendorId, VendorType; + + /* EAPOL packet type */ + packetType = zmw_rx_buf_readb(dev, buf, offset+1); // 0: EAP-Packet + // 1: EAPOL-Start + // 2: EAPOL-Logoff + // 3: EAPOL-Key + // 4: EAPOL-Encapsulated-ASF-Alert + + /* EAPOL frame format */ + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ + /* ----------------------------------------------- */ + /* PAE Ethernet Type (0x888e) */ + /* ----------------------------------------------- 2 */ + /* Protocol Version | Type */ + /* ----------------------------------------------- 4 */ + /* Length */ + /* ----------------------------------------------- 6 */ + /* Packet Body */ + /* ----------------------------------------------- N */ + + /* EAPOL body length */ + packetLen = (((u16_t) zmw_rx_buf_readb(dev, buf, offset+2)) << 8) + + zmw_rx_buf_readb(dev, buf, offset+3); + + if( packetType == 0 ) + { // EAP-Packet + + /* EAP-Packet Code */ + code = zmw_rx_buf_readb(dev, buf, offset+4); // 1 : Request + // 2 : Response + // 3 : Success + // 4 : Failure + // An EAP packet of the type of Success and Failure has no Data field, and has a length of 4. + + /* EAP Packet format */ + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ + /* ----------------------------------------------- */ + /* Code | Identifier */ + /* ----------------------------------------------- 2 */ + /* Length */ + /* ----------------------------------------------- 4 */ + /* Data */ + /* ----------------------------------------------- N */ + + zm_debug_msg0("EAP-Packet"); + zm_debug_msg1("Packet Length = ", packetLen); + zm_debug_msg1("EAP-Packet Code = ", code); + + if( code == 1 ) + { + zm_debug_msg0("EAP-Packet Request"); + + /* EAP-Packet Identifier */ + identifier = zmw_rx_buf_readb(dev, buf, offset+5); + /* EAP-Packet Length */ + length = (((u16_t) zmw_rx_buf_readb(dev, buf, offset+6)) << 8) + + zmw_rx_buf_readb(dev, buf, offset+7); + /* EAP-Packet Type */ + type = zmw_rx_buf_readb(dev, buf, offset+8); // 1 : Identity + // 2 : Notification + // 3 : Nak (Response Only) + // 4 : MD5-Challenge + // 5 : One Time Password (OTP) + // 6 : Generic Token Card (GTC) + // 254 : (Expanded Types)Wi-Fi Protected Setup + // 255 : Experimental Use + + /* The data field in an EAP packet of the type of Request or Response is in the format shown bellowing */ + /* 0 1 2 3 4 5 6 7 N */ + /* ----------------------------------------------- */ + /* Type | Type Data */ + /* ----------------------------------------------- */ + + zm_debug_msg1("EAP-Packet Identifier = ", identifier); + zm_debug_msg1("EAP-Packet Length = ", length); + zm_debug_msg1("EAP-Packet Type = ", type); + + if( type == 1 ) + { + zm_debug_msg0("EAP-Packet Request Identity"); + } + else if( type == 2 ) + { + zm_debug_msg0("EAP-Packet Request Notification"); + } + else if( type == 4 ) + { + zm_debug_msg0("EAP-Packet Request MD5-Challenge"); + } + else if( type == 5 ) + { + zm_debug_msg0("EAP-Packet Request One Time Password"); + } + else if( type == 6 ) + { + zm_debug_msg0("EAP-Packet Request Generic Token Card"); + } + else if( type == 254 ) + { + zm_debug_msg0("EAP-Packet Request Wi-Fi Protected Setup"); + + /* 0 1 2 3 */ + /* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 */ + /*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+*/ + /*| Type | Vendor-Id |*/ + /*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+*/ + /*| Vendor-Type |*/ + /*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+*/ + /*| Vendor data... */ + /*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ + + /* EAP-Packet Vendor ID */ + vendorId = (((u32_t) zmw_rx_buf_readb(dev, buf, offset+9)) << 16) + + (((u32_t) zmw_rx_buf_readb(dev, buf, offset+10)) << 8) + + zmw_rx_buf_readb(dev, buf, offset+11); + /* EAP-Packet Vendor Type */ + VendorType = (((u32_t) zmw_rx_buf_readb(dev, buf, offset+12)) << 24) + + (((u32_t) zmw_rx_buf_readb(dev, buf, offset+13)) << 16) + + (((u32_t) zmw_rx_buf_readb(dev, buf, offset+14)) << 8) + + zmw_rx_buf_readb(dev, buf, offset+15); + /* EAP-Packet Op Code */ + Op_Code = (((u16_t) zmw_rx_buf_readb(dev, buf, offset+16)) << 8) + + zmw_rx_buf_readb(dev, buf, offset+17); + /* EAP-Packet Flags */ + flags = zmw_rx_buf_readb(dev, buf, offset+18); + + zm_debug_msg1("EAP-Packet Vendor ID = ", vendorId); + zm_debug_msg1("EAP-Packet Venodr Type = ", VendorType); + zm_debug_msg1("EAP-Packet Op Code = ", Op_Code); + zm_debug_msg1("EAP-Packet Flags = ", flags); + } + } + else if( code == 2 ) + { + zm_debug_msg0("EAP-Packet Response"); + + /* EAP-Packet Identifier */ + identifier = zmw_rx_buf_readb(dev, buf, offset+5); + /* EAP-Packet Length */ + length = (((u16_t) zmw_rx_buf_readb(dev, buf, offset+6)) << 8) + + zmw_rx_buf_readb(dev, buf, offset+7); + /* EAP-Packet Type */ + type = zmw_rx_buf_readb(dev, buf, offset+8); + + zm_debug_msg1("EAP-Packet Identifier = ", identifier); + zm_debug_msg1("EAP-Packet Length = ", length); + zm_debug_msg1("EAP-Packet Type = ", type); + + if( type == 1 ) + { + zm_debug_msg0("EAP-Packet Response Identity"); + } + else if( type == 2 ) + { + zm_debug_msg0("EAP-Packet Request Notification"); + } + else if( type == 3 ) + { + zm_debug_msg0("EAP-Packet Request Nak"); + } + else if( type == 4 ) + { + zm_debug_msg0("EAP-Packet Request MD5-Challenge"); + } + else if( type == 5 ) + { + zm_debug_msg0("EAP-Packet Request One Time Password"); + } + else if( type == 6 ) + { + zm_debug_msg0("EAP-Packet Request Generic Token Card"); + } + else if( type == 254 ) + { + zm_debug_msg0("EAP-Packet Response Wi-Fi Protected Setup"); + + /* EAP-Packet Vendor ID */ + vendorId = (((u32_t) zmw_rx_buf_readb(dev, buf, offset+9)) << 16) + + (((u32_t) zmw_rx_buf_readb(dev, buf, offset+10)) << 8) + + zmw_rx_buf_readb(dev, buf, offset+11); + /* EAP-Packet Vendor Type */ + VendorType = (((u32_t) zmw_rx_buf_readb(dev, buf, offset+12)) << 24) + + (((u32_t) zmw_rx_buf_readb(dev, buf, offset+13)) << 16) + + (((u32_t) zmw_rx_buf_readb(dev, buf, offset+14)) << 8) + + zmw_rx_buf_readb(dev, buf, offset+15); + /* EAP-Packet Op Code */ + Op_Code = (((u16_t) zmw_rx_buf_readb(dev, buf, offset+16)) << 8) + + zmw_rx_buf_readb(dev, buf, offset+17); + /* EAP-Packet Flags */ + flags = zmw_rx_buf_readb(dev, buf, offset+18); + + zm_debug_msg1("EAP-Packet Vendor ID = ", vendorId); + zm_debug_msg1("EAP-Packet Venodr Type = ", VendorType); + zm_debug_msg1("EAP-Packet Op Code = ", Op_Code); + zm_debug_msg1("EAP-Packet Flags = ", flags); + } + } + else if( code == 3 ) + { + zm_debug_msg0("EAP-Packet Success"); + + /* EAP-Packet Identifier */ + identifier = zmw_rx_buf_readb(dev, buf, offset+5); + /* EAP-Packet Length */ + length = (((u16_t) zmw_rx_buf_readb(dev, buf, offset+6)) << 8) + + zmw_rx_buf_readb(dev, buf, offset+7); + + zm_debug_msg1("EAP-Packet Identifier = ", identifier); + zm_debug_msg1("EAP-Packet Length = ", length); + } + else if( code == 4 ) + { + zm_debug_msg0("EAP-Packet Failure"); + + /* EAP-Packet Identifier */ + identifier = zmw_rx_buf_readb(dev, buf, offset+5); + /* EAP-Packet Length */ + length = (((u16_t) zmw_rx_buf_readb(dev, buf, offset+6)) << 8) + + zmw_rx_buf_readb(dev, buf, offset+7); + + zm_debug_msg1("EAP-Packet Identifier = ", identifier); + zm_debug_msg1("EAP-Packet Length = ", length); + } + } + else if( packetType == 1 ) + { // EAPOL-Start + zm_debug_msg0("EAPOL-Start"); + } + else if( packetType == 2 ) + { // EAPOL-Logoff + zm_debug_msg0("EAPOL-Logoff"); + } + else if( packetType == 3 ) + { // EAPOL-Key + /* EAPOL-Key type */ + keyType = zmw_rx_buf_readb(dev, buf, offset+4); + /* EAPOL-Key information */ + keyInfo = (((u16_t) zmw_rx_buf_readb(dev, buf, offset+5)) << 8) + + zmw_rx_buf_readb(dev, buf, offset+6); + /* EAPOL-Key length */ + keyLen = (((u16_t) zmw_rx_buf_readb(dev, buf, offset+7)) << 8) + + zmw_rx_buf_readb(dev, buf, offset+8); + /* EAPOL-Key replay counter (high double word) */ + replayCounterH = (((u32_t) zmw_rx_buf_readb(dev, buf, offset+9)) << 24) + + (((u32_t) zmw_rx_buf_readb(dev, buf, offset+10)) << 16) + + (((u32_t) zmw_rx_buf_readb(dev, buf, offset+11)) << 8) + + zmw_rx_buf_readb(dev, buf, offset+12); + /* EAPOL-Key replay counter (low double word) */ + replayCounterL = (((u32_t) zmw_rx_buf_readb(dev, buf, offset+13)) << 24) + + (((u32_t) zmw_rx_buf_readb(dev, buf, offset+14)) << 16) + + (((u32_t) zmw_rx_buf_readb(dev, buf, offset+15)) << 8) + + zmw_rx_buf_readb(dev, buf, offset+16); + /* EAPOL-Key data length */ + keyDataLen = (((u16_t) zmw_rx_buf_readb(dev, buf, offset+97)) << 8) + + zmw_rx_buf_readb(dev, buf, offset+98); + + zm_debug_msg0("EAPOL-Key"); + zm_debug_msg1("packet length = ", packetLen); + + if ( keyType == 254 ) + { + zm_debug_msg0("key type = 254 (SSN key descriptor)"); + } + else + { + zm_debug_msg2("key type = 0x", keyType); + } + + zm_debug_msg2("replay counter(L) = ", replayCounterL); + + zm_debug_msg2("key information = ", keyInfo); + + if ( keyInfo & ZM_BIT_3 ) + { + zm_debug_msg0(" - pairwise key"); + } + else + { + zm_debug_msg0(" - group key"); + } + + if ( keyInfo & ZM_BIT_6 ) + { + zm_debug_msg0(" - Tx key installed"); + } + else + { + zm_debug_msg0(" - Tx key not set"); + } + + if ( keyInfo & ZM_BIT_7 ) + { + zm_debug_msg0(" - Ack needed"); + } + else + { + zm_debug_msg0(" - Ack not needed"); + } + + if ( keyInfo & ZM_BIT_8 ) + { + zm_debug_msg0(" - MIC set"); + } + else + { + zm_debug_msg0(" - MIC not set"); + } + + if ( keyInfo & ZM_BIT_9 ) + { + zm_debug_msg0(" - packet encrypted"); + } + else + { + zm_debug_msg0(" - packet not encrypted"); + } + + zm_debug_msg1("keyLen = ", keyLen); + zm_debug_msg1("keyDataLen = ", keyDataLen); + } + else if( packetType == 4 ) + { + zm_debug_msg0("EAPOL-Encapsulated-ASF-Alert"); + } +} + +void zfShowTxEAPOL(zdev_t* dev, zbuf_t* buf, u16_t offset) +{ + u8_t packetType, keyType, code, identifier, type, flags; + u16_t packetLen, keyInfo, keyLen, keyDataLen, length, Op_Code; + u32_t replayCounterH, replayCounterL, vendorId, VendorType; + + zmw_get_wlan_dev(dev); + + zm_debug_msg1("EAPOL Packet size = ", zfwBufGetSize(dev, buf)); + + /* EAPOL packet type */ + // 0: EAP-Packet + // 1: EAPOL-Start + // 2: EAPOL-Logoff + // 3: EAPOL-Key + // 4: EAPOL-Encapsulated-ASF-Alert + + /* EAPOL frame format */ + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ + /* ----------------------------------------------- */ + /* PAE Ethernet Type (0x888e) */ + /* ----------------------------------------------- 2 */ + /* Protocol Version | Type */ + /* ----------------------------------------------- 4 */ + /* Length */ + /* ----------------------------------------------- 6 */ + /* Packet Body */ + /* ----------------------------------------------- N */ + + packetType = zmw_tx_buf_readb(dev, buf, offset+1); + /* EAPOL body length */ + packetLen = (((u16_t) zmw_tx_buf_readb(dev, buf, offset+2)) << 8) + + zmw_tx_buf_readb(dev, buf, offset+3); + + if( packetType == 0 ) + { // EAP-Packet + /* EAP-Packet Code */ + code = zmw_tx_buf_readb(dev, buf, offset+4); // 1 : Request + // 2 : Response + // 3 : Success + // 4 : Failure + + // An EAP packet of the type of Success and Failure has no Data field, and has a length of 4. + + /* EAP Packet format */ + /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ + /* ----------------------------------------------- */ + /* Code | Identifier */ + /* ----------------------------------------------- 2 */ + /* Length */ + /* ----------------------------------------------- 4 */ + /* Data */ + /* ----------------------------------------------- N */ + + zm_debug_msg0("EAP-Packet"); + zm_debug_msg1("Packet Length = ", packetLen); + zm_debug_msg1("EAP-Packet Code = ", code); + + if( code == 1 ) + { + zm_debug_msg0("EAP-Packet Request"); + + /* EAP-Packet Identifier */ + identifier = zmw_tx_buf_readb(dev, buf, offset+5); + /* EAP-Packet Length */ + length = (((u16_t) zmw_tx_buf_readb(dev, buf, offset+6)) << 8) + + zmw_tx_buf_readb(dev, buf, offset+7); + /* EAP-Packet Type */ + type = zmw_tx_buf_readb(dev, buf, offset+8); // 1 : Identity + // 2 : Notification + // 3 : Nak (Response Only) + // 4 : MD5-Challenge + // 5 : One Time Password (OTP) + // 6 : Generic Token Card (GTC) + // 254 : (Expanded Types)Wi-Fi Protected Setup + // 255 : Experimental Use + + /* The data field in an EAP packet of the type of Request or Response is in the format shown bellowing */ + /* 0 1 2 3 4 5 6 7 N */ + /* ----------------------------------------------- */ + /* Type | Type Data */ + /* ----------------------------------------------- */ + + zm_debug_msg1("EAP-Packet Identifier = ", identifier); + zm_debug_msg1("EAP-Packet Length = ", length); + zm_debug_msg1("EAP-Packet Type = ", type); + + if( type == 1 ) + { + zm_debug_msg0("EAP-Packet Request Identity"); + } + else if( type == 2 ) + { + zm_debug_msg0("EAP-Packet Request Notification"); + } + else if( type == 4 ) + { + zm_debug_msg0("EAP-Packet Request MD5-Challenge"); + } + else if( type == 5 ) + { + zm_debug_msg0("EAP-Packet Request One Time Password"); + } + else if( type == 6 ) + { + zm_debug_msg0("EAP-Packet Request Generic Token Card"); + } + else if( type == 254 ) + { + zm_debug_msg0("EAP-Packet Request Wi-Fi Protected Setup"); + + /* 0 1 2 3 */ + /* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 */ + /*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+*/ + /*| Type | Vendor-Id |*/ + /*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+*/ + /*| Vendor-Type |*/ + /*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+*/ + /*| Vendor data... */ + /*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ + + /* EAP-Packet Vendor ID */ + vendorId = (((u32_t) zmw_tx_buf_readb(dev, buf, offset+9)) << 16) + + (((u32_t) zmw_tx_buf_readb(dev, buf, offset+10)) << 8) + + zmw_tx_buf_readb(dev, buf, offset+11); + /* EAP-Packet Vendor Type */ + VendorType = (((u32_t) zmw_tx_buf_readb(dev, buf, offset+12)) << 24) + + (((u32_t) zmw_tx_buf_readb(dev, buf, offset+13)) << 16) + + (((u32_t) zmw_tx_buf_readb(dev, buf, offset+14)) << 8) + + zmw_tx_buf_readb(dev, buf, offset+15); + /* EAP-Packet Op Code */ + Op_Code = (((u16_t) zmw_tx_buf_readb(dev, buf, offset+16)) << 8) + + zmw_tx_buf_readb(dev, buf, offset+17); + /* EAP-Packet Flags */ + flags = zmw_tx_buf_readb(dev, buf, offset+18); + + zm_debug_msg1("EAP-Packet Vendor ID = ", vendorId); + zm_debug_msg1("EAP-Packet Venodr Type = ", VendorType); + zm_debug_msg1("EAP-Packet Op Code = ", Op_Code); + zm_debug_msg1("EAP-Packet Flags = ", flags); + } + } + else if( code == 2 ) + { + zm_debug_msg0("EAP-Packet Response"); + + /* EAP-Packet Identifier */ + identifier = zmw_tx_buf_readb(dev, buf, offset+5); + /* EAP-Packet Length */ + length = (((u16_t) zmw_tx_buf_readb(dev, buf, offset+6)) << 8) + + zmw_tx_buf_readb(dev, buf, offset+7); + /* EAP-Packet Type */ + type = zmw_tx_buf_readb(dev, buf, offset+8); + + zm_debug_msg1("EAP-Packet Identifier = ", identifier); + zm_debug_msg1("EAP-Packet Length = ", length); + zm_debug_msg1("EAP-Packet Type = ", type); + + if( type == 1 ) + { + zm_debug_msg0("EAP-Packet Response Identity"); + } + else if( type == 2 ) + { + zm_debug_msg0("EAP-Packet Request Notification"); + } + else if( type == 3 ) + { + zm_debug_msg0("EAP-Packet Request Nak"); + } + else if( type == 4 ) + { + zm_debug_msg0("EAP-Packet Request MD5-Challenge"); + } + else if( type == 5 ) + { + zm_debug_msg0("EAP-Packet Request One Time Password"); + } + else if( type == 6 ) + { + zm_debug_msg0("EAP-Packet Request Generic Token Card"); + } + else if( type == 254 ) + { + zm_debug_msg0("EAP-Packet Response Wi-Fi Protected Setup"); + + /* EAP-Packet Vendor ID */ + vendorId = (((u32_t) zmw_tx_buf_readb(dev, buf, offset+9)) << 16) + + (((u32_t) zmw_tx_buf_readb(dev, buf, offset+10)) << 8) + + zmw_tx_buf_readb(dev, buf, offset+11); + /* EAP-Packet Vendor Type */ + VendorType = (((u32_t) zmw_tx_buf_readb(dev, buf, offset+12)) << 24) + + (((u32_t) zmw_tx_buf_readb(dev, buf, offset+13)) << 16) + + (((u32_t) zmw_tx_buf_readb(dev, buf, offset+14)) << 8) + + zmw_tx_buf_readb(dev, buf, offset+15); + /* EAP-Packet Op Code */ + Op_Code = (((u16_t) zmw_tx_buf_readb(dev, buf, offset+16)) << 8) + + zmw_tx_buf_readb(dev, buf, offset+17); + /* EAP-Packet Flags */ + flags = zmw_tx_buf_readb(dev, buf, offset+18); + + zm_debug_msg1("EAP-Packet Vendor ID = ", vendorId); + zm_debug_msg1("EAP-Packet Venodr Type = ", VendorType); + zm_debug_msg1("EAP-Packet Op Code = ", Op_Code); + zm_debug_msg1("EAP-Packet Flags = ", flags); + } + } + else if( code == 3 ) + { + zm_debug_msg0("EAP-Packet Success"); + + /* EAP-Packet Identifier */ + identifier = zmw_rx_buf_readb(dev, buf, offset+5); + /* EAP-Packet Length */ + length = (((u16_t) zmw_rx_buf_readb(dev, buf, offset+6)) << 8) + + zmw_rx_buf_readb(dev, buf, offset+7); + + zm_debug_msg1("EAP-Packet Identifier = ", identifier); + zm_debug_msg1("EAP-Packet Length = ", length); + } + else if( code == 4 ) + { + zm_debug_msg0("EAP-Packet Failure"); + + /* EAP-Packet Identifier */ + identifier = zmw_tx_buf_readb(dev, buf, offset+5); + /* EAP-Packet Length */ + length = (((u16_t) zmw_tx_buf_readb(dev, buf, offset+6)) << 8) + + zmw_tx_buf_readb(dev, buf, offset+7); + + zm_debug_msg1("EAP-Packet Identifier = ", identifier); + zm_debug_msg1("EAP-Packet Length = ", length); + } + } + else if( packetType == 1 ) + { // EAPOL-Start + zm_debug_msg0("EAPOL-Start"); + } + else if( packetType == 2 ) + { // EAPOL-Logoff + zm_debug_msg0("EAPOL-Logoff"); + } + else if( packetType == 3 ) + { // EAPOL-Key + /* EAPOL-Key type */ + keyType = zmw_tx_buf_readb(dev, buf, offset+4); + /* EAPOL-Key information */ + keyInfo = (((u16_t) zmw_tx_buf_readb(dev, buf, offset+5)) << 8) + + zmw_tx_buf_readb(dev, buf, offset+6); + /* EAPOL-Key length */ + keyLen = (((u16_t) zmw_tx_buf_readb(dev, buf, offset+7)) << 8) + + zmw_tx_buf_readb(dev, buf, offset+8); + /* EAPOL-Key replay counter (high double word) */ + replayCounterH = (((u32_t) zmw_tx_buf_readb(dev, buf, offset+9)) << 24) + + (((u32_t) zmw_tx_buf_readb(dev, buf, offset+10)) << 16) + + (((u32_t) zmw_tx_buf_readb(dev, buf, offset+11)) << 8) + + zmw_tx_buf_readb(dev, buf, offset+12); + /* EAPOL-Key replay counter (low double word) */ + replayCounterL = (((u32_t) zmw_tx_buf_readb(dev, buf, offset+13)) << 24) + + (((u32_t) zmw_tx_buf_readb(dev, buf, offset+14)) << 16) + + (((u32_t) zmw_tx_buf_readb(dev, buf, offset+15)) << 8) + + zmw_tx_buf_readb(dev, buf, offset+16); + /* EAPOL-Key data length */ + keyDataLen = (((u16_t) zmw_tx_buf_readb(dev, buf, offset+97)) << 8) + + zmw_tx_buf_readb(dev, buf, offset+98); + + zm_debug_msg0("EAPOL-Key"); + zm_debug_msg1("packet length = ", packetLen); + + if ( keyType == 254 ) + { + zm_debug_msg0("key type = 254 (SSN key descriptor)"); + } + else + { + zm_debug_msg2("key type = 0x", keyType); + } + + zm_debug_msg2("replay counter(L) = ", replayCounterL); + + zm_debug_msg2("key information = ", keyInfo); + + if ( keyInfo & ZM_BIT_3 ) + { + zm_debug_msg0(" - pairwise key"); + } + else + { + zm_debug_msg0(" - group key"); + } + + if ( keyInfo & ZM_BIT_6 ) + { + zm_debug_msg0(" - Tx key installed"); + } + else + { + zm_debug_msg0(" - Tx key not set"); + } + + if ( keyInfo & ZM_BIT_7 ) + { + zm_debug_msg0(" - Ack needed"); + } + else + { + zm_debug_msg0(" - Ack not needed"); + } + + if ( keyInfo & ZM_BIT_8 ) + { + zm_debug_msg0(" - MIC set"); + } + else + { + zm_debug_msg0(" - MIC not set"); + } + + if ( keyInfo & ZM_BIT_9 ) + { + zm_debug_msg0(" - packet encrypted"); + } + else + { + zm_debug_msg0(" - packet not encrypted"); + } + + zm_debug_msg1("keyLen = ", keyLen); + zm_debug_msg1("keyDataLen = ", keyDataLen); + } + else if( packetType == 4 ) + { + zm_debug_msg0("EAPOL-Encapsulated-ASF-Alert"); + } +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfiRecv80211 */ +/* Called to receive 802.11 frame. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : received 802.11 frame buffer. */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Stephen ZyDAS Technology Corporation 2005.5 */ +/* */ +/************************************************************************/ +void zfiRecv80211(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo) +{ + u8_t snapCase=0, encryMode; + u16_t frameType, typeLengthField; + u16_t frameCtrl; + u16_t frameSubtype; + u16_t ret; + u16_t len; + u8_t bIsDefrag = 0; + u16_t offset, tailLen; + u8_t vap = 0; + u16_t da[3], sa[3]; + u16_t ii; + u8_t uapsdTrig = 0; + zbuf_t* psBuf; +#ifdef ZM_ENABLE_NATIVE_WIFI + u8_t i; +#endif + + zmw_get_wlan_dev(dev); + + ZM_BUFFER_TRACE(dev, buf) + + //zm_msg2_rx(ZM_LV_2, "zfiRecv80211(), buf=", buf); + + //zm_msg2_rx(ZM_LV_0, "h[0]=", zmw_rx_buf_readh(dev, buf, 0)); + //zm_msg2_rx(ZM_LV_0, "h[2]=", zmw_rx_buf_readh(dev, buf, 2)); + //zm_msg2_rx(ZM_LV_0, "h[4]=", zmw_rx_buf_readh(dev, buf, 4)); + + frameCtrl = zmw_rx_buf_readb(dev, buf, 0); + frameType = frameCtrl & 0xf; + frameSubtype = frameCtrl & 0xf0; + +#if 0 // Move to ProcessBeacon to judge if there's a new peer station + if ( (wd->wlanMode == ZM_MODE_IBSS)&& + (wd->sta.ibssPartnerStatus != ZM_IBSS_PARTNER_ALIVE) ) + { + zfStaIbssMonitoring(dev, buf); + } +#endif + + /* If data frame */ + if (frameType == ZM_WLAN_DATA_FRAME) + { + wd->sta.TotalNumberOfReceivePackets++; + wd->sta.TotalNumberOfReceiveBytes += zfwBufGetSize(dev, buf); + //zm_debug_msg1("Receive packets = ", wd->sta.TotalNumberOfReceivePackets); + + //zm_msg0_rx(ZM_LV_0, "Rx data"); + if (wd->wlanMode == ZM_MODE_AP) + { + if ((ret = zfApUpdatePsBit(dev, buf, &vap, &uapsdTrig)) != ZM_SUCCESS) + { + zfwBufFree(dev, buf, 0); + return; + } + + if (((uapsdTrig&0xf) != 0) && ((frameSubtype & 0x80) != 0)) + { + u8_t ac = zcUpToAc[zmw_buf_readb(dev, buf, 24)&0x7]; + u8_t pktNum; + u8_t mb; + u16_t flag; + u8_t src[6]; + + //printk("QoS ctrl=%d\n", zmw_buf_readb(dev, buf, 24)); + //printk("UAPSD trigger, ac=%d\n", ac); + + if (((0x8>>ac) & uapsdTrig) != 0) + { + pktNum = zcMaxspToPktNum[(uapsdTrig>>4) & 0x3]; + + for (ii=0; ii<6; ii++) + { + src[ii] = zmw_buf_readb(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+ii); + } + + for (ii=0; iiap.uapsdQ)) != NULL) + if ((psBuf = zfQueueGetWithMac(dev, wd->ap.uapsdQ, src, &mb)) != NULL) + { + if ((ii+1) == pktNum) + { + //EOSP anyway + flag = 0x100 | (mb<<5); + } + else + { + if (mb != 0) + { + //more data, not EOSP + flag = 0x20; + } + else + { + //no more data, EOSP + flag = 0x100; + } + } + zfTxSendEth(dev, psBuf, 0, ZM_EXTERNAL_ALLOC_BUF, flag); + } + + if ((psBuf == NULL) || (mb == 0)) + { + if ((ii == 0) && (psBuf == NULL)) + { + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_QOS_NULL, (u16_t*)src, 0, 0, 0); + } + break; + } + } + } + } + + } + else if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) + { + u16_t frameCtrlMSB; + u8_t bssid[6]; + + /* Check Is RIFS frame and decide to enable RIFS or not */ + if( wd->sta.EnableHT ) + zfCheckIsRIFSFrame(dev, buf, frameSubtype); + + if ( zfPowerSavingMgrIsSleeping(dev) || wd->sta.psMgr.tempWakeUp == 1) + { + frameCtrlMSB = zmw_rx_buf_readb(dev, buf, 1); + + /* check more data */ + if ( frameCtrlMSB & ZM_BIT_5 ) + { + //if rx frame's AC is not delivery-enabled + if ((wd->sta.qosInfo&0xf) != 0xf) + { + u8_t rxAc = 0; + if ((frameSubtype & 0x80) != 0) + { + rxAc = zcUpToAc[zmw_buf_readb(dev, buf, 24)&0x7]; + } + + if (((0x8>>rxAc) & wd->sta.qosInfo) == 0) + { + zfSendPSPoll(dev); + wd->sta.psMgr.tempWakeUp = 0; + } + } + } + } + /*increase beacon count when receive vaild data frame from AP*/ + ZM_MAC_WORD_TO_BYTE(wd->sta.bssid, bssid); + + if (zfStaIsConnected(dev)&& + zfRxBufferEqualToStr(dev, buf, bssid, ZM_WLAN_HEADER_A2_OFFSET, 6)) + { + wd->sta.rxBeaconCount++; + } + } + + zm_msg1_rx(ZM_LV_2, "Rx VAP=", vap); + + /* handle IV, EXT-IV, ICV, and EXT-ICV */ + zfGetRxIvIcvLength(dev, buf, vap, &offset, &tailLen, addInfo); + + zfStaIbssPSCheckState(dev, buf); + //QoS data frame + if ((frameSubtype & 0x80) == 0x80) + { + offset += 2; + } + + len = zfwBufGetSize(dev, buf); + /* remove ICV */ + if (tailLen > 0) + { + if (len > tailLen) + { + len -= tailLen; + zfwBufSetSize(dev, buf, len); + } + } + + /* Filter NULL data */ + if (((frameSubtype&0x40) != 0) || ((len = zfwBufGetSize(dev, buf))<=24)) + { + zm_msg1_rx(ZM_LV_1, "Free Rx NULL data, len=", len); + zfwBufFree(dev, buf, 0); + return; + } + + /* check and handle defragmentation */ + if ( wd->sta.bSafeMode && (wd->sta.wepStatus == ZM_ENCRYPTION_AES) && wd->sta.SWEncryptEnable ) + { + zm_msg0_rx(ZM_LV_1, "Bypass defragmentation packets in safe mode"); + } + else + { + if ( (buf = zfDefragment(dev, buf, &bIsDefrag, addInfo)) == NULL ) + { + /* In this case, the buffer has been freed in zfDefragment */ + return; + } + } + + ret = ZM_MIC_SUCCESS; + + /* If SW WEP/TKIP are not turned on */ + if ((wd->sta.SWEncryptEnable & ZM_SW_TKIP_DECRY_EN) == 0 && + (wd->sta.SWEncryptEnable & ZM_SW_WEP_DECRY_EN) == 0) + { + encryMode = zfGetEncryModeFromRxStatus(addInfo); + + /* check if TKIP */ + if ( encryMode == ZM_TKIP ) + { + if ( bIsDefrag ) + { + ret = zfMicRxVerify(dev, buf); + } + else + { + /* check MIC failure bit */ + if ( ZM_RX_STATUS_IS_MIC_FAIL(addInfo) ) + { + ret = ZM_MIC_FAILURE; + } + } + + if ( ret == ZM_MIC_FAILURE ) + { + u8_t Unicast_Pkt = 0x0; + + if ((zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET) & 0x1) == 0) + { + wd->commTally.swRxUnicastMicFailCount++; + Unicast_Pkt = 0x1; + }/* + else if (zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET) == 0xffff) + { + wd->commTally.swRxMulticastMicFailCount++; + }*/ + else + { + wd->commTally.swRxMulticastMicFailCount++; + } + if ( wd->wlanMode == ZM_MODE_AP ) + { + u16_t idx; + u8_t addr[6]; + + for (idx=0; idx<6; idx++) + { + addr[idx] = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+idx); + } + + if (wd->zfcbApMicFailureNotify != NULL) + { + wd->zfcbApMicFailureNotify(dev, addr, buf); + } + } + else + { + if(Unicast_Pkt) + { + zm_debug_msg0("Countermeasure : Unicast_Pkt "); + } + else + { + zm_debug_msg0("Countermeasure : Non-Unicast_Pkt "); + } + + if((wd->TKIP_Group_KeyChanging == 0x0) || (Unicast_Pkt == 0x1)) + { + zm_debug_msg0("Countermeasure : Do MIC Check "); + zfStaMicFailureHandling(dev, buf); + } + else + { + zm_debug_msg0("Countermeasure : SKIP MIC Check due to Group Keychanging "); + } + } + /* Discard MIC failed frame */ + zfwBufFree(dev, buf, 0); + return; + } + } + } + else + { + u8_t IsEncryFrame; + + /* TODO: Check whether WEP bit is turned on in MAC header */ + encryMode = ZM_NO_WEP; + + IsEncryFrame = (zmw_rx_buf_readb(dev, buf, 1) & 0x40); + + if (IsEncryFrame) + { + /* Software decryption for TKIP */ + if (wd->sta.SWEncryptEnable & ZM_SW_TKIP_DECRY_EN) + { + u16_t iv16; + u16_t iv32; + u8_t RC4Key[16]; + u16_t IvOffset; + struct zsTkipSeed *rxSeed; + + IvOffset = offset + ZM_SIZE_OF_WLAN_DATA_HEADER; + + rxSeed = zfStaGetRxSeed(dev, buf); + + if (rxSeed == NULL) + { + zm_debug_msg0("rxSeed is NULL"); + + /* Discard this frame */ + zfwBufFree(dev, buf, 0); + return; + } + + iv16 = (zmw_rx_buf_readb(dev, buf, IvOffset) << 8) + zmw_rx_buf_readb(dev, buf, IvOffset+2); + iv32 = zmw_rx_buf_readb(dev, buf, IvOffset+4) + + (zmw_rx_buf_readb(dev, buf, IvOffset+5) << 8) + + (zmw_rx_buf_readb(dev, buf, IvOffset+6) << 16) + + (zmw_rx_buf_readb(dev, buf, IvOffset+7) << 24); + + /* TKIP Key Mixing */ + zfTkipPhase1KeyMix(iv32, rxSeed); + zfTkipPhase2KeyMix(iv16, rxSeed); + zfTkipGetseeds(iv16, RC4Key, rxSeed); + + /* Decrypt Data */ + ret = zfTKIPDecrypt(dev, buf, IvOffset+ZM_SIZE_OF_IV+ZM_SIZE_OF_EXT_IV, 16, RC4Key); + + if (ret == ZM_ICV_FAILURE) + { + zm_debug_msg0("TKIP ICV fail"); + + /* Discard ICV failed frame */ + zfwBufFree(dev, buf, 0); + return; + } + + /* Remove ICV from buffer */ + zfwBufSetSize(dev, buf, len-4); + + /* Check MIC */ + ret = zfMicRxVerify(dev, buf); + + if (ret == ZM_MIC_FAILURE) + { + if ((zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET) & 0x1) == 0) + { + wd->commTally.swRxUnicastMicFailCount++; + } + else if (zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET) == 0xffff) + { + wd->commTally.swRxMulticastMicFailCount++; + } + else + { + wd->commTally.swRxMulticastMicFailCount++; + } + if ( wd->wlanMode == ZM_MODE_AP ) + { + u16_t idx; + u8_t addr[6]; + + for (idx=0; idx<6; idx++) + { + addr[idx] = zmw_rx_buf_readb(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+idx); + } + + if (wd->zfcbApMicFailureNotify != NULL) + { + wd->zfcbApMicFailureNotify(dev, addr, buf); + } + } + else + { + zfStaMicFailureHandling(dev, buf); + } + + zm_debug_msg0("MIC fail"); + /* Discard MIC failed frame */ + zfwBufFree(dev, buf, 0); + return; + } + + encryMode = ZM_TKIP; + offset += ZM_SIZE_OF_IV + ZM_SIZE_OF_EXT_IV; + } + else if(wd->sta.SWEncryptEnable & ZM_SW_WEP_DECRY_EN) + { + u16_t IvOffset; + u8_t keyLen = 5; + u8_t iv[3]; + u8_t *wepKey; + u8_t keyIdx; + + IvOffset = offset + ZM_SIZE_OF_WLAN_DATA_HEADER; + + /* Retrieve IV */ + iv[0] = zmw_rx_buf_readb(dev, buf, IvOffset); + iv[1] = zmw_rx_buf_readb(dev, buf, IvOffset+1); + iv[2] = zmw_rx_buf_readb(dev, buf, IvOffset+2); + + keyIdx = ((zmw_rx_buf_readb(dev, buf, IvOffset+3) >> 6) & 0x03); + + IvOffset += ZM_SIZE_OF_IV; + + if (wd->sta.SWEncryMode[keyIdx] == ZM_WEP64) + { + keyLen = 5; + } + else if (wd->sta.SWEncryMode[keyIdx] == ZM_WEP128) + { + keyLen = 13; + } + else if (wd->sta.SWEncryMode[keyIdx] == ZM_WEP256) + { + keyLen = 29; + } + + zfWEPDecrypt(dev, buf, IvOffset, keyLen, wd->sta.wepKey[keyIdx], iv); + + if (ret == ZM_ICV_FAILURE) + { + zm_debug_msg0("WEP ICV fail"); + + /* Discard ICV failed frame */ + zfwBufFree(dev, buf, 0); + return; + } + + encryMode = wd->sta.SWEncryMode[keyIdx]; + + /* Remove ICV from buffer */ + zfwBufSetSize(dev, buf, len-4); + + offset += ZM_SIZE_OF_IV; + } + } + } + +#ifdef ZM_ENABLE_CENC + //else if ( encryMode == ZM_CENC ) /* check if CENC */ + if ( encryMode == ZM_CENC ) + { + u32_t rxIV[4]; + + rxIV[0] = (zmw_rx_buf_readh(dev, buf, 28) << 16) + + zmw_rx_buf_readh(dev, buf, 26); + rxIV[1] = (zmw_rx_buf_readh(dev, buf, 32) << 16) + + zmw_rx_buf_readh(dev, buf, 30); + rxIV[2] = (zmw_rx_buf_readh(dev, buf, 36) << 16) + + zmw_rx_buf_readh(dev, buf, 34); + rxIV[3] = (zmw_rx_buf_readh(dev, buf, 40) << 16) + + zmw_rx_buf_readh(dev, buf, 38); + + //zm_debug_msg2("rxIV[0] = 0x", rxIV[0]); + //zm_debug_msg2("rxIV[1] = 0x", rxIV[1]); + //zm_debug_msg2("rxIV[2] = 0x", rxIV[2]); + //zm_debug_msg2("rxIV[3] = 0x", rxIV[3]); + + /* destination address*/ + da[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET); + da[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET+2); + da[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET+4); + + if ( wd->wlanMode == ZM_MODE_AP ) + { + } + else + { + if ((da[0] & 0x1)) + { //multicast frame + /* Accumlate the PN sequence */ + wd->sta.rxivGK[0] ++; + + if (wd->sta.rxivGK[0] == 0) + { + wd->sta.rxivGK[1]++; + } + + if (wd->sta.rxivGK[1] == 0) + { + wd->sta.rxivGK[2]++; + } + + if (wd->sta.rxivGK[2] == 0) + { + wd->sta.rxivGK[3]++; + } + + if (wd->sta.rxivGK[3] == 0) + { + wd->sta.rxivGK[0] = 0; + wd->sta.rxivGK[1] = 0; + wd->sta.rxivGK[2] = 0; + } + + //zm_debug_msg2("wd->sta.rxivGK[0] = 0x", wd->sta.rxivGK[0]); + //zm_debug_msg2("wd->sta.rxivGK[1] = 0x", wd->sta.rxivGK[1]); + //zm_debug_msg2("wd->sta.rxivGK[2] = 0x", wd->sta.rxivGK[2]); + //zm_debug_msg2("wd->sta.rxivGK[3] = 0x", wd->sta.rxivGK[3]); + + if ( !((wd->sta.rxivGK[0] == rxIV[0]) + && (wd->sta.rxivGK[1] == rxIV[1]) + && (wd->sta.rxivGK[2] == rxIV[2]) + && (wd->sta.rxivGK[3] == rxIV[3]))) + { + u8_t PacketDiscard = 0; + /* Discard PN Code Error frame */ + if (rxIV[0] < wd->sta.rxivGK[0]) + { + PacketDiscard = 1; + } + if (wd->sta.rxivGK[0] > 0xfffffff0) + { //boundary case + if ((rxIV[0] < 0xfffffff0) + && (((0xffffffff - wd->sta.rxivGK[0]) + rxIV[0]) > 16)) + { + PacketDiscard = 1; + } + } + else + { //normal case + if ((rxIV[0] - wd->sta.rxivGK[0]) > 16) + { + PacketDiscard = 1; + } + } + // sync sta pn code with ap because of losting some packets + wd->sta.rxivGK[0] = rxIV[0]; + wd->sta.rxivGK[1] = rxIV[1]; + wd->sta.rxivGK[2] = rxIV[2]; + wd->sta.rxivGK[3] = rxIV[3]; + if (PacketDiscard) + { + zm_debug_msg0("Discard PN Code lost too much multicast frame"); + zfwBufFree(dev, buf, 0); + return; + } + } + } + else + { //unicast frame + /* Accumlate the PN sequence */ + wd->sta.rxiv[0] += 2; + + if (wd->sta.rxiv[0] == 0 || wd->sta.rxiv[0] == 1) + { + wd->sta.rxiv[1]++; + } + + if (wd->sta.rxiv[1] == 0) + { + wd->sta.rxiv[2]++; + } + + if (wd->sta.rxiv[2] == 0) + { + wd->sta.rxiv[3]++; + } + + if (wd->sta.rxiv[3] == 0) + { + wd->sta.rxiv[0] = 0; + wd->sta.rxiv[1] = 0; + wd->sta.rxiv[2] = 0; + } + + //zm_debug_msg2("wd->sta.rxiv[0] = 0x", wd->sta.rxiv[0]); + //zm_debug_msg2("wd->sta.rxiv[1] = 0x", wd->sta.rxiv[1]); + //zm_debug_msg2("wd->sta.rxiv[2] = 0x", wd->sta.rxiv[2]); + //zm_debug_msg2("wd->sta.rxiv[3] = 0x", wd->sta.rxiv[3]); + + if ( !((wd->sta.rxiv[0] == rxIV[0]) + && (wd->sta.rxiv[1] == rxIV[1]) + && (wd->sta.rxiv[2] == rxIV[2]) + && (wd->sta.rxiv[3] == rxIV[3]))) + { + zm_debug_msg0("PN Code mismatch, lost unicast frame, sync pn code to recv packet"); + // sync sta pn code with ap because of losting some packets + wd->sta.rxiv[0] = rxIV[0]; + wd->sta.rxiv[1] = rxIV[1]; + wd->sta.rxiv[2] = rxIV[2]; + wd->sta.rxiv[3] = rxIV[3]; + /* Discard PN Code Error frame */ + //zm_debug_msg0("Discard PN Code mismatch unicast frame"); + //zfwBufFree(dev, buf, 0); + //return; + } + } + } + } +#endif //ZM_ENABLE_CENC + + /* for tally */ + if ((zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET) & 0x1) == 0) + { + /* for ACU to display RxRate */ + zfWlanUpdateRxRate(dev, addInfo); + + wd->commTally.rxUnicastFrm++; + wd->commTally.rxUnicastOctets += (len-24); + } + else if (zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET) == 0xffff) + { + wd->commTally.rxBroadcastFrm++; + wd->commTally.rxBroadcastOctets += (len-24); + } + else + { + wd->commTally.rxMulticastFrm++; + wd->commTally.rxMulticastOctets += (len-24); + } + wd->ledStruct.rxTraffic++; + + if ((frameSubtype & 0x80) == 0x80) + { + /* if QoS control bit-7 is 1 => A-MSDU frame */ + if ((zmw_rx_buf_readh(dev, buf, 24) & 0x80) != 0) + { + zfDeAmsdu(dev, buf, vap, encryMode); + return; + } + } + + // Remove MIC of TKIP + if ( encryMode == ZM_TKIP ) + { + zfwBufSetSize(dev, buf, zfwBufGetSize(dev, buf) - 8); + } + + /* Convert 802.11 and SNAP header to ethernet header */ + if ( (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)|| + (wd->wlanMode == ZM_MODE_IBSS) ) + { + /* destination address*/ + da[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET); + da[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET+2); + da[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A1_OFFSET+4); + + /* check broadcast frame */ + if ( (da[0] == 0xffff) && (da[1] == 0xffff) && (da[2] == 0xffff) ) + { + // Ap send broadcast frame to the DUT ! + } + /* check multicast frame */ + /* TODO : Remove these code, hardware should be able to block */ + /* multicast frame on the multicast address list */ + /* or bypass all multicast packet by flag bAllMulticast */ + else if ((da[0] & 0x01) && (wd->sta.bAllMulticast == 0)) + { + for(ii=0; iista.multicastList.size; ii++) + { + if ( zfMemoryIsEqual(wd->sta.multicastList.macAddr[ii].addr, + (u8_t*) da, 6)) + { + break; + } + } + + if ( ii == wd->sta.multicastList.size ) + { /* not found */ + zm_debug_msg0("discard unknown multicast frame"); + + zfwBufFree(dev, buf, 0); + return; + } + } + +#ifdef ZM_ENABLE_NATIVE_WIFI //Native Wifi : 1, Ethernet format : 0 + //To remove IV + if (offset > 0) + { + for (i=12; i>0; i--) + { + zmw_rx_buf_writeh(dev, buf, ((i-1)*2)+offset, + zmw_rx_buf_readh(dev, buf, (i-1)*2)); + } + zfwBufRemoveHead(dev, buf, offset); + } +#else + + if (zfRxBufferEqualToStr(dev, buf, zgSnapBridgeTunnel, + 24+offset, 6)) + { + snapCase = 1; + } + else if ( zfRxBufferEqualToStr(dev, buf, zgSnap8021h, + 24+offset, 6) ) + { + typeLengthField = + (((u16_t) zmw_rx_buf_readb(dev, buf, 30+offset)) << 8) + + zmw_rx_buf_readb(dev, buf, 31+offset); + + //zm_debug_msg2("tpyeLengthField = ", typeLengthField); + + //8137 : IPX, 80F3 : Appletalk + if ( (typeLengthField != 0x8137)&& + (typeLengthField != 0x80F3) ) + { + snapCase = 2; + } + + if ( typeLengthField == 0x888E ) + { + zfShowRxEAPOL(dev, buf, 32); + } + } + else + { + //zfwDumpBuf(dev, buf); + } + + /* source address */ + if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) + { + /* SA = Address 3 */ + sa[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET); + sa[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+2); + sa[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A3_OFFSET+4); + } + else + { + /* SA = Address 2 */ + sa[0] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET); + sa[1] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+2); + sa[2] = zmw_rx_buf_readh(dev, buf, ZM_WLAN_HEADER_A2_OFFSET+4); + } + + if ( snapCase ) + { + /* SA */ + zmw_rx_buf_writeh(dev, buf, 24+offset, sa[0]); + zmw_rx_buf_writeh(dev, buf, 26+offset, sa[1]); + zmw_rx_buf_writeh(dev, buf, 28+offset, sa[2]); + + /* DA = Address 1 */ + zmw_rx_buf_writeh(dev, buf, 18+offset, da[0]); + zmw_rx_buf_writeh(dev, buf, 20+offset, da[1]); + zmw_rx_buf_writeh(dev, buf, 22+offset, da[2]); + zfwBufRemoveHead(dev, buf, 18+offset); + } + else + { + /* SA */ + zmw_rx_buf_writeh(dev, buf, 16+offset, sa[0]); + zmw_rx_buf_writeh(dev, buf, 18+offset, sa[1]); + zmw_rx_buf_writeh(dev, buf, 20+offset, sa[2]); + + /* DA = Address 1 */ + zmw_rx_buf_writeh(dev, buf, 10+offset, da[0]); + zmw_rx_buf_writeh(dev, buf, 12+offset, da[1]); + zmw_rx_buf_writeh(dev, buf, 14+offset, da[2]); + zfwBufRemoveHead(dev, buf, 10+offset); + /* Ethernet payload length */ + typeLengthField = zfwBufGetSize(dev, buf) - 14; + zmw_rx_buf_writeh(dev, buf, 12, (typeLengthField<<8)+(typeLengthField>>8)); + } +#endif // ZM_ENABLE_NATIVE_WIFI + } + else if (wd->wlanMode == ZM_MODE_AP) + { + //if ((zmw_rx_buf_readb(dev, buf, 1) & 0x3) != 3) + if (vap < ZM_MAX_AP_SUPPORT) + /* AP mode */ + { +#ifdef ZM_ENABLE_NATIVE_WIFI //Native Wifi : 1, Ethernet format : 0 + //To remove IV + if (offset > 0) + { + for (i=12; i>0; i--) + { + zmw_rx_buf_writeh(dev, buf, ((i-1)*2)+offset, + zmw_rx_buf_readh(dev, buf, (i-1)*2)); + } + zfwBufRemoveHead(dev, buf, offset); + } +#else + /* SA = Address 2 */ + zmw_rx_buf_writeh(dev, buf, 24+offset, zmw_rx_buf_readh(dev, buf, + ZM_WLAN_HEADER_A2_OFFSET)); + zmw_rx_buf_writeh(dev, buf, 26+offset, zmw_rx_buf_readh(dev, buf, + ZM_WLAN_HEADER_A2_OFFSET+2)); + zmw_rx_buf_writeh(dev, buf, 28+offset, zmw_rx_buf_readh(dev, buf, + ZM_WLAN_HEADER_A2_OFFSET+4)); + /* DA = Address 3 */ + /* Seq : Read 20 write 22, read 18 write 20, read 16 write 18 */ + /* sequence must not be inverted */ + zmw_rx_buf_writeh(dev, buf, 22+offset, zmw_rx_buf_readh(dev, buf, + ZM_WLAN_HEADER_A3_OFFSET+4)); + zmw_rx_buf_writeh(dev, buf, 20+offset, zmw_rx_buf_readh(dev, buf, + ZM_WLAN_HEADER_A3_OFFSET+2)); + zmw_rx_buf_writeh(dev, buf, 18+offset, zmw_rx_buf_readh(dev, buf, + ZM_WLAN_HEADER_A3_OFFSET)); + zfwBufRemoveHead(dev, buf, 18+offset); +#endif // ZM_ENABLE_NATIVE_WIFI + #if 1 + if ((ret = zfIntrabssForward(dev, buf, vap)) == 1) + { + /* Free Rx buffer if intra-BSS unicast frame */ + zm_msg0_rx(ZM_LV_2, "Free intra-BSS unicast frame"); + zfwBufFree(dev, buf, 0); + return; + } + #endif + } + else + /* WDS mode */ + { + zm_msg0_rx(ZM_LV_2, "Rx WDS data"); + + /* SA = Address 4 */ + zmw_rx_buf_writeh(dev, buf, 30+offset, zmw_rx_buf_readh(dev, buf, + ZM_WLAN_HEADER_A4_OFFSET)); + zmw_rx_buf_writeh(dev, buf, 32+offset, zmw_rx_buf_readh(dev, buf, + ZM_WLAN_HEADER_A4_OFFSET+2)); + zmw_rx_buf_writeh(dev, buf, 34+offset, zmw_rx_buf_readh(dev, buf, + ZM_WLAN_HEADER_A4_OFFSET+4)); + /* DA = Address 3 */ + /* Seq : Read 20 write 22, read 18 write 20, read 16 write 18 */ + /* sequence must not be inverted */ + zmw_rx_buf_writeh(dev, buf, 28+offset, zmw_rx_buf_readh(dev, buf, + ZM_WLAN_HEADER_A3_OFFSET+4)); + zmw_rx_buf_writeh(dev, buf, 26+offset, zmw_rx_buf_readh(dev, buf, + ZM_WLAN_HEADER_A3_OFFSET+2)); + zmw_rx_buf_writeh(dev, buf, 24+offset, zmw_rx_buf_readh(dev, buf, + ZM_WLAN_HEADER_A3_OFFSET)); + zfwBufRemoveHead(dev, buf, 24+offset); + } + } + else if (wd->wlanMode == ZM_MODE_PSEUDO) + { + /* WDS test: remove add4 */ + if (wd->enableWDS) + { + offset += 6; + } + + /* SA = Address 2 */ + zmw_rx_buf_writeh(dev, buf, 24+offset, zmw_rx_buf_readh(dev, buf, + ZM_WLAN_HEADER_A2_OFFSET)); + zmw_rx_buf_writeh(dev, buf, 26+offset, zmw_rx_buf_readh(dev, buf, + ZM_WLAN_HEADER_A2_OFFSET+2)); + zmw_rx_buf_writeh(dev, buf, 28+offset, zmw_rx_buf_readh(dev, buf, + ZM_WLAN_HEADER_A2_OFFSET+4)); + /* DA = Address 1 */ + zmw_rx_buf_writeh(dev, buf, 18+offset, zmw_rx_buf_readh(dev, buf, + ZM_WLAN_HEADER_A1_OFFSET)); + zmw_rx_buf_writeh(dev, buf, 20+offset, zmw_rx_buf_readh(dev, buf, + ZM_WLAN_HEADER_A1_OFFSET+2)); + zmw_rx_buf_writeh(dev, buf, 22+offset, zmw_rx_buf_readh(dev, buf, + ZM_WLAN_HEADER_A1_OFFSET+4)); + zfwBufRemoveHead(dev, buf, 18+offset); + } + else + { + zm_assert(0); + } + + /* Call zfwRecvEth() to notify upper layer */ + //zm_msg2_rx(ZM_LV_2, "Call zfwRecvEth(), buf=", buf); + //zfwDumpBuf(dev, buf); + + #if ZM_PROTOCOL_RESPONSE_SIMULATION == 1 + zfProtRspSim(dev, buf); + #endif + //zfwDumpBuf(dev, buf); + + /* tally */ + wd->commTally.NotifyNDISRxFrmCnt++; + + if (wd->zfcbRecvEth != NULL) + { + wd->zfcbRecvEth(dev, buf, vap); + ZM_PERFORMANCE_RX_MSDU(dev, wd->tick) + } + } + /* if management frame */ + else if (frameType == ZM_WLAN_MANAGEMENT_FRAME) + { + zm_msg2_rx(ZM_LV_2, "Rx management,FC=", frameCtrl); + /* Call zfProcessManagement() to handle management frame */ + zfProcessManagement(dev, buf, addInfo); //CWYang(m) + zfwBufFree(dev, buf, 0); + } + /* PsPoll */ + else if ((wd->wlanMode == ZM_MODE_AP) && (frameCtrl == 0xa4)) + { + zm_msg0_rx(ZM_LV_0, "Rx PsPoll"); + zfApProcessPsPoll(dev, buf); + zfwBufFree(dev, buf, 0); + } + else + { + zm_msg0_rx(ZM_LV_1, "Rx discard!!"); + wd->commTally.DriverDiscardedFrm++; + + zfwBufFree(dev, buf, 0); + } + return; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfWlanRxValidate */ +/* Validate Rx frame. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : received 802.11 frame buffer. */ +/* */ +/* OUTPUTS */ +/* Error code */ +/* */ +/* AUTHOR */ +/* Stephen ZyDAS Technology Corporation 2005.10 */ +/* */ +/************************************************************************/ +u16_t zfWlanRxValidate(zdev_t* dev, zbuf_t* buf) +{ + u16_t frameType; + u16_t frameCtrl; + u16_t frameLen; + u16_t ret; + u8_t frameSubType; + + zmw_get_wlan_dev(dev); + + frameCtrl = zmw_rx_buf_readh(dev, buf, 0); + frameType = frameCtrl & 0xC; + frameSubType = (frameCtrl & 0xF0) >> 4; + + frameLen = zfwBufGetSize(dev, buf); + + /* Accept Data/Management frame with protocol version = 0 */ + if ((frameType == 0x8) || (frameType == 0x0)) + { + + /* TODO : check rx status => erro bit */ + + /* Check Minimum Length with Wep */ + if ((frameCtrl & 0x4000) != 0) + { + /* Minimum Length = */ + /* PLCP(5)+Header(24)+IV(4)+ICV(4)+CRC(4)+RxStatus(8) */ + if (frameLen < 32) + { + return ZM_ERR_MIN_RX_ENCRYPT_FRAME_LENGTH; + } + } + else if ( frameSubType == 0x5 || frameSubType == 0x8 ) + { + /* Minimum Length = PLCP(5)+MACHeader(24)+Timestamp(8)+BeaconInterval(2)+Cap(2)+CRC(4)+RxStatus(8) */ + if (frameLen < 36) + { + return ZM_ERR_MIN_RX_FRAME_LENGTH; + } + } + else + { + /* Minimum Length = PLCP(5)+MACHeader(24)+CRC(4)+RxStatus(8) */ + if (frameLen < 24) + { + return ZM_ERR_MIN_RX_FRAME_LENGTH; + } + } + + /* Check if frame Length > ZM_WLAN_MAX_RX_SIZE. */ + if (frameLen > ZM_WLAN_MAX_RX_SIZE) + { + return ZM_ERR_MAX_RX_FRAME_LENGTH; + } + } + else if ((frameCtrl&0xff) == 0xa4) + { + /* PsPoll */ + //zm_msg0_rx(ZM_LV_0, "rx pspoll"); + } + else if ((frameCtrl&0xff) == ZM_WLAN_FRAME_TYPE_BAR) + { + if (wd->sta.enableDrvBA == 1) + { + zfAggRecvBAR(dev, buf); + } + + return ZM_ERR_RX_BAR_FRAME; + } + else + { + return ZM_ERR_RX_FRAME_TYPE; + } + + if ( wd->wlanMode == ZM_MODE_AP ) + { + } + else if ( wd->wlanMode != ZM_MODE_PSEUDO ) + { + if ( (ret=zfStaRxValidateFrame(dev, buf))!=ZM_SUCCESS ) + { + //zm_debug_msg1("discard frame, code = ", ret); + return ret; + } + } + + return ZM_SUCCESS; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfWlanRxFilter */ +/* Filter duplicated frame. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : received 802.11 frame buffer. */ +/* */ +/* OUTPUTS */ +/* Error code */ +/* */ +/* AUTHOR */ +/* Stephen ZyDAS Technology Corporation 2005.10 */ +/* */ +/************************************************************************/ +u16_t zfWlanRxFilter(zdev_t* dev, zbuf_t* buf) +{ + u16_t src[3]; + u16_t dst0; + u16_t frameType; + u16_t seq; + u16_t offset; + u16_t index; + u16_t col; + u16_t i; + u8_t up = 0; /* User priority */ + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + ZM_BUFFER_TRACE(dev, buf) + + /* RX PREFIX */ + offset = 0; + + frameType = zmw_rx_buf_readh(dev, buf, offset); + + // Don't divide 2^4 because we don't want the fragementation pkt to be treated as + // duplicated frames + seq = zmw_rx_buf_readh(dev, buf, offset+22); + dst0 = zmw_rx_buf_readh(dev, buf, offset+4); + src[0] = zmw_rx_buf_readh(dev, buf, offset+10); + src[1] = zmw_rx_buf_readh(dev, buf, offset+12); + src[2] = zmw_rx_buf_readh(dev, buf, offset+14); + + /* QoS data frame */ + if ((frameType & 0x88) == 0x88) + { + up = zmw_rx_buf_readb(dev, buf, offset+24); + up &= 0x7; + } + + index = (src[2]+up) & (ZM_FILTER_TABLE_ROW-1); + + /* TBD : filter frame with source address == own MAC adress */ + if ((wd->macAddr[0] == src[0]) && (wd->macAddr[1] == src[1]) + && (wd->macAddr[2] == src[2])) + { + //zm_msg0_rx(ZM_LV_0, "Rx filter=>src is own MAC"); + wd->trafTally.rxSrcIsOwnMac++; +#if 0 + return ZM_ERR_RX_SRC_ADDR_IS_OWN_MAC; +#endif + } + + zm_msg2_rx(ZM_LV_2, "Rx seq=", seq); + + /* Filter unicast frame only */ + if ((dst0 & 0x1) == 0) + { + zmw_enter_critical_section(dev); + + for(i=0; irxFilterTbl[i][index].addr[0] == src[0]) + && (wd->rxFilterTbl[i][index].addr[1] == src[1]) + && (wd->rxFilterTbl[i][index].addr[2] == src[2]) + && (wd->rxFilterTbl[i][index].up == up)) + { + if (((frameType&0x800)==0x800) + &&(wd->rxFilterTbl[i][index].seq==seq)) + { + zmw_leave_critical_section(dev); + /* hit : duplicated frame */ + zm_msg0_rx(ZM_LV_1, "Rx filter hit=>duplicated"); + wd->trafTally.rxDuplicate++; + return ZM_ERR_RX_DUPLICATE; + } + else + { + /* hit : not duplicated frame, update sequence number */ + wd->rxFilterTbl[i][index].seq = seq; + zmw_leave_critical_section(dev); + zm_msg0_rx(ZM_LV_2, "Rx filter hit"); + return ZM_SUCCESS; + } + } + } /* for(i=0; itick & (ZM_FILTER_TABLE_COL-1)); + wd->rxFilterTbl[col][index].addr[0] = src[0]; + wd->rxFilterTbl[col][index].addr[1] = src[1]; + wd->rxFilterTbl[col][index].addr[2] = src[2]; + wd->rxFilterTbl[col][index].seq = seq; + wd->rxFilterTbl[col][index].up = up; + + zmw_leave_critical_section(dev); + } /* if ((dst0 & 0x1) == 0) */ + + return ZM_SUCCESS; +} + + + +u16_t zfTxGenWlanTail(zdev_t* dev, zbuf_t* buf, u16_t* snap, u16_t snaplen, + u16_t* mic) +{ + struct zsMicVar* pMicKey; + u16_t i, length, payloadOffset; + u8_t bValue, qosType = 0; + u8_t snapByte[12]; + + zmw_get_wlan_dev(dev); + + if ( wd->wlanMode == ZM_MODE_AP ) + { + pMicKey = zfApGetTxMicKey(dev, buf, &qosType); + + if ( pMicKey == NULL ) + { + return 0; + } + } + else if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) + { + pMicKey = zfStaGetTxMicKey(dev, buf); + + if ( pMicKey == NULL ) + { + return 0; + } + } + else + { + return 0; + } + + length = zfwBufGetSize(dev, buf); + + zfMicClear(pMicKey); + + /* append DA and SA */ +#ifdef ZM_ENABLE_NATIVE_WIFI + for(i=16; i<22; i++) + { // VISTA DA + bValue = zmw_tx_buf_readb(dev, buf, i); + zfMicAppendByte(bValue, pMicKey); + } + for(i=10; i<16; i++) + { // VISTA SA + bValue = zmw_tx_buf_readb(dev, buf, i); + zfMicAppendByte(bValue, pMicKey); + } +#else + for(i=0; i<12; i++) + { + bValue = zmw_tx_buf_readb(dev, buf, i); + zfMicAppendByte(bValue, pMicKey); + } +#endif + + /* append for alignment */ + if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) + { + if (wd->sta.wmeConnected != 0) + zfMicAppendByte(zmw_tx_buf_readb(dev, buf, ZM_80211_FRAME_IP_OFFSET + 1) >> 5, pMicKey); + else + zfMicAppendByte(0, pMicKey); + } + else if ( wd->wlanMode == ZM_MODE_AP ) + { + if (qosType == 1) + zfMicAppendByte(zmw_tx_buf_readb(dev, buf, ZM_80211_FRAME_IP_OFFSET + 1) >> 5, pMicKey); + else + zfMicAppendByte(0, pMicKey); + } + else + { + /* TODO : Qos Software MIC in IBSS Mode */ + zfMicAppendByte(0, pMicKey); + } + zfMicAppendByte(0, pMicKey); + zfMicAppendByte(0, pMicKey); + zfMicAppendByte(0, pMicKey); + + if ( snaplen == 0 ) + { + payloadOffset = ZM_80211_FRAME_IP_OFFSET; + } + else + { + payloadOffset = ZM_80211_FRAME_TYPE_OFFSET; + + for(i=0; i<(snaplen>>1); i++) + { + snapByte[i*2] = (u8_t) (snap[i] & 0xff); + snapByte[i*2+1] = (u8_t) ((snap[i] >> 8) & 0xff); + } + + for(i=0; i= 34) //Minimum IPv4 packet size, 14(Ether header)+20(IPv4 header) + { + etherType = (((u16_t)zmw_tx_buf_readb(dev, buf, ZM_80211_FRAME_TYPE_OFFSET))<<8) + + zmw_tx_buf_readb(dev, buf, ZM_80211_FRAME_TYPE_OFFSET + 1); + + /* protocol type = IP */ + if (etherType == 0x0800) + { + ipv = zmw_tx_buf_readb(dev, buf, ZM_80211_FRAME_IP_OFFSET) >> 4; + if (ipv == 0x4) //IPv4 + { + tos = zmw_tx_buf_readb(dev, buf, ZM_80211_FRAME_IP_OFFSET + 1); + *up = (tos >> 5); + *fragOff = zmw_tx_buf_readh(dev, buf, ZM_80211_FRAME_IP_OFFSET + 6); + } + /* TODO : handle VLAN tag and IPv6 packet */ + } + } + return; +} + +#ifdef ZM_ENABLE_NATIVE_WIFI +u16_t zfTxGenWlanSnap(zdev_t* dev, zbuf_t* buf, u16_t* snap, u16_t* snaplen) +{ + snap[0] = zmw_buf_readh(dev, buf, ZM_80211_FRAME_HEADER_LEN + 0); + snap[1] = zmw_buf_readh(dev, buf, ZM_80211_FRAME_HEADER_LEN + 2); + snap[2] = zmw_buf_readh(dev, buf, ZM_80211_FRAME_HEADER_LEN + 4); + *snaplen = 6; + + return ZM_80211_FRAME_HEADER_LEN + *snaplen; +} +#else +u16_t zfTxGenWlanSnap(zdev_t* dev, zbuf_t* buf, u16_t* snap, u16_t* snaplen) +{ + u16_t removed; + u16_t etherType; + u16_t len; + + len = zfwBufGetSize(dev, buf); + if (len < 14) //Minimum Ethernet packet size, 14(Ether header) + { + /* TODO : Assert? */ + *snaplen = 0; + return 0; + } + + /* Generate RFC1042 header */ + etherType = (((u16_t)zmw_tx_buf_readb(dev, buf, 12))<<8) + + zmw_tx_buf_readb(dev, buf, 13); + + //zm_debug_msg2("ethernet type or length = ", etherType); + + if (etherType > 1500) + { + /* ETHERNET format */ + removed = 12; + snap[0] = 0xaaaa; + snap[1] = 0x0003; + if ((etherType ==0x8137) || (etherType == 0x80f3)) + { + /* Bridge Tunnel */ + snap[2] = 0xF800; + } + else + { + /* RFC 1042 */ + snap[2] = 0x0000; + } + *snaplen = 6; + + if ( etherType == 0x888E ) + { + zfShowTxEAPOL(dev, buf, 14); + } + } + else + { + /* 802.3 format */ + removed = 14; + *snaplen = 0; + } + + return removed; +} +#endif + +u8_t zfIsVtxqEmpty(zdev_t* dev) +{ + u8_t isEmpty = TRUE; + u8_t i; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + if (wd->vmmqHead != wd->vmmqTail) + { + isEmpty = FALSE; + goto check_done; + } + + for(i=0; i < 4; i++) + { + if (wd->vtxqHead[i] != wd->vtxqTail[i]) + { + isEmpty = FALSE; + goto check_done; + } + } + +check_done: + zmw_leave_critical_section(dev); + return isEmpty; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfPutVtxq */ +/* Put Tx buffer to virtual TxQ */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : Tx buffer pointer */ +/* */ +/* OUTPUTS */ +/* ZM_SUCCESS or error code */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2006.6 */ +/* */ +/************************************************************************/ +u16_t zfPutVtxq(zdev_t* dev, zbuf_t* buf) +{ + u8_t ac; + u8_t up; + u16_t fragOff; +#ifdef ZM_AGG_TALLY + struct aggTally *agg_tal; +#endif +#ifdef ZM_ENABLE_AGGREGATION + #ifndef ZM_BYPASS_AGGR_SCHEDULING + u16_t ret; + u16_t tid; + #endif +#endif + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff); + + if ( wd->zfcbClassifyTxPacket != NULL ) + { + ac = wd->zfcbClassifyTxPacket(dev, buf); + } + else + { + ac = zcUpToAc[up&0x7] & 0x3; + } + + /* + * add by honda + * main A-MPDU aggregation function + */ +#ifdef ZM_AGG_TALLY + agg_tal = &wd->agg_tal; + agg_tal->got_packets_sum++; + +#endif + +#ifdef ZM_ENABLE_AGGREGATION + #ifndef ZM_BYPASS_AGGR_SCHEDULING + tid = up&0x7; + if(wd->enableAggregation==0) + { + if( (wd->wlanMode == ZM_MODE_AP) || + (wd->wlanMode == ZM_MODE_INFRASTRUCTURE && wd->sta.EnableHT) || + (wd->wlanMode == ZM_MODE_PSEUDO) ) { + // (infrastructure_mode && connect_to_11n_ap) || (ap_mode && is_11n_ap) + //ret = zfAggPutVtxq(dev, buf); + + + ret = zfAggTx(dev, buf, tid); + if (ZM_SUCCESS == ret) + { + //zfwBufFree(dev, buf, ZM_SUCCESS); + + return ZM_SUCCESS; + } + if (ZM_ERR_EXCEED_PRIORITY_THRESHOLD == ret) + { + wd->commTally.txQosDropCount[ac]++; + zfwBufFree(dev, buf, ZM_SUCCESS); + + zm_msg1_tx(ZM_LV_1, "Packet discarded, VTXQ full, ac=", ac); + + return ZM_ERR_EXCEED_PRIORITY_THRESHOLD; + } + if (ZM_ERR_TX_BUFFER_UNAVAILABLE == ret) + { + /* + * do nothing + * continue following procession, put into VTXQ + * return ZM_SUCCESS; + */ + } + } + } + #endif +#endif + /* + * end of add by honda + */ + + /* First Ip frag */ + if ((fragOff & 0xff3f) == 0x0020) + { + /* Don't let ip frag in if VTXQ unable to hold */ + /* whole ip frag burst(assume 20 frag) */ + zmw_enter_critical_section(dev); + if (((wd->vtxqHead[ac] - wd->vtxqTail[ac])& ZM_VTXQ_SIZE_MASK) + > (ZM_VTXQ_SIZE-20)) + { + wd->qosDropIpFrag[ac] = 1; + } + else + { + wd->qosDropIpFrag[ac] = 0; + } + zmw_leave_critical_section(dev); + + if (wd->qosDropIpFrag[ac] == 1) + { + //zm_debug_msg2("vtQ full, drop buf = ", buf); + wd->commTally.txQosDropCount[ac]++; + zfwBufFree(dev, buf, ZM_SUCCESS); + zm_msg1_tx(ZM_LV_1, "Packet discarded, first ip frag, ac=", ac); + //VTXQ[] can not hold whold ip frag burst(assume 20 frags) + return ZM_ERR_EXCEED_PRIORITY_THRESHOLD; + } + } + else if ((fragOff & 0xff3f) == 0) + { + wd->qosDropIpFrag[ac] = 0; + } + + if (((fragOff &= 0xff1f) != 0) && (wd->qosDropIpFrag[ac] == 1)) + { + wd->commTally.txQosDropCount[ac]++; + zfwBufFree(dev, buf, ZM_SUCCESS); + zm_msg1_tx(ZM_LV_1, "Packet discarded, ip frag, ac=", ac); + //Discard following ip frags + return ZM_ERR_EXCEED_PRIORITY_THRESHOLD; + } + + zmw_enter_critical_section(dev); + if (((wd->vtxqHead[ac] + 1) & ZM_VTXQ_SIZE_MASK) != wd->vtxqTail[ac]) + { + wd->vtxq[ac][wd->vtxqHead[ac]] = buf; + wd->vtxqHead[ac] = ((wd->vtxqHead[ac] + 1) & ZM_VTXQ_SIZE_MASK); + zmw_leave_critical_section(dev); + return ZM_SUCCESS; + } + else + { + zmw_leave_critical_section(dev); + + wd->commTally.txQosDropCount[ac]++; + zfwBufFree(dev, buf, ZM_SUCCESS); + zm_msg1_tx(ZM_LV_1, "Packet discarded, VTXQ full, ac=", ac); + return ZM_ERR_EXCEED_PRIORITY_THRESHOLD; //VTXQ[] Full + } +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfGetVtxq */ +/* Get Tx buffer from virtual TxQ */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* Tx buffer pointer */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2006.6 */ +/* */ +/************************************************************************/ +zbuf_t* zfGetVtxq(zdev_t* dev, u8_t ac) +{ + zbuf_t* buf; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + ac &= 0x3; + zmw_enter_critical_section(dev); + if (wd->vtxqHead[ac] != wd->vtxqTail[ac]) + { + buf = wd->vtxq[ac][wd->vtxqTail[ac]]; + wd->vtxqTail[ac] = ((wd->vtxqTail[ac] + 1) & ZM_VTXQ_SIZE_MASK); + zmw_leave_critical_section(dev); + return buf; + } + else + { + zmw_leave_critical_section(dev); + return 0; //VTXQ[] empty + } +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfPutVmmq */ +/* Put Tx buffer to virtual MmQ */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : Tx buffer pointer */ +/* */ +/* OUTPUTS */ +/* ZM_SUCCESS or error code */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2006.12 */ +/* */ +/************************************************************************/ +u16_t zfPutVmmq(zdev_t* dev, zbuf_t* buf) +{ + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + if (((wd->vmmqHead + 1) & ZM_VMMQ_SIZE_MASK) != wd->vmmqTail) + { + wd->vmmq[wd->vmmqHead] = buf; + wd->vmmqHead = ((wd->vmmqHead + 1) & ZM_VMMQ_SIZE_MASK); + zmw_leave_critical_section(dev); + return ZM_SUCCESS; + } + else + { + zmw_leave_critical_section(dev); + + zfwBufFree(dev, buf, ZM_SUCCESS); + zm_msg0_mm(ZM_LV_0, "Packet discarded, VMmQ full"); + return ZM_ERR_VMMQ_FULL; //VTXQ[] Full + } +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfGetVmmq */ +/* Get Tx buffer from virtual MmQ */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* Tx buffer pointer */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2006.12 */ +/* */ +/************************************************************************/ +zbuf_t* zfGetVmmq(zdev_t* dev) +{ + zbuf_t* buf; + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + if (wd->vmmqHead != wd->vmmqTail) + { + buf = wd->vmmq[wd->vmmqTail]; + wd->vmmqTail = ((wd->vmmqTail + 1) & ZM_VMMQ_SIZE_MASK); + zmw_leave_critical_section(dev); + return buf; + } + else + { + zmw_leave_critical_section(dev); + return 0; //VTXQ[] empty + } +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfPushVtxq */ +/* Service Virtual TxQ (weighted round robin) */ +/* Get Tx buffer form virtual TxQ and put to hardware TxD queue */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2006.6 */ +/* */ +/************************************************************************/ +void zfPushVtxq(zdev_t* dev) +{ + zbuf_t* buf; + u16_t i; + u16_t txed; + u32_t freeTxd; + u16_t err; + u16_t skipFlag = 0; + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + + + //zm_debug_msg1("zfHpGetFreeTxdCount = ", zfHpGetFreeTxdCount(dev)); + + if (wd->halState == ZM_HAL_STATE_INIT) + { + if (!wd->modeMDKEnable) + { + zm_debug_msg0("HAL is not ready for Tx"); + } + return; + } + else if (wd->sta.DFSDisableTx) + { + zm_debug_msg0("return because 802.11h DFS Disable Tx"); + return; + } + else if (wd->sta.flagFreqChanging != 0) + { + //Hold until RF frequency changed + return; + } + else if (( wd->sta.flagKeyChanging ) && ( wd->wlanMode != ZM_MODE_AP )) + { + return; + } +#ifdef ZM_ENABLE_POWER_SAVE + else if ( zfPowerSavingMgrIsSleeping(dev) ) + { + //zm_debug_msg0("Packets queued since the MAC is in power-saving mode\n"); + return; + } +#endif + + zmw_enter_critical_section(dev); + if (wd->vtxqPushing != 0) + { + skipFlag = 1; + } + else + { + wd->vtxqPushing = 1; + } + zmw_leave_critical_section(dev); + + if (skipFlag == 1) + { + return; + } + + while (1) + { + txed = 0; + + /* 2006.12.20, Serve Management queue */ + while( zfHpGetFreeTxdCount(dev) > 0 ) + { + if ((buf = zfGetVmmq(dev)) != 0) + { + txed = 1; + //zm_debug_msg2("send buf = ", buf); + if ((err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0, + ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS) + { + zfwBufFree(dev, buf, 0); + } + } + else + { + break; + } + } + if ((wd->sta.bScheduleScan) || ((wd->sta.bChannelScan == TRUE) && (zfStaIsConnected(dev)))) + { + //Hold until Scan Stop + wd->vtxqPushing = 0; + return; + } + +#ifdef ZM_ENABLE_AGGREGATION + #ifndef ZM_BYPASS_AGGR_SCHEDULING + if( (wd->wlanMode == ZM_MODE_AP) || + (wd->wlanMode == ZM_MODE_INFRASTRUCTURE && wd->sta.EnableHT) || + (wd->wlanMode == ZM_MODE_PSEUDO) ) { + + zfAggTxScheduler(dev, 0); + + if (txed == 0) { + wd->vtxqPushing = 0; + return; + } + else { + continue; + } + } + #endif +#endif + + /* Service VTxQ[3] */ + for (i=0; i<4; i++) + { + if ((freeTxd = zfHpGetFreeTxdCount(dev)) >= 3) + { + if ((buf = zfGetVtxq(dev, 3)) != 0) + { + txed = 1; + //zm_debug_msg2("send buf = ", buf); + zfTxSendEth(dev, buf, 0, ZM_EXTERNAL_ALLOC_BUF, 0); + ZM_PERFORMANCE_TX_MPDU(dev, wd->tick); + } + } + else + { + break; + } + } + + /* Service VTxQ[2] */ + for (i=0; i<3; i++) + { + if ((freeTxd = zfHpGetFreeTxdCount(dev)) >= (zfHpGetMaxTxdCount(dev)*1/4)) + { + if ((buf = zfGetVtxq(dev, 2)) != 0) + { + txed = 1; + zfTxSendEth(dev, buf, 0, ZM_EXTERNAL_ALLOC_BUF, 0); + ZM_PERFORMANCE_TX_MPDU(dev, wd->tick); + } + if (wd->sta.ac0PriorityHigherThanAc2 == 1) + { + if ((buf = zfGetVtxq(dev, 0)) != 0) + { + txed = 1; + zfTxSendEth(dev, buf, 0, ZM_EXTERNAL_ALLOC_BUF, 0); + ZM_PERFORMANCE_TX_MPDU(dev, wd->tick); + } + } + } + else + { + break; + } + } + + /* Service VTxQ[0] */ + for (i=0; i<2; i++) + { + if ((freeTxd = zfHpGetFreeTxdCount(dev)) >= (zfHpGetMaxTxdCount(dev)*2/4)) + { + if ((buf = zfGetVtxq(dev, 0)) != 0) + { + txed = 1; + zfTxSendEth(dev, buf, 0, ZM_EXTERNAL_ALLOC_BUF, 0); + ZM_PERFORMANCE_TX_MPDU(dev, wd->tick); + } + } + else + { + break; + } + + } + + /* Service VTxQ[1] */ + if ((freeTxd = zfHpGetFreeTxdCount(dev)) >= (zfHpGetMaxTxdCount(dev)*3/4)) + { + if ((buf = zfGetVtxq(dev, 1)) != 0) + { + txed = 1; + zfTxSendEth(dev, buf, 0, ZM_EXTERNAL_ALLOC_BUF, 0); + ZM_PERFORMANCE_TX_MPDU(dev, wd->tick); + } + } + + /* All VTxQs are either empty or exceed their threshold */ + if (txed == 0) + { + wd->vtxqPushing = 0; + return; + } + } //while (1) +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfFlushVtxq */ +/* Flush Virtual TxQ and MmQ */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Stephen Chen Atheros Communications, INC. 2007.1 */ +/* */ +/************************************************************************/ +void zfFlushVtxq(zdev_t* dev) +{ + zbuf_t* buf; + u8_t i; + zmw_get_wlan_dev(dev); + + /* Flush MmQ */ + while ((buf = zfGetVmmq(dev)) != 0) + { + zfwBufFree(dev, buf, 0); + zm_debug_msg0("zfFlushVtxq: [Vmmq]"); + wd->queueFlushed |= 0x10; + } + + /* Flush VTxQ */ + for (i=0; i<4; i++) + { + while ((buf = zfGetVtxq(dev, i)) != 0) + { + zfwBufFree(dev, buf, 0); + zm_debug_msg1("zfFlushVtxq: [zfGetVtxq]- ", i); + wd->queueFlushed |= (1<commTally.txUnicastFrm++; + wd->commTally.txUnicastOctets += (fragLen+snapLen); + } + else if (da[0] == 0xffff) + { + wd->commTally.txBroadcastFrm++; + wd->commTally.txBroadcastOctets += (fragLen+snapLen); + } + else + { + wd->commTally.txMulticastFrm++; + wd->commTally.txMulticastOctets += (fragLen+snapLen); + } + wd->ledStruct.txTraffic++; + + if ((err = zfHpSend(dev, header, headerLen, snap, snapLen, + tail, tailLen, buf, offset, + bufType, ac, keyIdx)) != ZM_SUCCESS) + { + if (bufType == ZM_EXTERNAL_ALLOC_BUF) + { + zfwBufFree(dev, buf, err); + } + else if (bufType == ZM_INTERNAL_ALLOC_BUF) + { + zfwBufFree(dev, buf, 0); + } + else + { + zm_assert(0); + } + } +} + +void zfCheckIsRIFSFrame(zdev_t* dev, zbuf_t* buf, u16_t frameSubtype) +{ + zmw_get_wlan_dev(dev); + + /* #2 Record the sequence number to determine whether the unicast frame is separated by RIFS or not */ + if (frameSubtype & 0x80) + { //QoS data frame + u16_t sequenceNum; + u16_t qosControlField; + + sequenceNum = ( zmw_buf_readh(dev, buf, 22) >> 4 ); // Discard fragment number ! + qosControlField = zmw_buf_readh(dev, buf, 24); // Don't consider WDS (Wireless Distribution System) + //DbgPrint("The QoS Control Field : %d", qosControlField); + //DbgPrint("The RIFS Count : %d", wd->sta.rifsCount); + + if( qosControlField & ZM_BIT_5 ) + {// ACK policy is "No ACK" + /* RIFS-Like frame */ + wd->sta.rifsLikeFrameSequence[wd->sta.rifsLikeFrameCnt] = sequenceNum; + + if( wd->sta.rifsState == ZM_RIFS_STATE_DETECTING ) + { + if( wd->sta.rifsLikeFrameSequence[2] != 0 ) + {// RIFS-like Pattern collected + if( ( wd->sta.rifsLikeFrameSequence[2] - wd->sta.rifsLikeFrameSequence[1] == 2 ) && + ( wd->sta.rifsLikeFrameSequence[1] - wd->sta.rifsLikeFrameSequence[0] == 2 ) ) + { + /* RIFS pattern matched */ + + /* #3 Enable RIFS function if the RIFS pattern matched */ + zfHpEnableRifs(dev, ((wd->sta.currentFrequency<3000)?1:0), wd->sta.EnableHT, wd->sta.HT2040); + + // Set RIFS timer + wd->sta.rifsTimer = wd->tick; + + wd->sta.rifsCount++; + + // Set state to be Detected + wd->sta.rifsState = ZM_RIFS_STATE_DETECTED; + } + } + } + else + {// state = Detected + // Reset RIFS timer + if( (wd->tick - wd->sta.rifsTimer) < ZM_RIFS_TIMER_TIMEOUT ) + wd->sta.rifsTimer = wd->tick; + } + + //DbgPrint("SN1 = %d, SN2 = %d, SN3 = %d\n", wd->sta.rifsLikeFrameSequence[0], + // wd->sta.rifsLikeFrameSequence[1], + // wd->sta.rifsLikeFrameSequence[2]); + + // Update RIFS-like sequence number + if( wd->sta.rifsLikeFrameSequence[2] != 0 ) + { + wd->sta.rifsLikeFrameSequence[0] = wd->sta.rifsLikeFrameSequence[1]; + wd->sta.rifsLikeFrameSequence[1] = wd->sta.rifsLikeFrameSequence[2]; + wd->sta.rifsLikeFrameSequence[2] = 0; + } + + // Only record three adjacent frame + if( wd->sta.rifsLikeFrameCnt < 2 ) + wd->sta.rifsLikeFrameCnt++; + } + } + + /* #4 Disable RIFS function if the timer TIMEOUT */ + if( wd->sta.rifsState == ZM_RIFS_STATE_DETECTED ) + { + if( ( wd->tick - wd->sta.rifsTimer ) > ZM_RIFS_TIMER_TIMEOUT ) + {// TIMEOUT + // Disable RIFS + zfHpDisableRifs(dev); + + // Reset RIFS-like sequence number FIFO + wd->sta.rifsLikeFrameSequence[0] = 0; + wd->sta.rifsLikeFrameSequence[1] = 0; + wd->sta.rifsLikeFrameSequence[2] = 0; + wd->sta.rifsLikeFrameCnt = 0; + + // Set state to be Detecting + wd->sta.rifsState = ZM_RIFS_STATE_DETECTING; + } + } +} --- linux-2.6.28.orig/drivers/staging/otus/80211core/ratectrl.h +++ linux-2.6.28/drivers/staging/otus/80211core/ratectrl.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _RATECTRL_H +#define _RATECTRL_H + +#define ZM_RATE_CTRL_PROBING_INTERVAL_MS 1000 //1000ms +#define ZM_RATE_CTRL_MIN_PROBING_PACKET 8 + +#define ZM_MIN_RATE_FAIL_COUNT 20 + +#define ZM_RATE_PROBING_THRESHOLD 15 //6% +#define ZM_RATE_SUCCESS_PROBING 10 + +#define ZM_RATE_CTRL_RSSI_VARIATION 5 //TBD + +extern const u32_t zcRateToPhyCtrl[]; + +extern void zfRateCtrlInitCell(zdev_t* dev, struct zsRcCell* rcCell, u8_t type, u8_t gBand, u8_t SG40); +extern u16_t zfRateCtrlGetTxRate(zdev_t* dev, struct zsRcCell* rcCell, u16_t* probing); +extern void zfRateCtrlTxFailEvent(zdev_t* dev, struct zsRcCell* rcCell, u8_t aggRate, u32_t retryRate); +extern void zfRateCtrlTxSuccessEvent(zdev_t* dev, struct zsRcCell* rcCell, u8_t successRate); +extern void zfRateCtrlAggrSta(zdev_t* dev); +#endif --- linux-2.6.28.orig/drivers/staging/otus/80211core/cagg.c +++ linux-2.6.28/drivers/staging/otus/80211core/cagg.c @@ -0,0 +1,3611 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* */ +/* Module Name : cagg.c */ +/* */ +/* Abstract */ +/* This module contains A-MPDU aggregation related functions. */ +/* */ +/* NOTES */ +/* None */ +/* */ +/************************************************************************/ + +#include "cprecomp.h" + +extern u8_t zcUpToAc[8]; +const u8_t pri[] = {3,3,2,3,2,1,3,2,1,0}; + + +u16_t aggr_count; +u32_t success_mpdu; +u32_t total_mpdu; + +void zfAggInit(zdev_t* dev) +{ + u16_t i,j; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + /* + * reset sta information + */ + + zmw_enter_critical_section(dev); + wd->aggInitiated = 0; + wd->addbaComplete = 0; + wd->addbaCount = 0; + wd->reorder = 1; + for (i=0; iaggSta[i].aggQNumber[j] = ZM_AGG_POOL_SIZE; + wd->aggSta[i].aggFlag[j] = wd->aggSta[i].count[j] = 0; + wd->aggSta[i].tid_tx[j] = NULL; + wd->aggSta[i].tid_tx[j+1] = NULL; + + } + } + + /* + * reset Tx/Rx aggregation queue information + */ + wd->aggState = 0; + for (i=0; iaggQPool[i] = zfwMemAllocate(dev, sizeof(struct aggQueue)); + if(!wd->aggQPool[i]) + { + zmw_leave_critical_section(dev); + return; + } + wd->aggQPool[i]->aggHead = wd->aggQPool[i]->aggTail = + wd->aggQPool[i]->aggQEnabled = wd->aggQPool[i]->aggReady = + wd->aggQPool[i]->clearFlag = wd->aggQPool[i]->deleteFlag = 0; + //wd->aggQPool[i]->aggSize = 16; + + /* + * reset rx aggregation queue + */ + wd->tid_rx[i] = zfwMemAllocate(dev, sizeof(struct agg_tid_rx)); + if (!wd->tid_rx[i]) + { + zmw_leave_critical_section(dev); + return; + } + wd->tid_rx[i]->aid = ZM_MAX_STA_SUPPORT; + wd->tid_rx[i]->seq_start = wd->tid_rx[i]->baw_head = \ + wd->tid_rx[i]->baw_tail = 0; + wd->tid_rx[i]->sq_exceed_count = wd->tid_rx[i]->sq_behind_count = 0; + for (j=0; j<=ZM_AGG_BAW_SIZE; j++) + wd->tid_rx[i]->frame[j].buf = 0; + /* + * reset ADDBA exchange status code + * 0: NULL + * 1: ADDBA Request sent/received + * 2: ACK for ADDBA Request sent/received + * 3: ADDBA Response sent/received + * 4: ACK for ADDBA Response sent/received + */ + wd->tid_rx[i]->addBaExchangeStatusCode = 0; + + } + zmw_leave_critical_section(dev); + zfAggTallyReset(dev); + DESTQ.init = zfAggDestInit; + DESTQ.init(dev); + wd->aggInitiated = 1; + aggr_count = 0; + success_mpdu = 0; + total_mpdu = 0; +#ifdef ZM_ENABLE_AGGREGATION +#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW + BAW = zfwMemAllocate(dev, sizeof(struct baw_enabler)); + if(!BAW) + { + return; + } + BAW->init = zfBawInit; + BAW->init(dev); +#endif //disable BAW +#endif +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfAggGetSta */ +/* return STA AID. */ +/* take buf as input, use the dest address of buf as index to */ +/* search STA AID. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : buffer for one particular packet */ +/* */ +/* OUTPUTS */ +/* AID */ +/* */ +/* AUTHOR */ +/* Honda ZyDAS Technology Corporation 2006.11 */ +/* */ +/************************************************************************/ + + + +u16_t zfAggGetSta(zdev_t* dev, zbuf_t* buf) +{ + u16_t id; + u16_t dst[3]; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + dst[0] = zmw_rx_buf_readh(dev, buf, 0); + dst[1] = zmw_rx_buf_readh(dev, buf, 2); + dst[2] = zmw_rx_buf_readh(dev, buf, 4); + + zmw_enter_critical_section(dev); + + if(wd->wlanMode == ZM_MODE_AP) { + id = zfApFindSta(dev, dst); + } + else { + id = 0; + } + zmw_leave_critical_section(dev); + +#if ZM_AGG_FPGA_DEBUG + id = 0; +#endif + + return id; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfAggTxGetQueue */ +/* return Queue Pool index. */ +/* take aid as input, look for the queue index associated */ +/* with this aid. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* aid : associated id */ +/* */ +/* OUTPUTS */ +/* Queue number */ +/* */ +/* AUTHOR */ +/* Honda ZyDAS Technology Corporation 2006.11 */ +/* */ +/************************************************************************/ +TID_TX zfAggTxGetQueue(zdev_t* dev, u16_t aid, u16_t tid) +{ + //u16_t i; + TID_TX tid_tx; + zmw_get_wlan_dev(dev); + + //zmw_declare_for_critical_section(); + + /* + * not a STA aid + */ + if (0xffff == aid) + return NULL; + + //zmw_enter_critical_section(dev); + + tid_tx = wd->aggSta[aid].tid_tx[tid]; + if (!tid_tx) return NULL; + if (0 == tid_tx->aggQEnabled) + return NULL; + + //zmw_leave_critical_section(dev); + + return tid_tx; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfAggTxNewQueue */ +/* return Queue Pool index. */ +/* take aid as input, find a new queue for this aid. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* aid : associated id */ +/* */ +/* OUTPUTS */ +/* Queue number */ +/* */ +/* AUTHOR */ +/* Honda ZyDAS Technology Corporation 2006.12 */ +/* */ +/************************************************************************/ +TID_TX zfAggTxNewQueue(zdev_t* dev, u16_t aid, u16_t tid, zbuf_t* buf) +{ + u16_t i; + TID_TX tid_tx=NULL; + u16_t ac = zcUpToAc[tid&0x7] & 0x3; + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + /* + * not a STA aid + */ + if (0xffff == aid) + return NULL; + + zmw_enter_critical_section(dev); + + /* + * find one new queue for sta + */ + for (i=0; iaggQPool[i]->aggQEnabled) + { + /* + * this q is enabled + */ + } + else + { + tid_tx = wd->aggQPool[i]; + tid_tx->aggQEnabled = 1; + tid_tx->aggQSTA = aid; + tid_tx->ac = ac; + tid_tx->tid = tid; + tid_tx->aggHead = tid_tx->aggTail = tid_tx->size = 0; + tid_tx->aggReady = 0; + wd->aggSta[aid].tid_tx[tid] = tid_tx; + tid_tx->dst[0] = zmw_rx_buf_readh(dev, buf, 0); + tid_tx->dst[1] = zmw_rx_buf_readh(dev, buf, 2); + tid_tx->dst[2] = zmw_rx_buf_readh(dev, buf, 4); + break; + } + } + + zmw_leave_critical_section(dev); + + return tid_tx; +} + + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfAggTxEnqueue */ +/* return Status code ZM_SUCCESS or error code */ +/* take (aid,ac,qnum,buf) as input */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* aid : associated id */ +/* ac : access category */ +/* qnum: the queue number to which will be enqueued */ +/* buf : the packet to be queued */ +/* */ +/* OUTPUTS */ +/* status code */ +/* */ +/* AUTHOR */ +/* Honda Atheros Communications, INC. 2006.12 */ +/* */ +/************************************************************************/ +u16_t zfAggTxEnqueue(zdev_t* dev, zbuf_t* buf, u16_t aid, TID_TX tid_tx) +{ + //u16_t qlen, frameLen; + u32_t time; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail); + + if (tid_tx->size < (ZM_AGGQ_SIZE - 2)) + { + /* Queue not full */ + + + /* + * buffer copy + * in zfwBufFree will return a ndismsendcomplete + * to resolve the synchronize problem in aggregate + */ + + u8_t sendComplete = 0; + + tid_tx->aggvtxq[tid_tx->aggHead].buf = buf; + time = zm_agg_GetTime(); + tid_tx->aggvtxq[tid_tx->aggHead].arrivalTime = time; + tid_tx->aggvtxq[tid_tx->aggHead].baw_retransmit = 0; + + tid_tx->aggHead = ((tid_tx->aggHead + 1) & ZM_AGGQ_SIZE_MASK); + tid_tx->lastArrival = time; + tid_tx->size++; + tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail); + if (buf && (tid_tx->size < (ZM_AGGQ_SIZE - 10))) { + tid_tx->complete = tid_tx->aggHead; + sendComplete = 1; + } + zmw_leave_critical_section(dev); + + if (!DESTQ.exist(dev, 0, tid_tx->ac, tid_tx, NULL)) { + DESTQ.insert(dev, 0, tid_tx->ac, tid_tx, NULL); + } + + zm_msg1_agg(ZM_LV_0, "tid_tx->size=", tid_tx->size); + //zm_debug_msg1("tid_tx->size=", tid_tx->size); + + if (buf && sendComplete && wd->zfcbSendCompleteIndication) { + //zmw_leave_critical_section(dev); + wd->zfcbSendCompleteIndication(dev, buf); + } + + /*if (tid_tx->size >= 16 && zfHpGetFreeTxdCount(dev) > 20) + zfAggTxSend(dev, zfHpGetFreeTxdCount(dev), tid_tx); + */ + return ZM_SUCCESS; + } + else + { + zm_msg1_agg(ZM_LV_0, "can't enqueue, tid_tx->size=", tid_tx->size); + /* + * Queue Full + */ + + /* + * zm_msg1_agg(ZM_LV_0, "Queue full, qnum = ", qnum); + * wd->commTally.txQosDropCount[ac]++; + * zfwBufFree(dev, buf, ZM_SUCCESS); + * zm_msg1_agg(ZM_LV_1, "Packet discarded, VTXQ full, ac=", ac); + * + * return ZM_ERR_EXCEED_PRIORITY_THRESHOLD; + */ + } + + zmw_leave_critical_section(dev); + + if (!DESTQ.exist(dev, 0, tid_tx->ac, tid_tx, NULL)) { + DESTQ.insert(dev, 0, tid_tx->ac, tid_tx, NULL); + } + + return ZM_ERR_EXCEED_PRIORITY_THRESHOLD; +} + +u16_t zfAggDestExist(zdev_t* dev, u16_t Qtype, u16_t ac, TID_TX tid_tx, void* vtxq) { + struct dest* dest; + u16_t exist = 0; + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + if (!DESTQ.Head[ac]) { + exist = 0; + } + else { + dest = DESTQ.Head[ac]; + if (dest->tid_tx == tid_tx) { + exist = 1; + } + else { + while (dest->next != DESTQ.Head[ac]) { + dest = dest->next; + if (dest->tid_tx == tid_tx){ + exist = 1; + break; + } + } + } + } + + zmw_leave_critical_section(dev); + + return exist; +} + +void zfAggDestInsert(zdev_t* dev, u16_t Qtype, u16_t ac, TID_TX tid_tx, void* vtxq) +{ + struct dest* new_dest; + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + new_dest = zfwMemAllocate(dev, sizeof(struct dest)); + if(!new_dest) + { + return; + } + new_dest->Qtype = Qtype; + new_dest->tid_tx = tid_tx; + if (0 == Qtype) + new_dest->tid_tx = tid_tx; + else + new_dest->vtxq = vtxq; + if (!DESTQ.Head[ac]) { + + zmw_enter_critical_section(dev); + new_dest->next = new_dest; + DESTQ.Head[ac] = DESTQ.dest[ac] = new_dest; + zmw_leave_critical_section(dev); + } + else { + + zmw_enter_critical_section(dev); + new_dest->next = DESTQ.dest[ac]->next; + DESTQ.dest[ac]->next = new_dest; + zmw_leave_critical_section(dev); + } + + + //DESTQ.size[ac]++; + return; +} + +void zfAggDestDelete(zdev_t* dev, u16_t Qtype, TID_TX tid_tx, void* vtxq) +{ + struct dest* dest, *temp; + u16_t i; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + if (wd->destLock) { + zmw_leave_critical_section(dev); + return; + } + + + //zmw_declare_for_critical_section(); + for (i=0; i<4; i++) { + if (!DESTQ.Head[i]) continue; + dest = DESTQ.Head[i]; + if (!dest) continue; + + + while (dest && (dest->next != DESTQ.Head[i])) { + if (Qtype == 0 && dest->next->tid_tx == tid_tx){ + break; + } + if (Qtype == 1 && dest->next->vtxq == vtxq) { + break; + } + dest = dest->next; + } + + if ((Qtype == 0 && dest->next->tid_tx == tid_tx) || (Qtype == 1 && dest->next->vtxq == vtxq)) { + + tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail); + if (tid_tx->size) { + zmw_leave_critical_section(dev); + return; + } + if (!DESTQ.Head[i]) { + temp = NULL; + } + else { + temp = dest->next; + if (temp == dest) { + DESTQ.Head[i] = DESTQ.dest[i] = NULL; + //DESTQ.size[i] = 0; + } + else { + dest->next = dest->next->next; + } + } + + if (temp == NULL) + {/* do nothing */} //zfwMemFree(dev, temp, sizeof(struct dest)); + else + zfwMemFree(dev, temp, sizeof(struct dest)); + + /*zmw_enter_critical_section(dev); + if (DESTQ.size[i] > 0) + DESTQ.size[i]--; + zmw_leave_critical_section(dev); + */ + } + + } + zmw_leave_critical_section(dev); + return; +} + +void zfAggDestInit(zdev_t* dev) +{ + u16_t i; + zmw_get_wlan_dev(dev); + + //zmw_declare_for_critical_section(); + + for (i=0; i<4; i++) { + //wd->destQ.Head[i].next = wd->destQ.Head[i]; + //wd->destQ.dest[i] = wd->destQ.Head[i]; + //DESTQ.size[i] = 0; + DESTQ.Head[i] = NULL; + } + DESTQ.insert = zfAggDestInsert; + DESTQ.delete = zfAggDestDelete; + DESTQ.init = zfAggDestInit; + DESTQ.getNext = zfAggDestGetNext; + DESTQ.exist = zfAggDestExist; + DESTQ.ppri = 0; + return; +} + +struct dest* zfAggDestGetNext(zdev_t* dev, u16_t ac) +{ + struct dest *dest = NULL; + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + if (DESTQ.dest[ac]) { + dest = DESTQ.dest[ac]; + DESTQ.dest[ac] = DESTQ.dest[ac]->next; + } + else { + dest = NULL; + } + zmw_leave_critical_section(dev); + + return dest; +} + +#ifdef ZM_ENABLE_AGGREGATION +#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW +u16_t zfAggTidTxInsertHead(zdev_t* dev, struct bufInfo *buf_info,TID_TX tid_tx) +{ + zbuf_t* buf; + u32_t time; + struct baw_header *baw_header; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + + buf = buf_info->buf; + + zmw_enter_critical_section(dev); + tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail); + zmw_leave_critical_section(dev); + + if (tid_tx->size >= (ZM_AGGQ_SIZE - 2)) { + zfwBufFree(dev, buf, ZM_SUCCESS); + return 0; + } + + zmw_enter_critical_section(dev); + tid_tx->aggTail = (tid_tx->aggTail == 0)? ZM_AGGQ_SIZE_MASK: tid_tx->aggTail - 1; + tid_tx->aggvtxq[tid_tx->aggTail].buf = buf; + //time = zm_agg_GetTime(); + tid_tx->aggvtxq[tid_tx->aggTail].arrivalTime = buf_info->timestamp; + tid_tx->aggvtxq[tid_tx->aggTail].baw_retransmit = buf_info->baw_retransmit; + + baw_header = &tid_tx->aggvtxq[tid_tx->aggTail].baw_header; + baw_header->headerLen = buf_info->baw_header->headerLen; + baw_header->micLen = buf_info->baw_header->micLen; + baw_header->snapLen = buf_info->baw_header->snapLen; + baw_header->removeLen = buf_info->baw_header->removeLen; + baw_header->keyIdx = buf_info->baw_header->keyIdx; + zfwMemoryCopy((u8_t *)baw_header->header, (u8_t *)buf_info->baw_header->header, 58); + zfwMemoryCopy((u8_t *)baw_header->mic , (u8_t *)buf_info->baw_header->mic , 8); + zfwMemoryCopy((u8_t *)baw_header->snap , (u8_t *)buf_info->baw_header->snap , 8); + + tid_tx->size++; + tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail); + zmw_leave_critical_section(dev); + + //tid_tx->lastArrival = time; + if (1 == tid_tx->size) { + DESTQ.insert(dev, 0, tid_tx->ac, tid_tx, NULL); + } + + + zm_msg1_agg(ZM_LV_0, "0xC2:insertHead, tid_tx->size=", tid_tx->size); + + return TRUE; +} +#endif //disable BAW +#endif + +void zfiTxComplete(zdev_t* dev) +{ + + zmw_get_wlan_dev(dev); + + //zmw_declare_for_critical_section(); + + if( (wd->wlanMode == ZM_MODE_AP) || + (wd->wlanMode == ZM_MODE_INFRASTRUCTURE && wd->sta.EnableHT) || + (wd->wlanMode == ZM_MODE_PSEUDO) ) { + zfAggTxScheduler(dev, 0); + } + + return; +} + +TID_TX zfAggTxReady(zdev_t* dev) { + //struct dest* dest; + u16_t i; + TID_TX tid_tx = NULL; + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + for (i=0; iaggQPool[i]->aggQEnabled) + { + if (wd->aggQPool[i]->size >= 16) { + tid_tx = wd->aggQPool[i]; + break; + } + } + else { + } + } + zmw_leave_critical_section(dev); + return tid_tx; +} + +u16_t zfAggValidTidTx(zdev_t* dev, TID_TX tid_tx) { + u16_t i, valid = 0; + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + for (i=0; iaggQPool[i] == tid_tx) + { + valid = 1; + break; + } + else { + } + } + zmw_leave_critical_section(dev); + + return valid; +} + +void zfAggTxScheduler(zdev_t* dev, u8_t ScanAndClear) +{ + TID_TX tid_tx = NULL; + void* vtxq; + struct dest* dest; + zbuf_t* buf; + u32_t txql, min_txql; + //u16_t aggr_size = 1; + u16_t txq_threshold; + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + if (!wd->aggInitiated) + { + return; + } + + /* debug */ + txql = TXQL; + min_txql = AGG_MIN_TXQL; + + if(wd->txq_threshold) + txq_threshold = wd->txq_threshold; + else + txq_threshold = AGG_MIN_TXQL; + + tid_tx = zfAggTxReady(dev); + if (tid_tx) ScanAndClear = 0; + while (zfHpGetFreeTxdCount(dev) > 20 && (TXQL < txq_threshold || tid_tx)) { + //while (zfHpGetFreeTxdCount(dev) > 20 && (ScanAndClear || tid_tx)) { + //while (TXQL < txq_threshold) { + u16_t i; + u8_t ac; + s8_t destQ_count = 0; + //while ((zfHpGetFreeTxdCount(dev)) > 32) { + + //DbgPrint("zfAggTxScheduler: in while loop"); + for (i=0; i<4; i++) { + if (DESTQ.Head[i]) destQ_count++; + } + if (0 >= destQ_count) break; + + zmw_enter_critical_section(dev); + ac = pri[DESTQ.ppri]; DESTQ.ppri = (DESTQ.ppri + 1) % 10; + zmw_leave_critical_section(dev); + + for (i=0; i<10; i++){ + if(DESTQ.Head[ac]) break; + + zmw_enter_critical_section(dev); + ac = pri[DESTQ.ppri]; DESTQ.ppri = (DESTQ.ppri + 1) % 10; + zmw_leave_critical_section(dev); + } + if (i == 10) break; + //DbgPrint("zfAggTxScheduler: have dest Q"); + zmw_enter_critical_section(dev); + wd->destLock = 1; + zmw_leave_critical_section(dev); + + dest = DESTQ.getNext(dev, ac); + if (!dest) { + zmw_enter_critical_section(dev); + wd->destLock = 0; + zmw_leave_critical_section(dev); + + DbgPrint("bug report! DESTQ.getNext got nothing!"); + break; + } + if (dest->Qtype == 0) { + tid_tx = dest->tid_tx; + + //DbgPrint("zfAggTxScheduler: have tid_tx Q"); + + if(tid_tx && zfAggValidTidTx(dev, tid_tx)) + tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail); + else { + zmw_enter_critical_section(dev); + wd->destLock = 0; + zmw_leave_critical_section(dev); + + tid_tx = zfAggTxReady(dev); + continue; + } + + zmw_enter_critical_section(dev); + wd->destLock = 0; + zmw_leave_critical_section(dev); + //zmw_enter_critical_section(dev); + if (tid_tx && !tid_tx->size) { + + //zmw_leave_critical_section(dev); + //DESTQ.delete(dev, 0, tid_tx, NULL); + } + else if(wd->aggState == 0){ + //wd->aggState = 1; + //zmw_leave_critical_section(dev); + zfAggTxSend(dev, zfHpGetFreeTxdCount(dev), tid_tx); + //wd->aggState = 0; + } + else { + //zmw_leave_critical_section(dev); + break; + } + } + else { + vtxq = dest->vtxq; + buf = zfGetVtxq(dev, ac); + zm_assert( buf != 0 ); + + zfTxSendEth(dev, buf, 0, ZM_EXTERNAL_ALLOC_BUF, 0); + + } + /*flush all but < 16 frames in tid_tx to TXQ*/ + tid_tx = zfAggTxReady(dev); + } + + /*while ((zfHpGetFreeTxdCount(dev)) > 32) { + //while ((zfHpGetFreeTxdCount(dev)) > 32) { + + destQ_count = 0; + for (i=0; i<4; i++) destQ_count += wd->destQ.size[i]; + if (0 >= destQ_count) break; + + ac = pri[wd->destQ.ppri]; wd->destQ.ppri = (wd->destQ.ppri + 1) % 10; + for (i=0; i<10; i++){ + if(wd->destQ.size[ac]!=0) break; + ac = pri[wd->destQ.ppri]; wd->destQ.ppri = (wd->destQ.ppri + 1) % 10; + } + if (i == 10) break; + dest = wd->destQ.getNext(dev, ac); + if (dest->Qtype == 0) { + tid_tx = dest->tid_tx; + tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail); + if (!tid_tx->size) { + wd->destQ.delete(dev, 0, tid_tx, NULL); + break; + } + else if((wd->aggState == 0) && (tid_tx->size >= 16)){ + zfAggTxSend(dev, zfHpGetFreeTxdCount(dev), tid_tx); + } + else { + break; + } + } + + } + */ + return; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfAggTx */ +/* return Status code ZM_SUCCESS or error code */ +/* management A-MPDU aggregation function, */ +/* management aggregation queue, calculate arrivalrate, */ +/* add/delete an aggregation queue of a stream, */ +/* enqueue packets into responsible aggregate queue. */ +/* take (dev, buf, ac) as input */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : packet buff */ +/* ac : access category */ +/* */ +/* OUTPUTS */ +/* status code */ +/* */ +/* AUTHOR */ +/* Honda Atheros Communications, INC. 2006.12 */ +/* */ +/************************************************************************/ +u16_t zfAggTx(zdev_t* dev, zbuf_t* buf, u16_t tid) +{ + u16_t aid; + //u16_t qnum; + //u16_t aggflag = 0; + //u16_t arrivalrate = 0; + TID_TX tid_tx; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + if(!wd->aggInitiated) + { + return ZM_ERR_TX_BUFFER_UNAVAILABLE; + } + + aid = zfAggGetSta(dev, buf); + + //arrivalrate = zfAggTxArrivalRate(dev, aid, tid); + + if (0xffff == aid) + { + /* + * STA not associated, this is a BC/MC or STA->AP packet + */ + + return ZM_ERR_TX_BUFFER_UNAVAILABLE; + } + + /* + * STA associated, a unicast packet + */ + + tid_tx = zfAggTxGetQueue(dev, aid, tid); + + /*tid_q.tid_tx = tid_tx; + wd->destQ.insert = zfAggDestInsert; + wd->destQ.insert(dev, 0, tid_q); + */ + if (tid_tx != NULL) + { + /* + * this (aid, ac) is aggregated + */ + + //if (arrivalrate < ZM_AGG_LOW_THRESHOLD) + if (0) + { + /* + * arrival rate too low + * delete this aggregate queue + */ + + zmw_enter_critical_section(dev); + + //wd->aggQPool[qnum]->clearFlag = wd->aggQPool[qnum]->deleteFlag =1; + + zmw_leave_critical_section(dev); + + } + + return zfAggTxEnqueue(dev, buf, aid, tid_tx); + + } + else + { + /* + * this (aid, ac) not yet aggregated + * queue not found + */ + + //if (arrivalrate > ZM_AGG_HIGH_THRESHOLD) + if (1) + { + /* + * arrivalrate high enough to get a new agg queue + */ + + tid_tx = zfAggTxNewQueue(dev, aid, tid, buf); + + //zm_msg1_agg(ZM_LV_0, "get new AggQueue qnum = ", tid_tx->); + + if (tid_tx) + { + /* + * got a new aggregate queue + */ + + //zmw_enter_critical_section(dev); + + //wd->aggSta[aid].aggFlag[ac] = 1; + + //zmw_leave_critical_section(dev); + + /* + * add ADDBA functions here + * return ZM_ERR_TX_BUFFER_UNAVAILABLE; + */ + + + //zfAggSendAddbaRequest(dev, tid_tx->dst, tid_tx->ac, tid_tx->tid); + //zmw_enter_critical_section(dev); + + //wd->aggSta[aid].aggFlag[ac] = 0; + + //zmw_leave_critical_section(dev); + + return zfAggTxEnqueue(dev, buf, aid, tid_tx); + + } + else + { + /* + * just can't get a new aggregate queue + */ + + return ZM_ERR_TX_BUFFER_UNAVAILABLE; + } + } + else + { + /* + * arrival rate is not high enough to get a new agg queue + */ + + return ZM_ERR_TX_BUFFER_UNAVAILABLE; + } + } + + + +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfAggTxReadyCount */ +/* return counter of ready to aggregate queues. */ +/* take (dev, ac) as input, only calculate the ready to aggregate */ +/* queues of one particular ac. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* ac : access category */ +/* */ +/* OUTPUTS */ +/* counter of ready to aggregate queues */ +/* */ +/* AUTHOR */ +/* Honda Atheros Communications, INC. 2006.12 */ +/* */ +/************************************************************************/ +u16_t zfAggTxReadyCount(zdev_t* dev, u16_t ac) +{ + u16_t i; + u16_t readycount = 0; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + for (i=0 ; iaggQPool[i]->aggQEnabled && (wd->aggQPool[i]->aggReady || \ + wd->aggQPool[i]->clearFlag) && ac == wd->aggQPool[i]->ac) + readycount++; + } + + zmw_leave_critical_section(dev); + + return readycount; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfAggTxPartial */ +/* return the number that Vtxq has to send. */ +/* take (dev, ac, readycount) as input, calculate the ratio of */ +/* Vtxq length to (Vtxq length + readycount) of a particular ac, */ +/* and returns the Vtxq length * the ratio */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* ac : access category */ +/* readycount: the number of ready to aggregate queues of this ac */ +/* */ +/* OUTPUTS */ +/* Vtxq length * ratio */ +/* */ +/* AUTHOR */ +/* Honda Atheros Communications, INC. 2006.12 */ +/* */ +/************************************************************************/ +u16_t zfAggTxPartial(zdev_t* dev, u16_t ac, u16_t readycount) +{ + u16_t qlen; + u16_t partial; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + qlen = zm_agg_qlen(dev, wd->vtxqHead[ac], wd->vtxqTail[ac]); + + if ((qlen + readycount) > 0) + { + partial = (u16_t)( zm_agg_weight(ac) * ((u16_t)qlen/(qlen + \ + readycount)) ); + } + else + { + partial = 0; + } + + zmw_leave_critical_section(dev); + + if (partial > qlen) + partial = qlen; + + return partial; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfAggTxSend */ +/* return sentcount */ +/* take (dev, ac, n) as input, n is the number of scheduled agg */ +/* queues to be sent of the particular ac. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* ac : access category */ +/* n : the number of scheduled aggregation queues to be sent */ +/* */ +/* OUTPUTS */ +/* sentcount */ +/* */ +/* AUTHOR */ +/* Honda Atheros Communications, INC. 2006.12 */ +/* */ +/************************************************************************/ +u16_t zfAggTxSend(zdev_t* dev, u32_t freeTxd, TID_TX tid_tx) +{ + //u16_t qnum; + //u16_t qlen; + u16_t j; + //u16_t sentcount = 0; + zbuf_t* buf; + struct aggControl aggControl; + u16_t aggLen; + //zbuf_t* newBuf; + //u16_t bufLen; + //TID_BAW tid_baw = NULL; + //struct bufInfo *buf_info; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + //while (tid_tx->size > 0) + + zmw_enter_critical_section(dev); + tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail); + aggLen = zm_agg_min(16, zm_agg_min(tid_tx->size, (u16_t)(freeTxd - 2))); + zmw_leave_critical_section(dev); + + /* + * why there have to be 2 free Txd? + */ + if (aggLen <=0 ) + return 0; + + + if (aggLen == 1) { + buf = zfAggTxGetVtxq(dev, tid_tx); + if (buf) + zfTxSendEth(dev, buf, 0, ZM_EXTERNAL_ALLOC_BUF, 0); + if (tid_tx->size == 0) { + //DESTQ.delete(dev, 0, tid_tx, NULL); + } + + return 1; + } + /* + * Free Txd queue is big enough to put aggregation + */ + zmw_enter_critical_section(dev); + if (wd->aggState == 1) { + zmw_leave_critical_section(dev); + return 0; + } + wd->aggState = 1; + zmw_leave_critical_section(dev); + + + zm_msg1_agg(ZM_LV_0, "aggLen=", aggLen); + tid_tx->aggFrameSize = 0; + for (j=0; j < aggLen; j++) { + buf = zfAggTxGetVtxq(dev, tid_tx); + + zmw_enter_critical_section(dev); + tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail); + zmw_leave_critical_section(dev); + + if ( buf ) { + //struct aggTally *agg_tal; + u16_t completeIndex; + + if (0 == j) { + aggControl.ampduIndication = ZM_AGG_FIRST_MPDU; + + } + else if ((j == (aggLen - 1)) || tid_tx->size == 0) + { + aggControl.ampduIndication = ZM_AGG_LAST_MPDU; + //wd->aggState = 0; + + } + else + { + aggControl.ampduIndication = ZM_AGG_MIDDLE_MPDU; + /* the packet is delayed more than 500 ms, drop it */ + + } + tid_tx->aggFrameSize += zfwBufGetSize(dev, buf); + aggControl.addbaIndication = 0; + aggControl.aggEnabled = 1; + +#ifdef ZM_AGG_TALLY + agg_tal = &wd->agg_tal; + agg_tal->sent_packets_sum++; + +#endif + + zfAggTxSendEth(dev, buf, 0, ZM_EXTERNAL_ALLOC_BUF, 0, &aggControl, tid_tx); + + zmw_enter_critical_section(dev); + completeIndex = tid_tx->complete; + if(zm_agg_inQ(tid_tx, tid_tx->complete)) + zm_agg_plus(tid_tx->complete); + zmw_leave_critical_section(dev); + + if(zm_agg_inQ(tid_tx, completeIndex) && wd->zfcbSendCompleteIndication + && tid_tx->aggvtxq[completeIndex].buf) { + wd->zfcbSendCompleteIndication(dev, tid_tx->aggvtxq[completeIndex].buf); + zm_debug_msg0("in queue complete worked!"); + } + + } + else { + /* + * this aggregation queue is empty + */ + zm_msg1_agg(ZM_LV_0, "aggLen not reached, but no more frame, j=", j); + + break; + } + } + zmw_enter_critical_section(dev); + wd->aggState = 0; + zmw_leave_critical_section(dev); + + //zm_acquire_agg_spin_lock(Adapter); + tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail); + //zm_release_agg_spin_lock(Adapter); + + if (tid_tx->size == 0) { + //DESTQ.delete(dev, 0, tid_tx, NULL); + } + + + + //zfAggInvokeBar(dev, tid_tx); + if(j>0) { + aggr_count++; + zm_msg1_agg(ZM_LV_0, "0xC2:sent 1 aggr, aggr_count=", aggr_count); + zm_msg1_agg(ZM_LV_0, "0xC2:sent 1 aggr, aggr_size=", j); + } + return j; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfAggTxGetReadyQueue */ +/* return the number of the aggregation queue */ +/* take (dev, ac) as input, find the agg queue with smallest */ +/* arrival time (waited longest) among those ready or clearFlag */ +/* set queues. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* ac : access category */ +/* */ +/* OUTPUTS */ +/* aggregation queue number */ +/* */ +/* AUTHOR */ +/* Honda Atheros Communications, INC. 2006.12 */ +/* */ +/************************************************************************/ +TID_TX zfAggTxGetReadyQueue(zdev_t* dev, u16_t ac) +{ + //u16_t qnum = ZM_AGG_POOL_SIZE; + u16_t i; + u32_t time = 0; + TID_TX tid_tx = NULL; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + for (i=0 ;iaggQPool[i]->aggQEnabled && ac == wd->aggQPool[i]->ac && + (wd->aggQPool[i]->size > 0)) + { + if (0 == time || time > wd->aggQPool[i]->aggvtxq[ \ + wd->aggQPool[i]->aggHead ].arrivalTime) + { + tid_tx = wd->aggQPool[i]; + time = tid_tx->aggvtxq[ tid_tx->aggHead ].arrivalTime; + } + } + } + + zmw_leave_critical_section(dev); + + return tid_tx; +} + + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfAggTxGetVtxq */ +/* return an MSDU */ +/* take (dev, qnum) as input, return an MSDU out of the agg queue. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* qnum: queue number */ +/* */ +/* OUTPUTS */ +/* a MSDU */ +/* */ +/* AUTHOR */ +/* Honda Atheros Communications, INC. 2006.12 */ +/* */ +/************************************************************************/ +zbuf_t* zfAggTxGetVtxq(zdev_t* dev, TID_TX tid_tx) +{ + zbuf_t* buf = NULL; + + zmw_declare_for_critical_section(); + + if (tid_tx->aggHead != tid_tx->aggTail) + { + buf = tid_tx->aggvtxq[ tid_tx->aggTail ].buf; + + tid_tx->aggvtxq[tid_tx->aggTail].buf = NULL; + + zmw_enter_critical_section(dev); + tid_tx->aggTail = ((tid_tx->aggTail + 1) & ZM_AGGQ_SIZE_MASK); + if(tid_tx->size > 0) tid_tx->size--; + tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail); + if (NULL == buf) { + //tid_tx->aggTail = tid_tx->aggHead = tid_tx->size = 0; + //zm_msg1_agg(ZM_LV_0, "GetVtxq buf == NULL, tid_tx->size=", tid_tx->size); + } + zmw_leave_critical_section(dev); + } + else + { + /* + * queue is empty + */ + zm_msg1_agg(ZM_LV_0, "tid_tx->aggHead == tid_tx->aggTail, tid_tx->size=", tid_tx->size); + + } + + if (zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail) != tid_tx->size) + zm_msg1_agg(ZM_LV_0, "qlen!=tid_tx->size! tid_tx->size=", tid_tx->size); + return buf; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfAggTxDeleteQueue */ +/* return ZM_SUCCESS (can't fail) */ +/* take (dev, qnum) as input, reset (delete) this aggregate queue, */ +/* this queue is virtually returned to the aggregate queue pool. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* qnum: queue number */ +/* */ +/* OUTPUTS */ +/* ZM_SUCCESS */ +/* */ +/* AUTHOR */ +/* Honda Atheros Communications, INC. 2006.12 */ +/* */ +/************************************************************************/ +u16_t zfAggTxDeleteQueue(zdev_t* dev, u16_t qnum) +{ + u16_t ac, tid; + struct aggQueue *tx_tid; + struct aggSta *agg_sta; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + tx_tid = wd->aggQPool[qnum]; + agg_sta = &wd->aggSta[tx_tid->aggQSTA]; + ac = tx_tid->ac; + tid = tx_tid->tid; + + zmw_enter_critical_section(dev); + + tx_tid->aggQEnabled = 0; + tx_tid->aggHead = tx_tid->aggTail = 0; + tx_tid->aggReady = 0; + tx_tid->clearFlag = tx_tid->deleteFlag = 0; + tx_tid->size = 0; + agg_sta->count[ac] = 0; + + agg_sta->tid_tx[tid] = NULL; + agg_sta->aggFlag[ac] = 0; + + zmw_leave_critical_section(dev); + + zm_msg1_agg(ZM_LV_0, "queue deleted! qnum=", qnum); + + return ZM_SUCCESS; +} + +#ifdef ZM_ENABLE_AGGREGATION +#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW +void zfBawCore(zdev_t* dev, u16_t baw_seq, u32_t bitmap, u16_t aggLen) { + TID_BAW tid_baw; + s16_t i; + zbuf_t* buf; + struct bufInfo *buf_info; + + zmw_get_wlan_dev(dev); + //zmw_declare_for_critical_section(); + tid_baw = BAW->getQ(dev, baw_seq); + //tid_baw = NULL; + if (NULL == tid_baw) + return; + + total_mpdu += aggLen; + for (i = aggLen - 1; i>=0; i--) { + if (((bitmap >> i) & 0x1) == 0) { + buf_info = BAW->pop(dev, i, tid_baw); + buf = buf_info->buf; + if (buf) { + //wd->zfcbSetBawQ(dev, buf, 0); + zfAggTidTxInsertHead(dev, buf_info, tid_baw->tid_tx); + } + } + else { + success_mpdu++; + } + } + BAW->disable(dev, tid_baw); + zfAggTxScheduler(dev); + zm_debug_msg1("success_mpdu = ", success_mpdu); + zm_debug_msg1(" total_mpdu = ", total_mpdu); +} + +void zfBawInit(zdev_t* dev) { + TID_BAW tid_baw; + u16_t i,j; + zmw_get_wlan_dev(dev); + //zmw_declare_for_critical_section(); + + for (i=0; itid_baw[i]; + for (j=0; jframe[j].buf = NULL; + } + tid_baw->enabled = tid_baw->head = tid_baw->tail = tid_baw->size = 0; + tid_baw->start_seq = 0; + } + BAW->delPoint = 0; + BAW->core = zfBawCore; + BAW->getNewQ = zfBawGetNewQ; + BAW->insert = zfBawInsert; + BAW->pop = zfBawPop; + BAW->enable = zfBawEnable; + BAW->disable = zfBawDisable; + BAW->getQ = zfBawGetQ; +} + + + +TID_BAW zfBawGetNewQ(zdev_t* dev, u16_t start_seq, TID_TX tid_tx) { + TID_BAW tid_baw=NULL; + TID_BAW next_baw=NULL; + u16_t i; + zmw_get_wlan_dev(dev); + //zmw_declare_for_critical_section(); + + /* + for (i=0; itid_baw[i]; + if (FALSE == tid_baw->enabled) + break; + } + */ + + tid_baw = &BAW->tid_baw[BAW->delPoint]; + i = BAW->delPoint; + //if (ZM_BAW_POOL_SIZE == i) { + //return NULL; + // u8_t temp = BAW->delPoint; + // tid_baw = &BAW->tid_baw[BAW->delPoint]; + // BAW->disable(dev, tid_baw); + // BAW->delPoint = (BAW->delPoint < (ZM_BAW_POOL_SIZE - 1))? (BAW->delPoint + 1): 0; + // temp = BAW->delPoint; + //} + + zm_msg1_agg(ZM_LV_0, "get new tid_baw, index=", i); + BAW->delPoint = (i < (ZM_BAW_POOL_SIZE -1))? (i + 1): 0; + next_baw = &BAW->tid_baw[BAW->delPoint]; + if (1 == next_baw->enabled) BAW->disable(dev, next_baw); + + BAW->enable(dev, tid_baw, start_seq); + tid_baw->tid_tx = tid_tx; + + return tid_baw; +} + +u16_t zfBawInsert(zdev_t* dev, zbuf_t* buf, u16_t baw_seq, TID_BAW tid_baw, u8_t baw_retransmit, struct baw_header_r *header_r) { + //TID_BAW tid_baw; + //u16_t bufLen; + + //zmw_get_wlan_dev(dev); + //zmw_declare_for_critical_section(); + + if(tid_baw->size < (ZM_VTXQ_SIZE - 1)) { + struct baw_header *baw_header = &tid_baw->frame[tid_baw->head].baw_header; + + baw_header->headerLen = header_r->headerLen; + baw_header->micLen = header_r->micLen; + baw_header->snapLen = header_r->snapLen; + baw_header->removeLen = header_r->removeLen; + baw_header->keyIdx = header_r->keyIdx; + zfwMemoryCopy((u8_t *)baw_header->header, (u8_t *)header_r->header, 58); + zfwMemoryCopy((u8_t *)baw_header->mic , (u8_t *)header_r->mic , 8); + zfwMemoryCopy((u8_t *)baw_header->snap , (u8_t *)header_r->snap , 8); + //wd->zfcbSetBawQ(dev, buf, 1); + tid_baw->frame[tid_baw->head].buf = buf; + tid_baw->frame[tid_baw->head].baw_seq = baw_seq; + tid_baw->frame[tid_baw->head].baw_retransmit = baw_retransmit + 1; + + //tid_baw->frame[tid_baw->head].data = pBuf->data; + tid_baw->head++; + tid_baw->size++; + } + else { + //wd->zfcbSetBawQ(dev, buf, 0); + zfwBufFree(dev, buf, ZM_SUCCESS); + return FALSE; + } + return TRUE; +} + +struct bufInfo* zfBawPop(zdev_t* dev, u16_t index, TID_BAW tid_baw) { + //TID_BAW tid_baw; + //zbuf_t* buf; + struct bufInfo *buf_info; + zmw_get_wlan_dev(dev); + + buf_info = &wd->buf_info; + buf_info->baw_header = NULL; + + if (NULL == (buf_info->buf = tid_baw->frame[index].buf)) + return buf_info; + + buf_info->baw_retransmit = tid_baw->frame[index].baw_retransmit; + buf_info->baw_header = &tid_baw->frame[index].baw_header; + buf_info->timestamp = tid_baw->frame[index].timestamp; + //pBuf->data = pBuf->buffer; + //wd->zfcbRestoreBufData(dev, buf); + tid_baw->frame[index].buf = NULL; + + return buf_info; +} + +void zfBawEnable(zdev_t* dev, TID_BAW tid_baw, u16_t start_seq) { + //TID_BAW tid_baw; + + //zmw_get_wlan_dev(dev); + //zmw_declare_for_critical_section(); + + tid_baw->enabled = TRUE; + tid_baw->head = tid_baw->tail = tid_baw->size = 0; + tid_baw->start_seq = start_seq; +} + +void zfBawDisable(zdev_t* dev, TID_BAW tid_baw) { + //TID_BAW tid_baw; + u16_t i; + + //zmw_get_wlan_dev(dev); + //zmw_declare_for_critical_section(); + for (i=0; iframe[i].buf) { + + //wd->zfcbSetBawQ(dev, tid_baw->frame[i].buf, 0); + zfwBufFree(dev, tid_baw->frame[i].buf, ZM_SUCCESS); + tid_baw->frame[i].buf = NULL; + } + } + + tid_baw->enabled = FALSE; +} + +TID_BAW zfBawGetQ(zdev_t* dev, u16_t baw_seq) { + TID_BAW tid_baw=NULL; + u16_t i; + + zmw_get_wlan_dev(dev); + //zmw_declare_for_critical_section(); + for (i=0; itid_baw[i]; + if (TRUE == tid_baw->enabled) + { + zm_msg1_agg(ZM_LV_0, "get an old tid_baw, baw_seq=", baw_seq); + zm_msg1_agg(ZM_LV_0, "check a tid_baw->start_seq=", tid_baw->start_seq); + if(baw_seq == tid_baw->start_seq) + break; + } + + } + if (ZM_BAW_POOL_SIZE == i) + return NULL; + return tid_baw; +} +#endif //disable BAW +#endif + +u16_t zfAggTallyReset(zdev_t* dev) +{ + struct aggTally* agg_tal; + + zmw_get_wlan_dev(dev); + + //zmw_declare_for_critical_section(); + + agg_tal = &wd->agg_tal; + agg_tal->got_packets_sum = 0; + agg_tal->got_bytes_sum = 0; + agg_tal->sent_bytes_sum = 0; + agg_tal->sent_packets_sum = 0; + agg_tal->avg_got_packets = 0; + agg_tal->avg_got_bytes = 0; + agg_tal->avg_sent_packets = 0; + agg_tal->avg_sent_bytes = 0; + agg_tal->time = 0; + return 0; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfAggScanAndClear */ +/* If the packets in a queue have waited for too long, clear and */ +/* delete this aggregation queue. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* time : current time */ +/* */ +/* OUTPUTS */ +/* ZM_SUCCESS */ +/* */ +/* AUTHOR */ +/* Honda Atheros Communications, INC. 2006.12 */ +/* */ +/************************************************************************/ +u16_t zfAggScanAndClear(zdev_t* dev, u32_t time) +{ + u16_t i; + u16_t head; + u16_t tail; + u32_t tick; + u32_t arrivalTime; + //u16_t aid, ac; + TID_TX tid_tx; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + if(!(wd->state == ZM_WLAN_STATE_ENABLED)) return 0; + zfAggTxScheduler(dev, 1); + tick = zm_agg_GetTime(); + for (i=0; iaggQPool[i]) return 0; + if (1 == wd->aggQPool[i]->aggQEnabled) + { + tid_tx = wd->aggQPool[i]; + zmw_enter_critical_section(dev); + + head = tid_tx->aggHead; + tail = tid_tx->aggTail; + + arrivalTime = (u32_t)tid_tx->aggvtxq[tid_tx->aggTail].arrivalTime; + + + if((tick - arrivalTime) <= ZM_AGG_CLEAR_TIME) + { + + } + else if((tid_tx->size = zm_agg_qlen(dev, tid_tx->aggHead, tid_tx->aggTail)) > 0) + { + + tid_tx->clearFlag = 1; + + //zm_msg1_agg(ZM_LV_0, "clear queue tick =", tick); + //zm_msg1_agg(ZM_LV_0, "clear queue arrival =", arrivalTime); + + + //zmw_leave_critical_section(dev); + //zfAggTxScheduler(dev); + //zmw_enter_critical_section(dev); + + } + + if (tid_tx->size == 0) + { + /* + * queue empty + */ + if (tick - tid_tx->lastArrival > ZM_AGG_DELETE_TIME) + { + zm_msg1_agg(ZM_LV_0, "delete queue, idle for n sec. n = ", \ + ZM_AGG_DELETE_TIME/10); + + zmw_leave_critical_section(dev); + zfAggTxDeleteQueue(dev, i); + zmw_enter_critical_section(dev); + } + } + + zmw_leave_critical_section(dev); + } + } + + zfAggRxClear(dev, time); + +#ifdef ZM_AGG_TALLY + if((wd->tick % 100) == 0) { + zfAggPrintTally(dev); + } +#endif + + return ZM_SUCCESS; +} + +u16_t zfAggPrintTally(zdev_t* dev) +{ + struct aggTally* agg_tal; + + zmw_get_wlan_dev(dev); + + //zmw_declare_for_critical_section(); + + agg_tal = &wd->agg_tal; + + if(agg_tal->got_packets_sum < 10) + { + zfAggTallyReset(dev); + return 0; + } + + agg_tal->time++; + agg_tal->avg_got_packets = (agg_tal->avg_got_packets * (agg_tal->time - 1) + + agg_tal->got_packets_sum) / agg_tal->time; + agg_tal->avg_got_bytes = (agg_tal->avg_got_bytes * (agg_tal->time - 1) + + agg_tal->got_bytes_sum) / agg_tal->time; + agg_tal->avg_sent_packets = (agg_tal->avg_sent_packets * (agg_tal->time - 1) + + agg_tal->sent_packets_sum) / agg_tal->time; + agg_tal->avg_sent_bytes = (agg_tal->avg_sent_bytes * (agg_tal->time - 1) + + agg_tal->sent_bytes_sum) / agg_tal->time; + zm_msg1_agg(ZM_LV_0, "got_packets_sum =", agg_tal->got_packets_sum); + zm_msg1_agg(ZM_LV_0, " got_bytes_sum =", agg_tal->got_bytes_sum); + zm_msg1_agg(ZM_LV_0, "sent_packets_sum=", agg_tal->sent_packets_sum); + zm_msg1_agg(ZM_LV_0, " sent_bytes_sum =", agg_tal->sent_bytes_sum); + agg_tal->got_packets_sum = agg_tal->got_bytes_sum =agg_tal->sent_packets_sum + = agg_tal->sent_bytes_sum = 0; + zm_msg1_agg(ZM_LV_0, "avg_got_packets =", agg_tal->avg_got_packets); + zm_msg1_agg(ZM_LV_0, " avg_got_bytes =", agg_tal->avg_got_bytes); + zm_msg1_agg(ZM_LV_0, "avg_sent_packets=", agg_tal->avg_sent_packets); + zm_msg1_agg(ZM_LV_0, " avg_sent_bytes =", agg_tal->avg_sent_bytes); + if ((wd->commTally.BA_Fail == 0) || (wd->commTally.Hw_Tx_MPDU == 0)) + { + zm_msg1_agg(ZM_LV_0, "Hardware Tx MPDU=", wd->commTally.Hw_Tx_MPDU); + zm_msg1_agg(ZM_LV_0, " BA Fail number=", wd->commTally.BA_Fail); + } + else + zm_msg1_agg(ZM_LV_0, "1/(BA fail rate)=", wd->commTally.Hw_Tx_MPDU/wd->commTally.BA_Fail); + + return 0; +} + +u16_t zfAggRxClear(zdev_t* dev, u32_t time) +{ + u16_t i; + struct agg_tid_rx *tid_rx; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + for (i=0; itid_rx[i]; + if (tid_rx->baw_head != tid_rx->baw_tail) + { + u16_t j = tid_rx->baw_tail; + while ((j != tid_rx->baw_head) && !tid_rx->frame[j].buf) { + j = (j + 1) & ZM_AGG_BAW_MASK; + } + if ((j != tid_rx->baw_head) && (time - tid_rx->frame[j].arrivalTime) > + (ZM_AGG_CLEAR_TIME - 5)) + { + zmw_leave_critical_section(dev); + zm_msg0_agg(ZM_LV_1, "queue RxFlush by RxClear"); + zfAggRxFlush(dev, 0, tid_rx); + zmw_enter_critical_section(dev); + } + } + zmw_leave_critical_section(dev); + } + + return ZM_SUCCESS; +} + +struct agg_tid_rx* zfAggRxEnabled(zdev_t* dev, zbuf_t* buf) +{ + u16_t dst0, src[3], ac, aid, fragOff; + u8_t up; + u16_t offset = 0; + u16_t seq_no; + u16_t frameType; + u16_t frameCtrl; + u16_t frameSubtype; + u32_t tcp_seq; + //struct aggSta *agg_sta; +#if ZM_AGG_FPGA_REORDERING + struct agg_tid_rx *tid_rx; +#endif + zmw_get_wlan_dev(dev); + + //zmw_declare_for_critical_section(); + seq_no = zmw_rx_buf_readh(dev, buf, 22) >> 4; + //DbgPrint("Rx seq=%d\n", seq_no); + if (wd->sta.EnableHT == 0) + { + return NULL; + } + + frameCtrl = zmw_rx_buf_readb(dev, buf, 0); + frameType = frameCtrl & 0xf; + frameSubtype = frameCtrl & 0xf0; + + + if (frameType != ZM_WLAN_DATA_FRAME) //non-Qos Data? (frameSubtype&0x80) + { + return NULL; + } +#ifdef ZM_ENABLE_PERFORMANCE_EVALUATION + tcp_seq = zmw_rx_buf_readb(dev, buf, 22+36) << 24; + tcp_seq += zmw_rx_buf_readb(dev, buf, 22+37) << 16; + tcp_seq += zmw_rx_buf_readb(dev, buf, 22+38) << 8; + tcp_seq += zmw_rx_buf_readb(dev, buf, 22+39); +#endif + + ZM_SEQ_DEBUG("In %5d, %12u\n", seq_no, tcp_seq); + dst0 = zmw_rx_buf_readh(dev, buf, offset+4); + + src[0] = zmw_rx_buf_readh(dev, buf, offset+10); + src[1] = zmw_rx_buf_readh(dev, buf, offset+12); + src[2] = zmw_rx_buf_readh(dev, buf, offset+14); + +#if ZM_AGG_FPGA_DEBUG + aid = 0; +#else + aid = zfApFindSta(dev, src); +#endif + + //agg_sta = &wd->aggSta[aid]; + //zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff); + //ac = zcUpToAc[up&0x7] & 0x3; + + /* + * Filter unicast frame only, aid == 0 is for debug only + */ + if ((dst0 & 0x1) == 0 && aid == 0) + { +#if ZM_AGG_FPGA_REORDERING + tid_rx = zfAggRxGetQueue(dev, buf) ; + if(!tid_rx) + return NULL; + else + { + //if (tid_rx->addBaExchangeStatusCode == ZM_AGG_ADDBA_RESPONSE) + return tid_rx; + } +#else + return NULL; +#endif + } + + return NULL; +} + +u16_t zfAggRx(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo *addInfo, struct agg_tid_rx *tid_rx) +{ + u16_t seq_no; + s16_t index; + u16_t offset = 0; + zbuf_t* pbuf; + u8_t frameSubType; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + ZM_BUFFER_TRACE(dev, buf) + + ZM_PERFORMANCE_RX_REORDER(dev); + + seq_no = zmw_rx_buf_readh(dev, buf, offset+22) >> 4; + + index = seq_no - tid_rx->seq_start; + /* + * for debug + */ + + /* zm_msg2_agg(ZM_LV_0, "queue seq = ", seq_no); + * DbgPrint("%s:%s%lxh %s%lxh\n", __func__, "queue seq=", seq_no, + * "; seq_start=", tid_rx->seq_start); + */ + + //DbgPrint("seq_no=%d, seq_start=%d\n", seq_no, tid_rx->seq_start); + + /* In some APs, we found that it might transmit NULL data whose sequence number + is out or order. In order to avoid this problem, we ignore these NULL data. + */ + + frameSubType = (zmw_rx_buf_readh(dev, buf, 0) & 0xF0) >> 4; + + /* If this is a NULL data instead of Qos NULL data */ + if ((frameSubType & 0x0C) == 0x04) + { + s16_t seq_diff; + + seq_diff = (seq_no > tid_rx->seq_start) ? + seq_no - tid_rx->seq_start : tid_rx->seq_start - seq_no; + + if (seq_diff > ZM_AGG_BAW_SIZE) + { + zm_debug_msg0("Free Rx NULL data in zfAggRx"); + + /* Free Rx buffer */ + zfwBufFree(dev, buf, 0); + return ZM_ERR_OUT_OF_ORDER_NULL_DATA; + } + } + + /* + * sequence number wrap at 4k + */ + if (tid_rx->seq_start > seq_no) + { + //index += 4096; + + zmw_enter_critical_section(dev); + if (tid_rx->seq_start >= 4096) { + tid_rx->seq_start = 0; + } + zmw_leave_critical_section(dev); + + } + + if (tid_rx->seq_start == seq_no) { + zmw_enter_critical_section(dev); + if (((tid_rx->baw_head - tid_rx->baw_tail) & ZM_AGG_BAW_MASK) > 0) { + //DbgPrint("head=%d, tail=%d", tid_rx->baw_head, tid_rx->baw_tail); + tid_rx->baw_tail = (tid_rx->baw_tail + 1) & ZM_AGG_BAW_MASK; + } + tid_rx->seq_start = (tid_rx->seq_start + 1) & (4096 - 1); + zmw_leave_critical_section(dev); + + ZM_PERFORMANCE_RX_SEQ(dev, buf); + + if (wd->zfcbRecv80211 != NULL) { + //seq_no = zmw_rx_buf_readh(dev, buf, offset+22) >> 4; + //DbgPrint("Recv indicate seq=%d\n", seq_no); + //DbgPrint("1. seq=%d\n", seq_no); + + wd->zfcbRecv80211(dev, buf, addInfo); + } + else { + zfiRecv80211(dev, buf, addInfo); + } + } + else if (!zfAggRxEnqueue(dev, buf, tid_rx, addInfo)) + { + /* + * duplicated packet + */ + return 1; + } + + while (tid_rx->baw_head != tid_rx->baw_tail) {// && tid_rx->frame[tid_rx->baw_tail].buf) + u16_t tailIndex; + + zmw_enter_critical_section(dev); + + tailIndex = tid_rx->baw_tail; + pbuf = tid_rx->frame[tailIndex].buf; + tid_rx->frame[tailIndex].buf = 0; + if (!pbuf) + { + zmw_leave_critical_section(dev); + break; + } + + tid_rx->baw_tail = (tid_rx->baw_tail + 1) & ZM_AGG_BAW_MASK; + tid_rx->seq_start = (tid_rx->seq_start + 1) & (4096 - 1); + + + //if(pbuf && tid_rx->baw_size > 0) + // tid_rx->baw_size--; + + zmw_leave_critical_section(dev); + + ZM_PERFORMANCE_RX_SEQ(dev, pbuf); + + if (wd->zfcbRecv80211 != NULL) + { + //seq_no = zmw_rx_buf_readh(dev, pbuf, offset+22) >> 4; + //DbgPrint("Recv indicate seq=%d\n", seq_no); + //DbgPrint("1. seq=%d\n", seq_no); + wd->zfcbRecv80211(dev, pbuf, addInfo); + } + else + { + //seq_no = zmw_rx_buf_readh(dev, pbuf, offset+22) >> 4; + //DbgPrint("Recv indicate seq=%d\n", seq_no); + zfiRecv80211(dev, pbuf, addInfo); + } + } + + return 1; +} + +struct agg_tid_rx *zfAggRxGetQueue(zdev_t* dev, zbuf_t* buf) +{ + u16_t src[3]; + u16_t aid, ac, i; + u16_t offset = 0; + struct agg_tid_rx *tid_rx = NULL; + + zmw_get_wlan_dev(dev); + + //zmw_declare_for_critical_section(); + + src[0] = zmw_rx_buf_readh(dev, buf, offset+10); + src[1] = zmw_rx_buf_readh(dev, buf, offset+12); + src[2] = zmw_rx_buf_readh(dev, buf, offset+14); + aid = zfApFindSta(dev, src); + + ac = (zmw_rx_buf_readh(dev, buf, 24) & 0xF); + + // mark by spin lock debug + //zmw_enter_critical_section(dev); + + for (i=0; itid_rx[i]->aid == aid) && (wd->tid_rx[i]->ac == ac)) + { + tid_rx = wd->tid_rx[i]; + break; + } + } + + // mark by spin lock debug + //zmw_leave_critical_section(dev); + return tid_rx; +} + + +u16_t zfAggRxEnqueue(zdev_t* dev, zbuf_t* buf, struct agg_tid_rx *tid_rx, struct zsAdditionInfo *addInfo) +{ + u16_t seq_no, offset = 0; + u16_t q_index; + s16_t index; + u8_t bdropframe = 0; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + ZM_BUFFER_TRACE(dev, buf) + + seq_no = zmw_rx_buf_readh(dev, buf, offset+22) >> 4; + index = seq_no - tid_rx->seq_start; + + /* + * sequence number wrap at 4k + * -1000: check for duplicate past packet + */ + bdropframe = 0; + if (tid_rx->seq_start > seq_no) { + if ((tid_rx->seq_start > 3967) && (seq_no < 128)) { + index += 4096; + } else if (tid_rx->seq_start - seq_no > 70) { + zmw_enter_critical_section(dev); + tid_rx->sq_behind_count++; + if (tid_rx->sq_behind_count > 3) { + tid_rx->sq_behind_count = 0; + } else { + bdropframe = 1; + } + zmw_leave_critical_section(dev); + } else { + bdropframe = 1; + } + } else { + if (seq_no - tid_rx->seq_start > 70) { + zmw_enter_critical_section(dev); + tid_rx->sq_exceed_count++; + if (tid_rx->sq_exceed_count > 3) { + tid_rx->sq_exceed_count = 0; + } else { + bdropframe = 1; + } + zmw_leave_critical_section(dev); + } + } + + if (bdropframe == 1) { + /*if (wd->zfcbRecv80211 != NULL) { + wd->zfcbRecv80211(dev, buf, addInfo); + } + else { + zfiRecv80211(dev, buf, addInfo); + }*/ + + ZM_PERFORMANCE_FREE(dev, buf); + + zfwBufFree(dev, buf, 0); + /*zfAggRxFlush(dev, seq_no, tid_rx); + tid_rx->seq_start = seq_no; + index = seq_no - tid_rx->seq_start; + */ + + //DbgPrint("Free an old packet, seq_start=%d, seq_no=%d\n", tid_rx->seq_start, seq_no); + + /* + * duplicate past packet + * happens only in simulated aggregation environment + */ + return 0; + } else { + zmw_enter_critical_section(dev); + if (tid_rx->sq_exceed_count > 0){ + tid_rx->sq_exceed_count--; + } + + if (tid_rx->sq_behind_count > 0) { + tid_rx->sq_behind_count--; + } + zmw_leave_critical_section(dev); + } + + if (index < 0) { + zfAggRxFlush(dev, seq_no, tid_rx); + tid_rx->seq_start = seq_no; + index = 0; + } + + //if (index >= (ZM_AGG_BAW_SIZE - 1)) + if (index >= (ZM_AGG_BAW_MASK)) + { + /* + * queue full + */ + //DbgPrint("index >= 64, seq_start=%d, seq_no=%d\n", tid_rx->seq_start, seq_no); + zfAggRxFlush(dev, seq_no, tid_rx); + //tid_rx->seq_start = seq_no; + index = seq_no - tid_rx->seq_start; + if ((tid_rx->seq_start > seq_no) && (tid_rx->seq_start > 1000) && (tid_rx->seq_start - 1000) > seq_no) + { + //index = seq_no - tid_rx->seq_start; + index += 4096; + } + //index = seq_no - tid_rx->seq_start; + while (index >= (ZM_AGG_BAW_MASK)) { + //DbgPrint("index >= 64, seq_start=%d, seq_no=%d\n", tid_rx->seq_start, seq_no); + tid_rx->seq_start = (tid_rx->seq_start + ZM_AGG_BAW_MASK) & (4096 - 1); + index = seq_no - tid_rx->seq_start; + if ((tid_rx->seq_start > seq_no) && (tid_rx->seq_start > 1000) && (tid_rx->seq_start - 1000) > seq_no) + { + index += 4096; + } + } + } + + + q_index = (tid_rx->baw_tail + index) & ZM_AGG_BAW_MASK; + if (tid_rx->frame[q_index].buf && (((tid_rx->baw_head - tid_rx->baw_tail) & ZM_AGG_BAW_MASK) > + (((q_index) - tid_rx->baw_tail) & ZM_AGG_BAW_MASK))) + { + + ZM_PERFORMANCE_DUP(dev, tid_rx->frame[q_index].buf, buf); + zfwBufFree(dev, buf, 0); + //DbgPrint("Free a duplicate packet, seq_start=%d, seq_no=%d\n", tid_rx->seq_start, seq_no); + //DbgPrint("head=%d, tail=%d", tid_rx->baw_head, tid_rx->baw_tail); + /* + * duplicate packet + */ + return 0; + } + + zmw_enter_critical_section(dev); + if(tid_rx->frame[q_index].buf) { + zfwBufFree(dev, tid_rx->frame[q_index].buf, 0); + tid_rx->frame[q_index].buf = 0; + } + + tid_rx->frame[q_index].buf = buf; + tid_rx->frame[q_index].arrivalTime = zm_agg_GetTime(); + zfwMemoryCopy((void*)&tid_rx->frame[q_index].addInfo, (void*)addInfo, sizeof(struct zsAdditionInfo)); + + /* + * for debug simulated aggregation only, + * should be done in rx of ADDBA Request + */ + //tid_rx->addInfo = addInfo; + + + if (((tid_rx->baw_head - tid_rx->baw_tail) & ZM_AGG_BAW_MASK) <= index) + { + //tid_rx->baw_size = index + 1; + if (((tid_rx->baw_head - tid_rx->baw_tail) & ZM_AGG_BAW_MASK) <= + //((q_index + 1) & ZM_AGG_BAW_MASK)) + (((q_index) - tid_rx->baw_tail) & ZM_AGG_BAW_MASK))//tid_rx->baw_size ) + tid_rx->baw_head = (q_index + 1) & ZM_AGG_BAW_MASK; + } + zmw_leave_critical_section(dev); + + /* + * success + */ + //DbgPrint("head=%d, tail=%d, start=%d", tid_rx->baw_head, tid_rx->baw_tail, tid_rx->seq_start); + return 1; +} + +u16_t zfAggRxFlush(zdev_t* dev, u16_t seq_no, struct agg_tid_rx *tid_rx) +{ + zbuf_t* pbuf; + u16_t seq; + struct zsAdditionInfo addInfo; + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + ZM_PERFORMANCE_RX_FLUSH(dev); + + while (1) + { + zmw_enter_critical_section(dev); + if (tid_rx->baw_tail == tid_rx->baw_head) { + zmw_leave_critical_section(dev); + break; + } + + pbuf = tid_rx->frame[tid_rx->baw_tail].buf; + zfwMemoryCopy((void*)&addInfo, (void*)&tid_rx->frame[tid_rx->baw_tail].addInfo, sizeof(struct zsAdditionInfo)); + tid_rx->frame[tid_rx->baw_tail].buf = 0; + //if(pbuf && tid_rx->baw_size > 0) tid_rx->baw_size--; + tid_rx->baw_tail = (tid_rx->baw_tail + 1) & ZM_AGG_BAW_MASK; + tid_rx->seq_start = (tid_rx->seq_start + 1) & (4096 - 1); + zmw_leave_critical_section(dev); + + if (pbuf) + { + + ZM_PERFORMANCE_RX_SEQ(dev, pbuf); + + if (wd->zfcbRecv80211 != NULL) + { + seq = zmw_rx_buf_readh(dev, pbuf, 22) >> 4; + //DbgPrint("Recv indicate seq=%d\n", seq); + //DbgPrint("2. seq=%d\n", seq); + wd->zfcbRecv80211(dev, pbuf, &addInfo); + } + else + { + seq = zmw_rx_buf_readh(dev, pbuf, 22) >> 4; + //DbgPrint("Recv indicate seq=%d\n", seq); + zfiRecv80211(dev, pbuf, &addInfo); + } + } + } + + zmw_enter_critical_section(dev); + tid_rx->baw_head = tid_rx->baw_tail = 0; + zmw_leave_critical_section(dev); + return 1; +} + + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfAggRxFreeBuf */ +/* Frees all queued packets in buffer when the driver is down. */ +/* The zfFreeResource() will check if the buffer is all freed. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* ZM_SUCCESS */ +/* */ +/* AUTHOR */ +/* Honda Atheros Communications, INC. 2006.12 */ +/* */ +/************************************************************************/ +u16_t zfAggRxFreeBuf(zdev_t* dev, u16_t destroy) +{ + u16_t i; + zbuf_t* buf; + struct agg_tid_rx *tid_rx; + + TID_TX tid_tx; + //struct bufInfo *buf_info; + + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + for (i=0; itid_rx[i]; + + for(j=0; j <= ZM_AGG_BAW_SIZE; j++) + { + zmw_enter_critical_section(dev); + buf = tid_rx->frame[j].buf; + tid_rx->frame[j].buf = 0; + zmw_leave_critical_section(dev); + + if (buf) + { + zfwBufFree(dev, buf, 0); + } + } + + #if 0 + if ( tid_rx->baw_head != tid_rx->baw_tail ) + { + while (tid_rx->baw_head != tid_rx->baw_tail) + { + buf = tid_rx->frame[tid_rx->baw_tail].buf; + tid_rx->frame[tid_rx->baw_tail].buf = 0; + if (buf) + { + zfwBufFree(dev, buf, 0); + + zmw_enter_critical_section(dev); + tid_rx->frame[tid_rx->baw_tail].buf = 0; + zmw_leave_critical_section(dev); + } + zmw_enter_critical_section(dev); + //if (tid_rx->baw_size > 0)tid_rx->baw_size--; + tid_rx->baw_tail = (tid_rx->baw_tail + 1) & ZM_AGG_BAW_MASK; + tid_rx->seq_start++; + zmw_leave_critical_section(dev); + } + } + #endif + + zmw_enter_critical_section(dev); + tid_rx->seq_start = 0; + tid_rx->baw_head = tid_rx->baw_tail = 0; + tid_rx->aid = ZM_MAX_STA_SUPPORT; + zmw_leave_critical_section(dev); + + #ifdef ZM_ENABLE_AGGREGATION + #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW + if (tid_baw->enabled) { + zm_msg1_agg(ZM_LV_0, "Device down, clear BAW queue:", i); + BAW->disable(dev, tid_baw); + } + #endif + #endif + if (1 == wd->aggQPool[i]->aggQEnabled) { + tid_tx = wd->aggQPool[i]; + buf = zfAggTxGetVtxq(dev, tid_tx); + while (buf) { + zfwBufFree(dev, buf, 0); + buf = zfAggTxGetVtxq(dev, tid_tx); + } + } + + if(destroy) { + zfwMemFree(dev, wd->aggQPool[i], sizeof(struct aggQueue)); + zfwMemFree(dev, wd->tid_rx[i], sizeof(struct agg_tid_rx)); + } + } + #ifdef ZM_ENABLE_AGGREGATION + #ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW + if(destroy) zfwMemFree(dev, BAW, sizeof(struct baw_enabler)); + #endif + #endif + return ZM_SUCCESS; +} + + +void zfAggRecvBAR(zdev_t* dev, zbuf_t *buf) { + u16_t start_seq, len; + u8_t i, bitmap[8]; + len = zfwBufGetSize(dev, buf); + start_seq = zmw_rx_buf_readh(dev, buf, len-2); + DbgPrint("Received a BAR Control frame, start_seq=%d", start_seq>>4); + /* todo: set the bitmap by reordering buffer! */ + for (i=0; i<8; i++) bitmap[i]=0; + zfSendBA(dev, start_seq, bitmap); +} + +#ifdef ZM_ENABLE_AGGREGATION +#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW +void zfAggTxRetransmit(zdev_t* dev, struct bufInfo *buf_info, struct aggControl *aggControl, TID_TX tid_tx) { + u16_t removeLen; + u16_t err; + + zmw_get_wlan_dev(dev); + if (aggControl && (ZM_AGG_FIRST_MPDU == aggControl->ampduIndication) ) { + tid_tx->bar_ssn = buf_info->baw_header->header[15]; + aggControl->tid_baw->start_seq = tid_tx->bar_ssn >> 4; + zm_msg1_agg(ZM_LV_0, "start seq=", tid_tx->bar_ssn >> 4); + } + buf_info->baw_header->header[4] |= (1 << 11); + if (aggControl && aggControl->aggEnabled) { + //if (wd->enableAggregation==0 && !(buf_info->baw_header->header[6]&0x1)) + //{ + //if (((buf_info->baw_header->header[2] & 0x3) == 2)) + //{ + /* Enable aggregation */ + buf_info->baw_header->header[1] |= 0x20; + if (ZM_AGG_LAST_MPDU == aggControl->ampduIndication) { + buf_info->baw_header->header[1] |= 0x4000; + } + else { + buf_info->baw_header->header[1] &= ~0x4000; + //zm_debug_msg0("ZM_AGG_LAST_MPDU"); + } + //} + //else { + // zm_debug_msg1("no aggr, header[2]&0x3 = ",buf_info->baw_header->header[2] & 0x3) + // aggControl->aggEnabled = 0; + //} + //} + //else { + // zm_debug_msg1("no aggr, wd->enableAggregation = ", wd->enableAggregation); + // zm_debug_msg1("no aggr, !header[6]&0x1 = ",!(buf_info->baw_header->header[6]&0x1)); + // aggControl->aggEnabled = 0; + //} + } + + /*if (aggControl->tid_baw) { + struct baw_header_r header_r; + + header_r.header = buf_info->baw_header->header; + header_r.mic = buf_info->baw_header->mic; + header_r.snap = buf_info->baw_header->snap; + header_r.headerLen = buf_info->baw_header->headerLen; + header_r.micLen = buf_info->baw_header->micLen; + header_r.snapLen = buf_info->baw_header->snapLen; + header_r.removeLen = buf_info->baw_header->removeLen; + header_r.keyIdx = buf_info->baw_header->keyIdx; + + BAW->insert(dev, buf_info->buf, tid_tx->bar_ssn >> 4, aggControl->tid_baw, buf_info->baw_retransmit, &header_r); + }*/ + + if ((err = zfHpSend(dev, + buf_info->baw_header->header, + buf_info->baw_header->headerLen, + buf_info->baw_header->snap, + buf_info->baw_header->snapLen, + buf_info->baw_header->mic, + buf_info->baw_header->micLen, + buf_info->buf, + buf_info->baw_header->removeLen, + ZM_EXTERNAL_ALLOC_BUF, + (u8_t)tid_tx->ac, + buf_info->baw_header->keyIdx)) != ZM_SUCCESS) + { + goto zlError; + } + + return; + +zlError: + zfwBufFree(dev, buf_info->buf, 0); + return; + +} +#endif //disable BAW +#endif +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfAggTxSendEth */ +/* Called to transmit Ethernet frame from upper elayer. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : buffer pointer */ +/* port : WLAN port, 0=>standard, 0x10-0x17=>VAP, 0x20-0x25=>WDS */ +/* */ +/* OUTPUTS */ +/* error code */ +/* */ +/* AUTHOR */ +/* Stephen, Honda Atheros Communications, Inc. 2006.12 */ +/* */ +/************************************************************************/ +u16_t zfAggTxSendEth(zdev_t* dev, zbuf_t* buf, u16_t port, u16_t bufType, u8_t flag, struct aggControl *aggControl, TID_TX tid_tx) +{ + u16_t err; + //u16_t addrTblSize; + //struct zsAddrTbl addrTbl; + u16_t removeLen; + u16_t header[(8+30+2+18)/2]; /* ctr+(4+a1+a2+a3+2+a4)+qos+iv */ + u16_t headerLen; + u16_t mic[8/2]; + u16_t micLen; + u16_t snap[8/2]; + u16_t snapLen; + u16_t fragLen; + u16_t frameLen; + u16_t fragNum; + struct zsFrag frag; + u16_t i, id; + u16_t da[3]; + u16_t sa[3]; + u8_t up; + u8_t qosType, keyIdx = 0; + u16_t fragOff; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zm_msg1_tx(ZM_LV_2, "zfTxSendEth(), port=", port); + + /* Get IP TOS for QoS AC and IP frag offset */ + zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff); + +#ifdef ZM_ENABLE_NATIVE_WIFI + if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) + { + /* DA */ + da[0] = zmw_tx_buf_readh(dev, buf, 16); + da[1] = zmw_tx_buf_readh(dev, buf, 18); + da[2] = zmw_tx_buf_readh(dev, buf, 20); + /* SA */ + sa[0] = zmw_tx_buf_readh(dev, buf, 10); + sa[1] = zmw_tx_buf_readh(dev, buf, 12); + sa[2] = zmw_tx_buf_readh(dev, buf, 14); + } + else if ( wd->wlanMode == ZM_MODE_IBSS ) + { + /* DA */ + da[0] = zmw_tx_buf_readh(dev, buf, 4); + da[1] = zmw_tx_buf_readh(dev, buf, 6); + da[2] = zmw_tx_buf_readh(dev, buf, 8); + /* SA */ + sa[0] = zmw_tx_buf_readh(dev, buf, 10); + sa[1] = zmw_tx_buf_readh(dev, buf, 12); + sa[2] = zmw_tx_buf_readh(dev, buf, 14); + } + else if ( wd->wlanMode == ZM_MODE_AP ) + { + /* DA */ + da[0] = zmw_tx_buf_readh(dev, buf, 4); + da[1] = zmw_tx_buf_readh(dev, buf, 6); + da[2] = zmw_tx_buf_readh(dev, buf, 8); + /* SA */ + sa[0] = zmw_tx_buf_readh(dev, buf, 16); + sa[1] = zmw_tx_buf_readh(dev, buf, 18); + sa[2] = zmw_tx_buf_readh(dev, buf, 20); + } + else + { + // + } +#else + /* DA */ + da[0] = zmw_tx_buf_readh(dev, buf, 0); + da[1] = zmw_tx_buf_readh(dev, buf, 2); + da[2] = zmw_tx_buf_readh(dev, buf, 4); + /* SA */ + sa[0] = zmw_tx_buf_readh(dev, buf, 6); + sa[1] = zmw_tx_buf_readh(dev, buf, 8); + sa[2] = zmw_tx_buf_readh(dev, buf, 10); +#endif + //Decide Key Index in ATOM, No meaning in OTUS--CWYang(m) + if (wd->wlanMode == ZM_MODE_AP) + { + keyIdx = wd->ap.bcHalKeyIdx[port]; + id = zfApFindSta(dev, da); + if (id != 0xffff) + { + switch (wd->ap.staTable[id].encryMode) + { + case ZM_AES: + case ZM_TKIP: +#ifdef ZM_ENABLE_CENC + case ZM_CENC: +#endif //ZM_ENABLE_CENC + keyIdx = wd->ap.staTable[id].keyIdx; + break; + } + } + } + else + { + switch (wd->sta.encryMode) + { + case ZM_WEP64: + case ZM_WEP128: + case ZM_WEP256: + keyIdx = wd->sta.keyId; + break; + case ZM_AES: + case ZM_TKIP: + if ((da[0]& 0x1)) + keyIdx = 5; + else + keyIdx = 4; + break; +#ifdef ZM_ENABLE_CENC + case ZM_CENC: + keyIdx = wd->sta.cencKeyId; + break; +#endif //ZM_ENABLE_CENC + } + } + + /* Create SNAP */ + removeLen = zfTxGenWlanSnap(dev, buf, snap, &snapLen); + //zm_msg1_tx(ZM_LV_0, "fragOff=", fragOff); + + fragLen = wd->fragThreshold; + frameLen = zfwBufGetSize(dev, buf); + frameLen -= removeLen; + +#if 0 + /* Create MIC */ + if ( (wd->wlanMode == ZM_MODE_INFRASTRUCTURE)&& + (wd->sta.encryMode == ZM_TKIP) ) + { + if ( frameLen > fragLen ) + { + micLen = zfTxGenWlanTail(dev, buf, snap, snapLen, mic); + } + else + { + /* append MIC by HMAC */ + micLen = 8; + } + } + else + { + micLen = 0; + } +#else + if ( frameLen > fragLen ) + { + micLen = zfTxGenWlanTail(dev, buf, snap, snapLen, mic); + } + else + { + /* append MIC by HMAC */ + micLen = 0; + } +#endif + + /* Access Category */ + if (wd->wlanMode == ZM_MODE_AP) + { + zfApGetStaQosType(dev, da, &qosType); + if (qosType == 0) + { + up = 0; + } + } + else if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) + { + if (wd->sta.wmeConnected == 0) + { + up = 0; + } + } + else + { + /* TODO : STA QoS control field */ + up = 0; + } + + /* Assign sequence number */ + zmw_enter_critical_section(dev); + frag.seq[0] = ((wd->seq[zcUpToAc[up&0x7]]++) << 4); + if (aggControl && (ZM_AGG_FIRST_MPDU == aggControl->ampduIndication) ) { + tid_tx->bar_ssn = frag.seq[0]; + + zm_msg1_agg(ZM_LV_0, "start seq=", tid_tx->bar_ssn >> 4); + } + //tid_tx->baw_buf[tid_tx->baw_head-1].baw_seq=frag.seq[0]; + zmw_leave_critical_section(dev); + + + frag.buf[0] = buf; + frag.bufType[0] = bufType; + frag.flag[0] = flag; + fragNum = 1; + + for (i=0; i>1); i++) + { + zmw_tx_buf_writeh(dev, buf, i*2, header[i]); + } + + /* Get buffer DMA address */ + //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0) + //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0) + //{ + // goto zlError; + //} + + //zm_msg2_mm(ZM_LV_2, "offset=", offset); + //zm_msg2_mm(ZM_LV_2, "hlen=", hlen); + //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize); + //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]); + //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]); + //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data); + + #if 0 + if ((err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0, + ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS) + { + goto zlError; + } + #else + zfPutVmmq(dev, buf); + zfPushVtxq(dev); + #endif + + return ZM_SUCCESS; + +} + +u16_t zfAggSetAddbaFrameBody(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t ac, u16_t up) +{ + u16_t ba_parameter, start_seq; + + zmw_get_wlan_dev(dev); + + //zmw_declare_for_critical_section(); + /* + * ADDBA Request frame body + */ + + /* + * Category + */ + zmw_tx_buf_writeb(dev, buf, offset++, 3); + /* + * Action details = 0 + */ + zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_ADDBA_REQUEST_FRAME); + /* + * Dialog Token = nonzero + * TBD: define how to get dialog token? + */ + zmw_tx_buf_writeb(dev, buf, offset++, 2); + /* + * Block Ack parameter set + * BA policy = 1 for immediate BA, 0 for delayed BA + * TID(4bits) & buffer size(4bits) (TID=up & buffer size=0x80) + * TBD: how to get buffer size? + * ¢z¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢{ + * ¢x B0 ¢x B1 ¢x B2 B5 ¢x B6 B15 ¢x + * ¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t + * ¢x Reserved ¢x BA policy ¢x TID ¢x Buffer size ¢x + * ¢|¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢} + */ + ba_parameter = 1 << 12; // buffer size = 0x40(64) + ba_parameter |= up << 2; // tid = up + ba_parameter |= 2; // ba policy = 1 + zmw_tx_buf_writeh(dev, buf, offset, ba_parameter); + offset+=2; + /* + * BA timeout value + */ + zmw_tx_buf_writeh(dev, buf, offset, 0); + offset+=2; + /* + * BA starting sequence number + * ¢z¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢{ + * ¢x B0 B3 ¢x B4 B15 ¢x + * ¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t + * ¢x Frag num(0) ¢x BA starting seq num ¢x + * ¢|¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢} + */ + start_seq = ((wd->seq[ac]) << 4) & 0xFFF0; + zmw_tx_buf_writeh(dev, buf, offset, start_seq); + offset+=2; + + return offset; +} + +u16_t zfAggGenAddbaHeader(zdev_t* dev, u16_t* dst, + u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt) +{ + u8_t hlen = 32; // MAC ctrl + PHY ctrl + 802.11 MM header + //u8_t frameType = ZM_WLAN_FRAME_TYPE_ACTION; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + /* + * Generate control setting + */ + //bodyLen = zfwBufGetSize(dev, buf); + header[0] = 24+len+4; //Length + header[1] = 0x8; //MAC control, backoff + (ack) + +#if 0 + /* CCK 1M */ + header[2] = 0x0f00; //PHY control L + header[3] = 0x0000; //PHY control H +#else + /* OFDM 6M */ + header[2] = 0x0f01; //PHY control L + header[3] = 0x000B; //PHY control H +#endif + + /* + * Generate WLAN header + * Frame control frame type and subtype + */ + header[4+0] = ZM_WLAN_FRAME_TYPE_ACTION; + /* + * Duration + */ + header[4+1] = 0; + + if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) + { + header[4+8] = wd->sta.bssid[0]; + header[4+9] = wd->sta.bssid[1]; + header[4+10] = wd->sta.bssid[2]; + } + else if (wd->wlanMode == ZM_MODE_PSEUDO) + { + /* Address 3 = 00:00:00:00:00:00 */ + header[4+8] = 0; + header[4+9] = 0; + header[4+10] = 0; + } + else if (wd->wlanMode == ZM_MODE_IBSS) + { + header[4+8] = wd->sta.bssid[0]; + header[4+9] = wd->sta.bssid[1]; + header[4+10] = wd->sta.bssid[2]; + } + else if (wd->wlanMode == ZM_MODE_AP) + { + /* Address 3 = BSSID */ + header[4+8] = wd->macAddr[0]; + header[4+9] = wd->macAddr[1]; + header[4+10] = wd->macAddr[2] + (vap<<8); + } + + /* Address 1 = DA */ + header[4+2] = dst[0]; + header[4+3] = dst[1]; + header[4+4] = dst[2]; + + /* Address 2 = SA */ + header[4+5] = wd->macAddr[0]; + header[4+6] = wd->macAddr[1]; + if (wd->wlanMode == ZM_MODE_AP) + { + header[4+7] = wd->macAddr[2] + (vap<<8); + } + else + { + header[4+7] = wd->macAddr[2]; + } + + /* Sequence Control */ + zmw_enter_critical_section(dev); + header[4+11] = ((wd->mmseq++)<<4); + zmw_leave_critical_section(dev); + + + return hlen; +} + + +u16_t zfAggProcessAction(zdev_t* dev, zbuf_t* buf) +{ + u16_t category; + + //zmw_get_wlan_dev(dev); + + //zmw_declare_for_critical_section(); + + category = zmw_rx_buf_readb(dev, buf, 24); + + switch (category) + { + case ZM_WLAN_BLOCK_ACK_ACTION_FRAME: + zfAggBlockAckActionFrame(dev, buf); + break; + + } + + return ZM_SUCCESS; +} + + +u16_t zfAggBlockAckActionFrame(zdev_t* dev, zbuf_t* buf) +{ + u8_t action; + + //zmw_get_wlan_dev(dev); + + //zmw_declare_for_critical_section(); + + action = zmw_rx_buf_readb(dev, buf, 25); +#ifdef ZM_ENABLE_AGGREGATION + switch (action) + { + case ZM_WLAN_ADDBA_REQUEST_FRAME: + zm_msg0_agg(ZM_LV_0, "Received BA Action frame is ADDBA request"); + zfAggRecvAddbaRequest(dev, buf); + break; + case ZM_WLAN_ADDBA_RESPONSE_FRAME: + zm_msg0_agg(ZM_LV_0, "Received BA Action frame is ADDBA response"); + zfAggRecvAddbaResponse(dev, buf); + break; + case ZM_WLAN_DELBA_FRAME: + zfAggRecvDelba(dev, buf); + break; + } +#endif + return ZM_SUCCESS; +} + +u16_t zfAggRecvAddbaRequest(zdev_t* dev, zbuf_t* buf) +{ + //u16_t dialog; + struct aggBaFrameParameter bf; + u16_t i; + //zmw_get_wlan_dev(dev); + + //zmw_declare_for_critical_section(); + + bf.buf = buf; + bf.dialog = zmw_rx_buf_readb(dev, buf, 26); + /* + * ba parameter set + */ + bf.ba_parameter = zmw_rx_buf_readh(dev, buf, 27); + bf.ba_policy = (bf.ba_parameter >> 1) & 1; + bf.tid = (bf.ba_parameter >> 2) & 0xF; + bf.buffer_size = (bf.ba_parameter >> 6); + /* + * BA timeout value + */ + bf.ba_timeout = zmw_rx_buf_readh(dev, buf, 29); + /* + * BA starting sequence number + */ + bf.ba_start_seq = zmw_rx_buf_readh(dev, buf, 31) >> 4; + + i=26; + while(i < 32) { + zm_debug_msg2("Recv ADDBA Req:", zmw_rx_buf_readb(dev,buf,i)); + i++; + } + + zfAggSendAddbaResponse(dev, &bf); + + zfAggAddbaSetTidRx(dev, buf, &bf); + + return ZM_SUCCESS; +} + +u16_t zfAggAddbaSetTidRx(zdev_t* dev, zbuf_t* buf, struct aggBaFrameParameter *bf) +{ + u16_t i, ac, aid, fragOff; + u16_t src[3]; + u16_t offset = 0; + u8_t up; + struct agg_tid_rx *tid_rx = NULL; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + src[0] = zmw_rx_buf_readh(dev, buf, offset+10); + src[1] = zmw_rx_buf_readh(dev, buf, offset+12); + src[2] = zmw_rx_buf_readh(dev, buf, offset+14); + aid = zfApFindSta(dev, src); + + zfTxGetIpTosAndFrag(dev, buf, &up, &fragOff); + ac = zcUpToAc[up&0x7] & 0x3; + + ac = bf->tid; + + for (i=0; itid_rx[i]->aid == aid) && (wd->tid_rx[i]->ac == ac)) + { + tid_rx = wd->tid_rx[i]; + break; + } + } + + if (!tid_rx) + { + for (i=0; itid_rx[i]->aid == ZM_MAX_STA_SUPPORT) + { + tid_rx = wd->tid_rx[i]; + break; + } + } + if (!tid_rx) + return 0; + } + + zmw_enter_critical_section(dev); + + tid_rx->aid = aid; + tid_rx->ac = ac; + tid_rx->addBaExchangeStatusCode = ZM_AGG_ADDBA_RESPONSE; + tid_rx->seq_start = bf->ba_start_seq; + tid_rx->baw_head = tid_rx->baw_tail = 0; + tid_rx->sq_exceed_count = tid_rx->sq_behind_count = 0; + zmw_leave_critical_section(dev); + + return 0; +} + +u16_t zfAggRecvAddbaResponse(zdev_t* dev, zbuf_t* buf) +{ + u16_t i,ac, aid=0; + u16_t src[3]; + struct aggBaFrameParameter bf; + + zmw_get_wlan_dev(dev); + + //zmw_declare_for_critical_section(); + + src[0] = zmw_rx_buf_readh(dev, buf, 10); + src[1] = zmw_rx_buf_readh(dev, buf, 12); + src[2] = zmw_rx_buf_readh(dev, buf, 14); + + if (wd->wlanMode == ZM_MODE_AP) + aid = zfApFindSta(dev, src); + + + bf.buf = buf; + bf.dialog = zmw_rx_buf_readb(dev, buf, 26); + bf.status_code = zmw_rx_buf_readh(dev, buf, 27); + if (!bf.status_code) + { + wd->addbaComplete=1; + } + + /* + * ba parameter set + */ + bf.ba_parameter = zmw_rx_buf_readh(dev, buf, 29); + bf.ba_policy = (bf.ba_parameter >> 1) & 1; + bf.tid = (bf.ba_parameter >> 2) & 0xF; + bf.buffer_size = (bf.ba_parameter >> 6); + /* + * BA timeout value + */ + bf.ba_timeout = zmw_rx_buf_readh(dev, buf, 31); + + i=26; + while(i < 32) { + zm_debug_msg2("Recv ADDBA Rsp:", zmw_rx_buf_readb(dev,buf,i)); + i++; + } + + ac = zcUpToAc[bf.tid&0x7] & 0x3; + + //zmw_enter_critical_section(dev); + + //wd->aggSta[aid].aggFlag[ac] = 0; + + //zmw_leave_critical_section(dev); + + return ZM_SUCCESS; +} + +u16_t zfAggRecvDelba(zdev_t* dev, zbuf_t* buf) +{ + //zmw_get_wlan_dev(dev); + + //zmw_declare_for_critical_section(); + return ZM_SUCCESS; +} + +u16_t zfAggSendAddbaResponse(zdev_t* dev, struct aggBaFrameParameter *bf) +{ + zbuf_t* buf; + //u16_t addrTblSize; + //struct zsAddrTbl addrTbl; + //u16_t err; + u16_t offset = 0; + u16_t hlen = 32; + u16_t header[(24+25+1)/2]; + u16_t vap = 0; + u16_t i; + u8_t encrypt = 0; + u16_t dst[3]; + + //zmw_get_wlan_dev(dev); + + //zmw_declare_for_critical_section(); + + + /* + * TBD : Maximum size of managment frame + */ + if ((buf = zfwBufAllocate(dev, 1024)) == NULL) + { + zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!"); + return ZM_SUCCESS; + } + + /* + * Reserve room for wlan header + */ + offset = hlen; + + /* + * add addba frame body + */ + offset = zfAggSetAddbaResponseFrameBody(dev, buf, bf, offset); + + + zfwBufSetSize(dev, buf, offset); + + /* + * Copy wlan header + */ + + dst[0] = zmw_rx_buf_readh(dev, bf->buf, 10); + dst[1] = zmw_rx_buf_readh(dev, bf->buf, 12); + dst[2] = zmw_rx_buf_readh(dev, bf->buf, 14); + zfAggGenAddbaHeader(dev, dst, header, offset-hlen, buf, vap, encrypt); + for (i=0; i<(hlen>>1); i++) + { + zmw_tx_buf_writeh(dev, buf, i*2, header[i]); + } + + /* Get buffer DMA address */ + //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0) + //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0) + //{ + // goto zlError; + //} + + //zm_msg2_mm(ZM_LV_2, "offset=", offset); + //zm_msg2_mm(ZM_LV_2, "hlen=", hlen); + //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize); + //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]); + //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]); + //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data); + + #if 0 + if ((err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0, + ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS) + { + goto zlError; + } + #else + zfPutVmmq(dev, buf); + zfPushVtxq(dev); + #endif + + //zfAggSendAddbaRequest(dev, dst, zcUpToAc[bf->tid&0x7] & 0x3, bf->tid); + return ZM_SUCCESS; + +} + +u16_t zfAggSetAddbaResponseFrameBody(zdev_t* dev, zbuf_t* buf, + struct aggBaFrameParameter *bf, u16_t offset) +{ + + //zmw_get_wlan_dev(dev); + + //zmw_declare_for_critical_section(); + /* + * ADDBA Request frame body + */ + + /* + * Category + */ + zmw_tx_buf_writeb(dev, buf, offset++, 3); + /* + * Action details = 0 + */ + zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_ADDBA_RESPONSE_FRAME); + /* + * Dialog Token = nonzero + */ + zmw_tx_buf_writeb(dev, buf, offset++, bf->dialog); + /* + * Status code + */ + zmw_tx_buf_writeh(dev, buf, offset, 0); + offset+=2; + /* + * Block Ack parameter set + * BA policy = 1 for immediate BA, 0 for delayed BA + * TID(4bits) & buffer size(4bits) (TID=0x1 & buffer size=0x80) + * TBD: how to get TID number and buffer size? + * ¢z¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢{ + * ¢x B0 ¢x B1 ¢x B2 B5 ¢x B6 B15 ¢x + * ¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t + * ¢x Reserved ¢x BA policy ¢x TID ¢x Buffer size ¢x + * ¢|¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢} + */ + zmw_tx_buf_writeh(dev, buf, offset, bf->ba_parameter); + offset+=2; + /* + * BA timeout value + */ + zmw_tx_buf_writeh(dev, buf, offset, bf->ba_timeout); + offset+=2; + + return offset; +} + +void zfAggInvokeBar(zdev_t* dev, TID_TX tid_tx) +{ + struct aggBarControl aggBarControl; + //zmw_get_wlan_dev(dev); + + //zmw_declare_for_critical_section(); + //bar_control = aggBarControl->tid_info << 12 | aggBarControl->compressed_bitmap << 2 + // | aggBarControl->multi_tid << 1 | aggBarControl->bar_ack_policy; + aggBarControl.bar_ack_policy = 0; + aggBarControl.multi_tid = 0; + aggBarControl.compressed_bitmap = 0; + aggBarControl.tid_info = tid_tx->tid; + zfAggSendBar(dev, tid_tx, &aggBarControl); + + return; + +} +/* + * zfAggSendBar() refers zfAggSendAddbaRequest() + */ +u16_t zfAggSendBar(zdev_t* dev, TID_TX tid_tx, struct aggBarControl *aggBarControl) +{ + zbuf_t* buf; + //u16_t addrTblSize; + //struct zsAddrTbl addrTbl; + //u16_t err; + u16_t offset = 0; + u16_t hlen = 16+8; /* mac header + control headers*/ + u16_t header[(8+24+1)/2]; + u16_t vap = 0; + u16_t i; + u8_t encrypt = 0; + + //zmw_get_wlan_dev(dev); + + //zmw_declare_for_critical_section(); + + + /* + * TBD : Maximum size of managment frame + */ + if ((buf = zfwBufAllocate(dev, 1024)) == NULL) + { + zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!"); + return ZM_SUCCESS; + } + + /* + * Reserve room for wlan header + */ + offset = hlen; + + /* + * add addba frame body + */ + offset = zfAggSetBarBody(dev, buf, offset, tid_tx, aggBarControl); + + + zfwBufSetSize(dev, buf, offset); + + /* + * Copy wlan header + */ + zfAggGenBarHeader(dev, tid_tx->dst, header, offset-hlen, buf, vap, encrypt); + for (i=0; i<(hlen>>1); i++) + { + zmw_tx_buf_writeh(dev, buf, i*2, header[i]); + } + + /* Get buffer DMA address */ + //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0) + //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0) + //{ + // goto zlError; + //} + + //zm_msg2_mm(ZM_LV_2, "offset=", offset); + //zm_msg2_mm(ZM_LV_2, "hlen=", hlen); + //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize); + //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]); + //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]); + //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data); + + #if 0 + if ((err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0, + ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS) + { + goto zlError; + } + #else + zfPutVmmq(dev, buf); + zfPushVtxq(dev); + #endif + + return ZM_SUCCESS; + +} + +u16_t zfAggSetBarBody(zdev_t* dev, zbuf_t* buf, u16_t offset, TID_TX tid_tx, struct aggBarControl *aggBarControl) +{ + u16_t bar_control, start_seq; + + //zmw_get_wlan_dev(dev); + + //zmw_declare_for_critical_section(); + /* + * BAR Control frame body + */ + + /* + * BAR Control Field + * ¢z¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢{ + * ¢x B0 ¢x B1 ¢x B2 ¢x B3 B11 ¢x B12 B15 ¢x + * ¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t + * ¢x BAR Ack ¢x Multi-TID ¢x Compressed ¢x Reserved ¢x TID_INFO ¢x + * ¢x Policy ¢x ¢x Bitmap ¢x ¢x ¢x + * ¢|¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢} + */ + bar_control = aggBarControl->tid_info << 12 | aggBarControl->compressed_bitmap << 2 + | aggBarControl->multi_tid << 1 | aggBarControl->bar_ack_policy; + + zmw_tx_buf_writeh(dev, buf, offset, bar_control); + offset+=2; + if (0 == aggBarControl->multi_tid) { + /* + * BA starting sequence number + * ¢z¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢{ + * ¢x B0 B3 ¢x B4 B15 ¢x + * ¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t + * ¢x Frag num(0) ¢x BA starting seq num ¢x + * ¢|¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢} + */ + start_seq = (tid_tx->bar_ssn << 4) & 0xFFF0; + zmw_tx_buf_writeh(dev, buf, offset, start_seq); + offset+=2; + } + if (1 == aggBarControl->multi_tid && 1 == aggBarControl->compressed_bitmap) { + /* multi-tid BlockAckReq variant, not implemented*/ + } + + return offset; +} + +u16_t zfAggGenBarHeader(zdev_t* dev, u16_t* dst, + u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt) +{ + u8_t hlen = 16+8; // MAC ctrl + PHY ctrl + 802.11 MM header + //u8_t frameType = ZM_WLAN_FRAME_TYPE_ACTION; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + /* + * Generate control setting + */ + //bodyLen = zfwBufGetSize(dev, buf); + header[0] = 16+len+4; //Length + header[1] = 0x8; //MAC control, backoff + (ack) + +#if 1 + /* CCK 1M */ + header[2] = 0x0f00; //PHY control L + header[3] = 0x0000; //PHY control H +#else + /* CCK 6M */ + header[2] = 0x0f01; //PHY control L + header[3] = 0x000B; //PHY control H + +#endif + /* + * Generate WLAN header + * Frame control frame type and subtype + */ + header[4+0] = ZM_WLAN_FRAME_TYPE_BAR; + /* + * Duration + */ + header[4+1] = 0; + + /* Address 1 = DA */ + header[4+2] = dst[0]; + header[4+3] = dst[1]; + header[4+4] = dst[2]; + + /* Address 2 = SA */ + header[4+5] = wd->macAddr[0]; + header[4+6] = wd->macAddr[1]; + if (wd->wlanMode == ZM_MODE_AP) + { +#ifdef ZM_VAPMODE_MULTILE_SSID + header[4+7] = wd->macAddr[2]; //Multiple SSID +#else + header[4+7] = wd->macAddr[2] + (vap<<8); //VAP +#endif + } + else + { + header[4+7] = wd->macAddr[2]; + } + + /* Sequence Control */ + zmw_enter_critical_section(dev); + header[4+11] = ((wd->mmseq++)<<4); + zmw_leave_critical_section(dev); + + + return hlen; +} --- linux-2.6.28.orig/drivers/staging/otus/80211core/cinit.c +++ linux-2.6.28/drivers/staging/otus/80211core/cinit.c @@ -0,0 +1,1911 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* */ +/* Module Name : init.c */ +/* */ +/* Abstract */ +/* This module contains init functions. */ +/* */ +/* NOTES */ +/* None */ +/* */ +/************************************************************************/ +#include "cprecomp.h" +#include "../hal/hpreg.h" + +extern const u8_t zcUpToAc[8]; + +u16_t zcIndextoRateBG[16] = {1000, 2000, 5500, 11000, 0, 0, 0, 0, 48000, + 24000, 12000, 6000, 54000, 36000, 18000, 9000}; +u32_t zcIndextoRateN20L[16] = {6500, 13000, 19500, 26000, 39000, 52000, 58500, + 65000, 13000, 26000, 39000, 52000, 78000, 104000, + 117000, 130000}; +u32_t zcIndextoRateN20S[16] = {7200, 14400, 21700, 28900, 43300, 57800, 65000, + 72200, 14400, 28900, 43300, 57800, 86700, 115600, + 130000, 144400}; +u32_t zcIndextoRateN40L[16] = {13500, 27000, 40500, 54000, 81000, 108000, 121500, + 135000, 27000, 54000, 81000, 108000, 162000, 216000, + 243000, 270000}; +u32_t zcIndextoRateN40S[16] = {15000, 30000, 45000, 60000, 90000, 120000, 135000, + 150000, 30000, 60000, 90000, 120000, 180000, 240000, + 270000, 300000}; + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfTxGenWlanHeader */ +/* Generate WLAN MAC header and LLC header. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : buffer pointer */ +/* id : Index of TxD */ +/* port : WLAN port */ +/* */ +/* OUTPUTS */ +/* length of removed Ethernet header */ +/* */ +/* AUTHOR */ +/* Stephen ZyDAS Technology Corporation 2005.5 */ +/* */ +/************************************************************************/ +u16_t zfTxGenWlanHeader(zdev_t* dev, zbuf_t* buf, u16_t* header, u16_t seq, + u8_t flag, u16_t plusLen, u16_t minusLen, u16_t port, + u16_t* da, u16_t* sa, u8_t up, u16_t *micLen, + u16_t* snap, u16_t snapLen, struct aggControl *aggControl) +{ + + u16_t len; + u16_t macCtrl; + u32_t phyCtrl; + u16_t hlen = 16; + u16_t icvLen = 0; + u16_t wdsPortId; + u16_t vap = 0; + u16_t mcs = 0; + u16_t mt = 0; + u8_t qosType; + u8_t b1, b2; + u16_t wdsPort; + u8_t encExemptionActionType; + u16_t rateProbingFlag = 0; + u8_t tkipFrameOffset = 0; + +#ifdef ZM_ENABLE_IBSS_WPA2PSK + u8_t res, peerIdx; + u8_t userIdx=0; + u16_t *iv16; + u32_t *iv32; +#endif + + zmw_get_wlan_dev(dev); + + /* Generate WLAN header */ + /* Frame control */ + header[4] = 0x0008 | (flag<<8); + /* Duration */ + header[5] = 0x0000; + + if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) + { + /* ToDS bit */ + header[4] |= 0x0100; + + /*Sometimes we wake up to tx/rx but AP still think we are sleeping, so still need to set this bit*/ + if ( zfPowerSavingMgrIsSleeping(dev) || wd->sta.psMgr.tempWakeUp == 1 ) + { + header[4] |= 0x1000; + } + + /* Address 1 = BSSID */ + header[6] = wd->sta.bssid[0]; + header[7] = wd->sta.bssid[1]; + header[8] = wd->sta.bssid[2]; + /* Address 3 = DA */ + header[12] = da[0]; + header[13] = da[1]; + header[14] = da[2]; + } + else if (wd->wlanMode == ZM_MODE_PSEUDO) + { + /* Address 1 = DA */ + header[6] = da[0]; + header[7] = da[1]; + header[8] = da[2]; + /* Address 3 = 00:00:00:00:00:00 */ + header[12] = 0; + header[13] = 0; + header[14] = 0; + + /* PSEUDO test : WDS */ + if (wd->enableWDS) + { + /* ToDS and FromDS bit */ + header[4] |= 0x0300; + + /* Address 4 = SA */ + header[16] = 0; + header[17] = 0; + header[18] = 0; + + hlen = 19; + } + } + else if (wd->wlanMode == ZM_MODE_IBSS) + { + /* Address 1 = DA */ + header[6] = da[0]; + header[7] = da[1]; + header[8] = da[2]; + /* Address 3 = BSSID */ + header[12] = wd->sta.bssid[0]; + header[13] = wd->sta.bssid[1]; + header[14] = wd->sta.bssid[2]; + +#ifdef ZM_ENABLE_IBSS_WPA2PSK + zmw_enter_critical_section(dev); + res = zfStaFindOppositeByMACAddr(dev, da, &peerIdx); + if(res == 0) // Find opposite in our OppositeInfo Structure ! + { + userIdx = peerIdx; + } + zmw_leave_critical_section(dev); +#endif + } + else if (wd->wlanMode == ZM_MODE_AP) + { + if (port < 0x20) + /* AP mode */ + { + /* FromDS bit */ + header[4] |= 0x0200; + + /* Address 1 = DA */ + header[6] = da[0]; + header[7] = da[1]; + header[8] = da[2]; + /* Address 3 = SA */ + header[12] = sa[0]; + header[13] = sa[1]; + header[14] = sa[2]; + + if (port < ZM_MAX_AP_SUPPORT) + { + vap = port; + header[14] += (vap<<8); + } + } + else + /* WDS port */ + { + /* ToDS and FromDS bit */ + header[4] |= 0x0300; + + wdsPortId = port - 0x20; + + /* Address 1 = RA */ + header[6] = wd->ap.wds.macAddr[wdsPortId][0]; + header[7] = wd->ap.wds.macAddr[wdsPortId][1]; + header[8] = wd->ap.wds.macAddr[wdsPortId][2]; + /* Address 3 = DA */ + header[12] = da[0]; + header[13] = da[1]; + header[14] = da[2]; + /* Address 4 = SA */ + header[16] = sa[0]; + header[17] = sa[1]; + header[18] = sa[2]; + + hlen = 19; + } + } /* else if (wd->wlanMode == ZM_MODE_AP) */ + + /* Address 2 = TA */ + header[9] = wd->macAddr[0]; + header[10] = wd->macAddr[1]; +#ifdef ZM_VAPMODE_MULTILE_SSID + header[11] = wd->macAddr[2]; //Multiple SSID +#else + header[11] = wd->macAddr[2] + (vap<<8); //VAP +#endif + + if ( (wd->wlanMode == ZM_MODE_IBSS) && (wd->XLinkMode) ) + { + header[9] = sa[0]; + header[10] = sa[1]; + header[11] = sa[2]; + } + + /* Sequence Control */ + header[15] = seq; + + + if (wd->wlanMode == ZM_MODE_AP) + { + zfApGetStaTxRateAndQosType(dev, da, &phyCtrl, &qosType, &rateProbingFlag); + mt = (u16_t)(phyCtrl & 0x3); + mcs = (u16_t)((phyCtrl >> 16) & 0x3f); +#if 1 + //zfApGetStaQosType(dev, da, &qosType); + + /* if DA == WME STA */ + if (qosType == 1) + { + /* QoS data */ + header[4] |= 0x0080; + + /* QoS Control */ + header[hlen] = up; + hlen += 1; + } +#endif + } + +#if 0 + //AGG Test Code + if (header[6] == 0x8000) + { + /* QoS data */ + header[4] |= 0x0080; + + /* QoS Control */ + header[hlen] = 0; + hlen += 1; + } +#endif + + if (wd->wlanMode == ZM_MODE_AP) { + /* Todo: rate control here for qos field */ + } + else { + /* Rate control */ + zfStaGetTxRate(dev, da, &phyCtrl, &rateProbingFlag); + mt = (u16_t)(phyCtrl & 0x3); + mcs = (u16_t)((phyCtrl >> 16) & 0x3f); + } + + if (wd->txMCS != 0xff) + { + /* fixed rate */ + phyCtrl = ((u32_t)wd->txMCS<<16) + wd->txMT; + mcs = wd->txMCS; + mt = wd->txMT; + } + + if (wd->enableAggregation) + { + /* force enable aggregation */ + if (wd->enableAggregation==2 && !(header[6]&0x1)) + { + /* QoS data */ + header[4] |= 0x0080; + + /* QoS Control */ + header[hlen] = 0; + hlen += 1; + } + /* if wd->enableAggregation=1 => force disable */ + /* if wd->enableAggregation=0 => auto */ + } + +#ifdef ZM_ENABLE_AGGREGATION + /* + * aggregation control + */ + + /* + * QoS data + */ + if (wd->wlanMode == ZM_MODE_AP) { + if (aggControl && mt == 2) { + if (wd->enableAggregation==0 && !(header[6]&0x1)) + { + header[4] |= 0x0080; + + /* + * QoS Control + */ + header[hlen] = 0; + hlen += 1; + } + } + } +#endif + + // MSDU Length + len = zfwBufGetSize(dev, buf); + + /* Generate control setting */ + /* Backoff, Non-Burst and hardware duration */ + macCtrl = 0x208; + + /* ACK */ + if ((header[6] & 0x1) == 0x1) + { + /* multicast frame : Set NO-ACK bit */ + macCtrl |= 0x4; + } + else + { + /* unicast frame */ + #if 0 + // Enable RTS according to MPDU Lengths ( not MSDU Lengths ) + if (len >= wd->rtsThreshold) + { + /* Enable RTS */ + macCtrl |= 1; + } + #endif + } + /* VAP test code */ + //macCtrl |= 0x4; + + if (wd->wlanMode == ZM_MODE_AP) + { + u8_t encryType; + u16_t iv16; + u32_t iv32; + + /* Check whether this is a multicast frame */ + if ((header[6] & 0x1) == 0x1) + { + /* multicast frame */ + if (wd->ap.encryMode[vap] == ZM_TKIP) + { + wd->ap.iv16[vap]++; + + if(wd->ap.iv16[vap] == 0) + { + wd->ap.iv32[vap]++; + } + + b1 = (u8_t) (wd->ap.iv16[vap] >> 8); + b2 = (b1 | 0x20) & 0x7f; + header[hlen] = ((u16_t)b2 << 8) + b1; + b1 = (u8_t) wd->ap.iv16[vap]; + b2 = 0x20 | (wd->ap.bcKeyIndex[vap] << 6); + header[hlen+1] = ((u16_t)b2 << 8) + b1; + header[hlen+2] = (u16_t) wd->ap.iv32[vap]; + header[hlen+3] = (u16_t) (wd->ap.iv32[vap] >> 16); + + //macCtrl |= 0x80; + macCtrl |= 0x40; + icvLen = 4; + + /* set hardware MIC */ + if ( (!(seq & 0xf))&&(!(flag & 0x4)) ) + { + macCtrl |= 0x100; + plusLen += 8; + *micLen = 8; + } + + header[4] |= 0x4000; + hlen += 4; + } + else if (wd->ap.encryMode[vap] == ZM_AES) + { + wd->ap.iv16[vap]++; + + if(wd->ap.iv16[vap] == 0) + { + wd->ap.iv32[vap]++; + } + + b1 = (u8_t) wd->ap.iv16[vap]; + b2 = (u8_t) (wd->ap.iv16[vap] >> 8); + header[hlen] = ((u16_t)b2 << 8) + b1; + header[hlen+1] = 0x2000 | (wd->ap.bcKeyIndex[vap] << 14); + header[hlen+2] = (u16_t) (wd->ap.iv32[vap]); + header[hlen+3] = (u16_t) (wd->ap.iv32[vap] >> 16); + + macCtrl |= 0xc0; + icvLen = 8; /* MIC */ + + header[4] |= 0x4000; + hlen += 4; + } + #ifdef ZM_ENABLE_CENC + else if (wd->ap.encryMode[vap] == ZM_CENC) + { + //u32_t txiv[4]; + + wd->ap.txiv[vap][0]++; + + if (wd->ap.txiv[vap][0] == 0) + { + wd->ap.txiv[vap][1]++; + } + + if (wd->ap.txiv[vap][1] == 0) + { + wd->ap.txiv[vap][2]++; + } + + if (wd->ap.txiv[vap][2] == 0) + { + wd->ap.txiv[vap][3]++; + } + + if (wd->ap.txiv[vap][3] == 0) + { + wd->ap.txiv[vap][0] = 0; + wd->ap.txiv[vap][1] = 0; + wd->ap.txiv[vap][2] = 0; + } + + header[hlen] = (wd->ap.bcKeyIndex[vap] & 0x0001); /* For Key Id and reserved field */ + header[hlen+1] = (u16_t)wd->ap.txiv[vap][0]; + header[hlen+2] = (u16_t)(wd->ap.txiv[vap][0] >> 16); + header[hlen+3] = (u16_t)wd->ap.txiv[vap][1]; + header[hlen+4] = (u16_t)(wd->ap.txiv[vap][1] >> 16); + header[hlen+5] = (u16_t)wd->ap.txiv[vap][2]; + header[hlen+6] = (u16_t)(wd->ap.txiv[vap][2] >> 16); + header[hlen+7] = (u16_t)wd->ap.txiv[vap][3]; + header[hlen+8] = (u16_t)(wd->ap.txiv[vap][3] >> 16); + + macCtrl |= 0x80; + icvLen = 16; /* MIC */ + + header[4] |= 0x4000; + hlen += 9; + } + #endif //ZM_ENABLE_CENC + } + else + { + /* Get STA's encryption type */ + zfApGetStaEncryType(dev, da, &encryType); + + if (encryType == ZM_TKIP) + { + /* Get iv16 and iv32 */ + zfApGetStaWpaIv(dev, da, &iv16, &iv32); + + iv16++; + if (iv16 == 0) + { + iv32++; + } + + b1 = (u8_t) (iv16 >> 8); + b2 = (b1 | 0x20) & 0x7f; + header[hlen] = ((u16_t)b2 << 8) + b1; + b1 = (u8_t) iv16; + b2 = 0x20; + header[hlen+1] = ((u16_t)b2 << 8) + b1; + header[hlen+2] = (u16_t) iv32; + header[hlen+3] = (u16_t) (iv32 >> 16); + + //macCtrl |= 0x80; + macCtrl |= 0x40; + icvLen = 4; + + /* set hardware MIC */ + if ( (!(seq & 0xf))&&(!(flag & 0x4)) ) + { + macCtrl |= 0x100; + plusLen += 8; + *micLen = 8; + } + + header[4] |= 0x4000; + hlen += 4; + + /* Set iv16 and iv32 */ + zfApSetStaWpaIv(dev, da, iv16, iv32); + } + else if (encryType == ZM_AES) + { + /* Get iv16 and iv32 */ + zfApGetStaWpaIv(dev, da, &iv16, &iv32); + + iv16++; + if (iv16 == 0) + { + iv32++; + } + + b1 = (u8_t) iv16; + b2 = (u8_t) (iv16 >> 8); + header[hlen] = ((u16_t)b2 << 8) + b1; + header[hlen+1] = 0x2000; + header[hlen+2] = (u16_t) (iv32); + header[hlen+3] = (u16_t) (iv32 >> 16); + + macCtrl |= 0xc0; + icvLen = 8; /* MIC */ + + header[4] |= 0x4000; + hlen += 4; + + /* Set iv16 and iv32 */ + zfApSetStaWpaIv(dev, da, iv16, iv32); + } + #ifdef ZM_ENABLE_CENC + else if (encryType == ZM_CENC) + { + u32_t txiv[4]; + u8_t keyIdx; + + /* Get CENC TxIV */ + zfApGetStaCencIvAndKeyIdx(dev, da, txiv, &keyIdx); + + txiv[0] += 2; + + if (txiv[0] == 0 || txiv[0] == 1) + { + txiv[1]++; + } + + if (txiv[1] == 0) + { + txiv[2]++; + } + + if (txiv[2] == 0) + { + txiv[3]++; + } + + if (txiv[3] == 0) + { + txiv[0] = 0; + txiv[1] = 0; + txiv[2] = 0; + } + + header[hlen] = (keyIdx & 0x0001); /* For Key Id and reserved field */ + header[hlen+1] = (u16_t)txiv[0]; + header[hlen+2] = (u16_t)(txiv[0] >> 16); + header[hlen+3] = (u16_t)txiv[1]; + header[hlen+4] = (u16_t)(txiv[1] >> 16); + header[hlen+5] = (u16_t)txiv[2]; + header[hlen+6] = (u16_t)(txiv[2] >> 16); + header[hlen+7] = (u16_t)txiv[3]; + header[hlen+8] = (u16_t)(txiv[3] >> 16); + + macCtrl |= 0x80; + icvLen = 16; /* MIC */ + + header[4] |= 0x4000; + hlen += 9; + + /* Set CENC IV */ + zfApSetStaCencIv(dev, da, txiv); + } + #endif //ZM_ENABLE_CENC + } + + /* protection mode */ + if (wd->ap.protectionMode == 1) + { + /* Enable Self-CTS */ + macCtrl &= 0xFFFC; + macCtrl |= 2; + } + + /* Rate Control */ + if (port < 0x20) + { + /* AP */ + /* IV */ + if ((wd->ap.encryMode[vap] == ZM_WEP64) || + (wd->ap.encryMode[vap] == ZM_WEP128) || + (wd->ap.encryMode[vap] == ZM_WEP256)) + { + header[4] |= 0x4000; + header[hlen] = 0x0; //IV + header[hlen+1] = wd->ap.bcKeyIndex[vap] << 14; //IV with Keyid--CWYang(m) + hlen += 2; + icvLen = 4; + macCtrl |= 0x40; + } + } + else + { + /* WDS */ + + /* TODO : Fixed rate to 54M */ + phyCtrl = 0xc0001; //PHY control L + + /* WDS port checking */ + if ((wdsPort = (port - 0x20)) >= ZM_MAX_WDS_SUPPORT) + { + wdsPort = 0; + } + + #if 1 + /* IV */ + switch (wd->ap.wds.encryMode[wdsPort]) + { + case ZM_WEP64: + case ZM_WEP128: + case ZM_WEP256: + header[4] |= 0x4000; + header[hlen] = 0x0; //IV + header[hlen+1] = wd->ap.bcKeyIndex[vap] << 14; //IV with Keyid + hlen += 2; + icvLen = 4; + macCtrl |= 0x40; + break; + + case ZM_TKIP: + wd->sta.iv16++; + + if ( wd->sta.iv16 == 0 ) + { + wd->sta.iv32++; + } + + b1 = (u8_t) (wd->sta.iv16 >> 8); + b2 = (b1 | 0x20) & 0x7f; + header[hlen] = ((u16_t)b2 << 8) + b1; + b1 = (u8_t) wd->sta.iv16; + b2 = 0x20; + header[hlen+1] = ((u16_t)b2 << 8) + b1; + header[hlen+2] = (u16_t) wd->sta.iv32; + header[hlen+3] = (u16_t) (wd->sta.iv32 >> 16); + + //macCtrl |= 0x80; + macCtrl |= 0x40; + icvLen = 4; + + /* set hardware MIC */ + if ( (!(seq & 0xf))&&(!(flag & 0x4)) ) + { + macCtrl |= 0x100; + plusLen += 8; + *micLen = 8; + } + + header[4] |= 0x4000; + hlen += 4; + break; + + case ZM_AES: + wd->sta.iv16++; + if ( wd->sta.iv16 == 0 ) + { + wd->sta.iv32++; + } + + b1 = (u8_t) wd->sta.iv16; + b2 = (u8_t) (wd->sta.iv16 >> 8); + header[hlen] = ((u16_t)b2 << 8) + b1; + header[hlen+1] = 0x2000; + header[hlen+2] = (u16_t) (wd->sta.iv32); + header[hlen+3] = (u16_t) (wd->sta.iv32 >> 16); + + macCtrl |= 0xc0; /* Set to AES in control setting */ + icvLen = 8; /* MIC */ + + header[4] |= 0x4000; /* Set WEP bit in wlan header */ + hlen += 4; /* plus IV length */ + break; + }/* end of switch */ + #endif + } + } + else /* wd->wlanMode != ZM_MODE_AP */ + { + encExemptionActionType = zfwGetPktEncExemptionActionType(dev, buf); + + if ( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) + { + #if 1 + /* if WME AP */ + if (wd->sta.wmeConnected != 0) + { + /* QoS data */ + header[4] |= 0x0080; + + /* QoS Control */ + header[hlen] = up; + hlen += 1; + } + #endif + + if ( encExemptionActionType == ZM_ENCRYPTION_EXEMPT_NO_EXEMPTION ) + { + if ( wd->sta.authMode < ZM_AUTH_MODE_WPA ) + { /* non-WPA */ + if ( wd->sta.wepStatus == ZM_ENCRYPTION_WEP_ENABLED ) + { + if ( (wd->sta.encryMode == ZM_WEP64)|| + (wd->sta.encryMode == ZM_WEP128)|| + (wd->sta.encryMode == ZM_WEP256) ) + { + header[4] |= 0x4000; + header[hlen] = 0x0; //IV + header[hlen+1] = 0x0; //IV + header[hlen+1] |= (((u16_t) wd->sta.keyId) << 14); + hlen += 2; + icvLen = 4; + + /* For Software WEP */ + if ((wd->sta.SWEncryptEnable & ZM_SW_WEP_ENCRY_EN) != 0) + { + u8_t keyLen = 5; + u8_t iv[3]; + + iv[0] = 0x0; + iv[1] = 0x0; + iv[2] = 0x0; + + if (wd->sta.SWEncryMode[wd->sta.keyId] == ZM_WEP64) + { + keyLen = 5; + } + else if (wd->sta.SWEncryMode[wd->sta.keyId] == ZM_WEP128) + { + keyLen = 13; + } + else if (wd->sta.SWEncryMode[wd->sta.keyId] == ZM_WEP256) + { + keyLen = 29; + } + + zfWEPEncrypt(dev, buf, (u8_t*) snap, snapLen, minusLen, keyLen, + wd->sta.wepKey[wd->sta.keyId], iv); + } + else + { + macCtrl |= 0x40; + } + } + } + } + else + { /* WPA */ + if ( wd->sta.wpaState >= ZM_STA_WPA_STATE_PK_OK ) + { + wd->sta.iv16++; + if ( wd->sta.iv16 == 0 ) + { + wd->sta.iv32++; + } + + /* set encryption mode */ + if ( wd->sta.encryMode == ZM_TKIP ) + { + b1 = (u8_t) (wd->sta.iv16 >> 8); + b2 = (b1 | 0x20) & 0x7f; + header[hlen] = ((u16_t)b2 << 8) + b1; + b1 = (u8_t) wd->sta.iv16; + b2 = 0x20; + + // header[hlen+1] = (((u16_t) wd->sta.keyId) << 14) | (((u16_t)b2 << 8) + b1); + // STA in infrastructure mode should use keyId = 0 to transmit unicast ! + header[hlen+1] = (((u16_t)b2 << 8) + b1); + header[hlen+2] = (u16_t) wd->sta.iv32; + header[hlen+3] = (u16_t) (wd->sta.iv32 >> 16); + + /* If software encryption enable */ + if ((wd->sta.SWEncryptEnable & ZM_SW_TKIP_ENCRY_EN) == 0) + { + //macCtrl |= 0x80; + /* TKIP same to WEP */ + macCtrl |= 0x40; + icvLen = 4; + + /* set hardware MIC */ + if ( (!(seq & 0xf))&&(!(flag & 0x4)) ) + { + macCtrl |= 0x100; + plusLen += 8; + *micLen = 8; + } + } + else + { + u8_t mic[8]; + u16_t offset; + u32_t icv; + u8_t RC4Key[16]; + + /* TODO: Remove the criticial section here. */ + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + /* Calculate MIC */ + zfCalTxMic(dev, buf, (u8_t *)snap, snapLen, minusLen, da, sa, up, mic); + + offset = zfwBufGetSize(dev, buf); + + /* Append MIC to the buffer */ + zfCopyToIntTxBuffer(dev, buf, mic, offset, 8); + zfwBufSetSize(dev, buf, offset+8); + zmw_leave_critical_section(dev); + + /* TKIP Key Mixing */ + zfTkipPhase1KeyMix(wd->sta.iv32, &wd->sta.txSeed); + zfTkipPhase2KeyMix(wd->sta.iv16, &wd->sta.txSeed); + zfTkipGetseeds(wd->sta.iv16, RC4Key, &wd->sta.txSeed); + + /* Encrypt Data */ + zfTKIPEncrypt(dev, buf, (u8_t *)snap, snapLen, minusLen, 16, RC4Key, &icv); + + icvLen = 4; + len += 8; + } + + header[4] |= 0x4000; + hlen += 4; + } + else if ( wd->sta.encryMode == ZM_AES ) + { + b1 = (u8_t) wd->sta.iv16; + b2 = (u8_t) (wd->sta.iv16 >> 8); + header[hlen] = ((u16_t)b2 << 8) + b1; + // header[hlen+1] = (((u16_t) wd->sta.keyId) << 14) | (0x2000); + // STA in infrastructure mode should use keyId = 0 to transmit unicast ! + header[hlen+1] = 0x2000; + header[hlen+2] = (u16_t) (wd->sta.iv32); + header[hlen+3] = (u16_t) (wd->sta.iv32 >> 16); + + macCtrl |= 0xc0; + icvLen = 8; /* MIC */ + + header[4] |= 0x4000; + hlen += 4; + } + #ifdef ZM_ENABLE_CENC + else if ( wd->sta.encryMode == ZM_CENC ) + { + /* Accumlate the PN sequence */ + wd->sta.txiv[0] += 2; + + if (wd->sta.txiv[0] == 0 || wd->sta.txiv[0] == 1) + { + wd->sta.txiv[1]++; + } + + if (wd->sta.txiv[1] == 0) + { + wd->sta.txiv[2]++; + } + + if (wd->sta.txiv[2] == 0) + { + wd->sta.txiv[3]++; + } + + if (wd->sta.txiv[3] == 0) + { + wd->sta.txiv[0] = 0; + wd->sta.txiv[1] = 0; + wd->sta.txiv[2] = 0; + } + + header[hlen] = (wd->sta.cencKeyId & 0x0001); /* For Key Id and reserved field */ + header[hlen+1] = (u16_t) wd->sta.txiv[0]; + header[hlen+2] = (u16_t) (wd->sta.txiv[0] >> 16); + header[hlen+3] = (u16_t) wd->sta.txiv[1]; + header[hlen+4] = (u16_t) (wd->sta.txiv[1] >> 16); + header[hlen+5] = (u16_t) wd->sta.txiv[2]; + header[hlen+6] = (u16_t) (wd->sta.txiv[2] >> 16); + header[hlen+7] = (u16_t) wd->sta.txiv[3]; + header[hlen+8] = (u16_t) (wd->sta.txiv[3] >> 16); + + macCtrl |= 0x80; + icvLen = 16; /* MIC */ + + header[4] |= 0x4000; + hlen += 9; + } + #endif //ZM_ENABLE_CENC + } + } + } // if ( encExemptionActionType == ZM_ENCRYPTION_EXEMPT_NO_EXEMPTION ) + } /* if ( wd->wlanMode != ZM_MODE_INFRASTRUCTURE ) */ + + if ( wd->wlanMode == ZM_MODE_IBSS ) + { + if ( encExemptionActionType == ZM_ENCRYPTION_EXEMPT_NO_EXEMPTION ) + { +#ifdef ZM_ENABLE_IBSS_WPA2PSK + if( wd->sta.oppositeInfo[userIdx].wpaState >= ZM_STA_WPA_STATE_PK_OK || wd->sta.wpaState >= ZM_STA_WPA_STATE_PK_OK) + { + int isUnicast = 1 ; + + if((da[0]& 0x1)) + { + isUnicast = 0 ; // Not unicast , is broadcast + } + + if( wd->sta.ibssWpa2Psk == 1 ) + { /* The IV order is not the same between unicast and broadcast ! */ + if ( isUnicast ) + { + iv16 = &wd->sta.oppositeInfo[userIdx].iv16; + iv32 = &wd->sta.oppositeInfo[userIdx].iv32; + } + else + { + iv16 = &wd->sta.iv16; + iv32 = &wd->sta.iv32; + } + } + else + { + iv16 = &wd->sta.iv16; + iv32 = &wd->sta.iv32; + } + + (*iv16)++; + if ( *iv16 == 0 ) + { + *iv32++; + } + + if ( wd->sta.oppositeInfo[userIdx].encryMode == ZM_AES || wd->sta.encryMode == ZM_AES) + { + //printk("Station encryption mode is AES-CCMP\n") ; + b1 = (u8_t) (*iv16); + b2 = (u8_t) ((*iv16) >> 8); + header[hlen] = ((u16_t)b2 << 8) + b1; + + if ( isUnicast ) + { + header[hlen+1] = 0x2000; + } + else + { + header[hlen+1] = 0x2000 | (((u16_t) wd->sta.keyId) << 14); + } + + header[hlen+2] = (u16_t) (*iv32); + header[hlen+3] = (u16_t) ((*iv32) >> 16); + macCtrl |= 0xc0; + icvLen = 8; /* MIC */ + } + + header[4] |= 0x4000; + hlen += 4; + } + else if ( wd->sta.wepStatus == ZM_ENCRYPTION_WEP_ENABLED) + { + if ( (wd->sta.encryMode == ZM_WEP64)|| + (wd->sta.encryMode == ZM_WEP128)|| + (wd->sta.encryMode == ZM_WEP256) ) + { + header[4] |= 0x4000; + header[hlen] = 0x0; //IV + header[hlen+1] = 0x0; //IV + header[hlen+1] |= (((u16_t) wd->sta.keyId) << 14); + hlen += 2; + icvLen = 4; + macCtrl |= 0x40; + } + } +#else + /* ----- 20070405 add by Mxzeng ----- */ + if( wd->sta.wpaState >= ZM_STA_WPA_STATE_PK_OK ) + { + int isUnicast = 1 ; + + if((da[0]& 0x1)) + { + isUnicast = 0 ; // Not unicast , is broadcast + } + + wd->sta.iv16++; + if ( wd->sta.iv16 == 0 ) + { + wd->sta.iv32++; + } + + if ( wd->sta.encryMode == ZM_AES ) + { + //printk("Station encryption mode is AES-CCMP\n") ; + b1 = (u8_t) wd->sta.iv16; + b2 = (u8_t) (wd->sta.iv16 >> 8); + header[hlen] = ((u16_t)b2 << 8) + b1; + + if ( isUnicast ) + { + header[hlen+1] = 0x2000; + } + else + { + header[hlen+1] = 0x2000 | (((u16_t) wd->sta.keyId) << 14); + } + + header[hlen+2] = (u16_t) (wd->sta.iv32); + header[hlen+3] = (u16_t) (wd->sta.iv32 >> 16); + macCtrl |= 0xc0; + icvLen = 8; /* MIC */ + } + + header[4] |= 0x4000; + hlen += 4; + } + else if ( wd->sta.wepStatus == ZM_ENCRYPTION_WEP_ENABLED) + { + if ( (wd->sta.encryMode == ZM_WEP64)|| + (wd->sta.encryMode == ZM_WEP128)|| + (wd->sta.encryMode == ZM_WEP256) ) + { + header[4] |= 0x4000; + header[hlen] = 0x0; //IV + header[hlen+1] = 0x0; //IV + header[hlen+1] |= (((u16_t) wd->sta.keyId) << 14); + hlen += 2; + icvLen = 4; + macCtrl |= 0x40; + } + } +#endif + } // End if ( encExemptionActionType == ZM_ENCRYPTION_EXEMPT_NO_EXEMPTION ) + } // End if ( wd->wlanMode == ZM_MODE_IBSS ) + else if ( wd->wlanMode == ZM_MODE_PSEUDO ) + { + switch (wd->sta.encryMode) + { + case ZM_WEP64: + case ZM_WEP128: + case ZM_WEP256: + header[4] |= 0x4000; + header[hlen] = 0x0; //IV + header[hlen+1] = 0x0; //IV + hlen += 2; + icvLen = 4; + macCtrl |= 0x40; + break; + + case ZM_TKIP: + { + wd->sta.iv16++; + if ( wd->sta.iv16 == 0 ) + { + wd->sta.iv32++; + } + + b1 = (u8_t) (wd->sta.iv16 >> 8); + b2 = (b1 | 0x20) & 0x7f; + header[hlen] = ((u16_t)b2 << 8) + b1; + b1 = (u8_t) wd->sta.iv16; + b2 = 0x20; + header[hlen+1] = ((u16_t)b2 << 8) + b1; + header[hlen+2] = (u16_t) wd->sta.iv32; + header[hlen+3] = (u16_t) (wd->sta.iv32 >> 16); + + //macCtrl |= 0x80; + macCtrl |= 0x40; + icvLen = 4; + + /* set hardware MIC */ + if ( (!(seq & 0xf))&&(!(flag & 0x4)) ) + { + macCtrl |= 0x100; + plusLen += 8; + *micLen = 8; + } + + header[4] |= 0x4000; + hlen += 4; + }/* end of PSEUDO TKIP */ + break; + + case ZM_AES: + { + wd->sta.iv16++; + if ( wd->sta.iv16 == 0 ) + { + wd->sta.iv32++; + } + + b1 = (u8_t) wd->sta.iv16; + b2 = (u8_t) (wd->sta.iv16 >> 8); + header[hlen] = ((u16_t)b2 << 8) + b1; + header[hlen+1] = 0x2000; + header[hlen+2] = (u16_t) (wd->sta.iv32); + header[hlen+3] = (u16_t) (wd->sta.iv32 >> 16); + macCtrl |= 0xc0; + icvLen = 8; /* MIC */ + header[4] |= 0x4000; + hlen += 4; + }/* end of PSEUDO AES */ + break; + + #ifdef ZM_ENABLE_CENC + case ZM_CENC: + /* Accumlate the PN sequence */ + wd->sta.txiv[0] += 2; + + if (wd->sta.txiv[0] == 0 || wd->sta.txiv[0] == 1) + { + wd->sta.txiv[1]++; + } + + if (wd->sta.txiv[1] == 0) + { + wd->sta.txiv[2]++; + } + + if (wd->sta.txiv[2] == 0) + { + wd->sta.txiv[3]++; + } + + if (wd->sta.txiv[3] == 0) + { + wd->sta.txiv[0] = 0; + wd->sta.txiv[1] = 0; + wd->sta.txiv[2] = 0; + } + + header[hlen] = 0; + header[hlen+1] = (u16_t) wd->sta.txiv[0]; + header[hlen+2] = (u16_t) (wd->sta.txiv[0] >> 16); + header[hlen+3] = (u16_t) wd->sta.txiv[1]; + header[hlen+4] = (u16_t) (wd->sta.txiv[1] >> 16); + header[hlen+5] = (u16_t) wd->sta.txiv[2]; + header[hlen+6] = (u16_t) (wd->sta.txiv[2] >> 16); + header[hlen+7] = (u16_t) wd->sta.txiv[3]; + header[hlen+8] = (u16_t) (wd->sta.txiv[3] >> 16); + + macCtrl |= 0x80; + icvLen = 16; /* MIC */ + + header[4] |= 0x4000; + hlen += 9; + break; + #endif //ZM_ENABLE_CENC + }/* end of switch */ + } + + /* Generate control setting */ + + /* protection mode */ + if (wd->enableProtectionMode) + { + if (wd->enableProtectionMode==2) + { + /* Force enable protection: self cts */ + macCtrl &= 0xFFFC; + macCtrl |= 2; + } + /* if wd->enableProtectionMode=1 => force disable */ + /* if wd->enableProtectionMode=0 => auto */ + } + else + { + + /* protection mode */ + if (wd->sta.bProtectionMode == TRUE) + { + /* Enable Self-CTS */ + macCtrl &= 0xFFFC; + macCtrl |= 2; + } + } + + } + + if (wd->txMCS != 0xff) + { + /* fixed rate */ + phyCtrl = ((u32_t)wd->txMCS<<16) + wd->txMT; + mcs = wd->txMCS; + mt = wd->txMT; + } + + if (mt == 2) + { +#if 0 + /* HT PT: 0 Mixed mode 1 Green field */ + if (wd->sta.preambleTypeHT == ZM_PREAMBLE_TYPE_GREEN_FIELD) + { + phyCtrl |= 0x4; /* Bit 2 */ + } +#endif + /* Bandwidth */ + if (wd->sta.htCtrlBandwidth == ZM_BANDWIDTH_40MHZ) + { + phyCtrl |= (0x80<<16); /* BIT 23 */ + } +#if 0 + /* STBC */ + if (wd->sta.htCtrlSTBC<=0x3) + { + phyCtrl |= (wd->sta.htCtrlSTBC<<28); /* BIT 23 */ + } +#endif + /* Short GI */ + if(wd->sta.htCtrlSG) + { + phyCtrl |= (0x8000<<16); /* BIT 31 */ + } + + /* TA */ + if ( ((mcs >=0x8) && (mcs<=0xf)) || (wd->sta.htCtrlSTBC) ) + { + phyCtrl |= 0x1800; /* BIT 11 12 */ + } + } + else if(mt == 1) + { + #if 0 + //bug that cause OFDM rate become duplicate legacy rate + /* Bandwidth */ + if (wd->sta.htCtrlBandwidth == ZM_BANDWIDTH_40MHZ) + { + phyCtrl |= (0x80<<16); /* BIT 23 */ + mt = 3; /* duplicate legacy */ + phyCtrl |= mt; + } + #endif + } + else if(mt == 0) + { + /* CCK PT: Legcy Preamble: 1 long preamble 2 short preamble */ + if (wd->preambleTypeInUsed == ZM_PREAMBLE_TYPE_SHORT) + { + //phyCtrl |= 0x4; /* BIT 2 */ + } + } + + /* TA */ + if (wd->sta.defaultTA) + { + phyCtrl |= 0x1000; + } + else + { + phyCtrl |= 0x0800; + } + + //Get CurrentTxRate -- CWYang(+) + if ((mt == 0) || (mt == 1)) //B,G Rate + { + if (mcs < 16) + { + wd->CurrentTxRateKbps = zcIndextoRateBG[mcs]; + } + } + else if (mt == 2) + { + if (mcs < 16) + { + if (wd->sta.htCtrlBandwidth == ZM_BANDWIDTH_40MHZ) + { + if((phyCtrl & 0x80000000) != 0) + { + /* Short GI 40 MHz MIMO Rate */ + wd->CurrentTxRateKbps = zcIndextoRateN40S[mcs]; + } + else + { + /* Long GI 40 MHz MIMO Rate */ + wd->CurrentTxRateKbps = zcIndextoRateN40L[mcs]; + } + } + else + { + if((phyCtrl & 0x80000000) != 0) + { + /* Short GI 20 MHz MIMO Rate */ + wd->CurrentTxRateKbps = zcIndextoRateN20S[mcs]; + } + else + { + /* Long GI 20 MHz MIMO Rate */ + wd->CurrentTxRateKbps = zcIndextoRateN20L[mcs]; + } + } + } + } + + //802.11 header(include IV) = (hlen<<1)-8 + //ethernet frame = len + //snap + mic = plusLen + //ethernet header = minusLen + //icv = icvLen + //crc32 = 4 + //length=802.11 header+snap+(ethernet frame-ethernet header)+mic+icv+crc32 + header[0] = ((hlen<<1)-8)+plusLen+(len-minusLen)+icvLen+4; //Length + + // header[0] : MPDU Lengths + if ((header[6] & 0x1) != 0x1) // Unicast Frame + { + if (header[0] >= wd->rtsThreshold) + { + /* Enable RTS */ + macCtrl |= 1; + } + } + + if ( wd->sta.encryMode == ZM_TKIP ) + tkipFrameOffset = 8; + + if( wd->sta.EnableHT != 1 ) + { // Aggregation should not be fragmented ! + if ( header[0] > ( wd->fragThreshold + tkipFrameOffset ) ) + { + return 0; // Need to be fragmented ! ! + } + } + + //if ( wd->sta.encryMode == ZM_TKIP ) + //{ + // zm_debug_msg1("ctrl length = ", header[0]); + //} + + //MAC control + if (rateProbingFlag != 0) + { + macCtrl |= 0x8000; + } + header[1] = macCtrl; + //PHY control L + header[2] = (u16_t) ((phyCtrl&0xffff) | 0x700 | (zcUpToAc[up&0x7]<<13)); + //PHY control H + header[3] = (u16_t) ((phyCtrl>>16) | 0x700); + + if (wd->enableAggregation) + { + /* force enable aggregation */ + if (wd->enableAggregation==2 && !(header[6]&0x1)) + { + if (((header[2] & 0x3) == 2)) + { + /* Enable aggregation */ + header[1] |= 0x20; + } + } + /* if wd->enableAggregation=1 => force disable */ + /* if wd->enableAggregation=0 => auto */ + } + +#ifdef ZM_ENABLE_AGGREGATION + if (wd->addbaComplete) { + #ifdef ZM_BYPASS_AGGR_SCHEDULING + if (!(header[6]&0x1) && !rateProbingFlag && (wd->enableAggregation != 1)) + { + if (((header[2] & 0x3) == 2)) + { + /* Unicast frame with HT rate => Enable aggregation */ + /* We only support software encryption in single packet mode */ + if ((wd->sta.SWEncryptEnable & ZM_SW_TKIP_ENCRY_EN) == 0 && + (wd->sta.SWEncryptEnable & ZM_SW_WEP_ENCRY_EN) == 0) + { + /* Set aggregation group bits per AC */ + header[1] |= (0x20 | (zcUpToAc[up&0x7]<<10)); + + //if (wd->sta.currentFrequency < 3000) + { + /* issue: -PB42 Enable RTS/CTS to prevent OWL Tx hang up */ + /* If this is Owl Ap, enable RTS/CTS protect */ + if ( (wd->sta.athOwlAp == 1) || (wd->sta.RTSInAGGMode == TRUE) ) + { + header[1] &= 0xfffc; + header[1] |= 0x1; + } + + /* Enable RIFS : workaround 854T RTS/CTS */ + /* Bit13 : TI enable RIFS */ + //header[1] |= 0x2000; + } + } + } + } + #else + /* + * aggregation ampduIndication control + */ + if (aggControl && aggControl->aggEnabled) { + if (wd->enableAggregation==0 && !(header[6]&0x1)) + { + if (((header[2] & 0x3) == 2)) + { + /* Enable aggregation */ + header[1] |= 0x20; + if (ZM_AGG_LAST_MPDU == aggControl->ampduIndication) + header[1] |= 0x4000; + } + else { + zm_debug_msg1("no aggr, header[2]&0x3 = ",header[2] & 0x3) + aggControl->aggEnabled = 0; + } + } + else { + zm_debug_msg1("no aggr, wd->enableAggregation = ", wd->enableAggregation); + zm_debug_msg1("no aggr, !header[6]&0x1 = ",!(header[6]&0x1)); + aggControl->aggEnabled = 0; + } + } + #endif + + #ifdef ZM_AGGR_BIT_ON + if (!(header[6]&0x1) && !rateProbingFlag) + { + if (((header[2] & 0x3) == 2)) + { + /* Unicast frame with HT rate => Enable aggregation */ + /* Set aggregation group bits per AC */ + header[1] |= (0x20 | (zcUpToAc[up&0x7]<<10)); + + //if (wd->sta.currentFrequency < 3000) + { + /* Enable RTS/CTS to prevent OWL Tx hang up */ + header[1] &= 0xfffc; + header[1] |= 0x1; + } + } + } + #endif + } +#endif + + return (hlen<<1); +} + + +u16_t zfTxGenMmHeader(zdev_t* dev, u8_t frameType, u16_t* dst, + u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt) +{ + //u16_t bodyLen; + u8_t hlen = 32; // MAC ctrl + PHY ctrl + 802.11 MM header + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + /* Generate control setting */ + //bodyLen = zfwBufGetSize(dev, buf); + header[0] = 24+len+4; //Length + if ((dst[0] & 0x1) != 0) //Broadcast, multicast frames + { + header[1] = 0xc; //MAC control, backoff + noack + } + else + { + header[1] = 0x8; //MAC control, backoff + (ack) + } + /* Dualband Management frame tx Rate */ + if (wd->wlanMode == ZM_MODE_AP) + { + if (wd->frequency < 3000) + { + /* CCK 1M */ + header[2] = 0x0f00; //PHY control L + header[3] = 0x0000; //PHY control H + } + else + { + /* CCK 6M */ + header[2] = 0x0f01; //PHY control L + header[3] = 0x000B; //PHY control H + } + } + else + { + if (wd->sta.currentFrequency < 3000) + { + /* CCK 2M */ + header[2] = 0x0f00; //PHY control L + header[3] = 0x0001; //PHY control H + } + else + { + /* CCK 6M */ + header[2] = 0x0f01; //PHY control L + header[3] = 0x000B; //PHY control H + } + } + /* Generate WLAN header */ + /* Frame control */ + header[4+0] = frameType; + /* Duration */ + header[4+1] = 0; + + if (wd->wlanMode == ZM_MODE_INFRASTRUCTURE) + { + if ( frameType == ZM_WLAN_FRAME_TYPE_PROBEREQ ) + { + header[4+8] = 0xFFFF; + header[4+9] = 0xFFFF; + header[4+10] = 0xFFFF; + } + else if ( frameType == ZM_WLAN_FRAME_TYPE_BA ) { + /* do nothing */ + } + else + { + header[4+8] = wd->sta.bssid[0]; + header[4+9] = wd->sta.bssid[1]; + header[4+10] = wd->sta.bssid[2]; + } + } + else if (wd->wlanMode == ZM_MODE_PSEUDO) + { + /* Address 3 = 00:00:00:00:00:00 */ + header[4+8] = 0; + header[4+9] = 0; + header[4+10] = 0; + } + else if (wd->wlanMode == ZM_MODE_IBSS) + { + header[4+8] = wd->sta.bssid[0]; + header[4+9] = wd->sta.bssid[1]; + header[4+10] = wd->sta.bssid[2]; + + if ( frameType == ZM_WLAN_FRAME_TYPE_ATIM ) + { + /* put ATIM to queue 5th */ + //header[2] |= (ZM_BIT_13|ZM_BIT_14); + header[2] |= ZM_BIT_15; + } + } + else if (wd->wlanMode == ZM_MODE_AP) + { + /* Address 3 = BSSID */ + header[4+8] = wd->macAddr[0]; + header[4+9] = wd->macAddr[1]; +#ifdef ZM_VAPMODE_MULTILE_SSID + header[4+10] = wd->macAddr[2]; //Multiple SSID +#else + header[4+10] = wd->macAddr[2] + (vap<<8); //VAP +#endif + //if in scan, must set address 3 to broadcast because of some ap would care this + //if ((wd->heartBeatNotification & ZM_BSSID_LIST_SCAN) + // == ZM_BSSID_LIST_SCAN) + //if FrameType is Probe Request, Address3 should be boradcast + if (frameType == ZM_WLAN_FRAME_TYPE_PROBEREQ) + { + header[4+8] = 0xFFFF; + header[4+9] = 0xFFFF; + header[4+10] = 0xFFFF; + } + } + + /* Address 1 = DA */ + header[4+2] = dst[0]; + header[4+3] = dst[1]; + header[4+4] = dst[2]; + + /* Address 2 = SA */ + header[4+5] = wd->macAddr[0]; + header[4+6] = wd->macAddr[1]; + if (wd->wlanMode == ZM_MODE_AP) + { +#ifdef ZM_VAPMODE_MULTILE_SSID + header[4+7] = wd->macAddr[2]; //Multiple SSID +#else + header[4+7] = wd->macAddr[2] + (vap<<8); //VAP +#endif + } + else + { + header[4+7] = wd->macAddr[2]; + } + + /* Sequence Control */ + zmw_enter_critical_section(dev); + header[4+11] = ((wd->mmseq++)<<4); + zmw_leave_critical_section(dev); + + if( frameType == ZM_WLAN_FRAME_TYPE_QOS_NULL ) + { + /*Qos Control*/ + header[4+12] = 0x0; + hlen+=2; + header[0]+=2; + } + + if ( encrypt ) + { + if ( wd->sta.wepStatus == ZM_ENCRYPTION_WEP_ENABLED ) + { + if ( (wd->sta.encryMode == ZM_WEP64)|| + (wd->sta.encryMode == ZM_WEP128)|| + (wd->sta.encryMode == ZM_WEP256) ) + { + header[4] |= 0x4000; + header[16] = 0x0; //IV + header[17] = 0x0; //IV + header[17] |= (((u16_t) wd->sta.keyId) << 14); + hlen += 4; + + header[0] += 8; // icvLen = 4; + header[1] |= 0x40; // enable encryption on macCtrl + } + } + } + + // Enable HW duration + if ( frameType != ZM_WLAN_FRAME_TYPE_PSPOLL ) + { + header[1] |= 0x200; + } + + return hlen; +} + +void zfInitMacApMode(zdev_t* dev) +{ + u16_t i; + + zmw_get_wlan_dev(dev); + + zfHpEnableBeacon(dev, ZM_MODE_AP, (wd->beaconInterval/wd->ap.vapNumber), 1, 0); + + /* AP mode */ + zfHpSetApStaMode(dev, ZM_HAL_80211_MODE_AP); + + /* VAP test code */ + /* AP + VAP mode */ + if (wd->ap.vapNumber >= 2) + { + for (i=1; iap.apBitmap >> i) & 0x1) != 0) + { + u16_t mac[3]; + mac[0] = wd->macAddr[0]; + mac[1] = wd->macAddr[1]; +#ifdef ZM_VAPMODE_MULTILE_SSID + mac[2] = wd->macAddr[2]; //Multiple SSID +#else + mac[2] = wd->macAddr[2] + (i<<8); //VAP +#endif + zfHpSetMacAddress(dev, mac, i); + + } + } + } + + /* basic rate setting */ + zfHpSetBasicRateSet(dev, wd->bRateBasic, wd->gRateBasic); + + /* Set TxQs CWMIN, CWMAX, AIFS and TXO to WME AP default. */ + zfUpdateDefaultQosParameter(dev, 1); + + return; +} + +u16_t zfChGetNextChannel(zdev_t* dev, u16_t frequency, u8_t* pbPassive) +{ + u8_t i; + u8_t bPassive; + + zmw_get_wlan_dev(dev); + + /* Avoid NULL value */ + if ( pbPassive == NULL ) + { + pbPassive = &bPassive; + } + + for( i=0; iregulationTable.allowChannelCnt; i++ ) + { + if ( wd->regulationTable.allowChannel[i].channel == frequency ) + { + if ( i == (wd->regulationTable.allowChannelCnt-1) ) + { + i = 0; + } + else + { + i++; + } + + if ( wd->regulationTable.allowChannel[i].channelFlags + & ZM_REG_FLAG_CHANNEL_PASSIVE ) + { + *pbPassive = TRUE; + } + else + { + *pbPassive = FALSE; + } + + return wd->regulationTable.allowChannel[i].channel; + } + } + + return 0xffff; +} + +u16_t zfChGetFirstChannel(zdev_t* dev, u8_t* pbPassive) +{ + u8_t bPassive; + + zmw_get_wlan_dev(dev); + + /* Avoid NULL value */ + if ( pbPassive == NULL ) + { + pbPassive = &bPassive; + } + + if ( wd->regulationTable.allowChannel[0].channelFlags & ZM_REG_FLAG_CHANNEL_PASSIVE ) + { + *pbPassive = TRUE; + } + else + { + *pbPassive = FALSE; + } + + return wd->regulationTable.allowChannel[0].channel; +} + +u16_t zfChGetFirst2GhzChannel(zdev_t* dev) +{ + u8_t i; + + zmw_get_wlan_dev(dev); + + for( i=0; iregulationTable.allowChannelCnt; i++ ) + { + if ( wd->regulationTable.allowChannel[i].channel < 3000 ) + { + /* find the first 2Ghz channel */ + return wd->regulationTable.allowChannel[i].channel; + } + } + + /* Can not find any 2Ghz channel */ + return 0; +} + +u16_t zfChGetFirst5GhzChannel(zdev_t* dev) +{ + u8_t i; + + zmw_get_wlan_dev(dev); + + for( i=0; iregulationTable.allowChannelCnt; i++ ) + { + if ( wd->regulationTable.allowChannel[i].channel > 3000 ) + { + /* find the first 5Ghz channel */ + return wd->regulationTable.allowChannel[i].channel; + } + } + + /* Can not find any 5Ghz channel */ + return 0; +} + +u16_t zfChGetLastChannel(zdev_t* dev, u8_t* pbPassive) +{ + u8_t bPassive; + u8_t ChannelIndex; + + zmw_get_wlan_dev(dev); + + ChannelIndex = wd->regulationTable.allowChannelCnt-1; + + /* Avoid NULL value */ + if ( pbPassive == NULL ) + { + pbPassive = &bPassive; + } + + if ( wd->regulationTable.allowChannel[ChannelIndex].channelFlags + & ZM_REG_FLAG_CHANNEL_PASSIVE ) + { + *pbPassive = TRUE; + } + else + { + *pbPassive = FALSE; + } + + return wd->regulationTable.allowChannel[ChannelIndex].channel; +} + +u16_t zfChGetLast5GhzChannel(zdev_t* dev) +{ + u8_t i; + u16_t last5Ghzfrequency; + + zmw_get_wlan_dev(dev); + + last5Ghzfrequency = 0; + for( i=0; iregulationTable.allowChannelCnt; i++ ) + { + if ( wd->regulationTable.allowChannel[i].channel > 3000 ) + { + last5Ghzfrequency = wd->regulationTable.allowChannel[i].channel; + } + } + + return last5Ghzfrequency; +} + +/* freqBand = 0 => auto check */ +/* = 1 => 2.4 GHz band */ +/* = 2 => 5 GHz band */ +u16_t zfChNumToFreq(zdev_t* dev, u8_t ch, u8_t freqBand) +{ + u16_t freq = 0xffff; + + if ( freqBand == 0 ) + { + if (ch > 14) + { /* adapter is at 5 GHz band */ + freqBand = 2; + } + else + { + freqBand = 1; + } + } + + if ( freqBand == 2 ) + { /* the channel belongs to 5 GHz band */ + if ( (ch >= 184)&&(ch <= 196) ) + { + freq = 4000 + ch*5; + } + else + { + freq = 5000 + ch*5; + } + } + else + { /* the channel belongs to 2.4 GHz band */ + if ( ch == 14 ) + { + freq = ZM_CH_G_14; + } + else + { + freq = ZM_CH_G_1 + (ch-1)*5; + } + } + + return freq; +} + +u8_t zfChFreqToNum(u16_t freq, u8_t* pbIs5GBand) +{ + u8_t ch; + u8_t Is5GBand; + + /* to avoid NULL value */ + if ( pbIs5GBand == NULL ) + { + pbIs5GBand = &Is5GBand; + } + + *pbIs5GBand = FALSE; + + if ( freq == ZM_CH_G_14 ) + { + ch = 14; + } + else if ( freq < 4000 ) + { + ch = (freq - ZM_CH_G_1) / 5 + 1; + } + else if ( freq < 5000 ) + { + ch = (freq - 4000) / 5; + *pbIs5GBand = TRUE; + } + else + { + ch = (freq - 5000) / 5; + *pbIs5GBand = TRUE; + } + + return ch; +} --- linux-2.6.28.orig/drivers/staging/otus/80211core/performance.h +++ linux-2.6.28/drivers/staging/otus/80211core/performance.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef _PERFORMANCE_H +#define _PERFORMANCE_H + +#ifdef ZM_ENABLE_PERFORMANCE_EVALUATION + +struct zsSummary +{ + u32_t tx_msdu_count; + u32_t tx_mpdu_count; + u32_t rx_msdu_count; + u32_t rx_mpdu_count; + u32_t tick_base; + u16_t rx_seq_base; + u16_t rx_broken_seq; + u16_t rx_broken_sum; + u16_t rx_broken_seq_dis; + u16_t rx_duplicate_seq; + u16_t rx_duplicate_error; + u16_t rx_old_seq; + u16_t rx_lost_sum; + u16_t tx_idle_count; + u16_t rx_idle_count; + u16_t reset_count; + u16_t reset_sum; + u16_t rx_free; + u16_t rx_amsdu_len; + u16_t rx_flush; + u16_t rx_clear; + u32_t rx_reorder; +}; + +struct zsVariation +{ + u32_t tx_msdu_tick[100]; + u32_t tx_mpdu_tick[100]; + u32_t rx_msdu_tick[100]; + u32_t rx_mpdu_tick[100]; + + u32_t tx_msdu_mean; + u32_t tx_mpdu_mean; + u32_t rx_msdu_mean; + u32_t rx_mpdu_mean; + + u32_t tx_msdu_sum; + u32_t tx_mpdu_sum; + u32_t rx_msdu_sum; + u32_t rx_mpdu_sum; + + u32_t tx_msdu_var; + u32_t tx_mpdu_var; + u32_t rx_msdu_var; + u32_t rx_mpdu_var; +}; + +struct zsThroughput +{ + u32_t tx[50]; + u32_t rx[50]; + u16_t head; + u16_t tail; + u16_t size; + LARGE_INTEGER sys_time; + LARGE_INTEGER freq; +}; + +void zfiPerformanceInit(zdev_t* dev); +void zfiPerformanceRefresh(zdev_t* dev); + +void zfiTxPerformanceMSDU(zdev_t* dev, u32_t tick); +void zfiRxPerformanceMSDU(zdev_t* dev, u32_t tick); +void zfiTxPerformanceMPDU(zdev_t* dev, u32_t tick); +void zfiRxPerformanceMPDU(zdev_t* dev, zbuf_t* buf); +void zfiRxPerformanceSeq(zdev_t* dev, zbuf_t* buf); +void zfiRxPerformanceReg(zdev_t* dev, u32_t reg, u32_t rsp); +void zfiRxPerformanceDup(zdev_t* dev, zbuf_t* buf1, zbuf_t* buf2); +void zfiRxPerformanceFree(zdev_t* dev, zbuf_t* buf); +void zfiRxPerformanceAMSDU(zdev_t* dev, zbuf_t* buf, u16_t len); +void zfiRxPerformanceFlush(zdev_t* dev); +void zfiRxPerformanceClear(zdev_t* dev); +void zfiRxPerformanceReorder(zdev_t* dev); +#endif /* end of ZM_ENABLE_PERFORMANCE_EVALUATION */ +#endif /* end of _PERFORMANCE_H */ --- linux-2.6.28.orig/drivers/staging/otus/80211core/cprecomp.h +++ linux-2.6.28/drivers/staging/otus/80211core/cprecomp.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _CPRECOMP_H +#define _CPRECOMP_H + +#include "../oal_dt.h" +#include "../oal_marc.h" +#include "pub_zfi.h" +#include "pub_zfw.h" +#include "pub_usb.h" +#include "wlan.h" +#include "struct.h" +#include "cfunc.h" +#include "cagg.h" +#include "cwm.h" +#include "performance.h" +#endif + --- linux-2.6.28.orig/drivers/staging/otus/80211core/cmm.c +++ linux-2.6.28/drivers/staging/otus/80211core/cmm.c @@ -0,0 +1,2141 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* */ +/* Module Name : mm.c */ +/* */ +/* Abstract */ +/* This module contains common functions for handle management */ +/* frame. */ +/* */ +/* NOTES */ +/* None */ +/* */ +/************************************************************************/ +#include "cprecomp.h" +#include "../hal/hpreg.h" + +/* TODO : put all constant tables to a file */ +const u8_t zg11bRateTbl[4] = {2, 4, 11, 22}; +const u8_t zg11gRateTbl[8] = {12, 18, 24, 36, 48, 72, 96, 108}; + +/* 0xff => element does not exist */ +const u8_t zgElementOffsetTable[] = +{ + 4, /* 0 : asoc req */ + 6, /* 1 : asoc rsp */ + 10, /* 2 : reasoc req*/ + 6, /* 3 : reasoc rsp */ + 0, /* 4 : probe req */ + 12, /* 5 : probe rsp */ + 0xff, /* 6 : reserved */ + 0xff, /* 7 : reserved */ + 12, /* 8 : beacon */ + 4, /* 9 : ATIM */ + 0xff, /* 10 : disasoc */ + 6, /* 11 : auth */ + 0xff, /* 12 : deauth */ + 4, /* 13 : action */ + 0xff, /* 14 : reserved */ + 0xff, /* 15 : reserved */ +}; + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfFindElement */ +/* Find a specific element in management frame */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : management frame buffer */ +/* eid : target element id */ +/* */ +/* OUTPUTS */ +/* byte offset of target element */ +/* or 0xffff if not found */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2005.10 */ +/* */ +/************************************************************************/ +u16_t zfFindElement(zdev_t* dev, zbuf_t* buf, u8_t eid) +{ + u8_t subType; + u16_t offset; + u16_t bufLen; + u16_t elen; + u8_t id, HTEid=0; + u8_t oui[4] = {0x00, 0x50, 0xf2, 0x01}; + u8_t oui11n[3] = {0x00,0x90,0x4C}; + u8_t HTType = 0; + + /* Get offset of first element */ + subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4); + if ((offset = zgElementOffsetTable[subType]) == 0xff) + { + zm_assert(0); + } + + /* Plus wlan header */ + offset += 24; + + // jhlee HT 0 + + if ((eid == ZM_WLAN_EID_HT_CAPABILITY) || + (eid == ZM_WLAN_EID_EXTENDED_HT_CAPABILITY)) + { + HTEid = eid; + eid = ZM_WLAN_EID_WPA_IE; + HTType = 1; + } + + + bufLen = zfwBufGetSize(dev, buf); + /* Search loop */ + while ((offset+2)(bufLen - offset)) + { + /* Element length error */ + return 0xffff; + } + + if ( elen == 0 && eid != ZM_WLAN_EID_SSID) + { + /* Element length error */ + return 0xffff; + } + + if ( eid == ZM_WLAN_EID_WPA_IE ) + { + /* avoid sta to be thought use 11n when find a WPA_IE */ + if ( (HTType == 0) && zfRxBufferEqualToStr(dev, buf, oui, offset+2, 4) ) + { + return offset; + } + + // jhlee HT 0 + // CWYang(+) + + if ((HTType == 1) && ( zfRxBufferEqualToStr(dev, buf, oui11n, offset+2, 3) )) + { + if ( zmw_rx_buf_readb(dev, buf, offset+5) == HTEid ) + { + return offset + 5; + } + } + + } + else + { + return offset; + } + } + /* Advance to next element */ + #if 1 + elen = zmw_rx_buf_readb(dev, buf, offset+1); + #else + if ((elen = zmw_rx_buf_readb(dev, buf, offset+1)) == 0) + { + return 0xffff; + } + #endif + + offset += (elen+2); + } + return 0xffff; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfFindWifiElement */ +/* Find a specific Wifi element in management frame */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : management frame buffer */ +/* type : OUI type */ +/* subType : OUI subtype */ +/* */ +/* OUTPUTS */ +/* byte offset of target element */ +/* or 0xffff if not found */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2006.1 */ +/* */ +/************************************************************************/ +u16_t zfFindWifiElement(zdev_t* dev, zbuf_t* buf, u8_t type, u8_t subtype) +{ + u8_t subType; + u16_t offset; + u16_t bufLen; + u16_t elen; + u8_t id; + u8_t tmp; + + /* Get offset of first element */ + subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4); + + if ((offset = zgElementOffsetTable[subType]) == 0xff) + { + zm_assert(0); + } + + /* Plus wlan header */ + offset += 24; + + bufLen = zfwBufGetSize(dev, buf); + /* Search loop */ + while ((offset+2)(bufLen - offset)) + { + /* Element length error */ + return 0xffff; + } + + if ( elen == 0 ) + { + return 0xffff; + } + + if (((tmp = zmw_rx_buf_readb(dev, buf, offset+2)) == 0x00) + && ((tmp = zmw_rx_buf_readb(dev, buf, offset+3)) == 0x50) + && ((tmp = zmw_rx_buf_readb(dev, buf, offset+4)) == 0xF2) + && ((tmp = zmw_rx_buf_readb(dev, buf, offset+5)) == type)) + + { + if ( subtype != 0xff ) + { + if ( (tmp = zmw_rx_buf_readb(dev, buf, offset+6)) == subtype ) + { + return offset; + } + } + else + { + return offset; + } + } + } + /* Advance to next element */ + if ((elen = zmw_rx_buf_readb(dev, buf, offset+1)) == 0) + { + return 0xffff; + } + offset += (elen+2); + } + return 0xffff; +} + +u16_t zfRemoveElement(zdev_t* dev, u8_t* buf, u16_t size, u8_t eid) +{ + u16_t offset = 0; + u16_t elen; + u8_t HTEid = 0; + u8_t oui[4] = {0x00, 0x50, 0xf2, 0x01}; + u8_t oui11n[3] = {0x00,0x90,0x4C}; + u8_t HTType = 0; + + if ((eid == ZM_WLAN_EID_HT_CAPABILITY) || + (eid == ZM_WLAN_EID_EXTENDED_HT_CAPABILITY)) + { + HTEid = eid; + eid = ZM_WLAN_EID_WPA_IE; + HTType = 1; + } + + while (offset < size) + { + elen = *(buf+offset+1); + + if (*(buf+offset) == eid) + { + if ( eid == ZM_WLAN_EID_WPA_IE ) + { + if ( (HTType == 0) + && (*(buf+offset+2) == oui[0]) + && (*(buf+offset+3) == oui[1]) + && (*(buf+offset+4) == oui[2]) + && (*(buf+offset+5) == oui[3]) ) + { + zfMemoryMove(buf+offset, buf+offset+elen+2, size-offset-elen-2); + return (size-elen-2); + } + + if ( (HTType == 1) + && (*(buf+offset+2) == oui11n[0]) + && (*(buf+offset+3) == oui11n[1]) + && (*(buf+offset+4) == oui11n[2]) + && (*(buf+offset+5) == HTEid) ) + { + zfMemoryMove(buf+offset, buf+offset+elen+2, size-offset-elen-2); + return (size-elen-2); + } + } + else + { + zfMemoryMove(buf+offset, buf+offset+elen+2, size-offset-elen-2); + return (size-elen-2); + } + } + + offset += (elen+2); + } + + return size; +} + +u16_t zfUpdateElement(zdev_t* dev, u8_t* buf, u16_t size, u8_t* updateeid) +{ + u16_t offset = 0; + u16_t elen; + + while (offset < size) { + elen = *(buf+offset+1); + + if (*(buf+offset) == updateeid[0]) { + if (updateeid[1] <= elen) { + zfMemoryMove(buf+offset, updateeid, updateeid[1]+2); + zfMemoryMove(buf+offset+updateeid[1]+2, buf+offset+elen+2, size-offset-elen-2); + + return size-(elen-updateeid[1]); + } else { + zfMemoryMove(buf+offset+updateeid[1]+2, buf+offset+elen+2, size-offset-elen-2); + zfMemoryMove(buf+offset, updateeid, updateeid[1]+2); + + return size+(updateeid[1]-elen); + } + } + + offset += (elen+2); + } + + return size; +} + +u16_t zfFindSuperGElement(zdev_t* dev, zbuf_t* buf, u8_t type) +{ + u8_t subType; + u16_t offset; + u16_t bufLen; + u16_t elen; + u8_t id; + u8_t super_feature; + u8_t ouiSuperG[6] = {0x00,0x03,0x7f,0x01, 0x01, 0x00}; + + zmw_get_wlan_dev(dev); + + /* Get offset of first element */ + subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4); + if ((offset = zgElementOffsetTable[subType]) == 0xff) + { + zm_assert(0); + } + + /* Plus wlan header */ + offset += 24; + + bufLen = zfwBufGetSize(dev, buf); + /* Search loop */ + while ((offset+2)(bufLen - offset)) + { + /* Element length error */ + return 0xffff; + } + + if ( elen == 0 ) + { + return 0xffff; + } + + if (zfRxBufferEqualToStr(dev, buf, ouiSuperG, offset+2, 6) && ( zmw_rx_buf_readb(dev, buf, offset+1) >= 6)) + { + /* super_feature 0:useFastFrame, 1:useCompression, 2:useTurboPrime */ + super_feature= zmw_rx_buf_readb(dev, buf, offset+8); + if ((super_feature & 0x01) || (super_feature & 0x02) || (super_feature & 0x04)) + { + return offset; + } + } + } + /* Advance to next element */ + #if 1 + elen = zmw_rx_buf_readb(dev, buf, offset+1); + #else + if ((elen = zmw_rx_buf_readb(dev, buf, offset+1)) == 0) + { + return 0xffff; + } + #endif + + offset += (elen+2); + } + return 0xffff; +} + +u16_t zfFindXRElement(zdev_t* dev, zbuf_t* buf, u8_t type) +{ + u8_t subType; + u16_t offset; + u16_t bufLen; + u16_t elen; + u8_t id; + u8_t ouixr[6] = {0x00,0x03,0x7f,0x03, 0x01, 0x00}; + + zmw_get_wlan_dev(dev); + + /* Get offset of first element */ + subType = (zmw_rx_buf_readb(dev, buf, 0) >> 4); + if ((offset = zgElementOffsetTable[subType]) == 0xff) + { + zm_assert(0); + } + + /* Plus wlan header */ + offset += 24; + + bufLen = zfwBufGetSize(dev, buf); + /* Search loop */ + while ((offset+2)(bufLen - offset)) + { + /* Element length error */ + return 0xffff; + } + + if ( elen == 0 ) + { + return 0xffff; + } + + if (zfRxBufferEqualToStr(dev, buf, ouixr, offset+2, 6) && ( zmw_rx_buf_readb(dev, buf, offset+1) >= 6)) + { + return offset; + } + } + /* Advance to next element */ + #if 1 + elen = zmw_rx_buf_readb(dev, buf, offset+1); + #else + if ((elen = zmw_rx_buf_readb(dev, buf, offset+1)) == 0) + { + return 0xffff; + } + #endif + + offset += (elen+2); + } + return 0xffff; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfMmAddIeSupportRate */ +/* Add information element Support Rate to buffer. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : buffer to add information element */ +/* offset : add information element from this offset */ +/* eid : element ID */ +/* rateSet : CCK or OFDM */ +/* */ +/* OUTPUTS */ +/* buffer offset after adding information element */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2005.10 */ +/* */ +/************************************************************************/ +u16_t zfMmAddIeSupportRate(zdev_t* dev, zbuf_t* buf, u16_t offset, u8_t eid, u8_t rateSet) +{ + u8_t len = 0; + u16_t i; + + zmw_get_wlan_dev(dev); + + //if ( (rateSet == ZM_RATE_SET_OFDM)&&((wd->gRate & 0xff) == 0) ) + //{ + // return offset; + //} + + /* Information : Support Rate */ + if ( rateSet == ZM_RATE_SET_CCK ) + { + for (i=0; i<4; i++) + { + if ((wd->bRate & (0x1<bRateBasic & (0x1<gRate & (0x1<gRateBasic & (0x1< 0) + { + /* Element ID */ + zmw_tx_buf_writeb(dev, buf, offset, eid); + + /* Element Length */ + zmw_tx_buf_writeb(dev, buf, offset+1, len); + + /* Return value */ + offset += (2+len); + } + + return offset; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfMmAddIeDs */ +/* Add information element DS to buffer. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : buffer to add information element */ +/* offset : add information element from this offset */ +/* */ +/* OUTPUTS */ +/* buffer offset after adding information element */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2005.10 */ +/* */ +/************************************************************************/ +u16_t zfMmAddIeDs(zdev_t* dev, zbuf_t* buf, u16_t offset) +{ + zmw_get_wlan_dev(dev); + + /* Element ID */ + zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_DS); + + /* Element Length */ + zmw_tx_buf_writeb(dev, buf, offset++, 1); + + /* Information : DS */ + zmw_tx_buf_writeb(dev, buf, offset++, + zfChFreqToNum(wd->frequency, NULL)); + + return offset; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfMmAddIeErp */ +/* Add information element ERP to buffer. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : buffer to add information element */ +/* offset : add information element from this offset */ +/* */ +/* OUTPUTS */ +/* buffer offset after adding information element */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2005.10 */ +/* */ +/************************************************************************/ +u16_t zfMmAddIeErp(zdev_t* dev, zbuf_t* buf, u16_t offset) +{ + zmw_get_wlan_dev(dev); + + /* Element ID */ + zmw_tx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_ERP); + + /* Element Length */ + zmw_tx_buf_writeb(dev, buf, offset++, 1); + + /* Information : ERP */ + zmw_tx_buf_writeb(dev, buf, offset++, wd->erpElement); + + return offset; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfMmAddIeWpa */ +/* Add information element WPA to buffer. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : buffer to add information element */ +/* offset : add information element from this offset */ +/* */ +/* OUTPUTS */ +/* buffer offset after adding information element */ +/* */ +/* AUTHOR */ +/* Yuan-Gu Wei ZyDAS Technology Corporation 2006.2 */ +/* */ +/************************************************************************/ +u16_t zfMmAddIeWpa(zdev_t* dev, zbuf_t* buf, u16_t offset, u16_t apId) +{ + //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev); + int i; + + zmw_get_wlan_dev(dev); + + /* Element ID */ + //zmw_inttx_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_WPA_IE); + + /* Element Length */ + //zmw_inttx_buf_writeb(dev, buf, offset++, wd->ap.wpaLen); + for(i = 0; i < wd->ap.wpaLen[apId]; i++) + { + /* Information : WPA */ + zmw_tx_buf_writeb(dev, buf, offset++, wd->ap.wpaIe[apId][i]); + } + + return offset; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfMmAddHTCapability */ +/* Add HT Capability Infomation to buffer. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : buffer to add information element */ +/* offset : add information element from this offset */ +/* */ +/* OUTPUTS */ +/* buffer offset after adding information element */ +/* */ +/* AUTHOR */ +/* Chao-Wen Yang ZyDAS Technology Corporation 2006.06 */ +/* */ +/************************************************************************/ +u16_t zfMmAddHTCapability(zdev_t* dev, zbuf_t* buf, u16_t offset) +{ + u8_t OUI[3] = {0x0,0x90,0x4C}; + u16_t i; + + zmw_get_wlan_dev(dev); + + /* Prob ID */ + zmw_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_WPA_IE); + + if ( wd->wlanMode == ZM_MODE_AP ) + { + /* Element Length */ + zmw_buf_writeb(dev, buf, offset++, wd->ap.HTCap.Data.Length + 4); + + /* OUI Data */ + for (i = 0; i < 3; i++) + { + zmw_buf_writeb(dev, buf, offset++, OUI[i]); + } + + /* Element Type ID */ + zmw_buf_writeb(dev, buf, offset++, wd->ap.HTCap.Data.ElementID); + + /* HT Capability Data */ + for (i = 0; i < 26; i++) + { + zmw_buf_writeb(dev, buf, offset++, wd->ap.HTCap.Byte[i+2]); + } + } + else + { + /* Element Length */ + zmw_buf_writeb(dev, buf, offset++, wd->sta.HTCap.Data.Length + 4); + + /* OUI Data */ + for (i = 0; i < 3; i++) + { + zmw_buf_writeb(dev, buf, offset++, OUI[i]); + } + + /* Element Type ID */ + zmw_buf_writeb(dev, buf, offset++, wd->sta.HTCap.Data.ElementID); + + /* HT Capability Data */ + for (i = 0; i < 26; i++) + { + zmw_buf_writeb(dev, buf, offset++, wd->sta.HTCap.Byte[i+2]); + } + } + + return offset; +} + + +u16_t zfMmAddPreNHTCapability(zdev_t* dev, zbuf_t* buf, u16_t offset) +{ + //u8_t OUI[3] = {0x0,0x90,0x4C}; + u16_t i; + + zmw_get_wlan_dev(dev); + + /* Prob ID */ + zmw_buf_writeb(dev, buf, offset++, ZM_WLAN_PREN2_EID_HTCAPABILITY); + + if ( wd->wlanMode == ZM_MODE_AP ) + { + /* Element Length */ + zmw_buf_writeb(dev, buf, offset++, wd->ap.HTCap.Data.Length); + + /* HT Capability Data */ + for (i = 0; i < 26; i++) + { + zmw_buf_writeb(dev, buf, offset++, wd->ap.HTCap.Byte[i+2]); + } + } + else + { + /* Element Length */ + zmw_buf_writeb(dev, buf, offset++, wd->sta.HTCap.Data.Length); + + /* HT Capability Data */ + for (i = 0; i < 26; i++) + { + zmw_buf_writeb(dev, buf, offset++, wd->sta.HTCap.Byte[i+2]); + } + } + + return offset; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfMmAddExtendedHTCapability */ +/* Add Extended HT Capability Infomation to buffer. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : buffer to add information element */ +/* offset : add information element from this offset */ +/* */ +/* OUTPUTS */ +/* buffer offset after adding information element */ +/* */ +/* AUTHOR */ +/* Chao-Wen Yang ZyDAS Technology Corporation 2006.06 */ +/* */ +/************************************************************************/ +u16_t zfMmAddExtendedHTCapability(zdev_t* dev, zbuf_t* buf, u16_t offset) +{ + u8_t OUI[3] = {0x0,0x90,0x4C}; + u16_t i; + + zmw_get_wlan_dev(dev); + + /* Prob ID */ + zmw_buf_writeb(dev, buf, offset++, ZM_WLAN_EID_WPA_IE); + + if ( wd->wlanMode == ZM_MODE_AP ) + { + /* Element Length */ + zmw_buf_writeb(dev, buf, offset++, wd->ap.ExtHTCap.Data.Length + 4); + + /* OUI Data */ + for (i = 0; i < 3; i++) + { + zmw_buf_writeb(dev, buf, offset++, OUI[i]); + } + + /* Element Type ID */ + zmw_buf_writeb(dev, buf, offset++, wd->ap.ExtHTCap.Data.ElementID); + + /* HT Capability Data */ + for (i = 0; i < 22; i++) + { + zmw_buf_writeb(dev, buf, offset++, wd->ap.ExtHTCap.Byte[i+2]); + } + } + else + { + /* Element Length */ + zmw_buf_writeb(dev, buf, offset++, wd->sta.ExtHTCap.Data.Length + 4); + + /* OUI Data */ + for (i = 0; i < 3; i++) + { + zmw_buf_writeb(dev, buf, offset++, OUI[i]); + } + + /* Element Type ID */ + zmw_buf_writeb(dev, buf, offset++, wd->sta.ExtHTCap.Data.ElementID); + + /* HT Capability Data */ + for (i = 0; i < 22; i++) + { + zmw_buf_writeb(dev, buf, offset++, wd->sta.ExtHTCap.Byte[i+2]); + } + } + + return offset; +} + + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfSendMmFrame */ +/* Send management frame. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* frameType : management frame type */ +/* dst : destination MAC address */ +/* p1 : parameter 1 */ +/* p2 : parameter 2 */ +/* p3 : parameter 3 */ +/* */ +/* OUTPUTS */ +/* none */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2005.10 */ +/* */ +/************************************************************************/ +/* probe req : p1=> bWithSSID, p2=>R, p3=>R */ +/* probe rsp : p1=>R, p2=>R, p3=>VAP ID(AP) */ +/* deauth : p1=>Reason Code, p2=>R, p3=>VAP ID(AP) */ +/* Disasoc : p1=>Reason Code, p2=>R, p3=>VAP ID(AP) */ +/* ATIM : p1=>R, p2=>R, p3=>R */ +/* (re)asoc rsp : p1=>Status Code, p2=>AID, p3=>VAP ID(AP) */ +/* asoc req : p1=>R, p2=>R, p3=>R */ +/* reasoc req : p1=>AP MAC[0], p2=>AP MAC[1], p3=>AP MAC[2] */ +/* auth : p1=>low=Algorithm, high=Transaction, p2=>Status, p3=>VAP ID */ +void zfSendMmFrame(zdev_t* dev, u8_t frameType, u16_t* dst, + u32_t p1, u32_t p2, u32_t p3) +{ + zbuf_t* buf; + //u16_t addrTblSize; + //struct zsAddrTbl addrTbl; + u16_t offset = 0; + u16_t hlen = 32; + u16_t header[(24+25+1)/2]; + u16_t vap = 0; + u16_t i; + u8_t encrypt = 0; + u16_t aid; + + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + zm_msg2_mm(ZM_LV_2, "Send mm frame, type=", frameType); + /* TBD : Maximum size of managment frame */ + if ((buf = zfwBufAllocate(dev, 1024)) == NULL) + { + zm_msg0_mm(ZM_LV_0, "Alloc mm buf Fail!"); + return; + } + + //Reserve room for wlan header + offset = hlen; + + switch (frameType) + { + case ZM_WLAN_FRAME_TYPE_PROBEREQ : + offset = zfSendProbeReq(dev, buf, offset, (u8_t) p1); + break; + + case ZM_WLAN_FRAME_TYPE_PROBERSP : + zm_msg0_mm(ZM_LV_3, "probe rsp"); + /* 24-31 Time Stamp : hardware WON'T fill this field */ + zmw_tx_buf_writeh(dev, buf, offset, 0); + zmw_tx_buf_writeh(dev, buf, offset+2, 0); + zmw_tx_buf_writeh(dev, buf, offset+4, 0); + zmw_tx_buf_writeh(dev, buf, offset+6, 0); + offset+=8; + + /* Beacon Interval */ + zmw_tx_buf_writeh(dev, buf, offset, wd->beaconInterval); + offset+=2; + + if (wd->wlanMode == ZM_MODE_AP) + { + vap = (u16_t) p3; + /* Capability */ + zmw_tx_buf_writeh(dev, buf, offset, wd->ap.capab[vap]); + offset+=2; + /* SSID */ + offset = zfApAddIeSsid(dev, buf, offset, vap); + } + else + { + /* Capability */ + zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.capability[0]); + zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.capability[1]); + /* SSID */ + offset = zfStaAddIeSsid(dev, buf, offset); + } + + /* Support Rate */ + if ( wd->frequency < 3000 ) + { + offset = zfMmAddIeSupportRate(dev, buf, offset, + ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_CCK); + } + else + { + offset = zfMmAddIeSupportRate(dev, buf, offset, + ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_OFDM); + } + + /* DS parameter set */ + offset = zfMmAddIeDs(dev, buf, offset); + + /* TODO ¡G IBSS */ + if ( wd->wlanMode == ZM_MODE_IBSS ) + { + offset = zfStaAddIeIbss(dev, buf, offset); + + if (wd->frequency < 3000) + { + if( wd->wfc.bIbssGMode + && (wd->supportMode & (ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N)) ) // Only accompany with enabling a mode . + { + /* ERP Information */ + wd->erpElement = 0; + offset = zfMmAddIeErp(dev, buf, offset); + + /* Enable G Mode */ + /* Extended Supported Rates */ + offset = zfMmAddIeSupportRate(dev, buf, offset, + ZM_WLAN_EID_EXTENDED_RATE, ZM_RATE_SET_OFDM); + } + } + } + + + if ((wd->wlanMode == ZM_MODE_AP) + && (wd->ap.wlanType[vap] != ZM_WLAN_TYPE_PURE_B)) + { + /* ERP Information */ + offset = zfMmAddIeErp(dev, buf, offset); + + /* Extended Supported Rates */ + if ( wd->frequency < 3000 ) + { + offset = zfMmAddIeSupportRate(dev, buf, offset, + ZM_WLAN_EID_EXTENDED_RATE, ZM_RATE_SET_OFDM); + } + } + + /* ERP Information */ + //offset = zfMmAddIeErp(dev, buf, offset); + + /* Extended Supported Rates */ + //offset = zfMmAddIeSupportRate(dev, buf, offset, + // ZM_WLAN_EID_EXTENDED_RATE, ZM_RATE_SET_OFDM); + + /* TODO : RSN */ + if (wd->wlanMode == ZM_MODE_AP && wd->ap.wpaSupport[vap] == 1) + { + offset = zfMmAddIeWpa(dev, buf, offset, vap); + } + else if ( wd->wlanMode == ZM_MODE_IBSS && wd->sta.authMode == ZM_AUTH_MODE_WPA2PSK) + { + offset = zfwStaAddIeWpaRsn(dev, buf, offset, ZM_WLAN_FRAME_TYPE_AUTH); + } + + /* WME Parameters */ + if (wd->wlanMode == ZM_MODE_AP) + { + if (wd->ap.qosMode == 1) + { + offset = zfApAddIeWmePara(dev, buf, offset, vap); + } + } + + if ( wd->wlanMode != ZM_MODE_IBSS ) + { + // jhlee HT 0 + //CWYang(+) + /* TODO : Need to check if it is ok */ + /* HT Capabilities Info */ + offset = zfMmAddHTCapability(dev, buf, offset); + //CWYang(+) + /* Extended HT Capabilities Info */ + offset = zfMmAddExtendedHTCapability(dev, buf, offset); + } + + if ( wd->sta.ibssAdditionalIESize ) + offset = zfStaAddIbssAdditionalIE(dev, buf, offset); + break; + + case ZM_WLAN_FRAME_TYPE_AUTH : + if (p1 == 0x30001) + { + hlen += 4; + offset += 4; // for reserving wep header + encrypt = 1; + } + + /* Algotrithm Number */ + zmw_tx_buf_writeh(dev, buf, offset, (u16_t)(p1&0xffff)); + offset+=2; + + /* Transaction Number */ + zmw_tx_buf_writeh(dev, buf, offset, (u16_t)(p1>>16)); + offset+=2; + + /* Status Code */ + zmw_tx_buf_writeh(dev, buf, offset, (u16_t)p2); + offset+=2; + + if (wd->wlanMode == ZM_MODE_AP) + { + vap = (u16_t) p3; + } + + /* Challenge Text => share-2 or share-3 */ + if (p1 == 0x20001) + { + if (p2 == 0) //Status == success + { + zmw_buf_writeh(dev, buf, offset, 0x8010); + offset+=2; + /* share-2 : AP generate challenge text */ + for (i=0; i<128; i++) + { + wd->ap.challengeText[i] = (u8_t)zfGetRandomNumber(dev, 0); + } + zfCopyToIntTxBuffer(dev, buf, wd->ap.challengeText, offset, 128); + offset += 128; + } + } + else if (p1 == 0x30001) + { + /* share-3 : STA return challenge Text */ + zfCopyToIntTxBuffer(dev, buf, wd->sta.challengeText, offset, wd->sta.challengeText[1]+2); + offset += (wd->sta.challengeText[1]+2); + } + + break; + + case ZM_WLAN_FRAME_TYPE_ASOCREQ : + case ZM_WLAN_FRAME_TYPE_REASOCREQ : + /* Capability */ + zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.capability[0]); + zmw_tx_buf_writeb(dev, buf, offset++, wd->sta.capability[1]); + + /* Listen Interval */ + zmw_tx_buf_writeh(dev, buf, offset, 0x0005); + offset+=2; + + /* Reassocaited Request : Current AP address */ + if (frameType == ZM_WLAN_FRAME_TYPE_REASOCREQ) + { + zmw_tx_buf_writeh(dev, buf, offset, wd->sta.bssid[0]); + offset+=2; + zmw_tx_buf_writeh(dev, buf, offset, wd->sta.bssid[1]); + offset+=2; + zmw_tx_buf_writeh(dev, buf, offset, wd->sta.bssid[2]); + offset+=2; + } + + /* SSID */ + offset = zfStaAddIeSsid(dev, buf, offset); + + + if ( wd->sta.currentFrequency < 3000 ) + { + /* Support Rate */ + offset = zfMmAddIeSupportRate(dev, buf, offset, ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_CCK); + } + else + { + /* Support Rate */ + offset = zfMmAddIeSupportRate(dev, buf, offset, ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_OFDM); + } + + if ((wd->sta.capability[1] & ZM_BIT_0) == 1) + { //spectrum managment flag enable + offset = zfStaAddIePowerCap(dev, buf, offset); + offset = zfStaAddIeSupportCh(dev, buf, offset); + } + + if (wd->sta.currentFrequency < 3000) + { + /* Extended Supported Rates */ + if (wd->supportMode & (ZM_WIRELESS_MODE_24_54|ZM_WIRELESS_MODE_24_N)) + { + offset = zfMmAddIeSupportRate(dev, buf, offset, ZM_WLAN_EID_EXTENDED_RATE, ZM_RATE_SET_OFDM); + } + } + + + //offset = zfStaAddIeWpaRsn(dev, buf, offset, frameType); + //Move to wrapper function, for OS difference--CWYang(m) + //for windows wrapper, zfwStaAddIeWpaRsn() should be below: + //u16_t zfwStaAddIeWpaRsn(zdev_t* dev, zbuf_t* buf, u16_t offset, u8_t frameType) + //{ + // return zfStaAddIeWpaRsn(dev, buf, offset, frameType); + //} + offset = zfwStaAddIeWpaRsn(dev, buf, offset, frameType); + +#ifdef ZM_ENABLE_CENC + /* CENC */ + //if (wd->sta.encryMode == ZM_CENC) + offset = zfStaAddIeCenc(dev, buf, offset); +#endif //ZM_ENABLE_CENC + if (((wd->sta.wmeEnabled & ZM_STA_WME_ENABLE_BIT) != 0) //WME enabled + && ((wd->sta.apWmeCapability & 0x1) != 0)) //WME AP + { + if (((wd->sta.apWmeCapability & 0x80) != 0) //UAPSD AP + && ((wd->sta.wmeEnabled & ZM_STA_UAPSD_ENABLE_BIT) != 0)) //UAPSD enabled + { + offset = zfStaAddIeWmeInfo(dev, buf, offset, wd->sta.wmeQosInfo); + } + else + { + offset = zfStaAddIeWmeInfo(dev, buf, offset, 0); + } + } + // jhlee HT 0 + //CWYang(+) + if (wd->sta.EnableHT != 0) + { + #ifndef ZM_DISABLE_AMSDU8K_SUPPORT + //Support 8K A-MSDU + if (wd->sta.wepStatus == ZM_ENCRYPTION_WEP_DISABLED) + { + wd->sta.HTCap.Data.HtCapInfo |= HTCAP_MaxAMSDULength; + } + else + { + wd->sta.HTCap.Data.HtCapInfo &= (~HTCAP_MaxAMSDULength); + } + #else + //Support 4K A-MSDU + wd->sta.HTCap.Data.HtCapInfo &= (~HTCAP_MaxAMSDULength); + #endif + + /* HT Capabilities Info */ + if (wd->BandWidth40 == 1) { + wd->sta.HTCap.Data.HtCapInfo |= HTCAP_SupChannelWidthSet; + } + else { + wd->sta.HTCap.Data.HtCapInfo &= ~HTCAP_SupChannelWidthSet; + //wd->sta.HTCap.Data.HtCapInfo |= HTCAP_SupChannelWidthSet; + } + + wd->sta.HTCap.Data.AMPDUParam &= ~HTCAP_MaxRxAMPDU3; + wd->sta.HTCap.Data.AMPDUParam |= HTCAP_MaxRxAMPDU3; + wd->sta.HTCap.Data.MCSSet[1] = 0xFF; // MCS 8 ~ 15 + offset = zfMmAddHTCapability(dev, buf, offset); + offset = zfMmAddPreNHTCapability(dev, buf, offset); + //CWYang(+) + /* Extended HT Capabilities Info */ + //offset = zfMmAddExtendedHTCapability(dev, buf, offset); + } + + + //Store asoc request frame body, for VISTA only + wd->sta.asocReqFrameBodySize = ((offset - hlen) > + ZM_CACHED_FRAMEBODY_SIZE)? + ZM_CACHED_FRAMEBODY_SIZE:(offset - hlen); + for (i=0; ista.asocReqFrameBodySize; i++) + { + wd->sta.asocReqFrameBody[i] = zmw_tx_buf_readb(dev, buf, i + hlen); + } + break; + + case ZM_WLAN_FRAME_TYPE_ASOCRSP : + case ZM_WLAN_FRAME_TYPE_REASOCRSP : + vap = (u16_t) p3; + + /* Capability */ + zmw_tx_buf_writeh(dev, buf, offset, wd->ap.capab[vap]); + offset+=2; + + /* Status Code */ + zmw_tx_buf_writeh(dev, buf, offset, (u16_t)p1); + offset+=2; + + /* AID */ + zmw_tx_buf_writeh(dev, buf, offset, (u16_t)(p2|0xc000)); + offset+=2; + + + if ( wd->frequency < 3000 ) + { + /* Support Rate */ + offset = zfMmAddIeSupportRate(dev, buf, offset, ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_CCK); + + /* Extended Supported Rates */ + offset = zfMmAddIeSupportRate(dev, buf, offset, ZM_WLAN_EID_EXTENDED_RATE, ZM_RATE_SET_OFDM); + } + else + { + /* Support Rate */ + offset = zfMmAddIeSupportRate(dev, buf, offset, ZM_WLAN_EID_SUPPORT_RATE, ZM_RATE_SET_OFDM); + } + + + + /* WME Parameters */ + if (wd->wlanMode == ZM_MODE_AP) + { + /* TODO : if WME STA then send WME parameter element */ + if (wd->ap.qosMode == 1) + { + offset = zfApAddIeWmePara(dev, buf, offset, vap); + } + } + // jhlee HT 0 + //CWYang(+) + /* HT Capabilities Info */ + offset = zfMmAddHTCapability(dev, buf, offset); + //CWYang(+) + /* Extended HT Capabilities Info */ + offset = zfMmAddExtendedHTCapability(dev, buf, offset); + break; + + case ZM_WLAN_FRAME_TYPE_ATIM : + /* NULL frame */ + /* TODO : add two dumb bytes temporarily */ + offset += 2; + break; + + case ZM_WLAN_FRAME_TYPE_QOS_NULL : + zmw_buf_writeh(dev, buf, offset, 0x0010); + offset += 2; + break; + + case ZM_WLAN_DATA_FRAME : + break; + + case ZM_WLAN_FRAME_TYPE_DISASOC : + case ZM_WLAN_FRAME_TYPE_DEAUTH : + if (wd->wlanMode == ZM_MODE_AP) + { + vap = (u16_t) p3; + + if ((aid = zfApFindSta(dev, dst)) != 0xffff) + { + zmw_enter_critical_section(dev); + /* Clear STA table */ + wd->ap.staTable[aid].valid = 0; + + zmw_leave_critical_section(dev); + + if (wd->zfcbDisAsocNotify != NULL) + { + wd->zfcbDisAsocNotify(dev, (u8_t*)dst, vap); + } + } + } + /* Reason Code */ + zmw_tx_buf_writeh(dev, buf, offset, (u16_t)p1); + offset+=2; + break; + } + + zfwBufSetSize(dev, buf, offset); + + zm_msg2_mm(ZM_LV_2, "management frame body size=", offset-hlen); + + //Copy wlan header + zfTxGenMmHeader(dev, frameType, dst, header, offset-hlen, buf, vap, encrypt); + for (i=0; i<(hlen>>1); i++) + { + zmw_tx_buf_writeh(dev, buf, i*2, header[i]); + } + + /* Get buffer DMA address */ + //if ((addrTblSize = zfwBufMapDma(dev, buf, &addrTbl)) == 0) + //if ((addrTblSize = zfwMapTxDma(dev, buf, &addrTbl)) == 0) + //{ + // goto zlError; + //} + + zm_msg2_mm(ZM_LV_2, "offset=", offset); + zm_msg2_mm(ZM_LV_2, "hlen=", hlen); + //zm_msg2_mm(ZM_LV_2, "addrTblSize=", addrTblSize); + //zm_msg2_mm(ZM_LV_2, "addrTbl.len[0]=", addrTbl.len[0]); + //zm_msg2_mm(ZM_LV_2, "addrTbl.physAddrl[0]=", addrTbl.physAddrl[0]); + //zm_msg2_mm(ZM_LV_2, "buf->data=", buf->data); + + #if 0 + if ((err = zfHpSend(dev, NULL, 0, NULL, 0, NULL, 0, buf, 0, + ZM_INTERNAL_ALLOC_BUF, 0, 0xff)) != ZM_SUCCESS) + { + goto zlError; + } + #else + zfPutVmmq(dev, buf); + zfPushVtxq(dev); + #endif + + return; +#if 0 +zlError: + + zfwBufFree(dev, buf, 0); + return; +#endif +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfProcessManagement */ +/* Process received management frame. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : received management frame buffer */ +/* */ +/* OUTPUTS */ +/* none */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2005.10 */ +/* */ +/************************************************************************/ +void zfProcessManagement(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* AddInfo) //CWYang(m) +{ + u8_t frameType; + u16_t ta[3]; + u16_t ra[3]; + u16_t vap = 0, index = 0; + //u16_t i; + + zmw_get_wlan_dev(dev); + + ra[0] = zmw_rx_buf_readh(dev, buf, 4); + ra[1] = zmw_rx_buf_readh(dev, buf, 6); + ra[2] = zmw_rx_buf_readh(dev, buf, 8); + + ta[0] = zmw_rx_buf_readh(dev, buf, 10); + ta[1] = zmw_rx_buf_readh(dev, buf, 12); + ta[2] = zmw_rx_buf_readh(dev, buf, 14); + + frameType = zmw_rx_buf_readb(dev, buf, 0); + + if (wd->wlanMode == ZM_MODE_AP) + { +#if 1 + vap = 0; + if ((ra[0] & 0x1) != 1) + { + /* AP : Find virtual AP */ + if ((index = zfApFindSta(dev, ta)) != 0xffff) + { + vap = wd->ap.staTable[index].vap; + } + } + zm_msg2_mm(ZM_LV_2, "vap=", vap); +#endif + + /* Dispatch by frame type */ + switch (frameType) + { + /* Beacon */ + case ZM_WLAN_FRAME_TYPE_BEACON : + zfApProcessBeacon(dev, buf); + break; + /* Authentication */ + case ZM_WLAN_FRAME_TYPE_AUTH : + zfApProcessAuth(dev, buf, ta, vap); + break; + /* Association request */ + case ZM_WLAN_FRAME_TYPE_ASOCREQ : + /* Reassociation request */ + case ZM_WLAN_FRAME_TYPE_REASOCREQ : + zfApProcessAsocReq(dev, buf, ta, vap); + break; + /* Association response */ + case ZM_WLAN_FRAME_TYPE_ASOCRSP : + //zfApProcessAsocRsp(dev, buf); + break; + /* Deauthentication */ + case ZM_WLAN_FRAME_TYPE_DEAUTH : + zfApProcessDeauth(dev, buf, ta, vap); + break; + /* Disassociation */ + case ZM_WLAN_FRAME_TYPE_DISASOC : + zfApProcessDisasoc(dev, buf, ta, vap); + break; + /* Probe request */ + case ZM_WLAN_FRAME_TYPE_PROBEREQ : + zfProcessProbeReq(dev, buf, ta); + break; + /* Probe response */ + case ZM_WLAN_FRAME_TYPE_PROBERSP : + zfApProcessProbeRsp(dev, buf, AddInfo); + break; + /* Action */ + case ZM_WLAN_FRAME_TYPE_ACTION : + zfApProcessAction(dev, buf); + break; + } + } + else //if ((wd->wlanMode == ZM_MODE_INFRASTRUCTURE) || (wd->wlanMode == ZM_MODE_IBSS)) + { + /* Dispatch by frame type */ + switch (frameType) + { + /* Beacon */ + case ZM_WLAN_FRAME_TYPE_BEACON : + /* if enable 802.11h and current chanel is silent but receive beacon from other AP */ + if (((wd->regulationTable.allowChannel[wd->regulationTable.CurChIndex].channelFlags + & ZM_REG_FLAG_CHANNEL_CSA) != 0) && wd->sta.DFSEnable) + { + wd->regulationTable.allowChannel[wd->regulationTable.CurChIndex].channelFlags + &= ~(ZM_REG_FLAG_CHANNEL_CSA & ZM_REG_FLAG_CHANNEL_PASSIVE); + } + zfStaProcessBeacon(dev, buf, AddInfo); //CWYang(m) + break; + /* Authentication */ + case ZM_WLAN_FRAME_TYPE_AUTH : + /* TODO : vap parameter is useless in STA mode, get rid of it */ + zfStaProcessAuth(dev, buf, ta, 0); + break; + /* Association request */ + case ZM_WLAN_FRAME_TYPE_ASOCREQ : + /* TODO : vap parameter is useless in STA mode, get rid of it */ + zfStaProcessAsocReq(dev, buf, ta, 0); + break; + /* Association response */ + case ZM_WLAN_FRAME_TYPE_ASOCRSP : + /* Reassociation request */ + case ZM_WLAN_FRAME_TYPE_REASOCRSP : + zfStaProcessAsocRsp(dev, buf); + break; + /* Deauthentication */ + case ZM_WLAN_FRAME_TYPE_DEAUTH : + zm_debug_msg0("Deauthentication received"); + zfStaProcessDeauth(dev, buf); + break; + /* Disassociation */ + case ZM_WLAN_FRAME_TYPE_DISASOC : + zm_debug_msg0("Disassociation received"); + zfStaProcessDisasoc(dev, buf); + break; + /* Probe request */ + case ZM_WLAN_FRAME_TYPE_PROBEREQ : + zfProcessProbeReq(dev, buf, ta); + break; + /* Probe response */ + case ZM_WLAN_FRAME_TYPE_PROBERSP : + /* if enable 802.11h and current chanel is silent but receive probe response from other AP */ + if (((wd->regulationTable.allowChannel[wd->regulationTable.CurChIndex].channelFlags + & ZM_REG_FLAG_CHANNEL_CSA) != 0) && wd->sta.DFSEnable) + { + wd->regulationTable.allowChannel[wd->regulationTable.CurChIndex].channelFlags + &= ~(ZM_REG_FLAG_CHANNEL_CSA & ZM_REG_FLAG_CHANNEL_PASSIVE); + } + zfStaProcessProbeRsp(dev, buf, AddInfo); + break; + + case ZM_WLAN_FRAME_TYPE_ATIM: + zfStaProcessAtim(dev, buf); + break; + /* Action */ + case ZM_WLAN_FRAME_TYPE_ACTION : + zm_msg0_mm(ZM_LV_2, "ProcessActionMgtFrame"); + zfStaProcessAction(dev, buf); + break; + } + } +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfProcessProbeReq */ +/* Process probe request management frame. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* buf : auth frame buffer */ +/* */ +/* OUTPUTS */ +/* none */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2005.10 */ +/* */ +/************************************************************************/ +void zfProcessProbeReq(zdev_t* dev, zbuf_t* buf, u16_t* src) +{ + u16_t offset; + u8_t len; + u16_t i, j; + u8_t ch; + u16_t sendFlag; + + zmw_get_wlan_dev(dev); + + /* check mode : AP/IBSS */ + if ((wd->wlanMode != ZM_MODE_AP) && (wd->wlanMode != ZM_MODE_IBSS)) + { + zm_msg0_mm(ZM_LV_3, "Ignore probe req"); + return; + } + + if ((wd->wlanMode != ZM_MODE_AP) && (wd->sta.adapterState == ZM_STA_STATE_DISCONNECT)) + { + zm_msg0_mm(ZM_LV_3, "Packets dropped due to disconnect state"); + return; + } + + if ( wd->wlanMode == ZM_MODE_IBSS ) + { + zfSendMmFrame(dev, ZM_WLAN_FRAME_TYPE_PROBERSP, src, 0, 0, 0); + + return; + } + + /* check SSID */ + if ((offset = zfFindElement(dev, buf, ZM_WLAN_EID_SSID)) == 0xffff) + { + zm_msg0_mm(ZM_LV_3, "probe req SSID not found"); + return; + } + + len = zmw_rx_buf_readb(dev, buf, offset+1); + + for (i=0; iap.apBitmap & (1<| + * 1| ACK |1 + * |<-----------------------------| + * 2| ADDBA Response |2 + * |<-----------------------------| + * 3| ACK |3 + * |----------------------------->| + * 4 4 + */ +#define ZM_AGG_ADDBA_REQUEST 1 +#define ZM_AGG_ADDBA_REQUEST_ACK 2 +#define ZM_AGG_ADDBA_RESPONSE 3 +#define ZM_AGG_ADDBA_RESPONSE_ACK 4 + +#define ZM_AGG_SINGLE_MPDU 00 +#define ZM_AGG_FIRST_MPDU 01 +#define ZM_AGG_MIDDLE_MPDU 11 +#define ZM_AGG_LAST_MPDU 10 +/* + * end of Aggregate control + */ + +#define TID_TX struct aggQueue* +#define TID_BAW struct baw_q* +#define BAW wd->baw_enabler +#define DESTQ wd->destQ + +/* + * Queue access + */ +#define zm_agg_qlen(dev, head, tail) ((head - tail) & ZM_AGGQ_SIZE_MASK) +#define zm_agg_inQ(tid_tx, pt) ((((pt - tid_tx->aggTail) & ZM_AGGQ_SIZE_MASK) < \ + ((tid_tx->aggHead - tid_tx->aggTail) & ZM_AGGQ_SIZE_MASK))? TRUE:FALSE) +#define zm_agg_plus(pt) pt = (pt + 1) & ZM_AGGQ_SIZE_MASK +#define zm_agg_min(A, B) ((A>B)? B:A) +#define zm_agg_GetTime() wd->tick +#define TXQL (zfHpGetMaxTxdCount(dev) - zfHpGetFreeTxdCount(dev)) + +/* don't change AGG_MIN_TXQL easily, this might cause BAW BSOD */ +#define AGG_MIN_TXQL 2 +/* + * consider tcp,udp,ac(1234) + */ +#define zm_agg_dynamic_threshold(dev, ar) ((ar > 16)? 11: \ + (ar > 12)? 8: \ + (ar > 8)? 5: \ + (ar > 4)? 2:1) +#define zm_agg_weight(ac) ((3 == ac)? 4: \ + (2 == ac)? 3: \ + (0 == ac)? 2:1) +/* + * the required free queue ratio per ac + */ + +#define zm_agg_ratio(ac) ((3 == ac)? 3: \ + (2 == ac)? (zfHpGetMaxTxdCount(dev)*1/4): \ + (0 == ac)? (zfHpGetMaxTxdCount(dev)*2/4): \ + (zfHpGetMaxTxdCount(dev)*3/4)) + +//#define zm_agg_ratio(ac) 3 +/* + * end of Queue access + */ + +#define ZM_AGGMSG_LEV ZM_LV_3 +#define zm_msg0_agg(lv, msg) if (ZM_AGGMSG_LEV >= lv) \ + {zm_debug_msg0(msg);} +#define zm_msg1_agg(lv, msg, val) if (ZM_AGGMSG_LEV >= lv) \ + {zm_debug_msg1(msg, val);} +#define zm_msg2_agg(lv, msg, val) if (ZM_AGGMSG_LEV >= lv) \ + {zm_debug_msg2(msg, val);} + +#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW +struct baw_header_r { + u16_t *header; + u16_t *mic; + u16_t *snap; + u16_t headerLen; + u16_t micLen; + u16_t snapLen; + u16_t removeLen; + u8_t keyIdx; +}; + +struct baw_header { + u16_t header[29];//[(8+30+2+18)/2]; 58 bytes /* ctr+(4+a1+a2+a3+2+a4)+qos+iv */ + u16_t headerLen; + u16_t mic[4]; //[8/2]; 8 bytes + u16_t micLen; + u16_t snap[4]; //[8/2]; 8 bytes + u16_t snapLen; + u16_t removeLen; + u8_t keyIdx; +}; + +struct bufInfo { + zbuf_t* buf; + u8_t baw_retransmit; + u32_t timestamp; + struct baw_header *baw_header; +}; +#endif +struct aggElement +{ + zbuf_t* buf; + u32_t arrivalTime; + u8_t baw_retransmit; + struct zsAdditionInfo addInfo; + //struct baw_header baw_header; +}; + + +#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW +struct baw_buf +{ + zbuf_t* buf; + u16_t baw_seq; + u32_t timestamp; + u8_t baw_retransmit; + struct baw_header baw_header; +}; + +struct baw_q { + struct baw_buf frame[ZM_VTXQ_SIZE]; + u16_t enabled; + u16_t start_seq; + u16_t head; + u16_t tail; + u16_t size; + TID_TX tid_tx; + + //struct baw_header *baw_header; +}; + +struct baw_enabler +{ + struct baw_q tid_baw[ZM_BAW_POOL_SIZE]; + u8_t delPoint; + void (*core)(zdev_t* dev, u16_t baw_seq, u32_t bitmap, u16_t aggLen); + //void (*core); + void (*init)(zdev_t* dev); + TID_BAW (*getNewQ)(zdev_t* dev, u16_t start_seq, TID_TX tid_tx); + TID_BAW (*getQ)(zdev_t* dev, u16_t baw_seq); + u16_t (*insert)(zdev_t* dev, zbuf_t* buf, u16_t baw_seq, TID_BAW tid_baw, u8_t baw_retransmit, struct baw_header_r *header_r); + struct bufInfo* (*pop)(zdev_t* dev, u16_t index, TID_BAW tid_baw); + void (*enable)(zdev_t* dev, TID_BAW tid_baw, u16_t start_seq); + void (*disable)(zdev_t* dev, TID_BAW tid_baw); + +}; +#endif +struct aggQueue +{ + struct aggElement aggvtxq[ZM_AGGQ_SIZE]; + u16_t aggHead; + u16_t aggTail; + s16_t size; + u16_t aggQSTA; + u16_t aggQEnabled; + u16_t ac; + u16_t tid; + u16_t aggReady; + u16_t clearFlag; + u16_t deleteFlag; + u32_t lastArrival; + u16_t aggFrameSize; + u16_t bar_ssn; /* starting sequence number in BAR */ + u16_t dst[3]; + u16_t complete; /* complete indication pointer */ +}; + +struct aggSta +{ + u16_t count[ZM_AC]; + TID_TX tid_tx[8]; + u16_t aggFlag[ZM_AC]; +}; + +struct agg_tid_rx +{ + u16_t aid; + u16_t ac; + u16_t addBaExchangeStatusCode; + //struct zsAdditionInfo *addInfo; + u16_t seq_start; /* first seq expected next */ + u16_t baw_head; /* head of valid block ack window */ + u16_t baw_tail; /* tail of valid block ack window */ + //u16_t free_count; /* block ack window size */ + u8_t sq_exceed_count; + u8_t sq_behind_count; + struct aggElement frame[ZM_AGG_BAW_SIZE + 1]; /* out-of-order rx frames */ +}; + +struct aggControl +{ + u16_t aggEnabled; + u16_t ampduIndication; + u16_t addbaIndication; + //TID_BAW tid_baw; + u32_t timestamp; +}; + +struct aggBaFrameParameter +{ + zbuf_t* buf; + u16_t ba_parameter; + u8_t dialog; + u16_t ba_policy; + u16_t tid; + u16_t buffer_size; + u16_t ba_timeout; + u16_t ba_start_seq; + u16_t status_code; +}; + +struct aggBarControl +{ + u16_t bar_ack_policy ; + u16_t multi_tid ; + u16_t compressed_bitmap ; + u16_t tid_info ; +}; + +struct aggTally +{ + u32_t got_packets_sum; + u32_t got_bytes_sum; + u32_t sent_packets_sum; + u32_t sent_bytes_sum; + u32_t avg_got_packets; + u32_t avg_got_bytes; + u32_t avg_sent_packets; + u32_t avg_sent_bytes; + u16_t time; +}; + + +struct destQ { + struct dest{ + u16_t Qtype : 1; /* 0 aggr, 1 vtxq */ + TID_TX tid_tx; + void* vtxq; + + struct dest* next; + } *dest[4]; + struct dest* Head[4]; + //s16_t size[4]; + u16_t ppri; + void (*insert)(zdev_t* dev, u16_t Qtype, u16_t ac, TID_TX tid_tx, void* vtxq); + void (*delete)(zdev_t* dev, u16_t Qtype, TID_TX tid_tx, void* vtxq); + void (*init)(zdev_t* dev); + struct dest* (*getNext)(zdev_t* dev, u16_t ac); + u16_t (*exist)(zdev_t* dev, u16_t Qtype, u16_t ac, TID_TX tid_tx, void* vtxq); + //void (*scan)(zdev_t* dev); +}; +/* + * aggregation tx + */ +void zfAggInit(zdev_t* dev); +u16_t zfApFindSta(zdev_t* dev, u16_t* addr); +u16_t zfAggGetSta(zdev_t* dev, zbuf_t* buf); +TID_TX zfAggTxGetQueue(zdev_t* dev, u16_t aid, u16_t tid); +TID_TX zfAggTxNewQueue(zdev_t* dev, u16_t aid, u16_t tid, zbuf_t* buf); +u16_t zfAggTxEnqueue(zdev_t* dev, zbuf_t* buf, u16_t aid, TID_TX tid_tx); +u16_t zfAggTx(zdev_t* dev, zbuf_t* buf, u16_t tid); +u16_t zfAggTxReadyCount(zdev_t* dev, u16_t ac); +u16_t zfAggTxPartial(zdev_t* dev, u16_t ac, u16_t readycount); +u16_t zfAggTxSend(zdev_t* dev, u32_t freeTxd, TID_TX tid_tx); +TID_TX zfAggTxGetReadyQueue(zdev_t* dev, u16_t ac); +zbuf_t* zfAggTxGetVtxq(zdev_t* dev, TID_TX tid_tx); +u16_t zfAggTxDeleteQueue(zdev_t* dev, u16_t qnum); +u16_t zfAggScanAndClear(zdev_t* dev, u32_t time); +u16_t zfAggClearQueue(zdev_t* dev); +void zfAggTxScheduler(zdev_t* dev, u8_t ScanAndClear); + +/* tid_tx manipulation */ +#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW +u16_t zfAggTidTxInsertHead(zdev_t* dev, struct bufInfo* buf_info, TID_TX tid_tx); +#endif +void zfAggDestInsert(zdev_t* dev, u16_t Qtype, u16_t ac, TID_TX tid_tx, void* vtxq); +void zfAggDestDelete(zdev_t* dev, u16_t Qtype, TID_TX tid_tx, void* vtxq); +void zfAggDestInit(zdev_t* dev); +struct dest* zfAggDestGetNext(zdev_t* dev, u16_t ac); +u16_t zfAggDestExist(zdev_t* dev, u16_t Qtype, u16_t ac, TID_TX tid_tx, void* vtxq); +/* + * aggregation rx + */ +struct agg_tid_rx *zfAggRxEnabled(zdev_t* dev, zbuf_t* buf); +u16_t zfAggRx(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo *addInfo, struct agg_tid_rx *tid_rx); +struct agg_tid_rx *zfAggRxGetQueue(zdev_t* dev, zbuf_t* buf); +u16_t zfAggRxEnqueue(zdev_t* dev, zbuf_t* buf, struct agg_tid_rx *tid_rx, struct zsAdditionInfo *addInfo); +u16_t zfAggRxFlush(zdev_t* dev, u16_t seq_no, struct agg_tid_rx *tid_rx); +u16_t zfAggRxFreeBuf(zdev_t* dev, u16_t destroy); +u16_t zfAggRxClear(zdev_t* dev, u32_t time); +void zfAggRecvBAR(zdev_t* dev, zbuf_t* buf); +/* + * end of aggregation rx + */ + +/* + * ADDBA + */ +u16_t zfAggSendAddbaRequest(zdev_t* dev, u16_t *dst, u16_t ac, u16_t up); +u16_t zfAggSetAddbaFrameBody(zdev_t* dev,zbuf_t* buf, u16_t offset, u16_t ac, u16_t up); +u16_t zfAggGenAddbaHeader(zdev_t* dev, u16_t* dst, + u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt); +u16_t zfAggProcessAction(zdev_t* dev, zbuf_t* buf); +u16_t zfAggBlockAckActionFrame(zdev_t* dev, zbuf_t* buf); +u16_t zfAggRecvAddbaRequest(zdev_t* dev, zbuf_t* buf); +u16_t zfAggRecvAddbaResponse(zdev_t* dev, zbuf_t* buf); +u16_t zfAggRecvDelba(zdev_t* dev, zbuf_t* buf); +u16_t zfAggSendAddbaResponse(zdev_t* dev, struct aggBaFrameParameter *bf); +u16_t zfAggSetAddbaResponseFrameBody(zdev_t* dev, zbuf_t* buf, + struct aggBaFrameParameter *bf, u16_t offset); +u16_t zfAggAddbaSetTidRx(zdev_t* dev, zbuf_t* buf, + struct aggBaFrameParameter *bf); +/* + * zfAggTxSendEth + */ +u16_t zfAggTxSendEth(zdev_t* dev, zbuf_t* buf, u16_t port, u16_t bufType, u8_t flag, struct aggControl *aggControl, TID_TX tid_tx); + +/* + * statistics functions + */ +u16_t zfAggTallyReset(zdev_t* dev); + +u16_t zfAggPrintTally(zdev_t* dev); + +/* + * BAR + */ +void zfAggInvokeBar(zdev_t* dev, TID_TX tid_tx); +u16_t zfAggSendBar(zdev_t* dev, TID_TX tid_tx, struct aggBarControl *aggBarControl); +u16_t zfAggSetBarBody(zdev_t* dev, zbuf_t* buf, u16_t offset, TID_TX tid_tx, struct aggBarControl *aggBarControl); +u16_t zfAggGenBarHeader(zdev_t* dev, u16_t* dst, + u16_t* header, u16_t len, zbuf_t* buf, u16_t vap, u8_t encrypt); + +#ifndef ZM_ENABLE_FW_BA_RETRANSMISSION //disable BAW +/* BAW BA retransmission */ +void zfBawCore(zdev_t* dev, u16_t baw_seq, u32_t bitmap, u16_t aggLen); +void zfBawInit(zdev_t* dev); +TID_BAW zfBawGetNewQ(zdev_t* dev, u16_t start_seq, TID_TX tid_tx); +u16_t zfBawInsert(zdev_t* dev, zbuf_t* buf, u16_t baw_seq, TID_BAW tid_baw, u8_t baw_retransmit, struct baw_header_r *header_r); +struct bufInfo* zfBawPop(zdev_t* dev, u16_t index, TID_BAW tid_baw); +void zfBawEnable(zdev_t* dev, TID_BAW tid_baw, u16_t start_seq); +void zfBawDisable(zdev_t* dev, TID_BAW tid_baw); +TID_BAW zfBawGetQ(zdev_t* dev, u16_t baw_seq); +void zfAggTxRetransmit(zdev_t* dev, struct bufInfo *buf_info, struct aggControl *aggControl, TID_TX tid_tx); +#endif +/* extern functions */ +extern zbuf_t* zfGetVtxq(zdev_t* dev, u8_t ac); + +#endif /* #ifndef _CAGG_H */ + --- linux-2.6.28.orig/drivers/staging/otus/80211core/ledmgr.c +++ linux-2.6.28/drivers/staging/otus/80211core/ledmgr.c @@ -0,0 +1,557 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "cprecomp.h" + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfLedCtrlType1 */ +/* Traditional single-LED state */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Stephen Chen Atheros Communications, INC. 2007.6 */ +/* */ +/************************************************************************/ +// bit 15-12 : Toff for Scan state +// 11-8 : Ton for Scan state +// 7 : Reserved +// 6 : mode +//-------------------------------------- +// bit 6 = 0 +// 5-4 : Connect state +// 00 => always off +// 01 => always on +// 10 => Idle off, acitve on +// 11 => Idle on, active off +//-------------------------------------- +// bit 6 = 1 +// 5-4 : freq +// 00 => 1Hz +// 01 => 0.5Hz +// 10 => 0.25Hz +// 11 => 0.125Hz +//-------------------------------------- +// 3 : Power save state +// 0 => always off in power save state +// 1 => works as connect state +// 2 : Disable state +// 1 : Reserved +// 0 : Power-on state +void zfLedCtrlType1(zdev_t* dev) +{ + u16_t i; + u32_t ton, toff, tmp, period; + zmw_get_wlan_dev(dev); + + for (i=0; iledStruct.ledMode[i] & 0xf00) >> 8) * 5; + toff = ((wd->ledStruct.ledMode[i] & 0xf000) >> 12) * 5; + + if ((ton + toff) != 0) + { + tmp = wd->ledStruct.counter / (ton+toff); + tmp = wd->ledStruct.counter - (tmp * (ton+toff)); + if (tmp < ton) + { + zfHpLedCtrl(dev, i, 1); + } + else + { + zfHpLedCtrl(dev, i, 0); + } + } + } + else + { + if ((zfPowerSavingMgrIsSleeping(dev)) && ((wd->ledStruct.ledMode[i] & 0x8) == 0)) + { + zfHpLedCtrl(dev, i, 0); + } + else + { + //Connect state + if ((wd->ledStruct.ledMode[i] & 0x40) == 0) + { + if ((wd->ledStruct.counter & 1) == 0) + { + zfHpLedCtrl(dev, i, (wd->ledStruct.ledMode[i] & 0x10) >> 4); + } + else + { + if ((wd->ledStruct.txTraffic > 0) || (wd->ledStruct.rxTraffic > 0)) + { + wd->ledStruct.txTraffic = wd->ledStruct.rxTraffic = 0; + if ((wd->ledStruct.ledMode[i] & 0x20) != 0) + { + zfHpLedCtrl(dev, i, ((wd->ledStruct.ledMode[i] & 0x10) >> 4)^1); + } + } + } + }// if ((wd->ledStruct.ledMode[i] & 0x40) == 0) + else + { + period = 5 * (1 << ((wd->ledStruct.ledMode[i] & 0x30) >> 4)); + tmp = wd->ledStruct.counter / (period*2); + tmp = wd->ledStruct.counter - (tmp * (period*2)); + if (tmp < period) + { + if ((wd->ledStruct.counter & 1) == 0) + { + zfHpLedCtrl(dev, i, 0); + } + else + { + if ((wd->ledStruct.txTraffic > 0) || (wd->ledStruct.rxTraffic > 0)) + { + wd->ledStruct.txTraffic = wd->ledStruct.rxTraffic = 0; + zfHpLedCtrl(dev, i, 1); + } + } + } + else + { + if ((wd->ledStruct.counter & 1) == 0) + { + zfHpLedCtrl(dev, i, 1); + } + else + { + if ((wd->ledStruct.txTraffic > 0) || (wd->ledStruct.rxTraffic > 0)) + { + wd->ledStruct.txTraffic = wd->ledStruct.rxTraffic = 0; + zfHpLedCtrl(dev, i, 0); + } + } + } + } //else, if ((wd->ledStruct.ledMode[i] & 0x40) == 0) + } //else, if (zfPowerSavingMgrIsSleeping(dev)) + } //else : if (zfStaIsConnected(dev) != TRUE) + } //for (i=0; iSlow blinking, Amber then Blue per 500ms */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Shang-Chun Liu Atheros Communications, INC. 2007.11 */ +/* */ +/******************************************************************************/ +void zfLedCtrlType2_scan(zdev_t* dev); + +void zfLedCtrlType2(zdev_t* dev) +{ + u32_t ton, toff, tmp, period; + u16_t OperateLED; + zmw_get_wlan_dev(dev); + + if (zfStaIsConnected(dev) != TRUE) + { + // Disconnect state + if(wd->ledStruct.counter % 4 != 0) + { + // Update LED each 400ms(4*100) + // Prevent this situation + // _______ ___ + // LED[0] ON | | | x | + // ------ OFF->+-+-+-+-+-+-+-+-+-+-+-+->>>... + // LED[1] ON + // + return; + } + + if (((wd->state == ZM_WLAN_STATE_DISABLED) && (wd->sta.bChannelScan)) + || ((wd->state != ZM_WLAN_STATE_DISABLED) && (wd->sta.bAutoReconnect))) + { + // Scan/AutoReconnect state + zfLedCtrlType2_scan(dev); + } + else + { + // Neither Connected nor Scan + zfHpLedCtrl(dev, 0, 0); + zfHpLedCtrl(dev, 1, 0); + } + } + else + { + if( wd->sta.bChannelScan ) + { + // Scan state + if(wd->ledStruct.counter % 4 != 0) + return; + zfLedCtrlType2_scan(dev); + return; + } + + if(wd->frequency < 3000) + { + OperateLED = 0; // LED[0]: work on 2.4G (b/g band) + zfHpLedCtrl(dev, 1, 0); + } + else + { + OperateLED = 1; // LED[1]: work on 5G (a band) + zfHpLedCtrl(dev, 0, 0); + } + + if ((zfPowerSavingMgrIsSleeping(dev)) && ((wd->ledStruct.ledMode[OperateLED] & 0x8) == 0)) + { + // If Sleeping, turn OFF + zfHpLedCtrl(dev, OperateLED, 0); + } + else + { + //Connect state + if ((wd->ledStruct.counter & 1) == 0) // even + { + // No traffic, always ON + zfHpLedCtrl(dev, OperateLED, 1); + } + else // odd + { + if ((wd->ledStruct.txTraffic > 0) || (wd->ledStruct.rxTraffic > 0)) + { + // If have traffic, turn OFF + // _____ _ _ _ _____ + // LED[Operate] ON | | | | | | | | + // ------------ OFF->-+-+-+-+-+-+-+-+-+-+-+-+-+->>>... + // + wd->ledStruct.txTraffic = wd->ledStruct.rxTraffic = 0; + zfHpLedCtrl(dev, OperateLED, 0); + } + } + } + } +} + +void zfLedCtrlType2_scan(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + // When doing scan, blink(Amber/Blue) and off per 500ms (about 400ms in our driver) + // _______ _______ + // LED[0] ON | | 8 12 | | + // ------ OFF->-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+->>>... + // LED[1] ON 0 4 |_______| 0 3 + // + + switch(wd->ledStruct.counter % 16) + { + case 0: // case 0~3, LED[0] on + if(wd->supportMode & ZM_WIRELESS_MODE_24) + { + zfHpLedCtrl(dev, 0, 1); + zfHpLedCtrl(dev, 1, 0); + } + else + { + zfHpLedCtrl(dev, 1, 1); + zfHpLedCtrl(dev, 0, 0); + } + break; + + case 8: // case 8~11, LED[1] on + if(wd->supportMode & ZM_WIRELESS_MODE_5) + { + zfHpLedCtrl(dev, 1, 1); + zfHpLedCtrl(dev, 0, 0); + } + else + { + zfHpLedCtrl(dev, 0, 1); + zfHpLedCtrl(dev, 1, 0); + } + break; + + default: // others, all off + zfHpLedCtrl(dev, 0, 0); + zfHpLedCtrl(dev, 1, 0); + break; + } +} + +/**********************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfLedCtrlType3 */ +/* Customize for Netgear Single-LED state ((bug#32243)) */ +/* */ +/* ¡EOff: when the adapter is disabled or hasn't started to associate with AP */ +/* yet. */ +/* ¡EOn: Once adpater associate with AP successfully */ +/* ¡ESlow blinking: whenever adapters do site-survey or try to associate with AP */ +/* - If there is a connection already, and adapters do site-survey or */ +/* re-associate action, the LED should keep LED backgraoud as ON, thus */ +/* the blinking behavior SHOULD be OFF (200ms) - ON (800ms) and continue this*/ +/* cycle. */ +/* - If there is no connection yet, and adapters start to do site-survey or */ +/* associate action, the LED should keep LED background as OFF, thus the */ +/* blinking behavior SHOULD be ON (200ms) - OFF (800ms) and continue this */ +/* cycle. */ +/* - For the case that associate fail, adpater should keep associating, and the*/ +/* LED should also keep slow blinking. */ +/* ¡EQuick blinking: to blink OFF-ON cycle for each time that traffic packet is */ +/* received or is transmitted. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Shang-Chun Liu Atheros Communications, INC. 2008.01 */ +/* */ +/**********************************************************************************/ +void zfLedCtrlType3_scan(zdev_t* dev, u16_t isConnect); + +void zfLedCtrlType3(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + if (zfStaIsConnected(dev) != TRUE) + { + // Disconnect state + if(wd->ledStruct.counter % 2 != 0) + { + // Update LED each 200ms(2*100) + // Prevent this situation + // ___ _ + // LED[0] ON | | |x| + // ------ OFF->+-+-+-+-+-+-+->>>... + // + return; + } + + if (((wd->state == ZM_WLAN_STATE_DISABLED) && (wd->sta.bChannelScan)) + || ((wd->state != ZM_WLAN_STATE_DISABLED) && (wd->sta.bAutoReconnect))) + { + // Scan/AutoReconnect state + zfLedCtrlType3_scan(dev, 0); + } + else + { + // Neither Connected nor Scan + zfHpLedCtrl(dev, 0, 0); + zfHpLedCtrl(dev, 1, 0); + } + } + else + { + if( wd->sta.bChannelScan ) + { + // Scan state + if(wd->ledStruct.counter % 2 != 0) + return; + zfLedCtrlType3_scan(dev, 1); + return; + } + + if ((zfPowerSavingMgrIsSleeping(dev)) && ((wd->ledStruct.ledMode[0] & 0x8) == 0)) + { + // If Sleeping, turn OFF + zfHpLedCtrl(dev, 0, 0); + zfHpLedCtrl(dev, 1, 0); + } + else + { + //Connect state + if ((wd->ledStruct.counter & 1) == 0) // even + { + // No traffic, always ON + zfHpLedCtrl(dev, 0, 1); + zfHpLedCtrl(dev, 1, 1); + } + else // odd + { + if ((wd->ledStruct.txTraffic > 0) || (wd->ledStruct.rxTraffic > 0)) + { + // If have traffic, turn OFF + // _____ _ _ _ _____ + // LED[Operate] ON | | | | | | | | + // ------------ OFF->-+-+-+-+-+-+-+-+-+-+-+-+-+->>>... + // + wd->ledStruct.txTraffic = wd->ledStruct.rxTraffic = 0; + zfHpLedCtrl(dev, 0, 0); + zfHpLedCtrl(dev, 1, 0); + } + } + } + } +} + +void zfLedCtrlType3_scan(zdev_t* dev, u16_t isConnect) +{ + u32_t ton, toff, tmp; + zmw_get_wlan_dev(dev); + + // Doing scan when : + // 1. Disconnected: ON (200ms) - OFF (800ms) (200ms-600ms in our driver) + // ___ ___ ___ + // LED[0] ON | | | | | | + // ------ OFF->-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+->>>... + // 0 2 4 6 8 10 12 14 16 + // 2. Connected: ON (800ms) - OFF (200ms) (600ms-200ms in our driver) + // ___________ ___________ ______ + // LED[0] ON | | | | | + // ------ OFF->-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+->>>... + // 0 2 4 6 8 10 12 14 16 + + //Scan state + if(!isConnect) + ton = 2, toff = 6; + else + ton = 6, toff = 2; + + if ((ton + toff) != 0) + { + tmp = wd->ledStruct.counter % (ton+toff); + if (tmp < ton) + { + zfHpLedCtrl(dev, 0, 1); + zfHpLedCtrl(dev, 1, 1); + } + else + { + zfHpLedCtrl(dev, 0, 0); + zfHpLedCtrl(dev, 1, 0); + } + } +} + +/******************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfLedCtrl_BlinkWhenScan_Alpha */ +/* Customize for Alpha/DLink LED */ +/* - Blink LED 12 times within 3 seconds when doing Active Scan */ +/* ___ ___ ___ ___ */ +/* LED[0] ON | | | | | | | | */ +/* -------OFF->-+-+-+-+-+-+-+-+-+-+-+-+-+--+-->>>... */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Shang-Chun Liu Atheros Communications, INC. 2007.11 */ +/* */ +/******************************************************************************/ +void zfLedCtrl_BlinkWhenScan_Alpha(zdev_t* dev) +{ + static u32_t counter = 0; + zmw_get_wlan_dev(dev); + + if(counter > 34) // counter for 3 sec + { + wd->ledStruct.LEDCtrlFlag &= ~(u8_t)ZM_LED_CTRL_FLAG_ALPHA; + counter = 0; + } + + if( (counter % 3) < 2) + zfHpLedCtrl(dev, 0, 1); + else + zfHpLedCtrl(dev, 0, 0); + + counter++; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfLed100msCtrl */ +/* LED 100 milliseconds timer. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Stephen Chen Atheros Communications, INC. 2007.6 */ +/* */ +/************************************************************************/ +void zfLed100msCtrl(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + wd->ledStruct.counter++; + + if(wd->ledStruct.LEDCtrlFlag) + { + switch(wd->ledStruct.LEDCtrlFlag) { + case ZM_LED_CTRL_FLAG_ALPHA: + zfLedCtrl_BlinkWhenScan_Alpha(dev); + break; + } + } + else + { + switch(wd->ledStruct.LEDCtrlType) { + case 1: // Traditional 1 LED + zfLedCtrlType1(dev); + break; + + case 2: // Dual-LEDs for Netgear + zfLedCtrlType2(dev); + break; + + case 3: // Single-LED for Netgear (WN111v2) + zfLedCtrlType3(dev); + break; + + default: + zfLedCtrlType1(dev); + break; + } + } +} + --- linux-2.6.28.orig/drivers/staging/otus/80211core/struct.h +++ linux-2.6.28/drivers/staging/otus/80211core/struct.h @@ -0,0 +1,1315 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _STRUCT_H +#define _STRUCT_H + +#include "../oal_marc.h" + +#define ZM_SW_LOOP_BACK 0 /* 1=>enable, 0=>disable */ +#define ZM_PCI_LOOP_BACK 0 /* 1=>enable, 0=>disable */ +#define ZM_PROTOCOL_RESPONSE_SIMULATION 0 + +#define ZM_RX_FRAME_SIZE 1600 + +extern const u8_t zg11bRateTbl[4]; +extern const u8_t zg11gRateTbl[8]; + +#define ZM_DRIVER_CORE_MAJOR_VERSION 1 +#define ZM_DRIVER_CORE_MINOR_VERSION 1 +#define ZM_DRIVER_CORE_BRANCH_MAJOR_VERSION 3 +#define ZM_DRIVER_CORE_BRANCH_MINOR_VERSION 39 + +#ifndef ZM_VTXQ_SIZE +#define ZM_VTXQ_SIZE 1024 //2^N +#endif + +#define ZM_VTXQ_SIZE_MASK (ZM_VTXQ_SIZE-1) +#define ZM_VMMQ_SIZE 8 //2^N +#define ZM_VMMQ_SIZE_MASK (ZM_VMMQ_SIZE-1) + +#include "cagg.h" + +#define ZM_AGG_POOL_SIZE 20 +#define ZM_RATE_TABLE_SIZE 32 + +#define ZM_MAX_BUF_DISCRETE_NUMBER 5 + + + + + + + + + +/**********************************************************************************/ +/* IBSS macros */ +/**********************************************************************************/ +#define ZM_IBSS_PEER_ALIVE_COUNTER 4 + +/**********************************************************************************/ +/* BIT mapping related macros */ +/**********************************************************************************/ + +#define ZM_BIT_0 0x1 +#define ZM_BIT_1 0x2 +#define ZM_BIT_2 0x4 +#define ZM_BIT_3 0x8 +#define ZM_BIT_4 0x10 +#define ZM_BIT_5 0x20 +#define ZM_BIT_6 0x40 +#define ZM_BIT_7 0x80 +#define ZM_BIT_8 0x100 +#define ZM_BIT_9 0x200 +#define ZM_BIT_10 0x400 +#define ZM_BIT_11 0x800 +#define ZM_BIT_12 0x1000 +#define ZM_BIT_13 0x2000 +#define ZM_BIT_14 0x4000 +#define ZM_BIT_15 0x8000 +#define ZM_BIT_16 0x10000 +#define ZM_BIT_17 0x20000 +#define ZM_BIT_18 0x40000 +#define ZM_BIT_19 0x80000 +#define ZM_BIT_20 0x100000 +#define ZM_BIT_21 0x200000 +#define ZM_BIT_22 0x400000 +#define ZM_BIT_23 0x800000 +#define ZM_BIT_24 0x1000000 +#define ZM_BIT_25 0x2000000 +#define ZM_BIT_26 0x4000000 +#define ZM_BIT_27 0x8000000 +#define ZM_BIT_28 0x10000000 +#define ZM_BIT_29 0x20000000 //WPA support +#define ZM_BIT_30 0x40000000 +#define ZM_BIT_31 0x80000000 + + +/**********************************************************************************/ +/* MAC address related macros */ +/**********************************************************************************/ +#define ZM_MAC_BYTE_TO_WORD(macb, macw) macw[0] = macb[0] + (macb[1] << 8); \ + macw[1] = macb[2] + (macb[3] << 8); \ + macw[2] = macb[4] + (macb[5] << 8); + +#define ZM_MAC_WORD_TO_BYTE(macw, macb) macb[0] = (u8_t) (macw[0] & 0xff); \ + macb[1] = (u8_t) (macw[0] >> 8); \ + macb[2] = (u8_t) (macw[1] & 0xff); \ + macb[3] = (u8_t) (macw[1] >> 8); \ + macb[4] = (u8_t) (macw[2] & 0xff); \ + macb[5] = (u8_t) (macw[2] >> 8); + +#define ZM_MAC_0(macw) ((u8_t)(macw[0] & 0xff)) +#define ZM_MAC_1(macw) ((u8_t)(macw[0] >> 8)) +#define ZM_MAC_2(macw) ((u8_t)(macw[1] & 0xff)) +#define ZM_MAC_3(macw) ((u8_t)(macw[1] >> 8)) +#define ZM_MAC_4(macw) ((u8_t)(macw[2] & 0xff)) +#define ZM_MAC_5(macw) ((u8_t)(macw[2] >> 8)) + +#define ZM_IS_MULTICAST_OR_BROADCAST(mac) (mac[0] & 0x01) +#define ZM_IS_MULTICAST(mac) ((mac[0] & 0x01) && (((u8_t)mac[0]) != 0xFF)) + +#define ZM_MAC_EQUAL(mac1, mac2) ((mac1[0]==mac2[0])&&(mac1[1]==mac2[1])&&(mac1[2]==mac2[2])) +#define ZM_MAC_NOT_EQUAL(mac1, mac2) ((mac1[0]!=mac2[0])||(mac1[1]!=mac2[1])||(mac1[2]!=mac2[2])) +/**********************************************************************************/ +/* MAC address related mac'ros (end) */ +/**********************************************************************************/ +#define ZM_BYTE_TO_WORD(A, B) ((A<<8)+B) +#define ZM_ROL32( A, n ) \ + ( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) ) +#define ZM_ROR32( A, n ) ZM_ROL32( (A), 32-(n) ) +#define ZM_LO8(v16) ((u8_t)((v16) & 0xFF)) +#define ZM_HI8(v16) ((u8_t)(((v16)>>8)&0xFF)) + +#ifdef ZM_ENABLE_BUFFER_TRACE +extern void zfwBufTrace(zdev_t* dev, zbuf_t *buf, u8_t *functionName); +#define ZM_BUFFER_TRACE(dev, buf) zfwBufTrace(dev, buf, __func__); +#else +#define ZM_BUFFER_TRACE(dev, buf) +#endif + +/* notification events to heart beat function */ +#define ZM_BSSID_LIST_SCAN 0x01 + +/* CAM mode */ +#define ZM_CAM_AP 0x1 +#define ZM_CAM_STA 0x2 +#define ZM_CAM_HOST 0x4 + +/* finite state machine for adapter */ +#define ZM_STA_STATE_DISCONNECT 1 +#define ZM_STA_STATE_CONNECTING 2 +#define ZM_STA_STATE_CONNECTED 3 + +/* Event definitions for finite state machine */ +#define ZM_EVENT_TIMEOUT_SCAN 0x0000 +#define ZM_EVENT_TIMEOUT_BG_SCAN 0x0001 +#define ZN_EVENT_TIMEOUT_RECONNECT 0x0002 +#define ZM_EVENT_TIMEOUT_INIT_SCAN 0x0003 +#define ZM_EVENT_TIMEOUT_AUTH 0x0004 +#define ZM_EVENT_TIMEOUT_ASSO 0x0005 +#define ZM_EVENT_TIMEOUT_AUTO_SCAN 0x0006 +#define ZM_EVENT_TIMEOUT_MIC_FAIL 0x0007 +#define ZM_EVENT_TIMEOUT_CHECK_AP 0x0008 +#define ZM_EVENT_CONNECT 0x0009 +#define ZM_EVENT_INIT_SCAN 0x000a +#define ZM_EVENT_SCAN 0x000b +#define ZM_EVENT_BG_SCAN 0x000c +#define ZM_EVENT_DISCONNECT 0x000d +#define ZM_EVENT_WPA_MIC_FAIL 0x000e +#define ZM_EVENT_AP_ALIVE 0x000f +#define ZM_EVENT_CHANGE_TO_AP 0x0010 +#define ZM_EVENT_CHANGE_TO_STA 0x0011 +#define ZM_EVENT_IDLE 0x0012 +#define ZM_EVENT_AUTH 0x0013 +#define ZM_EVENT_ASSO_RSP 0x0014 +#define ZM_EVENT_WPA_PK_OK 0x0015 +#define ZM_EVENT_WPA_GK_OK 0x0016 +#define ZM_EVENT_RCV_BEACON 0x0017 +#define ZM_EVENT_RCV_PROBE_RSP 0x0018 +#define ZM_EVENT_SEND_DATA 0x0019 +#define ZM_EVENT_AUTO_SCAN 0x001a +#define ZM_EVENT_MIC_FAIL1 0x001d +#define ZM_EVENT_MIC_FAIL2 0x001e +#define ZM_EVENT_IBSS_MONITOR 0x001f +#define ZM_EVENT_IN_SCAN 0x0020 +#define ZM_EVENT_CM_TIMER 0x0021 +#define ZM_EVENT_CM_DISCONNECT 0x0022 +#define ZM_EVENT_CM_BLOCK_TIMER 0x0023 +#define ZM_EVENT_TIMEOUT_ADDBA 0x0024 +#define ZM_EVENT_TIMEOUT_PERFORMANCE 0x0025 +#define ZM_EVENT_SKIP_COUNTERMEASURE 0x0026 +#define ZM_EVENT_NONE 0xffff + +/* Actions after call finite state machine */ +#define ZM_ACTION_NONE 0x0000 +#define ZM_ACTION_QUEUE_DATA 0x0001 +#define ZM_ACTION_DROP_DATA 0x0002 + +/* Timers for finite state machine */ +#define ZM_TICK_ZERO 0 +#define ZM_TICK_INIT_SCAN_END 8 +#define ZM_TICK_NEXT_BG_SCAN 50 +#define ZM_TICK_BG_SCAN_END 8 +#define ZM_TICK_AUTH_TIMEOUT 4 +#define ZM_TICK_ASSO_TIMEOUT 4 +#define ZM_TICK_AUTO_SCAN 300 +#define ZM_TICK_MIC_FAIL_TIMEOUT 6000 +#define ZM_TICK_CHECK_AP1 150 +#define ZM_TICK_CHECK_AP2 350 +#define ZM_TICK_CHECK_AP3 250 +#define ZM_TICK_IBSS_MONITOR 160 +#define ZM_TICK_IN_SCAN 4 +#define ZM_TICK_CM_TIMEOUT 6000 +#define ZM_TICK_CM_DISCONNECT 200 +#define ZM_TICK_CM_BLOCK_TIMEOUT 6000 + +/* Fix bug#33338 Counter Measure Issur */ +#ifdef NDIS_CM_FOR_XP +#define ZM_TICK_CM_TIMEOUT_OFFSET 2160 +#define ZM_TICK_CM_DISCONNECT_OFFSET 72 +#define ZM_TICK_CM_BLOCK_TIMEOUT_OFFSET 2160 +#else +#define ZM_TICK_CM_TIMEOUT_OFFSET 0 +#define ZM_TICK_CM_DISCONNECT_OFFSET 0 +#define ZM_TICK_CM_BLOCK_TIMEOUT_OFFSET 0 +#endif + +#define ZM_TIME_ACTIVE_SCAN 30 //ms +#define ZM_TIME_PASSIVE_SCAN 110 //ms + +/* finite state machine for BSS connect */ +#define ZM_STA_CONN_STATE_NONE 0 +#define ZM_STA_CONN_STATE_AUTH_OPEN 1 +#define ZM_STA_CONN_STATE_AUTH_SHARE_1 2 +#define ZM_STA_CONN_STATE_AUTH_SHARE_2 3 +#define ZM_STA_CONN_STATE_ASSOCIATE 4 +#define ZM_STA_CONN_STATE_SSID_NOT_FOUND 5 +#define ZM_STA_CONN_STATE_AUTH_COMPLETED 6 + +/* finite state machine for WPA handshaking */ +#define ZM_STA_WPA_STATE_INIT 0 +#define ZM_STA_WPA_STATE_PK_OK 1 +#define ZM_STA_WPA_STATE_GK_OK 2 + +/* various timers */ +#define ZM_INTERVAL_CONNECT_TIMEOUT 20 /* 200 milisecond */ + +/* IBSS definitions */ +#define ZM_IBSS_PARTNER_LOST 0 +#define ZM_IBSS_PARTNER_ALIVE 1 +#define ZM_IBSS_PARTNER_CHECK 2 + +#define ZM_BCMC_ARRAY_SIZE 16 /* Must be 2^N */ +#define ZM_UNI_ARRAY_SIZE 16 /* Must be 2^N */ + +#define ZM_MAX_DEFRAG_ENTRIES 4 /* 2^N */ +#define ZM_DEFRAG_AGING_TIME_SEC 5 /* 5 seconds */ + +#define ZM_MAX_WPAIE_SIZE 128 +/* WEP related definitions */ +#define ZM_USER_KEY_DEFAULT 64 +#define ZM_USER_KEY_PK 0 /* Pairwise Key */ +#define ZM_USER_KEY_GK 1 /* Group Key */ +/* AP WLAN Type */ +#define ZM_WLAN_TYPE_PURE_B 2 +#define ZM_WLAN_TYPE_PURE_G 1 +#define ZM_WLAN_TYPE_MIXED 0 + +/* HAL State */ +#define ZM_HAL_STATE_INIT 0 +#define ZM_HAL_STATE_RUNNING 1 + +/* AP Capability */ +#define ZM_All11N_AP 0x01 +#define ZM_XR_AP 0x02 +#define ZM_SuperG_AP 0x04 + +/* MPDU Density */ +#define ZM_MPDU_DENSITY_NONE 0 +#define ZM_MPDU_DENSITY_1_8US 1 +#define ZM_MPDU_DENSITY_1_4US 2 +#define ZM_MPDU_DENSITY_1_2US 3 +#define ZM_MPDU_DENSITY_1US 4 +#define ZM_MPDU_DENSITY_2US 5 +#define ZM_MPDU_DENSITY_4US 6 +#define ZM_MPDU_DENSITY_8US 7 + +/* Software Encryption */ +#define ZM_SW_TKIP_ENCRY_EN 0x01 +#define ZM_SW_TKIP_DECRY_EN 0x02 +#define ZM_SW_WEP_ENCRY_EN 0x04 +#define ZM_SW_WEP_DECRY_EN 0x08 + +/* Default Support Rate */ +#define ZM_DEFAULT_SUPPORT_RATE_ZERO 0x0 +#define ZM_DEFAULT_SUPPORT_RATE_DISCONNECT 0x1 +#define ZM_DEFAULT_SUPPORT_RATE_IBSS_B 0x2 +#define ZM_DEFAULT_SUPPORT_RATE_IBSS_AG 0x3 + +/* security related definitions */ +struct zsTkipSeed +{ + u8_t tk[32]; /* key */ + u8_t ta[6]; + u16_t ttak[5]; + u16_t ppk[6]; + u16_t iv16,iv16tmp; + u32_t iv32,iv32tmp; +}; + +struct zsMicVar +{ + u32_t k0, k1; // Key + u32_t left, right; // Current state + u32_t m; // Message accumulator (single word) + u16_t nBytes; // # bytes in M +}; + +struct zsDefragEntry +{ + u8_t fragCount; + u8_t addr[6]; + u16_t seqNum; + zbuf_t* fragment[8]; + u32_t tick; +}; + +struct zsDefragList +{ + struct zsDefragEntry defragEntry[ZM_MAX_DEFRAG_ENTRIES]; + u8_t replaceNum; +}; + +#define ZM_MAX_OPPOSITE_COUNT 16 +#define ZM_MAX_TX_SAMPLES 15 +#define ZM_TX_RATE_DOWN_CRITERIA 80 +#define ZM_TX_RATE_UP_CRITERIA 200 + + +#define ZM_MAX_PROBE_HIDDEN_SSID_SIZE 2 +struct zsSsidList +{ + u8_t ssid[32]; + u8_t ssidLen; +}; + +struct zsWrapperSetting +{ + u8_t bDesiredBssid; + u8_t desiredBssid[6]; + u16_t bssid[3]; + u8_t ssid[32]; + u8_t ssidLen; + u8_t authMode; + u8_t wepStatus; + u8_t encryMode; + u8_t wlanMode; + u16_t frequency; + u16_t beaconInterval; + u8_t dtim; + u8_t preambleType; + u16_t atimWindow; + + struct zsSsidList probingSsidList[ZM_MAX_PROBE_HIDDEN_SSID_SIZE]; + + u8_t dropUnencryptedPkts; + u8_t ibssJoinOnly; + u32_t adhocMode; + u8_t countryIsoName[4]; + u16_t autoSetFrequency; + + /* AP */ + u8_t bRateBasic; + u8_t gRateBasic; + u32_t nRateBasic; + u8_t bgMode; + + /* Common */ + u8_t staWmeEnabled; + u8_t staWmeQosInfo; + u8_t apWmeEnabled; + + + /* rate information: added in the future */ +}; + +struct zsWrapperFeatureCtrl +{ + u8_t bIbssGMode; +}; + +#define ZM_MAX_PS_STA 16 +#define ZM_PS_QUEUE_SIZE 32 + +struct zsStaPSEntity +{ + u8_t bUsed; + u8_t macAddr[6]; + u8_t bDataQueued; +}; + +struct zsStaPSList +{ + u8_t count; + struct zsStaPSEntity entity[ZM_MAX_PS_STA]; +}; + +#define ZM_MAX_TIMER_COUNT 32 + +/* double linked list */ +struct zsTimerEntry +{ + u16_t event; + u32_t timer; + struct zsTimerEntry *pre; + struct zsTimerEntry *next; +}; + +struct zsTimerList +{ + u8_t freeCount; + struct zsTimerEntry list[ZM_MAX_TIMER_COUNT]; + struct zsTimerEntry *head; + struct zsTimerEntry *tail; +}; + +/* Multicast list */ +#define ZM_MAX_MULTICAST_LIST_SIZE 64 + +struct zsMulticastAddr +{ + u8_t addr[6]; +}; + +struct zsMulticastList +{ + u8_t size; + struct zsMulticastAddr macAddr[ZM_MAX_MULTICAST_LIST_SIZE]; +}; + +enum ieee80211_cwm_mode { + CWM_MODE20, + CWM_MODE2040, + CWM_MODE40, + CWM_MODEMAX + +}; + +enum ieee80211_cwm_extprotspacing { + CWM_EXTPROTSPACING20, + CWM_EXTPROTSPACING25, + CWM_EXTPROTSPACINGMAX +}; + +enum ieee80211_cwm_width { + CWM_WIDTH20, + CWM_WIDTH40 +}; + +enum ieee80211_cwm_extprotmode { + CWM_EXTPROTNONE, /* no protection */ + CWM_EXTPROTCTSONLY, /* CTS to self */ + CWM_EXTPROTRTSCTS, /* RTS-CTS */ + CWM_EXTPROTMAX +}; + +struct ieee80211_cwm { + + /* Configuration */ + enum ieee80211_cwm_mode cw_mode; /* CWM mode */ + u8_t cw_extoffset; /* CWM Extension Channel Offset */ + enum ieee80211_cwm_extprotmode cw_extprotmode; /* CWM Extension Channel Protection Mode */ + enum ieee80211_cwm_extprotspacing cw_extprotspacing;/* CWM Extension Channel Protection Spacing */ + u32_t cw_enable; /* CWM State Machine Enabled */ + u32_t cw_extbusythreshold;/* CWM Extension Channel Busy Threshold */ + + /* State */ + enum ieee80211_cwm_width cw_width; /* CWM channel width */ +}; + + +/* AP : STA database structure */ +struct zsStaTable +{ + u32_t time; /* tick time */ + //u32_t phyCtrl; /* Tx PHY CTRL */ + u16_t addr[3]; /* STA MAC address */ + u16_t state; /* aut/asoc */ + //u16_t retry; /* Retry count */ + struct zsRcCell rcCell; + + u8_t valid; /* Valid flag : 1=>valid */ + u8_t psMode; /* STA power saving mode */ + u8_t staType; /* 0=>11b, 1=>11g, 2=>11n */ + u8_t qosType; /* 0=>Legacy, 1=>WME */ + u8_t qosInfo; /* WME QoS info */ + u8_t vap; /* Virtual AP ID */ + u8_t encryMode; /* Encryption type for this STA */ + u8_t keyIdx; + struct zsMicVar txMicKey; + struct zsMicVar rxMicKey; + u16_t iv16; + u32_t iv32; +#ifdef ZM_ENABLE_CENC + /* CENC */ + u8_t cencKeyIdx; + u32_t txiv[4]; + u32_t rxiv[4]; +#endif //ZM_ENABLE_CENC +}; + +struct zdStructWds +{ + u8_t wdsBitmap; /* Set bit-N to 1 to enable WDS */ + u8_t encryMode[ZM_MAX_WDS_SUPPORT]; /* WDS encryption mode */ + u16_t macAddr[ZM_MAX_WDS_SUPPORT][3]; /* WDS neighbor MAC address */ +}; + + // htcapinfo 16bits +#define HTCAP_AdvCodingCap 0x0001 +#define HTCAP_SupChannelWidthSet 0x0002 +#define HTCAP_DynamicSMPS 0x0004 +#define HTCAP_SMEnabled 0x000C +#define HTCAP_GreenField 0x0010 +#define HTCAP_ShortGIfor20MHz 0x0020 +#define HTCAP_ShortGIfor40MHz 0x0040 +#define HTCAP_TxSTBC 0x0080 +#define HTCAP_RxOneStream 0x0100 +#define HTCAP_RxTwoStream 0x0200 +#define HTCAP_RxThreeStream 0x0300 +#define HTCAP_DelayedBlockACK 0x0400 +#define HTCAP_MaxAMSDULength 0x0800 +#define HTCAP_DSSSandCCKin40MHz 0x1000 +#define HTCAP_PSMPSup 0x2000 +#define HTCAP_STBCControlFrameSup 0x4000 +#define HTCAP_LSIGTXOPProtectionSUP 0x8000 + // Ampdu HT Parameter Info 8bits +#define HTCAP_MaxRxAMPDU0 0x00 +#define HTCAP_MaxRxAMPDU1 0x01 +#define HTCAP_MaxRxAMPDU2 0x02 +#define HTCAP_MaxRxAMPDU3 0x03 + // PCO 8bits +#define HTCAP_PCO 0x01 +#define HTCAP_TransmissionTime1 0x02 +#define HTCAP_TransmissionTime2 0x04 +#define HTCAP_TransmissionTime3 0x06 + // MCS FeedBack 8bits +#define HTCAP_PlusHTCSupport 0x04 +#define HTCAP_RDResponder 0x08 + // TX Beamforming 0 8bits +#define HTCAP_TxBFCapable 0x01 +#define HTCAP_RxStaggeredSoundCap 0x02 +#define HTCAP_TxStaggeredSoundCap 0x04 +#define HTCAP_RxZLFCapable 0x08 +#define HTCAP_TxZLFCapable 0x10 +#define HTCAP_ImplicitTxBFCapable 0x20 + // Tx Beamforming 1 8bits +#define HTCAP_ExplicitCSITxBFCap 0x01 +#define HTCAP_ExpUncompSteerMatrCap 0x02 + // Antenna Selection Capabilities 8bits +#define HTCAP_AntennaSelectionCap 0x01 +#define HTCAP_ExplicitCSITxASCap 0x02 +#define HTCAP_AntennaIndFeeTxASCap 0x04 +#define HTCAP_ExplicitCSIFeedbackCap 0x08 +#define HTCAP_AntennaIndFeedbackCap 0x10 +#define HTCAP_RxASCap 0x20 +#define HTCAP_TxSoundPPDUsCap 0x40 + + + +struct zsHTCapability +{ + u8_t ElementID; + u8_t Length; + // HT Capability Info + u16_t HtCapInfo; + u8_t AMPDUParam; + u8_t MCSSet[16]; //16 bytes + // Extended HT Capability Info + u8_t PCO; + u8_t MCSFeedBack; + + u8_t TxBFCap[4]; + u8_t AselCap; +}; + +union zuHTCapability +{ + struct zsHTCapability Data; + u8_t Byte[28]; +}; + + //channelinfo 8bits +#define ExtHtCap_ExtChannelOffsetAbove 0x01 +#define ExtHtCap_ExtChannelOffsetBelow 0x03 +#define ExtHtCap_RecomTxWidthSet 0x04 +#define ExtHtCap_RIFSMode 0x08 +#define ExtHtCap_ControlAccessOnly 0x10 + //operatinginfo 16bits +#define ExtHtCap_NonGFDevicePresent 0x0004 + //beaconinfo 16bits +#define ExtHtCap_DualBeacon 0x0040 +#define ExtHtCap_DualSTBCProtection 0x0080 +#define ExtHtCap_SecondaryBeacon 0x0100 +#define ExtHtCap_LSIGTXOPProtectFullSup 0x0200 +#define ExtHtCap_PCOActive 0x0400 +#define ExtHtCap_PCOPhase 0x0800 + + +struct zsExtHTCapability +{ + u8_t ElementID; + u8_t Length; + u8_t ControlChannel; + u8_t ChannelInfo; + u16_t OperatingInfo; + u16_t BeaconInfo; + // Supported MCS Set + u8_t MCSSet[16]; +}; + +union zuExtHTCapability +{ + struct zsExtHTCapability Data; + u8_t Byte[24]; +}; + +struct InformationElementSta { + struct zsHTCapability HtCap; + struct zsExtHTCapability HtInfo; +}; + +struct InformationElementAp { + struct zsHTCapability HtCap; +}; + +#define ZM_MAX_FREQ_REQ_QUEUE 32 +typedef void (*zfpFreqChangeCompleteCb)(zdev_t* dev); + +struct zsWlanDevFreqControl +{ + u16_t freqReqQueue[ZM_MAX_FREQ_REQ_QUEUE]; + u8_t freqReqBw40[ZM_MAX_FREQ_REQ_QUEUE]; + u8_t freqReqExtOffset[ZM_MAX_FREQ_REQ_QUEUE]; + zfpFreqChangeCompleteCb freqChangeCompCb[ZM_MAX_FREQ_REQ_QUEUE]; + u8_t freqReqQueueHead; + u8_t freqReqQueueTail; +}; + +struct zsWlanDevAp +{ + u16_t protectedObss; /* protected overlap BSS */ + u16_t staAgingTimeSec; /* in second, STA will be deathed if it does not */ + /* active for this long time */ + u16_t staProbingTimeSec;/* in second, STA will be probed if it does not */ + /* active for this long time */ + u8_t authSharing; /* authentication on going*/ + u8_t bStaAssociated; /* 11b STA associated */ + u8_t gStaAssociated; /* 11g STA associated */ + u8_t nStaAssociated; /* 11n STA associated */ + u16_t protectionMode; /* AP protection mode flag */ + u16_t staPowerSaving; /* Set associated power saving STA count */ + + + + zbuf_t* uniArray[ZM_UNI_ARRAY_SIZE]; /* array to store unicast frames */ + u16_t uniHead; + u16_t uniTail; + + /* HT Capability Info */ + union zuHTCapability HTCap; //CWYang(+) + + /* Extended HT Capability Info */ + union zuExtHTCapability ExtHTCap; //CWYang(+) + + /* STA table */ + struct zsStaTable staTable[ZM_MAX_STA_SUPPORT]; + + /* WDS */ + struct zdStructWds wds; + /* WPA */ + u8_t wpaIe[ZM_MAX_AP_SUPPORT][ZM_MAX_WPAIE_SIZE]; + u8_t wpaLen[ZM_MAX_AP_SUPPORT]; + u8_t stawpaIe[ZM_MAX_AP_SUPPORT][ZM_MAX_WPAIE_SIZE]; + u8_t stawpaLen[ZM_MAX_AP_SUPPORT]; + u8_t wpaSupport[ZM_MAX_AP_SUPPORT]; + + //struct zsTkipSeed bcSeed; + u8_t bcKeyIndex[ZM_MAX_AP_SUPPORT]; + u8_t bcHalKeyIdx[ZM_MAX_AP_SUPPORT]; + struct zsMicVar bcMicKey[ZM_MAX_AP_SUPPORT]; + u16_t iv16[ZM_MAX_AP_SUPPORT]; + u32_t iv32[ZM_MAX_AP_SUPPORT]; + +#ifdef ZM_ENABLE_CENC + /* CENC */ + u32_t txiv[ZM_MAX_AP_SUPPORT][4]; +#endif //ZM_ENABLE_CENC + + /* Virtual AP */ + u8_t beaconCounter; + u8_t vapNumber; + u8_t apBitmap; /* Set bit-N to 1 to enable VAP */ + u8_t hideSsid[ZM_MAX_AP_SUPPORT]; + u8_t authAlgo[ZM_MAX_AP_SUPPORT]; + u8_t ssid[ZM_MAX_AP_SUPPORT][32]; /* SSID */ + u8_t ssidLen[ZM_MAX_AP_SUPPORT]; /* SSID length */ + u8_t encryMode[ZM_MAX_AP_SUPPORT]; + u8_t wepStatus[ZM_MAX_AP_SUPPORT]; + u16_t capab[ZM_MAX_AP_SUPPORT]; /* Capability */ + u8_t timBcmcBit[ZM_MAX_AP_SUPPORT]; /* BMCM bit of TIM */ + u8_t wlanType[ZM_MAX_AP_SUPPORT]; + + /* Array to store BC or MC frames */ + zbuf_t* bcmcArray[ZM_MAX_AP_SUPPORT][ZM_BCMC_ARRAY_SIZE]; + u16_t bcmcHead[ZM_MAX_AP_SUPPORT]; + u16_t bcmcTail[ZM_MAX_AP_SUPPORT]; + + u8_t qosMode; /* 1=>WME */ + u8_t uapsdEnabled; + struct zsQueue* uapsdQ; + + u8_t challengeText[128]; + + struct InformationElementAp ie[ZM_MAX_STA_SUPPORT]; + + +}; + +#define ZM_MAX_BLOCKING_AP_LIST_SIZE 4 /* 2^N */ +struct zsBlockingAp +{ + u8_t addr[6]; + u8_t weight; +}; + +#define ZM_SCAN_MGR_SCAN_NONE 0 +#define ZM_SCAN_MGR_SCAN_INTERNAL 1 +#define ZM_SCAN_MGR_SCAN_EXTERNAL 2 + +struct zsWlanDevStaScanMgr +{ + u8_t scanReqs[2]; + u8_t currScanType; + u8_t scanStartDelay; +}; + +#define ZM_PS_MSG_STATE_ACTIVE 0 +#define ZM_PS_MSG_STATE_SLEEP 1 +#define ZM_PS_MSG_STATE_T1 2 +#define ZM_PS_MSG_STATE_T2 3 +#define ZM_PS_MSG_STATE_S1 4 + +#define ZM_PS_MAX_SLEEP_PERIODS 3 // The number of beacon periods + +struct zsWlanDevStaPSMgr +{ + u8_t state; + u8_t isSleepAllowed; + u8_t maxSleepPeriods; + u8_t ticks; + u32_t lastTxUnicastFrm; + u32_t lastTxMulticastFrm; + u32_t lastTxBroadcastFrm; + u8_t tempWakeUp; /*enable when wake up but still in ps mode */ + u16_t sleepAllowedtick; +}; + +struct zsWlanDevSta +{ + u32_t beaconTxCnt; /* Transmitted beacon counter (in IBSS) */ + u8_t txBeaconInd; /* In IBSS mode, true means that we just transmit a beacon during + last beacon period. + */ + u16_t beaconCnt; /* receive beacon count, will be perodically reset */ + u16_t bssid[3]; /* BSSID of connected AP */ + u8_t ssid[32]; /* SSID */ + u8_t ssidLen; /* SSID length */ + u8_t mTxRate; /* Tx rate for multicast */ + u8_t uTxRate; /* Tx rate for unicast */ + u8_t mmTxRate; /* Tx rate for management frame */ + u8_t bChannelScan; + u8_t bScheduleScan; + + u8_t InternalScanReq; + u16_t activescanTickPerChannel; + u16_t passiveScanTickPerChannel; + u16_t scanFrequency; + u32_t connPowerInHalfDbm; + + u16_t currentFrequency; + u16_t currentBw40; + u16_t currentExtOffset; + + u8_t bPassiveScan; + + struct zsBlockingAp blockingApList[ZM_MAX_BLOCKING_AP_LIST_SIZE]; + + //struct zsBssInfo bssInfoPool[ZM_MAX_BSS]; + struct zsBssInfo* bssInfoArray[ZM_MAX_BSS]; + struct zsBssList bssList; + u8_t bssInfoArrayHead; + u8_t bssInfoArrayTail; + u8_t bssInfoFreeCount; + + u8_t authMode; + u8_t currentAuthMode; + u8_t wepStatus; + u8_t encryMode; + u8_t keyId; +#ifdef ZM_ENABLE_IBSS_WPA2PSK + u8_t ibssWpa2Psk; +#endif +#ifdef ZM_ENABLE_CENC + u8_t cencKeyId; //CENC +#endif //ZM_ENABLE_CENC + u8_t dropUnencryptedPkts; + u8_t ibssJoinOnly; + u8_t adapterState; + u8_t oldAdapterState; + u8_t connectState; + u8_t connectRetry; + u8_t wpaState; + u8_t wpaIe[ZM_MAX_IE_SIZE + 2]; + u8_t rsnIe[ZM_MAX_IE_SIZE + 2]; + u8_t challengeText[255+2]; + u8_t capability[2]; + //u8_t connectingHiddenAP; + //u8_t scanWithSSID; + u16_t aid; + u32_t mgtFrameCount; + u8_t bProtectionMode; + u32_t NonNAPcount; + u8_t RTSInAGGMode; + u32_t connectTimer; + u16_t atimWindow; + u8_t desiredBssid[6]; + u8_t bDesiredBssid; + struct zsTkipSeed txSeed; + struct zsTkipSeed rxSeed[4]; + struct zsMicVar txMicKey; + struct zsMicVar rxMicKey[4]; + u16_t iv16; + u32_t iv32; + struct zsOppositeInfo oppositeInfo[ZM_MAX_OPPOSITE_COUNT]; + u8_t oppositeCount; + u8_t bssNotFoundCount; /* sitesurvey for search desired ISBB threshold */ + u16_t rxBeaconCount; + u8_t beaconMissState; + u32_t rxBeaconTotal; + u8_t bIsSharedKey; + u8_t connectTimeoutCount; + + u8_t recvAtim; + + /* ScanMgr Control block */ + struct zsWlanDevStaScanMgr scanMgr; + struct zsWlanDevStaPSMgr psMgr; + + // The callback would be called if receiving an unencrypted packets but + // the station is in encrypted mode. The wrapper could decide whether + // to drop the packet by its OS setting. + zfpStaRxSecurityCheckCb pStaRxSecurityCheckCb; + + /* WME */ + u8_t apWmeCapability; //bit-0 => a WME AP + //bit-7 => a UAPSD AP + u8_t wmeParameterSetCount; + + u8_t wmeEnabled; + #define ZM_STA_WME_ENABLE_BIT 0x1 + #define ZM_STA_UAPSD_ENABLE_BIT 0x2 + u8_t wmeQosInfo; + + u8_t wmeConnected; + u8_t qosInfo; + struct zsQueue* uapsdQ; + + /* countermeasures */ + u8_t cmMicFailureCount; + u8_t cmDisallowSsidLength; + u8_t cmDisallowSsid[32]; + + /* power-saving mode */ + u8_t powerSaveMode; + zbuf_t* staPSDataQueue[ZM_PS_QUEUE_SIZE]; + u8_t staPSDataCount; + + /* IBSS power-saving mode */ + /* record the STA which has entered the PS mode */ + struct zsStaPSList staPSList; + /* queue the data of the PS STAs */ + zbuf_t* ibssPSDataQueue[ZM_PS_QUEUE_SIZE]; + u8_t ibssPSDataCount; + u8_t ibssPrevPSDataCount; + u8_t bIbssPSEnable; + /* BIT_15: ON/OFF, BIT_0~14: Atim Timer */ + u16_t ibssAtimTimer; + + /* WPA2 */ + struct zsPmkidInfo pmkidInfo; + + /* Multicast list related objects */ + struct zsMulticastList multicastList; + + /* XP packet filter feature : */ + /* 1=>enable: All multicast address packets, not just the ones enumerated in the multicast address list. */ + /* 0=>disable */ + u8_t bAllMulticast; + + /* reassociation flag */ + u8_t connectByReasso; + u8_t failCntOfReasso; + + /* for HT configure control setting */ + u8_t preambleTypeHT; /* HT: 0 Mixed mode 1 Green field */ + u8_t htCtrlBandwidth; + u8_t htCtrlSTBC; + u8_t htCtrlSG; + u8_t defaultTA; + + u8_t connection_11b; + + u8_t EnableHT; + u8_t SG40; + u8_t HT2040; + /* for WPA setting */ + u8_t wpaSupport; + u8_t wpaLen; + + /* IBSS related objects */ + u8_t ibssDelayedInd; + struct zsPartnerNotifyEvent ibssDelayedIndEvent; + u8_t ibssPartnerStatus; + + u8_t bAutoReconnect; + + u8_t flagFreqChanging; + u8_t flagKeyChanging; + struct zsBssInfo ibssBssDesc; + u8_t ibssBssIsCreator; + u16_t ibssReceiveBeaconCount; + u8_t ibssSiteSurveyStatus; + + u8_t disableProbingWithSsid; +#ifdef ZM_ENABLE_CENC + /* CENC */ + u8_t cencIe[ZM_MAX_IE_SIZE + 2]; +#endif //ZM_ENABLE_CENC + u32_t txiv[4]; //Tx PN Sequence + u32_t rxiv[4]; //Rx PN Sequence + u32_t rxivGK[4];//Broadcast Rx PN Sequence + u8_t wepKey[4][32]; // For Software WEP + u8_t SWEncryMode[4]; + + /* 802.11d */ + u8_t b802_11D; + + /* 802.11h */ + u8_t TPCEnable; + u8_t DFSEnable; + u8_t DFSDisableTx; + + /* Owl AP */ + u8_t athOwlAp; + + /* Enable BA response in driver */ + u8_t enableDrvBA; + + /* HT Capability Info */ + union zuHTCapability HTCap; //CWYang(+) + + /* Extended HT Capability Info */ + union zuExtHTCapability ExtHTCap; //CWYang(+) + + struct InformationElementSta ie; + +#define ZM_CACHED_FRAMEBODY_SIZE 200 + u8_t asocReqFrameBody[ZM_CACHED_FRAMEBODY_SIZE]; + u16_t asocReqFrameBodySize; + u8_t asocRspFrameBody[ZM_CACHED_FRAMEBODY_SIZE]; + u16_t asocRspFrameBodySize; + u8_t beaconFrameBody[ZM_CACHED_FRAMEBODY_SIZE]; + u16_t beaconFrameBodySize; + + u8_t ac0PriorityHigherThanAc2; + u8_t SWEncryptEnable; + + u8_t leapEnabled; + + u32_t TotalNumberOfReceivePackets; + u32_t TotalNumberOfReceiveBytes; + u32_t avgSizeOfReceivePackets; + + u32_t ReceivedPacketRateCounter; + u32_t ReceivedPktRatePerSecond; + + /* #2 Record the sequence number to determine whether the unicast frame is separated by RIFS or not */ +#define ZM_RIFS_STATE_DETECTING 0 +#define ZM_RIFS_STATE_DETECTED 1 +#define ZM_RIFS_TIMER_TIMEOUT 4480 // 4480ms 7s + u8_t rifsState; + u8_t rifsLikeFrameCnt; + u16_t rifsLikeFrameSequence[3]; + u32_t rifsTimer; + u32_t rifsCount; + + /* RX filter desired by upper layers. Note this contains some bits which must be filtered + by sw since the hw supports only a subset of possible filter actions.= */ + u32_t osRxFilter; + + u8_t bSafeMode; + + u32_t ibssAdditionalIESize; + u8_t ibssAdditionalIE[256]; +}; //struct zsWlanDevSta + +#define ZM_CMD_QUEUE_SIZE 256 //Roger Check, test 64 when ready + +#define ZM_OID_READ 1 +#define ZM_OID_WRITE 2 +#define ZM_OID_INTERNAL_WRITE 3 +#define ZM_CMD_SET_FREQUENCY 4 +#define ZM_CMD_SET_KEY 5 +#define ZM_CWM_READ 6 +#define ZM_MAC_READ 7 +#define ZM_ANI_READ 8 +#define ZM_EEPROM_READ 9 +#define ZM_EEPROM_WRITE 0x0A +#define ZM_OID_CHAN 0x30 +#define ZM_OID_SYNTH 0x32 +#define ZM_OID_TALLY 0x81 +#define ZM_OID_TALLY_APD 0x82 + +#define ZM_OID_DKTX_STATUS 0x92 +#define ZM_OID_FLASH_CHKSUM 0xD0 +#define ZM_OID_FLASH_READ 0xD1 +#define ZM_OID_FLASH_PROGRAM 0xD2 +#define ZM_OID_FW_DL_INIT 0xD3 + +/* Driver to Firmware OID */ +#define ZM_CMD_ECHO 0x80 +#define ZM_CMD_TALLY 0x81 +#define ZM_CMD_TALLY_APD 0x82 +#define ZM_CMD_CONFIG 0x83 +#define ZM_CMD_RREG 0x00 +#define ZM_CMD_WREG 0x01 +#define ZM_CMD_RMEM 0x02 +#define ZM_CMD_WMEM 0x03 +#define ZM_CMD_BITAND 0x04 +#define ZM_CMD_BITOR 0x05 +#define ZM_CMD_EKEY 0x28 +#define ZM_CMD_DKEY 0x29 +#define ZM_CMD_FREQUENCY 0x30 +#define ZM_CMD_RF_INIT 0x31 +#define ZM_CMD_SYNTH 0x32 +#define ZM_CMD_FREQ_STRAT 0x33 +#define ZM_CMD_RESET 0x90 +#define ZM_CMD_DKRESET 0x91 +#define ZM_CMD_DKTX_STATUS 0x92 +#define ZM_CMD_FDC 0xA0 +#define ZM_CMD_WREEPROM 0xB0 +#define ZM_CMD_WFLASH 0xB0 +#define ZM_CMD_FLASH_ERASE 0xB1 +#define ZM_CMD_FLASH_PROG 0xB2 +#define ZM_CMD_FLASH_CHKSUM 0xB3 +#define ZM_CMD_FLASH_READ 0xB4 +#define ZM_CMD_FW_DL_INIT 0xB5 +#define ZM_CMD_MEM_WREEPROM 0xBB + + +/* duplicate filter table column */ +#define ZM_FILTER_TABLE_COL 2 /* 2^n */ +/* duplicate filter table Row */ +#define ZM_FILTER_TABLE_ROW 8 /* 2^n */ + +/* duplicate filter table structure */ +struct zsRxFilter +{ + u16_t addr[3]; + u16_t seq; + u8_t up; +}; + +struct zsWlanDev +{ + /* AP global variables */ + struct zsWlanDevAp ap; + /* STA global variables */ + struct zsWlanDevSta sta; + /* save wrapper setting */ + struct zsWrapperSetting ws; + /* features determined by wrapper (vendor) */ + struct zsWrapperFeatureCtrl wfc; + /* Traffic Monitor tally */ + struct zsTrafTally trafTally; + /* Communication tally */ + struct zsCommTally commTally; + /* Duplicate frame filter table */ + struct zsRxFilter rxFilterTbl[ZM_FILTER_TABLE_COL][ZM_FILTER_TABLE_ROW]; + /* Regulatory table */ + struct zsRegulationTable regulationTable; + + /* */ + struct zsWlanDevFreqControl freqCtrl; + + enum devState state; + + u8_t halState; + u8_t wlanMode; /* AP/INFRASTRUCTURE/IBSS/PSEUDO */ + u16_t macAddr[3]; /* MAC address */ + u16_t beaconInterval; /* beacon Interval */ + u8_t dtim; /* DTIM period */ + u8_t CurrentDtimCount; + u8_t preambleType; + u8_t preambleTypeInUsed; + u8_t maxTxPower2; /* 2.4 GHz Max Tx power (Unit: 0.5 dBm) */ + u8_t maxTxPower5; /* 5 GHz Max Tx power (Unit: 0.5 dBm) */ + u8_t connectMode; + u32_t supportMode; + + u8_t bRate; /* 11b Support Rate bit map */ + u8_t bRateBasic; /* 11b Basic Rate bit map */ + u8_t gRate; /* 11g Support Rate bit map */ + u8_t gRateBasic; /* 11g Basic Rate bit map */ + /* channel index point to the item in regulation table */ + u8_t channelIndex; + + /* channel management */ + u8_t BandWidth40; + u8_t ExtOffset; //1 above, 3 below, 0 not present + u16_t frequency; /* operation frequency */ + + u8_t erpElement; /* ERP information element data */ + + u8_t disableSelfCts; /* set to 1 to disable Self-CTS */ + u8_t bgMode; + + /* private test flag */ + u32_t enableProtectionMode; /* force enable/disable self cts */ + u32_t checksumTest; /* OTUS checksum test 1=>zero checksum 0=>normal */ + u32_t rxPacketDump; /* rx packet dump */ + + u8_t enableAggregation; /* force enable/disable A-MSPU */ + u8_t enableWDS; /* force enable/disable WDS testing */ + u8_t enableTxPathMode; /* OTUS special testing mode 1=>diable, 0=>enable: ZM_SYSTEM_TEST_MODE */ + u8_t enableHALDbgInfo; /* */ + + u32_t forceTxTPC; /* force tx packet send TPC */ + + u16_t seq[4]; + u16_t mmseq; + + /* driver core time tick */ + u32_t tick; + u16_t tickIbssSendBeacon; + u16_t tickIbssReceiveBeacon; + + /* RTS threshold */ + u16_t rtsThreshold; + + /* fragmentation threshold, 256 <= value <= 2346, 0=disabled */ + u16_t fragThreshold; + + /* Tx Rate */ + u16_t txMCS; + u16_t txMT; + u32_t CurrentTxRateKbps; //CWYang(+) + /* Rx Rate */ + u32_t CurrentRxRateKbps; //Janet(+) + u8_t CurrentRxRateUpdated; + u8_t modulationType; + u8_t rxInfo; + u16_t rateField; + + /* timer related objects */ + struct zsTimerList timerList; + u8_t bTimerReady; + + /* for defragmentation */ + struct zsDefragList defragTable; + + /* Data struct for Interface Dependent Layer */ + //struct zsIdlStruct idlStruct; + + /* Signal Strength/Quality Related Parameters */ + u8_t SignalStrength; //CWYang(+) + u8_t SignalQuality; //CWYang(+) + + + + /* QoS */ + zbuf_t* vtxq[4][ZM_VTXQ_SIZE]; + u16_t vtxqHead[4]; + u16_t vtxqTail[4]; + u16_t qosDropIpFrag[4]; + + /* Management Tx queue */ + zbuf_t* vmmq[ZM_VMMQ_SIZE]; + u16_t vmmqHead; + u16_t vmmqTail; + + u8_t vtxqPushing; + + /* + * add by honda + * 1. Aggregate queues + * 2. STA's associated information and queue number + * 3. rx aggregation re-ordering queue + */ + struct aggQueue *aggQPool[ZM_AGG_POOL_SIZE]; + u8_t aggInitiated; + u8_t addbaComplete; + u8_t addbaCount; + u8_t aggState; + u8_t destLock; + struct aggSta aggSta[ZM_MAX_STA_SUPPORT]; + struct agg_tid_rx *tid_rx[ZM_AGG_POOL_SIZE]; + struct aggTally agg_tal; + struct destQ destQ; + struct baw_enabler *baw_enabler; + struct ieee80211_cwm cwm; + u16_t reorder; + u16_t seq_debug; + /* rate control */ + u32_t txMPDU[ZM_RATE_TABLE_SIZE]; + u32_t txFail[ZM_RATE_TABLE_SIZE]; + u32_t PER[ZM_RATE_TABLE_SIZE]; + u16_t probeCount; + u16_t probeSuccessCount; + u16_t probeInterval; + u16_t success_probing; + /* + * end of add by honda + */ + + /* airopeek sniffer mode for upper sw */ + u32_t swSniffer; /* window: airoPeek */ + u32_t XLinkMode; + + /* MDK mode */ + /* init by 0=>normal driver 1=>MDK driver */ + u32_t modeMDKEnable; + + u32_t heartBeatNotification; + + /* pointer for HAL Plus private memory */ + void* hpPrivate; + + /* for WPA setting */ + //u8_t wpaSupport[ZM_MAX_AP_SUPPORT]; + //u8_t wpaLen[ZM_MAX_AP_SUPPORT]; + //u8_t wpaIe[ZM_MAX_AP_SUPPORT][ZM_MAX_IE_SIZE]; + + struct zsLedStruct ledStruct; + + /* ani flag */ + u8_t aniEnable; + u16_t txq_threshold; + + //Skip Mic Error Check + u8_t TKIP_Group_KeyChanging; + + u8_t dynamicSIFSEnable; + + u8_t queueFlushed; + + u16_t (*zfcbAuthNotify)(zdev_t* dev, u16_t* macAddr); + u16_t (*zfcbAsocNotify)(zdev_t* dev, u16_t* macAddr, u8_t* body, u16_t bodySize, u16_t port); + u16_t (*zfcbDisAsocNotify)(zdev_t* dev, u8_t* macAddr, u16_t port); + u16_t (*zfcbApConnectNotify)(zdev_t* dev, u8_t* macAddr, u16_t port); + void (*zfcbConnectNotify)(zdev_t* dev, u16_t status, u16_t* bssid); + void (*zfcbScanNotify)(zdev_t* dev, struct zsScanResult* result); + void (*zfcbMicFailureNotify)(zdev_t* dev, u16_t* addr, u16_t status); + void (*zfcbApMicFailureNotify)(zdev_t* dev, u8_t* addr, zbuf_t* buf); + void (*zfcbIbssPartnerNotify)(zdev_t* dev, u16_t status, struct zsPartnerNotifyEvent *event); + void (*zfcbMacAddressNotify)(zdev_t* dev, u8_t* addr); + void (*zfcbSendCompleteIndication)(zdev_t* dev, zbuf_t* buf); + void (*zfcbRecvEth)(zdev_t* dev, zbuf_t* buf, u16_t port); + void (*zfcbRecv80211)(zdev_t* dev, zbuf_t* buf, struct zsAdditionInfo* addInfo); + void (*zfcbRestoreBufData)(zdev_t* dev, zbuf_t* buf); +#ifdef ZM_ENABLE_CENC + u16_t (*zfcbCencAsocNotify)(zdev_t* dev, u16_t* macAddr, u8_t* body, + u16_t bodySize, u16_t port); +#endif //ZM_ENABLE_CENC + u8_t (*zfcbClassifyTxPacket)(zdev_t* dev, zbuf_t* buf); + void (*zfcbHwWatchDogNotify)(zdev_t* dev); +}; + + +struct zsWlanKey +{ + u8_t key; +}; + + +/* These macros are defined here for backward compatibility */ +/* Please leave them alone */ +/* For Tx packet allocated in upper layer layer */ +#define zmw_tx_buf_readb(dev, buf, offset) zmw_buf_readb(dev, buf, offset) +#define zmw_tx_buf_readh(dev, buf, offset) zmw_buf_readh(dev, buf, offset) +#define zmw_tx_buf_writeb(dev, buf, offset, value) zmw_buf_writeb(dev, buf, offset, value) +#define zmw_tx_buf_writeh(dev, buf, offset, value) zmw_buf_writeh(dev, buf, offset, value) + +/* For Rx packet allocated in driver */ +#define zmw_rx_buf_readb(dev, buf, offset) zmw_buf_readb(dev, buf, offset) +#define zmw_rx_buf_readh(dev, buf, offset) zmw_buf_readh(dev, buf, offset) +#define zmw_rx_buf_writeb(dev, buf, offset, value) zmw_buf_writeb(dev, buf, offset, value) +#define zmw_rx_buf_writeh(dev, buf, offset, value) zmw_buf_writeh(dev, buf, offset, value) + +#endif /* #ifndef _STRUCT_H */ --- linux-2.6.28.orig/drivers/staging/otus/80211core/performance.c +++ linux-2.6.28/drivers/staging/otus/80211core/performance.c @@ -0,0 +1,431 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* */ +/* Module Name : performance.c */ +/* */ +/* Abstract */ +/* This module performance evaluation functions. */ +/* */ +/* NOTES */ +/* None */ +/* */ +/************************************************************************/ +#include "cprecomp.h" +#ifdef ZM_ENABLE_PERFORMANCE_EVALUATION + +#define ZM_TP_SIZE 50 +struct zsSummary zm_summary; +struct zsVariation zm_var; +struct zsThroughput zm_tp; + +void zfiPerformanceInit(zdev_t* dev) +{ + u16_t i; + + zmw_get_wlan_dev(dev); + + zm_summary.tick_base = wd->tick; + zm_summary.tx_msdu_count = 0; + zm_summary.tx_mpdu_count = 0; + zm_summary.rx_msdu_count = 0; + zm_summary.rx_mpdu_count = 0; + zm_summary.rx_broken_seq = 0; + zm_summary.rx_broken_sum = 0; + zm_summary.rx_seq_base = 0; + zm_summary.rx_broken_seq_dis = 0; + zm_summary.rx_duplicate_seq = 0; + zm_summary.rx_old_seq = 0; + zm_summary.reset_count = 0; + zm_summary.reset_sum = 0; + zm_summary.rx_lost_sum = 0; + zm_summary.rx_duplicate_error = 0; + zm_summary.rx_free = 0; + zm_summary.rx_amsdu_len = 0; + zm_summary.rx_flush = 0; + zm_summary.rx_clear = 0; + zm_summary.rx_reorder = 0; + + for (i=0; i<100; i++) + { + zm_var.tx_msdu_tick[i] = zm_var.tx_mpdu_tick[i] = 0; + zm_var.rx_msdu_tick[i] = zm_var.rx_mpdu_tick[i] = 0; + } + + zfTimerSchedule(dev, ZM_EVENT_TIMEOUT_PERFORMANCE, 100); + + zm_tp.size = ZM_TP_SIZE; + zm_tp.head = zm_tp.size - 1; + zm_tp.tail = 0; + for (i=0; i0; i--) + { + s[0] = (i/10) + '0'; + s[1] = (i%10) + '0'; + s[2] = '0'; + s[3] = '|'; + for (j=0; jtick; + zm_summary.rx_broken_sum += zm_summary.rx_broken_seq; + zm_summary.rx_lost_sum += (zm_summary.rx_broken_seq - zm_summary.rx_duplicate_seq - zm_summary.rx_old_seq); + + zfiPerformanceGraph(dev); + + DbgPrint("******************************************************\n"); + DbgPrint("* TX: MSDU=%5d, VAR=%5d; MPDU=%5d, VAR=%5d\n", zm_summary.tx_msdu_count, + zm_var.tx_msdu_var, zm_summary.tx_mpdu_count, zm_var.tx_mpdu_var); + DbgPrint("* TX: idle=%5d,TxRate=%3d, PER=%5d\n", zm_summary.tx_idle_count, + wd->CurrentTxRateKbps/1000, + (u16_t)wd->PER[wd->sta.oppositeInfo[0].rcCell.currentRate]); + DbgPrint("* RX: MSDU=%5d, VAR=%5d; MPDU=%5d, VAR=%5d\n", zm_summary.rx_msdu_count, + zm_var.rx_msdu_var, zm_summary.rx_mpdu_count, zm_var.rx_mpdu_var); + DbgPrint("* RX: idle=%5d,RxRate=%3d,AMSDU=%5d\n", zm_summary.rx_idle_count, + wd->CurrentRxRateKbps/1000, zm_summary.rx_amsdu_len); + DbgPrint("* RX broken seq=%4d, distances=%4d, duplicates=%4d\n", zm_summary.rx_broken_seq, + zm_summary.rx_broken_seq_dis, zm_summary.rx_duplicate_seq); + DbgPrint("* RX old seq=%4d, lost=%4d, broken sum=%4d\n", zm_summary.rx_old_seq, + (zm_summary.rx_broken_seq - zm_summary.rx_duplicate_seq - zm_summary.rx_old_seq), + zm_summary.rx_broken_sum); + DbgPrint("* Rx lost sum=%4d,dup. error=%4d, free count=%4d\n", zm_summary.rx_lost_sum, + zm_summary.rx_duplicate_error, zm_summary.rx_free); + DbgPrint("* Rx flush sum=%4d, clear sum=%4d, reorder=%7d\n", zm_summary.rx_flush, + zm_summary.rx_clear, zm_summary.rx_reorder); + DbgPrint("* Firmware reset=%3d, reset sum=%4d\n", zm_summary.reset_count, + zm_summary.reset_sum); + DbgPrint("******************************************************\n\n"); + //reset count 11772c + zm_summary.tx_msdu_count = 0; + zm_summary.tx_mpdu_count = 0; + zm_summary.rx_msdu_count = 0; + zm_summary.rx_mpdu_count = 0; + zm_summary.rx_broken_seq = 0; + zm_summary.rx_broken_seq_dis = 0; + zm_summary.rx_duplicate_seq = 0; + zm_summary.rx_old_seq = 0; + zm_summary.reset_count = 0; + zm_summary.rx_amsdu_len = 0; + + for (i=0; i<100; i++) + { + zm_var.tx_msdu_tick[i] = zm_var.tx_mpdu_tick[i] = 0; + zm_var.rx_msdu_tick[i] = zm_var.rx_mpdu_tick[i] = 0; + } + + zfTimerSchedule(dev, ZM_EVENT_TIMEOUT_PERFORMANCE, 100); +} + +void zfiTxPerformanceMSDU(zdev_t* dev, u32_t tick) +{ + u32_t index; + zm_summary.tx_msdu_count++; + + index = tick - zm_summary.tick_base; + + if (index < 100) + { + zm_var.tx_msdu_tick[index]++; + } + else + { + //DbgPrint("wd->tick exceeded tick_base+100!\n"); + } +} + +void zfiRxPerformanceMSDU(zdev_t* dev, u32_t tick) +{ + u32_t index; + zm_summary.rx_msdu_count++; + + index = tick - zm_summary.tick_base; + + if (index < 100) + { + zm_var.rx_msdu_tick[index]++; + } + else + { + //DbgPrint("wd->tick exceeded tick_base+100!\n"); + } +} + +void zfiTxPerformanceMPDU(zdev_t* dev, u32_t tick) +{ + u32_t index; + zm_summary.tx_mpdu_count++; + + index = tick - zm_summary.tick_base; + + if (index < 100) + { + zm_var.tx_mpdu_tick[index]++; + } + else + { + //DbgPrint("wd->tick exceeded tick_base+100!\n"); + } +} + +#ifndef ZM_INT_USE_EP2_HEADER_SIZE +#define ZM_INT_USE_EP2_HEADER_SIZE 12 +#endif +void zfiRxPerformanceMPDU(zdev_t* dev, zbuf_t* buf) +{ + u32_t index; + u16_t frameType; + u16_t frameCtrl; + u8_t mpduInd; + u16_t plcpHdrLen; + u16_t len; + + zmw_get_wlan_dev(dev); + + len = zfwBufGetSize(dev, buf); + mpduInd = zmw_rx_buf_readb(dev, buf, len-1); + /* First MPDU or Single MPDU */ + if(((mpduInd & 0x30) == 0x00) || ((mpduInd & 0x30) == 0x20)) + //if ((mpduInd & 0x10) == 0x00) + { + plcpHdrLen = 12; // PLCP header length + } + else + { + if (zmw_rx_buf_readh(dev, buf, 4) == wd->macAddr[0] && + zmw_rx_buf_readh(dev, buf, 6) == wd->macAddr[1] && + zmw_rx_buf_readh(dev, buf, 8) == wd->macAddr[2]) { + plcpHdrLen = 0; + } + else if (zmw_rx_buf_readh(dev, buf, 16) == wd->macAddr[0] && + zmw_rx_buf_readh(dev, buf, 18) == wd->macAddr[1] && + zmw_rx_buf_readh(dev, buf, 20) == wd->macAddr[2]){ + plcpHdrLen = 12; + } + else { + plcpHdrLen = 0; + } + } + + frameCtrl = zmw_rx_buf_readb(dev, buf, plcpHdrLen + 0); + frameType = frameCtrl & 0xf; + + if (frameType != ZM_WLAN_DATA_FRAME) + { + return; + } + + zm_summary.rx_mpdu_count++; + + index = wd->tick - zm_summary.tick_base; + + if (index < 100) + { + zm_var.rx_mpdu_tick[index]++; + } + else + { + //DbgPrint("wd->tick exceeded tick_base+100!\n"); + } +} + +void zfiRxPerformanceSeq(zdev_t* dev, zbuf_t* buf) +{ + u16_t seq_no; + u16_t offset = 0; + u16_t old_dis = zm_summary.rx_broken_seq_dis; + //sys_time = KeQueryPerformanceCounter(&freq); + + seq_no = zmw_rx_buf_readh(dev, buf, offset+22) >> 4; + + ZM_SEQ_DEBUG("Out %5d\n", seq_no); + + if (seq_no < zm_summary.rx_seq_base) + { + if (seq_no == 0) + { + if (zm_summary.rx_seq_base != 4095) + { + zm_summary.rx_broken_seq++; + ZM_SEQ_DEBUG("Broken seq"); + zm_summary.rx_broken_seq_dis+=(4096 - zm_summary.rx_seq_base); + } + } + else if ((seq_no < 300) && (zm_summary.rx_seq_base > 3800)) + { + zm_summary.rx_broken_seq++; + ZM_SEQ_DEBUG("Broken seq"); + zm_summary.rx_broken_seq_dis+=(4096 - zm_summary.rx_seq_base + seq_no); + } + else + { + zm_summary.rx_broken_seq++; + ZM_SEQ_DEBUG("Broken seq"); + zm_summary.rx_broken_seq_dis+=(zm_summary.rx_seq_base - seq_no); + zm_summary.rx_old_seq++; + } + } + else + { + if (seq_no != (zm_summary.rx_seq_base + 1)) + { + if ((seq_no > 3800) && (zm_summary.rx_seq_base < 300)) + { + zm_summary.rx_broken_seq++; + ZM_SEQ_DEBUG("Broken seq"); + zm_summary.rx_broken_seq_dis+=(4096 - seq_no + zm_summary.rx_seq_base); + zm_summary.rx_old_seq++; + } + else + { + zm_summary.rx_broken_seq++; + ZM_SEQ_DEBUG("Broken seq"); + zm_summary.rx_broken_seq_dis+=(seq_no - zm_summary.rx_seq_base); + } + } + } + if (seq_no == zm_summary.rx_seq_base) + { + zm_summary.rx_duplicate_seq++; + } + + if ((zm_summary.rx_broken_seq_dis - old_dis) > 100) + { + DbgPrint("* seq_no=%4d, base_seq=%4d, dis_diff=%4d", seq_no, + zm_summary.rx_seq_base, zm_summary.rx_broken_seq_dis - old_dis); + } + zm_summary.rx_seq_base = seq_no; +} + +void zfiRxPerformanceReg(zdev_t* dev, u32_t reg, u32_t rsp) +{ + zm_summary.reset_count = (u16_t)rsp - zm_summary.reset_sum; + zm_summary.reset_sum = (u16_t)rsp; +} + +void zfiRxPerformanceDup(zdev_t* dev, zbuf_t* buf1, zbuf_t* buf2) +{ + u16_t seq_no1, seq_no2; + + seq_no1 = zmw_rx_buf_readh(dev, buf1, 22) >> 4; + seq_no2 = zmw_rx_buf_readh(dev, buf2, 22) >> 4; + if (seq_no1 != seq_no2) + { + zm_summary.rx_duplicate_error++; + } +} + +void zfiRxPerformanceFree(zdev_t* dev, zbuf_t* buf) +{ + zm_summary.rx_free++; +} + +void zfiRxPerformanceAMSDU(zdev_t* dev, zbuf_t* buf, u16_t len) +{ + if (zm_summary.rx_amsdu_len < len) + { + zm_summary.rx_amsdu_len = len; + } +} +void zfiRxPerformanceFlush(zdev_t* dev) +{ + zm_summary.rx_flush++; +} + +void zfiRxPerformanceClear(zdev_t* dev) +{ + zm_summary.rx_clear++; + ZM_SEQ_DEBUG("RxClear"); +} + +void zfiRxPerformanceReorder(zdev_t* dev) +{ + zm_summary.rx_reorder++; +} +#endif /* end of ZM_ENABLE_PERFORMANCE_EVALUATION */ --- linux-2.6.28.orig/drivers/staging/otus/80211core/queue.c +++ linux-2.6.28/drivers/staging/otus/80211core/queue.c @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* */ +/* Module Name : queue.c */ +/* */ +/* Abstract */ +/* This module contains queue management functions. */ +/* */ +/* NOTES */ +/* None */ +/* */ +/************************************************************************/ +#include "cprecomp.h" +#include "queue.h" + + +struct zsQueue* zfQueueCreate(zdev_t* dev, u16_t size) +{ + struct zsQueue* q; + + if ((q = (struct zsQueue*)zfwMemAllocate(dev, sizeof(struct zsQueue) + + (sizeof(struct zsQueueCell)*(size-1)))) != NULL) + { + q->size = size; + q->sizeMask = size-1; + q->head = 0; + q->tail = 0; + } + return q; +} + +void zfQueueDestroy(zdev_t* dev, struct zsQueue* q) +{ + u16_t size = sizeof(struct zsQueue) + (sizeof(struct zsQueueCell)*(q->size-1)); + + zfQueueFlush(dev, q); + zfwMemFree(dev, q, size); + + return; +} + +u16_t zfQueuePutNcs(zdev_t* dev, struct zsQueue* q, zbuf_t* buf, u32_t tick) +{ + u16_t ret = ZM_ERR_QUEUE_FULL; + + zm_msg0_mm(ZM_LV_1, "zfQueuePutNcs()"); + + if (((q->tail+1)&q->sizeMask) != q->head) + { + q->cell[q->tail].buf = buf; + q->cell[q->tail].tick = tick; + q->tail = (q->tail+1) & q->sizeMask; + ret = ZM_SUCCESS; + } + + return ret; +} + +u16_t zfQueuePut(zdev_t* dev, struct zsQueue* q, zbuf_t* buf, u32_t tick) +{ + u16_t ret; + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + ret = zfQueuePutNcs(dev, q, buf, tick); + + zmw_leave_critical_section(dev); + + return ret; +} + +zbuf_t* zfQueueGet(zdev_t* dev, struct zsQueue* q) +{ + zbuf_t* buf = NULL; + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + if (q->head != q->tail) + { + buf = q->cell[q->head].buf; + q->head = (q->head+1) & q->sizeMask; + } + + zmw_leave_critical_section(dev); + + return buf; +} + +u16_t zfCompareDstwithBuf(zdev_t* dev, zbuf_t* buf, u8_t* addr) +{ + u16_t i; + u8_t dst[6]; + + for (i=0; i<6; i++) + { + dst[i] = zmw_buf_readb(dev, buf, i); + if (dst[i] != addr[i]) + { + return 1+i; + } + } + + return 0; +} + + +zbuf_t* zfQueueGetWithMac(zdev_t* dev, struct zsQueue* q, u8_t* addr, u8_t* mb) +{ + zbuf_t* buf; + zbuf_t* retBuf = NULL; + u16_t index, next; + zmw_declare_for_critical_section(); + + *mb = 0; + + zmw_enter_critical_section(dev); + + index = q->head; + + while (1) + { + if (index != q->tail) + { + buf = q->cell[index].buf; + + //if buf's detination address == input addr + if (zfCompareDstwithBuf(dev, buf, addr) == 0) + { + retBuf = buf; + //Get it, and trace the whole queue to calculate more bit + while ((next =((index+1)&q->sizeMask)) != q->tail) + { + q->cell[index].buf = q->cell[next].buf; + q->cell[index].tick = q->cell[next].tick; + + if ((*mb == 0) && (zfCompareDstwithBuf(dev, + q->cell[next].buf, addr) == 0)) + { + *mb = 1; + } + + index = next; + } + q->tail = (q->tail-1) & q->sizeMask; + + zmw_leave_critical_section(dev); + return retBuf; + } + index = (index + 1) & q->sizeMask; + } //if (index != q->tail) + else + { + break; + } + } + + zmw_leave_critical_section(dev); + + return retBuf; + +} + +void zfQueueFlush(zdev_t* dev, struct zsQueue* q) +{ + zbuf_t* buf; + + while ((buf = zfQueueGet(dev, q)) != NULL) + { + zfwBufFree(dev, buf, 0); + } + + return; +} + +void zfQueueAge(zdev_t* dev, struct zsQueue* q, u32_t tick, u32_t msAge) +{ + zbuf_t* buf; + u32_t buftick; + zmw_declare_for_critical_section(); + + while (1) + { + buf = NULL; + zmw_enter_critical_section(dev); + + if (q->head != q->tail) + { + buftick = q->cell[q->head].tick; + if (((tick - buftick)*ZM_MS_PER_TICK) > msAge) + { + buf = q->cell[q->head].buf; + q->head = (q->head+1) & q->sizeMask; + } + } + + zmw_leave_critical_section(dev); + + if (buf != NULL) + { + zm_msg0_mm(ZM_LV_0, "Age frame in queue!"); + zfwBufFree(dev, buf, 0); + } + else + { + break; + } + } + return; +} + + +u8_t zfQueueRemovewithIndex(zdev_t* dev, struct zsQueue* q, u16_t index, u8_t* addr) +{ + u16_t next; + u8_t mb = 0; + + //trace the whole queue to calculate more bit + while ((next =((index+1)&q->sizeMask)) != q->tail) + { + q->cell[index].buf = q->cell[next].buf; + q->cell[index].tick = q->cell[next].tick; + + if ((mb == 0) && (zfCompareDstwithBuf(dev, + q->cell[next].buf, addr) == 0)) + { + mb = 1; + } + + index = next; + } + q->tail = (q->tail-1) & q->sizeMask; + + return mb; + +} + +void zfQueueGenerateUapsdTim(zdev_t* dev, struct zsQueue* q, + u8_t* uniBitMap, u16_t* highestByte) +{ + zbuf_t* psBuf; + u8_t dst[6]; + u16_t id, aid, index, i; + u16_t bitPosition; + u16_t bytePosition; + zmw_get_wlan_dev(dev); + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + index = q->head; + + while (index != q->tail) + { + psBuf = q->cell[index].buf; + for (i=0; i<6; i++) + { + dst[i] = zmw_buf_readb(dev, psBuf, i); + } + /* TODO : use u8_t* fot MAC address */ + if (((id = zfApFindSta(dev, (u16_t*)dst)) != 0xffff) + && (wd->ap.staTable[id].psMode != 0)) + { + /* Calculate PVB only when all AC are delivery-enabled */ + if ((wd->ap.staTable[id].qosInfo & 0xf) == 0xf) + { + aid = id + 1; + bitPosition = (1 << (aid & 0x7)); + bytePosition = (aid >> 3); + uniBitMap[bytePosition] |= bitPosition; + + if (bytePosition>*highestByte) + { + *highestByte = bytePosition; + } + } + index = (index+1) & q->sizeMask; + } + else + { + /* Free garbage UAPSD frame */ + zfQueueRemovewithIndex(dev, q, index, dst); + zfwBufFree(dev, psBuf, 0); + } + } + zmw_leave_critical_section(dev); + + return; +} --- linux-2.6.28.orig/drivers/staging/otus/hal/hpreg.c +++ linux-2.6.28/drivers/staging/otus/hal/hpreg.c @@ -0,0 +1,2481 @@ +/* + * Copyright (c) 2000-2005 ZyDAS Technology Corporation + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* */ +/* Module Name : hpreg.c */ +/* */ +/* Abstract */ +/* This module contains Regulatory Table and related function. */ +/* */ +/* NOTES */ +/* None */ +/* */ +/************************************************************************/ +#include "../80211core/cprecomp.h" +#include "hpani.h" +#include "hpreg.h" +#include "hpusb.h" + +/* used throughout this file... */ +#define N(a) (sizeof (a) / sizeof (a[0])) + +#define HAL_MODE_11A_TURBO HAL_MODE_108A +#define HAL_MODE_11G_TURBO HAL_MODE_108G + +#if 0 +enum { + /* test groups */ + FCC = 0x10, + MKK = 0x40, + ETSI = 0x30, + SD_NO_CTL = 0xe0, + NO_CTL = 0xff, + /* test modes */ + CTL_MODE_M = 0x0f, + CTL_11A = 0, + CTL_11B = 1, + CTL_11G = 2, + CTL_TURBO = 3, + CTL_108G = 4, + CTL_2GHT20 = 5, + CTL_5GHT20 = 6, + CTL_2GHT40 = 7, + CTL_5GHT40 = 8 +}; +#endif + +/* + * The following are flags for different requirements per reg domain. + * These requirements are either inhereted from the reg domain pair or + * from the unitary reg domain if the reg domain pair flags value is + * 0 + */ + +enum { + NO_REQ = 0x00000000, + DISALLOW_ADHOC_11A = 0x00000001, + DISALLOW_ADHOC_11A_TURB = 0x00000002, + NEED_NFC = 0x00000004, + + ADHOC_PER_11D = 0x00000008, /* Start Ad-Hoc mode */ + ADHOC_NO_11A = 0x00000010, + + PUBLIC_SAFETY_DOMAIN = 0x00000020, /* public safety domain */ + LIMIT_FRAME_4MS = 0x00000040, /* 4msec limit on the frame length */ +}; + +#define MKK5GHZ_FLAG1 (DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS) +#define MKK5GHZ_FLAG2 (DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS) + +typedef enum { + DFS_UNINIT_DOMAIN = 0, /* Uninitialized dfs domain */ + DFS_FCC_DOMAIN = 1, /* FCC3 dfs domain */ + DFS_ETSI_DOMAIN = 2, /* ETSI dfs domain */ +} HAL_DFS_DOMAIN; + +/* + * Used to set the RegDomain bitmask which chooses which frequency + * band specs are used. + */ + +#define BMLEN 2 /* Use 2 64 bit uint for channel bitmask + NB: Must agree with macro below (BM) */ +#define BMZERO {(u64_t) 0, (u64_t) 0} /* BMLEN zeros */ + +#if 0 + +#define BM(_fa, _fb, _fc, _fd, _fe, _ff, _fg, _fh, _fi, _fj, _fk, _fl) \ + {((((_fa >= 0) && (_fa < 64)) ? (((u64_t) 1) << _fa) : (u64_t) 0) | \ + (((_fb >= 0) && (_fb < 64)) ? (((u64_t) 1) << _fb) : (u64_t) 0) | \ + (((_fc >= 0) && (_fc < 64)) ? (((u64_t) 1) << _fc) : (u64_t) 0) | \ + (((_fd >= 0) && (_fd < 64)) ? (((u64_t) 1) << _fd) : (u64_t) 0) | \ + (((_fe >= 0) && (_fe < 64)) ? (((u64_t) 1) << _fe) : (u64_t) 0) | \ + (((_ff >= 0) && (_ff < 64)) ? (((u64_t) 1) << _ff) : (u64_t) 0) | \ + (((_fg >= 0) && (_fg < 64)) ? (((u64_t) 1) << _fg) : (u64_t) 0) | \ + (((_fh >= 0) && (_fh < 64)) ? (((u64_t) 1) << _fh) : (u64_t) 0) | \ + (((_fi >= 0) && (_fi < 64)) ? (((u64_t) 1) << _fi) : (u64_t) 0) | \ + (((_fj >= 0) && (_fj < 64)) ? (((u64_t) 1) << _fj) : (u64_t) 0) | \ + (((_fk >= 0) && (_fk < 64)) ? (((u64_t) 1) << _fk) : (u64_t) 0) | \ + (((_fl >= 0) && (_fl < 64)) ? (((u64_t) 1) << _fl) : (u64_t) 0) | \ + ((((_fa > 63) && (_fa < 128)) ? (((u64_t) 1) << (_fa - 64)) : (u64_t) 0) | \ + (((_fb > 63) && (_fb < 128)) ? (((u64_t) 1) << (_fb - 64)) : (u64_t) 0) | \ + (((_fc > 63) && (_fc < 128)) ? (((u64_t) 1) << (_fc - 64)) : (u64_t) 0) | \ + (((_fd > 63) && (_fd < 128)) ? (((u64_t) 1) << (_fd - 64)) : (u64_t) 0) | \ + (((_fe > 63) && (_fe < 128)) ? (((u64_t) 1) << (_fe - 64)) : (u64_t) 0) | \ + (((_ff > 63) && (_ff < 128)) ? (((u64_t) 1) << (_ff - 64)) : (u64_t) 0) | \ + (((_fg > 63) && (_fg < 128)) ? (((u64_t) 1) << (_fg - 64)) : (u64_t) 0) | \ + (((_fh > 63) && (_fh < 128)) ? (((u64_t) 1) << (_fh - 64)) : (u64_t) 0) | \ + (((_fi > 63) && (_fi < 128)) ? (((u64_t) 1) << (_fi - 64)) : (u64_t) 0) | \ + (((_fj > 63) && (_fj < 128)) ? (((u64_t) 1) << (_fj - 64)) : (u64_t) 0) | \ + (((_fk > 63) && (_fk < 128)) ? (((u64_t) 1) << (_fk - 64)) : (u64_t) 0) | \ + (((_fl > 63) && (_fl < 128)) ? (((u64_t) 1) << (_fl - 64)) : (u64_t) 0)))} + +#else + +#define BM(_fa, _fb, _fc, _fd, _fe, _ff, _fg, _fh, _fi, _fj, _fk, _fl) \ + {((((_fa >= 0) && (_fa < 64)) ? (((u64_t) 1) << (_fa&0x3f)) : (u64_t) 0) | \ + (((_fb >= 0) && (_fb < 64)) ? (((u64_t) 1) << (_fb&0x3f)) : (u64_t) 0) | \ + (((_fc >= 0) && (_fc < 64)) ? (((u64_t) 1) << (_fc&0x3f)) : (u64_t) 0) | \ + (((_fd >= 0) && (_fd < 64)) ? (((u64_t) 1) << (_fd&0x3f)) : (u64_t) 0) | \ + (((_fe >= 0) && (_fe < 64)) ? (((u64_t) 1) << (_fe&0x3f)) : (u64_t) 0) | \ + (((_ff >= 0) && (_ff < 64)) ? (((u64_t) 1) << (_ff&0x3f)) : (u64_t) 0) | \ + (((_fg >= 0) && (_fg < 64)) ? (((u64_t) 1) << (_fg&0x3f)) : (u64_t) 0) | \ + (((_fh >= 0) && (_fh < 64)) ? (((u64_t) 1) << (_fh&0x3f)) : (u64_t) 0) | \ + (((_fi >= 0) && (_fi < 64)) ? (((u64_t) 1) << (_fi&0x3f)) : (u64_t) 0) | \ + (((_fj >= 0) && (_fj < 64)) ? (((u64_t) 1) << (_fj&0x3f)) : (u64_t) 0) | \ + (((_fk >= 0) && (_fk < 64)) ? (((u64_t) 1) << (_fk&0x3f)) : (u64_t) 0) | \ + (((_fl >= 0) && (_fl < 64)) ? (((u64_t) 1) << (_fl&0x3f)) : (u64_t) 0) | \ + ((((_fa > 63) && (_fa < 128)) ? (((u64_t) 1) << ((_fa - 64)&0x3f)) : (u64_t) 0) | \ + (((_fb > 63) && (_fb < 128)) ? (((u64_t) 1) << ((_fb - 64)&0x3f)) : (u64_t) 0) | \ + (((_fc > 63) && (_fc < 128)) ? (((u64_t) 1) << ((_fc - 64)&0x3f)) : (u64_t) 0) | \ + (((_fd > 63) && (_fd < 128)) ? (((u64_t) 1) << ((_fd - 64)&0x3f)) : (u64_t) 0) | \ + (((_fe > 63) && (_fe < 128)) ? (((u64_t) 1) << ((_fe - 64)&0x3f)) : (u64_t) 0) | \ + (((_ff > 63) && (_ff < 128)) ? (((u64_t) 1) << ((_ff - 64)&0x3f)) : (u64_t) 0) | \ + (((_fg > 63) && (_fg < 128)) ? (((u64_t) 1) << ((_fg - 64)&0x3f)) : (u64_t) 0) | \ + (((_fh > 63) && (_fh < 128)) ? (((u64_t) 1) << ((_fh - 64)&0x3f)) : (u64_t) 0) | \ + (((_fi > 63) && (_fi < 128)) ? (((u64_t) 1) << ((_fi - 64)&0x3f)) : (u64_t) 0) | \ + (((_fj > 63) && (_fj < 128)) ? (((u64_t) 1) << ((_fj - 64)&0x3f)) : (u64_t) 0) | \ + (((_fk > 63) && (_fk < 128)) ? (((u64_t) 1) << ((_fk - 64)&0x3f)) : (u64_t) 0) | \ + (((_fl > 63) && (_fl < 128)) ? (((u64_t) 1) << ((_fl - 64)&0x3f)) : (u64_t) 0)))} + +#endif + +/* Mask to check whether a domain is a multidomain or a single + domain */ + +#define MULTI_DOMAIN_MASK 0xFF00 + + +/* + * The following describe the bit masks for different passive scan + * capability/requirements per regdomain. + */ +#define NO_PSCAN 0x0ULL +#define PSCAN_FCC 0x0000000000000001ULL +#define PSCAN_FCC_T 0x0000000000000002ULL +#define PSCAN_ETSI 0x0000000000000004ULL +#define PSCAN_MKK1 0x0000000000000008ULL +#define PSCAN_MKK2 0x0000000000000010ULL +#define PSCAN_MKKA 0x0000000000000020ULL +#define PSCAN_MKKA_G 0x0000000000000040ULL +#define PSCAN_ETSIA 0x0000000000000080ULL +#define PSCAN_ETSIB 0x0000000000000100ULL +#define PSCAN_ETSIC 0x0000000000000200ULL +#define PSCAN_WWR 0x0000000000000400ULL +#define PSCAN_MKKA1 0x0000000000000800ULL +#define PSCAN_MKKA1_G 0x0000000000001000ULL +#define PSCAN_MKKA2 0x0000000000002000ULL +#define PSCAN_MKKA2_G 0x0000000000004000ULL +#define PSCAN_MKK3 0x0000000000008000ULL +#define PSCAN_DEFER 0x7FFFFFFFFFFFFFFFULL +#define IS_ECM_CHAN 0x8000000000000000ULL + +/* + * THE following table is the mapping of regdomain pairs specified by + * an 8 bit regdomain value to the individual unitary reg domains + */ + +typedef struct reg_dmn_pair_mapping { + u16_t regDmnEnum; /* 16 bit reg domain pair */ + u16_t regDmn5GHz; /* 5GHz reg domain */ + u16_t regDmn2GHz; /* 2GHz reg domain */ + u32_t flags5GHz; /* Requirements flags (AdHoc + disallow, noise floor cal needed, + etc) */ + u32_t flags2GHz; /* Requirements flags (AdHoc + disallow, noise floor cal needed, + etc) */ + u64_t pscanMask; /* Passive Scan flags which + can override unitary domain + passive scan flags. This + value is used as a mask on + the unitary flags*/ + u16_t singleCC; /* Country code of single country if + a one-on-one mapping exists */ +} REG_DMN_PAIR_MAPPING; + +static REG_DMN_PAIR_MAPPING regDomainPairs[] = { + {NO_ENUMRD, FCC2, DEBUG_REG_DMN, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {NULL1_WORLD, NULL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {NULL1_ETSIB, NULL1, ETSIB, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {NULL1_ETSIC, NULL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + + {FCC2_FCCA, FCC2, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {FCC2_WORLD, FCC2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {FCC2_ETSIC, FCC2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {FCC3_FCCA, FCC3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {FCC3_WORLD, FCC3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {FCC4_FCCA, FCC4, FCCA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {FCC5_FCCA, FCC5, FCCA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {FCC6_FCCA, FCC6, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {FCC6_WORLD, FCC6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + + {ETSI1_WORLD, ETSI1, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {ETSI2_WORLD, ETSI2, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {ETSI3_WORLD, ETSI3, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {ETSI4_WORLD, ETSI4, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {ETSI5_WORLD, ETSI5, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {ETSI6_WORLD, ETSI6, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + + {ETSI3_ETSIA, ETSI3, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {FRANCE_RES, ETSI3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + + {FCC1_WORLD, FCC1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {FCC1_FCCA, FCC1, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {APL1_WORLD, APL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {APL2_WORLD, APL2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {APL3_WORLD, APL3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {APL4_WORLD, APL4, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {APL5_WORLD, APL5, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {APL6_WORLD, APL6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {APL8_WORLD, APL8, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {APL9_WORLD, APL9, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + + {APL3_FCCA, APL3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {APL1_ETSIC, APL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {APL2_ETSIC, APL2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {APL2_FCCA, APL2, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {APL2_APLD, APL2, APLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, + {APL7_FCCA, APL7, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + + {MKK1_MKKA, MKK1, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA, CTRY_JAPAN }, + {MKK1_MKKB, MKK1, MKKA, MKK5GHZ_FLAG2, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN1 }, + {MKK1_FCCA, MKK1, FCCA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK1, CTRY_JAPAN2 }, + {MKK1_MKKA1, MKK1, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN4 }, + {MKK1_MKKA2, MKK1, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN5 }, + {MKK1_MKKC, MKK1, MKKC, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK1, CTRY_JAPAN6 }, + + /* MKK2 */ + {MKK2_MKKA, MKK2, MKKA, MKK5GHZ_FLAG2, NEED_NFC, PSCAN_MKK2 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN3 }, + + /* MKK3 */ + {MKK3_MKKA, MKK3, MKKA, MKK5GHZ_FLAG1, NEED_NFC, NO_PSCAN, CTRY_JAPAN25 }, + {MKK3_MKKB, MKK3, MKKA, MKK5GHZ_FLAG2, NEED_NFC, PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN7 }, + {MKK3_MKKA1, MKK3, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN26 }, + {MKK3_MKKA2, MKK3, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN8 }, + {MKK3_MKKC, MKK3, MKKC, MKK5GHZ_FLAG1, NEED_NFC, NO_PSCAN, CTRY_JAPAN9 }, + {MKK3_FCCA, MKK3, FCCA, MKK5GHZ_FLAG1, NEED_NFC, NO_PSCAN, CTRY_JAPAN27 }, + + /* MKK4 */ + {MKK4_MKKB, MKK4, MKKA, MKK5GHZ_FLAG2, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN10 }, + {MKK4_MKKA1, MKK4, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN28 }, + {MKK4_MKKA2, MKK4, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK3 |PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN11 }, + {MKK4_MKKC, MKK4, MKKC, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN12 }, + {MKK4_FCCA, MKK4, FCCA, MKK5GHZ_FLAG1, NEED_NFC, NO_PSCAN, CTRY_JAPAN29 }, + {MKK4_MKKA, MKK4, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA, CTRY_JAPAN36 }, + + /* MKK5 */ + {MKK5_MKKB, MKK5, MKKA, MKK5GHZ_FLAG2, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN13 }, + {MKK5_MKKA2, MKK5, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN14 }, + {MKK5_MKKC, MKK5, MKKC, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN15 }, + + /* MKK6 */ + {MKK6_MKKB, MKK6, MKKA, MKK5GHZ_FLAG2, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN16 }, + {MKK6_MKKA2, MKK6, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN17 }, + {MKK6_MKKC, MKK6, MKKC, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK1, CTRY_JAPAN18 }, + {MKK6_MKKA1, MKK6, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN30 }, + {MKK6_FCCA, MKK6, FCCA, MKK5GHZ_FLAG1, NEED_NFC, NO_PSCAN, CTRY_JAPAN31 }, + + /* MKK7 */ + {MKK7_MKKB, MKK7, MKKA, MKK5GHZ_FLAG2, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN19 }, + {MKK7_MKKA, MKK7, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN20 }, + {MKK7_MKKC, MKK7, MKKC, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN21 }, + {MKK7_MKKA1, MKK7, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN32 }, + {MKK7_FCCA, MKK7, FCCA, MKK5GHZ_FLAG1, NEED_NFC, NO_PSCAN, CTRY_JAPAN33 }, + + /* MKK8 */ + {MKK8_MKKB, MKK8, MKKA, MKK5GHZ_FLAG2, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN22 }, + {MKK8_MKKA2, MKK8, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN23 }, + {MKK8_MKKC, MKK8, MKKC, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 , CTRY_JAPAN24 }, + + /* MKK9 */ + {MKK9_MKKA, MKK9, MKKA, MKK5GHZ_FLAG1, NEED_NFC, NO_PSCAN, CTRY_JAPAN34 }, + {MKK9_FCCA, MKK9, FCCA, MKK5GHZ_FLAG1, NEED_NFC, NO_PSCAN, CTRY_JAPAN37 }, + {MKK9_MKKA1, MKK9, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN38 }, + {MKK9_MKKC, MKK9, MKKC, MKK5GHZ_FLAG1, NEED_NFC, NO_PSCAN, CTRY_JAPAN39 }, + {MKK9_MKKA2, MKK9, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN40 }, + + /* MKK10 */ + {MKK10_MKKA, MKK10, MKKA, MKK5GHZ_FLAG1, NEED_NFC, NO_PSCAN, CTRY_JAPAN35 }, + {MKK10_FCCA, MKK10, FCCA, MKK5GHZ_FLAG1, NEED_NFC, NO_PSCAN, CTRY_JAPAN41 }, + {MKK10_MKKA1, MKK10, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN42 }, + {MKK10_MKKC, MKK10, MKKC, MKK5GHZ_FLAG1, NEED_NFC, NO_PSCAN, CTRY_JAPAN43 }, + {MKK10_MKKA2, MKK10, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN44 }, + + /* MKK11 */ + {MKK11_MKKA, MKK11, MKKA, MKK5GHZ_FLAG1, NEED_NFC, NO_PSCAN, CTRY_JAPAN45 }, + {MKK11_FCCA, MKK11, FCCA, MKK5GHZ_FLAG1, NEED_NFC, NO_PSCAN, CTRY_JAPAN46 }, + {MKK11_MKKA1, MKK11, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN47 }, + {MKK11_MKKC, MKK11, MKKC, MKK5GHZ_FLAG1, NEED_NFC, NO_PSCAN, CTRY_JAPAN48 }, + {MKK11_MKKA2, MKK11, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN49 }, + + /* MKK12 */ + {MKK12_MKKA, MKK12, MKKA, MKK5GHZ_FLAG1, NEED_NFC, NO_PSCAN, CTRY_JAPAN50 }, + {MKK12_FCCA, MKK12, FCCA, MKK5GHZ_FLAG1, NEED_NFC, NO_PSCAN, CTRY_JAPAN51 }, + {MKK12_MKKA1, MKK12, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN52 }, + {MKK12_MKKC, MKK12, MKKC, MKK5GHZ_FLAG1, NEED_NFC, NO_PSCAN, CTRY_JAPAN53 }, + {MKK12_MKKA2, MKK12, MKKA, MKK5GHZ_FLAG1, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN54 }, + + + /* These are super domains */ + {WOR0_WORLD, WOR0_WORLD, WOR0_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {WOR1_WORLD, WOR1_WORLD, WOR1_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {WOR2_WORLD, WOR2_WORLD, WOR2_WORLD, DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {WOR3_WORLD, WOR3_WORLD, WOR3_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {WOR4_WORLD, WOR4_WORLD, WOR4_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {WOR5_ETSIC, WOR5_ETSIC, WOR5_ETSIC, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {WOR01_WORLD, WOR01_WORLD, WOR01_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {WOR02_WORLD, WOR02_WORLD, WOR02_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {EU1_WORLD, EU1_WORLD, EU1_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 }, + {WOR9_WORLD, WOR9_WORLD, WOR9_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, + {WORA_WORLD, WORA_WORLD, WORA_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 }, +}; + +/* + * The following table is the master list for all different freqeuncy + * bands with the complete matrix of all possible flags and settings + * for each band if it is used in ANY reg domain. + */ + +#define DEF_REGDMN FCC1_FCCA +#define DEF_DMN_5 FCC1 +#define DEF_DMN_2 FCCA +#define COUNTRY_ERD_FLAG 0x8000 +#define WORLDWIDE_ROAMING_FLAG 0x4000 +#define SUPER_DOMAIN_MASK 0x0fff +#define COUNTRY_CODE_MASK 0x03ff +#define CF_INTERFERENCE (CHANNEL_CW_INT | CHANNEL_RADAR_INT) +#define CHANNEL_14 (2484) /* 802.11g operation is not permitted on channel 14 */ +#define IS_11G_CH14(_ch,_cf) \ + (((_ch) == CHANNEL_14) && ((_cf) == CHANNEL_G)) + +#define YES TRUE +#define NO FALSE + +enum { + CTRY_DEBUG = 0x1ff, /* debug country code */ + CTRY_DEFAULT = 0 /* default country code */ +}; + +typedef struct { + HAL_CTRY_CODE countryCode; + HAL_REG_DOMAIN regDmnEnum; + const char* isoName; + const char* name; + HAL_BOOL allow11g; + HAL_BOOL allow11aTurbo; + HAL_BOOL allow11gTurbo; + HAL_BOOL allow11na; /* HT-40 allowed in 5GHz? */ + HAL_BOOL allow11ng; /* HT-40 allowed in 2GHz? */ + u16_t outdoorChanStart; +} COUNTRY_CODE_TO_ENUM_RD; + +static COUNTRY_CODE_TO_ENUM_RD allCountries[] = { + {CTRY_DEBUG, NO_ENUMRD, "DB", "DEBUG", YES, YES, YES, YES, YES, 7000 }, + {CTRY_DEFAULT, DEF_REGDMN, "NA", "NO_COUNTRY_SET", YES, YES, YES, YES, YES, 7000 }, + {CTRY_ALBANIA, NULL1_WORLD, "AL", "ALBANIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_ALGERIA, NULL1_WORLD, "DZ", "ALGERIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_ARGENTINA, APL3_WORLD, "AR", "ARGENTINA", YES, NO, NO, NO, NO, 7000 }, + {CTRY_ARMENIA, ETSI4_WORLD, "AM", "ARMENIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_AUSTRALIA, FCC6_WORLD, "AU", "AUSTRALIA", YES, YES, YES, YES, YES, 7000 }, + {CTRY_AUSTRIA, ETSI2_WORLD, "AT", "AUSTRIA", YES, NO, YES, YES, YES, 7000 }, + {CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ", "AZERBAIJAN", YES, YES, YES, YES, YES, 7000 }, + {CTRY_BAHRAIN, APL6_WORLD, "BH", "BAHRAIN", YES, NO, YES, NO, YES, 7000 }, + {CTRY_BELARUS, ETSI1_WORLD, "BY", "BELARUS", YES, NO, YES, YES, YES, 7000 }, + {CTRY_BELGIUM, ETSI1_WORLD, "BE", "BELGIUM", YES, NO, YES, YES, YES, 7000 }, + {CTRY_BELIZE, APL1_ETSIC, "BZ", "BELIZE", YES, YES, YES, YES, YES, 7000 }, + {CTRY_BOLIVIA, APL1_ETSIC, "BO", "BOLVIA", YES, YES, YES, YES, YES, 7000 }, + {CTRY_BRAZIL, FCC3_WORLD, "BR", "BRAZIL", NO, NO, NO, NO, NO, 7000 }, + {CTRY_BRUNEI_DARUSSALAM,APL1_WORLD,"BN", "BRUNEI DARUSSALAM", YES, YES, YES, YES, YES, 7000 }, + {CTRY_BULGARIA, ETSI6_WORLD, "BG", "BULGARIA", YES, NO, YES, YES, YES, 7000 }, + {CTRY_CANADA, FCC6_FCCA, "CA", "CANADA", YES, YES, YES, YES, YES, 7000 }, + {CTRY_CHILE, APL6_WORLD, "CL", "CHILE", YES, YES, YES, YES, YES, 7000 }, + {CTRY_CHINA, APL1_WORLD, "CN", "CHINA", YES, YES, YES, YES, YES, 7000 }, + {CTRY_COLOMBIA, FCC1_FCCA, "CO", "COLOMBIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_COSTA_RICA, FCC1_WORLD, "CR", "COSTA RICA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_CROATIA, ETSI3_WORLD, "HR", "CROATIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_CYPRUS, ETSI3_WORLD, "CY", "CYPRUS", YES, YES, YES, YES, YES, 7000 }, + {CTRY_CZECH, ETSI3_WORLD, "CZ", "CZECH REPUBLIC", YES, NO, YES, YES, YES, 7000 }, + {CTRY_DENMARK, ETSI1_WORLD, "DK", "DENMARK", YES, NO, YES, YES, YES, 7000 }, + {CTRY_DOMINICAN_REPUBLIC,FCC1_FCCA,"DO", "DOMINICAN REPUBLIC", YES, YES, YES, YES, YES, 7000 }, + {CTRY_ECUADOR, FCC1_WORLD, "EC", "ECUADOR", YES, NO, NO, NO, YES, 7000 }, + {CTRY_EGYPT, ETSI3_WORLD, "EG", "EGYPT", YES, NO, YES, NO, YES, 7000 }, + {CTRY_EL_SALVADOR, FCC1_WORLD, "SV", "EL SALVADOR", YES, NO, YES, NO, YES, 7000 }, + {CTRY_ESTONIA, ETSI1_WORLD, "EE", "ESTONIA", YES, NO, YES, YES, YES, 7000 }, + {CTRY_FINLAND, ETSI1_WORLD, "FI", "FINLAND", YES, NO, YES, YES, YES, 7000 }, + {CTRY_FRANCE, ETSI1_WORLD, "FR", "FRANCE", YES, NO, YES, YES, YES, 7000 }, + {CTRY_FRANCE2, ETSI3_WORLD, "F2", "FRANCE_RES", YES, NO, YES, YES, YES, 7000 }, + {CTRY_GEORGIA, ETSI4_WORLD, "GE", "GEORGIA", YES, YES, YES, YES, YES, 7000 }, + {CTRY_GERMANY, ETSI1_WORLD, "DE", "GERMANY", YES, NO, YES, YES, YES, 7000 }, + {CTRY_GREECE, ETSI1_WORLD, "GR", "GREECE", YES, NO, YES, YES, YES, 7000 }, + {CTRY_GUATEMALA, FCC1_FCCA, "GT", "GUATEMALA", YES, YES, YES, YES, YES, 7000 }, + {CTRY_HONDURAS, NULL1_WORLD, "HN", "HONDURAS", YES, NO, YES, NO, YES, 7000 }, + {CTRY_HONG_KONG, FCC2_WORLD, "HK", "HONG KONG", YES, YES, YES, YES, YES, 7000 }, + {CTRY_HUNGARY, ETSI4_WORLD, "HU", "HUNGARY", YES, NO, YES, YES, YES, 7000 }, + {CTRY_ICELAND, ETSI1_WORLD, "IS", "ICELAND", YES, NO, YES, YES, YES, 7000 }, + {CTRY_INDIA, APL6_WORLD, "IN", "INDIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_INDONESIA, APL1_WORLD, "ID", "INDONESIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_IRAN, APL1_WORLD, "IR", "IRAN", YES, YES, YES, YES, YES, 7000 }, + {CTRY_IRELAND, ETSI1_WORLD, "IE", "IRELAND", YES, NO, YES, YES, YES, 7000 }, + {CTRY_ISRAEL, ETSI3_WORLD, "IL", "ISRAEL", YES, NO, YES, NO, YES, 7000 }, + {CTRY_ISRAEL2, NULL1_ETSIB, "ISR","ISRAEL_RES", YES, NO, YES, NO, YES, 7000 }, + {CTRY_ITALY, ETSI1_WORLD, "IT", "ITALY", YES, NO, YES, YES, YES, 7000 }, + {CTRY_JAMAICA, ETSI1_WORLD, "JM", "JAMAICA", YES, NO, YES, YES, YES, 7000 }, + {CTRY_JAPAN, MKK1_MKKA, "JP", "JAPAN", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN1, MKK1_MKKB, "J1", "JAPAN1", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN2, MKK1_FCCA, "J2", "JAPAN2", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN3, MKK2_MKKA, "J3", "JAPAN3", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN4, MKK1_MKKA1, "J4", "JAPAN4", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN5, MKK1_MKKA2, "J5", "JAPAN5", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN6, MKK1_MKKC, "J6", "JAPAN6", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN7, MKK3_MKKB, "J7", "JAPAN7", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN8, MKK3_MKKA2, "J8", "JAPAN8", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN9, MKK3_MKKC, "J9", "JAPAN9", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN10, MKK4_MKKB, "J10", "JAPAN10", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN11, MKK4_MKKA2, "J11", "JAPAN11", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN12, MKK4_MKKC, "J12", "JAPAN12", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN13, MKK5_MKKB, "J13", "JAPAN13", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN14, MKK5_MKKA2, "J14", "JAPAN14", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN15, MKK5_MKKC, "J15", "JAPAN15", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN16, MKK6_MKKB, "J16", "JAPAN16", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN17, MKK6_MKKA2, "J17", "JAPAN17", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN18, MKK6_MKKC, "J18", "JAPAN18", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN19, MKK7_MKKB, "J19", "JAPAN19", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN20, MKK7_MKKA, "J20", "JAPAN20", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN21, MKK7_MKKC, "J21", "JAPAN21", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN22, MKK8_MKKB, "J22", "JAPAN22", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN23, MKK8_MKKA2, "J23", "JAPAN23", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN24, MKK8_MKKC, "J24", "JAPAN24", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN25, MKK3_MKKA, "J25", "JAPAN25", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN26, MKK3_MKKA1, "J26", "JAPAN26", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN27, MKK3_FCCA, "J27", "JAPAN27", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN28, MKK4_MKKA1, "J28", "JAPAN28", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN29, MKK4_FCCA, "J29", "JAPAN29", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN30, MKK6_MKKA1, "J30", "JAPAN30", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN31, MKK6_FCCA, "J31", "JAPAN31", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN32, MKK7_MKKA1, "J32", "JAPAN32", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN33, MKK7_FCCA, "J33", "JAPAN33", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN34, MKK9_MKKA, "J34", "JAPAN34", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN35, MKK10_MKKA, "J35", "JAPAN35", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN36, MKK4_MKKA, "J36", "JAPAN36", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN37, MKK9_FCCA, "J37", "JAPAN37", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN38, MKK9_MKKA1, "J38", "JAPAN38", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN39, MKK9_MKKC, "J39", "JAPAN39", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN40, MKK10_MKKA2, "J40", "JAPAN40", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN41, MKK10_FCCA, "J41", "JAPAN41", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN42, MKK10_MKKA1, "J42", "JAPAN42", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN43, MKK10_MKKC, "J43", "JAPAN43", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN44, MKK10_MKKA2, "J44", "JAPAN44", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN45, MKK11_MKKA, "J45", "JAPAN45", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN46, MKK11_FCCA, "J46", "JAPAN46", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN47, MKK11_MKKA1, "J47", "JAPAN47", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN48, MKK11_MKKC, "J48", "JAPAN48", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN49, MKK11_MKKA2, "J49", "JAPAN49", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN50, MKK12_MKKA, "J50", "JAPAN50", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN51, MKK12_FCCA, "J51", "JAPAN51", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN52, MKK12_MKKA1, "J52", "JAPAN52", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN53, MKK12_MKKC, "J53", "JAPAN53", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JAPAN54, MKK12_MKKA2, "J54", "JAPAN54", YES, NO, NO, NO, NO, 7000 }, + {CTRY_JORDAN, ETSI2_WORLD, "JO", "JORDAN", YES, NO, YES, NO, YES, 7000 }, + {CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ", "KAZAKHSTAN", YES, NO, YES, NO, YES, 7000 }, + {CTRY_KOREA_NORTH, APL9_WORLD, "KP", "NORTH KOREA", YES, NO, NO, YES, YES, 7000 }, + {CTRY_KOREA_ROC, APL9_WORLD, "KR", "KOREA REPUBLIC", YES, NO, NO, NO, NO, 7000 }, + {CTRY_KOREA_ROC2, APL2_APLD, "K2", "KOREA REPUBLIC2",YES, NO, NO, NO, NO, 7000 }, + {CTRY_KOREA_ROC3, APL9_WORLD, "K3", "KOREA REPUBLIC3",YES, NO, NO, NO, NO, 7000 }, + {CTRY_KUWAIT, NULL1_WORLD, "KW", "KUWAIT", YES, NO, YES, NO, YES, 7000 }, + {CTRY_LATVIA, ETSI1_WORLD, "LV", "LATVIA", YES, NO, YES, YES, YES, 7000 }, + {CTRY_LEBANON, NULL1_WORLD, "LB", "LEBANON", YES, NO, YES, NO, YES, 7000 }, + {CTRY_LIECHTENSTEIN,ETSI1_WORLD, "LI", "LIECHTENSTEIN", YES, NO, YES, YES, YES, 7000 }, + {CTRY_LITHUANIA, ETSI1_WORLD, "LT", "LITHUANIA", YES, NO, YES, YES, YES, 7000 }, + {CTRY_LUXEMBOURG, ETSI1_WORLD, "LU", "LUXEMBOURG", YES, NO, YES, YES, YES, 7000 }, + {CTRY_MACAU, FCC2_WORLD, "MO", "MACAU", YES, YES, YES, YES, YES, 7000 }, + {CTRY_MACEDONIA, NULL1_WORLD, "MK", "MACEDONIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_MALAYSIA, APL8_WORLD, "MY", "MALAYSIA", NO, NO, NO, NO, NO, 7000 }, + {CTRY_MALTA, ETSI1_WORLD, "MT", "MALTA", YES, NO, YES, YES, YES, 7000 }, + {CTRY_MEXICO, FCC1_FCCA, "MX", "MEXICO", YES, YES, YES, YES, YES, 7000 }, + {CTRY_MONACO, ETSI4_WORLD, "MC", "MONACO", YES, YES, YES, YES, YES, 7000 }, + {CTRY_MOROCCO, NULL1_WORLD, "MA", "MOROCCO", YES, NO, YES, NO, YES, 7000 }, + {CTRY_NETHERLANDS, ETSI1_WORLD, "NL", "NETHERLANDS", YES, NO, YES, YES, YES, 7000 }, + {CTRY_NETHERLANDS_ANT, ETSI1_WORLD, "AN", "NETHERLANDS-ANTILLES", YES, NO, YES, YES, YES, 7000 }, + {CTRY_NEW_ZEALAND, FCC2_ETSIC, "NZ", "NEW ZEALAND", YES, NO, YES, NO, YES, 7000 }, + {CTRY_NORWAY, ETSI1_WORLD, "NO", "NORWAY", YES, NO, YES, YES, YES, 7000 }, + {CTRY_OMAN, APL6_WORLD, "OM", "OMAN", YES, NO, YES, NO, YES, 7000 }, + {CTRY_PAKISTAN, NULL1_WORLD, "PK", "PAKISTAN", YES, NO, YES, NO, YES, 7000 }, + {CTRY_PANAMA, FCC1_FCCA, "PA", "PANAMA", YES, YES, YES, YES, YES, 7000 }, + {CTRY_PERU, APL1_WORLD, "PE", "PERU", YES, NO, YES, NO, YES, 7000 }, + {CTRY_PHILIPPINES, APL1_WORLD, "PH", "PHILIPPINES", YES, YES, YES, YES, YES, 7000 }, + {CTRY_POLAND, ETSI1_WORLD, "PL", "POLAND", YES, NO, YES, YES, YES, 7000 }, + {CTRY_PORTUGAL, ETSI1_WORLD, "PT", "PORTUGAL", YES, NO, YES, YES, YES, 7000 }, + {CTRY_PUERTO_RICO, FCC1_FCCA, "PR", "PUERTO RICO", YES, YES, YES, YES, YES, 7000 }, + {CTRY_QATAR, NULL1_WORLD, "QA", "QATAR", YES, NO, YES, NO, YES, 7000 }, + {CTRY_ROMANIA, NULL1_WORLD, "RO", "ROMANIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_RUSSIA, NULL1_WORLD, "RU", "RUSSIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_SAUDI_ARABIA,NULL1_WORLD, "SA", "SAUDI ARABIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_SERBIA_MONT, ETSI1_WORLD, "CS", "SERBIA & MONTENEGRO", YES, NO, YES, YES, YES, 7000 }, + {CTRY_SINGAPORE, APL6_WORLD, "SG", "SINGAPORE", YES, YES, YES, YES, YES, 7000 }, + {CTRY_SLOVAKIA, ETSI1_WORLD, "SK", "SLOVAK REPUBLIC",YES, NO, YES, YES, YES, 7000 }, + {CTRY_SLOVENIA, ETSI1_WORLD, "SI", "SLOVENIA", YES, NO, YES, YES, YES, 7000 }, + {CTRY_SOUTH_AFRICA,FCC3_WORLD, "ZA", "SOUTH AFRICA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_SPAIN, ETSI1_WORLD, "ES", "SPAIN", YES, NO, YES, YES, YES, 7000 }, + {CTRY_SRILANKA, FCC3_WORLD, "LK", "SRI LANKA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_SWEDEN, ETSI1_WORLD, "SE", "SWEDEN", YES, NO, YES, YES, YES, 7000 }, + {CTRY_SWITZERLAND, ETSI1_WORLD, "CH", "SWITZERLAND", YES, NO, YES, YES, YES, 7000 }, + {CTRY_SYRIA, NULL1_WORLD, "SY", "SYRIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_TAIWAN, APL3_FCCA, "TW", "TAIWAN", YES, YES, YES, YES, YES, 7000 }, + {CTRY_THAILAND, NULL1_WORLD, "TH", "THAILAND", YES, NO, YES, NO, YES, 7000 }, + {CTRY_TRINIDAD_Y_TOBAGO,ETSI4_WORLD,"TT", "TRINIDAD & TOBAGO", YES, NO, YES, NO, YES, 7000 }, + {CTRY_TUNISIA, ETSI3_WORLD, "TN", "TUNISIA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_TURKEY, ETSI3_WORLD, "TR", "TURKEY", YES, NO, YES, NO, YES, 7000 }, + {CTRY_UKRAINE, NULL1_WORLD, "UA", "UKRAINE", YES, NO, YES, NO, YES, 7000 }, + {CTRY_UAE, NULL1_WORLD, "AE", "UNITED ARAB EMIRATES", YES, NO, YES, NO, YES, 7000 }, + {CTRY_UNITED_KINGDOM, ETSI1_WORLD,"GB", "UNITED KINGDOM", YES, NO, YES, NO, YES, 7000 }, + {CTRY_UNITED_STATES, FCC3_FCCA, "US", "UNITED STATES", YES, YES, YES, YES, YES, 5825 }, + {CTRY_UNITED_STATES_FCC49, FCC4_FCCA, "PS", "UNITED STATES (PUBLIC SAFETY)", YES, YES, YES, YES, YES, 7000 }, + {CTRY_URUGUAY, FCC1_WORLD, "UY", "URUGUAY", YES, NO, YES, NO, YES, 7000 }, + {CTRY_UZBEKISTAN, FCC3_FCCA, "UZ", "UZBEKISTAN", YES, YES, YES, YES, YES, 7000 }, + {CTRY_VENEZUELA, APL2_ETSIC, "VE", "VENEZUELA", YES, NO, YES, NO, YES, 7000 }, + {CTRY_VIET_NAM, NULL1_WORLD, "VN", "VIET NAM", YES, NO, YES, NO, YES, 7000 }, + {CTRY_YEMEN, NULL1_WORLD, "YE", "YEMEN", YES, NO, YES, NO, YES, 7000 }, + {CTRY_ZIMBABWE, NULL1_WORLD, "ZW", "ZIMBABWE", YES, NO, YES, NO, YES, 7000 } +}; + +typedef struct RegDmnFreqBand { + u16_t lowChannel; /* Low channel center in MHz */ + u16_t highChannel; /* High Channel center in MHz */ + u8_t powerDfs; /* Max power (dBm) for channel + range when using DFS */ + u8_t antennaMax; /* Max allowed antenna gain */ + u8_t channelBW; /* Bandwidth of the channel */ + u8_t channelSep; /* Channel separation within + the band */ + u64_t useDfs; /* Use DFS in the RegDomain + if corresponding bit is set */ + u64_t usePassScan; /* Use Passive Scan in the RegDomain + if corresponding bit is set */ + u8_t regClassId; /* Regulatory class id */ + u8_t useExtChanDfs; /* Regulatory class id */ +} REG_DMN_FREQ_BAND; + +/* Bit masks for DFS per regdomain */ + +enum { + NO_DFS = 0x0000000000000000ULL, + DFS_FCC3 = 0x0000000000000001ULL, + DFS_ETSI = 0x0000000000000002ULL, + DFS_MKK4 = 0x0000000000000004ULL, +}; + +/* The table of frequency bands is indexed by a bitmask. The ordering + * must be consistent with the enum below. When adding a new + * frequency band, be sure to match the location in the enum with the + * comments + */ + +/* + * 5GHz 11A channel tags + */ + +enum { + F1_4915_4925, + F1_4935_4945, + F1_4920_4980, + F1_4942_4987, + F1_4945_4985, + F1_4950_4980, + F1_5035_5040, + F1_5040_5080, + F1_5055_5055, + + F1_5120_5240, + + F1_5170_5230, + F2_5170_5230, + + F1_5180_5240, + F2_5180_5240, + F3_5180_5240, + F4_5180_5240, + F5_5180_5240, + F6_5180_5240, + F7_5180_5240, + + F1_5180_5320, + + F1_5240_5280, + + F1_5260_5280, + + F1_5260_5320, + F2_5260_5320, + F3_5260_5320, + F4_5260_5320, + F5_5260_5320, + F6_5260_5320, + F7_5260_5320, + + F1_5260_5700, + + F1_5280_5320, + + F1_5500_5580, + + F1_5500_5620, + + F1_5500_5700, + F2_5500_5700, + F3_5500_5700, + F4_5500_5700, + + F1_5660_5700, + + F1_5745_5805, + F2_5745_5805, + F3_5745_5805, + + F1_5745_5825, + F2_5745_5825, + F3_5745_5825, + F4_5745_5825, + F5_5745_5825, + F6_5745_5825, + + W1_4920_4980, + W1_5040_5080, + W1_5170_5230, + W1_5180_5240, + W1_5260_5320, + W1_5745_5825, + W1_5500_5700, + W2_5260_5320, + W2_5180_5240, + W2_5825_5825, +}; + +static REG_DMN_FREQ_BAND regDmn5GhzFreq[] = { + { 4915, 4925, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16, 0 }, /* F1_4915_4925 */ + { 4935, 4945, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16, 0 }, /* F1_4935_4945 */ + { 4920, 4980, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 7, 0 }, /* F1_4920_4980 */ + { 4942, 4987, 27, 6, 5, 5, DFS_FCC3, PSCAN_FCC, 0, 0 }, /* F1_4942_4987 */ + { 4945, 4985, 30, 6, 10, 5, DFS_FCC3, PSCAN_FCC, 0, 0 }, /* F1_4945_4985 */ + { 4950, 4980, 33, 6, 20, 5, DFS_FCC3, PSCAN_FCC, 0, 0 }, /* F1_4950_4980 */ + { 5035, 5040, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12, 0 }, /* F1_5035_5040 */ + { 5040, 5080, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 2, 0 }, /* F1_5040_5080 */ + { 5055, 5055, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12, 0 }, /* F1_5055_5055 */ + + { 5120, 5240, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0, 0 }, /* F1_5120_5240 */ + + { 5170, 5230, 23, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1, 0 }, /* F1_5170_5230 */ + { 5170, 5230, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1, 0 }, /* F2_5170_5230 */ + + { 5180, 5240, 15, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0, 0 }, /* F1_5180_5240 */ + { 5180, 5240, 17, 6, 20, 20, NO_DFS, PSCAN_FCC, 1, 0 }, /* F2_5180_5240 */ + { 5180, 5240, 18, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0, 0 }, /* F3_5180_5240 */ + { 5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0, 0 }, /* F4_5180_5240 */ + { 5180, 5240, 23, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0, 0 }, /* F5_5180_5240 */ + { 5180, 5240, 23, 6, 20, 20, NO_DFS, PSCAN_FCC, 0, 0 }, /* F6_5180_5240 */ + { 5180, 5240, 23, 6, 20, 20, NO_DFS, NO_PSCAN, 0 }, /* F7_5180_5240 */ + + { 5180, 5320, 20, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0, 0 }, /* F1_5180_5320 */ + + { 5240, 5280, 23, 0, 20, 20, DFS_FCC3, PSCAN_FCC | PSCAN_ETSI, 0, 0 }, /* F1_5240_5280 */ + + { 5260, 5280, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0, 0 }, /* F1_5260_5280 */ + + { 5260, 5320, 18, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0, 0 }, /* F1_5260_5320 */ + + { 5260, 5320, 20, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4, PSCAN_FCC | PSCAN_ETSI | PSCAN_MKK3 , 0, 0 }, + /* F2_5260_5320 */ + + { 5260, 5320, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2, 0 }, /* F3_5260_5320 */ + { 5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2, 0 }, /* F4_5260_5320 */ + { 5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0, 0 }, /* F5_5260_5320 */ + { 5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0, 0 }, /* F6_5260_5320 */ + { 5260, 5320, 17, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0, 0 }, /* F7_5260_5320 */ + + { 5260, 5700, 5, 6, 20, 20, DFS_FCC3 | DFS_ETSI, NO_PSCAN, 0, 0 }, /* F1_5260_5700 */ + + { 5280, 5320, 17, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0, 0 }, /* F1_5280_5320 */ + + { 5500, 5580, 23, 6, 20, 20, DFS_FCC3, PSCAN_FCC, 0}, /* F1_5500_5580 */ + + { 5500, 5620, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0, 0 }, /* F1_5500_5620 */ + + { 5500, 5700, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 4, 0 }, /* F1_5500_5700 */ + { 5500, 5700, 27, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0, 0 }, /* F2_5500_5700 */ + { 5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0, 0 }, /* F3_5500_5700 */ + { 5500, 5700, 20, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4, PSCAN_MKK3 | PSCAN_FCC, 0, 0 }, + /* F4_5500_5700 */ + + { 5660, 5700, 23, 6, 20, 20, DFS_FCC3, PSCAN_FCC, 0}, /* F1_5660_5700 */ + + { 5745, 5805, 23, 0, 20, 20, NO_DFS, NO_PSCAN, 0, 0 }, /* F1_5745_5805 */ + { 5745, 5805, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0, 0 }, /* F2_5745_5805 */ + { 5745, 5805, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0, 0 }, /* F3_5745_5805 */ + { 5745, 5825, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0, 0 }, /* F1_5745_5825 */ + { 5745, 5825, 17, 0, 20, 20, NO_DFS, NO_PSCAN, 0, 0 }, /* F2_5745_5825 */ + { 5745, 5825, 20, 0, 20, 20, DFS_ETSI, NO_PSCAN, 0, 0 }, /* F3_5745_5825 */ + { 5745, 5825, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0, 0 }, /* F4_5745_5825 */ + { 5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 3, 0 }, /* F5_5745_5825 */ + { 5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0, 0 }, /* F6_5745_5825 */ + + /* + * Below are the world roaming channels + * All WWR domains have no power limit, instead use the card's CTL + * or max power settings. + */ + { 4920, 4980, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0, 0 }, /* W1_4920_4980 */ + { 5040, 5080, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 }, /* W1_5040_5080 */ + { 5170, 5230, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0, 0 }, /* W1_5170_5230 */ + { 5180, 5240, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0, 0 }, /* W1_5180_5240 */ + { 5260, 5320, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0, 0 }, /* W1_5260_5320 */ + { 5745, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0, 0 }, /* W1_5745_5825 */ + { 5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0, 0 }, /* W1_5500_5700 */ + { 5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0, 0 }, /* W2_5260_5320 */ + { 5180, 5240, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0, 0 }, /* W2_5180_5240 */ + { 5825, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0, 0 }, /* W2_5825_5825 */ +}; +/* + * 5GHz Turbo (dynamic & static) tags + */ + +enum { + T1_5130_5210, + T1_5250_5330, + T1_5370_5490, + T1_5530_5650, + + T1_5150_5190, + T1_5230_5310, + T1_5350_5470, + T1_5510_5670, + + T1_5200_5240, + T2_5200_5240, + T1_5210_5210, + T2_5210_5210, + + T1_5280_5280, + T2_5280_5280, + T1_5250_5250, + T1_5290_5290, + T1_5250_5290, + T2_5250_5290, + + T1_5540_5660, + T1_5760_5800, + T2_5760_5800, + + T1_5765_5805, + + WT1_5210_5250, + WT1_5290_5290, + WT1_5540_5660, + WT1_5760_5800, +}; + +static REG_DMN_FREQ_BAND regDmn5GhzTurboFreq[] = { + { 5130, 5210, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5130_5210 */ + { 5250, 5330, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0, 0}, /* T1_5250_5330 */ + { 5370, 5490, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5370_5490 */ + { 5530, 5650, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0, 0}, /* T1_5530_5650 */ + + { 5150, 5190, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5150_5190 */ + { 5230, 5310, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0, 0}, /* T1_5230_5310 */ + { 5350, 5470, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5350_5470 */ + { 5510, 5670, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0, 0}, /* T1_5510_5670 */ + + { 5200, 5240, 17, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5200_5240 */ + { 5200, 5240, 23, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T2_5200_5240 */ + { 5210, 5210, 17, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5210_5210 */ + { 5210, 5210, 23, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T2_5210_5210 */ + + { 5280, 5280, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T1_5280_5280 */ + { 5280, 5280, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T2_5280_5280 */ + { 5250, 5250, 17, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T1_5250_5250 */ + { 5290, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T1_5290_5290 */ + { 5250, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T1_5250_5290 */ + { 5250, 5290, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T2_5250_5290 */ + + { 5540, 5660, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0, 0}, /* T1_5540_5660 */ + { 5760, 5800, 20, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5760_5800 */ + { 5760, 5800, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T2_5760_5800 */ + + { 5765, 5805, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_5765_5805 */ + + /* + * Below are the WWR frequencies + */ + + { 5210, 5250, 15, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0, 0}, /* WT1_5210_5250 */ + { 5290, 5290, 18, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0, 0}, /* WT1_5290_5290 */ + { 5540, 5660, 20, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0, 0}, /* WT1_5540_5660 */ + { 5760, 5800, 20, 0, 40, 40, NO_DFS, PSCAN_WWR, 0, 0}, /* WT1_5760_5800 */ +}; + +/* + * 2GHz 11b channel tags + */ +enum { + F1_2312_2372, + F2_2312_2372, + + F1_2412_2472, + F2_2412_2472, + F3_2412_2472, + + F1_2412_2462, + F2_2412_2462, + + F1_2432_2442, + + F1_2457_2472, + + F1_2467_2472, + + F1_2484_2484, + F2_2484_2484, + + F1_2512_2732, + + W1_2312_2372, + W1_2412_2412, + W1_2417_2432, + W1_2437_2442, + W1_2447_2457, + W1_2462_2462, + W1_2467_2467, + W2_2467_2467, + W1_2472_2472, + W2_2472_2472, + W1_2484_2484, + W2_2484_2484, +}; + +static REG_DMN_FREQ_BAND regDmn2GhzFreq[] = { + { 2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2312_2372 */ + { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F2_2312_2372 */ + + { 2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2412_2472 */ + { 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0, 0}, /* F2_2412_2472 */ + { 2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F3_2412_2472 */ + + { 2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2412_2462 */ + { 2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0, 0}, /* F2_2412_2462 */ + { 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2432_2442 */ + + { 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2457_2472 */ + + { 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0, 0}, /* F1_2467_2472 */ + + { 2484, 2484, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2484_2484 */ + { 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA | PSCAN_MKKA1 | PSCAN_MKKA2, 0, 0}, /* F2_2484_2484 */ + + { 2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* F1_2512_2732 */ + + /* + * WWR have powers opened up to 20dBm. Limits should often come from CTL/Max powers + */ + + { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* W1_2312_2372 */ + { 2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* W1_2412_2412 */ + { 2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* W1_2417_2432 */ + { 2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* W1_2437_2442 */ + { 2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* W1_2447_2457 */ + { 2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* W1_2462_2462 */ + { 2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0, 0}, /* W1_2467_2467 */ + { 2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0, 0}, /* W2_2467_2467 */ + { 2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0, 0}, /* W1_2472_2472 */ + { 2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0, 0}, /* W2_2472_2472 */ + { 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0, 0}, /* W1_2484_2484 */ + { 2484, 2484, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0, 0}, /* W2_2484_2484 */ +}; + + +/* + * 2GHz 11g channel tags + */ + +enum { + G1_2312_2372, + G2_2312_2372, + + G1_2412_2472, + G2_2412_2472, + G3_2412_2472, + + G1_2412_2462, + G2_2412_2462, + + G1_2432_2442, + + G1_2457_2472, + + G1_2512_2732, + + G1_2467_2472 , + + WG1_2312_2372, + WG1_2412_2412, + WG1_2417_2432, + WG1_2437_2442, + WG1_2447_2457, + WG1_2462_2462, + WG1_2467_2467, + WG2_2467_2467, + WG1_2472_2472, + WG2_2472_2472, + +}; +static REG_DMN_FREQ_BAND regDmn2Ghz11gFreq[] = { + { 2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* G1_2312_2372 */ + { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* G2_2312_2372 */ + + { 2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* G1_2412_2472 */ + { 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0, 0}, /* G2_2412_2472 */ + { 2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* G3_2412_2472 */ + + { 2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* G1_2412_2462 */ + { 2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0, 0}, /* G2_2412_2462 */ + { 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* G1_2432_2442 */ + + { 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* G1_2457_2472 */ + + { 2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* G1_2512_2732 */ + + { 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0, 0 }, /* G1_2467_2472 */ + + /* + * WWR open up the power to 20dBm + */ + + { 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* WG1_2312_2372 */ + { 2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* WG1_2412_2412 */ + { 2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* WG1_2417_2432 */ + { 2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* WG1_2437_2442 */ + { 2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* WG1_2447_2457 */ + { 2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* WG1_2462_2462 */ + { 2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0, 0}, /* WG1_2467_2467 */ + { 2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0, 0}, /* WG2_2467_2467 */ + { 2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0, 0}, /* WG1_2472_2472 */ + { 2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0, 0}, /* WG2_2472_2472 */ +}; +/* + * 2GHz Dynamic turbo tags + */ + +enum { + T1_2312_2372, + T1_2437_2437, + T2_2437_2437, + T3_2437_2437, + T1_2512_2732 +}; + +static REG_DMN_FREQ_BAND regDmn2Ghz11gTurboFreq[] = { + { 2312, 2372, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_2312_2372 */ + { 2437, 2437, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_2437_2437 */ + { 2437, 2437, 20, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T2_2437_2437 */ + { 2437, 2437, 18, 6, 40, 40, NO_DFS, PSCAN_WWR, 0, 0}, /* T3_2437_2437 */ + { 2512, 2732, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* T1_2512_2732 */ +}; + + + +/* + * 2GHz 11n frequency tags + */ +enum { + NG1_2422_2452, + NG2_2422_2452, + NG3_2422_2452, + + NG_DEMO_ALL_CHANNELS, +}; + +static REG_DMN_FREQ_BAND regDmn2Ghz11ngFreq[] = { + { 2422, 2452, 20, 0, 40, 5, NO_DFS, NO_PSCAN, 0, 0}, /* NG1_2422_2452 */ + { 2422, 2452, 27, 0, 40, 5, NO_DFS, NO_PSCAN, 0, 0}, /* NG2_2422_2452 */ + { 2422, 2452, 30, 0, 40, 5, NO_DFS, NO_PSCAN, 0, 0}, /* NG3_2422_2452 */ + + { 2312, 2732, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0, 0}, /* NG_DEMO_ALL_CHANNELS */ +}; + + +/* + * 5GHz 11n frequency tags + */ +enum { + NA1_5190_5230, + NA2_5190_5230, + NA3_5190_5230, + NA4_5190_5230, + NA5_5190_5230, + + NA1_5270_5270, + + NA1_5270_5310, + NA2_5270_5310, + NA3_5270_5310, + NA4_5270_5310, + + NA1_5310_5310, + + NA1_5510_5630, + + NA1_5510_5670, + NA2_5510_5670, + NA3_5510_5670, + + NA1_5755_5795, + NA2_5755_5795, + NA3_5755_5795, + NA4_5755_5795, + NA5_5755_5795, + + NA1_5795_5795, + + NA_DEMO_ALL_CHANNELS, +}; + +static REG_DMN_FREQ_BAND regDmn5Ghz11naFreq[] = { + /* + * ToDo: This table needs to be completely populated with 5GHz 11n properties + */ + { 5190, 5230, 15, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA1_5190_5230 */ + { 5190, 5230, 17, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA2_5190_5230 */ + { 5190, 5230, 18, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA3_5190_5230 */ + { 5190, 5230, 20, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA4_5190_5230 */ + { 5190, 5230, 23, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA5_5190_5230 */ + + { 5270, 5270, 23, 6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA1_5270_5270 */ + + { 5270, 5310, 18, 6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA1_5270_5310 */ + { 5270, 5310, 20, 0, 40, 40, DFS_FCC3|DFS_ETSI|DFS_MKK4, NO_PSCAN, 0, 1}, /* NA2_5270_5310 */ + { 5270, 5310, 23, 6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA3_5270_5310 */ + { 5270, 5310, 30, 6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA4_5270_5310 */ + + { 5310, 5310, 17, 6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA1_5310_5310 */ + + { 5510, 5630, 30, 6, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA1_5510_5630 */ + + { 5510, 5670, 20, 6, 40, 40, DFS_FCC3|DFS_ETSI|DFS_MKK4, NO_PSCAN, 0, 1}, /* NA1_5510_5670 */ + { 5510, 5670, 27, 0, 40, 40, DFS_FCC3|DFS_ETSI, NO_PSCAN, 0, 1}, /* NA2_5510_5670 */ + { 5510, 5670, 30, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0, 1}, /* NA3_5510_5670 */ + + { 5755, 5795, 17, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA1_5755_5795 */ + { 5755, 5795, 20, 6, 40, 40, DFS_ETSI, NO_PSCAN, 0, 0}, /* NA2_5755_5795 */ + { 5755, 5795, 23, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA3_5755_5795 */ + { 5755, 5795, 30, 0, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA4_5755_5795 */ + { 5755, 5795, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA5_5755_5795 */ + + { 5795, 5795, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA1_5795_5795 */ + + { 4920, 6100, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0, 0}, /* NA_DEMO_ALL_CHANNELS */ +}; + +typedef struct regDomain { + u16_t regDmnEnum; /* value from EnumRd table */ + u8_t conformanceTestLimit; + u64_t dfsMask; /* DFS bitmask for 5Ghz tables */ + u64_t pscan; /* Bitmask for passive scan */ + u32_t flags; /* Requirement flags (AdHoc disallow, noise + floor cal needed, etc) */ + u64_t chan11a[BMLEN];/* 128 bit bitmask for channel/band + selection */ + u64_t chan11a_turbo[BMLEN];/* 128 bit bitmask for channel/band + selection */ + u64_t chan11a_dyn_turbo[BMLEN]; /* 128 bit bitmask for channel/band + selection */ + u64_t chan11b[BMLEN];/* 128 bit bitmask for channel/band + selection */ + u64_t chan11g[BMLEN];/* 128 bit bitmask for channel/band + selection */ + u64_t chan11g_turbo[BMLEN];/* 128 bit bitmask for channel/band + selection */ + u64_t chan11ng[BMLEN];/* 128 bit bitmask for 11n in 2GHz */ + u64_t chan11na[BMLEN];/* 128 bit bitmask for 11n in 5GHz */ +} REG_DOMAIN; + +static REG_DOMAIN regDomains[] = { + + {DEBUG_REG_DMN, FCC, NO_DFS, NO_PSCAN, NO_REQ, + BM(F1_5120_5240, F1_5260_5700, F1_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5130_5210, T1_5250_5330, T1_5370_5490, T1_5530_5650, T1_5150_5190, T1_5230_5310, T1_5350_5470, T1_5510_5670, -1, -1, -1, -1), + BM(T1_5200_5240, T1_5280_5280, T1_5540_5660, T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1), + BM(F1_2312_2372, F1_2412_2472, F1_2484_2484, F1_2512_2732, -1, -1, -1, -1, -1, -1, -1, -1), + BM(G1_2312_2372, G1_2412_2472, G1_2512_2732, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_2312_2372, T1_2437_2437, T1_2512_2732, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(NG_DEMO_ALL_CHANNELS, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(NA_DEMO_ALL_CHANNELS, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, + + {APL1, ETSI, NO_DFS, NO_PSCAN, NO_REQ, + BM(F4_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA4_5755_5795, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, + + {APL2, ETSI, NO_DFS, NO_PSCAN, NO_REQ, + BM(F1_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA3_5755_5795, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, + + {APL3, FCC, NO_DFS, NO_PSCAN, NO_REQ, + BM(F1_5280_5320, F2_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA1_5310_5310, NA4_5755_5795, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, + + {APL4, ETSI, NO_DFS, NO_PSCAN, NO_REQ, + BM(F4_5180_5240, F3_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA4_5190_5230, NA2_5755_5795, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, + + {APL5, ETSI, NO_DFS, NO_PSCAN, NO_REQ, + BM(F2_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA1_5755_5795, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, + + {APL6, ETSI, DFS_ETSI, PSCAN_FCC_T | PSCAN_FCC , NO_REQ, + BM(F4_5180_5240, F2_5260_5320, F3_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T2_5210_5210, T1_5250_5290, T1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA4_5190_5230, NA2_5270_5310, NA2_5755_5795, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, + + {APL7, FCC, NO_DFS, PSCAN_FCC_T | PSCAN_FCC , NO_REQ, + BM(F7_5260_5320, F4_5500_5700, F3_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA1_5310_5310, NA2_5755_5795, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, + {APL8, ETSI, NO_DFS, NO_PSCAN, DISALLOW_ADHOC_11A|DISALLOW_ADHOC_11A_TURB, + BM(F6_5260_5320, F4_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA4_5270_5310, NA4_5755_5795, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, + + {APL9, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A|DISALLOW_ADHOC_11A_TURB, + BM(F1_5180_5320, F1_5500_5620, F3_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA4_5190_5230, NA2_5270_5310, NA1_5510_5630, NA4_5755_5795, -1, -1, -1, -1, -1, -1, -1, -1)}, + + {ETSI1, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, + BM(W2_5180_5240, F2_5260_5320, F2_5500_5700, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA4_5190_5230, NA2_5270_5310, NA2_5510_5670, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, + + {ETSI2, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, + BM(F3_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA3_5190_5230, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, + + {ETSI3, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, + BM(W2_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA4_5190_5230, NA2_5270_5310, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, + + {ETSI4, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, + BM(F3_5180_5240, F1_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA3_5190_5230, NA1_5270_5310, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, + + {ETSI5, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, + BM(F1_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA1_5190_5230, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, + + {ETSI6, ETSI, DFS_ETSI, PSCAN_ETSI, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, + BM(F5_5180_5240, F1_5260_5280, F3_5500_5700, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA5_5190_5230, NA1_5270_5270, NA3_5510_5670, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, + + {FCC1, FCC, NO_DFS, NO_PSCAN, NO_REQ, + BM(F2_5180_5240, F4_5260_5320, F5_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5210_5210, T2_5250_5290, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5200_5240, T1_5280_5280, T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA2_5190_5230, NA3_5270_5310, NA4_5755_5795, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, + + {FCC2, FCC, NO_DFS, NO_PSCAN, NO_REQ, + BM(F6_5180_5240, F5_5260_5320, F6_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T2_5200_5240, T1_5280_5280, T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA5_5190_5230, NA3_5270_5310, NA4_5755_5795, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, + + {FCC3, FCC, DFS_FCC3, PSCAN_FCC | PSCAN_FCC_T, NO_REQ, + BM(F2_5180_5240, F3_5260_5320, F1_5500_5700, F5_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5210_5210, T1_5250_5250, T1_5290_5290, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T1_5200_5240, T2_5280_5280, T1_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA2_5190_5230, NA2_5270_5310, NA3_5510_5670, NA4_5755_5795, -1, -1, -1, -1, -1, -1, -1, -1)}, + + {FCC4, FCC, DFS_FCC3, PSCAN_FCC | PSCAN_FCC_T, NO_REQ, + BM(F1_4942_4987, F1_4945_4985, F1_4950_4980, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO}, + + {FCC5, FCC, NO_DFS, NO_PSCAN, NO_REQ, + BM(F2_5180_5240, F5_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA2_5190_5230, NA4_5755_5795, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, + + {FCC6, FCC, DFS_FCC3, PSCAN_FCC, NO_REQ, + BM(F7_5180_5240, F5_5260_5320, F1_5500_5580, F1_5660_5700, F6_5745_5825, -1, -1, -1, -1, -1, -1, -1), + BM(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T2_5200_5240, T1_5280_5280, T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA5_5190_5230, NA5_5755_5795, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, + + {MKK1, MKK, NO_DFS, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB, + BM(F1_5170_5230, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO}, + + {MKK2, MKK, NO_DFS, PSCAN_MKK2, DISALLOW_ADHOC_11A_TURB, + BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040, F1_5055_5055, F1_5040_5080, F1_5170_5230, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO}, + + /* UNI-1 even */ + {MKK3, MKK, NO_DFS, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB, + BM(F4_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA4_5190_5230, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, + + /* UNI-1 even + UNI-2 */ + {MKK4, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB, + BM(F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA4_5190_5230, NA2_5270_5310, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, + + /* UNI-1 even + UNI-2 + mid-band */ + {MKK5, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB, + BM(F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA4_5190_5230, NA2_5270_5310, NA1_5510_5670, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, + + /* UNI-1 odd + even */ + {MKK6, MKK, DFS_MKK4, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB, + BM(F2_5170_5230, F4_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA4_5190_5230, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, + + /* UNI-1 odd + UNI-1 even + UNI-2 */ + {MKK7, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3 , DISALLOW_ADHOC_11A_TURB, + BM(F2_5170_5230, F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA4_5190_5230, NA2_5270_5310, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, + + /* UNI-1 odd + UNI-1 even + UNI-2 + mid-band */ + {MKK8, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3 , DISALLOW_ADHOC_11A_TURB, + BM(F2_5170_5230, F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BM(NA4_5190_5230, NA2_5270_5310, NA1_5510_5670, -1, -1, -1, -1, -1, -1, -1, -1, -1)}, + + /* UNI-1 even + 4.9 GHZ */ + {MKK9, MKK, NO_DFS, NO_PSCAN, DISALLOW_ADHOC_11A_TURB, + BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040, F1_5055_5055, F1_5040_5080, F4_5180_5240, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO}, + + /* UNI-1 even + UNI-2 + 4.9 GHZ */ + {MKK10, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB, + BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040, F1_5055_5055, F1_5040_5080, F4_5180_5240, F2_5260_5320, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO}, + + /* UNI-1 even + UNI-2 + 4.9 GHZ + mid-band */ + {MKK11, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB, + BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040, F1_5055_5055, F1_5040_5080, F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO}, + + /* UNI-1 even + UNI-1 odd + UNI-2 + 4.9 GHZ + mid-band */ + {MKK12, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB, + BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040, F1_5055_5055, F1_5040_5080, F1_5170_5230, F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1), + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO}, + + /* Defined here to use when 2G channels are authorised for country K2 */ + {APLD, NO_CTL, NO_DFS, NO_PSCAN, NO_REQ, + BMZERO, + BMZERO, + BMZERO, + BM(F2_2312_2372,F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(G2_2312_2372,G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BMZERO}, + + {ETSIA, NO_CTL, NO_DFS, PSCAN_ETSIA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, + BMZERO, + BMZERO, + BMZERO, + BM(F1_2457_2472,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(G1_2457_2472,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO}, + + {ETSIB, ETSI, NO_DFS, PSCAN_ETSIB, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, + BMZERO, + BMZERO, + BMZERO, + BM(F1_2432_2442,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), + BM(G1_2432_2442,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), + BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO}, + + {ETSIC, ETSI, NO_DFS, PSCAN_ETSIC, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, + BMZERO, + BMZERO, + BMZERO, + BM(F3_2412_2472,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), + BM(G3_2412_2472,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), + BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO}, + + {FCCA, FCC, NO_DFS, NO_PSCAN, NO_REQ, + BMZERO, + BMZERO, + BMZERO, + BM(F1_2412_2462,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), + BM(G1_2412_2462,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), + BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(NG2_2422_2452,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO}, + + {MKKA, MKK, NO_DFS, PSCAN_MKKA | PSCAN_MKKA_G | PSCAN_MKKA1 | PSCAN_MKKA1_G | PSCAN_MKKA2 | PSCAN_MKKA2_G, DISALLOW_ADHOC_11A_TURB, + BMZERO, + BMZERO, + BMZERO, + BM(F2_2412_2462, F1_2467_2472, F2_2484_2484, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(G2_2412_2462, G1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(NG1_2422_2452,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO}, + + {MKKC, MKK, NO_DFS, NO_PSCAN, NO_REQ, + BMZERO, + BMZERO, + BMZERO, + BM(F2_2412_2472,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), + BM(G2_2412_2472,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), + BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(NG1_2422_2452,-1,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO}, + + {WORLD, ETSI, NO_DFS, NO_PSCAN, NO_REQ, + BMZERO, + BMZERO, + BMZERO, + BM(F2_2412_2472,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), + BM(G2_2412_2472,-1,-1,-1,-1,-1,-1,-1, -1, -1, -1, -1), + BM(T2_2437_2437,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BM(NG1_2422_2452,-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO}, + + {WOR0_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D, + BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, W1_5500_5700, -1, -1, -1, -1, -1, -1, -1), + BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BM(W1_2412_2412,W1_2437_2442,W1_2462_2462,W1_2472_2472,W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1, -1, -1), + BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462,WG1_2472_2472,WG1_2417_2432,WG1_2447_2457,WG1_2467_2467, -1, -1, -1, -1, -1), + BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO}, + + {WOR01_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D, + BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, W1_5500_5700, -1, -1, -1, -1, -1, -1, -1), + BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432, W1_2447_2457, -1, -1, -1, -1, -1, -1, -1), + BM(WG1_2412_2412, WG1_2437_2442, WG1_2462_2462, WG1_2417_2432, WG1_2447_2457, -1, -1, -1, -1, -1, -1, -1), + BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO}, + + {WOR02_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D, + BM(W1_5260_5320, W1_5180_5240,W1_5170_5230,W1_5745_5825,W1_5500_5700, -1, -1, -1, -1, -1, -1, -1), + BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BM(W1_2412_2412,W1_2437_2442,W1_2462_2462, W1_2472_2472,W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1), + BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462, WG1_2472_2472,WG1_2417_2432, WG1_2447_2457, WG1_2467_2467, -1, -1, -1, -1, -1), + BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO}, + + {EU1_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D, + BM(W1_5260_5320, W1_5180_5240,W1_5170_5230,W1_5745_5825,W1_5500_5700, -1, -1, -1, -1, -1, -1, -1), + BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BM(W1_2412_2412,W1_2437_2442,W1_2462_2462, W2_2472_2472,W1_2417_2432, W1_2447_2457, W2_2467_2467, -1, -1, -1, -1, -1), + BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462, WG2_2472_2472,WG1_2417_2432, WG1_2447_2457, WG2_2467_2467, -1, -1, -1, -1, -1), + BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO}, + + {WOR1_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A, + BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, W1_5500_5700, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BM(W1_2412_2412,W1_2437_2442,W1_2462_2462,W1_2472_2472,W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1, -1, -1), + BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462,WG1_2472_2472,WG1_2417_2432,WG1_2447_2457,WG1_2467_2467, -1, -1, -1, -1, -1), + BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO}, + + {WOR2_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A, + BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, W1_5500_5700, -1, -1, -1, -1, -1, -1, -1), + BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BM(W1_2412_2412,W1_2437_2442,W1_2462_2462,W1_2472_2472,W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1, -1, -1), + BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462,WG1_2472_2472,WG1_2417_2432,WG1_2447_2457,WG1_2467_2467, -1, -1, -1, -1, -1), + BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO}, + + {WOR3_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D, + BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1), + BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BM(W1_2412_2412,W1_2437_2442,W1_2462_2462,W1_2472_2472,W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1), + BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462,WG1_2472_2472,WG1_2417_2432,WG1_2447_2457,WG1_2467_2467,-1, -1, -1, -1, -1), + BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO}, + + {WOR4_WORLD, NO_CTL, DFS_FCC3, PSCAN_WWR, ADHOC_NO_11A, + BM(W2_5260_5320, W2_5180_5240, F2_5745_5805, W2_5825_5825, -1, -1, -1, -1, -1, -1, -1, -1), + BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BM(W1_2412_2412,W1_2437_2442,W1_2462_2462, W1_2417_2432,W1_2447_2457,-1, -1, -1, -1, -1, -1, -1), + BM(WG1_2412_2412,WG1_2437_2442,WG1_2462_2462, WG1_2417_2432,WG1_2447_2457,-1, -1, -1, -1, -1, -1, -1), + BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO}, + + {WOR5_ETSIC, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A, + BM(W1_5260_5320, W2_5180_5240, F6_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W2_2472_2472, W1_2417_2432, W1_2447_2457, W2_2467_2467, -1, -1, -1, -1, -1), + BM(WG1_2412_2412, WG1_2437_2442, WG1_2462_2462, WG1_2472_2472, WG1_2417_2432, WG1_2447_2457, WG1_2467_2467, -1, -1, -1, -1, -1), + BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO}, + + {WOR9_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A, + BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, W1_5500_5700, -1, -1, -1, -1, -1, -1, -1, -1), + BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432, W1_2447_2457, -1, -1, -1, -1, -1, -1, -1), + BM(WG1_2412_2412, WG1_2437_2442, WG1_2462_2462, WG1_2417_2432, WG1_2447_2457, -1, -1, -1, -1, -1, -1, -1), + BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO}, + + {WORA_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A, + BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, W1_5500_5700, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO, + BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472, W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1), + BM(WG1_2412_2412, WG1_2437_2442, WG1_2462_2462, WG1_2472_2472, WG1_2417_2432, WG1_2447_2457, WG1_2467_2467, -1, -1, -1, -1, -1), + BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1), + BMZERO, + BMZERO}, + + {NULL1, NO_CTL, NO_DFS, NO_PSCAN, NO_REQ, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO, + BMZERO}, +}; + +struct cmode { + u16_t mode; + u32_t flags; +}; + +static const struct cmode modes[] = { + { HAL_MODE_TURBO, CHANNEL_ST}, /* TURBO means 11a Static Turbo */ + { HAL_MODE_11A, CHANNEL_A}, + { HAL_MODE_11B, CHANNEL_B}, + { HAL_MODE_11G, CHANNEL_G}, + { HAL_MODE_11G_TURBO, CHANNEL_108G}, + { HAL_MODE_11A_TURBO, CHANNEL_108A}, + { HAL_MODE_11NA, CHANNEL_A_HT40}, + { HAL_MODE_11NA, CHANNEL_A_HT20}, + { HAL_MODE_11NG, CHANNEL_G_HT40}, + { HAL_MODE_11NG, CHANNEL_G_HT20}, +}; + +/* + * Return the Wireless Mode Regulatory Domain based + * on the country code and the wireless mode. + */ +u8_t GetWmRD(u16_t regionCode, u16_t channelFlag, REG_DOMAIN *rd) +{ + s16_t i, found, regDmn; + u64_t flags=NO_REQ; + REG_DMN_PAIR_MAPPING *regPair=NULL; + + for (i=0, found=0; (iregDmn2GHz; + flags = regPair->flags2GHz; + } + else + { + regDmn = regPair->regDmn5GHz; + flags = regPair->flags5GHz; + } + + /* + * We either started with a unitary reg domain or we've found the + * unitary reg domain of the pair + */ + + for (i=0;ipscan &= regPair->pscanMask; + rd->flags = (u32_t)flags; + return TRUE; +} + +/* + * Test to see if the bitmask array is all zeros + */ +u8_t isChanBitMaskZero(u64_t *bitmask) +{ + u16_t i; + + for (i=0; ihpPrivate; + + zmw_declare_for_critical_section(); + + if (!GetWmRD(regionCode, ~ZM_REG_FLAG_CHANNEL_2GHZ, &rd5GHz)) + { + zm_debug_msg1("couldn't find unitary 5GHz reg domain for Region Code ", regionCode); + return; + } + if (!GetWmRD(regionCode, ZM_REG_FLAG_CHANNEL_2GHZ, &rd2GHz)) + { + zm_debug_msg1("couldn't find unitary 2GHz reg domain for Region Code ", regionCode); + return; + } + if (wd->regulationTable.regionCode == regionCode) + { + zm_debug_msg1("current region code is the same with Region Code ", regionCode); + return; + } + else + { + wd->regulationTable.regionCode = regionCode; + } + + next = 0; + + zmw_enter_critical_section(dev); + + for (cm = modes; cm < &modes[N(modes)]; cm++) + { + u16_t c; + u64_t *channelBM=NULL; + REG_DOMAIN *rd=NULL; + REG_DMN_FREQ_BAND *fband=NULL,*freqs=NULL; + + switch (cm->mode) + { + case HAL_MODE_TURBO: + //we don't have turbo mode so we disable it + //zm_debug_msg0("CWY - HAL_MODE_TURBO"); + channelBM = NULL; + //rd = &rd5GHz; + //channelBM = rd->chan11a_turbo; + //freqs = ®Dmn5GhzTurboFreq[0]; + //ctl = rd->conformanceTestLimit | CTL_TURBO; + break; + case HAL_MODE_11A: + if ((hpPriv->OpFlags & 0x1) != 0) + { + rd = &rd5GHz; + channelBM = rd->chan11a; + freqs = ®Dmn5GhzFreq[0]; + c_lo = 4920; //from channel 184 + c_hi = 5825; //to channel 165 + //ctl = rd->conformanceTestLimit; + //zm_debug_msg2("CWY - HAL_MODE_11A, channelBM = 0x", *channelBM); + } + //else + { + //channelBM = NULL; + } + break; + case HAL_MODE_11B: + //Disable 11B mode because it only has difference with 11G in PowerDFS Data, + //and we don't use this now. + //zm_debug_msg0("CWY - HAL_MODE_11B"); + channelBM = NULL; + //rd = &rd2GHz; + //channelBM = rd->chan11b; + //freqs = ®Dmn2GhzFreq[0]; + //ctl = rd->conformanceTestLimit | CTL_11B; + //zm_debug_msg2("CWY - HAL_MODE_11B, channelBM = 0x", *channelBM); + break; + case HAL_MODE_11G: + if ((hpPriv->OpFlags & 0x2) != 0) + { + rd = &rd2GHz; + channelBM = rd->chan11g; + freqs = ®Dmn2Ghz11gFreq[0]; + c_lo = 2412; //from channel 1 + //c_hi = 2462; //to channel 11 + c_hi = 2472; //to channel 13 + //ctl = rd->conformanceTestLimit | CTL_11G; + //zm_debug_msg2("CWY - HAL_MODE_11G, channelBM = 0x", *channelBM); + } + //else + { + //channelBM = NULL; + } + break; + case HAL_MODE_11G_TURBO: + //we don't have turbo mode so we disable it + //zm_debug_msg0("CWY - HAL_MODE_11G_TURBO"); + channelBM = NULL; + //rd = &rd2GHz; + //channelBM = rd->chan11g_turbo; + //freqs = ®Dmn2Ghz11gTurboFreq[0]; + //ctl = rd->conformanceTestLimit | CTL_108G; + break; + case HAL_MODE_11A_TURBO: + //we don't have turbo mode so we disable it + //zm_debug_msg0("CWY - HAL_MODE_11A_TURBO"); + channelBM = NULL; + //rd = &rd5GHz; + //channelBM = rd->chan11a_dyn_turbo; + //freqs = ®Dmn5GhzTurboFreq[0]; + //ctl = rd->conformanceTestLimit | CTL_108G; + break; + default: + zm_debug_msg1("Unkonwn HAL mode ", cm->mode); + continue; + } + if (channelBM == NULL) + { + //zm_debug_msg0("CWY - channelBM is NULL"); + continue; + } + if (isChanBitMaskZero(channelBM)) + { + //zm_debug_msg0("CWY - BitMask is Zero"); + continue; + } + + // RAY:Is it ok?? + if (freqs == NULL ) + { + continue; + } + + for (b=0;b<64*BMLEN; b++) + { + if (IS_BIT_SET(b,channelBM)) + { + fband = &freqs[b]; + + //zm_debug_msg1("CWY - lowChannel = ", fband->lowChannel); + //zm_debug_msg1("CWY - highChannel = ", fband->highChannel); + //zm_debug_msg1("CWY - channelSep = ", fband->channelSep); + for (c=fband->lowChannel; c <= fband->highChannel; + c += fband->channelSep) + { + ZM_HAL_CHANNEL icv; + + //Disable all DFS channel + if ((hpPriv->disableDfsCh==0) || (!(fband->useDfs & rd->dfsMask))) + { + if( fband->channelBW < 20 ) + { + /**************************************************************/ + /* */ + /* Temporary discard channel that BW < 20MHz (5 or 10MHz) */ + /* Our architecture does not implemnt it !!! */ + /* */ + /**************************************************************/ + continue; + } + if ((c >= c_lo) && (c <= c_hi)) + { + icv.channel = c; + icv.channelFlags = cm->flags; + icv.maxRegTxPower = fband->powerDfs; + if (fband->usePassScan & rd->pscan) + icv.channelFlags |= ZM_REG_FLAG_CHANNEL_PASSIVE; + else + icv.channelFlags &= ~ZM_REG_FLAG_CHANNEL_PASSIVE; + if (fband->useDfs & rd->dfsMask) + icv.privFlags = ZM_REG_FLAG_CHANNEL_DFS; + else + icv.privFlags = 0; + + /* For now disable radar for FCC3 */ + if (fband->useDfs & rd->dfsMask & DFS_FCC3) + { + icv.privFlags &= ~ZM_REG_FLAG_CHANNEL_DFS; + icv.privFlags |= ZM_REG_FLAG_CHANNEL_DFS_CLEAR; + } + + if(rd->flags & LIMIT_FRAME_4MS) + icv.privFlags |= ZM_REG_FLAG_CHANNEL_DFS_CLEAR; + + icv.minTxPower = 0; + icv.maxTxPower = 0; + + zm_assert(next < 60); + + wd->regulationTable.allowChannel[next++] = icv; + } + } + } + } + } + } + wd->regulationTable.allowChannelCnt = next; + + #if 0 + { + /* debug print */ + u32_t i; + DbgPrint("\n-------------------------------------------\n"); + DbgPrint("zfHpGetRegulationTable print all channel info regincode = 0x%x\n", wd->regulationTable.regionCode); + DbgPrint("index channel channelFlags maxRegTxPower privFlags useDFS\n"); + + for (i=0; iregulationTable.allowChannelCnt; i++) + { + DbgPrint("%02d %d %04x %02d %x %x\n", + i, + wd->regulationTable.allowChannel[i].channel, + wd->regulationTable.allowChannel[i].channelFlags, + wd->regulationTable.allowChannel[i].maxRegTxPower, + wd->regulationTable.allowChannel[i].privFlags, + wd->regulationTable.allowChannel[i].privFlags & ZM_REG_FLAG_CHANNEL_DFS); + } + } + #endif + + zmw_leave_critical_section(dev); +} + +void zfHpGetRegulationTablefromRegionCode(zdev_t* dev, u16_t regionCode) +{ + u16_t c_lo = 2000, c_hi = 6000; //default channel is all enable + u8_t isoName[3] = {'N', 'A', 0}; + + zfCoreSetIsoName(dev, isoName); + + zfHpGetRegulationTable(dev, regionCode, c_lo, c_hi); +} + +void zfHpGetRegulationTablefromCountry(zdev_t* dev, u16_t CountryCode) +{ + u16_t i; + u16_t c_lo = 2000, c_hi = 6000; //default channel is all enable + u16_t RegDomain; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + for (i = 0; i < N(allCountries); i++) + { + if (CountryCode == allCountries[i].countryCode) + { + RegDomain = allCountries[i].regDmnEnum; + + // read the ACU country code from EEPROM + zfCoreSetIsoName(dev, (u8_t*)allCountries[i].isoName); + + //zm_debug_msg_s("CWY - Country Name = ", allCountries[i].name); + + if (wd->regulationTable.regionCode != RegDomain) + { + //zm_debug_msg0("CWY - Change regulatory table"); + + zfHpGetRegulationTable(dev, RegDomain, c_lo, c_hi); + } + return; + } + } + zm_debug_msg1("Invalid CountryCode = ", CountryCode); +} + +u8_t zfHpGetRegulationTablefromISO(zdev_t* dev, u8_t *countryInfo, u8_t length) +{ + u16_t i; + u16_t RegDomain; + u16_t c_lo = 2000, c_hi = 6000; //default channel is all enable + //u8_t strLen = 2; + + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + if (countryInfo[4] != 0x20) + { // with (I)ndoor/(O)utdoor info + //strLen = 3; + } + //zm_debug_msg_s("Desired iso name = ", isoName); + for (i = 0; i < N(allCountries); i++) + { + //zm_debug_msg_s("Current iso name = ", allCountries[i].isoName); + if (zfMemoryIsEqual((u8_t *)allCountries[i].isoName, (u8_t *)&countryInfo[2], length-1)) + { + //DbgPrint("Set current iso name = %s\n", allCountries[i].isoName); + //zm_debug_msg0("iso name hit!!"); + + RegDomain = allCountries[i].regDmnEnum; + + if (wd->regulationTable.regionCode != RegDomain) + { + zfHpGetRegulationTable(dev, RegDomain, c_lo, c_hi); + } + + //while (index < (countryInfo[1]+2)) + //{ + // if (countryInfo[index] <= 14) + // { + // /* calculate 2.4GHz low boundary channel frequency */ + // ch = countryInfo[index]; + // if ( ch == 14 ) + // c_lo = ZM_CH_G_14; + // else + // c_lo = ZM_CH_G_1 + (ch - 1) * 5; + // /* calculate 2.4GHz high boundary channel frequency */ + // ch = countryInfo[index] + countryInfo[index + 1] - 1; + // if ( ch == 14 ) + // c_hi = ZM_CH_G_14; + // else + // c_hi = ZM_CH_G_1 + (ch - 1) * 5; + // } + // else + // { + // /* calculate 5GHz low boundary channel frequency */ + // ch = countryInfo[index]; + // if ( (ch >= 184)&&(ch <= 196) ) + // c_lo = 4000 + ch*5; + // else + // c_lo = 5000 + ch*5; + // /* calculate 5GHz high boundary channel frequency */ + // ch = countryInfo[index] + countryInfo[index + 1] - 1; + // if ( (ch >= 184)&&(ch <= 196) ) + // c_hi = 4000 + ch*5; + // else + // c_hi = 5000 + ch*5; + // } + // + // zfHpGetRegulationTable(dev, RegDomain, c_lo, c_hi); + // + // index+=3; + //} + + return 0; + } + } + //zm_debug_msg_s("Invalid iso name = ", &countryInfo[2]); + return 1; +} + +const char* zfHpGetisoNamefromregionCode(zdev_t* dev, u16_t regionCode) +{ + u16_t i; + + for (i = 0; i < N(allCountries); i++) + { + if (allCountries[i].regDmnEnum == regionCode) + { + return allCountries[i].isoName; + } + } + /* no matching item, return default */ + return allCountries[0].isoName; +} + +u16_t zfHpGetRegionCodeFromIsoName(zdev_t* dev, u8_t *countryIsoName) +{ + u16_t i; + u16_t regionCode; + + /* if no matching item, return default */ + regionCode = DEF_REGDMN; + + for (i = 0; i < N(allCountries); i++) + { + if (zfMemoryIsEqual((u8_t *)allCountries[i].isoName, countryIsoName, 2)) + { + regionCode = allCountries[i].regDmnEnum; + break; + } + } + + return regionCode; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfHpDeleteAllowChannel */ +/* Delete Allow Channel. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* freq : frequency */ +/* */ +/* OUTPUTS */ +/* 0 : success */ +/* other : fail */ +/* */ +/* AUTHOR */ +/* Chao-Wen Yang ZyDAS Technology Corporation 2007.3 */ +/* */ +/************************************************************************/ +u16_t zfHpDeleteAllowChannel(zdev_t* dev, u16_t freq) +{ + u16_t i, bandIndex = 0; + u16_t dfs5GBand[][2] = {{5150, 5240}, {5260, 5350}, {5450, 5700}, {5725, 5825}}; + + zmw_get_wlan_dev(dev); + /* Find which band does this frequency belong */ + for (i = 0; i < 4; i++) + { + if ((freq >= dfs5GBand[i][0]) && (freq <= dfs5GBand[i][1])) + bandIndex = i + 1; + } + + if (bandIndex == 0) + { + /* 2.4G, don't care */ + return 0; + } + else + { + bandIndex--; + } + /* Set all channels in this band to passive scan */ + for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) + { + if ((wd->regulationTable.allowChannel[i].channel >= dfs5GBand[bandIndex][0]) && + (wd->regulationTable.allowChannel[i].channel <= dfs5GBand[bandIndex][1])) + { + /* if channel is not passive, set it to be passive and mark it */ + if ((wd->regulationTable.allowChannel[i].channelFlags & + ZM_REG_FLAG_CHANNEL_PASSIVE) == 0) + { + wd->regulationTable.allowChannel[i].channelFlags |= + (ZM_REG_FLAG_CHANNEL_PASSIVE | ZM_REG_FLAG_CHANNEL_CSA); + } + } + } + + return 0; +} + +u16_t zfHpAddAllowChannel(zdev_t* dev, u16_t freq) +{ + u16_t i, j, arrayIndex; + + zmw_get_wlan_dev(dev); + + for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) + { + if (wd->regulationTable.allowChannel[i].channel == freq) + break; + } + + if ( i == wd->regulationTable.allowChannelCnt) + { + for (j = 0; j < wd->regulationTable.allowChannelCnt; j++) + { + if (wd->regulationTable.allowChannel[j].channel > freq) + break; + } + + //zm_debug_msg1("CWY - add frequency = ", freq); + //zm_debug_msg1("CWY - channel array index = ", j); + + arrayIndex = j; + + if (arrayIndex < wd->regulationTable.allowChannelCnt) + { + for (j = wd->regulationTable.allowChannelCnt; j > arrayIndex; j--) + wd->regulationTable.allowChannel[j] = wd->regulationTable.allowChannel[j - 1]; + } + wd->regulationTable.allowChannel[arrayIndex].channel = freq; + + wd->regulationTable.allowChannelCnt++; + } + + return 0; +} + +u16_t zfHpIsDfsChannelNCS(zdev_t* dev, u16_t freq) +{ + u8_t flag = ZM_REG_FLAG_CHANNEL_DFS; + u16_t i; + zmw_get_wlan_dev(dev); + + for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) + { + //DbgPrint("DFS:freq=%d, chan=%d", freq, wd->regulationTable.allowChannel[i].channel); + if (wd->regulationTable.allowChannel[i].channel == freq) + { + flag = wd->regulationTable.allowChannel[i].privFlags; + break; + } + } + + return (flag & (ZM_REG_FLAG_CHANNEL_DFS|ZM_REG_FLAG_CHANNEL_DFS_CLEAR)); +} + +u16_t zfHpIsDfsChannel(zdev_t* dev, u16_t freq) +{ + u8_t flag = ZM_REG_FLAG_CHANNEL_DFS; + u16_t i; + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) + { + //DbgPrint("DFS:freq=%d, chan=%d", freq, wd->regulationTable.allowChannel[i].channel); + if (wd->regulationTable.allowChannel[i].channel == freq) + { + flag = wd->regulationTable.allowChannel[i].privFlags; + break; + } + } + + zmw_leave_critical_section(dev); + + return (flag & (ZM_REG_FLAG_CHANNEL_DFS|ZM_REG_FLAG_CHANNEL_DFS_CLEAR)); +} + +u16_t zfHpIsAllowedChannel(zdev_t* dev, u16_t freq) +{ + u16_t i; + zmw_get_wlan_dev(dev); + + for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) + { + if (wd->regulationTable.allowChannel[i].channel == freq) + { + return 1; + } + } + + return 0; +} + +u16_t zfHpFindFirstNonDfsChannel(zdev_t* dev, u16_t aBand) +{ + u16_t chan = 2412; + u16_t i; + zmw_get_wlan_dev(dev); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) + { + if ((wd->regulationTable.allowChannel[i].privFlags & ZM_REG_FLAG_CHANNEL_DFS) != 0) + { + if (aBand) + { + if (wd->regulationTable.allowChannel[i].channel > 3000) + { + chan = wd->regulationTable.allowChannel[i].channel; + break; + } + } + else + { + if (wd->regulationTable.allowChannel[i].channel < 3000) + { + chan = wd->regulationTable.allowChannel[i].channel; + break; + } + } + } + } + + zmw_leave_critical_section(dev); + + return chan; +} + + +/* porting from ACU */ +/* save RegulatoryDomain in hpriv */ +u8_t zfHpGetRegulatoryDomain(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + switch (wd->regulationTable.regionCode) + { + case NO_ENUMRD: + return 0; + break; + case FCC1_FCCA: + case FCC1_WORLD: + case FCC4_FCCA: + case FCC5_FCCA: + case FCC2_WORLD: + case FCC2_ETSIC: + case FCC3_FCCA: + case FCC3_WORLD: + case FCC1: + case FCC2: + case FCC3: + case FCC4: + case FCC5: + case FCCA: + return 0x10;//WG_AMERICAS DOT11_REG_DOMAIN_FCC United States + break; + + case FCC2_FCCA: + return 0x20;//DOT11_REG_DOMAIN_DOC Canada + break; + + case ETSI1_WORLD: + case ETSI3_ETSIA: + case ETSI2_WORLD: + case ETSI3_WORLD: + case ETSI4_WORLD: + case ETSI4_ETSIC: + case ETSI5_WORLD: + case ETSI6_WORLD: + case ETSI_RESERVED: + case ETSI1: + case ETSI2: + case ETSI3: + case ETSI4: + case ETSI5: + case ETSI6: + case ETSIA: + case ETSIB: + case ETSIC: + return 0x30;//WG_EMEA DOT11_REG_DOMAIN_ETSI Most of Europe + break; + + case MKK1_MKKA: + case MKK1_MKKB: + case MKK2_MKKA: + case MKK1_FCCA: + case MKK1_MKKA1: + case MKK1_MKKA2: + case MKK1_MKKC: + case MKK3_MKKB: + case MKK3_MKKA2: + case MKK3_MKKC: + case MKK4_MKKB: + case MKK4_MKKA2: + case MKK4_MKKC: + case MKK5_MKKB: + case MKK5_MKKA2: + case MKK5_MKKC: + case MKK6_MKKB: + case MKK6_MKKA2: + case MKK6_MKKC: + case MKK7_MKKB: + case MKK7_MKKA: + case MKK7_MKKC: + case MKK8_MKKB: + case MKK8_MKKA2: + case MKK8_MKKC: + case MKK6_MKKA1: + case MKK6_FCCA: + case MKK7_MKKA1: + case MKK7_FCCA: + case MKK9_FCCA: + case MKK9_MKKA1: + case MKK9_MKKC: + case MKK9_MKKA2: + case MKK10_FCCA: + case MKK10_MKKA1: + case MKK10_MKKC: + case MKK10_MKKA2: + case MKK11_MKKA: + case MKK11_FCCA: + case MKK11_MKKA1: + case MKK11_MKKC: + case MKK11_MKKA2: + case MKK12_MKKA: + case MKK12_FCCA: + case MKK12_MKKA1: + case MKK12_MKKC: + case MKK12_MKKA2: + case MKK3_MKKA: + case MKK3_MKKA1: + case MKK3_FCCA: + case MKK4_MKKA: + case MKK4_MKKA1: + case MKK4_FCCA: + case MKK9_MKKA: + case MKK10_MKKA: + case MKK1: + case MKK2: + case MKK3: + case MKK4: + case MKK5: + case MKK6: + case MKK7: + case MKK8: + case MKK9: + case MKK10: + case MKK11: + case MKK12: + case MKKA: + case MKKC: + return 0x40;//WG_JAPAN DOT11_REG_DOMAIN_MKK Japan + break; + + default: + break; + } + return 0xFF;// Didn't input RegDmn by mean to distinguish by customer + +} + + +void zfHpDisableDfsChannel(zdev_t* dev, u8_t disableFlag) +{ + zmw_get_wlan_dev(dev); + + struct zsHpPriv* hpPriv=wd->hpPrivate; + hpPriv->disableDfsCh = disableFlag; + return; +} --- linux-2.6.28.orig/drivers/staging/otus/hal/hpfwu_BA.c +++ linux-2.6.28/drivers/staging/otus/hal/hpfwu_BA.c @@ -0,0 +1,874 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "cprecomp.h" + +const u32_t zcFwImage[] = { +0x0009000B, 0x4F222FE6, 0xDE917FFC, 0xE114D791, +0x1E13D491, 0x1E4C470B, 0x0009B017, 0x95C2E600, +0xC84060E2, 0x2F028F03, 0x8FF93652, 0xD48B7601, +0x4E0BDE8B, 0xD48B0009, 0x00094E0B, 0x4E0BD48A, +0x7F040009, 0xA0474F26, 0x4F226EF6, 0x410BD187, +0xD4870009, 0x0009440B, 0x450BD586, 0xD7860009, +0x611DE1FF, 0xD1852712, 0x6012E2FF, 0xCB01D484, +0x71DC2102, 0x71042122, 0x2122E501, 0xD5812452, +0xD2819792, 0xE7002572, 0xD481D180, 0x2270D681, +0x2172E201, 0x26202470, 0xE4FFD67F, 0xE6002641, +0xE104D57E, 0x6063666D, 0x626D7601, 0x32124000, +0x05458FF8, 0xE501D27A, 0xD17A2250, 0xD57BD47A, +0xE700E600, 0x25722470, 0x11622162, 0x11691166, +0x4F26116A, 0x116E000B, 0xD1757FC4, 0x2F12D875, +0xD476D175, 0xD577D676, 0x1F87D777, 0xD97778FC, +0x1F1BD277, 0x1F417104, 0x1F647404, 0x1F887604, +0x71F41F1C, 0x1F42E8C8, 0x1F651F53, 0x1F991F76, +0x1F1D1F2A, 0xDD6F688C, 0xDA70DE6F, 0xDC71DB70, +0x00094A0B, 0x00094B0B, 0x00094C0B, 0x6010D15E, +0x8B0F8801, 0xE950D15D, 0x49186212, 0x8B073296, +0x56FAD159, 0x2120E200, 0xCB016062, 0x2602A002, +0x21227201, 0x880160D2, 0xD1638907, 0x32866212, +0xD1628903, 0x88016010, 0x64E28BDA, 0x52F751F8, +0x55E12142, 0x2252D15E, 0x661254FB, 0x246259FC, +0x29725711, 0x880160D2, 0x66E28B53, 0x362052E1, +0x6061894C, 0x8801C90F, 0xD1568B48, 0x36206212, +0xA0438903, 0x27102162, 0xD5530FA0, 0x6651E710, +0x626D7601, 0x8F3C3273, 0x65F22561, 0x695251F2, +0x54F359F1, 0x679252F4, 0x61426512, 0x56F66922, +0x642252F5, 0xCB206062, 0xE6002602, 0x76011F1E, +0x626DE110, 0x32134118, 0x51FE8FF8, 0x267256F1, +0x56F457F2, 0x55F32752, 0x251257F5, 0x27422692, +0x51F969E2, 0x2192D43D, 0xE90161F2, 0x2192440B, +0x491865F2, 0xD9382592, 0xE200D539, 0x62512921, +0x720154FD, 0x622D2521, 0x2422A003, 0xE200D932, +0xE9012921, 0x2D92D12C, 0x26686612, 0xAF6F8B01, +0xD6300009, 0x0009460B, 0xE700D128, 0x2170AF68, +0x001C001C, 0x00200F7C, 0x0000B38E, 0x0020322C, +0x0020145E, 0x00203238, 0x00203250, 0x0020141C, +0x0020151C, 0x00200FA0, 0x001C3510, 0x001C3648, +0x001E212C, 0x00203188, 0x00202D24, 0x00203190, +0x0020319C, 0x002031A8, 0x002031B8, 0x002031BC, +0x002031B0, 0x00117708, 0x002031B1, 0x002031B4, +0x001C3D30, 0x00117718, 0x00117734, 0x001C3B9C, +0x001C3704, 0x001C3D98, 0x001C3500, 0x001C3D00, +0x001C36F8, 0x001C1028, 0x00202D98, 0x00201328, +0x00202C04, 0x00201E18, 0x002034BC, 0x002031BA, +0x00202D90, 0x002031CC, 0x002031D0, 0x00201276, +0x002031D2, 0x00201FD0, 0x2FB62F96, 0x2FD62FC6, +0x4F222FE6, 0xDE947F8C, 0x61E0E024, 0x0F14D493, +0x710161E3, 0xD7926210, 0x470BE028, 0xD5910F24, +0x0009450B, 0x6D032008, 0x1F0B8F11, 0xD48FDC8E, +0xDD8F67C0, 0x657C4D0B, 0xDD8FD18E, 0x6B9C6910, +0x420862B3, 0x32B84208, 0x3D2C4208, 0xE0281FDB, +0xE58004FC, 0x604C66E2, 0x3050655C, 0x2D628F13, +0x01FCE024, 0x641CE500, 0x625DDE84, 0x8B013243, +0x0009A33D, 0x6753655D, 0x607037EC, 0x39DC6953, +0xAFF27501, 0x20088094, 0xE0248B13, 0xE50001FC, +0xA009DE7A, 0x655D641C, 0x32EC6253, 0x6C536B22, +0x3CDC67B2, 0x75041C71, 0x3243625D, 0xA31E8BF3, +0x88012D10, 0xE0248B16, 0xE40001FC, 0x671C2D40, +0x624DDE6E, 0x8B013273, 0x0009A311, 0x6CE3644D, +0x7C046943, 0x39EC6B43, 0x65923BCC, 0x74086DB2, +0x25D2AFEF, 0x8B198804, 0x01FCE024, 0x2D70E700, +0x1FD86D1C, 0x627DDE61, 0x8B0132D3, 0x0009A2F7, +0x6B73677D, 0x3BEC61E3, 0x710464B2, 0x3C1C6C73, +0x694265C2, 0x29597708, 0x2492AFED, 0x8B188805, +0x01FCE024, 0x2D40E400, 0xDE54671C, 0x3273624D, +0xA2DC8B01, 0x644D0009, 0x6BE36D43, 0x65D23DEC, +0x61437B04, 0x6C1231BC, 0x74086952, 0xAFED29CB, +0x88312592, 0xDE4A8B20, 0x65E6DB4A, 0x61E6DC4A, +0x67E2D94A, 0x62E27E04, 0x1FEC7EE8, 0x7E0464E2, +0x6EE21FED, 0x5BFD2BE0, 0x60B27B04, 0xC9011FBE, +0x6BB22C00, 0x29B04B09, 0xDC412F26, 0x66134C0B, +0xE2007F04, 0x2D20A2AB, 0x8B218830, 0xD939DE38, +0xE06465E6, 0x720462E3, 0x672666E2, 0x6E23DC36, +0x62227EE8, 0x6BE261E6, 0x29B01FEF, 0x7E040F16, +0xC90160E2, 0x6EE22C00, 0x4E09DC30, 0x2F262CE0, +0xD130E068, 0x04FE410B, 0xE2007F04, 0x2D20A287, +0x8B058833, 0x4E0BDE2C, 0xE1000009, 0x2D10A27F, +0x89018828, 0x0009A106, 0xE143DE20, 0xE04062E1, +0x3217622D, 0x0FE68F04, 0x6023E240, 0x262106FE, +0x8B013217, 0x0009A0EF, 0x02FEE040, 0x8521E401, +0x8B013046, 0x0009A0E7, 0xE501E040, 0x2D5007FE, +0x6471B265, 0x09FEE040, 0x6291E143, 0x652DE068, +0x8D6B3517, 0xE6400F56, 0x8B273563, 0xE048E600, +0xE11A0F65, 0x72C0A031, 0x00117800, 0x00203254, +0x0020145E, 0x00202588, 0x002031A2, 0x00203258, +0x002014AA, 0x002031A1, 0x00202DC8, 0x00117804, +0x00117810, 0x0020319D, 0x0020319E, 0x0020319F, +0x00200C2C, 0x00200C80, 0x00200C7C, 0x41216153, +0x41214121, 0x41214121, 0x45214521, 0x60534521, +0x6603C903, 0x0F65E048, 0xE0077118, 0xE0442209, +0x641D0F25, 0x65F3E04C, 0x0F46B28C, 0x04FDE048, +0x0BFDE044, 0x61BD674D, 0x41084708, 0x0F16E050, +0xD29B6073, 0x420B09FE, 0x6C07E00F, 0x607329C9, +0xE0400F96, 0x65F30EFE, 0x6D0D85E2, 0x01FEE050, +0x60D3420B, 0x6073290B, 0xE04C0F96, 0x04FEB251, +0x06FEE040, 0x6261E068, 0x0F56652D, 0x3563E640, +0xE000894E, 0x602381F8, 0x4008C903, 0x6B034000, +0xE0546103, 0xE0580FB6, 0xECFFDD85, 0x6CCC0FF6, +0x0FD6E06C, 0x4D0B60C3, 0x42216253, 0x42214221, +0x64234221, 0x324C4200, 0xE05C6E07, 0x45214200, +0xE0400FE6, 0x0BFE4521, 0xC9036053, 0x30FC4008, +0x6D037B06, 0x85F81F05, 0x6C2D1FB7, 0x1FC66E03, +0x0FC6E060, 0x05FEE058, 0x64C3B22C, 0x33FCE354, +0x563262D2, 0x22696132, 0x67B42D22, 0x490B5936, +0x220B607C, 0x05FEE058, 0x64C32D22, 0x7E01B201, +0xE70662ED, 0x8FE33273, 0xE0407C01, 0x626106FE, +0x06FEE040, 0x85614200, 0x302C760C, 0x6103701B, +0x64F3E500, 0x7501E704, 0x6B5D6966, 0x24923B73, +0x74048FF9, 0xB1E465F3, 0xE040641D, 0xB1A306FE, +0xA17C6461, 0xD4570009, 0xE201D757, 0x2D20470B, +0x0009A175, 0x8B078829, 0xEC00DE54, 0x61E22DC0, +0x641DB175, 0x0009A16B, 0x622CE281, 0x8B013020, +0x0009A0B6, 0x06FCE028, 0xE682626C, 0x3260666C, +0x56FB8B20, 0x2610E124, 0x5217D149, 0x52181621, +0x52191622, 0x521A1623, 0x551B1624, 0x1655E200, +0x1656551C, 0x1657551D, 0x1658551E, 0x1659551F, +0x11281127, 0x112A1129, 0x112C112B, 0x112E112D, +0x112FA13D, 0x666CE683, 0x8B0B3260, 0xD63752FB, +0x2250E500, 0xD2376562, 0x22527604, 0xD6366262, +0x2620A12D, 0x666CE690, 0x8B033260, 0x0009B1C7, +0x0009A011, 0x666CE691, 0x8B103260, 0x6252D52B, +0x2228622C, 0xD22D8904, 0x0009420B, 0x0009A003, +0x420BD22B, 0x56FB0009, 0xA110E200, 0xE6B02620, +0x3260666C, 0xE0248B34, 0xE07002FC, 0x0F16612C, +0xEB04EC00, 0x01FEE070, 0x321362CD, 0xA0FE8B01, +0xD21A0009, 0x6DC36CCD, 0x72043D2C, 0x312C61C3, +0x6D126ED2, 0xD114D41B, 0x0009410B, 0x410BD11A, +0xD41A64E3, 0x420BD210, 0xD2170009, 0x64D3420B, +0xD60DD417, 0x0009460B, 0x61E3E600, 0x316C666D, +0x626D7601, 0x21D032B3, 0x4D198FF7, 0x7C08AFD2, +0xD211D410, 0xD4116542, 0x0009420B, 0x0009A0CF, +0x00202C80, 0x00203278, 0x0020145E, 0x00117804, +0x00202D2C, 0x00203188, 0x0020319C, 0x00200CBA, +0x00200CE0, 0x00203290, 0x002014A2, 0x002032A4, +0x002032AC, 0x00117800, 0x002014AA, 0x002032B0, +0xD5B5D1B4, 0x6252E040, 0x75046612, 0x2162362C, +0x56116256, 0x1161362C, 0x62526653, 0x76085512, +0x1152352C, 0x55136262, 0x352C76EC, 0x65631153, +0x56146262, 0x362C7510, 0x66531164, 0x55156252, +0x352C7610, 0x62621155, 0x362C5616, 0xD6A31166, +0x55176262, 0x352C7604, 0x62661157, 0x352C5518, +0x65631158, 0x56196262, 0x362C7504, 0x62561169, +0x362C561A, 0x6256116A, 0x362C561B, 0x6653116B, +0x551C6252, 0x352C7604, 0x6266115C, 0x352C551D, +0x6263115D, 0x551E6662, 0x356C7204, 0x6622115E, +0xD58F521F, 0x112F326C, 0x061E6252, 0x362C7594, +0xE0440166, 0x62526653, 0x7644051E, 0x0156352C, +0x6262E048, 0x362C061E, 0xD6860166, 0x6262E054, +0x4229051E, 0x0156352C, 0x62627604, 0x061EE058, +0x362C4229, 0x56FB0166, 0x2620E238, 0x021EE044, +0x1621E048, 0x16226212, 0x16235211, 0xE2005512, +0x55151654, 0x55131655, 0x55161656, 0x051E1657, +0x1658E040, 0xE050051E, 0x55141659, 0x051E165A, +0x165BE04C, 0xE054051E, 0x051E165C, 0x165DE058, +0xE044051E, 0x0126165E, 0x2122E048, 0x11221121, +0x11231125, 0x01261126, 0x0126E040, 0x1124E050, +0xE04C0126, 0xE0540126, 0xE0580126, 0x7F740126, +0x6EF64F26, 0x6CF66DF6, 0x000B6BF6, 0x4F2269F6, +0xE240614D, 0x89143123, 0x3127E21F, 0x8B09D75A, +0xD45A614D, 0xE00171E0, 0x5671440B, 0x26596507, +0x1761A007, 0xE001D455, 0x6672440B, 0x26596507, +0x4F262762, 0x0009000B, 0x614D4F22, 0x3123E240, +0xE21F8912, 0xD74C3127, 0x614D8B08, 0x5671D24B, +0x420B71E0, 0x260BE001, 0x1761A006, 0x6672D247, +0xE001420B, 0x2762260B, 0x000B4F26, 0xE6400009, +0x46284618, 0x6252D542, 0x89FC2268, 0x0009000B, +0x4618E680, 0xD53E4628, 0x22686252, 0x000B89FC, +0xA0010009, 0x7201E200, 0x8BFC3242, 0x0009000B, +0x4618E680, 0xD5374628, 0x22686252, 0x000B8BFC, +0x2FE60009, 0x7FFC4F22, 0xBFF16E53, 0x61E22F42, +0xE280D631, 0x54E11615, 0x16464218, 0x422855E2, +0x57E31657, 0x16786EF2, 0x26E22E2B, 0x4F267F04, +0x6EF6AFCE, 0x2FD62FC6, 0x4F222FE6, 0x6C53DD26, +0x6E43BFD6, 0x2DE2BFBB, 0x0009BFD2, 0x2C1251D5, +0x1C4154D6, 0x1C5255D7, 0x1C6356D8, 0x6EF64F26, +0x000B6DF6, 0x61636CF6, 0xA004E600, 0x62564109, +0x24227601, 0x36127404, 0x000B8BF9, 0x4F220009, +0xD117D416, 0x0009410B, 0xD417D216, 0xE5056022, +0x2202CB20, 0xD5152452, 0x450BE700, 0xD7142472, +0x0009470B, 0xE601D113, 0x2162D213, 0x4F264618, +0x2262000B, 0x00202D2C, 0x001C36A0, 0x001C3CA0, +0x001C36F4, 0x001C3B88, 0x001C3704, 0x00202C80, +0x001C373C, 0x001C3700, 0x001C370C, 0x002032C4, +0x0020145E, 0x001C3500, 0x001D4004, 0x002014D4, +0x00200FA0, 0x001E212C, 0x001C3D30, 0x0009A1A9, +0x2FE62FD6, 0xDD8F4F22, 0xA0049EA7, 0xD48E0009, +0x420BD28E, 0x62D265D2, 0x8BF822E8, 0x0009A004, +0xD28AD48B, 0x55D1420B, 0x22E852D1, 0xA0048BF8, +0xD4880009, 0x420BD285, 0x52D255D2, 0x8BF822E8, +0x0009A004, 0xD281D484, 0x55D3420B, 0x22E852D3, +0xA0048BF8, 0xD4810009, 0x420BD27C, 0x52D455D4, +0x8BF822E8, 0x6EF64F26, 0x6DF6000B, 0x2FD62FC6, +0x4F222FE6, 0x6E636D73, 0x6C53B018, 0x64C357F4, +0xB05465E3, 0xB06A66D3, 0xB09A0009, 0xB09E0009, +0xB0A20009, 0xB0BE0009, 0xB0C10009, 0xB1240009, +0x4F260009, 0x6DF66EF6, 0x6CF6A023, 0x3412D16C, +0xD66C0529, 0x2650D76C, 0x2742000B, 0x0009A014, +0x2FD62FC6, 0x4F222FE6, 0x6E636D73, 0x6C53BFEE, +0x64C357F4, 0xB02A65E3, 0xB10666D3, 0x4F260009, +0x6DF66EF6, 0x6CF6A005, 0xE603D260, 0x000B4618, +0xD25E2262, 0x000BE600, 0x4F222262, 0xE40ABF7E, +0x0009BF7E, 0xE104D25A, 0xE5004118, 0x2212E40A, +0x2252BF74, 0x6072D757, 0x4F26CB20, 0x2702000B, +0xD1554F22, 0xE400410B, 0x452BD554, 0x2FE64F26, +0x6E63D153, 0x44186612, 0x45289210, 0x26294408, +0x44084500, 0x4400265B, 0x4708264B, 0x47082162, +0x27EBD14C, 0x000B2172, 0x03F06EF6, 0x2FE61FFF, +0xDE494F22, 0xE40AE101, 0x2E12BF48, 0x726C62E3, +0xE401E100, 0x22122212, 0x22122212, 0x22122212, +0xE7302242, 0xE40AE503, 0x22122212, 0x22122212, +0x22122212, 0x22122212, 0x22122212, 0x22122212, +0x22522272, 0x22122212, 0x22122212, 0x22122212, +0x22122212, 0x121ABF22, 0x2E62E600, 0x000B4F26, +0xD2326EF6, 0xE441E101, 0x000B2212, 0xD1302242, +0xE605D430, 0x000B2162, 0xD52F2462, 0x6050D22F, +0x8B0E8801, 0x6040D42E, 0x8B078801, 0x9626D52D, +0x88016050, 0x96238B0C, 0x0009A00A, 0xA0079621, +0xE6000009, 0x2262D426, 0x88016040, 0xE6048B00, +0xAEF3E40A, 0xD2242262, 0xE40AE601, 0x2262AEEE, +0x2FC62FB6, 0x2FE62FD6, 0xDC204F22, 0x60C2ED00, +0xCB01EB64, 0x60C22C02, 0xA041C901, 0x03C46E03, +0x034003D4, 0x001C3B88, 0x002032C8, 0x002014AA, +0x002032D0, 0x002032D8, 0x002032E0, 0x002032E8, +0x0025E720, 0x002034B8, 0x0020318C, 0x001C5968, +0x001D4004, 0x001C3500, 0x0020124A, 0x00201276, +0x001C5814, 0x001C59D0, 0x001C5830, 0x001C6268, +0x001C59A4, 0x001C639C, 0x0020319E, 0x001C5804, +0x0020319D, 0x0020319F, 0x001C581C, 0x001C5860, +0x89073DB2, 0xE40A60C2, 0xBE9FC901, 0x7D016E03, +0x8BF52EE8, 0x8B033DB2, 0xD23ED43D, 0x0009420B, +0x4F26E40A, 0x6DF66EF6, 0xAE8F6CF6, 0x44116BF6, +0x604B8F01, 0x000B6043, 0x2FB60009, 0x2FD62FC6, +0x4F222FE6, 0xDC347FFC, 0x60C2ED00, 0xCB02EB64, +0x60C22C02, 0xC9022F02, 0x6E03A009, 0x89083DB3, +0xE40A60C2, 0xC9022F02, 0x6E03BE70, 0x2EE87D01, +0x3DB38BF4, 0xD4298B08, 0x7F04D226, 0x6EF64F26, +0x6CF66DF6, 0x6BF6422B, 0x4F267F04, 0x6DF66EF6, +0x000B6CF6, 0xD5226BF6, 0x60525651, 0x000B4628, +0x2FB6306C, 0x2FD62FC6, 0x4F222FE6, 0x4F024F12, +0x6E43BFF1, 0xDC1B6B03, 0xBFECDD1B, 0x30B80009, +0x060A3C05, 0x46094609, 0x3D654601, 0x4209020A, +0x42094209, 0x8BF032E2, 0x4F164F06, 0x6EF64F26, +0x6CF66DF6, 0x6BF6000B, 0x4F222FE6, 0xE102DE0F, +0xE403E500, 0xBFD42E12, 0xE6062E52, 0xE7004618, +0x2E62E403, 0x4F262E72, 0x6EF6AFCB, 0x0009000B, +0x002032F0, 0x0020145E, 0x001C5860, 0x00203308, +0x001C1040, 0xCCCCCCCD, 0x10624DD3, 0x001D4004, +0x2F962F86, 0x2FB62FA6, 0x2FD62FC6, 0x4F222FE6, +0xE5007FD8, 0x6453E110, 0x6C534128, 0x655DEE0A, +0x46086653, 0x4608365C, 0x361C7501, 0x675D6043, +0x60C30F66, 0x37E3ED00, 0x816126C1, 0x81638162, +0x16D316D2, 0x8FEA16D4, 0x68F27404, 0xDAB3D9B2, +0x29821981, 0xD1B259F1, 0x2A921A91, 0x5BF35AF2, +0x5EF55DF4, 0x11A154F6, 0x11B321A2, 0x11D511B2, +0x11E711D4, 0x114911E6, 0x55F71148, 0xEE00DBA9, +0xDDA957F8, 0xD6A952F9, 0x1B5164E3, 0xDBA82B52, +0xEAB8D8A8, 0x2D72E945, 0x6AAC2622, 0x6EED4908, +0x4D086DE3, 0x3DEC61E3, 0x4D084108, 0x3DBC31EC, +0x410860C3, 0x81D12DC1, 0x4108E050, 0x41084008, +0x60C381D2, 0xE500318C, 0x81D334A2, 0x1D131DD2, +0x8D01D494, 0xD4911D54, 0xB08165D3, 0x64ED7E01, +0x8BDC3492, 0xDB94D18D, 0xD28B6812, 0x1B814829, +0x2FD26412, 0x2B92694D, 0xD98A6722, 0x1B734729, +0xD7876822, 0x1BA26A8D, 0xD28C6B72, 0x22B2D586, +0xE0035D72, 0x5E7412D2, 0x12E44018, 0xD6885176, +0x54781216, 0x1248E1FF, 0xD4856792, 0x6852127A, +0x28C1E703, 0x81916952, 0x6A52E050, 0x81A24008, +0x60C36B52, 0x6D5281B3, 0x6E521DD2, 0x62521E63, +0x1264E600, 0x46086563, 0x7501364C, 0x665D2612, +0x8BF83673, 0xE003D471, 0x40186542, 0x674225C1, +0x8171D274, 0xEE006842, 0x69421882, 0x1923E024, +0xE5806A42, 0x6B421AE4, 0x81B266E3, 0xD46D6C42, +0x655C81C3, 0x6D63666D, 0x616D7604, 0x31533D4C, +0x2DE28FF8, 0xD569D268, 0x74042422, 0x7F282452, +0x6EF64F26, 0x6CF66DF6, 0x6AF66BF6, 0x000B69F6, +0x664268F6, 0xC8036061, 0xE5008D04, 0xC9036061, +0x8B038802, 0x65635262, 0x24125124, 0x6053000B, +0x2FE62FD6, 0x7FEC4F22, 0x62536E53, 0x6D43E550, +0x4508E400, 0xE101A001, 0x60435224, 0x81212211, +0x60538123, 0x56E28122, 0x8BF53620, 0x16E4D250, +0xE61464F3, 0x65E3420B, 0xE4FC65E1, 0x2E512549, +0x65F361F1, 0x2F112149, 0xD14954D1, 0xE614410B, +0x607157D1, 0x2701CB01, 0x7F141DE1, 0x6EF64F26, +0x6DF6000B, 0x2FE62FD6, 0x7FEC4F22, 0x66536E53, +0x6D43E5FC, 0x20596061, 0x2601CB01, 0x326052E2, +0x12E48B06, 0x31E051E2, 0x52D18B04, 0x1E22A002, +0x5664AFF0, 0x64F3D236, 0x420BE614, 0x67E165E3, +0x2719E1FC, 0x67F12E71, 0x271954D1, 0x65F3D130, +0x410BE614, 0x52D12F71, 0xCB016021, 0x1DE12201, +0x4F267F14, 0x000B6EF6, 0x2FE66DF6, 0x624C4F22, +0x4208DE1B, 0xA0054200, 0x52523E2C, 0x5624D417, +0x2E62BF8E, 0x52E165E2, 0x8BF63520, 0x2622D61B, +0x000B4F26, 0x2FB66EF6, 0x2FD62FC6, 0x4F222FE6, +0xDB1CDC10, 0x66C252C1, 0x89403620, 0xC9036061, +0x893C8801, 0xDD18DE0B, 0x64E3BF63, 0x85036503, +0x620D66B2, 0x892B3262, 0xBF9BD403, 0xD4130009, +0x00094D0B, 0x0009AFE6, 0x00202D88, 0x00202D90, +0x00202D98, 0x00202DC0, 0x002031A4, 0x002031AC, +0x001000C8, 0x00101680, 0x001E2108, 0x001C3D00, +0x00117880, 0x00117780, 0x00040020, 0x0026C401, +0x00200B26, 0x00203188, 0x0020145E, 0x00203324, +0x64E3BF3E, 0x4D0BD406, 0xAFBB0009, 0xD2050009, +0x4F262262, 0x6DF66EF6, 0x000B6CF6, 0x00006BF6, +0x00203328, 0x001C3D28, 0x2FC62FB6, 0x2FE62FD6, +0x7FFC4F22, 0x6022D22B, 0x8D41C803, 0xDE2A2F01, +0xDB2BDC2A, 0xED01A017, 0xC9036051, 0x89168801, +0xD128D426, 0x0009410B, 0x61035503, 0xC8208551, +0xE0508903, 0x720102BE, 0xD2230B26, 0x420B64E3, +0xD6226513, 0x52C126D2, 0x352065C2, 0xDE208BE4, +0xDB21DD20, 0x52D1DC21, 0x352065D2, 0x60518918, +0x8801C903, 0xD41B8914, 0x460BD616, 0x57030009, +0x8F0437E0, 0xE2016503, 0xAFEC2B20, 0xD4182C52, +0x420BD218, 0xD6110009, 0x4118E101, 0x2612AFE3, +0xC80460F1, 0xD2148907, 0x4F267F04, 0x6DF66EF6, +0x422B6CF6, 0x7F046BF6, 0x6EF64F26, 0x6CF66DF6, +0x6BF6000B, 0x001E2100, 0x00202D98, 0x00202D90, +0x00202D2C, 0x00201162, 0x002011E4, 0x001C3D30, +0x00117880, 0x00202D88, 0x002031A8, 0x002031A4, +0x00202DC0, 0x00201180, 0x00200308, 0xE601D203, +0x1265D503, 0x000B2252, 0x00001266, 0x001C1010, +0x0000C34F, 0x0009000B, 0x2FD62FC6, 0x4F222FE6, +0x6D436C53, 0xEE00A004, 0x7E0164D4, 0x644CBFF2, +0x8BF93EC2, 0x6EF64F26, 0x000B6DF6, 0xE5006CF6, +0x6643A002, 0x76017501, 0x22286260, 0xAFE38BFA, +0x2FE60009, 0x75076253, 0xE1086753, 0x6043EE0A, +0x4409C90F, 0x650330E2, 0x8D014409, 0xE630E637, +0x4110365C, 0x8FF22760, 0xE00077FF, 0x000B8028, +0x000B6EF6, 0x000BE000, 0x2FE6E000, 0x7FEC4F22, +0x6E436253, 0xBFDC65F3, 0xBFD06423, 0xBFCE64E3, +0xD40364F3, 0x0009BFCB, 0x4F267F14, 0x6EF6000B, +0x0020332C, 0xE4FDD29A, 0xD79A6122, 0x22122149, +0x74016022, 0x2202CB01, 0xD5976622, 0x22622649, +0xC8406070, 0x60528902, 0x2502CB04, 0xE1F76452, +0x25422419, 0xE7016052, 0x2502C9CF, 0xE6026052, +0x2502CB03, 0x15624718, 0x1573000B, 0xD78CD58B, +0xD48DD28C, 0xE600E100, 0x27112511, 0xAFD12210, +0x664C2461, 0x4600D289, 0x6060362C, 0x000BCB10, +0x654C2600, 0x4500D285, 0x6650352C, 0x2619E1EF, +0x2560000B, 0xD282664C, 0x362C4600, 0xCB106060, +0x2600000B, 0xD27E654C, 0x352C4500, 0xE1EF6650, +0x000B2619, 0x664C2560, 0x4600D278, 0x6060362C, +0x000BCB08, 0x654C2600, 0x4500D274, 0x6650352C, +0x2619E1F7, 0x2560000B, 0xD271664C, 0x362C4600, +0xCB086060, 0x2600000B, 0xD26D654C, 0x352C4500, +0xE1F76650, 0x000B2619, 0x624C2560, 0x4200D667, +0x6020326C, 0x4021C908, 0x40214021, 0x600C000B, +0xD663624C, 0x326C4200, 0xC9086020, 0x40214021, +0x000B4021, 0xD15F600C, 0x341C644C, 0x000B6240, +0xD15D602C, 0x341C644C, 0x000B6240, 0x2FE6602C, +0x6E434F22, 0xE60A645C, 0x89143467, 0x0009BFEB, +0x60EC640C, 0x8B028801, 0xA002E00F, 0x44092409, +0x624C4409, 0x3263E60A, 0xBFE28905, 0x620C644C, +0xC8806023, 0xE2008B00, 0x4F266023, 0x6EF6000B, +0xD64A4F22, 0x88016062, 0xB2458B03, 0xA0030009, +0xD2470009, 0x2260E640, 0xE200D646, 0x000B4F26, +0x4F222622, 0x6062D641, 0x8B018802, 0x0009B28E, +0xE200D640, 0x000B4F26, 0xD53C2622, 0xE100D43C, +0x2512E701, 0x2470000B, 0xE604D239, 0x2260000B, +0xD4394F22, 0x410BD139, 0xD5390009, 0x6650E1FD, +0x2619D238, 0x2560E700, 0x000B4F26, 0x4F222270, +0xD132D435, 0x0009410B, 0xE7FBD531, 0x26796650, +0x000B4F26, 0x4F222560, 0xD12CD430, 0x0009410B, +0xE7F7D52B, 0x26796650, 0x000B4F26, 0xD5282560, +0x6250942D, 0x000B2249, 0xD5252520, 0x6250E4BF, +0x000B2249, 0x4F222520, 0x8522D225, 0x2008600D, +0x88018911, 0x88038913, 0x88058915, 0x88068942, +0x88088948, 0x8809894E, 0x880A8954, 0x880B895A, +0xA0678960, 0xB0690009, 0xA0640009, 0xB077600C, +0xA0600009, 0xB080600C, 0xA05C0009, 0xFF7F600C, +0x001E2148, 0x001E1000, 0x001E1108, 0x002031FC, +0x002031FE, 0x0020321D, 0x002031E0, 0x001E103F, +0x001E105F, 0x001E102F, 0x001E1090, 0x00203204, +0x001E100B, 0x00203200, 0x00203330, 0x0020145E, +0x001E1028, 0x0020321C, 0x0020333C, 0x0020334C, +0x002031D4, 0x6260D684, 0x8B2B2228, 0x0009B061, +0x600CA029, 0x6260D680, 0x8B232228, 0x0009B069, +0x600CA021, 0x6260D67C, 0x8B1B2228, 0x0009B0C7, +0x600CA019, 0x6260D678, 0x8B132228, 0x0009B0CD, +0x600CA011, 0x6260D674, 0x8B0B2228, 0x0009B125, +0x600CA009, 0x6260D670, 0x8B032228, 0x0009B13D, +0x600CA001, 0x4F26E000, 0x0009000B, 0xD26CD16B, +0xD56C8412, 0x4000C90F, 0xD76B012D, 0xE403D66B, +0xE20F611C, 0x2540E001, 0x25202712, 0x2602000B, +0xE601D262, 0x30668523, 0xE0008D05, 0xD663D260, +0xE0018122, 0x000B2602, 0xD25C0009, 0x600D8523, +0x89052008, 0x8B0A8801, 0x6060D65D, 0x2600CB01, +0xD457D65A, 0xE001E101, 0x000B2612, 0x000B8142, +0xD152E000, 0x8513E501, 0x640D4518, 0x66033453, +0xE0008D05, 0xD551D253, 0x2260E001, 0x000B2502, +0x4F220009, 0x8513D149, 0x6453650D, 0x62494419, +0x227D672E, 0x8801602C, 0x88028909, 0x88038910, +0x8806891A, 0x88078935, 0xA04C893B, 0xD5460009, +0x6652D746, 0x2762D446, 0x622C6261, 0x2421A038, +0x2228625C, 0xD4438B3F, 0x6642D540, 0x2562D440, +0x24018561, 0x6203A02C, 0x2008605C, 0x88108907, +0x88208908, 0x88308909, 0xA02C890A, 0xD23A0009, +0x6222A008, 0xA005D239, 0xD2396222, 0x6222A002, +0x6262D638, 0xD432D531, 0x66212522, 0xA00F626C, +0xD6352421, 0x6261D52D, 0x622CD42D, 0xA0072562, +0xD6322421, 0x8561D529, 0x2562D429, 0x62032401, +0x662D8515, 0x3617610D, 0x65038F01, 0xB0CB2451, +0xA0010009, 0xE000E001, 0x000B4F26, 0xD6190009, +0xD427E101, 0x65412610, 0xD118D717, 0xE20F655D, +0x2752E001, 0x000B2620, 0x2FE62102, 0xD20F4F22, +0x640C8523, 0x8B082448, 0xD511D61D, 0x2621E200, +0x940F8451, 0xA0482049, 0xDE0D8051, 0xC84060E0, +0xE2018D32, 0x89443427, 0xD216D615, 0x2641420B, +0x0009A030, 0x0000FF7F, 0x0020321D, 0x002031D4, +0x002031E0, 0x001E1100, 0x001E100C, 0x00203200, +0x001E1000, 0x001E1001, 0x00203208, 0x002031E8, +0x002031EC, 0x002031F0, 0x0020320C, 0x00203210, +0x00203214, 0x00203218, 0x0020351C, 0x00203526, +0x002031FA, 0x00202362, 0x89123427, 0xD294D693, +0x2641420B, 0xCB8084E1, 0x80E1B0F5, 0xD69160E0, +0x2E00CB04, 0xC93F6060, 0xD68F2600, 0xA001E001, +0xE0002602, 0x000B4F26, 0xD68C6EF6, 0xC8806060, +0xD2868919, 0x88016021, 0xD2898B15, 0x8524E501, +0x89103056, 0xE203D187, 0x2120D487, 0xE00B6541, +0x0656655D, 0xE40FD585, 0x2140E702, 0xD77E2571, +0x000BE001, 0x000B2702, 0x2FE6E000, 0xDE804F22, +0xC88084E1, 0xD57A892C, 0x20088554, 0x61038F28, +0x8553D77C, 0x64036672, 0x8566650C, 0x3520620C, +0xD6798B1E, 0x651CD774, 0x2651644C, 0x60E02741, +0x8904C840, 0x420BD275, 0xA0030009, 0xD2680009, +0x0009420B, 0x0009B09F, 0xE201D167, 0x60E02122, +0xCB04D464, 0x60402E00, 0x2400C93F, 0x6023A001, +0x4F26E000, 0x6EF6000B, 0x2FB62FA6, 0x2FD62FC6, +0xDA622FE6, 0x66A1E240, 0x3622DC5E, 0x62638900, +0x6ED36D2C, 0x4E2136D8, 0x4E212A61, 0xDB61D460, +0xE700A00F, 0x770162B2, 0x71026123, 0x66212B12, +0x71026213, 0x61212B12, 0x651D666D, 0x356C4528, +0x627C2452, 0x8BED32E3, 0xC90360D3, 0x8B108803, +0x617367B2, 0x2B127102, 0x71026E13, 0x2B126571, +0x655D6DE1, 0x422862DD, 0x325CE107, 0xA00C2C10, +0x88022422, 0xA0038B01, 0x8801E203, 0xE2018B05, +0x66B22C20, 0x655D6561, 0xE60F2452, 0x67A12C60, +0x8B052778, 0xDD38DC44, 0xEB01EA00, 0x2DB22CA2, +0x6DF66EF6, 0x6BF66CF6, 0x6AF6000B, 0x2FE62FD6, +0xE240DD36, 0x362266D1, 0x62638900, 0x3678672C, +0x7703DE38, 0x47212D61, 0x64E2D635, 0xA00E4721, +0x6562E100, 0x62537101, 0x74012450, 0x24204219, +0x45297401, 0x74012450, 0x24504519, 0x621C7401, +0x8BEE3273, 0x66E24200, 0x420061D1, 0x2118362C, +0x2E628F06, 0xDD1CD728, 0xE501E400, 0x2D522742, +0x000B6EF6, 0x2FD66DF6, 0x4F222FE6, 0xED0AEE01, +0x64E3BC97, 0xBC9C64E3, 0x62EC7E01, 0x8BF732D7, +0xBC9FEE01, 0x64E364E3, 0x7E01BCA4, 0x32D762EC, +0x4F268BF7, 0x000B6EF6, 0xD1186DF6, 0xD418920D, +0x72122122, 0x2422D617, 0xD7177204, 0x72202622, +0x2722D116, 0x000B7230, 0x137A2122, 0x002031FA, +0x0020246E, 0x001E1015, 0x00203200, 0x001E1001, +0x002031D4, 0x001E1100, 0x002031FE, 0x002031EC, +0x001E1000, 0x002031F0, 0x002031FC, 0x00202362, +0x001E100C, 0x002031E8, 0x00203204, 0x00203208, +0x0020320C, 0x00203210, 0x00203214, 0x00203218, +0x4F222FE6, 0xD6507FFC, 0x88016060, 0xE2018951, +0x2620BFBB, 0xD54ED14D, 0xDE4E6010, 0x64E36552, +0x7402C840, 0x8D22D14C, 0xD24C7502, 0xE601D74C, +0xE7042722, 0x76016255, 0x626C2421, 0x8FF93273, +0xD4437402, 0x6242E601, 0x640D8528, 0x67494419, +0x275D657E, 0x81E4607C, 0xE417D542, 0x67557601, +0x3243626C, 0x8FF92171, 0xA0207102, 0xD23E0009, +0xE601D73B, 0xE7042722, 0x76016255, 0x626C2421, +0x8FF93273, 0xD4327402, 0x6242E601, 0x640D8528, +0x67494419, 0x275D657E, 0x81E4607C, 0xE417D533, +0x67557601, 0x3243626C, 0x8FF92171, 0x924A7102, +0xD2262E21, 0x5E23D72E, 0x64F22FE2, 0x604365F2, +0x2700C980, 0xC9606043, 0x80716103, 0xC9036043, +0x80724519, 0x65F2605C, 0x817266F2, 0x46194629, +0x606C4529, 0x4018645C, 0x8173304C, 0x21185E23, +0x64F22FE2, 0x6E4C62F2, 0x602C4219, 0x66F262F2, +0x46294018, 0x461930EC, 0x42298174, 0x652C606C, +0x305C4018, 0x81758F07, 0x0009BC9D, 0x2228620C, +0xA00A8908, 0x60130009, 0x8B038840, 0x0009B009, +0x0009A003, 0xE202D60F, 0x7F042622, 0x000B4F26, +0x000B6EF6, 0x060A0009, 0x0020321C, 0x001E1000, +0x00203208, 0x0020351C, 0x00203528, 0x002034C0, +0x002031F0, 0x002034F0, 0x002034EE, 0x002034C2, +0x002031D4, 0x00203200, 0x4F222FE6, 0xDE937FFC, +0x200884E9, 0x2F008D06, 0xD692D491, 0x0009460B, +0x64F0B194, 0x6620D290, 0x89022668, 0xC9BF60E0, +0x7F042E00, 0x000B4F26, 0x000B6EF6, 0x2FE60009, +0xDE8A4F22, 0x60E0D68A, 0xCBC0D48A, 0x62602E00, +0xC803602C, 0x40218904, 0x70014021, 0x6603A002, +0x66034009, 0xD684616D, 0xE500A004, 0x75016262, +0x74042422, 0x3213625D, 0xD2808BF8, 0x0009420B, +0xC9BF84E2, 0x4F2680E2, 0x6EF6000B, 0x2FE62FD6, +0x7FFC4F22, 0x6260D67A, 0x89442228, 0xD56FE100, +0x60502610, 0xCB40D477, 0x2500440B, 0x8D052008, +0x62E06E03, 0x7104612C, 0x2F11A006, 0xD472D66A, +0xDD726760, 0x657C4D0B, 0xE23C6D1D, 0x8B033D27, +0xD264D46F, 0x0009420B, 0x4D214D21, 0xA005D76D, +0x66E6E400, 0x357C4508, 0x74012562, 0x35D3654D, +0xD7698BF7, 0x6172E003, 0x81114018, 0x6E7260F1, +0x81E2700C, 0xD4656172, 0xDD658113, 0x4D0BDE65, +0xE2016572, 0xD4642E22, 0x420BD252, 0xD6530009, +0xC93F6060, 0x7F042600, 0x6EF64F26, 0x6DF6000B, +0x2FC62FB6, 0x2FE62FD6, 0xD25C4F22, 0x6B436E73, +0x420B6C53, 0x20086D63, 0x61038F08, 0xD245D458, +0x6EF64F26, 0x6CF66DF6, 0x6BF6422B, 0x21B060C3, +0x60D38011, 0xE5008111, 0x64BCA007, 0x6053655D, +0x665300EC, 0x7501361C, 0x625D8064, 0x8BF53243, +0x6060D636, 0x2600C9BF, 0x6EF64F26, 0x6CF66DF6, +0x6BF6000B, 0x7FC44F22, 0x720262F3, 0x22512F41, +0x45297202, 0x60632251, 0xE5C4E682, 0x67F38121, +0x655C666C, 0xE408BFBC, 0x4F267F3C, 0x0009000B, +0x2F962F86, 0x2FB62FA6, 0x2FD62FC6, 0x4F222FE6, +0xE1007FC4, 0x6513ECFF, 0x6B136CCD, 0xDE36D735, +0xEDFF64F3, 0xD835EA04, 0x6053655C, 0x027D4000, +0x32C0622D, 0x66038D0D, 0x09ED6063, 0x2491027D, +0x24217402, 0x698202ED, 0x3928622D, 0x74022892, +0x75017104, 0x6063625C, 0x07D532A2, 0x0EB58FE4, +0x2448641C, 0xE6808905, 0x67F3E5C5, 0xBF7F666C, +0x7F3C655C, 0x6EF64F26, 0x6CF66DF6, 0x6AF66BF6, +0x000B69F6, 0xD11E68F6, 0x6012D21E, 0xCB20E405, +0x2102E500, 0x000B2242, 0x00002252, 0x001E1017, +0x00203358, 0x0020145E, 0x002031A2, 0x001E1015, +0x001E10BF, 0x00117800, 0x001E10FC, 0x00200308, +0x002031A8, 0x002025C6, 0x0020335C, 0x002014AA, +0x00203378, 0x0011788C, 0x002031A4, 0x00202D88, +0x002011E4, 0x001E2130, 0x00203380, 0x00202588, +0x00203384, 0x002031BC, 0x002031C4, 0x002034BC, +0x001C3500, 0x001D4004, 0xD565D164, 0xE400D765, +0x2142E20F, 0x17411154, 0xD5632722, 0x9669D763, +0x15412572, 0x96661562, 0xE6011565, 0xD5601165, +0x666CE6F8, 0x25422542, 0x25422542, 0x25422542, +0x25622542, 0x7601E727, 0x67632572, 0x25627797, +0xE7042572, 0x2572E248, 0xE2192522, 0xE2702522, +0x25422542, 0x25422542, 0x25222542, 0x2522E20C, +0x25422542, 0x25422542, 0x25422542, 0x25422542, +0x000B154A, 0xE2081145, 0x0009422B, 0x2FE62FD6, +0x7FFC4F22, 0xC8206043, 0x6E438D02, 0x0009BE6D, +0xC81060E3, 0xBE6A8901, 0x60E30009, 0x8901C840, +0x0009BE8C, 0xC80160E3, 0xDD3E8938, 0xC80260D0, +0x2F008D03, 0x460BD63C, 0x60F00009, 0x8902C804, +0x460BD63A, 0x62F00009, 0xC8806023, 0x60D08902, +0x2D00C97F, 0xC8016023, 0xD6358906, 0x0009460B, +0x0009A007, 0x51630601, 0x8902C808, 0x460BD631, +0x60F00009, 0x8902C810, 0x420BD22F, 0xD52F0009, +0x88026052, 0xD22E8B03, 0xA005E604, 0x88012260, +0xD22B8B02, 0x2260E601, 0x2522E200, 0xC88060E3, +0xD628892E, 0x60E36E60, 0x8902C880, 0x420BD226, +0x60E30009, 0x8902C840, 0x420BD224, 0x60E30009, +0x8902C802, 0x420BD222, 0x60E30009, 0x890EC804, +0x410BD120, 0xBF0E0009, 0xBF4D0009, 0xD51E0009, +0x6050D41E, 0xC908D71E, 0xBF842500, 0x60E32472, +0x8905C808, 0x7F04D21B, 0x6EF64F26, 0x6DF6422B, +0x4F267F04, 0x000B6EF6, 0x00006DF6, 0x001C581C, +0xA000A000, 0x001D0100, 0x001D4000, 0x00040021, +0x001C589C, 0x001E1021, 0x00201640, 0x00201662, +0x00201CA0, 0x0020167A, 0x00201688, 0x00203200, +0x001E100B, 0x001E1028, 0x002016DE, 0x002016EA, +0x00201690, 0x002016AE, 0x001E1000, 0x0010F100, +0x12345678, 0x002016C6, 0x644CD6A7, 0x000B346C, +0xD6A62450, 0x346C644C, 0x2450000B, 0x644CD6A4, +0x000B346C, 0x625C2450, 0x4208616D, 0x42084119, +0x42006019, 0x670E614C, 0xD49E321C, 0x4200207D, +0x324CC90F, 0x2200000B, 0x4208625C, 0x42004208, +0x324C644C, 0x4200D498, 0x000B324C, 0x2FE62260, +0x614C4F12, 0x4100D493, 0x6710314C, 0xE29F666D, +0x27294619, 0x6E536269, 0x672E6573, 0x4221227D, +0x42214221, 0x7601662C, 0xE4014608, 0x34E84608, +0x644C4600, 0x071A0467, 0x2150257B, 0x000B4F16, +0x4F226EF6, 0xD2857FE8, 0x88016021, 0xD2848B7B, +0x26686621, 0xD2838B77, 0x26686621, 0xE50F8B73, +0xE401BFA2, 0xBFA4E501, 0xE586E400, 0xE400655C, +0x2F50BFA4, 0xBFA1E401, 0xE602E506, 0x60634618, +0x81F2E401, 0x6543BF9F, 0xE40185F2, 0xBFAB6543, +0x85F26603, 0x6543E401, 0x6603BFB1, 0xE40265F0, +0x6053756C, 0x80F8BF80, 0xBF82E402, 0x84F8E512, +0x7090E402, 0x6503BF82, 0x4618E602, 0x81F66063, +0xBF80E402, 0x85F6E500, 0x6603E402, 0xE500BF8C, +0xE40285F6, 0xBF926603, 0xE5FEE500, 0xE010655C, +0xBF61E403, 0xE5130F54, 0xE40EBF63, 0x05FCE010, +0xBF63E40E, 0xE5007585, 0xBF64E403, 0xE500E640, +0xBF71E403, 0xE500E640, 0xBF78E403, 0xE5FFE640, +0xE014655C, 0xBF47E404, 0xE40F0F54, 0xE504BF49, +0x05FCE014, 0xBF49E40F, 0xE5017584, 0xBF4AE640, +0xE501E404, 0xBF57E640, 0xE501E404, 0xE404E640, +0xAF5C7F18, 0x7F184F26, 0x000B4F26, 0x4F220009, +0xD2427FF0, 0x88016021, 0xD2418B71, 0x26686621, +0xD2408B6D, 0x26686621, 0xE50F8B69, 0xE401BF1C, +0xBF1EE501, 0xE586E400, 0xE400655C, 0x2F50BF1E, +0xBF1BE401, 0xE401E506, 0xBF1C6543, 0xE401E640, +0xBF296543, 0xE401E640, 0xBF306543, 0x65F0E640, +0x756CE402, 0xBEFF6053, 0xE40280F4, 0xE512BF01, +0xE40284F4, 0xBF017090, 0xE6406503, 0xBF02E402, +0xE640E500, 0xBF0FE402, 0xE640E500, 0xBF16E402, +0xE5FEE500, 0x6053655C, 0xBEE5E403, 0xE51380F8, +0xE40EBEE7, 0xE40E84F8, 0xBEE77085, 0xE5006503, +0xBEE8E640, 0xE500E403, 0xBEF5E640, 0xE500E403, +0xBEFCE640, 0xE5FFE403, 0x6053655C, 0xBECBE404, +0xE40F80FC, 0xE504BECD, 0xE40F84FC, 0xBECD7083, +0xE5016503, 0xBECEE640, 0xE501E404, 0xBEDBE640, +0xE501E404, 0xE404E640, 0xAEE07F10, 0x7F104F26, +0x000B4F26, 0x00000009, 0x001E102F, 0x001E1080, +0x001E1090, 0x001E103F, 0x001E103E, 0x002031FA, +0x002031FC, 0x002031FE, 0xD21DD11C, 0x66206010, +0x676C7001, 0x3700C90F, 0xE5008D13, 0x67106210, +0x7701622C, 0x64232170, 0xD6166010, 0x44084408, +0x3428C90F, 0x62602100, 0x7201D513, 0x44082620, +0x000B354C, 0xD10F6053, 0x25586510, 0xE6008D13, +0xD60DD40B, 0x655C6540, 0x47086753, 0x37584708, +0x47086540, 0x24507501, 0x367C6040, 0x2400C90F, +0x72FF6210, 0x000B2120, 0x00006063, 0x002031A1, +0x002031A0, 0x002031A2, 0x00202DC8, 0x7FFC4F22, +0xE680D19D, 0x666C6212, 0xD29C2F22, 0x67F36563, +0x420B7542, 0x7F04E404, 0x000B4F26, 0xE6800009, +0xD296666C, 0xE7006563, 0x422B7540, 0xE6806473, +0xD292666C, 0xE7006563, 0x422B7543, 0x2F866473, +0x2FA62F96, 0x2FC62FB6, 0x2FE62FD6, 0x7FF44F22, +0xDD8CD28B, 0x72011F21, 0xDB8B1F22, 0x6AF2E840, +0x5211D18A, 0x36206612, 0xA0A78B01, 0x60610009, +0x8801C903, 0xA0A18B01, 0xD9840009, 0x420BD284, +0x55036493, 0x845C6A03, 0x30E0EE84, 0xD1818B79, +0x606C6610, 0x8B3D8801, 0x6210D17F, 0x892F2228, +0xD57EE701, 0x64522B72, 0x1442E003, 0xD57C6252, +0xE6004018, 0x21608121, 0xD17A6453, 0x6E527404, +0x60126742, 0xCB20DC78, 0x76012102, 0x3283626D, +0x25E28BFB, 0x2472DE71, 0x62E267C2, 0x1274D173, +0x604164E2, 0x2401CB01, 0xEE0066E2, 0xDC702C62, +0xEC012C62, 0x2DC2410B, 0x4C18EC01, 0x2BE22DC2, +0xD764DE6C, 0xD16C60E2, 0xCB01E202, 0x27202E02, +0x2122A02F, 0x8B2C2008, 0xE701DE68, 0xD466EC00, +0x2170D264, 0xEE012EC2, 0x612224E2, 0x2169E6FE, +0xE01E2212, 0x54F10C5C, 0x24C0E01F, 0x56F2025C, +0x26207510, 0xD75EE600, 0xEE06D45E, 0x76018456, +0x6C542700, 0x31E3616C, 0x740124C0, 0x77018FF6, +0xE494D259, 0x72012240, 0x2250E500, 0xE605720F, +0xD2562260, 0x65A36493, 0xEE01420B, 0xAF6F4E18, +0x2FA22DE2, 0xD45265F2, 0x66428553, 0x3262620D, +0xD4508907, 0x410BD150, 0xD7500009, 0xAF57E601, +0xD43A2762, 0xDD37D149, 0x65F2410B, 0xD44CEE01, +0x4E18D64C, 0x2DE2460B, 0x0009AF4A, 0x7F0C2FA2, +0x6EF64F26, 0x6CF66DF6, 0x6AF66BF6, 0x000B69F6, +0x4F2268F6, 0x85467FF4, 0x2F01E681, 0x666C8547, +0x854881F1, 0x81F2D225, 0x67F38542, 0x854381F3, +0x81F4E40C, 0x65636053, 0x420B81F5, 0x7F0C7540, +0x000B4F26, 0x2F860009, 0x2FA62F96, 0x2FC62FB6, +0x2FE62FD6, 0x7FEC4F22, 0xE800D11A, 0xD4322F12, +0x1F416183, 0x6A13DB20, 0x4A08D630, 0xDE20E001, +0x4A00460B, 0x1F023AEC, 0x52B166B2, 0x8B013620, +0x0009A19B, 0xC9036061, 0x8B018801, 0x0009A195, +0xDE275263, 0x8B4F32E0, 0x420BD20D, 0xDE2564B3, +0xD70DD50E, 0xED01DC0B, 0x2E02E100, 0x27D02502, +0xAFE12C10, 0x00002E16, 0x001C3D9C, 0x00201F40, +0x0011779A, 0x001C3D30, 0x001D0104, 0x00202DC0, +0x00201162, 0x002031B1, 0x002031B0, 0x002031AC, +0x001C3B9C, 0x001C3500, 0x00202D98, 0x00201276, +0x001C3D00, 0x001C36F8, 0x00117708, 0x002031B4, +0x0011778C, 0x00117792, 0x00117788, 0x00201180, +0x00203188, 0x00202D88, 0x002011E4, 0x001E2130, +0x0020349C, 0x0020145E, 0x002034A8, 0x00202C80, +0x00117780, 0x0011770C, 0xC8018561, 0x5C63897A, +0x660385C2, 0x6403C903, 0x650D85C3, 0x40216053, +0xC93F4021, 0x6E034500, 0x252D322A, 0xE2106053, +0x3E23C901, 0x6D038D23, 0x4408D79D, 0x44086570, +0x440062E3, 0x25584200, 0x342C8F0F, 0x6043D299, +0x697D072D, 0x60994919, 0x201D610E, 0x60D381F6, +0x8F0C8801, 0xA00A697C, 0xD29369E3, 0x052D6043, +0x4219625D, 0x670E6029, 0x81F6207D, 0xD18F695C, +0x22286210, 0xE9FF8901, 0xEEFF699C, 0x6EEC659D, +0x8B0F35E0, 0x4C0BDC8A, 0x540364B3, 0xBF20E502, +0xD4886E03, 0x410BD188, 0xD78865E3, 0xD488ED01, +0x27D2A01E, 0x26E9EEFC, 0x81C26063, 0x97C585C3, +0x62032079, 0x450885F6, 0x6063260B, 0x81C2252B, +0x81C36053, 0xE10885C4, 0x201B4118, 0x62B281C4, +0x20E98521, 0x64B28121, 0xCB016041, 0xD4792401, +0x450BD579, 0x60B20009, 0x57F266F2, 0x2A02CB01, +0x2672AF22, 0xD26E8561, 0x8F02C802, 0xA09F64B3, +0x420B0009, 0xDC710009, 0x5E036503, 0x07CEE04C, +0x7701DD6F, 0x6CD20C76, 0x7C01D664, 0x6D602DC2, +0x89062DD8, 0xD264D463, 0xED01420B, 0xA07ED763, +0x625127D2, 0x4118E10F, 0x2219E402, 0x32404418, +0x85518B11, 0x20D9EDFC, 0x60518151, 0xCB017DE3, +0x85E12501, 0x20D9D65F, 0x460B81E1, 0x6CF264B3, +0xA06457F2, 0x6D512C72, 0x4D196DDD, 0x66DE6DD9, +0x7D012D6D, 0x610360DC, 0x88014118, 0x25118F45, +0x6462D653, 0x26427401, 0x660D85E3, 0x40216063, +0xC93F4021, 0x6D034600, 0x262D322A, 0xC8016063, +0xDC4ED14D, 0x964A8901, 0xE6002D6B, 0x0F64E010, +0xE01064DD, 0x607C07FC, 0x021D4000, 0x3240622D, +0x66038D12, 0x021D6063, 0x3270E7FF, 0xA00B8B01, +0xE01001D5, 0xE60402FC, 0x0F247201, 0x3262622C, +0x06FC8BE7, 0x4600666C, 0x01CD6063, 0x0C157101, +0x6711D13B, 0x3C406C7D, 0x62118907, 0x88FF602D, +0x21D18903, 0xE201DD37, 0x85512D20, 0x20D9EDFC, +0x60518151, 0xCB01D22F, 0x420B64B3, 0xE0102501, +0xD43102FC, 0xE001612C, 0x67F2440B, 0x85EF2702, +0x54F1D22E, 0x650D420B, 0x0009AE7E, 0x80007E03, +0x0009420B, 0x6E035403, 0xED088544, 0x20D94D18, +0x8B0330D0, 0xE501BE3D, 0x0009A007, 0xDD248541, +0x22D8620D, 0xBE348901, 0xD412E500, 0x420BD212, +0xD71265E3, 0xAE5FED01, 0x780127D2, 0xEE04618D, +0x8D0231E7, 0xAE4E7B08, 0x7F140009, 0x6EF64F26, +0x6CF66DF6, 0x6AF66BF6, 0x000B69F6, 0x000068F6, +0x002034B8, 0x0020339C, 0x0020341C, 0x0020319C, +0x00201162, 0x00202D90, 0x00201180, 0x001E212C, +0x002034A0, 0x002034A4, 0x0020145E, 0x00202D2C, +0x002034BC, 0x002011E4, 0x002031BC, 0x002031C4, +0x002031B8, 0x002031BA, 0x00202C80, 0x002014AA, +0x00008000, 0x4F222FE6, 0x6E22D212, 0xC84060E3, +0x22E28D02, 0x0009BCFA, 0x4218E240, 0x89012E28, +0x0009BD05, 0xC81060E3, 0xD40B8905, 0x420BD20B, +0xBD040009, 0x60E30009, 0x8901C805, 0x0009BDEB, +0xC80260E3, 0x4F268902, 0x6EF6AD01, 0x000B4F26, +0x00006EF6, 0x001C3510, 0x002034B0, 0x0020145E, +0x080A0C0E, 0x00020406, 0x1A1C1E20, 0x12141618, +0x2E303234, 0x26282A2C, 0x3A3C3E40, 0x6C625648, +0x41112F26, 0xE2208F18, 0x890B3123, 0x321CD204, +0xD1026220, 0x412B312C, 0x00090009, 0x00202CAA, +0x00202C60, 0x000BE000, 0x400062F6, 0x40004000, +0x40004000, 0x40004000, 0x62F6000B, 0x40004000, +0x40004000, 0x40004000, 0x40184000, 0x62F6000B, +0x40004000, 0x40004000, 0x40004000, 0x40284000, +0x62F6000B, 0x40004000, 0x40184000, 0x000B4028, +0xC90F62F6, 0x40054005, 0x40054005, 0x62F6000B, +0x4005C907, 0x40054005, 0x62F6000B, 0x4005C903, +0x000B4005, 0xC90162F6, 0x000B4005, 0x000062F6, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 0x544F0D0A, +0x46205355, 0x00003A57, 0x206C754A, 0x32203532, +0x20373030, 0x313A3132, 0x37323A32, 0x00000000, +0x00000D0A, 0x00000043, 0x42707372, 0x3D206675, +0x554E203D, 0x202C4C4C, 0x6E49677A, 0x4E497274, +0x6D754E51, 0x0000003D, 0x61766E49, 0x2064696C, +0x72657375, 0x20726F20, 0x2079656B, 0x00214449, +0x52504545, 0x57204D4F, 0x65746972, 0x6461202C, +0x003D7264, 0x6C617620, 0x0000003D, 0x00000A0D, +0x6E6B6E55, 0x206E776F, 0x6D6D6F63, 0x3D646E61, +0x00000000, 0x000A0D52, 0x203A3051, 0x00000020, +0x203A3151, 0x00000020, 0x203A3251, 0x00000020, +0x203A3351, 0x00000020, 0x203A3451, 0x00000020, +0x61437748, 0x7262696C, 0x6F697461, 0x6620206E, +0x0A6C6961, 0x0000000D, 0x73696F4E, 0x61432065, +0x7262696C, 0x6F697461, 0x6166206E, 0x21216C69, +0x00000D0A, 0x00000072, 0x00205220, 0x00000D0A, +0x62735576, 0x7473725F, 0x00000A0D, 0x62735576, +0x7375735F, 0x646E6570, 0x00000A0D, 0x62735576, +0x7365725F, 0x000A0D6D, 0x00000042, 0x72746E49, +0x6D652051, 0x2C797470, 0x49677A20, 0x4972746E, +0x754E514E, 0x00003D6D, 0x654C7245, 0x0000006E, +0x00000049, 0x20746F4E, 0x756F6E65, 0x49206867, +0x4220514E, 0x0A0D6675, 0x00000000, 0x000000FF, +0x00020001, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x010E010D, +0x00020003, 0x01090108, 0x0002010A, 0x02000003, +0x02020201, 0x02040203, 0x02060205, 0x02020200, +0x02040203, 0x020C0207, 0x020E020D, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x010E010D, +0x00FF010F, 0x01090108, 0x010B010A, 0x020000FF, +0x02020201, 0x02040203, 0x02060205, 0x02020200, +0x02040203, 0x020C020B, 0x020E020D, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00205220, +0x00000046, 0x00000059, 0x73204142, 0x003D7165, +0x49544120, 0x0000204D, 0x00000000, 0x00000000, +0x002E0209, 0x80000101, 0x000409FA, 0x00FF0400, +0x05070000, 0x02000201, 0x82050700, 0x00020002, +0x03830507, 0x07010040, 0x40020405, 0x02090000, +0x0101002E, 0x09FA8000, 0x04000004, 0x000000FF, +0x02010507, 0x07000040, 0x40028205, 0x05070000, +0x00400383, 0x04050701, 0x00004002, 0x00000000, +0x00000000, 0x07090000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, }; + +const u32_t zcFwImageSize=13656; --- linux-2.6.28.orig/drivers/staging/otus/hal/hpfwu.c.drv_ba_resend +++ linux-2.6.28/drivers/staging/otus/hal/hpfwu.c.drv_ba_resend @@ -0,0 +1,742 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "cprecomp.h" + +const u32_t zcFwImage[] = { +0x0009000B, 0x4F222FE6, 0xDE297FFC, 0xE114D729, +0x1E13D429, 0x1E4C470B, 0x0009B018, 0xA0039545, +0x3652E600, 0x76018D04, 0xC84060E2, 0x2F028DF9, +0xDE23D422, 0x00094E0B, 0x4E0BD422, 0xD4220009, +0x00094E0B, 0x4F267F04, 0x6EF6A024, 0xD11F4F22, +0x0009410B, 0x440BD41E, 0xD51E0009, 0x0009450B, +0xE1FFD71D, 0xD21D611D, 0x50292712, 0xCB01D41C, +0xE501E1FF, 0x22121209, 0x24521211, 0xD61AD519, +0xE2009714, 0xD4192572, 0xD6192620, 0x4F262422, +0x2622000B, 0xDD18DC17, 0x4C0BDE18, 0x4D0B0009, +0x4E0B0009, 0xAFF80009, 0x27100009, 0x00000640, +0x001C001C, 0x00200BC4, 0x0000B38E, 0x002029F8, +0x00200F72, 0x00202A04, 0x00202A1C, 0x00200F20, +0x00201056, 0x00200C1C, 0x001C3510, 0x001C3624, +0x001E212C, 0x00202994, 0x00202530, 0x0020299C, +0x002029A8, 0x00200E50, 0x002023E6, 0x00201920, +0x2FC62F96, 0x2FE62FD6, 0x7F904F22, 0xE020DE8D, +0xD48D61E0, 0x61E30F14, 0x62107101, 0xE024D78B, +0x0F24470B, 0x450BD58A, 0x20080009, 0x8F116D03, +0xDD881F0A, 0x67D0D488, 0x410BD188, 0xD288657C, +0x6920DD88, 0x66C36C9C, 0x46084608, 0x460836C8, +0x1FDA3D6C, 0x04FCE024, 0x66E2E580, 0x655C604C, +0x8F163050, 0xE0202D62, 0xE50001FC, 0xDE7E641C, +0x3243625D, 0xA32C8B01, 0x655D0009, 0x36EC6653, +0xE02C6760, 0x69530F74, 0x39DC607E, 0xAFEF8094, +0x20087501, 0xE0208B14, 0xE50001FC, 0xA00ADE72, +0x655D641C, 0x39EC6953, 0x67536C92, 0x37DC62C2, +0x75041721, 0x625D1F2C, 0x8BF23243, 0x2D10A309, +0x8B178801, 0x01FCE020, 0x2D70E700, 0x1FD76D1C, +0x627DDE65, 0x8B0132D3, 0x0009A2FB, 0x65E3677D, +0x75046673, 0x36EC6C73, 0x64623C5C, 0x770869C2, +0x2492AFEF, 0x8B188804, 0x01FCE020, 0x2D40E400, +0xDE59671C, 0x3273624D, 0xA2E28B01, 0x644D0009, +0x6CE36D43, 0x65D23DEC, 0x61437C04, 0x621231CC, +0x74086952, 0xAFED2929, 0x88052592, 0xE0208B18, +0xE40001FC, 0x671C2D40, 0x624DDE4B, 0x8B013273, +0x0009A2C7, 0x6943644D, 0x39EC61E3, 0x71046592, +0x3C1C6C43, 0x6D5262C2, 0x2D2B7408, 0x25D2AFED, +0x8B1B8831, 0xD942D241, 0x72046422, 0x72046622, +0x72046722, 0x72E86C22, 0x1F2E1F4D, 0x72046422, +0x72046E22, 0x652229E0, 0x2950D93A, 0xDE3A2FC6, +0x55FE4E0B, 0xE2007F04, 0x2D20A29B, 0x8B1D8830, +0xDE33D232, 0x72046522, 0x72046122, 0x72046722, +0x72E86922, 0x72046422, 0x72046C22, 0x6E222EC0, +0x1F9FD62C, 0x7FFC26E0, 0x09FEE040, 0x2F92DC2B, +0x66134C0B, 0xE2007F04, 0x2D20A27B, 0x89018828, +0x0009A109, 0xE143DE20, 0xE04062E1, 0x3617662D, +0x0FE68F03, 0x660302FE, 0x36172201, 0xA0F38B01, +0xE0400009, 0xE50104FE, 0x30568541, 0xA0EB8B01, +0xE0400009, 0x09FEE701, 0xB2612D70, 0xE0406491, +0xE1430CFE, 0xE06862C1, 0x3517652D, 0x0F568D68, +0x3563E640, 0xE6008B24, 0x0F65E048, 0xA02EE11A, +0x000072C0, 0x00117800, 0x00202A20, 0x00200F72, +0x00201FDC, 0x002029B0, 0x00202A24, 0x00200FBC, +0x002029AF, 0x002025D4, 0x00117804, 0x00117810, +0x002029AC, 0x002029AD, 0x00200948, 0x00200994, +0x41216153, 0x41214121, 0x41214121, 0x45214521, +0x60534521, 0x6603C903, 0x0F65E048, 0xE0077118, +0xE0442209, 0x641D0F25, 0x65F3E04C, 0x0F46B291, +0x0EFDE048, 0x0DFDE044, 0x61DD67ED, 0x41084708, +0x0F16E050, 0xDD946073, 0x4D0B06FE, 0x6E07E00F, +0x607326E9, 0xE0400F66, 0x65F30CFE, 0x690D85C2, +0x01FEE050, 0x60934D0B, 0x6073260B, 0xE04C0F66, +0x04FEB256, 0x07FEE040, 0x6271E068, 0x0F56652D, +0x3563E640, 0xED008954, 0x0FD5E064, 0xC9036023, +0x40004008, 0x61036903, 0x0F96E054, 0xDE7EE058, +0x0FF6ECFF, 0xE06C6CCC, 0x60C30FE6, 0x62534E0B, +0x42214221, 0x42214221, 0x42006723, 0x6107327C, +0x4200E05C, 0x0F164521, 0x4521E040, 0x60530CFE, +0x4008C903, 0x7C0630FC, 0x6E031FC6, 0x1FD56D2D, +0x1F04A01E, 0x0FD6E060, 0x05FEE058, 0x64D3B231, +0x62E2E05C, 0xE05409FE, 0x2E222299, 0x64D361C4, +0x01FE661C, 0x07FEE06C, 0x6063470B, 0xE058220B, +0xB20505FE, 0xE0642E22, 0x7D0102FD, 0x0F257201, +0x02FDE064, 0x3262E606, 0xE0408BDC, 0x626106FE, +0x05FEE040, 0x85514200, 0x302C750C, 0x6103701B, +0x64F3E600, 0xE704A004, 0x76016256, 0x74042422, +0x3273626D, 0x65F38BF8, 0x641DB1E2, 0x06FEE040, +0x6461B19E, 0x0009A175, 0xD74DD44C, 0x470BE201, +0xA16E2D20, 0x88290009, 0xDE4A8B07, 0x2D20E200, +0xB16D66E2, 0xA164646D, 0xE2810009, 0x3020622C, +0xA0A78B01, 0xE0240009, 0x626C06FC, 0x666CE682, +0x8B213260, 0xE42452FA, 0xD43F2240, 0x12615647, +0x12625648, 0x12635649, 0x1264564A, 0x1265564B, +0x1266564C, 0x1267564D, 0x1268564E, 0x1269564F, +0x1427E200, 0x14291428, 0x142B142A, 0x142D142C, +0x142F142E, 0x1F6CA135, 0x666CE683, 0x8B073260, +0xE60052FA, 0xD22B2260, 0x6222D62C, 0x2622A129, +0x666CE690, 0x8B183260, 0xE60052FA, 0xD2282260, +0x6022E605, 0x2202CB20, 0x2262D226, 0x2262E600, +0x460BD625, 0xD2250009, 0x0009420B, 0xE601D224, +0xD2242262, 0xA10C4618, 0xE6B02262, 0x3260666C, +0xD5188B22, 0xD216D420, 0x75046D52, 0x6E52420B, +0x420BD21E, 0xD41E64D3, 0x450BD511, 0xD21B0009, +0x64E3420B, 0xD60ED41B, 0x0009460B, 0xE600E504, +0x3253626D, 0xA0EC8B01, 0x666D0009, 0x326C62D3, +0x22E07601, 0x4E19AFF4, 0xD214D413, 0xD4146542, +0x0009420B, 0x0009A0DD, 0x0020248C, 0x00202A44, +0x00200F72, 0x00117804, 0x00202538, 0x00202994, +0x001C3500, 0x001D4004, 0x00201056, 0x00200C1C, +0x001E212C, 0x001C3D30, 0x00202A5C, 0x00200FB4, +0x00202A70, 0x00202A78, 0x00117800, 0x00200FBC, +0x00202A7C, 0xD6AED4AD, 0x6262E040, 0x76046542, +0x2452352C, 0x62626563, 0x75045641, 0x1461362C, +0x62526653, 0x76085542, 0x1452352C, 0x55436262, +0x352C76EC, 0x65631453, 0x56446262, 0x362C7510, +0x66531464, 0x55456252, 0x352C7610, 0x65621455, +0xD69C5246, 0x1426325C, 0x55476262, 0x352C7604, +0x62621457, 0x76045548, 0x1458352C, 0x62626563, +0x75045649, 0x1469362C, 0x564A6252, 0x362C7504, +0x6653146A, 0x554B6252, 0x352C7604, 0x6262145B, +0x7604554C, 0x145C352C, 0x62626563, 0x7504564D, +0x146D362C, 0x62526653, 0x7604554E, 0x145E352C, +0x524F6562, 0x325CD684, 0x6262142F, 0x7694054E, +0x0456352C, 0x6263E044, 0x054E6662, 0x356C7244, +0xE0480456, 0x054E6622, 0xD67C356C, 0x62620456, +0x054EE054, 0x352C4229, 0x76040456, 0xE0586262, +0x4229064E, 0x52FA362C, 0xE6380466, 0xE0442260, +0xE048064E, 0x66421261, 0x56411262, 0x56421263, +0x56451264, 0x56431265, 0x56461266, 0x064E1267, +0x1268E040, 0xE050064E, 0x56441269, 0x064E126A, +0x126BE04C, 0xE054064E, 0x064E126C, 0x126DE058, +0xE044064E, 0xE200126E, 0xE0480426, 0x14212422, +0x14251422, 0x14261423, 0xE0400426, 0xE0500426, +0x04261424, 0x0426E04C, 0x0426E054, 0x0426E058, +0x7F701F6C, 0x6EF64F26, 0x6CF66DF6, 0x69F6000B, +0x614D4F22, 0x3123E240, 0xE21F8917, 0x89083127, +0xD550D44F, 0x450BE001, 0x67076642, 0xA00C2679, +0xE23F2462, 0x89083127, 0xD64AD749, 0xE00171E0, +0x5571460B, 0x25296207, 0x4F261751, 0x0009000B, +0x614D4F22, 0x3123E240, 0xE21F8915, 0x89073127, +0xD240D43F, 0x420B6642, 0x260BE001, 0x2462A00B, +0x3127E23F, 0xD73A8907, 0x5571D63A, 0x460B71E0, +0x250BE001, 0x4F261751, 0x0009000B, 0x4618E640, +0xD5354628, 0x22686252, 0x000B89FC, 0xE6800009, +0x46284618, 0x6252D530, 0x89FC2268, 0x0009000B, +0xE200A001, 0x32427201, 0x000B8BFC, 0xE6800009, +0x46284618, 0x6252D529, 0x8BFC2268, 0x0009000B, +0x4F222FE6, 0x6E537FFC, 0x2F42BFF1, 0xD62461E2, +0x1615E280, 0x421854E1, 0x55E21646, 0x16574228, +0x6EF257E3, 0x2E2B1678, 0x7F0426E2, 0xAFCE4F26, +0x2FC66EF6, 0x2FE62FD6, 0xDD194F22, 0xBFD66C53, +0xBFBB6E43, 0xBFD22DE2, 0x51D50009, 0x54D62C12, +0x55D71C41, 0x56D81C52, 0x4F261C63, 0x6DF66EF6, +0x6CF6000B, 0xE6006163, 0x4109A004, 0x76016256, +0x74042422, 0x8BF93612, 0x0009000B, 0x00202538, +0x001C36A0, 0x001C3CA0, 0x001C36F4, 0x001C3B88, +0x001C3704, 0x0020248C, 0x001C373C, 0x001C3700, +0x001C370C, 0x0009A109, 0x2FD62FC6, 0x4F222FE6, +0x6E636D73, 0x6C53B016, 0x64C357F4, 0xB02965E3, +0xB03D66D3, 0xB06D0009, 0xB0710009, 0xB0750009, +0xB08A0009, 0xB08D0009, 0x4F260009, 0x6DF66EF6, +0x6CF6A0B4, 0x3412D190, 0xD6900529, 0x2650D790, +0x2742000B, 0x2FD62FC6, 0x4F222FE6, 0x6E636D73, +0x6C53BFF0, 0x64C357F4, 0x66D365E3, 0x6EF64F26, +0x6CF66DF6, 0xD1872FE6, 0x66126E63, 0x92BC4418, +0x44084528, 0x45002629, 0x265B4408, 0x264B4400, +0x21624708, 0xD1804708, 0x217227EB, 0x6EF6000B, +0x4F222FE6, 0xE101DE7D, 0xBFABE40A, 0x62E32E12, +0xE100726C, 0x2212E401, 0x22122212, 0x22122212, +0x22422212, 0xE503E730, 0x2212E40A, 0x22122212, +0x22122212, 0x22122212, 0x22122212, 0x22122212, +0x22722212, 0x22122252, 0x22122212, 0x22122212, +0x22122212, 0xBF852212, 0xE600121A, 0x4F262E62, +0x6EF6000B, 0xE101D266, 0x2212E441, 0x2242000B, +0xD465D164, 0x2162E605, 0x2462000B, 0xD264D563, +0x88016050, 0xD4638B07, 0x60409668, 0x8B098801, +0xA0079665, 0xE6000009, 0x2262D45E, 0x88016040, +0xE6048B00, 0xAF5DE40A, 0xD25B2262, 0xE40AE601, +0x2262AF58, 0x2FC62FB6, 0x2FE62FD6, 0xDC574F22, +0x60C2ED00, 0xCB01EB64, 0x60C22C02, 0xA008C901, +0x3DB26E03, 0x60C28907, 0xC901E40A, 0x6E03BF42, +0x2EE87D01, 0x3DB28BF5, 0xD44D8B03, 0x420BD24D, +0xE40A0009, 0x6EF64F26, 0x6CF66DF6, 0x6BF6AF32, +0x8F014411, 0x6043604B, 0x0009000B, 0x2FC62FB6, +0x2FE62FD6, 0x7FFC4F22, 0xED00DC40, 0xEB6460C2, +0x2C02CB02, 0x2F0260C2, 0xA009C902, 0x3DB36E03, +0x60C28908, 0x2F02E40A, 0xBF13C902, 0x7D016E03, +0x8BF42EE8, 0x8B0B3DB3, 0xD236D437, 0x4F267F04, +0x6DF66EF6, 0x422B6CF6, 0x1FFF6BF6, 0x03C40340, +0x4F267F04, 0x6DF66EF6, 0x000B6CF6, 0xD52F6BF6, +0x60525651, 0x000B4628, 0x2FB6306C, 0x2FD62FC6, +0x4F222FE6, 0x4F024F12, 0x6E43BFF1, 0xDC286B03, +0xBFECDD28, 0x30B80009, 0x060A3C05, 0x46094609, +0x3D654601, 0x4209020A, 0x42094209, 0x8BF032E2, +0x4F164F06, 0x6EF64F26, 0x6CF66DF6, 0x6BF6000B, +0x4F222FE6, 0xE102DE1C, 0xE403E500, 0xBFD42E12, +0xE6062E52, 0xE7004618, 0x2E62E403, 0x4F262E72, +0x6EF6AFCB, 0x0009000B, 0x0025E720, 0x00202C3C, +0x00202998, 0x001C5814, 0x001C59D0, 0x001C5830, +0x001C6268, 0x001C59A4, 0x001C639C, 0x002029AD, +0x001C5804, 0x002029AC, 0x001C581C, 0x001C5860, +0x00202A90, 0x00200F72, 0x00202AA8, 0x001C1040, +0xCCCCCCCD, 0x10624DD3, 0x001D4004, 0x2F962F86, +0x2FB62FA6, 0x2FD62FC6, 0x4F222FE6, 0xE4007FE0, +0x4528E510, 0x67436C43, 0xE108A00F, 0x6043644D, +0x0F564008, 0xEE0060C3, 0x815125C1, 0x81538152, +0x157315E2, 0x751415E4, 0x624D7401, 0x8BED3213, +0xDA7251F1, 0x1A1154F2, 0xD1712A12, 0x56F455F3, +0x58F657F5, 0x21421141, 0x11521153, 0x11641165, +0x11761177, 0x11881189, 0xD96A6DF2, 0xDB6A52F7, +0x29D219D1, 0x2B221B21, 0xD868EB45, 0xE9B8EA50, +0x4A084B08, 0xA020699C, 0x6EEDEE00, 0x61E36DE3, +0x41084D08, 0x31EC3DEC, 0x41084D08, 0x60C33D8C, +0xD75F4108, 0x81D12DC1, 0x410860A3, 0x60C381D2, +0xE200317C, 0x81D33492, 0x1D131DD2, 0x8D01D456, +0xD4521D24, 0x65D3B03C, 0x64ED7E01, 0x8BDC34B2, +0xDB54D14E, 0xD24F6512, 0x1B514529, 0xD14C6412, +0x2B72674D, 0xD6506722, 0x1B734729, 0x2FD26922, +0x1B82689D, 0x26926912, 0x16A25A12, 0xDA465B14, +0x5C1616B4, 0x5D1816C6, 0x6EA216D8, 0x7F2016EA, +0x6EF64F26, 0x6CF66DF6, 0x6AF66BF6, 0x000B69F6, +0x664268F6, 0xC8036061, 0xE5008D04, 0xC9036061, +0x8B038802, 0x65635262, 0x24125124, 0x6053000B, +0x2FE62FD6, 0x7FEC4F22, 0x62536E53, 0x6D43E550, +0x4508E400, 0xE101A001, 0x60435224, 0x81212211, +0x60538123, 0x56E28122, 0x8BF53620, 0x16E4D22F, +0xE61464F3, 0x65E3420B, 0xE4FC65E1, 0x2E512549, +0x65F361F1, 0x2F112149, 0xD12854D1, 0xE614410B, +0x607157D1, 0x2701CB01, 0x7F141DE1, 0x6EF64F26, +0x6DF6000B, 0x2FE62FD6, 0x7FEC4F22, 0x66536E53, +0x6D43E5FC, 0x20596061, 0x2601CB01, 0x326052E2, +0x12E48B06, 0x31E051E2, 0x52D18B04, 0x1E22A002, +0x5664AFF0, 0x64F3D215, 0x420BE614, 0x67E165E3, +0x2719E1FC, 0x67F12E71, 0x271954D1, 0x65F3D10F, +0x410BE614, 0x52D12F71, 0xCB016021, 0x1DE12201, +0x4F267F14, 0x000B6EF6, 0x00006DF6, 0x0020259C, +0x002025A4, 0x00202594, 0x002025CC, 0x001000A0, +0x00101640, 0x001E2108, 0x001C3D00, 0x00200904, +0x2FC62FB6, 0x2FE62FD6, 0x7FFC4F22, 0x6022D225, +0x8D35C803, 0xDE242F01, 0xDB25DC24, 0xED01A016, +0xC9036061, 0x89158801, 0xD122D420, 0x0009410B, +0x65035603, 0xC8208561, 0xE0508903, 0x720102BE, +0xD21D0B26, 0x64E3420B, 0x21D2D11C, 0x66C252C1, +0x8BE53620, 0xDD1AEE01, 0x4E18A00E, 0xC9036061, +0x890D8801, 0xD713D416, 0x470BDB16, 0xD4160009, +0x65034B0B, 0x21E2D111, 0x66D252D1, 0x8BED3620, +0xC80460F1, 0xD2118907, 0x4F267F04, 0x6DF66EF6, +0x422B6CF6, 0x7F046BF6, 0x6EF64F26, 0x6CF66DF6, +0x6BF6000B, 0x001E2100, 0x002025A4, 0x0020259C, +0x00202538, 0x00200D42, 0x00200DC4, 0x001C3D30, +0x00202594, 0x00200D60, 0x002025CC, 0x00200100, +0xE601D203, 0x1265D503, 0x000B2252, 0x00001266, +0x001C1010, 0x0000C34F, 0xD62A7FFC, 0x2642644C, +0xC8205066, 0x2F028DFC, 0x7F04000B, 0x2FD62FC6, +0x4F222FE6, 0x6D436C53, 0xEE00A004, 0x7E0164D4, +0x644CBFEA, 0x8BF93EC2, 0x6EF64F26, 0x000B6DF6, +0xA0016CF6, 0x76016643, 0x22286260, 0x36488BFB, +0x6563AFE4, 0x62532FE6, 0x67537507, 0xEE0AE108, +0xC90F6043, 0x30E24409, 0x44096503, 0xE6378D01, +0x365CE630, 0x27604110, 0x77FF8FF2, 0x8028E000, +0x6EF6000B, 0xE000000B, 0xE000000B, 0x4F222FE6, +0x62537FEC, 0x65F36E43, 0x6423BFDC, 0x64E3BFD1, +0x64F3BFCF, 0xBFCCD404, 0x7F140009, 0x000B4F26, +0x00006EF6, 0x001C0004, 0x00202AC4, 0xE110D5A1, +0xE6406050, 0x2500C9FD, 0xE0FF75E9, 0x80516453, +0x80538052, 0x80568055, 0x251075EF, 0xE1EF6250, +0x2219E001, 0xE7202520, 0x24608052, 0x2570000B, +0xE4FDD595, 0xE7026152, 0x25122149, 0x74016052, +0x2502CB01, 0xD1916652, 0x25622649, 0x92C46012, +0x2102CB08, 0xC9CF6012, 0x60122102, 0x2102CB03, +0x000B1172, 0x4F221123, 0xD78AD589, 0xD48BD28A, +0xE600E100, 0x27112511, 0xBFBF2210, 0xAFD72461, +0x664C4F26, 0x4600D286, 0x6060362C, 0x000BCB10, +0x654C2600, 0x4500D282, 0x6650352C, 0x2619E1EF, +0x2560000B, 0xD27F664C, 0x362C4600, 0xCB106060, +0x2600000B, 0xD27B654C, 0x352C4500, 0xE1EF6650, +0x000B2619, 0x664C2560, 0x4600D275, 0x6060362C, +0x000BCB08, 0x654C2600, 0x4500D271, 0x6650352C, +0x2619E1F7, 0x2560000B, 0xD26E664C, 0x362C4600, +0xCB086060, 0x2600000B, 0xD26A654C, 0x352C4500, +0xE1F76650, 0x000B2619, 0x624C2560, 0x4200D664, +0x6020326C, 0x4021C908, 0x40214021, 0x600C000B, +0xD660624C, 0x326C4200, 0xC9086020, 0x40214021, +0x000B4021, 0x644C600C, 0x74FFD15B, 0x6240341C, +0x602C000B, 0x644CD159, 0x6240341C, 0x602C000B, +0x4F222FE6, 0xE60A655C, 0x8D153567, 0xBFEA6E43, +0x640C6453, 0x880160EC, 0xE00F8B02, 0x2409A002, +0x44094409, 0xE60A624C, 0x89053263, 0x644CBFE2, +0x6023620C, 0x8B00C880, 0x6023E200, 0x000B4F26, +0x4F226EF6, 0x6062D646, 0x8B038801, 0x0009B241, +0x0009A003, 0xE640D243, 0xD6432260, 0x4F26E200, +0x2622000B, 0xD63E4F22, 0x88026062, 0xB28B8B01, +0xD63D0009, 0x4F26E200, 0x2622000B, 0xD439D538, +0xE701E100, 0x000B2512, 0x0FFF2470, 0xE604D235, +0x2260000B, 0xD4354F22, 0x410BD135, 0xD5250009, +0x6650E1FD, 0x2619D233, 0x2560E700, 0x000B4F26, +0x4F222270, 0xD12ED430, 0x0009410B, 0xE7FBD51D, +0x26796650, 0x000B4F26, 0x4F222560, 0xD128D42B, +0x0009410B, 0xE7F7D517, 0x26796650, 0x000B4F26, +0xD5142560, 0x62509425, 0x000B2249, 0xD5112520, +0x6250E4BF, 0x000B2249, 0x4F222520, 0x8522D220, +0x2008600D, 0x88018911, 0x8803893C, 0x8805893E, +0x88068940, 0x88088946, 0x8809894C, 0x880A8952, +0x880B8958, 0xA065895E, 0xB0670009, 0xA0620009, +0xFF7F600C, 0x001E1028, 0x001E2148, 0x001E1108, +0x002029DC, 0x002029DE, 0x002029E9, 0x002029C0, +0x001E103F, 0x001E105F, 0x001E1030, 0x001E1090, +0x002029E4, 0x001E100B, 0x002029E0, 0x00202AC8, +0x00200F72, 0x002029E8, 0x00202AD4, 0x00202AE4, +0x002029B4, 0x0009B04C, 0x600CA035, 0x0009B056, +0x600CA031, 0x6260D67C, 0x8B2B2228, 0x0009B062, +0x600CA029, 0x6260D678, 0x8B232228, 0x0009B06A, +0x600CA021, 0x6260D674, 0x8B1B2228, 0x0009B0B4, +0x600CA019, 0x6260D670, 0x8B132228, 0x0009B0BA, +0x600CA011, 0x6260D66C, 0x8B0B2228, 0x0009B11A, +0x600CA009, 0x6260D668, 0x8B032228, 0x0009B132, +0x600CA001, 0x4F26E000, 0x0009000B, 0xD264D163, +0xD5648412, 0x4000C90F, 0xD763012D, 0x611CE403, +0xD662E20F, 0x27122540, 0xE0012520, 0x2602000B, +0xE601D25A, 0x30668523, 0xE0008D06, 0xE000D258, +0x8122D65A, 0x2602E001, 0x0009000B, 0x8523D253, +0x2008600D, 0x88018905, 0xD6558B0A, 0xCB016060, +0xD6522600, 0xE101D44E, 0x2612E001, 0x8142000B, +0xE000000B, 0xE501D149, 0x45188513, 0x3453640D, +0x8D056603, 0xD24BE000, 0xE001D548, 0x25022260, +0x0009000B, 0xD1414F22, 0x650D8513, 0x44196453, +0x672E6249, 0x602C227D, 0x89098801, 0x890C8802, +0x89108803, 0x89268806, 0x89298807, 0x0009A038, +0xD63ED53D, 0xA027E212, 0x625C2652, 0x8B2F2228, +0xA01ED63B, 0x605C6262, 0x89052008, 0x89088810, +0x890B8820, 0x0009A024, 0xD634D436, 0xA013E204, +0xD7352642, 0xE20CD631, 0x2672A00E, 0xD62FD533, +0xA009E218, 0xD4322652, 0xE20AD62C, 0x2642A004, +0xD62AD230, 0xE22E2622, 0xD42F8515, 0x3277670D, +0x8F012421, 0x24516503, 0x0009B0DB, 0xE001A001, +0x4F26E000, 0x0009000B, 0xE101D61A, 0x2610D427, +0xD7196541, 0x655DD119, 0xE001E20F, 0x26202752, +0x2102000B, 0x4F222FE6, 0x8523D210, 0x2448640C, +0xD61E8B08, 0xE200D512, 0x84512621, 0x20499412, +0x8051A050, 0x60E0DE0E, 0x8D35C840, 0x3427E201, +0xD116894C, 0x420BD216, 0xD5162141, 0xCB046052, +0x2502A035, 0x0000FF7F, 0x002029E9, 0x002029B4, +0x002029C0, 0x001E1100, 0x001E100C, 0x002029E0, +0x001E1000, 0x001E1001, 0x00202C40, 0x002029C8, +0x002029D0, 0x00202CAE, 0x00202CB2, 0x00202CBE, +0x00202CD6, 0x00202CE0, 0x002029CC, 0x002029DA, +0x00201DB6, 0x001E1108, 0x89173427, 0xD794D293, +0x2241470B, 0xE5FBD693, 0x21596162, 0x84E12612, +0xB0FFCB80, 0x60E080E1, 0xCB04D68F, 0x60602E00, +0x2600C93F, 0xE001D68D, 0x2602A001, 0x4F26E000, +0x6EF6000B, 0x6060D68A, 0x8919C880, 0x6021D283, +0x8B158801, 0xE501D287, 0x30568524, 0xD1868910, +0xD486E203, 0x65412120, 0x655DE00B, 0xD5840656, +0xE702E40F, 0x25712140, 0xE001D77C, 0x2702000B, +0xE000000B, 0x4F222FE6, 0x84E1DE7E, 0x8934C880, +0x8554D578, 0x8F302008, 0xD77B6103, 0x66728553, +0x650C6403, 0x620C8566, 0x8B263520, 0xD773D677, +0x644C651C, 0x27412651, 0xC84060E0, 0xD2748907, +0x0009420B, 0x6062D667, 0xA008CB04, 0xD1642602, +0x0009410B, 0xE5FBD663, 0x24596462, 0xB0A12642, +0xD5620009, 0x2522E201, 0xD75F60E0, 0x2E00CB04, +0xC93F6070, 0xA0012700, 0xE0006023, 0x000B4F26, +0x2FA66EF6, 0x2FC62FB6, 0x2FE62FD6, 0xE240DA5C, +0xDC5966A1, 0x3123616D, 0x62638900, 0x6ED36D2C, +0x4E2136D8, 0x4E212A61, 0xDB5BD45A, 0xE700A00F, +0x770166B2, 0x71026163, 0x65612B12, 0x71026613, +0x62612B12, 0x622D655D, 0x325C4228, 0x627C2422, +0x8BED32E3, 0xC90360D3, 0x8B108803, 0xED076EB2, +0x710261E3, 0x67132B12, 0x62E17102, 0x65712B12, +0x655D622D, 0x352C4528, 0xA00C2CD0, 0x88022452, +0xA0038B01, 0x8801E203, 0xE2018B05, 0x66B22C20, +0x677D6761, 0xEB0F2472, 0x6DA12CB0, 0x8B052DD8, +0xD432D23E, 0xE101EE00, 0x241222E2, 0x6DF66EF6, +0x6BF66CF6, 0x6AF6000B, 0x2FE62FD6, 0xE240DD30, +0x616D66D1, 0x89003123, 0x672C6263, 0xDE323678, +0x2D617703, 0xD62F4721, 0x472164E2, 0xE100A00E, +0x71016562, 0x24506253, 0x42197401, 0x74012420, +0x24504529, 0x45197401, 0x74012450, 0x3273621C, +0x42008BEE, 0x64D166E2, 0x362C4200, 0x8F062448, +0xDD222E62, 0xE500DE15, 0x2D52E701, 0x6EF62E72, +0x6DF6000B, 0x2FE62FD6, 0xEE014F22, 0xED0AA005, +0x64E3BC97, 0x64E3BC9D, 0x62EC7E01, 0x8BF732D7, +0xEE01A005, 0x64E3BC9E, 0x64E3BCA4, 0x62EC7E01, +0x8BF732D7, 0x6EF64F26, 0x6DF6000B, 0x002029DA, +0x00201EC2, 0x001E1108, 0x001E1015, 0x002029E0, +0x001E1001, 0x002029B4, 0x001E1100, 0x002029DE, +0x002029CC, 0x001E1000, 0x002029D0, 0x002029DC, +0x00201DB6, 0x001E100C, 0x002029C8, 0x002029E4, +0x2FE62FD6, 0x7FFC4F22, 0x6060D64C, 0x89488801, +0xE101D44B, 0xD74B8548, 0x650D2610, 0x45196070, +0x6659DD49, 0x61D3626E, 0xC840262D, 0x74027102, +0x8D1AD746, 0xD246666C, 0xE501DE46, 0xA0042E22, +0x6245EE04, 0x21217501, 0x625C7102, 0x8BF832E3, +0x81D46063, 0xD540E601, 0x626CE417, 0x891E3243, +0x76016255, 0xAFF82721, 0xD23C7702, 0xE501DE39, +0xA0042E22, 0x6245EE04, 0x21217501, 0x625C7102, +0x8BF832E3, 0x81D46063, 0xD535E601, 0xE417A004, +0x76016255, 0x77022721, 0x3243626C, 0x924B8BF8, +0xD4302D21, 0x6142D730, 0x65F22F12, 0x60536DF2, +0x2700C980, 0xC9606053, 0x80716103, 0x6EF26053, +0xC90365F2, 0x45294D19, 0x60DC8072, 0x81724519, +0x605C4E29, 0x401862EC, 0x8173302C, 0x21186D42, +0x6EF22FD2, 0x66F262F2, 0x46294219, 0x66F2656C, +0x64EC602C, 0x46294018, 0x4619304C, 0x606C8174, +0x305C4018, 0x81758F07, 0x0009BCBF, 0x2228620C, +0xA00A8908, 0x60130009, 0x8B038840, 0x0009B00A, +0x0009A003, 0xE202D611, 0x7F042622, 0x6EF64F26, +0x6DF6000B, 0x0009000B, 0x0000060A, 0x002029E8, +0x00202C40, 0x001E1000, 0x00202CD6, 0x00202CE2, +0x00202C52, 0x002029D0, 0x00202C82, 0x00202C80, +0x00202C54, 0x001E100C, 0x002029B4, 0x002029E0, +0x4F222FE6, 0xDE907FFC, 0x200884E9, 0x2F008D06, +0xD68FD48E, 0x0009460B, 0x64F0B146, 0x6620D28D, +0x89022668, 0xC9BF60E0, 0x7F042E00, 0x000B4F26, +0x000B6EF6, 0x2FE60009, 0xDE874F22, 0x60E0D687, +0xCBC0D487, 0x62602E00, 0xC803602C, 0x40218904, +0x70014021, 0x6603A002, 0x66034009, 0xD681616D, +0xE500A004, 0x75016262, 0x74042422, 0x3213625D, +0xD27D8BF8, 0x0009420B, 0xC9BF84E2, 0x4F2680E2, +0x6EF6000B, 0x2FD62FC6, 0x4F222FE6, 0xDC727FFC, +0x84C2D276, 0xCB40DD76, 0x80C2420B, 0x8D042008, +0x62E06E03, 0xA006642C, 0xD66A7404, 0x6160D471, +0x470BD771, 0x644D651C, 0x45216543, 0xA0044521, +0x62E6E600, 0x2F227601, 0x626D2D22, 0x8BF83253, +0xC9036043, 0x89122008, 0x89058803, 0x89068802, +0x89078801, 0x0009A008, 0xA005E007, 0xE00380D8, +0x80D8A002, 0x80D8E001, 0x2F2262E2, 0xE00F2D22, +0x80D8D65E, 0xCB086060, 0x60C02600, 0x2C00C93F, +0x4F267F04, 0x6DF66EF6, 0x6CF6000B, 0x2FC62FB6, +0x2FE62FD6, 0xD2564F22, 0x6E436D73, 0x420B6B53, +0x20086C63, 0x64038F08, 0xD245D452, 0x6EF64F26, +0x6CF66DF6, 0x6BF6422B, 0x24E060B3, 0x60C38041, +0xA0078141, 0x655DE500, 0x00DC6053, 0x324C6253, +0x80247501, 0x6EEC625D, 0x8BF432E3, 0x6060D636, +0x2600C9BF, 0x6EF64F26, 0x6CF66DF6, 0x6BF6000B, +0x7FC44F22, 0x720262F3, 0x22512F41, 0x45297202, +0x60632251, 0xE5C4E682, 0x67F38121, 0x655C666C, +0xE408BFBC, 0x4F267F3C, 0x0009000B, 0xD237D136, +0xE4056012, 0xE500CB20, 0x22422102, 0x2252000B, +0xD534D133, 0xE400D734, 0x2142E20F, 0x17411154, +0xD5322722, 0x9635D732, 0x15412572, 0x96321562, +0xE6011565, 0xD52F1165, 0x666CE6F8, 0x25422542, +0x25422542, 0x25422542, 0x25622542, 0x7601E727, +0x67632572, 0x25627797, 0xE7042572, 0x2572E248, +0xE2192522, 0xE2702522, 0x25422542, 0x25422542, +0x25222542, 0x2522E20C, 0x25422542, 0x25422542, +0x25422542, 0x25422542, 0x000B154A, 0xE2081145, +0x0009422B, 0x51630601, 0x001E1017, 0x00202AF0, +0x00200F72, 0x002029B0, 0x001E1015, 0x001E10BF, +0x00117800, 0x001E10FC, 0x00200100, 0x0020201A, +0x001E10F8, 0x00202AF4, 0x00200FBC, 0x001E10AE, +0x00201FDC, 0x00202B10, 0x001C3500, 0x001D4004, +0x001C581C, 0xA000A000, 0x001D0100, 0x001D4000, +0x00040021, 0x001C589C, 0x2FE62FD6, 0x7FFC4F22, +0xC8206043, 0x6E438D02, 0x0009BEBB, 0xC81060E3, +0xBEB88901, 0x60E30009, 0x8901C840, 0x0009BEDA, +0xC80160E3, 0xDD378936, 0xC80260D0, 0x2F008D03, +0x460BD635, 0x60F00009, 0x8902C804, 0x460BD633, +0x62F00009, 0xC8806023, 0x60D08902, 0x2D00C97F, +0xC8016023, 0xD62E8904, 0x0009460B, 0x0009A005, +0x8902C808, 0x460BD62B, 0x60F00009, 0x8902C810, +0x420BD229, 0xD5290009, 0x88026052, 0xD2288B03, +0xA005E604, 0x88012260, 0xD2258B02, 0x2260E601, +0x2522E200, 0xC88060E3, 0xD622892E, 0x60E36E60, +0x8902C880, 0x420BD220, 0x60E30009, 0x8902C840, +0x420BD21E, 0x60E30009, 0x8902C802, 0x420BD21C, +0x60E30009, 0x890EC804, 0x410BD11A, 0xBF150009, +0xBF1D0009, 0xD5180009, 0x6050D418, 0xC908D718, +0xBF542500, 0x60E32472, 0x8905C808, 0x7F04D215, +0x6EF64F26, 0x6DF6422B, 0x4F267F04, 0x000B6EF6, +0x00006DF6, 0x001E1021, 0x00201182, 0x002011A4, +0x002017B0, 0x002011BC, 0x002011CC, 0x002029E0, +0x001E100B, 0x001E1028, 0x00201222, 0x0020122E, +0x002011D4, 0x002011F2, 0x001E1000, 0x0010F100, +0x12345678, 0x0020120A, 0xD6A8644C, 0x346C74FF, +0x2450000B, 0x644CD6A6, 0x000B346C, 0xD6A52450, +0x346C644C, 0x2450000B, 0x616D625C, 0x41194208, +0x60194208, 0x644C4200, 0x324C670E, 0x207DD19E, +0xC90F4200, 0x000B321C, 0x67632200, 0x4208625C, +0x42004208, 0x324C644C, 0x4200D198, 0x000B321C, +0x2FE62270, 0x614C4F12, 0x4100D493, 0x6710314C, +0x2729E29F, 0x65736E53, 0x4719676D, 0x672E6279, +0x4221227D, 0x42214221, 0x7601662C, 0xE4014608, +0x34E84608, 0x644C4600, 0x0E1A0467, 0x215025EB, +0x000B4F16, 0x4F226EF6, 0xD2857FE8, 0x88016021, +0xD2848B7B, 0x26686621, 0xD2838B77, 0x26686621, +0xE50F8B73, 0xE401BFA0, 0xBFA3E501, 0xE586E400, +0xE400655C, 0x2F50BFA3, 0xBFA0E401, 0xE602E506, +0x60634618, 0x81F2E401, 0x6543BF9E, 0xE40185F2, +0xBFAA6543, 0x85F26603, 0x6543E401, 0x6603BFB1, +0xE40265F0, 0x6053756C, 0x80F8BF7E, 0xBF81E402, +0x84F8E512, 0x7090E402, 0x6503BF81, 0x4618E602, +0x81F66063, 0xBF7FE402, 0x85F6E500, 0x6603E402, +0xE500BF8B, 0xE40285F6, 0xBF926603, 0xE5FEE500, +0xE010655C, 0xBF5FE403, 0xE5130F54, 0xE40EBF62, +0x05FCE010, 0xBF62E40E, 0xE5007585, 0xBF63E403, +0xE500E640, 0xBF70E403, 0xE500E640, 0xBF78E403, +0xE5FFE640, 0xE014655C, 0xBF45E404, 0xE40F0F54, +0xE504BF48, 0x05FCE014, 0xBF48E40F, 0xE5017584, +0xBF49E640, 0xE501E404, 0xBF56E640, 0xE501E404, +0xE404E640, 0xAF5C7F18, 0x7F184F26, 0x000B4F26, +0x4F220009, 0xD2427FF0, 0x88016021, 0xD2418B71, +0x26686621, 0xD2408B6D, 0x26686621, 0xE50F8B69, +0xE401BF1A, 0xBF1DE501, 0xE586E400, 0xE400655C, +0x2F50BF1D, 0xBF1AE401, 0xE401E506, 0xBF1B6543, +0xE401E640, 0xBF286543, 0xE401E640, 0xBF306543, +0x65F0E640, 0x756CE402, 0xBEFD6053, 0xE40280F4, +0xE512BF00, 0xE40284F4, 0xBF007090, 0xE6406503, +0xBF01E402, 0xE640E500, 0xBF0EE402, 0xE640E500, +0xBF16E402, 0xE5FEE500, 0x6053655C, 0xBEE3E403, +0xE51380F8, 0xE40EBEE6, 0xE40E84F8, 0xBEE67085, +0xE5006503, 0xBEE7E640, 0xE500E403, 0xBEF4E640, +0xE500E403, 0xBEFCE640, 0xE5FFE403, 0x6053655C, +0xBEC9E404, 0xE40F80FC, 0xE504BECC, 0xE40F84FC, +0xBECC7083, 0xE5016503, 0xBECDE640, 0xE501E404, +0xBEDAE640, 0xE501E404, 0xE404E640, 0xAEE07F10, +0x7F104F26, 0x000B4F26, 0x00000009, 0x001E1030, +0x001E1080, 0x001E1090, 0x001E103F, 0x001E103E, +0x002029DA, 0x002029DC, 0x002029DE, 0xD21DD11C, +0x66206010, 0x676C7001, 0x3700C90F, 0xE5008D13, +0x67106210, 0x7701622C, 0x64232170, 0xD6166010, +0x44084408, 0x3428C90F, 0x62602100, 0x7201D513, +0x44082620, 0x000B354C, 0xD10F6053, 0x25586510, +0xE6008D13, 0xD60DD40B, 0x655C6540, 0x47086753, +0x37584708, 0x47086540, 0x24507501, 0x367C6040, +0x2400C90F, 0x72FF6210, 0x000B2120, 0x00006063, +0x002029AF, 0x002029AE, 0x002029B0, 0x002025D4, +0x7FFC4F22, 0xE680D19D, 0x666C6212, 0xD29C2F22, +0x67F36563, 0x420B7542, 0x7F04E404, 0x000B4F26, +0xE6800009, 0xD296666C, 0xE7006563, 0x422B7540, +0xE6806473, 0xD292666C, 0xE7006563, 0x422B7543, +0x2FB66473, 0x2FD62FC6, 0x4F222FE6, 0x4D18ED01, +0xDB8DDC8C, 0x65C252C1, 0x89203520, 0xC9036051, +0x891C8801, 0xD189DE87, 0x64E3410B, 0x85036503, +0x670D66B2, 0x89073762, 0xD286D485, 0x0009420B, +0xE701D185, 0x2172AFE6, 0xDE8464E3, 0x00094E0B, +0xD484D683, 0x410BD184, 0xAFDB26D2, 0x4F260009, +0x6DF66EF6, 0x000B6CF6, 0x4F226BF6, 0x85467FF4, +0x2F01E681, 0x666C8547, 0x854881F1, 0x81F2D270, +0x67F38542, 0x854381F3, 0x81F4E40C, 0x65636053, +0x420B81F5, 0x7F0C7540, 0x000B4F26, 0x2F860009, +0x2FA62F96, 0x2FC62FB6, 0x2FE62FD6, 0x7FF44F22, +0xDC6EE200, 0x2F21A136, 0xDD6D6A13, 0xE0014A08, +0x4D0BD96C, 0x3A9C4A00, 0x1F917930, 0x66C21F02, +0x362052C1, 0xA1218B01, 0x60610009, 0x8801C903, +0xA11B8B01, 0x85610009, 0x8977C801, 0x85D25D63, +0xC9036603, 0x85D36403, 0x6053650D, 0x40214021, +0x4500C93F, 0x322A6103, 0x6053252D, 0xC901E210, +0xD9553123, 0x6E038D21, 0x4408D757, 0x44086570, +0x44006213, 0x25584200, 0x342C8F0E, 0x6043D253, +0x60E3072D, 0x4B196B7D, 0x658E68B9, 0x285D8801, +0x6B7C8F0B, 0x6B13A009, 0x6043D24D, 0x61ED0E2D, +0x68194119, 0x287D678E, 0xD14A6BEC, 0x22286212, +0xEBFF8901, 0xEEFF6BBC, 0x6EEC65BD, 0x8B0F35E0, +0x4D0BDD36, 0x540364C3, 0xBF76E502, 0xD4426D03, +0x410BD136, 0xD74165D3, 0xD441EE01, 0x27E2A01D, +0x26E9EEFC, 0x81D26063, 0x914E85D3, 0x81D32019, +0x450885D2, 0x81D2208B, 0xE20885D3, 0x81D3205B, +0x421885D4, 0x81D4202B, 0x854164C2, 0x814120E9, +0xD43465C2, 0xCB016051, 0x490B2501, 0x60C20009, +0x52F256F1, 0x2A02CB01, 0x2622AF79, 0x420BD21B, +0x5E0364C3, 0x85E16D03, 0x6053650D, 0x897BC820, +0x6210D129, 0x8B112228, 0xD72785EF, 0x4221620D, +0x42214221, 0xE501D625, 0x27504221, 0xD725D924, +0x2621D425, 0x2960E600, 0x24612762, 0x852162C2, +0x8B43C802, 0xD912D71E, 0xE0016270, 0x612C490B, +0x6692D91C, 0xA03E260B, 0x7E032962, 0x001C3D9C, +0x00201A3C, 0x002025CC, 0x00202994, 0x00200D42, +0x00202594, 0x00200DC4, 0x001E2130, 0x00200D60, +0x001C3D30, 0x00202C28, 0x00200F72, 0x002025A4, +0x0020248C, 0x001C3D00, 0x00202C3C, 0x00202B28, +0x00202BA8, 0x002029A8, 0x0020259C, 0x001E212C, +0x00202C2C, 0x00202C30, 0x00202D10, 0x002029EE, +0x002029EC, 0x002029F0, 0x002029F4, 0xE04CD139, +0x7201021E, 0xD9380126, 0x6290D438, 0x72016541, +0x29207501, 0x85E12451, 0x4618E640, 0x891D2068, +0xD934D733, 0x665D6171, 0x6592D733, 0x641D470B, +0xE200DE32, 0x2E20A012, 0xE90885E4, 0x49186203, +0x32902299, 0xE5018B04, 0x64E3BEB7, 0x0009A006, +0x2598D92B, 0xE5008902, 0x64E3BEAF, 0xD22AD429, +0x65D3420B, 0xEE01D729, 0x27E2AED9, 0x7C0862F1, +0x2F217201, 0xEE0462F1, 0x31E7612D, 0xAEC38901, +0x7F0C0009, 0x6EF64F26, 0x6CF66DF6, 0x6AF66BF6, +0x000B69F6, 0x2FE668F6, 0xD21D4F22, 0x60E36E22, +0x8D02C840, 0xBE3322E2, 0xE2400009, 0x2E284218, +0xBE3E8901, 0x60E30009, 0x8905C810, 0xD216D415, +0x0009420B, 0x0009BE3D, 0xC80560E3, 0xBE8E8901, +0x60E30009, 0x8902C802, 0xAE3A4F26, 0x4F266EF6, +0x6EF6000B, 0x00202538, 0x002029EC, 0x002029F4, +0x002029EE, 0x002029F0, 0x00201AA0, 0x00202D10, +0x00008000, 0x0020259C, 0x00200D60, 0x001E212C, +0x001C3510, 0x00202C34, 0x00200F72, 0x080A0C0E, +0x00020406, 0x1A1C1E20, 0x12141618, 0x2E303234, +0x26282A2C, 0x3A3C3E40, 0x6C625648, 0x41112F26, +0xE2208F18, 0x890B3123, 0x321CD204, 0xD1026220, +0x412B312C, 0x00090009, 0x002024B6, 0x0020246C, +0x000BE000, 0x400062F6, 0x40004000, 0x40004000, +0x40004000, 0x62F6000B, 0x40004000, 0x40004000, +0x40004000, 0x40184000, 0x62F6000B, 0x40004000, +0x40004000, 0x40004000, 0x40284000, 0x62F6000B, +0x40004000, 0x40184000, 0x000B4028, 0xC90F62F6, +0x40054005, 0x40054005, 0x62F6000B, 0x4005C907, +0x40054005, 0x62F6000B, 0x4005C903, 0x000B4005, +0xC90162F6, 0x000B4005, 0x000062F6, 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, +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, 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, 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, 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, +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, 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, 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, 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, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x544F0D0A, 0x46205355, +0x00003A57, 0x2079614D, 0x32203033, 0x20373030, +0x333A3231, 0x38313A37, 0x00000000, 0x00000D0A, +0x00000043, 0x42707372, 0x3D206675, 0x554E203D, +0x202C4C4C, 0x6E49677A, 0x4E497274, 0x6D754E51, +0x0000003D, 0x61766E49, 0x2064696C, 0x72657375, +0x20726F20, 0x2079656B, 0x00214449, 0x52504545, +0x57204D4F, 0x65746972, 0x6461202C, 0x003D7264, +0x6C617620, 0x0000003D, 0x00000A0D, 0x6E6B6E55, +0x206E776F, 0x6D6D6F63, 0x3D646E61, 0x00000000, +0x61437748, 0x7262696C, 0x6F697461, 0x6620206E, +0x0A6C6961, 0x0000000D, 0x73696F4E, 0x61432065, +0x7262696C, 0x6F697461, 0x6166206E, 0x21216C69, +0x00000D0A, 0x00000D0A, 0x62735576, 0x7473725F, +0x00000A0D, 0x62735576, 0x7375735F, 0x646E6570, +0x00000A0D, 0x62735576, 0x7365725F, 0x000A0D6D, +0x00000042, 0x72746E49, 0x6D652051, 0x2C797470, +0x49677A20, 0x4972746E, 0x754E514E, 0x00003D6D, +0x20746F4E, 0x756F6E65, 0x49206867, 0x4220514E, +0x0A0D6675, 0x00000000, 0x000000FF, 0x00020001, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x010E010D, 0x00020003, +0x01090108, 0x0002010A, 0x00030002, 0x02020201, +0x02040203, 0x02060205, 0x02080207, 0x020A0209, +0x020C020B, 0x020E020D, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x010E010D, 0x00FF010F, +0x01090108, 0x010B010A, 0x00030002, 0x02020201, +0x02040203, 0x02060205, 0x02080207, 0x020A0209, +0x020C020B, 0x020E020D, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00205220, 0x00000046, +0x00000059, 0x49544120, 0x0000204D, 0x00000000, +0x02000112, 0x40FFFFFF, 0x91700CF3, 0x20104890, +0x02090100, 0x0101002E, 0x09FA8000, 0x04000004, +0x000000FF, 0x02010507, 0x07000200, 0x00028205, +0x05070002, 0x00400383, 0x04050701, 0x01004003, +0x002E0209, 0x80000101, 0x000409FA, 0x00FF0400, +0x05070000, 0x00400201, 0x82050700, 0x00004002, +0x03830507, 0x07010040, 0x40030405, 0x03040100, +0x030C0409, 0x0079005A, 0x00410044, 0x03180053, +0x00530055, 0x00320042, 0x0030002E, 0x00570020, +0x0041004C, 0x0000004E, 0x00000000, 0x00000000, +0x00000709, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, }; + +const u32_t zcFwImageSize=11540; --- linux-2.6.28.orig/drivers/staging/otus/hal/hpfwbu.c +++ linux-2.6.28/drivers/staging/otus/hal/hpfwbu.c @@ -0,0 +1,5269 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "../80211core/cprecomp.h" + +const u32_t zcFwBufImage[] = { +0x3A4BCF18, 0xF44C076E, 0xF59452EA, 0x451BA755, +0x140AC87A, 0xC07EE942, 0x3EF978AB, 0xF5B03DC6, +0xB70080F0, 0xA89064EA, 0x54E2C1D6, 0xEB047DF4, +0x1798390C, 0x00350624, 0x35B3ECF0, 0x59F2FABF, +0xAF9D248E, 0xF9BDB9F0, 0xD05C8B47, 0xC08B5A16, +0x990093C7, 0xD335A160, 0x1C04942C, 0xBF6E7A88, +0xFD232B0F, 0x5C224387, 0xBF1E156C, 0xF24F2A27, +0xFF56421D, 0xB213037C, 0x2BA67BA0, 0x4950CF8A, +0x05F00F25, 0xA5E82085, 0x74168A0C, 0x2F2AB30B, +0xC80C57EE, 0xB6BDF570, 0x89BC5A99, 0x7F3B5A67, +0xF6C943B8, 0x0C9C9201, 0xE8383747, 0x0C9A72D6, +0xE0520704, 0xA66D7F30, 0xE444A434, 0xE0C94AB7, +0x8DD7751C, 0x1A659464, 0x6C9ABA4F, 0x792F2D2D, +0x5936F66B, 0x061E580E, 0x59903F6C, 0x1FBFB8A0, +0xCC822EFE, 0x4B030CAF, 0xB62457C9, 0x27E9BF15, +0xB113A487, 0xFA0FC915, 0x447B184A, 0x5330CD51, +0x00BCC622, 0xF30DE149, 0xFF718E1C, 0x7B5D2861, +0xDBCA573E, 0xFB0D7BF9, 0xE1CFBAAC, 0xF99D4583, +0x4BA7498A, 0x7CAEA7EB, 0xBA958E32, 0x36C530FF, +0x8F88CA99, 0xF93CABC2, 0x8E47EF11, 0xFB0EED6F, +0x5B3668A1, 0x9D63ADDE, 0xA0EEAB8C, 0x084915F1, +0xFACAAA27, 0x209638FE, 0x1CED9EFF, 0xEEBD2335, +0x38C6F424, 0x2D1F3D7E, 0x976E8106, 0xBE087AD2, +0x32194845, 0x756066DB, 0xC70E3165, 0xC568DCB1, +0x3212E4E1, 0xB5D991AD, 0x07C3CEF8, 0xDB4ABB38, +0x1574C232, 0xF8C792BC, 0x14E62DBE, 0x5A48E7DC, +0xEFDC5407, 0xC45B4017, 0x3B814E89, 0xF0936466, +0x89491B2B, 0x9A359A41, 0x82287675, 0xA0F338D3, +0x523FDD3C, 0x4E40B795, 0x458ADAA4, 0xED812957, +0x7ADC73BC, 0x6FD7DB78, 0x2740FC04, 0x6392AEA3, +0x185ABCEA, 0x6B50ABC3, 0x3681F07F, 0xC840F8CE, +0x5733E7EC, 0x0805FA71, 0x0B34530A, 0x8CB3D033, +0x81451551, 0x53B0B4EC, 0x908646D0, 0x10A3E642, +0xF358DC34, 0xC1FA570C, 0x2B1284B0, 0x592322BB, +0x9D587783, 0xE7D77988, 0xE1BE5D7B, 0x44B93E23, +0xF8BE94A2, 0x506DC723, 0x6E0A7D09, 0x3FB1046F, +0xDB3A166F, 0x9CB7D6A0, 0xE278DE6D, 0x88459334, +0xB52BA3C9, 0x284740A2, 0x04D30792, 0x944D79CA, +0x1D050EA9, 0xA404DB1B, 0x99526023, 0xBACE24E7, +0xB9F20704, 0x284E6432, 0x47A593D1, 0x95F8DFCB, +0x220C9167, 0x8FAABBBC, 0x93D34E8C, 0xCE077138, +0x4FC18081, 0xE76DD7E5, 0x67465F6C, 0x7A479D77, +0x74D61F82, 0x00559214, 0x2F66E42E, 0x8742A96B, +0x62063950, 0xA2DBFAE5, 0x368B966F, 0xAB5FCCE1, +0xCB4023B1, 0x1E7AF542, 0x05953E30, 0x8CA51CFC, +0x2216547D, 0x29D562D4, 0xE9C9F8EE, 0xA90505C9, +0x088D0EEB, 0xD7A290FA, 0x95E5B567, 0x53FAD3C0, +0xB89FC625, 0x69A7519B, 0x3687C7EF, 0x7188CB55, +0xCE5DB97E, 0xA260574A, 0xD453D173, 0x145D970B, +0x12112CC6, 0x399839E0, 0x29C55BEB, 0xE467C71F, +0x10B3C9D4, 0x8F1C9662, 0xF207A826, 0xE0245600, +0x688B1812, 0x5A483031, 0x7048380A, 0x78E3D5BB, +0x1951533D, 0x8FA5D8E3, 0xC5BE500D, 0x71DB5B2B, +0xA17AA000, 0x408C9BE8, 0x161E12F5, 0xB1C38C45, +0x22A88F05, 0xDE3F4405, 0x5078ADBB, 0xCE1BF1A6, +0xB7A75B04, 0x6B8364E8, 0x0CE32E3E, 0x9BF65504, +0x28C18157, 0x78359AC6, 0x617BF202, 0x1E76FA09, +0x0F8E61A8, 0x6D02F0D5, 0x80356459, 0x79CEFAE7, +0x7D00F155, 0x5C1C0128, 0xC75CA073, 0x32816090, +0x9FF78DFC, 0x848D269C, 0xF811B314, 0xA86920FC, +0x6F885D01, 0xACFE6525, 0xC726074D, 0xFED68599, +0xF1D5C76A, 0x8799E5F5, 0xF85F5171, 0xD8DE2D3B, +0xE7DD8E75, 0x43F8614A, 0x0684FC8D, 0x9683B8C8, +0x74BE786B, 0x2514762D, 0x7D866682, 0xE711FE1F, +0x0DE9E273, 0x12F53167, 0x4FA3A7FE, 0x2A00EB61, +0xB3984A28, 0x4319F2B0, 0x42BA0CA2, 0x848771B6, +0x995E945E, 0xD41115F5, 0x43D9834B, 0x54EEDC36, +0x5C3C5407, 0x671B540E, 0xDCF18948, 0x150ED973, +0x2D4922DE, 0xF93CA17D, 0xB24A76E5, 0xD1C01C22, +0xF2963DD6, 0x3B860066, 0x08EF0EA4, 0x609B60CC, +0xE2E901FA, 0x25BE9B93, 0xDF96D9BC, 0x86D415DF, +0x75CCF6BB, 0x882D54B2, 0x7976E9AF, 0x88A0B178, +0x5ADE5A55, 0x8A8C0112, 0xD896755A, 0xCB6789B3, +0x8B63AE2F, 0x2545036C, 0xE4655B94, 0x20959977, +0x29DFB4D1, 0xCDAAEBF4, 0x1C07EC05, 0x5A6F607D, +0x88A9B31D, 0x118C74D2, 0x000BB065, 0x75C46712, +0xEF1A58BD, 0x50ECA262, 0xCCE393B9, 0x6EDB92E8, +0x700EF517, 0xBF6CF4AD, 0x57456DC0, 0xF629517C, +0x40331F8B, 0xC10A454D, 0x6CCB02CF, 0x9BF11B1C, +0xE0871437, 0x23623585, 0xF519F09C, 0x4DB2AFC8, +0x88FCBD7B, 0xB512FE8D, 0xDE445894, 0x078AD03C, +0x44375FB0, 0x0BABEDB1, 0x40D5E8E1, 0x13F20A86, +0xF1406303, 0x7205C322, 0x3FC43779, 0x7A60D510, +0x14469E04, 0xF4E77873, 0x2EAD7ECE, 0xA135D6EA, +0x3F4C4B30, 0x21488077, 0x69F64F1C, 0xEEF4876E, +0x63610C0B, 0xB7B24C5C, 0x324A76FE, 0x0CF651D3, +0x9460F0B1, 0x81A83230, 0x0839CFF9, 0x70722F04, +0xC278FB3B, 0x5DD1BDA4, 0x1E4B3DBA, 0xAE161A93, +0x9E1033C3, 0xD938FCEC, 0xDA2B2F93, 0x28CD82EA, +0x14AD1FAF, 0xE4EC9CB8, 0xE770AFDF, 0xEFB12898, +0x500BE181, 0x602625C5, 0xF160631B, 0x78D3643F, +0x4E13ED37, 0x647BB223, 0xCF18D75C, 0xF477F94C, +0x786ECB89, 0xB3ED21F8, 0x1BEF3916, 0x240FB35A, +0x5C69B7D9, 0x8E96290A, 0xD40DC98C, 0xD1370291, +0x5870021E, 0x3F7CF23F, 0xFD4A6ADA, 0x36482457, +0x926600AF, 0xDC8618BC, 0x67D3779F, 0x3422830C, +0x87A41FBA, 0xCA0AFF53, 0x63BC45F3, 0x520BBBAE, +0xEDE2E031, 0xB6FA9450, 0x258CA712, 0xD709C4E4, +0x617709B2, 0xAACE0B41, 0x363DBF55, 0x701D6583, +0x39F3C885, 0x7CD6297B, 0x078FE13B, 0xA398DABF, +0xDB97C514, 0x039102E3, 0x5CA545AF, 0x9298BA18, +0xD18DAF86, 0x3D70EEA2, 0x5266AD68, 0xB04945B5, +0x402DDA5B, 0x01DC6CD1, 0x93AC5053, 0x08DF9EA9, +0x485EBE97, 0xA5D05853, 0x6CBEE910, 0xD485F4E2, +0x8F201D07, 0xEFC384A3, 0x7272AFBE, 0xC0B41FD7, +0x8E54A971, 0xA7F9E0F7, 0xC21700B4, 0xC24A4ED0, +0x5419EACF, 0xBC2D8FB1, 0x2C5B5AFF, 0x0345274C, +0xC41DF47A, 0x37658AFF, 0x24CF3BE7, 0xA3086248, +0xF82B5928, 0xB49A9B04, 0xD4105AEF, 0x444EBE8D, +0x348368DF, 0xDC77A7A0, 0x68D37E0D, 0xD2EB54EE, +0xDDAC8C33, 0xE5C93C79, 0xE4706ABF, 0x17536EFD, +0x6C2B2B16, 0x038AA806, 0xDAD42458, 0xAE1D76A1, +0xCC8DE95C, 0x1BA20647, 0x0521068C, 0x306FBE44, +0x4E29D881, 0xD2A14D53, 0xA155853E, 0x44500CC4, +0xFC4466B7, 0x5AACD51D, 0x506D3A73, 0x3F61E0FE, +0x58F11F9D, 0xC92A2CAD, 0xD9A4F86B, 0x1FA747B1, +0x77DEC5D2, 0xDFAB369A, 0xD471EA01, 0x724502DA, +0x618CE21A, 0x52388BEB, 0x2E8A4CC5, 0x58332211, +0x3FCC46E1, 0x501210E2, 0xE9D51D1A, 0x37237B55, +0x8CE3E2F1, 0x6B2E98CC, 0xB56A11E5, 0x8819036B, +0xA6AA2F27, 0xB0124A0E, 0x92F17364, 0xD4A89238, +0x0507E337, 0x8ED95DEC, 0x9C014BA8, 0xBA5B11C6, +0x9C15D38C, 0x52596C98, 0x9330DD3D, 0xD6147570, +0x21701F1B, 0x5A2385F1, 0xE2F38C6C, 0xB3E94698, +0x2F9C63FA, 0x7E0234D8, 0x4CDD3288, 0xE1969B5F, +0x853B3C1D, 0xF61465A7, 0xF281C419, 0x46C5F072, +0x9F1722DD, 0x64F2A994, 0x86AEE8A8, 0x55895E17, +0x6047D1AC, 0x3375A934, 0x336BEACA, 0x90791174, +0x4DACC4D2, 0x24253860, 0x2A7876FB, 0x9DBDF98D, +0xD5BCE182, 0x67EB5F70, 0xCC06BA38, 0xE8F78715, +0xFEB0EB44, 0xE9776E03, 0x892A0898, 0x7A070650, +0x6D04DDC4, 0x99A5B7EA, 0x3B416BB6, 0xDADCE834, +0xB3B03278, 0xDB73B70E, 0xB0F0224E, 0x538A4AF9, +0xD25D6A37, 0x8F627FB0, 0x11ED9387, 0xB8C88457, +0x0CF320CA, 0xA20E62A2, 0x1DACDD4A, 0xAB84575D, +0x740DAF75, 0xAB9DB955, 0xFF787314, 0xA680B8E3, +0xC976D38E, 0x1FD38F4D, 0x0AEB6633, 0xB69A03DF, +0xB6CA8610, 0x106354C2, 0xC37D48C8, 0x3E5EED54, +0x534CC9BA, 0xE37DFFAD, 0x9F69EB05, 0xF67217EE, +0x50180B3D, 0xCC61C127, 0xC3598D73, 0xE5C00F01, +0xFFE9B111, 0x5E23EA2F, 0xF6C45DCE, 0x44585E39, +0xB02C6004, 0x37233902, 0x4F374C0D, 0x34288898, +0xE274937D, 0xC81D472C, 0x17A43151, 0x2638F7D3, +0x5304E5B5, 0xD5CE5EDE, 0x357FA7B3, 0xFBE27986, +0x64E65D1F, 0xC28D1237, 0xA73D9AB3, 0x124CA6C8, +0x770D7415, 0x5788C32C, 0x18DEFC00, 0xB3B2B06A, +0x55CC86A0, 0x8D929309, 0x84AB381A, 0x9DEFE8DD, +0x26C742C8, 0x952BAC34, 0x0A3B140F, 0x82A9304B, +0x52CEC9F4, 0x47DF4D08, 0x15A116D8, 0x7B890B18, +0xC87BEF1A, 0xB59601B6, 0xD37BFB28, 0x5D9F564D, +0xFB002F8D, 0xE7602E57, 0xE429C852, 0x9C0A8C75, +0xE02611DC, 0x8A1C9861, 0x7495D6DE, 0xCA059710, +0xAE5969B8, 0xE5B2CBDC, 0xA49F6EC1, 0x85D2A553, +0xE4719B0F, 0x40F68BBC, 0x092E24B5, 0x7B132678, +0xD70C17E1, 0x309E6AA1, 0xE009657F, 0xA7238C7A, +0xE0575D78, 0x1D6980E7, 0xEFCDD368, 0x19F08D93, +0xFAC03B85, 0x51BADA8F, 0x037DF839, 0x8F4D29F4, +0x1DC8A913, 0x50C55402, 0xDEE578F0, 0x2BA1C091, +0x9ACA567E, 0xA8FFECFA, 0xA3C05D12, 0xF18C6283, +0xEAAE6662, 0xB4DC6A79, 0xCEC5E782, 0x93A2E384, +0x8F8A5E6F, 0xCA8379D5, 0x81BCD49E, 0x5FCE174B, +0xD1543A5B, 0x845D635F, 0xD53125B9, 0x3B2121AE, +0xF8ECDD01, 0xF84D2D11, 0x6579BC21, 0x5C2DC220, +0x9EC1A688, 0x1148D831, 0x6C087799, 0x58944357, +0x56F79FC6, 0x6B689B55, 0x740B5FD1, 0x9F7BFB5F, +0x6B2F3E2D, 0x10E09273, 0x2E9E3213, 0xF3436AA0, +0x14A9F681, 0x9087D3CE, 0x68D0430B, 0x9FAFE3EF, +0xD45B8C61, 0xB982724A, 0x04448D7F, 0x8712E47A, +0x2C188D15, 0x9C3F06CC, 0x6343B130, 0x56C6765C, +0xF657BC9A, 0x15F1E973, 0x47E71181, 0x8639F5D7, +0xC1F3FDD5, 0xDC522441, 0x56BB2908, 0xAA48AEC6, +0xEC04087A, 0x8D375875, 0xE2941F88, 0xED31CC72, +0x09BD8794, 0x4C81D5C1, 0x1CC96D9C, 0x98A89022, +0xAA362C57, 0x924D583D, 0x270430E6, 0x0FD4040A, +0xAF561155, 0x38DCD1CF, 0xE861D2AC, 0x24A2EF3C, +0x2B7E3868, 0x13DA6C12, 0x69202EB6, 0x4A5FEC66, +0x185417A9, 0x3C92EFF4, 0x949842E6, 0x02115D93, +0xAD1726FF, 0x4E093D7D, 0xC3E41B9C, 0x27BBC1C1, +0x4FFA49C7, 0x6C63D24C, 0x84255444, 0x282C3BA2, +0x3D679D86, 0x03B410B1, 0x64DB454C, 0x535499D4, +0x25B421A1, 0x7E68C8FE, 0x0477E3B9, 0xCEFB087D, +0x9E59B89C, 0xBB787559, 0x1A550EE4, 0x078B48AB, +0x73A865FE, 0xD7227471, 0x3A864049, 0xE5EE3A1D, +0x201BC19D, 0xEB8DAE2C, 0x0E2AB31D, 0xCDAC2D79, +0xDAAB08B1, 0x63ECD4F2, 0xC00F9716, 0xD415C6BB, +0x8C20C39F, 0xDED8F5A2, 0x1D6A4190, 0x3D319167, +0x56B3A26B, 0x0547BF52, 0xA056924F, 0x4DAA539A, +0x557241D1, 0x42C9124E, 0x18723323, 0x6AD6E7EC, +0x8E039337, 0xF6FDDD65, 0x5F3525F9, 0xC0AD9704, +0x810EF049, 0xCE022EE0, 0x41CE7E52, 0x8E172A44, +0x648808E2, 0xC7FF6896, 0x2AD0985C, 0x304B9631, +0xD21EA39B, 0x279F5089, 0xCDB5C390, 0x21716A40, +0x5E34B278, 0x39475D72, 0xBA4F4DB1, 0x8B25818F, +0xE6E466F4, 0xC4A09DF8, 0x59F18AC7, 0x887AB5FE, +0xEEA4BA42, 0x17371DA8, 0xA82193D1, 0x6DC30EF7, +0xDEB9D349, 0x2B3271D4, 0x1FE83836, 0xEC755A29, +0x05F07FCD, 0xC331D3AE, 0xC6208B76, 0x497FF280, +0x4C579C5A, 0x22B71F94, 0x30FD620B, 0x31B71AE3, +0xDF7D1A41, 0xF041ACA5, 0x9533261B, 0x3262D291, +0x060E9672, 0x7D191A55, 0x6D0F0945, 0xF8C7777C, +0x1C173808, 0x78308E77, 0xC1EEAD3B, 0x059CCD9D, +0xA8FDBE19, 0xE47630FA, 0x88A49DE5, 0x03347DAB, +0x4F31F969, 0xF9C62B12, 0x93AB126F, 0x8A7A3BFB, +0x82591545, 0x2A1A2131, 0x1DEBB134, 0x449E28DD, +0xFA7E0248, 0xC1E3A5BC, 0x1747E097, 0x4C69AA5C, +0x1FD71B4B, 0xAC64CA6C, 0x5545F9F9, 0x5E5886F2, +0x243DBA6C, 0x495BE163, 0x4ECF5A6C, 0x430C9019, +0x89A980FA, 0x528945AE, 0x00CE6936, 0x9F9A73B2, +0x9E59DC6B, 0xD57740CD, 0x0E0CB735, 0xB1202BE3, +0xAA26C2A9, 0x267A77A6, 0x3FA12CF0, 0x4587C0AF, +0x354ED831, 0xFFD8BD8E, 0x56CC0F26, 0x75717AE3, +0x51B10674, 0x3E33EC26, 0x26CE80DB, 0x5C4A9140, +0x017F6C2F, 0xF9038D9A, 0x0A22C29F, 0xBA1F7C8D, +0x125CC934, 0x6CF66BFF, 0x48C13DCD, 0x63FC3D81, +0x258C181D, 0x1A4C3DDD, 0x2E24BECC, 0x7C86A9ED, +0x5BD1989C, 0x57CE595C, 0xDF291AFE, 0xEAF00887, +0xD8DD4259, 0xDF67331E, 0x50D0CE88, 0x1FD090AE, +0x632DA5F0, 0x95272A5B, 0x31172F25, 0x547FD7DF, +0xAFBE11D9, 0x97189DFC, 0xC4881191, 0x1C92365D, +0x843DEFDE, 0xCF0A399B, 0xCF327CAF, 0xDDAF0BCE, +0x03AA7A2E, 0x411A8664, 0x6CCF7CD9, 0x61097EF5, +0x07F3941E, 0x5BC3EB75, 0x2791945F, 0xBEBB526E, +0x18631A34, 0x25FEBF10, 0x419834CF, 0xF642D176, +0x372FFF10, 0x2A1BEA1B, 0x400FF345, 0x257A234A, +0x9F15E99D, 0xE06AA1DB, 0x3A0DB315, 0x2BA30D99, +0x0E9E831E, 0x1B25EE41, 0x8DB30E70, 0x9FBA6D64, +0xAB8AA5E3, 0x5A96177A, 0x6BE03535, 0x97E37DCE, +0xACA24F26, 0x5F0096F7, 0x5D02722F, 0xAF8F3EC7, +0xA6824151, 0x70FAD406, 0xDEBA8513, 0x99C63E34, +0x1CC4A3DF, 0x7F756508, 0xB7386527, 0x647C7FB8, +0x43F1F4DF, 0xC7E4EC18, 0x302BA109, 0xD5E9175B, +0x82856F77, 0x0F6D45D9, 0x95AE28B9, 0xE63385C3, +0x8FB26619, 0xBD99F298, 0xC884B948, 0x0B596FF1, +0xE061C3F9, 0xBC2F9A81, 0xC488CD91, 0x372EF590, +0x3DA1BFE5, 0x10DE037B, 0x7210B4DC, 0x74E4EFF8, +0x6365AFD2, 0x8CEABC85, 0x1D8FFD43, 0x4DE243F8, +0xEC976FD9, 0xAD827765, 0xC679F15D, 0xC125EC31, +0x95D3481C, 0xC4EA6EAC, 0xC8FC014F, 0x1352EB66, +0x9C400EB5, 0x227BFAB9, 0xB12BF958, 0x85B6D782, +0x78B6E44D, 0xE2232EEE, 0x4F101711, 0x9ABEBF69, +0x66ACC682, 0x04AD5F55, 0xE4FC6238, 0xBA3D2266, +0xA2BA3170, 0x083F39AB, 0xFF2075C4, 0x945C4B05, +0x41E8C113, 0xEC7CAD67, 0x3653733E, 0x03510C3B, +0x1E973158, 0xFBE507F3, 0x2CCD8D9A, 0x6EA9442F, +0x0D48DE95, 0xC517BFAE, 0x04EBB5C9, 0xEFAB1823, +0xD5FBFC0A, 0x6890F212, 0xA1C00CCD, 0x6DD561E6, +0x20D39B1C, 0x56113FBA, 0xCF3A7FD7, 0x3AB5A0DB, +0x3656572E, 0x7BC48CD3, 0x8902AE36, 0xD3E94AFF, +0xC06EB447, 0xCC513C0C, 0x2544B7DD, 0x6F168877, +0x53162607, 0x461DCEF0, 0xF47AF2BB, 0x8AF9F3CC, +0x1EEFF9E6, 0x57CFB6B6, 0x7F712439, 0xAB20C93D, +0x043F9003, 0x60C808BC, 0x86C2137C, 0x46ADB474, +0x848B65F2, 0x5544789B, 0x18E9AEC7, 0xC889913E, +0xFEB79B2F, 0xA3FBE518, 0x67922463, 0x93746398, +0x968E160F, 0x8CA856A4, 0xA040202E, 0x660C00C6, +0x8F0A8E62, 0xE2BA54DE, 0x4BD0C117, 0x1A1A3092, +0x086CAA3A, 0x2BBA5676, 0x89610176, 0x00ED2F97, +0xC72130C7, 0x5A053880, 0x7298E553, 0xD67971EA, +0x0D41E477, 0x2FA8285F, 0xB856A190, 0x132DB916, +0xCDFFDD11, 0xB5519A81, 0x1BC7001B, 0x97C824DC, +0xBB4C707F, 0x90166DC2, 0x42DFAB7A, 0x90E33184, +0x6C6B940C, 0xDC553814, 0xC4F5E7AA, 0x99434AE9, +0x82BB09D4, 0xCB0A7DA3, 0x3A8033AE, 0x054D3481, +0xE20AF761, 0x25F5F254, 0x7AD3AF3A, 0x23A34C29, +0xA19C57BC, 0x39B57AD9, 0x55E1EC59, 0x5ECA4198, +0xDB908BCD, 0x4871C3F4, 0xE7091328, 0x64A9B6EC, +0x1CCAB2F3, 0xEDB22423, 0xFFB6A717, 0x6FA13548, +0x361FF711, 0x24664017, 0xCBBF9970, 0x83A7B7DE, +0x9B704690, 0x01A0B877, 0x95041B60, 0xC048F3E1, +0xA31625F2, 0xE3DFBE27, 0xF657295B, 0x1F5C3AF5, +0x60EE1637, 0x575EDFAC, 0x725844FB, 0x242723D0, +0x04FA46FC, 0x1A8C3F44, 0x0E03A5FE, 0x8778079F, +0x606E4E1A, 0x7C0AF3D5, 0x9578B266, 0x63BCE765, +0xA8ED66D9, 0x9242377A, 0x817A5D5E, 0xD0981A98, +0xC07F2E7F, 0x0E66F84A, 0x3635F854, 0xD7AD8359, +0xDCF23230, 0xC1B9084C, 0xA7987FE5, 0xC3B27EB4, +0x1F747061, 0xFD278601, 0xB6ED3B5A, 0x9CEF8AA0, +0xA5023C46, 0xB49832AF, 0xB12055FD, 0xD85310E1, +0x2C19ADE6, 0xEFBB17A8, 0xC246A4C7, 0xBE4B2666, +0x13C2D7F9, 0x50063BA1, 0x9B00E02D, 0x335B9DF8, +0xD424AF25, 0xBAE40C92, 0xE87BD6B7, 0x384D1EB1, +0x8B91E8F4, 0x9E3FC6D5, 0x6BB1A51E, 0x21AE5533, +0xFCB8E713, 0x188B66B1, 0x6572E9ED, 0x98829178, +0x7BAE8CBF, 0xE00C32B4, 0xDAFC14D5, 0xEA8FC746, +0x2C8D712E, 0x89A05FC9, 0x9A274641, 0xAC2450AD, +0x2437784F, 0x3B1B80F0, 0x0B4A31FD, 0x277C0232, +0xFDDC6829, 0x3F3C606C, 0x0EF62352, 0x3D07D04A, +0x4E0939E8, 0xD59BF115, 0xA02752E7, 0x42BF7133, +0x9FA0939E, 0x64764109, 0xD5D03EBA, 0x3D4433A3, +0x1749B437, 0x137298B1, 0x677BE344, 0xA83CEF7E, +0x17813A39, 0xBC71823F, 0x2070E9A7, 0x3873AEF8, +0x5AF1E21B, 0x1F0CC692, 0xB8EFB04D, 0x1A1CC514, +0xADED6C3D, 0xDF35A8D7, 0x6D93275E, 0x9C362545, +0x62BF7583, 0xFC56D990, 0x0CD6A324, 0xF12A7939, +0x52587029, 0xD00D5F16, 0x51622555, 0x1178E887, +0x81E7BCC8, 0x92BB1C11, 0x097330E4, 0xCF8C5CAF, +0xD076D6BC, 0xBA292918, 0xF835A829, 0x4280A51E, +0x09CD7827, 0x11583487, 0xB8BA2CEF, 0xD598AE93, +0x99F4FD77, 0xEB151110, 0x1571B076, 0x63F2103A, +0x56C6BF44, 0x9E63B556, 0xFB981238, 0x5D8C978B, +0x9501D936, 0x82A1E971, 0xE5A4F7E2, 0xC6E3727A, +0x03329F07, 0x248ACDD6, 0x437E917B, 0x23B02B20, +0x73F76AA0, 0x75EA06C5, 0xD7C662B3, 0x267777F8, +0xDC96BF06, 0x54020346, 0xCBDF069B, 0x030133EC, +0xA7EF1C2E, 0x568959AB, 0x4FC31DE0, 0x3A22890E, +0x280F8652, 0x1BD8CB24, 0x9A8D92C9, 0x52718DE1, +0x12033FC7, 0xD48490CC, 0x681ADEE2, 0xF91BF7B8, +0xB8609B38, 0x34CF4BCA, 0x8F123290, 0x0D0F4FCD, +0xC4F43323, 0x2FC04F1C, 0x4669B890, 0x1E8D2A7F, +0x0658CAE6, 0x5489F3A3, 0x9CD362FE, 0xBA5190B1, +0x06A58820, 0x7A9AF759, 0xDC94E672, 0xEB284B85, +0xF8EFA022, 0x3837C379, 0x7C9E9A2A, 0xD2ED96BC, +0x5D1E4C7E, 0x97F2169F, 0xFC3C37C2, 0xE039EDF1, +0xDBE93909, 0x81FEAC6B, 0xFCD383FC, 0x170B91FB, +0x05BA3243, 0x8FB2ADE1, 0x52AFB984, 0xE8262E9A, +0x1E704638, 0x89B8DFD8, 0x18C0C641, 0x2760C7E6, +0xD3AFF3C9, 0xC4E3543B, 0x0C0B7910, 0x1DEF7792, +0x483D7194, 0x9AAF5864, 0x08607947, 0x626F0CF3, +0xC0F6A486, 0xEB4525CE, 0xA8BBA8F8, 0xE450DA14, +0x2DC4D114, 0xBCA527C9, 0x6682AA4D, 0xCBB48A5F, +0x1B474C99, 0x7F5B526C, 0xEC435C0C, 0x9E8D3E1A, +0x67D2EA29, 0xA3B7ADCD, 0x8328590E, 0x7345607B, +0xB6057588, 0x1A8B034C, 0x5C8CA534, 0x8115DC5F, +0x189C2ABE, 0xF1B92927, 0x78A3B62F, 0x4B621D49, +0xDC176A68, 0xCBD3C1DC, 0xD82348BB, 0xEEF05FA7, +0xC0DD3D83, 0xC1F2A7BF, 0xB2079D00, 0x14B5730E, +0x73203CD7, 0xA8672433, 0xA171FFED, 0x9F181200, +0x4E16A5C8, 0x56D8AC31, 0x73803D86, 0xD4685CA4, +0xE8DE9FE2, 0xA35D2CE8, 0x808CF3E2, 0x198700AE, +0x0034163F, 0x57BC76FE, 0x271ACF93, 0xAA3AF6D0, +0x37003A7E, 0x450B74F4, 0x157401CB, 0xB79DDDA8, +0xD60AB7A4, 0x3A4C8779, 0xB6990FC8, 0xA1668D5A, +0x05B7965F, 0x7814376D, 0xFA0D2D8A, 0xD97A1142, +0xE804DE3D, 0x4939089E, 0x78D40CAC, 0x01DEF5EA, +0x3DD1CADA, 0x96465956, 0x6358CFB6, 0xACE02DE5, +0xB4C9F6CE, 0xE9C95AFF, 0x70EAD28E, 0x58803693, +0x89EF9972, 0x58F0273F, 0xDB17A277, 0x0B082B98, +0xAAB13ABD, 0xE86381EC, 0xC18924D4, 0xE28D4348, +0xC21895AB, 0xE17073AD, 0x9417539B, 0xA043E5F5, +0x88FFD026, 0xD972F017, 0xD0C8B8D3, 0xB34F3D67, +0xC525E4B5, 0x0189A5A1, 0x59224A35, 0xAA18F2D5, +0xFC9E170C, 0x16D3795A, 0x35DB09FA, 0x1624DB1D, +0x4A6E059F, 0xC5C88A93, 0x9051D373, 0x4B12B09C, +0x4088AF39, 0x705394F6, 0x360F2BAC, 0x8A1F2420, +0x641D4FA5, 0xA78B78F9, 0xA5A5302E, 0x691D2108, +0x7CFB57FD, 0x1812FE68, 0x8A2BB5E0, 0xF181CA14, +0x1846848E, 0xDC044F67, 0x17FCCA28, 0x21D7C5AC, +0x4C43432F, 0xC457E26E, 0xB0C9ADD2, 0x791EE2B4, +0x620F27BE, 0x229E0B1E, 0x746B4FFC, 0x02038738, +0x1C7B971B, 0x05193430, 0x8645DBD7, 0x58678F98, +0x141E912D, 0xD89C587E, 0x9FD7B43F, 0x21851D56, +0x725311A7, 0x0605B1B2, 0xC18BF2B7, 0xC6F79EA9, +0xBD84A01B, 0xC9B7F2DA, 0x04E47EE8, 0x1C1A14F5, +0xBD5B4FF1, 0xE15FBC2E, 0xC4D43F01, 0x5D39AD4A, +0xBD3BD983, 0xB2314A4B, 0x8DABA67E, 0xB5263B5A, +0x9912F262, 0x82659C80, 0xC3610181, 0x3F229014, +0x2685532F, 0xCE4EC210, 0xF46AB09A, 0xFAFA69C8, +0xD1292944, 0x2EF880D9, 0xD03AAEAB, 0x0E83C435, +0x842C482C, 0xA70951A1, 0x0E4EA07D, 0xE0332D0C, +0x3EA27E55, 0x04721425, 0x7C8B56DC, 0x96391312, +0xF600D78C, 0xC850517C, 0xB3F9F2AE, 0x59A99351, +0x8D6AA838, 0xF586672E, 0xD81FE525, 0x3CEF31DF, +0xABDC7079, 0x6E1BB8F6, 0x6B45B87B, 0x9FD2CAC4, +0x648E357A, 0x6C57D30B, 0x23766B64, 0x8C8BD9C1, +0x9A29001A, 0x206F47E3, 0x5F423D75, 0x293A32C4, +0xDCC6432B, 0xA4280954, 0x457790B8, 0x11E84CEF, +0xAB11D0BF, 0xD04258E3, 0xFB44C0CE, 0xED8231B2, +0x0277A6B2, 0xD8E5C517, 0xCEDF4C8B, 0x19D90170, +0x20555532, 0xFCB610B9, 0x88D5F5A9, 0xD35DC77E, +0xEF5EA686, 0xD866959C, 0xF0886B56, 0x005CFB90, +0x582AD255, 0x7381289F, 0xC18CED4D, 0x444F0A6B, +0x9917AE56, 0x505A7BCD, 0xCBDC903B, 0x51EF0F3C, +0xC4E6AF5A, 0xB148AD2F, 0x609A124A, 0xB5DA89E4, +0x3A68C7D4, 0x98694F02, 0xE85B1766, 0x754BA5FF, +0x1296A58E, 0x27736843, 0x9B6280BD, 0x2686032D, +0xB428AC04, 0xB06DBA5C, 0x625FE034, 0xD4BCB25E, +0xC91C5B3C, 0x73BB70E5, 0xA26A479A, 0x73173229, +0x3AA1235C, 0xE16171D1, 0x42D0D42F, 0xFC624752, +0xF1F5DCC2, 0x1B6F20A9, 0xFF9D626D, 0xDBF052C0, +0x90E38D23, 0xFB72CC5E, 0x9186519C, 0xF2330093, +0xE5251385, 0xA0094977, 0xE83FA066, 0x2E389CE2, +0xD3A62E72, 0xA9422A8B, 0xC61CFD5B, 0x1B3A516A, +0x58087800, 0x3A47462C, 0x557DDD8B, 0x94FD21D4, +0xE1AEA942, 0x4B2CC532, 0xB2185B36, 0xDCA15259, +0x1D044D7D, 0x781317B8, 0x49CB13E7, 0xDAAFFBC6, +0x30A05644, 0x77B05F37, 0x065A567C, 0x94721C79, +0x47316C60, 0x58AAC7C9, 0x410081AB, 0x7D4A36FA, +0xCDF23455, 0x1873EF87, 0x186982B5, 0x7C78D9DA, +0x3567D966, 0x10FF5E8E, 0xDB88E5B3, 0xFF1D39A1, +0xB8A345A3, 0x7A7258F3, 0x9706B3CE, 0xB5ADCC26, +0x4561EF5B, 0xB002FBF6, 0xF3F4C6FA, 0x57EC75AD, +0xBCF37924, 0xBC05B0AD, 0x2AB19DAA, 0x0EBD25EA, +0xF335D08C, 0xDFF79E19, 0xDD86D418, 0xECE11951, +0xC06F4D50, 0xFD698DF8, 0xBA6192EF, 0x365A28CE, +0x74DEC0B7, 0xE971F67B, 0xBF89DD42, 0x1E683399, +0x164A7158, 0xA1E48475, 0xBE139E8E, 0xBDEBA7FE, +0x74E03AEC, 0x88EA9618, 0x9B0048C2, 0x68C1DD20, +0x8DC9FC85, 0x24B55E3B, 0x51C38BDA, 0x2ECD7B13, +0x54D66C89, 0x69A3EBC1, 0x4B4E4F13, 0xAD37B7DF, +0x030A1D8B, 0x85A114D9, 0x403BE495, 0xB5E40331, +0x316E7310, 0xB36AA494, 0xDBFFCB9A, 0x5C0E5DA5, +0x099BA9E8, 0x66826E9D, 0x0BC5849B, 0x1A20CBAB, +0x0744FBE6, 0x2CB52040, 0x8B88533F, 0xA8A44BF1, +0x62FEB4A8, 0xDB2ABC4D, 0x46F0B676, 0xCBD06470, +0xDB6D71EF, 0x5DC3551A, 0x71B31A5B, 0x046D4C7F, +0xC051A998, 0x1EC19FF9, 0xA9E21F9F, 0x7951E081, +0x78BCBA62, 0x91B623F2, 0x8EF6A81D, 0x1023755E, +0xCE47F5AA, 0x0EF27527, 0xE9E488D5, 0xD53E4A29, +0x78A276E1, 0xB2100585, 0x01208E3C, 0xA38BCAFF, +0x36221FB7, 0xB3C9194E, 0x51BD75D4, 0x9C8C73AC, +0x7ACA9964, 0x17890C94, 0x9FDA51F4, 0xC4FDF688, +0x2C8244B2, 0x0D834C74, 0x290973D3, 0x7F134553, +0x296D2FC2, 0x4E08ED27, 0x1C51E53D, 0x3D892F49, +0x945F76CC, 0x2E531E63, 0x71EE37E0, 0x9C47F346, +0x2D8D920C, 0xC3E465BA, 0x3A72D142, 0x5B6AB80D, +0x364C2AE7, 0x3B18389B, 0xB9442484, 0x5D687BB5, +0x97C65A4F, 0xC7DBE8BE, 0x0F840061, 0x5A73EA89, +0xCBBDD954, 0xAFE9CABD, 0x06ABDF95, 0xF139302D, +0x3804FEA8, 0x7CE6542F, 0xDE47B8ED, 0xD34BE509, +0x5EB9C9E1, 0xDC582534, 0xE77D7FC8, 0x2BEFED7E, +0x4EA26DFD, 0x54670B81, 0x665C4531, 0x5B7A7023, +0xA05D9A2E, 0x71BDDB2E, 0x9D51D8C2, 0xD8A665CC, +0xA9B87A22, 0x581D28BF, 0xF9D40373, 0xE04D8F63, +0x117B9842, 0x8868B9BE, 0x8397FAB9, 0xEF5CED75, +0xF70F90D8, 0xD3DFD3A6, 0x1779F576, 0x3059520D, +0xC38F4AA9, 0x6B7A6D0A, 0x4E73112A, 0x4FF9DCED, +0xAEA1383A, 0xBAB0AA93, 0x41DBCBED, 0x266775A6, +0x8EE0D5D5, 0xB522CB9E, 0xC6E5D0D3, 0x86E4C8FD, +0xA894642F, 0xF69821A9, 0x88B41798, 0x4585A188, +0x9D2130FC, 0xC5B18E0D, 0x6B92C9EE, 0x3C9289FB, +0x1F02CBB6, 0x31FA86DE, 0x1B2295CD, 0x5B4DA19C, +0x3134D8FC, 0xE5EABC44, 0xDF8C5095, 0xF6571881, +0x1F2FBD62, 0xE585FE61, 0x020CEDF6, 0xD70ABC83, +0x5F37746A, 0x6FDA3BF7, 0x5434E503, 0x44CF6915, +0x561B2393, 0xEA4A2251, 0xA988C080, 0xE47B1791, +0xD335CFBE, 0xEDA9DEE2, 0x4F70FB22, 0x83A2C29F, +0xF44FA002, 0x069D25EC, 0x4D5043F5, 0x887464CA, +0x661D1E9F, 0x98B856AD, 0x81A23FB0, 0x3693BD42, +0xCE0AEB0B, 0x1F6E8322, 0xCBDF571B, 0x93688909, +0xFA16A774, 0x25834437, 0xEE77FA98, 0x8DC68C60, +0x155A8760, 0x22B8FCA3, 0x1B1BB054, 0xCA3AFFCA, +0xC8EACEA4, 0xC86BADD9, 0x473770AB, 0x41D6E398, +0x568B397D, 0x065C0BE5, 0x51D38A0D, 0x3BB3A0E1, +0xBC386DCB, 0x7DCBA6B0, 0x19007254, 0x3F4FC726, +0xF27DAE85, 0xF7FDA72A, 0x6D0B5C07, 0x64A0ED12, +0xE26D8878, 0x210E4F6B, 0x65F92C0D, 0x4E4E2CA6, +0x5E479D49, 0x7B287050, 0xE9A4836C, 0xC3A111A2, +0x9B90D6FD, 0xA5F362E0, 0xADC9526B, 0x79B736E9, +0x72A9A57B, 0x181B4E70, 0x5236F32A, 0x5567E3C9, +0x23EFD063, 0x87113163, 0xCDF6D4F4, 0xF53A8722, +0xB70CF941, 0x757F40C8, 0x6A652BE7, 0xD71DA5AA, +0xF87D51C2, 0xB4A68E16, 0x763D8FEB, 0xB6DE5436, +0x12184DCD, 0x38D1DE90, 0xB39E5209, 0x1600492A, +0x073AE8F5, 0x0366AC0E, 0x1AD5014F, 0x398E0873, +0xD653928E, 0x30B5B4DE, 0xAC68A06E, 0x8DAEF4D3, +0x76A880D8, 0xF3B3BCC5, 0x2B631F58, 0x340914DB, +0xB4771DCC, 0x7C9D4A43, 0xAFDB1138, 0x014B5A83, +0x0D44185D, 0x20C89576, 0x994B4367, 0xA84BD792, +0xB2E17CB1, 0x00CE5214, 0xFB93E54F, 0x03CCA7F1, +0x956A82E6, 0x22329A71, 0x2A634374, 0xF18B7AD9, +0x1F168BC4, 0xC2CB1EDC, 0x8E0AF6CD, 0x211AF22A, +0xAB5DA374, 0x63F1F25E, 0xEC58D4CC, 0x48C65C46, +0x5A7F7574, 0x7BA60047, 0x279EF299, 0xE0B77F48, +0x647A03C3, 0xAE7C4D8F, 0xF65149D0, 0xAC9EF228, +0xCD90B1CD, 0xCEEDA54C, 0xD8FD0A6A, 0x8D7C2291, +0xB38EF6C1, 0x7F38E676, 0xDADD0A8F, 0x1125713C, +0xAA78A299, 0x54033F20, 0x199C76C5, 0xCAF82A17, +0x16F2EE8B, 0x20071D0F, 0x2CA000F8, 0x0178A24B, +0x0029EE46, 0xA9D8C738, 0x123D2BBD, 0xEF7CAC52, +0xBD241869, 0x435F8FF7, 0xB573A190, 0x402BFB2F, +0xFDA3097C, 0xF3765889, 0x68E2C7D5, 0x4C26F858, +0xD6814D1F, 0x6B043C7B, 0x173DB091, 0x95126C7C, +0x0FE8E1BE, 0xFDEB233C, 0xB979B0CB, 0x00E00659, +0x19952E52, 0xA0976F7E, 0x02FB462C, 0x798815C8, +0xA2504EFE, 0x0F4811AD, 0xBA8F122E, 0x5EE5864F, +0xD39B6799, 0x5319F6A3, 0xF6A66685, 0x988D106F, +0x7ABA5220, 0x0320384B, 0x4DE48C79, 0xF5CB36E6, +0x2B33270F, 0xFF4E6965, 0xD4D843D5, 0x7EEE861C, +0xA96AE5EE, 0x310E5215, 0x6D20068E, 0xB149AE8B, +0x0997D9EF, 0x5043FFFA, 0x0516E2B6, 0x3FCCDA32, +0x8E604A04, 0x23012778, 0x9444A474, 0xB7F5DC24, +0x3A58E6FB, 0x17B759FB, 0xF29C1EE7, 0x8893D2D1, +0xC6CD235B, 0xAAB0CBCE, 0x2D84474C, 0x8A0BE027, +0xFDB87FB5, 0xE6B507BD, 0x19B41927, 0x783FF4DA, +0x485A1D5D, 0x8ED285C2, 0x25AFC4C5, 0xBF0D662B, +0xC4238532, 0x4339FCCF, 0x14A784B6, 0x71665819, +0xED76E473, 0x5F1BAE9E, 0xD0AEC17B, 0x4CE78814, +0xD3609F61, 0xD4E49EB0, 0xE4E3EFDA, 0x9B7CAD1D, +0xEF01ABB7, 0xD137BEE9, 0xEE87A81D, 0xD4B204FF, +0x00B25737, 0x2770FBD1, 0x174AFF7F, 0x0A77A21C, +0xF1B370E7, 0x9C093CB0, 0x080C1FFA, 0x83CE92D9, +0x1707470C, 0x3303479F, 0x25F1B6AF, 0xF40EEB7F, +0xB98A1677, 0xA54A1BA2, 0x43B4144A, 0x2F092A35, +0x33286A77, 0xA0AB9C93, 0x4F8D70DC, 0x3A47BF6F, +0xB6209AB5, 0xA4C94557, 0x5E757055, 0x706EAD9F, +0x467BC02A, 0x6472A857, 0x42055C57, 0x66F2BA60, +0x33C0536F, 0x3240BFBD, 0x3DD74E6B, 0x1F58A552, +0x822E9577, 0xF49BFE77, 0x5490DC6D, 0x1D32BBA0, +0x1C30B072, 0x78A4A5C0, 0x1EE88A57, 0x97CAC3C8, +0x9912861F, 0xC916BBAF, 0xFC3A7F0E, 0xCA5E1F3A, +0x630F09CD, 0xF6C8C210, 0xF0A12A72, 0xF3148619, +0xDF1672E1, 0xFCE5C390, 0x29CAE554, 0xE984A45C, +0x8A1F0A3A, 0x6A02C707, 0x8CFB3ED6, 0xC0A741BD, +0x7A871FE5, 0x91021A69, 0x505FB05A, 0x8F85227B, +0xC300ACF1, 0x0A1B201B, 0x224614B2, 0x54A23576, +0x5360A5BA, 0xDCD23A31, 0xF98DF638, 0x79FF79D7, +0xEAC8EAC3, 0x4D22C65D, 0xDFFBF1D9, 0x55FD8848, +0x4BFD2347, 0xE2A08287, 0xE6A48824, 0x80625EA9, +0x71AB3F7E, 0x99B84DE5, 0x6512ADBE, 0xFBF24C47, +0x3EEF2564, 0x23DF9F1B, 0x24BE5199, 0xDEDD72D5, +0xA2FE063B, 0x4FE520B1, 0x9E4E7BBE, 0xD615BDBE, +0xC14E8184, 0x40F86FB1, 0xD403A65A, 0xC5AF6386, +0x412F8434, 0x6D6012B0, 0x4EC57107, 0x3F76AF19, +0x54A305BD, 0xEA9C4EB2, 0x584E0176, 0x20759805, +0x1A16C84A, 0x50BB10DB, 0xE610AF45, 0x98CF1EA0, +0x3F8C7756, 0xF9056BE0, 0xBAA66B7D, 0xF7076DCF, +0x67F1994D, 0x92BFEB62, 0x86FBDE17, 0x389DB311, +0x2A171F5A, 0xE14898B1, 0x4D11723F, 0x29889062, +0xCBF3DD79, 0x2B7468FC, 0x4FB93770, 0xC5FCEFE8, +0x8FEE6678, 0x9F4ABA9C, 0x6A6B23E1, 0xFEA7077F, +0xC835F734, 0xCA67807C, 0x1BFBEB49, 0xB8B1E842, +0x6A850623, 0x001C1E8D, 0x782AC01E, 0xA28A72D8, +0x6CD66FC1, 0x77EF6F13, 0xFF40D7CF, 0x4A163DFB, +0xDB21AA89, 0x29D03A9E, 0x3A4D1D57, 0x7A89CDC9, +0xC5623E10, 0x8A444799, 0x1F620DF4, 0xFF876758, +0xC9DEEF2E, 0x7F86911E, 0xE3196093, 0xA00EB422, +0xCDB1743F, 0x4AAD1988, 0x70167700, 0x70595C5F, +0x8E648013, 0x401D8770, 0xC762F0E7, 0xDB776926, +0x2BDC55B3, 0x8F4AD2C1, 0x1A2EEB50, 0xBD4BF2A4, +0xA43FFE90, 0x752935E7, 0xB02C7801, 0xDD4CD3DB, +0x3815C394, 0xAF427695, 0x7455A8F9, 0xC444C7EC, +0x9BC9B2C5, 0x08423BA7, 0x5D91ADD8, 0x59D866DB, +0x0AD32258, 0x7BC397F6, 0x0EF7DB59, 0xC1034320, +0x79073406, 0x991A12B9, 0x9D6776A0, 0x6348A5EB, +0xBD98CDC4, 0x81A6C5C5, 0x76A3ABA6, 0xFA9CDF77, +0x97772B59, 0xD987E42B, 0xA4B893D4, 0x61F78E38, +0x82567691, 0xCB91CD58, 0xEEFA69AE, 0xF7D51178, +0xA436C578, 0x99E86E08, 0xA8C3B16B, 0xD609054F, +0x1E0ADCE8, 0x5DF6EF20, 0xEB3CC45B, 0x9FAEA24F, +0x97F57F19, 0x66E2713F, 0x42A423C3, 0x2A21B17C, +0x6A4C6B40, 0xFA0F4F2B, 0xD1F3F64A, 0xD0AAFA50, +0x767D3AC2, 0x837E626D, 0x3B21279C, 0xCAE18855, +0xFA8CA385, 0xA91BDE45, 0x1A953327, 0x733948CC, +0x158B8CD2, 0x904AC43D, 0xA6BC8F82, 0x55F027DA, +0x95B6BB32, 0x9265FF80, 0x8EEF0D24, 0x28F6796E, +0x1D736700, 0xB621D4D6, 0xAB2F1A4A, 0xECD7DB83, +0x35CAD419, 0x60604917, 0x5DE51335, 0xA3D7E122, +0x685D04D4, 0x494739D4, 0x0060722C, 0x59149718, +0x03C9F144, 0x43328818, 0xBB1AE189, 0xCA7B9250, +0xC835666D, 0x83950220, 0xD774405F, 0xF6F4FCCE, +0x0E38794D, 0xAF184A7E, 0xEF66E15B, 0xA0C2A74F, +0x876112D5, 0x7D68C9CF, 0x8902011C, 0x6AB0E128, +0x2A515520, 0xA99D1DA0, 0x9EACEB4D, 0xB669AA8F, +0x6F96DCE2, 0xCFEB5CDF, 0x46EB36BD, 0xEDDF8317, +0x4FA30C3E, 0x9541A8A1, 0xA5F75533, 0xEFE1FEF6, +0x7F21B481, 0xDA11D5EA, 0x64642069, 0x083D2137, +0xDF508726, 0x8F6CCC4B, 0xC5412D0A, 0x6A9F6BEA, +0x3E3CC54F, 0x078BBB1E, 0xA6047468, 0xF1FA39C2, +0x26143435, 0x90132EB3, 0x4216580C, 0xF6773B8C, +0xA6B188BF, 0xE3B49523, 0x89E4563F, 0xD0B16538, +0x2D9079FD, 0x69ABDE36, 0x669AC5EB, 0xD0618DD9, +0x5080BFEF, 0xADC056D6, 0x72402C9C, 0x0AE79E07, +0x8D6DF48E, 0x0502837E, 0x79BA17AD, 0xE4871C89, +0xC4554CD5, 0x23FCB2A4, 0x646FA999, 0x212A9DB8, +0xBD23DF0A, 0x890B5FE6, 0xB5D03292, 0x9FA3FD59, +0xD612F8B1, 0x611365FB, 0x7E7C9FAB, 0x024194D2, +0x46C2C617, 0xAEB0FAD9, 0xAE5D3A7E, 0xEA8B0ABB, +0x760730A4, 0x50443E76, 0xECA64341, 0x538E5256, +0x8A8505F5, 0xE0E4DC29, 0x105DC564, 0xC73D93D9, +0xE3F27C90, 0x8CC01FC8, 0x400D0F76, 0xDCD01130, +0x1E3416D4, 0x4C612E03, 0x0BFE7A5C, 0xFDB15334, +0x5326A77F, 0x99549BDA, 0xDDE90BAB, 0x920BD872, +0xC4B4F5DF, 0x7B39BAC2, 0x777C6694, 0xB4971103, +0x9E7806A1, 0xD3141F2D, 0x2B40BAD0, 0x74AF248F, +0xD1AEED43, 0x2F453736, 0x1880104E, 0xF9CD502F, +0x7691FE59, 0x39C3FEC7, 0x72EA7BF2, 0x0C94BAB5, +0x35D6F509, 0xAE86AC96, 0x0624C181, 0xA69DF699, +0x5991FCE3, 0xAB20D4F1, 0xF30F1BC9, 0xB094CF62, +0xA3B5A732, 0x3BC8C32F, 0xE7710370, 0x429A8D96, +0xD8913A42, 0xCFBD0E4F, 0x710B7078, 0xC6501E93, +0x241224AF, 0x978D2320, 0x8EF1064B, 0x273FAE07, +0x316EC02C, 0xB3C16C0B, 0x8249C245, 0x21AD11CB, +0x6265FE57, 0xA9F1D5FC, 0x0B52F1CD, 0x0381D983, +0x2931D6B1, 0xD126CD94, 0x69D95197, 0x7CFB6AD0, +0x46E6D50D, 0xE60BCBD2, 0x72FBB436, 0xC971A4CA, +0xA580B9B9, 0xBC823514, 0x5D15A840, 0x87A91622, +0x63490D13, 0x277189A8, 0x22CA2EDC, 0x1C56456D, +0x1B5EB836, 0xD8BBF2EB, 0x20F56DFB, 0x99321E4B, +0x9238B783, 0xE5E5D085, 0xC81DAA11, 0xEF8DD032, +0xCEC28645, 0xFC40AAA5, 0xBFA5FC68, 0x1C2CF7C7, +0xC0DFD194, 0x5AB730DA, 0xE3FB56A9, 0xA0AD00E9, +0xB7BA2E2E, 0x579C8722, 0x04AA07FD, 0xF55C6C5C, +0xE56CD6DD, 0xA7DA5100, 0x2A6BA1E5, 0x9B7E5104, +0x81410420, 0xDC6130A8, 0x3EC8935B, 0xCC2EC782, +0x142344EF, 0xF016E0CA, 0xA3ACFA8E, 0x019A7009, +0xA0DAEC5D, 0xFA503565, 0xC907794E, 0x77AA4E69, +0xB45B7E54, 0x929A056A, 0x46AA4AE1, 0x55E56EDF, +0xFDD9D726, 0x35744D5C, 0xD6854700, 0x9A6E1EEE, +0x0B00F6FB, 0x6BE65BFB, 0x9CF98DE0, 0xD80ACE66, +0x1E5300E4, 0x745338DD, 0x4CB925DE, 0xB369B0D4, +0x7A53A606, 0xD2B96E54, 0x88F96B30, 0xB72C3E19, +0xC2A41177, 0x6206F879, 0xC1F6CD78, 0x879DA74F, +0x763F9417, 0xD109B779, 0x6A58B34C, 0xDCD7C21A, +0x1B0A0154, 0x45EE3A9C, 0x62C60161, 0x79E47020, +0x42250A39, 0x9E2C2C59, 0xCE4F6206, 0xC2970386, +0x983CC2C3, 0x0DAF0A85, 0x388626DA, 0x06A56D27, +0x9223203A, 0x96E0148C, 0x22F0D052, 0xD5F1AA88, +0x394BC8B9, 0x03CF58FA, 0xC0B1073C, 0xC16B35C7, +0x7B7CF9F8, 0x2E3A24A5, 0xA19089C9, 0x4223FAE9, +0x7751D977, 0x802E7062, 0x6D3651EF, 0x39E9B52E, +0x946D07F8, 0x8E2EAEB7, 0xF9279A65, 0x14DEE911, +0x8B92A149, 0x9611756E, 0x067DD22D, 0x59907967, +0xB3417E3C, 0x3B72AB7A, 0x825D87C7, 0xCE5FA852, +0x5D88C5F8, 0xE792BF66, 0x28DB3A4A, 0x118CA3A2, +0xCC86284E, 0xA0AC4AE8, 0x33394B70, 0x974F96C2, +0x86ADD3B5, 0xC87295B9, 0x1447D26F, 0xC9ECAE80, +0x10CA01D7, 0xE04ECC68, 0xAE56597E, 0xAAA1248C, +0x81C35460, 0x0087CA93, 0x943AABA2, 0x0AFCBFAA, +0xEA77D5AB, 0x020D36D6, 0xF1CCBBB6, 0x8DF1426F, +0xAE726D96, 0xA6E4C915, 0x58F15F91, 0x5B696D6F, +0x00042B30, 0xC6AC90C3, 0xBD8E0187, 0xE73ED2E2, +0xCEE64CF6, 0x48B56436, 0xA33994CA, 0xB3E3B7AB, +0x060D5E14, 0xC1B176C6, 0x4A76C391, 0xD7C8DB1D, +0x333E4998, 0xC20BAC4F, 0x523BE3E0, 0x237E87BC, +0xE6CDBEC0, 0xC506F19C, 0x262C0039, 0x7F85A4AC, +0x46160693, 0x2EA1BC36, 0x4CAC0DF2, 0x0066B83F, +0xBCBC778D, 0x7F4AB507, 0x99CADB2F, 0xC95520D0, +0xC5CBF067, 0x903ECD68, 0xF5D7B0FC, 0x08198C8F, +0xA17879EC, 0x18C2723D, 0x5A4D6D37, 0x080198B6, +0x3525186C, 0xEF8BE144, 0x44B05851, 0x28B5025A, +0x0FDF085D, 0xDEB1F249, 0xA7C00F42, 0x7614A735, +0x3BEBF467, 0x7871D305, 0xD4F63809, 0x9D044079, +0xE585D3D6, 0xA89952F3, 0xF42C2B8E, 0x04179DA4, +0x00A6CE87, 0x96CA92B8, 0x9DF2B156, 0x3ECF18BC, +0xDE2509CF, 0x5CD85FCA, 0xF8A7CEEF, 0xCB7DC25E, +0xF2847474, 0x35B501D1, 0x137BBB3E, 0x451E1BB9, +0xD360D811, 0x792B3464, 0x4BF89A81, 0xA7E9C450, +0x628BCB0C, 0x2AF7037D, 0xA45F628E, 0xF0EC875D, +0x9CE3677D, 0x2CD0EA59, 0xA50A0217, 0x8BA45DD7, +0x1735ACF1, 0x5804C4D9, 0xE619B352, 0x948F44A8, +0xA9BF5C7F, 0x614D4F6C, 0x6D9FCA79, 0x29717B0C, +0x50BF2D5C, 0xD5847B52, 0x0D4FAAA5, 0x1AABCA5D, +0x779399E0, 0x58A90CD6, 0x37EC2615, 0x61B68C07, +0xC49F4AEE, 0xFAC4D897, 0x9C68CC6D, 0xBB3352F6, +0xF933436D, 0xD310078E, 0x2FBFA17A, 0x3D839C4C, +0x186E69EF, 0xCBE7CC6A, 0x7434231A, 0x80F8130B, +0x58CD7EA2, 0x2E46D714, 0x367286E2, 0xA6E2044D, +0xC2ABC50A, 0x6FEDC9C4, 0xE2F26F03, 0x3B030D52, +0x3674D8E7, 0x9096DF78, 0x90902892, 0x44A32190, +0xD08D2649, 0xEFE0ED0A, 0xCE1BF4E9, 0x62C19753, +0xFBF3D1A8, 0xD4AA5390, 0x4B32E77F, 0x9894F05E, +0x41B9DBBE, 0xE9B09561, 0x46C883A0, 0xADD5D60F, +0x69CE5BBE, 0xFD29CCF1, 0x2F209371, 0x4C6716E9, +0x31E9A09F, 0x04089795, 0xB9EF9025, 0x97C6267D, +0x63823150, 0x3AB346BA, 0xED3E0579, 0x85FC7062, +0x37B35761, 0x4A32B6CD, 0xC38EB479, 0x203642CC, +0x568FCAD7, 0x67D92B5D, 0xE51B8C3E, 0x02104078, +0x026BC607, 0x5A06CDA7, 0xE27435D0, 0xC7C20CE7, +0xFEA74022, 0x77310076, 0x35C6F953, 0xE1B199C5, +0x262F139B, 0xFD2FE2C7, 0x3EEE02EB, 0x915A873F, +0x2DE4AB8E, 0x2421DC15, 0xD1DD0D9E, 0xDE02B5AD, +0x151C76CF, 0x798B90B7, 0x82EDDF4C, 0x795E18CF, +0xF09CEC5A, 0x070ADF8F, 0xCDCF5232, 0xD498D43C, +0xB4FC2662, 0x25678E54, 0x5D200482, 0xC31F21C9, +0x35E5AF29, 0x8CC0E603, 0x995351AD, 0xD8EB54F6, +0x564E35D9, 0x0C13E321, 0x34CFA33D, 0x33D1E5F9, +0x2EAC9748, 0xFFB950D6, 0x2032206F, 0x4F871AE3, +0xBD464C61, 0x06356EA0, 0xA15A290D, 0xA78456D0, +0xD2F4EE88, 0x4D835908, 0x15DC87B3, 0x79EDB6C3, +0xAEAF0F9E, 0x5C3E7EF9, 0x639A099E, 0xD375D8DA, +0xB718510B, 0x090DF965, 0x9C8A362E, 0x25AD10BB, +0xF9A42BE9, 0x8ADE3DF0, 0x5527424E, 0x301F0D0F, +0x2F691C9A, 0x534FE1FC, 0x7D406016, 0xF98820A2, +0x4D204871, 0xED145173, 0xD67ECE9A, 0x35F9F990, +0x8ED4D787, 0x1F3F46E1, 0x5A68F171, 0x9A9D28B0, +0xE726BD5C, 0x8119228D, 0x0ADBA4D2, 0xEA243204, +0xE523C0D6, 0x261E3664, 0xB2D1211C, 0xB4D9293A, +0x9C89D924, 0x15A6A3A9, 0x0D8C6C66, 0xEC04AD36, +0x0CDF0F98, 0x9262C7DF, 0x8EE0E09B, 0x6B929EE9, +0xDCC713BC, 0x75FD34FF, 0x2784E694, 0x23C23044, +0xB7B04F09, 0xF10B753E, 0x2EC774DA, 0x470BE72E, +0x054510E9, 0x9C7DDF10, 0x1466C277, 0x9F52F493, +0x7F298608, 0xF1BA10D3, 0x8847A319, 0xEE8A63CA, +0x8E64B34E, 0xEBB66933, 0x575ADB24, 0x041BFD76, +0x727ED364, 0x00F4A008, 0x8F5EDA92, 0x21477637, +0x0B360617, 0x56DC8978, 0x27F88944, 0x69B799EF, +0xEA1E943B, 0x6FDD60B0, 0xCE2AD89F, 0xB98CCF43, +0x2A3796BF, 0x4DD02535, 0xC6B524EA, 0x6B173341, +0xDCE0A457, 0x91770646, 0x57A8D138, 0xFC218331, +0xDC6B712D, 0x14C0B3B9, 0x30CA09AD, 0x759EB942, +0xBC9634AB, 0x8F92A7E5, 0xF7F85B53, 0x6C831B3B, +0x56A75B18, 0x43DB9F1C, 0xF81FC212, 0xB8EB9026, +0x78A74B51, 0x870655E3, 0xA17B536D, 0xBDE866CF, +0xFC609F11, 0xF34A7016, 0x7C4FD4DD, 0x236312F6, +0xB50520A8, 0x4BEEA2C3, 0x2B690BA3, 0x18701667, +0xBD791FA9, 0x236D36CF, 0x49E576CC, 0x316A77E1, +0x93E9B0BF, 0x52715603, 0x83B9AAF2, 0x0F8F2A80, +0xA87F764A, 0xD2079BEB, 0x48A24AB6, 0xAC370950, +0x3077FB2F, 0x4BAFF3F5, 0x1A79926D, 0x8B369956, +0xAD78F739, 0xED88CE42, 0xB96A7C15, 0xA7BBA2EE, +0x47CC3233, 0x804DE962, 0xE0B431A3, 0x4A8257B8, +0xA4B0E8E2, 0x2FFC49B8, 0xF0CDF5E5, 0xF089C32A, +0x46328288, 0xEACBC054, 0xA48CB5CC, 0x77996530, +0x83A4E184, 0x3C2F47D9, 0x5106177C, 0x33F1A787, +0xA2266E7A, 0xEBC426C8, 0xD7E8ADD3, 0x2DF40477, +0xF9E8D7BD, 0x80BD8EAB, 0xE61CE55F, 0xF6A7EF6F, +0x5C67E1C0, 0xFBD0088A, 0x7ED37B24, 0xF5BFD58E, +0xC29CFB0F, 0x61ECE08B, 0xA776CFD8, 0x9E0F3A05, +0x8FC8B02F, 0xFDF82702, 0x028C2F2C, 0x169D3094, +0xE4AA3228, 0xF2CD142D, 0x9C70574E, 0x057BFE78, +0x782B9039, 0x0D01311F, 0x97552050, 0x6A097F2F, +0x1B3242B8, 0xF43F32FB, 0x96004287, 0xC3DC0939, +0x4215A0E1, 0xACD1A28A, 0x189932EC, 0x9BBA0475, +0xFA154E5B, 0x4B4E8D01, 0x4D6B18B1, 0x31545B3C, +0xC849C52D, 0x60958B9B, 0xE92CF090, 0xAC3E1B58, +0x251D02A3, 0xFAEE4F8B, 0xB1CF6CCC, 0xC2A0D8B0, +0x0501DF46, 0xD0369D94, 0xF3E11479, 0x397599F8, +0xB90064D2, 0x341F6D57, 0x31F0141A, 0x2F899029, +0xBC9EF6E8, 0x13B47347, 0xB93D59BB, 0x556E990F, +0x5727BDFC, 0xBA9F5121, 0xD67BE7CA, 0xB167E84D, +0x2C0ED0FF, 0x251FFD4A, 0xC98719F2, 0xD379D976, +0x8B3A0A9B, 0x40BA5F66, 0xE40A93E8, 0x2F89FC04, +0xFCBAFDD4, 0xF2424270, 0x1BDBDD15, 0x7F1459B0, +0x5ACB6C6A, 0xFA20719F, 0x2F16FFB4, 0x820DDE50, +0x468AAC15, 0x7816134C, 0x978D9570, 0x6745CD6D, +0xC1E768C1, 0x15E243B5, 0xBA30AD61, 0x483FB6FE, +0xCAA17D0F, 0x2F8F0974, 0x34AB68B4, 0xB3E864B0, +0xC1DA3828, 0x5DAD43B0, 0x72D13B81, 0x01F274AB, +0x9C0651AD, 0x0FC30C10, 0x0E7AA3CB, 0xDBE6B9D9, +0xF423B9A7, 0x457B4E32, 0x40E8E269, 0x91DA042A, +0x9DBF41E9, 0x308C0F2E, 0xCABFAC0D, 0x0E2C86B2, +0x117BC3C6, 0xEEA538F8, 0xF31585DF, 0x0DF50281, +0xEAA9601E, 0x8F408AFA, 0xF1144F9A, 0xA2AB2ECD, +0xACB88685, 0x6F4EFFBD, 0x81EEF886, 0x46B02240, +0x3C09D916, 0x4F0DAF68, 0x8337B3E3, 0x9A011BA6, +0x4C63AC66, 0x2FCC669E, 0x0C7D15BB, 0x51279D9F, +0xC1354779, 0xEFF940AF, 0xA956CB37, 0x0DB797E2, +0xE665EE55, 0x79AF879D, 0x21BBC902, 0x30B264BF, +0x411CDC98, 0xE453389F, 0x47C2C197, 0x3E6015F8, +0xF9E7AA2B, 0xA9302474, 0x04C6888F, 0x4D118BF9, +0x0DB7AAC0, 0x52A38EDB, 0x4DAB22F2, 0x7DBB6EAB, +0xD4D17851, 0xFD944314, 0x40C5838C, 0xBA6EB0EF, +0x9AA287A5, 0xF6D236F0, 0x41D9E2BA, 0x6968D776, +0x31B1D129, 0x42C3F963, 0x27CCAD30, 0xCD61BF4E, +0x2C7DABAB, 0xA78A9CC3, 0x7F856B6F, 0xB6D444A5, +0x90CBB312, 0x95611781, 0x4916D531, 0xC496C30E, +0x706D0CB7, 0x35D0064B, 0xFE26C36A, 0x6211F14B, +0x2C2340BA, 0x58633567, 0x06B6BA8E, 0xA7EC3D8D, +0x1071B0CD, 0x388EEFA8, 0x60D8FB1C, 0x5F99D147, +0x52CA6EBF, 0xFA73602E, 0x0376C15C, 0x3C91B57D, +0x9386AF17, 0x14A35A1A, 0xBDB42A39, 0x0E83C257, +0xD4C5C775, 0xA607FA46, 0x91B9AD40, 0x7623C5D6, +0xE3D53E6A, 0xA3C663E7, 0x5AD39BCE, 0x03B58394, +0x38862C7A, 0x01D50B9F, 0xEAAB38EC, 0xAB3DFB8B, +0x06795385, 0xB17F485E, 0xE2F57914, 0xB79A3BAA, +0x13DA7886, 0x7136C7EB, 0x5E748AF7, 0xD34F16FC, +0x968F6701, 0x99C5D7BE, 0x530F7FAC, 0xCDF5D567, +0xE31DE0D3, 0xCF93BC68, 0x34C578AA, 0xA201F761, +0x5CB8DC00, 0xCA24DB98, 0xF8AD7E4F, 0x808EC476, +0x603BA751, 0x489555C6, 0xF2A03FF0, 0xD2461E9A, +0x102C33BE, 0x7673933C, 0xC11A2424, 0x6A23C8C6, +0x69499812, 0x19AA8510, 0xC8CDA75F, 0x34B5216A, +0xD87F7420, 0xC8CEDB53, 0x8DF11BA2, 0xB10911C6, +0x3F1E5955, 0xF075F4EB, 0x17874FC5, 0x0D55685B, +0x5EE521E5, 0x46C72924, 0xF8540210, 0x5D5E4C5C, +0xE87A133C, 0x91633DC9, 0x36B54D5D, 0xA8B5D440, +0x7DB7D6C4, 0x5FA82C17, 0xAD679039, 0x86B3B839, +0xDF5121B7, 0xC08B768A, 0x338A512F, 0xCF9A4F9A, +0x5DEFBB5B, 0x4C9301B2, 0x08023702, 0x5B1D7E28, +0xEC800505, 0x3A869E80, 0x4C50C8AE, 0xB1AE9064, +0xAFFA34EB, 0xF2F006B9, 0xD8A9A3D1, 0x2C6C2134, +0x677EE648, 0xBB6B6D5C, 0xA285136C, 0x6C47BF4C, +0xAF158DC1, 0x0EF75E2B, 0x5B9C74D5, 0x9B8D4BE3, +0xE495BE19, 0x5940B228, 0x55E62656, 0x3247E060, +0xBF7094CD, 0x1C1AB380, 0xECEA2275, 0xB6DD8251, +0xCCA39DD2, 0xAB85D992, 0x278197D2, 0xFB6C9FD0, +0xBD53B458, 0x89EFE0EC, 0x52A3DFFD, 0xA6B7FF7B, +0xFB043649, 0x93C93F79, 0xAEB4CD6D, 0x71DB5C90, +0x9E8DFE92, 0x0F1A5B91, 0x55C5CF5D, 0x1A1847AC, +0x8D25CF6C, 0x914FD316, 0x39FCFE20, 0xD8F66A07, +0x2CDD3DC6, 0xE415AC72, 0x3D1BD09B, 0xA8322C59, +0xBD3A826A, 0x2A988A40, 0xEBD8B1DD, 0x9F53EEEF, +0xDF571816, 0xD4FCCDAE, 0xB85A1E50, 0xBE1A571F, +0x0ED07534, 0x4C1E471A, 0x8B4D36F6, 0x0E388FC6, +0x9ED2BC4D, 0x3E2D7F72, 0x752ACA15, 0x8960B48E, +0x5892B3D7, 0x70F6F3CD, 0x26C485EF, 0xC83839B9, +0xFE6C224B, 0x3547203F, 0xF73ACA84, 0x065DCDBC, +0x8986EBDC, 0xCD59EA14, 0xC0EF58A8, 0xC5587229, +0x484FBCEF, 0x9B8BF24D, 0x351CF946, 0xE10AA973, +0x17919640, 0x95FF7B1C, 0x82AB65E5, 0x070BCC98, +0x0E7CDB8D, 0x38DB27DE, 0xCA543C2B, 0x0131EB41, +0x8300996B, 0x88B63D66, 0x03ADAC1D, 0xB205A87B, +0xD8BDC0C6, 0x443F6071, 0x2CE69D2A, 0x6E1E5A53, +0x4EFF93AC, 0x70322657, 0x5CCDD146, 0x04C435B6, +0x5BF3CD69, 0x51E09115, 0x2545DFB2, 0xA52EF448, +0x8D387046, 0x7C4F1F25, 0x2EFFD8AA, 0xFD6422B0, +0xB82E26A7, 0xCF01CC45, 0x88899EBE, 0xDB621966, +0xBBA1822F, 0xB264AAEB, 0x1076EAA5, 0xC24B0CD5, +0x54D554B0, 0x4ECA7C05, 0xC8C9B053, 0x70A86D97, +0x4E3265CA, 0xEA24F810, 0x873B172D, 0x79A74D18, +0xEC3F49D5, 0xD1799602, 0xA21A28B6, 0x3FB99AD1, +0xC2DB35B3, 0x63EC2E51, 0x17E4489F, 0xE8E19164, +0x79ADD819, 0x10D66157, 0x5F621A73, 0x1CD063BA, +0x6665815F, 0xFA0B7081, 0x6E0FA473, 0x0CE3571E, +0xB5EAEF46, 0xAA04CF54, 0x336680CA, 0xDABBFF11, +0x2259E797, 0xB57B4470, 0x111EB4BF, 0xC171D42B, +0x5889A7A4, 0x419CCB3E, 0xBEA1F366, 0x41FE414B, +0xA65CB898, 0x6C28363A, 0x8F82FC84, 0xDBED5A9C, +0x4DBF3526, 0xF2F34E66, 0x9D2C9B11, 0x0C0D4DFB, +0x4DBF79D4, 0xA256E86D, 0x6407376C, 0x3F3E8AFF, +0x474B3593, 0xE55965C8, 0xCB20D358, 0x0C671A9B, +0x169F8342, 0xD2E1C9E7, 0xBDDBAAEB, 0x93DF0C75, +0xF27707F7, 0x5108305B, 0x4FF2C060, 0xEB9C08DE, +0xDF11020E, 0xD2271046, 0x6D1BFD27, 0xED020CDC, +0x2C22659B, 0x692050D9, 0xD14BE291, 0x3EBF8E86, +0x8344B625, 0x7840B91C, 0xB702BD5F, 0x4935D318, +0x01A22013, 0xF2A20B08, 0x651A1C38, 0x004FE633, +0xE51DCC06, 0xF5B86138, 0x9FBFF118, 0x6F7B3CD4, +0x028938B4, 0x071E96AE, 0xDF33DC9E, 0x79001AC7, +0x7B5D20FC, 0x3F137794, 0x81165B04, 0x973F8FD4, +0x0AE4CBF5, 0x7C48180B, 0x4A96BC89, 0x58066E74, +0x86669DC6, 0xDC55A218, 0x858C3130, 0x99AEAC91, +0x26983FC4, 0xEE4D4F06, 0xD8D6D657, 0x18EF262B, +0x374A620F, 0x85995F9C, 0xCC814AC1, 0x39F487E0, +0xC628177B, 0x2FAE2C39, 0x642525A2, 0xC1474F2D, +0xBC7CD49E, 0xE81E13F7, 0x83F42BDB, 0x8AB7D99A, +0xA8040B11, 0xD8AA68EC, 0x983B3739, 0xEE42ECDB, +0xC9513498, 0xCAA06A14, 0xE4784094, 0xE6BEBB9E, +0x13BE8018, 0x59E3D5D4, 0x0CF1728F, 0x963413BE, +0x319533B7, 0x14662ABE, 0x3363B45D, 0x59A99687, +0xBBB0FDA4, 0xCDBB8B21, 0x0240F3B1, 0x226DAC3B, +0x30E1C49E, 0x76E076D7, 0x4B91C598, 0xB3C46E2F, +0x4A657CC7, 0x66C3875A, 0xCBC6FC54, 0xF832EBE8, +0xDD1EAD3D, 0xFEFDAF85, 0x8DE51B88, 0xAEAFD5D3, +0x3E4CEA82, 0x55F47934, 0x9F8314CA, 0xD0220BC0, +0x5ACEF81F, 0x71FDD8E9, 0x13A14ED8, 0x6F1FC1E4, +0x75046A04, 0xC6C4FDAF, 0x4FFFF724, 0xF44FEDD6, +0x7E1C5CBC, 0x784C6B4C, 0x8D85F220, 0x38B65C3E, +0x8C992050, 0x2DE34C13, 0x9F2A4547, 0x48E58F65, +0xA280B689, 0x6F540D8A, 0x10B61B39, 0x1C8A2849, +0xA7316358, 0xDBFB7862, 0x182C553D, 0x92F04389, +0x1FE7BADD, 0x6A724CBA, 0x970BE020, 0x93760058, +0x2DF9E0AD, 0xCFF1F8B1, 0x170D810A, 0x45F4E6A2, +0x37A0E8FD, 0x86D11C6D, 0x4F3C6A3A, 0x4B144452, +0xCE9B87A1, 0x7C08C30D, 0x9CB9B0AB, 0xD55F2CC5, +0xFF95180F, 0xF35505BD, 0xED5BDB96, 0x85CA2E41, +0x8708B264, 0xD6079734, 0xCA76AB3D, 0xFD6CDF4F, +0x9AAB840B, 0x92D3A5F7, 0x93A92C38, 0x0419AA7A, +0x1D50006E, 0x126F48FF, 0xACDA412C, 0x01139454, +0x8E23C486, 0x01D44F51, 0x7A5F6F10, 0x377D4D5E, +0xB784E72F, 0xA9AC925F, 0xB9C66C79, 0x057331E6, +0xCFF040E4, 0x77E8A960, 0x35E31EEC, 0xEB807A44, +0x8594FFFC, 0xD27629B7, 0x5DDF526E, 0xBCF2F484, +0x88805013, 0x41047850, 0xB8574ECD, 0x3E15082F, +0x309C16DC, 0x297B6904, 0x30C39ECB, 0xD20B61AF, +0x51A578AF, 0x4E0D24A9, 0xC61FBE5F, 0x7A89F4C6, +0x9432299D, 0xFE261B95, 0xDD1FC4CA, 0x044BFB92, +0x41BE56CA, 0x0A2B6831, 0xE135D75D, 0xAB2D00A0, +0xB4374080, 0xFAA6DBD0, 0xA704C4A9, 0xD81385A4, +0x51533312, 0xED5EDAF7, 0xE4EDFAEB, 0x74B7DAFE, +0x9D810AA7, 0x40B91827, 0x65219BCB, 0x75431C16, +0x94D923D3, 0x00B7AA4E, 0xB8A88FDA, 0x927278D7, +0x7A237697, 0x45B14097, 0x2E3A562F, 0x93003322, +0x0B88A5FF, 0xD13D4ADD, 0x6D7B7579, 0x72D834C4, +0x0BCAA361, 0xC02E00B8, 0x15023551, 0x481C5E93, +0x02E81A16, 0x8A846A33, 0x1239A971, 0x994818B4, +0xFC3DBB6D, 0x43C8D2F2, 0xE3AE548C, 0x408032F1, +0x02B05636, 0xE361A60C, 0xFE2CA292, 0x061D2374, +0xDB285556, 0x70627EA4, 0x7FC64AF0, 0xFE100B6D, +0x71AEB3F2, 0xA565A412, 0xA698731F, 0x49DD9767, +0xC3627EBC, 0x75FB2DBF, 0xFDC0E971, 0xF6ED12A6, +0xA23DC00F, 0x897E917B, 0x7F2031E0, 0x17DCE568, +0xDF69CAD3, 0xC6FB5B6D, 0x097268B0, 0xE1102444, +0x86DF9383, 0xBD7B9CC2, 0xBAAF7DCF, 0x985B45D1, +0x4218E95A, 0xB2455EF4, 0xDB015F9B, 0x54CCCE76, +0x56EDF561, 0x6F66F95E, 0xF8B1EBD0, 0xF7A39AE0, +0xF66D8346, 0xA4677007, 0x02C4B3EB, 0x829987B0, +0x7C0E1919, 0x51F7060B, 0x4B30F1D6, 0x85A4E0CA, +0xEC049FA0, 0x17CBF1E4, 0x7A1AAD95, 0xEBA4C513, +0xE8462E78, 0x54CDDA0C, 0xEE7B8378, 0x9858C8C1, +0xBA33587C, 0x4D6F1B14, 0x7A2C0525, 0x7E6EE4D2, +0xACA18692, 0xDD186820, 0x41198B03, 0x8AC85AB7, +0xBD86900B, 0x36E2C354, 0xE65F9115, 0xB10645DA, +0x7971D230, 0xC83D3583, 0x8C60C81D, 0x94DB5741, +0x4FCB8934, 0x9A520FE2, 0xCE49446D, 0x8864E641, +0xF5EF25A5, 0xC1DEED0A, 0xC8057F37, 0xFB305C73, +0x392E670D, 0xA4D00D2A, 0x356A46F0, 0x2F675567, +0xB7997CF0, 0x88AF3A4E, 0x56C9D51E, 0xDD746ECD, +0x40CFA453, 0x5EA740CD, 0xE4DD6BB1, 0xCCB31429, +0xA2227F3F, 0x18A1EAF0, 0xC155417B, 0x41FE735F, +0x16D40B00, 0xC9F72AFC, 0x86B1D62D, 0x6A99A82A, +0x09D33248, 0xEC44639C, 0x9B0AB2B2, 0x6969164C, +0xEF602BB1, 0x0208FC6F, 0xC1109578, 0x2997AB87, +0xE5626B14, 0xCDAF48E1, 0x20781633, 0x2EBE0A41, +0x7379261E, 0xF216F7A1, 0x714D8258, 0x936FE68F, +0x160856F9, 0x2A4D1416, 0xB558E412, 0x7DB196DF, +0xDC88CCB2, 0xF37AB612, 0x7423F214, 0xD3B06A43, +0x25A8012D, 0xC1C69FFA, 0x936F2C18, 0x56D77C19, +0x774BFC69, 0xF5E85E24, 0xD79158C9, 0xA67C3E15, +0xB958819E, 0x69F81278, 0xF2B35107, 0xBF2F4085, +0x1C997A06, 0x6C238C3B, 0xC756D56E, 0xD15C1149, +0x351E6EC4, 0x2311303F, 0x0621602C, 0xB11B6DD1, +0xBE8E50B5, 0x34A5F589, 0xE4D308AE, 0x4344B297, +0xA33AE98D, 0x0A303CDB, 0x388EA17B, 0x0107B5A5, +0x38B39042, 0xFE678995, 0xB426FE69, 0x221FCF06, +0xC45926AB, 0x21A430F9, 0x6D192D2E, 0x4168C10B, +0x5BA6B132, 0x0519ECA7, 0x21127582, 0xF6C447E0, +0x0C72FC31, 0x0941B3F0, 0x76F23877, 0x86CF0677, +0xE7785105, 0xA4637864, 0x94C82B45, 0xF60FD6A0, +0x46941C27, 0x7A33A698, 0xE1DF8BFB, 0x5249970B, +0xDFE65E1C, 0xF4A4FB22, 0x599639F4, 0xFE0E9722, +0x7BB48F58, 0x533465E3, 0x9E884B35, 0x2620429C, +0x2875FFC1, 0xF11EC0CA, 0x663AF5F0, 0xB2C59C38, +0x03556ED9, 0x271E9E39, 0x8556E062, 0x08207682, +0xE5797F00, 0x66A362B5, 0x7ED8394D, 0x2922C374, +0x271657BE, 0xAC15071B, 0xE296691E, 0x0FE2C740, +0x19120FB5, 0x9ABD888A, 0xA200762C, 0x7837F41C, +0xC6F4EA19, 0xF286ABF4, 0xFCA8998F, 0x97B0E7D5, +0x1339C79F, 0xFED05D43, 0xB3392E71, 0xFC2A01EB, +0xB720CBED, 0x4FA71358, 0x04A57F62, 0x3D558B0A, +0x1DEB4D40, 0xC9C823F1, 0x470F630A, 0x08F22975, +0x2BD85107, 0x3288A628, 0xB0C89675, 0x32D957C1, +0x80B78426, 0x98A46953, 0xA493AF60, 0xC2B84AC4, +0x486D658F, 0xFE119FF9, 0xB2FE565F, 0xEADB58CD, +0x1F45F9B4, 0xCEAE62B6, 0x68EC702D, 0xF52ADDF7, +0x0FFC0715, 0x4129E42C, 0x956AC4D9, 0x0035CD9C, +0xF8FEBAA1, 0x29C58397, 0x7C2E2E41, 0x7BE74DAF, +0x2791D34D, 0xB6D67B0D, 0x8F557528, 0x9DDEED5B, +0xB3AA4BB7, 0x05E22E43, 0x4CDA600D, 0x432E2D32, +0x405DA5BD, 0xAF23818C, 0x2F73FE09, 0xD4624626, +0x653EFCB3, 0x77D65D3F, 0x51A3DCB3, 0x767F407C, +0xC66452E3, 0x10B6842E, 0x93A0840E, 0xE453AD10, +0xDE58FC3D, 0x6C227215, 0x1EE130EA, 0xB0BF64BE, +0xA11E5D38, 0x0131B755, 0x191F70D0, 0xDB483959, +0xAA8D2F9E, 0x5A002AA0, 0xF5A2996D, 0xFD0F95F9, +0xD6A12864, 0x3AA48B74, 0x50F6679F, 0x0ADF5C49, +0xE2F8CE68, 0xBF213E67, 0x5E9ACEEA, 0xCACD0EBE, +0x6DF766A5, 0x33C0A156, 0x720868EA, 0x3112A0DC, +0xB382350A, 0x369D9C50, 0xE8F890D0, 0x0A121399, +0x2AB458EA, 0x51C8233D, 0xBF46403C, 0x0728CD55, +0x23F6774B, 0x2FB59DB0, 0xFA2CF724, 0xB49FA848, +0x5FFFA125, 0xDE2C0D15, 0x76B78C41, 0x192BA62C, +0x4C9563E2, 0x8F742507, 0x882104E0, 0x357AD078, +0x799E25A2, 0xEF3ED021, 0x69D54B46, 0x5EC57870, +0x0FF418E0, 0x07C5AC7F, 0xC1ACBF9A, 0x80A830D9, +0x837C7C5A, 0x04C11D86, 0xC14C8BC7, 0x92BA650B, +0x94D34FA8, 0xDBDD5EDC, 0x9ED2A08F, 0xA1FAE485, +0x5FD66C3D, 0x4CCB6F9F, 0xB7AA56B0, 0x0FB3C73A, +0x03AF96E6, 0xDB2D38F9, 0x7AF20D60, 0xB57CBE90, +0x20EB2D6E, 0xCF934452, 0x82EC26F6, 0x84B3737A, +0x0972F1B7, 0x39B6DB4D, 0x13E53CC0, 0x67C41D72, +0x94BAAC78, 0x663A9C6C, 0x36927448, 0xCFBC2610, +0x980F53BA, 0x7E56C96A, 0x04C62DFB, 0xA471D579, +0xDF9B2EE1, 0xE12DEBB7, 0x2DB9B042, 0xF0C74B96, +0x6A3762E9, 0xF4DC39D9, 0x761A5884, 0xFA363D3B, +0x92766759, 0xF3EAD441, 0x878269ED, 0x1AFFAFE5, +0xCB432764, 0xFE19475C, 0xCF8776DA, 0x1F0AD906, +0x7D99AC20, 0xC27317FB, 0x439944A4, 0x65D14C2D, +0x43E45262, 0xCDE6B3BD, 0xE25C67CD, 0x321AA2E6, +0x352A2764, 0x5569EF42, 0x005C370D, 0x290801E0, +0x61883035, 0x2A2DBC48, 0xE2D559FF, 0x01F5DF13, +0x69B61558, 0xE94BF364, 0x3CA76FCA, 0x2E016483, +0xDB675F9C, 0x4FA5B6DC, 0x59A6C3EC, 0x56C6E6CF, +0x24CD59F5, 0x46911834, 0x683B9E39, 0xB5AF6174, +0x5C31E269, 0x679C9A12, 0x3787D3E6, 0xF1727EE6, +0xB070882F, 0xFC37EACA, 0xBEE0783F, 0xF6218369, +0x19372940, 0x3FF7D890, 0x69736919, 0xDD961CB9, +0x883010F1, 0x6E472D5B, 0x2447E00D, 0xF39E1F0E, +0x1DBD442F, 0xBE1977E0, 0xC8655F42, 0x37C84253, +0x3480DAC4, 0x4CFE1DC8, 0xF1521AD5, 0xA45C4F8C, +0x87FBAEE0, 0x3E41E9E2, 0xF47771E5, 0x16C74CDF, +0xA33D4035, 0x38513A10, 0xABF3264D, 0xB8D80DF6, +0xD9AD7256, 0xF78375B8, 0xD7661CF7, 0x1C363AF9, +0xD425FA32, 0x001D7B98, 0xDB96A1CC, 0xA092E683, +0x65CF5316, 0x5F282689, 0x9F52F912, 0x8958A1B7, +0x6457A3F7, 0xAB43FADD, 0x061328C7, 0x9D31B5E3, +0x75A77F6D, 0x4A764D4A, 0x488CE83E, 0x29887218, +0x9A04BDD0, 0xEF331070, 0xBCD2F884, 0x6BF66A6F, +0xB85143CB, 0xFA529278, 0x9EA3A354, 0x4A73BDAF, +0x0CBB7563, 0xD01AE35F, 0xD2AC3DAA, 0xFC8243B7, +0xD805D97B, 0xC162A75F, 0x1D49AC67, 0x9E1BC38C, +0x1D06AAE8, 0xEAF80CD8, 0xCE825DD4, 0xACA3F06A, +0x83D092EE, 0x3F2BAABC, 0x2482D120, 0xF301680C, +0x7DAC373F, 0xF5D6178D, 0xB7E9217F, 0xCCFE8C13, +0x976024E0, 0xA2F39F8C, 0xB6C65734, 0x10AE514A, +0x696584CF, 0x2542113C, 0x479CB20F, 0x8D3A22E3, +0xF7C4B88C, 0xF4F7FBE2, 0x2F553308, 0x9EA71E3A, +0x7B958F48, 0x0927DAAB, 0xF08949B7, 0x7CD46C0E, +0x7A892BBC, 0x882F32CE, 0x34C490C8, 0x8483ED04, +0x07EB4EFC, 0x4BEBCD82, 0x83B15EE8, 0x8F3B78AC, +0xF95EFDA9, 0x816BEBF9, 0x269BDA58, 0xEE373342, +0xE09FDA9F, 0xC7651AAB, 0xB8D398B2, 0xC7F449B2, +0x031310F5, 0xC869706F, 0xDA22F127, 0x8C68DF91, +0xE676068A, 0xB85AAAC7, 0xD32F35BC, 0xE22DF031, +0xFE142BD9, 0xD4FB2700, 0x2D197707, 0xA3A43A64, +0x0C02B050, 0xE945AD56, 0x7DEE0A5D, 0x1075DE3E, +0xD99AD91C, 0x6A7BB71D, 0x1774B3B8, 0x2228B112, +0x0DEEE844, 0x38074EBE, 0x6DACF57B, 0x7E0094B7, +0xCE46F8EC, 0x4DAF34F4, 0x5B961907, 0xC8236FF7, +0xFD380AA7, 0x61EBA84A, 0xAE4892EB, 0x0F1B6365, +0xB0C4C9A0, 0x04E6012D, 0xA5F90D01, 0xD6C8882E, +0xBCB9C1EB, 0x0E5E0FEC, 0x53A46889, 0xA2C0FA51, +0x520DA459, 0x3FD95FA2, 0x6E1D6FE8, 0xBC093220, +0xAB16390A, 0x163E3D6D, 0x0A63517C, 0x3BF38F3D, +0x88A1F66D, 0x96263536, 0x412DF008, 0x12FB126D, +0x44441D7A, 0x31C9F726, 0xF66F60CF, 0xAE1453D4, +0xDAEAD71B, 0x54EAEE0F, 0x948B73BB, 0x31EA3E74, +0x355D4FDC, 0x2A1F3A9E, 0x586D08DF, 0x123AC2E8, +0xF5AC0065, 0x8874ACAB, 0x05B03D63, 0x01BD6A4C, +0x7A6A9880, 0x2BC16F93, 0xC4112F0C, 0x8287B40D, +0x48EABF08, 0x29E56860, 0x0F505C84, 0x447DC08B, +0x1665119C, 0x00347E37, 0x482EF03E, 0x01B15D44, +0xE6C1B9FF, 0xB165E436, 0x0CF690F7, 0x7FC5BD01, +0xB784C7F4, 0x9BE04EBB, 0x9F614431, 0x6C37A5A9, +0x2D0DB87D, 0xF6511369, 0xE115073A, 0xF96C6AB6, +0x04A13C3C, 0xBF30B2DA, 0x93D18FC6, 0xF67D2E47, +0xCA089151, 0x51A6BC39, 0x8C1FCA93, 0xFBF2F2BB, +0xAD0A3F33, 0x82AA2767, 0x81BF2313, 0x758A82B8, +0xE103788E, 0xC00C4B5C, 0x5F52FF58, 0xABAD38F7, +0xDA68EE9A, 0x9B6D405D, 0x803449D9, 0x6178B345, +0x3C785FB4, 0xFEBABE55, 0x0E2458AB, 0x021F0D71, +0x39201ED1, 0x741B1A7D, 0xE0B0AFF4, 0x45652CFF, +0x907DA678, 0x313A93B4, 0x0B0D6B0D, 0x42C96E43, +0xEEE3E7E1, 0xE83C83E9, 0x9052B867, 0xF9514243, +0x61F20CB2, 0x57E1AC64, 0xC2443123, 0x432C96D4, +0x616A824F, 0x3C8D1E06, 0x8E64222A, 0x65C1A21D, +0x8686308A, 0x2A576A2F, 0x1CA0FF20, 0x2C8F9D3A, +0xC98C9C69, 0x35322A29, 0xDFD33C93, 0x9634F411, +0x0B4F8FFC, 0x3AED4B01, 0xEBBC7012, 0xED2387EA, +0x48BF42AF, 0xD60399D6, 0x7A9B8CA9, 0x53886337, +0x2DBB9429, 0x0A6AF764, 0xDE4D8F78, 0x1EDECEE4, +0x4F8EE99E, 0xAF23EAFD, 0x929550B1, 0x2CBD8621, +0x22A8FAA2, 0xBE2A0A8D, 0x06F7E794, 0x16E1F3EC, +0x093AAEAA, 0x92D429F8, 0xBB79A7E7, 0x43EF89BB, +0x0E097511, 0x748E68B0, 0x322C00AC, 0xA62EF42A, +0xD03BB8BC, 0x9FF67810, 0xDE24BF03, 0x140CA6FD, +0x68F16B41, 0x1B7C68C7, 0x32646342, 0xC5E714F8, +0xEFFFD2B8, 0x27843628, 0xF8445F51, 0xB9E8519B, +0x8EB01D04, 0x356FBF2F, 0x32E96BAD, 0x6A629BDE, +0x52063313, 0x200069B0, 0xE161CF71, 0x84FB7A12, +0x1805ADC0, 0x80F75012, 0xFE9E629E, 0x93395C33, +0xFF075A91, 0xB61E46B8, 0xCA9FE7C8, 0x97DCCBCA, +0xCEFFB6F8, 0x30EE7985, 0x1FABC829, 0x20B3F57B, +0x27042B07, 0xE12C5151, 0x23482B8A, 0x7B9B8EB2, +0xC997FEB3, 0x76AB2497, 0xD5CDA590, 0x9EBE90FD, +0xE3732B18, 0xFF28CEC9, 0xC6582320, 0x6EF106FA, +0x8ED74023, 0x1A0B69E5, 0x4A95DD91, 0xB41AF82C, +0x83DF69D3, 0xC548861C, 0x2F60BA93, 0xFC815984, +0x1A848B67, 0x1EAE87C4, 0xF7479103, 0x8E16DB51, +0x040B95B9, 0x2A9DB812, 0x987AFCD1, 0x866DF413, +0xBF9558ED, 0xACF1AF2F, 0xA65305CC, 0x168336F3, +0x1E59B97F, 0x3F9F447C, 0x3D54B30D, 0xE939D598, +0x36A40885, 0x02396794, 0xEB0F0A67, 0xCEAEA12F, +0xC58B4AC8, 0xE6D49760, 0x0F8F2776, 0x66A8F436, +0x31BACD7D, 0x376993DE, 0x32BD0431, 0x68BDC728, +0x63EA6748, 0xE6B00E29, 0x7448CABC, 0x42A6517D, +0xBB1313C4, 0xA04DC8FF, 0x3D402237, 0xA382645F, +0x52ED55D6, 0x92D7D7B7, 0x541230FF, 0x7AFC0420, +0x3DC4624F, 0xD9B2193D, 0xA73B9704, 0xBBDE0FF1, +0x9EB56615, 0x8AB080B6, 0x3C4D8E14, 0x5001B43D, +0x1EBFAA23, 0xD4AACD27, 0xCFAAB4BB, 0x6FFEE61F, +0xAE5A7426, 0xDB942949, 0x452C0B16, 0x738E0637, +0x36A5122D, 0xFF1F7A4E, 0x743D35CF, 0x847D54A9, +0x42C3EABA, 0xD46728C5, 0x30B2708D, 0x4F6BE0BC, +0x3C26790D, 0xB0B67C8A, 0xEE07EFDC, 0x9E380611, +0xEAD6804C, 0x4EF66024, 0x8459AE38, 0x1DEAAFFB, +0xF76573AE, 0x6CB1C8F0, 0xFFCC267E, 0x26A215F7, +0x0B1A057C, 0x7DAB9CB7, 0xD40BCBA9, 0xE561F9FE, +0xA44013A6, 0x7B22C0B9, 0x998A921F, 0xBD25244B, +0x15E07FED, 0xF15B2E31, 0x54E80016, 0xA12BCE7F, +0x658A2093, 0xB642C47B, 0xD731FC00, 0xC00E302D, +0x55B251DC, 0x342939EB, 0x6EADB2F7, 0x0CF93318, +0x61EBD85A, 0x99B715EF, 0x679C8D3A, 0x9CC1B803, +0xABEF955E, 0xB8CFF9D4, 0x707A839F, 0xF5D02A7E, +0x59E0D903, 0x5A425E3B, 0xBB61163C, 0x96ECE9AA, +0x797B82AA, 0xA9FA6BB6, 0x797C00DC, 0xC1C1FC4C, +0x8F7FDA66, 0x77902514, 0x6D1B843D, 0x4F881FA4, +0xC24AD625, 0xBC237A45, 0x9A2E0F44, 0x82FAA3F3, +0xD70E3489, 0x4F2B3417, 0x65CF65E4, 0xEAAE6A93, +0x4BEAEC2C, 0x4918723D, 0x7D8F30B4, 0x7706F59A, +0xCB2A7452, 0x5083D2D6, 0x4724B426, 0x84EB15DC, +0xBAA2C6CF, 0x71FA984A, 0xDDF7A3DF, 0xB115BF1A, +0x258AF0E3, 0xA1637D87, 0x03585DF8, 0x5EA4B80D, +0x8641F318, 0x66EE2F24, 0xC81E505E, 0x5E640639, +0xDB7739B8, 0x1A3B861F, 0x0F5ECC51, 0xB21C00DD, +0x680FF30B, 0xDE697468, 0x57A43B33, 0xD7EF6B3B, +0x4BFC7D25, 0x710F0752, 0xABAA9752, 0xCFCFD84D, +0x3BCC1CDC, 0x2381C524, 0xB60CAD92, 0xE05BC1AA, +0x2B887D88, 0xCD4566C5, 0x0D2976E7, 0xCB000A2C, +0x667BECF6, 0xEFC7F221, 0x7A7584D1, 0xC41D8B2E, +0xD9BB7D3F, 0x7CEB5626, 0x7D8165A0, 0xEE178F99, +0x3E8A8CB7, 0x693D4501, 0xB0E228A5, 0xD55B73C1, +0xAF9043BF, 0x6C627A2C, 0x7B9F490C, 0x7EA61899, +0x92B980AF, 0x6D13C758, 0x2C007C73, 0x74336E0D, +0xA39F13AC, 0x533F05D7, 0x75536CFB, 0x9708DE27, +0xE2A14E87, 0x36673FEF, 0x71BA654F, 0xB98CD2FC, +0x27F29A6E, 0x82478171, 0x1C2815F0, 0x8A8F4549, +0x048A8D9B, 0x7CEE51F2, 0xA1648AC3, 0x004F8B8F, +0xB6FE8EF0, 0x6D10A0A1, 0xAD7A24D8, 0x75039717, +0x97847786, 0x2791CC05, 0x6937FD6F, 0x60F98115, +0x5FAB6D35, 0xC0550A70, 0xC0F4D817, 0x7B5BFDDB, +0xEF63B4D2, 0x6C87C6C5, 0x956D6B87, 0x69179257, +0x10973C90, 0x8CDBE860, 0xC7C761EE, 0xF823E34E, +0x6FA2CF3B, 0xA903ABCB, 0xC82C9B01, 0x60FE96E6, +0xE5EC33C0, 0x73A3011C, 0x2A1B9054, 0xCF16F92D, +0x4FAF6CC8, 0xD9DD74FE, 0xB3C639ED, 0x3F47AF63, +0xC8E99D12, 0x92D95986, 0x835ACA6F, 0xD52930A2, +0xC7DD54A5, 0x617FDD15, 0xE9A6D295, 0xF56C6087, +0x7813B662, 0x1F8EA244, 0x1CDE3BAD, 0x58FC0F7B, +0x02E31A5A, 0xA78EAC74, 0x10C06107, 0x22BA3C63, +0xF84AD224, 0x6A8BF66C, 0x2A5CAAC5, 0x8ADC3FB5, +0x9683451A, 0x1B52FCB4, 0x95491BA5, 0xFE6C3713, +0xE9098CEF, 0x73C01EF9, 0x6E85EF1A, 0xEE189743, +0x2E9E5286, 0xC1FAA665, 0xD861E384, 0x701C834D, +0xDC5CA5CC, 0x52A3A6C4, 0xF2AF2C43, 0xC37C6465, +0x6E94AD69, 0x98808AF4, 0xED8A99F2, 0x377257D3, +0xE60F2096, 0x615EFCB8, 0x67A2BB3A, 0xB4DDD40F, +0x1D47F918, 0x86F77D6E, 0xFD05D2B8, 0xE18C330C, +0xA48260A4, 0x5615B83B, 0xBCD7D855, 0xF8073219, +0x8622BB89, 0xD35CE05B, 0x17162483, 0x137BDB69, +0xECD0F226, 0x61F8982A, 0x3C10ABD4, 0x2F33ABF4, +0x9358B547, 0x58B277A7, 0x92456A7C, 0x4384B49A, +0x5F1FF0EC, 0xA153EA4D, 0xA8E49100, 0xD3A75723, +0xD1ADC606, 0x76C314B7, 0xBC6AB227, 0x257312AF, +0x8B6AA1E3, 0xD87FF5E8, 0x2BAED373, 0xC848AB63, +0xB72B1E5E, 0x730A73D8, 0x4915E5B6, 0xDF7D77AD, +0xEAE247D7, 0x9556DDA8, 0xDE0C9C47, 0xA4E3296E, +0x31F5BC94, 0x05258B24, 0x2837374F, 0xC7E4C81B, +0x5A1AC819, 0x068074AE, 0xDF876732, 0xC0192EF9, +0x7FFD84D8, 0xFF1CE148, 0x821B4AA3, 0x56674838, +0xF9A147F4, 0x182EF58B, 0x16E17174, 0xDE27029E, +0x8BEC55AD, 0x40646F89, 0xDBFF92FC, 0x9F24C017, +0x711EAD18, 0xA663E1EF, 0xEF92F684, 0x4BD05E67, +0x7E089B13, 0xCBF619BE, 0xCEBEF231, 0xC947586C, +0x0F526C47, 0x6672600F, 0xDAAB63DD, 0x950D4FD0, +0x199C3EC2, 0x0F201C9D, 0x06BCC8D3, 0xA7672C6D, +0xB39C7D0C, 0xC74B0805, 0xC9BBD249, 0xACDD5396, +0xAB7BDF8E, 0x12012B8E, 0x67236047, 0x0AE0741B, +0x1D747E56, 0x7EC6C00C, 0xD08E8341, 0xB0ABDAD6, +0x4FA4BDF6, 0x90CE8D0E, 0x6E734117, 0x3EF9192E, +0xACA32DA2, 0xFDB9C58E, 0x256626B5, 0x5EA961B3, +0xFBC15776, 0x36602B5F, 0xF8D08644, 0x5B693C23, +0xC62EA3B1, 0xC664C7C3, 0x73BE8859, 0x17F44E8F, +0xF9B8D923, 0xD168A3A5, 0x6CCD110C, 0xD353181F, +0xC0E774EC, 0x5F9E127C, 0x6C824511, 0xFDA13494, +0xCB588BA6, 0x47148694, 0xAB877E87, 0xE97F757B, +0xF54D0A2A, 0x0FE11891, 0x5D8747FB, 0xE7800C7E, +0xEF96298F, 0x400F458A, 0xE2D04518, 0x4B4E6EFC, +0x9B15002C, 0x3CE1B537, 0xF5ACB9B8, 0x67030647, +0x475FD148, 0x1E03A40A, 0x896C7C05, 0x85F70B68, +0xC590CA84, 0x53B5440E, 0x1400F78F, 0x3ABE7F8A, +0x19CA67FF, 0x68B54A34, 0x555988AC, 0x4AB16B4A, +0x7511FA63, 0x248EC9EC, 0xC25AFE4F, 0x19F578E1, +0xE92AF03D, 0xAF9DE18F, 0x2798C7A7, 0x6B46990F, +0x41D45894, 0x74696A0A, 0xC6AAF5F8, 0x72CC10E0, +0xDB9CA283, 0xD6BBD0F3, 0x58EA4C06, 0xDEA5E8B9, +0x1908EBDB, 0x95D33DD5, 0x20D7013C, 0xE725C282, +0xFD48C92F, 0xDBBA7D19, 0xC7BEBEA9, 0xB186B799, +0xDD0DD17B, 0xD8090A41, 0xF98BC20B, 0xDD7E4B9D, +0xEBAE4247, 0x4376FDC4, 0x7F3EFAC6, 0xA9B9A951, +0x4AE390C4, 0x651863AF, 0x2CD42DBC, 0xC2A13962, +0xEF0FC443, 0xAEE63246, 0x09B83E19, 0xC3C940AB, +0x00B12826, 0xC0A30412, 0xFCF6ABCC, 0x3CFE721A, +0x62C1F4C6, 0xE963A359, 0xAE11F3D6, 0xE490D12A, +0xC45C928B, 0x05CCA78A, 0x1982E93F, 0x577F81CA, +0x66D50D6E, 0xB4C7030F, 0x93092C3E, 0x118B08FF, +0x178545B7, 0xEED74838, 0xF7D2CE48, 0x238969BC, +0xB8EFAEAE, 0x75726A3B, 0xB1E0220F, 0xC4D60EB6, +0x0EBC0243, 0x5FE0D6CA, 0x35456B45, 0x1F64AC2A, +0x58484A1F, 0x2A11455D, 0x33BC4403, 0x56E4E62D, +0x60B41E2B, 0xDB65D3F8, 0x7EC18D34, 0xF575DC85, +0x6E0B9995, 0x1C14C91E, 0xB2A94718, 0xAEC4A823, +0x993D374E, 0xF1E4210B, 0x8CFCC03A, 0x99BD1C28, +0xA928E3F9, 0xBB957D0E, 0x77C865EF, 0x7FF50A45, +0x4279A638, 0xE628FFA1, 0xBCCA171E, 0x284C9CEC, +0xA476E346, 0x7E2F9C08, 0xBF65044F, 0x5B7C3D5B, +0x6E60EE5D, 0xF5C99509, 0xFA352B7E, 0x6FDE8E8A, +0xF2340FE1, 0xDF542B6C, 0x510CB30B, 0x367E7016, +0x198A0A95, 0xA4DF508E, 0x593C2338, 0xB12BCDE1, +0x554AD3C0, 0x4DDAB1C1, 0xD2BD1850, 0xF6E126CA, +0xF87289C7, 0x86EC92A5, 0x4E033906, 0x52DC5F3F, +0xCC6E2E59, 0xFF751753, 0xDF8B8BA2, 0xDBF5954A, +0xBD367488, 0x6A0CDF1F, 0x4103139C, 0xDE49DBB0, +0x5A8428F4, 0xA26872B1, 0x96BF7203, 0x99D5E78E, +0x243850A6, 0x389DAD80, 0x6335D33F, 0xEC67B0A5, +0x029C0CA9, 0xF5F6F6C9, 0xDF574C15, 0xE6D3EC29, +0x1AA349BA, 0x453E7258, 0x7DB79BE3, 0x51FCA7F6, +0x2B42FCA5, 0xBF0E4871, 0x58063C40, 0x193580E2, +0x25605322, 0xBC49C479, 0x0ED70FC4, 0xA78B59A0, +0xE6CE3E8C, 0x92EE657A, 0x63D12529, 0xF95DAF45, +0xF92C3BF3, 0x7D514200, 0x694DF84A, 0xEF177E2D, +0x4E119CCF, 0xA025C55D, 0xF96974D6, 0x26D13E7F, +0x799ADC27, 0xD7925EC1, 0x8AE60BF7, 0xF9EF1A2E, +0x89EADD3A, 0x9C28CACF, 0x63377EB7, 0x6D1EF7E5, +0x6585B16C, 0x9972D115, 0x65F8F5E6, 0xF93DECB4, +0x6D71605D, 0xC6FDBCB8, 0xD937BA31, 0xCED727EE, +0xC34C5605, 0x25FA70B6, 0x5C0B7FB0, 0x8F9340F5, +0xA3376693, 0x4498B66A, 0x2D21F377, 0xC0A4C6EA, +0x0780736B, 0xF42D7F07, 0xE56D47E5, 0xB48C25D6, +0xA48DA0DA, 0xFE69693F, 0xF01E19CA, 0x8A0C5C8F, +0xDF702C23, 0xE18A93F0, 0xD4D5C91E, 0xD2A706F7, +0x674F9E28, 0xAF0F80C7, 0x648D49E8, 0x6BE8640F, +0xF5FCFFD5, 0x8EDC391E, 0xE583D8BC, 0x8426C090, +0xF456A27D, 0x07249BF4, 0x054A2F45, 0xAC46B73B, +0xB89EEDFB, 0x48EAF867, 0x69B2D7CC, 0xCA0CA0F1, +0x38CD0428, 0x029808CF, 0x86EE75DC, 0xF4FEE9F0, +0x6987D5E9, 0x56AB5537, 0x3DDD0940, 0x4742FF89, +0x2C3B179E, 0xD05B5CB1, 0x3C4E9033, 0x6BCF0141, +0xF2F6D3E2, 0xAD297B1F, 0xB1CC23D4, 0x5452038B, +0x1751FCBE, 0x24AA465F, 0x94C62D18, 0xF49B2EC8, +0x97AC47DF, 0xD66C19B5, 0x09AAB297, 0x89936144, +0xD15C026B, 0x4CEC8778, 0x94050D61, 0xD812E96F, +0xB6BD7B12, 0xA5F9BE77, 0x531A5C7A, 0x3605BA71, +0xD500CE54, 0xE325964C, 0x323432FE, 0x580A9DC8, +0xD25A3135, 0x089D6C9C, 0x58856F73, 0x7DFCEE30, +0x7DE2580F, 0xF4E4488B, 0x71821DDF, 0xD194F5DC, +0x7D070394, 0xBA28BF76, 0xAAF0A38E, 0xD4F6275E, +0x1B742E66, 0xD9E68EA9, 0x68B0F939, 0x52AF9D7B, +0x54A39705, 0x20F844C1, 0xE6981DDC, 0x80322E62, +0x536235B9, 0x7A57F4FC, 0x14EBF376, 0x64BE2E5A, +0x70A18910, 0x0FE09587, 0x10E9CA78, 0x8F90D3D2, +0xAE74717D, 0xA544EAED, 0x6746AF3E, 0x430CB3FC, +0xBC185576, 0xEAA35DC3, 0xDA6309D2, 0x40643F87, +0x68859117, 0xA17AC84D, 0xD7922CA8, 0xEF7C0BEF, +0x83337348, 0x9B4B1790, 0x8876A77E, 0xF293C9C7, +0x20D399CD, 0xA78224BA, 0xFD1279C8, 0x8B7837C1, +0x0F1DD415, 0xAE3FBD2E, 0xC4F77B52, 0x51E79FB3, +0x7A856D9D, 0x14BFDAD7, 0x993FB625, 0x667C65EF, +0x32F83338, 0xAA06EDCE, 0xACE7A099, 0xD26DAE89, +0xDC6891CE, 0xCD2F6F04, 0x27425FB8, 0x7C301D8D, +0x1EDEBE1A, 0xBE540AF8, 0x1D356C6A, 0x963E8639, +0x9920CA55, 0xDEFE5F44, 0x107D5545, 0x3D079BE4, +0xEF673F66, 0xDB3C2954, 0xDD76D666, 0x1DFBEF59, +0x8F384B34, 0xBE6F773C, 0x079DD187, 0x2314AC8B, +0x5FEB0114, 0x59E85CF3, 0x9BFE9190, 0xB360A31B, +0x4F7EF967, 0xFEB0D561, 0xBFE779F2, 0xF33702B3, +0xBB263417, 0x09607C65, 0xA877F109, 0xBB43CFF1, +0x4A190DB2, 0x9B7BD38F, 0xAEB7C449, 0x3DB3A460, +0x7D928522, 0xD18AC966, 0x187FE766, 0x97629792, +0xF59D506E, 0x6FBA202C, 0x77035FF3, 0xDA068CDE, +0xE195779A, 0xAEB92298, 0xD2A44EDD, 0x12577D85, +0xA3B47B9E, 0x5BD07CB7, 0x4B6AE3FC, 0xBE35B6E2, +0x9D7F7AF2, 0x9A38EA75, 0xD87FB055, 0x3339F2A3, +0xD7CB82B4, 0x357721E4, 0xBEF46553, 0x9DE28CA3, +0x1B1EC2DF, 0xE29B9CC0, 0xEFAE347E, 0xE5864917, +0xA097B712, 0x6B67041E, 0x5B29542F, 0x01D96EED, +0xF9A6DC07, 0xC0B5E3F0, 0x21E1899C, 0xE9373A86, +0xF3176509, 0x950844A2, 0x7D24FFEB, 0x5DC0BCA0, +0xC442B7C1, 0x37DC6EC1, 0xC65C8BA5, 0x18F0FA85, +0x2AD80D2D, 0xC68CDCBB, 0x6AE5EC93, 0xE3955DBD, +0x3E80C4B3, 0x50FED127, 0x743CABC0, 0xD0E91707, +0x9BF7EB4B, 0x7A632755, 0x9A192482, 0x8F923E9E, +0xE2E70FE5, 0x5F50AA16, 0x0EC496D1, 0xC6EC4862, +0x040A0274, 0x2FC951C2, 0xF65D3A80, 0x8D585163, +0xC6B529D1, 0xD2CAEE6E, 0xE3E112B7, 0x3244312F, +0x1B393E58, 0x2444D538, 0xBE69AC21, 0xC92A0506, +0xD1A74434, 0x49C3EA05, 0x0E53B319, 0x3843CE03, +0x8DB8415E, 0x766B6FC7, 0x515B9E7A, 0x3BA05B32, +0xBFAFC449, 0x31302A57, 0x1960A211, 0x66A097E0, +0xBC65A9B4, 0x89E83065, 0x36FDBF2C, 0xDCD4664A, +0x0ED6CFBF, 0xDD4DC6DC, 0xD76D2F00, 0xB6DA6540, +0x9A396444, 0x28F185DE, 0xA0FEFA1D, 0xF476E0ED, +0xEF15505A, 0x183365BF, 0x481FFD90, 0x29ABEE75, +0x1EC90B07, 0xC10B2657, 0x0DBF6DDB, 0x52AD02B7, +0xE87DDB54, 0xD3704106, 0xD4E2C592, 0x0CB2DD05, +0x4BAA2FFB, 0x02611368, 0xD50F8F1C, 0x416FF25C, +0x9A69782D, 0x268C6474, 0x2ECD4D64, 0x196DE2F5, +0x47A8561C, 0x8C7CE6C9, 0xD2B1E2D2, 0xA038C165, +0x3AB8844B, 0x4A699830, 0x0FFC0B17, 0x89B685AA, +0xDA276D85, 0xE934C4CD, 0xF511226F, 0x9CDD2B1F, +0x94F75492, 0x55ECEB42, 0x42F0A3D3, 0xD7EB482C, +0xA78D0373, 0x62F088A6, 0x7ECF4602, 0x7A3404B6, +0x40B36495, 0x60441DF4, 0x6722F539, 0xCFE76C48, +0xB6B94C9F, 0x9ADB4B6A, 0x1EBBA65F, 0x5B5081AF, +0xB764423C, 0xB6F910E3, 0x14AC4B6F, 0x5C811E82, +0xAA36E5F1, 0x24EC82AF, 0xA2F1C050, 0x0504324C, +0x304CED0F, 0x01E31DD9, 0xC82EC7E6, 0xD55AFFF9, +0xFFB3047B, 0x3006F2E9, 0xC725BCD1, 0x7DCC1082, +0xA9A22CF8, 0x64D5AF9D, 0x389C34AD, 0x7DFF37C6, +0x41F1509D, 0x1845B3FE, 0x055C23F0, 0xC6291F5F, +0xCDD3C7DD, 0x5F0356B4, 0x7FD2C387, 0x494A091E, +0x50C69D3E, 0xFE769A5A, 0x63904701, 0x8960ABF2, +0xE68EDF3A, 0x0AB57C8E, 0x0B9D0A6C, 0x51888148, +0x50C5D533, 0xC69038FA, 0x3ACBE661, 0x0CAEB601, +0x8C14AB6C, 0xBA86D94F, 0x0724056B, 0x0FEFFCBA, +0x12449DDB, 0xABFFECCE, 0xB12A2BD7, 0x7260A0E8, +0xBE184A48, 0xCFD3CA3F, 0xDF088660, 0x78EE9B67, +0xA9EDB113, 0x4FD5D353, 0x8E348CC6, 0xD578C337, +0xF0493BE9, 0xCCFB54EC, 0x9CEEF85C, 0x0CAAE15E, +0x371AD12F, 0x9C5B9270, 0x2495F0DE, 0x06DE2DBB, +0x911AE7EC, 0xEEDE3363, 0x6DD38D6C, 0x2AF7F3D9, +0x51C8D118, 0xF23818A7, 0x95438AEA, 0x3A8A798F, +0x230D2BEF, 0x3D16273C, 0x9C36FF83, 0x785C9537, +0x3E42AF2F, 0x12A16741, 0xE58D0DC4, 0x33EBEFF9, +0x6F1972DA, 0x128C9BAA, 0x858D6032, 0xDAF185E1, +0xAE355065, 0xDE0086F3, 0x0F661A65, 0xF4334169, +0xB1559BA6, 0x3892109A, 0xE903BA00, 0xAE0CBD58, +0x073C21A0, 0xFCADB299, 0xB4E39AF1, 0x78475459, +0xB46DC847, 0xDBA97661, 0x15D118F5, 0x01ED48D0, +0x99F658BC, 0x399FDC8E, 0x44D4A919, 0x7C2CE4B9, +0xCA0367CC, 0xCC2B9828, 0x16AACAA6, 0x7AA5B6BA, +0xFEC77C66, 0x231B22F9, 0xC8BE0D04, 0x6FF2788C, +0x5F9CEBB5, 0x901EAA5D, 0xDE682BBF, 0x998E70D4, +0xBD9CCCDA, 0x6995441E, 0x5702F360, 0xBC035EED, +0x20F60B51, 0xD57361D8, 0xC071113B, 0x73CE6CE4, +0xC6569DC9, 0xD24B89ED, 0xA6052276, 0x8CEE2026, +0xFBF5B58E, 0xF692DF81, 0x6B7CDD7C, 0xF5B6C04C, +0xEC1BBA29, 0xD6AC8CDD, 0x320491F8, 0x1D812AC7, +0x631B0051, 0xD08A4D2A, 0x569746DD, 0xAA653FCF, +0xA92E8E70, 0xC59A6705, 0x278EA1FF, 0x63E5FA17, +0x1C20E82D, 0x550F7CE3, 0x55CED415, 0x5F9C4C4A, +0x7D746311, 0x5B07976A, 0x12477E31, 0xAB8113AA, +0x796EDCEA, 0x4A90E4B4, 0xB36E6188, 0xEE7D5E0F, +0x15CEA060, 0xB81AB2CA, 0x296D22B0, 0xFA0753E2, +0x0D0D15BB, 0xD4AF8BD7, 0x951FA575, 0xCBEBD58A, +0x0AF5C362, 0x9EF43FB0, 0xD97E5184, 0xA14469BC, +0xCAE5D55E, 0x93D4CDF9, 0x95B013A8, 0x6998F35C, +0xF1DDC0B1, 0x476F9FC7, 0xB6472B70, 0x1D55AC5C, +0xF0E0C0C8, 0x95372BF5, 0x75CCCDBE, 0x9F9D2003, +0xCAAD0D51, 0xEE54CC2E, 0xE5EBDBF0, 0x9B248BB3, +0x4BF07D19, 0x542997E9, 0x17447C4B, 0xCF2B2768, +0x86118A5B, 0x57579F12, 0xC5CD9E74, 0x97ED5724, +0x01BD2EE4, 0x2A0403A6, 0x01833741, 0xA1E8D364, +0x4D1A2EEA, 0x62760377, 0xA10D6861, 0x09C68E2F, +0xAB482850, 0xACD24B74, 0x5038C8CA, 0x71DE3A93, +0x671D25E4, 0x9EA7AC1A, 0x3E7287F5, 0x9FC963CF, +0x73F90AB6, 0xC775D840, 0x00B868D9, 0xF6A9BE3D, +0x17FFB472, 0x5D2389E3, 0x0D42A149, 0x2FAB1235, +0x90A7998E, 0xD895F6EE, 0x19921013, 0xEE42EA48, +0xC5D19A17, 0x5507890A, 0x9F893B29, 0x4FF39F19, +0xD6EF85AD, 0x3FFB1599, 0xF1761017, 0xFC51B90D, +0x8F6C566B, 0x44BAC7A4, 0x2B2E3755, 0xABECB8DB, +0x5C4A1629, 0x837CC4F7, 0x3E732B0A, 0x803CE303, +0x71865D8D, 0x346665AB, 0x58BF809B, 0x100626AA, +0x9446AB13, 0xD53ADCDA, 0x75C0BFCD, 0x95853304, +0xF4758E87, 0xD6B64517, 0x13293D0D, 0xEC9368FB, +0xD449A2CC, 0xAA17B0BE, 0x9D0B85C0, 0x77BEED16, +0x7699CAE7, 0xC776D10D, 0x962D48CE, 0x838D00BE, +0x279AEBF9, 0x22EF837B, 0x58E46DAD, 0xB56B6305, +0x3232D58B, 0x167969DB, 0x5B63F5B5, 0x7E82B175, +0x05DDB402, 0x5AB29BBA, 0xF3B627D5, 0x97168C85, +0xAD9EE022, 0x48F0CEEA, 0x84104C22, 0x690FCC19, +0xCA2F2474, 0x76F95539, 0x9FD2B987, 0x79EFC557, +0xCEE5DA4D, 0x27EB98F6, 0xA0628916, 0x8E05614F, +0x8AC89026, 0x7705135E, 0x3F7E42B8, 0x7BCD773B, +0xF98B9741, 0xCB8A514E, 0x9298220D, 0x5665FA3A, +0xE66A1FF7, 0xAC4ECB71, 0xA7E56FEF, 0x9D1EF7F8, +0x23566B64, 0xB4FE822E, 0x1AA53208, 0xF4545E5D, +0xEA86C879, 0x18F6B7C2, 0xE10A17AC, 0xBD37011F, +0xFBDF81B8, 0xA978A4EB, 0xD42437A7, 0x474E6A41, +0xF8885248, 0xF750BAA9, 0xD238EA62, 0xD69BA74D, +0x266EC6BF, 0xE7EDE077, 0xE8F0A303, 0x8B56A96D, +0x41380980, 0xDDF0B16C, 0x00E83594, 0xA503EBF5, +0x960A258E, 0x499827BD, 0x6C8E6F7B, 0x166C845D, +0xC842C934, 0xBAEFC699, 0xD9846213, 0x832EC19B, +0x1EAD7599, 0x221E7EE9, 0x8176A313, 0xB28D8E39, +0xBAC29A96, 0xB964F91F, 0x3F268150, 0xD4BB7011, +0x347EC445, 0x7FDC9E82, 0xEB70F4C9, 0xA6F38EBF, +0x398CF137, 0xD7F88CF5, 0xCBDDCB3F, 0xA0DAFA74, +0xD29D30AD, 0x822B6919, 0xCE059949, 0x3A946183, +0xDE4C572D, 0xD1E6D844, 0xC43C7DAC, 0xDBBEEDD0, +0xA656DF6D, 0x454C22A9, 0x9FA48790, 0x69B04531, +0x99BB305F, 0x80500F71, 0xFE2363C2, 0xB67F538F, +0x302EC0C3, 0x4A6E3458, 0x57E4CFD4, 0xE65CDAEB, +0xF31ABB31, 0x62DF98AC, 0x894AE781, 0xB1588AB1, +0x45D5CC3E, 0x3520F5B0, 0xC72D0CB7, 0xA1D6CBF9, +0x742FFA63, 0xA0A5224F, 0x5EA1C85A, 0xB81E9F77, +0x31D76C4F, 0x525257F5, 0xBFF85009, 0x2125B270, +0x16E47E6E, 0x9128B981, 0x0D5FBE39, 0xF67A418C, +0xCF3C71CB, 0xAC04ABE1, 0x9B550AAF, 0xB5077F18, +0xFB7C5EC0, 0x64784DB4, 0x1E668B48, 0x84659836, +0x604457BF, 0xF6F69C8D, 0x394301DC, 0xED0211BD, +0x8BAC1A3A, 0xBB752FD2, 0x78B8C036, 0xBCB98E8A, +0x33C595DE, 0xB3F3C5F8, 0x698666AC, 0xA1F42D7A, +0x5751ACC8, 0xC069575B, 0x35D50F99, 0xB294BF38, +0x82A4A331, 0x05147751, 0xCAE18C12, 0x9E89AAF1, +0x3531C372, 0xB2114A88, 0x41797201, 0xDDDDEC10, +0x01185F2A, 0xDED50CDC, 0x72156BAD, 0x88F3DB94, +0x50450DDF, 0x6B1E7ABF, 0x3D317708, 0xFDFF5A15, +0xDC8B1697, 0xCC2248FD, 0xD9196272, 0x4445195D, +0x54D90281, 0x7A891C9D, 0x69FF98D5, 0xADE6D74B, +0x26D27973, 0x0F14734F, 0x3F957FC8, 0x812AC874, +0xEDC0F9B4, 0xD31D6D75, 0x7A2608C3, 0xD89984B1, +0xF581081A, 0xEDB9DF6F, 0x16ECC191, 0x6B945724, +0x1BCE8269, 0x02E6DB68, 0x56362541, 0x9D247CF4, +0xA5265E72, 0x2C8B9413, 0x1157DB4B, 0x3145CFB2, +0xFBDEBCF5, 0x1042B117, 0x284DAE18, 0x10575C21, +0x1DDE578E, 0x80F59EDE, 0xCAB51C04, 0xB594BDA8, +0x08ACEF85, 0x08C8D4C7, 0x7304D433, 0xE87D3A88, +0x31CCFED8, 0x1D8E71E5, 0xC5A2F02C, 0xACBF3B5E, +0xAA161BCA, 0xA10BE577, 0xF9CE41D2, 0x2B86F031, +0x3D4A8D23, 0xED926DE4, 0x3844E21F, 0xFE57BCD0, +0x36DC309D, 0x17137409, 0x9F6A8507, 0x14CF12EB, +0xA770AFB5, 0x7C6DA2E4, 0x856B48B8, 0x2EA235DF, +0x55BD1164, 0x5BD9FF0C, 0x5228C552, 0x9E719AFA, +0x3EC3703B, 0xE06A94F3, 0x296FF0D9, 0xE468D9C9, +0xD2A15CDC, 0x6C4EAAA2, 0x2AF3B8BF, 0x6B6EDC78, +0x42B78972, 0x4C97A66C, 0x161C30BF, 0xCD2816DC, +0x431BDA17, 0xD9653022, 0x67D95E39, 0xBCB18342, +0x227982E7, 0x23C5B11B, 0x514420AB, 0x089F3A5C, +0x2B2F8244, 0x2F2A80C8, 0xB0A90558, 0x75BAA243, +0xE2FC4F62, 0xEB0A6104, 0xB7F221B2, 0x4ECD79DF, +0xB3E08B8B, 0xBA25E1CB, 0xD39F3431, 0xB50202FE, +0x78F15ECE, 0xEFF61ECF, 0xB3CDDD50, 0x3FD064A8, +0x96B028BC, 0xB29DD4E1, 0x7E9EC629, 0xC407F4D1, +0x8C21785B, 0xE11767BA, 0xCFE6DE26, 0x0DA98E22, +0x33AC5670, 0x0FDBC175, 0xF11F8EF5, 0x60638843, +0x8B67E55A, 0x3F27F75B, 0x6691FB98, 0x635A35A9, +0xB317459C, 0xE7419C01, 0x8BAB28D7, 0xE347D791, +0xEFC019A0, 0x45009041, 0xA6DEB3E8, 0x6F7379FF, +0x0FF50390, 0x810BEE78, 0xAD13716B, 0xA7DBD7AB, +0xEF439D4B, 0xDDA744A5, 0x31EDDE8D, 0xA85B71F2, +0xDF439C70, 0xA7E3DA94, 0x525ED453, 0x3D913C32, +0xD104CE61, 0x42F5FFED, 0x14C7625A, 0x4E5B314B, +0xA7EAD1ED, 0xFA01D595, 0xE67BCF06, 0xE63685E2, +0x3A32E9D3, 0x374C25F0, 0xA8E8A41D, 0xA403AEF5, +0x901A194C, 0x17605BC9, 0x8522DD12, 0x27096BAA, +0x017434B7, 0x99C8D2DA, 0x7F96B068, 0x8521CD09, +0x529B46D6, 0x47852810, 0x021BC8BF, 0x93C98329, +0x6FE73A78, 0x44DB69A9, 0xC839D490, 0xCAC42AFE, +0xCF1ECCF4, 0x6F2E5F44, 0x795C8219, 0xA06C667B, +0x80411F31, 0xB09926E1, 0xC62B6C18, 0x77C6E6DD, +0x7622FC07, 0x02162DB2, 0x3EA31334, 0x6CC02B4A, +0xAA6B81C3, 0x4424A9A5, 0x26BD2EF3, 0x334896D6, +0xADDD2711, 0x76035757, 0x80AA328E, 0x2F39C06E, +0x357520CB, 0xF62BDF46, 0xC59343C4, 0x7CA4CAE2, +0x89B03EF3, 0x251A785B, 0xA4755BB9, 0x262D478D, +0x462E6252, 0x6B5F6BED, 0xCA46E77B, 0xA2CF08AD, +0x561E19EA, 0xBF31AA15, 0xD376F44C, 0xCC332150, +0x8C0AEE42, 0xC06D5F91, 0xDADF8613, 0xBE0FA22C, +0xF50AE482, 0xE3615501, 0xECC8D5AA, 0x58A7FD3E, +0xD59B8CC9, 0x09DB0987, 0xF1D9753D, 0x9C79E20E, +0x9A222AEA, 0xC4E58914, 0x6712E0A2, 0x8CD5C80E, +0xEAB8AA56, 0xDBFA8D9C, 0x3515BD21, 0xB65B9E0C, +0xF0D27FEE, 0xE33871C1, 0xEE8FE52F, 0x02ACCB3F, +0xE9197277, 0xB7B70770, 0xA26E3581, 0x82481E7F, +0x005AF99F, 0x8B970B4B, 0xEC74B662, 0x2F21C5A3, +0x049DBA83, 0x495B3E1B, 0x112234B8, 0x95B42A5F, +0x2C8FA833, 0x6D706E30, 0x2AAAEC09, 0xDE7C3377, +0x06CE9D46, 0x7574EAAB, 0xFCB1A08D, 0x462AFB6C, +0x192847B2, 0xCC149AC3, 0x427834CE, 0xE90180A0, +0x946E526E, 0x6018BE4E, 0x20442F52, 0x1D39FA05, +0x35F690AD, 0x29DB3A53, 0x6360158C, 0x3EC815F8, +0xDED650AF, 0xFA168B37, 0x233F8A3D, 0x245009CF, +0x71BB2237, 0x4989A01C, 0xD58AE4F1, 0x62C99EA0, +0x48E9056E, 0x7E1A786D, 0xBF6CBAAB, 0x22669A6B, +0x57857590, 0xE4558CE3, 0xBC6C63EC, 0x6AE02A61, +0xA2ABFBBB, 0xD2B2FE90, 0xDF8BDB43, 0xEC2D59AC, +0x7B6AFDC3, 0x6B001D5F, 0x3DFEE08F, 0xB9A597D6, +0x09DEAC68, 0xE42D9E73, 0x2E33507C, 0x6525F051, +0x0D7143C6, 0x01DD115B, 0x94180279, 0x28FC60D7, +0xC0900603, 0xED4FBE53, 0xFC0677BD, 0x7DA2A878, +0xA8D0EC73, 0xF6A09B2A, 0x24A129EE, 0x169BCA2F, +0xE0BAE526, 0x5C8E2FCB, 0xA218EFFA, 0x842B61FB, +0x87B860CD, 0x106E9B86, 0x930685F0, 0xC5A72109, +0xFB977BD5, 0x9D3B4AC6, 0xDA378FE0, 0x0AAF747B, +0x0408D50D, 0x488785B9, 0x81AE971D, 0x12ADFEF3, +0xF0B64128, 0x3D4C90BB, 0xC994AAA1, 0xB854400E, +0x901AE3DD, 0x7A4A0DE7, 0x18E07456, 0x20C38BCD, +0x94441976, 0xE2E419C2, 0xDBD3C92F, 0x4DD63841, +0xE2994959, 0xF41F196D, 0x0835431A, 0x93A2E9CF, +0xB01FABED, 0xD0135535, 0xEBCEA18D, 0xC4F83A1B, +0x5D72845C, 0x04335E3A, 0x68C4C987, 0x77178710, +0xC5293A9A, 0x44E40AE1, 0xCE454FDE, 0x71DE89B7, +0xA373D9D3, 0x6D19E483, 0x812896D6, 0xC3231C14, +0xE960ABA4, 0xB7FB6F83, 0x1F7C4EB8, 0xD10DBE69, +0x8575CF6E, 0xC03B15D5, 0x4D7F4EF3, 0xF0615F31, +0x34E21762, 0x22D5A7A1, 0x729FA3F8, 0x2E1050FB, +0x8A9F46DC, 0x535EB5A7, 0xD143560E, 0xF8EC3A4B, +0x2249FD06, 0xE8E2AB08, 0x1E734127, 0xBA5B635A, +0xD8F419DB, 0x0B5200D0, 0x8110304F, 0x3497DA80, +0x35CA71CD, 0x0FD8227E, 0x086C74E2, 0xAB68A1AF, +0xE3BD57EC, 0x83B42D29, 0x3C2D672D, 0x05D85CED, +0x64F04926, 0x91364A12, 0x7FC73349, 0xEBA1FC77, +0xECE0D20D, 0xB1DDDB9B, 0xEB6B492B, 0x0FC02BB6, +0x56201D76, 0xED20F79E, 0xFC6034FB, 0x6A539F1D, +0x520FECBF, 0x4E3AECF6, 0x76B01C74, 0xEFC421D4, +0x82AC989A, 0x407A77CD, 0x6D287BFE, 0x26617425, +0xEA2316C3, 0x8616554E, 0x9F4C4535, 0x88C0C6C1, +0xEAC4F0F7, 0x32C7DD93, 0x41D9C37E, 0x2A9CBB2E, +0x0591BAEF, 0x2BE43F21, 0x5E06EE4D, 0xDDDF5525, +0xEC137DBE, 0xF0AA295C, 0xF2C9FDE2, 0x5DF9D693, +0x10A6CAC0, 0xC6846D09, 0xF1DDABF3, 0xD56F8BBC, +0xAA5DCE9D, 0x6F59004F, 0xB8A035BC, 0x61F47282, +0xC89DAC9E, 0xFC7E5B3D, 0x4C5406DD, 0x54CFD147, +0xBB44AB2A, 0x791269C0, 0x8CF66B4D, 0xD01A3190, +0x636F45CA, 0xB32FC209, 0xCB8B9F49, 0xF46D74B9, +0x5AFC9BD0, 0xC4C716C1, 0xF98C54F3, 0x36AFF013, +0xB4D6D90B, 0x5F1299B6, 0xA3BFCFA4, 0xEA336AAD, +0xCCD443DA, 0x74CA40B4, 0x31EF1614, 0x36D3FFEE, +0x876AE252, 0xC8D62E9F, 0x6424F397, 0x1F730F2D, +0xB20FDA53, 0xFCFEE60F, 0x676A61C3, 0x26C5E143, +0xC201573E, 0x4A8C46BE, 0xEF87D0A9, 0xE07E80B4, +0x34F20109, 0x8B936A70, 0x9F8E0305, 0xF3297CA0, +0x4E7BF0E9, 0x0F374BB9, 0xCE78A01E, 0x5FE26DD8, +0xA3826ACF, 0x321F69AB, 0x441AF14E, 0x8AC19CF7, +0x4BFD1AD6, 0x5951ABD1, 0x098C17F0, 0xA9B75F76, +0xA462551B, 0x6B703A12, 0xEDCB57B2, 0x8CD4C933, +0xD338D3D8, 0xE343FC24, 0x9CDD52EB, 0x17A41942, +0x63A8EF50, 0x215BB11A, 0xE1E25CB6, 0xB62C0A88, +0xE58CDEC3, 0xC0E6389A, 0x2B7BEE55, 0xA3FCBD07, +0x7CD451FE, 0xB06F6724, 0x5675A7EA, 0x141D52FC, +0x05E86E9B, 0x53D75C3A, 0xE799AA2A, 0xE474384C, +0x8C85E6E6, 0xA477A8D7, 0xA1E6AB0C, 0x9033E7CD, +0x2F55D504, 0x4DAE81FB, 0xBD229A64, 0x862765C9, +0x5B6A85F0, 0x95A39328, 0x38826CFB, 0xBF7DEBA4, +0x42EFAB62, 0x2D0BBA60, 0xB06731AF, 0x16D4C4B0, +0xCA4B9264, 0x3DF24AE2, 0xFED93848, 0x7CB33B08, +0xAC9CAE9F, 0xA0F80B61, 0xA66CF713, 0x9364865F, +0xDFA1E0B3, 0xFE6DF33F, 0x8039A612, 0x119F60BF, +0xCEEDE309, 0xD28316A8, 0xCD61D2F5, 0x3CBEB015, +0x85C0BF51, 0x6EDBBC15, 0x79F3D207, 0x485EE4FA, +0xCEC302EA, 0x59D8B92D, 0x51C1FB36, 0xF4FE8B71, +0x2DBD5718, 0x84024040, 0xFDD6590F, 0xA1CE9CC9, +0xC4AEAB72, 0x0A2FE8BF, 0x28C33618, 0xBA4E15FB, +0xA9C72819, 0xA3EE45D7, 0xD2DC52F1, 0x3FC84A2E, +0x1C9DF73E, 0x632F9BDE, 0x7E9FBD20, 0x0D689B79, +0x91E8D5C0, 0x6EE7952C, 0x905F192E, 0x2D79E712, +0x8670A7A2, 0x1DBFC4D9, 0x64634429, 0xE636043B, +0x643C6B0F, 0x50AF327B, 0x0E734D61, 0x2D7D6E46, +0xB877DCD6, 0x7CCF4F1A, 0xDF4D8CF8, 0x0E7FA78E, +0x0CBC4EC2, 0xAE9B4A22, 0x4F02D49C, 0x48F09C43, +0x5031B1A0, 0xDCB8A1FC, 0x91C73599, 0xCF00A64D, +0xDFCE561E, 0x8B18157D, 0xE1ED6A81, 0xCF94EF36, +0xB412CE1A, 0x602E2076, 0x716B0F3F, 0xADEB32C0, +0xD4E16094, 0xEC95D41F, 0x75858767, 0x438AD1A1, +0xE61C5527, 0x0D71FBB2, 0x2A99D070, 0x5C018826, +0xCCCC27FD, 0x053883D9, 0xF1D30EF5, 0x676AD38A, +0xDF81AB28, 0x2257FB9D, 0x373313AE, 0x67E1FE8A, +0xF4F66B02, 0xAFF8C7FA, 0x3B60D94D, 0xD44D0FE2, +0x5FCDFE4B, 0xC63010B6, 0x06CFCCF4, 0x09D8DD85, +0xAB79F2BE, 0xD5C0C498, 0x7364E4FD, 0xB295CEDF, +0xDB89A068, 0x59A6A0C7, 0x0C823207, 0x7380FCFE, +0x6E33C4B9, 0x0744E4F2, 0xF663BB33, 0x9EE512CE, +0x870ED35B, 0xB4502654, 0x367CD4FD, 0x5D4238D9, +0xEAB2B86E, 0x6E8ADDAA, 0xF080EDD6, 0x1DC90F46, +0xB1FC9127, 0x63771392, 0x96729BF6, 0xD18E1413, +0x5D85938D, 0xB8CED349, 0xF9B886C1, 0xCA486562, +0xBAA9ED7A, 0x049718D8, 0x7CF8E67A, 0x1702843C, +0x6DCDC34E, 0x93C51F83, 0x2415A4F3, 0xA8D77B3A, +0x0FB823E8, 0x424F03C3, 0x9CAA503C, 0x7AA5433F, +0x3BDD74FE, 0x99D3332E, 0x1E62231B, 0x90A4E595, +0x7EDA974D, 0x43E2CD14, 0x27DB9D9F, 0x561F5CC6, +0xA77EABA6, 0x97867B48, 0xAD6533CE, 0xEB726CF4, +0x5857B217, 0x2D7DA10B, 0xD939C20E, 0x81F1F073, +0xF42DEAF2, 0x3AD7780E, 0x88C77661, 0xD2E819B2, +0xF872F581, 0x999F0C5A, 0x3887ABA4, 0x27F95B6D, +0x991D9458, 0x9D1BB131, 0x6ECC5298, 0x9E9A7B26, +0x6E65F271, 0xE90FA04C, 0x7B692AA0, 0x878943D5, +0x924895E5, 0x041BC73A, 0x448E28B2, 0x61D22D1F, +0xE7969773, 0xBC8E5980, 0x9A198852, 0xB94415C9, +0xA02374BA, 0x340BD5F3, 0x27F2A0FF, 0x39BDB33F, +0xCC042BCF, 0x83D6C135, 0x9C7A8D8E, 0x05823C23, +0x2D7A3F91, 0xE792BCCA, 0xA2D82177, 0x73C82E7E, +0xBEBC9613, 0x9F596CB0, 0x6E784AA7, 0x1B7BDA9F, +0x846391F7, 0x852AD070, 0xF831E8CA, 0x16A78223, +0xF68F5250, 0xE2554493, 0xD38F2AFB, 0x764BA7A8, +0x3CAEFC55, 0x6E9B9037, 0xD87D486E, 0x7352AEA9, +0x11987EE0, 0xDF7E84DA, 0x2838E736, 0xA8C7BAC2, +0xF49E21EE, 0xFAD106E9, 0x7363AC6F, 0x5E9974CB, +0xBA008BB0, 0xAF5DB3FC, 0x7AC3CFD7, 0x2D55EDC6, +0x2C1C9AD7, 0x6A3AA494, 0x5F0E0A3A, 0x37422BFA, +0x83B4D594, 0xB7ECCF66, 0x82FCCDD0, 0x8ECBFD79, +0x664B9341, 0x02F178A2, 0x2095C8E0, 0xFC5F17B7, +0x1810BA9B, 0x964E4CD1, 0xFBAED808, 0xDEE87796, +0x63DE4F69, 0xC99275DD, 0x65242304, 0x7AB5C28B, +0x01BB7A3B, 0xC85D7716, 0x32AFB9A3, 0x2ED2CBB1, +0xB194218F, 0x21FE560D, 0xCB4503A5, 0x5CE0464D, +0xC4AE9A3C, 0x061530CB, 0xEDA38E6B, 0x4029D3E6, +0xB0C20336, 0xA37825C0, 0xC68F8B37, 0x9405AD3B, +0x8B1A8F99, 0xA761DE8B, 0x683B3259, 0xA154C554, +0x6BD835C9, 0x6DEAE35A, 0xBEAE6D49, 0x21D8B074, +0x46C01B31, 0xBE9B3A16, 0x1D611EAA, 0x423AB74C, +0x931F5AF5, 0xBB9E289A, 0xA4101132, 0x4A8BE0D7, +0x3307E4B2, 0xDE78DB5E, 0x347EB5CE, 0x13EEE999, +0x2C2D7955, 0xBA893EBA, 0x5DFC2EC1, 0xE7DD7A5F, +0x5E1C64D8, 0x4552E447, 0x1837D8E4, 0x9711836B, +0x3219F893, 0x04392C84, 0x3E94848C, 0x15E5F481, +0x0EC58819, 0x7341D458, 0x4AE63711, 0x85C1FD1F, +0x97B58BD7, 0xB0550EBE, 0xB9108743, 0x6F53B386, +0x7A73F31B, 0xE07CF8B9, 0x61FF27C8, 0x06A9A8B4, +0xEB0F2BB9, 0x46D275FB, 0xCF39B474, 0xC34F3B6D, +0x52F2F119, 0xD87963BF, 0xC60BF16C, 0x7797D0AD, +0x7EA4DBF0, 0xD21409C7, 0xF678A927, 0x638E67CD, +0x93261AED, 0xEA9B25FE, 0x1EBCAFDC, 0x580CC829, +0x58D1DA1A, 0x658881F8, 0xC48DB682, 0xD42E8CB4, +0x1DF33D74, 0x31C04F68, 0x7D871E29, 0xAE11FD72, +0xD7E8F8F6, 0x530D9D9C, 0x580A0715, 0x0F17B1A3, +0xB863F42F, 0xA6A4DC08, 0x82773E76, 0x9354B309, +0xE17D0770, 0x04E4DE5B, 0x712EA396, 0x49D37B55, +0xAE4109BA, 0x03862DC9, 0x7BCF61D2, 0x43CA2017, +0x23BDD50F, 0x74577459, 0x4E8F4E23, 0xBF924C1A, +0xE4EC70CE, 0x37FBEC66, 0xA6DA8935, 0xE11F4090, +0x5C8F9EE3, 0x19D167EC, 0x9EE4F2C5, 0x64A81E6C, +0xB35642BB, 0x82083A01, 0x001CA1F6, 0xAA69C7E8, +0x685F24D9, 0xE6868E31, 0x38ADD8F0, 0xA2FDD44E, +0xEE0C491D, 0xC60B1E9A, 0xF7A89268, 0xFD784F35, +0xC6B7335C, 0x75EFCEC1, 0xE2D9F7CF, 0xE1C364F8, +0x7CC63B2C, 0xC179E2AD, 0x56C193A5, 0x5134FB69, +0x35058BB5, 0x36F4BCD5, 0xDF4A08C2, 0x14AA2330, +0x760C8CD8, 0x2C562394, 0x0BEB669B, 0x2301973A, +0xAF5C4FF2, 0x1C770AAB, 0x25DD2087, 0x732AADC4, +0x59054958, 0x59DDCBE4, 0x74CFC8A8, 0x7C015016, +0x32A0276E, 0x8F1C2E93, 0x0CE91F71, 0x055C307A, +0x435D967E, 0xF4C33704, 0x5BDF2AD7, 0x8855099C, +0x307B2736, 0xBB6B19CB, 0x626349D3, 0x8F52ABFA, +0x251A1ED6, 0xE0587BC0, 0x12831408, 0xDA83CABF, +0xAB2C7DFD, 0x6BCF0271, 0x72058DF0, 0x17AFC1DD, +0xFFC52C30, 0x551401E0, 0x9EED54DF, 0x14E951E4, +0x14624B3F, 0x4C24650B, 0x5A65F86B, 0xE94F6143, +0xDC7CE9CF, 0x94D5D8F3, 0x093B0A04, 0x22098D01, +0xEDF09E7C, 0x165EDB0F, 0xD09CA774, 0xB96AA141, +0xB5745978, 0x9D820434, 0x42B0E026, 0x96938A25, +0x72E8634B, 0xBE36EC02, 0x42F3F74B, 0x358FA621, +0xBD451484, 0xB43A75D1, 0xB0A57F91, 0x701A7C82, +0x484B3F46, 0x047F78AD, 0x65F7371C, 0xEAC8A954, +0xE59F6354, 0x3EEEFB4E, 0xF131954B, 0x1C00BAC2, +0xE3897637, 0x5FEC83AB, 0x58CFA2C4, 0x1F4C0A6A, +0x97956BC6, 0x63D11D7D, 0xB46179D0, 0x11039A75, +0x1B50E088, 0x68E9476B, 0xAA68DB55, 0x8A4A051E, +0xEFA0DDF5, 0x05A2A674, 0xFFE03E72, 0xC5A0295C, +0x6FD4D834, 0x8E42BB94, 0xF3DFD88E, 0xBA691AD2, +0x3458473E, 0x6269A348, 0x72962FB6, 0x86D5064B, +0x8A153740, 0x54AC97D8, 0xED2CE057, 0x68200474, +0xBBA8E19D, 0xBFDD08F3, 0xB0DF76D1, 0x62F29649, +0x5AB77030, 0x1EE9A00E, 0x7DAB1C90, 0xAB608FFD, +0x8506A853, 0x75B9339B, 0x1AE0CCBA, 0xFB60BB79, +0x8650F92F, 0x4819E1F7, 0x0A7045A8, 0xB5BCE5F1, +0x77A98B27, 0x03DE21E4, 0x3FE3F132, 0x106827EC, +0xD4DC1469, 0xAAC82F9B, 0x1D5953A1, 0x8034B369, +0xD4412B6F, 0x90FB9F25, 0x14279070, 0x6D98AF1C, +0x3D286F37, 0x8324A732, 0x58123E4E, 0xEB051032, +0xC15CD557, 0xEB82DE99, 0x6213434E, 0x39F0FC9C, +0x5EBFE1C5, 0x8CEBF470, 0xFF7D8D8A, 0x740A6A3E, +0x720D080C, 0xB73B74FA, 0x5173F96E, 0x9FC01794, +0xDABF1C81, 0xCA813295, 0xBEA2DB8D, 0x4C7E0CE4, +0x8051BA67, 0xE63399E2, 0x83A15EE4, 0x47F4A718, +0xD8246E6A, 0x0B4F87BE, 0x031648B8, 0x99E3E3E6, +0x4ABCC64F, 0x52768181, 0xE708372B, 0x2D0B1D2C, +0x4DF52402, 0x389BE9F6, 0xDE2F3232, 0x5D43D74E, +0xD37BB898, 0xE7272645, 0x9B5432DA, 0x9D7A9473, +0xA69628A5, 0x583555A7, 0x255B08BD, 0xAD68EAE3, +0x1A79982D, 0xACE09726, 0x15E576AD, 0x260EB406, +0xA7440B46, 0x66B6D317, 0xBE6ECA3B, 0x3ADEA1C1, +0xD80399C3, 0x0EF198D0, 0xFAEE2010, 0xEF2E8E56, +0x5B6CC402, 0x3FD27BE2, 0x970AAB5F, 0x618C17C6, +0x7F5022FB, 0x552FC1FA, 0x5DD82984, 0x09769539, +0x98812D1F, 0xBD8B2539, 0xD78AD9A6, 0x1CE41D07, +0x272A0AB7, 0x5CB7E101, 0x6F42D56A, 0x001D930E, +0x3C17C305, 0x30AAE354, 0x2A4AABE0, 0x922BCB94, +0x73F34C1C, 0xE07E1501, 0xCB55A3E1, 0x0CDC3669, +0xD9C07DE7, 0x2DAB82BF, 0x963EACAA, 0x9B05E0F1, +0xE2DA0EFA, 0x0613BFE5, 0xDFB605E9, 0x5DCCA8FD, +0x6D433873, 0x81A9B4C5, 0xD1D1CB14, 0x9B6A9906, +0xC104767C, 0x30101D37, 0x186FBB79, 0x8F95D488, +0xA3094F43, 0x7F17C981, 0xFD92B3FE, 0xADAB3AB5, +0x20D1406C, 0x9462C8E7, 0x5D64819D, 0xB3E85196, +0x67B854FE, 0x7D039FC6, 0xAD98A85E, 0xF672E041, +0x30FA19A9, 0x4A276EB8, 0xB7041D2E, 0x57BB21E2, +0x4E251667, 0x15C5401E, 0xDAB59431, 0xD6C6FD1F, +0x1726EB70, 0x900F4E84, 0xD327DE33, 0x7A0AE04B, +0x76B1174E, 0xFD547B94, 0x370832DC, 0xDDE65CDD, +0x74672C02, 0x164703FE, 0x34CAD31F, 0x3E692DED, +0x4BC38FA5, 0x143F99E5, 0x61BB640E, 0xB957BC8D, +0xC9DD9E35, 0x2B5CB310, 0xADD6EAD0, 0x91981D46, +0xED803D57, 0x61D7737C, 0x92D3AC3E, 0x36A034CB, +0xE1395DC5, 0x5F2070F8, 0xC5EE9F8A, 0x70546B88, +0xC9EA230C, 0x58DC3073, 0x57CBBEB7, 0xA0B78CFE, +0x0B3FE75B, 0x07ADACCD, 0xC292C338, 0xD70CD7E5, +0x729D8F4E, 0x218FA041, 0x10EC1199, 0xAC1EC51D, +0x5DECC8D1, 0xBA36230A, 0xBC41F5A5, 0x75864896, +0xB4403D4A, 0xFEEE8F44, 0x8D94A256, 0x62BA0115, +0x3A570C61, 0x9221C583, 0xD2981A6B, 0xFD8AAF5A, +0x2A102D59, 0x64083BDD, 0xBD1AADE6, 0x7E6D1E99, +0x20568A6D, 0x8DFA704B, 0x87D27122, 0x2EFDAB7D, +0xF3AF9D39, 0xD8DED0B2, 0x2D4B34B9, 0x12F3E32C, +0xA6BCBE65, 0x680029A1, 0x094B07B3, 0xDA5918ED, +0xF7D0A86D, 0x1A7E18C8, 0x9285A97F, 0x2040282C, +0x5B133531, 0xA48237AC, 0x3557BC1B, 0x7E6ED77B, +0x436234C7, 0x9B2094DE, 0x5D967593, 0x8867D1C4, +0x88EC3948, 0xE7F84AD4, 0x1871B3E6, 0xE8E992C6, +0xA16DC2F8, 0x0DFDF590, 0x9B56238D, 0x329017F5, +0xBF9BD409, 0x68BD9B1C, 0x4036C4FF, 0x3BF6D93C, +0xAE100602, 0x90B43508, 0xA85B4013, 0x2C66EA54, +0x227D32D7, 0x0BA526D1, 0x075213B8, 0x1A3DED07, +0xD458DFFD, 0xDC8ACD43, 0xAC7809AB, 0x2D25408A, +0xD8F0C887, 0xAD8CD30D, 0x4054F61E, 0xA9F0CCA3, +0xBFEBD31D, 0x6D2BAB1E, 0xF8E42D8B, 0x6C94A4E4, +0x1158D2A3, 0x93F44EFE, 0x8AD05A25, 0x8C229D32, +0xB213D76E, 0xDFE63822, 0x561986EC, 0x806CA082, +0x6DB3BF8D, 0x1E850D30, 0x8F7A44C0, 0x75BB3328, +0x86C7BE12, 0xDE5C44BD, 0xDF4D048E, 0x968712C3, +0xB1B41CF8, 0xCC194FE9, 0xDA2E1A8D, 0x72A08662, +0x5ABA2536, 0x223E2013, 0xA5A923A5, 0x7565B5DD, +0xBCA0A2B0, 0x0C29864B, 0xAAD8CB87, 0xE4C7E559, +0x77E19E51, 0x194E54ED, 0x54DD1B54, 0x0FAD37A7, +0x0EF6B0E3, 0x0E3A2FC8, 0xA0063995, 0xE17AE20E, +0xDC11B7F8, 0x85F1A76D, 0xD97858D4, 0xB763E49C, +0xB5BE7EC4, 0x3CE924C4, 0x4246019D, 0xD33DBB27, +0x737863A7, 0x32C26BDD, 0x714897A3, 0x36091018, +0xF26BC990, 0xDDB640B0, 0x448F5B12, 0xD7A5EB4B, +0x5614EEA4, 0xCA4912FB, 0x011F9D6C, 0xA4FC90AB, +0x9FB4982D, 0x20AD146F, 0x4B7AB74E, 0x107A9411, +0x71DBA90A, 0xD510E3D2, 0x248D0D35, 0xB666229E, +0x61EE1EEA, 0x702031B5, 0x36992A7B, 0xC90C08CB, +0x6478995A, 0xE6C2BA7A, 0x8A9179AC, 0xC8EE2956, +0x27B042C8, 0x48DB81D9, 0xAA39F2CB, 0x5E4D5F3C, +0x24FFD6B9, 0x5B562C2F, 0x00FD33B6, 0x435F5F52, +0xF392FFC1, 0x0E927C40, 0x5508CBAB, 0x976AA567, +0xA13E7C52, 0x532109E9, 0x16B9021F, 0x60C615A1, +0x1D23C258, 0xFD783147, 0x63600FB1, 0xAAA245F0, +0x9B3DC1E1, 0x7B270D0D, 0x5B1632CE, 0x8B871F7F, +0xC535EFF8, 0x73109C6A, 0xEB83D02D, 0xF7AE76FB, +0x2E39E502, 0xA4128216, 0xF90D57E5, 0xFF0C465E, +0x02008029, 0xE5CBBA1F, 0x4280FA3C, 0xCDBD75C8, +0xCB4AF342, 0x17695A4E, 0xAA6162B5, 0x8660A679, +0xD1A8701C, 0x47694CA7, 0xDA8D43FD, 0x44A4BC1B, +0xAB34B9AA, 0xE55563DD, 0x08D4142B, 0x81197AC8, +0x997B1DC2, 0x2E7CC50A, 0x7A326A21, 0xA76419DB, +0xEA8B5428, 0x65729140, 0x051DAF66, 0x8871BCA9, +0xA175E5BF, 0x60310C98, 0xB7DE8929, 0x35E2459E, +0x08EB4547, 0x904D7B2B, 0x29382CC4, 0xCEC8664E, +0x1E8C9C2C, 0x3B942134, 0x9CEC5D55, 0xDA548376, +0x2E4EFD61, 0x26F65F09, 0x5A3DD7CA, 0x2FD4E58D, +0x6B71B8C2, 0x13189115, 0x2B5542BA, 0x1CE85C2C, +0x5B9FE09D, 0x68704BFE, 0xB15313B9, 0x3EF2729E, +0x583ECC31, 0xA3DED8CA, 0xFCD27C3D, 0x904DAB39, +0xFE1069A4, 0xE99A57BA, 0x112EB80C, 0xE1483C74, +0x8A27B0D7, 0xA58F7325, 0x7CD050A1, 0x626D4F3E, +0x51643657, 0xA967FC59, 0x5BACBC0B, 0x2CF3E459, +0x7D8988D9, 0x53913DF8, 0x2381A6FC, 0x64D6D441, +0x48AE9101, 0x185D9539, 0x1B044AEC, 0xB5ABCEDD, +0xFA8ECA52, 0x8CCDD142, 0x96FD4442, 0xD865FEDF, +0xCE4EE2FA, 0xA5160AE9, 0xC91B2B3A, 0xF993F45F, +0x1509132C, 0x920ECC5F, 0xD813DDC1, 0x834B68E4, +0xD5E876A0, 0x61DE0E41, 0x4C143913, 0xC7293985, +0x17E226E7, 0x38830927, 0xDC604DF2, 0x799D1430, +0x846585AB, 0xE5D21E38, 0x6381D136, 0x1B60633B, +0x23B7AE14, 0x554E53CC, 0x5807A210, 0x30560866, +0x12F79E62, 0xE27B5D45, 0x3889C1E5, 0x47F845FF, +0xFFD9DE98, 0xB10E09D2, 0x4A184A72, 0x083D2971, +0x8AB7478D, 0x92380377, 0x57A724EC, 0xBBBD5CA6, +0xE2FB9D32, 0xAB6ADFC6, 0x3916DED4, 0x4E19438F, +0xE21E15CF, 0x6AF4BCC9, 0x8D08924A, 0x1662BAA9, +0x3064AD27, 0xB86D7EE4, 0x88624C62, 0x1A0BF3E7, +0xF3E4A287, 0x6787F006, 0x01375D4B, 0x998BB38F, +0x6D669A29, 0xD760B093, 0xC4768853, 0xF041100F, +0x35DE10DD, 0xE06C8BB8, 0x2C79A902, 0x60600DAD, +0x6E11CF5C, 0x18778777, 0x7CCE406C, 0xE54AF2EA, +0x7472C475, 0x73DBEE7E, 0xE533DC40, 0xB07407DD, +0xF6ACA8D3, 0xE71BD7D1, 0x4BD3514D, 0xC5C362CA, +0x0690E5A1, 0x0FFDC8D8, 0x58188645, 0x8636413C, +0x3412A033, 0xAF4FC340, 0xA5DFEAB8, 0xB87272E3, +0xA4A9219F, 0x29696E90, 0x35D2F627, 0x8794DBD7, +0x5D2D87F8, 0xFA73559D, 0x7D22F440, 0xF50197E9, +0xEB74B829, 0x8F9649CF, 0x16F47D30, 0x5C7D9870, +0x36FF6C0B, 0x313A92ED, 0x303B3654, 0xE3E33CCA, +0x02C26ECC, 0x26949920, 0x4445DF20, 0x01FDBC98, +0x49138C6F, 0x1B5555E2, 0x122B45D2, 0x4B2E0202, +0x7B6014D4, 0xFAE0CD09, 0x77E165A0, 0xFBE76980, +0xF5808BD3, 0xFD110E5E, 0x97450E11, 0x297F9B1F, +0x607A2C41, 0xE384DFC9, 0x25D9A8DC, 0xF919D955, +0x5E025993, 0xCC318847, 0x9717D2D5, 0x48F0DD1F, +0x6CC4A8EB, 0x9BD0F4E1, 0x506F2A93, 0x18B8748E, +0x16FFBA48, 0x552E4955, 0xB963F64F, 0xA1A34AC8, +0x62E95CC7, 0x4D87EA89, 0x21E8C031, 0xC1F0ED07, +0x28B7BB22, 0x0B838D04, 0x6361B440, 0xA653521C, +0x92DA3F78, 0x4241CFED, 0xFAFCBD41, 0x3EFAB6BC, +0x25F30607, 0x41BB70DA, 0x9FF3440A, 0x2502039E, +0x3813EC82, 0xC6A4FD6B, 0xF8537C8C, 0x098ED49F, +0xE0A0BD6E, 0x6BA2F2B3, 0xC35C9D9D, 0x1256E66A, +0x790B2490, 0xD5C69889, 0x39E712FE, 0xCF73DE0B, +0x41B3B614, 0x745ABD73, 0x654C79D8, 0x5B15923D, +0x8C15F218, 0x585CCCF0, 0x624F7B44, 0x76BDDFDB, +0x96F26B52, 0xE13058A1, 0x086C950E, 0x29519DEA, +0xA42CFE04, 0x0D7A190B, 0xD0678C6A, 0xABB78679, +0xBA48A2E4, 0x5F3DA10A, 0x11F04183, 0xAC720A3F, +0x6A807781, 0x6F146BFB, 0xE8A67934, 0x54578834, +0xAA60C8F0, 0x2061A1E6, 0x9E87799B, 0x68D91F86, +0x8974F540, 0xB1C3F101, 0x99C21E56, 0xB57BA73F, +0x8B2DAA3E, 0xF1E2D24E, 0x48F7D4EE, 0x7039FDB3, +0xC666EEDC, 0x251F972E, 0x4D53F6BF, 0x6CC73EE7, +0xCB07F7B9, 0x69ECB8CA, 0x363FD80C, 0x3B587AB3, +0x738C1E5C, 0x5C9C1D92, 0xE7B52396, 0xEDE6324B, +0xFE5B5045, 0xC90D8B3E, 0x371A0128, 0xF2C8DCF8, +0x5B648CB5, 0x12F8E8FF, 0x5FE4BA71, 0xB925CFBE, +0x7416E14F, 0x76489FFE, 0x1F4DE367, 0xA400F039, +0x66390E83, 0x1AE79CEC, 0xDB573E98, 0xB6021F29, +0xD01615E5, 0x02A2281F, 0xE85019C1, 0x027BB41F, +0x8D9177C3, 0x79026E78, 0xF158B623, 0xBEFF5858, +0x7B63518E, 0x8F42C08C, 0xB388227D, 0x940D607A, +0xA4C79541, 0x9800CC91, 0xA356B535, 0x285BABB9, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0xE411E520, 0xA0024528, 0x442B4428, 0x96070009, +0x46106246, 0x8FFB2522, 0xD4027504, 0x0009AFF5, +0x00000FB3, 0x00200004, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x16D49357, +0x0009000B, 0x4F222FE6, 0xDE947FFC, 0xE114D594, +0x1E13D494, 0x67521E4C, 0xD494D693, 0x37402769, +0x62528F06, 0x7201D692, 0x60602522, 0x2600C93F, +0xD7906152, 0x2512611D, 0x264B6652, 0x2562470B, +0x0009B00D, 0xE60095AC, 0xC84060E2, 0x2F028F03, +0x8FF93652, 0x7F047601, 0xA05A4F26, 0x4F226EF6, +0x410BD185, 0xD4850009, 0x0009440B, 0x450BD584, +0xD7840009, 0xD284E1FF, 0x2712611D, 0xD4835029, +0xE1FFCB01, 0x1209E501, 0x12112212, 0xE7202452, +0x4718D57F, 0x2572D27F, 0xD17FE700, 0xD680D47F, +0xE2012270, 0x24702172, 0xD67E2620, 0x2641E4FF, +0xD57DE600, 0x666DE104, 0x76016063, 0x4000626D, +0x8FF83212, 0xD5790545, 0x2520E201, 0xD279D778, +0x2710E100, 0xE5802212, 0x655C6613, 0x666DD476, +0x76046763, 0x374C626D, 0x8FF83253, 0xD4732712, +0xD573E101, 0xD6732410, 0x2542E400, 0xE03AE501, +0xD272D771, 0xE0390654, 0x27110654, 0x000B4F26, +0x7FC82211, 0xD76FD16E, 0xDC70DB6F, 0xD271DE70, +0xD572D471, 0x1F12D672, 0x1F76710C, 0x1FB877FC, +0x1FEA1FC9, 0x72041F2B, 0xDE6FDC6E, 0x1F13EB10, +0x1F511F44, 0x1F771F65, 0xD86C1F2C, 0xDD6DD96C, +0xD26DEA00, 0x89003A22, 0xD1587A01, 0x88016010, +0x56F98B03, 0x4218E201, 0xD1682622, 0x0009410B, +0x440BD467, 0xD5670009, 0x0009450B, 0x6010D14C, +0x8B108801, 0xE650D14B, 0x46186212, 0x8B083266, +0x56FAD147, 0x2120E200, 0xCB016062, 0x2602A003, +0x72012710, 0x60822122, 0x89098801, 0xE2C8D15A, +0x622C6612, 0x89033626, 0x6010D158, 0x8BC88801, +0x51F76792, 0x217252F6, 0xD6555191, 0x55FB2212, +0x52FC6462, 0x55612542, 0x2252E400, 0x61436643, +0x05DE6013, 0x36CC4608, 0x02DE2652, 0xC9036021, +0x8B028801, 0x720162E2, 0x74012E22, 0x36B3664C, +0x71048FEE, 0x66C2D147, 0x45286512, 0x265B4518, +0x60822C62, 0x89018801, 0x0009A168, 0x6272D742, +0x8B132228, 0xD726D541, 0x6552D441, 0x51436672, +0x316C365C, 0x27622668, 0x14138D05, 0x6262D63D, +0xB1A57201, 0xD61E2622, 0x2622E200, 0x52916692, +0x8B013620, 0x0009A144, 0x6061A06E, 0x001C001C, +0x001D4020, 0x0000B38E, 0xFFFF0000, 0x12340000, +0x001E1015, 0x00201278, 0x002018A0, 0x00201922, +0x0020128C, 0x001C3510, 0x001C3624, 0x001E212C, +0x0020397C, 0x00203514, 0x00203984, 0x00203990, +0x0020399C, 0x002039F8, 0x002039FC, 0x002039A4, +0x002039A5, 0x002039A8, 0x00117700, 0x00203A12, +0x00203578, 0x001142D8, 0x00203A14, 0x00203A16, +0x001C3D30, 0x00117718, 0x001C3D00, 0x001C1000, +0x001C36F8, 0x00117734, 0x001C3684, 0x00117710, +0x001C3520, 0x00117600, 0x00117740, 0x001C1028, +0x0020358C, 0x002039AC, 0x7FFFFFFF, 0x00201734, +0x002032BE, 0x002022E8, 0x00203DC0, 0x002039FA, +0x00203584, 0x002039EC, 0x001C3D2C, 0x001C36B0, +0x0020351C, 0x0011775C, 0x8801C90F, 0xA0CF8901, +0xD17C0009, 0x36206212, 0xD47B8904, 0x2421E200, +0x2162A0CC, 0x6211D179, 0x89012228, 0x0009A0C3, +0xE202D775, 0x75016571, 0x3123615D, 0x27518D02, +0x0009A0BC, 0xD27255F2, 0x62226052, 0x40094019, +0xC90F4009, 0x8F19880A, 0x52F31F2D, 0x40196022, +0x40094009, 0x8808C90F, 0xA0A78901, 0x60630009, +0x51F255F8, 0xE701CB01, 0x2502D263, 0xE1002172, +0x2211D564, 0x74016452, 0x2542A098, 0x8B3F8805, +0x602252F3, 0x40094019, 0xC90F4009, 0x8B168802, +0xE5FFD45D, 0x655D6742, 0x8B102758, 0x6272D75B, +0x8B0C3260, 0x55F257F8, 0x2762E101, 0xD5522512, +0xD757E400, 0x62722541, 0xA0777201, 0x52F32722, +0x40196022, 0x40094009, 0x8805C90F, 0x31B38B6E, +0xD5508B6C, 0x615257F4, 0x7101E240, 0x64722512, +0x1F4DD14D, 0x42182419, 0x8B033420, 0x6262D64B, +0x26227201, 0xE200D640, 0x2621B0AA, 0x0009A056, +0x3123E220, 0x88038B52, 0x52F38B1E, 0x40196022, +0x40094009, 0x8803C90F, 0xD7418B16, 0x647251F4, +0x7401D23D, 0x65122742, 0x1F5DE640, 0x46182529, +0x8B033560, 0x6262D63B, 0x26227201, 0xE200D62E, +0x2621B086, 0x0009A010, 0xD738D137, 0xD22A6412, +0xE5007401, 0x21423A76, 0x22518F06, 0xEA00D634, +0x72016262, 0x2622B074, 0x2FB2D532, 0x95406652, +0xD4305BF1, 0x36205241, 0x60618910, 0x8B01C803, +0x2B22E201, 0x8FF54510, 0x57F15664, 0x6272E1F0, +0x41284118, 0x2722221B, 0x6BF2A008, 0x6BF2A006, +0xE200D615, 0xD1152621, 0x2121E200, 0xE20256F5, +0x42186662, 0x26284228, 0x1F6D8D0C, 0xD61FD11E, +0x460B6511, 0x2008645D, 0x57F58904, 0x6272D11C, +0x27222219, 0xD11BE201, 0x66122822, 0x8B012668, +0x0009AE17, 0x450BD518, 0xD1180009, 0xAE10E600, +0x07D12160, 0x00203A0C, 0x00203A10, 0x00203A18, +0x001C3DC0, 0x0011772C, 0x001C3B88, 0x002039F4, +0x0011773C, 0x00117744, 0x0000F000, 0x00117764, +0x00117748, 0x00117768, 0x0011776C, 0x01FFFFFF, +0x0011774C, 0x00203584, 0x001142D8, 0x00114774, +0xFDFFFFFF, 0x00203DC0, 0x0020246C, 0x002039FA, +0x2F962F86, 0x2FB62FA6, 0x2FD62FC6, 0x4F222FE6, +0xD11F7FF4, 0x6212DE1F, 0x67E25411, 0xD41E1F41, +0x1F722F22, 0x6743D51D, 0x7794D21D, 0x5A425841, +0x6C726942, 0x6D225B16, 0xE6006052, 0x2502CB20, +0x7601E540, 0x3253626D, 0x62F28BFB, 0x212255F1, +0x55F21151, 0x2E52D613, 0x14A21481, 0xD4122492, +0x11B627C2, 0x674226D2, 0xD911DA10, 0x2A72E801, +0x1A8C490B, 0x4218E201, 0x7F0C1A2C, 0x6EF64F26, +0x6CF66DF6, 0x6AF66BF6, 0x000B69F6, 0x000068F6, +0x001C3B9C, 0x001C3D98, 0x001C3700, 0x001C3500, +0x001C5960, 0x001C8960, 0x0020358C, 0x001C3D00, +0x00201610, 0x2F962F86, 0x2FC62FA6, 0x2FE62FD6, +0x4F124F22, 0x7F884F02, 0xE018DEB2, 0xD4B261E0, +0x61E30F14, 0x62107101, 0x440BE01C, 0x20080F24, +0x8F126D03, 0xD4AD1F08, 0x6740DDAD, 0x657CD4AD, +0x470BD7AD, 0xD2AD0009, 0x621C6120, 0x46086623, +0x36284608, 0x3D6C4608, 0xE01C1FD8, 0xE58004FC, +0x604C66E2, 0x3050655C, 0x2D628F17, 0x01FCE018, +0xDEA3E500, 0x641CA008, 0x6753655D, 0x607037EC, +0x31DC6153, 0x80147501, 0x3243625D, 0xD49D8BF4, +0xE200D59D, 0xA27F2421, 0x20082521, 0xE0188B13, +0xE50001FC, 0xA009DE96, 0x655D641C, 0x32EC6253, +0x62536722, 0x32DC6672, 0x75041261, 0x3243625D, +0xA2698BF3, 0x88012D10, 0xE0188B16, 0xE40001FC, +0x671C2D40, 0x624DDE8A, 0x8B013273, 0x0009A25C, +0x6DE3644D, 0x7D046243, 0x32EC6643, 0x652236DC, +0x74086162, 0x2512AFEF, 0x8B198804, 0x01FCE018, +0x2D70E700, 0x1FD56D1C, 0x627DDE7D, 0x8B0132D3, +0x0009A242, 0x6173677D, 0x31EC65E3, 0x75046412, +0x365C6673, 0x61426262, 0x21297708, 0x2412AFED, +0x8B198805, 0x01FCE018, 0x2D70E700, 0x1FD46D1C, +0x627DDE6F, 0x8B0132D3, 0x0009A226, 0x6173677D, +0x31EC65E3, 0x75046412, 0x365C6673, 0x61426262, +0x212B7708, 0x2412AFED, 0x8B598831, 0x61E6DE67, +0x61E31F19, 0x64E27104, 0x1F4A6216, 0x1F2B6416, +0x75E46513, 0x66536712, 0x1F4C7604, 0x64521F7D, +0xD75F6E66, 0x27E0D25F, 0xDE5F6062, 0xC9013245, +0x65622E00, 0x4609060A, 0x4609D15C, 0x46094509, +0x21501F4E, 0xB2B0646D, 0x620D1F6F, 0x8B012228, +0x0009A1EA, 0xD756DE55, 0x661C61E0, 0x6410D150, +0x470B654C, 0x7FFC54FF, 0x2FE25EFE, 0x51FE7FFC, +0x2F12E040, 0x55FBD14F, 0x57FD56FC, 0x04FE410B, +0xD24D7F08, 0xE11C640D, 0x1D412D10, 0xD44B6522, +0x67421D52, 0x1D73DE4A, 0xD24A65E2, 0x67221D54, +0x1D75D249, 0xD2496E22, 0x66221DE6, 0x1D67A1BC, +0x89018830, 0x0009A08E, 0xE340D538, 0x33FC6156, +0x23126456, 0x71046153, 0x67521341, 0x13726416, +0x7EE46E13, 0x65E66212, 0x66E3D731, 0x13246EE2, +0x760427E0, 0x6062D22F, 0x3255DE2F, 0x2E00C901, +0x060A6E62, 0xD12D4609, 0x4E094609, 0x13434609, +0x646D21E0, 0xB2501F5E, 0x620D1F6F, 0x8B012228, +0x0009A18A, 0xDE25D522, 0x61E06450, 0xD724654C, +0x470B54FF, 0x7FFC661C, 0x06FEE054, 0x7FFC2F62, +0xEE4001FE, 0x2F123EFC, 0x55E2D125, 0x57E456E3, +0x64E2410B, 0xD21C7F08, 0xE11C640D, 0x1D412D10, +0xD61A6522, 0x67621D52, 0x1D73DE19, 0xD2196EE2, +0x62221DE4, 0xD2181D25, 0x1D266222, 0x6222D217, +0x1D27A15A, 0x00117800, 0x00202A18, 0x00203996, +0x002035BC, 0x00203A7C, 0x002018D0, 0x00203995, +0x00117804, 0x00203A14, 0x00203A16, 0x00117810, +0x00203991, 0x10624DD3, 0x00203992, 0x00203993, +0x00114AA4, 0x00200F68, 0x001C5864, 0x001C6864, +0x001C7864, 0x001C59BC, 0x001C69BC, 0x001C79BC, +0x00200FC0, 0x8B048833, 0x470BD7A2, 0xA123EE00, +0x88282DE0, 0xA0D38901, 0xDE9F0009, 0x62E1E143, +0x3216E054, 0x0FE68F02, 0x2E21E240, 0x622D62E1, +0x8B013217, 0x0009A0BC, 0xE50185E1, 0x8B013056, +0x0009A0B6, 0x2D10E101, 0x64E1B111, 0x06FEE054, +0x6261E143, 0x3517652D, 0xE6408945, 0x8B0C3563, +0xE058E41A, 0xE5000F45, 0x72C0E05C, 0x60230F55, +0x6703C907, 0xA014E060, 0x66530F75, 0x46214621, +0x46214621, 0x45214621, 0xE0587618, 0x0F654521, +0xE0034521, 0xE05C2509, 0xE0070F55, 0xE0602209, +0xE8540F25, 0x858238FC, 0x640D65F3, 0x1844B170, +0xDD7A8584, 0x85866C0D, 0x610D4C08, 0x410860C3, +0xE00F0EFE, 0x18154D0B, 0x2E296207, 0x668260C3, +0x85620FE6, 0x4D0B5185, 0x2E0B600D, 0x548460C3, +0xB13C0FE6, 0xE05465F3, 0xE5400EFE, 0xE06C62E1, +0x3653662D, 0x0F668D41, 0xC9036023, 0x40004008, +0x61036403, 0xD965E070, 0x0F46E5FF, 0xE074655C, +0x60530F96, 0x6263490B, 0x42214221, 0x42214221, +0x42006723, 0x4200327C, 0x6C074621, 0x4621E054, +0x606309FE, 0x4008C903, 0x790630FC, 0x6A036D2D, +0x65F3E800, 0x64D3B124, 0xE0706EA2, 0x2AE22EC9, +0x01FE6694, 0x666CE074, 0x470B07FE, 0x2E0B6063, +0x65F32AE2, 0xB0FA64D3, 0x628D7801, 0x32E3EE06, +0x7D018FE7, 0x0EFEE054, 0xE05462E1, 0x420006FE, +0x760C8561, 0x701B302C, 0xE4006103, 0xE70465F3, +0x68667401, 0x3973694D, 0x8FF92582, 0x65F37504, +0x641DB0DD, 0x0EFEE054, 0x64E1B09C, 0x0009A054, +0xD43B56F8, 0xEA01D23B, 0x26A0420B, 0x0009A04C, +0x06FCE01C, 0x8829606C, 0x5CF88B08, 0xE200D636, +0x52612C20, 0x642DB04B, 0x0009A03E, 0x666CE681, +0x8B043060, 0x420BD231, 0xA03554F8, 0xE6820009, +0x3060666C, 0xD22E8B04, 0x54F8420B, 0x0009A02C, +0x666CE683, 0x8B0A3060, 0xDA2755F8, 0x2590E900, +0xD82855A1, 0x2852D628, 0xA01D52A2, 0xE6922620, +0x3060666C, 0xD2208B08, 0x5C21D824, 0x6CCC52F8, +0x28C1E600, 0x2260A010, 0x666CE693, 0x8B063060, +0xD61F59F8, 0xE201EA00, 0xA00529A0, 0xD6162621, +0xD21DD41C, 0x6562420B, 0x4F067F78, 0x4F264F16, +0x6DF66EF6, 0x6AF66CF6, 0x000B69F6, 0x4F2268F6, +0xE240614D, 0x89323123, 0x3127E21F, 0x8B27D713, +0xD406614D, 0xE00171E0, 0x5671440B, 0x26596507, +0x1761A025, 0x00200FBC, 0x00117804, 0x00203470, +0x00203A9C, 0x002018C0, 0x00117800, 0x00115F00, +0x00116058, 0x0020397C, 0x00203990, 0x00203A1A, +0x00203A16, 0x00203AB4, 0x002018D0, 0x001C3704, +0xE001D490, 0x6672440B, 0x26596507, 0x4F262762, +0x0009000B, 0x614D4F22, 0x3123E240, 0xE21F8912, +0xD7893127, 0x614D8B08, 0x5671D286, 0x420B71E0, +0x260BE001, 0x1761A006, 0x6672D282, 0xE001420B, +0x2762260B, 0x000B4F26, 0xE6400009, 0x46284618, +0x6252D57E, 0x89FC2268, 0x0009000B, 0x4618E680, +0xD57A4628, 0x22686252, 0x000B89FC, 0xA0010009, +0x7201E200, 0x8BFC3242, 0x0009000B, 0x4618E680, +0xD5734628, 0x22686252, 0x000B8BFC, 0x2FE60009, +0x7FFC4F22, 0xBFF16E53, 0x61E22F42, 0xE280D66D, +0x54E11615, 0x16464218, 0x422855E2, 0x57E31657, +0x16786EF2, 0x26E22E2B, 0x4F267F04, 0x6EF6AFCE, +0x2FD62FC6, 0x4F222FE6, 0x6C53DD62, 0x6E43BFD6, +0x2DE2BFBB, 0x0009BFD2, 0x2C1251D5, 0x1C4154D6, +0x1C5255D7, 0x1C6356D8, 0x6EF64F26, 0x000B6DF6, +0x61636CF6, 0xA004E600, 0x62564109, 0x24227601, +0x36127404, 0x000B8BF9, 0xD6530009, 0x8562E500, +0xA00B674D, 0x655D610D, 0x40006053, 0x305CD44F, +0x024D4008, 0x3270622D, 0x75018905, 0x3213625D, +0x000B8BF1, 0x000BE000, 0x2FE6E001, 0x54416743, +0x4E08EE7F, 0x4E28D246, 0x25E96543, 0x60436E21, +0x9E7562ED, 0x4529C903, 0xE60032E3, 0x8D456103, +0x21184509, 0xD23F8B05, 0x002C6053, 0xA08AC93F, +0x60136603, 0x8B268801, 0x880C6053, 0xD53A8B04, +0xC93F8453, 0x6603A07F, 0x8B048808, 0x84E2DE36, +0xA078C93F, 0x880D6603, 0x8B03D633, 0xC93F8461, +0x6603A071, 0x88096260, 0x622C8F09, 0xE014DE2C, +0x655C05EC, 0x60233258, 0xA064C93F, 0x60236603, +0xA060C93F, 0x88026603, 0xE0078B5D, 0x60432509, +0x8905C810, 0x6053D225, 0xC93F002C, 0x6603A053, +0x6053DE23, 0xC93F00EC, 0x6603A04D, 0x88016013, +0x60538B19, 0x8B04880C, 0x8423D21E, 0xA042C93F, +0x88086603, 0xD51B8B04, 0xC93F8452, 0x6603A03B, +0xD618880D, 0x84618B03, 0xA034C93F, 0x60606603, +0xA030C93F, 0x88026603, 0xE0078B2D, 0x60432509, +0x8923C810, 0x6053DE10, 0xC93F00EC, 0x6603A023, +0x00000BB8, 0x00203470, 0x001C3704, 0x001C373C, +0x001C3700, 0x001C370C, 0x00114000, 0x00114008, +0x001142D8, 0x001142E4, 0x001142E8, 0x001142F5, +0x001142ED, 0x001142FD, 0x00114309, 0x6053D209, +0xC93F002C, 0x60136603, 0x8B038802, 0xC8106043, +0x76028900, 0xC93F6063, 0x40004018, 0x1741240B, +0x6EF6000B, 0x00114301, 0x0009A16E, 0x2FE62FD6, +0xDD944F22, 0xA0049EB2, 0xD4930009, 0x420BD293, +0x62D265D2, 0x8BF822E8, 0x0009A004, 0xD28FD490, +0x55D1420B, 0x22E852D1, 0xA0048BF8, 0xD48D0009, +0x420BD28A, 0x52D255D2, 0x8BF822E8, 0x0009A004, +0xD286D489, 0x55D3420B, 0x22E852D3, 0xA0048BF8, +0xD4860009, 0x420BD281, 0x52D455D4, 0x8BF822E8, +0x6EF64F26, 0x6DF6000B, 0x2FD62FC6, 0x4F222FE6, +0x6E636C73, 0x6D53B01A, 0x64D357F4, 0xB05F65E3, +0xB07566C3, 0xB0A40009, 0xB0A80009, 0xB0AC0009, +0xB0AC0009, 0xB0AF0009, 0xB03154F5, 0x6CCD6C03, +0x4F2660C3, 0x6DF66EF6, 0x6CF6000B, 0x3412D170, +0xD6700529, 0x2650D770, 0x2742000B, 0x0009A018, +0x2FD62FC6, 0x4F222FE6, 0x6E636C73, 0x6D53BFEE, +0x64D357F4, 0xB03365E3, 0xB08D66C3, 0xB00F54F5, +0x6CCD6C03, 0x4F2660C3, 0x6DF66EF6, 0x6CF6000B, +0xE503D162, 0xD763D462, 0x21524518, 0x2472000B, +0xD45FD15E, 0x2162E600, 0x2462000B, 0xBF734F22, +0xBF73E40A, 0xD25C0009, 0x4118E104, 0xE40AE500, +0xBF692212, 0xD7592252, 0xCB206072, 0x000B4F26, +0x4F222702, 0x410BD156, 0xD556E400, 0x4F26452B, +0xD1552FE6, 0x66126E63, 0x92104418, 0x44084528, +0x45002629, 0x265B4408, 0x264B4400, 0x21624708, +0xD14E4708, 0x217227EB, 0x6EF6000B, 0x1FFF03F0, +0x4F222FE6, 0xE101DE4A, 0xBF3DE40A, 0x67E32E12, +0xE500776C, 0xE204E130, 0x2752E40A, 0x27522752, +0x27522752, 0x27522752, 0x27522752, 0x27522752, +0x27522752, 0x27522752, 0x27522752, 0x27522752, +0x27222712, 0x27522752, 0x27522752, 0x27522752, +0x27522752, 0x175ABF18, 0x2E62E600, 0x000B4F26, +0xD2346EF6, 0xE441E101, 0x000B2212, 0xD1322242, +0xE605D432, 0x000B2162, 0x000B2462, 0xD2300009, +0xE40AE601, 0x2262AF00, 0x2FC62FB6, 0x2FE62FD6, +0x7FFC4F22, 0x6C43DB2B, 0xED0060B2, 0x2B02CB03, +0xC90360B2, 0x6E03A008, 0x89073DC2, 0xE46460B2, +0xB07CC903, 0x7D016E03, 0x8BF52EE8, 0x8F043DC2, +0xD4212FE1, 0x460BD621, 0x62F10009, 0x6023622D, +0x89FFC801, 0x7F046023, 0x6EF64F26, 0x6CF66DF6, +0x6BF6000B, 0x001C3B88, 0x00203AC8, 0x002018D0, +0x00203AD0, 0x00203AD8, 0x00203AE0, 0x00203AE8, +0x0025E720, 0x00203DBC, 0x00203980, 0x001C5968, +0x001C3B40, 0x000F8000, 0x001D4004, 0x001C3500, +0x002015E4, 0x00201610, 0x001C5814, 0x001C59D0, +0x001C5830, 0x001C6268, 0x001C59A4, 0x001C639C, +0x001C581C, 0x001C5860, 0x00203AF0, 0x002018C0, +0x8F014411, 0x6043604B, 0x0009000B, 0x5651D52B, +0x46286052, 0x306C000B, 0x2FC62FB6, 0x2FE62FD6, +0x4F124F22, 0xBFF14F02, 0x6B036E43, 0xDD25DC24, +0x0009BFEC, 0x3C0530B8, 0x4609060A, 0x46014609, +0x020A3D65, 0x42094209, 0x32E24209, 0x4F068BF0, +0x4F264F16, 0x6DF66EF6, 0x000B6CF6, 0x2FC66BF6, +0x2FE62FD6, 0x4F124F22, 0xBFCF4F02, 0x6C036E43, +0xBFCBDD13, 0x30C80009, 0x060A3D05, 0x46094609, +0x36E24601, 0x4F068BF5, 0x4F264F16, 0x6DF66EF6, +0x6CF6000B, 0x4F222FE6, 0xE102DE0B, 0xE403E500, +0xBFB92E12, 0xE6062E52, 0xE7004618, 0x2E62E403, +0x4F262E72, 0x6EF6AFB0, 0x0009000B, 0x001C1040, +0xCCCCCCCD, 0x10624DD3, 0x001D4004, 0x2F962F86, +0x2FB62FA6, 0x2FD62FC6, 0x4F222FE6, 0xE5007F98, +0x6453E710, 0x6B534728, 0xEE1ADCBC, 0x6153655D, +0x315C4108, 0x75014108, 0x6043317C, 0x0F16665D, +0xED0060B3, 0x21B136E3, 0x81128111, 0x11D28113, +0x11D411D3, 0x74048FEA, 0xD8B167F2, 0x1871D9B1, +0x58F12872, 0x1981D1B0, 0x59F22982, 0x5DF45AF3, +0x54F65EF5, 0x21921191, 0x11A211A3, 0x11D411D5, +0x11E611E7, 0x11481149, 0xDAA855F7, 0x57F8EE00, +0x52F9DDA7, 0x64E3D6A7, 0x2A521A51, 0xD8A7D9A6, +0x2D72EAEF, 0x6AAC2622, 0x6DE36EED, 0x61E34D08, +0x41083DEC, 0x31EC4D08, 0x60B33D9C, 0x2DB14108, +0xE05081D1, 0xE79F4108, 0x41084008, 0x81D2677C, +0x318C60B3, 0x3472E200, 0x1DD281D3, 0xD4931D13, +0x1D248D01, 0x65D3D48F, 0x7E01B0B2, 0x34A264ED, +0xDA8C8BDA, 0x68A22FD2, 0x4829DD91, 0x64A22D82, +0x694D7DFC, 0x2D92D286, 0x4E296E22, 0x2DE27D0C, +0x6AD36822, 0xD784618D, 0x6D722A16, 0xD583D489, +0x5E7224D2, 0x14E2D688, 0xEE005174, 0x58761414, +0x1486D186, 0xE7105978, 0x62521498, 0x142A65E3, +0x64E326E2, 0x644DE600, 0x48086843, 0x4808384C, +0x6053381C, 0x28B10C86, 0x60B309CE, 0x60538191, +0x60430ACE, 0x605381A2, 0x60B30DCE, 0x605381D3, +0x740108CE, 0x09CE1882, 0x19E3624D, 0x32730ACE, +0x8FE01A64, 0xD96A7504, 0x6C92E003, 0x2CB14018, +0xDA6F6D92, 0xE05081D1, 0x40086E92, 0x619281E2, +0x811360B3, 0xE6006492, 0x67921442, 0x17A3D468, +0xE1FF6892, 0xE7031864, 0x46086563, 0x7501364C, +0x665D2612, 0x8BF83673, 0xE003DC5A, 0x40186DC2, +0x6EC22DB1, 0x81E1D25F, 0xEE0061C2, 0x64C21112, +0x1423E024, 0xD45B65C2, 0x67C215E4, 0x8172E580, +0x66E368C2, 0x655C8183, 0x6963666D, 0x6A6D7604, +0x3A53394C, 0x29E28FF8, 0xDC54DB53, 0x740424B2, +0x7F6824C2, 0x6EF64F26, 0x6CF66DF6, 0x6AF66BF6, +0x000B69F6, 0x614268F6, 0xC8036011, 0xE5008F03, +0x3420D23C, 0x60118B06, 0x8802C903, 0xD2398B06, +0x8B033420, 0x65135612, 0x24225264, 0x6053000B, +0x2FE62FD6, 0x7FEC4F22, 0x62536E53, 0x6D43E550, +0x4508E400, 0xE101A001, 0x60435224, 0x81212211, +0x60538123, 0x56E28122, 0x8BF53620, 0x16E4D238, +0xE61464F3, 0x65E3420B, 0xE4FC65E1, 0x2E512549, +0x65F361F1, 0x2F112149, 0xD13154D1, 0xE614410B, +0x607157D1, 0x2701CB01, 0x7F141DE1, 0x6EF64F26, +0x6DF6000B, 0x2FE62FD6, 0x7FEC4F22, 0x66536E53, +0x6D43E5FC, 0x20596061, 0x2601CB01, 0x326052E2, +0x12E48B06, 0x31E051E2, 0x52D18B04, 0x1E22A002, +0x5664AFF0, 0x64F3D21E, 0x420BE614, 0x67E165E3, +0x2719E1FC, 0x67F12E71, 0x271954D1, 0x65F3D118, +0x410BE614, 0x52D12F71, 0xCB016021, 0x1DE12201, +0x4F267F14, 0x000B6EF6, 0x00006DF6, 0x002039AC, +0x0020357C, 0x00203584, 0x0020358C, 0x002035B4, +0x00203998, 0x002039A0, 0x00100208, 0x001014C0, +0x001E210C, 0x001C3D00, 0x002039EC, 0x001000C8, +0x00117880, 0x00117780, 0x00040020, 0x0026C401, +0x00200D42, 0x4F222FE6, 0xDE42624C, 0x42004208, +0x3E2CA005, 0xD4405252, 0xBF695624, 0x65E22E62, +0x352052E1, 0xD63D8BF6, 0x4F262622, 0x6EF6000B, +0x2FC62FB6, 0x2FE62FD6, 0xDC394F22, 0x52C1DB39, +0x362066C2, 0x6061891C, 0x8801C903, 0xDE348918, +0xBF38DD35, 0x650364E3, 0x66B28503, 0x3262620D, +0xD4328907, 0x0009BF76, 0x4D0BD431, 0xAFE60009, +0xBF3D0009, 0xD42F64E3, 0x00094D0B, 0x0009AFDF, +0x2262D22D, 0x6EF64F26, 0x6CF66DF6, 0x6BF6000B, +0x2FD62FC6, 0x4F222FE6, 0xDD29DC28, 0x6E4360C2, +0x04DE4008, 0xE614D127, 0x65E3410B, 0xD127D726, +0x55E227E2, 0x35E05254, 0x21228F04, 0x400860C2, +0x122202DE, 0x605365C2, 0x75014008, 0x0DE606DE, +0xC90F6053, 0x60632C02, 0x6EF64F26, 0x000B6DF6, +0x85436CF6, 0x650D5643, 0x622D6262, 0x35277204, +0xE1008F0C, 0x2268960C, 0xD6158B03, 0x72015261, +0xD6131621, 0x6262E101, 0x26227201, 0x6013000B, +0x000001FF, 0x0020358C, 0x00203584, 0x001C3D00, +0x002035B4, 0x0020397C, 0x002018C0, 0x0020357C, +0x00203B18, 0x00203B1C, 0x001C3D28, 0x002039EC, +0x002039AC, 0x00200D42, 0x002039F0, 0x002039F4, +0x00117754, 0x2FA62F96, 0x2FC62FB6, 0x2FE62FD6, +0x7FF84F22, 0x6C22D241, 0xC80360C3, 0xDE40896E, +0xDA41DB40, 0x52B1D941, 0x362066B2, 0x60618945, +0x8801C903, 0xDD3B8941, 0x420BD23D, 0x650364D3, +0x60A12F02, 0x89328801, 0x85145153, 0x8840600C, +0x1F118F0C, 0xD5376191, 0x641D450B, 0x8B262008, +0xD7356691, 0x646D470B, 0x8B202008, 0x420BD233, +0x51F154F1, 0xC8208511, 0xD1318904, 0x021EE050, +0x01267201, 0x420BD22F, 0x200864F2, 0x64D38907, +0x4D0BDD2D, 0xD12D65F2, 0xAFC4E601, 0xD22C2162, +0x420B65F2, 0xD72B64E3, 0xAFBCE601, 0xD2262762, +0x420B65F2, 0xAFB664D3, 0xDE270009, 0xDA28DD27, +0x52D1DB28, 0x362066D2, 0x60618918, 0x8801C903, +0xD4228914, 0x450BD516, 0x56030009, 0x8F0436E0, +0xE2016503, 0xAFEC2A20, 0xD41F2B52, 0x420BD216, +0xD7180009, 0x4118E101, 0x2712AFE3, 0xC80460C3, +0xD21A8902, 0x0009420B, 0x4F267F08, 0x6DF66EF6, +0x6BF66CF6, 0x000B6AF6, 0x000069F6, 0x001E2100, +0x0020358C, 0x00203584, 0x00203A14, 0x001142D8, +0x002014A6, 0x00115EA2, 0x00114774, 0x00200D8A, +0x0020351C, 0x002016C2, 0x002014D0, 0x001E212C, +0x00201534, 0x001C3D30, 0x00117880, 0x0020357C, +0x0020399C, 0x00203998, 0x002035B4, 0x00200644, +0xE601D203, 0x1265D503, 0x000B2252, 0x00001266, +0x001C1010, 0x0000C34F, 0x0009000B, 0x0009000B, +0x0009000B, 0x0009000B, 0xE000000B, 0xE000000B, +0x0009000B, 0xE4FDD59D, 0xD69D6152, 0x25122149, +0x74016052, 0x2502CB01, 0xD19A6752, 0x25722749, +0xC8406010, 0x60628902, 0x2602CB04, 0xE1F76462, +0x26422419, 0xE7016062, 0x2602C9CF, 0xE5026062, +0x2602CB10, 0x47186062, 0x2602CB03, 0x000B1652, +0xD58D1673, 0xD28ED78D, 0xE100D48E, 0x2511E600, +0x22102711, 0x2461AFCE, 0xD28B664C, 0x362C4600, +0xCB106060, 0x2600000B, 0xD287654C, 0x352C4500, +0xE1EF6650, 0x000B2619, 0x664C2560, 0x4600D283, +0x6060362C, 0x000BCB10, 0x654C2600, 0x4500D27F, +0x6650352C, 0x2619E1EF, 0x2560000B, 0xD27A664C, +0x362C4600, 0xCB086060, 0x2600000B, 0xD276654C, +0x352C4500, 0xE1F76650, 0x000B2619, 0x664C2560, +0x4600D272, 0x6060362C, 0x000BCB08, 0x654C2600, +0x4500D26E, 0x6650352C, 0x2619E1F7, 0x2560000B, +0xD669624C, 0x326C4200, 0xC9086020, 0x40214021, +0x000B4021, 0x624C600C, 0x4200D664, 0x6020326C, +0x4021C908, 0x40214021, 0x600C000B, 0x644CD160, +0x6240341C, 0x602C000B, 0x644CD15E, 0x6240341C, +0x602C000B, 0x4F222FE6, 0x645C6E43, 0x3467E60A, +0xBFEB8914, 0x640C0009, 0x880160EC, 0xE00F8B02, +0x2409A002, 0x44094409, 0xE60A624C, 0x89053263, +0x644CBFE2, 0x6023620C, 0x8B00C880, 0x6023E200, +0x000B4F26, 0x4F226EF6, 0x6062D64B, 0x8B038801, +0x0009B256, 0x0009A003, 0xE640D248, 0xD6482260, +0x4F26E200, 0x2622000B, 0xD6434F22, 0x88026062, +0xB29F8B01, 0xD6420009, 0x4F26E200, 0x2622000B, +0xD43ED53D, 0xE701E100, 0x000B2512, 0xD23B2470, +0x000BE604, 0x4F222260, 0xD13BD43A, 0x0009410B, +0xE1FDD53A, 0xD23A6650, 0xE7002619, 0x4F262560, +0x2270000B, 0xD5374F22, 0x6152D237, 0x611DD737, +0x64522512, 0x242BE6FF, 0xD4352542, 0x666DD22E, +0x2762420B, 0xE1FBD52D, 0x27196750, 0x000B4F26, +0x4F222570, 0xD128D42F, 0x0009410B, 0xE7F7D527, +0x26796650, 0x000B4F26, 0xD5242560, 0x62509425, +0x000B2249, 0xD5212520, 0x6250E4BF, 0x000B2249, +0x4F222520, 0x8522D224, 0x2008600D, 0x88018911, +0x88038944, 0x88058946, 0x88068948, 0x8808894E, +0x88098954, 0x880A895A, 0x880B8960, 0xA06D8966, +0xB06F0009, 0xA06A0009, 0xFF7F600C, 0x001E2148, +0x001E1108, 0x001E1000, 0x00203A4C, 0x00203A4E, +0x00203A6D, 0x00203A30, 0x001E103F, 0x001E105F, +0x001E102F, 0x001E1090, 0x00203A54, 0x001E100B, +0x00203A50, 0x00203B20, 0x002018C0, 0x001E1028, +0x00203A6C, 0x001D4020, 0x98760000, 0x001C1000, +0x00203B2C, 0x00203B3C, 0x00203A24, 0x0009B04C, +0x600CA035, 0x0009B055, 0x600CA031, 0x6260D684, +0x8B2B2228, 0x0009B061, 0x600CA029, 0x6260D680, +0x8B232228, 0x0009B069, 0x600CA021, 0x6260D67C, +0x8B1B2228, 0x0009B0C7, 0x600CA019, 0x6260D678, +0x8B132228, 0x0009B0CD, 0x600CA011, 0x6260D674, +0x8B0B2228, 0x0009B125, 0x600CA009, 0x6260D670, +0x8B032228, 0x0009B13D, 0x600CA001, 0x4F26E000, +0x0009000B, 0xD26CD16B, 0xD56C8412, 0x4000C90F, +0xD76B012D, 0xE403D66B, 0xE20F611C, 0x2540E001, +0x25202712, 0x2602000B, 0xE601D262, 0x30668523, +0xE0008D05, 0xD663D260, 0xE0018122, 0x000B2602, +0xD25C0009, 0x600D8523, 0x89052008, 0x8B0A8801, +0x6060D65D, 0x2600CB01, 0xD457D65A, 0xE001E101, +0x000B2612, 0x000B8142, 0xD152E000, 0x8513E501, +0x640D4518, 0x66033453, 0xE0008D05, 0xD551D253, +0x2260E001, 0x000B2502, 0x4F220009, 0x8513D149, +0x6453650D, 0x62494419, 0x227D672E, 0x8801602C, +0x88028909, 0x88038910, 0x8806891A, 0x88078935, +0xA04C893B, 0xD5460009, 0x6652D746, 0x2762D446, +0x622C6261, 0x2421A038, 0x2228625C, 0xD4438B3F, +0x6642D540, 0x2562D440, 0x24018561, 0x6203A02C, +0x2008605C, 0x88108907, 0x88208908, 0x88308909, +0xA02C890A, 0xD23A0009, 0x6222A008, 0xA005D239, +0xD2396222, 0x6222A002, 0x6262D638, 0xD432D531, +0x66212522, 0xA00F626C, 0xD6352421, 0x6261D52D, +0x622CD42D, 0xA0072562, 0xD6322421, 0x8561D529, +0x2562D429, 0x62032401, 0x662D8515, 0x3617610D, +0x65038F01, 0xB0CB2451, 0xA0010009, 0xE000E001, +0x000B4F26, 0xD6190009, 0xD427E101, 0x65412610, +0xD118D717, 0xE20F655D, 0x2752E001, 0x000B2620, +0x2FE62102, 0xD20F4F22, 0x640C8523, 0x8B082448, +0xD511D61D, 0x2621E200, 0x940F8451, 0xA0482049, +0xDE0D8051, 0xC84060E0, 0xE2018D32, 0x89443427, +0xD216D615, 0x2641420B, 0x0009A030, 0x0000FF7F, +0x00203A6D, 0x00203A24, 0x00203A30, 0x001E1100, +0x001E100C, 0x00203A50, 0x001E1000, 0x001E1001, +0x00203A58, 0x00203A38, 0x00203A3C, 0x00203A40, +0x00203A5C, 0x00203A60, 0x00203A64, 0x00203A68, +0x00203E20, 0x00203E2A, 0x00203A4A, 0x002027F2, +0x89123427, 0xD294D693, 0x2641420B, 0xCB8084E1, +0x80E1B0F5, 0xD69160E0, 0x2E00CB04, 0xC93F6060, +0xD68F2600, 0xA001E001, 0xE0002602, 0x000B4F26, +0xD68C6EF6, 0xC8806060, 0xD2868919, 0x88016021, +0xD2898B15, 0x8524E501, 0x89103056, 0xE203D187, +0x2120D487, 0xE00B6541, 0x0656655D, 0xE40FD585, +0x2140E702, 0xD77E2571, 0x000BE001, 0x000B2702, +0x2FE6E000, 0xDE804F22, 0xC88084E1, 0xD57A892C, +0x20088554, 0x61038F28, 0x8553D77C, 0x64036672, +0x8566650C, 0x3520620C, 0xD6798B1E, 0x651CD774, +0x2651644C, 0x60E02741, 0x8904C840, 0x420BD275, +0xA0030009, 0xD2680009, 0x0009420B, 0x0009B09F, +0xE201D167, 0x60E02122, 0xCB04D464, 0x60402E00, +0x2400C93F, 0x6023A001, 0x4F26E000, 0x6EF6000B, +0x2FB62FA6, 0x2FD62FC6, 0xDA622FE6, 0x66A1E240, +0x3622DC5E, 0x62638900, 0x6ED36D2C, 0x4E2136D8, +0x4E212A61, 0xDB61D460, 0xE700A00F, 0x770162B2, +0x71026123, 0x66212B12, 0x71026213, 0x61212B12, +0x651D666D, 0x356C4528, 0x627C2452, 0x8BED32E3, +0xC90360D3, 0x8B108803, 0x617367B2, 0x2B127102, +0x71026E13, 0x2B126571, 0x655D6DE1, 0x422862DD, +0x325CE107, 0xA00C2C10, 0x88022422, 0xA0038B01, +0x8801E203, 0xE2018B05, 0x66B22C20, 0x655D6561, +0xE60F2452, 0x67A12C60, 0x8B052778, 0xDD38DC44, +0xEB01EA00, 0x2DB22CA2, 0x6DF66EF6, 0x6BF66CF6, +0x6AF6000B, 0x2FE62FD6, 0xE240DD36, 0x362266D1, +0x62638900, 0x3678672C, 0x7703DE38, 0x47212D61, +0x64E2D635, 0xA00E4721, 0x6562E100, 0x62537101, +0x74012450, 0x24204219, 0x45297401, 0x74012450, +0x24504519, 0x621C7401, 0x8BEE3273, 0x66E24200, +0x420061D1, 0x2118362C, 0x2E628F06, 0xDD1CD728, +0xE501E400, 0x2D522742, 0x000B6EF6, 0x2FD66DF6, +0x4F222FE6, 0xED0AEE01, 0x64E3BC86, 0xBC8B64E3, +0x62EC7E01, 0x8BF732D7, 0xBC8EEE01, 0x64E364E3, +0x7E01BC93, 0x32D762EC, 0x4F268BF7, 0x000B6EF6, +0xD1186DF6, 0xD418920D, 0x72122122, 0x2422D617, +0xD7177204, 0x72202622, 0x2722D116, 0x000B7230, +0x137A2122, 0x00203A4A, 0x002028FE, 0x001E1015, +0x00203A50, 0x001E1001, 0x00203A24, 0x001E1100, +0x00203A4E, 0x00203A3C, 0x001E1000, 0x00203A40, +0x00203A4C, 0x002027F2, 0x001E100C, 0x00203A38, +0x00203A54, 0x00203A58, 0x00203A5C, 0x00203A60, +0x00203A64, 0x00203A68, 0x4F222FE6, 0xD6707FFC, +0x88016060, 0xE2018951, 0x2620BFBB, 0xD56ED16D, +0xDE6E6010, 0x64E36552, 0x7402C840, 0x8D22D16C, +0xD26C7502, 0xE601D76C, 0xE7042722, 0x76016255, +0x626C2421, 0x8FF93273, 0xD4637402, 0x6242E601, +0x640D8528, 0x67494419, 0x275D657E, 0x81E4607C, +0xE417D562, 0x67557601, 0x3243626C, 0x8FF92171, +0xA0207102, 0xD25E0009, 0xE601D75B, 0xE7042722, +0x76016255, 0x626C2421, 0x8FF93273, 0xD4527402, +0x6242E601, 0x640D8528, 0x67494419, 0x275D657E, +0x81E4607C, 0xE417D553, 0x67557601, 0x3243626C, +0x8FF92171, 0x92897102, 0xD2462E21, 0x5E23D74E, +0x64F22FE2, 0x604365F2, 0x2700C980, 0xC9606043, +0x80716103, 0xC9036043, 0x80724519, 0x65F2605C, +0x817266F2, 0x46194629, 0x606C4529, 0x4018645C, +0x8173304C, 0x21185E23, 0x64F22FE2, 0x6E4C62F2, +0x602C4219, 0x66F262F2, 0x46294018, 0x461930EC, +0x42298174, 0x652C606C, 0x305C4018, 0x81758F07, +0x0009BC97, 0x2228620C, 0xA00A8908, 0x60130009, +0x8B038840, 0x0009B009, 0x0009A003, 0xE202D62F, +0x7F042622, 0x000B4F26, 0x4F226EF6, 0x8552D52A, +0x8830600D, 0x88318903, 0xA0348923, 0x85550009, +0xD428D727, 0x85532701, 0x610DD627, 0x24124118, +0x460BD426, 0xD7230009, 0xD226D425, 0x6572420B, +0xE230D120, 0x42286712, 0x2729E620, 0x37604628, +0xD6218B03, 0xA016E200, 0xD61F2622, 0xA012E202, +0xD1182622, 0x6212E530, 0xE6204528, 0x46282259, +0x89083260, 0xD41AD119, 0xE601D513, 0x2160450B, +0x472BD718, 0x4F264F26, 0x0009000B, 0x0000060A, +0x00203A6C, 0x001E1000, 0x00203A58, 0x00203E20, +0x00203E2C, 0x00203DC4, 0x00203A40, 0x00203DF4, +0x00203DF2, 0x00203DC6, 0x00203A24, 0x00203A50, +0x00203A3C, 0x00203A38, 0x002018C0, 0x00203B48, +0x00203B4C, 0x002018D0, 0x00203A54, 0x001E100B, +0x00203B60, 0x00114004, 0x4F222FE6, 0x84E9DE86, +0x2448640C, 0xB17B8901, 0xD2840009, 0x26686620, +0x60E08902, 0x2E00C9BF, 0x000B4F26, 0x000B6EF6, +0x2FE60009, 0xDE7E4F22, 0x60E0D67E, 0xCBC0D47E, +0x62602E00, 0xC803602C, 0x40218904, 0x70014021, +0x6603A002, 0x66034009, 0xD678616D, 0xE500A004, +0x75016262, 0x74042422, 0x3213625D, 0xD2748BF8, +0x0009420B, 0xC9BF84E2, 0x4F2680E2, 0x6EF6000B, +0x2FE62FD6, 0x7FFC4F22, 0x6260D66E, 0x89402228, +0xD565E100, 0x60502610, 0xCB40D46B, 0x2500440B, +0x8D052008, 0x62E06E03, 0x7104612C, 0x2F11A006, +0xD466D65E, 0xDD666760, 0x657C4D0B, 0xE23C6D1D, +0x8B033D27, 0xD264D463, 0x0009420B, 0x4D214D21, +0xA005D762, 0x66E6E400, 0x357C4508, 0x74012562, +0x35D3654D, 0xD75E8BF7, 0x6E72E003, 0x81E14018, +0x6E7260F1, 0x81E2700C, 0xD45A6172, 0xDD5A8113, +0x65724D0B, 0xD64AD259, 0x2212E101, 0xC93F6060, +0x7F042600, 0x6EF64F26, 0x6DF6000B, 0x2FC62FB6, +0x2FE62FD6, 0xD2524F22, 0x6B436E73, 0x420B6C53, +0x20086D63, 0x64038D1C, 0xE50ED13C, 0x32526210, +0x60C38916, 0x804124B0, 0x814160D3, 0xA007E500, +0x655D61BC, 0x00EC6053, 0x364C6653, 0x80647501, +0x3213625D, 0xD6308BF5, 0xC9BF6060, 0x2600A008, +0xD239D440, 0x6EF64F26, 0x6CF66DF6, 0x6BF6422B, +0x6EF64F26, 0x6CF66DF6, 0x6BF6000B, 0x2F962F86, +0x2FB62FA6, 0x2FD62FC6, 0x4F222FE6, 0xE1007FC4, +0x6513ECFF, 0x6B136CCD, 0xDE34D733, 0xEDFF64F3, +0xD833EA04, 0x6053655C, 0x027D4000, 0x32C0622D, +0x66038D0D, 0x09ED6063, 0x2491027D, 0x24217402, +0x698202ED, 0x3928622D, 0x74022892, 0x75017104, +0x6063625C, 0x07D532A2, 0x0EB58FE4, 0x2448641C, +0xE6808905, 0x67F3E5C5, 0xBF8F666C, 0x7F3C655C, +0x6EF64F26, 0x6CF66DF6, 0x6AF66BF6, 0x000B69F6, +0xD11C68F6, 0x6012D21C, 0xCB20E405, 0x2102E500, +0x000B2242, 0x00002252, 0x001E1017, 0x00203996, +0x001E1015, 0x001E10BF, 0x00117800, 0x001E10FC, +0x00200644, 0x0020399C, 0x00202A56, 0x00203B64, +0x002018D0, 0x00203B80, 0x002018C0, 0x0011788C, +0x00203998, 0x0020357C, 0x00201534, 0x001E2130, +0x00202A18, 0x00203B88, 0x002039FC, 0x00203A04, +0x00203DC0, 0x001C3500, 0x001D4004, 0xD564D163, +0xE400D764, 0x2142E20F, 0x17411154, 0xD5622722, +0x9669D762, 0x15412572, 0x96661562, 0xE6011565, +0xD55F1165, 0x666CE6F8, 0x25422542, 0x25422542, +0x25422542, 0x25622542, 0x7601E727, 0x67632572, +0x25627797, 0xE7042572, 0x2572E248, 0xE2192522, +0xE2702522, 0x25422542, 0x25422542, 0x25222542, +0x2522E20C, 0x25422542, 0x25422542, 0x25422542, +0x25422542, 0x000B154A, 0xE2081145, 0x0009422B, +0x2FE62FD6, 0x7FFC4F22, 0xC8206043, 0x6E438D02, +0x0009BE85, 0xC81060E3, 0xBE828901, 0x60E30009, +0x8901C840, 0x0009BEA4, 0xC80160E3, 0xDD3D8938, +0xC80260D0, 0x2F008D03, 0x460BD63B, 0x60F00009, +0x8902C804, 0x460BD639, 0x62F00009, 0xC8806023, +0x60D08902, 0x2D00C97F, 0xC8016023, 0xD6348906, +0x0009460B, 0x0009A007, 0x51630601, 0x8902C808, +0x460BD630, 0x60F00009, 0x8902C810, 0x420BD22E, +0xD52E0009, 0x88026052, 0xD22D8B03, 0xA005E604, +0x88012260, 0xD22A8B02, 0x2260E601, 0x2522E200, +0xC88060E3, 0xD227892D, 0x60E36E20, 0x8902C880, +0x420BD225, 0x60E30009, 0x8902C840, 0x420BD223, +0x60E30009, 0x8902C802, 0x420BD221, 0x60E30009, +0x890DC804, 0xDD20D11F, 0x0009410B, 0x0009BF11, +0x0009BF4C, 0xD51ED41D, 0x2470E708, 0x25D2BF85, +0xC80860E3, 0xD21B8905, 0x4F267F04, 0x422B6EF6, +0x7F046DF6, 0x6EF64F26, 0x6DF6000B, 0x001C581C, +0xA000A000, 0x001D0100, 0x001D4000, 0x00040021, +0x001C589C, 0x001E1021, 0x00201A46, 0x00201A68, +0x002020C8, 0x00201A80, 0x00201A8E, 0x00203A50, +0x001E100B, 0x001E1028, 0x00201AFA, 0x00201B06, +0x00201A96, 0x00201AB4, 0x12345678, 0x001E1000, +0x0010F100, 0x00201AE2, 0x644CD6A7, 0x000B346C, +0xD6A62450, 0x346C644C, 0x2450000B, 0x644CD6A4, +0x000B346C, 0x625C2450, 0x4208616D, 0x42084119, +0x42006019, 0x670E614C, 0xD49E321C, 0x4200207D, +0x324CC90F, 0x2200000B, 0x4208625C, 0x42004208, +0x324C644C, 0x4200D498, 0x000B324C, 0x2FE62260, +0x614C4F12, 0x4100D493, 0x6710314C, 0xE29F666D, +0x27294619, 0x6E536269, 0x672E6573, 0x4221227D, +0x42214221, 0x7601662C, 0xE4014608, 0x34E84608, +0x644C4600, 0x071A0467, 0x2150257B, 0x000B4F16, +0x4F226EF6, 0xD2857FE8, 0x88016021, 0xD2848B7B, +0x26686621, 0xD2838B77, 0x26686621, 0xE50F8B73, +0xE401BFA2, 0xBFA4E501, 0xE586E400, 0xE400655C, +0x2F50BFA4, 0xBFA1E401, 0xE602E506, 0x60634618, +0x81F2E401, 0x6543BF9F, 0xE40185F2, 0xBFAB6543, +0x85F26603, 0x6543E401, 0x6603BFB1, 0xE40265F0, +0x6053756C, 0x80F8BF80, 0xBF82E402, 0x84F8E512, +0x7090E402, 0x6503BF82, 0x4618E602, 0x81F66063, +0xBF80E402, 0x85F6E500, 0x6603E402, 0xE500BF8C, +0xE40285F6, 0xBF926603, 0xE5FEE500, 0xE010655C, +0xBF61E403, 0xE5130F54, 0xE40EBF63, 0x05FCE010, +0xBF63E40E, 0xE5007585, 0xBF64E403, 0xE500E640, +0xBF71E403, 0xE500E640, 0xBF78E403, 0xE5FFE640, +0xE014655C, 0xBF47E404, 0xE40F0F54, 0xE504BF49, +0x05FCE014, 0xBF49E40F, 0xE5017584, 0xBF4AE640, +0xE501E404, 0xBF57E640, 0xE501E404, 0xE404E640, +0xAF5C7F18, 0x7F184F26, 0x000B4F26, 0x4F220009, +0xD2427FF0, 0x88016021, 0xD2418B71, 0x26686621, +0xD2408B6D, 0x26686621, 0xE50F8B69, 0xE401BF1C, +0xBF1EE501, 0xE586E400, 0xE400655C, 0x2F50BF1E, +0xBF1BE401, 0xE401E506, 0xBF1C6543, 0xE401E640, +0xBF296543, 0xE401E640, 0xBF306543, 0x65F0E640, +0x756CE402, 0xBEFF6053, 0xE40280F4, 0xE512BF01, +0xE40284F4, 0xBF017090, 0xE6406503, 0xBF02E402, +0xE640E500, 0xBF0FE402, 0xE640E500, 0xBF16E402, +0xE5FEE500, 0x6053655C, 0xBEE5E403, 0xE51380F8, +0xE40EBEE7, 0xE40E84F8, 0xBEE77085, 0xE5006503, +0xBEE8E640, 0xE500E403, 0xBEF5E640, 0xE500E403, +0xBEFCE640, 0xE5FFE403, 0x6053655C, 0xBECBE404, +0xE40F80FC, 0xE504BECD, 0xE40F84FC, 0xBECD7083, +0xE5016503, 0xBECEE640, 0xE501E404, 0xBEDBE640, +0xE501E404, 0xE404E640, 0xAEE07F10, 0x7F104F26, +0x000B4F26, 0x00000009, 0x001E102F, 0x001E1080, +0x001E1090, 0x001E103F, 0x001E103E, 0x00203A4A, +0x00203A4C, 0x00203A4E, 0xD21DD11C, 0x66206010, +0x676C7001, 0x3700C90F, 0xE5008D13, 0x67106210, +0x7701622C, 0x64232170, 0xD6166010, 0x44084408, +0x3428C90F, 0x62602100, 0x7201D513, 0x44082620, +0x000B354C, 0xD10F6053, 0x25586510, 0xE6008D13, +0xD60DD40B, 0x655C6540, 0x47086753, 0x37584708, +0x47086540, 0x24507501, 0x367C6040, 0x2400C90F, +0x72FF6210, 0x000B2120, 0x00006063, 0x00203995, +0x00203994, 0x00203996, 0x002035BC, 0x7FFC4F22, +0xE680D1A8, 0x666C6212, 0xD2A72F22, 0x67F36563, +0x420B7542, 0x7F04E404, 0x000B4F26, 0xE6800009, +0xD2A1666C, 0xE7006563, 0x422B7540, 0xE6806473, +0xD29D666C, 0xE7006563, 0x422B7543, 0x2F866473, +0x2FA62F96, 0x2FC62FB6, 0x2FE62FD6, 0x7FC04F22, +0xDB97D296, 0x72012F22, 0xD1961F21, 0x66125211, +0x8B013620, 0x0009A0F9, 0xC9036061, 0x8B018801, +0x0009A0F3, 0xD290DC8F, 0x64C3420B, 0x6503D18F, +0x60111F02, 0x8B048801, 0x420BD28D, 0xAFE464C3, +0x54530009, 0x844CEE84, 0x890130E0, 0x0009A0C3, +0x6610D188, 0x6023626C, 0x8B718801, 0x6210D186, +0x89662228, 0xDA86D285, 0xE0036122, 0x64221112, +0x4018D881, 0xDD83E500, 0x814167A3, 0x77042850, +0x647266A2, 0x6ED3D580, 0x1F457E04, 0x65521F56, +0x64E368D2, 0x1F8874F8, 0x684369E2, 0x1F637894, +0x1F991F74, 0x62826142, 0xD779D978, 0x1F2BD679, +0x67726292, 0x1F1A6062, 0x2602CB20, 0xD176E600, +0xE5401F57, 0x1F7D1F2C, 0x76011F1E, 0x3253626D, +0x51F38BFB, 0x52F555F4, 0x25222A12, 0x55F757F6, +0x27525AF8, 0x5DF92DA2, 0x2ED251FB, 0xD56B5EFA, +0x54FC24E2, 0x281257FD, 0xD160D869, 0x25722942, +0x69126782, 0x1974D866, 0xDD666A12, 0x56FE60A1, +0x2A01CB01, 0xDA646412, 0xE9012842, 0x4A0B2D42, +0x52FE2692, 0xD661EE01, 0x22E24E18, 0x72016262, +0x60B22622, 0xCB01D14F, 0x2B02E202, 0x2120A03F, +0x8B3C2228, 0xE601D55A, 0x2160E700, 0xE01C2572, +0xC801004C, 0xD8578B0C, 0x1F8FD257, 0xE6002822, +0x7601E57D, 0x3253626C, 0x56FF8BFB, 0x2622D253, +0xE2FE69B2, 0x2B922929, 0x0A4CE01E, 0xE01F65F2, +0x014C25A0, 0x741057F1, 0xEA062710, 0xDD4CE600, +0x8446DE4C, 0x2D007601, 0x696C6844, 0x2E8039A3, +0x8FF67E01, 0xDE487D01, 0x2EA0EA94, 0xE1007E01, +0x7E0F2E10, 0xD12FE205, 0x64102E20, 0x6023624C, +0x89088801, 0x55F2D22A, 0x64C3420B, 0xEE01D132, +0xAF1A4E18, 0x55F221E2, 0x8553D13C, 0x620D6612, +0x89063262, 0xD63BD43A, 0xE801460B, 0xAF0CD73A, +0xD91F2782, 0x64C3490B, 0xEE01D127, 0xDA38D437, +0x4A0B4E18, 0xAF0021E2, 0x7F400009, 0x6EF64F26, +0x6CF66DF6, 0x6AF66BF6, 0x000B69F6, 0x4F2268F6, +0x85467FF4, 0x2F01E681, 0x666C8547, 0x854881F1, +0x81F2D209, 0x67F38542, 0x854381F3, 0x81F4E40C, +0x65636053, 0x420B81F5, 0x7F0C7540, 0x000B4F26, +0x00000009, 0x001C3D9C, 0x002023FC, 0x0011779A, +0x001C36F8, 0x002035B4, 0x002014A6, 0x00203A16, +0x002014D0, 0x002039A5, 0x002039A4, 0x002039A0, +0x001C3B9C, 0x001C3704, 0x001C3D98, 0x001C3BB4, +0x001C5960, 0x001C3500, 0x001C3D30, 0x001C8960, +0x0020358C, 0x001C3D00, 0x00201610, 0x00117730, +0x002039A8, 0x001C582C, 0x2000A000, 0x0000A000, +0x0011778C, 0x00117792, 0x00117788, 0x0020397C, +0x0020357C, 0x00201534, 0x001E2130, 0x00203DA0, +0x002018C0, 0x2F962F86, 0x2FB62FA6, 0x2FD62FC6, +0x4F222FE6, 0xD19B7FEC, 0x2F12E000, 0x6103D49A, +0x1F4281F2, 0xDD9ADA99, 0xD69A6813, 0xE0014808, +0x460BDE99, 0x38EC4800, 0x65A21F03, 0x352052A1, +0xA23E8B01, 0x60510009, 0x8801C903, 0xA2388B01, +0x52530009, 0x32E0DE91, 0xD9918B10, 0x64A3490B, +0x4B0BDB90, 0xDE906403, 0xD791D690, 0xEC01D591, +0x2E02E100, 0x271026C0, 0x2502AFDF, 0xC8018551, +0xA1578B01, 0x62510009, 0x4200622D, 0x5E53366A, +0x85E2226D, 0xC903642C, 0x85E36603, 0x6053650D, +0x40214021, 0x4500C93F, 0x322A6703, 0x6053252D, +0xC901D17F, 0x60106C03, 0x8801D97F, 0xDB7F8B05, +0x2120E200, 0xCB0160B2, 0xD17D2B02, 0x88016011, +0x65A28B0A, 0x8D042448, 0x9B9E6251, 0xA00322B9, +0x919B2521, 0x2521221B, 0x37B3EB10, 0x2448895E, +0xD4738B07, 0x22286241, 0x60638903, 0xA05781F8, +0xD5706473, 0x46084608, 0x85E26273, 0x46006B50, +0x362C4200, 0x2BB8C910, 0x8F1F6463, 0x26686603, +0xD2698911, 0x062D6043, 0x4119616D, 0x6B0E6019, +0x81F820BD, 0x880160C3, 0x646C8F2C, 0x880F6073, +0xA0278B1B, 0xD2610009, 0x052D6043, 0x4119615D, +0x670E6019, 0x645C207D, 0x81F8A01C, 0x890F2668, +0x6043D25B, 0x6B5D052D, 0x60B94B19, 0x201D610E, +0x60C381F8, 0x8F0D8801, 0x6473645C, 0xEC00A00A, +0x6043D254, 0x625D052D, 0x60294219, 0x207D670E, +0x81F8645C, 0x880285F8, 0x85E1890A, 0x8D07C820, +0xE6DC6203, 0x60232269, 0x81E1A002, 0x644CE4FF, +0x6210D149, 0x89012228, 0x644CE4FF, 0x654DEBFF, +0x35B06BBC, 0xDB368B2B, 0x64A34B0B, 0x410BD135, +0x54036403, 0x85446E03, 0xC948DB40, 0xDC408808, +0xBEAC8B01, 0x64B3E502, 0x65E34C0B, 0xDB3DEC01, +0xD13D2DC2, 0x621260B2, 0x72017001, 0x21228805, +0x2B028F08, 0x666CE680, 0x6563D238, 0x7549E700, +0x6473420B, 0xA030D436, 0x7FFF0009, 0x85E28000, +0x20B9EBFC, 0x610381E2, 0x942A85E3, 0x62032049, +0x450885F8, 0x81E2201B, 0xC90160C3, 0x40084018, +0x40084008, 0x4000225B, 0x6023220B, 0x85E481E3, +0x4118E108, 0x81E4201B, 0xE40262A2, 0x20B98521, +0x67A28121, 0xCB016071, 0x85F82701, 0x89033042, +0xECE785E2, 0x81E220C9, 0x490BD41E, 0xA03B0009, +0x7E030009, 0x001C3D30, 0x00203DAC, 0x0020358C, +0x001E212C, 0x00203470, 0x001C3D00, 0x00117780, +0x002014A6, 0x00201670, 0x0011770C, 0x002039A4, +0x002039A5, 0x002039A0, 0x002018C0, 0x001C36F8, +0x00203A1A, 0x00203DBC, 0x00203BA0, 0x00203C20, +0x00203CA0, 0x00203D20, 0x00203990, 0x00203584, +0x002014D0, 0x00203A1C, 0x00203A20, 0x002023FC, +0x00203DA4, 0x00203DA8, 0x602262F2, 0x40094019, +0xC90F4009, 0x8B0B880A, 0x60E2DE8C, 0x40094019, +0xC90F4009, 0x8B038808, 0xCB0160A2, 0x2802A006, +0x65E2DE87, 0x2E527501, 0x286266A2, 0x52F366F2, +0x2622AE83, 0xD2838551, 0xDE83C802, 0xA0958B01, +0x420B0009, 0x4E0B64A3, 0x5E036403, 0x85E46503, +0x4918E908, 0xD77D209B, 0xE04C81E4, 0xDC7C0B7E, +0x7B01D97C, 0x61C207B6, 0x71016690, 0x8D062668, +0xD4792C12, 0x420BD279, 0xA070EB01, 0x62512DB2, +0x4B18EB0F, 0x22B9E102, 0x32104118, 0x85518B0F, +0x2029E2FC, 0x60518151, 0xCB0172E0, 0x85E12501, +0x202994A3, 0x85E481E1, 0xA0522049, 0x675181E4, +0x4719677D, 0x667E6779, 0x7701276D, 0x6903607C, +0x88014918, 0x25918F3E, 0x6B12D161, 0x21B27B01, +0x660D85E3, 0x40216063, 0xC93F4021, 0x6C034600, +0x262D322A, 0xC8016063, 0xDB5ED15D, 0x967D8901, +0xE6002C6B, 0x666C67CD, 0x40006063, 0x622D021D, +0x8D0E3270, 0x60436403, 0xE9FF021D, 0x8B013290, +0x01C5A007, 0x626C7601, 0x3292E904, 0x646C8BEB, +0x60434400, 0xD15004BD, 0x0B457401, 0x669D6911, +0x89073670, 0x602D6211, 0x890388FF, 0xE201DB4B, +0x2B2021C1, 0xECFC8551, 0x815120C9, 0xCB016051, +0xDC472501, 0x64A34C0B, 0x51F366F2, 0x85EF2612, +0x54F2D244, 0x650D420B, 0x0009ADE7, 0xE500DC42, +0x420B2C52, 0x4E0B64A3, 0x54036403, 0x85446E03, +0x6703E908, 0x65034918, 0x27998541, 0xDB323790, +0x8F0BD932, 0x6013610D, 0x8B07C820, 0xC9486053, +0x8B038808, 0xE501BD4B, 0x0009A005, 0x2128D233, +0xBD448901, 0x64B3E500, 0x490B65E3, 0xADBCEC01, +0x85F22DC2, 0x7001EE04, 0x31E7610D, 0x8D0281F2, +0xADA97A08, 0x7F140009, 0x6EF64F26, 0x6CF66DF6, +0x6AF66BF6, 0x000B69F6, 0xF7FF68F6, 0x2FE68000, +0xD2234F22, 0x60E36E22, 0x8D02C840, 0xBBE522E2, +0xE2400009, 0x2E284218, 0xBBF08901, 0x60E30009, +0x8905C810, 0xD21CD41B, 0x0009420B, 0x0009BBEF, +0xC80560E3, 0xBD6D8901, 0x60E30009, 0x8902C802, +0xABEC4F26, 0x4F266EF6, 0x6EF6000B, 0x001C3D3C, +0x00117760, 0x002014A6, 0x00201670, 0x0020351C, +0x00203DC0, 0x00203990, 0x00203584, 0x002014D0, +0x002039FC, 0x00203A04, 0x002039F8, 0x002039FA, +0x00201534, 0x002018D0, 0x00203A1C, 0x00008000, +0x001C3510, 0x00203DB4, 0x002018C0, 0x89014F22, +0x611B600B, 0x611BB00A, 0x000B4F26, 0x600B600B, +0x611BA004, 0x8DF12107, 0x8BF84011, 0x620D2F26, +0x8F3E3020, 0x40180019, 0x8B0B3016, 0x31043104, +0x31043104, 0x31043104, 0x31043104, 0x412462F6, +0x601C000B, 0x41296219, 0x20084018, 0x31048926, +0x31043104, 0x31043104, 0x31043104, 0x31043104, +0x31043104, 0x31043104, 0x31043104, 0x61193104, +0x3204221D, 0x32043204, 0x32043204, 0x32043204, +0x32043204, 0x32043204, 0x32043204, 0x32043204, +0x212D3204, 0x601962F6, 0x4024000B, 0x000BE000, +0x621362F6, 0x41294228, 0x31044224, 0x31044224, +0x31044224, 0x31044224, 0x31044224, 0x31044224, +0x31044224, 0x31044224, 0x31044224, 0x31044224, +0x31044224, 0x31044224, 0x31044224, 0x31044224, +0x31044224, 0x31044224, 0x602D4224, 0x62F6000B, +0x080A0C0E, 0x00020406, 0x1A1C1E20, 0x12141618, +0x2E303234, 0x26282A2C, 0x3A3C3E40, 0x6C625648, +0x41112F26, 0xE2208F18, 0x890B3123, 0x321CD204, +0xD1026220, 0x412B312C, 0x00090009, 0x0020349A, +0x00203450, 0x000BE000, 0x400062F6, 0x40004000, +0x40004000, 0x40004000, 0x62F6000B, 0x40004000, +0x40004000, 0x40004000, 0x40184000, 0x62F6000B, +0x40004000, 0x40004000, 0x40004000, 0x40284000, +0x62F6000B, 0x40004000, 0x40184000, 0x000B4028, +0xC90F62F6, 0x40054005, 0x40054005, 0x62F6000B, +0x4005C907, 0x40054005, 0x62F6000B, 0x4005C903, +0x000B4005, 0xC90162F6, 0x000B4005, 0x000062F6, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x42707372, +0x3D206675, 0x554E203D, 0x202C4C4C, 0x6E49677A, +0x4E497274, 0x6D754E51, 0x0000003D, 0x61766E49, +0x2064696C, 0x72657375, 0x20726F20, 0x2079656B, +0x00214449, 0x6E6B6E55, 0x206E776F, 0x6D6D6F63, +0x3D646E61, 0x00000000, 0x203A3051, 0x00000020, +0x203A3151, 0x00000020, 0x203A3251, 0x00000020, +0x203A3351, 0x00000020, 0x203A3451, 0x00000020, +0x2B434741, 0x73696F4E, 0x61432065, 0x7262696C, +0x6F697461, 0x6166206E, 0x6F206C69, 0x6974206E, +0x0D0A656D, 0x00000000, 0x00000072, 0x00205220, +0x62735576, 0x7473725F, 0x00000A0D, 0x62735576, +0x7375735F, 0x646E6570, 0x00000A0D, 0x62735576, +0x7365725F, 0x000A0D6D, 0x00000044, 0x44387570, +0x72637365, 0x6F747069, 0x3D584572, 0x00000000, +0x00000047, 0x72746E49, 0x6D652051, 0x2C797470, +0x49677A20, 0x4972746E, 0x754E514E, 0x00003D6D, +0x654C7245, 0x0000006E, 0x20746F4E, 0x756F6E65, +0x49206867, 0x4220514E, 0x0A0D6675, 0x00000000, +0x000000FF, 0x00020001, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x010E010D, 0x00020003, 0x01090108, 0x0002010A, +0x02000003, 0x02020201, 0x02040203, 0x02060205, +0x02020200, 0x02040203, 0x020C020B, 0x020E020D, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x000000FF, 0x00020001, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x010E010D, 0x00020003, 0x01090108, 0x0002010A, +0x00030003, 0x02020201, 0x02040203, 0x02060205, +0x02020200, 0x02040203, 0x020C020B, 0x020E020D, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x010E010D, 0x00FF010F, 0x01090108, 0x010B010A, +0x0200010F, 0x02020201, 0x02040203, 0x02060205, +0x02020200, 0x02040203, 0x020C020B, 0x020E020D, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x010E010D, 0x00FF010F, 0x01090108, 0x010B010A, +0x010F010F, 0x02020201, 0x02040203, 0x02060205, +0x02020200, 0x02040203, 0x020C020B, 0x020E020D, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00205220, 0x00000046, 0x00000059, 0x73204142, +0x003D7165, 0x49544120, 0x0000204D, 0x00000000, +0x00000000, 0x002E0209, 0x80000101, 0x000409FA, +0x00FF0400, 0x05070000, 0x02000201, 0x82050700, +0x00020002, 0x03830507, 0x07010040, 0x40030405, +0x02090100, 0x0101002E, 0x09FA8000, 0x04000004, +0x000000FF, 0x02010507, 0x07000040, 0x40028205, +0x05070000, 0x00400383, 0x04050701, 0x00004002, +0x00000000, 0x00000000, 0x07090000, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x6621D2A8, 0x2008606D, 0xA1B18B01, 0x88100009, +0x88118922, 0x88128920, 0x8813891E, 0x8821891C, +0x8822891A, 0x883A8918, 0x883B8916, 0xE6448914, +0x30604608, 0xE6488910, 0x30604608, 0xE658890C, +0x30604608, 0x963D8908, 0x89053060, 0x3060963B, +0x96398902, 0x8B013060, 0xE010000B, 0x8B018820, +0xE020000B, 0x892B8837, 0x89298832, 0x89278835, +0x89258836, 0x89238830, 0x89218838, 0x891F8839, +0x891D8834, 0x891B8833, 0x4608E64C, 0x89173060, +0x3060961B, 0x96198914, 0x89113060, 0x30609617, +0x9615890E, 0x890B3060, 0x30609613, 0x96118908, +0x89053060, 0x3060960F, 0x960D8902, 0x8B0C3060, +0xE030000B, 0x05100165, 0x02300A10, 0x04300330, +0x06300530, 0x0B300A30, 0x88400C30, 0xA1428B01, +0x88410009, 0xA13E8B01, 0x88430009, 0xA13A8B01, +0x88480009, 0xA1368B01, 0x884A0009, 0xA1328B01, +0x884B0009, 0xA12E8B01, 0x884C0009, 0xA12A8B01, +0xE6800009, 0x3060666C, 0xA1248B01, 0xE6810009, +0x3060666C, 0xA11E8B01, 0xE6820009, 0x3060666C, +0xA1188B01, 0xE6830009, 0x3060666C, 0xA1128B01, +0xE6840009, 0x3060666C, 0xA10C8B01, 0xE6850009, +0x3060666C, 0xA1068B01, 0xE6860009, 0x3060666C, +0xA1008B01, 0xE6870009, 0x3060666C, 0xA0FA8B01, +0xE6880009, 0x3060666C, 0xA0F48B01, 0xE6890009, +0x3060666C, 0xA0EE8B01, 0xE68A0009, 0x3060666C, +0xA0E88B01, 0xE68B0009, 0x3060666C, 0xA0E28B01, +0xE68C0009, 0x3060666C, 0xA0DC8B01, 0xE68D0009, +0x3060666C, 0xA0D68B01, 0xE68E0009, 0x3060666C, +0xA0D08B01, 0xE68F0009, 0x3060666C, 0xA0CA8B01, +0xE6900009, 0x3060666C, 0xA0C48B01, 0xE6910009, +0x3060666C, 0xA0BE8B01, 0xE6F80009, 0x3060666C, +0xA0B88B01, 0xE6F90009, 0x3060666C, 0xA0B28B01, +0xE6FA0009, 0x3060666C, 0xA0AC8B01, 0xE6FB0009, +0x3060666C, 0xA0A68B01, 0xE6FC0009, 0x3060666C, +0xA0A08B01, 0xE6FD0009, 0x3060666C, 0xA09A8B01, +0xE6FE0009, 0x3060666C, 0xA0948B01, 0xE6FF0009, +0x3060666C, 0xA08E8B01, 0xE6D00009, 0x3060666C, +0xA0888B01, 0xE6D10009, 0x3060666C, 0xA0828B01, +0xE6D20009, 0x3060666C, 0xA07C8B01, 0xE6D30009, +0x3060666C, 0xE6D48977, 0x3060666C, 0xE6D58973, +0x3060666C, 0xE6D6896F, 0x3060666C, 0xE6D7896B, +0x3060666C, 0xE6D88967, 0x3060666C, 0xA0038963, +0x00000009, 0x00114000, 0x666CE6D9, 0x895A3060, +0x666CE6DA, 0x89563060, 0x666CE6DB, 0x89523060, +0x666CE6DC, 0x894E3060, 0x666CE6DD, 0x894A3060, +0x666CE6F0, 0x89463060, 0x666CE6F1, 0x89423060, +0x666CE6F2, 0x893E3060, 0x666CE6F3, 0x893A3060, +0x666CE6F4, 0x89363060, 0x666CE6F5, 0x89323060, +0x666CE6F6, 0x892E3060, 0x666CE6F7, 0x892A3060, +0x4608E650, 0x89263060, 0x3060969A, 0x96988923, +0x89203060, 0x30609696, 0x9694891D, 0x891A3060, +0x30609692, 0x96908917, 0x89143060, 0x3060968E, +0x968C8911, 0x890E3060, 0x3060968A, 0x9688890B, +0x89083060, 0x30609686, 0x96848905, 0x89023060, +0x30609682, 0x000B8B01, 0xE0FFE040, 0x600C000B, +0xE000000B, 0x6243D157, 0xE4028512, 0x662D670D, +0xE500A00E, 0x6053655D, 0x305C4000, 0x4008D152, +0x622D021D, 0x8B023260, 0xA0047108, 0x7501041C, +0x3273625D, 0x60438BEE, 0xC90A000B, 0x674C76FE, +0x025C606C, 0x3723622C, 0x20088906, 0x70FF8902, +0x6603AFF6, 0xE000000B, 0x0009000B, 0x4F124F22, +0x326052F2, 0x34508910, 0x3470890E, 0x3750890D, +0x3268890A, 0x04273458, 0x60733758, 0x440BD43B, +0x306C011A, 0x6203A001, 0x4F166263, 0x000B4F26, +0x2FE66023, 0x4F124F22, 0x6E434F02, 0x614C54F4, +0x2F164118, 0x666C677C, 0x64EC655C, 0x46184718, +0xBFD34518, 0x65034418, 0x60537F04, 0xC980E702, +0x6E034718, 0x37ED4728, 0x62594519, 0x010A652E, +0x312C225D, 0x4F06601C, 0x4F264F16, 0x6EF6000B, +0x03400240, 0x05400440, 0x07400640, 0x09400840, +0x11400B40, 0x0A401240, 0x4F220A50, 0x614C8451, +0x3127620C, 0xA00C8901, 0x8452E400, 0x3127620C, +0xA0068901, 0x8453E401, 0x3127620C, 0xE4038D01, +0x6263E402, 0x60437201, 0x677C072C, 0x62532F76, +0x072C7201, 0x055C066C, 0x666C677C, 0xBFA8655C, +0x7F046413, 0x000B4F26, 0x605C600C, 0x8F068801, +0x606C6243, 0x8B018801, 0x720AA001, 0x000B72F6, +0x00006023, 0x00114000, 0x00114008, 0x00203374, +0xE040D690, 0x056E614C, 0x9274D78F, 0x352C357C, +0xE400E718, 0x626C6650, 0x89043120, 0x624C7401, +0x8FF73273, 0x000B7501, 0xE2FF6043, 0x622C644C, +0x890D3420, 0x8801605C, 0x965D8B03, 0xA005346C, +0x62436243, 0x324C4208, 0x326C9657, 0x6023000B, +0x6043000B, 0x2F962F86, 0x2FB62FA6, 0x2FD62FC6, +0x4F222FE6, 0x92497FF4, 0x6B533526, 0x00296943, +0xE13FCA01, 0x6E03EAFF, 0x6AAC2F10, 0x6D43EC00, +0x62D0E808, 0x34A0642C, 0xBFCE8939, 0x3B0065E3, +0x6CCC8F0A, 0x420062C3, 0x362C6693, 0x1FC18461, +0x4109610C, 0x2F10A02D, 0x891C2CC8, 0x65E364D0, +0x644CBFBB, 0x89163B02, 0x70FF60C3, 0x049C4000, +0x644C65E3, 0x1F02BFB1, 0x8D1A30B2, 0x56F21FC1, +0x356C6593, 0xC9038451, 0x89122008, 0x660C8451, +0xA00E4609, 0x7C012F60, 0x328362CC, 0x8FC87D02, +0xA0061F21, 0x06250009, 0x12C008FC, 0x62CC09B4, +0x50F11F21, 0x8B128808, 0x7CFF6CCC, 0x60C34C00, +0x65E3049C, 0x644CBF89, 0x8B083B06, 0x849139CC, +0x2008C903, 0x84918903, 0x4209620C, 0x60F02F20, +0x4F267F0C, 0x6DF66EF6, 0x6BF66CF6, 0x69F66AF6, +0x68F6000B, 0x2F962F86, 0x2FB62FA6, 0x2FD62FC6, +0x4F222FE6, 0x92727FFC, 0x3426E100, 0x6B436953, +0x2F12666C, 0xCA010029, 0x8D032668, 0xE2F06E03, +0x2F22622C, 0x6AACEAFF, 0x6C93ED00, 0x66C0E808, +0x34A0646C, 0xBF508913, 0x3B0065E3, 0x6DDC8B0A, +0x39DC4D00, 0xC9038491, 0x8B082008, 0xCB0F60F2, +0x2F02A005, 0x62DC7D01, 0x8FE83283, 0x60F27C02, +0x4F267F04, 0x6DF66EF6, 0x6BF66CF6, 0x69F66AF6, +0x68F6000B, 0x2F962F86, 0x2FB62FA6, 0x2FD62FC6, +0x4F222FE6, 0x4F024F12, 0x3F3C9332, 0x4308E35B, +0x605333FC, 0x80341351, 0xE7606063, 0x80381362, +0x4708E012, 0xE03F8136, 0xD11237FC, 0x27008138, +0x80788074, 0xE9166053, 0x60638012, 0x21414918, +0x6B938013, 0xEDFF6AB4, 0x6AAC61B0, 0x6C1C4A18, +0x68C82CAB, 0x6DDD688D, 0x234238D0, 0x8B131398, +0xD207D406, 0x0009420B, 0x432BD306, 0x09B40009, +0x0000FE10, 0x001142D8, 0x000DDD00, 0x001160B0, +0x002018C0, 0x00115E88, 0x342292E3, 0x8F02E100, +0xA1616593, 0x92DD0009, 0x352CE7FF, 0xEE04677C, +0x622C6250, 0x89043270, 0x621C7101, 0x8FF732E3, +0xE8FC7501, 0x3488688C, 0x9ACBE064, 0x40086893, +0x0F4438AC, 0x661C6583, 0x644CBE18, 0x64E36E0C, +0x65E37401, 0x45086643, 0x35EC4608, 0x4508364C, +0x45004608, 0x369C4600, 0x61A39AB5, 0xE0656763, +0x400837AC, 0x62637114, 0x321C0F76, 0x94AB7004, +0x61430F26, 0x359C6263, 0x7004324C, 0x0F267114, +0x7004361C, 0x0F666753, 0x700437AC, 0x7A140F76, +0x37AC6753, 0x66537004, 0x364C0F76, 0x74147004, +0x354C0F66, 0x0F567004, 0x395C958F, 0xED006A93, +0x6BD3E956, 0xEC054908, 0x4008E065, 0x60B302FE, +0x644C042C, 0x60E32F46, 0xE06A07AC, 0x01FE4008, +0x061C60B3, 0x058C60E3, 0x4008E065, 0x677C01FC, +0x655C666C, 0x641CBDED, 0x7F046403, 0x60D36DDC, +0xE0660F44, 0x04FE4008, 0x054C60B3, 0x2F56655C, +0x07AC60E3, 0x4008E06B, 0x60B301FE, 0x60E3061C, +0xE065058C, 0x01FC4008, 0x666C677C, 0xBDD0655C, +0x6403641C, 0x65F37F04, 0x60D37510, 0xE0650544, +0x07FE4008, 0x057C60C3, 0x2F56655C, 0x07AC60E3, +0x4008E06A, 0x60C301FE, 0x60E3061C, 0xE065058C, +0x01FC4008, 0x666C677C, 0xBDB2655C, 0x6403641C, +0x61F37F04, 0x60D37120, 0xE0660144, 0x02FE4008, +0x052C60C3, 0x2F56655C, 0x07AC60E3, 0x4008E06B, +0x60C301FE, 0x60E3061C, 0xE065058C, 0x01FC4008, +0x666C677C, 0xBD94655C, 0x6503641C, 0x64F37F04, +0x60D3349C, 0xE0670454, 0x07FE4008, 0x057C60B3, +0x2F56655C, 0x07AC60E3, 0x4008E06C, 0xA00501FE, +0x0BB860B3, 0x03C2013E, 0x013F0462, 0x60E3061C, +0xE065058C, 0x01FC4008, 0x666C677C, 0xBD70655C, +0x6203641C, 0xE1B87F04, 0x64F3611C, 0x60D3341C, +0xE0680424, 0x05FE4008, 0x075C60B3, 0x2F76677C, +0x07AC60E3, 0x4008E06D, 0x60B301FE, 0x60E3061C, +0xE065058C, 0x02FC4008, 0x666C677C, 0xBD50655C, +0x6703642C, 0xE2C07F04, 0x66F3622C, 0x60D3362C, +0xE0670674, 0x07FE4008, 0x027C60C3, 0x2F26622C, +0x07AC60E3, 0x4008E06C, 0x60C302FE, 0x60E3062C, +0xE065058C, 0x02FC4008, 0x666C677C, 0xBD30655C, +0x6203642C, 0xE7C87F04, 0x66F3677C, 0x60D3367C, +0xE0680624, 0x06FE4008, 0x026C60C3, 0x2F26622C, +0x07AC60E3, 0x4008E06D, 0x60C302FE, 0x60E3062C, +0xE065058C, 0x02FC4008, 0x666C677C, 0xBD10655C, +0x6103642C, 0x66937F04, 0x62F37608, 0x60D3326C, +0x02147D01, 0xE60562DC, 0x7C013263, 0x7B018D02, +0x0009AEFA, 0x0009A17B, 0xE7FF9BD5, 0x677C35BC, +0x6250EE08, 0x3270622C, 0x71018904, 0x32E3621C, +0x75018FF7, 0xDDD89CC8, 0x3D4534C8, 0x4008E064, +0x4E090E0A, 0x0FE46593, 0x702435BC, 0x64EC661C, +0x0F56BCB4, 0x64E36E0C, 0x65E37401, 0x45086243, +0x35EC4208, 0x4508324C, 0x45004208, 0x329C4200, +0x61B37B0C, 0x38BC6823, 0x7114E06E, 0x40086B23, +0x91A23B1C, 0x70040F86, 0x68236413, 0x0FB6359C, +0x7004381C, 0x0F867414, 0x7004342C, 0x67539896, +0x0F466253, 0x7004378C, 0x6B537814, 0x7114321C, +0x3B8C0F76, 0x351C7004, 0x0FB69789, 0x397C7004, +0x70040F26, 0xED006893, 0x0F56EC05, 0x6AD3E956, +0xE06E4908, 0x02FE4008, 0x012C60A3, 0x2F16611C, +0x078C60E3, 0x4008E073, 0x60A304FE, 0xE06E064C, +0x0BFE4008, 0x05BC60E3, 0x4008E065, 0x677C01FC, +0x655C666C, 0x641CBC85, 0x7F046403, 0x60D36DDC, +0xE06F0F44, 0x04FE4008, 0x054C60A3, 0x2F56655C, +0x078C60E3, 0x4008E074, 0x60A30BFE, 0xE06E06BC, +0x0BFE4008, 0x05BC60E3, 0x4008E065, 0x677C01FC, +0x655C666C, 0x641CBC65, 0x7F046403, 0x751065F3, +0x054460D3, 0x4008E06E, 0x60C307FE, 0x655C057C, +0x60E32F56, 0xE073078C, 0x0BFE4008, 0x06BC60C3, +0x4008E06E, 0x60E301FE, 0xE065051C, 0x0BFC4008, +0x666C677C, 0xBC44655C, 0x610364BC, 0x6BF37F04, +0x60D37B20, 0xE06F0B14, 0x01FE4008, 0x041C60C3, +0x2F46644C, 0x078C60E3, 0x4008E074, 0x60C301FE, +0xE06E061C, 0x0BFE4008, 0x05BC60E3, 0x4008E065, +0xA00501FC, 0x0136677C, 0x028212C0, 0x01370142, +0x655C666C, 0x641CBC1D, 0x7F046203, 0x349C64F3, +0x042460D3, 0x4008E070, 0x60A304FE, 0x655C054C, +0x60E32F56, 0xE075078C, 0x0BFE4008, 0x06BC60A3, +0x4008E06E, 0x60E301FE, 0xE065051C, 0x0BFC4008, +0x666C677C, 0xBBFC655C, 0x610364BC, 0xEBB87F04, +0x65F36BBC, 0x60D335BC, 0xE0710514, 0x07FE4008, +0x047C60A3, 0x2F46644C, 0x078C60E3, 0x4008E076, +0x60A30BFE, 0xE06E06BC, 0x01FE4008, 0x051C60E3, +0x4008E065, 0x677C0BFC, 0x655C666C, 0x64BCBBD9, +0x7F046103, 0x622CE2C0, 0x3B2C6BF3, 0x0B1460D3, +0x4008E070, 0x60C302FE, 0x677C072C, 0x60E32F76, +0xE075078C, 0x02FE4008, 0x062C60C3, 0x4008E06E, +0x60E302FE, 0xE065052C, 0x02FC4008, 0x666C677C, +0xBBB6655C, 0x6703642C, 0xEBC87F04, 0x66F36BBC, +0x60D336BC, 0xE0710674, 0x06FE4008, 0x026C60C3, +0x2F26622C, 0x078C60E3, 0x4008E076, 0x60C302FE, +0xE06E062C, 0x02FE4008, 0x052C60E3, 0x4008E065, +0x677C02FC, 0x655C666C, 0x642CBB93, 0x7F046103, +0x72086293, 0x362C66F3, 0x7D0160D3, 0x62DC0614, +0x3263E605, 0x8D027C01, 0xAEE27A01, 0x6EF30009, +0xE2B068F3, 0x6AF3E05A, 0x389C7E18, 0x69F3622C, +0x7A084008, 0x67F36DF3, 0x392C61F3, 0x6CA30FE6, +0x77207D10, 0xE4007128, 0xEB0565F3, 0x604C6654, +0x66D4626C, 0x2E604221, 0x048C6674, 0x626C2C20, +0x09444221, 0x21207001, 0x32B3620C, 0x71016403, +0x8FEB7E01, 0xE05A7C01, 0x6EF34008, 0x7E300BFE, +0xEC19ED00, 0x66B365A3, 0xBB7E64DC, 0x62DC7D01, +0x2E0032C3, 0x7E018FF6, 0x666CE6B0, 0x6BF36EF3, +0x7B283E6C, 0xEC4CA010, 0xCCCCCCCD, 0x64D36DDC, +0x644C74F4, 0xBB6865B3, 0x67F366E3, 0x77306503, +0x075460D3, 0x62DC7D01, 0x8BEF32C3, 0x7B306BF3, +0x61B367B3, 0xED8064B3, 0x71027701, 0x6DDC7403, +0xDC37E500, 0x605CDE37, 0x091C084C, 0x0A7C668C, +0x699C4628, 0x49284618, 0x05BC6AAC, 0x4A18269B, +0x70046803, 0x655C26AB, 0x620C38CC, 0x38EC265B, +0x286232D3, 0x65038FE7, 0x644CE4B8, 0x3C4C6CF3, +0x6EF37408, 0xE2B0E658, 0x3E4C6AF3, 0x74086BF3, +0x460861F3, 0x622C68F3, 0x7A0869F3, 0x314C7B18, +0x386C64F3, 0x6DA3392C, 0x742867B3, 0x66C4E500, +0x626C605C, 0x422166E4, 0x66142760, 0x2D20058C, +0x4221626C, 0x70010954, 0x620C2420, 0x3263E605, +0x74016503, 0x8FEA7701, 0xE05E7D01, 0x02FD4008, +0x6D2DE9D0, 0x699C7D07, 0xEE00A00B, 0x66B365A3, +0x64ECBAFB, 0x620367F3, 0x60EC379C, 0x70010724, +0x62EC6E03, 0x8BF132D3, 0x4008E05F, 0xEAB008FD, +0x6DF36AAC, 0x6BF36C8D, 0x7C0D3DAC, 0x7B28A012, +0x0000A280, 0x001BC000, 0x64E36EEC, 0x644C74F4, +0xBADA65B3, 0x62F366D3, 0x329C6103, 0x7E0160E3, +0x62EC0214, 0x8BEF32C3, 0x3D9C6DF3, 0x67D36ED3, +0xEC8061D3, 0x77027E01, 0x6CCC7103, 0xDBB9E400, +0x604CDAB9, 0x067C041C, 0x08EC654C, 0x666C4528, +0x46284518, 0x09DC688C, 0x4818256B, 0x70046603, +0x699C258B, 0x620C36BC, 0x36AC259B, 0x265232C3, +0x64038FE7, 0x4008E064, 0x70E007FC, 0x706C0CFC, +0x0F8668CC, 0x0DFC7098, 0x6ADC706C, 0x708C0FA6, +0x9BBF0EFE, 0xE2543EB2, 0x697CE100, 0x42088F02, +0x0009A163, 0x4008E063, 0x6EF305FE, 0x3E2C96B3, +0x64E3356C, 0xEDFFE703, 0x32D06250, 0x622C8D07, +0x681C7101, 0x24203873, 0x8FF57505, 0xE0647401, +0x0AFC4008, 0x64AC65E3, 0x661CBA18, 0xE063670C, +0x62734008, 0x42080BFE, 0x7701327C, 0x3A2C6AB3, +0x48086873, 0x948F6EA3, 0x3E4C387C, 0x3B8C74FF, +0x38283A4C, 0xEC003B4C, 0x6083DD88, 0x655C05EC, +0xE0652F56, 0x67B04008, 0x65A066E4, 0x677C01FC, +0x655C666C, 0x641CBA1D, 0x7C017F04, 0xE40462CC, +0x2D003243, 0x7D018FE9, 0xE063E554, 0x67F34508, +0x375C4008, 0x966805FE, 0x356CEDFF, 0x6DDC6473, +0xEE04E100, 0x666C6650, 0x890636D0, 0x621C7101, +0x246032E3, 0x8FF57505, 0xE0647401, 0x02FC4008, +0x642C6573, 0x661CB9CA, 0x6E23620C, 0xE0634E08, +0x72013E2C, 0x0BFE4008, 0x47086723, 0x6AB3372C, +0x68733AEC, 0x6EA338E8, 0x3E1C9140, 0x3B7C71FF, +0x3B1C3A1C, 0x0F96704C, 0xEC00E904, 0x6083DD60, +0x644C04EC, 0xE0652F46, 0x67B04008, 0x65A066E4, +0x677C01FC, 0x655C666C, 0x641CB9CB, 0x7C017F04, +0x329362CC, 0x8FEA2D00, 0xE0767D01, 0x09FE4008, +0x70B4E454, 0x67F34408, 0x374C05FE, 0xEDFF9617, +0x356C6473, 0xE1006DDC, 0x6650EE04, 0x36D0666C, +0x71018906, 0x32E3621C, 0x75092460, 0x74018FF5, +0xE064A006, 0x05BA0BB8, 0x05C905BB, 0x05DD05CA, +0x65734008, 0x661C07FC, 0x647CB970, 0x6623620C, +0x4608E063, 0x46004008, 0x362C0BFE, 0x68237201, +0x3A6C6AB3, 0x48004808, 0x91676EA3, 0x3E1C382C, +0x3B8C71FF, 0x38683A1C, 0xEC003B1C, 0x6083DD35, +0x644C04EC, 0xE0652F46, 0x67B04008, 0x65A066E4, +0x677C01FC, 0x655C666C, 0x641CB973, 0x7C017F04, +0xE50862CC, 0x2D003253, 0x7D018FE9, 0x4008E063, +0x05FEE654, 0x64F34608, 0xECFF9741, 0x357C346C, +0xEE006CCC, 0x6250ED04, 0x32C0622C, 0x7E018906, +0x38D368EC, 0x75092420, 0x74018FF5, 0x4008E077, +0x700405FE, 0x649306FE, 0xEA54B9A7, 0x65F34A08, +0x640C35AC, 0x66ECB91A, 0x6613610C, 0x4608E063, +0x46004008, 0x361C0BFE, 0x68137101, 0x3A6C6AB3, +0x48004808, 0x92136EA3, 0x3E2C381C, 0x3B8C72FF, +0x38683A2C, 0xEC003B2C, 0xE077DD0B, 0x05FE4008, +0x06FE7004, 0x6493B981, 0x0009A010, 0x060105DE, +0x00000602, 0x0000B280, 0x001BC000, 0x001142E4, +0x001142E8, 0x001142ED, 0x001142F5, 0x60836403, +0x677C07EC, 0x67B02F76, 0x65A066E4, 0x666C677C, +0xB906655C, 0x7F04644C, 0x61CC7C01, 0x3123E208, +0x8FD22D00, 0xA0FC7D01, 0xE0630009, 0x05FE4008, +0x96D067F3, 0x356C372C, 0xEEFF6473, 0x32E06250, +0x622C8D08, 0x681C7101, 0x3863E608, 0x75052420, +0x74018FF4, 0x4008E064, 0x657302FC, 0xB8B5642C, +0x650C661C, 0x4008E063, 0x0BFE6253, 0x325C4208, +0x6AB37501, 0x68533A2C, 0x6EA34808, 0x385C94AC, +0x74FF3E4C, 0x3A4C3B8C, 0x3B4C3828, 0xDD96EC00, +0x06EC6083, 0x2F66666C, 0x4008E065, 0x66E467B0, +0x01FC65A0, 0x666C677C, 0xB8BA655C, 0x7F04641C, +0x62CC7C01, 0x3243E404, 0x8FE92D00, 0xE5547D01, +0x4508E063, 0x400867F3, 0x05FE375C, 0xEEFF9685, +0x6473356C, 0xE1006EEC, 0x666C6650, 0x890736E0, +0x621C7101, 0x3283E808, 0x75092460, 0x74018FF4, +0x4008E064, 0x65730AFC, 0xB86764AC, 0x620C661C, +0xE0636623, 0x40084608, 0x0BFE4600, 0x7201362C, +0x6AB36823, 0x48083A6C, 0x6EA34800, 0x382C915E, +0x71FF3E1C, 0x3A1C3B8C, 0x3B1C3868, 0xDD6FEC00, +0x04EC6083, 0x2F46644C, 0x4008E065, 0x66E467B0, +0x01FC65A0, 0x666C677C, 0xB86A655C, 0x7F04641C, +0x62CC7C01, 0x3253E508, 0x8FE92D00, 0xE0637D01, +0xE6544008, 0x460805FE, 0x973864F3, 0x346CECFF, +0x6CCC357C, 0xED08EE00, 0x666C6650, 0x890636C0, +0x62EC7E01, 0x246032D3, 0x8FF57509, 0xE0777401, +0x05FE4008, 0x06FE7004, 0xB89E6493, 0x4808E854, +0x358C65F3, 0xB811640C, 0x610C66EC, 0xE0636613, +0x40084608, 0x0BFE4600, 0x7101361C, 0x6AB36813, +0x48083A6C, 0x6EA34800, 0x381C920A, 0x72FF3E2C, +0xA0063B8C, 0x05023A2C, 0x052A0503, 0x0572052B, +0x38680573, 0xEC003B2C, 0xE077DD41, 0x05FE4008, +0x06FE7004, 0x6493B871, 0x60836403, 0x677C07EC, +0x67B02F76, 0x65A066E4, 0x666C677C, 0xB808655C, +0x7F04644C, 0x61CC7C01, 0x3123E208, 0x8FE42D00, +0xD3347D01, 0x0009430B, 0xE079620C, 0x0F244008, +0x88306023, 0xA24D8B01, 0x88400009, 0xA2498B01, +0x22280009, 0xA2458B01, 0xE5FF0009, 0x655CD42A, +0xE03AE601, 0x8F043250, 0xE0790464, 0x4008E210, +0xE05B0F24, 0x05FE4008, 0x3566963B, 0xA1498B01, +0x60230009, 0x640CCB01, 0x6E23B842, 0xE118660C, +0x890F3613, 0x4008E063, 0x04FE4608, 0x97294608, +0x460070E0, 0x05FE347C, 0x346CB85C, 0xE0606203, +0x0F244008, 0xCB0260E3, 0x640CB82A, 0xE118660C, +0x890F3613, 0x4008E063, 0x04FE4608, 0x91114608, +0x460070E0, 0x05FE341C, 0x346CB844, 0xE0616203, +0x0F244008, 0xCB0560E3, 0x640CB812, 0xA00D660C, +0x09B4E07A, 0x0000064D, 0x001142FD, 0x00114301, +0x00114309, 0x00114400, 0x001142D8, 0x4008E118, +0x8F043613, 0xE0610F64, 0xA0104008, 0xE07A0DFC, +0x06FC4008, 0x626C70A4, 0x04FE4208, 0x97B44208, +0x420070E0, 0x05FE347C, 0x342CB814, 0xE0796D03, +0x00FC4008, 0xCB07DB8E, 0x430BD38E, 0x610C640C, +0x4008E07A, 0x709C0F14, 0xE61802FC, 0x8D1C3163, +0xE05D682C, 0x01FC4008, 0x09FC70FC, 0x04FE70FC, +0xD385661C, 0x659C430B, 0xE07A6503, 0x01FC4008, +0x611C70A4, 0x04FE4108, 0x97864108, 0x347C4100, +0x430BD37E, 0xA003341C, 0xE0616C03, 0x0CFC4008, +0xE500D67B, 0x640D8562, 0x4008E05B, 0x0AFEA036, +0x6053655C, 0x305C4000, 0x4008D676, 0x622D026D, +0x8F2A32A0, 0xD3746E03, 0x64AD430B, 0x2228620D, +0xD6728927, 0x066C60E3, 0x4008E060, 0x460002FC, +0x3E676E2C, 0x62638B00, 0x4008E060, 0x0F243867, +0x62638D03, 0x4008E061, 0xE06102FC, 0x400861DC, +0x0F243167, 0x8F01682C, 0x626362D3, 0x346764CC, +0x6D238D01, 0xA00466C3, 0x75016C63, 0x3243625C, +0xE0608BC6, 0x07FC4008, 0x617CE400, 0xE904D55C, +0x666C6650, 0x8B013617, 0x6673677C, 0x624C7401, +0x25603293, 0x75018FF4, 0xE03AD656, 0xE400056C, +0x8D012558, 0xE2026243, 0x4008E061, 0x67830EFC, +0x3E283828, 0x9119E500, 0x6053655C, 0x3A1002BC, +0x622C8D0B, 0x3A609613, 0x32778907, 0xE0618B02, +0x02FC4008, 0xA01D6053, 0x25580B24, 0x32878908, +0x62838B00, 0xA0156053, 0x064D0B24, 0x099E096C, +0x8F083277, 0xE07B6623, 0x0F164008, 0x02FC7098, +0x01FE7068, 0x626C662C, 0x32876053, 0x0B648F02, +0x646336E8, 0x625C7501, 0x8BCD3293, 0xE014D635, +0xE4000644, 0xD53461DC, 0x6250E708, 0x3217622C, +0x6DDC8B01, 0x740162D3, 0x3673664C, 0x8FF42520, +0xE4007501, 0xD52D61CC, 0x622C6250, 0x8B013217, +0x62C36CCC, 0x664C7401, 0x25203673, 0x75018FF4, +0x0009A0EC, 0x4008E079, 0x642C02FC, 0x430BD319, +0x660C6E43, 0x3653E518, 0xE0638910, 0x46084008, +0x460804FE, 0x70E09722, 0x347C4600, 0xD31305FE, +0x346C430B, 0xE0626203, 0x0F244008, 0xCB0660E3, +0x430BD30C, 0x660C6403, 0x3653E518, 0xE0638928, +0x46084008, 0x460804FE, 0x70E09708, 0x347C4600, +0xD30605FE, 0x346C430B, 0x6C03A01D, 0x0000064D, +0x001142E8, 0x001148E0, 0x001148BA, 0x00114934, +0x00114000, 0x00114008, 0x00114774, 0x00114011, +0x001142E4, 0x001142D8, 0x001142ED, 0x001142F5, +0x4008E062, 0x60E30CFC, 0xD39CCB08, 0x6403430B, +0xE07A610C, 0x4008E618, 0x8D1C3163, 0xE05D0F14, +0x07FC4008, 0x09FC70FC, 0x04FE70FC, 0xD394667C, +0x659C430B, 0xE07A6503, 0x01FC4008, 0x611C70A4, +0x04FE4108, 0x9D744108, 0x34DC4100, 0x430BD38D, +0xA003341C, 0xE0626D03, 0x0DFC4008, 0xE500D68A, +0x640D8562, 0x4008E05B, 0x01FEA02C, 0x6053655C, +0x305C4000, 0x4008D685, 0x622D026D, 0x8F203210, +0xD3836E03, 0x641D430B, 0x2228620D, 0xD681891D, +0x066C60E3, 0x4008E062, 0x460002FC, 0x3167612C, +0x62638B00, 0x64CCE062, 0x34674008, 0x8F010F24, +0x626362C3, 0x356765DC, 0x6C238D01, 0xA00466D3, +0x75016D63, 0x3243625C, 0xE0628BD0, 0x07FC4008, +0x617CE400, 0xE904D570, 0x622C6250, 0x8B013217, +0x6273677C, 0x664C7401, 0x25203693, 0x75018FF4, +0x61CCE400, 0xE708D569, 0x666C6650, 0x8B013617, +0x66C36CCC, 0x624C7401, 0x25603273, 0x75018FF4, +0x61DCE400, 0x6650D562, 0x3617666C, 0x6DDC8B01, +0x740166D3, 0x3273624C, 0x8FF42560, 0xA0057501, +0x064D0009, 0xE200D65B, 0x0624E03A, 0xE03AD659, +0x2228026C, 0xE039894B, 0x2228026C, 0xE05B8947, +0x0EFE4008, 0x3E669690, 0xE0798941, 0x00FC4008, +0x8D023E66, 0xCB02640C, 0xD344640C, 0x0009430B, +0xE05C660C, 0x07FC4008, 0x4608701C, 0x617C05FE, +0x977A4608, 0x357C4600, 0x6613356C, 0x430BD346, +0xD54464E3, 0x62032008, 0x0029150F, 0x6603CA01, +0x2668E03B, 0x05648D20, 0xC8F06023, 0xD53F8909, +0x76FF6650, 0x84512560, 0x805170FF, 0x70FF8452, +0x60238052, 0x890FC80F, 0x6260D639, 0x26207201, +0x70018461, 0x84628061, 0xA0057001, 0xD6318062, +0xE03BE200, 0x162F0624, 0x4008E05B, 0x964302FE, +0x8B653266, 0xD72BD428, 0xD52E6040, 0x4028C93F, +0x40084008, 0x50726203, 0xC802D12B, 0xE604891A, +0x46284618, 0x2522226B, 0xE2086040, 0x6503C93F, +0x66034508, 0x45004508, 0x46284218, 0x6263252B, +0x42084208, 0x252B4200, 0x4218E208, 0x252B4228, +0x2152A062, 0x4618E614, 0x226B4628, 0x60402522, +0xC93FE428, 0x45086503, 0x45084028, 0x45004008, +0x40084418, 0x254BE728, 0x47184000, 0x4728250B, +0xD412257B, 0x2152A044, 0x064D09B4, 0x001148E0, +0x001148BA, 0x00114934, 0x00114000, 0x00114008, +0x00114774, 0x00114011, 0x001142FD, 0x00114301, +0x00114309, 0x001142D8, 0x00114A24, 0x001142F5, +0x001142ED, 0x001C3694, 0x001C3BB4, 0x001142E8, +0xE214D429, 0x42186040, 0x4028C93F, 0x40084008, +0xD6264228, 0x2602202B, 0xE7286040, 0x6503C93F, +0x45084508, 0x45004028, 0x40084718, 0x4008257B, +0x4000E728, 0x250B4718, 0xD21D4728, 0x2252257B, +0xD71C6240, 0x0724E044, 0x3F3C932C, 0x4F164F06, +0x6EF64F26, 0x6CF66DF6, 0x6AF66BF6, 0x000B69F6, +0x2FE668F6, 0x6243D114, 0xE4028512, 0x6E2D670D, +0xE500A00F, 0x6053655D, 0x305C4000, 0x4008D10F, +0x622D021D, 0x8B0332E0, 0x041C7108, 0x644CA004, +0x625D7501, 0x8BED3273, 0x4618E602, 0x604D2469, +0x6EF6000B, 0x000001F0, 0x001142E8, 0x001C3694, +0x001C3BB4, 0x001142D8, 0x00114000, 0x00114008, +0xD766D565, 0x62725151, 0x321CE340, 0x51522722, +0x337C5271, 0x1721321C, 0x52725153, 0x321C644C, +0x1722D15F, 0x66125255, 0x2162362C, 0x316C5173, +0x61521713, 0xD65B5274, 0x1724321C, 0x52755154, +0x1725321C, 0x52765158, 0x1726321C, 0x51776262, +0x1717312C, 0x51785261, 0x1718312C, 0x51795262, +0x1719312C, 0x517A5263, 0x171A312C, 0x517B5264, +0x171B312C, 0x517C5265, 0x171C312C, 0x517D5266, +0x171D312C, 0x517E5267, 0x171E312C, 0x527F5168, +0x321CD645, 0x6262172F, 0x76946132, 0x2312312C, +0x52316162, 0x321CD641, 0x515C1321, 0x351C5532, +0x61621352, 0x41295235, 0x1325321C, 0x56365561, +0x365C4529, 0x1366E538, 0x55312450, 0x71046143, +0x66722152, 0x75086543, 0x56712562, 0x750C6543, +0x56722562, 0x75106543, 0x56752562, 0x75146543, +0x56732562, 0x75186543, 0x56762562, 0x751C6543, +0x56322562, 0x75206543, 0x66322562, 0x75246543, +0x56742562, 0x75286543, 0x56342562, 0x752C6543, +0x55332562, 0x72306243, 0x55352252, 0x72346243, +0x56362252, 0x24627438, 0x1341E400, 0x17412742, +0x17451742, 0x17461743, 0x23421342, 0x13441744, +0x13451343, 0x1346000B, 0xD510E124, 0x51572410, +0x52581411, 0x57591422, 0x515A1473, 0x525B1414, +0x575C1425, 0x525D1476, 0x1427E700, 0x1468565E, +0x1469565F, 0x15781577, 0x157A1579, 0x157C157B, +0x157E157D, 0x157F000B, 0x001C369C, 0x0020351C, +0x00203578, 0x001C3CA0, 0x001C36F4, 0x001C3B88, +0x6E726157, 0x21676E69, 0x69685420, 0x6F642073, +0x656C676E, 0x746F6E20, 0x65656220, 0x6163206E, +0x7262696C, 0x64657461, 0x0000000A, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +const u32_t zcFwBufImageSize=83968; --- linux-2.6.28.orig/drivers/staging/otus/hal/hpfwu.c +++ linux-2.6.28/drivers/staging/otus/hal/hpfwu.c @@ -0,0 +1,1017 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "cprecomp.h" + +const u32_t zcFwImage[] = { +0x0009000B, 0x4F222FE6, 0xDE947FFC, 0xE114D594, +0x1E13D494, 0x67521E4C, 0xD494D693, 0x37402769, +0x62528F06, 0x7201D692, 0x60602522, 0x2600C93F, +0xD7906152, 0x2512611D, 0x264B6652, 0x2562470B, +0x0009B017, 0xE60095AC, 0xC84060E2, 0x2F028F03, +0x8FF93652, 0xD4887601, 0x4E0BDE88, 0xD4880009, +0x00094E0B, 0x4E0BD487, 0x7F040009, 0xA0524F26, +0x4F226EF6, 0x410BD184, 0xD4840009, 0x0009440B, +0x450BD583, 0xD7830009, 0xD283E1FF, 0x2712611D, +0xD4825029, 0xE1FFCB01, 0x1209E501, 0x12112212, +0xE7202452, 0x4718D57E, 0x2572D27E, 0xD17EE700, +0xD67FD47E, 0xE2012270, 0x24702172, 0xD67D2620, +0x2641E4FF, 0xD57CE600, 0x666DE104, 0x76016063, +0x4000626D, 0x8FF83212, 0xD5780545, 0x2520E201, +0xD278D777, 0xE480E100, 0x22122710, 0x6613D576, +0x666D644C, 0x76046763, 0x375C626D, 0x8FF83243, +0xD5722712, 0xD273D772, 0xE400E101, 0x27102511, +0x000B4F26, 0x7FCC2242, 0xD170D56F, 0xD271DB70, +0x1F51D471, 0xD6717508, 0x1F12D771, 0x1F55710C, +0x1FB975FC, 0x72041F2A, 0x1F13EB10, 0x1F561F44, +0x1F781F67, 0xD86B1F2B, 0xDD6CD96B, 0xDC6CEA00, +0xD26DDE6C, 0x89003A22, 0xD15D7A01, 0x88016010, +0x56F88B03, 0x4218E201, 0xD1682622, 0x0009410B, +0x440BD467, 0xD5670009, 0x0009450B, 0x6010D150, +0x8B108801, 0xE650D14F, 0x46186212, 0x8B083266, +0x56F9D14B, 0x2120E200, 0xCB016062, 0x2602A003, +0x72012710, 0x60822122, 0x89098801, 0xE2C8D15A, +0x622C6612, 0x89033626, 0x6010D158, 0x8BC88801, +0x51F66792, 0x217252F5, 0xD6555191, 0x55FA2212, +0x52FB6462, 0x55612542, 0x2252E400, 0x61436643, +0x05DE6013, 0x36CC4608, 0x07DE2652, 0xC9036071, +0x8B028801, 0x720162E2, 0x74012E22, 0x36B3664C, +0x71048FEE, 0x66C2D147, 0x45286512, 0x265B4518, +0x60822C62, 0x89018801, 0x0009A168, 0x6272D742, +0x8B132228, 0xD42BD741, 0x6772D541, 0x51536242, +0x312C327C, 0x24222228, 0x15138D05, 0x6262D63D, +0xB1627201, 0xD6232622, 0x2622E200, 0x52916692, +0x8B013620, 0x0009A144, 0x6061A06E, 0x001C001C, +0x001D4020, 0x0000B38E, 0xFFFF0000, 0x12340000, +0x001E1015, 0x00201274, 0x002039F4, 0x002018A2, +0x00203A00, 0x00203A18, 0x00201860, 0x0020196C, +0x00201288, 0x001C3510, 0x001C3624, 0x001E212C, +0x002038F4, 0x0020348C, 0x002038FC, 0x00203908, +0x00203914, 0x00203970, 0x00203974, 0x0020391C, +0x0020391D, 0x00203920, 0x00117700, 0x0020398C, +0x0020398A, 0x002034F0, 0x00117710, 0x001C3D30, +0x001C36F8, 0x00117734, 0x001C3684, 0x001C3D00, +0x001C1000, 0x001C1028, 0x00203504, 0x00203924, +0x00117600, 0x00117740, 0x7FFFFFFF, 0x00201730, +0x0020332A, 0x00202334, 0x00203DA4, 0x00203972, +0x002034FC, 0x00203964, 0x001C3D2C, 0x001C36B0, +0x00203494, 0x0011775C, 0x8801C90F, 0xA0CF8901, +0xD1960009, 0x36206212, 0xD4958904, 0x2421E200, +0x2162A0CC, 0x6211D193, 0x89012228, 0x0009A0C3, +0xE202D78F, 0x75016571, 0x3123615D, 0x27518D02, +0x0009A0BC, 0xD28C57F2, 0x62226072, 0x40094019, +0xC90F4009, 0x8F19880A, 0x52F31F2C, 0x40196022, +0x40094009, 0x8808C90F, 0xA0A78901, 0x60630009, +0xCB0154F7, 0xD27E55F2, 0xE7012402, 0xD47FE100, +0x22112572, 0x72016242, 0x2422A098, 0x8B3F8805, +0x602252F3, 0x40094019, 0xC90F4009, 0x8B168802, +0xE4FFD577, 0x644D6752, 0x8B102748, 0x6272D775, +0x8B0C3260, 0x51F255F7, 0xD26DE701, 0x21722562, +0xD571E100, 0x64522211, 0xA0777401, 0x52F32542, +0x40196022, 0x40094009, 0x8805C90F, 0x31B38B6E, +0xD26A8B6C, 0x672254F4, 0x7701D569, 0x61422272, +0x1F1CE640, 0x46182159, 0x8B033160, 0x6262D665, +0x26227201, 0xE200D65A, 0x2621B067, 0x0009A056, +0x3123E220, 0x88038B52, 0x52F38B1E, 0x40196022, +0x40094009, 0x8803C90F, 0xD25B8B16, 0x672254F4, +0x7701D557, 0x61422272, 0x1F1CE640, 0x46182159, +0x8B033160, 0x6262D655, 0x26227201, 0xE200D648, +0x2621B043, 0x0009A010, 0xD452D551, 0xD2446752, +0xE1007701, 0x25723A46, 0x22118F06, 0xEA00D64E, +0x72016262, 0x2622B031, 0x2FB2D54C, 0x95736652, +0xD44A5BF1, 0x36205241, 0x60618910, 0x8B01C803, +0x2B22E201, 0x8FF54510, 0x57F15664, 0x6272E1F0, +0x41284118, 0x2722221B, 0x6BF2A008, 0x6BF2A006, +0xE200D62F, 0xD12F2621, 0x2121E200, 0xD13CE201, +0x66122822, 0x8B012668, 0x0009AE2B, 0x450BD539, +0xD1390009, 0xAE24E600, 0x2F862160, 0x2FA62F96, +0x2FC62FB6, 0x2FE62FD6, 0x7FF44F22, 0xDE34D133, +0x54116212, 0x1F4167E2, 0x2F22D432, 0xD5321F72, +0xD2326743, 0x58417794, 0x69425A42, 0x5B166C72, +0x60526D22, 0xCB20E600, 0xE5402502, 0x626D7601, +0x8BFB3253, 0x55F162F2, 0x11512122, 0xD62855F2, +0x14812E52, 0x249214A2, 0x27C2D426, 0x26D211B6, +0xDA256742, 0xE801D925, 0x490B2A72, 0xE2011A8C, +0x1A2C4218, 0x4F267F0C, 0x6DF66EF6, 0x6BF66CF6, +0x69F66AF6, 0x68F6000B, 0x000007D1, 0x00203984, +0x00203988, 0x0020398E, 0x001C3DC0, 0x0011772C, +0x001C3B88, 0x0020396C, 0x0011773C, 0x00117744, +0x0000F000, 0x00117764, 0x00117748, 0x00117768, +0x0011776C, 0x01FFFFFF, 0x0011774C, 0x002034FC, +0x00203DA4, 0x002024F8, 0x00203972, 0x001C3B9C, +0x001C3D98, 0x001C3700, 0x001C3500, 0x001C5960, +0x001C8960, 0x00203504, 0x001C3D00, 0x0020160C, +0x2F962F86, 0x2FB62FA6, 0x2FD62FC6, 0x4F222FE6, +0xDE957FAC, 0x61E0E014, 0x0F14D494, 0x710161E3, +0xE0186210, 0xD2920F24, 0x0009420B, 0x450BD591, +0x20080009, 0x8F126D03, 0xD28F1F07, 0x6720D48F, +0x657CDD8F, 0x470BD78F, 0xD18F0009, 0x619C6910, +0x46086613, 0x36184608, 0x3D6C4608, 0xE0181FD7, +0xE58004FC, 0x604C66E2, 0x3050655C, 0x2D628F15, +0x01FCE014, 0xDE85E500, 0x641CA008, 0x6753655D, +0x607037EC, 0x39DC6953, 0x80947501, 0x3243625D, +0xD67F8BF4, 0xA34EE200, 0x20082621, 0xE0148B13, +0xE40001FC, 0xA009DE79, 0x644D671C, 0x35EC6543, +0x69436652, 0x39DC6262, 0x74041921, 0x3273624D, +0xA3388BF3, 0x88012D10, 0xE0148B17, 0xE70001FC, +0x6D1C2D70, 0xDE6D1FD4, 0x32D3627D, 0xA32A8B01, +0x677D0009, 0x667365E3, 0x61737504, 0x315C36EC, +0x69126462, 0xAFEF7708, 0x88042492, 0xE0148B18, +0xE40001FC, 0x671C2D40, 0x624DDE60, 0x8B013273, +0x0009A311, 0x6943644D, 0x39EC62E3, 0x72046592, +0x3D2C6D43, 0x615266D2, 0x21697408, 0x2512AFED, +0x8B188805, 0x01FCE014, 0x2D40E400, 0xDE53671C, +0x3273624D, 0xA2F68B01, 0x644D0009, 0x62E36943, +0x659239EC, 0x6D437204, 0x66D23D2C, 0x74086152, +0xAFED216B, 0x88312512, 0xD44A8B3A, 0x6146D94A, +0x75046543, 0x67566442, 0x6E531F48, 0x65527E04, +0x7EE462E2, 0x7E0464E2, 0x6EE21FE9, 0x5EF929E0, +0x7E04D942, 0x1FEA60E2, 0x2900C901, 0xD9406EE2, +0x29E04E09, 0x2F562F26, 0x56FAD93E, 0x6513490B, +0xD13D7F08, 0xE71C6E0D, 0x1DE12D70, 0xDE3B6912, +0x64E21D92, 0x1D43D13A, 0xD23A6512, 0x67221D54, +0x1D75D239, 0x1D666622, 0x6262D638, 0x1D27A2AB, +0x8B398830, 0x6596D92B, 0x67926696, 0x61967904, +0x74E46493, 0x6E436992, 0x1F9B7E04, 0x1FEC6442, +0xD9256EE2, 0x5EFC29E0, 0x7E04D924, 0x1FED60E2, +0x2900C901, 0xD9226EE2, 0x29E04E09, 0x59FC7FFC, +0xDE272F92, 0x2F164E0B, 0xD41F7F08, 0xE21C610D, +0x1D112D20, 0xD2206442, 0xD41C1D42, 0x1D536542, +0x6752D51B, 0xD71B1D74, 0x1D156172, 0x1D666622, +0x6262D61A, 0x1D27A26F, 0x8B358833, 0x490BD919, +0xA268EE00, 0x00002DE0, 0x00117800, 0x00203A1C, +0x002018A2, 0x00202AAC, 0x0020390E, 0x00203A20, +0x00203534, 0x002018EE, 0x0020390D, 0x00117804, +0x0020398C, 0x00117810, 0x00203909, 0x0020390A, +0x0020390B, 0x00200F64, 0x001C5864, 0x001C6864, +0x001C7864, 0x001C59BC, 0x001C69BC, 0x001C79BC, +0x00200FBC, 0x00200FB8, 0x89018828, 0x0009A0C0, +0xE643DEB5, 0x326662E1, 0x1FEE8F02, 0x2E21E240, +0x622D62E1, 0x8B013267, 0x0009A0AA, 0xE50185E1, +0x8B013056, 0x0009A0A4, 0x2D10E101, 0x64E1B225, +0xE64357FE, 0x652D6271, 0x89443567, 0x3563E640, +0xE6008B05, 0x0F65E040, 0xA00FE11A, 0x615372C0, +0x41214121, 0x41214121, 0x45214121, 0x45214521, +0xC9036053, 0xE0406603, 0x71180F65, 0x2209E007, +0x0F25E03C, 0xE044641D, 0xB2A365F3, 0xE33C0F46, +0x853233FC, 0x620DDE95, 0x42086031, 0x6023610D, +0x1323E944, 0x06FE4108, 0xE00F39FC, 0x13144E0B, +0x67075D91, 0x60D32679, 0x0F6654FE, 0x51928542, +0x600D4E0B, 0x60D3260B, 0x0F666492, 0x65F3B237, +0x696156FE, 0xE640659D, 0x89383563, 0xD78359FE, +0x79066591, 0xC9036053, 0x40004008, 0x61036203, +0x0F26E050, 0x470BE0FF, 0x6C07600C, 0x6603605D, +0x46214621, 0x46214621, 0x42006263, 0x4200326C, +0x40214021, 0x4008C903, 0x6D2D30FC, 0xE8006A03, +0xB25765F3, 0x6EA264D3, 0x2EC9E050, 0x66942AE2, +0xD76E01FE, 0x606C470B, 0x2AE22E0B, 0x64D365F3, +0x7801B1FD, 0xEE06628D, 0x8FE932E3, 0x5EFE7D01, +0x61E1E400, 0x410085E1, 0x66E3310C, 0x760C711B, +0xE70465F3, 0x68667401, 0x3A736A4D, 0x8FF92582, +0x65F37504, 0x641DB1E3, 0x64E1B1A4, 0x0009A17B, +0xD45B56F7, 0xEC01D25B, 0x26C0420B, 0x0009A173, +0x06FCE018, 0x8829606C, 0x58F78B08, 0xE400D252, +0x66222840, 0x646DB171, 0x0009A165, 0x666CE681, +0x89013060, 0x0009A0AC, 0xD550D14F, 0x62126A56, +0x212232AC, 0x54116C56, 0x34CC6253, 0x64521141, +0x72085812, 0xD44A384C, 0x68221182, 0x5A136C42, +0x3ACC3C8C, 0x11A324C2, 0x6C2272EC, 0x72105814, +0x118438CC, 0x5A156822, 0x11A53A8C, 0x6A227210, +0xD6405816, 0x118638AC, 0x52176C62, 0x112732CC, +0x5A185861, 0x11A83A8C, 0x5C195A62, 0x11C93CAC, +0x521A5C63, 0x112A32CC, 0x5A1B5864, 0x11AB3A8C, +0x5C1C5A65, 0x11CC3CAC, 0x521D5C66, 0x112D32CC, +0x5A1E5867, 0x11AE3A8C, 0x561F5A68, 0x36ACE840, +0x116FDA2D, 0x6CA2381C, 0x7A946682, 0x286236CC, +0x5C8162A2, 0x18C13C2C, 0x62A27A44, 0x362C5682, +0xD6261862, 0x5A856262, 0x3A2C4229, 0x760418A5, +0x56866262, 0x362C4229, 0x56F71866, 0x2620E238, +0x16C15C81, 0x16226212, 0xE2005C11, 0x551216C3, +0x55151654, 0x55131655, 0x55161656, 0x55821657, +0x65821658, 0x55141659, 0x5584165A, 0x5583165B, +0x5585165C, 0x5586165D, 0x1821165E, 0x11212122, +0x11251122, 0x11261123, 0x28221822, 0x18241124, +0x18251823, 0x1826A0C7, 0x00117804, 0x002033E8, +0x00203A40, 0x002018A2, 0x00203494, 0x001C36A0, +0x002034F0, 0x001C3CA0, 0x001C36F4, 0x001C3B88, +0x666CE682, 0x8B203060, 0xEA2456F7, 0x26A0D194, +0x16C15C17, 0x16225218, 0x16835819, 0x16A45A1A, +0x16C55C1B, 0x1626521C, 0xE200581D, 0x551E1687, +0x551F1658, 0x11271659, 0x11291128, 0x112B112A, +0x112D112C, 0xA08E112E, 0xE683112F, 0x3060666C, +0x52F78B0B, 0xEA00D883, 0x658222A0, 0x7804DC82, +0x62822C52, 0xA07ED681, 0xE6902620, 0x3060666C, +0xDA7F8B06, 0x00094A0B, 0xE20056F7, 0x2620A073, +0x666CE691, 0x8B103060, 0x6222D276, 0x2228622C, +0xD2788904, 0x0009420B, 0x0009A003, 0x420BD276, +0x56F70009, 0xA05EE200, 0xE6922620, 0x3060666C, +0xE0188951, 0xE6B00BFC, 0x666C62BC, 0x8B2A3260, +0x02FCE014, 0x682CEA00, 0x62ADE904, 0x894A3283, +0x6AADDD64, 0x3CDC6CA3, 0x7D046EC2, 0xDB68D467, +0x32DC62A3, 0x4B0BDC67, 0x4C0B6D22, 0xD46664E3, +0x00094B0B, 0x64D34C0B, 0x4B0BD464, 0xE6000009, +0x666D6BE3, 0x76013B6C, 0x3293626D, 0x8FF72BD0, +0xAFDA4D19, 0xE6B57A08, 0x3260666C, 0xD45C8B13, +0x4B0BDB57, 0xD25B0009, 0x6022DB5B, 0xCB20E6FF, +0x2202666D, 0xDB592B62, 0xE014E200, 0x56F72B20, +0xA01002FC, 0xD4562620, 0x6542D256, 0x420BD456, +0xA0080009, 0xDB520009, 0x52B1E600, 0x622CDB53, +0x52F72B21, 0x7F542260, 0x6EF64F26, 0x6CF66DF6, +0x6AF66BF6, 0x000B69F6, 0x4F2268F6, 0xE240614D, +0x89143123, 0x3127E21F, 0x8B09D749, 0xD449614D, +0xE00171E0, 0x5671440B, 0x26596507, 0x1761A007, +0xE001D444, 0x6672440B, 0x26596507, 0x4F262762, +0x0009000B, 0x614D4F22, 0x3123E240, 0xE21F8912, +0xD73B3127, 0x614D8B08, 0x5671D23A, 0x420B71E0, +0x260BE001, 0x1761A006, 0x6672D236, 0xE001420B, +0x2762260B, 0x000B4F26, 0xE6400009, 0x46284618, +0x6252D531, 0x89FC2268, 0x0009000B, 0x4618E680, +0xD52D4628, 0x22686252, 0x000B89FC, 0xA0010009, +0x7201E200, 0x8BFC3242, 0x0009000B, 0x4618E680, +0xD5264628, 0x22686252, 0x000B8BFC, 0x2FE60009, +0x7FFC4F22, 0xBFF16E53, 0x61E22F42, 0xE280D620, +0x54E11615, 0x16464218, 0x422855E2, 0x57E31657, +0x16786EF2, 0x26E22E2B, 0x4F267F04, 0x6EF6AFCE, +0x00203494, 0x00117804, 0x002038F4, 0x00203908, +0x0020050A, 0x00201008, 0x0020102E, 0x00203A58, +0x002018A2, 0x002018E6, 0x00203A6C, 0x00203A74, +0x00203A78, 0x001C3500, 0x001C1000, 0x0020398A, +0x00117800, 0x002018EE, 0x00203A8C, 0x00203990, +0x001C3704, 0x002033E8, 0x001C373C, 0x001C3700, +0x001C370C, 0x2FD62FC6, 0x4F222FE6, 0x6C53DD10, +0x6E43BFA4, 0x2DE2BF89, 0x0009BFA0, 0x2C1251D5, +0x1C4154D6, 0x1C5255D7, 0x1C6356D8, 0x6EF64F26, +0x000B6DF6, 0x61636CF6, 0xA004E600, 0x62564109, +0x24227601, 0x36127404, 0x000B8BF9, 0x00000009, +0x001C370C, 0x0009A16E, 0x2FE62FD6, 0xDD944F22, +0xA0049EB2, 0xD4930009, 0x420BD293, 0x62D265D2, +0x8BF822E8, 0x0009A004, 0xD28FD490, 0x55D1420B, +0x22E852D1, 0xA0048BF8, 0xD48D0009, 0x420BD28A, +0x52D255D2, 0x8BF822E8, 0x0009A004, 0xD286D489, +0x55D3420B, 0x22E852D3, 0xA0048BF8, 0xD4860009, +0x420BD281, 0x52D455D4, 0x8BF822E8, 0x6EF64F26, +0x6DF6000B, 0x2FD62FC6, 0x4F222FE6, 0x6E636C73, +0x6D53B01A, 0x64D357F4, 0xB05F65E3, 0xB07566C3, +0xB0A40009, 0xB0A80009, 0xB0AC0009, 0xB0AC0009, +0xB0AF0009, 0xB03154F5, 0x6CCD6C03, 0x4F2660C3, +0x6DF66EF6, 0x6CF6000B, 0x3412D170, 0xD6700529, +0x2650D770, 0x2742000B, 0x0009A018, 0x2FD62FC6, +0x4F222FE6, 0x6E636C73, 0x6D53BFEE, 0x64D357F4, +0xB03365E3, 0xB08D66C3, 0xB00F54F5, 0x6CCD6C03, +0x4F2660C3, 0x6DF66EF6, 0x6CF6000B, 0xE503D162, +0xD763D462, 0x21524518, 0x2472000B, 0xD45FD15E, +0x2162E600, 0x2462000B, 0xBF734F22, 0xBF73E40A, +0xD25C0009, 0x4118E104, 0xE40AE500, 0xBF692212, +0xD7592252, 0xCB206072, 0x000B4F26, 0x4F222702, +0x410BD156, 0xD556E400, 0x4F26452B, 0xD1552FE6, +0x66126E63, 0x92104418, 0x44084528, 0x45002629, +0x265B4408, 0x264B4400, 0x21624708, 0xD14E4708, +0x217227EB, 0x6EF6000B, 0x1FFF03F0, 0x4F222FE6, +0xE101DE4A, 0xBF3DE40A, 0x67E32E12, 0xE500776C, +0xE204E130, 0x2752E40A, 0x27522752, 0x27522752, +0x27522752, 0x27522752, 0x27522752, 0x27522752, +0x27522752, 0x27522752, 0x27522752, 0x27222712, +0x27522752, 0x27522752, 0x27522752, 0x27522752, +0x175ABF18, 0x2E62E600, 0x000B4F26, 0xD2346EF6, +0xE441E101, 0x000B2212, 0xD1322242, 0xE605D432, +0x000B2162, 0x000B2462, 0xD2300009, 0xE40AE601, +0x2262AF00, 0x2FC62FB6, 0x2FE62FD6, 0x7FFC4F22, +0x6C43DB2B, 0xED0060B2, 0x2B02CB03, 0xC90360B2, +0x6E03A008, 0x89073DC2, 0xE46460B2, 0xB07CC903, +0x7D016E03, 0x8BF52EE8, 0x8F043DC2, 0xD4212FE1, +0x460BD621, 0x62F10009, 0x6023622D, 0x89FFC801, +0x7F046023, 0x6EF64F26, 0x6CF66DF6, 0x6BF6000B, +0x001C3B88, 0x00203AA0, 0x002018EE, 0x00203AA8, +0x00203AB0, 0x00203AB8, 0x00203AC0, 0x0025E720, +0x00203DA0, 0x002038F8, 0x001C5968, 0x001C3B40, +0x000F8000, 0x001D4004, 0x001C3500, 0x002015E0, +0x0020160C, 0x001C5814, 0x001C59D0, 0x001C5830, +0x001C6268, 0x001C59A4, 0x001C639C, 0x001C581C, +0x001C5860, 0x00203AC8, 0x002018A2, 0x8F014411, +0x6043604B, 0x0009000B, 0x5651D52B, 0x46286052, +0x306C000B, 0x2FC62FB6, 0x2FE62FD6, 0x4F124F22, +0xBFF14F02, 0x6B036E43, 0xDD25DC24, 0x0009BFEC, +0x3C0530B8, 0x4609060A, 0x46014609, 0x020A3D65, +0x42094209, 0x32E24209, 0x4F068BF0, 0x4F264F16, +0x6DF66EF6, 0x000B6CF6, 0x2FC66BF6, 0x2FE62FD6, +0x4F124F22, 0xBFCF4F02, 0x6C036E43, 0xBFCBDD13, +0x30C80009, 0x060A3D05, 0x46094609, 0x36E24601, +0x4F068BF5, 0x4F264F16, 0x6DF66EF6, 0x6CF6000B, +0x4F222FE6, 0xE102DE0B, 0xE403E500, 0xBFB92E12, +0xE6062E52, 0xE7004618, 0x2E62E403, 0x4F262E72, +0x6EF6AFB0, 0x0009000B, 0x001C1040, 0xCCCCCCCD, +0x10624DD3, 0x001D4004, 0x2F962F86, 0x2FB62FA6, +0x2FD62FC6, 0x4F222FE6, 0xE5007F98, 0x6453E710, +0x6B534728, 0xEE1ADCBC, 0x6153655D, 0x315C4108, +0x75014108, 0x6043317C, 0x0F16665D, 0xED0060B3, +0x21B136E3, 0x81128111, 0x11D28113, 0x11D411D3, +0x74048FEA, 0xD8B167F2, 0x1871D9B1, 0x58F12872, +0x1981D1B0, 0x59F22982, 0x5DF45AF3, 0x54F65EF5, +0x21921191, 0x11A211A3, 0x11D411D5, 0x11E611E7, +0x11481149, 0xDAA855F7, 0x57F8EE00, 0x52F9DDA7, +0x64E3D6A7, 0x2A521A51, 0xD8A7D9A6, 0x2D729AD5, +0x6EED2622, 0x4D086DE3, 0x3DEC61E3, 0x4D084108, +0x3D9C31EC, 0x410860B3, 0x81D12DB1, 0x4108E050, +0x4008E7B7, 0x677C4108, 0x60B381D2, 0xE200318C, +0x81D33472, 0x1D131DD2, 0x8D01D493, 0xD4901D24, +0xB0B365D3, 0x64ED7E01, 0x8BDA34A2, 0x2FD2DA8C, +0xDD9268A2, 0x2D824829, 0x7DFC64A2, 0xD287694D, +0x6E222D92, 0x7D0C4E29, 0x68222DE2, 0x618D6AD3, +0x2A16D784, 0xD48A6D72, 0x24D2D583, 0xD6895E72, +0x517414E2, 0x1414EE00, 0xD1875876, 0x59781486, +0x1498E710, 0x65E36252, 0x26E2142A, 0xE60064E3, +0x6843644D, 0x384C4808, 0x381C4808, 0x0C866053, +0x09CE28B1, 0x819160B3, 0x0ACE6053, 0x81A26043, +0x0DCE6053, 0x81D360B3, 0x08CE6053, 0x18827401, +0x624D09CE, 0x0ACE19E3, 0x1A643273, 0x75048FE0, +0xE003D96A, 0x40186C92, 0x6D922CB1, 0x81D1DA6F, +0x6E92E050, 0x81E24008, 0x60B36192, 0x64928113, +0x1442E600, 0xD4696792, 0x689217A3, 0x1864E1FF, +0x6563E703, 0x364C4608, 0x26127501, 0x3673665D, +0xDC5B8BF8, 0x6DC2E003, 0x2DB14018, 0xD2606EC2, +0x61C281E1, 0x1112EE00, 0xE02464C2, 0x65C21423, +0x15E4D45B, 0xE58067C2, 0x68C28172, 0x818366E3, +0x666D655C, 0x76046963, 0x394C6A6D, 0x8FF83A53, +0xDB5429E2, 0x24B2DC54, 0x24C27404, 0x4F267F68, +0x6DF66EF6, 0x6BF66CF6, 0x69F66AF6, 0x68F6000B, +0x60116142, 0x8F03C803, 0xD23DE500, 0x8B063420, +0xC9036011, 0x8B068802, 0x3420D239, 0x56128B03, +0x52646513, 0x000B2422, 0x01136053, 0x2FE62FD6, +0x7FEC4F22, 0x62536E53, 0x6D43E550, 0x4508E400, +0xE101A001, 0x60435224, 0x81212211, 0x60538123, +0x56E28122, 0x8BF53620, 0x16E4D238, 0xE61464F3, +0x65E3420B, 0xE4FC65E1, 0x2E512549, 0x65F361F1, +0x2F112149, 0xD13154D1, 0xE614410B, 0x607157D1, +0x2701CB01, 0x7F141DE1, 0x6EF64F26, 0x6DF6000B, +0x2FE62FD6, 0x7FEC4F22, 0x66536E53, 0x6D43E5FC, +0x20596061, 0x2601CB01, 0x326052E2, 0x12E48B06, +0x31E051E2, 0x52D18B04, 0x1E22A002, 0x5664AFF0, +0x64F3D21E, 0x420BE614, 0x67E165E3, 0x2719E1FC, +0x67F12E71, 0x271954D1, 0x65F3D118, 0x410BE614, +0x52D12F71, 0xCB016021, 0x1DE12201, 0x4F267F14, +0x000B6EF6, 0x00006DF6, 0x00203924, 0x002034F4, +0x002034FC, 0x00203504, 0x0020352C, 0x00203910, +0x00203918, 0x00100208, 0x001017C0, 0x001E210C, +0x001C3D00, 0x00203964, 0x001000C8, 0x00117880, +0x00117780, 0x00040020, 0x0026C401, 0x00200ED6, +0x4F222FE6, 0xDE42624C, 0x42004208, 0x3E2CA005, +0xD4405252, 0xBF695624, 0x65E22E62, 0x352052E1, +0xD63D8BF6, 0x4F262622, 0x6EF6000B, 0x2FC62FB6, +0x2FE62FD6, 0xDC394F22, 0x52C1DB39, 0x362066C2, +0x6061891C, 0x8801C903, 0xDE348918, 0xBF37DD35, +0x650364E3, 0x66B28503, 0x3262620D, 0xD4328907, +0x0009BF76, 0x4D0BD431, 0xAFE60009, 0xBF3D0009, +0xD42F64E3, 0x00094D0B, 0x0009AFDF, 0x2262D22D, +0x6EF64F26, 0x6CF66DF6, 0x6BF6000B, 0x2FD62FC6, +0x4F222FE6, 0xDD29DC28, 0x6E4360C2, 0x04DE4008, +0xE614D127, 0x65E3410B, 0xD127D726, 0x55E227E2, +0x35E05254, 0x21228F04, 0x400860C2, 0x122202DE, +0x605365C2, 0x75014008, 0x0DE606DE, 0xC90F6053, +0x60632C02, 0x6EF64F26, 0x000B6DF6, 0x85436CF6, +0x650D5643, 0x622D6262, 0x35277204, 0xE1008F0C, +0x2268960C, 0xD6158B03, 0x72015261, 0xD6131621, +0x6262E101, 0x26227201, 0x6013000B, 0x000001FF, +0x00203504, 0x002034FC, 0x001C3D00, 0x0020352C, +0x002038F4, 0x002018A2, 0x002034F4, 0x00203AF0, +0x00203AF4, 0x001C3D28, 0x00203964, 0x00203924, +0x00200ED6, 0x00203968, 0x0020396C, 0x00117754, +0x2FC62FB6, 0x2FE62FD6, 0x7FF84F22, 0x6022D237, +0x8D58C803, 0xDE362F01, 0xDB37DC36, 0x66C252C1, +0x892F3620, 0xC9036061, 0x892B8801, 0xD233DD31, +0x64D3420B, 0x1F016503, 0x880160B1, 0xD2308B04, +0x64D3420B, 0x0009AFEA, 0x85615653, 0x8904C820, +0xE050D72C, 0x7201027E, 0xD22B0726, 0x6453420B, +0x89072008, 0x55F1D126, 0x64D3410B, 0xE601D727, +0x2762AFD4, 0x55F1D226, 0x64E3420B, 0xE601D125, +0x2162AFCC, 0xDD25DE24, 0xDC26DB25, 0x66D252D1, +0x89183620, 0xC9036061, 0x89148801, 0xD117D41F, +0x0009410B, 0x36E05603, 0x65038F04, 0x2B20E201, +0x2C52AFEC, 0xD712D41C, 0x0009470B, 0xE601D115, +0xAFE34618, 0x60F12162, 0x8907C804, 0x7F08D217, +0x6EF64F26, 0x6CF66DF6, 0x6BF6422B, 0x4F267F08, +0x6DF66EF6, 0x000B6CF6, 0x00006BF6, 0x001E2100, +0x00203504, 0x002034FC, 0x0020398C, 0x002014A0, +0x002014CC, 0x00203494, 0x002016BE, 0x001E212C, +0x00201530, 0x001C3D30, 0x00117880, 0x002034F4, +0x00203914, 0x00203910, 0x0020352C, 0x00200610, +0xE601D203, 0x1265D503, 0x000B2252, 0x00001266, +0x001C1010, 0x0000C34F, 0x0009000B, 0x2FD62FC6, +0x4F222FE6, 0x6D436C53, 0xEE00A004, 0x7E0164D4, +0x644CBFF2, 0x8BF93EC2, 0x6EF64F26, 0x000B6DF6, +0xE5006CF6, 0x6643A002, 0x76017501, 0x22286260, +0xAFE38BFA, 0x2FE60009, 0x75076253, 0xE1086753, +0x6043EE0A, 0x4409C90F, 0x650330E2, 0x8D014409, +0xE630E637, 0x4110365C, 0x8FF22760, 0xE00077FF, +0x000B8028, 0x000B6EF6, 0x000BE000, 0x2FE6E000, +0x7FEC4F22, 0x6E436253, 0xBFDC65F3, 0xBFD06423, +0xBFCE64E3, 0xD40364F3, 0x0009BFCB, 0x4F267F14, +0x6EF6000B, 0x00203AF8, 0xE4FDD29F, 0xD79F6122, +0x22122149, 0x74016022, 0x2202CB01, 0xD59C6622, +0x22622649, 0xC8406070, 0x60528902, 0x2502CB04, +0xE1F76452, 0x25422419, 0xE7016052, 0x2502CB40, +0xE6026052, 0x2502C9CF, 0x47186052, 0x2502CB10, +0xCB036052, 0x15622502, 0x1573000B, 0xD78ED58D, +0xD48FD28E, 0xE600E100, 0x27112511, 0xAFCB2210, +0x664C2461, 0x4600D28B, 0x6060362C, 0x000BCB10, +0x654C2600, 0x4500D287, 0x6650352C, 0x2619E1EF, +0x2560000B, 0xD284664C, 0x362C4600, 0xCB106060, +0x2600000B, 0xD280654C, 0x352C4500, 0xE1EF6650, +0x000B2619, 0x664C2560, 0x4600D27A, 0x6060362C, +0x000BCB08, 0x654C2600, 0x4500D276, 0x6650352C, +0x2619E1F7, 0x2560000B, 0xD273664C, 0x362C4600, +0xCB086060, 0x2600000B, 0xD26F654C, 0x352C4500, +0xE1F76650, 0x000B2619, 0x624C2560, 0x4200D669, +0x6020326C, 0x4021C908, 0x40214021, 0x600C000B, +0xD665624C, 0x326C4200, 0xC9086020, 0x40214021, +0x000B4021, 0xD161600C, 0x341C644C, 0x000B6240, +0xD15F602C, 0x341C644C, 0x000B6240, 0x2FE6602C, +0x6E434F22, 0xE60A645C, 0x89143467, 0x0009BFEB, +0x60EC640C, 0x8B028801, 0xA002E00F, 0x44092409, +0x624C4409, 0x3263E60A, 0xBFE28905, 0x620C644C, +0xC8806023, 0xE2008B00, 0x4F266023, 0x6EF6000B, +0xD64C4F22, 0x88016062, 0xB2578B03, 0xA0030009, +0xD2490009, 0x2260E640, 0xE200D648, 0x000B4F26, +0x4F222622, 0x6062D643, 0x8B018802, 0x0009B2A0, +0xE200D642, 0x000B4F26, 0xD53E2622, 0xE100D43E, +0x2512E701, 0x2470000B, 0xE604D23B, 0x2260000B, +0xD43B4F22, 0x410BD13B, 0xD53B0009, 0x6650E1FD, +0x2619D23A, 0x2560E700, 0x000B4F26, 0x4F222270, +0xD238D537, 0xD7386152, 0x2512611D, 0xE6FF6452, +0x2542242B, 0xD22FD435, 0x420B666D, 0xD52E2762, +0x6750E1FB, 0x4F262719, 0x2570000B, 0xD4304F22, +0x410BD128, 0xD5280009, 0x6650E7F7, 0x4F262679, +0x2560000B, 0x9425D524, 0x22496250, 0x2520000B, +0xE4BFD521, 0x22496250, 0x2520000B, 0xD2254F22, +0x600D8522, 0x89112008, 0x89458801, 0x89478803, +0x89498805, 0x894F8806, 0x89558808, 0x895B8809, +0x8961880A, 0x8967880B, 0x0009A06E, 0x0009B070, +0x600CA06B, 0x0000FF7F, 0x001E2148, 0x001E1000, +0x001E1108, 0x002039C4, 0x002039C6, 0x002039E5, +0x002039A8, 0x001E103F, 0x001E105F, 0x001E102F, +0x001E1090, 0x002039CC, 0x001E100B, 0x002039C8, +0x00203AFC, 0x002018A2, 0x001E1028, 0x002039E4, +0x001D4020, 0x98760000, 0x001C1000, 0x00203B08, +0x00203B18, 0x0020399C, 0x0009B04C, 0x600CA035, +0x0009B055, 0x600CA031, 0x6260D684, 0x8B2B2228, +0x0009B061, 0x600CA029, 0x6260D680, 0x8B232228, +0x0009B069, 0x600CA021, 0x6260D67C, 0x8B1B2228, +0x0009B0C7, 0x600CA019, 0x6260D678, 0x8B132228, +0x0009B0CD, 0x600CA011, 0x6260D674, 0x8B0B2228, +0x0009B125, 0x600CA009, 0x6260D670, 0x8B032228, +0x0009B13D, 0x600CA001, 0x4F26E000, 0x0009000B, +0xD26CD16B, 0xD56C8412, 0x4000C90F, 0xD76B012D, +0xE403D66B, 0xE20F611C, 0x2540E001, 0x25202712, +0x2602000B, 0xE601D262, 0x30668523, 0xE0008D05, +0xD663D260, 0xE0018122, 0x000B2602, 0xD25C0009, +0x600D8523, 0x89052008, 0x8B0A8801, 0x6060D65D, +0x2600CB01, 0xD457D65A, 0xE001E101, 0x000B2612, +0x000B8142, 0xD152E000, 0x8513E501, 0x640D4518, +0x66033453, 0xE0008D05, 0xD551D253, 0x2260E001, +0x000B2502, 0x4F220009, 0x8513D149, 0x6453650D, +0x62494419, 0x227D672E, 0x8801602C, 0x88028909, +0x88038910, 0x8806891A, 0x88078935, 0xA04C893B, +0xD5460009, 0x6652D746, 0x2762D446, 0x622C6261, +0x2421A038, 0x2228625C, 0xD4438B3F, 0x6642D540, +0x2562D440, 0x24018561, 0x6203A02C, 0x2008605C, +0x88108907, 0x88208908, 0x88308909, 0xA02C890A, +0xD23A0009, 0x6222A008, 0xA005D239, 0xD2396222, +0x6222A002, 0x6262D638, 0xD432D531, 0x66212522, +0xA00F626C, 0xD6352421, 0x6261D52D, 0x622CD42D, +0xA0072562, 0xD6322421, 0x8561D529, 0x2562D429, +0x62032401, 0x662D8515, 0x3617610D, 0x65038F01, +0xB0CB2451, 0xA0010009, 0xE000E001, 0x000B4F26, +0xD6190009, 0xD427E101, 0x65412610, 0xD118D717, +0xE20F655D, 0x2752E001, 0x000B2620, 0x2FE62102, +0xD20F4F22, 0x640C8523, 0x8B082448, 0xD511D61D, +0x2621E200, 0x940F8451, 0xA0482049, 0xDE0D8051, +0xC84060E0, 0xE2018D32, 0x89443427, 0xD216D615, +0x2641420B, 0x0009A030, 0x0000FF7F, 0x002039E5, +0x0020399C, 0x002039A8, 0x001E1100, 0x001E100C, +0x002039C8, 0x001E1000, 0x001E1001, 0x002039D0, +0x002039B0, 0x002039B4, 0x002039B8, 0x002039D4, +0x002039D8, 0x002039DC, 0x002039E0, 0x00203E04, +0x00203E0E, 0x002039C2, 0x00202886, 0x89123427, +0xD294D693, 0x2641420B, 0xCB8084E1, 0x80E1B0F5, +0xD69160E0, 0x2E00CB04, 0xC93F6060, 0xD68F2600, +0xA001E001, 0xE0002602, 0x000B4F26, 0xD68C6EF6, +0xC8806060, 0xD2868919, 0x88016021, 0xD2898B15, +0x8524E501, 0x89103056, 0xE203D187, 0x2120D487, +0xE00B6541, 0x0656655D, 0xE40FD585, 0x2140E702, +0xD77E2571, 0x000BE001, 0x000B2702, 0x2FE6E000, +0xDE804F22, 0xC88084E1, 0xD57A892C, 0x20088554, +0x61038F28, 0x8553D77C, 0x64036672, 0x8566650C, +0x3520620C, 0xD6798B1E, 0x651CD774, 0x2651644C, +0x60E02741, 0x8904C840, 0x420BD275, 0xA0030009, +0xD2680009, 0x0009420B, 0x0009B09F, 0xE201D167, +0x60E02122, 0xCB04D464, 0x60402E00, 0x2400C93F, +0x6023A001, 0x4F26E000, 0x6EF6000B, 0x2FB62FA6, +0x2FD62FC6, 0xDA622FE6, 0x66A1E240, 0x3622DC5E, +0x62638900, 0x6ED36D2C, 0x4E2136D8, 0x4E212A61, +0xDB61D460, 0xE700A00F, 0x770162B2, 0x71026123, +0x66212B12, 0x71026213, 0x61212B12, 0x651D666D, +0x356C4528, 0x627C2452, 0x8BED32E3, 0xC90360D3, +0x8B108803, 0x617367B2, 0x2B127102, 0x71026E13, +0x2B126571, 0x655D6DE1, 0x422862DD, 0x325CE107, +0xA00C2C10, 0x88022422, 0xA0038B01, 0x8801E203, +0xE2018B05, 0x66B22C20, 0x655D6561, 0xE60F2452, +0x67A12C60, 0x8B052778, 0xDD38DC44, 0xEB01EA00, +0x2DB22CA2, 0x6DF66EF6, 0x6BF66CF6, 0x6AF6000B, +0x2FE62FD6, 0xE240DD36, 0x362266D1, 0x62638900, +0x3678672C, 0x7703DE38, 0x47212D61, 0x64E2D635, +0xA00E4721, 0x6562E100, 0x62537101, 0x74012450, +0x24204219, 0x45297401, 0x74012450, 0x24504519, +0x621C7401, 0x8BEE3273, 0x66E24200, 0x420061D1, +0x2118362C, 0x2E628F06, 0xDD1CD728, 0xE501E400, +0x2D522742, 0x000B6EF6, 0x2FD66DF6, 0x4F222FE6, +0xED0AEE01, 0x64E3BC85, 0xBC8A64E3, 0x62EC7E01, +0x8BF732D7, 0xBC8DEE01, 0x64E364E3, 0x7E01BC92, +0x32D762EC, 0x4F268BF7, 0x000B6EF6, 0xD1186DF6, +0xD418920D, 0x72122122, 0x2422D617, 0xD7177204, +0x72202622, 0x2722D116, 0x000B7230, 0x137A2122, +0x002039C2, 0x00202992, 0x001E1015, 0x002039C8, +0x001E1001, 0x0020399C, 0x001E1100, 0x002039C6, +0x002039B4, 0x001E1000, 0x002039B8, 0x002039C4, +0x00202886, 0x001E100C, 0x002039B0, 0x002039CC, +0x002039D0, 0x002039D4, 0x002039D8, 0x002039DC, +0x002039E0, 0x4F222FE6, 0xD6707FFC, 0x88016060, +0xE2018951, 0x2620BFBB, 0xD56ED16D, 0xDE6E6010, +0x64E36552, 0x7402C840, 0x8D22D16C, 0xD26C7502, +0xE601D76C, 0xE7042722, 0x76016255, 0x626C2421, +0x8FF93273, 0xD4637402, 0x6242E601, 0x640D8528, +0x67494419, 0x275D657E, 0x81E4607C, 0xE417D562, +0x67557601, 0x3243626C, 0x8FF92171, 0xA0207102, +0xD25E0009, 0xE601D75B, 0xE7042722, 0x76016255, +0x626C2421, 0x8FF93273, 0xD4527402, 0x6242E601, +0x640D8528, 0x67494419, 0x275D657E, 0x81E4607C, +0xE417D553, 0x67557601, 0x3243626C, 0x8FF92171, +0x92897102, 0xD2462E21, 0x5E23D74E, 0x64F22FE2, +0x604365F2, 0x2700C980, 0xC9606043, 0x80716103, +0xC9036043, 0x80724519, 0x65F2605C, 0x817266F2, +0x46194629, 0x606C4529, 0x4018645C, 0x8173304C, +0x21185E23, 0x64F22FE2, 0x6E4C62F2, 0x602C4219, +0x66F262F2, 0x46294018, 0x461930EC, 0x42298174, +0x652C606C, 0x305C4018, 0x81758F07, 0x0009BC96, +0x2228620C, 0xA00A8908, 0x60130009, 0x8B038840, +0x0009B009, 0x0009A003, 0xE202D62F, 0x7F042622, +0x000B4F26, 0x4F226EF6, 0x8552D52A, 0x8830600D, +0x88318903, 0xA0348923, 0x85550009, 0xD428D727, +0x85532701, 0x610DD627, 0x24124118, 0x460BD426, +0xD7230009, 0xD226D425, 0x6572420B, 0xE230D120, +0x42286712, 0x2729E620, 0x37604628, 0xD6218B03, +0xA016E200, 0xD61F2622, 0xA012E202, 0xD1182622, +0x6212E530, 0xE6204528, 0x46282259, 0x89083260, +0xD41AD119, 0xE601D513, 0x2160450B, 0x472BD718, +0x4F264F26, 0x0009000B, 0x0000060A, 0x002039E4, +0x001E1000, 0x002039D0, 0x00203E04, 0x00203E10, +0x00203DA8, 0x002039B8, 0x00203DD8, 0x00203DD6, +0x00203DAA, 0x0020399C, 0x002039C8, 0x002039B4, +0x002039B0, 0x002018A2, 0x00203B24, 0x00203B28, +0x002018EE, 0x002039CC, 0x001E100B, 0x00203B3C, +0x00114004, 0x4F222FE6, 0xDE967FFC, 0x200884E9, +0x2F008D06, 0xD695D494, 0x0009460B, 0x64F0B19A, +0x6620D293, 0x89022668, 0xC9BF60E0, 0x7F042E00, +0x000B4F26, 0x000B6EF6, 0x2FE60009, 0xDE8D4F22, +0x60E0D68D, 0xCBC0D48D, 0x62602E00, 0xC803602C, +0x40218904, 0x70014021, 0x6603A002, 0x66034009, +0xD687616D, 0xE500A004, 0x75016262, 0x74042422, +0x3213625D, 0xD2838BF8, 0x0009420B, 0xC9BF84E2, +0x4F2680E2, 0x6EF6000B, 0x2FE62FD6, 0x7FFC4F22, +0x6260D67D, 0x89442228, 0xD572E100, 0x60502610, +0xCB40D47A, 0x2500440B, 0x8D052008, 0x62E06E03, +0x7104612C, 0x2F11A006, 0xD475D66D, 0xDD756760, +0x657C4D0B, 0xE23C6D1D, 0x8B033D27, 0xD267D472, +0x0009420B, 0x4D214D21, 0xA005D770, 0x66E6E400, +0x357C4508, 0x74012562, 0x35D3654D, 0xD76C8BF7, +0x6172E003, 0x81114018, 0x6E7260F1, 0x81E2700C, +0xD4686172, 0xDD688113, 0x4D0BDE68, 0xE2016572, +0xD4672E22, 0x420BD255, 0xD6560009, 0xC93F6060, +0x7F042600, 0x6EF64F26, 0x6DF6000B, 0x2FC62FB6, +0x2FE62FD6, 0xD25F4F22, 0x6B436E73, 0x420B6C53, +0x20086D63, 0x64038D1C, 0xE50ED149, 0x32526210, +0x60C38916, 0x804124B0, 0x814160D3, 0xA007E500, +0x655D61BC, 0x00EC6053, 0x364C6653, 0x80647501, +0x3213625D, 0xD63B8BF5, 0xC9BF6060, 0x2600A008, +0xD23AD44D, 0x6EF64F26, 0x6CF66DF6, 0x6BF6422B, +0x6EF64F26, 0x6CF66DF6, 0x6BF6000B, 0x7FC44F22, +0x720262F3, 0x22512F41, 0x45297202, 0x60632251, +0xE5C4E682, 0x67F38121, 0x655C666C, 0xE408BFB6, +0x4F267F3C, 0x0009000B, 0x2F962F86, 0x2FB62FA6, +0x2FD62FC6, 0x4F222FE6, 0xE1007FC4, 0x6513ECFF, +0x6B136CCD, 0xDE36D735, 0xEDFF64F3, 0xD835EA04, +0x6053655C, 0x027D4000, 0x32C0622D, 0x66038D0D, +0x09ED6063, 0x2491027D, 0x24217402, 0x698202ED, +0x3928622D, 0x74022892, 0x75017104, 0x6063625C, +0x07D532A2, 0x0EB58FE4, 0x2448641C, 0xE6808905, +0x67F3E5C5, 0xBF79666C, 0x7F3C655C, 0x6EF64F26, +0x6CF66DF6, 0x6AF66BF6, 0x000B69F6, 0xD11E68F6, +0x6012D21E, 0xCB20E405, 0x2102E500, 0x000B2242, +0x00002252, 0x001E1017, 0x00203B40, 0x002018A2, +0x0020390E, 0x001E1015, 0x001E10BF, 0x00117800, +0x001E10FC, 0x00200610, 0x00203914, 0x00202AEA, +0x00203B44, 0x002018EE, 0x00203B60, 0x0011788C, +0x00203910, 0x002034F4, 0x00201530, 0x001E2130, +0x00203B68, 0x00202AAC, 0x00203B6C, 0x00203974, +0x0020397C, 0x00203DA4, 0x001C3500, 0x001D4004, +0xD564D163, 0xE400D764, 0x2142E20F, 0x17411154, +0xD5622722, 0x9669D762, 0x15412572, 0x96661562, +0xE6011565, 0xD55F1165, 0x666CE6F8, 0x25422542, +0x25422542, 0x25422542, 0x25622542, 0x7601E727, +0x67632572, 0x25627797, 0xE7042572, 0x2572E248, +0xE2192522, 0xE2702522, 0x25422542, 0x25422542, +0x25222542, 0x2522E20C, 0x25422542, 0x25422542, +0x25422542, 0x25422542, 0x000B154A, 0xE2081145, +0x0009422B, 0x2FE62FD6, 0x7FFC4F22, 0xC8206043, +0x6E438D02, 0x0009BE67, 0xC81060E3, 0xBE648901, +0x60E30009, 0x8901C840, 0x0009BE86, 0xC80160E3, +0xDD3D8938, 0xC80260D0, 0x2F008D03, 0x460BD63B, +0x60F00009, 0x8902C804, 0x460BD639, 0x62F00009, +0xC8806023, 0x60D08902, 0x2D00C97F, 0xC8016023, +0xD6348906, 0x0009460B, 0x0009A007, 0x51630601, +0x8902C808, 0x460BD630, 0x60F00009, 0x8902C810, +0x420BD22E, 0xD52E0009, 0x88026052, 0xD22D8B03, +0xA005E604, 0x88012260, 0xD22A8B02, 0x2260E601, +0x2522E200, 0xC88060E3, 0xD227892D, 0x60E36E20, +0x8902C880, 0x420BD225, 0x60E30009, 0x8902C840, +0x420BD223, 0x60E30009, 0x8902C802, 0x420BD221, +0x60E30009, 0x890DC804, 0xDD20D11F, 0x0009410B, +0x0009BF0D, 0x0009BF4C, 0xD51ED41D, 0x2470E708, +0x25D2BF85, 0xC80860E3, 0xD21B8905, 0x4F267F04, +0x422B6EF6, 0x7F046DF6, 0x6EF64F26, 0x6DF6000B, +0x001C581C, 0xA000A000, 0x001D0100, 0x001D4000, +0x00040021, 0x001C589C, 0x001E1021, 0x00201A90, +0x00201AB2, 0x00202114, 0x00201ACA, 0x00201AD8, +0x002039C8, 0x001E100B, 0x001E1028, 0x00201B44, +0x00201B50, 0x00201AE0, 0x00201AFE, 0x12345678, +0x001E1000, 0x0010F100, 0x00201B2C, 0x644CD6A7, +0x000B346C, 0xD6A62450, 0x346C644C, 0x2450000B, +0x644CD6A4, 0x000B346C, 0x625C2450, 0x4208616D, +0x42084119, 0x42006019, 0x670E614C, 0xD49E321C, +0x4200207D, 0x324CC90F, 0x2200000B, 0x4208625C, +0x42004208, 0x324C644C, 0x4200D498, 0x000B324C, +0x2FE62260, 0x614C4F12, 0x4100D493, 0x6710314C, +0xE29F666D, 0x27294619, 0x6E536269, 0x672E6573, +0x4221227D, 0x42214221, 0x7601662C, 0xE4014608, +0x34E84608, 0x644C4600, 0x071A0467, 0x2150257B, +0x000B4F16, 0x4F226EF6, 0xD2857FE8, 0x88016021, +0xD2848B7B, 0x26686621, 0xD2838B77, 0x26686621, +0xE50F8B73, 0xE401BFA2, 0xBFA4E501, 0xE586E400, +0xE400655C, 0x2F50BFA4, 0xBFA1E401, 0xE602E506, +0x60634618, 0x81F2E401, 0x6543BF9F, 0xE40185F2, +0xBFAB6543, 0x85F26603, 0x6543E401, 0x6603BFB1, +0xE40265F0, 0x6053756C, 0x80F8BF80, 0xBF82E402, +0x84F8E512, 0x7090E402, 0x6503BF82, 0x4618E602, +0x81F66063, 0xBF80E402, 0x85F6E500, 0x6603E402, +0xE500BF8C, 0xE40285F6, 0xBF926603, 0xE5FEE500, +0xE010655C, 0xBF61E403, 0xE5130F54, 0xE40EBF63, +0x05FCE010, 0xBF63E40E, 0xE5007585, 0xBF64E403, +0xE500E640, 0xBF71E403, 0xE500E640, 0xBF78E403, +0xE5FFE640, 0xE014655C, 0xBF47E404, 0xE40F0F54, +0xE504BF49, 0x05FCE014, 0xBF49E40F, 0xE5017584, +0xBF4AE640, 0xE501E404, 0xBF57E640, 0xE501E404, +0xE404E640, 0xAF5C7F18, 0x7F184F26, 0x000B4F26, +0x4F220009, 0xD2427FF0, 0x88016021, 0xD2418B71, +0x26686621, 0xD2408B6D, 0x26686621, 0xE50F8B69, +0xE401BF1C, 0xBF1EE501, 0xE586E400, 0xE400655C, +0x2F50BF1E, 0xBF1BE401, 0xE401E506, 0xBF1C6543, +0xE401E640, 0xBF296543, 0xE401E640, 0xBF306543, +0x65F0E640, 0x756CE402, 0xBEFF6053, 0xE40280F4, +0xE512BF01, 0xE40284F4, 0xBF017090, 0xE6406503, +0xBF02E402, 0xE640E500, 0xBF0FE402, 0xE640E500, +0xBF16E402, 0xE5FEE500, 0x6053655C, 0xBEE5E403, +0xE51380F8, 0xE40EBEE7, 0xE40E84F8, 0xBEE77085, +0xE5006503, 0xBEE8E640, 0xE500E403, 0xBEF5E640, +0xE500E403, 0xBEFCE640, 0xE5FFE403, 0x6053655C, +0xBECBE404, 0xE40F80FC, 0xE504BECD, 0xE40F84FC, +0xBECD7083, 0xE5016503, 0xBECEE640, 0xE501E404, +0xBEDBE640, 0xE501E404, 0xE404E640, 0xAEE07F10, +0x7F104F26, 0x000B4F26, 0x00000009, 0x001E102F, +0x001E1080, 0x001E1090, 0x001E103F, 0x001E103E, +0x002039C2, 0x002039C4, 0x002039C6, 0xD21DD11C, +0x66206010, 0x676C7001, 0x3700C90F, 0xE5008D13, +0x67106210, 0x7701622C, 0x64232170, 0xD6166010, +0x44084408, 0x3428C90F, 0x62602100, 0x7201D513, +0x44082620, 0x000B354C, 0xD10F6053, 0x25586510, +0xE6008D13, 0xD60DD40B, 0x655C6540, 0x47086753, +0x37584708, 0x47086540, 0x24507501, 0x367C6040, +0x2400C90F, 0x72FF6210, 0x000B2120, 0x00006063, +0x0020390D, 0x0020390C, 0x0020390E, 0x00203534, +0x7FFC4F22, 0xE680D19F, 0x666C6212, 0xD29E2F22, +0x67F36563, 0x420B7542, 0x7F04E404, 0x000B4F26, +0xE6800009, 0xD298666C, 0xE7006563, 0x422B7540, +0xE6806473, 0xD294666C, 0xE7006563, 0x422B7543, +0x2F866473, 0x2FA62F96, 0x2FC62FB6, 0x2FE62FD6, +0x7FCC4F22, 0xDC8ED28D, 0x72011F21, 0xDB8D1F22, +0xD18EDE8D, 0x66125211, 0x8B013620, 0x0009A0E5, +0xC9036061, 0x8B018801, 0x0009A0DF, 0xD288D487, +0xED84420B, 0x2F025503, 0x30D0845C, 0xA0B88901, +0xD1840009, 0x626C6610, 0x88016023, 0xD1828B68, +0x62101FC3, 0x895B2228, 0xE003D480, 0x40186742, +0x68421772, 0xD57EE900, 0x81816DB3, 0x7D042190, +0x67D26AB2, 0x64E26852, 0x1F491F57, 0x740464E3, +0x1FA46542, 0x65431F5A, 0x625275F8, 0x1F761FD5, +0x6D531F2B, 0xDA74D773, 0x7D94D274, 0x68D21F88, +0x6AA26972, 0xD1726022, 0x2202CB20, 0xE1401F1C, +0x7601E600, 0x3213626D, 0x56F48BFB, 0x52F651F5, +0x21222B62, 0x52F851F7, 0x212256F9, 0x2E6251FA, +0x51FB2412, 0x2D822512, 0xD9662792, 0x29A2DD5F, +0x6AD2D965, 0xD9646892, 0x68D21A84, 0x6081DA63, +0x2801CB01, 0xD86266D2, 0x2A622962, 0xED015AFC, +0x2AD2480B, 0x2AD24D18, 0x62D2DD5E, 0x2D227201, +0xD15056F3, 0xE2026062, 0x2602CB01, 0x2120A03D, +0x8B3A2228, 0xE401DD58, 0x2140E600, 0xE01C2D62, +0xC801005C, 0xD4558B0A, 0xE600D755, 0xED7D2472, +0x626C7601, 0x8BFB32D3, 0x24D2DD52, 0xE2FE68C2, +0x2C822829, 0x095CE01E, 0xE01F5DF1, 0x0A5C2D90, +0x751051F2, 0xED0621A0, 0xD74BE600, 0x8456D44B, +0x27007601, 0x696C6854, 0x248039D3, 0x8FF67401, +0xDA477701, 0x2A10E194, 0xE2007A01, 0x7A0F2A20, +0xD130E805, 0x66102A80, 0x6023626C, 0x89088801, +0xD240D42A, 0x420B65F2, 0xD131ED01, 0xAF304D18, +0x65F221D2, 0x8553D43C, 0x620D6642, 0x89073262, +0xD13BD43A, 0x0009410B, 0xE601D73A, 0x2762AF1A, +0xD134D41E, 0x410B65F2, 0xD125ED01, 0xD637D436, +0x460B4D18, 0xAF0D21D2, 0x7F340009, 0x6EF64F26, +0x6CF66DF6, 0x6AF66BF6, 0x000B69F6, 0x4F2268F6, +0x85467FF4, 0x2F01E681, 0x666C8547, 0x854881F1, +0x81F2D209, 0x67F38542, 0x854381F3, 0x81F4E40C, +0x65636053, 0x420B81F5, 0x7F0C7540, 0x000B4F26, +0x00000009, 0x001C3D9C, 0x0020245C, 0x0011779A, +0x001C36F8, 0x001C3B9C, 0x001C3704, 0x0020352C, +0x002014A0, 0x0020391D, 0x0020391C, 0x00203918, +0x001C3D98, 0x001C3BB4, 0x001C5960, 0x001C3500, +0x001C3D30, 0x001C8960, 0x00203504, 0x001C3D00, +0x0020160C, 0x00117730, 0x00203920, 0x001C582C, +0x2000A000, 0x0000A000, 0x0011778C, 0x00117792, +0x00117788, 0x002014CC, 0x002038F4, 0x002034F4, +0x00201530, 0x001E2130, 0x00203D84, 0x002018A2, +0x2F962F86, 0x2FB62FA6, 0x2FD62FC6, 0x4F222FE6, +0xD19B7FEC, 0x2F12E000, 0x6103D49A, 0x1F4281F2, +0xDD9ADA99, 0xD69A6813, 0xE0014808, 0x460BDE99, +0x38EC4800, 0x65A21F03, 0x352052A1, 0xA23E8B01, +0x60510009, 0x8801C903, 0xA2388B01, 0x52530009, +0x32E0DE91, 0xD9918B10, 0x64A3490B, 0x4B0BDB90, +0xDE906403, 0xD791D690, 0xEC01D591, 0x2E02E100, +0x271026C0, 0x2502AFDF, 0xC8018551, 0xA1578B01, +0x62510009, 0x4200622D, 0x5E53366A, 0x85E2226D, +0xC903642C, 0x85E36603, 0x6053650D, 0x40214021, +0x4500C93F, 0x322A6703, 0x6053252D, 0xC901D17F, +0x60106C03, 0x8801D97F, 0xDB7F8B05, 0x2120E200, +0xCB0160B2, 0xD17D2B02, 0x88016011, 0x65A28B0A, +0x8D042448, 0x9B9E6251, 0xA00322B9, 0x919B2521, +0x2521221B, 0x37B3EB10, 0x2448895E, 0xD4738B07, +0x22286241, 0x60638903, 0xA05781F8, 0xD5706473, +0x46084608, 0x85E26273, 0x46006B50, 0x362C4200, +0x2BB8C910, 0x8F1F6463, 0x26686603, 0xD2698911, +0x062D6043, 0x4119616D, 0x6B0E6019, 0x81F820BD, +0x880160C3, 0x646C8F2C, 0x880F6073, 0xA0278B1B, +0xD2610009, 0x052D6043, 0x4119615D, 0x670E6019, +0x645C207D, 0x81F8A01C, 0x890F2668, 0x6043D25B, +0x6B5D052D, 0x60B94B19, 0x201D610E, 0x60C381F8, +0x8F0D8801, 0x6473645C, 0xEC00A00A, 0x6043D254, +0x625D052D, 0x60294219, 0x207D670E, 0x81F8645C, +0x880285F8, 0x85E1890A, 0x8D07C820, 0xE6DC6203, +0x60232269, 0x81E1A002, 0x644CE4FF, 0x6210D149, +0x89012228, 0x644CE4FF, 0x654DEBFF, 0x35B06BBC, +0xDB368B2B, 0x64A34B0B, 0x410BD135, 0x54036403, +0x85446E03, 0xC948DB40, 0xDC408808, 0xBEAE8B01, +0x64B3E502, 0x65E34C0B, 0xDB3DEC01, 0xD13D2DC2, +0x621260B2, 0x72017001, 0x21228805, 0x2B028F08, +0x666CE680, 0x6563D238, 0x7549E700, 0x6473420B, +0xA030D436, 0x7FFF0009, 0x85E28000, 0x20B9EBFC, +0x610381E2, 0x942A85E3, 0x62032049, 0x450885F8, +0x81E2201B, 0xC90160C3, 0x40084018, 0x40084008, +0x4000225B, 0x6023220B, 0x85E481E3, 0x4118E108, +0x81E4201B, 0xE40262A2, 0x20B98521, 0x67A28121, +0xCB016071, 0x85F82701, 0x89033042, 0xECE785E2, +0x81E220C9, 0x490BD41E, 0xA03B0009, 0x7E030009, +0x001C3D30, 0x00203D90, 0x00203504, 0x001E212C, +0x002033E8, 0x001C3D00, 0x00117780, 0x002014A0, +0x0020166C, 0x0011770C, 0x0020391C, 0x0020391D, +0x00203918, 0x002018A2, 0x001C36F8, 0x00203990, +0x00203DA0, 0x00203B84, 0x00203C04, 0x00203C84, +0x00203D04, 0x00203908, 0x002034FC, 0x002014CC, +0x00203994, 0x00203998, 0x0020245C, 0x00203D88, +0x00203D8C, 0x602262F2, 0x40094019, 0xC90F4009, +0x8B0B880A, 0x60E2DE8C, 0x40094019, 0xC90F4009, +0x8B038808, 0xCB0160A2, 0x2802A006, 0x65E2DE87, +0x2E527501, 0x286266A2, 0x52F366F2, 0x2622AE83, +0xD2838551, 0xDE83C802, 0xA0958B01, 0x420B0009, +0x4E0B64A3, 0x5E036403, 0x85E46503, 0x4918E908, +0xD77D209B, 0xE04C81E4, 0xDC7C0B7E, 0x7B01D97C, +0x61C207B6, 0x71016690, 0x8D062668, 0xD4792C12, +0x420BD279, 0xA070EB01, 0x62512DB2, 0x4B18EB0F, +0x22B9E102, 0x32104118, 0x85518B0F, 0x2029E2FC, +0x60518151, 0xCB0172E0, 0x85E12501, 0x202994A3, +0x85E481E1, 0xA0522049, 0x675181E4, 0x4719677D, +0x667E6779, 0x7701276D, 0x6903607C, 0x88014918, +0x25918F3E, 0x6B12D161, 0x21B27B01, 0x660D85E3, +0x40216063, 0xC93F4021, 0x6C034600, 0x262D322A, +0xC8016063, 0xDB5ED15D, 0x967D8901, 0xE6002C6B, +0x666C67CD, 0x40006063, 0x622D021D, 0x8D0E3270, +0x60436403, 0xE9FF021D, 0x8B013290, 0x01C5A007, +0x626C7601, 0x3292E904, 0x646C8BEB, 0x60434400, +0xD15004BD, 0x0B457401, 0x669D6911, 0x89073670, +0x602D6211, 0x890388FF, 0xE201DB4B, 0x2B2021C1, +0xECFC8551, 0x815120C9, 0xCB016051, 0xDC472501, +0x64A34C0B, 0x51F366F2, 0x85EF2612, 0x54F2D244, +0x650D420B, 0x0009ADE7, 0xE500DC42, 0x420B2C52, +0x4E0B64A3, 0x54036403, 0x85446E03, 0x6703E908, +0x65034918, 0x27998541, 0xDB323790, 0x8F0BD932, +0x6013610D, 0x8B07C820, 0xC9486053, 0x8B038808, +0xE501BD4D, 0x0009A005, 0x2128D233, 0xBD468901, +0x64B3E500, 0x490B65E3, 0xADBCEC01, 0x85F22DC2, +0x7001EE04, 0x31E7610D, 0x8D0281F2, 0xADA97A08, +0x7F140009, 0x6EF64F26, 0x6CF66DF6, 0x6AF66BF6, +0x000B69F6, 0xF7FF68F6, 0x2FE68000, 0xD2234F22, +0x60E36E22, 0x8D02C840, 0xBBF922E2, 0xE2400009, +0x2E284218, 0xBC048901, 0x60E30009, 0x8905C810, +0xD21CD41B, 0x0009420B, 0x0009BC03, 0xC80560E3, +0xBD6D8901, 0x60E30009, 0x8902C802, 0xAC004F26, +0x4F266EF6, 0x6EF6000B, 0x001C3D3C, 0x00117760, +0x002014A0, 0x0020166C, 0x00203494, 0x00203DA4, +0x00203908, 0x002034FC, 0x002014CC, 0x00203974, +0x0020397C, 0x00203970, 0x00203972, 0x00201530, +0x002018EE, 0x00203994, 0x00008000, 0x001C3510, +0x00203D98, 0x002018A2, 0x080A0C0E, 0x00020406, +0x1A1C1E20, 0x12141618, 0x2E303234, 0x26282A2C, +0x3A3C3E40, 0x6C625648, 0x41112F26, 0xE2208F18, +0x890B3123, 0x321CD204, 0xD1026220, 0x412B312C, +0x00090009, 0x00203412, 0x002033C8, 0x000BE000, +0x400062F6, 0x40004000, 0x40004000, 0x40004000, +0x62F6000B, 0x40004000, 0x40004000, 0x40004000, +0x40184000, 0x62F6000B, 0x40004000, 0x40004000, +0x40004000, 0x40284000, 0x62F6000B, 0x40004000, +0x40184000, 0x000B4028, 0xC90F62F6, 0x40054005, +0x40054005, 0x62F6000B, 0x4005C907, 0x40054005, +0x62F6000B, 0x4005C903, 0x000B4005, 0xC90162F6, +0x000B4005, 0x000062F6, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x544F0D0A, 0x46205355, 0x00003A57, +0x206C754A, 0x32203120, 0x20383030, 0x323A3132, +0x34333A38, 0x00000000, 0x00000D0A, 0x00000043, +0x42707372, 0x3D206675, 0x554E203D, 0x202C4C4C, +0x6E49677A, 0x4E497274, 0x6D754E51, 0x0000003D, +0x61766E49, 0x2064696C, 0x72657375, 0x20726F20, +0x2079656B, 0x00214449, 0x52504545, 0x57204D4F, +0x65746972, 0x6461202C, 0x003D7264, 0x6C617620, +0x0000003D, 0x00000A0D, 0x435F4D5A, 0x465F444D, +0x4C445F57, 0x494E495F, 0x00000054, 0x6E6B6E55, +0x206E776F, 0x6D6D6F63, 0x3D646E61, 0x00000000, +0x203A3051, 0x00000020, 0x203A3151, 0x00000020, +0x203A3251, 0x00000020, 0x203A3351, 0x00000020, +0x203A3451, 0x00000020, 0x2B434741, 0x73696F4E, +0x61432065, 0x7262696C, 0x6F697461, 0x6166206E, +0x6F206C69, 0x6974206E, 0x0D0A656D, 0x00000000, +0x00000072, 0x00205220, 0x00000D0A, 0x62735576, +0x7473725F, 0x00000A0D, 0x62735576, 0x7375735F, +0x646E6570, 0x00000A0D, 0x62735576, 0x7365725F, +0x000A0D6D, 0x00000044, 0x44387570, 0x72637365, +0x6F747069, 0x3D584572, 0x00000000, 0x00000047, +0x00000042, 0x72746E49, 0x6D652051, 0x2C797470, +0x49677A20, 0x4972746E, 0x754E514E, 0x00003D6D, +0x654C7245, 0x0000006E, 0x00000049, 0x20746F4E, +0x756F6E65, 0x49206867, 0x4220514E, 0x0A0D6675, +0x00000000, 0x000000FF, 0x00020001, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x010E010D, 0x00020003, 0x01090108, +0x0002010A, 0x02000003, 0x02020201, 0x02040203, +0x02060205, 0x02020200, 0x02040203, 0x020C020B, +0x020E020D, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x000000FF, 0x00020001, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x010E010D, 0x00020003, 0x01090108, +0x0002010A, 0x00030003, 0x02020201, 0x02040203, +0x02060205, 0x02020200, 0x02040203, 0x020C020B, +0x020E020D, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x010E010D, 0x00FF010F, 0x01090108, +0x010B010A, 0x0200010F, 0x02020201, 0x02040203, +0x02060205, 0x02020200, 0x02040203, 0x020C020B, +0x020E020D, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x010E010D, 0x00FF010F, 0x01090108, +0x010B010A, 0x010F010F, 0x02020201, 0x02040203, +0x02060205, 0x02020200, 0x02040203, 0x020C020B, +0x020E020D, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00205220, 0x00000046, 0x00000059, +0x73204142, 0x003D7165, 0x49544120, 0x0000204D, +0x00000000, 0x00000000, 0x002E0209, 0x80000101, +0x000409FA, 0x00FF0400, 0x05070000, 0x02000201, +0x82050700, 0x00020002, 0x03830507, 0x07010040, +0x40030405, 0x02090100, 0x0101002E, 0x09FA8000, +0x04000004, 0x000000FF, 0x02010507, 0x07000040, +0x40028205, 0x05070000, 0x00400383, 0x04050701, +0x00004002, 0x00000000, 0x00000000, 0x07090000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +const u32_t zcFwImageSize=15936; --- linux-2.6.28.orig/drivers/staging/otus/hal/hpDKfwu.c +++ linux-2.6.28/drivers/staging/otus/hal/hpDKfwu.c @@ -0,0 +1,832 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "../80211core/cprecomp.h" + +const u32_t zcDKFwImage[] = { +0x0009000B, 0x4F222FE6, 0xDE3E7FFC, 0xE114D73E, +0x1E13D43E, 0x1E4C470B, 0x0009B017, 0x956EE600, +0xC84060E2, 0x2F028F03, 0x8FF93652, 0xD4387601, +0x4E0BDE38, 0xD4380009, 0x00094E0B, 0x4E0BD437, +0x7F040009, 0xA0364F26, 0x4F226EF6, 0x410BD134, +0xD4340009, 0x0009440B, 0x450BD533, 0xD7330009, +0xD233E1FF, 0x2712611D, 0xD4325029, 0xE1FFCB01, +0x1209E501, 0x12112212, 0xD52F2452, 0xD22F9740, +0xE7002572, 0xD42FD12E, 0x2270D62F, 0x2172E201, +0x26202420, 0xE4FFD62D, 0xE6002641, 0xE104D52C, +0x6063666D, 0x626D7601, 0x32124000, 0x05458FF8, +0x000B4F26, 0xEAC80009, 0xDB266AAC, 0xDD27DC26, +0xD828DE27, 0x4C0BE901, 0x4D0B0009, 0x4E0B0009, +0x60B20009, 0x89078801, 0x6242D423, 0x890332A6, +0x6050D522, 0x8BEE8801, 0x2B92D41F, 0x26686642, +0x480B89E9, 0xD51D0009, 0xAFE4E200, 0x27102520, +0x00000FA0, 0x001C001C, 0x00200ED4, 0x0000B38E, +0x00202F90, 0x00201356, 0x00202F9C, 0x00202FB4, +0x00201314, 0x00201412, 0x00200EF8, 0x001C3510, +0x001C3624, 0x001E212C, 0x00202F00, 0x00202A9C, +0x00202F08, 0x00202F14, 0x00202F20, 0x00202F22, +0x00202F26, 0x001C1028, 0x00201220, 0x0020294C, +0x00201D10, 0x00201EC8, 0x00203220, 0x00202F24, +0x2FB62F96, 0x2FD62FC6, 0x4F222FE6, 0xDE947F80, +0x61E0E024, 0x0F14D493, 0x710161E3, 0xD7926210, +0x470BE028, 0xD5910F24, 0x0009450B, 0x6D032008, +0x1F0B8F11, 0xD48FDC8E, 0xDD8F67C0, 0x657C4D0B, +0xDD8FD18E, 0x6B9C6910, 0x420862B3, 0x32B84208, +0x3D2C4208, 0xE0281FDB, 0xE58004FC, 0x604C66E2, +0x3050655C, 0x2D628F13, 0x01FCE024, 0x641CE500, +0x625DDE84, 0x8B013243, 0x0009A39E, 0x6753655D, +0x607037EC, 0x39DC6953, 0xAFF27501, 0x20088094, +0xE0248B13, 0xE50001FC, 0xA009DE7A, 0x655D641C, +0x32EC6253, 0x6C536B22, 0x3CDC67B2, 0x75041C71, +0x3243625D, 0xA37F8BF3, 0x88012D10, 0xE0248B16, +0xE40001FC, 0x671C2D40, 0x624DDE6E, 0x8B013273, +0x0009A372, 0x6CE3644D, 0x7C046943, 0x39EC6B43, +0x65923BCC, 0x74086DB2, 0x25D2AFEF, 0x8B198804, +0x01FCE024, 0x2D70E700, 0x1FD86D1C, 0x627DDE61, +0x8B0132D3, 0x0009A358, 0x6B73677D, 0x3BEC61E3, +0x710464B2, 0x3C1C6C73, 0x694265C2, 0x29597708, +0x2492AFED, 0x8B188805, 0x01FCE024, 0x2D40E400, +0xDE54671C, 0x3273624D, 0xA33D8B01, 0x644D0009, +0x6BE36D43, 0x65D23DEC, 0x61437B04, 0x6C1231BC, +0x74086952, 0xAFED29CB, 0x88312592, 0xDE4A8B20, +0x65E6DB4A, 0x61E6DC4A, 0x67E2D94A, 0x62E27E04, +0x1FEC7EE8, 0x7E0464E2, 0x6EE21FED, 0x5BFD2BE0, +0x60B27B04, 0xC9011FBE, 0x6BB22C00, 0x29B04B09, +0xDC412F26, 0x66134C0B, 0xE2007F04, 0x2D20A30C, +0x8B218830, 0xD939DE38, 0xE06465E6, 0x720462E3, +0x672666E2, 0x6E23DC36, 0x62227EE8, 0x6BE261E6, +0x29B01FEF, 0x7E040F16, 0xC90160E2, 0x6EE22C00, +0x4E09DC30, 0x2F262CE0, 0xD130E068, 0x04FE410B, +0xE2007F04, 0x2D20A2E8, 0x8B058833, 0x4E0BDE2C, +0xE1000009, 0x2D10A2E0, 0x89018828, 0x0009A106, +0xE143DE20, 0xE04062E1, 0x3217622D, 0x0FE68F04, +0x6023E240, 0x262106FE, 0x8B013217, 0x0009A0EF, +0x02FEE040, 0x8521E401, 0x8B013046, 0x0009A0E7, +0xE501E040, 0x2D5007FE, 0x6471B2C7, 0x09FEE040, +0x6291E143, 0x652DE068, 0x8D6B3517, 0xE6400F56, +0x8B273563, 0xE048E600, 0xE11A0F65, 0x72C0A031, +0x00117800, 0x00202FB8, 0x00201356, 0x00202480, +0x00202F1A, 0x00202FBC, 0x002013A2, 0x00202F19, +0x00202B40, 0x00117804, 0x00117810, 0x00202F15, +0x00202F16, 0x00202F17, 0x00200B84, 0x00200BD8, +0x00200BD4, 0x41216153, 0x41214121, 0x41214121, +0x45214521, 0x60534521, 0x6603C903, 0x0F65E048, +0xE0077118, 0xE0442209, 0x641D0F25, 0x65F3E04C, +0x0F46B314, 0x04FDE048, 0x0BFDE044, 0x61BD674D, +0x41084708, 0x0F16E050, 0xD2936073, 0x420B09FE, +0x6C07E00F, 0x607329C9, 0xE0400F96, 0x65F30EFE, +0x6D0D85E2, 0x01FEE050, 0x60D3420B, 0x6073290B, +0xE04C0F96, 0x04FEB2D9, 0x06FEE040, 0x6261E068, +0x0F56652D, 0x3563E640, 0xE000894E, 0x602381F8, +0x4008C903, 0x6B034000, 0xE0546103, 0xE0580FB6, +0xECFFDD7D, 0x6CCC0FF6, 0x0FD6E06C, 0x4D0B60C3, +0x42216253, 0x42214221, 0x64234221, 0x324C4200, +0xE05C6E07, 0x45214200, 0xE0400FE6, 0x0BFE4521, +0xC9036053, 0x30FC4008, 0x6D037B06, 0x85F81F05, +0x6C2D1FB7, 0x1FC66E03, 0x0FC6E060, 0x05FEE058, +0x64C3B2B4, 0x33FCE354, 0x563262D2, 0x22696132, +0x67B42D22, 0x490B5936, 0x220B607C, 0x05FEE058, +0x64C32D22, 0x7E01B289, 0xE70662ED, 0x8FE33273, +0xE0407C01, 0x626106FE, 0x06FEE040, 0x85614200, +0x302C760C, 0x6103701B, 0x64F3E500, 0x7501E704, +0x6B5D6966, 0x24923B73, 0x74048FF9, 0xB26C65F3, +0xE040641D, 0xB20506FE, 0xA1DD6461, 0xD44F0009, +0xE201D74F, 0x2D20470B, 0x0009A1D6, 0x8B078829, +0xEC00DE4C, 0x61E22DC0, 0x641DB1D7, 0x0009A1CC, +0x622CE281, 0x8B013020, 0x0009A118, 0x06FCE028, +0xE682626C, 0x3260666C, 0xA0EE8B01, 0xE6830009, +0x3260666C, 0xA0DC8B01, 0xE6900009, 0x3260666C, +0xA0D08B01, 0xE6910009, 0x3260666C, 0xA0B98B01, +0xE6B00009, 0x3260666C, 0xA07F8B01, 0xE6BB0009, +0x3260666C, 0xE6928920, 0x3260666C, 0xE4008B14, +0xEB04D531, 0x52516652, 0x8B073620, 0x624D7401, +0x8FF732B7, 0xE6007508, 0x52FBA002, 0xE60152FB, +0xE6041261, 0x2260A188, 0xD229D428, 0xD4296542, +0x0009420B, 0x0009A180, 0xE100E670, 0x601336FC, +0xE0248162, 0x0BFCD21F, 0x6BBC6722, 0x26727BFC, +0xEB0416B2, 0x06FEE078, 0x3263621D, 0xA16B8B01, +0xDE1D0009, 0x31EC611D, 0xD41C6E12, 0x410BD114, +0xE0700009, 0x450BD51A, 0xD41A04FE, 0x420BD210, +0xD2170009, 0x64E3420B, 0xD60DD417, 0x0009460B, +0x05FEE070, 0x01FDE074, 0x611DE600, 0x6253351C, +0x326C666D, 0x22E07601, 0x32B3626D, 0x4E198FF7, +0xE0747104, 0x0F15AFCE, 0x002029F8, 0x00202FDC, +0x00201356, 0x00117804, 0x00202B10, 0x00117800, +0x002013A2, 0x00203014, 0x00117808, 0x00202FF4, +0x0020139A, 0x00203008, 0x00203010, 0x02FCE024, +0x672CE07C, 0xEC000F76, 0xE07CEB04, 0x62CD07FE, +0x8B013273, 0x0009A118, 0x6CCDD7B9, 0x357C65C3, +0x62C37704, 0xD4B7327C, 0x6D52D7B7, 0x6E22470B, +0x470BD7B6, 0xD4B664D3, 0x420BD2B3, 0xD2B30009, +0x64E3420B, 0xD6B0D4B3, 0x0009460B, 0x67D3E600, +0x376C666D, 0x626D7601, 0x27E032B3, 0x4E198FF7, +0x7C08AFD3, 0x6212D1A6, 0x2228622C, 0xD2AA8B04, +0x0009420B, 0x0009A003, 0x420BD2A8, 0x56FB0009, +0xA0E1E200, 0xB1A62620, 0x56FB0009, 0xA0DBE200, +0x52FB2620, 0xE500D69A, 0x65622250, 0x7604D2A0, +0x62622252, 0xA0CFD69F, 0x56FB2620, 0x2610E124, +0x5217D19D, 0x52181621, 0x52191622, 0x521A1623, +0x551B1624, 0x1655E200, 0x1656551C, 0x1657551D, +0x1658551E, 0x1659551F, 0x11281127, 0x112A1129, +0x112C112B, 0x112E112D, 0x112FA0AE, 0xD68FD18E, +0x6262E040, 0x76046512, 0x2152352C, 0x55116266, +0x1151352C, 0x62626563, 0x75085612, 0x1162362C, +0x56136252, 0x362C75EC, 0x62521163, 0x75105614, +0x1164362C, 0x62526653, 0x76105515, 0x1155352C, +0x56166262, 0x362CD57E, 0x62561166, 0x362C5617, +0x66531167, 0x55186252, 0x352C7604, 0x62661158, +0x352C5519, 0x65631159, 0x561A6262, 0x362C7504, +0x6252116A, 0x7504561B, 0x116B362C, 0x561C6256, +0x116C362C, 0x561D6256, 0x116D362C, 0x62526653, +0x7604551E, 0x115E352C, 0x561F6262, 0x362CD569, +0x6252116F, 0x7594061E, 0x0166362C, 0x6653E044, +0x051E6252, 0x352C7644, 0xE0480156, 0x061E6262, +0x0166362C, 0xE054D660, 0x051E6262, 0x352C4229, +0x76040156, 0xE0586262, 0x4229061E, 0x0166362C, +0xE23856FB, 0xE0442620, 0xE048021E, 0x62121621, +0x55111622, 0x1653E200, 0x16545512, 0x16555515, +0x16565513, 0x16575516, 0xE040051E, 0x051E1658, +0x1659E050, 0x165A5514, 0xE04C051E, 0x051E165B, +0x165CE054, 0xE058051E, 0x051E165D, 0x165EE044, +0xE0480126, 0x11212122, 0x11251122, 0x11261123, +0xE0400126, 0xE0500126, 0x01261124, 0x0126E04C, +0x0126E054, 0x0126E058, 0x3F3C9358, 0x6EF64F26, +0x6CF66DF6, 0x000B6BF6, 0x4F2269F6, 0xE240614D, +0x89143123, 0x3127E21F, 0x8B09D734, 0xD434614D, +0xE00171E0, 0x5671440B, 0x26596507, 0x1761A007, +0xE001D42F, 0x6672440B, 0x26596507, 0x4F262762, +0x0009000B, 0x614D4F22, 0x3123E240, 0xE21F8912, +0xD7263127, 0x614D8B08, 0x5671D225, 0x420B71E0, +0x260BE001, 0x1761A006, 0x6672D221, 0xE001420B, +0x2762260B, 0x000B4F26, 0xE6400009, 0x46284618, +0x6252D51C, 0x89FC2268, 0x0009000B, 0x4618E680, +0xD5184628, 0x22686252, 0x000B89FC, 0xA0010009, +0x7201E200, 0x8BFC3242, 0x0009000B, 0x00000080, +0x00117804, 0x00202FF4, 0x00201356, 0x0020139A, +0x00203008, 0x00203010, 0x00200C38, 0x00200C12, +0x00202F00, 0x00202F14, 0x00202AA4, 0x001C36A0, +0x001C3CA0, 0x001C36F4, 0x001C3B88, 0x001C3704, +0x002029F8, 0x001C373C, 0x4618E680, 0xD52F4628, +0x22686252, 0x000B8BFC, 0x2FE60009, 0x7FFC4F22, +0xBFF16E53, 0x61E22F42, 0xE280D629, 0x54E11615, +0x16464218, 0x422855E2, 0x57E31657, 0x16786EF2, +0x26E22E2B, 0x4F267F04, 0x6EF6AFA8, 0x2FD62FC6, +0x4F222FE6, 0x6C53DD1E, 0x6E43BFD6, 0x2DE2BF95, +0x0009BFD2, 0x2C1251D5, 0x1C4154D6, 0x1C5255D7, +0x1C6356D8, 0x6EF64F26, 0x000B6DF6, 0x61636CF6, +0xA004E600, 0x62564109, 0x24227601, 0x36127404, +0x000B8BF9, 0x4F220009, 0xD10FD40E, 0x0009410B, +0xD40FD20E, 0xE5056022, 0x2202CB20, 0xD50D2452, +0x450BE700, 0xD70C2472, 0x0009470B, 0xE601D10B, +0x2162D20B, 0x4F264618, 0x2262000B, 0x001C3700, +0x001C370C, 0x00203028, 0x00201356, 0x001C3500, +0x001D4004, 0x002013CC, 0x00200EF8, 0x001E212C, +0x001C3D30, 0x0009A1A9, 0x2FE62FD6, 0xDD8F4F22, +0xA0049EA7, 0xD48E0009, 0x420BD28E, 0x62D265D2, +0x8BF822E8, 0x0009A004, 0xD28AD48B, 0x55D1420B, +0x22E852D1, 0xA0048BF8, 0xD4880009, 0x420BD285, +0x52D255D2, 0x8BF822E8, 0x0009A004, 0xD281D484, +0x55D3420B, 0x22E852D3, 0xA0048BF8, 0xD4810009, +0x420BD27C, 0x52D455D4, 0x8BF822E8, 0x6EF64F26, +0x6DF6000B, 0x2FD62FC6, 0x4F222FE6, 0x6E636D73, +0x6C53B018, 0x64C357F4, 0xB05465E3, 0xB06A66D3, +0xB09A0009, 0xB09E0009, 0xB0A20009, 0xB0BE0009, +0xB0C10009, 0xB1240009, 0x4F260009, 0x6DF66EF6, +0x6CF6A023, 0x3412D16C, 0xD66C0529, 0x2650D76C, +0x2742000B, 0x0009A014, 0x2FD62FC6, 0x4F222FE6, +0x6E636D73, 0x6C53BFEE, 0x64C357F4, 0xB02A65E3, +0xB10666D3, 0x4F260009, 0x6DF66EF6, 0x6CF6A005, +0xE603D260, 0x000B4618, 0xD25E2262, 0x000BE600, +0x4F222262, 0xE40ABF7E, 0x0009BF7E, 0xE104D25A, +0xE5004118, 0x2212E40A, 0x2252BF74, 0x6072D757, +0x4F26CB20, 0x2702000B, 0xD1554F22, 0xE400410B, +0x452BD554, 0x2FE64F26, 0x6E63D153, 0x44186612, +0x45289210, 0x26294408, 0x44084500, 0x4400265B, +0x4708264B, 0x47082162, 0x27EBD14C, 0x000B2172, +0x03F06EF6, 0x2FE61FFF, 0xDE494F22, 0xE40AE101, +0x2E12BF48, 0x726C62E3, 0xE401E100, 0x22122212, +0x22122212, 0x22122212, 0xE7302242, 0xE40AE503, +0x22122212, 0x22122212, 0x22122212, 0x22122212, +0x22122212, 0x22122212, 0x22522272, 0x22122212, +0x22122212, 0x22122212, 0x22122212, 0x121ABF22, +0x2E62E600, 0x000B4F26, 0xD2326EF6, 0xE441E101, +0x000B2212, 0xD1302242, 0xE605D430, 0x000B2162, +0xD52F2462, 0x6050D22F, 0x8B0E8801, 0x6040D42E, +0x8B078801, 0x9626D52D, 0x88016050, 0x96238B0C, +0x0009A00A, 0xA0079621, 0xE6000009, 0x2262D426, +0x88016040, 0xE6048B00, 0xAEF3E40A, 0xD2242262, +0xE40AE601, 0x2262AEEE, 0x2FC62FB6, 0x2FE62FD6, +0xDC204F22, 0x60C2ED00, 0xCB01EB64, 0x60C22C02, +0xA041C901, 0x03C46E03, 0x034003D4, 0x001C3B88, +0x0020302C, 0x002013A2, 0x00203034, 0x0020303C, +0x00203044, 0x0020304C, 0x0025E720, 0x0020321C, +0x00202F04, 0x001C5968, 0x001D4004, 0x001C3500, +0x00201154, 0x00201180, 0x001C5814, 0x001C59D0, +0x001C5830, 0x001C6268, 0x001C59A4, 0x001C639C, +0x00202F16, 0x001C5804, 0x00202F15, 0x00202F17, +0x001C581C, 0x001C5860, 0x89073DB2, 0xE40A60C2, +0xBE9FC901, 0x7D016E03, 0x8BF52EE8, 0x8B033DB2, +0xD23ED43D, 0x0009420B, 0x4F26E40A, 0x6DF66EF6, +0xAE8F6CF6, 0x44116BF6, 0x604B8F01, 0x000B6043, +0x2FB60009, 0x2FD62FC6, 0x4F222FE6, 0xDC347FFC, +0x60C2ED00, 0xCB02EB64, 0x60C22C02, 0xC9022F02, +0x6E03A009, 0x89083DB3, 0xE40A60C2, 0xC9022F02, +0x6E03BE70, 0x2EE87D01, 0x3DB38BF4, 0xD4298B08, +0x7F04D226, 0x6EF64F26, 0x6CF66DF6, 0x6BF6422B, +0x4F267F04, 0x6DF66EF6, 0x000B6CF6, 0xD5226BF6, +0x60525651, 0x000B4628, 0x2FB6306C, 0x2FD62FC6, +0x4F222FE6, 0x4F024F12, 0x6E43BFF1, 0xDC1B6B03, +0xBFECDD1B, 0x30B80009, 0x060A3C05, 0x46094609, +0x3D654601, 0x4209020A, 0x42094209, 0x8BF032E2, +0x4F164F06, 0x6EF64F26, 0x6CF66DF6, 0x6BF6000B, +0x4F222FE6, 0xE102DE0F, 0xE403E500, 0xBFD42E12, +0xE6062E52, 0xE7004618, 0x2E62E403, 0x4F262E72, +0x6EF6AFCB, 0x0009000B, 0x00203054, 0x00201356, +0x001C5860, 0x0020306C, 0x001C1040, 0xCCCCCCCD, +0x10624DD3, 0x001D4004, 0x2F962F86, 0x2FB62FA6, +0x2FD62FC6, 0x4F222FE6, 0xE5007FDC, 0x6453E110, +0x6C534128, 0xED096E53, 0x6653655D, 0x365C4608, +0x75014608, 0x6043361C, 0x0F66675D, 0xEB0060C3, +0x26C137D3, 0x81628161, 0x16B28163, 0x16B416E3, +0x74048FEA, 0xD9A668F2, 0x1981DAA6, 0x59F12982, +0x1A91D1A5, 0x5AF22A92, 0x5DF45BF3, 0x54F65EF5, +0x21A211A1, 0x11B211B3, 0x11D411D5, 0x11E611E7, +0x11481149, 0x55F7EE00, 0x57F8DD9C, 0x64E3D29C, +0xDB9DD99C, 0xE845EAB8, 0x2D521D51, 0x6AAC2272, +0x6EED4808, 0x4D086DE3, 0x3DEC65E3, 0x4D084508, +0x3D9C35EC, 0x450860C3, 0x81D12DC1, 0x4508E050, +0x45084008, 0x60C381D2, 0xE60035BC, 0x81D334A2, +0x1D531DD2, 0x8D01D489, 0xD4861D64, 0xB05C65D3, +0x64ED7E01, 0x8BDC3482, 0xDB88D182, 0xD2806812, +0x1B814829, 0x2FD26412, 0x2B92694D, 0xD97F6722, +0x1B734729, 0xD77C6822, 0x1BA26A8D, 0xD2806B72, +0x22B2D57B, 0xE0035D72, 0x5E7412D2, 0x12E44018, +0xD67C5176, 0x54781216, 0x1248E103, 0xD4796792, +0x6852127A, 0x28C1E7FF, 0x81916952, 0x6A52E050, +0x81A24008, 0x60C36B52, 0x6C5281B3, 0x6E521CC2, +0x62521E63, 0x1264E600, 0x46086563, 0x7501364C, +0x665D2672, 0x8BF83613, 0x4F267F24, 0x6DF66EF6, +0x6BF66CF6, 0x69F66AF6, 0x68F6000B, 0x60616642, +0x8D04C803, 0x6061E500, 0x8802C903, 0x52628B03, +0x51246563, 0x000B2412, 0x2FD66053, 0x4F222FE6, +0x6E537FEC, 0xE5506253, 0xE4006D43, 0xA0014508, +0x5224E101, 0x22116043, 0x81238121, 0x81226053, +0x362056E2, 0xD2548BF5, 0x64F316E4, 0x420BE614, +0x65E165E3, 0x2549E4FC, 0x61F12E51, 0x214965F3, +0x54D12F11, 0x410BD14C, 0x57D1E614, 0xCB016071, +0x1DE12701, 0x4F267F14, 0x000B6EF6, 0x2FD66DF6, +0x4F222FE6, 0x6E537FEC, 0xE5FC6653, 0x60616D43, +0xCB012059, 0x52E22601, 0x8B063260, 0x51E212E4, +0x8B0431E0, 0xA00252D1, 0xAFF01E22, 0xD23A5664, +0xE61464F3, 0x65E3420B, 0xE1FC67E1, 0x2E712719, +0x54D167F1, 0xD1342719, 0xE61465F3, 0x2F71410B, +0x602152D1, 0x2201CB01, 0x7F141DE1, 0x6EF64F26, +0x6DF6000B, 0x4F222FE6, 0xDE23624C, 0x42004208, +0x3E2CA005, 0xD41F5252, 0xBF8E5624, 0x65E22E62, +0x352052E1, 0xD6228BF6, 0x4F262622, 0x6EF6000B, +0x2FC62FB6, 0x2FE62FD6, 0xDC184F22, 0x52C1DB1F, +0x362066C2, 0x6061891C, 0x8801C903, 0xDE138918, +0xBF63DD1B, 0x650364E3, 0x66B28503, 0x3262620D, +0xD40B8907, 0x0009BF9B, 0x4D0BD416, 0xAFE60009, +0xBF620009, 0xD41464E3, 0x00094D0B, 0x0009AFDF, +0x2262D212, 0x6EF64F26, 0x6CF66DF6, 0x6BF6000B, +0x00202B00, 0x00202B08, 0x00202B10, 0x00202B38, +0x00202F1C, 0x001000B4, 0x00101680, 0x001E2108, +0x001C3D00, 0x00117880, 0x00200A9E, 0x00202F00, +0x00201356, 0x00203088, 0x0020308C, 0x001C3D28, +0x2FC62FB6, 0x2FE62FD6, 0x7FFC4F22, 0x6022D22B, +0x8D41C803, 0xDE2A2F01, 0xDB2BDC2A, 0xED01A017, +0xC9036051, 0x89168801, 0xD128D426, 0x0009410B, +0x61035503, 0xC8208551, 0xE0508903, 0x720102BE, +0xD2230B26, 0x420B64E3, 0xD6226513, 0x52C126D2, +0x352065C2, 0xDE208BE4, 0xDB21DD20, 0x52D1DC21, +0x352065D2, 0x60518918, 0x8801C903, 0xD41B8914, +0x460BD616, 0x57030009, 0x8F0437E0, 0xE2016503, +0xAFEC2B20, 0xD4182C52, 0x420BD218, 0xD6110009, +0x4118E101, 0x2612AFE3, 0xC80460F1, 0xD2148907, +0x4F267F04, 0x6DF66EF6, 0x422B6CF6, 0x7F046BF6, +0x6EF64F26, 0x6CF66DF6, 0x6BF6000B, 0x001E2100, +0x00202B10, 0x00202B08, 0x00202AA4, 0x0020106C, +0x002010EE, 0x001C3D30, 0x00117880, 0x00202B00, +0x00202F20, 0x00202F1C, 0x00202B38, 0x0020108A, +0x00200170, 0xE601D203, 0x1265D503, 0x000B2252, +0x00001266, 0x001C1010, 0x0000C34F, 0x0009000B, +0x2FD62FC6, 0x4F222FE6, 0x6D436C53, 0xEE00A004, +0x7E0164D4, 0x644CBFF2, 0x8BF93EC2, 0x6EF64F26, +0x000B6DF6, 0xE5006CF6, 0x6643A002, 0x76017501, +0x22286260, 0xAFE38BFA, 0x2FE60009, 0x75076253, +0xE1086753, 0x6043EE0A, 0x4409C90F, 0x650330E2, +0x8D014409, 0xE630E637, 0x4110365C, 0x8FF22760, +0xE00077FF, 0x000B8028, 0x000B6EF6, 0x000BE000, +0x2FE6E000, 0x7FEC4F22, 0x6E436253, 0xBFDC65F3, +0xBFD06423, 0xBFCE64E3, 0xD40364F3, 0x0009BFCB, +0x4F267F14, 0x6EF6000B, 0x00203090, 0xE4FDD59A, +0xD69A6152, 0x25122149, 0x74016052, 0x2502CB01, +0xD1976752, 0x25722749, 0xC8406010, 0x60628902, +0x2602CB04, 0xE5016062, 0x2602CB08, 0xE4026062, +0x2602C9CF, 0x45186062, 0x2602CB03, 0x000B1642, +0xD58C1653, 0xD28DD78C, 0xE100D48D, 0x2511E600, +0x22102711, 0x2461AFD2, 0xD28A664C, 0x362C4600, +0xCB106060, 0x2600000B, 0xD286654C, 0x352C4500, +0xE1EF6650, 0x000B2619, 0x664C2560, 0x4600D282, +0x6060362C, 0x000BCB10, 0x654C2600, 0x4500D27E, +0x6650352C, 0x2619E1EF, 0x2560000B, 0xD279664C, +0x362C4600, 0xCB086060, 0x2600000B, 0xD275654C, +0x352C4500, 0xE1F76650, 0x000B2619, 0x664C2560, +0x4600D271, 0x6060362C, 0x000BCB08, 0x654C2600, +0x4500D26D, 0x6650352C, 0x2619E1F7, 0x2560000B, +0xD668624C, 0x326C4200, 0xC9086020, 0x40214021, +0x000B4021, 0x624C600C, 0x4200D663, 0x6020326C, +0x4021C908, 0x40214021, 0x600C000B, 0x644CD15F, +0x6240341C, 0x602C000B, 0x644CD15D, 0x6240341C, +0x602C000B, 0x4F222FE6, 0x645C6E43, 0x3467E60A, +0xBFEB8914, 0x640C0009, 0x880160EC, 0xE00F8B02, +0x2409A002, 0x44094409, 0xE60A624C, 0x89053263, +0x644CBFE2, 0x6023620C, 0x8B00C880, 0x6023E200, +0x000B4F26, 0x4F226EF6, 0x6062D64A, 0x8B038801, +0x0009B246, 0x0009A003, 0xE640D247, 0xD6472260, +0x4F26E200, 0x2622000B, 0xD6424F22, 0x88026062, +0xB28F8B01, 0xD6410009, 0x4F26E200, 0x2622000B, +0xD43DD53C, 0xE701E100, 0x000B2512, 0xD23A2470, +0x000BE604, 0x4F222260, 0xD13AD439, 0x0009410B, +0xE1FDD539, 0xD2396650, 0xE7002619, 0x4F262560, +0x2270000B, 0xD4364F22, 0x410BD132, 0xD5320009, +0x6650E7FB, 0x4F262679, 0x2560000B, 0xD4314F22, +0x410BD12C, 0xD52C0009, 0x6650E7F7, 0x4F262679, +0x2560000B, 0x942DD528, 0x22496250, 0x2520000B, +0xE4BFD525, 0x22496250, 0x2520000B, 0xD2264F22, +0x600D8522, 0x89112008, 0x89138801, 0x89158803, +0x89438805, 0x89498806, 0x894F8808, 0x89558809, +0x895B880A, 0x8961880B, 0x0009A068, 0x0009B06A, +0x600CA065, 0x0009B078, 0x600CA061, 0x0009B081, +0x600CA05D, 0x0000FF7F, 0x001E2148, 0x001E1108, +0x001E1000, 0x00202F60, 0x00202F62, 0x00202F81, +0x00202F44, 0x001E103F, 0x001E105F, 0x001E102F, +0x001E1090, 0x00202F68, 0x001E100B, 0x00202F64, +0x00203094, 0x00201356, 0x001E1028, 0x00202F80, +0x002030A0, 0x002030B0, 0x00202F38, 0x6260D684, +0x8B2B2228, 0x0009B061, 0x600CA029, 0x6260D680, +0x8B232228, 0x0009B069, 0x600CA021, 0x6260D67C, +0x8B1B2228, 0x0009B0C7, 0x600CA019, 0x6260D678, +0x8B132228, 0x0009B0CD, 0x600CA011, 0x6260D674, +0x8B0B2228, 0x0009B125, 0x600CA009, 0x6260D670, +0x8B032228, 0x0009B13D, 0x600CA001, 0x4F26E000, +0x0009000B, 0xD26CD16B, 0xD56C8412, 0x4000C90F, +0xD76B012D, 0xE403D66B, 0xE20F611C, 0x2540E001, +0x25202712, 0x2602000B, 0xE601D262, 0x30668523, +0xE0008D05, 0xD663D260, 0xE0018122, 0x000B2602, +0xD25C0009, 0x600D8523, 0x89052008, 0x8B0A8801, +0x6060D65D, 0x2600CB01, 0xD457D65A, 0xE001E101, +0x000B2612, 0x000B8142, 0xD152E000, 0x8513E501, +0x640D4518, 0x66033453, 0xE0008D05, 0xD551D253, +0x2260E001, 0x000B2502, 0x4F220009, 0x8513D149, +0x6453650D, 0x62494419, 0x227D672E, 0x8801602C, +0x88028909, 0x88038910, 0x8806891A, 0x88078935, +0xA04C893B, 0xD5460009, 0x6652D746, 0x2762D446, +0x622C6261, 0x2421A038, 0x2228625C, 0xD4438B3F, +0x6642D540, 0x2562D440, 0x24018561, 0x6203A02C, +0x2008605C, 0x88108907, 0x88208908, 0x88308909, +0xA02C890A, 0xD23A0009, 0x6222A008, 0xA005D239, +0xD2396222, 0x6222A002, 0x6262D638, 0xD432D531, +0x66212522, 0xA00F626C, 0xD6352421, 0x6261D52D, +0x622CD42D, 0xA0072562, 0xD6322421, 0x8561D529, +0x2562D429, 0x62032401, 0x662D8515, 0x3617610D, +0x65038F01, 0xB0CB2451, 0xA0010009, 0xE000E001, +0x000B4F26, 0xD6190009, 0xD427E101, 0x65412610, +0xD118D717, 0xE20F655D, 0x2752E001, 0x000B2620, +0x2FE62102, 0xD20F4F22, 0x640C8523, 0x8B082448, +0xD511D61D, 0x2621E200, 0x940F8451, 0xA0482049, +0xDE0D8051, 0xC84060E0, 0xE2018D32, 0x89443427, +0xD216D615, 0x2641420B, 0x0009A030, 0x0000FF7F, +0x00202F81, 0x00202F38, 0x00202F44, 0x001E1100, +0x001E100C, 0x00202F64, 0x001E1000, 0x001E1001, +0x00202F6C, 0x00202F4C, 0x00202F50, 0x00202F54, +0x00202F70, 0x00202F74, 0x00202F78, 0x00202F7C, +0x00203280, 0x0020328A, 0x00202F5E, 0x0020225A, +0x89123427, 0xD294D693, 0x2641420B, 0xCB8084E1, +0x80E1B0F5, 0xD69160E0, 0x2E00CB04, 0xC93F6060, +0xD68F2600, 0xA001E001, 0xE0002602, 0x000B4F26, +0xD68C6EF6, 0xC8806060, 0xD2868919, 0x88016021, +0xD2898B15, 0x8524E501, 0x89103056, 0xE203D187, +0x2120D487, 0xE00B6541, 0x0656655D, 0xE40FD585, +0x2140E702, 0xD77E2571, 0x000BE001, 0x000B2702, +0x2FE6E000, 0xDE804F22, 0xC88084E1, 0xD57A892C, +0x20088554, 0x61038F28, 0x8553D77C, 0x64036672, +0x8566650C, 0x3520620C, 0xD6798B1E, 0x651CD774, +0x2651644C, 0x60E02741, 0x8904C840, 0x420BD275, +0xA0030009, 0xD2680009, 0x0009420B, 0x0009B09F, +0xE201D167, 0x60E02122, 0xCB04D464, 0x60402E00, +0x2400C93F, 0x6023A001, 0x4F26E000, 0x6EF6000B, +0x2FB62FA6, 0x2FD62FC6, 0xDA622FE6, 0x66A1E240, +0x3622DC5E, 0x62638900, 0x6ED36D2C, 0x4E2136D8, +0x4E212A61, 0xDB61D460, 0xE700A00F, 0x770162B2, +0x71026123, 0x66212B12, 0x71026213, 0x61212B12, +0x651D666D, 0x356C4528, 0x627C2452, 0x8BED32E3, +0xC90360D3, 0x8B108803, 0x617367B2, 0x2B127102, +0x71026E13, 0x2B126571, 0x655D6DE1, 0x422862DD, +0x325CE107, 0xA00C2C10, 0x88022422, 0xA0038B01, +0x8801E203, 0xE2018B05, 0x66B22C20, 0x655D6561, +0xE60F2452, 0x67A12C60, 0x8B052778, 0xDD38DC44, +0xEB01EA00, 0x2DB22CA2, 0x6DF66EF6, 0x6BF66CF6, +0x6AF6000B, 0x2FE62FD6, 0xE240DD36, 0x362266D1, +0x62638900, 0x3678672C, 0x7703DE38, 0x47212D61, +0x64E2D635, 0xA00E4721, 0x6562E100, 0x62537101, +0x74012450, 0x24204219, 0x45297401, 0x74012450, +0x24504519, 0x621C7401, 0x8BEE3273, 0x66E24200, +0x420061D1, 0x2118362C, 0x2E628F06, 0xDD1CD728, +0xE501E400, 0x2D522742, 0x000B6EF6, 0x2FD66DF6, +0x4F222FE6, 0xED0AEE01, 0x64E3BC96, 0xBC9B64E3, +0x62EC7E01, 0x8BF732D7, 0xBC9EEE01, 0x64E364E3, +0x7E01BCA3, 0x32D762EC, 0x4F268BF7, 0x000B6EF6, +0xD1186DF6, 0xD418920D, 0x72122122, 0x2422D617, +0xD7177204, 0x72202622, 0x2722D116, 0x000B7230, +0x137A2122, 0x00202F5E, 0x00202366, 0x001E1015, +0x00202F64, 0x001E1001, 0x00202F38, 0x001E1100, +0x00202F62, 0x00202F50, 0x001E1000, 0x00202F54, +0x00202F60, 0x0020225A, 0x001E100C, 0x00202F4C, +0x00202F68, 0x00202F6C, 0x00202F70, 0x00202F74, +0x00202F78, 0x00202F7C, 0x4F222FE6, 0xD6507FFC, +0x88016060, 0xE2018951, 0x2620BFBB, 0xD54ED14D, +0xDE4E6010, 0x64E36552, 0x7402C840, 0x8D22D14C, +0xD24C7502, 0xE601D74C, 0xE7042722, 0x76016255, +0x626C2421, 0x8FF93273, 0xD4437402, 0x6242E601, +0x640D8528, 0x67494419, 0x275D657E, 0x81E4607C, +0xE417D542, 0x67557601, 0x3243626C, 0x8FF92171, +0xA0207102, 0xD23E0009, 0xE601D73B, 0xE7042722, +0x76016255, 0x626C2421, 0x8FF93273, 0xD4327402, +0x6242E601, 0x640D8528, 0x67494419, 0x275D657E, +0x81E4607C, 0xE417D533, 0x67557601, 0x3243626C, +0x8FF92171, 0x924A7102, 0xD2262E21, 0x5E23D72E, +0x64F22FE2, 0x604365F2, 0x2700C980, 0xC9606043, +0x80716103, 0xC9036043, 0x80724519, 0x65F2605C, +0x817266F2, 0x46194629, 0x606C4529, 0x4018645C, +0x8173304C, 0x21185E23, 0x64F22FE2, 0x6E4C62F2, +0x602C4219, 0x66F262F2, 0x46294018, 0x461930EC, +0x42298174, 0x652C606C, 0x305C4018, 0x81758F07, +0x0009BC9C, 0x2228620C, 0xA00A8908, 0x60130009, +0x8B038840, 0x0009B009, 0x0009A003, 0xE202D60F, +0x7F042622, 0x000B4F26, 0x000B6EF6, 0x060A0009, +0x00202F80, 0x001E1000, 0x00202F6C, 0x00203280, +0x0020328C, 0x00203224, 0x00202F54, 0x00203254, +0x00203252, 0x00203226, 0x00202F38, 0x00202F64, +0x4F222FE6, 0xDE937FFC, 0x200884E9, 0x2F008D06, +0xD692D491, 0x0009460B, 0x64F0B194, 0x6620D290, +0x89022668, 0xC9BF60E0, 0x7F042E00, 0x000B4F26, +0x000B6EF6, 0x2FE60009, 0xDE8A4F22, 0x60E0D68A, +0xCBC0D48A, 0x62602E00, 0xC803602C, 0x40218904, +0x70014021, 0x6603A002, 0x66034009, 0xD684616D, +0xE500A004, 0x75016262, 0x74042422, 0x3213625D, +0xD2808BF8, 0x0009420B, 0xC9BF84E2, 0x4F2680E2, +0x6EF6000B, 0x2FE62FD6, 0x7FFC4F22, 0x6260D67A, +0x89442228, 0xD56FE100, 0x60502610, 0xCB40D477, +0x2500440B, 0x8D052008, 0x62E06E03, 0x7104612C, +0x2F11A006, 0xD472D66A, 0xDD726760, 0x657C4D0B, +0xE23C6D1D, 0x8B033D27, 0xD264D46F, 0x0009420B, +0x4D214D21, 0xA005D76D, 0x66E6E400, 0x357C4508, +0x74012562, 0x35D3654D, 0xD7698BF7, 0x6172E003, +0x81114018, 0x6E7260F1, 0x81E2700C, 0xD4656172, +0xDD658113, 0x4D0BDE65, 0xE2016572, 0xD4642E22, +0x420BD252, 0xD6530009, 0xC93F6060, 0x7F042600, +0x6EF64F26, 0x6DF6000B, 0x2FC62FB6, 0x2FE62FD6, +0xD25C4F22, 0x6B436E73, 0x420B6C53, 0x20086D63, +0x61038F08, 0xD245D458, 0x6EF64F26, 0x6CF66DF6, +0x6BF6422B, 0x21B060C3, 0x60D38011, 0xE5008111, +0x64BCA007, 0x6053655D, 0x665300EC, 0x7501361C, +0x625D8064, 0x8BF53243, 0x6060D636, 0x2600C9BF, +0x6EF64F26, 0x6CF66DF6, 0x6BF6000B, 0x7FC44F22, +0x720262F3, 0x22512F41, 0x45297202, 0x60632251, +0xE5C4E682, 0x67F38121, 0x655C666C, 0xE408BFBC, +0x4F267F3C, 0x0009000B, 0x2F962F86, 0x2FB62FA6, +0x2FD62FC6, 0x4F222FE6, 0xE1007FC4, 0x6513ECFF, +0x6B136CCD, 0xDE36D735, 0xEDFF64F3, 0xD835EA04, +0x6053655C, 0x027D4000, 0x32C0622D, 0x66038D0D, +0x09ED6063, 0x2491027D, 0x24217402, 0x698202ED, +0x3928622D, 0x74022892, 0x75017104, 0x6063625C, +0x07D532A2, 0x0EB58FE4, 0x2448641C, 0xE6808905, +0x67F3E5C5, 0xBF7F666C, 0x7F3C655C, 0x6EF64F26, +0x6CF66DF6, 0x6AF66BF6, 0x000B69F6, 0xD11E68F6, +0x6012D21E, 0xCB20E405, 0x2102E500, 0x000B2242, +0x00002252, 0x001E1017, 0x002030BC, 0x00201356, +0x00202F1A, 0x001E1015, 0x001E10BF, 0x00117800, +0x001E10FC, 0x00200170, 0x00202F20, 0x002024BE, +0x002030C0, 0x002013A2, 0x002030DC, 0x0011788C, +0x00202F1C, 0x00202B00, 0x002010EE, 0x001E2130, +0x002030E4, 0x00202480, 0x002030E8, 0x00202F26, +0x00202F2E, 0x00203220, 0x001C3500, 0x001D4004, +0xD565D164, 0xE400D765, 0x2142E20F, 0x17411154, +0xD5632722, 0x9669D763, 0x15412572, 0x96661562, +0xE6011565, 0xD5601165, 0x666CE6F8, 0x25422542, +0x25422542, 0x25422542, 0x25622542, 0x7601E727, +0x67632572, 0x25627797, 0xE7042572, 0x2572E248, +0xE2192522, 0xE2702522, 0x25422542, 0x25422542, +0x25222542, 0x2522E20C, 0x25422542, 0x25422542, +0x25422542, 0x25422542, 0x000B154A, 0xE2081145, +0x0009422B, 0x2FE62FD6, 0x7FFC4F22, 0xC8206043, +0x6E438D02, 0x0009BE6D, 0xC81060E3, 0xBE6A8901, +0x60E30009, 0x8901C840, 0x0009BE8C, 0xC80160E3, +0xDD3E8938, 0xC80260D0, 0x2F008D03, 0x460BD63C, +0x60F00009, 0x8902C804, 0x460BD63A, 0x62F00009, +0xC8806023, 0x60D08902, 0x2D00C97F, 0xC8016023, +0xD6358906, 0x0009460B, 0x0009A007, 0x51630601, +0x8902C808, 0x460BD631, 0x60F00009, 0x8902C810, +0x420BD22F, 0xD52F0009, 0x88026052, 0xD22E8B03, +0xA005E604, 0x88012260, 0xD22B8B02, 0x2260E601, +0x2522E200, 0xC88060E3, 0xD628892E, 0x60E36E60, +0x8902C880, 0x420BD226, 0x60E30009, 0x8902C840, +0x420BD224, 0x60E30009, 0x8902C802, 0x420BD222, +0x60E30009, 0x890EC804, 0x410BD120, 0xBF0E0009, +0xBF4D0009, 0xD51E0009, 0x6050D41E, 0xC908D71E, +0xBF842500, 0x60E32472, 0x8905C808, 0x7F04D21B, +0x6EF64F26, 0x6DF6422B, 0x4F267F04, 0x000B6EF6, +0x00006DF6, 0x001C581C, 0xA000A000, 0x001D0100, +0x001D4000, 0x00040021, 0x001C589C, 0x001E1021, +0x00201536, 0x00201558, 0x00201B98, 0x00201570, +0x0020157E, 0x00202F64, 0x001E100B, 0x001E1028, +0x002015D4, 0x002015E0, 0x00201586, 0x002015A4, +0x001E1000, 0x0010F100, 0x12345678, 0x002015BC, +0x644CD6A7, 0x000B346C, 0xD6A62450, 0x346C644C, +0x2450000B, 0x644CD6A4, 0x000B346C, 0x625C2450, +0x4208616D, 0x42084119, 0x42006019, 0x670E614C, +0xD49E321C, 0x4200207D, 0x324CC90F, 0x2200000B, +0x4208625C, 0x42004208, 0x324C644C, 0x4200D498, +0x000B324C, 0x2FE62260, 0x614C4F12, 0x4100D493, +0x6710314C, 0xE29F666D, 0x27294619, 0x6E536269, +0x672E6573, 0x4221227D, 0x42214221, 0x7601662C, +0xE4014608, 0x34E84608, 0x644C4600, 0x071A0467, +0x2150257B, 0x000B4F16, 0x4F226EF6, 0xD2857FE8, +0x88016021, 0xD2848B7B, 0x26686621, 0xD2838B77, +0x26686621, 0xE50F8B73, 0xE401BFA2, 0xBFA4E501, +0xE586E400, 0xE400655C, 0x2F50BFA4, 0xBFA1E401, +0xE602E506, 0x60634618, 0x81F2E401, 0x6543BF9F, +0xE40185F2, 0xBFAB6543, 0x85F26603, 0x6543E401, +0x6603BFB1, 0xE40265F0, 0x6053756C, 0x80F8BF80, +0xBF82E402, 0x84F8E512, 0x7090E402, 0x6503BF82, +0x4618E602, 0x81F66063, 0xBF80E402, 0x85F6E500, +0x6603E402, 0xE500BF8C, 0xE40285F6, 0xBF926603, +0xE5FEE500, 0xE010655C, 0xBF61E403, 0xE5130F54, +0xE40EBF63, 0x05FCE010, 0xBF63E40E, 0xE5007585, +0xBF64E403, 0xE500E640, 0xBF71E403, 0xE500E640, +0xBF78E403, 0xE5FFE640, 0xE014655C, 0xBF47E404, +0xE40F0F54, 0xE504BF49, 0x05FCE014, 0xBF49E40F, +0xE5017584, 0xBF4AE640, 0xE501E404, 0xBF57E640, +0xE501E404, 0xE404E640, 0xAF5C7F18, 0x7F184F26, +0x000B4F26, 0x4F220009, 0xD2427FF0, 0x88016021, +0xD2418B71, 0x26686621, 0xD2408B6D, 0x26686621, +0xE50F8B69, 0xE401BF1C, 0xBF1EE501, 0xE586E400, +0xE400655C, 0x2F50BF1E, 0xBF1BE401, 0xE401E506, +0xBF1C6543, 0xE401E640, 0xBF296543, 0xE401E640, +0xBF306543, 0x65F0E640, 0x756CE402, 0xBEFF6053, +0xE40280F4, 0xE512BF01, 0xE40284F4, 0xBF017090, +0xE6406503, 0xBF02E402, 0xE640E500, 0xBF0FE402, +0xE640E500, 0xBF16E402, 0xE5FEE500, 0x6053655C, +0xBEE5E403, 0xE51380F8, 0xE40EBEE7, 0xE40E84F8, +0xBEE77085, 0xE5006503, 0xBEE8E640, 0xE500E403, +0xBEF5E640, 0xE500E403, 0xBEFCE640, 0xE5FFE403, +0x6053655C, 0xBECBE404, 0xE40F80FC, 0xE504BECD, +0xE40F84FC, 0xBECD7083, 0xE5016503, 0xBECEE640, +0xE501E404, 0xBEDBE640, 0xE501E404, 0xE404E640, +0xAEE07F10, 0x7F104F26, 0x000B4F26, 0x00000009, +0x001E102F, 0x001E1080, 0x001E1090, 0x001E103F, +0x001E103E, 0x00202F5E, 0x00202F60, 0x00202F62, +0xD21DD11C, 0x66206010, 0x676C7001, 0x3700C90F, +0xE5008D13, 0x67106210, 0x7701622C, 0x64232170, +0xD6166010, 0x44084408, 0x3428C90F, 0x62602100, +0x7201D513, 0x44082620, 0x000B354C, 0xD10F6053, +0x25586510, 0xE6008D13, 0xD60DD40B, 0x655C6540, +0x47086753, 0x37584708, 0x47086540, 0x24507501, +0x367C6040, 0x2400C90F, 0x72FF6210, 0x000B2120, +0x00006063, 0x00202F19, 0x00202F18, 0x00202F1A, +0x00202B40, 0x7FFC4F22, 0xE680D1A8, 0x666C6212, +0xD2A72F22, 0x67F36563, 0x420B7542, 0x7F04E404, +0x000B4F26, 0xE6800009, 0xD2A1666C, 0xE7006563, +0x422B7540, 0xE6806473, 0xD29D666C, 0xE7006563, +0x422B7543, 0x2FB66473, 0x2FD62FC6, 0x4F222FE6, +0x4D18ED01, 0xDB98DC97, 0x65C252C1, 0x89203520, +0xC9036051, 0x891C8801, 0xD194DE92, 0x64E3410B, +0x85036503, 0x670D66B2, 0x89073762, 0xD291D490, +0x0009420B, 0xE701D190, 0x2172AFE6, 0xDE8F64E3, +0x00094E0B, 0xD48FD68E, 0x410BD18F, 0xAFDB26D2, +0x4F260009, 0x6DF66EF6, 0x000B6CF6, 0x4F226BF6, +0x85467FF4, 0x2F01E681, 0x666C8547, 0x854881F1, +0x81F2D27B, 0x67F38542, 0x854381F3, 0x81F4E40C, +0x65636053, 0x420B81F5, 0x7F0C7540, 0x000B4F26, +0x2F860009, 0x2FA62F96, 0x2FC62FB6, 0x2FE62FD6, +0x7FEC4F22, 0xE000D176, 0xD4782F12, 0x81F26103, +0xDC771F42, 0xD6776B13, 0xE0014B08, 0x460BDE76, +0x3BEC4B00, 0x66C21F03, 0x362052C1, 0xA1818B01, +0x60610009, 0x8801C903, 0xA17B8B01, 0x85610009, +0x8B01C801, 0x0009A080, 0x85D25D63, 0xC9036603, +0x85D36403, 0x6053650D, 0x40214021, 0x4500C93F, +0x322A6103, 0x6053252D, 0xC901E510, 0xD95E3153, +0x6E038D21, 0x4408D761, 0x44086870, 0x44006213, +0x28884200, 0x342C8F0E, 0x6043D25D, 0x60E3072D, +0x4A196A7D, 0x658E68A9, 0x285D8801, 0x6A7C8F0B, +0x6A13A009, 0x6043D257, 0x61ED0E2D, 0x68194119, +0x287D678E, 0xD1546AEC, 0x22286210, 0xEAFF8901, +0xEEFF6AAC, 0x6EEC65AD, 0x8B0F35E0, 0x4D0BDD3F, +0x540364C3, 0xBF72E502, 0xD44C6D03, 0x410BD13F, +0xD74B65D3, 0xD44BEE01, 0x27E2A025, 0x2679E7FC, +0x81D26063, 0x946085D3, 0x61032049, 0x4508268B, +0x251B6063, 0x605381D2, 0x85D481D3, 0x4118E108, +0x81D4201B, 0xEE0262C2, 0x20798521, 0x64C28121, +0x6041678D, 0xCB0137E3, 0x24018D04, 0xEEE785D2, +0x81D220E9, 0x490BD438, 0x60C20009, 0x52F366F2, +0x2B02CB01, 0x2622AF6F, 0xD2208561, 0x8F02C802, +0xA0D264C3, 0x420B0009, 0xD9300009, 0x5E036503, +0x079EE04C, 0x7701DD2E, 0x69D20976, 0x7901D626, +0x6D602D92, 0x89062DD8, 0xD218D424, 0xED01420B, +0xA0B3D723, 0x625127D2, 0x4118E10F, 0x2219E402, +0x32404418, 0x85518B46, 0x20D9EDFC, 0x60518151, +0xCB017DE3, 0x85E12501, 0x20D9D60A, 0x460B81E1, +0x69F264C3, 0xA09957F3, 0x7E032972, 0x001C3D9C, +0x00201E38, 0x00202B38, 0x00202F00, 0x0020106C, +0x00202B00, 0x002010EE, 0x001E2130, 0x0020108A, +0x001C3D30, 0x00203200, 0x00201356, 0x0020320C, +0x00202B10, 0x002029F8, 0x001C3D00, 0x0020321C, +0x00203100, 0x00203180, 0x00202F14, 0x00202B08, +0x001E212C, 0x00203204, 0x00203208, 0x00202AA4, +0x00203220, 0x6DDD6D51, 0x6DD94D19, 0x2D6D66DE, +0x60DC7D01, 0x41186103, 0x8F458801, 0xD65B2511, +0x74016462, 0x85E32642, 0x6063660D, 0x40214021, +0x4600C93F, 0x322A6D03, 0x6063262D, 0xD154C801, +0x8901D954, 0x2D6B96A1, 0xE010E600, 0x64DD0F64, +0x07FCE010, 0x4000607C, 0x622D021D, 0x8D123240, +0x60636603, 0xE7FF021D, 0x8B013270, 0x01D5A00B, +0x02FCE010, 0x7201E604, 0x622C0F24, 0x8BE73262, +0x666C06FC, 0x60634600, 0x7101019D, 0xD1420915, +0x697D6711, 0x89073940, 0x602D6211, 0x890388FF, +0xDD3E21D1, 0x2D20E201, 0xEDFC8551, 0x815120D9, +0xD23B6051, 0x64C3CB01, 0x2501420B, 0x02FCE010, +0x612CD438, 0x440BE001, 0x270267F2, 0xD23685EF, +0x420B54F2, 0xAE96650D, 0x420B0009, 0x54030009, +0x85446E03, 0x4D18ED08, 0x30D020D9, 0xBE568B03, +0xA007E501, 0x85410009, 0x620DDD2C, 0x890122D8, +0xE500BE4D, 0xD22BD42A, 0x65E3420B, 0xED01D72A, +0x27D2AE79, 0xEE0485F2, 0x610D7001, 0x81F231E7, +0x7C088D02, 0x0009AE66, 0x4F267F14, 0x6DF66EF6, +0x6BF66CF6, 0x69F66AF6, 0x68F6000B, 0x4F222FE6, +0x6E22D21E, 0xC84060E3, 0x22E28D02, 0x0009BDD2, +0x4218E240, 0x89012E28, 0x0009BDDD, 0xC81060E3, +0xD4178905, 0x420BD217, 0xBDDC0009, 0x60E30009, +0x8901C805, 0x0009BE2D, 0xC80260E3, 0x4F268902, +0x6EF6ADD9, 0x000B4F26, 0x80006EF6, 0x00203220, +0x00202F26, 0x00202F2E, 0x00202F22, 0x00202F24, +0x002010EE, 0x002029F8, 0x002013A2, 0x00008000, +0x00202B08, 0x0020108A, 0x001E212C, 0x001C3510, +0x00203214, 0x00201356, 0x080A0C0E, 0x00020406, +0x1A1C1E20, 0x12141618, 0x2E303234, 0x26282A2C, +0x3A3C3E40, 0x6C625648, 0x41112F26, 0xE2208F18, +0x890B3123, 0x321CD204, 0xD1026220, 0x412B312C, +0x00090009, 0x00202A22, 0x002029D8, 0x000BE000, +0x400062F6, 0x40004000, 0x40004000, 0x40004000, +0x62F6000B, 0x40004000, 0x40004000, 0x40004000, +0x40184000, 0x62F6000B, 0x40004000, 0x40004000, +0x40004000, 0x40284000, 0x62F6000B, 0x40004000, +0x40184000, 0x000B4028, 0xC90F62F6, 0x40054005, +0x40054005, 0x62F6000B, 0x4005C907, 0x40054005, +0x62F6000B, 0x4005C903, 0x000B4005, 0xC90162F6, +0x000B4005, 0x000062F6, 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, 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, +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, 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, 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, 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, +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, 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, 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, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x544F0D0A, 0x46205355, 0x00003A57, 0x20636544, +0x32203231, 0x20373030, 0x333A3132, 0x34323A36, +0x00000000, 0x00000D0A, 0x00000043, 0x42707372, +0x3D206675, 0x554E203D, 0x202C4C4C, 0x6E49677A, +0x4E497274, 0x6D754E51, 0x0000003D, 0x61766E49, +0x2064696C, 0x72657375, 0x20726F20, 0x2079656B, +0x00214449, 0x52504545, 0x57204D4F, 0x65746972, +0x6461202C, 0x003D7264, 0x6C617620, 0x0000003D, +0x00000A0D, 0x6E6B6E55, 0x206E776F, 0x6D6D6F63, +0x3D646E61, 0x00000000, 0x000A0D52, 0x203A3051, +0x00000020, 0x203A3151, 0x00000020, 0x203A3251, +0x00000020, 0x203A3351, 0x00000020, 0x203A3451, +0x00000020, 0x61437748, 0x7262696C, 0x6F697461, +0x6620206E, 0x0A6C6961, 0x0000000D, 0x73696F4E, +0x61432065, 0x7262696C, 0x6F697461, 0x6166206E, +0x21216C69, 0x00000D0A, 0x00000072, 0x00205220, +0x00000D0A, 0x62735576, 0x7473725F, 0x00000A0D, +0x62735576, 0x7375735F, 0x646E6570, 0x00000A0D, +0x62735576, 0x7365725F, 0x000A0D6D, 0x00000042, +0x72746E49, 0x6D652051, 0x2C797470, 0x49677A20, +0x4972746E, 0x754E514E, 0x00003D6D, 0x654C7245, +0x0000006E, 0x00000049, 0x20746F4E, 0x756F6E65, +0x49206867, 0x4220514E, 0x0A0D6675, 0x00000000, +0x000000FF, 0x00020001, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x010E010D, 0x00020003, 0x01090108, 0x0002010A, +0x02000003, 0x02020201, 0x02040203, 0x02060205, +0x02020200, 0x02040203, 0x020C0207, 0x020E020D, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x010E010D, 0x00FF010F, 0x01090108, 0x010B010A, +0x020000FF, 0x02020201, 0x02040203, 0x02060205, +0x02020200, 0x02040203, 0x020C020B, 0x020E020D, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00205220, 0x00000046, 0x00000059, 0x73204142, +0x003D7165, 0x49544120, 0x0000204D, 0x00000000, +0x00000000, 0x002E0209, 0x80000101, 0x000409FA, +0x00FF0400, 0x05070000, 0x02000201, 0x82050700, +0x00020002, 0x03830507, 0x07010040, 0x40020405, +0x02090000, 0x0101002E, 0x09FA8000, 0x04000004, +0x000000FF, 0x02010507, 0x07000040, 0x40028205, +0x05070000, 0x00400383, 0x04050701, 0x00004002, +0x00000000, 0x00000000, 0x07090000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, }; + +const u32_t zcDKFwImageSize=12988; --- linux-2.6.28.orig/drivers/staging/otus/hal/hpfwspiu.c +++ linux-2.6.28/drivers/staging/otus/hal/hpfwspiu.c @@ -0,0 +1,655 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "../80211core/cprecomp.h" + +const u32_t zcFwImageSPI[]={ +0x0009000B, 0x4F222FE6, 0xB0187FFC, 0xE6000009, +0x943DD520, 0xC8406052, 0x2F028F03, 0x8FF93642, +0xD41D7601, 0x4E0BDE1D, 0xD41D0009, 0x00094E0B, +0x4E0BD41C, 0x7F040009, 0xA0214F26, 0x4F226EF6, +0xE205D119, 0x2122E400, 0x92222142, 0x8BFD4210, +0x450BD516, 0xD6160009, 0x0009460B, 0xE5FFD715, +0x2752655D, 0xE1FFD714, 0xD4145079, 0x1709CB01, +0x17112712, 0x2412E101, 0x4F26D411, 0x2410000B, +0xDE11DD10, 0x00094D0B, 0x00094E0B, 0x0009AFFA, +0x03E82710, 0x001C001C, 0x00116594, 0x00114EBE, +0x001165A4, 0x001165BC, 0x001D4004, 0x00114FA0, +0x00114378, 0x001C3510, 0x001C3624, 0x001E212C, +0x001164FC, 0x00114700, 0x0011589C, 0x2FA62F96, +0x2FC62FB6, 0x2FE62FD6, 0x7FC84F22, 0xD28DDD8C, +0x61D360D0, 0x80F47101, 0x420B6010, 0x200880F8, +0x6E038F10, 0xDB89D488, 0xD4896A40, 0x4B0BDC89, +0x67C065AC, 0x697CDE88, 0x41086193, 0x31984108, +0x3E1C4108, 0x66D284F8, 0x2008600C, 0x2E628F13, +0xE40084F4, 0xDA81670C, 0x3273624D, 0xA0D38B01, +0x644D0009, 0x35AC6543, 0x69436652, 0x39EC6B62, +0xAFF119B1, 0x88017404, 0x84F48B15, 0x2E70E700, +0xDA766E0C, 0x32E3627D, 0xA0C48B01, 0x677D0009, +0x6C7366A3, 0x65737604, 0x356C3CAC, 0x6D5264C2, +0xAFEF7708, 0xE2B024D2, 0x3020622C, 0x84F48B30, +0x650CEC00, 0xDA691F53, 0x55F3E904, 0x325362CD, +0xA0A88B01, 0x6CCD0009, 0x67C36EA3, 0x6BC37E04, +0x3BEC37AC, 0x6EB26D72, 0xDB62D461, 0x00094B0B, +0x410BD161, 0xD46164D3, 0x00094B0B, 0x450BD55E, +0xD45F64E3, 0x00094B0B, 0x61D3E600, 0x316C666D, +0x646D7601, 0x21E03493, 0x4E198FF7, 0x7C08AFD5, +0x622CE2B1, 0x8B113020, 0xD552D456, 0xDA56DC4F, +0x0009450B, 0x4A0BE400, 0xD75467C2, 0x470BDB52, +0x4B0B0009, 0xE900E403, 0x2E90A06D, 0x622CE2B2, +0x89683020, 0x622CE2B3, 0x8B1D3020, 0xDA45D44C, +0x4A0BD942, 0x65960009, 0x6792D44A, 0x1F74DD3B, +0x1F5D4D0B, 0xD639D448, 0x460BDB48, 0x55F455F4, +0x4B0BD936, 0xD44654FD, 0x490B6503, 0x5DF51F05, +0x1ED1EC04, 0x2EC0A047, 0x622CE2B4, 0x8B3E3020, +0xDA34D440, 0x4A0BDD31, 0x84F40009, 0x600C6CD2, +0x1F072F02, 0x1FC6C903, 0xE6001F08, 0xD73AE030, +0x6CF2DB3A, 0x1F790F65, 0xA0211FBA, 0x51F6E904, +0x6D63666D, 0x4C1536EC, 0xD2353D1C, 0x1F6B8F05, +0x89023C93, 0xA00264D3, 0xE50455F8, 0x420B64D3, +0x5BFB0009, 0xD61954FA, 0x460B65D3, 0x54F91B01, +0xDA1655B1, 0x7CFC4A0B, 0x06FDE030, 0x0F657604, +0x626D55F7, 0x8BDA3253, 0xA00484F4, 0xD4252E00, +0x420BD20E, 0x7F3865D2, 0x6EF64F26, 0x6CF66DF6, +0x6AF66BF6, 0x69F6000B, 0xE6006163, 0x4109A004, +0x76016256, 0x74042422, 0x8BF93612, 0x0009000B, +0x00117800, 0x00115FF0, 0x001164F6, 0x00114F2C, +0x001165C0, 0x001164F5, 0x0011611C, 0x00117804, +0x001165E0, 0x00114EBE, 0x00114F02, 0x001165F4, +0x001165FC, 0x00116600, 0x00114BF0, 0x001148FC, +0x00116618, 0x00116634, 0x00116640, 0x00114E56, +0x0011664C, 0x00116658, 0x0011667C, 0x00116670, +0x00114BC4, 0x00116688, 0x2F962F86, 0x2FB62FA6, +0x2FD62FC6, 0x4F222FE6, 0xE5007FD8, 0x6453E110, +0x6C534128, 0x655DEE0A, 0x46086653, 0x4608365C, +0x361C7501, 0x675D6043, 0x60C30F66, 0x37E3ED00, +0x816126C1, 0x81638162, 0x16D316D2, 0x8FEA16D4, +0x68F27404, 0xDAB3D9B2, 0x29821981, 0xD1B259F1, +0x2A921A91, 0x5BF35AF2, 0x5EF55DF4, 0x11A154F6, +0x11B321A2, 0x11D511B2, 0x11E711D4, 0x114911E6, +0x55F71148, 0xEE00DBA9, 0xDDA957F8, 0xD6A952F9, +0x1B5164E3, 0xDBA82B52, 0xEAB8D8A8, 0x2D72E945, +0x6AAC2622, 0x6EED4908, 0x4D086DE3, 0x3DEC61E3, +0x4D084108, 0x3DBC31EC, 0x410860C3, 0x81D12DC1, +0x4108E050, 0x41084008, 0x60C381D2, 0xE500318C, +0x81D334A2, 0x1D131DD2, 0x8D01D494, 0xD4911D54, +0xB08165D3, 0x64ED7E01, 0x8BDC3492, 0xDB94D18D, +0xD28B6812, 0x1B814829, 0x2FD26412, 0x2B92694D, +0xD98A6722, 0x1B734729, 0xD7876822, 0x1BA26A8D, +0xD28C6B72, 0x22B2D586, 0xE0035D72, 0x5E7412D2, +0x12E44018, 0xD6885176, 0x54781216, 0x1248E1FF, +0xD4856792, 0x6852127A, 0x28C1E703, 0x81916952, +0x6A52E050, 0x81A24008, 0x60C36B52, 0x6D5281B3, +0x6E521DD2, 0x62521E63, 0x1264E600, 0x46086563, +0x7501364C, 0x665D2612, 0x8BF83673, 0xE003D471, +0x40186542, 0x674225C1, 0x8171D274, 0xEE006842, +0x69421882, 0x1923E024, 0xE5806A42, 0x6B421AE4, +0x81B266E3, 0xD46D6C42, 0x655C81C3, 0x6D63666D, +0x616D7604, 0x31533D4C, 0x2DE28FF8, 0xD569D268, +0x74042422, 0x7F282452, 0x6EF64F26, 0x6CF66DF6, +0x6AF66BF6, 0x000B69F6, 0x664268F6, 0xC8036061, +0xE5008D04, 0xC9036061, 0x8B038802, 0x65635262, +0x24125124, 0x6053000B, 0x2FE62FD6, 0x7FEC4F22, +0x62536E53, 0x6D43E550, 0x4508E400, 0xE101A001, +0x60435224, 0x81212211, 0x60538123, 0x56E28122, +0x8BF53620, 0x16E4D250, 0xE61464F3, 0x65E3420B, +0xE4FC65E1, 0x2E512549, 0x65F361F1, 0x2F112149, +0xD14954D1, 0xE614410B, 0x607157D1, 0x2701CB01, +0x7F141DE1, 0x6EF64F26, 0x6DF6000B, 0x2FE62FD6, +0x7FEC4F22, 0x66536E53, 0x6D43E5FC, 0x20596061, +0x2601CB01, 0x326052E2, 0x12E48B06, 0x31E051E2, +0x52D18B04, 0x1E22A002, 0x5664AFF0, 0x64F3D236, +0x420BE614, 0x67E165E3, 0x2719E1FC, 0x67F12E71, +0x271954D1, 0x65F3D130, 0x410BE614, 0x52D12F71, +0xCB016021, 0x1DE12201, 0x4F267F14, 0x000B6EF6, +0x2FE66DF6, 0x624C4F22, 0x4208DE1B, 0xA0054200, +0x52523E2C, 0x5624D417, 0x2E62BF8E, 0x52E165E2, +0x8BF63520, 0x2622D61B, 0x000B4F26, 0x2FB66EF6, +0x2FD62FC6, 0x4F222FE6, 0xDB1CDC10, 0x66C252C1, +0x89403620, 0xC9036061, 0x893C8801, 0xDD18DE0B, +0x64E3BF63, 0x85036503, 0x620D66B2, 0x892B3262, +0xBF9BD403, 0xD4130009, 0x00094D0B, 0x0009AFE6, +0x001160DC, 0x001160E4, 0x001160EC, 0x00116114, +0x001164F8, 0x00116500, 0x001000C8, 0x00101680, +0x001E2108, 0x001C3D00, 0x00117880, 0x00117780, +0x00040020, 0x0026C401, 0x001142F8, 0x001164DC, +0x00114EBE, 0x0011669C, 0x64E3BF3E, 0x4D0BD406, +0xAFBB0009, 0xD2050009, 0x4F262262, 0x6DF66EF6, +0x000B6CF6, 0x00006BF6, 0x001166A0, 0x001C3D28, +0x2F962F86, 0x2FB62FA6, 0x2FD62FC6, 0x4F222FE6, +0xD23C7FFC, 0xC8036022, 0x2F018F3D, 0x0009A061, +0xC9036061, 0x893B8801, 0xD238D837, 0x420BD938, +0xE4006483, 0x6A036D03, 0x5C02490B, 0xD236DB35, +0x56D385D2, 0x650D6422, 0x4B0BE740, 0xD1326E03, +0x64126EED, 0x214234EC, 0x3DC05DD4, 0x85D28BEF, +0x70FF56D3, 0xE740650D, 0x6C034B0B, 0x490BDB2A, +0x66B2E403, 0x36CC6CCD, 0xE700D928, 0x2B62E5C8, +0x6473E650, 0x490BDC26, 0x6483655C, 0x65A34C0B, +0xEE01D124, 0xD11C21E2, 0x66125211, 0x8BBF3620, +0xDD22DE21, 0xDC23DB22, 0x65D252D1, 0x89183520, +0xC9036051, 0x89148801, 0xD114D41C, 0x0009410B, +0x36E05603, 0x65038F04, 0x2B20E201, 0x2C52AFEC, +0xD213D419, 0x0009420B, 0xE101D618, 0xAFE34118, +0x60F12612, 0x8902C804, 0x420BD215, 0x7F040009, +0x6EF64F26, 0x6CF66DF6, 0x6AF66BF6, 0x000B69F6, +0x000068F6, 0x001E2100, 0x001160E4, 0x0011453A, +0x00114BF0, 0x00114E0C, 0x00116714, 0x001159B0, +0x00114558, 0x001E212C, 0x00117880, 0x001160DC, +0x001164FC, 0x001164F8, 0x00116114, 0x001C3D30, +0x001140CC, 0xD6C2D5C1, 0x26226252, 0xC8016060, +0x000B8BFA, 0x2FE60009, 0xBFF34F22, 0xD2BD0009, +0xE405E100, 0x22402212, 0x6422DEB8, 0xE700D5B8, +0x25721E42, 0xC98F8451, 0xC9F0CB10, 0x8051CB02, +0xCB026050, 0x62522500, 0x2E22BFDC, 0xD6B250E4, +0x4F262602, 0x6EF6000B, 0x4F222FD6, 0x0009BFDB, +0x620CDDAE, 0x60D02D22, 0x8906C801, 0x0009BFD3, +0x2D22620C, 0xC80160D0, 0x4F268BF8, 0x6DF6000B, +0x4F222FE6, 0x6E43BFE8, 0xE100D2A2, 0x22E02212, +0x6422D59E, 0xE600DE9E, 0x2E621542, 0xC9F084E1, +0x80E1CB01, 0xCB0260E0, 0x67E22E00, 0x4F262572, +0x6EF6AFA8, 0xE406AFE4, 0xE404AFE2, 0xBFF94F22, +0xE4C70009, 0x644CBFDC, 0x4F26AFF6, 0xE406AFD8, +0xE404AFD6, 0x4F222FE6, 0x6E43BFF8, 0xD58DD28D, +0xE401E100, 0x221260E3, 0x80512240, 0x6622D187, +0xE700DE87, 0x2E721162, 0xC9F084E1, 0x80E1CB02, +0xCB0260E0, 0x62E22E00, 0x2122BF7C, 0xAFDF4F26, +0x2FD66EF6, 0x4F222FE6, 0xBFCB6D53, 0xBF9B6E43, +0xD27C0009, 0x22E061D3, 0x6022DE7D, 0x411821E9, +0x201BC9FF, 0x2202D577, 0xD6768453, 0x60D38051, +0xD4728053, 0xD1726762, 0x1472ED00, 0x841121D2, +0xCB04C9F0, 0x60108011, 0x2100CB02, 0xBF516212, +0x4F262422, 0xAFA76EF6, 0x65436DF6, 0xAFD0E4D8, +0x6543644C, 0xAFCCE4D8, 0x2FC6644C, 0x2FE62FD6, +0x6E534F22, 0xBF676D43, 0xD7626C63, 0x27D0D264, +0x61E36072, 0x41182129, 0x201BC9FF, 0x2702D45D, +0xD15B8443, 0x60E38041, 0xDE588043, 0xE6006472, +0x21621E42, 0x65DC8411, 0x60C36203, 0x4008C907, +0x67034008, 0xE29F6023, 0x622CC98F, 0x3520207B, +0x80118D18, 0x7C048411, 0x60C36603, 0x6203C90F, +0xC9F06063, 0x8011202B, 0x880B6053, 0x84118B14, +0xC90F6603, 0xC90F7001, 0x60636203, 0x202BC9F0, +0x8011A00A, 0x7C018411, 0x60C36603, 0x6203C90F, +0xC9F06063, 0x8011202B, 0xCB026010, 0x62122100, +0x2E22BEF0, 0xD63C50E4, 0x4F262602, 0x6DF66EF6, +0x6CF6000B, 0x2FC62FB6, 0x2FE62FD6, 0x6C634F22, +0x6E436D53, 0x6B73BF36, 0x0009BF06, 0x61D3D231, +0xDE3322E0, 0x21E96022, 0xC9FF4118, 0xD42D201B, +0x84432202, 0x8041D72F, 0x804360D3, 0x6622D427, +0x1462D127, 0x14C327C2, 0x21C2EC00, 0x7B048411, +0x60B36D03, 0x6503C90F, 0xC9F060D3, 0x8011205B, +0xCB026010, 0x62122100, 0x4F262422, 0x6DF66EF6, +0xAEAF6CF6, 0x2FB66BF6, 0x2FD62FC6, 0x4F222FE6, +0x6C536D63, 0xBEFD6E43, 0xBECD6B73, 0xD2150009, +0x22E061C3, 0x6022DE16, 0x411821E9, 0x201BC9FF, +0x2202D110, 0xD60F8413, 0x60C38011, 0xDE0B8013, +0xD40B6762, 0xEC006BBD, 0x1EB51E72, 0x844124C2, +0xC9F04B21, 0x8041CB04, 0xE1406040, 0x2400CB06, +0xE5006242, 0x4B212E22, 0x4128A014, 0x001D1200, +0x00116528, 0x00116530, 0x00116538, 0x00116544, +0x00FFFFFF, 0x00116534, 0x6053655D, 0x06DE4008, +0x21627501, 0x32B3625D, 0x4F268BF6, 0x6DF66EF6, +0xAE5F6CF6, 0x4F226BF6, 0xBF73677C, 0xAEB3644C, +0x4F224F26, 0xBFA6677D, 0xAEAD644C, 0x4F224F26, +0xE500E49F, 0xBF08E603, 0x4F26644C, 0x600C000B, +0xE49F4F22, 0xE603E500, 0x644CBEFF, 0x4F264019, +0x600D000B, 0x6543665C, 0xE403AEF7, 0x6543665C, +0xE40BAEF3, 0xD175D674, 0x60436262, 0xC8012122, +0x8F016010, 0xC9EFCB10, 0x62122100, 0x2622000B, +0x4F222FE6, 0xE0004F13, 0xBE2C401E, 0xD56C6E43, +0x2522620C, 0xE401BFE6, 0x6063D669, 0x60ECCF80, +0x89072008, 0x89098801, 0x890D8802, 0x89118803, +0x0009A013, 0xC9E36060, 0x2600A00F, 0xCB106060, +0xCB04C9F7, 0x2600A009, 0xCB106060, 0xCB08C9FB, +0x2600A003, 0xCB1C6060, 0xD5592600, 0xBE616252, +0xE400642C, 0x4F264F17, 0x6EF6AFBC, 0x2F962F86, +0x2FB62FA6, 0x2FD62FC6, 0x4F222FE6, 0x60C36C7C, +0x6A638802, 0x69538F09, 0x65436290, 0x662CE4AF, +0xBEF7E701, 0xA00A644C, 0x2CC80009, 0x88018901, +0x65438B05, 0xE600E4AF, 0xBEEBE701, 0xBDD1644C, +0xED010009, 0xDE43EBAF, 0xE800A02C, 0x0009BDF4, +0x60C3D141, 0x8802E200, 0xD5402122, 0x21B08D06, +0x89082CC8, 0x890A8801, 0x0009A00C, 0x009C60D3, +0xA007D639, 0xD2388061, 0xA0036083, 0xD2368021, +0x802160D3, 0xD1356412, 0x1E42E600, 0x84512162, +0xC9F07D01, 0x8051CB02, 0xCB026050, 0x67122500, +0x2E72BDA0, 0x8BD13DA2, 0x0009BDF6, 0x0009BDA3, +0x620CD627, 0x4F262622, 0x6DF66EF6, 0x6BF66CF6, +0x69F66AF6, 0x68F6000B, 0xE702AF98, 0x2F962F86, +0x2FB62FA6, 0x2FD62FC6, 0x4F222FE6, 0x3F3C9331, +0x0F569030, 0xE8FF70FC, 0x688C0F46, 0xE900A049, +0x4018E010, 0xE50404FE, 0xBF33349C, 0x88FF6A43, +0x901F893E, 0xE1100CFE, 0x41183C98, 0x8B033C16, +0x64A3BE1B, 0x0009A031, 0x4018E010, 0xED000BFE, +0xA0073BCC, 0x64D36EF3, 0xBF1F34BC, 0x2E00E501, +0x7E017D01, 0x8BF63DC2, 0x64A3BE07, 0xA01AED00, +0xEFF86EF3, 0x00001004, 0x001D1204, 0x0011652C, +0x00116544, 0x001D1200, 0x00116530, 0x00116528, +0x666C66E0, 0x89043680, 0x35BC65D3, 0xBE51E701, +0x7D01E402, 0x3DC27E01, 0xE1108BF2, 0x391C4118, +0x90547904, 0x391201FE, 0x93518BB2, 0x4F263F3C, +0x6DF66EF6, 0x6BF66CF6, 0x69F66AF6, 0x68F6000B, +0x676D6253, 0x66236543, 0xE402AEC3, 0x2FA62F96, +0x2FC62FB6, 0x2FE62FD6, 0x697D4F22, 0x4A216A93, +0x4A084A21, 0x6C436D63, 0xA0086B73, 0x64C36E53, +0x669365D3, 0x6BBDBFE4, 0x3DAC3CBC, 0x6EEF3EB8, +0x8BF42EE8, 0x4F26E000, 0x6DF66EF6, 0x6BF66CF6, +0x000B6AF6, 0x2FA669F6, 0x2FC62FB6, 0x2FE62FD6, +0xEC004F22, 0x6B536EC3, 0xA0066D43, 0x64D3EA01, +0x65A3BEA8, 0x7D013C0C, 0x3EB27E01, 0x60C38BF7, +0x6EF64F26, 0x6CF66DF6, 0x000B6BF6, 0x10046AF6, +0x00001008, 0x0009000B, 0x2FD62FC6, 0x4F222FE6, +0x6D436C53, 0xEE00A004, 0x7E0164D4, 0x644CBFF2, +0x8BF93EC2, 0x6EF64F26, 0x000B6DF6, 0xE5006CF6, +0x6643A002, 0x76017501, 0x22286260, 0xAFE38BFA, +0x2FE60009, 0x75076253, 0xE1086753, 0x6043EE0A, +0x4409C90F, 0x650330E2, 0x8D014409, 0xE630E637, +0x4110365C, 0x8FF22760, 0xE00077FF, 0x000B8028, +0x4F226EF6, 0xBFE47FEC, 0xBFD865F3, 0x7F1464F3, +0x000B4F26, 0x4F22E000, 0xBFDA7FEC, 0x64F365F3, +0x7406BFCD, 0x4F267F14, 0xE000000B, 0x4F222FE6, +0x62537FEC, 0x65F36E43, 0x6423BFCB, 0x64E3BFBF, +0x64F3BFBD, 0xBFBAD403, 0x7F140009, 0x000B4F26, +0x00006EF6, 0x001166A4, 0xE4FDD29A, 0xD79A6122, +0x22122149, 0x74016022, 0x2202CB01, 0xD5976622, +0x22622649, 0xC8406070, 0x60528902, 0x2502CB04, +0xE1F76452, 0x25422419, 0xE7016052, 0x2502C9CF, +0xE6026052, 0x2502CB03, 0x15624718, 0x1573000B, +0xD78CD58B, 0xD48DD28C, 0xE600E100, 0x27112511, +0xAFD12210, 0x664C2461, 0x4600D289, 0x6060362C, +0x000BCB10, 0x654C2600, 0x4500D285, 0x6650352C, +0x2619E1EF, 0x2560000B, 0xD282664C, 0x362C4600, +0xCB106060, 0x2600000B, 0xD27E654C, 0x352C4500, +0xE1EF6650, 0x000B2619, 0x664C2560, 0x4600D278, +0x6060362C, 0x000BCB08, 0x654C2600, 0x4500D274, +0x6650352C, 0x2619E1F7, 0x2560000B, 0xD271664C, +0x362C4600, 0xCB086060, 0x2600000B, 0xD26D654C, +0x352C4500, 0xE1F76650, 0x000B2619, 0x624C2560, +0x4200D667, 0x6020326C, 0x4021C908, 0x40214021, +0x600C000B, 0xD663624C, 0x326C4200, 0xC9086020, +0x40214021, 0x000B4021, 0xD15F600C, 0x341C644C, +0x000B6240, 0xD15D602C, 0x341C644C, 0x000B6240, +0x2FE6602C, 0x6E434F22, 0xE60A645C, 0x89143467, +0x0009BFEB, 0x60EC640C, 0x8B028801, 0xA002E00F, +0x44092409, 0x624C4409, 0x3263E60A, 0xBFE28905, +0x620C644C, 0xC8806023, 0xE2008B00, 0x4F266023, +0x6EF6000B, 0xD64A4F22, 0x88016062, 0xB2458B03, +0xA0030009, 0xD2470009, 0x2260E640, 0xE200D646, +0x000B4F26, 0x4F222622, 0x6062D641, 0x8B018802, +0x0009B28E, 0xE200D640, 0x000B4F26, 0xD53C2622, +0xE100D43C, 0x2512E701, 0x2470000B, 0xE604D239, +0x2260000B, 0xD4394F22, 0x410BD139, 0xD5390009, +0x6650E1FD, 0x2619D238, 0x2560E700, 0x000B4F26, +0x4F222270, 0xD132D435, 0x0009410B, 0xE7FBD531, +0x26796650, 0x000B4F26, 0x4F222560, 0xD12CD430, +0x0009410B, 0xE7F7D52B, 0x26796650, 0x000B4F26, +0xD5282560, 0x6250942D, 0x000B2249, 0xD5252520, +0x6250E4BF, 0x000B2249, 0x4F222520, 0x8522D225, +0x2008600D, 0x88018911, 0x88038913, 0x88058915, +0x88068942, 0x88088948, 0x8809894E, 0x880A8954, +0x880B895A, 0xA0678960, 0xB0690009, 0xA0640009, +0xB077600C, 0xA0600009, 0xB080600C, 0xA05C0009, +0xFF7F600C, 0x001E2148, 0x001E1000, 0x001E1108, +0x00116570, 0x00116572, 0x00116591, 0x00116554, +0x001E103F, 0x001E105F, 0x001E102F, 0x001E1090, +0x00116578, 0x001E100B, 0x00116574, 0x001166A8, +0x00114EBE, 0x001E1028, 0x00116590, 0x001166B4, +0x001166C4, 0x00116548, 0x6260D684, 0x8B2B2228, +0x0009B061, 0x600CA029, 0x6260D680, 0x8B232228, +0x0009B069, 0x600CA021, 0x6260D67C, 0x8B1B2228, +0x0009B0C7, 0x600CA019, 0x6260D678, 0x8B132228, +0x0009B0CD, 0x600CA011, 0x6260D674, 0x8B0B2228, +0x0009B125, 0x600CA009, 0x6260D670, 0x8B032228, +0x0009B13D, 0x600CA001, 0x4F26E000, 0x0009000B, +0xD26CD16B, 0xD56C8412, 0x4000C90F, 0xD76B012D, +0xE403D66B, 0xE20F611C, 0x2540E001, 0x25202712, +0x2602000B, 0xE601D262, 0x30668523, 0xE0008D05, +0xD663D260, 0xE0018122, 0x000B2602, 0xD25C0009, +0x600D8523, 0x89052008, 0x8B0A8801, 0x6060D65D, +0x2600CB01, 0xD457D65A, 0xE001E101, 0x000B2612, +0x000B8142, 0xD152E000, 0x8513E501, 0x640D4518, +0x66033453, 0xE0008D05, 0xD551D253, 0x2260E001, +0x000B2502, 0x4F220009, 0x8513D149, 0x6453650D, +0x62494419, 0x227D672E, 0x8801602C, 0x88028909, +0x88038910, 0x8806891A, 0x88078935, 0xA04C893B, +0xD5460009, 0x6652D746, 0x2762D446, 0x622C6261, +0x2421A038, 0x2228625C, 0xD4438B3F, 0x6642D540, +0x2562D440, 0x24018561, 0x6203A02C, 0x2008605C, +0x88108907, 0x88208908, 0x88308909, 0xA02C890A, +0xD23A0009, 0x6222A008, 0xA005D239, 0xD2396222, +0x6222A002, 0x6262D638, 0xD432D531, 0x66212522, +0xA00F626C, 0xD6352421, 0x6261D52D, 0x622CD42D, +0xA0072562, 0xD6322421, 0x8561D529, 0x2562D429, +0x62032401, 0x662D8515, 0x3617610D, 0x65038F01, +0xB0CB2451, 0xA0010009, 0xE000E001, 0x000B4F26, +0xD6190009, 0xD427E101, 0x65412610, 0xD118D717, +0xE20F655D, 0x2752E001, 0x000B2620, 0x2FE62102, +0xD20F4F22, 0x640C8523, 0x8B082448, 0xD511D61D, +0x2621E200, 0x940F8451, 0xA0482049, 0xDE0D8051, +0xC84060E0, 0xE2018D32, 0x89443427, 0xD216D615, +0x2641420B, 0x0009A030, 0x0000FF7F, 0x00116591, +0x00116548, 0x00116554, 0x001E1100, 0x001E100C, +0x00116574, 0x001E1000, 0x001E1001, 0x0011657C, +0x0011655C, 0x00116560, 0x00116564, 0x00116580, +0x00116584, 0x00116588, 0x0011658C, 0x00116774, +0x0011677E, 0x0011656E, 0x00115DCA, 0x89123427, +0xD294D693, 0x2641420B, 0xCB8084E1, 0x80E1B0F5, +0xD69160E0, 0x2E00CB04, 0xC93F6060, 0xD68F2600, +0xA001E001, 0xE0002602, 0x000B4F26, 0xD68C6EF6, +0xC8806060, 0xD2868919, 0x88016021, 0xD2898B15, +0x8524E501, 0x89103056, 0xE203D187, 0x2120D487, +0xE00B6541, 0x0656655D, 0xE40FD585, 0x2140E702, +0xD77E2571, 0x000BE001, 0x000B2702, 0x2FE6E000, +0xDE804F22, 0xC88084E1, 0xD57A892C, 0x20088554, +0x61038F28, 0x8553D77C, 0x64036672, 0x8566650C, +0x3520620C, 0xD6798B1E, 0x651CD774, 0x2651644C, +0x60E02741, 0x8904C840, 0x420BD275, 0xA0030009, +0xD2680009, 0x0009420B, 0x0009B09F, 0xE201D167, +0x60E02122, 0xCB04D464, 0x60402E00, 0x2400C93F, +0x6023A001, 0x4F26E000, 0x6EF6000B, 0x2FB62FA6, +0x2FD62FC6, 0xDA622FE6, 0x66A1E240, 0x3622DC5E, +0x62638900, 0x6ED36D2C, 0x4E2136D8, 0x4E212A61, +0xDB61D460, 0xE700A00F, 0x770162B2, 0x71026123, +0x66212B12, 0x71026213, 0x61212B12, 0x651D666D, +0x356C4528, 0x627C2452, 0x8BED32E3, 0xC90360D3, +0x8B108803, 0x617367B2, 0x2B127102, 0x71026E13, +0x2B126571, 0x655D6DE1, 0x422862DD, 0x325CE107, +0xA00C2C10, 0x88022422, 0xA0038B01, 0x8801E203, +0xE2018B05, 0x66B22C20, 0x655D6561, 0xE60F2452, +0x67A12C60, 0x8B052778, 0xDD38DC44, 0xEB01EA00, +0x2DB22CA2, 0x6DF66EF6, 0x6BF66CF6, 0x6AF6000B, +0x2FE62FD6, 0xE240DD36, 0x362266D1, 0x62638900, +0x3678672C, 0x7703DE38, 0x47212D61, 0x64E2D635, +0xA00E4721, 0x6562E100, 0x62537101, 0x74012450, +0x24204219, 0x45297401, 0x74012450, 0x24504519, +0x621C7401, 0x8BEE3273, 0x66E24200, 0x420061D1, +0x2118362C, 0x2E628F06, 0xDD1CD728, 0xE501E400, +0x2D522742, 0x000B6EF6, 0x2FD66DF6, 0x4F222FE6, +0xED0AEE01, 0x64E3BC97, 0xBC9C64E3, 0x62EC7E01, +0x8BF732D7, 0xBC9FEE01, 0x64E364E3, 0x7E01BCA4, +0x32D762EC, 0x4F268BF7, 0x000B6EF6, 0xD1186DF6, +0xD418920D, 0x72122122, 0x2422D617, 0xD7177204, +0x72202622, 0x2722D116, 0x000B7230, 0x137A2122, +0x0011656E, 0x00115ED6, 0x001E1015, 0x00116574, +0x001E1001, 0x00116548, 0x001E1100, 0x00116572, +0x00116560, 0x001E1000, 0x00116564, 0x00116570, +0x00115DCA, 0x001E100C, 0x0011655C, 0x00116578, +0x0011657C, 0x00116580, 0x00116584, 0x00116588, +0x0011658C, 0x4F222FE6, 0xD6507FFC, 0x88016060, +0xE2018951, 0x2620BFBB, 0xD54ED14D, 0xDE4E6010, +0x64E36552, 0x7402C840, 0x8D22D14C, 0xD24C7502, +0xE601D74C, 0xE7042722, 0x76016255, 0x626C2421, +0x8FF93273, 0xD4437402, 0x6242E601, 0x640D8528, +0x67494419, 0x275D657E, 0x81E4607C, 0xE417D542, +0x67557601, 0x3243626C, 0x8FF92171, 0xA0207102, +0xD23E0009, 0xE601D73B, 0xE7042722, 0x76016255, +0x626C2421, 0x8FF93273, 0xD4327402, 0x6242E601, +0x640D8528, 0x67494419, 0x275D657E, 0x81E4607C, +0xE417D533, 0x67557601, 0x3243626C, 0x8FF92171, +0x924A7102, 0xD2262E21, 0x5E23D72E, 0x64F22FE2, +0x604365F2, 0x2700C980, 0xC9606043, 0x80716103, +0xC9036043, 0x80724519, 0x65F2605C, 0x817266F2, +0x46194629, 0x606C4529, 0x4018645C, 0x8173304C, +0x21185E23, 0x64F22FE2, 0x6E4C62F2, 0x602C4219, +0x66F262F2, 0x46294018, 0x461930EC, 0x42298174, +0x652C606C, 0x305C4018, 0x81758F07, 0x0009BC9D, +0x2228620C, 0xA00A8908, 0x60130009, 0x8B038840, +0x0009B009, 0x0009A003, 0xE202D60F, 0x7F042622, +0x000B4F26, 0x000B6EF6, 0x060A0009, 0x00116590, +0x001E1000, 0x0011657C, 0x00116774, 0x00116780, +0x00116718, 0x00116564, 0x00116748, 0x00116746, +0x0011671A, 0x00116548, 0x00116574, 0x4F222FE6, +0x84E9DE8E, 0x2448640C, 0xB18B8901, 0xD28C0009, +0x26686620, 0x60E08902, 0x2E00C9BF, 0x000B4F26, +0x000B6EF6, 0x2FE60009, 0xDE864F22, 0x60E0D686, +0xCBC0D486, 0x62602E00, 0xC803602C, 0x40218904, +0x70014021, 0x6603A002, 0x66034009, 0xD680616D, +0xE500A004, 0x75016262, 0x74042422, 0x3213625D, +0xD27C8BF8, 0x0009420B, 0xC9BF84E2, 0x4F2680E2, +0x6EF6000B, 0x2FE62FD6, 0x7FFC4F22, 0x6260D676, +0x89402228, 0xD56DE100, 0x60502610, 0xCB40D473, +0x2500440B, 0x8D052008, 0x62E06E03, 0x7104612C, +0x2F11A006, 0xD46ED666, 0xDD6E6760, 0x657C4D0B, +0xE23C6D1D, 0x8B033D27, 0xD26CD46B, 0x0009420B, +0x4D214D21, 0xA005D76A, 0x66E6E400, 0x357C4508, +0x74012562, 0x35D3654D, 0xD7668BF7, 0x6E72E003, +0x81E14018, 0x6E7260F1, 0x81E2700C, 0xD4626172, +0xDD628113, 0x65724D0B, 0xD652D261, 0x2212E101, +0xC93F6060, 0x7F042600, 0x6EF64F26, 0x6DF6000B, +0x2FC62FB6, 0x2FE62FD6, 0xD25A4F22, 0x6B436E73, +0x420B6C53, 0x20086D63, 0x61038F08, 0xD24FD456, +0x6EF64F26, 0x6CF66DF6, 0x6BF6422B, 0x21B060C3, +0x60D38011, 0xE5008111, 0x64BCA007, 0x6053655D, +0x665300EC, 0x7501361C, 0x625D8064, 0x8BF53243, +0x6060D636, 0x2600C9BF, 0x6EF64F26, 0x6CF66DF6, +0x6BF6000B, 0x7FC44F22, 0x720262F3, 0x22512F41, +0x45297202, 0x60632251, 0xE5C4E682, 0x67F38121, +0x655C666C, 0xE408BFBC, 0x4F267F3C, 0x0009000B, +0x2F962F86, 0x2FB62FA6, 0x2FD62FC6, 0x4F222FE6, +0xE1007FC4, 0x6513ECFF, 0x6B136CCD, 0xDE34D733, +0xEDFF64F3, 0xD833EA04, 0x6053655C, 0x027D4000, +0x32C0622D, 0x66038D0D, 0x09ED6063, 0x2491027D, +0x24217402, 0x698202ED, 0x3928622D, 0x74022892, +0x75017104, 0x6063625C, 0x07D532A2, 0x0EB58FE4, +0x2448641C, 0xE6808905, 0x67F3E5C5, 0xBF7F666C, +0x7F3C655C, 0x6EF64F26, 0x6CF66DF6, 0x6AF66BF6, +0x000B69F6, 0xD11C68F6, 0x6012D21C, 0xCB20E405, +0x2102E500, 0x000B2242, 0x00002252, 0x001E1017, +0x001164F6, 0x001E1015, 0x001E10BF, 0x00117800, +0x001E10FC, 0x001140CC, 0x001164FC, 0x0011602E, +0x001166D0, 0x00114F2C, 0x001166EC, 0x00114EBE, +0x0011788C, 0x001164F8, 0x001160DC, 0x001145BC, +0x001E2130, 0x00115FF0, 0x001166F4, 0x00116510, +0x00116518, 0x00116710, 0x001C3500, 0x001D4004, +0xD565D164, 0xE400D765, 0x2142E20F, 0x17411154, +0xD5632722, 0x9669D763, 0x15412572, 0x96661562, +0xE6011565, 0xD5601165, 0x666CE6F8, 0x25422542, +0x25422542, 0x25422542, 0x25622542, 0x7601E727, +0x67632572, 0x25627797, 0xE7042572, 0x2572E248, +0xE2192522, 0xE2702522, 0x25422542, 0x25422542, +0x25222542, 0x2522E20C, 0x25422542, 0x25422542, +0x25422542, 0x25422542, 0x000B154A, 0xE2081145, +0x0009422B, 0x2FE62FD6, 0x7FFC4F22, 0xC8206043, +0x6E438D02, 0x0009BE75, 0xC81060E3, 0xBE728901, +0x60E30009, 0x8901C840, 0x0009BE94, 0xC80160E3, +0xDD3E8938, 0xC80260D0, 0x2F008D03, 0x460BD63C, +0x60F00009, 0x8902C804, 0x460BD63A, 0x62F00009, +0xC8806023, 0x60D08902, 0x2D00C97F, 0xC8016023, +0xD6358906, 0x0009460B, 0x0009A007, 0x51630601, +0x8902C808, 0x460BD631, 0x60F00009, 0x8902C810, +0x420BD22F, 0xD52F0009, 0x88026052, 0xD22E8B03, +0xA005E604, 0x88012260, 0xD22B8B02, 0x2260E601, +0x2522E200, 0xC88060E3, 0xD628892E, 0x60E36E60, +0x8902C880, 0x420BD226, 0x60E30009, 0x8902C840, +0x420BD224, 0x60E30009, 0x8902C802, 0x420BD222, +0x60E30009, 0x890EC804, 0x410BD120, 0xBF120009, +0xBF4D0009, 0xD51E0009, 0x6050D41E, 0xC908D71E, +0xBF842500, 0x60E32472, 0x8905C808, 0x7F04D21B, +0x6EF64F26, 0x6DF6422B, 0x4F267F04, 0x000B6EF6, +0x00006DF6, 0x001C581C, 0xA000A000, 0x001D0100, +0x001D4000, 0x00040021, 0x001C589C, 0x001E1021, +0x001150C4, 0x001150E6, 0x00115724, 0x001150FE, +0x0011510C, 0x00116574, 0x001E100B, 0x001E1028, +0x00115162, 0x0011516E, 0x00115114, 0x00115132, +0x001E1000, 0x0010F100, 0x12345678, 0x0011514A, +0x644CD6A7, 0x000B346C, 0xD6A62450, 0x346C644C, +0x2450000B, 0x644CD6A4, 0x000B346C, 0x625C2450, +0x4208616D, 0x42084119, 0x42006019, 0x670E614C, +0xD49E321C, 0x4200207D, 0x324CC90F, 0x2200000B, +0x4208625C, 0x42004208, 0x324C644C, 0x4200D498, +0x000B324C, 0x2FE62260, 0x614C4F12, 0x4100D493, +0x6710314C, 0xE29F666D, 0x27294619, 0x6E536269, +0x672E6573, 0x4221227D, 0x42214221, 0x7601662C, +0xE4014608, 0x34E84608, 0x644C4600, 0x071A0467, +0x2150257B, 0x000B4F16, 0x4F226EF6, 0xD2857FE8, +0x88016021, 0xD2848B7B, 0x26686621, 0xD2838B77, +0x26686621, 0xE50F8B73, 0xE401BFA2, 0xBFA4E501, +0xE586E400, 0xE400655C, 0x2F50BFA4, 0xBFA1E401, +0xE602E506, 0x60634618, 0x81F2E401, 0x6543BF9F, +0xE40185F2, 0xBFAB6543, 0x85F26603, 0x6543E401, +0x6603BFB1, 0xE40265F0, 0x6053756C, 0x80F8BF80, +0xBF82E402, 0x84F8E512, 0x7090E402, 0x6503BF82, +0x4618E602, 0x81F66063, 0xBF80E402, 0x85F6E500, +0x6603E402, 0xE500BF8C, 0xE40285F6, 0xBF926603, +0xE5FEE500, 0xE010655C, 0xBF61E403, 0xE5130F54, +0xE40EBF63, 0x05FCE010, 0xBF63E40E, 0xE5007585, +0xBF64E403, 0xE500E640, 0xBF71E403, 0xE500E640, +0xBF78E403, 0xE5FFE640, 0xE014655C, 0xBF47E404, +0xE40F0F54, 0xE504BF49, 0x05FCE014, 0xBF49E40F, +0xE5017584, 0xBF4AE640, 0xE501E404, 0xBF57E640, +0xE501E404, 0xE404E640, 0xAF5C7F18, 0x7F184F26, +0x000B4F26, 0x4F220009, 0xD2427FF0, 0x88016021, +0xD2418B71, 0x26686621, 0xD2408B6D, 0x26686621, +0xE50F8B69, 0xE401BF1C, 0xBF1EE501, 0xE586E400, +0xE400655C, 0x2F50BF1E, 0xBF1BE401, 0xE401E506, +0xBF1C6543, 0xE401E640, 0xBF296543, 0xE401E640, +0xBF306543, 0x65F0E640, 0x756CE402, 0xBEFF6053, +0xE40280F4, 0xE512BF01, 0xE40284F4, 0xBF017090, +0xE6406503, 0xBF02E402, 0xE640E500, 0xBF0FE402, +0xE640E500, 0xBF16E402, 0xE5FEE500, 0x6053655C, +0xBEE5E403, 0xE51380F8, 0xE40EBEE7, 0xE40E84F8, +0xBEE77085, 0xE5006503, 0xBEE8E640, 0xE500E403, +0xBEF5E640, 0xE500E403, 0xBEFCE640, 0xE5FFE403, +0x6053655C, 0xBECBE404, 0xE40F80FC, 0xE504BECD, +0xE40F84FC, 0xBECD7083, 0xE5016503, 0xBECEE640, +0xE501E404, 0xBEDBE640, 0xE501E404, 0xE404E640, +0xAEE07F10, 0x7F104F26, 0x000B4F26, 0x00000009, +0x001E102F, 0x001E1080, 0x001E1090, 0x001E103F, +0x001E103E, 0x0011656E, 0x00116570, 0x00116572, +0xD21DD11C, 0x66206010, 0x676C7001, 0x3700C90F, +0xE5008D13, 0x67106210, 0x7701622C, 0x64232170, +0xD6166010, 0x44084408, 0x3428C90F, 0x62602100, +0x7201D513, 0x44082620, 0x000B354C, 0xD10F6053, +0x25586510, 0xE6008D13, 0xD60DD40B, 0x655C6540, +0x47086753, 0x37584708, 0x47086540, 0x24507501, +0x367C6040, 0x2400C90F, 0x72FF6210, 0x000B2120, +0x00006063, 0x001164F5, 0x001164F4, 0x001164F6, +0x0011611C, 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, 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, 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, +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, 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, 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, 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, +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, 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, 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, 0x544F0D0A, 0x53205355, 0x46204950, +0x00003A57, 0x2074634F, 0x32203220, 0x20373030, +0x333A3831, 0x36343A32, 0x00000000, 0x00000D0A, +0x42707372, 0x3D206675, 0x554E203D, 0x202C4C4C, +0x6E49677A, 0x4E497274, 0x6D754E51, 0x0000003D, +0x52504545, 0x57204D4F, 0x65746972, 0x6461202C, +0x003D7264, 0x6C617620, 0x0000003D, 0x00000A0D, +0x5A205746, 0x4D435F4D, 0x4C465F44, 0x5F485341, +0x53415245, 0x000A0D45, 0x5A205746, 0x4D435F4D, +0x4C465F44, 0x5F485341, 0x534B4843, 0x0A0D4D55, +0x00000000, 0x2D495053, 0x72646461, 0x0000003D, +0x2D495053, 0x676E656C, 0x003D6874, 0x2D495053, +0x736B6863, 0x003D6D75, 0x5A205746, 0x4D435F4D, +0x4C465F44, 0x5F485341, 0x44414552, 0x00000A0D, +0x61202072, 0x3D726464, 0x00000000, 0x72202020, +0x75427073, 0x00003D66, 0x6E6B6E55, 0x206E776F, +0x6D6D6F63, 0x3D646E61, 0x00000000, 0x00000072, +0x00205220, 0x00000D0A, 0x62735576, 0x7473725F, +0x00000A0D, 0x62735576, 0x7375735F, 0x646E6570, +0x00000A0D, 0x62735576, 0x7365725F, 0x000A0D6D, +0x72746E49, 0x6D652051, 0x2C797470, 0x49677A20, +0x4972746E, 0x754E514E, 0x00003D6D, 0x654C7245, +0x0000006E, 0x20746F4E, 0x756F6E65, 0x49206867, +0x4220514E, 0x0A0D6675, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x002E0209, 0x80000101, +0x000409FA, 0x00FF0400, 0x05070000, 0x02000201, +0x82050700, 0x00020002, 0x03830507, 0x07010040, +0x40020405, 0x02090000, 0x0101002E, 0x09FA8000, +0x04000004, 0x000000FF, 0x02010507, 0x07000040, +0x40028205, 0x05070000, 0x00400383, 0x04050701, +0x00004002, 0x00000000, 0x00000000, 0x07090000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, }; + +const u32_t zcFwImageSPISize=10156; --- linux-2.6.28.orig/drivers/staging/otus/hal/hpmain.c +++ linux-2.6.28/drivers/staging/otus/hal/hpmain.c @@ -0,0 +1,4643 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "../80211core/cprecomp.h" +#include "hpani.h" +#include "hpusb.h" +#include "otus.ini" + +extern const u32_t zcFwImage[]; +extern const u32_t zcFwImageSize; +extern const u32_t zcDKFwImage[]; +extern const u32_t zcDKFwImageSize; +extern const u32_t zcFwImageSPI[]; +extern const u32_t zcFwImageSPISize; + +#ifdef ZM_OTUS_LINUX_PHASE_2 +extern const u32_t zcFwBufImage[]; +extern const u32_t zcFwBufImageSize; +extern const u32_t zcP2FwImage[]; +extern const u32_t zcP2FwImageSize; +#endif +extern void zfInitCmdQueue(zdev_t* dev); +extern u16_t zfIssueCmd(zdev_t* dev, u32_t* cmd, u16_t cmdLen, + u16_t src, u8_t* buf); +extern void zfIdlRsp(zdev_t* dev, u32_t* rsp, u16_t rspLen); +extern u16_t zfDelayWriteInternalReg(zdev_t* dev, u32_t addr, u32_t val); +extern u16_t zfFlushDelayWrite(zdev_t* dev); +extern void zfUsbInit(zdev_t* dev); +extern u16_t zfFirmwareDownload(zdev_t* dev, u32_t* fw, u32_t len, u32_t offset); +extern u16_t zfFirmwareDownloadNotJump(zdev_t* dev, u32_t* fw, u32_t len, u32_t offset); +extern void zfUsbFree(zdev_t* dev); +extern u16_t zfCwmIsExtChanBusy(u32_t ctlBusy, u32_t extBusy); +extern void zfCoreCwmBusy(zdev_t* dev, u16_t busy); + +/* Prototypes */ +void zfInitRf(zdev_t* dev, u32_t frequency); +void zfInitPhy(zdev_t* dev, u32_t frequency, u8_t bw40); +void zfInitMac(zdev_t* dev); + +void zfSetPowerCalTable(zdev_t* dev, u32_t frequency, u8_t bw40, u8_t extOffset); +void zfInitPowerCal(zdev_t* dev); + +#ifdef ZM_DRV_INIT_USB_MODE +void zfInitUsbMode(zdev_t* dev); +u16_t zfHpUsbReset(zdev_t* dev); +#endif + +/* Bank 0 1 2 3 5 6 7 */ +void zfSetRfRegs(zdev_t* dev, u32_t frequency); +/* Bank 4 */ +void zfSetBank4AndPowerTable(zdev_t* dev, u32_t frequency, u8_t bw40, + u8_t extOffset); +/* Get param for turnoffdyn */ +void zfGetHwTurnOffdynParam(zdev_t* dev, + u32_t frequency, u8_t bw40, u8_t extOffset, + int* delta_slope_coeff_exp, + int* delta_slope_coeff_man, + int* delta_slope_coeff_exp_shgi, + int* delta_slope_coeff_man_shgi); + +void zfSelAdcClk(zdev_t* dev, u8_t bw40, u32_t frequency); +u32_t zfHpEchoCommand(zdev_t* dev, u32_t value); + + + +#define zm_hp_priv(x) (((struct zsHpPriv*)wd->hpPrivate)->x) +struct zsHpPriv zgHpPriv; + +#define ZM_FIRMWARE_WLAN_ADDR 0x200000 +#define ZM_FIRMWARE_SPI_ADDR 0x114000 +/* 0: real chip 1: FPGA test */ +#define ZM_FPGA_PHY 0 + +#define reg_write(addr, val) zfDelayWriteInternalReg(dev, addr+0x1bc000, val) +#define zm_min(A, B) ((A>B)? B:A) + + +/******************** Intialization ********************/ +u16_t zfHpInit(zdev_t* dev, u32_t frequency) +{ + u16_t ret; + zmw_get_wlan_dev(dev); + + /* Initializa HAL Plus private variables */ + wd->hpPrivate = &zgHpPriv; + + ((struct zsHpPriv*)wd->hpPrivate)->halCapability = ZM_HP_CAP_11N; + + ((struct zsHpPriv*)wd->hpPrivate)->hwFrequency = 0; + ((struct zsHpPriv*)wd->hpPrivate)->hwBw40 = 0; + ((struct zsHpPriv*)wd->hpPrivate)->hwExtOffset = 0; + + ((struct zsHpPriv*)wd->hpPrivate)->disableDfsCh = 0; + + ((struct zsHpPriv*)wd->hpPrivate)->ledMode[0] = 1; + ((struct zsHpPriv*)wd->hpPrivate)->ledMode[1] = 1; + ((struct zsHpPriv*)wd->hpPrivate)->strongRSSI = 0; + ((struct zsHpPriv*)wd->hpPrivate)->rxStrongRSSI = 0; + + ((struct zsHpPriv*)wd->hpPrivate)->slotType = 1; + ((struct zsHpPriv*)wd->hpPrivate)->aggPktNum = 0x10000a; + + ((struct zsHpPriv*)wd->hpPrivate)->eepromImageIndex = 0; + + + ((struct zsHpPriv*)wd->hpPrivate)->eepromImageRdReq = 0; +#ifdef ZM_OTUS_RX_STREAM_MODE + ((struct zsHpPriv*)wd->hpPrivate)->remainBuf = NULL; + ((struct zsHpPriv*)wd->hpPrivate)->usbRxRemainLen = 0; + ((struct zsHpPriv*)wd->hpPrivate)->usbRxPktLen = 0; + ((struct zsHpPriv*)wd->hpPrivate)->usbRxPadLen = 0; + ((struct zsHpPriv*)wd->hpPrivate)->usbRxTransferLen = 0; +#endif + + ((struct zsHpPriv*)wd->hpPrivate)->enableBBHeavyClip = 1; + ((struct zsHpPriv*)wd->hpPrivate)->hwBBHeavyClip = 1; // force enable 8107 + ((struct zsHpPriv*)wd->hpPrivate)->doBBHeavyClip = 0; + ((struct zsHpPriv*)wd->hpPrivate)->setValueHeavyClip = 0; + + + /* Initialize driver core */ + zfInitCmdQueue(dev); + + /* Initialize USB */ + zfUsbInit(dev); + +#if ZM_SW_LOOP_BACK != 1 + + /* TODO : [Download FW] */ + if (wd->modeMDKEnable) + { + /* download the MDK firmware */ + if ((ret = zfFirmwareDownload(dev, (u32_t*)zcDKFwImage, + (u32_t)zcDKFwImageSize, ZM_FIRMWARE_WLAN_ADDR)) != ZM_SUCCESS) + { + /* TODO : exception handling */ + //return 1; + } + } + else + { + #ifndef ZM_OTUS_LINUX_PHASE_2 + /* donwload the normal frimware */ + if ((ret = zfFirmwareDownload(dev, (u32_t*)zcFwImage, + (u32_t)zcFwImageSize, ZM_FIRMWARE_WLAN_ADDR)) != ZM_SUCCESS) + { + /* TODO : exception handling */ + //return 1; + } + #else + + // 1-PH fw: ReadMac() store some global variable + if ((ret = zfFirmwareDownloadNotJump(dev, (u32_t*)zcFwBufImage, + (u32_t)zcFwBufImageSize, 0x102800)) != ZM_SUCCESS) + { + DbgPrint("Dl zcFwBufImage failed!"); + } + + zfwSleep(dev, 1000); + + if ((ret = zfFirmwareDownload(dev, (u32_t*)zcFwImage, + (u32_t)zcFwImageSize, ZM_FIRMWARE_WLAN_ADDR)) != ZM_SUCCESS) + { + DbgPrint("Dl zcFwBufImage failed!"); + } + #endif + } +#endif + +#ifdef ZM_DRV_INIT_USB_MODE + /* Init USB Mode */ + zfInitUsbMode(dev); + + /* Do the USB Reset */ + zfHpUsbReset(dev); +#endif + +/* Register setting */ +/* ZM_DRIVER_MODEL_TYPE_MDK + * 1=>for MDK, disable init RF, PHY, and MAC, + * 0=>normal init + */ +//#if ((ZM_SW_LOOP_BACK != 1) && (ZM_DRIVER_MODEL_TYPE_MDK !=1)) +#if ZM_SW_LOOP_BACK != 1 + if(!wd->modeMDKEnable) + { + /* Init MAC */ + zfInitMac(dev); + + #if ZM_FW_LOOP_BACK != 1 + /* Init PHY */ + zfInitPhy(dev, frequency, 0); + + /* Init RF */ + zfInitRf(dev, frequency); + + #if ZM_FPGA_PHY == 0 + /* BringUp issue */ + //zfDelayWriteInternalReg(dev, 0x9800+0x1bc000, 0x10000007); + //zfFlushDelayWrite(dev); + #endif + + #endif /* end of ZM_FW_LOOP_BACK != 1 */ + } +#endif /* end of ((ZM_SW_LOOP_BACK != 1) && (ZM_DRIVER_MODEL_TYPE_MDK !=1)) */ + + zfHpEchoCommand(dev, 0xAABBCCDD); + + return 0; +} + + +u16_t zfHpReinit(zdev_t* dev, u32_t frequency) +{ + u16_t ret; + zmw_get_wlan_dev(dev); + + ((struct zsHpPriv*)wd->hpPrivate)->halReInit = 1; + + ((struct zsHpPriv*)wd->hpPrivate)->strongRSSI = 0; + ((struct zsHpPriv*)wd->hpPrivate)->rxStrongRSSI = 0; + +#ifdef ZM_OTUS_RX_STREAM_MODE + if (((struct zsHpPriv*)wd->hpPrivate)->remainBuf != NULL) + { + zfwBufFree(dev, ((struct zsHpPriv*)wd->hpPrivate)->remainBuf, 0); + } + ((struct zsHpPriv*)wd->hpPrivate)->remainBuf = NULL; + ((struct zsHpPriv*)wd->hpPrivate)->usbRxRemainLen = 0; + ((struct zsHpPriv*)wd->hpPrivate)->usbRxPktLen = 0; + ((struct zsHpPriv*)wd->hpPrivate)->usbRxPadLen = 0; + ((struct zsHpPriv*)wd->hpPrivate)->usbRxTransferLen = 0; +#endif + + zfInitCmdQueue(dev); + zfCoreReinit(dev); + + #ifndef ZM_OTUS_LINUX_PHASE_2 + /* Download firmware */ + if ((ret = zfFirmwareDownload(dev, (u32_t*)zcFwImage, + (u32_t)zcFwImageSize, ZM_FIRMWARE_WLAN_ADDR)) != ZM_SUCCESS) + { + /* TODO : exception handling */ + //return 1; + } + #else + if ((ret = zfFirmwareDownload(dev, (u32_t*)zcP2FwImage, + (u32_t)zcP2FwImageSize, ZM_FIRMWARE_WLAN_ADDR)) != ZM_SUCCESS) + { + /* TODO : exception handling */ + //return 1; + } + #endif + +#ifdef ZM_DRV_INIT_USB_MODE + /* Init USB Mode */ + zfInitUsbMode(dev); + + /* Do the USB Reset */ + zfHpUsbReset(dev); +#endif + + /* Init MAC */ + zfInitMac(dev); + + /* Init PHY */ + zfInitPhy(dev, frequency, 0); + /* Init RF */ + zfInitRf(dev, frequency); + + #if ZM_FPGA_PHY == 0 + /* BringUp issue */ + //zfDelayWriteInternalReg(dev, 0x9800+0x1bc000, 0x10000007); + //zfFlushDelayWrite(dev); + #endif + + zfHpEchoCommand(dev, 0xAABBCCDD); + + return 0; +} + + +u16_t zfHpRelease(zdev_t* dev) +{ + /* Free USB resource */ + zfUsbFree(dev); + + return 0; +} + +/* MDK mode setting for dontRetransmit */ +void zfHpConfigFM(zdev_t* dev, u32_t RxMaxSize, u32_t DontRetransmit) +{ + u32_t cmd[3]; + u16_t ret; + + cmd[0] = 8 | (ZM_CMD_CONFIG << 8); + cmd[1] = RxMaxSize; /* zgRxMaxSize */ + cmd[2] = DontRetransmit; /* zgDontRetransmit */ + + ret = zfIssueCmd(dev, cmd, 12, ZM_OID_INTERNAL_WRITE, 0); +} + +const u8_t zcXpdToPd[16] = +{ + /* 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF */ + 0x2, 0x2, 0x2, 0x1, 0x2, 0x2, 0x6, 0x2, 0x2, 0x3, 0x7, 0x2, 0xB, 0x2, 0x2, 0x2 +}; + +/******************** RF and PHY ********************/ + +void zfInitPhy(zdev_t* dev, u32_t frequency, u8_t bw40) +{ + u16_t i, j, k; + u16_t entries; + u16_t modesIndex = 0; + u16_t freqIndex = 0; + u32_t tmp, tmp1; + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv=wd->hpPrivate; + u32_t eepromBoardData[15][6] = { + /* Register A-20 A-20/40 G-20/40 G-20 G-Turbo */ + {0x9964, 0, 0, 0, 0, 0}, + {0x9960, 0, 0, 0, 0, 0}, + {0xb960, 0, 0, 0, 0, 0}, + {0x9844, 0, 0, 0, 0, 0}, + {0x9850, 0, 0, 0, 0, 0}, + {0x9834, 0, 0, 0, 0, 0}, + {0x9828, 0, 0, 0, 0, 0}, + {0xc864, 0, 0, 0, 0, 0}, + {0x9848, 0, 0, 0, 0, 0}, + {0xb848, 0, 0, 0, 0, 0}, + {0xa20c, 0, 0, 0, 0, 0}, + {0xc20c, 0, 0, 0, 0, 0}, + {0x9920, 0, 0, 0, 0, 0}, + {0xb920, 0, 0, 0, 0, 0}, + {0xa258, 0, 0, 0, 0, 0}, + }; + + /* #1 Save the initial value of the related RIFS register settings */ + //((struct zsHpPriv*)wd->hpPrivate)->isInitialPhy++; + + /* + * Setup the indices for the next set of register array writes + * PHY mode is static20 / 2040 + * Frequency is 2.4GHz (B) / 5GHz (A) + */ + if ( frequency > ZM_CH_G_14 ) + { + /* 5GHz */ + freqIndex = 1; + if (bw40) + { + modesIndex = 2; + zm_debug_msg0("init ar5416Modes in 2: A-20/40"); + } + else + { + modesIndex = 1; + zm_debug_msg0("init ar5416Modes in 1: A-20"); + } + } + else + { + /* 2.4GHz */ + freqIndex = 2; + if (bw40) + { + modesIndex = 3; + zm_debug_msg0("init ar5416Modes in 3: G-20/40"); + } + else + { + modesIndex = 4; + zm_debug_msg0("init ar5416Modes in 4: G-20"); + } + } + + +#if ZM_FPGA_PHY == 1 + /* Starting External Hainan Register Initialization */ + /* TODO: */ + + zfwSleep(dev, 10); +#endif + + /* + *Set correct Baseband to analog shift setting to access analog chips. + */ + //reg_write(PHY_BASE, 0x00000007); +// reg_write(0x9800, 0x00000007); + + /* + * Write addac shifts + */ + // do this in firmware + + + + /* Zeroize board data */ + for (j=0; j<15; j++) + { + for (k=1; k<=4; k++) + { + eepromBoardData[j][k] = 0; + } + } + /* + * Register setting by mode + */ + + entries = sizeof(ar5416Modes) / sizeof(*ar5416Modes); + zm_msg1_scan(ZM_LV_2, "Modes register setting entries=", entries); + for (i=0; ihpPrivate)->hwNotFirstInit && (ar5416Modes[i][0] == 0xa27c) ) + { + /* Force disable CR671 bit20 / 7823 */ + /* The bug has to do with the polarity of the pdadc offset calibration. There */ + /* is an initial calibration that is OK, and there is a continuous */ + /* calibration that updates the pddac with the wrong polarity. Fortunately */ + /* the second loop can be disabled with a bit called en_pd_dc_offset_thr. */ + + reg_write(ar5416Modes[i][0], (ar5416Modes[i][modesIndex]& 0xffefffff) ); + ((struct zsHpPriv*)wd->hpPrivate)->hwNotFirstInit = 1; + } + else + { +#endif + /* FirstTime Init or not 0xa27c(CR671) */ + reg_write(ar5416Modes[i][0], ar5416Modes[i][modesIndex]); +// } + /* Initialize board data */ + for (j=0; j<15; j++) + { + if (ar5416Modes[i][0] == eepromBoardData[j][0]) + { + for (k=1; k<=4; k++) + { + eepromBoardData[j][k] = ar5416Modes[i][k]; + } + } + } + /* #1 Save the initial value of the related RIFS register settings */ + //if( ((struct zsHpPriv*)wd->hpPrivate)->isInitialPhy == 1 ) + { + switch(ar5416Modes[i][0]) + { + case 0x9850 : + ((struct zsHpPriv*)wd->hpPrivate)->initDesiredSigSize = ar5416Modes[i][modesIndex]; + break; + case 0x985c : + ((struct zsHpPriv*)wd->hpPrivate)->initAGC = ar5416Modes[i][modesIndex]; + break; + case 0x9860 : + ((struct zsHpPriv*)wd->hpPrivate)->initAgcControl = ar5416Modes[i][modesIndex]; + break; + case 0x9918 : + ((struct zsHpPriv*)wd->hpPrivate)->initSearchStartDelay = ar5416Modes[i][modesIndex]; + break; + case 0x99ec : + ((struct zsHpPriv*)wd->hpPrivate)->initRIFSSearchParams = ar5416Modes[i][modesIndex]; + break; + case 0xa388 : + ((struct zsHpPriv*)wd->hpPrivate)->initFastChannelChangeControl = ar5416Modes[i][modesIndex]; + default : + break; + } + } + } +#if 0 + zfFlushDelayWrite(dev); + + /* + * Common Register setting + */ + entries = sizeof(ar5416Common) / sizeof(*ar5416Common); + for (i=0; ieepromImage[0x100+0x144*2/4]; + eepromBoardData[0][1] = tmp; + eepromBoardData[0][2] = tmp; + //Ant control chain 0 + tmp = hpPriv->eepromImage[0x100+0x140*2/4]; + eepromBoardData[1][1] = tmp; + eepromBoardData[1][2] = tmp; + //Ant control chain 2 + tmp = hpPriv->eepromImage[0x100+0x142*2/4]; + eepromBoardData[2][1] = tmp; + eepromBoardData[2][2] = tmp; + //SwSettle + tmp = hpPriv->eepromImage[0x100+0x146*2/4]; + tmp = (tmp >> 16) & 0x7f; + eepromBoardData[3][1] &= (~((u32_t)0x3f80)); + eepromBoardData[3][1] |= (tmp << 7); +#if 0 + //swSettleHt40 + tmp = hpPriv->eepromImage[0x100+0x158*2/4]; + tmp = (tmp) & 0x7f; + eepromBoardData[3][2] &= (~((u32_t)0x3f80)); + eepromBoardData[3][2] |= (tmp << 7); +#endif + //adcDesired, pdaDesired + tmp = hpPriv->eepromImage[0x100+0x148*2/4]; + tmp = (tmp >> 24); + tmp1 = hpPriv->eepromImage[0x100+0x14a*2/4]; + tmp1 = tmp1 & 0xff; + tmp = tmp + (tmp1<<8); + eepromBoardData[4][1] &= (~((u32_t)0xffff)); + eepromBoardData[4][1] |= tmp; + eepromBoardData[4][2] &= (~((u32_t)0xffff)); + eepromBoardData[4][2] |= tmp; + //TxEndToXpaOff, TxFrameToXpaOn + tmp = hpPriv->eepromImage[0x100+0x14a*2/4]; + tmp = (tmp >> 24) & 0xff; + tmp1 = hpPriv->eepromImage[0x100+0x14c*2/4]; + tmp1 = (tmp1 >> 8) & 0xff; + tmp = (tmp<<24) + (tmp<<16) + (tmp1<<8) + tmp1; + eepromBoardData[5][1] = tmp; + eepromBoardData[5][2] = tmp; + //TxEnaToRxOm + tmp = hpPriv->eepromImage[0x100+0x14c*2/4] & 0xff; + eepromBoardData[6][1] &= (~((u32_t)0xff0000)); + eepromBoardData[6][1] |= (tmp<<16); + eepromBoardData[6][2] &= (~((u32_t)0xff0000)); + eepromBoardData[6][2] |= (tmp<<16); + //Thresh62 + tmp = hpPriv->eepromImage[0x100+0x14c*2/4]; + tmp = (tmp >> 16) & 0x7f; + eepromBoardData[7][1] &= (~((u32_t)0x7f000)); + eepromBoardData[7][1] |= (tmp<<12); + eepromBoardData[7][2] &= (~((u32_t)0x7f000)); + eepromBoardData[7][2] |= (tmp<<12); + //TxRxAtten chain_0 + tmp = hpPriv->eepromImage[0x100+0x146*2/4]; + tmp = (tmp >> 24) & 0x3f; + eepromBoardData[8][1] &= (~((u32_t)0x3f000)); + eepromBoardData[8][1] |= (tmp<<12); + eepromBoardData[8][2] &= (~((u32_t)0x3f000)); + eepromBoardData[8][2] |= (tmp<<12); + //TxRxAtten chain_2 + tmp = hpPriv->eepromImage[0x100+0x148*2/4] & 0x3f; + eepromBoardData[9][1] &= (~((u32_t)0x3f000)); + eepromBoardData[9][1] |= (tmp<<12); + eepromBoardData[9][2] &= (~((u32_t)0x3f000)); + eepromBoardData[9][2] |= (tmp<<12); + //TxRxMargin chain_0 + tmp = hpPriv->eepromImage[0x100+0x148*2/4]; + tmp = (tmp >> 8) & 0x3f; + eepromBoardData[10][1] &= (~((u32_t)0xfc0000)); + eepromBoardData[10][1] |= (tmp<<18); + eepromBoardData[10][2] &= (~((u32_t)0xfc0000)); + eepromBoardData[10][2] |= (tmp<<18); + //TxRxMargin chain_2 + tmp = hpPriv->eepromImage[0x100+0x148*2/4]; + tmp = (tmp >> 16) & 0x3f; + eepromBoardData[11][1] &= (~((u32_t)0xfc0000)); + eepromBoardData[11][1] |= (tmp<<18); + eepromBoardData[11][2] &= (~((u32_t)0xfc0000)); + eepromBoardData[11][2] |= (tmp<<18); + //iqCall chain_0, iqCallQ chain_0 + tmp = hpPriv->eepromImage[0x100+0x14e*2/4]; + tmp = (tmp >> 24) & 0x3f; + tmp1 = hpPriv->eepromImage[0x100+0x150*2/4]; + tmp1 = (tmp1 >> 8) & 0x1f; + tmp = (tmp<<5) + tmp1; + eepromBoardData[12][1] &= (~((u32_t)0x7ff)); + eepromBoardData[12][1] |= (tmp); + eepromBoardData[12][2] &= (~((u32_t)0x7ff)); + eepromBoardData[12][2] |= (tmp); + //iqCall chain_2, iqCallQ chain_2 + tmp = hpPriv->eepromImage[0x100+0x150*2/4]; + tmp = tmp & 0x3f; + tmp1 = hpPriv->eepromImage[0x100+0x150*2/4]; + tmp1 = (tmp1 >> 16) & 0x1f; + tmp = (tmp<<5) + tmp1; + eepromBoardData[13][1] &= (~((u32_t)0x7ff)); + eepromBoardData[13][1] |= (tmp); + eepromBoardData[13][2] &= (~((u32_t)0x7ff)); + eepromBoardData[13][2] |= (tmp); + //bsw_Margin chain_0 + tmp = hpPriv->eepromImage[0x100+0x156*2/4]; + tmp = (tmp >> 16) & 0xf; + eepromBoardData[10][1] &= (~((u32_t)0x3c00)); + eepromBoardData[10][1] |= (tmp << 10); + eepromBoardData[10][2] &= (~((u32_t)0x3c00)); + eepromBoardData[10][2] |= (tmp << 10); + //xpd gain mask + tmp = hpPriv->eepromImage[0x100+0x14e*2/4]; + tmp = (tmp >> 8) & 0xf; + eepromBoardData[14][1] &= (~((u32_t)0xf0000)); + eepromBoardData[14][1] |= (zcXpdToPd[tmp] << 16); + eepromBoardData[14][2] &= (~((u32_t)0xf0000)); + eepromBoardData[14][2] |= (zcXpdToPd[tmp] << 16); +#if 0 + //bsw_Atten chain_0 + tmp = hpPriv->eepromImage[0x100+0x156*2/4]; + tmp = (tmp) & 0x1f; + eepromBoardData[10][1] &= (~((u32_t)0x1f)); + eepromBoardData[10][1] |= (tmp); + eepromBoardData[10][2] &= (~((u32_t)0x1f)); + eepromBoardData[10][2] |= (tmp); + //bsw_Margin chain_2 + tmp = hpPriv->eepromImage[0x100+0x156*2/4]; + tmp = (tmp >> 24) & 0xf; + eepromBoardData[11][1] &= (~((u32_t)0x3c00)); + eepromBoardData[11][1] |= (tmp << 10); + eepromBoardData[11][2] &= (~((u32_t)0x3c00)); + eepromBoardData[11][2] |= (tmp << 10); + //bsw_Atten chain_2 + tmp = hpPriv->eepromImage[0x100+0x156*2/4]; + tmp = (tmp >> 8) & 0x1f; + eepromBoardData[11][1] &= (~((u32_t)0x1f)); + eepromBoardData[11][1] |= (tmp); + eepromBoardData[11][2] &= (~((u32_t)0x1f)); + eepromBoardData[11][2] |= (tmp); +#endif + + /* Update 2.4G board data */ + //Ant control common + tmp = hpPriv->eepromImage[0x100+0x170*2/4]; + tmp = tmp >> 24; + tmp1 = hpPriv->eepromImage[0x100+0x172*2/4]; + tmp = tmp + (tmp1 << 8); + eepromBoardData[0][3] = tmp; + eepromBoardData[0][4] = tmp; + //Ant control chain 0 + tmp = hpPriv->eepromImage[0x100+0x16c*2/4]; + tmp = tmp >> 24; + tmp1 = hpPriv->eepromImage[0x100+0x16e*2/4]; + tmp = tmp + (tmp1 << 8); + eepromBoardData[1][3] = tmp; + eepromBoardData[1][4] = tmp; + //Ant control chain 2 + tmp = hpPriv->eepromImage[0x100+0x16e*2/4]; + tmp = tmp >> 24; + tmp1 = hpPriv->eepromImage[0x100+0x170*2/4]; + tmp = tmp + (tmp1 << 8); + eepromBoardData[2][3] = tmp; + eepromBoardData[2][4] = tmp; + //SwSettle + tmp = hpPriv->eepromImage[0x100+0x174*2/4]; + tmp = (tmp >> 8) & 0x7f; + eepromBoardData[3][4] &= (~((u32_t)0x3f80)); + eepromBoardData[3][4] |= (tmp << 7); +#if 0 + //swSettleHt40 + tmp = hpPriv->eepromImage[0x100+0x184*2/4]; + tmp = (tmp >> 24) & 0x7f; + eepromBoardData[3][3] &= (~((u32_t)0x3f80)); + eepromBoardData[3][3] |= (tmp << 7); +#endif + //adcDesired, pdaDesired + tmp = hpPriv->eepromImage[0x100+0x176*2/4]; + tmp = (tmp >> 16) & 0xff; + tmp1 = hpPriv->eepromImage[0x100+0x176*2/4]; + tmp1 = tmp1 >> 24; + tmp = tmp + (tmp1<<8); + eepromBoardData[4][3] &= (~((u32_t)0xffff)); + eepromBoardData[4][3] |= tmp; + eepromBoardData[4][4] &= (~((u32_t)0xffff)); + eepromBoardData[4][4] |= tmp; + //TxEndToXpaOff, TxFrameToXpaOn + tmp = hpPriv->eepromImage[0x100+0x178*2/4]; + tmp = (tmp >> 16) & 0xff; + tmp1 = hpPriv->eepromImage[0x100+0x17a*2/4]; + tmp1 = tmp1 & 0xff; + tmp = (tmp << 24) + (tmp << 16) + (tmp1 << 8) + tmp1; + eepromBoardData[5][3] = tmp; + eepromBoardData[5][4] = tmp; + //TxEnaToRxOm + tmp = hpPriv->eepromImage[0x100+0x178*2/4]; + tmp = (tmp >> 24); + eepromBoardData[6][3] &= (~((u32_t)0xff0000)); + eepromBoardData[6][3] |= (tmp<<16); + eepromBoardData[6][4] &= (~((u32_t)0xff0000)); + eepromBoardData[6][4] |= (tmp<<16); + //Thresh62 + tmp = hpPriv->eepromImage[0x100+0x17a*2/4]; + tmp = (tmp >> 8) & 0x7f; + eepromBoardData[7][3] &= (~((u32_t)0x7f000)); + eepromBoardData[7][3] |= (tmp<<12); + eepromBoardData[7][4] &= (~((u32_t)0x7f000)); + eepromBoardData[7][4] |= (tmp<<12); + //TxRxAtten chain_0 + tmp = hpPriv->eepromImage[0x100+0x174*2/4]; + tmp = (tmp >> 16) & 0x3f; + eepromBoardData[8][3] &= (~((u32_t)0x3f000)); + eepromBoardData[8][3] |= (tmp<<12); + eepromBoardData[8][4] &= (~((u32_t)0x3f000)); + eepromBoardData[8][4] |= (tmp<<12); + //TxRxAtten chain_2 + tmp = hpPriv->eepromImage[0x100+0x174*2/4]; + tmp = (tmp >> 24) & 0x3f; + eepromBoardData[9][3] &= (~((u32_t)0x3f000)); + eepromBoardData[9][3] |= (tmp<<12); + eepromBoardData[9][4] &= (~((u32_t)0x3f000)); + eepromBoardData[9][4] |= (tmp<<12); + //TxRxMargin chain_0 + tmp = hpPriv->eepromImage[0x100+0x176*2/4]; + tmp = (tmp) & 0x3f; + eepromBoardData[10][3] &= (~((u32_t)0xfc0000)); + eepromBoardData[10][3] |= (tmp<<18); + eepromBoardData[10][4] &= (~((u32_t)0xfc0000)); + eepromBoardData[10][4] |= (tmp<<18); + //TxRxMargin chain_2 + tmp = hpPriv->eepromImage[0x100+0x176*2/4]; + tmp = (tmp >> 8) & 0x3f; + eepromBoardData[11][3] &= (~((u32_t)0xfc0000)); + eepromBoardData[11][3] |= (tmp<<18); + eepromBoardData[11][4] &= (~((u32_t)0xfc0000)); + eepromBoardData[11][4] |= (tmp<<18); + //iqCall chain_0, iqCallQ chain_0 + tmp = hpPriv->eepromImage[0x100+0x17c*2/4]; + tmp = (tmp >> 16) & 0x3f; + tmp1 = hpPriv->eepromImage[0x100+0x17e*2/4]; + tmp1 = (tmp1) & 0x1f; + tmp = (tmp<<5) + tmp1; + eepromBoardData[12][3] &= (~((u32_t)0x7ff)); + eepromBoardData[12][3] |= (tmp); + eepromBoardData[12][4] &= (~((u32_t)0x7ff)); + eepromBoardData[12][4] |= (tmp); + //iqCall chain_2, iqCallQ chain_2 + tmp = hpPriv->eepromImage[0x100+0x17c*2/4]; + tmp = (tmp>>24) & 0x3f; + tmp1 = hpPriv->eepromImage[0x100+0x17e*2/4]; + tmp1 = (tmp1 >> 8) & 0x1f; + tmp = (tmp<<5) + tmp1; + eepromBoardData[13][3] &= (~((u32_t)0x7ff)); + eepromBoardData[13][3] |= (tmp); + eepromBoardData[13][4] &= (~((u32_t)0x7ff)); + eepromBoardData[13][4] |= (tmp); + //xpd gain mask + tmp = hpPriv->eepromImage[0x100+0x17c*2/4]; + tmp = tmp & 0xf; + DbgPrint("xpd=0x%x, pd=0x%x\n", tmp, zcXpdToPd[tmp]); + eepromBoardData[14][3] &= (~((u32_t)0xf0000)); + eepromBoardData[14][3] |= (zcXpdToPd[tmp] << 16); + eepromBoardData[14][4] &= (~((u32_t)0xf0000)); + eepromBoardData[14][4] |= (zcXpdToPd[tmp] << 16); +#if 0 + //bsw_Margin chain_0 + tmp = hpPriv->eepromImage[0x100+0x184*2/4]; + tmp = (tmp >> 8) & 0xf; + eepromBoardData[10][3] &= (~((u32_t)0x3c00)); + eepromBoardData[10][3] |= (tmp << 10); + eepromBoardData[10][4] &= (~((u32_t)0x3c00)); + eepromBoardData[10][4] |= (tmp << 10); + //bsw_Atten chain_0 + tmp = hpPriv->eepromImage[0x100+0x182*2/4]; + tmp = (tmp>>24) & 0x1f; + eepromBoardData[10][3] &= (~((u32_t)0x1f)); + eepromBoardData[10][3] |= (tmp); + eepromBoardData[10][4] &= (~((u32_t)0x1f)); + eepromBoardData[10][4] |= (tmp); + //bsw_Margin chain_2 + tmp = hpPriv->eepromImage[0x100+0x184*2/4]; + tmp = (tmp >> 16) & 0xf; + eepromBoardData[11][3] &= (~((u32_t)0x3c00)); + eepromBoardData[11][3] |= (tmp << 10); + eepromBoardData[11][4] &= (~((u32_t)0x3c00)); + eepromBoardData[11][4] |= (tmp << 10); + //bsw_Atten chain_2 + tmp = hpPriv->eepromImage[0x100+0x184*2/4]; + tmp = (tmp) & 0x1f; + eepromBoardData[11][3] &= (~((u32_t)0x1f)); + eepromBoardData[11][3] |= (tmp); + eepromBoardData[11][4] &= (~((u32_t)0x1f)); + eepromBoardData[11][4] |= (tmp); +#endif + +#if 0 + for (j=0; j<14; j++) + { + DbgPrint("%04x, %08x, %08x, %08x, %08x\n", eepromBoardData[j][0], eepromBoardData[j][1], eepromBoardData[j][2], eepromBoardData[j][3], eepromBoardData[j][4]); + } +#endif + + if ((hpPriv->eepromImage[0x100+0x110*2/4]&0xff) == 0x80) //FEM TYPE + { + /* Update board data to registers */ + for (j=0; j<15; j++) + { + reg_write(eepromBoardData[j][0], eepromBoardData[j][modesIndex]); + + /* #1 Save the initial value of the related RIFS register settings */ + //if( ((struct zsHpPriv*)wd->hpPrivate)->isInitialPhy == 1 ) + { + switch(eepromBoardData[j][0]) + { + case 0x9850 : + ((struct zsHpPriv*)wd->hpPrivate)->initDesiredSigSize = eepromBoardData[j][modesIndex]; + break; + case 0x985c : + ((struct zsHpPriv*)wd->hpPrivate)->initAGC = eepromBoardData[j][modesIndex]; + break; + case 0x9860 : + ((struct zsHpPriv*)wd->hpPrivate)->initAgcControl = eepromBoardData[j][modesIndex]; + break; + case 0x9918 : + ((struct zsHpPriv*)wd->hpPrivate)->initSearchStartDelay = eepromBoardData[j][modesIndex]; + break; + case 0x99ec : + ((struct zsHpPriv*)wd->hpPrivate)->initRIFSSearchParams = eepromBoardData[j][modesIndex]; + break; + case 0xa388 : + ((struct zsHpPriv*)wd->hpPrivate)->initFastChannelChangeControl = eepromBoardData[j][modesIndex]; + default : + break; + } + } + } + } /* if ((hpPriv->eepromImage[0x100+0x110*2/4]&0xff) == 0x80) //FEM TYPE */ + + + /* Bringup issue : force tx gain */ + //reg_write(0xa258, 0x0cc65381); + //reg_write(0xa274, 0x0a1a7c15); + zfInitPowerCal(dev); + + if(frequency > ZM_CH_G_14) + { + zfDelayWriteInternalReg(dev, 0x1d4014, 0x5143); + } + else + { + zfDelayWriteInternalReg(dev, 0x1d4014, 0x5163); + } + + zfFlushDelayWrite(dev); +} + + +void zfInitRf(zdev_t* dev, u32_t frequency) +{ + u32_t cmd[8]; + u16_t ret; + int delta_slope_coeff_exp; + int delta_slope_coeff_man; + int delta_slope_coeff_exp_shgi; + int delta_slope_coeff_man_shgi; + + zmw_get_wlan_dev(dev); + + zm_debug_msg1(" initRf frequency = ", frequency); + + if (frequency == 0) + { + frequency = 2412; + } + + /* Bank 0 1 2 3 5 6 7 */ + zfSetRfRegs(dev, frequency); + /* Bank 4 */ + zfSetBank4AndPowerTable(dev, frequency, 0, 0); + + /* stroe frequency */ + ((struct zsHpPriv*)wd->hpPrivate)->hwFrequency = (u16_t)frequency; + + zfGetHwTurnOffdynParam(dev, + frequency, 0, 0, + &delta_slope_coeff_exp, + &delta_slope_coeff_man, + &delta_slope_coeff_exp_shgi, + &delta_slope_coeff_man_shgi); + + /* related functions */ + frequency = frequency*1000; + cmd[0] = 28 | (ZM_CMD_RF_INIT << 8); + cmd[1] = frequency; + cmd[2] = 0;//((struct zsHpPriv*)wd->hpPrivate)->hw_DYNAMIC_HT2040_EN; + cmd[3] = 1;//((wd->ExtOffset << 2) | ((struct zsHpPriv*)wd->hpPrivate)->hw_HT_ENABLE); + cmd[4] = delta_slope_coeff_exp; + cmd[5] = delta_slope_coeff_man; + cmd[6] = delta_slope_coeff_exp_shgi; + cmd[7] = delta_slope_coeff_man_shgi; + + ret = zfIssueCmd(dev, cmd, 32, ZM_OID_INTERNAL_WRITE, 0); + + // delay temporarily, wait for new PHY and RF + zfwSleep(dev, 1000); +} + +int tn(int exp) +{ + int i; + int tmp = 1; + for(i=0; i>(7-i) & 0x1) << i); + return chansel; +} + +/* Bank 0 1 2 3 5 6 7 */ +void zfSetRfRegs(zdev_t* dev, u32_t frequency) +{ + u16_t entries; + u16_t freqIndex = 0; + u16_t i; + + //zmw_get_wlan_dev(dev); + + if ( frequency > ZM_CH_G_14 ) + { + /* 5G */ + freqIndex = 1; + zm_msg0_scan(ZM_LV_2, "Set to 5GHz"); + + } + else + { + /* 2.4G */ + freqIndex = 2; + zm_msg0_scan(ZM_LV_2, "Set to 2.4GHz"); + } + +#if 1 + entries = sizeof(otusBank) / sizeof(*otusBank); + for (i=0; ista.DFSEnable) + { + for (i = 0; i < wd->regulationTable.allowChannelCnt; i++) + { + if (wd->regulationTable.allowChannel[i].channel == frequency) + break; + } + wd->regulationTable.CurChIndex = i; + } + + if (bw40 == 1) + { + if (extOffset == 1) + { + frequency += 10; + } + else + { + frequency -= 10; + } + + } + + + if ( frequency > 3000 ) + { + if ( frequency % 10 ) + { + /* 5M */ + chan_sel = (u8_t)((frequency - 4800)/5); + chan_sel = (u8_t)(chan_sel & 0xff); + chansel = (u8_t)reverse_bits(chan_sel); + } + else + { + /* 10M : improve Tx EVM */ + chan_sel = (u8_t)((frequency - 4800)/10); + chan_sel = (u8_t)(chan_sel & 0xff)<<1; + chansel = (u8_t)reverse_bits(chan_sel); + + amode_refsel_1 = 1; + amode_refsel_0 = 0; + } + } + else + { + //temp_chan_sel = (((frequency - 672)*2) - 3040)/10; + if (frequency == 2484) + { + temp_chan_sel = 10 + (frequency - 2274)/5 ; + bmode_LF_synth_freq = 1; + } + else + { + temp_chan_sel = 16 + (frequency - 2272)/5 ; + bmode_LF_synth_freq = 0; + } + chan_sel = (u8_t)(temp_chan_sel << 2) & 0xff; + chansel = (u8_t)reverse_bits(chan_sel); + } + + d1 = chansel; //# 8 bits of chan + d0 = addr0<<7 | addr1<<6 | addr2<<5 + | amode_refsel_0<<3 | amode_refsel_1<<2 + | bmode_LF_synth_freq<<1 | chup; + + tmp_0 = d0 & 0x1f; //# 5-1 + tmp_1 = d1 & 0x1f; //# 5-1 + data0 = tmp_1<<5 | tmp_0; + + tmp_0 = d0>>5 & 0x7; //# 8-6 + tmp_1 = d1>>5 & 0x7; //# 8-6 + data1 = tmp_1<<5 | tmp_0; + + /* Bank4 */ + reg_write (0x9800+(0x2c<<2), data0); + reg_write (0x9800+(0x3a<<2), data1); + //zm_debug_msg1("0x9800+(0x2c<<2 = ", data0); + //zm_debug_msg1("0x9800+(0x3a<<2 = ", data1); + + + zfFlushDelayWrite(dev); + + zfwSleep(dev, 10); + + return; +} + + +struct zsPhyFreqPara +{ + u32_t coeff_exp; + u32_t coeff_man; + u32_t coeff_exp_shgi; + u32_t coeff_man_shgi; +}; + +struct zsPhyFreqTable +{ + u32_t frequency; + struct zsPhyFreqPara FpgaDynamicHT; + struct zsPhyFreqPara FpgaStaticHT; + struct zsPhyFreqPara ChipST20Mhz; + struct zsPhyFreqPara Chip2040Mhz; + struct zsPhyFreqPara Chip2040ExtAbove; +}; + +const struct zsPhyFreqTable zgPhyFreqCoeff[] = +{ +/*Index freq FPGA DYNAMIC_HT2040_EN FPGA STATIC_HT20 Real Chip static20MHz Real Chip 2040MHz Real Chip 2040Mhz */ + /* fclk = 10.8 21.6 40 ext below 40 ext above 40 */ +/* 0 */ {2412, {5, 23476, 5, 21128}, {4, 23476, 4, 21128}, {3, 21737, 3, 19563}, {3, 21827, 3, 19644}, {3, 21647, 3, 19482}}, +/* 1 */ {2417, {5, 23427, 5, 21084}, {4, 23427, 4, 21084}, {3, 21692, 3, 19523}, {3, 21782, 3, 19604}, {3, 21602, 3, 19442}}, +/* 2 */ {2422, {5, 23379, 5, 21041}, {4, 23379, 4, 21041}, {3, 21647, 3, 19482}, {3, 21737, 3, 19563}, {3, 21558, 3, 19402}}, +/* 3 */ {2427, {5, 23330, 5, 20997}, {4, 23330, 4, 20997}, {3, 21602, 3, 19442}, {3, 21692, 3, 19523}, {3, 21514, 3, 19362}}, +/* 4 */ {2432, {5, 23283, 5, 20954}, {4, 23283, 4, 20954}, {3, 21558, 3, 19402}, {3, 21647, 3, 19482}, {3, 21470, 3, 19323}}, +/* 5 */ {2437, {5, 23235, 5, 20911}, {4, 23235, 4, 20911}, {3, 21514, 3, 19362}, {3, 21602, 3, 19442}, {3, 21426, 3, 19283}}, +/* 6 */ {2442, {5, 23187, 5, 20868}, {4, 23187, 4, 20868}, {3, 21470, 3, 19323}, {3, 21558, 3, 19402}, {3, 21382, 3, 19244}}, +/* 7 */ {2447, {5, 23140, 5, 20826}, {4, 23140, 4, 20826}, {3, 21426, 3, 19283}, {3, 21514, 3, 19362}, {3, 21339, 3, 19205}}, +/* 8 */ {2452, {5, 23093, 5, 20783}, {4, 23093, 4, 20783}, {3, 21382, 3, 19244}, {3, 21470, 3, 19323}, {3, 21295, 3, 19166}}, +/* 9 */ {2457, {5, 23046, 5, 20741}, {4, 23046, 4, 20741}, {3, 21339, 3, 19205}, {3, 21426, 3, 19283}, {3, 21252, 3, 19127}}, +/* 10 */ {2462, {5, 22999, 5, 20699}, {4, 22999, 4, 20699}, {3, 21295, 3, 19166}, {3, 21382, 3, 19244}, {3, 21209, 3, 19088}}, +/* 11 */ {2467, {5, 22952, 5, 20657}, {4, 22952, 4, 20657}, {3, 21252, 3, 19127}, {3, 21339, 3, 19205}, {3, 21166, 3, 19050}}, +/* 12 */ {2472, {5, 22906, 5, 20615}, {4, 22906, 4, 20615}, {3, 21209, 3, 19088}, {3, 21295, 3, 19166}, {3, 21124, 3, 19011}}, +/* 13 */ {2484, {5, 22795, 5, 20516}, {4, 22795, 4, 20516}, {3, 21107, 3, 18996}, {3, 21192, 3, 19073}, {3, 21022, 3, 18920}}, +/* 14 */ {4920, {6, 23018, 6, 20716}, {5, 23018, 5, 20716}, {4, 21313, 4, 19181}, {4, 21356, 4, 19220}, {4, 21269, 4, 19142}}, +/* 15 */ {4940, {6, 22924, 6, 20632}, {5, 22924, 5, 20632}, {4, 21226, 4, 19104}, {4, 21269, 4, 19142}, {4, 21183, 4, 19065}}, +/* 16 */ {4960, {6, 22832, 6, 20549}, {5, 22832, 5, 20549}, {4, 21141, 4, 19027}, {4, 21183, 4, 19065}, {4, 21098, 4, 18988}}, +/* 17 */ {4980, {6, 22740, 6, 20466}, {5, 22740, 5, 20466}, {4, 21056, 4, 18950}, {4, 21098, 4, 18988}, {4, 21014, 4, 18912}}, +/* 18 */ {5040, {6, 22469, 6, 20223}, {5, 22469, 5, 20223}, {4, 20805, 4, 18725}, {4, 20846, 4, 18762}, {4, 20764, 4, 18687}}, +/* 19 */ {5060, {6, 22381, 6, 20143}, {5, 22381, 5, 20143}, {4, 20723, 4, 18651}, {4, 20764, 4, 18687}, {4, 20682, 4, 18614}}, +/* 20 */ {5080, {6, 22293, 6, 20063}, {5, 22293, 5, 20063}, {4, 20641, 4, 18577}, {4, 20682, 4, 18614}, {4, 20601, 4, 18541}}, +/* 21 */ {5180, {6, 21862, 6, 19676}, {5, 21862, 5, 19676}, {4, 20243, 4, 18219}, {4, 20282, 4, 18254}, {4, 20204, 4, 18183}}, +/* 22 */ {5200, {6, 21778, 6, 19600}, {5, 21778, 5, 19600}, {4, 20165, 4, 18148}, {4, 20204, 4, 18183}, {4, 20126, 4, 18114}}, +/* 23 */ {5220, {6, 21695, 6, 19525}, {5, 21695, 5, 19525}, {4, 20088, 4, 18079}, {4, 20126, 4, 18114}, {4, 20049, 4, 18044}}, +/* 24 */ {5240, {6, 21612, 6, 19451}, {5, 21612, 5, 19451}, {4, 20011, 4, 18010}, {4, 20049, 4, 18044}, {4, 19973, 4, 17976}}, +/* 25 */ {5260, {6, 21530, 6, 19377}, {5, 21530, 5, 19377}, {4, 19935, 4, 17941}, {4, 19973, 4, 17976}, {4, 19897, 4, 17907}}, +/* 26 */ {5280, {6, 21448, 6, 19303}, {5, 21448, 5, 19303}, {4, 19859, 4, 17873}, {4, 19897, 4, 17907}, {4, 19822, 4, 17840}}, +/* 27 */ {5300, {6, 21367, 6, 19230}, {5, 21367, 5, 19230}, {4, 19784, 4, 17806}, {4, 19822, 4, 17840}, {4, 19747, 4, 17772}}, +/* 28 */ {5320, {6, 21287, 6, 19158}, {5, 21287, 5, 19158}, {4, 19710, 4, 17739}, {4, 19747, 4, 17772}, {4, 19673, 4, 17706}}, +/* 29 */ {5500, {6, 20590, 6, 18531}, {5, 20590, 5, 18531}, {4, 19065, 4, 17159}, {4, 19100, 4, 17190}, {4, 19030, 4, 17127}}, +/* 30 */ {5520, {6, 20516, 6, 18464}, {5, 20516, 5, 18464}, {4, 18996, 4, 17096}, {4, 19030, 4, 17127}, {4, 18962, 4, 17065}}, +/* 31 */ {5540, {6, 20442, 6, 18397}, {5, 20442, 5, 18397}, {4, 18927, 4, 17035}, {4, 18962, 4, 17065}, {4, 18893, 4, 17004}}, +/* 32 */ {5560, {6, 20368, 6, 18331}, {5, 20368, 5, 18331}, {4, 18859, 4, 16973}, {4, 18893, 4, 17004}, {4, 18825, 4, 16943}}, +/* 33 */ {5580, {6, 20295, 6, 18266}, {5, 20295, 5, 18266}, {4, 18792, 4, 16913}, {4, 18825, 4, 16943}, {4, 18758, 4, 16882}}, +/* 34 */ {5600, {6, 20223, 6, 18200}, {5, 20223, 5, 18200}, {4, 18725, 4, 16852}, {4, 18758, 4, 16882}, {4, 18691, 4, 16822}}, +/* 35 */ {5620, {6, 20151, 6, 18136}, {5, 20151, 5, 18136}, {4, 18658, 4, 16792}, {4, 18691, 4, 16822}, {4, 18625, 4, 16762}}, +/* 36 */ {5640, {6, 20079, 6, 18071}, {5, 20079, 5, 18071}, {4, 18592, 4, 16733}, {4, 18625, 4, 16762}, {4, 18559, 4, 16703}}, +/* 37 */ {5660, {6, 20008, 6, 18007}, {5, 20008, 5, 18007}, {4, 18526, 4, 16673}, {4, 18559, 4, 16703}, {4, 18493, 4, 16644}}, +/* 38 */ {5680, {6, 19938, 6, 17944}, {5, 19938, 5, 17944}, {4, 18461, 4, 16615}, {4, 18493, 4, 16644}, {4, 18428, 4, 16586}}, +/* 39 */ {5700, {6, 19868, 6, 17881}, {5, 19868, 5, 17881}, {4, 18396, 4, 16556}, {4, 18428, 4, 16586}, {4, 18364, 4, 16527}}, +/* 40 */ {5745, {6, 19712, 6, 17741}, {5, 19712, 5, 17741}, {4, 18252, 4, 16427}, {4, 18284, 4, 16455}, {4, 18220, 4, 16398}}, +/* 41 */ {5765, {6, 19644, 6, 17679}, {5, 19644, 5, 17679}, {4, 18189, 5, 32740}, {4, 18220, 4, 16398}, {4, 18157, 5, 32683}}, +/* 42 */ {5785, {6, 19576, 6, 17618}, {5, 19576, 5, 17618}, {4, 18126, 5, 32626}, {4, 18157, 5, 32683}, {4, 18094, 5, 32570}}, +/* 43 */ {5805, {6, 19508, 6, 17558}, {5, 19508, 5, 17558}, {4, 18063, 5, 32514}, {4, 18094, 5, 32570}, {4, 18032, 5, 32458}}, +/* 44 */ {5825, {6, 19441, 6, 17497}, {5, 19441, 5, 17497}, {4, 18001, 5, 32402}, {4, 18032, 5, 32458}, {4, 17970, 5, 32347}}, +/* 45 */ {5170, {6, 21904, 6, 19714}, {5, 21904, 5, 19714}, {4, 20282, 4, 18254}, {4, 20321, 4, 18289}, {4, 20243, 4, 18219}}, +/* 46 */ {5190, {6, 21820, 6, 19638}, {5, 21820, 5, 19638}, {4, 20204, 4, 18183}, {4, 20243, 4, 18219}, {4, 20165, 4, 18148}}, +/* 47 */ {5210, {6, 21736, 6, 19563}, {5, 21736, 5, 19563}, {4, 20126, 4, 18114}, {4, 20165, 4, 18148}, {4, 20088, 4, 18079}}, +/* 48 */ {5230, {6, 21653, 6, 19488}, {5, 21653, 5, 19488}, {4, 20049, 4, 18044}, {4, 20088, 4, 18079}, {4, 20011, 4, 18010}} +}; +/* to reduce search time, please modify this define if you add or delete channel in table */ +#define First5GChannelIndex 14 + +void zfGetHwTurnOffdynParam(zdev_t* dev, + u32_t frequency, u8_t bw40, u8_t extOffset, + int* delta_slope_coeff_exp, + int* delta_slope_coeff_man, + int* delta_slope_coeff_exp_shgi, + int* delta_slope_coeff_man_shgi) +{ + /* Get param for turnoffdyn */ + u16_t i, arraySize; + + //zmw_get_wlan_dev(dev); + + arraySize = sizeof(zgPhyFreqCoeff)/sizeof(struct zsPhyFreqTable); + if (frequency < 3000) + { + /* 2.4GHz Channel */ + for (i = 0; i < First5GChannelIndex; i++) + { + if (frequency == zgPhyFreqCoeff[i].frequency) + break; + } + + if (i < First5GChannelIndex) + { + } + else + { + zm_msg1_scan(ZM_LV_0, "Unsupported 2.4G frequency = ", frequency); + return; + } + } + else + { + /* 5GHz Channel */ + for (i = First5GChannelIndex; i < arraySize; i++) + { + if (frequency == zgPhyFreqCoeff[i].frequency) + break; + } + + if (i < arraySize) + { + } + else + { + zm_msg1_scan(ZM_LV_0, "Unsupported 5G frequency = ", frequency); + return; + } + } + + /* FPGA DYNAMIC_HT2040_EN fclk = 10.8 */ + /* FPGA STATIC_HT20_ fclk = 21.6 */ + /* Real Chip fclk = 40 */ + #if ZM_FPGA_PHY == 1 + //fclk = 10.8; + *delta_slope_coeff_exp = zgPhyFreqCoeff[i].FpgaDynamicHT.coeff_exp; + *delta_slope_coeff_man = zgPhyFreqCoeff[i].FpgaDynamicHT.coeff_man; + *delta_slope_coeff_exp_shgi = zgPhyFreqCoeff[i].FpgaDynamicHT.coeff_exp_shgi; + *delta_slope_coeff_man_shgi = zgPhyFreqCoeff[i].FpgaDynamicHT.coeff_man_shgi; + #else + //fclk = 40; + if (bw40) + { + /* ht2040 */ + if (extOffset == 1) { + *delta_slope_coeff_exp = zgPhyFreqCoeff[i].Chip2040ExtAbove.coeff_exp; + *delta_slope_coeff_man = zgPhyFreqCoeff[i].Chip2040ExtAbove.coeff_man; + *delta_slope_coeff_exp_shgi = zgPhyFreqCoeff[i].Chip2040ExtAbove.coeff_exp_shgi; + *delta_slope_coeff_man_shgi = zgPhyFreqCoeff[i].Chip2040ExtAbove.coeff_man_shgi; + } + else { + *delta_slope_coeff_exp = zgPhyFreqCoeff[i].Chip2040Mhz.coeff_exp; + *delta_slope_coeff_man = zgPhyFreqCoeff[i].Chip2040Mhz.coeff_man; + *delta_slope_coeff_exp_shgi = zgPhyFreqCoeff[i].Chip2040Mhz.coeff_exp_shgi; + *delta_slope_coeff_man_shgi = zgPhyFreqCoeff[i].Chip2040Mhz.coeff_man_shgi; + } + } + else + { + /* static 20 */ + *delta_slope_coeff_exp = zgPhyFreqCoeff[i].ChipST20Mhz.coeff_exp; + *delta_slope_coeff_man = zgPhyFreqCoeff[i].ChipST20Mhz.coeff_man; + *delta_slope_coeff_exp_shgi = zgPhyFreqCoeff[i].ChipST20Mhz.coeff_exp_shgi; + *delta_slope_coeff_man_shgi = zgPhyFreqCoeff[i].ChipST20Mhz.coeff_man_shgi; + } + #endif +} + +/* Main routin frequency setting function */ +/* If 2.4G/5G switch, PHY need resetting BB and RF for band switch */ +/* Do the setting switch in zfSendFrequencyCmd() */ +void zfHpSetFrequencyEx(zdev_t* dev, u32_t frequency, u8_t bw40, + u8_t extOffset, u8_t initRF) +{ + u32_t cmd[9]; + u32_t cmdB[3]; + u16_t ret; + u8_t old_band; + u8_t new_band; + u32_t checkLoopCount; + u32_t tmpValue; + + int delta_slope_coeff_exp; + int delta_slope_coeff_man; + int delta_slope_coeff_exp_shgi; + int delta_slope_coeff_man_shgi; + + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv = wd->hpPrivate; + + zm_msg1_scan(ZM_LV_1, "Frequency = ", frequency); + zm_msg1_scan(ZM_LV_1, "bw40 = ", bw40); + zm_msg1_scan(ZM_LV_1, "extOffset = ", extOffset); + + if ( hpPriv->coldResetNeedFreq ) + { + hpPriv->coldResetNeedFreq = 0; + initRF = 2; + zm_debug_msg0("zfHpSetFrequencyEx: Do ColdReset "); + } + if ( hpPriv->isSiteSurvey == 2 ) + { + /* wait time for AGC and noise calibration : not in sitesurvey and connected */ + checkLoopCount = 2000; /* 2000*100 = 200ms */ + } + else + { + /* wait time for AGC and noise calibration : in sitesurvey */ + checkLoopCount = 1000; /* 1000*100 = 100ms */ + } + + hpPriv->latestFrequency = frequency; + hpPriv->latestBw40 = bw40; + hpPriv->latestExtOffset = extOffset; + + if ((hpPriv->dot11Mode == ZM_HAL_80211_MODE_IBSS_GENERAL) || + (hpPriv->dot11Mode == ZM_HAL_80211_MODE_IBSS_WPA2PSK)) + { + if ( frequency <= ZM_CH_G_14 ) + { + /* workaround for 11g Ad Hoc beacon distribution */ + zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC0_CW, 0x7f0007); + //zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC1_AC0_AIFS, 0x1c04901c); + } + } + + /* AHB, DAC, ADC clock selection by static20/ht2040 */ + zfSelAdcClk(dev, bw40, frequency); + + /* clear bb_heavy_clip_enable */ + reg_write(0x99e0, 0x200); + zfFlushDelayWrite(dev); + + /* Set CTS/RTS rate */ + if ( frequency > ZM_CH_G_14 ) + { + //zfHpSetRTSCTSRate(dev, 0x10b010b); /* OFDM 6M */ + new_band = 1; + } + else + { + //zfHpSetRTSCTSRate(dev, 0x30003); /* CCK 11M */ + new_band = 0; + } + + if (((struct zsHpPriv*)wd->hpPrivate)->hwFrequency > ZM_CH_G_14) + old_band = 1; + else + old_band = 0; + + //Workaround for 2.4GHz only device + if ((hpPriv->OpFlags & 0x1) == 0) + { + if ((((struct zsHpPriv*)wd->hpPrivate)->hwFrequency == ZM_CH_G_1) && (frequency == ZM_CH_G_2)) + { + /* Force to do band switching */ + old_band = 1; + } + } + + /* Notify channel switch to firmware */ + /* TX/RX must be stopped by now */ + cmd[0] = 0 | (ZM_CMD_FREQ_STRAT << 8); + ret = zfIssueCmd(dev, cmd, 8, ZM_OID_INTERNAL_WRITE, 0); + + if ((initRF != 0) || (new_band != old_band) + || (((struct zsHpPriv*)wd->hpPrivate)->hwBw40 != bw40)) + { + /* band switch */ + zm_msg0_scan(ZM_LV_1, "=====band switch====="); + + if (initRF == 2 ) + { + //Cold reset BB/ADDA + zfDelayWriteInternalReg(dev, 0x1d4004, 0x800); + zfFlushDelayWrite(dev); + zm_msg0_scan(ZM_LV_1, "Do cold reset BB/ADDA"); + } + else + { + //Warm reset BB/ADDA + zfDelayWriteInternalReg(dev, 0x1d4004, 0x400); + zfFlushDelayWrite(dev); + } + + /* reset workaround state to default */ + hpPriv->rxStrongRSSI = 0; + hpPriv->strongRSSI = 0; + + zfDelayWriteInternalReg(dev, 0x1d4004, 0x0); + zfFlushDelayWrite(dev); + + zfInitPhy(dev, frequency, bw40); + +// zfiCheckRifs(dev); + + /* Bank 0 1 2 3 5 6 7 */ + zfSetRfRegs(dev, frequency); + /* Bank 4 */ + zfSetBank4AndPowerTable(dev, frequency, bw40, extOffset); + + cmd[0] = 32 | (ZM_CMD_RF_INIT << 8); + } + else //((new_band == old_band) && !initRF) + { + /* same band */ + + /* Force disable CR671 bit20 / 7823 */ + /* The bug has to do with the polarity of the pdadc offset calibration. There */ + /* is an initial calibration that is OK, and there is a continuous */ + /* calibration that updates the pddac with the wrong polarity. Fortunately */ + /* the second loop can be disabled with a bit called en_pd_dc_offset_thr. */ +#if 0 + cmdB[0] = 8 | (ZM_CMD_BITAND << 8);; + cmdB[1] = (0xa27c + 0x1bc000); + cmdB[2] = 0xffefffff; + ret = zfIssueCmd(dev, cmdB, 12, ZM_OID_INTERNAL_WRITE, 0); +#endif + + /* Bank 4 */ + zfSetBank4AndPowerTable(dev, frequency, bw40, extOffset); + + + cmd[0] = 32 | (ZM_CMD_FREQUENCY << 8); + } + + /* Compatibility for new layout UB83 */ + /* Setting code at CR1 here move from the func:zfHwHTEnable() in firmware */ + if (((struct zsHpPriv*)wd->hpPrivate)->halCapability & ZM_HP_CAP_11N_ONE_TX_STREAM) + { + /* UB83 : one stream */ + tmpValue = 0; + } + else + { + /* UB81, UB82 : two stream */ + tmpValue = 0x100; + } + + if (1) //if (((struct zsHpPriv*)wd->hpPrivate)->hw_HT_ENABLE == 1) + { + if (bw40 == 1) + { + if (extOffset == 1) { + reg_write(0x9804, tmpValue | 0x2d4); //3d4 for real + } + else { + reg_write(0x9804, tmpValue | 0x2c4); //3c4 for real + } + //# Dyn HT2040.Refer to Reg 1. + //#[3]:single length (4us) 1st HT long training symbol; use Walsh spatial spreading for 2 chains 2 streams TX + //#[c]:allow short GI for HT40 packets; enable HT detection. + //#[4]:enable 20/40 MHz channel detection. + } + else + { + reg_write(0x9804, tmpValue | 0x240); + //# Static HT20 + //#[3]:single length (4us) 1st HT long training symbol; use Walsh spatial spreading for 2 chains 2 streams TX + //#[4]:Otus don't allow short GI for HT20 packets yet; enable HT detection. + //#[0]:disable 20/40 MHz channel detection. + } + } + else + { + reg_write(0x9804, 0x0); + //# Legacy;# Direct Mapping for each chain. + //#Be modified by Oligo to add dynanic for legacy. + if (bw40 == 1) + { + reg_write(0x9804, 0x4); //# Dyn Legacy .Refer to reg 1. + } + else + { + reg_write(0x9804, 0x0); //# Static Legacy + } + } + zfFlushDelayWrite(dev); + /* end of ub83 compatibility */ + + /* Set Power, TPC, Gain table... */ + zfSetPowerCalTable(dev, frequency, bw40, extOffset); + + + /* store frequency */ + ((struct zsHpPriv*)wd->hpPrivate)->hwFrequency = (u16_t)frequency; + ((struct zsHpPriv*)wd->hpPrivate)->hwBw40 = bw40; + ((struct zsHpPriv*)wd->hpPrivate)->hwExtOffset = extOffset; + + zfGetHwTurnOffdynParam(dev, + frequency, bw40, extOffset, + &delta_slope_coeff_exp, + &delta_slope_coeff_man, + &delta_slope_coeff_exp_shgi, + &delta_slope_coeff_man_shgi); + + /* related functions */ + frequency = frequency*1000; + /* len[36] : type[0x30] : seq[?] */ +// cmd[0] = 28 | (ZM_CMD_FREQUENCY << 8); + cmd[1] = frequency; + cmd[2] = bw40;//((struct zsHpPriv*)wd->hpPrivate)->hw_DYNAMIC_HT2040_EN; + cmd[3] = (extOffset<<2)|0x1;//((wd->ExtOffset << 2) | ((struct zsHpPriv*)wd->hpPrivate)->hw_HT_ENABLE); + cmd[4] = delta_slope_coeff_exp; + cmd[5] = delta_slope_coeff_man; + cmd[6] = delta_slope_coeff_exp_shgi; + cmd[7] = delta_slope_coeff_man_shgi; + cmd[8] = checkLoopCount; + + ret = zfIssueCmd(dev, cmd, 36, ZM_CMD_SET_FREQUENCY, 0); + + // delay temporarily, wait for new PHY and RF + //zfwSleep(dev, 1000); +} + + +/******************** Key ********************/ + +u16_t zfHpResetKeyCache(zdev_t* dev) +{ + u8_t i; + u32_t key[4] = {0, 0, 0, 0}; + + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv=wd->hpPrivate; + + for(i=0;i<4;i++) + { + zfHpSetDefaultKey(dev, i, ZM_WEP64, key, NULL); + } + zfDelayWriteInternalReg(dev, ZM_MAC_REG_ROLL_CALL_TBL_L, 0x00); + zfDelayWriteInternalReg(dev, ZM_MAC_REG_ROLL_CALL_TBL_H, 0x00); + zfFlushDelayWrite(dev); + + hpPriv->camRollCallTable = (u64_t) 0; + + return 0; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfSetKey */ +/* Set key. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* 0 : success */ +/* other : fail */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2006.1 */ +/* */ +/************************************************************************/ +/* ! please use zfCoreSetKey() in 80211Core for SetKey */ +u32_t zfHpSetKey(zdev_t* dev, u8_t user, u8_t keyId, u8_t type, + u16_t* mac, u32_t* key) +{ + u32_t cmd[(ZM_MAX_CMD_SIZE/4)]; + u16_t ret; + u16_t i; + + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv=wd->hpPrivate; + +#if 0 /* remove to zfCoreSetKey() */ + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + wd->sta.flagKeyChanging++; + zm_debug_msg1(" zfHpSetKey++++ ", wd->sta.flagKeyChanging); + zmw_leave_critical_section(dev); +#endif + + cmd[0] = 0x0000281C; + cmd[1] = ((u32_t)keyId<<16) + (u32_t)user; + cmd[2] = ((u32_t)mac[0]<<16) + (u32_t)type; + cmd[3] = ((u32_t)mac[2]<<16) + ((u32_t)mac[1]); + + for (i=0; i<4; i++) + { + cmd[4+i] = key[i]; + } + + if (user < 64) + { + hpPriv->camRollCallTable |= ((u64_t) 1) << user; + } + + //ret = zfIssueCmd(dev, cmd, 32, ZM_OID_INTERNAL_WRITE, NULL); + ret = zfIssueCmd(dev, cmd, 32, ZM_CMD_SET_KEY, NULL); + return ret; +} + + +u32_t zfHpSetApPairwiseKey(zdev_t* dev, u16_t* staMacAddr, u8_t type, + u32_t* key, u32_t* micKey, u16_t staAid) +{ + if ((staAid!=0) && (staAid<64)) + { + zfHpSetKey(dev, (staAid-1), 0, type, staMacAddr, key); + if ((type == ZM_TKIP) +#ifdef ZM_ENABLE_CENC + || (type == ZM_CENC) +#endif //ZM_ENABLE_CENC + ) + zfHpSetKey(dev, (staAid-1), 1, type, staMacAddr, micKey); + return 0; + } + return 1; +} + +u32_t zfHpSetApGroupKey(zdev_t* dev, u16_t* apMacAddr, u8_t type, + u32_t* key, u32_t* micKey, u16_t vapId) +{ + zfHpSetKey(dev, ZM_USER_KEY_DEFAULT - 1 - vapId, 0, type, apMacAddr, key); // 6D18 modify from 0 to 1 ?? + if ((type == ZM_TKIP) +#ifdef ZM_ENABLE_CENC + || (type == ZM_CENC) +#endif //ZM_ENABLE_CENC + ) + zfHpSetKey(dev, ZM_USER_KEY_DEFAULT - 1 - vapId, 1, type, apMacAddr, micKey); + return 0; +} + +u32_t zfHpSetDefaultKey(zdev_t* dev, u8_t keyId, u8_t type, u32_t* key, u32_t* micKey) +{ + u16_t macAddr[3] = {0, 0, 0}; + + #ifdef ZM_ENABLE_IBSS_WPA2PSK + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv = wd->hpPrivate; + + if ( hpPriv->dot11Mode == ZM_HAL_80211_MODE_IBSS_WPA2PSK ) + { /* If not wpa2psk , use traditional */ + /* Because the bug of chip , defaultkey should follow the key map rule in register 700 */ + if ( keyId == 0 ) + zfHpSetKey(dev, ZM_USER_KEY_DEFAULT+keyId, 0, type, macAddr, key); + else + zfHpSetKey(dev, ZM_USER_KEY_DEFAULT+keyId, 1, type, macAddr, key); + } + else + zfHpSetKey(dev, ZM_USER_KEY_DEFAULT+keyId, 0, type, macAddr, key); + #else + zfHpSetKey(dev, ZM_USER_KEY_DEFAULT+keyId, 0, type, macAddr, key); + #endif + if ((type == ZM_TKIP) + +#ifdef ZM_ENABLE_CENC + || (type == ZM_CENC) +#endif //ZM_ENABLE_CENC + ) + { + zfHpSetKey(dev, ZM_USER_KEY_DEFAULT+keyId, 1, type, macAddr, micKey); + } + + return 0; +} + +u32_t zfHpSetPerUserKey(zdev_t* dev, u8_t user, u8_t keyId, u8_t* mac, u8_t type, u32_t* key, u32_t* micKey) +{ +#ifdef ZM_ENABLE_IBSS_WPA2PSK + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv = wd->hpPrivate; + + if ( hpPriv->dot11Mode == ZM_HAL_80211_MODE_IBSS_WPA2PSK ) + { /* If not wpa2psk , use traditional */ + if(keyId) + { /* Set Group Key */ + zfHpSetKey(dev, user, 1, type, (u16_t *)mac, key); + } + else if(keyId == 0) + { /* Set Pairwise Key */ + zfHpSetKey(dev, user, 0, type, (u16_t *)mac, key); + } + } + else + { + zfHpSetKey(dev, user, keyId, type, (u16_t *)mac, key); + } +#else + zfHpSetKey(dev, user, keyId, type, (u16_t *)mac, key); +#endif + + if ((type == ZM_TKIP) +#ifdef ZM_ENABLE_CENC + || (type == ZM_CENC) +#endif //ZM_ENABLE_CENC + ) + { + zfHpSetKey(dev, user, keyId + 1, type, (u16_t *)mac, micKey); + } + return 0; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfHpRemoveKey */ +/* Remove key. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* 0 : success */ +/* other : fail */ +/* */ +/* AUTHOR */ +/* Yuan-Gu Wei ZyDAS Technology Corporation 2006.6 */ +/* */ +/************************************************************************/ +u16_t zfHpRemoveKey(zdev_t* dev, u16_t user) +{ + u32_t cmd[(ZM_MAX_CMD_SIZE/4)]; + u16_t ret = 0; + + cmd[0] = 0x00002904; + cmd[1] = (u32_t)user; + + ret = zfIssueCmd(dev, cmd, 8, ZM_OID_INTERNAL_WRITE, NULL); + return ret; +} + + + +/******************** DMA ********************/ +u16_t zfHpStartRecv(zdev_t* dev) +{ + zfDelayWriteInternalReg(dev, 0x1c3d30, 0x100); + zfFlushDelayWrite(dev); + + return 0; +} + +u16_t zfHpStopRecv(zdev_t* dev) +{ + return 0; +} + + +/******************** MAC ********************/ +void zfInitMac(zdev_t* dev) +{ + /* ACK extension register */ + // jhlee temp : change value 0x2c -> 0x40 + // honda resolve short preamble problem : 0x40 -> 0x75 + zfDelayWriteInternalReg(dev, ZM_MAC_REG_ACK_EXTENSION, 0x40); // 0x28 -> 0x2c 6522:yflee + + /* TxQ0/1/2/3 Retry MAX=2 => transmit 3 times and degrade rate for retry */ + /* PB42 AP crash issue: */ + /* Workaround the crash issue by CTS/RTS, set retry max to zero for */ + /* workaround tx underrun which enable CTS/RTS */ + zfDelayWriteInternalReg(dev, ZM_MAC_REG_RETRY_MAX, 0); // 0x11111 => 0 + + /* use hardware MIC check */ + zfDelayWriteInternalReg(dev, ZM_MAC_REG_SNIFFER, 0x2000000); + + /* Set Rx threshold to 1600 */ +#if ZM_LARGEPAYLOAD_TEST == 1 + zfDelayWriteInternalReg(dev, ZM_MAC_REG_RX_THRESHOLD, 0xc4000); +#else + #ifndef ZM_DISABLE_AMSDU8K_SUPPORT + /* The maximum A-MSDU length is 3839/7935 */ + zfDelayWriteInternalReg(dev, ZM_MAC_REG_RX_THRESHOLD, 0xc1f80); + #else + zfDelayWriteInternalReg(dev, ZM_MAC_REG_RX_THRESHOLD, 0xc0f80); + #endif +#endif + + //zfDelayWriteInternalReg(dev, ZM_MAC_REG_DYNAMIC_SIFS_ACK, 0x10A); + zfDelayWriteInternalReg(dev, ZM_MAC_REG_RX_PE_DELAY, 0x70); + zfDelayWriteInternalReg(dev, ZM_MAC_REG_EIFS_AND_SIFS, 0xa144000); + zfDelayWriteInternalReg(dev, ZM_MAC_REG_SLOT_TIME, 9<<10); + + /* CF-END mode */ + zfDelayWriteInternalReg(dev, 0x1c3b2c, 0x19000000); + + //NAV protects ACK only (in TXOP) + zfDelayWriteInternalReg(dev, 0x1c3b38, 0x201); + + + /* Set Beacon PHY CTRL's TPC to 0x7, TA1=1 */ + /* OTUS set AM to 0x1 */ + zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_HT1, 0x8000170); + + /* TODO : wep backoff protection 0x63c */ + zfDelayWriteInternalReg(dev, ZM_MAC_REG_BACKOFF_PROTECT, 0x105); + + /* AGG test code*/ + /* Aggregation MAX number and timeout */ + zfDelayWriteInternalReg(dev, 0x1c3b9c, 0x10000a); + /* Filter any control frames, BAR is bit 24 */ + zfDelayWriteInternalReg(dev, 0x1c368c, 0x0500ffff); + /* Enable deaggregator */ + zfDelayWriteInternalReg(dev, 0x1c3c40, 0x1); + + /* Basic rate */ + zfDelayWriteInternalReg(dev, ZM_MAC_REG_BASIC_RATE, 0x150f); + zfDelayWriteInternalReg(dev, ZM_MAC_REG_MANDATORY_RATE, 0x150f); + zfDelayWriteInternalReg(dev, ZM_MAC_REG_RTS_CTS_RATE, 0x10b01bb); + + /* MIMO resposne control */ + zfDelayWriteInternalReg(dev, 0x1c3694, 0x4003C1E);/* bit 26~28 otus-AM */ + + /* Enable LED0 and LED1 */ + zfDelayWriteInternalReg(dev, 0x1d0100, 0x3); + zfDelayWriteInternalReg(dev, 0x1d0104, 0x3); + + /* switch MAC to OTUS interface */ + zfDelayWriteInternalReg(dev, 0x1c3600, 0x3); + + /* RXMAC A-MPDU length threshold */ + zfDelayWriteInternalReg(dev, 0x1c3c50, 0xffff); + + /* Phy register read timeout */ + zfDelayWriteInternalReg(dev, 0x1c3680, 0xf00008); + + /* Disable Rx TimeOut : workaround for BB. + * OTUS would interrupt the rx frame that sent by OWL TxUnderRun + * because OTUS rx timeout behavior, then OTUS would not ack the BA for + * this AMPDU from OWL. + * Fix by Perry Hwang. 2007/05/10. + * 0x1c362c : Rx timeout value : bit 27~16 + */ + zfDelayWriteInternalReg(dev, 0x1c362c, 0x0); + + //Set USB Rx stream mode MAX packet number to 2 + // Max packet number = *0x1e1110 + 1 + zfDelayWriteInternalReg(dev, 0x1e1110, 0x4); + //Set USB Rx stream mode timeout to 10us + zfDelayWriteInternalReg(dev, 0x1e1114, 0x80); + + //Set CPU clock frequency to 88/80MHz + zfDelayWriteInternalReg(dev, 0x1D4008, 0x73); + + //Set WLAN DMA interrupt mode : generate int per packet + zfDelayWriteInternalReg(dev, 0x1c3d7c, 0x110011); + + /* 7807 */ + /* enable func : Reset FIFO1 and FIFO2 when queue-gnt is low */ + /* 0x1c3bb0 Bit2 */ + /* Disable SwReset in firmware for TxHang, enable reset FIFO func. */ + zfDelayWriteInternalReg(dev, 0x1c3bb0, 0x4); + + /* Disables the CF_END frame */ + zfDelayWriteInternalReg(dev, ZM_MAC_REG_TXOP_NOT_ENOUGH_INDICATION, 0x141E0F48); + + /* Disable the SW Decrypt*/ + zfDelayWriteInternalReg(dev, 0x1c3678, 0x70); + zfFlushDelayWrite(dev); + //--------------------- + + /* Set TxQs CWMIN, CWMAX, AIFS and TXO to WME STA default. */ + zfUpdateDefaultQosParameter(dev, 0); + + //zfSelAdcClk(dev, 0); + + return; +} + + +u16_t zfHpSetSnifferMode(zdev_t* dev, u16_t on) +{ + if (on != 0) + { + zfDelayWriteInternalReg(dev, ZM_MAC_REG_SNIFFER, 0x2000001); + } + else + { + zfDelayWriteInternalReg(dev, ZM_MAC_REG_SNIFFER, 0x2000000); + } + zfFlushDelayWrite(dev); + return 0; +} + + +u16_t zfHpSetApStaMode(zdev_t* dev, u8_t mode) +{ + zmw_get_wlan_dev(dev); + + struct zsHpPriv* hpPriv = wd->hpPrivate; + hpPriv->dot11Mode = mode; + + switch(mode) + { + case ZM_HAL_80211_MODE_AP: + zfDelayWriteInternalReg(dev, 0x1c3700, 0x0f0000a1); + zfDelayWriteInternalReg(dev, 0x1c3c40, 0x1); + break; + + case ZM_HAL_80211_MODE_STA: + zfDelayWriteInternalReg(dev, 0x1c3700, 0x0f000002); + zfDelayWriteInternalReg(dev, 0x1c3c40, 0x1); + break; + + case ZM_HAL_80211_MODE_IBSS_GENERAL: + zfDelayWriteInternalReg(dev, 0x1c3700, 0x0f000000); + zfDelayWriteInternalReg(dev, 0x1c3c40, 0x1); + break; + + case ZM_HAL_80211_MODE_IBSS_WPA2PSK: + zfDelayWriteInternalReg(dev, 0x1c3700, 0x0f0000e0); + zfDelayWriteInternalReg(dev, 0x1c3c40, 0x41); // for multiple ( > 2 ) stations IBSS network + break; + + default: + goto skip; + } + + zfFlushDelayWrite(dev); + +skip: + return 0; +} + + +u16_t zfHpSetBssid(zdev_t* dev, u8_t* bssidSrc) +{ + u32_t address; + u16_t *bssid = (u16_t *)bssidSrc; + + address = bssid[0] + (((u32_t)bssid[1]) << 16); + zfDelayWriteInternalReg(dev, 0x1c3618, address); + + address = (u32_t)bssid[2]; + zfDelayWriteInternalReg(dev, 0x1c361C, address); + zfFlushDelayWrite(dev); + return 0; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfHpUpdateQosParameter */ +/* Update TxQs CWMIN, CWMAX, AIFS and TXOP. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* cwminTbl : CWMIN parameter for TxQs */ +/* cwmaxTbl : CWMAX parameter for TxQs */ +/* aifsTbl: AIFS parameter for TxQs */ +/* txopTbl : TXOP parameter for TxQs */ +/* */ +/* OUTPUTS */ +/* none */ +/* */ +/* AUTHOR */ +/* Stephen ZyDAS Technology Corporation 2006.6 */ +/* */ +/************************************************************************/ +u8_t zfHpUpdateQosParameter(zdev_t* dev, u16_t* cwminTbl, u16_t* cwmaxTbl, + u16_t* aifsTbl, u16_t* txopTbl) +{ + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv = wd->hpPrivate; + + zm_msg0_mm(ZM_LV_0, "zfHalUpdateQosParameter()"); + + /* Note : Do not change cwmin for Q0 in Ad Hoc mode */ + /* otherwise driver will fail in Wifi beacon distribution */ + if (hpPriv->dot11Mode == ZM_HAL_80211_MODE_STA) + { +#if 0 //Restore CWmin to improve down link throughput + //cheating in BE traffic + if (wd->sta.EnableHT == 1) + { + //cheating in BE traffic + cwminTbl[0] = 7;//15; + } +#endif + cwmaxTbl[0] = 127;//1023; + aifsTbl[0] = 2*9+10;//3 * 9 + 10; + } + + /* CWMIN and CWMAX */ + zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC0_CW, cwminTbl[0] + + ((u32_t)cwmaxTbl[0]<<16)); + zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC1_CW, cwminTbl[1] + + ((u32_t)cwmaxTbl[1]<<16)); + zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC2_CW, cwminTbl[2] + + ((u32_t)cwmaxTbl[2]<<16)); + zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC3_CW, cwminTbl[3] + + ((u32_t)cwmaxTbl[3]<<16)); + zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC4_CW, cwminTbl[4] + + ((u32_t)cwmaxTbl[4]<<16)); + + /* AIFS */ + zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC1_AC0_AIFS, aifsTbl[0] + +((u32_t)aifsTbl[0]<<12)+((u32_t)aifsTbl[0]<<24)); + zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC3_AC2_AIFS, (aifsTbl[0]>>8) + +((u32_t)aifsTbl[0]<<4)+((u32_t)aifsTbl[0]<<16)); + + /* TXOP */ + zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC1_AC0_TXOP, txopTbl[0] + + ((u32_t)txopTbl[1]<<16)); + zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC3_AC2_TXOP, txopTbl[2] + + ((u32_t)txopTbl[3]<<16)); + + zfFlushDelayWrite(dev); + + hpPriv->txop[0] = txopTbl[0]; + hpPriv->txop[1] = txopTbl[1]; + hpPriv->txop[2] = txopTbl[2]; + hpPriv->txop[3] = txopTbl[3]; + hpPriv->cwmin[0] = cwminTbl[0]; + hpPriv->cwmax[0] = cwmaxTbl[0]; + hpPriv->cwmin[1] = cwminTbl[1]; + hpPriv->cwmax[1] = cwmaxTbl[1]; + + return 0; +} + + +void zfHpSetAtimWindow(zdev_t* dev, u16_t atimWin) +{ + zm_msg1_mm(ZM_LV_0, "Set ATIM window to ", atimWin); + zfDelayWriteInternalReg(dev, ZM_MAC_REG_ATIM_WINDOW, atimWin); + zfFlushDelayWrite(dev); +} + + +void zfHpSetBasicRateSet(zdev_t* dev, u16_t bRateBasic, u16_t gRateBasic) +{ + zfDelayWriteInternalReg(dev, ZM_MAC_REG_BASIC_RATE, bRateBasic + | ((u16_t)gRateBasic<<8)); + zfFlushDelayWrite(dev); +} + + +/* HT40 send by OFDM 6M */ +/* otherwise use reg 0x638 */ +void zfHpSetRTSCTSRate(zdev_t* dev, u32_t rate) +{ + zfDelayWriteInternalReg(dev, ZM_MAC_REG_RTS_CTS_RATE, rate); + zfFlushDelayWrite(dev); +} + +void zfHpSetMacAddress(zdev_t* dev, u16_t* macAddr, u16_t macAddrId) +{ + if (macAddrId == 0) + { + zfDelayWriteInternalReg(dev, ZM_MAC_REG_MAC_ADDR_L, + (((u32_t)macAddr[1])<<16) | macAddr[0]); + zfDelayWriteInternalReg(dev, ZM_MAC_REG_MAC_ADDR_H, macAddr[2]); + } + else if (macAddrId <= 7) + { + zfDelayWriteInternalReg(dev, ZM_MAC_REG_ACK_TABLE+((macAddrId-1)*8), + macAddr[0] + ((u32_t)macAddr[1]<<16)); + zfDelayWriteInternalReg(dev, ZM_MAC_REG_ACK_TABLE+((macAddrId-1)*8)+4, + macAddr[2]); + } + zfFlushDelayWrite(dev); +} + +void zfHpSetMulticastList(zdev_t* dev, u8_t size, u8_t* pList, u8_t bAllMulticast) +{ + struct zsMulticastAddr* pMacList = (struct zsMulticastAddr*) pList; + u8_t i; + u32_t value; + u32_t swRegMulHashValueH, swRegMulHashValueL; + + swRegMulHashValueH = 0x80000000; + swRegMulHashValueL = 0; + + if ( bAllMulticast ) + { + swRegMulHashValueH = swRegMulHashValueL = ~0; + } + else + { + for(i=0; i> 2; + + if ( value < 32 ) + { + swRegMulHashValueL |= (1 << value); + } + else + { + swRegMulHashValueH |= (1 << (value-32)); + } + } + } + + zfDelayWriteInternalReg(dev, ZM_MAC_REG_GROUP_HASH_TBL_L, + swRegMulHashValueL); + zfDelayWriteInternalReg(dev, ZM_MAC_REG_GROUP_HASH_TBL_H, + swRegMulHashValueH); + zfFlushDelayWrite(dev); + return; +} + +/******************** Beacon ********************/ +void zfHpEnableBeacon(zdev_t* dev, u16_t mode, u16_t bcnInterval, u16_t dtim, u8_t enableAtim) +{ + u32_t value; + + zmw_get_wlan_dev(dev); + + /* Beacon Ready */ + zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_CTRL, 0); + /* Beacon DMA buffer address */ + zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_ADDR, ZM_BEACON_BUFFER_ADDRESS); + + value = bcnInterval; + + value |= (((u32_t) dtim) << 16); + + if (mode == ZM_MODE_AP) + { + + value |= 0x1000000; + } + else if (mode == ZM_MODE_IBSS) + { + value |= 0x2000000; + + if ( enableAtim ) + { + value |= 0x4000000; + } + ((struct zsHpPriv*)wd->hpPrivate)->ibssBcnEnabled = 1; + ((struct zsHpPriv*)wd->hpPrivate)->ibssBcnInterval = value; + } + zfDelayWriteInternalReg(dev, ZM_MAC_REG_PRETBTT, (bcnInterval-6)<<16); + + /* Beacon period and beacon enable */ + zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_PERIOD, value); + zfFlushDelayWrite(dev); +} + +void zfHpDisableBeacon(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + ((struct zsHpPriv*)wd->hpPrivate)->ibssBcnEnabled = 0; + + zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_PERIOD, 0); + zfFlushDelayWrite(dev); +} + +void zfHpLedCtrl(zdev_t* dev, u16_t ledId, u8_t mode) +{ + u16_t state; + zmw_get_wlan_dev(dev); + + //zm_debug_msg1("LED ID=", ledId); + //zm_debug_msg1("LED mode=", mode); + if (ledId < 2) + { + if (((struct zsHpPriv*)wd->hpPrivate)->ledMode[ledId] != mode) + { + ((struct zsHpPriv*)wd->hpPrivate)->ledMode[ledId] = mode; + + state = ((struct zsHpPriv*)wd->hpPrivate)->ledMode[0] + | (((struct zsHpPriv*)wd->hpPrivate)->ledMode[1]<<1); + zfDelayWriteInternalReg(dev, 0x1d0104, state); + zfFlushDelayWrite(dev); + //zm_debug_msg0("Update LED"); + } + } +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfHpResetTxRx */ +/* Reset Tx and Rx Desc. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* 0 : success */ +/* other : fail */ +/* */ +/* AUTHOR */ +/* Chao-Wen Yang ZyDAS Technology Corporation 2007.3 */ +/* */ +/************************************************************************/ +u16_t zfHpUsbReset(zdev_t* dev) +{ + u32_t cmd[(ZM_MAX_CMD_SIZE/4)]; + u16_t ret = 0; + + //zm_debug_msg0("CWY - Reset Tx and Rx"); + + cmd[0] = 0 | (ZM_CMD_RESET << 8); + + ret = zfIssueCmd(dev, cmd, 4, ZM_OID_INTERNAL_WRITE, NULL); + return ret; +} + +u16_t zfHpDKReset(zdev_t* dev, u8_t flag) +{ + u32_t cmd[(ZM_MAX_CMD_SIZE/4)]; + u16_t ret = 0; + + //zm_debug_msg0("CWY - Reset Tx and Rx"); + + cmd[0] = 4 | (ZM_CMD_DKRESET << 8); + cmd[1] = flag; + + ret = zfIssueCmd(dev, cmd, 8, ZM_OID_INTERNAL_WRITE, NULL); + return ret; +} + +u32_t zfHpCwmUpdate(zdev_t* dev) +{ + //u32_t cmd[3]; + //u16_t ret; + // + //cmd[0] = 0x00000008; + //cmd[1] = 0x1c36e8; + //cmd[2] = 0x1c36ec; + // + //ret = zfIssueCmd(dev, cmd, 12, ZM_CWM_READ, 0); + //return ret; + zmw_get_wlan_dev(dev); + + struct zsHpPriv* hpPriv=wd->hpPrivate; + + zfCoreCwmBusy(dev, zfCwmIsExtChanBusy(hpPriv->ctlBusy, hpPriv->extBusy)); + + hpPriv->ctlBusy = 0; + hpPriv->extBusy = 0; + + return 0; +} + +u32_t zfHpAniUpdate(zdev_t* dev) +{ + u32_t cmd[5]; + u16_t ret; + + cmd[0] = 0x00000010; + cmd[1] = 0x1c36e8; + cmd[2] = 0x1c36ec; + cmd[3] = 0x1c3cb4; + cmd[4] = 0x1c3cb8; + + ret = zfIssueCmd(dev, cmd, 20, ZM_ANI_READ, 0); + return ret; +} + +/* + * Update Beacon RSSI in ANI + */ +u32_t zfHpAniUpdateRssi(zdev_t* dev, u8_t rssi) +{ + zmw_get_wlan_dev(dev); + + struct zsHpPriv* hpPriv=wd->hpPrivate; + + hpPriv->stats.ast_nodestats.ns_avgbrssi = rssi; + + return 0; +} + +#define ZM_SEEPROM_MAC_ADDRESS_OFFSET (0x1400 + (0x106<<1)) +#define ZM_SEEPROM_REGDOMAIN_OFFSET (0x1400 + (0x104<<1)) +#define ZM_SEEPROM_VERISON_OFFSET (0x1400 + (0x102<<1)) +#define ZM_SEEPROM_HARDWARE_TYPE_OFFSET (0x1374) +#define ZM_SEEPROM_HW_HEAVY_CLIP (0x161c) + +u32_t zfHpGetMacAddress(zdev_t* dev) +{ + u32_t cmd[7]; + u16_t ret; + + cmd[0] = 0x00000000 | 24; + cmd[1] = ZM_SEEPROM_MAC_ADDRESS_OFFSET; + cmd[2] = ZM_SEEPROM_MAC_ADDRESS_OFFSET+4; + cmd[3] = ZM_SEEPROM_REGDOMAIN_OFFSET; + cmd[4] = ZM_SEEPROM_VERISON_OFFSET; + cmd[5] = ZM_SEEPROM_HARDWARE_TYPE_OFFSET; + cmd[6] = ZM_SEEPROM_HW_HEAVY_CLIP; + + ret = zfIssueCmd(dev, cmd, 28, ZM_MAC_READ, 0); + return ret; +} + +u32_t zfHpGetTransmitPower(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + struct zsHpPriv* hpPriv = wd->hpPrivate; + u16_t tpc = 0; + + if (hpPriv->hwFrequency < 3000) { + tpc = hpPriv->tPow2x2g[0] & 0x3f; + wd->maxTxPower2 &= 0x3f; + tpc = (tpc > wd->maxTxPower2)? wd->maxTxPower2 : tpc; + } else { + tpc = hpPriv->tPow2x5g[0] & 0x3f; + wd->maxTxPower5 &= 0x3f; + tpc = (tpc > wd->maxTxPower5)? wd->maxTxPower5 : tpc; + } + + return tpc; +} + +u8_t zfHpGetMinTxPower(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + struct zsHpPriv* hpPriv = wd->hpPrivate; + u8_t tpc = 0; + + if (hpPriv->hwFrequency < 3000) + { + if(wd->BandWidth40) + { + //40M + tpc = (hpPriv->tPow2x2gHt40[7]&0x3f); + } + else + { + //20M + tpc = (hpPriv->tPow2x2gHt20[7]&0x3f); + } + } + else + { + if(wd->BandWidth40) + { + //40M + tpc = (hpPriv->tPow2x5gHt40[7]&0x3f); + } + else + { + //20M + tpc = (hpPriv->tPow2x5gHt20[7]&0x3f); + } + } + + return tpc; +} + +u8_t zfHpGetMaxTxPower(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + struct zsHpPriv* hpPriv = wd->hpPrivate; + u8_t tpc = 0; + + if (hpPriv->hwFrequency < 3000) + { + tpc = (hpPriv->tPow2xCck[0]&0x3f); + } + else + { + tpc =(hpPriv->tPow2x5g[0]&0x3f); + } + + return tpc; +} + +u32_t zfHpLoadEEPROMFromFW(zdev_t* dev) +{ + u32_t cmd[16]; + u32_t ret=0, i, j; + zmw_get_wlan_dev(dev); + + i = ((struct zsHpPriv*)wd->hpPrivate)->eepromImageRdReq; + + cmd[0] = ZM_HAL_MAX_EEPROM_PRQ*4; + + for (j=0; jhpPrivate; + u8_t polluted = 0; + u8_t ackTpc; + + /* Workaround : Make OTUS fire more beacon in ad hoc mode in 2.4GHz */ + if (hpPriv->ibssBcnEnabled != 0) + { + if (hpPriv->hwFrequency <= ZM_CH_G_14) + { + if ((wd->tick % 10) == 0) + { + if ((wd->tick % 40) == 0) + { + zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_PERIOD, hpPriv->ibssBcnInterval-1); + polluted = 1; + } + else + { + zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_PERIOD, hpPriv->ibssBcnInterval); + polluted = 1; + } + } + } + } + + if ((wd->tick & 0x3f) == 0x25) + { + /* Workaround for beacon stuck after SW reset */ + if (hpPriv->ibssBcnEnabled != 0) + { + zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_ADDR, ZM_BEACON_BUFFER_ADDRESS); + polluted = 1; + } + + //DbgPrint("hpPriv->aggMaxDurationBE=%d", hpPriv->aggMaxDurationBE); + //DbgPrint("wd->sta.avgSizeOfReceivePackets=%d", wd->sta.avgSizeOfReceivePackets); + if (( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) + && (zfStaIsConnected(dev)) + && (wd->sta.EnableHT == 1) //11n mode + && (wd->BandWidth40 == 1) //40MHz mode + && (wd->sta.enableDrvBA ==0) //Marvel AP + && (hpPriv->aggMaxDurationBE > 2000) //BE TXOP > 2ms + && (wd->sta.avgSizeOfReceivePackets > 1420)) + { + zfDelayWriteInternalReg(dev, 0x1c3b9c, 0x8000a); + polluted = 1; + } + else + { + zfDelayWriteInternalReg(dev, 0x1c3b9c, hpPriv->aggPktNum); + polluted = 1; + } + + if (wd->dynamicSIFSEnable == 0) + { + if (( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) + && (zfStaIsConnected(dev)) + && (wd->sta.EnableHT == 1) //11n mode + && (wd->BandWidth40 == 0) //20MHz mode + && (wd->sta.enableDrvBA ==0)) //Marvel AP + { + zfDelayWriteInternalReg(dev, 0x1c3698, 0x5144000); + polluted = 1; + } + else + { + zfDelayWriteInternalReg(dev, 0x1c3698, 0xA144000); + polluted = 1; + } + } + else + { + if (( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) + && (zfStaIsConnected(dev)) + && (wd->sta.EnableHT == 1) //11n mode + && (wd->sta.athOwlAp == 1)) //Atheros AP + { + if (hpPriv->retransmissionEvent) + { + switch(hpPriv->latestSIFS) + { + case 0: + hpPriv->latestSIFS = 1; + zfDelayWriteInternalReg(dev, ZM_MAC_REG_EIFS_AND_SIFS, 0x8144000); + break; + case 1: + hpPriv->latestSIFS = 2; + zfDelayWriteInternalReg(dev, ZM_MAC_REG_EIFS_AND_SIFS, 0xa144000); + break; + case 2: + hpPriv->latestSIFS = 3; + zfDelayWriteInternalReg(dev, ZM_MAC_REG_EIFS_AND_SIFS, 0xc144000); + break; + case 3: + hpPriv->latestSIFS = 0; + zfDelayWriteInternalReg(dev, ZM_MAC_REG_EIFS_AND_SIFS, 0xa144000); + break; + default: + hpPriv->latestSIFS = 0; + zfDelayWriteInternalReg(dev, ZM_MAC_REG_EIFS_AND_SIFS, 0xa144000); + break; + } + polluted = 1; + zm_debug_msg1("##### Correct Tx retransmission issue #####, ", hpPriv->latestSIFS); + hpPriv->retransmissionEvent = 0; + } + } + else + { + hpPriv->latestSIFS = 0; + hpPriv->retransmissionEvent = 0; + zfDelayWriteInternalReg(dev, 0x1c3698, 0xA144000); + polluted = 1; + } + } + + if ((wd->sta.bScheduleScan == FALSE) && (wd->sta.bChannelScan == FALSE)) + { +#define ZM_SIGNAL_THRESHOLD 66 + if (( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) + && (zfStaIsConnected(dev)) + && (wd->SignalStrength > ZM_SIGNAL_THRESHOLD)) + { + /* remove state handle, always rewrite register setting */ + //if (hpPriv->strongRSSI == 0) + { + hpPriv->strongRSSI = 1; + /* Strong RSSI, set ACK to one Tx stream and lower Tx power 7dbm */ + if (hpPriv->currentAckRtsTpc > (14+10)) + { + ackTpc = hpPriv->currentAckRtsTpc - 14; + } + else + { + ackTpc = 10; + } + zfDelayWriteInternalReg(dev, 0x1c3694, ((ackTpc) << 20) | (0x1<<26)); + zfDelayWriteInternalReg(dev, 0x1c3bb4, ((ackTpc) << 5 ) | (0x1<<11) | + ((ackTpc) << 21) | (0x1<<27) ); + polluted = 1; + } + } + else + { + /* remove state handle, always rewrite register setting */ + //if (hpPriv->strongRSSI == 1) + { + hpPriv->strongRSSI = 0; + if (hpPriv->halCapability & ZM_HP_CAP_11N_ONE_TX_STREAM) + { + zfDelayWriteInternalReg(dev, 0x1c3694, ((hpPriv->currentAckRtsTpc&0x3f) << 20) | (0x1<<26)); + zfDelayWriteInternalReg(dev, 0x1c3bb4, ((hpPriv->currentAckRtsTpc&0x3f) << 5 ) | (0x1<<11) | + ((hpPriv->currentAckRtsTpc&0x3f) << 21) | (0x1<<27) ); + } + else + { + zfDelayWriteInternalReg(dev, 0x1c3694, ((hpPriv->currentAckRtsTpc&0x3f) << 20) | (0x5<<26)); + zfDelayWriteInternalReg(dev, 0x1c3bb4, ((hpPriv->currentAckRtsTpc&0x3f) << 5 ) | (0x5<<11) | + ((hpPriv->currentAckRtsTpc&0x3f) << 21) | (0x5<<27) ); + } + polluted = 1; + } + } +#undef ZM_SIGNAL_THRESHOLD + } + + if ((hpPriv->halCapability & ZM_HP_CAP_11N_ONE_TX_STREAM) == 0) + { + if ((wd->sta.bScheduleScan == FALSE) && (wd->sta.bChannelScan == FALSE)) + { + #define ZM_RX_SIGNAL_THRESHOLD_H 71 + #define ZM_RX_SIGNAL_THRESHOLD_L 66 + u8_t rxSignalThresholdH = ZM_RX_SIGNAL_THRESHOLD_H; + u8_t rxSignalThresholdL = ZM_RX_SIGNAL_THRESHOLD_L; + #undef ZM_RX_SIGNAL_THRESHOLD_H + #undef ZM_RX_SIGNAL_THRESHOLD_L + + if (( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) + && (zfStaIsConnected(dev)) + && (wd->SignalStrength > rxSignalThresholdH) + )//&& (hpPriv->rxStrongRSSI == 0)) + { + hpPriv->rxStrongRSSI = 1; + //zfDelayWriteInternalReg(dev, 0x1c5964, 0x1220); + //zfDelayWriteInternalReg(dev, 0x1c5960, 0x900); + //zfDelayWriteInternalReg(dev, 0x1c6960, 0x900); + //zfDelayWriteInternalReg(dev, 0x1c7960, 0x900); + if ((hpPriv->eepromImage[0x100+0x110*2/4]&0xff) == 0x80) //FEM TYPE + { + if (hpPriv->hwFrequency <= ZM_CH_G_14) + { + zfDelayWriteInternalReg(dev, 0x1c8960, 0x900); + } + else + { + zfDelayWriteInternalReg(dev, 0x1c8960, 0x9b49); + } + } + else + { + zfDelayWriteInternalReg(dev, 0x1c8960, 0x0900); + } + polluted = 1; + } + else if (( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) + && (zfStaIsConnected(dev)) + && (wd->SignalStrength > rxSignalThresholdL) + )//&& (hpPriv->rxStrongRSSI == 1)) + { + //Do nothing to prevent frequently Rx switching + } + else + { + /* remove state handle, always rewrite register setting */ + //if (hpPriv->rxStrongRSSI == 1) + { + hpPriv->rxStrongRSSI = 0; + //zfDelayWriteInternalReg(dev, 0x1c5964, 0x1120); + //zfDelayWriteInternalReg(dev, 0x1c5960, 0x9b40); + //zfDelayWriteInternalReg(dev, 0x1c6960, 0x9b40); + //zfDelayWriteInternalReg(dev, 0x1c7960, 0x9b40); + if ((hpPriv->eepromImage[0x100+0x110*2/4]&0xff) == 0x80) //FEM TYPE + { + if (hpPriv->hwFrequency <= ZM_CH_G_14) + { + zfDelayWriteInternalReg(dev, 0x1c8960, 0x9b49); + } + else + { + zfDelayWriteInternalReg(dev, 0x1c8960, 0x0900); + } + } + else + { + zfDelayWriteInternalReg(dev, 0x1c8960, 0x9b40); + } + polluted = 1; + } + } + + } + } + + if (hpPriv->usbAcSendBytes[3] > (hpPriv->usbAcSendBytes[0]*2)) + { + zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC1_AC0_TXOP, hpPriv->txop[3]); + polluted = 1; + } + else if (hpPriv->usbAcSendBytes[2] > (hpPriv->usbAcSendBytes[0]*2)) + { + zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC1_AC0_TXOP, hpPriv->txop[2]); + polluted = 1; + } + else if (hpPriv->usbAcSendBytes[1] > (hpPriv->usbAcSendBytes[0]*2)) + { + zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC0_CW, hpPriv->cwmin[1]+((u32_t)hpPriv->cwmax[1]<<16)); + polluted = 1; + } + else + { + if (hpPriv->slotType == 1) + { + if ((wd->sta.enableDrvBA ==0) //Marvel AP + && (hpPriv->aggMaxDurationBE > 2000)) //BE TXOP > 2ms + { + zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC0_CW, (hpPriv->cwmin[0]/2)+((u32_t)hpPriv->cwmax[0]<<16)); + } + else + { + zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC0_CW, hpPriv->cwmin[0]+((u32_t)hpPriv->cwmax[0]<<16)); + } + polluted = 1; + } + else + { + /* Compensation for 20us slot time */ + //zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC0_CW, 58+((u32_t)hpPriv->cwmax[0]<<16)); + zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC0_CW, hpPriv->cwmin[0]+((u32_t)hpPriv->cwmax[0]<<16)); + polluted = 1; + } + + if ((wd->sta.SWEncryptEnable & (ZM_SW_TKIP_ENCRY_EN|ZM_SW_WEP_ENCRY_EN)) == 0) + { + zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC1_AC0_TXOP, hpPriv->txop[0]); + polluted = 1; + } + else + { + zfDelayWriteInternalReg(dev, ZM_MAC_REG_AC1_AC0_TXOP, 0x30); + polluted = 1; + } + + } + hpPriv->usbAcSendBytes[3] = 0; + hpPriv->usbAcSendBytes[2] = 0; + hpPriv->usbAcSendBytes[1] = 0; + hpPriv->usbAcSendBytes[0] = 0; + } + + if (polluted == 1) + { + zfFlushDelayWrite(dev); + } + + return; +} + +/* + * 0x1d4008 : AHB, DAC, ADC clock selection + * bit1~0 AHB_CLK : AHB clock selection, + * 00 : OSC 40MHz; + * 01 : 20MHz in A mode, 22MHz in G mode; + * 10 : 40MHz in A mode, 44MHz in G mode; + * 11 : 80MHz in A mode, 88MHz in G mode. + * bit3~2 CLK_SEL : Select the clock source of clk160 in ADDAC. + * 00 : PLL divider's output; + * 01 : PLL divider's output divided by 2; + * 10 : PLL divider's output divided by 4; + * 11 : REFCLK from XTALOSCPAD. + */ +void zfSelAdcClk(zdev_t* dev, u8_t bw40, u32_t frequency) +{ + if(bw40 == 1) + { + //zfDelayWriteInternalReg(dev, 0x1D4008, 0x73); + zfDelayWriteInternalReg(dev, ZM_MAC_REG_DYNAMIC_SIFS_ACK, 0x10A); + zfFlushDelayWrite(dev); + } + else + { + //zfDelayWriteInternalReg(dev, 0x1D4008, 0x70); + if ( frequency <= ZM_CH_G_14 ) + { + zfDelayWriteInternalReg(dev, ZM_MAC_REG_DYNAMIC_SIFS_ACK, 0x105); + } + else + { + zfDelayWriteInternalReg(dev, ZM_MAC_REG_DYNAMIC_SIFS_ACK, 0x104); + } + zfFlushDelayWrite(dev); + } +} + +u32_t zfHpEchoCommand(zdev_t* dev, u32_t value) +{ + u32_t cmd[2]; + u16_t ret; + + cmd[0] = 0x00008004; + cmd[1] = value; + + ret = zfIssueCmd(dev, cmd, 8, ZM_CMD_ECHO, NULL); + return ret; +} + +#ifdef ZM_DRV_INIT_USB_MODE + +#define ZM_USB_US_STREAM_MODE 0x00000000 +#define ZM_USB_US_PACKET_MODE 0x00000008 +#define ZM_USB_DS_ENABLE 0x00000001 +#define ZM_USB_US_ENABLE 0x00000002 + +#define ZM_USB_RX_STREAM_4K 0x00000000 +#define ZM_USB_RX_STREAM_8K 0x00000010 +#define ZM_USB_RX_STREAM_16K 0x00000020 +#define ZM_USB_RX_STREAM_32K 0x00000030 + +#define ZM_USB_TX_STREAM_MODE 0x00000040 + +#define ZM_USB_MODE_CTRL_REG 0x001E1108 + +void zfInitUsbMode(zdev_t* dev) +{ + u32_t mode; + zmw_get_wlan_dev(dev); + + /* TODO: Set USB mode by reading registery */ + mode = ZM_USB_DS_ENABLE | ZM_USB_US_ENABLE | ZM_USB_US_PACKET_MODE; + + zfDelayWriteInternalReg(dev, ZM_USB_MODE_CTRL_REG, mode); + zfFlushDelayWrite(dev); +} +#endif + +void zfDumpEepBandEdges(struct ar5416Eeprom* eepromImage); +void zfPrintTargetPower2G(u8_t* tPow2xCck, u8_t* tPow2x2g, u8_t* tPow2x2gHt20, u8_t* tPow2x2gHt40); +void zfPrintTargetPower5G(u8_t* tPow2x5g, u8_t* tPow2x5gHt20, u8_t* tPow2x5gHt40); + + +s32_t zfInterpolateFunc(s32_t x, s32_t x1, s32_t y1, s32_t x2, s32_t y2) +{ + s32_t y; + + if (y2 == y1) + { + y = y1; + } + else if (x == x1) + { + y = y1; + } + else if (x == x2) + { + y = y2; + } + else if (x2 != x1) + { + y = y1 + (((y2-y1) * (x-x1))/(x2-x1)); + } + else + { + y = y1; + } + + return y; +} + +//#define ZM_ENABLE_TPC_WINDOWS_DEBUG +//#define ZM_ENABLE_BANDEDGES_WINDOWS_DEBUG + +/* the tx power offset workaround for ART vs NDIS/MDK */ +#define HALTX_POWER_OFFSET 0 + +u8_t zfInterpolateFuncX(u8_t x, u8_t x1, u8_t y1, u8_t x2, u8_t y2) +{ + s32_t y; + s32_t inc; + + #define ZM_MULTIPLIER 8 + y = zfInterpolateFunc((s32_t)x<> (ZM_MULTIPLIER-1); + y = (y >> ZM_MULTIPLIER) + inc; + #undef ZM_MULTIPLIER + + return (u8_t)y; +} + +u8_t zfGetInterpolatedValue(u8_t x, u8_t* x_array, u8_t* y_array) +{ + s32_t y; + u16_t xIndex; + + if (x <= x_array[1]) + { + xIndex = 0; + } + else if (x <= x_array[2]) + { + xIndex = 1; + } + else if (x <= x_array[3]) + { + xIndex = 2; + } + else //(x > x_array[3]) + { + xIndex = 3; + } + + y = zfInterpolateFuncX(x, + x_array[xIndex], + y_array[xIndex], + x_array[xIndex+1], + y_array[xIndex+1]); + + return (u8_t)y; +} + +u8_t zfFindFreqIndex(u8_t f, u8_t* fArray, u8_t fArraySize) +{ + u8_t i; +#ifdef ZM_ENABLE_TPC_WINDOWS_DEBUG + DbgPrint("f=%d ", f); + for (i=0; i= fArray[i]) + { + return i; + } + if (i!=0) + { + i--; + } + else + { + return 0; + } + } +} + + + + +void zfInitPowerCal(zdev_t* dev) +{ + //Program PHY Tx power relatives registers +#define zm_write_phy_reg(cr, val) reg_write((cr*4)+0x9800, val) + + zm_write_phy_reg(79, 0x7f); + zm_write_phy_reg(77, 0x3f3f3f3f); + zm_write_phy_reg(78, 0x3f3f3f3f); + zm_write_phy_reg(653, 0x3f3f3f3f); + zm_write_phy_reg(654, 0x3f3f3f3f); + zm_write_phy_reg(739, 0x3f3f3f3f); + zm_write_phy_reg(740, 0x3f3f3f3f); + zm_write_phy_reg(755, 0x3f3f3f3f); + zm_write_phy_reg(756, 0x3f3f3f3f); + zm_write_phy_reg(757, 0x3f3f3f3f); + +#undef zm_write_phy_reg +} + + + +void zfPrintTp(u8_t* pwr0, u8_t* vpd0, u8_t* pwr1, u8_t* vpd1) +{ + #ifdef ZM_ENABLE_TPC_WINDOWS_DEBUG + DbgPrint("pwr0 : %d, %d, %d, %d ,%d\n", pwr0[0], pwr0[1], pwr0[2], pwr0[3], pwr0[4]); + DbgPrint("vpd0 : %d, %d, %d, %d ,%d\n", vpd0[0], vpd0[1], vpd0[2], vpd0[3], vpd0[4]); + DbgPrint("pwr1 : %d, %d, %d, %d ,%d\n", pwr1[0], pwr1[1], pwr1[2], pwr1[3], pwr1[4]); + DbgPrint("vpd1 : %d, %d, %d, %d ,%d\n", vpd1[0], vpd1[1], vpd1[2], vpd1[3], vpd1[4]); + #endif +} + + +/* + * To find CTL index(0~23) + * return 24(AR5416_NUM_CTLS)=>no desired index found + */ +u8_t zfFindCtlEdgesIndex(zdev_t* dev, u8_t desired_CtlIndex) +{ + u8_t i; + struct zsHpPriv* hpPriv; + struct ar5416Eeprom* eepromImage; + + zmw_get_wlan_dev(dev); + + hpPriv = wd->hpPrivate; + + eepromImage = (struct ar5416Eeprom*)&(hpPriv->eepromImage[(1024+512)/4]); + + //for (i = 0; (i < AR5416_NUM_CTLS) && eepromImage->ctlIndex[i]; i++) + for (i = 0; i < AR5416_NUM_CTLS; i++) + { + if(desired_CtlIndex == eepromImage->ctlIndex[i]) + break; + } + return i; +} + +/************************************************************************** + * fbin2freq + * + * Get channel value from binary representation held in eeprom + * RETURNS: the frequency in MHz + */ +u32_t +fbin2freq(u8_t fbin, u8_t is2GHz) +{ + /* + * Reserved value 0xFF provides an empty definition both as + * an fbin and as a frequency - do not convert + */ + if (fbin == AR5416_BCHAN_UNUSED) { + return fbin; + } + + return (u32_t)((is2GHz==1) ? (2300 + fbin) : (4800 + 5 * fbin)); +} + + +u8_t zfGetMaxEdgePower(zdev_t* dev, CAL_CTL_EDGES *pCtlEdges, u32_t freq) +{ + u8_t i; + u8_t maxEdgePower; + u8_t is2GHz; + struct zsHpPriv* hpPriv; + struct ar5416Eeprom* eepromImage; + + zmw_get_wlan_dev(dev); + + hpPriv = wd->hpPrivate; + + eepromImage = (struct ar5416Eeprom*)&(hpPriv->eepromImage[(1024+512)/4]); + + if(freq > ZM_CH_G_14) + is2GHz = 0; + else + is2GHz = 1; + + maxEdgePower = AR5416_MAX_RATE_POWER; + + /* Get the edge power */ + for (i = 0; (i < AR5416_NUM_BAND_EDGES) && (pCtlEdges[i].bChannel != AR5416_BCHAN_UNUSED) ; i++) + { + /* + * If there's an exact channel match or an inband flag set + * on the lower channel use the given rdEdgePower + */ + if (freq == fbin2freq(pCtlEdges[i].bChannel, is2GHz)) + { + maxEdgePower = pCtlEdges[i].tPower; + #ifdef ZM_ENABLE_BANDEDGES_WINDOWS_DEBUG + zm_dbg(("zfGetMaxEdgePower index i = %d \n", i)); + #endif + break; + } + else if ((i > 0) && (freq < fbin2freq(pCtlEdges[i].bChannel, is2GHz))) + { + if (fbin2freq(pCtlEdges[i - 1].bChannel, is2GHz) < freq && pCtlEdges[i - 1].flag) + { + maxEdgePower = pCtlEdges[i - 1].tPower; + #ifdef ZM_ENABLE_BANDEDGES_WINDOWS_DEBUG + zm_dbg(("zfGetMaxEdgePower index i-1 = %d \n", i-1)); + #endif + } + /* Leave loop - no more affecting edges possible in this monotonic increasing list */ + break; + } + + } + + if( i == AR5416_NUM_BAND_EDGES ) + { + if (freq > fbin2freq(pCtlEdges[i - 1].bChannel, is2GHz) && pCtlEdges[i - 1].flag) + { + maxEdgePower = pCtlEdges[i - 1].tPower; + #ifdef ZM_ENABLE_BANDEDGES_WINDOWS_DEBUG + zm_dbg(("zfGetMaxEdgePower index=>i-1 = %d \n", i-1)); + #endif + } + } + + zm_assert(maxEdgePower > 0); + + #ifdef ZM_ENABLE_BANDEDGES_WINDOWS_DEBUG + if ( maxEdgePower == AR5416_MAX_RATE_POWER ) + { + zm_dbg(("zfGetMaxEdgePower = %d !!!\n", AR5416_MAX_RATE_POWER)); + } + #endif + return maxEdgePower; +} + +u32_t zfAdjustHT40FreqOffset(zdev_t* dev, u32_t frequency, u8_t bw40, u8_t extOffset) +{ + u32_t newFreq = frequency; + + if (bw40 == 1) + { + if (extOffset == 1) + { + newFreq += 10; + } + else + { + newFreq -= 10; + } + } + return newFreq; +} + +u32_t zfHpCheckDoHeavyClip(zdev_t* dev, u32_t freq, CAL_CTL_EDGES *pCtlEdges, u8_t bw40) +{ + u32_t ret = 0; + u8_t i; + u8_t is2GHz; + struct zsHpPriv* hpPriv; + + zmw_get_wlan_dev(dev); + + hpPriv = wd->hpPrivate; + + if(freq > ZM_CH_G_14) + is2GHz = 0; + else + is2GHz = 1; + + /* HT40 force enable heavy clip */ + if (bw40) + { + ret |= 0xf0; + } +#if 1 + /* HT20 : frequency bandedge */ + for (i = 0; (i < AR5416_NUM_BAND_EDGES) && (pCtlEdges[i].bChannel != AR5416_BCHAN_UNUSED) ; i++) + { + if (freq == fbin2freq(pCtlEdges[i].bChannel, is2GHz)) + { + if (pCtlEdges[i].flag == 0) + { + ret |= 0xf; + } + break; + } + } +#endif + + return ret; +} + + +void zfSetPowerCalTable(zdev_t* dev, u32_t frequency, u8_t bw40, u8_t extOffset) +{ + struct ar5416Eeprom* eepromImage; + u8_t pwr0[5]; + u8_t pwr1[5]; + u8_t vpd0[5]; + u8_t vpd1[5]; + u8_t vpd_chain1[128]; + u8_t vpd_chain3[128]; + u16_t boundary1 = 18; //CR 667 + u16_t powerTxMax = 63; //CR 79 + u8_t i; + struct zsHpPriv* hpPriv; + u8_t fbin; + u8_t index, max2gIndex, max5gIndex; + u8_t chain0pwrPdg0[5]; + u8_t chain0vpdPdg0[5]; + u8_t chain0pwrPdg1[5]; + u8_t chain0vpdPdg1[5]; + u8_t chain2pwrPdg0[5]; + u8_t chain2vpdPdg0[5]; + u8_t chain2pwrPdg1[5]; + u8_t chain2vpdPdg1[5]; + u8_t fbinArray[8]; + + /* 4 CTL */ + u8_t ctl_i; + u8_t desired_CtlIndex; + + u8_t ctlEdgesMaxPowerCCK = AR5416_MAX_RATE_POWER; + u8_t ctlEdgesMaxPower2G = AR5416_MAX_RATE_POWER; + u8_t ctlEdgesMaxPower2GHT20 = AR5416_MAX_RATE_POWER; + u8_t ctlEdgesMaxPower2GHT40 = AR5416_MAX_RATE_POWER; + u8_t ctlEdgesMaxPower5G = AR5416_MAX_RATE_POWER; + u8_t ctlEdgesMaxPower5GHT20 = AR5416_MAX_RATE_POWER; + u8_t ctlEdgesMaxPower5GHT40 = AR5416_MAX_RATE_POWER; + + u8_t ctlOffset; + + zmw_get_wlan_dev(dev); + + hpPriv = wd->hpPrivate; + + eepromImage = (struct ar5416Eeprom*)&(hpPriv->eepromImage[(1024+512)/4]); + + // Check the total bytes of the EEPROM structure to see the dongle have been calibrated or not. + if (eepromImage->baseEepHeader.length == 0xffff) + { + #ifdef ZM_ENABLE_BANDEDGES_WINDOWS_DEBUG + zm_dbg(("Warning! This dongle not been calibrated\n")); + #endif + return; + } + + #ifdef ZM_ENABLE_TPC_WINDOWS_DEBUG + DbgPrint("-----zfSetPowerCalTable : frequency=%d-----\n", frequency); + #endif + /* TODO : 1. boundary1 and powerTxMax should be refered to CR667 and CR79 */ + /* in otus.ini file */ + + #ifdef ZM_ENABLE_TPC_WINDOWS_DEBUG + /* 2. Interpolate pwr and vpd test points from frequency */ + DbgPrint("calFreqPier5G : %d, %d, %d, %d ,%d, %d, %d, %d\n", + eepromImage->calFreqPier5G[0]*5+4800, + eepromImage->calFreqPier5G[1]*5+4800, + eepromImage->calFreqPier5G[2]*5+4800, + eepromImage->calFreqPier5G[3]*5+4800, + eepromImage->calFreqPier5G[4]*5+4800, + eepromImage->calFreqPier5G[5]*5+4800, + eepromImage->calFreqPier5G[6]*5+4800, + eepromImage->calFreqPier5G[7]*5+4800 + ); + DbgPrint("calFreqPier2G : %d, %d, %d, %d\n", + eepromImage->calFreqPier2G[0]+2300, + eepromImage->calFreqPier2G[1]+2300, + eepromImage->calFreqPier2G[2]+2300, + eepromImage->calFreqPier2G[3]+2300 + ); + #endif + if (frequency < 3000) + { + for (i=0; i<4; i++) + { + if (eepromImage->calFreqPier2G[i] == 0xff) + { + break; + } + } + max2gIndex = i; + #ifdef ZM_ENABLE_TPC_WINDOWS_DEBUG + DbgPrint("max2gIndex : %d\n", max2gIndex); + #endif + fbin = (u8_t)(frequency - 2300); + index = zfFindFreqIndex(fbin, eepromImage->calFreqPier2G, max2gIndex); + #ifdef ZM_ENABLE_TPC_WINDOWS_DEBUG + DbgPrint("2G index : %d\n", index); + DbgPrint("chain 0 index\n"); + #endif + zfPrintTp(&eepromImage->calPierData2G[0][index].pwrPdg[0][0], + &eepromImage->calPierData2G[0][index].vpdPdg[0][0], + &eepromImage->calPierData2G[0][index].pwrPdg[1][0], + &eepromImage->calPierData2G[0][index].vpdPdg[1][0] + ); + #ifdef ZM_ENABLE_TPC_WINDOWS_DEBUG + DbgPrint("chain 0 index+1\n"); + #endif + zfPrintTp(&eepromImage->calPierData2G[0][index+1].pwrPdg[0][0], + &eepromImage->calPierData2G[0][index+1].vpdPdg[0][0], + &eepromImage->calPierData2G[0][index+1].pwrPdg[1][0], + &eepromImage->calPierData2G[0][index+1].vpdPdg[1][0] + ); + + for (i=0; i<5; i++) + { + chain0pwrPdg0[i] = zfInterpolateFuncX(fbin, + eepromImage->calFreqPier2G[index], + eepromImage->calPierData2G[0][index].pwrPdg[0][i], + eepromImage->calFreqPier2G[index+1], + eepromImage->calPierData2G[0][index+1].pwrPdg[0][i] + ); + chain0vpdPdg0[i] = zfInterpolateFuncX(fbin, + eepromImage->calFreqPier2G[index], + eepromImage->calPierData2G[0][index].vpdPdg[0][i], + eepromImage->calFreqPier2G[index+1], + eepromImage->calPierData2G[0][index+1].vpdPdg[0][i] + ); + chain0pwrPdg1[i] = zfInterpolateFuncX(fbin, + eepromImage->calFreqPier2G[index], + eepromImage->calPierData2G[0][index].pwrPdg[1][i], + eepromImage->calFreqPier2G[index+1], + eepromImage->calPierData2G[0][index+1].pwrPdg[1][i] + ); + chain0vpdPdg1[i] = zfInterpolateFuncX(fbin, + eepromImage->calFreqPier2G[index], + eepromImage->calPierData2G[0][index].vpdPdg[1][i], + eepromImage->calFreqPier2G[index+1], + eepromImage->calPierData2G[0][index+1].vpdPdg[1][i] + ); + + chain2pwrPdg0[i] = zfInterpolateFuncX(fbin, + eepromImage->calFreqPier2G[index], + eepromImage->calPierData2G[1][index].pwrPdg[0][i], + eepromImage->calFreqPier2G[index+1], + eepromImage->calPierData2G[1][index+1].pwrPdg[0][i] + ); + chain2vpdPdg0[i] = zfInterpolateFuncX(fbin, + eepromImage->calFreqPier2G[index], + eepromImage->calPierData2G[1][index].vpdPdg[0][i], + eepromImage->calFreqPier2G[index+1], + eepromImage->calPierData2G[1][index+1].vpdPdg[0][i] + ); + chain2pwrPdg1[i] = zfInterpolateFuncX(fbin, + eepromImage->calFreqPier2G[index], + eepromImage->calPierData2G[1][index].pwrPdg[1][i], + eepromImage->calFreqPier2G[index+1], + eepromImage->calPierData2G[1][index+1].pwrPdg[1][i] + ); + chain2vpdPdg1[i] = zfInterpolateFuncX(fbin, + eepromImage->calFreqPier2G[index], + eepromImage->calPierData2G[1][index].vpdPdg[1][i], + eepromImage->calFreqPier2G[index+1], + eepromImage->calPierData2G[1][index+1].vpdPdg[1][i] + ); + } + } + else + { + for (i=0; i<8; i++) + { + if (eepromImage->calFreqPier5G[i] == 0xff) + { + break; + } + } + max5gIndex = i; + #ifdef ZM_ENABLE_TPC_WINDOWS_DEBUG + DbgPrint("max5gIndex : %d\n", max5gIndex); + #endif + fbin = (u8_t)((frequency - 4800)/5); + index = zfFindFreqIndex(fbin, eepromImage->calFreqPier5G, max5gIndex); + #ifdef ZM_ENABLE_TPC_WINDOWS_DEBUG + DbgPrint("5G index : %d\n", index); + #endif + + for (i=0; i<5; i++) + { + chain0pwrPdg0[i] = zfInterpolateFuncX(fbin, + eepromImage->calFreqPier5G[index], + eepromImage->calPierData5G[0][index].pwrPdg[0][i], + eepromImage->calFreqPier5G[index+1], + eepromImage->calPierData5G[0][index+1].pwrPdg[0][i] + ); + chain0vpdPdg0[i] = zfInterpolateFuncX(fbin, + eepromImage->calFreqPier5G[index], + eepromImage->calPierData5G[0][index].vpdPdg[0][i], + eepromImage->calFreqPier5G[index+1], + eepromImage->calPierData5G[0][index+1].vpdPdg[0][i] + ); + chain0pwrPdg1[i] = zfInterpolateFuncX(fbin, + eepromImage->calFreqPier5G[index], + eepromImage->calPierData5G[0][index].pwrPdg[1][i], + eepromImage->calFreqPier5G[index+1], + eepromImage->calPierData5G[0][index+1].pwrPdg[1][i] + ); + chain0vpdPdg1[i] = zfInterpolateFuncX(fbin, + eepromImage->calFreqPier5G[index], + eepromImage->calPierData5G[0][index].vpdPdg[1][i], + eepromImage->calFreqPier5G[index+1], + eepromImage->calPierData5G[0][index+1].vpdPdg[1][i] + ); + + chain2pwrPdg0[i] = zfInterpolateFuncX(fbin, + eepromImage->calFreqPier5G[index], + eepromImage->calPierData5G[1][index].pwrPdg[0][i], + eepromImage->calFreqPier5G[index+1], + eepromImage->calPierData5G[1][index+1].pwrPdg[0][i] + ); + chain2vpdPdg0[i] = zfInterpolateFuncX(fbin, + eepromImage->calFreqPier5G[index], + eepromImage->calPierData5G[1][index].vpdPdg[0][i], + eepromImage->calFreqPier5G[index+1], + eepromImage->calPierData5G[1][index+1].vpdPdg[0][i] + ); + chain2pwrPdg1[i] = zfInterpolateFuncX(fbin, + eepromImage->calFreqPier5G[index], + eepromImage->calPierData5G[1][index].pwrPdg[1][i], + eepromImage->calFreqPier5G[index+1], + eepromImage->calPierData5G[1][index+1].pwrPdg[1][i] + ); + chain2vpdPdg1[i] = zfInterpolateFuncX(fbin, + eepromImage->calFreqPier5G[index], + eepromImage->calPierData5G[1][index].vpdPdg[1][i], + eepromImage->calFreqPier5G[index+1], + eepromImage->calPierData5G[1][index+1].vpdPdg[1][i] + ); + } + + } + + + /* Chain 1 */ + /* Get pwr and vpd test points from frequency */ + for (i=0; i<5; i++) + { + pwr0[i] = chain0pwrPdg0[i]>>1; + vpd0[i] = chain0vpdPdg0[i]; + pwr1[i] = chain0pwrPdg1[i]>>1; + vpd1[i] = chain0vpdPdg1[i]; + } + #ifdef ZM_ENABLE_TPC_WINDOWS_DEBUG + DbgPrint("Test Points\n"); + DbgPrint("pwr0 : %d, %d, %d, %d ,%d\n", pwr0[0], pwr0[1], pwr0[2], pwr0[3], pwr0[4]); + DbgPrint("vpd0 : %d, %d, %d, %d ,%d\n", vpd0[0], vpd0[1], vpd0[2], vpd0[3], vpd0[4]); + DbgPrint("pwr1 : %d, %d, %d, %d ,%d\n", pwr1[0], pwr1[1], pwr1[2], pwr1[3], pwr1[4]); + DbgPrint("vpd1 : %d, %d, %d, %d ,%d\n", vpd1[0], vpd1[1], vpd1[2], vpd1[3], vpd1[4]); + #endif + /* Generate the vpd arrays */ + for (i=0; i>1; + vpd0[i] = chain2vpdPdg0[i]; + pwr1[i] = chain2pwrPdg1[i]>>1; + vpd1[i] = chain2vpdPdg1[i]; + } + #ifdef ZM_ENABLE_TPC_WINDOWS_DEBUG + DbgPrint("Test Points\n"); + DbgPrint("pwr0 : %d, %d, %d, %d ,%d\n", pwr0[0], pwr0[1], pwr0[2], pwr0[3], pwr0[4]); + DbgPrint("vpd0 : %d, %d, %d, %d ,%d\n", vpd0[0], vpd0[1], vpd0[2], vpd0[3], vpd0[4]); + DbgPrint("pwr1 : %d, %d, %d, %d ,%d\n", pwr1[0], pwr1[1], pwr1[2], pwr1[3], pwr1[4]); + DbgPrint("vpd1 : %d, %d, %d, %d ,%d\n", vpd1[0], vpd1[1], vpd1[2], vpd1[3], vpd1[4]); + #endif + /* Generate the vpd arrays */ + for (i=0; icalTargetPowerCck[i].bChannel != 0xff) + { + fbinArray[i] = eepromImage->calTargetPowerCck[i].bChannel; + } + else + { + break; + } + + } + index = zfFindFreqIndex(fbin, fbinArray, i); + #ifdef ZM_ENABLE_TPC_WINDOWS_DEBUG + DbgPrint("CCK index=%d\n", index); + #endif + for (i=0; i<4; i++) + { + hpPriv->tPow2xCck[i] = zfInterpolateFuncX(fbin, + eepromImage->calTargetPowerCck[index].bChannel, + eepromImage->calTargetPowerCck[index].tPow2x[i], + eepromImage->calTargetPowerCck[index+1].bChannel, + eepromImage->calTargetPowerCck[index+1].tPow2x[i] + ); + } + + for (i=0; i<4; i++) + { + if (eepromImage->calTargetPower2G[i].bChannel != 0xff) + { + fbinArray[i] = eepromImage->calTargetPower2G[i].bChannel; + } + else + { + break; + } + + } + index = zfFindFreqIndex(fbin, fbinArray, i); + #ifdef ZM_ENABLE_TPC_WINDOWS_DEBUG + DbgPrint("2G index=%d\n", index); + #endif + for (i=0; i<4; i++) + { + hpPriv->tPow2x2g[i] = zfInterpolateFuncX(fbin, + eepromImage->calTargetPower2G[index].bChannel, + eepromImage->calTargetPower2G[index].tPow2x[i], + eepromImage->calTargetPower2G[index+1].bChannel, + eepromImage->calTargetPower2G[index+1].tPow2x[i] + ); + } + + for (i=0; i<4; i++) + { + if (eepromImage->calTargetPower2GHT20[i].bChannel != 0xff) + { + fbinArray[i] = eepromImage->calTargetPower2GHT20[i].bChannel; + } + else + { + break; + } + + } + index = zfFindFreqIndex(fbin, fbinArray, i); + #ifdef ZM_ENABLE_TPC_WINDOWS_DEBUG + DbgPrint("2G HT20 index=%d\n", index); + #endif + for (i=0; i<8; i++) + { + hpPriv->tPow2x2gHt20[i] = zfInterpolateFuncX(fbin, + eepromImage->calTargetPower2GHT20[index].bChannel, + eepromImage->calTargetPower2GHT20[index].tPow2x[i], + eepromImage->calTargetPower2GHT20[index+1].bChannel, + eepromImage->calTargetPower2GHT20[index+1].tPow2x[i] + ); + } + + for (i=0; i<4; i++) + { + if (eepromImage->calTargetPower2GHT40[i].bChannel != 0xff) + { + fbinArray[i] = eepromImage->calTargetPower2GHT40[i].bChannel; + } + else + { + break; + } + + } + index = zfFindFreqIndex( (u8_t)zfAdjustHT40FreqOffset(dev, fbin, bw40, extOffset), fbinArray, i); + #ifdef ZM_ENABLE_TPC_WINDOWS_DEBUG + DbgPrint("2G HT40 index=%d\n", index); + #endif + for (i=0; i<8; i++) + { + hpPriv->tPow2x2gHt40[i] = zfInterpolateFuncX( + (u8_t)zfAdjustHT40FreqOffset(dev, fbin, bw40, extOffset), + eepromImage->calTargetPower2GHT40[index].bChannel, + eepromImage->calTargetPower2GHT40[index].tPow2x[i], + eepromImage->calTargetPower2GHT40[index+1].bChannel, + eepromImage->calTargetPower2GHT40[index+1].tPow2x[i] + ); + } + + zfPrintTargetPower2G(hpPriv->tPow2xCck, + hpPriv->tPow2x2g, + hpPriv->tPow2x2gHt20, + hpPriv->tPow2x2gHt40); + } + else + { + /* 5G */ + for (i=0; i<8; i++) + { + if (eepromImage->calTargetPower5G[i].bChannel != 0xff) + { + fbinArray[i] = eepromImage->calTargetPower5G[i].bChannel; + } + else + { + break; + } + + } + index = zfFindFreqIndex(fbin, fbinArray, i); + #ifdef ZM_ENABLE_TPC_WINDOWS_DEBUG + DbgPrint("5G index=%d\n", index); + #endif + for (i=0; i<4; i++) + { + hpPriv->tPow2x5g[i] = zfInterpolateFuncX(fbin, + eepromImage->calTargetPower5G[index].bChannel, + eepromImage->calTargetPower5G[index].tPow2x[i], + eepromImage->calTargetPower5G[index+1].bChannel, + eepromImage->calTargetPower5G[index+1].tPow2x[i] + ); + } + + for (i=0; i<8; i++) + { + if (eepromImage->calTargetPower5GHT20[i].bChannel != 0xff) + { + fbinArray[i] = eepromImage->calTargetPower5GHT20[i].bChannel; + } + else + { + break; + } + + } + index = zfFindFreqIndex(fbin, fbinArray, i); + #ifdef ZM_ENABLE_TPC_WINDOWS_DEBUG + DbgPrint("5G HT20 index=%d\n", index); + #endif + for (i=0; i<8; i++) + { + hpPriv->tPow2x5gHt20[i] = zfInterpolateFuncX(fbin, + eepromImage->calTargetPower5GHT20[index].bChannel, + eepromImage->calTargetPower5GHT20[index].tPow2x[i], + eepromImage->calTargetPower5GHT20[index+1].bChannel, + eepromImage->calTargetPower5GHT20[index+1].tPow2x[i] + ); + } + + for (i=0; i<8; i++) + { + if (eepromImage->calTargetPower5GHT40[i].bChannel != 0xff) + { + fbinArray[i] = eepromImage->calTargetPower5GHT40[i].bChannel; + } + else + { + break; + } + + } + index = zfFindFreqIndex((u8_t)zfAdjustHT40FreqOffset(dev, fbin, bw40, extOffset), fbinArray, i); + #ifdef ZM_ENABLE_TPC_WINDOWS_DEBUG + DbgPrint("5G HT40 index=%d\n", index); + #endif + for (i=0; i<8; i++) + { + hpPriv->tPow2x5gHt40[i] = zfInterpolateFuncX( + (u8_t)zfAdjustHT40FreqOffset(dev, fbin, bw40, extOffset), + eepromImage->calTargetPower5GHT40[index].bChannel, + eepromImage->calTargetPower5GHT40[index].tPow2x[i], + eepromImage->calTargetPower5GHT40[index+1].bChannel, + eepromImage->calTargetPower5GHT40[index+1].tPow2x[i] + ); + } + + zfPrintTargetPower5G( + hpPriv->tPow2x5g, + hpPriv->tPow2x5gHt20, + hpPriv->tPow2x5gHt40); + } + + + + /* 4. CTL */ + /* + * 4.1 Get the bandedges tx power by frequency + * 2.4G we get ctlEdgesMaxPowerCCK + * ctlEdgesMaxPower2G + * ctlEdgesMaxPower2GHT20 + * ctlEdgesMaxPower2GHT40 + * 5G we get ctlEdgesMaxPower5G + * ctlEdgesMaxPower5GHT20 + * ctlEdgesMaxPower5GHT40 + * 4.2 Update (3.) target power table by 4.1 + * 4.3 Tx power offset for ART - NDIS/MDK + * 4.4 Write MAC reg 0x694 for ACK's TPC + * + */ + + //zfDumpEepBandEdges(eepromImage); + + /* get the cfg from Eeprom: regionCode => RegulatoryDomain : 0x10-FFC 0x30-eu 0x40-jap */ + desired_CtlIndex = zfHpGetRegulatoryDomain(dev); + if ((desired_CtlIndex == 0x30) || (desired_CtlIndex == 0x40) || (desired_CtlIndex == 0x0)) + { + /* skip CTL and heavy clip */ + hpPriv->enableBBHeavyClip = 0; + #ifdef ZM_ENABLE_BANDEDGES_WINDOWS_DEBUG + zm_dbg(("RegulatoryDomain = 0, skip CTL and heavy clip\n")); + #endif + } + else + { + hpPriv->enableBBHeavyClip = 1; + + if (desired_CtlIndex == 0xff) + { + /* desired index not found */ + desired_CtlIndex = 0x10; + } + + /* first part : 2.4G */ + if (frequency <= ZM_CH_G_14) + { + /* 2.4G - CTL_11B */ + ctl_i = zfFindCtlEdgesIndex(dev, desired_CtlIndex|CTL_11B); + if(ctl_ictlData[ctl_i].ctlEdges[1], frequency); + } + #ifdef ZM_ENABLE_BANDEDGES_WINDOWS_DEBUG + zm_dbg(("CTL_11B ctl_i = %d\n", ctl_i)); + #endif + + /* 2.4G - CTL_11G */ + ctl_i = zfFindCtlEdgesIndex(dev, desired_CtlIndex|CTL_11G); + if(ctl_ictlData[ctl_i].ctlEdges[1], frequency); + } + #ifdef ZM_ENABLE_BANDEDGES_WINDOWS_DEBUG + zm_dbg(("CTL_11G ctl_i = %d\n", ctl_i)); + #endif + + /* 2.4G - CTL_2GHT20 */ + ctl_i = zfFindCtlEdgesIndex(dev, desired_CtlIndex|CTL_2GHT20); + if(ctl_ictlData[ctl_i].ctlEdges[1], frequency); + } + else + { + /* workaround for no data in Eeprom, replace by normal 2G */ + ctlEdgesMaxPower2GHT20 = ctlEdgesMaxPower2G; + } + #ifdef ZM_ENABLE_BANDEDGES_WINDOWS_DEBUG + zm_dbg(("CTL_2GHT20 ctl_i = %d\n", ctl_i)); + #endif + + /* 2.4G - CTL_2GHT40 */ + ctl_i = zfFindCtlEdgesIndex(dev, desired_CtlIndex|CTL_2GHT40); + if(ctl_ictlData[ctl_i].ctlEdges[1], + zfAdjustHT40FreqOffset(dev, frequency, bw40, extOffset)); + } + else + { + /* workaround for no data in Eeprom, replace by normal 2G */ + ctlEdgesMaxPower2GHT40 = ctlEdgesMaxPower2G; + } + #ifdef ZM_ENABLE_BANDEDGES_WINDOWS_DEBUG + zm_dbg(("CTL_2GHT40 ctl_i = %d\n", ctl_i)); + #endif + + + /* 7a17 : */ + /* Max power (dBm) for channel range when using DFS define by madwifi*/ + for (i=0; iregulationTable.allowChannelCnt; i++) + { + if (wd->regulationTable.allowChannel[i].channel == frequency) + { + if (zfHpIsDfsChannel(dev, (u16_t)frequency)) + { + zm_debug_msg1("frequency use DFS -- ", frequency); + ctlEdgesMaxPowerCCK = zm_min(ctlEdgesMaxPowerCCK, wd->regulationTable.allowChannel[i].maxRegTxPower*2); + ctlEdgesMaxPower2G = zm_min(ctlEdgesMaxPower2G, wd->regulationTable.allowChannel[i].maxRegTxPower*2); + ctlEdgesMaxPower2GHT20 = zm_min(ctlEdgesMaxPower2GHT20, wd->regulationTable.allowChannel[i].maxRegTxPower*2); + ctlEdgesMaxPower2GHT40 = zm_min(ctlEdgesMaxPower2GHT40, wd->regulationTable.allowChannel[i].maxRegTxPower*2); + } + break; + } + } + + /* Apply ctl mode to correct target power set */ + #ifdef ZM_ENABLE_BANDEDGES_WINDOWS_DEBUG + zm_debug_msg1("ctlEdgesMaxPowerCCK = ", ctlEdgesMaxPowerCCK); + zm_debug_msg1("ctlEdgesMaxPower2G = ", ctlEdgesMaxPower2G); + zm_debug_msg1("ctlEdgesMaxPower2GHT20 = ", ctlEdgesMaxPower2GHT20); + zm_debug_msg1("ctlEdgesMaxPower2GHT40 = ", ctlEdgesMaxPower2GHT40); + #endif + for (i=0; i<4; i++) + { + hpPriv->tPow2xCck[i] = zm_min(hpPriv->tPow2xCck[i], ctlEdgesMaxPowerCCK) + HALTX_POWER_OFFSET; + } + hpPriv->tPow2x2g24HeavyClipOffset = 0; + if (hpPriv->enableBBHeavyClip) + { + ctlOffset = 2; + } + else + { + ctlOffset = 0; + } + for (i=0; i<4; i++) + { + if (((frequency == 2412) || (frequency == 2462))) + { + if (i != 0) + { + hpPriv->tPow2x2g[i] = zm_min(hpPriv->tPow2x2g[i], ctlEdgesMaxPower2G-ctlOffset) + HALTX_POWER_OFFSET; + } + else + { + hpPriv->tPow2x2g[i] = zm_min(hpPriv->tPow2x2g[i], ctlEdgesMaxPower2G) + HALTX_POWER_OFFSET; + if (hpPriv->tPow2x2g[i] > (ctlEdgesMaxPower2G-ctlOffset)) + { + hpPriv->tPow2x2g24HeavyClipOffset = hpPriv->tPow2x2g[i] - (ctlEdgesMaxPower2G-ctlOffset); + } + } + } + else + { + hpPriv->tPow2x2g[i] = zm_min(hpPriv->tPow2x2g[i], ctlEdgesMaxPower2G) + HALTX_POWER_OFFSET; + } + } + for (i=0; i<8; i++) + { + if (((frequency == 2412) || (frequency == 2462)) && (i>=3)) + { + hpPriv->tPow2x2gHt20[i] = zm_min(hpPriv->tPow2x2gHt20[i], ctlEdgesMaxPower2GHT20-ctlOffset) + HALTX_POWER_OFFSET; + } + else + { + hpPriv->tPow2x2gHt20[i] = zm_min(hpPriv->tPow2x2gHt20[i], ctlEdgesMaxPower2GHT20) + HALTX_POWER_OFFSET; + } + } + for (i=0; i<8; i++) + { + if ((frequency == 2412) && (i>=3)) + { + hpPriv->tPow2x2gHt40[i] = zm_min(hpPriv->tPow2x2gHt40[i], ctlEdgesMaxPower2GHT40-ctlOffset) + HALTX_POWER_OFFSET; + } + else if ((frequency == 2462) && (i>=3)) + { + hpPriv->tPow2x2gHt40[i] = zm_min(hpPriv->tPow2x2gHt40[i], ctlEdgesMaxPower2GHT40-(ctlOffset*2)) + HALTX_POWER_OFFSET; + } + else + { + hpPriv->tPow2x2gHt40[i] = zm_min(hpPriv->tPow2x2gHt40[i], ctlEdgesMaxPower2GHT40) + HALTX_POWER_OFFSET; + } + } + } + else + { + /* 5G - CTL_11A */ + ctl_i = zfFindCtlEdgesIndex(dev, desired_CtlIndex|CTL_11A); + if(ctl_ictlData[ctl_i].ctlEdges[1], frequency); + } + #ifdef ZM_ENABLE_BANDEDGES_WINDOWS_DEBUG + zm_dbg(("CTL_11A ctl_i = %d\n", ctl_i)); + #endif + + /* 5G - CTL_5GHT20 */ + ctl_i = zfFindCtlEdgesIndex(dev, desired_CtlIndex|CTL_5GHT20); + if(ctl_ictlData[ctl_i].ctlEdges[1], frequency); + } + else + { + /* workaround for no data in Eeprom, replace by normal 5G */ + ctlEdgesMaxPower5GHT20 = ctlEdgesMaxPower5G; + } + #ifdef ZM_ENABLE_BANDEDGES_WINDOWS_DEBUG + zm_dbg(("CTL_5GHT20 ctl_i = %d\n", ctl_i)); + #endif + + /* 5G - CTL_5GHT40 */ + ctl_i = zfFindCtlEdgesIndex(dev, desired_CtlIndex|CTL_5GHT40); + if(ctl_ictlData[ctl_i].ctlEdges[1], + zfAdjustHT40FreqOffset(dev, frequency, bw40, extOffset)); + } + else + { + /* workaround for no data in Eeprom, replace by normal 5G */ + ctlEdgesMaxPower5GHT40 = ctlEdgesMaxPower5G; + } + #ifdef ZM_ENABLE_BANDEDGES_WINDOWS_DEBUG + zm_dbg(("CTL_5GHT40 ctl_i = %d\n", ctl_i)); + #endif + + /* 7a17 : */ + /* Max power (dBm) for channel range when using DFS define by madwifi*/ + for (i=0; iregulationTable.allowChannelCnt; i++) + { + if (wd->regulationTable.allowChannel[i].channel == frequency) + { + if (zfHpIsDfsChannel(dev, (u16_t)frequency)) + { + zm_debug_msg1("frequency use DFS -- ", frequency); + ctlEdgesMaxPower5G = zm_min(ctlEdgesMaxPower5G, wd->regulationTable.allowChannel[i].maxRegTxPower*2); + ctlEdgesMaxPower5GHT20 = zm_min(ctlEdgesMaxPower5GHT20, wd->regulationTable.allowChannel[i].maxRegTxPower*2); + ctlEdgesMaxPower5GHT40 = zm_min(ctlEdgesMaxPower5GHT40, wd->regulationTable.allowChannel[i].maxRegTxPower*2); + } + break; + } + } + + + /* Apply ctl mode to correct target power set */ + #ifdef ZM_ENABLE_BANDEDGES_WINDOWS_DEBUG + zm_debug_msg1("ctlEdgesMaxPower5G = ", ctlEdgesMaxPower5G); + zm_debug_msg1("ctlEdgesMaxPower5GHT20 = ", ctlEdgesMaxPower5GHT20); + zm_debug_msg1("ctlEdgesMaxPower5GHT40 = ", ctlEdgesMaxPower5GHT40); + #endif + for (i=0; i<4; i++) + { + hpPriv->tPow2x5g[i] = zm_min(hpPriv->tPow2x5g[i], ctlEdgesMaxPower5G) + HALTX_POWER_OFFSET; + } + for (i=0; i<8; i++) + { + hpPriv->tPow2x5gHt20[i] = zm_min(hpPriv->tPow2x5gHt20[i], ctlEdgesMaxPower5GHT20) + HALTX_POWER_OFFSET; + } + for (i=0; i<8; i++) + { + hpPriv->tPow2x5gHt40[i] = zm_min(hpPriv->tPow2x5gHt40[i], ctlEdgesMaxPower5GHT40) + HALTX_POWER_OFFSET; + } + + }/* end of bandedges of 5G */ + }/* end of if ((desired_CtlIndex = zfHpGetRegulatoryDomain(dev)) == 0) */ + + /* workaround */ + /* 5. BB heavy clip */ + /* only 2.4G do heavy clip */ + if (hpPriv->enableBBHeavyClip && hpPriv->hwBBHeavyClip && (frequency <= ZM_CH_G_14)) + { + if (frequency <= ZM_CH_G_14) + { + ctl_i = zfFindCtlEdgesIndex(dev, desired_CtlIndex|CTL_11G); + } + else + { + ctl_i = zfFindCtlEdgesIndex(dev, desired_CtlIndex|CTL_11A); + } + + hpPriv->setValueHeavyClip = zfHpCheckDoHeavyClip(dev, frequency, eepromImage->ctlData[ctl_i].ctlEdges[1], bw40); + + if (hpPriv->setValueHeavyClip) + { + hpPriv->doBBHeavyClip = 1; + } + else + { + hpPriv->doBBHeavyClip = 0; + } + #ifdef ZM_ENABLE_BANDEDGES_WINDOWS_DEBUG + zm_dbg(("zfHpCheckDoHeavyClip ret = %02x, doBBHeavyClip = %d\n", + hpPriv->setValueHeavyClip, hpPriv->doBBHeavyClip)); + #endif + + if (hpPriv->doBBHeavyClip) + { + if (hpPriv->setValueHeavyClip & 0xf0) + { + hpPriv->tPow2x2gHt40[0] -= 1; + hpPriv->tPow2x2gHt40[1] -= 1; + hpPriv->tPow2x2gHt40[2] -= 1; + } + + if (hpPriv->setValueHeavyClip & 0xf) + { + hpPriv->tPow2x2gHt20[0] += 1; + hpPriv->tPow2x2gHt20[1] += 1; + hpPriv->tPow2x2gHt20[2] += 1; + } + } + } + else + { + hpPriv->doBBHeavyClip = 0; + hpPriv->setValueHeavyClip = 0; + } + + /* Final : write MAC register for some ctrl frame Tx power */ + /* first part : 2.4G */ + if (frequency <= ZM_CH_G_14) + { + /* Write MAC reg 0x694 for ACK's TPC */ + /* Write MAC reg 0xbb4 RTS and SF-CTS frame power control */ + /* Always use two stream for low legacy rate */ + #if 0 + //if (hpPriv->halCapability & ZM_HP_CAP_11N_ONE_TX_STREAM) + //{ + zfDelayWriteInternalReg(dev, 0x1c3694, ((hpPriv->tPow2x2g[0]&0x3f) << 20) | (0x1<<26)); + zfDelayWriteInternalReg(dev, 0x1c3bb4, ((hpPriv->tPow2x2g[0]&0x3f) << 5 ) | (0x1<<11) | + ((hpPriv->tPow2x2g[0]&0x3f) << 21) | (0x1<<27) ); + //} + #endif + #if 1 + //else + { + #ifndef ZM_OTUS_LINUX_PHASE_2 + zfDelayWriteInternalReg(dev, 0x1c3694, ((hpPriv->tPow2x2g[0]&0x3f) << 20) | (0x5<<26)); + zfDelayWriteInternalReg(dev, 0x1c3bb4, ((hpPriv->tPow2x2g[0]&0x3f) << 5 ) | (0x5<<11) | + ((hpPriv->tPow2x2g[0]&0x3f) << 21) | (0x5<<27) ); + #endif + hpPriv->currentAckRtsTpc = hpPriv->tPow2x2g[0]; + } + #endif + zfFlushDelayWrite(dev); + + zfPrintTargetPower2G(hpPriv->tPow2xCck, + hpPriv->tPow2x2g, + hpPriv->tPow2x2gHt20, + hpPriv->tPow2x2gHt40); + } + else + { + /* Write MAC reg 0x694 for ACK's TPC */ + /* Write MAC reg 0xbb4 RTS and SF-CTS frame power control */ + /* Always use two stream for low legacy rate */ + if (hpPriv->halCapability & ZM_HP_CAP_11N_ONE_TX_STREAM) + { + #ifndef ZM_OTUS_LINUX_PHASE_2 + zfDelayWriteInternalReg(dev, 0x1c3694, ((hpPriv->tPow2x5g[0]&0x3f) << 20) | (0x1<<26)); + zfDelayWriteInternalReg(dev, 0x1c3bb4, ((hpPriv->tPow2x5g[0]&0x3f) << 5 ) | (0x1<<11) | + ((hpPriv->tPow2x5g[0]&0x3f) << 21) | (0x1<<27) ); + #endif + } + else + { + #ifndef ZM_OTUS_LINUX_PHASE_2 + zfDelayWriteInternalReg(dev, 0x1c3694, ((hpPriv->tPow2x5g[0]&0x3f) << 20) | (0x5<<26)); + zfDelayWriteInternalReg(dev, 0x1c3bb4, ((hpPriv->tPow2x5g[0]&0x3f) << 5 ) | (0x5<<11) | + ((hpPriv->tPow2x5g[0]&0x3f) << 21) | (0x5<<27) ); + #endif + hpPriv->currentAckRtsTpc = hpPriv->tPow2x2g[0]; + } + + + zfFlushDelayWrite(dev); + + zfPrintTargetPower5G( + hpPriv->tPow2x5g, + hpPriv->tPow2x5gHt20, + hpPriv->tPow2x5gHt40); + }/* end of bandedges of 5G */ + +} + +void zfDumpEepBandEdges(struct ar5416Eeprom* eepromImage) +{ + #ifdef ZM_ENABLE_BANDEDGES_WINDOWS_DEBUG + u8_t i, j, k; + +#if 0 + zm_dbg(("\n === BandEdges index dump ==== \n")); + + for (i = 0; i < AR5416_NUM_CTLS; i++) + { + zm_dbg(("%02x ", eepromImage->ctlIndex[i])); + } + + zm_dbg(("\n === BandEdges data dump ==== \n")); + + for (i = 0; i < AR5416_NUM_CTLS; i++) + { + for (j = 0; j < 2; j++) + { + for(k = 0; k < AR5416_NUM_BAND_EDGES; k++) + { + u8_t *pdata = (u8_t*)&(eepromImage->ctlData[i].ctlEdges[j][k]); + zm_dbg(("(%02x %02x)", pdata[0], pdata[1])); + } + zm_dbg(("\n")); + } + } +#else + zm_dbg(("\n === BandEdges index dump ==== \n")); + for (i = 0; i < 24; i+=8) + { + zm_dbg(("%02x %02x %02x %02x %02x %02x %02x %02x", + eepromImage->ctlIndex[i+0], eepromImage->ctlIndex[i+1], eepromImage->ctlIndex[i+2], eepromImage->ctlIndex[i+3], + eepromImage->ctlIndex[i+4], eepromImage->ctlIndex[i+5], eepromImage->ctlIndex[i+6], eepromImage->ctlIndex[i+7] + )); + } + + zm_dbg(("\n === BandEdges data dump ==== \n")); + + for (i = 0; i < AR5416_NUM_CTLS; i++) + { + for (j = 0; j < 2; j++) + { + u8_t *pdata = (u8_t*)&(eepromImage->ctlData[i].ctlEdges[j]); + zm_dbg(("(%03d %02x) (%03d %02x) (%03d %02x) (%03d %02x) \n", + pdata[0], pdata[1], pdata[2], pdata[3], + pdata[4], pdata[5], pdata[6], pdata[7] + )); + zm_dbg(("(%03d %02x) (%03d %02x) (%03d %02x) (%03d %02x) \n", + pdata[8], pdata[9], pdata[10], pdata[11], + pdata[12], pdata[13], pdata[14], pdata[15] + )); + } + } +#endif + #endif +} + +void zfPrintTargetPower2G(u8_t* tPow2xCck, u8_t* tPow2x2g, u8_t* tPow2x2gHt20, u8_t* tPow2x2gHt40) +{ + //#ifdef ZM_ENABLE_TPC_WINDOWS_DEBUG + #ifdef ZM_ENABLE_BANDEDGES_WINDOWS_DEBUG + DbgPrint("targetPwr CCK : %d, %d, %d, %d\n", + tPow2xCck[0], + tPow2xCck[1], + tPow2xCck[2], + tPow2xCck[3] + ); + DbgPrint("targetPwr 2G : %d, %d, %d, %d\n", + tPow2x2g[0], + tPow2x2g[1], + tPow2x2g[2], + tPow2x2g[3] + ); + DbgPrint("targetPwr 2GHT20 : %d, %d, %d, %d, %d, %d, %d, %d\n", + tPow2x2gHt20[0], + tPow2x2gHt20[1], + tPow2x2gHt20[2], + tPow2x2gHt20[3], + tPow2x2gHt20[4], + tPow2x2gHt20[5], + tPow2x2gHt20[6], + tPow2x2gHt20[7] + ); + DbgPrint("targetPwr 2GHT40 : %d, %d, %d, %d, %d, %d, %d, %d\n", + tPow2x2gHt40[0], + tPow2x2gHt40[1], + tPow2x2gHt40[2], + tPow2x2gHt40[3], + tPow2x2gHt40[4], + tPow2x2gHt40[5], + tPow2x2gHt40[6], + tPow2x2gHt40[7] + ); + #endif + return; +} + +void zfPrintTargetPower5G(u8_t* tPow2x5g, u8_t* tPow2x5gHt20, u8_t* tPow2x5gHt40) +{ + //#ifdef ZM_ENABLE_TPC_WINDOWS_DEBUG + #ifdef ZM_ENABLE_BANDEDGES_WINDOWS_DEBUG + DbgPrint("targetPwr 5G : %d, %d, %d, %d\n", + tPow2x5g[0], + tPow2x5g[1], + tPow2x5g[2], + tPow2x5g[3] + ); + DbgPrint("targetPwr 5GHT20 : %d, %d, %d, %d, %d, %d, %d, %d\n", + tPow2x5gHt20[0], + tPow2x5gHt20[1], + tPow2x5gHt20[2], + tPow2x5gHt20[3], + tPow2x5gHt20[4], + tPow2x5gHt20[5], + tPow2x5gHt20[6], + tPow2x5gHt20[7] + ); + DbgPrint("targetPwr 5GHT40 : %d, %d, %d, %d, %d, %d, %d, %d\n", + tPow2x5gHt40[0], + tPow2x5gHt40[1], + tPow2x5gHt40[2], + tPow2x5gHt40[3], + tPow2x5gHt40[4], + tPow2x5gHt40[5], + tPow2x5gHt40[6], + tPow2x5gHt40[7] + ); + #endif + return; +} + +void zfHpPowerSaveSetMode(zdev_t* dev, u8_t staMode, u8_t psMode, u16_t bcnInterval) +{ + if ( staMode == 0 ) + { + if ( psMode == 0 ) + { + // Turn off pre-TBTT interrupt + zfDelayWriteInternalReg(dev, ZM_MAC_REG_PRETBTT, 0); + zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_PERIOD, 0); + zfFlushDelayWrite(dev); + } + else + { + // Turn on pre-TBTT interrupt + zfDelayWriteInternalReg(dev, ZM_MAC_REG_PRETBTT, (bcnInterval-6)<<16); + zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_PERIOD, bcnInterval); + zfFlushDelayWrite(dev); + } + } +} + +void zfHpPowerSaveSetState(zdev_t* dev, u8_t psState) +{ + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv = wd->hpPrivate; + + //DbgPrint("INTO zfHpPowerSaveSetState"); + + if ( psState == 0 ) //power up + { + //DbgPrint("zfHpPowerSaveSetState Wake up from PS\n"); + reg_write(0x982C, 0x0000a000); //wake up ADDAC + reg_write(0x9808, 0x0); //enable all agc gain and offset updates to a2 + //# bank 3 + if (((struct zsHpPriv*)wd->hpPrivate)->hwFrequency <= ZM_CH_G_14) + { + /* 11g */ + //reg_write (0x98f0, 0x01c00018); + reg_write (0x98f0, 0x01c20098);//syn_on+RX_ON + } + else + { + /* 11a */ + //reg_write (0x98f0, 0x01400018); + reg_write (0x98f0, 0x01420098);//syn_on+RX_ON + } + + ////#bank 5 + //reg_write(0x98b0, 0x00000013); + //reg_write(0x98e4, 0x00000002); + + + zfFlushDelayWrite(dev); + } + else //power down + { + //DbgPrint("zfHpPowerSaveSetState Go to PS\n"); + //reg_write(0x982C, 0xa000a000); + reg_write(0x9808, 0x8000000); //disable all agc gain and offset updates to a2 + reg_write(0x982C, 0xa000a000); //power down ADDAC + //# bank 3 + if (((struct zsHpPriv*)wd->hpPrivate)->hwFrequency <= ZM_CH_G_14) + { + /* 11g */ + reg_write (0x98f0, 0x00c00018);//syn_off+RX_off + } + else + { + /* 11a */ + reg_write (0x98f0, 0x00400018);//syn_off+RX_off + } + + ////#bank 5 + //reg_write(0x98b0, 0x000e0013); + //reg_write(0x98e4, 0x00018002); + + + zfFlushDelayWrite(dev); + } +} + +void zfHpSetAggPktNum(zdev_t* dev, u32_t num) +{ + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv = wd->hpPrivate; + + num = (num << 16) | (0xa); + + hpPriv->aggPktNum = num; + + //aggregation number will be update in HAL heart beat + //zfDelayWriteInternalReg(dev, 0x1c3b9c, num); + //zfFlushDelayWrite(dev); +} + +void zfHpSetMPDUDensity(zdev_t* dev, u8_t density) +{ + u32_t value; + + if (density > ZM_MPDU_DENSITY_8US) + { + return; + } + + /* Default value in this register */ + value = 0x140A00 | density; + + zfDelayWriteInternalReg(dev, 0x1c3ba0, value); + zfFlushDelayWrite(dev); + return; +} + +void zfHpSetSlotTime(zdev_t* dev, u8_t type) +{ + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv = wd->hpPrivate; + + if (type == 0) + { + //normal slot = 20us + hpPriv->slotType = 0; + } + else //if (type == 1) + { + //short slot = 9us + hpPriv->slotType = 1; + } + + return; +} + +void zfHpSetSlotTimeRegister(zdev_t* dev, u8_t type) +{ + if(type == 0) + { + //normal slot = 20us + zfDelayWriteInternalReg(dev, ZM_MAC_REG_SLOT_TIME, 20<<10); + } + else + { + //short slot = 9us + zfDelayWriteInternalReg(dev, ZM_MAC_REG_SLOT_TIME, 9<<10); + } +} + +void zfHpSetRifs(zdev_t* dev, u8_t ht_enable, u8_t ht2040, u8_t g_mode) +{ + zfDelayWriteInternalReg(dev, 0x1c6388, 0x0c000000); + + zfDelayWriteInternalReg(dev, 0x1c59ec, 0x0cc80caa); + + if (ht_enable) + { + if (ht2040) + { + zfDelayWriteInternalReg(dev, 0x1c5918, 40); + } + else + { + zfDelayWriteInternalReg(dev, 0x1c5918, 20); + } + } + + if (g_mode) + { + zfDelayWriteInternalReg(dev, 0x1c5850, 0xec08b4e2); + zfDelayWriteInternalReg(dev, 0x1c585c, 0x313a5d5e); + } + else + { + zfDelayWriteInternalReg(dev, 0x1c5850, 0xede8b4e0); + zfDelayWriteInternalReg(dev, 0x1c585c, 0x3139605e); + } + + zfFlushDelayWrite(dev); + return; +} + +void zfHpBeginSiteSurvey(zdev_t* dev, u8_t status) +{ + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv=wd->hpPrivate; + + if ( status == 1 ) + { // Connected + hpPriv->isSiteSurvey = 1; + } + else + { // Not connected + hpPriv->isSiteSurvey = 0; + } + + /* reset workaround state to default */ +// if (hpPriv->rxStrongRSSI == 1) + { + hpPriv->rxStrongRSSI = 0; + if ((hpPriv->eepromImage[0x100+0x110*2/4]&0xff) == 0x80) //FEM TYPE + { + if (hpPriv->hwFrequency <= ZM_CH_G_14) + { + zfDelayWriteInternalReg(dev, 0x1c8960, 0x9b49); + } + else + { + zfDelayWriteInternalReg(dev, 0x1c8960, 0x0900); + } + } + else + { + zfDelayWriteInternalReg(dev, 0x1c8960, 0x9b40); + } + zfFlushDelayWrite(dev); + } +// if (hpPriv->strongRSSI == 1) + { + hpPriv->strongRSSI = 0; + zfDelayWriteInternalReg(dev, 0x1c3694, ((hpPriv->currentAckRtsTpc&0x3f) << 20) | (0x5<<26)); + zfDelayWriteInternalReg(dev, 0x1c3bb4, ((hpPriv->currentAckRtsTpc&0x3f) << 5 ) | (0x5<<11) | + ((hpPriv->currentAckRtsTpc&0x3f) << 21) | (0x5<<27) ); + zfFlushDelayWrite(dev); + } +} + +void zfHpFinishSiteSurvey(zdev_t* dev, u8_t status) +{ + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv=wd->hpPrivate; + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + if ( status == 1 ) + { + hpPriv->isSiteSurvey = 2; + } + else + { + hpPriv->isSiteSurvey = 0; + } + zmw_leave_critical_section(dev); +} + +u16_t zfFwRetry(zdev_t* dev, u8_t enable) +{ + u32_t cmd[(ZM_MAX_CMD_SIZE/4)]; + u16_t ret = 0; + + cmd[0] = 4 | (0x92 << 8); + cmd[1] = (enable == 1) ? 0x01 : 0x00; + + ret = zfIssueCmd(dev, cmd, 8, ZM_OID_INTERNAL_WRITE, NULL); + return ret; +} + +u16_t zfHpEnableHwRetry(zdev_t* dev) +{ + u16_t ret; + + ret = zfFwRetry(dev, 0); + + zfDelayWriteInternalReg(dev, 0x1c3b28, 0x33333); + zfFlushDelayWrite(dev); + + return ret; +} + +u16_t zfHpDisableHwRetry(zdev_t* dev) +{ + u16_t ret; + + ret = zfFwRetry(dev, 1); + + zfDelayWriteInternalReg(dev, 0x1c3b28, 0x00000); + zfFlushDelayWrite(dev); + + return ret; +} + +/* Download SPI Fw */ +#define ZM_FIRMWARE_WLAN 0 +#define ZM_FIRMWARE_SPI_FLASH 1 + + +u16_t zfHpFirmwareDownload(zdev_t* dev, u8_t fwType) +{ + u16_t ret = ZM_SUCCESS; + + if (fwType == ZM_FIRMWARE_WLAN) + { + ret = zfFirmwareDownload(dev, (u32_t*)zcFwImage, + (u32_t)zcFwImageSize, ZM_FIRMWARE_WLAN_ADDR); + } + else if (fwType == ZM_FIRMWARE_SPI_FLASH) + { + ret = zfFirmwareDownload(dev, (u32_t*)zcFwImageSPI, + (u32_t)zcFwImageSPISize, ZM_FIRMWARE_SPI_ADDR); + } + else + { + zm_debug_msg1("Unknown firmware type = ", fwType); + ret = ZM_ERR_FIRMWARE_WRONG_TYPE; + } + + return ret; +} + +/* Enable software decryption */ +void zfHpSWDecrypt(zdev_t* dev, u8_t enable) +{ + u32_t value = 0x70; + + /* Bit 4 for enable software decryption */ + if (enable == 1) + { + value = 0x78; + } + + zfDelayWriteInternalReg(dev, 0x1c3678, value); + zfFlushDelayWrite(dev); +} + +/* Enable software encryption */ +void zfHpSWEncrypt(zdev_t* dev, u8_t enable) +{ + /* Because encryption by software or hardware is judged by driver in Otus, + we don't need to do anything in the HAL layer. + */ +} + +u32_t zfHpCapability(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv=wd->hpPrivate; + + return hpPriv->halCapability; +} + +void zfHpSetRollCallTable(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv=wd->hpPrivate; + + if (hpPriv->camRollCallTable != (u64_t) 0) + { + zfDelayWriteInternalReg(dev, ZM_MAC_REG_ROLL_CALL_TBL_L, (u32_t)(hpPriv->camRollCallTable & 0xffffffff)); + zfDelayWriteInternalReg(dev, ZM_MAC_REG_ROLL_CALL_TBL_H, (u32_t)((hpPriv->camRollCallTable >> 32) & 0xffffffff)); + zfFlushDelayWrite(dev); + } +} + +void zfHpSetTTSIFSTime(zdev_t* dev, u8_t sifs_time) +{ + u32_t reg_value = 0; + zmw_get_wlan_dev(dev); + + sifs_time &= 0x3f; + reg_value = 0x14400b | (((u32_t)sifs_time)<<24); + + zfDelayWriteInternalReg(dev, ZM_MAC_REG_EIFS_AND_SIFS, reg_value); + zfFlushDelayWrite(dev); +} + +/* #3 Enable RIFS function if the RIFS pattern matched ! */ +void zfHpEnableRifs(zdev_t* dev, u8_t mode24g, u8_t modeHt, u8_t modeHt2040) +{ + + /* # Enable Reset TDOMAIN + * $rddata = &$phyreg_read(0x9800+(738<<2)); + * $wrdata = $rddata | (0x1 << 26) | (0x1 << 27); + * &$phyreg_write(0x9800+(738<<2), $wrdata); + */ + reg_write (0x9800+(738<<2), 0x08000000 | (0x1 << 26) | (0x1 << 27)); + //reg_write (0x9800+(738<<2), 0x08000000 | (0x1 << 26)); + + /* # reg 123: heavy clip factor, xr / RIFS search parameters */ + reg_write (0x99ec, 0x0cc80caa); + + /* # Reduce Search Start Delay for RIFS */ + if (modeHt == 1) /* ($HT_ENABLE == 1) */ + { + if (modeHt2040 == 0x1) /* ($DYNAMIC_HT2040_EN == 0x1) */ + { + reg_write(0x9800+(70<<2), 40);/*40*/ + } + else + { + reg_write(0x9800+(70<<2), 20); + if(mode24g == 0x0) + { + /* $rddata = &$phyreg_read(0x9800+(24<<2));#0x9860;0x1c5860 + *$wrdata = ($rddata & 0xffffffc7) | (0x4 << 3); + * &$phyreg_write(0x9800+(24<<2), $wrdata); + */ + reg_write(0x9800+(24<<2), (0x0004dd10 & 0xffffffc7) | (0x4 << 3)); + } + } + } + + if (mode24g == 0x1) + { + reg_write(0x9850, 0xece8b4e4);/*org*/ + //reg_write(0x9850, 0xece8b4e2); + reg_write(0x985c, 0x313a5d5e); + } + else + { + reg_write(0x9850, 0xede8b4e4); + reg_write(0x985c, 0x3139605e); + } + + zfFlushDelayWrite(dev); + + return; +} + +/* #4 Disable RIFS function if the RIFS timer is timeout ! */ +void zfHpDisableRifs(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + + /* Disable RIFS function is to store these HW register initial value while the device plug-in and + re-write to these register if the RIFS function is disabled */ + + // reg : 9850 + reg_write(0x9850, ((struct zsHpPriv*)wd->hpPrivate)->initDesiredSigSize); + + // reg : 985c + reg_write(0x985c, ((struct zsHpPriv*)wd->hpPrivate)->initAGC); + + // reg : 9860 + reg_write(0x9800+(24<<2), ((struct zsHpPriv*)wd->hpPrivate)->initAgcControl); + + // reg : 9918 + reg_write(0x9800+(70<<2), ((struct zsHpPriv*)wd->hpPrivate)->initSearchStartDelay); + + // reg : 991c + reg_write (0x99ec, ((struct zsHpPriv*)wd->hpPrivate)->initRIFSSearchParams); + + // reg : a388 + reg_write (0x9800+(738<<2), ((struct zsHpPriv*)wd->hpPrivate)->initFastChannelChangeControl); + + zfFlushDelayWrite(dev); + + return; +} --- linux-2.6.28.orig/drivers/staging/otus/hal/hpfwu_2k.c +++ linux-2.6.28/drivers/staging/otus/hal/hpfwu_2k.c @@ -0,0 +1,1016 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "cprecomp.h" + +const u32_t zcFwImage[] = { +0x0009000B, 0x4F222FE6, 0xDE947FFC, 0xE114D594, +0x1E13D494, 0x67521E4C, 0xD494D693, 0x37402769, +0x62528F06, 0x7201D692, 0x60602522, 0x2600C93F, +0xD7906152, 0x2512611D, 0x264B6652, 0x2562470B, +0x0009B017, 0xE60095AC, 0xC84060E2, 0x2F028F03, +0x8FF93652, 0xD4887601, 0x4E0BDE88, 0xD4880009, +0x00094E0B, 0x4E0BD487, 0x7F040009, 0xA0524F26, +0x4F226EF6, 0x410BD184, 0xD4840009, 0x0009440B, +0x450BD583, 0xD7830009, 0xD283E1FF, 0x2712611D, +0xD4825029, 0xE1FFCB01, 0x1209E501, 0x12112212, +0xE7202452, 0x4718D57E, 0x2572D27E, 0xD17EE700, +0xD67FD47E, 0xE2012270, 0x24702172, 0xD67D2620, +0x2641E4FF, 0xD57CE600, 0x666DE104, 0x76016063, +0x4000626D, 0x8FF83212, 0xD5780545, 0x2520E201, +0xD278D777, 0xE480E100, 0x22122710, 0x6613D576, +0x666D644C, 0x76046763, 0x375C626D, 0x8FF83243, +0xD5722712, 0xD273D772, 0xE400E101, 0x27102511, +0x000B4F26, 0x7FCC2242, 0xD170D56F, 0xD271DB70, +0x1F51D471, 0xD6717508, 0x1F12D771, 0x1F55710C, +0x1FB975FC, 0x72041F2A, 0x1F13EB10, 0x1F561F44, +0x1F781F67, 0xD86B1F2B, 0xDD6CD96B, 0xDC6CEA00, +0xD26DDE6C, 0x89003A22, 0xD15D7A01, 0x88016010, +0x56F88B03, 0x4218E201, 0xD1682622, 0x0009410B, +0x440BD467, 0xD5670009, 0x0009450B, 0x6010D150, +0x8B108801, 0xE650D14F, 0x46186212, 0x8B083266, +0x56F9D14B, 0x2120E200, 0xCB016062, 0x2602A003, +0x72012710, 0x60822122, 0x89098801, 0xE2C8D15A, +0x622C6612, 0x89033626, 0x6010D158, 0x8BC88801, +0x51F66792, 0x217252F5, 0xD6555191, 0x55FA2212, +0x52FB6462, 0x55612542, 0x2252E400, 0x61436643, +0x05DE6013, 0x36CC4608, 0x07DE2652, 0xC9036071, +0x8B028801, 0x720162E2, 0x74012E22, 0x36B3664C, +0x71048FEE, 0x66C2D147, 0x45286512, 0x265B4518, +0x60822C62, 0x89018801, 0x0009A168, 0x6272D742, +0x8B132228, 0xD42BD741, 0x6772D541, 0x51536242, +0x312C327C, 0x24222228, 0x15138D05, 0x6262D63D, +0xB1627201, 0xD6232622, 0x2622E200, 0x52916692, +0x8B013620, 0x0009A144, 0x6061A06E, 0x001C001C, +0x001D4020, 0x0000B38E, 0xFFFF0000, 0x12340000, +0x001E1015, 0x00201274, 0x002039EC, 0x002018A2, +0x002039F8, 0x00203A10, 0x00201860, 0x00201964, +0x00201288, 0x001C3510, 0x001C3624, 0x001E212C, +0x002038EC, 0x00203484, 0x002038F4, 0x00203900, +0x0020390C, 0x00203968, 0x0020396C, 0x00203914, +0x00203915, 0x00203918, 0x00117700, 0x00203984, +0x00203982, 0x002034E8, 0x00117710, 0x001C3D30, +0x001C36F8, 0x00117734, 0x001C3684, 0x001C3D00, +0x001C1000, 0x001C1028, 0x002034FC, 0x0020391C, +0x00117600, 0x00117740, 0x7FFFFFFF, 0x00201730, +0x00203322, 0x0020232C, 0x00203D9C, 0x0020396A, +0x002034F4, 0x0020395C, 0x001C3D2C, 0x001C36B0, +0x0020348C, 0x0011775C, 0x8801C90F, 0xA0CF8901, +0xD1960009, 0x36206212, 0xD4958904, 0x2421E200, +0x2162A0CC, 0x6211D193, 0x89012228, 0x0009A0C3, +0xE202D78F, 0x75016571, 0x3123615D, 0x27518D02, +0x0009A0BC, 0xD28C57F2, 0x62226072, 0x40094019, +0xC90F4009, 0x8F19880A, 0x52F31F2C, 0x40196022, +0x40094009, 0x8808C90F, 0xA0A78901, 0x60630009, +0xCB0154F7, 0xD27E55F2, 0xE7012402, 0xD47FE100, +0x22112572, 0x72016242, 0x2422A098, 0x8B3F8805, +0x602252F3, 0x40094019, 0xC90F4009, 0x8B168802, +0xE4FFD577, 0x644D6752, 0x8B102748, 0x6272D775, +0x8B0C3260, 0x51F255F7, 0xD26DE701, 0x21722562, +0xD571E100, 0x64522211, 0xA0777401, 0x52F32542, +0x40196022, 0x40094009, 0x8805C90F, 0x31B38B6E, +0xD26A8B6C, 0x672254F4, 0x7701D569, 0x61422272, +0x1F1CE640, 0x46182159, 0x8B033160, 0x6262D665, +0x26227201, 0xE200D65A, 0x2621B067, 0x0009A056, +0x3123E220, 0x88038B52, 0x52F38B1E, 0x40196022, +0x40094009, 0x8803C90F, 0xD25B8B16, 0x672254F4, +0x7701D557, 0x61422272, 0x1F1CE640, 0x46182159, +0x8B033160, 0x6262D655, 0x26227201, 0xE200D648, +0x2621B043, 0x0009A010, 0xD452D551, 0xD2446752, +0xE1007701, 0x25723A46, 0x22118F06, 0xEA00D64E, +0x72016262, 0x2622B031, 0x2FB2D54C, 0x95736652, +0xD44A5BF1, 0x36205241, 0x60618910, 0x8B01C803, +0x2B22E201, 0x8FF54510, 0x57F15664, 0x6272E1F0, +0x41284118, 0x2722221B, 0x6BF2A008, 0x6BF2A006, +0xE200D62F, 0xD12F2621, 0x2121E200, 0xD13CE201, +0x66122822, 0x8B012668, 0x0009AE2B, 0x450BD539, +0xD1390009, 0xAE24E600, 0x2F862160, 0x2FA62F96, +0x2FC62FB6, 0x2FE62FD6, 0x7FF44F22, 0xDE34D133, +0x54116212, 0x1F4167E2, 0x2F22D432, 0xD5321F72, +0xD2326743, 0x58417794, 0x69425A42, 0x5B166C72, +0x60526D22, 0xCB20E600, 0xE5402502, 0x626D7601, +0x8BFB3253, 0x55F162F2, 0x11512122, 0xD62855F2, +0x14812E52, 0x249214A2, 0x27C2D426, 0x26D211B6, +0xDA256742, 0xE801D925, 0x490B2A72, 0xE2011A8C, +0x1A2C4218, 0x4F267F0C, 0x6DF66EF6, 0x6BF66CF6, +0x69F66AF6, 0x68F6000B, 0x000007D1, 0x0020397C, +0x00203980, 0x00203986, 0x001C3DC0, 0x0011772C, +0x001C3B88, 0x00203964, 0x0011773C, 0x00117744, +0x0000F000, 0x00117764, 0x00117748, 0x00117768, +0x0011776C, 0x01FFFFFF, 0x0011774C, 0x002034F4, +0x00203D9C, 0x002024F0, 0x0020396A, 0x001C3B9C, +0x001C3D98, 0x001C3700, 0x001C3500, 0x001C5960, +0x001C8960, 0x002034FC, 0x001C3D00, 0x0020160C, +0x2F962F86, 0x2FB62FA6, 0x2FD62FC6, 0x4F222FE6, +0xDE957FAC, 0x61E0E014, 0x0F14D494, 0x710161E3, +0xE0186210, 0xD2920F24, 0x0009420B, 0x450BD591, +0x20080009, 0x8F126D03, 0xD28F1F07, 0x6720D48F, +0x657CDD8F, 0x470BD78F, 0xD18F0009, 0x619C6910, +0x46086613, 0x36184608, 0x3D6C4608, 0xE0181FD7, +0xE58004FC, 0x604C66E2, 0x3050655C, 0x2D628F15, +0x01FCE014, 0xDE85E500, 0x641CA008, 0x6753655D, +0x607037EC, 0x39DC6953, 0x80947501, 0x3243625D, +0xD67F8BF4, 0xA34EE200, 0x20082621, 0xE0148B13, +0xE40001FC, 0xA009DE79, 0x644D671C, 0x35EC6543, +0x69436652, 0x39DC6262, 0x74041921, 0x3273624D, +0xA3388BF3, 0x88012D10, 0xE0148B17, 0xE70001FC, +0x6D1C2D70, 0xDE6D1FD4, 0x32D3627D, 0xA32A8B01, +0x677D0009, 0x667365E3, 0x61737504, 0x315C36EC, +0x69126462, 0xAFEF7708, 0x88042492, 0xE0148B18, +0xE40001FC, 0x671C2D40, 0x624DDE60, 0x8B013273, +0x0009A311, 0x6943644D, 0x39EC62E3, 0x72046592, +0x3D2C6D43, 0x615266D2, 0x21697408, 0x2512AFED, +0x8B188805, 0x01FCE014, 0x2D40E400, 0xDE53671C, +0x3273624D, 0xA2F68B01, 0x644D0009, 0x62E36943, +0x659239EC, 0x6D437204, 0x66D23D2C, 0x74086152, +0xAFED216B, 0x88312512, 0xD44A8B3A, 0x6146D94A, +0x75046543, 0x67566442, 0x6E531F48, 0x65527E04, +0x7EE462E2, 0x7E0464E2, 0x6EE21FE9, 0x5EF929E0, +0x7E04D942, 0x1FEA60E2, 0x2900C901, 0xD9406EE2, +0x29E04E09, 0x2F562F26, 0x56FAD93E, 0x6513490B, +0xD13D7F08, 0xE71C6E0D, 0x1DE12D70, 0xDE3B6912, +0x64E21D92, 0x1D43D13A, 0xD23A6512, 0x67221D54, +0x1D75D239, 0x1D666622, 0x6262D638, 0x1D27A2AB, +0x8B398830, 0x6596D92B, 0x67926696, 0x61967904, +0x74E46493, 0x6E436992, 0x1F9B7E04, 0x1FEC6442, +0xD9256EE2, 0x5EFC29E0, 0x7E04D924, 0x1FED60E2, +0x2900C901, 0xD9226EE2, 0x29E04E09, 0x59FC7FFC, +0xDE272F92, 0x2F164E0B, 0xD41F7F08, 0xE21C610D, +0x1D112D20, 0xD2206442, 0xD41C1D42, 0x1D536542, +0x6752D51B, 0xD71B1D74, 0x1D156172, 0x1D666622, +0x6262D61A, 0x1D27A26F, 0x8B358833, 0x490BD919, +0xA268EE00, 0x00002DE0, 0x00117800, 0x00203A14, +0x002018A2, 0x00202AA4, 0x00203906, 0x00203A18, +0x0020352C, 0x002018EE, 0x00203905, 0x00117804, +0x00203984, 0x00117810, 0x00203901, 0x00203902, +0x00203903, 0x00200F64, 0x001C5864, 0x001C6864, +0x001C7864, 0x001C59BC, 0x001C69BC, 0x001C79BC, +0x00200FBC, 0x00200FB8, 0x89018828, 0x0009A0C0, +0xE643DEB5, 0x326662E1, 0x1FEE8F02, 0x2E21E240, +0x622D62E1, 0x8B013267, 0x0009A0AA, 0xE50185E1, +0x8B013056, 0x0009A0A4, 0x2D10E101, 0x64E1B225, +0xE64357FE, 0x652D6271, 0x89443567, 0x3563E640, +0xE6008B05, 0x0F65E040, 0xA00FE11A, 0x615372C0, +0x41214121, 0x41214121, 0x45214121, 0x45214521, +0xC9036053, 0xE0406603, 0x71180F65, 0x2209E007, +0x0F25E03C, 0xE044641D, 0xB2A365F3, 0xE33C0F46, +0x853233FC, 0x620DDE95, 0x42086031, 0x6023610D, +0x1323E944, 0x06FE4108, 0xE00F39FC, 0x13144E0B, +0x67075D91, 0x60D32679, 0x0F6654FE, 0x51928542, +0x600D4E0B, 0x60D3260B, 0x0F666492, 0x65F3B237, +0x696156FE, 0xE640659D, 0x89383563, 0xD78359FE, +0x79066591, 0xC9036053, 0x40004008, 0x61036203, +0x0F26E050, 0x470BE0FF, 0x6C07600C, 0x6603605D, +0x46214621, 0x46214621, 0x42006263, 0x4200326C, +0x40214021, 0x4008C903, 0x6D2D30FC, 0xE8006A03, +0xB25765F3, 0x6EA264D3, 0x2EC9E050, 0x66942AE2, +0xD76E01FE, 0x606C470B, 0x2AE22E0B, 0x64D365F3, +0x7801B1FD, 0xEE06628D, 0x8FE932E3, 0x5EFE7D01, +0x61E1E400, 0x410085E1, 0x66E3310C, 0x760C711B, +0xE70465F3, 0x68667401, 0x3A736A4D, 0x8FF92582, +0x65F37504, 0x641DB1E3, 0x64E1B1A4, 0x0009A17B, +0xD45B56F7, 0xEC01D25B, 0x26C0420B, 0x0009A173, +0x06FCE018, 0x8829606C, 0x58F78B08, 0xE400D252, +0x66222840, 0x646DB171, 0x0009A165, 0x666CE681, +0x89013060, 0x0009A0AC, 0xD550D14F, 0x62126A56, +0x212232AC, 0x54116C56, 0x34CC6253, 0x64521141, +0x72085812, 0xD44A384C, 0x68221182, 0x5A136C42, +0x3ACC3C8C, 0x11A324C2, 0x6C2272EC, 0x72105814, +0x118438CC, 0x5A156822, 0x11A53A8C, 0x6A227210, +0xD6405816, 0x118638AC, 0x52176C62, 0x112732CC, +0x5A185861, 0x11A83A8C, 0x5C195A62, 0x11C93CAC, +0x521A5C63, 0x112A32CC, 0x5A1B5864, 0x11AB3A8C, +0x5C1C5A65, 0x11CC3CAC, 0x521D5C66, 0x112D32CC, +0x5A1E5867, 0x11AE3A8C, 0x561F5A68, 0x36ACE840, +0x116FDA2D, 0x6CA2381C, 0x7A946682, 0x286236CC, +0x5C8162A2, 0x18C13C2C, 0x62A27A44, 0x362C5682, +0xD6261862, 0x5A856262, 0x3A2C4229, 0x760418A5, +0x56866262, 0x362C4229, 0x56F71866, 0x2620E238, +0x16C15C81, 0x16226212, 0xE2005C11, 0x551216C3, +0x55151654, 0x55131655, 0x55161656, 0x55821657, +0x65821658, 0x55141659, 0x5584165A, 0x5583165B, +0x5585165C, 0x5586165D, 0x1821165E, 0x11212122, +0x11251122, 0x11261123, 0x28221822, 0x18241124, +0x18251823, 0x1826A0C7, 0x00117804, 0x002033E0, +0x00203A38, 0x002018A2, 0x0020348C, 0x001C36A0, +0x002034E8, 0x001C3CA0, 0x001C36F4, 0x001C3B88, +0x666CE682, 0x8B203060, 0xEA2456F7, 0x26A0D194, +0x16C15C17, 0x16225218, 0x16835819, 0x16A45A1A, +0x16C55C1B, 0x1626521C, 0xE200581D, 0x551E1687, +0x551F1658, 0x11271659, 0x11291128, 0x112B112A, +0x112D112C, 0xA08E112E, 0xE683112F, 0x3060666C, +0x52F78B0B, 0xEA00D883, 0x658222A0, 0x7804DC82, +0x62822C52, 0xA07ED681, 0xE6902620, 0x3060666C, +0xDA7F8B06, 0x00094A0B, 0xE20056F7, 0x2620A073, +0x666CE691, 0x8B103060, 0x6222D276, 0x2228622C, +0xD2788904, 0x0009420B, 0x0009A003, 0x420BD276, +0x56F70009, 0xA05EE200, 0xE6922620, 0x3060666C, +0xE0188951, 0xE6B00BFC, 0x666C62BC, 0x8B2A3260, +0x02FCE014, 0x682CEA00, 0x62ADE904, 0x894A3283, +0x6AADDD64, 0x3CDC6CA3, 0x7D046EC2, 0xDB68D467, +0x32DC62A3, 0x4B0BDC67, 0x4C0B6D22, 0xD46664E3, +0x00094B0B, 0x64D34C0B, 0x4B0BD464, 0xE6000009, +0x666D6BE3, 0x76013B6C, 0x3293626D, 0x8FF72BD0, +0xAFDA4D19, 0xE6B57A08, 0x3260666C, 0xD45C8B13, +0x4B0BDB57, 0xD25B0009, 0x6022DB5B, 0xCB20E6FF, +0x2202666D, 0xDB592B62, 0xE014E200, 0x56F72B20, +0xA01002FC, 0xD4562620, 0x6542D256, 0x420BD456, +0xA0080009, 0xDB520009, 0x52B1E600, 0x622CDB53, +0x52F72B21, 0x7F542260, 0x6EF64F26, 0x6CF66DF6, +0x6AF66BF6, 0x000B69F6, 0x4F2268F6, 0xE240614D, +0x89143123, 0x3127E21F, 0x8B09D749, 0xD449614D, +0xE00171E0, 0x5671440B, 0x26596507, 0x1761A007, +0xE001D444, 0x6672440B, 0x26596507, 0x4F262762, +0x0009000B, 0x614D4F22, 0x3123E240, 0xE21F8912, +0xD73B3127, 0x614D8B08, 0x5671D23A, 0x420B71E0, +0x260BE001, 0x1761A006, 0x6672D236, 0xE001420B, +0x2762260B, 0x000B4F26, 0xE6400009, 0x46284618, +0x6252D531, 0x89FC2268, 0x0009000B, 0x4618E680, +0xD52D4628, 0x22686252, 0x000B89FC, 0xA0010009, +0x7201E200, 0x8BFC3242, 0x0009000B, 0x4618E680, +0xD5264628, 0x22686252, 0x000B8BFC, 0x2FE60009, +0x7FFC4F22, 0xBFF16E53, 0x61E22F42, 0xE280D620, +0x54E11615, 0x16464218, 0x422855E2, 0x57E31657, +0x16786EF2, 0x26E22E2B, 0x4F267F04, 0x6EF6AFCE, +0x0020348C, 0x00117804, 0x002038EC, 0x00203900, +0x0020050A, 0x00201008, 0x0020102E, 0x00203A50, +0x002018A2, 0x002018E6, 0x00203A64, 0x00203A6C, +0x00203A70, 0x001C3500, 0x001C1000, 0x00203982, +0x00117800, 0x002018EE, 0x00203A84, 0x00203988, +0x001C3704, 0x002033E0, 0x001C373C, 0x001C3700, +0x001C370C, 0x2FD62FC6, 0x4F222FE6, 0x6C53DD10, +0x6E43BFA4, 0x2DE2BF89, 0x0009BFA0, 0x2C1251D5, +0x1C4154D6, 0x1C5255D7, 0x1C6356D8, 0x6EF64F26, +0x000B6DF6, 0x61636CF6, 0xA004E600, 0x62564109, +0x24227601, 0x36127404, 0x000B8BF9, 0x00000009, +0x001C370C, 0x0009A16E, 0x2FE62FD6, 0xDD944F22, +0xA0049EB2, 0xD4930009, 0x420BD293, 0x62D265D2, +0x8BF822E8, 0x0009A004, 0xD28FD490, 0x55D1420B, +0x22E852D1, 0xA0048BF8, 0xD48D0009, 0x420BD28A, +0x52D255D2, 0x8BF822E8, 0x0009A004, 0xD286D489, +0x55D3420B, 0x22E852D3, 0xA0048BF8, 0xD4860009, +0x420BD281, 0x52D455D4, 0x8BF822E8, 0x6EF64F26, +0x6DF6000B, 0x2FD62FC6, 0x4F222FE6, 0x6E636C73, +0x6D53B01A, 0x64D357F4, 0xB05F65E3, 0xB07566C3, +0xB0A40009, 0xB0A80009, 0xB0AC0009, 0xB0AC0009, +0xB0AF0009, 0xB03154F5, 0x6CCD6C03, 0x4F2660C3, +0x6DF66EF6, 0x6CF6000B, 0x3412D170, 0xD6700529, +0x2650D770, 0x2742000B, 0x0009A018, 0x2FD62FC6, +0x4F222FE6, 0x6E636C73, 0x6D53BFEE, 0x64D357F4, +0xB03365E3, 0xB08D66C3, 0xB00F54F5, 0x6CCD6C03, +0x4F2660C3, 0x6DF66EF6, 0x6CF6000B, 0xE503D162, +0xD763D462, 0x21524518, 0x2472000B, 0xD45FD15E, +0x2162E600, 0x2462000B, 0xBF734F22, 0xBF73E40A, +0xD25C0009, 0x4118E104, 0xE40AE500, 0xBF692212, +0xD7592252, 0xCB206072, 0x000B4F26, 0x4F222702, +0x410BD156, 0xD556E400, 0x4F26452B, 0xD1552FE6, +0x66126E63, 0x92104418, 0x44084528, 0x45002629, +0x265B4408, 0x264B4400, 0x21624708, 0xD14E4708, +0x217227EB, 0x6EF6000B, 0x1FFF03F0, 0x4F222FE6, +0xE101DE4A, 0xBF3DE40A, 0x67E32E12, 0xE500776C, +0xE204E130, 0x2752E40A, 0x27522752, 0x27522752, +0x27522752, 0x27522752, 0x27522752, 0x27522752, +0x27522752, 0x27522752, 0x27522752, 0x27222712, +0x27522752, 0x27522752, 0x27522752, 0x27522752, +0x175ABF18, 0x2E62E600, 0x000B4F26, 0xD2346EF6, +0xE441E101, 0x000B2212, 0xD1322242, 0xE605D432, +0x000B2162, 0x000B2462, 0xD2300009, 0xE40AE601, +0x2262AF00, 0x2FC62FB6, 0x2FE62FD6, 0x7FFC4F22, +0x6C43DB2B, 0xED0060B2, 0x2B02CB03, 0xC90360B2, +0x6E03A008, 0x89073DC2, 0xE46460B2, 0xB07CC903, +0x7D016E03, 0x8BF52EE8, 0x8F043DC2, 0xD4212FE1, +0x460BD621, 0x62F10009, 0x6023622D, 0x89FFC801, +0x7F046023, 0x6EF64F26, 0x6CF66DF6, 0x6BF6000B, +0x001C3B88, 0x00203A98, 0x002018EE, 0x00203AA0, +0x00203AA8, 0x00203AB0, 0x00203AB8, 0x0025E720, +0x00203D98, 0x002038F0, 0x001C5968, 0x001C3B40, +0x000F8000, 0x001D4004, 0x001C3500, 0x002015E0, +0x0020160C, 0x001C5814, 0x001C59D0, 0x001C5830, +0x001C6268, 0x001C59A4, 0x001C639C, 0x001C581C, +0x001C5860, 0x00203AC0, 0x002018A2, 0x8F014411, +0x6043604B, 0x0009000B, 0x5651D52B, 0x46286052, +0x306C000B, 0x2FC62FB6, 0x2FE62FD6, 0x4F124F22, +0xBFF14F02, 0x6B036E43, 0xDD25DC24, 0x0009BFEC, +0x3C0530B8, 0x4609060A, 0x46014609, 0x020A3D65, +0x42094209, 0x32E24209, 0x4F068BF0, 0x4F264F16, +0x6DF66EF6, 0x000B6CF6, 0x2FC66BF6, 0x2FE62FD6, +0x4F124F22, 0xBFCF4F02, 0x6C036E43, 0xBFCBDD13, +0x30C80009, 0x060A3D05, 0x46094609, 0x36E24601, +0x4F068BF5, 0x4F264F16, 0x6DF66EF6, 0x6CF6000B, +0x4F222FE6, 0xE102DE0B, 0xE403E500, 0xBFB92E12, +0xE6062E52, 0xE7004618, 0x2E62E403, 0x4F262E72, +0x6EF6AFB0, 0x0009000B, 0x001C1040, 0xCCCCCCCD, +0x10624DD3, 0x001D4004, 0x2F962F86, 0x2FB62FA6, +0x2FD62FC6, 0x4F222FE6, 0xE5007F98, 0x6453E710, +0x6B534728, 0xEE1ADCBC, 0x6153655D, 0x315C4108, +0x75014108, 0x6043317C, 0x0F16665D, 0xED0060B3, +0x21B136E3, 0x81128111, 0x11D28113, 0x11D411D3, +0x74048FEA, 0xD8B167F2, 0x1871D9B1, 0x58F12872, +0x1981D1B0, 0x59F22982, 0x5DF45AF3, 0x54F65EF5, +0x21921191, 0x11A211A3, 0x11D411D5, 0x11E611E7, +0x11481149, 0xDAA855F7, 0x57F8EE00, 0x52F9DDA7, +0x64E3D6A7, 0x2A521A51, 0xD8A7D9A6, 0x2D729AD5, +0x6EED2622, 0x4D086DE3, 0x3DEC61E3, 0x4D084108, +0x3D9C31EC, 0x410860B3, 0x81D12DB1, 0x4108E050, +0x4008E7B7, 0x677C4108, 0x60B381D2, 0xE200318C, +0x81D33472, 0x1D131DD2, 0x8D01D493, 0xD4901D24, +0xB0B365D3, 0x64ED7E01, 0x8BDA34A2, 0x2FD2DA8C, +0xDD9268A2, 0x2D824829, 0x7DFC64A2, 0xD287694D, +0x6E222D92, 0x7D0C4E29, 0x68222DE2, 0x618D6AD3, +0x2A16D784, 0xD48A6D72, 0x24D2D583, 0xD6895E72, +0x517414E2, 0x1414EE00, 0xD1875876, 0x59781486, +0x1498E710, 0x65E36252, 0x26E2142A, 0xE60064E3, +0x6843644D, 0x384C4808, 0x381C4808, 0x0C866053, +0x09CE28B1, 0x819160B3, 0x0ACE6053, 0x81A26043, +0x0DCE6053, 0x81D360B3, 0x08CE6053, 0x18827401, +0x624D09CE, 0x0ACE19E3, 0x1A643273, 0x75048FE0, +0xE003D96A, 0x40186C92, 0x6D922CB1, 0x81D1DA6F, +0x6E92E050, 0x81E24008, 0x60B36192, 0x64928113, +0x1442E600, 0xD4696792, 0x689217A3, 0x1864E1FF, +0x6563E703, 0x364C4608, 0x26127501, 0x3673665D, +0xDC5B8BF8, 0x6DC2E003, 0x2DB14018, 0xD2606EC2, +0x61C281E1, 0x1112EE00, 0xE02464C2, 0x65C21423, +0x15E4D45B, 0xE58067C2, 0x68C28172, 0x818366E3, +0x666D655C, 0x76046963, 0x394C6A6D, 0x8FF83A53, +0xDB5429E2, 0x24B2DC54, 0x24C27404, 0x4F267F68, +0x6DF66EF6, 0x6BF66CF6, 0x69F66AF6, 0x68F6000B, +0x60116142, 0x8F03C803, 0xD23DE500, 0x8B063420, +0xC9036011, 0x8B068802, 0x3420D239, 0x56128B03, +0x52646513, 0x000B2422, 0x01136053, 0x2FE62FD6, +0x7FEC4F22, 0x62536E53, 0x6D43E550, 0x4508E400, +0xE101A001, 0x60435224, 0x81212211, 0x60538123, +0x56E28122, 0x8BF53620, 0x16E4D238, 0xE61464F3, +0x65E3420B, 0xE4FC65E1, 0x2E512549, 0x65F361F1, +0x2F112149, 0xD13154D1, 0xE614410B, 0x607157D1, +0x2701CB01, 0x7F141DE1, 0x6EF64F26, 0x6DF6000B, +0x2FE62FD6, 0x7FEC4F22, 0x66536E53, 0x6D43E5FC, +0x20596061, 0x2601CB01, 0x326052E2, 0x12E48B06, +0x31E051E2, 0x52D18B04, 0x1E22A002, 0x5664AFF0, +0x64F3D21E, 0x420BE614, 0x67E165E3, 0x2719E1FC, +0x67F12E71, 0x271954D1, 0x65F3D118, 0x410BE614, +0x52D12F71, 0xCB016021, 0x1DE12201, 0x4F267F14, +0x000B6EF6, 0x00006DF6, 0x0020391C, 0x002034EC, +0x002034F4, 0x002034FC, 0x00203524, 0x00203908, +0x00203910, 0x00100208, 0x001017C0, 0x001E210C, +0x001C3D00, 0x0020395C, 0x001000C8, 0x00117880, +0x00117780, 0x00040020, 0x0026C401, 0x00200ED6, +0x4F222FE6, 0xDE42624C, 0x42004208, 0x3E2CA005, +0xD4405252, 0xBF695624, 0x65E22E62, 0x352052E1, +0xD63D8BF6, 0x4F262622, 0x6EF6000B, 0x2FC62FB6, +0x2FE62FD6, 0xDC394F22, 0x52C1DB39, 0x362066C2, +0x6061891C, 0x8801C903, 0xDE348918, 0xBF37DD35, +0x650364E3, 0x66B28503, 0x3262620D, 0xD4328907, +0x0009BF76, 0x4D0BD431, 0xAFE60009, 0xBF3D0009, +0xD42F64E3, 0x00094D0B, 0x0009AFDF, 0x2262D22D, +0x6EF64F26, 0x6CF66DF6, 0x6BF6000B, 0x2FD62FC6, +0x4F222FE6, 0xDD29DC28, 0x6E4360C2, 0x04DE4008, +0xE614D127, 0x65E3410B, 0xD127D726, 0x55E227E2, +0x35E05254, 0x21228F04, 0x400860C2, 0x122202DE, +0x605365C2, 0x75014008, 0x0DE606DE, 0xC90F6053, +0x60632C02, 0x6EF64F26, 0x000B6DF6, 0x85436CF6, +0x650D5643, 0x622D6262, 0x35277204, 0xE1008F0C, +0x2268960C, 0xD6158B03, 0x72015261, 0xD6131621, +0x6262E101, 0x26227201, 0x6013000B, 0x000001FF, +0x002034FC, 0x002034F4, 0x001C3D00, 0x00203524, +0x002038EC, 0x002018A2, 0x002034EC, 0x00203AE8, +0x00203AEC, 0x001C3D28, 0x0020395C, 0x0020391C, +0x00200ED6, 0x00203960, 0x00203964, 0x00117754, +0x2FC62FB6, 0x2FE62FD6, 0x7FF84F22, 0x6022D237, +0x8D58C803, 0xDE362F01, 0xDB37DC36, 0x66C252C1, +0x892F3620, 0xC9036061, 0x892B8801, 0xD233DD31, +0x64D3420B, 0x1F016503, 0x880160B1, 0xD2308B04, +0x64D3420B, 0x0009AFEA, 0x85615653, 0x8904C820, +0xE050D72C, 0x7201027E, 0xD22B0726, 0x6453420B, +0x89072008, 0x55F1D126, 0x64D3410B, 0xE601D727, +0x2762AFD4, 0x55F1D226, 0x64E3420B, 0xE601D125, +0x2162AFCC, 0xDD25DE24, 0xDC26DB25, 0x66D252D1, +0x89183620, 0xC9036061, 0x89148801, 0xD117D41F, +0x0009410B, 0x36E05603, 0x65038F04, 0x2B20E201, +0x2C52AFEC, 0xD712D41C, 0x0009470B, 0xE601D115, +0xAFE34618, 0x60F12162, 0x8907C804, 0x7F08D217, +0x6EF64F26, 0x6CF66DF6, 0x6BF6422B, 0x4F267F08, +0x6DF66EF6, 0x000B6CF6, 0x00006BF6, 0x001E2100, +0x002034FC, 0x002034F4, 0x00203984, 0x002014A0, +0x002014CC, 0x0020348C, 0x002016BE, 0x001E212C, +0x00201530, 0x001C3D30, 0x00117880, 0x002034EC, +0x0020390C, 0x00203908, 0x00203524, 0x00200610, +0xE601D203, 0x1265D503, 0x000B2252, 0x00001266, +0x001C1010, 0x0000C34F, 0x0009000B, 0x2FD62FC6, +0x4F222FE6, 0x6D436C53, 0xEE00A004, 0x7E0164D4, +0x644CBFF2, 0x8BF93EC2, 0x6EF64F26, 0x000B6DF6, +0xE5006CF6, 0x6643A002, 0x76017501, 0x22286260, +0xAFE38BFA, 0x2FE60009, 0x75076253, 0xE1086753, +0x6043EE0A, 0x4409C90F, 0x650330E2, 0x8D014409, +0xE630E637, 0x4110365C, 0x8FF22760, 0xE00077FF, +0x000B8028, 0x000B6EF6, 0x000BE000, 0x2FE6E000, +0x7FEC4F22, 0x6E436253, 0xBFDC65F3, 0xBFD06423, +0xBFCE64E3, 0xD40364F3, 0x0009BFCB, 0x4F267F14, +0x6EF6000B, 0x00203AF0, 0xE4FDD29D, 0xD79D6122, +0x22122149, 0x74016022, 0x2202CB01, 0xD59A6622, +0x22622649, 0xC8406070, 0x60528902, 0x2502CB04, +0xE6016052, 0x2502CB08, 0xE4026052, 0x2502C9CF, +0x46186052, 0x2502CB10, 0xCB036052, 0x15422502, +0x1563000B, 0xD78ED58D, 0xD48FD28E, 0xE600E100, +0x27112511, 0xAFCF2210, 0x664C2461, 0x4600D28B, +0x6060362C, 0x000BCB10, 0x654C2600, 0x4500D287, +0x6650352C, 0x2619E1EF, 0x2560000B, 0xD284664C, +0x362C4600, 0xCB106060, 0x2600000B, 0xD280654C, +0x352C4500, 0xE1EF6650, 0x000B2619, 0x664C2560, +0x4600D27A, 0x6060362C, 0x000BCB08, 0x654C2600, +0x4500D276, 0x6650352C, 0x2619E1F7, 0x2560000B, +0xD273664C, 0x362C4600, 0xCB086060, 0x2600000B, +0xD26F654C, 0x352C4500, 0xE1F76650, 0x000B2619, +0x624C2560, 0x4200D669, 0x6020326C, 0x4021C908, +0x40214021, 0x600C000B, 0xD665624C, 0x326C4200, +0xC9086020, 0x40214021, 0x000B4021, 0xD161600C, +0x341C644C, 0x000B6240, 0xD15F602C, 0x341C644C, +0x000B6240, 0x2FE6602C, 0x6E434F22, 0xE60A645C, +0x89143467, 0x0009BFEB, 0x60EC640C, 0x8B028801, +0xA002E00F, 0x44092409, 0x624C4409, 0x3263E60A, +0xBFE28905, 0x620C644C, 0xC8806023, 0xE2008B00, +0x4F266023, 0x6EF6000B, 0xD64C4F22, 0x88016062, +0xB2578B03, 0xA0030009, 0xD2490009, 0x2260E640, +0xE200D648, 0x000B4F26, 0x4F222622, 0x6062D643, +0x8B018802, 0x0009B2A0, 0xE200D642, 0x000B4F26, +0xD53E2622, 0xE100D43E, 0x2512E701, 0x2470000B, +0xE604D23B, 0x2260000B, 0xD43B4F22, 0x410BD13B, +0xD53B0009, 0x6650E1FD, 0x2619D23A, 0x2560E700, +0x000B4F26, 0x4F222270, 0xD238D537, 0xD7386152, +0x2512611D, 0xE6FF6452, 0x2542242B, 0xD22FD435, +0x420B666D, 0xD52E2762, 0x6750E1FB, 0x4F262719, +0x2570000B, 0xD4304F22, 0x410BD128, 0xD5280009, +0x6650E7F7, 0x4F262679, 0x2560000B, 0x9425D524, +0x22496250, 0x2520000B, 0xE4BFD521, 0x22496250, +0x2520000B, 0xD2254F22, 0x600D8522, 0x89112008, +0x89458801, 0x89478803, 0x89498805, 0x894F8806, +0x89558808, 0x895B8809, 0x8961880A, 0x8967880B, +0x0009A06E, 0x0009B070, 0x600CA06B, 0x0000FF7F, +0x001E2148, 0x001E1000, 0x001E1108, 0x002039BC, +0x002039BE, 0x002039DD, 0x002039A0, 0x001E103F, +0x001E105F, 0x001E102F, 0x001E1090, 0x002039C4, +0x001E100B, 0x002039C0, 0x00203AF4, 0x002018A2, +0x001E1028, 0x002039DC, 0x001D4020, 0x98760000, +0x001C1000, 0x00203B00, 0x00203B10, 0x00203994, +0x0009B04C, 0x600CA035, 0x0009B055, 0x600CA031, +0x6260D684, 0x8B2B2228, 0x0009B061, 0x600CA029, +0x6260D680, 0x8B232228, 0x0009B069, 0x600CA021, +0x6260D67C, 0x8B1B2228, 0x0009B0C7, 0x600CA019, +0x6260D678, 0x8B132228, 0x0009B0CD, 0x600CA011, +0x6260D674, 0x8B0B2228, 0x0009B125, 0x600CA009, +0x6260D670, 0x8B032228, 0x0009B13D, 0x600CA001, +0x4F26E000, 0x0009000B, 0xD26CD16B, 0xD56C8412, +0x4000C90F, 0xD76B012D, 0xE403D66B, 0xE20F611C, +0x2540E001, 0x25202712, 0x2602000B, 0xE601D262, +0x30668523, 0xE0008D05, 0xD663D260, 0xE0018122, +0x000B2602, 0xD25C0009, 0x600D8523, 0x89052008, +0x8B0A8801, 0x6060D65D, 0x2600CB01, 0xD457D65A, +0xE001E101, 0x000B2612, 0x000B8142, 0xD152E000, +0x8513E501, 0x640D4518, 0x66033453, 0xE0008D05, +0xD551D253, 0x2260E001, 0x000B2502, 0x4F220009, +0x8513D149, 0x6453650D, 0x62494419, 0x227D672E, +0x8801602C, 0x88028909, 0x88038910, 0x8806891A, +0x88078935, 0xA04C893B, 0xD5460009, 0x6652D746, +0x2762D446, 0x622C6261, 0x2421A038, 0x2228625C, +0xD4438B3F, 0x6642D540, 0x2562D440, 0x24018561, +0x6203A02C, 0x2008605C, 0x88108907, 0x88208908, +0x88308909, 0xA02C890A, 0xD23A0009, 0x6222A008, +0xA005D239, 0xD2396222, 0x6222A002, 0x6262D638, +0xD432D531, 0x66212522, 0xA00F626C, 0xD6352421, +0x6261D52D, 0x622CD42D, 0xA0072562, 0xD6322421, +0x8561D529, 0x2562D429, 0x62032401, 0x662D8515, +0x3617610D, 0x65038F01, 0xB0CB2451, 0xA0010009, +0xE000E001, 0x000B4F26, 0xD6190009, 0xD427E101, +0x65412610, 0xD118D717, 0xE20F655D, 0x2752E001, +0x000B2620, 0x2FE62102, 0xD20F4F22, 0x640C8523, +0x8B082448, 0xD511D61D, 0x2621E200, 0x940F8451, +0xA0482049, 0xDE0D8051, 0xC84060E0, 0xE2018D32, +0x89443427, 0xD216D615, 0x2641420B, 0x0009A030, +0x0000FF7F, 0x002039DD, 0x00203994, 0x002039A0, +0x001E1100, 0x001E100C, 0x002039C0, 0x001E1000, +0x001E1001, 0x002039C8, 0x002039A8, 0x002039AC, +0x002039B0, 0x002039CC, 0x002039D0, 0x002039D4, +0x002039D8, 0x00203DFC, 0x00203E06, 0x002039BA, +0x0020287E, 0x89123427, 0xD294D693, 0x2641420B, +0xCB8084E1, 0x80E1B0F5, 0xD69160E0, 0x2E00CB04, +0xC93F6060, 0xD68F2600, 0xA001E001, 0xE0002602, +0x000B4F26, 0xD68C6EF6, 0xC8806060, 0xD2868919, +0x88016021, 0xD2898B15, 0x8524E501, 0x89103056, +0xE203D187, 0x2120D487, 0xE00B6541, 0x0656655D, +0xE40FD585, 0x2140E702, 0xD77E2571, 0x000BE001, +0x000B2702, 0x2FE6E000, 0xDE804F22, 0xC88084E1, +0xD57A892C, 0x20088554, 0x61038F28, 0x8553D77C, +0x64036672, 0x8566650C, 0x3520620C, 0xD6798B1E, +0x651CD774, 0x2651644C, 0x60E02741, 0x8904C840, +0x420BD275, 0xA0030009, 0xD2680009, 0x0009420B, +0x0009B09F, 0xE201D167, 0x60E02122, 0xCB04D464, +0x60402E00, 0x2400C93F, 0x6023A001, 0x4F26E000, +0x6EF6000B, 0x2FB62FA6, 0x2FD62FC6, 0xDA622FE6, +0x66A1E240, 0x3622DC5E, 0x62638900, 0x6ED36D2C, +0x4E2136D8, 0x4E212A61, 0xDB61D460, 0xE700A00F, +0x770162B2, 0x71026123, 0x66212B12, 0x71026213, +0x61212B12, 0x651D666D, 0x356C4528, 0x627C2452, +0x8BED32E3, 0xC90360D3, 0x8B108803, 0x617367B2, +0x2B127102, 0x71026E13, 0x2B126571, 0x655D6DE1, +0x422862DD, 0x325CE107, 0xA00C2C10, 0x88022422, +0xA0038B01, 0x8801E203, 0xE2018B05, 0x66B22C20, +0x655D6561, 0xE60F2452, 0x67A12C60, 0x8B052778, +0xDD38DC44, 0xEB01EA00, 0x2DB22CA2, 0x6DF66EF6, +0x6BF66CF6, 0x6AF6000B, 0x2FE62FD6, 0xE240DD36, +0x362266D1, 0x62638900, 0x3678672C, 0x7703DE38, +0x47212D61, 0x64E2D635, 0xA00E4721, 0x6562E100, +0x62537101, 0x74012450, 0x24204219, 0x45297401, +0x74012450, 0x24504519, 0x621C7401, 0x8BEE3273, +0x66E24200, 0x420061D1, 0x2118362C, 0x2E628F06, +0xDD1CD728, 0xE501E400, 0x2D522742, 0x000B6EF6, +0x2FD66DF6, 0x4F222FE6, 0xED0AEE01, 0x64E3BC85, +0xBC8A64E3, 0x62EC7E01, 0x8BF732D7, 0xBC8DEE01, +0x64E364E3, 0x7E01BC92, 0x32D762EC, 0x4F268BF7, +0x000B6EF6, 0xD1186DF6, 0xD418920D, 0x72122122, +0x2422D617, 0xD7177204, 0x72202622, 0x2722D116, +0x000B7230, 0x137A2122, 0x002039BA, 0x0020298A, +0x001E1015, 0x002039C0, 0x001E1001, 0x00203994, +0x001E1100, 0x002039BE, 0x002039AC, 0x001E1000, +0x002039B0, 0x002039BC, 0x0020287E, 0x001E100C, +0x002039A8, 0x002039C4, 0x002039C8, 0x002039CC, +0x002039D0, 0x002039D4, 0x002039D8, 0x4F222FE6, +0xD6707FFC, 0x88016060, 0xE2018951, 0x2620BFBB, +0xD56ED16D, 0xDE6E6010, 0x64E36552, 0x7402C840, +0x8D22D16C, 0xD26C7502, 0xE601D76C, 0xE7042722, +0x76016255, 0x626C2421, 0x8FF93273, 0xD4637402, +0x6242E601, 0x640D8528, 0x67494419, 0x275D657E, +0x81E4607C, 0xE417D562, 0x67557601, 0x3243626C, +0x8FF92171, 0xA0207102, 0xD25E0009, 0xE601D75B, +0xE7042722, 0x76016255, 0x626C2421, 0x8FF93273, +0xD4527402, 0x6242E601, 0x640D8528, 0x67494419, +0x275D657E, 0x81E4607C, 0xE417D553, 0x67557601, +0x3243626C, 0x8FF92171, 0x92897102, 0xD2462E21, +0x5E23D74E, 0x64F22FE2, 0x604365F2, 0x2700C980, +0xC9606043, 0x80716103, 0xC9036043, 0x80724519, +0x65F2605C, 0x817266F2, 0x46194629, 0x606C4529, +0x4018645C, 0x8173304C, 0x21185E23, 0x64F22FE2, +0x6E4C62F2, 0x602C4219, 0x66F262F2, 0x46294018, +0x461930EC, 0x42298174, 0x652C606C, 0x305C4018, +0x81758F07, 0x0009BC96, 0x2228620C, 0xA00A8908, +0x60130009, 0x8B038840, 0x0009B009, 0x0009A003, +0xE202D62F, 0x7F042622, 0x000B4F26, 0x4F226EF6, +0x8552D52A, 0x8830600D, 0x88318903, 0xA0348923, +0x85550009, 0xD428D727, 0x85532701, 0x610DD627, +0x24124118, 0x460BD426, 0xD7230009, 0xD226D425, +0x6572420B, 0xE230D120, 0x42286712, 0x2729E620, +0x37604628, 0xD6218B03, 0xA016E200, 0xD61F2622, +0xA012E202, 0xD1182622, 0x6212E530, 0xE6204528, +0x46282259, 0x89083260, 0xD41AD119, 0xE601D513, +0x2160450B, 0x472BD718, 0x4F264F26, 0x0009000B, +0x0000060A, 0x002039DC, 0x001E1000, 0x002039C8, +0x00203DFC, 0x00203E08, 0x00203DA0, 0x002039B0, +0x00203DD0, 0x00203DCE, 0x00203DA2, 0x00203994, +0x002039C0, 0x002039AC, 0x002039A8, 0x002018A2, +0x00203B1C, 0x00203B20, 0x002018EE, 0x002039C4, +0x001E100B, 0x00203B34, 0x00114004, 0x4F222FE6, +0xDE967FFC, 0x200884E9, 0x2F008D06, 0xD695D494, +0x0009460B, 0x64F0B19A, 0x6620D293, 0x89022668, +0xC9BF60E0, 0x7F042E00, 0x000B4F26, 0x000B6EF6, +0x2FE60009, 0xDE8D4F22, 0x60E0D68D, 0xCBC0D48D, +0x62602E00, 0xC803602C, 0x40218904, 0x70014021, +0x6603A002, 0x66034009, 0xD687616D, 0xE500A004, +0x75016262, 0x74042422, 0x3213625D, 0xD2838BF8, +0x0009420B, 0xC9BF84E2, 0x4F2680E2, 0x6EF6000B, +0x2FE62FD6, 0x7FFC4F22, 0x6260D67D, 0x89442228, +0xD572E100, 0x60502610, 0xCB40D47A, 0x2500440B, +0x8D052008, 0x62E06E03, 0x7104612C, 0x2F11A006, +0xD475D66D, 0xDD756760, 0x657C4D0B, 0xE23C6D1D, +0x8B033D27, 0xD267D472, 0x0009420B, 0x4D214D21, +0xA005D770, 0x66E6E400, 0x357C4508, 0x74012562, +0x35D3654D, 0xD76C8BF7, 0x6172E003, 0x81114018, +0x6E7260F1, 0x81E2700C, 0xD4686172, 0xDD688113, +0x4D0BDE68, 0xE2016572, 0xD4672E22, 0x420BD255, +0xD6560009, 0xC93F6060, 0x7F042600, 0x6EF64F26, +0x6DF6000B, 0x2FC62FB6, 0x2FE62FD6, 0xD25F4F22, +0x6B436E73, 0x420B6C53, 0x20086D63, 0x64038D1C, +0xE50ED149, 0x32526210, 0x60C38916, 0x804124B0, +0x814160D3, 0xA007E500, 0x655D61BC, 0x00EC6053, +0x364C6653, 0x80647501, 0x3213625D, 0xD63B8BF5, +0xC9BF6060, 0x2600A008, 0xD23AD44D, 0x6EF64F26, +0x6CF66DF6, 0x6BF6422B, 0x6EF64F26, 0x6CF66DF6, +0x6BF6000B, 0x7FC44F22, 0x720262F3, 0x22512F41, +0x45297202, 0x60632251, 0xE5C4E682, 0x67F38121, +0x655C666C, 0xE408BFB6, 0x4F267F3C, 0x0009000B, +0x2F962F86, 0x2FB62FA6, 0x2FD62FC6, 0x4F222FE6, +0xE1007FC4, 0x6513ECFF, 0x6B136CCD, 0xDE36D735, +0xEDFF64F3, 0xD835EA04, 0x6053655C, 0x027D4000, +0x32C0622D, 0x66038D0D, 0x09ED6063, 0x2491027D, +0x24217402, 0x698202ED, 0x3928622D, 0x74022892, +0x75017104, 0x6063625C, 0x07D532A2, 0x0EB58FE4, +0x2448641C, 0xE6808905, 0x67F3E5C5, 0xBF79666C, +0x7F3C655C, 0x6EF64F26, 0x6CF66DF6, 0x6AF66BF6, +0x000B69F6, 0xD11E68F6, 0x6012D21E, 0xCB20E405, +0x2102E500, 0x000B2242, 0x00002252, 0x001E1017, +0x00203B38, 0x002018A2, 0x00203906, 0x001E1015, +0x001E10BF, 0x00117800, 0x001E10FC, 0x00200610, +0x0020390C, 0x00202AE2, 0x00203B3C, 0x002018EE, +0x00203B58, 0x0011788C, 0x00203908, 0x002034EC, +0x00201530, 0x001E2130, 0x00203B60, 0x00202AA4, +0x00203B64, 0x0020396C, 0x00203974, 0x00203D9C, +0x001C3500, 0x001D4004, 0xD564D163, 0xE400D764, +0x2142E20F, 0x17411154, 0xD5622722, 0x9669D762, +0x15412572, 0x96661562, 0xE6011565, 0xD55F1165, +0x666CE6F8, 0x25422542, 0x25422542, 0x25422542, +0x25622542, 0x7601E727, 0x67632572, 0x25627797, +0xE7042572, 0x2572E248, 0xE2192522, 0xE2702522, +0x25422542, 0x25422542, 0x25222542, 0x2522E20C, +0x25422542, 0x25422542, 0x25422542, 0x25422542, +0x000B154A, 0xE2081145, 0x0009422B, 0x2FE62FD6, +0x7FFC4F22, 0xC8206043, 0x6E438D02, 0x0009BE67, +0xC81060E3, 0xBE648901, 0x60E30009, 0x8901C840, +0x0009BE86, 0xC80160E3, 0xDD3D8938, 0xC80260D0, +0x2F008D03, 0x460BD63B, 0x60F00009, 0x8902C804, +0x460BD639, 0x62F00009, 0xC8806023, 0x60D08902, +0x2D00C97F, 0xC8016023, 0xD6348906, 0x0009460B, +0x0009A007, 0x51630601, 0x8902C808, 0x460BD630, +0x60F00009, 0x8902C810, 0x420BD22E, 0xD52E0009, +0x88026052, 0xD22D8B03, 0xA005E604, 0x88012260, +0xD22A8B02, 0x2260E601, 0x2522E200, 0xC88060E3, +0xD227892D, 0x60E36E20, 0x8902C880, 0x420BD225, +0x60E30009, 0x8902C840, 0x420BD223, 0x60E30009, +0x8902C802, 0x420BD221, 0x60E30009, 0x890DC804, +0xDD20D11F, 0x0009410B, 0x0009BF0D, 0x0009BF4C, +0xD51ED41D, 0x2470E708, 0x25D2BF85, 0xC80860E3, +0xD21B8905, 0x4F267F04, 0x422B6EF6, 0x7F046DF6, +0x6EF64F26, 0x6DF6000B, 0x001C581C, 0xA000A000, +0x001D0100, 0x001D4000, 0x00040021, 0x001C589C, +0x001E1021, 0x00201A88, 0x00201AAA, 0x0020210C, +0x00201AC2, 0x00201AD0, 0x002039C0, 0x001E100B, +0x001E1028, 0x00201B3C, 0x00201B48, 0x00201AD8, +0x00201AF6, 0x12345678, 0x001E1000, 0x0010F100, +0x00201B24, 0x644CD6A7, 0x000B346C, 0xD6A62450, +0x346C644C, 0x2450000B, 0x644CD6A4, 0x000B346C, +0x625C2450, 0x4208616D, 0x42084119, 0x42006019, +0x670E614C, 0xD49E321C, 0x4200207D, 0x324CC90F, +0x2200000B, 0x4208625C, 0x42004208, 0x324C644C, +0x4200D498, 0x000B324C, 0x2FE62260, 0x614C4F12, +0x4100D493, 0x6710314C, 0xE29F666D, 0x27294619, +0x6E536269, 0x672E6573, 0x4221227D, 0x42214221, +0x7601662C, 0xE4014608, 0x34E84608, 0x644C4600, +0x071A0467, 0x2150257B, 0x000B4F16, 0x4F226EF6, +0xD2857FE8, 0x88016021, 0xD2848B7B, 0x26686621, +0xD2838B77, 0x26686621, 0xE50F8B73, 0xE401BFA2, +0xBFA4E501, 0xE586E400, 0xE400655C, 0x2F50BFA4, +0xBFA1E401, 0xE602E506, 0x60634618, 0x81F2E401, +0x6543BF9F, 0xE40185F2, 0xBFAB6543, 0x85F26603, +0x6543E401, 0x6603BFB1, 0xE40265F0, 0x6053756C, +0x80F8BF80, 0xBF82E402, 0x84F8E512, 0x7090E402, +0x6503BF82, 0x4618E602, 0x81F66063, 0xBF80E402, +0x85F6E500, 0x6603E402, 0xE500BF8C, 0xE40285F6, +0xBF926603, 0xE5FEE500, 0xE010655C, 0xBF61E403, +0xE5130F54, 0xE40EBF63, 0x05FCE010, 0xBF63E40E, +0xE5007585, 0xBF64E403, 0xE500E640, 0xBF71E403, +0xE500E640, 0xBF78E403, 0xE5FFE640, 0xE014655C, +0xBF47E404, 0xE40F0F54, 0xE504BF49, 0x05FCE014, +0xBF49E40F, 0xE5017584, 0xBF4AE640, 0xE501E404, +0xBF57E640, 0xE501E404, 0xE404E640, 0xAF5C7F18, +0x7F184F26, 0x000B4F26, 0x4F220009, 0xD2427FF0, +0x88016021, 0xD2418B71, 0x26686621, 0xD2408B6D, +0x26686621, 0xE50F8B69, 0xE401BF1C, 0xBF1EE501, +0xE586E400, 0xE400655C, 0x2F50BF1E, 0xBF1BE401, +0xE401E506, 0xBF1C6543, 0xE401E640, 0xBF296543, +0xE401E640, 0xBF306543, 0x65F0E640, 0x756CE402, +0xBEFF6053, 0xE40280F4, 0xE512BF01, 0xE40284F4, +0xBF017090, 0xE6406503, 0xBF02E402, 0xE640E500, +0xBF0FE402, 0xE640E500, 0xBF16E402, 0xE5FEE500, +0x6053655C, 0xBEE5E403, 0xE51380F8, 0xE40EBEE7, +0xE40E84F8, 0xBEE77085, 0xE5006503, 0xBEE8E640, +0xE500E403, 0xBEF5E640, 0xE500E403, 0xBEFCE640, +0xE5FFE403, 0x6053655C, 0xBECBE404, 0xE40F80FC, +0xE504BECD, 0xE40F84FC, 0xBECD7083, 0xE5016503, +0xBECEE640, 0xE501E404, 0xBEDBE640, 0xE501E404, +0xE404E640, 0xAEE07F10, 0x7F104F26, 0x000B4F26, +0x00000009, 0x001E102F, 0x001E1080, 0x001E1090, +0x001E103F, 0x001E103E, 0x002039BA, 0x002039BC, +0x002039BE, 0xD21DD11C, 0x66206010, 0x676C7001, +0x3700C90F, 0xE5008D13, 0x67106210, 0x7701622C, +0x64232170, 0xD6166010, 0x44084408, 0x3428C90F, +0x62602100, 0x7201D513, 0x44082620, 0x000B354C, +0xD10F6053, 0x25586510, 0xE6008D13, 0xD60DD40B, +0x655C6540, 0x47086753, 0x37584708, 0x47086540, +0x24507501, 0x367C6040, 0x2400C90F, 0x72FF6210, +0x000B2120, 0x00006063, 0x00203905, 0x00203904, +0x00203906, 0x0020352C, 0x7FFC4F22, 0xE680D19F, +0x666C6212, 0xD29E2F22, 0x67F36563, 0x420B7542, +0x7F04E404, 0x000B4F26, 0xE6800009, 0xD298666C, +0xE7006563, 0x422B7540, 0xE6806473, 0xD294666C, +0xE7006563, 0x422B7543, 0x2F866473, 0x2FA62F96, +0x2FC62FB6, 0x2FE62FD6, 0x7FCC4F22, 0xDC8ED28D, +0x72011F21, 0xDB8D1F22, 0xD18EDE8D, 0x66125211, +0x8B013620, 0x0009A0E5, 0xC9036061, 0x8B018801, +0x0009A0DF, 0xD288D487, 0xED84420B, 0x2F025503, +0x30D0845C, 0xA0B88901, 0xD1840009, 0x626C6610, +0x88016023, 0xD1828B68, 0x62101FC3, 0x895B2228, +0xE003D480, 0x40186742, 0x68421772, 0xD57EE900, +0x81816DB3, 0x7D042190, 0x67D26AB2, 0x64E26852, +0x1F491F57, 0x740464E3, 0x1FA46542, 0x65431F5A, +0x625275F8, 0x1F761FD5, 0x6D531F2B, 0xDA74D773, +0x7D94D274, 0x68D21F88, 0x6AA26972, 0xD1726022, +0x2202CB20, 0xE1401F1C, 0x7601E600, 0x3213626D, +0x56F48BFB, 0x52F651F5, 0x21222B62, 0x52F851F7, +0x212256F9, 0x2E6251FA, 0x51FB2412, 0x2D822512, +0xD9662792, 0x29A2DD5F, 0x6AD2D965, 0xD9646892, +0x68D21A84, 0x6081DA63, 0x2801CB01, 0xD86266D2, +0x2A622962, 0xED015AFC, 0x2AD2480B, 0x2AD24D18, +0x62D2DD5E, 0x2D227201, 0xD15056F3, 0xE2026062, +0x2602CB01, 0x2120A03D, 0x8B3A2228, 0xE401DD58, +0x2140E600, 0xE01C2D62, 0xC801005C, 0xD4558B0A, +0xE600D755, 0xED7D2472, 0x626C7601, 0x8BFB32D3, +0x24D2DD52, 0xE2FE68C2, 0x2C822829, 0x095CE01E, +0xE01F5DF1, 0x0A5C2D90, 0x751051F2, 0xED0621A0, +0xD74BE600, 0x8456D44B, 0x27007601, 0x696C6854, +0x248039D3, 0x8FF67401, 0xDA477701, 0x2A10E194, +0xE2007A01, 0x7A0F2A20, 0xD130E805, 0x66102A80, +0x6023626C, 0x89088801, 0xD240D42A, 0x420B65F2, +0xD131ED01, 0xAF304D18, 0x65F221D2, 0x8553D43C, +0x620D6642, 0x89073262, 0xD13BD43A, 0x0009410B, +0xE601D73A, 0x2762AF1A, 0xD134D41E, 0x410B65F2, +0xD125ED01, 0xD637D436, 0x460B4D18, 0xAF0D21D2, +0x7F340009, 0x6EF64F26, 0x6CF66DF6, 0x6AF66BF6, +0x000B69F6, 0x4F2268F6, 0x85467FF4, 0x2F01E681, +0x666C8547, 0x854881F1, 0x81F2D209, 0x67F38542, +0x854381F3, 0x81F4E40C, 0x65636053, 0x420B81F5, +0x7F0C7540, 0x000B4F26, 0x00000009, 0x001C3D9C, +0x00202454, 0x0011779A, 0x001C36F8, 0x001C3B9C, +0x001C3704, 0x00203524, 0x002014A0, 0x00203915, +0x00203914, 0x00203910, 0x001C3D98, 0x001C3BB4, +0x001C5960, 0x001C3500, 0x001C3D30, 0x001C8960, +0x002034FC, 0x001C3D00, 0x0020160C, 0x00117730, +0x00203918, 0x001C582C, 0x2000A000, 0x0000A000, +0x0011778C, 0x00117792, 0x00117788, 0x002014CC, +0x002038EC, 0x002034EC, 0x00201530, 0x001E2130, +0x00203D7C, 0x002018A2, 0x2F962F86, 0x2FB62FA6, +0x2FD62FC6, 0x4F222FE6, 0xD19B7FEC, 0x2F12E000, +0x6103D49A, 0x1F4281F2, 0xDD9ADA99, 0xD69A6813, +0xE0014808, 0x460BDE99, 0x38EC4800, 0x65A21F03, +0x352052A1, 0xA23E8B01, 0x60510009, 0x8801C903, +0xA2388B01, 0x52530009, 0x32E0DE91, 0xD9918B10, +0x64A3490B, 0x4B0BDB90, 0xDE906403, 0xD791D690, +0xEC01D591, 0x2E02E100, 0x271026C0, 0x2502AFDF, +0xC8018551, 0xA1578B01, 0x62510009, 0x4200622D, +0x5E53366A, 0x85E2226D, 0xC903642C, 0x85E36603, +0x6053650D, 0x40214021, 0x4500C93F, 0x322A6703, +0x6053252D, 0xC901D17F, 0x60106C03, 0x8801D97F, +0xDB7F8B05, 0x2120E200, 0xCB0160B2, 0xD17D2B02, +0x88016011, 0x65A28B0A, 0x8D042448, 0x9B9E6251, +0xA00322B9, 0x919B2521, 0x2521221B, 0x37B3EB10, +0x2448895E, 0xD4738B07, 0x22286241, 0x60638903, +0xA05781F8, 0xD5706473, 0x46084608, 0x85E26273, +0x46006B50, 0x362C4200, 0x2BB8C910, 0x8F1F6463, +0x26686603, 0xD2698911, 0x062D6043, 0x4119616D, +0x6B0E6019, 0x81F820BD, 0x880160C3, 0x646C8F2C, +0x880F6073, 0xA0278B1B, 0xD2610009, 0x052D6043, +0x4119615D, 0x670E6019, 0x645C207D, 0x81F8A01C, +0x890F2668, 0x6043D25B, 0x6B5D052D, 0x60B94B19, +0x201D610E, 0x60C381F8, 0x8F0D8801, 0x6473645C, +0xEC00A00A, 0x6043D254, 0x625D052D, 0x60294219, +0x207D670E, 0x81F8645C, 0x880285F8, 0x85E1890A, +0x8D07C820, 0xE6DC6203, 0x60232269, 0x81E1A002, +0x644CE4FF, 0x6210D149, 0x89012228, 0x644CE4FF, +0x654DEBFF, 0x35B06BBC, 0xDB368B2B, 0x64A34B0B, +0x410BD135, 0x54036403, 0x85446E03, 0xC948DB40, +0xDC408808, 0xBEAE8B01, 0x64B3E502, 0x65E34C0B, +0xDB3DEC01, 0xD13D2DC2, 0x621260B2, 0x72017001, +0x21228805, 0x2B028F08, 0x666CE680, 0x6563D238, +0x7549E700, 0x6473420B, 0xA030D436, 0x7FFF0009, +0x85E28000, 0x20B9EBFC, 0x610381E2, 0x942A85E3, +0x62032049, 0x450885F8, 0x81E2201B, 0xC90160C3, +0x40084018, 0x40084008, 0x4000225B, 0x6023220B, +0x85E481E3, 0x4118E108, 0x81E4201B, 0xE40262A2, +0x20B98521, 0x67A28121, 0xCB016071, 0x85F82701, +0x89033042, 0xECE785E2, 0x81E220C9, 0x490BD41E, +0xA03B0009, 0x7E030009, 0x001C3D30, 0x00203D88, +0x002034FC, 0x001E212C, 0x002033E0, 0x001C3D00, +0x00117780, 0x002014A0, 0x0020166C, 0x0011770C, +0x00203914, 0x00203915, 0x00203910, 0x002018A2, +0x001C36F8, 0x00203988, 0x00203D98, 0x00203B7C, +0x00203BFC, 0x00203C7C, 0x00203CFC, 0x00203900, +0x002034F4, 0x002014CC, 0x0020398C, 0x00203990, +0x00202454, 0x00203D80, 0x00203D84, 0x602262F2, +0x40094019, 0xC90F4009, 0x8B0B880A, 0x60E2DE8C, +0x40094019, 0xC90F4009, 0x8B038808, 0xCB0160A2, +0x2802A006, 0x65E2DE87, 0x2E527501, 0x286266A2, +0x52F366F2, 0x2622AE83, 0xD2838551, 0xDE83C802, +0xA0958B01, 0x420B0009, 0x4E0B64A3, 0x5E036403, +0x85E46503, 0x4918E908, 0xD77D209B, 0xE04C81E4, +0xDC7C0B7E, 0x7B01D97C, 0x61C207B6, 0x71016690, +0x8D062668, 0xD4792C12, 0x420BD279, 0xA070EB01, +0x62512DB2, 0x4B18EB0F, 0x22B9E102, 0x32104118, +0x85518B0F, 0x2029E2FC, 0x60518151, 0xCB0172E0, +0x85E12501, 0x202994A3, 0x85E481E1, 0xA0522049, +0x675181E4, 0x4719677D, 0x667E6779, 0x7701276D, +0x6903607C, 0x88014918, 0x25918F3E, 0x6B12D161, +0x21B27B01, 0x660D85E3, 0x40216063, 0xC93F4021, +0x6C034600, 0x262D322A, 0xC8016063, 0xDB5ED15D, +0x967D8901, 0xE6002C6B, 0x666C67CD, 0x40006063, +0x622D021D, 0x8D0E3270, 0x60436403, 0xE9FF021D, +0x8B013290, 0x01C5A007, 0x626C7601, 0x3292E904, +0x646C8BEB, 0x60434400, 0xD15004BD, 0x0B457401, +0x669D6911, 0x89073670, 0x602D6211, 0x890388FF, +0xE201DB4B, 0x2B2021C1, 0xECFC8551, 0x815120C9, +0xCB016051, 0xDC472501, 0x64A34C0B, 0x51F366F2, +0x85EF2612, 0x54F2D244, 0x650D420B, 0x0009ADE7, +0xE500DC42, 0x420B2C52, 0x4E0B64A3, 0x54036403, +0x85446E03, 0x6703E908, 0x65034918, 0x27998541, +0xDB323790, 0x8F0BD932, 0x6013610D, 0x8B07C820, +0xC9486053, 0x8B038808, 0xE501BD4D, 0x0009A005, +0x2128D233, 0xBD468901, 0x64B3E500, 0x490B65E3, +0xADBCEC01, 0x85F22DC2, 0x7001EE04, 0x31E7610D, +0x8D0281F2, 0xADA97A08, 0x7F140009, 0x6EF64F26, +0x6CF66DF6, 0x6AF66BF6, 0x000B69F6, 0xF7FF68F6, +0x2FE68000, 0xD2234F22, 0x60E36E22, 0x8D02C840, +0xBBF922E2, 0xE2400009, 0x2E284218, 0xBC048901, +0x60E30009, 0x8905C810, 0xD21CD41B, 0x0009420B, +0x0009BC03, 0xC80560E3, 0xBD6D8901, 0x60E30009, +0x8902C802, 0xAC004F26, 0x4F266EF6, 0x6EF6000B, +0x001C3D3C, 0x00117760, 0x002014A0, 0x0020166C, +0x0020348C, 0x00203D9C, 0x00203900, 0x002034F4, +0x002014CC, 0x0020396C, 0x00203974, 0x00203968, +0x0020396A, 0x00201530, 0x002018EE, 0x0020398C, +0x00008000, 0x001C3510, 0x00203D90, 0x002018A2, +0x080A0C0E, 0x00020406, 0x1A1C1E20, 0x12141618, +0x2E303234, 0x26282A2C, 0x3A3C3E40, 0x6C625648, +0x41112F26, 0xE2208F18, 0x890B3123, 0x321CD204, +0xD1026220, 0x412B312C, 0x00090009, 0x0020340A, +0x002033C0, 0x000BE000, 0x400062F6, 0x40004000, +0x40004000, 0x40004000, 0x62F6000B, 0x40004000, +0x40004000, 0x40004000, 0x40184000, 0x62F6000B, +0x40004000, 0x40004000, 0x40004000, 0x40284000, +0x62F6000B, 0x40004000, 0x40184000, 0x000B4028, +0xC90F62F6, 0x40054005, 0x40054005, 0x62F6000B, +0x4005C907, 0x40054005, 0x62F6000B, 0x4005C903, +0x000B4005, 0xC90162F6, 0x000B4005, 0x000062F6, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x544F0D0A, +0x46205355, 0x00003A57, 0x206C754A, 0x32203120, +0x20383030, 0x323A3132, 0x32313A37, 0x00000000, +0x00000D0A, 0x00000043, 0x42707372, 0x3D206675, +0x554E203D, 0x202C4C4C, 0x6E49677A, 0x4E497274, +0x6D754E51, 0x0000003D, 0x61766E49, 0x2064696C, +0x72657375, 0x20726F20, 0x2079656B, 0x00214449, +0x52504545, 0x57204D4F, 0x65746972, 0x6461202C, +0x003D7264, 0x6C617620, 0x0000003D, 0x00000A0D, +0x435F4D5A, 0x465F444D, 0x4C445F57, 0x494E495F, +0x00000054, 0x6E6B6E55, 0x206E776F, 0x6D6D6F63, +0x3D646E61, 0x00000000, 0x203A3051, 0x00000020, +0x203A3151, 0x00000020, 0x203A3251, 0x00000020, +0x203A3351, 0x00000020, 0x203A3451, 0x00000020, +0x2B434741, 0x73696F4E, 0x61432065, 0x7262696C, +0x6F697461, 0x6166206E, 0x6F206C69, 0x6974206E, +0x0D0A656D, 0x00000000, 0x00000072, 0x00205220, +0x00000D0A, 0x62735576, 0x7473725F, 0x00000A0D, +0x62735576, 0x7375735F, 0x646E6570, 0x00000A0D, +0x62735576, 0x7365725F, 0x000A0D6D, 0x00000044, +0x44387570, 0x72637365, 0x6F747069, 0x3D584572, +0x00000000, 0x00000047, 0x00000042, 0x72746E49, +0x6D652051, 0x2C797470, 0x49677A20, 0x4972746E, +0x754E514E, 0x00003D6D, 0x654C7245, 0x0000006E, +0x00000049, 0x20746F4E, 0x756F6E65, 0x49206867, +0x4220514E, 0x0A0D6675, 0x00000000, 0x000000FF, +0x00020001, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x010E010D, +0x00020003, 0x01090108, 0x0002010A, 0x02000003, +0x02020201, 0x02040203, 0x02060205, 0x02020200, +0x02040203, 0x020C020B, 0x020E020D, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x000000FF, +0x00020001, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x010E010D, +0x00020003, 0x01090108, 0x0002010A, 0x00030003, +0x02020201, 0x02040203, 0x02060205, 0x02020200, +0x02040203, 0x020C020B, 0x020E020D, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x010E010D, +0x00FF010F, 0x01090108, 0x010B010A, 0x0200010F, +0x02020201, 0x02040203, 0x02060205, 0x02020200, +0x02040203, 0x020C020B, 0x020E020D, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x010E010D, +0x00FF010F, 0x01090108, 0x010B010A, 0x010F010F, +0x02020201, 0x02040203, 0x02060205, 0x02020200, +0x02040203, 0x020C020B, 0x020E020D, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00205220, +0x00000046, 0x00000059, 0x73204142, 0x003D7165, +0x49544120, 0x0000204D, 0x00000000, 0x00000000, +0x002E0209, 0x80000101, 0x000409FA, 0x00FF0400, +0x05070000, 0x02000201, 0x82050700, 0x00020002, +0x03830507, 0x07010040, 0x40030405, 0x02090100, +0x0101002E, 0x09FA8000, 0x04000004, 0x000000FF, +0x02010507, 0x07000040, 0x40028205, 0x05070000, +0x00400383, 0x04050701, 0x00004002, 0x00000000, +0x00000000, 0x07090000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, }; + +const u32_t zcFwImageSize=15928; --- linux-2.6.28.orig/drivers/staging/otus/hal/hpfwu_OTUS_RC.c +++ linux-2.6.28/drivers/staging/otus/hal/hpfwu_OTUS_RC.c @@ -0,0 +1,715 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "cprecomp.h" + +const u32_t zcFwImage[] = { +0x0009000B, 0x4F222FE6, 0xDE287FFC, 0xE114D728, +0x1E13D428, 0x1E4C470B, 0x0009B018, 0xA0039543, +0x3652E600, 0x76018D04, 0xC84060E2, 0x2F028DF9, +0xDE22D421, 0x00094E0B, 0x4E0BD421, 0xD4210009, +0x00094E0B, 0x4F267F04, 0x6EF6A022, 0xD11E4F22, +0x0009410B, 0x440BD41D, 0xD51D0009, 0x0009450B, +0xE1FFD71C, 0xD21C611D, 0x50292712, 0xCB01E1FF, +0xD61BD41A, 0x22121209, 0xE5011211, 0x2452E200, +0xD5182622, 0x970FD618, 0x4F262572, 0x2620000B, +0xDD17DC16, 0x4C0BDE17, 0x4D0B0009, 0x4E0B0009, +0xAFF80009, 0x27100009, 0x00000640, 0x001C001C, +0x002008EA, 0x0000B38E, 0x002028DC, 0x00200DA6, +0x002028E8, 0x00202900, 0x00200C6C, 0x00200EA2, +0x00200940, 0x001C3510, 0x001C3624, 0x001E212C, +0x00202894, 0x0020288C, 0x002027F0, 0x00200B68, +0x00201F74, 0x00201734, 0x2FD62FC6, 0x4F222FE6, +0xDEA17FA4, 0x61E0E01C, 0x7D016DE3, 0x61D00F14, +0xD59FD49E, 0x450BE020, 0xE0200F14, 0xE78004FC, +0x604C66E2, 0x7D7F677C, 0x1F693070, 0x2D628F17, +0x01FCE01C, 0x641CE500, 0xD797DE96, 0x3243625D, +0xA21A8B01, 0x655D0009, 0x31EC6153, 0xE0286C10, +0x6D530FC4, 0x3D7C62CE, 0xAFEF2D20, 0x20087501, +0xE01C8B15, 0xE50001FC, 0xD78BDE8A, 0x641CA00A, +0x6C53655D, 0x66C23CEC, 0x66626253, 0x2262327C, +0x1F697504, 0x3243625D, 0xA1F68BF2, 0x88012D10, +0xE01C8B16, 0xE40001FC, 0x671C2D40, 0x624DDE7D, +0x8B013273, 0x0009A1E9, 0x62E3644D, 0x72046D43, +0x3DEC6143, 0x65D2312C, 0x74086C12, 0x25C2AFEF, +0x8B188804, 0x01FCE01C, 0x2D40E400, 0xDE71671C, +0x3273624D, 0xA1D08B01, 0x644D0009, 0x62E36D43, +0x65D23DEC, 0x61437204, 0x6612312C, 0x74086C52, +0xAFED2C69, 0x880525C2, 0xE01C8B18, 0xE40001FC, +0x671C2D40, 0x624DDE63, 0x8B013273, 0x0009A1B5, +0x6C43644D, 0x3CEC62E3, 0x720465C2, 0x3D2C6D43, +0x615266D2, 0x216B7408, 0x2512AFED, 0x8B138830, +0xE200DE58, 0x64E22D20, 0x8B042448, 0x420BD257, +0xA19A0009, 0x55E10009, 0x57E356E2, 0xDD545CE4, +0x2FC64D0B, 0x7F04A191, 0x89018828, 0x0009A0EA, +0xE143DE4C, 0x622D62E1, 0x8F033217, 0x56FB1FEB, +0x2621E240, 0x8B013217, 0x0009A0D5, 0xE1015EFB, +0x301685E1, 0xA0CE8B01, 0xE4010009, 0x2D4055FB, +0x6451B179, 0xE14357FB, 0xE0546271, 0x3517652D, +0x0F568D41, 0x3563E640, 0xE6008B05, 0x0F65E034, +0xA00FE11A, 0x615372C0, 0x41214121, 0x41214121, +0x45214121, 0x45214521, 0xC9036053, 0xE0346603, +0x71180F65, 0x2209E007, 0x641DE030, 0x0F2565F3, +0x1F4EB1F1, 0x04FDE034, 0x674DE030, 0x47080CFD, +0x607361CD, 0x4108D22B, 0xE00F0CFE, 0x1F1F420B, +0x2CD96D07, 0x5EFB6073, 0x85E20FC6, 0x420B51FF, +0x2C0B600D, 0x54FE6073, 0xB1BB0FC6, 0xE05465F3, +0x652D62E1, 0xE6400F56, 0x89623563, 0xE050E100, +0x60230F15, 0x4008C903, 0x6D034000, 0xE0406103, +0xE0440FD6, 0xD217EEFF, 0x6EEC0FF6, 0x0F26E058, +0x60E3420B, 0x42216253, 0x42214221, 0x66234221, +0x326C4200, 0x45214200, 0xE0486707, 0x0F764521, +0xC9036053, 0x40085CFB, 0x7C0630FC, 0x6E036D2D, +0x1FD51FC6, 0x1F04A02E, 0x00117D00, 0x00202904, +0x00200DA6, 0x00117D04, 0x00117D84, 0x00200700, +0x0020074C, 0x00201FD4, 0x0FD6E04C, 0x05FEE044, +0x64D3B189, 0x64E2E048, 0xE04006FE, 0x2E422469, +0x01FE67C4, 0x667CE058, 0x420B02FE, 0x240B6063, +0x05FEE044, 0xB15D2E42, 0xE05064D3, 0x7D0101FD, +0x0F157101, 0x02FDE050, 0x3262E606, 0x56FB8BDC, +0x55FB6261, 0x85514200, 0x302C750C, 0x6103701B, +0x64F3E600, 0xE704A004, 0x76016256, 0x74042422, +0x3273626D, 0x65F38BF8, 0x641DB13C, 0xB0D256FB, +0xA0AA6461, 0xD4880009, 0xE201D588, 0x2D20450B, +0x0009A0A3, 0x8B078829, 0xE200DE85, 0x66E22D20, +0x646DB0A1, 0x0009A099, 0x622CE281, 0x8B3D3020, +0xD680E738, 0xE0442D70, 0xE0480C6E, 0x6E621DC1, +0x51611DE2, 0x54621D13, 0x55651D44, 0x57631D55, +0x5C661D76, 0x0E6E1DC7, 0x1DE8E040, 0xE050016E, +0x54641D19, 0x056E1D4A, 0x1D5BE04C, 0xE054076E, +0x0C6E1D7C, 0x1DCDE058, 0xE044026E, 0xED001D2E, +0xE04806D6, 0x16D126D2, 0x16D516D2, 0x16D616D3, +0xE04006D6, 0xE05006D6, 0x06D616D4, 0x06D6E04C, +0x06D6E054, 0x06D6E058, 0x1F29A057, 0x622CE282, +0x89313020, 0x05FCE020, 0x625CE683, 0x3260666C, +0xD65D8B07, 0x2650E500, 0x52617680, 0xA044D65B, +0xE6902622, 0x3260666C, 0xD2578B16, 0xE500D658, +0x60622250, 0xCB20D257, 0xE6052602, 0xD6562262, +0x2252460B, 0x420BD255, 0xD2550009, 0x2262E601, +0x4618D254, 0x2262A029, 0xD254D453, 0xD4546542, +0x0009420B, 0x0009A021, 0xE524D647, 0xD5452650, +0x16215257, 0x16225258, 0x16235259, 0x1624525A, +0x1625525B, 0x1626525C, 0x1627525D, 0x1628525E, +0x1F29525F, 0xE2001629, 0x15281527, 0x152A1529, +0x152C152B, 0x152E152D, 0x7F5C152F, 0x6EF64F26, +0x000B6DF6, 0x4F226CF6, 0xE240614D, 0x89173123, +0x3127E21F, 0xD43B8908, 0xE001D53B, 0x6642450B, +0x26796707, 0x2462A00C, 0x3127E23F, 0xD7358908, +0x71E0D635, 0x460BE001, 0x62075571, 0x17512529, +0x000B4F26, 0x4F220009, 0xE240614D, 0x89153123, +0x3127E21F, 0xD42B8907, 0x6642D22B, 0xE001420B, +0xA00B260B, 0xE23F2462, 0x89073127, 0xD626D725, +0x71E05571, 0xE001460B, 0x1751250B, 0x000B4F26, +0xE6400009, 0x46284618, 0x6252D520, 0x89FC2268, +0x0009000B, 0x4618E680, 0xD51C4628, 0x22686252, +0x000B89FC, 0xA0010009, 0x7201E200, 0x8BFC3242, +0x0009000B, 0x4618E680, 0xD5154628, 0x22686252, +0x000B8BFC, 0x00000009, 0x00202908, 0x00200DA6, +0x00117D04, 0x002027F8, 0x00117D80, 0x0020288C, +0x001C3500, 0x001D4004, 0x00200EA2, 0x00200940, +0x001E212C, 0x001C3D28, 0x00117D00, 0x00200E06, +0x00202920, 0x001C3704, 0x00201FD4, 0x001C373C, +0x001C3700, 0x4F222FE6, 0x6E537FFC, 0x2F42BFCA, +0xD61561E2, 0x1615E280, 0x421854E1, 0x55E21646, +0x16574228, 0x6EF257E3, 0x2E2B1678, 0x7F0426E2, +0xAFA74F26, 0x2FC66EF6, 0x2FE62FD6, 0xDD0A4F22, +0xBFAF6C53, 0xBF946E43, 0xBFAB2DE2, 0x51D50009, +0x54D62C12, 0x55D71C41, 0x56D81C52, 0x4F261C63, +0x6DF66EF6, 0x6CF6000B, 0x001C370C, 0x0009A0C0, +0xD17B4F22, 0xD47B92B6, 0x2122B00D, 0x97B2E605, +0xB02295B2, 0xB0366463, 0xB0360009, 0xB0390009, +0xA0680009, 0x4F124F26, 0xD1734F02, 0x94A43145, +0x4609060A, 0x46094609, 0x00293646, 0xD76CD56F, +0x2500CA01, 0x4F062762, 0x4F16000B, 0xBFEA4F22, +0xB01F0009, 0xA04E0009, 0x2FE64F26, 0x6E63D168, +0x44186612, 0x4528928A, 0x26294408, 0x44084500, +0x4400265B, 0x4708264B, 0x47082162, 0x27EBD161, +0x000B2172, 0x000B6EF6, 0xD25F0009, 0xE40A9677, +0x2262AFB4, 0x2FC62FB6, 0x2FE62FD6, 0xDC5B4F22, +0x2C22E201, 0xBFA9E40A, 0x60C27C44, 0xCB01ED00, +0x60C22C02, 0xC901EB64, 0x6E03A008, 0x89073DB2, +0xE40160C2, 0xBF99C901, 0x7D016E03, 0x8BF52EE8, +0x8B033DB2, 0xD24FD44E, 0x0009420B, 0x4F26E40A, +0x6DF66EF6, 0xAF896CF6, 0x44116BF6, 0x604B8F01, +0x000B6043, 0x2FB60009, 0x2FD62FC6, 0x4F222FE6, +0xDC457FFC, 0x60C2ED00, 0xCB02EB64, 0x60C22C02, +0xC9022F02, 0x6E03A009, 0x89083DB3, 0xE46460C2, +0xC9022F02, 0x6E03BF6A, 0x2EE87D01, 0xD73B8BF4, +0x617251C1, 0xDE3BDC3A, 0xD23CD13B, 0x64C23DB3, +0x651264E2, 0x65228F09, 0xD232D439, 0x4F267F04, +0x6DF66EF6, 0x422B6CF6, 0x7F046BF6, 0x6EF64F26, +0x6CF66DF6, 0x6BF6000B, 0x5651D532, 0x46286052, +0x306C000B, 0x5288096C, 0x09B45BB4, 0x03C41FFF, +0x2FC62FB6, 0x2FE62FD6, 0x4F124F22, 0xBFEB4F02, +0x6B036E43, 0xDD18DC28, 0x0009BFE6, 0x3C0530B8, +0x4609060A, 0x46014609, 0x020A3D65, 0x42094209, +0x32E24209, 0x4F068BF0, 0x4F264F16, 0x6DF66EF6, +0x000B6CF6, 0x2FE66BF6, 0xDE1C4F22, 0xE500E102, +0x2E12E403, 0x2E52BFD4, 0x4618E606, 0xE403E700, +0x2E722E62, 0xAFCB4F26, 0x000B6EF6, 0x00000009, +0x00202890, 0x0024CDE0, 0x10624DD3, 0x00202A8C, +0x001C5814, 0x001C59D0, 0x001C5804, 0x001C581C, +0x00202934, 0x00200DA6, 0x001C5860, 0x001C6864, +0x001C7864, 0x001C59BC, 0x001C69BC, 0x001C79BC, +0x0020294C, 0x001C1040, 0xCCCCCCCD, 0x001D4004, +0x2F962F86, 0x2FB62FA6, 0x2FD62FC6, 0x4F222FE6, +0xE4007FE4, 0x4528E510, 0x67436C43, 0xE107A00F, +0x6043644D, 0x0F564008, 0xEE0060C3, 0x815125C1, +0x81538152, 0x157315E2, 0x751415E4, 0x624D7401, +0x8BED3213, 0xDA6F51F1, 0x1A1154F2, 0xD16E2A12, +0x57F455F3, 0x6DF258F5, 0x1141D96C, 0x11532142, +0x11751152, 0x11871174, 0x52F61186, 0x19D1D668, +0xD86829D2, 0xDA68E950, 0x1621EBB4, 0x6BBC2622, +0xA0214908, 0x6EEDEE00, 0x61E36DE3, 0x41084D08, +0x31EC3DEC, 0x41084D08, 0x60C33D8C, 0xE7904108, +0x81D12DC1, 0x41086093, 0x81D2677C, 0x31AC60C3, +0x3472E200, 0x1DD281D3, 0xD4551D13, 0x1D248D01, +0xB03AD450, 0x7E0165D3, 0x34B264ED, 0xD14D8BDB, +0x6512DB52, 0x4529D24D, 0x64121B51, 0x674DD14A, +0x67222B72, 0x4729D64E, 0x69221B73, 0x689D2FD2, +0x69121B82, 0x5A122692, 0x5B1416A2, 0x16B4DA44, +0x16C65C16, 0x16EA6EA2, 0x4F267F1C, 0x6DF66EF6, +0x6BF66CF6, 0x69F66AF6, 0x68F6000B, 0x60616642, +0x8D04C803, 0x6061E500, 0x8802C903, 0x52628B03, +0x51246563, 0x000B2412, 0x2FD66053, 0x4F222FE6, +0x6E537FEC, 0xE5506253, 0xE4006D43, 0xA0014508, +0x5224E101, 0x22116043, 0x81238121, 0x81226053, +0x362056E2, 0xD22F8BF5, 0x64F316E4, 0x420BE614, +0x65E165E3, 0x2549E4FC, 0x61F12E51, 0x214965F3, +0x54D12F11, 0x410BD127, 0x57D1E614, 0xCB016071, +0x1DE12701, 0x4F267F14, 0x000B6EF6, 0x2FD66DF6, +0x4F222FE6, 0x6E537FEC, 0xE5FC6653, 0x60616D43, +0xCB012059, 0x52E22601, 0x8B063260, 0x51E212E4, +0x8B0431E0, 0xA00252D1, 0xAFF01E22, 0xD2155664, +0xE61464F3, 0x65E3420B, 0xE1FC67E1, 0x2E712719, +0x54D167F1, 0xD10F2719, 0xE61465F3, 0x2F71410B, +0x602152D1, 0x2201CB01, 0x7F141DE1, 0x6EF64F26, +0x6DF6000B, 0x0020285C, 0x00202864, 0x00202854, +0x00202884, 0x0010008C, 0x00100EC0, 0x001E2108, +0x001C3D00, 0x00202134, 0x2FC62FB6, 0x2FE62FD6, +0xD6314F22, 0x60D36D62, 0x894DC803, 0xDB30DC2F, +0x0009A02C, 0xC9036061, 0x892B8801, 0xD22DD42B, +0x0009420B, 0x65035603, 0xC8208561, 0xE0508903, +0x720102BE, 0x85620B26, 0x4000600D, 0x4000366A, +0x40004624, 0x206D4624, 0xD423C903, 0x40086E03, +0xD1224000, 0x340C410B, 0x61E3D521, 0xD721E001, +0x450BD221, 0x64E37E30, 0x2702420B, 0x66C252C1, +0x8BCF3620, 0x4E18EE01, 0xA011DB1C, 0x6061EC75, +0x8801C903, 0xD4198910, 0x460BD612, 0xD4180009, +0x470BD718, 0xD2136503, 0x64C3D113, 0x22E2410B, +0x66B252B1, 0x8BEA3620, 0xC80460D3, 0xD2128906, +0x6EF64F26, 0x6CF66DF6, 0x6BF6422B, 0x6EF64F26, +0x6CF66DF6, 0x6BF6000B, 0x001E2100, 0x0020285C, +0x002027F8, 0x00200A5C, 0x00202864, 0x00200ADE, +0x00201FD4, 0x001C3D30, 0x00200D6C, 0x00202854, +0x00202884, 0x00200A7A, 0x002000F8, 0xE601D237, +0x1265D537, 0x000B2252, 0xD6361266, 0x88016062, +0xE1018B62, 0xD5342612, 0x5451D134, 0xE0406212, +0x2122324C, 0x54115752, 0x1141347C, 0x57125453, +0x1172374C, 0x52135755, 0x1123327C, 0x56146452, +0x1164364C, 0x54155754, 0x1145347C, 0x56165458, +0x1166364C, 0x6762D626, 0x327C5217, 0x57611127, +0x327C5218, 0x57621128, 0x327C5219, 0x57631129, +0x347C541A, 0x5764114A, 0x347C541B, 0x5765114B, +0x347C541C, 0x5266114C, 0x372C571D, 0x5267117D, +0x342C541E, 0x5268114E, 0x362C561F, 0xD615116F, +0x041E6262, 0x342C7694, 0xE0440146, 0x061E6262, +0x0166362C, 0x525CE048, 0xD60F051E, 0x0156352C, +0xE0546262, 0x4229051E, 0x0156352C, 0xE0585561, +0x4529061E, 0x0166365C, 0x0009000B, 0x001C1010, +0x0000C34F, 0x001C1028, 0x001C369C, 0x002027F8, +0x001C3CA0, 0x001C36F4, 0x001C3B88, 0xD62F7FFC, +0x2642644C, 0xC8205066, 0x2F028DFC, 0x7F04000B, +0x2FD62FC6, 0x4F222FE6, 0x6D436C53, 0xEE00A004, +0x7E0164D4, 0x644CBFEA, 0x8BF93EC2, 0x6EF64F26, +0x000B6DF6, 0xA0016CF6, 0x76016643, 0x22286260, +0x36488BFB, 0x6563AFE4, 0x2FB62F96, 0x2FD62FC6, +0x4F222FE6, 0xEC1CED08, 0xDB196E53, 0x61C3E90A, +0x60434B0B, 0x3092C90F, 0x66038D02, 0x7630A001, +0x4D107637, 0x7E012E60, 0x7CFC8FF1, 0x8058E000, +0x6EF64F26, 0x6CF66DF6, 0x000B6BF6, 0x000B69F6, +0x000BE000, 0x2FE6E000, 0x7FEC4F22, 0x6E436253, +0xBFD165F3, 0xBFC66423, 0xBFC464E3, 0xD40564F3, +0x0009BFC1, 0x4F267F14, 0x6EF6000B, 0x001C0004, +0x00202094, 0x00202968, 0xE110D59C, 0xE6406050, +0x2500C9FD, 0xE0FF75E9, 0x80516453, 0x80538052, +0x80568055, 0x251075EF, 0xE1EF6250, 0x2219E001, +0xE7202520, 0x24608052, 0x2570000B, 0xE4FDD590, +0xE7026152, 0x25122149, 0x74016052, 0x2502CB01, +0xD18C6652, 0x25622649, 0x92C26012, 0x2102CB08, +0xC9CF6012, 0x60122102, 0x2102CB03, 0x000B1172, +0x4F221123, 0xE100D484, 0xD285D784, 0xD5852410, +0x2711D485, 0x2211E700, 0xBFBD2511, 0xD5832471, +0x2560E600, 0x4F26AFD2, 0xD281664C, 0x362C4600, +0xCB106060, 0x2600000B, 0xD27D654C, 0x352C4500, +0xE1EF6650, 0x000B2619, 0x664C2560, 0x4600D279, +0x6060362C, 0x000BCB10, 0x654C2600, 0x4500D275, +0x6650352C, 0x2619E1EF, 0x2560000B, 0xD270664C, +0x362C4600, 0xCB086060, 0x2600000B, 0xD26C654C, +0x352C4500, 0xE1F76650, 0x000B2619, 0x664C2560, +0x4600D268, 0x6060362C, 0x000BCB08, 0x654C2600, +0x4500D264, 0x6650352C, 0x2619E1F7, 0x2560000B, +0xD65F624C, 0x326C4200, 0xC9086020, 0x40214021, +0x000B4021, 0x624C600C, 0x4200D65A, 0x6020326C, +0x4021C908, 0x40214021, 0x600C000B, 0xD156644C, +0x341C74FF, 0x000B6240, 0xD154602C, 0x341C644C, +0x000B6240, 0x2FE6602C, 0x655C4F22, 0x3567E60A, +0x6E438D15, 0x6453BFEA, 0x60EC640C, 0x8B028801, +0xA002E00F, 0x44092409, 0x624C4409, 0x3263E60A, +0xBFE28905, 0x620C644C, 0xC8806023, 0xE2008B00, +0x4F266023, 0x6EF6000B, 0xD6414F22, 0x88016062, +0xB2228B03, 0xA0030009, 0xD23E0009, 0x2260E640, +0xE200D63D, 0x000B4F26, 0x4F222622, 0x6062D638, +0x8B018802, 0x0009B26C, 0xE200D637, 0x000B4F26, +0x0FFF2622, 0xD433D532, 0xE701E100, 0x000B2512, +0xD2302470, 0x000BE604, 0xD5202260, 0x6150E4FD, +0x2149D62E, 0x2510E700, 0x2670000B, 0xE4FBD51B, +0x22496250, 0x2520000B, 0xE4F7D518, 0x22496250, +0x2520000B, 0xD2264F22, 0x600D8522, 0x89112008, +0x89138801, 0x89158803, 0x89178805, 0x89418806, +0x89478808, 0x894D8809, 0x8953880A, 0x8959880B, +0x0009A060, 0x0009B062, 0x600CA05D, 0x0009B070, +0x600CA059, 0x0009B07A, 0x600CA055, 0x6260D606, +0x8B4F2228, 0x0009B086, 0x600CA04D, 0x001E1028, +0x001E2148, 0x001E1108, 0x002028D9, 0x002028C8, +0x002028CA, 0x002028CC, 0x002028AC, 0x001E1008, +0x001E103F, 0x001E105F, 0x001E1030, 0x001E1090, +0x002028D4, 0x001E100B, 0x002028D0, 0x002028D8, +0x002028A0, 0x6260D687, 0x8B232228, 0x0009B06A, +0x600CA021, 0x6260D683, 0x8B1B2228, 0x0009B0B4, +0x600CA019, 0x6260D67F, 0x8B132228, 0x0009B0BA, +0x600CA011, 0x6260D67B, 0x8B0B2228, 0x0009B11E, +0x600CA009, 0x6260D677, 0x8B032228, 0x0009B136, +0x600CA001, 0x4F26E000, 0x0009000B, 0xD273D172, +0xD5738412, 0x4000C90F, 0xD772012D, 0x611CE403, +0xD671E20F, 0x27122540, 0xE0012520, 0x2602000B, +0xE601D269, 0x30668523, 0xE0008D06, 0xE000D267, +0x8122D669, 0x2602E001, 0x0009000B, 0x8523D262, +0x2008600D, 0x88018905, 0xD6648B0A, 0xCB016060, +0xD6612600, 0xE101D45D, 0x2612E001, 0x8142000B, +0xE000000B, 0xE501D158, 0x45188513, 0x3453640D, +0x8D056603, 0xD25AE000, 0xE001D557, 0x25022260, +0x0009000B, 0xD1504F22, 0x650D8513, 0x44196453, +0x672E6249, 0x602C227D, 0x89098801, 0x890C8802, +0x89108803, 0x89268806, 0x89298807, 0x0009A038, +0xD64DD54C, 0xA027E212, 0x625C2652, 0x8B2F2228, +0xA01ED64A, 0x605C6262, 0x89052008, 0x89088810, +0x890B8820, 0x0009A024, 0xD643D445, 0xA013E204, +0xD7442642, 0xE20CD640, 0x2672A00E, 0xD63ED542, +0xA009E218, 0xD4412652, 0xE20AD63B, 0x2642A004, +0xD639D23F, 0xE22E2622, 0xD43E8515, 0x3277670D, +0x8F012421, 0x24516503, 0x0009B0DF, 0xE001A001, +0x4F26E000, 0x0009000B, 0xE101D629, 0x2610D436, +0xD7286541, 0x655DD128, 0xE001E20F, 0x26202752, +0x2102000B, 0x4F222FE6, 0x8523D21F, 0x2448640C, +0xD62D8B08, 0xE200D521, 0x84512621, 0x20499430, +0x8051A026, 0x60E0DE1D, 0x8D0BC840, 0x3427E201, +0xD1258922, 0x420BD225, 0xD5252141, 0xCB046052, +0x2502A00B, 0x89173427, 0xD722D21F, 0x2241470B, +0xE5FBD61F, 0x21596162, 0x84E12612, 0xB12DCB80, +0x60E080E1, 0xCB04D61C, 0x60602E00, 0x2600C93F, +0xE001D609, 0x2602A001, 0x4F26E000, 0x6EF6000B, +0x0000FF7F, 0x002028D9, 0x002028A0, 0x002028AC, +0x001E1100, 0x001E100C, 0x002028D0, 0x001E1000, +0x001E1001, 0x00202A90, 0x002028B4, 0x002028BC, +0x00202AFE, 0x00202B02, 0x00202B0E, 0x00202B26, +0x00202B30, 0x002028B8, 0x002028C6, 0x00201A32, +0x001E1108, 0x00201B3E, 0x001E1015, 0x6060D696, +0x8919C880, 0x6021D295, 0x8B158801, 0xE501D294, +0x30568524, 0xD1938910, 0xD493E203, 0x65412120, +0x655DE00B, 0xD5910656, 0xE702E40F, 0x25712140, +0xE001D78F, 0x2702000B, 0xE000000B, 0x4F222FE6, +0x84E1DE8C, 0x8934C880, 0x8554D585, 0x8F302008, +0xD7896103, 0x66728553, 0x650C6403, 0x620C8566, +0x8B263520, 0xD780D685, 0x644C651C, 0x27412651, +0xC84060E0, 0xD2828907, 0x0009420B, 0x6062D681, +0xA008CB04, 0xD1802602, 0x0009410B, 0xE5FBD67D, +0x24596462, 0xB0A12642, 0xD5750009, 0x2522E201, +0xD77A60E0, 0x2E00CB04, 0xC93F6070, 0xA0012700, +0xE0006023, 0x000B4F26, 0x2FA66EF6, 0x2FC62FB6, +0x2FE62FD6, 0xE240DA69, 0xDC6666A1, 0x3123616D, +0x62638900, 0x6ED36D2C, 0x4E2136D8, 0x4E212A61, +0xDB6CD46B, 0xE700A00F, 0x770166B2, 0x71026163, +0x65612B12, 0x71026613, 0x62612B12, 0x622D655D, +0x325C4228, 0x627C2422, 0x8BED32E3, 0xC90360D3, +0x8B108803, 0xED076EB2, 0x710261E3, 0x67132B12, +0x62E17102, 0x65712B12, 0x655D622D, 0x352C4528, +0xA00C2CD0, 0x88022452, 0xA0038B01, 0x8801E203, +0xE2018B05, 0x66B22C20, 0x677D6761, 0xEB0F2472, +0x6DA12CB0, 0x8B052DD8, 0xD445D24F, 0xE101EE00, +0x241222E2, 0x6DF66EF6, 0x6BF66CF6, 0x6AF6000B, +0x2FE62FD6, 0xE240DD3D, 0x616D66D1, 0x89003123, +0x672C6263, 0xDE433678, 0x2D617703, 0xD6404721, +0x472164E2, 0xE100A00E, 0x71016562, 0x24506253, +0x42197401, 0x74012420, 0x24504529, 0x45197401, +0x74012450, 0x3273621C, 0x42008BEE, 0x64D166E2, +0x362C4200, 0x8F062448, 0xDD332E62, 0xE500DE28, +0x2D52E701, 0x6EF62E72, 0x6DF6000B, 0x2FE62FD6, +0xEE014F22, 0xED0AA005, 0x64E3BCB6, 0x64E3BCBC, +0x62EC7E01, 0x8BF732D7, 0xEE01A005, 0x64E3BCBD, +0x64E3BCC3, 0x62EC7E01, 0x8BF732D7, 0x6EF64F26, +0x6DF6000B, 0x2FE62FD6, 0x7FFC4F22, 0x6060D61F, +0x89758801, 0xE101D41E, 0xD7128548, 0x650D2610, +0x45196070, 0x6659DD1B, 0x61D3626E, 0xC840262D, +0x74027102, 0x8D47D718, 0xD218666C, 0xE501DE0A, +0xA0312E22, 0x0000EE04, 0x001E1001, 0x002028C6, +0x002028A0, 0x001E1100, 0x002028CA, 0x002028B8, +0x002028D0, 0x001E1000, 0x002028BC, 0x002028C8, +0x00201A32, 0x001E1108, 0x00201B3E, 0x001E1015, +0x001E100C, 0x002028B4, 0x002028D4, 0x002028D8, +0x00202A90, 0x00202B26, 0x00202B32, 0x00202AA2, +0x75016245, 0x71022121, 0x32E3625C, 0x60638BF8, +0xE60181D4, 0xE417D538, 0x3243626C, 0x6255891E, +0x27217601, 0x7702AFF8, 0xDE35D234, 0x2E22E501, +0xEE04A004, 0x75016245, 0x71022121, 0x32E3625C, +0x60638BF8, 0xE60181D4, 0xA004D52E, 0x6255E417, +0x27217601, 0x626C7702, 0x8BF83243, 0x2D21924B, +0xD72AD429, 0x2F126142, 0x6DF265F2, 0xC9806053, +0x60532700, 0x6103C960, 0x60538071, 0x65F26EF2, +0x4D19C903, 0x80724529, 0x451960DC, 0x4E298172, +0x62EC605C, 0x302C4018, 0x6D428173, 0x2FD22118, +0x62F26EF2, 0x421966F2, 0x656C4629, 0x602C66F2, +0x401864EC, 0x304C4629, 0x81744619, 0x4018606C, +0x8F07305C, 0xBCB58175, 0x620C0009, 0x89082228, +0x0009A00A, 0x88406013, 0xB00A8B03, 0xA0030009, +0xD60B0009, 0x2622E202, 0x4F267F04, 0x000B6EF6, +0x000B6DF6, 0x060A0009, 0x00202AD2, 0x00202AD0, +0x002028BC, 0x00202AA4, 0x001E100C, 0x002028A0, +0x002028D0, 0x7FFC4F22, 0x6620D27E, 0x8D082668, +0xD47D2F60, 0x420BD27D, 0x64F00009, 0xA0907F04, +0x7F044F26, 0x000B4F26, 0x000B0009, 0x2FE60009, +0xDE774F22, 0x60E0D677, 0xCBC0D477, 0x62602E00, +0xC803602C, 0x40218904, 0x70014021, 0x6603A002, +0x66034009, 0xD671616D, 0xE500A004, 0x75016262, +0x74042422, 0x3213625D, 0xD16D8BF8, 0x0009410B, +0xE401D66C, 0x84E22641, 0x80E2C9BF, 0x000B4F26, +0x2FE66EF6, 0xD5687FFC, 0x6250DE61, 0x642C84E2, +0xCB407404, 0x80E2614D, 0x44216413, 0xD7634421, +0xE600A004, 0x76016256, 0x27222F22, 0x3243626D, +0x60138BF8, 0x2008C903, 0x88038912, 0x88028905, +0x88018906, 0xA0088907, 0xE0070009, 0x8078A005, +0xA002E003, 0xE0018078, 0x62528078, 0x27222F22, +0xD650E00F, 0x60618078, 0x8B018801, 0x2621E200, +0x6060D64F, 0x2600CB08, 0xC93F60E0, 0x7F042E00, +0x6EF6000B, 0x6021D247, 0x8D188801, 0xD2466143, +0x22106053, 0x60638021, 0xD4468121, 0xE500A007, +0x027C605D, 0x364C6603, 0x26207001, 0x625D6503, +0x3213611C, 0xD6408BF4, 0xC9BF6060, 0x000B2600, +0x2FD60009, 0x4F222FE6, 0x60437FFC, 0x8D02C820, +0xBF6A6E43, 0x60E30009, 0x8901C810, 0x0009BF67, +0xC84060E3, 0xBF8C8901, 0x60E30009, 0x8929C801, +0x60D0DD32, 0x8D03C802, 0xD6312F00, 0x0009460B, +0xC80460F0, 0xD62F8902, 0x0009460B, 0x602362F0, +0x8902C880, 0xC97F60D0, 0x60232D00, 0x8902C801, +0x420BD229, 0xD5290009, 0x88026052, 0xD2288B03, +0xA005E604, 0x88012260, 0xD2258B02, 0x2260E601, +0x2522E200, 0xC88060E3, 0xD2228916, 0x60E36E20, +0x8902C802, 0x420BD220, 0x60E30009, 0x8902C804, +0x420BD21E, 0x60E30009, 0x8905C808, 0x7F04D21C, +0x6EF64F26, 0x6DF6422B, 0x4F267F04, 0x000B6EF6, +0x00006DF6, 0x001E1020, 0x0020296C, 0x00200DA6, +0x001E1015, 0x001E10BF, 0x00117D00, 0x001E10FC, +0x002000F8, 0x002028CC, 0x00117D80, 0x001E10F8, +0x001E10AE, 0x00117D84, 0x001E1017, 0x001E1021, +0x00200FD8, 0x00200FFA, 0x00201584, 0x002028D0, +0x001E100B, 0x001E1028, 0x0020102A, 0x0020103C, +0x00201048, 0xD6A8644C, 0x346C74FF, 0x2450000B, +0x644CD6A6, 0x000B346C, 0xD6A52450, 0x346C644C, +0x2450000B, 0x616D625C, 0x41194208, 0x60194208, +0x644C4200, 0x324C670E, 0x207DD19E, 0xC90F4200, +0x000B321C, 0x67632200, 0x4208625C, 0x42004208, +0x324C644C, 0x4200D198, 0x000B321C, 0x2FE62270, +0x614C4F12, 0x4100D493, 0x6710314C, 0x2729E29F, +0x65736E53, 0x4719676D, 0x672E6279, 0x4221227D, +0x42214221, 0x7601662C, 0xE4014608, 0x34E84608, +0x644C4600, 0x0E1A0467, 0x215025EB, 0x000B4F16, +0x4F226EF6, 0xD2857FE8, 0x88016021, 0xD2848B7B, +0x26686621, 0xD2838B77, 0x26686621, 0xE50F8B73, +0xE401BFA0, 0xBFA3E501, 0xE586E400, 0xE400655C, +0x2F50BFA3, 0xBFA0E401, 0xE602E506, 0x60634618, +0x81F2E401, 0x6543BF9E, 0xE40185F2, 0xBFAA6543, +0x85F26603, 0x6543E401, 0x6603BFB1, 0xE40265F0, +0x6053756C, 0x80F8BF7E, 0xBF81E402, 0x84F8E512, +0x7090E402, 0x6503BF81, 0x4618E602, 0x81F66063, +0xBF7FE402, 0x85F6E500, 0x6603E402, 0xE500BF8B, +0xE40285F6, 0xBF926603, 0xE5FEE500, 0xE010655C, +0xBF5FE403, 0xE5130F54, 0xE40EBF62, 0x05FCE010, +0xBF62E40E, 0xE5007585, 0xBF63E403, 0xE500E640, +0xBF70E403, 0xE500E640, 0xBF78E403, 0xE5FFE640, +0xE014655C, 0xBF45E404, 0xE40F0F54, 0xE504BF48, +0x05FCE014, 0xBF48E40F, 0xE5017584, 0xBF49E640, +0xE501E404, 0xBF56E640, 0xE501E404, 0xE404E640, +0xAF5C7F18, 0x7F184F26, 0x000B4F26, 0x4F220009, +0xD2427FF0, 0x88016021, 0xD2418B71, 0x26686621, +0xD2408B6D, 0x26686621, 0xE50F8B69, 0xE401BF1A, +0xBF1DE501, 0xE586E400, 0xE400655C, 0x2F50BF1D, +0xBF1AE401, 0xE401E506, 0xBF1B6543, 0xE401E640, +0xBF286543, 0xE401E640, 0xBF306543, 0x65F0E640, +0x756CE402, 0xBEFD6053, 0xE40280F4, 0xE512BF00, +0xE40284F4, 0xBF007090, 0xE6406503, 0xBF01E402, +0xE640E500, 0xBF0EE402, 0xE640E500, 0xBF16E402, +0xE5FEE500, 0x6053655C, 0xBEE3E403, 0xE51380F8, +0xE40EBEE6, 0xE40E84F8, 0xBEE67085, 0xE5006503, +0xBEE7E640, 0xE500E403, 0xBEF4E640, 0xE500E403, +0xBEFCE640, 0xE5FFE403, 0x6053655C, 0xBEC9E404, +0xE40F80FC, 0xE504BECC, 0xE40F84FC, 0xBECC7083, +0xE5016503, 0xBECDE640, 0xE501E404, 0xBEDAE640, +0xE501E404, 0xE404E640, 0xAEE07F10, 0x7F104F26, +0x000B4F26, 0x00000009, 0x001E1030, 0x001E1080, +0x001E1090, 0x001E103F, 0x001E103E, 0x002028C6, +0x002028C8, 0x002028CA, 0x0009000B, 0x666CE680, +0x6563D2A8, 0x7540E700, 0x6473422B, 0x2FB62FA6, +0x2FD62FC6, 0x4F222FE6, 0x4C18EC01, 0xDAA3DBA2, +0x65B252B1, 0x89223520, 0xC9036051, 0x891E8801, +0xD19FDE9D, 0x64E3410B, 0x85036503, 0x670D66A2, +0xDD9C3762, 0xD49C890A, 0x420BD29C, 0xD19C0009, +0xE701D49C, 0x21724D0B, 0x0009AFE2, 0x420BD29A, +0xD69A64E3, 0x4D0BD49A, 0xAFD926C2, 0x4F260009, +0x6DF66EF6, 0x6BF66CF6, 0x6AF6000B, 0x7FF44F22, +0xE6818546, 0x85472F01, 0x81F1666C, 0xD2858548, +0x854281F2, 0x81F367F3, 0xE40C8543, 0x605381F4, +0x81F56563, 0x7540420B, 0x4F267F0C, 0x0009000B, +0x2F962F86, 0x2FB62FA6, 0x2FD62FC6, 0x4F222FE6, +0xDC847FF0, 0xE800A0DD, 0xD2836B13, 0xE0014B08, +0x4B00420B, 0x1F03DE81, 0x3BEC85F2, 0x2F827E30, +0x1FE26803, 0x66C2DD7E, 0x362052C1, 0xA0C38B01, +0x60610009, 0x8801C903, 0xA0BD8B01, 0x85610009, +0x8965C801, 0xEE105163, 0xDA6A8512, 0xC9036603, +0x85136403, 0x4021600D, 0xC93F4021, 0x8D1C30E3, +0xD7706503, 0x62704408, 0x44004408, 0x22284500, +0x345C8F0A, 0x6043D26C, 0x697D072D, 0x68994919, +0x697C6E8E, 0x28EDA009, 0x6043D268, 0x697D072D, +0x68994919, 0x697C6E8E, 0xEEFF28ED, 0x6EEC629D, +0x8B0F32E0, 0x410BD152, 0x540364C3, 0xBF85E502, +0xD45F6E03, 0x460BD654, 0xD75E65E3, 0xD45EEE01, +0x27E2A01D, 0x26E9EEFC, 0x81126063, 0x97888513, +0x20794208, 0x85128113, 0x8112208B, 0x202B8513, +0x85148113, 0x4218E208, 0x8114202B, 0x854164C2, +0x814120E9, 0xD45165C2, 0xCB016051, 0x4A0B2501, +0x60C20009, 0x52F356F2, 0x2B02CB01, 0x2622AF8B, +0xD2378561, 0x8D2EC802, 0x420B64C3, 0xD6480009, +0x5E036503, 0x076EE04C, 0x7701D146, 0x60120676, +0x8B058801, 0xEA0C85E1, 0x20AB4A18, 0x81E1A007, +0x88026012, 0x85E18B03, 0x20A9EADF, 0x855181E1, +0x20A9EAFC, 0x60518151, 0xCB01DA28, 0x4A0B64C3, +0x56F22501, 0xD73851F3, 0x85EF2612, 0x470B64D3, +0xAF58650D, 0x420B0009, 0x54030009, 0x85446E03, +0x4A18EA08, 0x30A020A9, 0x8B03DA1A, 0xE501BF16, +0x0009A007, 0xD62D8541, 0x2268620D, 0xBF0D8901, +0xD423E500, 0x420BD218, 0xD72265E3, 0xEE01D428, +0x27E24A0B, 0x0009AF37, 0x68F26083, 0x780181F2, +0x618D7C08, 0x31E7EE03, 0xAF1D8901, 0x7F100009, +0x6EF64F26, 0x6CF66DF6, 0x6AF66BF6, 0x000B69F6, +0xFE0368F6, 0x00201834, 0x00202884, 0x0020288C, +0x00200A5C, 0x00200DA6, 0x00202854, 0x00200ADE, +0x001E2130, 0x00202A70, 0x00200A7A, 0x001C3D30, +0x00202A74, 0x00202864, 0x00201FD4, 0x001C3D00, +0x00202A80, 0x00202A8C, 0x00202970, 0x002029F0, +0x0020285C, 0x001E212C, 0x00202A78, 0x00202A7C, +0x002027F8, 0x002027F4, 0x00200E06, 0x00008000, +0x00202A88, 0x4F222FE6, 0x6E22D20D, 0xC84060E3, +0x22E28D02, 0x0009BE68, 0x4218E240, 0x89012E28, +0x0009BE64, 0xC80560E3, 0xBEB98901, 0x60E30009, +0x8902C802, 0xAE614F26, 0x4F266EF6, 0x6EF6000B, +0x001C3510, 0x080A0C0E, 0x00020406, 0x1A1C1E20, +0x12141618, 0x2E303234, 0x26282A2C, 0x3A3C3E40, +0x6C625648, 0x41112F26, 0xE2208F18, 0x890B3123, +0x321CD204, 0xD1026220, 0x412B312C, 0x00090009, +0x00201FFE, 0x00201FB4, 0x000BE000, 0x400062F6, +0x40004000, 0x40004000, 0x40004000, 0x62F6000B, +0x40004000, 0x40004000, 0x40004000, 0x40184000, +0x62F6000B, 0x40004000, 0x40004000, 0x40004000, +0x40284000, 0x62F6000B, 0x40004000, 0x40184000, +0x000B4028, 0xC90F62F6, 0x40054005, 0x40054005, +0x62F6000B, 0x4005C907, 0x40054005, 0x62F6000B, +0x4005C903, 0x000B4005, 0xC90162F6, 0x000B4005, +0x000062F6, 0x080A0C0E, 0x00020406, 0x1A1C1E20, +0x12141618, 0x2E303234, 0x26282A2C, 0x3A3C3E40, +0x6C625648, 0x41112F26, 0xE2208F18, 0x890B3123, +0x321CD204, 0xD1026220, 0x412B312C, 0x00090009, +0x002020BE, 0x00202074, 0x000BE000, 0x400162F6, +0x40014001, 0x40014001, 0x40014001, 0x62F6000B, +0x40014001, 0x40014001, 0x40014001, 0x40194001, +0x62F6000B, 0x40014001, 0x40014001, 0x40014001, +0x40294001, 0x62F6000B, 0x40014001, 0x40194001, +0x000B4029, 0x400462F6, 0x40044004, 0xC90F4004, +0x62F6000B, 0x40044004, 0xC9074004, 0x62F6000B, +0x40044004, 0x000BC903, 0x400462F6, 0x000BC901, +0x000062F6, 0x3622E218, 0x67438F12, 0x0009A004, +0x76FF6254, 0x74012420, 0xC8036053, 0x60438BF8, +0x8902C803, 0x422BD22B, 0xD22B0009, 0x0009422B, +0x2FE66473, 0x8D4A3450, 0x27786763, 0x62438947, +0x227B225B, 0xC9016023, 0x8D203452, 0x2EE86E03, +0x60238B15, 0x8B08C803, 0x47096643, 0x47106256, +0x8FFB2622, 0xA0327604, 0x47010009, 0x61436673, +0x46106255, 0x8FFB2121, 0xA0287102, 0x66430009, +0x47106254, 0x8FFB2620, 0xA0207601, 0x61430009, +0x2EE8357C, 0x8F15317C, 0x60236653, 0x8B07C803, +0x76FC4709, 0x47106262, 0x21268FFB, 0x0009A00F, +0x65634701, 0x75FE6673, 0x46106251, 0x21258FFB, +0x0009A005, 0x626076FF, 0x8FFB4710, 0x60432124, +0x6EF6000B, 0x002022A6, 0x00202752, 0xE21E2FE6, +0x67633626, 0x8D1B6153, 0x3E106E43, 0x3E128916, +0x65E38908, 0x3672E600, 0x62148910, 0x25207601, +0x7501AFF9, 0x317C64E3, 0x6513347C, 0xE600A004, +0x625075FF, 0x24247601, 0x8BF93672, 0x60E3A011, +0x890831E2, 0x327C6213, 0x8B0432E6, 0x651364E3, +0xA0086673, 0xD28F6EF6, 0x651364E3, 0x422B6673, +0x000B6EF6, 0xE2046EF6, 0x67433622, 0x8F10356C, +0xA004346C, 0x75FF0009, 0x76FF6250, 0x60532424, +0x8BF8C803, 0xC8036043, 0xA1058901, 0xA2770009, +0xA2990009, 0x2FB60009, 0x2FD62FC6, 0x7FE42FE6, +0x6C636043, 0x66521F62, 0xC9037504, 0x1F516E53, +0x45086503, 0xE1FC6D43, 0x2D194500, 0x1F732558, +0x1F651F44, 0x2FD28D0B, 0x88086053, 0x88108923, +0x8818895B, 0xA0898B01, 0xA0BD0009, 0x62630009, +0x2D22E600, 0x7CFC7D04, 0xEB10A00D, 0xE60064E6, +0x7CF065E6, 0x62E261E6, 0x1D512D42, 0x1D231D12, +0x7E047D10, 0x3CB21FE1, 0x1F6589F0, 0x2FD21FC2, +0xA0A11FE6, 0x64D21FD4, 0x44286263, 0x44294418, +0x42184419, 0x4629242B, 0x2D424619, 0x65637D04, +0xA0217CFD, 0x67E6EB10, 0x62E67CF0, 0x64E66673, +0x256B4618, 0x2D5261E2, 0x65234729, 0x45184719, +0x4229275B, 0x42191D71, 0x47186743, 0x4429227B, +0x44196713, 0x247B4718, 0x1D431D22, 0x41194129, +0x65137D10, 0x1FE17E04, 0x89DC3CB2, 0x1FE67EFF, +0x1FC21F55, 0xA0672FD2, 0x6CF21FD4, 0x66C257F5, +0x46286273, 0x42284629, 0x2C62262B, 0x7C045DF2, +0x7DFE4729, 0xA01CEB10, 0x65E65EF1, 0x66E66273, +0x47286753, 0x6763227B, 0x452961E6, 0x257B4728, +0x2C2264E6, 0x65131C51, 0x45284629, 0x1C62265B, +0x41296643, 0x216B4628, 0x44291C13, 0x67437C10, +0x3DB27DF0, 0x1FD289E1, 0x7EFEA034, 0x51F56CF2, +0x621366C2, 0x42284618, 0x42184619, 0x2C62262B, +0x7C045DF2, 0x7DFF4119, 0xA01FEB10, 0x65E65EF1, +0x64E67DF0, 0x42286253, 0x421867E6, 0x66E6212B, +0x61432C12, 0x45194128, 0x251B4118, 0x65731C51, +0x44194528, 0x245B4518, 0x64631C42, 0x47194428, +0x274B4418, 0x46191C73, 0x61637C10, 0x89DE3DB2, +0x7EFD1FD2, 0x1FC41FE6, 0x5DF2E704, 0xA00D5EF6, +0x62E451F4, 0x66E47DFC, 0x65E464E4, 0x71012120, +0x71012160, 0x71012140, 0x71012150, 0x89F03D72, +0x66D357F3, 0x641365E3, 0x6EF67F1C, 0x6CF66DF6, +0x6BF6A190, 0x00202134, 0x2FC62FB6, 0x2FE62FD6, +0x60437FE4, 0x6C63C903, 0x66031F62, 0x460875FC, +0x61526E43, 0x4600E2FC, 0x26682E29, 0x1F441F73, +0x1F516D53, 0x8D0B1F15, 0x60632FE2, 0x891F8808, +0x89538810, 0x8B018818, 0x0009A081, 0x0009A0B9, +0xEB10A00D, 0x52D37DF0, 0x54D156D2, 0x2E1665D2, +0x2E662E26, 0x2E427EFC, 0x1FD16153, 0x3CB27CF0, +0x7D0489F0, 0x1F151FD6, 0x2FE21FC2, 0x1FE4A0A1, +0x621366E2, 0x42294619, 0x42194618, 0x2E62262B, +0x7CFF4118, 0xEB10A021, 0x54D37DF0, 0x624357D2, +0x42194229, 0x55D1212B, 0x2E1666D2, 0x41296173, +0x41194418, 0x2E46241B, 0x44296453, 0x44194718, +0x2E76274B, 0x47296763, 0x47194518, 0x257B7EFC, +0x46182E52, 0x1FD16163, 0x3CB27CF0, 0x7D0389DC, +0x1F151FD6, 0x2FE21FC2, 0x1FE4A06B, 0x57F56EF2, +0x627366E2, 0x46284629, 0x262B4229, 0x2E625CF2, +0x7CFE4728, 0xA01BEB10, 0x7DF05DF1, 0x55D251D3, +0x46296613, 0x54D1276B, 0x2E7662D2, 0x41286753, +0x217B4729, 0x61432E16, 0x41294528, 0x2E56251B, +0x44286523, 0x245B4529, 0x42282E46, 0x7CF06723, +0x89E23CB2, 0x1FD67D02, 0xA03A1FC2, 0x67F21FE4, +0x657251F5, 0x45296213, 0x45284519, 0x42194518, +0x5CF2252B, 0x41282752, 0x7CFD4118, 0xA022EB10, +0x7DF05DF1, 0x54D256D3, 0x45196563, 0x52D14628, +0x4618215B, 0x6ED26543, 0x45192716, 0x265B4428, +0x65436163, 0x45186423, 0x42284419, 0x4218254B, +0x271664E3, 0x44196623, 0x264B2756, 0x4E282766, +0x61E34E18, 0x3CB27CF0, 0x7D0189DB, 0x1FC21FD6, +0xE7041F74, 0x51F45DF2, 0x5EF6A00D, 0x84E27EFC, +0x620364E0, 0x7DFC84E1, 0x84E36503, 0x21646603, +0x21542124, 0x3D722144, 0x57F389F0, 0x641366D3, +0x7F1C65E3, 0x6DF66EF6, 0xA09D6CF6, 0x2F866BF6, +0x2FA62F96, 0x2FC62FB6, 0x2FE62FD6, 0x614374E0, +0x6A636873, 0x6B56E920, 0x6C567AE0, 0x6D567120, +0x6E563A92, 0x64566756, 0x62566656, 0x11C121B2, +0x11E311D2, 0x11451174, 0x8DEC1166, 0x71201127, +0x6613A004, 0x7AFF6254, 0x76012620, 0x8BF92AA8, +0x6EF66083, 0x6CF66DF6, 0x6AF66BF6, 0x000B69F6, +0x2F8668F6, 0x2FA62F96, 0x2FC62FB6, 0x2FE62FD6, +0x6A636873, 0x75E0E920, 0x56565257, 0x57545155, +0x5D525E53, 0x6B525C51, 0x24662426, 0x24762416, +0x7AE024E6, 0x24C624D6, 0x8DEC3A92, 0x66A324B6, +0x6EF66783, 0x6CF66DF6, 0x6AF66BF6, 0xA04369F6, +0x2FE668F6, 0xC8046063, 0x8D046E63, 0x62166153, +0x24227EFC, 0x60E37404, 0x8908C818, 0x71046513, +0x62526616, 0x24227EF8, 0xAFF41461, 0xE2047408, +0x65133E22, 0x66E38D02, 0x6EF6A01C, 0x6EF6AF87, +0xC8046063, 0x61638D04, 0x625275FC, 0x242671FC, +0xC8186013, 0x75F88906, 0x66525251, 0x24662426, +0x71F8AFF6, 0x3122E204, 0x66138F02, 0x0009AFA1, +0x0009A00A, 0x0009A004, 0x76FF6254, 0x74012420, +0x8BF92668, 0x6073000B, 0x0009A004, 0x625075FF, +0x242476FF, 0x8BF92668, 0x6073000B, 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, +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, 0x544F0D0A, +0x46205355, 0x00003A57, 0x2072614D, 0x32203232, +0x20373030, 0x353A3431, 0x33353A34, 0x00000000, +0x00000D0A, 0x00000043, 0x61766E49, 0x2064696C, +0x72657375, 0x20726F20, 0x2079656B, 0x00214449, +0x6E6B6E55, 0x206E776F, 0x6D6D6F63, 0x3D646E61, +0x00000000, 0x61437748, 0x7262696C, 0x6F697461, +0x6620206E, 0x0A6C6961, 0x0000000D, 0x73696F4E, +0x61432065, 0x7262696C, 0x6F697461, 0x6166206E, +0x21216C69, 0x00000D0A, 0x00000D0A, 0x00000042, +0x000000FF, 0x00020001, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x010E010D, 0x00020003, 0x01090108, 0x0002010A, +0x00030002, 0x02020201, 0x02040203, 0x02060205, +0x02080207, 0x020A0209, 0x020C020B, 0x020E020D, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x010E010D, 0x00FF010F, 0x01090108, 0x010B010A, +0x00030002, 0x02020201, 0x02040203, 0x02060205, +0x02080207, 0x020A0209, 0x020C020B, 0x020E020D, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00000072, 0x00205220, 0x00000046, 0x00000059, +0x73204142, 0x003D7165, 0x00000074, 0x00000000, +0x02000112, 0x40FFFFFF, 0x12210ACE, 0x20104890, +0x02090100, 0x0101002E, 0x09FA8000, 0x04000004, +0x000000FF, 0x02010507, 0x07000200, 0x00028205, +0x05070002, 0x00400383, 0x04050701, 0x01004003, +0x002E0209, 0x80000101, 0x000409FA, 0x00FF0400, +0x05070000, 0x00400201, 0x82050700, 0x00004002, +0x03830507, 0x07010040, 0x40030405, 0x03040100, +0x030C0409, 0x0079005A, 0x00410044, 0x03180053, +0x00530055, 0x00320042, 0x0030002E, 0x00570020, +0x0041004C, 0x0000004E, 0x00000000, 0x00000000, +0x00000709, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +const u32_t zcFwImageSize=11104; --- linux-2.6.28.orig/drivers/staging/otus/hal/hpfwu_FB50_mdk.c +++ linux-2.6.28/drivers/staging/otus/hal/hpfwu_FB50_mdk.c @@ -0,0 +1,721 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "cprecomp.h" + +const u32_t zcFwImage[] = { +0x0009000B, 0x4F222FE6, 0xD2287FFC, 0x0009420B, +0x0009B019, 0x9446D526, 0xE600A003, 0x8D043642, +0x60527601, 0x8DF9C840, 0xD4222F02, 0x4E0BDE22, +0xD4220009, 0x00094E0B, 0x4E0BD421, 0x7F040009, +0xA0254F26, 0x4F226EF6, 0x410BD11E, 0xD41E0009, +0x0009440B, 0x450BD51D, 0xD71D0009, 0x611DE1FF, +0x2712D21C, 0xD41C5029, 0xE1FFCB01, 0x1209E501, +0x12112212, 0xD5192452, 0xD6199716, 0xE7002572, +0x2670D218, 0x2272D618, 0x4F26E201, 0x2622000B, +0xDD17DC16, 0x4C0BDE17, 0x4D0B0009, 0x4E0B0009, +0xAFF80009, 0x27100009, 0x00000640, 0x0020095A, +0x001C001C, 0x00202940, 0x00200E2A, 0x0020294C, +0x00202964, 0x00200CF0, 0x00200F26, 0x002009C4, +0x001C3510, 0x001C3624, 0x001E212C, 0x002028EC, +0x00202850, 0x002028F4, 0x00202900, 0x00200BEC, +0x00201FD4, 0x002017B8, 0x2FD62FC6, 0x4F222FE6, +0xDEA17FA4, 0x61E0E01C, 0x7D016DE3, 0x61D00F14, +0xD59FD49E, 0x450BE020, 0xE0200F14, 0xE78004FC, +0x604C66E2, 0x7D7F677C, 0x1F693070, 0x2D628F17, +0x01FCE01C, 0x641CE500, 0xD797DE96, 0x3243625D, +0xA21A8B01, 0x655D0009, 0x31EC6153, 0xE0286C10, +0x6D530FC4, 0x3D7C62CE, 0xAFEF2D20, 0x20087501, +0xE01C8B15, 0xE50001FC, 0xD78BDE8A, 0x641CA00A, +0x6C53655D, 0x66C23CEC, 0x66626253, 0x2262327C, +0x1F697504, 0x3243625D, 0xA1F68BF2, 0x88012D10, +0xE01C8B16, 0xE40001FC, 0x671C2D40, 0x624DDE7D, +0x8B013273, 0x0009A1E9, 0x62E3644D, 0x72046D43, +0x3DEC6143, 0x65D2312C, 0x74086C12, 0x25C2AFEF, +0x8B188804, 0x01FCE01C, 0x2D40E400, 0xDE71671C, +0x3273624D, 0xA1D08B01, 0x644D0009, 0x62E36D43, +0x65D23DEC, 0x61437204, 0x6612312C, 0x74086C52, +0xAFED2C69, 0x880525C2, 0xE01C8B18, 0xE40001FC, +0x671C2D40, 0x624DDE63, 0x8B013273, 0x0009A1B5, +0x6C43644D, 0x3CEC62E3, 0x720465C2, 0x3D2C6D43, +0x615266D2, 0x216B7408, 0x2512AFED, 0x8B138830, +0xE200DE58, 0x64E22D20, 0x8B042448, 0x420BD257, +0xA19A0009, 0x55E10009, 0x57E356E2, 0xDD545CE4, +0x2FC64D0B, 0x7F04A191, 0x89018828, 0x0009A0EA, +0xE143DE4C, 0x622D62E1, 0x8F033217, 0x56FB1FEB, +0x2621E240, 0x8B013217, 0x0009A0D5, 0xE1015EFB, +0x301685E1, 0xA0CE8B01, 0xE4010009, 0x2D4055FB, +0x6451B179, 0xE14357FB, 0xE0546271, 0x3517652D, +0x0F568D41, 0x3563E640, 0xE6008B05, 0x0F65E034, +0xA00FE11A, 0x615372C0, 0x41214121, 0x41214121, +0x45214121, 0x45214521, 0xC9036053, 0xE0346603, +0x71180F65, 0x2209E007, 0x641DE030, 0x0F2565F3, +0x1F4EB1F1, 0x04FDE034, 0x674DE030, 0x47080CFD, +0x607361CD, 0x4108D22B, 0xE00F0CFE, 0x1F1F420B, +0x2CD96D07, 0x5EFB6073, 0x85E20FC6, 0x420B51FF, +0x2C0B600D, 0x54FE6073, 0xB1BB0FC6, 0xE05465F3, +0x652D62E1, 0xE6400F56, 0x89623563, 0xE050E100, +0x60230F15, 0x4008C903, 0x6D034000, 0xE0406103, +0xE0440FD6, 0xD217EEFF, 0x6EEC0FF6, 0x0F26E058, +0x60E3420B, 0x42216253, 0x42214221, 0x66234221, +0x326C4200, 0x45214200, 0xE0486707, 0x0F764521, +0xC9036053, 0x40085CFB, 0x7C0630FC, 0x6E036D2D, +0x1FD51FC6, 0x1F04A02E, 0x00117D00, 0x00202968, +0x00200E2A, 0x00117D04, 0x00117D84, 0x00200700, +0x0020074C, 0x00202034, 0x0FD6E04C, 0x05FEE044, +0x64D3B189, 0x64E2E048, 0xE04006FE, 0x2E422469, +0x01FE67C4, 0x667CE058, 0x420B02FE, 0x240B6063, +0x05FEE044, 0xB15D2E42, 0xE05064D3, 0x7D0101FD, +0x0F157101, 0x02FDE050, 0x3262E606, 0x56FB8BDC, +0x55FB6261, 0x85514200, 0x302C750C, 0x6103701B, +0x64F3E600, 0xE704A004, 0x76016256, 0x74042422, +0x3273626D, 0x65F38BF8, 0x641DB13C, 0xB0D256FB, +0xA0AA6461, 0xD4880009, 0xE201D588, 0x2D20450B, +0x0009A0A3, 0x8B078829, 0xE200DE85, 0x66E22D20, +0x646DB0A1, 0x0009A099, 0x622CE281, 0x8B3D3020, +0xD680E738, 0xE0442D70, 0xE0480C6E, 0x6E621DC1, +0x51611DE2, 0x54621D13, 0x55651D44, 0x57631D55, +0x5C661D76, 0x0E6E1DC7, 0x1DE8E040, 0xE050016E, +0x54641D19, 0x056E1D4A, 0x1D5BE04C, 0xE054076E, +0x0C6E1D7C, 0x1DCDE058, 0xE044026E, 0xED001D2E, +0xE04806D6, 0x16D126D2, 0x16D516D2, 0x16D616D3, +0xE04006D6, 0xE05006D6, 0x06D616D4, 0x06D6E04C, +0x06D6E054, 0x06D6E058, 0x1F29A057, 0x622CE282, +0x89313020, 0x05FCE020, 0x625CE683, 0x3260666C, +0xD65D8B07, 0x2650E500, 0x52617680, 0xA044D65B, +0xE6902622, 0x3260666C, 0xD2578B16, 0xE500D658, +0x60622250, 0xCB20D257, 0xE6052602, 0xD6562262, +0x2252460B, 0x420BD255, 0xD2550009, 0x2262E601, +0x4618D254, 0x2262A029, 0xD254D453, 0xD4546542, +0x0009420B, 0x0009A021, 0xE524D647, 0xD5452650, +0x16215257, 0x16225258, 0x16235259, 0x1624525A, +0x1625525B, 0x1626525C, 0x1627525D, 0x1628525E, +0x1F29525F, 0xE2001629, 0x15281527, 0x152A1529, +0x152C152B, 0x152E152D, 0x7F5C152F, 0x6EF64F26, +0x000B6DF6, 0x4F226CF6, 0xE240614D, 0x89173123, +0x3127E21F, 0xD43B8908, 0xE001D53B, 0x6642450B, +0x26796707, 0x2462A00C, 0x3127E23F, 0xD7358908, +0x71E0D635, 0x460BE001, 0x62075571, 0x17512529, +0x000B4F26, 0x4F220009, 0xE240614D, 0x89153123, +0x3127E21F, 0xD42B8907, 0x6642D22B, 0xE001420B, +0xA00B260B, 0xE23F2462, 0x89073127, 0xD626D725, +0x71E05571, 0xE001460B, 0x1751250B, 0x000B4F26, +0xE6400009, 0x46284618, 0x6252D520, 0x89FC2268, +0x0009000B, 0x4618E680, 0xD51C4628, 0x22686252, +0x000B89FC, 0xA0010009, 0x7201E200, 0x8BFC3242, +0x0009000B, 0x4618E680, 0xD5154628, 0x22686252, +0x000B8BFC, 0x00000009, 0x0020296C, 0x00200E2A, +0x00117D04, 0x00202858, 0x00117D80, 0x002028EC, +0x001C3500, 0x001D4004, 0x00200F26, 0x002009C4, +0x001E212C, 0x001C3D28, 0x00117D00, 0x00200E8A, +0x00202984, 0x001C3704, 0x00202034, 0x001C373C, +0x001C3700, 0x4F222FE6, 0x6E537FFC, 0x2F42BFCA, +0xD61561E2, 0x1615E280, 0x421854E1, 0x55E21646, +0x16574228, 0x6EF257E3, 0x2E2B1678, 0x7F0426E2, +0xAFA74F26, 0x2FC66EF6, 0x2FE62FD6, 0xDD0A4F22, +0xBFAF6C53, 0xBF946E43, 0xBFAB2DE2, 0x51D50009, +0x54D62C12, 0x55D71C41, 0x56D81C52, 0x4F261C63, +0x6DF66EF6, 0x6CF6000B, 0x001C370C, 0x0009A0F8, +0xD19B4F22, 0xD49B9299, 0x2122B00D, 0x9795E605, +0xB0229595, 0xB0366463, 0xB03A0009, 0xB03D0009, +0xA06C0009, 0x4F124F26, 0xD1934F02, 0x94873145, +0x4609060A, 0x46094609, 0x00293646, 0xD78CD58F, +0x2500CA01, 0x4F062762, 0x4F16000B, 0xBFEA4F22, +0xB0230009, 0xA0520009, 0x2FE64F26, 0x6E63D188, +0x44186612, 0x4528926D, 0x26294408, 0x44084500, +0x4400265B, 0x4708264B, 0x47082162, 0x27EBD181, +0x000B2172, 0xD1806EF6, 0xE603D480, 0x000B2162, +0xD27F2462, 0xE40A9656, 0x2262AFB0, 0x2FC62FB6, +0x2FE62FD6, 0xDC7B4F22, 0x2C22E201, 0xBFA5E40A, +0x60C27C44, 0xCB01ED00, 0x60C22C02, 0xC901EB64, +0x6E03A008, 0x89073DB2, 0xE40160C2, 0xBF95C901, +0x7D016E03, 0x8BF52EE8, 0x8B033DB2, 0xD26FD46E, +0x0009420B, 0x4F26E40A, 0x6DF66EF6, 0xAF856CF6, +0x44116BF6, 0x604B8F01, 0x000B6043, 0x2F860009, +0x2FA62F96, 0x2FC62FB6, 0x2FE62FD6, 0x7FFC4F22, +0x6DA3EA00, 0xDC626BA3, 0x9914E864, 0x8B4E2BB8, +0x3AE3EE0A, 0x60C2894B, 0xCB02ED00, 0x62C22C02, +0x2F0260C2, 0xA010C902, 0x096C6E03, 0x5BB45288, +0x1FFF09B4, 0x01FF03C4, 0x89083D83, 0xE46460C2, +0xC9022F02, 0x6E03BF52, 0x2EE87D01, 0xD1518BF4, +0x54C1D551, 0x66526412, 0x6269EE01, 0x4220622F, +0x622F4219, 0x4E182299, 0x8D0322E8, 0xE4FF6423, +0x3428229A, 0x6572D749, 0x622F6259, 0x42194220, +0x2299622F, 0x8D0322E8, 0xE6FF6623, 0x3628229A, +0x3468BFA7, 0x30E2EE02, 0xAFB78901, 0xD240EB01, +0x6EECEEE6, 0xBF21E40A, 0xAFAF22E2, 0xEE0A7A01, +0x89013AE3, 0x8B033D83, 0xD234D43A, 0x0009420B, +0x4F267F04, 0x6DF66EF6, 0x6BF66CF6, 0x69F66AF6, +0x68F6000B, 0x5651D534, 0x46286052, 0x306C000B, +0x2FC62FB6, 0x2FE62FD6, 0x4F124F22, 0xBFF14F02, +0x6B036E43, 0xDD1CDC2D, 0x0009BFEC, 0x3C0530B8, +0x4609060A, 0x46014609, 0x020A3D65, 0x42094209, +0x32E24209, 0x4F068BF0, 0x4F264F16, 0x6DF66EF6, +0x000B6CF6, 0x2FE66BF6, 0xDE214F22, 0xE500E102, +0x2E12E403, 0x2E52BFD4, 0x4618E606, 0xE403E700, +0x2E722E62, 0xAFCB4F26, 0x4F226EF6, 0x0009BFEB, +0xE6E6D213, 0xE40A666C, 0x2262BFC2, 0x4F26AFE3, +0x002028F0, 0x0024CDE0, 0x10624DD3, 0x00202AF0, +0x001C5814, 0x001C59D0, 0x001C59A4, 0x001C639C, +0x001C5804, 0x001C581C, 0x00202998, 0x00200E2A, +0x001C5860, 0x001C6864, 0x001C59BC, 0x001C69BC, +0x001C947C, 0x002029B0, 0x001C1040, 0xCCCCCCCD, +0x001D4004, 0x2F962F86, 0x2FB62FA6, 0x2FD62FC6, +0x4F222FE6, 0xE4007FE4, 0x4528E510, 0x67436C43, +0xE107A00F, 0x6043644D, 0x0F564008, 0xEE0060C3, +0x815125C1, 0x81538152, 0x157315E2, 0x751415E4, +0x624D7401, 0x8BED3213, 0xDA6F51F1, 0x1A1154F2, +0xD16E2A12, 0x57F455F3, 0x6DF258F5, 0x1141D96C, +0x11532142, 0x11751152, 0x11871174, 0x52F61186, +0x19D1D668, 0xD86829D2, 0xDA68E950, 0x1621EBB4, +0x6BBC2622, 0xA0214908, 0x6EEDEE00, 0x61E36DE3, +0x41084D08, 0x31EC3DEC, 0x41084D08, 0x60C33D8C, +0xE7904108, 0x81D12DC1, 0x41086093, 0x81D2677C, +0x31AC60C3, 0x3472E200, 0x1DD281D3, 0xD4551D13, +0x1D248D01, 0xB03AD450, 0x7E0165D3, 0x34B264ED, +0xD14D8BDB, 0x6512DB52, 0x4529D24D, 0x64121B51, +0x674DD14A, 0x67222B72, 0x4729D64E, 0x69221B73, +0x689D2FD2, 0x69121B82, 0x5A122692, 0x5B1416A2, +0x16B4DA44, 0x16C65C16, 0x16EA6EA2, 0x4F267F1C, +0x6DF66EF6, 0x6BF66CF6, 0x69F66AF6, 0x68F6000B, +0x60616642, 0x8D04C803, 0x6061E500, 0x8802C903, +0x52628B03, 0x51246563, 0x000B2412, 0x2FD66053, +0x4F222FE6, 0x6E537FEC, 0xE5506253, 0xE4006D43, +0xA0014508, 0x5224E101, 0x22116043, 0x81238121, +0x81226053, 0x362056E2, 0xD22F8BF5, 0x64F316E4, +0x420BE614, 0x65E165E3, 0x2549E4FC, 0x61F12E51, +0x214965F3, 0x54D12F11, 0x410BD127, 0x57D1E614, +0xCB016071, 0x1DE12701, 0x4F267F14, 0x000B6EF6, +0x2FD66DF6, 0x4F222FE6, 0x6E537FEC, 0xE5FC6653, +0x60616D43, 0xCB012059, 0x52E22601, 0x8B063260, +0x51E212E4, 0x8B0431E0, 0xA00252D1, 0xAFF01E22, +0xD2155664, 0xE61464F3, 0x65E3420B, 0xE1FC67E1, +0x2E712719, 0x54D167F1, 0xD10F2719, 0xE61465F3, +0x2F71410B, 0x602152D1, 0x2201CB01, 0x7F141DE1, +0x6EF64F26, 0x6DF6000B, 0x002028BC, 0x002028C4, +0x002028B4, 0x002028E4, 0x0010008C, 0x00100EC0, +0x001E2108, 0x001C3D00, 0x00202194, 0x2FC62FB6, +0x2FE62FD6, 0xD6314F22, 0x60D36D62, 0x894DC803, +0xDB30DC2F, 0x0009A02C, 0xC9036061, 0x892B8801, +0xD22DD42B, 0x0009420B, 0x65035603, 0xC8208561, +0xE0508903, 0x720102BE, 0x85620B26, 0x4000600D, +0x4000366A, 0x40004624, 0x206D4624, 0xD423C903, +0x40086E03, 0xD1224000, 0x340C410B, 0x61E3D521, +0xD721E001, 0x450BD221, 0x64E37E30, 0x2702420B, +0x66C252C1, 0x8BCF3620, 0x4E18EE01, 0xA011DB1C, +0x6061EC75, 0x8801C903, 0xD4198910, 0x460BD612, +0xD4180009, 0x470BD718, 0xD2136503, 0x64C3D113, +0x22E2410B, 0x66B252B1, 0x8BEA3620, 0xC80460D3, +0xD2128906, 0x6EF64F26, 0x6CF66DF6, 0x6BF6422B, +0x6EF64F26, 0x6CF66DF6, 0x6BF6000B, 0x001E2100, +0x002028BC, 0x00202858, 0x00200AE0, 0x002028C4, +0x00200B62, 0x00202034, 0x001C3D30, 0x00200DF0, +0x002028B4, 0x002028E4, 0x00200AFE, 0x002000F8, +0xE601D237, 0x1265D537, 0x000B2252, 0xD6361266, +0x88016062, 0xE1018B62, 0xD5342612, 0x5451D134, +0xE0406212, 0x2122324C, 0x54115752, 0x1141347C, +0x57125453, 0x1172374C, 0x52135755, 0x1123327C, +0x56146452, 0x1164364C, 0x54155754, 0x1145347C, +0x56165458, 0x1166364C, 0x6762D626, 0x327C5217, +0x57611127, 0x327C5218, 0x57621128, 0x327C5219, +0x57631129, 0x347C541A, 0x5764114A, 0x347C541B, +0x5765114B, 0x347C541C, 0x5266114C, 0x372C571D, +0x5267117D, 0x342C541E, 0x5268114E, 0x362C561F, +0xD615116F, 0x041E6262, 0x342C7694, 0xE0440146, +0x061E6262, 0x0166362C, 0x525CE048, 0xD60F051E, +0x0156352C, 0xE0546262, 0x4229051E, 0x0156352C, +0xE0585561, 0x4529061E, 0x0166365C, 0x0009000B, +0x001C1010, 0x0000C34F, 0x001C1028, 0x001C369C, +0x00202858, 0x001C3CA0, 0x001C36F4, 0x001C3B88, +0xD62F7FFC, 0x2642644C, 0xC8205066, 0x2F028DFC, +0x7F04000B, 0x2FD62FC6, 0x4F222FE6, 0x6D436C53, +0xEE00A004, 0x7E0164D4, 0x644CBFEA, 0x8BF93EC2, +0x6EF64F26, 0x000B6DF6, 0xA0016CF6, 0x76016643, +0x22286260, 0x36488BFB, 0x6563AFE4, 0x2FB62F96, +0x2FD62FC6, 0x4F222FE6, 0xEC1CED08, 0xDB196E53, +0x61C3E90A, 0x60434B0B, 0x3092C90F, 0x66038D02, +0x7630A001, 0x4D107637, 0x7E012E60, 0x7CFC8FF1, +0x8058E000, 0x6EF64F26, 0x6CF66DF6, 0x000B6BF6, +0x000B69F6, 0x000BE000, 0x2FE6E000, 0x7FEC4F22, +0x6E436253, 0xBFD165F3, 0xBFC66423, 0xBFC464E3, +0xD40564F3, 0x0009BFC1, 0x4F267F14, 0x6EF6000B, +0x001C0004, 0x002020F4, 0x002029CC, 0xE110D59C, +0xE6406050, 0x2500C9FD, 0xE0FF75E9, 0x80516453, +0x80538052, 0x80568055, 0x251075EF, 0xE1EF6250, +0x2219E001, 0xE7202520, 0x24608052, 0x2570000B, +0xE4FDD590, 0xE7026152, 0x25122149, 0x74016052, +0x2502CB01, 0xD18C6652, 0x25622649, 0x92C26012, +0x2102CB08, 0xC9CF6012, 0x60122102, 0x2102CB03, +0x000B1172, 0x4F221123, 0xE100D484, 0xD285D784, +0xD5852410, 0x2711D485, 0x2211E700, 0xBFBD2511, +0xD5832471, 0x2560E600, 0x4F26AFD2, 0xD281664C, +0x362C4600, 0xCB106060, 0x2600000B, 0xD27D654C, +0x352C4500, 0xE1EF6650, 0x000B2619, 0x664C2560, +0x4600D279, 0x6060362C, 0x000BCB10, 0x654C2600, +0x4500D275, 0x6650352C, 0x2619E1EF, 0x2560000B, +0xD270664C, 0x362C4600, 0xCB086060, 0x2600000B, +0xD26C654C, 0x352C4500, 0xE1F76650, 0x000B2619, +0x664C2560, 0x4600D268, 0x6060362C, 0x000BCB08, +0x654C2600, 0x4500D264, 0x6650352C, 0x2619E1F7, +0x2560000B, 0xD65F624C, 0x326C4200, 0xC9086020, +0x40214021, 0x000B4021, 0x624C600C, 0x4200D65A, +0x6020326C, 0x4021C908, 0x40214021, 0x600C000B, +0xD156644C, 0x341C74FF, 0x000B6240, 0xD154602C, +0x341C644C, 0x000B6240, 0x2FE6602C, 0x655C4F22, +0x3567E60A, 0x6E438D15, 0x6453BFEA, 0x60EC640C, +0x8B028801, 0xA002E00F, 0x44092409, 0x624C4409, +0x3263E60A, 0xBFE28905, 0x620C644C, 0xC8806023, +0xE2008B00, 0x4F266023, 0x6EF6000B, 0xD6414F22, +0x88016062, 0xB2228B03, 0xA0030009, 0xD23E0009, +0x2260E640, 0xE200D63D, 0x000B4F26, 0x4F222622, +0x6062D638, 0x8B018802, 0x0009B26C, 0xE200D637, +0x000B4F26, 0x0FFF2622, 0xD433D532, 0xE701E100, +0x000B2512, 0xD2302470, 0x000BE604, 0xD5202260, +0x6150E4FD, 0x2149D62E, 0x2510E700, 0x2670000B, +0xE4FBD51B, 0x22496250, 0x2520000B, 0xE4F7D518, +0x22496250, 0x2520000B, 0xD2264F22, 0x600D8522, +0x89112008, 0x89138801, 0x89158803, 0x89178805, +0x89418806, 0x89478808, 0x894D8809, 0x8953880A, +0x8959880B, 0x0009A060, 0x0009B062, 0x600CA05D, +0x0009B070, 0x600CA059, 0x0009B07A, 0x600CA055, +0x6260D606, 0x8B4F2228, 0x0009B086, 0x600CA04D, +0x001E1028, 0x001E2148, 0x001E1108, 0x0020293D, +0x0020292C, 0x0020292E, 0x00202930, 0x00202910, +0x001E1008, 0x001E103F, 0x001E105F, 0x001E1030, +0x001E1090, 0x00202938, 0x001E100B, 0x00202934, +0x0020293C, 0x00202904, 0x6260D687, 0x8B232228, +0x0009B06A, 0x600CA021, 0x6260D683, 0x8B1B2228, +0x0009B0B4, 0x600CA019, 0x6260D67F, 0x8B132228, +0x0009B0BA, 0x600CA011, 0x6260D67B, 0x8B0B2228, +0x0009B11E, 0x600CA009, 0x6260D677, 0x8B032228, +0x0009B136, 0x600CA001, 0x4F26E000, 0x0009000B, +0xD273D172, 0xD5738412, 0x4000C90F, 0xD772012D, +0x611CE403, 0xD671E20F, 0x27122540, 0xE0012520, +0x2602000B, 0xE601D269, 0x30668523, 0xE0008D06, +0xE000D267, 0x8122D669, 0x2602E001, 0x0009000B, +0x8523D262, 0x2008600D, 0x88018905, 0xD6648B0A, +0xCB016060, 0xD6612600, 0xE101D45D, 0x2612E001, +0x8142000B, 0xE000000B, 0xE501D158, 0x45188513, +0x3453640D, 0x8D056603, 0xD25AE000, 0xE001D557, +0x25022260, 0x0009000B, 0xD1504F22, 0x650D8513, +0x44196453, 0x672E6249, 0x602C227D, 0x89098801, +0x890C8802, 0x89108803, 0x89268806, 0x89298807, +0x0009A038, 0xD64DD54C, 0xA027E212, 0x625C2652, +0x8B2F2228, 0xA01ED64A, 0x605C6262, 0x89052008, +0x89088810, 0x890B8820, 0x0009A024, 0xD643D445, +0xA013E204, 0xD7442642, 0xE20CD640, 0x2672A00E, +0xD63ED542, 0xA009E218, 0xD4412652, 0xE20AD63B, +0x2642A004, 0xD639D23F, 0xE22E2622, 0xD43E8515, +0x3277670D, 0x8F012421, 0x24516503, 0x0009B0DF, +0xE001A001, 0x4F26E000, 0x0009000B, 0xE101D629, +0x2610D436, 0xD7286541, 0x655DD128, 0xE001E20F, +0x26202752, 0x2102000B, 0x4F222FE6, 0x8523D21F, +0x2448640C, 0xD62D8B08, 0xE200D521, 0x84512621, +0x20499430, 0x8051A026, 0x60E0DE1D, 0x8D0BC840, +0x3427E201, 0xD1258922, 0x420BD225, 0xD5252141, +0xCB046052, 0x2502A00B, 0x89173427, 0xD722D21F, +0x2241470B, 0xE5FBD61F, 0x21596162, 0x84E12612, +0xB12DCB80, 0x60E080E1, 0xCB04D61C, 0x60602E00, +0x2600C93F, 0xE001D609, 0x2602A001, 0x4F26E000, +0x6EF6000B, 0x0000FF7F, 0x0020293D, 0x00202904, +0x00202910, 0x001E1100, 0x001E100C, 0x00202934, +0x001E1000, 0x001E1001, 0x00202AF4, 0x00202918, +0x00202920, 0x00202B62, 0x00202B66, 0x00202B72, +0x00202B8A, 0x00202B94, 0x0020291C, 0x0020292A, +0x00201AB6, 0x001E1108, 0x00201BC2, 0x001E1015, +0x6060D696, 0x8919C880, 0x6021D295, 0x8B158801, +0xE501D294, 0x30568524, 0xD1938910, 0xD493E203, +0x65412120, 0x655DE00B, 0xD5910656, 0xE702E40F, +0x25712140, 0xE001D78F, 0x2702000B, 0xE000000B, +0x4F222FE6, 0x84E1DE8C, 0x8934C880, 0x8554D585, +0x8F302008, 0xD7896103, 0x66728553, 0x650C6403, +0x620C8566, 0x8B263520, 0xD780D685, 0x644C651C, +0x27412651, 0xC84060E0, 0xD2828907, 0x0009420B, +0x6062D681, 0xA008CB04, 0xD1802602, 0x0009410B, +0xE5FBD67D, 0x24596462, 0xB0A12642, 0xD5750009, +0x2522E201, 0xD77A60E0, 0x2E00CB04, 0xC93F6070, +0xA0012700, 0xE0006023, 0x000B4F26, 0x2FA66EF6, +0x2FC62FB6, 0x2FE62FD6, 0xE240DA69, 0xDC6666A1, +0x3123616D, 0x62638900, 0x6ED36D2C, 0x4E2136D8, +0x4E212A61, 0xDB6CD46B, 0xE700A00F, 0x770166B2, +0x71026163, 0x65612B12, 0x71026613, 0x62612B12, +0x622D655D, 0x325C4228, 0x627C2422, 0x8BED32E3, +0xC90360D3, 0x8B108803, 0xED076EB2, 0x710261E3, +0x67132B12, 0x62E17102, 0x65712B12, 0x655D622D, +0x352C4528, 0xA00C2CD0, 0x88022452, 0xA0038B01, +0x8801E203, 0xE2018B05, 0x66B22C20, 0x677D6761, +0xEB0F2472, 0x6DA12CB0, 0x8B052DD8, 0xD445D24F, +0xE101EE00, 0x241222E2, 0x6DF66EF6, 0x6BF66CF6, +0x6AF6000B, 0x2FE62FD6, 0xE240DD3D, 0x616D66D1, +0x89003123, 0x672C6263, 0xDE433678, 0x2D617703, +0xD6404721, 0x472164E2, 0xE100A00E, 0x71016562, +0x24506253, 0x42197401, 0x74012420, 0x24504529, +0x45197401, 0x74012450, 0x3273621C, 0x42008BEE, +0x64D166E2, 0x362C4200, 0x8F062448, 0xDD332E62, +0xE500DE28, 0x2D52E701, 0x6EF62E72, 0x6DF6000B, +0x2FE62FD6, 0xEE014F22, 0xED0AA005, 0x64E3BCB6, +0x64E3BCBC, 0x62EC7E01, 0x8BF732D7, 0xEE01A005, +0x64E3BCBD, 0x64E3BCC3, 0x62EC7E01, 0x8BF732D7, +0x6EF64F26, 0x6DF6000B, 0x2FE62FD6, 0x7FFC4F22, +0x6060D61F, 0x89758801, 0xE101D41E, 0xD7128548, +0x650D2610, 0x45196070, 0x6659DD1B, 0x61D3626E, +0xC840262D, 0x74027102, 0x8D47D718, 0xD218666C, +0xE501DE0A, 0xA0312E22, 0x0000EE04, 0x001E1001, +0x0020292A, 0x00202904, 0x001E1100, 0x0020292E, +0x0020291C, 0x00202934, 0x001E1000, 0x00202920, +0x0020292C, 0x00201AB6, 0x001E1108, 0x00201BC2, +0x001E1015, 0x001E100C, 0x00202918, 0x00202938, +0x0020293C, 0x00202AF4, 0x00202B8A, 0x00202B96, +0x00202B06, 0x75016245, 0x71022121, 0x32E3625C, +0x60638BF8, 0xE60181D4, 0xE417D538, 0x3243626C, +0x6255891E, 0x27217601, 0x7702AFF8, 0xDE35D234, +0x2E22E501, 0xEE04A004, 0x75016245, 0x71022121, +0x32E3625C, 0x60638BF8, 0xE60181D4, 0xA004D52E, +0x6255E417, 0x27217601, 0x626C7702, 0x8BF83243, +0x2D21924B, 0xD72AD429, 0x2F126142, 0x6DF265F2, +0xC9806053, 0x60532700, 0x6103C960, 0x60538071, +0x65F26EF2, 0x4D19C903, 0x80724529, 0x451960DC, +0x4E298172, 0x62EC605C, 0x302C4018, 0x6D428173, +0x2FD22118, 0x62F26EF2, 0x421966F2, 0x656C4629, +0x602C66F2, 0x401864EC, 0x304C4629, 0x81744619, +0x4018606C, 0x8F07305C, 0xBCB58175, 0x620C0009, +0x89082228, 0x0009A00A, 0x88406013, 0xB00A8B03, +0xA0030009, 0xD60B0009, 0x2622E202, 0x4F267F04, +0x000B6EF6, 0x000B6DF6, 0x060A0009, 0x00202B36, +0x00202B34, 0x00202920, 0x00202B08, 0x001E100C, +0x00202904, 0x00202934, 0x7FFC4F22, 0x6620D27E, +0x8D082668, 0xD47D2F60, 0x420BD27D, 0x64F00009, +0xA0907F04, 0x7F044F26, 0x000B4F26, 0x000B0009, +0x2FE60009, 0xDE774F22, 0x60E0D677, 0xCBC0D477, +0x62602E00, 0xC803602C, 0x40218904, 0x70014021, +0x6603A002, 0x66034009, 0xD671616D, 0xE500A004, +0x75016262, 0x74042422, 0x3213625D, 0xD16D8BF8, +0x0009410B, 0xE401D66C, 0x84E22641, 0x80E2C9BF, +0x000B4F26, 0x2FE66EF6, 0xD5687FFC, 0x6250DE61, +0x642C84E2, 0xCB407404, 0x80E2614D, 0x44216413, +0xD7634421, 0xE600A004, 0x76016256, 0x27222F22, +0x3243626D, 0x60138BF8, 0x2008C903, 0x88038912, +0x88028905, 0x88018906, 0xA0088907, 0xE0070009, +0x8078A005, 0xA002E003, 0xE0018078, 0x62528078, +0x27222F22, 0xD650E00F, 0x60618078, 0x8B018801, +0x2621E200, 0x6060D64F, 0x2600CB08, 0xC93F60E0, +0x7F042E00, 0x6EF6000B, 0x6021D247, 0x8D188801, +0xD2466143, 0x22106053, 0x60638021, 0xD4468121, +0xE500A007, 0x027C605D, 0x364C6603, 0x26207001, +0x625D6503, 0x3213611C, 0xD6408BF4, 0xC9BF6060, +0x000B2600, 0x2FD60009, 0x4F222FE6, 0x60437FFC, +0x8D02C820, 0xBF6A6E43, 0x60E30009, 0x8901C810, +0x0009BF67, 0xC84060E3, 0xBF8C8901, 0x60E30009, +0x8929C801, 0x60D0DD32, 0x8D03C802, 0xD6312F00, +0x0009460B, 0xC80460F0, 0xD62F8902, 0x0009460B, +0x602362F0, 0x8902C880, 0xC97F60D0, 0x60232D00, +0x8902C801, 0x420BD229, 0xD5290009, 0x88026052, +0xD2288B03, 0xA005E604, 0x88012260, 0xD2258B02, +0x2260E601, 0x2522E200, 0xC88060E3, 0xD2228916, +0x60E36E20, 0x8902C802, 0x420BD220, 0x60E30009, +0x8902C804, 0x420BD21E, 0x60E30009, 0x8905C808, +0x7F04D21C, 0x6EF64F26, 0x6DF6422B, 0x4F267F04, +0x000B6EF6, 0x00006DF6, 0x001E1020, 0x002029D0, +0x00200E2A, 0x001E1015, 0x001E10BF, 0x00117D00, +0x001E10FC, 0x002000F8, 0x00202930, 0x00117D80, +0x001E10F8, 0x001E10AE, 0x00117D84, 0x001E1017, +0x001E1021, 0x0020105C, 0x0020107E, 0x00201608, +0x00202934, 0x001E100B, 0x001E1028, 0x002010AE, +0x002010C0, 0x002010CC, 0xD6A8644C, 0x346C74FF, +0x2450000B, 0x644CD6A6, 0x000B346C, 0xD6A52450, +0x346C644C, 0x2450000B, 0x616D625C, 0x41194208, +0x60194208, 0x644C4200, 0x324C670E, 0x207DD19E, +0xC90F4200, 0x000B321C, 0x67632200, 0x4208625C, +0x42004208, 0x324C644C, 0x4200D198, 0x000B321C, +0x2FE62270, 0x614C4F12, 0x4100D493, 0x6710314C, +0x2729E29F, 0x65736E53, 0x4719676D, 0x672E6279, +0x4221227D, 0x42214221, 0x7601662C, 0xE4014608, +0x34E84608, 0x644C4600, 0x0E1A0467, 0x215025EB, +0x000B4F16, 0x4F226EF6, 0xD2857FE8, 0x88016021, +0xD2848B7B, 0x26686621, 0xD2838B77, 0x26686621, +0xE50F8B73, 0xE401BFA0, 0xBFA3E501, 0xE586E400, +0xE400655C, 0x2F50BFA3, 0xBFA0E401, 0xE602E506, +0x60634618, 0x81F2E401, 0x6543BF9E, 0xE40185F2, +0xBFAA6543, 0x85F26603, 0x6543E401, 0x6603BFB1, +0xE40265F0, 0x6053756C, 0x80F8BF7E, 0xBF81E402, +0x84F8E512, 0x7090E402, 0x6503BF81, 0x4618E602, +0x81F66063, 0xBF7FE402, 0x85F6E500, 0x6603E402, +0xE500BF8B, 0xE40285F6, 0xBF926603, 0xE5FEE500, +0xE010655C, 0xBF5FE403, 0xE5130F54, 0xE40EBF62, +0x05FCE010, 0xBF62E40E, 0xE5007585, 0xBF63E403, +0xE500E640, 0xBF70E403, 0xE500E640, 0xBF78E403, +0xE5FFE640, 0xE014655C, 0xBF45E404, 0xE40F0F54, +0xE504BF48, 0x05FCE014, 0xBF48E40F, 0xE5017584, +0xBF49E640, 0xE501E404, 0xBF56E640, 0xE501E404, +0xE404E640, 0xAF5C7F18, 0x7F184F26, 0x000B4F26, +0x4F220009, 0xD2427FF0, 0x88016021, 0xD2418B71, +0x26686621, 0xD2408B6D, 0x26686621, 0xE50F8B69, +0xE401BF1A, 0xBF1DE501, 0xE586E400, 0xE400655C, +0x2F50BF1D, 0xBF1AE401, 0xE401E506, 0xBF1B6543, +0xE401E640, 0xBF286543, 0xE401E640, 0xBF306543, +0x65F0E640, 0x756CE402, 0xBEFD6053, 0xE40280F4, +0xE512BF00, 0xE40284F4, 0xBF007090, 0xE6406503, +0xBF01E402, 0xE640E500, 0xBF0EE402, 0xE640E500, +0xBF16E402, 0xE5FEE500, 0x6053655C, 0xBEE3E403, +0xE51380F8, 0xE40EBEE6, 0xE40E84F8, 0xBEE67085, +0xE5006503, 0xBEE7E640, 0xE500E403, 0xBEF4E640, +0xE500E403, 0xBEFCE640, 0xE5FFE403, 0x6053655C, +0xBEC9E404, 0xE40F80FC, 0xE504BECC, 0xE40F84FC, +0xBECC7083, 0xE5016503, 0xBECDE640, 0xE501E404, +0xBEDAE640, 0xE501E404, 0xE404E640, 0xAEE07F10, +0x7F104F26, 0x000B4F26, 0x00000009, 0x001E1030, +0x001E1080, 0x001E1090, 0x001E103F, 0x001E103E, +0x0020292A, 0x0020292C, 0x0020292E, 0x0009000B, +0x666CE680, 0x6563D2A0, 0x7540E700, 0x6473422B, +0x2FB62FA6, 0x2FD62FC6, 0x4F222FE6, 0x4C18EC01, +0xDA9BDB9A, 0x65B252B1, 0x89223520, 0xC9036051, +0x891E8801, 0xD197DE95, 0x64E3410B, 0x85036503, +0x670D66A2, 0xDD943762, 0xD494890A, 0x420BD294, +0xD1940009, 0xE701D494, 0x21724D0B, 0x0009AFE2, +0x420BD292, 0xD69264E3, 0x4D0BD492, 0xAFD926C2, +0x4F260009, 0x6DF66EF6, 0x6BF66CF6, 0x6AF6000B, +0x7FF44F22, 0xE6818546, 0x85472F01, 0x81F1666C, +0xD27D8548, 0x854281F2, 0x81F367F3, 0xE40C8543, +0x605381F4, 0x81F56563, 0x7540420B, 0x4F267F0C, +0x0009000B, 0x2F962F86, 0x2FB62FA6, 0x2FD62FC6, +0x4F222FE6, 0xE2007FEC, 0xA0CBDB7B, 0x6A132F21, +0x4A08D27A, 0xDE7AE001, 0x4A00420B, 0x7E303AEC, +0x1F021FE1, 0x66B2DD77, 0x362052B1, 0xA0B58B01, +0x60610009, 0x8801C903, 0xA0AF8B01, 0x85610009, +0x8974C801, 0xEE105163, 0xDC638512, 0xC9036603, +0x85136403, 0x4021600D, 0xC93F4021, 0x8D2030E3, +0xD7696503, 0x62704408, 0x44004408, 0x22284500, +0x345C8F0C, 0x6043D265, 0x625D052D, 0x60294219, +0x207D670E, 0x605C81F6, 0x81F8A00B, 0x6043D260, +0x685D052D, 0x60894819, 0x209D690E, 0x605C81F6, +0xD75C81F8, 0x22286272, 0xE0FF8902, 0x81F8600C, +0xEEFF85F8, 0x6EEC650D, 0x8B0F35E0, 0x4E0BDE45, +0x540364B3, 0xBF7BE502, 0xD4536803, 0x410BD147, +0xD7526583, 0xD452E901, 0x2792A020, 0x26E9EEFC, +0x81126063, 0x946E8513, 0x81132049, 0x45088512, +0x62036953, 0xE50885F6, 0x8112202B, 0x45188513, +0x8113209B, 0xD4478514, 0x8114205B, 0x851161B2, +0x811120E9, 0x602162B2, 0x2201CB01, 0x00094C0B, +0x56F160B2, 0xCB0152F2, 0xAF7C2A02, 0x85612622, +0xC802DC3A, 0xD938D227, 0x8D0FD82C, 0x420B64B3, +0x65030009, 0x480B6493, 0xE8015E03, 0x85EF2C82, +0x650DD635, 0x64D3460B, 0x0009AF65, 0x0009420B, +0x6E035403, 0xE5088544, 0x45186103, 0x31502159, +0xBF258B03, 0xA007E501, 0x85410009, 0x620DD52B, +0x89012258, 0xE500BF1C, 0x480B6493, 0xD42865E3, +0xE801D611, 0x2C82460B, 0x0009AF45, 0x7B0862F1, +0x2F217201, 0xEE0362F1, 0x31E7612D, 0xAF2E8901, +0x7F140009, 0x6EF64F26, 0x6CF66DF6, 0x6AF66BF6, +0x000B69F6, 0xFE0368F6, 0x002018B8, 0x002028E4, +0x002028EC, 0x00200AE0, 0x00200E2A, 0x002028B4, +0x00200B62, 0x001E2130, 0x00202AD4, 0x00200AFE, +0x001C3D30, 0x00202AD8, 0x002028C4, 0x00202034, +0x001C3D00, 0x00202AE4, 0x00202AF0, 0x002029D4, +0x00202A54, 0x00202900, 0x002028BC, 0x001E212C, +0x00202ADC, 0x00202AE0, 0x00200E8A, 0x00008000, +0x00202AEC, 0x4F222FE6, 0x6E22D20D, 0xC84060E3, +0x22E28D02, 0x0009BE7A, 0x4218E240, 0x89012E28, +0x0009BE76, 0xC80560E3, 0xBECB8901, 0x60E30009, +0x8902C802, 0xAE734F26, 0x4F266EF6, 0x6EF6000B, +0x001C3510, 0x080A0C0E, 0x00020406, 0x1A1C1E20, +0x12141618, 0x2E303234, 0x26282A2C, 0x3A3C3E40, +0x6C625648, 0x41112F26, 0xE2208F18, 0x890B3123, +0x321CD204, 0xD1026220, 0x412B312C, 0x00090009, +0x0020205E, 0x00202014, 0x000BE000, 0x400062F6, +0x40004000, 0x40004000, 0x40004000, 0x62F6000B, +0x40004000, 0x40004000, 0x40004000, 0x40184000, +0x62F6000B, 0x40004000, 0x40004000, 0x40004000, +0x40284000, 0x62F6000B, 0x40004000, 0x40184000, +0x000B4028, 0xC90F62F6, 0x40054005, 0x40054005, +0x62F6000B, 0x4005C907, 0x40054005, 0x62F6000B, +0x4005C903, 0x000B4005, 0xC90162F6, 0x000B4005, +0x000062F6, 0x080A0C0E, 0x00020406, 0x1A1C1E20, +0x12141618, 0x2E303234, 0x26282A2C, 0x3A3C3E40, +0x6C625648, 0x41112F26, 0xE2208F18, 0x890B3123, +0x321CD204, 0xD1026220, 0x412B312C, 0x00090009, +0x0020211E, 0x002020D4, 0x000BE000, 0x400162F6, +0x40014001, 0x40014001, 0x40014001, 0x62F6000B, +0x40014001, 0x40014001, 0x40014001, 0x40194001, +0x62F6000B, 0x40014001, 0x40014001, 0x40014001, +0x40294001, 0x62F6000B, 0x40014001, 0x40194001, +0x000B4029, 0x400462F6, 0x40044004, 0xC90F4004, +0x62F6000B, 0x40044004, 0xC9074004, 0x62F6000B, +0x40044004, 0x000BC903, 0x400462F6, 0x000BC901, +0x000062F6, 0x3622E218, 0x67438F12, 0x0009A004, +0x76FF6254, 0x74012420, 0xC8036053, 0x60438BF8, +0x8902C803, 0x422BD22B, 0xD22B0009, 0x0009422B, +0x2FE66473, 0x8D4A3450, 0x27786763, 0x62438947, +0x227B225B, 0xC9016023, 0x8D203452, 0x2EE86E03, +0x60238B15, 0x8B08C803, 0x47096643, 0x47106256, +0x8FFB2622, 0xA0327604, 0x47010009, 0x61436673, +0x46106255, 0x8FFB2121, 0xA0287102, 0x66430009, +0x47106254, 0x8FFB2620, 0xA0207601, 0x61430009, +0x2EE8357C, 0x8F15317C, 0x60236653, 0x8B07C803, +0x76FC4709, 0x47106262, 0x21268FFB, 0x0009A00F, +0x65634701, 0x75FE6673, 0x46106251, 0x21258FFB, +0x0009A005, 0x626076FF, 0x8FFB4710, 0x60432124, +0x6EF6000B, 0x00202306, 0x002027B2, 0xE21E2FE6, +0x67633626, 0x8D1B6153, 0x3E106E43, 0x3E128916, +0x65E38908, 0x3672E600, 0x62148910, 0x25207601, +0x7501AFF9, 0x317C64E3, 0x6513347C, 0xE600A004, +0x625075FF, 0x24247601, 0x8BF93672, 0x60E3A011, +0x890831E2, 0x327C6213, 0x8B0432E6, 0x651364E3, +0xA0086673, 0xD28F6EF6, 0x651364E3, 0x422B6673, +0x000B6EF6, 0xE2046EF6, 0x67433622, 0x8F10356C, +0xA004346C, 0x75FF0009, 0x76FF6250, 0x60532424, +0x8BF8C803, 0xC8036043, 0xA1058901, 0xA2770009, +0xA2990009, 0x2FB60009, 0x2FD62FC6, 0x7FE42FE6, +0x6C636043, 0x66521F62, 0xC9037504, 0x1F516E53, +0x45086503, 0xE1FC6D43, 0x2D194500, 0x1F732558, +0x1F651F44, 0x2FD28D0B, 0x88086053, 0x88108923, +0x8818895B, 0xA0898B01, 0xA0BD0009, 0x62630009, +0x2D22E600, 0x7CFC7D04, 0xEB10A00D, 0xE60064E6, +0x7CF065E6, 0x62E261E6, 0x1D512D42, 0x1D231D12, +0x7E047D10, 0x3CB21FE1, 0x1F6589F0, 0x2FD21FC2, +0xA0A11FE6, 0x64D21FD4, 0x44286263, 0x44294418, +0x42184419, 0x4629242B, 0x2D424619, 0x65637D04, +0xA0217CFD, 0x67E6EB10, 0x62E67CF0, 0x64E66673, +0x256B4618, 0x2D5261E2, 0x65234729, 0x45184719, +0x4229275B, 0x42191D71, 0x47186743, 0x4429227B, +0x44196713, 0x247B4718, 0x1D431D22, 0x41194129, +0x65137D10, 0x1FE17E04, 0x89DC3CB2, 0x1FE67EFF, +0x1FC21F55, 0xA0672FD2, 0x6CF21FD4, 0x66C257F5, +0x46286273, 0x42284629, 0x2C62262B, 0x7C045DF2, +0x7DFE4729, 0xA01CEB10, 0x65E65EF1, 0x66E66273, +0x47286753, 0x6763227B, 0x452961E6, 0x257B4728, +0x2C2264E6, 0x65131C51, 0x45284629, 0x1C62265B, +0x41296643, 0x216B4628, 0x44291C13, 0x67437C10, +0x3DB27DF0, 0x1FD289E1, 0x7EFEA034, 0x51F56CF2, +0x621366C2, 0x42284618, 0x42184619, 0x2C62262B, +0x7C045DF2, 0x7DFF4119, 0xA01FEB10, 0x65E65EF1, +0x64E67DF0, 0x42286253, 0x421867E6, 0x66E6212B, +0x61432C12, 0x45194128, 0x251B4118, 0x65731C51, +0x44194528, 0x245B4518, 0x64631C42, 0x47194428, +0x274B4418, 0x46191C73, 0x61637C10, 0x89DE3DB2, +0x7EFD1FD2, 0x1FC41FE6, 0x5DF2E704, 0xA00D5EF6, +0x62E451F4, 0x66E47DFC, 0x65E464E4, 0x71012120, +0x71012160, 0x71012140, 0x71012150, 0x89F03D72, +0x66D357F3, 0x641365E3, 0x6EF67F1C, 0x6CF66DF6, +0x6BF6A190, 0x00202194, 0x2FC62FB6, 0x2FE62FD6, +0x60437FE4, 0x6C63C903, 0x66031F62, 0x460875FC, +0x61526E43, 0x4600E2FC, 0x26682E29, 0x1F441F73, +0x1F516D53, 0x8D0B1F15, 0x60632FE2, 0x891F8808, +0x89538810, 0x8B018818, 0x0009A081, 0x0009A0B9, +0xEB10A00D, 0x52D37DF0, 0x54D156D2, 0x2E1665D2, +0x2E662E26, 0x2E427EFC, 0x1FD16153, 0x3CB27CF0, +0x7D0489F0, 0x1F151FD6, 0x2FE21FC2, 0x1FE4A0A1, +0x621366E2, 0x42294619, 0x42194618, 0x2E62262B, +0x7CFF4118, 0xEB10A021, 0x54D37DF0, 0x624357D2, +0x42194229, 0x55D1212B, 0x2E1666D2, 0x41296173, +0x41194418, 0x2E46241B, 0x44296453, 0x44194718, +0x2E76274B, 0x47296763, 0x47194518, 0x257B7EFC, +0x46182E52, 0x1FD16163, 0x3CB27CF0, 0x7D0389DC, +0x1F151FD6, 0x2FE21FC2, 0x1FE4A06B, 0x57F56EF2, +0x627366E2, 0x46284629, 0x262B4229, 0x2E625CF2, +0x7CFE4728, 0xA01BEB10, 0x7DF05DF1, 0x55D251D3, +0x46296613, 0x54D1276B, 0x2E7662D2, 0x41286753, +0x217B4729, 0x61432E16, 0x41294528, 0x2E56251B, +0x44286523, 0x245B4529, 0x42282E46, 0x7CF06723, +0x89E23CB2, 0x1FD67D02, 0xA03A1FC2, 0x67F21FE4, +0x657251F5, 0x45296213, 0x45284519, 0x42194518, +0x5CF2252B, 0x41282752, 0x7CFD4118, 0xA022EB10, +0x7DF05DF1, 0x54D256D3, 0x45196563, 0x52D14628, +0x4618215B, 0x6ED26543, 0x45192716, 0x265B4428, +0x65436163, 0x45186423, 0x42284419, 0x4218254B, +0x271664E3, 0x44196623, 0x264B2756, 0x4E282766, +0x61E34E18, 0x3CB27CF0, 0x7D0189DB, 0x1FC21FD6, +0xE7041F74, 0x51F45DF2, 0x5EF6A00D, 0x84E27EFC, +0x620364E0, 0x7DFC84E1, 0x84E36503, 0x21646603, +0x21542124, 0x3D722144, 0x57F389F0, 0x641366D3, +0x7F1C65E3, 0x6DF66EF6, 0xA09D6CF6, 0x2F866BF6, +0x2FA62F96, 0x2FC62FB6, 0x2FE62FD6, 0x614374E0, +0x6A636873, 0x6B56E920, 0x6C567AE0, 0x6D567120, +0x6E563A92, 0x64566756, 0x62566656, 0x11C121B2, +0x11E311D2, 0x11451174, 0x8DEC1166, 0x71201127, +0x6613A004, 0x7AFF6254, 0x76012620, 0x8BF92AA8, +0x6EF66083, 0x6CF66DF6, 0x6AF66BF6, 0x000B69F6, +0x2F8668F6, 0x2FA62F96, 0x2FC62FB6, 0x2FE62FD6, +0x6A636873, 0x75E0E920, 0x56565257, 0x57545155, +0x5D525E53, 0x6B525C51, 0x24662426, 0x24762416, +0x7AE024E6, 0x24C624D6, 0x8DEC3A92, 0x66A324B6, +0x6EF66783, 0x6CF66DF6, 0x6AF66BF6, 0xA04369F6, +0x2FE668F6, 0xC8046063, 0x8D046E63, 0x62166153, +0x24227EFC, 0x60E37404, 0x8908C818, 0x71046513, +0x62526616, 0x24227EF8, 0xAFF41461, 0xE2047408, +0x65133E22, 0x66E38D02, 0x6EF6A01C, 0x6EF6AF87, +0xC8046063, 0x61638D04, 0x625275FC, 0x242671FC, +0xC8186013, 0x75F88906, 0x66525251, 0x24662426, +0x71F8AFF6, 0x3122E204, 0x66138F02, 0x0009AFA1, +0x0009A00A, 0x0009A004, 0x76FF6254, 0x74012420, +0x8BF92668, 0x6073000B, 0x0009A004, 0x625075FF, +0x242476FF, 0x8BF92668, 0x6073000B, 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, +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, +0x544F0D0A, 0x46205355, 0x00003A57, 0x2072614D, +0x32203232, 0x20373030, 0x353A3731, 0x37333A32, +0x00000000, 0x00000D0A, 0x00000043, 0x61766E49, +0x2064696C, 0x72657375, 0x20726F20, 0x2079656B, +0x00214449, 0x6E6B6E55, 0x206E776F, 0x6D6D6F63, +0x3D646E61, 0x00000000, 0x61437748, 0x7262696C, +0x6F697461, 0x6620206E, 0x0A6C6961, 0x0000000D, +0x73696F4E, 0x61432065, 0x7262696C, 0x6F697461, +0x6166206E, 0x21216C69, 0x00000D0A, 0x00000D0A, +0x00000042, 0x000000FF, 0x00020001, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x010E010D, 0x00020003, 0x01090108, +0x0002010A, 0x00030002, 0x02020201, 0x02040203, +0x02060205, 0x02080207, 0x020A0209, 0x020C020B, +0x020E020D, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x010E010D, 0x00FF010F, 0x01090108, +0x010B010A, 0x00030002, 0x02020201, 0x02040203, +0x02060205, 0x02080207, 0x020A0209, 0x020C020B, +0x020E020D, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00000072, 0x00205220, 0x00000046, +0x00000059, 0x73204142, 0x003D7165, 0x00000074, +0x00000000, 0x02000112, 0x40FFFFFF, 0x12210ACE, +0x20104890, 0x02090100, 0x0101002E, 0x09FA8000, +0x04000004, 0x000000FF, 0x02010507, 0x07000200, +0x00028205, 0x05070002, 0x00400383, 0x04050701, +0x01004003, 0x002E0209, 0x80000101, 0x000409FA, +0x00FF0400, 0x05070000, 0x00400201, 0x82050700, +0x00004002, 0x03830507, 0x07010040, 0x40030405, +0x03040100, 0x030C0409, 0x0079005A, 0x00410044, +0x03180053, 0x00530055, 0x00320042, 0x0030002E, +0x00570020, 0x0041004C, 0x0000004E, 0x00000000, +0x00000000, 0x00000709, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, }; + +const u32_t zcFwImageSize=11204; --- linux-2.6.28.orig/drivers/staging/otus/hal/hpreg.h +++ linux-2.6.28/drivers/staging/otus/hal/hpreg.h @@ -0,0 +1,524 @@ +/* + * Copyright (c) 2000-2005 ZyDAS Technology Corporation + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* Module Name : hpreg.h */ +/* */ +/* Abstract */ +/* This module contains Regulatory Table definitions. */ +/* */ +/* NOTES */ +/* None */ +/* */ +/************************************************************************/ + +#ifndef _HPREG_H +#define _HPREG_H + +typedef u16_t HAL_CTRY_CODE; /* country code */ +typedef u16_t HAL_REG_DOMAIN; /* regulatory domain code */ +typedef enum { + AH_FALSE = 0, /* NB: lots of code assumes false is zero */ + AH_TRUE = 1, +} HAL_BOOL; + + +/* + * Country/Region Codes from MS WINNLS.H + * Numbering from ISO 3166 + */ +enum CountryCode { + CTRY_ALBANIA = 8, /* Albania */ + CTRY_ALGERIA = 12, /* Algeria */ + CTRY_ARGENTINA = 32, /* Argentina */ + CTRY_ARMENIA = 51, /* Armenia */ + CTRY_AUSTRALIA = 36, /* Australia */ + CTRY_AUSTRIA = 40, /* Austria */ + CTRY_AZERBAIJAN = 31, /* Azerbaijan */ + CTRY_BAHRAIN = 48, /* Bahrain */ + CTRY_BELARUS = 112, /* Belarus */ + CTRY_BELGIUM = 56, /* Belgium */ + CTRY_BELIZE = 84, /* Belize */ + CTRY_BOLIVIA = 68, /* Bolivia */ + CTRY_BOSNIA = 70, /* Bosnia */ + CTRY_BRAZIL = 76, /* Brazil */ + CTRY_BRUNEI_DARUSSALAM = 96, /* Brunei Darussalam */ + CTRY_BULGARIA = 100, /* Bulgaria */ + CTRY_CANADA = 124, /* Canada */ + CTRY_CHILE = 152, /* Chile */ + CTRY_CHINA = 156, /* People's Republic of China */ + CTRY_COLOMBIA = 170, /* Colombia */ + CTRY_COSTA_RICA = 188, /* Costa Rica */ + CTRY_CROATIA = 191, /* Croatia */ + CTRY_CYPRUS = 196, /* Cyprus */ + CTRY_CZECH = 203, /* Czech Republic */ + CTRY_DENMARK = 208, /* Denmark */ + CTRY_DOMINICAN_REPUBLIC = 214, /* Dominican Republic */ + CTRY_ECUADOR = 218, /* Ecuador */ + CTRY_EGYPT = 818, /* Egypt */ + CTRY_EL_SALVADOR = 222, /* El Salvador */ + CTRY_ESTONIA = 233, /* Estonia */ + CTRY_FAEROE_ISLANDS = 234, /* Faeroe Islands */ + CTRY_FINLAND = 246, /* Finland */ + CTRY_FRANCE = 250, /* France */ + CTRY_FRANCE2 = 255, /* France2 */ + CTRY_GEORGIA = 268, /* Georgia */ + CTRY_GERMANY = 276, /* Germany */ + CTRY_GREECE = 300, /* Greece */ + CTRY_GUATEMALA = 320, /* Guatemala */ + CTRY_HONDURAS = 340, /* Honduras */ + CTRY_HONG_KONG = 344, /* Hong Kong S.A.R., P.R.C. */ + CTRY_HUNGARY = 348, /* Hungary */ + CTRY_ICELAND = 352, /* Iceland */ + CTRY_INDIA = 356, /* India */ + CTRY_INDONESIA = 360, /* Indonesia */ + CTRY_IRAN = 364, /* Iran */ + CTRY_IRAQ = 368, /* Iraq */ + CTRY_IRELAND = 372, /* Ireland */ + CTRY_ISRAEL = 376, /* Israel */ + CTRY_ISRAEL2 = 377, /* Israel2 */ + CTRY_ITALY = 380, /* Italy */ + CTRY_JAMAICA = 388, /* Jamaica */ + CTRY_JAPAN = 392, /* Japan */ + CTRY_JAPAN1 = 393, /* Japan (JP1) */ + CTRY_JAPAN2 = 394, /* Japan (JP0) */ + CTRY_JAPAN3 = 395, /* Japan (JP1-1) */ + CTRY_JAPAN4 = 396, /* Japan (JE1) */ + CTRY_JAPAN5 = 397, /* Japan (JE2) */ + CTRY_JAPAN6 = 399, /* Japan (JP6) */ + + CTRY_JAPAN7 = 4007, /* Japan (J7) */ + CTRY_JAPAN8 = 4008, /* Japan (J8) */ + CTRY_JAPAN9 = 4009, /* Japan (J9) */ + + CTRY_JAPAN10 = 4010, /* Japan (J10) */ + CTRY_JAPAN11 = 4011, /* Japan (J11) */ + CTRY_JAPAN12 = 4012, /* Japan (J12) */ + + CTRY_JAPAN13 = 4013, /* Japan (J13) */ + CTRY_JAPAN14 = 4014, /* Japan (J14) */ + CTRY_JAPAN15 = 4015, /* Japan (J15) */ + + CTRY_JAPAN16 = 4016, /* Japan (J16) */ + CTRY_JAPAN17 = 4017, /* Japan (J17) */ + CTRY_JAPAN18 = 4018, /* Japan (J18) */ + + CTRY_JAPAN19 = 4019, /* Japan (J19) */ + CTRY_JAPAN20 = 4020, /* Japan (J20) */ + CTRY_JAPAN21 = 4021, /* Japan (J21) */ + + CTRY_JAPAN22 = 4022, /* Japan (J22) */ + CTRY_JAPAN23 = 4023, /* Japan (J23) */ + CTRY_JAPAN24 = 4024, /* Japan (J24) */ + + CTRY_JAPAN25 = 4025, /* Japan (J25) */ + CTRY_JAPAN26 = 4026, /* Japan (J26) */ + CTRY_JAPAN27 = 4027, /* Japan (J27) */ + + CTRY_JAPAN28 = 4028, /* Japan (J28) */ + CTRY_JAPAN29 = 4029, /* Japan (J29) */ + CTRY_JAPAN30 = 4030, /* Japan (J30) */ + + CTRY_JAPAN31 = 4031, /* Japan (J31) */ + CTRY_JAPAN32 = 4032, /* Japan (J32) */ + CTRY_JAPAN33 = 4033, /* Japan (J33) */ + + CTRY_JAPAN34 = 4034, /* Japan (J34) */ + CTRY_JAPAN35 = 4035, /* Japan (J35) */ + CTRY_JAPAN36 = 4036, /* Japan (J36) */ + + CTRY_JAPAN37 = 4037, /* Japan (J37) */ + CTRY_JAPAN38 = 4038, /* Japan (J38) */ + CTRY_JAPAN39 = 4039, /* Japan (J39) */ + + CTRY_JAPAN40 = 4040, /* Japan (J40) */ + CTRY_JAPAN41 = 4041, /* Japan (J41) */ + CTRY_JAPAN42 = 4042, /* Japan (J42) */ + CTRY_JAPAN43 = 4043, /* Japan (J43) */ + CTRY_JAPAN44 = 4044, /* Japan (J44) */ + CTRY_JAPAN45 = 4045, /* Japan (J45) */ + CTRY_JAPAN46 = 4046, /* Japan (J46) */ + CTRY_JAPAN47 = 4047, /* Japan (J47) */ + CTRY_JAPAN48 = 4048, /* Japan (J48) */ + CTRY_JAPAN49 = 4049, /* Japan (J49) */ + + CTRY_JAPAN50 = 4050, /* Japan (J50) */ + CTRY_JAPAN51 = 4051, /* Japan (J51) */ + CTRY_JAPAN52 = 4052, /* Japan (J52) */ + CTRY_JAPAN53 = 4053, /* Japan (J53) */ + CTRY_JAPAN54 = 4054, /* Japan (J54) */ + + CTRY_JORDAN = 400, /* Jordan */ + CTRY_KAZAKHSTAN = 398, /* Kazakhstan */ + CTRY_KENYA = 404, /* Kenya */ + CTRY_KOREA_NORTH = 408, /* North Korea */ + CTRY_KOREA_ROC = 410, /* South Korea */ + CTRY_KOREA_ROC2 = 411, /* South Korea */ + CTRY_KOREA_ROC3 = 412, /* South Korea */ + CTRY_KUWAIT = 414, /* Kuwait */ + CTRY_LATVIA = 428, /* Latvia */ + CTRY_LEBANON = 422, /* Lebanon */ + CTRY_LIBYA = 434, /* Libya */ + CTRY_LIECHTENSTEIN = 438, /* Liechtenstein */ + CTRY_LITHUANIA = 440, /* Lithuania */ + CTRY_LUXEMBOURG = 442, /* Luxembourg */ + CTRY_MACAU = 446, /* Macau */ + CTRY_MACEDONIA = 807, /* the Former Yugoslav Republic of Macedonia */ + CTRY_MALAYSIA = 458, /* Malaysia */ + CTRY_MALTA = 470, /* Malta */ + CTRY_MEXICO = 484, /* Mexico */ + CTRY_MONACO = 492, /* Principality of Monaco */ + CTRY_MOROCCO = 504, /* Morocco */ + CTRY_NETHERLANDS = 528, /* Netherlands */ + CTRY_NETHERLANDS_ANT = 530, /* Netherlands-Antellis */ + CTRY_NEW_ZEALAND = 554, /* New Zealand */ + CTRY_NICARAGUA = 558, /* Nicaragua */ + CTRY_NORWAY = 578, /* Norway */ + CTRY_OMAN = 512, /* Oman */ + CTRY_PAKISTAN = 586, /* Islamic Republic of Pakistan */ + CTRY_PANAMA = 591, /* Panama */ + CTRY_PARAGUAY = 600, /* Paraguay */ + CTRY_PERU = 604, /* Peru */ + CTRY_PHILIPPINES = 608, /* Republic of the Philippines */ + CTRY_POLAND = 616, /* Poland */ + CTRY_PORTUGAL = 620, /* Portugal */ + CTRY_PUERTO_RICO = 630, /* Puerto Rico */ + CTRY_QATAR = 634, /* Qatar */ + CTRY_ROMANIA = 642, /* Romania */ + CTRY_RUSSIA = 643, /* Russia */ + CTRY_SAUDI_ARABIA = 682, /* Saudi Arabia */ + CTRY_SERBIA_MONT = 891, /* Serbia and Montenegro */ + CTRY_SINGAPORE = 702, /* Singapore */ + CTRY_SLOVAKIA = 703, /* Slovak Republic */ + CTRY_SLOVENIA = 705, /* Slovenia */ + CTRY_SOUTH_AFRICA = 710, /* South Africa */ + CTRY_SPAIN = 724, /* Spain */ + CTRY_SRILANKA = 144, /* Srilanka */ + CTRY_SWEDEN = 752, /* Sweden */ + CTRY_SWITZERLAND = 756, /* Switzerland */ + CTRY_SYRIA = 760, /* Syria */ + CTRY_TAIWAN = 158, /* Taiwan */ + CTRY_THAILAND = 764, /* Thailand */ + CTRY_TRINIDAD_Y_TOBAGO = 780, /* Trinidad y Tobago */ + CTRY_TUNISIA = 788, /* Tunisia */ + CTRY_TURKEY = 792, /* Turkey */ + CTRY_UAE = 784, /* U.A.E. */ + CTRY_UKRAINE = 804, /* Ukraine */ + CTRY_UNITED_KINGDOM = 826, /* United Kingdom */ + CTRY_UNITED_STATES = 840, /* United States */ + CTRY_UNITED_STATES_FCC49 = 842, /* United States (Public Safety)*/ + CTRY_URUGUAY = 858, /* Uruguay */ + CTRY_UZBEKISTAN = 860, /* Uzbekistan */ + CTRY_VENEZUELA = 862, /* Venezuela */ + CTRY_VIET_NAM = 704, /* Viet Nam */ + CTRY_YEMEN = 887, /* Yemen */ + CTRY_ZIMBABWE = 716 /* Zimbabwe */ +}; + +/* Enumerated Regulatory Domain Information 8 bit values indicate that + * the regdomain is really a pair of unitary regdomains. 12 bit values + * are the real unitary regdomains and are the only ones which have the + * frequency bitmasks and flags set. + */ +enum EnumRd { + /* + * The following regulatory domain definitions are + * found in the EEPROM. Each regulatory domain + * can operate in either a 5GHz or 2.4GHz wireless mode or + * both 5GHz and 2.4GHz wireless modes. + * In general, the value holds no special + * meaning and is used to decode into either specific + * 2.4GHz or 5GHz wireless mode for that particular + * regulatory domain. + */ + NO_ENUMRD = 0x00, + NULL1_WORLD = 0x03, /* For 11b-only countries (no 11a allowed) */ + NULL1_ETSIB = 0x07, /* Israel */ + NULL1_ETSIC = 0x08, + FCC1_FCCA = 0x10, /* USA */ + FCC1_WORLD = 0x11, /* Hong Kong */ + FCC4_FCCA = 0x12, /* USA - Public Safety */ + FCC5_FCCA = 0x13, /* USA - with no DFS (UNII-1 + UNII-3 only) */ + FCC6_FCCA = 0x14, /* Canada */ + + FCC2_FCCA = 0x20, /* Canada */ + FCC2_WORLD = 0x21, /* Australia & HK */ + FCC2_ETSIC = 0x22, + FCC6_WORLD = 0x23, /* Australia */ + + FRANCE_RES = 0x31, /* Legacy France for OEM */ + FCC3_FCCA = 0x3A, /* USA & Canada w/5470 band, 11h, DFS enabled */ + FCC3_WORLD = 0x3B, /* USA & Canada w/5470 band, 11h, DFS enabled */ + + ETSI1_WORLD = 0x37, + ETSI3_ETSIA = 0x32, /* France (optional) */ + ETSI2_WORLD = 0x35, /* Hungary & others */ + ETSI3_WORLD = 0x36, /* France & others */ + ETSI4_WORLD = 0x30, + ETSI4_ETSIC = 0x38, + ETSI5_WORLD = 0x39, + ETSI6_WORLD = 0x34, /* Bulgaria */ + ETSI_RESERVED = 0x33, /* Reserved (Do not used) */ + + MKK1_MKKA = 0x40, /* Japan (JP1) */ + MKK1_MKKB = 0x41, /* Japan (JP0) */ + APL4_WORLD = 0x42, /* Singapore */ + MKK2_MKKA = 0x43, /* Japan with 4.9G channels */ + APL_RESERVED = 0x44, /* Reserved (Do not used) */ + APL2_WORLD = 0x45, /* Korea */ + APL2_APLC = 0x46, + APL3_WORLD = 0x47, + MKK1_FCCA = 0x48, /* Japan (JP1-1) */ + APL2_APLD = 0x49, /* Korea with 2.3G channels */ + MKK1_MKKA1 = 0x4A, /* Japan (JE1) */ + MKK1_MKKA2 = 0x4B, /* Japan (JE2) */ + MKK1_MKKC = 0x4C, /* Japan (MKK1_MKKA,except Ch14) */ + + APL3_FCCA = 0x50, + APL1_WORLD = 0x52, /* Latin America */ + APL1_FCCA = 0x53, + APL1_APLA = 0x54, + APL1_ETSIC = 0x55, + APL2_ETSIC = 0x56, /* Venezuela */ + APL2_FCCA = 0x57, /* new Latin America */ + APL5_WORLD = 0x58, /* Chile */ + APL6_WORLD = 0x5B, /* Singapore */ + APL7_FCCA = 0x5C, /* Taiwan 5.47 Band */ + APL8_WORLD = 0x5D, /* Malaysia 5GHz */ + APL9_WORLD = 0x5E, /* Korea 5GHz */ + + /* + * World mode SKUs + */ + WOR0_WORLD = 0x60, /* World0 (WO0 SKU) */ + WOR1_WORLD = 0x61, /* World1 (WO1 SKU) */ + WOR2_WORLD = 0x62, /* World2 (WO2 SKU) */ + WOR3_WORLD = 0x63, /* World3 (WO3 SKU) */ + WOR4_WORLD = 0x64, /* World4 (WO4 SKU) */ + WOR5_ETSIC = 0x65, /* World5 (WO5 SKU) */ + + WOR01_WORLD = 0x66, /* World0-1 (WW0-1 SKU) */ + WOR02_WORLD = 0x67, /* World0-2 (WW0-2 SKU) */ + EU1_WORLD = 0x68, /* Same as World0-2 (WW0-2 SKU), except active scan ch1-13. No ch14 */ + + WOR9_WORLD = 0x69, /* World9 (WO9 SKU) */ + WORA_WORLD = 0x6A, /* WorldA (WOA SKU) */ + + MKK3_MKKB = 0x80, /* Japan UNI-1 even + MKKB */ + MKK3_MKKA2 = 0x81, /* Japan UNI-1 even + MKKA2 */ + MKK3_MKKC = 0x82, /* Japan UNI-1 even + MKKC */ + + MKK4_MKKB = 0x83, /* Japan UNI-1 even + UNI-2 + MKKB */ + MKK4_MKKA2 = 0x84, /* Japan UNI-1 even + UNI-2 + MKKA2 */ + MKK4_MKKC = 0x85, /* Japan UNI-1 even + UNI-2 + MKKC */ + + MKK5_MKKB = 0x86, /* Japan UNI-1 even + UNI-2 + mid-band + MKKB */ + MKK5_MKKA2 = 0x87, /* Japan UNI-1 even + UNI-2 + mid-band + MKKA2 */ + MKK5_MKKC = 0x88, /* Japan UNI-1 even + UNI-2 + mid-band + MKKC */ + + MKK6_MKKB = 0x89, /* Japan UNI-1 even + UNI-1 odd MKKB */ + MKK6_MKKA2 = 0x8A, /* Japan UNI-1 even + UNI-1 odd + MKKA2 */ + MKK6_MKKC = 0x8B, /* Japan UNI-1 even + UNI-1 odd + MKKC */ + + MKK7_MKKB = 0x8C, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKB */ + MKK7_MKKA = 0x8D, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKA2 */ + MKK7_MKKC = 0x8E, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKC */ + + MKK8_MKKB = 0x8F, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKB */ + MKK8_MKKA2 = 0x90, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKA2 */ + MKK8_MKKC = 0x91, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKC */ + + MKK6_MKKA1 = 0xF8, /* Japan UNI-1 even + UNI-1 odd + MKKA1 */ + MKK6_FCCA = 0xF9, /* Japan UNI-1 even + UNI-1 odd + FCCA */ + MKK7_MKKA1 = 0xFA, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKA1 */ + MKK7_FCCA = 0xFB, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + FCCA */ + MKK9_FCCA = 0xFC, /* Japan UNI-1 even + 4.9GHz + FCCA */ + MKK9_MKKA1 = 0xFD, /* Japan UNI-1 even + 4.9GHz + MKKA1 */ + MKK9_MKKC = 0xFE, /* Japan UNI-1 even + 4.9GHz + MKKC */ + MKK9_MKKA2 = 0xFF, /* Japan UNI-1 even + 4.9GHz + MKKA2 */ + + MKK10_FCCA = 0xD0, /* Japan UNI-1 even + UNI-2 + 4.9GHz + FCCA */ + MKK10_MKKA1 = 0xD1, /* Japan UNI-1 even + UNI-2 + 4.9GHz + MKKA1 */ + MKK10_MKKC = 0xD2, /* Japan UNI-1 even + UNI-2 + 4.9GHz + MKKC */ + MKK10_MKKA2 = 0xD3, /* Japan UNI-1 even + UNI-2 + 4.9GHz + MKKA2 */ + + MKK11_MKKA = 0xD4, /* Japan UNI-1 even + UNI-2 + Midband + 4.9GHz + MKKA */ + MKK11_FCCA = 0xD5, /* Japan UNI-1 even + UNI-2 + Midband + 4.9GHz + FCCA */ + MKK11_MKKA1 = 0xD6, /* Japan UNI-1 even + UNI-2 + Midband + 4.9GHz + MKKA1 */ + MKK11_MKKC = 0xD7, /* Japan UNI-1 even + UNI-2 + Midband + 4.9GHz + MKKC */ + MKK11_MKKA2 = 0xD8, /* Japan UNI-1 even + UNI-2 + Midband + 4.9GHz + MKKA2 */ + + MKK12_MKKA = 0xD9, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + Midband + 4.9GHz + MKKA */ + MKK12_FCCA = 0xDA, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + Midband + 4.9GHz + FCCA */ + MKK12_MKKA1 = 0xDB, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + Midband + 4.9GHz + MKKA1 */ + MKK12_MKKC = 0xDC, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + Midband + 4.9GHz + MKKC */ + MKK12_MKKA2 = 0xDD, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + Midband + 4.9GHz + MKKA2 */ + + /* Following definitions are used only by s/w to map old + * Japan SKUs. + */ + MKK3_MKKA = 0xF0, /* Japan UNI-1 even + MKKA */ + MKK3_MKKA1 = 0xF1, /* Japan UNI-1 even + MKKA1 */ + MKK3_FCCA = 0xF2, /* Japan UNI-1 even + FCCA */ + MKK4_MKKA = 0xF3, /* Japan UNI-1 even + UNI-2 + MKKA */ + MKK4_MKKA1 = 0xF4, /* Japan UNI-1 even + UNI-2 + MKKA1 */ + MKK4_FCCA = 0xF5, /* Japan UNI-1 even + UNI-2 + FCCA */ + MKK9_MKKA = 0xF6, /* Japan UNI-1 even + 4.9GHz + MKKA*/ + MKK10_MKKA = 0xF7, /* Japan UNI-1 even + UNI-2 + 4.9GHz + MKKA */ + + /* + * Regulator domains ending in a number (e.g. APL1, + * MK1, ETSI4, etc) apply to 5GHz channel and power + * information. Regulator domains ending in a letter + * (e.g. APLA, FCCA, etc) apply to 2.4GHz channel and + * power information. + */ + APL1 = 0x0150, /* LAT & Asia */ + APL2 = 0x0250, /* LAT & Asia */ + APL3 = 0x0350, /* Taiwan */ + APL4 = 0x0450, /* Jordan */ + APL5 = 0x0550, /* Chile */ + APL6 = 0x0650, /* Singapore */ + APL7 = 0x0750, /* Taiwan Middle */ + APL8 = 0x0850, /* Malaysia */ + APL9 = 0x0950, /* Korea (South) ROC 3 */ + + ETSI1 = 0x0130, /* Europe & others */ + ETSI2 = 0x0230, /* Europe & others */ + ETSI3 = 0x0330, /* Europe & others */ + ETSI4 = 0x0430, /* Europe & others */ + ETSI5 = 0x0530, /* Europe & others */ + ETSI6 = 0x0630, /* Europe & others */ + ETSIA = 0x0A30, /* France */ + ETSIB = 0x0B30, /* Israel */ + ETSIC = 0x0C30, /* Latin America */ + + FCC1 = 0x0110, /* US & others */ + FCC2 = 0x0120, /* Canada, Australia & New Zealand */ + FCC3 = 0x0160, /* US w/new middle band & DFS */ + FCC4 = 0x0165, /* US Public Safety */ + FCC5 = 0x0510, /* US no DFS */ + FCC6 = 0x0610, /* Canada & Australia */ + + FCCA = 0x0A10, + + APLD = 0x0D50, /* South Korea */ + + MKK1 = 0x0140, /* Japan (UNI-1 odd)*/ + MKK2 = 0x0240, /* Japan (4.9 GHz + UNI-1 odd) */ + MKK3 = 0x0340, /* Japan (UNI-1 even) */ + MKK4 = 0x0440, /* Japan (UNI-1 even + UNI-2) */ + MKK5 = 0x0540, /* Japan (UNI-1 even + UNI-2 + mid-band) */ + MKK6 = 0x0640, /* Japan (UNI-1 odd + UNI-1 even) */ + MKK7 = 0x0740, /* Japan (UNI-1 odd + UNI-1 even + UNI-2 */ + MKK8 = 0x0840, /* Japan (UNI-1 odd + UNI-1 even + UNI-2 + mid-band) */ + MKK9 = 0x0940, /* Japan (UNI-1 even + 4.9 GHZ) */ + MKK10 = 0x0B40, /* Japan (UNI-1 even + UNI-2 + 4.9 GHZ) */ + MKK11 = 0x1140, /* Japan (UNI-1 even + UNI-2 + mid-band + 4.9 GHZ) */ + MKK12 = 0x1240, /* Japan (UNI-1 even + UNI-1 odd + UNI-2 + mid-band + 4.9 GHZ) */ + MKKA = 0x0A40, /* Japan */ + MKKC = 0x0A50, + + NULL1 = 0x0198, + WORLD = 0x0199, + DEBUG_REG_DMN = 0x01ff, +}; + +/* channelFlags */ +#define ZM_REG_FLAG_CHANNEL_CW_INT 0x0002 /* CW interference detected on channel */ +#define ZM_REG_FLAG_CHANNEL_TURBO 0x0010 /* Turbo Channel */ +#define ZM_REG_FLAG_CHANNEL_CCK 0x0020 /* CCK channel */ +#define ZM_REG_FLAG_CHANNEL_OFDM 0x0040 /* OFDM channel */ +#define ZM_REG_FLAG_CHANNEL_2GHZ 0x0080 /* 2 GHz spectrum channel. */ +#define ZM_REG_FLAG_CHANNEL_5GHZ 0x0100 /* 5 GHz spectrum channel */ +#define ZM_REG_FLAG_CHANNEL_PASSIVE 0x0200 /* Only passive scan allowed in the channel */ +#define ZM_REG_FLAG_CHANNEL_DYN 0x0400 /* dynamic CCK-OFDM channel */ +#define ZM_REG_FLAG_CHANNEL_XR 0x0800 /* XR channel */ +#define ZM_REG_FLAG_CHANNEL_CSA 0x1000 /* Channel by CSA(Channel Switch Announcement) */ +#define ZM_REG_FLAG_CHANNEL_STURBO 0x2000 /* Static turbo, no 11a-only usage */ +#define ZM_REG_FLAG_CHANNEL_HALF 0x4000 /* Half rate channel */ +#define ZM_REG_FLAG_CHANNEL_QUARTER 0x8000 /* Quarter rate channel */ + +/* channelFlags */ +#define CHANNEL_CW_INT 0x0002 /* CW interference detected on channel */ +#define CHANNEL_TURBO 0x0010 /* Turbo Channel */ +#define CHANNEL_CCK 0x0020 /* CCK channel */ +#define CHANNEL_OFDM 0x0040 /* OFDM channel */ +#define CHANNEL_2GHZ 0x0080 /* 2 GHz spectrum channel. */ +#define CHANNEL_5GHZ 0x0100 /* 5 GHz spectrum channel */ +#define CHANNEL_PASSIVE 0x0200 /* Only passive scan allowed in the channel */ +#define CHANNEL_DYN 0x0400 /* dynamic CCK-OFDM channel */ +#define CHANNEL_XR 0x0800 /* XR channel */ +#define CHANNEL_STURBO 0x2000 /* Static turbo, no 11a-only usage */ +#define CHANNEL_HALF 0x4000 /* Half rate channel */ +#define CHANNEL_QUARTER 0x8000 /* Quarter rate channel */ +#define CHANNEL_HT20 0x10000 /* HT20 channel */ +#define CHANNEL_HT40 0x20000 /* HT40 channel */ +#define CHANNEL_HT40U 0x40000 /* control channel can be upper channel */ +#define CHANNEL_HT40L 0x80000 /* control channel can be lower channel */ + +/* privFlags */ +#define ZM_REG_FLAG_CHANNEL_INTERFERENCE 0x01 /* Software use: channel interference + used for as AR as well as RADAR + interference detection */ +#define ZM_REG_FLAG_CHANNEL_DFS 0x02 /* DFS required on channel */ +#define ZM_REG_FLAG_CHANNEL_4MS_LIMIT 0x04 /* 4msec packet limit on this channel */ +#define ZM_REG_FLAG_CHANNEL_DFS_CLEAR 0x08 /* if channel has been checked for DFS */ + +#define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM) +#define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK) +#define CHANNEL_PUREG (CHANNEL_2GHZ|CHANNEL_OFDM) +#ifdef notdef +#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_DYN) +#else +#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM) +#endif +#define CHANNEL_T (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_TURBO) +#define CHANNEL_ST (CHANNEL_T|CHANNEL_STURBO) +#define CHANNEL_108G (CHANNEL_2GHZ|CHANNEL_OFDM|CHANNEL_TURBO) +#define CHANNEL_108A CHANNEL_T +#define CHANNEL_X (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_XR) +#define CHANNEL_G_HT (CHANNEL_2GHZ | CHANNEL_OFDM | CHANNEL_HT20) +#define CHANNEL_A_HT (CHANNEL_5GHZ | CHANNEL_OFDM | CHANNEL_HT20) + +#define CHANNEL_G_HT20 (CHANNEL_2GHZ|CHANNEL_HT20) +#define CHANNEL_A_HT20 (CHANNEL_5GHZ|CHANNEL_HT20) +#define CHANNEL_G_HT40 (CHANNEL_2GHZ|CHANNEL_HT20|CHANNEL_HT40) +#define CHANNEL_A_HT40 (CHANNEL_5GHZ|CHANNEL_HT20|CHANNEL_HT40) +#define CHANNEL_ALL \ + (CHANNEL_OFDM|CHANNEL_CCK| CHANNEL_2GHZ | CHANNEL_5GHZ | CHANNEL_TURBO | CHANNEL_HT20 | CHANNEL_HT40) +#define CHANNEL_ALL_NOTURBO (CHANNEL_ALL &~ CHANNEL_TURBO) + +enum { + HAL_MODE_11A = 0x001, /* 11a channels */ + HAL_MODE_TURBO = 0x002, /* 11a turbo-only channels */ + HAL_MODE_11B = 0x004, /* 11b channels */ + HAL_MODE_PUREG = 0x008, /* 11g channels (OFDM only) */ +#ifdef notdef + HAL_MODE_11G = 0x010, /* 11g channels (OFDM/CCK) */ +#else + HAL_MODE_11G = 0x008, /* XXX historical */ +#endif + HAL_MODE_108G = 0x020, /* 11a+Turbo channels */ + HAL_MODE_108A = 0x040, /* 11g+Turbo channels */ + HAL_MODE_XR = 0x100, /* XR channels */ + HAL_MODE_11A_HALF_RATE = 0x200, /* 11A half rate channels */ + HAL_MODE_11A_QUARTER_RATE = 0x400, /* 11A quarter rate channels */ + HAL_MODE_11NG = 0x4000, /* 11ng channels */ + HAL_MODE_11NA = 0x8000, /* 11na channels */ + HAL_MODE_ALL = 0xffff +}; + +#endif /* #ifndef _HPREG_H */ --- linux-2.6.28.orig/drivers/staging/otus/hal/hprw.c +++ linux-2.6.28/drivers/staging/otus/hal/hprw.c @@ -0,0 +1,1557 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "../80211core/cprecomp.h" +#include "hpani.h" +#include "hpusb.h" +#include "hpreg.h" +#include "../80211core/ratectrl.h" + +extern void zfIdlCmd(zdev_t* dev, u32_t* cmd, u16_t cmdLen); + +extern void zfCoreCwmBusy(zdev_t* dev, u16_t busy); +u16_t zfDelayWriteInternalReg(zdev_t* dev, u32_t addr, u32_t val); +u16_t zfFlushDelayWrite(zdev_t* dev); + +//#define zm_hp_priv(x) struct zsHpPriv* hpPriv=zgWlanDev.hpPrivate; + +void zfInitCmdQueue(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv = (struct zsHpPriv*)(wd->hpPrivate); + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); +#ifdef ZM_XP_USB_MULTCMD + hpPriv->cmdTail = hpPriv->cmdHead = hpPriv->cmdSend = 0; +#else + hpPriv->cmdTail = hpPriv->cmdHead = 0; +#endif + hpPriv->cmdPending = 0; + hpPriv->cmd.delayWcmdCount = 0; + zmw_leave_critical_section(dev); +} + +u16_t zfPutCmd(zdev_t* dev, u32_t* cmd, u16_t cmdLen, u16_t src, u8_t* buf) +{ + u16_t i; + + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv=wd->hpPrivate; + + /* Make sure command length < ZM_MAX_CMD_SIZE */ + zm_assert(cmdLen <= ZM_MAX_CMD_SIZE); + /* Make sure command queue not full */ + //zm_assert(((hpPriv->cmdTail+1) & (ZM_CMD_QUEUE_SIZE-1)) != hpPriv->cmdHead); + if (((hpPriv->cmdTail+1) & (ZM_CMD_QUEUE_SIZE-1)) == hpPriv->cmdHead ) { + zm_debug_msg0("CMD queue full!!"); + return 0; + } + + hpPriv->cmdQ[hpPriv->cmdTail].cmdLen = cmdLen; + hpPriv->cmdQ[hpPriv->cmdTail].src = src; + hpPriv->cmdQ[hpPriv->cmdTail].buf = buf; + for (i=0; i<(cmdLen>>2); i++) + { + hpPriv->cmdQ[hpPriv->cmdTail].cmd[i] = cmd[i]; + } + + hpPriv->cmdTail = (hpPriv->cmdTail+1) & (ZM_CMD_QUEUE_SIZE-1); + + return 0; +} + +u16_t zfGetCmd(zdev_t* dev, u32_t* cmd, u16_t* cmdLen, u16_t* src, u8_t** buf) +{ + u16_t i; + + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv=wd->hpPrivate; + + if (hpPriv->cmdTail == hpPriv->cmdHead) + { + return 3; + } + + *cmdLen = hpPriv->cmdQ[hpPriv->cmdHead].cmdLen; + *src = hpPriv->cmdQ[hpPriv->cmdHead].src; + *buf = hpPriv->cmdQ[hpPriv->cmdHead].buf; + for (i=0; i<((*cmdLen)>>2); i++) + { + cmd[i] = hpPriv->cmdQ[hpPriv->cmdHead].cmd[i]; + } + + hpPriv->cmdHead = (hpPriv->cmdHead+1) & (ZM_CMD_QUEUE_SIZE-1); + + return 0; +} + +#ifdef ZM_XP_USB_MULTCMD +void zfSendCmdEx(zdev_t* dev) +{ + u32_t ncmd[ZM_MAX_CMD_SIZE/4]; + u16_t ncmdLen = 0; + u16_t cmdFlag = 0; + u16_t i; + + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv=wd->hpPrivate; + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + if (hpPriv->cmdPending == 0) + { + if (hpPriv->cmdTail != hpPriv->cmdSend) + { + cmdFlag = 1; + /* Get queueing command */ + ncmdLen= hpPriv->cmdQ[hpPriv->cmdSend].cmdLen; + for (i=0; i<(ncmdLen>>2); i++) + { + ncmd[i] = hpPriv->cmdQ[hpPriv->cmdSend].cmd[i]; + } + hpPriv->cmdSend = (hpPriv->cmdSend+1) & (ZM_CMD_QUEUE_SIZE-1); + + hpPriv->cmdPending = 1; + } + } + + zmw_leave_critical_section(dev); + + if ((cmdFlag == 1)) + { + zfIdlCmd(dev, ncmd, ncmdLen); + } +} + +void zfiSendCmdComp(zdev_t* dev) +{ + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv=wd->hpPrivate; + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + hpPriv->cmdPending = 0; + zmw_leave_critical_section(dev); + + zfSendCmdEx(dev); +} +#endif + +u16_t zfIssueCmd(zdev_t* dev, u32_t* cmd, u16_t cmdLen, u16_t src, u8_t* buf) +{ + u16_t cmdFlag = 0; + u16_t ret; + + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv=wd->hpPrivate; + + zmw_declare_for_critical_section(); + + zm_msg2_mm(ZM_LV_1, "cmdLen=", cmdLen); + + zmw_enter_critical_section(dev); + +#ifdef ZM_XP_USB_MULTCMD + ret = zfPutCmd(dev, cmd, cmdLen, src, buf); + zmw_leave_critical_section(dev); + + if (ret != 0) + { + return 1; + } + + zfSendCmdEx(dev); +#else + if (hpPriv->cmdPending == 0) + { + hpPriv->cmdPending = 1; + cmdFlag = 1; + } + ret = zfPutCmd(dev, cmd, cmdLen, src, buf); + + zmw_leave_critical_section(dev); + + if (ret != 0) + { + return 1; + } + + if (cmdFlag == 1) + { + zfIdlCmd(dev, cmd, cmdLen); + } +#endif + return 0; +} + +void zfIdlRsp(zdev_t* dev, u32_t* rsp, u16_t rspLen) +{ + u32_t cmd[ZM_MAX_CMD_SIZE/4]; + u16_t cmdLen; + u16_t src; + u8_t* buf; + u32_t ncmd[ZM_MAX_CMD_SIZE/4]; + u16_t ncmdLen = 0; + u16_t ret; + u16_t cmdFlag = 0; + u16_t i; + s32_t nf; + s32_t noisefloor[4]; + + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv=wd->hpPrivate; + + + zmw_declare_for_critical_section(); + + zmw_enter_critical_section(dev); + + ret = zfGetCmd(dev, cmd, &cmdLen, &src, &buf); + #if 0 + zm_assert(ret == 0); + #else + if (ret != 0) + { + zm_debug_msg0("Error IdlRsp because none cmd!!\n"); + #ifndef ZM_XP_USB_MULTCMD + zmw_leave_critical_section(dev); + return; + #endif + } + #endif +#ifdef ZM_XP_USB_MULTCMD + zmw_leave_critical_section(dev); +#else + if (hpPriv->cmdTail != hpPriv->cmdHead) + { + cmdFlag = 1; + /* Get queueing command */ + ncmdLen= hpPriv->cmdQ[hpPriv->cmdHead].cmdLen; + for (i=0; i<(ncmdLen>>2); i++) + { + ncmd[i] = hpPriv->cmdQ[hpPriv->cmdHead].cmd[i]; + } + } + else + { + hpPriv->cmdPending = 0; + } + + zmw_leave_critical_section(dev); + + if (cmdFlag == 1) + { + zfIdlCmd(dev, ncmd, ncmdLen); + } +#endif + if (src == ZM_OID_READ) + { + ZM_PERFORMANCE_REG(dev, 0x11772c, rsp[1]); + zfwDbgReadRegDone(dev, cmd[1], rsp[1]); + } + else if (src == ZM_OID_FLASH_CHKSUM) + { + zfwDbgGetFlashChkSumDone(dev, rsp+1); + } + else if (src == ZM_OID_FLASH_READ) + { + u32_t datalen; + u16_t i; + + datalen = (rsp[0] & 255); + + zfwDbgReadFlashDone(dev, cmd[1], rsp+1, datalen); + } + else if (src == ZM_OID_FLASH_PROGRAM) + { + /* Non do */ + } + else if (src == ZM_OID_WRITE) + { + zfwDbgWriteRegDone(dev, cmd[1], cmd[2]); + } + else if (src == ZM_OID_TALLY) + { + zfCollectHWTally(dev, rsp, 0); + } + else if (src == ZM_OID_TALLY_APD) + { + zfCollectHWTally(dev, rsp, 1); + zfwDbgReadTallyDone(dev); +#ifdef ZM_ENABLE_BA_RATECTRL + zfRateCtrlAggrSta(dev); +#endif + } + else if (src == ZM_OID_DKTX_STATUS) + { + zm_debug_msg0("src = zm_OID_DKTX_STATUS"); + zfwDbgQueryHwTxBusyDone(dev, rsp[1]); + } + else if (src == ZM_CMD_SET_FREQUENCY) + { + +//#ifdef ZM_OTUS_ENABLE_RETRY_FREQ_CHANGE +#if 0 + zm_debug_msg1("Retry Set Frequency = ", rsp[1]); + + #if 1 + // Read the Noise Floor value ! + nf = ((rsp[2]>>19) & 0x1ff); + if ((nf & 0x100) != 0x0) + { + noisefloor[0] = 0 - ((nf ^ 0x1ff) + 1); + } + else + { + noisefloor[0] = nf; + } + + zm_debug_msg1("Noise Floor[1] = ", noisefloor[0]); + + nf = ((rsp[3]>>19) & 0x1ff); + if ((nf & 0x100) != 0x0) + { + noisefloor[1] = 0 - ((nf ^ 0x1ff) + 1); + } + else + { + noisefloor[1] = nf; + } + + zm_debug_msg1("Noise Floor[2] = ", noisefloor[1]); + zm_debug_msg1("Is Site Survey = ", hpPriv->isSiteSurvey); + #endif + + if ( (rsp[1] && hpPriv->freqRetryCounter == 0) || + (((noisefloor[0]>-60)||(noisefloor[1]>-60)) && hpPriv->freqRetryCounter==0) || + ((abs(noisefloor[0]-noisefloor[1])>=9) && hpPriv->freqRetryCounter==0) ) + { + zm_debug_msg0("Retry to issue the frequency change command"); + + if ( hpPriv->recordFreqRetryCounter == 1 ) + { + zm_debug_msg0("Cold Reset"); + + zfHpSetFrequencyEx(dev, hpPriv->latestFrequency, + hpPriv->latestBw40, + hpPriv->latestExtOffset, + 2); + + if ( hpPriv->isSiteSurvey != 2 ) + { + hpPriv->freqRetryCounter++; + } + hpPriv->recordFreqRetryCounter = 0; + } + else + { + zfHpSetFrequencyEx(dev, hpPriv->latestFrequency, + hpPriv->latestBw40, + hpPriv->latestExtOffset, + 0); + } + hpPriv->recordFreqRetryCounter++; + } + else +#endif + +/* ret: Bit0: AGC calibration 0=>finish 1=>unfinish */ +/* Bit1: Noise calibration 0=>finish 1=>unfinish */ +/* Bit2: Noise calibration finish, but NF value unexcepted => 1 */ + if ( (rsp[1] & 0x1) || (rsp[1] & 0x4) ) + { + zm_debug_msg1("Set Frequency fail : ret = ", rsp[1]); + + /* 1. AGC Calibration fail */ + /* 2. Noise Calibration finish but error NoiseFloor value */ + /* and not in sitesurvey, try more twice */ + if ( hpPriv->isSiteSurvey == 2 ) + { + if ( hpPriv->recordFreqRetryCounter < 2 ) + { + /* cold reset */ + zfHpSetFrequencyEx(dev, hpPriv->latestFrequency, + hpPriv->latestBw40, + hpPriv->latestExtOffset, + 2); + hpPriv->recordFreqRetryCounter++; + zm_debug_msg1("Retry to issue the frequency change command(cold reset) counter = ", hpPriv->recordFreqRetryCounter); + } + else + { + /* Fail : we would not accept this result! */ + zm_debug_msg0("\n\n\n\n Fail twice cold reset \n\n\n\n"); + hpPriv->coldResetNeedFreq = 0; + hpPriv->recordFreqRetryCounter = 0; + zfCoreSetFrequencyComplete(dev); + } + } + else + { + /* in sitesurvey, coldreset in next channel */ + hpPriv->coldResetNeedFreq = 1; + hpPriv->recordFreqRetryCounter = 0; + zfCoreSetFrequencyComplete(dev); + } + } + else if (rsp[1] & 0x2) + { + zm_debug_msg1("Set Frequency fail 2 : ret = ", rsp[1]); + + /* Noise Calibration un-finish */ + /* and not in sitesurvey, try more once */ + if ( hpPriv->isSiteSurvey == 2 ) + { + if ( hpPriv->recordFreqRetryCounter < 1 ) + { + /* cold reset */ + zfHpSetFrequencyEx(dev, hpPriv->latestFrequency, + hpPriv->latestBw40, + hpPriv->latestExtOffset, + 2); + hpPriv->recordFreqRetryCounter++; + zm_debug_msg1("2 Retry to issue the frequency change command(cold reset) counter = ", hpPriv->recordFreqRetryCounter); + } + else + { + /* Fail : we would not accept this result! */ + zm_debug_msg0("\n\n\n\n 2 Fail twice cold reset \n\n\n\n"); + hpPriv->coldResetNeedFreq = 0; + hpPriv->recordFreqRetryCounter = 0; + zfCoreSetFrequencyComplete(dev); + } + } + else + { + /* in sitesurvey, skip this frequency */ + hpPriv->coldResetNeedFreq = 0; + hpPriv->recordFreqRetryCounter = 0; + zfCoreSetFrequencyComplete(dev); + } + } + //else if (rsp[1] & 0x4) + //{ + // zm_debug_msg1("Set Frequency fail 3 : ret = ", rsp[1]); + // hpPriv->coldResetNeedFreq = 0; + // hpPriv->recordFreqRetryCounter = 0; + // zfCoreSetFrequencyComplete(dev); + //} + else + { + //hpPriv->freqRetryCounter = 0; + zm_debug_msg2(" return complete, ret = ", rsp[1]); + + /* set bb_heavy_clip_enable */ + if (hpPriv->enableBBHeavyClip && hpPriv->hwBBHeavyClip && + hpPriv->doBBHeavyClip) + { + u32_t setValue = 0x200; + + setValue |= hpPriv->setValueHeavyClip; + + //zm_dbg(("Do heavy clip setValue = %d\n", setValue)); + + zfDelayWriteInternalReg(dev, 0x99e0+0x1bc000, setValue); + zfFlushDelayWrite(dev); + } + + hpPriv->coldResetNeedFreq = 0; + hpPriv->recordFreqRetryCounter = 0; + zfCoreSetFrequencyComplete(dev); + } + + #if 1 + // Read the Noise Floor value ! + nf = ((rsp[2]>>19) & 0x1ff); + if ((nf & 0x100) != 0x0) + { + noisefloor[0] = 0 - ((nf ^ 0x1ff) + 1); + } + else + { + noisefloor[0] = nf; + } + + //zm_debug_msg1("Noise Floor[1] = ", noisefloor[0]); + + nf = ((rsp[3]>>19) & 0x1ff); + if ((nf & 0x100) != 0x0) + { + noisefloor[1] = 0 - ((nf ^ 0x1ff) + 1); + } + else + { + noisefloor[1] = nf; + } + + //zm_debug_msg1("Noise Floor[2] = ", noisefloor[1]); + + nf = ((rsp[5]>>23) & 0x1ff); + if ((nf & 0x100) != 0x0) + { + noisefloor[2] = 0 - ((nf ^ 0x1ff) + 1); + } + else + { + noisefloor[2] = nf; + } + + //zm_debug_msg1("Noise Floor ext[1] = ", noisefloor[2]); + + nf = ((rsp[6]>>23) & 0x1ff); + if ((nf & 0x100) != 0x0) + { + noisefloor[3] = 0 - ((nf ^ 0x1ff) + 1); + } + else + { + noisefloor[3] = nf; + } + + //zm_debug_msg1("Noise Floor ext[2] = ", noisefloor[3]); + + //zm_debug_msg1("Is Site Survey = ", hpPriv->isSiteSurvey); + #endif + } + else if (src == ZM_CMD_SET_KEY) + { + zfCoreSetKeyComplete(dev); + } + else if (src == ZM_CWM_READ) + { + zm_msg2_mm(ZM_LV_0, "CWM rsp[1]=", rsp[1]); + zm_msg2_mm(ZM_LV_0, "CWM rsp[2]=", rsp[2]); + zfCoreCwmBusy(dev, zfCwmIsExtChanBusy(rsp[1], rsp[2])); + } + else if (src == ZM_MAC_READ) + { + /* rsp[1] = ZM_SEEPROM_MAC_ADDRESS_OFFSET; */ + /* rsp[2] = ZM_SEEPROM_MAC_ADDRESS_OFFSET+4; */ + /* rsp[3] = ZM_SEEPROM_REGDOMAIN_OFFSET; */ + /* rsp[4] = ZM_SEEPROM_VERISON_OFFSET; */ + /* rsp[5] = ZM_SEEPROM_HARDWARE_TYPE_OFFSET; */ + /* rsp[6] = ZM_SEEPROM_HW_HEAVY_CLIP; */ + + u8_t addr[6], CCS, WWR; + u16_t CountryDomainCode; + + /* BB heavy clip */ + //hpPriv->eepromHeavyClipFlag = (u8_t)((rsp[6]>>24) & 0xff); // force enable 8107 + //zm_msg2_mm(ZM_LV_0, "eepromHeavyClipFlag", hpPriv->eepromHeavyClipFlag); + #if 0 + if (hpPriv->hwBBHeavyClip) + { + zm_msg0_mm(ZM_LV_0, "enable BB Heavy Clip"); + } + else + { + zm_msg0_mm(ZM_LV_0, "Not enable BB Heavy Clip"); + } + #endif + zm_msg2_mm(ZM_LV_0, "MAC rsp[1]=", rsp[1]); + zm_msg2_mm(ZM_LV_0, "MAC rsp[2]=", rsp[2]); + + addr[0] = (u8_t)(rsp[1] & 0xff); + addr[1] = (u8_t)((rsp[1]>>8) & 0xff); + addr[2] = (u8_t)((rsp[1]>>16) & 0xff); + addr[3] = (u8_t)((rsp[1]>>24) & 0xff); + addr[4] = (u8_t)(rsp[2] & 0xff); + addr[5] = (u8_t)((rsp[2]>>8) & 0xff); +/*#ifdef ZM_FB50 + addr[0] = (u8_t)(0 & 0xff); + addr[1] = (u8_t)(3 & 0xff); + addr[2] = (u8_t)(127 & 0xff); + addr[3] = (u8_t)(0 & 0xff); + addr[4] = (u8_t)(9 & 0xff); + addr[5] = (u8_t)(11 & 0xff); +#endif*/ + + zfDelayWriteInternalReg(dev, ZM_MAC_REG_MAC_ADDR_L, + ((((u32_t)addr[3])<<24) | (((u32_t)addr[2])<<16) | (((u32_t)addr[1])<<8) | addr[0])); + zfDelayWriteInternalReg(dev, ZM_MAC_REG_MAC_ADDR_H, + ((((u32_t)addr[5])<<8) | addr[4])); + zfFlushDelayWrite(dev); + + wd->ledStruct.ledMode[0] = (u16_t)(rsp[5]&0xffff); + wd->ledStruct.ledMode[1] = (u16_t)(rsp[5]>>16); + zm_msg2_mm(ZM_LV_0, "ledMode[0]=", wd->ledStruct.ledMode[0]); + zm_msg2_mm(ZM_LV_0, "ledMode[1]=", wd->ledStruct.ledMode[1]); + + /* Regulatory Related Setting */ + zm_msg2_mm(ZM_LV_0, "RegDomain rsp=", rsp[3]); + zm_msg2_mm(ZM_LV_0, "OpFlags+EepMisc=", rsp[4]); + hpPriv->OpFlags = (u8_t)((rsp[4]>>16) & 0xff); + if ((rsp[2] >> 24) == 0x1) //Tx mask == 0x1 + { + zm_msg0_mm(ZM_LV_0, "OTUS 1x2"); + hpPriv->halCapability |= ZM_HP_CAP_11N_ONE_TX_STREAM; + } + else + { + zm_msg0_mm(ZM_LV_0, "OTUS 2x2"); + } + if (hpPriv->OpFlags & 0x1) + { + hpPriv->halCapability |= ZM_HP_CAP_5G; + } + if (hpPriv->OpFlags & 0x2) + { + hpPriv->halCapability |= ZM_HP_CAP_2G; + } + + + CCS = (u8_t)((rsp[3] & 0x8000) >> 15); + WWR = (u8_t)((rsp[3] & 0x4000) >> 14); + CountryDomainCode = (u16_t)(rsp[3] & 0x3FFF); + + if (rsp[3] != 0xffffffff) + { + if (CCS) + { + //zm_debug_msg0("CWY - Get Regulation Table from Country Code"); + zfHpGetRegulationTablefromCountry(dev, CountryDomainCode); + } + else + { + //zm_debug_msg0("CWY - Get Regulation Table from Reg Domain"); + zfHpGetRegulationTablefromRegionCode(dev, CountryDomainCode); + } + if (WWR) + { + //zm_debug_msg0("CWY - Enable 802.11d"); + /* below line shall be unmarked after A band is ready */ + //zfiWlanSetDot11DMode(dev, 1); + } + } + else + { + zfHpGetRegulationTablefromRegionCode(dev, NO_ENUMRD); + } + + zfCoreMacAddressNotify(dev, addr); + + } + else if (src == ZM_EEPROM_READ) + { +#if 0 + u8_t addr[6], CCS, WWR; + u16_t CountryDomainCode; +#endif + for (i=0; ieepromImageIndex < 1024) + { + hpPriv->eepromImage[hpPriv->eepromImageIndex++] = rsp[i+1]; + } + } + + if (hpPriv->eepromImageIndex == (ZM_HAL_MAX_EEPROM_REQ*ZM_HAL_MAX_EEPROM_PRQ)) + { + #if 0 + for (i=0; i<1024; i++) + { + zm_msg2_mm(ZM_LV_0, "index=", i); + zm_msg2_mm(ZM_LV_0, "eepromImage=", hpPriv->eepromImage[i]); + } + #endif + zm_msg2_mm(ZM_LV_0, "MAC [1]=", hpPriv->eepromImage[0x20c/4]); + zm_msg2_mm(ZM_LV_0, "MAC [2]=", hpPriv->eepromImage[0x210/4]); +#if 0 + addr[0] = (u8_t)(hpPriv->eepromImage[0x20c/4] & 0xff); + addr[1] = (u8_t)((hpPriv->eepromImage[0x20c/4]>>8) & 0xff); + addr[2] = (u8_t)((hpPriv->eepromImage[0x20c/4]>>16) & 0xff); + addr[3] = (u8_t)((hpPriv->eepromImage[0x20c/4]>>24) & 0xff); + addr[4] = (u8_t)(hpPriv->eepromImage[0x210/4] & 0xff); + addr[5] = (u8_t)((hpPriv->eepromImage[0x210/4]>>8) & 0xff); + + zfCoreMacAddressNotify(dev, addr); + + zfDelayWriteInternalReg(dev, ZM_MAC_REG_MAC_ADDR_L, + ((((u32_t)addr[3])<<24) | (((u32_t)addr[2])<<16) | (((u32_t)addr[1])<<8) | addr[0])); + zfDelayWriteInternalReg(dev, ZM_MAC_REG_MAC_ADDR_H, + ((((u32_t)addr[5])<<8) | addr[4])); + zfFlushDelayWrite(dev); + + /* Regulatory Related Setting */ + zm_msg2_mm(ZM_LV_0, "RegDomain =", hpPriv->eepromImage[0x208/4]); + CCS = (u8_t)((hpPriv->eepromImage[0x208/4] & 0x8000) >> 15); + WWR = (u8_t)((hpPriv->eepromImage[0x208/4] & 0x4000) >> 14); + /* below line shall be unmarked after A band is ready */ + //CountryDomainCode = (u16_t)(hpPriv->eepromImage[0x208/4] & 0x3FFF); + CountryDomainCode = 8; + if (CCS) + { + //zm_debug_msg0("CWY - Get Regulation Table from Country Code"); + zfHpGetRegulationTablefromCountry(dev, CountryDomainCode); + } + else + { + //zm_debug_msg0("CWY - Get Regulation Table from Reg Domain"); + zfHpGetRegulationTablefromRegionCode(dev, CountryDomainCode); + } + if (WWR) + { + //zm_debug_msg0("CWY - Enable 802.11d"); + /* below line shall be unmarked after A band is ready */ + //zfiWlanSetDot11DMode(dev, 1); + } +#endif + zfCoreHalInitComplete(dev); + } + else + { + hpPriv->eepromImageRdReq++; + zfHpLoadEEPROMFromFW(dev); + } + } + else if (src == ZM_EEPROM_WRITE) + { + zfwDbgWriteEepromDone(dev, cmd[1], cmd[2]); + } + else if (src == ZM_ANI_READ) + { + u32_t cycleTime, ctlClear; + + zm_msg2_mm(ZM_LV_0, "ANI rsp[1]=", rsp[1]); + zm_msg2_mm(ZM_LV_0, "ANI rsp[2]=", rsp[2]); + zm_msg2_mm(ZM_LV_0, "ANI rsp[3]=", rsp[3]); + zm_msg2_mm(ZM_LV_0, "ANI rsp[4]=", rsp[4]); + + hpPriv->ctlBusy += rsp[1]; + hpPriv->extBusy += rsp[2]; + + cycleTime = 100000; //100 miniseconds + + if (cycleTime > rsp[1]) + { + ctlClear = (cycleTime - rsp[1]) / 100; + } + else + { + ctlClear = 0; + } + if (wd->aniEnable) + zfHpAniArPoll(dev, ctlClear, rsp[3], rsp[4]); + } + else if (src == ZM_CMD_ECHO) + { + if ( ((struct zsHpPriv*)wd->hpPrivate)->halReInit ) + { + zfCoreHalInitComplete(dev); + ((struct zsHpPriv*)wd->hpPrivate)->halReInit = 0; + } + else + { + zfHpLoadEEPROMFromFW(dev); + } + } + else if (src == ZM_OID_FW_DL_INIT) + { + zfwDbgDownloadFwInitDone(dev); + } + return; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfWriteRegInternalReg */ +/* Write on chip internal register immediately. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* addr : register address */ +/* val : value */ +/* */ +/* OUTPUTS */ +/* 0 : success */ +/* other : fail */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2005.11 */ +/* */ +/************************************************************************/ +u32_t zfWriteRegInternalReg(zdev_t* dev, u32_t addr, u32_t val) +{ + u32_t cmd[3]; + u16_t ret; + + cmd[0] = 0x00000108; + cmd[1] = addr; + cmd[2] = val; + + ret = zfIssueCmd(dev, cmd, 12, ZM_OID_INTERNAL_WRITE, NULL); + return ret; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfDelayWriteInternalReg */ +/* Write on chip internal register, write operation may be */ +/* postponed to form a multiple write command. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* addr : register address */ +/* val : value */ +/* */ +/* OUTPUTS */ +/* 0 : command been postponed */ +/* 1 : commands been executed */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2005.11 */ +/* */ +/************************************************************************/ +u16_t zfDelayWriteInternalReg(zdev_t* dev, u32_t addr, u32_t val) +{ + u32_t cmd[(ZM_MAX_CMD_SIZE/4)]; + u16_t i; + u16_t ret; + + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv=wd->hpPrivate; + + zmw_declare_for_critical_section(); + + /* enter critical section */ + zmw_enter_critical_section(dev); + + /* Store command to global buffer */ + hpPriv->cmd.delayWcmdAddr[hpPriv->cmd.delayWcmdCount] = addr; + hpPriv->cmd.delayWcmdVal[hpPriv->cmd.delayWcmdCount++] = val; + + /* If pending command reach size limit */ + if ((hpPriv->cmd.delayWcmdCount) >= ((ZM_MAX_CMD_SIZE - 4) >> 3)) + { + cmd[0] = 0x00000100 + (hpPriv->cmd.delayWcmdCount<<3); + + /* copy command to cmd buffer */ + for (i=0; icmd.delayWcmdCount; i++) + { + cmd[1+(i<<1)] = hpPriv->cmd.delayWcmdAddr[i]; + cmd[2+(i<<1)] = hpPriv->cmd.delayWcmdVal[i]; + } + /* reset pending command */ + hpPriv->cmd.delayWcmdCount = 0; + + /* leave critical section */ + zmw_leave_critical_section(dev); + + /* issue write command */ + ret = zfIssueCmd(dev, cmd, 4+(i<<3), ZM_OID_INTERNAL_WRITE, NULL); + + return 1; + } + else + { + /* leave critical section */ + zmw_leave_critical_section(dev); + + return 0; + } +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfFlushDelayWrite */ +/* Flush pending write command. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* 0 : no pending command */ +/* 1 : commands been executed */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2005.11 */ +/* */ +/************************************************************************/ +u16_t zfFlushDelayWrite(zdev_t* dev) +{ + u32_t cmd[(ZM_MAX_CMD_SIZE/4)]; + u16_t i; + u16_t ret; + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv=wd->hpPrivate; + + zmw_declare_for_critical_section(); + + /* enter critical section */ + zmw_enter_critical_section(dev); + + /* If there is pending command */ + if (hpPriv->cmd.delayWcmdCount > 0) + { + cmd[0] = 0x00000100 + (hpPriv->cmd.delayWcmdCount<<3); + + /* copy command to cmd buffer */ + for (i=0; icmd.delayWcmdCount; i++) + { + cmd[1+(i<<1)] = hpPriv->cmd.delayWcmdAddr[i]; + cmd[2+(i<<1)] = hpPriv->cmd.delayWcmdVal[i]; + } + /* reset pending command */ + hpPriv->cmd.delayWcmdCount = 0; + + /* leave critical section */ + zmw_leave_critical_section(dev); + + /* issue write command */ + ret = zfIssueCmd(dev, cmd, 4+(i<<3), ZM_OID_INTERNAL_WRITE, NULL); + + return 1; + } + else + { + /* leave critical section */ + zmw_leave_critical_section(dev); + + return 0; + } +} + + +u32_t zfiDbgDelayWriteReg(zdev_t* dev, u32_t addr, u32_t val) +{ + zfDelayWriteInternalReg(dev, addr, val); + return 0; +} + +u32_t zfiDbgFlushDelayWrite(zdev_t* dev) +{ + zfFlushDelayWrite(dev); + return 0; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfiDbgWriteReg */ +/* Write register. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* addr : register address */ +/* val : value */ +/* */ +/* OUTPUTS */ +/* 0 : success */ +/* other : fail */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2005.10 */ +/* */ +/************************************************************************/ +u32_t zfiDbgWriteReg(zdev_t* dev, u32_t addr, u32_t val) +{ + u32_t cmd[3]; + u16_t ret; + + cmd[0] = 0x00000108; + cmd[1] = addr; + cmd[2] = val; + + ret = zfIssueCmd(dev, cmd, 12, ZM_OID_WRITE, 0); + return ret; +} +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfiDbgWriteFlash */ +/* Write flash. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* addr : register address */ +/* val : value */ +/* */ +/* OUTPUTS */ +/* 0 : success */ +/* other : fail */ +/* */ +/* AUTHOR */ +/* Yjsung ZyDAS Technology Corporation 2007.02 */ +/* */ +/************************************************************************/ +u32_t zfiDbgWriteFlash(zdev_t* dev, u32_t addr, u32_t val) +{ + u32_t cmd[3]; + u16_t ret; + + //cmd[0] = 0x0000B008; + /* len[0] : type[0xB0] : seq[?] */ + cmd[0] = 8 | (ZM_CMD_WFLASH << 8); + cmd[1] = addr; + cmd[2] = val; + + ret = zfIssueCmd(dev, cmd, 12, ZM_OID_WRITE, 0); + return ret; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfiDbgWriteEeprom */ +/* Write EEPROM. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* addr : register address */ +/* val : value */ +/* */ +/* OUTPUTS */ +/* 0 : success */ +/* other : fail */ +/* */ +/* AUTHOR */ +/* Paul ZyDAS Technology Corporation 2007.06 */ +/* */ +/************************************************************************/ +u32_t zfiDbgWriteEeprom(zdev_t* dev, u32_t addr, u32_t val) +{ + u32_t cmd[3]; + u16_t ret; + + //cmd[0] = 0x0000B008; + /* len[0] : type[0xB0] : seq[?] */ + cmd[0] = 8 | (ZM_CMD_WREEPROM << 8); + cmd[1] = addr; + cmd[2] = val; + + ret = zfIssueCmd(dev, cmd, 12, ZM_EEPROM_WRITE, 0); + return ret; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfiDbgBlockWriteEeprom */ +/* Block Write Eeprom. */ +/* */ +/* p.s: now,it will write 16 bytes register data per block (N=4) */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* addr : register address */ +/* buf : input data buffer pointer */ +/* */ +/* OUTPUTS */ +/* 0 : success */ +/* other : fail */ +/* */ +/* AUTHOR */ +/* Paul ZyDAS Technology Corporation 2007.06 */ +/* */ +/************************************************************************/ +//#define N buflen/4 +//#define SIZE (2*N+1) + +u32_t zfiDbgBlockWriteEeprom(zdev_t* dev, u32_t addr, u32_t* buf) +{ + u32_t cmd[9]; //2N+1 + u16_t ret,i; + + //cmd[0] = 0x0000B008; + /* len[0] : type[0xB0] : seq[?] */ + + //cmd[0] = (8*N) | (ZM_CMD_WFLASH << 8); + cmd[0] = 32 | (ZM_CMD_WREEPROM << 8); //8N + + for (i=0; i<4; i++) // i 0x2000) + { + return 1; + } + + for(i=0; ihpPrivate)->halReInit ) + { + return 1; + } + + /* len[0] : type[0x81] : seq[?] */ + cmd[0] = 0 | (ZM_CMD_TALLY << 8); + ret = zfIssueCmd(dev, cmd, 4, ZM_OID_TALLY, 0); + + /* len[0] : type[0x82] : seq[?] */ + cmd[0] = 0 | (ZM_CMD_TALLY_APD << 8); + ret = zfIssueCmd(dev, cmd, 4, ZM_OID_TALLY_APD, 0); + + return ret; +} + + +u32_t zfiDbgSetIFSynthesizer(zdev_t* dev, u32_t value) +{ + u32_t cmd[2]; + u16_t ret; + + /* len[4] : type[0x32] : seq[?] */ + cmd[0] = 0x4 | (ZM_OID_SYNTH << 8); + cmd[1] = value; + + ret = zfIssueCmd(dev, cmd, 8, ZM_OID_SYNTH, 0); + return ret; +} + +u32_t zfiDbgQueryHwTxBusy(zdev_t* dev) +{ + u32_t cmd[1]; + u16_t ret; + + /* len[4] : type[0xC0] : seq[?] */ + cmd[0] = 0 | (ZM_CMD_DKTX_STATUS << 8); + + ret = zfIssueCmd(dev, cmd, 4, ZM_OID_DKTX_STATUS, 0); + return ret; +} + +//Paul++ +#if 0 +u16_t zfHpBlockEraseFlash(zdev_t *dev, u32_t addr) +{ + u32_t cmd[(ZM_MAX_CMD_SIZE/4)]; + u16_t ret; + + cmd[0] = 0x00000004 | (ZM_CMD_FLASH_ERASE << 8); + cmd[1] = addr; + + ret = zfIssueCmd(dev, cmd, 8, ZM_OID_INTERNAL_WRITE, NULL); + return ret; +} +#endif + +#if 0 +u16_t zfiDbgProgramFlash(zdev_t *dev, u32_t offset, u32_t len, u32_t *data) +{ + u32_t cmd[(ZM_MAX_CMD_SIZE/4)]; + u16_t ret; + u16_t i; + + + cmd[0] = (ZM_CMD_FLASH_PROG << 8) | ((len+8) & 0xff); + cmd[1] = offset; + cmd[2] = len; + + for (i = 0; i < (len >> 2); i++) + { + cmd[3+i] = data[i]; + } + + ret = zfIssueCmd(dev, cmd, 12, ZM_OID_FLASH_PROGRAM, NULL); + + return ret; +} +#endif + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfiDbgChipEraseFlash */ +/* Chip Erase Flash. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* 0 : success */ +/* other : fail */ +/* */ +/* AUTHOR */ +/* Paul Atheros Technology Corporation 2007.09 */ +/* */ +/************************************************************************/ +u16_t zfiDbgChipEraseFlash(zdev_t *dev) +{ + u32_t cmd[(ZM_MAX_CMD_SIZE/4)]; + u16_t ret; + + cmd[0] = 0x00000000 | (ZM_CMD_FLASH_ERASE << 8); + + ret = zfIssueCmd(dev, cmd, 4, ZM_OID_INTERNAL_WRITE, NULL); + return ret; +} +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfiDbgGetFlashCheckSum */ +/* Get FlashCheckSum. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* addr : Start address of getchksum */ +/* len : total lenth of calculate getchksum */ +/* */ +/* OUTPUTS */ +/* 0 : success */ +/* other : fail */ +/* */ +/* AUTHOR */ +/* Paul Atheros Technology Corporation 2007.08 */ +/* */ +/************************************************************************/ +u32_t zfiDbgGetFlashCheckSum(zdev_t *dev, u32_t addr, u32_t len) +{ + u32_t cmd[(ZM_MAX_CMD_SIZE/4)]; + u32_t ret; + + cmd[0] = 0x00000008 | (ZM_CMD_FLASH_CHKSUM << 8); + cmd[1] = addr; + cmd[2] = len; + + ret = zfIssueCmd(dev, cmd, 12, ZM_OID_FLASH_CHKSUM, NULL); + + return ret; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfiDbgReadFlash */ +/* Read Flash. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* addr : Start address of read flash */ +/* len : total lenth of read flash data */ +/* */ +/* OUTPUTS */ +/* 0 : success */ +/* other : fail */ +/* */ +/* AUTHOR */ +/* Paul Atheros Technology Corporation 2007.09 */ +/* */ +/************************************************************************/ +u32_t zfiDbgReadFlash(zdev_t *dev, u32_t addr, u32_t len) +{ + u32_t cmd[(ZM_MAX_CMD_SIZE/4)]; + u32_t ret; + + cmd[0] = len | (ZM_CMD_FLASH_READ << 8); + cmd[1] = addr; + + ret = zfIssueCmd(dev, cmd, 8, ZM_OID_FLASH_READ, NULL); + return ret; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfiDownloadFwSet */ +/* Before Download FW, */ +/* Command FW to Software reset and close watch dog control. */ +/* */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* 0 : success */ +/* other : fail */ +/* */ +/* AUTHOR */ +/* Paul Atheros Technology Corporation 2007.09 */ +/* */ +/************************************************************************/ +u32_t zfiDownloadFwSet(zdev_t *dev) +{ +//softwarereset +//close watch dog + u32_t cmd[(ZM_MAX_CMD_SIZE/4)]; + u32_t ret; + + cmd[0] = 0x00000008 | (ZM_CMD_FW_DL_INIT << 8); + + ret = zfIssueCmd(dev, cmd, 12, ZM_OID_FW_DL_INIT, NULL); + + return ret; +} +//Paul-- --- linux-2.6.28.orig/drivers/staging/otus/hal/hpani.h +++ linux-2.6.28/drivers/staging/otus/hal/hpani.h @@ -0,0 +1,420 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "../80211core/cprecomp.h" + +typedef struct { + u32_t ackrcv_bad; + u32_t rts_bad; + u32_t rts_good; + u32_t fcs_bad; + u32_t beacons; +} ZM_HAL_MIB_STATS; + +/* + * Per-node statistics maintained by the driver for use in + * optimizing signal quality and other operational aspects. + */ +typedef struct { + u32_t ns_avgbrssi; /* average beacon rssi */ + u32_t ns_avgrssi; /* average data rssi */ + u32_t ns_avgtxrssi; /* average tx rssi */ +} ZM_HAL_NODE_STATS; + +#define ZM_HAL_RSSI_EP_MULTIPLIER (1<<7) /* pow2 to optimize out * and / */ + +struct zsAniStats { + u32_t ast_ani_niup; /* ANI increased noise immunity */ + u32_t ast_ani_nidown; /* ANI decreased noise immunity */ + u32_t ast_ani_spurup; /* ANI increased spur immunity */ + u32_t ast_ani_spurdown;/* ANI descreased spur immunity */ + u32_t ast_ani_ofdmon; /* ANI OFDM weak signal detect on */ + u32_t ast_ani_ofdmoff;/* ANI OFDM weak signal detect off */ + u32_t ast_ani_cckhigh;/* ANI CCK weak signal threshold high */ + u32_t ast_ani_ccklow; /* ANI CCK weak signal threshold low */ + u32_t ast_ani_stepup; /* ANI increased first step level */ + u32_t ast_ani_stepdown;/* ANI decreased first step level */ + u32_t ast_ani_ofdmerrs;/* ANI cumulative ofdm phy err count */ + u32_t ast_ani_cckerrs;/* ANI cumulative cck phy err count */ + u32_t ast_ani_reset; /* ANI parameters zero'd for non-STA */ + u32_t ast_ani_lzero; /* ANI listen time forced to zero */ + u32_t ast_ani_lneg; /* ANI listen time calculated < 0 */ + ZM_HAL_MIB_STATS ast_mibstats; /* MIB counter stats */ + ZM_HAL_NODE_STATS ast_nodestats; /* Latest rssi stats from driver */ +}; + +/* + * Per-channel ANI state private to the driver. + */ +struct zsAniState { + ZM_HAL_CHANNEL c; + u8_t noiseImmunityLevel; + u8_t spurImmunityLevel; + u8_t firstepLevel; + u8_t ofdmWeakSigDetectOff; + u8_t cckWeakSigThreshold; + + /* Thresholds */ + u32_t listenTime; + u32_t ofdmTrigHigh; + u32_t ofdmTrigLow; + s32_t cckTrigHigh; + s32_t cckTrigLow; + s32_t rssiThrLow; + s32_t rssiThrHigh; + + u32_t noiseFloor; /* The current noise floor */ + u32_t txFrameCount; /* Last txFrameCount */ + u32_t rxFrameCount; /* Last rx Frame count */ + u32_t cycleCount; /* Last cycleCount (can detect wrap-around) */ + u32_t ofdmPhyErrCount;/* OFDM err count since last reset */ + u32_t cckPhyErrCount; /* CCK err count since last reset */ + u32_t ofdmPhyErrBase; /* Base value for ofdm err counter */ + u32_t cckPhyErrBase; /* Base value for cck err counters */ + s16_t pktRssi[2]; /* Average rssi of pkts for 2 antennas */ + s16_t ofdmErrRssi[2]; /* Average rssi of ofdm phy errs for 2 ant */ + s16_t cckErrRssi[2]; /* Average rssi of cck phy errs for 2 ant */ +}; + +typedef enum { + ZM_HAL_ANI_PRESENT, /* is ANI support present */ + ZM_HAL_ANI_NOISE_IMMUNITY_LEVEL, /* set level */ + ZM_HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION, /* enable/disable */ + ZM_HAL_ANI_CCK_WEAK_SIGNAL_THR, /* enable/disable */ + ZM_HAL_ANI_FIRSTEP_LEVEL, /* set level */ + ZM_HAL_ANI_SPUR_IMMUNITY_LEVEL, /* set level */ + ZM_HAL_ANI_MODE, /* 0 => manual, 1 => auto */ + ZM_HAL_ANI_PHYERR_RESET, /* reset phy error stats */ +} ZM_HAL_ANI_CMD; + +#define AR_PHY_COUNTMAX (3 << 22) // Max counted before intr +#define ZM_HAL_PROCESS_ANI 0x00000001 /* ANI state setup */ +#define ZM_RSSI_DUMMY_MARKER 0x127 + +/* PHY registers in ar5416, related base and register offsets + may need to be changed in otus BB */ +#define AR_PHY_BASE 0x1C5800 /* base address of phy regs */ +#define AR_PHY(_n) (AR_PHY_BASE + ((_n)<<2)) + +#define AR_PHY_TEST 0x1C5800 /* PHY test control */ +#define PHY_AGC_CLR 0x10000000 /* disable AGC to A2 */ +#define RFSILENT_BB 0x00002000 /* shush bb */ + +#define AR_PHY_TURBO 0x1C5804 /* frame control register */ +#define AR_PHY_FC_TURBO_MODE 0x00000001 /* Set turbo mode bits */ +#define AR_PHY_FC_TURBO_SHORT 0x00000002 /* Set short symbols to turbo mode setting */ +#define AR_PHY_FC_DYN2040_EN 0x00000004 /* Enable dyn 20/40 mode */ +#define AR_PHY_FC_DYN2040_PRI_ONLY 0x00000008 /* dyn 20/40 - primary only */ +#define AR_PHY_FC_DYN2040_PRI_CH 0x00000010 /* dyn 20/40 - primary ch offset (0=+10MHz, 1=-10MHz)*/ +#define AR_PHY_FC_DYN2040_EXT_CH 0x00000020 /* dyn 20/40 - ext ch spacing (0=20MHz/ 1=25MHz) */ +#define AR_PHY_FC_HT_EN 0x00000040 /* ht enable */ +#define AR_PHY_FC_SHORT_GI_40 0x00000080 /* allow short GI for HT 40 */ +#define AR_PHY_FC_WALSH 0x00000100 /* walsh spatial spreading for 2 chains,2 streams TX */ +#define AR_PHY_FC_SINGLE_HT_LTF1 0x00000200 /* single length (4us) 1st HT long training symbol */ + +#define AR_PHY_TIMING2 0x1C5810 /* Timing Control 2 */ +#define AR_PHY_TIMING2_USE_FORCE 0x00001000 +#define AR_PHY_TIMING2_FORCE_VAL 0x00000fff + +#define AR_PHY_TIMING3 0x1C5814 /* Timing control 3 */ +#define AR_PHY_TIMING3_DSC_MAN 0xFFFE0000 +#define AR_PHY_TIMING3_DSC_MAN_S 17 +#define AR_PHY_TIMING3_DSC_EXP 0x0001E000 +#define AR_PHY_TIMING3_DSC_EXP_S 13 + +#define AR_PHY_CHIP_ID 0x1C5818 /* PHY chip revision ID */ +#define AR_PHY_CHIP_ID_REV_0 0x80 /* 5416 Rev 0 (owl 1.0) BB */ +#define AR_PHY_CHIP_ID_REV_1 0x81 /* 5416 Rev 1 (owl 2.0) BB */ + +#define AR_PHY_ACTIVE 0x1C581C /* activation register */ +#define AR_PHY_ACTIVE_EN 0x00000001 /* Activate PHY chips */ +#define AR_PHY_ACTIVE_DIS 0x00000000 /* Deactivate PHY chips */ + +#define AR_PHY_RF_CTL2 0x1C5824 +#define AR_PHY_TX_END_DATA_START 0x000000FF +#define AR_PHY_TX_END_DATA_START_S 0 +#define AR_PHY_TX_END_PA_ON 0x0000FF00 +#define AR_PHY_TX_END_PA_ON_S 8 + + +#define AR_PHY_RF_CTL3 0x1C5828 +#define AR_PHY_TX_END_TO_A2_RX_ON 0x00FF0000 +#define AR_PHY_TX_END_TO_A2_RX_ON_S 16 + +#define AR_PHY_ADC_CTL 0x1C582C +#define AR_PHY_ADC_CTL_OFF_INBUFGAIN 0x00000003 +#define AR_PHY_ADC_CTL_OFF_INBUFGAIN_S 0 +#define AR_PHY_ADC_CTL_OFF_PWDDAC 0x00002000 +#define AR_PHY_ADC_CTL_OFF_PWDBANDGAP 0x00004000 /* BB Rev 4.2+ only */ +#define AR_PHY_ADC_CTL_OFF_PWDADC 0x00008000 /* BB Rev 4.2+ only */ +#define AR_PHY_ADC_CTL_ON_INBUFGAIN 0x00030000 +#define AR_PHY_ADC_CTL_ON_INBUFGAIN_S 16 + +#define AR_PHY_ADC_SERIAL_CTL 0x1C5830 +#define AR_PHY_SEL_INTERNAL_ADDAC 0x00000000 +#define AR_PHY_SEL_EXTERNAL_RADIO 0x00000001 + +#define AR_PHY_RF_CTL4 0x1C5834 +#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF 0xFF000000 +#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF_S 24 +#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF 0x00FF0000 +#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF_S 16 +#define AR_PHY_RF_CTL4_FRAME_XPAB_ON 0x0000FF00 +#define AR_PHY_RF_CTL4_FRAME_XPAB_ON_S 8 +#define AR_PHY_RF_CTL4_FRAME_XPAA_ON 0x000000FF +#define AR_PHY_RF_CTL4_FRAME_XPAA_ON_S 0 + +#define AR_PHY_SETTLING 0x1C5844 +#define AR_PHY_SETTLING_SWITCH 0x00003F80 +#define AR_PHY_SETTLING_SWITCH_S 7 + +#define AR_PHY_RXGAIN 0x1C5848 +#define AR_PHY_RXGAIN_TXRX_ATTEN 0x0003F000 +#define AR_PHY_RXGAIN_TXRX_ATTEN_S 12 +#define AR_PHY_RXGAIN_TXRX_RF_MAX 0x007C0000 +#define AR_PHY_RXGAIN_TXRX_RF_MAX_S 18 + +#define AR_PHY_DESIRED_SZ 0x1C5850 +#define AR_PHY_DESIRED_SZ_ADC 0x000000FF +#define AR_PHY_DESIRED_SZ_ADC_S 0 +#define AR_PHY_DESIRED_SZ_PGA 0x0000FF00 +#define AR_PHY_DESIRED_SZ_PGA_S 8 +#define AR_PHY_DESIRED_SZ_TOT_DES 0x0FF00000 +#define AR_PHY_DESIRED_SZ_TOT_DES_S 20 + +#define AR_PHY_FIND_SIG 0x1C5858 +#define AR_PHY_FIND_SIG_FIRSTEP 0x0003F000 +#define AR_PHY_FIND_SIG_FIRSTEP_S 12 +#define AR_PHY_FIND_SIG_FIRPWR 0x03FC0000 +#define AR_PHY_FIND_SIG_FIRPWR_S 18 + +#define AR_PHY_AGC_CTL1 0x1C585C +#define AR_PHY_AGC_CTL1_COARSE_LOW 0x00007F80 +#define AR_PHY_AGC_CTL1_COARSE_LOW_S 7 +#define AR_PHY_AGC_CTL1_COARSE_HIGH 0x003F8000 +#define AR_PHY_AGC_CTL1_COARSE_HIGH_S 15 + +#define AR_PHY_AGC_CONTROL 0x1C5860 /* chip calibration and noise floor setting */ +#define AR_PHY_AGC_CONTROL_CAL 0x00000001 /* do internal calibration */ +#define AR_PHY_AGC_CONTROL_NF 0x00000002 /* do noise-floor calculation */ + +#define AR_PHY_CCA 0x1C5864 +#define AR_PHY_MINCCA_PWR 0x1FF00000 +#define AR_PHY_MINCCA_PWR_S 19 +#define AR_PHY_CCA_THRESH62 0x0007F000 +#define AR_PHY_CCA_THRESH62_S 12 + +#define AR_PHY_SFCORR_LOW 0x1C586C +#define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW 0x00000001 +#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW 0x00003F00 +#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S 8 +#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW 0x001FC000 +#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S 14 +#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW 0x0FE00000 +#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S 21 + +#define AR_PHY_SFCORR 0x1C5868 +#define AR_PHY_SFCORR_M2COUNT_THR 0x0000001F +#define AR_PHY_SFCORR_M2COUNT_THR_S 0 +#define AR_PHY_SFCORR_M1_THRESH 0x00FE0000 +#define AR_PHY_SFCORR_M1_THRESH_S 17 +#define AR_PHY_SFCORR_M2_THRESH 0x7F000000 +#define AR_PHY_SFCORR_M2_THRESH_S 24 + +#define AR_PHY_SLEEP_CTR_CONTROL 0x1C5870 +#define AR_PHY_SLEEP_CTR_LIMIT 0x1C5874 +#define AR_PHY_SLEEP_SCAL 0x1C5878 + +#define AR_PHY_PLL_CTL 0x1C587c /* PLL control register */ +#define AR_PHY_PLL_CTL_40 0xaa /* 40 MHz */ +#define AR_PHY_PLL_CTL_40_5413 0x04 +#define AR_PHY_PLL_CTL_44 0xab /* 44 MHz for 11b, 11g */ +#define AR_PHY_PLL_CTL_44_2133 0xeb /* 44 MHz for 11b, 11g */ +#define AR_PHY_PLL_CTL_40_2133 0xea /* 40 MHz for 11a, turbos */ + +#define AR_PHY_RX_DELAY 0x1C5914 /* analog pow-on time (100ns) */ +#define AR_PHY_RX_DELAY_DELAY 0x00003FFF /* delay from wakeup to rx ena */ + +#define AR_PHY_TIMING_CTRL4 0x1C5920 /* timing control */ +#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF 0x01F /* Mask for kcos_theta-1 for q correction */ +#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S 0 /* shift for Q_COFF */ +#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF 0x7E0 /* Mask for sin_theta for i correction */ +#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S 5 /* Shift for sin_theta for i correction */ +#define AR_PHY_TIMING_CTRL4_IQCORR_ENABLE 0x800 /* enable IQ correction */ +#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX 0xF000 /* Mask for max number of samples (logarithmic) */ +#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S 12 /* Shift for max number of samples */ +#define AR_PHY_TIMING_CTRL4_DO_IQCAL 0x10000 /* perform IQ calibration */ + +#define AR_PHY_TIMING5 0x1C5924 +#define AR_PHY_TIMING5_CYCPWR_THR1 0x000000FE +#define AR_PHY_TIMING5_CYCPWR_THR1_S 1 + +#define AR_PHY_POWER_TX_RATE1 0x1C5934 +#define AR_PHY_POWER_TX_RATE2 0x1C5938 +#define AR_PHY_POWER_TX_RATE_MAX 0x1C593c +#define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040 + +#define AR_PHY_FRAME_CTL 0x1C5944 +#define AR_PHY_FRAME_CTL_TX_CLIP 0x00000038 +#define AR_PHY_FRAME_CTL_TX_CLIP_S 3 + +#define AR_PHY_TXPWRADJ 0x1C594C /* BB Rev 4.2+ only */ +#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA 0x00000FC0 +#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA_S 6 +#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX 0x00FC0000 +#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX_S 18 + +#define AR_PHY_RADAR_0 0x1C5954 /* radar detection settings */ +#define AR_PHY_RADAR_0_ENA 0x00000001 /* Enable radar detection */ +#define AR_PHY_RADAR_0_INBAND 0x0000003e /* Inband pulse threshold */ +#define AR_PHY_RADAR_0_INBAND_S 1 +#define AR_PHY_RADAR_0_PRSSI 0x00000FC0 /* Pulse rssi threshold */ +#define AR_PHY_RADAR_0_PRSSI_S 6 +#define AR_PHY_RADAR_0_HEIGHT 0x0003F000 /* Pulse height threshold */ +#define AR_PHY_RADAR_0_HEIGHT_S 12 +#define AR_PHY_RADAR_0_RRSSI 0x00FC0000 /* Radar rssi threshold */ +#define AR_PHY_RADAR_0_RRSSI_S 18 +#define AR_PHY_RADAR_0_FIRPWR 0x7F000000 /* Radar firpwr threshold */ +#define AR_PHY_RADAR_0_FIRPWR_S 24 + +#define AR_PHY_SWITCH_CHAIN_0 0x1C5960 +#define AR_PHY_SWITCH_COM 0x1C5964 + +#define AR_PHY_SIGMA_DELTA 0x1C596C /* AR5312 only */ +#define AR_PHY_SIGMA_DELTA_ADC_SEL 0x00000003 +#define AR_PHY_SIGMA_DELTA_ADC_SEL_S 0 +#define AR_PHY_SIGMA_DELTA_FILT2 0x000000F8 +#define AR_PHY_SIGMA_DELTA_FILT2_S 3 +#define AR_PHY_SIGMA_DELTA_FILT1 0x00001F00 +#define AR_PHY_SIGMA_DELTA_FILT1_S 8 +#define AR_PHY_SIGMA_DELTA_ADC_CLIP 0x01FFE000 +#define AR_PHY_SIGMA_DELTA_ADC_CLIP_S 13 + +#define AR_PHY_RESTART 0x1C5970 /* restart */ +#define AR_PHY_RESTART_DIV_GC 0x001C0000 /* bb_ant_fast_div_gc_limit */ +#define AR_PHY_RESTART_DIV_GC_S 18 + +#define AR_PHY_RFBUS_REQ 0x1C597C +#define AR_PHY_RFBUS_REQ_EN 0x00000001 + +#define AR_PHY_RX_CHAINMASK 0x1C59a4 + +#define AR_PHY_EXT_CCA 0x1C59bc +#define AR_PHY_EXT_MINCCA_PWR 0xFF800000 +#define AR_PHY_EXT_MINCCA_PWR_S 23 + +#define AR_PHY_HALFGI 0x1C59D0 /* Timing control 3 */ +#define AR_PHY_HALFGI_DSC_MAN 0x0007FFF0 +#define AR_PHY_HALFGI_DSC_MAN_S 4 +#define AR_PHY_HALFGI_DSC_EXP 0x0000000F +#define AR_PHY_HALFGI_DSC_EXP_S 0 + +#define AR_PHY_HEAVY_CLIP_ENABLE 0x1C59E0 + +#define AR_PHY_M_SLEEP 0x1C59f0 /* sleep control registers */ +#define AR_PHY_REFCLKDLY 0x1C59f4 +#define AR_PHY_REFCLKPD 0x1C59f8 + +/* PHY IQ calibration results */ +#define AR_PHY_IQCAL_RES_PWR_MEAS_I 0x1C5C10 /* power measurement for I */ +#define AR_PHY_IQCAL_RES_PWR_MEAS_Q 0x1C5C14 /* power measurement for Q */ +#define AR_PHY_IQCAL_RES_IQ_CORR_MEAS 0x1C5C18 /* IQ correlation measurement */ + +#define AR_PHY_CURRENT_RSSI 0x1C5C1c /* rssi of current frame rx'd */ + +#define AR_PHY_RFBUS_GRANT 0x1C5C20 +#define AR_PHY_RFBUS_GRANT_EN 0x00000001 + +#define AR_PHY_MODE 0x1C6200 /* Mode register */ +#define AR_PHY_MODE_AR2133 0x08 /* AR2133 */ +#define AR_PHY_MODE_AR5111 0x00 /* AR5111/AR2111 */ +#define AR_PHY_MODE_AR5112 0x08 /* AR5112*/ +#define AR_PHY_MODE_DYNAMIC 0x04 /* dynamic CCK/OFDM mode */ +#define AR_PHY_MODE_RF2GHZ 0x02 /* 2.4 GHz */ +#define AR_PHY_MODE_RF5GHZ 0x00 /* 5 GHz */ +#define AR_PHY_MODE_CCK 0x01 /* CCK */ +#define AR_PHY_MODE_OFDM 0x00 /* OFDM */ + +#define AR_PHY_CCK_TX_CTRL 0x1C6204 +#define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010 + +#define AR_PHY_CCK_DETECT 0x1C6208 +#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003F +#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0 +#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001FC0 // [12:6] settling time for antenna switch +#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6 +#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000 + +#define AR_PHY_GAIN_2GHZ 0x1C620C +#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00FC0000 +#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN_S 18 +#define AR_PHY_GAIN_2GHZ_BSW_MARGIN 0x00003C00 +#define AR_PHY_GAIN_2GHZ_BSW_MARGIN_S 10 +#define AR_PHY_GAIN_2GHZ_BSW_ATTEN 0x0000001F +#define AR_PHY_GAIN_2GHZ_BSW_ATTEN_S 0 + +#define AR_PHY_CCK_RXCTRL4 0x1C621C +#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT 0x01F80000 +#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19 + +#define AR_PHY_DAG_CTRLCCK 0x1C6228 +#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR 0x00000200 /* BB Rev 4.2+ only */ +#define AR_PHY_DAG_CTRLCCK_RSSI_THR 0x0001FC00 /* BB Rev 4.2+ only */ +#define AR_PHY_DAG_CTRLCCK_RSSI_THR_S 10 /* BB Rev 4.2+ only */ + +#define AR_PHY_POWER_TX_RATE3 0x1C6234 +#define AR_PHY_POWER_TX_RATE4 0x1C6238 + +#define AR_PHY_SCRM_SEQ_XR 0x1C623C +#define AR_PHY_HEADER_DETECT_XR 0x1C6240 +#define AR_PHY_CHIRP_DETECTED_XR 0x1C6244 +#define AR_PHY_BLUETOOTH 0x1C6254 + +#define AR_PHY_TPCRG1 0x1C6258 /* ar2413 power control */ +#define AR_PHY_TPCRG1_NUM_PD_GAIN 0x0000c000 +#define AR_PHY_TPCRG1_NUM_PD_GAIN_S 14 + +#define AR_PHY_TPCRG1_PD_GAIN_1 0x00030000 +#define AR_PHY_TPCRG1_PD_GAIN_1_S 16 +#define AR_PHY_TPCRG1_PD_GAIN_2 0x000C0000 +#define AR_PHY_TPCRG1_PD_GAIN_2_S 18 +#define AR_PHY_TPCRG1_PD_GAIN_3 0x00300000 +#define AR_PHY_TPCRG1_PD_GAIN_3_S 20 +// + +#define AR_PHY_ANALOG_SWAP 0xa268 +#define AR_PHY_SWAP_ALT_CHAIN 0x00000040 + +#define AR_PHY_TPCRG5 0x1C626C /* ar2413 power control */ +#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP 0x0000000F +#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S 0 +#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1 0x000003F0 +#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S 4 +#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2 0x0000FC00 +#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S 10 +#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3 0x003F0000 +#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S 16 +#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4 0x0FC00000 +#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S 22 + +#define AR_PHY_POWER_TX_RATE5 0x1C638C +#define AR_PHY_POWER_TX_RATE6 0x1C6390 + +#define AR_PHY_CAL_CHAINMASK 0x1C639C + +#define AR_PHY_POWER_TX_SUB 0x1C63C8 +#define AR_PHY_POWER_TX_RATE7 0x1C63CC +#define AR_PHY_POWER_TX_RATE8 0x1C63D0 +#define AR_PHY_POWER_TX_RATE9 0x1C63D4 --- linux-2.6.28.orig/drivers/staging/otus/hal/hpani.c +++ linux-2.6.28/drivers/staging/otus/hal/hpani.c @@ -0,0 +1,732 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "../80211core/cprecomp.h" +#include "hpani.h" +#include "hpusb.h" + + +extern u16_t zfDelayWriteInternalReg(zdev_t* dev, u32_t addr, u32_t val); +extern u16_t zfFlushDelayWrite(zdev_t* dev); + +/* + * Anti noise immunity support. We track phy errors and react + * to excessive errors by adjusting the noise immunity parameters. + */ + +/****************************************************************************** + * + * New Ani Algorithm for Station side only + * + *****************************************************************************/ + +#define ZM_HAL_NOISE_IMMUNE_MAX 4 /* Max noise immunity level */ +#define ZM_HAL_SPUR_IMMUNE_MAX 7 /* Max spur immunity level */ +#define ZM_HAL_FIRST_STEP_MAX 2 /* Max first step level */ + +#define ZM_HAL_ANI_OFDM_TRIG_HIGH 500 +#define ZM_HAL_ANI_OFDM_TRIG_LOW 200 +#define ZM_HAL_ANI_CCK_TRIG_HIGH 200 +#define ZM_HAL_ANI_CCK_TRIG_LOW 100 +#define ZM_HAL_ANI_NOISE_IMMUNE_LVL 4 +#define ZM_HAL_ANI_USE_OFDM_WEAK_SIG TRUE +#define ZM_HAL_ANI_CCK_WEAK_SIG_THR FALSE +#define ZM_HAL_ANI_SPUR_IMMUNE_LVL 7 +#define ZM_HAL_ANI_FIRSTEP_LVL 0 +#define ZM_HAL_ANI_RSSI_THR_HIGH 40 +#define ZM_HAL_ANI_RSSI_THR_LOW 7 +#define ZM_HAL_ANI_PERIOD 100 + +#define ZM_HAL_EP_RND(x, mul) \ + ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) + +s32_t BEACON_RSSI(zdev_t* dev) +{ + s32_t rssi; + + zmw_get_wlan_dev(dev); + + struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate; + + rssi = ZM_HAL_EP_RND(HpPriv->stats.ast_nodestats.ns_avgbrssi, ZM_HAL_RSSI_EP_MULTIPLIER); + + return rssi; +} + +/* + * Setup ANI handling. Sets all thresholds and levels to default level AND + * resets the channel statistics + */ + +void zfHpAniAttach(zdev_t* dev) +{ +#define N(a) (sizeof(a) / sizeof(a[0])) + u32_t i; + + zmw_get_wlan_dev(dev); + + struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate; + + const int totalSizeDesired[] = { -55, -55, -55, -55, -62 }; + const int coarseHigh[] = { -14, -14, -14, -14, -12 }; + const int coarseLow[] = { -64, -64, -64, -64, -70 }; + const int firpwr[] = { -78, -78, -78, -78, -80 }; + + for (i = 0; i < 5; i++) + { + HpPriv->totalSizeDesired[i] = totalSizeDesired[i]; + HpPriv->coarseHigh[i] = coarseHigh[i]; + HpPriv->coarseLow[i] = coarseLow[i]; + HpPriv->firpwr[i] = firpwr[i]; + } + + /* owl has phy counters */ + HpPriv->hasHwPhyCounters = 1; + + memset((char *)&HpPriv->ani, 0, sizeof(HpPriv->ani)); + for (i = 0; i < N(wd->regulationTable.allowChannel); i++) + { + /* New ANI stuff */ + HpPriv->ani[i].ofdmTrigHigh = ZM_HAL_ANI_OFDM_TRIG_HIGH; + HpPriv->ani[i].ofdmTrigLow = ZM_HAL_ANI_OFDM_TRIG_LOW; + HpPriv->ani[i].cckTrigHigh = ZM_HAL_ANI_CCK_TRIG_HIGH; + HpPriv->ani[i].cckTrigLow = ZM_HAL_ANI_CCK_TRIG_LOW; + HpPriv->ani[i].rssiThrHigh = ZM_HAL_ANI_RSSI_THR_HIGH; + HpPriv->ani[i].rssiThrLow = ZM_HAL_ANI_RSSI_THR_LOW; + HpPriv->ani[i].ofdmWeakSigDetectOff = !ZM_HAL_ANI_USE_OFDM_WEAK_SIG; + HpPriv->ani[i].cckWeakSigThreshold = ZM_HAL_ANI_CCK_WEAK_SIG_THR; + HpPriv->ani[i].spurImmunityLevel = ZM_HAL_ANI_SPUR_IMMUNE_LVL; + HpPriv->ani[i].firstepLevel = ZM_HAL_ANI_FIRSTEP_LVL; + if (HpPriv->hasHwPhyCounters) + { + HpPriv->ani[i].ofdmPhyErrBase = 0;//AR_PHY_COUNTMAX - ZM_HAL_ANI_OFDM_TRIG_HIGH; + HpPriv->ani[i].cckPhyErrBase = 0;//AR_PHY_COUNTMAX - ZM_HAL_ANI_CCK_TRIG_HIGH; + } + } + if (HpPriv->hasHwPhyCounters) + { + //zm_debug_msg2("Setting OfdmErrBase = 0x", HpPriv->ani[0].ofdmPhyErrBase); + //zm_debug_msg2("Setting cckErrBase = 0x", HpPriv->ani[0].cckPhyErrBase); + //OS_REG_WRITE(ah, AR_PHY_ERR_1, HpPriv->ani[0].ofdmPhyErrBase); + //OS_REG_WRITE(ah, AR_PHY_ERR_2, HpPriv->ani[0].cckPhyErrBase); + } + HpPriv->aniPeriod = ZM_HAL_ANI_PERIOD; + //if (ath_hal_enableANI) + HpPriv->procPhyErr |= ZM_HAL_PROCESS_ANI; + + HpPriv->stats.ast_nodestats.ns_avgbrssi = ZM_RSSI_DUMMY_MARKER; + HpPriv->stats.ast_nodestats.ns_avgrssi = ZM_RSSI_DUMMY_MARKER; + HpPriv->stats.ast_nodestats.ns_avgtxrssi = ZM_RSSI_DUMMY_MARKER; +#undef N +} + +/* + * Control Adaptive Noise Immunity Parameters + */ +u8_t zfHpAniControl(zdev_t* dev, ZM_HAL_ANI_CMD cmd, int param) +{ +#define N(a) (sizeof(a)/sizeof(a[0])) + typedef s32_t TABLE[]; + + zmw_get_wlan_dev(dev); + + struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate; + + struct zsAniState *aniState = HpPriv->curani; + + switch (cmd) + { + case ZM_HAL_ANI_NOISE_IMMUNITY_LEVEL: + { + u32_t level = param; + + if (level >= N(HpPriv->totalSizeDesired)) + { + zm_debug_msg1("level out of range, desired level : ", level); + zm_debug_msg1("max level : ", N(HpPriv->totalSizeDesired)); + return FALSE; + } + + zfDelayWriteInternalReg(dev, AR_PHY_DESIRED_SZ, + (HpPriv->regPHYDesiredSZ & ~AR_PHY_DESIRED_SZ_TOT_DES) + | ((HpPriv->totalSizeDesired[level] << AR_PHY_DESIRED_SZ_TOT_DES_S) + & AR_PHY_DESIRED_SZ_TOT_DES)); + zfDelayWriteInternalReg(dev, AR_PHY_AGC_CTL1, + (HpPriv->regPHYAgcCtl1 & ~AR_PHY_AGC_CTL1_COARSE_LOW) + | ((HpPriv->coarseLow[level] << AR_PHY_AGC_CTL1_COARSE_LOW_S) + & AR_PHY_AGC_CTL1_COARSE_LOW)); + zfDelayWriteInternalReg(dev, AR_PHY_AGC_CTL1, + (HpPriv->regPHYAgcCtl1 & ~AR_PHY_AGC_CTL1_COARSE_HIGH) + | ((HpPriv->coarseHigh[level] << AR_PHY_AGC_CTL1_COARSE_HIGH_S) + & AR_PHY_AGC_CTL1_COARSE_HIGH)); + zfDelayWriteInternalReg(dev, AR_PHY_FIND_SIG, + (HpPriv->regPHYFindSig & ~AR_PHY_FIND_SIG_FIRPWR) + | ((HpPriv->firpwr[level] << AR_PHY_FIND_SIG_FIRPWR_S) + & AR_PHY_FIND_SIG_FIRPWR)); + zfFlushDelayWrite(dev); + + if (level > aniState->noiseImmunityLevel) + HpPriv->stats.ast_ani_niup++; + else if (level < aniState->noiseImmunityLevel) + HpPriv->stats.ast_ani_nidown++; + aniState->noiseImmunityLevel = (u8_t)level; + break; + } + case ZM_HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION: + { + const TABLE m1ThreshLow = { 127, 50 }; + const TABLE m2ThreshLow = { 127, 40 }; + const TABLE m1Thresh = { 127, 0x4d }; + const TABLE m2Thresh = { 127, 0x40 }; + const TABLE m2CountThr = { 31, 16 }; + const TABLE m2CountThrLow = { 63, 48 }; + u32_t on = param ? 1 : 0; + + zfDelayWriteInternalReg(dev, AR_PHY_SFCORR_LOW, + (HpPriv->regPHYSfcorrLow & ~AR_PHY_SFCORR_LOW_M1_THRESH_LOW) + | ((m1ThreshLow[on] << AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S) + & AR_PHY_SFCORR_LOW_M1_THRESH_LOW)); + zfDelayWriteInternalReg(dev, AR_PHY_SFCORR_LOW, + (HpPriv->regPHYSfcorrLow & ~AR_PHY_SFCORR_LOW_M2_THRESH_LOW) + | ((m2ThreshLow[on] << AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S) + & AR_PHY_SFCORR_LOW_M2_THRESH_LOW)); + zfDelayWriteInternalReg(dev, AR_PHY_SFCORR, + (HpPriv->regPHYSfcorr & ~AR_PHY_SFCORR_M1_THRESH) + | ((m1Thresh[on] << AR_PHY_SFCORR_M1_THRESH_S) + & AR_PHY_SFCORR_M1_THRESH)); + zfDelayWriteInternalReg(dev, AR_PHY_SFCORR, + (HpPriv->regPHYSfcorr & ~AR_PHY_SFCORR_M2_THRESH) + | ((m2Thresh[on] << AR_PHY_SFCORR_M2_THRESH_S) + & AR_PHY_SFCORR_M2_THRESH)); + zfDelayWriteInternalReg(dev, AR_PHY_SFCORR, + (HpPriv->regPHYSfcorr & ~AR_PHY_SFCORR_M2COUNT_THR) + | ((m2CountThr[on] << AR_PHY_SFCORR_M2COUNT_THR_S) + & AR_PHY_SFCORR_M2COUNT_THR)); + zfDelayWriteInternalReg(dev, AR_PHY_SFCORR_LOW, + (HpPriv->regPHYSfcorrLow & ~AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW) + | ((m2CountThrLow[on] << AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S) + & AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW)); + + if (on) + { + zfDelayWriteInternalReg(dev, AR_PHY_SFCORR_LOW, + HpPriv->regPHYSfcorrLow | AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); + } + else + { + zfDelayWriteInternalReg(dev, AR_PHY_SFCORR_LOW, + HpPriv->regPHYSfcorrLow & ~AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); + } + zfFlushDelayWrite(dev); + if (!on != aniState->ofdmWeakSigDetectOff) + { + if (on) + HpPriv->stats.ast_ani_ofdmon++; + else + HpPriv->stats.ast_ani_ofdmoff++; + aniState->ofdmWeakSigDetectOff = !on; + } + break; + } + case ZM_HAL_ANI_CCK_WEAK_SIGNAL_THR: + { + const TABLE weakSigThrCck = { 8, 6 }; + u32_t high = param ? 1 : 0; + + zfDelayWriteInternalReg(dev, AR_PHY_CCK_DETECT, + (HpPriv->regPHYCckDetect & ~AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK) + | ((weakSigThrCck[high] << AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S) + & AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK)); + zfFlushDelayWrite(dev); + if (high != aniState->cckWeakSigThreshold) + { + if (high) + HpPriv->stats.ast_ani_cckhigh++; + else + HpPriv->stats.ast_ani_ccklow++; + aniState->cckWeakSigThreshold = (u8_t)high; + } + break; + } + case ZM_HAL_ANI_FIRSTEP_LEVEL: + { + const TABLE firstep = { 0, 4, 8 }; + u32_t level = param; + + if (level >= N(firstep)) + { + zm_debug_msg1("level out of range, desired level : ", level); + zm_debug_msg1("max level : ", N(firstep)); + return FALSE; + } + zfDelayWriteInternalReg(dev, AR_PHY_FIND_SIG, + (HpPriv->regPHYFindSig & ~AR_PHY_FIND_SIG_FIRSTEP) + | ((firstep[level] << AR_PHY_FIND_SIG_FIRSTEP_S) + & AR_PHY_FIND_SIG_FIRSTEP)); + zfFlushDelayWrite(dev); + if (level > aniState->firstepLevel) + HpPriv->stats.ast_ani_stepup++; + else if (level < aniState->firstepLevel) + HpPriv->stats.ast_ani_stepdown++; + aniState->firstepLevel = (u8_t)level; + break; + } + case ZM_HAL_ANI_SPUR_IMMUNITY_LEVEL: + { + const TABLE cycpwrThr1 = { 2, 4, 6, 8, 10, 12, 14, 16 }; + u32_t level = param; + + if (level >= N(cycpwrThr1)) + { + zm_debug_msg1("level out of range, desired level : ", level); + zm_debug_msg1("max level : ", N(cycpwrThr1)); + return FALSE; + } + zfDelayWriteInternalReg(dev, AR_PHY_TIMING5, + (HpPriv->regPHYTiming5 & ~AR_PHY_TIMING5_CYCPWR_THR1) + | ((cycpwrThr1[level] << AR_PHY_TIMING5_CYCPWR_THR1_S) + & AR_PHY_TIMING5_CYCPWR_THR1)); + zfFlushDelayWrite(dev); + if (level > aniState->spurImmunityLevel) + HpPriv->stats.ast_ani_spurup++; + else if (level < aniState->spurImmunityLevel) + HpPriv->stats.ast_ani_spurdown++; + aniState->spurImmunityLevel = (u8_t)level; + break; + } + case ZM_HAL_ANI_PRESENT: + break; +#ifdef AH_PRIVATE_DIAG + case ZM_HAL_ANI_MODE: + if (param == 0) + { + HpPriv->procPhyErr &= ~ZM_HAL_PROCESS_ANI; + /* Turn off HW counters if we have them */ + zfHpAniDetach(dev); + //zfHpSetRxFilter(dev, zfHpGetRxFilter(dev) &~ HAL_RX_FILTER_PHYERR); + } + else + { /* normal/auto mode */ + HpPriv->procPhyErr |= ZM_HAL_PROCESS_ANI; + if (HpPriv->hasHwPhyCounters) + { + //zfHpSetRxFilter(dev, zfHpGetRxFilter(dev) &~ HAL_RX_FILTER_PHYERR); + } + else + { + //zfHpSetRxFilter(dev, zfHpGetRxFilter(dev) | HAL_RX_FILTER_PHYERR); + } + } + break; + case ZM_HAL_ANI_PHYERR_RESET: + HpPriv->stats.ast_ani_ofdmerrs = 0; + HpPriv->stats.ast_ani_cckerrs = 0; + break; +#endif /* AH_PRIVATE_DIAG */ + default: + zm_debug_msg1("invalid cmd ", cmd); + return FALSE; + } + return TRUE; +#undef N +} + +void zfHpAniRestart(zdev_t* dev) +{ + struct zsAniState *aniState; + + zmw_get_wlan_dev(dev); + + struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate; + + aniState = HpPriv->curani; + + aniState->listenTime = 0; + if (HpPriv->hasHwPhyCounters) + { + //if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) + //{ + // aniState->ofdmPhyErrBase = 0; + // zm_debug_msg0("OFDM Trigger is too high for hw counters"); + //} + //else + // aniState->ofdmPhyErrBase = AR_PHY_COUNTMAX - aniState->ofdmTrigHigh; + //if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) + //{ + // aniState->cckPhyErrBase = 0; + // zm_debug_msg0("CCK Trigger is too high for hw counters"); + //} + //else + // aniState->cckPhyErrBase = AR_PHY_COUNTMAX - aniState->cckTrigHigh; + //zm_debug_msg2("Writing ofdmbase = 0x", aniState->ofdmPhyErrBase); + //zm_debug_msg2("Writing cckbase = 0x", aniState->cckPhyErrBase); + //OS_REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase); + //OS_REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase); + //OS_REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); + //OS_REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); + aniState->ofdmPhyErrBase = 0; + aniState->cckPhyErrBase = 0; + } + aniState->ofdmPhyErrCount = 0; + aniState->cckPhyErrCount = 0; +} + +void zfHpAniOfdmErrTrigger(zdev_t* dev) +{ + struct zsAniState *aniState; + s32_t rssi; + + zmw_get_wlan_dev(dev); + + struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate; + + //HALASSERT(chan != NULL); + + if ((HpPriv->procPhyErr & ZM_HAL_PROCESS_ANI) == 0) + return; + + aniState = HpPriv->curani; + /* First, raise noise immunity level, up to max */ + if (aniState->noiseImmunityLevel < ZM_HAL_NOISE_IMMUNE_MAX) + { + zfHpAniControl(dev, ZM_HAL_ANI_NOISE_IMMUNITY_LEVEL, aniState->noiseImmunityLevel + 1); + return; + } + /* then, raise spur immunity level, up to max */ + if (aniState->spurImmunityLevel < ZM_HAL_SPUR_IMMUNE_MAX) + { + zfHpAniControl(dev, ZM_HAL_ANI_SPUR_IMMUNITY_LEVEL, aniState->spurImmunityLevel + 1); + return; + } + rssi = BEACON_RSSI(dev); + if (rssi > aniState->rssiThrHigh) + { + /* + * Beacon rssi is high, can turn off ofdm weak sig detect. + */ + if (!aniState->ofdmWeakSigDetectOff) + { + zfHpAniControl(dev, ZM_HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION, FALSE); + zfHpAniControl(dev, ZM_HAL_ANI_SPUR_IMMUNITY_LEVEL, 0); + return; + } + /* + * If weak sig detect is already off, as last resort, raise + * first step level + */ + if (aniState->firstepLevel < ZM_HAL_FIRST_STEP_MAX) + { + zfHpAniControl(dev, ZM_HAL_ANI_FIRSTEP_LEVEL, aniState->firstepLevel + 1); + return; + } + } + else if (rssi > aniState->rssiThrLow) + { + /* + * Beacon rssi in mid range, need ofdm weak signal detect, + * but we can raise firststepLevel + */ + if (aniState->ofdmWeakSigDetectOff) + zfHpAniControl(dev, ZM_HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION, TRUE); + if (aniState->firstepLevel < ZM_HAL_FIRST_STEP_MAX) + zfHpAniControl(dev, ZM_HAL_ANI_FIRSTEP_LEVEL, aniState->firstepLevel + 1); + return; + } + else + { + /* + * Beacon rssi is low, if in 11b/g mode, turn off ofdm + * weak sign detction and zero firstepLevel to maximize + * CCK sensitivity + */ + if (wd->frequency < 3000) + { + if (!aniState->ofdmWeakSigDetectOff) + zfHpAniControl(dev, ZM_HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION, FALSE); + if (aniState->firstepLevel > 0) + zfHpAniControl(dev, ZM_HAL_ANI_FIRSTEP_LEVEL, 0); + return; + } + } +} + +void zfHpAniCckErrTrigger(zdev_t* dev) +{ + struct zsAniState *aniState; + s32_t rssi; + + zmw_get_wlan_dev(dev); + + struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate; + + //HALASSERT(chan != NULL); + + if ((HpPriv->procPhyErr & ZM_HAL_PROCESS_ANI) == 0) + return; + + /* first, raise noise immunity level, up to max */ + aniState = HpPriv->curani; + if (aniState->noiseImmunityLevel < ZM_HAL_NOISE_IMMUNE_MAX) + { + zfHpAniControl(dev, ZM_HAL_ANI_NOISE_IMMUNITY_LEVEL, + aniState->noiseImmunityLevel + 1); + return; + } + rssi = BEACON_RSSI(dev); + if (rssi > aniState->rssiThrLow) + { + /* + * Beacon signal in mid and high range, raise firsteplevel. + */ + if (aniState->firstepLevel < ZM_HAL_FIRST_STEP_MAX) + zfHpAniControl(dev, ZM_HAL_ANI_FIRSTEP_LEVEL, aniState->firstepLevel + 1); + } + else + { + /* + * Beacon rssi is low, zero firstepLevel to maximize + * CCK sensitivity. + */ + if (wd->frequency < 3000) + { + if (aniState->firstepLevel > 0) + zfHpAniControl(dev, ZM_HAL_ANI_FIRSTEP_LEVEL, 0); + } + } +} + +void zfHpAniLowerImmunity(zdev_t* dev) +{ + struct zsAniState *aniState; + s32_t rssi; + + zmw_get_wlan_dev(dev); + + struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate; + + aniState = HpPriv->curani; + + rssi = BEACON_RSSI(dev); + if (rssi > aniState->rssiThrHigh) + { + /* + * Beacon signal is high, leave ofdm weak signal detection off + * or it may oscillate. Let it fall through. + */ + } + else if (rssi > aniState->rssiThrLow) + { + /* + * Beacon rssi in mid range, turn on ofdm weak signal + * detection or lower first step level. + */ + if (aniState->ofdmWeakSigDetectOff) + { + zfHpAniControl(dev, ZM_HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION, TRUE); + return; + } + if (aniState->firstepLevel > 0) + { + zfHpAniControl(dev, ZM_HAL_ANI_FIRSTEP_LEVEL, aniState->firstepLevel - 1); + return; + } + } + else + { + /* + * Beacon rssi is low, reduce first step level. + */ + if (aniState->firstepLevel > 0) + { + zfHpAniControl(dev, ZM_HAL_ANI_FIRSTEP_LEVEL, aniState->firstepLevel - 1); + return; + } + } + /* then lower spur immunity level, down to zero */ + if (aniState->spurImmunityLevel > 0) + { + zfHpAniControl(dev, ZM_HAL_ANI_SPUR_IMMUNITY_LEVEL, aniState->spurImmunityLevel - 1); + return; + } + /* + * if all else fails, lower noise immunity level down to a min value + * zero for now + */ + if (aniState->noiseImmunityLevel > 0) + { + zfHpAniControl(dev, ZM_HAL_ANI_NOISE_IMMUNITY_LEVEL, aniState->noiseImmunityLevel - 1); + return; + } +} + +#define CLOCK_RATE 44000 /* XXX use mac_usec or similar */ +/* convert HW counter values to ms using 11g clock rate, goo9d enough + for 11a and Turbo */ + +/* + * Return an approximation of the time spent ``listening'' by + * deducting the cycles spent tx'ing and rx'ing from the total + * cycle count since our last call. A return value <0 indicates + * an invalid/inconsistent time. + */ +s32_t zfHpAniGetListenTime(zdev_t* dev) +{ + struct zsAniState *aniState; + u32_t txFrameCount, rxFrameCount, cycleCount; + s32_t listenTime; + + zmw_get_wlan_dev(dev); + + struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate; + + txFrameCount = 0;//OS_REG_READ(ah, AR_TFCNT); + rxFrameCount = 0;//OS_REG_READ(ah, AR_RFCNT); + cycleCount = 0;//OS_REG_READ(ah, AR_CCCNT); + + aniState = HpPriv->curani; + if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) + { + /* + * Cycle counter wrap (or initial call); it's not possible + * to accurately calculate a value because the registers + * right shift rather than wrap--so punt and return 0. + */ + listenTime = 0; + HpPriv->stats.ast_ani_lzero++; + } + else + { + s32_t ccdelta = cycleCount - aniState->cycleCount; + s32_t rfdelta = rxFrameCount - aniState->rxFrameCount; + s32_t tfdelta = txFrameCount - aniState->txFrameCount; + listenTime = (ccdelta - rfdelta - tfdelta) / CLOCK_RATE; + } + aniState->cycleCount = cycleCount; + aniState->txFrameCount = txFrameCount; + aniState->rxFrameCount = rxFrameCount; + return listenTime; +} + +/* + * Do periodic processing. This routine is called from the + * driver's rx interrupt handler after processing frames. + */ +void zfHpAniArPoll(zdev_t* dev, u32_t listenTime, u32_t phyCnt1, u32_t phyCnt2) +{ + struct zsAniState *aniState; + //s32_t listenTime; + + zmw_get_wlan_dev(dev); + + struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate; + + /* + * Since we're called from end of rx tasklet, we also check for + * AR processing now + */ + + aniState = HpPriv->curani; + //HpPriv->stats.ast_nodestats = *stats; /* XXX optimize? */ + + //listenTime = zfHpAniGetListenTime(dev); + //if (listenTime < 0) + //{ + // HpPriv->stats.ast_ani_lneg++; + // /* restart ANI period if listenTime is invalid */ + // zfHpAniRestart(dev); + // return; + //} + /* XXX beware of overflow? */ + aniState->listenTime += listenTime; + + if (HpPriv->hasHwPhyCounters) + { + //u32_t phyCnt1, phyCnt2; + u32_t ofdmPhyErrCnt, cckPhyErrCnt; + + /* NB: these are not reset-on-read */ + //phyCnt1 = 0;//OS_REG_READ(ah, AR_PHY_ERR_1); + //phyCnt2 = 0;//OS_REG_READ(ah, AR_PHY_ERR_2); + /* XXX sometimes zero, why? */ + //if (phyCnt1 < aniState->ofdmPhyErrBase || + // phyCnt2 < aniState->cckPhyErrBase) + //{ + // if (phyCnt1 < aniState->ofdmPhyErrBase) + // { + // zm_debug_msg2("phyCnt1 = 0x", phyCnt1); + // zm_debug_msg2("resetting counter value to 0x", aniState->ofdmPhyErrBase); + // //OS_REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase); + // //OS_REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); + // } + // if (phyCnt2 < aniState->cckPhyErrBase) + // { + // zm_debug_msg2("phyCnt2 = 0x", phyCnt2); + // zm_debug_msg2("resetting counter value to 0x", aniState->cckPhyErrBase); + // //OS_REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase); + // //OS_REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); + // } + // return; /* XXX */ + //} + /* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */ + //ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; + //HpPriv->stats.ast_ani_ofdmerrs += ofdmPhyErrCnt - aniState->ofdmPhyErrCount; + //aniState->ofdmPhyErrCount = ofdmPhyErrCnt; + ofdmPhyErrCnt = phyCnt1; + HpPriv->stats.ast_ani_ofdmerrs += ofdmPhyErrCnt; + aniState->ofdmPhyErrCount += ofdmPhyErrCnt; + + //cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase; + //HpPriv->stats.ast_ani_cckerrs += cckPhyErrCnt - aniState->cckPhyErrCount; + //aniState->cckPhyErrCount = cckPhyErrCnt; + cckPhyErrCnt = phyCnt2; + HpPriv->stats.ast_ani_cckerrs += cckPhyErrCnt; + aniState->cckPhyErrCount += cckPhyErrCnt; + } + /* + * If ani is not enabled, return after we've collected + * statistics + */ + if ((HpPriv->procPhyErr & ZM_HAL_PROCESS_ANI) == 0) + return; + if (aniState->listenTime > 5 * HpPriv->aniPeriod) + { + /* + * Check to see if need to lower immunity if + * 5 aniPeriods have passed + */ + if (aniState->ofdmPhyErrCount <= aniState->listenTime * + aniState->ofdmTrigLow/1000 && + aniState->cckPhyErrCount <= aniState->listenTime * + aniState->cckTrigLow/1000) + zfHpAniLowerImmunity(dev); + zfHpAniRestart(dev); + } + else if (aniState->listenTime > HpPriv->aniPeriod) + { + /* check to see if need to raise immunity */ + if (aniState->ofdmPhyErrCount > aniState->listenTime * + aniState->ofdmTrigHigh / 1000) + { + zfHpAniOfdmErrTrigger(dev); + zfHpAniRestart(dev); + } + else if (aniState->cckPhyErrCount > aniState->listenTime * + aniState->cckTrigHigh / 1000) + { + zfHpAniCckErrTrigger(dev); + zfHpAniRestart(dev); + } + } +} --- linux-2.6.28.orig/drivers/staging/otus/hal/hpusb.c +++ linux-2.6.28/drivers/staging/otus/hal/hpusb.c @@ -0,0 +1,1584 @@ +/* + * Copyright (c) 2000-2005 ZyDAS Technology Corporation + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* */ +/* Module Name : ud.c */ +/* */ +/* Abstract */ +/* This module contains USB descriptor functions. */ +/* */ +/* NOTES */ +/* None */ +/* */ +/************************************************************************/ +#include "../80211core/cprecomp.h" +#include "hpani.h" +#include "hpusb.h" + +extern void zfwUsbCmd(zdev_t* dev, u8_t endpt, u32_t* cmd, u16_t cmdLen); + +extern void zfIdlRsp(zdev_t* dev, u32_t* rsp, u16_t rspLen); +extern u16_t zfDelayWriteInternalReg(zdev_t* dev, u32_t addr, u32_t val); +extern u16_t zfFlushDelayWrite(zdev_t* dev); + + +#define USB_ENDPOINT_TX_INDEX 1 +#define USB_ENDPOINT_RX_INDEX 2 +#define USB_ENDPOINT_INT_INDEX 3 +#define USB_ENDPOINT_CMD_INDEX 4 + +void zfIdlCmd(zdev_t* dev, u32_t* cmd, u16_t cmdLen) +{ +#if ZM_SW_LOOP_BACK != 1 + zfwUsbCmd(dev, USB_ENDPOINT_CMD_INDEX, cmd, cmdLen); +#endif + + return; +} + + +/* zfAdjustCtrlSetting: fit OUTS format */ +/* convert MIMO2 to OUTS */ +void zfAdjustCtrlSetting(zdev_t* dev, u16_t* header, zbuf_t* buf) +{ + /* MIMO2 => OUTS FB-50 */ + /* length not change, only modify format */ + + u32_t oldMT; + u32_t oldMCS; + + u32_t phyCtrl; + u32_t oldPhyCtrl; + + u16_t tpc = 0; + + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv=wd->hpPrivate; + + /* mm */ + if (header == NULL) + { + oldPhyCtrl = zmw_buf_readh(dev, buf, 4) | ((u32_t)zmw_buf_readh(dev, buf, 6) << 16); + } + else + { + oldPhyCtrl = header[2] | ((u32_t)header[3] <<16); + } + + phyCtrl = 0; + + + /* MT : Bit[1~0] */ + oldMT = oldPhyCtrl&0x3; + phyCtrl |= oldMT; + if ( oldMT == 0x3 ) /* DL-OFDM (Duplicate Legacy OFDM) */ + phyCtrl |= 0x1; + + + /* PT : Bit[2] HT PT: 0 Mixed mode 1 Green field */ + phyCtrl |= (oldPhyCtrl&0x4); + + /* Bandwidth control : Bit[4~3] */ + if ( oldPhyCtrl&0x800000 ) /* Bit23 : 40M */ + { + #if 0 + if (oldMT == 0x3) /* DL-OFDM */ + phyCtrl |= (0x3<<3); /* 40M duplicate */ + else + phyCtrl |= (0x2<<3); /* 40M shared */ + #else + if (oldMT == 0x2 && ((struct zsHpPriv*)wd->hpPrivate)->hwBw40) + { + phyCtrl |= (0x2<<3); /* 40M shared */ + } + #endif + } + else { + oldPhyCtrl &= ~0x80000000; + } + + /* MCS : Bit[24~18] */ + oldMCS = (oldPhyCtrl&0x7f0000)>>16; /* Bit[22~16] */ + phyCtrl |= (oldMCS<<18); + + /* Short GI : Bit[31]*/ + phyCtrl |= (oldPhyCtrl&0x80000000); + + /* AM : Antenna mask */ + //if ((oldMT == 2) && (oldMCS > 7)) + if (hpPriv->halCapability & ZM_HP_CAP_11N_ONE_TX_STREAM) + { + phyCtrl |= (0x1<<15); + } + else + { + /* HT Tx 2 chain */ + /* OFDM 6M/9M/12M/18M/24M Tx 2 chain */ + /* OFDM 36M/48M/54M/ Tx 1 chain */ + /* CCK Tx 2 chain */ + if ((oldMT == 2) || (oldMT == 3)) + { + phyCtrl |= (0x5<<15); + } + else if (oldMT == 1) + { + if ((oldMCS == 0xb) || (oldMCS == 0xf) || + (oldMCS == 0xa) || (oldMCS == 0xe) || + (oldMCS == 0x9)) //6M/9M/12M/18M/24M + { + phyCtrl |= (0x5<<15); + } + else + { + phyCtrl |= (0x1<<15); + } + } + else //(oldMT==0) + { + phyCtrl |= (0x5<<15); + } + } + //else + // phyCtrl |= (0x1<<15); + + /* TPC */ + /* TODO : accelerating these code */ + if (hpPriv->hwFrequency < 3000) + { + if (oldMT == 0) + { + /* CCK */ + tpc = (hpPriv->tPow2xCck[oldMCS]&0x3f); + } + else if (oldMT == 1) + { + /* OFDM */ + if (oldMCS == 0xc) + { + tpc = (hpPriv->tPow2x2g[3]&0x3f); + } + else if (oldMCS == 0x8) + { + tpc = (hpPriv->tPow2x2g[2]&0x3f); + } + else if (oldMCS == 0xd) + { + tpc = (hpPriv->tPow2x2g[1]&0x3f); + } + else if (oldMCS == 0x9) + { + tpc = ((hpPriv->tPow2x2g[0]-hpPriv->tPow2x2g24HeavyClipOffset)&0x3f); + } + else + { + tpc = (hpPriv->tPow2x2g[0]&0x3f); + } + } + else if (oldMT == 2) + { + if ( oldPhyCtrl&0x800000 ) /* Bit23 : 40M */ + { + /* HT 40 */ + tpc = (hpPriv->tPow2x2gHt40[oldMCS&0x7]&0x3f); + } + else + { + /* HT 20 */ + tpc = (hpPriv->tPow2x2gHt20[oldMCS&0x7]&0x3f); + } + } + } + else //5GHz + { + if (oldMT == 1) + { + /* OFDM */ + if (oldMCS == 0xc) + { + tpc = (hpPriv->tPow2x5g[3]&0x3f); + } + else if (oldMCS == 0x8) + { + tpc = (hpPriv->tPow2x5g[2]&0x3f); + } + else if (oldMCS == 0xd) + { + tpc = (hpPriv->tPow2x5g[1]&0x3f); + } + else + { + tpc = (hpPriv->tPow2x5g[0]&0x3f); + } + } + else if (oldMT == 2) + { + if ( oldPhyCtrl&0x800000 ) /* Bit23 : 40M */ + { + /* HT 40 */ + tpc = (hpPriv->tPow2x5gHt40[oldMCS&0x7]&0x3f); + } + else + { + /* HT 20 */ + tpc = (hpPriv->tPow2x5gHt20[oldMCS&0x7]&0x3f); + } + } + } + + /* Tx power adjust for HT40 */ + /* HT40 +1dBm */ + if ((oldMT==2) && (oldPhyCtrl&0x800000) ) + { + tpc += 2; + } + tpc &= 0x3f; + + /* Evl force tx TPC */ + if(wd->forceTxTPC) + { + tpc = (u16_t)(wd->forceTxTPC & 0x3f); + } + + if (hpPriv->hwFrequency < 3000) { + wd->maxTxPower2 &= 0x3f; + tpc = (tpc > wd->maxTxPower2)? wd->maxTxPower2 : tpc; + } else { + wd->maxTxPower5 &= 0x3f; + tpc = (tpc > wd->maxTxPower5)? wd->maxTxPower5 : tpc; + } + + +#define ZM_MIN_TPC 5 +#define ZM_TPC_OFFSET 5 +#define ZM_SIGNAL_THRESHOLD 56 + if ((wd->sta.bScheduleScan == FALSE) && (wd->sta.bChannelScan == FALSE)) + { + if (( wd->wlanMode == ZM_MODE_INFRASTRUCTURE ) + && (zfStaIsConnected(dev)) + && (wd->SignalStrength > ZM_SIGNAL_THRESHOLD)) + { + if (tpc > ((ZM_MIN_TPC+ZM_TPC_OFFSET)*2)) + { + tpc -= (ZM_TPC_OFFSET*2); + } + else if (tpc > (ZM_MIN_TPC*2)) + { + tpc = (ZM_MIN_TPC*2); + } + } + } +#undef ZM_MIN_TPC +#undef ZM_TPC_OFFSET +#undef ZM_SIGNAL_THRESHOLD + + #ifndef ZM_OTUS_LINUX_PHASE_2 + phyCtrl |= (tpc & 0x3f) << 9; + #endif + + /* Set bits[8:6]BF-MCS for heavy clip */ + if ((phyCtrl&0x3) == 2) + { + phyCtrl |= ((phyCtrl >> 12) & 0x1c0); + } + + /* PHY control */ + if (header == NULL) + { + zmw_buf_writeh(dev, buf, 4, (u16_t) (phyCtrl&0xffff)); + zmw_buf_writeh(dev, buf, 6, (u16_t) (phyCtrl>>16)); + } + else + { + //PHY control L + header[2] = (u16_t) (phyCtrl&0xffff); + //PHY control H + header[3] = (u16_t) (phyCtrl>>16); + } + + zm_msg2_tx(ZM_LV_2, "old phy ctrl = ", oldPhyCtrl); + zm_msg2_tx(ZM_LV_2, "new phy ctrl = ", phyCtrl); + //DbgPrint("old phy ctrl =%08x \n", oldPhyCtrl); + //DbgPrint("new phy ctrl =%08x \n", phyCtrl); +} + + +#define EXTRA_INFO_LEN 24 //RSSI(7) + EVM(12) + PHY(1) + MACStatus(4) +u16_t zfHpSend(zdev_t* dev, u16_t* header, u16_t headerLen, + u16_t* snap, u16_t snapLen, + u16_t* tail, u16_t tailLen, zbuf_t* buf, u16_t offset, + u16_t bufType, u8_t ac, u8_t keyIdx) +{ +#if ZM_SW_LOOP_BACK == 1 + zbuf_t *rxbuf; + u8_t *puRxBuf; + u8_t *pHdr; + u8_t *psnap; + u16_t plcplen = 12; + u16_t i; + u16_t swlpOffset; +#endif /* #if ZM_SW_LOOP_BACK == 1 */ + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv=wd->hpPrivate; + + zm_msg1_tx(ZM_LV_1, "zfHpSend(), len = ", 12 + headerLen-8 + snapLen + zfwBufGetSize(dev, buf) + 4 + 8); + + /* Adjust ctrl setting : 6N14 yjsung */ + zfAdjustCtrlSetting(dev, header, buf); + +#if ZM_SW_LOOP_BACK != 1 + hpPriv->usbSendBytes += zfwBufGetSize(dev, buf); + hpPriv->usbAcSendBytes[ac&0x3] += zfwBufGetSize(dev, buf); + + /* Submit USB Out Urb */ + zfwUsbSend(dev, USB_ENDPOINT_TX_INDEX, (u8_t *)header, headerLen, + (u8_t *)snap, snapLen, (u8_t *)tail, tailLen, buf, offset); +#endif + +#if ZM_SW_LOOP_BACK == 1 + + rxbuf = zfwBufAllocate(dev, plcplen + headerLen-8 + snapLen + (zfwBufGetSize(dev, buf)-offset) + 4 + EXTRA_INFO_LEN); + pHdr = (u8_t *) header+8; + psnap = (u8_t *) snap; + + zmw_enter_critical_section(dev); + /* software loop back */ + /* Copy WLAN header and packet buffer */ + swlpOffset = plcplen; + + for(i = 0; i < headerLen-8; i++) + { + zmw_rx_buf_writeb(dev, rxbuf, swlpOffset+i, pHdr[i]); + } + + swlpOffset += headerLen-8; + + /* Copy SNAP header */ + for(i = 0; i < snapLen; i++) + { + zmw_rx_buf_writeb(dev, rxbuf, swlpOffset+i, psnap[i]); + } + + swlpOffset += snapLen; + + /* Copy body from tx buf to rxbuf */ + for(i = 0; i < (zfwBufGetSize(dev, buf)-offset); i++) + { + u8_t value = zmw_rx_buf_readb(dev, buf, i+offset); + zmw_rx_buf_writeb(dev, rxbuf, swlpOffset+i, value); + } + + /* total length = PLCP + MacHeader + Payload + FCS + RXstatus */ + /* 12 + headerLen-8 + snapLen + buf length + 4 + 8 */ + zfwSetBufSetSize(dev, rxbuf, swlpOffset + (zfwBufGetSize(dev, buf)-offset) + 4 + EXTRA_INFO_LEN ); + + zmw_leave_critical_section(dev); + + zfwBufFree(dev, buf, 0); + + //zfwDumpBuf(dev, rxbuf); + //------------------------------------------------- + + //zfCoreRecv(dev, rxbuf); + +#endif /* #if ZM_SW_LOOP_BACK */ + + return ZM_SUCCESS; +} + +/* Report moniter Hal rx information about rssi, evm, bandwidth, SG etc */ +void zfHpQueryMonHalRxInfo(zdev_t* dev, u8_t *monHalRxInfo) +{ + zmw_get_wlan_dev(dev); + zfMemoryCopy(monHalRxInfo, + (u8_t*)&(((struct zsHpPriv*)wd->hpPrivate)->halRxInfo), + sizeof(struct zsHalRxInfo)); +} + + +u8_t zfIsDataFrame(zdev_t* dev, zbuf_t* buf) +{ + u8_t frameType; + u8_t mpduInd; + + mpduInd = zmw_rx_buf_readb(dev, buf, zfwBufGetSize(dev, buf)-1); + + /* sinlge or First */ + if ((mpduInd & 0x30) == 0x00 || (mpduInd & 0x30) == 0x20) + { + frameType = zmw_rx_buf_readb(dev, buf, 12); + } + else + { + frameType = zmw_rx_buf_readb(dev, buf, 0); + } + + if((frameType & 0xf) == ZM_WLAN_DATA_FRAME) + return 1; + else + return 0; +} + +u32_t zfcConvertRateOFDM(zdev_t* dev, zbuf_t* buf) +{ + // What's the default value?? + u32_t MCS = 0; + + switch(zmw_rx_buf_readb(dev, buf, 0)& 0xf) + { + case 0xb: + MCS = 0x4; + break; + case 0xf: + MCS = 0x5; + break; + case 0xa: + MCS = 0x6; + break; + case 0xe: + MCS = 0x7; + break; + case 0x9: + MCS = 0x8; + break; + case 0xd: + MCS = 0x9; + break; + case 0x8: + MCS = 0xa; + break; + case 0xc: + MCS = 0xb; + break; + } + return MCS; +} + +u16_t zfHpGetPayloadLen(zdev_t* dev, + zbuf_t* buf, + u16_t len, + u16_t plcpHdrLen, + u32_t *rxMT, + u32_t *rxMCS, + u32_t *rxBW, + u32_t *rxSG + ) +{ + u8_t modulation,mpduInd; + u16_t low, high, msb; + s16_t payloadLen = 0; + + zmw_get_wlan_dev(dev); + + mpduInd = zmw_rx_buf_readb(dev, buf, len-1); + modulation = zmw_rx_buf_readb(dev, buf, (len-1)) & 0x3; + *rxMT = modulation; + + //zm_debug_msg1(" modulation= ", modulation); + switch (modulation) { + case 0: /* CCK Mode */ + low = zmw_rx_buf_readb(dev, buf, 2); + high = zmw_rx_buf_readb(dev, buf, 3); + payloadLen = (low | high << 8) - 4; + if (wd->enableHALDbgInfo) + { + *rxMCS = zmw_rx_buf_readb(dev, buf, 0); + *rxBW = 0; + *rxSG = 0; + } + break; + case 1: /* Legacy-OFDM mode */ + low = zmw_rx_buf_readb(dev, buf, 0) >> 5; + high = zmw_rx_buf_readb(dev, buf, 1); + msb = zmw_rx_buf_readb(dev, buf, 2) & 0x1; + payloadLen = (low | (high << 3) | (msb << 11)) - 4; + if (wd->enableHALDbgInfo) + { + *rxMCS = zfcConvertRateOFDM(dev, buf); + *rxBW = 0; + *rxSG = 0; + } + break; + case 2: /* HT OFDM mode */ + //zm_debug_msg1("aggregation= ", (zmw_rx_buf_readb(dev, buf, 6) >> 3) &0x1 ); + if ((mpduInd & 0x30) == 0x00 || (mpduInd & 0x30) == 0x10) //single or last mpdu + payloadLen = len - 24 - 4 - plcpHdrLen; // - rxStatus - fcs + else { + payloadLen = len - 4 - 4 - plcpHdrLen; // - rxStatus - fcs + //zm_debug_msg1("first or middle mpdu, plcpHdrLen= ", plcpHdrLen); + } + if (wd->enableHALDbgInfo) + { + *rxMCS = zmw_rx_buf_readb(dev, buf, 3) & 0x7f; + *rxBW = (zmw_rx_buf_readb(dev, buf, 3) >> 7) & 0x1; + *rxSG = (zmw_rx_buf_readb(dev, buf, 6) >> 7) & 0x1; + } + break; + default: + break; + + } + /* return the payload length - FCS */ + if (payloadLen < 0) payloadLen = 0; + return payloadLen; +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfiUsbRecv */ +/* Callback function for USB IN Transfer. */ +/* */ +/* INPUTS */ +/* dev: device pointer */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Yuan-Gu Wei ZyDAS Technology Corporation 2005.10 */ +/* */ +/************************************************************************/ +#define ZM_INT_USE_EP2 1 +#define ZM_INT_USE_EP2_HEADER_SIZE 12 + +#if ZM_INT_USE_EP2 == 1 +void zfiUsbRegIn(zdev_t* dev, u32_t* rsp, u16_t rspLen); +#endif + +#ifdef ZM_OTUS_RX_STREAM_MODE +void zfiUsbRecvPerPkt(zdev_t *dev, zbuf_t *buf) +#else +void zfiUsbRecv(zdev_t *dev, zbuf_t *buf) +#endif +{ + + +#if ZM_FW_LOOP_BACK != 1 + u8_t mpduInd; + u16_t plcpHdrLen; + u16_t crcPlusRxStatusLen; + u16_t len, payloadLen=0; + u16_t i; //CWYang(+) + struct zsAdditionInfo addInfo; + u32_t rxMT; + u32_t rxMCS; + u32_t rxBW; + u32_t rxSG; + zmw_get_wlan_dev(dev); + struct zsHpPriv* hpPriv=wd->hpPrivate; + + //zm_msg0_rx(ZM_LV_0, "zfiUsbRecv()"); + +#if ZM_INT_USE_EP2 == 1 + + for (i=0; i<(ZM_INT_USE_EP2_HEADER_SIZE>>1); i++) + { + if (zmw_rx_buf_readh(dev, buf, i*2) != 0xffff) + break; + } + + if (i==(ZM_INT_USE_EP2_HEADER_SIZE>>1)) + { + u32_t rsp[ZM_USB_MAX_EPINT_BUFFER/4]; + u16_t rspLen; + u32_t rspi; + u8_t* pdst = (u8_t*)rsp; + + /* Interrupt Rsp */ + rspLen = (u16_t) zfwBufGetSize(dev, buf)-ZM_INT_USE_EP2_HEADER_SIZE; + + if (rspLen > 60) + { + zm_debug_msg1("Get error len by EP2 = \n", rspLen); + /* free USB buf */ + zfwBufFree(dev, buf, 0); + return; + } + + for (rspi=0; rspizfcbUsbRegIn) + // adapter->zfcbUsbRegIn(adapter, rsp, rspLen); + zfiUsbRegIn(dev, rsp, rspLen); + + /* free USB buf */ + zfwBufFree(dev, buf, 0); + return; + } +#endif /* end of #if ZM_INT_USE_EP2 == 1 */ + + ZM_PERFORMANCE_RX_MPDU(dev, buf); + + if (wd->swSniffer) + { + /* airopeek: Report everything up */ + if (wd->zfcbRecv80211 != NULL) + { + wd->zfcbRecv80211(dev, buf, NULL); + } + } + + /* Read the last byte */ + len = zfwBufGetSize(dev, buf); + mpduInd = zmw_rx_buf_readb(dev, buf, len-1); + + /* First MPDU */ + if((mpduInd & 0x30) == 0x20) + { + u16_t duration; + if (zmw_rx_buf_readb(dev, buf, 36) == 0) //AC = BE + { + duration = zmw_rx_buf_readh(dev, buf, 14); + if (duration > hpPriv->aggMaxDurationBE) + { + hpPriv->aggMaxDurationBE = duration; + } + else + { + if (hpPriv->aggMaxDurationBE > 10) + { + hpPriv->aggMaxDurationBE--; + } + } + //DbgPrint("aggMaxDurationBE=%d", hpPriv->aggMaxDurationBE); + } + } + +#if 1 + /* First MPDU or Single MPDU */ + if(((mpduInd & 0x30) == 0x00) || ((mpduInd & 0x30) == 0x20)) + //if ((mpduInd & 0x10) == 0x00) + { + plcpHdrLen = 12; // PLCP header length + } + else + { + if (zmw_rx_buf_readh(dev, buf, 4) == wd->macAddr[0] && + zmw_rx_buf_readh(dev, buf, 6) == wd->macAddr[1] && + zmw_rx_buf_readh(dev, buf, 8) == wd->macAddr[2]) { + plcpHdrLen = 0; + } + else if (zmw_rx_buf_readh(dev, buf, 16) == wd->macAddr[0] && + zmw_rx_buf_readh(dev, buf, 18) == wd->macAddr[1] && + zmw_rx_buf_readh(dev, buf, 20) == wd->macAddr[2]){ + plcpHdrLen = 12; + } + else { + plcpHdrLen = 0; + } + } + + /* Last MPDU or Single MPDU */ + if ((mpduInd & 0x30) == 0x00 || (mpduInd & 0x30) == 0x10) + { + crcPlusRxStatusLen = EXTRA_INFO_LEN + 4; // Extra bytes + FCS + } + else + { + crcPlusRxStatusLen = 4 + 4; // Extra 4 bytes + FCS + } +#else + plcpHdrLen = 12; + crcPlusRxStatusLen = EXTRA_INFO_LEN + 4; // Extra bytes + FCS +#endif + + if (len < (plcpHdrLen+10+crcPlusRxStatusLen)) + { + zm_msg1_rx(ZM_LV_0, "Invalid Rx length=", len); + //zfwDumpBuf(dev, buf); + + zfwBufFree(dev, buf, 0); + return; + } + + /* display RSSI combined */ + /* + * ¢z¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢{ + * ¢x PLCP Header ¢x MPDU ¢x RSSI ¢x EVM ¢x PHY Err ¢x MAC Status ¢x + * ¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t + * ¢x 12 ¢x n ¢x 7 ¢x 12 ¢x 1 ¢x 4 ¢x + * ¢|¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢} + * RSSI filed (From BB and MAC just pass them to host) + * Byte1: RSSI for antenna 0. + * Byte2: RSSI for antenna 1. + * Byte3: RSSI for antenna 2. + * Byte4: RSSI for antenna 0 extension. + * Byte5: RSSI for antenna 1 extension. + * Byte6: RSSI for antenna 2 extension. + * Byte7: RSSI for antenna combined. + */ + + //zm_debug_msg1(" recv RSSI = ", zmw_rx_buf_readb(dev, buf, (len-1)-17)); + + payloadLen = zfHpGetPayloadLen(dev, buf, len, plcpHdrLen, &rxMT, &rxMCS, &rxBW, &rxSG); + + /* Hal Rx info */ + /* First MPDU or Single MPDU */ + if(((mpduInd & 0x30) == 0x00) || ((mpduInd & 0x30) == 0x20)) + { + if (wd->enableHALDbgInfo && zfIsDataFrame(dev, buf)) + { + ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxDataMT = rxMT; + ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxDataMCS = rxMCS; + ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxDataBW = rxBW; + ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxDataSG = rxSG; + } + } + + if ((plcpHdrLen + payloadLen) > len) { + zm_msg1_rx(ZM_LV_0, "Invalid payload length=", payloadLen); + zfwBufFree(dev, buf, 0); + return; + } + + //Store Rx Tail Infomation before Remove--CWYang(+) + +#if 0 + for (i = 0; i < crcPlusRxStatusLen-4; i++) + { + addInfo.Tail.Byte[i] = + zmw_rx_buf_readb(dev, buf, len - crcPlusRxStatusLen + 4 + i); + } +#else +/* +* Brief format of OUTS chip +* ¢z¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢s¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢{ +* ¢x PLCP Header ¢x MPDU ¢x RSSI ¢x EVM ¢x PHY Err ¢x MAC Status ¢x +* ¢u¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢q¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢t +* ¢x 12 ¢x n ¢x 7 ¢x 12 ¢x 1 ¢x 4 ¢x +* ¢|¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢r¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢w¢} +* RSSI: +* Byte 1 antenna 0 +* Byte 2 antenna 1 +* Byte 3 antenna 2 +* Byte 4 antenna 0 extension +* Byte 5 antenna 1 extension +* Byte 6 antenna 2 extension +* Byte 7 antenna combined +* EVM: +* Byte 1 Stream 0 pilot 0 +* Byte 2 Stream 0 pilot 1 +* Byte 3 Stream 0 pilot 2 +* Byte 4 Stream 0 pilot 3 +* Byte 5 Stream 0 pilot 4 +* Byte 6 Stream 0 pilot 5 +* Byte 7 Stream 1 pilot 0 +* Byte 8 Stream 1 pilot 1 +* Byte 9 Stream 1 pilot 2 +* Byte 10 Stream 1 pilot 3 +* Byte 11 Stream 1 pilot 4 +* Byte 12 Stream 1 pilot 5 +*/ + + /* Fill the Tail information */ + /* Last MPDU or Single MPDU */ + if ((mpduInd & 0x30) == 0x00 || (mpduInd & 0x30) == 0x10) + { +#define ZM_RX_RSSI_COMPENSATION 27 + u8_t zm_rx_rssi_compensation = ZM_RX_RSSI_COMPENSATION; + + /* RSSI information */ + addInfo.Tail.Data.SignalStrength1 = zmw_rx_buf_readb(dev, buf, + (len-1) - 17) + ((hpPriv->rxStrongRSSI == 1)?zm_rx_rssi_compensation:0); +#undef ZM_RX_RSSI_COMPENSATION + + /* EVM */ + + /* TODO: for RD/BB debug message */ + /* save current rx hw infomration, report to DrvCore/Application */ + if (wd->enableHALDbgInfo && zfIsDataFrame(dev, buf)) + { + u8_t trssi; + for (i=0; i<7; i++) + { + trssi = zmw_rx_buf_readb(dev, buf, (len-1) - 23 + i); + if (trssi&0x80) + { + trssi = ((~((u8_t)trssi) & 0x7f) + 1) & 0x7f; + } + ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRSSI[i] = trssi; + + } + if (rxMT==2) + { + //if (rxBW) + //{ + for (i=0; i<12; i++) + ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[i] = + zmw_rx_buf_readb(dev, buf, (len-1) - 16 + i); + //} + //else + //{ + // for (i=0; i<4; i++) + // ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[i] = + // zmw_rx_buf_readb(dev, buf, (len-1) - 16 + i); + //} + } + + #if 0 + /* print */ + zm_dbg(("MT(%d) MCS(%d) BW(%d) SG(%d) RSSI:%d,%d,%d,%d,%d,%d,%d EVM:(%d,%d,%d,%d,%d,%d)(%d,%d,%d,%d,%d,%d)\n", + rxMT, + rxMCS, + rxBW, + rxSG, + ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRSSI[0], + ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRSSI[1], + ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRSSI[2], + ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRSSI[3], + ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRSSI[4], + ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRSSI[5], + ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRSSI[6], + ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[0], + ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[1], + ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[2], + ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[3], + ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[4], + ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[5], + ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[6], + ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[7], + ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[8], + ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[9], + ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[10], + ((struct zsHpPriv*)wd->hpPrivate)->halRxInfo.currentRxEVM[11] + )); + #endif + } /* if (wd->enableHALDbgInfo && zfIsDataFrame(dev, buf)) */ + + } + else + { + /* Mid or First aggregate frame without phy rx information */ + addInfo.Tail.Data.SignalStrength1 = 0; + } + + addInfo.Tail.Data.SignalStrength2 = 0; + addInfo.Tail.Data.SignalStrength3 = 0; + addInfo.Tail.Data.SignalQuality = 0; + + addInfo.Tail.Data.SAIndex = zmw_rx_buf_readb(dev, buf, len - 4); + addInfo.Tail.Data.DAIndex = zmw_rx_buf_readb(dev, buf, len - 3); + addInfo.Tail.Data.ErrorIndication = zmw_rx_buf_readb(dev, buf, len - 2); + addInfo.Tail.Data.RxMacStatus = zmw_rx_buf_readb(dev, buf, len - 1); + +#endif + /* Remove CRC and Rx Status */ + zfwBufSetSize(dev, buf, (len-crcPlusRxStatusLen)); + //zfwBufSetSize(dev, buf, payloadLen + plcpHdrLen); /* payloadLen + PLCP 12 - FCS 4*/ + + //Store PLCP Header Infomation before Remove--CWYang(+) + if (plcpHdrLen != 0) + { + for (i = 0; i < plcpHdrLen; i++) + { + addInfo.PlcpHeader[i] = zmw_rx_buf_readb(dev, buf, i); + } + } + else + { + addInfo.PlcpHeader[0] = 0; + } + /* Remove PLCP header */ + zfwBufRemoveHead(dev, buf, plcpHdrLen); + + /* handle 802.11 frame */ + zfCoreRecv(dev, buf, &addInfo); + +#else + /* Firmware loopback: Rx frame = Tx frame */ + /* convert Rx frame to fit receive frame format */ + zbuf_t *new_buf; + u8_t ctrl_offset = 8; + u8_t PLCP_Len = 12; + u8_t data; + u8_t i; + + + /* Tx: | ctrl_setting | Mac hdr | data | */ + /* 8 24 x */ + + /* Rx: | PLCP | Mac hdr | data | FCS | Rxstatus | */ + /* 12 24 x 4 8 */ + + /* new allocate a rx format size buf */ + new_buf = zfwBufAllocate(dev, zfwBufGetSize(dev, buf)-8+12+4+EXTRA_INFO_LEN); + + for (i=0; ihpPrivate; + srcBufPtr = zmw_buf_get_buffer(dev, buf); + + bufferLength = zfwBufGetSize(dev, buf); + + /* Zero Length Transfer */ + if (!bufferLength) + { + zfwBufFree(dev, buf, 0); + return; + } + + usbRxRemainLen = halPriv->usbRxRemainLen; + usbRxPktLen = halPriv->usbRxTransferLen; + + /* Check whether there is any data in the last transfer */ + if (usbRxRemainLen != 0 ) + { + zbuf_t *remainBufPtr = halPriv->remainBuf; + u8_t* BufPtr = NULL; + + if ( remainBufPtr != NULL ) + { + BufPtr = zmw_buf_get_buffer(dev, remainBufPtr); + } + + index = usbRxRemainLen; + usbRxRemainLen -= halPriv->usbRxPadLen; + + /* Copy data */ + if ( BufPtr != NULL ) + { + zfwMemoryCopy(&(BufPtr[usbRxPktLen]), srcBufPtr, usbRxRemainLen); + } + + usbRxPktLen += usbRxRemainLen; + halPriv->usbRxRemainLen = 0; + + if ( remainBufPtr != NULL ) + { + zfwBufSetSize(dev, remainBufPtr, usbRxPktLen); + rxBufPool[rxBufPoolIndex++] = remainBufPtr; + } + halPriv->remainBuf = NULL; + } + + //zm_debug_msg1("length: %d\n", (int)pUsbRxTransfer->pRxUrb->UrbBulkOrInterruptTransfer.TransferBufferLength); + + bufferLength = zfwBufGetSize(dev, buf); +//printk("bufferLength %d\n", bufferLength); + while(index < bufferLength) + { + u16_t pktLen; + u16_t pktTag; + //u8_t *ptr = (u8_t*)((struct zsBuffer*)pUsbRxTransfer->buf)->data; + u8_t *ptr = srcBufPtr; + + /* Retrieve packet length and tag */ + pktLen = ptr[index] + (ptr[index+1] << 8); + pktTag = ptr[index+2] + (ptr[index+3] << 8); + + if (pktTag == ZM_USB_STREAM_MODE_TAG) + { + u16_t padLen; + + zm_assert(pktLen < ZM_WLAN_MAX_RX_SIZE); + + //printk("Get a packet, pktLen: 0x%04x\n", pktLen); + #if 0 + /* Dump data */ + for (ii = index; ii < pkt_len+4;) + { + DbgPrint("0x%02x ", + (zmw_rx_buf_readb(adapter, pUsbRxTransfer->buf, ii) & 0xff)); + + if ((++ii % 16) == 0) + DbgPrint("\n"); + } + + DbgPrint("\n"); + #endif + + /* Calcuate the padding length, in the current design, + the length should be padded to 4 byte boundray. */ + padLen = ZM_USB_STREAM_MODE_TAG_LEN - (pktLen & 0x3); + + if(padLen == ZM_USB_STREAM_MODE_TAG_LEN) + padLen = 0; + + chkIdx = index; + index = index + ZM_USB_STREAM_MODE_TAG_LEN + pktLen + padLen; + + if (chkIdx > ZM_MAX_USB_IN_TRANSFER_SIZE) + { + zm_debug_msg1("chkIdx is too large, chkIdx: %d\n", chkIdx); + zm_assert(0); + status = 1; + break; + } + + if (index > ZM_MAX_USB_IN_TRANSFER_SIZE) + { + //struct zsBuffer* BufPtr; + //struct zsBuffer* UsbBufPtr; + u8_t *BufPtr; + u8_t *UsbBufPtr; + + halPriv->usbRxRemainLen = index - ZM_MAX_USB_IN_TRANSFER_SIZE; // - padLen; + halPriv->usbRxTransferLen = ZM_MAX_USB_IN_TRANSFER_SIZE - + chkIdx - ZM_USB_STREAM_MODE_TAG_LEN; + halPriv->usbRxPadLen = padLen; + //check_index = index; + + if (halPriv->usbRxTransferLen > ZM_WLAN_MAX_RX_SIZE) + { + zm_debug_msg1("check_len is too large, chk_len: %d\n", + halPriv->usbRxTransferLen); + status = 1; + break; + } + + /* Allocate a skb buffer */ + newBuf = zfwBufAllocate(dev, ZM_WLAN_MAX_RX_SIZE); + + if ( newBuf != NULL ) + { + BufPtr = zmw_buf_get_buffer(dev, newBuf); + UsbBufPtr = srcBufPtr; + + /* Copy the buffer */ + zfwMemoryCopy(BufPtr, &(UsbBufPtr[chkIdx+ZM_USB_STREAM_MODE_TAG_LEN]), halPriv->usbRxTransferLen); + + /* Record the buffer pointer */ + halPriv->remainBuf = newBuf; + } + } + else + { + u8_t* BufPtr; + u8_t* UsbBufPtr; + + /* Allocate a skb buffer */ + newBuf = zfwBufAllocate(dev, ZM_WLAN_MAX_RX_SIZE); + if ( newBuf != NULL ) + { + BufPtr = zmw_buf_get_buffer(dev, newBuf); + UsbBufPtr = srcBufPtr; + + /* Copy the buffer */ + zfwMemoryCopy(BufPtr, &(UsbBufPtr[chkIdx+ZM_USB_STREAM_MODE_TAG_LEN]), pktLen); + + zfwBufSetSize(dev, newBuf, pktLen); + rxBufPool[rxBufPoolIndex++] = newBuf; + } + } + } + else + { + u16_t i; + + DbgPrint("Can't find tag, pkt_len: 0x%04x, tag: 0x%04x\n", + pktLen, pktTag); + + #if 0 + for(i = 0; i < 32; i++) + { + DbgPrint("%02x ", buf->data[index-16+i]); + + if ((i & 0xf) == 0xf) + DbgPrint("\n"); + } + #endif + + break; + } + } + + /* Free buffer */ + //zfwBufFree(adapter, pUsbRxTransfer->buf, 0); + zfwBufFree(dev, buf, 0); + + for(ii = 0; ii < rxBufPoolIndex; ii++) + { + zfiUsbRecvPerPkt(dev, rxBufPool[ii]); + } +} +#endif + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfUsbInit */ +/* Initialize USB resource. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2005.12 */ +/* */ +/************************************************************************/ +void zfUsbInit(zdev_t* dev) +{ + /* Initialize Rx & INT endpoint for receiving data & interrupt */ + zfwUsbEnableRxEpt(dev, USB_ENDPOINT_RX_INDEX); + zfwUsbEnableIntEpt(dev, USB_ENDPOINT_INT_INDEX); + + return; +} + + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfUsbFree */ +/* Free PCI resource. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Stephen Chen ZyDAS Technology Corporation 2005.12 */ +/* */ +/************************************************************************/ +void zfUsbFree(zdev_t* dev) +{ + struct zsHpPriv *halPriv; + + zmw_get_wlan_dev(dev); + + halPriv = (struct zsHpPriv*)wd->hpPrivate; + +#ifdef ZM_OTUS_RX_STREAM_MODE + if ( halPriv->remainBuf != NULL ) + { + zfwBufFree(dev, halPriv->remainBuf, 0); + } +#endif + + return; +} + +void zfHpSendBeacon(zdev_t* dev, zbuf_t* buf, u16_t len) +{ + u32_t hw, lw; + u16_t i; + zmw_get_wlan_dev(dev); + + /* Write to beacon buffer (ZM_BEACON_BUFFER_ADDRESS) */ + for (i = 0; ihpPrivate)->hwFrequency < 3000) + { + zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_PLCP, ((len+4)<<(3+16))+0x0400); + } + else + { + zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_PLCP, ((len+4)<<(16))+0x001b); + } + + /* Beacon length (include CRC32) */ + zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_LENGTH, len+4); + + /* Beacon Ready */ + zfDelayWriteInternalReg(dev, ZM_MAC_REG_BCN_CTRL, 1); + zfFlushDelayWrite(dev); + + /* Free beacon buf */ + zfwBufFree(dev, buf, 0); + + return; +} + + +#define ZM_STATUS_TX_COMP 0x00 +#define ZM_STATUS_RETRY_COMP 0x01 +#define ZM_STATUS_TX_FAILED 0x02 +void zfiUsbRegIn(zdev_t* dev, u32_t* rsp, u16_t rspLen) +{ + //u8_t len, type, i; + u8_t type; + u8_t *u8rsp; + u16_t status; + u32_t bitmap; + zmw_get_wlan_dev(dev); + + zm_msg0_mm(ZM_LV_3, "zfiUsbRegIn()"); + + u8rsp = (u8_t *)rsp; + + //len = *u8rsp; + type = *(u8rsp+1); + u8rsp = u8rsp+4; + + + /* Interrupt event */ + if ((type & 0xC0) == 0xC0) + { + if (type == 0xC0) + { + zfCoreEvent(dev, 0, u8rsp); + + } + else if (type == 0xC1) + { +#if 0 + { + u16_t i; + DbgPrint("rspLen=%d\n", rspLen); + for (i=0; i<(rspLen/4); i++) + { + DbgPrint("rsp[%d]=0x%lx\n", i, rsp[i]); + } + } +#endif + status = (u16_t)(rsp[3] >> 16); + + ////6789 + rsp[8] = rsp[8] >> 2 | (rsp[9] & 0x1) << 6; + switch (status) + { + case ZM_STATUS_RETRY_COMP : + zfCoreEvent(dev, 1, u8rsp); + break; + case ZM_STATUS_TX_FAILED : + zfCoreEvent(dev, 2, u8rsp); + break; + case ZM_STATUS_TX_COMP : + zfCoreEvent(dev, 3, u8rsp); + break; + } + } + else if (type == 0xC2) + { + zfBeaconCfgInterrupt(dev, u8rsp); + } + else if (type == 0xC3) + { + zfEndOfAtimWindowInterrupt(dev); + } + else if (type == 0xC4) + { +#if 0 + { + u16_t i; + DbgPrint("0xC2:rspLen=%d\n", rspLen); + for (i=0; i<(rspLen/4); i++) + { + DbgPrint("0xC2:rsp[%d]=0x%lx\n", i, rsp[i]); + } + } +#endif + bitmap = (rsp[1] >> 16) + ((rsp[2] & 0xFFFF) << 16 ); + //zfBawCore(dev, (u16_t)rsp[1] & 0xFFFF, bitmap, (u16_t)(rsp[2] >> 16) & 0xFF); + } + else if (type == 0xC5) + { + u16_t i; +#if 0 + + for (i=0; i<(rspLen/4); i++) { + DbgPrint("0xC5:rsp[%d]=0x%lx\n", i, rsp[i]); + } +#endif + for (i=1; i<(rspLen/4); i++) { + u8rsp = (u8_t *)(rsp+i); + //DbgPrint("0xC5:rsp[%d]=0x%lx\n", i, ((u32_t*)u8rsp)[0]); + zfCoreEvent(dev, 4, u8rsp); + } + } + else if (type == 0xC6) + { + zm_debug_msg0("\n\n WatchDog interrupt!!! : 0xC6 \n\n"); + if (wd->zfcbHwWatchDogNotify != NULL) + { + wd->zfcbHwWatchDogNotify(dev); + } + } + else if (type == 0xC8) + { + //PZSW_ADAPTER adapter; + + // for SPI flash program chk Flag + zfwDbgProgrameFlashChkDone(dev); + } + else if (type == 0xC9) + { + struct zsHpPriv* hpPriv=wd->hpPrivate; + + zm_debug_msg0("##### Tx retransmission 5 times event #####"); + + /* correct tx retransmission issue */ + hpPriv->retransmissionEvent = 1; + } + } + else + { + zfIdlRsp(dev, rsp, rspLen); + } +} + + +#define ZM_PROGRAM_RAM_ADDR 0x200000 //0x1000 //0x700000 +#define FIRMWARE_DOWNLOAD 0x30 +#define FIRMWARE_DOWNLOAD_COMP 0x31 +#define FIRMWARE_CONFIRM 0x32 + +u16_t zfFirmwareDownload(zdev_t* dev, u32_t* fw, u32_t len, u32_t offset) +{ + u16_t ret = ZM_SUCCESS; + u32_t uCodeOfst = offset; + u8_t *image, *ptr; + u32_t result; + + image = (u8_t*) fw; + ptr = image; + + while (len > 0) + { + u32_t translen = (len > 4096) ? 4096 : len; + + result = zfwUsbSubmitControl(dev, FIRMWARE_DOWNLOAD, + (u16_t) (uCodeOfst >> 8), + 0, image, translen); + + if (result != ZM_SUCCESS) + { + zm_msg0_init(ZM_LV_0, "FIRMWARE_DOWNLOAD failed"); + ret = 1; + goto exit; + } + + len -= translen; + image += translen; + uCodeOfst += translen; // in Word (16 bit) + + result = 0; + } + + /* If download firmware success, issue a command to firmware */ + if (ret == 0) + { + result = zfwUsbSubmitControl(dev, FIRMWARE_DOWNLOAD_COMP, + 0, 0, NULL, 0); + + if (result != ZM_SUCCESS) + { + zm_msg0_init(ZM_LV_0, "FIRMWARE_DOWNLOAD_COMP failed"); + ret = 1; + goto exit; + } + } + +#if 0 + /* PCI code */ + /* Wait for firmware ready */ + result = zfwUsbSubmitControl(dev, FIRMWARE_CONFIRM, USB_DIR_IN | 0x40, + 0, 0, &ret_value, sizeof(ret_value), HZ); + + if (result != 0) + { + zm_msg0_init(ZM_LV_0, "Can't receive firmware ready: ", result); + ret = 1; + } +#endif + +exit: + + return ret; + +} + +u16_t zfFirmwareDownloadNotJump(zdev_t* dev, u32_t* fw, u32_t len, u32_t offset) +{ + u16_t ret = ZM_SUCCESS; + u32_t uCodeOfst = offset; + u8_t *image, *ptr; + u32_t result; + + image = (u8_t*) fw; + ptr = image; + + while (len > 0) + { + u32_t translen = (len > 4096) ? 4096 : len; + + result = zfwUsbSubmitControl(dev, FIRMWARE_DOWNLOAD, + (u16_t) (uCodeOfst >> 8), + 0, image, translen); + + if (result != ZM_SUCCESS) + { + zm_msg0_init(ZM_LV_0, "FIRMWARE_DOWNLOAD failed"); + ret = 1; + goto exit; + } + + len -= translen; + image += translen; + uCodeOfst += translen; // in Word (16 bit) + + result = 0; + } + +exit: + + return ret; + +} + +/************************************************************************/ +/* */ +/* FUNCTION DESCRIPTION zfIdlGetFreeTxdCount */ +/* Get free PCI PCI TxD count. */ +/* */ +/* INPUTS */ +/* dev : device pointer */ +/* */ +/* OUTPUTS */ +/* None */ +/* */ +/* AUTHOR */ +/* Stephen ZyDAS Technology Corporation 2006.6 */ +/* */ +/************************************************************************/ +u32_t zfHpGetFreeTxdCount(zdev_t* dev) +{ + return zfwUsbGetFreeTxQSize(dev); +} + +u32_t zfHpGetMaxTxdCount(zdev_t* dev) +{ + //return 8; + return zfwUsbGetMaxTxQSize(dev); +} + +void zfiUsbRegOutComplete(zdev_t* dev) +{ + return; +} + +extern void zfPushVtxq(zdev_t* dev); + +void zfiUsbOutComplete(zdev_t* dev, zbuf_t *buf, u8_t status, u8_t *hdr) { +#ifndef ZM_ENABLE_AGGREGATION + if (buf) { + zfwBufFree(dev, buf, 0); + } +#else + #ifdef ZM_BYPASS_AGGR_SCHEDULING + //Simply free the buf since BA retransmission is done in the firmware + if (buf) + { + zfwBufFree(dev, buf, 0); + } + zfPushVtxq(dev); + #else + zmw_get_wlan_dev(dev); + + #ifdef ZM_ENABLE_FW_BA_RETRANSMISSION + //Simply free the buf since BA retransmission is done in the firmware + if (buf) + { + zfwBufFree(dev, buf, 0); + } + #else + u8_t agg; + u16_t frameType; + + if(!hdr && buf) { + zfwBufFree(dev, buf, 0); + //zm_debug_msg0("buf Free due to hdr == NULL"); + return; + } + + if(hdr && buf) { + frameType = hdr[8] & 0xf; + agg = (u8_t)(hdr[2] >> 5 ) & 0x1; + //zm_debug_msg1("AGG=", agg); + + if (!status) { + if (agg) { + //delete buf in ba fail queue?? + //not ganna happen? + } + else { + zfwBufFree(dev, buf, 0); + } + } + else { + if (agg) { + //don't do anything + //zfwBufFree(dev, buf, 0); + } + else { + zfwBufFree(dev, buf, 0); + } + } + } + #endif + + if (wd->state != ZM_WLAN_STATE_ENABLED) { + return; + } + + if( (wd->wlanMode == ZM_MODE_AP) || + (wd->wlanMode == ZM_MODE_INFRASTRUCTURE && wd->sta.EnableHT) || + (wd->wlanMode == ZM_MODE_PSEUDO) ) { + zfAggTxScheduler(dev, 0); + } + #endif +#endif + + return; + +} + --- linux-2.6.28.orig/drivers/staging/otus/hal/hpfw2.c +++ linux-2.6.28/drivers/staging/otus/hal/hpfw2.c @@ -0,0 +1,1018 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "../80211core/cprecomp.h" + +const u32_t zcP2FwImage[] = { +0x0009000B, 0x4F222FE6, 0xDE947FFC, 0xE114D594, +0x1E13D494, 0x67521E4C, 0xD494D693, 0x37402769, +0x62528F06, 0x7201D692, 0x60602522, 0x2600C93F, +0xD7906152, 0x2512611D, 0x264B6652, 0x2562470B, +0x0009B00D, 0xE60095AC, 0xC84060E2, 0x2F028F03, +0x8FF93652, 0x7F047601, 0xA05A4F26, 0x4F226EF6, +0x410BD185, 0xD4850009, 0x0009440B, 0x450BD584, +0xD7840009, 0xD284E1FF, 0x2712611D, 0xD4835029, +0xE1FFCB01, 0x1209E501, 0x12112212, 0xE7202452, +0x4718D57F, 0x2572D27F, 0xD17FE700, 0xD680D47F, +0xE2012270, 0x24702172, 0xD67E2620, 0x2641E4FF, +0xD57DE600, 0x666DE104, 0x76016063, 0x4000626D, +0x8FF83212, 0xD5790545, 0x2520E201, 0xD279D778, +0x2710E100, 0xE5802212, 0x655C6613, 0x666DD476, +0x76046763, 0x374C626D, 0x8FF83253, 0xD4732712, +0xD573E101, 0xD6732410, 0x2542E400, 0xE03AE501, +0xD272D771, 0xE0390654, 0x27110654, 0x000B4F26, +0x7FC82211, 0xD76FD16E, 0xDC70DB6F, 0xD271DE70, +0xD572D471, 0x1F12D672, 0x1F76710C, 0x1FB877FC, +0x1FEA1FC9, 0x72041F2B, 0xDE6FDC6E, 0x1F13EB10, +0x1F511F44, 0x1F771F65, 0xD86C1F2C, 0xDD6DD96C, +0xD26DEA00, 0x89003A22, 0xD1587A01, 0x88016010, +0x56F98B03, 0x4218E201, 0xD1682622, 0x0009410B, +0x440BD467, 0xD5670009, 0x0009450B, 0x6010D14C, +0x8B108801, 0xE650D14B, 0x46186212, 0x8B083266, +0x56FAD147, 0x2120E200, 0xCB016062, 0x2602A003, +0x72012710, 0x60822122, 0x89098801, 0xE2C8D15A, +0x622C6612, 0x89033626, 0x6010D158, 0x8BC88801, +0x51F76792, 0x217252F6, 0xD6555191, 0x55FB2212, +0x52FC6462, 0x55612542, 0x2252E400, 0x61436643, +0x05DE6013, 0x36CC4608, 0x02DE2652, 0xC9036021, +0x8B028801, 0x720162E2, 0x74012E22, 0x36B3664C, +0x71048FEE, 0x66C2D147, 0x45286512, 0x265B4518, +0x60822C62, 0x89018801, 0x0009A168, 0x6272D742, +0x8B132228, 0xD726D541, 0x6552D441, 0x51436672, +0x316C365C, 0x27622668, 0x14138D05, 0x6262D63D, +0xB1A57201, 0xD61E2622, 0x2622E200, 0x52916692, +0x8B013620, 0x0009A144, 0x6061A06E, 0x001C001C, +0x001D4020, 0x0000B38E, 0xFFFF0000, 0x12340000, +0x001E1015, 0x00201278, 0x002018A0, 0x00201922, +0x0020128C, 0x001C3510, 0x001C3624, 0x001E212C, +0x0020397C, 0x00203514, 0x00203984, 0x00203990, +0x0020399C, 0x002039F8, 0x002039FC, 0x002039A4, +0x002039A5, 0x002039A8, 0x00117700, 0x00203A12, +0x00203578, 0x001142D8, 0x00203A14, 0x00203A16, +0x001C3D30, 0x00117718, 0x001C3D00, 0x001C1000, +0x001C36F8, 0x00117734, 0x001C3684, 0x00117710, +0x001C3520, 0x00117600, 0x00117740, 0x001C1028, +0x0020358C, 0x002039AC, 0x7FFFFFFF, 0x00201734, +0x002032BE, 0x002022E8, 0x00203DC0, 0x002039FA, +0x00203584, 0x002039EC, 0x001C3D2C, 0x001C36B0, +0x0020351C, 0x0011775C, 0x8801C90F, 0xA0CF8901, +0xD17C0009, 0x36206212, 0xD47B8904, 0x2421E200, +0x2162A0CC, 0x6211D179, 0x89012228, 0x0009A0C3, +0xE202D775, 0x75016571, 0x3123615D, 0x27518D02, +0x0009A0BC, 0xD27255F2, 0x62226052, 0x40094019, +0xC90F4009, 0x8F19880A, 0x52F31F2D, 0x40196022, +0x40094009, 0x8808C90F, 0xA0A78901, 0x60630009, +0x51F255F8, 0xE701CB01, 0x2502D263, 0xE1002172, +0x2211D564, 0x74016452, 0x2542A098, 0x8B3F8805, +0x602252F3, 0x40094019, 0xC90F4009, 0x8B168802, +0xE5FFD45D, 0x655D6742, 0x8B102758, 0x6272D75B, +0x8B0C3260, 0x55F257F8, 0x2762E101, 0xD5522512, +0xD757E400, 0x62722541, 0xA0777201, 0x52F32722, +0x40196022, 0x40094009, 0x8805C90F, 0x31B38B6E, +0xD5508B6C, 0x615257F4, 0x7101E240, 0x64722512, +0x1F4DD14D, 0x42182419, 0x8B033420, 0x6262D64B, +0x26227201, 0xE200D640, 0x2621B0AA, 0x0009A056, +0x3123E220, 0x88038B52, 0x52F38B1E, 0x40196022, +0x40094009, 0x8803C90F, 0xD7418B16, 0x647251F4, +0x7401D23D, 0x65122742, 0x1F5DE640, 0x46182529, +0x8B033560, 0x6262D63B, 0x26227201, 0xE200D62E, +0x2621B086, 0x0009A010, 0xD738D137, 0xD22A6412, +0xE5007401, 0x21423A76, 0x22518F06, 0xEA00D634, +0x72016262, 0x2622B074, 0x2FB2D532, 0x95406652, +0xD4305BF1, 0x36205241, 0x60618910, 0x8B01C803, +0x2B22E201, 0x8FF54510, 0x57F15664, 0x6272E1F0, +0x41284118, 0x2722221B, 0x6BF2A008, 0x6BF2A006, +0xE200D615, 0xD1152621, 0x2121E200, 0xE20256F5, +0x42186662, 0x26284228, 0x1F6D8D0C, 0xD61FD11E, +0x460B6511, 0x2008645D, 0x57F58904, 0x6272D11C, +0x27222219, 0xD11BE201, 0x66122822, 0x8B012668, +0x0009AE17, 0x450BD518, 0xD1180009, 0xAE10E600, +0x07D12160, 0x00203A0C, 0x00203A10, 0x00203A18, +0x001C3DC0, 0x0011772C, 0x001C3B88, 0x002039F4, +0x0011773C, 0x00117744, 0x0000F000, 0x00117764, +0x00117748, 0x00117768, 0x0011776C, 0x01FFFFFF, +0x0011774C, 0x00203584, 0x001142D8, 0x00114774, +0xFDFFFFFF, 0x00203DC0, 0x0020246C, 0x002039FA, +0x2F962F86, 0x2FB62FA6, 0x2FD62FC6, 0x4F222FE6, +0xD11F7FF4, 0x6212DE1F, 0x67E25411, 0xD41E1F41, +0x1F722F22, 0x6743D51D, 0x7794D21D, 0x5A425841, +0x6C726942, 0x6D225B16, 0xE6006052, 0x2502CB20, +0x7601E540, 0x3253626D, 0x62F28BFB, 0x212255F1, +0x55F21151, 0x2E52D613, 0x14A21481, 0xD4122492, +0x11B627C2, 0x674226D2, 0xD911DA10, 0x2A72E801, +0x1A8C490B, 0x4218E201, 0x7F0C1A2C, 0x6EF64F26, +0x6CF66DF6, 0x6AF66BF6, 0x000B69F6, 0x000068F6, +0x001C3B9C, 0x001C3D98, 0x001C3700, 0x001C3500, +0x001C5960, 0x001C8960, 0x0020358C, 0x001C3D00, +0x00201610, 0x2F962F86, 0x2FC62FA6, 0x2FE62FD6, +0x4F124F22, 0x7F884F02, 0xE018DEB2, 0xD4B261E0, +0x61E30F14, 0x62107101, 0x440BE01C, 0x20080F24, +0x8F126D03, 0xD4AD1F08, 0x6740DDAD, 0x657CD4AD, +0x470BD7AD, 0xD2AD0009, 0x621C6120, 0x46086623, +0x36284608, 0x3D6C4608, 0xE01C1FD8, 0xE58004FC, +0x604C66E2, 0x3050655C, 0x2D628F17, 0x01FCE018, +0xDEA3E500, 0x641CA008, 0x6753655D, 0x607037EC, +0x31DC6153, 0x80147501, 0x3243625D, 0xD49D8BF4, +0xE200D59D, 0xA27F2421, 0x20082521, 0xE0188B13, +0xE50001FC, 0xA009DE96, 0x655D641C, 0x32EC6253, +0x62536722, 0x32DC6672, 0x75041261, 0x3243625D, +0xA2698BF3, 0x88012D10, 0xE0188B16, 0xE40001FC, +0x671C2D40, 0x624DDE8A, 0x8B013273, 0x0009A25C, +0x6DE3644D, 0x7D046243, 0x32EC6643, 0x652236DC, +0x74086162, 0x2512AFEF, 0x8B198804, 0x01FCE018, +0x2D70E700, 0x1FD56D1C, 0x627DDE7D, 0x8B0132D3, +0x0009A242, 0x6173677D, 0x31EC65E3, 0x75046412, +0x365C6673, 0x61426262, 0x21297708, 0x2412AFED, +0x8B198805, 0x01FCE018, 0x2D70E700, 0x1FD46D1C, +0x627DDE6F, 0x8B0132D3, 0x0009A226, 0x6173677D, +0x31EC65E3, 0x75046412, 0x365C6673, 0x61426262, +0x212B7708, 0x2412AFED, 0x8B598831, 0x61E6DE67, +0x61E31F19, 0x64E27104, 0x1F4A6216, 0x1F2B6416, +0x75E46513, 0x66536712, 0x1F4C7604, 0x64521F7D, +0xD75F6E66, 0x27E0D25F, 0xDE5F6062, 0xC9013245, +0x65622E00, 0x4609060A, 0x4609D15C, 0x46094509, +0x21501F4E, 0xB2B0646D, 0x620D1F6F, 0x8B012228, +0x0009A1EA, 0xD756DE55, 0x661C61E0, 0x6410D150, +0x470B654C, 0x7FFC54FF, 0x2FE25EFE, 0x51FE7FFC, +0x2F12E040, 0x55FBD14F, 0x57FD56FC, 0x04FE410B, +0xD24D7F08, 0xE11C640D, 0x1D412D10, 0xD44B6522, +0x67421D52, 0x1D73DE4A, 0xD24A65E2, 0x67221D54, +0x1D75D249, 0xD2496E22, 0x66221DE6, 0x1D67A1BC, +0x89018830, 0x0009A08E, 0xE340D538, 0x33FC6156, +0x23126456, 0x71046153, 0x67521341, 0x13726416, +0x7EE46E13, 0x65E66212, 0x66E3D731, 0x13246EE2, +0x760427E0, 0x6062D22F, 0x3255DE2F, 0x2E00C901, +0x060A6E62, 0xD12D4609, 0x4E094609, 0x13434609, +0x646D21E0, 0xB2501F5E, 0x620D1F6F, 0x8B012228, +0x0009A18A, 0xDE25D522, 0x61E06450, 0xD724654C, +0x470B54FF, 0x7FFC661C, 0x06FEE054, 0x7FFC2F62, +0xEE4001FE, 0x2F123EFC, 0x55E2D125, 0x57E456E3, +0x64E2410B, 0xD21C7F08, 0xE11C640D, 0x1D412D10, +0xD61A6522, 0x67621D52, 0x1D73DE19, 0xD2196EE2, +0x62221DE4, 0xD2181D25, 0x1D266222, 0x6222D217, +0x1D27A15A, 0x00117800, 0x00202A18, 0x00203996, +0x002035BC, 0x00203A7C, 0x002018D0, 0x00203995, +0x00117804, 0x00203A14, 0x00203A16, 0x00117810, +0x00203991, 0x10624DD3, 0x00203992, 0x00203993, +0x00114AA4, 0x00200F68, 0x001C5864, 0x001C6864, +0x001C7864, 0x001C59BC, 0x001C69BC, 0x001C79BC, +0x00200FC0, 0x8B048833, 0x470BD7A2, 0xA123EE00, +0x88282DE0, 0xA0D38901, 0xDE9F0009, 0x62E1E143, +0x3216E054, 0x0FE68F02, 0x2E21E240, 0x622D62E1, +0x8B013217, 0x0009A0BC, 0xE50185E1, 0x8B013056, +0x0009A0B6, 0x2D10E101, 0x64E1B111, 0x06FEE054, +0x6261E143, 0x3517652D, 0xE6408945, 0x8B0C3563, +0xE058E41A, 0xE5000F45, 0x72C0E05C, 0x60230F55, +0x6703C907, 0xA014E060, 0x66530F75, 0x46214621, +0x46214621, 0x45214621, 0xE0587618, 0x0F654521, +0xE0034521, 0xE05C2509, 0xE0070F55, 0xE0602209, +0xE8540F25, 0x858238FC, 0x640D65F3, 0x1844B170, +0xDD7A8584, 0x85866C0D, 0x610D4C08, 0x410860C3, +0xE00F0EFE, 0x18154D0B, 0x2E296207, 0x668260C3, +0x85620FE6, 0x4D0B5185, 0x2E0B600D, 0x548460C3, +0xB13C0FE6, 0xE05465F3, 0xE5400EFE, 0xE06C62E1, +0x3653662D, 0x0F668D41, 0xC9036023, 0x40004008, +0x61036403, 0xD965E070, 0x0F46E5FF, 0xE074655C, +0x60530F96, 0x6263490B, 0x42214221, 0x42214221, +0x42006723, 0x4200327C, 0x6C074621, 0x4621E054, +0x606309FE, 0x4008C903, 0x790630FC, 0x6A036D2D, +0x65F3E800, 0x64D3B124, 0xE0706EA2, 0x2AE22EC9, +0x01FE6694, 0x666CE074, 0x470B07FE, 0x2E0B6063, +0x65F32AE2, 0xB0FA64D3, 0x628D7801, 0x32E3EE06, +0x7D018FE7, 0x0EFEE054, 0xE05462E1, 0x420006FE, +0x760C8561, 0x701B302C, 0xE4006103, 0xE70465F3, +0x68667401, 0x3973694D, 0x8FF92582, 0x65F37504, +0x641DB0DD, 0x0EFEE054, 0x64E1B09C, 0x0009A054, +0xD43B56F8, 0xEA01D23B, 0x26A0420B, 0x0009A04C, +0x06FCE01C, 0x8829606C, 0x5CF88B08, 0xE200D636, +0x52612C20, 0x642DB04B, 0x0009A03E, 0x666CE681, +0x8B043060, 0x420BD231, 0xA03554F8, 0xE6820009, +0x3060666C, 0xD22E8B04, 0x54F8420B, 0x0009A02C, +0x666CE683, 0x8B0A3060, 0xDA2755F8, 0x2590E900, +0xD82855A1, 0x2852D628, 0xA01D52A2, 0xE6922620, +0x3060666C, 0xD2208B08, 0x5C21D824, 0x6CCC52F8, +0x28C1E600, 0x2260A010, 0x666CE693, 0x8B063060, +0xD61F59F8, 0xE201EA00, 0xA00529A0, 0xD6162621, +0xD21DD41C, 0x6562420B, 0x4F067F78, 0x4F264F16, +0x6DF66EF6, 0x6AF66CF6, 0x000B69F6, 0x4F2268F6, +0xE240614D, 0x89323123, 0x3127E21F, 0x8B27D713, +0xD406614D, 0xE00171E0, 0x5671440B, 0x26596507, +0x1761A025, 0x00200FBC, 0x00117804, 0x00203470, +0x00203A9C, 0x002018C0, 0x00117800, 0x00115F00, +0x00116058, 0x0020397C, 0x00203990, 0x00203A1A, +0x00203A16, 0x00203AB4, 0x002018D0, 0x001C3704, +0xE001D490, 0x6672440B, 0x26596507, 0x4F262762, +0x0009000B, 0x614D4F22, 0x3123E240, 0xE21F8912, +0xD7893127, 0x614D8B08, 0x5671D286, 0x420B71E0, +0x260BE001, 0x1761A006, 0x6672D282, 0xE001420B, +0x2762260B, 0x000B4F26, 0xE6400009, 0x46284618, +0x6252D57E, 0x89FC2268, 0x0009000B, 0x4618E680, +0xD57A4628, 0x22686252, 0x000B89FC, 0xA0010009, +0x7201E200, 0x8BFC3242, 0x0009000B, 0x4618E680, +0xD5734628, 0x22686252, 0x000B8BFC, 0x2FE60009, +0x7FFC4F22, 0xBFF16E53, 0x61E22F42, 0xE280D66D, +0x54E11615, 0x16464218, 0x422855E2, 0x57E31657, +0x16786EF2, 0x26E22E2B, 0x4F267F04, 0x6EF6AFCE, +0x2FD62FC6, 0x4F222FE6, 0x6C53DD62, 0x6E43BFD6, +0x2DE2BFBB, 0x0009BFD2, 0x2C1251D5, 0x1C4154D6, +0x1C5255D7, 0x1C6356D8, 0x6EF64F26, 0x000B6DF6, +0x61636CF6, 0xA004E600, 0x62564109, 0x24227601, +0x36127404, 0x000B8BF9, 0xD6530009, 0x8562E500, +0xA00B674D, 0x655D610D, 0x40006053, 0x305CD44F, +0x024D4008, 0x3270622D, 0x75018905, 0x3213625D, +0x000B8BF1, 0x000BE000, 0x2FE6E001, 0x54416743, +0x4E08EE7F, 0x4E28D246, 0x25E96543, 0x60436E21, +0x9E7562ED, 0x4529C903, 0xE60032E3, 0x8D456103, +0x21184509, 0xD23F8B05, 0x002C6053, 0xA08AC93F, +0x60136603, 0x8B268801, 0x880C6053, 0xD53A8B04, +0xC93F8453, 0x6603A07F, 0x8B048808, 0x84E2DE36, +0xA078C93F, 0x880D6603, 0x8B03D633, 0xC93F8461, +0x6603A071, 0x88096260, 0x622C8F09, 0xE014DE2C, +0x655C05EC, 0x60233258, 0xA064C93F, 0x60236603, +0xA060C93F, 0x88026603, 0xE0078B5D, 0x60432509, +0x8905C810, 0x6053D225, 0xC93F002C, 0x6603A053, +0x6053DE23, 0xC93F00EC, 0x6603A04D, 0x88016013, +0x60538B19, 0x8B04880C, 0x8423D21E, 0xA042C93F, +0x88086603, 0xD51B8B04, 0xC93F8452, 0x6603A03B, +0xD618880D, 0x84618B03, 0xA034C93F, 0x60606603, +0xA030C93F, 0x88026603, 0xE0078B2D, 0x60432509, +0x8923C810, 0x6053DE10, 0xC93F00EC, 0x6603A023, +0x00000BB8, 0x00203470, 0x001C3704, 0x001C373C, +0x001C3700, 0x001C370C, 0x00114000, 0x00114008, +0x001142D8, 0x001142E4, 0x001142E8, 0x001142F5, +0x001142ED, 0x001142FD, 0x00114309, 0x6053D209, +0xC93F002C, 0x60136603, 0x8B038802, 0xC8106043, +0x76028900, 0xC93F6063, 0x40004018, 0x1741240B, +0x6EF6000B, 0x00114301, 0x0009A16E, 0x2FE62FD6, +0xDD944F22, 0xA0049EB2, 0xD4930009, 0x420BD293, +0x62D265D2, 0x8BF822E8, 0x0009A004, 0xD28FD490, +0x55D1420B, 0x22E852D1, 0xA0048BF8, 0xD48D0009, +0x420BD28A, 0x52D255D2, 0x8BF822E8, 0x0009A004, +0xD286D489, 0x55D3420B, 0x22E852D3, 0xA0048BF8, +0xD4860009, 0x420BD281, 0x52D455D4, 0x8BF822E8, +0x6EF64F26, 0x6DF6000B, 0x2FD62FC6, 0x4F222FE6, +0x6E636C73, 0x6D53B01A, 0x64D357F4, 0xB05F65E3, +0xB07566C3, 0xB0A40009, 0xB0A80009, 0xB0AC0009, +0xB0AC0009, 0xB0AF0009, 0xB03154F5, 0x6CCD6C03, +0x4F2660C3, 0x6DF66EF6, 0x6CF6000B, 0x3412D170, +0xD6700529, 0x2650D770, 0x2742000B, 0x0009A018, +0x2FD62FC6, 0x4F222FE6, 0x6E636C73, 0x6D53BFEE, +0x64D357F4, 0xB03365E3, 0xB08D66C3, 0xB00F54F5, +0x6CCD6C03, 0x4F2660C3, 0x6DF66EF6, 0x6CF6000B, +0xE503D162, 0xD763D462, 0x21524518, 0x2472000B, +0xD45FD15E, 0x2162E600, 0x2462000B, 0xBF734F22, +0xBF73E40A, 0xD25C0009, 0x4118E104, 0xE40AE500, +0xBF692212, 0xD7592252, 0xCB206072, 0x000B4F26, +0x4F222702, 0x410BD156, 0xD556E400, 0x4F26452B, +0xD1552FE6, 0x66126E63, 0x92104418, 0x44084528, +0x45002629, 0x265B4408, 0x264B4400, 0x21624708, +0xD14E4708, 0x217227EB, 0x6EF6000B, 0x1FFF03F0, +0x4F222FE6, 0xE101DE4A, 0xBF3DE40A, 0x67E32E12, +0xE500776C, 0xE204E130, 0x2752E40A, 0x27522752, +0x27522752, 0x27522752, 0x27522752, 0x27522752, +0x27522752, 0x27522752, 0x27522752, 0x27522752, +0x27222712, 0x27522752, 0x27522752, 0x27522752, +0x27522752, 0x175ABF18, 0x2E62E600, 0x000B4F26, +0xD2346EF6, 0xE441E101, 0x000B2212, 0xD1322242, +0xE605D432, 0x000B2162, 0x000B2462, 0xD2300009, +0xE40AE601, 0x2262AF00, 0x2FC62FB6, 0x2FE62FD6, +0x7FFC4F22, 0x6C43DB2B, 0xED0060B2, 0x2B02CB03, +0xC90360B2, 0x6E03A008, 0x89073DC2, 0xE46460B2, +0xB07CC903, 0x7D016E03, 0x8BF52EE8, 0x8F043DC2, +0xD4212FE1, 0x460BD621, 0x62F10009, 0x6023622D, +0x89FFC801, 0x7F046023, 0x6EF64F26, 0x6CF66DF6, +0x6BF6000B, 0x001C3B88, 0x00203AC8, 0x002018D0, +0x00203AD0, 0x00203AD8, 0x00203AE0, 0x00203AE8, +0x0025E720, 0x00203DBC, 0x00203980, 0x001C5968, +0x001C3B40, 0x000F8000, 0x001D4004, 0x001C3500, +0x002015E4, 0x00201610, 0x001C5814, 0x001C59D0, +0x001C5830, 0x001C6268, 0x001C59A4, 0x001C639C, +0x001C581C, 0x001C5860, 0x00203AF0, 0x002018C0, +0x8F014411, 0x6043604B, 0x0009000B, 0x5651D52B, +0x46286052, 0x306C000B, 0x2FC62FB6, 0x2FE62FD6, +0x4F124F22, 0xBFF14F02, 0x6B036E43, 0xDD25DC24, +0x0009BFEC, 0x3C0530B8, 0x4609060A, 0x46014609, +0x020A3D65, 0x42094209, 0x32E24209, 0x4F068BF0, +0x4F264F16, 0x6DF66EF6, 0x000B6CF6, 0x2FC66BF6, +0x2FE62FD6, 0x4F124F22, 0xBFCF4F02, 0x6C036E43, +0xBFCBDD13, 0x30C80009, 0x060A3D05, 0x46094609, +0x36E24601, 0x4F068BF5, 0x4F264F16, 0x6DF66EF6, +0x6CF6000B, 0x4F222FE6, 0xE102DE0B, 0xE403E500, +0xBFB92E12, 0xE6062E52, 0xE7004618, 0x2E62E403, +0x4F262E72, 0x6EF6AFB0, 0x0009000B, 0x001C1040, +0xCCCCCCCD, 0x10624DD3, 0x001D4004, 0x2F962F86, +0x2FB62FA6, 0x2FD62FC6, 0x4F222FE6, 0xE5007F98, +0x6453E710, 0x6B534728, 0xEE1ADCBC, 0x6153655D, +0x315C4108, 0x75014108, 0x6043317C, 0x0F16665D, +0xED0060B3, 0x21B136E3, 0x81128111, 0x11D28113, +0x11D411D3, 0x74048FEA, 0xD8B167F2, 0x1871D9B1, +0x58F12872, 0x1981D1B0, 0x59F22982, 0x5DF45AF3, +0x54F65EF5, 0x21921191, 0x11A211A3, 0x11D411D5, +0x11E611E7, 0x11481149, 0xDAA855F7, 0x57F8EE00, +0x52F9DDA7, 0x64E3D6A7, 0x2A521A51, 0xD8A7D9A6, +0x2D72EAEF, 0x6AAC2622, 0x6DE36EED, 0x61E34D08, +0x41083DEC, 0x31EC4D08, 0x60B33D9C, 0x2DB14108, +0xE05081D1, 0xE79F4108, 0x41084008, 0x81D2677C, +0x318C60B3, 0x3472E200, 0x1DD281D3, 0xD4931D13, +0x1D248D01, 0x65D3D48F, 0x7E01B0B2, 0x34A264ED, +0xDA8C8BDA, 0x68A22FD2, 0x4829DD91, 0x64A22D82, +0x694D7DFC, 0x2D92D286, 0x4E296E22, 0x2DE27D0C, +0x6AD36822, 0xD784618D, 0x6D722A16, 0xD583D489, +0x5E7224D2, 0x14E2D688, 0xEE005174, 0x58761414, +0x1486D186, 0xE7105978, 0x62521498, 0x142A65E3, +0x64E326E2, 0x644DE600, 0x48086843, 0x4808384C, +0x6053381C, 0x28B10C86, 0x60B309CE, 0x60538191, +0x60430ACE, 0x605381A2, 0x60B30DCE, 0x605381D3, +0x740108CE, 0x09CE1882, 0x19E3624D, 0x32730ACE, +0x8FE01A64, 0xD96A7504, 0x6C92E003, 0x2CB14018, +0xDA6F6D92, 0xE05081D1, 0x40086E92, 0x619281E2, +0x811360B3, 0xE6006492, 0x67921442, 0x17A3D468, +0xE1FF6892, 0xE7031864, 0x46086563, 0x7501364C, +0x665D2612, 0x8BF83673, 0xE003DC5A, 0x40186DC2, +0x6EC22DB1, 0x81E1D25F, 0xEE0061C2, 0x64C21112, +0x1423E024, 0xD45B65C2, 0x67C215E4, 0x8172E580, +0x66E368C2, 0x655C8183, 0x6963666D, 0x6A6D7604, +0x3A53394C, 0x29E28FF8, 0xDC54DB53, 0x740424B2, +0x7F6824C2, 0x6EF64F26, 0x6CF66DF6, 0x6AF66BF6, +0x000B69F6, 0x614268F6, 0xC8036011, 0xE5008F03, +0x3420D23C, 0x60118B06, 0x8802C903, 0xD2398B06, +0x8B033420, 0x65135612, 0x24225264, 0x6053000B, +0x2FE62FD6, 0x7FEC4F22, 0x62536E53, 0x6D43E550, +0x4508E400, 0xE101A001, 0x60435224, 0x81212211, +0x60538123, 0x56E28122, 0x8BF53620, 0x16E4D238, +0xE61464F3, 0x65E3420B, 0xE4FC65E1, 0x2E512549, +0x65F361F1, 0x2F112149, 0xD13154D1, 0xE614410B, +0x607157D1, 0x2701CB01, 0x7F141DE1, 0x6EF64F26, +0x6DF6000B, 0x2FE62FD6, 0x7FEC4F22, 0x66536E53, +0x6D43E5FC, 0x20596061, 0x2601CB01, 0x326052E2, +0x12E48B06, 0x31E051E2, 0x52D18B04, 0x1E22A002, +0x5664AFF0, 0x64F3D21E, 0x420BE614, 0x67E165E3, +0x2719E1FC, 0x67F12E71, 0x271954D1, 0x65F3D118, +0x410BE614, 0x52D12F71, 0xCB016021, 0x1DE12201, +0x4F267F14, 0x000B6EF6, 0x00006DF6, 0x002039AC, +0x0020357C, 0x00203584, 0x0020358C, 0x002035B4, +0x00203998, 0x002039A0, 0x00100208, 0x001014C0, +0x001E210C, 0x001C3D00, 0x002039EC, 0x001000C8, +0x00117880, 0x00117780, 0x00040020, 0x0026C401, +0x00200D42, 0x4F222FE6, 0xDE42624C, 0x42004208, +0x3E2CA005, 0xD4405252, 0xBF695624, 0x65E22E62, +0x352052E1, 0xD63D8BF6, 0x4F262622, 0x6EF6000B, +0x2FC62FB6, 0x2FE62FD6, 0xDC394F22, 0x52C1DB39, +0x362066C2, 0x6061891C, 0x8801C903, 0xDE348918, +0xBF38DD35, 0x650364E3, 0x66B28503, 0x3262620D, +0xD4328907, 0x0009BF76, 0x4D0BD431, 0xAFE60009, +0xBF3D0009, 0xD42F64E3, 0x00094D0B, 0x0009AFDF, +0x2262D22D, 0x6EF64F26, 0x6CF66DF6, 0x6BF6000B, +0x2FD62FC6, 0x4F222FE6, 0xDD29DC28, 0x6E4360C2, +0x04DE4008, 0xE614D127, 0x65E3410B, 0xD127D726, +0x55E227E2, 0x35E05254, 0x21228F04, 0x400860C2, +0x122202DE, 0x605365C2, 0x75014008, 0x0DE606DE, +0xC90F6053, 0x60632C02, 0x6EF64F26, 0x000B6DF6, +0x85436CF6, 0x650D5643, 0x622D6262, 0x35277204, +0xE1008F0C, 0x2268960C, 0xD6158B03, 0x72015261, +0xD6131621, 0x6262E101, 0x26227201, 0x6013000B, +0x000001FF, 0x0020358C, 0x00203584, 0x001C3D00, +0x002035B4, 0x0020397C, 0x002018C0, 0x0020357C, +0x00203B18, 0x00203B1C, 0x001C3D28, 0x002039EC, +0x002039AC, 0x00200D42, 0x002039F0, 0x002039F4, +0x00117754, 0x2FA62F96, 0x2FC62FB6, 0x2FE62FD6, +0x7FF84F22, 0x6C22D241, 0xC80360C3, 0xDE40896E, +0xDA41DB40, 0x52B1D941, 0x362066B2, 0x60618945, +0x8801C903, 0xDD3B8941, 0x420BD23D, 0x650364D3, +0x60A12F02, 0x89328801, 0x85145153, 0x8840600C, +0x1F118F0C, 0xD5376191, 0x641D450B, 0x8B262008, +0xD7356691, 0x646D470B, 0x8B202008, 0x420BD233, +0x51F154F1, 0xC8208511, 0xD1318904, 0x021EE050, +0x01267201, 0x420BD22F, 0x200864F2, 0x64D38907, +0x4D0BDD2D, 0xD12D65F2, 0xAFC4E601, 0xD22C2162, +0x420B65F2, 0xD72B64E3, 0xAFBCE601, 0xD2262762, +0x420B65F2, 0xAFB664D3, 0xDE270009, 0xDA28DD27, +0x52D1DB28, 0x362066D2, 0x60618918, 0x8801C903, +0xD4228914, 0x450BD516, 0x56030009, 0x8F0436E0, +0xE2016503, 0xAFEC2A20, 0xD41F2B52, 0x420BD216, +0xD7180009, 0x4118E101, 0x2712AFE3, 0xC80460C3, +0xD21A8902, 0x0009420B, 0x4F267F08, 0x6DF66EF6, +0x6BF66CF6, 0x000B6AF6, 0x000069F6, 0x001E2100, +0x0020358C, 0x00203584, 0x00203A14, 0x001142D8, +0x002014A6, 0x00115EA2, 0x00114774, 0x00200D8A, +0x0020351C, 0x002016C2, 0x002014D0, 0x001E212C, +0x00201534, 0x001C3D30, 0x00117880, 0x0020357C, +0x0020399C, 0x00203998, 0x002035B4, 0x00200644, +0xE601D203, 0x1265D503, 0x000B2252, 0x00001266, +0x001C1010, 0x0000C34F, 0x0009000B, 0x0009000B, +0x0009000B, 0x0009000B, 0xE000000B, 0xE000000B, +0x0009000B, 0xE4FDD59D, 0xD69D6152, 0x25122149, +0x74016052, 0x2502CB01, 0xD19A6752, 0x25722749, +0xC8406010, 0x60628902, 0x2602CB04, 0xE1F76462, +0x26422419, 0xE7016062, 0x2602C9CF, 0xE5026062, +0x2602CB10, 0x47186062, 0x2602CB03, 0x000B1652, +0xD58D1673, 0xD28ED78D, 0xE100D48E, 0x2511E600, +0x22102711, 0x2461AFCE, 0xD28B664C, 0x362C4600, +0xCB106060, 0x2600000B, 0xD287654C, 0x352C4500, +0xE1EF6650, 0x000B2619, 0x664C2560, 0x4600D283, +0x6060362C, 0x000BCB10, 0x654C2600, 0x4500D27F, +0x6650352C, 0x2619E1EF, 0x2560000B, 0xD27A664C, +0x362C4600, 0xCB086060, 0x2600000B, 0xD276654C, +0x352C4500, 0xE1F76650, 0x000B2619, 0x664C2560, +0x4600D272, 0x6060362C, 0x000BCB08, 0x654C2600, +0x4500D26E, 0x6650352C, 0x2619E1F7, 0x2560000B, +0xD669624C, 0x326C4200, 0xC9086020, 0x40214021, +0x000B4021, 0x624C600C, 0x4200D664, 0x6020326C, +0x4021C908, 0x40214021, 0x600C000B, 0x644CD160, +0x6240341C, 0x602C000B, 0x644CD15E, 0x6240341C, +0x602C000B, 0x4F222FE6, 0x645C6E43, 0x3467E60A, +0xBFEB8914, 0x640C0009, 0x880160EC, 0xE00F8B02, +0x2409A002, 0x44094409, 0xE60A624C, 0x89053263, +0x644CBFE2, 0x6023620C, 0x8B00C880, 0x6023E200, +0x000B4F26, 0x4F226EF6, 0x6062D64B, 0x8B038801, +0x0009B256, 0x0009A003, 0xE640D248, 0xD6482260, +0x4F26E200, 0x2622000B, 0xD6434F22, 0x88026062, +0xB29F8B01, 0xD6420009, 0x4F26E200, 0x2622000B, +0xD43ED53D, 0xE701E100, 0x000B2512, 0xD23B2470, +0x000BE604, 0x4F222260, 0xD13BD43A, 0x0009410B, +0xE1FDD53A, 0xD23A6650, 0xE7002619, 0x4F262560, +0x2270000B, 0xD5374F22, 0x6152D237, 0x611DD737, +0x64522512, 0x242BE6FF, 0xD4352542, 0x666DD22E, +0x2762420B, 0xE1FBD52D, 0x27196750, 0x000B4F26, +0x4F222570, 0xD128D42F, 0x0009410B, 0xE7F7D527, +0x26796650, 0x000B4F26, 0xD5242560, 0x62509425, +0x000B2249, 0xD5212520, 0x6250E4BF, 0x000B2249, +0x4F222520, 0x8522D224, 0x2008600D, 0x88018911, +0x88038944, 0x88058946, 0x88068948, 0x8808894E, +0x88098954, 0x880A895A, 0x880B8960, 0xA06D8966, +0xB06F0009, 0xA06A0009, 0xFF7F600C, 0x001E2148, +0x001E1108, 0x001E1000, 0x00203A4C, 0x00203A4E, +0x00203A6D, 0x00203A30, 0x001E103F, 0x001E105F, +0x001E102F, 0x001E1090, 0x00203A54, 0x001E100B, +0x00203A50, 0x00203B20, 0x002018C0, 0x001E1028, +0x00203A6C, 0x001D4020, 0x98760000, 0x001C1000, +0x00203B2C, 0x00203B3C, 0x00203A24, 0x0009B04C, +0x600CA035, 0x0009B055, 0x600CA031, 0x6260D684, +0x8B2B2228, 0x0009B061, 0x600CA029, 0x6260D680, +0x8B232228, 0x0009B069, 0x600CA021, 0x6260D67C, +0x8B1B2228, 0x0009B0C7, 0x600CA019, 0x6260D678, +0x8B132228, 0x0009B0CD, 0x600CA011, 0x6260D674, +0x8B0B2228, 0x0009B125, 0x600CA009, 0x6260D670, +0x8B032228, 0x0009B13D, 0x600CA001, 0x4F26E000, +0x0009000B, 0xD26CD16B, 0xD56C8412, 0x4000C90F, +0xD76B012D, 0xE403D66B, 0xE20F611C, 0x2540E001, +0x25202712, 0x2602000B, 0xE601D262, 0x30668523, +0xE0008D05, 0xD663D260, 0xE0018122, 0x000B2602, +0xD25C0009, 0x600D8523, 0x89052008, 0x8B0A8801, +0x6060D65D, 0x2600CB01, 0xD457D65A, 0xE001E101, +0x000B2612, 0x000B8142, 0xD152E000, 0x8513E501, +0x640D4518, 0x66033453, 0xE0008D05, 0xD551D253, +0x2260E001, 0x000B2502, 0x4F220009, 0x8513D149, +0x6453650D, 0x62494419, 0x227D672E, 0x8801602C, +0x88028909, 0x88038910, 0x8806891A, 0x88078935, +0xA04C893B, 0xD5460009, 0x6652D746, 0x2762D446, +0x622C6261, 0x2421A038, 0x2228625C, 0xD4438B3F, +0x6642D540, 0x2562D440, 0x24018561, 0x6203A02C, +0x2008605C, 0x88108907, 0x88208908, 0x88308909, +0xA02C890A, 0xD23A0009, 0x6222A008, 0xA005D239, +0xD2396222, 0x6222A002, 0x6262D638, 0xD432D531, +0x66212522, 0xA00F626C, 0xD6352421, 0x6261D52D, +0x622CD42D, 0xA0072562, 0xD6322421, 0x8561D529, +0x2562D429, 0x62032401, 0x662D8515, 0x3617610D, +0x65038F01, 0xB0CB2451, 0xA0010009, 0xE000E001, +0x000B4F26, 0xD6190009, 0xD427E101, 0x65412610, +0xD118D717, 0xE20F655D, 0x2752E001, 0x000B2620, +0x2FE62102, 0xD20F4F22, 0x640C8523, 0x8B082448, +0xD511D61D, 0x2621E200, 0x940F8451, 0xA0482049, +0xDE0D8051, 0xC84060E0, 0xE2018D32, 0x89443427, +0xD216D615, 0x2641420B, 0x0009A030, 0x0000FF7F, +0x00203A6D, 0x00203A24, 0x00203A30, 0x001E1100, +0x001E100C, 0x00203A50, 0x001E1000, 0x001E1001, +0x00203A58, 0x00203A38, 0x00203A3C, 0x00203A40, +0x00203A5C, 0x00203A60, 0x00203A64, 0x00203A68, +0x00203E20, 0x00203E2A, 0x00203A4A, 0x002027F2, +0x89123427, 0xD294D693, 0x2641420B, 0xCB8084E1, +0x80E1B0F5, 0xD69160E0, 0x2E00CB04, 0xC93F6060, +0xD68F2600, 0xA001E001, 0xE0002602, 0x000B4F26, +0xD68C6EF6, 0xC8806060, 0xD2868919, 0x88016021, +0xD2898B15, 0x8524E501, 0x89103056, 0xE203D187, +0x2120D487, 0xE00B6541, 0x0656655D, 0xE40FD585, +0x2140E702, 0xD77E2571, 0x000BE001, 0x000B2702, +0x2FE6E000, 0xDE804F22, 0xC88084E1, 0xD57A892C, +0x20088554, 0x61038F28, 0x8553D77C, 0x64036672, +0x8566650C, 0x3520620C, 0xD6798B1E, 0x651CD774, +0x2651644C, 0x60E02741, 0x8904C840, 0x420BD275, +0xA0030009, 0xD2680009, 0x0009420B, 0x0009B09F, +0xE201D167, 0x60E02122, 0xCB04D464, 0x60402E00, +0x2400C93F, 0x6023A001, 0x4F26E000, 0x6EF6000B, +0x2FB62FA6, 0x2FD62FC6, 0xDA622FE6, 0x66A1E240, +0x3622DC5E, 0x62638900, 0x6ED36D2C, 0x4E2136D8, +0x4E212A61, 0xDB61D460, 0xE700A00F, 0x770162B2, +0x71026123, 0x66212B12, 0x71026213, 0x61212B12, +0x651D666D, 0x356C4528, 0x627C2452, 0x8BED32E3, +0xC90360D3, 0x8B108803, 0x617367B2, 0x2B127102, +0x71026E13, 0x2B126571, 0x655D6DE1, 0x422862DD, +0x325CE107, 0xA00C2C10, 0x88022422, 0xA0038B01, +0x8801E203, 0xE2018B05, 0x66B22C20, 0x655D6561, +0xE60F2452, 0x67A12C60, 0x8B052778, 0xDD38DC44, +0xEB01EA00, 0x2DB22CA2, 0x6DF66EF6, 0x6BF66CF6, +0x6AF6000B, 0x2FE62FD6, 0xE240DD36, 0x362266D1, +0x62638900, 0x3678672C, 0x7703DE38, 0x47212D61, +0x64E2D635, 0xA00E4721, 0x6562E100, 0x62537101, +0x74012450, 0x24204219, 0x45297401, 0x74012450, +0x24504519, 0x621C7401, 0x8BEE3273, 0x66E24200, +0x420061D1, 0x2118362C, 0x2E628F06, 0xDD1CD728, +0xE501E400, 0x2D522742, 0x000B6EF6, 0x2FD66DF6, +0x4F222FE6, 0xED0AEE01, 0x64E3BC86, 0xBC8B64E3, +0x62EC7E01, 0x8BF732D7, 0xBC8EEE01, 0x64E364E3, +0x7E01BC93, 0x32D762EC, 0x4F268BF7, 0x000B6EF6, +0xD1186DF6, 0xD418920D, 0x72122122, 0x2422D617, +0xD7177204, 0x72202622, 0x2722D116, 0x000B7230, +0x137A2122, 0x00203A4A, 0x002028FE, 0x001E1015, +0x00203A50, 0x001E1001, 0x00203A24, 0x001E1100, +0x00203A4E, 0x00203A3C, 0x001E1000, 0x00203A40, +0x00203A4C, 0x002027F2, 0x001E100C, 0x00203A38, +0x00203A54, 0x00203A58, 0x00203A5C, 0x00203A60, +0x00203A64, 0x00203A68, 0x4F222FE6, 0xD6707FFC, +0x88016060, 0xE2018951, 0x2620BFBB, 0xD56ED16D, +0xDE6E6010, 0x64E36552, 0x7402C840, 0x8D22D16C, +0xD26C7502, 0xE601D76C, 0xE7042722, 0x76016255, +0x626C2421, 0x8FF93273, 0xD4637402, 0x6242E601, +0x640D8528, 0x67494419, 0x275D657E, 0x81E4607C, +0xE417D562, 0x67557601, 0x3243626C, 0x8FF92171, +0xA0207102, 0xD25E0009, 0xE601D75B, 0xE7042722, +0x76016255, 0x626C2421, 0x8FF93273, 0xD4527402, +0x6242E601, 0x640D8528, 0x67494419, 0x275D657E, +0x81E4607C, 0xE417D553, 0x67557601, 0x3243626C, +0x8FF92171, 0x92897102, 0xD2462E21, 0x5E23D74E, +0x64F22FE2, 0x604365F2, 0x2700C980, 0xC9606043, +0x80716103, 0xC9036043, 0x80724519, 0x65F2605C, +0x817266F2, 0x46194629, 0x606C4529, 0x4018645C, +0x8173304C, 0x21185E23, 0x64F22FE2, 0x6E4C62F2, +0x602C4219, 0x66F262F2, 0x46294018, 0x461930EC, +0x42298174, 0x652C606C, 0x305C4018, 0x81758F07, +0x0009BC97, 0x2228620C, 0xA00A8908, 0x60130009, +0x8B038840, 0x0009B009, 0x0009A003, 0xE202D62F, +0x7F042622, 0x000B4F26, 0x4F226EF6, 0x8552D52A, +0x8830600D, 0x88318903, 0xA0348923, 0x85550009, +0xD428D727, 0x85532701, 0x610DD627, 0x24124118, +0x460BD426, 0xD7230009, 0xD226D425, 0x6572420B, +0xE230D120, 0x42286712, 0x2729E620, 0x37604628, +0xD6218B03, 0xA016E200, 0xD61F2622, 0xA012E202, +0xD1182622, 0x6212E530, 0xE6204528, 0x46282259, +0x89083260, 0xD41AD119, 0xE601D513, 0x2160450B, +0x472BD718, 0x4F264F26, 0x0009000B, 0x0000060A, +0x00203A6C, 0x001E1000, 0x00203A58, 0x00203E20, +0x00203E2C, 0x00203DC4, 0x00203A40, 0x00203DF4, +0x00203DF2, 0x00203DC6, 0x00203A24, 0x00203A50, +0x00203A3C, 0x00203A38, 0x002018C0, 0x00203B48, +0x00203B4C, 0x002018D0, 0x00203A54, 0x001E100B, +0x00203B60, 0x00114004, 0x4F222FE6, 0x84E9DE86, +0x2448640C, 0xB17B8901, 0xD2840009, 0x26686620, +0x60E08902, 0x2E00C9BF, 0x000B4F26, 0x000B6EF6, +0x2FE60009, 0xDE7E4F22, 0x60E0D67E, 0xCBC0D47E, +0x62602E00, 0xC803602C, 0x40218904, 0x70014021, +0x6603A002, 0x66034009, 0xD678616D, 0xE500A004, +0x75016262, 0x74042422, 0x3213625D, 0xD2748BF8, +0x0009420B, 0xC9BF84E2, 0x4F2680E2, 0x6EF6000B, +0x2FE62FD6, 0x7FFC4F22, 0x6260D66E, 0x89402228, +0xD565E100, 0x60502610, 0xCB40D46B, 0x2500440B, +0x8D052008, 0x62E06E03, 0x7104612C, 0x2F11A006, +0xD466D65E, 0xDD666760, 0x657C4D0B, 0xE23C6D1D, +0x8B033D27, 0xD264D463, 0x0009420B, 0x4D214D21, +0xA005D762, 0x66E6E400, 0x357C4508, 0x74012562, +0x35D3654D, 0xD75E8BF7, 0x6E72E003, 0x81E14018, +0x6E7260F1, 0x81E2700C, 0xD45A6172, 0xDD5A8113, +0x65724D0B, 0xD64AD259, 0x2212E101, 0xC93F6060, +0x7F042600, 0x6EF64F26, 0x6DF6000B, 0x2FC62FB6, +0x2FE62FD6, 0xD2524F22, 0x6B436E73, 0x420B6C53, +0x20086D63, 0x64038D1C, 0xE50ED13C, 0x32526210, +0x60C38916, 0x804124B0, 0x814160D3, 0xA007E500, +0x655D61BC, 0x00EC6053, 0x364C6653, 0x80647501, +0x3213625D, 0xD6308BF5, 0xC9BF6060, 0x2600A008, +0xD239D440, 0x6EF64F26, 0x6CF66DF6, 0x6BF6422B, +0x6EF64F26, 0x6CF66DF6, 0x6BF6000B, 0x2F962F86, +0x2FB62FA6, 0x2FD62FC6, 0x4F222FE6, 0xE1007FC4, +0x6513ECFF, 0x6B136CCD, 0xDE34D733, 0xEDFF64F3, +0xD833EA04, 0x6053655C, 0x027D4000, 0x32C0622D, +0x66038D0D, 0x09ED6063, 0x2491027D, 0x24217402, +0x698202ED, 0x3928622D, 0x74022892, 0x75017104, +0x6063625C, 0x07D532A2, 0x0EB58FE4, 0x2448641C, +0xE6808905, 0x67F3E5C5, 0xBF8F666C, 0x7F3C655C, +0x6EF64F26, 0x6CF66DF6, 0x6AF66BF6, 0x000B69F6, +0xD11C68F6, 0x6012D21C, 0xCB20E405, 0x2102E500, +0x000B2242, 0x00002252, 0x001E1017, 0x00203996, +0x001E1015, 0x001E10BF, 0x00117800, 0x001E10FC, +0x00200644, 0x0020399C, 0x00202A56, 0x00203B64, +0x002018D0, 0x00203B80, 0x002018C0, 0x0011788C, +0x00203998, 0x0020357C, 0x00201534, 0x001E2130, +0x00202A18, 0x00203B88, 0x002039FC, 0x00203A04, +0x00203DC0, 0x001C3500, 0x001D4004, 0xD564D163, +0xE400D764, 0x2142E20F, 0x17411154, 0xD5622722, +0x9669D762, 0x15412572, 0x96661562, 0xE6011565, +0xD55F1165, 0x666CE6F8, 0x25422542, 0x25422542, +0x25422542, 0x25622542, 0x7601E727, 0x67632572, +0x25627797, 0xE7042572, 0x2572E248, 0xE2192522, +0xE2702522, 0x25422542, 0x25422542, 0x25222542, +0x2522E20C, 0x25422542, 0x25422542, 0x25422542, +0x25422542, 0x000B154A, 0xE2081145, 0x0009422B, +0x2FE62FD6, 0x7FFC4F22, 0xC8206043, 0x6E438D02, +0x0009BE85, 0xC81060E3, 0xBE828901, 0x60E30009, +0x8901C840, 0x0009BEA4, 0xC80160E3, 0xDD3D8938, +0xC80260D0, 0x2F008D03, 0x460BD63B, 0x60F00009, +0x8902C804, 0x460BD639, 0x62F00009, 0xC8806023, +0x60D08902, 0x2D00C97F, 0xC8016023, 0xD6348906, +0x0009460B, 0x0009A007, 0x51630601, 0x8902C808, +0x460BD630, 0x60F00009, 0x8902C810, 0x420BD22E, +0xD52E0009, 0x88026052, 0xD22D8B03, 0xA005E604, +0x88012260, 0xD22A8B02, 0x2260E601, 0x2522E200, +0xC88060E3, 0xD227892D, 0x60E36E20, 0x8902C880, +0x420BD225, 0x60E30009, 0x8902C840, 0x420BD223, +0x60E30009, 0x8902C802, 0x420BD221, 0x60E30009, +0x890DC804, 0xDD20D11F, 0x0009410B, 0x0009BF11, +0x0009BF4C, 0xD51ED41D, 0x2470E708, 0x25D2BF85, +0xC80860E3, 0xD21B8905, 0x4F267F04, 0x422B6EF6, +0x7F046DF6, 0x6EF64F26, 0x6DF6000B, 0x001C581C, +0xA000A000, 0x001D0100, 0x001D4000, 0x00040021, +0x001C589C, 0x001E1021, 0x00201A46, 0x00201A68, +0x002020C8, 0x00201A80, 0x00201A8E, 0x00203A50, +0x001E100B, 0x001E1028, 0x00201AFA, 0x00201B06, +0x00201A96, 0x00201AB4, 0x12345678, 0x001E1000, +0x0010F100, 0x00201AE2, 0x644CD6A7, 0x000B346C, +0xD6A62450, 0x346C644C, 0x2450000B, 0x644CD6A4, +0x000B346C, 0x625C2450, 0x4208616D, 0x42084119, +0x42006019, 0x670E614C, 0xD49E321C, 0x4200207D, +0x324CC90F, 0x2200000B, 0x4208625C, 0x42004208, +0x324C644C, 0x4200D498, 0x000B324C, 0x2FE62260, +0x614C4F12, 0x4100D493, 0x6710314C, 0xE29F666D, +0x27294619, 0x6E536269, 0x672E6573, 0x4221227D, +0x42214221, 0x7601662C, 0xE4014608, 0x34E84608, +0x644C4600, 0x071A0467, 0x2150257B, 0x000B4F16, +0x4F226EF6, 0xD2857FE8, 0x88016021, 0xD2848B7B, +0x26686621, 0xD2838B77, 0x26686621, 0xE50F8B73, +0xE401BFA2, 0xBFA4E501, 0xE586E400, 0xE400655C, +0x2F50BFA4, 0xBFA1E401, 0xE602E506, 0x60634618, +0x81F2E401, 0x6543BF9F, 0xE40185F2, 0xBFAB6543, +0x85F26603, 0x6543E401, 0x6603BFB1, 0xE40265F0, +0x6053756C, 0x80F8BF80, 0xBF82E402, 0x84F8E512, +0x7090E402, 0x6503BF82, 0x4618E602, 0x81F66063, +0xBF80E402, 0x85F6E500, 0x6603E402, 0xE500BF8C, +0xE40285F6, 0xBF926603, 0xE5FEE500, 0xE010655C, +0xBF61E403, 0xE5130F54, 0xE40EBF63, 0x05FCE010, +0xBF63E40E, 0xE5007585, 0xBF64E403, 0xE500E640, +0xBF71E403, 0xE500E640, 0xBF78E403, 0xE5FFE640, +0xE014655C, 0xBF47E404, 0xE40F0F54, 0xE504BF49, +0x05FCE014, 0xBF49E40F, 0xE5017584, 0xBF4AE640, +0xE501E404, 0xBF57E640, 0xE501E404, 0xE404E640, +0xAF5C7F18, 0x7F184F26, 0x000B4F26, 0x4F220009, +0xD2427FF0, 0x88016021, 0xD2418B71, 0x26686621, +0xD2408B6D, 0x26686621, 0xE50F8B69, 0xE401BF1C, +0xBF1EE501, 0xE586E400, 0xE400655C, 0x2F50BF1E, +0xBF1BE401, 0xE401E506, 0xBF1C6543, 0xE401E640, +0xBF296543, 0xE401E640, 0xBF306543, 0x65F0E640, +0x756CE402, 0xBEFF6053, 0xE40280F4, 0xE512BF01, +0xE40284F4, 0xBF017090, 0xE6406503, 0xBF02E402, +0xE640E500, 0xBF0FE402, 0xE640E500, 0xBF16E402, +0xE5FEE500, 0x6053655C, 0xBEE5E403, 0xE51380F8, +0xE40EBEE7, 0xE40E84F8, 0xBEE77085, 0xE5006503, +0xBEE8E640, 0xE500E403, 0xBEF5E640, 0xE500E403, +0xBEFCE640, 0xE5FFE403, 0x6053655C, 0xBECBE404, +0xE40F80FC, 0xE504BECD, 0xE40F84FC, 0xBECD7083, +0xE5016503, 0xBECEE640, 0xE501E404, 0xBEDBE640, +0xE501E404, 0xE404E640, 0xAEE07F10, 0x7F104F26, +0x000B4F26, 0x00000009, 0x001E102F, 0x001E1080, +0x001E1090, 0x001E103F, 0x001E103E, 0x00203A4A, +0x00203A4C, 0x00203A4E, 0xD21DD11C, 0x66206010, +0x676C7001, 0x3700C90F, 0xE5008D13, 0x67106210, +0x7701622C, 0x64232170, 0xD6166010, 0x44084408, +0x3428C90F, 0x62602100, 0x7201D513, 0x44082620, +0x000B354C, 0xD10F6053, 0x25586510, 0xE6008D13, +0xD60DD40B, 0x655C6540, 0x47086753, 0x37584708, +0x47086540, 0x24507501, 0x367C6040, 0x2400C90F, +0x72FF6210, 0x000B2120, 0x00006063, 0x00203995, +0x00203994, 0x00203996, 0x002035BC, 0x7FFC4F22, +0xE680D1A8, 0x666C6212, 0xD2A72F22, 0x67F36563, +0x420B7542, 0x7F04E404, 0x000B4F26, 0xE6800009, +0xD2A1666C, 0xE7006563, 0x422B7540, 0xE6806473, +0xD29D666C, 0xE7006563, 0x422B7543, 0x2F866473, +0x2FA62F96, 0x2FC62FB6, 0x2FE62FD6, 0x7FC04F22, +0xDB97D296, 0x72012F22, 0xD1961F21, 0x66125211, +0x8B013620, 0x0009A0F9, 0xC9036061, 0x8B018801, +0x0009A0F3, 0xD290DC8F, 0x64C3420B, 0x6503D18F, +0x60111F02, 0x8B048801, 0x420BD28D, 0xAFE464C3, +0x54530009, 0x844CEE84, 0x890130E0, 0x0009A0C3, +0x6610D188, 0x6023626C, 0x8B718801, 0x6210D186, +0x89662228, 0xDA86D285, 0xE0036122, 0x64221112, +0x4018D881, 0xDD83E500, 0x814167A3, 0x77042850, +0x647266A2, 0x6ED3D580, 0x1F457E04, 0x65521F56, +0x64E368D2, 0x1F8874F8, 0x684369E2, 0x1F637894, +0x1F991F74, 0x62826142, 0xD779D978, 0x1F2BD679, +0x67726292, 0x1F1A6062, 0x2602CB20, 0xD176E600, +0xE5401F57, 0x1F7D1F2C, 0x76011F1E, 0x3253626D, +0x51F38BFB, 0x52F555F4, 0x25222A12, 0x55F757F6, +0x27525AF8, 0x5DF92DA2, 0x2ED251FB, 0xD56B5EFA, +0x54FC24E2, 0x281257FD, 0xD160D869, 0x25722942, +0x69126782, 0x1974D866, 0xDD666A12, 0x56FE60A1, +0x2A01CB01, 0xDA646412, 0xE9012842, 0x4A0B2D42, +0x52FE2692, 0xD661EE01, 0x22E24E18, 0x72016262, +0x60B22622, 0xCB01D14F, 0x2B02E202, 0x2120A03F, +0x8B3C2228, 0xE601D55A, 0x2160E700, 0xE01C2572, +0xC801004C, 0xD8578B0C, 0x1F8FD257, 0xE6002822, +0x7601E57D, 0x3253626C, 0x56FF8BFB, 0x2622D253, +0xE2FE69B2, 0x2B922929, 0x0A4CE01E, 0xE01F65F2, +0x014C25A0, 0x741057F1, 0xEA062710, 0xDD4CE600, +0x8446DE4C, 0x2D007601, 0x696C6844, 0x2E8039A3, +0x8FF67E01, 0xDE487D01, 0x2EA0EA94, 0xE1007E01, +0x7E0F2E10, 0xD12FE205, 0x64102E20, 0x6023624C, +0x89088801, 0x55F2D22A, 0x64C3420B, 0xEE01D132, +0xAF1A4E18, 0x55F221E2, 0x8553D13C, 0x620D6612, +0x89063262, 0xD63BD43A, 0xE801460B, 0xAF0CD73A, +0xD91F2782, 0x64C3490B, 0xEE01D127, 0xDA38D437, +0x4A0B4E18, 0xAF0021E2, 0x7F400009, 0x6EF64F26, +0x6CF66DF6, 0x6AF66BF6, 0x000B69F6, 0x4F2268F6, +0x85467FF4, 0x2F01E681, 0x666C8547, 0x854881F1, +0x81F2D209, 0x67F38542, 0x854381F3, 0x81F4E40C, +0x65636053, 0x420B81F5, 0x7F0C7540, 0x000B4F26, +0x00000009, 0x001C3D9C, 0x002023FC, 0x0011779A, +0x001C36F8, 0x002035B4, 0x002014A6, 0x00203A16, +0x002014D0, 0x002039A5, 0x002039A4, 0x002039A0, +0x001C3B9C, 0x001C3704, 0x001C3D98, 0x001C3BB4, +0x001C5960, 0x001C3500, 0x001C3D30, 0x001C8960, +0x0020358C, 0x001C3D00, 0x00201610, 0x00117730, +0x002039A8, 0x001C582C, 0x2000A000, 0x0000A000, +0x0011778C, 0x00117792, 0x00117788, 0x0020397C, +0x0020357C, 0x00201534, 0x001E2130, 0x00203DA0, +0x002018C0, 0x2F962F86, 0x2FB62FA6, 0x2FD62FC6, +0x4F222FE6, 0xD19B7FEC, 0x2F12E000, 0x6103D49A, +0x1F4281F2, 0xDD9ADA99, 0xD69A6813, 0xE0014808, +0x460BDE99, 0x38EC4800, 0x65A21F03, 0x352052A1, +0xA23E8B01, 0x60510009, 0x8801C903, 0xA2388B01, +0x52530009, 0x32E0DE91, 0xD9918B10, 0x64A3490B, +0x4B0BDB90, 0xDE906403, 0xD791D690, 0xEC01D591, +0x2E02E100, 0x271026C0, 0x2502AFDF, 0xC8018551, +0xA1578B01, 0x62510009, 0x4200622D, 0x5E53366A, +0x85E2226D, 0xC903642C, 0x85E36603, 0x6053650D, +0x40214021, 0x4500C93F, 0x322A6703, 0x6053252D, +0xC901D17F, 0x60106C03, 0x8801D97F, 0xDB7F8B05, +0x2120E200, 0xCB0160B2, 0xD17D2B02, 0x88016011, +0x65A28B0A, 0x8D042448, 0x9B9E6251, 0xA00322B9, +0x919B2521, 0x2521221B, 0x37B3EB10, 0x2448895E, +0xD4738B07, 0x22286241, 0x60638903, 0xA05781F8, +0xD5706473, 0x46084608, 0x85E26273, 0x46006B50, +0x362C4200, 0x2BB8C910, 0x8F1F6463, 0x26686603, +0xD2698911, 0x062D6043, 0x4119616D, 0x6B0E6019, +0x81F820BD, 0x880160C3, 0x646C8F2C, 0x880F6073, +0xA0278B1B, 0xD2610009, 0x052D6043, 0x4119615D, +0x670E6019, 0x645C207D, 0x81F8A01C, 0x890F2668, +0x6043D25B, 0x6B5D052D, 0x60B94B19, 0x201D610E, +0x60C381F8, 0x8F0D8801, 0x6473645C, 0xEC00A00A, +0x6043D254, 0x625D052D, 0x60294219, 0x207D670E, +0x81F8645C, 0x880285F8, 0x85E1890A, 0x8D07C820, +0xE6DC6203, 0x60232269, 0x81E1A002, 0x644CE4FF, +0x6210D149, 0x89012228, 0x644CE4FF, 0x654DEBFF, +0x35B06BBC, 0xDB368B2B, 0x64A34B0B, 0x410BD135, +0x54036403, 0x85446E03, 0xC948DB40, 0xDC408808, +0xBEAC8B01, 0x64B3E502, 0x65E34C0B, 0xDB3DEC01, +0xD13D2DC2, 0x621260B2, 0x72017001, 0x21228805, +0x2B028F08, 0x666CE680, 0x6563D238, 0x7549E700, +0x6473420B, 0xA030D436, 0x7FFF0009, 0x85E28000, +0x20B9EBFC, 0x610381E2, 0x942A85E3, 0x62032049, +0x450885F8, 0x81E2201B, 0xC90160C3, 0x40084018, +0x40084008, 0x4000225B, 0x6023220B, 0x85E481E3, +0x4118E108, 0x81E4201B, 0xE40262A2, 0x20B98521, +0x67A28121, 0xCB016071, 0x85F82701, 0x89033042, +0xECE785E2, 0x81E220C9, 0x490BD41E, 0xA03B0009, +0x7E030009, 0x001C3D30, 0x00203DAC, 0x0020358C, +0x001E212C, 0x00203470, 0x001C3D00, 0x00117780, +0x002014A6, 0x00201670, 0x0011770C, 0x002039A4, +0x002039A5, 0x002039A0, 0x002018C0, 0x001C36F8, +0x00203A1A, 0x00203DBC, 0x00203BA0, 0x00203C20, +0x00203CA0, 0x00203D20, 0x00203990, 0x00203584, +0x002014D0, 0x00203A1C, 0x00203A20, 0x002023FC, +0x00203DA4, 0x00203DA8, 0x602262F2, 0x40094019, +0xC90F4009, 0x8B0B880A, 0x60E2DE8C, 0x40094019, +0xC90F4009, 0x8B038808, 0xCB0160A2, 0x2802A006, +0x65E2DE87, 0x2E527501, 0x286266A2, 0x52F366F2, +0x2622AE83, 0xD2838551, 0xDE83C802, 0xA0958B01, +0x420B0009, 0x4E0B64A3, 0x5E036403, 0x85E46503, +0x4918E908, 0xD77D209B, 0xE04C81E4, 0xDC7C0B7E, +0x7B01D97C, 0x61C207B6, 0x71016690, 0x8D062668, +0xD4792C12, 0x420BD279, 0xA070EB01, 0x62512DB2, +0x4B18EB0F, 0x22B9E102, 0x32104118, 0x85518B0F, +0x2029E2FC, 0x60518151, 0xCB0172E0, 0x85E12501, +0x202994A3, 0x85E481E1, 0xA0522049, 0x675181E4, +0x4719677D, 0x667E6779, 0x7701276D, 0x6903607C, +0x88014918, 0x25918F3E, 0x6B12D161, 0x21B27B01, +0x660D85E3, 0x40216063, 0xC93F4021, 0x6C034600, +0x262D322A, 0xC8016063, 0xDB5ED15D, 0x967D8901, +0xE6002C6B, 0x666C67CD, 0x40006063, 0x622D021D, +0x8D0E3270, 0x60436403, 0xE9FF021D, 0x8B013290, +0x01C5A007, 0x626C7601, 0x3292E904, 0x646C8BEB, +0x60434400, 0xD15004BD, 0x0B457401, 0x669D6911, +0x89073670, 0x602D6211, 0x890388FF, 0xE201DB4B, +0x2B2021C1, 0xECFC8551, 0x815120C9, 0xCB016051, +0xDC472501, 0x64A34C0B, 0x51F366F2, 0x85EF2612, +0x54F2D244, 0x650D420B, 0x0009ADE7, 0xE500DC42, +0x420B2C52, 0x4E0B64A3, 0x54036403, 0x85446E03, +0x6703E908, 0x65034918, 0x27998541, 0xDB323790, +0x8F0BD932, 0x6013610D, 0x8B07C820, 0xC9486053, +0x8B038808, 0xE501BD4B, 0x0009A005, 0x2128D233, +0xBD448901, 0x64B3E500, 0x490B65E3, 0xADBCEC01, +0x85F22DC2, 0x7001EE04, 0x31E7610D, 0x8D0281F2, +0xADA97A08, 0x7F140009, 0x6EF64F26, 0x6CF66DF6, +0x6AF66BF6, 0x000B69F6, 0xF7FF68F6, 0x2FE68000, +0xD2234F22, 0x60E36E22, 0x8D02C840, 0xBBE522E2, +0xE2400009, 0x2E284218, 0xBBF08901, 0x60E30009, +0x8905C810, 0xD21CD41B, 0x0009420B, 0x0009BBEF, +0xC80560E3, 0xBD6D8901, 0x60E30009, 0x8902C802, +0xABEC4F26, 0x4F266EF6, 0x6EF6000B, 0x001C3D3C, +0x00117760, 0x002014A6, 0x00201670, 0x0020351C, +0x00203DC0, 0x00203990, 0x00203584, 0x002014D0, +0x002039FC, 0x00203A04, 0x002039F8, 0x002039FA, +0x00201534, 0x002018D0, 0x00203A1C, 0x00008000, +0x001C3510, 0x00203DB4, 0x002018C0, 0x89014F22, +0x611B600B, 0x611BB00A, 0x000B4F26, 0x600B600B, +0x611BA004, 0x8DF12107, 0x8BF84011, 0x620D2F26, +0x8F3E3020, 0x40180019, 0x8B0B3016, 0x31043104, +0x31043104, 0x31043104, 0x31043104, 0x412462F6, +0x601C000B, 0x41296219, 0x20084018, 0x31048926, +0x31043104, 0x31043104, 0x31043104, 0x31043104, +0x31043104, 0x31043104, 0x31043104, 0x61193104, +0x3204221D, 0x32043204, 0x32043204, 0x32043204, +0x32043204, 0x32043204, 0x32043204, 0x32043204, +0x212D3204, 0x601962F6, 0x4024000B, 0x000BE000, +0x621362F6, 0x41294228, 0x31044224, 0x31044224, +0x31044224, 0x31044224, 0x31044224, 0x31044224, +0x31044224, 0x31044224, 0x31044224, 0x31044224, +0x31044224, 0x31044224, 0x31044224, 0x31044224, +0x31044224, 0x31044224, 0x602D4224, 0x62F6000B, +0x080A0C0E, 0x00020406, 0x1A1C1E20, 0x12141618, +0x2E303234, 0x26282A2C, 0x3A3C3E40, 0x6C625648, +0x41112F26, 0xE2208F18, 0x890B3123, 0x321CD204, +0xD1026220, 0x412B312C, 0x00090009, 0x0020349A, +0x00203450, 0x000BE000, 0x400062F6, 0x40004000, +0x40004000, 0x40004000, 0x62F6000B, 0x40004000, +0x40004000, 0x40004000, 0x40184000, 0x62F6000B, +0x40004000, 0x40004000, 0x40004000, 0x40284000, +0x62F6000B, 0x40004000, 0x40184000, 0x000B4028, +0xC90F62F6, 0x40054005, 0x40054005, 0x62F6000B, +0x4005C907, 0x40054005, 0x62F6000B, 0x4005C903, +0x000B4005, 0xC90162F6, 0x000B4005, 0x000062F6, +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, 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, 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, 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, +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, 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, 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, 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, +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, 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, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x42707372, +0x3D206675, 0x554E203D, 0x202C4C4C, 0x6E49677A, +0x4E497274, 0x6D754E51, 0x0000003D, 0x61766E49, +0x2064696C, 0x72657375, 0x20726F20, 0x2079656B, +0x00214449, 0x6E6B6E55, 0x206E776F, 0x6D6D6F63, +0x3D646E61, 0x00000000, 0x203A3051, 0x00000020, +0x203A3151, 0x00000020, 0x203A3251, 0x00000020, +0x203A3351, 0x00000020, 0x203A3451, 0x00000020, +0x2B434741, 0x73696F4E, 0x61432065, 0x7262696C, +0x6F697461, 0x6166206E, 0x6F206C69, 0x6974206E, +0x0D0A656D, 0x00000000, 0x00000072, 0x00205220, +0x62735576, 0x7473725F, 0x00000A0D, 0x62735576, +0x7375735F, 0x646E6570, 0x00000A0D, 0x62735576, +0x7365725F, 0x000A0D6D, 0x00000044, 0x44387570, +0x72637365, 0x6F747069, 0x3D584572, 0x00000000, +0x00000047, 0x72746E49, 0x6D652051, 0x2C797470, +0x49677A20, 0x4972746E, 0x754E514E, 0x00003D6D, +0x654C7245, 0x0000006E, 0x20746F4E, 0x756F6E65, +0x49206867, 0x4220514E, 0x0A0D6675, 0x00000000, +0x000000FF, 0x00020001, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x010E010D, 0x00020003, 0x01090108, 0x0002010A, +0x02000003, 0x02020201, 0x02040203, 0x02060205, +0x02020200, 0x02040203, 0x020C020B, 0x020E020D, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x000000FF, 0x00020001, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x010E010D, 0x00020003, 0x01090108, 0x0002010A, +0x00030003, 0x02020201, 0x02040203, 0x02060205, +0x02020200, 0x02040203, 0x020C020B, 0x020E020D, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x010E010D, 0x00FF010F, 0x01090108, 0x010B010A, +0x0200010F, 0x02020201, 0x02040203, 0x02060205, +0x02020200, 0x02040203, 0x020C020B, 0x020E020D, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x010E010D, 0x00FF010F, 0x01090108, 0x010B010A, +0x010F010F, 0x02020201, 0x02040203, 0x02060205, +0x02020200, 0x02040203, 0x020C020B, 0x020E020D, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00205220, 0x00000046, 0x00000059, 0x73204142, +0x003D7165, 0x49544120, 0x0000204D, 0x00000000, +0x00000000, 0x002E0209, 0x80000101, 0x000409FA, +0x00FF0400, 0x05070000, 0x02000201, 0x82050700, +0x00020002, 0x03830507, 0x07010040, 0x40030405, +0x02090100, 0x0101002E, 0x09FA8000, 0x04000004, +0x000000FF, 0x02010507, 0x07000040, 0x40028205, +0x05070000, 0x00400383, 0x04050701, 0x00004002, +0x00000000, 0x00000000, 0x07090000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, }; + +const u32_t zcP2FwImageSize=15964; --- linux-2.6.28.orig/drivers/staging/otus/hal/hpusb.h +++ linux-2.6.28/drivers/staging/otus/hal/hpusb.h @@ -0,0 +1,437 @@ +/* + * Copyright (c) 2000-2005 ZyDAS Technology Corporation + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* Module Name : ud_defs.h */ +/* */ +/* Abstract */ +/* This module contains USB data structure definitions. */ +/* */ +/* NOTES */ +/* None */ +/* */ +/************************************************************************/ + +#ifndef _HPUSB_H +#define _HPUSB_H + +#define ZM_OTUS_ENABLE_RETRY_FREQ_CHANGE +#define ZM_BEACON_BUFFER_ADDRESS 0x117900 + +#define ZM_MAX_CMD_SIZE 64 +#define ZM_HAL_MAX_EEPROM_REQ 510 +#define ZM_HAL_MAX_EEPROM_PRQ 2 + +/* For USB STREAM mode */ +#ifdef ZM_DISABLE_AMSDU8K_SUPPORT +#define ZM_MAX_USB_IN_TRANSFER_SIZE 4096 +#else +#define ZM_MAX_USB_IN_TRANSFER_SIZE 8192 +#endif +#define ZM_USB_STREAM_MODE_TAG_LEN 4 +#define ZM_USB_STREAM_MODE_TAG 0x4e00 +#define ZM_USB_MAX_EPINT_BUFFER 64 + +struct zsCmdQ +{ + u16_t src; + u16_t cmdLen; + u8_t* buf; + u32_t cmd[ZM_MAX_CMD_SIZE/4]; +}; + +struct zsCommand +{ + u16_t delayWcmdCount; + u32_t delayWcmdAddr[(ZM_CMD_QUEUE_SIZE-4)/4]; + u32_t delayWcmdVal[(ZM_CMD_QUEUE_SIZE-4)/4]; +}; + +struct zsHalRxInfo +{ + u32_t currentRSSI[7]; /* RSSI combined */ + u32_t currentRxEVM[14]; + u32_t currentRxDataMT; + u32_t currentRxDataMCS; + u32_t currentRxDataBW; + u32_t currentRxDataSG; +}; + +struct zsHpPriv +{ + u16_t hwFrequency; + u8_t hwBw40; + u8_t hwExtOffset; + + u8_t disableDfsCh; + + u32_t halCapability; + + /* Fortunately the second loop can be disabled with a bit */ + /* called en_pd_dc_offset_thr */ + u8_t hwNotFirstInit; + + /* command queue */ + u16_t cmdHead; + u16_t cmdTail; +#ifdef ZM_XP_USB_MULTCMD + u16_t cmdSend; // Used for Mult send USB cmd +#endif + struct zsCmdQ cmdQ[ZM_CMD_QUEUE_SIZE]; + u16_t cmdPending; + struct zsCommand cmd; /* buffer for delayed commands */ + u8_t ledMode[2]; + u32_t ctlBusy; + u32_t extBusy; + + /* + * ANI & Radar support. + */ + u32_t procPhyErr; /* Process Phy errs */ + u8_t hasHwPhyCounters; /* Hardware has phy counters */ + u32_t aniPeriod; /* ani update list period */ + struct zsAniStats stats; /* various statistics */ + struct zsAniState *curani; /* cached last reference */ + struct zsAniState ani[50]; /* per-channel state */ + + /* + * Ani tables that change between the 5416 and 5312. + * These get set at attach time. + * XXX don't belong here + * XXX need better explanation + */ + s32_t totalSizeDesired[5]; + s32_t coarseHigh[5]; + s32_t coarseLow[5]; + s32_t firpwr[5]; + + /* + * ANI related PHY register value. + */ + u32_t regPHYDesiredSZ; + u32_t regPHYFindSig; + u32_t regPHYAgcCtl1; + u32_t regPHYSfcorr; + u32_t regPHYSfcorrLow; + u32_t regPHYTiming5; + u32_t regPHYCckDetect; + + u32_t eepromImage[1024]; + u32_t eepromImageIndex; + u32_t eepromImageRdReq; + + u8_t halReInit; + + u8_t OpFlags; + + u8_t tPow2xCck[4]; + u8_t tPow2x2g[4]; + u8_t tPow2x2g24HeavyClipOffset; + u8_t tPow2x2gHt20[8]; + u8_t tPow2x2gHt40[8]; + u8_t tPow2x5g[4]; + u8_t tPow2x5gHt20[8]; + u8_t tPow2x5gHt40[8]; + + /* hwBBHeavyClip : used compatibility */ + /* 0 : dongle not support. */ + /* !0: support heavy clip. */ + u8_t hwBBHeavyClip; + u8_t enableBBHeavyClip; /* 0=>force disable 1=>enable */ + u8_t doBBHeavyClip; /* set 1 if heavy clip need by each frequency switch */ + u32_t setValueHeavyClip; /* save setting value for heavy clip when completed routine */ + + /* + * Rxdata RSSI, EVM, Rate etc... + */ + struct zsHalRxInfo halRxInfo; + + u32_t usbSendBytes; + u32_t usbAcSendBytes[4]; + + u16_t aggMaxDurationBE; + u32_t aggPktNum; + + u16_t txop[4]; + u16_t cwmin[4]; + u16_t cwmax[4]; + u8_t strongRSSI; + u8_t rxStrongRSSI; + + u8_t slotType; //0->20us, 1=>9us + +#ifdef ZM_OTUS_RX_STREAM_MODE + u16_t usbRxRemainLen; + u16_t usbRxPktLen; + u16_t usbRxPadLen; + u16_t usbRxTransferLen; + zbuf_t *remainBuf; +#endif + + u8_t dot11Mode; + + u8_t ibssBcnEnabled; + u32_t ibssBcnInterval; + + // For re-issue the frequency change command + u32_t latestFrequency; + u8_t latestBw40; + u8_t latestExtOffset; + u8_t freqRetryCounter; + + u8_t recordFreqRetryCounter; + u8_t isSiteSurvey; + u8_t coldResetNeedFreq; + + u64_t camRollCallTable; + u8_t currentAckRtsTpc; + + /* #1 Save the initial value of the related RIFS register settings */ + //u32_t isInitialPhy; + u32_t initDesiredSigSize; + u32_t initAGC; + u32_t initAgcControl; + u32_t initSearchStartDelay; + u32_t initRIFSSearchParams; + u32_t initFastChannelChangeControl; + + /* Dynamic SIFS for retransmission event */ + u8_t retransmissionEvent; + u8_t latestSIFS; +}; + +extern u32_t zfHpLoadEEPROMFromFW(zdev_t* dev); + + +typedef u8_t A_UINT8; +typedef s8_t A_INT8; +typedef u16_t A_UINT16; +typedef u32_t A_UINT32; +#define __ATTRIB_PACK + +#pragma pack (push, 1) + +#define AR5416_EEP_VER 0xE +#define AR5416_EEP_VER_MINOR_MASK 0xFFF +#define AR5416_EEP_NO_BACK_VER 0x1 +#define AR5416_EEP_MINOR_VER_2 0x2 // Adds modal params txFrameToPaOn, txFrametoDataStart, ht40PowerInc +#define AR5416_EEP_MINOR_VER_3 0x3 // Adds modal params bswAtten, bswMargin, swSettle and base OpFlags for HT20/40 Disable + +// 16-bit offset location start of calibration struct +#define AR5416_EEP_START_LOC 256 +#define AR5416_NUM_5G_CAL_PIERS 8 +#define AR5416_NUM_2G_CAL_PIERS 4 +#define AR5416_NUM_5G_20_TARGET_POWERS 8 +#define AR5416_NUM_5G_40_TARGET_POWERS 8 +#define AR5416_NUM_2G_CCK_TARGET_POWERS 3 +#define AR5416_NUM_2G_20_TARGET_POWERS 4 +#define AR5416_NUM_2G_40_TARGET_POWERS 4 +#define AR5416_NUM_CTLS 24 +#define AR5416_NUM_BAND_EDGES 8 +#define AR5416_NUM_PD_GAINS 4 +#define AR5416_PD_GAINS_IN_MASK 4 +#define AR5416_PD_GAIN_ICEPTS 5 +#define AR5416_EEPROM_MODAL_SPURS 5 +#define AR5416_MAX_RATE_POWER 63 +#define AR5416_NUM_PDADC_VALUES 128 +#define AR5416_NUM_RATES 16 +#define AR5416_BCHAN_UNUSED 0xFF +#define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64 +#define AR5416_OPFLAGS_11A 0x01 +#define AR5416_OPFLAGS_11G 0x02 +#define AR5416_OPFLAGS_5G_HT40 0x04 +#define AR5416_OPFLAGS_2G_HT40 0x08 +#define AR5416_OPFLAGS_5G_HT20 0x10 +#define AR5416_OPFLAGS_2G_HT20 0x20 +#define AR5416_EEPMISC_BIG_ENDIAN 0x01 +#define FREQ2FBIN(x,y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5)) +#define AR5416_MAX_CHAINS 2 +#define AR5416_ANT_16S 25 + +#define AR5416_NUM_ANT_CHAIN_FIELDS 7 +#define AR5416_NUM_ANT_COMMON_FIELDS 4 +#define AR5416_SIZE_ANT_CHAIN_FIELD 3 +#define AR5416_SIZE_ANT_COMMON_FIELD 4 +#define AR5416_ANT_CHAIN_MASK 0x7 +#define AR5416_ANT_COMMON_MASK 0xf +#define AR5416_CHAIN_0_IDX 0 +#define AR5416_CHAIN_1_IDX 1 +#define AR5416_CHAIN_2_IDX 2 + + +/* Capabilities Enum */ +typedef enum { + EEPCAP_COMPRESS_DIS = 0x0001, + EEPCAP_AES_DIS = 0x0002, + EEPCAP_FASTFRAME_DIS = 0x0004, + EEPCAP_BURST_DIS = 0x0008, + EEPCAP_MAXQCU_M = 0x01F0, + EEPCAP_MAXQCU_S = 4, + EEPCAP_HEAVY_CLIP_EN = 0x0200, + EEPCAP_KC_ENTRIES_M = 0xF000, + EEPCAP_KC_ENTRIES_S = 12, +} EEPROM_CAPABILITIES; + +typedef enum Ar5416_Rates { + rate6mb, rate9mb, rate12mb, rate18mb, + rate24mb, rate36mb, rate48mb, rate54mb, + rate1l, rate2l, rate2s, rate5_5l, + rate5_5s, rate11l, rate11s, rateXr, + rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3, + rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7, + rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3, + rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7, + rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm, + Ar5416RateSize +} AR5416_RATES; + +typedef struct eepFlags { + A_UINT8 opFlags; + A_UINT8 eepMisc; +} __ATTRIB_PACK EEP_FLAGS; + +#define AR5416_CHECKSUM_LOCATION (AR5416_EEP_START_LOC + 1) +typedef struct BaseEepHeader { + A_UINT16 length; + A_UINT16 checksum; + A_UINT16 version; + EEP_FLAGS opCapFlags; + A_UINT16 regDmn[2]; + A_UINT8 macAddr[6]; + A_UINT8 rxMask; + A_UINT8 txMask; + A_UINT16 rfSilent; + A_UINT16 blueToothOptions; + A_UINT16 deviceCap; + A_UINT32 binBuildNumber; + A_UINT8 deviceType; + A_UINT8 futureBase[33]; +} __ATTRIB_PACK BASE_EEP_HEADER; // 64 B + +typedef struct spurChanStruct { + A_UINT16 spurChan; + A_UINT8 spurRangeLow; + A_UINT8 spurRangeHigh; +} __ATTRIB_PACK SPUR_CHAN; + +typedef struct ModalEepHeader { + A_UINT32 antCtrlChain[AR5416_MAX_CHAINS]; // 12 + A_UINT32 antCtrlCommon; // 4 + A_INT8 antennaGainCh[AR5416_MAX_CHAINS]; // 3 + A_UINT8 switchSettling; // 1 + A_UINT8 txRxAttenCh[AR5416_MAX_CHAINS]; // 3 + A_UINT8 rxTxMarginCh[AR5416_MAX_CHAINS]; // 3 + A_INT8 adcDesiredSize; // 1 + A_INT8 pgaDesiredSize; // 1 + A_UINT8 xlnaGainCh[AR5416_MAX_CHAINS]; // 3 + A_UINT8 txEndToXpaOff; // 1 + A_UINT8 txEndToRxOn; // 1 + A_UINT8 txFrameToXpaOn; // 1 + A_UINT8 thresh62; // 1 + A_INT8 noiseFloorThreshCh[AR5416_MAX_CHAINS]; // 3 + A_UINT8 xpdGain; // 1 + A_UINT8 xpd; // 1 + A_INT8 iqCalICh[AR5416_MAX_CHAINS]; // 1 + A_INT8 iqCalQCh[AR5416_MAX_CHAINS]; // 1 + A_UINT8 pdGainOverlap; // 1 + A_UINT8 ob; // 1 + A_UINT8 db; // 1 + A_UINT8 xpaBiasLvl; // 1 + A_UINT8 pwrDecreaseFor2Chain; // 1 + A_UINT8 pwrDecreaseFor3Chain; // 1 -> 48 B + A_UINT8 txFrameToDataStart; // 1 + A_UINT8 txFrameToPaOn; // 1 + A_UINT8 ht40PowerIncForPdadc; // 1 + A_UINT8 bswAtten[AR5416_MAX_CHAINS]; // 3 + A_UINT8 bswMargin[AR5416_MAX_CHAINS]; // 3 + A_UINT8 swSettleHt40; // 1 + A_UINT8 futureModal[22]; // + SPUR_CHAN spurChans[AR5416_EEPROM_MODAL_SPURS]; // 20 B +} __ATTRIB_PACK MODAL_EEP_HEADER; // == 100 B + +typedef struct calDataPerFreq { + A_UINT8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; + A_UINT8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; +} __ATTRIB_PACK CAL_DATA_PER_FREQ; + +typedef struct CalTargetPowerLegacy { + A_UINT8 bChannel; + A_UINT8 tPow2x[4]; +} __ATTRIB_PACK CAL_TARGET_POWER_LEG; + +typedef struct CalTargetPowerHt { + A_UINT8 bChannel; + A_UINT8 tPow2x[8]; +} __ATTRIB_PACK CAL_TARGET_POWER_HT; + +#if defined(ARCH_BIG_ENDIAN) || defined(BIG_ENDIAN) +typedef struct CalCtlEdges { + A_UINT8 bChannel; + A_UINT8 flag :2, + tPower :6; +} __ATTRIB_PACK CAL_CTL_EDGES; +#else +typedef struct CalCtlEdges { + A_UINT8 bChannel; + A_UINT8 tPower :6, + flag :2; +} __ATTRIB_PACK CAL_CTL_EDGES; +#endif + +typedef struct CalCtlData { + CAL_CTL_EDGES ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES]; +} __ATTRIB_PACK CAL_CTL_DATA; + +typedef struct ar5416Eeprom { + BASE_EEP_HEADER baseEepHeader; // 64 B + A_UINT8 custData[64]; // 64 B + MODAL_EEP_HEADER modalHeader[2]; // 200 B + A_UINT8 calFreqPier5G[AR5416_NUM_5G_CAL_PIERS]; + A_UINT8 calFreqPier2G[AR5416_NUM_2G_CAL_PIERS]; + CAL_DATA_PER_FREQ calPierData5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS]; + CAL_DATA_PER_FREQ calPierData2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS]; + CAL_TARGET_POWER_LEG calTargetPower5G[AR5416_NUM_5G_20_TARGET_POWERS]; + CAL_TARGET_POWER_HT calTargetPower5GHT20[AR5416_NUM_5G_20_TARGET_POWERS]; + CAL_TARGET_POWER_HT calTargetPower5GHT40[AR5416_NUM_5G_40_TARGET_POWERS]; + CAL_TARGET_POWER_LEG calTargetPowerCck[AR5416_NUM_2G_CCK_TARGET_POWERS]; + CAL_TARGET_POWER_LEG calTargetPower2G[AR5416_NUM_2G_20_TARGET_POWERS]; + CAL_TARGET_POWER_HT calTargetPower2GHT20[AR5416_NUM_2G_20_TARGET_POWERS]; + CAL_TARGET_POWER_HT calTargetPower2GHT40[AR5416_NUM_2G_40_TARGET_POWERS]; + A_UINT8 ctlIndex[AR5416_NUM_CTLS]; + CAL_CTL_DATA ctlData[AR5416_NUM_CTLS]; + A_UINT8 padding; +} __ATTRIB_PACK AR5416_EEPROM; + +#pragma pack (pop) + +typedef enum ConformanceTestLimits { + FCC = 0x10, + MKK = 0x40, + ETSI = 0x30, + SD_NO_CTL = 0xE0, + NO_CTL = 0xFF, + CTL_MODE_M = 0xF, + CTL_11A = 0, + CTL_11B = 1, + CTL_11G = 2, + CTL_TURBO = 3, + CTL_108G = 4, + CTL_2GHT20 = 5, + CTL_5GHT20 = 6, + CTL_2GHT40 = 7, + CTL_5GHT40 = 8, +} ATH_CTLS; + +#endif /* #ifndef _HPUSB_H */ --- linux-2.6.28.orig/drivers/staging/otus/hal/otus.ini +++ linux-2.6.28/drivers/staging/otus/hal/otus.ini @@ -0,0 +1,414 @@ +/* 8602 : update mismatch register between NDIS and ART */ +static const u32_t ar5416Modes[][6] = { +/* Register A-20 A-20/40 G-20/40 G-20 G-Turbo */ + {0x9800, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0}, + {0x9804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0}, + {0x9808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x980c, 0xad848e19, 0xad848e19, 0xad848e19, 0xad848e19, 0}, + {0x9810, 0x7d14e000, 0x7d14e000, 0x7d14e000, 0x7d14e000, 0}, + {0x9814, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, 0}, + {0x9818, 0x00000090, 0x00000090, 0x00000090, 0x00000090, 0}, + {0x981c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0}, + {0x9824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0}, + {0x9828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0}, + {0x982c, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, 0}, + {0x9830, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0}, + {0x9838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0}, + {0x983c, 0x00200400, 0x00200400, 0x00200400, 0x00200400, 0}, + {0x9840, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e, 0}, + {0x9844, 0x1372161e, 0x13721c1e, 0x13721c24, 0x137216a4, 0}, + {0x9848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0}, + {0x984c, 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c, 0}, + {0x9850, 0x6c48b4e4, 0x6c48b4e4, 0x6c48b0e4, 0x6c48b0e4, 0}, + {0x9854, 0x00000859, 0x00000859, 0x00000859, 0x00000859, 0}, + {0x9858, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0}, + {0x985c, 0x31395c5e, 0x31395c5e, 0x31395c5e, 0x31395c5e, 0}, + {0x9860, 0x0004dd10, 0x0004dd10, 0x0004dd20, 0x0004dd20, 0}, + {0x9868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0}, + {0x986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0}, + {0x9900, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9904, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9908, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x990c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0}, + {0x9918, 0x00000118, 0x00000230, 0x00000268, 0x00000134, 0}, + {0x991c, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff, 0}, + {0x9920, 0x0510081c, 0x0510081c, 0x0510001c, 0x0510001c, 0}, + {0x9924, 0xd0058a15, 0xd0058a15, 0xd0058a15, 0xd0058a15, 0}, + {0x9928, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0}, + {0x992c, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0}, + {0x9934, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0}, + {0x9938, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0}, + {0x993c, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, 0}, + {0x9944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0}, + {0x9948, 0x9280b212, 0x9280b212, 0x9280b212, 0x9280b212, 0}, + {0x994c, 0x00020028, 0x00020028, 0x00020028, 0x00020028, 0}, + {0x9954, 0x5d50e188, 0x5d50e188, 0x5d50e188, 0x5d50e188, 0}, + {0x9958, 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff, 0}, + {0x9960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0}, + {0x9964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0}, + {0x9970, 0x190fb515, 0x190fb515, 0x190fb515, 0x190fb515, 0}, + {0x9974, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9978, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0}, + {0x997c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9980, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9984, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9988, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x998c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9990, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9994, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9998, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x999c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x99a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x99a4, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0}, + {0x99a8, 0x001fff00, 0x001fff00, 0x001fff00, 0x001fff00, 0}, + {0x99ac, 0x006f00c4, 0x006f00c4, 0x006f00c4, 0x006f00c4, 0}, + {0x99b0, 0x03051000, 0x03051000, 0x03051000, 0x03051000, 0}, + {0x99b4, 0x00000820, 0x00000820, 0x00000820, 0x00000820, 0}, + {0x99c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0}, + {0x99c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0}, + {0x99c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0}, + {0x99cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0}, + {0x99d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0}, + {0x99d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x99d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x99dc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x99e0, 0x00000200, 0x00000200, 0x00000200, 0x00000200, 0}, + {0x99e4, 0x64646464, 0x64646464, 0x64646464, 0x64646464, 0}, + {0x99e8, 0x3c787878, 0x3c787878, 0x3c787878, 0x3c787878, 0}, + {0x99ec, 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa, 0}, + {0x99f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x99fc, 0x00001042, 0x00001042, 0x00001042, 0x00001042, 0}, + {0x9a00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9a04, 0x00000040, 0x00000040, 0x00000040, 0x00000040, 0}, + {0x9a08, 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0}, + {0x9a0c, 0x000001a1, 0x000001a1, 0x00000141, 0x00000141, 0}, + {0x9a10, 0x000001e1, 0x000001e1, 0x00000181, 0x00000181, 0}, + {0x9a14, 0x00000021, 0x00000021, 0x000001c1, 0x000001c1, 0}, + {0x9a18, 0x00000061, 0x00000061, 0x00000001, 0x00000001, 0}, + {0x9a1c, 0x00000168, 0x00000168, 0x00000041, 0x00000041, 0}, + {0x9a20, 0x000001a8, 0x000001a8, 0x000001a8, 0x000001a8, 0}, + {0x9a24, 0x000001e8, 0x000001e8, 0x000001e8, 0x000001e8, 0}, + {0x9a28, 0x00000028, 0x00000028, 0x00000028, 0x00000028, 0}, + {0x9a2c, 0x00000068, 0x00000068, 0x00000068, 0x00000068, 0}, + {0x9a30, 0x00000189, 0x00000189, 0x000000a8, 0x000000a8, 0}, + {0x9a34, 0x000001c9, 0x000001c9, 0x00000169, 0x00000169, 0}, + {0x9a38, 0x00000009, 0x00000009, 0x000001a9, 0x000001a9, 0}, + {0x9a3c, 0x00000049, 0x00000049, 0x000001e9, 0x000001e9, 0}, + {0x9a40, 0x00000089, 0x00000089, 0x00000029, 0x00000029, 0}, + {0x9a44, 0x00000170, 0x00000170, 0x00000069, 0x00000069, 0}, + {0x9a48, 0x000001b0, 0x000001b0, 0x00000190, 0x00000190, 0}, + {0x9a4c, 0x000001f0, 0x000001f0, 0x000001d0, 0x000001d0, 0}, + {0x9a50, 0x00000030, 0x00000030, 0x00000010, 0x00000010, 0}, + {0x9a54, 0x00000070, 0x00000070, 0x00000050, 0x00000050, 0}, + {0x9a58, 0x00000191, 0x00000191, 0x00000090, 0x00000090, 0}, + {0x9a5c, 0x000001d1, 0x000001d1, 0x00000151, 0x00000151, 0}, + {0x9a60, 0x00000011, 0x00000011, 0x00000191, 0x00000191, 0}, + {0x9a64, 0x00000051, 0x00000051, 0x000001d1, 0x000001d1, 0}, + {0x9a68, 0x00000091, 0x00000091, 0x00000011, 0x00000011, 0}, + {0x9a6c, 0x000001b8, 0x000001b8, 0x00000051, 0x00000051, 0}, + {0x9a70, 0x000001f8, 0x000001f8, 0x00000198, 0x00000198, 0}, + {0x9a74, 0x00000038, 0x00000038, 0x000001d8, 0x000001d8, 0}, + {0x9a78, 0x00000078, 0x00000078, 0x00000018, 0x00000018, 0}, + {0x9a7c, 0x00000199, 0x00000199, 0x00000058, 0x00000058, 0}, + {0x9a80, 0x000001d9, 0x000001d9, 0x00000098, 0x00000098, 0}, + {0x9a84, 0x00000019, 0x00000019, 0x00000159, 0x00000159, 0}, + {0x9a88, 0x00000059, 0x00000059, 0x00000199, 0x00000199, 0}, + {0x9a8c, 0x00000099, 0x00000099, 0x000001d9, 0x000001d9, 0}, + {0x9a90, 0x000000d9, 0x000000d9, 0x00000019, 0x00000019, 0}, + {0x9a94, 0x000000f9, 0x000000f9, 0x00000059, 0x00000059, 0}, + {0x9a98, 0x000000f9, 0x000000f9, 0x00000099, 0x00000099, 0}, + {0x9a9c, 0x000000f9, 0x000000f9, 0x000000d9, 0x000000d9, 0}, + {0x9aa0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0}, + {0x9aa4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0}, + {0x9aa8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0}, + {0x9aac, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0}, + {0x9ab0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0}, + {0x9ab4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0}, + {0x9ab8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0}, + {0x9abc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0}, + {0x9ac0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0}, + {0x9ac4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0}, + {0x9ac8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0}, + {0x9acc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0}, + {0x9ad0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0}, + {0x9ad4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0}, + {0x9ad8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0}, + {0x9adc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0}, + {0x9ae0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0}, + {0x9ae4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0}, + {0x9ae8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0}, + {0x9aec, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0}, + {0x9af0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0}, + {0x9af4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0}, + {0x9af8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0}, + {0x9afc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0}, + {0x9b00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9b04, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0}, + {0x9b08, 0x00000002, 0x00000002, 0x00000002, 0x00000002, 0}, + {0x9b0c, 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0}, + {0x9b10, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0}, + {0x9b14, 0x00000005, 0x00000005, 0x00000005, 0x00000005, 0}, + {0x9b18, 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0}, + {0x9b1c, 0x00000009, 0x00000009, 0x00000009, 0x00000009, 0}, + {0x9b20, 0x0000000a, 0x0000000a, 0x0000000a, 0x0000000a, 0}, + {0x9b24, 0x0000000b, 0x0000000b, 0x0000000b, 0x0000000b, 0}, + {0x9b28, 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c, 0}, + {0x9b2c, 0x0000000d, 0x0000000d, 0x0000000d, 0x0000000d, 0}, + {0x9b30, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0}, + {0x9b34, 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0}, + {0x9b38, 0x00000012, 0x00000012, 0x00000012, 0x00000012, 0}, + {0x9b3c, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0}, + {0x9b40, 0x00000014, 0x00000014, 0x00000014, 0x00000014, 0}, + {0x9b44, 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0}, + {0x9b48, 0x00000018, 0x00000018, 0x00000018, 0x00000018, 0}, + {0x9b4c, 0x00000019, 0x00000019, 0x00000019, 0x00000019, 0}, + {0x9b50, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0}, + {0x9b54, 0x0000001b, 0x0000001b, 0x0000001b, 0x0000001b, 0}, + {0x9b58, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, 0}, + {0x9b5c, 0x0000001d, 0x0000001d, 0x0000001d, 0x0000001d, 0}, + {0x9b60, 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0}, + {0x9b64, 0x00000021, 0x00000021, 0x00000021, 0x00000021, 0}, + {0x9b68, 0x00000022, 0x00000022, 0x00000022, 0x00000022, 0}, + {0x9b6c, 0x00000023, 0x00000023, 0x00000023, 0x00000023, 0}, + {0x9b70, 0x00000024, 0x00000024, 0x00000024, 0x00000024, 0}, + {0x9b74, 0x00000025, 0x00000025, 0x00000025, 0x00000025, 0}, + {0x9b78, 0x00000028, 0x00000028, 0x00000028, 0x00000028, 0}, + {0x9b7c, 0x00000029, 0x00000029, 0x00000029, 0x00000029, 0}, + {0x9b80, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a, 0}, + {0x9b84, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, 0}, + {0x9b88, 0x0000002c, 0x0000002c, 0x0000002c, 0x0000002c, 0}, + {0x9b8c, 0x0000002d, 0x0000002d, 0x0000002d, 0x0000002d, 0}, + {0x9b90, 0x00000030, 0x00000030, 0x00000030, 0x00000030, 0}, + {0x9b94, 0x00000031, 0x00000031, 0x00000031, 0x00000031, 0}, + {0x9b98, 0x00000032, 0x00000032, 0x00000032, 0x00000032, 0}, + {0x9b9c, 0x00000033, 0x00000033, 0x00000033, 0x00000033, 0}, + {0x9ba0, 0x00000034, 0x00000034, 0x00000034, 0x00000034, 0}, + {0x9ba4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0}, + {0x9ba8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0}, + {0x9bac, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0}, + {0x9bb0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0}, + {0x9bb4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0}, + {0x9bb8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0}, + {0x9bbc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0}, + {0x9bc0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0}, + {0x9bc4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0}, + {0x9bc8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0}, + {0x9bcc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0}, + {0x9bd0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0}, + {0x9bd4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0}, + {0x9bd8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0}, + {0x9bdc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0}, + {0x9be0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0}, + {0x9be4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0}, + {0x9be8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0}, + {0x9bec, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0}, + {0x9bf0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0}, + {0x9bf4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, 0}, + {0x9bf8, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0}, + {0x9bfc, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0}, + {0x9c00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9c0c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9c10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9c14, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9c18, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9c1c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9c20, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9c24, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9c28, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9c2c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9c30, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9c34, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9c38, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9c3c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9cf0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9cf4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9cf8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0x9cfc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0xa200, 0x00000008, 0x00000008, 0x0000000e, 0x0000000e, 0}, + {0xa204, 0x00000440, 0x00000440, 0x00000440, 0x00000440, 0}, + {0xa208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0}, + {0xa20c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, 0}, + {0xa210, 0x40806333, 0x40806333, 0x40806333, 0x40806333, 0}, + {0xa214, 0x00106c10, 0x00106c10, 0x00106c10, 0x00106c10, 0}, + {0xa218, 0x009c4060, 0x009c4060, 0x009c4060, 0x009c4060, 0}, + {0xa21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0}, + {0xa220, 0x018830c6, 0x018830c6, 0x018830c6, 0x018830c6, 0}, + {0xa224, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0}, + {0xa228, 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5, 0}, + {0xa22c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0xa230, 0x00000108, 0x00000210, 0x00000210, 0x00000108, 0}, + {0xa234, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0}, + {0xa238, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0}, + {0xa23c, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, 0}, + {0xa240, 0x38490a20, 0x38490a20, 0x38490a20, 0x38490a20, 0}, + {0xa244, 0x00007bb6, 0x00007bb6, 0x00007bb6, 0x00007bb6, 0}, + {0xa248, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, 0}, + {0xa24c, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0}, + {0xa250, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, 0}, + {0xa254, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0xa258, 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380, 0}, + {0xa25c, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0}, + {0xa260, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, 0}, + {0xa264, 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11, 0}, + {0xa268, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0xa26c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, 0}, + {0xa274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0}, + {0xa278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0}, + {0xa27c, 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce, 0}, + {0xa300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0}, + {0xa304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0}, + {0xa308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0}, + {0xa30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0}, + {0xa310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0}, + {0xa314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0}, + {0xa318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0}, + {0xa31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0}, + {0xa320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0}, + {0xa324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0}, + {0xa328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0}, + {0xa32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0xa330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0xa334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0xa338, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0xa33c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0xa340, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0xa344, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0xa348, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0}, + {0xa34c, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0}, + {0xa350, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0}, + {0xa354, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0}, + {0xa358, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0}, + {0xa388, 0x08000000, 0x08000000, 0x08000000, 0x08000000, 0}, + {0xa38c, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0}, + {0xa390, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0}, + {0xa394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0}, + {0xa398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, 0}, + {0xa39c, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0}, + {0xa3a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0xa3a4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0xa3a8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0xa3ac, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0xa3b0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0xa3b4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0xa3b8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0xa3bc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0xa3c0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0xa3c4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0xa3c8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0xa3cc, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0}, + {0xa3d0, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0}, + {0xa3d4, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0}, + {0xa3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0}, + {0xa3dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0}, + {0xa3e0, 0x000000c0, 0x000000c0, 0x000000c0, 0x000000c0, 0}, + {0xa848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, 0}, + {0xa920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, 0}, + {0xa960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0}, + {0xb20c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, 0}, + {0xb26c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, 0}, + {0xb848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, 0}, + {0xb920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, 0}, + {0xb960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0}, + {0xc20c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, 0}, + {0xc26c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, 0}, + //{0xc864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0}, + {0xc864, 0x0001c600, 0x0001c600, 0x0001c600, 0x0001c600, 0}, + {0xc95c, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, 0}, + {0xc968, 0x000003ce, 0x000003ce, 0x000003ce, 0x000003ce, 0}, + {0xc9bc, 0x00181400, 0x00181400, 0x00181400, 0x00181400, 0}, + {0xd270, 0x00820820, 0x00820820, 0x00820820, 0x00820820, 0}, + {0xd35c, 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f, 0}, + {0xd360, 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207, 0}, + {0xd364, 0x17601685, 0x17601685, 0x17601685, 0x17601685, 0}, + {0xd368, 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104, 0}, + {0xd36c, 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03, 0}, + {0xd370, 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883, 0}, + {0xd374, 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803, 0}, + {0xd378, 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682, 0}, + {0xd37c, 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482, 0}, + {0xd380, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0}, + {0xd384, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0} +}; + + +static const u32_t otusBank[][3] = { + //# bank 0 + {0x98b0, 0x1e5795e5, 0x1e5795e5}, + {0x98e0, 0x02008020, 0x02008020}, + //# bank 1 + {0x98b0, 0x02108421, 0x02108421}, + {0x98ec, 0x00000008, 0x00000008}, + //# bank 2 + {0x98b0, 0x0e73ff17, 0x0e73ff17}, + {0x98e0, 0x00000420, 0x00000420}, + //# bank 3 + {0x98f0, 0x01400018, 0x01c00018}, + //# bank 4 + {0x98b0, 0x000001a1, 0x000001a1}, + {0x98e8, 0x00000001, 0x00000001}, + //# bank 5 + {0x98b0, 0x00000013, 0x00000013}, + {0x98e4, 0x00000002, 0x00000002}, + //# bank 6 + {0x98b0, 0x00000000, 0x00000000}, + {0x98b0, 0x00000000, 0x00000000}, + {0x98b0, 0x00000000, 0x00000000}, + {0x98b0, 0x00000000, 0x00000000}, + {0x98b0, 0x00000000, 0x00000000}, + {0x98b0, 0x00004000, 0x00004000}, + {0x98b0, 0x00006c00, 0x00006c00}, + {0x98b0, 0x00002c00, 0x00002c00}, + {0x98b0, 0x00004800, 0x00004800}, + {0x98b0, 0x00004000, 0x00004000}, + {0x98b0, 0x00006000, 0x00006000}, + {0x98b0, 0x00001000, 0x00001000}, + {0x98b0, 0x00004000, 0x00004000}, + {0x98b0, 0x00007c00, 0x00007c00}, + {0x98b0, 0x00007c00, 0x00007c00}, + {0x98b0, 0x00007c00, 0x00007c00}, + {0x98b0, 0x00007c00, 0x00007c00}, + {0x98b0, 0x00007c00, 0x00007c00}, + {0x98b0, 0x00087c00, 0x00087c00}, + {0x98b0, 0x00007c00, 0x00007c00}, + {0x98b0, 0x00005400, 0x00005400}, + {0x98b0, 0x00000c00, 0x00000c00}, + {0x98b0, 0x00001800, 0x00001800}, + {0x98b0, 0x00007c00, 0x00007c00}, + {0x98b0, 0x00006c00, 0x00006c00}, + {0x98b0, 0x00006c00, 0x00006c00}, + {0x98b0, 0x00007c00, 0x00007c00}, + {0x98b0, 0x00002c00, 0x00002c00}, + {0x98b0, 0x00003c00, 0x00003c00}, + {0x98b0, 0x00003800, 0x00003800}, + {0x98b0, 0x00001c00, 0x00001c00}, + {0x98b0, 0x00000800, 0x00000800}, + {0x98b0, 0x00000408, 0x00000408}, + {0x98b0, 0x00004c15, 0x00004c15}, + {0x98b0, 0x00004188, 0x00004188}, + {0x98b0, 0x0000201e, 0x0000201e}, + {0x98b0, 0x00010408, 0x00010408}, + {0x98b0, 0x00000801, 0x00000801}, + {0x98b0, 0x00000c08, 0x00000c08}, + {0x98b0, 0x0000181e, 0x0000181e}, + {0x98b0, 0x00001016, 0x00001016}, + {0x98b0, 0x00002800, 0x00002800}, + {0x98b0, 0x00004010, 0x00004010}, + {0x98b0, 0x0000081c, 0x0000081c}, + {0x98b0, 0x00000115, 0x00000115}, + {0x98b0, 0x00000015, 0x00000015}, + {0x98b0, 0x00000066, 0x00000066}, + {0x98b0, 0x0000001c, 0x0000001c}, + {0x98b0, 0x00000000, 0x00000000}, + {0x98b0, 0x00000004, 0x00000004}, + {0x98b0, 0x00000015, 0x00000015}, + {0x98b0, 0x0000001f, 0x0000001f}, + {0x98e0, 0x00000000, 0x00000400}, + //# bank 7 + {0x98b0, 0x000000a0, 0x000000a0}, + {0x98b0, 0x00000000, 0x00000000}, + {0x98b0, 0x00000040, 0x00000040}, + {0x98f0, 0x0000001c, 0x0000001c} +}; --- linux-2.6.28.orig/drivers/staging/otus/hal/hpfwu_txstream.c +++ linux-2.6.28/drivers/staging/otus/hal/hpfwu_txstream.c @@ -0,0 +1,1017 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "cprecomp.h" + +const u32_t zcFwImage[] = { +0x0009000B, 0x4F222FE6, 0xDE947FFC, 0xE114D594, +0x1E13D494, 0x67521E4C, 0xD494D693, 0x37402769, +0x62528F06, 0x7201D692, 0x60602522, 0x2600C93F, +0xD7906152, 0x2512611D, 0x264B6652, 0x2562470B, +0x0009B017, 0xE60095AC, 0xC84060E2, 0x2F028F03, +0x8FF93652, 0xD4887601, 0x4E0BDE88, 0xD4880009, +0x00094E0B, 0x4E0BD487, 0x7F040009, 0xA0524F26, +0x4F226EF6, 0x410BD184, 0xD4840009, 0x0009440B, +0x450BD583, 0xD7830009, 0xD283E1FF, 0x2712611D, +0xD4825029, 0xE1FFCB01, 0x1209E501, 0x12112212, +0xE7202452, 0x4718D57E, 0x2572D27E, 0xD17EE700, +0xD67FD47E, 0xE2012270, 0x24702172, 0xD67D2620, +0x2641E4FF, 0xD57CE600, 0x666DE104, 0x76016063, +0x4000626D, 0x8FF83212, 0xD5780545, 0x2520E201, +0xD278D777, 0xE480E100, 0x22122710, 0x6613D576, +0x666D644C, 0x76046763, 0x375C626D, 0x8FF83243, +0xD5722712, 0xD273D772, 0xE400E101, 0x27102511, +0x000B4F26, 0x7FCC2242, 0xD170D56F, 0xD271DB70, +0x1F51D471, 0xD6717508, 0x1F12D771, 0x1F55710C, +0x1FB975FC, 0x72041F2A, 0x1F13EB10, 0x1F561F44, +0x1F781F67, 0xD86B1F2B, 0xDD6CD96B, 0xDC6CEA00, +0xD26DDE6C, 0x89003A22, 0xD15D7A01, 0x88016010, +0x56F88B03, 0x4218E201, 0xD1682622, 0x0009410B, +0x440BD467, 0xD5670009, 0x0009450B, 0x6010D150, +0x8B108801, 0xE650D14F, 0x46186212, 0x8B083266, +0x56F9D14B, 0x2120E200, 0xCB016062, 0x2602A003, +0x72012710, 0x60822122, 0x89098801, 0xE2C8D15A, +0x622C6612, 0x89033626, 0x6010D158, 0x8BC88801, +0x51F66792, 0x217252F5, 0xD6555191, 0x55FA2212, +0x52FB6462, 0x55612542, 0x2252E400, 0x61436643, +0x05DE6013, 0x36CC4608, 0x07DE2652, 0xC9036071, +0x8B028801, 0x720162E2, 0x74012E22, 0x36B3664C, +0x71048FEE, 0x66C2D147, 0x45286512, 0x265B4518, +0x60822C62, 0x89018801, 0x0009A168, 0x6272D742, +0x8B132228, 0xD42BD741, 0x6772D541, 0x51536242, +0x312C327C, 0x24222228, 0x15138D05, 0x6262D63D, +0xB1627201, 0xD6232622, 0x2622E200, 0x52916692, +0x8B013620, 0x0009A144, 0x6061A06E, 0x001C001C, +0x001D4020, 0x0000B38E, 0xFFFF0000, 0x12340000, +0x001E1015, 0x00201274, 0x002039F4, 0x002018A2, +0x00203A00, 0x00203A18, 0x00201860, 0x0020196C, +0x00201288, 0x001C3510, 0x001C3624, 0x001E212C, +0x002038F4, 0x0020348C, 0x002038FC, 0x00203908, +0x00203914, 0x00203970, 0x00203974, 0x0020391C, +0x0020391D, 0x00203920, 0x00117700, 0x0020398C, +0x0020398A, 0x002034F0, 0x00117710, 0x001C3D30, +0x001C36F8, 0x00117734, 0x001C3684, 0x001C3D00, +0x001C1000, 0x001C1028, 0x00203504, 0x00203924, +0x00117600, 0x00117740, 0x7FFFFFFF, 0x00201730, +0x0020332A, 0x00202334, 0x00203DA4, 0x00203972, +0x002034FC, 0x00203964, 0x001C3D2C, 0x001C36B0, +0x00203494, 0x0011775C, 0x8801C90F, 0xA0CF8901, +0xD1960009, 0x36206212, 0xD4958904, 0x2421E200, +0x2162A0CC, 0x6211D193, 0x89012228, 0x0009A0C3, +0xE202D78F, 0x75016571, 0x3123615D, 0x27518D02, +0x0009A0BC, 0xD28C57F2, 0x62226072, 0x40094019, +0xC90F4009, 0x8F19880A, 0x52F31F2C, 0x40196022, +0x40094009, 0x8808C90F, 0xA0A78901, 0x60630009, +0xCB0154F7, 0xD27E55F2, 0xE7012402, 0xD47FE100, +0x22112572, 0x72016242, 0x2422A098, 0x8B3F8805, +0x602252F3, 0x40094019, 0xC90F4009, 0x8B168802, +0xE4FFD577, 0x644D6752, 0x8B102748, 0x6272D775, +0x8B0C3260, 0x51F255F7, 0xD26DE701, 0x21722562, +0xD571E100, 0x64522211, 0xA0777401, 0x52F32542, +0x40196022, 0x40094009, 0x8805C90F, 0x31B38B6E, +0xD26A8B6C, 0x672254F4, 0x7701D569, 0x61422272, +0x1F1CE640, 0x46182159, 0x8B033160, 0x6262D665, +0x26227201, 0xE200D65A, 0x2621B067, 0x0009A056, +0x3123E220, 0x88038B52, 0x52F38B1E, 0x40196022, +0x40094009, 0x8803C90F, 0xD25B8B16, 0x672254F4, +0x7701D557, 0x61422272, 0x1F1CE640, 0x46182159, +0x8B033160, 0x6262D655, 0x26227201, 0xE200D648, +0x2621B043, 0x0009A010, 0xD452D551, 0xD2446752, +0xE1007701, 0x25723A46, 0x22118F06, 0xEA00D64E, +0x72016262, 0x2622B031, 0x2FB2D54C, 0x95736652, +0xD44A5BF1, 0x36205241, 0x60618910, 0x8B01C803, +0x2B22E201, 0x8FF54510, 0x57F15664, 0x6272E1F0, +0x41284118, 0x2722221B, 0x6BF2A008, 0x6BF2A006, +0xE200D62F, 0xD12F2621, 0x2121E200, 0xD13CE201, +0x66122822, 0x8B012668, 0x0009AE2B, 0x450BD539, +0xD1390009, 0xAE24E600, 0x2F862160, 0x2FA62F96, +0x2FC62FB6, 0x2FE62FD6, 0x7FF44F22, 0xDE34D133, +0x54116212, 0x1F4167E2, 0x2F22D432, 0xD5321F72, +0xD2326743, 0x58417794, 0x69425A42, 0x5B166C72, +0x60526D22, 0xCB20E600, 0xE5402502, 0x626D7601, +0x8BFB3253, 0x55F162F2, 0x11512122, 0xD62855F2, +0x14812E52, 0x249214A2, 0x27C2D426, 0x26D211B6, +0xDA256742, 0xE801D925, 0x490B2A72, 0xE2011A8C, +0x1A2C4218, 0x4F267F0C, 0x6DF66EF6, 0x6BF66CF6, +0x69F66AF6, 0x68F6000B, 0x000007D1, 0x00203984, +0x00203988, 0x0020398E, 0x001C3DC0, 0x0011772C, +0x001C3B88, 0x0020396C, 0x0011773C, 0x00117744, +0x0000F000, 0x00117764, 0x00117748, 0x00117768, +0x0011776C, 0x01FFFFFF, 0x0011774C, 0x002034FC, +0x00203DA4, 0x002024F8, 0x00203972, 0x001C3B9C, +0x001C3D98, 0x001C3700, 0x001C3500, 0x001C5960, +0x001C8960, 0x00203504, 0x001C3D00, 0x0020160C, +0x2F962F86, 0x2FB62FA6, 0x2FD62FC6, 0x4F222FE6, +0xDE957FAC, 0x61E0E014, 0x0F14D494, 0x710161E3, +0xE0186210, 0xD2920F24, 0x0009420B, 0x450BD591, +0x20080009, 0x8F126D03, 0xD28F1F07, 0x6720D48F, +0x657CDD8F, 0x470BD78F, 0xD18F0009, 0x619C6910, +0x46086613, 0x36184608, 0x3D6C4608, 0xE0181FD7, +0xE58004FC, 0x604C66E2, 0x3050655C, 0x2D628F15, +0x01FCE014, 0xDE85E500, 0x641CA008, 0x6753655D, +0x607037EC, 0x39DC6953, 0x80947501, 0x3243625D, +0xD67F8BF4, 0xA34EE200, 0x20082621, 0xE0148B13, +0xE40001FC, 0xA009DE79, 0x644D671C, 0x35EC6543, +0x69436652, 0x39DC6262, 0x74041921, 0x3273624D, +0xA3388BF3, 0x88012D10, 0xE0148B17, 0xE70001FC, +0x6D1C2D70, 0xDE6D1FD4, 0x32D3627D, 0xA32A8B01, +0x677D0009, 0x667365E3, 0x61737504, 0x315C36EC, +0x69126462, 0xAFEF7708, 0x88042492, 0xE0148B18, +0xE40001FC, 0x671C2D40, 0x624DDE60, 0x8B013273, +0x0009A311, 0x6943644D, 0x39EC62E3, 0x72046592, +0x3D2C6D43, 0x615266D2, 0x21697408, 0x2512AFED, +0x8B188805, 0x01FCE014, 0x2D40E400, 0xDE53671C, +0x3273624D, 0xA2F68B01, 0x644D0009, 0x62E36943, +0x659239EC, 0x6D437204, 0x66D23D2C, 0x74086152, +0xAFED216B, 0x88312512, 0xD44A8B3A, 0x6146D94A, +0x75046543, 0x67566442, 0x6E531F48, 0x65527E04, +0x7EE462E2, 0x7E0464E2, 0x6EE21FE9, 0x5EF929E0, +0x7E04D942, 0x1FEA60E2, 0x2900C901, 0xD9406EE2, +0x29E04E09, 0x2F562F26, 0x56FAD93E, 0x6513490B, +0xD13D7F08, 0xE71C6E0D, 0x1DE12D70, 0xDE3B6912, +0x64E21D92, 0x1D43D13A, 0xD23A6512, 0x67221D54, +0x1D75D239, 0x1D666622, 0x6262D638, 0x1D27A2AB, +0x8B398830, 0x6596D92B, 0x67926696, 0x61967904, +0x74E46493, 0x6E436992, 0x1F9B7E04, 0x1FEC6442, +0xD9256EE2, 0x5EFC29E0, 0x7E04D924, 0x1FED60E2, +0x2900C901, 0xD9226EE2, 0x29E04E09, 0x59FC7FFC, +0xDE272F92, 0x2F164E0B, 0xD41F7F08, 0xE21C610D, +0x1D112D20, 0xD2206442, 0xD41C1D42, 0x1D536542, +0x6752D51B, 0xD71B1D74, 0x1D156172, 0x1D666622, +0x6262D61A, 0x1D27A26F, 0x8B358833, 0x490BD919, +0xA268EE00, 0x00002DE0, 0x00117800, 0x00203A1C, +0x002018A2, 0x00202AAC, 0x0020390E, 0x00203A20, +0x00203534, 0x002018EE, 0x0020390D, 0x00117804, +0x0020398C, 0x00117810, 0x00203909, 0x0020390A, +0x0020390B, 0x00200F64, 0x001C5864, 0x001C6864, +0x001C7864, 0x001C59BC, 0x001C69BC, 0x001C79BC, +0x00200FBC, 0x00200FB8, 0x89018828, 0x0009A0C0, +0xE643DEB5, 0x326662E1, 0x1FEE8F02, 0x2E21E240, +0x622D62E1, 0x8B013267, 0x0009A0AA, 0xE50185E1, +0x8B013056, 0x0009A0A4, 0x2D10E101, 0x64E1B225, +0xE64357FE, 0x652D6271, 0x89443567, 0x3563E640, +0xE6008B05, 0x0F65E040, 0xA00FE11A, 0x615372C0, +0x41214121, 0x41214121, 0x45214121, 0x45214521, +0xC9036053, 0xE0406603, 0x71180F65, 0x2209E007, +0x0F25E03C, 0xE044641D, 0xB2A365F3, 0xE33C0F46, +0x853233FC, 0x620DDE95, 0x42086031, 0x6023610D, +0x1323E944, 0x06FE4108, 0xE00F39FC, 0x13144E0B, +0x67075D91, 0x60D32679, 0x0F6654FE, 0x51928542, +0x600D4E0B, 0x60D3260B, 0x0F666492, 0x65F3B237, +0x696156FE, 0xE640659D, 0x89383563, 0xD78359FE, +0x79066591, 0xC9036053, 0x40004008, 0x61036203, +0x0F26E050, 0x470BE0FF, 0x6C07600C, 0x6603605D, +0x46214621, 0x46214621, 0x42006263, 0x4200326C, +0x40214021, 0x4008C903, 0x6D2D30FC, 0xE8006A03, +0xB25765F3, 0x6EA264D3, 0x2EC9E050, 0x66942AE2, +0xD76E01FE, 0x606C470B, 0x2AE22E0B, 0x64D365F3, +0x7801B1FD, 0xEE06628D, 0x8FE932E3, 0x5EFE7D01, +0x61E1E400, 0x410085E1, 0x66E3310C, 0x760C711B, +0xE70465F3, 0x68667401, 0x3A736A4D, 0x8FF92582, +0x65F37504, 0x641DB1E3, 0x64E1B1A4, 0x0009A17B, +0xD45B56F7, 0xEC01D25B, 0x26C0420B, 0x0009A173, +0x06FCE018, 0x8829606C, 0x58F78B08, 0xE400D252, +0x66222840, 0x646DB171, 0x0009A165, 0x666CE681, +0x89013060, 0x0009A0AC, 0xD550D14F, 0x62126A56, +0x212232AC, 0x54116C56, 0x34CC6253, 0x64521141, +0x72085812, 0xD44A384C, 0x68221182, 0x5A136C42, +0x3ACC3C8C, 0x11A324C2, 0x6C2272EC, 0x72105814, +0x118438CC, 0x5A156822, 0x11A53A8C, 0x6A227210, +0xD6405816, 0x118638AC, 0x52176C62, 0x112732CC, +0x5A185861, 0x11A83A8C, 0x5C195A62, 0x11C93CAC, +0x521A5C63, 0x112A32CC, 0x5A1B5864, 0x11AB3A8C, +0x5C1C5A65, 0x11CC3CAC, 0x521D5C66, 0x112D32CC, +0x5A1E5867, 0x11AE3A8C, 0x561F5A68, 0x36ACE840, +0x116FDA2D, 0x6CA2381C, 0x7A946682, 0x286236CC, +0x5C8162A2, 0x18C13C2C, 0x62A27A44, 0x362C5682, +0xD6261862, 0x5A856262, 0x3A2C4229, 0x760418A5, +0x56866262, 0x362C4229, 0x56F71866, 0x2620E238, +0x16C15C81, 0x16226212, 0xE2005C11, 0x551216C3, +0x55151654, 0x55131655, 0x55161656, 0x55821657, +0x65821658, 0x55141659, 0x5584165A, 0x5583165B, +0x5585165C, 0x5586165D, 0x1821165E, 0x11212122, +0x11251122, 0x11261123, 0x28221822, 0x18241124, +0x18251823, 0x1826A0C7, 0x00117804, 0x002033E8, +0x00203A40, 0x002018A2, 0x00203494, 0x001C36A0, +0x002034F0, 0x001C3CA0, 0x001C36F4, 0x001C3B88, +0x666CE682, 0x8B203060, 0xEA2456F7, 0x26A0D194, +0x16C15C17, 0x16225218, 0x16835819, 0x16A45A1A, +0x16C55C1B, 0x1626521C, 0xE200581D, 0x551E1687, +0x551F1658, 0x11271659, 0x11291128, 0x112B112A, +0x112D112C, 0xA08E112E, 0xE683112F, 0x3060666C, +0x52F78B0B, 0xEA00D883, 0x658222A0, 0x7804DC82, +0x62822C52, 0xA07ED681, 0xE6902620, 0x3060666C, +0xDA7F8B06, 0x00094A0B, 0xE20056F7, 0x2620A073, +0x666CE691, 0x8B103060, 0x6222D276, 0x2228622C, +0xD2788904, 0x0009420B, 0x0009A003, 0x420BD276, +0x56F70009, 0xA05EE200, 0xE6922620, 0x3060666C, +0xE0188951, 0xE6B00BFC, 0x666C62BC, 0x8B2A3260, +0x02FCE014, 0x682CEA00, 0x62ADE904, 0x894A3283, +0x6AADDD64, 0x3CDC6CA3, 0x7D046EC2, 0xDB68D467, +0x32DC62A3, 0x4B0BDC67, 0x4C0B6D22, 0xD46664E3, +0x00094B0B, 0x64D34C0B, 0x4B0BD464, 0xE6000009, +0x666D6BE3, 0x76013B6C, 0x3293626D, 0x8FF72BD0, +0xAFDA4D19, 0xE6B57A08, 0x3260666C, 0xD45C8B13, +0x4B0BDB57, 0xD25B0009, 0x6022DB5B, 0xCB20E6FF, +0x2202666D, 0xDB592B62, 0xE014E200, 0x56F72B20, +0xA01002FC, 0xD4562620, 0x6542D256, 0x420BD456, +0xA0080009, 0xDB520009, 0x52B1E600, 0x622CDB53, +0x52F72B21, 0x7F542260, 0x6EF64F26, 0x6CF66DF6, +0x6AF66BF6, 0x000B69F6, 0x4F2268F6, 0xE240614D, +0x89143123, 0x3127E21F, 0x8B09D749, 0xD449614D, +0xE00171E0, 0x5671440B, 0x26596507, 0x1761A007, +0xE001D444, 0x6672440B, 0x26596507, 0x4F262762, +0x0009000B, 0x614D4F22, 0x3123E240, 0xE21F8912, +0xD73B3127, 0x614D8B08, 0x5671D23A, 0x420B71E0, +0x260BE001, 0x1761A006, 0x6672D236, 0xE001420B, +0x2762260B, 0x000B4F26, 0xE6400009, 0x46284618, +0x6252D531, 0x89FC2268, 0x0009000B, 0x4618E680, +0xD52D4628, 0x22686252, 0x000B89FC, 0xA0010009, +0x7201E200, 0x8BFC3242, 0x0009000B, 0x4618E680, +0xD5264628, 0x22686252, 0x000B8BFC, 0x2FE60009, +0x7FFC4F22, 0xBFF16E53, 0x61E22F42, 0xE280D620, +0x54E11615, 0x16464218, 0x422855E2, 0x57E31657, +0x16786EF2, 0x26E22E2B, 0x4F267F04, 0x6EF6AFCE, +0x00203494, 0x00117804, 0x002038F4, 0x00203908, +0x0020050A, 0x00201008, 0x0020102E, 0x00203A58, +0x002018A2, 0x002018E6, 0x00203A6C, 0x00203A74, +0x00203A78, 0x001C3500, 0x001C1000, 0x0020398A, +0x00117800, 0x002018EE, 0x00203A8C, 0x00203990, +0x001C3704, 0x002033E8, 0x001C373C, 0x001C3700, +0x001C370C, 0x2FD62FC6, 0x4F222FE6, 0x6C53DD10, +0x6E43BFA4, 0x2DE2BF89, 0x0009BFA0, 0x2C1251D5, +0x1C4154D6, 0x1C5255D7, 0x1C6356D8, 0x6EF64F26, +0x000B6DF6, 0x61636CF6, 0xA004E600, 0x62564109, +0x24227601, 0x36127404, 0x000B8BF9, 0x00000009, +0x001C370C, 0x0009A16E, 0x2FE62FD6, 0xDD944F22, +0xA0049EB2, 0xD4930009, 0x420BD293, 0x62D265D2, +0x8BF822E8, 0x0009A004, 0xD28FD490, 0x55D1420B, +0x22E852D1, 0xA0048BF8, 0xD48D0009, 0x420BD28A, +0x52D255D2, 0x8BF822E8, 0x0009A004, 0xD286D489, +0x55D3420B, 0x22E852D3, 0xA0048BF8, 0xD4860009, +0x420BD281, 0x52D455D4, 0x8BF822E8, 0x6EF64F26, +0x6DF6000B, 0x2FD62FC6, 0x4F222FE6, 0x6E636C73, +0x6D53B01A, 0x64D357F4, 0xB05F65E3, 0xB07566C3, +0xB0A40009, 0xB0A80009, 0xB0AC0009, 0xB0AC0009, +0xB0AF0009, 0xB03154F5, 0x6CCD6C03, 0x4F2660C3, +0x6DF66EF6, 0x6CF6000B, 0x3412D170, 0xD6700529, +0x2650D770, 0x2742000B, 0x0009A018, 0x2FD62FC6, +0x4F222FE6, 0x6E636C73, 0x6D53BFEE, 0x64D357F4, +0xB03365E3, 0xB08D66C3, 0xB00F54F5, 0x6CCD6C03, +0x4F2660C3, 0x6DF66EF6, 0x6CF6000B, 0xE503D162, +0xD763D462, 0x21524518, 0x2472000B, 0xD45FD15E, +0x2162E600, 0x2462000B, 0xBF734F22, 0xBF73E40A, +0xD25C0009, 0x4118E104, 0xE40AE500, 0xBF692212, +0xD7592252, 0xCB206072, 0x000B4F26, 0x4F222702, +0x410BD156, 0xD556E400, 0x4F26452B, 0xD1552FE6, +0x66126E63, 0x92104418, 0x44084528, 0x45002629, +0x265B4408, 0x264B4400, 0x21624708, 0xD14E4708, +0x217227EB, 0x6EF6000B, 0x1FFF03F0, 0x4F222FE6, +0xE101DE4A, 0xBF3DE40A, 0x67E32E12, 0xE500776C, +0xE204E130, 0x2752E40A, 0x27522752, 0x27522752, +0x27522752, 0x27522752, 0x27522752, 0x27522752, +0x27522752, 0x27522752, 0x27522752, 0x27222712, +0x27522752, 0x27522752, 0x27522752, 0x27522752, +0x175ABF18, 0x2E62E600, 0x000B4F26, 0xD2346EF6, +0xE441E101, 0x000B2212, 0xD1322242, 0xE605D432, +0x000B2162, 0x000B2462, 0xD2300009, 0xE40AE601, +0x2262AF00, 0x2FC62FB6, 0x2FE62FD6, 0x7FFC4F22, +0x6C43DB2B, 0xED0060B2, 0x2B02CB03, 0xC90360B2, +0x6E03A008, 0x89073DC2, 0xE46460B2, 0xB07CC903, +0x7D016E03, 0x8BF52EE8, 0x8F043DC2, 0xD4212FE1, +0x460BD621, 0x62F10009, 0x6023622D, 0x89FFC801, +0x7F046023, 0x6EF64F26, 0x6CF66DF6, 0x6BF6000B, +0x001C3B88, 0x00203AA0, 0x002018EE, 0x00203AA8, +0x00203AB0, 0x00203AB8, 0x00203AC0, 0x0025E720, +0x00203DA0, 0x002038F8, 0x001C5968, 0x001C3B40, +0x000F8000, 0x001D4004, 0x001C3500, 0x002015E0, +0x0020160C, 0x001C5814, 0x001C59D0, 0x001C5830, +0x001C6268, 0x001C59A4, 0x001C639C, 0x001C581C, +0x001C5860, 0x00203AC8, 0x002018A2, 0x8F014411, +0x6043604B, 0x0009000B, 0x5651D52B, 0x46286052, +0x306C000B, 0x2FC62FB6, 0x2FE62FD6, 0x4F124F22, +0xBFF14F02, 0x6B036E43, 0xDD25DC24, 0x0009BFEC, +0x3C0530B8, 0x4609060A, 0x46014609, 0x020A3D65, +0x42094209, 0x32E24209, 0x4F068BF0, 0x4F264F16, +0x6DF66EF6, 0x000B6CF6, 0x2FC66BF6, 0x2FE62FD6, +0x4F124F22, 0xBFCF4F02, 0x6C036E43, 0xBFCBDD13, +0x30C80009, 0x060A3D05, 0x46094609, 0x36E24601, +0x4F068BF5, 0x4F264F16, 0x6DF66EF6, 0x6CF6000B, +0x4F222FE6, 0xE102DE0B, 0xE403E500, 0xBFB92E12, +0xE6062E52, 0xE7004618, 0x2E62E403, 0x4F262E72, +0x6EF6AFB0, 0x0009000B, 0x001C1040, 0xCCCCCCCD, +0x10624DD3, 0x001D4004, 0x2F962F86, 0x2FB62FA6, +0x2FD62FC6, 0x4F222FE6, 0xE5007F98, 0x6453E710, +0x6B534728, 0xEE1ADCBC, 0x6153655D, 0x315C4108, +0x75014108, 0x6043317C, 0x0F16665D, 0xED0060B3, +0x21B136E3, 0x81128111, 0x11D28113, 0x11D411D3, +0x74048FEA, 0xD8B167F2, 0x1871D9B1, 0x58F12872, +0x1981D1B0, 0x59F22982, 0x5DF45AF3, 0x54F65EF5, +0x21921191, 0x11A211A3, 0x11D411D5, 0x11E611E7, +0x11481149, 0xDAA855F7, 0x57F8EE00, 0x52F9DDA7, +0x64E3D6A7, 0x2A521A51, 0xD8A7D9A6, 0x2D729AD5, +0x6EED2622, 0x4D086DE3, 0x3DEC61E3, 0x4D084108, +0x3D9C31EC, 0x410860B3, 0x81D12DB1, 0x4108E050, +0x4008E7B7, 0x677C4108, 0x60B381D2, 0xE200318C, +0x81D33472, 0x1D131DD2, 0x8D01D493, 0xD4901D24, +0xB0B365D3, 0x64ED7E01, 0x8BDA34A2, 0x2FD2DA8C, +0xDD9268A2, 0x2D824829, 0x7DFC64A2, 0xD287694D, +0x6E222D92, 0x7D0C4E29, 0x68222DE2, 0x618D6AD3, +0x2A16D784, 0xD48A6D72, 0x24D2D583, 0xD6895E72, +0x517414E2, 0x1414EE00, 0xD1875876, 0x59781486, +0x1498E710, 0x65E36252, 0x26E2142A, 0xE60064E3, +0x6843644D, 0x384C4808, 0x381C4808, 0x0C866053, +0x09CE28B1, 0x819160B3, 0x0ACE6053, 0x81A26043, +0x0DCE6053, 0x81D360B3, 0x08CE6053, 0x18827401, +0x624D09CE, 0x0ACE19E3, 0x1A643273, 0x75048FE0, +0xE003D96A, 0x40186C92, 0x6D922CB1, 0x81D1DA6F, +0x6E92E050, 0x81E24008, 0x60B36192, 0x64928113, +0x1442E600, 0xD4696792, 0x689217A3, 0x1864E1FF, +0x6563E703, 0x364C4608, 0x26127501, 0x3673665D, +0xDC5B8BF8, 0x6DC2E003, 0x2DB14018, 0xD2606EC2, +0x61C281E1, 0x1112EE00, 0xE02464C2, 0x65C21423, +0x15E4D45B, 0xE58067C2, 0x68C28172, 0x818366E3, +0x666D655C, 0x76046963, 0x394C6A6D, 0x8FF83A53, +0xDB5429E2, 0x24B2DC54, 0x24C27404, 0x4F267F68, +0x6DF66EF6, 0x6BF66CF6, 0x69F66AF6, 0x68F6000B, +0x60116142, 0x8F03C803, 0xD23DE500, 0x8B063420, +0xC9036011, 0x8B068802, 0x3420D239, 0x56128B03, +0x52646513, 0x000B2422, 0x01136053, 0x2FE62FD6, +0x7FEC4F22, 0x62536E53, 0x6D43E550, 0x4508E400, +0xE101A001, 0x60435224, 0x81212211, 0x60538123, +0x56E28122, 0x8BF53620, 0x16E4D238, 0xE61464F3, +0x65E3420B, 0xE4FC65E1, 0x2E512549, 0x65F361F1, +0x2F112149, 0xD13154D1, 0xE614410B, 0x607157D1, +0x2701CB01, 0x7F141DE1, 0x6EF64F26, 0x6DF6000B, +0x2FE62FD6, 0x7FEC4F22, 0x66536E53, 0x6D43E5FC, +0x20596061, 0x2601CB01, 0x326052E2, 0x12E48B06, +0x31E051E2, 0x52D18B04, 0x1E22A002, 0x5664AFF0, +0x64F3D21E, 0x420BE614, 0x67E165E3, 0x2719E1FC, +0x67F12E71, 0x271954D1, 0x65F3D118, 0x410BE614, +0x52D12F71, 0xCB016021, 0x1DE12201, 0x4F267F14, +0x000B6EF6, 0x00006DF6, 0x00203924, 0x002034F4, +0x002034FC, 0x00203504, 0x0020352C, 0x00203910, +0x00203918, 0x00100208, 0x001017C0, 0x001E210C, +0x001C3D00, 0x00203964, 0x001000C8, 0x00117880, +0x00117780, 0x00040020, 0x0026C401, 0x00200ED6, +0x4F222FE6, 0xDE42624C, 0x42004208, 0x3E2CA005, +0xD4405252, 0xBF695624, 0x65E22E62, 0x352052E1, +0xD63D8BF6, 0x4F262622, 0x6EF6000B, 0x2FC62FB6, +0x2FE62FD6, 0xDC394F22, 0x52C1DB39, 0x362066C2, +0x6061891C, 0x8801C903, 0xDE348918, 0xBF37DD35, +0x650364E3, 0x66B28503, 0x3262620D, 0xD4328907, +0x0009BF76, 0x4D0BD431, 0xAFE60009, 0xBF3D0009, +0xD42F64E3, 0x00094D0B, 0x0009AFDF, 0x2262D22D, +0x6EF64F26, 0x6CF66DF6, 0x6BF6000B, 0x2FD62FC6, +0x4F222FE6, 0xDD29DC28, 0x6E4360C2, 0x04DE4008, +0xE614D127, 0x65E3410B, 0xD127D726, 0x55E227E2, +0x35E05254, 0x21228F04, 0x400860C2, 0x122202DE, +0x605365C2, 0x75014008, 0x0DE606DE, 0xC90F6053, +0x60632C02, 0x6EF64F26, 0x000B6DF6, 0x85436CF6, +0x650D5643, 0x622D6262, 0x35277204, 0xE1008F0C, +0x2268960C, 0xD6158B03, 0x72015261, 0xD6131621, +0x6262E101, 0x26227201, 0x6013000B, 0x000001FF, +0x00203504, 0x002034FC, 0x001C3D00, 0x0020352C, +0x002038F4, 0x002018A2, 0x002034F4, 0x00203AF0, +0x00203AF4, 0x001C3D28, 0x00203964, 0x00203924, +0x00200ED6, 0x00203968, 0x0020396C, 0x00117754, +0x2FC62FB6, 0x2FE62FD6, 0x7FF84F22, 0x6022D237, +0x8D58C803, 0xDE362F01, 0xDB37DC36, 0x66C252C1, +0x892F3620, 0xC9036061, 0x892B8801, 0xD233DD31, +0x64D3420B, 0x1F016503, 0x880160B1, 0xD2308B04, +0x64D3420B, 0x0009AFEA, 0x85615653, 0x8904C820, +0xE050D72C, 0x7201027E, 0xD22B0726, 0x6453420B, +0x89072008, 0x55F1D126, 0x64D3410B, 0xE601D727, +0x2762AFD4, 0x55F1D226, 0x64E3420B, 0xE601D125, +0x2162AFCC, 0xDD25DE24, 0xDC26DB25, 0x66D252D1, +0x89183620, 0xC9036061, 0x89148801, 0xD117D41F, +0x0009410B, 0x36E05603, 0x65038F04, 0x2B20E201, +0x2C52AFEC, 0xD712D41C, 0x0009470B, 0xE601D115, +0xAFE34618, 0x60F12162, 0x8907C804, 0x7F08D217, +0x6EF64F26, 0x6CF66DF6, 0x6BF6422B, 0x4F267F08, +0x6DF66EF6, 0x000B6CF6, 0x00006BF6, 0x001E2100, +0x00203504, 0x002034FC, 0x0020398C, 0x002014A0, +0x002014CC, 0x00203494, 0x002016BE, 0x001E212C, +0x00201530, 0x001C3D30, 0x00117880, 0x002034F4, +0x00203914, 0x00203910, 0x0020352C, 0x00200610, +0xE601D203, 0x1265D503, 0x000B2252, 0x00001266, +0x001C1010, 0x0000C34F, 0x0009000B, 0x2FD62FC6, +0x4F222FE6, 0x6D436C53, 0xEE00A004, 0x7E0164D4, +0x644CBFF2, 0x8BF93EC2, 0x6EF64F26, 0x000B6DF6, +0xE5006CF6, 0x6643A002, 0x76017501, 0x22286260, +0xAFE38BFA, 0x2FE60009, 0x75076253, 0xE1086753, +0x6043EE0A, 0x4409C90F, 0x650330E2, 0x8D014409, +0xE630E637, 0x4110365C, 0x8FF22760, 0xE00077FF, +0x000B8028, 0x000B6EF6, 0x000BE000, 0x2FE6E000, +0x7FEC4F22, 0x6E436253, 0xBFDC65F3, 0xBFD06423, +0xBFCE64E3, 0xD40364F3, 0x0009BFCB, 0x4F267F14, +0x6EF6000B, 0x00203AF8, 0xE4FDD29F, 0xD79F6122, +0x22122149, 0x74016022, 0x2202CB01, 0xD59C6622, +0x22622649, 0xC8406070, 0x60528902, 0x2502CB04, +0xE1F76452, 0x25422419, 0xE7016052, 0x2502CB40, +0xE6026052, 0x2502C9CF, 0x47186052, 0x2502CB10, +0xCB036052, 0x15622502, 0x1573000B, 0xD78ED58D, +0xD48FD28E, 0xE600E100, 0x27112511, 0xAFCB2210, +0x664C2461, 0x4600D28B, 0x6060362C, 0x000BCB10, +0x654C2600, 0x4500D287, 0x6650352C, 0x2619E1EF, +0x2560000B, 0xD284664C, 0x362C4600, 0xCB106060, +0x2600000B, 0xD280654C, 0x352C4500, 0xE1EF6650, +0x000B2619, 0x664C2560, 0x4600D27A, 0x6060362C, +0x000BCB08, 0x654C2600, 0x4500D276, 0x6650352C, +0x2619E1F7, 0x2560000B, 0xD273664C, 0x362C4600, +0xCB086060, 0x2600000B, 0xD26F654C, 0x352C4500, +0xE1F76650, 0x000B2619, 0x624C2560, 0x4200D669, +0x6020326C, 0x4021C908, 0x40214021, 0x600C000B, +0xD665624C, 0x326C4200, 0xC9086020, 0x40214021, +0x000B4021, 0xD161600C, 0x341C644C, 0x000B6240, +0xD15F602C, 0x341C644C, 0x000B6240, 0x2FE6602C, +0x6E434F22, 0xE60A645C, 0x89143467, 0x0009BFEB, +0x60EC640C, 0x8B028801, 0xA002E00F, 0x44092409, +0x624C4409, 0x3263E60A, 0xBFE28905, 0x620C644C, +0xC8806023, 0xE2008B00, 0x4F266023, 0x6EF6000B, +0xD64C4F22, 0x88016062, 0xB2578B03, 0xA0030009, +0xD2490009, 0x2260E640, 0xE200D648, 0x000B4F26, +0x4F222622, 0x6062D643, 0x8B018802, 0x0009B2A0, +0xE200D642, 0x000B4F26, 0xD53E2622, 0xE100D43E, +0x2512E701, 0x2470000B, 0xE604D23B, 0x2260000B, +0xD43B4F22, 0x410BD13B, 0xD53B0009, 0x6650E1FD, +0x2619D23A, 0x2560E700, 0x000B4F26, 0x4F222270, +0xD238D537, 0xD7386152, 0x2512611D, 0xE6FF6452, +0x2542242B, 0xD22FD435, 0x420B666D, 0xD52E2762, +0x6750E1FB, 0x4F262719, 0x2570000B, 0xD4304F22, +0x410BD128, 0xD5280009, 0x6650E7F7, 0x4F262679, +0x2560000B, 0x9425D524, 0x22496250, 0x2520000B, +0xE4BFD521, 0x22496250, 0x2520000B, 0xD2254F22, +0x600D8522, 0x89112008, 0x89458801, 0x89478803, +0x89498805, 0x894F8806, 0x89558808, 0x895B8809, +0x8961880A, 0x8967880B, 0x0009A06E, 0x0009B070, +0x600CA06B, 0x0000FF7F, 0x001E2148, 0x001E1000, +0x001E1108, 0x002039C4, 0x002039C6, 0x002039E5, +0x002039A8, 0x001E103F, 0x001E105F, 0x001E102F, +0x001E1090, 0x002039CC, 0x001E100B, 0x002039C8, +0x00203AFC, 0x002018A2, 0x001E1028, 0x002039E4, +0x001D4020, 0x98760000, 0x001C1000, 0x00203B08, +0x00203B18, 0x0020399C, 0x0009B04C, 0x600CA035, +0x0009B055, 0x600CA031, 0x6260D684, 0x8B2B2228, +0x0009B061, 0x600CA029, 0x6260D680, 0x8B232228, +0x0009B069, 0x600CA021, 0x6260D67C, 0x8B1B2228, +0x0009B0C7, 0x600CA019, 0x6260D678, 0x8B132228, +0x0009B0CD, 0x600CA011, 0x6260D674, 0x8B0B2228, +0x0009B125, 0x600CA009, 0x6260D670, 0x8B032228, +0x0009B13D, 0x600CA001, 0x4F26E000, 0x0009000B, +0xD26CD16B, 0xD56C8412, 0x4000C90F, 0xD76B012D, +0xE403D66B, 0xE20F611C, 0x2540E001, 0x25202712, +0x2602000B, 0xE601D262, 0x30668523, 0xE0008D05, +0xD663D260, 0xE0018122, 0x000B2602, 0xD25C0009, +0x600D8523, 0x89052008, 0x8B0A8801, 0x6060D65D, +0x2600CB01, 0xD457D65A, 0xE001E101, 0x000B2612, +0x000B8142, 0xD152E000, 0x8513E501, 0x640D4518, +0x66033453, 0xE0008D05, 0xD551D253, 0x2260E001, +0x000B2502, 0x4F220009, 0x8513D149, 0x6453650D, +0x62494419, 0x227D672E, 0x8801602C, 0x88028909, +0x88038910, 0x8806891A, 0x88078935, 0xA04C893B, +0xD5460009, 0x6652D746, 0x2762D446, 0x622C6261, +0x2421A038, 0x2228625C, 0xD4438B3F, 0x6642D540, +0x2562D440, 0x24018561, 0x6203A02C, 0x2008605C, +0x88108907, 0x88208908, 0x88308909, 0xA02C890A, +0xD23A0009, 0x6222A008, 0xA005D239, 0xD2396222, +0x6222A002, 0x6262D638, 0xD432D531, 0x66212522, +0xA00F626C, 0xD6352421, 0x6261D52D, 0x622CD42D, +0xA0072562, 0xD6322421, 0x8561D529, 0x2562D429, +0x62032401, 0x662D8515, 0x3617610D, 0x65038F01, +0xB0CB2451, 0xA0010009, 0xE000E001, 0x000B4F26, +0xD6190009, 0xD427E101, 0x65412610, 0xD118D717, +0xE20F655D, 0x2752E001, 0x000B2620, 0x2FE62102, +0xD20F4F22, 0x640C8523, 0x8B082448, 0xD511D61D, +0x2621E200, 0x940F8451, 0xA0482049, 0xDE0D8051, +0xC84060E0, 0xE2018D32, 0x89443427, 0xD216D615, +0x2641420B, 0x0009A030, 0x0000FF7F, 0x002039E5, +0x0020399C, 0x002039A8, 0x001E1100, 0x001E100C, +0x002039C8, 0x001E1000, 0x001E1001, 0x002039D0, +0x002039B0, 0x002039B4, 0x002039B8, 0x002039D4, +0x002039D8, 0x002039DC, 0x002039E0, 0x00203E04, +0x00203E0E, 0x002039C2, 0x00202886, 0x89123427, +0xD294D693, 0x2641420B, 0xCB8084E1, 0x80E1B0F5, +0xD69160E0, 0x2E00CB04, 0xC93F6060, 0xD68F2600, +0xA001E001, 0xE0002602, 0x000B4F26, 0xD68C6EF6, +0xC8806060, 0xD2868919, 0x88016021, 0xD2898B15, +0x8524E501, 0x89103056, 0xE203D187, 0x2120D487, +0xE00B6541, 0x0656655D, 0xE40FD585, 0x2140E702, +0xD77E2571, 0x000BE001, 0x000B2702, 0x2FE6E000, +0xDE804F22, 0xC88084E1, 0xD57A892C, 0x20088554, +0x61038F28, 0x8553D77C, 0x64036672, 0x8566650C, +0x3520620C, 0xD6798B1E, 0x651CD774, 0x2651644C, +0x60E02741, 0x8904C840, 0x420BD275, 0xA0030009, +0xD2680009, 0x0009420B, 0x0009B09F, 0xE201D167, +0x60E02122, 0xCB04D464, 0x60402E00, 0x2400C93F, +0x6023A001, 0x4F26E000, 0x6EF6000B, 0x2FB62FA6, +0x2FD62FC6, 0xDA622FE6, 0x66A1E240, 0x3622DC5E, +0x62638900, 0x6ED36D2C, 0x4E2136D8, 0x4E212A61, +0xDB61D460, 0xE700A00F, 0x770162B2, 0x71026123, +0x66212B12, 0x71026213, 0x61212B12, 0x651D666D, +0x356C4528, 0x627C2452, 0x8BED32E3, 0xC90360D3, +0x8B108803, 0x617367B2, 0x2B127102, 0x71026E13, +0x2B126571, 0x655D6DE1, 0x422862DD, 0x325CE107, +0xA00C2C10, 0x88022422, 0xA0038B01, 0x8801E203, +0xE2018B05, 0x66B22C20, 0x655D6561, 0xE60F2452, +0x67A12C60, 0x8B052778, 0xDD38DC44, 0xEB01EA00, +0x2DB22CA2, 0x6DF66EF6, 0x6BF66CF6, 0x6AF6000B, +0x2FE62FD6, 0xE240DD36, 0x362266D1, 0x62638900, +0x3678672C, 0x7703DE38, 0x47212D61, 0x64E2D635, +0xA00E4721, 0x6562E100, 0x62537101, 0x74012450, +0x24204219, 0x45297401, 0x74012450, 0x24504519, +0x621C7401, 0x8BEE3273, 0x66E24200, 0x420061D1, +0x2118362C, 0x2E628F06, 0xDD1CD728, 0xE501E400, +0x2D522742, 0x000B6EF6, 0x2FD66DF6, 0x4F222FE6, +0xED0AEE01, 0x64E3BC85, 0xBC8A64E3, 0x62EC7E01, +0x8BF732D7, 0xBC8DEE01, 0x64E364E3, 0x7E01BC92, +0x32D762EC, 0x4F268BF7, 0x000B6EF6, 0xD1186DF6, +0xD418920D, 0x72122122, 0x2422D617, 0xD7177204, +0x72202622, 0x2722D116, 0x000B7230, 0x137A2122, +0x002039C2, 0x00202992, 0x001E1015, 0x002039C8, +0x001E1001, 0x0020399C, 0x001E1100, 0x002039C6, +0x002039B4, 0x001E1000, 0x002039B8, 0x002039C4, +0x00202886, 0x001E100C, 0x002039B0, 0x002039CC, +0x002039D0, 0x002039D4, 0x002039D8, 0x002039DC, +0x002039E0, 0x4F222FE6, 0xD6707FFC, 0x88016060, +0xE2018951, 0x2620BFBB, 0xD56ED16D, 0xDE6E6010, +0x64E36552, 0x7402C840, 0x8D22D16C, 0xD26C7502, +0xE601D76C, 0xE7042722, 0x76016255, 0x626C2421, +0x8FF93273, 0xD4637402, 0x6242E601, 0x640D8528, +0x67494419, 0x275D657E, 0x81E4607C, 0xE417D562, +0x67557601, 0x3243626C, 0x8FF92171, 0xA0207102, +0xD25E0009, 0xE601D75B, 0xE7042722, 0x76016255, +0x626C2421, 0x8FF93273, 0xD4527402, 0x6242E601, +0x640D8528, 0x67494419, 0x275D657E, 0x81E4607C, +0xE417D553, 0x67557601, 0x3243626C, 0x8FF92171, +0x92897102, 0xD2462E21, 0x5E23D74E, 0x64F22FE2, +0x604365F2, 0x2700C980, 0xC9606043, 0x80716103, +0xC9036043, 0x80724519, 0x65F2605C, 0x817266F2, +0x46194629, 0x606C4529, 0x4018645C, 0x8173304C, +0x21185E23, 0x64F22FE2, 0x6E4C62F2, 0x602C4219, +0x66F262F2, 0x46294018, 0x461930EC, 0x42298174, +0x652C606C, 0x305C4018, 0x81758F07, 0x0009BC96, +0x2228620C, 0xA00A8908, 0x60130009, 0x8B038840, +0x0009B009, 0x0009A003, 0xE202D62F, 0x7F042622, +0x000B4F26, 0x4F226EF6, 0x8552D52A, 0x8830600D, +0x88318903, 0xA0348923, 0x85550009, 0xD428D727, +0x85532701, 0x610DD627, 0x24124118, 0x460BD426, +0xD7230009, 0xD226D425, 0x6572420B, 0xE230D120, +0x42286712, 0x2729E620, 0x37604628, 0xD6218B03, +0xA016E200, 0xD61F2622, 0xA012E202, 0xD1182622, +0x6212E530, 0xE6204528, 0x46282259, 0x89083260, +0xD41AD119, 0xE601D513, 0x2160450B, 0x472BD718, +0x4F264F26, 0x0009000B, 0x0000060A, 0x002039E4, +0x001E1000, 0x002039D0, 0x00203E04, 0x00203E10, +0x00203DA8, 0x002039B8, 0x00203DD8, 0x00203DD6, +0x00203DAA, 0x0020399C, 0x002039C8, 0x002039B4, +0x002039B0, 0x002018A2, 0x00203B24, 0x00203B28, +0x002018EE, 0x002039CC, 0x001E100B, 0x00203B3C, +0x00114004, 0x4F222FE6, 0xDE967FFC, 0x200884E9, +0x2F008D06, 0xD695D494, 0x0009460B, 0x64F0B19A, +0x6620D293, 0x89022668, 0xC9BF60E0, 0x7F042E00, +0x000B4F26, 0x000B6EF6, 0x2FE60009, 0xDE8D4F22, +0x60E0D68D, 0xCBC0D48D, 0x62602E00, 0xC803602C, +0x40218904, 0x70014021, 0x6603A002, 0x66034009, +0xD687616D, 0xE500A004, 0x75016262, 0x74042422, +0x3213625D, 0xD2838BF8, 0x0009420B, 0xC9BF84E2, +0x4F2680E2, 0x6EF6000B, 0x2FE62FD6, 0x7FFC4F22, +0x6260D67D, 0x89442228, 0xD572E100, 0x60502610, +0xCB40D47A, 0x2500440B, 0x8D052008, 0x62E06E03, +0x7104612C, 0x2F11A006, 0xD475D66D, 0xDD756760, +0x657C4D0B, 0xE23C6D1D, 0x8B033D27, 0xD267D472, +0x0009420B, 0x4D214D21, 0xA005D770, 0x66E6E400, +0x357C4508, 0x74012562, 0x35D3654D, 0xD76C8BF7, +0x6172E003, 0x81114018, 0x6E7260F1, 0x81E2700C, +0xD4686172, 0xDD688113, 0x4D0BDE68, 0xE2016572, +0xD4672E22, 0x420BD255, 0xD6560009, 0xC93F6060, +0x7F042600, 0x6EF64F26, 0x6DF6000B, 0x2FC62FB6, +0x2FE62FD6, 0xD25F4F22, 0x6B436E73, 0x420B6C53, +0x20086D63, 0x64038D1C, 0xE50ED149, 0x32526210, +0x60C38916, 0x804124B0, 0x814160D3, 0xA007E500, +0x655D61BC, 0x00EC6053, 0x364C6653, 0x80647501, +0x3213625D, 0xD63B8BF5, 0xC9BF6060, 0x2600A008, +0xD23AD44D, 0x6EF64F26, 0x6CF66DF6, 0x6BF6422B, +0x6EF64F26, 0x6CF66DF6, 0x6BF6000B, 0x7FC44F22, +0x720262F3, 0x22512F41, 0x45297202, 0x60632251, +0xE5C4E682, 0x67F38121, 0x655C666C, 0xE408BFB6, +0x4F267F3C, 0x0009000B, 0x2F962F86, 0x2FB62FA6, +0x2FD62FC6, 0x4F222FE6, 0xE1007FC4, 0x6513ECFF, +0x6B136CCD, 0xDE36D735, 0xEDFF64F3, 0xD835EA04, +0x6053655C, 0x027D4000, 0x32C0622D, 0x66038D0D, +0x09ED6063, 0x2491027D, 0x24217402, 0x698202ED, +0x3928622D, 0x74022892, 0x75017104, 0x6063625C, +0x07D532A2, 0x0EB58FE4, 0x2448641C, 0xE6808905, +0x67F3E5C5, 0xBF79666C, 0x7F3C655C, 0x6EF64F26, +0x6CF66DF6, 0x6AF66BF6, 0x000B69F6, 0xD11E68F6, +0x6012D21E, 0xCB20E405, 0x2102E500, 0x000B2242, +0x00002252, 0x001E1017, 0x00203B40, 0x002018A2, +0x0020390E, 0x001E1015, 0x001E10BF, 0x00117800, +0x001E10FC, 0x00200610, 0x00203914, 0x00202AEA, +0x00203B44, 0x002018EE, 0x00203B60, 0x0011788C, +0x00203910, 0x002034F4, 0x00201530, 0x001E2130, +0x00203B68, 0x00202AAC, 0x00203B6C, 0x00203974, +0x0020397C, 0x00203DA4, 0x001C3500, 0x001D4004, +0xD564D163, 0xE400D764, 0x2142E20F, 0x17411154, +0xD5622722, 0x9669D762, 0x15412572, 0x96661562, +0xE6011565, 0xD55F1165, 0x666CE6F8, 0x25422542, +0x25422542, 0x25422542, 0x25622542, 0x7601E727, +0x67632572, 0x25627797, 0xE7042572, 0x2572E248, +0xE2192522, 0xE2702522, 0x25422542, 0x25422542, +0x25222542, 0x2522E20C, 0x25422542, 0x25422542, +0x25422542, 0x25422542, 0x000B154A, 0xE2081145, +0x0009422B, 0x2FE62FD6, 0x7FFC4F22, 0xC8206043, +0x6E438D02, 0x0009BE67, 0xC81060E3, 0xBE648901, +0x60E30009, 0x8901C840, 0x0009BE86, 0xC80160E3, +0xDD3D8938, 0xC80260D0, 0x2F008D03, 0x460BD63B, +0x60F00009, 0x8902C804, 0x460BD639, 0x62F00009, +0xC8806023, 0x60D08902, 0x2D00C97F, 0xC8016023, +0xD6348906, 0x0009460B, 0x0009A007, 0x51630601, +0x8902C808, 0x460BD630, 0x60F00009, 0x8902C810, +0x420BD22E, 0xD52E0009, 0x88026052, 0xD22D8B03, +0xA005E604, 0x88012260, 0xD22A8B02, 0x2260E601, +0x2522E200, 0xC88060E3, 0xD227892D, 0x60E36E20, +0x8902C880, 0x420BD225, 0x60E30009, 0x8902C840, +0x420BD223, 0x60E30009, 0x8902C802, 0x420BD221, +0x60E30009, 0x890DC804, 0xDD20D11F, 0x0009410B, +0x0009BF0D, 0x0009BF4C, 0xD51ED41D, 0x2470E708, +0x25D2BF85, 0xC80860E3, 0xD21B8905, 0x4F267F04, +0x422B6EF6, 0x7F046DF6, 0x6EF64F26, 0x6DF6000B, +0x001C581C, 0xA000A000, 0x001D0100, 0x001D4000, +0x00040021, 0x001C589C, 0x001E1021, 0x00201A90, +0x00201AB2, 0x00202114, 0x00201ACA, 0x00201AD8, +0x002039C8, 0x001E100B, 0x001E1028, 0x00201B44, +0x00201B50, 0x00201AE0, 0x00201AFE, 0x12345678, +0x001E1000, 0x0010F100, 0x00201B2C, 0x644CD6A7, +0x000B346C, 0xD6A62450, 0x346C644C, 0x2450000B, +0x644CD6A4, 0x000B346C, 0x625C2450, 0x4208616D, +0x42084119, 0x42006019, 0x670E614C, 0xD49E321C, +0x4200207D, 0x324CC90F, 0x2200000B, 0x4208625C, +0x42004208, 0x324C644C, 0x4200D498, 0x000B324C, +0x2FE62260, 0x614C4F12, 0x4100D493, 0x6710314C, +0xE29F666D, 0x27294619, 0x6E536269, 0x672E6573, +0x4221227D, 0x42214221, 0x7601662C, 0xE4014608, +0x34E84608, 0x644C4600, 0x071A0467, 0x2150257B, +0x000B4F16, 0x4F226EF6, 0xD2857FE8, 0x88016021, +0xD2848B7B, 0x26686621, 0xD2838B77, 0x26686621, +0xE50F8B73, 0xE401BFA2, 0xBFA4E501, 0xE586E400, +0xE400655C, 0x2F50BFA4, 0xBFA1E401, 0xE602E506, +0x60634618, 0x81F2E401, 0x6543BF9F, 0xE40185F2, +0xBFAB6543, 0x85F26603, 0x6543E401, 0x6603BFB1, +0xE40265F0, 0x6053756C, 0x80F8BF80, 0xBF82E402, +0x84F8E512, 0x7090E402, 0x6503BF82, 0x4618E602, +0x81F66063, 0xBF80E402, 0x85F6E500, 0x6603E402, +0xE500BF8C, 0xE40285F6, 0xBF926603, 0xE5FEE500, +0xE010655C, 0xBF61E403, 0xE5130F54, 0xE40EBF63, +0x05FCE010, 0xBF63E40E, 0xE5007585, 0xBF64E403, +0xE500E640, 0xBF71E403, 0xE500E640, 0xBF78E403, +0xE5FFE640, 0xE014655C, 0xBF47E404, 0xE40F0F54, +0xE504BF49, 0x05FCE014, 0xBF49E40F, 0xE5017584, +0xBF4AE640, 0xE501E404, 0xBF57E640, 0xE501E404, +0xE404E640, 0xAF5C7F18, 0x7F184F26, 0x000B4F26, +0x4F220009, 0xD2427FF0, 0x88016021, 0xD2418B71, +0x26686621, 0xD2408B6D, 0x26686621, 0xE50F8B69, +0xE401BF1C, 0xBF1EE501, 0xE586E400, 0xE400655C, +0x2F50BF1E, 0xBF1BE401, 0xE401E506, 0xBF1C6543, +0xE401E640, 0xBF296543, 0xE401E640, 0xBF306543, +0x65F0E640, 0x756CE402, 0xBEFF6053, 0xE40280F4, +0xE512BF01, 0xE40284F4, 0xBF017090, 0xE6406503, +0xBF02E402, 0xE640E500, 0xBF0FE402, 0xE640E500, +0xBF16E402, 0xE5FEE500, 0x6053655C, 0xBEE5E403, +0xE51380F8, 0xE40EBEE7, 0xE40E84F8, 0xBEE77085, +0xE5006503, 0xBEE8E640, 0xE500E403, 0xBEF5E640, +0xE500E403, 0xBEFCE640, 0xE5FFE403, 0x6053655C, +0xBECBE404, 0xE40F80FC, 0xE504BECD, 0xE40F84FC, +0xBECD7083, 0xE5016503, 0xBECEE640, 0xE501E404, +0xBEDBE640, 0xE501E404, 0xE404E640, 0xAEE07F10, +0x7F104F26, 0x000B4F26, 0x00000009, 0x001E102F, +0x001E1080, 0x001E1090, 0x001E103F, 0x001E103E, +0x002039C2, 0x002039C4, 0x002039C6, 0xD21DD11C, +0x66206010, 0x676C7001, 0x3700C90F, 0xE5008D13, +0x67106210, 0x7701622C, 0x64232170, 0xD6166010, +0x44084408, 0x3428C90F, 0x62602100, 0x7201D513, +0x44082620, 0x000B354C, 0xD10F6053, 0x25586510, +0xE6008D13, 0xD60DD40B, 0x655C6540, 0x47086753, +0x37584708, 0x47086540, 0x24507501, 0x367C6040, +0x2400C90F, 0x72FF6210, 0x000B2120, 0x00006063, +0x0020390D, 0x0020390C, 0x0020390E, 0x00203534, +0x7FFC4F22, 0xE680D19F, 0x666C6212, 0xD29E2F22, +0x67F36563, 0x420B7542, 0x7F04E404, 0x000B4F26, +0xE6800009, 0xD298666C, 0xE7006563, 0x422B7540, +0xE6806473, 0xD294666C, 0xE7006563, 0x422B7543, +0x2F866473, 0x2FA62F96, 0x2FC62FB6, 0x2FE62FD6, +0x7FCC4F22, 0xDC8ED28D, 0x72011F21, 0xDB8D1F22, +0xD18EDE8D, 0x66125211, 0x8B013620, 0x0009A0E5, +0xC9036061, 0x8B018801, 0x0009A0DF, 0xD288D487, +0xED84420B, 0x2F025503, 0x30D0845C, 0xA0B88901, +0xD1840009, 0x626C6610, 0x88016023, 0xD1828B68, +0x62101FC3, 0x895B2228, 0xE003D480, 0x40186742, +0x68421772, 0xD57EE900, 0x81816DB3, 0x7D042190, +0x67D26AB2, 0x64E26852, 0x1F491F57, 0x740464E3, +0x1FA46542, 0x65431F5A, 0x625275F8, 0x1F761FD5, +0x6D531F2B, 0xDA74D773, 0x7D94D274, 0x68D21F88, +0x6AA26972, 0xD1726022, 0x2202CB20, 0xE1401F1C, +0x7601E600, 0x3213626D, 0x56F48BFB, 0x52F651F5, +0x21222B62, 0x52F851F7, 0x212256F9, 0x2E6251FA, +0x51FB2412, 0x2D822512, 0xD9662792, 0x29A2DD5F, +0x6AD2D965, 0xD9646892, 0x68D21A84, 0x6081DA63, +0x2801CB01, 0xD86266D2, 0x2A622962, 0xED015AFC, +0x2AD2480B, 0x2AD24D18, 0x62D2DD5E, 0x2D227201, +0xD15056F3, 0xE2026062, 0x2602CB01, 0x2120A03D, +0x8B3A2228, 0xE401DD58, 0x2140E600, 0xE01C2D62, +0xC801005C, 0xD4558B0A, 0xE600D755, 0xED7D2472, +0x626C7601, 0x8BFB32D3, 0x24D2DD52, 0xE2FE68C2, +0x2C822829, 0x095CE01E, 0xE01F5DF1, 0x0A5C2D90, +0x751051F2, 0xED0621A0, 0xD74BE600, 0x8456D44B, +0x27007601, 0x696C6854, 0x248039D3, 0x8FF67401, +0xDA477701, 0x2A10E194, 0xE2007A01, 0x7A0F2A20, +0xD130E805, 0x66102A80, 0x6023626C, 0x89088801, +0xD240D42A, 0x420B65F2, 0xD131ED01, 0xAF304D18, +0x65F221D2, 0x8553D43C, 0x620D6642, 0x89073262, +0xD13BD43A, 0x0009410B, 0xE601D73A, 0x2762AF1A, +0xD134D41E, 0x410B65F2, 0xD125ED01, 0xD637D436, +0x460B4D18, 0xAF0D21D2, 0x7F340009, 0x6EF64F26, +0x6CF66DF6, 0x6AF66BF6, 0x000B69F6, 0x4F2268F6, +0x85467FF4, 0x2F01E681, 0x666C8547, 0x854881F1, +0x81F2D209, 0x67F38542, 0x854381F3, 0x81F4E40C, +0x65636053, 0x420B81F5, 0x7F0C7540, 0x000B4F26, +0x00000009, 0x001C3D9C, 0x0020245C, 0x0011779A, +0x001C36F8, 0x001C3B9C, 0x001C3704, 0x0020352C, +0x002014A0, 0x0020391D, 0x0020391C, 0x00203918, +0x001C3D98, 0x001C3BB4, 0x001C5960, 0x001C3500, +0x001C3D30, 0x001C8960, 0x00203504, 0x001C3D00, +0x0020160C, 0x00117730, 0x00203920, 0x001C582C, +0x2000A000, 0x0000A000, 0x0011778C, 0x00117792, +0x00117788, 0x002014CC, 0x002038F4, 0x002034F4, +0x00201530, 0x001E2130, 0x00203D84, 0x002018A2, +0x2F962F86, 0x2FB62FA6, 0x2FD62FC6, 0x4F222FE6, +0xD19B7FEC, 0x2F12E000, 0x6103D49A, 0x1F4281F2, +0xDD9ADA99, 0xD69A6813, 0xE0014808, 0x460BDE99, +0x38EC4800, 0x65A21F03, 0x352052A1, 0xA23E8B01, +0x60510009, 0x8801C903, 0xA2388B01, 0x52530009, +0x32E0DE91, 0xD9918B10, 0x64A3490B, 0x4B0BDB90, +0xDE906403, 0xD791D690, 0xEC01D591, 0x2E02E100, +0x271026C0, 0x2502AFDF, 0xC8018551, 0xA1578B01, +0x62510009, 0x4200622D, 0x5E53366A, 0x85E2226D, +0xC903642C, 0x85E36603, 0x6053650D, 0x40214021, +0x4500C93F, 0x322A6703, 0x6053252D, 0xC901D17F, +0x60106C03, 0x8801D97F, 0xDB7F8B05, 0x2120E200, +0xCB0160B2, 0xD17D2B02, 0x88016011, 0x65A28B0A, +0x8D042448, 0x9B9E6251, 0xA00322B9, 0x919B2521, +0x2521221B, 0x37B3EB10, 0x2448895E, 0xD4738B07, +0x22286241, 0x60638903, 0xA05781F8, 0xD5706473, +0x46084608, 0x85E26273, 0x46006B50, 0x362C4200, +0x2BB8C910, 0x8F1F6463, 0x26686603, 0xD2698911, +0x062D6043, 0x4119616D, 0x6B0E6019, 0x81F820BD, +0x880160C3, 0x646C8F2C, 0x880F6073, 0xA0278B1B, +0xD2610009, 0x052D6043, 0x4119615D, 0x670E6019, +0x645C207D, 0x81F8A01C, 0x890F2668, 0x6043D25B, +0x6B5D052D, 0x60B94B19, 0x201D610E, 0x60C381F8, +0x8F0D8801, 0x6473645C, 0xEC00A00A, 0x6043D254, +0x625D052D, 0x60294219, 0x207D670E, 0x81F8645C, +0x880285F8, 0x85E1890A, 0x8D07C820, 0xE6DC6203, +0x60232269, 0x81E1A002, 0x644CE4FF, 0x6210D149, +0x89012228, 0x644CE4FF, 0x654DEBFF, 0x35B06BBC, +0xDB368B2B, 0x64A34B0B, 0x410BD135, 0x54036403, +0x85446E03, 0xC948DB40, 0xDC408808, 0xBEAE8B01, +0x64B3E502, 0x65E34C0B, 0xDB3DEC01, 0xD13D2DC2, +0x621260B2, 0x72017001, 0x21228805, 0x2B028F08, +0x666CE680, 0x6563D238, 0x7549E700, 0x6473420B, +0xA030D436, 0x7FFF0009, 0x85E28000, 0x20B9EBFC, +0x610381E2, 0x942A85E3, 0x62032049, 0x450885F8, +0x81E2201B, 0xC90160C3, 0x40084018, 0x40084008, +0x4000225B, 0x6023220B, 0x85E481E3, 0x4118E108, +0x81E4201B, 0xE40262A2, 0x20B98521, 0x67A28121, +0xCB016071, 0x85F82701, 0x89033042, 0xECE785E2, +0x81E220C9, 0x490BD41E, 0xA03B0009, 0x7E030009, +0x001C3D30, 0x00203D90, 0x00203504, 0x001E212C, +0x002033E8, 0x001C3D00, 0x00117780, 0x002014A0, +0x0020166C, 0x0011770C, 0x0020391C, 0x0020391D, +0x00203918, 0x002018A2, 0x001C36F8, 0x00203990, +0x00203DA0, 0x00203B84, 0x00203C04, 0x00203C84, +0x00203D04, 0x00203908, 0x002034FC, 0x002014CC, +0x00203994, 0x00203998, 0x0020245C, 0x00203D88, +0x00203D8C, 0x602262F2, 0x40094019, 0xC90F4009, +0x8B0B880A, 0x60E2DE8C, 0x40094019, 0xC90F4009, +0x8B038808, 0xCB0160A2, 0x2802A006, 0x65E2DE87, +0x2E527501, 0x286266A2, 0x52F366F2, 0x2622AE83, +0xD2838551, 0xDE83C802, 0xA0958B01, 0x420B0009, +0x4E0B64A3, 0x5E036403, 0x85E46503, 0x4918E908, +0xD77D209B, 0xE04C81E4, 0xDC7C0B7E, 0x7B01D97C, +0x61C207B6, 0x71016690, 0x8D062668, 0xD4792C12, +0x420BD279, 0xA070EB01, 0x62512DB2, 0x4B18EB0F, +0x22B9E102, 0x32104118, 0x85518B0F, 0x2029E2FC, +0x60518151, 0xCB0172E0, 0x85E12501, 0x202994A3, +0x85E481E1, 0xA0522049, 0x675181E4, 0x4719677D, +0x667E6779, 0x7701276D, 0x6903607C, 0x88014918, +0x25918F3E, 0x6B12D161, 0x21B27B01, 0x660D85E3, +0x40216063, 0xC93F4021, 0x6C034600, 0x262D322A, +0xC8016063, 0xDB5ED15D, 0x967D8901, 0xE6002C6B, +0x666C67CD, 0x40006063, 0x622D021D, 0x8D0E3270, +0x60436403, 0xE9FF021D, 0x8B013290, 0x01C5A007, +0x626C7601, 0x3292E904, 0x646C8BEB, 0x60434400, +0xD15004BD, 0x0B457401, 0x669D6911, 0x89073670, +0x602D6211, 0x890388FF, 0xE201DB4B, 0x2B2021C1, +0xECFC8551, 0x815120C9, 0xCB016051, 0xDC472501, +0x64A34C0B, 0x51F366F2, 0x85EF2612, 0x54F2D244, +0x650D420B, 0x0009ADE7, 0xE500DC42, 0x420B2C52, +0x4E0B64A3, 0x54036403, 0x85446E03, 0x6703E908, +0x65034918, 0x27998541, 0xDB323790, 0x8F0BD932, +0x6013610D, 0x8B07C820, 0xC9486053, 0x8B038808, +0xE501BD4D, 0x0009A005, 0x2128D233, 0xBD468901, +0x64B3E500, 0x490B65E3, 0xADBCEC01, 0x85F22DC2, +0x7001EE04, 0x31E7610D, 0x8D0281F2, 0xADA97A08, +0x7F140009, 0x6EF64F26, 0x6CF66DF6, 0x6AF66BF6, +0x000B69F6, 0xF7FF68F6, 0x2FE68000, 0xD2234F22, +0x60E36E22, 0x8D02C840, 0xBBF922E2, 0xE2400009, +0x2E284218, 0xBC048901, 0x60E30009, 0x8905C810, +0xD21CD41B, 0x0009420B, 0x0009BC03, 0xC80560E3, +0xBD6D8901, 0x60E30009, 0x8902C802, 0xAC004F26, +0x4F266EF6, 0x6EF6000B, 0x001C3D3C, 0x00117760, +0x002014A0, 0x0020166C, 0x00203494, 0x00203DA4, +0x00203908, 0x002034FC, 0x002014CC, 0x00203974, +0x0020397C, 0x00203970, 0x00203972, 0x00201530, +0x002018EE, 0x00203994, 0x00008000, 0x001C3510, +0x00203D98, 0x002018A2, 0x080A0C0E, 0x00020406, +0x1A1C1E20, 0x12141618, 0x2E303234, 0x26282A2C, +0x3A3C3E40, 0x6C625648, 0x41112F26, 0xE2208F18, +0x890B3123, 0x321CD204, 0xD1026220, 0x412B312C, +0x00090009, 0x00203412, 0x002033C8, 0x000BE000, +0x400062F6, 0x40004000, 0x40004000, 0x40004000, +0x62F6000B, 0x40004000, 0x40004000, 0x40004000, +0x40184000, 0x62F6000B, 0x40004000, 0x40004000, +0x40004000, 0x40284000, 0x62F6000B, 0x40004000, +0x40184000, 0x000B4028, 0xC90F62F6, 0x40054005, +0x40054005, 0x62F6000B, 0x4005C907, 0x40054005, +0x62F6000B, 0x4005C903, 0x000B4005, 0xC90162F6, +0x000B4005, 0x000062F6, 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, 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, +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, 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, 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, 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, +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, 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, 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, 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, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x544F0D0A, 0x46205355, 0x00003A57, +0x206C754A, 0x32203120, 0x20383030, 0x323A3132, +0x34333A38, 0x00000000, 0x00000D0A, 0x00000043, +0x42707372, 0x3D206675, 0x554E203D, 0x202C4C4C, +0x6E49677A, 0x4E497274, 0x6D754E51, 0x0000003D, +0x61766E49, 0x2064696C, 0x72657375, 0x20726F20, +0x2079656B, 0x00214449, 0x52504545, 0x57204D4F, +0x65746972, 0x6461202C, 0x003D7264, 0x6C617620, +0x0000003D, 0x00000A0D, 0x435F4D5A, 0x465F444D, +0x4C445F57, 0x494E495F, 0x00000054, 0x6E6B6E55, +0x206E776F, 0x6D6D6F63, 0x3D646E61, 0x00000000, +0x203A3051, 0x00000020, 0x203A3151, 0x00000020, +0x203A3251, 0x00000020, 0x203A3351, 0x00000020, +0x203A3451, 0x00000020, 0x2B434741, 0x73696F4E, +0x61432065, 0x7262696C, 0x6F697461, 0x6166206E, +0x6F206C69, 0x6974206E, 0x0D0A656D, 0x00000000, +0x00000072, 0x00205220, 0x00000D0A, 0x62735576, +0x7473725F, 0x00000A0D, 0x62735576, 0x7375735F, +0x646E6570, 0x00000A0D, 0x62735576, 0x7365725F, +0x000A0D6D, 0x00000044, 0x44387570, 0x72637365, +0x6F747069, 0x3D584572, 0x00000000, 0x00000047, +0x00000042, 0x72746E49, 0x6D652051, 0x2C797470, +0x49677A20, 0x4972746E, 0x754E514E, 0x00003D6D, +0x654C7245, 0x0000006E, 0x00000049, 0x20746F4E, +0x756F6E65, 0x49206867, 0x4220514E, 0x0A0D6675, +0x00000000, 0x000000FF, 0x00020001, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x010E010D, 0x00020003, 0x01090108, +0x0002010A, 0x02000003, 0x02020201, 0x02040203, +0x02060205, 0x02020200, 0x02040203, 0x020C020B, +0x020E020D, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x000000FF, 0x00020001, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x010E010D, 0x00020003, 0x01090108, +0x0002010A, 0x00030003, 0x02020201, 0x02040203, +0x02060205, 0x02020200, 0x02040203, 0x020C020B, +0x020E020D, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x010E010D, 0x00FF010F, 0x01090108, +0x010B010A, 0x0200010F, 0x02020201, 0x02040203, +0x02060205, 0x02020200, 0x02040203, 0x020C020B, +0x020E020D, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x010E010D, 0x00FF010F, 0x01090108, +0x010B010A, 0x010F010F, 0x02020201, 0x02040203, +0x02060205, 0x02020200, 0x02040203, 0x020C020B, +0x020E020D, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, +0x00FF00FF, 0x00205220, 0x00000046, 0x00000059, +0x73204142, 0x003D7165, 0x49544120, 0x0000204D, +0x00000000, 0x00000000, 0x002E0209, 0x80000101, +0x000409FA, 0x00FF0400, 0x05070000, 0x02000201, +0x82050700, 0x00020002, 0x03830507, 0x07010040, +0x40030405, 0x02090100, 0x0101002E, 0x09FA8000, +0x04000004, 0x000000FF, 0x02010507, 0x07000040, +0x40028205, 0x05070000, 0x00400383, 0x04050701, +0x00004002, 0x00000000, 0x00000000, 0x07090000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +0x00000000, 0x00000000, 0x00000000, 0x00000000, +}; + +const u32_t zcFwImageSize=15936; --- linux-2.6.28.orig/drivers/staging/otus/hal/hpfwuinit.c +++ linux-2.6.28/drivers/staging/otus/hal/hpfwuinit.c @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2007-2008 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "../80211core/cprecomp.h" + +const u32_t zcFwImage[] = { +0x0009000B, 0x7FFC4F22, 0xD695D494, 0x0009460B, +0xD494E570, 0x4518B01E, 0x89042008, 0xD690D492, +0x462B7F04, 0xB0124F26, 0xD2900009, 0x420BD490, +0xE6000009, 0x949AD58F, 0xC8406052, 0x2F028F03, +0x8FF93642, 0x7F047601, 0x000B4F26, 0xD28A0009, +0x0009422B, 0x2FD62FC6, 0x4F222FE6, 0xD6877FEC, +0x626061F3, 0x2F208461, 0x846280F1, 0x80F27110, +0x6D438463, 0x846480F3, 0x80F46413, 0x6C538465, +0x846680F5, 0x80F6E500, 0xD77D8467, 0x846880F7, +0x80F8EE04, 0x80F98469, 0x80FA846A, 0x80FB846B, +0x80FC846C, 0x80FD846D, 0x80FE846E, 0x80FF846F, +0x6653655C, 0x7501367C, 0x665C6260, 0x242036E3, +0x74018FF6, 0x66F32F16, 0xE7107604, 0xB00D65C3, +0x6E0364D3, 0xD46B7F04, 0x420BD26B, 0x60E36503, +0x4F267F14, 0x6DF66EF6, 0x6CF6000B, 0x2FB62FA6, +0x2FD62FC6, 0x4F222FE6, 0x3F3C933A, 0x4108E141, +0x31FCE200, 0x11733526, 0x21521162, 0x11418D02, +0xE0FFA098, 0x4A18EA01, 0x262066F3, 0x32A27201, +0x76018FFB, 0x6BE3EE00, 0xE0446CF3, 0x00FE4008, +0x450BD556, 0x660361B3, 0x4008E043, 0x6DC004FE, +0x014C6063, 0x31EC3EDC, 0x60E36E1C, 0x7B0107FC, +0x2C703BA2, 0x8FE80FD4, 0xE0427C01, 0xEB004008, +0x70FC07FE, 0x6EB36CB3, 0xA0200AFE, 0x2710EDFF, +0x7C01FEE0, 0x60C36CCC, 0x657002FC, 0x6BBC3B2C, +0x01FC60B3, 0x0F1460C3, 0x0F2460B3, 0x04FC60C3, +0x342C7E01, 0x01FC604C, 0x251A62D3, 0xD43C225A, +0x2750602C, 0x064E4008, 0x2D6A4D19, 0x3EA27701, +0x66D78BDF, 0x4018E001, 0x0F646563, 0x70014519, +0x0F544629, 0x0F647001, 0x70014619, 0x90420F64, +0xE0450EFE, 0xEA014008, 0xE0460FF6, 0x4A184008, +0xED0067F3, 0x0FF637AC, 0x0FF67004, 0xE345E104, +0x7C014308, 0x6CCC33FC, 0x60C36432, 0x5531024C, +0x6BBC3B2C, 0x045C60B3, 0x60C35A32, 0x60B30A44, +0x60C30F24, 0x6A7006FC, 0x606C362C, 0x66E005FC, +0x6A5C64AC, 0x626C24AA, 0x89053420, 0x4D084D08, +0xCB0460D3, 0x600BA006, 0x7D014110, 0x8FD67701, +0xE0007E01, 0x3F3C9308, 0x6EF64F26, 0x6CF66DF6, +0x000B6BF6, 0x01386AF6, 0x00000120, 0x00200D54, +0x002002BE, 0x00102800, 0x00200D64, 0x0010F00A, +0x0010F000, 0x001C001C, 0x00103252, 0x00200DA0, +0x0010FFFC, 0x00200D7C, 0x0020032C, 0x00200370, +0x00200954, 0x0009000B, 0x2FD62FC6, 0x4F222FE6, +0x6D436C53, 0xEE00A004, 0x7E0164D4, 0x644CBFF2, +0x8BF93EC2, 0x6EF64F26, 0x000B6DF6, 0xE5006CF6, +0x6643A002, 0x76017501, 0x22286260, 0xAFE38BFA, +0x2FE60009, 0x75076253, 0xE1086753, 0x6043EE0A, +0x4409C90F, 0x650330E2, 0x8D014409, 0xE630E637, +0x4110365C, 0x8FF22760, 0xE00077FF, 0x000B8028, +0x4F226EF6, 0xBFE47FEC, 0xBFD865F3, 0x7F1464F3, +0x000B4F26, 0x4F22E000, 0xBFDA7FEC, 0x64F365F3, +0x7406BFCD, 0x4F267F14, 0xE000000B, 0x4F222FE6, +0x62537FEC, 0x65F36E43, 0x6423BFCB, 0x64E3BFBF, +0x64F3BFBD, 0xBFBAD403, 0x7F140009, 0x000B4F26, +0x00006EF6, 0x00200DB0, 0x89004011, 0x4111600B, +0x4F228906, 0x611BB004, 0x000B4F26, 0x0009600B, +0x620D2F26, 0x8F413020, 0x40180019, 0x8B0D3016, +0x31043104, 0x31043104, 0x31043104, 0x31043104, +0x890062F6, 0x4119310C, 0x6013000B, 0x41296219, +0x20084018, 0x31048927, 0x31043104, 0x31043104, +0x31043104, 0x31043104, 0x31043104, 0x31043104, +0x31043104, 0x61193104, 0x3204221D, 0x32043204, +0x32043204, 0x32043204, 0x32043204, 0x32043204, +0x32043204, 0x32043204, 0x89003204, 0x4229320C, +0x000B6023, 0xE00062F6, 0x62F6000B, 0x42286213, +0x42244129, 0x42243104, 0x42243104, 0x42243104, +0x42243104, 0x42243104, 0x42243104, 0x42243104, +0x42243104, 0x42243104, 0x42243104, 0x42243104, +0x42243104, 0x42243104, 0x42243104, 0x42243104, +0x89003104, 0x6013310C, 0x62F6000B, 0x2F262F16, +0x51F552F3, 0x52F22129, 0x52F41210, 0x212951F6, +0x121152F2, 0x000B62F6, 0x000061F6, 0x51F32F16, +0x310050F1, 0x51F48B02, 0x310050F2, 0x000B0029, +0x000061F6, 0x51F32F16, 0x310050F1, 0x51F48B06, +0x310050F2, 0xCA010029, 0x61F6000B, 0x000BE001, +0x000061F6, 0x50F0000B, 0x2F262F16, 0xE10052F2, +0x12001211, 0x000B62F6, 0x000061F6, 0x2F162F06, +0x8B264115, 0x3103E040, 0x2F26892B, 0x52F62F36, +0xE02053F5, 0x8B053103, 0xE3006233, 0x89093100, +0x3108A002, 0x8B0F2338, 0xD0064F22, 0x6023400B, +0x4F266203, 0x112151F4, 0x63F61130, 0x61F662F6, +0x60F6000B, 0x002007F4, 0x4100C709, 0x0123011D, +0x51F20009, 0x110150F4, 0x110050F3, 0x000B61F6, +0x51F260F6, 0x1101E000, 0x61F61100, 0x60F6000B, +0x01300000, 0x0128012C, 0x01200124, 0x0118011C, +0x0106010A, 0x00FE0102, 0x00E200E6, 0x00DA00DE, +0x00CC00D0, 0x00C400C8, 0x00A800AC, 0x00A000A4, +0x008C0090, 0x00840088, 0x0066006A, 0x005E0062, +0x42244300, 0x42244300, 0x42244300, 0x43286133, +0x43084318, 0x42284308, 0x42084218, 0x41094208, +0xAFAF4109, 0x4300221B, 0x43004224, 0x43004224, +0x61334224, 0x43184328, 0x42184228, 0xAFA14119, +0x4300221B, 0x43004224, 0x43004224, 0x61334224, +0x43084328, 0x42284308, 0x42084208, 0x41094119, +0xAF8F4109, 0x4300221B, 0x43004224, 0x43004224, +0x61334224, 0x212D4328, 0x6213AF84, 0x42244300, +0x42244300, 0x42244300, 0x43186133, 0x43084308, +0x42084218, 0x41294208, 0x41094109, 0x221BAF72, +0x42244300, 0x42244300, 0x42244300, 0x43186133, +0x41294218, 0xAF654119, 0x4300221B, 0x43004224, +0x43004224, 0x43004224, 0x43004224, 0x43004224, +0x43004224, 0x4224AF56, 0x2F162F06, 0x8B264115, +0x3103E040, 0x2F26892B, 0x52F62F36, 0xE02053F5, +0x8B053103, 0xE2006323, 0x89093100, 0x3108A002, +0x8B0F2228, 0xD0064F22, 0x6033400B, 0x4F266303, +0x112151F4, 0x63F61130, 0x61F662F6, 0x60F6000B, +0x002008B4, 0x4100C709, 0x0123011D, 0x51F20009, +0x110150F4, 0x110050F3, 0x000B61F6, 0x51F260F6, +0x1101E000, 0x61F61100, 0x60F6000B, 0x012E0000, +0x0126012A, 0x011E0122, 0x0116011A, 0x01040108, +0x00FC0100, 0x00E000E4, 0x00D800DC, 0x00CC00D0, +0x00C400C8, 0x00A800AC, 0x00A000A4, 0x008C0090, +0x00840088, 0x0066006A, 0x005E0062, 0x43254201, +0x43254201, 0x43254201, 0x42296123, 0x42094219, +0x43294209, 0x43094319, 0x41084309, 0xAFAF4108, +0x4201231B, 0x42014325, 0x42014325, 0x61234325, +0x42194229, 0x43194329, 0xAFA14118, 0x4201231B, +0x42014325, 0x42014325, 0x61234325, 0x42094229, +0x43294209, 0x43094309, 0x41084118, 0xAF8F4108, +0x4201231B, 0x42014325, 0x42014325, 0x61234325, +0xAF854229, 0x4201231D, 0x42014325, 0x42014325, +0x61234325, 0x42094219, 0x43194209, 0x43094309, +0x41084128, 0xAF734108, 0x4201231B, 0x42014325, +0x42014325, 0x61234325, 0x43194219, 0x41184128, +0x231BAF66, 0x43254201, 0x43254201, 0x43254201, +0x43254201, 0x43254201, 0x43254201, 0xAF574201, +0x00004325, 0x080A0C0E, 0x00020406, 0x1A1C1E20, +0x12141618, 0x2E303234, 0x26282A2C, 0x3A3C3E40, +0x6C625648, 0x41112F26, 0xE2208F18, 0x890B3123, +0x321CD204, 0xD1026220, 0x412B312C, 0x00090009, +0x0020081E, 0x002007D4, 0x000BE000, 0x400062F6, +0x40004000, 0x40004000, 0x40004000, 0x62F6000B, +0x40004000, 0x40004000, 0x40004000, 0x40184000, +0x62F6000B, 0x40004000, 0x40004000, 0x40004000, +0x40284000, 0x62F6000B, 0x40004000, 0x40184000, +0x000B4028, 0xC90F62F6, 0x40054005, 0x40054005, +0x62F6000B, 0x4005C907, 0x40054005, 0x62F6000B, +0x4005C903, 0x000B4005, 0xC90162F6, 0x000B4005, +0x000062F6, 0x080A0C0E, 0x00020406, 0x1A1C1E20, +0x12141618, 0x2E303234, 0x26282A2C, 0x3A3C3E40, +0x6C625648, 0x41112F26, 0xE2208F18, 0x890B3123, +0x321CD204, 0xD1026220, 0x412B312C, 0x00090009, +0x002008DE, 0x00200894, 0x000BE000, 0x400162F6, +0x40014001, 0x40014001, 0x40014001, 0x62F6000B, +0x40014001, 0x40014001, 0x40014001, 0x40194001, +0x62F6000B, 0x40014001, 0x40014001, 0x40014001, +0x40294001, 0x62F6000B, 0x40014001, 0x40194001, +0x000B4029, 0x400462F6, 0x40044004, 0xC90F4004, +0x62F6000B, 0x40044004, 0xC9074004, 0x62F6000B, +0x40044004, 0x000BC903, 0x400462F6, 0x000BC901, +0x000062F6, 0x00000000, 0x77073096, 0xEE0E612C, +0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, +0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, +0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, +0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, +0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, +0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, +0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, +0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, +0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, +0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, +0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, +0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, +0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, +0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, +0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, +0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, +0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, +0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, +0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, +0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, +0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, +0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, +0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, +0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, +0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, +0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, +0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, +0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, +0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, +0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, +0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, +0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, +0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, +0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, +0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, +0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, +0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, +0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, +0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, +0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, +0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, +0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, +0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, +0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, +0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, +0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, +0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, +0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, +0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, +0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, +0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, +0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, +0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, +0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, +0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, +0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, +0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, +0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, +0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, +0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, +0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, +0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, +0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, +0x2D02EF8D, 0x544F0D0A, 0x50205355, 0x20312D48, +0x003A5746, 0x72636564, 0x69747079, 0x65206E6F, +0x726F7272, 0x0A0D2121, 0x00000000, 0x6564667A, +0x70797263, 0x65725F74, 0x616C7567, 0x79726F74, +0x6261745F, 0x7220656C, 0x203D7465, 0x00000000, +0x45485441, 0x38731652, 0x89ACFF91, 0xEE55D178, +0xEE000D0A, }; + +const u32_t zcFwImageSize=3508; --- linux-2.6.28.orig/drivers/staging/go7007/go7007-v4l2.c +++ linux-2.6.28/drivers/staging/go7007/go7007-v4l2.c @@ -38,6 +38,14 @@ #include "go7007-priv.h" #include "wis-i2c.h" +/* Temporary defines until accepted in v4l-dvb */ +#ifndef V4L2_MPEG_STREAM_TYPE_MPEG_ELEM +#define V4L2_MPEG_STREAM_TYPE_MPEG_ELEM 6 /* MPEG elementary stream */ +#endif +#ifndef V4L2_MPEG_VIDEO_ENCODING_MPEG_4 +#define V4L2_MPEG_VIDEO_ENCODING_MPEG_4 3 +#endif + static void deactivate_buffer(struct go7007_buffer *gobuf) { int i; @@ -81,7 +89,7 @@ return 0; } -static int go7007_open(struct inode *inode, struct file *file) +static int go7007_open(struct file *file) { struct go7007 *go = video_get_drvdata(video_devdata(file)); struct go7007_file *gofh; @@ -99,7 +107,7 @@ return 0; } -static int go7007_release(struct inode *inode, struct file *file) +static int go7007_release(struct file *file) { struct go7007_file *gofh = file->private_data; struct go7007 *go = gofh->go; @@ -319,6 +327,7 @@ return 0; } +#if 0 static int clip_to_modet_map(struct go7007 *go, int region, struct v4l2_clip *clip_list) { @@ -375,499 +384,801 @@ return 0; } -static int go7007_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) +static int mpeg_queryctrl(u32 id, struct v4l2_queryctrl *ctrl) { - struct go7007_file *gofh = file->private_data; - struct go7007 *go = gofh->go; - unsigned long flags; - int retval = 0; - - switch (cmd) { - case VIDIOC_QUERYCAP: - { - struct v4l2_capability *cap = arg; - - memset(cap, 0, sizeof(*cap)); - strcpy(cap->driver, "go7007"); - strncpy(cap->card, go->name, sizeof(cap->card)); - cap->version = KERNEL_VERSION(0, 9, 8); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_STREAMING; /* | V4L2_CAP_AUDIO; */ - if (go->board_info->flags & GO7007_BOARD_HAS_TUNER) - cap->capabilities |= V4L2_CAP_TUNER; - return 0; + static const u32 user_ctrls[] = { + V4L2_CID_USER_CLASS, + 0 + }; + static const u32 mpeg_ctrls[] = { + V4L2_CID_MPEG_CLASS, + V4L2_CID_MPEG_STREAM_TYPE, + V4L2_CID_MPEG_VIDEO_ENCODING, + V4L2_CID_MPEG_VIDEO_ASPECT, + V4L2_CID_MPEG_VIDEO_GOP_SIZE, + V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, + V4L2_CID_MPEG_VIDEO_BITRATE, + 0 + }; + static const u32 *ctrl_classes[] = { + user_ctrls, + mpeg_ctrls, + NULL + }; + + /* The ctrl may already contain the queried i2c controls, + * query the mpeg controls if the existing ctrl id is + * greater than the next mpeg ctrl id. + */ + id = v4l2_ctrl_next(ctrl_classes, id); + if (id >= ctrl->id && ctrl->name[0]) + return 0; + + memset(ctrl, 0, sizeof(*ctrl)); + ctrl->id = id; + + switch (ctrl->id) { + case V4L2_CID_USER_CLASS: + case V4L2_CID_MPEG_CLASS: + return v4l2_ctrl_query_fill_std(ctrl); + case V4L2_CID_MPEG_STREAM_TYPE: + return v4l2_ctrl_query_fill(ctrl, + V4L2_MPEG_STREAM_TYPE_MPEG2_DVD, + V4L2_MPEG_STREAM_TYPE_MPEG_ELEM, 1, + V4L2_MPEG_STREAM_TYPE_MPEG_ELEM); + case V4L2_CID_MPEG_VIDEO_ENCODING: + return v4l2_ctrl_query_fill(ctrl, + V4L2_MPEG_VIDEO_ENCODING_MPEG_1, + V4L2_MPEG_VIDEO_ENCODING_MPEG_4, 1, + V4L2_MPEG_VIDEO_ENCODING_MPEG_2); + case V4L2_CID_MPEG_VIDEO_ASPECT: + return v4l2_ctrl_query_fill(ctrl, + V4L2_MPEG_VIDEO_ASPECT_1x1, + V4L2_MPEG_VIDEO_ASPECT_16x9, 1, + V4L2_MPEG_VIDEO_ASPECT_1x1); + case V4L2_CID_MPEG_VIDEO_GOP_SIZE: + case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: + return v4l2_ctrl_query_fill_std(ctrl); + case V4L2_CID_MPEG_VIDEO_BITRATE: + return v4l2_ctrl_query_fill(ctrl, + 64000, + 10000000, 1, + 9800000); + default: + break; } - case VIDIOC_ENUM_FMT: - { - struct v4l2_fmtdesc *fmt = arg; - unsigned int index; - char *desc; - u32 pixelformat; + return -EINVAL; +} + +static int mpeg_s_control(struct v4l2_control *ctrl, struct go7007 *go) +{ + /* pretty sure we can't change any of these while streaming */ + if (go->streaming) + return -EBUSY; - if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + switch (ctrl->id) { + case V4L2_CID_MPEG_STREAM_TYPE: + switch (ctrl->value) { + case V4L2_MPEG_STREAM_TYPE_MPEG2_DVD: + go->format = GO7007_FORMAT_MPEG2; + go->bitrate = 9800000; + go->gop_size = 15; + go->pali = 0x48; + go->closed_gop = 1; + go->repeat_seqhead = 0; + go->seq_header_enable = 1; + go->gop_header_enable = 1; + go->dvd_mode = 1; + break; + case V4L2_MPEG_STREAM_TYPE_MPEG_ELEM: + /* todo: */ + break; + default: return -EINVAL; - switch (fmt->index) { - case 0: - pixelformat = V4L2_PIX_FMT_MJPEG; - desc = "Motion-JPEG"; + } + break; + case V4L2_CID_MPEG_VIDEO_ENCODING: + switch (ctrl->value) { + case V4L2_MPEG_VIDEO_ENCODING_MPEG_1: + go->format = GO7007_FORMAT_MPEG1; + go->pali = 0; break; - case 1: - pixelformat = V4L2_PIX_FMT_MPEG; - desc = "MPEG1/MPEG2/MPEG4"; + case V4L2_MPEG_VIDEO_ENCODING_MPEG_2: + go->format = GO7007_FORMAT_MPEG2; + /*if (mpeg->pali >> 24 == 2) + go->pali = mpeg->pali & 0xff; + else*/ + go->pali = 0x48; + break; + case V4L2_MPEG_VIDEO_ENCODING_MPEG_4: + go->format = GO7007_FORMAT_MPEG4; + /*if (mpeg->pali >> 24 == 4) + go->pali = mpeg->pali & 0xff; + else*/ + go->pali = 0xf5; break; default: return -EINVAL; } - index = fmt->index; - memset(fmt, 0, sizeof(*fmt)); - fmt->index = index; - fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - fmt->flags = V4L2_FMT_FLAG_COMPRESSED; - strncpy(fmt->description, desc, sizeof(fmt->description)); - fmt->pixelformat = pixelformat; - - return 0; - } - case VIDIOC_TRY_FMT: - { - struct v4l2_format *fmt = arg; - - if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + go->gop_header_enable = + /*mpeg->flags & GO7007_MPEG_OMIT_GOP_HEADER + ? 0 :*/ 1; + /*if (mpeg->flags & GO7007_MPEG_REPEAT_SEQHEADER) + go->repeat_seqhead = 1; + else*/ + go->repeat_seqhead = 0; + go->dvd_mode = 0; + break; + case V4L2_CID_MPEG_VIDEO_ASPECT: + if (go->format == GO7007_FORMAT_MJPEG) return -EINVAL; - return set_capture_size(go, fmt, 1); - } - case VIDIOC_G_FMT: - { - struct v4l2_format *fmt = arg; - - if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + switch (ctrl->value) { + case V4L2_MPEG_VIDEO_ASPECT_1x1: + go->aspect_ratio = GO7007_RATIO_1_1; + break; + case V4L2_MPEG_VIDEO_ASPECT_4x3: + go->aspect_ratio = GO7007_RATIO_4_3; + break; + case V4L2_MPEG_VIDEO_ASPECT_16x9: + go->aspect_ratio = GO7007_RATIO_16_9; + break; + case V4L2_MPEG_VIDEO_ASPECT_221x100: + default: return -EINVAL; - memset(fmt, 0, sizeof(*fmt)); - fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - fmt->fmt.pix.width = go->width; - fmt->fmt.pix.height = go->height; - fmt->fmt.pix.pixelformat = go->format == GO7007_FORMAT_MJPEG ? - V4L2_PIX_FMT_MJPEG : V4L2_PIX_FMT_MPEG; - fmt->fmt.pix.field = V4L2_FIELD_NONE; - fmt->fmt.pix.bytesperline = 0; - fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE; - fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* ?? */ - return 0; - } - case VIDIOC_S_FMT: - { - struct v4l2_format *fmt = arg; - - if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + } + break; + case V4L2_CID_MPEG_VIDEO_GOP_SIZE: + go->gop_size = ctrl->value; + break; + case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: + if (ctrl->value != 0 && ctrl->value != 1) return -EINVAL; - if (go->streaming) - return -EBUSY; - return set_capture_size(go, fmt, 0); - } - case VIDIOC_G_FBUF: - case VIDIOC_S_FBUF: - return -EINVAL; - case VIDIOC_REQBUFS: - { - struct v4l2_requestbuffers *req = arg; - unsigned int count, i; - - if (go->streaming) - return -EBUSY; - if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - req->memory != V4L2_MEMORY_MMAP) + go->closed_gop = ctrl->value; + break; + case V4L2_CID_MPEG_VIDEO_BITRATE: + /* Upper bound is kind of arbitrary here */ + if (ctrl->value < 64000 || ctrl->value > 10000000) return -EINVAL; - - down(&gofh->lock); - retval = -EBUSY; - for (i = 0; i < gofh->buf_count; ++i) - if (gofh->bufs[i].mapped > 0) - goto unlock_and_return; - down(&go->hw_lock); - if (go->in_use > 0 && gofh->buf_count == 0) { - up(&go->hw_lock); - goto unlock_and_return; - } - if (gofh->buf_count > 0) - kfree(gofh->bufs); - retval = -ENOMEM; - count = req->count; - if (count > 0) { - if (count < 2) - count = 2; - if (count > 32) - count = 32; - gofh->bufs = kmalloc(count * - sizeof(struct go7007_buffer), - GFP_KERNEL); - if (gofh->bufs == NULL) { - up(&go->hw_lock); - goto unlock_and_return; - } - memset(gofh->bufs, 0, - count * sizeof(struct go7007_buffer)); - for (i = 0; i < count; ++i) { - gofh->bufs[i].go = go; - gofh->bufs[i].index = i; - gofh->bufs[i].state = BUF_STATE_IDLE; - gofh->bufs[i].mapped = 0; - } - go->in_use = 1; - } else { - go->in_use = 0; - } - gofh->buf_count = count; - up(&go->hw_lock); - up(&gofh->lock); - memset(req, 0, sizeof(*req)); - req->count = count; - req->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - req->memory = V4L2_MEMORY_MMAP; - return 0; + go->bitrate = ctrl->value; + break; + default: + return -EINVAL; } - case VIDIOC_QUERYBUF: - { - struct v4l2_buffer *buf = arg; - unsigned int index; + return 0; +} - retval = -EINVAL; - if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) +static int mpeg_g_control(struct v4l2_control *ctrl, struct go7007 *go) +{ + switch (ctrl->id) { + case V4L2_CID_MPEG_STREAM_TYPE: + if (go->dvd_mode) + ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_DVD; + else + ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG_ELEM; + break; + case V4L2_CID_MPEG_VIDEO_ENCODING: + switch (go->format) { + case GO7007_FORMAT_MPEG1: + ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_1; + break; + case GO7007_FORMAT_MPEG2: + ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_2; + break; + case GO7007_FORMAT_MPEG4: + ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_4; + break; + default: return -EINVAL; - index = buf->index; - down(&gofh->lock); - if (index >= gofh->buf_count) - goto unlock_and_return; - memset(buf, 0, sizeof(*buf)); - buf->index = index; - buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - switch (gofh->bufs[index].state) { - case BUF_STATE_QUEUED: - buf->flags = V4L2_BUF_FLAG_QUEUED; + } + break; + case V4L2_CID_MPEG_VIDEO_ASPECT: + switch (go->aspect_ratio) { + case GO7007_RATIO_1_1: + ctrl->value = V4L2_MPEG_VIDEO_ASPECT_1x1; break; - case BUF_STATE_DONE: - buf->flags = V4L2_BUF_FLAG_DONE; + case GO7007_RATIO_4_3: + ctrl->value = V4L2_MPEG_VIDEO_ASPECT_4x3; + break; + case GO7007_RATIO_16_9: + ctrl->value = V4L2_MPEG_VIDEO_ASPECT_16x9; break; default: - buf->flags = 0; + return -EINVAL; } - if (gofh->bufs[index].mapped) - buf->flags |= V4L2_BUF_FLAG_MAPPED; - buf->memory = V4L2_MEMORY_MMAP; - buf->m.offset = index * GO7007_BUF_SIZE; - buf->length = GO7007_BUF_SIZE; - up(&gofh->lock); + break; + case V4L2_CID_MPEG_VIDEO_GOP_SIZE: + ctrl->value = go->gop_size; + break; + case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: + ctrl->value = go->closed_gop; + break; + case V4L2_CID_MPEG_VIDEO_BITRATE: + ctrl->value = go->bitrate; + break; + default: + return -EINVAL; + } + return 0; +} +#endif - return 0; +static int vidioc_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; + + strlcpy(cap->driver, "go7007", sizeof(cap->driver)); + strlcpy(cap->card, go->name, sizeof(cap->card)); +#if 0 + strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info)); +#endif + + cap->version = KERNEL_VERSION(0, 9, 8); + + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_STREAMING; /* | V4L2_CAP_AUDIO; */ + + if (go->board_info->flags & GO7007_BOARD_HAS_TUNER) + cap->capabilities |= V4L2_CAP_TUNER; + + return 0; +} + +static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *fmt) +{ + char *desc = NULL; + + switch (fmt->index) { + case 0: + fmt->pixelformat = V4L2_PIX_FMT_MJPEG; + desc = "Motion-JPEG"; + break; + case 1: + fmt->pixelformat = V4L2_PIX_FMT_MPEG; + desc = "MPEG1/MPEG2/MPEG4"; + break; + default: + return -EINVAL; } - case VIDIOC_QBUF: - { - struct v4l2_buffer *buf = arg; - struct go7007_buffer *gobuf; - int ret; - - retval = -EINVAL; - if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || - buf->memory != V4L2_MEMORY_MMAP) - return -EINVAL; - down(&gofh->lock); - if (buf->index < 0 || buf->index >= gofh->buf_count) - goto unlock_and_return; - gobuf = &gofh->bufs[buf->index]; - if (gobuf->mapped == 0) - goto unlock_and_return; - retval = -EBUSY; - if (gobuf->state != BUF_STATE_IDLE) - goto unlock_and_return; - /* offset will be 0 until we really support USERPTR streaming */ - gobuf->offset = gobuf->user_addr & ~PAGE_MASK; - gobuf->bytesused = 0; - gobuf->frame_offset = 0; - gobuf->modet_active = 0; - if (gobuf->offset > 0) - gobuf->page_count = GO7007_BUF_PAGES + 1; - else - gobuf->page_count = GO7007_BUF_PAGES; - retval = -ENOMEM; - down_read(¤t->mm->mmap_sem); - ret = get_user_pages(current, current->mm, - gobuf->user_addr & PAGE_MASK, gobuf->page_count, - 1, 1, gobuf->pages, NULL); - up_read(¤t->mm->mmap_sem); - if (ret != gobuf->page_count) { - int i; - for (i = 0; i < ret; ++i) - page_cache_release(gobuf->pages[i]); - gobuf->page_count = 0; + fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + fmt->flags = V4L2_FMT_FLAG_COMPRESSED; + + strncpy(fmt->description, desc, sizeof(fmt->description)); + + return 0; +} + +static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *fmt) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; + + fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + fmt->fmt.pix.width = go->width; + fmt->fmt.pix.height = go->height; + fmt->fmt.pix.pixelformat = (go->format == GO7007_FORMAT_MJPEG) ? + V4L2_PIX_FMT_MJPEG : V4L2_PIX_FMT_MPEG; + fmt->fmt.pix.field = V4L2_FIELD_NONE; + fmt->fmt.pix.bytesperline = 0; + fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE; + fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; + + return 0; +} + +static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *fmt) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; + + return set_capture_size(go, fmt, 1); +} + +static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *fmt) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; + + if (go->streaming) + return -EBUSY; + + return set_capture_size(go, fmt, 0); +} + +static int vidioc_reqbufs(struct file *file, void *priv, + struct v4l2_requestbuffers *req) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; + int retval = -EBUSY; + unsigned int count, i; + + if (go->streaming) + return retval; + + if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + req->memory != V4L2_MEMORY_MMAP) + return -EINVAL; + + down(&gofh->lock); + for (i = 0; i < gofh->buf_count; ++i) + if (gofh->bufs[i].mapped > 0) goto unlock_and_return; - } - gobuf->state = BUF_STATE_QUEUED; - spin_lock_irqsave(&go->spinlock, flags); - list_add_tail(&gobuf->stream, &go->stream); - spin_unlock_irqrestore(&go->spinlock, flags); - up(&gofh->lock); - return 0; + + down(&go->hw_lock); + if (go->in_use > 0 && gofh->buf_count == 0) { + up(&go->hw_lock); + goto unlock_and_return; } - case VIDIOC_DQBUF: - { - struct v4l2_buffer *buf = arg; - struct go7007_buffer *gobuf; - u32 frame_type_flag; - DEFINE_WAIT(wait); - - if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - if (buf->memory != V4L2_MEMORY_MMAP) - return -EINVAL; - down(&gofh->lock); - retval = -EINVAL; - if (list_empty(&go->stream)) + + if (gofh->buf_count > 0) + kfree(gofh->bufs); + + retval = -ENOMEM; + count = req->count; + if (count > 0) { + if (count < 2) + count = 2; + if (count > 32) + count = 32; + + gofh->bufs = kmalloc(count * sizeof(struct go7007_buffer), + GFP_KERNEL); + + if (!gofh->bufs) { + up(&go->hw_lock); goto unlock_and_return; - gobuf = list_entry(go->stream.next, - struct go7007_buffer, stream); - retval = -EAGAIN; - if (gobuf->state != BUF_STATE_DONE && - !(file->f_flags & O_NONBLOCK)) { - for (;;) { - prepare_to_wait(&go->frame_waitq, &wait, - TASK_INTERRUPTIBLE); - if (gobuf->state == BUF_STATE_DONE) - break; - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } - schedule(); - } - finish_wait(&go->frame_waitq, &wait); } - if (gobuf->state != BUF_STATE_DONE) - goto unlock_and_return; - spin_lock_irqsave(&go->spinlock, flags); - deactivate_buffer(gobuf); - spin_unlock_irqrestore(&go->spinlock, flags); - frame_type_flag = get_frame_type_flag(gobuf, go->format); - gobuf->state = BUF_STATE_IDLE; - memset(buf, 0, sizeof(*buf)); - buf->index = gobuf->index; - buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - buf->bytesused = gobuf->bytesused; - buf->flags = V4L2_BUF_FLAG_MAPPED | frame_type_flag; - buf->field = V4L2_FIELD_NONE; - buf->timestamp = gobuf->timestamp; - buf->sequence = gobuf->seq; - buf->memory = V4L2_MEMORY_MMAP; - buf->m.offset = gobuf->index * GO7007_BUF_SIZE; - buf->length = GO7007_BUF_SIZE; - buf->reserved = gobuf->modet_active; - up(&gofh->lock); - return 0; - } - case VIDIOC_STREAMON: - { - unsigned int *type = arg; - if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - down(&gofh->lock); - down(&go->hw_lock); - if (!go->streaming) { - go->streaming = 1; - go->next_seq = 0; - go->active_buf = NULL; - if (go7007_start_encoder(go) < 0) - retval = -EIO; - else - retval = 0; + memset(gofh->bufs, 0, count * sizeof(struct go7007_buffer)); + + for (i = 0; i < count; ++i) { + gofh->bufs[i].go = go; + gofh->bufs[i].index = i; + gofh->bufs[i].state = BUF_STATE_IDLE; + gofh->bufs[i].mapped = 0; } - up(&go->hw_lock); - up(&gofh->lock); + + go->in_use = 1; + } else { + go->in_use = 0; + } + + gofh->buf_count = count; + up(&go->hw_lock); + up(&gofh->lock); + + memset(req, 0, sizeof(*req)); + + req->count = count; + req->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + req->memory = V4L2_MEMORY_MMAP; + + return 0; + +unlock_and_return: + up(&gofh->lock); + return retval; +} + +static int vidioc_querybuf(struct file *file, void *priv, + struct v4l2_buffer *buf) +{ + struct go7007_file *gofh = priv; + int retval = -EINVAL; + unsigned int index; + + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return retval; + + index = buf->index; + + down(&gofh->lock); + if (index >= gofh->buf_count) + goto unlock_and_return; + + memset(buf, 0, sizeof(*buf)); + buf->index = index; + buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + switch (gofh->bufs[index].state) { + case BUF_STATE_QUEUED: + buf->flags = V4L2_BUF_FLAG_QUEUED; + break; + case BUF_STATE_DONE: + buf->flags = V4L2_BUF_FLAG_DONE; + break; + default: + buf->flags = 0; } - case VIDIOC_STREAMOFF: - { - unsigned int *type = arg; - if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - down(&gofh->lock); - go7007_streamoff(go); - up(&gofh->lock); - return 0; + if (gofh->bufs[index].mapped) + buf->flags |= V4L2_BUF_FLAG_MAPPED; + buf->memory = V4L2_MEMORY_MMAP; + buf->m.offset = index * GO7007_BUF_SIZE; + buf->length = GO7007_BUF_SIZE; + up(&gofh->lock); + + return 0; + +unlock_and_return: + up(&gofh->lock); + return retval; +} + +static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; + struct go7007_buffer *gobuf; + unsigned long flags; + int retval = -EINVAL; + int ret; + + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + buf->memory != V4L2_MEMORY_MMAP) + return retval; + + down(&gofh->lock); + if (buf->index < 0 || buf->index >= gofh->buf_count) + goto unlock_and_return; + + gobuf = &gofh->bufs[buf->index]; + if (!gobuf->mapped) + goto unlock_and_return; + + retval = -EBUSY; + if (gobuf->state != BUF_STATE_IDLE) + goto unlock_and_return; + + /* offset will be 0 until we really support USERPTR streaming */ + gobuf->offset = gobuf->user_addr & ~PAGE_MASK; + gobuf->bytesused = 0; + gobuf->frame_offset = 0; + gobuf->modet_active = 0; + if (gobuf->offset > 0) + gobuf->page_count = GO7007_BUF_PAGES + 1; + else + gobuf->page_count = GO7007_BUF_PAGES; + + retval = -ENOMEM; + down_read(¤t->mm->mmap_sem); + ret = get_user_pages(current, current->mm, + gobuf->user_addr & PAGE_MASK, gobuf->page_count, + 1, 1, gobuf->pages, NULL); + up_read(¤t->mm->mmap_sem); + + if (ret != gobuf->page_count) { + int i; + for (i = 0; i < ret; ++i) + page_cache_release(gobuf->pages[i]); + gobuf->page_count = 0; + goto unlock_and_return; } - case VIDIOC_QUERYCTRL: - { - struct v4l2_queryctrl *ctrl = arg; - u32 id; - if (!go->i2c_adapter_online) - return -EIO; - id = ctrl->id; - memset(ctrl, 0, sizeof(*ctrl)); - ctrl->id = id; - i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, arg); - return ctrl->name[0] == 0 ? -EINVAL : 0; + gobuf->state = BUF_STATE_QUEUED; + spin_lock_irqsave(&go->spinlock, flags); + list_add_tail(&gobuf->stream, &go->stream); + spin_unlock_irqrestore(&go->spinlock, flags); + up(&gofh->lock); + + return 0; + +unlock_and_return: + up(&gofh->lock); + return retval; +} + + +static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; + struct go7007_buffer *gobuf; + int retval = -EINVAL; + unsigned long flags; + u32 frame_type_flag; + DEFINE_WAIT(wait); + + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return retval; + if (buf->memory != V4L2_MEMORY_MMAP) + return retval; + + down(&gofh->lock); + if (list_empty(&go->stream)) + goto unlock_and_return; + gobuf = list_entry(go->stream.next, + struct go7007_buffer, stream); + + retval = -EAGAIN; + if (gobuf->state != BUF_STATE_DONE && + !(file->f_flags & O_NONBLOCK)) { + for (;;) { + prepare_to_wait(&go->frame_waitq, &wait, + TASK_INTERRUPTIBLE); + if (gobuf->state == BUF_STATE_DONE) + break; + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } + schedule(); + } + finish_wait(&go->frame_waitq, &wait); } - case VIDIOC_G_CTRL: - { - struct v4l2_control *ctrl = arg; - struct v4l2_queryctrl query; + if (gobuf->state != BUF_STATE_DONE) + goto unlock_and_return; - if (!go->i2c_adapter_online) - return -EIO; - memset(&query, 0, sizeof(query)); - query.id = ctrl->id; - i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query); - if (query.name[0] == 0) - return -EINVAL; - i2c_clients_command(&go->i2c_adapter, VIDIOC_G_CTRL, arg); - return 0; + spin_lock_irqsave(&go->spinlock, flags); + deactivate_buffer(gobuf); + spin_unlock_irqrestore(&go->spinlock, flags); + frame_type_flag = get_frame_type_flag(gobuf, go->format); + gobuf->state = BUF_STATE_IDLE; + + memset(buf, 0, sizeof(*buf)); + buf->index = gobuf->index; + buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf->bytesused = gobuf->bytesused; + buf->flags = V4L2_BUF_FLAG_MAPPED | frame_type_flag; + buf->field = V4L2_FIELD_NONE; + buf->timestamp = gobuf->timestamp; + buf->sequence = gobuf->seq; + buf->memory = V4L2_MEMORY_MMAP; + buf->m.offset = gobuf->index * GO7007_BUF_SIZE; + buf->length = GO7007_BUF_SIZE; + buf->reserved = gobuf->modet_active; + + up(&gofh->lock); + return 0; + +unlock_and_return: + up(&gofh->lock); + return retval; +} + +static int vidioc_streamon(struct file *file, void *priv, + enum v4l2_buf_type type) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; + int retval = 0; + + if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + down(&gofh->lock); + down(&go->hw_lock); + + if (!go->streaming) { + go->streaming = 1; + go->next_seq = 0; + go->active_buf = NULL; + if (go7007_start_encoder(go) < 0) + retval = -EIO; + else + retval = 0; } - case VIDIOC_S_CTRL: - { - struct v4l2_control *ctrl = arg; - struct v4l2_queryctrl query; + up(&go->hw_lock); + up(&gofh->lock); + + return retval; +} + +static int vidioc_streamoff(struct file *file, void *priv, + enum v4l2_buf_type type) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; + + if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + down(&gofh->lock); + go7007_streamoff(go); + up(&gofh->lock); + + return 0; +} + +static int vidioc_queryctrl(struct file *file, void *priv, + struct v4l2_queryctrl *query) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; + + if (!go->i2c_adapter_online) + return -EIO; + + i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, query); + + return (!query->name[0]) ? -EINVAL : 0; +} + +static int vidioc_g_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; + struct v4l2_queryctrl query; + + if (!go->i2c_adapter_online) + return -EIO; + + memset(&query, 0, sizeof(query)); + query.id = ctrl->id; + i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query); + if (query.name[0] == 0) + return -EINVAL; + i2c_clients_command(&go->i2c_adapter, VIDIOC_G_CTRL, ctrl); + + return 0; +} + +static int vidioc_s_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; + struct v4l2_queryctrl query; + + if (!go->i2c_adapter_online) + return -EIO; + + memset(&query, 0, sizeof(query)); + query.id = ctrl->id; + i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query); + if (query.name[0] == 0) + return -EINVAL; + i2c_clients_command(&go->i2c_adapter, VIDIOC_S_CTRL, ctrl); + + return 0; +} + +static int vidioc_g_parm(struct file *filp, void *priv, + struct v4l2_streamparm *parm) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; + struct v4l2_fract timeperframe = { + .numerator = 1001 * go->fps_scale, + .denominator = go->sensor_framerate, + }; + + if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + parm->parm.capture.capability |= V4L2_CAP_TIMEPERFRAME; + parm->parm.capture.timeperframe = timeperframe; + + return 0; +} + +static int vidioc_s_parm(struct file *filp, void *priv, + struct v4l2_streamparm *parm) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; + unsigned int n, d; + + if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (parm->parm.capture.capturemode != 0) + return -EINVAL; + + n = go->sensor_framerate * + parm->parm.capture.timeperframe.numerator; + d = 1001 * parm->parm.capture.timeperframe.denominator; + if (n != 0 && d != 0 && n > d) + go->fps_scale = (n + d/2) / d; + else + go->fps_scale = 1; + + return 0; +} + +/* VIDIOC_ENUMSTD on go7007 were used for enumberating the supported fps and + its resolution, when the device is not connected to TV. + This were an API abuse, probably used by the lack of specific IOCTL's to + enumberate it, by the time the driver were written. + + However, since kernel 2.6.19, two new ioctls (VIDIOC_ENUM_FRAMEINTERVALS + and VIDIOC_ENUM_FRAMESIZES) were added for this purpose. + + The two functions bellow implements the newer ioctls +*/ +static int vidioc_enum_framesizes(struct file *filp, void *priv, + struct v4l2_frmsizeenum *fsize) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; + + /* Return -EINVAL, if it is a TV board */ + if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) || + (go->board_info->sensor_flags & GO7007_SENSOR_TV)) + return -EINVAL; + + if (fsize->index > 0) + return -EINVAL; + + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; + fsize->discrete.width = go->board_info->sensor_width; + fsize->discrete.height = go->board_info->sensor_height; + + return 0; +} + +static int vidioc_enum_frameintervals(struct file *filp, void *priv, + struct v4l2_frmivalenum *fival) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; + + /* Return -EINVAL, if it is a TV board */ + if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) || + (go->board_info->sensor_flags & GO7007_SENSOR_TV)) + return -EINVAL; + + if (fival->index > 0) + return -EINVAL; + + fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; + fival->discrete.numerator = 1001; + fival->discrete.denominator = go->board_info->sensor_framerate; + + return 0; +} + +static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; + + if (go->streaming) + return -EBUSY; + + if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV) && + *std != 0) + return -EINVAL; + + if (*std == 0) + return -EINVAL; + if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) && + go->input == go->board_info->num_inputs - 1) { if (!go->i2c_adapter_online) return -EIO; - memset(&query, 0, sizeof(query)); - query.id = ctrl->id; - i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query); - if (query.name[0] == 0) + i2c_clients_command(&go->i2c_adapter, + VIDIOC_S_STD, std); + if (!*std) /* hack to indicate EINVAL from tuner */ return -EINVAL; - i2c_clients_command(&go->i2c_adapter, VIDIOC_S_CTRL, arg); - return 0; - } - case VIDIOC_G_PARM: - { - struct v4l2_streamparm *parm = arg; - struct v4l2_fract timeperframe = { - .numerator = 1001 * go->fps_scale, - .denominator = go->sensor_framerate, - }; - - if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - memset(parm, 0, sizeof(*parm)); - parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - parm->parm.capture.capability |= V4L2_CAP_TIMEPERFRAME; - parm->parm.capture.timeperframe = timeperframe; - return 0; } - case VIDIOC_S_PARM: - { - struct v4l2_streamparm *parm = arg; - unsigned int n, d; - if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - if (parm->parm.capture.capturemode != 0) - return -EINVAL; - n = go->sensor_framerate * - parm->parm.capture.timeperframe.numerator; - d = 1001 * parm->parm.capture.timeperframe.denominator; - if (n != 0 && d != 0 && n > d) - go->fps_scale = (n + d/2) / d; - else - go->fps_scale = 1; - return 0; - } - case VIDIOC_ENUMSTD: - { - struct v4l2_standard *std = arg; + if (*std & V4L2_STD_NTSC) { + go->standard = GO7007_STD_NTSC; + go->sensor_framerate = 30000; + } else if (*std & V4L2_STD_PAL) { + go->standard = GO7007_STD_PAL; + go->sensor_framerate = 25025; + } else if (*std & V4L2_STD_SECAM) { + go->standard = GO7007_STD_PAL; + go->sensor_framerate = 25025; + } else + return -EINVAL; - if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) && - go->input == go->board_info->num_inputs - 1) { - if (!go->i2c_adapter_online) - return -EIO; - i2c_clients_command(&go->i2c_adapter, - VIDIOC_ENUMSTD, arg); - if (!std->id) /* hack to indicate EINVAL from tuner */ - return -EINVAL; - } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV) { - switch (std->index) { - case 0: - v4l2_video_std_construct(std, - V4L2_STD_NTSC, "NTSC"); - break; - case 1: - v4l2_video_std_construct(std, - V4L2_STD_PAL | V4L2_STD_SECAM, - "PAL/SECAM"); - break; - default: - return -EINVAL; - } - } else { - if (std->index != 0) - return -EINVAL; - memset(std, 0, sizeof(*std)); - snprintf(std->name, sizeof(std->name), "%dx%d, %dfps", - go->board_info->sensor_width, - go->board_info->sensor_height, - go->board_info->sensor_framerate / 1000); - std->frameperiod.numerator = 1001; - std->frameperiod.denominator = - go->board_info->sensor_framerate; - } - return 0; - } - case VIDIOC_G_STD: - { - v4l2_std_id *std = arg; + if (go->i2c_adapter_online) + i2c_clients_command(&go->i2c_adapter, + VIDIOC_S_STD, std); + set_capture_size(go, NULL, 0); - if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) && - go->input == go->board_info->num_inputs - 1) { - if (!go->i2c_adapter_online) - return -EIO; - i2c_clients_command(&go->i2c_adapter, - VIDIOC_G_STD, arg); - } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV) { - if (go->standard == GO7007_STD_NTSC) - *std = V4L2_STD_NTSC; - else - *std = V4L2_STD_PAL | V4L2_STD_SECAM; - } else - *std = 0; - return 0; - } - case VIDIOC_S_STD: - { - v4l2_std_id *std = arg; + return 0; +} - if (go->streaming) - return -EBUSY; - if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV) && - *std != 0) - return -EINVAL; - if (*std == 0) - return -EINVAL; - if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) && - go->input == go->board_info->num_inputs - 1) { - if (!go->i2c_adapter_online) - return -EIO; - i2c_clients_command(&go->i2c_adapter, - VIDIOC_S_STD, arg); - if (!*std) /* hack to indicate EINVAL from tuner */ - return -EINVAL; - } - if (*std & V4L2_STD_NTSC) { - go->standard = GO7007_STD_NTSC; - go->sensor_framerate = 30000; - } else if (*std & V4L2_STD_PAL) { - go->standard = GO7007_STD_PAL; - go->sensor_framerate = 25025; - } else if (*std & V4L2_STD_SECAM) { - go->standard = GO7007_STD_PAL; - go->sensor_framerate = 25025; - } else - return -EINVAL; - if (go->i2c_adapter_online) - i2c_clients_command(&go->i2c_adapter, - VIDIOC_S_STD, std); - set_capture_size(go, NULL, 0); - return 0; - } +#if 0 case VIDIOC_QUERYSTD: { v4l2_std_id *std = arg; @@ -884,219 +1195,269 @@ *std = 0; return 0; } - case VIDIOC_ENUMINPUT: - { - struct v4l2_input *inp = arg; - int index; +#endif - if (inp->index >= go->board_info->num_inputs) - return -EINVAL; - index = inp->index; - memset(inp, 0, sizeof(*inp)); - inp->index = index; - strncpy(inp->name, go->board_info->inputs[index].name, - sizeof(inp->name)); - /* If this board has a tuner, it will be the last input */ - if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) && - index == go->board_info->num_inputs - 1) - inp->type = V4L2_INPUT_TYPE_TUNER; - else - inp->type = V4L2_INPUT_TYPE_CAMERA; - inp->audioset = 0; - inp->tuner = 0; - if (go->board_info->sensor_flags & GO7007_SENSOR_TV) - inp->std = V4L2_STD_NTSC | V4L2_STD_PAL | - V4L2_STD_SECAM; - else - inp->std = 0; - return 0; - } - case VIDIOC_G_INPUT: - { - int *input = arg; +static int vidioc_enum_input(struct file *file, void *priv, + struct v4l2_input *inp) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; - *input = go->input; - return 0; - } - case VIDIOC_S_INPUT: - { - int *input = arg; + if (inp->index >= go->board_info->num_inputs) + return -EINVAL; - if (*input >= go->board_info->num_inputs) - return -EINVAL; - if (go->streaming) - return -EBUSY; - go->input = *input; - if (go->i2c_adapter_online) { - i2c_clients_command(&go->i2c_adapter, VIDIOC_S_INPUT, - &go->board_info->inputs[*input].video_input); - i2c_clients_command(&go->i2c_adapter, VIDIOC_S_AUDIO, - &go->board_info->inputs[*input].audio_input); - } - return 0; - } - case VIDIOC_G_TUNER: - { - struct v4l2_tuner *t = arg; + strncpy(inp->name, go->board_info->inputs[inp->index].name, + sizeof(inp->name)); - if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) - return -EINVAL; - if (t->index != 0) - return -EINVAL; - if (!go->i2c_adapter_online) - return -EIO; - i2c_clients_command(&go->i2c_adapter, VIDIOC_G_TUNER, arg); - t->index = 0; - return 0; - } - case VIDIOC_S_TUNER: - { - struct v4l2_tuner *t = arg; + /* If this board has a tuner, it will be the last input */ + if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) && + inp->index == go->board_info->num_inputs - 1) + inp->type = V4L2_INPUT_TYPE_TUNER; + else + inp->type = V4L2_INPUT_TYPE_CAMERA; + + inp->audioset = 0; + inp->tuner = 0; + if (go->board_info->sensor_flags & GO7007_SENSOR_TV) + inp->std = V4L2_STD_NTSC | V4L2_STD_PAL | + V4L2_STD_SECAM; + else + inp->std = 0; - if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) - return -EINVAL; - if (t->index != 0) - return -EINVAL; - if (!go->i2c_adapter_online) - return -EIO; - switch (go->board_id) { - case GO7007_BOARDID_PX_TV402U_NA: - case GO7007_BOARDID_PX_TV402U_JP: - /* No selectable options currently */ - if (t->audmode != V4L2_TUNER_MODE_STEREO) - return -EINVAL; - break; - } - i2c_clients_command(&go->i2c_adapter, VIDIOC_S_TUNER, arg); - return 0; - } - case VIDIOC_G_FREQUENCY: - { - struct v4l2_frequency *f = arg; + return 0; +} - if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) - return -EINVAL; - if (!go->i2c_adapter_online) - return -EIO; - memset(f, 0, sizeof(*f)); - f->type = V4L2_TUNER_ANALOG_TV; - i2c_clients_command(&go->i2c_adapter, VIDIOC_G_FREQUENCY, arg); - return 0; - } - case VIDIOC_S_FREQUENCY: - { - if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) - return -EINVAL; - if (!go->i2c_adapter_online) - return -EIO; - i2c_clients_command(&go->i2c_adapter, VIDIOC_S_FREQUENCY, arg); - return 0; - } - case VIDIOC_CROPCAP: - { - struct v4l2_cropcap *cropcap = arg; - if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - memset(cropcap, 0, sizeof(*cropcap)); - cropcap->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - /* These specify the raw input of the sensor */ - switch (go->standard) { - case GO7007_STD_NTSC: - cropcap->bounds.top = 0; - cropcap->bounds.left = 0; - cropcap->bounds.width = 720; - cropcap->bounds.height = 480; - cropcap->defrect.top = 0; - cropcap->defrect.left = 0; - cropcap->defrect.width = 720; - cropcap->defrect.height = 480; - break; - case GO7007_STD_PAL: - cropcap->bounds.top = 0; - cropcap->bounds.left = 0; - cropcap->bounds.width = 720; - cropcap->bounds.height = 576; - cropcap->defrect.top = 0; - cropcap->defrect.left = 0; - cropcap->defrect.width = 720; - cropcap->defrect.height = 576; - break; - case GO7007_STD_OTHER: - cropcap->bounds.top = 0; - cropcap->bounds.left = 0; - cropcap->bounds.width = go->board_info->sensor_width; - cropcap->bounds.height = go->board_info->sensor_height; - cropcap->defrect.top = 0; - cropcap->defrect.left = 0; - cropcap->defrect.width = go->board_info->sensor_width; - cropcap->defrect.height = go->board_info->sensor_height; - break; - } +static int vidioc_g_input(struct file *file, void *priv, unsigned int *input) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; - return 0; - } - case VIDIOC_G_CROP: - { - struct v4l2_crop *crop = arg; + *input = go->input; - if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - memset(crop, 0, sizeof(*crop)); - crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - /* These specify the raw input of the sensor */ - switch (go->standard) { - case GO7007_STD_NTSC: - crop->c.top = 0; - crop->c.left = 0; - crop->c.width = 720; - crop->c.height = 480; - break; - case GO7007_STD_PAL: - crop->c.top = 0; - crop->c.left = 0; - crop->c.width = 720; - crop->c.height = 576; - break; - case GO7007_STD_OTHER: - crop->c.top = 0; - crop->c.left = 0; - crop->c.width = go->board_info->sensor_width; - crop->c.height = go->board_info->sensor_height; - break; - } + return 0; +} - return 0; +static int vidioc_s_input(struct file *file, void *priv, unsigned int input) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; + + if (input >= go->board_info->num_inputs) + return -EINVAL; + if (go->streaming) + return -EBUSY; + + go->input = input; + if (go->i2c_adapter_online) { + i2c_clients_command(&go->i2c_adapter, VIDIOC_S_INPUT, + &go->board_info->inputs[input].video_input); + i2c_clients_command(&go->i2c_adapter, VIDIOC_S_AUDIO, + &go->board_info->inputs[input].audio_input); } - case VIDIOC_S_CROP: - { - struct v4l2_crop *crop = arg; - if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return 0; +} + +static int vidioc_g_tuner(struct file *file, void *priv, + struct v4l2_tuner *t) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; + + if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) + return -EINVAL; + if (t->index != 0) + return -EINVAL; + if (!go->i2c_adapter_online) + return -EIO; + + i2c_clients_command(&go->i2c_adapter, VIDIOC_G_TUNER, t); + + t->index = 0; + return 0; +} + +static int vidioc_s_tuner(struct file *file, void *priv, + struct v4l2_tuner *t) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; + + if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) + return -EINVAL; + if (t->index != 0) + return -EINVAL; + if (!go->i2c_adapter_online) + return -EIO; + + switch (go->board_id) { + case GO7007_BOARDID_PX_TV402U_NA: + case GO7007_BOARDID_PX_TV402U_JP: + /* No selectable options currently */ + if (t->audmode != V4L2_TUNER_MODE_STEREO) return -EINVAL; - return 0; + break; } - case VIDIOC_G_JPEGCOMP: - { - struct v4l2_jpegcompression *params = arg; - memset(params, 0, sizeof(*params)); - params->quality = 50; /* ?? */ - params->jpeg_markers = V4L2_JPEG_MARKER_DHT | - V4L2_JPEG_MARKER_DQT; + i2c_clients_command(&go->i2c_adapter, VIDIOC_S_TUNER, t); - return 0; + return 0; +} + +static int vidioc_g_frequency(struct file *file, void *priv, + struct v4l2_frequency *f) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; + + if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) + return -EINVAL; + if (!go->i2c_adapter_online) + return -EIO; + + f->type = V4L2_TUNER_ANALOG_TV; + i2c_clients_command(&go->i2c_adapter, VIDIOC_G_FREQUENCY, f); + return 0; +} + +static int vidioc_s_frequency(struct file *file, void *priv, + struct v4l2_frequency *f) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; + + if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) + return -EINVAL; + if (!go->i2c_adapter_online) + return -EIO; + + i2c_clients_command(&go->i2c_adapter, VIDIOC_S_FREQUENCY, f); + + return 0; +} + +static int vidioc_cropcap(struct file *file, void *priv, + struct v4l2_cropcap *cropcap) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; + + if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + /* These specify the raw input of the sensor */ + switch (go->standard) { + case GO7007_STD_NTSC: + cropcap->bounds.top = 0; + cropcap->bounds.left = 0; + cropcap->bounds.width = 720; + cropcap->bounds.height = 480; + cropcap->defrect.top = 0; + cropcap->defrect.left = 0; + cropcap->defrect.width = 720; + cropcap->defrect.height = 480; + break; + case GO7007_STD_PAL: + cropcap->bounds.top = 0; + cropcap->bounds.left = 0; + cropcap->bounds.width = 720; + cropcap->bounds.height = 576; + cropcap->defrect.top = 0; + cropcap->defrect.left = 0; + cropcap->defrect.width = 720; + cropcap->defrect.height = 576; + break; + case GO7007_STD_OTHER: + cropcap->bounds.top = 0; + cropcap->bounds.left = 0; + cropcap->bounds.width = go->board_info->sensor_width; + cropcap->bounds.height = go->board_info->sensor_height; + cropcap->defrect.top = 0; + cropcap->defrect.left = 0; + cropcap->defrect.width = go->board_info->sensor_width; + cropcap->defrect.height = go->board_info->sensor_height; + break; } - case VIDIOC_S_JPEGCOMP: - { - struct v4l2_jpegcompression *params = arg; - if (params->quality != 50 || - params->jpeg_markers != (V4L2_JPEG_MARKER_DHT | - V4L2_JPEG_MARKER_DQT)) - return -EINVAL; - return 0; + return 0; +} + +static int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop) +{ + struct go7007_file *gofh = priv; + struct go7007 *go = gofh->go; + + if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + /* These specify the raw input of the sensor */ + switch (go->standard) { + case GO7007_STD_NTSC: + crop->c.top = 0; + crop->c.left = 0; + crop->c.width = 720; + crop->c.height = 480; + break; + case GO7007_STD_PAL: + crop->c.top = 0; + crop->c.left = 0; + crop->c.width = 720; + crop->c.height = 576; + break; + case GO7007_STD_OTHER: + crop->c.top = 0; + crop->c.left = 0; + crop->c.width = go->board_info->sensor_width; + crop->c.height = go->board_info->sensor_height; + break; } + + return 0; +} + +/* FIXME: vidioc_s_crop is not really implemented!!! + */ +static int vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop) +{ + if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + return 0; +} + +static int vidioc_g_jpegcomp(struct file *file, void *priv, + struct v4l2_jpegcompression *params) +{ + memset(params, 0, sizeof(*params)); + params->quality = 50; /* ?? */ + params->jpeg_markers = V4L2_JPEG_MARKER_DHT | + V4L2_JPEG_MARKER_DQT; + + return 0; +} + +static int vidioc_s_jpegcomp(struct file *file, void *priv, + struct v4l2_jpegcompression *params) +{ + if (params->quality != 50 || + params->jpeg_markers != (V4L2_JPEG_MARKER_DHT | + V4L2_JPEG_MARKER_DQT)) + return -EINVAL; + + return 0; +} + +/* FIXME: + Those ioctls are private, and not needed, since several standard + extended controls already provide streaming control. + So, those ioctls should be converted into vidioc_g_ext_ctrls() + and vidioc_s_ext_ctrls() + */ + +#if 0 /* Temporary ioctls for controlling compression characteristics */ case GO7007IOC_S_BITRATE: { @@ -1316,27 +1677,7 @@ return -EINVAL; return clip_to_modet_map(go, region->region, region->clips); } - default: - printk(KERN_DEBUG "go7007: unsupported ioctl %d\n", cmd); - return -ENOIOCTLCMD; - } - return 0; - -unlock_and_return: - up(&gofh->lock); - return retval; -} - -static int go7007_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct go7007_file *gofh = file->private_data; - - if (gofh->go->status != STATUS_ONLINE) - return -EIO; - - return video_usercopy(inode, file, cmd, arg, go7007_do_ioctl); -} +#endif static ssize_t go7007_read(struct file *file, char __user *data, size_t count, loff_t *ppos) @@ -1371,8 +1712,7 @@ page = alloc_page(GFP_USER | __GFP_DMA32); if (!page) return VM_FAULT_OOM; - clear_user_page(page_address(page), (unsigned long)vmf->virtual_address, - page); + clear_user_highpage(page, (unsigned long)vmf->virtual_address); vmf->page = page; return 0; } @@ -1441,23 +1781,59 @@ kfree(go); } -static struct file_operations go7007_fops = { +static struct v4l2_file_operations go7007_fops = { .owner = THIS_MODULE, .open = go7007_open, .release = go7007_release, - .ioctl = go7007_ioctl, - .llseek = no_llseek, + .ioctl = video_ioctl2, .read = go7007_read, .mmap = go7007_mmap, .poll = go7007_poll, }; +static const struct v4l2_ioctl_ops video_ioctl_ops = { + .vidioc_querycap = vidioc_querycap, + .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, + .vidioc_reqbufs = vidioc_reqbufs, + .vidioc_querybuf = vidioc_querybuf, + .vidioc_qbuf = vidioc_qbuf, + .vidioc_dqbuf = vidioc_dqbuf, + .vidioc_s_std = vidioc_s_std, + .vidioc_enum_input = vidioc_enum_input, + .vidioc_g_input = vidioc_g_input, + .vidioc_s_input = vidioc_s_input, + .vidioc_queryctrl = vidioc_queryctrl, + .vidioc_g_ctrl = vidioc_g_ctrl, + .vidioc_s_ctrl = vidioc_s_ctrl, + .vidioc_streamon = vidioc_streamon, + .vidioc_streamoff = vidioc_streamoff, + .vidioc_g_tuner = vidioc_g_tuner, + .vidioc_s_tuner = vidioc_s_tuner, + .vidioc_g_frequency = vidioc_g_frequency, + .vidioc_s_frequency = vidioc_s_frequency, + .vidioc_g_parm = vidioc_g_parm, + .vidioc_s_parm = vidioc_s_parm, + .vidioc_enum_framesizes = vidioc_enum_framesizes, + .vidioc_enum_frameintervals = vidioc_enum_frameintervals, + .vidioc_cropcap = vidioc_cropcap, + .vidioc_g_crop = vidioc_g_crop, + .vidioc_s_crop = vidioc_s_crop, + .vidioc_g_jpegcomp = vidioc_g_jpegcomp, + .vidioc_s_jpegcomp = vidioc_s_jpegcomp, +}; + static struct video_device go7007_template = { .name = "go7007", .vfl_type = VID_TYPE_CAPTURE, .fops = &go7007_fops, .minor = -1, .release = go7007_vfl_release, + .ioctl_ops = &video_ioctl_ops, + .tvnorms = V4L2_STD_ALL, + .current_norm = V4L2_STD_NTSC, }; int go7007_v4l2_init(struct go7007 *go) @@ -1477,6 +1853,8 @@ } video_set_drvdata(go->video_dev, go); ++go->ref_count; + printk(KERN_INFO "%s: registered device video%d [v4l2]\n", + go->video_dev->name, go->video_dev->num); return 0; } --- linux-2.6.28.orig/drivers/staging/go7007/go7007-driver.c +++ linux-2.6.28/drivers/staging/go7007/go7007-driver.c @@ -217,6 +217,9 @@ case I2C_DRIVERID_WIS_OV7640: modname = "wis-ov7640"; break; + case I2C_DRIVERID_S2250: + modname = "s2250-board"; + break; default: modname = NULL; break; @@ -227,7 +230,7 @@ return 0; if (modname != NULL) printk(KERN_INFO - "go7007: probing for module %s failed", modname); + "go7007: probing for module %s failed\n", modname); else printk(KERN_INFO "go7007: sensor %u seems to be unsupported!\n", id); --- linux-2.6.28.orig/drivers/staging/go7007/s2250-board.c +++ linux-2.6.28/drivers/staging/go7007/s2250-board.c @@ -0,0 +1,630 @@ +/* + * Copyright (C) 2008 Sensoray Company 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You 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 "go7007-priv.h" +#include "wis-i2c.h" + +extern int s2250loader_init(void); +extern void s2250loader_cleanup(void); + +#define TLV320_ADDRESS 0x34 +#define S2250_VIDDEC 0x86 +#define VPX322_ADDR_ANALOGCONTROL1 0x02 +#define VPX322_ADDR_BRIGHTNESS0 0x0127 +#define VPX322_ADDR_BRIGHTNESS1 0x0131 +#define VPX322_ADDR_CONTRAST0 0x0128 +#define VPX322_ADDR_CONTRAST1 0x0132 +#define VPX322_ADDR_HUE 0x00dc +#define VPX322_ADDR_SAT 0x0030 + +struct go7007_usb_board { + unsigned int flags; + struct go7007_board_info main_info; +}; + +struct go7007_usb { + struct go7007_usb_board *board; + struct semaphore i2c_lock; + struct usb_device *usbdev; + struct urb *video_urbs[8]; + struct urb *audio_urbs[8]; + struct urb *intr_urb; +}; + +static unsigned char aud_regs[] = { + 0x1e, 0x00, + 0x00, 0x17, + 0x02, 0x17, + 0x04, 0xf9, + 0x06, 0xf9, + 0x08, 0x02, + 0x0a, 0x00, + 0x0c, 0x00, + 0x0a, 0x00, + 0x0c, 0x00, + 0x0e, 0x02, + 0x10, 0x00, + 0x12, 0x01, + 0x00, 0x00, +}; + + +static unsigned char vid_regs[] = { + 0xF2, 0x0f, + 0xAA, 0x00, + 0xF8, 0xff, + 0x00, 0x00, +}; + +static u16 vid_regs_fp[] = { + 0x028, 0x067, + 0x120, 0x016, + 0x121, 0xcF2, + 0x122, 0x0F2, + 0x123, 0x00c, + 0x124, 0x2d0, + 0x125, 0x2e0, + 0x126, 0x004, + 0x128, 0x1E0, + 0x12A, 0x016, + 0x12B, 0x0F2, + 0x12C, 0x0F2, + 0x12D, 0x00c, + 0x12E, 0x2d0, + 0x12F, 0x2e0, + 0x130, 0x004, + 0x132, 0x1E0, + 0x140, 0x060, + 0x153, 0x00C, + 0x154, 0x200, + 0x150, 0x801, + 0x000, 0x000 +}; + +/* PAL specific values */ +static u16 vid_regs_fp_pal[] = +{ + 0x120, 0x017, + 0x121, 0xd22, + 0x122, 0x122, + 0x12A, 0x017, + 0x12B, 0x122, + 0x12C, 0x122, + 0x140, 0x060, + 0x000, 0x000, +}; + +struct s2250 { + int std; + int input; + int brightness; + int contrast; + int saturation; + int hue; + int reg12b_val; + int audio_input; +}; + +/* from go7007-usb.c which is Copyright (C) 2005-2006 Micronas USA Inc.*/ +static int go7007_usb_vendor_request(struct go7007 *go, u16 request, + u16 value, u16 index, void *transfer_buffer, int length, int in) +{ + struct go7007_usb *usb = go->hpi_context; + int timeout = 5000; + + if (in) { + return usb_control_msg(usb->usbdev, + usb_rcvctrlpipe(usb->usbdev, 0), request, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, + value, index, transfer_buffer, length, timeout); + } else { + return usb_control_msg(usb->usbdev, + usb_sndctrlpipe(usb->usbdev, 0), request, + USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, index, transfer_buffer, length, timeout); + } +} +/* end from go7007-usb.c which is Copyright (C) 2005-2006 Micronas USA Inc.*/ + +static int write_reg(struct i2c_client *client, u8 reg, u8 value) +{ + struct go7007 *go = i2c_get_adapdata(client->adapter); + struct go7007_usb *usb = go->hpi_context; + int rc; + int dev_addr = client->addr; + u8 *buf; + + if (go == NULL) + return -ENODEV; + + if (go->status == STATUS_SHUTDOWN) + return -EBUSY; + + buf = kzalloc(16, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + + if (down_interruptible(&usb->i2c_lock) != 0) { + printk(KERN_INFO "i2c lock failed\n"); + return -EINTR; + } + rc = go7007_usb_vendor_request(go, 0x55, dev_addr, + (reg<<8 | value), + buf, + 16, 1); + + up(&usb->i2c_lock); + kfree(buf); + return rc; +} + +static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val) +{ + struct go7007 *go = i2c_get_adapdata(client->adapter); + struct go7007_usb *usb = go->hpi_context; + u8 *buf; + struct s2250 *dec = i2c_get_clientdata(client); + + if (go == NULL) + return -ENODEV; + + if (go->status == STATUS_SHUTDOWN) + return -EBUSY; + + buf = kzalloc(16, GFP_KERNEL); + + if (buf == NULL) + return -ENOMEM; + + + + memset(buf, 0xcd, 6); + + if (down_interruptible(&usb->i2c_lock) != 0) { + printk(KERN_INFO "i2c lock failed\n"); + return -EINTR; + } + if (go7007_usb_vendor_request(go, 0x57, addr, val, buf, 16, 1) < 0) + return -EFAULT; + + up(&usb->i2c_lock); + if (buf[0] == 0) { + unsigned int subaddr, val_read; + + subaddr = (buf[4] << 8) + buf[5]; + val_read = (buf[2] << 8) + buf[3]; + if (val_read != val) { + printk(KERN_INFO "invalid fp write %x %x\n", + val_read, val); + return -EFAULT; + } + if (subaddr != addr) { + printk(KERN_INFO "invalid fp write addr %x %x\n", + subaddr, addr); + return -EFAULT; + } + } else + return -EFAULT; + + /* save last 12b value */ + if (addr == 0x12b) + dec->reg12b_val = val; + + return 0; +} + +static int write_regs(struct i2c_client *client, u8 *regs) +{ + int i; + + for (i = 0; !((regs[i] == 0x00) && (regs[i+1] == 0x00)); i += 2) { + if (write_reg(client, regs[i], regs[i+1]) < 0) { + printk(KERN_INFO "s2250: failed\n"); + return -1; + } + } + return 0; +} + +static int write_regs_fp(struct i2c_client *client, u16 *regs) +{ + int i; + + for (i = 0; !((regs[i] == 0x00) && (regs[i+1] == 0x00)); i += 2) { + if (write_reg_fp(client, regs[i], regs[i+1]) < 0) { + printk(KERN_INFO "s2250: failed fp\n"); + return -1; + } + } + return 0; +} + + +static int s2250_command(struct i2c_client *client, + unsigned int cmd, void *arg) +{ + struct s2250 *dec = i2c_get_clientdata(client); + + switch (cmd) { + case VIDIOC_S_INPUT: + { + int vidsys; + int *input = arg; + + vidsys = (dec->std == V4L2_STD_NTSC) ? 0x01 : 0x00; + if (*input == 0) { + /* composite */ + write_reg_fp(client, 0x20, 0x020 | vidsys); + write_reg_fp(client, 0x21, 0x662); + write_reg_fp(client, 0x140, 0x060); + } else { + /* S-Video */ + write_reg_fp(client, 0x20, 0x040 | vidsys); + write_reg_fp(client, 0x21, 0x666); + write_reg_fp(client, 0x140, 0x060); + } + dec->input = *input; + break; + } + case VIDIOC_S_STD: + { + v4l2_std_id *std = arg; + u16 vidsource; + + vidsource = (dec->input == 1) ? 0x040 : 0x020; + dec->std = *std; + switch (dec->std) { + case V4L2_STD_NTSC: + write_regs_fp(client, vid_regs_fp); + write_reg_fp(client, 0x20, vidsource | 1); + break; + case V4L2_STD_PAL: + write_regs_fp(client, vid_regs_fp); + write_regs_fp(client, vid_regs_fp_pal); + write_reg_fp(client, 0x20, vidsource); + break; + default: + return -EINVAL; + } + break; + } + case VIDIOC_QUERYCTRL: + { + struct v4l2_queryctrl *ctrl = arg; + static const u32 user_ctrls[] = { + V4L2_CID_BRIGHTNESS, + V4L2_CID_CONTRAST, + V4L2_CID_SATURATION, + V4L2_CID_HUE, + 0 + }; + static const u32 *ctrl_classes[] = { + user_ctrls, + NULL + }; + + ctrl->id = v4l2_ctrl_next(ctrl_classes, ctrl->id); + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + v4l2_ctrl_query_fill(ctrl, 0, 100, 1, 50); + break; + case V4L2_CID_CONTRAST: + v4l2_ctrl_query_fill(ctrl, 0, 100, 1, 50); + break; + case V4L2_CID_SATURATION: + v4l2_ctrl_query_fill(ctrl, 0, 100, 1, 50); + break; + case V4L2_CID_HUE: + v4l2_ctrl_query_fill(ctrl, -50, 50, 1, 0); + break; + default: + ctrl->name[0] = '\0'; + return -EINVAL; + } + break; + } + case VIDIOC_S_CTRL: + { + struct v4l2_control *ctrl = arg; + int value1; + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + printk(KERN_INFO "s2250: future setting\n"); + return -EINVAL; + case V4L2_CID_CONTRAST: + printk(KERN_INFO "s2250: future setting\n"); + return -EINVAL; + break; + case V4L2_CID_SATURATION: + if (ctrl->value > 127) + dec->saturation = 127; + else if (ctrl->value < 0) + dec->saturation = 0; + else + dec->saturation = ctrl->value; + + value1 = dec->saturation * 4140 / 100; + if (value1 > 4094) + value1 = 4094; + write_reg_fp(client, VPX322_ADDR_SAT, value1); + break; + case V4L2_CID_HUE: + if (ctrl->value > 50) + dec->hue = 50; + else if (ctrl->value < -50) + dec->hue = -50; + else + dec->hue = ctrl->value; + /* clamp the hue range */ + value1 = dec->hue * 280 / 50; + write_reg_fp(client, VPX322_ADDR_HUE, value1); + break; + } + break; + } + case VIDIOC_G_CTRL: + { + struct v4l2_control *ctrl = arg; + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + ctrl->value = dec->brightness; + break; + case V4L2_CID_CONTRAST: + ctrl->value = dec->contrast; + break; + case V4L2_CID_SATURATION: + ctrl->value = dec->saturation; + break; + case V4L2_CID_HUE: + ctrl->value = dec->hue; + break; + } + break; + } + case VIDIOC_S_FMT: + { + struct v4l2_format *fmt = arg; + if (fmt->fmt.pix.height < 640) { + write_reg_fp(client, 0x12b, dec->reg12b_val | 0x400); + write_reg_fp(client, 0x140, 0x060); + } else { + write_reg_fp(client, 0x12b, dec->reg12b_val & ~0x400); + write_reg_fp(client, 0x140, 0x060); + } + return 0; + } + case VIDIOC_G_AUDIO: + { + struct v4l2_audio *audio = arg; + + memset(audio, 0, sizeof(*audio)); + audio->index = dec->audio_input; + /* fall through */ + } + case VIDIOC_ENUMAUDIO: + { + struct v4l2_audio *audio = arg; + + switch (audio->index) { + case 0: + strcpy(audio->name, "Line In"); + break; + case 1: + strcpy(audio->name, "Mic"); + break; + case 2: + strcpy(audio->name, "Mic Boost"); + break; + default: + audio->name[0] = '\0'; + return 0; + } + audio->capability = V4L2_AUDCAP_STEREO; + audio->mode = 0; + return 0; + } + case VIDIOC_S_AUDIO: + { + struct v4l2_audio *audio = arg; + + client->addr = TLV320_ADDRESS; + switch (audio->index) { + case 0: + write_reg(client, 0x08, 0x02); /* Line In */ + break; + case 1: + write_reg(client, 0x08, 0x04); /* Mic */ + break; + case 2: + write_reg(client, 0x08, 0x05); /* Mic Boost */ + break; + default: + return -EINVAL; + } + dec->audio_input = audio->index; + return 0; + } + + default: + printk(KERN_INFO "s2250: unknown command 0x%x\n", cmd); + break; + } + return 0; +} + +static struct i2c_driver s2250_driver; + +static struct i2c_client s2250_client_templ = { + .name = "Sensoray 2250", + .driver = &s2250_driver, +}; + +static int s2250_detect(struct i2c_adapter *adapter, int addr, int kind) +{ + struct i2c_client *client; + struct s2250 *dec; + u8 *data; + struct go7007 *go = i2c_get_adapdata(adapter); + struct go7007_usb *usb = go->hpi_context; + + client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (client == NULL) + return -ENOMEM; + memcpy(client, &s2250_client_templ, + sizeof(s2250_client_templ)); + client->adapter = adapter; + + dec = kmalloc(sizeof(struct s2250), GFP_KERNEL); + if (dec == NULL) { + kfree(client); + return -ENOMEM; + } + + dec->std = V4L2_STD_NTSC; + dec->brightness = 50; + dec->contrast = 50; + dec->saturation = 50; + dec->hue = 0; + client->addr = TLV320_ADDRESS; + i2c_set_clientdata(client, dec); + + printk(KERN_DEBUG + "s2250: initializing video decoder on %s\n", + adapter->name); + + /* initialize the audio */ + client->addr = TLV320_ADDRESS; + if (write_regs(client, aud_regs) < 0) { + printk(KERN_ERR + "s2250: error initializing audio\n"); + kfree(client); + kfree(dec); + return 0; + } + client->addr = S2250_VIDDEC; + i2c_set_clientdata(client, dec); + + if (write_regs(client, vid_regs) < 0) { + printk(KERN_ERR + "s2250: error initializing decoder\n"); + kfree(client); + kfree(dec); + return 0; + } + if (write_regs_fp(client, vid_regs_fp) < 0) { + printk(KERN_ERR + "s2250: error initializing decoder\n"); + kfree(client); + kfree(dec); + return 0; + } + /* set default channel */ + /* composite */ + write_reg_fp(client, 0x20, 0x020 | 1); + write_reg_fp(client, 0x21, 0x662); + write_reg_fp(client, 0x140, 0x060); + + /* set default audio input */ + dec->audio_input = 0; + write_reg(client, 0x08, 0x02); /* Line In */ + + if (down_interruptible(&usb->i2c_lock) == 0) { + data = kzalloc(16, GFP_KERNEL); + if (data != NULL) { + int rc; + rc = go7007_usb_vendor_request(go, 0x41, 0, 0, + data, 16, 1); + if (rc > 0) { + u8 mask; + data[0] = 0; + mask = 1<<5; + data[0] &= ~mask; + data[1] |= mask; + go7007_usb_vendor_request(go, 0x40, 0, + (data[1]<<8) + + data[1], + data, 16, 0); + } + kfree(data); + } + up(&usb->i2c_lock); + } + + i2c_attach_client(client); + printk("s2250: initialized successfully\n"); + return 0; +} + +static int s2250_detach(struct i2c_client *client) +{ + struct s2250 *dec = i2c_get_clientdata(client); + int r; + + r = i2c_detach_client(client); + if (r < 0) + return r; + + kfree(client); + kfree(dec); + return 0; +} + +static struct i2c_driver s2250_driver = { + .driver = { + .name = "Sensoray 2250 board driver", + }, + .id = I2C_DRIVERID_S2250, + .detach_client = s2250_detach, + .command = s2250_command, +}; + +static int __init s2250_init(void) +{ + int r; + + r = s2250loader_init(); + if (r < 0) + return r; + + r = i2c_add_driver(&s2250_driver); + if (r < 0) + return r; + return wis_i2c_add_driver(s2250_driver.id, s2250_detect); +} + +static void __exit s2250_cleanup(void) +{ + wis_i2c_del_driver(s2250_detect); + i2c_del_driver(&s2250_driver); + + s2250loader_cleanup(); +} + +module_init(s2250_init); +module_exit(s2250_cleanup); + +MODULE_AUTHOR(""); +MODULE_DESCRIPTION("Board driver for Sensoryray 2250"); +MODULE_LICENSE("GPL v2"); --- linux-2.6.28.orig/drivers/staging/go7007/Kconfig +++ linux-2.6.28/drivers/staging/go7007/Kconfig @@ -25,3 +25,13 @@ To compile this driver as a module, choose M here: the module will be called go7007-usb +config VIDEO_GO7007_USB_S2250_BOARD + tristate "Sensoray 2250/2251 support" + depends on VIDEO_GO7007_USB && DVB_USB + default N + ---help--- + This is a video4linux driver for the Sensoray 2250/2251 device + + To compile this driver as a module, choose M here: the + module will be called s2250-board + --- linux-2.6.28.orig/drivers/staging/go7007/wis-sony-tuner.c +++ linux-2.6.28/drivers/staging/go7007/wis-sony-tuner.c @@ -604,7 +604,7 @@ { struct v4l2_tuner *tun = arg; - memset(t, 0, sizeof(*tun)); + memset(tun, 0, sizeof(*tun)); strcpy(tun->name, "Television"); tun->type = V4L2_TUNER_ANALOG_TV; tun->rangelow = 0UL; /* does anything use these? */ --- linux-2.6.28.orig/drivers/staging/go7007/wis-i2c.h +++ linux-2.6.28/drivers/staging/go7007/wis-i2c.h @@ -23,6 +23,7 @@ #define I2C_DRIVERID_WIS_SAA7113 0xf0f4 #define I2C_DRIVERID_WIS_OV7640 0xf0f5 #define I2C_DRIVERID_WIS_TW2804 0xf0f6 +#define I2C_DRIVERID_S2250 0xf0f7 #define I2C_ALGO_GO7007 0xf00000 #define I2C_ALGO_GO7007_USB 0xf10000 --- linux-2.6.28.orig/drivers/staging/go7007/go7007-priv.h +++ linux-2.6.28/drivers/staging/go7007/go7007-priv.h @@ -40,6 +40,7 @@ #define GO7007_BOARDID_LIFEVIEW_LR192 21 /* TV Walker Ultra */ #define GO7007_BOARDID_ENDURA 22 #define GO7007_BOARDID_ADLINK_MPG24 23 +#define GO7007_BOARDID_SENSORAY_2250 24 /* Sensoray 2250/2251 */ /* Various characteristics of each board */ #define GO7007_BOARD_HAS_AUDIO (1<<0) @@ -104,6 +105,7 @@ int (*stream_start)(struct go7007 *go); int (*stream_stop)(struct go7007 *go); int (*send_firmware)(struct go7007 *go, u8 *data, int len); + int (*send_command)(struct go7007 *go, unsigned int cmd, void *arg); }; /* The video buffer size must be a multiple of PAGE_SIZE */ --- linux-2.6.28.orig/drivers/staging/go7007/go7007-usb.c +++ linux-2.6.28/drivers/staging/go7007/go7007-usb.c @@ -225,7 +225,7 @@ .inputs = { { .video_input = 1, - .audio_input = TVAUDIO_INPUT_EXTERN, + .audio_input = TVAUDIO_INPUT_EXTERN, .name = "Composite", }, { @@ -398,6 +398,41 @@ }, }; +static struct go7007_usb_board board_sensoray_2250 = { + .flags = GO7007_USB_EZUSB | GO7007_USB_EZUSB_I2C, + .main_info = { + .firmware = "go7007tv.bin", + .audio_flags = GO7007_AUDIO_I2S_MODE_1 | + GO7007_AUDIO_I2S_MASTER | + GO7007_AUDIO_WORD_16, + .flags = GO7007_BOARD_HAS_AUDIO, + .audio_rate = 48000, + .audio_bclk_div = 8, + .audio_main_div = 2, + .hpi_buffer_cap = 7, + .sensor_flags = GO7007_SENSOR_656 | + GO7007_SENSOR_TV, + .num_i2c_devs = 1, + .i2c_devs = { + { + .id = I2C_DRIVERID_S2250, + .addr = 0x34, + }, + }, + .num_inputs = 2, + .inputs = { + { + .video_input = 0, + .name = "Composite", + }, + { + .video_input = 1, + .name = "S-Video", + }, + }, + }, +}; + static struct usb_device_id go7007_usb_id_table[] = { { .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION | @@ -491,6 +526,14 @@ .bcdDevice_hi = 0x1, .driver_info = (kernel_ulong_t)GO7007_BOARDID_LIFEVIEW_LR192, }, + { + .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION, + .idVendor = 0x1943, /* Vendor ID Sensoray */ + .idProduct = 0x2250, /* Product ID of 2250/2251 */ + .bcdDevice_lo = 0x1, + .bcdDevice_hi = 0x1, + .driver_info = (kernel_ulong_t)GO7007_BOARDID_SENSORAY_2250, + }, { } /* Terminating entry */ }; @@ -637,9 +680,10 @@ { struct go7007 *go = (struct go7007 *)urb->context; u16 *regs = (u16 *)urb->transfer_buffer; + int status = urb->status; - if (urb->status != 0) { - if (urb->status != -ESHUTDOWN && + if (status) { + if (status != -ESHUTDOWN && go->status != STATUS_SHUTDOWN) { printk(KERN_ERR "go7007-usb: error in read interrupt: %d\n", @@ -680,15 +724,14 @@ static void go7007_usb_read_video_pipe_complete(struct urb *urb) { struct go7007 *go = (struct go7007 *)urb->context; - int r; + int r, status = urb-> status; if (!go->streaming) { wake_up_interruptible(&go->frame_waitq); return; } - if (urb->status != 0) { - printk(KERN_ERR "go7007-usb: error in video pipe: %d\n", - urb->status); + if (status) { + printk(KERN_ERR "go7007-usb: error in video pipe: %d\n", status); return; } if (urb->actual_length != urb->transfer_buffer_length) { @@ -704,13 +747,12 @@ static void go7007_usb_read_audio_pipe_complete(struct urb *urb) { struct go7007 *go = (struct go7007 *)urb->context; - int r; + int r, status = urb->status; if (!go->streaming) return; - if (urb->status != 0) { - printk(KERN_ERR "go7007-usb: error in audio pipe: %d\n", - urb->status); + if (status) { + printk(KERN_ERR "go7007-usb: error in audio pipe: %d\n", status); return; } if (urb->actual_length != urb->transfer_buffer_length) { @@ -751,7 +793,7 @@ return 0; audio_submit_failed: - for (i = 0; i < 8; ++i) + for (i = 0; i < 7; ++i) usb_kill_urb(usb->audio_urbs[i]); video_submit_failed: for (i = 0; i < 8; ++i) @@ -965,16 +1007,20 @@ name = "Lifeview TV Walker Ultra"; board = &board_lifeview_lr192; break; + case GO7007_BOARDID_SENSORAY_2250: + printk(KERN_INFO "Sensoray 2250 found\n"); + name = "Sensoray 2250/2251\n"; + board = &board_sensoray_2250; + break; default: printk(KERN_ERR "go7007-usb: unknown board ID %d!\n", (unsigned int)id->driver_info); return 0; } - usb = kmalloc(sizeof(struct go7007_usb), GFP_KERNEL); + usb = kzalloc(sizeof(struct go7007_usb), GFP_KERNEL); if (usb == NULL) return -ENOMEM; - memset(usb, 0, sizeof(struct go7007_usb)); /* Allocate the URB and buffer for receiving incoming interrupts */ usb->intr_urb = usb_alloc_urb(0, GFP_KERNEL); @@ -1179,6 +1225,7 @@ { struct go7007 *go = usb_get_intfdata(intf); struct go7007_usb *usb = go->hpi_context; + struct urb *vurb, *aurb; int i; go->status = STATUS_SHUTDOWN; @@ -1186,15 +1233,19 @@ /* Free USB-related structs */ for (i = 0; i < 8; ++i) { - if (usb->video_urbs[i] != NULL) { - if (usb->video_urbs[i]->transfer_buffer != NULL) - kfree(usb->video_urbs[i]->transfer_buffer); - usb_free_urb(usb->video_urbs[i]); - } - if (usb->audio_urbs[i] != NULL) { - if (usb->audio_urbs[i]->transfer_buffer != NULL) - kfree(usb->audio_urbs[i]->transfer_buffer); - usb_free_urb(usb->audio_urbs[i]); + vurb = usb->video_urbs[i]; + if (vurb) { + usb_kill_urb(vurb); + if (vurb->transfer_buffer) + kfree(vurb->transfer_buffer); + usb_free_urb(vurb); + } + aurb = usb->audio_urbs[i]; + if (aurb) { + usb_kill_urb(aurb); + if (aurb->transfer_buffer) + kfree(aurb->transfer_buffer); + usb_free_urb(aurb); } } kfree(usb->intr_urb->transfer_buffer); --- linux-2.6.28.orig/drivers/staging/go7007/go7007.txt +++ linux-2.6.28/drivers/staging/go7007/go7007.txt @@ -0,0 +1,481 @@ +This is a driver for the WIS GO7007SB multi-format video encoder. + +Pete Eberlein + +The driver was orignally released under the GPL and is currently hosted at: +http://nikosapi.org/wiki/index.php/WIS_Go7007_Linux_driver +The go7007 firmware can be acquired from the package on the site above. + +I've modified the driver to support the following Video4Linux2 MPEG +controls, with acceptable values: + +V4L2_CID_MPEG_STREAM_TYPE V4L2_MPEG_STREAM_TYPE_MPEG2_DVD + V4L2_MPEG_STREAM_TYPE_MPEG_ELEM +V4L2_CID_MPEG_VIDEO_ENCODING V4L2_MPEG_VIDEO_ENCODING_MPEG_1 + V4L2_MPEG_VIDEO_ENCODING_MPEG_2 + V4L2_MPEG_VIDEO_ENCODING_MPEG_4 +V4L2_CID_MPEG_VIDEO_ASPECT V4L2_MPEG_VIDEO_ASPECT_1x1 + V4L2_MPEG_VIDEO_ASPECT_4x3 + V4L2_MPEG_VIDEO_ASPECT_16x9 +V4L2_CID_MPEG_VIDEO_GOP_SIZE integer +V4L2_CID_MPEG_VIDEO_BITRATE 64000 .. 10000000 + +These should be used instead of the non-standard GO7007 ioctls described +below. + + +The README files from the orignal package appear below: + +--------------------------------------------------------------------------- + WIS GO7007SB Public Linux Driver +--------------------------------------------------------------------------- + + +*** Please see the file RELEASE-NOTES for important last-minute updates *** + + + 0. OVERVIEW AND LICENSING/DISCLAIMER + + +This driver kit contains Linux drivers for the WIS GO7007SB multi-format +video encoder. Only kernel version 2.6.x is supported. The video stream +is available through the Video4Linux2 API and the audio stream is available +through the ALSA API (or the OSS emulation layer of the ALSA system). + +The files in kernel/ and hotplug/ are licensed under the GNU General Public +License Version 2 from the Free Software Foundation. A copy of the license +is included in the file COPYING. + +The example applications in apps/ and C header files in include/ are +licensed under a permissive license included in the source files which +allows copying, modification and redistribution for any purpose without +attribution. + +The firmware files included in the firmware/ directory may be freely +redistributed only in conjunction with this document; but modification, +tampering and reverse engineering are prohibited. + +MICRONAS USA, INC., MAKES NO WARRANTIES TO ANY PERSON OR ENTITY WITH +RESPECT TO THE SOFTWARE OR ANY DERIVATIVES THEREOF OR ANY SERVICES OR +LICENSES AND DISCLAIMS ALL IMPLIED WARRANTIES, INCLUDING WITHOUT LIMITATION +WARRANTIES OF MERCHANTABILITY, SUPPORT, AND FITNESS FOR A PARTICULAR +PURPOSE AND NON-INFRINGEMENT. + + + 1. SYSTEM REQUIREMENTS + + +This driver requires Linux kernel 2.6. Kernel 2.4 is not supported. Using +kernel 2.6.10 or later is recommended, as earlier kernels are known to have +unstable USB 2.0 support. + +A fully built kernel source tree must be available. Typically this will be +linked from "/lib/modules//build" for convenience. If this +link does not exist, an extra parameter will need to be passed to the +`make` command. + +All vendor-built kernels should already be configured properly. However, +for custom-built kernels, the following options need to be enabled in the +kernel as built-in or modules: + + CONFIG_HOTPLUG - Support for hot-pluggable devices + CONFIG_MODULES - Enable loadable module support + CONFIG_KMOD - Automatic kernel module loading + CONFIG_FW_LOADER - Hotplug firmware loading support + CONFIG_I2C - I2C support + CONFIG_VIDEO_DEV - Video For Linux + CONFIG_SOUND - Sound card support + CONFIG_SND - Advanced Linux Sound Architecture + CONFIG_USB - Support for Host-side USB + CONFIG_USB_DEVICEFS - USB device filesystem + CONFIG_USB_EHCI_HCD - EHCI HCD (USB 2.0) support + +Additionally, to use the example application, the following options need to +be enabled in the ALSA section: + + CONFIG_SND_MIXER_OSS - OSS Mixer API + CONFIG_SND_PCM_OSS - OSS PCM (digital audio) API + +The hotplug scripts, along with the fxload utility, must also be installed. +These scripts can be obtained from . +Hotplugging is used for loading firmware into the Cypruss EZ-USB chip using +fxload and for loading firmware into the driver using the firmware agent. + + + 2. COMPILING AND INSTALLING THE DRIVER + + +Most users should be able to compile the driver by simply running: + + $ make + +in the top-level directory of the driver kit. First the kernel modules +will be built, followed by the example applications. + +If the build system is unable to locate the kernel source tree for the +currently-running kernel, or if the module should be built for a kernel +other than the currently-running kernel, an additional parameter will need +to be passed to make to specify the appropriate kernel source directory: + + $ make KERNELSRC=/usr/src/linux-2.6.10-custom3 + +Once the compile completes, the driver and firmware files should be +installed by running: + + $ make install + +The kernel modules will be placed in "/lib/modules//extra" +and the firmware files will be placed in the appropriate hotplug firmware +directory, usually /lib/firmware. In addition, USB maps and scripts will +be placed in /etc/hotplug/usb to enable fxload to initialize the EZ-USB +control chip when the device is connected. + + + 3. PAL/SECAM TUNER CONFIGURATION (TV402U-EU only) + + +The PAL model of the Plextor ConvertX TV402U may require additional +configuration to correctly select the appropriate TV frequency band and +audio subchannel. + +Users with a device other than the Plextor ConvertX TV402U-EU should skip +this section. + +The wide variety of PAL TV systems used in Europe requires that additional +information about the local TV standards be passed to the driver in order +to properly tune TV channels. The two necessary parameters are (a) the PAL +TV band, and (b) the audio subchannel format in use. + +In many cases, the appropriate TV band selection is passed to the driver +from applications. However, in some cases, the application only specifies +that the driver should use PAL but not the specific information about the +appropriate TV band. To work around this issue, the correct TV band may be +specified in the "force_band" parameter to the wis-sony-tuner module: + + TV band force_band + ------- ---------- + PAL B/G B + PAL I I + PAL D/K D + SECAM L L + +If the "force_band" parameter is specified, the driver will ignore any TV +band specified by applications and will always use the band provided in the +module parameter. + +The other parameter that can be specified is the audio subchannel format. +There are several stereo audio carrier systems in use, including NICAM and +three varieties of A2. To receive audio broadcast on one of these stereo +carriers, the "force_mpx_mode" parameter must be specified to the +wis-sony-tuner module. + + TV band Audio subcarrier force_mpx_mode + ------- ---------------- -------------- + PAL B/G Mono (default) 1 + PAL B/G A2 2 + PAL B/G NICAM 3 + PAL I Mono (default) 4 + PAL I NICAM 5 + PAL D/K Mono (default) 6 + PAL D/K A2 (1) 7 + PAL D/K A2 (2) 8 + PAL D/K A2 (3) 9 + PAL D/K NICAM 10 + SECAM L Mono (default) 11 + SECAM L NICAM 12 + +If the "force_mpx_mode" parameter is not specified, the correct mono-only +mode will be chosen based on the TV band. However, the tuner will not +receive stereo audio or bilingual broadcasts correctly. + +To pass the "force_band" or "force_mpx_mode" parameters to the +wis-sony-tuner module, the following line must be added to the modprobe +configuration file, which varies from one Linux distribution to another. + + options wis-sony-tuner force_band=B force_mpx_mode=2 + +The above example would force the tuner to the PAL B/G TV band and receive +stereo audio broadcasts on the A2 carrier. + +To verify that the configuration has been placed in the correct location, +execute: + + $ modprobe -c | grep wis-sony-tuner + +If the configuration line appears, then modprobe will pass the parameters +correctly the next time the wis-sony-tuner module is loaded into the +kernel. + + + 4. TESTING THE DRIVER + + +Because few Linux applications are able to correctly capture from +Video4Linux2 devices with only compressed formats supported, the new driver +should be tested with the "gorecord" application in the apps/ directory. + +First connect a video source to the device, such as a DVD player or VCR. +This will be captured to a file for testing the driver. If an input source +is unavailable, a test file can still be captured, but the video will be +black and the audio will be silent. + +This application will auto-detect the V4L2 and ALSA/OSS device names of the +hardware and will record video and audio to an AVI file for a specified +number of seconds. For example: + + $ apps/gorecord -duration 60 capture.avi + +If this application does not successfully record an AVI file, the error +messages produced by gorecord and recorded in the system log (usually in +/var/log/messages) should provide information to help resolve the problem. + +Supplying no parameters to gorecord will cause it to probe the available +devices and exit. Use the -help flag for usage information. + + + 5. USING THE DRIVER + + +The V4L2 device implemented by the driver provides a standard compressed +format API, within the following criteria: + + * Applications that only support the original Video4Linux1 API will not + be able to communicate with this driver at all. + + * No raw video modes are supported, so applications like xawtv that + expect only uncompressed video will not function. + + * Supported compression formats are: Motion-JPEG, MPEG1, MPEG2 and MPEG4. + + * MPEG video formats are delivered as Video Elementary Streams only. + Program Stream (PS), Transport Stream (TS) and Packetized Elementary + Stream (PES) formats are not supported. + + * Video parameters such as format and input port may not be changed while + the encoder is active. + + * The audio capture device only functions when the video encoder is + actively capturing video. Attempts to read from the audio device when + the encoder is inactive will result in an I/O error. + + * The native format of the audio device is 48Khz 2-channel 16-bit + little-endian PCM, delivered through the ALSA system. No audio + compression is implemented in the hardware. ALSA may convert to other + uncompressed formats on the fly. + +The include/ directory contains a C header file describing non-standard +features of the GO7007SB encoder, which are described below: + + + GO7007IOC_S_COMP_PARAMS, GO7007IOC_G_COMP_PARAMS + + These ioctls are used to negotiate general compression parameters. + + To query the current parameters, call the GO7007IOC_G_COMP_PARAMS ioctl + with a pointer to a struct go7007_comp_params. If the driver is not + set to MPEG format, the EINVAL error code will be returned. + + To change the current parameters, initialize all fields of a struct + go7007_comp_params and call the GO7007_IOC_S_COMP_PARAMS ioctl with a + pointer to this structure. The driver will return the current + parameters with any necessary changes to conform to the limitations of + the hardware or current compression mode. Any or all fields can be set + to zero to request a reasonable default value. If the driver is not + set to MPEG format, the EINVAL error code will be returned. When I/O + is in progress, the EBUSY error code will be returned. + + Fields in struct go7007_comp_params: + + __u32 The maximum number of frames in each + gop_size Group Of Pictures; i.e. the maximum + number of frames minus one between + each key frame. + + __u32 The maximum number of sequential + max_b_frames bidirectionally-predicted frames. + (B-frames are not yet supported.) + + enum go7007_aspect_ratio The aspect ratio to be encoded in the + aspect_ratio meta-data of the compressed format. + + Choices are: + GO7007_ASPECT_RATIO_1_1 + GO7007_ASPECT_RATIO_4_3_NTSC + GO7007_ASPECT_RATIO_4_3_PAL + GO7007_ASPECT_RATIO_16_9_NTSC + GO7007_ASPECT_RATIO_16_9_PAL + + __u32 Bit-wise OR of control flags (below) + flags + + Flags in struct go7007_comp_params: + + GO7007_COMP_CLOSED_GOP Only produce self-contained GOPs, used + to produce streams appropriate for + random seeking. + + GO7007_COMP_OMIT_SEQ_HEADER Omit the stream sequence header. + + + GO7007IOC_S_MPEG_PARAMS, GO7007IOC_G_MPEG_PARAMS + + These ioctls are used to negotiate MPEG-specific stream parameters when + the pixelformat has been set to V4L2_PIX_FMT_MPEG. + + To query the current parameters, call the GO7007IOC_G_MPEG_PARAMS ioctl + with a pointer to a struct go7007_mpeg_params. If the driver is not + set to MPEG format, the EINVAL error code will be returned. + + To change the current parameters, initialize all fields of a struct + go7007_mpeg_params and call the GO7007_IOC_S_MPEG_PARAMS ioctl with a + pointer to this structure. The driver will return the current + parameters with any necessary changes to conform to the limitations of + the hardware or selected MPEG mode. Any or all fields can be set to + zero to request a reasonable default value. If the driver is not set + to MPEG format, the EINVAL error code will be returned. When I/O is in + progress, the EBUSY error code will be returned. + + Fields in struct go7007_mpeg_params: + + enum go7007_mpeg_video_standard + mpeg_video_standard The MPEG video standard in which to + compress the video. + + Choices are: + GO7007_MPEG_VIDEO_MPEG1 + GO7007_MPEG_VIDEO_MPEG2 + GO7007_MPEG_VIDEO_MPEG4 + + __u32 Bit-wise OR of control flags (below) + flags + + __u32 The profile and level indication to be + pali stored in the sequence header. This + is only used as an indicator to the + decoder, and does not affect the MPEG + features used in the video stream. + Not valid for MPEG1. + + Choices for MPEG2 are: + GO7007_MPEG2_PROFILE_MAIN_MAIN + + Choices for MPEG4 are: + GO7007_MPEG4_PROFILE_S_L0 + GO7007_MPEG4_PROFILE_S_L1 + GO7007_MPEG4_PROFILE_S_L2 + GO7007_MPEG4_PROFILE_S_L3 + GO7007_MPEG4_PROFILE_ARTS_L1 + GO7007_MPEG4_PROFILE_ARTS_L2 + GO7007_MPEG4_PROFILE_ARTS_L3 + GO7007_MPEG4_PROFILE_ARTS_L4 + GO7007_MPEG4_PROFILE_AS_L0 + GO7007_MPEG4_PROFILE_AS_L1 + GO7007_MPEG4_PROFILE_AS_L2 + GO7007_MPEG4_PROFILE_AS_L3 + GO7007_MPEG4_PROFILE_AS_L4 + GO7007_MPEG4_PROFILE_AS_L5 + + Flags in struct go7007_mpeg_params: + + GO7007_MPEG_FORCE_DVD_MODE Force all compression parameters and + bitrate control settings to comply + with DVD MPEG2 stream requirements. + This overrides most compression and + bitrate settings! + + GO7007_MPEG_OMIT_GOP_HEADER Omit the GOP header. + + GO7007_MPEG_REPEAT_SEQHEADER Repeat the MPEG sequence header at + the start of each GOP. + + + GO7007IOC_S_BITRATE, GO7007IOC_G_BITRATE + + These ioctls are used to set and query the target bitrate value for the + compressed video stream. The bitrate may be selected by storing the + target bits per second in an int and calling GO7007IOC_S_BITRATE with a + pointer to the int. The bitrate may be queried by calling + GO7007IOC_G_BITRATE with a pointer to an int where the current bitrate + will be stored. + + Note that this is the primary means of controlling the video quality + for all compression modes, including V4L2_PIX_FMT_MJPEG. The + VIDIOC_S_JPEGCOMP ioctl is not supported. + + +---------------------------------------------------------------------------- + Installing the WIS PCI Voyager Driver +--------------------------------------------------------------------------- + +The WIS PCI Voyager driver requires several patches to the Linux 2.6.11.x +kernel source tree before compiling the driver. These patches update the +in-kernel SAA7134 driver to the newest development version and patch bugs +in the TDA8290/TDA8275 tuner driver. + +The following patches must be downloaded from Gerd Knorr's website and +applied in the order listed: + + http://dl.bytesex.org/patches/2.6.11-2/i2c-tuner + http://dl.bytesex.org/patches/2.6.11-2/i2c-tuner2 + http://dl.bytesex.org/patches/2.6.11-2/v4l2-api-mpeg + http://dl.bytesex.org/patches/2.6.11-2/saa7134-update + +The following patches are included with this SDK and can be applied in any +order: + + patches/2.6.11/saa7134-voyager.diff + patches/2.6.11/tda8275-newaddr.diff + patches/2.6.11/tda8290-ntsc.diff + +Check to make sure the CONFIG_VIDEO_SAA7134 option is enabled in the kernel +configuration, and build and install the kernel. + +After rebooting into the new kernel, the GO7007 driver can be compiled and +installed: + + $ make SAA7134_BUILD=y + $ make install + $ modprobe saa7134-go7007 + +There will be two V4L video devices associated with the PCI Voyager. The +first device (most likely /dev/video0) provides access to the raw video +capture mode of the SAA7133 device and is used to configure the source +video parameters and tune the TV tuner. This device can be used with xawtv +or other V4L(2) video software as a standard uncompressed device. + +The second device (most likely /dev/video1) provides access to the +compression functions of the GO7007. It can be tested using the gorecord +application in the apps/ directory of this SDK: + + $ apps/gorecord -vdevice /dev/video1 -noaudio test.avi + +Currently the frame resolution is fixed at 720x480 (NTSC) or 720x576 (PAL), +and the video standard must be specified to both the raw and the compressed +video devices (xawtv and gorecord, for example). + + +-------------------------------------------------------------------------- +RELEASE NOTES FOR WIS GO7007SB LINUX DRIVER +--------------------------------------------------------------------------- + +Last updated: 5 November 2005 + + - Release 0.9.7 includes new support for using udev to run fxload. The + install script should automatically detect whether the old hotplug + scripts or the new udev rules should be used. To force the use of + hotplug, run "make install USE_UDEV=n". To force the use of udev, run + "make install USE_UDEV=y". + + - Motion detection is supported but undocumented. Try the `modet` app + for a demonstration of how to use the facility. + + - Using USB2.0 devices such as the TV402U with USB1.1 HCDs or hubs can + cause buffer overruns and frame drops, even at low framerates, due to + inconsistency in the bitrate control mechanism. + + - On devices with an SAA7115, including the Plextor ConvertX, video height + values of 96, 128, 160, 192, 256, 320, and 384 do not work in NTSC mode. + All valid heights up to 512 work correctly in PAL mode. + + - The WIS Star Trek and PCI Voyager boards have no support yet for audio + or the TV tuner. --- linux-2.6.28.orig/drivers/staging/go7007/Makefile +++ linux-2.6.28/drivers/staging/go7007/Makefile @@ -5,14 +5,23 @@ obj-$(CONFIG_VIDEO_GO7007) += go7007.o obj-$(CONFIG_VIDEO_GO7007_USB) += go7007-usb.o +obj-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD) += s2250.o -go7007-objs += go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o snd-go7007.o +go7007-objs += go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o \ + snd-go7007.o wis-saa7113.o +s2250-objs += s2250-board.o s2250-loader.o -#ifneq ($(SAA7134_BUILD),) -#obj-m += saa7134-go7007.o +# Uncompile when the saa7134 patches get into upstream +#ifneq ($(CONFIG_VIDEO_SAA7134),) +#obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o +#EXTRA_CFLAGS += -Idrivers/media/video/saa7134 #endif +ifneq ($(CONFIG_VIDEO_GO7007_USB_S2250_BOARD),) +EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-usb +endif + EXTRA_CFLAGS += -Idrivers/staging/saa7134 EXTRA_CFLAGS += -Idrivers/media/dvb/frontends EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core --- linux-2.6.28.orig/drivers/staging/go7007/saa7134-go7007.c +++ linux-2.6.28/drivers/staging/go7007/saa7134-go7007.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include "saa7134-reg.h" #include "saa7134.h" @@ -314,7 +314,13 @@ static int saa7134_go7007_stream_stop(struct go7007 *go) { struct saa7134_go7007 *saa = go->hpi_context; - struct saa7134_dev *dev = saa->dev; + struct saa7134_dev *dev; + + if (!saa) + return -EINVAL; + dev = saa->dev; + if (!dev) + return -EINVAL; /* Shut down TS FIFO */ saa_clearl(SAA7134_MAIN_CTRL, SAA7134_MAIN_CTRL_TE5); @@ -373,6 +379,47 @@ return 0; } +static int saa7134_go7007_send_command(struct go7007 *go, unsigned int cmd, + void *arg) +{ + struct saa7134_go7007 *saa = go->hpi_context; + struct saa7134_dev *dev = saa->dev; + + switch (cmd) { + case VIDIOC_S_STD: + { + v4l2_std_id *std = arg; + return saa7134_s_std_internal(dev, NULL, std); + } + case VIDIOC_G_STD: + { + v4l2_std_id *std = arg; + *std = dev->tvnorm->id; + return 0; + } + case VIDIOC_QUERYCTRL: + { + struct v4l2_queryctrl *ctrl = arg; + if (V4L2_CTRL_ID2CLASS(ctrl->id) == V4L2_CTRL_CLASS_USER) + return saa7134_queryctrl(NULL, NULL, ctrl); + } + case VIDIOC_G_CTRL: + { + struct v4l2_control *ctrl = arg; + if (V4L2_CTRL_ID2CLASS(ctrl->id) == V4L2_CTRL_CLASS_USER) + return saa7134_g_ctrl_internal(dev, NULL, ctrl); + } + case VIDIOC_S_CTRL: + { + struct v4l2_control *ctrl = arg; + if (V4L2_CTRL_ID2CLASS(ctrl->id) == V4L2_CTRL_CLASS_USER) + return saa7134_s_ctrl_internal(dev, NULL, ctrl); + } + } + return -EINVAL; + +} + static struct go7007_hpi_ops saa7134_go7007_hpi_ops = { .interface_reset = saa7134_go7007_interface_reset, .write_interrupt = saa7134_go7007_write_interrupt, @@ -380,6 +427,7 @@ .stream_start = saa7134_go7007_stream_start, .stream_stop = saa7134_go7007_stream_stop, .send_firmware = saa7134_go7007_send_firmware, + .send_command = saa7134_go7007_send_command, }; /********************* Add/remove functions *********************/ --- linux-2.6.28.orig/drivers/staging/go7007/go7007-fw.c +++ linux-2.6.28/drivers/staging/go7007/go7007-fw.c @@ -284,7 +284,7 @@ 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 }; -static int copy_packages(u16 *dest, u16 *src, int pkg_cnt, int space) +static int copy_packages(__le16 *dest, u16 *src, int pkg_cnt, int space) { int i, cnt = pkg_cnt * 32; @@ -292,7 +292,7 @@ return -1; for (i = 0; i < cnt; ++i) - dest[i] = __cpu_to_le16(src[i]); + dest[i] = cpu_to_le16p(src + i); return cnt; } @@ -372,7 +372,7 @@ return p; } -static int gen_mjpeghdr_to_package(struct go7007 *go, u16 *code, int space) +static int gen_mjpeghdr_to_package(struct go7007 *go, __le16 *code, int space) { u8 *buf; u16 mem = 0x3e00; @@ -643,7 +643,7 @@ } static int gen_mpeg1hdr_to_package(struct go7007 *go, - u16 *code, int space, int *framelen) + __le16 *code, int space, int *framelen) { u8 *buf; u16 mem = 0x3e00; @@ -831,7 +831,7 @@ } static int gen_mpeg4hdr_to_package(struct go7007 *go, - u16 *code, int space, int *framelen) + __le16 *code, int space, int *framelen) { u8 *buf; u16 mem = 0x3e00; @@ -936,7 +936,7 @@ } static int brctrl_to_package(struct go7007 *go, - u16 *code, int space, int *framelen) + __le16 *code, int space, int *framelen) { int converge_speed = 0; int lambda = (go->format == GO7007_FORMAT_MJPEG || go->dvd_mode) ? @@ -1091,7 +1091,7 @@ return copy_packages(code, pack, 6, space); } -static int config_package(struct go7007 *go, u16 *code, int space) +static int config_package(struct go7007 *go, __le16 *code, int space) { int fps = go->sensor_framerate / go->fps_scale / 1000; int rows = go->interlace_coding ? go->height / 32 : go->height / 16; @@ -1213,7 +1213,7 @@ return copy_packages(code, pack, 5, space); } -static int seqhead_to_package(struct go7007 *go, u16 *code, int space, +static int seqhead_to_package(struct go7007 *go, __le16 *code, int space, int (*sequence_header_func)(struct go7007 *go, unsigned char *buf, int ext)) { @@ -1292,7 +1292,7 @@ return big; } -static int avsync_to_package(struct go7007 *go, u16 *code, int space) +static int avsync_to_package(struct go7007 *go, __le16 *code, int space) { int arate = go->board_info->audio_rate * 1001 * go->fps_scale; int ratio = arate / go->sensor_framerate; @@ -1323,7 +1323,7 @@ return copy_packages(code, pack, 1, space); } -static int final_package(struct go7007 *go, u16 *code, int space) +static int final_package(struct go7007 *go, __le16 *code, int space) { int rows = go->interlace_coding ? go->height / 32 : go->height / 16; u16 pack[] = { @@ -1386,7 +1386,7 @@ return copy_packages(code, pack, 1, space); } -static int audio_to_package(struct go7007 *go, u16 *code, int space) +static int audio_to_package(struct go7007 *go, __le16 *code, int space) { int clock_config = ((go->board_info->audio_flags & GO7007_AUDIO_I2S_MASTER ? 1 : 0) << 11) | @@ -1436,7 +1436,7 @@ return copy_packages(code, pack, 2, space); } -static int modet_to_package(struct go7007 *go, u16 *code, int space) +static int modet_to_package(struct go7007 *go, __le16 *code, int space) { int ret, mb, i, addr, cnt = 0; u16 pack[32]; @@ -1505,7 +1505,7 @@ return cnt; } -static int do_special(struct go7007 *go, u16 type, u16 *code, int space, +static int do_special(struct go7007 *go, u16 type, __le16 *code, int space, int *framelen) { switch (type) { @@ -1555,7 +1555,7 @@ int go7007_construct_fw_image(struct go7007 *go, u8 **fw, int *fwlen) { const struct firmware *fw_entry; - u16 *code, *src; + __le16 *code, *src; int framelen[8] = { }; /* holds the lengths of empty frame templates */ int codespace = 64 * 1024, i = 0, srclen, chunk_len, chunk_flags; int mode_flag; @@ -1590,7 +1590,7 @@ goto fw_failed; } memset(code, 0, codespace * 2); - src = (u16 *)fw_entry->data; + src = (__le16 *)fw_entry->data; srclen = fw_entry->size / 2; while (srclen >= 2) { chunk_flags = __le16_to_cpu(src[0]); --- linux-2.6.28.orig/drivers/staging/go7007/s2250-loader.c +++ linux-2.6.28/drivers/staging/go7007/s2250-loader.c @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2008 Sensoray Company 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You 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 + +#define S2250_LOADER_FIRMWARE "s2250_loader.fw" +#define S2250_FIRMWARE "s2250.fw" + +typedef struct device_extension_s { + struct kref kref; + int minor; + struct usb_device *usbdev; +} device_extension_t, *pdevice_extension_t; + +#define USB_s2250loader_MAJOR 240 +#define USB_s2250loader_MINOR_BASE 0 +#define MAX_DEVICES 256 + +static pdevice_extension_t s2250_dev_table[MAX_DEVICES]; +static DECLARE_MUTEX(s2250_dev_table_mutex); + +#define to_s2250loader_dev_common(d) container_of(d, device_extension_t, kref) +static void s2250loader_delete(struct kref *kref) +{ + pdevice_extension_t s = to_s2250loader_dev_common(kref); + s2250_dev_table[s->minor] = NULL; + kfree(s); +} + +static int s2250loader_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct usb_device *usbdev; + int minor, ret; + pdevice_extension_t s = NULL; + const struct firmware *fw; + + usbdev = usb_get_dev(interface_to_usbdev(interface)); + if (!usbdev) { + printk(KERN_ERR "Enter s2250loader_probe failed\n"); + return -1; + } + printk(KERN_INFO "Enter s2250loader_probe 2.6 kernel\n"); + printk(KERN_INFO "vendor id 0x%x, device id 0x%x devnum:%d\n", + usbdev->descriptor.idVendor, usbdev->descriptor.idProduct, + usbdev->devnum); + + if (usbdev->descriptor.bNumConfigurations != 1) { + printk(KERN_ERR "can't handle multiple config\n"); + return -1; + } + down(&s2250_dev_table_mutex); + + for (minor = 0; minor < MAX_DEVICES; minor++) { + if (s2250_dev_table[minor] == NULL) + break; + } + + if (minor < 0 || minor >= MAX_DEVICES) { + printk(KERN_ERR "Invalid minor: %d\n", minor); + goto failed; + } + + /* Allocate dev data structure */ + s = kmalloc(sizeof(device_extension_t), GFP_KERNEL); + if (s == NULL) { + printk(KERN_ERR "Out of memory\n"); + goto failed; + } + s2250_dev_table[minor] = s; + + printk(KERN_INFO "s2250loader_probe: Device %d on Bus %d Minor %d\n", + usbdev->devnum, usbdev->bus->busnum, minor); + + memset(s, 0, sizeof(device_extension_t)); + s->usbdev = usbdev; + printk(KERN_INFO "loading 2250 loader\n"); + + kref_init(&(s->kref)); + + up(&s2250_dev_table_mutex); + + if (request_firmware(&fw, S2250_LOADER_FIRMWARE, &usbdev->dev)) { + printk(KERN_ERR + "s2250: unable to load firmware from file \"%s\"\n", + S2250_LOADER_FIRMWARE); + goto failed2; + } + ret = usb_cypress_load_firmware(usbdev, fw, CYPRESS_FX2); + release_firmware(fw); + if (0 != ret) { + printk(KERN_ERR "loader download failed\n"); + goto failed2; + } + + if (request_firmware(&fw, S2250_FIRMWARE, &usbdev->dev)) { + printk(KERN_ERR + "s2250: unable to load firmware from file \"%s\"\n", + S2250_FIRMWARE); + goto failed2; + } + ret = usb_cypress_load_firmware(usbdev, fw, CYPRESS_FX2); + release_firmware(fw); + if (0 != ret) { + printk(KERN_ERR "firmware_s2250 download failed\n"); + goto failed2; + } + + usb_set_intfdata(interface, s); + return 0; + +failed: + up(&s2250_dev_table_mutex); +failed2: + if (s) + kref_put(&(s->kref), s2250loader_delete); + + printk(KERN_ERR "probe failed\n"); + return -1; +} + +static void s2250loader_disconnect(struct usb_interface *interface) +{ + pdevice_extension_t s = usb_get_intfdata(interface); + printk(KERN_INFO "s2250: disconnect\n"); + lock_kernel(); + s = usb_get_intfdata(interface); + usb_set_intfdata(interface, NULL); + kref_put(&(s->kref), s2250loader_delete); + unlock_kernel(); +} + +static struct usb_device_id s2250loader_ids[] = { + {USB_DEVICE(0x1943, 0xa250)}, + {} /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(usb, s2250loader_ids); + +static struct usb_driver s2250loader_driver = { + .name = "s2250-loader", + .probe = s2250loader_probe, + .disconnect = s2250loader_disconnect, + .id_table = s2250loader_ids, +}; + +int s2250loader_init(void) +{ + int r; + unsigned i = 0; + + for (i = 0; i < MAX_DEVICES; i++) + s2250_dev_table[i] = NULL; + + r = usb_register(&s2250loader_driver); + if (r) { + printk(KERN_ERR "usb_register failed. Error number %d\n", r); + return -1; + } + + printk(KERN_INFO "s2250loader_init: driver registered\n"); + return 0; +} +EXPORT_SYMBOL(s2250loader_init); + +void s2250loader_cleanup(void) +{ + printk(KERN_INFO "s2250loader_cleanup\n"); + usb_deregister(&s2250loader_driver); +} +EXPORT_SYMBOL(s2250loader_cleanup); --- linux-2.6.28.orig/drivers/staging/et131x/et131x_debug.h +++ linux-2.6.28/drivers/staging/et131x/et131x_debug.h @@ -82,11 +82,11 @@ #define DBG_LVL 3 #endif /* DBG_LVL */ -#define DBG_DEFAULTS (DBG_ERROR_ON | DBG_WARNING_ON | DBG_BREAK_ON ) +#define DBG_DEFAULTS (DBG_ERROR_ON | DBG_WARNING_ON | DBG_BREAK_ON) -#define DBG_FLAGS(A) (A)->dbgFlags -#define DBG_NAME(A) (A)->dbgName -#define DBG_LEVEL(A) (A)->dbgLevel +#define DBG_FLAGS(A) ((A)->dbgFlags) +#define DBG_NAME(A) ((A)->dbgName) +#define DBG_LEVEL(A) ((A)->dbgLevel) #ifndef DBG_PRINT #define DBG_PRINT(S...) printk(KERN_DEBUG S) @@ -108,56 +108,110 @@ #define _DBG_LEAVE(A) printk(KERN_DEBUG "%s:%.*s:%s\n", DBG_NAME(A), \ DBG_LEVEL(A)--, _LEAVE_STR, __func__) -#define DBG_ENTER(A) {if (DBG_FLAGS(A) & DBG_TRACE_ON) \ - _DBG_ENTER(A);} +#define DBG_ENTER(A) \ + do { \ + if (DBG_FLAGS(A) & DBG_TRACE_ON) \ + _DBG_ENTER(A); \ + } while (0) + +#define DBG_LEAVE(A) \ + do { \ + if (DBG_FLAGS(A) & DBG_TRACE_ON) \ + _DBG_LEAVE(A); \ + } while (0) + +#define DBG_PARAM(A, N, F, S...) \ + do { \ + if (DBG_FLAGS(A) & DBG_PARAM_ON) \ + DBG_PRINT(" %s -- "F" ", N, S); \ + } while (0) + +#define DBG_ERROR(A, S...) \ + do { \ + if (DBG_FLAGS(A) & DBG_ERROR_ON) { \ + DBG_PRINT("%s:ERROR:%s ", DBG_NAME(A), __func__);\ + DBG_PRINTC(S); \ + DBG_TRAP; \ + } \ + } while (0) + +#define DBG_WARNING(A, S...) \ + do { \ + if (DBG_FLAGS(A) & DBG_WARNING_ON) { \ + DBG_PRINT("%s:WARNING:%s ", DBG_NAME(A), __func__); \ + DBG_PRINTC(S); \ + } \ + } while (0) + +#define DBG_NOTICE(A, S...) \ + do { \ + if (DBG_FLAGS(A) & DBG_NOTICE_ON) { \ + DBG_PRINT("%s:NOTICE:%s ", DBG_NAME(A), __func__); \ + DBG_PRINTC(S); \ + } \ + } while (0) + +#define DBG_TRACE(A, S...) \ + do { \ + if (DBG_FLAGS(A) & DBG_TRACE_ON) { \ + DBG_PRINT("%s:TRACE:%s ", DBG_NAME(A), __func__); \ + DBG_PRINTC(S); \ + } \ + } while (0) + +#define DBG_VERBOSE(A, S...) \ + do { \ + if (DBG_FLAGS(A) & DBG_VERBOSE_ON) { \ + DBG_PRINT("%s:VERBOSE:%s ", DBG_NAME(A), __func__); \ + DBG_PRINTC(S); \ + } \ + } while (0) + +#define DBG_RX(A, S...) \ + do { \ + if (DBG_FLAGS(A) & DBG_RX_ON) \ + DBG_PRINT(S); \ + } while (0) + +#define DBG_RX_ENTER(A) \ + do { \ + if (DBG_FLAGS(A) & DBG_RX_ON) \ + _DBG_ENTER(A); \ + } while (0) + +#define DBG_RX_LEAVE(A) \ + do { \ + if (DBG_FLAGS(A) & DBG_RX_ON) \ + _DBG_LEAVE(A); \ + } while (0) + +#define DBG_TX(A, S...) \ + do { \ + if (DBG_FLAGS(A) & DBG_TX_ON) \ + DBG_PRINT(S); \ + } while (0) + +#define DBG_TX_ENTER(A) \ + do { \ + if (DBG_FLAGS(A) & DBG_TX_ON) \ + _DBG_ENTER(A); \ + } while (0) + +#define DBG_TX_LEAVE(A) \ + do { \ + if (DBG_FLAGS(A) & DBG_TX_ON) \ + _DBG_LEAVE(A); \ + } while (0) + +#define DBG_ASSERT(C) \ + do { \ + if (!(C)) { \ + DBG_PRINT("ASSERT(%s) -- %s#%d (%s) ", \ + #C, __FILE__, __LINE__, __func__); \ + DBG_TRAP; \ + } \ + } while (0) -#define DBG_LEAVE(A) {if (DBG_FLAGS(A) & DBG_TRACE_ON) \ - _DBG_LEAVE(A);} - -#define DBG_PARAM(A,N,F,S...) {if (DBG_FLAGS(A) & DBG_PARAM_ON) \ - DBG_PRINT(" %s -- "F"\n",N,S);} - -#define DBG_ERROR(A,S...) \ - if (DBG_FLAGS(A) & DBG_ERROR_ON) { \ - DBG_PRINT("%s:ERROR:%s ",DBG_NAME(A), __func__); \ - DBG_PRINTC(S); \ - DBG_TRAP; \ - } - -#define DBG_WARNING(A,S...) {if (DBG_FLAGS(A) & DBG_WARNING_ON) \ - {DBG_PRINT("%s:WARNING:%s ",DBG_NAME(A),__func__);DBG_PRINTC(S);}} - -#define DBG_NOTICE(A,S...) {if (DBG_FLAGS(A) & DBG_NOTICE_ON) \ - {DBG_PRINT("%s:NOTICE:%s ",DBG_NAME(A),__func__);DBG_PRINTC(S);}} - -#define DBG_TRACE(A,S...) {if (DBG_FLAGS(A) & DBG_TRACE_ON) \ - {DBG_PRINT("%s:TRACE:%s ",DBG_NAME(A), __func__);DBG_PRINTC(S);}} - -#define DBG_VERBOSE(A,S...) {if (DBG_FLAGS(A) & DBG_VERBOSE_ON) \ - {DBG_PRINT("%s:VERBOSE:%s ",DBG_NAME(A), __func__);DBG_PRINTC(S);}} - -#define DBG_RX(A,S...) {if (DBG_FLAGS(A) & DBG_RX_ON) \ - {DBG_PRINT(S);}} - -#define DBG_RX_ENTER(A) {if (DBG_FLAGS(A) & DBG_RX_ON) \ - _DBG_ENTER(A);} - -#define DBG_RX_LEAVE(A) {if (DBG_FLAGS(A) & DBG_RX_ON) \ - _DBG_LEAVE(A);} - -#define DBG_TX(A,S...) {if (DBG_FLAGS(A) & DBG_TX_ON) \ - {DBG_PRINT(S);}} - -#define DBG_TX_ENTER(A) {if (DBG_FLAGS(A) & DBG_TX_ON) \ - _DBG_ENTER(A);} - -#define DBG_TX_LEAVE(A) {if (DBG_FLAGS(A) & DBG_TX_ON) \ - _DBG_LEAVE(A);} - -#define DBG_ASSERT(C) {if (!(C)) \ - {DBG_PRINT("ASSERT(%s) -- %s#%d (%s)\n", \ - #C,__FILE__,__LINE__,__func__); \ - DBG_TRAP;}} #define STATIC typedef struct { --- linux-2.6.28.orig/drivers/staging/et131x/et1310_tx.c +++ linux-2.6.28/drivers/staging/et131x/et1310_tx.c @@ -1345,7 +1345,6 @@ { PMP_TCB pMpTcb; struct list_head *pEntry; - struct sk_buff *pPacket = NULL; unsigned long lockflags; uint32_t FreeCounter = 0; @@ -1358,8 +1357,6 @@ spin_unlock_irqrestore(&pAdapter->SendWaitLock, lockflags); pEntry = pAdapter->TxRing.SendWaitQueue.next; - - pPacket = NULL; } pAdapter->TxRing.nWaitSend = 0; --- linux-2.6.28.orig/drivers/staging/usbip/vhci_hcd.c +++ linux-2.6.28/drivers/staging/usbip/vhci_hcd.c @@ -1091,7 +1091,7 @@ * Allocate and initialize hcd. * Our private data is also allocated automatically. */ - hcd = usb_create_hcd(&vhci_hc_driver, &pdev->dev, pdev->dev.bus_id); + hcd = usb_create_hcd(&vhci_hc_driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { uerr("create hcd failed\n"); return -ENOMEM; --- linux-2.6.28.orig/drivers/staging/usbip/stub_main.c +++ linux-2.6.28/drivers/staging/usbip/stub_main.c @@ -40,11 +40,12 @@ * remote host. */ #define MAX_BUSID 16 -static char busid_table[MAX_BUSID][BUS_ID_SIZE]; +#define BUSID_SIZE 20 +static char busid_table[MAX_BUSID][BUSID_SIZE]; static spinlock_t busid_table_lock; -int match_busid(char *busid) +int match_busid(const char *busid) { int i; @@ -52,7 +53,7 @@ for (i = 0; i < MAX_BUSID; i++) if (busid_table[i][0]) - if (!strncmp(busid_table[i], busid, BUS_ID_SIZE)) { + if (!strncmp(busid_table[i], busid, BUSID_SIZE)) { /* already registerd */ spin_unlock(&busid_table_lock); return 0; @@ -92,7 +93,7 @@ for (i = 0; i < MAX_BUSID; i++) if (!busid_table[i][0]) { - strncpy(busid_table[i], busid, BUS_ID_SIZE); + strncpy(busid_table[i], busid, BUSID_SIZE); spin_unlock(&busid_table_lock); return 0; } @@ -109,9 +110,9 @@ spin_lock(&busid_table_lock); for (i = 0; i < MAX_BUSID; i++) - if (!strncmp(busid_table[i], busid, BUS_ID_SIZE)) { + if (!strncmp(busid_table[i], busid, BUSID_SIZE)) { /* found */ - memset(busid_table[i], 0, BUS_ID_SIZE); + memset(busid_table[i], 0, BUSID_SIZE); spin_unlock(&busid_table_lock); return 0; } @@ -125,19 +126,19 @@ size_t count) { int len; - char busid[BUS_ID_SIZE]; + char busid[BUSID_SIZE]; if (count < 5) return -EINVAL; /* strnlen() does not include \0 */ - len = strnlen(buf + 4, BUS_ID_SIZE); + len = strnlen(buf + 4, BUSID_SIZE); /* busid needs to include \0 termination */ - if (!(len < BUS_ID_SIZE)) + if (!(len < BUSID_SIZE)) return -EINVAL; - strncpy(busid, buf + 4, BUS_ID_SIZE); + strncpy(busid, buf + 4, BUSID_SIZE); if (!strncmp(buf, "add ", 4)) { --- linux-2.6.28.orig/drivers/staging/usbip/vhci_sysfs.c +++ linux-2.6.28/drivers/staging/usbip/vhci_sysfs.c @@ -60,7 +60,7 @@ out += sprintf(out, "%03u %08x ", vdev->speed, vdev->devid); out += sprintf(out, "%16p ", vdev->ud.tcp_socket); - out += sprintf(out, "%s", vdev->udev->dev.bus_id); + out += sprintf(out, "%s", dev_name(&vdev->udev->dev)); } else out += sprintf(out, "000 000 000 0000000000000000 0-0"); --- linux-2.6.28.orig/drivers/staging/usbip/stub_dev.c +++ linux-2.6.28/drivers/staging/usbip/stub_dev.c @@ -389,7 +389,7 @@ { struct usb_device *udev = interface_to_usbdev(interface); struct stub_device *sdev = NULL; - char *udev_busid = interface->dev.parent->bus_id; + const char *udev_busid = dev_name(interface->dev.parent); int err = 0; dev_dbg(&interface->dev, "Enter\n"); --- linux-2.6.28.orig/drivers/staging/usbip/stub_rx.c +++ linux-2.6.28/drivers/staging/usbip/stub_rx.c @@ -157,7 +157,7 @@ * A user may need to set a special configuration value before * exporting the device. */ - uinfo("set_configuration (%d) to %s\n", config, urb->dev->dev.bus_id); + uinfo("set_configuration (%d) to %s\n", config, dev_name(&urb->dev->dev)); uinfo("but, skip!\n"); return 0; @@ -175,7 +175,7 @@ value = le16_to_cpu(req->wValue); index = le16_to_cpu(req->wIndex); - uinfo("reset_device (port %d) to %s\n", index, urb->dev->dev.bus_id); + uinfo("reset_device (port %d) to %s\n", index, dev_name(&urb->dev->dev)); /* all interfaces should be owned by usbip driver, so just reset it. */ ret = usb_lock_device_for_reset(urb->dev, NULL); @@ -234,8 +234,6 @@ static int stub_recv_cmd_unlink(struct stub_device *sdev, struct usbip_header *pdu) { - struct list_head *listhead = &sdev->priv_init; - struct list_head *ptr; unsigned long flags; struct stub_priv *priv; @@ -243,8 +241,7 @@ spin_lock_irqsave(&sdev->priv_lock, flags); - for (ptr = listhead->next; ptr != listhead; ptr = ptr->next) { - priv = list_entry(ptr, struct stub_priv, list); + list_for_each_entry(priv, &sdev->priv_init, list) { if (priv->seqnum == pdu->u.cmd_unlink.seqnum) { int ret; --- linux-2.6.28.orig/drivers/staging/usbip/usbip_common.c +++ linux-2.6.28/drivers/staging/usbip/usbip_common.c @@ -406,8 +406,20 @@ /* * threads are invoked per one device (per one connection). */ - kernel_thread(usbip_thread, (void *)&ud->tcp_rx, 0); - kernel_thread(usbip_thread, (void *)&ud->tcp_tx, 0); + int retval; + + retval = kernel_thread(usbip_thread, (void *)&ud->tcp_rx, 0); + if (retval < 0) { + printk(KERN_ERR "Creating tcp_rx thread for ud %p failed.\n", + ud); + return; + } + retval = kernel_thread(usbip_thread, (void *)&ud->tcp_tx, 0); + if (retval < 0) { + printk(KERN_ERR "Creating tcp_tx thread for ud %p failed.\n", + ud); + return; + } /* confirm threads are starting */ wait_for_completion(&ud->tcp_rx.thread_done); --- linux-2.6.28.orig/drivers/staging/usbip/stub.h +++ linux-2.6.28/drivers/staging/usbip/stub.h @@ -91,5 +91,5 @@ void stub_enqueue_ret_unlink(struct stub_device *, __u32, __u32); /* stub_main.c */ -int match_busid(char *busid); +int match_busid(const char *busid); void stub_device_cleanup_urbs(struct stub_device *sdev); --- linux-2.6.28.orig/drivers/staging/usbip/stub_tx.c +++ linux-2.6.28/drivers/staging/usbip/stub_tx.c @@ -54,7 +54,6 @@ /** * stub_complete - completion handler of a usbip urb * @urb: pointer to the urb completed - * @regs: * * When a urb has completed, the USB core driver calls this function mostly in * the interrupt context. To return the result of a urb, the completed urb is --- linux-2.6.28.orig/drivers/staging/at76_usb/at76_usb.c +++ linux-2.6.28/drivers/staging/at76_usb/at76_usb.c @@ -231,6 +231,8 @@ {USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A)}, /* Siemens Gigaset USB WLAN Adapter 11 */ {USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A)}, + /* OQO Model 01+ Internal Wi-Fi */ + {USB_DEVICE(0x1557, 0x0002), USB_DEVICE_DATA(BOARD_505A)}, /* * at76c505amx-rfmd */ @@ -641,18 +643,25 @@ static int at76_get_op_mode(struct usb_device *udev) { int ret; - u8 op_mode; + u8 saved; + u8 *op_mode; + op_mode = kmalloc(1, GFP_NOIO); + if (!op_mode) + return -ENOMEM; ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33, USB_TYPE_VENDOR | USB_DIR_IN | - USB_RECIP_INTERFACE, 0x01, 0, &op_mode, 1, + USB_RECIP_INTERFACE, 0x01, 0, op_mode, 1, USB_CTRL_GET_TIMEOUT); + saved = *op_mode; + kfree(op_mode); + if (ret < 0) return ret; else if (ret < 1) return -EIO; else - return op_mode; + return saved; } /* Load a block of the second ("external") part of the firmware */ @@ -765,20 +774,25 @@ /* Return positive number for status, negative for an error */ static inline int at76_get_cmd_status(struct usb_device *udev, u8 cmd) { - u8 stat_buf[40]; + u8 *stat_buf; int ret; + stat_buf = kmalloc(40, GFP_NOIO); + if (!stat_buf) + return -ENOMEM; + ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x22, USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_INTERFACE, cmd, 0, stat_buf, - sizeof(stat_buf), USB_CTRL_GET_TIMEOUT); - if (ret < 0) - return ret; + 40, USB_CTRL_GET_TIMEOUT); + if (ret >= 0) + ret = stat_buf[5]; + kfree(stat_buf); - return stat_buf[5]; + return ret; } -static int at76_set_card_command(struct usb_device *udev, int cmd, void *buf, +static int at76_set_card_command(struct usb_device *udev, u8 cmd, void *buf, int buf_size) { int ret; @@ -5315,7 +5329,7 @@ priv->netdev_registered = 1; printk(KERN_INFO "%s: USB %s, MAC %s, firmware %d.%d.%d-%d\n", - netdev->name, interface->dev.bus_id, mac2str(priv->mac_addr), + netdev->name, dev_name(&interface->dev), mac2str(priv->mac_addr), priv->fw_version.major, priv->fw_version.minor, priv->fw_version.patch, priv->fw_version.build); printk(KERN_INFO "%s: regulatory domain 0x%02x: %s\n", netdev->name, --- linux-2.6.28.orig/drivers/usb/serial/ftdi_sio.c +++ linux-2.6.28/drivers/usb/serial/ftdi_sio.c @@ -660,6 +660,11 @@ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) }, { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DGQG_PID) }, { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, + { USB_DEVICE(ATMEL_VID, STK541_PID) }, + { USB_DEVICE(DE_VID, STB_PID) }, + { USB_DEVICE(DE_VID, WHT_PID) }, + { USB_DEVICE(ADI_VID, ADI_GNICE_PID), + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; --- linux-2.6.28.orig/drivers/usb/serial/ftdi_sio.h +++ linux-2.6.28/drivers/usb/serial/ftdi_sio.h @@ -881,6 +881,26 @@ #define RATOC_PRODUCT_ID_USB60F 0xb020 /* + * Atmel STK541 + */ +#define ATMEL_VID 0x03eb /* Vendor ID */ +#define STK541_PID 0x2109 /* Zigbee Controller */ + +/* + * Dresden Elektronic Sensor Terminal Board + */ +#define DE_VID 0x1cf1 /* Vendor ID */ +#define STB_PID 0x0001 /* Sensor Terminal Board */ +#define WHT_PID 0x0004 /* Wireless Handheld Terminal */ + +/* + * Blackfin gnICE JTAG + * http://docs.blackfin.uclinux.org/doku.php?id=hw:jtag:gnice + */ +#define ADI_VID 0x0456 +#define ADI_GNICE_PID 0xF000 + +/* * BmRequestType: 1100 0000b * bRequest: FTDI_E2_READ * wValue: 0 --- linux-2.6.28.orig/drivers/usb/serial/ti_usb_3410_5052.c +++ linux-2.6.28/drivers/usb/serial/ti_usb_3410_5052.c @@ -145,7 +145,7 @@ 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, int type); +static int ti_download_firmware(struct ti_device *tdev); /* circular buffer */ static struct circ_buf *ti_buf_alloc(void); @@ -176,25 +176,32 @@ /* the array dimension is the number of default entries plus */ /* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */ /* null entry */ -static struct usb_device_id ti_id_table_3410[1+TI_EXTRA_VID_PID_COUNT+1] = { +static struct usb_device_id ti_id_table_3410[10+TI_EXTRA_VID_PID_COUNT+1] = { { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) }, { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) }, + { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, + { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) }, + { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) }, }; -static struct usb_device_id ti_id_table_5052[4+TI_EXTRA_VID_PID_COUNT+1] = { +static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = { { USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) }, { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) }, { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) }, { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) }, + { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, }; -static struct usb_device_id ti_id_table_combined[] = { +static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] = { { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) }, { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) }, { USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) }, { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) }, { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) }, { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) }, + { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, + { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) }, + { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) }, { } }; @@ -304,21 +311,28 @@ static int __init ti_init(void) { - int i, j; + int i, j, c; int ret; /* insert extra vendor and product ids */ + c = ARRAY_SIZE(ti_id_table_combined) - 2 * TI_EXTRA_VID_PID_COUNT - 1; j = ARRAY_SIZE(ti_id_table_3410) - TI_EXTRA_VID_PID_COUNT - 1; - for (i = 0; i < min(vendor_3410_count, product_3410_count); i++, j++) { + for (i = 0; i < min(vendor_3410_count, product_3410_count); i++, j++, c++) { ti_id_table_3410[j].idVendor = vendor_3410[i]; ti_id_table_3410[j].idProduct = product_3410[i]; ti_id_table_3410[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE; + ti_id_table_combined[c].idVendor = vendor_3410[i]; + ti_id_table_combined[c].idProduct = product_3410[i]; + ti_id_table_combined[c].match_flags = USB_DEVICE_ID_MATCH_DEVICE; } j = ARRAY_SIZE(ti_id_table_5052) - TI_EXTRA_VID_PID_COUNT - 1; - for (i = 0; i < min(vendor_5052_count, product_5052_count); i++, j++) { + for (i = 0; i < min(vendor_5052_count, product_5052_count); i++, j++, c++) { ti_id_table_5052[j].idVendor = vendor_5052[i]; ti_id_table_5052[j].idProduct = product_5052[i]; ti_id_table_5052[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE; + ti_id_table_combined[c].idVendor = vendor_5052[i]; + ti_id_table_combined[c].idProduct = product_5052[i]; + ti_id_table_combined[c].match_flags = USB_DEVICE_ID_MATCH_DEVICE; } ret = usb_serial_register(&ti_1port_device); @@ -390,11 +404,7 @@ /* if we have only 1 configuration, download firmware */ if (dev->descriptor.bNumConfigurations == 1) { - if (tdev->td_is_3410) - status = ti_download_firmware(tdev, 3410); - else - status = ti_download_firmware(tdev, 5052); - if (status) + if ((status = ti_download_firmware(tdev)) != 0) goto free_tdev; /* 3410 must be reset, 5052 resets itself */ @@ -1671,9 +1681,9 @@ return status; } -static int ti_download_firmware(struct ti_device *tdev, int type) +static int ti_download_firmware(struct ti_device *tdev) { - int status = -ENOMEM; + int status; int buffer_size; __u8 *buffer; struct usb_device *dev = tdev->td_serial->dev; @@ -1681,9 +1691,18 @@ tdev->td_serial->port[0]->bulk_out_endpointAddress); const struct firmware *fw_p; char buf[32]; - sprintf(buf, "ti_usb-%d.bin", type); - if (request_firmware(&fw_p, buf, &dev->dev)) { + /* try ID specific firmware first, then try generic firmware */ + sprintf(buf, "ti_usb-v%04x-p%04x.fw", dev->descriptor.idVendor, + dev->descriptor.idProduct); + if ((status = request_firmware(&fw_p, buf, &dev->dev)) != 0) { + if (tdev->td_is_3410) + strcpy(buf, "ti_3410.fw"); + else + strcpy(buf, "ti_5052.fw"); + status = request_firmware(&fw_p, buf, &dev->dev); + } + if (status) { dev_err(&dev->dev, "%s - firmware not found\n", __func__); return -ENOENT; } @@ -1699,6 +1718,8 @@ memset(buffer + fw_p->size, 0xff, buffer_size - fw_p->size); status = ti_do_download(dev, pipe, buffer, fw_p->size); kfree(buffer); + } else { + status = -ENOMEM; } release_firmware(fw_p); if (status) { --- linux-2.6.28.orig/drivers/usb/serial/ipaq.c +++ linux-2.6.28/drivers/usb/serial/ipaq.c @@ -548,7 +548,6 @@ { USB_DEVICE(0x413C, 0x4009) }, /* Dell Axim USB Sync */ { USB_DEVICE(0x4505, 0x0010) }, /* Smartphone */ { USB_DEVICE(0x5E04, 0xCE00) }, /* SAGEM Wireless Assistant */ - { USB_DEVICE(0x0BB4, 0x00CF) }, /* HTC smartphone modems */ { } /* Terminating entry */ }; --- linux-2.6.28.orig/drivers/usb/serial/option.c +++ linux-2.6.28/drivers/usb/serial/option.c @@ -89,6 +89,7 @@ #define OPTION_PRODUCT_ETNA_MODEM_GT 0x7041 #define OPTION_PRODUCT_ETNA_MODEM_EX 0x7061 #define OPTION_PRODUCT_ETNA_KOI_MODEM 0x7100 +#define OPTION_PRODUCT_GTM380_MODEM 0x7201 #define HUAWEI_VENDOR_ID 0x12D1 #define HUAWEI_PRODUCT_E600 0x1001 @@ -158,6 +159,13 @@ #define HUAWEI_PRODUCT_E143E 0x143E #define HUAWEI_PRODUCT_E143F 0x143F +#define QUANTA_VENDOR_ID 0x0408 +#define QUANTA_PRODUCT_Q101 0xEA02 +#define QUANTA_PRODUCT_Q111 0xEA03 +#define QUANTA_PRODUCT_GLX 0xEA04 +#define QUANTA_PRODUCT_GKE 0xEA05 +#define QUANTA_PRODUCT_GLE 0xEA06 + #define NOVATELWIRELESS_VENDOR_ID 0x1410 /* YISO PRODUCTS */ @@ -190,25 +198,49 @@ /* OVATION PRODUCTS */ #define NOVATELWIRELESS_PRODUCT_MC727 0x4100 #define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 +#define NOVATELWIRELESS_PRODUCT_U727 0x5010 /* FUTURE NOVATEL PRODUCTS */ -#define NOVATELWIRELESS_PRODUCT_EVDO_1 0x6000 -#define NOVATELWIRELESS_PRODUCT_HSPA_1 0x7000 -#define NOVATELWIRELESS_PRODUCT_EMBEDDED_1 0x8000 -#define NOVATELWIRELESS_PRODUCT_GLOBAL_1 0x9000 -#define NOVATELWIRELESS_PRODUCT_EVDO_2 0x6001 -#define NOVATELWIRELESS_PRODUCT_HSPA_2 0x7001 -#define NOVATELWIRELESS_PRODUCT_EMBEDDED_2 0x8001 -#define NOVATELWIRELESS_PRODUCT_GLOBAL_2 0x9001 +#define NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED 0X6000 +#define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001 +#define NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED 0X7000 +#define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED 0X7001 +#define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED 0X8000 +#define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED 0X8001 +#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0X9000 +#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0X9001 +#define NOVATELWIRELESS_PRODUCT_GLOBAL 0XA001 /* AMOI PRODUCTS */ #define AMOI_VENDOR_ID 0x1614 #define AMOI_PRODUCT_H01 0x0800 #define AMOI_PRODUCT_H01A 0x7002 +#define AMOI_PRODUCT_9508 0x0800 #define AMOI_PRODUCT_H02 0x0802 #define DELL_VENDOR_ID 0x413C +/* Dell modems */ +#define DELL_PRODUCT_5700_MINICARD 0x8114 +#define DELL_PRODUCT_5500_MINICARD 0x8115 +#define DELL_PRODUCT_5505_MINICARD 0x8116 +#define DELL_PRODUCT_5700_EXPRESSCARD 0x8117 +#define DELL_PRODUCT_5510_EXPRESSCARD 0x8118 + +#define DELL_PRODUCT_5700_MINICARD_SPRINT 0x8128 +#define DELL_PRODUCT_5700_MINICARD_TELUS 0x8129 + +#define DELL_PRODUCT_5720_MINICARD_VZW 0x8133 +#define DELL_PRODUCT_5720_MINICARD_SPRINT 0x8134 +#define DELL_PRODUCT_5720_MINICARD_TELUS 0x8135 +#define DELL_PRODUCT_5520_MINICARD_CINGULAR 0x8136 +#define DELL_PRODUCT_5520_MINICARD_GENERIC_L 0x8137 +#define DELL_PRODUCT_5520_MINICARD_GENERIC_I 0x8138 + +#define DELL_PRODUCT_5730_MINICARD_SPRINT 0x8180 +#define DELL_PRODUCT_5730_MINICARD_TELUS 0x8181 +#define DELL_PRODUCT_5730_MINICARD_VZW 0x8182 + #define KYOCERA_VENDOR_ID 0x0c88 #define KYOCERA_PRODUCT_KPC650 0x17da #define KYOCERA_PRODUCT_KPC680 0x180a @@ -247,9 +279,6 @@ #define BANDRICH_PRODUCT_1011 0x1011 #define BANDRICH_PRODUCT_1012 0x1012 -#define AMOI_VENDOR_ID 0x1614 -#define AMOI_PRODUCT_9508 0x0800 - #define QUALCOMM_VENDOR_ID 0x05C6 #define MAXON_VENDOR_ID 0x16d8 @@ -259,19 +288,13 @@ /* ZTE PRODUCTS */ #define ZTE_VENDOR_ID 0x19d2 +#define ZTE_PRODUCT_MF622 0x0001 #define ZTE_PRODUCT_MF628 0x0015 #define ZTE_PRODUCT_MF626 0x0031 #define ZTE_PRODUCT_CDMA_TECH 0xfffe -/* Ericsson products */ -#define ERICSSON_VENDOR_ID 0x0bdb -#define ERICSSON_PRODUCT_F3507G 0x1900 - -/* Pantech products */ -#define PANTECH_VENDOR_ID 0x106c -#define PANTECH_PRODUCT_PC5740 0x3701 -#define PANTECH_PRODUCT_PC5750 0x3702 /* PX-500 */ -#define PANTECH_PRODUCT_UM150 0x3711 +#define BENQ_VENDOR_ID 0x04a5 +#define BENQ_PRODUCT_H10 0x4068 static struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, @@ -298,6 +321,12 @@ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_GT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_EX) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_MODEM) }, + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTM380_MODEM) }, + { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_Q101) }, + { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_Q111) }, + { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) }, + { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) }, + { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) }, @@ -383,31 +412,37 @@ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, /* Novatel EU850D/EU860D/EU870D */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_1) }, /* Novatel EVDO product */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_1) }, /* Novatel HSPA product */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EMBEDDED_1) }, /* Novatel Embedded product */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL_1) }, /* Novatel Global product */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_2) }, /* Novatel EVDO product */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_2) }, /* Novatel HSPA product */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EMBEDDED_2) }, /* Novatel Embedded product */ - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL_2) }, /* Novatel Global product */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED) }, /* Novatel EVDO product */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, /* Novatel HSPA Embedded product */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED) }, /* Novatel EVDO product */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED) }, /* Novatel HSPA product */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED) }, /* Novatel EVDO Embedded product */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED) }, /* Novatel HSPA Embedded product */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL) }, /* Novatel Global product */ { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H02) }, - { USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ - { USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ - { USB_DEVICE(DELL_VENDOR_ID, 0x8117) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */ - { USB_DEVICE(DELL_VENDOR_ID, 0x8128) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, 0x8129) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite ET620 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, 0x8133) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ - { USB_DEVICE(DELL_VENDOR_ID, 0x8136) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */ - { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */ - { USB_DEVICE(DELL_VENDOR_ID, 0x8138) }, /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */ - { USB_DEVICE(DELL_VENDOR_ID, 0x8147) }, /* Dell Wireless 5530 Mobile Broadband (3G HSPA) Mini-Card */ + { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */ + { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5500_MINICARD) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ + { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5505_MINICARD) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ + { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_EXPRESSCARD) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */ + { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5510_EXPRESSCARD) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */ + { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD_SPRINT) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */ + { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD_TELUS) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite ET620 CDMA/EV-DO */ + { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_VZW) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ + { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_SPRINT) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ + { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_TELUS) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ + { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_CINGULAR) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */ + { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_GENERIC_L) }, /* Dell Wireless HSDPA 5520 */ + { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_GENERIC_I) }, /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */ + { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ + { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ + { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, @@ -472,13 +507,12 @@ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622) }, { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626) }, { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) }, { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) }, - { USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G) }, - { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_PC5740) }, - { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_PC5750) }, - { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_UM150) }, + { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, + { USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */ { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); --- linux-2.6.28.orig/drivers/usb/serial/ti_usb_3410_5052.h +++ linux-2.6.28/drivers/usb/serial/ti_usb_3410_5052.h @@ -27,7 +27,11 @@ /* Vendor and product ids */ #define TI_VENDOR_ID 0x0451 +#define IBM_VENDOR_ID 0x04b3 #define TI_3410_PRODUCT_ID 0x3410 +#define IBM_4543_PRODUCT_ID 0x4543 +#define IBM_454B_PRODUCT_ID 0x454b +#define IBM_454C_PRODUCT_ID 0x454c #define TI_3410_EZ430_ID 0xF430 /* TI ez430 development tool */ #define TI_5052_BOOT_PRODUCT_ID 0x5052 /* no EEPROM, no firmware */ #define TI_5152_BOOT_PRODUCT_ID 0x5152 /* no EEPROM, no firmware */ --- linux-2.6.28.orig/drivers/usb/serial/cp2101.c +++ linux-2.6.28/drivers/usb/serial/cp2101.c @@ -79,6 +79,7 @@ { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ + { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */ { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */ { USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */ { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ --- linux-2.6.28.orig/drivers/usb/gadget/Kconfig +++ linux-2.6.28/drivers/usb/gadget/Kconfig @@ -208,17 +208,6 @@ default USB_GADGET select USB_GADGET_SELECTED -config USB_OTG - boolean "OTG Support" - depends on USB_GADGET_OMAP && ARCH_OMAP_OTG && USB_OHCI_HCD - help - The most notable feature of USB OTG is support for a - "Dual-Role" device, which can act as either a device - or a host. The initial role choice can be changed - later, when two dual-role devices talk to each other. - - Select this only if your OMAP board has a Mini-AB connector. - config USB_GADGET_PXA25X boolean "PXA 25x or IXP 4xx" depends on (ARCH_PXA && PXA25x) || ARCH_IXP4XX @@ -419,6 +408,25 @@ default USB_GADGET select USB_GADGET_SELECTED +config USB_GADGET_ARC + boolean "Freescale USB Device Controller" + depends on ARCH_MXC + select USB_GADGET_DUALSPEED if USB_GADGET_FSL_1504 || USB_GADGET_FSL_UTMI + help + Some Freescale processors have a USBOTG controller, + which supports device mode. + + Say "y" to link the driver statically, or "m" to build a + dynamically linked module called "arc_udc" and force all + gadget drivers to also be dynamically linked. + +config USB_ARC + tristate + depends on USB_GADGET_ARC + default USB_GADGET + select USB_GADGET_SELECTED + + # # LAST -- dummy/emulated controller @@ -466,6 +474,41 @@ Means that gadget drivers should include extra descriptors and code to handle dual-speed controllers. +config USB_GADGET_ARC_OTG + bool "Support for DR peripheral port on Freescale controller" + depends on USB_GADGET_ARC + default y + help + Enable support for the Freescale Dual Role port in peripheral mode. + +choice + prompt "Select transceiver for DR port" + depends on USB_GADGET_ARC_OTG + help + Choose the transceiver to use with the Freescale DR port. + +config USB_GADGET_FSL_UTMI + bool "On-chip UTMI" + depends on !USB_EHCI_FSL_MC13783 && !USB_EHCI_FSL_1301 && !USB_EHCI_FSL_1504 + ---help--- + Enable support for the High Speed Philips ISP1504 transceiver. + + This is the factory default for the mx35 board. + +endchoice + +config USB_OTG + boolean "OTG Support" + depends on (USB_GADGET_OMAP && ARCH_OMAP_OTG && USB_OHCI_HCD) || \ + (USB_GADGET_ARC && ARCH_MXC && USB_EHCI_HCD) + help + The most notable feature of USB OTG is support for a + "Dual-Role" device, which can act as either a device + or a host. The initial role choice can be changed + later, when two dual-role devices talk to each other. + + Select this only if your OMAP board has a Mini-AB connector. + # # USB Gadget Drivers # --- linux-2.6.28.orig/drivers/usb/gadget/arm_mxc_ubuntu_inode.c +++ linux-2.6.28/drivers/usb/gadget/arm_mxc_ubuntu_inode.c @@ -0,0 +1,2260 @@ +/* + * inode.c -- user mode filesystem api for usb gadget controllers + * + * Copyright (C) 2003-2004 David Brownell + * Copyright (C) 2003 Agilent Technologies + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +/* #define VERBOSE_DEBUG */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +/* + * The gadgetfs API maps each endpoint to a file descriptor so that you + * can use standard synchronous read/write calls for I/O. There's some + * O_NONBLOCK and O_ASYNC/FASYNC style i/o support. Example usermode + * drivers show how this works in practice. You can also use AIO to + * eliminate I/O gaps between requests, to help when streaming data. + * + * Key parts that must be USB-specific are protocols defining how the + * read/write operations relate to the hardware state machines. There + * are two types of files. One type is for the device, implementing ep0. + * The other type is for each IN or OUT endpoint. In both cases, the + * user mode driver must configure the hardware before using it. + * + * - First, dev_config() is called when /dev/gadget/$CHIP is configured + * (by writing configuration and device descriptors). Afterwards it + * may serve as a source of device events, used to handle all control + * requests other than basic enumeration. + * + * - Then, after a SET_CONFIGURATION control request, ep_config() is + * called when each /dev/gadget/ep* file is configured (by writing + * endpoint descriptors). Afterwards these files are used to write() + * IN data or to read() OUT data. To halt the endpoint, a "wrong + * direction" request is issued (like reading an IN endpoint). + * + * Unlike "usbfs" the only ioctl()s are for things that are rare, and maybe + * not possible on all hardware. For example, precise fault handling with + * respect to data left in endpoint fifos after aborted operations; or + * selective clearing of endpoint halts, to implement SET_INTERFACE. + */ + +#define DRIVER_DESC "USB Gadget filesystem" +#define DRIVER_VERSION "24 Aug 2004" + +static const char driver_desc [] = DRIVER_DESC; +static const char shortname [] = "gadgetfs"; + +MODULE_DESCRIPTION (DRIVER_DESC); +MODULE_AUTHOR ("David Brownell"); +MODULE_LICENSE ("GPL"); + +/* Cancel IO, To store the bulkin and bulkout ep data. */ +static struct ep_data *gp_ep_bulkin_data; +static struct ep_data *gp_ep_bulkout_data; + +/*----------------------------------------------------------------------*/ + +#define GADGETFS_MAGIC 0xaee71ee7 +#define DMA_ADDR_INVALID (~(dma_addr_t)0) + +/* /dev/gadget/$CHIP represents ep0 and the whole device */ +enum ep0_state { + /* DISBLED is the initial state. + */ + STATE_DEV_DISABLED = 0, + + /* Only one open() of /dev/gadget/$CHIP; only one file tracks + * ep0/device i/o modes and binding to the controller. Driver + * must always write descriptors to initialize the device, then + * the device becomes UNCONNECTED until enumeration. + */ + STATE_DEV_OPENED, + + /* From then on, ep0 fd is in either of two basic modes: + * - (UN)CONNECTED: read usb_gadgetfs_event(s) from it + * - SETUP: read/write will transfer control data and succeed; + * or if "wrong direction", performs protocol stall + */ + STATE_DEV_UNCONNECTED, + STATE_DEV_CONNECTED, + STATE_DEV_SETUP, + + /* UNBOUND means the driver closed ep0, so the device won't be + * accessible again (DEV_DISABLED) until all fds are closed. + */ + STATE_DEV_UNBOUND, +}; + +/* enough for the whole queue: most events invalidate others */ +#define N_EVENT 5 + +struct dev_data { + spinlock_t lock; + atomic_t count; + enum ep0_state state; /* P: lock */ + struct usb_gadgetfs_event event [N_EVENT]; + unsigned ev_next; + struct fasync_struct *fasync; + u8 current_config; + + /* drivers reading ep0 MUST handle control requests (SETUP) + * reported that way; else the host will time out. + */ + unsigned usermode_setup : 1, + setup_in : 1, + setup_can_stall : 1, + setup_out_ready : 1, + setup_out_error : 1, + setup_abort : 1; + unsigned setup_wLength; + + /* the rest is basically write-once */ + struct usb_config_descriptor *config, *hs_config; + struct usb_device_descriptor *dev; + struct usb_request *req; + struct usb_gadget *gadget; + struct list_head epfiles; + void *buf; + wait_queue_head_t wait; + struct super_block *sb; + struct dentry *dentry; + + /* except this scratch i/o buffer for ep0 */ + u8 rbuf [256]; +}; + +static inline void get_dev (struct dev_data *data) +{ + atomic_inc (&data->count); +} + +static void put_dev (struct dev_data *data) +{ + if (likely (!atomic_dec_and_test (&data->count))) + return; + /* needs no more cleanup */ + BUG_ON (waitqueue_active (&data->wait)); + kfree (data); +} + +static struct dev_data *dev_new (void) +{ + struct dev_data *dev; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return NULL; + dev->state = STATE_DEV_DISABLED; + atomic_set (&dev->count, 1); + spin_lock_init (&dev->lock); + INIT_LIST_HEAD (&dev->epfiles); + init_waitqueue_head (&dev->wait); + return dev; +} + +/*----------------------------------------------------------------------*/ + +/* other /dev/gadget/$ENDPOINT files represent endpoints */ +enum ep_state { + STATE_EP_DISABLED = 0, + STATE_EP_READY, + STATE_EP_ENABLED, + STATE_EP_UNBOUND, +}; + +struct ep_data { + struct semaphore lock; + enum ep_state state; + atomic_t count; + struct dev_data *dev; + /* must hold dev->lock before accessing ep or req */ + struct usb_ep *ep; + struct usb_request *req; + ssize_t status; + char name [16]; + struct usb_endpoint_descriptor desc, hs_desc; + struct list_head epfiles; + wait_queue_head_t wait; + struct dentry *dentry; + struct inode *inode; +}; + +static inline void get_ep (struct ep_data *data) +{ + atomic_inc (&data->count); +} + +static void put_ep (struct ep_data *data) +{ + if (likely (!atomic_dec_and_test (&data->count))) + return; + put_dev (data->dev); + /* needs no more cleanup */ + BUG_ON (!list_empty (&data->epfiles)); + BUG_ON (waitqueue_active (&data->wait)); + kfree (data); +} + +/*----------------------------------------------------------------------*/ + +/* most "how to use the hardware" policy choices are in userspace: + * mapping endpoint roles (which the driver needs) to the capabilities + * which the usb controller has. most of those capabilities are exposed + * implicitly, starting with the driver name and then endpoint names. + */ + +static const char *CHIP; + +/*----------------------------------------------------------------------*/ + +/* NOTE: don't use dev_printk calls before binding to the gadget + * at the end of ep0 configuration, or after unbind. + */ + +/* too wordy: dev_printk(level , &(d)->gadget->dev , fmt , ## args) */ +#define xprintk(d,level,fmt,args...) \ + printk(level "%s: " fmt , shortname , ## args) + +#ifdef DEBUG +#define DBG(dev,fmt,args...) \ + xprintk(dev , KERN_DEBUG , fmt , ## args) +#else +#define DBG(dev,fmt,args...) \ + do { } while (0) +#endif /* DEBUG */ + +#ifdef VERBOSE_DEBUG +#define VDEBUG DBG +#else +#define VDEBUG(dev,fmt,args...) \ + do { } while (0) +#endif /* DEBUG */ + +#define ERROR(dev,fmt,args...) \ + xprintk(dev , KERN_ERR , fmt , ## args) +#define INFO(dev,fmt,args...) \ + xprintk(dev , KERN_INFO , fmt , ## args) + +/* Cancel IO */ +static int mtp_ctrl_cmd; +static int gbCancelFlag; +static unsigned long mtptimestamp; + +/*----------------------------------------------------------------------*/ + +/* SYNCHRONOUS ENDPOINT OPERATIONS (bulk/intr/iso) + * + * After opening, configure non-control endpoints. Then use normal + * stream read() and write() requests; and maybe ioctl() to get more + * precise FIFO status when recovering from cancellation. + */ + +/* Cancel IO */ +static void cancel_io_process(struct work_struct *work) +{ + if (gp_ep_bulkout_data->req->status == -EINPROGRESS) + usb_ep_dequeue(gp_ep_bulkout_data->ep, gp_ep_bulkout_data->req); + + if (gp_ep_bulkin_data->req->status == -EINPROGRESS) + usb_ep_dequeue(gp_ep_bulkin_data->ep, gp_ep_bulkin_data->req); +} +static DECLARE_DELAYED_WORK(cancel_work, cancel_io_process); + +static void epio_complete (struct usb_ep *ep, struct usb_request *req) +{ + struct ep_data *epdata = ep->driver_data; + + if (!req->context) + return; + if (req->status) + epdata->status = req->status; + else + epdata->status = req->actual; + complete ((struct completion *)req->context); +} + +/* tasklock endpoint, returning when it's connected. + * still need dev->lock to use epdata->ep. + */ +static int +get_ready_ep (unsigned f_flags, struct ep_data *epdata) +{ + int val; + + if (f_flags & O_NONBLOCK) { + if (down_trylock (&epdata->lock) != 0) + goto nonblock; + if (epdata->state != STATE_EP_ENABLED) { + up (&epdata->lock); +nonblock: + val = -EAGAIN; + } else + val = 0; + return val; + } + + if ((val = down_interruptible (&epdata->lock)) < 0) + return val; + + switch (epdata->state) { + case STATE_EP_ENABLED: + break; + // case STATE_EP_DISABLED: /* "can't happen" */ + // case STATE_EP_READY: /* "can't happen" */ + default: /* error! */ + pr_debug ("%s: ep %p not available, state %d\n", + shortname, epdata, epdata->state); + // FALLTHROUGH + case STATE_EP_UNBOUND: /* clean disconnect */ + val = -ENODEV; + up (&epdata->lock); + } + return val; +} + +static ssize_t +ep_io (struct ep_data *epdata, void *buf, unsigned len) +{ + DECLARE_COMPLETION_ONSTACK (done); + int value; + + spin_lock_irq (&epdata->dev->lock); + if (likely (epdata->ep != NULL)) { + struct usb_request *req = epdata->req; + + req->context = &done; + req->complete = epio_complete; + req->buf = buf; + req->length = len; + value = usb_ep_queue (epdata->ep, req, GFP_ATOMIC); + } else + value = -ENODEV; + spin_unlock_irq (&epdata->dev->lock); + + if (likely (value == 0)) { + value = wait_event_interruptible (done.wait, done.done); + if (value != 0) { + spin_lock_irq (&epdata->dev->lock); + if (likely (epdata->ep != NULL)) { + DBG (epdata->dev, "%s i/o interrupted\n", + epdata->name); + usb_ep_dequeue (epdata->ep, epdata->req); + spin_unlock_irq (&epdata->dev->lock); + + wait_event (done.wait, done.done); + if (epdata->status == -ECONNRESET) + epdata->status = -EINTR; + } else { + spin_unlock_irq (&epdata->dev->lock); + + DBG (epdata->dev, "endpoint gone\n"); + epdata->status = -ENODEV; + } + } + return epdata->status; + } + return value; +} + + +/* handle a synchronous OUT bulk/intr/iso transfer */ +static ssize_t +ep_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) +{ + struct ep_data *data = fd->private_data; + void *kbuf; + ssize_t value; + + if ((value = get_ready_ep (fd->f_flags, data)) < 0) + return value; + + /* halt any endpoint by doing a "wrong direction" i/o call */ + if (data->desc.bEndpointAddress & USB_DIR_IN) { + if ((data->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_ISOC) + return -EINVAL; + DBG (data->dev, "%s halt\n", data->name); + spin_lock_irq (&data->dev->lock); + if (likely (data->ep != NULL)) + usb_ep_set_halt (data->ep); + spin_unlock_irq (&data->dev->lock); + up (&data->lock); + return -EBADMSG; + } + + /* FIXME readahead for O_NONBLOCK and poll(); careful with ZLPs */ + + value = -ENOMEM; + kbuf = kmalloc (len, GFP_KERNEL); + if (unlikely (!kbuf)) + goto free1; + + value = ep_io (data, kbuf, len); + VDEBUG (data->dev, "%s read %zu OUT, status %d\n", + data->name, len, (int) value); + if (value >= 0 && copy_to_user (buf, kbuf, value)) + value = -EFAULT; + +free1: + up (&data->lock); + kfree (kbuf); + return value; +} + +/* handle a synchronous IN bulk/intr/iso transfer */ +static ssize_t +ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) +{ + struct ep_data *data = fd->private_data; + void *kbuf; + ssize_t value; + + if ((value = get_ready_ep (fd->f_flags, data)) < 0) + return value; + + /* halt any endpoint by doing a "wrong direction" i/o call */ + if (!(data->desc.bEndpointAddress & USB_DIR_IN)) { + if ((data->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_ISOC) + return -EINVAL; + DBG (data->dev, "%s halt\n", data->name); + spin_lock_irq (&data->dev->lock); + if (likely (data->ep != NULL)) + usb_ep_set_halt (data->ep); + spin_unlock_irq (&data->dev->lock); + up (&data->lock); + return -EBADMSG; + } + + /* FIXME writebehind for O_NONBLOCK and poll(), qlen = 1 */ + + value = -ENOMEM; + kbuf = kmalloc (len, GFP_KERNEL); + if (!kbuf) + goto free1; + if (copy_from_user (kbuf, buf, len)) { + value = -EFAULT; + goto free1; + } + + value = ep_io (data, kbuf, len); + VDEBUG (data->dev, "%s write %zu IN, status %d\n", + data->name, len, (int) value); +free1: + up (&data->lock); + kfree (kbuf); + return value; +} + +static int +ep_release (struct inode *inode, struct file *fd) +{ + struct ep_data *data = fd->private_data; + int value; + + if ((value = down_interruptible(&data->lock)) < 0) + return value; + + /* clean up if this can be reopened */ + if (data->state != STATE_EP_UNBOUND) { + data->state = STATE_EP_DISABLED; + data->desc.bDescriptorType = 0; + data->hs_desc.bDescriptorType = 0; + usb_ep_disable(data->ep); + } + up (&data->lock); + put_ep (data); + return 0; +} + +static long ep_ioctl(struct file *fd, unsigned code, unsigned long value) +{ + struct ep_data *data = fd->private_data; + int status; + + if ((status = get_ready_ep (fd->f_flags, data)) < 0) + return status; + + spin_lock_irq (&data->dev->lock); + if (likely (data->ep != NULL)) { + switch (code) { + case GADGETFS_FIFO_STATUS: + status = usb_ep_fifo_status (data->ep); + break; + case GADGETFS_FIFO_FLUSH: + usb_ep_fifo_flush (data->ep); + break; + case GADGETFS_CLEAR_HALT: + status = usb_ep_clear_halt (data->ep); + break; + default: + status = -ENOTTY; + } + } else + status = -ENODEV; + spin_unlock_irq (&data->dev->lock); + up (&data->lock); + return status; +} + +/*----------------------------------------------------------------------*/ + +/* ASYNCHRONOUS ENDPOINT I/O OPERATIONS (bulk/intr/iso) */ + +struct kiocb_priv { + struct usb_request *req; + struct ep_data *epdata; + void *buf; + const struct iovec *iv; + unsigned long nr_segs; + unsigned actual; +}; + +static int ep_aio_cancel(struct kiocb *iocb, struct io_event *e) +{ + struct kiocb_priv *priv = iocb->private; + struct ep_data *epdata; + int value; + + local_irq_disable(); + epdata = priv->epdata; + // spin_lock(&epdata->dev->lock); + kiocbSetCancelled(iocb); + if (likely(epdata && epdata->ep && priv->req)) + value = usb_ep_dequeue (epdata->ep, priv->req); + else + value = -EINVAL; + // spin_unlock(&epdata->dev->lock); + local_irq_enable(); + + aio_put_req(iocb); + return value; +} + +static ssize_t ep_aio_read_retry(struct kiocb *iocb) +{ + struct kiocb_priv *priv = iocb->private; + ssize_t len, total; + void *to_copy; + int i; + + /* we "retry" to get the right mm context for this: */ + + /* copy stuff into user buffers */ + total = priv->actual; + len = 0; + to_copy = priv->buf; + for (i=0; i < priv->nr_segs; i++) { + ssize_t this = min((ssize_t)(priv->iv[i].iov_len), total); + + if (copy_to_user(priv->iv[i].iov_base, to_copy, this)) { + if (len == 0) + len = -EFAULT; + break; + } + + total -= this; + len += this; + to_copy += this; + if (total == 0) + break; + } + kfree(priv->buf); + kfree(priv); + return len; +} + +static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req) +{ + struct kiocb *iocb = req->context; + struct kiocb_priv *priv = iocb->private; + struct ep_data *epdata = priv->epdata; + + /* lock against disconnect (and ideally, cancel) */ + spin_lock(&epdata->dev->lock); + priv->req = NULL; + priv->epdata = NULL; + + /* if this was a write or a read returning no data then we + * don't need to copy anything to userspace, so we can + * complete the aio request immediately. + */ + if (priv->iv == NULL || unlikely(req->actual == 0)) { + kfree(req->buf); + kfree(priv); + iocb->private = NULL; + /* aio_complete() reports bytes-transferred _and_ faults */ + aio_complete(iocb, req->actual ? req->actual : req->status, + req->status); + } else { + /* retry() won't report both; so we hide some faults */ + if (unlikely(0 != req->status)) + DBG(epdata->dev, "%s fault %d len %d\n", + ep->name, req->status, req->actual); + + priv->buf = req->buf; + priv->actual = req->actual; + kick_iocb(iocb); + } + spin_unlock(&epdata->dev->lock); + + usb_ep_free_request(ep, req); + put_ep(epdata); +} + +static ssize_t +ep_aio_rwtail( + struct kiocb *iocb, + char *buf, + size_t len, + struct ep_data *epdata, + const struct iovec *iv, + unsigned long nr_segs +) +{ + struct kiocb_priv *priv; + struct usb_request *req; + ssize_t value; + + priv = kmalloc(sizeof *priv, GFP_KERNEL); + if (!priv) { + value = -ENOMEM; +fail: + kfree(buf); + return value; + } + iocb->private = priv; + priv->iv = iv; + priv->nr_segs = nr_segs; + + value = get_ready_ep(iocb->ki_filp->f_flags, epdata); + if (unlikely(value < 0)) { + kfree(priv); + goto fail; + } + + iocb->ki_cancel = ep_aio_cancel; + get_ep(epdata); + priv->epdata = epdata; + priv->actual = 0; + + /* each kiocb is coupled to one usb_request, but we can't + * allocate or submit those if the host disconnected. + */ + spin_lock_irq(&epdata->dev->lock); + if (likely(epdata->ep)) { + req = usb_ep_alloc_request(epdata->ep, GFP_ATOMIC); + if (likely(req)) { + priv->req = req; + req->buf = buf; + req->length = len; + req->complete = ep_aio_complete; + req->context = iocb; + value = usb_ep_queue(epdata->ep, req, GFP_ATOMIC); + if (unlikely(0 != value)) + usb_ep_free_request(epdata->ep, req); + } else + value = -EAGAIN; + } else + value = -ENODEV; + spin_unlock_irq(&epdata->dev->lock); + + up(&epdata->lock); + + if (unlikely(value)) { + kfree(priv); + put_ep(epdata); + } else + value = (iv ? -EIOCBRETRY : -EIOCBQUEUED); + return value; +} + +static ssize_t +ep_aio_read(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t o) +{ + struct ep_data *epdata = iocb->ki_filp->private_data; + char *buf; + + if (unlikely(epdata->desc.bEndpointAddress & USB_DIR_IN)) + return -EINVAL; + + buf = kmalloc(iocb->ki_left, GFP_KERNEL); + if (unlikely(!buf)) + return -ENOMEM; + + iocb->ki_retry = ep_aio_read_retry; + return ep_aio_rwtail(iocb, buf, iocb->ki_left, epdata, iov, nr_segs); +} + +static ssize_t +ep_aio_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t o) +{ + struct ep_data *epdata = iocb->ki_filp->private_data; + char *buf; + size_t len = 0; + int i = 0; + + if (unlikely(!(epdata->desc.bEndpointAddress & USB_DIR_IN))) + return -EINVAL; + + buf = kmalloc(iocb->ki_left, GFP_KERNEL); + if (unlikely(!buf)) + return -ENOMEM; + + for (i=0; i < nr_segs; i++) { + if (unlikely(copy_from_user(&buf[len], iov[i].iov_base, + iov[i].iov_len) != 0)) { + kfree(buf); + return -EFAULT; + } + len += iov[i].iov_len; + } + return ep_aio_rwtail(iocb, buf, len, epdata, NULL, 0); +} + +/*----------------------------------------------------------------------*/ + +/* used after endpoint configuration */ +static const struct file_operations ep_io_operations = { + .owner = THIS_MODULE, + .llseek = no_llseek, + + .read = ep_read, + .write = ep_write, + .unlocked_ioctl = ep_ioctl, + .release = ep_release, + + .aio_read = ep_aio_read, + .aio_write = ep_aio_write, +}; + +/* ENDPOINT INITIALIZATION + * + * fd = open ("/dev/gadget/$ENDPOINT", O_RDWR) + * status = write (fd, descriptors, sizeof descriptors) + * + * That write establishes the endpoint configuration, configuring + * the controller to process bulk, interrupt, or isochronous transfers + * at the right maxpacket size, and so on. + * + * The descriptors are message type 1, identified by a host order u32 + * at the beginning of what's written. Descriptor order is: full/low + * speed descriptor, then optional high speed descriptor. + */ +static ssize_t +ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) +{ + struct ep_data *data = fd->private_data; + struct usb_ep *ep; + u32 tag; + int value, length = len; + + if ((value = down_interruptible (&data->lock)) < 0) + return value; + + if (data->state != STATE_EP_READY) { + value = -EL2HLT; + goto fail; + } + + value = len; + if (len < USB_DT_ENDPOINT_SIZE + 4) + goto fail0; + + /* we might need to change message format someday */ + if (copy_from_user (&tag, buf, 4)) { + goto fail1; + } + if (tag != 1) { + DBG(data->dev, "config %s, bad tag %d\n", data->name, tag); + goto fail0; + } + buf += 4; + len -= 4; + + /* NOTE: audio endpoint extensions not accepted here; + * just don't include the extra bytes. + */ + + /* full/low speed descriptor, then high speed */ + if (copy_from_user (&data->desc, buf, USB_DT_ENDPOINT_SIZE)) { + goto fail1; + } + if (data->desc.bLength != USB_DT_ENDPOINT_SIZE + || data->desc.bDescriptorType != USB_DT_ENDPOINT) + goto fail0; + if (len != USB_DT_ENDPOINT_SIZE) { + if (len != 2 * USB_DT_ENDPOINT_SIZE) + goto fail0; + if (copy_from_user (&data->hs_desc, buf + USB_DT_ENDPOINT_SIZE, + USB_DT_ENDPOINT_SIZE)) { + goto fail1; + } + if (data->hs_desc.bLength != USB_DT_ENDPOINT_SIZE + || data->hs_desc.bDescriptorType + != USB_DT_ENDPOINT) { + DBG(data->dev, "config %s, bad hs length or type\n", + data->name); + goto fail0; + } + } + + spin_lock_irq (&data->dev->lock); + if (data->dev->state == STATE_DEV_UNBOUND) { + value = -ENOENT; + goto gone; + } else if ((ep = data->ep) == NULL) { + value = -ENODEV; + goto gone; + } + switch (data->dev->gadget->speed) { + case USB_SPEED_LOW: + case USB_SPEED_FULL: + value = usb_ep_enable (ep, &data->desc); + if (value == 0) + data->state = STATE_EP_ENABLED; + break; +#ifdef CONFIG_USB_GADGET_DUALSPEED + case USB_SPEED_HIGH: + /* fails if caller didn't provide that descriptor... */ + value = usb_ep_enable (ep, &data->hs_desc); + if (value == 0) + data->state = STATE_EP_ENABLED; + break; +#endif + default: + DBG(data->dev, "unconnected, %s init abandoned\n", + data->name); + value = -EINVAL; + } + if (value == 0) { + fd->f_op = &ep_io_operations; + value = length; + } +gone: + spin_unlock_irq (&data->dev->lock); + if (value < 0) { +fail: + data->desc.bDescriptorType = 0; + data->hs_desc.bDescriptorType = 0; + } + up (&data->lock); + return value; +fail0: + value = -EINVAL; + goto fail; +fail1: + value = -EFAULT; + goto fail; +} + +static int +ep_open (struct inode *inode, struct file *fd) +{ + struct ep_data *data = inode->i_private; + int value = -EBUSY; + char *epin = "ep1in"; + char *epout = "ep1out"; + + if (down_interruptible (&data->lock) != 0) + return -EINTR; + spin_lock_irq (&data->dev->lock); + + if (data->dev->state == STATE_DEV_UNBOUND) + value = -ENOENT; + else if (data->state == STATE_EP_DISABLED) { + value = 0; + data->state = STATE_EP_READY; + get_ep (data); + fd->private_data = data; + VDEBUG (data->dev, "%s ready\n", data->name); + /* Cancel IO */ + if (0 == strcmp(data->name, epin)) + gp_ep_bulkin_data = fd->private_data; + + if (0 == strcmp(data->name, epout)) + gp_ep_bulkout_data = fd->private_data; + } else + DBG (data->dev, "%s state %d\n", + data->name, data->state); + + spin_unlock_irq (&data->dev->lock); + up (&data->lock); + return value; +} + +/* used before endpoint configuration */ +static const struct file_operations ep_config_operations = { + .owner = THIS_MODULE, + .llseek = no_llseek, + + .open = ep_open, + .write = ep_config, + .release = ep_release, +}; + +/*----------------------------------------------------------------------*/ + +/* EP0 IMPLEMENTATION can be partly in userspace. + * + * Drivers that use this facility receive various events, including + * control requests the kernel doesn't handle. Drivers that don't + * use this facility may be too simple-minded for real applications. + */ + +static inline void ep0_readable (struct dev_data *dev) +{ + wake_up (&dev->wait); + kill_fasync (&dev->fasync, SIGIO, POLL_IN); +} + +static void clean_req (struct usb_ep *ep, struct usb_request *req) +{ + struct dev_data *dev = ep->driver_data; + + if (req->buf != dev->rbuf) { + kfree(req->buf); + req->buf = dev->rbuf; + req->dma = DMA_ADDR_INVALID; + } + req->complete = epio_complete; + dev->setup_out_ready = 0; +} + +static void ep0_complete (struct usb_ep *ep, struct usb_request *req) +{ + struct dev_data *dev = ep->driver_data; + unsigned long flags; + int free = 1; + + /* for control OUT, data must still get to userspace */ + spin_lock_irqsave(&dev->lock, flags); + if (!dev->setup_in) { + dev->setup_out_error = (req->status != 0); + if (!dev->setup_out_error) + free = 0; + dev->setup_out_ready = 1; + ep0_readable (dev); + } + + /* clean up as appropriate */ + if (free && req->buf != &dev->rbuf) + clean_req (ep, req); + req->complete = epio_complete; + spin_unlock_irqrestore(&dev->lock, flags); +} + +static int setup_req (struct usb_ep *ep, struct usb_request *req, u16 len) +{ + struct dev_data *dev = ep->driver_data; + + if (dev->setup_out_ready) { + DBG (dev, "ep0 request busy!\n"); + return -EBUSY; + } + if (len > sizeof (dev->rbuf)) + req->buf = kmalloc(len, GFP_ATOMIC); + if (req->buf == NULL) { + req->buf = dev->rbuf; + return -ENOMEM; + } + req->complete = ep0_complete; + req->length = len; + req->zero = 0; + return 0; +} + +static ssize_t +ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) +{ + struct dev_data *dev = fd->private_data; + ssize_t retval; + enum ep0_state state; + + spin_lock_irq (&dev->lock); + + /* report fd mode change before acting on it */ + if (dev->setup_abort) { + dev->setup_abort = 0; + retval = -EIDRM; + goto done; + } + + /* control DATA stage */ + if ((state = dev->state) == STATE_DEV_SETUP) { + + if (dev->setup_in) { /* stall IN */ + VDEBUG(dev, "ep0in stall\n"); + (void) usb_ep_set_halt (dev->gadget->ep0); + retval = -EL2HLT; + dev->state = STATE_DEV_CONNECTED; + + } else if (len == 0) { /* ack SET_CONFIGURATION etc */ + struct usb_ep *ep = dev->gadget->ep0; + struct usb_request *req = dev->req; + + if ((retval = setup_req (ep, req, 0)) == 0) + retval = usb_ep_queue (ep, req, GFP_ATOMIC); + dev->state = STATE_DEV_CONNECTED; + + /* assume that was SET_CONFIGURATION */ + if (dev->current_config) { + unsigned power; + + if (gadget_is_dualspeed(dev->gadget) + && (dev->gadget->speed + == USB_SPEED_HIGH)) + power = dev->hs_config->bMaxPower; + else + power = dev->config->bMaxPower; + usb_gadget_vbus_draw(dev->gadget, 2 * power); + } + + } else { /* collect OUT data */ + if ((fd->f_flags & O_NONBLOCK) != 0 + && !dev->setup_out_ready) { + retval = -EAGAIN; + goto done; + } + spin_unlock_irq (&dev->lock); + retval = wait_event_interruptible (dev->wait, + dev->setup_out_ready != 0); + + /* FIXME state could change from under us */ + spin_lock_irq (&dev->lock); + if (retval) + goto done; + + if (dev->state != STATE_DEV_SETUP) { + retval = -ECANCELED; + goto done; + } + dev->state = STATE_DEV_CONNECTED; + + if (dev->setup_out_error) + retval = -EIO; + else { + len = min (len, (size_t)dev->req->actual); +/* FIXME don't call this with the spinlock held ... */ + if (copy_to_user (buf, dev->req->buf, len)) + retval = -EFAULT; + else + /* Bug of Cancel IO 6 bytes read. */ + retval = len; + clean_req (dev->gadget->ep0, dev->req); + /* NOTE userspace can't yet choose to stall */ + dev->state = STATE_DEV_CONNECTED; /* Cancel IO */ + } + } + goto done; + } + + /* else normal: return event data */ + if (len < sizeof dev->event [0]) { + retval = -EINVAL; + goto done; + } + len -= len % sizeof (struct usb_gadgetfs_event); + dev->usermode_setup = 1; + + /* Cancel IO, signal abort blocked IO. */ + if (mtp_ctrl_cmd == 1) { + mtp_ctrl_cmd = 0; + schedule_delayed_work(&cancel_work, HZ / 100); + } + +scan: + /* return queued events right away */ + if (dev->ev_next != 0) { + unsigned i, n; + + n = len / sizeof (struct usb_gadgetfs_event); + if (dev->ev_next < n) + n = dev->ev_next; + + /* ep0 i/o has special semantics during STATE_DEV_SETUP */ + for (i = 0; i < n; i++) { + if (dev->event [i].type == GADGETFS_SETUP) { + dev->state = STATE_DEV_SETUP; + n = i + 1; + break; + } + } + spin_unlock_irq (&dev->lock); + len = n * sizeof (struct usb_gadgetfs_event); + if (copy_to_user (buf, &dev->event, len)) + retval = -EFAULT; + else + retval = len; + if (len > 0) { + /* NOTE this doesn't guard against broken drivers; + * concurrent ep0 readers may lose events. + */ + spin_lock_irq (&dev->lock); + if (dev->ev_next > n) { + memmove(&dev->event[0], &dev->event[n], + sizeof (struct usb_gadgetfs_event) + * (dev->ev_next - n)); + } + dev->ev_next -= n; + spin_unlock_irq (&dev->lock); + } + return retval; + } + if (fd->f_flags & O_NONBLOCK) { + retval = -EAGAIN; + goto done; + } + + switch (state) { + default: + DBG (dev, "fail %s, state %d\n", __func__, state); + retval = -ESRCH; + break; + case STATE_DEV_UNCONNECTED: + case STATE_DEV_CONNECTED: + spin_unlock_irq (&dev->lock); + DBG (dev, "%s wait\n", __func__); + + /* wait for events */ + retval = wait_event_interruptible (dev->wait, + dev->ev_next != 0); + if (retval < 0) + return retval; + spin_lock_irq (&dev->lock); + goto scan; + } + +done: + spin_unlock_irq (&dev->lock); + return retval; +} + +static struct usb_gadgetfs_event * +next_event (struct dev_data *dev, enum usb_gadgetfs_event_type type) +{ + struct usb_gadgetfs_event *event; + unsigned i; + + switch (type) { + /* these events purge the queue */ + case GADGETFS_DISCONNECT: + if (dev->state == STATE_DEV_SETUP) + dev->setup_abort = 1; + // FALL THROUGH + case GADGETFS_CONNECT: + dev->ev_next = 0; + break; + case GADGETFS_SETUP: /* previous request timed out */ + case GADGETFS_SUSPEND: /* same effect */ + /* these events can't be repeated */ + for (i = 0; i != dev->ev_next; i++) { + if (dev->event [i].type != type) + continue; + DBG(dev, "discard old event[%d] %d\n", i, type); + dev->ev_next--; + if (i == dev->ev_next) + break; + /* indices start at zero, for simplicity */ + memmove (&dev->event [i], &dev->event [i + 1], + sizeof (struct usb_gadgetfs_event) + * (dev->ev_next - i)); + } + break; + default: + BUG (); + } + VDEBUG(dev, "event[%d] = %d\n", dev->ev_next, type); + event = &dev->event [dev->ev_next++]; + BUG_ON (dev->ev_next > N_EVENT); + memset (event, 0, sizeof *event); + event->type = type; + return event; +} + +static ssize_t +ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) +{ + struct dev_data *dev = fd->private_data; + ssize_t retval = -ESRCH; + + spin_lock_irq (&dev->lock); + + /* report fd mode change before acting on it */ + if (dev->setup_abort) { + dev->setup_abort = 0; + retval = -EIDRM; + + /* data and/or status stage for control request */ + } else if (dev->state == STATE_DEV_SETUP) { + + /* IN DATA+STATUS caller makes len <= wLength */ + if (dev->setup_in) { + retval = setup_req (dev->gadget->ep0, dev->req, len); + if (retval == 0) { + dev->state = STATE_DEV_CONNECTED; + spin_unlock_irq (&dev->lock); + if (copy_from_user (dev->req->buf, buf, len)) + retval = -EFAULT; + else { + if (len < dev->setup_wLength) + dev->req->zero = 1; + retval = usb_ep_queue ( + dev->gadget->ep0, dev->req, + GFP_KERNEL); + } + if (retval < 0) { + spin_lock_irq (&dev->lock); + clean_req (dev->gadget->ep0, dev->req); + spin_unlock_irq (&dev->lock); + } else + retval = len; + + return retval; + } + + /* can stall some OUT transfers */ + } else if (dev->setup_can_stall) { + VDEBUG(dev, "ep0out stall\n"); + (void) usb_ep_set_halt (dev->gadget->ep0); + retval = -EL2HLT; + dev->state = STATE_DEV_CONNECTED; + } else { + DBG(dev, "bogus ep0out stall!\n"); + } + } else + DBG (dev, "fail %s, state %d\n", __func__, dev->state); + + spin_unlock_irq (&dev->lock); + return retval; +} + +static int +ep0_fasync (int f, struct file *fd, int on) +{ + struct dev_data *dev = fd->private_data; + // caller must F_SETOWN before signal delivery happens + VDEBUG (dev, "%s %s\n", __func__, on ? "on" : "off"); + return fasync_helper (f, fd, on, &dev->fasync); +} + +static struct usb_gadget_driver gadgetfs_driver; + +static int +dev_release (struct inode *inode, struct file *fd) +{ + struct dev_data *dev = fd->private_data; + + /* closing ep0 === shutdown all */ + + usb_gadget_unregister_driver (&gadgetfs_driver); + + /* at this point "good" hardware has disconnected the + * device from USB; the host won't see it any more. + * alternatively, all host requests will time out. + */ + + kfree (dev->buf); + dev->buf = NULL; + put_dev (dev); + + /* other endpoints were all decoupled from this device */ + spin_lock_irq(&dev->lock); + dev->state = STATE_DEV_DISABLED; + spin_unlock_irq(&dev->lock); + return 0; +} + +static unsigned int +ep0_poll (struct file *fd, poll_table *wait) +{ + struct dev_data *dev = fd->private_data; + int mask = 0; + + poll_wait(fd, &dev->wait, wait); + + spin_lock_irq (&dev->lock); + + /* report fd mode change before acting on it */ + if (dev->setup_abort) { + dev->setup_abort = 0; + mask = POLLHUP; + goto out; + } + + if (dev->state == STATE_DEV_SETUP) { + if (dev->setup_in || dev->setup_can_stall) + mask = POLLOUT; + } else { + if (dev->ev_next != 0) + mask = POLLIN; + } +out: + spin_unlock_irq(&dev->lock); + return mask; +} + +static long dev_ioctl (struct file *fd, unsigned code, unsigned long value) +{ + struct dev_data *dev = fd->private_data; + struct usb_gadget *gadget = dev->gadget; + long ret = -ENOTTY; + + if (gadget->ops->ioctl) { + lock_kernel(); + ret = gadget->ops->ioctl (gadget, code, value); + unlock_kernel(); + } + return ret; +} + +/* used after device configuration */ +static const struct file_operations ep0_io_operations = { + .owner = THIS_MODULE, + .llseek = no_llseek, + + .read = ep0_read, + .write = ep0_write, + .fasync = ep0_fasync, + .poll = ep0_poll, + .unlocked_ioctl = dev_ioctl, + .release = dev_release, +}; + +/*----------------------------------------------------------------------*/ + +/* The in-kernel gadget driver handles most ep0 issues, in particular + * enumerating the single configuration (as provided from user space). + * + * Unrecognized ep0 requests may be handled in user space. + */ + +#ifdef CONFIG_USB_GADGET_DUALSPEED +static void make_qualifier (struct dev_data *dev) +{ + struct usb_qualifier_descriptor qual; + struct usb_device_descriptor *desc; + + qual.bLength = sizeof qual; + qual.bDescriptorType = USB_DT_DEVICE_QUALIFIER; + qual.bcdUSB = __constant_cpu_to_le16 (0x0200); + + desc = dev->dev; + qual.bDeviceClass = desc->bDeviceClass; + qual.bDeviceSubClass = desc->bDeviceSubClass; + qual.bDeviceProtocol = desc->bDeviceProtocol; + + /* assumes ep0 uses the same value for both speeds ... */ + qual.bMaxPacketSize0 = desc->bMaxPacketSize0; + + qual.bNumConfigurations = 1; + qual.bRESERVED = 0; + + memcpy (dev->rbuf, &qual, sizeof qual); +} +#endif + +static int +config_buf (struct dev_data *dev, u8 type, unsigned index) +{ + int len; + int hs = 0; + + /* only one configuration */ + if (index > 0) + return -EINVAL; + + if (gadget_is_dualspeed(dev->gadget)) { + hs = (dev->gadget->speed == USB_SPEED_HIGH); + if (type == USB_DT_OTHER_SPEED_CONFIG) + hs = !hs; + } + if (hs) { + dev->req->buf = dev->hs_config; + len = le16_to_cpu(dev->hs_config->wTotalLength); + } else { + dev->req->buf = dev->config; + len = le16_to_cpu(dev->config->wTotalLength); + } + ((u8 *)dev->req->buf) [1] = type; + return len; +} + +static int +gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) +{ + struct dev_data *dev = get_gadget_data (gadget); + struct usb_request *req = dev->req; + int value = -EOPNOTSUPP; + struct usb_gadgetfs_event *event; + u16 w_value = le16_to_cpu(ctrl->wValue); + u16 w_length = le16_to_cpu(ctrl->wLength); + struct timeval tv; + + /* Cancel IO */ + if (0x67 == ctrl->bRequest && 1 == gbCancelFlag + && dev->state == STATE_DEV_SETUP) + dev->state = STATE_DEV_CONNECTED; + + if (0x67 == ctrl->bRequest && 2 == mtp_ctrl_cmd + && dev->state == STATE_DEV_SETUP) + dev->state = STATE_DEV_CONNECTED; + + spin_lock (&dev->lock); + dev->setup_abort = 0; + if (dev->state == STATE_DEV_UNCONNECTED) { + if (gadget_is_dualspeed(gadget) + && gadget->speed == USB_SPEED_HIGH + && dev->hs_config == NULL) { + spin_unlock(&dev->lock); + ERROR (dev, "no high speed config??\n"); + return -EINVAL; + } + + dev->state = STATE_DEV_CONNECTED; + dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket; + + INFO (dev, "connected\n"); + event = next_event (dev, GADGETFS_CONNECT); + event->u.speed = gadget->speed; + ep0_readable (dev); + + /* host may have given up waiting for response. we can miss control + * requests handled lower down (device/endpoint status and features); + * then ep0_{read,write} will report the wrong status. controller + * driver will have aborted pending i/o. + */ + } else if (dev->state == STATE_DEV_SETUP) + dev->setup_abort = 1; + /*Cancel IO */ + if (mtp_ctrl_cmd == 1 && gbCancelFlag == 1 && dev->setup_abort == 1) { + INFO(dev, "0x64->setup\n"); + dev->setup_abort = 0; + } + + req->buf = dev->rbuf; + req->dma = DMA_ADDR_INVALID; + req->context = NULL; + value = -EOPNOTSUPP; + switch (ctrl->bRequest) { + + case USB_REQ_GET_DESCRIPTOR: + if (ctrl->bRequestType != USB_DIR_IN) + goto unrecognized; + switch (w_value >> 8) { + + case USB_DT_DEVICE: + value = min (w_length, (u16) sizeof *dev->dev); + req->buf = dev->dev; + break; +#ifdef CONFIG_USB_GADGET_DUALSPEED + case USB_DT_DEVICE_QUALIFIER: + if (!dev->hs_config) + break; + value = min (w_length, (u16) + sizeof (struct usb_qualifier_descriptor)); + make_qualifier (dev); + break; + case USB_DT_OTHER_SPEED_CONFIG: + /* FALLTHROUGH */ +#endif + case USB_DT_CONFIG: + value = config_buf (dev, + w_value >> 8, + w_value & 0xff); + if (value >= 0) + value = min (w_length, (u16) value); + break; + case USB_DT_STRING: + goto unrecognized; + + default: // all others are errors + break; + } + break; + + /* currently one config, two speeds */ + case USB_REQ_SET_CONFIGURATION: + if (ctrl->bRequestType != 0) + goto unrecognized; + if (0 == (u8) w_value) { + value = 0; + dev->current_config = 0; + usb_gadget_vbus_draw(gadget, 8 /* mA */ ); + // user mode expected to disable endpoints + } else { + u8 config, power; + + if (gadget_is_dualspeed(gadget) + && gadget->speed == USB_SPEED_HIGH) { + config = dev->hs_config->bConfigurationValue; + power = dev->hs_config->bMaxPower; + } else { + config = dev->config->bConfigurationValue; + power = dev->config->bMaxPower; + } + + if (config == (u8) w_value) { + value = 0; + dev->current_config = config; + usb_gadget_vbus_draw(gadget, 2 * power); + } + } + + /* report SET_CONFIGURATION like any other control request, + * except that usermode may not stall this. the next + * request mustn't be allowed start until this finishes: + * endpoints and threads set up, etc. + * + * NOTE: older PXA hardware (before PXA 255: without UDCCFR) + * has bad/racey automagic that prevents synchronizing here. + * even kernel mode drivers often miss them. + */ + if (value == 0) { + INFO (dev, "configuration #%d\n", dev->current_config); + if (dev->usermode_setup) { + dev->setup_can_stall = 0; + goto delegate; + } + } + break; + +#ifndef CONFIG_USB_GADGET_PXA25X + /* PXA automagically handles this request too */ + case USB_REQ_GET_CONFIGURATION: + if (ctrl->bRequestType != 0x80) + goto unrecognized; + *(u8 *)req->buf = dev->current_config; + value = min (w_length, (u16) 1); + break; +#endif + + default: +unrecognized: + VDEBUG (dev, "%s req%02x.%02x v%04x i%04x l%d\n", + dev->usermode_setup ? "delegate" : "fail", + ctrl->bRequestType, ctrl->bRequest, + w_value, le16_to_cpu(ctrl->wIndex), w_length); + + /* if there's an ep0 reader, don't stall */ + if (dev->usermode_setup) { + dev->setup_can_stall = 1; +delegate: + dev->setup_in = (ctrl->bRequestType & USB_DIR_IN) + ? 1 : 0; + dev->setup_wLength = w_length; + dev->setup_out_ready = 0; + dev->setup_out_error = 0; + value = 0; + + /* read DATA stage for OUT right away */ + if (unlikely (!dev->setup_in && w_length)) { + value = setup_req (gadget->ep0, dev->req, + w_length); + if (value < 0) + break; + value = usb_ep_queue (gadget->ep0, dev->req, + GFP_ATOMIC); + if (value < 0) { + clean_req (gadget->ep0, dev->req); + break; + } + + /* we can't currently stall these */ + dev->setup_can_stall = 0; + } + /* Cancel IO */ + if (0x67 == ctrl->bRequest && 1 == gbCancelFlag) { + gbCancelFlag = 0; + + setup_req(gadget->ep0, dev->req, 4); + *(unsigned long *)dev->req->buf = 0x20190004; + usb_ep_queue(gadget->ep0, dev->req, GFP_ATOMIC); + + spin_unlock(&dev->lock); + return 0; + } + if (ctrl->bRequest == 0x67 && mtp_ctrl_cmd == 2) { + /* get status */ + mtp_ctrl_cmd = 0; + } + + /* state changes when reader collects event */ + event = next_event (dev, GADGETFS_SETUP); + event->u.setup = *ctrl; + /* Cancel IO */ + if (0x64 == ctrl->bRequest) { + mtp_ctrl_cmd = 1; + gbCancelFlag = 1; + + /* get the timestamp */ + do_gettimeofday(&tv); + mtptimestamp = tv.tv_usec; + event->u.setup.wValue = + (unsigned short)tv.tv_usec; + } + if (0x66 == ctrl->bRequest) { + /* get the timestamp */ + do_gettimeofday(&tv); + mtptimestamp = tv.tv_usec; + event->u.setup.wValue = + (unsigned short)tv.tv_usec; + } + + ep0_readable (dev); + /* Reset request. */ + if (ctrl->bRequest == 0x66) { /* reset ,send ZLP */ + mtp_ctrl_cmd = 2; + + if (gp_ep_bulkout_data->req->status == + -EINPROGRESS) { + usb_ep_dequeue(gp_ep_bulkout_data->ep, + gp_ep_bulkout_data->req); + } + if (gp_ep_bulkin_data->req->status == + -EINPROGRESS) { + usb_ep_dequeue(gp_ep_bulkin_data->ep, + gp_ep_bulkin_data->req); + } + } + if (ctrl->bRequest == 0x65) + pr_debug("i:0x65,not supported\n"); + + spin_unlock (&dev->lock); + return 0; + } + } + + /* proceed with data transfer and status phases? */ + if (value >= 0 && dev->state != STATE_DEV_SETUP) { + req->length = value; + req->zero = value < w_length; + value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC); + if (value < 0) { + DBG (dev, "ep_queue --> %d\n", value); + req->status = 0; + } + } + + /* device stalls when value < 0 */ + spin_unlock (&dev->lock); + return value; +} + +static void destroy_ep_files (struct dev_data *dev) +{ + struct list_head *entry, *tmp; + + DBG (dev, "%s %d\n", __func__, dev->state); + + /* dev->state must prevent interference */ +restart: + spin_lock_irq (&dev->lock); + list_for_each_safe (entry, tmp, &dev->epfiles) { + struct ep_data *ep; + struct inode *parent; + struct dentry *dentry; + + /* break link to FS */ + ep = list_entry (entry, struct ep_data, epfiles); + list_del_init (&ep->epfiles); + dentry = ep->dentry; + ep->dentry = NULL; + parent = dentry->d_parent->d_inode; + + /* break link to controller */ + if (ep->state == STATE_EP_ENABLED) + (void) usb_ep_disable (ep->ep); + ep->state = STATE_EP_UNBOUND; + usb_ep_free_request (ep->ep, ep->req); + ep->ep = NULL; + wake_up (&ep->wait); + put_ep (ep); + + spin_unlock_irq (&dev->lock); + + /* break link to dcache */ + mutex_lock (&parent->i_mutex); + d_delete (dentry); + dput (dentry); + mutex_unlock (&parent->i_mutex); + + /* fds may still be open */ + goto restart; + } + spin_unlock_irq (&dev->lock); +} + + +static struct inode * +gadgetfs_create_file (struct super_block *sb, char const *name, + void *data, const struct file_operations *fops, + struct dentry **dentry_p); + +static int activate_ep_files (struct dev_data *dev) +{ + struct usb_ep *ep; + struct ep_data *data; + + gadget_for_each_ep (ep, dev->gadget) { + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + goto enomem0; + data->state = STATE_EP_DISABLED; + init_MUTEX (&data->lock); + init_waitqueue_head (&data->wait); + + strncpy (data->name, ep->name, sizeof (data->name) - 1); + atomic_set (&data->count, 1); + data->dev = dev; + get_dev (dev); + + data->ep = ep; + ep->driver_data = data; + + data->req = usb_ep_alloc_request (ep, GFP_KERNEL); + if (!data->req) + goto enomem1; + + data->inode = gadgetfs_create_file (dev->sb, data->name, + data, &ep_config_operations, + &data->dentry); + if (!data->inode) + goto enomem2; + list_add_tail (&data->epfiles, &dev->epfiles); + } + return 0; + +enomem2: + usb_ep_free_request (ep, data->req); +enomem1: + put_dev (dev); + kfree (data); +enomem0: + DBG (dev, "%s enomem\n", __func__); + destroy_ep_files (dev); + return -ENOMEM; +} + +static void +gadgetfs_unbind (struct usb_gadget *gadget) +{ + struct dev_data *dev = get_gadget_data (gadget); + + DBG (dev, "%s\n", __func__); + + spin_lock_irq (&dev->lock); + dev->state = STATE_DEV_UNBOUND; + spin_unlock_irq (&dev->lock); + + destroy_ep_files (dev); + gadget->ep0->driver_data = NULL; + set_gadget_data (gadget, NULL); + + /* we've already been disconnected ... no i/o is active */ + if (dev->req) + usb_ep_free_request (gadget->ep0, dev->req); + DBG (dev, "%s done\n", __func__); + put_dev (dev); +} + +static struct dev_data *the_device; + +static int +gadgetfs_bind (struct usb_gadget *gadget) +{ + struct dev_data *dev = the_device; + + if (!dev) + return -ESRCH; + if (0 != strcmp (CHIP, gadget->name)) { + pr_err("%s expected %s controller not %s\n", + shortname, CHIP, gadget->name); + return -ENODEV; + } + + set_gadget_data (gadget, dev); + dev->gadget = gadget; + gadget->ep0->driver_data = dev; + dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket; + + /* preallocate control response and buffer */ + dev->req = usb_ep_alloc_request (gadget->ep0, GFP_KERNEL); + if (!dev->req) + goto enomem; + dev->req->context = NULL; + dev->req->complete = epio_complete; + + if (activate_ep_files (dev) < 0) + goto enomem; + + INFO (dev, "bound to %s driver\n", gadget->name); + spin_lock_irq(&dev->lock); + dev->state = STATE_DEV_UNCONNECTED; + spin_unlock_irq(&dev->lock); + get_dev (dev); + return 0; + +enomem: + gadgetfs_unbind (gadget); + return -ENOMEM; +} + +static void +gadgetfs_disconnect (struct usb_gadget *gadget) +{ + struct dev_data *dev = get_gadget_data (gadget); + + spin_lock (&dev->lock); + if (dev->state == STATE_DEV_UNCONNECTED) + goto exit; + dev->state = STATE_DEV_UNCONNECTED; + + INFO (dev, "disconnected\n"); + next_event (dev, GADGETFS_DISCONNECT); + ep0_readable (dev); +exit: + spin_unlock (&dev->lock); +} + +static void +gadgetfs_suspend (struct usb_gadget *gadget) +{ + struct dev_data *dev = get_gadget_data (gadget); + + INFO (dev, "suspended from state %d\n", dev->state); + spin_lock (&dev->lock); + switch (dev->state) { + case STATE_DEV_SETUP: // VERY odd... host died?? + case STATE_DEV_CONNECTED: + case STATE_DEV_UNCONNECTED: + next_event (dev, GADGETFS_SUSPEND); + ep0_readable (dev); + /* FALLTHROUGH */ + default: + break; + } + spin_unlock (&dev->lock); +} + +static struct usb_gadget_driver gadgetfs_driver = { +#ifdef CONFIG_USB_GADGET_DUALSPEED + .speed = USB_SPEED_HIGH, +#else + .speed = USB_SPEED_FULL, +#endif + .function = (char *) driver_desc, + .bind = gadgetfs_bind, + .unbind = gadgetfs_unbind, + .setup = gadgetfs_setup, + .disconnect = gadgetfs_disconnect, + .suspend = gadgetfs_suspend, + + .driver = { + .name = (char *) shortname, + }, +}; + +/*----------------------------------------------------------------------*/ + +static void gadgetfs_nop(struct usb_gadget *arg) { } + +static int gadgetfs_probe (struct usb_gadget *gadget) +{ + CHIP = gadget->name; + return -EISNAM; +} + +static struct usb_gadget_driver probe_driver = { + .speed = USB_SPEED_HIGH, + .bind = gadgetfs_probe, + .unbind = gadgetfs_nop, + .setup = (void *)gadgetfs_nop, + .disconnect = gadgetfs_nop, + .driver = { + .name = "nop", + }, +}; + + +/* DEVICE INITIALIZATION + * + * fd = open ("/dev/gadget/$CHIP", O_RDWR) + * status = write (fd, descriptors, sizeof descriptors) + * + * That write establishes the device configuration, so the kernel can + * bind to the controller ... guaranteeing it can handle enumeration + * at all necessary speeds. Descriptor order is: + * + * . message tag (u32, host order) ... for now, must be zero; it + * would change to support features like multi-config devices + * . full/low speed config ... all wTotalLength bytes (with interface, + * class, altsetting, endpoint, and other descriptors) + * . high speed config ... all descriptors, for high speed operation; + * this one's optional except for high-speed hardware + * . device descriptor + * + * Endpoints are not yet enabled. Drivers must wait until device + * configuration and interface altsetting changes create + * the need to configure (or unconfigure) them. + * + * After initialization, the device stays active for as long as that + * $CHIP file is open. Events must then be read from that descriptor, + * such as configuration notifications. + */ + +static int is_valid_config (struct usb_config_descriptor *config) +{ + return config->bDescriptorType == USB_DT_CONFIG + && config->bLength == USB_DT_CONFIG_SIZE + && config->bConfigurationValue != 0 + && (config->bmAttributes & USB_CONFIG_ATT_ONE) != 0 + && (config->bmAttributes & USB_CONFIG_ATT_WAKEUP) == 0; + /* FIXME if gadget->is_otg, _must_ include an otg descriptor */ + /* FIXME check lengths: walk to end */ +} + +static ssize_t +dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) +{ + struct dev_data *dev = fd->private_data; + ssize_t value = len, length = len; + unsigned total; + u32 tag; + char *kbuf; + + if (len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4)) + return -EINVAL; + + /* we might need to change message format someday */ + if (copy_from_user (&tag, buf, 4)) + return -EFAULT; + if (tag != 0) + return -EINVAL; + buf += 4; + length -= 4; + + kbuf = kmalloc (length, GFP_KERNEL); + if (!kbuf) + return -ENOMEM; + if (copy_from_user (kbuf, buf, length)) { + kfree (kbuf); + return -EFAULT; + } + + spin_lock_irq (&dev->lock); + value = -EINVAL; + if (dev->buf) + goto fail; + dev->buf = kbuf; + + /* full or low speed config */ + dev->config = (void *) kbuf; + total = le16_to_cpu(dev->config->wTotalLength); + if (!is_valid_config (dev->config) || total >= length) + goto fail; + kbuf += total; + length -= total; + + /* optional high speed config */ + if (kbuf [1] == USB_DT_CONFIG) { + dev->hs_config = (void *) kbuf; + total = le16_to_cpu(dev->hs_config->wTotalLength); + if (!is_valid_config (dev->hs_config) || total >= length) + goto fail; + kbuf += total; + length -= total; + } + + /* could support multiple configs, using another encoding! */ + + /* device descriptor (tweaked for paranoia) */ + if (length != USB_DT_DEVICE_SIZE) + goto fail; + dev->dev = (void *)kbuf; + if (dev->dev->bLength != USB_DT_DEVICE_SIZE + || dev->dev->bDescriptorType != USB_DT_DEVICE + || dev->dev->bNumConfigurations != 1) + goto fail; + dev->dev->bNumConfigurations = 1; + dev->dev->bcdUSB = __constant_cpu_to_le16 (0x0200); + + /* triggers gadgetfs_bind(); then we can enumerate. */ + spin_unlock_irq (&dev->lock); + value = usb_gadget_register_driver (&gadgetfs_driver); + if (value != 0) { + kfree (dev->buf); + dev->buf = NULL; + } else { + /* at this point "good" hardware has for the first time + * let the USB the host see us. alternatively, if users + * unplug/replug that will clear all the error state. + * + * note: everything running before here was guaranteed + * to choke driver model style diagnostics. from here + * on, they can work ... except in cleanup paths that + * kick in after the ep0 descriptor is closed. + */ + fd->f_op = &ep0_io_operations; + value = len; + } + return value; + +fail: + spin_unlock_irq (&dev->lock); + pr_debug ("%s: %s fail %Zd, %p\n", shortname, __func__, value, dev); + kfree (dev->buf); + dev->buf = NULL; + return value; +} + +static int +dev_open (struct inode *inode, struct file *fd) +{ + struct dev_data *dev = inode->i_private; + int value = -EBUSY; + + spin_lock_irq(&dev->lock); + if (dev->state == STATE_DEV_DISABLED) { + dev->ev_next = 0; + dev->state = STATE_DEV_OPENED; + fd->private_data = dev; + get_dev (dev); + value = 0; + } + spin_unlock_irq(&dev->lock); + return value; +} + +static const struct file_operations dev_init_operations = { + .owner = THIS_MODULE, + .llseek = no_llseek, + + .open = dev_open, + .write = dev_config, + .fasync = ep0_fasync, + .unlocked_ioctl = dev_ioctl, + .release = dev_release, +}; + +/*----------------------------------------------------------------------*/ + +/* FILESYSTEM AND SUPERBLOCK OPERATIONS + * + * Mounting the filesystem creates a controller file, used first for + * device configuration then later for event monitoring. + */ + + +/* FIXME PAM etc could set this security policy without mount options + * if epfiles inherited ownership and permissons from ep0 ... + */ + +static unsigned default_uid; +static unsigned default_gid; +static unsigned default_perm = S_IRUSR | S_IWUSR; + +module_param (default_uid, uint, 0644); +module_param (default_gid, uint, 0644); +module_param (default_perm, uint, 0644); + + +static struct inode * +gadgetfs_make_inode (struct super_block *sb, + void *data, const struct file_operations *fops, + int mode) +{ + struct inode *inode = new_inode (sb); + + if (inode) { + inode->i_mode = mode; + inode->i_uid = default_uid; + inode->i_gid = default_gid; + inode->i_blocks = 0; + inode->i_atime = inode->i_mtime = inode->i_ctime + = CURRENT_TIME; + inode->i_private = data; + inode->i_fop = fops; + } + return inode; +} + +/* creates in fs root directory, so non-renamable and non-linkable. + * so inode and dentry are paired, until device reconfig. + */ +static struct inode * +gadgetfs_create_file (struct super_block *sb, char const *name, + void *data, const struct file_operations *fops, + struct dentry **dentry_p) +{ + struct dentry *dentry; + struct inode *inode; + + dentry = d_alloc_name(sb->s_root, name); + if (!dentry) + return NULL; + + inode = gadgetfs_make_inode (sb, data, fops, + S_IFREG | (default_perm & S_IRWXUGO)); + if (!inode) { + dput(dentry); + return NULL; + } + d_add (dentry, inode); + *dentry_p = dentry; + return inode; +} + +static struct super_operations gadget_fs_operations = { + .statfs = simple_statfs, + .drop_inode = generic_delete_inode, +}; + +static int +gadgetfs_fill_super (struct super_block *sb, void *opts, int silent) +{ + struct inode *inode; + struct dentry *d; + struct dev_data *dev; + + if (the_device) + return -ESRCH; + + /* fake probe to determine $CHIP */ + (void) usb_gadget_register_driver (&probe_driver); + if (!CHIP) + return -ENODEV; + + /* superblock */ + sb->s_blocksize = PAGE_CACHE_SIZE; + sb->s_blocksize_bits = PAGE_CACHE_SHIFT; + sb->s_magic = GADGETFS_MAGIC; + sb->s_op = &gadget_fs_operations; + sb->s_time_gran = 1; + + /* root inode */ + inode = gadgetfs_make_inode (sb, + NULL, &simple_dir_operations, + S_IFDIR | S_IRUGO | S_IXUGO); + if (!inode) + goto enomem0; + inode->i_op = &simple_dir_inode_operations; + if (!(d = d_alloc_root (inode))) + goto enomem1; + sb->s_root = d; + + /* the ep0 file is named after the controller we expect; + * user mode code can use it for sanity checks, like we do. + */ + dev = dev_new (); + if (!dev) + goto enomem2; + + dev->sb = sb; + if (!gadgetfs_create_file (sb, CHIP, + dev, &dev_init_operations, + &dev->dentry)) + goto enomem3; + + /* other endpoint files are available after hardware setup, + * from binding to a controller. + */ + the_device = dev; + return 0; + +enomem3: + put_dev (dev); +enomem2: + dput (d); +enomem1: + iput (inode); +enomem0: + return -ENOMEM; +} + +/* "mount -t gadgetfs path /dev/gadget" ends up here */ +static int +gadgetfs_get_sb (struct file_system_type *t, int flags, + const char *path, void *opts, struct vfsmount *mnt) +{ + return get_sb_single (t, flags, opts, gadgetfs_fill_super, mnt); +} + +static void +gadgetfs_kill_sb (struct super_block *sb) +{ + kill_litter_super (sb); + if (the_device) { + put_dev (the_device); + the_device = NULL; + } +} + +/*----------------------------------------------------------------------*/ + +static struct file_system_type gadgetfs_type = { + .owner = THIS_MODULE, + .name = shortname, + .get_sb = gadgetfs_get_sb, + .kill_sb = gadgetfs_kill_sb, +}; + +/*----------------------------------------------------------------------*/ + +static int __init init (void) +{ + int status; + + status = register_filesystem (&gadgetfs_type); + if (status == 0) + pr_info ("%s: %s, version " DRIVER_VERSION "\n", + shortname, driver_desc); + return status; +} +module_init (init); + +static void __exit cleanup (void) +{ + pr_debug ("unregister %s\n", shortname); + unregister_filesystem (&gadgetfs_type); +} +module_exit (cleanup); + --- linux-2.6.28.orig/drivers/usb/gadget/arcotg_udc.c +++ linux-2.6.28/drivers/usb/gadget/arcotg_udc.c @@ -0,0 +1,2838 @@ +/* + * Copyright 2004-2009 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 + */ + +#undef DEBUG +#undef VERBOSE + +#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 "arcotg_udc.h" +#include + +#define DRIVER_DESC "ARC USBOTG Device Controller driver" +#define DRIVER_AUTHOR "Freescale Semiconductor" +#define DRIVER_VERSION "1 August 2005" + +#ifdef CONFIG_PPC_MPC512x +#define BIG_ENDIAN_DESC +#endif + +#ifdef BIG_ENDIAN_DESC +#define cpu_to_hc32(x) (x) +#define hc32_to_cpu(x) (x) +#else +#define cpu_to_hc32(x) cpu_to_le32((x)) +#define hc32_to_cpu(x) le32_to_cpu((x)) +#endif + +#define DMA_ADDR_INVALID (~(dma_addr_t)0) + +static const char driver_name[] = "fsl-usb2-udc"; +static const char driver_desc[] = DRIVER_DESC; + +volatile static struct usb_dr_device *dr_regs; +volatile static struct usb_sys_interface *usb_sys_regs; + +/* it is initialized in probe() */ +static struct fsl_udc *udc_controller; + +static const struct usb_endpoint_descriptor +fsl_ep0_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0, + .bmAttributes = USB_ENDPOINT_XFER_CONTROL, + .wMaxPacketSize = USB_MAX_CTRL_PAYLOAD, +}; +static const size_t g_iram_size = IRAM_TD_PPH_SIZE; + +static int udc_suspend(struct fsl_udc *udc); +static int fsl_udc_suspend(struct platform_device *pdev, pm_message_t state); +static int fsl_udc_resume(struct platform_device *pdev); +static void fsl_ep_fifo_flush(struct usb_ep *_ep); + +#ifdef CONFIG_USB_OTG +/* Get platform resource from OTG driver */ +extern struct resource *otg_get_resources(void); +#endif + +extern void fsl_platform_set_test_mode(struct fsl_usb2_platform_data *pdata, enum usb_test_mode mode); + +#ifdef CONFIG_PPC32 +#define fsl_readl(addr) in_le32((addr)) +#define fsl_writel(addr, val32) out_le32((val32), (addr)) +#else +#define fsl_readl(addr) readl((addr)) +#define fsl_writel(addr, val32) writel((addr), (val32)) +#endif + +/******************************************************************** + * Internal Used Function +********************************************************************/ + +#ifdef DUMP_QUEUES +static void dump_ep_queue(struct fsl_ep *ep) +{ + int ep_index; + struct fsl_req *req; + struct ep_td_struct *dtd; + + if (list_empty(&ep->queue)) { + pr_debug("udc: empty\n"); + return; + } + + ep_index = ep_index(ep) * 2 + ep_is_in(ep); + pr_debug("udc: ep=0x%p index=%d\n", ep, ep_index); + + list_for_each_entry(req, &ep->queue, queue) { + pr_debug("udc: req=0x%p dTD count=%d\n", req, req->dtd_count); + pr_debug("udc: dTD head=0x%p tail=0x%p\n", req->head, + req->tail); + + dtd = req->head; + + while (dtd) { + if (le32_to_cpu(dtd->next_td_ptr) & DTD_NEXT_TERMINATE) + break; /* end of dTD list */ + + dtd = dtd->next_td_virt; + } + } +} +#else +static inline void dump_ep_queue(struct fsl_ep *ep) +{ +} +#endif + +/*----------------------------------------------------------------- + * done() - retire a request; caller blocked irqs + * @status : request status to be set, only works when + * request is still in progress. + *--------------------------------------------------------------*/ +static void done(struct fsl_ep *ep, struct fsl_req *req, int status) +{ + struct fsl_udc *udc = NULL; + unsigned char stopped = ep->stopped; + struct ep_td_struct *curr_td, *next_td; + int j; + + udc = (struct fsl_udc *)ep->udc; + /* Removed the req from fsl_ep->queue */ + list_del_init(&req->queue); + + /* req.status should be set as -EINPROGRESS in ep_queue() */ + if (req->req.status == -EINPROGRESS) + req->req.status = status; + else + status = req->req.status; + + /* Free dtd for the request */ + next_td = req->head; + for (j = 0; j < req->dtd_count; j++) { + curr_td = next_td; + if (j != req->dtd_count - 1) + next_td = curr_td->next_td_virt; + + dma_pool_free(udc->td_pool, curr_td, curr_td->td_dma); + } + + if (USE_MSC_WR(req->req.length)) { + req->req.dma -= 1; + memmove(req->req.buf, req->req.buf + 1, MSC_BULK_CB_WRAP_LEN); + } + + if (req->mapped) { + dma_unmap_single(ep->udc->gadget.dev.parent, + req->req.dma, req->req.length, + ep_is_in(ep) + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); + req->req.dma = DMA_ADDR_INVALID; + req->mapped = 0; + } else + dma_sync_single_for_cpu(ep->udc->gadget.dev.parent, + req->req.dma, req->req.length, + ep_is_in(ep) + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); + + if (status && (status != -ESHUTDOWN)) + VDBG("complete %s req %p stat %d len %u/%u", + ep->ep.name, &req->req, status, + req->req.actual, req->req.length); + + ep->stopped = 1; + + spin_unlock(&ep->udc->lock); + /* complete() is from gadget layer, + * eg fsg->bulk_in_complete() */ + if (req->req.complete) + req->req.complete(&ep->ep, &req->req); + + spin_lock(&ep->udc->lock); + ep->stopped = stopped; +} + +/*----------------------------------------------------------------- + * nuke(): delete all requests related to this ep + * called with spinlock held + *--------------------------------------------------------------*/ +static void nuke(struct fsl_ep *ep, int status) +{ + ep->stopped = 1; + + /* Flush fifo */ + fsl_ep_fifo_flush(&ep->ep); + + /* Whether this eq has request linked */ + while (!list_empty(&ep->queue)) { + struct fsl_req *req = NULL; + + req = list_entry(ep->queue.next, struct fsl_req, queue); + done(ep, req, status); + } + dump_ep_queue(ep); +} + +/*------------------------------------------------------------------ + Internal Hardware related function + ------------------------------------------------------------------*/ + +static int dr_controller_setup(struct fsl_udc *udc) +{ + unsigned int tmp = 0, portctrl = 0; + unsigned int __attribute((unused)) ctrl = 0; + unsigned long timeout; + struct fsl_usb2_platform_data *pdata; + +#define FSL_UDC_RESET_TIMEOUT 1000 + + /* before here, make sure dr_regs has been initialized */ + if (!udc) + return -EINVAL; + pdata = udc->pdata; + + /* Stop and reset the usb controller */ + tmp = fsl_readl(&dr_regs->usbcmd); + tmp &= ~USB_CMD_RUN_STOP; + fsl_writel(tmp, &dr_regs->usbcmd); + + tmp = fsl_readl(&dr_regs->usbcmd); + tmp |= USB_CMD_CTRL_RESET; + fsl_writel(tmp, &dr_regs->usbcmd); + + /* Wait for reset to complete */ + timeout = jiffies + FSL_UDC_RESET_TIMEOUT; + while (fsl_readl(&dr_regs->usbcmd) & USB_CMD_CTRL_RESET) { + if (time_after(jiffies, timeout)) { + ERR("udc reset timeout! \n"); + return -ETIMEDOUT; + } + cpu_relax(); + } + + /* Set the controller as device mode */ + tmp = fsl_readl(&dr_regs->usbmode); + tmp &= ~USB_MODE_CTRL_MODE_MASK; /* clear mode bits */ + tmp |= USB_MODE_CTRL_MODE_DEVICE; + /* Disable Setup Lockout */ + tmp |= USB_MODE_SETUP_LOCK_OFF; + if (pdata->es) + tmp |= USB_MODE_ES; + fsl_writel(tmp, &dr_regs->usbmode); + + fsl_platform_set_device_mode(pdata); + + /* Clear the setup status */ + fsl_writel(0, &dr_regs->usbsts); + + tmp = udc->ep_qh_dma; + tmp &= USB_EP_LIST_ADDRESS_MASK; + fsl_writel(tmp, &dr_regs->endpointlistaddr); + + VDBG("vir[qh_base] is %p phy[qh_base] is 0x%8x reg is 0x%8x", + (int)udc->ep_qh, (int)tmp, + fsl_readl(&dr_regs->endpointlistaddr)); + + /* Config PHY interface */ + portctrl = fsl_readl(&dr_regs->portsc1); + portctrl &= ~(PORTSCX_PHY_TYPE_SEL | PORTSCX_PORT_WIDTH); + switch (udc->phy_mode) { + case FSL_USB2_PHY_ULPI: + portctrl |= PORTSCX_PTS_ULPI; + break; + case FSL_USB2_PHY_UTMI_WIDE: + portctrl |= PORTSCX_PTW_16BIT; + /* fall through */ + case FSL_USB2_PHY_UTMI: + portctrl |= PORTSCX_PTS_UTMI; + break; + case FSL_USB2_PHY_SERIAL: + portctrl |= PORTSCX_PTS_FSLS; + break; + default: + return -EINVAL; + } + fsl_writel(portctrl, &dr_regs->portsc1); + + if (pdata->change_ahb_burst) { + /* if usb should not work in default INCRx mode */ + tmp = fsl_readl(&dr_regs->sbuscfg); + tmp = (tmp & ~0x07) | pdata->ahb_burst_mode; + fsl_writel(tmp, &dr_regs->sbuscfg); + } + + if (pdata->have_sysif_regs) { + /* Config control enable i/o output, cpu endian register */ + ctrl = __raw_readl(&usb_sys_regs->control); + ctrl |= USB_CTRL_IOENB; + __raw_writel(ctrl, &usb_sys_regs->control); + } + +#if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) + /* Turn on cache snooping hardware, since some PowerPC platforms + * wholly rely on hardware to deal with cache coherent. */ + + if (pdata->have_sysif_regs) { + /* Setup Snooping for all the 4GB space */ + tmp = SNOOP_SIZE_2GB; /* starts from 0x0, size 2G */ + __raw_writel(tmp, &usb_sys_regs->snoop1); + tmp |= 0x80000000; /* starts from 0x8000000, size 2G */ + __raw_writel(tmp, &usb_sys_regs->snoop2); + } +#endif + + return 0; +} + +/* Enable DR irq and set controller to run state */ +static void dr_controller_run(struct fsl_udc *udc) +{ + u32 temp; + + fsl_platform_pullup_enable(udc->pdata); + + /* Enable DR irq reg */ + temp = USB_INTR_INT_EN | USB_INTR_ERR_INT_EN + | USB_INTR_PTC_DETECT_EN | USB_INTR_RESET_EN + | USB_INTR_DEVICE_SUSPEND | USB_INTR_SYS_ERR_EN; + + fsl_writel(temp, &dr_regs->usbintr); + + /* Clear stopped bit */ + udc->stopped = 0; + + /* Set controller to Run */ + temp = fsl_readl(&dr_regs->usbcmd); + temp |= USB_CMD_RUN_STOP; + fsl_writel(temp, &dr_regs->usbcmd); + + return; +} + +static void dr_controller_stop(struct fsl_udc *udc) +{ + unsigned int tmp; + + pr_debug("%s\n", __func__); + + /* if we're in OTG mode, and the Host is currently using the port, + * stop now and don't rip the controller out from under the + * ehci driver + */ + if (udc->gadget.is_otg) { + if (!(fsl_readl(&dr_regs->otgsc) & OTGSC_STS_USB_ID)) { + pr_debug("udc: Leaving early\n"); + return; + } + } + + /* disable all INTR */ + fsl_writel(0, &dr_regs->usbintr); + + /* Set stopped bit for isr */ + udc->stopped = 1; + + /* disable IO output */ +/* usb_sys_regs->control = 0; */ + + fsl_platform_pullup_disable(udc->pdata); + + /* set controller to Stop */ + tmp = fsl_readl(&dr_regs->usbcmd); + tmp &= ~USB_CMD_RUN_STOP; + fsl_writel(tmp, &dr_regs->usbcmd); + + return; +} + +void dr_ep_setup(unsigned char ep_num, unsigned char dir, unsigned char ep_type) +{ + unsigned int tmp_epctrl = 0; + + tmp_epctrl = fsl_readl(&dr_regs->endptctrl[ep_num]); + if (dir) { + if (ep_num) + tmp_epctrl |= EPCTRL_TX_DATA_TOGGLE_RST; + tmp_epctrl |= EPCTRL_TX_ENABLE; + tmp_epctrl |= ((unsigned int)(ep_type) + << EPCTRL_TX_EP_TYPE_SHIFT); + } else { + if (ep_num) + tmp_epctrl |= EPCTRL_RX_DATA_TOGGLE_RST; + tmp_epctrl |= EPCTRL_RX_ENABLE; + tmp_epctrl |= ((unsigned int)(ep_type) + << EPCTRL_RX_EP_TYPE_SHIFT); + } + + fsl_writel(tmp_epctrl, &dr_regs->endptctrl[ep_num]); +} + +static void +dr_ep_change_stall(unsigned char ep_num, unsigned char dir, int value) +{ + u32 tmp_epctrl = 0; + + tmp_epctrl = fsl_readl(&dr_regs->endptctrl[ep_num]); + + if (value) { + /* set the stall bit */ + if (dir) + tmp_epctrl |= EPCTRL_TX_EP_STALL; + else + tmp_epctrl |= EPCTRL_RX_EP_STALL; + } else { + /* clear the stall bit and reset data toggle */ + if (dir) { + tmp_epctrl &= ~EPCTRL_TX_EP_STALL; + tmp_epctrl |= EPCTRL_TX_DATA_TOGGLE_RST; + } else { + tmp_epctrl &= ~EPCTRL_RX_EP_STALL; + tmp_epctrl |= EPCTRL_RX_DATA_TOGGLE_RST; + } + } + fsl_writel(tmp_epctrl, &dr_regs->endptctrl[ep_num]); +} + +/* Get stall status of a specific ep + Return: 0: not stalled; 1:stalled */ +static int dr_ep_get_stall(unsigned char ep_num, unsigned char dir) +{ + u32 epctrl; + + epctrl = fsl_readl(&dr_regs->endptctrl[ep_num]); + if (dir) + return (epctrl & EPCTRL_TX_EP_STALL) ? 1 : 0; + else + return (epctrl & EPCTRL_RX_EP_STALL) ? 1 : 0; +} + +/******************************************************************** + Internal Structure Build up functions +********************************************************************/ + +/*------------------------------------------------------------------ +* struct_ep_qh_setup(): set the Endpoint Capabilites field of QH + * @zlt: Zero Length Termination Select (1: disable; 0: enable) + * @mult: Mult field + ------------------------------------------------------------------*/ +static void struct_ep_qh_setup(struct fsl_udc *udc, unsigned char ep_num, + unsigned char dir, unsigned char ep_type, + unsigned int max_pkt_len, + unsigned int zlt, unsigned char mult) +{ + struct ep_queue_head *p_QH = &udc->ep_qh[2 * ep_num + dir]; + unsigned int tmp = 0; + + /* set the Endpoint Capabilites in QH */ + switch (ep_type) { + case USB_ENDPOINT_XFER_CONTROL: + /* Interrupt On Setup (IOS). for control ep */ + tmp = (max_pkt_len << EP_QUEUE_HEAD_MAX_PKT_LEN_POS) + | EP_QUEUE_HEAD_IOS; + break; + case USB_ENDPOINT_XFER_ISOC: + tmp = (max_pkt_len << EP_QUEUE_HEAD_MAX_PKT_LEN_POS) + | (mult << EP_QUEUE_HEAD_MULT_POS); + break; + case USB_ENDPOINT_XFER_BULK: + case USB_ENDPOINT_XFER_INT: + tmp = max_pkt_len << EP_QUEUE_HEAD_MAX_PKT_LEN_POS; + break; + default: + VDBG("error ep type is %d", ep_type); + return; + } + if (zlt) + tmp |= EP_QUEUE_HEAD_ZLT_SEL; + p_QH->max_pkt_length = cpu_to_hc32(tmp); + + return; +} + +/* Setup qh structure and ep register for ep0. */ +static void ep0_setup(struct fsl_udc *udc) +{ + /* the intialization of an ep includes: fields in QH, Regs, + * fsl_ep struct */ + struct_ep_qh_setup(udc, 0, USB_RECV, USB_ENDPOINT_XFER_CONTROL, + USB_MAX_CTRL_PAYLOAD, 0, 0); + struct_ep_qh_setup(udc, 0, USB_SEND, USB_ENDPOINT_XFER_CONTROL, + USB_MAX_CTRL_PAYLOAD, 0, 0); + dr_ep_setup(0, USB_RECV, USB_ENDPOINT_XFER_CONTROL); + dr_ep_setup(0, USB_SEND, USB_ENDPOINT_XFER_CONTROL); + + return; + +} + +/*********************************************************************** + Endpoint Management Functions +***********************************************************************/ + +/*------------------------------------------------------------------------- + * when configurations are set, or when interface settings change + * for example the do_set_interface() in gadget layer, + * the driver will enable or disable the relevant endpoints + * ep0 doesn't use this routine. It is always enabled. +-------------------------------------------------------------------------*/ +static int fsl_ep_enable(struct usb_ep *_ep, + const struct usb_endpoint_descriptor *desc) +{ + struct fsl_udc *udc = NULL; + struct fsl_ep *ep = NULL; + unsigned short max = 0; + unsigned char mult = 0, zlt; + int retval = -EINVAL; + unsigned long flags = 0; + + ep = container_of(_ep, struct fsl_ep, ep); + + pr_debug("udc: %s ep.name=%s\n", __func__, ep->ep.name); + /* catch various bogus parameters */ + if (!_ep || !desc || ep->desc + || (desc->bDescriptorType != USB_DT_ENDPOINT)) + return -EINVAL; + + udc = ep->udc; + + if (!udc->driver || (udc->gadget.speed == USB_SPEED_UNKNOWN)) + return -ESHUTDOWN; + + max = le16_to_cpu(desc->wMaxPacketSize); + + /* Disable automatic zlp generation. Driver is reponsible to indicate + * explicitly through req->req.zero. This is needed to enable multi-td + * request. */ + zlt = 1; + + /* Assume the max packet size from gadget is always correct */ + switch (desc->bmAttributes & 0x03) { + case USB_ENDPOINT_XFER_CONTROL: + case USB_ENDPOINT_XFER_BULK: + case USB_ENDPOINT_XFER_INT: + /* mult = 0. Execute N Transactions as demonstrated by + * the USB variable length packet protocol where N is + * computed using the Maximum Packet Length (dQH) and + * the Total Bytes field (dTD) */ + mult = 0; + break; + case USB_ENDPOINT_XFER_ISOC: + /* Calculate transactions needed for high bandwidth iso */ + mult = (unsigned char)(1 + ((max >> 11) & 0x03)); + max = max & 0x8ff; /* bit 0~10 */ + /* 3 transactions at most */ + if (mult > 3) + goto en_done; + break; + default: + goto en_done; + } + + spin_lock_irqsave(&udc->lock, flags); + ep->ep.maxpacket = max; + ep->desc = desc; + ep->stopped = 0; + + /* Controller related setup */ + /* Init EPx Queue Head (Ep Capabilites field in QH + * according to max, zlt, mult) */ + struct_ep_qh_setup(udc, (unsigned char) ep_index(ep), + (unsigned char) ((desc->bEndpointAddress & USB_DIR_IN) + ? USB_SEND : USB_RECV), + (unsigned char) (desc->bmAttributes + & USB_ENDPOINT_XFERTYPE_MASK), + max, zlt, mult); + + /* Init endpoint ctrl register */ + dr_ep_setup((unsigned char) ep_index(ep), + (unsigned char) ((desc->bEndpointAddress & USB_DIR_IN) + ? USB_SEND : USB_RECV), + (unsigned char) (desc->bmAttributes + & USB_ENDPOINT_XFERTYPE_MASK)); + + spin_unlock_irqrestore(&udc->lock, flags); + retval = 0; + + VDBG("enabled %s (ep%d%s) maxpacket %d", ep->ep.name, + ep->desc->bEndpointAddress & 0x0f, + (desc->bEndpointAddress & USB_DIR_IN) + ? "in" : "out", max); +en_done: + return retval; +} + +/*--------------------------------------------------------------------- + * @ep : the ep being unconfigured. May not be ep0 + * Any pending and uncomplete req will complete with status (-ESHUTDOWN) +*---------------------------------------------------------------------*/ +static int fsl_ep_disable(struct usb_ep *_ep) +{ + struct fsl_udc *udc = NULL; + struct fsl_ep *ep = NULL; + unsigned long flags = 0; + u32 epctrl; + int ep_num; + + ep = container_of(_ep, struct fsl_ep, ep); + if (!_ep || !ep->desc) { + VDBG("%s not enabled", _ep ? ep->ep.name : NULL); + return -EINVAL; + } + + /* disable ep on controller */ + ep_num = ep_index(ep); + epctrl = fsl_readl(&dr_regs->endptctrl[ep_num]); + if (ep_is_in(ep)) + epctrl &= ~EPCTRL_TX_ENABLE; + else + epctrl &= ~EPCTRL_RX_ENABLE; + fsl_writel(epctrl, &dr_regs->endptctrl[ep_num]); + + udc = (struct fsl_udc *)ep->udc; + spin_lock_irqsave(&udc->lock, flags); + + /* nuke all pending requests (does flush) */ + nuke(ep, -ESHUTDOWN); + + ep->desc = 0; + ep->stopped = 1; + spin_unlock_irqrestore(&udc->lock, flags); + + VDBG("disabled %s OK", _ep->name); + return 0; +} + +/*--------------------------------------------------------------------- + * allocate a request object used by this endpoint + * the main operation is to insert the req->queue to the eq->queue + * Returns the request, or null if one could not be allocated +*---------------------------------------------------------------------*/ +static struct usb_request * +fsl_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) +{ + struct fsl_req *req = NULL; + + req = kzalloc(sizeof *req, gfp_flags); + if (!req) + return NULL; + + req->req.dma = DMA_ADDR_INVALID; + pr_debug("udc: req=0x%p set req.dma=0x%x\n", req, req->req.dma); + INIT_LIST_HEAD(&req->queue); + + return &req->req; +} + +static void fsl_free_request(struct usb_ep *_ep, struct usb_request *_req) +{ + struct fsl_req *req = NULL; + + req = container_of(_req, struct fsl_req, req); + + if (_req) + kfree(req); +} + +static void update_qh(struct fsl_req *req) +{ + struct fsl_ep *ep = req->ep; + int i = ep_index(ep) * 2 + ep_is_in(ep); + u32 temp; + struct ep_queue_head *dQH = &ep->udc->ep_qh[i]; + + /* Write dQH next pointer and terminate bit to 0 */ + temp = req->head->td_dma & EP_QUEUE_HEAD_NEXT_POINTER_MASK; + if (NEED_IRAM(req->ep)) { + /* set next dtd stop bit,ensure only one dtd in this list */ + req->cur->next_td_ptr |= cpu_to_hc32(DTD_NEXT_TERMINATE); + temp = req->cur->td_dma & EP_QUEUE_HEAD_NEXT_POINTER_MASK; + } + dQH->next_dtd_ptr = cpu_to_hc32(temp); + /* Clear active and halt bit */ + temp = cpu_to_hc32(~(EP_QUEUE_HEAD_STATUS_ACTIVE + | EP_QUEUE_HEAD_STATUS_HALT)); + dQH->size_ioc_int_sts &= temp; + + /* Prime endpoint by writing 1 to ENDPTPRIME */ + temp = ep_is_in(ep) + ? (1 << (ep_index(ep) + 16)) + : (1 << (ep_index(ep))); + fsl_writel(temp, &dr_regs->endpointprime); +} + +/*-------------------------------------------------------------------------*/ +static int fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) +{ + u32 temp, bitmask, tmp_stat; + + /* VDBG("QH addr Register 0x%8x", dr_regs->endpointlistaddr); + VDBG("ep_qh[%d] addr is 0x%8x", i, (u32)&(ep->udc->ep_qh[i])); */ + + bitmask = ep_is_in(ep) + ? (1 << (ep_index(ep) + 16)) + : (1 << (ep_index(ep))); + + /* check if the pipe is empty */ + if (!(list_empty(&ep->queue))) { + /* Add td to the end */ + struct fsl_req *lastreq; + lastreq = list_entry(ep->queue.prev, struct fsl_req, queue); + if (NEED_IRAM(ep)) { + /* only one dtd in dqh */ + lastreq->tail->next_td_ptr = + cpu_to_hc32(req->head->td_dma | DTD_NEXT_TERMINATE); + goto out; + } else { + lastreq->tail->next_td_ptr = + cpu_to_hc32(req->head->td_dma & DTD_ADDR_MASK); + } + /* Read prime bit, if 1 goto done */ + if (fsl_readl(&dr_regs->endpointprime) & bitmask) + goto out; + do { + /* Set ATDTW bit in USBCMD */ + temp = fsl_readl(&dr_regs->usbcmd); + fsl_writel(temp | USB_CMD_ATDTW, &dr_regs->usbcmd); + + /* Read correct status bit */ + tmp_stat = fsl_readl(&dr_regs->endptstatus) & bitmask; + + } while (!(fsl_readl(&dr_regs->usbcmd) & USB_CMD_ATDTW)); + + /* Write ATDTW bit to 0 */ + temp = fsl_readl(&dr_regs->usbcmd); + fsl_writel(temp & ~USB_CMD_ATDTW, &dr_regs->usbcmd); + + if (tmp_stat) + goto out; + } + update_qh(req); +out: + return 0; +} + +/* Fill in the dTD structure + * @req: request that the transfer belongs to + * @length: return actually data length of the dTD + * @dma: return dma address of the dTD + * @is_last: return flag if it is the last dTD of the request + * return: pointer to the built dTD */ +static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length, + dma_addr_t *dma, int *is_last) +{ + u32 swap_temp; + struct ep_td_struct *dtd; + + /* how big will this transfer be? */ + *length = min(req->req.length - req->req.actual, + (unsigned)EP_MAX_LENGTH_TRANSFER); + if (NEED_IRAM(req->ep)) + *length = min(*length, g_iram_size); + dtd = dma_pool_alloc(udc_controller->td_pool, GFP_KERNEL, dma); + if (dtd == NULL) + return dtd; + + dtd->td_dma = *dma; + /* Clear reserved field */ + swap_temp = hc32_to_cpu(dtd->size_ioc_sts); + swap_temp &= ~DTD_RESERVED_FIELDS; + dtd->size_ioc_sts = cpu_to_hc32(swap_temp); + + /* Init all of buffer page pointers */ + swap_temp = (u32) (req->req.dma + req->req.actual); + if (NEED_IRAM(req->ep)) + swap_temp = (u32) (req->req.dma); + dtd->buff_ptr0 = cpu_to_hc32(swap_temp); + dtd->buff_ptr1 = cpu_to_hc32(swap_temp + 0x1000); + dtd->buff_ptr2 = cpu_to_hc32(swap_temp + 0x2000); + dtd->buff_ptr3 = cpu_to_hc32(swap_temp + 0x3000); + dtd->buff_ptr4 = cpu_to_hc32(swap_temp + 0x4000); + + req->req.actual += *length; + + /* zlp is needed if req->req.zero is set */ + if (req->req.zero) { + if (*length == 0 || (*length % req->ep->ep.maxpacket) != 0) + *is_last = 1; + else + *is_last = 0; + } else if (req->req.length == req->req.actual) + *is_last = 1; + else + *is_last = 0; + + if ((*is_last) == 0) + VDBG("multi-dtd request!\n"); + /* Fill in the transfer size; set active bit */ + swap_temp = ((*length << DTD_LENGTH_BIT_POS) | DTD_STATUS_ACTIVE); + + /* Enable interrupt for the last dtd of a request */ + if (*is_last && !req->req.no_interrupt) + swap_temp |= DTD_IOC; + if (NEED_IRAM(req->ep)) + swap_temp |= DTD_IOC; + + dtd->size_ioc_sts = cpu_to_hc32(swap_temp); + + mb(); + + VDBG("length = %d address= 0x%x", *length, (int)*dma); + + return dtd; +} + +/* Generate dtd chain for a request */ +static int fsl_req_to_dtd(struct fsl_req *req) +{ + unsigned count; + int is_last; + int is_first = 1; + struct ep_td_struct *last_dtd = NULL, *dtd; + dma_addr_t dma; + + if (NEED_IRAM(req->ep)) { + req->oridma = req->req.dma; + /* here, replace user buffer to iram buffer */ + if (ep_is_in(req->ep)) { + req->req.dma = req->ep->udc->iram_buffer[1]; + if ((list_empty(&req->ep->queue))) { + /* copy data only when no bulk in transfer is + running */ + memcpy((char *)req->ep->udc->iram_buffer_v[1], + req->req.buf, min(req->req.length, + g_iram_size)); + } + } else { + req->req.dma = req->ep->udc->iram_buffer[0]; + } + } + + if (USE_MSC_WR(req->req.length)) + req->req.dma += 1; + + do { + dtd = fsl_build_dtd(req, &count, &dma, &is_last); + if (dtd == NULL) + return -ENOMEM; + + if (is_first) { + is_first = 0; + req->head = dtd; + } else { + last_dtd->next_td_ptr = cpu_to_hc32(dma); + last_dtd->next_td_virt = dtd; + } + last_dtd = dtd; + + req->dtd_count++; + } while (!is_last); + + dtd->next_td_ptr = cpu_to_hc32(DTD_NEXT_TERMINATE); + req->cur = req->head; + req->tail = dtd; + + return 0; +} + +/* queues (submits) an I/O request to an endpoint */ +static int +fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) +{ + struct fsl_ep *ep = container_of(_ep, struct fsl_ep, ep); + struct fsl_req *req = container_of(_req, struct fsl_req, req); + struct fsl_udc *udc; + unsigned long flags; + int is_iso = 0; + + /* catch various bogus parameters */ + if (!_req || !req->req.buf || (ep_index(ep) + && !list_empty(&req->queue))) { + VDBG("%s, bad params\n", __func__); + return -EINVAL; + } + if (!_ep || (!ep->desc && ep_index(ep))) { + VDBG("%s, bad ep\n", __func__); + return -EINVAL; + } + if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) { + if (req->req.length > ep->ep.maxpacket) + return -EMSGSIZE; + is_iso = 1; + } + + udc = ep->udc; + if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) + return -ESHUTDOWN; + + req->ep = ep; + + /* map virtual address to hardware */ + if (req->req.dma == DMA_ADDR_INVALID) { + req->req.dma = dma_map_single(ep->udc->gadget.dev.parent, + req->req.buf, + req->req.length, ep_is_in(ep) + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); + req->mapped = 1; + } else { + dma_sync_single_for_device(ep->udc->gadget.dev.parent, + req->req.dma, req->req.length, + ep_is_in(ep) + ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); + req->mapped = 0; + } + + req->req.status = -EINPROGRESS; + req->req.actual = 0; + req->dtd_count = 0; + if (NEED_IRAM(ep)) { + req->last_one = 0; + req->buffer_offset = 0; + } + + spin_lock_irqsave(&udc->lock, flags); + + /* build dtds and push them to device queue */ + if (!fsl_req_to_dtd(req)) { + fsl_queue_td(ep, req); + } else { + spin_unlock_irqrestore(&udc->lock, flags); + return -ENOMEM; + } + + /* irq handler advances the queue */ + if (req != NULL) + list_add_tail(&req->queue, &ep->queue); + spin_unlock_irqrestore(&udc->lock, flags); + + return 0; +} + +/* dequeues (cancels, unlinks) an I/O request from an endpoint */ +static int fsl_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) +{ + struct fsl_ep *ep = container_of(_ep, struct fsl_ep, ep); + struct fsl_req *req; + unsigned long flags; + int ep_num, stopped, ret = 0; + u32 epctrl; + + if (!_ep || !_req) + return -EINVAL; + + spin_lock_irqsave(&ep->udc->lock, flags); + stopped = ep->stopped; + + /* Stop the ep before we deal with the queue */ + ep->stopped = 1; + ep_num = ep_index(ep); + epctrl = fsl_readl(&dr_regs->endptctrl[ep_num]); + if (ep_is_in(ep)) + epctrl &= ~EPCTRL_TX_ENABLE; + else + epctrl &= ~EPCTRL_RX_ENABLE; + fsl_writel(epctrl, &dr_regs->endptctrl[ep_num]); + + /* make sure it's actually queued on this endpoint */ + list_for_each_entry(req, &ep->queue, queue) { + if (&req->req == _req) + break; + } + if (&req->req != _req) { + ret = -EINVAL; + goto out; + } + + /* The request is in progress, or completed but not dequeued */ + if (ep->queue.next == &req->queue) { + _req->status = -ECONNRESET; + fsl_ep_fifo_flush(_ep); /* flush current transfer */ + + /* The request isn't the last request in this ep queue */ + if (req->queue.next != &ep->queue) { + struct ep_queue_head *qh; + struct fsl_req *next_req; + + qh = ep->qh; + next_req = list_entry(req->queue.next, struct fsl_req, + queue); + + /* Point the QH to the first TD of next request */ + fsl_writel((u32) next_req->head, &qh->curr_dtd_ptr); + } + + /* The request hasn't been processed, patch up the TD chain */ + } else { + struct fsl_req *prev_req; + + prev_req = list_entry(req->queue.prev, struct fsl_req, queue); + fsl_writel(fsl_readl(&req->tail->next_td_ptr), + &prev_req->tail->next_td_ptr); + + } + + done(ep, req, -ECONNRESET); + + /* Enable EP */ +out: epctrl = fsl_readl(&dr_regs->endptctrl[ep_num]); + if (ep_is_in(ep)) + epctrl |= EPCTRL_TX_ENABLE; + else + epctrl |= EPCTRL_RX_ENABLE; + fsl_writel(epctrl, &dr_regs->endptctrl[ep_num]); + ep->stopped = stopped; + + spin_unlock_irqrestore(&ep->udc->lock, flags); + return ret; +} + +/*-------------------------------------------------------------------------*/ + +/*----------------------------------------------------------------- + * modify the endpoint halt feature + * @ep: the non-isochronous endpoint being stalled + * @value: 1--set halt 0--clear halt + * Returns zero, or a negative error code. +*----------------------------------------------------------------*/ +static int fsl_ep_set_halt(struct usb_ep *_ep, int value) +{ + struct fsl_ep *ep = NULL; + unsigned long flags = 0; + int status = -EOPNOTSUPP; /* operation not supported */ + unsigned char ep_dir = 0, ep_num = 0; + struct fsl_udc *udc = NULL; + + ep = container_of(_ep, struct fsl_ep, ep); + udc = ep->udc; + if (!_ep || !ep->desc) { + status = -EINVAL; + goto out; + } + + if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) { + status = -EOPNOTSUPP; + goto out; + } + + /* Attempt to halt IN ep will fail if any transfer requests + * are still queue */ + if (value && ep_is_in(ep) && !list_empty(&ep->queue)) { + status = -EAGAIN; + goto out; + } + + status = 0; + ep_dir = ep_is_in(ep) ? USB_SEND : USB_RECV; + ep_num = (unsigned char)(ep_index(ep)); + spin_lock_irqsave(&ep->udc->lock, flags); + dr_ep_change_stall(ep_num, ep_dir, value); + spin_unlock_irqrestore(&ep->udc->lock, flags); + + if (ep_index(ep) == 0) { + udc->ep0_dir = 0; + } +out: + VDBG(" %s %s halt stat %d", ep->ep.name, + value ? "set" : "clear", status); + + return status; +} + +static int arcotg_fifo_status(struct usb_ep *_ep) +{ + struct fsl_ep *ep; + struct fsl_udc *udc; + int size = 0; + u32 bitmask; + struct ep_queue_head *d_qh; + + ep = container_of(_ep, struct fsl_ep, ep); + if (!_ep || (!ep->desc && ep_index(ep) != 0)) + return -ENODEV; + + udc = (struct fsl_udc *)ep->udc; + + if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) + return -ESHUTDOWN; + + d_qh = &ep->udc->ep_qh[ep_index(ep) * 2 + ep_is_in(ep)]; + + bitmask = (ep_is_in(ep)) ? (1 << (ep_index(ep) + 16)) : + (1 << (ep_index(ep))); + + if (fsl_readl(&dr_regs->endptstatus) & bitmask) + size = (d_qh->size_ioc_int_sts & DTD_PACKET_SIZE) + >> DTD_LENGTH_BIT_POS; + + pr_debug("%s %u\n", __func__, size); + return size; +} + +static void fsl_ep_fifo_flush(struct usb_ep *_ep) +{ + struct fsl_ep *ep; + int ep_num, ep_dir; + u32 bits; + unsigned long timeout; +#define FSL_UDC_FLUSH_TIMEOUT 1000 + + if (!_ep) { + return; + } else { + ep = container_of(_ep, struct fsl_ep, ep); + if (!ep->desc) + return; + } + ep_num = ep_index(ep); + ep_dir = ep_is_in(ep) ? USB_SEND : USB_RECV; + + if (ep_num == 0) + bits = (1 << 16) | 1; + else if (ep_dir == USB_SEND) + bits = 1 << (16 + ep_num); + else + bits = 1 << ep_num; + + timeout = jiffies + FSL_UDC_FLUSH_TIMEOUT; + do { + fsl_writel(bits, &dr_regs->endptflush); + + /* Wait until flush complete */ + while (fsl_readl(&dr_regs->endptflush)) { + if (time_after(jiffies, timeout)) { + ERR("ep flush timeout\n"); + return; + } + cpu_relax(); + } + /* See if we need to flush again */ + } while (fsl_readl(&dr_regs->endptstatus) & bits); +} + +static struct usb_ep_ops fsl_ep_ops = { + .enable = fsl_ep_enable, + .disable = fsl_ep_disable, + + .alloc_request = fsl_alloc_request, + .free_request = fsl_free_request, + + .queue = fsl_ep_queue, + .dequeue = fsl_ep_dequeue, + + .set_halt = fsl_ep_set_halt, + .fifo_status = arcotg_fifo_status, + .fifo_flush = fsl_ep_fifo_flush, /* flush fifo */ +}; + +/*------------------------------------------------------------------------- + Gadget Driver Layer Operations +-------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------- + * Get the current frame number (from DR frame_index Reg ) + *----------------------------------------------------------------------*/ +static int fsl_get_frame(struct usb_gadget *gadget) +{ + return (int)(fsl_readl(&dr_regs->frindex) & USB_FRINDEX_MASKS); +} + +/*----------------------------------------------------------------------- + * Tries to wake up the host connected to this gadget + -----------------------------------------------------------------------*/ +static int fsl_wakeup(struct usb_gadget *gadget) +{ + struct fsl_udc *udc = container_of(gadget, struct fsl_udc, gadget); + u32 portsc; + + /* Remote wakeup feature not enabled by host */ + if (!udc->remote_wakeup) + return -ENOTSUPP; + + portsc = fsl_readl(&dr_regs->portsc1); + /* not suspended? */ + if (!(portsc & PORTSCX_PORT_SUSPEND)) + return 0; + /* trigger force resume */ + portsc |= PORTSCX_PORT_FORCE_RESUME; + fsl_writel(portsc, &dr_regs->portsc1); + return 0; +} + +static int can_pullup(struct fsl_udc *udc) +{ + return udc->driver && udc->softconnect && udc->vbus_active; +} + +/* Notify controller that VBUS is powered, Called by whatever + detects VBUS sessions */ +static int fsl_vbus_session(struct usb_gadget *gadget, int is_active) +{ + struct fsl_udc *udc; + unsigned long flags; + + udc = container_of(gadget, struct fsl_udc, gadget); + spin_lock_irqsave(&udc->lock, flags); + VDBG("VBUS %s\n", is_active ? "on" : "off"); + udc->vbus_active = (is_active != 0); + if (can_pullup(udc)) + fsl_writel((fsl_readl(&dr_regs->usbcmd) | USB_CMD_RUN_STOP), + &dr_regs->usbcmd); + else + fsl_writel((fsl_readl(&dr_regs->usbcmd) & ~USB_CMD_RUN_STOP), + &dr_regs->usbcmd); + spin_unlock_irqrestore(&udc->lock, flags); + return 0; +} + +/* constrain controller's VBUS power usage + * This call is used by gadget drivers during SET_CONFIGURATION calls, + * reporting how much power the device may consume. For example, this + * could affect how quickly batteries are recharged. + * + * Returns zero on success, else negative errno. + */ +static int fsl_vbus_draw(struct usb_gadget *gadget, unsigned mA) +{ + struct fsl_udc *udc; + + udc = container_of(gadget, struct fsl_udc, gadget); + if (udc->transceiver) + return otg_set_power(udc->transceiver, mA); + return -ENOTSUPP; +} + +/* Change Data+ pullup status + * this func is used by usb_gadget_connect/disconnet + */ +static int fsl_pullup(struct usb_gadget *gadget, int is_on) +{ + struct fsl_udc *udc; + + udc = container_of(gadget, struct fsl_udc, gadget); + udc->softconnect = (is_on != 0); + if (can_pullup(udc)) + fsl_writel((fsl_readl(&dr_regs->usbcmd) | USB_CMD_RUN_STOP), + &dr_regs->usbcmd); + else + fsl_writel((fsl_readl(&dr_regs->usbcmd) & ~USB_CMD_RUN_STOP), + &dr_regs->usbcmd); + + return 0; +} + +/* defined in gadget.h */ +static struct usb_gadget_ops fsl_gadget_ops = { + .get_frame = fsl_get_frame, + .wakeup = fsl_wakeup, +/* .set_selfpowered = fsl_set_selfpowered, */ /* Always selfpowered */ + .vbus_session = fsl_vbus_session, + .vbus_draw = fsl_vbus_draw, + .pullup = fsl_pullup, +}; + +/* Set protocol stall on ep0, protocol stall will automatically be cleared + on new transaction */ +static void ep0stall(struct fsl_udc *udc) +{ + u32 tmp; + + /* must set tx and rx to stall at the same time */ + tmp = fsl_readl(&dr_regs->endptctrl[0]); + tmp |= EPCTRL_TX_EP_STALL | EPCTRL_RX_EP_STALL; + fsl_writel(tmp, &dr_regs->endptctrl[0]); + udc->ep0_dir = 0; +} + +/* Prime a status phase for ep0 */ +static int ep0_prime_status(struct fsl_udc *udc, int direction) +{ + struct fsl_req *req = udc->status_req; + struct fsl_ep *ep; + int status = 0; + + if (direction == EP_DIR_IN) + udc->ep0_dir = USB_DIR_IN; + else + udc->ep0_dir = USB_DIR_OUT; + ep = &udc->eps[0]; + req->ep = ep; + req->req.length = 0; + status = fsl_ep_queue(&ep->ep, &req->req, GFP_ATOMIC); + return status; +} + +static inline int udc_reset_ep_queue(struct fsl_udc *udc, u8 pipe) +{ + struct fsl_ep *ep = get_ep_by_pipe(udc, pipe); + + if (!ep->name) + return 0; + + nuke(ep, -ESHUTDOWN); + + return 0; +} + +/* + * ch9 Set address + */ +static void ch9setaddress(struct fsl_udc *udc, u16 value, u16 index, u16 length) +{ + /* Save the new address to device struct */ + udc->device_address = (u8) value; + /* Update usb state */ + udc->usb_state = USB_STATE_ADDRESS; + /* Status phase */ + if (ep0_prime_status(udc, EP_DIR_IN)) + ep0stall(udc); +} + +/* + * ch9 Get status + */ +static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value, + u16 index, u16 length) +{ + u16 tmp = 0; /* Status, cpu endian */ + + struct fsl_req *req; + struct fsl_ep *ep; + int status = 0; + + ep = &udc->eps[0]; + + if ((request_type & USB_RECIP_MASK) == USB_RECIP_DEVICE) { + /* Get device status */ + tmp = 1 << USB_DEVICE_SELF_POWERED; + tmp |= udc->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP; + } else if ((request_type & USB_RECIP_MASK) == USB_RECIP_INTERFACE) { + /* Get interface status */ + /* We don't have interface information in udc driver */ + tmp = 0; + } else if ((request_type & USB_RECIP_MASK) == USB_RECIP_ENDPOINT) { + /* Get endpoint status */ + struct fsl_ep *target_ep; + + target_ep = get_ep_by_pipe(udc, get_pipe_by_windex(index)); + + /* stall if endpoint doesn't exist */ + if (!target_ep->desc) + goto stall; + tmp = dr_ep_get_stall(ep_index(target_ep), ep_is_in(target_ep)) + << USB_ENDPOINT_HALT; + } + + udc->ep0_dir = USB_DIR_IN; + /* Borrow the per device data_req */ + /* status_req had been used to prime status */ + req = udc->data_req; + /* Fill in the reqest structure */ + *((u16 *) req->req.buf) = cpu_to_le16(tmp); + req->ep = ep; + req->req.length = 2; + + status = fsl_ep_queue(&ep->ep, &req->req, GFP_ATOMIC); + if (status) { + udc_reset_ep_queue(udc, 0); + ERR("Can't respond to getstatus request \n"); + goto stall; + } + return; +stall: + ep0stall(udc); +} + +static void setup_received_irq(struct fsl_udc *udc, + struct usb_ctrlrequest *setup) +{ + u16 wValue = le16_to_cpu(setup->wValue); + u16 wIndex = le16_to_cpu(setup->wIndex); + u16 wLength = le16_to_cpu(setup->wLength); + + udc_reset_ep_queue(udc, 0); + if (setup->bRequestType & USB_DIR_IN) { + if (ep0_prime_status(udc, EP_DIR_OUT)) + ep0stall(udc); + } + /* We process some stardard setup requests here */ + switch (setup->bRequest) { + case USB_REQ_GET_STATUS: + /* Data+Status phase from udc */ + if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_MASK)) + != (USB_DIR_IN | USB_TYPE_STANDARD)) + break; + ch9getstatus(udc, setup->bRequestType, wValue, wIndex, wLength); + return; + + case USB_REQ_SET_ADDRESS: + /* Status phase from udc */ + if (setup->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD + | USB_RECIP_DEVICE)) + break; + ch9setaddress(udc, wValue, wIndex, wLength); + return; + + case USB_REQ_CLEAR_FEATURE: + case USB_REQ_SET_FEATURE: + /* Status phase from udc */ + { + int rc = -EOPNOTSUPP; + u16 ptc = 0; + + if ((setup->bRequestType & (USB_RECIP_MASK | USB_TYPE_MASK)) + == (USB_RECIP_ENDPOINT | USB_TYPE_STANDARD)) { + int pipe = get_pipe_by_windex(wIndex); + struct fsl_ep *ep; + + if (wValue != 0 || wLength != 0 || pipe > udc->max_ep) + break; + ep = get_ep_by_pipe(udc, pipe); + + spin_unlock(&udc->lock); + rc = fsl_ep_set_halt(&ep->ep, + (setup->bRequest == USB_REQ_SET_FEATURE) + ? 1 : 0); + spin_lock(&udc->lock); + + } else if ((setup->bRequestType & (USB_RECIP_MASK + | USB_TYPE_MASK)) == (USB_RECIP_DEVICE + | USB_TYPE_STANDARD)) { + /* Note: The driver has not include OTG support yet. + * This will be set when OTG support is added */ + if (setup->wValue == USB_DEVICE_TEST_MODE) + ptc = setup->wIndex >> 8; + else if (gadget_is_otg(&udc->gadget)) { + if (setup->bRequest == + USB_DEVICE_B_HNP_ENABLE) + udc->gadget.b_hnp_enable = 1; + else if (setup->bRequest == + USB_DEVICE_A_HNP_SUPPORT) + udc->gadget.a_hnp_support = 1; + else if (setup->bRequest == + USB_DEVICE_A_ALT_HNP_SUPPORT) + udc->gadget.a_alt_hnp_support = 1; + } + rc = 0; + } else + break; + + if (rc == 0) { + if (ep0_prime_status(udc, EP_DIR_IN)) + ep0stall(udc); + } + if (ptc) { + u32 tmp; + + mdelay(10); + fsl_platform_set_test_mode(udc->pdata, ptc); + tmp = fsl_readl(&dr_regs->portsc1) | (ptc << 16); + fsl_writel(tmp, &dr_regs->portsc1); + printk(KERN_INFO "udc: switch to test mode 0x%x.\n", ptc); + } + + return; + } + + default: + break; + } + + /* Requests handled by gadget */ + if (wLength) { + /* Data phase from gadget, status phase from udc */ + udc->ep0_dir = (setup->bRequestType & USB_DIR_IN) + ? USB_DIR_IN : USB_DIR_OUT; + spin_unlock(&udc->lock); + if (udc->driver->setup(&udc->gadget, + &udc->local_setup_buff) < 0) { + /* cancel status phase */ + udc_reset_ep_queue(udc, 0); + ep0stall(udc); + } + } else { + /* No data phase, IN status from gadget */ + udc->ep0_dir = USB_DIR_IN; + spin_unlock(&udc->lock); + if (udc->driver->setup(&udc->gadget, + &udc->local_setup_buff) < 0) + ep0stall(udc); + } + spin_lock(&udc->lock); +} + +/* Process request for Data or Status phase of ep0 + * prime status phase if needed */ +static void ep0_req_complete(struct fsl_udc *udc, struct fsl_ep *ep0, + struct fsl_req *req) +{ + if (udc->usb_state == USB_STATE_ADDRESS) { + /* Set the new address */ + u32 new_address = (u32) udc->device_address; + fsl_writel(new_address << USB_DEVICE_ADDRESS_BIT_POS, + &dr_regs->deviceaddr); + } + done(ep0, req, 0); +} + +/* Tripwire mechanism to ensure a setup packet payload is extracted without + * being corrupted by another incoming setup packet */ +static void tripwire_handler(struct fsl_udc *udc, u8 ep_num, u8 *buffer_ptr) +{ + u32 temp; + struct ep_queue_head *qh; + struct fsl_usb2_platform_data *pdata = udc->pdata; + + qh = &udc->ep_qh[ep_num * 2 + EP_DIR_OUT]; + + /* Clear bit in ENDPTSETUPSTAT */ + temp = fsl_readl(&dr_regs->endptsetupstat); + fsl_writel(temp | (1 << ep_num), &dr_regs->endptsetupstat); + + /* while a hazard exists when setup package arrives */ + do { + /* Set Setup Tripwire */ + temp = fsl_readl(&dr_regs->usbcmd); + fsl_writel(temp | USB_CMD_SUTW, &dr_regs->usbcmd); + + /* Copy the setup packet to local buffer */ + if (pdata->le_setup_buf) { + u32 *p = (u32 *)buffer_ptr; + u32 *s = (u32 *)qh->setup_buffer; + + /* Convert little endian setup buffer to CPU endian */ + *p++ = le32_to_cpu(*s++); + *p = le32_to_cpu(*s); + } else { + memcpy(buffer_ptr, (u8 *) qh->setup_buffer, 8); + } + } while (!(fsl_readl(&dr_regs->usbcmd) & USB_CMD_SUTW)); + + /* Clear Setup Tripwire */ + temp = fsl_readl(&dr_regs->usbcmd); + fsl_writel(temp & ~USB_CMD_SUTW, &dr_regs->usbcmd); +} + +static void iram_process_ep_complete(struct fsl_req *curr_req, + int cur_transfer) +{ + char *buf; + u32 len; + int in = ep_is_in(curr_req->ep); + + if (in) + buf = (char *)udc_controller->iram_buffer_v[1]; + else + buf = (char *)udc_controller->iram_buffer_v[0]; + + if (curr_req->cur->next_td_ptr == cpu_to_hc32(DTD_NEXT_TERMINATE) + || (cur_transfer < g_iram_size) + || (curr_req->req.length == curr_req->req.actual)) + curr_req->last_one = 1; + + if (curr_req->last_one) { + /* the last transfer */ + if (!in) { + memcpy(curr_req->req.buf + curr_req->buffer_offset, buf, + cur_transfer); + } + if (curr_req->tail->next_td_ptr != + cpu_to_hc32(DTD_NEXT_TERMINATE)) { + /* have next request,queue it */ + struct fsl_req *next_req; + next_req = + list_entry(curr_req->queue.next, + struct fsl_req, queue); + if (in) + memcpy(buf, next_req->req.buf, + min(g_iram_size, next_req->req.length)); + update_qh(next_req); + } + curr_req->req.dma = curr_req->oridma; + } else { + /* queue next dtd */ + /* because had next dtd, so should finish */ + /* tranferring g_iram_size data */ + curr_req->buffer_offset += g_iram_size; + /* pervious set stop bit,now clear it */ + curr_req->cur->next_td_ptr &= ~cpu_to_hc32(DTD_NEXT_TERMINATE); + curr_req->cur = curr_req->cur->next_td_virt; + if (in) { + len = + min(curr_req->req.length - curr_req->buffer_offset, + g_iram_size); + memcpy(buf, curr_req->req.buf + curr_req->buffer_offset, + len); + } else { + memcpy(curr_req->req.buf + curr_req->buffer_offset - + g_iram_size, buf, g_iram_size); + } + update_qh(curr_req); + } +} + +/* process-ep_req(): free the completed Tds for this req */ +static int process_ep_req(struct fsl_udc *udc, int pipe, + struct fsl_req *curr_req) +{ + struct ep_td_struct *curr_td; + int td_complete, actual, remaining_length, j, tmp; + int status = 0; + int errors = 0; + struct ep_queue_head *curr_qh = &udc->ep_qh[pipe]; + int direction = pipe % 2; + int total = 0, real_len; + + curr_td = curr_req->head; + td_complete = 0; + actual = curr_req->req.length; + real_len = curr_req->req.length; + + for (j = 0; j < curr_req->dtd_count; j++) { + remaining_length = (hc32_to_cpu(curr_td->size_ioc_sts) + & DTD_PACKET_SIZE) + >> DTD_LENGTH_BIT_POS; + if (NEED_IRAM(curr_req->ep)) { + if (real_len >= g_iram_size) { + actual = g_iram_size; + real_len -= g_iram_size; + } else { /* the last packet */ + actual = real_len; + curr_req->last_one = 1; + } + } + actual -= remaining_length; + total += actual; + + errors = hc32_to_cpu(curr_td->size_ioc_sts) & DTD_ERROR_MASK; + if (errors) { + if (errors & DTD_STATUS_HALTED) { + ERR("dTD error %08x QH=%d\n", errors, pipe); + /* Clear the errors and Halt condition */ + tmp = hc32_to_cpu(curr_qh->size_ioc_int_sts); + tmp &= ~errors; + curr_qh->size_ioc_int_sts = cpu_to_hc32(tmp); + status = -EPIPE; + /* FIXME: continue with next queued TD? */ + + break; + } + if (errors & DTD_STATUS_DATA_BUFF_ERR) { + VDBG("Transfer overflow"); + status = -EPROTO; + break; + } else if (errors & DTD_STATUS_TRANSACTION_ERR) { + VDBG("ISO error"); + status = -EILSEQ; + break; + } else + ERR("Unknown error has occured (0x%x)!\r\n", + errors); + + } else if (hc32_to_cpu(curr_td->size_ioc_sts) + & DTD_STATUS_ACTIVE) { + VDBG("Request not complete"); + status = REQ_UNCOMPLETE; + return status; + } else if (remaining_length) { + if (direction) { + VDBG("Transmit dTD remaining length not zero"); + status = -EPROTO; + break; + } else { + td_complete++; + break; + } + } else { + td_complete++; + VDBG("dTD transmitted successful "); + } + if (NEED_IRAM(curr_req->ep)) + if (curr_td-> + next_td_ptr & cpu_to_hc32(DTD_NEXT_TERMINATE)) + break; + if (j != curr_req->dtd_count - 1) + curr_td = (struct ep_td_struct *)curr_td->next_td_virt; + } + + if (status) + return status; + curr_req->req.actual = total; + if (NEED_IRAM(curr_req->ep)) + iram_process_ep_complete(curr_req, actual); + return 0; +} + +/* Process a DTD completion interrupt */ +static void dtd_complete_irq(struct fsl_udc *udc) +{ + u32 bit_pos; + int i, ep_num, direction, bit_mask, status; + struct fsl_ep *curr_ep; + struct fsl_req *curr_req, *temp_req; + + /* Clear the bits in the register */ + bit_pos = fsl_readl(&dr_regs->endptcomplete); + fsl_writel(bit_pos, &dr_regs->endptcomplete); + + if (!bit_pos) + return; + + for (i = 0; i < udc->max_ep * 2; i++) { + ep_num = i >> 1; + direction = i % 2; + + bit_mask = 1 << (ep_num + 16 * direction); + + if (!(bit_pos & bit_mask)) + continue; + + curr_ep = get_ep_by_pipe(udc, i); + + /* If the ep is configured */ + if (curr_ep->name == NULL) { + WARN("Invalid EP?"); + continue; + } + + /* process the req queue until an uncomplete request */ + list_for_each_entry_safe(curr_req, temp_req, &curr_ep->queue, + queue) { + status = process_ep_req(udc, i, curr_req); + + VDBG("status of process_ep_req= %d, ep = %d", + status, ep_num); + if (status == REQ_UNCOMPLETE) + break; + /* write back status to req */ + curr_req->req.status = status; + + if (ep_num == 0) { + ep0_req_complete(udc, curr_ep, curr_req); + break; + } else { + if (NEED_IRAM(curr_ep)) { + if (curr_req->last_one) + done(curr_ep, curr_req, status); + /* only check the 1th req */ + break; + } else + done(curr_ep, curr_req, status); + } + } + dump_ep_queue(curr_ep); + } +} + +/* Process a port change interrupt */ +static void port_change_irq(struct fsl_udc *udc) +{ + u32 speed; + + if (udc->bus_reset) + udc->bus_reset = 0; + + /* Bus resetting is finished */ + if (!(fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET)) { + /* Get the speed */ + speed = (fsl_readl(&dr_regs->portsc1) + & PORTSCX_PORT_SPEED_MASK); + switch (speed) { + case PORTSCX_PORT_SPEED_HIGH: + udc->gadget.speed = USB_SPEED_HIGH; + break; + case PORTSCX_PORT_SPEED_FULL: + udc->gadget.speed = USB_SPEED_FULL; + break; + case PORTSCX_PORT_SPEED_LOW: + udc->gadget.speed = USB_SPEED_LOW; + break; + default: + udc->gadget.speed = USB_SPEED_UNKNOWN; + break; + } + } + + /* Update USB state */ + if (!udc->resume_state) + udc->usb_state = USB_STATE_DEFAULT; +} + +/* Process suspend interrupt */ +static void suspend_irq(struct fsl_udc *udc) +{ + pr_debug("%s\n", __func__); + + udc->resume_state = udc->usb_state; + udc->usb_state = USB_STATE_SUSPENDED; + + /* report suspend to the driver, serial.c does not support this */ + if (udc->driver->suspend) + udc->driver->suspend(&udc->gadget); +} + +static void bus_resume(struct fsl_udc *udc) +{ + udc->usb_state = udc->resume_state; + udc->resume_state = 0; + + /* report resume to the driver, serial.c does not support this */ + if (udc->driver->resume) + udc->driver->resume(&udc->gadget); +} + +/* Clear up all ep queues */ +static int reset_queues(struct fsl_udc *udc) +{ + u8 pipe; + + for (pipe = 0; pipe < udc->max_pipes; pipe++) + udc_reset_ep_queue(udc, pipe); + + /* report disconnect; the driver is already quiesced */ + udc->driver->disconnect(&udc->gadget); + + return 0; +} + +/* Process reset interrupt */ +static void reset_irq(struct fsl_udc *udc) +{ + u32 temp; + unsigned long timeout; + + /* Clear the device address */ + temp = fsl_readl(&dr_regs->deviceaddr); + fsl_writel(temp & ~USB_DEVICE_ADDRESS_MASK, &dr_regs->deviceaddr); + + udc->device_address = 0; + + /* Clear usb state */ + udc->resume_state = 0; + udc->ep0_dir = 0; + udc->remote_wakeup = 0; /* default to 0 on reset */ + udc->gadget.b_hnp_enable = 0; + udc->gadget.a_hnp_support = 0; + udc->gadget.a_alt_hnp_support = 0; + + /* Clear all the setup token semaphores */ + temp = fsl_readl(&dr_regs->endptsetupstat); + fsl_writel(temp, &dr_regs->endptsetupstat); + + /* Clear all the endpoint complete status bits */ + temp = fsl_readl(&dr_regs->endptcomplete); + fsl_writel(temp, &dr_regs->endptcomplete); + + /* Write 1s to the flush register */ + fsl_writel(0xffffffff, &dr_regs->endptflush); + + if (fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET) { + VDBG("Bus reset"); + /* Bus is reseting */ + udc->bus_reset = 1; + /* Reset all the queues, include XD, dTD, EP queue + * head and TR Queue */ + reset_queues(udc); + udc->usb_state = USB_STATE_DEFAULT; + } else { + VDBG("Controller reset"); + /* initialize usb hw reg except for regs for EP, not + * touch usbintr reg */ + dr_controller_setup(udc); + + /* Reset all internal used Queues */ + reset_queues(udc); + + ep0_setup(udc); + + /* Enable DR IRQ reg, Set Run bit, change udc state */ + dr_controller_run(udc); + udc->usb_state = USB_STATE_ATTACHED; + } +} + +/* + * USB device controller interrupt handler + */ +static irqreturn_t fsl_udc_irq(int irq, void *_udc) +{ + struct fsl_udc *udc = _udc; + u32 irq_src; + irqreturn_t status = IRQ_NONE; + unsigned long flags; + + /* Disable ISR for OTG host mode */ + if (udc->stopped) + return IRQ_NONE; + spin_lock_irqsave(&udc->lock, flags); + irq_src = fsl_readl(&dr_regs->usbsts) & fsl_readl(&dr_regs->usbintr); + /* Clear notification bits */ + fsl_writel(irq_src, &dr_regs->usbsts); + + /* VDBG("irq_src [0x%8x]", irq_src); */ + + /* Need to resume? */ + if (udc->usb_state == USB_STATE_SUSPENDED) + if ((fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_SUSPEND) == 0) + bus_resume(udc); + + /* USB Interrupt */ + if (irq_src & USB_STS_INT) { + VDBG("Packet int"); + /* Setup package, we only support ep0 as control ep */ + if (fsl_readl(&dr_regs->endptsetupstat) & EP_SETUP_STATUS_EP0) { + tripwire_handler(udc, 0, + (u8 *) (&udc->local_setup_buff)); + setup_received_irq(udc, &udc->local_setup_buff); + status = IRQ_HANDLED; + } + + /* completion of dtd */ + if (fsl_readl(&dr_regs->endptcomplete)) { + dtd_complete_irq(udc); + status = IRQ_HANDLED; + } + } + + /* SOF (for ISO transfer) */ + if (irq_src & USB_STS_SOF) { + status = IRQ_HANDLED; + } + + /* Port Change */ + if (irq_src & USB_STS_PORT_CHANGE) { + port_change_irq(udc); + status = IRQ_HANDLED; + } + + /* Reset Received */ + if (irq_src & USB_STS_RESET) { + VDBG("reset int"); + reset_irq(udc); + status = IRQ_HANDLED; + } + + /* Sleep Enable (Suspend) */ + if (irq_src & USB_STS_SUSPEND) { + suspend_irq(udc); + status = IRQ_HANDLED; + } + + if (irq_src & (USB_STS_ERR | USB_STS_SYS_ERR)) { + VDBG("Error IRQ %x ", irq_src); + } + + spin_unlock_irqrestore(&udc->lock, flags); + return status; +} + +/*----------------------------------------------------------------* + * Hook to gadget drivers + * Called by initialization code of gadget drivers +*----------------------------------------------------------------*/ +int usb_gadget_register_driver(struct usb_gadget_driver *driver) +{ + int retval = -ENODEV; + unsigned long flags = 0; + + if (!udc_controller) + return -ENODEV; + + if (!driver || (driver->speed != USB_SPEED_FULL + && driver->speed != USB_SPEED_HIGH) + || !driver->bind || !driver->disconnect + || !driver->setup) + return -EINVAL; + + if (udc_controller->driver) + return -EBUSY; + + /* lock is needed but whether should use this lock or another */ + spin_lock_irqsave(&udc_controller->lock, flags); + + driver->driver.bus = 0; + /* hook up the driver */ + udc_controller->driver = driver; + udc_controller->gadget.dev.driver = &driver->driver; + spin_unlock_irqrestore(&udc_controller->lock, flags); + + /* bind udc driver to gadget driver */ + retval = driver->bind(&udc_controller->gadget); + if (retval) { + VDBG("bind to %s --> %d", driver->driver.name, retval); + udc_controller->gadget.dev.driver = 0; + udc_controller->driver = 0; + goto out; + } + + if (udc_controller->transceiver) { + /* Suspend the controller until OTG enable it */ + udc_controller->stopped = 1; + printk(KERN_INFO "Suspend udc for OTG auto detect\n"); + + /* export udc suspend/resume call to OTG */ + udc_controller->gadget.dev.driver->suspend = fsl_udc_suspend; + udc_controller->gadget.dev.driver->resume = fsl_udc_resume; + + /* connect to bus through transceiver */ + if (udc_controller->transceiver) { + retval = otg_set_peripheral(udc_controller->transceiver, + &udc_controller->gadget); + if (retval < 0) { + ERR("can't bind to transceiver\n"); + driver->unbind(&udc_controller->gadget); + udc_controller->gadget.dev.driver = 0; + udc_controller->driver = 0; + return retval; + } + } + } else { + /* Enable DR IRQ reg and Set usbcmd reg Run bit */ + dr_controller_run(udc_controller); + udc_controller->usb_state = USB_STATE_ATTACHED; + udc_controller->ep0_dir = 0; + } + printk(KERN_INFO "%s: bind to driver %s \n", + udc_controller->gadget.name, driver->driver.name); + +out: + if (retval) + printk(KERN_DEBUG "retval %d \n", retval); + return retval; +} +EXPORT_SYMBOL(usb_gadget_register_driver); + +/* Disconnect from gadget driver */ +int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) +{ + struct fsl_ep *loop_ep; + unsigned long flags; + + if (!udc_controller) + return -ENODEV; + + if (!driver || driver != udc_controller->driver || !driver->unbind) + return -EINVAL; + + if (udc_controller->transceiver) + (void)otg_set_peripheral(udc_controller->transceiver, 0); + + /* stop DR, disable intr */ + dr_controller_stop(udc_controller); + + /* in fact, no needed */ + udc_controller->usb_state = USB_STATE_ATTACHED; + udc_controller->ep0_dir = 0; + + /* stand operation */ + spin_lock_irqsave(&udc_controller->lock, flags); + udc_controller->gadget.speed = USB_SPEED_UNKNOWN; + nuke(&udc_controller->eps[0], -ESHUTDOWN); + list_for_each_entry(loop_ep, &udc_controller->gadget.ep_list, + ep.ep_list) + nuke(loop_ep, -ESHUTDOWN); + spin_unlock_irqrestore(&udc_controller->lock, flags); + + /* unbind gadget and unhook driver. */ + driver->unbind(&udc_controller->gadget); + udc_controller->gadget.dev.driver = 0; + udc_controller->driver = 0; + + printk(KERN_INFO "unregistered gadget driver '%s'\r\n", + driver->driver.name); + return 0; +} +EXPORT_SYMBOL(usb_gadget_unregister_driver); + +/*------------------------------------------------------------------------- + PROC File System Support +-------------------------------------------------------------------------*/ +#ifdef CONFIG_USB_GADGET_DEBUG_FILES + +#include + +static const char proc_filename[] = "driver/fsl_usb2_udc"; + +static int fsl_proc_read(char *page, char **start, off_t off, int count, + int *eof, void *_dev) +{ + char *buf = page; + char *next = buf; + unsigned size = count; + unsigned long flags; + int t, i; + u32 tmp_reg; + struct fsl_ep *ep = NULL; + struct fsl_req *req; + struct fsl_usb2_platform_data *pdata; + + struct fsl_udc *udc = udc_controller; + pdata = udc->pdata; + if (off != 0) + return 0; + + spin_lock_irqsave(&udc->lock, flags); + + /* ------basic driver infomation ---- */ + t = scnprintf(next, size, + DRIVER_DESC "\n" + "%s version: %s\n" + "Gadget driver: %s\n\n", + driver_name, DRIVER_VERSION, + udc->driver ? udc->driver->driver.name : "(none)"); + size -= t; + next += t; + + /* ------ DR Registers ----- */ + tmp_reg = fsl_readl(&dr_regs->usbcmd); + t = scnprintf(next, size, + "USBCMD reg:\n" + "SetupTW: %d\n" + "Run/Stop: %s\n\n", + (tmp_reg & USB_CMD_SUTW) ? 1 : 0, + (tmp_reg & USB_CMD_RUN_STOP) ? "Run" : "Stop"); + size -= t; + next += t; + + tmp_reg = fsl_readl(&dr_regs->usbsts); + t = scnprintf(next, size, + "USB Status Reg:\n" + "Dr Suspend: %d" "Reset Received: %d" "System Error: %s" + "USB Error Interrupt: %s\n\n", + (tmp_reg & USB_STS_SUSPEND) ? 1 : 0, + (tmp_reg & USB_STS_RESET) ? 1 : 0, + (tmp_reg & USB_STS_SYS_ERR) ? "Err" : "Normal", + (tmp_reg & USB_STS_ERR) ? "Err detected" : "No err"); + size -= t; + next += t; + + tmp_reg = fsl_readl(&dr_regs->usbintr); + t = scnprintf(next, size, + "USB Intrrupt Enable Reg:\n" + "Sleep Enable: %d" "SOF Received Enable: %d" + "Reset Enable: %d\n" + "System Error Enable: %d" + "Port Change Dectected Enable: %d\n" + "USB Error Intr Enable: %d" "USB Intr Enable: %d\n\n", + (tmp_reg & USB_INTR_DEVICE_SUSPEND) ? 1 : 0, + (tmp_reg & USB_INTR_SOF_EN) ? 1 : 0, + (tmp_reg & USB_INTR_RESET_EN) ? 1 : 0, + (tmp_reg & USB_INTR_SYS_ERR_EN) ? 1 : 0, + (tmp_reg & USB_INTR_PTC_DETECT_EN) ? 1 : 0, + (tmp_reg & USB_INTR_ERR_INT_EN) ? 1 : 0, + (tmp_reg & USB_INTR_INT_EN) ? 1 : 0); + size -= t; + next += t; + + tmp_reg = fsl_readl(&dr_regs->frindex); + t = scnprintf(next, size, + "USB Frame Index Reg:" "Frame Number is 0x%x\n\n", + (tmp_reg & USB_FRINDEX_MASKS)); + size -= t; + next += t; + + tmp_reg = fsl_readl(&dr_regs->deviceaddr); + t = scnprintf(next, size, + "USB Device Address Reg:" "Device Addr is 0x%x\n\n", + (tmp_reg & USB_DEVICE_ADDRESS_MASK)); + size -= t; + next += t; + + tmp_reg = fsl_readl(&dr_regs->endpointlistaddr); + t = scnprintf(next, size, + "USB Endpoint List Address Reg:" + "Device Addr is 0x%x\n\n", + (tmp_reg & USB_EP_LIST_ADDRESS_MASK)); + size -= t; + next += t; + + tmp_reg = fsl_readl(&dr_regs->portsc1); + t = scnprintf(next, size, + "USB Port Status&Control Reg:\n" + "Port Transceiver Type : %s" "Port Speed: %s \n" + "PHY Low Power Suspend: %s" "Port Reset: %s" + "Port Suspend Mode: %s \n" "Over-current Change: %s" + "Port Enable/Disable Change: %s\n" + "Port Enabled/Disabled: %s" + "Current Connect Status: %s\n\n", ({ + char *s; + switch (tmp_reg & PORTSCX_PTS_FSLS) { + case PORTSCX_PTS_UTMI: + s = "UTMI"; break; + case PORTSCX_PTS_ULPI: + s = "ULPI "; break; + case PORTSCX_PTS_FSLS: + s = "FS/LS Serial"; break; + default: + s = "None"; break; + } + s; }), ({ + char *s; + switch (tmp_reg & PORTSCX_PORT_SPEED_UNDEF) { + case PORTSCX_PORT_SPEED_FULL: + s = "Full Speed"; break; + case PORTSCX_PORT_SPEED_LOW: + s = "Low Speed"; break; + case PORTSCX_PORT_SPEED_HIGH: + s = "High Speed"; break; + default: + s = "Undefined"; break; + } + s; + }), + (tmp_reg & PORTSCX_PHY_LOW_POWER_SPD) ? + "Normal PHY mode" : "Low power mode", + (tmp_reg & PORTSCX_PORT_RESET) ? "In Reset" : + "Not in Reset", + (tmp_reg & PORTSCX_PORT_SUSPEND) ? "In " : "Not in", + (tmp_reg & PORTSCX_OVER_CURRENT_CHG) ? "Dected" : + "No", + (tmp_reg & PORTSCX_PORT_EN_DIS_CHANGE) ? "Disable" : + "Not change", + (tmp_reg & PORTSCX_PORT_ENABLE) ? "Enable" : + "Not correct", + (tmp_reg & PORTSCX_CURRENT_CONNECT_STATUS) ? + "Attached" : "Not-Att"); + size -= t; + next += t; + + tmp_reg = fsl_readl(&dr_regs->usbmode); + t = scnprintf(next, size, + "USB Mode Reg:" "Controller Mode is : %s\n\n", ({ + char *s; + switch (tmp_reg & USB_MODE_CTRL_MODE_HOST) { + case USB_MODE_CTRL_MODE_IDLE: + s = "Idle"; break; + case USB_MODE_CTRL_MODE_DEVICE: + s = "Device Controller"; break; + case USB_MODE_CTRL_MODE_HOST: + s = "Host Controller"; break; + default: + s = "None"; break; + } + s; + })); + size -= t; + next += t; + + tmp_reg = fsl_readl(&dr_regs->endptsetupstat); + t = scnprintf(next, size, + "Endpoint Setup Status Reg:" "SETUP on ep 0x%x\n\n", + (tmp_reg & EP_SETUP_STATUS_MASK)); + size -= t; + next += t; + + for (i = 0; i < udc->max_ep / 2; i++) { + tmp_reg = fsl_readl(&dr_regs->endptctrl[i]); + t = scnprintf(next, size, "EP Ctrl Reg [0x%x]: = [0x%x]\n", + i, tmp_reg); + size -= t; + next += t; + } + tmp_reg = fsl_readl(&dr_regs->endpointprime); + t = scnprintf(next, size, "EP Prime Reg = [0x%x]\n", tmp_reg); + size -= t; + next += t; + + if (pdata->have_sysif_regs) { + tmp_reg = usb_sys_regs->snoop1; + t = scnprintf(next, size, "\nSnoop1 Reg = [0x%x]\n\n", tmp_reg); + size -= t; + next += t; + + tmp_reg = usb_sys_regs->control; + t = scnprintf(next, size, "General Control Reg = [0x%x]\n\n", + tmp_reg); + size -= t; + next += t; + } + + /* ------fsl_udc, fsl_ep, fsl_request structure information ----- */ + ep = &udc->eps[0]; + t = scnprintf(next, size, "For %s Maxpkt is 0x%x index is 0x%x\n", + ep->ep.name, ep_maxpacket(ep), ep_index(ep)); + size -= t; + next += t; + + if (list_empty(&ep->queue)) { + t = scnprintf(next, size, "its req queue is empty\n\n"); + size -= t; + next += t; + } else { + list_for_each_entry(req, &ep->queue, queue) { + t = scnprintf(next, size, + "req %p actual 0x%x length 0x%x buf %p\n", + &req->req, req->req.actual, + req->req.length, req->req.buf); + size -= t; + next += t; + } + } + /* other gadget->eplist ep */ + list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) { + if (ep->desc) { + t = scnprintf(next, size, + "\nFor %s Maxpkt is 0x%x " + "index is 0x%x\n", + ep->ep.name, ep_maxpacket(ep), + ep_index(ep)); + size -= t; + next += t; + + if (list_empty(&ep->queue)) { + t = scnprintf(next, size, + "its req queue is empty\n\n"); + size -= t; + next += t; + } else { + list_for_each_entry(req, &ep->queue, queue) { + t = scnprintf(next, size, + "req %p actual 0x%x length" + "0x%x buf %p\n", + &req->req, req->req.actual, + req->req.length, req->req.buf); + size -= t; + next += t; + } /* end for each_entry of ep req */ + } /* end for else */ + } /* end for if(ep->queue) */ + } /* end (ep->desc) */ + + spin_unlock_irqrestore(&udc->lock, flags); + + *eof = 1; + return count - size; +} + +#define create_proc_file() create_proc_read_entry(proc_filename, \ + 0, NULL, fsl_proc_read, NULL) + +#define remove_proc_file() remove_proc_entry(proc_filename, NULL) + +#else /* !CONFIG_USB_GADGET_DEBUG_FILES */ + +#define create_proc_file() do {} while (0) +#define remove_proc_file() do {} while (0) + +#endif /* CONFIG_USB_GADGET_DEBUG_FILES */ + +/*-------------------------------------------------------------------------*/ + +/* Release udc structures */ +static void fsl_udc_release(struct device *dev) +{ + complete(udc_controller->done); + dma_free_coherent(dev, udc_controller->ep_qh_size, + udc_controller->ep_qh, udc_controller->ep_qh_dma); + kfree(udc_controller); +} + +/****************************************************************** + Internal structure setup functions +*******************************************************************/ +/*------------------------------------------------------------------ + * init resource for globle controller + * Return the udc handle on success or NULL on failure + ------------------------------------------------------------------*/ +static int __init struct_udc_setup(struct fsl_udc *udc, + struct platform_device *pdev) +{ + struct fsl_usb2_platform_data *pdata; + size_t size; + + pdata = pdev->dev.platform_data; + udc->phy_mode = pdata->phy_mode; + + udc->eps = kzalloc(sizeof(struct fsl_ep) * udc->max_ep, GFP_KERNEL); + if (!udc->eps) { + ERR("malloc fsl_ep failed\n"); + return -1; + } + + /* initialized QHs, take care of alignment */ + size = udc->max_ep * sizeof(struct ep_queue_head); + if (size < QH_ALIGNMENT) + size = QH_ALIGNMENT; + else if ((size % QH_ALIGNMENT) != 0) { + size += QH_ALIGNMENT + 1; + size &= ~(QH_ALIGNMENT - 1); + } + udc->ep_qh = dma_alloc_coherent(&pdev->dev, size, + &udc->ep_qh_dma, GFP_KERNEL); + if (!udc->ep_qh) { + ERR("malloc QHs for udc failed\n"); + kfree(udc->eps); + return -1; + } + + udc->ep_qh_size = size; + + /* Initialize ep0 status request structure */ + /* FIXME: fsl_alloc_request() ignores ep argument */ + udc->status_req = container_of(fsl_alloc_request(NULL, GFP_KERNEL), + struct fsl_req, req); + /* for future use */ + udc->status_req->req.buf = kmalloc(8, GFP_KERNEL); + udc->status_req->req.dma = virt_to_phys(udc->status_req->req.buf); + /* Initialize ep0 data request structure */ + udc->data_req = container_of(fsl_alloc_request(NULL, GFP_KERNEL), + struct fsl_req, req); + udc->data_req->req.buf = kmalloc(8, GFP_KERNEL); + udc->data_req->req.dma = virt_to_phys(udc->data_req->req.buf); + + udc->resume_state = USB_STATE_NOTATTACHED; + udc->usb_state = USB_STATE_POWERED; + udc->ep0_dir = 0; + udc->remote_wakeup = 0; /* default to 0 on reset */ + spin_lock_init(&udc->lock); + + return 0; +} + +/*---------------------------------------------------------------- + * Setup the fsl_ep struct for eps + * Link fsl_ep->ep to gadget->ep_list + * ep0out is not used so do nothing here + * ep0in should be taken care + *--------------------------------------------------------------*/ +static int __init struct_ep_setup(struct fsl_udc *udc, unsigned char index, + char *name, int link) +{ + struct fsl_ep *ep = &udc->eps[index]; + + ep->udc = udc; + strcpy(ep->name, name); + ep->ep.name = ep->name; + + ep->ep.ops = &fsl_ep_ops; + ep->stopped = 0; + + /* for ep0: maxP defined in desc + * for other eps, maxP is set by epautoconfig() called by gadget layer + */ + ep->ep.maxpacket = (unsigned short) ~0; + + /* the queue lists any req for this ep */ + INIT_LIST_HEAD(&ep->queue); + + /* gagdet.ep_list used for ep_autoconfig so no ep0 */ + if (link) + list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list); + ep->gadget = &udc->gadget; + ep->qh = &udc->ep_qh[index]; + + return 0; +} + +/* Driver probe function + * all intialization operations implemented here except enabling usb_intr reg + * board setup should have been done in the platform code + */ +static int __init fsl_udc_probe(struct platform_device *pdev) +{ + struct resource *res; + struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; + int ret = -ENODEV; + unsigned int i; + u32 dccparams; + + if (strcmp(pdev->name, driver_name)) { + VDBG("Wrong device\n"); + return -ENODEV; + } + + udc_controller = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL); + if (udc_controller == NULL) { + ERR("malloc udc failed\n"); + return -ENOMEM; + } + udc_controller->pdata = pdata; + +#ifdef CONFIG_USB_OTG + /* Memory and interrupt resources will be passed from OTG */ + udc_controller->transceiver = otg_get_transceiver(); + if (!udc_controller->transceiver) { + printk(KERN_ERR "Can't find OTG driver!\n"); + ret = -ENODEV; + goto err1a; + } + + res = otg_get_resources(); + if (!res) { + DBG("resource not registered!\n"); + return -ENODEV; + } +#else + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + ret = -ENXIO; + goto err1a; + } + + if (!request_mem_region(res->start, res->end - res->start + 1, + driver_name)) { + ERR("request mem region for %s failed \n", pdev->name); + ret = -EBUSY; + goto err1a; + } +#endif + dr_regs = ioremap(res->start, res->end - res->start + 1); + if (!dr_regs) { + ret = -ENOMEM; + goto err1; + } + pdata->regs = (void *)dr_regs; + /* + * do platform specific init: check the clock, grab/config pins, etc. + */ + if (pdata->platform_init && pdata->platform_init(pdev)) { + ret = -ENODEV; + goto err2a; + } + + if (pdata->have_sysif_regs) + usb_sys_regs = (struct usb_sys_interface *) + ((u32)dr_regs + USB_DR_SYS_OFFSET); + + /* Read Device Controller Capability Parameters register */ + dccparams = fsl_readl(&dr_regs->dccparams); + if (!(dccparams & DCCPARAMS_DC)) { + ERR("This SOC doesn't support device role\n"); + ret = -ENODEV; + goto err2; + } + /* Get max device endpoints */ + /* DEN is bidirectional ep number, max_ep doubles the number */ + udc_controller->max_ep = (dccparams & DCCPARAMS_DEN_MASK) * 2; + +#ifdef CONFIG_USB_OTG + res++; + udc_controller->irq = res->start; +#else + udc_controller->irq = platform_get_irq(pdev, 0); +#endif + if (!udc_controller->irq) { + ret = -ENODEV; + goto err2; + } + + ret = request_irq(udc_controller->irq, fsl_udc_irq, IRQF_SHARED, + driver_name, udc_controller); + if (ret != 0) { + ERR("cannot request irq %d err %d \n", + udc_controller->irq, ret); + goto err2; + } + + /* Initialize the udc structure including QH member and other member */ + if (struct_udc_setup(udc_controller, pdev)) { + ERR("Can't initialize udc data structure\n"); + ret = -ENOMEM; + goto err3; + } + + if (!udc_controller->transceiver) { + /* initialize usb hw reg except for regs for EP, + * leave usbintr reg untouched */ + dr_controller_setup(udc_controller); + } + + /* Setup gadget structure */ + udc_controller->gadget.ops = &fsl_gadget_ops; + udc_controller->gadget.is_dualspeed = 1; + udc_controller->gadget.ep0 = &udc_controller->eps[0].ep; + INIT_LIST_HEAD(&udc_controller->gadget.ep_list); + udc_controller->gadget.speed = USB_SPEED_UNKNOWN; + udc_controller->gadget.name = driver_name; + + /* Setup gadget.dev and register with kernel */ + strcpy(udc_controller->gadget.dev.bus_id, "gadget"); + udc_controller->gadget.dev.release = fsl_udc_release; + udc_controller->gadget.dev.parent = &pdev->dev; + ret = device_register(&udc_controller->gadget.dev); + if (ret < 0) + goto err3; + + if (udc_controller->transceiver) + udc_controller->gadget.is_otg = 1; + + /* setup QH and epctrl for ep0 */ + ep0_setup(udc_controller); + + /* setup udc->eps[] for ep0 */ + struct_ep_setup(udc_controller, 0, "ep0", 0); + /* for ep0: the desc defined here; + * for other eps, gadget layer called ep_enable with defined desc + */ + udc_controller->eps[0].desc = &fsl_ep0_desc; + udc_controller->eps[0].ep.maxpacket = USB_MAX_CTRL_PAYLOAD; + + /* setup the udc->eps[] for non-control endpoints and link + * to gadget.ep_list */ + for (i = 1; i < (int)(udc_controller->max_ep / 2); i++) { + char name[14]; + + sprintf(name, "ep%dout", i); + struct_ep_setup(udc_controller, i * 2, name, 1); + sprintf(name, "ep%din", i); + struct_ep_setup(udc_controller, i * 2 + 1, name, 1); + } + + /* use dma_pool for TD management */ + udc_controller->td_pool = dma_pool_create("udc_td", &pdev->dev, + sizeof(struct ep_td_struct), + DTD_ALIGNMENT, UDC_DMA_BOUNDARY); + if (udc_controller->td_pool == NULL) { + ret = -ENOMEM; + goto err4; + } + if (g_iram_size) { + for (i = 0; i < IRAM_PPH_NTD; i++) { + udc_controller->iram_buffer[i] = + USB_IRAM_BASE_ADDR + i * g_iram_size; + udc_controller->iram_buffer_v[i] = + IO_ADDRESS(udc_controller->iram_buffer[i]); + } + } + + create_proc_file(); + return 0; + +err4: + device_unregister(&udc_controller->gadget.dev); +err3: + free_irq(udc_controller->irq, udc_controller); +err2: + if (pdata->platform_uninit) + pdata->platform_uninit(pdata); +err2a: + iounmap(dr_regs); +err1: + if (!udc_controller->transceiver) + release_mem_region(res->start, res->end - res->start + 1); +err1a: + kfree(udc_controller); + udc_controller = NULL; + return ret; +} + +/* Driver removal function + * Free resources and finish pending transactions + */ +static int __exit fsl_udc_remove(struct platform_device *pdev) +{ + struct resource *res; + struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; + + DECLARE_COMPLETION(done); + + if (!udc_controller) + return -ENODEV; + udc_controller->done = &done; + + /* DR has been stopped in usb_gadget_unregister_driver() */ + remove_proc_file(); + + /* Free allocated memory */ + kfree(udc_controller->status_req->req.buf); + kfree(udc_controller->status_req); + kfree(udc_controller->data_req->req.buf); + kfree(udc_controller->data_req); + kfree(udc_controller->eps); + + dma_pool_destroy(udc_controller->td_pool); + free_irq(udc_controller->irq, udc_controller); + iounmap(dr_regs); + +#ifndef CONFIG_USB_OTG + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(res->start, res->end - res->start + 1); +#endif + + device_unregister(&udc_controller->gadget.dev); + /* free udc --wait for the release() finished */ + wait_for_completion(&done); + + /* + * do platform specific un-initialization: + * release iomux pins, etc. + */ + if (pdata->platform_uninit) + pdata->platform_uninit(pdata); + + return 0; +} + +static int udc_suspend(struct fsl_udc *udc) +{ + u32 mode, usbcmd; + + mode = fsl_readl(&dr_regs->usbmode) & USB_MODE_CTRL_MODE_MASK; + usbcmd = fsl_readl(&dr_regs->usbcmd); + + pr_debug("%s(): mode 0x%x stopped %d\n", __func__, mode, udc->stopped); + + /* + * If the controller is already stopped, then this must be a + * PM suspend. Remember this fact, so that we will leave the + * controller stopped at PM resume time. + */ + if (udc->stopped) { + pr_debug("gadget already stopped, leaving early\n"); + udc->already_stopped = 1; + return 0; + } + + if (mode != USB_MODE_CTRL_MODE_DEVICE) { + pr_debug("gadget not in device mode, leaving early\n"); + return 0; + } + + printk(KERN_INFO "USB Gadget suspended\n"); + + /* stop the controller */ + usbcmd = fsl_readl(&dr_regs->usbcmd) & ~USB_CMD_RUN_STOP; + fsl_writel(usbcmd, &dr_regs->usbcmd); + + udc->stopped = 1; + return 0; +} + +/*----------------------------------------------------------------- + * Modify Power management attributes + * Used by OTG statemachine to disable gadget temporarily + -----------------------------------------------------------------*/ +static int fsl_udc_suspend(struct platform_device *pdev, pm_message_t state) +{ + return udc_suspend(udc_controller); +} + +/*----------------------------------------------------------------- + * Invoked on USB resume. May be called in_interrupt. + * Here we start the DR controller and enable the irq + *-----------------------------------------------------------------*/ +static int fsl_udc_resume(struct platform_device *pdev) +{ + pr_debug("%s(): stopped %d already_stopped %d\n", __func__, + udc_controller->stopped, udc_controller->already_stopped); + + /* + * If the controller was stopped at suspend time, then + * don't resume it now. + */ + if (udc_controller->already_stopped) { + udc_controller->already_stopped = 0; + pr_debug("gadget was already stopped, leaving early\n"); + return 0; + } + + /* Enable DR irq reg and set controller Run */ + if (udc_controller->stopped) { + dr_controller_setup(udc_controller); + dr_controller_run(udc_controller); + } + udc_controller->usb_state = USB_STATE_ATTACHED; + udc_controller->ep0_dir = 0; + + printk(KERN_INFO "USB Gadget resumed\n"); + return 0; +} + +/*------------------------------------------------------------------------- + Register entry point for the peripheral controller driver +--------------------------------------------------------------------------*/ + +static struct platform_driver udc_driver = { + .remove = __exit_p(fsl_udc_remove), + /* these suspend and resume are not usb suspend and resume */ + .suspend = fsl_udc_suspend, + .resume = fsl_udc_resume, + .probe = fsl_udc_probe, + .driver = { + .name = driver_name, + .owner = THIS_MODULE, + }, +}; + +static int __init udc_init(void) +{ + printk(KERN_INFO "%s (%s)\n", driver_desc, DRIVER_VERSION); + return platform_driver_register(&udc_driver); +} + +module_init(udc_init); + +static void __exit udc_exit(void) +{ + platform_driver_unregister(&udc_driver); + printk(KERN_INFO "%s unregistered \n", driver_desc); +} + +module_exit(udc_exit); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/usb/gadget/Makefile +++ linux-2.6.28/drivers/usb/gadget/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o obj-$(CONFIG_USB_M66592) += m66592-udc.o obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o +obj-$(CONFIG_USB_ARC) += arcotg_udc.o # # USB gadget drivers @@ -27,7 +28,11 @@ g_ether-objs := ether.o g_serial-objs := serial.o g_midi-objs := gmidi.o +ifeq ($(CONFIG_ARCH_MXC_CANONICAL),y) +gadgetfs-objs := arm_mxc_ubuntu_inode.o +else gadgetfs-objs := inode.o +endif g_file_storage-objs := file_storage.o g_printer-objs := printer.o g_cdc-objs := cdc2.o --- linux-2.6.28.orig/drivers/usb/gadget/arcotg_udc.h +++ linux-2.6.28/drivers/usb/gadget/arcotg_udc.h @@ -0,0 +1,669 @@ +/* + * Copyright 2004-2009 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 + */ + +/*! + * @file arcotg_udc.h + * @brief Freescale USB device/endpoint management registers + * @ingroup USB + */ + +#ifndef __ARCOTG_UDC_H +#define __ARCOTG_UDC_H + +#define TRUE 1 +#define FALSE 0 + +#define MSC_BULK_CB_WRAP_LEN 31 +#define USE_MSC_WR(len) (((cpu_is_mx37_rev(CHIP_REV_1_0) == 1) ||\ + (cpu_is_mx51_rev(CHIP_REV_2_0) < 0)) && ((len) == MSC_BULK_CB_WRAP_LEN)) + +/* Iram patch */ +#ifdef CONFIG_USB_STATIC_IRAM_PPH +/* size of 1 qTD's buffer,one is for BULK IN and other is BULK OUT */ +#define IRAM_TD_PPH_SIZE (USB_IRAM_SIZE / 2) +#define IRAM_PPH_NTD 2 /* number of TDs in IRAM */ +#else +#define IRAM_TD_PPH_SIZE 0 +#define IRAM_PPH_NTD 0 +#endif + +#ifndef USB_IRAM_BASE_ADDR +#define USB_IRAM_BASE_ADDR 0 +#endif + +#define NEED_IRAM(ep) ((g_iram_size) && \ + ((ep)->desc->bmAttributes == USB_ENDPOINT_XFER_BULK)) + +/* ### define USB registers here + */ +#define USB_MAX_ENDPOINTS 8 +#define USB_MAX_PIPES (USB_MAX_ENDPOINTS*2) +#define USB_MAX_CTRL_PAYLOAD 64 +#define USB_DR_SYS_OFFSET 0x400 + +#define USB_DR_OFFSET 0x3100 + +struct usb_dr_device { + /* Capability register */ + u32 id; + u32 res1[35]; + u32 sbuscfg; /* sbuscfg ahb burst */ + u32 res11[27]; + u16 caplength; /* Capability Register Length */ + u16 hciversion; /* Host Controller Interface Version */ + u32 hcsparams; /* Host Controller Structual Parameters */ + u32 hccparams; /* Host Controller Capability Parameters */ + u32 res2[5]; + u32 dciversion; /* Device Controller Interface Version */ + u32 dccparams; /* Device Controller Capability Parameters */ + u32 res3[6]; + /* Operation register */ + u32 usbcmd; /* USB Command Register */ + u32 usbsts; /* USB Status Register */ + u32 usbintr; /* USB Interrupt Enable Register */ + u32 frindex; /* Frame Index Register */ + u32 res4; + u32 deviceaddr; /* Device Address */ + u32 endpointlistaddr; /* Endpoint List Address Register */ + u32 res5; + u32 burstsize; /* Master Interface Data Burst Size Register */ + u32 txttfilltuning; /* Transmit FIFO Tuning Controls Register */ + u32 res6[6]; + u32 configflag; /* Configure Flag Register */ + u32 portsc1; /* Port 1 Status and Control Register */ + u32 res7[7]; + u32 otgsc; /* On-The-Go Status and Control */ + u32 usbmode; /* USB Mode Register */ + u32 endptsetupstat; /* Endpoint Setup Status Register */ + u32 endpointprime; /* Endpoint Initialization Register */ + u32 endptflush; /* Endpoint Flush Register */ + u32 endptstatus; /* Endpoint Status Register */ + u32 endptcomplete; /* Endpoint Complete Register */ + u32 endptctrl[8 * 2]; /* Endpoint Control Registers */ +}; + + /* non-EHCI USB system interface registers (Big Endian) */ +struct usb_sys_interface { + u32 snoop1; + u32 snoop2; + u32 age_cnt_thresh; /* Age Count Threshold Register */ + u32 pri_ctrl; /* Priority Control Register */ + u32 si_ctrl; /* System Interface Control Register */ + u8 res[236]; + u32 control; /* General Purpose Control Register */ +}; + +/* ep0 transfer state */ +#define WAIT_FOR_SETUP 0 +#define DATA_STATE_XMIT 1 +#define DATA_STATE_NEED_ZLP 2 +#define WAIT_FOR_OUT_STATUS 3 +#define DATA_STATE_RECV 4 + +/* Device Controller Capability Parameter register */ +#define DCCPARAMS_DC 0x00000080 +#define DCCPARAMS_DEN_MASK 0x0000001f + +/* Frame Index Register Bit Masks */ +#define USB_FRINDEX_MASKS (0x3fff) +/* USB CMD Register Bit Masks */ +#define USB_CMD_RUN_STOP (0x00000001) +#define USB_CMD_CTRL_RESET (0x00000002) +#define USB_CMD_PERIODIC_SCHEDULE_EN (0x00000010) +#define USB_CMD_ASYNC_SCHEDULE_EN (0x00000020) +#define USB_CMD_INT_AA_DOORBELL (0x00000040) +#define USB_CMD_ASP (0x00000300) +#define USB_CMD_ASYNC_SCH_PARK_EN (0x00000800) +#define USB_CMD_SUTW (0x00002000) +#define USB_CMD_ATDTW (0x00004000) +#define USB_CMD_ITC (0x00FF0000) + +/* bit 15,3,2 are frame list size */ +#define USB_CMD_FRAME_SIZE_1024 (0x00000000) +#define USB_CMD_FRAME_SIZE_512 (0x00000004) +#define USB_CMD_FRAME_SIZE_256 (0x00000008) +#define USB_CMD_FRAME_SIZE_128 (0x0000000C) +#define USB_CMD_FRAME_SIZE_64 (0x00008000) +#define USB_CMD_FRAME_SIZE_32 (0x00008004) +#define USB_CMD_FRAME_SIZE_16 (0x00008008) +#define USB_CMD_FRAME_SIZE_8 (0x0000800C) + +/* bit 9-8 are async schedule park mode count */ +#define USB_CMD_ASP_00 (0x00000000) +#define USB_CMD_ASP_01 (0x00000100) +#define USB_CMD_ASP_10 (0x00000200) +#define USB_CMD_ASP_11 (0x00000300) +#define USB_CMD_ASP_BIT_POS (8) + +/* bit 23-16 are interrupt threshold control */ +#define USB_CMD_ITC_NO_THRESHOLD (0x00000000) +#define USB_CMD_ITC_1_MICRO_FRM (0x00010000) +#define USB_CMD_ITC_2_MICRO_FRM (0x00020000) +#define USB_CMD_ITC_4_MICRO_FRM (0x00040000) +#define USB_CMD_ITC_8_MICRO_FRM (0x00080000) +#define USB_CMD_ITC_16_MICRO_FRM (0x00100000) +#define USB_CMD_ITC_32_MICRO_FRM (0x00200000) +#define USB_CMD_ITC_64_MICRO_FRM (0x00400000) +#define USB_CMD_ITC_BIT_POS (16) + +/* USB STS Register Bit Masks */ +#define USB_STS_INT (0x00000001) +#define USB_STS_ERR (0x00000002) +#define USB_STS_PORT_CHANGE (0x00000004) +#define USB_STS_FRM_LST_ROLL (0x00000008) +#define USB_STS_SYS_ERR (0x00000010) +#define USB_STS_IAA (0x00000020) +#define USB_STS_RESET (0x00000040) +#define USB_STS_SOF (0x00000080) +#define USB_STS_SUSPEND (0x00000100) +#define USB_STS_HC_HALTED (0x00001000) +#define USB_STS_RCL (0x00002000) +#define USB_STS_PERIODIC_SCHEDULE (0x00004000) +#define USB_STS_ASYNC_SCHEDULE (0x00008000) + +/* USB INTR Register Bit Masks */ +#define USB_INTR_INT_EN (0x00000001) +#define USB_INTR_ERR_INT_EN (0x00000002) +#define USB_INTR_PTC_DETECT_EN (0x00000004) +#define USB_INTR_FRM_LST_ROLL_EN (0x00000008) +#define USB_INTR_SYS_ERR_EN (0x00000010) +#define USB_INTR_ASYN_ADV_EN (0x00000020) +#define USB_INTR_RESET_EN (0x00000040) +#define USB_INTR_SOF_EN (0x00000080) +#define USB_INTR_DEVICE_SUSPEND (0x00000100) + +/* Device Address bit masks */ +#define USB_DEVICE_ADDRESS_MASK (0xFE000000) +#define USB_DEVICE_ADDRESS_BIT_POS (25) + +/* endpoint list address bit masks */ +#define USB_EP_LIST_ADDRESS_MASK (0xfffff800) + +/* PORTSCX Register Bit Masks */ +#define PORTSCX_CURRENT_CONNECT_STATUS (0x00000001) +#define PORTSCX_CONNECT_STATUS_CHANGE (0x00000002) +#define PORTSCX_PORT_ENABLE (0x00000004) +#define PORTSCX_PORT_EN_DIS_CHANGE (0x00000008) +#define PORTSCX_OVER_CURRENT_ACT (0x00000010) +#define PORTSCX_OVER_CURRENT_CHG (0x00000020) +#define PORTSCX_PORT_FORCE_RESUME (0x00000040) +#define PORTSCX_PORT_SUSPEND (0x00000080) +#define PORTSCX_PORT_RESET (0x00000100) +#define PORTSCX_LINE_STATUS_BITS (0x00000C00) +#define PORTSCX_PORT_POWER (0x00001000) +#define PORTSCX_PORT_INDICTOR_CTRL (0x0000C000) +#define PORTSCX_PORT_TEST_CTRL (0x000F0000) +#define PORTSCX_WAKE_ON_CONNECT_EN (0x00100000) +#define PORTSCX_WAKE_ON_CONNECT_DIS (0x00200000) +#define PORTSCX_WAKE_ON_OVER_CURRENT (0x00400000) +#define PORTSCX_PHY_LOW_POWER_SPD (0x00800000) +#define PORTSCX_PORT_FORCE_FULL_SPEED (0x01000000) +#define PORTSCX_PORT_SPEED_MASK (0x0C000000) +#define PORTSCX_PORT_WIDTH (0x10000000) +#define PORTSCX_PHY_TYPE_SEL (0xC0000000) + +/* bit 11-10 are line status */ +#define PORTSCX_LINE_STATUS_SE0 (0x00000000) +#define PORTSCX_LINE_STATUS_JSTATE (0x00000400) +#define PORTSCX_LINE_STATUS_KSTATE (0x00000800) +#define PORTSCX_LINE_STATUS_UNDEF (0x00000C00) +#define PORTSCX_LINE_STATUS_BIT_POS (10) + +/* bit 15-14 are port indicator control */ +#define PORTSCX_PIC_OFF (0x00000000) +#define PORTSCX_PIC_AMBER (0x00004000) +#define PORTSCX_PIC_GREEN (0x00008000) +#define PORTSCX_PIC_UNDEF (0x0000C000) +#define PORTSCX_PIC_BIT_POS (14) + +/* bit 19-16 are port test control */ +#define PORTSCX_PTC_DISABLE (0x00000000) +#define PORTSCX_PTC_JSTATE (0x00010000) +#define PORTSCX_PTC_KSTATE (0x00020000) +#define PORTSCX_PTC_SEQNAK (0x00030000) +#define PORTSCX_PTC_PACKET (0x00040000) +#define PORTSCX_PTC_FORCE_EN (0x00050000) +#define PORTSCX_PTC_BIT_POS (16) + +/* bit 27-26 are port speed */ +#define PORTSCX_PORT_SPEED_FULL (0x00000000) +#define PORTSCX_PORT_SPEED_LOW (0x04000000) +#define PORTSCX_PORT_SPEED_HIGH (0x08000000) +#define PORTSCX_PORT_SPEED_UNDEF (0x0C000000) +#define PORTSCX_SPEED_BIT_POS (26) + +/* bit 28 is parallel transceiver width for UTMI interface */ +#define PORTSCX_PTW (0x10000000) +#define PORTSCX_PTW_8BIT (0x00000000) +#define PORTSCX_PTW_16BIT (0x10000000) + +/* bit 31-30 are port transceiver select */ +#define PORTSCX_PTS_UTMI (0x00000000) +#define PORTSCX_PTS_ULPI (0x80000000) +#define PORTSCX_PTS_FSLS (0xC0000000) +#define PORTSCX_PTS_BIT_POS (30) + +/* USB MODE Register Bit Masks */ +#define USB_MODE_CTRL_MODE_IDLE (0x00000000) +#define USB_MODE_CTRL_MODE_DEVICE (0x00000002) +#define USB_MODE_CTRL_MODE_HOST (0x00000003) +#define USB_MODE_CTRL_MODE_MASK 0x00000003 +#define USB_MODE_CTRL_MODE_RSV (0x00000001) +#define USB_MODE_ES 0x00000004 /* (big) Endian Sel */ +#define USB_MODE_SETUP_LOCK_OFF (0x00000008) +#define USB_MODE_STREAM_DISABLE (0x00000010) +/* Endpoint Flush Register */ +#define EPFLUSH_TX_OFFSET (0x00010000) +#define EPFLUSH_RX_OFFSET (0x00000000) + +/* Endpoint Setup Status bit masks */ +#define EP_SETUP_STATUS_MASK (0x0000003F) +#define EP_SETUP_STATUS_EP0 (0x00000001) + +/* ENDPOINTCTRLx Register Bit Masks */ +#define EPCTRL_TX_ENABLE (0x00800000) +#define EPCTRL_TX_DATA_TOGGLE_RST (0x00400000) /* Not EP0 */ +#define EPCTRL_TX_DATA_TOGGLE_INH (0x00200000) /* Not EP0 */ +#define EPCTRL_TX_TYPE (0x000C0000) +#define EPCTRL_TX_DATA_SOURCE (0x00020000) /* Not EP0 */ +#define EPCTRL_TX_EP_STALL (0x00010000) +#define EPCTRL_RX_ENABLE (0x00000080) +#define EPCTRL_RX_DATA_TOGGLE_RST (0x00000040) /* Not EP0 */ +#define EPCTRL_RX_DATA_TOGGLE_INH (0x00000020) /* Not EP0 */ +#define EPCTRL_RX_TYPE (0x0000000C) +#define EPCTRL_RX_DATA_SINK (0x00000002) /* Not EP0 */ +#define EPCTRL_RX_EP_STALL (0x00000001) + +/* bit 19-18 and 3-2 are endpoint type */ +#define EPCTRL_EP_TYPE_CONTROL (0) +#define EPCTRL_EP_TYPE_ISO (1) +#define EPCTRL_EP_TYPE_BULK (2) +#define EPCTRL_EP_TYPE_INTERRUPT (3) +#define EPCTRL_TX_EP_TYPE_SHIFT (18) +#define EPCTRL_RX_EP_TYPE_SHIFT (2) + +/* SNOOPn Register Bit Masks */ +#define SNOOP_ADDRESS_MASK (0xFFFFF000) +#define SNOOP_SIZE_ZERO (0x00) /* snooping disable */ +#define SNOOP_SIZE_4KB (0x0B) /* 4KB snoop size */ +#define SNOOP_SIZE_8KB (0x0C) +#define SNOOP_SIZE_16KB (0x0D) +#define SNOOP_SIZE_32KB (0x0E) +#define SNOOP_SIZE_64KB (0x0F) +#define SNOOP_SIZE_128KB (0x10) +#define SNOOP_SIZE_256KB (0x11) +#define SNOOP_SIZE_512KB (0x12) +#define SNOOP_SIZE_1MB (0x13) +#define SNOOP_SIZE_2MB (0x14) +#define SNOOP_SIZE_4MB (0x15) +#define SNOOP_SIZE_8MB (0x16) +#define SNOOP_SIZE_16MB (0x17) +#define SNOOP_SIZE_32MB (0x18) +#define SNOOP_SIZE_64MB (0x19) +#define SNOOP_SIZE_128MB (0x1A) +#define SNOOP_SIZE_256MB (0x1B) +#define SNOOP_SIZE_512MB (0x1C) +#define SNOOP_SIZE_1GB (0x1D) +#define SNOOP_SIZE_2GB (0x1E) /* 2GB snoop size */ + +/* pri_ctrl Register Bit Masks */ +#define PRI_CTRL_PRI_LVL1 (0x0000000C) +#define PRI_CTRL_PRI_LVL0 (0x00000003) + +/* si_ctrl Register Bit Masks */ +#define SI_CTRL_ERR_DISABLE (0x00000010) +#define SI_CTRL_IDRC_DISABLE (0x00000008) +#define SI_CTRL_RD_SAFE_EN (0x00000004) +#define SI_CTRL_RD_PREFETCH_DISABLE (0x00000002) +#define SI_CTRL_RD_PREFEFETCH_VAL (0x00000001) + +/* control Register Bit Masks */ +#define USB_CTRL_IOENB (0x00000004) +#define USB_CTRL_ULPI_INT0EN (0x00000001) + +/*! + * Endpoint Queue Head data struct + * Rem: all the variables of qh are LittleEndian Mode + * and NEXT_POINTER_MASK should operate on a LittleEndian, Phy Addr + */ +struct ep_queue_head { + /*! + * Mult(31-30) , Zlt(29) , Max Pkt len and IOS(15) + */ + u32 max_pkt_length; + + /*! + * Current dTD Pointer(31-5) + */ + u32 curr_dtd_ptr; + + /*! + * Next dTD Pointer(31-5), T(0) + */ + u32 next_dtd_ptr; + + /*! + * Total bytes (30-16), IOC (15), MultO(11-10), STS (7-0) + */ + u32 size_ioc_int_sts; + + /*! + * Buffer pointer Page 0 (31-12) + */ + u32 buff_ptr0; + + /*! + * Buffer pointer Page 1 (31-12) + */ + u32 buff_ptr1; + + /*! + * Buffer pointer Page 2 (31-12) + */ + u32 buff_ptr2; + + /*! + * Buffer pointer Page 3 (31-12) + */ + u32 buff_ptr3; + + /*! + * Buffer pointer Page 4 (31-12) + */ + u32 buff_ptr4; + + /*! + * reserved field 1 + */ + u32 res1; + /*! + * Setup data 8 bytes + */ + u8 setup_buffer[8]; /* Setup data 8 bytes */ + + /*! + * reserved field 2,pad out to 64 bytes + */ + u32 res2[4]; +}; + +/* Endpoint Queue Head Bit Masks */ +#define EP_QUEUE_HEAD_MULT_POS (30) +#define EP_QUEUE_HEAD_ZLT_SEL (0x20000000) +#define EP_QUEUE_HEAD_MAX_PKT_LEN_POS (16) +#define EP_QUEUE_HEAD_MAX_PKT_LEN(ep_info) (((ep_info)>>16)&0x07ff) +#define EP_QUEUE_HEAD_IOS (0x00008000) +#define EP_QUEUE_HEAD_NEXT_TERMINATE (0x00000001) +#define EP_QUEUE_HEAD_IOC (0x00008000) +#define EP_QUEUE_HEAD_MULTO (0x00000C00) +#define EP_QUEUE_HEAD_STATUS_HALT (0x00000040) +#define EP_QUEUE_HEAD_STATUS_ACTIVE (0x00000080) +#define EP_QUEUE_CURRENT_OFFSET_MASK (0x00000FFF) +#define EP_QUEUE_HEAD_NEXT_POINTER_MASK 0xFFFFFFE0 +#define EP_QUEUE_FRINDEX_MASK (0x000007FF) +#define EP_MAX_LENGTH_TRANSFER (0x4000) + +/*! + * Endpoint Transfer Descriptor data struct + * Rem: all the variables of td are LittleEndian Mode + * must be 32-byte aligned + */ +struct ep_td_struct { + /*! + * Next TD pointer(31-5), T(0) set indicate invalid + */ + u32 next_td_ptr; + + /*! + * Total bytes (30-16), IOC (15),MultO(11-10), STS (7-0) + */ + u32 size_ioc_sts; + + /*! + * Buffer pointer Page 0 + */ + u32 buff_ptr0; + + /*! + * Buffer pointer Page 1 + */ + u32 buff_ptr1; + + /*! + * Buffer pointer Page 2 + */ + u32 buff_ptr2; + + /*! + * Buffer pointer Page 3 + */ + u32 buff_ptr3; + + /*! + * Buffer pointer Page 4 + */ + u32 buff_ptr4; + + /*! + * dma address of this td + * */ + dma_addr_t td_dma; + + /*! + * virtual address of next td + * */ + struct ep_td_struct *next_td_virt; + + /*! + * make it an even 16 words + * */ + u32 res[7]; +}; + +/*! + * Endpoint Transfer Descriptor bit Masks + */ +#define DTD_NEXT_TERMINATE (0x00000001) +#define DTD_IOC (0x00008000) +#define DTD_STATUS_ACTIVE (0x00000080) +#define DTD_STATUS_HALTED (0x00000040) +#define DTD_STATUS_DATA_BUFF_ERR (0x00000020) +#define DTD_STATUS_TRANSACTION_ERR (0x00000008) +#define DTD_RESERVED_FIELDS (0x80007300) +#define DTD_ADDR_MASK 0xFFFFFFE0 +#define DTD_PACKET_SIZE (0x7FFF0000) +#define DTD_LENGTH_BIT_POS (16) +#define DTD_ERROR_MASK (DTD_STATUS_HALTED | \ + DTD_STATUS_DATA_BUFF_ERR | \ + DTD_STATUS_TRANSACTION_ERR) +/* Alignment requirements; must be a power of two */ +#define DTD_ALIGNMENT 0x20 +#define QH_ALIGNMENT 2048 + +/* Controller dma boundary */ +#define UDC_DMA_BOUNDARY 0x1000 + +/* -----------------------------------------------------------------------*/ +/* ##### enum data +*/ +typedef enum { + e_ULPI, + e_UTMI_8BIT, + e_UTMI_16BIT, + e_SERIAL +} e_PhyInterface; + +/*-------------------------------------------------------------------------*/ + +struct fsl_req { + struct usb_request req; + struct list_head queue; + /* ep_queue() func will add + a request->queue into a udc_ep->queue 'd tail */ + struct fsl_ep *ep; + unsigned mapped; + + struct ep_td_struct *head, *tail; /* For dTD List + this is a BigEndian Virtual addr */ + unsigned int dtd_count; + /* just for IRAM patch */ + dma_addr_t oridma; /* original dma */ + size_t buffer_offset; /* offset of user buffer */ + int last_one; /* mark if reach to last packet */ + struct ep_td_struct *cur; /* current tranfer dtd */ +}; + +#define REQ_UNCOMPLETE (1) + +struct fsl_ep { + struct usb_ep ep; + struct list_head queue; + struct fsl_udc *udc; + struct ep_queue_head *qh; + const struct usb_endpoint_descriptor *desc; + struct usb_gadget *gadget; + + char name[14]; + unsigned stopped:1; +}; + +#define EP_DIR_IN 1 +#define EP_DIR_OUT 0 + +struct fsl_udc { + struct usb_gadget gadget; + struct usb_gadget_driver *driver; + struct fsl_usb2_platform_data *pdata; + struct fsl_ep *eps; + unsigned int max_ep; + unsigned int irq; + + struct usb_ctrlrequest local_setup_buff; + spinlock_t lock; + u32 xcvr_type; + struct otg_transceiver *transceiver; + unsigned softconnect:1; + unsigned vbus_active:1; + unsigned stopped:1; + unsigned remote_wakeup:1; + unsigned already_stopped:1; + + struct ep_queue_head *ep_qh; /* Endpoints Queue-Head */ + struct fsl_req *status_req; /* ep0 status request */ + struct fsl_req *data_req; /* ep0 data request */ + struct dma_pool *td_pool; /* dma pool for DTD */ + enum fsl_usb2_phy_modes phy_mode; + + size_t ep_qh_size; /* size after alignment adjustment*/ + dma_addr_t ep_qh_dma; /* dma address of QH */ + + u32 max_pipes; /* Device max pipes */ + u32 max_use_endpts; /* Max endpointes to be used */ + u32 bus_reset; /* Device is bus reseting */ + u32 resume_state; /* USB state to resume */ + u32 usb_state; /* USB current state */ + u32 usb_next_state; /* USB next state */ + u32 ep0_dir; /* Endpoint zero direction: can be + USB_DIR_IN or USB_DIR_OUT */ + u32 usb_sof_count; /* SOF count */ + u32 errors; /* USB ERRORs count */ + u8 device_address; /* Device USB address */ + + struct completion *done; /* to make sure release() is done */ + u32 iram_buffer[IRAM_PPH_NTD]; + u32 iram_buffer_v[IRAM_PPH_NTD]; +}; + +/*-------------------------------------------------------------------------*/ + +#ifdef DEBUG +#define DBG(fmt, args...) printk(KERN_DEBUG "[%s] " fmt "\n", \ + __func__, ## args) +#else +#define DBG(fmt, args...) do {} while (0) +#endif + +#if 0 +static void dump_msg(const char *label, const u8 * buf, unsigned int length) +{ + unsigned int start, num, i; + char line[52], *p; + + if (length >= 512) + return; + pr_debug("udc: %s, length %u:\n", label, length); + start = 0; + while (length > 0) { + num = min(length, 16u); + p = line; + for (i = 0; i < num; ++i) { + if (i == 8) + *p++ = ' '; + sprintf(p, " %02x", buf[i]); + p += 3; + } + *p = 0; + printk(KERN_DEBUG "%6x: %s\n", start, line); + buf += num; + start += num; + length -= num; + } +} +#endif + +#ifdef VERBOSE +#define VDBG DBG +#else +#define VDBG(stuff...) do {} while (0) +#endif + +#define ERR(stuff...) printk(KERN_ERR "udc: " stuff) +#define WARN(stuff...) printk(KERN_WARNING "udc: " stuff) +#define INFO(stuff...) printk(KERN_INFO "udc: " stuff) + +/*-------------------------------------------------------------------------*/ + +/* ### Add board specific defines here + */ + +/* + * ### pipe direction macro from device view + */ +#define USB_RECV (0) /* OUT EP */ +#define USB_SEND (1) /* IN EP */ + +/* + * ### internal used help routines. + */ +#define ep_index(EP) ((EP)->desc->bEndpointAddress&0xF) +#define ep_maxpacket(EP) ((EP)->ep.maxpacket) + +#define ep_is_in(EP) ( (ep_index(EP) == 0) ? (EP->udc->ep0_dir == \ + USB_DIR_IN ):((EP)->desc->bEndpointAddress \ + & USB_DIR_IN)==USB_DIR_IN) + +#define get_ep_by_pipe(udc, pipe) ((pipe == 1)? &udc->eps[0]: \ + &udc->eps[pipe]) +#define get_pipe_by_windex(windex) ((windex & USB_ENDPOINT_NUMBER_MASK) \ + * 2 + ((windex & USB_DIR_IN) ? 1 : 0)) + +/* Bulk only class request */ +#define USB_BULK_RESET_REQUEST 0xff + +#ifdef CONFIG_ARCH_MXC +#include +#elif CONFIG_PPC32 +#include +#endif + +#endif /* __ARCOTG_UDC_H */ --- linux-2.6.28.orig/drivers/usb/class/cdc-acm.c +++ linux-2.6.28/drivers/usb/class/cdc-acm.c @@ -1370,6 +1370,11 @@ { USB_DEVICE(0x0572, 0x1321), /* Conexant USB MODEM CX93010 */ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ }, + { USB_DEVICE(0x0572, 0x1324), /* Conexant USB MODEM RD02-D400 */ + .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ + }, + { USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */ + }, /* control interfaces with various AT-command sets */ { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, @@ -1478,4 +1483,4 @@ MODULE_AUTHOR( DRIVER_AUTHOR ); MODULE_DESCRIPTION( DRIVER_DESC ); MODULE_LICENSE("GPL"); - +MODULE_ALIAS_CHARDEV_MAJOR(ACM_TTY_MAJOR); --- linux-2.6.28.orig/drivers/usb/class/usbtmc.c +++ linux-2.6.28/drivers/usb/class/usbtmc.c @@ -49,6 +49,7 @@ static struct usb_device_id usbtmc_devices[] = { { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 0), }, + { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 1), }, { 0, } /* terminating entry */ }; MODULE_DEVICE_TABLE(usb, usbtmc_devices); @@ -105,12 +106,13 @@ { struct usb_interface *intf; struct usbtmc_device_data *data; - int retval = -ENODEV; + int retval = 0; intf = usb_find_interface(&usbtmc_driver, iminor(inode)); if (!intf) { printk(KERN_ERR KBUILD_MODNAME ": can not find device for minor %d", iminor(inode)); + retval = -ENODEV; goto exit; } --- linux-2.6.28.orig/drivers/usb/core/devio.c +++ linux-2.6.28/drivers/usb/core/devio.c @@ -359,11 +359,6 @@ spin_lock_irqsave(&ps->lock, flags); } spin_unlock_irqrestore(&ps->lock, flags); - as = async_getcompleted(ps); - while (as) { - free_async(as); - as = async_getcompleted(ps); - } } static void destroy_async_on_interface(struct dev_state *ps, @@ -642,6 +637,7 @@ struct dev_state *ps = file->private_data; struct usb_device *dev = ps->dev; unsigned int ifnum; + struct async *as; usb_lock_device(dev); @@ -660,6 +656,12 @@ usb_unlock_device(dev); usb_put_dev(dev); put_pid(ps->disc_pid); + + as = async_getcompleted(ps); + while (as) { + free_async(as); + as = async_getcompleted(ps); + } kfree(ps); return 0; } @@ -1703,7 +1705,7 @@ .release = usbdev_release, }; -void usb_fs_classdev_common_remove(struct usb_device *udev) +static void usbdev_remove(struct usb_device *udev) { struct dev_state *ps; struct siginfo sinfo; @@ -1745,10 +1747,15 @@ { if (dev->usb_classdev) device_unregister(dev->usb_classdev); - usb_fs_classdev_common_remove(dev); } -static int usb_classdev_notify(struct notifier_block *self, +#else +#define usb_classdev_add(dev) 0 +#define usb_classdev_remove(dev) do {} while (0) + +#endif + +static int usbdev_notify(struct notifier_block *self, unsigned long action, void *dev) { switch (action) { @@ -1758,15 +1765,15 @@ break; case USB_DEVICE_REMOVE: usb_classdev_remove(dev); + usbdev_remove(dev); break; } return NOTIFY_OK; } static struct notifier_block usbdev_nb = { - .notifier_call = usb_classdev_notify, + .notifier_call = usbdev_notify, }; -#endif static struct cdev usb_device_cdev; @@ -1801,9 +1808,8 @@ * to /sys/dev */ usb_classdev_class->dev_kobj = NULL; - - usb_register_notify(&usbdev_nb); #endif + usb_register_notify(&usbdev_nb); out: return retval; @@ -1814,8 +1820,8 @@ void usb_devio_cleanup(void) { -#ifdef CONFIG_USB_DEVICE_CLASS usb_unregister_notify(&usbdev_nb); +#ifdef CONFIG_USB_DEVICE_CLASS class_destroy(usb_classdev_class); #endif cdev_del(&usb_device_cdev); --- linux-2.6.28.orig/drivers/usb/core/usb.c +++ linux-2.6.28/drivers/usb/core/usb.c @@ -362,7 +362,7 @@ dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE; dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT; /* ep0 maxpacket comes later, from device descriptor */ - usb_enable_endpoint(dev, &dev->ep0); + usb_enable_endpoint(dev, &dev->ep0, true); dev->can_submit = 1; /* Save readable and stable topology id, distinguishing devices --- linux-2.6.28.orig/drivers/usb/core/quirks.c +++ linux-2.6.28/drivers/usb/core/quirks.c @@ -70,6 +70,10 @@ /* INTEL VALUE SSD */ { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, +#ifdef CONFIG_X86_LPIA + /* ASIX Ethernet Device */ + { USB_DEVICE(0x0b95, 0x1720), .driver_info = USB_QUIRK_RESET_RESUME }, +#endif { } /* terminating entry must be last */ }; --- linux-2.6.28.orig/drivers/usb/core/driver.c +++ linux-2.6.28/drivers/usb/core/driver.c @@ -269,7 +269,7 @@ * supports "soft" unbinding. */ if (!driver->soft_unbind) - usb_disable_interface(udev, intf); + usb_disable_interface(udev, intf, false); driver->disconnect(intf); @@ -279,9 +279,12 @@ * altsetting means creating new endpoint device entries). * When either of these happens, defer the Set-Interface. */ - if (intf->cur_altsetting->desc.bAlternateSetting == 0) - ; /* Already in altsetting 0 so skip Set-Interface */ - else if (!error && intf->dev.power.status == DPM_ON) + if (intf->cur_altsetting->desc.bAlternateSetting == 0) { + /* Already in altsetting 0 so skip Set-Interface. + * Just re-enable it without affecting the endpoint toggles. + */ + usb_enable_interface(udev, intf, false); + } else if (!error && intf->dev.power.status == DPM_ON) usb_set_interface(udev, intf->altsetting[0]. desc.bInterfaceNumber, 0); else @@ -966,6 +969,11 @@ return status; } +#ifdef CONFIG_X86_LPIA +struct usb_hub; +void hub_port_logical_disconnect(struct usb_hub *hub, int port1); +#endif + /* Caller has locked intf's usb_device's pm_mutex */ static int usb_resume_interface(struct usb_device *udev, struct usb_interface *intf, int reset_resume) @@ -1005,9 +1013,19 @@ dev_err(&intf->dev, "%s error %d\n", "reset_resume", status); } else { +#ifdef CONFIG_X86_LPIA + struct usb_device *udev = interface_to_usbdev(intf); + struct usb_device *pdev = udev->parent; +#endif intf->needs_binding = 1; dev_warn(&intf->dev, "no %s for driver %s?\n", "reset_resume", driver->name); +#ifdef CONFIG_X86_LPIA + if (pdev) { + struct usb_hub *phub = usb_get_intfdata(pdev->actconfig->interface[0]); + hub_port_logical_disconnect(phub, udev->portnum); + } +#endif } } else { if (driver->resume) { --- linux-2.6.28.orig/drivers/usb/core/inode.c +++ linux-2.6.28/drivers/usb/core/inode.c @@ -718,7 +718,6 @@ fs_remove_file (dev->usbfs_dentry); dev->usbfs_dentry = NULL; } - usb_fs_classdev_common_remove(dev); } static int usbfs_notify(struct notifier_block *self, unsigned long action, void *dev) --- linux-2.6.28.orig/drivers/usb/core/hub.c +++ linux-2.6.28/drivers/usb/core/hub.c @@ -597,7 +597,7 @@ * time later khubd will disconnect() any existing usb_device on the port * and will re-enumerate if there actually is a device attached. */ -static void hub_port_logical_disconnect(struct usb_hub *hub, int port1) +void hub_port_logical_disconnect(struct usb_hub *hub, int port1) { dev_dbg(hub->intfdev, "logical disconnect on port %d\n", port1); hub_port_disable(hub, port1, 1); @@ -614,6 +614,7 @@ set_bit(port1, hub->change_bits); kick_khubd(hub); } +EXPORT_SYMBOL(hub_port_logical_disconnect); enum hub_activation_type { HUB_INIT, HUB_INIT2, HUB_INIT3, @@ -1141,6 +1142,16 @@ return -E2BIG; } +#ifdef CONFIG_ARCH_MXC_CANONICAL + /* With OTG enabled, suspending root hub results in gadget not + * working because gadget uses the same root hub. We disable + * this feature when OTG is selected. + */ +#if defined(CONFIG_PM) && defined(CONFIG_USB_EHCI_ARC_OTG) + hdev->autosuspend_disabled = 1; +#endif +#endif + #ifdef CONFIG_USB_OTG_BLACKLIST_HUB if (hdev->parent) { dev_warn(&intf->dev, "ignoring external hub\n"); @@ -2383,9 +2394,9 @@ void usb_ep0_reinit(struct usb_device *udev) { - usb_disable_endpoint(udev, 0 + USB_DIR_IN); - usb_disable_endpoint(udev, 0 + USB_DIR_OUT); - usb_enable_endpoint(udev, &udev->ep0); + usb_disable_endpoint(udev, 0 + USB_DIR_IN, true); + usb_disable_endpoint(udev, 0 + USB_DIR_OUT, true); + usb_enable_endpoint(udev, &udev->ep0, true); } EXPORT_SYMBOL_GPL(usb_ep0_reinit); --- linux-2.6.28.orig/drivers/usb/core/usb.h +++ linux-2.6.28/drivers/usb/core/usb.h @@ -10,10 +10,13 @@ extern void usb_remove_ep_files(struct usb_host_endpoint *endpoint); extern void usb_enable_endpoint(struct usb_device *dev, - struct usb_host_endpoint *ep); -extern void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr); + struct usb_host_endpoint *ep, bool reset_toggle); +extern void usb_enable_interface(struct usb_device *dev, + struct usb_interface *intf, bool reset_toggles); +extern void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr, + bool reset_hardware); extern void usb_disable_interface(struct usb_device *dev, - struct usb_interface *intf); + struct usb_interface *intf, bool reset_hardware); extern void usb_release_interface_cache(struct kref *ref); extern void usb_disable_device(struct usb_device *dev, int skip_ep0); extern int usb_deauthorize_device(struct usb_device *); @@ -145,7 +148,6 @@ extern const struct file_operations usbfs_devices_fops; extern const struct file_operations usbdev_file_operations; extern void usbfs_conn_disc_event(void); -extern void usb_fs_classdev_common_remove(struct usb_device *udev); extern int usb_devio_init(void); extern void usb_devio_cleanup(void); --- linux-2.6.28.orig/drivers/usb/core/message.c +++ linux-2.6.28/drivers/usb/core/message.c @@ -651,7 +651,7 @@ if (result <= 0 && result != -ETIMEDOUT) continue; if (result > 1 && ((u8 *)buf)[1] != type) { - result = -EPROTO; + result = -ENODATA; continue; } break; @@ -694,8 +694,13 @@ USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, (USB_DT_STRING << 8) + index, langid, buf, size, USB_CTRL_GET_TIMEOUT); - if (!(result == 0 || result == -EPIPE)) - break; + if (result == 0 || result == -EPIPE) + continue; + if (result > 1 && ((u8 *) buf)[1] != USB_DT_STRING) { + result = -ENODATA; + continue; + } + break; } return result; } @@ -1009,14 +1014,15 @@ * @dev: the device whose endpoint is being disabled * @epaddr: the endpoint's address. Endpoint number for output, * endpoint number + USB_DIR_IN for input + * @reset_hardware: flag to erase any endpoint state stored in the + * controller hardware * - * Deallocates hcd/hardware state for this endpoint ... and nukes all - * pending urbs. - * - * If the HCD hasn't registered a disable() function, this sets the - * endpoint's maxpacket size to 0 to prevent further submissions. + * Disables the endpoint for URB submission and nukes all pending URBs. + * If @reset_hardware is set then also deallocates hcd/hardware state + * for the endpoint. */ -void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr) +void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr, + bool reset_hardware) { unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK; struct usb_host_endpoint *ep; @@ -1026,15 +1032,18 @@ if (usb_endpoint_out(epaddr)) { ep = dev->ep_out[epnum]; - dev->ep_out[epnum] = NULL; + if (reset_hardware) + dev->ep_out[epnum] = NULL; } else { ep = dev->ep_in[epnum]; - dev->ep_in[epnum] = NULL; + if (reset_hardware) + dev->ep_in[epnum] = NULL; } if (ep) { ep->enabled = 0; usb_hcd_flush_endpoint(dev, ep); - usb_hcd_disable_endpoint(dev, ep); + if (reset_hardware) + usb_hcd_disable_endpoint(dev, ep); } } @@ -1042,17 +1051,21 @@ * usb_disable_interface -- Disable all endpoints for an interface * @dev: the device whose interface is being disabled * @intf: pointer to the interface descriptor + * @reset_hardware: flag to erase any endpoint state stored in the + * controller hardware * * Disables all the endpoints for the interface's current altsetting. */ -void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf) +void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf, + bool reset_hardware) { struct usb_host_interface *alt = intf->cur_altsetting; int i; for (i = 0; i < alt->desc.bNumEndpoints; ++i) { usb_disable_endpoint(dev, - alt->endpoint[i].desc.bEndpointAddress); + alt->endpoint[i].desc.bEndpointAddress, + reset_hardware); } } @@ -1073,8 +1086,8 @@ dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__, skip_ep0 ? "non-ep0" : "all"); for (i = skip_ep0; i < 16; ++i) { - usb_disable_endpoint(dev, i); - usb_disable_endpoint(dev, i + USB_DIR_IN); + usb_disable_endpoint(dev, i, true); + usb_disable_endpoint(dev, i + USB_DIR_IN, true); } dev->toggle[0] = dev->toggle[1] = 0; @@ -1113,22 +1126,26 @@ * usb_enable_endpoint - Enable an endpoint for USB communications * @dev: the device whose interface is being enabled * @ep: the endpoint + * @reset_toggle: flag to set the endpoint's toggle back to 0 * - * Resets the endpoint toggle, and sets dev->ep_{in,out} pointers. + * Resets the endpoint toggle if asked, and sets dev->ep_{in,out} pointers. * For control endpoints, both the input and output sides are handled. */ -void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep) +void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep, + bool reset_toggle) { int epnum = usb_endpoint_num(&ep->desc); int is_out = usb_endpoint_dir_out(&ep->desc); int is_control = usb_endpoint_xfer_control(&ep->desc); if (is_out || is_control) { - usb_settoggle(dev, epnum, 1, 0); + if (reset_toggle) + usb_settoggle(dev, epnum, 1, 0); dev->ep_out[epnum] = ep; } if (!is_out || is_control) { - usb_settoggle(dev, epnum, 0, 0); + if (reset_toggle) + usb_settoggle(dev, epnum, 0, 0); dev->ep_in[epnum] = ep; } ep->enabled = 1; @@ -1138,17 +1155,18 @@ * usb_enable_interface - Enable all the endpoints for an interface * @dev: the device whose interface is being enabled * @intf: pointer to the interface descriptor + * @reset_toggles: flag to set the endpoints' toggles back to 0 * * Enables all the endpoints for the interface's current altsetting. */ -static void usb_enable_interface(struct usb_device *dev, - struct usb_interface *intf) +void usb_enable_interface(struct usb_device *dev, + struct usb_interface *intf, bool reset_toggles) { struct usb_host_interface *alt = intf->cur_altsetting; int i; for (i = 0; i < alt->desc.bNumEndpoints; ++i) - usb_enable_endpoint(dev, &alt->endpoint[i]); + usb_enable_endpoint(dev, &alt->endpoint[i], reset_toggles); } /** @@ -1237,7 +1255,7 @@ /* prevent submissions using previous endpoint settings */ if (iface->cur_altsetting != alt) usb_remove_sysfs_intf_files(iface); - usb_disable_interface(dev, iface); + usb_disable_interface(dev, iface, true); iface->cur_altsetting = alt; @@ -1271,7 +1289,7 @@ * during the SETUP stage - hence EP0 toggles are "don't care" here. * (Likewise, EP0 never "halts" on well designed devices.) */ - usb_enable_interface(dev, iface); + usb_enable_interface(dev, iface, true); if (device_is_registered(&iface->dev)) usb_create_sysfs_intf_files(iface); @@ -1315,8 +1333,8 @@ */ for (i = 1; i < 16; ++i) { - usb_disable_endpoint(dev, i); - usb_disable_endpoint(dev, i + USB_DIR_IN); + usb_disable_endpoint(dev, i, true); + usb_disable_endpoint(dev, i + USB_DIR_IN, true); } config = dev->actconfig; @@ -1346,7 +1364,7 @@ alt = &intf->altsetting[0]; intf->cur_altsetting = alt; - usb_enable_interface(dev, intf); + usb_enable_interface(dev, intf, true); if (device_is_registered(&intf->dev)) usb_create_sysfs_intf_files(intf); } @@ -1604,7 +1622,7 @@ alt = &intf->altsetting[0]; intf->cur_altsetting = alt; - usb_enable_interface(dev, intf); + usb_enable_interface(dev, intf, true); intf->dev.parent = &dev->dev; intf->dev.driver = NULL; intf->dev.bus = &usb_bus_type; --- linux-2.6.28.orig/drivers/usb/storage/usb.c +++ linux-2.6.28/drivers/usb/storage/usb.c @@ -103,6 +103,7 @@ #include "cypress_atacb.h" #endif #include "sierra_ms.h" +#include "option_ms.h" /* Some informational data */ MODULE_AUTHOR("Matthew Dharm "); @@ -126,6 +127,8 @@ { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } +#define COMPLIANT_DEV UNUSUAL_DEV + #define USUAL_DEV(useProto, useTrans, useType) \ { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \ .driver_info = (USB_US_TYPE_STOR<<24) } @@ -134,6 +137,7 @@ # include "unusual_devs.h" #undef UNUSUAL_DEV +#undef COMPLIANT_DEV #undef USUAL_DEV /* Terminating entry */ { } @@ -164,6 +168,8 @@ .initFunction = init_function, \ } +#define COMPLIANT_DEV UNUSUAL_DEV + #define USUAL_DEV(use_protocol, use_transport, use_type) \ { \ .useProtocol = use_protocol, \ @@ -173,6 +179,7 @@ static struct us_unusual_dev us_unusual_dev_list[] = { # include "unusual_devs.h" # undef UNUSUAL_DEV +# undef COMPLIANT_DEV # undef USUAL_DEV /* Terminating entry */ --- linux-2.6.28.orig/drivers/usb/storage/unusual_devs.h +++ linux-2.6.28/drivers/usb/storage/unusual_devs.h @@ -27,7 +27,8 @@ /* IMPORTANT NOTE: This file must be included in another file which does * the following thing for it to work: - * The macro UNUSUAL_DEV() must be defined before this file is included + * The UNUSUAL_DEV, COMPLIANT_DEV, and USUAL_DEV macros must be defined + * before this file is included. */ /* If you edit this file, please try to keep it sorted first by VendorID, @@ -46,6 +47,12 @@ * */ +/* Note: If you add an entry only in order to set the CAPACITY_OK flag, + * use the COMPLIANT_DEV macro instead of UNUSUAL_DEV. This is + * because such entries mark devices which actually work correctly, + * as opposed to devices that do something strangely or wrongly. + */ + /* patch submitted by Vivian Bregier */ UNUSUAL_DEV( 0x03eb, 0x2002, 0x0100, 0x0100, @@ -160,34 +167,6 @@ US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_MAX_SECTORS_64 ), -/* Reported by Filip Joelsson */ -UNUSUAL_DEV( 0x0421, 0x005d, 0x0001, 0x0600, - "Nokia", - "Nokia 3110c", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY ), - -/* Reported by Ozan Sener */ -UNUSUAL_DEV( 0x0421, 0x0060, 0x0551, 0x0551, - "Nokia", - "3500c", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY ), - -/* Reported by CSECSY Laszlo */ -UNUSUAL_DEV( 0x0421, 0x0063, 0x0001, 0x0601, - "Nokia", - "Nokia 3109c", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY ), - -/* Patch for Nokia 5310 capacity */ -UNUSUAL_DEV( 0x0421, 0x006a, 0x0000, 0x0701, - "Nokia", - "5310", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY ), - /* Reported by Mario Rettig */ UNUSUAL_DEV( 0x0421, 0x042e, 0x0100, 0x0100, "Nokia", @@ -240,7 +219,7 @@ US_FL_MAX_SECTORS_64 ), /* Reported by Manuel Osdoba */ -UNUSUAL_DEV( 0x0421, 0x0492, 0x0452, 0x0452, +UNUSUAL_DEV( 0x0421, 0x0492, 0x0452, 0x9999, "Nokia", "Nokia 6233", US_SC_DEVICE, US_PR_DEVICE, NULL, @@ -253,35 +232,6 @@ US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_MAX_SECTORS_64 ), -/* Reported by Cedric Godin */ -UNUSUAL_DEV( 0x0421, 0x04b9, 0x0500, 0x0551, - "Nokia", - "5300", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY ), - -/* Reported by Richard Nauber */ -UNUSUAL_DEV( 0x0421, 0x04fa, 0x0550, 0x0660, - "Nokia", - "6300", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY ), - -/* Patch for Nokia 5310 capacity */ -UNUSUAL_DEV( 0x0421, 0x006a, 0x0000, 0x0591, - "Nokia", - "5310", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY ), - -/* Submitted by Ricky Wong Yung Fei */ -/* Nokia 7610 Supernova - Too many sectors reported in usb storage mode */ -UNUSUAL_DEV( 0x0421, 0x00f5, 0x0000, 0x0470, - "Nokia", - "7610 Supernova", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY ), - /* Reported by Olaf Hering from novell bug #105878 */ UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210, "SMSC", @@ -396,83 +346,6 @@ US_SC_DEVICE, US_PR_DEVICE,NULL, US_FL_NOT_LOCKABLE ), -/* Reported by Stefan de Konink */ -UNUSUAL_DEV( 0x04b0, 0x0401, 0x0200, 0x0200, - "NIKON", - "NIKON DSC D100", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY), - -/* Reported by Tobias Kunze Briseno */ -UNUSUAL_DEV( 0x04b0, 0x0403, 0x0200, 0x0200, - "NIKON", - "NIKON DSC D2H", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY), - -/* Reported by Milinevsky Dmitry */ -UNUSUAL_DEV( 0x04b0, 0x0409, 0x0100, 0x0100, - "NIKON", - "NIKON DSC D50", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY), - -/* Reported by Andreas Bockhold */ -UNUSUAL_DEV( 0x04b0, 0x0405, 0x0100, 0x0100, - "NIKON", - "NIKON DSC D70", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY), - -/* Reported by Jamie Kitson */ -UNUSUAL_DEV( 0x04b0, 0x040d, 0x0100, 0x0100, - "NIKON", - "NIKON DSC D70s", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY), - -/* Reported by Graber and Mike Pagano */ -UNUSUAL_DEV( 0x04b0, 0x040f, 0x0100, 0x0200, - "NIKON", - "NIKON DSC D200", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY), - -/* Reported by Emil Larsson */ -UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0111, - "NIKON", - "NIKON DSC D80", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY), - -/* Reported by Ortwin Glueck */ -UNUSUAL_DEV( 0x04b0, 0x0413, 0x0110, 0x0111, - "NIKON", - "NIKON DSC D40", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY), - -/* Reported by Paul Check */ -UNUSUAL_DEV( 0x04b0, 0x0415, 0x0100, 0x0100, - "NIKON", - "NIKON DSC D2Xs", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY), - -/* Reported by Shan Destromp (shansan@gmail.com) */ -UNUSUAL_DEV( 0x04b0, 0x0417, 0x0100, 0x0100, - "NIKON", - "NIKON DSC D40X", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY), - -/* Reported by paul ready */ -UNUSUAL_DEV( 0x04b0, 0x0419, 0x0100, 0x0200, - "NIKON", - "NIKON DSC D300", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY), - /* Reported by Doug Maxey (dwm@austin.ibm.com) */ UNUSUAL_DEV( 0x04b3, 0x4001, 0x0110, 0x0110, "IBM", @@ -685,6 +558,13 @@ US_SC_8070, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY ), +/* Added by Alan Stern */ +COMPLIANT_DEV(0x0525, 0xa4a5, 0x0000, 0x9999, + "Linux", + "File-backed Storage Gadget", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_CAPACITY_OK ), + /* Yakumo Mega Image 37 * Submitted by Stephan Fuhrmann */ UNUSUAL_DEV( 0x052b, 0x1801, 0x0100, 0x0100, @@ -966,6 +846,18 @@ US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY ), +/* Reported by Dan Williams + * Option N.V. mobile broadband modems + * Ignore driver CD mode and force into modem mode by default. + */ + +/* Globetrotter HSDPA; mass storage shows up as Qualcomm for vendor */ +UNUSUAL_DEV( 0x05c6, 0x1000, 0x0000, 0x9999, + "Option N.V.", + "Mass Storage", + US_SC_DEVICE, US_PR_DEVICE, option_ms_init, + 0), + #ifdef CONFIG_USB_STORAGE_JUMPSHOT UNUSUAL_DEV( 0x05dc, 0x0001, 0x0000, 0x0001, "Lexar", @@ -996,13 +888,13 @@ "Genesys Logic", "USB to IDE Optical", US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ), + US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 | US_FL_IGNORE_RESIDUE ), UNUSUAL_DEV( 0x05e3, 0x0702, 0x0000, 0xffff, "Genesys Logic", "USB to IDE Disk", US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ), + US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 | US_FL_IGNORE_RESIDUE ), /* Reported by Hanno Boeck * Taken from the Lycoris Kernel */ @@ -1033,14 +925,16 @@ US_FL_FIX_CAPACITY ), /* Reported by Richard -=[]=- */ -UNUSUAL_DEV( 0x067b, 0x2507, 0x0100, 0x0100, +/* Change to bcdDeviceMin (0x0100 to 0x0001) reported by + * Thomas Bartosik */ +UNUSUAL_DEV( 0x067b, 0x2507, 0x0001, 0x0100, "Prolific Technology Inc.", "Mass Storage Device", US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY | US_FL_GO_SLOW ), /* Reported by Alex Butcher */ -UNUSUAL_DEV( 0x067b, 0x3507, 0x0001, 0x0001, +UNUSUAL_DEV( 0x067b, 0x3507, 0x0001, 0x0101, "Prolific Technology Inc.", "ATAPI-6 Bridge Controller", US_SC_DEVICE, US_PR_DEVICE, NULL, @@ -1320,6 +1214,13 @@ US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY), +/* Reported and patched by Nguyen Anh Quynh */ +UNUSUAL_DEV( 0x0840, 0x0084, 0x0001, 0x0001, + "Argosy", + "Storage", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY), + /* Entry and supporting patch by Theodore Kilgore . * Flag will support Bulk devices which use a standards-violating 32-byte * Command Block Wrapper. Here, the "DC2MEGA" cameras (several brands) with @@ -1417,14 +1318,6 @@ US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY ), - -/* Submitted by Per Winkvist */ -UNUSUAL_DEV( 0x0a17, 0x006, 0x0000, 0xffff, - "Pentax", - "Optio S/S4", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_INQUIRY ), - /* These are virtual windows driver CDs, which the zd1211rw driver * automatically converts into WLAN devices. */ UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101, @@ -1439,6 +1332,25 @@ US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_DEVICE ), +/* Reported by Dan Williams + * Option N.V. mobile broadband modems + * Ignore driver CD mode and force into modem mode by default. + */ + +/* iCON 225 */ +UNUSUAL_DEV( 0x0af0, 0x6971, 0x0000, 0x9999, + "Option N.V.", + "Mass Storage", + US_SC_DEVICE, US_PR_DEVICE, option_ms_init, + 0), + +/* Reported by Timo Aaltonen */ +UNUSUAL_DEV( 0x0af0, 0x7011, 0x0000, 0x9999, + "Option", + "Mass Storage", + US_SC_DEVICE, US_PR_DEVICE, option_ms_init, + 0 ), + /* Reported by F. Aben * This device (wrongly) has a vendor-specific device descriptor. * The entry is needed so usb-storage can bind to it's mass-storage @@ -1449,6 +1361,16 @@ US_SC_DEVICE, US_PR_DEVICE, NULL, 0 ), +/* Reported by Jan Dumon + * This device (wrongly) has a vendor-specific device descriptor. + * The entry is needed so usb-storage can bind to it's mass-storage + * interface as an interface driver */ +UNUSUAL_DEV( 0x0af0, 0x7501, 0x0000, 0x0000, + "Option", + "GI 0431 SD-Card", + US_SC_DEVICE, US_PR_DEVICE, NULL, + 0 ), + #ifdef CONFIG_USB_STORAGE_ISD200 UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110, "ATI", @@ -2076,6 +1998,12 @@ US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_DEVICE), +UNUSUAL_DEV( 0x2116, 0x0320, 0x0001, 0x0001, + "ST", + "2A", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY), + /* patch submitted by Davide Perini * and Renato Perini */ @@ -2086,27 +2014,6 @@ US_FL_FIX_CAPACITY | US_FL_IGNORE_RESIDUE ), /* - * Patch by Pete Zaitcev - * Report by Mark Patton. Red Hat bz#208928. - * Added support for rev 0x0002 (Motorola ROKR W5) - * by Javier Smaldone - */ -UNUSUAL_DEV( 0x22b8, 0x4810, 0x0001, 0x0002, - "Motorola", - "RAZR V3i/ROKR W5", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY), - -/* - * Patch by Jost Diederichs - */ -UNUSUAL_DEV(0x22b8, 0x6410, 0x0001, 0x9999, - "Motorola Inc.", - "Motorola Phone (RAZRV3xx)", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_FIX_CAPACITY), - -/* * Patch by Constantin Baranov * Report by Andreas Koenecke. * Motorola ROKR Z6. --- linux-2.6.28.orig/drivers/usb/storage/option_ms.h +++ linux-2.6.28/drivers/usb/storage/option_ms.h @@ -0,0 +1,4 @@ +#ifndef _OPTION_MS_H_ +#define _OPTION_MS_H_ +extern int option_ms_init(struct us_data *us); +#endif --- linux-2.6.28.orig/drivers/usb/storage/transport.c +++ linux-2.6.28/drivers/usb/storage/transport.c @@ -57,6 +57,9 @@ #include "scsiglue.h" #include "debug.h" +#include +#include "../../scsi/sd.h" + /*********************************************************************** * Data transfer routines @@ -511,6 +514,80 @@ * Transport routines ***********************************************************************/ +/* There are so many devices that report the capacity incorrectly, + * this routine was written to counteract some of the resulting + * problems. + */ +static void last_sector_hacks(struct us_data *us, struct scsi_cmnd *srb) +{ + struct gendisk *disk; + struct scsi_disk *sdkp; + u32 sector; + + /* To Report "Medium Error: Record Not Found */ + static unsigned char record_not_found[18] = { + [0] = 0x70, /* current error */ + [2] = MEDIUM_ERROR, /* = 0x03 */ + [7] = 0x0a, /* additional length */ + [12] = 0x14 /* Record Not Found */ + }; + + /* If last-sector problems can't occur, whether because the + * capacity was already decremented or because the device is + * known to report the correct capacity, then we don't need + * to do anything. + */ + if (!us->use_last_sector_hacks) + return; + + /* Was this command a READ(10) or a WRITE(10)? */ + if (srb->cmnd[0] != READ_10 && srb->cmnd[0] != WRITE_10) + goto done; + + /* Did this command access the last sector? */ + sector = (srb->cmnd[2] << 24) | (srb->cmnd[3] << 16) | + (srb->cmnd[4] << 8) | (srb->cmnd[5]); + disk = srb->request->rq_disk; + if (!disk) + goto done; + sdkp = scsi_disk(disk); + if (!sdkp) + goto done; + if (sector + 1 != sdkp->capacity) + goto done; + + if (srb->result == SAM_STAT_GOOD && scsi_get_resid(srb) == 0) { + + /* The command succeeded. We know this device doesn't + * have the last-sector bug, so stop checking it. + */ + us->use_last_sector_hacks = 0; + + } else { + /* The command failed. Allow up to 3 retries in case this + * is some normal sort of failure. After that, assume the + * capacity is wrong and we're trying to access the sector + * beyond the end. Replace the result code and sense data + * with values that will cause the SCSI core to fail the + * command immediately, instead of going into an infinite + * (or even just a very long) retry loop. + */ + if (++us->last_sector_retries < 3) + return; + srb->result = SAM_STAT_CHECK_CONDITION; + memcpy(srb->sense_buffer, record_not_found, + sizeof(record_not_found)); + } + + done: + /* Don't reset the retry counter for TEST UNIT READY commands, + * because they get issued after device resets which might be + * caused by a failed last-sector access. + */ + if (srb->cmnd[0] != TEST_UNIT_READY) + us->last_sector_retries = 0; +} + /* Invoke the transport and basic error-handling/recovery methods * * This is used by the protocol layers to actually send the message to @@ -544,6 +621,7 @@ /* if the transport provided its own sense data, don't auto-sense */ if (result == USB_STOR_TRANSPORT_NO_SENSE) { srb->result = SAM_STAT_CHECK_CONDITION; + last_sector_hacks(us, srb); return; } @@ -667,6 +745,7 @@ scsi_bufflen(srb) - scsi_get_resid(srb) < srb->underflow) srb->result = (DID_ERROR << 16) | (SUGGEST_RETRY << 24); + last_sector_hacks(us, srb); return; /* Error and abort processing: try to resynchronize with the device @@ -694,6 +773,7 @@ us->transport_reset(us); } clear_bit(US_FLIDX_RESETTING, &us->dflags); + last_sector_hacks(us, srb); } /* Stop the current URB transfer */ --- linux-2.6.28.orig/drivers/usb/storage/Makefile +++ linux-2.6.28/drivers/usb/storage/Makefile @@ -24,7 +24,7 @@ usb-storage-obj-$(CONFIG_USB_STORAGE_CYPRESS_ATACB) += cypress_atacb.o usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \ - initializers.o sierra_ms.o $(usb-storage-obj-y) + initializers.o sierra_ms.o option_ms.o $(usb-storage-obj-y) ifneq ($(CONFIG_USB_LIBUSUAL),) obj-$(CONFIG_USB) += libusual.o --- linux-2.6.28.orig/drivers/usb/storage/usb.h +++ linux-2.6.28/drivers/usb/storage/usb.h @@ -155,6 +155,10 @@ #ifdef CONFIG_PM pm_hook suspend_resume_hook; #endif + + /* hacks for READ CAPACITY bug handling */ + int use_last_sector_hacks; + int last_sector_retries; }; /* Convert between us_data and the corresponding Scsi_Host */ --- linux-2.6.28.orig/drivers/usb/storage/scsiglue.c +++ linux-2.6.28/drivers/usb/storage/scsiglue.c @@ -59,6 +59,14 @@ #include "transport.h" #include "protocol.h" +/* Vendor IDs for companies that seem to include the READ CAPACITY bug + * in all their devices + */ +#define VENDOR_ID_NOKIA 0x0421 +#define VENDOR_ID_NIKON 0x04b0 +#define VENDOR_ID_PENTAX 0x0a17 +#define VENDOR_ID_MOTOROLA 0x22b8 + /*********************************************************************** * Host functions ***********************************************************************/ @@ -134,6 +142,23 @@ * settings can't be overridden via the scsi devinfo mechanism. */ if (sdev->type == TYPE_DISK) { + /* Some vendors seem to put the READ CAPACITY bug into + * all their devices -- primarily makers of cell phones + * and digital cameras. Since these devices always use + * flash media and can be expected to have an even number + * of sectors, we will always enable the CAPACITY_HEURISTICS + * flag unless told otherwise. */ + switch (le16_to_cpu(us->pusb_dev->descriptor.idVendor)) { + case VENDOR_ID_NOKIA: + case VENDOR_ID_NIKON: + case VENDOR_ID_PENTAX: + case VENDOR_ID_MOTOROLA: + if (!(us->fflags & (US_FL_FIX_CAPACITY | + US_FL_CAPACITY_OK))) + us->fflags |= US_FL_CAPACITY_HEURISTICS; + break; + } + /* Disk-type devices use MODE SENSE(6) if the protocol * (SubClass) is Transparent SCSI, otherwise they use * MODE SENSE(10). */ @@ -196,6 +221,14 @@ * sector in a larger then 1 sector read, since the performance * impact is negible we set this flag for all USB disks */ sdev->last_sector_bug = 1; + + /* Enable last-sector hacks for single-target devices using + * the Bulk-only transport, unless we already know the + * capacity will be decremented or is correct. */ + if (!(us->fflags & (US_FL_FIX_CAPACITY | US_FL_CAPACITY_OK | + US_FL_SCM_MULT_TARG)) && + us->protocol == US_PR_BULK) + us->use_last_sector_hacks = 1; } else { /* Non-disk-type devices don't need to blacklist any pages --- linux-2.6.28.orig/drivers/usb/storage/libusual.c +++ linux-2.6.28/drivers/usb/storage/libusual.c @@ -46,6 +46,12 @@ { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } +#define COMPLIANT_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ + vendorName, productName, useProtocol, useTransport, \ + initFunction, flags) \ +{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ + .driver_info = (flags) } + #define USUAL_DEV(useProto, useTrans, useType) \ { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \ .driver_info = ((useType)<<24) } @@ -57,6 +63,7 @@ #undef USUAL_DEV #undef UNUSUAL_DEV +#undef COMPLIANT_DEV MODULE_DEVICE_TABLE(usb, storage_usb_ids); EXPORT_SYMBOL_GPL(storage_usb_ids); --- linux-2.6.28.orig/drivers/usb/storage/option_ms.c +++ linux-2.6.28/drivers/usb/storage/option_ms.c @@ -0,0 +1,147 @@ +/* + * Driver for Option High Speed Mobile Devices. + * + * (c) 2008 Dan Williams + * + * Inspiration taken from sierra_ms.c by Kevin Lloyd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 "usb.h" +#include "transport.h" +#include "option_ms.h" +#include "debug.h" + +#define ZCD_FORCE_MODEM 0x01 +#define ZCD_ALLOW_MS 0x02 + +static unsigned int option_zero_cd = ZCD_FORCE_MODEM; +module_param(option_zero_cd, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(option_zero_cd, "ZeroCD mode (1=Force Modem (default)," + " 2=Allow CD-Rom"); + +#define RESPONSE_LEN 1024 + +static int option_rezero(struct us_data *us, int ep_in, int ep_out) +{ + const unsigned char rezero_msg[] = { + 0x55, 0x53, 0x42, 0x43, 0x78, 0x56, 0x34, 0x12, + 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x06, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + char *buffer; + int result; + + US_DEBUGP("Option MS: %s", "DEVICE MODE SWITCH\n"); + + buffer = kzalloc(RESPONSE_LEN, GFP_KERNEL); + if (buffer == NULL) + return USB_STOR_TRANSPORT_ERROR; + + memcpy(buffer, rezero_msg, sizeof (rezero_msg)); + result = usb_stor_bulk_transfer_buf(us, + usb_sndbulkpipe(us->pusb_dev, ep_out), + buffer, sizeof (rezero_msg), NULL); + if (result != USB_STOR_XFER_GOOD) { + result = USB_STOR_XFER_ERROR; + goto out; + } + + /* Some of the devices need to be asked for a response, but we don't + * care what that response is. + */ + result = usb_stor_bulk_transfer_buf(us, + usb_sndbulkpipe(us->pusb_dev, ep_out), + buffer, RESPONSE_LEN, NULL); + result = USB_STOR_XFER_GOOD; + +out: + kfree(buffer); + return result; +} + +int option_ms_init(struct us_data *us) +{ + struct usb_device *udev; + struct usb_interface *intf; + struct usb_host_interface *iface_desc; + struct usb_endpoint_descriptor *endpoint = NULL; + u8 ep_in = 0, ep_out = 0; + int ep_in_size = 0, ep_out_size = 0; + int i, result; + + udev = us->pusb_dev; + intf = us->pusb_intf; + + /* Ensure it's really a ZeroCD device; devices that are already + * in modem mode return 0xFF for class, subclass, and protocol. + */ + if (udev->descriptor.bDeviceClass != 0 || + udev->descriptor.bDeviceSubClass != 0 || + udev->descriptor.bDeviceProtocol != 0) + return USB_STOR_TRANSPORT_GOOD; + + US_DEBUGP("Option MS: option_ms_init called\n"); + + /* Find the right mass storage interface */ + iface_desc = intf->cur_altsetting; + if (iface_desc->desc.bInterfaceClass != 0x8 || + iface_desc->desc.bInterfaceSubClass != 0x6 || + iface_desc->desc.bInterfaceProtocol != 0x50) { + US_DEBUGP("Option MS: mass storage interface not found, no action " + "required\n"); + return USB_STOR_TRANSPORT_GOOD; + } + + /* Find the mass storage bulk endpoints */ + for (i = 0; i < iface_desc->desc.bNumEndpoints && (!ep_in_size || !ep_out_size); ++i) { + endpoint = &iface_desc->endpoint[i].desc; + + if (usb_endpoint_is_bulk_in(endpoint)) { + ep_in = usb_endpoint_num(endpoint); + ep_in_size = le16_to_cpu(endpoint->wMaxPacketSize); + } else if (usb_endpoint_is_bulk_out(endpoint)) { + ep_out = usb_endpoint_num(endpoint); + ep_out_size = le16_to_cpu(endpoint->wMaxPacketSize); + } + } + + /* Can't find the mass storage endpoints */ + if (!ep_in_size || !ep_out_size) { + US_DEBUGP("Option MS: mass storage endpoints not found, no action " + "required\n"); + return USB_STOR_TRANSPORT_GOOD; + } + + /* Force Modem mode */ + if (option_zero_cd == ZCD_FORCE_MODEM) { + US_DEBUGP("Option MS: %s", "Forcing Modem Mode\n"); + result = option_rezero(us, ep_in, ep_out); + if (result != USB_STOR_XFER_GOOD) + US_DEBUGP("Option MS: Failed to switch to modem mode.\n"); + return -EIO; + } else if (option_zero_cd == ZCD_ALLOW_MS) { + /* Allow Mass Storage mode (keep CD-Rom) */ + US_DEBUGP("Option MS: %s", "Allowing Mass Storage Mode if device" + " requests it\n"); + } + + return USB_STOR_TRANSPORT_GOOD; +} + --- linux-2.6.28.orig/drivers/usb/host/isp1760-if.c +++ linux-2.6.28/drivers/usb/host/isp1760-if.c @@ -129,23 +129,23 @@ #endif #ifdef CONFIG_PCI -static u32 nxp_pci_io_base; -static u32 iolength; -static u32 pci_mem_phy0; -static u32 length; -static u8 __iomem *chip_addr; -static u8 __iomem *iobase; - static int __devinit isp1761_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) { u8 latency, limit; __u32 reg_data; int retry_count; - int length; - int status = 1; struct usb_hcd *hcd; unsigned int devflags = 0; + int ret_status = 0; + + resource_size_t pci_mem_phy0; + resource_size_t memlength; + + u8 __iomem *chip_addr; + u8 __iomem *iobase; + resource_size_t nxp_pci_io_base; + resource_size_t iolength; if (usb_disabled()) return -ENODEV; @@ -168,26 +168,30 @@ iobase = ioremap_nocache(nxp_pci_io_base, iolength); if (!iobase) { printk(KERN_ERR "ioremap #1\n"); - release_mem_region(nxp_pci_io_base, iolength); - return -ENOMEM; + ret_status = -ENOMEM; + goto cleanup1; } /* Grab the PLX PCI shared memory of the ISP 1761 we need */ pci_mem_phy0 = pci_resource_start(dev, 3); - length = pci_resource_len(dev, 3); - - if (length < 0xffff) { - printk(KERN_ERR "memory length for this resource is less than " - "required\n"); - release_mem_region(nxp_pci_io_base, iolength); - iounmap(iobase); - return -ENOMEM; + memlength = pci_resource_len(dev, 3); + if (memlength < 0xffff) { + printk(KERN_ERR "memory length for this resource is wrong\n"); + ret_status = -ENOMEM; + goto cleanup2; } - if (!request_mem_region(pci_mem_phy0, length, "ISP-PCI")) { + if (!request_mem_region(pci_mem_phy0, memlength, "ISP-PCI")) { printk(KERN_ERR "host controller already in use\n"); - release_mem_region(nxp_pci_io_base, iolength); - iounmap(iobase); - return -EBUSY; + ret_status = -EBUSY; + goto cleanup2; + } + + /* map available memory */ + chip_addr = ioremap_nocache(pci_mem_phy0,memlength); + if (!chip_addr) { + printk(KERN_ERR "Error ioremap failed\n"); + ret_status = -ENOMEM; + goto cleanup3; } /* bad pci latencies can contribute to overruns */ @@ -210,39 +214,54 @@ * */ writel(0xface, chip_addr + HC_SCRATCH_REG); udelay(100); - reg_data = readl(chip_addr + HC_SCRATCH_REG); + reg_data = readl(chip_addr + HC_SCRATCH_REG) & 0x0000ffff; retry_count--; } + iounmap(chip_addr); + /* Host Controller presence is detected by writing to scratch register * and reading back and checking the contents are same or not */ if (reg_data != 0xFACE) { dev_err(&dev->dev, "scratch register mismatch %x\n", reg_data); - goto clean; + ret_status = -ENOMEM; + goto cleanup3; } pci_set_master(dev); - status = readl(iobase + 0x68); - status |= 0x900; - writel(status, iobase + 0x68); + /* configure PLX PCI chip to pass interrupts */ +#define PLX_INT_CSR_REG 0x68 + reg_data = readl(iobase + PLX_INT_CSR_REG); + reg_data |= 0x900; + writel(reg_data, iobase + PLX_INT_CSR_REG); dev->dev.dma_mask = NULL; - hcd = isp1760_register(pci_mem_phy0, length, dev->irq, + hcd = isp1760_register(pci_mem_phy0, memlength, dev->irq, IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev), devflags); - if (!IS_ERR(hcd)) { - pci_set_drvdata(dev, hcd); - return 0; + if (IS_ERR(hcd)) { + ret_status = -ENODEV; + goto cleanup3; } -clean: - status = -ENODEV; + + /* done with PLX IO access */ iounmap(iobase); - release_mem_region(pci_mem_phy0, length); release_mem_region(nxp_pci_io_base, iolength); - return status; + + pci_set_drvdata(dev, hcd); + return 0; + +cleanup3: + release_mem_region(pci_mem_phy0, memlength); +cleanup2: + iounmap(iobase); +cleanup1: + release_mem_region(nxp_pci_io_base, iolength); + return ret_status; } + static void isp1761_pci_remove(struct pci_dev *dev) { struct usb_hcd *hcd; @@ -255,12 +274,6 @@ usb_put_hcd(hcd); pci_disable_device(dev); - - iounmap(iobase); - iounmap(chip_addr); - - release_mem_region(nxp_pci_io_base, iolength); - release_mem_region(pci_mem_phy0, length); } static void isp1761_pci_shutdown(struct pci_dev *dev) @@ -268,12 +281,16 @@ printk(KERN_ERR "ips1761_pci_shutdown\n"); } -static const struct pci_device_id isp1760_plx [] = { { - /* handle any USB 2.0 EHCI controller */ - PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_OTHER << 8) | (0x06 << 16)), ~0), - .driver_data = 0, -}, -{ /* end: all zeroes */ } +static const struct pci_device_id isp1760_plx [] = { + { + .class = PCI_CLASS_BRIDGE_OTHER << 8, + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_PLX, + .device = 0x5406, + .subvendor = PCI_VENDOR_ID_PLX, + .subdevice = 0x9054, + }, + { } }; MODULE_DEVICE_TABLE(pci, isp1760_plx); --- linux-2.6.28.orig/drivers/usb/host/ehci-sched.c +++ linux-2.6.28/drivers/usb/host/ehci-sched.c @@ -1004,7 +1004,8 @@ is_in = (stream->bEndpointAddress & USB_DIR_IN) ? 0x10 : 0; stream->bEndpointAddress &= 0x0f; - stream->ep->hcpriv = NULL; + if (stream->ep) + stream->ep->hcpriv = NULL; if (stream->rescheduled) { ehci_info (ehci, "ep%d%s-iso rescheduled " @@ -1535,7 +1536,7 @@ struct ehci_itd, itd_list); list_move_tail (&itd->itd_list, &stream->td_list); itd->stream = iso_stream_get (stream); - itd->urb = usb_get_urb (urb); + itd->urb = urb; itd_init (ehci, stream, itd); } @@ -1644,7 +1645,7 @@ (void) disable_periodic(ehci); ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; - if (unlikely (list_empty (&stream->td_list))) { + if (unlikely(list_is_singular(&stream->td_list))) { ehci_to_hcd(ehci)->self.bandwidth_allocated -= stream->bandwidth; ehci_vdbg (ehci, @@ -1653,14 +1654,27 @@ (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); } iso_stream_put (ehci, stream); - /* OK to recycle this ITD now that its completion callback ran. */ + done: - usb_put_urb(urb); itd->urb = NULL; - itd->stream = NULL; - list_move(&itd->itd_list, &stream->free_list); - iso_stream_put(ehci, stream); - + if (ehci->clock_frame != itd->frame || itd->index[7] != -1) { + /* OK to recycle this ITD now. */ + itd->stream = NULL; + list_move(&itd->itd_list, &stream->free_list); + iso_stream_put(ehci, stream); + } else { + /* HW might remember this ITD, so we can't recycle it yet. + * Move it to a safe place until a new frame starts. + */ + list_move(&itd->itd_list, &ehci->cached_itd_list); + if (stream->refcount == 2) { + /* If iso_stream_put() were called here, stream + * would be freed. Instead, just prevent reuse. + */ + stream->ep->hcpriv = NULL; + stream->ep = NULL; + } + } return retval; } @@ -1934,7 +1948,7 @@ struct ehci_sitd, sitd_list); list_move_tail (&sitd->sitd_list, &stream->td_list); sitd->stream = iso_stream_get (stream); - sitd->urb = usb_get_urb (urb); + sitd->urb = urb; sitd_patch(ehci, stream, sitd, sched, packet); sitd_link (ehci, (next_uframe >> 3) % ehci->periodic_size, @@ -2019,7 +2033,7 @@ (void) disable_periodic(ehci); ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; - if (list_empty (&stream->td_list)) { + if (list_is_singular(&stream->td_list)) { ehci_to_hcd(ehci)->self.bandwidth_allocated -= stream->bandwidth; ehci_vdbg (ehci, @@ -2030,7 +2044,6 @@ iso_stream_put (ehci, stream); /* OK to recycle this SITD now that its completion callback ran. */ done: - usb_put_urb(urb); sitd->urb = NULL; sitd->stream = NULL; list_move(&sitd->sitd_list, &stream->free_list); @@ -2101,6 +2114,20 @@ /*-------------------------------------------------------------------------*/ +static void free_cached_itd_list(struct ehci_hcd *ehci) +{ + struct ehci_itd *itd, *n; + + list_for_each_entry_safe(itd, n, &ehci->cached_itd_list, itd_list) { + struct ehci_iso_stream *stream = itd->stream; + itd->stream = NULL; + list_move(&itd->itd_list, &stream->free_list); + iso_stream_put(ehci, stream); + } +} + +/*-------------------------------------------------------------------------*/ + static void scan_periodic (struct ehci_hcd *ehci) { @@ -2115,10 +2142,17 @@ * Touches as few pages as possible: cache-friendly. */ now_uframe = ehci->next_uframe; - if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) + if (HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) { clock = ehci_readl(ehci, &ehci->regs->frame_index); - else + clock_frame = (clock >> 3) % ehci->periodic_size; + } else { clock = now_uframe + mod - 1; + clock_frame = -1; + } + if (ehci->clock_frame != clock_frame) { + free_cached_itd_list(ehci); + ehci->clock_frame = clock_frame; + } clock %= mod; clock_frame = clock >> 3; @@ -2277,6 +2311,10 @@ /* rescan the rest of this frame, then ... */ clock = now; clock_frame = clock >> 3; + if (ehci->clock_frame != clock_frame) { + free_cached_itd_list(ehci); + ehci->clock_frame = clock_frame; + } } else { now_uframe++; now_uframe %= mod; --- linux-2.6.28.orig/drivers/usb/host/pci-quirks.c +++ linux-2.6.28/drivers/usb/host/pci-quirks.c @@ -51,6 +51,19 @@ #define EHCI_USBLEGCTLSTS 4 /* legacy control/status */ #define EHCI_USBLEGCTLSTS_SOOE (1 << 13) /* SMI on ownership change */ +#ifdef CONFIG_X86_LPIA +void uhci_clear_usb_int(unsigned long base) +{ + outw(UHCI_USBCMD_HCRESET, base + UHCI_USBCMD); + mb(); + udelay(5); + outw(0, base + UHCI_USBINTR); + outw(0, base + UHCI_USBCMD); + mb(); + return; +} +EXPORT_SYMBOL (uhci_clear_usb_int); +#endif /* * Make sure the controller is completely inactive, unable to --- linux-2.6.28.orig/drivers/usb/host/uhci-hcd.c +++ linux-2.6.28/drivers/usb/host/uhci-hcd.c @@ -932,6 +932,20 @@ MODULE_DEVICE_TABLE(pci, uhci_pci_ids); +#ifdef CONFIG_X86_LPIA +extern void uhci_clear_usb_int(unsigned long base); +static int usb_hcd_resume_early(struct pci_dev *dev) +{ + struct usb_hcd *hcd; + struct uhci_hcd *uhci; + + hcd = pci_get_drvdata(dev); + uhci = hcd_to_uhci(hcd); + uhci_clear_usb_int(uhci->io_addr); + return 0; +} +#endif + static struct pci_driver uhci_pci_driver = { .name = (char *)hcd_name, .id_table = uhci_pci_ids, @@ -941,6 +955,9 @@ .shutdown = uhci_shutdown, #ifdef CONFIG_PM +#ifdef CONFIG_X86_LPIA + .resume_early = usb_hcd_resume_early, +#endif .suspend = usb_hcd_pci_suspend, .resume = usb_hcd_pci_resume, #endif /* PM */ --- linux-2.6.28.orig/drivers/usb/host/ehci.h +++ linux-2.6.28/drivers/usb/host/ehci.h @@ -87,6 +87,10 @@ int next_uframe; /* scan periodic, start here */ unsigned periodic_sched; /* periodic activity count */ + /* list of itds completed while clock_frame was still active */ + struct list_head cached_itd_list; + unsigned clock_frame; + /* per root hub port */ unsigned long reset_done [EHCI_MAX_ROOT_PORTS]; @@ -123,6 +127,20 @@ u8 sbrn; /* packed release number */ +#ifdef CONFIG_ARCH_MXC_CANONICAL + /* + * OTG controllers and transceivers need software interaction; + * other external transceivers should be software-transparent + */ + struct otg_transceiver *transceiver; +#ifdef CONFIG_USB_STATIC_IRAM + u32 iram_buffer[2]; + u32 iram_buffer_v[2]; + int iram_in_use[2]; + int usb_address[2]; +#endif +#endif + /* irq statistics */ #ifdef EHCI_STATS struct ehci_stats stats; @@ -210,6 +228,8 @@ } } +static void free_cached_itd_list(struct ehci_hcd *ehci); + /*-------------------------------------------------------------------------*/ #include @@ -257,6 +277,12 @@ struct list_head qtd_list; /* sw qtd list */ struct urb *urb; /* qtd's urb */ size_t length; /* length of buffer */ +#ifdef CONFIG_ARCH_MXC_CANONICAL +#ifdef CONFIG_USB_STATIC_IRAM + size_t buffer_offset; + int last_one; +#endif +#endif } __attribute__ ((aligned (32))); /* mask NakCnt+T in qh->hw_alt_next */ @@ -698,6 +724,12 @@ #define STUB_DEBUG_FILES #endif /* DEBUG */ +#ifdef CONFIG_ARCH_MXC_CANONICAL +#ifdef CONFIG_USB_STATIC_IRAM +#define IRAM_TD_SIZE 1024 /* size of 1 qTD's buffer */ +#define IRAM_NTD 2 /* number of TDs in IRAM */ +#endif +#endif /*-------------------------------------------------------------------------*/ #endif /* __LINUX_EHCI_HCD_H */ --- linux-2.6.28.orig/drivers/usb/host/ehci-hub.c +++ linux-2.6.28/drivers/usb/host/ehci-hub.c @@ -530,6 +530,39 @@ desc->wHubCharacteristics = cpu_to_le16(temp); } +#ifdef CONFIG_ARCH_MXC_CANONICAL +#ifdef CONFIG_USB_OTG +static int ehci_start_port_reset(struct usb_hcd *hcd, unsigned port) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + u32 status; + + if (!port) + return -EINVAL; + port--; + + /* start port reset before HNP protocol time out */ + status = readl(&ehci->regs->port_status[port]); + if (!(status & PORT_CONNECT)) + return -ENODEV; + + /* khubd will finish the reset later */ + if (ehci_is_TDI(ehci)) + writel(PORT_RESET | (status & ~(PORT_CSC | PORT_PEC + | PORT_OCC)), &ehci->regs->port_status[port]); + else + writel(PORT_RESET, &ehci->regs->port_status[port]); + + return 0; +} +#else +static int ehci_start_port_reset(struct usb_hcd *hcd, unsigned port) +{ + return 0; +} +#endif /* CONFIG_USB_OTG */ +#endif /* CONFIG_ARCH_MXC_CANONICAL */ + /*-------------------------------------------------------------------------*/ static int ehci_hub_control ( --- linux-2.6.28.orig/drivers/usb/host/Kconfig +++ linux-2.6.28/drivers/usb/host/Kconfig @@ -42,9 +42,69 @@ To compile this driver as a module, choose M here: the module will be called ehci-hcd. +config USB_EHCI_ARC + bool "Support for Freescale controller" + depends on USB_EHCI_HCD && ARCH_MXC + ---help--- + Some Freescale processors have an integrated High Speed + USBOTG controller, which supports EHCI host mode. + + Say "y" here to add support for this controller + to the EHCI HCD driver. + +config USB_EHCI_ARC_H1 + bool "Support for Host1 port on Freescale controller" + depends on USB_EHCI_ARC && (ARCH_MX51) + ---help--- + Enable support for the USB Host1 port. + +config USB_EHCI_ARC_H2 + bool "Support for Host2 port on Freescale controller" + depends on USB_EHCI_ARC && (ARCH_MX51) + ---help--- + Enable support for the USB Host2 port. + +config USB_EHCI_ARC_OTG + bool "Support for DR host port on Freescale controller" + depends on USB_EHCI_ARC + default y + ---help--- + Enable support for the USB OTG port in HS/FS Host mode. + +config USB_STATIC_IRAM + bool "Use IRAM for USB" + depends on USB_EHCI_ARC + ---help--- + Enable this option to use IRAM instead of DRAM for USB + structures and buffers. This option will reduce bus + contention on systems with large (VGA+) framebuffer + devices and heavy USB activity. There are performance + penalties and usage restrictions when using this option. + + If in doubt, say N. + +choice + prompt "Select transceiver for DR port" + depends on USB_EHCI_ARC_OTG + default USB_EHCI_FSL_UTMI if (ARCH_MX51) + ---help--- + Choose the transceiver to use with the Freescale DR port. + +config USB_EHCI_FSL_UTMI + bool "Internal UTMI" + depends on (ARCH_MX51) + ---help--- + Enable support for the on-chip High Speed UTMI transceiver. + + This is the factory default for the mx35ads board. + +endchoice + + config USB_EHCI_ROOT_HUB_TT bool "Root Hub Transaction Translators" depends on USB_EHCI_HCD + default y if USB_EHCI_ARC ---help--- Some EHCI chips have vendor-specific extensions to integrate transaction translators, so that no OHCI or UHCI companion --- linux-2.6.28.orig/drivers/usb/host/ehci-mem-iram.c +++ linux-2.6.28/drivers/usb/host/ehci-mem-iram.c @@ -0,0 +1,506 @@ +/* + * Copyright (c) 2001 by David Brownell + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You 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 file is part of ehci-hcd.c */ + +/*-------------------------------------------------------------------------*/ + +/* + * There's basically three types of memory: + * - data used only by the HCD ... kmalloc is fine + * - async and periodic schedules, shared by HC and HCD ... these + * need to use dma_pool or dma_alloc_coherent + * - driver buffers, read/written by HC ... single shot DMA mapped + * + * There's also "register" data (e.g. PCI or SOC), which is memory mapped. + * No memory seen by this driver is pageable. + */ + +/*-------------------------------------------------------------------------*/ + +/* Allocate the key transfer structures from the previously allocated pool */ +#include + +bool use_iram_qtd; + +struct memDesc { + u32 start; + u32 end; + struct memDesc *next; +} ; + +static u32 g_usb_pool_start; +static s32 g_usb_pool_count; +static u32 g_total_pages; +static u32 g_alignment = 32; +struct memDesc *g_allocated_desc; +static spinlock_t g_usb_sema; +static u32 g_debug_qtd_allocated; +static u32 g_debug_qH_allocated; +static int g_alloc_map; + +/*! + * usb_pool_initialize + * + * @param memPool start address of the pool + * @param poolSize memory pool size + * @param alignment alignment for example page alignmnet will be 4K + * + * @return 0 for success -1 for errors + */ +static int usb_pool_initialize(u32 memPool, u32 poolSize, u32 alignment) +{ + if (g_usb_pool_count) { + printk(KERN_INFO "usb_pool_initialize : already initialzed.\n"); + return 0; + } + + g_alignment = alignment; + if (g_alignment == 0) { + printk(KERN_INFO + "usb_pool_initialize : g_alignment can not be zero.\n"); + g_alignment = 32; + } + + g_total_pages = poolSize / g_alignment; + g_usb_pool_start = (u32) memPool; + + g_allocated_desc = kmalloc(sizeof(struct memDesc), GFP_KERNEL); + if (!g_allocated_desc) { + printk(KERN_ALERT "usb_pool_initialize : kmalloc failed \n"); + return (-1); + } + + g_allocated_desc->start = 0; + g_allocated_desc->end = 0; + g_allocated_desc->next = NULL; + + spin_lock_init(&g_usb_sema); + g_usb_pool_count++; + return (0); +} + +static void usb_pool_deinit() +{ + if (--g_usb_pool_count < 0) + g_usb_pool_count = 0; +} + +/*! + * usb_malloc + * + * @param size memory pool size + * + * @return physical address, 0 for error + */ +static u32 usb_malloc(u32 size, gfp_t mem_flags) +{ + unsigned long flags; + struct memDesc *prevDesc = NULL; + struct memDesc *nextDesc = NULL; + struct memDesc *currentDesc = NULL; + u32 pages = (size + g_alignment - 1) / g_alignment; + + if ((size == 0) || (pages > g_total_pages)) + return 0; + + currentDesc = kmalloc(sizeof(struct memDesc), mem_flags); + if (!currentDesc) { + printk(KERN_ALERT "usb_malloc: kmalloc failed \n"); + return 0; + } + + spin_lock_irqsave(&g_usb_sema, flags); + + /* Create the first Allocated descriptor */ + if (!g_allocated_desc->next) { + g_allocated_desc->next = currentDesc; + currentDesc->start = 0; + currentDesc->end = pages; + currentDesc->next = NULL; + spin_unlock_irqrestore(&g_usb_sema, flags); + return (g_usb_pool_start + currentDesc->start * g_alignment); + } + + /* Find the free spot */ + prevDesc = g_allocated_desc; + while (prevDesc->next) { + nextDesc = prevDesc->next; + if (pages <= nextDesc->start - prevDesc->end) { + currentDesc->start = prevDesc->end; + currentDesc->end = currentDesc->start + pages; + currentDesc->next = nextDesc; + prevDesc->next = currentDesc; + break; + } + prevDesc = nextDesc; + } + + /* Do not find the free spot inside the chain, append to the end */ + if (!prevDesc->next) { + if (pages > (g_total_pages - prevDesc->end)) { + spin_unlock_irqrestore(&g_usb_sema, flags); + kfree(currentDesc); + return 0; + } else { + currentDesc->start = prevDesc->end; + currentDesc->end = currentDesc->start + pages; + currentDesc->next = NULL; + prevDesc->next = currentDesc; + } + } + + spin_unlock_irqrestore(&g_usb_sema, flags); + return (g_usb_pool_start + currentDesc->start * g_alignment); +} + +/*! + * usb_free + * + * @param physical physical address try to free + * + */ +static void usb_free(u32 physical) +{ + unsigned long flags; + struct memDesc *prevDesc = NULL; + struct memDesc *nextDesc = NULL; + u32 pages = (physical - g_usb_pool_start) / g_alignment; + + /* Protect the memory pool data structures. */ + spin_lock_irqsave(&g_usb_sema, flags); + + prevDesc = g_allocated_desc; + while (prevDesc->next) { + nextDesc = prevDesc->next; + if (nextDesc->start == pages) { + prevDesc->next = nextDesc->next; + kfree(nextDesc); + break; + } + prevDesc = prevDesc->next; + } + /* All done with memory pool data structures. */ + spin_unlock_irqrestore(&g_usb_sema, flags); +} + +static int address_to_buffer(struct ehci_hcd *ehci, int address) +{ + int i; + + for (i = 0; i < IRAM_NTD; i++) { + if (ehci->usb_address[i] == address) + return i; + } + return IRAM_NTD; +} + +static void use_buffer(struct ehci_hcd *ehci, int address) +{ + int i; + + for (i = 0; i < IRAM_NTD; i++) { + if (ehci->usb_address[i] == address) + return; + } + + if (ehci->usb_address[0] == 0) { + ehci->usb_address[0] = address; + printk(KERN_INFO "usb_address[0] %x\n", address); + return; + } else if (ehci->usb_address[1] == 0) { + ehci->usb_address[1] = address; + printk(KERN_INFO "usb_address[1] %x\n", address); + return; + } else + printk(KERN_ALERT "qh_make run out of iRAM, already be used"); +} + +static u32 alloc_iram_buf(void) +{ + int i; + + for (i = 0; i < IRAM_NTD; i++) { + if (!(g_alloc_map & (1 << i))) { + g_alloc_map |= (1 << i); + return USB_IRAM_BASE_ADDR + i * (IRAM_TD_SIZE * 2); + } + } + panic("Out of IRAM buffers\n"); +} + +void free_iram_buf(u32 buf) +{ + int i = (buf - USB_IRAM_BASE_ADDR) / (IRAM_TD_SIZE * 2); + + g_alloc_map &= ~(1 << i); +} + +static inline void ehci_qtd_init(struct ehci_hcd *ehci, struct ehci_qtd *qtd, + dma_addr_t dma) +{ + memset(qtd, 0, sizeof *qtd); + qtd->qtd_dma = dma; + qtd->hw_token = cpu_to_le32(QTD_STS_HALT); + qtd->hw_next = EHCI_LIST_END(ehci); + qtd->hw_alt_next = EHCI_LIST_END(ehci); + INIT_LIST_HEAD(&qtd->qtd_list); +} + +static struct ehci_qtd *ehci_qtd_alloc(struct ehci_hcd *ehci, gfp_t flags) +{ + struct ehci_qtd *qtd; + dma_addr_t dma; + + if (use_iram_qtd) { + dma = usb_malloc(sizeof(struct ehci_qtd), flags); + if (dma != 0) + qtd = (struct ehci_qtd *)IO_ADDRESS(dma); + else + qtd = dma_pool_alloc(ehci->qtd_pool, flags, &dma); + } + else + qtd = dma_pool_alloc(ehci->qtd_pool, flags, &dma); + + if (qtd != NULL) { + ehci_qtd_init(ehci, qtd, dma); + ++g_debug_qtd_allocated; + } else { + panic + ("out of i-ram for qtd allocation g_debug_qtd_allocated %d \ + size%d \n", g_debug_qtd_allocated, + sizeof(struct ehci_qtd)); + } + return qtd; +} + +static inline void ehci_qtd_free(struct ehci_hcd *ehci, struct ehci_qtd *qtd) +{ + if ((qtd->qtd_dma & (USB_IRAM_BASE_ADDR & 0xFFF00000)) == + (USB_IRAM_BASE_ADDR & 0xFFF00000)) + usb_free(qtd->qtd_dma); + else + dma_pool_free(ehci->qtd_pool, qtd, qtd->qtd_dma); + --g_debug_qtd_allocated; +} + +static void qh_destroy(struct ehci_qh *qh) +{ + struct ehci_hcd *ehci = qh->ehci; + + /* clean qtds first, and know this is not linked */ + if (!list_empty(&qh->qtd_list) || qh->qh_next.ptr) { + ehci_dbg(ehci, "unused qh not empty!\n"); + BUG(); + } + if (qh->dummy) + ehci_qtd_free(ehci, qh->dummy); + int i; + for (i = 0; i < IRAM_NTD; i++) { + if (ehci->usb_address[i] == (qh->hw_info1 & 0x7F)) + ehci->usb_address[i] = 0; + } + + if ((qh->qh_dma & (USB_IRAM_BASE_ADDR & 0xFFF00000)) == + (USB_IRAM_BASE_ADDR & 0xFFF00000)) + usb_free(qh->qh_dma); + else + dma_pool_free(ehci->qh_pool, qh, qh->qh_dma); + --g_debug_qH_allocated; +} + +static struct ehci_qh *ehci_qh_alloc(struct ehci_hcd *ehci, gfp_t flags) +{ + struct ehci_qh *qh; + dma_addr_t dma; + + dma = usb_malloc(sizeof(struct ehci_qh), flags); + if (dma != 0) + qh = (struct ehci_qh *)IO_ADDRESS(dma); + else + qh = (struct ehci_qh *) + dma_pool_alloc(ehci->qh_pool, flags, &dma); + ++g_debug_qH_allocated; + if (qh == NULL) { + panic("run out of i-ram for qH allocation\n"); + return qh; + } + + memset(qh, 0, sizeof *qh); + qh->refcount = 1; + qh->ehci = ehci; + qh->qh_dma = dma; + INIT_LIST_HEAD(&qh->qtd_list); + + /* dummy td enables safe urb queuing */ + qh->dummy = ehci_qtd_alloc(ehci, flags); + if (qh->dummy == NULL) { + ehci_dbg(ehci, "no dummy td\n"); + dma_pool_free(ehci->qh_pool, qh, qh->qh_dma); + qh = NULL; + } + return qh; +} + +/* to share a qh (cpu threads, or hc) */ +static inline struct ehci_qh *qh_get(struct ehci_qh *qh) +{ + WARN_ON(!qh->refcount); + qh->refcount++; + return qh; +} + +static inline void qh_put(struct ehci_qh *qh) +{ + if (!--qh->refcount) + qh_destroy(qh); +} + +/*-------------------------------------------------------------------------*/ + +/* The queue heads and transfer descriptors are managed from pools tied + * to each of the "per device" structures. + * This is the initialisation and cleanup code. + */ + +static void ehci_mem_cleanup(struct ehci_hcd *ehci) +{ + if (ehci->async) + qh_put(ehci->async); + ehci->async = NULL; + + /* DMA consistent memory and pools */ + if (ehci->qtd_pool) + dma_pool_destroy(ehci->qtd_pool); + ehci->qtd_pool = NULL; + + if (ehci->qh_pool) { + dma_pool_destroy(ehci->qh_pool); + ehci->qh_pool = NULL; + } + + if (ehci->itd_pool) + dma_pool_destroy(ehci->itd_pool); + ehci->itd_pool = NULL; + + if (ehci->sitd_pool) + dma_pool_destroy(ehci->sitd_pool); + ehci->sitd_pool = NULL; + + if (ehci->periodic) + dma_free_coherent(ehci_to_hcd(ehci)->self.controller, + ehci->periodic_size * sizeof(u32), + ehci->periodic, ehci->periodic_dma); + ehci->periodic = NULL; + + if (ehci->iram_buffer[0]) + free_iram_buf(ehci->iram_buffer[0]); + if (ehci->iram_buffer[1]) + free_iram_buf(ehci->iram_buffer[1]); + + /* shadow periodic table */ + kfree(ehci->pshadow); + ehci->pshadow = NULL; + usb_pool_deinit(); +} + +/* remember to add cleanup code (above) if you add anything here */ +static int ehci_mem_init(struct ehci_hcd *ehci, gfp_t flags) +{ + int i; + g_usb_pool_count = 0; + g_debug_qtd_allocated = 0; + g_debug_qH_allocated = 0; + g_alloc_map = 0; + + if (cpu_is_mx37()) + use_iram_qtd = 0; + else + use_iram_qtd = 1; + + usb_pool_initialize(USB_IRAM_BASE_ADDR + IRAM_TD_SIZE * IRAM_NTD * 2, + USB_IRAM_SIZE - IRAM_TD_SIZE * IRAM_NTD * 2, 32); + + if (!ehci->iram_buffer[0]) { + ehci->iram_buffer[0] = alloc_iram_buf(); + ehci->iram_buffer_v[0] = IO_ADDRESS(ehci->iram_buffer[0]); + ehci->iram_buffer[1] = alloc_iram_buf(); + ehci->iram_buffer_v[1] = IO_ADDRESS(ehci->iram_buffer[1]); + } + + /* QTDs for control/bulk/intr transfers */ + ehci->qtd_pool = dma_pool_create("ehci_qtd", + ehci_to_hcd(ehci)->self.controller, + sizeof(struct ehci_qtd), + 32/* byte alignment (for hw parts) */ + , 4096 /* can't cross 4K */); + if (!ehci->qtd_pool) + goto fail; + + /* QHs for control/bulk/intr transfers */ + ehci->qh_pool = dma_pool_create("ehci_qh", + ehci_to_hcd(ehci)->self.controller, + sizeof(struct ehci_qh), + 32 /* byte alignment (for hw parts) */ , + 4096 /* can't cross 4K */); + if (!ehci->qh_pool) + goto fail; + + ehci->async = ehci_qh_alloc(ehci, flags); + if (!ehci->async) + goto fail; + + /* ITD for high speed ISO transfers */ + ehci->itd_pool = dma_pool_create("ehci_itd", + ehci_to_hcd(ehci)->self.controller, + sizeof(struct ehci_itd), + 32/* byte alignment (for hw parts) */ + , 4096 /* can't cross 4K */); + if (!ehci->itd_pool) + goto fail; + + /* SITD for full/low speed split ISO transfers */ + ehci->sitd_pool = dma_pool_create("ehci_sitd", + ehci_to_hcd(ehci)->self.controller, + sizeof(struct ehci_sitd), + 32/* byte alignment (for hw parts) */ + , 4096 /* can't cross 4K */); + if (!ehci->sitd_pool) + goto fail; + + ehci->periodic = (__le32 *) + dma_alloc_coherent(ehci_to_hcd(ehci)->self.controller, + ehci->periodic_size * sizeof(__le32), + &ehci->periodic_dma, 0); + + if (ehci->periodic == NULL) + goto fail; + + for (i = 0; i < ehci->periodic_size; i++) + ehci->periodic[i] = EHCI_LIST_END(ehci); + + /* software shadow of hardware table */ + ehci->pshadow = kcalloc(ehci->periodic_size, sizeof(void *), flags); + if (ehci->pshadow != NULL) + return 0; + +fail: + ehci_dbg(ehci, "couldn't init memory\n"); + ehci_mem_cleanup(ehci); + return -ENOMEM; +} --- linux-2.6.28.orig/drivers/usb/host/ehci-q.c +++ linux-2.6.28/drivers/usb/host/ehci-q.c @@ -1095,7 +1095,8 @@ prev->qh_next = qh->qh_next; wmb (); - if (unlikely (ehci_to_hcd(ehci)->state == HC_STATE_HALT)) { + /* If the controller isn't running, we don't have to wait for it */ + if (unlikely(!HC_IS_RUNNING(ehci_to_hcd(ehci)->state))) { /* if (unlikely (qh->reclaim != 0)) * this will recurse, probably not much */ --- linux-2.6.28.orig/drivers/usb/host/ehci-q-iram.c +++ linux-2.6.28/drivers/usb/host/ehci-q-iram.c @@ -0,0 +1,1345 @@ +/* + * Copyright (C) 2001-2004 by David Brownell + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You 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. + */ +#undef EHCI_NO_ERR_COUNT +static size_t g_iram_size = IRAM_TD_SIZE; + +/* this file is part of ehci-hcd.c */ + +/*-------------------------------------------------------------------------*/ + +/* + * EHCI hardware queue manipulation ... the core. QH/QTD manipulation. + * + * Control, bulk, and interrupt traffic all use "qh" lists. They list "qtd" + * entries describing USB transactions, max 16-20kB/entry (with 4kB-aligned + * buffers needed for the larger number). We use one QH per endpoint, queue + * multiple urbs (all three types) per endpoint. URBs may need several qtds. + * + * ISO traffic uses "ISO TD" (itd, and sitd) records, and (along with + * interrupts) needs careful scheduling. Performance improvements can be + * an ongoing challenge. That's in "ehci-sched.c". + * + * USB 1.1 devices are handled (a) by "companion" OHCI or UHCI root hubs, + * or otherwise through transaction translators (TTs) in USB 2.0 hubs using + * (b) special fields in qh entries or (c) split iso entries. TTs will + * buffer low/full speed data so the host collects it at high speed. + */ + +/*-------------------------------------------------------------------------*/ +/* fill a qtd, returning how much of the buffer we were able to queue up */ +static int qtd_fill(struct ehci_hcd *ehci, struct ehci_qtd *qtd, dma_addr_t buf, + size_t len, int token, int maxpacket) +{ + int i, count; + u64 addr = buf; + struct urb *urb = qtd->urb; + + if (usb_pipebulk(urb->pipe) && + (address_to_buffer(ehci, usb_pipedevice(urb->pipe)) != 2)) { + urb->use_iram = 1; + qtd->buffer_offset = (size_t) (buf - urb->transfer_dma); + token |= QTD_IOC; + if (usb_pipeout(urb->pipe)) { + addr = ehci->iram_buffer[address_to_buffer(ehci, + usb_pipedevice(urb->pipe))]; + } else if (usb_pipein(urb->pipe)) { + addr = ehci->iram_buffer[address_to_buffer(ehci, + usb_pipedevice(urb->pipe))] + + g_iram_size; + } + } else { + urb->use_iram = 0; + addr = buf; + } + len = min(g_iram_size, len); + + /* one buffer entry per 4K ... first might be short or unaligned */ + qtd->hw_buf[0] = cpu_to_hc32(ehci, (u32) addr); + qtd->hw_buf_hi[0] = cpu_to_hc32(ehci, (u32) (addr >> 32)); + count = 0x1000 - (buf & 0x0fff); /* rest of that page */ + if (likely(len < count)) /* ... iff needed */ + count = len; + else { + buf += 0x1000; + buf &= ~0x0fff; + + /* per-qtd limit: from 16K to 20K (best alignment) */ + for (i = 1; count < len && i < 5; i++) { + addr = buf; + qtd->hw_buf[i] = cpu_to_hc32(ehci, (u32) addr); + qtd->hw_buf_hi[i] = + cpu_to_hc32(ehci, (u32) (addr >> 32)); + buf += 0x1000; + if ((count + 0x1000) < len) + count += 0x1000; + else + count = len; + } + + /* short packets may only terminate transfers */ + if (count != len) + count -= (count % maxpacket); + } + qtd->hw_token = cpu_to_hc32(ehci, (count << 16) | token); + qtd->length = count; + + return count; +} + +/*-------------------------------------------------------------------------*/ + +static inline void +qh_update(struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd) +{ + /* writes to an active overlay are unsafe */ + BUG_ON(qh->qh_state != QH_STATE_IDLE); + + qh->hw_qtd_next = QTD_NEXT(ehci, qtd->qtd_dma); + qh->hw_alt_next = EHCI_LIST_END(ehci); + + /* Except for control endpoints, we make hardware maintain data + * toggle (like OHCI) ... here (re)initialize the toggle in the QH, + * and set the pseudo-toggle in udev. Only usb_clear_halt() will + * ever clear it. + */ + if (!(qh->hw_info1 & cpu_to_hc32(ehci, 1 << 14))) { + unsigned is_out, epnum; + + is_out = !(qtd->hw_token & cpu_to_hc32(ehci, 1 << 8)); + epnum = (hc32_to_cpup(ehci, &qh->hw_info1) >> 8) & 0x0f; + if (unlikely(!usb_gettoggle(qh->dev, epnum, is_out))) { + qh->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE); + usb_settoggle(qh->dev, epnum, is_out, 1); + } + } + + /* HC must see latest qtd and qh data before we clear ACTIVE+HALT */ + wmb(); + qh->hw_token &= cpu_to_hc32(ehci, QTD_TOGGLE | QTD_STS_PING); +} + +/* if it weren't for a common silicon quirk (writing the dummy into the qh + * overlay, so qh->hw_token wrongly becomes inactive/halted), only fault + * recovery (including urb dequeue) would need software changes to a QH... + */ +static void qh_refresh(struct ehci_hcd *ehci, struct ehci_qh *qh) +{ + struct ehci_qtd *qtd; + + if (list_empty(&qh->qtd_list)) + qtd = qh->dummy; + else { + qtd = list_entry(qh->qtd_list.next, struct ehci_qtd, qtd_list); + /* first qtd may already be partially processed */ + if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw_current) + qtd = NULL; + } + + if (qtd) + qh_update(ehci, qh, qtd); +} + +/*-------------------------------------------------------------------------*/ + +static int qtd_copy_status(struct ehci_hcd *ehci, + struct urb *urb, size_t length, u32 token) +{ + int status = -EINPROGRESS; + + /* count IN/OUT bytes, not SETUP (even short packets) */ + if (likely(QTD_PID(token) != 2)) + urb->actual_length += length - QTD_LENGTH(token); + + /* don't modify error codes */ + if (unlikely(urb->unlinked)) + return status; + + /* force cleanup after short read; not always an error */ + if (unlikely(IS_SHORT_READ(token))) + status = -EREMOTEIO; + + /* serious "can't proceed" faults reported by the hardware */ + if (token & QTD_STS_HALT) { + if (token & QTD_STS_BABBLE) { + /* FIXME "must" disable babbling device's port too */ + status = -EOVERFLOW; + } else if (token & QTD_STS_MMF) { + /* fs/ls interrupt xfer missed the complete-split */ + status = -EPROTO; + } else if (token & QTD_STS_DBE) { + status = (QTD_PID(token) == 1) /* IN ? */ + ? -ENOSR /* hc couldn't read data */ + : -ECOMM; /* hc couldn't write data */ + } else if (token & QTD_STS_XACT) { + /* timeout, bad crc, wrong PID, etc; retried */ + if (QTD_CERR(token)) + status = -EPIPE; + else { + ehci_dbg(ehci, "devpath %s ep%d%s 3strikes\n", + urb->dev->devpath, + usb_pipeendpoint(urb->pipe), + usb_pipein(urb->pipe) ? "in" : "out"); + status = -EPROTO; + } + /* CERR nonzero + no errors + halt --> stall */ + } else if (QTD_CERR(token)) + status = -EPIPE; + else /* unknown */ + status = -EPROTO; + + ehci_vdbg(ehci, + "dev%d ep%d%s qtd token %08x --> status %d\n", + usb_pipedevice(urb->pipe), + usb_pipeendpoint(urb->pipe), + usb_pipein(urb->pipe) ? "in" : "out", token, status); + + /* if async CSPLIT failed, try cleaning out the TT buffer */ + if (status != -EPIPE && urb->dev->tt && !usb_pipeint(urb->pipe) + && ((token & QTD_STS_MMF) != 0 || QTD_CERR(token) == 0) + && (!ehci_is_TDI(ehci) + || urb->dev->tt->hub != + ehci_to_hcd(ehci)->self.root_hub)) { +#ifdef DEBUG + struct usb_device *tt = urb->dev->tt->hub; + dev_dbg(&tt->dev, + "clear tt buffer port %d, a%d ep%d t%08x\n", + urb->dev->ttport, urb->dev->devnum, + usb_pipeendpoint(urb->pipe), token); +#endif /* DEBUG */ + /* REVISIT ARC-derived cores don't clear the root + * hub TT buffer in this way... + */ + usb_hub_tt_clear_buffer(urb->dev, urb->pipe); + } + } + + return status; +} + +static void +ehci_urb_done(struct ehci_hcd *ehci, struct urb *urb, int status) +__releases(ehci->lock) __acquires(ehci->lock) +{ + if (likely(urb->hcpriv != NULL)) { + struct ehci_qh *qh = (struct ehci_qh *)urb->hcpriv; + + /* S-mask in a QH means it's an interrupt urb */ + if ((qh->hw_info2 & cpu_to_hc32(ehci, QH_SMASK)) != 0) { + + /* ... update hc-wide periodic stats (for usbfs) */ + ehci_to_hcd(ehci)->self.bandwidth_int_reqs--; + } + qh_put(qh); + } + + if (unlikely(urb->unlinked)) { + COUNT(ehci->stats.unlink); + } else { + /* report non-error and short read status as zero */ + if (status == -EINPROGRESS || status == -EREMOTEIO) + status = 0; + COUNT(ehci->stats.complete); + } + +#ifdef EHCI_URB_TRACE + ehci_dbg(ehci, + "%s %s urb %p ep%d%s status %d len %d/%d\n", + __func__, urb->dev->devpath, urb, + usb_pipeendpoint(urb->pipe), + usb_pipein(urb->pipe) ? "in" : "out", + status, urb->actual_length, urb->transfer_buffer_length); +#endif + + /* complete() can reenter this HCD */ + usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); + spin_unlock(&ehci->lock); + usb_hcd_giveback_urb(ehci_to_hcd(ehci), urb, status); + spin_lock(&ehci->lock); +} + +static void start_unlink_async(struct ehci_hcd *ehci, struct ehci_qh *qh); +static void unlink_async(struct ehci_hcd *ehci, struct ehci_qh *qh); + +static void intr_deschedule(struct ehci_hcd *ehci, struct ehci_qh *qh); +static int qh_schedule(struct ehci_hcd *ehci, struct ehci_qh *qh); + +/* + * Process and free completed qtds for a qh, returning URBs to drivers. + * Chases up to qh->hw_current. Returns number of completions called, + * indicating how much "real" work we did. + */ +static unsigned qh_completions(struct ehci_hcd *ehci, struct ehci_qh *qh) +{ + struct ehci_qtd *last = NULL, *end = qh->dummy; + struct list_head *entry, *tmp; + int last_status = -EINPROGRESS; + int stopped; + unsigned count = 0; + u8 state; + __le32 halt = HALT_BIT(ehci); + __hc32 temp_hw_qtd_next = 0; + + if (unlikely(list_empty(&qh->qtd_list))) + return count; + + /* completions (or tasks on other cpus) must never clobber HALT + * till we've gone through and cleaned everything up, even when + * they add urbs to this qh's queue or mark them for unlinking. + * + * NOTE: unlinking expects to be done in queue order. + */ + state = qh->qh_state; + qh->qh_state = QH_STATE_COMPLETING; + stopped = (state == QH_STATE_IDLE); + + /* remove de-activated QTDs from front of queue. + * after faults (including short reads), cleanup this urb + * then let the queue advance. + * if queue is stopped, handles unlinks. + */ + list_for_each_safe(entry, tmp, &qh->qtd_list) { + struct ehci_qtd *qtd; + struct urb *urb; + struct ehci_qtd *qtd2; + struct urb *urb2; + + u32 token = 0; + + qtd = list_entry(entry, struct ehci_qtd, qtd_list); + urb = qtd->urb; + + /* clean up any state from previous QTD ... */ + if (last) { + if (likely(last->urb != urb)) { + ehci_urb_done(ehci, last->urb, last_status); + count++; + last_status = -EINPROGRESS; + } + ehci_qtd_free(ehci, last); + last = NULL; + } + + /* ignore urbs submitted during completions we reported */ + if (qtd == end) + break; + + /* hardware copies qtd out of qh overlay */ + rmb(); + token = hc32_to_cpu(ehci, qtd->hw_token); + + /* always clean up qtds the hc de-activated */ + if ((token & QTD_STS_ACTIVE) == 0) { + + /* on STALL, error, and short reads this urb must + * complete and all its qtds must be recycled. + */ + if ((token & QTD_STS_HALT) != 0) { + stopped = 1; + + /* magic dummy for some short reads; qh won't advance. + * that silicon quirk can kick in with this dummy too. + * + * other short reads won't stop the queue, including + * control transfers (status stage handles that) or + * most other single-qtd reads ... the queue stops if + * URB_SHORT_NOT_OK was set so the driver submitting + * the urbs could clean it up. + */ + } else if (IS_SHORT_READ(token) + && !(qtd->hw_alt_next & EHCI_LIST_END(ehci))) { + if (urb->use_iram && usb_pipein(urb->pipe)) { + if (urb->transfer_buffer == NULL) { + memcpy(phys_to_virt + (urb->transfer_dma) + + qtd->buffer_offset, + ehci-> + iram_buffer_v + [address_to_buffer + (ehci, + usb_pipedevice(urb-> + pipe))] + + g_iram_size, + min(g_iram_size, + qtd->length)); + } else { + memcpy(urb->transfer_buffer + + qtd->buffer_offset, + ehci-> + iram_buffer_v + [address_to_buffer + (ehci, + usb_pipedevice(urb-> + pipe))] + + g_iram_size, + min(g_iram_size, + qtd->length)); + } + } + stopped = 1; + goto halt; + } else if (urb->use_iram && (!qtd->last_one) + && usb_pipeout(urb->pipe)) { + ehci-> + iram_in_use[address_to_buffer + (ehci, + usb_pipedevice(urb->pipe))] = + 1; + qtd2 = + list_entry(tmp, struct ehci_qtd, qtd_list); + if (urb->transfer_buffer == NULL) { + memcpy(ehci-> + iram_buffer_v[address_to_buffer + (ehci, + usb_pipedevice + (urb->pipe))], + phys_to_virt(urb->transfer_dma) + + qtd->buffer_offset + qtd->length, + min(g_iram_size, qtd2->length)); + } else { + memcpy(ehci-> + iram_buffer_v[address_to_buffer + (ehci, + usb_pipedevice + (urb->pipe))], + urb->transfer_buffer + + qtd->buffer_offset + qtd->length, + min(g_iram_size, qtd2->length)); + } + temp_hw_qtd_next = + QTD_NEXT(ehci, qtd->hw_next) & 0xFFFFFFFE; + } else if (urb->use_iram && (qtd->last_one) + && usb_pipeout(urb->pipe)) { + urb->use_iram = 0; + qtd2 = + list_entry(tmp, struct ehci_qtd, qtd_list); + if (tmp != &qh->qtd_list) { + urb2 = qtd2->urb; + if (urb2 && urb2->use_iram == 1) { + ehci-> + iram_in_use + [address_to_buffer + (ehci, + usb_pipedevice(urb-> + pipe))] = + 1; + if (urb2->transfer_buffer == + NULL) { + memcpy(ehci-> + iram_buffer_v + [address_to_buffer + (ehci, + usb_pipedevice + (urb->pipe))], + phys_to_virt + (urb2-> + transfer_dma), + min(g_iram_size, + qtd2-> + length)); + } else { + memcpy(ehci-> + iram_buffer_v + [address_to_buffer + (ehci, + usb_pipedevice + (urb->pipe))], + urb2-> + transfer_buffer, + min(g_iram_size, + qtd2-> + length)); + } + } else { + ehci-> + iram_in_use + [address_to_buffer + (ehci, + usb_pipedevice(urb-> + pipe))] = + 0; + } + } else { + ehci-> + iram_in_use[address_to_buffer + (ehci, + usb_pipedevice(urb-> + pipe))] + = 0; + } + temp_hw_qtd_next = + QTD_NEXT(ehci, qtd->hw_next) & 0xFFFFFFFE; + } else if (urb->use_iram && usb_pipein(urb->pipe)) { + if (urb->transfer_buffer == NULL) { + memcpy(phys_to_virt(urb->transfer_dma) + + qtd->buffer_offset, + ehci-> + iram_buffer_v[address_to_buffer + (ehci, + usb_pipedevice + (urb->pipe))] + + g_iram_size, min(g_iram_size, + qtd->length)); + } else { + memcpy(urb->transfer_buffer + + qtd->buffer_offset, + ehci-> + iram_buffer_v[address_to_buffer + (ehci, + usb_pipedevice + (urb->pipe))] + + g_iram_size, min(g_iram_size, + qtd->length)); + } + temp_hw_qtd_next = + QTD_NEXT(ehci, qtd->hw_next) & 0xFFFFFFFE; + } + /* stop scanning when we reach qtds the hc is using */ + } else if (likely(!stopped + && HC_IS_RUNNING(ehci_to_hcd(ehci)->state))) { + break; + + /* scan the whole queue for unlinks whenever it stops */ + } else { + stopped = 1; + + /* cancel everything if we halt, suspend, etc */ + if (!HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) + last_status = -ESHUTDOWN; + + /* this qtd is active; skip it unless a previous qtd + * for its urb faulted, or its urb was canceled. + */ + else if (last_status == -EINPROGRESS && !urb->unlinked) + continue; + + /* qh unlinked; token in overlay may be most current */ + if (state == QH_STATE_IDLE + && cpu_to_hc32(ehci, qtd->qtd_dma) + == qh->hw_current) + token = hc32_to_cpu(ehci, qh->hw_token); + + /* qh unlinked; token in overlay may be most current */ + if (state == QH_STATE_IDLE + && cpu_to_hc32(ehci, qtd->qtd_dma) + == qh->hw_current) + token = hc32_to_cpu(ehci, qh->hw_token); + + /* force halt for unlinked or blocked qh, so we'll + * patch the qh later and so that completions can't + * activate it while we "know" it's stopped. + */ + if ((halt & qh->hw_token) == 0) { +halt: + qh->hw_token |= halt; + wmb(); + } + } + + /* unless we already know the urb's status, collect qtd status + * and update count of bytes transferred. in common short read + * cases with only one data qtd (including control transfers), + * queue processing won't halt. but with two or more qtds (for + * example, with a 32 KB transfer), when the first qtd gets a + * short read the second must be removed by hand. + */ + if (last_status == -EINPROGRESS) { + last_status = qtd_copy_status(ehci, urb, + qtd->length, token); + if (last_status == -EREMOTEIO + && (qtd->hw_alt_next + & EHCI_LIST_END(ehci))) + last_status = -EINPROGRESS; + } + + /* if we're removing something not at the queue head, + * patch the hardware queue pointer. + */ + + if (stopped && qtd->qtd_list.prev != &qh->qtd_list) { + last = list_entry(qtd->qtd_list.prev, + struct ehci_qtd, qtd_list); + last->hw_next = qtd->hw_next; + } + +/* remove qtd; it's recycled after possible urb completion */ + list_del(&qtd->qtd_list); + last = qtd; + } + + /* last urb's completion might still need calling */ + if (likely(last != NULL)) { + ehci_urb_done(ehci, last->urb, last_status); + count++; + ehci_qtd_free(ehci, last); + } + + /* restore original state; caller must unlink or relink */ + qh->qh_state = state; + + /* be sure the hardware's done with the qh before refreshing + * it after fault cleanup, or recovering from silicon wrongly + * overlaying the dummy qtd (which reduces DMA chatter). + */ + if ((stopped != 0) || (qh->hw_qtd_next == EHCI_LIST_END(ehci)) + && (temp_hw_qtd_next == 0)) { + switch (state) { + case QH_STATE_IDLE: + qh_refresh(ehci, qh); + break; + case QH_STATE_LINKED: + /* We won't refresh a QH that's linked (after the HC + * stopped the queue). That avoids a race: + * - HC reads first part of QH; + * - CPU updates that first part and the token; + * - HC reads rest of that QH, including token + * Result: HC gets an inconsistent image, and then + * DMAs to/from the wrong memory (corrupting it). + * + * That should be rare for interrupt transfers, + * except maybe high bandwidth ... + */ + if ((cpu_to_hc32(ehci, QH_SMASK) + & qh->hw_info2) != 0) { + intr_deschedule(ehci, qh); + (void)qh_schedule(ehci, qh); + } else + unlink_async(ehci, qh); + break; + /* otherwise, unlink already started */ + } + } + if (temp_hw_qtd_next) + qh->hw_qtd_next = temp_hw_qtd_next; + + return count; +} + +/*-------------------------------------------------------------------------*/ + +/* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */ +#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03)) +/* ... and packet size, for any kind of endpoint descriptor */ +#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff) + +/* + * reverse of qh_urb_transaction: free a list of TDs. + * used for cleanup after errors, before HC sees an URB's TDs. + */ +static void qtd_list_free(struct ehci_hcd *ehci, + struct urb *urb, struct list_head *qtd_list) +{ + struct list_head *entry, *temp; + + list_for_each_safe(entry, temp, qtd_list) { + struct ehci_qtd *qtd; + + qtd = list_entry(entry, struct ehci_qtd, qtd_list); + list_del(&qtd->qtd_list); + ehci_qtd_free(ehci, qtd); + } +} + +/* + * create a list of filled qtds for this URB; won't link into qh. + */ +static struct list_head *qh_urb_transaction(struct ehci_hcd *ehci, + struct urb *urb, + struct list_head *head, gfp_t flags) +{ + struct ehci_qtd *qtd, *qtd_prev; + dma_addr_t buf; + int len, maxpacket; + int is_input; + u32 token; + + /* + * URBs map to sequences of QTDs: one logical transaction + */ + qtd = ehci_qtd_alloc(ehci, flags); + if (unlikely(!qtd)) + return NULL; + list_add_tail(&qtd->qtd_list, head); + qtd->urb = urb; + + token = QTD_STS_ACTIVE; + token |= (EHCI_TUNE_CERR << 10); + /* for split transactions, SplitXState initialized to zero */ + + len = urb->transfer_buffer_length; + is_input = usb_pipein(urb->pipe); + if (usb_pipecontrol(urb->pipe)) { + /* SETUP pid */ + qtd_fill(ehci, qtd, urb->setup_dma, + sizeof(struct usb_ctrlrequest), + token | (2 /* "setup" */ << 8), 8); + + /* ... and always at least one more pid */ + token ^= QTD_TOGGLE; + qtd_prev = qtd; + qtd = ehci_qtd_alloc(ehci, flags); + if (unlikely(!qtd)) + goto cleanup; + qtd->urb = urb; + qtd_prev->hw_next = QTD_NEXT(ehci, qtd->qtd_dma); + list_add_tail(&qtd->qtd_list, head); + + /* for zero length DATA stages, STATUS is always IN */ + if (len == 0) + token |= (1 /* "in" */ << 8); + } + + /* + * data transfer stage: buffer setup + */ + buf = urb->transfer_dma; + + if (is_input) + token |= (1 /* "in" */ << 8); + /* else it's already initted to "out" pid (0 << 8) */ + + maxpacket = max_packet(usb_maxpacket(urb->dev, urb->pipe, !is_input)); + + /* + * buffer gets wrapped in one or more qtds; + * last one may be "short" (including zero len) + * and may serve as a control status ack + */ + for (;;) { + int this_qtd_len; + this_qtd_len = qtd_fill(ehci, qtd, buf, len, token, maxpacket); + if (urb->use_iram && (!qtd->buffer_offset) + && usb_pipeout(urb->pipe) + && (ehci-> + iram_in_use[address_to_buffer + (ehci, usb_pipedevice(urb->pipe))] == 0)) { + ehci-> + iram_in_use[address_to_buffer + (ehci, usb_pipedevice(urb->pipe))] = 1; + if (urb->transfer_buffer == NULL) { + memcpy(ehci-> + iram_buffer_v[address_to_buffer + (ehci, + usb_pipedevice(urb-> + pipe))], + phys_to_virt(urb->transfer_dma), + min((int)g_iram_size, len)); + } else { + memcpy(ehci-> + iram_buffer_v[address_to_buffer + (ehci, + usb_pipedevice(urb-> + pipe))], + urb->transfer_buffer, + min((int)g_iram_size, len)); + } + } + len -= this_qtd_len; + buf += this_qtd_len; + + /* + * short reads advance to a "magic" dummy instead of the next + * qtd ... that forces the queue to stop, for manual cleanup. + * (this will usually be overridden later.) + */ + if (is_input) + qtd->hw_alt_next = ehci->async->hw_alt_next; + + /* qh makes control packets use qtd toggle; maybe switch it */ + if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0) + token ^= QTD_TOGGLE; + + if (likely(len <= 0)) { + qtd->last_one = 1; + break; + } + qtd_prev = qtd; + qtd = ehci_qtd_alloc(ehci, flags); + if (unlikely(!qtd)) + goto cleanup; + qtd->urb = urb; + if (urb->use_iram) + qtd_prev->hw_next = QTD_NEXT(ehci, qtd->qtd_dma) | 0x1; + else + qtd_prev->hw_next = QTD_NEXT(ehci, qtd->qtd_dma); + + list_add_tail(&qtd->qtd_list, head); + } + + /* + * unless the caller requires manual cleanup after short reads, + * have the alt_next mechanism keep the queue running after the + * last data qtd (the only one, for control and most other cases). + */ + if (likely((urb->transfer_flags & URB_SHORT_NOT_OK) == 0 + || usb_pipecontrol(urb->pipe))) + qtd->hw_alt_next = EHCI_LIST_END(ehci); + + /* + * control requests may need a terminating data "status" ack; + * bulk ones may need a terminating short packet (zero length). + */ + if (likely(urb->transfer_buffer_length != 0)) { + int one_more = 0; + + if (usb_pipecontrol(urb->pipe)) { + one_more = 1; + token ^= 0x0100; /* "in" <--> "out" */ + token |= QTD_TOGGLE; /* force DATA1 */ + } else if (usb_pipebulk(urb->pipe) + && (urb->transfer_flags & URB_ZERO_PACKET) + && !(urb->transfer_buffer_length % maxpacket)) + one_more = 1; + if (one_more) { + qtd_prev = qtd; + qtd = ehci_qtd_alloc(ehci, flags); + if (unlikely(!qtd)) + goto cleanup; + qtd->urb = urb; + qtd_prev->hw_next = QTD_NEXT(ehci, qtd->qtd_dma); + list_add_tail(&qtd->qtd_list, head); + + /* never any data in such packets */ + qtd_fill(ehci, qtd, 0, 0, token, 0); + } + } + + /* by default, enable interrupt on urb completion */ + if (likely(!(urb->transfer_flags & URB_NO_INTERRUPT))) + qtd->hw_token |= cpu_to_hc32(ehci, QTD_IOC); + return head; + +cleanup: + qtd_list_free(ehci, urb, head); + return NULL; +} + +/*-------------------------------------------------------------------------*/ + +/* Would be best to create all qh's from config descriptors, + * when each interface/altsetting is established. Unlink + * any previous qh and cancel its urbs first; endpoints are + * implicitly reset then (data toggle too). + * That'd mean updating how usbcore talks to HCDs. (2.7?) + */ + +/* + * Each QH holds a qtd list; a QH is used for everything except iso. + * + * For interrupt urbs, the scheduler must set the microframe scheduling + * mask(s) each time the QH gets scheduled. For highspeed, that's + * just one microframe in the s-mask. For split interrupt transactions + * there are additional complications: c-mask, maybe FSTNs. + */ +static struct ehci_qh *qh_make(struct ehci_hcd *ehci, + struct urb *urb, gfp_t flags) +{ + struct ehci_qh *qh = ehci_qh_alloc(ehci, flags); + u32 info1 = 0, info2 = 0; + int is_input, type; + int maxp = 0; + struct usb_tt *tt = urb->dev->tt; + + if (!qh) + return qh; + + /* + * init endpoint/device data for this QH + */ + info1 |= usb_pipeendpoint(urb->pipe) << 8; + info1 |= usb_pipedevice(urb->pipe) << 0; + + is_input = usb_pipein(urb->pipe); + type = usb_pipetype(urb->pipe); + maxp = usb_maxpacket(urb->dev, urb->pipe, !is_input); + + /* 1024 byte maxpacket is a hardware ceiling. High bandwidth + * acts like up to 3KB, but is built from smaller packets. + */ + if (max_packet(maxp) > 1024) { + ehci_dbg(ehci, "bogus qh maxpacket %d\n", max_packet(maxp)); + goto done; + } + + /* Compute interrupt scheduling parameters just once, and save. + * - allowing for high bandwidth, how many nsec/uframe are used? + * - split transactions need a second CSPLIT uframe; same question + * - splits also need a schedule gap (for full/low speed I/O) + * - qh has a polling interval + * + * For control/bulk requests, the HC or TT handles these. + */ + if (type == PIPE_INTERRUPT) { + qh->usecs = + NS_TO_US(usb_calc_bus_time + (USB_SPEED_HIGH, is_input, 0, + hb_mult(maxp) * max_packet(maxp))); + qh->start = NO_FRAME; + + if (urb->dev->speed == USB_SPEED_HIGH) { + qh->c_usecs = 0; + qh->gap_uf = 0; + + qh->period = urb->interval >> 3; + if (qh->period == 0 && urb->interval != 1) { + /* NOTE interval 2 or 4 uframes could work. + * But interval 1 scheduling is simpler, and + * includes high bandwidth. + */ + dbg("intr period %d uframes, NYET!", + urb->interval); + goto done; + } + } else { + int think_time; + + /* gap is f(FS/LS transfer times) */ + qh->gap_uf = 1 + usb_calc_bus_time(urb->dev->speed, + is_input, 0, + maxp) / (125 * 1000); + + /* FIXME this just approximates SPLIT/CSPLIT times */ + if (is_input) { + qh->c_usecs = qh->usecs + HS_USECS(0); + qh->usecs = HS_USECS(1); + } else { + qh->usecs += HS_USECS(1); + qh->c_usecs = HS_USECS(0); + } + + think_time = tt ? tt->think_time : 0; + qh->tt_usecs = NS_TO_US(think_time + + usb_calc_bus_time(urb->dev-> + speed, + is_input, 0, + max_packet + (maxp))); + qh->period = urb->interval; + } + } + + /* support for tt scheduling, and access to toggles */ + qh->dev = urb->dev; + + /* using TT? */ + switch (urb->dev->speed) { + case USB_SPEED_LOW: + info1 |= (1 << 12); /* EPS "low" */ + /* FALL THROUGH */ + + case USB_SPEED_FULL: + /* EPS 0 means "full" */ + if (type != PIPE_INTERRUPT) + info1 |= (EHCI_TUNE_RL_TT << 28); + if (type == PIPE_CONTROL) { + info1 |= (1 << 27); /* for TT */ + info1 |= 1 << 14; /* toggle from qtd */ + } + info1 |= maxp << 16; + + info2 |= (EHCI_TUNE_MULT_TT << 30); + + /* Some Freescale processors have an erratum in which the + * port number in the queue head was 0..N-1 instead of 1..N. + */ + if (ehci_has_fsl_portno_bug(ehci)) + info2 |= (urb->dev->ttport - 1) << 23; + else + info2 |= urb->dev->ttport << 23; + + /* set the address of the TT; for TDI's integrated + * root hub tt, leave it zeroed. + */ + if (tt && tt->hub != ehci_to_hcd(ehci)->self.root_hub) + info2 |= tt->hub->devnum << 16; + + /* NOTE: if (PIPE_INTERRUPT) { scheduler sets c-mask } */ + + break; + + case USB_SPEED_HIGH: /* no TT involved */ + info1 |= (2 << 12); /* EPS "high" */ + if (type == PIPE_CONTROL) { + info1 |= (EHCI_TUNE_RL_HS << 28); + info1 |= 64 << 16; /* usb2 fixed maxpacket */ + info1 |= 1 << 14; /* toggle from qtd */ + info2 |= (EHCI_TUNE_MULT_HS << 30); + } else if (type == PIPE_BULK) { + info1 |= (EHCI_TUNE_RL_HS << 28); + /* The USB spec says that high speed bulk endpoints + * always use 512 byte maxpacket. But some device + * vendors decided to ignore that, and MSFT is happy + * to help them do so. So now people expect to use + * such nonconformant devices with Linux too; sigh. + */ + info1 |= max_packet(maxp) << 16; + info2 |= (EHCI_TUNE_MULT_HS << 30); + use_buffer(ehci, usb_pipedevice(urb->pipe)); + } else { /* PIPE_INTERRUPT */ + info1 |= max_packet(maxp) << 16; + info2 |= hb_mult(maxp) << 30; + } + break; + default: + dbg("bogus dev %p speed %d", urb->dev, urb->dev->speed); +done: + qh_put(qh); + return NULL; + } + + /* NOTE: if (PIPE_INTERRUPT) { scheduler sets s-mask } */ + + /* init as live, toggle clear, advance to dummy */ + qh->qh_state = QH_STATE_IDLE; + qh->hw_info1 = cpu_to_hc32(ehci, info1); + qh->hw_info2 = cpu_to_hc32(ehci, info2); + usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), !is_input, 1); + qh_refresh(ehci, qh); + return qh; +} + +/*-------------------------------------------------------------------------*/ + +/* move qh (and its qtds) onto async queue; maybe enable queue. */ + +static void qh_link_async(struct ehci_hcd *ehci, struct ehci_qh *qh) +{ + __hc32 dma = QH_NEXT(ehci, qh->qh_dma); + struct ehci_qh *head; + + /* (re)start the async schedule? */ + head = ehci->async; + timer_action_done(ehci, TIMER_ASYNC_OFF); + if (!head->qh_next.qh) { + u32 cmd = ehci_readl(ehci, &ehci->regs->command); + + if (!(cmd & CMD_ASE)) { + /* in case a clear of CMD_ASE didn't take yet */ + (void)handshake(ehci, &ehci->regs->status, + STS_ASS, 0, 150); + cmd |= CMD_ASE | CMD_RUN; + ehci_writel(ehci, cmd, &ehci->regs->command); + ehci_to_hcd(ehci)->state = HC_STATE_RUNNING; + /* posted write need not be known to HC yet ... */ + } + } + + /* clear halt and/or toggle; and maybe recover from silicon quirk */ + if (qh->qh_state == QH_STATE_IDLE) + qh_refresh(ehci, qh); + + /* splice right after start */ + qh->qh_next = head->qh_next; + qh->hw_next = head->hw_next; + wmb(); + + head->qh_next.qh = qh; + head->hw_next = dma; + + qh->qh_state = QH_STATE_LINKED; + /* qtd completions reported later by interrupt */ +} + +/*-------------------------------------------------------------------------*/ + +/* + * For control/bulk/interrupt, return QH with these TDs appended. + * Allocates and initializes the QH if necessary. + * Returns null if it can't allocate a QH it needs to. + * If the QH has TDs (urbs) already, that's great. + */ +static struct ehci_qh *qh_append_tds(struct ehci_hcd *ehci, + struct urb *urb, + struct list_head *qtd_list, + int epnum, void **ptr) +{ + struct ehci_qh *qh = NULL; + __hc32 qh_addr_mask = cpu_to_hc32(ehci, 0x7f); + + qh = (struct ehci_qh *)*ptr; + if (unlikely(qh == NULL)) { + /* can't sleep here, we have ehci->lock... */ + qh = qh_make(ehci, urb, GFP_ATOMIC); + *ptr = qh; + } + if (likely(qh != NULL)) { + struct ehci_qtd *qtd; + + if (unlikely(list_empty(qtd_list))) + qtd = NULL; + else + qtd = list_entry(qtd_list->next, struct ehci_qtd, + qtd_list); + + /* control qh may need patching ... */ + if (unlikely(epnum == 0)) { + + /* usb_reset_device() briefly reverts to address 0 */ + if (usb_pipedevice(urb->pipe) == 0) + qh->hw_info1 &= ~qh_addr_mask; + } + + /* just one way to queue requests: swap with the dummy qtd. + * only hc or qh_refresh() ever modify the overlay. + */ + if (likely(qtd != NULL)) { + struct ehci_qtd *dummy; + dma_addr_t dma; + __hc32 token; + + /* to avoid racing the HC, use the dummy td instead of + * the first td of our list (becomes new dummy). both + * tds stay deactivated until we're done, when the + * HC is allowed to fetch the old dummy (4.10.2). + */ + token = qtd->hw_token; + qtd->hw_token = HALT_BIT(ehci); + wmb(); + dummy = qh->dummy; + + dma = dummy->qtd_dma; + *dummy = *qtd; + dummy->qtd_dma = dma; + + list_del(&qtd->qtd_list); + list_add(&dummy->qtd_list, qtd_list); + __list_splice(qtd_list, qh->qtd_list.prev); + + ehci_qtd_init(ehci, qtd, qtd->qtd_dma); + qh->dummy = qtd; + + /* hc must see the new dummy at list end */ + dma = qtd->qtd_dma; + qtd = list_entry(qh->qtd_list.prev, + struct ehci_qtd, qtd_list); + if (urb->use_iram) + qtd->hw_next = QTD_NEXT(ehci, dma) | 0x1; + else + qtd->hw_next = QTD_NEXT(ehci, dma); + + /* let the hc process these next qtds */ + wmb(); + dummy->hw_token = token; + + urb->hcpriv = qh_get(qh); + } + } + return qh; +} + +/*-------------------------------------------------------------------------*/ + +static int +submit_async(struct ehci_hcd *ehci, + struct urb *urb, struct list_head *qtd_list, gfp_t mem_flags) +{ + struct ehci_qtd *qtd; + int epnum; + unsigned long flags; + struct ehci_qh *qh = NULL; + int rc; + + qtd = list_entry(qtd_list->next, struct ehci_qtd, qtd_list); + epnum = urb->ep->desc.bEndpointAddress; + +#ifdef EHCI_URB_TRACE + ehci_dbg(ehci, + "%s %s urb %p ep%d%s len %d, qtd %p [qh %p]\n", + __func__, urb->dev->devpath, urb, + epnum & 0x0f, (epnum & USB_DIR_IN) ? "in" : "out", + urb->transfer_buffer_length, qtd, urb->ep->hcpriv); +#endif + + spin_lock_irqsave(&ehci->lock, flags); + if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, + &ehci_to_hcd(ehci)->flags))) { + rc = -ESHUTDOWN; + goto done; + } + rc = usb_hcd_link_urb_to_ep(ehci_to_hcd(ehci), urb); + if (unlikely(rc)) + goto done; + + qh = qh_append_tds(ehci, urb, qtd_list, epnum, &urb->ep->hcpriv); + if (unlikely(qh == NULL)) { + usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); + rc = -ENOMEM; + goto done; + } + + /* Control/bulk operations through TTs don't need scheduling, + * the HC and TT handle it when the TT has a buffer ready. + */ + if (likely(qh->qh_state == QH_STATE_IDLE)) + qh_link_async(ehci, qh_get(qh)); +done: + spin_unlock_irqrestore(&ehci->lock, flags); + if (unlikely(qh == NULL)) + qtd_list_free(ehci, urb, qtd_list); + return rc; +} + +/*-------------------------------------------------------------------------*/ + +/* the async qh for the qtds being reclaimed are now unlinked from the HC */ + +static void end_unlink_async(struct ehci_hcd *ehci) +{ + struct ehci_qh *qh = ehci->reclaim; + struct ehci_qh *next; + + iaa_watchdog_done(ehci); + + qh->qh_state = QH_STATE_IDLE; + qh->qh_next.qh = NULL; + qh_put(qh); /* refcount from reclaim */ + + /* other unlink(s) may be pending (in QH_STATE_UNLINK_WAIT) */ + next = qh->reclaim; + ehci->reclaim = next; + qh->reclaim = NULL; + + qh_completions(ehci, qh); + + if (!list_empty(&qh->qtd_list) + && HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) + qh_link_async(ehci, qh); + else { + qh_put(qh); /* refcount from async list */ + + /* it's not free to turn the async schedule on/off; leave it + * active but idle for a while once it empties. + */ + if (HC_IS_RUNNING(ehci_to_hcd(ehci)->state) + && ehci->async->qh_next.qh == NULL) + timer_action(ehci, TIMER_ASYNC_OFF); + } + + if (next) { + ehci->reclaim = NULL; + start_unlink_async(ehci, next); + } +} + +/* makes sure the async qh will become idle */ +/* caller must own ehci->lock */ + +static void start_unlink_async(struct ehci_hcd *ehci, struct ehci_qh *qh) +{ + int cmd = ehci_readl(ehci, &ehci->regs->command); + struct ehci_qh *prev; + +#ifdef DEBUG + assert_spin_locked(&ehci->lock); + if (ehci->reclaim + || (qh->qh_state != QH_STATE_LINKED + && qh->qh_state != QH_STATE_UNLINK_WAIT) + ) + BUG(); +#endif + + /* stop async schedule right now? */ + if (unlikely(qh == ehci->async)) { + /* can't get here without STS_ASS set */ + if (ehci_to_hcd(ehci)->state != HC_STATE_HALT && + !ehci->reclaim) { + /* ... and CMD_IAAD clear */ + ehci_writel(ehci, cmd & ~CMD_ASE, &ehci->regs->command); + wmb(); + /* handshake later, if we need to */ + timer_action_done(ehci, TIMER_ASYNC_OFF); + } + return; + } + + qh->qh_state = QH_STATE_UNLINK; + ehci->reclaim = qh = qh_get(qh); + + prev = ehci->async; + while (prev->qh_next.qh != qh) + prev = prev->qh_next.qh; + + prev->hw_next = qh->hw_next; + prev->qh_next = qh->qh_next; + wmb(); + + if (unlikely(ehci_to_hcd(ehci)->state == HC_STATE_HALT)) { + /* if (unlikely (qh->reclaim != 0)) + * this will recurse, probably not much + */ + end_unlink_async(ehci); + return; + } + + cmd |= CMD_IAAD; + ehci_writel(ehci, cmd, &ehci->regs->command); + (void)ehci_readl(ehci, &ehci->regs->command); + iaa_watchdog_start(ehci); +} + +/*-------------------------------------------------------------------------*/ + +static void scan_async(struct ehci_hcd *ehci) +{ + struct ehci_qh *qh; + enum ehci_timer_action action = TIMER_IO_WATCHDOG; + + if (!++(ehci->stamp)) + ehci->stamp++; + timer_action_done(ehci, TIMER_ASYNC_SHRINK); +rescan: + qh = ehci->async->qh_next.qh; + if (likely(qh != NULL)) { + do { + /* clean any finished work for this qh */ + if (!list_empty(&qh->qtd_list) + && qh->stamp != ehci->stamp) { + int temp; + + /* unlinks could happen here; completion + * reporting drops the lock. rescan using + * the latest schedule, but don't rescan + * qhs we already finished (no looping). + */ + qh = qh_get(qh); + qh->stamp = ehci->stamp; + temp = qh_completions(ehci, qh); + qh_put(qh); + if (temp != 0) + goto rescan; + } + + /* unlink idle entries, reducing HC PCI usage as well + * as HCD schedule-scanning costs. delay for any qh + * we just scanned, there's a not-unusual case that it + * doesn't stay idle for long. + * (plus, avoids some kind of re-activation race.) + */ + if (list_empty(&qh->qtd_list)) { + if (qh->stamp == ehci->stamp) + action = TIMER_ASYNC_SHRINK; + else if (!ehci->reclaim + && qh->qh_state == QH_STATE_LINKED) + start_unlink_async(ehci, qh); + } + + qh = qh->qh_next.qh; + } while (qh); + } + if (action == TIMER_ASYNC_SHRINK) + timer_action(ehci, TIMER_ASYNC_SHRINK); +} --- linux-2.6.28.orig/drivers/usb/host/ehci-hcd.c +++ linux-2.6.28/drivers/usb/host/ehci-hcd.c @@ -253,8 +253,13 @@ static void ehci_work(struct ehci_hcd *ehci); #include "ehci-hub.c" +#ifdef CONFIG_USB_STATIC_IRAM +#include "ehci-mem-iram.c" +#include "ehci-q-iram.c" +#else #include "ehci-mem.c" #include "ehci-q.c" +#endif #include "ehci-sched.c" /*-------------------------------------------------------------------------*/ @@ -485,6 +490,7 @@ * periodic_size can shrink by USBCMD update if hcc_params allows. */ ehci->periodic_size = DEFAULT_I_TDPS; + INIT_LIST_HEAD(&ehci->cached_itd_list); if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0) return retval; @@ -497,6 +503,7 @@ ehci->reclaim = NULL; ehci->next_uframe = -1; + ehci->clock_frame = -1; /* * dedicate a qh for the async ring head, since we couldn't unlink @@ -1014,6 +1021,11 @@ #define PLATFORM_DRIVER ehci_hcd_au1xxx_driver #endif +#ifdef CONFIG_USB_EHCI_ARC +#include "ehci-arc.c" +#define PLATFORM_DRIVER ehci_fsl_driver +#endif + #ifdef CONFIG_PPC_PS3 #include "ehci-ps3.c" #define PS3_SYSTEM_BUS_DRIVER ps3_ehci_driver --- linux-2.6.28.orig/drivers/usb/host/ehci-mem.c +++ linux-2.6.28/drivers/usb/host/ehci-mem.c @@ -128,6 +128,7 @@ static void ehci_mem_cleanup (struct ehci_hcd *ehci) { + free_cached_itd_list(ehci); if (ehci->async) qh_put (ehci->async); ehci->async = NULL; --- linux-2.6.28.orig/drivers/usb/host/ehci-arc.c +++ linux-2.6.28/drivers/usb/host/ehci-arc.c @@ -0,0 +1,597 @@ +/* + * (C) Copyright David Brownell 2000-2002 + * Copyright (c) 2005 MontaVista Software + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the 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. + * + * Ported to 834x by Randy Vinson using code provided + * by Hunter Wu. + */ + +#include +#include +#include +#include + +#include "ehci-fsl.h" + +extern struct resource *otg_get_resources(void); + +#undef EHCI_PROC_PTC +#ifdef EHCI_PROC_PTC /* /proc PORTSC:PTC support */ +/* + * write a PORTSC:PTC value to /proc/driver/ehci-ptc + * to put the controller into test mode. + */ +#include +#include +#define EFPSL 3 /* ehci fsl proc string length */ + +static int ehci_fsl_proc_read(char *page, char **start, off_t off, int count, + int *eof, void *data) +{ + return 0; +} + +static int ehci_fsl_proc_write(struct file *file, const char __user *buffer, + unsigned long count, void *data) +{ + int ptc; + u32 portsc; + struct ehci_hcd *ehci = (struct ehci_hcd *) data; + char str[EFPSL] = {0}; + + if (count > EFPSL-1) + return -EINVAL; + + if (copy_from_user(str, buffer, count)) + return -EFAULT; + + str[count] = '\0'; + + ptc = simple_strtoul(str, NULL, 0); + + portsc = ehci_readl(ehci, &ehci->regs->port_status[0]); + portsc &= ~(0xf << 16); + portsc |= (ptc << 16); + printk(KERN_INFO "PTC %x portsc %08x\n", ptc, portsc); + + ehci_writel(ehci, portsc, &ehci->regs->port_status[0]); + + return count; +} + +static int ehci_testmode_init(struct ehci_hcd *ehci) +{ + struct proc_dir_entry *entry; + + entry = create_proc_read_entry("driver/ehci-ptc", 0644, NULL, + ehci_fsl_proc_read, ehci); + if (!entry) + return -ENODEV; + + entry->write_proc = ehci_fsl_proc_write; + return 0; +} +#else +static int ehci_testmode_init(struct ehci_hcd *ehci) +{ + return 0; +} +#endif /* /proc PORTSC:PTC support */ + + +/* PCI-based HCs are common, but plenty of non-PCI HCs are used too */ + +/* configure so an HC device and id are always provided */ +/* always called with process context; sleeping is OK */ + +/** + * usb_hcd_fsl_probe - initialize FSL-based HCDs + * @drvier: Driver to be used for this HCD + * @pdev: USB Host Controller being probed + * Context: !in_interrupt() + * + * Allocates basic resources for this USB host controller. + * + */ +static int usb_hcd_fsl_probe(const struct hc_driver *driver, + struct platform_device *pdev) +{ + struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; + struct usb_hcd *hcd; + struct resource *res; + int irq; + int retval; + unsigned int __maybe_unused temp; + + pr_debug("initializing FSL-SOC USB Controller\n"); + + /* Need platform data for setup */ + if (!pdata) { + dev_err(&pdev->dev, + "No platform data for %s.\n", pdev->dev.bus_id); + return -ENODEV; + } + + /* + * This is a host mode driver, verify that we're supposed to be + * in host mode. + */ + if (!((pdata->operating_mode == FSL_USB2_DR_HOST) || + (pdata->operating_mode == FSL_USB2_MPH_HOST) || + (pdata->operating_mode == FSL_USB2_DR_OTG))) { + dev_err(&pdev->dev, + "Non Host Mode configured for %s. " + "Wrong driver linked.\n", pdev->dev.bus_id); + return -ENODEV; + } + + hcd = usb_create_hcd(driver, &pdev->dev, pdev->dev.bus_id); + if (!hcd) { + retval = -ENOMEM; + goto err1; + } + +#if defined(CONFIG_USB_OTG) + if (pdata->operating_mode == FSL_USB2_DR_OTG) { + res = otg_get_resources(); + if (!res) { + dev_err(&pdev->dev, + "Found HC with no IRQ. Check %s setup!\n", + pdev->dev.bus_id); + return -ENODEV; + } + irq = res[1].start; + hcd->rsrc_start = res[0].start; + hcd->rsrc_len = res[0].end - res[0].start + 1; + } else +#endif + { + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res) { + dev_err(&pdev->dev, + "Found HC with no IRQ. Check %s setup!\n", + pdev->dev.bus_id); + return -ENODEV; + } + irq = res->start; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + hcd->rsrc_start = res->start; + hcd->rsrc_len = res->end - res->start + 1; + + if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, + driver->description)) { + dev_dbg(&pdev->dev, "controller already in use\n"); + retval = -EBUSY; + goto err2; + } + } + + hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); + + if (hcd->regs == NULL) { + dev_dbg(&pdev->dev, "error mapping memory\n"); + retval = -EFAULT; + goto err3; + } + pdata->regs = hcd->regs; + + /* + * do platform specific init: check the clock, grab/config pins, etc. + */ + if (pdata->platform_init && pdata->platform_init(pdev)) { + retval = -ENODEV; + goto err3; + } + + fsl_platform_set_host_mode(hcd); + hcd->power_budget = pdata->power_budget; + + retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); + if (retval != 0) + goto err4; + + fsl_platform_set_vbus_power(pdata, 1); + +#ifdef CONFIG_USB_OTG + if (pdata->operating_mode == FSL_USB2_DR_OTG) { + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + + dbg("pdev=0x%p hcd=0x%p ehci=0x%p\n", pdev, hcd, ehci); + + ehci->transceiver = otg_get_transceiver(); + dbg("ehci->transceiver=0x%p\n", ehci->transceiver); + + if (ehci->transceiver) { + retval = otg_set_host(ehci->transceiver, + &ehci_to_hcd(ehci)->self); + if (retval) { + if (ehci->transceiver) + put_device(ehci->transceiver->dev); + goto err4; + } + } else { + printk(KERN_ERR "can't find transceiver\n"); + retval = -ENODEV; + goto err4; + } + } +#endif + + fsl_platform_set_ahb_burst(hcd); + ehci_testmode_init(hcd_to_ehci(hcd)); + return retval; + +err4: + iounmap(hcd->regs); +err3: + if (pdata->operating_mode != FSL_USB2_DR_OTG) + release_mem_region(hcd->rsrc_start, hcd->rsrc_len); +err2: + usb_put_hcd(hcd); +err1: + dev_err(&pdev->dev, "init %s fail, %d\n", pdev->dev.bus_id, retval); + if (pdata->platform_uninit) + pdata->platform_uninit(pdata); + return retval; +} + +/* may be called without controller electrically present */ +/* may be called with controller, bus, and devices active */ + +/** + * usb_hcd_fsl_remove - shutdown processing for FSL-based HCDs + * @dev: USB Host Controller being removed + * Context: !in_interrupt() + * + * Reverses the effect of usb_hcd_fsl_probe(). + * + */ +static void usb_hcd_fsl_remove(struct usb_hcd *hcd, + struct platform_device *pdev) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; + + /* DDD shouldn't we turn off the power here? */ + fsl_platform_set_vbus_power(pdata, 0); + + if (ehci->transceiver) { + (void)otg_set_host(ehci->transceiver, 0); + put_device(ehci->transceiver->dev); + } else { + release_mem_region(hcd->rsrc_start, hcd->rsrc_len); + } + + usb_remove_hcd(hcd); + usb_put_hcd(hcd); + + /* + * do platform specific un-initialization: + * release iomux pins, etc. + */ + if (pdata->platform_uninit) + pdata->platform_uninit(pdata); + + iounmap(hcd->regs); +} + +static void fsl_setup_phy(struct ehci_hcd *ehci, + enum fsl_usb2_phy_modes phy_mode, int port_offset) +{ + u32 portsc; + + portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]); + portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW); + + switch (phy_mode) { + case FSL_USB2_PHY_ULPI: + portsc |= PORT_PTS_ULPI; + break; + case FSL_USB2_PHY_SERIAL: + portsc |= PORT_PTS_SERIAL; + break; + case FSL_USB2_PHY_UTMI_WIDE: + portsc |= PORT_PTS_PTW; + /* fall through */ + case FSL_USB2_PHY_UTMI: + portsc |= PORT_PTS_UTMI; + break; + case FSL_USB2_PHY_NONE: + break; + } + ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]); +} + +/* called after powerup, by probe or system-pm "wakeup" */ +static int ehci_fsl_reinit(struct ehci_hcd *ehci) +{ + fsl_platform_usb_setup(ehci); + ehci_port_power(ehci, 0); + return 0; +} + +/* called during probe() after chip reset completes */ +static int ehci_fsl_setup(struct usb_hcd *hcd) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + int retval; + struct fsl_usb2_platform_data *pdata; + pdata = hcd->self.controller->platform_data; + + ehci->big_endian_desc = pdata->big_endian_desc; + ehci->big_endian_mmio = pdata->big_endian_mmio; + + /* EHCI registers start at offset 0x100 */ + ehci->caps = hcd->regs + 0x100; + ehci->regs = hcd->regs + 0x100 + + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); + dbg_hcs_params(ehci, "reset"); + dbg_hcc_params(ehci, "reset"); + + /* cache this readonly data; minimize chip reads */ + ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); + + retval = ehci_halt(ehci); + + /* data structure init */ + retval = ehci_init(hcd); + if (retval) + return retval; + + hcd->has_tt = 1; + + ehci->sbrn = 0x20; + + ehci_reset(ehci); + + retval = ehci_fsl_reinit(ehci); + return retval; +} + +static const struct hc_driver ehci_fsl_hc_driver = { + .description = hcd_name, + .product_desc = "Freescale On-Chip EHCI Host Controller", + .hcd_priv_size = sizeof(struct ehci_hcd), + + /* + * generic hardware linkage + */ + .irq = ehci_irq, + .flags = FSL_PLATFORM_HC_FLAGS, + + /* + * basic lifecycle operations + */ + .reset = ehci_fsl_setup, + .start = ehci_run, + .stop = ehci_stop, + .shutdown = ehci_shutdown, + + /* + * managing i/o requests and associated device resources + */ + .urb_enqueue = ehci_urb_enqueue, + .urb_dequeue = ehci_urb_dequeue, + .endpoint_disable = ehci_endpoint_disable, + + /* + * scheduling support + */ + .get_frame_number = ehci_get_frame, + + /* + * root hub support + */ + .hub_status_data = ehci_hub_status_data, + .hub_control = ehci_hub_control, + .bus_suspend = ehci_bus_suspend, + .bus_resume = ehci_bus_resume, + .start_port_reset = ehci_start_port_reset, +}; + +static int ehci_fsl_drv_probe(struct platform_device *pdev) +{ + struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; + + if (usb_disabled()) + return -ENODEV; + + if (pdata->name[5] == '2') { + if (!machine_is_mx51_3ds()) + return usb_hcd_fsl_probe(&ehci_fsl_hc_driver, pdev); + } else + return usb_hcd_fsl_probe(&ehci_fsl_hc_driver, pdev); +} + +static int ehci_fsl_drv_remove(struct platform_device *pdev) +{ + struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; + struct usb_hcd *hcd = platform_get_drvdata(pdev); + + if (pdata->name[5] == '2') { + if (!machine_is_mx51_3ds()) + usb_hcd_fsl_remove(hcd, pdev); + } else + usb_hcd_fsl_remove(hcd, pdev); + return 0; +} + +static int ehci_fsl_drv_shutdown(struct platform_device *pdev) +{ + struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; + + if (pdata->name[5] == '2') { + if (!machine_is_mx51_3ds()) + usb_hcd_platform_shutdown(pdev); + } else + usb_hcd_platform_shutdown(pdev); +} + +#ifdef CONFIG_PM +/* suspend/resume, section 4.3 */ + +/* These routines rely on the bus (pci, platform, etc) + * to handle powerdown and wakeup, and currently also on + * transceivers that don't need any software attention to set up + * the right sort of wakeup. + * + * They're also used for turning on/off the port when doing OTG. + */ +static int ehci_fsl_drv_suspend(struct platform_device *pdev, + pm_message_t message) +{ + struct usb_hcd *hcd = platform_get_drvdata(pdev); + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + u32 tmp; + struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; + +#ifdef DEBUG + u32 mode = ehci_readl(ehci, hcd->regs + FSL_SOC_USB_USBMODE); + mode &= USBMODE_CM_MASK; + tmp = ehci_readl(ehci, hcd->regs + 0x140); /* usbcmd */ + + printk(KERN_DEBUG "%s('%s'): suspend=%d already_suspended=%d " + "mode=%d usbcmd %08x\n", __func__, pdata->name, + pdata->suspended, pdata->already_suspended, mode, tmp); +#endif + + /* + * If the controller is already suspended, then this must be a + * PM suspend. Remember this fact, so that we will leave the + * controller suspended at PM resume time. + */ + if (pdata->suspended) { + pr_debug("%s: already suspended, leaving early\n", __func__); + pdata->already_suspended = 1; + return 0; + } + + pr_debug("%s: suspending...\n", __func__); + + printk(KERN_INFO "USB Host suspended\n"); + + hcd->state = HC_STATE_SUSPENDED; + pdev->dev.power.power_state = PMSG_SUSPEND; + + /* ignore non-host interrupts */ + clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + + /* stop the controller */ + tmp = ehci_readl(ehci, &ehci->regs->command); + tmp &= ~CMD_RUN; + ehci_writel(ehci, tmp, &ehci->regs->command); + + /* save EHCI registers */ + pdata->pm_command = ehci_readl(ehci, &ehci->regs->command); + pdata->pm_command &= ~CMD_RUN; + pdata->pm_status = ehci_readl(ehci, &ehci->regs->status); + pdata->pm_intr_enable = ehci_readl(ehci, &ehci->regs->intr_enable); + pdata->pm_frame_index = ehci_readl(ehci, &ehci->regs->frame_index); + pdata->pm_segment = ehci_readl(ehci, &ehci->regs->segment); + pdata->pm_frame_list = ehci_readl(ehci, &ehci->regs->frame_list); + pdata->pm_async_next = ehci_readl(ehci, &ehci->regs->async_next); + pdata->pm_configured_flag = + ehci_readl(ehci, &ehci->regs->configured_flag); + pdata->pm_portsc = ehci_readl(ehci, &ehci->regs->port_status[0]); + + /* clear the W1C bits */ + pdata->pm_portsc &= cpu_to_hc32(ehci, ~PORT_RWC_BITS); + + pdata->suspended = 1; + + /* clear PP to cut power to the port */ + tmp = ehci_readl(ehci, &ehci->regs->port_status[0]); + tmp &= ~PORT_POWER; + ehci_writel(ehci, tmp, &ehci->regs->port_status[0]); + + return 0; +} + +static int ehci_fsl_drv_resume(struct platform_device *pdev) +{ + struct usb_hcd *hcd = platform_get_drvdata(pdev); + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + u32 tmp; + struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; + + printk(KERN_INFO "USB Host resumed\n"); + + pr_debug("%s('%s'): suspend=%d already_suspended=%d\n", __func__, + pdata->name, pdata->suspended, pdata->already_suspended); + + /* + * If the controller was already suspended at suspend time, + * then don't resume it now. + */ + if (pdata->already_suspended) { + pr_debug("already suspended, leaving early\n"); + pdata->already_suspended = 0; + return 0; + } + + if (!pdata->suspended) { + pr_debug("not suspended, leaving early\n"); + return 0; + } + + pdata->suspended = 0; + + pr_debug("%s resuming...\n", __func__); + + /* set host mode */ + fsl_platform_set_host_mode(hcd); + + /* restore EHCI registers */ + ehci_writel(ehci, pdata->pm_command, &ehci->regs->command); + ehci_writel(ehci, pdata->pm_intr_enable, &ehci->regs->intr_enable); + ehci_writel(ehci, pdata->pm_frame_index, &ehci->regs->frame_index); + ehci_writel(ehci, pdata->pm_segment, &ehci->regs->segment); + ehci_writel(ehci, pdata->pm_frame_list, &ehci->regs->frame_list); + ehci_writel(ehci, pdata->pm_async_next, &ehci->regs->async_next); + ehci_writel(ehci, pdata->pm_configured_flag, + &ehci->regs->configured_flag); + ehci_writel(ehci, pdata->pm_portsc, &ehci->regs->port_status[0]); + + set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + hcd->state = HC_STATE_RUNNING; + pdev->dev.power.power_state = PMSG_ON; + + tmp = ehci_readl(ehci, &ehci->regs->command); + tmp |= CMD_RUN; + ehci_writel(ehci, tmp, &ehci->regs->command); + + usb_hcd_resume_root_hub(hcd); + + return 0; +} +#endif /* CONFIG_USB_OTG */ + +MODULE_ALIAS("fsl-ehci"); + +static struct platform_driver ehci_fsl_driver = { + .probe = ehci_fsl_drv_probe, + .remove = ehci_fsl_drv_remove, + .shutdown = ehci_fsl_drv_shutdown, +#ifdef CONFIG_PM + .suspend = ehci_fsl_drv_suspend, + .resume = ehci_fsl_drv_resume, +#endif + .driver = { + .name = "fsl-ehci", + }, +}; --- linux-2.6.28.orig/drivers/usb/host/ehci-fsl.h +++ linux-2.6.28/drivers/usb/host/ehci-fsl.h @@ -19,6 +19,9 @@ #define _EHCI_FSL_H /* offsets for the non-ehci registers in the FSL SOC USB controller */ +#define FSL_SOC_USB_SBUSCFG 0x90 +#define FSL_SOC_USB_BURSTSIZE 0x160 +#define FSL_SOC_USB_TXFILLTUNING 0x164 #define FSL_SOC_USB_ULPIVP 0x170 #define FSL_SOC_USB_PORTSC1 0x184 #define PORT_PTS_MSK (3<<30) @@ -26,8 +29,12 @@ #define PORT_PTS_ULPI (2<<30) #define PORT_PTS_SERIAL (3<<30) #define PORT_PTS_PTW (1<<28) +#define PORT_PTS_PHCD (1<<23) #define FSL_SOC_USB_PORTSC2 0x188 #define FSL_SOC_USB_USBMODE 0x1a8 +#define USBMODE_CM_HOST (3 << 0) /* controller mode: host */ +#define USBMODE_ES (1 << 2) /* (Big) Endian Select */ + #define FSL_SOC_USB_SNOOP1 0x400 /* NOTE: big-endian */ #define FSL_SOC_USB_SNOOP2 0x404 /* NOTE: big-endian */ #define FSL_SOC_USB_AGECNTTHRSH 0x408 /* NOTE: big-endian */ @@ -35,4 +42,11 @@ #define FSL_SOC_USB_SICTRL 0x410 /* NOTE: big-endian */ #define FSL_SOC_USB_CTRL 0x500 /* NOTE: big-endian */ #define SNOOP_SIZE_2GB 0x1e + +#ifdef CONFIG_ARCH_MXC +#include +#elif CONFIG_PPC32 +#include +#endif + #endif /* _EHCI_FSL_H */ --- linux-2.6.28.orig/drivers/usb/mon/mon_bin.c +++ linux-2.6.28/drivers/usb/mon/mon_bin.c @@ -37,6 +37,7 @@ #define MON_IOCX_GET _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get) #define MON_IOCX_MFETCH _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch) #define MON_IOCH_MFLUSH _IO(MON_IOC_MAGIC, 8) + #ifdef CONFIG_COMPAT #define MON_IOCX_GET32 _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get32) #define MON_IOCX_MFETCH32 _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch32) @@ -921,21 +922,6 @@ } break; -#ifdef CONFIG_COMPAT - case MON_IOCX_GET32: { - struct mon_bin_get32 getb; - - if (copy_from_user(&getb, (void __user *)arg, - sizeof(struct mon_bin_get32))) - return -EFAULT; - - ret = mon_bin_get_event(file, rp, - compat_ptr(getb.hdr32), compat_ptr(getb.data32), - getb.alloc32); - } - break; -#endif - case MON_IOCX_MFETCH: { struct mon_bin_mfetch mfetch; @@ -962,7 +948,57 @@ } break; + case MON_IOCG_STATS: { + struct mon_bin_stats __user *sp; + unsigned int nevents; + unsigned int ndropped; + + spin_lock_irqsave(&rp->b_lock, flags); + ndropped = rp->cnt_lost; + rp->cnt_lost = 0; + spin_unlock_irqrestore(&rp->b_lock, flags); + nevents = mon_bin_queued(rp); + + sp = (struct mon_bin_stats __user *)arg; + if (put_user(rp->cnt_lost, &sp->dropped)) + return -EFAULT; + if (put_user(nevents, &sp->queued)) + return -EFAULT; + + } + break; + + default: + return -ENOTTY; + } + + return ret; +} + #ifdef CONFIG_COMPAT +static long mon_bin_compat_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct mon_reader_bin *rp = file->private_data; + int ret; + + switch (cmd) { + + case MON_IOCX_GET32: { + struct mon_bin_get32 getb; + + if (copy_from_user(&getb, (void __user *)arg, + sizeof(struct mon_bin_get32))) + return -EFAULT; + + ret = mon_bin_get_event(file, rp, + compat_ptr(getb.hdr32), compat_ptr(getb.data32), + getb.alloc32); + if (ret < 0) + return ret; + } + return 0; + case MON_IOCX_MFETCH32: { struct mon_bin_mfetch32 mfetch; @@ -986,37 +1022,25 @@ return ret; if (put_user(ret, &uptr->nfetch32)) return -EFAULT; - ret = 0; } - break; -#endif - - case MON_IOCG_STATS: { - struct mon_bin_stats __user *sp; - unsigned int nevents; - unsigned int ndropped; - - spin_lock_irqsave(&rp->b_lock, flags); - ndropped = rp->cnt_lost; - rp->cnt_lost = 0; - spin_unlock_irqrestore(&rp->b_lock, flags); - nevents = mon_bin_queued(rp); + return 0; - sp = (struct mon_bin_stats __user *)arg; - if (put_user(rp->cnt_lost, &sp->dropped)) - return -EFAULT; - if (put_user(nevents, &sp->queued)) - return -EFAULT; + case MON_IOCG_STATS: + return mon_bin_ioctl(NULL, file, cmd, + (unsigned long) compat_ptr(arg)); - } - break; + case MON_IOCQ_URB_LEN: + case MON_IOCQ_RING_SIZE: + case MON_IOCT_RING_SIZE: + case MON_IOCH_MFLUSH: + return mon_bin_ioctl(NULL, file, cmd, arg); default: - return -ENOTTY; + ; } - - return ret; + return -ENOTTY; } +#endif /* CONFIG_COMPAT */ static unsigned int mon_bin_poll(struct file *file, struct poll_table_struct *wait) @@ -1094,6 +1118,9 @@ /* .write = mon_text_write, */ .poll = mon_bin_poll, .ioctl = mon_bin_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = mon_bin_compat_ioctl, +#endif .release = mon_bin_release, .mmap = mon_bin_mmap, }; --- linux-2.6.28.orig/drivers/usb/misc/emi26.c +++ linux-2.6.28/drivers/usb/misc/emi26.c @@ -160,7 +160,7 @@ err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } - } while (i > 0); + } while (rec); /* Assert reset (stop the CPU in the EMI) */ err = emi26_set_reset(dev,1); --- linux-2.6.28.orig/drivers/w1/w1_family.h +++ linux-2.6.28/drivers/w1/w1_family.h @@ -34,6 +34,7 @@ #define W1_EEPROM_DS2433 0x23 #define W1_THERM_DS18B20 0x28 #define W1_EEPROM_DS2431 0x2D +#define W1_FAMILY_DS2438 0x26 #define W1_FAMILY_DS2760 0x30 #define MAXNAMELEN 32 --- linux-2.6.28.orig/drivers/w1/slaves/w1_ds2438.h +++ linux-2.6.28/drivers/w1/slaves/w1_ds2438.h @@ -0,0 +1,119 @@ +/* + * Copyright 2008 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 __W1_DS2438_H__ +#define __W1_DS2438_H__ + +#include + +#include +#include +#include +#include +#include + +#define DS2438_DEV_NAME "ds2438-battery" + +#define DS2438_PAGE_SIZE 8 +#define DS2438_PAGE_NUM 8 + +#define DS2438_CONVERT_TEMP 0x44 +#define DS2438_CONVERT_VOLT 0xB4 +#define DS2438_WRITE_SCRATCHPAD 0x4E +#define DS2438_COPY_SCRATCHPAD 0x48 +#define DS2438_RECALL_MEMORY 0xB8 + +enum DS2438_PAGE { + PAGE0_CONTROL = 0, + PAGE1_ETM, + PAGE2_STAMP, + PAGE3_RESV3, + PAGE4_RESV4, + PAGE5_RESV5, + PAGE6_RESV6, + PAGE7_CCA, +}; + +enum DS2438_REG { + /* PAGE 0 */ + PAGE0_STAT_CTRL = 0, + PAGE0_TEMP_LSB = 1, + PAGE0_TEMP_MSB = 2, + PAGE0_VOLTAGE_LSB = 3, + PAGE0_VOLTAGE_MSB = 4, + PAGE0_CURRENT_LSB = 5, + PAGE0_CURRENT_MSB = 6, + PAGE0_THRESHOLD = 7, + + /* PAGE 1 */ + PAGE1_ETM_BYTE0 = 0, + PAGE1_ETM_BYTE1 = 1, + PAGE1_ETM_BYTE2 = 2, + PAGE1_ETM_BYTE3 = 3, + PAGE1_ICA = 4, + PAGE1_OFFSET_LSB = 5, + PAGE1_OFFSET_MSB = 6, + + /* PAGE 2 */ + PAGE2_DISCONNECT_BYTE0 = 0, + PAGE2_DISCONNECT_BYTE1 = 1, + PAGE2_DISCONNECT_BYTE2 = 2, + PAGE2_DISCONNECT_BYTE3 = 3, + PAGE2_END_CHARGE_BYTE0 = 4, + PAGE2_END_CHARGE_BYTE1 = 5, + PAGE2_END_CHARGE_BYTE2 = 6, + PAGE2_END_CHARGE_BYTE3 = 7, + + /* PAGE 3 */ + /* PAGE 4 */ + /* PAGE 5 */ + /* PAGE 6 */ + /* PAGE 7 */ + PAGE7_CCA_LSB = 4, + PAGE7_CCA_MSB = 5, + PAGE7_DCA_LSB = 6, + PAGE7_DCA_MSB = 7, +}; + +#define DS2438_CTRL_IAD (1 << 0) +#define DS2438_CTRL_CA (1 << 1) +#define DS2438_CTRL_EE (1 << 2) +#define DS2438_CTRL_AD (1 << 3) +#define DS2438_STAT_TB (1 << 4) +#define DS2438_STAT_NVB (1 << 5) +#define DS2438_STAT_ADB (1 << 6) + +struct ds2438_ops { + int (*read_page) (struct device *, u8, u8 *); + int (*read_byte) (struct device *, u8, u8, u8 *); + int (*read_halfword) (struct device *, u8, u8, u16 *); + int (*read_word) (struct device *, u8, u8, u32 *); + int (*write_page) (struct device *, u8, u8 *); + int (*write_byte) (struct device *, u8, u8, u8); + int (*write_halfword) (struct device *, u8, u8, u16); + int (*write_word) (struct device *, u8, u8, u32); + int (*drain_sram) (struct device *, u8); + int (*load_sram) (struct device *, u8); + int (*command) (struct device *, u8, u8); +}; + +static inline u16 ds2438_readw(u8 *raw) +{ + return ((*(raw + 1)) << 8) | (*raw); +} + +static inline void ds2438_writew(u8 *raw, u16 data) +{ + *raw++ = data & 0xFF; + *raw = (data >> 8) & 0xFF; +} +#endif /* __W1_DS2438_H__ */ --- linux-2.6.28.orig/drivers/w1/slaves/w1_ds2438.c +++ linux-2.6.28/drivers/w1/slaves/w1_ds2438.c @@ -0,0 +1,585 @@ +/* + * Copyright 2008 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 + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../w1.h" +#include "../w1_int.h" +#include "../w1_family.h" +#include "w1_ds2438.h" + +struct ds2438_device_info { + /* DS2438 data, valid after calling ds2438_battery_read_status() */ + unsigned long update_time; /* jiffies when data read */ + char raw[DS2438_PAGE_SIZE]; /* raw DS2438 data */ + int voltage_uV; + int current_uA; + int accum_current_uAh; + int temp_C; + int charge_status; + u8 init:1; + u8 setup:1; + u8 calibrate:1; + u8 input_src:1; + u8 ee_flg:1; + u8 resv_bit:3; + u8 threshold:8; + u16 resv_bytes; + u32 senser; + + struct power_supply bat; + struct device *w1_dev; + struct ds2438_ops ops; + struct workqueue_struct *monitor_wqueue; + struct delayed_work monitor_work; +}; + +#define DS2438_SENSER 25 +#define to_ds2438_device_info(x) container_of((x), struct ds2438_device_info, \ + bat); + + +static enum power_supply_property ds2438_battery_props[] = { + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_VOLTAGE_NOW, + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_TEMP, + POWER_SUPPLY_PROP_CHARGE_NOW, +}; + +static char ds2438_sensers_title[] = "DS2438 senserin thousands of resister:"; +static unsigned int cache_time = 1000; +module_param(cache_time, uint, 0644); +MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); + +static ssize_t ds2438_show_input(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct power_supply *psy = dev_get_drvdata(dev); + struct ds2438_device_info *di = to_ds2438_device_info(psy); + + return sprintf(buf, "%s\n", di->input_src ? "1:VDD" : "0:VAD"); +} + +static ssize_t ds2438_show_senser(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int len; + struct power_supply *psy = dev_get_drvdata(dev); + struct ds2438_device_info *di = to_ds2438_device_info(psy); + + len = sprintf(buf, "%s\n", ds2438_sensers_title); + len += sprintf(buf + len, "%d\n", di->senser); + return len; +} + +static ssize_t ds2438_show_ee(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct power_supply *psy = dev_get_drvdata(dev); + struct ds2438_device_info *di = to_ds2438_device_info(psy); + + return sprintf(buf, "%d\n", di->ee_flg); +} + +static ssize_t ds2438_show_threshold(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct power_supply *psy = dev_get_drvdata(dev); + struct ds2438_device_info *di = to_ds2438_device_info(psy); + + return sprintf(buf, "%d\n", di->threshold); +} + +static ssize_t ds2438_set_input(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + struct power_supply *psy = dev_get_drvdata(dev); + struct ds2438_device_info *di = to_ds2438_device_info(psy); + di->input_src = !!simple_strtoul(buf, NULL, 0); + return count; +} + +static ssize_t ds2438_set_senser(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + u32 resister; + struct power_supply *psy = dev_get_drvdata(dev); + struct ds2438_device_info *di = to_ds2438_device_info(psy); + resister = simple_strtoul(buf, NULL, 0); + if (resister) + di->senser = resister; + return count; +} + +static ssize_t ds2438_set_ee(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct power_supply *psy = dev_get_drvdata(dev); + struct ds2438_device_info *di = to_ds2438_device_info(psy); + + di->ee_flg = !!simple_strtoul(buf, NULL, 0); + di->setup = 1; + return count; +} + +static ssize_t ds2438_set_threshold(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int threshold; + struct power_supply *psy = dev_get_drvdata(dev); + struct ds2438_device_info *di = to_ds2438_device_info(psy); + + threshold = simple_strtoul(buf, NULL, 0); + if (threshold < 256) { + di->threshold = threshold; + di->setup = 1; + return count; + } + return -EINVAL; +} + +static ssize_t ds2438_set_calibrate(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct power_supply *psy = dev_get_drvdata(dev); + struct ds2438_device_info *di = to_ds2438_device_info(psy); + + di->calibrate = !!simple_strtoul(buf, NULL, 0); + return count; +} + +static struct device_attribute ds2438_dev_attr[] = { + __ATTR(input_src, 0664, ds2438_show_input, ds2438_set_input), + __ATTR(senser, 0664, ds2438_show_senser, ds2438_set_senser), + __ATTR(ee_flg, 0664, ds2438_show_ee, ds2438_set_ee), + __ATTR(threshold, 0664, ds2438_show_threshold, ds2438_set_threshold), + __ATTR(calibrate, 0220, NULL, ds2438_set_calibrate), +}; + +static void ds2438_setup(struct ds2438_device_info *di) +{ + di->ops.load_sram(di->w1_dev, PAGE0_CONTROL); + di->ops.read_page(di->w1_dev, PAGE0_CONTROL, di->raw); + if (di->init && di->setup) { + if (di->ee_flg) + di->raw[PAGE0_STAT_CTRL] |= DS2438_CTRL_EE; + else + di->raw[PAGE0_STAT_CTRL] &= ~DS2438_CTRL_EE; + if (di->input_src) + di->raw[PAGE0_STAT_CTRL] |= DS2438_CTRL_AD; + else + di->raw[PAGE0_STAT_CTRL] &= ~DS2438_CTRL_AD; + di->raw[PAGE0_THRESHOLD] = di->threshold; + } else { + di->ee_flg = !!(di->raw[PAGE0_STAT_CTRL] & DS2438_CTRL_EE); + di->input_src = !!(di->raw[PAGE0_STAT_CTRL] & DS2438_CTRL_AD); + di->threshold = di->raw[PAGE0_THRESHOLD]; + di->raw[PAGE0_STAT_CTRL] |= DS2438_CTRL_IAD | DS2438_CTRL_CA; + } + di->ops.write_page(di->w1_dev, PAGE0_CONTROL, di->raw); + di->ops.drain_sram(di->w1_dev, PAGE0_CONTROL); + if (!di->init) { + di->calibrate = 1; + di->init = 1; + } + di->setup = 0; +} + +static void ds2438_calibrate(struct ds2438_device_info *di) +{ + int current_raw; + /* disable ICA */ + di->ops.load_sram(di->w1_dev, PAGE0_CONTROL); + di->ops.read_page(di->w1_dev, PAGE0_CONTROL, di->raw); + di->raw[PAGE0_STAT_CTRL] &= ~DS2438_CTRL_IAD; + di->ops.write_page(di->w1_dev, PAGE0_CONTROL, di->raw); + di->ops.drain_sram(di->w1_dev, PAGE0_CONTROL); + + /* Zero offset */ + di->ops.load_sram(di->w1_dev, PAGE1_ETM); + di->ops.read_page(di->w1_dev, PAGE1_ETM, di->raw); + ds2438_writew(di->raw + PAGE1_OFFSET_LSB, 0); + di->ops.drain_sram(di->w1_dev, PAGE1_ETM_BYTE0); + + /* enable ICA & read current */ + di->ops.load_sram(di->w1_dev, PAGE0_CONTROL); + di->ops.read_page(di->w1_dev, PAGE0_CONTROL, di->raw); + di->raw[PAGE0_STAT_CTRL] |= DS2438_CTRL_IAD; + di->ops.write_page(di->w1_dev, PAGE0_CONTROL, di->raw); + di->ops.drain_sram(di->w1_dev, PAGE0_CONTROL); + /*wait current convert about 36HZ */ + mdelay(30); + /* disable ICA */ + di->ops.load_sram(di->w1_dev, PAGE0_CONTROL); + di->ops.read_page(di->w1_dev, PAGE0_CONTROL, di->raw); + di->raw[PAGE0_STAT_CTRL] &= ~DS2438_CTRL_IAD; + di->ops.write_page(di->w1_dev, PAGE0_CONTROL, di->raw); + di->ops.drain_sram(di->w1_dev, PAGE0_CONTROL); + /* read current value */ + current_raw = ds2438_readw(di->raw + PAGE0_CURRENT_LSB); + /* write offset by current value */ + di->ops.load_sram(di->w1_dev, PAGE1_ETM); + di->ops.read_page(di->w1_dev, PAGE1_ETM, di->raw); + ds2438_writew(di->raw + PAGE1_OFFSET_LSB, current_raw << 8); + di->ops.write_page(di->w1_dev, PAGE1_ETM, di->raw); + di->ops.drain_sram(di->w1_dev, PAGE1_ETM); + + /*enable ICA again */ + di->ops.load_sram(di->w1_dev, PAGE0_CONTROL); + di->ops.read_page(di->w1_dev, PAGE0_CONTROL, di->raw); + di->raw[PAGE0_STAT_CTRL] |= DS2438_CTRL_IAD; + di->ops.write_page(di->w1_dev, PAGE0_CONTROL, di->raw); + di->ops.drain_sram(di->w1_dev, PAGE0_CONTROL); + di->calibrate = 0; +} + +/* + * power supply temperture is in tenths of degree. + */ +static inline int ds2438_get_temp(u16 raw) +{ + int degree, s; + s = !!(raw & 0x8000); + + if (s) + raw = ((~raw & 0x7FFF) + 1); + degree = ((raw >> 8) * 10) + (((raw & 0xFF) * 5) + 63) / 128; + return s ? -degree : degree; +} + +/* + * power supply current is in uA. + */ +static inline int ds2438_get_current(u32 senser, u16 raw) +{ + int s, current_uA; + s = !!(raw & 0xFC00); + /* (x * 1000 * 1000)uA / (4096 * (Rsens / 1000)) */ + raw &= 0x3FF; + current_uA = raw * 125 * 125 * 125; + current_uA /= (senser << 3); + return s ? -current_uA : current_uA; +} + +/* + * power supply current is in uAh. + */ +static inline int ds2438_get_ica(u32 senser, u8 raw) +{ + int charge_uAh; + /* (x * 1000 * 1000)uA / (2048 * (Rsens / 1000)) */ + charge_uAh = (raw * 125 * 125 * 125) >> 4; + charge_uAh /= (senser << 4); + return charge_uAh; +} + +static int ds2438_battery_update_page1(struct ds2438_device_info *di) +{ + int ica_raw; + di->ops.load_sram(di->w1_dev, PAGE1_ETM); + di->ops.read_page(di->w1_dev, PAGE1_ETM, di->raw); + ica_raw = di->raw[PAGE1_ICA]; + di->accum_current_uAh = ds2438_get_ica(di->senser, ica_raw); + return 0; +} + +static int ds2438_battery_read_status(struct ds2438_device_info *di) +{ + u8 status; + int temp_raw, voltage_raw, current_raw; + + if (!(di->init) || di->setup) + ds2438_setup(di); + + if (di->calibrate) + ds2438_calibrate(di); + + if (di->update_time && time_before(jiffies, di->update_time + + msecs_to_jiffies(cache_time))) + return 0; + + di->ops.load_sram(di->w1_dev, PAGE0_CONTROL); + di->ops.read_page(di->w1_dev, PAGE0_CONTROL, di->raw); + status = di->raw[PAGE0_STAT_CTRL]; + temp_raw = ds2438_readw(di->raw + PAGE0_TEMP_LSB); + voltage_raw = ds2438_readw(di->raw + PAGE0_VOLTAGE_LSB); + current_raw = ds2438_readw(di->raw + PAGE0_CURRENT_LSB); + di->temp_C = ds2438_get_temp(temp_raw); + di->voltage_uV = voltage_raw * 10000; + di->current_uA = ds2438_get_current(di->senser, current_raw); + + ds2438_battery_update_page1(di); + + if (!(status & DS2438_STAT_TB)) + di->ops.command(di->w1_dev, DS2438_CONVERT_TEMP, 0); + if (!(status & DS2438_STAT_ADB)) + di->ops.command(di->w1_dev, DS2438_CONVERT_VOLT, 0); + di->update_time = jiffies; + return 0; +} + +static void ds2438_battery_update_status(struct ds2438_device_info *di) +{ + int old_charge_status = di->charge_status; + + ds2438_battery_read_status(di); + + if (di->charge_status != old_charge_status) + power_supply_changed(&di->bat); +} + +static void ds2438_battery_work(struct work_struct *work) +{ + struct ds2438_device_info *di = container_of(work, + struct ds2438_device_info, + monitor_work.work); + const int interval = HZ * 60; + + dev_dbg(di->w1_dev, "%s\n", __func__); + + ds2438_battery_update_status(di); + queue_delayed_work(di->monitor_wqueue, &di->monitor_work, interval); +} + +static void ds2438_battery_external_power_changed(struct power_supply *psy) +{ + struct ds2438_device_info *di = to_ds2438_device_info(psy); + + dev_dbg(di->w1_dev, "%s\n", __func__); + + cancel_delayed_work(&di->monitor_work); + queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ / 10); +} + +static int ds2438_battery_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct ds2438_device_info *di = to_ds2438_device_info(psy); + + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + val->intval = di->charge_status; + return 0; + default: + break; + } + + ds2438_battery_read_status(di); + + switch (psp) { + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + val->intval = di->voltage_uV; + break; + case POWER_SUPPLY_PROP_CURRENT_NOW: + val->intval = di->current_uA; + break; + case POWER_SUPPLY_PROP_TEMP: + val->intval = di->temp_C; + break; + case POWER_SUPPLY_PROP_CHARGE_NOW: + val->intval = di->accum_current_uAh; + break; + default: + return -EINVAL; + } + + return 0; +} + +/* W1 slave DS2438 famliy operations */ +static int ds2438_read_page(struct device *dev, u8 page, u8 *buf) +{ + struct w1_slave *slave = container_of(dev, struct w1_slave, dev); + if ((page >= DS2438_PAGE_NUM) || (buf == NULL)) + return -EINVAL; + + mutex_lock(&slave->master->mutex); + if (!w1_reset_select_slave(slave)) { + w1_write_8(slave->master, W1_READ_SCRATCHPAD); + w1_write_8(slave->master, page); + w1_read_block(slave->master, buf, DS2438_PAGE_SIZE); + } + mutex_unlock(&slave->master->mutex); + return 0; +} + +static int ds2438_write_page(struct device *dev, u8 page, u8 *buf) +{ + struct w1_slave *slave = container_of(dev, struct w1_slave, dev); + if ((page >= DS2438_PAGE_NUM) || (buf == NULL)) + return -EINVAL; + + mutex_lock(&slave->master->mutex); + if (!w1_reset_select_slave(slave)) { + w1_write_8(slave->master, DS2438_WRITE_SCRATCHPAD); + w1_write_8(slave->master, page); + w1_write_block(slave->master, buf, DS2438_PAGE_SIZE); + } + mutex_unlock(&slave->master->mutex); + return 0; +} + +static int ds2438_command(struct device *dev, u8 command, u8 data) +{ + struct w1_slave *slave = container_of(dev, struct w1_slave, dev); + + mutex_lock(&slave->master->mutex); + if (!w1_reset_select_slave(slave)) { + w1_write_8(slave->master, command); + switch (command) { + case DS2438_COPY_SCRATCHPAD: + case DS2438_RECALL_MEMORY: + w1_write_8(slave->master, data); + } + } + mutex_unlock(&slave->master->mutex); + return 0; +} + +static int ds2438_drain_sram(struct device *dev, u8 page) +{ + return ds2438_command(dev, DS2438_COPY_SCRATCHPAD, page); +} + +static int ds2438_load_sram(struct device *dev, u8 page) +{ + return ds2438_command(dev, DS2438_RECALL_MEMORY, page); +} + +static inline void ds2438_defaut_ops(struct ds2438_ops *ops) +{ + ops->read_page = ds2438_read_page; + ops->write_page = ds2438_write_page; + ops->drain_sram = ds2438_drain_sram; + ops->load_sram = ds2438_load_sram; + ops->command = ds2438_command; +} + +static int ds2438_add_slave(struct w1_slave *slave) +{ + int i, retval = 0; + struct ds2438_device_info *di; + + di = kzalloc(sizeof(*di), GFP_KERNEL); + if (!di) { + retval = -ENOMEM; + goto di_alloc_failed; + } + + di->w1_dev = &slave->dev; + di->bat.name = slave->dev.bus_id; + di->bat.type = POWER_SUPPLY_TYPE_BATTERY; + di->bat.properties = ds2438_battery_props; + di->bat.num_properties = ARRAY_SIZE(ds2438_battery_props); + di->bat.get_property = ds2438_battery_get_property; + di->bat.external_power_changed = ds2438_battery_external_power_changed; + ds2438_defaut_ops(&di->ops); + di->senser = DS2438_SENSER; + di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN; + + retval = power_supply_register(&slave->dev, &di->bat); + if (retval) { + dev_err(&slave->dev, "failed to register battery\n"); + goto batt_failed; + } + + for (i = 0; i < ARRAY_SIZE(ds2438_dev_attr); i++) { + if (device_create_file(di->bat.dev, ds2438_dev_attr + i)) { + printk(KERN_ERR "Customize attribute file fail!\n"); + break; + } + } + + if (i != ARRAY_SIZE(ds2438_dev_attr)) { + for (; i >= 0; i++) + device_remove_file(di->bat.dev, ds2438_dev_attr + i); + goto workqueue_failed; + } + INIT_DELAYED_WORK(&di->monitor_work, ds2438_battery_work); + di->monitor_wqueue = create_singlethread_workqueue(slave->dev.bus_id); + if (!di->monitor_wqueue) { + retval = -ESRCH; + goto workqueue_failed; + } + dev_set_drvdata(&slave->dev, di); + queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ / 2); + + goto success; + + workqueue_failed: + power_supply_unregister(&di->bat); + batt_failed: + kfree(di); + di_alloc_failed: + success: + return retval; +} + +static void ds2438_remove_slave(struct w1_slave *slave) +{ + struct ds2438_device_info *di = dev_get_drvdata(&slave->dev); + + cancel_rearming_delayed_workqueue(di->monitor_wqueue, + &di->monitor_work); + destroy_workqueue(di->monitor_wqueue); + power_supply_unregister(&di->bat); +} + +static struct w1_family_ops w1_ds2438_fops = { + .add_slave = ds2438_add_slave, + .remove_slave = ds2438_remove_slave, +}; + +static struct w1_family w1_family_ds2438 = { + .fid = W1_FAMILY_DS2438, + .fops = &w1_ds2438_fops, +}; + +static int __init w1_ds2438_init(void) +{ + pr_info("1-wire driver for the DS2438 smart battery monitor\n"); + return w1_register_family(&w1_family_ds2438); +} + +static void __exit w1_ds2438_fini(void) +{ + w1_unregister_family(&w1_family_ds2438); +} + +module_init(w1_ds2438_init); +module_exit(w1_ds2438_fini); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Freescale Semiconductors Inc"); +MODULE_DESCRIPTION("1-wire DS2438 family, smart battery monitor."); --- linux-2.6.28.orig/drivers/w1/slaves/Kconfig +++ linux-2.6.28/drivers/w1/slaves/Kconfig @@ -22,6 +22,12 @@ Say Y here if you want to use a 1-wire 4kb EEPROM family device (DS2433). +config W1_SLAVE_DS2438 + tristate "Smart Battery Monitor (DS2438)" + help + Say Y here if you want to use a 1-wire + Smart Battery Monitor family device (DS2438). + config W1_SLAVE_DS2433_CRC bool "Protect DS2433 data with a CRC16" depends on W1_SLAVE_DS2433 --- linux-2.6.28.orig/drivers/w1/slaves/w1_therm.c +++ linux-2.6.28/drivers/w1/slaves/w1_therm.c @@ -115,7 +115,7 @@ static inline int w1_DS18B20_convert_temp(u8 rom[9]) { - s16 t = (rom[1] << 8) | rom[0]; + int t = ((s16)rom[1] << 8) | rom[0]; t = t*1000/16; return t; } --- linux-2.6.28.orig/drivers/w1/masters/mxc_w1.c +++ linux-2.6.28/drivers/w1/masters/mxc_w1.c @@ -0,0 +1,432 @@ +/* + * Copyright 2005-2009 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 + */ + +/*! + * @defgroup MXC_OWIRE MXC Driver for owire interface + */ + +/*! + * @file mxc_w1.c + * + * @brief Driver for the Freescale Semiconductor MXC owire interface. + * + * + * @ingroup MXC_OWIRE + */ + +/*! + * Include Files + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../w1.h" +#include "../w1_int.h" +#include "../w1_log.h" + +/* + * mxc function declarations + */ + +static int __devinit mxc_w1_probe(struct platform_device *pdev); +static int __devexit mxc_w1_remove(struct platform_device *pdev); +static DECLARE_COMPLETION(transmit_done); +extern void gpio_owire_active(void); +extern void gpio_owire_inactive(void); + +/* + * MXC W1 Register offsets + */ +#define MXC_W1_CONTROL 0x00 +#define MXC_W1_TIME_DIVIDER 0x02 +#define MXC_W1_RESET 0x04 +#define MXC_W1_COMMAND 0x06 +#define MXC_W1_TXRX 0x08 +#define MXC_W1_INTERRUPT 0x0A +#define MXC_W1_INTERRUPT_EN 0x0C +DEFINE_SPINLOCK(w1_lock); + +/*! + * This structure contains pointers to callback functions. + */ +static struct platform_driver mxc_w1_driver = { + .driver = { + .name = "mxc_w1", + }, + .probe = mxc_w1_probe, + .remove = mxc_w1_remove, +}; + +/*! + * This structure is used to store + * information specific to w1 module. + */ + +struct mxc_w1_device { + char *base_address; + unsigned long found; + unsigned int clkdiv; + struct clk *clk; + struct w1_bus_master *bus_master; +}; + +/* + * this is the low level routine to + * reset the device on the One Wire interface + * on the hardware + * @param data the data field of the w1 device structure + * @return the function returns 0 when the reset pulse has + * been generated + */ +static u8 mxc_w1_ds2_reset_bus(void *data) +{ + volatile u8 reg_val; + u8 ret; + struct mxc_w1_device *dev = (struct mxc_w1_device *)data; + + __raw_writeb(0x80, (dev->base_address + MXC_W1_CONTROL)); + + do { + reg_val = __raw_readb(dev->base_address + MXC_W1_CONTROL); + } while (((reg_val >> 7) & 0x1) != 0); + ret = ((reg_val >> 7) & 0x1); + return ret; +} + +/*! + * this is the low level routine to read/write a bit on the One Wire + * interface on the hardware + * @param data the data field of the w1 device structure + * @param bit 0 = write-0 cycle, 1 = write-1/read cycle + * @return the function returns the bit read (0 or 1) + */ +static u8 mxc_w1_ds2_touch_bit(void *data, u8 bit) +{ + + volatile u8 reg_val; + struct mxc_w1_device *dev = (struct mxc_w1_device *)data; + u8 ret = 0; + + if (0 == bit) { + __raw_writeb((1 << 5), (dev->base_address + MXC_W1_CONTROL)); + + do { + reg_val = + __raw_readb(dev->base_address + MXC_W1_CONTROL); + } while (0 != ((reg_val >> 5) & 0x1)); + } + + else { + __raw_writeb((1 << 4), dev->base_address + MXC_W1_CONTROL); + do { + reg_val = + __raw_readb(dev->base_address + MXC_W1_CONTROL); + } while (0 != ((reg_val >> 4) & 0x1)); + + reg_val = + (((__raw_readb(dev->base_address + MXC_W1_CONTROL)) >> 3) & + 0x1); + ret = (u8) (reg_val); + } + + return ret; +} + +static void mxc_w1_ds2_write_byte(void *data, u8 byte) +{ + struct mxc_w1_device *dev = (struct mxc_w1_device *)data; + INIT_COMPLETION(transmit_done); + __raw_writeb(byte, (dev->base_address + MXC_W1_TXRX)); + __raw_writeb(0x10, (dev->base_address + MXC_W1_INTERRUPT_EN)); + wait_for_completion(&transmit_done); +} +static u8 mxc_w1_ds2_read_byte(void *data) +{ + volatile u8 reg_val; + struct mxc_w1_device *dev = (struct mxc_w1_device *)data; + mxc_w1_ds2_write_byte(data, 0xFF); + reg_val = __raw_readb((dev->base_address + MXC_W1_TXRX)); + return reg_val; +} +static u8 mxc_w1_read_byte(void *data) +{ + volatile u8 reg_val; + struct mxc_w1_device *dev = (struct mxc_w1_device *)data; + reg_val = __raw_readb((dev->base_address + MXC_W1_TXRX)); + return reg_val; +} +static irqreturn_t w1_interrupt_handler(int irq, void *data) +{ + u8 reg_val; + irqreturn_t ret = IRQ_NONE; + struct mxc_w1_device *dev = (struct mxc_w1_device *)data; + reg_val = __raw_readb((dev->base_address + MXC_W1_INTERRUPT)); + if ((reg_val & 0x10)) { + complete(&transmit_done); + reg_val = __raw_readb((dev->base_address + MXC_W1_TXRX)); + ret = IRQ_HANDLED; + } + return ret; +} +void search_ROM_accelerator(void *data, struct w1_master *master, u8 search_type, + w1_slave_found_callback cb) +{ + u64 rn[2], last_rn[2], rn2[2]; + u64 rn1, rom_id, temp, temp1; + int i, j, z, w, last_zero, loop; + u8 bit, reg_val, bit2; + u8 byte, byte1; + int disc, prev_disc, last_disc; + struct mxc_w1_device *dev = (struct mxc_w1_device *)data; + last_rn[0] = 0; + last_rn[1] = 0; + rom_id = 0; + prev_disc = 0; + loop = 0; + disc = -1; + last_disc = 0; + last_zero = 0; + while (!last_zero) { + /* + * Reset bus and all 1-wire device state machines + * so they can respond to our requests. + * + * Return 0 - device(s) present, 1 - no devices present. + */ + if (mxc_w1_ds2_reset_bus(data)) { + pr_debug("No devices present on the wire.\n"); + break; + } + rn[0] = 0; + rn[1] = 0; + __raw_writeb(0x80, (dev->base_address + MXC_W1_CONTROL)); + mdelay(1); + mxc_w1_ds2_write_byte(data, 0xF0); + __raw_writeb(0x02, (dev->base_address + MXC_W1_COMMAND)); + memcpy(rn2, last_rn, 16); + z = 0; + w = 0; + for (i = 0; i < 16; i++) { + reg_val = rn2[z] >> (8 * w); + mxc_w1_ds2_write_byte(data, reg_val); + reg_val = mxc_w1_read_byte(data); + if ((reg_val & 0x3) == 0x3) { + pr_debug("Device is Not Responding\n"); + break; + } + for (j = 0; j < 8; j += 2) { + byte = 0xFF; + byte1 = 1; + byte ^= byte1 << j; + bit = (reg_val >> j) & 0x1; + bit2 = (reg_val >> j); + if (bit) { + prev_disc = disc; + disc = 8 * i + j; + reg_val &= byte; + } + } + rn1 = 0; + rn1 = reg_val; + rn[z] |= rn1 << (8 * w); + w++; + if (i == 7) { + z++; + w = 0; + } + } + if ((disc == -1) || (disc == prev_disc)) + last_zero = 1; + if (disc == last_disc) + disc = prev_disc; + z = 0; + rom_id = 0; + for (i = 0, j = 1; i < 64; i++) { + temp = 0; + temp = (rn[z] >> j) & 0x1; + rom_id |= (temp << i); + j += 2; + if (i == 31) { + z++; + j = 1; + } + + } + if (disc > 63) { + last_rn[0] = rn[0]; + temp1 = rn[1]; + loop = disc % 64; + temp = 1; + temp1 |= (temp << (loop + 1)) - 1; + temp1 |= (temp << (loop + 1)); + last_rn[1] = temp1; + + } else { + last_rn[1] = 0; + temp1 = rn[0]; + temp = 1; + temp1 |= (temp << (loop + 1)) - 1; + temp1 |= (temp << (loop + 1)); + last_rn[0] = temp1; + } + last_disc = disc; + cb(data, rom_id); + } +} + +/*! + * this routine sets the One Wire clock + * to a value of 1 Mhz, as required by + * hardware. + * @param dev the device structure for w1 + * @return The function returns void + */ +static void mxc_w1_hw_init(struct mxc_w1_device *dev) +{ + clk_enable(dev->clk); + + /* set the timer divider clock to divide by 65 */ + /* as the clock to the One Wire is at 66.5MHz */ + __raw_writeb(dev->clkdiv, dev->base_address + MXC_W1_TIME_DIVIDER); + + return; +} + +/*! + * this is the probe routine for the One Wire driver. + * It is called during the driver initilaization. + * @param pdev the platform device structure for w1 + * @return The function returns 0 on success + * and a non-zero value on failure + * + */ +static int __devinit mxc_w1_probe(struct platform_device *pdev) +{ + struct mxc_w1_device *dev; + struct mxc_w1_config *data = + (struct mxc_w1_config *)pdev->dev.platform_data; + int flag, ret_val, irq; + int err = 0; + ret_val = 0; + flag = data->search_rom_accelerator; + dev = kzalloc(sizeof(struct mxc_w1_device) + + sizeof(struct w1_bus_master), GFP_KERNEL); + if (!dev) { + return -ENOMEM; + } + dev->clk = clk_get(&pdev->dev, "owire_clk"); + dev->bus_master = (struct w1_bus_master *)(dev + 1); + dev->found = 1; + dev->clkdiv = (clk_get_rate(dev->clk) / 1000000) - 1; + dev->base_address = (void *)IO_ADDRESS(OWIRE_BASE_ADDR); + + mxc_w1_hw_init(dev); + dev->bus_master->data = dev; + dev->bus_master->reset_bus = &mxc_w1_ds2_reset_bus; + dev->bus_master->touch_bit = &mxc_w1_ds2_touch_bit; + if (flag) { + dev->bus_master->write_byte = &mxc_w1_ds2_write_byte; + dev->bus_master->read_byte = &mxc_w1_ds2_read_byte; + dev->bus_master->search = &search_ROM_accelerator; + irq = platform_get_irq(pdev, 0); + ret_val = + request_irq(irq, w1_interrupt_handler, 0, "mxc_w1", dev); + if (ret_val) { + pr_debug("OWire:request_irq(%d) returned error %d\n", + irq, ret_val); + return -1; + } + } + err = w1_add_master_device(dev->bus_master); + if (err) + goto err_out_free_device; + + platform_set_drvdata(pdev, dev); + return 0; + + err_out_free_device: + + kfree(dev); + return err; +} + +/* + * disassociate the w1 device from the driver + * @param dev the device structure for w1 + * @return The function returns void + */ +static int mxc_w1_remove(struct platform_device *pdev) +{ + struct mxc_w1_device *dev = platform_get_drvdata(pdev); + + clk_disable(dev->clk); + clk_put(dev->clk); + if (dev->found) { + w1_remove_master_device(dev->bus_master); + } + platform_set_drvdata(pdev, NULL); + + return 0; +} + +/* + * initialize the driver + * @return The function returns 0 on success + * and a non-zero value on failure + */ + +static int __init mxc_w1_init(void) +{ + int ret; + + printk(KERN_INFO "Serial: MXC OWire driver\n"); + + gpio_owire_active(); + + ret = platform_driver_register(&mxc_w1_driver); + + return ret; +} + +/* + * cleanup before the driver exits + */ +static void mxc_w1_exit(void) +{ + gpio_owire_inactive(); + platform_driver_unregister(&mxc_w1_driver); +} + +module_init(mxc_w1_init); +module_exit(mxc_w1_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Freescale Semiconductors Inc"); +MODULE_DESCRIPTION("Driver for One-Wire on MXC"); --- linux-2.6.28.orig/drivers/w1/masters/Kconfig +++ linux-2.6.28/drivers/w1/masters/Kconfig @@ -34,6 +34,12 @@ This driver can also be built as a module. If so, the module will be called ds2482. +config W1_MASTER_MXC + tristate "Freescale MXC driver for 1-wire" + depends on W1 && ARCH_MXC + help + Say Y here to enable MXC 1-wire host + config W1_MASTER_DS1WM tristate "Maxim DS1WM 1-wire busmaster" depends on W1 && ARM && HAVE_CLK --- linux-2.6.28.orig/drivers/w1/masters/Makefile +++ linux-2.6.28/drivers/w1/masters/Makefile @@ -5,6 +5,8 @@ obj-$(CONFIG_W1_MASTER_MATROX) += matrox_w1.o obj-$(CONFIG_W1_MASTER_DS2490) += ds2490.o obj-$(CONFIG_W1_MASTER_DS2482) += ds2482.o +obj-$(CONFIG_W1_MASTER_MXC) += mxc_w1.o + obj-$(CONFIG_W1_MASTER_DS1WM) += ds1wm.o obj-$(CONFIG_W1_MASTER_GPIO) += w1-gpio.o obj-$(CONFIG_HDQ_MASTER_OMAP) += omap_hdq.o --- linux-2.6.28.orig/drivers/sbus/char/openprom.c +++ linux-2.6.28/drivers/sbus/char/openprom.c @@ -51,6 +51,7 @@ MODULE_DESCRIPTION("OPENPROM Configuration Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION("1.0"); +MODULE_ALIAS_MISCDEV(SUN_OPENPROM_MINOR); /* Private data kept by the driver for each descriptor. */ typedef struct openprom_private_data --- linux-2.6.28.orig/drivers/net/3c505.c +++ linux-2.6.28/drivers/net/3c505.c @@ -493,21 +493,27 @@ } /* read the data */ spin_lock_irqsave(&adapter->lock, flags); - i = 0; - do { - j = 0; - while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && j++ < 20000); - pcb->data.raw[i++] = inb_command(dev->base_addr); - if (i > MAX_PCB_DATA) - INVALID_PCB_MSG(i); - } while ((stat & ASF_PCB_MASK) != ASF_PCB_END && j < 20000); + for (i = 0; i < MAX_PCB_DATA; i++) { + for (j = 0; j < 20000; j++) { + stat = get_status(dev->base_addr); + if (stat & ACRF) + break; + } + pcb->data.raw[i] = inb_command(dev->base_addr); + if ((stat & ASF_PCB_MASK) == ASF_PCB_END || j >= 20000) + break; + } spin_unlock_irqrestore(&adapter->lock, flags); + if (i >= MAX_PCB_DATA) { + INVALID_PCB_MSG(i); + return false; + } if (j >= 20000) { TIMEOUT_MSG(__LINE__); return false; } - /* woops, the last "data" byte was really the length! */ - total_length = pcb->data.raw[--i]; + /* the last "data" byte was really the length! */ + total_length = pcb->data.raw[i]; /* safety check total length vs data length */ if (total_length != (pcb->length + 2)) { --- linux-2.6.28.orig/drivers/net/Makefile +++ linux-2.6.28/drivers/net/Makefile @@ -220,6 +220,7 @@ obj-$(CONFIG_MYRI10GE) += myri10ge/ obj-$(CONFIG_SMC91X) += smc91x.o obj-$(CONFIG_SMC911X) += smc911x.o +obj-$(CONFIG_SMSC911X) += smsc911x.o obj-$(CONFIG_BFIN_MAC) += bfin_mac.o obj-$(CONFIG_DM9000) += dm9000.o obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o --- linux-2.6.28.orig/drivers/net/fec.h +++ linux-2.6.28/drivers/net/fec.h @@ -14,7 +14,7 @@ /****************************************************************************/ #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ - defined(CONFIG_M520x) || defined(CONFIG_M532x) + defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC) /* * Just figures, Motorola would have to change the offsets for * registers in the same peripheral device on different models @@ -56,6 +56,10 @@ unsigned long fec_r_des_start; /* Receive descriptor ring */ unsigned long fec_x_des_start; /* Transmit descriptor ring */ unsigned long fec_r_buff_size; /* Maximum receive buff size */ + unsigned long fec_reserved12[93]; + unsigned long fec_miigsk_cfgr; /* MIIGSK config register */ + unsigned long fec_reserved13; + unsigned long fec_miigsk_enr; /* MIIGSK enable register */ } fec_t; #else @@ -103,12 +107,22 @@ /* * Define the buffer descriptor structure. */ +/* Please see "Receive Buffer Descriptor Field Definitions" in Specification. + * It's LE. + */ +#ifdef CONFIG_ARCH_MXC +typedef struct bufdesc { + unsigned short cbd_datlen; /* Data length */ + unsigned short cbd_sc; /* Control and status info */ + unsigned long cbd_bufaddr; /* Buffer address */ +} cbd_t; +#else typedef struct bufdesc { unsigned short cbd_sc; /* Control and status info */ unsigned short cbd_datlen; /* Data length */ unsigned long cbd_bufaddr; /* Buffer address */ } cbd_t; - +#endif /* * The following definitions courtesy of commproc.h, which where --- linux-2.6.28.orig/drivers/net/r6040.c +++ linux-2.6.28/drivers/net/r6040.c @@ -49,8 +49,8 @@ #include #define DRV_NAME "r6040" -#define DRV_VERSION "0.18" -#define DRV_RELDATE "13Jul2008" +#define DRV_VERSION "0.19" +#define DRV_RELDATE "18Dec2008" /* PHY CHIP Address */ #define PHY1_ADDR 1 /* For MAC1 */ @@ -214,7 +214,7 @@ /* Wait for the read bit to be cleared */ while (limit--) { cmd = ioread16(ioaddr + MMDIO); - if (cmd & MDIO_READ) + if (!(cmd & MDIO_READ)) break; } @@ -233,7 +233,7 @@ /* Wait for the write bit to be cleared */ while (limit--) { cmd = ioread16(ioaddr + MMDIO); - if (cmd & MDIO_WRITE) + if (!(cmd & MDIO_WRITE)) break; } } @@ -681,8 +681,10 @@ struct net_device *dev = dev_id; struct r6040_private *lp = netdev_priv(dev); void __iomem *ioaddr = lp->base; - u16 status; + u16 misr, status; + /* Save MIER */ + misr = ioread16(ioaddr + MIER); /* Mask off RDC MAC interrupt */ iowrite16(MSK_INT, ioaddr + MIER); /* Read MISR status and clear */ @@ -702,7 +704,7 @@ dev->stats.rx_fifo_errors++; /* Mask off RX interrupt */ - iowrite16(ioread16(ioaddr + MIER) & ~RX_INTS, ioaddr + MIER); + misr &= ~RX_INTS; netif_rx_schedule(dev, &lp->napi); } @@ -710,6 +712,9 @@ if (status & TX_INTS) r6040_tx(dev); + /* Restore RDC MAC interrupt */ + iowrite16(misr, ioaddr + MIER); + return IRQ_HANDLED; } --- linux-2.6.28.orig/drivers/net/sky2.c +++ linux-2.6.28/drivers/net/sky2.c @@ -1403,9 +1403,6 @@ } - if (netif_msg_ifup(sky2)) - printk(KERN_INFO PFX "%s: enabling interface\n", dev->name); - netif_carrier_off(dev); /* must be power of 2 */ @@ -1484,6 +1481,9 @@ sky2_write32(hw, B0_IMSK, imask); sky2_set_multicast(dev); + + if (netif_msg_ifup(sky2)) + printk(KERN_INFO PFX "%s: enabling interface\n", dev->name); return 0; err_out: --- linux-2.6.28.orig/drivers/net/tun.c +++ linux-2.6.28/drivers/net/tun.c @@ -157,10 +157,16 @@ nexact = n; - /* The rest is hashed */ + /* Remaining multicast addresses are hashed, + * unicast will leave the filter disabled. */ memset(filter->mask, 0, sizeof(filter->mask)); - for (; n < uf.count; n++) + for (; n < uf.count; n++) { + if (!is_multicast_ether_addr(addr[n].u)) { + err = 0; /* no filter */ + goto done; + } addr_hash_set(filter->mask, addr[n].u); + } /* For ALLMULTI just set the mask to all ones. * This overrides the mask populated above. */ --- linux-2.6.28.orig/drivers/net/virtio_net.c +++ linux-2.6.28/drivers/net/virtio_net.c @@ -24,6 +24,7 @@ #include #include #include +#include static int napi_weight = 128; module_param(napi_weight, int, 0444); @@ -33,7 +34,7 @@ module_param(gso, bool, 0444); /* FIXME: MTU in config. */ -#define MAX_PACKET_LEN (ETH_HLEN+ETH_DATA_LEN) +#define MAX_PACKET_LEN (ETH_HLEN + VLAN_HLEN + ETH_DATA_LEN) struct virtnet_info { --- linux-2.6.28.orig/drivers/net/r8169.c +++ linux-2.6.28/drivers/net/r8169.c @@ -2121,6 +2121,13 @@ dev->poll_controller = rtl8169_netpoll; #endif + /* Ubuntu temporary workaround for bug #76489, disable + * NETIF_F_TSO by default for RTL8111/8168B chipsets. + * People can re-enable if required */ + if (tp->mac_version == RTL_GIGA_MAC_VER_11 + || tp->mac_version == RTL_GIGA_MAC_VER_12) + dev->features &= ~NETIF_F_TSO; + tp->intr_mask = 0xffff; tp->align = cfg->align; tp->hw_start = cfg->hw_start; --- linux-2.6.28.orig/drivers/net/forcedeth.c +++ linux-2.6.28/drivers/net/forcedeth.c @@ -582,6 +582,9 @@ #define NV_MSI_X_VECTOR_TX 0x1 #define NV_MSI_X_VECTOR_OTHER 0x2 +#define NV_MSI_PRIV_OFFSET 0x68 +#define NV_MSI_PRIV_VALUE 0xffffffff + #define NV_RESTART_TX 0x1 #define NV_RESTART_RX 0x2 @@ -5967,6 +5970,8 @@ for (i = 0;i <= np->register_size/sizeof(u32); i++) writel(np->saved_config_space[i], base+i*sizeof(u32)); + pci_write_config_dword(pdev, NV_MSI_PRIV_OFFSET, NV_MSI_PRIV_VALUE); + netif_device_attach(dev); if (netif_running(dev)) { rc = nv_open(dev); --- linux-2.6.28.orig/drivers/net/fec.c +++ linux-2.6.28/drivers/net/fec.c @@ -18,6 +18,9 @@ * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be) * Copyright (c) 2004-2006 Macq Electronique SA. */ +/* + * Copyright 2006-2009 Freescale Semiconductor, Inc. All Rights Reserved. + */ #include #include @@ -36,16 +39,29 @@ #include #include #include +#include #include #include #include #include #include +#include +#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ + defined(CONFIG_M520x) || defined(CONFIG_M532x) #include #include #include "fec.h" +#define FEC_ALIGNMENT (0x03) /*FEC needs 4bytes alignment*/ +#elif defined(CONFIG_ARCH_MXC) +#include +#include +#include "fec.h" +#define FEC_ALIGNMENT (0x0F) /*FEC needs 128bits(32bytes) alignment*/ +#endif + +#define FEC_ADDR_ALIGNMENT(x) ((unsigned char *)(((unsigned long )(x) + (FEC_ALIGNMENT)) & (~FEC_ALIGNMENT))) #if defined(CONFIG_FEC2) #define FEC_MAX_PORTS 2 @@ -53,7 +69,7 @@ #define FEC_MAX_PORTS 1 #endif -#if defined(CONFIG_M5272) +#if defined(CONFIG_M5272) || defined(CONFIG_ARCH_MXC) #define HAVE_mii_link_interrupt #endif @@ -72,6 +88,8 @@ (MCF_MBAR+0x30000), #elif defined(CONFIG_M532x) (MCF_MBAR+0xfc030000), +#elif defined(CONFIG_ARCH_MXC) + (IO_ADDRESS(FEC_BASE_ADDR)), #else &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec), #endif @@ -149,6 +167,12 @@ #define FEC_ENET_MII ((uint)0x00800000) /* MII interrupt */ #define FEC_ENET_EBERR ((uint)0x00400000) /* SDMA bus error */ +#ifndef CONFIG_ARCH_MXC +#define FEC_ENET_MASK ((uint)0xffc00000) +#else +#define FEC_ENET_MASK ((uint)0xfff80000) +#endif + /* The FEC stores dest/src/type, data, and checksum for receive packets. */ #define PKT_MAXBUF_SIZE 1518 @@ -162,7 +186,7 @@ * account when setting it. */ #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ - defined(CONFIG_M520x) || defined(CONFIG_M532x) + defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC) #define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16) #else #define OPT_FRAME_SIZE 0 @@ -185,11 +209,13 @@ /* The saved address of a sent-in-place packet/buffer, for skfree(). */ unsigned char *tx_bounce[TX_RING_SIZE]; struct sk_buff* tx_skbuff[TX_RING_SIZE]; + struct sk_buff* rx_skbuff[RX_RING_SIZE]; ushort skb_cur; ushort skb_dirty; /* CPM dual port RAM relative addresses. */ + void * cbd_mem_base; /* save the virtual base address of rx&tx buffer descripter */ cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */ cbd_t *tx_bd_base; cbd_t *cur_rx, *cur_tx; /* The next free ring entry */ @@ -206,6 +232,7 @@ uint phy_speed; phy_info_t const *phy; struct work_struct phy_task; + struct net_device *net; uint sequence_done; uint mii_phy_task_queued; @@ -217,6 +244,8 @@ int link; int old_link; int full_duplex; + + struct clk *clk; }; static int fec_enet_open(struct net_device *dev); @@ -231,6 +260,17 @@ static void fec_stop(struct net_device *dev); static void fec_set_mac_address(struct net_device *dev); +static void __inline__ fec_dcache_inv_range(void * start, void * end); +static void __inline__ fec_dcache_flush_range(void * start, void * end); + +/* + * fec_copy_threshold controls the copy when recieving ethernet frame. + * If ethernet header aligns 4bytes, the ip header and upper header will not aligns 4bytes. + * The resean is ethernet header is 14bytes. + * And the max size of tcp & ip header is 128bytes. Normally it is 40bytes. + * So I set the default value between 128 to 256. + */ +static int fec_copy_threshold = -1; /* MII processing. We keep this as simple as possible. Requests are * placed on the list (if there is room). When the request is finished @@ -342,10 +382,10 @@ * 4-byte boundaries. Use bounce buffers to copy data * and get it aligned. Ugh. */ - if (bdp->cbd_bufaddr & 0x3) { + if ((bdp->cbd_bufaddr) & FEC_ALIGNMENT) { unsigned int index; index = bdp - fep->tx_bd_base; - memcpy(fep->tx_bounce[index], (void *) bdp->cbd_bufaddr, bdp->cbd_datlen); + memcpy(fep->tx_bounce[index], (void *) skb->data, skb->len); bdp->cbd_bufaddr = __pa(fep->tx_bounce[index]); } @@ -359,8 +399,8 @@ /* Push the data cache so the CPM does not get stale memory * data. */ - flush_dcache_range((unsigned long)skb->data, - (unsigned long)skb->data + skb->len); + fec_dcache_flush_range(__va(bdp->cbd_bufaddr), __va(bdp->cbd_bufaddr) + + bdp->cbd_datlen); /* Send it on its way. Tell FEC it's ready, interrupt when done, * it's the last BD of the frame, and to put the CRC on the end. @@ -373,7 +413,7 @@ dev->trans_start = jiffies; /* Trigger transmission start */ - fecp->fec_x_des_active = 0; + fecp->fec_x_des_active = 0x01000000; /* If this was the last BD in the ring, start at the beginning again. */ @@ -460,7 +500,7 @@ /* Handle receive event in its own function. */ - if (int_events & FEC_ENET_RXF) { + if (int_events & (FEC_ENET_RXF | FEC_ENET_RXB)) { ret = IRQ_HANDLED; fec_enet_rx(dev); } @@ -469,7 +509,7 @@ descriptors. FEC handles all errors, we just discover them as part of the transmit process. */ - if (int_events & FEC_ENET_TXF) { + if (int_events & (FEC_ENET_TXF | FEC_ENET_TXB)) { ret = IRQ_HANDLED; fec_enet_tx(dev); } @@ -572,6 +612,7 @@ struct sk_buff *skb; ushort pkt_len; __u8 *data; + int rx_index ; #ifdef CONFIG_M532x flush_cache_all(); @@ -588,7 +629,7 @@ bdp = fep->cur_rx; while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { - + rx_index = bdp - fep->rx_bd_base; #ifndef final_version /* Since we have allocated space to hold a complete frame, * the last indicator should be set. @@ -638,14 +679,31 @@ * include that when passing upstream as it messes up * bridging applications. */ - skb = dev_alloc_skb(pkt_len-4); + if ((pkt_len - 4) < fec_copy_threshold) { + skb = dev_alloc_skb(pkt_len); + } else { + skb = dev_alloc_skb(FEC_ENET_RX_FRSIZE); + } if (skb == NULL) { printk("%s: Memory squeeze, dropping packet.\n", dev->name); dev->stats.rx_dropped++; } else { - skb_put(skb,pkt_len-4); /* Make room */ - skb_copy_to_linear_data(skb, data, pkt_len-4); + if ((pkt_len - 4) < fec_copy_threshold) { + skb_reserve(skb, 2); /*skip 2bytes, so ipheader is align 4bytes*/ + skb_put(skb,pkt_len-4); /* Make room */ + skb_copy_to_linear_data(skb, data, pkt_len-4); + } else { + struct sk_buff * pskb = fep->rx_skbuff[rx_index]; + + fec_dcache_inv_range(skb->data, skb->data + + FEC_ENET_RX_FRSIZE); + fep->rx_skbuff[rx_index] = skb; + skb->data = FEC_ADDR_ALIGNMENT(skb->data); + bdp->cbd_bufaddr = __pa(skb->data); + skb_put(pskb,pkt_len-4); /* Make room */ + skb = pskb; + } skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); } @@ -672,7 +730,7 @@ * incoming frames. On a heavily loaded network, we should be * able to keep up at the expense of system resources. */ - fecp->fec_r_des_active = 0; + fecp->fec_r_des_active = 0x01000000; #endif } /* while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) */ fep->cur_rx = (cbd_t *)bdp; @@ -1207,6 +1265,26 @@ }, }; +static phy_info_t phy_info_lan8700 = { + 0x0007C0C, + "LAN8700", + (const phy_cmd_t []) { /* config */ + { mk_mii_read(MII_REG_CR), mii_parse_cr }, + { mk_mii_read(MII_REG_ANAR), mii_parse_anar }, + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* startup */ + { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */ + { mk_mii_read(MII_REG_SR), mii_parse_sr }, + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* act_int */ + { mk_mii_end, } + }, + (const phy_cmd_t []) { /* shutdown */ + { mk_mii_end, } + }, +}; /* ------------------------------------------------------------------------- */ static phy_info_t const * const phy_info[] = { @@ -1216,6 +1294,7 @@ &phy_info_am79c874, &phy_info_ks8721bl, &phy_info_dp83848, + &phy_info_lan8700, NULL }; @@ -1227,6 +1306,21 @@ #if defined(CONFIG_M5272) /* + * * do some initializtion based architecture of this chip + * */ +static void __inline__ fec_arch_init(void) +{ + return; +} +/* + * * do some cleanup based architecture of this chip + * */ +static void __inline__ fec_arch_exit(void) +{ + return; +} + +/* * Code specific to Coldfire 5272 setup. */ static void __inline__ fec_request_intrs(struct net_device *dev) @@ -1327,15 +1421,40 @@ *icrp = 0x0d000000; } -static void __inline__ fec_localhw_setup(void) +static void __inline__ fec_localhw_setup(struct net_device *dev) +{ +} + +/* + * invalidate dcache related with the virtual memory range(start, end) + */ +static void __inline__ fec_dcache_inv_range(void * start, void * end) +{ + return ; +} + +/* + * flush dcache related with the virtual memory range(start, end) + */ +static void __inline__ fec_dcache_flush_range(void * start, void * end) +{ + return ; +} + +/* + * map memory space (addr, addr+size) to uncachable erea. + */ +static unsigned long __inline__ fec_map_uncache(unsigned long addr, int size) { + return addr; } /* - * Do not need to make region uncached on 5272. + * unmap memory erea started with addr from uncachable erea. */ -static void __inline__ fec_uncache(unsigned long addr) +static void __inline__ fec_unmap_uncache(void * addr) { + return ; } /* ------------------------------------------------------------------------- */ @@ -1343,6 +1462,22 @@ #elif defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) /* + * do some initializtion based architecture of this chip + */ +static void __inline__ fec_arch_init(void) +{ + return; +} + +/* + * do some cleanup based architecture of this chip + */ +static void __inline__ fec_arch_exit(void) +{ + return; +} + +/* * Code specific to Coldfire 5230/5231/5232/5234/5235, * the 5270/5271/5274/5275 and 5280/5282 setups. */ @@ -1489,20 +1624,58 @@ { } -static void __inline__ fec_localhw_setup(void) +static void __inline__ fec_localhw_setup(struct net_device *dev) +{ +} +/* + * invalidate dcache related with the virtual memory range(start, end) + */ +static void __inline__ fec_dcache_inv_range(void * start, void * end) +{ + return ; +} + +/* + * flush dcache related with the virtual memory range(start, end) + */ +static void __inline__ fec_dcache_flush_range(void * start, void * end) +{ + return ; +} + +/* + * map memory space (addr, addr+size) to uncachable erea. + */ +static unsigned long __inline__ fec_map_uncache(unsigned long addr, int size) { + return addr; } /* - * Do not need to make region uncached on 5272. + * unmap memory erea started with addr from uncachable erea. */ -static void __inline__ fec_uncache(unsigned long addr) +static void __inline__ fec_unmap_uncache(void * addr) { + return ; } /* ------------------------------------------------------------------------- */ #elif defined(CONFIG_M520x) +/* + * do some initializtion based architecture of this chip + */ +static void __inline__ fec_arch_init(void) +{ + return; +} +/* + * do some cleanup based architecture of this chip + */ +static void __inline__ fec_arch_exit(void) +{ + return; +} /* * Code specific to Coldfire 520x @@ -1610,17 +1783,63 @@ { } -static void __inline__ fec_localhw_setup(void) +static void __inline__ fec_localhw_setup(struct net_device *dev) { } -static void __inline__ fec_uncache(unsigned long addr) +/* + * invalidate dcache related with the virtual memory range(start, end) + */ +static void __inline__ fec_dcache_inv_range(void * start, void * end) { + return ; } +/* + * flush dcache related with the virtual memory range(start, end) + */ +static void __inline__ fec_dcache_flush_range(void * start, void * end) +{ + return ; +} + +/* + * map memory space (addr, addr+size) to uncachable erea. + */ +static unsigned long __inline__ fec_map_uncache(unsigned long addr, int size) +{ + return addr; +} + +/* + * unmap memory erea started with addr from uncachable erea. + */ +static void __inline__ fec_unmap_uncache(void * addr) +{ + return ; +} + + /* ------------------------------------------------------------------------- */ #elif defined(CONFIG_M532x) + +/* + * do some initializtion based architecture of this chip + */ +static void __inline__ fec_arch_init(void) +{ + return; +} + +/* + * do some cleanup based architecture of this chip + */ +static void __inline__ fec_arch_exit(void) +{ + return; +} + /* * Code specific for M532x */ @@ -1749,21 +1968,297 @@ { } -static void __inline__ fec_localhw_setup(void) +static void __inline__ fec_localhw_setup(struct net_device *dev) { } /* - * Do not need to make region uncached on 532x. + * invalidate dcache related with the virtual memory range(start, end) */ -static void __inline__ fec_uncache(unsigned long addr) +static void __inline__ fec_dcache_inv_range(void * start, void * end) { + return ; +} + +/* + * flush dcache related with the virtual memory range(start, end) + */ +static void __inline__ fec_dcache_flush_range(void * start, void * end) +{ + return ; +} + +/* + * map memory space (addr, addr+size) to uncachable erea. + */ +static unsigned long __inline__ fec_map_uncache(unsigned long addr, int size) +{ + return addr; +} + +/* + * unmap memory erea started with addr from uncachable erea. + */ +static void __inline__ fec_unmap_uncache(void * addr) +{ + return ; } /* ------------------------------------------------------------------------- */ +#elif defined(CONFIG_ARCH_MXC) + +extern void gpio_fec_active(void); +extern void gpio_fec_inactive(void); +extern unsigned int expio_intr_fec; + +/* + * do some initializtion based architecture of this chip + */ +static void __inline__ fec_arch_init(void) +{ + struct clk *clk; + gpio_fec_active(); + clk = clk_get(NULL, "fec_clk"); + clk_enable(clk); + clk_put(clk); + return; +} +/* + * do some cleanup based architecture of this chip + */ +static void __inline__ fec_arch_exit(void) +{ + struct clk *clk; + clk = clk_get(NULL, "fec_clk"); + clk_disable(clk); + clk_put(clk); + gpio_fec_inactive(); + return; +} + +/* + * Code specific to Freescale i.MXC + */ +static void __inline__ fec_request_intrs(struct net_device *dev) +{ + /* Setup interrupt handlers. */ + if (request_irq(MXC_INT_FEC, fec_enet_interrupt, 0, "fec", dev) != 0) + panic("FEC: Could not allocate FEC IRQ(%d)!\n", MXC_INT_FEC); + /* TODO: disable now due to CPLD issue */ + if ((expio_intr_fec > 0) && + (request_irq(expio_intr_fec, mii_link_interrupt, 0, "fec(MII)", dev) != 0)) + panic("FEC: Could not allocate FEC(MII) IRQ(%d)!\n", expio_intr_fec); + disable_irq(expio_intr_fec); +} + +static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep) +{ + u32 rate; + struct clk *clk; + volatile fec_t *fecp; + fecp = fep->hwp; + fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04; + fecp->fec_x_cntrl = 0x00; + + /* + * Set MII speed to 2.5 MHz + */ + clk = clk_get(NULL, "fec_clk"); + rate = clk_get_rate(clk); + clk_put(clk); + fep->phy_speed = + ((((rate / 2 + 4999999) / 2500000) / 2) & 0x3F) << 1; + fecp->fec_mii_speed = fep->phy_speed; + fec_restart(dev, 0); +} + +#define FEC_IIM_BASE IO_ADDRESS(IIM_BASE_ADDR) +static void __inline__ fec_get_mac(struct net_device *dev) +{ + struct fec_enet_private *fep = netdev_priv(dev); + volatile fec_t *fecp; + unsigned char *iap, tmpaddr[ETH_ALEN]; + int i; + unsigned long fec_mac_base = FEC_IIM_BASE + MXC_IIMKEY0; + fecp = fep->hwp; + + if (fecp->fec_addr_low || fecp->fec_addr_high) { + *((unsigned long *) &tmpaddr[0]) = + be32_to_cpu(fecp->fec_addr_low); + *((unsigned short *) &tmpaddr[4]) = + be32_to_cpu(fecp->fec_addr_high); + iap = &tmpaddr[0]; + } else { + if (cpu_is_mx27_rev(CHIP_REV_2_0) > 0) + fec_mac_base = FEC_IIM_BASE + MXC_IIMMAC; + + memset(tmpaddr, 0, ETH_ALEN); + if (!(machine_is_mx35_3ds() || cpu_is_mx51())) { + /* + * Get MAC address from IIM. + * If it is all 1's or 0's, use the default. + */ + for (i = 0; i < ETH_ALEN; i++) + tmpaddr[ETH_ALEN-1-i] = + __raw_readb(fec_mac_base + i * 4); + } + iap = &tmpaddr[0]; + + if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) && + (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0)) + iap = fec_mac_default; + if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) && + (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff)) + iap = fec_mac_default; + } + + memcpy(dev->dev_addr, iap, ETH_ALEN); + + /* Adjust MAC if using default MAC address */ + if (iap == fec_mac_default) + dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index; +} + +#ifndef MODULE +static int fec_mac_setup(char *new_mac) +{ + char *ptr, *p = new_mac; + int i = 0; + + while (p && (*p) && i < 6) { + ptr = strchr(p, ':'); + if (ptr) + *ptr++ = '\0'; + + if (strlen(p)) { + unsigned long tmp = simple_strtoul(p, NULL, 16); + if (tmp > 0xff) + break; + fec_mac_default[i++] = tmp; + } + p = ptr; + } + + return 0; +} + +__setup("fec_mac=", fec_mac_setup); +#endif + +static void __inline__ fec_enable_phy_intr(void) +{ + if (expio_intr_fec > 0) + enable_irq(expio_intr_fec); +} + +static void __inline__ fec_disable_phy_intr(void) +{ + if (expio_intr_fec > 0) + disable_irq(expio_intr_fec); +} + +static void __inline__ fec_phy_ack_intr(void) +{ + if (expio_intr_fec > 0) + disable_irq(expio_intr_fec); +} + +#ifdef CONFIG_ARCH_MX25 +/* + * i.MX25 allows RMII mode to be configured via a gasket + */ +#define FEC_MIIGSK_CFGR_FRCONT (1 << 6) +#define FEC_MIIGSK_CFGR_LBMODE (1 << 4) +#define FEC_MIIGSK_CFGR_EMODE (1 << 3) +#define FEC_MIIGSK_CFGR_IF_MODE_MASK (3 << 0) +#define FEC_MIIGSK_CFGR_IF_MODE_MII (0 << 0) +#define FEC_MIIGSK_CFGR_IF_MODE_RMII (1 << 0) + +#define FEC_MIIGSK_ENR_READY (1 << 2) +#define FEC_MIIGSK_ENR_EN (1 << 1) + +static void __inline__ fec_localhw_setup(struct net_device *dev) +{ + struct fec_enet_private *fep = netdev_priv(dev); + volatile fec_t *fecp = fep->hwp; + /* + * Set up the MII gasket for RMII mode + */ + printk("%s: enable RMII gasket\n", dev->name); + + /* disable the gasket and wait */ + fecp->fec_miigsk_enr = 0; + while (fecp->fec_miigsk_enr & FEC_MIIGSK_ENR_READY) + udelay(1); + + /* configure the gasket for RMII, 50 MHz, no loopback, no echo */ + fecp->fec_miigsk_cfgr = FEC_MIIGSK_CFGR_IF_MODE_RMII; + + /* re-enable the gasket */ + fecp->fec_miigsk_enr = FEC_MIIGSK_ENR_EN; +} #else +static void __inline__ fec_localhw_setup(struct net_device *dev) +{ +} +#endif + +/* + * invalidate dcache related with the virtual memory range(start, end) + */ +static void __inline__ fec_dcache_inv_range(void * start, void * end) +{ + dma_sync_single_for_device(NULL, (unsigned long)__pa(start), + (unsigned long)(end - start), + DMA_FROM_DEVICE); + return ; +} + +/* + * flush dcache related with the virtual memory range(start, end) + */ +static void __inline__ fec_dcache_flush_range(void * start, void * end) +{ + dma_sync_single_for_device(NULL, (unsigned long)__pa(start), + (unsigned long)(end - start), DMA_TO_DEVICE); + return ; +} + +/* + * map memory space (addr, addr+size) to uncachable erea. + */ +static unsigned long __inline__ fec_map_uncache(unsigned long addr, int size) +{ + return (unsigned long)ioremap(__pa(addr), size); +} + +/* + * unmap memory erea started with addr from uncachable erea. + */ +static void __inline__ fec_unmap_uncache(void * addr) +{ + return iounmap(addr); +} + +/* ------------------------------------------------------------------------- */ + +#else +/* + * do some initializtion based architecture of this chip + */ +static void __inline__ fec_arch_init(void) +{ + return; +} +/* + * do some cleanup based architecture of this chip + */ +static void __inline__ fec_arch_exit(void) +{ + return; +} /* * Code specific to the MPC860T setup. @@ -1831,7 +2326,7 @@ { } -static void __inline__ fec_localhw_setup(void) +static void __inline__ fec_localhw_setup(struct net_device *dev) { volatile fec_t *fecp; @@ -1842,12 +2337,40 @@ fecp->fec_fun_code = 0x78000000; } -static void __inline__ fec_uncache(unsigned long addr) +/* + * invalidate dcache related with the virtual memory range(start, end) + */ +static void __inline__ fec_dcache_inv_range(void * start, void * end) +{ + return ; +} + +/* + * flush dcache related with the virtual memory range(start, end) + */ +static void __inline__ fec_dcache_flush_range(void * start, void * end) +{ + return ; +} + +/* + * map memory space (addr, addr+size) to uncachable erea. + */ +static unsigned long __inline__ fec_map_uncache(unsigned long addr, int size) { pte_t *pte; pte = va_to_pte(mem_addr); pte_val(*pte) |= _PAGE_NO_CACHE; flush_tlb_page(init_mm.mmap, mem_addr); + return addr; +} + +/* + * * unmap memory erea started with addr from uncachable erea. + * */ +static void __inline__ fec_unmap_uncache(void * addr) +{ + return ; } #endif @@ -2073,10 +2596,14 @@ #if 0 disable_irq(fep->mii_irq); /* disable now, enable later */ #endif - - mii_do_cmd(dev, fep->phy->ack_int); - mii_do_cmd(dev, phy_cmd_relink); /* restart and display status */ - + /* + * Some board will trigger phy interrupt before phy enable. + * And at that moment , fep->phy is not initialized. + */ + if (fep->phy) { + mii_do_cmd(dev, fep->phy->ack_int); + mii_do_cmd(dev, phy_cmd_relink); /* restart and display status */ + } return IRQ_HANDLED; } #endif @@ -2122,7 +2649,6 @@ fec_restart(dev, 1); } - netif_start_queue(dev); fep->opened = 1; return 0; /* Success */ } @@ -2135,9 +2661,9 @@ /* Don't know what to do yet. */ fep->opened = 0; - netif_stop_queue(dev); - fec_stop(dev); - + if (fep->link) { + fec_stop(dev); + } return 0; } @@ -2248,6 +2774,7 @@ unsigned long mem_addr; volatile cbd_t *bdp; cbd_t *cbd_base; + struct sk_buff* pskb; volatile fec_t *fecp; int i, j; static int index = 0; @@ -2256,6 +2783,8 @@ if (index >= FEC_MAX_PORTS) return -ENXIO; + fep->net = dev; + /* Allocate memory for buffer descriptors. */ mem_addr = __get_free_page(GFP_KERNEL); @@ -2264,6 +2793,7 @@ return -ENOMEM; } + fep->cbd_mem_base = (void *)mem_addr; spin_lock_init(&fep->hw_lock); spin_lock_init(&fep->mii_lock); @@ -2288,10 +2818,14 @@ */ fec_get_mac(dev); - cbd_base = (cbd_t *)mem_addr; - /* XXX: missing check for allocation failure */ + cbd_base = (cbd_t *)fec_map_uncache(mem_addr, PAGE_SIZE); + if (cbd_base == NULL) { + free_page(mem_addr); + printk("FEC: map descriptor memory to uncacheable failed?\n"); + return -ENOMEM; + } - fec_uncache(mem_addr); + /* XXX: missing check for allocation failure */ /* Set receive and transmit descriptor base. */ @@ -2306,25 +2840,26 @@ /* Initialize the receive buffer descriptors. */ bdp = fep->rx_bd_base; - for (i=0; icbd_sc = BD_ENET_RX_EMPTY; - bdp->cbd_bufaddr = __pa(mem_addr); - mem_addr += FEC_ENET_RX_FRSIZE; - bdp++; + for (i=0; i0; i--) { + if( fep->rx_skbuff[i-1] ) { + kfree_skb(fep->rx_skbuff[i-1]); + fep->rx_skbuff[i-1] = NULL; + } + } + printk("FEC: allocate skb fail when initializing rx buffer \n"); + free_page(mem_addr); + return -ENOMEM; } + fep->rx_skbuff[i] = pskb; + fec_dcache_inv_range(pskb->data, pskb->data + + FEC_ENET_RX_FRSIZE); + pskb->data = FEC_ADDR_ALIGNMENT(pskb->data); + bdp->cbd_sc = BD_ENET_RX_EMPTY; + bdp->cbd_bufaddr = __pa(pskb->data); } - /* Set the last buffer to wrap. */ bdp--; @@ -2357,19 +2892,23 @@ /* Set receive and transmit descriptor base. */ - fecp->fec_r_des_start = __pa((uint)(fep->rx_bd_base)); - fecp->fec_x_des_start = __pa((uint)(fep->tx_bd_base)); + fecp->fec_r_des_start = __pa((uint)(fep->cbd_mem_base)); + fecp->fec_x_des_start = __pa((uint)(fep->cbd_mem_base + RX_RING_SIZE*sizeof(cbd_t))); /* Install our interrupt handlers. This varies depending on * the architecture. */ fec_request_intrs(dev); + /* Clear and enable interrupts */ + fecp->fec_ievent = FEC_ENET_MASK; + fecp->fec_imask = FEC_ENET_TXF | FEC_ENET_TXB | FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII; + fecp->fec_grp_hash_table_high = 0; fecp->fec_grp_hash_table_low = 0; fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; fecp->fec_ecntrl = 2; - fecp->fec_r_des_active = 0; + fecp->fec_r_des_active = 0x01000000; #ifndef CONFIG_M5272 fecp->fec_hash_table_high = 0; fecp->fec_hash_table_low = 0; @@ -2392,10 +2931,6 @@ /* setup MII interface */ fec_set_mii(dev, fep); - /* Clear and enable interrupts */ - fecp->fec_ievent = 0xffc00000; - fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII); - /* Queue up command to detect the PHY and initialize the * remainder of the interface. */ @@ -2427,9 +2962,15 @@ fecp->fec_ecntrl = 1; udelay(10); + /* Enable interrupts we wish to service. + */ + fecp->fec_imask = FEC_ENET_TXF | FEC_ENET_TXB | FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII; + /* Clear any outstanding interrupt. - */ - fecp->fec_ievent = 0xffc00000; + * + */ + fecp->fec_ievent = FEC_ENET_MASK; + fec_enable_phy_intr(); /* Set station address. @@ -2445,12 +2986,12 @@ */ fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; - fec_localhw_setup(); + fec_localhw_setup(dev); /* Set receive and transmit descriptor base. */ - fecp->fec_r_des_start = __pa((uint)(fep->rx_bd_base)); - fecp->fec_x_des_start = __pa((uint)(fep->tx_bd_base)); + fecp->fec_r_des_start = __pa((uint)(fep->cbd_mem_base)); + fecp->fec_x_des_start = __pa((uint)(fep->cbd_mem_base + RX_RING_SIZE*sizeof(cbd_t))); fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; fep->cur_rx = fep->rx_bd_base; @@ -2517,11 +3058,9 @@ /* And last, enable the transmit and receive processing. */ fecp->fec_ecntrl = 2; - fecp->fec_r_des_active = 0; + fecp->fec_r_des_active = 0x01000000; - /* Enable interrupts we wish to service. - */ - fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII); + netif_start_queue(dev); } static void @@ -2530,6 +3069,8 @@ volatile fec_t *fecp; struct fec_enet_private *fep; + netif_stop_queue(dev); + fep = netdev_priv(dev); fecp = fep->hwp; @@ -2565,6 +3106,7 @@ DECLARE_MAC_BUF(mac); printk("FEC ENET Version 0.2\n"); + fec_arch_init(); for (i = 0; (i < FEC_MAX_PORTS); i++) { dev = alloc_etherdev(sizeof(struct fec_enet_private)); --- linux-2.6.28.orig/drivers/net/bnx2x_main.c +++ linux-2.6.28/drivers/net/bnx2x_main.c @@ -8079,6 +8079,9 @@ struct bnx2x *bp = netdev_priv(dev); int rc; + if (!netif_running(dev)) + return -EAGAIN; + DP(BNX2X_MSG_NVM, "ethtool_eeprom: cmd %d\n" DP_LEVEL " magic 0x%x offset 0x%x (%d) len 0x%x (%d)\n", eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset, --- linux-2.6.28.orig/drivers/net/Kconfig +++ linux-2.6.28/drivers/net/Kconfig @@ -978,6 +978,18 @@ called smc911x. If you want to compile it as a module, say M here and read +config SMSC911X + tristate "SMSC LAN911x/LAN921x families embedded ethernet support" + depends on NET_ETHERNET + select CRC32 + select MII + ---help--- + Say Y here if you want support for SMSC LAN911x and LAN921x families + of ethernet controllers. + To compile this driver as a module, choose M here and read + . The module + will be called smsc911x. + config NET_VENDOR_RACAL bool "Racal-Interlan (Micom) NI cards" depends on ISA @@ -1811,10 +1823,10 @@ config FEC bool "FEC ethernet controller (of ColdFire CPUs)" - depends on M523x || M527x || M5272 || M528x || M520x + depends on M523x || M527x || M5272 || M528x || M520x || ARCH_MX51 help Say Y here if you want to use the built-in 10/100 Fast ethernet - controller on some Motorola ColdFire processors. + controller on some Motorola ColdFire/Freescale processors. config FEC2 bool "Second FEC ethernet controller (on some ColdFire CPUs)" --- linux-2.6.28.orig/drivers/net/sungem.c +++ linux-2.6.28/drivers/net/sungem.c @@ -2222,6 +2222,8 @@ gp->running = 1; + napi_enable(&gp->napi); + if (gp->lstate == link_up) { netif_carrier_on(gp->dev); gem_set_link_modes(gp); @@ -2239,6 +2241,8 @@ spin_lock_irqsave(&gp->lock, flags); spin_lock(&gp->tx_lock); + napi_disable(&gp->napi); + gp->running = 0; gem_reset(gp); gem_clean_rings(gp); @@ -2339,8 +2343,6 @@ if (!gp->asleep) rc = gem_do_start(dev); gp->opened = (rc == 0); - if (gp->opened) - napi_enable(&gp->napi); mutex_unlock(&gp->pm_mutex); @@ -2477,8 +2479,6 @@ /* Re-attach net device */ netif_device_attach(dev); - - napi_enable(&gp->napi); } spin_lock_irqsave(&gp->lock, flags); --- linux-2.6.28.orig/drivers/net/smsc911x.c +++ linux-2.6.28/drivers/net/smsc911x.c @@ -0,0 +1,2253 @@ +/*************************************************************************** + * + * Copyright (C) 2004-2007 SMSC + * Copyright (C) 2005 ARM + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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. + * + *************************************************************************** + * Rewritten, heavily based on smsc911x simple driver by SMSC. + * Partly uses io macros from smc91x.c by Nicolas Pitre + * + * Supported devices: + * LAN9115, LAN9116, LAN9117, LAN9118 + * LAN9215, LAN9216, LAN9217, LAN9218 + * + * History: + * 05/05/2005 bahadir.balban@arm.com + * - Transition to linux coding style + * - Platform driver and module interface + * + * 17/07/2006 steve.glendinning@smsc.com + * - Added support for LAN921x family + * - Added workaround for multicast filters + * + * 31/07/2006 steve.glendinning@smsc.com + * - Removed tasklet, using NAPI poll instead + * - Multiple device support + * - Large tidy-up following feedback from netdev list + * + * 03/08/2006 steve.glendinning@smsc.com + * - Added ethtool support + * - Convert to use generic MII interface + * + * 04/08/2006 bahadir.balban@arm.com + * - Added ethtool eeprom r/w support + * + * 17/06/2007 steve.glendinning@smsc.com + * - Incorporate changes from Bill Gatliff and Russell King + * + * 04/07/2007 steve.glendinning@smsc.com + * - move irq configuration to platform_device + * - fix link poller after interface is stopped and restarted + * + * 13/07/2007 bahadir.balban@arm.com + * - set irq polarity before requesting irq + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "smsc911x.h" + +#define SMSC_CHIPNAME "smsc911x" +#define SMSC_DRV_VERSION "2007-07-13" + +MODULE_LICENSE("GPL"); + +struct smsc911x_data { + void __iomem *ioaddr; + + unsigned int idrev; + unsigned int generation; /* used to decide which workarounds apply */ + + /* device configuration */ + unsigned int irq_polarity; + unsigned int irq_type; + + /* This needs to be acquired before calling any of below: + * smsc911x_mac_read(), smsc911x_mac_write() + * smsc911x_phy_read(), smsc911x_phy_write() + */ + spinlock_t phy_lock; + + struct net_device_stats stats; + struct mii_if_info mii; + unsigned int using_extphy; + u32 msg_enable; +#ifdef USE_LED1_WORK_AROUND + unsigned int gpio_setting; + unsigned int gpio_orig_setting; +#endif + struct net_device *netdev; + struct napi_struct napi; + struct timer_list link_poll_timer; + unsigned int stop_link_poll; + + unsigned int software_irq_signal; + +#ifdef USE_PHY_WORK_AROUND +#define MIN_PACKET_SIZE (64) + char loopback_tx_pkt[MIN_PACKET_SIZE]; + char loopback_rx_pkt[MIN_PACKET_SIZE]; + unsigned int resetcount; +#endif + + /* Members for Multicast filter workaround */ + unsigned int multicast_update_pending; + unsigned int set_bits_mask; + unsigned int clear_bits_mask; + unsigned int hashhi; + unsigned int hashlo; +}; + +#if SMSC_CAN_USE_32BIT + +static inline u32 smsc911x_reg_read(struct smsc911x_data *pdata, u32 reg) +{ + return readl(pdata->ioaddr + reg); +} + +static inline void smsc911x_reg_write(u32 val, struct smsc911x_data *pdata, + u32 reg) +{ + writel(val, pdata->ioaddr + reg); +} + +#elif SMSC_CAN_USE_SPI + +static u32 smsc911x_reg_read(struct smsc911x_data *pdata, u32 reg) +{ + u32 reg_val; + unsigned long flags; + + local_irq_save(flags); + reg_val = spi_cpld_read(reg); + local_irq_restore(flags); + + return reg_val; +} + +static void smsc911x_reg_write(u32 val, struct smsc911x_data *pdata, + u32 reg) +{ + unsigned long flags; + + local_irq_save(flags); + spi_cpld_write(reg, val); + local_irq_restore(flags); +} + +#else /* SMSC_CAN_USE_32BIT */ + +static inline u32 smsc911x_reg_read(struct smsc911x_data *pdata, u32 reg) +{ + u32 reg_val; + unsigned long flags; + + /* these two 16-bit reads must be performed consecutively, so must + * not be interrupted by our own ISR (which would start another + * read operation) */ + local_irq_save(flags); + reg_val = ((readw(pdata->ioaddr + reg) & 0xFFFF) | + ((readw(pdata->ioaddr + reg + 2) & 0xFFFF) << 16)); + local_irq_restore(flags); + + return reg_val; +} + +static inline void smsc911x_reg_write(u32 val, struct smsc911x_data *pdata, + u32 reg) +{ + unsigned long flags; + + /* these two 16-bit writes must be performed consecutively, so must + * not be interrupted by our own ISR (which would start another + * read operation) */ + local_irq_save(flags); + writew(val & 0xFFFF, pdata->ioaddr + reg); + writew((val >> 16) & 0xFFFF, pdata->ioaddr + reg + 2); + local_irq_restore(flags); +} + +#endif /* SMSC_CAN_USE_32BIT */ + +/* Writes a packet to the TX_DATA_FIFO */ +static inline void +smsc911x_tx_writefifo(struct smsc911x_data *pdata, unsigned int *buf, + unsigned int wordcount) +{ + while (wordcount--) + smsc911x_reg_write(*buf++, pdata, TX_DATA_FIFO); +} + +/* Reads a packet out of the RX_DATA_FIFO */ +static inline void +smsc911x_rx_readfifo(struct smsc911x_data *pdata, unsigned int *buf, + unsigned int wordcount) +{ + while (wordcount--) + *buf++ = smsc911x_reg_read(pdata, RX_DATA_FIFO); +} + +/* waits for MAC not busy, with timeout. Only called by smsc911x_mac_read + * and smsc911x_mac_write, so assumes phy_lock is held */ +static int smsc911x_mac_notbusy(struct smsc911x_data *pdata) +{ + int i; + u32 val; + + for (i = 0; i < 40; i++) { + val = smsc911x_reg_read(pdata, MAC_CSR_CMD); + if (!(val & MAC_CSR_CMD_CSR_BUSY_)) + return 1; + } + SMSC_WARNING("Timed out waiting for MAC not BUSY. " + "MAC_CSR_CMD: 0x%08X", val); + return 0; +} + +/* Fetches a MAC register value. Assumes phy_lock is acquired */ +static u32 smsc911x_mac_read(struct smsc911x_data *pdata, unsigned int offset) +{ + unsigned int temp; + +#ifdef CONFIG_DEBUG_SPINLOCK + if (!spin_is_locked(&pdata->phy_lock)) + SMSC_WARNING("phy_lock not held"); +#endif /* CONFIG_DEBUG_SPINLOCK */ + + temp = smsc911x_reg_read(pdata, MAC_CSR_CMD); + if (unlikely(temp & MAC_CSR_CMD_CSR_BUSY_)) { + SMSC_WARNING("smsc911x_mac_read failed, MAC busy at entry"); + return 0xFFFFFFFF; + } + + /* Send the MAC cmd */ + smsc911x_reg_write(((offset & 0xFF) | MAC_CSR_CMD_CSR_BUSY_ + | MAC_CSR_CMD_R_NOT_W_), pdata, MAC_CSR_CMD); + + /* Workaround for hardware read-after-write restriction */ + temp = smsc911x_reg_read(pdata, BYTE_TEST); + + /* Wait for the read to happen */ + if (likely(smsc911x_mac_notbusy(pdata))) + return smsc911x_reg_read(pdata, MAC_CSR_DATA); + + SMSC_WARNING("smsc911x_mac_read failed, MAC busy after read"); + return 0xFFFFFFFF; +} + +/* Set a mac register, phy_lock must be acquired before calling */ +static void smsc911x_mac_write(struct smsc911x_data *pdata, + unsigned int offset, u32 val) +{ + unsigned int temp; + +#ifdef CONFIG_DEBUG_SPINLOCK + if (!spin_is_locked(&pdata->phy_lock)) + SMSC_WARNING("phy_lock not held"); +#endif /* CONFIG_DEBUG_SPINLOCK */ + + temp = smsc911x_reg_read(pdata, MAC_CSR_CMD); + if (unlikely(temp & MAC_CSR_CMD_CSR_BUSY_)) { + SMSC_WARNING("smsc911x_mac_write failed, MAC busy at entry"); + return; + } + + /* Send data to write */ + smsc911x_reg_write(val, pdata, MAC_CSR_DATA); + + /* Write the actual data */ + smsc911x_reg_write(((offset & 0xFF) | MAC_CSR_CMD_CSR_BUSY_), pdata, + MAC_CSR_CMD); + + /* Workaround for hardware read-after-write restriction */ + temp = smsc911x_reg_read(pdata, BYTE_TEST); + + /* Wait for the write to complete */ + if (likely(smsc911x_mac_notbusy(pdata))) + return; + + SMSC_WARNING("smsc911x_mac_write failed, MAC busy after write"); +} + +/* Gets a phy register, phy_lock must be acquired before calling */ +static u16 smsc911x_phy_read(struct smsc911x_data *pdata, unsigned int index) +{ + unsigned int addr; + int i; + +#ifdef CONFIG_DEBUG_SPINLOCK + if (!spin_is_locked(&pdata->phy_lock)) + SMSC_WARNING("phy_lock not held"); +#endif /* CONFIG_DEBUG_SPINLOCK */ + + /* Confirm MII not busy */ + if (unlikely(smsc911x_mac_read(pdata, MII_ACC) & MII_ACC_MII_BUSY_)) { + SMSC_WARNING("MII is busy in smsc911x_phy_read???"); + return 0; + } + + /* Set the address, index & direction (read from PHY) */ + addr = (((pdata->mii.phy_id) & 0x1F) << 11) + | ((index & 0x1F) << 6); + smsc911x_mac_write(pdata, MII_ACC, addr); + + /* Wait for read to complete w/ timeout */ + for (i = 0; i < 100; i++) { + /* See if MII is finished yet */ + if (!(smsc911x_mac_read(pdata, MII_ACC) & MII_ACC_MII_BUSY_)) { + return smsc911x_mac_read(pdata, MII_DATA); + } + } + SMSC_WARNING("Timed out waiting for MII write to finish"); + return 0xFFFF; +} + +/* Sets a phy register, phy_lock must be acquired before calling */ +static void smsc911x_phy_write(struct smsc911x_data *pdata, + unsigned int index, u16 val) +{ + unsigned int addr; + int i; + +#ifdef CONFIG_DEBUG_SPINLOCK + if (!spin_is_locked(&pdata->phy_lock)) + SMSC_WARNING("phy_lock not held"); +#endif /* CONFIG_DEBUG_SPINLOCK */ + + /* Confirm MII not busy */ + if (unlikely(smsc911x_mac_read(pdata, MII_ACC) & MII_ACC_MII_BUSY_)) { + SMSC_WARNING("MII is busy in smsc911x_write_phy???"); + return; + } + + /* Put the data to write in the MAC */ + smsc911x_mac_write(pdata, MII_DATA, val); + + /* Set the address, index & direction (write to PHY) */ + addr = (((pdata->mii.phy_id) & 0x1F) << 11) | + ((index & 0x1F) << 6) | MII_ACC_MII_WRITE_; + smsc911x_mac_write(pdata, MII_ACC, addr); + + /* Wait for write to complete w/ timeout */ + for (i = 0; i < 100; i++) { + /* See if MII is finished yet */ + if (!(smsc911x_mac_read(pdata, MII_ACC) & MII_ACC_MII_BUSY_)) + return; + } + SMSC_WARNING("Timed out waiting for MII write to finish"); +} + +static int smsc911x_mdio_read(struct net_device *dev, int phy_id, int location) +{ + struct smsc911x_data *pdata = netdev_priv(dev); + unsigned long flags; + int reg; + + spin_lock_irqsave(&pdata->phy_lock, flags); + reg = smsc911x_phy_read(pdata, location); + spin_unlock_irqrestore(&pdata->phy_lock, flags); + + return reg; +} + +static void smsc911x_mdio_write(struct net_device *dev, int phy_id, + int location, int val) +{ + struct smsc911x_data *pdata = netdev_priv(dev); + unsigned long flags; + + spin_lock_irqsave(&pdata->phy_lock, flags); + smsc911x_phy_write(pdata, location, val); + spin_unlock_irqrestore(&pdata->phy_lock, flags); +} + +/* Autodetects and initialises external phy for SMSC9115 and SMSC9117 flavors. + * If something goes wrong, returns -ENODEV to revert back to internal phy. + * Performed at initialisation only, so interrupts are enabled */ +static int smsc911x_phy_initialise_external(struct smsc911x_data *pdata) +{ + unsigned int address; + unsigned int hwcfg; + unsigned int phyid1; + unsigned int phyid2; + + hwcfg = smsc911x_reg_read(pdata, HW_CFG); + + /* External phy is requested, supported, and detected */ + if (hwcfg & HW_CFG_EXT_PHY_DET_) { + + /* Attempt to switch to external phy for auto-detecting + * its address. Assuming tx and rx are stopped because + * smsc911x_phy_initialise is called before + * smsc911x_rx_initialise and tx_initialise. + */ + + /* Disable phy clocks to the MAC */ + hwcfg &= (~HW_CFG_PHY_CLK_SEL_); + hwcfg |= HW_CFG_PHY_CLK_SEL_CLK_DIS_; + smsc911x_reg_write(hwcfg, pdata, HW_CFG); + udelay(10); /* Enough time for clocks to stop */ + + /* Switch to external phy */ + hwcfg |= HW_CFG_EXT_PHY_EN_; + smsc911x_reg_write(hwcfg, pdata, HW_CFG); + + /* Enable phy clocks to the MAC */ + hwcfg &= (~HW_CFG_PHY_CLK_SEL_); + hwcfg |= HW_CFG_PHY_CLK_SEL_EXT_PHY_; + smsc911x_reg_write(hwcfg, pdata, HW_CFG); + udelay(10); /* Enough time for clocks to restart */ + + hwcfg |= HW_CFG_SMI_SEL_; + smsc911x_reg_write(hwcfg, pdata, HW_CFG); + + /* Auto-detect PHY */ + spin_lock_irq(&pdata->phy_lock); + for (address = 0; address <= 31; address++) { + pdata->mii.phy_id = address; + phyid1 = smsc911x_phy_read(pdata, MII_PHYSID1); + phyid2 = smsc911x_phy_read(pdata, MII_PHYSID2); + if ((phyid1 != 0xFFFFU) || (phyid2 != 0xFFFFU)) { + SMSC_TRACE("Detected PHY at address = " + "0x%02X = %d", address, address); + break; + } + } + spin_unlock_irq(&pdata->phy_lock); + + if ((phyid1 == 0xFFFFU) && (phyid2 == 0xFFFFU)) { + SMSC_WARNING("External PHY is not accessable, " + "using internal PHY instead"); + /* Revert back to internal phy settings. */ + + /* Disable phy clocks to the MAC */ + hwcfg &= (~HW_CFG_PHY_CLK_SEL_); + hwcfg |= HW_CFG_PHY_CLK_SEL_CLK_DIS_; + smsc911x_reg_write(hwcfg, pdata, HW_CFG); + udelay(10); /* Enough time for clocks to stop */ + + /* Switch to internal phy */ + hwcfg &= (~HW_CFG_EXT_PHY_EN_); + smsc911x_reg_write(hwcfg, pdata, HW_CFG); + + /* Enable phy clocks to the MAC */ + hwcfg &= (~HW_CFG_PHY_CLK_SEL_); + hwcfg |= HW_CFG_PHY_CLK_SEL_INT_PHY_; + smsc911x_reg_write(hwcfg, pdata, HW_CFG); + udelay(10); /* Enough time for clocks to restart */ + + hwcfg &= (~HW_CFG_SMI_SEL_); + smsc911x_reg_write(hwcfg, pdata, HW_CFG); + /* Use internal phy */ + return -ENODEV; + } else { + SMSC_TRACE("Successfully switched to external PHY"); + pdata->using_extphy = 1; + } + } else { + SMSC_WARNING("No external PHY detected."); + SMSC_WARNING("Using internal PHY instead."); + /* Use internal phy */ + return -ENODEV; + } + return 0; +} + +/* called by phy_initialise and loopback test */ +static int smsc911x_phy_reset(struct smsc911x_data *pdata) +{ + unsigned int temp; + unsigned int i = 100000; + unsigned long flags; + + SMSC_TRACE("Performing PHY BCR Reset"); + spin_lock_irqsave(&pdata->phy_lock, flags); + smsc911x_phy_write(pdata, MII_BMCR, BMCR_RESET); + do { + udelay(10); + temp = smsc911x_phy_read(pdata, MII_BMCR); + } while ((i--) && (temp & BMCR_RESET)); + spin_unlock_irqrestore(&pdata->phy_lock, flags); + + if (temp & BMCR_RESET) { + SMSC_WARNING("PHY reset failed to complete."); + return 0; + } + /* Extra delay required because the phy may not be completed with + * its reset when BMCR_RESET is cleared. Specs say 256 uS is + * enough delay but using 1ms here to be safe + */ + msleep(1); + + return 1; +} + +/* Fetches a tx status out of the status fifo */ +static unsigned int smsc911x_tx_get_txstatus(struct smsc911x_data *pdata) +{ + unsigned int result = + smsc911x_reg_read(pdata, TX_FIFO_INF) & TX_FIFO_INF_TSUSED_; + + if (result != 0) + result = smsc911x_reg_read(pdata, TX_STATUS_FIFO); + + return result; +} + +/* Fetches the next rx status */ +static unsigned int smsc911x_rx_get_rxstatus(struct smsc911x_data *pdata) +{ + unsigned int result = + smsc911x_reg_read(pdata, RX_FIFO_INF) & RX_FIFO_INF_RXSUSED_; + + if (result != 0) + result = smsc911x_reg_read(pdata, RX_STATUS_FIFO); + + return result; +} + +#ifdef USE_PHY_WORK_AROUND +static int smsc911x_phy_check_loopbackpkt(struct smsc911x_data *pdata) +{ + unsigned int tries; + u32 wrsz; + u32 rdsz; + u32 bufp; + + for (tries = 0; tries < 10; tries++) { + unsigned int txcmd_a; + unsigned int txcmd_b; + unsigned int status; + unsigned int pktlength; + unsigned int i; + + /* Zero-out rx packet memory */ + memset(pdata->loopback_rx_pkt, 0, MIN_PACKET_SIZE); + + /* Write tx packet to 118 */ + txcmd_a = (((unsigned int)pdata->loopback_tx_pkt) + & 0x03) << 16; + txcmd_a |= TX_CMD_A_FIRST_SEG_ | TX_CMD_A_LAST_SEG_; + txcmd_a |= MIN_PACKET_SIZE; + + txcmd_b = MIN_PACKET_SIZE << 16 | MIN_PACKET_SIZE; + + smsc911x_reg_write(txcmd_a, pdata, TX_DATA_FIFO); + smsc911x_reg_write(txcmd_b, pdata, TX_DATA_FIFO); + + bufp = ((u32) pdata->loopback_tx_pkt) & 0xFFFFFFFC; + wrsz = MIN_PACKET_SIZE + 3; + wrsz += (((u32) pdata->loopback_tx_pkt) & 0x3); + wrsz >>= 2; + + smsc911x_tx_writefifo(pdata, (unsigned int *)bufp, wrsz); + + /* Wait till transmit is done */ + i = 60; + do { + udelay(5); + status = smsc911x_tx_get_txstatus(pdata); + } while ((i--) && (!status)); + + if (!status) { + SMSC_WARNING("Failed to transmit during loopback test"); + continue; + } + if (status & TX_STS_ES_) { + SMSC_WARNING("Transmit encountered errors during " + "loopback test"); + continue; + } + + /* Wait till receive is done */ + i = 60; + do { + udelay(5); + status = smsc911x_rx_get_rxstatus(pdata); + } while ((i--) && (!status)); + + if (!status) { + SMSC_WARNING("Failed to receive during loopback test"); + continue; + } + if (status & RX_STS_ES_) { + SMSC_WARNING("Receive encountered errors during " + "loopback test"); + continue; + } + + pktlength = ((status & 0x3FFF0000UL) >> 16); + bufp = (u32)pdata->loopback_rx_pkt; + rdsz = pktlength + 3; + rdsz += ((u32)pdata->loopback_rx_pkt) & 0x3; + rdsz >>= 2; + + smsc911x_rx_readfifo(pdata, (unsigned int *)bufp, rdsz); + + if (pktlength != (MIN_PACKET_SIZE + 4)) { + SMSC_WARNING("Unexpected packet size during " + "loop back test, size=%d, " + "will retry", pktlength); + } else { + unsigned int j; + int mismatch = 0; + for (j = 0; j < MIN_PACKET_SIZE; j++) { + if (pdata->loopback_tx_pkt[j] + != pdata->loopback_rx_pkt[j]) { + mismatch = 1; + break; + } + } + if (!mismatch) { + SMSC_TRACE("Successfully verified " + "loopback packet"); + return 1; + } else { + SMSC_WARNING("Data miss match during " + "loop back test, will retry."); + } + } + } + + return 0; +} + +static int smsc911x_phy_loopbacktest(struct smsc911x_data *pdata) +{ + int result = 0; + unsigned int i; + unsigned int val; + unsigned long flags; + + /* Initialise tx packet */ + for (i = 0; i < 6; i++) { + /* Use broadcast destination address */ + pdata->loopback_tx_pkt[i] = (char)0xFF; + } + + for (i = 6; i < 12; i++) { + /* Use incrementing source address */ + pdata->loopback_tx_pkt[i] = (char)i; + } + + /* Set length type field */ + pdata->loopback_tx_pkt[12] = 0x00; + pdata->loopback_tx_pkt[13] = 0x00; + for (i = 14; i < MIN_PACKET_SIZE; i++) { + pdata->loopback_tx_pkt[i] = (char)i; + } + + val = smsc911x_reg_read(pdata, HW_CFG); + val &= HW_CFG_TX_FIF_SZ_; + val |= HW_CFG_SF_; + smsc911x_reg_write(val, pdata, HW_CFG); + + smsc911x_reg_write(TX_CFG_TX_ON_, pdata, TX_CFG); + smsc911x_reg_write((((unsigned int)pdata->loopback_rx_pkt) + & 0x03) << 8, pdata, RX_CFG); + + for (i = 0; i < 10; i++) { + /* Set PHY to 10/FD, no ANEG, and loopback mode */ + spin_lock_irqsave(&pdata->phy_lock, flags); + smsc911x_phy_write(pdata, MII_BMCR, 0x4100); + + /* Enable MAC tx/rx, FD */ + smsc911x_mac_write(pdata, MAC_CR, MAC_CR_FDPX_ + | MAC_CR_TXEN_ | MAC_CR_RXEN_); + spin_unlock_irqrestore(&pdata->phy_lock, flags); + + if (smsc911x_phy_check_loopbackpkt(pdata)) { + result = 1; + break; + } + pdata->resetcount++; + + /* Disable MAC rx */ + spin_lock_irqsave(&pdata->phy_lock, flags); + smsc911x_mac_write(pdata, MAC_CR, 0); + spin_unlock_irqrestore(&pdata->phy_lock, flags); + + smsc911x_phy_reset(pdata); + } + + /* Disable MAC */ + spin_lock_irqsave(&pdata->phy_lock, flags); + smsc911x_mac_write(pdata, MAC_CR, 0); + + /* Cancel PHY loopback mode */ + smsc911x_phy_write(pdata, MII_BMCR, 0); + spin_unlock_irqrestore(&pdata->phy_lock, flags); + + smsc911x_reg_write(0, pdata, TX_CFG); + smsc911x_reg_write(0, pdata, RX_CFG); + + return result; +} +#endif /* USE_PHY_WORK_AROUND */ + +/* assumes phy_lock is held */ +static void smsc911x_phy_update_flowcontrol(struct smsc911x_data *pdata) +{ + unsigned int temp; + + if (pdata->mii.full_duplex) { + unsigned int phy_adv; + unsigned int phy_lpa; + phy_adv = smsc911x_phy_read(pdata, MII_ADVERTISE); + phy_lpa = smsc911x_phy_read(pdata, MII_LPA); + if (phy_adv & phy_lpa & LPA_PAUSE_CAP) { + /* Both ends support symmetric pause, enable + * PAUSE receive and transmit */ + smsc911x_mac_write(pdata, FLOW, 0xFFFF0002); + temp = smsc911x_reg_read(pdata, AFC_CFG); + temp |= 0xF; + smsc911x_reg_write(temp, pdata, AFC_CFG); + } else if (((phy_adv & ADVERTISE_PAUSE_ALL) == + ADVERTISE_PAUSE_ALL) && + ((phy_lpa & LPA_PAUSE_ALL) == LPA_PAUSE_ASYM)) { + /* We support symmetric and asym pause, the + * other end only supports asym, Enable PAUSE + * receive, disable PAUSE transmit */ + smsc911x_mac_write(pdata, FLOW, 0xFFFF0002); + temp = smsc911x_reg_read(pdata, AFC_CFG); + temp &= ~0xF; + smsc911x_reg_write(temp, pdata, AFC_CFG); + } else { + /* Disable PAUSE receive and transmit */ + smsc911x_mac_write(pdata, FLOW, 0); + temp = smsc911x_reg_read(pdata, AFC_CFG); + temp &= ~0xF; + smsc911x_reg_write(temp, pdata, AFC_CFG); + } + } else { + smsc911x_mac_write(pdata, FLOW, 0); + temp = smsc911x_reg_read(pdata, AFC_CFG); + temp |= 0xF; + smsc911x_reg_write(temp, pdata, AFC_CFG); + } +} + +/* Update link mode if any thing has changed */ +static void smsc911x_phy_update_linkmode(struct net_device *dev, int init) +{ + struct smsc911x_data *pdata = netdev_priv(dev); + unsigned long flags; + + if (mii_check_media(&pdata->mii, netif_msg_link(pdata), init)) { + /* duplex state has changed */ + unsigned int mac_cr; + + spin_lock_irqsave(&pdata->phy_lock, flags); + mac_cr = smsc911x_mac_read(pdata, MAC_CR); + if (pdata->mii.full_duplex) { + SMSC_TRACE("configuring for full duplex mode"); + mac_cr |= MAC_CR_FDPX_; + } else { + SMSC_TRACE("configuring for half duplex mode"); + mac_cr &= ~MAC_CR_FDPX_; + } + smsc911x_mac_write(pdata, MAC_CR, mac_cr); + + smsc911x_phy_update_flowcontrol(pdata); + + spin_unlock_irqrestore(&pdata->phy_lock, flags); + } +#ifdef USE_LED1_WORK_AROUND + if (netif_carrier_ok(dev)) { + if ((pdata->gpio_orig_setting & GPIO_CFG_LED1_EN_) && + (!pdata->using_extphy)) { + /* Restore orginal GPIO configuration */ + pdata->gpio_setting = pdata->gpio_orig_setting; + smsc911x_reg_write(pdata->gpio_setting, pdata, + GPIO_CFG); + } + } else { + /* Check global setting that LED1 + * usage is 10/100 indicator */ + pdata->gpio_setting = smsc911x_reg_read(pdata, GPIO_CFG); + if ((pdata->gpio_setting & GPIO_CFG_LED1_EN_) + && (!pdata->using_extphy)) { + /* Force 10/100 LED off, after saving + * orginal GPIO configuration */ + pdata->gpio_orig_setting = pdata->gpio_setting; + + pdata->gpio_setting &= ~GPIO_CFG_LED1_EN_; + pdata->gpio_setting |= (GPIO_CFG_GPIOBUF0_ + | GPIO_CFG_GPIODIR0_ + | GPIO_CFG_GPIOD0_); + smsc911x_reg_write(pdata->gpio_setting, pdata, + GPIO_CFG); + } + } +#endif /* USE_LED1_WORK_AROUND */ +} + +/* Entry point for the link poller */ +static void smsc911x_phy_checklink(unsigned long ptr) +{ + struct net_device *dev = (struct net_device *)ptr; + struct smsc911x_data *pdata = netdev_priv(dev); + + smsc911x_phy_update_linkmode(dev, 0); + + if (!(pdata->stop_link_poll)) { + pdata->link_poll_timer.expires = jiffies + 2 * HZ; + add_timer(&pdata->link_poll_timer); + } else { + pdata->stop_link_poll = 0; + } +} + +/* Initialises the PHY layer. Called at initialisation by open() so + * interrupts are enabled */ +static int smsc911x_phy_initialise(struct net_device *dev) +{ + struct smsc911x_data *pdata = netdev_priv(dev); + unsigned int phyid1 = 0; + unsigned int phyid2 = 0; + unsigned int temp; + + pdata->using_extphy = 0; + + switch (pdata->idrev & 0xFFFF0000) { + case 0x01170000: + case 0x01150000: + /* External PHY supported, try to autodetect */ + if (smsc911x_phy_initialise_external(pdata) < 0) { + SMSC_TRACE("External PHY is not detected, using " + "internal PHY instead"); + pdata->mii.phy_id = 1; + } + break; + default: + SMSC_TRACE("External PHY is not supported, using internal PHY " + "instead"); + pdata->mii.phy_id = 1; + break; + } + + spin_lock_irq(&pdata->phy_lock); + phyid1 = smsc911x_phy_read(pdata, MII_PHYSID1); + phyid2 = smsc911x_phy_read(pdata, MII_PHYSID2); + spin_unlock_irq(&pdata->phy_lock); + + if ((phyid1 == 0xFFFF) && (phyid2 == 0xFFFF)) { + SMSC_WARNING("Internal PHY not detected!"); + return 0; + } + + /* Reset the phy */ + if (!smsc911x_phy_reset(pdata)) { + SMSC_WARNING("PHY reset failed to complete."); + return 0; + } +#ifdef USE_PHY_WORK_AROUND + if (!smsc911x_phy_loopbacktest(pdata)) { + SMSC_WARNING("Failed Loop Back Test"); + return 0; + } else { + SMSC_TRACE("Passed Loop Back Test"); + } +#endif /* USE_PHY_WORK_AROUND */ + + /* Advertise all speeds and pause capabilities */ + spin_lock_irq(&pdata->phy_lock); + temp = smsc911x_phy_read(pdata, MII_ADVERTISE); + temp |= (ADVERTISE_ALL | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); + smsc911x_phy_write(pdata, MII_ADVERTISE, temp); + pdata->mii.advertising = temp; + + if (!pdata->using_extphy) { + /* using internal phy, enable PHY interrupts */ + smsc911x_phy_read(pdata, MII_INTSTS); + smsc911x_phy_write(pdata, MII_INTMSK, PHY_INTMSK_DEFAULT_); + } + + /* begin to establish link */ + smsc911x_phy_write(pdata, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART); + spin_unlock_irq(&pdata->phy_lock); + + smsc911x_phy_update_linkmode(dev, 1); + + setup_timer(&pdata->link_poll_timer, smsc911x_phy_checklink, + (unsigned long)dev); + pdata->link_poll_timer.expires = jiffies + 2 * HZ; + add_timer(&pdata->link_poll_timer); + + SMSC_TRACE("phy initialised succesfully"); + return 1; +} + +/* Gets the number of tx statuses in the fifo */ +static unsigned int smsc911x_tx_get_txstatcount(struct smsc911x_data *pdata) +{ + unsigned int result = (smsc911x_reg_read(pdata, TX_FIFO_INF) + & TX_FIFO_INF_TSUSED_) >> 16; + return result; +} + +/* Reads tx statuses and increments counters where necessary */ +static void smsc911x_tx_update_txcounters(struct smsc911x_data *pdata) +{ + unsigned int tx_stat; + + while ((tx_stat = smsc911x_tx_get_txstatus(pdata)) != 0) { + if (unlikely(tx_stat & 0x80000000)) { + /* In this driver the packet tag is used as the packet + * length. Since a packet length can never reach the + * size of 0x8000, this bit is reserved. It is worth + * noting that the "reserved bit" in the warning above + * does not reference a hardware defined reserved bit + * but rather a driver defined one. + */ + SMSC_WARNING("Packet tag reserved bit is high"); + } else { + if (unlikely(tx_stat & 0x00008000)) { + pdata->stats.tx_errors++; + } else { + pdata->stats.tx_packets++; + pdata->stats.tx_bytes += (tx_stat >> 16); + } + if (unlikely(tx_stat & 0x00000100)) { + pdata->stats.collisions += 16; + pdata->stats.tx_aborted_errors += 1; + } else { + pdata->stats.collisions += + ((tx_stat >> 3) & 0xF); + } + if (unlikely(tx_stat & 0x00000800)) { + pdata->stats.tx_carrier_errors += 1; + } + if (unlikely(tx_stat & 0x00000200)) { + pdata->stats.collisions++; + pdata->stats.tx_aborted_errors++; + } + } + } +} + +/* Increments the Rx error counters */ +static void +smsc911x_rx_counterrors(struct smsc911x_data *pdata, unsigned int rxstat) +{ + int crc_err = 0; + + if (unlikely(rxstat & 0x00008000)) { + pdata->stats.rx_errors++; + if (unlikely(rxstat & 0x00000002)) { + pdata->stats.rx_crc_errors++; + crc_err = 1; + } + } + if (likely(!crc_err)) { + if (unlikely((rxstat & 0x00001020) == 0x00001020)) { + /* Frame type indicates length, + * and length error is set */ + pdata->stats.rx_length_errors++; + } + if (rxstat & RX_STS_MCAST_) + pdata->stats.multicast++; + } +} + +/* Quickly dumps bad packets */ +static void +smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktbytes) +{ + unsigned int pktwords = (pktbytes + NET_IP_ALIGN + 3) >> 2; + + if (likely(pktwords >= 4)) { + unsigned int timeout = 500; + unsigned int val; + smsc911x_reg_write(RX_DP_CTRL_RX_FFWD_, pdata, RX_DP_CTRL); + do { + udelay(1); + val = smsc911x_reg_read(pdata, RX_DP_CTRL); + } while (timeout-- && (val & RX_DP_CTRL_RX_FFWD_)); + + if (unlikely(timeout == 0)) + SMSC_WARNING("Timed out waiting for RX FFWD " + "to finish, RX_DP_CTRL: 0x%08X", val); + } else { + unsigned int temp; + while (pktwords--) + temp = smsc911x_reg_read(pdata, RX_DATA_FIFO); + } +} + +/* NAPI poll function */ +static int smsc911x_poll(struct napi_struct *napi, int budget) +{ + struct smsc911x_data *pdata = container_of(napi, struct smsc911x_data, napi); + struct net_device *dev = pdata->netdev; + int npackets = 0; + + while (npackets < budget) { + unsigned int pktlength; + unsigned int pktwords; + unsigned int rxstat = smsc911x_rx_get_rxstatus(pdata); + + /* break out of while loop if there are no more packets waiting */ + if (!rxstat) + break; + + pktlength = ((rxstat & 0x3FFF0000) >> 16); + pktwords = (pktlength + NET_IP_ALIGN + 3) >> 2; + smsc911x_rx_counterrors(pdata, rxstat); + + if (likely((rxstat & RX_STS_ES_) == 0)) { + struct sk_buff *skb; + skb = dev_alloc_skb(pktlength + NET_IP_ALIGN); + if (likely(skb)) { + skb->data = skb->head; + skb->tail = skb->head; + /* Align IP on 16B boundary */ + skb_reserve(skb, NET_IP_ALIGN); + skb_put(skb, pktlength - 4); + smsc911x_rx_readfifo(pdata, + (unsigned int *)skb->head, + pktwords); + skb->dev = dev; + skb->protocol = eth_type_trans(skb, dev); + skb->ip_summed = CHECKSUM_NONE; + netif_receive_skb(skb); + + /* Update counters */ + pdata->stats.rx_packets++; + pdata->stats.rx_bytes += (pktlength - 4); + dev->last_rx = jiffies; + npackets++; + continue; + } else { + SMSC_WARNING("Unable to allocate sk_buff " + "for rx packet, in PIO path"); + pdata->stats.rx_dropped++; + } + } + /* At this point, the packet is to be read out + * of the fifo and discarded */ + smsc911x_rx_fastforward(pdata, pktlength); + } + + pdata->stats.rx_dropped += smsc911x_reg_read(pdata, RX_DROP); + smsc911x_reg_write(INT_STS_RSFL_, pdata, INT_STS); + + if (npackets < budget) { + unsigned int temp; + /* We processed all packets available. Tell NAPI it can + * stop polling then re-enable rx interrupts */ + netif_rx_complete(dev, napi); + temp = smsc911x_reg_read(pdata, INT_EN); + temp |= INT_EN_RSFL_EN_; + smsc911x_reg_write(temp, pdata, INT_EN); + } + + /* There are still packets waiting */ + return npackets; +} + +/* Returns hash bit number for given MAC address + * Example: + * 01 00 5E 00 00 01 -> returns bit number 31 */ +static unsigned int smsc911x_hash(char addr[ETH_ALEN]) +{ + unsigned int crc; + unsigned int result; + + crc = ether_crc(ETH_ALEN, addr); + result = (crc >> 26) & 0x3f; + + return result; +} + +static void smsc911x_rx_multicast_update(struct smsc911x_data *pdata) +{ + /* Performs the multicast & mac_cr update. This is called when + * safe on the current hardware, and with the phy_lock held */ + unsigned int mac_cr = smsc911x_mac_read(pdata, MAC_CR); + mac_cr |= pdata->set_bits_mask; + mac_cr &= ~(pdata->clear_bits_mask); + smsc911x_mac_write(pdata, MAC_CR, mac_cr); + smsc911x_mac_write(pdata, HASHH, pdata->hashhi); + smsc911x_mac_write(pdata, HASHL, pdata->hashlo); + SMSC_TRACE("maccr 0x%08X, HASHH 0x%08X, HASHL 0x%08X", mac_cr, + pdata->hashhi, pdata->hashlo); +} + +static void smsc911x_rx_multicast_update_workaround(struct smsc911x_data *pdata) +{ + unsigned int mac_cr; + + /* This function is only called for older LAN911x devices + * (revA or revB), where MAC_CR, HASHH and HASHL should not + * be modified during Rx - newer devices immediately update the + * registers. + * + * This is called from interrupt context */ + + spin_lock(&pdata->phy_lock); + + /* Check Rx has stopped */ + if (smsc911x_mac_read(pdata, MAC_CR) & MAC_CR_RXEN_) + SMSC_WARNING("Rx not stopped\n"); + + /* Perform the update - safe to do now Rx has stopped */ + smsc911x_rx_multicast_update(pdata); + + /* Re-enable Rx */ + mac_cr = smsc911x_mac_read(pdata, MAC_CR); + mac_cr |= MAC_CR_RXEN_; + smsc911x_mac_write(pdata, MAC_CR, mac_cr); + + pdata->multicast_update_pending = 0; + + spin_unlock(&pdata->phy_lock); +} + +/* Sets the device MAC address to dev_addr, called with phy_lock held */ +static void +smsc911x_set_mac_address(struct smsc911x_data *pdata, u8 dev_addr[6]) +{ + u32 mac_high16 = (dev_addr[5] << 8) | dev_addr[4]; + u32 mac_low32 = (dev_addr[3] << 24) | (dev_addr[2] << 16) | + (dev_addr[1] << 8) | dev_addr[0]; + + smsc911x_mac_write(pdata, ADDRH, mac_high16); + smsc911x_mac_write(pdata, ADDRL, mac_low32); +} + +static int smsc911x_open(struct net_device *dev) +{ + struct smsc911x_data *pdata = netdev_priv(dev); + unsigned int timeout; + unsigned int temp; + unsigned int intcfg; + + spin_lock_init(&pdata->phy_lock); + + /* Reset the LAN911x */ + smsc911x_reg_write(HW_CFG_SRST_, pdata, HW_CFG); + timeout = 10; + do { + udelay(10); + temp = smsc911x_reg_read(pdata, HW_CFG); + } while ((--timeout) && (temp & HW_CFG_SRST_)); + + if (unlikely(temp & HW_CFG_SRST_)) { + SMSC_WARNING("Failed to complete reset"); + return -ENODEV; + } + + smsc911x_reg_write(0x00050000, pdata, HW_CFG); + smsc911x_reg_write(0x006E3740, pdata, AFC_CFG); + + /* Make sure EEPROM has finished loading before setting GPIO_CFG */ + timeout = 50; + while ((timeout--) && + (smsc911x_reg_read(pdata, E2P_CMD) & E2P_CMD_EPC_BUSY_)) { + udelay(10); + } + + if (unlikely(timeout == 0)) { + SMSC_WARNING("Timed out waiting for EEPROM " + "busy bit to clear"); + } +#if USE_DEBUG >= 1 + smsc911x_reg_write(0x00670700, pdata, GPIO_CFG); +#else + smsc911x_reg_write(0x70070000, pdata, GPIO_CFG); +#endif + + /* Initialise irqs, but leave all sources disabled */ + smsc911x_reg_write(0, pdata, INT_EN); + smsc911x_reg_write(0xFFFFFFFF, pdata, INT_STS); + + /* Set interrupt deassertion to 100uS */ + intcfg = ((10 << 24) | INT_CFG_IRQ_EN_); + + if (pdata->irq_polarity) { + SMSC_TRACE("irq polarity: active high"); + intcfg |= INT_CFG_IRQ_POL_; + } else { + SMSC_TRACE("irq polarity: active low"); + } + + if (pdata->irq_type) { + SMSC_TRACE("irq type: push-pull"); + intcfg |= INT_CFG_IRQ_TYPE_; + } else { + SMSC_TRACE("irq type: open drain"); + } + + smsc911x_reg_write(intcfg, pdata, INT_CFG); + + SMSC_TRACE("Testing irq handler using IRQ %d", dev->irq); + pdata->software_irq_signal = 0; + smp_wmb(); + + temp = smsc911x_reg_read(pdata, INT_EN); + temp |= INT_EN_SW_INT_EN_; + smsc911x_reg_write(temp, pdata, INT_EN); + + timeout = 1000; + while (timeout--) { + smp_rmb(); + if (pdata->software_irq_signal) + break; + msleep(1); + } + + if (!pdata->software_irq_signal) { + printk(KERN_WARNING "%s: ISR failed signaling test (IRQ %d)\n", + dev->name, dev->irq); + return -ENODEV; + } + SMSC_TRACE("IRQ handler passed test using IRQ %d", dev->irq); + + printk(KERN_INFO "%s: SMSC911x/921x identified at %#08lx, IRQ: %d\n", + dev->name, (unsigned long)pdata->ioaddr, dev->irq); + + netif_carrier_off(dev); + + if (!smsc911x_phy_initialise(dev)) { + SMSC_WARNING("Failed to initialize PHY"); + return -ENODEV; + } + + smsc911x_set_mac_address(pdata, dev->dev_addr); + + temp = smsc911x_reg_read(pdata, HW_CFG); + temp &= HW_CFG_TX_FIF_SZ_; + temp |= HW_CFG_SF_; + smsc911x_reg_write(temp, pdata, HW_CFG); + + temp = smsc911x_reg_read(pdata, FIFO_INT); + temp |= FIFO_INT_TX_AVAIL_LEVEL_; + temp &= ~(FIFO_INT_RX_STS_LEVEL_); + smsc911x_reg_write(temp, pdata, FIFO_INT); + + /* set RX Data offset to 2 bytes for alignment */ + smsc911x_reg_write((2 << 8), pdata, RX_CFG); + + napi_enable(&pdata->napi); + + temp = smsc911x_reg_read(pdata, INT_EN); + temp |= (INT_EN_TDFA_EN_ | INT_EN_RSFL_EN_ | INT_EN_PHY_INT_EN_); + smsc911x_reg_write(temp, pdata, INT_EN); + + spin_lock_irq(&pdata->phy_lock); + temp = smsc911x_mac_read(pdata, MAC_CR); + temp |= (MAC_CR_TXEN_ | MAC_CR_RXEN_ | MAC_CR_HBDIS_); + smsc911x_mac_write(pdata, MAC_CR, temp); + spin_unlock_irq(&pdata->phy_lock); + + smsc911x_reg_write(TX_CFG_TX_ON_, pdata, TX_CFG); + + netif_start_queue(dev); + return 0; +} + +/* Entry point for stopping the interface */ +static int smsc911x_stop(struct net_device *dev) +{ + struct smsc911x_data *pdata = netdev_priv(dev); + + napi_disable(&pdata->napi); + + pdata->stop_link_poll = 1; + del_timer_sync(&pdata->link_poll_timer); + + smsc911x_reg_write((smsc911x_reg_read(pdata, INT_CFG) & + (~INT_CFG_IRQ_EN_)), pdata, INT_CFG); + netif_stop_queue(dev); + + /* At this point all Rx and Tx activity is stopped */ + pdata->stats.rx_dropped += smsc911x_reg_read(pdata, RX_DROP); + smsc911x_tx_update_txcounters(pdata); + + SMSC_TRACE("Interface stopped"); + return 0; +} + +/* Entry point for transmitting a packet */ +static int smsc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct smsc911x_data *pdata = netdev_priv(dev); + unsigned int freespace; + unsigned int tx_cmd_a; + unsigned int tx_cmd_b; + unsigned int temp; + u32 wrsz; + u32 bufp; + + freespace = smsc911x_reg_read(pdata, TX_FIFO_INF) & TX_FIFO_INF_TDFREE_; + + if (unlikely(freespace < TX_FIFO_LOW_THRESHOLD)) + SMSC_WARNING("Tx data fifo low, space available: %d", + freespace); + + /* Word alignment adjustment */ + tx_cmd_a = ((((unsigned int)(skb->data)) & 0x03) << 16); + tx_cmd_a |= TX_CMD_A_FIRST_SEG_ | TX_CMD_A_LAST_SEG_; + tx_cmd_a |= (unsigned int)skb->len; + + tx_cmd_b = ((unsigned int)skb->len) << 16; + tx_cmd_b |= (unsigned int)skb->len; + + smsc911x_reg_write(tx_cmd_a, pdata, TX_DATA_FIFO); + smsc911x_reg_write(tx_cmd_b, pdata, TX_DATA_FIFO); + + bufp = ((u32)skb->data) & 0xFFFFFFFC; + wrsz = (u32)skb->len + 3; + wrsz += ((u32)skb->data) & 0x3; + wrsz >>= 2; + + smsc911x_tx_writefifo(pdata, (unsigned int *)bufp, wrsz); + freespace -= (skb->len + 32); + dev_kfree_skb(skb); + dev->trans_start = jiffies; + + if (unlikely(smsc911x_tx_get_txstatcount(pdata) >= 30)) + smsc911x_tx_update_txcounters(pdata); + + if (freespace < TX_FIFO_LOW_THRESHOLD) { + netif_stop_queue(dev); + temp = smsc911x_reg_read(pdata, FIFO_INT); + temp &= 0x00FFFFFF; + temp |= 0x32000000; + smsc911x_reg_write(temp, pdata, FIFO_INT); + } + + return NETDEV_TX_OK; +} + +/* Entry point for getting status counters */ +static struct net_device_stats *smsc911x_get_stats(struct net_device *dev) +{ + struct smsc911x_data *pdata = netdev_priv(dev); + smsc911x_tx_update_txcounters(pdata); + pdata->stats.rx_dropped += smsc911x_reg_read(pdata, RX_DROP); + return &pdata->stats; +} + +/* Entry point for setting addressing modes */ +static void smsc911x_set_multicast_list(struct net_device *dev) +{ + struct smsc911x_data *pdata = netdev_priv(dev); + unsigned long flags; + + if (dev->flags & IFF_PROMISC) { + /* Enabling promiscuous mode */ + pdata->set_bits_mask = MAC_CR_PRMS_; + pdata->clear_bits_mask = (MAC_CR_MCPAS_ | MAC_CR_HPFILT_); + pdata->hashhi = 0; + pdata->hashlo = 0; + } else if (dev->flags & IFF_ALLMULTI) { + /* Enabling all multicast mode */ + pdata->set_bits_mask = MAC_CR_MCPAS_; + pdata->clear_bits_mask = (MAC_CR_PRMS_ | MAC_CR_HPFILT_); + pdata->hashhi = 0; + pdata->hashlo = 0; + } else if (dev->mc_count > 0) { + /* Enabling specific multicast addresses */ + unsigned int hash_high = 0; + unsigned int hash_low = 0; + unsigned int count = 0; + struct dev_mc_list *mc_list = dev->mc_list; + + pdata->set_bits_mask = MAC_CR_HPFILT_; + pdata->clear_bits_mask = (MAC_CR_PRMS_ | MAC_CR_MCPAS_); + + while (mc_list) { + count++; + if ((mc_list->dmi_addrlen) == ETH_ALEN) { + unsigned int bitnum = + smsc911x_hash(mc_list->dmi_addr); + unsigned int mask = 0x01 << (bitnum & 0x1F); + if (bitnum & 0x20) + hash_high |= mask; + else + hash_low |= mask; + } else { + SMSC_WARNING("dmi_addrlen != 6"); + } + mc_list = mc_list->next; + } + if (count != (unsigned int)dev->mc_count) + SMSC_WARNING("mc_count != dev->mc_count"); + + pdata->hashhi = hash_high; + pdata->hashlo = hash_low; + } else { + /* Enabling local MAC address only */ + pdata->set_bits_mask = 0; + pdata->clear_bits_mask = + (MAC_CR_PRMS_ | MAC_CR_MCPAS_ | MAC_CR_HPFILT_); + pdata->hashhi = 0; + pdata->hashlo = 0; + } + + spin_lock_irqsave(&pdata->phy_lock, flags); + + if (pdata->generation <= 1) { + /* Older hardware revision - cannot change these flags while + * receiving data */ + if (!pdata->multicast_update_pending) { + unsigned int temp; + SMSC_TRACE("scheduling mcast update"); + pdata->multicast_update_pending = 1; + + /* Request the hardware to stop, then perform the + * update when we get an RX_STOP interrupt */ + smsc911x_reg_write(INT_STS_RXSTOP_INT_, pdata, INT_STS); + temp = smsc911x_reg_read(pdata, INT_EN); + temp |= INT_EN_RXSTOP_INT_EN_; + smsc911x_reg_write(temp, pdata, INT_EN); + + temp = smsc911x_mac_read(pdata, MAC_CR); + temp &= ~(MAC_CR_RXEN_); + smsc911x_mac_write(pdata, MAC_CR, temp); + } else { + /* There is another update pending, this should now + * use the newer values */ + } + } else { + /* Newer hardware revision - can write immediately */ + smsc911x_rx_multicast_update(pdata); + } + + spin_unlock_irqrestore(&pdata->phy_lock, flags); +} + +static irqreturn_t smsc911x_irqhandler(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; + struct smsc911x_data *pdata = netdev_priv(dev); + unsigned int intsts; + unsigned int inten; + unsigned int temp; + int serviced = IRQ_NONE; + + intsts = smsc911x_reg_read(pdata, INT_STS); + inten = smsc911x_reg_read(pdata, INT_EN); + + if (unlikely(intsts & inten & INT_STS_SW_INT_)) { + temp = smsc911x_reg_read(pdata, INT_EN); + temp &= (~INT_EN_SW_INT_EN_); + smsc911x_reg_write(temp, pdata, INT_EN); + smsc911x_reg_write(INT_STS_SW_INT_, pdata, INT_STS); + pdata->software_irq_signal = 1; + smp_wmb(); + serviced = IRQ_HANDLED; + } + + if (unlikely(intsts & inten & INT_STS_RXSTOP_INT_)) { + /* Called when there is a multicast update scheduled and + * it is now safe to complete the update */ + SMSC_TRACE("RX Stop interrupt"); + temp = smsc911x_reg_read(pdata, INT_EN); + temp &= (~INT_EN_RXSTOP_INT_EN_); + smsc911x_reg_write(temp, pdata, INT_EN); + smsc911x_reg_write(INT_STS_RXSTOP_INT_, pdata, INT_STS); + smsc911x_rx_multicast_update_workaround(pdata); + serviced = IRQ_HANDLED; + } + + if (intsts & inten & INT_STS_TDFA_) { + temp = smsc911x_reg_read(pdata, FIFO_INT); + temp |= FIFO_INT_TX_AVAIL_LEVEL_; + smsc911x_reg_write(temp, pdata, FIFO_INT); + smsc911x_reg_write(INT_STS_TDFA_, pdata, INT_STS); + netif_wake_queue(dev); + serviced = IRQ_HANDLED; + } + + if (unlikely(intsts & inten & INT_STS_RXE_)) { + smsc911x_reg_write(INT_STS_RXE_, pdata, INT_STS); + serviced = IRQ_HANDLED; + } + + if (likely(intsts & inten & INT_STS_RSFL_)) { + /* Disable Rx interrupts and schedule NAPI poll */ + temp = smsc911x_reg_read(pdata, INT_EN); + temp &= (~INT_EN_RSFL_EN_); + smsc911x_reg_write(temp, pdata, INT_EN); + netif_rx_schedule(dev, &pdata->napi); + serviced = IRQ_HANDLED; + } + + if (unlikely(intsts & inten & INT_STS_PHY_INT_)) { + smsc911x_reg_write(INT_STS_PHY_INT_, pdata, INT_STS); + spin_lock(&pdata->phy_lock); + temp = smsc911x_phy_read(pdata, MII_INTSTS); + spin_unlock(&pdata->phy_lock); + SMSC_TRACE("PHY interrupt, sts 0x%04X", (u16)temp); + smsc911x_phy_update_linkmode(dev, 0); + serviced = IRQ_HANDLED; + } + return serviced; +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +void smsc911x_poll_controller(struct net_device *dev) +{ + disable_irq(dev->irq); + smsc911x_irqhandler(0, dev); + enable_irq(dev->irq); +} +#endif /* CONFIG_NET_POLL_CONTROLLER */ + +/* Standard ioctls for mii-tool */ +static int smsc911x_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct smsc911x_data *pdata = netdev_priv(dev); + struct mii_ioctl_data *data = if_mii(ifr); + unsigned long flags; + + SMSC_TRACE("ioctl cmd 0x%x", cmd); + switch (cmd) { + case SIOCGMIIPHY: + data->phy_id = pdata->mii.phy_id; + return 0; + case SIOCGMIIREG: + spin_lock_irqsave(&pdata->phy_lock, flags); + data->val_out = smsc911x_phy_read(pdata, data->reg_num); + spin_unlock_irqrestore(&pdata->phy_lock, flags); + return 0; + case SIOCSMIIREG: + spin_lock_irqsave(&pdata->phy_lock, flags); + smsc911x_phy_write(pdata, data->reg_num, data->val_in); + spin_unlock_irqrestore(&pdata->phy_lock, flags); + return 0; + } + + SMSC_TRACE("unsupported ioctl cmd"); + return -1; +} + +static int +smsc911x_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct smsc911x_data *pdata = netdev_priv(dev); + + cmd->maxtxpkt = 1; + cmd->maxrxpkt = 1; + return mii_ethtool_gset(&pdata->mii, cmd); +} + +static int +smsc911x_ethtool_setsettings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct smsc911x_data *pdata = netdev_priv(dev); + + return mii_ethtool_sset(&pdata->mii, cmd); +} + +static void smsc911x_ethtool_getdrvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + strncpy(info->driver, SMSC_CHIPNAME, sizeof(info->driver)); + strncpy(info->version, SMSC_DRV_VERSION, sizeof(info->version)); + strncpy(info->bus_info, dev->dev.bus_id, sizeof(info->bus_info)); +} + +static int smsc911x_ethtool_nwayreset(struct net_device *dev) +{ + struct smsc911x_data *pdata = netdev_priv(dev); + + return mii_nway_restart(&pdata->mii); +} + +static u32 smsc911x_ethtool_getmsglevel(struct net_device *dev) +{ + struct smsc911x_data *pdata = netdev_priv(dev); + return pdata->msg_enable; +} + +static void smsc911x_ethtool_setmsglevel(struct net_device *dev, u32 level) +{ + struct smsc911x_data *pdata = netdev_priv(dev); + pdata->msg_enable = level; +} + +static int smsc911x_ethtool_getregslen(struct net_device *dev) +{ + return (((E2P_CMD - ID_REV) / 4 + 1) + (WUCSR - MAC_CR) + 1 + 32) * + sizeof(u32); +} + +static void +smsc911x_ethtool_getregs(struct net_device *dev, struct ethtool_regs *regs, + void *buf) +{ + struct smsc911x_data *pdata = netdev_priv(dev); + unsigned long flags; + unsigned int i; + unsigned int j = 0; + u32 *data = buf; + + regs->version = pdata->idrev; + for (i = ID_REV; i <= E2P_CMD; i += (sizeof(u32))) + data[j++] = smsc911x_reg_read(pdata, i); + + spin_lock_irqsave(&pdata->phy_lock, flags); + for (i = MAC_CR; i <= WUCSR; i++) + data[j++] = smsc911x_mac_read(pdata, i); + for (i = 0; i <= 31; i++) + data[j++] = smsc911x_phy_read(pdata, i); + spin_unlock_irqrestore(&pdata->phy_lock, flags); +} + +static void smsc911x_eeprom_enable_access(struct smsc911x_data *pdata) +{ + unsigned int temp = smsc911x_reg_read(pdata, GPIO_CFG); + temp &= ~GPIO_CFG_EEPR_EN_; + smsc911x_reg_write(temp, pdata, GPIO_CFG); + msleep(1); +} + +static int smsc911x_eeprom_send_cmd(struct smsc911x_data *pdata, u32 op) +{ + int timeout = 100; + u32 e2cmd; + + SMSC_TRACE("op 0x%08x", op); + if (smsc911x_reg_read(pdata, E2P_CMD) & E2P_CMD_EPC_BUSY_) { + SMSC_WARNING("Busy at start"); + return -EBUSY; + } + + e2cmd = op | E2P_CMD_EPC_BUSY_; + smsc911x_reg_write(e2cmd, pdata, E2P_CMD); + + do { + msleep(1); + e2cmd = smsc911x_reg_read(pdata, E2P_CMD); + } while ((e2cmd & E2P_CMD_EPC_BUSY_) && (timeout--)); + + if (!timeout) { + SMSC_TRACE("TIMED OUT"); + return -EAGAIN; + } + + if (e2cmd & E2P_CMD_EPC_TIMEOUT_) { + SMSC_TRACE("Error occured during eeprom operation"); + return -EINVAL; + } + + return 0; +} + +static int smsc911x_eeprom_read_location(struct smsc911x_data *pdata, + u8 address, u8 *data) +{ + u32 op = E2P_CMD_EPC_CMD_READ_ | address; + int ret; + + SMSC_TRACE("address 0x%x", address); + ret = smsc911x_eeprom_send_cmd(pdata, op); + + if (!ret) + data[address] = smsc911x_reg_read(pdata, E2P_DATA); + + return ret; +} + +static int smsc911x_eeprom_write_location(struct smsc911x_data *pdata, + u8 address, u8 data) +{ + u32 op = E2P_CMD_EPC_CMD_ERASE_ | address; + int ret; + + SMSC_TRACE("address 0x%x, data 0x%x", address, data); + ret = smsc911x_eeprom_send_cmd(pdata, op); + + if (!ret) { + op = E2P_CMD_EPC_CMD_WRITE_ | address; + smsc911x_reg_write((u32)data, pdata, E2P_DATA); + ret = smsc911x_eeprom_send_cmd(pdata, op); + } + + return ret; +} + +static int smsc911x_ethtool_get_eeprom_len(struct net_device *dev) +{ + return SMSC911X_EEPROM_SIZE; +} + +static int smsc911x_ethtool_get_eeprom(struct net_device *dev, + struct ethtool_eeprom *eeprom, u8 *data) +{ + struct smsc911x_data *pdata = netdev_priv(dev); + u8 eeprom_data[SMSC911X_EEPROM_SIZE]; + int len; + int i; + + smsc911x_eeprom_enable_access(pdata); + + len = min(eeprom->len, SMSC911X_EEPROM_SIZE); + for (i = 0; i < len; i++) { + int ret = smsc911x_eeprom_read_location(pdata, i, eeprom_data); + if (ret < 0) { + eeprom->len = 0; + return ret; + } + } + + memcpy(data, &eeprom_data[eeprom->offset], len); + eeprom->len = len; + return 0; +} + +static int smsc911x_ethtool_set_eeprom(struct net_device *dev, + struct ethtool_eeprom *eeprom, u8 *data) +{ + int ret; + struct smsc911x_data *pdata = netdev_priv(dev); + + smsc911x_eeprom_enable_access(pdata); + smsc911x_eeprom_send_cmd(pdata, E2P_CMD_EPC_CMD_EWEN_); + ret = smsc911x_eeprom_write_location(pdata, eeprom->offset, *data); + smsc911x_eeprom_send_cmd(pdata, E2P_CMD_EPC_CMD_EWDS_); + + /* Single byte write, according to man page */ + eeprom->len = 1; + + return ret; +} + +static struct ethtool_ops smsc911x_ethtool_ops = { + .get_settings = smsc911x_ethtool_getsettings, + .set_settings = smsc911x_ethtool_setsettings, + .get_link = ethtool_op_get_link, + .get_drvinfo = smsc911x_ethtool_getdrvinfo, + .nway_reset = smsc911x_ethtool_nwayreset, + .get_msglevel = smsc911x_ethtool_getmsglevel, + .set_msglevel = smsc911x_ethtool_setmsglevel, + .get_regs_len = smsc911x_ethtool_getregslen, + .get_regs = smsc911x_ethtool_getregs, + .get_eeprom_len = smsc911x_ethtool_get_eeprom_len, + .get_eeprom = smsc911x_ethtool_get_eeprom, + .set_eeprom = smsc911x_ethtool_set_eeprom, +}; + +/* Initializing private device structures */ +static int smsc911x_init(struct net_device *dev) +{ + u32 mac_high16; + u32 mac_low32; + struct smsc911x_data *pdata = netdev_priv(dev); + + SMSC_TRACE("Driver Parameters:"); + SMSC_TRACE("LAN base: 0x%08lX", (unsigned long)pdata->ioaddr); + SMSC_TRACE("IRQ: %d", dev->irq); + SMSC_TRACE("PHY will be autodetected."); + + if (pdata->ioaddr == 0) { + SMSC_WARNING("pdata->ioaddr: 0x00000000"); + return -ENODEV; + } + + /* Default generation to zero (all workarounds apply) */ + pdata->generation = 0; + + pdata->idrev = smsc911x_reg_read(pdata, ID_REV); + if (((pdata->idrev >> 16) & 0xFFFF) == (pdata->idrev & 0xFFFF)) { + SMSC_WARNING("idrev top 16 bits equal to bottom 16 bits, " + "idrev: 0x%08X", pdata->idrev); + SMSC_TRACE("This may mean the chip is set for 32 bit while " + "the bus is reading as 16 bit"); + return -ENODEV; + } + switch (pdata->idrev & 0xFFFF0000) { + case 0x01180000: + switch (pdata->idrev & 0x0000FFFFUL) { + case 0UL: + SMSC_TRACE("LAN9118 Beacon identified, idrev: 0x%08X", + pdata->idrev); + pdata->generation = 0; + break; + case 1UL: + SMSC_TRACE + ("LAN9118 Concord A0 identified, idrev: 0x%08X", + pdata->idrev); + pdata->generation = 1; + break; + case 2UL: + SMSC_TRACE + ("LAN9118 Concord A1 identified, idrev: 0x%08X", + pdata->idrev); + pdata->generation = 2; + break; + default: + SMSC_TRACE + ("LAN9118 Concord A1 identified (NEW), idrev: 0x%08X", + pdata->idrev); + pdata->generation = 2; + break; + } + break; + + case 0x01170000: + switch (pdata->idrev & 0x0000FFFFUL) { + case 0UL: + SMSC_TRACE("LAN9117 Beacon identified, idrev: 0x%08X", + pdata->idrev); + pdata->generation = 0; + break; + case 1UL: + SMSC_TRACE + ("LAN9117 Concord A0 identified, idrev: 0x%08X", + pdata->idrev); + pdata->generation = 1; + break; + case 2UL: + SMSC_TRACE + ("LAN9117 Concord A1 identified, idrev: 0x%08X", + pdata->idrev); + pdata->generation = 2; + break; + default: + SMSC_TRACE + ("LAN9117 Concord A1 identified (NEW), idrev: 0x%08X", + pdata->idrev); + pdata->generation = 2; + break; + } + break; + + case 0x01160000: + switch (pdata->idrev & 0x0000FFFFUL) { + case 0UL: + SMSC_WARNING("LAN911x not identified, idrev: 0x%08X", + pdata->idrev); + return -ENODEV; + case 1UL: + SMSC_TRACE + ("LAN9116 Concord A0 identified, idrev: 0x%08X", + pdata->idrev); + pdata->generation = 1; + break; + case 2UL: + SMSC_TRACE + ("LAN9116 Concord A1 identified, idrev: 0x%08X", + pdata->idrev); + pdata->generation = 2; + break; + default: + SMSC_TRACE + ("LAN9116 Concord A1 identified (NEW), idrev: 0x%08X", + pdata->idrev); + pdata->generation = 2; + break; + } + break; + + case 0x01150000: + switch (pdata->idrev & 0x0000FFFFUL) { + case 0UL: + SMSC_WARNING("LAN911x not identified, idrev: 0x%08X", + pdata->idrev); + return -ENODEV; + case 1UL: + SMSC_TRACE + ("LAN9115 Concord A0 identified, idrev: 0x%08X", + pdata->idrev); + pdata->generation = 1; + break; + case 2UL: + SMSC_TRACE + ("LAN9115 Concord A1 identified, idrev: 0x%08X", + pdata->idrev); + pdata->generation = 2; + break; + default: + SMSC_TRACE + ("LAN9115 Concord A1 identified (NEW), idrev: 0x%08X", + pdata->idrev); + pdata->generation = 2; + break; + } + break; + + case 0x118A0000UL: + switch (pdata->idrev & 0x0000FFFFUL) { + case 0UL: + SMSC_TRACE + ("LAN9218 Boylston identified, idrev: 0x%08X", + pdata->idrev); + pdata->generation = 3; + break; + default: + SMSC_TRACE + ("LAN9218 Boylston identified (NEW), idrev: 0x%08X", + pdata->idrev); + pdata->generation = 3; + break; + } + break; + + case 0x117A0000UL: + switch (pdata->idrev & 0x0000FFFFUL) { + case 0UL: + SMSC_TRACE + ("LAN9217 Boylston identified, idrev: 0x%08X", + pdata->idrev); + pdata->generation = 3; + break; + default: + SMSC_TRACE + ("LAN9217 Boylston identified (NEW), idrev: 0x%08X", + pdata->idrev); + pdata->generation = 3; + break; + } + break; + + case 0x116A0000UL: + switch (pdata->idrev & 0x0000FFFFUL) { + case 0UL: + SMSC_TRACE + ("LAN9216 Boylston identified, idrev: 0x%08X", + pdata->idrev); + pdata->generation = 3; + break; + default: + SMSC_TRACE + ("LAN9216 Boylston identified (NEW), idrev: 0x%08X", + pdata->idrev); + pdata->generation = 3; + break; + } + break; + + case 0x115A0000UL: + switch (pdata->idrev & 0x0000FFFFUL) { + case 0UL: + SMSC_TRACE + ("LAN9215 Boylston identified, idrev: 0x%08X", + pdata->idrev); + pdata->generation = 3; + break; + default: + SMSC_TRACE + ("LAN9215 Boylston identified (NEW), idrev: 0x%08X", + pdata->idrev); + pdata->generation = 3; + break; + } + break; + + case 0x92100000UL: + case 0x92110000UL: + case 0x92200000UL: + case 0x92210000UL: + /* LAN9210/LAN9211/LAN9220/LAN9221 */ + pdata->generation = 4; + break; + + default: + SMSC_WARNING("LAN911x not identified, idrev: 0x%08X", + pdata->idrev); + return -ENODEV; + } + + if (pdata->generation == 0) + SMSC_WARNING("This driver is not intended " + "for this chip revision"); + + ether_setup(dev); + dev->open = smsc911x_open; + dev->stop = smsc911x_stop; + dev->hard_start_xmit = smsc911x_hard_start_xmit; + dev->get_stats = smsc911x_get_stats; + dev->set_multicast_list = smsc911x_set_multicast_list; + dev->flags |= IFF_MULTICAST; + dev->do_ioctl = smsc911x_do_ioctl; + netif_napi_add(dev, &pdata->napi, smsc911x_poll, 64); + dev->ethtool_ops = &smsc911x_ethtool_ops; + + /* Check if mac address has been specified when bringing interface up */ + if (is_valid_ether_addr(dev->dev_addr)) { + smsc911x_set_mac_address(pdata, dev->dev_addr); + SMSC_TRACE("MAC Address is specified by configuration"); + } else { + /* Try reading mac address from device. if EEPROM is present + * it will already have been set */ + u32 mac_high16 = smsc911x_mac_read(pdata, ADDRH); + u32 mac_low32 = smsc911x_mac_read(pdata, ADDRL); + dev->dev_addr[0] = (u8)(mac_low32); + dev->dev_addr[1] = (u8)(mac_low32 >> 8); + dev->dev_addr[2] = (u8)(mac_low32 >> 16); + dev->dev_addr[3] = (u8)(mac_low32 >> 24); + dev->dev_addr[4] = (u8)(mac_high16); + dev->dev_addr[5] = (u8)(mac_high16 >> 8); + + if (is_valid_ether_addr(dev->dev_addr)) { + /* eeprom values are valid so use them */ + SMSC_TRACE("Mac Address is read from LAN911x EEPROM"); + } else { + /* eeprom values are invalid, generate random MAC */ + random_ether_addr(dev->dev_addr); + smsc911x_set_mac_address(pdata, dev->dev_addr); + SMSC_TRACE("MAC Address is set to random_ether_addr"); + } + } + + printk(KERN_INFO + "%s: SMSC911x MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n", + dev->name, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], + dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); + +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = smsc911x_poll_controller; +#endif /* CONFIG_NET_POLL_CONTROLLER */ + + pdata->mii.phy_id_mask = 0x1f; + pdata->mii.reg_num_mask = 0x1f; + pdata->mii.force_media = 0; + pdata->mii.full_duplex = 0; + pdata->mii.dev = dev; + pdata->mii.mdio_read = smsc911x_mdio_read; + pdata->mii.mdio_write = smsc911x_mdio_write; + + pdata->msg_enable = NETIF_MSG_LINK; + + return 0; +} + +static int smsc911x_drv_remove(struct platform_device *pdev) +{ + struct net_device *dev; + struct smsc911x_data *pdata; + struct resource *res; + + dev = platform_get_drvdata(pdev); + BUG_ON(!dev); + pdata = netdev_priv(dev); + BUG_ON(!pdata); + BUG_ON(!pdata->ioaddr); + + SMSC_TRACE("Stopping driver."); + platform_set_drvdata(pdev, NULL); + unregister_netdev(dev); + free_irq(dev->irq, dev); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "smsc911x-memory"); + if (!res) + platform_get_resource(pdev, IORESOURCE_MEM, 0); + + release_mem_region(res->start, res->end - res->start); + + iounmap(pdata->ioaddr); + + free_netdev(dev); + + return 0; +} + +static int smsc911x_drv_probe(struct platform_device *pdev) +{ + struct net_device *dev; + struct smsc911x_data *pdata; + struct resource *res; + unsigned int intcfg = 0; + int res_size; + int retval; + + printk(KERN_INFO "%s: Driver version %s.\n", SMSC_CHIPNAME, + SMSC_DRV_VERSION); + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "smsc911x-memory"); + if (!res) + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + printk(KERN_WARNING "%s: Could not allocate resource.\n", + SMSC_CHIPNAME); + retval = -ENODEV; + goto out_0; + } + res_size = res->end - res->start; + + if (!request_mem_region(res->start, res_size, SMSC_CHIPNAME)) { + retval = -EBUSY; + goto out_0; + } + + dev = alloc_etherdev(sizeof(struct smsc911x_data)); + if (!dev) { + printk(KERN_WARNING "%s: Could not allocate device.\n", + SMSC_CHIPNAME); + retval = -ENOMEM; + goto out_release_io_1; + } + + SET_NETDEV_DEV(dev, &pdev->dev); + + pdata = netdev_priv(dev); + pdata->netdev = dev; + + dev->irq = platform_get_irq(pdev, 0); + pdata->ioaddr = ioremap_nocache(res->start, res_size); + + /* copy config parameters across if present, otherwise pdata + * defaults to zeros */ + if (pdev->dev.platform_data) { + struct smsc911x_platform_config *config = pdev->dev.platform_data; + pdata->irq_polarity = config->irq_polarity; + pdata->irq_type = config->irq_type; + } + + if (pdata->ioaddr == NULL) { + SMSC_WARNING("Error smsc911x base address invalid"); + retval = -ENOMEM; + goto out_free_netdev_2; + } + + if ((retval = smsc911x_init(dev)) < 0) + goto out_unmap_io_3; + + /* configure irq polarity and type before connecting isr */ + if (pdata->irq_polarity) + intcfg |= INT_CFG_IRQ_POL_; + + if (pdata->irq_type) + intcfg |= INT_CFG_IRQ_TYPE_; + + smsc911x_reg_write(intcfg, pdata, INT_CFG); + + retval = request_irq(dev->irq, smsc911x_irqhandler, IRQF_DISABLED, + SMSC_CHIPNAME, dev); + if (retval) { + SMSC_WARNING("Unable to claim requested irq: %d", dev->irq); + goto out_unmap_io_3; + } + + platform_set_drvdata(pdev, dev); + + retval = register_netdev(dev); + if (retval) { + SMSC_WARNING("Error %i registering device", retval); + goto out_unset_drvdata_4; + } else { + SMSC_TRACE("Network interface: \"%s\"", dev->name); + } + + return 0; + +out_unset_drvdata_4: + platform_set_drvdata(pdev, NULL); + free_irq(dev->irq, dev); +out_unmap_io_3: + iounmap(pdata->ioaddr); +out_free_netdev_2: + free_netdev(dev); +out_release_io_1: + release_mem_region(res->start, res->end - res->start); +out_0: + return retval; +} + +static int smsc911x_drv_suspend(struct platform_device *pdev, + pm_message_t state) +{ + unsigned long flags; + struct net_device *dev; + struct smsc911x_data *pdata; + + dev = platform_get_drvdata(pdev); + BUG_ON(!dev); + pdata = netdev_priv(dev); + BUG_ON(!pdata); + BUG_ON(!pdata->ioaddr); + + spin_lock_irqsave(&pdata->phy_lock, flags); + smsc911x_phy_write(pdata, MII_BMCR, BMCR_PDOWN); + spin_unlock_irqrestore(&pdata->phy_lock, flags); + + smsc911x_reg_write(PMT_CTRL_PM_MODE_D2_, pdata, PMT_CTRL); + + return 0; +} + +static int smsc911x_drv_resume(struct platform_device *pdev) +{ + unsigned long flags; + struct net_device *dev; + struct smsc911x_data *pdata; + unsigned int temp; + + dev = platform_get_drvdata(pdev); + BUG_ON(!dev); + pdata = netdev_priv(dev); + BUG_ON(!pdata); + BUG_ON(!pdata->ioaddr); + + smsc911x_reg_write(0xFFFFFFFF, pdata, BYTE_TEST); + while (!(smsc911x_reg_read(pdata, PMT_CTRL) & PMT_CTRL_READY_)) + ; + + spin_lock_irqsave(&pdata->phy_lock, flags); + smsc911x_phy_write(pdata, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART); + spin_unlock_irqrestore(&pdata->phy_lock, flags); + return 0; +} + +static struct platform_driver smsc911x_driver = { + .probe = smsc911x_drv_probe, + .remove = smsc911x_drv_remove, + .suspend = smsc911x_drv_suspend, + .resume = smsc911x_drv_resume, + .driver = { + .name = SMSC_CHIPNAME, + }, +}; + +/* Entry point for loading the module */ +static int __init smsc911x_init_module(void) +{ + return platform_driver_register(&smsc911x_driver); +} + +/* entry point for unloading the module */ +static void __exit smsc911x_cleanup_module(void) +{ + platform_driver_unregister(&smsc911x_driver); +} + +module_init(smsc911x_init_module); +module_exit(smsc911x_cleanup_module); --- linux-2.6.28.orig/drivers/net/smsc911x.h +++ linux-2.6.28/drivers/net/smsc911x.h @@ -0,0 +1,395 @@ +/*************************************************************************** + * + * Copyright (C) 2004-2007 SMSC + * Copyright (C) 2005 ARM + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the 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 __SMSC911X_H__ +#define __SMSC911X_H__ + +#if defined(CONFIG_MACH_MX37_3DS) || defined(CONFIG_MACH_MX25_3DS) +#define SMSC_CAN_USE_SPI 1 +#define SMSC_CAN_USE_32BIT 0 +#elif defined(CONFIG_MACH_MX31_3DS) || defined(CONFIG_MACH_MX35_3DS) +#define SMSC_CAN_USE_32BIT 0 +#define SMSC_CAN_USE_SPI 0 +#else +#define SMSC_CAN_USE_32BIT 1 +#define SMSC_CAN_USE_SPI 0 +#endif + +#define TX_FIFO_LOW_THRESHOLD (u32)1600 +#define SMSC911X_EEPROM_SIZE (u32)7 +#define USE_DEBUG 0 + +/* implements a PHY loopback test at initialisation time, to ensure a packet + * can be succesfully looped back */ +#define USE_PHY_WORK_AROUND + +/* 10/100 LED link-state inversion when media is disconnected */ +#define USE_LED1_WORK_AROUND + +/* platform_device configuration data, should be assigned to + * the platform_device's dev.platform_data */ +struct smsc911x_platform_config { + unsigned int irq_polarity; + unsigned int irq_type; +}; + +#if USE_DEBUG >= 1 +#define SMSC_WARNING(fmt, args...) \ + printk(KERN_EMERG "SMSC_WARNING: %s: " fmt "\n", \ + __FUNCTION__ , ## args) +#else +#define SMSC_WARNING(msg, args...) +#endif /* USE_DEBUG >= 1 */ + +#if USE_DEBUG >= 2 +#define SMSC_TRACE(fmt,args...) \ + printk(KERN_EMERG "SMSC_TRACE: %s: " fmt "\n", \ + __FUNCTION__ , ## args) +#else +#define SMSC_TRACE(msg,args...) +#endif /* USE_DEBUG >= 2 */ + +/* SMSC911x registers and bitfields */ +#define RX_DATA_FIFO 0x00 + +#define TX_DATA_FIFO 0x20 +#define TX_CMD_A_ON_COMP_ 0x80000000 +#define TX_CMD_A_BUF_END_ALGN_ 0x03000000 +#define TX_CMD_A_4_BYTE_ALGN_ 0x00000000 +#define TX_CMD_A_16_BYTE_ALGN_ 0x01000000 +#define TX_CMD_A_32_BYTE_ALGN_ 0x02000000 +#define TX_CMD_A_DATA_OFFSET_ 0x001F0000 +#define TX_CMD_A_FIRST_SEG_ 0x00002000 +#define TX_CMD_A_LAST_SEG_ 0x00001000 +#define TX_CMD_A_BUF_SIZE_ 0x000007FF +#define TX_CMD_B_PKT_TAG_ 0xFFFF0000 +#define TX_CMD_B_ADD_CRC_DISABLE_ 0x00002000 +#define TX_CMD_B_DISABLE_PADDING_ 0x00001000 +#define TX_CMD_B_PKT_BYTE_LENGTH_ 0x000007FF + +#define RX_STATUS_FIFO 0x40 +#define RX_STS_ES_ 0x00008000 +#define RX_STS_MCAST_ 0x00000400 + +#define RX_STATUS_FIFO_PEEK 0x44 + +#define TX_STATUS_FIFO 0x48 +#define TX_STS_ES_ 0x00008000 + +#define TX_STATUS_FIFO_PEEK 0x4C + +#define ID_REV 0x50 +#define ID_REV_CHIP_ID_ 0xFFFF0000 +#define ID_REV_REV_ID_ 0x0000FFFF + +#define INT_CFG 0x54 +#define INT_CFG_INT_DEAS_ 0xFF000000 +#define INT_CFG_INT_DEAS_CLR_ 0x00004000 +#define INT_CFG_INT_DEAS_STS_ 0x00002000 +#define INT_CFG_IRQ_INT_ 0x00001000 +#define INT_CFG_IRQ_EN_ 0x00000100 +#define INT_CFG_IRQ_POL_ 0x00000010 +#define INT_CFG_IRQ_TYPE_ 0x00000001 + +#define INT_STS 0x58 +#define INT_STS_SW_INT_ 0x80000000 +#define INT_STS_TXSTOP_INT_ 0x02000000 +#define INT_STS_RXSTOP_INT_ 0x01000000 +#define INT_STS_RXDFH_INT_ 0x00800000 +#define INT_STS_RXDF_INT_ 0x00400000 +#define INT_STS_TX_IOC_ 0x00200000 +#define INT_STS_RXD_INT_ 0x00100000 +#define INT_STS_GPT_INT_ 0x00080000 +#define INT_STS_PHY_INT_ 0x00040000 +#define INT_STS_PME_INT_ 0x00020000 +#define INT_STS_TXSO_ 0x00010000 +#define INT_STS_RWT_ 0x00008000 +#define INT_STS_RXE_ 0x00004000 +#define INT_STS_TXE_ 0x00002000 +#define INT_STS_TDFU_ 0x00000800 +#define INT_STS_TDFO_ 0x00000400 +#define INT_STS_TDFA_ 0x00000200 +#define INT_STS_TSFF_ 0x00000100 +#define INT_STS_TSFL_ 0x00000080 +#define INT_STS_RXDF_ 0x00000040 +#define INT_STS_RDFL_ 0x00000020 +#define INT_STS_RSFF_ 0x00000010 +#define INT_STS_RSFL_ 0x00000008 +#define INT_STS_GPIO2_INT_ 0x00000004 +#define INT_STS_GPIO1_INT_ 0x00000002 +#define INT_STS_GPIO0_INT_ 0x00000001 + +#define INT_EN 0x5C +#define INT_EN_SW_INT_EN_ 0x80000000 +#define INT_EN_TXSTOP_INT_EN_ 0x02000000 +#define INT_EN_RXSTOP_INT_EN_ 0x01000000 +#define INT_EN_RXDFH_INT_EN_ 0x00800000 +#define INT_EN_TIOC_INT_EN_ 0x00200000 +#define INT_EN_RXD_INT_EN_ 0x00100000 +#define INT_EN_GPT_INT_EN_ 0x00080000 +#define INT_EN_PHY_INT_EN_ 0x00040000 +#define INT_EN_PME_INT_EN_ 0x00020000 +#define INT_EN_TXSO_EN_ 0x00010000 +#define INT_EN_RWT_EN_ 0x00008000 +#define INT_EN_RXE_EN_ 0x00004000 +#define INT_EN_TXE_EN_ 0x00002000 +#define INT_EN_TDFU_EN_ 0x00000800 +#define INT_EN_TDFO_EN_ 0x00000400 +#define INT_EN_TDFA_EN_ 0x00000200 +#define INT_EN_TSFF_EN_ 0x00000100 +#define INT_EN_TSFL_EN_ 0x00000080 +#define INT_EN_RXDF_EN_ 0x00000040 +#define INT_EN_RDFL_EN_ 0x00000020 +#define INT_EN_RSFF_EN_ 0x00000010 +#define INT_EN_RSFL_EN_ 0x00000008 +#define INT_EN_GPIO2_INT_ 0x00000004 +#define INT_EN_GPIO1_INT_ 0x00000002 +#define INT_EN_GPIO0_INT_ 0x00000001 + +#define BYTE_TEST 0x64 + +#define FIFO_INT 0x68 +#define FIFO_INT_TX_AVAIL_LEVEL_ 0xFF000000 +#define FIFO_INT_TX_STS_LEVEL_ 0x00FF0000 +#define FIFO_INT_RX_AVAIL_LEVEL_ 0x0000FF00 +#define FIFO_INT_RX_STS_LEVEL_ 0x000000FF + +#define RX_CFG 0x6C +#define RX_CFG_RX_END_ALGN_ 0xC0000000 +#define RX_CFG_RX_END_ALGN4_ 0x00000000 +#define RX_CFG_RX_END_ALGN16_ 0x40000000 +#define RX_CFG_RX_END_ALGN32_ 0x80000000 +#define RX_CFG_RX_DMA_CNT_ 0x0FFF0000 +#define RX_CFG_RX_DUMP_ 0x00008000 +#define RX_CFG_RXDOFF_ 0x00001F00 + +#define TX_CFG 0x70 +#define TX_CFG_TXS_DUMP_ 0x00008000 +#define TX_CFG_TXD_DUMP_ 0x00004000 +#define TX_CFG_TXSAO_ 0x00000004 +#define TX_CFG_TX_ON_ 0x00000002 +#define TX_CFG_STOP_TX_ 0x00000001 + +#define HW_CFG 0x74 +#define HW_CFG_TTM_ 0x00200000 +#define HW_CFG_SF_ 0x00100000 +#define HW_CFG_TX_FIF_SZ_ 0x000F0000 +#define HW_CFG_TR_ 0x00003000 +#define HW_CFG_SRST_ 0x00000001 + +/* only available on 115/117 */ +#define HW_CFG_PHY_CLK_SEL_ 0x00000060 +#define HW_CFG_PHY_CLK_SEL_INT_PHY_ 0x00000000 +#define HW_CFG_PHY_CLK_SEL_EXT_PHY_ 0x00000020 +#define HW_CFG_PHY_CLK_SEL_CLK_DIS_ 0x00000040 +#define HW_CFG_SMI_SEL_ 0x00000010 +#define HW_CFG_EXT_PHY_DET_ 0x00000008 +#define HW_CFG_EXT_PHY_EN_ 0x00000004 +#define HW_CFG_SRST_TO_ 0x00000002 + +/* only available on 116/118 */ +#define HW_CFG_32_16_BIT_MODE_ 0x00000004 + +#define RX_DP_CTRL 0x78 +#define RX_DP_CTRL_RX_FFWD_ 0x80000000 + +#define RX_FIFO_INF 0x7C +#define RX_FIFO_INF_RXSUSED_ 0x00FF0000 +#define RX_FIFO_INF_RXDUSED_ 0x0000FFFF + +#define TX_FIFO_INF 0x80 +#define TX_FIFO_INF_TSUSED_ 0x00FF0000 +#define TX_FIFO_INF_TDFREE_ 0x0000FFFF + +#define PMT_CTRL 0x84 +#define PMT_CTRL_PM_MODE_ 0x00003000 +#define PMT_CTRL_PM_MODE_D0_ 0x00000000 +#define PMT_CTRL_PM_MODE_D1_ 0x00001000 +#define PMT_CTRL_PM_MODE_D2_ 0x00002000 +#define PMT_CTRL_PM_MODE_D3_ 0x00003000 +#define PMT_CTRL_PHY_RST_ 0x00000400 +#define PMT_CTRL_WOL_EN_ 0x00000200 +#define PMT_CTRL_ED_EN_ 0x00000100 +#define PMT_CTRL_PME_TYPE_ 0x00000040 +#define PMT_CTRL_WUPS_ 0x00000030 +#define PMT_CTRL_WUPS_NOWAKE_ 0x00000000 +#define PMT_CTRL_WUPS_ED_ 0x00000010 +#define PMT_CTRL_WUPS_WOL_ 0x00000020 +#define PMT_CTRL_WUPS_MULTI_ 0x00000030 +#define PMT_CTRL_PME_IND_ 0x00000008 +#define PMT_CTRL_PME_POL_ 0x00000004 +#define PMT_CTRL_PME_EN_ 0x00000002 +#define PMT_CTRL_READY_ 0x00000001 + +#define GPIO_CFG 0x88 +#define GPIO_CFG_LED3_EN_ 0x40000000 +#define GPIO_CFG_LED2_EN_ 0x20000000 +#define GPIO_CFG_LED1_EN_ 0x10000000 +#define GPIO_CFG_GPIO2_INT_POL_ 0x04000000 +#define GPIO_CFG_GPIO1_INT_POL_ 0x02000000 +#define GPIO_CFG_GPIO0_INT_POL_ 0x01000000 +#define GPIO_CFG_EEPR_EN_ 0x00700000 +#define GPIO_CFG_GPIOBUF2_ 0x00040000 +#define GPIO_CFG_GPIOBUF1_ 0x00020000 +#define GPIO_CFG_GPIOBUF0_ 0x00010000 +#define GPIO_CFG_GPIODIR2_ 0x00000400 +#define GPIO_CFG_GPIODIR1_ 0x00000200 +#define GPIO_CFG_GPIODIR0_ 0x00000100 +#define GPIO_CFG_GPIOD4_ 0x00000020 +#define GPIO_CFG_GPIOD3_ 0x00000010 +#define GPIO_CFG_GPIOD2_ 0x00000004 +#define GPIO_CFG_GPIOD1_ 0x00000002 +#define GPIO_CFG_GPIOD0_ 0x00000001 + +#define GPT_CFG 0x8C +#define GPT_CFG_TIMER_EN_ 0x20000000 +#define GPT_CFG_GPT_LOAD_ 0x0000FFFF + +#define GPT_CNT 0x90 +#define GPT_CNT_GPT_CNT_ 0x0000FFFF + +#define ENDIAN 0x98 + +#define FREE_RUN 0x9C + +#define RX_DROP 0xA0 + +#define MAC_CSR_CMD 0xA4 +#define MAC_CSR_CMD_CSR_BUSY_ 0x80000000 +#define MAC_CSR_CMD_R_NOT_W_ 0x40000000 +#define MAC_CSR_CMD_CSR_ADDR_ 0x000000FF + +#define MAC_CSR_DATA 0xA8 + +#define AFC_CFG 0xAC +#define AFC_CFG_AFC_HI_ 0x00FF0000 +#define AFC_CFG_AFC_LO_ 0x0000FF00 +#define AFC_CFG_BACK_DUR_ 0x000000F0 +#define AFC_CFG_FCMULT_ 0x00000008 +#define AFC_CFG_FCBRD_ 0x00000004 +#define AFC_CFG_FCADD_ 0x00000002 +#define AFC_CFG_FCANY_ 0x00000001 + +#define E2P_CMD 0xB0 +#define E2P_CMD_EPC_BUSY_ 0x80000000 +#define E2P_CMD_EPC_CMD_ 0x70000000 +#define E2P_CMD_EPC_CMD_READ_ 0x00000000 +#define E2P_CMD_EPC_CMD_EWDS_ 0x10000000 +#define E2P_CMD_EPC_CMD_EWEN_ 0x20000000 +#define E2P_CMD_EPC_CMD_WRITE_ 0x30000000 +#define E2P_CMD_EPC_CMD_WRAL_ 0x40000000 +#define E2P_CMD_EPC_CMD_ERASE_ 0x50000000 +#define E2P_CMD_EPC_CMD_ERAL_ 0x60000000 +#define E2P_CMD_EPC_CMD_RELOAD_ 0x70000000 +#define E2P_CMD_EPC_TIMEOUT_ 0x00000200 +#define E2P_CMD_MAC_ADDR_LOADED_ 0x00000100 +#define E2P_CMD_EPC_ADDR_ 0x000000FF + +#define E2P_DATA 0xB4 +#define E2P_DATA_EEPROM_DATA_ 0x000000FF +#define LAN_REGISTER_EXTENT 0x00000100 + +/* + * MAC Control and Status Register (Indirect Address) + * Offset (through the MAC_CSR CMD and DATA port) + */ +#define MAC_CR 0x01 +#define MAC_CR_RXALL_ 0x80000000 +#define MAC_CR_HBDIS_ 0x10000000 +#define MAC_CR_RCVOWN_ 0x00800000 +#define MAC_CR_LOOPBK_ 0x00200000 +#define MAC_CR_FDPX_ 0x00100000 +#define MAC_CR_MCPAS_ 0x00080000 +#define MAC_CR_PRMS_ 0x00040000 +#define MAC_CR_INVFILT_ 0x00020000 +#define MAC_CR_PASSBAD_ 0x00010000 +#define MAC_CR_HFILT_ 0x00008000 +#define MAC_CR_HPFILT_ 0x00002000 +#define MAC_CR_LCOLL_ 0x00001000 +#define MAC_CR_BCAST_ 0x00000800 +#define MAC_CR_DISRTY_ 0x00000400 +#define MAC_CR_PADSTR_ 0x00000100 +#define MAC_CR_BOLMT_MASK_ 0x000000C0 +#define MAC_CR_DFCHK_ 0x00000020 +#define MAC_CR_TXEN_ 0x00000008 +#define MAC_CR_RXEN_ 0x00000004 + +#define ADDRH 0x02 + +#define ADDRL 0x03 + +#define HASHH 0x04 + +#define HASHL 0x05 + +#define MII_ACC 0x06 +#define MII_ACC_PHY_ADDR_ 0x0000F800 +#define MII_ACC_MIIRINDA_ 0x000007C0 +#define MII_ACC_MII_WRITE_ 0x00000002 +#define MII_ACC_MII_BUSY_ 0x00000001 + +#define MII_DATA 0x07 + +#define FLOW 0x08 +#define FLOW_FCPT_ 0xFFFF0000 +#define FLOW_FCPASS_ 0x00000004 +#define FLOW_FCEN_ 0x00000002 +#define FLOW_FCBSY_ 0x00000001 + +#define VLAN1 0x09 + +#define VLAN2 0x0A + +#define WUFF 0x0B + +#define WUCSR 0x0C +#define WUCSR_GUE_ 0x00000200 +#define WUCSR_WUFR_ 0x00000040 +#define WUCSR_MPR_ 0x00000020 +#define WUCSR_WAKE_EN_ 0x00000004 +#define WUCSR_MPEN_ 0x00000002 + +/* + * Phy definitions (vendor-specific) + */ +#define LAN9118_PHY_ID 0x00C0001C + +#define MII_INTSTS 0x1D + +#define MII_INTMSK 0x1E +#define PHY_INTMSK_AN_RCV_ (1 << 1) +#define PHY_INTMSK_PDFAULT_ (1 << 2) +#define PHY_INTMSK_AN_ACK_ (1 << 3) +#define PHY_INTMSK_LNKDOWN_ (1 << 4) +#define PHY_INTMSK_RFAULT_ (1 << 5) +#define PHY_INTMSK_AN_COMP_ (1 << 6) +#define PHY_INTMSK_ENERGYON_ (1 << 7) +#define PHY_INTMSK_DEFAULT_ (PHY_INTMSK_ENERGYON_ | \ + PHY_INTMSK_AN_COMP_ | \ + PHY_INTMSK_RFAULT_ | \ + PHY_INTMSK_LNKDOWN_) + +#define ADVERTISE_PAUSE_ALL (ADVERTISE_PAUSE_CAP | \ + ADVERTISE_PAUSE_ASYM) + +#define LPA_PAUSE_ALL (LPA_PAUSE_CAP | \ + LPA_PAUSE_ASYM) + +#endif /* __SMSC911X_H__ */ --- linux-2.6.28.orig/drivers/net/e1000/e1000_main.c +++ linux-2.6.28/drivers/net/e1000/e1000_main.c @@ -31,7 +31,7 @@ char e1000_driver_name[] = "e1000"; static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; -#define DRV_VERSION "7.3.20-k3-NAPI" +#define DRV_VERSION "7.3.21-k3-NAPI" const char e1000_driver_version[] = DRV_VERSION; static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation."; @@ -921,7 +921,7 @@ err = pci_enable_device(pdev); } else { bars = pci_select_bars(pdev, IORESOURCE_MEM); - err = pci_enable_device(pdev); + err = pci_enable_device_mem(pdev); } if (err) return err; @@ -3732,7 +3732,7 @@ struct e1000_hw *hw = &adapter->hw; u32 rctl, icr = er32(ICR); - if (unlikely(!icr)) + if (unlikely((!icr) || test_bit(__E1000_RESETTING, &adapter->flags))) return IRQ_NONE; /* Not our interrupt */ /* IMS will not auto-mask if INT_ASSERTED is not set, and if it is --- linux-2.6.28.orig/drivers/net/e1000e/netdev.c +++ linux-2.6.28/drivers/net/e1000e/netdev.c @@ -5146,6 +5146,7 @@ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M), board_ich9lan }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_AMT), board_ich9lan }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_V), board_ich9lan }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_V_2), board_ich9lan }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LM), board_ich9lan }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LF), board_ich9lan }, --- linux-2.6.28.orig/drivers/net/e1000e/hw.h +++ linux-2.6.28/drivers/net/e1000e/hw.h @@ -355,6 +355,7 @@ #define E1000_DEV_ID_ICH9_IGP_M_AMT 0x10F5 #define E1000_DEV_ID_ICH9_IGP_M 0x10BF #define E1000_DEV_ID_ICH9_IGP_M_V 0x10CB +#define E1000_DEV_ID_ICH9_IGP_M_V_2 0x10BE #define E1000_DEV_ID_ICH9_IGP_C 0x294C #define E1000_DEV_ID_ICH9_IFE 0x10C0 #define E1000_DEV_ID_ICH9_IFE_GT 0x10C3 --- linux-2.6.28.orig/drivers/net/irda/irda-usb.c +++ linux-2.6.28/drivers/net/irda/irda-usb.c @@ -1075,7 +1075,7 @@ { unsigned int i; int ret; - char stir421x_fw_name[11]; + char stir421x_fw_name[12]; const struct firmware *fw; const unsigned char *fw_version_ptr; /* pointer to version string */ unsigned long fw_version = 0; --- linux-2.6.28.orig/drivers/net/skfp/skfddi.c +++ linux-2.6.28/drivers/net/skfp/skfddi.c @@ -998,9 +998,9 @@ break; case SKFP_CLR_STATS: /* Zero out the driver statistics */ if (!capable(CAP_NET_ADMIN)) { - memset(&lp->MacStat, 0, sizeof(lp->MacStat)); - } else { status = -EPERM; + } else { + memset(&lp->MacStat, 0, sizeof(lp->MacStat)); } break; default: --- linux-2.6.28.orig/drivers/net/usb/cdc_ether.c +++ linux-2.6.28/drivers/net/usb/cdc_ether.c @@ -559,6 +559,11 @@ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), .driver_info = (unsigned long) &cdc_info, +}, { + /* Ericsson F3507g */ + USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1900, USB_CLASS_COMM, + USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), + .driver_info = (unsigned long) &cdc_info, }, { }, // END }; --- linux-2.6.28.orig/drivers/net/usb/zaurus.c +++ linux-2.6.28/drivers/net/usb/zaurus.c @@ -341,6 +341,11 @@ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), .driver_info = (unsigned long) &bogus_mdlm_info, +}, { + /* Motorola MOTOMAGX phones */ + USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x6425, USB_CLASS_COMM, + USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), + .driver_info = (unsigned long) &bogus_mdlm_info, }, /* Olympus has some models with a Zaurus-compatible option. --- linux-2.6.28.orig/drivers/net/usb/asix.c +++ linux-2.6.28/drivers/net/usb/asix.c @@ -1450,6 +1450,14 @@ // Cables-to-Go USB Ethernet Adapter USB_DEVICE(0x0b95, 0x772a), .driver_info = (unsigned long) &ax88772_info, +}, { + // ABOCOM for pci + USB_DEVICE(0x14ea, 0xab11), + .driver_info = (unsigned long) &ax88178_info, +}, { + // ASIX 88772a + USB_DEVICE(0x0db0, 0xa877), + .driver_info = (unsigned long) &ax88772_info, }, { }, // END }; --- linux-2.6.28.orig/drivers/net/netxen/netxen_nic_ctx.c +++ linux-2.6.28/drivers/net/netxen/netxen_nic_ctx.c @@ -76,7 +76,7 @@ static u32 netxen_poll_rsp(struct netxen_adapter *adapter) { - u32 raw_rsp, rsp = NX_CDRP_RSP_OK; + u32 rsp = NX_CDRP_RSP_OK; int timeout = 0; do { @@ -86,10 +86,7 @@ if (++timeout > NX_OS_CRB_RETRY_COUNT) return NX_CDRP_RSP_TIMEOUT; - netxen_nic_read_w1(adapter, NX_CDRP_CRB_OFFSET, - &raw_rsp); - - rsp = le32_to_cpu(raw_rsp); + netxen_nic_read_w1(adapter, NX_CDRP_CRB_OFFSET, &rsp); } while (!NX_CDRP_IS_RSP(rsp)); return rsp; @@ -109,20 +106,16 @@ if (netxen_api_lock(adapter)) return NX_RCODE_TIMEOUT; - netxen_nic_write_w1(adapter, NX_SIGN_CRB_OFFSET, - cpu_to_le32(signature)); + netxen_nic_write_w1(adapter, NX_SIGN_CRB_OFFSET, signature); - netxen_nic_write_w1(adapter, NX_ARG1_CRB_OFFSET, - cpu_to_le32(arg1)); + netxen_nic_write_w1(adapter, NX_ARG1_CRB_OFFSET, arg1); - netxen_nic_write_w1(adapter, NX_ARG2_CRB_OFFSET, - cpu_to_le32(arg2)); + netxen_nic_write_w1(adapter, NX_ARG2_CRB_OFFSET, arg2); - netxen_nic_write_w1(adapter, NX_ARG3_CRB_OFFSET, - cpu_to_le32(arg3)); + netxen_nic_write_w1(adapter, NX_ARG3_CRB_OFFSET, arg3); netxen_nic_write_w1(adapter, NX_CDRP_CRB_OFFSET, - cpu_to_le32(NX_CDRP_FORM_CMD(cmd))); + NX_CDRP_FORM_CMD(cmd)); rsp = netxen_poll_rsp(adapter); @@ -133,7 +126,6 @@ rcode = NX_RCODE_TIMEOUT; } else if (rsp == NX_CDRP_RSP_FAIL) { netxen_nic_read_w1(adapter, NX_ARG1_CRB_OFFSET, &rcode); - rcode = le32_to_cpu(rcode); printk(KERN_ERR "%s: failed card response code:0x%x\n", netxen_nic_driver_name, rcode); @@ -183,7 +175,7 @@ int i, nrds_rings, nsds_rings; size_t rq_size, rsp_size; - u32 cap, reg; + u32 cap, reg, val; int err; @@ -225,11 +217,14 @@ prq->num_rds_rings = cpu_to_le16(nrds_rings); prq->num_sds_rings = cpu_to_le16(nsds_rings); - prq->rds_ring_offset = 0; - prq->sds_ring_offset = prq->rds_ring_offset + + prq->rds_ring_offset = cpu_to_le32(0); + + val = le32_to_cpu(prq->rds_ring_offset) + (sizeof(nx_hostrq_rds_ring_t) * nrds_rings); + prq->sds_ring_offset = cpu_to_le32(val); - prq_rds = (nx_hostrq_rds_ring_t *)(prq->data + prq->rds_ring_offset); + prq_rds = (nx_hostrq_rds_ring_t *)(prq->data + + le32_to_cpu(prq->rds_ring_offset)); for (i = 0; i < nrds_rings; i++) { @@ -241,17 +236,14 @@ prq_rds[i].buff_size = cpu_to_le64(rds_ring->dma_size); } - prq_sds = (nx_hostrq_sds_ring_t *)(prq->data + prq->sds_ring_offset); + prq_sds = (nx_hostrq_sds_ring_t *)(prq->data + + le32_to_cpu(prq->sds_ring_offset)); prq_sds[0].host_phys_addr = cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr); prq_sds[0].ring_size = cpu_to_le32(adapter->max_rx_desc_count); /* only one msix vector for now */ - prq_sds[0].msi_index = cpu_to_le32(0); - - /* now byteswap offsets */ - prq->rds_ring_offset = cpu_to_le32(prq->rds_ring_offset); - prq->sds_ring_offset = cpu_to_le32(prq->sds_ring_offset); + prq_sds[0].msi_index = cpu_to_le16(0); phys_addr = hostrq_phys_addr; err = netxen_issue_cmd(adapter, @@ -269,9 +261,9 @@ prsp_rds = ((nx_cardrsp_rds_ring_t *) - &prsp->data[prsp->rds_ring_offset]); + &prsp->data[le32_to_cpu(prsp->rds_ring_offset)]); - for (i = 0; i < le32_to_cpu(prsp->num_rds_rings); i++) { + for (i = 0; i < le16_to_cpu(prsp->num_rds_rings); i++) { rds_ring = &recv_ctx->rds_rings[i]; reg = le32_to_cpu(prsp_rds[i].host_producer_crb); @@ -279,7 +271,7 @@ } prsp_sds = ((nx_cardrsp_sds_ring_t *) - &prsp->data[prsp->sds_ring_offset]); + &prsp->data[le32_to_cpu(prsp->sds_ring_offset)]); reg = le32_to_cpu(prsp_sds[0].host_consumer_crb); recv_ctx->crb_sts_consumer = NETXEN_NIC_REG(reg - 0x200); @@ -288,7 +280,7 @@ recv_ctx->state = le32_to_cpu(prsp->host_ctx_state); recv_ctx->context_id = le16_to_cpu(prsp->context_id); - recv_ctx->virt_port = le16_to_cpu(prsp->virt_port); + recv_ctx->virt_port = prsp->virt_port; out_free_rsp: pci_free_consistent(adapter->pdev, rsp_size, prsp, cardrsp_phys_addr); --- linux-2.6.28.orig/drivers/net/netxen/netxen_nic_main.c +++ linux-2.6.28/drivers/net/netxen/netxen_nic_main.c @@ -39,7 +39,9 @@ #include "netxen_nic_phan_reg.h" #include +#include #include +#include MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver"); MODULE_LICENSE("GPL"); @@ -74,6 +76,7 @@ #endif static irqreturn_t netxen_intr(int irq, void *data); static irqreturn_t netxen_msi_intr(int irq, void *data); +static irqreturn_t netxen_msix_intr(int irq, void *data); /* PCI Device ID Table */ #define ENTRY(device) \ @@ -242,7 +245,7 @@ case NETXEN_BRDTYPE_P3_4_GB: case NETXEN_BRDTYPE_P3_4_GB_MM: adapter->msix_supported = !!use_msi_x; - adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G; + adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; break; case NETXEN_BRDTYPE_P2_SB35_4G: @@ -251,6 +254,14 @@ adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; break; + case NETXEN_BRDTYPE_P3_10G_TP: + adapter->msix_supported = !!use_msi_x; + if (adapter->ahw.board_type == NETXEN_NIC_XGBE) + adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G; + else + adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; + break; + default: adapter->msix_supported = 0; adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; @@ -271,10 +282,15 @@ static int netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot) { - int ret = 0; + u32 val, timeout; if (first_boot == 0x55555555) { /* This is the first boot after power up */ + adapter->pci_write_normalize(adapter, + NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC); + + if (!NX_IS_REVISION_P2(adapter->ahw.revision_id)) + return 0; /* PCI bus master workaround */ adapter->hw_read_wx(adapter, @@ -294,18 +310,26 @@ /* clear the register for future unloads/loads */ adapter->pci_write_normalize(adapter, NETXEN_CAM_RAM(0x1fc), 0); - ret = -1; + return -EIO; } - if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { - /* Start P2 boot loader */ - adapter->pci_write_normalize(adapter, - NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC); - adapter->pci_write_normalize(adapter, - NETXEN_ROMUSB_GLB_PEGTUNE_DONE, 1); - } + /* Start P2 boot loader */ + val = adapter->pci_read_normalize(adapter, + NETXEN_ROMUSB_GLB_PEGTUNE_DONE); + adapter->pci_write_normalize(adapter, + NETXEN_ROMUSB_GLB_PEGTUNE_DONE, val | 0x1); + timeout = 0; + do { + msleep(1); + val = adapter->pci_read_normalize(adapter, + NETXEN_CAM_RAM(0x1fc)); + + if (++timeout > 5000) + return -EIO; + + } while (val == NETXEN_BDINFO_MAGIC); } - return ret; + return 0; } static void netxen_set_port_mode(struct netxen_adapter *adapter) @@ -348,67 +372,6 @@ } } -#define PCI_CAP_ID_GEN 0x10 - -static void netxen_pcie_strap_init(struct netxen_adapter *adapter) -{ - u32 pdevfuncsave; - u32 c8c9value = 0; - u32 chicken = 0; - u32 control = 0; - int i, pos; - struct pci_dev *pdev; - - pdev = adapter->pdev; - - adapter->hw_read_wx(adapter, - NETXEN_PCIE_REG(PCIE_CHICKEN3), &chicken, 4); - /* clear chicken3.25:24 */ - chicken &= 0xFCFFFFFF; - /* - * if gen1 and B0, set F1020 - if gen 2, do nothing - * if gen2 set to F1000 - */ - pos = pci_find_capability(pdev, PCI_CAP_ID_GEN); - if (pos == 0xC0) { - pci_read_config_dword(pdev, pos + 0x10, &control); - if ((control & 0x000F0000) != 0x00020000) { - /* set chicken3.24 if gen1 */ - chicken |= 0x01000000; - } - printk(KERN_INFO "%s Gen2 strapping detected\n", - netxen_nic_driver_name); - c8c9value = 0xF1000; - } else { - /* set chicken3.24 if gen1 */ - chicken |= 0x01000000; - printk(KERN_INFO "%s Gen1 strapping detected\n", - netxen_nic_driver_name); - if (adapter->ahw.revision_id == NX_P3_B0) - c8c9value = 0xF1020; - else - c8c9value = 0; - - } - adapter->hw_write_wx(adapter, - NETXEN_PCIE_REG(PCIE_CHICKEN3), &chicken, 4); - - if (!c8c9value) - return; - - pdevfuncsave = pdev->devfn; - if (pdevfuncsave & 0x07) - return; - - for (i = 0; i < 8; i++) { - pci_read_config_dword(pdev, pos + 8, &control); - pci_read_config_dword(pdev, pos + 8, &control); - pci_write_config_dword(pdev, pos + 8, c8c9value); - pdev->devfn++; - } - pdev->devfn = pdevfuncsave; -} - static void netxen_set_msix_bit(struct pci_dev *pdev, int enable) { u32 control; @@ -701,17 +664,19 @@ #ifdef CONFIG_NET_POLL_CONTROLLER netdev->poll_controller = netxen_nic_poll_controller; #endif - /* ScatterGather support */ - netdev->features = NETIF_F_SG; - netdev->features |= NETIF_F_IP_CSUM; - netdev->features |= NETIF_F_TSO; + + netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO); + netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO); + if (NX_IS_REVISION_P3(revision_id)) { - netdev->features |= NETIF_F_IPV6_CSUM; - netdev->features |= NETIF_F_TSO6; + netdev->features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6); + netdev->vlan_features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6); } - if (adapter->pci_using_dac) + if (adapter->pci_using_dac) { netdev->features |= NETIF_F_HIGHDMA; + netdev->vlan_features |= NETIF_F_HIGHDMA; + } /* * Set the CRB window to invalid. If any register in window 0 is @@ -773,11 +738,8 @@ CRB_CMDPEG_STATE, 0); netxen_pinit_from_rom(adapter, 0); msleep(1); - netxen_load_firmware(adapter); } - - if (NX_IS_REVISION_P3(revision_id)) - netxen_pcie_strap_init(adapter); + netxen_load_firmware(adapter); if (NX_IS_REVISION_P2(revision_id)) { @@ -790,13 +752,6 @@ } - if ((first_boot == 0x55555555) && - (NX_IS_REVISION_P2(revision_id))) { - /* Unlock the HW, prompting the boot sequence */ - adapter->pci_write_normalize(adapter, - NETXEN_ROMUSB_GLB_PEGTUNE_DONE, 1); - } - err = netxen_initialize_adapter_offload(adapter); if (err) goto err_out_iounmap; @@ -810,7 +765,9 @@ adapter->pci_write_normalize(adapter, CRB_DRIVER_VERSION, i); /* Handshake with the card before we register the devices. */ - netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); + err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); + if (err) + goto err_out_free_offload; } /* first_driver */ @@ -914,6 +871,7 @@ if (adapter->flags & NETXEN_NIC_MSI_ENABLED) pci_disable_msi(pdev); +err_out_free_offload: if (first_driver) netxen_free_adapter_offload(adapter); @@ -957,6 +915,9 @@ netxen_free_hw_resources(adapter); netxen_release_rx_buffers(adapter); netxen_free_sw_resources(adapter); + + if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) + netxen_p3_free_mac_list(adapter); } if (adapter->portnum == 0) @@ -972,8 +933,10 @@ iounmap(adapter->ahw.db_base); iounmap(adapter->ahw.pci_base0); - iounmap(adapter->ahw.pci_base1); - iounmap(adapter->ahw.pci_base2); + if (adapter->ahw.pci_base1 != NULL) + iounmap(adapter->ahw.pci_base1); + if (adapter->ahw.pci_base2 != NULL) + iounmap(adapter->ahw.pci_base2); pci_release_regions(pdev); pci_disable_device(pdev); @@ -1048,7 +1011,9 @@ for (ring = 0; ring < adapter->max_rds_rings; ring++) netxen_post_rx_buffers(adapter, ctx, ring); } - if (NETXEN_IS_MSI_FAMILY(adapter)) + if (adapter->flags & NETXEN_NIC_MSIX_ENABLED) + handler = netxen_msix_intr; + else if (adapter->flags & NETXEN_NIC_MSI_ENABLED) handler = netxen_msi_intr; else { flags |= IRQF_SHARED; @@ -1126,29 +1091,72 @@ return 0; } -void netxen_tso_check(struct netxen_adapter *adapter, +static bool netxen_tso_check(struct net_device *netdev, struct cmd_desc_type0 *desc, struct sk_buff *skb) { - if (desc->mss) { - desc->total_hdr_length = (sizeof(struct ethhdr) + - ip_hdrlen(skb) + tcp_hdrlen(skb)); - - if ((NX_IS_REVISION_P3(adapter->ahw.revision_id)) && - (skb->protocol == htons(ETH_P_IPV6))) - netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO6); - else - netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO); + bool tso = false; + u8 opcode = TX_ETHER_PKT; + __be16 protocol = skb->protocol; + u16 flags = 0; + + if (protocol == __constant_htons(ETH_P_8021Q)) { + struct vlan_ethhdr *vh = (struct vlan_ethhdr *)skb->data; + protocol = vh->h_vlan_encapsulated_proto; + flags = FLAGS_VLAN_TAGGED; + } + + if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) && + skb_shinfo(skb)->gso_size > 0) { + + desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); + desc->total_hdr_length = + skb_transport_offset(skb) + tcp_hdrlen(skb); + + opcode = (protocol == __constant_htons(ETH_P_IPV6)) ? + TX_TCP_LSO6 : TX_TCP_LSO; + tso = true; } else if (skb->ip_summed == CHECKSUM_PARTIAL) { - if (ip_hdr(skb)->protocol == IPPROTO_TCP) - netxen_set_cmd_desc_opcode(desc, TX_TCP_PKT); - else if (ip_hdr(skb)->protocol == IPPROTO_UDP) - netxen_set_cmd_desc_opcode(desc, TX_UDP_PKT); - else - return; + u8 l4proto; + + if (protocol == __constant_htons(ETH_P_IP)) { + l4proto = ip_hdr(skb)->protocol; + + if (l4proto == IPPROTO_TCP) + opcode = TX_TCP_PKT; + else if(l4proto == IPPROTO_UDP) + opcode = TX_UDP_PKT; + } else if (protocol == __constant_htons(ETH_P_IPV6)) { + l4proto = ipv6_hdr(skb)->nexthdr; + + if (l4proto == IPPROTO_TCP) + opcode = TX_TCPV6_PKT; + else if(l4proto == IPPROTO_UDP) + opcode = TX_UDPV6_PKT; + } } desc->tcp_hdr_offset = skb_transport_offset(skb); desc->ip_hdr_offset = skb_network_offset(skb); + netxen_set_tx_flags_opcode(desc, flags, opcode); + return tso; +} + +static void +netxen_clean_tx_dma_mapping(struct pci_dev *pdev, + struct netxen_cmd_buffer *pbuf, int last) +{ + int k; + struct netxen_skb_frag *buffrag; + + buffrag = &pbuf->frag_array[0]; + pci_unmap_single(pdev, buffrag->dma, + buffrag->length, PCI_DMA_TODEVICE); + + for (k = 1; k < last; k++) { + buffrag = &pbuf->frag_array[k]; + pci_unmap_page(pdev, buffrag->dma, + buffrag->length, PCI_DMA_TODEVICE); + } } static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) @@ -1156,33 +1164,22 @@ struct netxen_adapter *adapter = netdev_priv(netdev); struct netxen_hardware_context *hw = &adapter->ahw; unsigned int first_seg_len = skb->len - skb->data_len; + struct netxen_cmd_buffer *pbuf; struct netxen_skb_frag *buffrag; - unsigned int i; + struct cmd_desc_type0 *hwdesc; + struct pci_dev *pdev = adapter->pdev; + dma_addr_t temp_dma; + int i, k; u32 producer, consumer; - u32 saved_producer = 0; - struct cmd_desc_type0 *hwdesc; - int k; - struct netxen_cmd_buffer *pbuf = NULL; - int frag_count; - int no_of_desc; + int frag_count, no_of_desc; u32 num_txd = adapter->max_tx_desc_count; + bool is_tso = false; frag_count = skb_shinfo(skb)->nr_frags + 1; /* There 4 fragments per descriptor */ no_of_desc = (frag_count + 3) >> 2; - if (netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) { - if (skb_shinfo(skb)->gso_size > 0) { - - no_of_desc++; - if ((ip_hdrlen(skb) + tcp_hdrlen(skb) + - sizeof(struct ethhdr)) > - (sizeof(struct cmd_desc_type0) - 2)) { - no_of_desc++; - } - } - } producer = adapter->cmd_producer; smp_mb(); @@ -1194,34 +1191,26 @@ } /* Copy the descriptors into the hardware */ - saved_producer = producer; hwdesc = &hw->cmd_desc_head[producer]; memset(hwdesc, 0, sizeof(struct cmd_desc_type0)); /* Take skb->data itself */ pbuf = &adapter->cmd_buf_arr[producer]; - if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) && - skb_shinfo(skb)->gso_size > 0) { - pbuf->mss = skb_shinfo(skb)->gso_size; - hwdesc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size); - } else { - pbuf->mss = 0; - hwdesc->mss = 0; - } - pbuf->total_length = skb->len; + + is_tso = netxen_tso_check(netdev, hwdesc, skb); + pbuf->skb = skb; - pbuf->cmd = TX_ETHER_PKT; pbuf->frag_count = frag_count; - pbuf->port = adapter->portnum; buffrag = &pbuf->frag_array[0]; - buffrag->dma = pci_map_single(adapter->pdev, skb->data, first_seg_len, + temp_dma = pci_map_single(pdev, skb->data, first_seg_len, PCI_DMA_TODEVICE); + if (pci_dma_mapping_error(pdev, temp_dma)) + goto drop_packet; + + buffrag->dma = temp_dma; buffrag->length = first_seg_len; - netxen_set_cmd_desc_totallength(hwdesc, skb->len); - netxen_set_cmd_desc_num_of_buff(hwdesc, frag_count); - netxen_set_cmd_desc_opcode(hwdesc, TX_ETHER_PKT); + netxen_set_tx_frags_len(hwdesc, frag_count, skb->len); + netxen_set_tx_port(hwdesc, adapter->portnum); - netxen_set_cmd_desc_port(hwdesc, adapter->portnum); - netxen_set_cmd_desc_ctxid(hwdesc, adapter->portnum); hwdesc->buffer1_length = cpu_to_le16(first_seg_len); hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma); @@ -1229,7 +1218,6 @@ struct skb_frag_struct *frag; int len, temp_len; unsigned long offset; - dma_addr_t temp_dma; /* move to next desc. if there is a need */ if ((i & 0x3) == 0) { @@ -1245,8 +1233,12 @@ offset = frag->page_offset; temp_len = len; - temp_dma = pci_map_page(adapter->pdev, frag->page, offset, + temp_dma = pci_map_page(pdev, frag->page, offset, len, PCI_DMA_TODEVICE); + if (pci_dma_mapping_error(pdev, temp_dma)) { + netxen_clean_tx_dma_mapping(pdev, pbuf, i); + goto drop_packet; + } buffrag++; buffrag->dma = temp_dma; @@ -1274,16 +1266,12 @@ } producer = get_next_index(producer, num_txd); - /* might change opcode to TX_TCP_LSO */ - netxen_tso_check(adapter, &hw->cmd_desc_head[saved_producer], skb); - /* For LSO, we need to copy the MAC/IP/TCP headers into * the descriptor ring */ - if (netxen_get_cmd_desc_opcode(&hw->cmd_desc_head[saved_producer]) - == TX_TCP_LSO) { + if (is_tso) { int hdr_len, first_hdr_len, more_hdr; - hdr_len = hw->cmd_desc_head[saved_producer].total_hdr_length; + hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); if (hdr_len > (sizeof(struct cmd_desc_type0) - 2)) { first_hdr_len = sizeof(struct cmd_desc_type0) - 2; more_hdr = 1; @@ -1325,6 +1313,11 @@ netdev->trans_start = jiffies; return NETDEV_TX_OK; + +drop_packet: + adapter->stats.txdropped++; + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; } static int netxen_nic_check_temp(struct netxen_adapter *adapter) @@ -1396,6 +1389,8 @@ netif_carrier_off(netdev); netif_stop_queue(netdev); } + + netxen_nic_set_link_parameters(adapter); } else if (!adapter->ahw.linkup && linkup) { printk(KERN_INFO "%s: %s NIC Link is up\n", netxen_nic_driver_name, netdev->name); @@ -1404,6 +1399,8 @@ netif_carrier_on(netdev); netif_wake_queue(netdev); } + + netxen_nic_set_link_parameters(adapter); } } @@ -1544,6 +1541,14 @@ return IRQ_HANDLED; } +static irqreturn_t netxen_msix_intr(int irq, void *data) +{ + struct netxen_adapter *adapter = data; + + napi_schedule(&adapter->napi); + return IRQ_HANDLED; +} + static int netxen_nic_poll(struct napi_struct *napi, int budget) { struct netxen_adapter *adapter = container_of(napi, struct netxen_adapter, napi); --- linux-2.6.28.orig/drivers/net/netxen/netxen_nic_hw.c +++ linux-2.6.28/drivers/net/netxen/netxen_nic_hw.c @@ -503,17 +503,15 @@ i = 0; + netif_tx_lock_bh(adapter->netdev); + producer = adapter->cmd_producer; do { cmd_desc = &cmd_desc_arr[i]; pbuf = &adapter->cmd_buf_arr[producer]; - pbuf->mss = 0; - pbuf->total_length = 0; pbuf->skb = NULL; - pbuf->cmd = 0; pbuf->frag_count = 0; - pbuf->port = 0; /* adapter->ahw.cmd_desc_head[producer] = *cmd_desc; */ memcpy(&adapter->ahw.cmd_desc_head[producer], @@ -531,6 +529,8 @@ netxen_nic_update_cmd_producer(adapter, adapter->cmd_producer); + netif_tx_unlock_bh(adapter->netdev); + return 0; } @@ -539,16 +539,19 @@ { struct netxen_adapter *adapter = (struct netxen_adapter *)dev->priv; nx_nic_req_t req; - nx_mac_req_t mac_req; + nx_mac_req_t *mac_req; + u64 word; int rv; memset(&req, 0, sizeof(nx_nic_req_t)); - req.qhdr |= (NX_NIC_REQUEST << 23); - req.req_hdr |= NX_MAC_EVENT; - req.req_hdr |= ((u64)adapter->portnum << 16); - mac_req.op = op; - memcpy(&mac_req.mac_addr, addr, 6); - req.words[0] = cpu_to_le64(*(u64 *)&mac_req); + req.qhdr = cpu_to_le64(NX_NIC_REQUEST << 23); + + word = NX_MAC_EVENT | ((u64)adapter->portnum << 16); + req.req_hdr = cpu_to_le64(word); + + mac_req = (nx_mac_req_t *)&req.words[0]; + mac_req->op = op; + memcpy(mac_req->mac_addr, addr, 6); rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); if (rv != 0) { @@ -612,18 +615,35 @@ int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) { nx_nic_req_t req; + u64 word; memset(&req, 0, sizeof(nx_nic_req_t)); - req.qhdr |= (NX_HOST_REQUEST << 23); - req.req_hdr |= NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE; - req.req_hdr |= ((u64)adapter->portnum << 16); + req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23); + + word = NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE | + ((u64)adapter->portnum << 16); + req.req_hdr = cpu_to_le64(word); + req.words[0] = cpu_to_le64(mode); return netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); } +void netxen_p3_free_mac_list(struct netxen_adapter *adapter) +{ + nx_mac_list_t *cur, *next; + + cur = adapter->mac_list; + + while (cur) { + next = cur->next; + kfree(cur); + cur = next; + } +} + #define NETXEN_CONFIG_INTR_COALESCE 3 /* @@ -632,13 +652,15 @@ int netxen_config_intr_coalesce(struct netxen_adapter *adapter) { nx_nic_req_t req; + u64 word; int rv; memset(&req, 0, sizeof(nx_nic_req_t)); - req.qhdr |= (NX_NIC_REQUEST << 23); - req.req_hdr |= NETXEN_CONFIG_INTR_COALESCE; - req.req_hdr |= ((u64)adapter->portnum << 16); + req.qhdr = cpu_to_le64(NX_NIC_REQUEST << 23); + + word = NETXEN_CONFIG_INTR_COALESCE | ((u64)adapter->portnum << 16); + req.req_hdr = cpu_to_le64(word); memcpy(&req.words[0], &adapter->coal, sizeof(adapter->coal)); @@ -772,13 +794,10 @@ adapter->hw_read_wx(adapter, crbaddr, &mac_lo, 4); adapter->hw_read_wx(adapter, crbaddr+4, &mac_hi, 4); - mac_hi = cpu_to_le32(mac_hi); - mac_lo = cpu_to_le32(mac_lo); - if (pci_func & 1) - *mac = ((mac_lo >> 16) | ((u64)mac_hi << 16)); + *mac = le64_to_cpu((mac_lo >> 16) | ((u64)mac_hi << 16)); else - *mac = ((mac_lo) | ((u64)mac_hi << 32)); + *mac = le64_to_cpu((u64)mac_lo | ((u64)mac_hi << 32)); return 0; } @@ -937,7 +956,7 @@ { int i; u32 data, size = 0; - u32 flashaddr = NETXEN_BOOTLD_START, memaddr = NETXEN_BOOTLD_START; + u32 flashaddr = NETXEN_BOOTLD_START; size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START)/4; @@ -949,10 +968,8 @@ if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0) return -EIO; - adapter->pci_mem_write(adapter, memaddr, &data, 4); + adapter->pci_mem_write(adapter, flashaddr, &data, 4); flashaddr += 4; - memaddr += 4; - cond_resched(); } msleep(1); @@ -1459,7 +1476,7 @@ mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2); else mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE); - if (mem_ptr == 0UL) { + if (mem_ptr == NULL) { *(uint8_t *)data = 0; return -1; } @@ -1533,7 +1550,7 @@ mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE*2); else mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE); - if (mem_ptr == 0UL) + if (mem_ptr == NULL) return -1; addr = mem_ptr; addr += start & (PAGE_SIZE - 1); @@ -2034,7 +2051,13 @@ rv = -1; } - DPRINTK(INFO, "Discovered board type:0x%x ", boardinfo->board_type); + if (boardinfo->board_type == NETXEN_BRDTYPE_P3_4_GB_MM) { + u32 gpio = netxen_nic_reg_read(adapter, + NETXEN_ROMUSB_GLB_PAD_GPIO_I); + if ((gpio & 0x8000) == 0) + boardinfo->board_type = NETXEN_BRDTYPE_P3_10G_TP; + } + switch ((netxen_brdtype_t) boardinfo->board_type) { case NETXEN_BRDTYPE_P2_SB35_4G: adapter->ahw.board_type = NETXEN_NIC_GBE; @@ -2053,7 +2076,6 @@ case NETXEN_BRDTYPE_P3_10G_SFP_QT: case NETXEN_BRDTYPE_P3_10G_XFP: case NETXEN_BRDTYPE_P3_10000_BASE_T: - adapter->ahw.board_type = NETXEN_NIC_XGBE; break; case NETXEN_BRDTYPE_P1_BD: @@ -2063,9 +2085,12 @@ case NETXEN_BRDTYPE_P3_REF_QG: case NETXEN_BRDTYPE_P3_4_GB: case NETXEN_BRDTYPE_P3_4_GB_MM: - adapter->ahw.board_type = NETXEN_NIC_GBE; break; + case NETXEN_BRDTYPE_P3_10G_TP: + adapter->ahw.board_type = (adapter->portnum < 2) ? + NETXEN_NIC_XGBE : NETXEN_NIC_GBE; + break; default: printk("%s: Unknown(%x)\n", netxen_nic_driver_name, boardinfo->board_type); @@ -2110,12 +2135,16 @@ { __u32 status; __u32 autoneg; - __u32 mode; __u32 port_mode; - netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, &mode); - if (netxen_get_niu_enable_ge(mode)) { /* Gb 10/100/1000 Mbps mode */ + if (!netif_carrier_ok(adapter->netdev)) { + adapter->link_speed = 0; + adapter->link_duplex = -1; + adapter->link_autoneg = AUTONEG_ENABLE; + return; + } + if (adapter->ahw.board_type == NETXEN_NIC_GBE) { adapter->hw_read_wx(adapter, NETXEN_PORT_MODE_ADDR, &port_mode, 4); if (port_mode == NETXEN_PORT_MODE_802_3_AP) { @@ -2141,7 +2170,7 @@ adapter->link_speed = SPEED_1000; break; default: - adapter->link_speed = -1; + adapter->link_speed = 0; break; } switch (netxen_get_phy_duplex(status)) { @@ -2164,7 +2193,7 @@ goto link_down; } else { link_down: - adapter->link_speed = -1; + adapter->link_speed = 0; adapter->link_duplex = -1; } } --- linux-2.6.28.orig/drivers/net/netxen/netxen_nic_ethtool.c +++ linux-2.6.28/drivers/net/netxen/netxen_nic_ethtool.c @@ -136,11 +136,9 @@ ecmd->port = PORT_TP; - if (netif_running(dev)) { - ecmd->speed = adapter->link_speed; - ecmd->duplex = adapter->link_duplex; - ecmd->autoneg = adapter->link_autoneg; - } + ecmd->speed = adapter->link_speed; + ecmd->duplex = adapter->link_duplex; + ecmd->autoneg = adapter->link_autoneg; } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { u32 val; @@ -171,7 +169,7 @@ } else return -EIO; - ecmd->phy_address = adapter->portnum; + ecmd->phy_address = adapter->physical_port; ecmd->transceiver = XCVR_EXTERNAL; switch ((netxen_brdtype_t) boardinfo->board_type) { @@ -180,13 +178,13 @@ case NETXEN_BRDTYPE_P3_REF_QG: case NETXEN_BRDTYPE_P3_4_GB: case NETXEN_BRDTYPE_P3_4_GB_MM: - case NETXEN_BRDTYPE_P3_10000_BASE_T: ecmd->supported |= SUPPORTED_Autoneg; ecmd->advertising |= ADVERTISED_Autoneg; case NETXEN_BRDTYPE_P2_SB31_10G_CX4: case NETXEN_BRDTYPE_P3_10G_CX4: case NETXEN_BRDTYPE_P3_10G_CX4_LP: + case NETXEN_BRDTYPE_P3_10000_BASE_T: ecmd->supported |= SUPPORTED_TP; ecmd->advertising |= ADVERTISED_TP; ecmd->port = PORT_TP; @@ -204,16 +202,33 @@ ecmd->port = PORT_FIBRE; ecmd->autoneg = AUTONEG_DISABLE; break; - case NETXEN_BRDTYPE_P2_SB31_10G: case NETXEN_BRDTYPE_P3_10G_SFP_PLUS: case NETXEN_BRDTYPE_P3_10G_SFP_CT: case NETXEN_BRDTYPE_P3_10G_SFP_QT: + ecmd->advertising |= ADVERTISED_TP; + ecmd->supported |= SUPPORTED_TP; + case NETXEN_BRDTYPE_P2_SB31_10G: case NETXEN_BRDTYPE_P3_10G_XFP: ecmd->supported |= SUPPORTED_FIBRE; ecmd->advertising |= ADVERTISED_FIBRE; ecmd->port = PORT_FIBRE; ecmd->autoneg = AUTONEG_DISABLE; break; + case NETXEN_BRDTYPE_P3_10G_TP: + if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { + ecmd->autoneg = AUTONEG_DISABLE; + ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP); + ecmd->advertising |= + (ADVERTISED_FIBRE | ADVERTISED_TP); + ecmd->port = PORT_FIBRE; + } else { + ecmd->autoneg = AUTONEG_ENABLE; + ecmd->supported |= (SUPPORTED_TP |SUPPORTED_Autoneg); + ecmd->advertising |= + (ADVERTISED_TP | ADVERTISED_Autoneg); + ecmd->port = PORT_TP; + } + break; default: printk(KERN_ERR "netxen-nic: Unsupported board model %d\n", (netxen_brdtype_t) boardinfo->board_type); @@ -546,7 +561,10 @@ } ring->tx_pending = adapter->max_tx_desc_count; - ring->rx_max_pending = MAX_RCV_DESCRIPTORS; + if (adapter->ahw.board_type == NETXEN_NIC_GBE) + ring->rx_max_pending = MAX_RCV_DESCRIPTORS_1G; + else + ring->rx_max_pending = MAX_RCV_DESCRIPTORS_10G; ring->tx_max_pending = MAX_CMD_DESCRIPTORS_HOST; ring->rx_jumbo_max_pending = MAX_JUMBO_RCV_DESCRIPTORS; ring->rx_mini_max_pending = 0; --- linux-2.6.28.orig/drivers/net/netxen/netxen_nic_init.c +++ linux-2.6.28/drivers/net/netxen/netxen_nic_init.c @@ -308,7 +308,6 @@ } memset(rds_ring->rx_buf_arr, 0, RCV_BUFFSIZE); INIT_LIST_HEAD(&rds_ring->free_list); - rds_ring->begin_alloc = 0; /* * Now go through all of them, set reference handles * and put them in the queues. @@ -439,6 +438,8 @@ long timeout = 0; long done = 0; + cond_resched(); + while (done == 0) { done = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_GLB_STATUS); done &= 2; @@ -533,12 +534,9 @@ static int do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) { - cond_resched(); - netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr); - netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3); - udelay(100); /* prevent bursting on CRB */ netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0); + netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3); netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb); if (netxen_wait_rom_done(adapter)) { printk("Error waiting for rom done\n"); @@ -546,7 +544,7 @@ } /* reset abyte_cnt and dummy_byte_cnt */ netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0); - udelay(100); /* prevent bursting on CRB */ + udelay(10); netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0); *valp = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_ROM_RDATA); @@ -884,14 +882,16 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) { int addr, val; - int i, init_delay = 0; + int i, n, init_delay = 0; struct crb_addr_pair *buf; - unsigned offset, n; + unsigned offset; u32 off; /* resetall */ + rom_lock(adapter); netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff); + netxen_rom_unlock(adapter); if (verbose) { if (netxen_rom_fast_read(adapter, NETXEN_BOARDTYPE, &val) == 0) @@ -910,7 +910,7 @@ if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { if (netxen_rom_fast_read(adapter, 0, &n) != 0 || - (n != 0xcafecafeUL) || + (n != 0xcafecafe) || netxen_rom_fast_read(adapter, 4, &n) != 0) { printk(KERN_ERR "%s: ERROR Reading crb_init area: " "n: %08x\n", netxen_nic_driver_name, n); @@ -947,8 +947,10 @@ } for (i = 0; i < n; i++) { if (netxen_rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 || - netxen_rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0) + netxen_rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0) { + kfree(buf); return -EIO; + } buf[i].addr = addr; buf[i].data = val; @@ -975,6 +977,14 @@ /* do not reset PCI */ if (off == (ROMUSB_GLB + 0xbc)) continue; + if (off == (ROMUSB_GLB + 0xa8)) + continue; + if (off == (ROMUSB_GLB + 0xc8)) /* core clock */ + continue; + if (off == (ROMUSB_GLB + 0x24)) /* MN clock */ + continue; + if (off == (ROMUSB_GLB + 0x1c)) /* MS clock */ + continue; if (off == (NETXEN_CRB_PEG_NET_1 + 0x18)) buf[i].data = 0x1020; /* skip the function enable register */ @@ -992,23 +1002,21 @@ continue; } + init_delay = 1; /* After writing this register, HW needs time for CRB */ /* to quiet down (else crb_window returns 0xffffffff) */ if (off == NETXEN_ROMUSB_GLB_SW_RESET) { - init_delay = 1; + init_delay = 1000; if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { /* hold xdma in reset also */ buf[i].data = NETXEN_NIC_XDMA_RESET; + buf[i].data = 0x8000ff; } } adapter->hw_write_wx(adapter, off, &buf[i].data, 4); - if (init_delay == 1) { - msleep(1000); - init_delay = 0; - } - msleep(1); + msleep(init_delay); } kfree(buf); @@ -1277,7 +1285,7 @@ dev_kfree_skb_any(skb); for (i = 0; i < nr_frags; i++) { - index = frag_desc->frag_handles[i]; + index = le16_to_cpu(frag_desc->frag_handles[i]); skb = netxen_process_rxbuf(adapter, rds_ring, index, cksum); if (skb) @@ -1430,7 +1438,6 @@ struct rcv_desc *pdesc; struct netxen_rx_buffer *buffer; int count = 0; - int index = 0; netxen_ctx_msg msg = 0; dma_addr_t dma; struct list_head *head; @@ -1438,7 +1445,6 @@ rds_ring = &recv_ctx->rds_rings[ringid]; producer = rds_ring->producer; - index = rds_ring->begin_alloc; head = &rds_ring->free_list; /* We can start writing rx descriptors into the phantom memory. */ @@ -1446,39 +1452,37 @@ skb = dev_alloc_skb(rds_ring->skb_size); if (unlikely(!skb)) { - rds_ring->begin_alloc = index; break; } + if (!adapter->ahw.cut_through) + skb_reserve(skb, 2); + + dma = pci_map_single(pdev, skb->data, + rds_ring->dma_size, PCI_DMA_FROMDEVICE); + if (pci_dma_mapping_error(pdev, dma)) { + dev_kfree_skb_any(skb); + break; + } + + count++; buffer = list_entry(head->next, struct netxen_rx_buffer, list); list_del(&buffer->list); - count++; /* now there should be no failure */ - pdesc = &rds_ring->desc_head[producer]; - - if (!adapter->ahw.cut_through) - skb_reserve(skb, 2); - /* This will be setup when we receive the - * buffer after it has been filled FSL TBD TBD - * skb->dev = netdev; - */ - dma = pci_map_single(pdev, skb->data, rds_ring->dma_size, - PCI_DMA_FROMDEVICE); - pdesc->addr_buffer = cpu_to_le64(dma); buffer->skb = skb; buffer->state = NETXEN_BUFFER_BUSY; buffer->dma = dma; + /* make a rcv descriptor */ + pdesc = &rds_ring->desc_head[producer]; + pdesc->addr_buffer = cpu_to_le64(dma); pdesc->reference_handle = cpu_to_le16(buffer->ref_handle); pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size); - DPRINTK(INFO, "done writing descripter\n"); - producer = - get_next_index(producer, rds_ring->max_rx_desc_count); - index = get_next_index(index, rds_ring->max_rx_desc_count); + + producer = get_next_index(producer, rds_ring->max_rx_desc_count); } /* if we did allocate buffers, then write the count to Phantom */ if (count) { - rds_ring->begin_alloc = index; rds_ring->producer = producer; /* Window = 1 */ adapter->pci_write_normalize(adapter, @@ -1517,49 +1521,50 @@ struct rcv_desc *pdesc; struct netxen_rx_buffer *buffer; int count = 0; - int index = 0; struct list_head *head; + dma_addr_t dma; rds_ring = &recv_ctx->rds_rings[ringid]; producer = rds_ring->producer; - index = rds_ring->begin_alloc; head = &rds_ring->free_list; /* We can start writing rx descriptors into the phantom memory. */ while (!list_empty(head)) { skb = dev_alloc_skb(rds_ring->skb_size); if (unlikely(!skb)) { - rds_ring->begin_alloc = index; break; } + if (!adapter->ahw.cut_through) + skb_reserve(skb, 2); + + dma = pci_map_single(pdev, skb->data, + rds_ring->dma_size, PCI_DMA_FROMDEVICE); + if (pci_dma_mapping_error(pdev, dma)) { + dev_kfree_skb_any(skb); + break; + } + + count++; buffer = list_entry(head->next, struct netxen_rx_buffer, list); list_del(&buffer->list); - count++; /* now there should be no failure */ - pdesc = &rds_ring->desc_head[producer]; - if (!adapter->ahw.cut_through) - skb_reserve(skb, 2); buffer->skb = skb; buffer->state = NETXEN_BUFFER_BUSY; - buffer->dma = pci_map_single(pdev, skb->data, - rds_ring->dma_size, - PCI_DMA_FROMDEVICE); + buffer->dma = dma; /* make a rcv descriptor */ + pdesc = &rds_ring->desc_head[producer]; pdesc->reference_handle = cpu_to_le16(buffer->ref_handle); pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size); pdesc->addr_buffer = cpu_to_le64(buffer->dma); - producer = - get_next_index(producer, rds_ring->max_rx_desc_count); - index = get_next_index(index, rds_ring->max_rx_desc_count); - buffer = &rds_ring->rx_buf_arr[index]; + + producer = get_next_index(producer, rds_ring->max_rx_desc_count); } /* if we did allocate buffers, then write the count to Phantom */ if (count) { - rds_ring->begin_alloc = index; rds_ring->producer = producer; /* Window = 1 */ adapter->pci_write_normalize(adapter, --- linux-2.6.28.orig/drivers/net/netxen/netxen_nic.h +++ linux-2.6.28/drivers/net/netxen/netxen_nic.h @@ -146,7 +146,7 @@ #define MAX_RX_BUFFER_LENGTH 1760 #define MAX_RX_JUMBO_BUFFER_LENGTH 8062 -#define MAX_RX_LRO_BUFFER_LENGTH ((48*1024)-512) +#define MAX_RX_LRO_BUFFER_LENGTH (8062) #define RX_DMA_MAP_LEN (MAX_RX_BUFFER_LENGTH - 2) #define RX_JUMBO_DMA_MAP_LEN \ (MAX_RX_JUMBO_BUFFER_LENGTH - 2) @@ -207,11 +207,11 @@ #define MAX_CMD_DESCRIPTORS 4096 #define MAX_RCV_DESCRIPTORS 16384 -#define MAX_CMD_DESCRIPTORS_HOST (MAX_CMD_DESCRIPTORS / 4) -#define MAX_RCV_DESCRIPTORS_1G (MAX_RCV_DESCRIPTORS / 4) -#define MAX_RCV_DESCRIPTORS_10G 8192 +#define MAX_CMD_DESCRIPTORS_HOST 1024 +#define MAX_RCV_DESCRIPTORS_1G 2048 +#define MAX_RCV_DESCRIPTORS_10G 4096 #define MAX_JUMBO_RCV_DESCRIPTORS 1024 -#define MAX_LRO_RCV_DESCRIPTORS 64 +#define MAX_LRO_RCV_DESCRIPTORS 8 #define MAX_RCVSTATUS_DESCRIPTORS MAX_RCV_DESCRIPTORS #define MAX_JUMBO_RCV_DESC MAX_JUMBO_RCV_DESCRIPTORS #define MAX_RCV_DESC MAX_RCV_DESCRIPTORS @@ -308,27 +308,16 @@ #define netxen_set_cmd_desc_ctxid(cmd_desc, var) \ ((cmd_desc)->port_ctxid |= ((var) << 4 & 0xF0)) -#define netxen_set_cmd_desc_flags(cmd_desc, val) \ - (cmd_desc)->flags_opcode = ((cmd_desc)->flags_opcode & \ - ~cpu_to_le16(0x7f)) | cpu_to_le16((val) & 0x7f) -#define netxen_set_cmd_desc_opcode(cmd_desc, val) \ - (cmd_desc)->flags_opcode = ((cmd_desc)->flags_opcode & \ - ~cpu_to_le16((u16)0x3f << 7)) | cpu_to_le16(((val) & 0x3f) << 7) - -#define netxen_set_cmd_desc_num_of_buff(cmd_desc, val) \ - (cmd_desc)->num_of_buffers_total_length = \ - ((cmd_desc)->num_of_buffers_total_length & \ - ~cpu_to_le32(0xff)) | cpu_to_le32((val) & 0xff) -#define netxen_set_cmd_desc_totallength(cmd_desc, val) \ - (cmd_desc)->num_of_buffers_total_length = \ - ((cmd_desc)->num_of_buffers_total_length & \ - ~cpu_to_le32((u32)0xffffff << 8)) | \ - cpu_to_le32(((val) & 0xffffff) << 8) - -#define netxen_get_cmd_desc_opcode(cmd_desc) \ - ((le16_to_cpu((cmd_desc)->flags_opcode) >> 7) & 0x003f) -#define netxen_get_cmd_desc_totallength(cmd_desc) \ - ((le32_to_cpu((cmd_desc)->num_of_buffers_total_length) >> 8) & 0xffffff) +#define netxen_set_tx_port(_desc, _port) \ + (_desc)->port_ctxid = ((_port) & 0xf) | (((_port) << 4) & 0xf0) + +#define netxen_set_tx_flags_opcode(_desc, _flags, _opcode) \ + (_desc)->flags_opcode = \ + cpu_to_le16(((_flags) & 0x7f) | (((_opcode) & 0x3f) << 7)) + +#define netxen_set_tx_frags_len(_desc, _frags, _len) \ + (_desc)->num_of_buffers_total_length = \ + cpu_to_le32(((_frags) & 0xff) | (((_len) & 0xffffff) << 8)) struct cmd_desc_type0 { u8 tcp_hdr_offset; /* For LSO only */ @@ -510,7 +499,8 @@ NETXEN_BRDTYPE_P3_10G_SFP_CT = 0x002a, NETXEN_BRDTYPE_P3_10G_SFP_QT = 0x002b, NETXEN_BRDTYPE_P3_10G_CX4 = 0x0031, - NETXEN_BRDTYPE_P3_10G_XFP = 0x0032 + NETXEN_BRDTYPE_P3_10G_XFP = 0x0032, + NETXEN_BRDTYPE_P3_10G_TP = 0x0080 } netxen_brdtype_t; @@ -757,7 +747,7 @@ */ struct netxen_skb_frag { u64 dma; - u32 length; + ulong length; }; #define _netxen_set_bits(config_word, start, bits, val) {\ @@ -783,13 +773,7 @@ struct netxen_cmd_buffer { struct sk_buff *skb; struct netxen_skb_frag frag_array[MAX_BUFFERS_PER_CMD + 1]; - u32 total_length; - u32 mss; - u16 port; - u8 cmd; - u8 frag_count; - unsigned long time_stamp; - u32 state; + u32 frag_count; }; /* In rx_buffer, we do not need multiple fragments as is a single buffer */ @@ -876,7 +860,6 @@ u32 skb_size; struct netxen_rx_buffer *rx_buf_arr; /* rx buffers for receive */ struct list_head free_list; - int begin_alloc; }; /* @@ -995,31 +978,31 @@ */ typedef struct { - u64 host_phys_addr; /* Ring base addr */ - u32 ring_size; /* Ring entries */ - u16 msi_index; - u16 rsvd; /* Padding */ + __le64 host_phys_addr; /* Ring base addr */ + __le32 ring_size; /* Ring entries */ + __le16 msi_index; + __le16 rsvd; /* Padding */ } nx_hostrq_sds_ring_t; typedef struct { - u64 host_phys_addr; /* Ring base addr */ - u64 buff_size; /* Packet buffer size */ - u32 ring_size; /* Ring entries */ - u32 ring_kind; /* Class of ring */ + __le64 host_phys_addr; /* Ring base addr */ + __le64 buff_size; /* Packet buffer size */ + __le32 ring_size; /* Ring entries */ + __le32 ring_kind; /* Class of ring */ } nx_hostrq_rds_ring_t; typedef struct { - u64 host_rsp_dma_addr; /* Response dma'd here */ - u32 capabilities[4]; /* Flag bit vector */ - u32 host_int_crb_mode; /* Interrupt crb usage */ - u32 host_rds_crb_mode; /* RDS crb usage */ + __le64 host_rsp_dma_addr; /* Response dma'd here */ + __le32 capabilities[4]; /* Flag bit vector */ + __le32 host_int_crb_mode; /* Interrupt crb usage */ + __le32 host_rds_crb_mode; /* RDS crb usage */ /* These ring offsets are relative to data[0] below */ - u32 rds_ring_offset; /* Offset to RDS config */ - u32 sds_ring_offset; /* Offset to SDS config */ - u16 num_rds_rings; /* Count of RDS rings */ - u16 num_sds_rings; /* Count of SDS rings */ - u16 rsvd1; /* Padding */ - u16 rsvd2; /* Padding */ + __le32 rds_ring_offset; /* Offset to RDS config */ + __le32 sds_ring_offset; /* Offset to SDS config */ + __le16 num_rds_rings; /* Count of RDS rings */ + __le16 num_sds_rings; /* Count of SDS rings */ + __le16 rsvd1; /* Padding */ + __le16 rsvd2; /* Padding */ u8 reserved[128]; /* reserve space for future expansion*/ /* MUST BE 64-bit aligned. The following is packed: @@ -1029,24 +1012,24 @@ } nx_hostrq_rx_ctx_t; typedef struct { - u32 host_producer_crb; /* Crb to use */ - u32 rsvd1; /* Padding */ + __le32 host_producer_crb; /* Crb to use */ + __le32 rsvd1; /* Padding */ } nx_cardrsp_rds_ring_t; typedef struct { - u32 host_consumer_crb; /* Crb to use */ - u32 interrupt_crb; /* Crb to use */ + __le32 host_consumer_crb; /* Crb to use */ + __le32 interrupt_crb; /* Crb to use */ } nx_cardrsp_sds_ring_t; typedef struct { /* These ring offsets are relative to data[0] below */ - u32 rds_ring_offset; /* Offset to RDS config */ - u32 sds_ring_offset; /* Offset to SDS config */ - u32 host_ctx_state; /* Starting State */ - u32 num_fn_per_port; /* How many PCI fn share the port */ - u16 num_rds_rings; /* Count of RDS rings */ - u16 num_sds_rings; /* Count of SDS rings */ - u16 context_id; /* Handle for context */ + __le32 rds_ring_offset; /* Offset to RDS config */ + __le32 sds_ring_offset; /* Offset to SDS config */ + __le32 host_ctx_state; /* Starting State */ + __le32 num_fn_per_port; /* How many PCI fn share the port */ + __le16 num_rds_rings; /* Count of RDS rings */ + __le16 num_sds_rings; /* Count of SDS rings */ + __le16 context_id; /* Handle for context */ u8 phys_port; /* Physical id of port */ u8 virt_port; /* Virtual/Logical id of port */ u8 reserved[128]; /* save space for future expansion */ @@ -1072,34 +1055,34 @@ */ typedef struct { - u64 host_phys_addr; /* Ring base addr */ - u32 ring_size; /* Ring entries */ - u32 rsvd; /* Padding */ + __le64 host_phys_addr; /* Ring base addr */ + __le32 ring_size; /* Ring entries */ + __le32 rsvd; /* Padding */ } nx_hostrq_cds_ring_t; typedef struct { - u64 host_rsp_dma_addr; /* Response dma'd here */ - u64 cmd_cons_dma_addr; /* */ - u64 dummy_dma_addr; /* */ - u32 capabilities[4]; /* Flag bit vector */ - u32 host_int_crb_mode; /* Interrupt crb usage */ - u32 rsvd1; /* Padding */ - u16 rsvd2; /* Padding */ - u16 interrupt_ctl; - u16 msi_index; - u16 rsvd3; /* Padding */ + __le64 host_rsp_dma_addr; /* Response dma'd here */ + __le64 cmd_cons_dma_addr; /* */ + __le64 dummy_dma_addr; /* */ + __le32 capabilities[4]; /* Flag bit vector */ + __le32 host_int_crb_mode; /* Interrupt crb usage */ + __le32 rsvd1; /* Padding */ + __le16 rsvd2; /* Padding */ + __le16 interrupt_ctl; + __le16 msi_index; + __le16 rsvd3; /* Padding */ nx_hostrq_cds_ring_t cds_ring; /* Desc of cds ring */ u8 reserved[128]; /* future expansion */ } nx_hostrq_tx_ctx_t; typedef struct { - u32 host_producer_crb; /* Crb to use */ - u32 interrupt_crb; /* Crb to use */ + __le32 host_producer_crb; /* Crb to use */ + __le32 interrupt_crb; /* Crb to use */ } nx_cardrsp_cds_ring_t; typedef struct { - u32 host_ctx_state; /* Starting state */ - u16 context_id; /* Handle for context */ + __le32 host_ctx_state; /* Starting state */ + __le16 context_id; /* Handle for context */ u8 phys_port; /* Physical id of port */ u8 virt_port; /* Virtual/Logical id of port */ nx_cardrsp_cds_ring_t cds_ring; /* Card cds settings */ @@ -1202,9 +1185,9 @@ #define VPORT_MISS_MODE_ACCEPT_MULTI 2 /* accept unmatched multicast */ typedef struct { - u64 qhdr; - u64 req_hdr; - u64 words[6]; + __le64 qhdr; + __le64 req_hdr; + __le64 words[6]; } nx_nic_req_t; typedef struct { @@ -1220,7 +1203,7 @@ #define NETXEN_IS_MSI_FAMILY(adapter) \ ((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED)) -#define MSIX_ENTRIES_PER_ADAPTER 8 +#define MSIX_ENTRIES_PER_ADAPTER 1 #define NETXEN_MSIX_TBL_SPACE 8192 #define NETXEN_PCI_REG_MSIX_TBL 0x44 @@ -1486,8 +1469,6 @@ void netxen_initialize_adapter_ops(struct netxen_adapter *adapter); int netxen_init_firmware(struct netxen_adapter *adapter); -void netxen_tso_check(struct netxen_adapter *adapter, - struct cmd_desc_type0 *desc, struct sk_buff *skb); void netxen_nic_clear_stats(struct netxen_adapter *adapter); void netxen_watchdog_task(struct work_struct *work); void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, @@ -1496,6 +1477,7 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max); void netxen_p2_nic_set_multi(struct net_device *netdev); void netxen_p3_nic_set_multi(struct net_device *netdev); +void netxen_p3_free_mac_list(struct netxen_adapter *adapter); int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32); int netxen_config_intr_coalesce(struct netxen_adapter *adapter); --- linux-2.6.28.orig/drivers/net/tulip/tulip_core.c +++ linux-2.6.28/drivers/net/tulip/tulip_core.c @@ -228,8 +228,12 @@ { 0x1259, 0xa120, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { 0x11F6, 0x9881, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMPEX9881 }, { 0x8086, 0x0039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, I21145 }, + /* Ubuntu: On non-sparc, this seems to be handled better by the + * dmfe driver. */ +#ifdef __sparc__ { 0x1282, 0x9100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X }, { 0x1282, 0x9102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X }, +#endif { 0x1113, 0x1216, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { 0x1113, 0x1217, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 }, { 0x1113, 0x9511, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, @@ -392,6 +396,11 @@ goto media_picked; } } + if (tp->chip_id == PCI_ULI5261_ID || tp->chip_id == PCI_ULI5263_ID) { + for (i = tp->mtable->leafcount - 1; i >= 0; i--) + if (tulip_media_cap[tp->mtable->mleaf[i].media] & MediaIsMII) + goto media_picked; + } /* Start sensing first non-full-duplex media. */ for (i = tp->mtable->leafcount - 1; (tulip_media_cap[tp->mtable->mleaf[i].media] & MediaAlwaysFD) && i > 0; i--) --- linux-2.6.28.orig/drivers/net/tulip/tulip.h +++ linux-2.6.28/drivers/net/tulip/tulip.h @@ -38,7 +38,10 @@ #define TULIP_BAR 0 /* CBIO */ #endif - +#ifndef PCI_ULI5261_ID +#define PCI_ULI5261_ID 0x526110B9 /* ULi M5261 ID*/ +#define PCI_ULI5263_ID 0x526310B9 /* ULi M5263 ID*/ +#endif struct tulip_chip_table { char *chip_name; --- linux-2.6.28.orig/drivers/net/wireless/rtl8187_rtl8225.c +++ linux-2.6.28/drivers/net/wireless/rtl8187_rtl8225.c @@ -287,7 +287,10 @@ ofdm_power = priv->channels[channel - 1].hw_value >> 4; cck_power = min(cck_power, (u8)11); - ofdm_power = min(ofdm_power, (u8)35); + if (ofdm_power > (u8)15) + ofdm_power = 25; + else + ofdm_power += 10; rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1); @@ -540,7 +543,10 @@ cck_power += priv->txpwr_base & 0xF; cck_power = min(cck_power, (u8)35); - ofdm_power = min(ofdm_power, (u8)15); + if (ofdm_power > (u8)15) + ofdm_power = 25; + else + ofdm_power += 10; ofdm_power += priv->txpwr_base >> 4; ofdm_power = min(ofdm_power, (u8)35); --- linux-2.6.28.orig/drivers/net/wireless/ipw2100.h +++ linux-2.6.28/drivers/net/wireless/ipw2100.h @@ -591,6 +591,10 @@ int user_requested_scan; + /* Track time in suspend */ + unsigned long suspend_at; + unsigned long suspend_time; + u32 interrupts; int tx_interrupts; int rx_interrupts; --- linux-2.6.28.orig/drivers/net/wireless/ipw2100.c +++ linux-2.6.28/drivers/net/wireless/ipw2100.c @@ -1690,7 +1690,13 @@ u32 lock; u32 ord_len = sizeof(lock); - /* Quite if manually disabled. */ + /* Age scan list entries found before suspend */ + if (priv->suspend_time) { + ieee80211_networks_age(priv->ieee, priv->suspend_time); + priv->suspend_time = 0; + } + + /* Quiet if manually disabled. */ if (priv->status & STATUS_RF_KILL_SW) { IPW_DEBUG_INFO("%s: Radio is disabled by Manual Disable " "switch\n", priv->net_dev->name); @@ -6417,6 +6423,8 @@ pci_disable_device(pci_dev); pci_set_power_state(pci_dev, PCI_D3hot); + priv->suspend_at = get_seconds(); + mutex_unlock(&priv->action_mutex); return 0; @@ -6460,6 +6468,8 @@ * the queue of needed */ netif_device_attach(dev); + priv->suspend_time = get_seconds() - priv->suspend_at; + /* Bring the device back up */ if (!(priv->status & STATUS_RF_KILL_SW)) ipw2100_up(priv, 0); --- linux-2.6.28.orig/drivers/net/wireless/ipw2200.h +++ linux-2.6.28/drivers/net/wireless/ipw2200.h @@ -244,6 +244,7 @@ #define HOST_NOTIFICATION_S36_MEASUREMENT_REFUSED 31 #define HOST_NOTIFICATION_STATUS_BEACON_MISSING 1 +#define IPW_MB_SCAN_CANCEL_THRESHOLD 3 #define IPW_MB_ROAMING_THRESHOLD_MIN 1 #define IPW_MB_ROAMING_THRESHOLD_DEFAULT 8 #define IPW_MB_ROAMING_THRESHOLD_MAX 30 @@ -1344,6 +1345,10 @@ s8 tx_power; + /* Track time in suspend */ + unsigned long suspend_at; + unsigned long suspend_time; + #ifdef CONFIG_PM u32 pm_state[16]; #endif --- linux-2.6.28.orig/drivers/net/wireless/ipw2200.c +++ linux-2.6.28/drivers/net/wireless/ipw2200.c @@ -87,9 +87,9 @@ static int mode = 0; static u32 ipw_debug_level; -static int associate = 1; +static int associate; static int auto_create = 1; -static int led = 0; +static int led = 1; static int disable = 0; static int bt_coexist = 0; static int hwcrypto = 0; @@ -4347,7 +4347,8 @@ return; } - if (priv->status & STATUS_SCANNING) { + if (priv->status & STATUS_SCANNING && + missed_count > IPW_MB_SCAN_CANCEL_THRESHOLD) { /* Stop scan to keep fw from getting * stuck (only if we aren't roaming -- * otherwise we'll never scan more than 2 or 3 @@ -6277,6 +6278,20 @@ } } +static int ipw_passive_dwell_time(struct ipw_priv *priv) +{ + /* staying on passive channels longer than the DTIM interval during a + * scan, while associated, causes the firmware to cancel the scan + * without notification. Hence, don't stay on passive channels longer + * than the beacon interval. + */ + if (priv->status & STATUS_ASSOCIATED + && priv->assoc_network->beacon_interval > 10) + return priv->assoc_network->beacon_interval - 10; + else + return 120; +} + static int ipw_request_scan_helper(struct ipw_priv *priv, int type, int direct) { struct ipw_scan_request_ext scan; @@ -6320,16 +6335,16 @@ scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee)); if (type == IW_SCAN_TYPE_PASSIVE) { - IPW_DEBUG_WX("use passive scanning\n"); - scan_type = IPW_SCAN_PASSIVE_FULL_DWELL_SCAN; + IPW_DEBUG_WX("use passive scanning\n"); + scan_type = IPW_SCAN_PASSIVE_FULL_DWELL_SCAN; scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = - cpu_to_le16(120); + cpu_to_le16(ipw_passive_dwell_time(priv)); ipw_add_scan_channels(priv, &scan, scan_type); goto send_request; } /* Use active scan by default. */ - if (priv->config & CFG_SPEED_SCAN) + if (priv->config & CFG_SPEED_SCAN) scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = cpu_to_le16(30); else @@ -6339,7 +6354,8 @@ scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] = cpu_to_le16(20); - scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120); + scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = + cpu_to_le16(ipw_passive_dwell_time(priv)); scan.dwell_time[IPW_SCAN_ACTIVE_DIRECT_SCAN] = cpu_to_le16(20); #ifdef CONFIG_IPW2200_MONITOR @@ -11246,6 +11262,12 @@ { int rc, i, j; + /* Age scan list entries found before suspend */ + if (priv->suspend_time) { + ieee80211_networks_age(priv->ieee, priv->suspend_time); + priv->suspend_time = 0; + } + if (priv->status & STATUS_EXIT_PENDING) return -EIO; @@ -11846,6 +11868,8 @@ pci_disable_device(pdev); pci_set_power_state(pdev, pci_choose_state(pdev, state)); + priv->suspend_at = get_seconds(); + return 0; } @@ -11881,6 +11905,8 @@ * the queue of needed */ netif_device_attach(dev); + priv->suspend_time = get_seconds() - priv->suspend_at; + /* Bring the device back up */ queue_work(priv->workqueue, &priv->up); @@ -11950,7 +11976,7 @@ MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)"); module_param(led, int, 0444); -MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)"); +MODULE_PARM_DESC(led, "enable led control on some systems (default 1 on)"); module_param(debug, int, 0444); MODULE_PARM_DESC(debug, "debug output mask"); --- linux-2.6.28.orig/drivers/net/wireless/orinoco.c +++ linux-2.6.28/drivers/net/wireless/orinoco.c @@ -4938,32 +4938,29 @@ struct orinoco_private *priv = netdev_priv(dev); u8 *buf; unsigned long flags; - int err = 0; if ((wrqu->data.length > MAX_WPA_IE_LEN) || (wrqu->data.length && (extra == NULL))) return -EINVAL; - if (orinoco_lock(priv, &flags) != 0) - return -EBUSY; - if (wrqu->data.length) { buf = kmalloc(wrqu->data.length, GFP_KERNEL); - if (buf == NULL) { - err = -ENOMEM; - goto out; - } + if (buf == NULL) + return -ENOMEM; memcpy(buf, extra, wrqu->data.length); - kfree(priv->wpa_ie); - priv->wpa_ie = buf; - priv->wpa_ie_len = wrqu->data.length; - } else { - kfree(priv->wpa_ie); - priv->wpa_ie = NULL; - priv->wpa_ie_len = 0; + } else + buf = NULL; + + if (orinoco_lock(priv, &flags) != 0) { + kfree(buf); + return -EBUSY; } + kfree(priv->wpa_ie); + priv->wpa_ie = buf; + priv->wpa_ie_len = wrqu->data.length; + if (priv->wpa_ie) { /* Looks like wl_lkm wants to check the auth alg, and * somehow pass it to the firmware. @@ -4972,9 +4969,8 @@ */ } -out: orinoco_unlock(priv, &flags); - return err; + return 0; } static int orinoco_ioctl_get_genie(struct net_device *dev, --- linux-2.6.28.orig/drivers/net/wireless/rtl8187_dev.c +++ linux-2.6.28/drivers/net/wireless/rtl8187_dev.c @@ -40,6 +40,10 @@ {USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B}, {USB_DEVICE(0x0bda, 0x8197), .driver_info = DEVICE_RTL8187B}, {USB_DEVICE(0x0bda, 0x8198), .driver_info = DEVICE_RTL8187B}, + /* Surecom */ + {USB_DEVICE(0x0769, 0x11F2), .driver_info = DEVICE_RTL8187}, + /* Logitech */ + {USB_DEVICE(0x0789, 0x010C), .driver_info = DEVICE_RTL8187}, /* Netgear */ {USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187}, {USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187}, @@ -49,8 +53,16 @@ /* Sitecom */ {USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187}, {USB_DEVICE(0x0df6, 0x0028), .driver_info = DEVICE_RTL8187B}, + /* Sphairon Access Systems GmbH */ + {USB_DEVICE(0x114B, 0x0150), .driver_info = DEVICE_RTL8187}, + /* Dick Smith Electronics */ + {USB_DEVICE(0x1371, 0x9401), .driver_info = DEVICE_RTL8187}, /* Abocom */ {USB_DEVICE(0x13d1, 0xabe6), .driver_info = DEVICE_RTL8187}, + /* Qcom */ + {USB_DEVICE(0x18E8, 0x6232), .driver_info = DEVICE_RTL8187}, + /* AirLive */ + {USB_DEVICE(0x1b75, 0x8187), .driver_info = DEVICE_RTL8187}, {} }; @@ -263,6 +275,7 @@ usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, ep), buf, skb->len, rtl8187_tx_cb, skb); + urb->transfer_flags |= URB_ZERO_PACKET; rc = usb_submit_urb(urb, GFP_ATOMIC); if (rc < 0) { usb_free_urb(urb); --- linux-2.6.28.orig/drivers/net/wireless/orinoco_cs.c +++ linux-2.6.28/drivers/net/wireless/orinoco_cs.c @@ -11,6 +11,7 @@ */ #define DRIVER_NAME "orinoco_cs" +#define OVERLAP_DRIVER_NAME "orinoco_cs_overlap" #define PFX DRIVER_NAME ": " #include @@ -417,67 +418,94 @@ " (David Gibson , " "Pavel Roskin , et al)"; -static struct pcmcia_device_id orinoco_cs_ids[] = { +/* + * PCMCIA IDs that are also defined in hostap_cs. + */ +static struct pcmcia_device_id orinoco_overlap_cs_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), /* SonicWALL Long Range Wireless Card */ PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), /* Sohoware NCP110, Philips 802.11b */ - PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), /* AnyPoint(TM) Wireless II PC Card */ PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), /* 3Com AirConnect PCI 777A */ PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000), /* PROXIM RangeLAN-DS/LAN PC CARD */ PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), /* Compaq WL100 11 Mbps Wireless Adapter */ + PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), /* Samsung SWL2000-N 11Mb/s WLAN Card */ + PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), /* Linksys WPC11 Version 2.5 */ + PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), /* Linksys WPC11 Version 3 */ + PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), /* Compaq HNW-100 11 Mbps Wireless Adapter */ + PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */ + PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */ + PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), /* Safeway 802.11b, ZCOMAX AirRunner/XI-300 */ + PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), /* D-Link DCF660, Sandisk Connect SDWCFB-000 */ + + PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18), + PCMCIA_DEVICE_PROD_ID12("Intersil", "PRISM 2_5 PCMCIA ADAPTER", 0x4b801a17, 0x6345a0bf), + + PCMCIA_DEVICE_PROD_ID123("Intersil", "PRISM Freedom PCMCIA Adapter", "ISL37100P", 0x4b801a17, 0xf222ec2d, 0x630d52b2), + + PCMCIA_DEVICE_PROD_ID12("Addtron", "AWP-100 Wireless PCMCIA", 0xe6ec52ce, 0x08649af2), + PCMCIA_DEVICE_PROD_ID12("D", "Link DRC-650 11Mbps WLAN Card", 0x71b18589, 0xf144e3ac), + PCMCIA_DEVICE_PROD_ID12("D", "Link DWL-650 11Mbps WLAN Card", 0x71b18589, 0xb6f1b0ab), + PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0), + PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2532W-B EliteConnect Wireless Adapter", 0xc4f8b18b, 0x196bd757), + PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a), + PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-PCM-L11G", 0x2decece3, 0xf57ca4b3), + PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18), + PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", 0x54f7c49c, 0x15a75e5b), + PCMCIA_DEVICE_PROD_ID12("INTERSIL", "I-GATE 11M PC Card / PC Card plus", 0x74c5e40d, 0x8304ff77), + PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", 0x0733cc81, 0x0c52f395), + PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee), + PCMCIA_DEVICE_PROD_ID12("Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", 0x5cd01705, 0x4271660f), + + PCMCIA_DEVICE_NULL, +}; + +static struct pcmcia_driver orinoco_overlap_driver = { + .owner = THIS_MODULE, + .drv = { + .name = OVERLAP_DRIVER_NAME, + }, + .probe = orinoco_cs_probe, + .remove = orinoco_cs_detach, + .id_table = orinoco_overlap_cs_ids, + .suspend = orinoco_cs_suspend, + .resume = orinoco_cs_resume, +}; + +static struct pcmcia_device_id orinoco_cs_ids[] = { + PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), /* AnyPoint(TM) Wireless II PC Card */ PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), /* Lucent Orinoco and old Intersil */ PCMCIA_DEVICE_MANF_CARD(0x016b, 0x0001), /* Ericsson WLAN Card C11 */ PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a), /* Nortel Networks eMobility 802.11 Wireless Adapter */ PCMCIA_DEVICE_MANF_CARD(0x01ff, 0x0008), /* Intermec MobileLAN 11Mbps 802.11b WLAN Card */ - PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), /* Samsung SWL2000-N 11Mb/s WLAN Card */ PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002), /* AirWay 802.11 Adapter (PCMCIA) */ PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001), /* ARtem Onair */ PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305), /* Buffalo WLI-PCM-S11 */ - PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), /* Linksys WPC11 Version 2.5 */ - PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), /* Linksys WPC11 Version 3 */ - PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), /* Compaq HNW-100 11 Mbps Wireless Adapter */ PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), /* Linksys WCF12 Wireless CompactFlash Card */ - PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */ PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002), /* SpeedStream SS1021 Wireless Adapter */ PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x3021), /* SpeedStream Wireless Adapter */ PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001), /* PLANEX RoadLannerWave GW-NS11H */ - PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */ PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), /* Adaptec Ultra Wireless ANW-8030 */ PCMCIA_DEVICE_MANF_CARD(0xc001, 0x0008), /* CONTEC FLEXSCAN/FX-DDS110-PCC */ PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), /* Conceptronic CON11Cpro, EMTAC A2424i */ - PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), /* Safeway 802.11b, ZCOMAX AirRunner/XI-300 */ - PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), /* D-Link DCF660, Sandisk Connect SDWCFB-000 */ + PCMCIA_DEVICE_PROD_ID12(" ", "IEEE 802.11 Wireless LAN/PC Card", 0x3b6e20c8, 0xefccafe9), PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3), PCMCIA_DEVICE_PROD_ID12("ACTIONTEC", "PRISM Wireless LAN PC Card", 0x393089da, 0xa71e69d5), - PCMCIA_DEVICE_PROD_ID12("Addtron", "AWP-100 Wireless PCMCIA", 0xe6ec52ce, 0x08649af2), PCMCIA_DEVICE_PROD_ID123("AIRVAST", "IEEE 802.11b Wireless PCMCIA Card", "HFA3863", 0xea569531, 0x4bcb9645, 0x355cb092), - PCMCIA_DEVICE_PROD_ID12("Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", 0x5cd01705, 0x4271660f), PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11b_PC_CARD_25", 0x78fc06ee, 0xdb9aa842), PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11B_CF_CARD_25", 0x78fc06ee, 0x45a50c1e), PCMCIA_DEVICE_PROD_ID12("Avaya Communication", "Avaya Wireless PC Card", 0xd8a43b78, 0x0d341169), PCMCIA_DEVICE_PROD_ID12("BENQ", "AWL100 PCMCIA ADAPTER", 0x35dadc74, 0x01f7fedb), - PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-PCM-L11G", 0x2decece3, 0xf57ca4b3), - PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18), PCMCIA_DEVICE_PROD_ID12("Cabletron", "RoamAbout 802.11 DS", 0x32d445f5, 0xedeffd90), - PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", 0x54f7c49c, 0x15a75e5b), PCMCIA_DEVICE_PROD_ID123("corega", "WL PCCL-11", "ISL37300P", 0x0a21501a, 0x59868926, 0xc9049a39), PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584), PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9), PCMCIA_DEVICE_PROD_ID12("corega_K.K.", "Wireless_LAN_PCCB-11", 0x29e33311, 0xee7a27ae), - PCMCIA_DEVICE_PROD_ID12("D", "Link DRC-650 11Mbps WLAN Card", 0x71b18589, 0xf144e3ac), - PCMCIA_DEVICE_PROD_ID12("D", "Link DWL-650 11Mbps WLAN Card", 0x71b18589, 0xb6f1b0ab), PCMCIA_DEVICE_PROD_ID12("D-Link Corporation", "D-Link DWL-650H 11Mbps WLAN Adapter", 0xef544d24, 0xcd8ea916), PCMCIA_DEVICE_PROD_ID12("Digital Data Communications", "WPC-0100", 0xfdd73470, 0xe0b6f146), PCMCIA_DEVICE_PROD_ID12("ELSA", "AirLancer MC-11", 0x4507a33a, 0xef54f0e3), PCMCIA_DEVICE_PROD_ID12("HyperLink", "Wireless PC Card 11Mbps", 0x56cc3f1a, 0x0bcf220c), - PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0), PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless 2011 LAN PC Card", 0x816cc815, 0x07f58077), - PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18), - PCMCIA_DEVICE_PROD_ID12("INTERSIL", "I-GATE 11M PC Card / PC Card plus", 0x74c5e40d, 0x8304ff77), - PCMCIA_DEVICE_PROD_ID12("Intersil", "PRISM 2_5 PCMCIA ADAPTER", 0x4b801a17, 0x6345a0bf), - PCMCIA_DEVICE_PROD_ID123("Intersil", "PRISM Freedom PCMCIA Adapter", "ISL37100P", 0x4b801a17, 0xf222ec2d, 0x630d52b2), PCMCIA_DEVICE_PROD_ID12("LeArtery", "SYNCBYAIR 11Mbps Wireless LAN PC Card", 0x7e3b326a, 0x49893e92), - PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", 0x0733cc81, 0x0c52f395), PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/IEEE", 0x23eb9949, 0xc562e72a), PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11", 0x481e0094, 0x7360e410), PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11G", 0x481e0094, 0xf57ca4b3), @@ -494,11 +522,8 @@ PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PC CARD HARMONY 80211B", 0xc6536a5e, 0x090c3cd9), PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PCI CARD HARMONY 80211B", 0xc6536a5e, 0x9f494e26), PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "11Mbps WLAN Card", 0x43d74cb4, 0x579bd91b), - PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2532W-B EliteConnect Wireless Adapter", 0xc4f8b18b, 0x196bd757), - PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a), PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e), PCMCIA_DEVICE_PROD_ID123("The Linksys Group, Inc.", "Instant Wireless Network PC Card", "ISL37300P", 0xa5f472c2, 0x590eb502, 0xc9049a39), - PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee), PCMCIA_DEVICE_NULL, }; MODULE_DEVICE_TABLE(pcmcia, orinoco_cs_ids); @@ -515,18 +540,39 @@ .resume = orinoco_cs_resume, }; +static int orinoco_driver_registered = 0; +static int orinoco_overlap_driver_registered = 0; + static int __init init_orinoco_cs(void) { + int status; + printk(KERN_DEBUG "%s\n", version); - return pcmcia_register_driver(&orinoco_driver); + status = pcmcia_register_driver(&orinoco_driver); + if (status >= 0) + orinoco_driver_registered = 1; + + status = pcmcia_register_driver(&orinoco_overlap_driver); + if (status >= 0) + orinoco_overlap_driver_registered = 1; + + return status; } static void __exit exit_orinoco_cs(void) { - pcmcia_unregister_driver(&orinoco_driver); + if (orinoco_overlap_driver_registered) { + pcmcia_unregister_driver(&orinoco_overlap_driver); + orinoco_overlap_driver_registered = 0; + } + + if (orinoco_driver_registered) { + pcmcia_unregister_driver(&orinoco_driver); + orinoco_driver_registered = 0; + } } module_init(init_orinoco_cs); --- linux-2.6.28.orig/drivers/net/wireless/ath9k/recv.c +++ linux-2.6.28/drivers/net/wireless/ath9k/recv.c @@ -627,9 +627,8 @@ rfilt &= ~ATH9K_RX_FILTER_UCAST; } - if (((sc->sc_ah->ah_opmode == ATH9K_M_STA) && - (sc->rx_filter & FIF_BCN_PRBRESP_PROMISC)) || - (sc->sc_ah->ah_opmode == ATH9K_M_IBSS)) + if (sc->sc_ah->ah_opmode == ATH9K_M_STA || + sc->sc_ah->ah_opmode == ATH9K_M_IBSS) rfilt |= ATH9K_RX_FILTER_BEACON; /* If in HOSTAP mode, want to enable reception of PSPOLL frames --- linux-2.6.28.orig/drivers/net/wireless/ath9k/hw.c +++ linux-2.6.28/drivers/net/wireless/ath9k/hw.c @@ -706,7 +706,7 @@ AR_AN_TOP2_LOCALBIAS, AR_AN_TOP2_LOCALBIAS_S, pModal->local_bias); - DPRINTF(ah->ah_sc, ATH_DBG_ANY, "ForceXPAon: %d\n", + DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "ForceXPAon: %d\n", pModal->force_xpaon); REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG, pModal->force_xpaon); --- linux-2.6.28.orig/drivers/net/wireless/p54/p54usb.c +++ linux-2.6.28/drivers/net/wireless/p54/p54usb.c @@ -54,6 +54,7 @@ {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */ {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */ {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */ + {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */ @@ -61,7 +62,7 @@ {USB_DEVICE(0x0915, 0x2002)}, /* Cohiba Proto board */ {USB_DEVICE(0x0baf, 0x0118)}, /* U.S. Robotics U5 802.11g Adapter*/ {USB_DEVICE(0x0bf8, 0x1009)}, /* FUJITSU E-5400 USB D1700*/ - {USB_DEVICE(0x0cde, 0x0006)}, /* Medion MD40900 */ +// DUPE {USB_DEVICE(0x0cde, 0x0006)}, /* Medion MD40900 */ {USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */ {USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */ {USB_DEVICE(0x124a, 0x4025)}, /* IOGear GWU513 (GW3887IK chip) */ @@ -84,13 +85,13 @@ struct ieee80211_hw *dev = info->dev; struct p54u_priv *priv = dev->priv; + skb_unlink(skb, &priv->rx_queue); + if (unlikely(urb->status)) { - info->urb = NULL; - usb_free_urb(urb); + dev_kfree_skb_irq(skb); return; } - skb_unlink(skb, &priv->rx_queue); skb_put(skb, urb->actual_length); if (priv->hw_type == P54U_NET2280) @@ -103,7 +104,6 @@ if (p54_rx(dev, skb)) { skb = dev_alloc_skb(priv->common.rx_mtu + 32); if (unlikely(!skb)) { - usb_free_urb(urb); /* TODO check rx queue length and refill *somewhere* */ return; } @@ -113,7 +113,6 @@ info->dev = dev; urb->transfer_buffer = skb_tail_pointer(skb); urb->context = skb; - skb_queue_tail(&priv->rx_queue, skb); } else { if (priv->hw_type == P54U_NET2280) skb_push(skb, priv->common.tx_hdr_len); @@ -128,22 +127,23 @@ WARN_ON(1); urb->transfer_buffer = skb_tail_pointer(skb); } - - skb_queue_tail(&priv->rx_queue, skb); } - usb_submit_urb(urb, GFP_ATOMIC); + usb_anchor_urb(urb, &priv->submitted); + if (usb_submit_urb(urb, GFP_ATOMIC)) { + usb_unanchor_urb(urb); + dev_kfree_skb_irq(skb); + } else + skb_queue_tail(&priv->rx_queue, skb); } -static void p54u_tx_cb(struct urb *urb) -{ - usb_free_urb(urb); -} +static void p54u_tx_cb(struct urb *urb) { } -static void p54u_tx_free_cb(struct urb *urb) +static void p54u_free_urbs(struct ieee80211_hw *dev) { - kfree(urb->transfer_buffer); - usb_free_urb(urb); + struct p54u_priv *priv = dev->priv; + + usb_kill_anchored_urbs(&priv->submitted); } static int p54u_init_urbs(struct ieee80211_hw *dev) @@ -152,15 +152,18 @@ struct urb *entry; struct sk_buff *skb; struct p54u_rx_info *info; + int ret = 0; while (skb_queue_len(&priv->rx_queue) < 32) { skb = __dev_alloc_skb(priv->common.rx_mtu + 32, GFP_KERNEL); - if (!skb) - break; + if (!skb) { + ret = -ENOMEM; + goto err; + } entry = usb_alloc_urb(0, GFP_KERNEL); if (!entry) { - kfree_skb(skb); - break; + ret = -ENOMEM; + goto err; } usb_fill_bulk_urb(entry, priv->udev, usb_rcvbulkpipe(priv->udev, P54U_PIPE_DATA), @@ -170,26 +173,25 @@ info->urb = entry; info->dev = dev; skb_queue_tail(&priv->rx_queue, skb); - usb_submit_urb(entry, GFP_KERNEL); + + usb_anchor_urb(entry, &priv->submitted); + ret = usb_submit_urb(entry, GFP_KERNEL); + if (ret) { + skb_unlink(skb, &priv->rx_queue); + usb_unanchor_urb(entry); + goto err; + } + usb_free_urb(entry); + entry = NULL; } return 0; -} - -static void p54u_free_urbs(struct ieee80211_hw *dev) -{ - struct p54u_priv *priv = dev->priv; - struct p54u_rx_info *info; - struct sk_buff *skb; - - while ((skb = skb_dequeue(&priv->rx_queue))) { - info = (struct p54u_rx_info *) skb->cb; - if (!info->urb) - continue; - usb_kill_urb(info->urb); - kfree_skb(skb); - } +err: + usb_free_urb(entry); + kfree_skb(skb); + p54u_free_urbs(dev); + return ret; } static void p54u_tx_3887(struct ieee80211_hw *dev, struct p54_control_hdr *data, @@ -209,23 +211,38 @@ } usb_fill_bulk_urb(addr_urb, priv->udev, - usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), &data->req_id, - sizeof(data->req_id), p54u_tx_cb, dev); + usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), + &data->req_id, sizeof(data->req_id), p54u_tx_cb, + dev); usb_fill_bulk_urb(data_urb, priv->udev, - usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), data, len, - free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev); + usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), + data, len, p54u_tx_cb, dev); + addr_urb->transfer_flags |= URB_ZERO_PACKET; + data_urb->transfer_flags |= URB_ZERO_PACKET | + (free_on_tx ? URB_FREE_BUFFER : 0); + + usb_anchor_urb(addr_urb, &priv->submitted); + if (usb_submit_urb(addr_urb, GFP_ATOMIC)) { + usb_unanchor_urb(addr_urb); + goto out; + } - usb_submit_urb(addr_urb, GFP_ATOMIC); - usb_submit_urb(data_urb, GFP_ATOMIC); + usb_anchor_urb(data_urb, &priv->submitted); + if (usb_submit_urb(data_urb, GFP_ATOMIC)) + usb_unanchor_urb(data_urb); + +out: + usb_free_urb(addr_urb); + usb_free_urb(data_urb); } -static __le32 p54u_lm87_chksum(const u32 *data, size_t length) +static __le32 p54u_lm87_chksum(const __le32 *data, size_t length) { u32 chk = 0; length >>= 2; while (length--) { - chk ^= *data++; + chk ^= le32_to_cpu(*data++); chk = (chk >> 5) ^ (chk << 3); } @@ -244,15 +261,20 @@ if (!data_urb) return; - hdr->chksum = p54u_lm87_chksum((u32 *)data, len); + hdr->chksum = p54u_lm87_chksum((__le32 *) data, len); hdr->device_addr = data->req_id; usb_fill_bulk_urb(data_urb, priv->udev, - usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), hdr, - len + sizeof(*hdr), free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, - dev); + usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), hdr, + len + sizeof(*hdr), p54u_tx_cb, dev); + data_urb->transfer_flags |= URB_ZERO_PACKET | + (free_on_tx ? URB_FREE_BUFFER : 0); + + usb_anchor_urb(data_urb, &priv->submitted); + if (usb_submit_urb(data_urb, GFP_ATOMIC)) + usb_unanchor_urb(data_urb); - usb_submit_urb(data_urb, GFP_ATOMIC); + usb_free_urb(data_urb); } static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *data, @@ -291,14 +313,30 @@ hdr->len = cpu_to_le16(len); usb_fill_bulk_urb(int_urb, priv->udev, - usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg), - p54u_tx_free_cb, dev); - usb_submit_urb(int_urb, GFP_ATOMIC); + usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), + reg, sizeof(*reg), p54u_tx_cb, dev); + int_urb->transfer_flags |= URB_ZERO_PACKET | URB_FREE_BUFFER; + usb_anchor_urb(int_urb, &priv->submitted); + if (usb_submit_urb(int_urb, GFP_ATOMIC)) { + usb_unanchor_urb(int_urb); + goto out; + } usb_fill_bulk_urb(data_urb, priv->udev, - usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), hdr, len + sizeof(*hdr), - free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev); - usb_submit_urb(data_urb, GFP_ATOMIC); + usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), hdr, + len + sizeof(*hdr), p54u_tx_cb, dev); + data_urb->transfer_flags |= URB_ZERO_PACKET | + (free_on_tx ? URB_FREE_BUFFER : 0); + + usb_anchor_urb(int_urb, &priv->submitted); + if (usb_submit_urb(data_urb, GFP_ATOMIC)) { + usb_unanchor_urb(data_urb); + goto out; + } + +out: + usb_free_urb(int_urb); + usb_free_urb(data_urb); } static int p54u_write(struct p54u_priv *priv, @@ -799,6 +837,7 @@ SET_IEEE80211_DEV(dev, &intf->dev); usb_set_intfdata(intf, dev); priv->udev = udev; + init_usb_anchor(&priv->submitted); usb_get_dev(udev); --- linux-2.6.28.orig/drivers/net/wireless/p54/p54common.c +++ linux-2.6.28/drivers/net/wireless/p54/p54common.c @@ -741,17 +741,19 @@ int p54_read_eeprom(struct ieee80211_hw *dev) { struct p54_common *priv = dev->priv; - struct p54_control_hdr *hdr = NULL; + struct p54_control_hdr *hdr = NULL, *org_hdr; struct p54_eeprom_lm86 *eeprom_hdr; size_t eeprom_size = 0x2020, offset = 0, blocksize; int ret = -ENOMEM; void *eeprom = NULL; - hdr = (struct p54_control_hdr *)kzalloc(sizeof(*hdr) + - sizeof(*eeprom_hdr) + EEPROM_READBACK_LEN, GFP_KERNEL); - if (!hdr) + org_hdr = kzalloc(priv->tx_hdr_len + sizeof(*hdr) + + sizeof(*eeprom_hdr) + EEPROM_READBACK_LEN, + GFP_KERNEL); + if (!org_hdr) goto free; + hdr = (void *) org_hdr + priv->tx_hdr_len; priv->eeprom = kzalloc(EEPROM_READBACK_LEN, GFP_KERNEL); if (!priv->eeprom) goto free; @@ -790,7 +792,7 @@ free: kfree(priv->eeprom); priv->eeprom = NULL; - kfree(hdr); + kfree(org_hdr); kfree(eeprom); return ret; --- linux-2.6.28.orig/drivers/net/wireless/p54/p54usb.h +++ linux-2.6.28/drivers/net/wireless/p54/p54usb.h @@ -133,6 +133,7 @@ spinlock_t lock; struct sk_buff_head rx_queue; + struct usb_anchor submitted; }; #endif /* P54USB_H */ --- linux-2.6.28.orig/drivers/net/wireless/iwlwifi/iwl-agn.c +++ linux-2.6.28/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1334,16 +1334,6 @@ priv->cfg->ops->lib->rx_handler_setup(priv); } -/* - * this should be called while priv->lock is locked -*/ -static void __iwl_rx_replenish(struct iwl_priv *priv) -{ - iwl_rx_allocate(priv); - iwl_rx_queue_restock(priv); -} - - /** * iwl_rx_handle - Main entry function for receiving responses from uCode * @@ -1451,7 +1441,7 @@ count++; if (count >= 8) { priv->rxq.read = i; - __iwl_rx_replenish(priv); + iwl_rx_queue_restock(priv); count = 0; } } @@ -1655,11 +1645,17 @@ hw_rf_kill ? "disable radio":"enable radio"); /* driver only loads ucode once setting the interface up. - * the driver as well won't allow loading if RFKILL is set - * therefore no need to restart the driver from this handler + * the driver allows loading the ucode even if the radio + * is killed. Hence update the killswitch state here. The + * rfkill handler will care about restarting if needed. */ - if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) - clear_bit(STATUS_RF_KILL_HW, &priv->status); + if (!test_bit(STATUS_ALIVE, &priv->status)) { + if (hw_rf_kill) + set_bit(STATUS_RF_KILL_HW, &priv->status); + else + clear_bit(STATUS_RF_KILL_HW, &priv->status); + queue_work(priv->workqueue, &priv->rf_kill); + } handled |= CSR_INT_BIT_RF_KILL; } @@ -2360,7 +2356,8 @@ IWL_DEBUG(IWL_DL_RF_KILL, "HW and/or SW RF Kill no longer active, restarting " "device\n"); - if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) + if (!test_bit(STATUS_EXIT_PENDING, &priv->status) && + test_bit(STATUS_ALIVE, &priv->status)) queue_work(priv->workqueue, &priv->restart); } else { /* make sure mac80211 stop sending Tx frame */ @@ -2582,31 +2579,9 @@ { struct iwl_priv *priv = hw->priv; int ret; - u16 pci_cmd; IWL_DEBUG_MAC80211("enter\n"); - if (pci_enable_device(priv->pci_dev)) { - IWL_ERROR("Fail to pci_enable_device\n"); - return -ENODEV; - } - pci_restore_state(priv->pci_dev); - pci_enable_msi(priv->pci_dev); - - /* enable interrupts if needed: hw bug w/a */ - pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd); - if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { - pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; - pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd); - } - - ret = request_irq(priv->pci_dev->irq, iwl4965_isr, IRQF_SHARED, - DRV_NAME, priv); - if (ret) { - IWL_ERROR("Error allocating IRQ %d\n", priv->pci_dev->irq); - goto out_disable_msi; - } - /* we should be verifying the device is ready to be opened */ mutex_lock(&priv->mutex); @@ -2619,7 +2594,7 @@ if (ret) { IWL_ERROR("Could not read microcode: %d\n", ret); mutex_unlock(&priv->mutex); - goto out_release_irq; + return ret; } } @@ -2630,7 +2605,7 @@ iwl_rfkill_set_hw_state(priv); if (ret) - goto out_release_irq; + return ret; if (iwl_is_rfkill(priv)) goto out; @@ -2649,8 +2624,7 @@ if (!test_bit(STATUS_READY, &priv->status)) { IWL_ERROR("START_ALIVE timeout after %dms.\n", jiffies_to_msecs(UCODE_READY_TIMEOUT)); - ret = -ETIMEDOUT; - goto out_release_irq; + return -ETIMEDOUT; } } @@ -2658,15 +2632,6 @@ priv->is_open = 1; IWL_DEBUG_MAC80211("leave\n"); return 0; - -out_release_irq: - free_irq(priv->pci_dev->irq, priv); -out_disable_msi: - pci_disable_msi(priv->pci_dev); - pci_disable_device(priv->pci_dev); - priv->is_open = 0; - IWL_DEBUG_MAC80211("leave - failed\n"); - return ret; } static void iwl4965_mac_stop(struct ieee80211_hw *hw) @@ -2694,10 +2659,10 @@ iwl4965_down(priv); flush_workqueue(priv->workqueue); - free_irq(priv->pci_dev->irq, priv); - pci_disable_msi(priv->pci_dev); - pci_save_state(priv->pci_dev); - pci_disable_device(priv->pci_dev); + + /* enable interrupts again in order to receive rfkill changes */ + iwl_write32(priv, CSR_INT, 0xFFFFFFFF); + iwl4965_enable_interrupts(priv); IWL_DEBUG_MAC80211("leave\n"); } @@ -4176,6 +4141,8 @@ struct ieee80211_hw *hw; struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); unsigned long flags; + u16 pci_cmd; + DECLARE_MAC_BUF(mac); /************************ @@ -4321,7 +4288,14 @@ spin_lock_irqsave(&priv->lock, flags); iwl4965_disable_interrupts(priv); spin_unlock_irqrestore(&priv->lock, flags); - + pci_enable_msi(priv->pci_dev); + + err = request_irq(priv->pci_dev->irq, iwl4965_isr, IRQF_SHARED, + DRV_NAME, priv); + if (err) { + IWL_ERROR("Error allocating IRQ %d\n", priv->pci_dev->irq); + goto out_disable_msi; + } err = sysfs_create_group(&pdev->dev.kobj, &iwl4965_attribute_group); if (err) { IWL_ERROR("failed to create sysfs device attributes\n"); @@ -4332,15 +4306,18 @@ iwl_setup_deferred_work(priv); iwl_setup_rx_handlers(priv); - /******************** - * 9. Conclude - ********************/ - pci_save_state(pdev); - pci_disable_device(pdev); - /********************************** - * 10. Setup and register mac80211 + * 9. Setup and register mac80211 **********************************/ + + /* enable interrupts if needed: hw bug w/a */ + pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd); + if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { + pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; + pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd); + } + + iwl4965_enable_interrupts(priv); err = iwl_setup_mac(priv); if (err) @@ -4350,15 +4327,28 @@ if (err) IWL_ERROR("failed to create debugfs files\n"); + + /* If platform's RF_KILL switch is NOT set to KILL */ + if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) + clear_bit(STATUS_RF_KILL_HW, &priv->status); + else + set_bit(STATUS_RF_KILL_HW, &priv->status); + err = iwl_rfkill_init(priv); if (err) IWL_ERROR("Unable to initialize RFKILL system. " "Ignoring error: %d\n", err); + else + iwl_rfkill_set_hw_state(priv); + iwl_power_initialize(priv); return 0; out_remove_sysfs: sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group); + out_disable_msi: + pci_disable_msi(priv->pci_dev); + pci_disable_device(priv->pci_dev); out_uninit_drv: iwl_uninit_drv(priv); out_free_eeprom: @@ -4430,6 +4420,8 @@ destroy_workqueue(priv->workqueue); priv->workqueue = NULL; + free_irq(priv->pci_dev->irq, priv); + pci_disable_msi(priv->pci_dev); pci_iounmap(pdev, priv->hw_base); pci_release_regions(pdev); pci_disable_device(pdev); @@ -4455,6 +4447,8 @@ priv->is_open = 1; } + pci_save_state(pdev); + pci_disable_device(pdev); pci_set_power_state(pdev, PCI_D3hot); return 0; @@ -4465,6 +4459,9 @@ struct iwl_priv *priv = pci_get_drvdata(pdev); pci_set_power_state(pdev, PCI_D0); + pci_enable_device(pdev); + pci_restore_state(pdev); + iwl4965_enable_interrupts(priv); if (priv->is_open) iwl4965_mac_start(priv->hw); --- linux-2.6.28.orig/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ linux-2.6.28/drivers/net/wireless/iwlwifi/iwl-3945-rs.c @@ -647,12 +647,16 @@ s8 scale_action = 0; unsigned long flags; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - u16 fc, rate_mask; + u16 fc; + u16 rate_mask = 0; struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_r; DECLARE_MAC_BUF(mac); IWL_DEBUG_RATE("enter\n"); + if (sta) + rate_mask = sta->supp_rates[sband->band]; + /* Send management frames and broadcast/multicast data using lowest * rate. */ fc = le16_to_cpu(hdr->frame_control); @@ -660,11 +664,13 @@ is_multicast_ether_addr(hdr->addr1) || !sta || !priv_sta) { IWL_DEBUG_RATE("leave: No STA priv data to update!\n"); - sel->rate_idx = rate_lowest_index(sband, sta); + if (!rate_mask) + sel->rate_idx = rate_lowest_index(sband, NULL); + else + sel->rate_idx = rate_lowest_index(sband, sta); return; } - rate_mask = sta->supp_rates[sband->band]; index = min(rs_sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT - 1); if (sband->band == IEEE80211_BAND_5GHZ) --- linux-2.6.28.orig/drivers/net/wireless/iwlwifi/iwl-core.c +++ linux-2.6.28/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1465,6 +1465,16 @@ return 0; } + /* when driver is up while rfkill is on, it wont receive + * any CARD_STATE_NOTIFICATION notifications so we have to + * restart it in here + */ + if (priv->is_open && !test_bit(STATUS_ALIVE, &priv->status)) { + clear_bit(STATUS_RF_KILL_SW, &priv->status); + if (!iwl_is_rfkill(priv)) + queue_work(priv->workqueue, &priv->up); + } + /* If the driver is already loaded, it will receive * CARD_STATE_NOTIFICATION notifications and the handler will * call restart to reload the driver. --- linux-2.6.28.orig/drivers/net/wireless/iwlwifi/iwl-3945.h +++ linux-2.6.28/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -898,7 +898,8 @@ struct delayed_work thermal_periodic; struct delayed_work gather_stats; struct delayed_work scan_check; - + struct delayed_work rfkill_poll; + #define IWL_DEFAULT_TX_POWER 0x0F s8 user_txpower_limit; s8 max_channel_txpower_limit; --- linux-2.6.28.orig/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ linux-2.6.28/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -6029,7 +6029,8 @@ IWL_DEBUG(IWL_DL_INFO | IWL_DL_RF_KILL, "HW and/or SW RF Kill no longer active, restarting " "device\n"); - if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) + if (!test_bit(STATUS_EXIT_PENDING, &priv->status) && + test_bit(STATUS_ALIVE, &priv->status)) queue_work(priv->workqueue, &priv->restart); } else { @@ -6046,6 +6047,26 @@ iwl3945_rfkill_set_hw_state(priv); } + +static void iwl3945_rfkill_poll(struct work_struct *data) +{ + struct iwl3945_priv *priv = + container_of(data, struct iwl3945_priv, rfkill_poll.work); + unsigned long status = priv->status; + + if (iwl3945_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) + clear_bit(STATUS_RF_KILL_HW, &priv->status); + else + set_bit(STATUS_RF_KILL_HW, &priv->status); + + if (test_bit(STATUS_RF_KILL_HW, &status) != test_bit(STATUS_RF_KILL_HW, &priv->status)) + queue_work(priv->workqueue, &priv->rf_kill); + + queue_delayed_work(priv->workqueue, &priv->rfkill_poll, + round_jiffies_relative(2 * HZ)); + +} + static void iwl3945_bg_set_monitor(struct work_struct *work) { struct iwl3945_priv *priv = container_of(work, @@ -6260,6 +6281,11 @@ goto done; } + if (scan->channel_count == 0) { + IWL_DEBUG_SCAN("channel count %d\n", scan->channel_count); + goto done; + } + cmd.len += le16_to_cpu(scan->tx_cmd.len) + scan->channel_count * sizeof(struct iwl3945_scan_channel); cmd.data = scan; @@ -6478,20 +6504,6 @@ IWL_DEBUG_MAC80211("enter\n"); - if (pci_enable_device(priv->pci_dev)) { - IWL_ERROR("Fail to pci_enable_device\n"); - return -ENODEV; - } - pci_restore_state(priv->pci_dev); - pci_enable_msi(priv->pci_dev); - - ret = request_irq(priv->pci_dev->irq, iwl3945_isr, IRQF_SHARED, - DRV_NAME, priv); - if (ret) { - IWL_ERROR("Error allocating IRQ %d\n", priv->pci_dev->irq); - goto out_disable_msi; - } - /* we should be verifying the device is ready to be opened */ mutex_lock(&priv->mutex); @@ -6535,16 +6547,15 @@ goto out_release_irq; } } + /* ucode is running and will send rfkill notifications, + * no need to poll the killswitch state anymore */ + cancel_delayed_work(&priv->rfkill_poll); priv->is_open = 1; IWL_DEBUG_MAC80211("leave\n"); return 0; out_release_irq: - free_irq(priv->pci_dev->irq, priv); -out_disable_msi: - pci_disable_msi(priv->pci_dev); - pci_disable_device(priv->pci_dev); priv->is_open = 0; IWL_DEBUG_MAC80211("leave - failed\n"); return ret; @@ -6575,10 +6586,10 @@ iwl3945_down(priv); flush_workqueue(priv->workqueue); - free_irq(priv->pci_dev->irq, priv); - pci_disable_msi(priv->pci_dev); - pci_save_state(priv->pci_dev); - pci_disable_device(priv->pci_dev); + + /* start polling the killswitch state again */ + queue_delayed_work(priv->workqueue, &priv->rfkill_poll, + round_jiffies_relative(2 * HZ)); IWL_DEBUG_MAC80211("leave\n"); } @@ -7814,7 +7825,7 @@ INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); INIT_DELAYED_WORK(&priv->scan_check, iwl3945_bg_scan_check); - + INIT_DELAYED_WORK(&priv->rfkill_poll, iwl3945_rfkill_poll); iwl3945_hw_setup_deferred_work(priv); tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) @@ -8031,6 +8042,15 @@ iwl3945_disable_interrupts(priv); spin_unlock_irqrestore(&priv->lock, flags); + pci_enable_msi(priv->pci_dev); + + err = request_irq(priv->pci_dev->irq, iwl3945_isr, IRQF_SHARED, + DRV_NAME, priv); + if (err) { + IWL_ERROR("Error allocating IRQ %d\n", priv->pci_dev->irq); + goto out_disable_msi; + } + err = sysfs_create_group(&pdev->dev.kobj, &iwl3945_attribute_group); if (err) { IWL_ERROR("failed to create sysfs device attributes\n"); @@ -8080,14 +8100,16 @@ priv->hw->conf.beacon_int = 100; priv->mac80211_registered = 1; - pci_save_state(pdev); - pci_disable_device(pdev); err = iwl3945_rfkill_init(priv); if (err) IWL_ERROR("Unable to initialize RFKILL system. " "Ignoring error: %d\n", err); + /* Start monitoring the killswitch */ + queue_delayed_work(priv->workqueue, &priv->rfkill_poll, + 2 * HZ); + return 0; out_free_geos: @@ -8098,10 +8120,13 @@ sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); out_release_irq: + free_irq(priv->pci_dev->irq, priv); destroy_workqueue(priv->workqueue); priv->workqueue = NULL; iwl3945_unset_hw_setting(priv); - + out_disable_msi: + pci_disable_msi(priv->pci_dev); + out_iounmap: pci_iounmap(pdev, priv->hw_base); out_pci_release_regions: @@ -8141,6 +8166,7 @@ sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); iwl3945_rfkill_unregister(priv); + cancel_delayed_work(&priv->rfkill_poll); iwl3945_dealloc_ucode_pci(priv); if (priv->rxq.bd) @@ -8162,6 +8188,10 @@ destroy_workqueue(priv->workqueue); priv->workqueue = NULL; + free_irq(pdev->irq, priv); + pci_disable_msi(pdev); + + pci_iounmap(pdev, priv->hw_base); pci_release_regions(pdev); pci_disable_device(pdev); @@ -8188,6 +8218,8 @@ priv->is_open = 1; } + pci_save_state(pdev); + pci_disable_device(pdev); pci_set_power_state(pdev, PCI_D3hot); return 0; @@ -8198,6 +8230,8 @@ struct iwl3945_priv *priv = pci_get_drvdata(pdev); pci_set_power_state(pdev, PCI_D0); + pci_enable_device(pdev); + pci_restore_state(pdev); if (priv->is_open) iwl3945_mac_start(priv->hw); --- linux-2.6.28.orig/drivers/net/wireless/iwlwifi/iwl-io.h +++ linux-2.6.28/drivers/net/wireless/iwlwifi/iwl-io.h @@ -95,7 +95,7 @@ do { if ((_iwl_read32(priv, addr) & mask) == (bits & mask)) return i; - mdelay(10); + udelay(10); i += 10; } while (i < timeout); @@ -277,7 +277,7 @@ do { if ((_iwl_read_direct32(priv, addr) & mask) == mask) return i; - mdelay(10); + udelay(10); i += 10; } while (i < timeout); --- linux-2.6.28.orig/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ linux-2.6.28/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -951,7 +951,8 @@ } /* See if there's a better rate or modulation mode to try. */ - rs_rate_scale_perform(priv, hdr, sta, lq_sta); + if (sta && sta->supp_rates[sband->band]) + rs_rate_scale_perform(priv, hdr, sta, lq_sta); out: return; } @@ -2114,15 +2115,22 @@ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; __le16 fc; struct iwl_lq_sta *lq_sta; + u64 mask_bit = 0; IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n"); + if (sta) + mask_bit = sta->supp_rates[sband->band]; + /* Send management frames and broadcast/multicast data using lowest * rate. */ fc = hdr->frame_control; if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) || !sta || !priv_sta) { - sel->rate_idx = rate_lowest_index(sband, sta); + if (!mask_bit) + sel->rate_idx = rate_lowest_index(sband, NULL); + else + sel->rate_idx = rate_lowest_index(sband, sta); return; } --- linux-2.6.28.orig/drivers/net/wireless/iwlwifi/iwl-tx.c +++ linux-2.6.28/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -97,13 +97,13 @@ (IWL_GET_BITS(bd->pa[index], tb2_addr_hi20) << 16), IWL_GET_BITS(bd->pa[index], tb2_len), - PCI_DMA_TODEVICE); + PCI_DMA_BIDIRECTIONAL); else if (i > 0) pci_unmap_single(dev, le32_to_cpu(bd->pa[index].tb1_addr), IWL_GET_BITS(bd->pa[index], tb1_len), - PCI_DMA_TODEVICE); + PCI_DMA_BIDIRECTIONAL); /* Free SKB, if any, for this chunk */ if (txq->txb[txq->q.read_ptr].skb[i]) { @@ -567,7 +567,7 @@ FH_TCSR_CHNL_TX_CONFIG_REG(txq_id), 0x0); iwl_poll_direct_bit(priv, FH_TSSR_TX_STATUS_REG, FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE - (txq_id), 200); + (txq_id), 1000); } iwl_release_nic_access(priv); spin_unlock_irqrestore(&priv->lock, flags); @@ -913,7 +913,7 @@ /* Physical address of this Tx command's header (not MAC header!), * within command buffer array. */ txcmd_phys = pci_map_single(priv->pci_dev, out_cmd, - sizeof(struct iwl_cmd), PCI_DMA_TODEVICE); + sizeof(struct iwl_cmd), PCI_DMA_BIDIRECTIONAL); txcmd_phys += offsetof(struct iwl_cmd, hdr); /* Add buffer containing Tx command and MAC(!) header to TFD's @@ -1062,7 +1062,7 @@ len = (idx == TFD_CMD_SLOTS) ? IWL_MAX_SCAN_SIZE : sizeof(struct iwl_cmd); phys_addr = pci_map_single(priv->pci_dev, out_cmd, len, - PCI_DMA_TODEVICE); + PCI_DMA_BIDIRECTIONAL); phys_addr += offsetof(struct iwl_cmd, hdr); iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size); @@ -1174,7 +1174,7 @@ } pci_unmap_single(priv->pci_dev, dma_addr, buf_len, - PCI_DMA_TODEVICE); + PCI_DMA_BIDIRECTIONAL); nfreed++; } } --- linux-2.6.28.orig/drivers/net/wireless/iwlwifi/iwl-3945-io.h +++ linux-2.6.28/drivers/net/wireless/iwlwifi/iwl-3945-io.h @@ -93,7 +93,7 @@ do { if ((_iwl3945_read32(priv, addr) & mask) == (bits & mask)) return i; - mdelay(10); + udelay(10); i += 10; } while (i < timeout); @@ -276,7 +276,7 @@ do { if ((_iwl3945_read_direct32(priv, addr) & mask) == mask) return i; - mdelay(10); + udelay(10); i += 10; } while (i < timeout); --- linux-2.6.28.orig/drivers/net/wireless/iwlwifi/iwl-rx.c +++ linux-2.6.28/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -245,25 +245,31 @@ struct list_head *element; struct iwl_rx_mem_buffer *rxb; unsigned long flags; - spin_lock_irqsave(&rxq->lock, flags); - while (!list_empty(&rxq->rx_used)) { + + while (1) { + spin_lock_irqsave(&rxq->lock, flags); + + if (list_empty(&rxq->rx_used)) { + spin_unlock_irqrestore(&rxq->lock, flags); + return; + } element = rxq->rx_used.next; rxb = list_entry(element, struct iwl_rx_mem_buffer, list); + list_del(element); + + spin_unlock_irqrestore(&rxq->lock, flags); /* Alloc a new receive buffer */ rxb->skb = alloc_skb(priv->hw_params.rx_buf_size + 256, - __GFP_NOWARN | GFP_ATOMIC); + GFP_KERNEL); if (!rxb->skb) { - if (net_ratelimit()) - printk(KERN_CRIT DRV_NAME - ": Can not allocate SKB buffers\n"); + printk(KERN_CRIT DRV_NAME + "Can not allocate SKB buffers\n"); /* We don't reschedule replenish work here -- we will * call the restock method and if it still needs * more buffers it will schedule replenish */ break; } - priv->alloc_rxb_skb++; - list_del(element); /* Get physical address of RB/SKB */ rxb->real_dma_addr = pci_map_single( @@ -277,12 +283,15 @@ rxb->aligned_dma_addr = ALIGN(rxb->real_dma_addr, 256); skb_reserve(rxb->skb, rxb->aligned_dma_addr - rxb->real_dma_addr); + spin_lock_irqsave(&rxq->lock, flags); + list_add_tail(&rxb->list, &rxq->rx_free); rxq->free_count++; + priv->alloc_rxb_skb++; + + spin_unlock_irqrestore(&rxq->lock, flags); } - spin_unlock_irqrestore(&rxq->lock, flags); } -EXPORT_SYMBOL(iwl_rx_allocate); void iwl_rx_replenish(struct iwl_priv *priv) { --- linux-2.6.28.orig/drivers/net/wireless/hostap/hostap_main.c +++ linux-2.6.28/drivers/net/wireless/hostap/hostap_main.c @@ -1094,6 +1094,7 @@ (u8 *) &val, 2); memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); wireless_send_event(local->dev, SIOCGIWAP, &wrqu, NULL); + wireless_send_event(local->ddev, SIOCGIWAP, &wrqu, NULL); return ret; } --- linux-2.6.28.orig/drivers/net/wireless/hostap/hostap_hw.c +++ linux-2.6.28/drivers/net/wireless/hostap/hostap_hw.c @@ -69,7 +69,7 @@ module_param_string(essid, essid, sizeof(essid), 0444); MODULE_PARM_DESC(essid, "Host AP's ESSID"); -static int iw_mode[MAX_PARM_DEVICES] = { IW_MODE_MASTER, DEF_INTS }; +static int iw_mode[MAX_PARM_DEVICES] = { IW_MODE_INFRA, DEF_INTS }; module_param_array(iw_mode, int, NULL, 0444); MODULE_PARM_DESC(iw_mode, "Initial operation mode"); @@ -3447,6 +3447,7 @@ memset(&wrqu, 0, sizeof(wrqu)); wrqu.ap_addr.sa_family = ARPHRD_ETHER; wireless_send_event(local->dev, SIOCGIWAP, &wrqu, NULL); + wireless_send_event(local->ddev, SIOCGIWAP, &wrqu, NULL); /* Disable hardware and firmware */ prism2_hw_shutdown(dev, 0); --- linux-2.6.28.orig/drivers/net/wireless/hostap/hostap_info.c +++ linux-2.6.28/drivers/net/wireless/hostap/hostap_info.c @@ -238,6 +238,7 @@ wrqu.data.length = 0; wrqu.data.flags = 0; wireless_send_event(local->dev, SIOCGIWSCAN, &wrqu, NULL); + wireless_send_event(local->ddev, SIOCGIWSCAN, &wrqu, NULL); /* Allow SIOCGIWSCAN handling to occur since we have received * scanning result */ @@ -451,8 +452,10 @@ * frames and can confuse wpa_supplicant about the current association * status. */ - if (connected || local->prev_linkstatus_connected) + if (connected || local->prev_linkstatus_connected) { wireless_send_event(local->dev, SIOCGIWAP, &wrqu, NULL); + wireless_send_event(local->ddev, SIOCGIWAP, &wrqu, NULL); + } local->prev_linkstatus_connected = connected; } --- linux-2.6.28.orig/drivers/net/wireless/rt2x00/rt73usb.c +++ linux-2.6.28/drivers/net/wireless/rt2x00/rt73usb.c @@ -2434,6 +2434,7 @@ /* Linksys */ { USB_DEVICE(0x13b1, 0x0020), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x13b1, 0x0023), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x13b1, 0x0028), USB_DEVICE_DATA(&rt73usb_ops) }, /* MSI */ { USB_DEVICE(0x0db0, 0x6877), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0db0, 0x6874), USB_DEVICE_DATA(&rt73usb_ops) }, --- linux-2.6.28.orig/drivers/net/wireless/ath5k/phy.c +++ linux-2.6.28/drivers/net/wireless/ath5k/phy.c @@ -2195,9 +2195,7 @@ return ret; } - ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq); - if (ret) - return ret; + ath5k_hw_noise_floor_calibration(ah, channel->center_freq); /* * Re-enable RX/TX and beacons --- linux-2.6.28.orig/drivers/net/wireless/ath5k/base.c +++ linux-2.6.28/drivers/net/wireless/ath5k/base.c @@ -2157,7 +2157,8 @@ if (sc->opmode == NL80211_IFTYPE_STATION) { sc->imask |= AR5K_INT_BMISS; - } else if (sc->opmode == NL80211_IFTYPE_ADHOC) { + } else if (sc->opmode == NL80211_IFTYPE_ADHOC || + sc->opmode == NL80211_IFTYPE_MESH_POINT) { /* * In IBSS mode we use a self-linked tx descriptor and let the * hardware send the beacons automatically. We have to load it @@ -2748,6 +2749,7 @@ switch (conf->type) { case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_MESH_POINT: case NL80211_IFTYPE_MONITOR: sc->opmode = conf->type; break; @@ -2819,7 +2821,8 @@ } if (conf->changed & IEEE80211_IFCC_BEACON && - vif->type == NL80211_IFTYPE_ADHOC) { + (vif->type == NL80211_IFTYPE_ADHOC || + vif->type == NL80211_IFTYPE_MESH_POINT)) { struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); if (!beacon) { ret = -ENOMEM; @@ -2951,6 +2954,9 @@ sc->opmode == NL80211_IFTYPE_ADHOC) { rfilt |= AR5K_RX_FILTER_BEACON; } + if (sc->opmode == NL80211_IFTYPE_MESH_POINT) + rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON | + AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM; /* Set filters */ ath5k_hw_set_rx_filter(ah,rfilt); --- linux-2.6.28.orig/drivers/net/wireless/ath5k/reset.c +++ linux-2.6.28/drivers/net/wireless/ath5k/reset.c @@ -842,9 +842,7 @@ * * XXX: Find an interval that's OK for all cards... */ - ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq); - if (ret) - return ret; + ath5k_hw_noise_floor_calibration(ah, channel->center_freq); /* * Reset queues and start beacon timers at the end of the reset routine --- linux-2.6.28.orig/drivers/net/wireless/zd1211rw/zd_rf.c +++ linux-2.6.28/drivers/net/wireless/zd1211rw/zd_rf.c @@ -86,6 +86,7 @@ case AL7230B_RF: r = zd_rf_init_al7230b(rf); break; + case MAXIM_NEW_RF: case UW2453_RF: r = zd_rf_init_uw2453(rf); break; --- linux-2.6.28.orig/drivers/net/wireless/zd1211rw/zd_usb.c +++ linux-2.6.28/drivers/net/wireless/zd1211rw/zd_usb.c @@ -37,6 +37,7 @@ static struct usb_device_id usb_ids[] = { /* ZD1211 */ { USB_DEVICE(0x0ace, 0x1211), .driver_info = DEVICE_ZD1211 }, + { USB_DEVICE(0x0ace, 0xa211), .driver_info = DEVICE_ZD1211 }, { USB_DEVICE(0x07b8, 0x6001), .driver_info = DEVICE_ZD1211 }, { USB_DEVICE(0x126f, 0xa006), .driver_info = DEVICE_ZD1211 }, { USB_DEVICE(0x6891, 0xa727), .driver_info = DEVICE_ZD1211 }, @@ -84,6 +85,7 @@ { USB_DEVICE(0x0586, 0x340a), .driver_info = DEVICE_ZD1211B }, { USB_DEVICE(0x0471, 0x1237), .driver_info = DEVICE_ZD1211B }, { USB_DEVICE(0x07fa, 0x1196), .driver_info = DEVICE_ZD1211B }, + { USB_DEVICE(0x0df6, 0x0036), .driver_info = DEVICE_ZD1211B }, /* "Driverless" devices that need ejecting */ { USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER }, { USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER }, --- linux-2.6.28.orig/drivers/firewire/fw-sbp2.c +++ linux-2.6.28/drivers/firewire/fw-sbp2.c @@ -357,15 +357,17 @@ .model = ~0, .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS, }, - /* - * There are iPods (2nd gen, 3rd gen) with model_id == 0, but - * these iPods do not feature the read_capacity bug according - * to one report. Read_capacity behaviour as well as model_id - * could change due to Apple-supplied firmware updates though. + * iPod 2nd generation: needs 128k max transfer size workaround + * iPod 3rd generation: needs fix capacity workaround */ - - /* iPod 4th generation. */ { + { + .firmware_revision = 0x0a2700, + .model = 0x000000, + .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS | + SBP2_WORKAROUND_FIX_CAPACITY, + }, + /* iPod 4th generation */ { .firmware_revision = 0x0a2700, .model = 0x000021, .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, @@ -1282,6 +1284,19 @@ .id_table = sbp2_id_table, }; +static void sbp2_unmap_scatterlist(struct device *card_device, + struct sbp2_command_orb *orb) +{ + if (scsi_sg_count(orb->cmd)) + dma_unmap_sg(card_device, scsi_sglist(orb->cmd), + scsi_sg_count(orb->cmd), + orb->cmd->sc_data_direction); + + if (orb->request.misc & cpu_to_be32(COMMAND_ORB_PAGE_TABLE_PRESENT)) + dma_unmap_single(card_device, orb->page_table_bus, + sizeof(orb->page_table), DMA_TO_DEVICE); +} + static unsigned int sbp2_status_to_sense_data(u8 *sbp2_status, u8 *sense_data) { @@ -1361,15 +1376,7 @@ dma_unmap_single(device->card->device, orb->base.request_bus, sizeof(orb->request), DMA_TO_DEVICE); - - if (scsi_sg_count(orb->cmd) > 0) - dma_unmap_sg(device->card->device, scsi_sglist(orb->cmd), - scsi_sg_count(orb->cmd), - orb->cmd->sc_data_direction); - - if (orb->page_table_bus != 0) - dma_unmap_single(device->card->device, orb->page_table_bus, - sizeof(orb->page_table), DMA_TO_DEVICE); + sbp2_unmap_scatterlist(device->card->device, orb); orb->cmd->result = result; orb->done(orb->cmd); @@ -1500,8 +1507,10 @@ orb->base.request_bus = dma_map_single(device->card->device, &orb->request, sizeof(orb->request), DMA_TO_DEVICE); - if (dma_mapping_error(device->card->device, orb->base.request_bus)) + if (dma_mapping_error(device->card->device, orb->base.request_bus)) { + sbp2_unmap_scatterlist(device->card->device, orb); goto out; + } sbp2_send_orb(&orb->base, lu, lu->tgt->node_id, generation, lu->command_block_agent_address + SBP2_ORB_POINTER); --- linux-2.6.28.orig/drivers/firewire/fw-ohci.c +++ linux-2.6.28/drivers/firewire/fw-ohci.c @@ -226,7 +226,7 @@ #define CONTEXT_DEAD 0x0800 #define CONTEXT_ACTIVE 0x0400 -#define OHCI1394_MAX_AT_REQ_RETRIES 0x2 +#define OHCI1394_MAX_AT_REQ_RETRIES 0xf #define OHCI1394_MAX_AT_RESP_RETRIES 0x2 #define OHCI1394_MAX_PHYS_RESP_RETRIES 0x8 --- linux-2.6.28.orig/drivers/char/cyclades.c +++ linux-2.6.28/drivers/char/cyclades.c @@ -646,6 +646,7 @@ #include #include #include +#include #include #include @@ -5422,3 +5423,4 @@ MODULE_LICENSE("GPL"); MODULE_VERSION(CY_VERSION); +MODULE_ALIAS_CHARDEV_MAJOR(CYCLADES_MAJOR); --- linux-2.6.28.orig/drivers/char/toshiba.c +++ linux-2.6.28/drivers/char/toshiba.c @@ -77,6 +77,7 @@ MODULE_AUTHOR("Jonathan Buzzard "); MODULE_DESCRIPTION("Toshiba laptop SMM driver"); MODULE_SUPPORTED_DEVICE("toshiba"); +MODULE_ALIAS_MISCDEV(TOSH_MINOR_DEV); static int tosh_fn; module_param_named(fn, tosh_fn, int, 0); --- linux-2.6.28.orig/drivers/char/riscom8.c +++ linux-2.6.28/drivers/char/riscom8.c @@ -48,6 +48,7 @@ #include #include #include +#include #include @@ -1622,6 +1623,7 @@ module_param(iobase3, int, 0); MODULE_LICENSE("GPL"); +MODULE_ALIAS_CHARDEV_MAJOR(RISCOM8_NORMAL_MAJOR); #endif /* MODULE */ /* --- linux-2.6.28.orig/drivers/char/vt_ioctl.c +++ linux-2.6.28/drivers/char/vt_ioctl.c @@ -35,6 +35,8 @@ #include #include +#define max_font_size 65536 + char vt_dont_switch; extern struct tty_driver *console_driver; @@ -1254,6 +1256,7 @@ static void complete_change_console(struct vc_data *vc) { unsigned char old_vc_mode; + struct vc_data *oldvc = vc_cons[fg_console].d; last_console = fg_console; @@ -1262,9 +1265,31 @@ * KD_TEXT mode or vice versa, which means we need to blank or * unblank the screen later. */ - old_vc_mode = vc_cons[fg_console].d->vc_mode; + old_vc_mode = oldvc->vc_mode; + +#if defined(CONFIG_VGA_CONSOLE) + if (old_vc_mode == KD_TEXT && oldvc->vc_sw == &vga_con && + oldvc->vc_sw->con_font_get) { + if (!oldvc->vc_font.data) + oldvc->vc_font.data = kmalloc(max_font_size, + GFP_KERNEL); + lock_kernel(); + oldvc->vc_sw->con_font_get(oldvc, &oldvc->vc_font); + unlock_kernel(); + } +#endif switch_screen(vc); +#if defined(CONFIG_VGA_CONSOLE) + if (vc->vc_mode == KD_TEXT && vc->vc_sw == &vga_con && + vc->vc_sw->con_font_set) { + if (vc->vc_font.data) { + lock_kernel(); + vc->vc_sw->con_font_set(vc, &vc->vc_font, 0); + unlock_kernel(); + } + } +#endif /* * This can't appear below a successful kill_pid(). If it did, * then the *blank_screen operation could occur while X, having --- linux-2.6.28.orig/drivers/char/applicom.c +++ linux-2.6.28/drivers/char/applicom.c @@ -75,6 +75,7 @@ MODULE_AUTHOR("David Woodhouse & Applicom International"); MODULE_DESCRIPTION("Driver for Applicom Profibus card"); MODULE_LICENSE("GPL"); +MODULE_ALIAS_MISCDEV(AC_MINOR); MODULE_SUPPORTED_DEVICE("ac"); --- linux-2.6.28.orig/drivers/char/selection.c +++ linux-2.6.28/drivers/char/selection.c @@ -268,7 +268,7 @@ /* Allocate a new buffer before freeing the old one ... */ multiplier = use_unicode ? 3 : 1; /* chars can take up to 3 bytes */ - bp = kmalloc((sel_end-sel_start)/2*multiplier+1, GFP_KERNEL); + bp = kmalloc(((sel_end-sel_start)/2+1)*multiplier, GFP_KERNEL); if (!bp) { printk(KERN_WARNING "selection: kmalloc() failed\n"); clear_selection(); --- linux-2.6.28.orig/drivers/char/keyboard.c +++ linux-2.6.28/drivers/char/keyboard.c @@ -1068,6 +1068,8 @@ int code; switch (keycode) { + case KEY_RESERVED: + break; case KEY_PAUSE: put_queue(vc, 0xe1); put_queue(vc, 0x1d | up_flag); @@ -1127,6 +1129,8 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char up_flag) { + if (keycode == KEY_RESERVED) + return 0; if (keycode > 127) return -1; --- linux-2.6.28.orig/drivers/char/specialix.c +++ linux-2.6.28/drivers/char/specialix.c @@ -2365,3 +2365,4 @@ module_exit(specialix_exit_module); MODULE_LICENSE("GPL"); +MODULE_ALIAS_CHARDEV_MAJOR(SPECIALIX_NORMAL_MAJOR); --- linux-2.6.28.orig/drivers/char/mwave/mwavedd.c +++ linux-2.6.28/drivers/char/mwave/mwavedd.c @@ -67,6 +67,7 @@ MODULE_DESCRIPTION("3780i Advanced Communications Processor (Mwave) driver"); MODULE_AUTHOR("Mike Sullivan and Paul Schroeder"); MODULE_LICENSE("GPL"); +MODULE_ALIAS_MISCDEV(MWAVE_MINOR); /* * These parameters support the setting of MWave resources. Note that no --- linux-2.6.28.orig/drivers/char/agp/intel-agp.c +++ linux-2.6.28/drivers/char/agp/intel-agp.c @@ -40,6 +40,8 @@ #define PCI_DEVICE_ID_INTEL_Q45_IG 0x2E12 #define PCI_DEVICE_ID_INTEL_G45_HB 0x2E20 #define PCI_DEVICE_ID_INTEL_G45_IG 0x2E22 +#define PCI_DEVICE_ID_INTEL_G41_HB 0x2E30 +#define PCI_DEVICE_ID_INTEL_G41_IG 0x2E32 /* cover 915 and 945 variants */ #define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \ @@ -63,7 +65,8 @@ #define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_E_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB || \ - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB) + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB || \ + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G41_HB) extern int agp_memory_reserved; @@ -630,13 +633,15 @@ break; } } - if (gtt_entries > 0) + if (gtt_entries > 0) { dev_info(&agp_bridge->dev->dev, "detected %dK %s memory\n", gtt_entries / KB(1), local ? "local" : "stolen"); - else + gtt_entries /= KB(4); + } else { dev_info(&agp_bridge->dev->dev, "no pre-allocated video memory detected\n"); - gtt_entries /= KB(4); + gtt_entries = 0; + } intel_private.gtt_entries = gtt_entries; } @@ -1196,6 +1201,7 @@ case PCI_DEVICE_ID_INTEL_IGD_E_HB: case PCI_DEVICE_ID_INTEL_Q45_HB: case PCI_DEVICE_ID_INTEL_G45_HB: + case PCI_DEVICE_ID_INTEL_G41_HB: *gtt_offset = *gtt_size = MB(2); break; default: @@ -2156,13 +2162,15 @@ { PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, 0, "Q33", NULL, &intel_g33_driver }, { PCI_DEVICE_ID_INTEL_GM45_HB, PCI_DEVICE_ID_INTEL_GM45_IG, 0, - "Mobile Intel? GM45 Express", NULL, &intel_i965_driver }, + "Mobile Intel® GM45 Express", NULL, &intel_i965_driver }, { PCI_DEVICE_ID_INTEL_IGD_E_HB, PCI_DEVICE_ID_INTEL_IGD_E_IG, 0, "Intel Integrated Graphics Device", NULL, &intel_i965_driver }, { PCI_DEVICE_ID_INTEL_Q45_HB, PCI_DEVICE_ID_INTEL_Q45_IG, 0, "Q45/Q43", NULL, &intel_i965_driver }, { PCI_DEVICE_ID_INTEL_G45_HB, PCI_DEVICE_ID_INTEL_G45_IG, 0, "G45/G43", NULL, &intel_i965_driver }, + { PCI_DEVICE_ID_INTEL_G41_HB, PCI_DEVICE_ID_INTEL_G41_IG, 0, + "G41", NULL, &intel_i965_driver }, { 0, 0, 0, NULL, NULL, NULL } }; @@ -2360,6 +2368,7 @@ ID(PCI_DEVICE_ID_INTEL_IGD_E_HB), ID(PCI_DEVICE_ID_INTEL_Q45_HB), ID(PCI_DEVICE_ID_INTEL_G45_HB), + ID(PCI_DEVICE_ID_INTEL_G41_HB), { } }; --- linux-2.6.28.orig/drivers/char/hw_random/core.c +++ linux-2.6.28/drivers/char/hw_random/core.c @@ -347,3 +347,4 @@ MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS_MISCDEV(RNG_MISCDEV_MINOR); --- linux-2.6.28.orig/drivers/regulator/reg-mc13892.c +++ linux-2.6.28/drivers/regulator/reg-mc13892.c @@ -0,0 +1,1940 @@ +/* + * Copyright 2008-2009 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Convenience conversion. + * Here atm, maybe there is somewhere better for this. + */ +#define mV_to_uV(mV) (mV * 1000) +#define uV_to_mV(uV) (uV / 1000) +#define V_to_uV(V) (mV_to_uV(V * 1000)) +#define uV_to_V(uV) (uV_to_mV(uV) / 1000) + +enum { + VDIG_1_05V = 0, + VDIG_1_25V, + VDIG_1_65V, + VDIG_1_80V, +} regulator_voltage_vdig; + +enum { + VPLL_1_05V = 0, + VPLL_1_25V, + VPLL_1_65V, + VPLL_1_80V, +} regulator_voltage_vpll; + +enum { + VGEN1_1_2V = 0, + VGEN1_1_5V, + VGEN1_2_775V, + VGEN1_3_15V, +} regulator_voltage_vgen1; + +enum { + VGEN2_1_2V = 0, + VGEN2_1_5V, + VGEN2_1_6V, + VGEN2_1_8V, + VGEN2_2_7V, + VGEN2_2_8V, + VGEN2_3_0V, + VGEN2_3_15V, +} regulator_voltage_vgen2; + +enum { + VGEN3_1_8V = 0, + VGEN3_2_9V, +} regulator_voltage_vgen3; + +enum { + VSD_1_8V = 0, + VSD_2_0V, + VSD_2_6V, + VSD_2_7V, + VSD_2_8V, + VSD_2_9V, + VSD_3_0V, + VSD_3_15V, +} regulator_voltage_vsd; + +enum { + VCAM_2_5V, + VCAM_2_6V, + VCAM_2_75V, + VCAM_3_0V, +} regulator_voltage_vcam; + +enum { + VAUDIO_2_3V, + VAUDIO_2_5V, + VAUDIO_2_775V, + VAUDIO_3V, +} regulator_voltage_vaudio; + +enum { + VUSB2_2_4V, + VUSB2_2_6V, + VUSB2_2_7V, + VUSB2_2_775V, +} regulator_voltage_vusb2; + +enum { + VVIDEO_2_7V, + VVIDEO_2_775V, + VVIDEO_2_5V, + VVIDEO_2_6V, +} regulator_voltage_vvideo; + +#define VAUDIO_LSH 4 +#define VAUDIO_WID 2 +#define VAUDIO_EN_LSH 15 +#define VAUDIO_EN_WID 1 +#define VAUDIO_EN_ENABLE 1 +#define VAUDIO_EN_DISABLE 0 + +#define VUSB2_LSH 11 +#define VUSB2_WID 2 +#define VUSB2_EN_LSH 18 +#define VUSB2_EN_WID 1 +#define VUSB2_EN_ENABLE 1 +#define VUSB2_EN_DISABLE 0 + +#define VVIDEO_LSH 2 +#define VVIDEO_WID 2 +#define VVIDEO_EN_LSH 12 +#define VVIDEO_EN_WID 1 +#define VVIDEO_EN_ENABLE 1 +#define VVIDEO_EN_DISABLE 0 + +#define SWBST_EN_LSH 20 +#define SWBST_EN_WID 1 +#define SWBST_EN_ENABLE 1 +#define SWBST_EN_DISABLE 0 + +#define VIOHI_EN_LSH 3 +#define VIOHI_EN_WID 1 +#define VIOHI_EN_ENABLE 1 +#define VIOHI_EN_DISABLE 0 + +#define VDIG_LSH 4 +#define VDIG_WID 2 +#define VDIG_EN_LSH 9 +#define VDIG_EN_WID 1 +#define VDIG_EN_ENABLE 1 +#define VDIG_EN_DISABLE 0 + +#define VPLL_LSH 9 +#define VPLL_WID 2 +#define VPLL_EN_LSH 15 +#define VPLL_EN_WID 1 +#define VPLL_EN_ENABLE 1 +#define VPLL_EN_DISABLE 0 + +#define VGEN1_LSH 0 +#define VGEN1_WID 2 +#define VGEN1_EN_LSH 0 +#define VGEN1_EN_WID 1 +#define VGEN1_EN_ENABLE 1 +#define VGEN1_EN_DISABLE 0 + +#define VGEN2_LSH 6 +#define VGEN2_WID 3 +#define VGEN2_EN_LSH 12 +#define VGEN2_EN_WID 1 +#define VGEN2_EN_ENABLE 1 +#define VGEN2_EN_DISABLE 0 + +#define VGEN3_LSH 14 +#define VGEN3_WID 1 +#define VGEN3_EN_LSH 0 +#define VGEN3_EN_WID 1 +#define VGEN3_EN_ENABLE 1 +#define VGEN3_EN_DISABLE 0 + +#define VSD_LSH 6 +#define VSD_WID 3 +#define VSD_EN_LSH 18 +#define VSD_EN_WID 1 +#define VSD_EN_ENABLE 1 +#define VSD_EN_DISABLE 0 + +#define VCAM_LSH 16 +#define VCAM_WID 2 +#define VCAM_EN_LSH 6 +#define VCAM_EN_WID 1 +#define VCAM_EN_ENABLE 1 +#define VCAM_EN_DISABLE 0 +#define VCAM_CONFIG_LSH 9 +#define VCAM_CONFIG_WID 1 +#define VCAM_CONFIG_EXT 1 +#define VCAM_CONFIG_INT 0 + +#define SW1_LSH 0 +#define SW1_WID 5 +#define SW1_DVS_LSH 5 +#define SW1_DVS_WID 5 +#define SW1_STDBY_LSH 10 +#define SW1_STDBY_WID 5 + +#define SW2_LSH 0 +#define SW2_WID 5 +#define SW2_DVS_LSH 5 +#define SW2_DVS_WID 5 +#define SW2_STDBY_LSH 10 +#define SW2_STDBY_WID 5 + +#define SW3_LSH 0 +#define SW3_WID 5 +#define SW3_STDBY_LSH 10 +#define SW3_STDBY_WID 5 + +#define SW4_LSH 0 +#define SW4_WID 5 +#define SW4_STDBY_LSH 10 +#define SW4_STDBY_WID 5 + +#define VUSB_EN_LSH 3 +#define VUSB_EN_WID 1 +#define VUSB_EN_ENABLE 1 +#define VUSB_EN_DISABLE 0 + +#define GPO1_EN_LSH 6 +#define GPO1_EN_WID 1 +#define GPO1_EN_ENABLE 1 +#define GPO1_EN_DISABLE 0 + +#define GPO2_EN_LSH 8 +#define GPO2_EN_WID 1 +#define GPO2_EN_ENABLE 1 +#define GPO2_EN_DISABLE 0 + +#define GPO3_EN_LSH 10 +#define GPO3_EN_WID 1 +#define GPO3_EN_ENABLE 1 +#define GPO3_EN_DISABLE 0 + +#define GPO4_EN_LSH 12 +#define GPO4_EN_WID 1 +#define GPO4_EN_ENABLE 1 +#define GPO4_EN_DISABLE 0 + +#define GPO4_ADIN_LSH 21 +#define GPO4_ADIN_WID 1 +#define GPO4_ADIN_ENABLE 1 +#define GPO4_ADIN_DISABLE 0 + +#define PWGT1SPI_EN_LSH 15 +#define PWGT1SPI_EN_WID 1 +#define PWGT1SPI_EN_ENABLE 0 +#define PWGT1SPI_EN_DISABLE 1 + +#define PWGT2SPI_EN_LSH 16 +#define PWGT2SPI_EN_WID 1 +#define PWGT2SPI_EN_ENABLE 0 +#define PWGT2SPI_EN_DISABLE 1 + +#define SWXHI_LSH 23 +#define SWXHI_WID 1 +#define SWXHI_ON 1 +#define SWXHI_OFF 0 + +static int mc13892_get_sw_hi_bit(int sw) +{ + unsigned int register_val = 0; + unsigned int reg = 0; + + switch (sw) { + case MC13892_SW1: + reg = REG_SW_0; + break; + case MC13892_SW2: + reg = REG_SW_1; + break; + case MC13892_SW3: + reg = REG_SW_2; + break; + case MC13892_SW4: + reg = REG_SW_3; + break; + default: + return -EINVAL; + } + + CHECK_ERROR(pmic_read_reg(reg, ®ister_val, PMIC_ALL_BITS)); + return (register_val & 0x800000) >> SWXHI_LSH; +} + +static int mc13892_get_voltage_value(int *hi, int mV) +{ + int voltage; + + if (mV < 600) + mV = 600; + if (mV > 1850) + mV = 1850; + + if (mV > 1375) + *hi = 1; + if (mV < 1100) + *hi = 0; + + if (*hi == 0) + voltage = (mV - 600) / 25; + else + voltage = (mV - 1100) / 25; + + return voltage; +} + +static int mc13892_get_voltage_mV(int hi, int voltage) +{ + int mV; + + if (hi == 0) + mV = voltage * 25 + 600; + else + mV = voltage * 25 + 1100; + + return mV; +} + +static int mc13892_sw_set_voltage(struct regulator_dev *reg, int MiniV, int uV) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1 = 0; + int voltage; + int sw = rdev_get_id(reg); + int mV = uV / 1000; + int hi; + + hi = mc13892_get_sw_hi_bit(sw); + voltage = mc13892_get_voltage_value(&hi, mV); + + switch (sw) { + case MC13892_SW1: + register1 = REG_SW_0; + register_val = BITFVAL(SW1, voltage); + register_mask = BITFMASK(SW1); + break; + case MC13892_SW2: + register1 = REG_SW_1; + register_val = BITFVAL(SW2, voltage); + register_mask = BITFMASK(SW2); + break; + case MC13892_SW3: + register1 = REG_SW_2; + register_val = BITFVAL(SW3, voltage); + register_mask = BITFMASK(SW3); + break; + case MC13892_SW4: + register1 = REG_SW_3; + register_val = BITFVAL(SW4, voltage); + register_mask = BITFMASK(SW4); + break; + default: + return -EINVAL; + } + + register_val |= (hi << SWXHI_LSH); + register_mask |= (1 << SWXHI_LSH); + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_sw_get_voltage(struct regulator_dev *reg) +{ + unsigned int register_val = 0; + int voltage = 0; + int mV = 0; + int sw = rdev_get_id(reg); + int hi; + + switch (sw) { + case MC13892_SW1: + CHECK_ERROR(pmic_read_reg(REG_SW_0, + ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, SW1); + break; + case MC13892_SW2: + CHECK_ERROR(pmic_read_reg(REG_SW_1, + ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, SW2); + break; + case MC13892_SW3: + CHECK_ERROR(pmic_read_reg(REG_SW_2, + ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, SW3); + break; + case MC13892_SW4: + CHECK_ERROR(pmic_read_reg(REG_SW_3, + ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, SW4); + break; + default: + return -EINVAL; + } + + hi = mc13892_get_sw_hi_bit(sw); + mV = mc13892_get_voltage_mV(hi, voltage); + + return mV; +} + +static int mc13892_sw_stby_enable(struct regulator_dev *reg) +{ + return 0; +} + +static int mc13892_sw_stby_disable(struct regulator_dev *reg) +{ + return 0; +} + +static int mc13892_sw_stby_set_mode(struct regulator_dev *reg, unsigned int mode) +{ + return 0; +} + +static int mc13892_sw_stby_set_voltage(struct regulator_dev *reg, int uV) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1 = 0; + int voltage, mV = uV / 1000, hi; + int sw = rdev_get_id(reg); + + hi = mc13892_get_sw_hi_bit(sw); + voltage = mc13892_get_voltage_value(&hi, mV); + + switch (sw) { + case MC13892_SW1: + register1 = REG_SW_0; + register_val = BITFVAL(SW1_STDBY, voltage); + register_mask = BITFMASK(SW1_STDBY); + break; + case MC13892_SW2: + register1 = REG_SW_1; + register_val = BITFVAL(SW2_STDBY, voltage); + register_mask = BITFMASK(SW2_STDBY); + break; + case MC13892_SW3: + register1 = REG_SW_2; + register_val = BITFVAL(SW3_STDBY, voltage); + register_mask = BITFMASK(SW3_STDBY); + break; + case MC13892_SW4: + register1 = REG_SW_3; + register_val = BITFVAL(SW4_STDBY, voltage); + register_mask = BITFMASK(SW4_STDBY); + break; + default: + return -EINVAL; + } + + register_val |= (hi << SWXHI_LSH); + register_mask |= (1 << SWXHI_LSH); + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_sw_stby_get_voltage(struct regulator_dev *reg) +{ + unsigned int register_val = 0; + int voltage = 0, mV = 0, hi; + int sw = rdev_get_id(reg); + + switch (sw) { + case MC13892_SW1: + CHECK_ERROR(pmic_read_reg(REG_SW_0, + ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, SW1_STDBY); + break; + case MC13892_SW2: + CHECK_ERROR(pmic_read_reg(REG_SW_1, + ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, SW2_STDBY); + break; + case MC13892_SW3: + CHECK_ERROR(pmic_read_reg(REG_SW_2, + ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, SW3_STDBY); + break; + case MC13892_SW4: + CHECK_ERROR(pmic_read_reg(REG_SW_3, + ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, SW4_STDBY); + break; + default: + return -EINVAL; + } + + hi = mc13892_get_sw_hi_bit(sw); + mV = mc13892_get_voltage_mV(hi, voltage); + + return mV; +} + +static int mc13892_sw_dvs_set_voltage(struct regulator_dev *reg, + int minuV, int uV) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1 = 0; + int voltage, mV = uV / 1000, hi; + int sw = rdev_get_id(reg); + + hi = mc13892_get_sw_hi_bit(sw); + voltage = mc13892_get_voltage_value(&hi, mV); + + switch (sw) { + case MC13892_SW1: + register1 = REG_SW_0; + register_val = BITFVAL(SW1_DVS, voltage); + register_mask = BITFMASK(SW1_DVS); + break; + case MC13892_SW2: + register1 = REG_SW_1; + register_val = BITFVAL(SW2_DVS, voltage); + register_mask = BITFMASK(SW2_DVS); + break; + default: + return -EINVAL; + } + + register_val |= (hi << SWXHI_LSH); + register_mask |= (1 << SWXHI_LSH); + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_sw_dvs_get_voltage(struct regulator_dev *reg) +{ + unsigned int register_val = 0; + int voltage = 0, mV = 0, hi; + int sw = rdev_get_id(reg); + + switch (sw) { + case MC13892_SW1: + CHECK_ERROR(pmic_read_reg(REG_SW_0, + ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, SW1_DVS); + break; + case MC13892_SW2: + CHECK_ERROR(pmic_read_reg(REG_SW_1, + ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, SW2_DVS); + break; + default: + return -EINVAL; + } + + hi = mc13892_get_sw_hi_bit(sw); + mV = mc13892_get_voltage_mV(hi, voltage); + + return mV; +} + +static int mc13892_swbst_enable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(SWBST_EN, SWBST_EN_ENABLE); + register_mask = BITFMASK(SWBST_EN); + register1 = REG_SW_5; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_swbst_disable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(SWBST_EN, SWBST_EN_DISABLE); + register_mask = BITFMASK(SWBST_EN); + register1 = REG_SW_5; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_viohi_enable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(VIOHI_EN, VIOHI_EN_ENABLE); + register_mask = BITFMASK(VIOHI_EN); + register1 = REG_MODE_0; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_viohi_disable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(VIOHI_EN, VIOHI_EN_DISABLE); + register_mask = BITFMASK(VIOHI_EN); + register1 = REG_MODE_0; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vusb_enable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(VUSB_EN, VUSB_EN_ENABLE); + register_mask = BITFMASK(VUSB_EN); + register1 = REG_USB1; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vusb_disable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(VUSB_EN, VUSB_EN_DISABLE); + register_mask = BITFMASK(VUSB_EN); + register1 = REG_USB1; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vdig_set_voltage(struct regulator_dev *reg, + int minuV, int uV) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + int voltage, mV = uV / 1000; + + if ((mV >= 1050) && (mV < 1250)) + voltage = VDIG_1_05V; + else if ((mV >= 1250) && (mV < 1650)) + voltage = VDIG_1_25V; + else if ((mV >= 1650) && (mV < 1800)) + voltage = VDIG_1_65V; + else + voltage = VDIG_1_80V; + + register_val = BITFVAL(VDIG, voltage); + register_mask = BITFMASK(VDIG); + register1 = REG_SETTING_0; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vdig_get_voltage(struct regulator_dev *reg) +{ + unsigned int register_val = 0; + int voltage = 0, mV = 0; + + CHECK_ERROR(pmic_read_reg(REG_SETTING_0, ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, VDIG); + + switch (voltage) { + case VDIG_1_05V: + mV = 1050; + break; + case VDIG_1_25V: + mV = 1250; + break; + case VDIG_1_65V: + mV = 1650; + break; + case VDIG_1_80V: + mV = 1800; + break; + default: + return -EINVAL; + } + + return mV * 1000; +} + +static int mc13892_vdig_enable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(VDIG_EN, VDIG_EN_ENABLE); + register_mask = BITFMASK(VDIG_EN); + register1 = REG_MODE_0; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vdig_disable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(VDIG_EN, VDIG_EN_DISABLE); + register_mask = BITFMASK(VDIG_EN); + register1 = REG_MODE_0; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vpll_set_voltage(struct regulator_dev *reg, + int minuV, int uV) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + int voltage, mV = uV / 1000; + + if ((mV >= 1050) && (mV < 1250)) + voltage = VPLL_1_05V; + else if ((mV >= 1250) && (mV < 1650)) + voltage = VPLL_1_25V; + else if ((mV >= 1650) && (mV < 1800)) + voltage = VPLL_1_65V; + else + voltage = VPLL_1_80V; + + register_val = BITFVAL(VPLL, voltage); + register_mask = BITFMASK(VPLL); + register1 = REG_SETTING_0; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vpll_get_voltage(struct regulator_dev *reg) +{ + unsigned int register_val = 0; + int voltage = 0, mV = 0; + + CHECK_ERROR(pmic_read_reg(REG_SETTING_0, ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, VPLL); + + switch (voltage) { + case VPLL_1_05V: + mV = 1050; + break; + case VPLL_1_25V: + mV = 1250; + break; + case VPLL_1_65V: + mV = 1650; + break; + case VPLL_1_80V: + mV = 1800; + break; + default: + return -EINVAL; + } + + return mV * 1000; +} + +static int mc13892_vpll_enable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(VPLL_EN, VPLL_EN_ENABLE); + register_mask = BITFMASK(VPLL_EN); + register1 = REG_MODE_0; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vpll_disable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(VPLL_EN, VPLL_EN_DISABLE); + register_mask = BITFMASK(VPLL_EN); + register1 = REG_MODE_0; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vaudio_set_voltage(struct regulator_dev *reg, + int minuV, int uV) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + int voltage, mV = uV / 1000; + + if ((mV >= 2300) && (mV < 2500)) + voltage = VAUDIO_2_3V; + else if ((mV >= 2500) && (mV < 2775)) + voltage = VAUDIO_2_5V; + else if ((mV >= 2775) && (mV < 3000)) + voltage = VAUDIO_2_775V; + else + voltage = VAUDIO_3V; + + register_val = BITFVAL(VAUDIO, voltage); + register_mask = BITFMASK(VAUDIO); + register1 = REG_SETTING_1; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vaudio_get_voltage(struct regulator_dev *reg) +{ + unsigned int register_val = 0; + int voltage = 0, mV = 0; + + CHECK_ERROR(pmic_read_reg(REG_SETTING_1, ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, VAUDIO); + + switch (voltage) { + case VAUDIO_2_3V: + mV = 2300; + break; + case VAUDIO_2_5V: + mV = 2500; + break; + case VAUDIO_2_775V: + mV = 2775; + break; + case VAUDIO_3V: + mV = 3000; + break; + default: + return -EINVAL; + } + + return mV * 1000; +} + +static int mc13892_vaudio_enable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(VAUDIO_EN, VAUDIO_EN_ENABLE); + register_mask = BITFMASK(VAUDIO_EN); + register1 = REG_MODE_1; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vaudio_disable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(VAUDIO_EN, VAUDIO_EN_DISABLE); + register_mask = BITFMASK(VAUDIO_EN); + register1 = REG_MODE_1; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vusb2_set_voltage(struct regulator_dev *reg, + int minuV, int uV) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + int voltage, mV = uV / 1000; + + if ((mV >= 2400) && (mV < 2600)) + voltage = VUSB2_2_4V; + else if ((mV >= 2600) && (mV < 2700)) + voltage = VUSB2_2_6V; + else if ((mV >= 2700) && (mV < 2775)) + voltage = VUSB2_2_7V; + else + voltage = VUSB2_2_775V; + + register_val = BITFVAL(VUSB2, voltage); + register_mask = BITFMASK(VUSB2); + register1 = REG_SETTING_0; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vusb2_get_voltage(struct regulator_dev *reg) +{ + unsigned int register_val = 0; + int voltage = 0, mV = 0; + + CHECK_ERROR(pmic_read_reg(REG_SETTING_0, ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, VUSB2); + + switch (voltage) { + case VUSB2_2_4V: + mV = 2400; + break; + case VUSB2_2_6V: + mV = 2600; + break; + case VUSB2_2_7V: + mV = 2700; + break; + case VUSB2_2_775V: + mV = 2775; + break; + default: + return -EINVAL; + } + + return mV * 1000; +} + +static int mc13892_vusb2_enable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(VUSB2_EN, VUSB2_EN_ENABLE); + register_mask = BITFMASK(VUSB2_EN); + register1 = REG_MODE_0; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vusb2_disable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(VUSB2_EN, VUSB2_EN_DISABLE); + register_mask = BITFMASK(VUSB2_EN); + register1 = REG_MODE_0; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vvideo_set_voltage(struct regulator_dev *reg, + int minuV, int uV) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + int voltage, mV = uV / 1000; + + if ((mV >= 2500) && (mV < 2600)) + voltage = VVIDEO_2_5V; + else if ((mV >= 2600) && (mV < 2700)) + voltage = VVIDEO_2_6V; + else if ((mV >= 2700) && (mV < 2775)) + voltage = VVIDEO_2_7V; + else + voltage = VVIDEO_2_775V; + + register_val = BITFVAL(VVIDEO, voltage); + register_mask = BITFMASK(VVIDEO); + register1 = REG_SETTING_1; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vvideo_get_voltage(struct regulator_dev *reg) +{ + unsigned int register_val = 0; + int voltage = 0, mV = 0; + + CHECK_ERROR(pmic_read_reg(REG_SETTING_1, ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, VVIDEO); + + switch (voltage) { + case VVIDEO_2_5V: + mV = 2500; + break; + case VVIDEO_2_6V: + mV = 2600; + break; + case VVIDEO_2_7V: + mV = 2700; + break; + case VVIDEO_2_775V: + mV = 2775; + break; + default: + return -EINVAL; + } + + return mV * 1000; +} + +static int mc13892_vvideo_enable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(VVIDEO_EN, VVIDEO_EN_ENABLE); + register_mask = BITFMASK(VVIDEO_EN); + register1 = REG_MODE_1; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vvideo_disable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(VVIDEO_EN, VVIDEO_EN_DISABLE); + register_mask = BITFMASK(VVIDEO_EN); + register1 = REG_MODE_1; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vsd_set_voltage(struct regulator_dev *reg, + int minuV, int uV) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + int voltage, mV = uV / 1000; + + if ((mV >= 1800) && (mV < 2000)) + voltage = VSD_1_8V; + else if ((mV >= 2000) && (mV < 2600)) + voltage = VSD_2_0V; + else if ((mV >= 2600) && (mV < 2700)) + voltage = VSD_2_6V; + else if ((mV >= 2700) && (mV < 2800)) + voltage = VSD_2_7V; + else if ((mV >= 2800) && (mV < 2900)) + voltage = VSD_2_8V; + else if ((mV >= 2900) && (mV < 3000)) + voltage = VSD_2_9V; + else if ((mV >= 3000) && (mV < 3150)) + voltage = VSD_3_0V; + else + voltage = VSD_3_15V; + + register_val = BITFVAL(VSD, voltage); + register_mask = BITFMASK(VSD); + register1 = REG_SETTING_1; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vsd_get_voltage(struct regulator_dev *reg) +{ + unsigned int register_val = 0; + int voltage = 0, mV = 0; + + CHECK_ERROR(pmic_read_reg(REG_SETTING_1, ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, VSD); + + switch (voltage) { + case VSD_1_8V: + mV = 1800; + break; + case VSD_2_0V: + mV = 2000; + break; + case VSD_2_6V: + mV = 2600; + break; + case VSD_2_7V: + mV = 2700; + break; + case VSD_2_8V: + mV = 2800; + break; + case VSD_2_9V: + mV = 2900; + break; + case VSD_3_0V: + mV = 3000; + break; + case VSD_3_15V: + mV = 3150; + break; + default: + return -EINVAL; + } + + return mV * 1000; +} + +static int mc13892_vsd_enable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(VSD_EN, VSD_EN_ENABLE); + register_mask = BITFMASK(VSD_EN); + register1 = REG_MODE_1; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vsd_disable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(VSD_EN, VSD_EN_DISABLE); + register_mask = BITFMASK(VSD_EN); + register1 = REG_MODE_1; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vcam_set_voltage(struct regulator_dev *reg, + int minuV, int uV) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + int voltage, mV = uV / 1000; + + if ((mV >= 2500) && (mV < 2600)) + voltage = VCAM_2_5V; + else if ((mV >= 2600) && (mV < 2750)) + voltage = VCAM_2_6V; + else if ((mV >= 2750) && (mV < 3000)) + voltage = VCAM_2_75V; + else + voltage = VCAM_3_0V; + + register_val = BITFVAL(VCAM, voltage); + register_mask = BITFMASK(VCAM); + register1 = REG_SETTING_0; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vcam_get_voltage(struct regulator_dev *reg) +{ + unsigned int register_val = 0; + int voltage = 0, mV = 0; + + CHECK_ERROR(pmic_read_reg(REG_SETTING_0, ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, VCAM); + + switch (voltage) { + case VCAM_2_5V: + mV = 2500; + break; + case VCAM_2_6V: + mV = 2600; + break; + case VCAM_2_75V: + mV = 2750; + break; + case VCAM_3_0V: + mV = 3000; + break; + default: + return -EINVAL; + } + + return mV * 1000; +} + +static int mc13892_vcam_enable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(VCAM_EN, VCAM_EN_ENABLE); + register_mask = BITFMASK(VCAM_EN); + register1 = REG_MODE_1; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vcam_disable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(VCAM_EN, VCAM_EN_DISABLE); + register_mask = BITFMASK(VCAM_EN); + register1 = REG_MODE_1; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vcam_set_mode(struct regulator_dev *reg, unsigned int mode) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + switch (mode) { + case REGULATOR_MODE_FAST: + register_val = BITFVAL(VCAM_CONFIG, VCAM_CONFIG_EXT); + break; + case REGULATOR_MODE_NORMAL: + register_val = BITFVAL(VCAM_CONFIG, VCAM_CONFIG_INT); + break; + default: + return -EINVAL; + } + register_mask = BITFMASK(VCAM_CONFIG); + register1 = REG_MODE_1; + + return pmic_write_reg(register1, register_val, register_mask); +} + +unsigned int mc13892_vcam_get_mode(struct regulator_dev *reg) +{ + unsigned int register_val = 0; + int config = 0, mode = VCAM_CONFIG_INT; + + CHECK_ERROR(pmic_read_reg(REG_MODE_1, ®ister_val, PMIC_ALL_BITS)); + config = BITFEXT(register_val, VCAM_CONFIG); + + switch (config) { + case VCAM_CONFIG_EXT: + mode = REGULATOR_MODE_FAST; + break; + case VCAM_CONFIG_INT: + mode = REGULATOR_MODE_NORMAL; + break; + default: + return -EINVAL; + } + return mode; +} + +static int mc13892_vgen1_set_voltage(struct regulator_dev *reg, + int minuV, int uV) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + int voltage, mV = uV / 1000; + + if ((mV >= 1200) && (mV < 1500)) + voltage = VGEN1_1_2V; + else if ((mV >= 1500) && (mV < 2775)) + voltage = VGEN1_1_5V; + else if ((mV >= 2775) && (mV < 3150)) + voltage = VGEN1_2_775V; + else + voltage = VGEN1_3_15V; + + register_val = BITFVAL(VGEN1, voltage); + register_mask = BITFMASK(VGEN1); + register1 = REG_SETTING_0; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vgen1_get_voltage(struct regulator_dev *reg) +{ + unsigned int register_val = 0; + int voltage = 0, mV = 0; + + CHECK_ERROR(pmic_read_reg(REG_SETTING_0, ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, VGEN1); + + switch (voltage) { + case VGEN1_1_2V: + mV = 1200; + break; + case VGEN1_1_5V: + mV = 1500; + break; + case VGEN1_2_775V: + mV = 2775; + break; + case VGEN1_3_15V: + mV = 3150; + break; + default: + return -EINVAL; + } + + return mV * 1000; +} + +static int mc13892_vgen1_enable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(VGEN1_EN, VGEN1_EN_ENABLE); + register_mask = BITFMASK(VGEN1_EN); + register1 = REG_MODE_0; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vgen1_disable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(VGEN1_EN, VGEN1_EN_DISABLE); + register_mask = BITFMASK(VGEN1_EN); + register1 = REG_MODE_0; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vgen2_set_voltage(struct regulator_dev *reg, + int minuV, int uV) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + int voltage, mV = uV / 1000; + + if ((mV >= 1200) && (mV < 1500)) + voltage = VGEN2_1_2V; + else if ((mV >= 1500) && (mV < 1600)) + voltage = VGEN2_1_5V; + else if ((mV >= 1600) && (mV < 1800)) + voltage = VGEN2_1_6V; + else if ((mV >= 1800) && (mV < 2700)) + voltage = VGEN2_1_8V; + else if ((mV >= 2700) && (mV < 2800)) + voltage = VGEN2_2_7V; + else if ((mV >= 2800) && (mV < 3000)) + voltage = VGEN2_2_8V; + else if ((mV >= 3000) && (mV < 3150)) + voltage = VGEN2_3_0V; + else + voltage = VGEN2_3_15V; + + register_val = BITFVAL(VGEN2, voltage); + register_mask = BITFMASK(VGEN2); + register1 = REG_SETTING_0; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vgen2_get_voltage(struct regulator_dev *reg) +{ + unsigned int register_val = 0; + int voltage = 0, mV = 0; + + CHECK_ERROR(pmic_read_reg(REG_SETTING_0, ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, VGEN2); + + switch (voltage) { + case VGEN2_1_2V: + mV = 1200; + break; + case VGEN2_1_5V: + mV = 1500; + break; + case VGEN2_1_6V: + mV = 1600; + break; + case VGEN2_1_8V: + mV = 1800; + break; + case VGEN2_2_7V: + mV = 2700; + break; + case VGEN2_2_8V: + mV = 2800; + break; + case VGEN2_3_0V: + mV = 3000; + break; + case VGEN2_3_15V: + mV = 3150; + break; + default: + return -EINVAL; + } + + return mV * 1000; +} + +static int mc13892_vgen2_enable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(VGEN2_EN, VGEN2_EN_ENABLE); + register_mask = BITFMASK(VGEN2_EN); + register1 = REG_MODE_0; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vgen2_disable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(VGEN2_EN, VGEN2_EN_DISABLE); + register_mask = BITFMASK(VGEN2_EN); + register1 = REG_MODE_0; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vgen3_set_voltage(struct regulator_dev *reg, + int minuV, int uV) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + int voltage, mV = uV / 1000; + + if ((mV >= 1800) && (mV < 2900)) + voltage = VGEN3_1_8V; + else + voltage = VGEN3_2_9V; + + register_val = BITFVAL(VGEN3, voltage); + register_mask = BITFMASK(VGEN3); + register1 = REG_SETTING_0; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vgen3_get_voltage(struct regulator_dev *reg) +{ + unsigned int register_val = 0; + int voltage = 0, mV = 0; + + CHECK_ERROR(pmic_read_reg(REG_SETTING_0, ®ister_val, PMIC_ALL_BITS)); + voltage = BITFEXT(register_val, VGEN3); + + switch (voltage) { + case VGEN3_1_8V: + mV = 1800; + break; + case VGEN3_2_9V: + mV = 2900; + break; + default: + return -EINVAL; + } + + return mV * 1000; +} + +static int mc13892_vgen3_enable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(VGEN3_EN, VGEN3_EN_ENABLE); + register_mask = BITFMASK(VGEN3_EN); + register1 = REG_MODE_1; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_vgen3_disable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + + register_val = BITFVAL(VGEN3_EN, VGEN3_EN_DISABLE); + register_mask = BITFMASK(VGEN3_EN); + register1 = REG_MODE_1; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_gpo_enable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + int gpo = rdev_get_id(reg); + + switch (gpo) { + case MC13892_GPO1: + register_val = BITFVAL(GPO1_EN, GPO1_EN_ENABLE); + register_mask = BITFMASK(GPO1_EN); + break; + case MC13892_GPO2: + register_val = BITFVAL(GPO2_EN, GPO2_EN_ENABLE); + register_mask = BITFMASK(GPO2_EN); + break; + case MC13892_GPO3: + register_val = BITFVAL(GPO3_EN, GPO3_EN_ENABLE); + register_mask = BITFMASK(GPO3_EN); + break; + case MC13892_GPO4: + register_val = BITFVAL(GPO4_EN, GPO4_EN_ENABLE) + + BITFVAL(GPO4_ADIN, GPO4_ADIN_DISABLE); + register_mask = BITFMASK(GPO4_EN) + BITFMASK(GPO4_ADIN); + break; + default: + return -EINVAL; + }; + + register1 = REG_POWER_MISC; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_gpo_disable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + int gpo = rdev_get_id(reg); + + switch (gpo) { + case MC13892_GPO1: + register_val = BITFVAL(GPO1_EN, GPO1_EN_DISABLE); + register_mask = BITFMASK(GPO1_EN); + break; + case MC13892_GPO2: + register_val = BITFVAL(GPO2_EN, GPO2_EN_DISABLE); + register_mask = BITFMASK(GPO2_EN); + break; + case MC13892_GPO3: + register_val = BITFVAL(GPO3_EN, GPO3_EN_DISABLE); + register_mask = BITFMASK(GPO3_EN); + break; + case MC13892_GPO4: + register_val = BITFVAL(GPO4_EN, GPO4_EN_DISABLE); + register_mask = BITFMASK(GPO4_EN); + break; + default: + return -EINVAL; + }; + + register1 = REG_POWER_MISC; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_power_gating_enable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + int gpo = rdev_get_id(reg); + + switch (gpo) { + case MC13892_PWGT1: + register_val = BITFVAL(PWGT1SPI_EN, PWGT1SPI_EN_ENABLE); + register_mask = BITFMASK(PWGT1SPI_EN); + break; + case MC13892_PWGT2: + register_val = BITFVAL(PWGT2SPI_EN, PWGT2SPI_EN_ENABLE); + register_mask = BITFMASK(PWGT2SPI_EN); + break; + default: + return -EINVAL; + }; + + register1 = REG_POWER_MISC; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static int mc13892_power_gating_disable(struct regulator_dev *reg) +{ + unsigned int register_val = 0, register_mask = 0; + unsigned int register1; + int gpo = rdev_get_id(reg); + + switch (gpo) { + case MC13892_PWGT1: + register_val = BITFVAL(PWGT1SPI_EN, PWGT1SPI_EN_DISABLE); + register_mask = BITFMASK(PWGT1SPI_EN); + break; + case MC13892_PWGT2: + register_val = BITFVAL(PWGT2SPI_EN, PWGT2SPI_EN_DISABLE); + register_mask = BITFMASK(PWGT2SPI_EN); + break; + default: + return -EINVAL; + }; + + register1 = REG_POWER_MISC; + + return pmic_write_reg(register1, register_val, register_mask); +} + +static struct regulator_ops mc13892_sw_ops = { + .set_voltage = mc13892_sw_set_voltage, + .get_voltage = mc13892_sw_get_voltage, + .set_suspend_voltage = mc13892_sw_stby_set_voltage, + .set_suspend_enable = mc13892_sw_stby_enable, + .set_suspend_disable = mc13892_sw_stby_disable, + .set_suspend_mode = mc13892_sw_stby_set_mode, +}; + +static struct regulator_ops mc13892_sw_dvs_ops = { + .set_voltage = mc13892_sw_dvs_set_voltage, + .get_voltage = mc13892_sw_dvs_get_voltage, +}; + +static struct regulator_ops mc13892_swbst_ops = { + .enable = mc13892_swbst_enable, + .disable = mc13892_swbst_disable, +}; + +static struct regulator_ops mc13892_viohi_ops = { + .enable = mc13892_viohi_enable, + .disable = mc13892_viohi_disable, +}; + +static struct regulator_ops mc13892_vusb_ops = { + .enable = mc13892_vusb_enable, + .disable = mc13892_vusb_disable, +}; + +static struct regulator_ops mc13892_vdig_ops = { + .set_voltage = mc13892_vdig_set_voltage, + .get_voltage = mc13892_vdig_get_voltage, + .enable = mc13892_vdig_enable, + .disable = mc13892_vdig_disable, +}; + +static struct regulator_ops mc13892_vpll_ops = { + .set_voltage = mc13892_vpll_set_voltage, + .get_voltage = mc13892_vpll_get_voltage, + .enable = mc13892_vpll_enable, + .disable = mc13892_vpll_disable, +}; + +static struct regulator_ops mc13892_vusb2_ops = { + .set_voltage = mc13892_vusb2_set_voltage, + .get_voltage = mc13892_vusb2_get_voltage, + .enable = mc13892_vusb2_enable, + .disable = mc13892_vusb2_disable, +}; + +static struct regulator_ops mc13892_vvideo_ops = { + .set_voltage = mc13892_vvideo_set_voltage, + .get_voltage = mc13892_vvideo_get_voltage, + .enable = mc13892_vvideo_enable, + .disable = mc13892_vvideo_disable, +}; + +static struct regulator_ops mc13892_vaudio_ops = { + .set_voltage = mc13892_vaudio_set_voltage, + .get_voltage = mc13892_vaudio_get_voltage, + .enable = mc13892_vaudio_enable, + .disable = mc13892_vaudio_disable, +}; + +static struct regulator_ops mc13892_vsd_ops = { + .set_voltage = mc13892_vsd_set_voltage, + .get_voltage = mc13892_vsd_get_voltage, + .enable = mc13892_vsd_enable, + .disable = mc13892_vsd_disable, +}; + +static struct regulator_ops mc13892_vcam_ops = { + .set_voltage = mc13892_vcam_set_voltage, + .get_voltage = mc13892_vcam_get_voltage, + .enable = mc13892_vcam_enable, + .disable = mc13892_vcam_disable, + .set_mode = mc13892_vcam_set_mode, + .get_mode = mc13892_vcam_get_mode, +}; + +static struct regulator_ops mc13892_vgen1_ops = { + .set_voltage = mc13892_vgen1_set_voltage, + .get_voltage = mc13892_vgen1_get_voltage, + .enable = mc13892_vgen1_enable, + .disable = mc13892_vgen1_disable, +}; + +static struct regulator_ops mc13892_vgen2_ops = { + .set_voltage = mc13892_vgen2_set_voltage, + .get_voltage = mc13892_vgen2_get_voltage, + .enable = mc13892_vgen2_enable, + .disable = mc13892_vgen2_disable, +}; + +static struct regulator_ops mc13892_vgen3_ops = { + .set_voltage = mc13892_vgen3_set_voltage, + .get_voltage = mc13892_vgen3_get_voltage, + .enable = mc13892_vgen3_enable, + .disable = mc13892_vgen3_disable, +}; + +static struct regulator_ops mc13892_gpo_ops = { + .enable = mc13892_gpo_enable, + .disable = mc13892_gpo_disable, +}; + +static struct regulator_ops mc13892_power_gating_ops = { + .enable = mc13892_power_gating_enable, + .disable = mc13892_power_gating_disable, + +}; + +static struct regulator_desc mc13892_reg[] = { + { + .name = "SW1", + .id = MC13892_SW1, + .ops = &mc13892_sw_ops, + .irq = 0, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE + }, + { + .name = "SW2", + .id = MC13892_SW2, + .ops = &mc13892_sw_ops, + .irq = 0, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE + }, + { + .name = "SW3", + .id = MC13892_SW3, + .ops = &mc13892_sw_ops, + .irq = 0, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE + }, + { + .name = "SW4", + .id = MC13892_SW4, + .ops = &mc13892_sw_ops, + .irq = 0, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE + }, + { + .name = "SWBST", + .id = MC13892_SWBST, + .ops = &mc13892_swbst_ops, + .irq = 0, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE + }, + { + .name = "VIOHI", + .id = MC13892_VIOHI, + .ops = &mc13892_viohi_ops, + .irq = 0, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE + }, + { + .name = "VPLL", + .id = MC13892_VPLL, + .ops = &mc13892_vpll_ops, + .irq = 0, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE + }, + { + .name = "VDIG", + .id = MC13892_VDIG, + .ops = &mc13892_vdig_ops, + .irq = 0, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE + }, + { + .name = "VSD", + .id = MC13892_VSD, + .ops = &mc13892_vsd_ops, + .irq = 0, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE + }, + { + .name = "VUSB2", + .id = MC13892_VUSB2, + .ops = &mc13892_vusb2_ops, + .irq = 0, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE + }, + { + .name = "VVIDEO", + .id = MC13892_VVIDEO, + .ops = &mc13892_vvideo_ops, + .irq = 0, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE + }, + { + .name = "VAUDIO", + .id = MC13892_VAUDIO, + .ops = &mc13892_vaudio_ops, + .irq = 0, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE + }, + { + .name = "VCAM", + .id = MC13892_VCAM, + .ops = &mc13892_vcam_ops, + .irq = 0, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE + }, + { + .name = "VGEN1", + .id = MC13892_VGEN1, + .ops = &mc13892_vgen1_ops, + .irq = 0, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE + }, + { + .name = "VGEN2", + .id = MC13892_VGEN2, + .ops = &mc13892_vgen2_ops, + .irq = 0, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE + }, + { + .name = "VGEN3", + .id = MC13892_VGEN3, + .ops = &mc13892_vgen3_ops, + .irq = 0, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE + }, + { + .name = "VUSB", + .id = MC13892_VUSB, + .ops = &mc13892_vusb_ops, + .irq = 0, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE + }, + { + .name = "GPO1", + .id = MC13892_GPO1, + .ops = &mc13892_gpo_ops, + .irq = 0, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE + }, + { + .name = "GPO2", + .id = MC13892_GPO2, + .ops = &mc13892_gpo_ops, + .irq = 0, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE + }, + { + .name = "GPO3", + .id = MC13892_GPO3, + .ops = &mc13892_gpo_ops, + .irq = 0, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE + }, + { + .name = "GPO4", + .id = MC13892_GPO4, + .ops = &mc13892_gpo_ops, + .irq = 0, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE + }, + { + .name = "PWGT1", + .id = MC13892_PWGT1, + .ops = &mc13892_power_gating_ops, + .irq = 0, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE + }, +}; + +static int mc13892_regulator_probe(struct platform_device *pdev) +{ + struct regulator_dev *rdev; + + /* register regulator */ + rdev = regulator_register(&mc13892_reg[pdev->id], &pdev->dev, + dev_get_drvdata(&pdev->dev)); + if (IS_ERR(rdev)) { + dev_err(&pdev->dev, "failed to register %s\n", + mc13892_reg[pdev->id].name); + return PTR_ERR(rdev); + } + + return 0; +} + + +static int mc13892_regulator_remove(struct platform_device *pdev) +{ + struct regulator_dev *rdev = platform_get_drvdata(pdev); + + regulator_unregister(rdev); + + return 0; +} + +int mc13892_register_regulator(struct mc13892 *mc13892, int reg, + struct regulator_init_data *initdata) +{ + struct platform_device *pdev; + int ret; + + if (mc13892->pmic.pdev[reg]) + return -EBUSY; + + pdev = platform_device_alloc("mc13892-regulatr", reg); + if (!pdev) + return -ENOMEM; + + mc13892->pmic.pdev[reg] = pdev; + + initdata->driver_data = mc13892; + + pdev->dev.platform_data = initdata; + pdev->dev.parent = mc13892->dev; + platform_set_drvdata(pdev, mc13892); + ret = platform_device_add(pdev); + + if (ret != 0) { + dev_err(mc13892->dev, "Failed to register regulator %d: %d\n", + reg, ret); + platform_device_del(pdev); + mc13892->pmic.pdev[reg] = NULL; + } + + return ret; +} +EXPORT_SYMBOL_GPL(mc13892_register_regulator); + +static struct platform_driver mc13892_regulator_driver = { + .probe = mc13892_regulator_probe, + .remove = mc13892_regulator_remove, + .driver = { + .name = "mc13892-regulatr", + }, +}; + +static int __init mc13892_regulator_init(void) +{ + return platform_driver_register(&mc13892_regulator_driver); +} +subsys_initcall(mc13892_regulator_init); + +static void __exit mc13892_regulator_exit(void) +{ + platform_driver_unregister(&mc13892_regulator_driver); +} +module_exit(mc13892_regulator_exit); + + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("MC13892 Regulator driver"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/regulator/Kconfig +++ linux-2.6.28/drivers/regulator/Kconfig @@ -73,4 +73,10 @@ Say y here to support the BUCKs and LDOs regulators found on Dialog Semiconductor DA9030/DA9034 PMIC. +config REGULATOR_MC13892 + tristate "MC13892 Regulator Support" + depends on REGULATOR + depends on MXC_PMIC_MC13892 + default y + endif --- linux-2.6.28.orig/drivers/regulator/Makefile +++ linux-2.6.28/drivers/regulator/Makefile @@ -2,7 +2,6 @@ # Makefile for regulator drivers. # - obj-$(CONFIG_REGULATOR) += core.o obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o @@ -12,4 +11,6 @@ obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o obj-$(CONFIG_REGULATOR_DA903X) += da903x.o +obj-$(CONFIG_REGULATOR_MC13892) += reg-mc13892.o + ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG --- linux-2.6.28.orig/drivers/misc/acer-wmi.c +++ linux-2.6.28/drivers/misc/acer-wmi.c @@ -107,6 +107,7 @@ #define ACER_CAP_BLUETOOTH (1<<2) #define ACER_CAP_BRIGHTNESS (1<<3) #define ACER_CAP_THREEG (1<<4) +#define ACER_CAP_SWRFKILL (1<<5) #define ACER_CAP_ANY (0xFFFFFFFF) /* @@ -139,6 +140,10 @@ MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware"); MODULE_PARM_DESC(force_series, "Force a different laptop series"); +static int rfkill = -1; +module_param(rfkill, bool, 0444); +MODULE_PARM_DESC(rfkill, "Force software rfkill on/off"); + struct acer_data { int mailled; int threeg; @@ -183,6 +188,7 @@ u8 mailled; s8 brightness; u8 bluetooth; + u8 hw_rfkill; }; static struct quirk_entry *quirks; @@ -197,6 +203,9 @@ if (quirks->brightness) interface->capability |= ACER_CAP_BRIGHTNESS; + + if (!quirks->hw_rfkill) + interface->capability |= ACER_CAP_SWRFKILL; } static int dmi_matched(const struct dmi_system_id *dmi) @@ -216,6 +225,10 @@ .mailled = 1, }; +static struct quirk_entry quirk_acer_aspire_one = { + .hw_rfkill = 1, +}; + /* This AMW0 laptop has no bluetooth */ static struct quirk_entry quirk_medion_md_98300 = { .wireless = 1, @@ -336,6 +349,24 @@ }, { .callback = dmi_matched, + .ident = "Acer Aspire One 110", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"), + }, + .driver_data = &quirk_acer_aspire_one, + }, + { + .callback = dmi_matched, + .ident = "Acer Aspire One 150", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"), + }, + .driver_data = &quirk_acer_aspire_one, + }, + { + .callback = dmi_matched, .ident = "Fujitsu Siemens Amilo Li 1718", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), @@ -999,6 +1030,8 @@ static int acer_rfkill_init(struct device *dev) { + printk(ACER_INFO "software RFKILL enabled\n"); + wireless_rfkill = acer_rfkill_register(dev, RFKILL_TYPE_WLAN, "acer-wireless", ACER_CAP_WIRELESS); if (IS_ERR(wireless_rfkill)) @@ -1116,12 +1149,20 @@ goto error_brightness; } - err = acer_rfkill_init(&device->dev); + if ((has_cap(ACER_CAP_SWRFKILL) || rfkill == 1) && rfkill != 0) { + err = acer_rfkill_init(&device->dev); + if (err) + goto error_rfkill; + } return err; +error_rfkill: + if (has_cap(ACER_CAP_BRIGHTNESS)) + acer_backlight_exit(); error_brightness: - acer_led_exit(); + if (has_cap(ACER_CAP_MAILLED)) + acer_led_exit(); error_mailled: return err; } @@ -1132,8 +1173,8 @@ acer_led_exit(); if (has_cap(ACER_CAP_BRIGHTNESS)) acer_backlight_exit(); - - acer_rfkill_exit(); + if (has_cap(ACER_CAP_SWRFKILL)) + acer_rfkill_exit(); return 0; } @@ -1297,7 +1338,7 @@ set_quirks(); - if (!acpi_video_backlight_support() && has_cap(ACER_CAP_BRIGHTNESS)) { + if (acpi_video_backlight_support() && has_cap(ACER_CAP_BRIGHTNESS)) { interface->capability &= ~ACER_CAP_BRIGHTNESS; printk(ACER_INFO "Brightness must be controlled by " "generic video driver\n"); --- linux-2.6.28.orig/drivers/misc/hpilo.c +++ linux-2.6.28/drivers/misc/hpilo.c @@ -207,7 +207,7 @@ &device_ccb->recv_ctrl); /* give iLO some time to process stop request */ - for (retries = 1000; retries > 0; retries--) { + for (retries = MAX_WAIT; retries > 0; retries--) { doorbell_set(driver_ccb); udelay(1); if (!(ioread32(&device_ccb->send_ctrl) & (1 << CTRL_BITPOS_A)) @@ -309,7 +309,7 @@ doorbell_clr(driver_ccb); /* make sure iLO is really handling requests */ - for (i = 1000; i > 0; i--) { + for (i = MAX_WAIT; i > 0; i--) { if (ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, NULL, NULL)) break; udelay(1); @@ -326,7 +326,7 @@ return 0; free: - pci_free_consistent(pdev, data->dma_size, data->dma_va, data->dma_pa); + ilo_ccb_close(pdev, data); out: return error; } @@ -710,6 +710,7 @@ static struct pci_device_id ilo_devices[] = { { PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xB204) }, + { PCI_DEVICE(PCI_VENDOR_ID_HP, 0x3307) }, { } }; MODULE_DEVICE_TABLE(pci, ilo_devices); --- linux-2.6.28.orig/drivers/misc/thinkpad_acpi.c +++ linux-2.6.28/drivers/misc/thinkpad_acpi.c @@ -6927,7 +6927,7 @@ * if it is not there yet. */ #define IBM_BIOS_MODULE_ALIAS(__type) \ - MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW") + MODULE_ALIAS("dmi:bvnIBM:bvr" __type "ET??WW*") /* Non-ancient thinkpads */ MODULE_ALIAS("dmi:bvnIBM:*:svnIBM:*:pvrThinkPad*:rvnIBM:*"); @@ -6936,9 +6936,9 @@ /* Ancient thinkpad BIOSes have to be identified by * BIOS type or model number, and there are far less * BIOS types than model numbers... */ -IBM_BIOS_MODULE_ALIAS("I[B,D,H,I,M,N,O,T,W,V,Y,Z]"); -IBM_BIOS_MODULE_ALIAS("1[0,3,6,8,A-G,I,K,M-P,S,T]"); -IBM_BIOS_MODULE_ALIAS("K[U,X-Z]"); +IBM_BIOS_MODULE_ALIAS("I[BDHIMNOTWVYZ]"); +IBM_BIOS_MODULE_ALIAS("1[0368A-GIKM-PST]"); +IBM_BIOS_MODULE_ALIAS("K[UX-Z]"); MODULE_AUTHOR("Borislav Deianov, Henrique de Moraes Holschuh"); MODULE_DESCRIPTION(TPACPI_DESC); --- linux-2.6.28.orig/drivers/misc/eeepc-laptop.c +++ linux-2.6.28/drivers/misc/eeepc-laptop.c @@ -161,6 +161,10 @@ {KE_KEY, 0x13, KEY_MUTE }, {KE_KEY, 0x14, KEY_VOLUMEDOWN }, {KE_KEY, 0x15, KEY_VOLUMEUP }, + {KE_KEY, 0x1a, KEY_COFFEE }, + {KE_KEY, 0x1b, KEY_ZOOM }, + {KE_KEY, 0x1c, KEY_PROG2 }, + {KE_KEY, 0x1d, KEY_PROG3 }, {KE_KEY, 0x30, KEY_SWITCHVIDEOMODE }, {KE_KEY, 0x31, KEY_SWITCHVIDEOMODE }, {KE_KEY, 0x32, KEY_SWITCHVIDEOMODE }, @@ -510,7 +514,8 @@ static void notify_brn(void) { struct backlight_device *bd = eeepc_backlight_device; - bd->props.brightness = read_brightness(bd); + if (bd) + bd->props.brightness = read_brightness(bd); } static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) --- linux-2.6.28.orig/drivers/misc/sony-laptop.c +++ linux-2.6.28/drivers/misc/sony-laptop.c @@ -851,6 +851,28 @@ { 0, 0 }, }; +static struct sony_nc_event sony_FW_events[] = { + { 0x82, SONYPI_EVENT_FNKEY_F2 }, + { 0x02, SONYPI_EVENT_FNKEY_RELEASED }, + { 0x85, SONYPI_EVENT_FNKEY_F5 }, + { 0x05, SONYPI_EVENT_FNKEY_RELEASED }, + { 0x86, SONYPI_EVENT_FNKEY_F6 }, + { 0x06, SONYPI_EVENT_FNKEY_RELEASED }, + { 0x87, SONYPI_EVENT_FNKEY_F7 }, + { 0x07, SONYPI_EVENT_FNKEY_RELEASED }, + { 0x89, SONYPI_EVENT_FNKEY_F9 }, + { 0x09, SONYPI_EVENT_FNKEY_RELEASED }, + { 0x8A, SONYPI_EVENT_FNKEY_F10 }, + { 0x0A, SONYPI_EVENT_FNKEY_RELEASED }, + { 0x8C, SONYPI_EVENT_FNKEY_F12 }, + { 0x0C, SONYPI_EVENT_FNKEY_RELEASED }, + { 0x90, SONYPI_EVENT_PKEY_P1 }, + { 0x10, SONYPI_EVENT_FNKEY_RELEASED }, + { 0xA1, SONYPI_EVENT_PKEY_P2 }, + { 0x21, SONYPI_EVENT_FNKEY_RELEASED }, + { 0, 0 }, +}; + /* SNC-only model map */ static const struct dmi_system_id sony_nc_ids[] = { { @@ -889,6 +911,15 @@ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-N"), }, }, + { + .ident = "Sony Vaio FW Series", + .callback = sony_nc_C_enable, + .driver_data = sony_FW_events, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW"), + }, + }, { } }; --- linux-2.6.28.orig/drivers/misc/hpilo.h +++ linux-2.6.28/drivers/misc/hpilo.h @@ -19,6 +19,8 @@ #define MAX_ILO_DEV 1 /* max number of files */ #define MAX_OPEN (MAX_CCB * MAX_ILO_DEV) +/* spin counter for open/close delay */ +#define MAX_WAIT 10000 /* * Per device, used to track global memory allocations. --- linux-2.6.28.orig/drivers/misc/panasonic-laptop.c +++ linux-2.6.28/drivers/misc/panasonic-laptop.c @@ -515,7 +515,7 @@ hkey_num = result & 0xf; - if (hkey_num < 0 || hkey_num > ARRAY_SIZE(pcc->keymap)) { + if (hkey_num < 0 || hkey_num >= ARRAY_SIZE(pcc->keymap)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "hotkey number out of range: %d\n", hkey_num)); --- linux-2.6.28.orig/drivers/misc/sgi-xp/xpc_sn2.c +++ linux-2.6.28/drivers/misc/sgi-xp/xpc_sn2.c @@ -904,7 +904,7 @@ dev_dbg(xpc_part, " remote_vars_pa = 0x%016lx\n", part_sn2->remote_vars_pa); - part->last_heartbeat = remote_vars->heartbeat; + part->last_heartbeat = remote_vars->heartbeat - 1; dev_dbg(xpc_part, " last_heartbeat = 0x%016lx\n", part->last_heartbeat); @@ -1841,6 +1841,7 @@ */ xpc_clear_remote_msgqueue_flags_sn2(ch); + smp_wmb(); /* ensure flags have been cleared before bte_copy */ ch_sn2->w_remote_GP.put = ch_sn2->remote_GP.put; dev_dbg(xpc_chan, "w_remote_GP.put changed to %ld, partid=%d, " @@ -1939,7 +1940,7 @@ break; get = ch_sn2->w_local_GP.get; - rmb(); /* guarantee that .get loads before .put */ + smp_rmb(); /* guarantee that .get loads before .put */ if (get == ch_sn2->w_remote_GP.put) break; @@ -1961,11 +1962,13 @@ msg = xpc_pull_remote_msg_sn2(ch, get); - DBUG_ON(msg != NULL && msg->number != get); - DBUG_ON(msg != NULL && (msg->flags & XPC_M_SN2_DONE)); - DBUG_ON(msg != NULL && !(msg->flags & XPC_M_SN2_READY)); + if (msg != NULL) { + DBUG_ON(msg->number != get); + DBUG_ON(msg->flags & XPC_M_SN2_DONE); + DBUG_ON(!(msg->flags & XPC_M_SN2_READY)); - payload = &msg->payload; + payload = &msg->payload; + } break; } @@ -2058,7 +2061,7 @@ while (1) { put = ch_sn2->w_local_GP.put; - rmb(); /* guarantee that .put loads before .get */ + smp_rmb(); /* guarantee that .put loads before .get */ if (put - ch_sn2->w_remote_GP.get < ch->local_nentries) { /* There are available message entries. We need to try @@ -2191,7 +2194,7 @@ * The preceding store of msg->flags must occur before the following * load of local_GP->put. */ - mb(); + smp_mb(); /* see if the message is next in line to be sent, if so send it */ @@ -2292,7 +2295,7 @@ * The preceding store of msg->flags must occur before the following * load of local_GP->get. */ - mb(); + smp_mb(); /* * See if this message is next in line to be acknowledged as having --- linux-2.6.28.orig/drivers/misc/sgi-xp/xpc_uv.c +++ linux-2.6.28/drivers/misc/sgi-xp/xpc_uv.c @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2008-2009 Silicon Graphics, Inc. All Rights Reserved. */ /* @@ -825,8 +825,8 @@ continue; for (entry = 0; entry < nentries; entry++) { - msg_slot = ch_uv->recv_msg_slots + entry * - ch->entry_size; + msg_slot = ch_uv->recv_msg_slots + + entry * ch->entry_size; msg_slot->hdr.msg_slot_number = entry; } @@ -1123,9 +1123,8 @@ /* we're dealing with a normal message sent via the notify_mq */ ch_uv = &ch->sn.uv; - msg_slot = (struct xpc_notify_mq_msg_uv *)((u64)ch_uv->recv_msg_slots + - (msg->hdr.msg_slot_number % ch->remote_nentries) * - ch->entry_size); + msg_slot = ch_uv->recv_msg_slots + + (msg->hdr.msg_slot_number % ch->remote_nentries) * ch->entry_size; BUG_ON(msg->hdr.msg_slot_number != msg_slot->hdr.msg_slot_number); BUG_ON(msg_slot->hdr.size != 0); @@ -1238,7 +1237,7 @@ atomic_inc(&ch->n_to_notify); msg_slot->key = key; - wmb(); /* a non-NULL func must hit memory after the key */ + smp_wmb(); /* a non-NULL func must hit memory after the key */ msg_slot->func = func; if (ch->flags & XPC_C_DISCONNECTING) { --- linux-2.6.28.orig/drivers/misc/sgi-xp/xpc.h +++ linux-2.6.28/drivers/misc/sgi-xp/xpc.h @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2004-2009 Silicon Graphics, Inc. All Rights Reserved. */ /* @@ -502,7 +502,8 @@ /* partition's notify mq */ struct xpc_send_msg_slot_uv *send_msg_slots; - struct xpc_notify_mq_msg_uv *recv_msg_slots; + void *recv_msg_slots; /* each slot will hold a xpc_notify_mq_msg_uv */ + /* structure plus the user's payload */ struct xpc_fifo_head_uv msg_slot_free_list; struct xpc_fifo_head_uv recv_msg_list; /* deliverable payloads */ --- linux-2.6.28.orig/drivers/md/dm-log.c +++ linux-2.6.28/drivers/md/dm-log.c @@ -467,6 +467,7 @@ lc->disk_header = vmalloc(buf_size); if (!lc->disk_header) { DMWARN("couldn't allocate disk log buffer"); + dm_io_client_destroy(lc->io_req.client); kfree(lc); return -ENOMEM; } @@ -482,6 +483,8 @@ DMWARN("couldn't allocate sync bitset"); if (!dev) vfree(lc->clean_bits); + else + dm_io_client_destroy(lc->io_req.client); vfree(lc->disk_header); kfree(lc); return -ENOMEM; @@ -495,6 +498,8 @@ vfree(lc->sync_bits); if (!dev) vfree(lc->clean_bits); + else + dm_io_client_destroy(lc->io_req.client); vfree(lc->disk_header); kfree(lc); return -ENOMEM; --- linux-2.6.28.orig/drivers/md/dm.c +++ linux-2.6.28/drivers/md/dm.c @@ -480,9 +480,12 @@ static void dec_pending(struct dm_io *io, int error) { unsigned long flags; + int io_error; + struct bio *bio; + struct mapped_device *md = io->md; /* Push-back supersedes any I/O errors */ - if (error && !(io->error > 0 && __noflush_suspending(io->md))) + if (error && !(io->error > 0 && __noflush_suspending(md))) io->error = error; if (atomic_dec_and_test(&io->io_count)) { @@ -492,25 +495,28 @@ * This must be handled before the sleeper on * suspend queue merges the pushback list. */ - spin_lock_irqsave(&io->md->pushback_lock, flags); - if (__noflush_suspending(io->md)) - bio_list_add(&io->md->pushback, io->bio); + spin_lock_irqsave(&md->pushback_lock, flags); + if (__noflush_suspending(md)) + bio_list_add(&md->pushback, io->bio); else /* noflush suspend was interrupted. */ io->error = -EIO; - spin_unlock_irqrestore(&io->md->pushback_lock, flags); + spin_unlock_irqrestore(&md->pushback_lock, flags); } end_io_acct(io); - if (io->error != DM_ENDIO_REQUEUE) { - blk_add_trace_bio(io->md->queue, io->bio, + io_error = io->error; + bio = io->bio; + + free_io(md, io); + + if (io_error != DM_ENDIO_REQUEUE) { + blk_add_trace_bio(md->queue, io->bio, BLK_TA_COMPLETE); - bio_endio(io->bio, io->error); + bio_endio(bio, io_error); } - - free_io(io->md, io); } } @@ -518,6 +524,7 @@ { int r = 0; struct dm_target_io *tio = bio->bi_private; + struct dm_io *io = tio->io; struct mapped_device *md = tio->io->md; dm_endio_fn endio = tio->ti->type->end_io; @@ -541,15 +548,14 @@ } } - dec_pending(tio->io, error); - /* * Store md for cleanup instead of tio which is about to get freed. */ bio->bi_private = md->bs; - bio_put(bio); free_tio(md, tio); + bio_put(bio); + dec_pending(io, error); } static sector_t max_io_len(struct mapped_device *md, @@ -1666,6 +1672,7 @@ { return md->disk; } +EXPORT_SYMBOL_GPL(dm_disk); int dm_suspended(struct mapped_device *md) { --- linux-2.6.28.orig/drivers/md/bitmap.c +++ linux-2.6.28/drivers/md/bitmap.c @@ -964,9 +964,11 @@ */ page = bitmap->sb_page; offset = sizeof(bitmap_super_t); - read_sb_page(bitmap->mddev, bitmap->offset, - page, - index, count); + if (!file) + read_sb_page(bitmap->mddev, + bitmap->offset, + page, + index, count); } else if (file) { page = read_page(file, index, bitmap, count); offset = 0; --- linux-2.6.28.orig/drivers/md/dm-ioctl.c +++ linux-2.6.28/drivers/md/dm-ioctl.c @@ -704,7 +704,8 @@ char *new_name = (char *) param + param->data_start; if (new_name < param->data || - invalid_str(new_name, (void *) param + param_size)) { + invalid_str(new_name, (void *) param + param_size) || + strlen(new_name) > DM_NAME_LEN - 1) { DMWARN("Invalid new logical volume name supplied."); return -EINVAL; } --- linux-2.6.28.orig/drivers/md/linear.c +++ linux-2.6.28/drivers/md/linear.c @@ -25,13 +25,13 @@ { dev_info_t *hash; linear_conf_t *conf = mddev_to_conf(mddev); + sector_t idx = sector >> conf->sector_shift; /* * sector_div(a,b) returns the remainer and sets a to a/b */ - sector >>= conf->sector_shift; - (void)sector_div(sector, conf->spacing); - hash = conf->hash_table[sector]; + (void)sector_div(idx, conf->spacing); + hash = conf->hash_table[idx]; while (sector >= hash->num_sectors + hash->start_sector) hash++; --- linux-2.6.28.orig/drivers/md/md.c +++ linux-2.6.28/drivers/md/md.c @@ -1447,6 +1447,11 @@ if (find_rdev_nr(mddev, rdev->desc_nr)) return -EBUSY; } + if (mddev->max_disks && rdev->desc_nr >= mddev->max_disks) { + printk(KERN_WARNING "md: %s: array is limited to %d devices\n", + mdname(mddev), mddev->max_disks); + return -EBUSY; + } bdevname(rdev->bdev,b); while ( (s=strchr(b, '/')) != NULL) *s = '!'; @@ -2355,6 +2360,15 @@ i = 0; rdev_for_each(rdev, tmp, mddev) { + if (rdev->desc_nr >= mddev->max_disks || + i > mddev->max_disks) { + printk(KERN_WARNING + "md: %s: %s: only %d devices permitted\n", + mdname(mddev), bdevname(rdev->bdev, b), + mddev->max_disks); + kick_rdev_from_array(rdev); + continue; + } if (rdev != freshest) if (super_types[mddev->major_version]. validate_super(mddev, rdev)) { @@ -3902,11 +3916,11 @@ sysfs_remove_link(&mddev->kobj, nm); } + export_array(mddev); + /* make sure all md_delayed_delete calls have finished */ flush_scheduled_work(); - export_array(mddev); - mddev->array_sectors = 0; mddev->size = 0; mddev->raid_disks = 0; @@ -4448,13 +4462,6 @@ * noticed in interrupt contexts ... */ - if (rdev->desc_nr == mddev->max_disks) { - printk(KERN_WARNING "%s: can not hot-add to full array!\n", - mdname(mddev)); - err = -EBUSY; - goto abort_unbind_export; - } - rdev->raid_disk = -1; md_update_sb(mddev, 1); @@ -4468,9 +4475,6 @@ md_new_event(mddev); return 0; -abort_unbind_export: - unbind_rdev_from_array(rdev); - abort_export: export_rdev(rdev); return err; --- linux-2.6.28.orig/drivers/md/dm-io.c +++ linux-2.6.28/drivers/md/dm-io.c @@ -292,6 +292,8 @@ (PAGE_SIZE >> SECTOR_SHIFT)); num_bvecs = 1 + min_t(int, bio_get_nr_vecs(where->bdev), num_bvecs); + if (unlikely(num_bvecs > BIO_MAX_PAGES)) + num_bvecs = BIO_MAX_PAGES; bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, io->client->bios); bio->bi_sector = where->sector + (where->count - remaining); bio->bi_bdev = where->bdev; --- linux-2.6.28.orig/drivers/md/raid1.c +++ linux-2.6.28/drivers/md/raid1.c @@ -1233,8 +1233,9 @@ update_head_pos(mirror, r1_bio); if (atomic_dec_and_test(&r1_bio->remaining)) { - md_done_sync(mddev, r1_bio->sectors, uptodate); + sector_t s = r1_bio->sectors; put_buf(r1_bio); + md_done_sync(mddev, s, uptodate); } } --- linux-2.6.28.orig/drivers/md/raid10.c +++ linux-2.6.28/drivers/md/raid10.c @@ -1236,6 +1236,7 @@ /* for reconstruct, we always reschedule after a read. * for resync, only after all reads */ + rdev_dec_pending(conf->mirrors[d].rdev, conf->mddev); if (test_bit(R10BIO_IsRecover, &r10_bio->state) || atomic_dec_and_test(&r10_bio->remaining)) { /* we have read all the blocks, @@ -1243,7 +1244,6 @@ */ reschedule_retry(r10_bio); } - rdev_dec_pending(conf->mirrors[d].rdev, conf->mddev); } static void end_sync_write(struct bio *bio, int error) @@ -1264,11 +1264,13 @@ update_head_pos(i, r10_bio); + rdev_dec_pending(conf->mirrors[d].rdev, mddev); while (atomic_dec_and_test(&r10_bio->remaining)) { if (r10_bio->master_bio == NULL) { /* the primary of several recovery bios */ - md_done_sync(mddev, r10_bio->sectors, 1); + sector_t s = r10_bio->sectors; put_buf(r10_bio); + md_done_sync(mddev, s, 1); break; } else { r10bio_t *r10_bio2 = (r10bio_t *)r10_bio->master_bio; @@ -1276,7 +1278,6 @@ r10_bio = r10_bio2; } } - rdev_dec_pending(conf->mirrors[d].rdev, mddev); } /* @@ -1749,8 +1750,6 @@ if (!go_faster && conf->nr_waiting) msleep_interruptible(1000); - bitmap_cond_end_sync(mddev->bitmap, sector_nr); - /* Again, very different code for resync and recovery. * Both must result in an r10bio with a list of bios that * have bi_end_io, bi_sector, bi_bdev set, @@ -1886,6 +1885,8 @@ /* resync. Schedule a read for every block at this virt offset */ int count = 0; + bitmap_cond_end_sync(mddev->bitmap, sector_nr); + if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, mddev->degraded) && !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { @@ -2010,13 +2011,13 @@ /* There is nowhere to write, so all non-sync * drives must be failed, so try the next chunk... */ - { - sector_t sec = max_sector - sector_nr; - sectors_skipped += sec; + if (sector_nr + max_sync < max_sector) + max_sector = sector_nr + max_sync; + + sectors_skipped += (max_sector - sector_nr); chunks_skipped ++; sector_nr = max_sector; goto skipped; - } } static int run(mddev_t *mddev) --- linux-2.6.28.orig/drivers/md/dm-raid1.c +++ linux-2.6.28/drivers/md/dm-raid1.c @@ -197,9 +197,6 @@ struct mirror_set *ms = m->ms; struct mirror *new; - if (!errors_handled(ms)) - return; - /* * error_count is used for nothing more than a * simple way to tell if a device has encountered @@ -210,6 +207,9 @@ if (test_and_set_bit(error_type, &m->error_type)) return; + if (!errors_handled(ms)) + return; + if (m != get_default_mirror(ms)) goto out; --- linux-2.6.28.orig/drivers/md/dm-crypt.c +++ linux-2.6.28/drivers/md/dm-crypt.c @@ -60,6 +60,7 @@ }; struct dm_crypt_request { + struct convert_context *ctx; struct scatterlist sg_in; struct scatterlist sg_out; }; @@ -335,6 +336,18 @@ init_completion(&ctx->restart); } +static struct dm_crypt_request *dmreq_of_req(struct crypt_config *cc, + struct ablkcipher_request *req) +{ + return (struct dm_crypt_request *)((char *)req + cc->dmreq_start); +} + +static struct ablkcipher_request *req_of_dmreq(struct crypt_config *cc, + struct dm_crypt_request *dmreq) +{ + return (struct ablkcipher_request *)((char *)dmreq - cc->dmreq_start); +} + static int crypt_convert_block(struct crypt_config *cc, struct convert_context *ctx, struct ablkcipher_request *req) @@ -345,10 +358,11 @@ u8 *iv; int r = 0; - dmreq = (struct dm_crypt_request *)((char *)req + cc->dmreq_start); + dmreq = dmreq_of_req(cc, req); iv = (u8 *)ALIGN((unsigned long)(dmreq + 1), crypto_ablkcipher_alignmask(cc->tfm) + 1); + dmreq->ctx = ctx; sg_init_table(&dmreq->sg_in, 1); sg_set_page(&dmreq->sg_in, bv_in->bv_page, 1 << SECTOR_SHIFT, bv_in->bv_offset + ctx->offset_in); @@ -395,8 +409,9 @@ cc->req = mempool_alloc(cc->req_pool, GFP_NOIO); ablkcipher_request_set_tfm(cc->req, cc->tfm); ablkcipher_request_set_callback(cc->req, CRYPTO_TFM_REQ_MAY_BACKLOG | - CRYPTO_TFM_REQ_MAY_SLEEP, - kcryptd_async_done, ctx); + CRYPTO_TFM_REQ_MAY_SLEEP, + kcryptd_async_done, + dmreq_of_req(cc, cc->req)); } /* @@ -553,19 +568,22 @@ static void crypt_dec_pending(struct dm_crypt_io *io) { struct crypt_config *cc = io->target->private; + struct bio *base_bio = io->base_bio; + struct dm_crypt_io *base_io = io->base_io; + int error = io->error; if (!atomic_dec_and_test(&io->pending)) return; - if (likely(!io->base_io)) - bio_endio(io->base_bio, io->error); + mempool_free(io, cc->io_pool); + + if (likely(!base_io)) + bio_endio(base_bio, error); else { - if (io->error && !io->base_io->error) - io->base_io->error = io->error; - crypt_dec_pending(io->base_io); + if (error && !base_io->error) + base_io->error = error; + crypt_dec_pending(base_io); } - - mempool_free(io, cc->io_pool); } /* @@ -821,7 +839,8 @@ static void kcryptd_async_done(struct crypto_async_request *async_req, int error) { - struct convert_context *ctx = async_req->data; + struct dm_crypt_request *dmreq = async_req->data; + struct convert_context *ctx = dmreq->ctx; struct dm_crypt_io *io = container_of(ctx, struct dm_crypt_io, ctx); struct crypt_config *cc = io->target->private; @@ -830,7 +849,7 @@ return; } - mempool_free(ablkcipher_request_cast(async_req), cc->req_pool); + mempool_free(req_of_dmreq(cc, dmreq), cc->req_pool); if (!atomic_dec_and_test(&ctx->pending)) return; --- linux-2.6.28.orig/drivers/ide/ide-cd.c +++ linux-2.6.28/drivers/ide/ide-cd.c @@ -984,6 +984,9 @@ if (blk_fs_request(rq)) { ide_end_request(drive, 1, rq->nr_sectors); return ide_stopped; + } else if (rq->cmd_type == REQ_TYPE_ATA_PC && !rq->bio) { + ide_end_request(drive, 1, 1); + return ide_stopped; } goto end_request; } --- linux-2.6.28.orig/drivers/ide/it821x.c +++ linux-2.6.28/drivers/ide/it821x.c @@ -68,6 +68,8 @@ #define DRV_NAME "it821x" +#define QUIRK_VORTEX86 1 + struct it821x_dev { unsigned int smart:1, /* Are we in smart raid mode */ @@ -79,6 +81,7 @@ u16 pio[2]; /* Cached PIO values */ u16 mwdma[2]; /* Cached MWDMA values */ u16 udma[2]; /* Cached UDMA values (per drive) */ + u16 quirks; }; #define ATA_66 0 @@ -580,6 +583,12 @@ hwif->ultra_mask = ATA_UDMA6; hwif->mwdma_mask = ATA_MWDMA2; + + /* Vortex86SX quirk: prevent Ultra-DMA mode to fix BadCRC issue */ + if (idev->quirks & QUIRK_VORTEX86) { + if (dev->revision == 0x11) + hwif->ultra_mask = 0; + } } static void it8212_disable_raid(struct pci_dev *dev) @@ -652,6 +661,8 @@ return -ENOMEM; } + itdevs->quirks = id->driver_data; + rc = ide_pci_init_one(dev, &it821x_chipset, itdevs); if (rc) kfree(itdevs); @@ -671,6 +682,7 @@ static const struct pci_device_id it821x_pci_tbl[] = { { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8211), 0 }, { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8212), 0 }, + { PCI_VDEVICE(RDC, PCI_DEVICE_ID_RDC_D1010), QUIRK_VORTEX86 }, { 0, }, }; --- linux-2.6.28.orig/drivers/ide/tx4938ide.c +++ linux-2.6.28/drivers/ide/tx4938ide.c @@ -181,7 +181,7 @@ while (count--) *ptr++ = cpu_to_le16(__raw_readw((void __iomem *)port)); - __ide_flush_dcache_range((unsigned long)buf, count * 2); + __ide_flush_dcache_range((unsigned long)buf, roundup(len, 2)); } static void tx4938ide_output_data_swap(ide_drive_t *drive, struct request *rq, @@ -195,7 +195,7 @@ __raw_writew(le16_to_cpu(*ptr), (void __iomem *)port); ptr++; } - __ide_flush_dcache_range((unsigned long)buf, count * 2); + __ide_flush_dcache_range((unsigned long)buf, roundup(len, 2)); } static const struct ide_tp_ops tx4938ide_tp_ops = { --- linux-2.6.28.orig/drivers/ide/ide-io.c +++ linux-2.6.28/drivers/ide/ide-io.c @@ -577,11 +577,14 @@ if (hwif->sg_mapped) /* needed by ide-scsi */ return; - if (rq->cmd_type != REQ_TYPE_ATA_TASKFILE) { - hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg); - } else { + if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE); hwif->sg_nents = 1; + } else if (!rq->bio) { + sg_init_one(sg, rq->data, rq->data_len); + hwif->sg_nents = 1; + } else { + hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg); } } --- linux-2.6.28.orig/drivers/ide/tx4939ide.c +++ linux-2.6.28/drivers/ide/tx4939ide.c @@ -259,6 +259,12 @@ bcount = 0x10000 - (cur_addr & 0xffff); if (bcount > cur_len) bcount = cur_len; + /* + * This workaround for zero count seems required. + * (standard ide_build_dmatable do it too) + */ + if ((bcount & 0xffff) == 0x0000) + bcount = 0x8000; *table++ = bcount & 0xffff; *table++ = cur_addr; cur_addr += bcount; @@ -558,7 +564,7 @@ while (count--) *ptr++ = cpu_to_le16(__raw_readw((void __iomem *)port)); - __ide_flush_dcache_range((unsigned long)buf, count * 2); + __ide_flush_dcache_range((unsigned long)buf, roundup(len, 2)); } static void tx4939ide_output_data_swap(ide_drive_t *drive, struct request *rq, @@ -572,7 +578,7 @@ __raw_writew(le16_to_cpu(*ptr), (void __iomem *)port); ptr++; } - __ide_flush_dcache_range((unsigned long)buf, count * 2); + __ide_flush_dcache_range((unsigned long)buf, roundup(len, 2)); } static const struct ide_tp_ops tx4939ide_tp_ops = { --- linux-2.6.28.orig/drivers/ide/ide-iops.c +++ linux-2.6.28/drivers/ide/ide-iops.c @@ -324,6 +324,8 @@ u8 io_32bit = drive->io_32bit; u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; + len++; + if (io_32bit) { unsigned long uninitialized_var(flags); --- linux-2.6.28.orig/drivers/leds/Kconfig +++ linux-2.6.28/drivers/leds/Kconfig @@ -24,6 +24,10 @@ This option enables support for LEDs driven using outputs of the dedicated PWM controller found on newer Atmel SOCs. +config LEDS_MC13892 + tristate "LED Support for mc13892 pmic" + depends on LEDS_CLASS && MXC_MC13892_LIGHT + config LEDS_LOCOMO tristate "LED Support for Locomo device" depends on LEDS_CLASS && SHARP_LOCOMO --- linux-2.6.28.orig/drivers/leds/Makefile +++ linux-2.6.28/drivers/leds/Makefile @@ -6,6 +6,7 @@ # LED Platform Drivers obj-$(CONFIG_LEDS_ATMEL_PWM) += leds-atmel-pwm.o +obj-$(CONFIG_LEDS_MC13892) += leds-mc13892.o obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o --- linux-2.6.28.orig/drivers/leds/leds-mc13892.c +++ linux-2.6.28/drivers/leds/leds-mc13892.c @@ -0,0 +1,152 @@ +/* + * Copyright 2008-2009 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 + */ + +#include +#include +#include +#include +#include + +static void mc13892_led_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + struct platform_device *dev = to_platform_device(led_cdev->dev->parent); + int led_ch; + + switch (dev->id) { + case 'r': + led_ch = LIT_RED; + break; + case 'g': + led_ch = LIT_GREEN; + break; + case 'b': + led_ch = LIT_BLUE; + break; + default: + return; + } + + /* set current with medium value, in case current is too large */ + mc13892_bklit_set_current(led_ch, LIT_CURR_12); + /* max duty cycle is 63, brightness needs to be divided by 4 */ + mc13892_bklit_set_dutycycle(led_ch, value / 4); + +} + +static int mc13892_led_remove(struct platform_device *dev) +{ + struct led_classdev *led_cdev = platform_get_drvdata(dev); + + led_classdev_unregister(led_cdev); + kfree(led_cdev->name); + kfree(led_cdev); + + return 0; +} + +#define LED_NAME_LEN 16 + +static int mc13892_led_probe(struct platform_device *dev) +{ + int ret; + struct led_classdev *led_cdev; + char *name; + + led_cdev = kzalloc(sizeof(struct led_classdev), GFP_KERNEL); + if (led_cdev == NULL) { + dev_err(&dev->dev, "No memory for device\n"); + return -ENOMEM; + } + name = kzalloc(LED_NAME_LEN, GFP_KERNEL); + if (name == NULL) { + dev_err(&dev->dev, "No memory for device\n"); + ret = -ENOMEM; + goto exit_err; + } + + strcpy(name, dev->name); + ret = strlen(dev->name); + if (ret > LED_NAME_LEN - 2) { + dev_err(&dev->dev, "led name is too long\n"); + goto exit_err1; + } + name[ret] = dev->id; + name[ret + 1] = '\0'; + led_cdev->name = name; + led_cdev->brightness_set = mc13892_led_set; + + ret = led_classdev_register(&dev->dev, led_cdev); + if (ret < 0) { + dev_err(&dev->dev, "led_classdev_register failed\n"); + goto exit_err1; + } + + platform_set_drvdata(dev, led_cdev); + + return 0; + exit_err1: + kfree(led_cdev->name); + exit_err: + kfree(led_cdev); + return ret; +} + +#ifdef CONFIG_PM +static int mc13892_led_suspend(struct platform_device *dev, pm_message_t state) +{ + struct led_classdev *led_cdev = platform_get_drvdata(dev); + + led_classdev_suspend(led_cdev); + return 0; +} + +static int mc13892_led_resume(struct platform_device *dev) +{ + struct led_classdev *led_cdev = platform_get_drvdata(dev); + + led_classdev_resume(led_cdev); + return 0; +} +#else +#define mc13892_led_suspend NULL +#define mc13892_led_resume NULL +#endif + +static struct platform_driver mc13892_led_driver = { + .probe = mc13892_led_probe, + .remove = mc13892_led_remove, + .suspend = mc13892_led_suspend, + .resume = mc13892_led_resume, + .driver = { + .name = "pmic_leds", + .owner = THIS_MODULE, + }, +}; + +static int __init mc13892_led_init(void) +{ + return platform_driver_register(&mc13892_led_driver); +} + +static void __exit mc13892_led_exit(void) +{ + platform_driver_unregister(&mc13892_led_driver); +} + +module_init(mc13892_led_init); +module_exit(mc13892_led_exit); + +MODULE_DESCRIPTION("Led driver for PMIC mc13892"); +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/drivers/dma/ioat_dma.c +++ linux-2.6.28/drivers/dma/ioat_dma.c @@ -1341,12 +1341,11 @@ */ #define IOAT_TEST_SIZE 2000 -DECLARE_COMPLETION(test_completion); static void ioat_dma_test_callback(void *dma_async_param) { - printk(KERN_ERR "ioatdma: ioat_dma_test_callback(%p)\n", - dma_async_param); - complete(&test_completion); + struct completion *cmp = dma_async_param; + + complete(cmp); } /** @@ -1363,6 +1362,7 @@ dma_addr_t dma_dest, dma_src; dma_cookie_t cookie; int err = 0; + struct completion cmp; src = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, GFP_KERNEL); if (!src) @@ -1402,8 +1402,9 @@ } async_tx_ack(tx); + init_completion(&cmp); tx->callback = ioat_dma_test_callback; - tx->callback_param = (void *)0x8086; + tx->callback_param = &cmp; cookie = tx->tx_submit(tx); if (cookie < 0) { dev_err(&device->pdev->dev, @@ -1413,7 +1414,7 @@ } device->common.device_issue_pending(dma_chan); - wait_for_completion_timeout(&test_completion, msecs_to_jiffies(3000)); + wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)); if (device->common.device_is_tx_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) {